summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/acpi/arm64/iort.c140
-rw-r--r--drivers/acpi/nfit/core.c2
-rw-r--r--drivers/acpi/processor_idle.c2
-rw-r--r--drivers/ata/ahci_da850.c8
-rw-r--r--drivers/ata/libata-core.c3
-rw-r--r--drivers/ata/libata-eh.c8
-rw-r--r--drivers/base/arch_topology.c86
-rw-r--r--drivers/base/base.h5
-rw-r--r--drivers/base/bus.c2
-rw-r--r--drivers/base/core.c141
-rw-r--r--drivers/base/dd.c32
-rw-r--r--drivers/base/firmware_class.c13
-rw-r--r--drivers/base/topology.c2
-rw-r--r--drivers/block/Kconfig2
-rw-r--r--drivers/block/null_blk.c2
-rw-r--r--drivers/block/xen-blkback/xenbus.c10
-rw-r--r--drivers/char/Kconfig2
-rw-r--r--drivers/char/agp/ali-agp.c2
-rw-r--r--drivers/char/agp/amd-k7-agp.c4
-rw-r--r--drivers/char/agp/amd64-agp.c2
-rw-r--r--drivers/char/agp/ati-agp.c2
-rw-r--r--drivers/char/agp/efficeon-agp.c2
-rw-r--r--drivers/char/agp/intel-agp.c2
-rw-r--r--drivers/char/agp/nvidia-agp.c2
-rw-r--r--drivers/char/agp/sis-agp.c2
-rw-r--r--drivers/char/agp/uninorth-agp.c2
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c12
-rw-r--r--drivers/char/tpm/tpm-chip.c11
-rw-r--r--drivers/char/virtio_console.c2
-rw-r--r--drivers/clocksource/Kconfig8
-rw-r--r--drivers/clocksource/Makefile1
-rw-r--r--drivers/clocksource/arm_arch_timer.c6
-rw-r--r--drivers/clocksource/bcm2835_timer.c1
-rw-r--r--drivers/clocksource/tango_xtal.c6
-rw-r--r--drivers/clocksource/timer-imx-tpm.c239
-rw-r--r--drivers/clocksource/timer-of.c11
-rw-r--r--drivers/clocksource/timer-probe.c3
-rw-r--r--drivers/clocksource/timer-stm32.c8
-rw-r--r--drivers/cpuidle/coupled.c10
-rw-r--r--drivers/dma-buf/dma-fence.c4
-rw-r--r--drivers/dma-buf/reservation.c99
-rw-r--r--drivers/dma-buf/sw_sync.c201
-rw-r--r--drivers/dma-buf/sync_debug.c19
-rw-r--r--drivers/dma-buf/sync_debug.h26
-rw-r--r--drivers/firmware/dmi-sysfs.c5
-rw-r--r--drivers/firmware/efi/efi.c33
-rw-r--r--drivers/firmware/efi/libstub/arm64-stub.c6
-rw-r--r--drivers/firmware/efi/libstub/efi-stub-helper.c4
-rw-r--r--drivers/firmware/pcdp.c4
-rw-r--r--drivers/gpu/drm/Makefile2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/Makefile2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h223
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c72
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c44
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h18
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c189
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c227
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c32
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c161
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c17
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c12
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c30
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c131
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c251
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_display.c6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c31
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c31
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c81
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h77
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c64
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c73
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c7
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_job.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c39
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c31
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h13
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_object.c234
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_object.h68
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_pm.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c63
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c53
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h40
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_test.c56
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h82
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c488
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h22
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c18
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c8
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c18
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.c85
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.h62
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c25
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c504
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h39
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c77
-rw-r--r--drivers/gpu/drm/amd/amdgpu/cik.c9
-rw-r--r--drivers/gpu/drm/amd/amdgpu/cik_sdma.c60
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v10_0.c168
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v11_0.c113
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v6_0.c152
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v8_0.c115
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_virtual.c125
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c109
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c243
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c172
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c152
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v9_0.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c18
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c80
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c78
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c91
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c142
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c111
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.h3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c46
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mxgpu_vi.h4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c15
-rw-r--r--drivers/gpu/drm/amd/amdgpu/nbio_v6_1.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/psp_v10_0.c96
-rw-r--r--drivers/gpu/drm/amd/amdgpu/psp_v10_0.h5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/psp_v3_1.c10
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c42
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c70
-rw-r--r--drivers/gpu/drm/amd/amdgpu/si.c28
-rw-r--r--drivers/gpu/drm/amd/amdgpu/si_dpm.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/soc15.c66
-rw-r--r--drivers/gpu/drm/amd/amdgpu/soc15_common.h7
-rw-r--r--drivers/gpu/drm/amd/amdgpu/soc15d.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c80
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vce_v4_0.c33
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vi.c3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_chardev.c183
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c102
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.c21
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.h27
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device.c123
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c318
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c8
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c8
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c40
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_events.c33
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c2
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c2
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c63
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_module.c10
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c62
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c46
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c294
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_pasid.c7
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h330
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_vi.h140
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_priv.h32
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_process.c25
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c71
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_queue.c12
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_topology.c46
-rw-r--r--drivers/gpu/drm/amd/include/atomfirmware.h63
-rw-r--r--drivers/gpu/drm/amd/include/cgs_common.h6
-rw-r--r--drivers/gpu/drm/amd/include/kgd_kfd_interface.h30
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c113
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c25
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c241
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h8
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c9
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.h2
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c12
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c302
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h15
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c1291
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.h16
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c88
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c6
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h5
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/hwmgr.h2
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/pp_debug.h6
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/pp_soc15.h2
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h7
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/smu9.h13
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/smu9_driver_if.h5
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/smumgr.h3
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h4
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.c19
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.h1
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c184
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.h11
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.c4
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c34
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.h12
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c6
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h8
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c11
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c30
-rw-r--r--drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h9
-rw-r--r--drivers/gpu/drm/arc/arcpgu_crtc.c43
-rw-r--r--drivers/gpu/drm/arc/arcpgu_drv.c61
-rw-r--r--drivers/gpu/drm/arm/hdlcd_crtc.c11
-rw-r--r--drivers/gpu/drm/arm/hdlcd_drv.c4
-rw-r--r--drivers/gpu/drm/arm/malidp_crtc.c10
-rw-r--r--drivers/gpu/drm/arm/malidp_drv.c4
-rw-r--r--drivers/gpu/drm/arm/malidp_planes.c3
-rw-r--r--drivers/gpu/drm/armada/armada_crtc.c20
-rw-r--r--drivers/gpu/drm/armada/armada_crtc.h2
-rw-r--r--drivers/gpu/drm/armada/armada_drv.c4
-rw-r--r--drivers/gpu/drm/armada/armada_fbdev.c3
-rw-r--r--drivers/gpu/drm/armada/armada_overlay.c3
-rw-r--r--drivers/gpu/drm/ast/ast_dp501.c25
-rw-r--r--drivers/gpu/drm/ast/ast_drv.c6
-rw-r--r--drivers/gpu/drm/ast/ast_drv.h4
-rw-r--r--drivers/gpu/drm/ast/ast_fb.c23
-rw-r--r--drivers/gpu/drm/ast/ast_main.c13
-rw-r--r--drivers/gpu/drm/ast/ast_mode.c48
-rw-r--r--drivers/gpu/drm/ast/ast_ttm.c19
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c17
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c32
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h16
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c45
-rw-r--r--drivers/gpu/drm/bochs/bochs_drv.c6
-rw-r--r--drivers/gpu/drm/bochs/bochs_fbdev.c7
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7511_drv.c11
-rw-r--r--drivers/gpu/drm/bridge/analogix-anx78xx.c10
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix_dp_core.c1
-rw-r--r--drivers/gpu/drm/bridge/dumb-vga-dac.c10
-rw-r--r--drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c1
-rw-r--r--drivers/gpu/drm/bridge/nxp-ptn3460.c7
-rw-r--r--drivers/gpu/drm/bridge/panel.c36
-rw-r--r--drivers/gpu/drm/bridge/parade-ps8622.c7
-rw-r--r--drivers/gpu/drm/bridge/sii902x.c9
-rw-r--r--drivers/gpu/drm/bridge/sil-sii8620.c4
-rw-r--r--drivers/gpu/drm/bridge/synopsys/Kconfig16
-rw-r--r--drivers/gpu/drm/bridge/synopsys/Makefile3
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c2
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c327
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h19
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c3
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi.c107
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi.h46
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c981
-rw-r--r--drivers/gpu/drm/bridge/tc358767.c7
-rw-r--r--drivers/gpu/drm/bridge/ti-tfp410.c7
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_drv.c6
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_drv.h8
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_fbdev.c5
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_main.c10
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_mode.c71
-rw-r--r--drivers/gpu/drm/drm_atomic.c219
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c611
-rw-r--r--drivers/gpu/drm/drm_color_mgmt.c3
-rw-r--r--drivers/gpu/drm/drm_connector.c7
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c3
-rw-r--r--drivers/gpu/drm/drm_crtc_internal.h7
-rw-r--r--drivers/gpu/drm/drm_debugfs_crc.c59
-rw-r--r--drivers/gpu/drm/drm_dp_mst_topology.c89
-rw-r--r--drivers/gpu/drm/drm_drv.c56
-rw-r--r--drivers/gpu/drm/drm_dumb_buffers.c26
-rw-r--r--drivers/gpu/drm/drm_edid.c440
-rw-r--r--drivers/gpu/drm/drm_fb_cma_helper.c184
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c681
-rw-r--r--drivers/gpu/drm/drm_file.c9
-rw-r--r--drivers/gpu/drm/drm_framebuffer.c2
-rw-r--r--drivers/gpu/drm/drm_gem.c49
-rw-r--r--drivers/gpu/drm/drm_gem_cma_helper.c39
-rw-r--r--drivers/gpu/drm/drm_gem_framebuffer_helper.c283
-rw-r--r--drivers/gpu/drm/drm_internal.h20
-rw-r--r--drivers/gpu/drm/drm_ioc32.c2
-rw-r--r--drivers/gpu/drm/drm_ioctl.c23
-rw-r--r--drivers/gpu/drm/drm_mipi_dsi.c6
-rw-r--r--drivers/gpu/drm/drm_mode_config.c7
-rw-r--r--drivers/gpu/drm/drm_mode_object.c159
-rw-r--r--drivers/gpu/drm/drm_modes.c91
-rw-r--r--drivers/gpu/drm/drm_modeset_helper.c1
-rw-r--r--drivers/gpu/drm/drm_modeset_lock.c12
-rw-r--r--drivers/gpu/drm/drm_of.c4
-rw-r--r--drivers/gpu/drm/drm_pci.c40
-rw-r--r--drivers/gpu/drm/drm_plane.c120
-rw-r--r--drivers/gpu/drm/drm_probe_helper.c4
-rw-r--r--drivers/gpu/drm/drm_property.c23
-rw-r--r--drivers/gpu/drm/drm_scdc_helper.c33
-rw-r--r--drivers/gpu/drm/drm_simple_kms_helper.c23
-rw-r--r--drivers/gpu/drm/drm_syncobj.c531
-rw-r--r--drivers/gpu/drm/drm_vblank.c187
-rw-r--r--drivers/gpu/drm/drm_vm.c6
-rw-r--r--drivers/gpu/drm/etnaviv/Kconfig2
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_drv.c8
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gem.c45
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c2
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c4
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gpu.c8
-rw-r--r--drivers/gpu/drm/exynos/exynos5433_drm_decon.c124
-rw-r--r--drivers/gpu/drm/exynos/exynos7_drm_decon.c13
-rw-r--r--drivers/gpu/drm/exynos/exynos_dp.c15
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_core.c1
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.c43
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.h10
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dpi.c13
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c8
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.h5
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dsi.c222
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fb.c29
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fbdev.c26
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c16
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gem.c30
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gem.h5
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_mic.c44
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_plane.c30
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_vidi.c16
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c28
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c48
-rw-r--r--drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c5
-rw-r--r--drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c2
-rw-r--r--drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c2
-rw-r--r--drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c1
-rw-r--r--drivers/gpu/drm/gma500/framebuffer.c22
-rw-r--r--drivers/gpu/drm/gma500/gem.c30
-rw-r--r--drivers/gpu/drm/gma500/gma_display.c32
-rw-r--r--drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c4
-rw-r--r--drivers/gpu/drm/gma500/mdfld_intel_display.c4
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.c7
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.h2
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_display.c7
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_drv.h1
-rw-r--r--drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c12
-rw-r--r--drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c4
-rw-r--r--drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c5
-rw-r--r--drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c1
-rw-r--r--drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c8
-rw-r--r--drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c67
-rw-r--r--drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c31
-rw-r--r--drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c30
-rw-r--r--drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h2
-rw-r--r--drivers/gpu/drm/i2c/tda998x_drv.c12
-rw-r--r--drivers/gpu/drm/i810/i810_drv.c5
-rw-r--r--drivers/gpu/drm/i915/Kconfig1
-rw-r--r--drivers/gpu/drm/i915/Kconfig.debug1
-rw-r--r--drivers/gpu/drm/i915/Makefile1
-rw-r--r--drivers/gpu/drm/i915/gvt/aperture_gm.c4
-rw-r--r--drivers/gpu/drm/i915/gvt/cmd_parser.c8
-rw-r--r--drivers/gpu/drm/i915/gvt/cmd_parser.h2
-rw-r--r--drivers/gpu/drm/i915/gvt/display.c6
-rw-r--r--drivers/gpu/drm/i915/gvt/execlist.c15
-rw-r--r--drivers/gpu/drm/i915/gvt/gtt.c128
-rw-r--r--drivers/gpu/drm/i915/gvt/gtt.h26
-rw-r--r--drivers/gpu/drm/i915/gvt/gvt.h3
-rw-r--r--drivers/gpu/drm/i915/gvt/handlers.c50
-rw-r--r--drivers/gpu/drm/i915/gvt/kvmgt.c17
-rw-r--r--drivers/gpu/drm/i915/gvt/render.c54
-rw-r--r--drivers/gpu/drm/i915/gvt/scheduler.c113
-rw-r--r--drivers/gpu/drm/i915/gvt/scheduler.h1
-rw-r--r--drivers/gpu/drm/i915/gvt/vgpu.c7
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c205
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c197
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h366
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c432
-rw-r--r--drivers/gpu/drm/i915/i915_gem_clflush.c3
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.c275
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.h79
-rw-r--r--drivers/gpu/drm/i915/i915_gem_evict.c4
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c640
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.c109
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.h3
-rw-r--r--drivers/gpu/drm/i915/i915_gem_internal.c7
-rw-r--r--drivers/gpu/drm/i915/i915_gem_object.c48
-rw-r--r--drivers/gpu/drm/i915/i915_gem_object.h32
-rw-r--r--drivers/gpu/drm/i915/i915_gem_request.c104
-rw-r--r--drivers/gpu/drm/i915/i915_gem_request.h2
-rw-r--r--drivers/gpu/drm/i915/i915_gem_stolen.c8
-rw-r--r--drivers/gpu/drm/i915/i915_gem_userptr.c4
-rw-r--r--drivers/gpu/drm/i915/i915_gpu_error.c11
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c377
-rw-r--r--drivers/gpu/drm/i915/i915_oa_bdw.c5310
-rw-r--r--drivers/gpu/drm/i915/i915_oa_bdw.h8
-rw-r--r--drivers/gpu/drm/i915/i915_oa_bxt.c2624
-rw-r--r--drivers/gpu/drm/i915/i915_oa_bxt.h8
-rw-r--r--drivers/gpu/drm/i915/i915_oa_chv.c2808
-rw-r--r--drivers/gpu/drm/i915/i915_oa_chv.h8
-rw-r--r--drivers/gpu/drm/i915/i915_oa_glk.c2536
-rw-r--r--drivers/gpu/drm/i915/i915_oa_glk.h8
-rw-r--r--drivers/gpu/drm/i915/i915_oa_hsw.c765
-rw-r--r--drivers/gpu/drm/i915/i915_oa_hsw.h8
-rw-r--r--drivers/gpu/drm/i915/i915_oa_kblgt2.c2924
-rw-r--r--drivers/gpu/drm/i915/i915_oa_kblgt2.h8
-rw-r--r--drivers/gpu/drm/i915/i915_oa_kblgt3.c2973
-rw-r--r--drivers/gpu/drm/i915/i915_oa_kblgt3.h8
-rw-r--r--drivers/gpu/drm/i915/i915_oa_sklgt2.c3413
-rw-r--r--drivers/gpu/drm/i915/i915_oa_sklgt2.h8
-rw-r--r--drivers/gpu/drm/i915/i915_oa_sklgt3.c2972
-rw-r--r--drivers/gpu/drm/i915/i915_oa_sklgt3.h8
-rw-r--r--drivers/gpu/drm/i915/i915_oa_sklgt4.c3026
-rw-r--r--drivers/gpu/drm/i915/i915_oa_sklgt4.h8
-rw-r--r--drivers/gpu/drm/i915/i915_params.c10
-rw-r--r--drivers/gpu/drm/i915/i915_params.h3
-rw-r--r--drivers/gpu/drm/i915/i915_pci.c7
-rw-r--r--drivers/gpu/drm/i915/i915_perf.c809
-rw-r--r--drivers/gpu/drm/i915/i915_pvinfo.h8
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h521
-rw-r--r--drivers/gpu/drm/i915/i915_selftest.h2
-rw-r--r--drivers/gpu/drm/i915/i915_sysfs.c16
-rw-r--r--drivers/gpu/drm/i915/i915_vgpu.c7
-rw-r--r--drivers/gpu/drm/i915/i915_vgpu.h3
-rw-r--r--drivers/gpu/drm/i915/i915_vma.c31
-rw-r--r--drivers/gpu/drm/i915/i915_vma.h6
-rw-r--r--drivers/gpu/drm/i915/intel_atomic_plane.c15
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c9
-rw-r--r--drivers/gpu/drm/i915/intel_color.c47
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c2
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c119
-rw-r--r--drivers/gpu/drm/i915/intel_device_info.c2
-rw-r--r--drivers/gpu/drm/i915/intel_display.c1717
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c218
-rw-r--r--drivers/gpu/drm/i915/intel_dp_aux_backlight.c98
-rw-r--r--drivers/gpu/drm/i915/intel_dp_link_training.c8
-rw-r--r--drivers/gpu/drm/i915/intel_dp_mst.c52
-rw-r--r--drivers/gpu/drm/i915/intel_dpll_mgr.c11
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h57
-rw-r--r--drivers/gpu/drm/i915/intel_dsi.c4
-rw-r--r--drivers/gpu/drm/i915/intel_dvo.c4
-rw-r--r--drivers/gpu/drm/i915/intel_engine_cs.c45
-rw-r--r--drivers/gpu/drm/i915/intel_fbc.c4
-rw-r--r--drivers/gpu/drm/i915/intel_fbdev.c72
-rw-r--r--drivers/gpu/drm/i915/intel_fifo_underrun.c6
-rw-r--r--drivers/gpu/drm/i915/intel_hangcheck.c2
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c204
-rw-r--r--drivers/gpu/drm/i915/intel_hotplug.c57
-rw-r--r--drivers/gpu/drm/i915/intel_i2c.c36
-rw-r--r--drivers/gpu/drm/i915/intel_lrc.c38
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c5
-rw-r--r--drivers/gpu/drm/i915/intel_opregion.c45
-rw-r--r--drivers/gpu/drm/i915/intel_overlay.c11
-rw-r--r--drivers/gpu/drm/i915/intel_panel.c9
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c245
-rw-r--r--drivers/gpu/drm/i915/intel_psr.c1
-rw-r--r--drivers/gpu/drm/i915/intel_renderstate_gen9.c4
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c8
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.h13
-rw-r--r--drivers/gpu/drm/i915/intel_runtime_pm.c1028
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c81
-rw-r--r--drivers/gpu/drm/i915/intel_sprite.c161
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c2
-rw-r--r--drivers/gpu/drm/i915/intel_uc.c4
-rw-r--r--drivers/gpu/drm/i915/intel_uncore.c22
-rw-r--r--drivers/gpu/drm/i915/selftests/huge_gem_object.c6
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_gem_coherency.c2
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_gem_context.c6
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_gem_gtt.c10
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_vma.c8
-rw-r--r--drivers/gpu/drm/i915/selftests/intel_hangcheck.c343
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_context.c36
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_context.h5
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_engine.c8
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_engine.h3
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_gem_device.c30
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_gtt.c3
-rw-r--r--drivers/gpu/drm/imx/imx-drm-core.c10
-rw-r--r--drivers/gpu/drm/imx/imx-ldb.c1
-rw-r--r--drivers/gpu/drm/imx/imx-tve.c1
-rw-r--r--drivers/gpu/drm/imx/ipuv3-crtc.c5
-rw-r--r--drivers/gpu/drm/imx/ipuv3-plane.c57
-rw-r--r--drivers/gpu/drm/imx/parallel-display.c1
-rw-r--r--drivers/gpu/drm/mediatek/mtk_disp_color.c4
-rw-r--r--drivers/gpu/drm/mediatek/mtk_disp_ovl.c4
-rw-r--r--drivers/gpu/drm/mediatek/mtk_disp_rdma.c4
-rw-r--r--drivers/gpu/drm/mediatek/mtk_dpi.c6
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_crtc.c17
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c6
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_drv.c32
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_fb.c4
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_gem.c27
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_gem.h3
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_plane.c2
-rw-r--r--drivers/gpu/drm/mediatek/mtk_dsi.c5
-rw-r--r--drivers/gpu/drm/mediatek/mtk_hdmi.c11
-rw-r--r--drivers/gpu/drm/meson/meson_crtc.c10
-rw-r--r--drivers/gpu/drm/meson/meson_drv.c7
-rw-r--r--drivers/gpu/drm/meson/meson_plane.c1
-rw-r--r--drivers/gpu/drm/meson/meson_venc_cvbs.c1
-rw-r--r--drivers/gpu/drm/mga/mga_drv.c5
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_cursor.c2
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_drv.c7
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_drv.h5
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_fb.c7
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_main.c10
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_mode.c62
-rw-r--r--drivers/gpu/drm/msm/adreno/a3xx_gpu.c2
-rw-r--r--drivers/gpu/drm/msm/adreno/a3xx_gpu.h1
-rw-r--r--drivers/gpu/drm/msm/adreno/a4xx_gpu.c2
-rw-r--r--drivers/gpu/drm/msm/adreno/a4xx_gpu.h1
-rw-r--r--drivers/gpu/drm/msm/adreno/a5xx_gpu.c51
-rw-r--r--drivers/gpu/drm/msm/adreno/a5xx_gpu.h1
-rw-r--r--drivers/gpu/drm/msm/adreno/a5xx_power.c14
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.c53
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi.c5
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi.h2
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_host.c94
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_manager.c1
-rw-r--r--drivers/gpu/drm/msm/dsi/phy/dsi_phy.c2
-rw-r--r--drivers/gpu/drm/msm/edp/edp_connector.c1
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi.c2
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi_bridge.c6
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi_connector.c64
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c11
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c4
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c1
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c2
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c7
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c38
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c12
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c27
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c54
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h7
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c63
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c6
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c59
-rw-r--r--drivers/gpu/drm/msm/msm_atomic.c34
-rw-r--r--drivers/gpu/drm/msm/msm_drv.c37
-rw-r--r--drivers/gpu/drm/msm/msm_drv.h12
-rw-r--r--drivers/gpu/drm/msm/msm_fb.c45
-rw-r--r--drivers/gpu/drm/msm/msm_fbdev.c58
-rw-r--r--drivers/gpu/drm/msm/msm_gem.c46
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.c85
-rw-r--r--drivers/gpu/drm/msm/msm_kms.h2
-rw-r--r--drivers/gpu/drm/msm/msm_ringbuffer.c12
-rw-r--r--drivers/gpu/drm/mxsfb/mxsfb_drv.c7
-rw-r--r--drivers/gpu/drm/mxsfb/mxsfb_out.c1
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/crtc.c62
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/overlay.c71
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/conn.h1
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dcb.h1
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c7
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c16
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_crtc.h3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c23
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c35
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.c22
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_ttm.c6
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c157
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/base.c33
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c7
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv40.c7
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c6
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf100.c19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf119.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk110.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk208.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm107.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp100.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp102.c7
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gt215.c15
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h5
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/g84.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/gm200.c39
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c6
-rw-r--r--drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c3
-rw-r--r--drivers/gpu/drm/omapdrm/displays/connector-hdmi.c104
-rw-r--r--drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c81
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-dpi.c3
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c2
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c2
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c5
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c2
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/Makefile2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/core.c190
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dispc.c824
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dpi.c88
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dsi.c329
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dss.c406
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dss.h49
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dss_features.c905
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dss_features.h109
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi.h16
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi4.c7
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi4_core.c38
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi5.c7
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi_phy.c60
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi_pll.c24
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi_wp.c12
-rw-r--r--drivers/gpu/drm/omapdrm/dss/omapdss.h25
-rw-r--r--drivers/gpu/drm/omapdrm/dss/pll.c29
-rw-r--r--drivers/gpu/drm/omapdrm/dss/venc.c86
-rw-r--r--drivers/gpu/drm/omapdrm/dss/video-pll.c3
-rw-r--r--drivers/gpu/drm/omapdrm/omap_connector.c38
-rw-r--r--drivers/gpu/drm/omapdrm/omap_crtc.c137
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.c124
-rw-r--r--drivers/gpu/drm/omapdrm/omap_encoder.c3
-rw-r--r--drivers/gpu/drm/omapdrm/omap_fb.c2
-rw-r--r--drivers/gpu/drm/omapdrm/omap_fbdev.c1
-rw-r--r--drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c2
-rw-r--r--drivers/gpu/drm/omapdrm/omap_plane.c3
-rw-r--r--drivers/gpu/drm/panel/panel-lvds.c16
-rw-r--r--drivers/gpu/drm/pl111/pl111_connector.c1
-rw-r--r--drivers/gpu/drm/pl111/pl111_display.c5
-rw-r--r--drivers/gpu/drm/pl111/pl111_drv.c9
-rw-r--r--drivers/gpu/drm/qxl/qxl_display.c35
-rw-r--r--drivers/gpu/drm/qxl/qxl_drv.c8
-rw-r--r--drivers/gpu/drm/qxl/qxl_drv.h1
-rw-r--r--drivers/gpu/drm/qxl/qxl_fb.c1
-rw-r--r--drivers/gpu/drm/qxl/qxl_ioctl.c17
-rw-r--r--drivers/gpu/drm/qxl/qxl_object.c4
-rw-r--r--drivers/gpu/drm/qxl/qxl_ttm.c2
-rw-r--r--drivers/gpu/drm/r128/r128_drv.c5
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon.h4
-rw-r--r--drivers/gpu/drm/radeon/radeon_acpi.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_acpi.h3
-rw-r--r--drivers/gpu/drm/radeon/radeon_audio.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c7
-rw-r--r--drivers/gpu/drm/radeon/radeon_cs.c10
-rw-r--r--drivers/gpu/drm/radeon/radeon_cursor.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c95
-rw-r--r--drivers/gpu/drm/radeon/radeon_dp_mst.c7
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c7
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c14
-rw-r--r--drivers/gpu/drm/radeon/radeon_gem.c30
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq_kms.c5
-rw-r--r--drivers/gpu/drm/radeon/radeon_kfd.c15
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_crtc.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h4
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_ttm.c32
-rw-r--r--drivers/gpu/drm/radeon/radeon_vm.c4
-rw-r--r--drivers/gpu/drm/radeon/vce_v2_0.c4
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_crtc.c199
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_crtc.h17
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_drv.c30
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_encoder.c4
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_group.c38
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_kms.c129
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c1
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c12
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_plane.c119
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_plane.h3
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_vsp.c56
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_vsp.h10
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c2
-rw-r--r--drivers/gpu/drm/rockchip/cdn-dp-core.c1
-rw-r--r--drivers/gpu/drm/rockchip/dw-mipi-dsi.c1
-rw-r--r--drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c110
-rw-r--r--drivers/gpu/drm/rockchip/inno_hdmi.c5
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_drv.c21
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_fb.c31
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c2
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_gem.c28
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_gem.h3
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop.c174
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop.h81
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_vop_reg.c375
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_vop_reg.h905
-rw-r--r--drivers/gpu/drm/savage/savage_drv.c5
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_drv.c6
-rw-r--r--drivers/gpu/drm/sis/sis_drv.c5
-rw-r--r--drivers/gpu/drm/sti/sti_crtc.c10
-rw-r--r--drivers/gpu/drm/sti/sti_cursor.c3
-rw-r--r--drivers/gpu/drm/sti/sti_drv.c3
-rw-r--r--drivers/gpu/drm/sti/sti_dvo.c3
-rw-r--r--drivers/gpu/drm/sti/sti_gdp.c3
-rw-r--r--drivers/gpu/drm/sti/sti_hda.c1
-rw-r--r--drivers/gpu/drm/sti/sti_hdmi.c4
-rw-r--r--drivers/gpu/drm/sti/sti_hqvdp.c8
-rw-r--r--drivers/gpu/drm/stm/Kconfig9
-rw-r--r--drivers/gpu/drm/stm/Makefile2
-rw-r--r--drivers/gpu/drm/stm/drv.c23
-rw-r--r--drivers/gpu/drm/stm/dw_mipi_dsi-stm.c352
-rw-r--r--drivers/gpu/drm/stm/ltdc.c470
-rw-r--r--drivers/gpu/drm/stm/ltdc.h4
-rw-r--r--drivers/gpu/drm/sun4i/Kconfig16
-rw-r--r--drivers/gpu/drm/sun4i/Makefile1
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_backend.c2
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_crtc.c10
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_drv.c11
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_hdmi.h32
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c159
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_hdmi_i2c.c220
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_layer.c11
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_rgb.c11
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_tcon.h2
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_tv.c11
-rw-r--r--drivers/gpu/drm/sun4i/sun8i_layer.c2
-rw-r--r--drivers/gpu/drm/tdfx/tdfx_drv.c5
-rw-r--r--drivers/gpu/drm/tegra/Kconfig1
-rw-r--r--drivers/gpu/drm/tegra/Makefile2
-rw-r--r--drivers/gpu/drm/tegra/dc.c22
-rw-r--r--drivers/gpu/drm/tegra/dpaux.c12
-rw-r--r--drivers/gpu/drm/tegra/drm.c116
-rw-r--r--drivers/gpu/drm/tegra/drm.h12
-rw-r--r--drivers/gpu/drm/tegra/dsi.c15
-rw-r--r--drivers/gpu/drm/tegra/fb.c8
-rw-r--r--drivers/gpu/drm/tegra/gem.c78
-rw-r--r--drivers/gpu/drm/tegra/gem.h2
-rw-r--r--drivers/gpu/drm/tegra/hdmi.c15
-rw-r--r--drivers/gpu/drm/tegra/rgb.c1
-rw-r--r--drivers/gpu/drm/tegra/sor.c15
-rw-r--r--drivers/gpu/drm/tegra/trace.c2
-rw-r--r--drivers/gpu/drm/tegra/trace.h68
-rw-r--r--drivers/gpu/drm/tegra/vic.c15
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_crtc.c20
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_drv.c8
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_panel.c1
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_plane.c1
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_tfp410.c1
-rw-r--r--drivers/gpu/drm/tinydrm/Kconfig23
-rw-r--r--drivers/gpu/drm/tinydrm/Makefile2
-rw-r--r--drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c60
-rw-r--r--drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c5
-rw-r--r--drivers/gpu/drm/tinydrm/mi0283qt.c8
-rw-r--r--drivers/gpu/drm/tinydrm/mipi-dbi.c17
-rw-r--r--drivers/gpu/drm/tinydrm/repaper.c1117
-rw-r--r--drivers/gpu/drm/tinydrm/st7586.c428
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c64
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_manager.c5
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_vm.c86
-rw-r--r--drivers/gpu/drm/ttm/ttm_page_alloc.c2
-rw-r--r--drivers/gpu/drm/udl/udl_connector.c2
-rw-r--r--drivers/gpu/drm/udl/udl_dmabuf.c2
-rw-r--r--drivers/gpu/drm/udl/udl_drv.c11
-rw-r--r--drivers/gpu/drm/udl/udl_fb.c13
-rw-r--r--drivers/gpu/drm/udl/udl_gem.c4
-rw-r--r--drivers/gpu/drm/udl/udl_main.c2
-rw-r--r--drivers/gpu/drm/vc4/Kconfig8
-rw-r--r--drivers/gpu/drm/vc4/vc4_bo.c291
-rw-r--r--drivers/gpu/drm/vc4/vc4_crtc.c50
-rw-r--r--drivers/gpu/drm/vc4/vc4_dpi.c13
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.c11
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.h40
-rw-r--r--drivers/gpu/drm/vc4/vc4_dsi.c24
-rw-r--r--drivers/gpu/drm/vc4/vc4_gem.c44
-rw-r--r--drivers/gpu/drm/vc4/vc4_hdmi.c291
-rw-r--r--drivers/gpu/drm/vc4/vc4_kms.c85
-rw-r--r--drivers/gpu/drm/vc4/vc4_plane.c19
-rw-r--r--drivers/gpu/drm/vc4/vc4_regs.h113
-rw-r--r--drivers/gpu/drm/vc4/vc4_render_cl.c63
-rw-r--r--drivers/gpu/drm/vc4/vc4_v3d.c3
-rw-r--r--drivers/gpu/drm/vc4/vc4_validate.c78
-rw-r--r--drivers/gpu/drm/vc4/vc4_validate_shaders.c72
-rw-r--r--drivers/gpu/drm/vc4/vc4_vec.c2
-rw-r--r--drivers/gpu/drm/vgem/vgem_drv.c86
-rw-r--r--drivers/gpu/drm/vgem/vgem_drv.h4
-rw-r--r--drivers/gpu/drm/vgem/vgem_fence.c2
-rw-r--r--drivers/gpu/drm/via/via_drv.c5
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_display.c11
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_drv.c1
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_drv.h3
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_fb.c3
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_gem.c7
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_plane.c2
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_ttm.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c242
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c16
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.h39
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c148
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fb.c1
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fence.c104
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fence.h4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_irq.c111
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c41
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.h2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c35
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c27
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c41
-rw-r--r--drivers/gpu/drm/zte/zx_drm_drv.c6
-rw-r--r--drivers/gpu/drm/zte/zx_hdmi.c3
-rw-r--r--drivers/gpu/drm/zte/zx_plane.c2
-rw-r--r--drivers/gpu/drm/zte/zx_tvenc.c1
-rw-r--r--drivers/gpu/drm/zte/zx_vga.c1
-rw-r--r--drivers/gpu/drm/zte/zx_vou.c10
-rw-r--r--drivers/gpu/host1x/bus.c19
-rw-r--r--drivers/gpu/host1x/dev.c4
-rw-r--r--drivers/gpu/host1x/hw/intr_hw.c24
-rw-r--r--drivers/gpu/host1x/hw/syncpt_hw.c2
-rw-r--r--drivers/gpu/host1x/job.c8
-rw-r--r--drivers/gpu/ipu-v3/ipu-common.c4
-rw-r--r--drivers/hwmon/Kconfig8
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/adc128d818.c2
-rw-r--r--drivers/hwmon/ads1015.c14
-rw-r--r--drivers/hwmon/adt7475.c16
-rw-r--r--drivers/hwmon/asc7621.c4
-rw-r--r--drivers/hwmon/aspeed-pwm-tacho.c116
-rw-r--r--drivers/hwmon/da9052-hwmon.c285
-rw-r--r--drivers/hwmon/ftsteutates.c4
-rw-r--r--drivers/hwmon/hwmon.c4
-rw-r--r--drivers/hwmon/i5k_amb.c2
-rw-r--r--drivers/hwmon/it87.c214
-rw-r--r--drivers/hwmon/jc42.c19
-rw-r--r--drivers/hwmon/ltq-cputemp.c163
-rw-r--r--drivers/hwmon/nct7802.c10
-rw-r--r--drivers/hwmon/pmbus/Kconfig18
-rw-r--r--drivers/hwmon/pmbus/Makefile2
-rw-r--r--drivers/hwmon/pmbus/ibm-cffps.c151
-rw-r--r--drivers/hwmon/pmbus/lm25066.c47
-rw-r--r--drivers/hwmon/pmbus/pmbus.h2
-rw-r--r--drivers/hwmon/pmbus/pmbus_core.c292
-rw-r--r--drivers/hwmon/pmbus/tps53679.c113
-rw-r--r--drivers/hwmon/scpi-hwmon.c2
-rw-r--r--drivers/hwmon/stts751.c4
-rw-r--r--drivers/i2c/busses/i2c-designware-platdrv.c16
-rw-r--r--drivers/i2c/busses/i2c-ismt.c6
-rw-r--r--drivers/idle/intel_idle.c9
-rw-r--r--drivers/iio/accel/bma180.c2
-rw-r--r--drivers/iio/accel/bmc150-accel-i2c.c1
-rw-r--r--drivers/iio/accel/da311.c2
-rw-r--r--drivers/iio/accel/sca3000.c6
-rw-r--r--drivers/iio/accel/st_accel.h5
-rw-r--r--drivers/iio/accel/st_accel_core.c6
-rw-r--r--drivers/iio/accel/st_accel_i2c.c8
-rw-r--r--drivers/iio/accel/st_accel_spi.c86
-rw-r--r--drivers/iio/adc/Kconfig33
-rw-r--r--drivers/iio/adc/Makefile3
-rw-r--r--drivers/iio/adc/ad7766.c6
-rw-r--r--drivers/iio/adc/at91-sama5d2_adc.c329
-rw-r--r--drivers/iio/adc/at91_adc.c2
-rw-r--r--drivers/iio/adc/dln2-adc.c722
-rw-r--r--drivers/iio/adc/ep93xx_adc.c255
-rw-r--r--drivers/iio/adc/ina2xx-adc.c36
-rw-r--r--drivers/iio/adc/ltc2471.c160
-rw-r--r--drivers/iio/adc/ltc2497.c54
-rw-r--r--drivers/iio/adc/max9611.c4
-rw-r--r--drivers/iio/adc/mcp3422.c6
-rw-r--r--drivers/iio/adc/meson_saradc.c13
-rw-r--r--drivers/iio/adc/mt6577_auxadc.c37
-rw-r--r--drivers/iio/adc/rockchip_saradc.c8
-rw-r--r--drivers/iio/adc/stm32-adc-core.c2
-rw-r--r--drivers/iio/adc/stm32-adc.c140
-rw-r--r--drivers/iio/adc/ti-ads1015.c611
-rw-r--r--drivers/iio/adc/ti-ads7950.c42
-rw-r--r--drivers/iio/adc/xilinx-xadc-events.c38
-rw-r--r--drivers/iio/adc/xilinx-xadc.h10
-rw-r--r--drivers/iio/chemical/Kconfig9
-rw-r--r--drivers/iio/chemical/Makefile1
-rw-r--r--drivers/iio/chemical/ccs811.c405
-rw-r--r--drivers/iio/common/st_sensors/st_sensors_core.c31
-rw-r--r--drivers/iio/common/st_sensors/st_sensors_i2c.c29
-rw-r--r--drivers/iio/dac/stm32-dac-core.c40
-rw-r--r--drivers/iio/dac/stm32-dac.c2
-rw-r--r--drivers/iio/gyro/mpu3050-core.c10
-rw-r--r--drivers/iio/gyro/st_gyro.h1
-rw-r--r--drivers/iio/gyro/st_gyro_core.c13
-rw-r--r--drivers/iio/gyro/st_gyro_i2c.c8
-rw-r--r--drivers/iio/gyro/st_gyro_spi.c54
-rw-r--r--drivers/iio/humidity/Kconfig3
-rw-r--r--drivers/iio/humidity/hdc100x.c22
-rw-r--r--drivers/iio/humidity/hts221.h11
-rw-r--r--drivers/iio/humidity/hts221_buffer.c43
-rw-r--r--drivers/iio/humidity/hts221_core.c144
-rw-r--r--drivers/iio/humidity/htu21.c8
-rw-r--r--drivers/iio/imu/adis16400_core.c4
-rw-r--r--drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c17
-rw-r--r--drivers/iio/inkern.c6
-rw-r--r--drivers/iio/light/apds9300.c2
-rw-r--r--drivers/iio/light/rpr0521.c336
-rw-r--r--drivers/iio/light/tcs3472.c4
-rw-r--r--drivers/iio/light/tsl2583.c2
-rw-r--r--drivers/iio/magnetometer/Kconfig4
-rw-r--r--drivers/iio/magnetometer/ak8974.c133
-rw-r--r--drivers/iio/magnetometer/ak8975.c2
-rw-r--r--drivers/iio/magnetometer/st_magn.h1
-rw-r--r--drivers/iio/magnetometer/st_magn_core.c3
-rw-r--r--drivers/iio/magnetometer/st_magn_i2c.c8
-rw-r--r--drivers/iio/magnetometer/st_magn_spi.c30
-rw-r--r--drivers/iio/orientation/hid-sensor-rotation.c2
-rw-r--r--drivers/iio/pressure/ms5637.c12
-rw-r--r--drivers/iio/pressure/st_pressure_core.c4
-rw-r--r--drivers/iio/pressure/st_pressure_i2c.c3
-rw-r--r--drivers/iio/pressure/st_pressure_spi.c33
-rw-r--r--drivers/iio/pressure/zpa2326.c12
-rw-r--r--drivers/iio/proximity/Kconfig8
-rw-r--r--drivers/iio/proximity/srf08.c227
-rw-r--r--drivers/iio/temperature/tsys01.c7
-rw-r--r--drivers/iio/trigger/stm32-timer-trigger.c78
-rw-r--r--drivers/infiniband/Kconfig9
-rw-r--r--drivers/infiniband/core/Makefile6
-rw-r--r--drivers/infiniband/core/addr.c12
-rw-r--r--drivers/infiniband/core/cache.c23
-rw-r--r--drivers/infiniband/core/cm.c224
-rw-r--r--drivers/infiniband/core/cma.c35
-rw-r--r--drivers/infiniband/core/core_priv.h27
-rw-r--r--drivers/infiniband/core/device.c144
-rw-r--r--drivers/infiniband/core/iwcm.c16
-rw-r--r--drivers/infiniband/core/iwpm_msg.c20
-rw-r--r--drivers/infiniband/core/iwpm_util.c15
-rw-r--r--drivers/infiniband/core/mad_rmpp.c2
-rw-r--r--drivers/infiniband/core/netlink.c321
-rw-r--r--drivers/infiniband/core/nldev.c325
-rw-r--r--drivers/infiniband/core/rdma_core.c179
-rw-r--r--drivers/infiniband/core/rdma_core.h42
-rw-r--r--drivers/infiniband/core/roce_gid_mgmt.c2
-rw-r--r--drivers/infiniband/core/sa_query.c42
-rw-r--r--drivers/infiniband/core/sysfs.c4
-rw-r--r--drivers/infiniband/core/ucm.c2
-rw-r--r--drivers/infiniband/core/ucma.c10
-rw-r--r--drivers/infiniband/core/umem_odp.c19
-rw-r--r--drivers/infiniband/core/user_mad.c2
-rw-r--r--drivers/infiniband/core/uverbs.h3
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c276
-rw-r--r--drivers/infiniband/core/uverbs_ioctl.c364
-rw-r--r--drivers/infiniband/core/uverbs_ioctl_merge.c665
-rw-r--r--drivers/infiniband/core/uverbs_main.c37
-rw-r--r--drivers/infiniband/core/uverbs_marshall.c48
-rw-r--r--drivers/infiniband/core/uverbs_std_types.c281
-rw-r--r--drivers/infiniband/core/verbs.c169
-rw-r--r--drivers/infiniband/hw/bnxt_re/Makefile2
-rw-r--r--drivers/infiniband/hw/bnxt_re/bnxt_re.h5
-rw-r--r--drivers/infiniband/hw/bnxt_re/hw_counters.c114
-rw-r--r--drivers/infiniband/hw/bnxt_re/hw_counters.h62
-rw-r--r--drivers/infiniband/hw/bnxt_re/ib_verbs.c107
-rw-r--r--drivers/infiniband/hw/bnxt_re/ib_verbs.h3
-rw-r--r--drivers/infiniband/hw/bnxt_re/main.c168
-rw-r--r--drivers/infiniband/hw/bnxt_re/qplib_fp.c486
-rw-r--r--drivers/infiniband/hw/bnxt_re/qplib_fp.h29
-rw-r--r--drivers/infiniband/hw/bnxt_re/qplib_rcfw.c26
-rw-r--r--drivers/infiniband/hw/bnxt_re/qplib_rcfw.h10
-rw-r--r--drivers/infiniband/hw/bnxt_re/qplib_res.c10
-rw-r--r--drivers/infiniband/hw/bnxt_re/qplib_res.h2
-rw-r--r--drivers/infiniband/hw/bnxt_re/qplib_sp.c77
-rw-r--r--drivers/infiniband/hw/bnxt_re/qplib_sp.h2
-rw-r--r--drivers/infiniband/hw/bnxt_re/roce_hsi.h4
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch.c1
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_provider.c5
-rw-r--r--drivers/infiniband/hw/cxgb4/cm.c1
-rw-r--r--drivers/infiniband/hw/cxgb4/device.c1
-rw-r--r--drivers/infiniband/hw/cxgb4/provider.c5
-rw-r--r--drivers/infiniband/hw/hfi1/Kconfig7
-rw-r--r--drivers/infiniband/hw/hfi1/Makefile2
-rw-r--r--drivers/infiniband/hw/hfi1/affinity.c18
-rw-r--r--drivers/infiniband/hw/hfi1/affinity.h14
-rw-r--r--drivers/infiniband/hw/hfi1/aspm.h41
-rw-r--r--drivers/infiniband/hw/hfi1/chip.c808
-rw-r--r--drivers/infiniband/hw/hfi1/chip.h29
-rw-r--r--drivers/infiniband/hw/hfi1/common.h11
-rw-r--r--drivers/infiniband/hw/hfi1/debugfs.c94
-rw-r--r--drivers/infiniband/hw/hfi1/driver.c513
-rw-r--r--drivers/infiniband/hw/hfi1/eprom.c11
-rw-r--r--drivers/infiniband/hw/hfi1/exp_rcv.c114
-rw-r--r--drivers/infiniband/hw/hfi1/exp_rcv.h190
-rw-r--r--drivers/infiniband/hw/hfi1/file_ops.c437
-rw-r--r--drivers/infiniband/hw/hfi1/firmware.c73
-rw-r--r--drivers/infiniband/hw/hfi1/hfi.h554
-rw-r--r--drivers/infiniband/hw/hfi1/init.c393
-rw-r--r--drivers/infiniband/hw/hfi1/intr.c3
-rw-r--r--drivers/infiniband/hw/hfi1/iowait.h70
-rw-r--r--drivers/infiniband/hw/hfi1/mad.c805
-rw-r--r--drivers/infiniband/hw/hfi1/mad.h5
-rw-r--r--drivers/infiniband/hw/hfi1/mmu_rb.c36
-rw-r--r--drivers/infiniband/hw/hfi1/mmu_rb.h5
-rw-r--r--drivers/infiniband/hw/hfi1/opa_compat.h21
-rw-r--r--drivers/infiniband/hw/hfi1/pcie.c384
-rw-r--r--drivers/infiniband/hw/hfi1/pio.c15
-rw-r--r--drivers/infiniband/hw/hfi1/platform.c102
-rw-r--r--drivers/infiniband/hw/hfi1/qp.c222
-rw-r--r--drivers/infiniband/hw/hfi1/qp.h23
-rw-r--r--drivers/infiniband/hw/hfi1/rc.c426
-rw-r--r--drivers/infiniband/hw/hfi1/ruc.c321
-rw-r--r--drivers/infiniband/hw/hfi1/sdma.c42
-rw-r--r--drivers/infiniband/hw/hfi1/sdma.h3
-rw-r--r--drivers/infiniband/hw/hfi1/sysfs.c4
-rw-r--r--drivers/infiniband/hw/hfi1/trace.c191
-rw-r--r--drivers/infiniband/hw/hfi1/trace.h3
-rw-r--r--drivers/infiniband/hw/hfi1/trace_ibhdrs.h456
-rw-r--r--drivers/infiniband/hw/hfi1/trace_misc.h20
-rw-r--r--drivers/infiniband/hw/hfi1/trace_mmu.h95
-rw-r--r--drivers/infiniband/hw/hfi1/trace_rx.h102
-rw-r--r--drivers/infiniband/hw/hfi1/trace_tx.h136
-rw-r--r--drivers/infiniband/hw/hfi1/uc.c60
-rw-r--r--drivers/infiniband/hw/hfi1/ud.c487
-rw-r--r--drivers/infiniband/hw/hfi1/user_exp_rcv.c371
-rw-r--r--drivers/infiniband/hw/hfi1/user_exp_rcv.h58
-rw-r--r--drivers/infiniband/hw/hfi1/user_sdma.c626
-rw-r--r--drivers/infiniband/hw/hfi1/user_sdma.h169
-rw-r--r--drivers/infiniband/hw/hfi1/verbs.c384
-rw-r--r--drivers/infiniband/hw/hfi1/verbs.h59
-rw-r--r--drivers/infiniband/hw/hfi1/verbs_txreq.c11
-rw-r--r--drivers/infiniband/hw/hfi1/vnic.h16
-rw-r--r--drivers/infiniband/hw/hfi1/vnic_main.c39
-rw-r--r--drivers/infiniband/hw/hfi1/vnic_sdma.c27
-rw-r--r--drivers/infiniband/hw/hns/Kconfig2
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_alloc.c1
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_eq.c3
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_hw_v1.c3
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_mr.c1
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_qp.c2
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_cm.c27
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_ctrl.c11
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_main.c1
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_p.h14
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_pble.c9
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_puda.c6
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_type.h5
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_uk.c6
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_utils.c22
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_verbs.c7
-rw-r--r--drivers/infiniband/hw/mlx4/alias_GUID.c4
-rw-r--r--drivers/infiniband/hw/mlx4/cq.c4
-rw-r--r--drivers/infiniband/hw/mlx4/mad.c8
-rw-r--r--drivers/infiniband/hw/mlx4/main.c54
-rw-r--r--drivers/infiniband/hw/mlx4/mcg.c9
-rw-r--r--drivers/infiniband/hw/mlx4/mlx4_ib.h42
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c1054
-rw-r--r--drivers/infiniband/hw/mlx4/srq.c17
-rw-r--r--drivers/infiniband/hw/mlx5/Makefile2
-rw-r--r--drivers/infiniband/hw/mlx5/cmd.c20
-rw-r--r--drivers/infiniband/hw/mlx5/cmd.h4
-rw-r--r--drivers/infiniband/hw/mlx5/cong.c421
-rw-r--r--drivers/infiniband/hw/mlx5/cq.c8
-rw-r--r--drivers/infiniband/hw/mlx5/ib_virt.c9
-rw-r--r--drivers/infiniband/hw/mlx5/mad.c4
-rw-r--r--drivers/infiniband/hw/mlx5/main.c458
-rw-r--r--drivers/infiniband/hw/mlx5/mlx5_ib.h86
-rw-r--r--drivers/infiniband/hw/mlx5/mr.c121
-rw-r--r--drivers/infiniband/hw/mlx5/qp.c171
-rw-r--r--drivers/infiniband/hw/mlx5/srq.c33
-rw-r--r--drivers/infiniband/hw/mthca/mthca_av.c10
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.c14
-rw-r--r--drivers/infiniband/hw/mthca/mthca_dev.h4
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mad.c4
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c3
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c7
-rw-r--r--drivers/infiniband/hw/nes/nes.c70
-rw-r--r--drivers/infiniband/hw/nes/nes_verbs.c10
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma_main.c6
-rw-r--r--drivers/infiniband/hw/qedr/main.c7
-rw-r--r--drivers/infiniband/hw/qedr/qedr.h3
-rw-r--r--drivers/infiniband/hw/qedr/verbs.c5
-rw-r--r--drivers/infiniband/hw/qib/qib.h8
-rw-r--r--drivers/infiniband/hw/qib/qib_debugfs.c18
-rw-r--r--drivers/infiniband/hw/qib/qib_driver.c1
-rw-r--r--drivers/infiniband/hw/qib/qib_iba6120.c26
-rw-r--r--drivers/infiniband/hw/qib/qib_iba7220.c29
-rw-r--r--drivers/infiniband/hw/qib/qib_iba7322.c92
-rw-r--r--drivers/infiniband/hw/qib/qib_init.c3
-rw-r--r--drivers/infiniband/hw/qib/qib_mad.c23
-rw-r--r--drivers/infiniband/hw/qib/qib_pcie.c149
-rw-r--r--drivers/infiniband/hw/qib/qib_qp.c51
-rw-r--r--drivers/infiniband/hw/qib/qib_rc.c4
-rw-r--r--drivers/infiniband/hw/qib/qib_ruc.c32
-rw-r--r--drivers/infiniband/hw/qib/qib_sysfs.c4
-rw-r--r--drivers/infiniband/hw/qib/qib_ud.c43
-rw-r--r--drivers/infiniband/hw/qib/qib_verbs.c9
-rw-r--r--drivers/infiniband/hw/qib/qib_verbs.h14
-rw-r--r--drivers/infiniband/hw/usnic/usnic_fwd.c12
-rw-r--r--drivers/infiniband/hw/usnic/usnic_fwd.h2
-rw-r--r--drivers/infiniband/hw/usnic/usnic_ib_main.c18
-rw-r--r--drivers/infiniband/hw/usnic/usnic_ib_verbs.c43
-rw-r--r--drivers/infiniband/hw/usnic/usnic_ib_verbs.h1
-rw-r--r--drivers/infiniband/hw/vmw_pvrdma/pvrdma.h2
-rw-r--r--drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c3
-rw-r--r--drivers/infiniband/hw/vmw_pvrdma/pvrdma_dev_api.h37
-rw-r--r--drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c44
-rw-r--r--drivers/infiniband/hw/vmw_pvrdma/pvrdma_misc.c7
-rw-r--r--drivers/infiniband/hw/vmw_pvrdma/pvrdma_ring.h17
-rw-r--r--drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c9
-rw-r--r--drivers/infiniband/sw/rdmavt/ah.c10
-rw-r--r--drivers/infiniband/sw/rdmavt/cq.c2
-rw-r--r--drivers/infiniband/sw/rdmavt/mr.c170
-rw-r--r--drivers/infiniband/sw/rdmavt/qp.c348
-rw-r--r--drivers/infiniband/sw/rdmavt/trace_mr.h62
-rw-r--r--drivers/infiniband/sw/rdmavt/trace_tx.h11
-rw-r--r--drivers/infiniband/sw/rdmavt/vt.c9
-rw-r--r--drivers/infiniband/sw/rxe/rxe.c1
-rw-r--r--drivers/infiniband/sw/rxe/rxe.h2
-rw-r--r--drivers/infiniband/sw/rxe/rxe_av.c7
-rw-r--r--drivers/infiniband/sw/rxe/rxe_cq.c19
-rw-r--r--drivers/infiniband/sw/rxe/rxe_hw_counters.c2
-rw-r--r--drivers/infiniband/sw/rxe/rxe_loc.h6
-rw-r--r--drivers/infiniband/sw/rxe/rxe_mmap.c2
-rw-r--r--drivers/infiniband/sw/rxe/rxe_mr.c12
-rw-r--r--drivers/infiniband/sw/rxe/rxe_net.c26
-rw-r--r--drivers/infiniband/sw/rxe/rxe_pool.c2
-rw-r--r--drivers/infiniband/sw/rxe/rxe_qp.c9
-rw-r--r--drivers/infiniband/sw/rxe/rxe_req.c6
-rw-r--r--drivers/infiniband/sw/rxe/rxe_resp.c2
-rw-r--r--drivers/infiniband/sw/rxe/rxe_task.c4
-rw-r--r--drivers/infiniband/sw/rxe/rxe_verbs.c67
-rw-r--r--drivers/infiniband/sw/rxe/rxe_verbs.h2
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h3
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c8
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ethtool.c3
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c31
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_vlan.c22
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.c1
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c6
-rw-r--r--drivers/infiniband/ulp/isert/ib_isert.c1
-rw-r--r--drivers/infiniband/ulp/opa_vnic/opa_vnic_vema.c35
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c1
-rw-r--r--drivers/infiniband/ulp/srpt/ib_srpt.c5
-rw-r--r--drivers/infiniband/ulp/srpt/ib_srpt.h4
-rw-r--r--drivers/input/joystick/xpad.c24
-rw-r--r--drivers/input/keyboard/gpio_keys.c16
-rw-r--r--drivers/input/keyboard/hilkbd.c10
-rw-r--r--drivers/input/misc/axp20x-pek.c18
-rw-r--r--drivers/input/mouse/synaptics.c35
-rw-r--r--drivers/input/rmi4/rmi_f01.c11
-rw-r--r--drivers/input/serio/gscps2.c10
-rw-r--r--drivers/input/serio/hp_sdc.c4
-rw-r--r--drivers/iommu/amd_iommu.c30
-rw-r--r--drivers/iommu/amd_iommu_init.c34
-rw-r--r--drivers/iommu/amd_iommu_proto.h10
-rw-r--r--drivers/iommu/amd_iommu_types.h2
-rw-r--r--drivers/iommu/amd_iommu_v2.c8
-rw-r--r--drivers/iommu/intel-svm.c9
-rw-r--r--drivers/irqchip/Kconfig15
-rw-r--r--drivers/irqchip/Makefile3
-rw-r--r--drivers/irqchip/irq-armada-370-xp.c5
-rw-r--r--drivers/irqchip/irq-bcm2835.c9
-rw-r--r--drivers/irqchip/irq-bcm2836.c5
-rw-r--r--drivers/irqchip/irq-bcm6345-l1.c3
-rw-r--r--drivers/irqchip/irq-bcm7038-l1.c3
-rw-r--r--drivers/irqchip/irq-bcm7120-l2.c10
-rw-r--r--drivers/irqchip/irq-crossbar.c6
-rw-r--r--drivers/irqchip/irq-digicolor.c8
-rw-r--r--drivers/irqchip/irq-dw-apb-ictl.c12
-rw-r--r--drivers/irqchip/irq-gic-v3-its-pci-msi.c2
-rw-r--r--drivers/irqchip/irq-gic-v3-its.c1496
-rw-r--r--drivers/irqchip/irq-gic-v3.c109
-rw-r--r--drivers/irqchip/irq-gic-v4.c225
-rw-r--r--drivers/irqchip/irq-gic.c5
-rw-r--r--drivers/irqchip/irq-hip04.c3
-rw-r--r--drivers/irqchip/irq-imx-gpcv2.c4
-rw-r--r--drivers/irqchip/irq-lpc32xx.c2
-rw-r--r--drivers/irqchip/irq-ls-scfg-msi.c256
-rw-r--r--drivers/irqchip/irq-metag-ext.c4
-rw-r--r--drivers/irqchip/irq-mips-gic.c15
-rw-r--r--drivers/irqchip/irq-mmp.c4
-rw-r--r--drivers/irqchip/irq-mtk-sysirq.c3
-rw-r--r--drivers/irqchip/irq-mxs.c4
-rw-r--r--drivers/irqchip/irq-stm32-exti.c8
-rw-r--r--drivers/irqchip/irq-sun4i.c6
-rw-r--r--drivers/irqchip/irq-tegra.c16
-rw-r--r--drivers/irqchip/irq-uniphier-aidet.c261
-rw-r--r--drivers/irqchip/irq-xilinx-intc.c4
-rw-r--r--drivers/irqchip/irq-xtensa-mx.c6
-rw-r--r--drivers/lguest/Kconfig13
-rw-r--r--drivers/lguest/Makefile26
-rw-r--r--drivers/lguest/README47
-rw-r--r--drivers/lguest/core.c398
-rw-r--r--drivers/lguest/hypercalls.c304
-rw-r--r--drivers/lguest/interrupts_and_traps.c706
-rw-r--r--drivers/lguest/lg.h258
-rw-r--r--drivers/lguest/lguest_user.c446
-rw-r--r--drivers/lguest/page_tables.c1239
-rw-r--r--drivers/lguest/segments.c228
-rw-r--r--drivers/lguest/x86/core.c724
-rw-r--r--drivers/lguest/x86/switcher_32.S388
-rw-r--r--drivers/mcb/mcb-core.c20
-rw-r--r--drivers/md/dm-mpath.c2
-rw-r--r--drivers/md/dm.c12
-rw-r--r--drivers/media/platform/vsp1/vsp1.h7
-rw-r--r--drivers/media/platform/vsp1/vsp1_bru.c45
-rw-r--r--drivers/media/platform/vsp1/vsp1_bru.h4
-rw-r--r--drivers/media/platform/vsp1/vsp1_dl.c205
-rw-r--r--drivers/media/platform/vsp1/vsp1_dl.h1
-rw-r--r--drivers/media/platform/vsp1/vsp1_drm.c286
-rw-r--r--drivers/media/platform/vsp1/vsp1_drm.h38
-rw-r--r--drivers/media/platform/vsp1/vsp1_drv.c115
-rw-r--r--drivers/media/platform/vsp1/vsp1_entity.c40
-rw-r--r--drivers/media/platform/vsp1/vsp1_entity.h5
-rw-r--r--drivers/media/platform/vsp1/vsp1_lif.c5
-rw-r--r--drivers/media/platform/vsp1/vsp1_lif.h2
-rw-r--r--drivers/media/platform/vsp1/vsp1_pipe.c27
-rw-r--r--drivers/media/platform/vsp1/vsp1_pipe.h2
-rw-r--r--drivers/media/platform/vsp1/vsp1_regs.h46
-rw-r--r--drivers/media/platform/vsp1/vsp1_video.c69
-rw-r--r--drivers/media/platform/vsp1/vsp1_wpf.c4
-rw-r--r--drivers/mfd/da9052-core.c26
-rw-r--r--drivers/misc/mic/scif/scif_dma.c11
-rw-r--r--drivers/misc/sgi-gru/grutlbpurge.c12
-rw-r--r--drivers/mmc/core/block.c6
-rw-r--r--drivers/mmc/host/sdhci-xenon.c19
-rw-r--r--drivers/net/Kconfig2
-rw-r--r--drivers/net/dsa/bcm_sf2.c4
-rw-r--r--drivers/net/dsa/bcm_sf2.h1
-rw-r--r--drivers/net/dsa/bcm_sf2_cfp.c8
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_main.c27
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_hw.h3
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_nic.c92
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_ring.c1
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_utils.h1
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_vec.c11
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c6
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c6
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c10
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h3
-rw-r--r--drivers/net/ethernet/broadcom/bcmsysport.c4
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.c41
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c2
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmgenet.c6
-rw-r--r--drivers/net/ethernet/cavium/liquidio/lio_main.c2
-rw-r--r--drivers/net/ethernet/cavium/liquidio/octeon_droq.h2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_hw.c6
-rw-r--r--drivers/net/ethernet/faraday/ftgmac100.c1
-rw-r--r--drivers/net/ethernet/freescale/fman/mac.c2
-rw-r--r--drivers/net/ethernet/i825xx/lasi_82596.c10
-rw-r--r--drivers/net/ethernet/marvell/mvpp2.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cmd.c10
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cq.c7
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_cq.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_rx.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_tx.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c7
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/qp.c5
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/cmd.c11
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c24
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_main.c58
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_rx.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c13
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_tc.c8
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_tx.c17
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eq.c32
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eswitch.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fw.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/health.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/main.c129
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/qp.c14
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/sriov.c42
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/srq.c162
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/vport.c62
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c15
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/match.c139
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/offload.c60
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_main.c16
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net_common.c14
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net_main.c26
-rw-r--r--drivers/net/ethernet/qlogic/qlge/qlge_dbg.c2
-rw-r--r--drivers/net/ethernet/realtek/r8169.c5
-rw-r--r--drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c2
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c5
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c8
-rw-r--r--drivers/net/ethernet/ti/cpsw-common.c2
-rw-r--r--drivers/net/hyperv/netvsc_drv.c7
-rw-r--r--drivers/net/macsec.c1
-rw-r--r--drivers/net/phy/phy.c3
-rw-r--r--drivers/net/phy/phy_device.c6
-rw-r--r--drivers/net/usb/cdc_ncm.c7
-rw-r--r--drivers/net/virtio_net.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/internal.h2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/rx.c10
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/trans.c9
-rw-r--r--drivers/net/wireless/ti/wl1251/main.c1
-rw-r--r--drivers/nvme/host/pci.c22
-rw-r--r--drivers/nvme/host/rdma.c42
-rw-r--r--drivers/nvme/target/rdma.c5
-rw-r--r--drivers/parisc/asp.c4
-rw-r--r--drivers/parisc/ccio-dma.c4
-rw-r--r--drivers/parisc/ccio-rm-dma.c6
-rw-r--r--drivers/parisc/dino.c4
-rw-r--r--drivers/parisc/eisa.c4
-rw-r--r--drivers/parisc/hppb.c6
-rw-r--r--drivers/parisc/lasi.c4
-rw-r--r--drivers/parisc/lba_pci.c46
-rw-r--r--drivers/parisc/sba_iommu.c6
-rw-r--r--drivers/parisc/superio.c4
-rw-r--r--drivers/parisc/wax.c4
-rw-r--r--drivers/parport/parport_gsc.c10
-rw-r--r--drivers/pci/pci-driver.c1
-rw-r--r--drivers/perf/arm_pmu.c6
-rw-r--r--drivers/perf/xgene_pmu.c74
-rw-r--r--drivers/phy/Kconfig10
-rw-r--r--drivers/phy/Makefile3
-rw-r--r--drivers/phy/allwinner/phy-sun4i-usb.c112
-rw-r--r--drivers/phy/broadcom/phy-brcm-sata.c2
-rw-r--r--drivers/phy/mediatek/Kconfig14
-rw-r--r--drivers/phy/mediatek/Makefile5
-rw-r--r--drivers/phy/mediatek/phy-mtk-tphy.c (renamed from drivers/phy/phy-mt65xx-usb3.c)557
-rw-r--r--drivers/phy/motorola/phy-cpcap-usb.c2
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp.c162
-rw-r--r--drivers/phy/ralink/Kconfig11
-rw-r--r--drivers/phy/ralink/Makefile1
-rw-r--r--drivers/phy/ralink/phy-ralink-usb.c249
-rw-r--r--drivers/phy/rockchip/phy-rockchip-inno-usb2.c215
-rw-r--r--drivers/phy/rockchip/phy-rockchip-typec.c3
-rw-r--r--drivers/phy/samsung/phy-exynos-dp-video.c5
-rw-r--r--drivers/phy/samsung/phy-exynos5-usbdrd.c7
-rw-r--r--drivers/phy/samsung/phy-samsung-usb2.c9
-rw-r--r--drivers/phy/ti/phy-ti-pipe3.c10
-rw-r--r--drivers/phy/ti/phy-twl4030-usb.c2
-rw-r--r--drivers/power/supply/wm831x_power.c72
-rw-r--r--drivers/s390/block/dasd.c55
-rw-r--r--drivers/s390/block/dasd_3990_erp.c2
-rw-r--r--drivers/s390/block/dasd_devmap.c3
-rw-r--r--drivers/s390/block/dasd_diag.c2
-rw-r--r--drivers/s390/block/dasd_eckd.c8
-rw-r--r--drivers/s390/block/dasd_eckd.h2
-rw-r--r--drivers/s390/block/dasd_erp.c2
-rw-r--r--drivers/s390/block/dasd_fba.c202
-rw-r--r--drivers/s390/block/dasd_int.h19
-rw-r--r--drivers/s390/block/dasd_proc.c2
-rw-r--r--drivers/s390/block/scm_blk.c13
-rw-r--r--drivers/s390/char/Kconfig11
-rw-r--r--drivers/s390/char/raw3270.c2
-rw-r--r--drivers/s390/char/sclp_cmd.c1
-rw-r--r--drivers/s390/char/sclp_config.c2
-rw-r--r--drivers/s390/char/sclp_early.c6
-rw-r--r--drivers/s390/char/sclp_ocf.c2
-rw-r--r--drivers/s390/char/tape_core.c2
-rw-r--r--drivers/s390/char/vmcp.c112
-rw-r--r--drivers/s390/char/vmcp.h30
-rw-r--r--drivers/s390/cio/chp.c4
-rw-r--r--drivers/s390/cio/device.c4
-rw-r--r--drivers/s390/cio/vfio_ccw_cp.c2
-rw-r--r--drivers/s390/crypto/zcrypt_card.c2
-rw-r--r--drivers/s390/crypto/zcrypt_msgtype6.c2
-rw-r--r--drivers/s390/crypto/zcrypt_queue.c2
-rw-r--r--drivers/s390/net/qeth_l3_sys.c8
-rw-r--r--drivers/scsi/ipr.c1
-rw-r--r--drivers/scsi/lasi700.c6
-rw-r--r--drivers/scsi/qedf/qedf_els.c14
-rw-r--r--drivers/scsi/sg.c2
-rw-r--r--drivers/scsi/zalon.c8
-rw-r--r--drivers/sfi/sfi_core.c23
-rw-r--r--drivers/staging/Kconfig4
-rw-r--r--drivers/staging/Makefile2
-rw-r--r--drivers/staging/android/ion/ion.h12
-rw-r--r--drivers/staging/android/ion/ion_cma_heap.c5
-rw-r--r--drivers/staging/android/ion/ion_system_heap.c2
-rw-r--r--drivers/staging/ccree/Kconfig9
-rw-r--r--drivers/staging/ccree/Makefile2
-rw-r--r--drivers/staging/ccree/cc_hw_queue_defs.h3
-rw-r--r--drivers/staging/ccree/ssi_aead.c246
-rw-r--r--drivers/staging/ccree/ssi_aead.h12
-rw-r--r--drivers/staging/ccree/ssi_buffer_mgr.c473
-rw-r--r--drivers/staging/ccree/ssi_cipher.c185
-rw-r--r--drivers/staging/ccree/ssi_driver.c64
-rw-r--r--drivers/staging/ccree/ssi_driver.h1
-rw-r--r--drivers/staging/ccree/ssi_fips.c119
-rw-r--r--drivers/staging/ccree/ssi_fips.h58
-rw-r--r--drivers/staging/ccree/ssi_fips_data.h306
-rw-r--r--drivers/staging/ccree/ssi_fips_ext.c92
-rw-r--r--drivers/staging/ccree/ssi_fips_ll.c1649
-rw-r--r--drivers/staging/ccree/ssi_fips_local.c357
-rw-r--r--drivers/staging/ccree/ssi_fips_local.h67
-rw-r--r--drivers/staging/ccree/ssi_hash.c276
-rw-r--r--drivers/staging/ccree/ssi_ivgen.c13
-rw-r--r--drivers/staging/ccree/ssi_pm.c4
-rw-r--r--drivers/staging/ccree/ssi_request_mgr.c54
-rw-r--r--drivers/staging/ccree/ssi_sram_mgr.c6
-rw-r--r--drivers/staging/ccree/ssi_sysfs.c80
-rw-r--r--drivers/staging/comedi/comedi_buf.c2
-rw-r--r--drivers/staging/comedi/comedi_fops.c2
-rw-r--r--drivers/staging/comedi/drivers.c4
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_common.c3
-rw-r--r--drivers/staging/fbtft/fb_st7789v.c2
-rw-r--r--drivers/staging/fbtft/fbtft-core.c4
-rw-r--r--drivers/staging/fsl-dpaa2/Kconfig2
-rw-r--r--drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c6
-rw-r--r--drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h4
-rw-r--r--drivers/staging/fsl-dpaa2/ethernet/dpaa2-ethtool.c2
-rw-r--r--drivers/staging/fsl-dpaa2/ethernet/dpni.c2
-rw-r--r--drivers/staging/fsl-mc/bus/Kconfig4
-rw-r--r--drivers/staging/fsl-mc/bus/dpio/qbman-portal.c24
-rw-r--r--drivers/staging/fsl-mc/bus/dprc-driver.c5
-rw-r--r--drivers/staging/fsl-mc/bus/fsl-mc-bus.c4
-rw-r--r--drivers/staging/fsl-mc/bus/fsl-mc-msi.c9
-rw-r--r--drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c11
-rw-r--r--drivers/staging/fsl-mc/bus/mc-io.c11
-rw-r--r--drivers/staging/fsl-mc/bus/mc-sys.c36
-rw-r--r--drivers/staging/fsl-mc/include/dpaa2-io.h1
-rw-r--r--drivers/staging/goldfish/goldfish_nand.c24
-rw-r--r--drivers/staging/greybus/arche-platform.c14
-rw-r--r--drivers/staging/greybus/audio_codec.c2
-rw-r--r--drivers/staging/greybus/gbphy.c2
-rw-r--r--drivers/staging/greybus/interface.c40
-rw-r--r--drivers/staging/greybus/spilib.h3
-rw-r--r--drivers/staging/greybus/tools/loopback_test.c48
-rw-r--r--drivers/staging/greybus/usb.c2
-rw-r--r--drivers/staging/greybus/vibrator.c8
-rw-r--r--drivers/staging/gs_fpgaboot/gs_fpgaboot.c90
-rw-r--r--drivers/staging/gs_fpgaboot/gs_fpgaboot.h2
-rw-r--r--drivers/staging/gs_fpgaboot/io.c4
-rw-r--r--drivers/staging/iio/adc/ad7280a.c21
-rw-r--r--drivers/staging/iio/adc/ad7606_par.c4
-rw-r--r--drivers/staging/iio/light/tsl2x7x.c372
-rw-r--r--drivers/staging/ks7010/ks7010_sdio.c4
-rw-r--r--drivers/staging/ks7010/ks_hostif.c4
-rw-r--r--drivers/staging/ks7010/ks_wlan_net.c2
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/libcfs.h28
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h104
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/libcfs_private.h26
-rw-r--r--drivers/staging/lustre/include/linux/lnet/api.h2
-rw-r--r--drivers/staging/lustre/include/linux/lnet/lib-lnet.h15
-rw-r--r--drivers/staging/lustre/include/linux/lnet/lib-types.h50
-rw-r--r--drivers/staging/lustre/include/linux/lnet/socklnd.h15
-rw-r--r--drivers/staging/lustre/include/uapi/linux/lnet/libcfs_debug.h149
-rw-r--r--drivers/staging/lustre/include/uapi/linux/lnet/libcfs_ioctl.h (renamed from drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h)0
-rw-r--r--drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h (renamed from drivers/staging/lustre/include/linux/lnet/lib-dlc.h)4
-rw-r--r--drivers/staging/lustre/include/uapi/linux/lnet/lnet-types.h (renamed from drivers/staging/lustre/include/linux/lnet/types.h)0
-rw-r--r--drivers/staging/lustre/include/uapi/linux/lnet/lnetctl.h (renamed from drivers/staging/lustre/include/linux/lnet/lnetctl.h)51
-rw-r--r--drivers/staging/lustre/include/uapi/linux/lnet/lnetst.h (renamed from drivers/staging/lustre/include/linux/lnet/lnetst.h)129
-rw-r--r--drivers/staging/lustre/include/uapi/linux/lnet/nidstr.h (renamed from drivers/staging/lustre/include/linux/lnet/nidstr.h)2
-rw-r--r--drivers/staging/lustre/include/uapi/linux/lnet/socklnd.h (renamed from drivers/staging/lustre/include/linux/lnet/lnet.h)24
-rw-r--r--drivers/staging/lustre/include/uapi/linux/lustre/lustre_cfg.h (renamed from drivers/staging/lustre/lustre/include/lustre_cfg.h)188
-rw-r--r--drivers/staging/lustre/include/uapi/linux/lustre/lustre_fid.h293
-rw-r--r--drivers/staging/lustre/include/uapi/linux/lustre/lustre_fiemap.h (renamed from drivers/staging/lustre/lustre/include/lustre/ll_fiemap.h)6
-rw-r--r--drivers/staging/lustre/include/uapi/linux/lustre/lustre_idl.h (renamed from drivers/staging/lustre/lustre/include/lustre/lustre_idl.h)689
-rw-r--r--drivers/staging/lustre/include/uapi/linux/lustre/lustre_ioctl.h (renamed from drivers/staging/lustre/lustre/include/lustre/lustre_ioctl.h)203
-rw-r--r--drivers/staging/lustre/include/uapi/linux/lustre/lustre_kernelcomm.h (renamed from drivers/staging/lustre/lustre/include/uapi_kernelcomm.h)6
-rw-r--r--drivers/staging/lustre/include/uapi/linux/lustre/lustre_ostid.h236
-rw-r--r--drivers/staging/lustre/include/uapi/linux/lustre/lustre_param.h94
-rw-r--r--drivers/staging/lustre/include/uapi/linux/lustre/lustre_user.h (renamed from drivers/staging/lustre/lustre/include/lustre/lustre_user.h)15
-rw-r--r--drivers/staging/lustre/include/uapi/linux/lustre/lustre_ver.h (renamed from drivers/staging/lustre/lustre/include/lustre_ver.h)0
-rw-r--r--drivers/staging/lustre/lnet/klnds/o2iblnd/Makefile3
-rw-r--r--drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c2
-rw-r--r--drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h5
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/Makefile3
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h18
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c20
-rw-r--r--drivers/staging/lustre/lnet/libcfs/Makefile3
-rw-r--r--drivers/staging/lustre/lnet/libcfs/debug.c2
-rw-r--r--drivers/staging/lustre/lnet/libcfs/fail.c2
-rw-r--r--drivers/staging/lustre/lnet/libcfs/hash.c49
-rw-r--r--drivers/staging/lustre/lnet/libcfs/libcfs_cpu.c2
-rw-r--r--drivers/staging/lustre/lnet/libcfs/libcfs_lock.c2
-rw-r--r--drivers/staging/lustre/lnet/libcfs/libcfs_mem.c2
-rw-r--r--drivers/staging/lustre/lnet/libcfs/libcfs_string.c2
-rw-r--r--drivers/staging/lustre/lnet/libcfs/linux/linux-cpu.c2
-rw-r--r--drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c4
-rw-r--r--drivers/staging/lustre/lnet/libcfs/linux/linux-curproc.c2
-rw-r--r--drivers/staging/lustre/lnet/libcfs/linux/linux-debug.c2
-rw-r--r--drivers/staging/lustre/lnet/libcfs/linux/linux-mem.c2
-rw-r--r--drivers/staging/lustre/lnet/libcfs/linux/linux-module.c4
-rw-r--r--drivers/staging/lustre/lnet/libcfs/linux/linux-prim.c2
-rw-r--r--drivers/staging/lustre/lnet/libcfs/linux/linux-tracefile.c2
-rw-r--r--drivers/staging/lustre/lnet/libcfs/module.c9
-rw-r--r--drivers/staging/lustre/lnet/libcfs/prng.c2
-rw-r--r--drivers/staging/lustre/lnet/libcfs/tracefile.c2
-rw-r--r--drivers/staging/lustre/lnet/libcfs/tracefile.h2
-rw-r--r--drivers/staging/lustre/lnet/libcfs/workitem.c2
-rw-r--r--drivers/staging/lustre/lnet/lnet/Makefile3
-rw-r--r--drivers/staging/lustre/lnet/lnet/acceptor.c2
-rw-r--r--drivers/staging/lustre/lnet/lnet/api-ni.c4
-rw-r--r--drivers/staging/lustre/lnet/lnet/config.c2
-rw-r--r--drivers/staging/lustre/lnet/lnet/lib-eq.c3
-rw-r--r--drivers/staging/lustre/lnet/lnet/lib-md.c2
-rw-r--r--drivers/staging/lustre/lnet/lnet/lib-me.c2
-rw-r--r--drivers/staging/lustre/lnet/lnet/lib-move.c6
-rw-r--r--drivers/staging/lustre/lnet/lnet/lib-msg.c2
-rw-r--r--drivers/staging/lustre/lnet/lnet/lib-ptl.c2
-rw-r--r--drivers/staging/lustre/lnet/lnet/lib-socket.c4
-rw-r--r--drivers/staging/lustre/lnet/lnet/lo.c3
-rw-r--r--drivers/staging/lustre/lnet/lnet/module.c5
-rw-r--r--drivers/staging/lustre/lnet/lnet/net_fault.c4
-rw-r--r--drivers/staging/lustre/lnet/lnet/nidstrings.c4
-rw-r--r--drivers/staging/lustre/lnet/lnet/peer.c4
-rw-r--r--drivers/staging/lustre/lnet/lnet/router.c3
-rw-r--r--drivers/staging/lustre/lnet/lnet/router_proc.c5
-rw-r--r--drivers/staging/lustre/lnet/selftest/Makefile3
-rw-r--r--drivers/staging/lustre/lnet/selftest/conctl.c8
-rw-r--r--drivers/staging/lustre/lnet/selftest/conrpc.c9
-rw-r--r--drivers/staging/lustre/lnet/selftest/conrpc.h7
-rw-r--r--drivers/staging/lustre/lnet/selftest/console.c4
-rw-r--r--drivers/staging/lustre/lnet/selftest/console.h7
-rw-r--r--drivers/staging/lustre/lnet/selftest/rpc.h2
-rw-r--r--drivers/staging/lustre/lnet/selftest/selftest.h9
-rw-r--r--drivers/staging/lustre/lustre/Kconfig10
-rw-r--r--drivers/staging/lustre/lustre/fid/Makefile3
-rw-r--r--drivers/staging/lustre/lustre/fid/fid_internal.h4
-rw-r--r--drivers/staging/lustre/lustre/fid/fid_lib.c5
-rw-r--r--drivers/staging/lustre/lustre/fid/fid_request.c12
-rw-r--r--drivers/staging/lustre/lustre/fid/lproc_fid.c12
-rw-r--r--drivers/staging/lustre/lustre/fld/Makefile3
-rw-r--r--drivers/staging/lustre/lustre/fld/fld_cache.c19
-rw-r--r--drivers/staging/lustre/lustre/fld/fld_internal.h8
-rw-r--r--drivers/staging/lustre/lustre/fld/fld_request.c18
-rw-r--r--drivers/staging/lustre/lustre/fld/lproc_fld.c14
-rw-r--r--drivers/staging/lustre/lustre/include/cl_object.h6
-rw-r--r--drivers/staging/lustre/lustre/include/interval_tree.h4
-rw-r--r--drivers/staging/lustre/lustre/include/llog_swab.h3
-rw-r--r--drivers/staging/lustre/lustre/include/lprocfs_status.h10
-rw-r--r--drivers/staging/lustre/lustre/include/lu_object.h6
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_compat.h2
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_debug.h4
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_disk.h23
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_dlm.h25
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_errno.h (renamed from drivers/staging/lustre/lustre/include/lustre/lustre_errno.h)0
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_export.h6
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_fid.h84
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_fld.h5
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_handles.h2
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_import.h4
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_kernelcomm.h2
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_lib.h12
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_linkea.h15
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_lmv.h2
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_log.h4
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_mdc.h15
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_mds.h11
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_net.h39
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_nrs.h2
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_obdo.h2
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_param.h109
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_swab.h8
-rw-r--r--drivers/staging/lustre/lustre/include/obd.h20
-rw-r--r--drivers/staging/lustre/lustre/include/obd_cksum.h6
-rw-r--r--drivers/staging/lustre/lustre/include/obd_class.h44
-rw-r--r--drivers/staging/lustre/lustre/include/obd_support.h6
-rw-r--r--drivers/staging/lustre/lustre/include/seq_range.h2
-rw-r--r--drivers/staging/lustre/lustre/ldlm/interval_tree.c46
-rw-r--r--drivers/staging/lustre/lustre/ldlm/l_lock.c6
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_extent.c12
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_flock.c12
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_inodebits.c6
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_internal.h9
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_lib.c12
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_lock.c17
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c10
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_plain.c6
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_pool.c8
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_request.c36
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_resource.c53
-rw-r--r--drivers/staging/lustre/lustre/llite/Makefile3
-rw-r--r--drivers/staging/lustre/lustre/llite/dcache.c6
-rw-r--r--drivers/staging/lustre/lustre/llite/dir.c22
-rw-r--r--drivers/staging/lustre/lustre/llite/file.c13
-rw-r--r--drivers/staging/lustre/lustre/llite/glimpse.c16
-rw-r--r--drivers/staging/lustre/lustre/llite/lcommon_cl.c35
-rw-r--r--drivers/staging/lustre/lustre/llite/lcommon_misc.c8
-rw-r--r--drivers/staging/lustre/lustre/llite/llite_internal.h20
-rw-r--r--drivers/staging/lustre/lustre/llite/llite_lib.c27
-rw-r--r--drivers/staging/lustre/lustre/llite/lproc_llite.c4
-rw-r--r--drivers/staging/lustre/lustre/llite/namei.c9
-rw-r--r--drivers/staging/lustre/lustre/llite/range_lock.c2
-rw-r--r--drivers/staging/lustre/lustre/llite/range_lock.h4
-rw-r--r--drivers/staging/lustre/lustre/llite/rw.c4
-rw-r--r--drivers/staging/lustre/lustre/llite/statahead.c4
-rw-r--r--drivers/staging/lustre/lustre/llite/super25.c6
-rw-r--r--drivers/staging/lustre/lustre/llite/vvp_dev.c7
-rw-r--r--drivers/staging/lustre/lustre/llite/vvp_internal.h4
-rw-r--r--drivers/staging/lustre/lustre/llite/vvp_io.c2
-rw-r--r--drivers/staging/lustre/lustre/llite/vvp_lock.c2
-rw-r--r--drivers/staging/lustre/lustre/llite/vvp_object.c4
-rw-r--r--drivers/staging/lustre/lustre/llite/xattr.c6
-rw-r--r--drivers/staging/lustre/lustre/llite/xattr_cache.c5
-rw-r--r--drivers/staging/lustre/lustre/llite/xattr_security.c23
-rw-r--r--drivers/staging/lustre/lustre/lmv/Makefile3
-rw-r--r--drivers/staging/lustre/lustre/lmv/lmv_fld.c15
-rw-r--r--drivers/staging/lustre/lustre/lmv/lmv_intent.c22
-rw-r--r--drivers/staging/lustre/lustre/lmv/lmv_internal.h8
-rw-r--r--drivers/staging/lustre/lustre/lmv/lmv_obd.c184
-rw-r--r--drivers/staging/lustre/lustre/lmv/lproc_lmv.c6
-rw-r--r--drivers/staging/lustre/lustre/lov/Makefile5
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_cl_internal.h96
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_dev.c87
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_ea.c29
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_internal.h31
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_io.c152
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_lock.c15
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_merge.c4
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_obd.c43
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_object.c469
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_offset.c4
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_pack.c13
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_page.c1
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_pool.c4
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_request.c46
-rw-r--r--drivers/staging/lustre/lustre/lov/lovsub_dev.c1
-rw-r--r--drivers/staging/lustre/lustre/lov/lovsub_io.c51
-rw-r--r--drivers/staging/lustre/lustre/lov/lovsub_lock.c2
-rw-r--r--drivers/staging/lustre/lustre/lov/lproc_lov.c6
-rw-r--r--drivers/staging/lustre/lustre/mdc/Makefile3
-rw-r--r--drivers/staging/lustre/lustre/mdc/lproc_mdc.c8
-rw-r--r--drivers/staging/lustre/lustre/mdc/mdc_internal.h2
-rw-r--r--drivers/staging/lustre/lustre/mdc/mdc_lib.c10
-rw-r--r--drivers/staging/lustre/lustre/mdc/mdc_locks.c26
-rw-r--r--drivers/staging/lustre/lustre/mdc/mdc_reint.c4
-rw-r--r--drivers/staging/lustre/lustre/mdc/mdc_request.c25
-rw-r--r--drivers/staging/lustre/lustre/mgc/Makefile3
-rw-r--r--drivers/staging/lustre/lustre/mgc/lproc_mgc.c4
-rw-r--r--drivers/staging/lustre/lustre/mgc/mgc_internal.h11
-rw-r--r--drivers/staging/lustre/lustre/mgc/mgc_request.c39
-rw-r--r--drivers/staging/lustre/lustre/obdclass/Makefile3
-rw-r--r--drivers/staging/lustre/lustre/obdclass/cl_io.c8
-rw-r--r--drivers/staging/lustre/lustre/obdclass/cl_lock.c8
-rw-r--r--drivers/staging/lustre/lustre/obdclass/cl_object.c14
-rw-r--r--drivers/staging/lustre/lustre/obdclass/cl_page.c8
-rw-r--r--drivers/staging/lustre/lustre/obdclass/class_obd.c41
-rw-r--r--drivers/staging/lustre/lustre/obdclass/debug.c6
-rw-r--r--drivers/staging/lustre/lustre/obdclass/genops.c6
-rw-r--r--drivers/staging/lustre/lustre/obdclass/kernelcomm.c4
-rw-r--r--drivers/staging/lustre/lustre/obdclass/linkea.c75
-rw-r--r--drivers/staging/lustre/lustre/obdclass/linux/linux-module.c102
-rw-r--r--drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c8
-rw-r--r--drivers/staging/lustre/lustre/obdclass/llog.c6
-rw-r--r--drivers/staging/lustre/lustre/obdclass/llog_cat.c2
-rw-r--r--drivers/staging/lustre/lustre/obdclass/llog_internal.h2
-rw-r--r--drivers/staging/lustre/lustre/obdclass/llog_obd.c4
-rw-r--r--drivers/staging/lustre/lustre/obdclass/llog_swab.c4
-rw-r--r--drivers/staging/lustre/lustre/obdclass/lprocfs_counters.c4
-rw-r--r--drivers/staging/lustre/lustre/obdclass/lprocfs_status.c8
-rw-r--r--drivers/staging/lustre/lustre/obdclass/lu_object.c29
-rw-r--r--drivers/staging/lustre/lustre/obdclass/lu_ref.c10
-rw-r--r--drivers/staging/lustre/lustre/obdclass/lustre_handles.c6
-rw-r--r--drivers/staging/lustre/lustre/obdclass/lustre_peer.c14
-rw-r--r--drivers/staging/lustre/lustre/obdclass/obd_config.c74
-rw-r--r--drivers/staging/lustre/lustre/obdclass/obd_mount.c44
-rw-r--r--drivers/staging/lustre/lustre/obdclass/obdo.c6
-rw-r--r--drivers/staging/lustre/lustre/obdclass/statfs_pack.c8
-rw-r--r--drivers/staging/lustre/lustre/obdclass/uuid.c6
-rw-r--r--drivers/staging/lustre/lustre/obdecho/Makefile3
-rw-r--r--drivers/staging/lustre/lustre/obdecho/echo_client.c33
-rw-r--r--drivers/staging/lustre/lustre/osc/Makefile3
-rw-r--r--drivers/staging/lustre/lustre/osc/lproc_osc.c8
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_cache.c31
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_cl_internal.h6
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_dev.c2
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_internal.h2
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_io.c2
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_lock.c4
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_object.c9
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_quota.c2
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_request.c32
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/Makefile3
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/client.c47
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/connection.c6
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/errno.c4
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/events.c8
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/import.c18
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/layout.c18
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/llog_client.c8
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/llog_net.c6
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c27
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/niobuf.c10
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/nrs.c10
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/nrs_fifo.c6
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/pack_generic.c20
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/pers.c10
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/pinger.c4
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/ptlrpc_module.c8
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c18
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/recover.c18
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/sec.c16
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c20
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/sec_config.c13
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/sec_gc.c12
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/sec_lproc.c16
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/sec_null.c10
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/sec_plain.c10
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/service.c26
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/wiretest.c24
-rw-r--r--drivers/staging/most/hdm-dim2/dim2_hdm.c10
-rw-r--r--drivers/staging/most/hdm-usb/hdm_usb.c22
-rw-r--r--drivers/staging/nvec/nvec.c2
-rw-r--r--drivers/staging/octeon/ethernet-rx.c79
-rw-r--r--drivers/staging/olpc_dcon/olpc_dcon.c2
-rw-r--r--drivers/staging/pi433/Documentation/devicetree/pi433-overlay.dts53
-rw-r--r--drivers/staging/pi433/Documentation/devicetree/pi433.txt62
-rw-r--r--drivers/staging/pi433/Documentation/pi433.txt274
-rw-r--r--drivers/staging/pi433/Kconfig16
-rw-r--r--drivers/staging/pi433/Makefile3
-rw-r--r--drivers/staging/pi433/TODO5
-rw-r--r--drivers/staging/pi433/pi433_if.c1338
-rw-r--r--drivers/staging/pi433/pi433_if.h152
-rw-r--r--drivers/staging/pi433/rf69.c1032
-rw-r--r--drivers/staging/pi433/rf69.h82
-rw-r--r--drivers/staging/pi433/rf69_enum.h201
-rw-r--r--drivers/staging/pi433/rf69_registers.h489
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_ap.c16
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_cmd.c2
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_ioctl_set.c6
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_mlme.c14
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_mlme_ext.c6
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_ioctl.h3
-rw-r--r--drivers/staging/rtl8188eu/os_dep/ioctl_linux.c2
-rw-r--r--drivers/staging/rtl8188eu/os_dep/usb_intf.c2
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c78
-rw-r--r--drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c2
-rw-r--r--drivers/staging/rtl8192u/r8192U_core.c23
-rw-r--r--drivers/staging/rtl8192u/r8192U_hw.h11
-rw-r--r--drivers/staging/rtl8192u/r819xU_cmdpkt.c2
-rw-r--r--drivers/staging/rtl8712/mlme_linux.c4
-rw-r--r--drivers/staging/rtl8712/rtl8712_cmd.c2
-rw-r--r--drivers/staging/rtl8712/rtl8712_efuse.c2
-rw-r--r--drivers/staging/rtl8712/rtl8712_xmit.c8
-rw-r--r--drivers/staging/rtl8712/usb_intf.c2
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_btcoex.c2
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_cmd.c2
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_efuse.c2
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_ioctl_set.c1
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_mlme.c7
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_mlme_ext.c4
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_odm.c38
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_pwrctrl.c6
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_recv.c4
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_security.c14
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_xmit.c6
-rw-r--r--drivers/staging/rtl8723bs/hal/hal_btcoex.c14
-rw-r--r--drivers/staging/rtl8723bs/hal/hal_com.c4
-rw-r--r--drivers/staging/rtl8723bs/hal/odm.c46
-rw-r--r--drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c20
-rw-r--r--drivers/staging/rtl8723bs/hal/rtl8723b_rxdesc.c2
-rw-r--r--drivers/staging/rtl8723bs/hal/rtl8723bs_recv.c2
-rw-r--r--drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c2
-rw-r--r--drivers/staging/rtl8723bs/hal/sdio_ops.c2
-rw-r--r--drivers/staging/rtl8723bs/os_dep/ioctl_linux.c1008
-rw-r--r--drivers/staging/rtl8723bs/os_dep/mlme_linux.c6
-rw-r--r--drivers/staging/rtl8723bs/os_dep/osdep_service.c2
-rw-r--r--drivers/staging/rtl8723bs/os_dep/sdio_intf.c2
-rw-r--r--drivers/staging/rtl8723bs/os_dep/sdio_ops_linux.c4
-rw-r--r--drivers/staging/rtl8723bs/os_dep/xmit_linux.c10
-rw-r--r--drivers/staging/rtlwifi/Kconfig22
-rw-r--r--drivers/staging/rtlwifi/Makefile70
-rw-r--r--drivers/staging/rtlwifi/TODO11
-rw-r--r--drivers/staging/rtlwifi/base.c2826
-rw-r--r--drivers/staging/rtlwifi/base.h186
-rw-r--r--drivers/staging/rtlwifi/btcoexist/Makefile8
-rw-r--r--drivers/staging/rtlwifi/btcoexist/halbt_precomp.h85
-rw-r--r--drivers/staging/rtlwifi/btcoexist/halbtc8822b1ant.c5244
-rw-r--r--drivers/staging/rtlwifi/btcoexist/halbtc8822b1ant.h444
-rw-r--r--drivers/staging/rtlwifi/btcoexist/halbtc8822b2ant.c5225
-rw-r--r--drivers/staging/rtlwifi/btcoexist/halbtc8822b2ant.h498
-rw-r--r--drivers/staging/rtlwifi/btcoexist/halbtc8822bwifionly.c65
-rw-r--r--drivers/staging/rtlwifi/btcoexist/halbtc8822bwifionly.h35
-rw-r--r--drivers/staging/rtlwifi/btcoexist/halbtcoutsrc.c1881
-rw-r--r--drivers/staging/rtlwifi/btcoexist/halbtcoutsrc.h802
-rw-r--r--drivers/staging/rtlwifi/btcoexist/rtl_btc.c528
-rw-r--r--drivers/staging/rtlwifi/btcoexist/rtl_btc.h75
-rw-r--r--drivers/staging/rtlwifi/cam.c326
-rw-r--r--drivers/staging/rtlwifi/cam.h50
-rw-r--r--drivers/staging/rtlwifi/core.c2046
-rw-r--r--drivers/staging/rtlwifi/core.h86
-rw-r--r--drivers/staging/rtlwifi/debug.c636
-rw-r--r--drivers/staging/rtlwifi/debug.h234
-rw-r--r--drivers/staging/rtlwifi/efuse.c1342
-rw-r--r--drivers/staging/rtlwifi/efuse.h120
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_2_platform.h52
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_8822b_cfg.h132
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_8822b_phy.c106
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_8822b_pwr_seq.c563
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_8822b_pwr_seq.h40
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b.c343
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b.h44
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_pcie.c323
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_pcie.h53
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_sdio.c184
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_sdio.h42
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_usb.c185
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_usb.h45
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_func_8822b.c414
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_func_8822b.h38
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_88xx_cfg.h171
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx.c5979
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx.h396
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx_pcie.c329
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx_pcie.h71
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx_sdio.c974
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx_sdio.h84
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx_usb.c554
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx_usb.h73
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_func_88xx.c4494
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_func_88xx.h321
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_api.c426
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_api.h82
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_bit2.h13407
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_bit_8822b.h12103
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_fw_info.h122
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_fw_offload_c2h_nic.h184
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_fw_offload_h2c_nic.h515
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_h2c_extra_info_nic.h115
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_intf_phy_cmd.h54
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_original_c2h_nic.h403
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_original_h2c_nic.h1011
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_pcie_reg.h28
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_pwr_seq_cmd.h116
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_reg2.h1132
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_reg_8822b.h728
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_rx_bd_chip.h48
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_rx_bd_nic.h48
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_rx_desc_chip.h118
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_rx_desc_nic.h133
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_sdio_reg.h62
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_tx_bd_chip.h118
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_tx_bd_nic.h123
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_tx_desc_chip.h444
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_tx_desc_nic.h506
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_type.h1934
-rw-r--r--drivers/staging/rtlwifi/halmac/halmac_usb_reg.h28
-rw-r--r--drivers/staging/rtlwifi/halmac/rtl_halmac.c1384
-rw-r--r--drivers/staging/rtlwifi/halmac/rtl_halmac.h94
-rw-r--r--drivers/staging/rtlwifi/pci.c2508
-rw-r--r--drivers/staging/rtlwifi/pci.h329
-rw-r--r--drivers/staging/rtlwifi/phydm/halphyrf_ce.c965
-rw-r--r--drivers/staging/rtlwifi/phydm/halphyrf_ce.h85
-rw-r--r--drivers/staging/rtlwifi/phydm/mp_precomp.h24
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm.c1986
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm.h946
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_acs.c200
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_acs.h57
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_adaptivity.c941
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_adaptivity.h119
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_adc_sampling.c628
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_adc_sampling.h96
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_antdiv.c83
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_antdiv.h301
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_beamforming.h48
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_ccx.c457
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_ccx.h83
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_cfotracking.c343
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_cfotracking.h60
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_debug.c2910
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_debug.h175
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_dfs.h59
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_dig.c1535
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_dig.h241
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_dynamic_rx_path.h37
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_dynamicbbpowersaving.c129
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_dynamicbbpowersaving.h50
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_dynamictxpower.c102
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_dynamictxpower.h64
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_edcaturbocheck.c139
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_edcaturbocheck.h44
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_features.h33
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_hwconfig.c1928
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_hwconfig.h510
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_interface.c341
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_interface.h205
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_iqk.h76
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_kfree.c228
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_kfree.h42
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_noisemonitor.c330
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_noisemonitor.h46
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_powertracking_ce.c644
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_powertracking_ce.h293
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_pre_define.h613
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_precomp.h85
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_psd.c422
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_psd.h67
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_rainfo.c1208
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_rainfo.h269
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_reg.h151
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_regdefine11ac.h94
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_regdefine11n.h213
-rw-r--r--drivers/staging/rtlwifi/phydm/phydm_types.h130
-rw-r--r--drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_bb.c1969
-rw-r--r--drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_bb.h54
-rw-r--r--drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_mac.c222
-rw-r--r--drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_mac.h38
-rw-r--r--drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_rf.c4744
-rw-r--r--drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_rf.h129
-rw-r--r--drivers/staging/rtlwifi/phydm/rtl8822b/halphyrf_8822b.c351
-rw-r--r--drivers/staging/rtlwifi/phydm/rtl8822b/halphyrf_8822b.h45
-rw-r--r--drivers/staging/rtlwifi/phydm/rtl8822b/phydm_hal_api8822b.c1815
-rw-r--r--drivers/staging/rtlwifi/phydm/rtl8822b/phydm_hal_api8822b.h84
-rw-r--r--drivers/staging/rtlwifi/phydm/rtl8822b/phydm_iqk_8822b.c1410
-rw-r--r--drivers/staging/rtlwifi/phydm/rtl8822b/phydm_iqk_8822b.h48
-rw-r--r--drivers/staging/rtlwifi/phydm/rtl8822b/phydm_regconfig8822b.c168
-rw-r--r--drivers/staging/rtlwifi/phydm/rtl8822b/phydm_regconfig8822b.h54
-rw-r--r--drivers/staging/rtlwifi/phydm/rtl8822b/phydm_rtl8822b.c225
-rw-r--r--drivers/staging/rtlwifi/phydm/rtl8822b/phydm_rtl8822b.h30
-rw-r--r--drivers/staging/rtlwifi/phydm/rtl8822b/version_rtl8822b.h34
-rw-r--r--drivers/staging/rtlwifi/phydm/rtl_phydm.c874
-rw-r--r--drivers/staging/rtlwifi/phydm/rtl_phydm.h45
-rw-r--r--drivers/staging/rtlwifi/phydm/txbf/halcomtxbf.h67
-rw-r--r--drivers/staging/rtlwifi/phydm/txbf/haltxbf8822b.h39
-rw-r--r--drivers/staging/rtlwifi/phydm/txbf/haltxbfinterface.h38
-rw-r--r--drivers/staging/rtlwifi/phydm/txbf/haltxbfjaguar.h36
-rw-r--r--drivers/staging/rtlwifi/phydm/txbf/phydm_hal_txbf_api.h41
-rw-r--r--drivers/staging/rtlwifi/ps.c1007
-rw-r--r--drivers/staging/rtlwifi/ps.h50
-rw-r--r--drivers/staging/rtlwifi/pwrseqcmd.h94
-rw-r--r--drivers/staging/rtlwifi/rc.c322
-rw-r--r--drivers/staging/rtlwifi/rc.h49
-rw-r--r--drivers/staging/rtlwifi/regd.c469
-rw-r--r--drivers/staging/rtlwifi/regd.h63
-rw-r--r--drivers/staging/rtlwifi/rtl8822be/Makefile7
-rw-r--r--drivers/staging/rtlwifi/rtl8822be/def.h82
-rw-r--r--drivers/staging/rtlwifi/rtl8822be/fw.c968
-rw-r--r--drivers/staging/rtlwifi/rtl8822be/fw.h198
-rw-r--r--drivers/staging/rtlwifi/rtl8822be/hw.c2441
-rw-r--r--drivers/staging/rtlwifi/rtl8822be/hw.h66
-rw-r--r--drivers/staging/rtlwifi/rtl8822be/led.c127
-rw-r--r--drivers/staging/rtlwifi/rtl8822be/led.h34
-rw-r--r--drivers/staging/rtlwifi/rtl8822be/phy.c2233
-rw-r--r--drivers/staging/rtlwifi/rtl8822be/phy.h145
-rw-r--r--drivers/staging/rtlwifi/rtl8822be/reg.h1653
-rw-r--r--drivers/staging/rtlwifi/rtl8822be/sw.c481
-rw-r--r--drivers/staging/rtlwifi/rtl8822be/sw.h32
-rw-r--r--drivers/staging/rtlwifi/rtl8822be/trx.c1015
-rw-r--r--drivers/staging/rtlwifi/rtl8822be/trx.h165
-rw-r--r--drivers/staging/rtlwifi/stats.c260
-rw-r--r--drivers/staging/rtlwifi/stats.h42
-rw-r--r--drivers/staging/rtlwifi/wifi.h3375
-rw-r--r--drivers/staging/rts5208/ms.c5
-rw-r--r--drivers/staging/rts5208/rtsx.c4
-rw-r--r--drivers/staging/rts5208/rtsx_chip.c4
-rw-r--r--drivers/staging/rts5208/rtsx_scsi.c2
-rw-r--r--drivers/staging/rts5208/sd.c25
-rw-r--r--drivers/staging/rts5208/spi.c8
-rw-r--r--drivers/staging/rts5208/xd.c17
-rw-r--r--drivers/staging/skein/skein_block.c323
-rw-r--r--drivers/staging/skein/skein_block.h323
-rw-r--r--drivers/staging/speakup/spk_ttyio.c77
-rw-r--r--drivers/staging/typec/fusb302/Kconfig2
-rw-r--r--drivers/staging/typec/fusb302/TODO4
-rw-r--r--drivers/staging/typec/fusb302/fusb302.c144
-rw-r--r--drivers/staging/typec/pd.h2
-rw-r--r--drivers/staging/typec/tcpm.c471
-rw-r--r--drivers/staging/typec/tcpm.h12
-rw-r--r--drivers/staging/unisys/Documentation/overview.txt14
-rw-r--r--drivers/staging/unisys/include/channel.h361
-rw-r--r--drivers/staging/unisys/include/iochannel.h554
-rw-r--r--drivers/staging/unisys/include/visorbus.h44
-rw-r--r--drivers/staging/unisys/visorbus/controlvmchannel.h715
-rw-r--r--drivers/staging/unisys/visorbus/vbuschannel.h96
-rw-r--r--drivers/staging/unisys/visorbus/visorbus_main.c469
-rw-r--r--drivers/staging/unisys/visorbus/visorbus_private.h38
-rw-r--r--drivers/staging/unisys/visorbus/visorchannel.c219
-rw-r--r--drivers/staging/unisys/visorbus/visorchipset.c607
-rw-r--r--drivers/staging/unisys/visorbus/vmcallinterface.h54
-rw-r--r--drivers/staging/unisys/visorhba/visorhba_main.c438
-rw-r--r--drivers/staging/unisys/visorinput/ultrainputreport.h68
-rw-r--r--drivers/staging/unisys/visorinput/visorinput.c138
-rw-r--r--drivers/staging/unisys/visornic/visornic_main.c736
-rw-r--r--drivers/staging/vboxvideo/Kconfig11
-rw-r--r--drivers/staging/vboxvideo/TODO4
-rw-r--r--drivers/staging/vboxvideo/vbox_drv.c7
-rw-r--r--drivers/staging/vboxvideo/vbox_fb.c176
-rw-r--r--drivers/staging/vboxvideo/vbox_main.c8
-rw-r--r--drivers/staging/vboxvideo/vbox_mode.c12
-rw-r--r--drivers/staging/vboxvideo/vbox_ttm.c2
-rw-r--r--drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c8
-rw-r--r--drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c4
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c2
-rw-r--r--drivers/staging/vt6655/card.c6
-rw-r--r--drivers/staging/vt6655/mac.c2
-rw-r--r--drivers/staging/vt6656/device.h2
-rw-r--r--drivers/staging/vt6656/firmware.c2
-rw-r--r--drivers/staging/vt6656/key.h2
-rw-r--r--drivers/staging/vt6656/main_usb.c5
-rw-r--r--drivers/staging/vt6656/power.c6
-rw-r--r--drivers/staging/vt6656/rf.c6
-rw-r--r--drivers/staging/vt6656/usbpipe.c4
-rw-r--r--drivers/staging/wilc1000/host_interface.c4
-rw-r--r--drivers/staging/wilc1000/linux_wlan.c5
-rw-r--r--drivers/staging/wilc1000/wilc_wfi_cfgoperations.c65
-rw-r--r--drivers/staging/wilc1000/wilc_wfi_netdevice.h4
-rw-r--r--drivers/staging/wlan-ng/hfa384x.h100
-rw-r--r--drivers/staging/wlan-ng/hfa384x_usb.c16
-rw-r--r--drivers/staging/wlan-ng/p80211conv.c1
-rw-r--r--drivers/staging/wlan-ng/p80211netdev.c2
-rw-r--r--drivers/staging/wlan-ng/prism2fw.c27
-rw-r--r--drivers/staging/wlan-ng/prism2sta.c37
-rw-r--r--drivers/tty/Kconfig3
-rw-r--r--drivers/tty/ehv_bytechan.c2
-rw-r--r--drivers/tty/goldfish.c234
-rw-r--r--drivers/tty/hvc/Kconfig2
-rw-r--r--drivers/tty/hvc/hvc_opal.c16
-rw-r--r--drivers/tty/hvc/hvc_vio.c8
-rw-r--r--drivers/tty/hvc/hvcs.c4
-rw-r--r--drivers/tty/isicom.c2
-rw-r--r--drivers/tty/mips_ejtag_fdc.c2
-rw-r--r--drivers/tty/moxa.c2
-rw-r--r--drivers/tty/mxser.c2
-rw-r--r--drivers/tty/n_gsm.c11
-rw-r--r--drivers/tty/pty.c8
-rw-r--r--drivers/tty/serdev/core.c2
-rw-r--r--drivers/tty/serial/21285.c2
-rw-r--r--drivers/tty/serial/8250/8250_aspeed_vuart.c7
-rw-r--r--drivers/tty/serial/8250/8250_core.c16
-rw-r--r--drivers/tty/serial/8250/8250_dw.c2
-rw-r--r--drivers/tty/serial/8250/8250_early.c8
-rw-r--r--drivers/tty/serial/8250/8250_exar.c2
-rw-r--r--drivers/tty/serial/8250/8250_gsc.c8
-rw-r--r--drivers/tty/serial/8250/8250_ingenic.c8
-rw-r--r--drivers/tty/serial/8250/8250_men_mcb.c118
-rw-r--r--drivers/tty/serial/8250/8250_mtk.c5
-rw-r--r--drivers/tty/serial/8250/8250_of.c60
-rw-r--r--drivers/tty/serial/8250/8250_pci.c43
-rw-r--r--drivers/tty/serial/8250/8250_port.c81
-rw-r--r--drivers/tty/serial/8250/8250_uniphier.c63
-rw-r--r--drivers/tty/serial/8250/Kconfig11
-rw-r--r--drivers/tty/serial/8250/Makefile1
-rw-r--r--drivers/tty/serial/Kconfig4
-rw-r--r--drivers/tty/serial/amba-pl010.c2
-rw-r--r--drivers/tty/serial/amba-pl011.c6
-rw-r--r--drivers/tty/serial/apbuart.c2
-rw-r--r--drivers/tty/serial/arc_uart.c4
-rw-r--r--drivers/tty/serial/cpm_uart/cpm_uart_core.c2
-rw-r--r--drivers/tty/serial/earlycon.c7
-rw-r--r--drivers/tty/serial/fsl_lpuart.c76
-rw-r--r--drivers/tty/serial/imx.c20
-rw-r--r--drivers/tty/serial/jsm/jsm_driver.c2
-rw-r--r--drivers/tty/serial/m32r_sio.c2
-rw-r--r--drivers/tty/serial/meson_uart.c2
-rw-r--r--drivers/tty/serial/mpc52xx_uart.c14
-rw-r--r--drivers/tty/serial/msm_serial.c19
-rw-r--r--drivers/tty/serial/mux.c16
-rw-r--r--drivers/tty/serial/omap-serial.c13
-rw-r--r--drivers/tty/serial/owl-uart.c635
-rw-r--r--drivers/tty/serial/pch_uart.c38
-rw-r--r--drivers/tty/serial/pmac_zilog.c4
-rw-r--r--drivers/tty/serial/serial-tegra.c2
-rw-r--r--drivers/tty/serial/serial_core.c47
-rw-r--r--drivers/tty/serial/sh-sci.c3
-rw-r--r--drivers/tty/serial/sprd_serial.c8
-rw-r--r--drivers/tty/serial/st-asc.c2
-rw-r--r--drivers/tty/serial/stm32-usart.c125
-rw-r--r--drivers/tty/serial/stm32-usart.h37
-rw-r--r--drivers/tty/serial/sunsab.c2
-rw-r--r--drivers/tty/serial/sunsu.c6
-rw-r--r--drivers/tty/serial/ucc_uart.c2
-rw-r--r--drivers/tty/serial/xilinx_uartps.c2
-rw-r--r--drivers/tty/synclink.c2
-rw-r--r--drivers/tty/synclink_gt.c2
-rw-r--r--drivers/tty/synclinkmp.c2
-rw-r--r--drivers/tty/tty_buffer.c26
-rw-r--r--drivers/tty/tty_io.c112
-rw-r--r--drivers/usb/atm/cxacru.c2
-rw-r--r--drivers/usb/atm/speedtch.c6
-rw-r--r--drivers/usb/atm/ueagle-atm.c4
-rw-r--r--drivers/usb/atm/usbatm.c6
-rw-r--r--drivers/usb/atm/xusbatm.c1
-rw-r--r--drivers/usb/c67x00/c67x00-hcd.c2
-rw-r--r--drivers/usb/chipidea/Makefile1
-rw-r--r--drivers/usb/chipidea/ci_hdrc_msm.c2
-rw-r--r--drivers/usb/chipidea/ci_hdrc_pci.c1
-rw-r--r--drivers/usb/chipidea/ci_hdrc_tegra.c155
-rw-r--r--drivers/usb/chipidea/ci_hdrc_usb2.c2
-rw-r--r--drivers/usb/chipidea/core.c6
-rw-r--r--drivers/usb/chipidea/otg_fsm.c2
-rw-r--r--drivers/usb/chipidea/udc.c8
-rw-r--r--drivers/usb/class/cdc-wdm.c4
-rw-r--r--drivers/usb/class/usbtmc.c4
-rw-r--r--drivers/usb/common/common.c15
-rw-r--r--drivers/usb/common/ulpi.c2
-rw-r--r--drivers/usb/core/devio.c6
-rw-r--r--drivers/usb/core/hcd.c2
-rw-r--r--drivers/usb/core/hub.c19
-rw-r--r--drivers/usb/core/ledtrig-usbport.c5
-rw-r--r--drivers/usb/core/quirks.c6
-rw-r--r--drivers/usb/core/sysfs.c2
-rw-r--r--drivers/usb/dwc2/gadget.c2
-rw-r--r--drivers/usb/dwc2/hcd.c6
-rw-r--r--drivers/usb/dwc3/dwc3-keystone.c22
-rw-r--r--drivers/usb/dwc3/dwc3-of-simple.c4
-rw-r--r--drivers/usb/dwc3/dwc3-omap.c4
-rw-r--r--drivers/usb/dwc3/dwc3-pci.c2
-rw-r--r--drivers/usb/gadget/Kconfig2
-rw-r--r--drivers/usb/gadget/function/f_fs.c7
-rw-r--r--drivers/usb/gadget/function/f_hid.c17
-rw-r--r--drivers/usb/gadget/function/f_midi.c68
-rw-r--r--drivers/usb/gadget/function/f_ncm.c2
-rw-r--r--drivers/usb/gadget/function/f_rndis.c20
-rw-r--r--drivers/usb/gadget/function/u_audio.c4
-rw-r--r--drivers/usb/gadget/function/u_ether.c2
-rw-r--r--drivers/usb/gadget/function/u_ether.h1
-rw-r--r--drivers/usb/gadget/function/u_ether_configfs.h35
-rw-r--r--drivers/usb/gadget/function/u_rndis.h4
-rw-r--r--drivers/usb/gadget/function/u_serial.c2
-rw-r--r--drivers/usb/gadget/legacy/webcam.c1
-rw-r--r--drivers/usb/gadget/udc/bdc/Kconfig1
-rw-r--r--drivers/usb/gadget/udc/bdc/bdc.h24
-rw-r--r--drivers/usb/gadget/udc/bdc/bdc_core.c148
-rw-r--r--drivers/usb/gadget/udc/bdc/bdc_dbg.c16
-rw-r--r--drivers/usb/gadget/udc/bdc/bdc_ep.c4
-rw-r--r--drivers/usb/gadget/udc/bdc/bdc_udc.c7
-rw-r--r--drivers/usb/gadget/udc/core.c20
-rw-r--r--drivers/usb/gadget/udc/dummy_hcd.c2
-rw-r--r--drivers/usb/gadget/udc/fsl_qe_udc.c2
-rw-r--r--drivers/usb/gadget/udc/mv_udc_core.c2
-rw-r--r--drivers/usb/gadget/udc/renesas_usb3.c117
-rw-r--r--drivers/usb/gadget/udc/s3c2410_udc.c4
-rw-r--r--drivers/usb/host/ehci-fsl.c2
-rw-r--r--drivers/usb/host/ehci-omap.c4
-rw-r--r--drivers/usb/host/fsl-mph-dr-of.c4
-rw-r--r--drivers/usb/host/hwa-hc.c4
-rw-r--r--drivers/usb/host/imx21-hcd.c8
-rw-r--r--drivers/usb/host/isp116x-hcd.c2
-rw-r--r--drivers/usb/host/isp1362-hcd.c2
-rw-r--r--drivers/usb/host/max3421-hcd.c2
-rw-r--r--drivers/usb/host/pci-quirks.c35
-rw-r--r--drivers/usb/host/r8a66597-hcd.c2
-rw-r--r--drivers/usb/host/sl811-hcd.c2
-rw-r--r--drivers/usb/host/u132-hcd.c2
-rw-r--r--drivers/usb/host/whci/hcd.c2
-rw-r--r--drivers/usb/host/xhci-hub.c127
-rw-r--r--drivers/usb/host/xhci-mtk.c1
-rw-r--r--drivers/usb/host/xhci-plat.c10
-rw-r--r--drivers/usb/host/xhci-rcar.c40
-rw-r--r--drivers/usb/host/xhci-ring.c22
-rw-r--r--drivers/usb/host/xhci-trace.h23
-rw-r--r--drivers/usb/host/xhci.h90
-rw-r--r--drivers/usb/image/microtek.c4
-rw-r--r--drivers/usb/isp1760/isp1760-hcd.c6
-rw-r--r--drivers/usb/misc/adutux.c2
-rw-r--r--drivers/usb/misc/chaoskey.c2
-rw-r--r--drivers/usb/misc/cytherm.c1
-rw-r--r--drivers/usb/misc/ftdi-elan.c33
-rw-r--r--drivers/usb/misc/idmouse.c2
-rw-r--r--drivers/usb/misc/iowarrior.c4
-rw-r--r--drivers/usb/misc/ldusb.c1
-rw-r--r--drivers/usb/misc/legousbtower.c2
-rw-r--r--drivers/usb/misc/lvstest.c41
-rw-r--r--drivers/usb/misc/rio500.c4
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb.c13
-rw-r--r--drivers/usb/misc/trancevibrator.c2
-rw-r--r--drivers/usb/misc/usb251xb.c1
-rw-r--r--drivers/usb/misc/usbsevseg.c2
-rw-r--r--drivers/usb/misc/uss720.c7
-rw-r--r--drivers/usb/mtu3/mtu3.h2
-rw-r--r--drivers/usb/mtu3/mtu3_dr.c58
-rw-r--r--drivers/usb/mtu3/mtu3_gadget.c4
-rw-r--r--drivers/usb/mtu3/mtu3_gadget_ep0.c23
-rw-r--r--drivers/usb/mtu3/mtu3_host.c4
-rw-r--r--drivers/usb/mtu3/mtu3_hw_regs.h4
-rw-r--r--drivers/usb/mtu3/mtu3_plat.c1
-rw-r--r--drivers/usb/musb/musb_core.c22
-rw-r--r--drivers/usb/musb/musb_core.h24
-rw-r--r--drivers/usb/musb/musb_dsps.c13
-rw-r--r--drivers/usb/musb/musb_gadget.c6
-rw-r--r--drivers/usb/musb/musb_host.c8
-rw-r--r--drivers/usb/phy/phy-mv-usb.c4
-rw-r--r--drivers/usb/phy/phy-qcom-8x16-usb.c9
-rw-r--r--drivers/usb/phy/phy-tahvo.c2
-rw-r--r--drivers/usb/phy/phy.c276
-rw-r--r--drivers/usb/renesas_usbhs/mod_gadget.c4
-rw-r--r--drivers/usb/renesas_usbhs/mod_host.c2
-rw-r--r--drivers/usb/renesas_usbhs/pipe.c2
-rw-r--r--drivers/usb/serial/option.c10
-rw-r--r--drivers/usb/storage/realtek_cr.c1
-rw-r--r--drivers/usb/usbip/stub_main.c2
-rw-r--r--drivers/usb/usbip/usbip_common.c2
-rw-r--r--drivers/usb/usbip/usbip_common.h2
-rw-r--r--drivers/usb/usbip/vhci_hcd.c4
-rw-r--r--drivers/usb/usbip/vhci_sysfs.c6
-rw-r--r--drivers/usb/wusbcore/cbaf.c2
-rw-r--r--drivers/usb/wusbcore/dev-sysfs.c2
-rw-r--r--drivers/usb/wusbcore/wusbhc.c2
-rw-r--r--drivers/uwb/lc-rc.c2
-rw-r--r--drivers/video/console/sticore.c11
-rw-r--r--drivers/video/fbdev/core/fbmem.c12
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c2
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c2
-rw-r--r--drivers/video/fbdev/uvesafb.c7
-rw-r--r--drivers/virtio/Kconfig4
-rw-r--r--drivers/xen/events/events_base.c6
-rw-r--r--drivers/xen/gntdev.c8
-rw-r--r--drivers/xen/xen-pciback/pci_stub.c44
2171 files changed, 192235 insertions, 68945 deletions
diff --git a/drivers/Makefile b/drivers/Makefile
index dfdcda0..d90fdc4 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -125,7 +125,6 @@ obj-$(CONFIG_ACCESSIBILITY) += accessibility/
obj-$(CONFIG_ISDN) += isdn/
obj-$(CONFIG_EDAC) += edac/
obj-$(CONFIG_EISA) += eisa/
-obj-y += lguest/
obj-$(CONFIG_CPU_FREQ) += cpufreq/
obj-$(CONFIG_CPU_IDLE) += cpuidle/
obj-y += mmc/
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index a3215ee..736783c 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -588,7 +588,8 @@ void acpi_configure_pmsi_domain(struct device *dev)
dev_set_msi_domain(dev, msi_domain);
}
-static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
+static int __maybe_unused __get_pci_rid(struct pci_dev *pdev, u16 alias,
+ void *data)
{
u32 *rid = data;
@@ -633,8 +634,7 @@ int iort_add_device_replay(const struct iommu_ops *ops, struct device *dev)
{
int err = 0;
- if (!IS_ERR_OR_NULL(ops) && ops->add_device && dev->bus &&
- !dev->iommu_group)
+ if (ops->add_device && dev->bus && !dev->iommu_group)
err = ops->add_device(dev);
return err;
@@ -648,36 +648,49 @@ int iort_add_device_replay(const struct iommu_ops *ops, struct device *dev)
{ return 0; }
#endif
-static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
- struct acpi_iort_node *node,
- u32 streamid)
+static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
+ u32 streamid)
{
- const struct iommu_ops *ops = NULL;
- int ret = -ENODEV;
+ const struct iommu_ops *ops;
struct fwnode_handle *iort_fwnode;
- if (node) {
- iort_fwnode = iort_get_fwnode(node);
- if (!iort_fwnode)
- return NULL;
+ if (!node)
+ return -ENODEV;
- ops = iommu_ops_from_fwnode(iort_fwnode);
- /*
- * If the ops look-up fails, this means that either
- * the SMMU drivers have not been probed yet or that
- * the SMMU drivers are not built in the kernel;
- * Depending on whether the SMMU drivers are built-in
- * in the kernel or not, defer the IOMMU configuration
- * or just abort it.
- */
- if (!ops)
- return iort_iommu_driver_enabled(node->type) ?
- ERR_PTR(-EPROBE_DEFER) : NULL;
+ iort_fwnode = iort_get_fwnode(node);
+ if (!iort_fwnode)
+ return -ENODEV;
- ret = arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops);
- }
+ /*
+ * If the ops look-up fails, this means that either
+ * the SMMU drivers have not been probed yet or that
+ * the SMMU drivers are not built in the kernel;
+ * Depending on whether the SMMU drivers are built-in
+ * in the kernel or not, defer the IOMMU configuration
+ * or just abort it.
+ */
+ ops = iommu_ops_from_fwnode(iort_fwnode);
+ if (!ops)
+ return iort_iommu_driver_enabled(node->type) ?
+ -EPROBE_DEFER : -ENODEV;
- return ret ? NULL : ops;
+ return arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops);
+}
+
+struct iort_pci_alias_info {
+ struct device *dev;
+ struct acpi_iort_node *node;
+};
+
+static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
+{
+ struct iort_pci_alias_info *info = data;
+ struct acpi_iort_node *parent;
+ u32 streamid;
+
+ parent = iort_node_map_id(info->node, alias, &streamid,
+ IORT_IOMMU_TYPE);
+ return iort_iommu_xlate(info->dev, parent, streamid);
}
/**
@@ -713,9 +726,9 @@ void iort_set_dma_mask(struct device *dev)
const struct iommu_ops *iort_iommu_configure(struct device *dev)
{
struct acpi_iort_node *node, *parent;
- const struct iommu_ops *ops = NULL;
+ const struct iommu_ops *ops;
u32 streamid = 0;
- int err;
+ int err = -ENODEV;
/*
* If we already translated the fwspec there
@@ -727,21 +740,16 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
if (dev_is_pci(dev)) {
struct pci_bus *bus = to_pci_dev(dev)->bus;
- u32 rid;
-
- pci_for_each_dma_alias(to_pci_dev(dev), __get_pci_rid,
- &rid);
+ struct iort_pci_alias_info info = { .dev = dev };
node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
iort_match_node_callback, &bus->dev);
if (!node)
return NULL;
- parent = iort_node_map_id(node, rid, &streamid,
- IORT_IOMMU_TYPE);
-
- ops = iort_iommu_xlate(dev, parent, streamid);
-
+ info.node = node;
+ err = pci_for_each_dma_alias(to_pci_dev(dev),
+ iort_pci_iommu_init, &info);
} else {
int i = 0;
@@ -750,31 +758,30 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
if (!node)
return NULL;
- parent = iort_node_map_platform_id(node, &streamid,
- IORT_IOMMU_TYPE, i++);
-
- while (parent) {
- ops = iort_iommu_xlate(dev, parent, streamid);
- if (IS_ERR_OR_NULL(ops))
- return ops;
-
+ do {
parent = iort_node_map_platform_id(node, &streamid,
IORT_IOMMU_TYPE,
i++);
- }
+
+ if (parent)
+ err = iort_iommu_xlate(dev, parent, streamid);
+ } while (parent && !err);
}
/*
* If we have reason to believe the IOMMU driver missed the initial
* add_device callback for dev, replay it to get things in order.
*/
- err = iort_add_device_replay(ops, dev);
- if (err)
- ops = ERR_PTR(err);
+ if (!err) {
+ ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
+ err = iort_add_device_replay(ops, dev);
+ }
/* Ignore all other errors apart from EPROBE_DEFER */
- if (IS_ERR(ops) && (PTR_ERR(ops) != -EPROBE_DEFER)) {
- dev_dbg(dev, "Adding to IOMMU failed: %ld\n", PTR_ERR(ops));
+ if (err == -EPROBE_DEFER) {
+ ops = ERR_PTR(err);
+ } else if (err) {
+ dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
ops = NULL;
}
@@ -908,6 +915,27 @@ static bool __init arm_smmu_v3_is_coherent(struct acpi_iort_node *node)
return smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE;
}
+#if defined(CONFIG_ACPI_NUMA) && defined(ACPI_IORT_SMMU_V3_PXM_VALID)
+/*
+ * set numa proximity domain for smmuv3 device
+ */
+static void __init arm_smmu_v3_set_proximity(struct device *dev,
+ struct acpi_iort_node *node)
+{
+ struct acpi_iort_smmu_v3 *smmu;
+
+ smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
+ if (smmu->flags & ACPI_IORT_SMMU_V3_PXM_VALID) {
+ set_dev_node(dev, acpi_map_pxm_to_node(smmu->pxm));
+ pr_info("SMMU-v3[%llx] Mapped to Proximity domain %d\n",
+ smmu->base_address,
+ smmu->pxm);
+ }
+}
+#else
+#define arm_smmu_v3_set_proximity NULL
+#endif
+
static int __init arm_smmu_count_resources(struct acpi_iort_node *node)
{
struct acpi_iort_smmu *smmu;
@@ -977,13 +1005,16 @@ struct iort_iommu_config {
int (*iommu_count_resources)(struct acpi_iort_node *node);
void (*iommu_init_resources)(struct resource *res,
struct acpi_iort_node *node);
+ void (*iommu_set_proximity)(struct device *dev,
+ struct acpi_iort_node *node);
};
static const struct iort_iommu_config iort_arm_smmu_v3_cfg __initconst = {
.name = "arm-smmu-v3",
.iommu_is_coherent = arm_smmu_v3_is_coherent,
.iommu_count_resources = arm_smmu_v3_count_resources,
- .iommu_init_resources = arm_smmu_v3_init_resources
+ .iommu_init_resources = arm_smmu_v3_init_resources,
+ .iommu_set_proximity = arm_smmu_v3_set_proximity,
};
static const struct iort_iommu_config iort_arm_smmu_cfg __initconst = {
@@ -1028,6 +1059,9 @@ static int __init iort_add_smmu_platform_device(struct acpi_iort_node *node)
if (!pdev)
return -ENOMEM;
+ if (ops->iommu_set_proximity)
+ ops->iommu_set_proximity(&pdev->dev, node);
+
count = ops->iommu_count_resources(node);
r = kcalloc(count, sizeof(*r), GFP_KERNEL);
diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 19182d0..1893e41 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -2884,7 +2884,7 @@ static int acpi_nfit_flush_probe(struct nvdimm_bus_descriptor *nd_desc)
* need to be interruptible while waiting.
*/
INIT_WORK_ONSTACK(&flush.work, flush_probe);
- COMPLETION_INITIALIZER_ONSTACK(flush.cmp);
+ init_completion(&flush.cmp);
queue_work(nfit_wq, &flush.work);
mutex_unlock(&acpi_desc->init_mutex);
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 5c8aa9c..fe3d2a4 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -708,8 +708,6 @@ static DEFINE_RAW_SPINLOCK(c3_lock);
static void acpi_idle_enter_bm(struct acpi_processor *pr,
struct acpi_processor_cx *cx, bool timer_bc)
{
- acpi_unlazy_tlb(smp_processor_id());
-
/*
* Must be done before busmaster disable as we might need to
* access HPET !
diff --git a/drivers/ata/ahci_da850.c b/drivers/ata/ahci_da850.c
index 1a50cd3..9b34dff 100644
--- a/drivers/ata/ahci_da850.c
+++ b/drivers/ata/ahci_da850.c
@@ -216,12 +216,16 @@ static int ahci_da850_probe(struct platform_device *pdev)
return rc;
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- if (!res)
+ if (!res) {
+ rc = -ENODEV;
goto disable_resources;
+ }
pwrdn_reg = devm_ioremap(dev, res->start, resource_size(res));
- if (!pwrdn_reg)
+ if (!pwrdn_reg) {
+ rc = -ENOMEM;
goto disable_resources;
+ }
da850_sata_init(dev, pwrdn_reg, hpriv->mmio, mpy);
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index fa7dd43..1945a8e 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2411,6 +2411,9 @@ static void ata_dev_config_trusted(struct ata_device *dev)
u64 trusted_cap;
unsigned int err;
+ if (!ata_id_has_trusted(dev->id))
+ return;
+
if (!ata_identify_page_supported(dev, ATA_LOG_SECURITY)) {
ata_dev_warn(dev,
"Security Log not supported\n");
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 3dbd055..e4effef 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -645,12 +645,11 @@ void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap,
* completions are honored. A scmd is determined to have
* timed out iff its associated qc is active and not failed.
*/
+ spin_lock_irqsave(ap->lock, flags);
if (ap->ops->error_handler) {
struct scsi_cmnd *scmd, *tmp;
int nr_timedout = 0;
- spin_lock_irqsave(ap->lock, flags);
-
/* This must occur under the ap->lock as we don't want
a polled recovery to race the real interrupt handler
@@ -700,12 +699,11 @@ void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap,
if (nr_timedout)
__ata_port_freeze(ap);
- spin_unlock_irqrestore(ap->lock, flags);
/* initialize eh_tries */
ap->eh_tries = ATA_EH_MAX_TRIES;
- } else
- spin_unlock_wait(ap->lock);
+ }
+ spin_unlock_irqrestore(ap->lock, flags);
}
EXPORT_SYMBOL(ata_scsi_cmd_error_handler);
diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c
index d1c33a8..41be9ff 100644
--- a/drivers/base/arch_topology.c
+++ b/drivers/base/arch_topology.c
@@ -41,8 +41,7 @@ static ssize_t cpu_capacity_show(struct device *dev,
{
struct cpu *cpu = container_of(dev, struct cpu, dev);
- return sprintf(buf, "%lu\n",
- topology_get_cpu_scale(NULL, cpu->dev.id));
+ return sprintf(buf, "%lu\n", topology_get_cpu_scale(NULL, cpu->dev.id));
}
static ssize_t cpu_capacity_store(struct device *dev,
@@ -96,14 +95,21 @@ subsys_initcall(register_cpu_capacity_sysctl);
static u32 capacity_scale;
static u32 *raw_capacity;
-static bool cap_parsing_failed;
+
+static int __init free_raw_capacity(void)
+{
+ kfree(raw_capacity);
+ raw_capacity = NULL;
+
+ return 0;
+}
void topology_normalize_cpu_scale(void)
{
u64 capacity;
int cpu;
- if (!raw_capacity || cap_parsing_failed)
+ if (!raw_capacity)
return;
pr_debug("cpu_capacity: capacity_scale=%u\n", capacity_scale);
@@ -120,16 +126,16 @@ void topology_normalize_cpu_scale(void)
mutex_unlock(&cpu_scale_mutex);
}
-int __init topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu)
+bool __init topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu)
{
- int ret = 1;
+ static bool cap_parsing_failed;
+ int ret;
u32 cpu_capacity;
if (cap_parsing_failed)
- return !ret;
+ return false;
- ret = of_property_read_u32(cpu_node,
- "capacity-dmips-mhz",
+ ret = of_property_read_u32(cpu_node, "capacity-dmips-mhz",
&cpu_capacity);
if (!ret) {
if (!raw_capacity) {
@@ -139,21 +145,21 @@ int __init topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu)
if (!raw_capacity) {
pr_err("cpu_capacity: failed to allocate memory for raw capacities\n");
cap_parsing_failed = true;
- return 0;
+ return false;
}
}
capacity_scale = max(cpu_capacity, capacity_scale);
raw_capacity[cpu] = cpu_capacity;
- pr_debug("cpu_capacity: %s cpu_capacity=%u (raw)\n",
- cpu_node->full_name, raw_capacity[cpu]);
+ pr_debug("cpu_capacity: %pOF cpu_capacity=%u (raw)\n",
+ cpu_node, raw_capacity[cpu]);
} else {
if (raw_capacity) {
- pr_err("cpu_capacity: missing %s raw capacity\n",
- cpu_node->full_name);
+ pr_err("cpu_capacity: missing %pOF raw capacity\n",
+ cpu_node);
pr_err("cpu_capacity: partial information: fallback to 1024 for all CPUs\n");
}
cap_parsing_failed = true;
- kfree(raw_capacity);
+ free_raw_capacity();
}
return !ret;
@@ -161,7 +167,6 @@ int __init topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu)
#ifdef CONFIG_CPU_FREQ
static cpumask_var_t cpus_to_visit;
-static bool cap_parsing_done;
static void parsing_done_workfn(struct work_struct *work);
static DECLARE_WORK(parsing_done_work, parsing_done_workfn);
@@ -173,30 +178,31 @@ init_cpu_capacity_callback(struct notifier_block *nb,
struct cpufreq_policy *policy = data;
int cpu;
- if (cap_parsing_failed || cap_parsing_done)
+ if (!raw_capacity)
return 0;
- switch (val) {
- case CPUFREQ_NOTIFY:
- pr_debug("cpu_capacity: init cpu capacity for CPUs [%*pbl] (to_visit=%*pbl)\n",
- cpumask_pr_args(policy->related_cpus),
- cpumask_pr_args(cpus_to_visit));
- cpumask_andnot(cpus_to_visit,
- cpus_to_visit,
- policy->related_cpus);
- for_each_cpu(cpu, policy->related_cpus) {
- raw_capacity[cpu] = topology_get_cpu_scale(NULL, cpu) *
- policy->cpuinfo.max_freq / 1000UL;
- capacity_scale = max(raw_capacity[cpu], capacity_scale);
- }
- if (cpumask_empty(cpus_to_visit)) {
- topology_normalize_cpu_scale();
- kfree(raw_capacity);
- pr_debug("cpu_capacity: parsing done\n");
- cap_parsing_done = true;
- schedule_work(&parsing_done_work);
- }
+ if (val != CPUFREQ_NOTIFY)
+ return 0;
+
+ pr_debug("cpu_capacity: init cpu capacity for CPUs [%*pbl] (to_visit=%*pbl)\n",
+ cpumask_pr_args(policy->related_cpus),
+ cpumask_pr_args(cpus_to_visit));
+
+ cpumask_andnot(cpus_to_visit, cpus_to_visit, policy->related_cpus);
+
+ for_each_cpu(cpu, policy->related_cpus) {
+ raw_capacity[cpu] = topology_get_cpu_scale(NULL, cpu) *
+ policy->cpuinfo.max_freq / 1000UL;
+ capacity_scale = max(raw_capacity[cpu], capacity_scale);
+ }
+
+ if (cpumask_empty(cpus_to_visit)) {
+ topology_normalize_cpu_scale();
+ free_raw_capacity();
+ pr_debug("cpu_capacity: parsing done\n");
+ schedule_work(&parsing_done_work);
}
+
return 0;
}
@@ -233,11 +239,5 @@ static void parsing_done_workfn(struct work_struct *work)
}
#else
-static int __init free_raw_capacity(void)
-{
- kfree(raw_capacity);
-
- return 0;
-}
core_initcall(free_raw_capacity);
#endif
diff --git a/drivers/base/base.h b/drivers/base/base.h
index e19b100..539432a 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -126,11 +126,6 @@ extern int driver_add_groups(struct device_driver *drv,
extern void driver_remove_groups(struct device_driver *drv,
const struct attribute_group **groups);
-extern int device_add_groups(struct device *dev,
- const struct attribute_group **groups);
-extern void device_remove_groups(struct device *dev,
- const struct attribute_group **groups);
-
extern char *make_class_name(const char *name, struct kobject *kobj);
extern int devres_release_all(struct device *dev);
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index e162c9a..22a64fd3 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -698,7 +698,7 @@ int bus_add_driver(struct device_driver *drv)
out_unregister:
kobject_put(&priv->kobj);
- kfree(drv->p);
+ /* drv->p is freed in driver_release() */
drv->p = NULL;
out_put_bus:
bus_put(bus);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 755451f..12ebd05 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1023,12 +1023,144 @@ int device_add_groups(struct device *dev, const struct attribute_group **groups)
{
return sysfs_create_groups(&dev->kobj, groups);
}
+EXPORT_SYMBOL_GPL(device_add_groups);
void device_remove_groups(struct device *dev,
const struct attribute_group **groups)
{
sysfs_remove_groups(&dev->kobj, groups);
}
+EXPORT_SYMBOL_GPL(device_remove_groups);
+
+union device_attr_group_devres {
+ const struct attribute_group *group;
+ const struct attribute_group **groups;
+};
+
+static int devm_attr_group_match(struct device *dev, void *res, void *data)
+{
+ return ((union device_attr_group_devres *)res)->group == data;
+}
+
+static void devm_attr_group_remove(struct device *dev, void *res)
+{
+ union device_attr_group_devres *devres = res;
+ const struct attribute_group *group = devres->group;
+
+ dev_dbg(dev, "%s: removing group %p\n", __func__, group);
+ sysfs_remove_group(&dev->kobj, group);
+}
+
+static void devm_attr_groups_remove(struct device *dev, void *res)
+{
+ union device_attr_group_devres *devres = res;
+ const struct attribute_group **groups = devres->groups;
+
+ dev_dbg(dev, "%s: removing groups %p\n", __func__, groups);
+ sysfs_remove_groups(&dev->kobj, groups);
+}
+
+/**
+ * devm_device_add_group - given a device, create a managed attribute group
+ * @dev: The device to create the group for
+ * @grp: The attribute group to create
+ *
+ * This function creates a group for the first time. It will explicitly
+ * warn and error if any of the attribute files being created already exist.
+ *
+ * Returns 0 on success or error code on failure.
+ */
+int devm_device_add_group(struct device *dev, const struct attribute_group *grp)
+{
+ union device_attr_group_devres *devres;
+ int error;
+
+ devres = devres_alloc(devm_attr_group_remove,
+ sizeof(*devres), GFP_KERNEL);
+ if (!devres)
+ return -ENOMEM;
+
+ error = sysfs_create_group(&dev->kobj, grp);
+ if (error) {
+ devres_free(devres);
+ return error;
+ }
+
+ devres->group = grp;
+ devres_add(dev, devres);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(devm_device_add_group);
+
+/**
+ * devm_device_remove_group: remove a managed group from a device
+ * @dev: device to remove the group from
+ * @grp: group to remove
+ *
+ * This function removes a group of attributes from a device. The attributes
+ * previously have to have been created for this group, otherwise it will fail.
+ */
+void devm_device_remove_group(struct device *dev,
+ const struct attribute_group *grp)
+{
+ WARN_ON(devres_release(dev, devm_attr_group_remove,
+ devm_attr_group_match,
+ /* cast away const */ (void *)grp));
+}
+EXPORT_SYMBOL_GPL(devm_device_remove_group);
+
+/**
+ * devm_device_add_groups - create a bunch of managed attribute groups
+ * @dev: The device to create the group for
+ * @groups: The attribute groups to create, NULL terminated
+ *
+ * This function creates a bunch of managed attribute groups. If an error
+ * occurs when creating a group, all previously created groups will be
+ * removed, unwinding everything back to the original state when this
+ * function was called. It will explicitly warn and error if any of the
+ * attribute files being created already exist.
+ *
+ * Returns 0 on success or error code from sysfs_create_group on failure.
+ */
+int devm_device_add_groups(struct device *dev,
+ const struct attribute_group **groups)
+{
+ union device_attr_group_devres *devres;
+ int error;
+
+ devres = devres_alloc(devm_attr_groups_remove,
+ sizeof(*devres), GFP_KERNEL);
+ if (!devres)
+ return -ENOMEM;
+
+ error = sysfs_create_groups(&dev->kobj, groups);
+ if (error) {
+ devres_free(devres);
+ return error;
+ }
+
+ devres->groups = groups;
+ devres_add(dev, devres);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(devm_device_add_groups);
+
+/**
+ * devm_device_remove_groups - remove a list of managed groups
+ *
+ * @dev: The device for the groups to be removed from
+ * @groups: NULL terminated list of groups to be removed
+ *
+ * If groups is not NULL, remove the specified groups from the device.
+ */
+void devm_device_remove_groups(struct device *dev,
+ const struct attribute_group **groups)
+{
+ WARN_ON(devres_release(dev, devm_attr_groups_remove,
+ devm_attr_group_match,
+ /* cast away const */ (void *)groups));
+}
+EXPORT_SYMBOL_GPL(devm_device_remove_groups);
static int device_add_attrs(struct device *dev)
{
@@ -2664,11 +2796,12 @@ void device_shutdown(void)
pm_runtime_get_noresume(dev);
pm_runtime_barrier(dev);
- if (dev->class && dev->class->shutdown) {
+ if (dev->class && dev->class->shutdown_pre) {
if (initcall_debug)
- dev_info(dev, "shutdown\n");
- dev->class->shutdown(dev);
- } else if (dev->bus && dev->bus->shutdown) {
+ dev_info(dev, "shutdown_pre\n");
+ dev->class->shutdown_pre(dev);
+ }
+ if (dev->bus && dev->bus->shutdown) {
if (initcall_debug)
dev_info(dev, "shutdown\n");
dev->bus->shutdown(dev);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 4882f06..ad44b40 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -20,6 +20,7 @@
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
+#include <linux/init.h>
#include <linux/module.h>
#include <linux/kthread.h>
#include <linux/wait.h>
@@ -53,6 +54,7 @@ static DEFINE_MUTEX(deferred_probe_mutex);
static LIST_HEAD(deferred_probe_pending_list);
static LIST_HEAD(deferred_probe_active_list);
static atomic_t deferred_trigger_count = ATOMIC_INIT(0);
+static bool initcalls_done;
/*
* In some cases, like suspend to RAM or hibernation, It might be reasonable
@@ -62,6 +64,26 @@ static atomic_t deferred_trigger_count = ATOMIC_INIT(0);
static bool defer_all_probes;
/*
+ * For initcall_debug, show the deferred probes executed in late_initcall
+ * processing.
+ */
+static void deferred_probe_debug(struct device *dev)
+{
+ ktime_t calltime, delta, rettime;
+ unsigned long long duration;
+
+ printk(KERN_DEBUG "deferred probe %s @ %i\n", dev_name(dev),
+ task_pid_nr(current));
+ calltime = ktime_get();
+ bus_probe_device(dev);
+ rettime = ktime_get();
+ delta = ktime_sub(rettime, calltime);
+ duration = (unsigned long long) ktime_to_ns(delta) >> 10;
+ printk(KERN_DEBUG "deferred probe %s returned after %lld usecs\n",
+ dev_name(dev), duration);
+}
+
+/*
* deferred_probe_work_func() - Retry probing devices in the active list.
*/
static void deferred_probe_work_func(struct work_struct *work)
@@ -106,7 +128,10 @@ static void deferred_probe_work_func(struct work_struct *work)
device_pm_unlock();
dev_dbg(dev, "Retrying from deferred list\n");
- bus_probe_device(dev);
+ if (initcall_debug && !initcalls_done)
+ deferred_probe_debug(dev);
+ else
+ bus_probe_device(dev);
mutex_lock(&deferred_probe_mutex);
@@ -215,6 +240,7 @@ static int deferred_probe_initcall(void)
driver_deferred_probe_trigger();
/* Sort as many dependencies as possible before exiting initcalls */
flush_work(&deferred_probe_work);
+ initcalls_done = true;
return 0;
}
late_initcall(deferred_probe_initcall);
@@ -259,6 +285,8 @@ static void driver_bound(struct device *dev)
if (dev->bus)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
BUS_NOTIFY_BOUND_DRIVER, dev);
+
+ kobject_uevent(&dev->kobj, KOBJ_BIND);
}
static int driver_sysfs_add(struct device *dev)
@@ -848,6 +876,8 @@ static void __device_release_driver(struct device *dev, struct device *parent)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
BUS_NOTIFY_UNBOUND_DRIVER,
dev);
+
+ kobject_uevent(&dev->kobj, KOBJ_UNBIND);
}
}
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index bfbe1e1..a5fb884 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -7,6 +7,8 @@
*
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/capability.h>
#include <linux/device.h>
#include <linux/module.h>
@@ -331,6 +333,7 @@ static struct firmware_buf *__fw_lookup_buf(const char *fw_name)
return NULL;
}
+/* Returns 1 for batching firmware requests with the same name */
static int fw_lookup_and_allocate_buf(const char *fw_name,
struct firmware_cache *fwc,
struct firmware_buf **buf, void *dbuf,
@@ -344,6 +347,7 @@ static int fw_lookup_and_allocate_buf(const char *fw_name,
kref_get(&tmp->ref);
spin_unlock(&fwc->lock);
*buf = tmp;
+ pr_debug("batched request - sharing the same struct firmware_buf and lookup for multiple requests\n");
return 1;
}
tmp = __allocate_fw_buf(fw_name, fwc, dbuf, size);
@@ -1085,9 +1089,12 @@ static int _request_firmware_load(struct firmware_priv *fw_priv,
mutex_unlock(&fw_lock);
}
- if (fw_state_is_aborted(&buf->fw_st))
- retval = -EAGAIN;
- else if (buf->is_paged_buf && !buf->data)
+ if (fw_state_is_aborted(&buf->fw_st)) {
+ if (retval == -ERESTARTSYS)
+ retval = -EINTR;
+ else
+ retval = -EAGAIN;
+ } else if (buf->is_paged_buf && !buf->data)
retval = -ENOMEM;
device_del(f_dev);
diff --git a/drivers/base/topology.c b/drivers/base/topology.c
index d6ec1c5..d936fcf 100644
--- a/drivers/base/topology.c
+++ b/drivers/base/topology.c
@@ -105,7 +105,7 @@ static struct attribute *default_attrs[] = {
NULL
};
-static struct attribute_group topology_attr_group = {
+static const struct attribute_group topology_attr_group = {
.attrs = default_attrs,
.name = "topology"
};
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 8ddc982..80aaf34 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -470,7 +470,7 @@ config VIRTIO_BLK
depends on VIRTIO
---help---
This is the virtual block driver for virtio. It can be used with
- lguest or QEMU based VMMs (like KVM or Xen). Say Y or M.
+ QEMU based VMMs (like KVM or Xen). Say Y or M.
config VIRTIO_BLK_SCSI
bool "SCSI passthrough request for the Virtio block driver"
diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c
index 85c24ca..81142ce 100644
--- a/drivers/block/null_blk.c
+++ b/drivers/block/null_blk.c
@@ -13,7 +13,7 @@
struct nullb_cmd {
struct list_head list;
struct llist_node ll_list;
- struct call_single_data csd;
+ call_single_data_t csd;
struct request *rq;
struct bio *bio;
unsigned int tag;
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c
index 792da68..2adb859 100644
--- a/drivers/block/xen-blkback/xenbus.c
+++ b/drivers/block/xen-blkback/xenbus.c
@@ -244,6 +244,7 @@ static int xen_blkif_disconnect(struct xen_blkif *blkif)
{
struct pending_req *req, *n;
unsigned int j, r;
+ bool busy = false;
for (r = 0; r < blkif->nr_rings; r++) {
struct xen_blkif_ring *ring = &blkif->rings[r];
@@ -261,8 +262,10 @@ static int xen_blkif_disconnect(struct xen_blkif *blkif)
* don't have any discard_io or other_io requests. So, checking
* for inflight IO is enough.
*/
- if (atomic_read(&ring->inflight) > 0)
- return -EBUSY;
+ if (atomic_read(&ring->inflight) > 0) {
+ busy = true;
+ continue;
+ }
if (ring->irq) {
unbind_from_irqhandler(ring->irq, ring);
@@ -300,6 +303,9 @@ static int xen_blkif_disconnect(struct xen_blkif *blkif)
WARN_ON(i != (XEN_BLKIF_REQS_PER_PAGE * blkif->nr_ring_pages));
ring->active = false;
}
+ if (busy)
+ return -EBUSY;
+
blkif->nr_ring_pages = 0;
/*
* blkif->rings was allocated in connect_ring, so we should free it in
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index ccd239a..6237143 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -161,7 +161,7 @@ config VIRTIO_CONSOLE
depends on VIRTIO && TTY
select HVC_DRIVER
help
- Virtio console for use with lguest and other hypervisors.
+ Virtio console for use with hypervisors.
Also serves as a general-purpose serial device for data
transfer between the guest and host. Character devices at
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c
index dcbbb4e..89527ba 100644
--- a/drivers/char/agp/ali-agp.c
+++ b/drivers/char/agp/ali-agp.c
@@ -381,7 +381,7 @@ static void agp_ali_remove(struct pci_dev *pdev)
agp_put_bridge(bridge);
}
-static struct pci_device_id agp_ali_pci_table[] = {
+static const struct pci_device_id agp_ali_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index 5fbd333..b450544 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -21,7 +21,7 @@
#define AMD_TLBFLUSH 0x0c /* In mmio region (32-bit register) */
#define AMD_CACHEENTRY 0x10 /* In mmio region (32-bit register) */
-static struct pci_device_id agp_amdk7_pci_table[];
+static const struct pci_device_id agp_amdk7_pci_table[];
struct amd_page_map {
unsigned long *real;
@@ -508,7 +508,7 @@ static int agp_amdk7_resume(struct pci_dev *pdev)
#endif /* CONFIG_PM */
/* must be the same order as name table above */
-static struct pci_device_id agp_amdk7_pci_table[] = {
+static const struct pci_device_id agp_amdk7_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index c99cd19..e50c29c 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -610,7 +610,7 @@ static int agp_amd64_resume(struct pci_dev *pdev)
#endif /* CONFIG_PM */
-static struct pci_device_id agp_amd64_pci_table[] = {
+static const struct pci_device_id agp_amd64_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index 0b5ec7a..88b4cbe 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -540,7 +540,7 @@ static void agp_ati_remove(struct pci_dev *pdev)
agp_put_bridge(bridge);
}
-static struct pci_device_id agp_ati_pci_table[] = {
+static const struct pci_device_id agp_ati_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c
index 533cb6d..7f88490 100644
--- a/drivers/char/agp/efficeon-agp.c
+++ b/drivers/char/agp/efficeon-agp.c
@@ -427,7 +427,7 @@ static int agp_efficeon_resume(struct pci_dev *pdev)
}
#endif
-static struct pci_device_id agp_efficeon_pci_table[] = {
+static const struct pci_device_id agp_efficeon_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 0a21dae..9e4f27a 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -828,7 +828,7 @@ static int agp_intel_resume(struct pci_dev *pdev)
}
#endif
-static struct pci_device_id agp_intel_pci_table[] = {
+static const struct pci_device_id agp_intel_pci_table[] = {
#define ID(x) \
{ \
.class = (PCI_CLASS_BRIDGE_HOST << 8), \
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c
index 6c8d39c..828b344 100644
--- a/drivers/char/agp/nvidia-agp.c
+++ b/drivers/char/agp/nvidia-agp.c
@@ -420,7 +420,7 @@ static int agp_nvidia_resume(struct pci_dev *pdev)
#endif
-static struct pci_device_id agp_nvidia_pci_table[] = {
+static const struct pci_device_id agp_nvidia_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
index 2c74038..14909fc 100644
--- a/drivers/char/agp/sis-agp.c
+++ b/drivers/char/agp/sis-agp.c
@@ -237,7 +237,7 @@ static int agp_sis_resume(struct pci_dev *pdev)
#endif /* CONFIG_PM */
-static struct pci_device_id agp_sis_pci_table[] = {
+static const struct pci_device_id agp_sis_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index fdced54..c381c8e 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -679,7 +679,7 @@ static void agp_uninorth_remove(struct pci_dev *pdev)
agp_put_bridge(bridge);
}
-static struct pci_device_id agp_uninorth_pci_table[] = {
+static const struct pci_device_id agp_uninorth_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 9859738..36f47e8 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -2812,7 +2812,7 @@ static struct platform_driver ipmi_driver = {
};
#ifdef CONFIG_PARISC
-static int ipmi_parisc_probe(struct parisc_device *dev)
+static int __init ipmi_parisc_probe(struct parisc_device *dev)
{
struct smi_info *info;
int rv;
@@ -2850,22 +2850,24 @@ static int ipmi_parisc_probe(struct parisc_device *dev)
return 0;
}
-static int ipmi_parisc_remove(struct parisc_device *dev)
+static int __exit ipmi_parisc_remove(struct parisc_device *dev)
{
cleanup_one_si(dev_get_drvdata(&dev->dev));
return 0;
}
-static const struct parisc_device_id ipmi_parisc_tbl[] = {
+static const struct parisc_device_id ipmi_parisc_tbl[] __initconst = {
{ HPHW_MC, HVERSION_REV_ANY_ID, 0x004, 0xC0 },
{ 0, }
};
-static struct parisc_driver ipmi_parisc_driver = {
+MODULE_DEVICE_TABLE(parisc, ipmi_parisc_tbl);
+
+static struct parisc_driver ipmi_parisc_driver __refdata = {
.name = "ipmi",
.id_table = ipmi_parisc_tbl,
.probe = ipmi_parisc_probe,
- .remove = ipmi_parisc_remove,
+ .remove = __exit_p(ipmi_parisc_remove),
};
#endif /* CONFIG_PARISC */
diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 67ec9d3..0eca20c 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -164,14 +164,7 @@ static int tpm_class_shutdown(struct device *dev)
chip->ops = NULL;
up_write(&chip->ops_sem);
}
- /* Allow bus- and device-specific code to run. Note: since chip->ops
- * is NULL, more-specific shutdown code will not be able to issue TPM
- * commands.
- */
- if (dev->bus && dev->bus->shutdown)
- dev->bus->shutdown(dev);
- else if (dev->driver && dev->driver->shutdown)
- dev->driver->shutdown(dev);
+
return 0;
}
@@ -214,7 +207,7 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
device_initialize(&chip->devs);
chip->dev.class = tpm_class;
- chip->dev.class->shutdown = tpm_class_shutdown;
+ chip->dev.class->shutdown_pre = tpm_class_shutdown;
chip->dev.release = tpm_dev_release;
chip->dev.parent = pdev;
chip->dev.groups = chip->groups;
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 06bd635..23f33f9 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -1130,7 +1130,7 @@ static const struct file_operations port_fops = {
* We turn the characters into a scatter-gather list, add it to the
* output queue and then kick the Host. Then we sit here waiting for
* it to finish: inefficient in theory, but in practice
- * implementations will do it immediately (lguest's Launcher does).
+ * implementations will do it immediately.
*/
static int put_chars(u32 vtermno, const char *buf, int count)
{
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 54a67f8..cc60620 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -598,6 +598,14 @@ config CLKSRC_IMX_GPT
depends on ARM && CLKDEV_LOOKUP
select CLKSRC_MMIO
+config CLKSRC_IMX_TPM
+ bool "Clocksource using i.MX TPM" if COMPILE_TEST
+ depends on ARM && CLKDEV_LOOKUP && GENERIC_CLOCKEVENTS
+ select CLKSRC_MMIO
+ help
+ Enable this option to use IMX Timer/PWM Module (TPM) timer as
+ clocksource.
+
config CLKSRC_ST_LPC
bool "Low power clocksource found in the LPC" if COMPILE_TEST
select TIMER_OF if OF
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 6df9494..dbc1ad1 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -67,6 +67,7 @@ obj-$(CONFIG_CLKSRC_VERSATILE) += versatile.o
obj-$(CONFIG_CLKSRC_MIPS_GIC) += mips-gic-timer.o
obj-$(CONFIG_CLKSRC_TANGO_XTAL) += tango_xtal.o
obj-$(CONFIG_CLKSRC_IMX_GPT) += timer-imx-gpt.o
+obj-$(CONFIG_CLKSRC_IMX_TPM) += timer-imx-tpm.o
obj-$(CONFIG_ASM9260_TIMER) += asm9260_timer.o
obj-$(CONFIG_H8300_TMR8) += h8300_timer8.o
obj-$(CONFIG_H8300_TMR16) += h8300_timer16.o
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 72bbfcc..fd4b7f6 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -455,7 +455,11 @@ void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa
per_cpu(timer_unstable_counter_workaround, i) = wa;
}
- static_branch_enable(&arch_timer_read_ool_enabled);
+ /*
+ * Use the locked version, as we're called from the CPU
+ * hotplug framework. Otherwise, we end-up in deadlock-land.
+ */
+ static_branch_enable_cpuslocked(&arch_timer_read_ool_enabled);
/*
* Don't use the vdso fastpath if errata require using the
diff --git a/drivers/clocksource/bcm2835_timer.c b/drivers/clocksource/bcm2835_timer.c
index 82828d3..39e489a 100644
--- a/drivers/clocksource/bcm2835_timer.c
+++ b/drivers/clocksource/bcm2835_timer.c
@@ -114,7 +114,6 @@ static int __init bcm2835_timer_init(struct device_node *node)
timer = kzalloc(sizeof(*timer), GFP_KERNEL);
if (!timer) {
- pr_err("Can't allocate timer struct\n");
ret = -ENOMEM;
goto err_iounmap;
}
diff --git a/drivers/clocksource/tango_xtal.c b/drivers/clocksource/tango_xtal.c
index c4e1c2e..6a8d9838 100644
--- a/drivers/clocksource/tango_xtal.c
+++ b/drivers/clocksource/tango_xtal.c
@@ -26,13 +26,13 @@ static int __init tango_clocksource_init(struct device_node *np)
xtal_in_cnt = of_iomap(np, 0);
if (xtal_in_cnt == NULL) {
- pr_err("%s: invalid address\n", np->full_name);
+ pr_err("%pOF: invalid address\n", np);
return -ENXIO;
}
clk = of_clk_get(np, 0);
if (IS_ERR(clk)) {
- pr_err("%s: invalid clock\n", np->full_name);
+ pr_err("%pOF: invalid clock\n", np);
return PTR_ERR(clk);
}
@@ -43,7 +43,7 @@ static int __init tango_clocksource_init(struct device_node *np)
ret = clocksource_mmio_init(xtal_in_cnt, "tango-xtal", xtal_freq, 350,
32, clocksource_mmio_readl_up);
if (ret) {
- pr_err("%s: registration failed\n", np->full_name);
+ pr_err("%pOF: registration failed\n", np);
return ret;
}
diff --git a/drivers/clocksource/timer-imx-tpm.c b/drivers/clocksource/timer-imx-tpm.c
new file mode 100644
index 0000000..21bffdc
--- /dev/null
+++ b/drivers/clocksource/timer-imx-tpm.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ */
+
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/sched_clock.h>
+
+#define TPM_SC 0x10
+#define TPM_SC_CMOD_INC_PER_CNT (0x1 << 3)
+#define TPM_SC_CMOD_DIV_DEFAULT 0x3
+#define TPM_CNT 0x14
+#define TPM_MOD 0x18
+#define TPM_STATUS 0x1c
+#define TPM_STATUS_CH0F BIT(0)
+#define TPM_C0SC 0x20
+#define TPM_C0SC_CHIE BIT(6)
+#define TPM_C0SC_MODE_SHIFT 2
+#define TPM_C0SC_MODE_MASK 0x3c
+#define TPM_C0SC_MODE_SW_COMPARE 0x4
+#define TPM_C0V 0x24
+
+static void __iomem *timer_base;
+static struct clock_event_device clockevent_tpm;
+
+static inline void tpm_timer_disable(void)
+{
+ unsigned int val;
+
+ /* channel disable */
+ val = readl(timer_base + TPM_C0SC);
+ val &= ~(TPM_C0SC_MODE_MASK | TPM_C0SC_CHIE);
+ writel(val, timer_base + TPM_C0SC);
+}
+
+static inline void tpm_timer_enable(void)
+{
+ unsigned int val;
+
+ /* channel enabled in sw compare mode */
+ val = readl(timer_base + TPM_C0SC);
+ val |= (TPM_C0SC_MODE_SW_COMPARE << TPM_C0SC_MODE_SHIFT) |
+ TPM_C0SC_CHIE;
+ writel(val, timer_base + TPM_C0SC);
+}
+
+static inline void tpm_irq_acknowledge(void)
+{
+ writel(TPM_STATUS_CH0F, timer_base + TPM_STATUS);
+}
+
+static struct delay_timer tpm_delay_timer;
+
+static inline unsigned long tpm_read_counter(void)
+{
+ return readl(timer_base + TPM_CNT);
+}
+
+static unsigned long tpm_read_current_timer(void)
+{
+ return tpm_read_counter();
+}
+
+static u64 notrace tpm_read_sched_clock(void)
+{
+ return tpm_read_counter();
+}
+
+static int __init tpm_clocksource_init(unsigned long rate)
+{
+ tpm_delay_timer.read_current_timer = &tpm_read_current_timer;
+ tpm_delay_timer.freq = rate;
+ register_current_timer_delay(&tpm_delay_timer);
+
+ sched_clock_register(tpm_read_sched_clock, 32, rate);
+
+ return clocksource_mmio_init(timer_base + TPM_CNT, "imx-tpm",
+ rate, 200, 32, clocksource_mmio_readl_up);
+}
+
+static int tpm_set_next_event(unsigned long delta,
+ struct clock_event_device *evt)
+{
+ unsigned long next, now;
+
+ next = tpm_read_counter();
+ next += delta;
+ writel(next, timer_base + TPM_C0V);
+ now = tpm_read_counter();
+
+ /*
+ * NOTE: We observed in a very small probability, the bus fabric
+ * contention between GPU and A7 may results a few cycles delay
+ * of writing CNT registers which may cause the min_delta event got
+ * missed, so we need add a ETIME check here in case it happened.
+ */
+ return (int)((next - now) <= 0) ? -ETIME : 0;
+}
+
+static int tpm_set_state_oneshot(struct clock_event_device *evt)
+{
+ tpm_timer_enable();
+
+ return 0;
+}
+
+static int tpm_set_state_shutdown(struct clock_event_device *evt)
+{
+ tpm_timer_disable();
+
+ return 0;
+}
+
+static irqreturn_t tpm_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+
+ tpm_irq_acknowledge();
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct clock_event_device clockevent_tpm = {
+ .name = "i.MX7ULP TPM Timer",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .set_state_oneshot = tpm_set_state_oneshot,
+ .set_next_event = tpm_set_next_event,
+ .set_state_shutdown = tpm_set_state_shutdown,
+ .rating = 200,
+};
+
+static int __init tpm_clockevent_init(unsigned long rate, int irq)
+{
+ int ret;
+
+ ret = request_irq(irq, tpm_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL,
+ "i.MX7ULP TPM Timer", &clockevent_tpm);
+
+ clockevent_tpm.cpumask = cpumask_of(0);
+ clockevent_tpm.irq = irq;
+ clockevents_config_and_register(&clockevent_tpm,
+ rate, 300, 0xfffffffe);
+
+ return ret;
+}
+
+static int __init tpm_timer_init(struct device_node *np)
+{
+ struct clk *ipg, *per;
+ int irq, ret;
+ u32 rate;
+
+ timer_base = of_iomap(np, 0);
+ if (!timer_base) {
+ pr_err("tpm: failed to get base address\n");
+ return -ENXIO;
+ }
+
+ irq = irq_of_parse_and_map(np, 0);
+ if (!irq) {
+ pr_err("tpm: failed to get irq\n");
+ ret = -ENOENT;
+ goto err_iomap;
+ }
+
+ ipg = of_clk_get_by_name(np, "ipg");
+ per = of_clk_get_by_name(np, "per");
+ if (IS_ERR(ipg) || IS_ERR(per)) {
+ pr_err("tpm: failed to get igp or per clk\n");
+ ret = -ENODEV;
+ goto err_clk_get;
+ }
+
+ /* enable clk before accessing registers */
+ ret = clk_prepare_enable(ipg);
+ if (ret) {
+ pr_err("tpm: ipg clock enable failed (%d)\n", ret);
+ goto err_clk_get;
+ }
+
+ ret = clk_prepare_enable(per);
+ if (ret) {
+ pr_err("tpm: per clock enable failed (%d)\n", ret);
+ goto err_per_clk_enable;
+ }
+
+ /*
+ * Initialize tpm module to a known state
+ * 1) Counter disabled
+ * 2) TPM counter operates in up counting mode
+ * 3) Timer Overflow Interrupt disabled
+ * 4) Channel0 disabled
+ * 5) DMA transfers disabled
+ */
+ writel(0, timer_base + TPM_SC);
+ writel(0, timer_base + TPM_CNT);
+ writel(0, timer_base + TPM_C0SC);
+
+ /* increase per cnt, div 8 by default */
+ writel(TPM_SC_CMOD_INC_PER_CNT | TPM_SC_CMOD_DIV_DEFAULT,
+ timer_base + TPM_SC);
+
+ /* set MOD register to maximum for free running mode */
+ writel(0xffffffff, timer_base + TPM_MOD);
+
+ rate = clk_get_rate(per) >> 3;
+ ret = tpm_clocksource_init(rate);
+ if (ret)
+ goto err_per_clk_enable;
+
+ ret = tpm_clockevent_init(rate, irq);
+ if (ret)
+ goto err_per_clk_enable;
+
+ return 0;
+
+err_per_clk_enable:
+ clk_disable_unprepare(ipg);
+err_clk_get:
+ clk_put(per);
+ clk_put(ipg);
+err_iomap:
+ iounmap(timer_base);
+ return ret;
+}
+TIMER_OF_DECLARE(imx7ulp, "fsl,imx7ulp-tpm", tpm_timer_init);
diff --git a/drivers/clocksource/timer-of.c b/drivers/clocksource/timer-of.c
index 4d7aef9..c79122d 100644
--- a/drivers/clocksource/timer-of.c
+++ b/drivers/clocksource/timer-of.c
@@ -52,7 +52,7 @@ static __init int timer_irq_init(struct device_node *np,
of_irq->irq = irq_of_parse_and_map(np, of_irq->index);
}
if (!of_irq->irq) {
- pr_err("Failed to map interrupt for %s\n", np->full_name);
+ pr_err("Failed to map interrupt for %pOF\n", np);
return -EINVAL;
}
@@ -63,8 +63,7 @@ static __init int timer_irq_init(struct device_node *np,
of_irq->flags ? of_irq->flags : IRQF_TIMER,
np->full_name, clkevt);
if (ret) {
- pr_err("Failed to request irq %d for %s\n", of_irq->irq,
- np->full_name);
+ pr_err("Failed to request irq %d for %pOF\n", of_irq->irq, np);
return ret;
}
@@ -88,20 +87,20 @@ static __init int timer_clk_init(struct device_node *np,
of_clk->clk = of_clk->name ? of_clk_get_by_name(np, of_clk->name) :
of_clk_get(np, of_clk->index);
if (IS_ERR(of_clk->clk)) {
- pr_err("Failed to get clock for %s\n", np->full_name);
+ pr_err("Failed to get clock for %pOF\n", np);
return PTR_ERR(of_clk->clk);
}
ret = clk_prepare_enable(of_clk->clk);
if (ret) {
- pr_err("Failed for enable clock for %s\n", np->full_name);
+ pr_err("Failed for enable clock for %pOF\n", np);
goto out_clk_put;
}
of_clk->rate = clk_get_rate(of_clk->clk);
if (!of_clk->rate) {
ret = -EINVAL;
- pr_err("Failed to get clock rate for %s\n", np->full_name);
+ pr_err("Failed to get clock rate for %pOF\n", np);
goto out_clk_disable;
}
diff --git a/drivers/clocksource/timer-probe.c b/drivers/clocksource/timer-probe.c
index da81e5d..0280757 100644
--- a/drivers/clocksource/timer-probe.c
+++ b/drivers/clocksource/timer-probe.c
@@ -40,8 +40,7 @@ void __init timer_probe(void)
ret = init_func_ret(np);
if (ret) {
- pr_err("Failed to initialize '%s': %d\n",
- of_node_full_name(np), ret);
+ pr_err("Failed to initialize '%pOF': %d\n", np, ret);
continue;
}
diff --git a/drivers/clocksource/timer-stm32.c b/drivers/clocksource/timer-stm32.c
index 174d1243..8f24237 100644
--- a/drivers/clocksource/timer-stm32.c
+++ b/drivers/clocksource/timer-stm32.c
@@ -138,7 +138,7 @@ static int __init stm32_clockevent_init(struct device_node *np)
irq = irq_of_parse_and_map(np, 0);
if (!irq) {
ret = -EINVAL;
- pr_err("%s: failed to get irq.\n", np->full_name);
+ pr_err("%pOF: failed to get irq.\n", np);
goto err_get_irq;
}
@@ -168,12 +168,12 @@ static int __init stm32_clockevent_init(struct device_node *np)
ret = request_irq(irq, stm32_clock_event_handler, IRQF_TIMER,
"stm32 clockevent", data);
if (ret) {
- pr_err("%s: failed to request irq.\n", np->full_name);
+ pr_err("%pOF: failed to request irq.\n", np);
goto err_get_irq;
}
- pr_info("%s: STM32 clockevent driver initialized (%d bits)\n",
- np->full_name, bits);
+ pr_info("%pOF: STM32 clockevent driver initialized (%d bits)\n",
+ np, bits);
return ret;
diff --git a/drivers/cpuidle/coupled.c b/drivers/cpuidle/coupled.c
index 71e586d..147f38e 100644
--- a/drivers/cpuidle/coupled.c
+++ b/drivers/cpuidle/coupled.c
@@ -119,13 +119,13 @@ struct cpuidle_coupled {
#define CPUIDLE_COUPLED_NOT_IDLE (-1)
-static DEFINE_PER_CPU(struct call_single_data, cpuidle_coupled_poke_cb);
+static DEFINE_PER_CPU(call_single_data_t, cpuidle_coupled_poke_cb);
/*
* The cpuidle_coupled_poke_pending mask is used to avoid calling
- * __smp_call_function_single with the per cpu call_single_data struct already
+ * __smp_call_function_single with the per cpu call_single_data_t struct already
* in use. This prevents a deadlock where two cpus are waiting for each others
- * call_single_data struct to be available
+ * call_single_data_t struct to be available
*/
static cpumask_t cpuidle_coupled_poke_pending;
@@ -339,7 +339,7 @@ static void cpuidle_coupled_handle_poke(void *info)
*/
static void cpuidle_coupled_poke(int cpu)
{
- struct call_single_data *csd = &per_cpu(cpuidle_coupled_poke_cb, cpu);
+ call_single_data_t *csd = &per_cpu(cpuidle_coupled_poke_cb, cpu);
if (!cpumask_test_and_set_cpu(cpu, &cpuidle_coupled_poke_pending))
smp_call_function_single_async(cpu, csd);
@@ -651,7 +651,7 @@ int cpuidle_coupled_register_device(struct cpuidle_device *dev)
{
int cpu;
struct cpuidle_device *other_dev;
- struct call_single_data *csd;
+ call_single_data_t *csd;
struct cpuidle_coupled *coupled;
if (cpumask_empty(&dev->coupled_cpus))
diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
index 56e0a0e..9a30279 100644
--- a/drivers/dma-buf/dma-fence.c
+++ b/drivers/dma-buf/dma-fence.c
@@ -48,7 +48,7 @@ static atomic64_t dma_fence_context_counter = ATOMIC64_INIT(0);
*/
u64 dma_fence_context_alloc(unsigned num)
{
- BUG_ON(!num);
+ WARN_ON(!num);
return atomic64_add_return(num, &dma_fence_context_counter) - num;
}
EXPORT_SYMBOL(dma_fence_context_alloc);
@@ -172,7 +172,7 @@ void dma_fence_release(struct kref *kref)
trace_dma_fence_destroy(fence);
- BUG_ON(!list_empty(&fence->cb_list));
+ WARN_ON(!list_empty(&fence->cb_list));
if (fence->ops->release)
fence->ops->release(fence);
diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
index 393817e..dec3a81 100644
--- a/drivers/dma-buf/reservation.c
+++ b/drivers/dma-buf/reservation.c
@@ -195,8 +195,7 @@ done:
if (old)
kfree_rcu(old, rcu);
- if (old_fence)
- dma_fence_put(old_fence);
+ dma_fence_put(old_fence);
}
/**
@@ -258,12 +257,71 @@ void reservation_object_add_excl_fence(struct reservation_object *obj,
dma_fence_put(rcu_dereference_protected(old->shared[i],
reservation_object_held(obj)));
- if (old_fence)
- dma_fence_put(old_fence);
+ dma_fence_put(old_fence);
}
EXPORT_SYMBOL(reservation_object_add_excl_fence);
/**
+* reservation_object_copy_fences - Copy all fences from src to dst.
+* @dst: the destination reservation object
+* @src: the source reservation object
+*
+* Copy all fences from src to dst. Both src->lock as well as dst-lock must be
+* held.
+*/
+int reservation_object_copy_fences(struct reservation_object *dst,
+ struct reservation_object *src)
+{
+ struct reservation_object_list *src_list, *dst_list;
+ struct dma_fence *old, *new;
+ size_t size;
+ unsigned i;
+
+ src_list = reservation_object_get_list(src);
+
+ if (src_list) {
+ size = offsetof(typeof(*src_list),
+ shared[src_list->shared_count]);
+ dst_list = kmalloc(size, GFP_KERNEL);
+ if (!dst_list)
+ return -ENOMEM;
+
+ dst_list->shared_count = src_list->shared_count;
+ dst_list->shared_max = src_list->shared_count;
+ for (i = 0; i < src_list->shared_count; ++i)
+ dst_list->shared[i] =
+ dma_fence_get(src_list->shared[i]);
+ } else {
+ dst_list = NULL;
+ }
+
+ kfree(dst->staged);
+ dst->staged = NULL;
+
+ src_list = reservation_object_get_list(dst);
+
+ old = reservation_object_get_excl(dst);
+ new = reservation_object_get_excl(src);
+
+ dma_fence_get(new);
+
+ preempt_disable();
+ write_seqcount_begin(&dst->seq);
+ /* write_seqcount_begin provides the necessary memory barrier */
+ RCU_INIT_POINTER(dst->fence_excl, new);
+ RCU_INIT_POINTER(dst->fence, dst_list);
+ write_seqcount_end(&dst->seq);
+ preempt_enable();
+
+ if (src_list)
+ kfree_rcu(src_list, rcu);
+ dma_fence_put(old);
+
+ return 0;
+}
+EXPORT_SYMBOL(reservation_object_copy_fences);
+
+/**
* reservation_object_get_fences_rcu - Get an object's shared and exclusive
* fences without update side lock held
* @obj: the reservation object
@@ -373,12 +431,25 @@ long reservation_object_wait_timeout_rcu(struct reservation_object *obj,
long ret = timeout ? timeout : 1;
retry:
- fence = NULL;
shared_count = 0;
seq = read_seqcount_begin(&obj->seq);
rcu_read_lock();
- if (wait_all) {
+ fence = rcu_dereference(obj->fence_excl);
+ if (fence && !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) {
+ if (!dma_fence_get_rcu(fence))
+ goto unlock_retry;
+
+ if (dma_fence_is_signaled(fence)) {
+ dma_fence_put(fence);
+ fence = NULL;
+ }
+
+ } else {
+ fence = NULL;
+ }
+
+ if (!fence && wait_all) {
struct reservation_object_list *fobj =
rcu_dereference(obj->fence);
@@ -405,22 +476,6 @@ retry:
}
}
- if (!shared_count) {
- struct dma_fence *fence_excl = rcu_dereference(obj->fence_excl);
-
- if (fence_excl &&
- !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
- &fence_excl->flags)) {
- if (!dma_fence_get_rcu(fence_excl))
- goto unlock_retry;
-
- if (dma_fence_is_signaled(fence_excl))
- dma_fence_put(fence_excl);
- else
- fence = fence_excl;
- }
- }
-
rcu_read_unlock();
if (fence) {
if (read_seqcount_retry(&obj->seq, seq)) {
diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
index 69c5ff3..38cc738 100644
--- a/drivers/dma-buf/sw_sync.c
+++ b/drivers/dma-buf/sw_sync.c
@@ -96,9 +96,9 @@ static struct sync_timeline *sync_timeline_create(const char *name)
obj->context = dma_fence_context_alloc(1);
strlcpy(obj->name, name, sizeof(obj->name));
- INIT_LIST_HEAD(&obj->child_list_head);
- INIT_LIST_HEAD(&obj->active_list_head);
- spin_lock_init(&obj->child_list_lock);
+ obj->pt_tree = RB_ROOT;
+ INIT_LIST_HEAD(&obj->pt_list);
+ spin_lock_init(&obj->lock);
sync_timeline_debug_add(obj);
@@ -125,68 +125,6 @@ static void sync_timeline_put(struct sync_timeline *obj)
kref_put(&obj->kref, sync_timeline_free);
}
-/**
- * sync_timeline_signal() - signal a status change on a sync_timeline
- * @obj: sync_timeline to signal
- * @inc: num to increment on timeline->value
- *
- * A sync implementation should call this any time one of it's fences
- * has signaled or has an error condition.
- */
-static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc)
-{
- unsigned long flags;
- struct sync_pt *pt, *next;
-
- trace_sync_timeline(obj);
-
- spin_lock_irqsave(&obj->child_list_lock, flags);
-
- obj->value += inc;
-
- list_for_each_entry_safe(pt, next, &obj->active_list_head,
- active_list) {
- if (dma_fence_is_signaled_locked(&pt->base))
- list_del_init(&pt->active_list);
- }
-
- spin_unlock_irqrestore(&obj->child_list_lock, flags);
-}
-
-/**
- * sync_pt_create() - creates a sync pt
- * @parent: fence's parent sync_timeline
- * @size: size to allocate for this pt
- * @inc: value of the fence
- *
- * Creates a new sync_pt as a child of @parent. @size bytes will be
- * allocated allowing for implementation specific data to be kept after
- * the generic sync_timeline struct. Returns the sync_pt object or
- * NULL in case of error.
- */
-static struct sync_pt *sync_pt_create(struct sync_timeline *obj, int size,
- unsigned int value)
-{
- unsigned long flags;
- struct sync_pt *pt;
-
- if (size < sizeof(*pt))
- return NULL;
-
- pt = kzalloc(size, GFP_KERNEL);
- if (!pt)
- return NULL;
-
- spin_lock_irqsave(&obj->child_list_lock, flags);
- sync_timeline_get(obj);
- dma_fence_init(&pt->base, &timeline_fence_ops, &obj->child_list_lock,
- obj->context, value);
- list_add_tail(&pt->child_list, &obj->child_list_head);
- INIT_LIST_HEAD(&pt->active_list);
- spin_unlock_irqrestore(&obj->child_list_lock, flags);
- return pt;
-}
-
static const char *timeline_fence_get_driver_name(struct dma_fence *fence)
{
return "sw_sync";
@@ -203,13 +141,17 @@ static void timeline_fence_release(struct dma_fence *fence)
{
struct sync_pt *pt = dma_fence_to_sync_pt(fence);
struct sync_timeline *parent = dma_fence_parent(fence);
- unsigned long flags;
- spin_lock_irqsave(fence->lock, flags);
- list_del(&pt->child_list);
- if (!list_empty(&pt->active_list))
- list_del(&pt->active_list);
- spin_unlock_irqrestore(fence->lock, flags);
+ if (!list_empty(&pt->link)) {
+ unsigned long flags;
+
+ spin_lock_irqsave(fence->lock, flags);
+ if (!list_empty(&pt->link)) {
+ list_del(&pt->link);
+ rb_erase(&pt->node, &parent->pt_tree);
+ }
+ spin_unlock_irqrestore(fence->lock, flags);
+ }
sync_timeline_put(parent);
dma_fence_free(fence);
@@ -219,18 +161,11 @@ static bool timeline_fence_signaled(struct dma_fence *fence)
{
struct sync_timeline *parent = dma_fence_parent(fence);
- return (fence->seqno > parent->value) ? false : true;
+ return !__dma_fence_is_later(fence->seqno, parent->value);
}
static bool timeline_fence_enable_signaling(struct dma_fence *fence)
{
- struct sync_pt *pt = dma_fence_to_sync_pt(fence);
- struct sync_timeline *parent = dma_fence_parent(fence);
-
- if (timeline_fence_signaled(fence))
- return false;
-
- list_add_tail(&pt->active_list, &parent->active_list_head);
return true;
}
@@ -259,6 +194,107 @@ static const struct dma_fence_ops timeline_fence_ops = {
.timeline_value_str = timeline_fence_timeline_value_str,
};
+/**
+ * sync_timeline_signal() - signal a status change on a sync_timeline
+ * @obj: sync_timeline to signal
+ * @inc: num to increment on timeline->value
+ *
+ * A sync implementation should call this any time one of it's fences
+ * has signaled or has an error condition.
+ */
+static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc)
+{
+ struct sync_pt *pt, *next;
+
+ trace_sync_timeline(obj);
+
+ spin_lock_irq(&obj->lock);
+
+ obj->value += inc;
+
+ list_for_each_entry_safe(pt, next, &obj->pt_list, link) {
+ if (!timeline_fence_signaled(&pt->base))
+ break;
+
+ list_del_init(&pt->link);
+ rb_erase(&pt->node, &obj->pt_tree);
+
+ /*
+ * A signal callback may release the last reference to this
+ * fence, causing it to be freed. That operation has to be
+ * last to avoid a use after free inside this loop, and must
+ * be after we remove the fence from the timeline in order to
+ * prevent deadlocking on timeline->lock inside
+ * timeline_fence_release().
+ */
+ dma_fence_signal_locked(&pt->base);
+ }
+
+ spin_unlock_irq(&obj->lock);
+}
+
+/**
+ * sync_pt_create() - creates a sync pt
+ * @parent: fence's parent sync_timeline
+ * @inc: value of the fence
+ *
+ * Creates a new sync_pt as a child of @parent. @size bytes will be
+ * allocated allowing for implementation specific data to be kept after
+ * the generic sync_timeline struct. Returns the sync_pt object or
+ * NULL in case of error.
+ */
+static struct sync_pt *sync_pt_create(struct sync_timeline *obj,
+ unsigned int value)
+{
+ struct sync_pt *pt;
+
+ pt = kzalloc(sizeof(*pt), GFP_KERNEL);
+ if (!pt)
+ return NULL;
+
+ sync_timeline_get(obj);
+ dma_fence_init(&pt->base, &timeline_fence_ops, &obj->lock,
+ obj->context, value);
+ INIT_LIST_HEAD(&pt->link);
+
+ spin_lock_irq(&obj->lock);
+ if (!dma_fence_is_signaled_locked(&pt->base)) {
+ struct rb_node **p = &obj->pt_tree.rb_node;
+ struct rb_node *parent = NULL;
+
+ while (*p) {
+ struct sync_pt *other;
+ int cmp;
+
+ parent = *p;
+ other = rb_entry(parent, typeof(*pt), node);
+ cmp = value - other->base.seqno;
+ if (cmp > 0) {
+ p = &parent->rb_right;
+ } else if (cmp < 0) {
+ p = &parent->rb_left;
+ } else {
+ if (dma_fence_get_rcu(&other->base)) {
+ dma_fence_put(&pt->base);
+ pt = other;
+ goto unlock;
+ }
+ p = &parent->rb_left;
+ }
+ }
+ rb_link_node(&pt->node, parent, p);
+ rb_insert_color(&pt->node, &obj->pt_tree);
+
+ parent = rb_next(&pt->node);
+ list_add_tail(&pt->link,
+ parent ? &rb_entry(parent, typeof(*pt), node)->link : &obj->pt_list);
+ }
+unlock:
+ spin_unlock_irq(&obj->lock);
+
+ return pt;
+}
+
/*
* *WARNING*
*
@@ -309,7 +345,7 @@ static long sw_sync_ioctl_create_fence(struct sync_timeline *obj,
goto err;
}
- pt = sync_pt_create(obj, sizeof(*pt), data.value);
+ pt = sync_pt_create(obj, data.value);
if (!pt) {
err = -ENOMEM;
goto err;
@@ -345,6 +381,11 @@ static long sw_sync_ioctl_inc(struct sync_timeline *obj, unsigned long arg)
if (copy_from_user(&value, (void __user *)arg, sizeof(value)))
return -EFAULT;
+ while (value > INT_MAX) {
+ sync_timeline_signal(obj, INT_MAX);
+ value -= INT_MAX;
+ }
+
sync_timeline_signal(obj, value);
return 0;
diff --git a/drivers/dma-buf/sync_debug.c b/drivers/dma-buf/sync_debug.c
index 59a3b2f8..c4c8ecb 100644
--- a/drivers/dma-buf/sync_debug.c
+++ b/drivers/dma-buf/sync_debug.c
@@ -116,17 +116,15 @@ static void sync_print_fence(struct seq_file *s,
static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj)
{
struct list_head *pos;
- unsigned long flags;
seq_printf(s, "%s: %d\n", obj->name, obj->value);
- spin_lock_irqsave(&obj->child_list_lock, flags);
- list_for_each(pos, &obj->child_list_head) {
- struct sync_pt *pt =
- container_of(pos, struct sync_pt, child_list);
+ spin_lock_irq(&obj->lock);
+ list_for_each(pos, &obj->pt_list) {
+ struct sync_pt *pt = container_of(pos, struct sync_pt, link);
sync_print_fence(s, &pt->base, false);
}
- spin_unlock_irqrestore(&obj->child_list_lock, flags);
+ spin_unlock_irq(&obj->lock);
}
static void sync_print_sync_file(struct seq_file *s,
@@ -151,12 +149,11 @@ static void sync_print_sync_file(struct seq_file *s,
static int sync_debugfs_show(struct seq_file *s, void *unused)
{
- unsigned long flags;
struct list_head *pos;
seq_puts(s, "objs:\n--------------\n");
- spin_lock_irqsave(&sync_timeline_list_lock, flags);
+ spin_lock_irq(&sync_timeline_list_lock);
list_for_each(pos, &sync_timeline_list_head) {
struct sync_timeline *obj =
container_of(pos, struct sync_timeline,
@@ -165,11 +162,11 @@ static int sync_debugfs_show(struct seq_file *s, void *unused)
sync_print_obj(s, obj);
seq_putc(s, '\n');
}
- spin_unlock_irqrestore(&sync_timeline_list_lock, flags);
+ spin_unlock_irq(&sync_timeline_list_lock);
seq_puts(s, "fences:\n--------------\n");
- spin_lock_irqsave(&sync_file_list_lock, flags);
+ spin_lock_irq(&sync_file_list_lock);
list_for_each(pos, &sync_file_list_head) {
struct sync_file *sync_file =
container_of(pos, struct sync_file, sync_file_list);
@@ -177,7 +174,7 @@ static int sync_debugfs_show(struct seq_file *s, void *unused)
sync_print_sync_file(s, sync_file);
seq_putc(s, '\n');
}
- spin_unlock_irqrestore(&sync_file_list_lock, flags);
+ spin_unlock_irq(&sync_file_list_lock);
return 0;
}
diff --git a/drivers/dma-buf/sync_debug.h b/drivers/dma-buf/sync_debug.h
index 26fe8b9..d615a89 100644
--- a/drivers/dma-buf/sync_debug.h
+++ b/drivers/dma-buf/sync_debug.h
@@ -14,6 +14,7 @@
#define _LINUX_SYNC_H
#include <linux/list.h>
+#include <linux/rbtree.h>
#include <linux/spinlock.h>
#include <linux/dma-fence.h>
@@ -24,42 +25,41 @@
* struct sync_timeline - sync object
* @kref: reference count on fence.
* @name: name of the sync_timeline. Useful for debugging
- * @child_list_head: list of children sync_pts for this sync_timeline
- * @child_list_lock: lock protecting @child_list_head and fence.status
- * @active_list_head: list of active (unsignaled/errored) sync_pts
+ * @lock: lock protecting @pt_list and @value
+ * @pt_tree: rbtree of active (unsignaled/errored) sync_pts
+ * @pt_list: list of active (unsignaled/errored) sync_pts
* @sync_timeline_list: membership in global sync_timeline_list
*/
struct sync_timeline {
struct kref kref;
char name[32];
- /* protected by child_list_lock */
+ /* protected by lock */
u64 context;
int value;
- struct list_head child_list_head;
- spinlock_t child_list_lock;
-
- struct list_head active_list_head;
+ struct rb_root pt_tree;
+ struct list_head pt_list;
+ spinlock_t lock;
struct list_head sync_timeline_list;
};
static inline struct sync_timeline *dma_fence_parent(struct dma_fence *fence)
{
- return container_of(fence->lock, struct sync_timeline, child_list_lock);
+ return container_of(fence->lock, struct sync_timeline, lock);
}
/**
* struct sync_pt - sync_pt object
* @base: base fence object
- * @child_list: sync timeline child's list
- * @active_list: sync timeline active child's list
+ * @link: link on the sync timeline's list
+ * @node: node in the sync timeline's tree
*/
struct sync_pt {
struct dma_fence base;
- struct list_head child_list;
- struct list_head active_list;
+ struct list_head link;
+ struct rb_node node;
};
#ifdef CONFIG_SW_SYNC
diff --git a/drivers/firmware/dmi-sysfs.c b/drivers/firmware/dmi-sysfs.c
index ef76e5e..d5de6ee 100644
--- a/drivers/firmware/dmi-sysfs.c
+++ b/drivers/firmware/dmi-sysfs.c
@@ -25,6 +25,7 @@
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/io.h>
+#include <asm/dmi.h>
#define MAX_ENTRY_TYPE 255 /* Most of these aren't used, but we consider
the top entry type is only 8 bits */
@@ -380,7 +381,7 @@ static ssize_t dmi_sel_raw_read_phys32(struct dmi_sysfs_entry *entry,
u8 __iomem *mapped;
ssize_t wrote = 0;
- mapped = ioremap(sel->access_method_address, sel->area_length);
+ mapped = dmi_remap(sel->access_method_address, sel->area_length);
if (!mapped)
return -EIO;
@@ -390,7 +391,7 @@ static ssize_t dmi_sel_raw_read_phys32(struct dmi_sysfs_entry *entry,
wrote++;
}
- iounmap(mapped);
+ dmi_unmap(mapped);
return wrote;
}
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 045d6d3..69d4d13 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -55,6 +55,25 @@ struct efi __read_mostly efi = {
};
EXPORT_SYMBOL(efi);
+static unsigned long *efi_tables[] = {
+ &efi.mps,
+ &efi.acpi,
+ &efi.acpi20,
+ &efi.smbios,
+ &efi.smbios3,
+ &efi.sal_systab,
+ &efi.boot_info,
+ &efi.hcdp,
+ &efi.uga,
+ &efi.uv_systab,
+ &efi.fw_vendor,
+ &efi.runtime,
+ &efi.config_table,
+ &efi.esrt,
+ &efi.properties_table,
+ &efi.mem_attr_table,
+};
+
static bool disable_runtime;
static int __init setup_noefi(char *arg)
{
@@ -855,6 +874,20 @@ int efi_status_to_err(efi_status_t status)
return err;
}
+bool efi_is_table_address(unsigned long phys_addr)
+{
+ unsigned int i;
+
+ if (phys_addr == EFI_INVALID_TABLE_ADDR)
+ return false;
+
+ for (i = 0; i < ARRAY_SIZE(efi_tables); i++)
+ if (*(efi_tables[i]) == phys_addr)
+ return true;
+
+ return false;
+}
+
#ifdef CONFIG_KEXEC
static int update_efi_random_seed(struct notifier_block *nb,
unsigned long code, void *unused)
diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c
index b4c2589..af6ae95 100644
--- a/drivers/firmware/efi/libstub/arm64-stub.c
+++ b/drivers/firmware/efi/libstub/arm64-stub.c
@@ -11,6 +11,7 @@
*/
#include <linux/efi.h>
#include <asm/efi.h>
+#include <asm/memory.h>
#include <asm/sections.h>
#include <asm/sysreg.h>
@@ -81,9 +82,10 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table_arg,
/*
* If CONFIG_DEBUG_ALIGN_RODATA is not set, produce a
* displacement in the interval [0, MIN_KIMG_ALIGN) that
- * is a multiple of the minimal segment alignment (SZ_64K)
+ * doesn't violate this kernel's de-facto alignment
+ * constraints.
*/
- u32 mask = (MIN_KIMG_ALIGN - 1) & ~(SZ_64K - 1);
+ u32 mask = (MIN_KIMG_ALIGN - 1) & ~(EFI_KIMG_ALIGN - 1);
u32 offset = !IS_ENABLED(CONFIG_DEBUG_ALIGN_RODATA) ?
(phys_seed >> 32) & mask : TEXT_OFFSET;
diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
index b018436..50a9cab 100644
--- a/drivers/firmware/efi/libstub/efi-stub-helper.c
+++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
@@ -205,7 +205,7 @@ again:
unsigned long m = (unsigned long)map;
u64 start, end;
- desc = (efi_memory_desc_t *)(m + (i * desc_size));
+ desc = efi_early_memdesc_ptr(m, desc_size, i);
if (desc->type != EFI_CONVENTIONAL_MEMORY)
continue;
@@ -298,7 +298,7 @@ efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg,
unsigned long m = (unsigned long)map;
u64 start, end;
- desc = (efi_memory_desc_t *)(m + (i * desc_size));
+ desc = efi_early_memdesc_ptr(m, desc_size, i);
if (desc->type != EFI_CONVENTIONAL_MEMORY)
continue;
diff --git a/drivers/firmware/pcdp.c b/drivers/firmware/pcdp.c
index 75273a25..e83d6ae 100644
--- a/drivers/firmware/pcdp.c
+++ b/drivers/firmware/pcdp.c
@@ -95,7 +95,7 @@ efi_setup_pcdp_console(char *cmdline)
if (efi.hcdp == EFI_INVALID_TABLE_ADDR)
return -ENODEV;
- pcdp = early_ioremap(efi.hcdp, 4096);
+ pcdp = early_memremap(efi.hcdp, 4096);
printk(KERN_INFO "PCDP: v%d at 0x%lx\n", pcdp->rev, efi.hcdp);
if (strstr(cmdline, "console=hcdp")) {
@@ -131,6 +131,6 @@ efi_setup_pcdp_console(char *cmdline)
}
out:
- early_iounmap(pcdp, 4096);
+ early_memunmap(pcdp, 4096);
return rc;
}
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 24a066e..a8acc19 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -33,7 +33,7 @@ drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
drm_kms_helper_common.o drm_dp_dual_mode_helper.o \
drm_simple_kms_helper.o drm_modeset_helper.o \
- drm_scdc_helper.o
+ drm_scdc_helper.o drm_gem_framebuffer_helper.o
drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o
drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
index faea634..658bac0 100644
--- a/drivers/gpu/drm/amd/amdgpu/Makefile
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -25,7 +25,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \
amdgpu_prime.o amdgpu_vm.o amdgpu_ib.o amdgpu_pll.o \
amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o \
amdgpu_gtt_mgr.o amdgpu_vram_mgr.o amdgpu_virt.o amdgpu_atomfirmware.o \
- amdgpu_queue_mgr.o
+ amdgpu_queue_mgr.o amdgpu_vf_error.o
# add asic specific block
amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index ff7bf1a..12e71bb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -68,13 +68,16 @@
#include "gpu_scheduler.h"
#include "amdgpu_virt.h"
+#include "amdgpu_gart.h"
/*
* Modules parameters.
*/
extern int amdgpu_modeset;
extern int amdgpu_vram_limit;
-extern int amdgpu_gart_size;
+extern int amdgpu_vis_vram_limit;
+extern unsigned amdgpu_gart_size;
+extern int amdgpu_gtt_size;
extern int amdgpu_moverate;
extern int amdgpu_benchmarking;
extern int amdgpu_testing;
@@ -93,6 +96,7 @@ extern int amdgpu_bapm;
extern int amdgpu_deep_color;
extern int amdgpu_vm_size;
extern int amdgpu_vm_block_size;
+extern int amdgpu_vm_fragment_size;
extern int amdgpu_vm_fault_stop;
extern int amdgpu_vm_debug;
extern int amdgpu_vm_update_mode;
@@ -104,6 +108,7 @@ extern unsigned amdgpu_pcie_gen_cap;
extern unsigned amdgpu_pcie_lane_cap;
extern unsigned amdgpu_cg_mask;
extern unsigned amdgpu_pg_mask;
+extern unsigned amdgpu_sdma_phase_quantum;
extern char *amdgpu_disable_cu;
extern char *amdgpu_virtual_display;
extern unsigned amdgpu_pp_feature_mask;
@@ -369,78 +374,10 @@ struct amdgpu_clock {
};
/*
- * BO.
+ * GEM.
*/
-struct amdgpu_bo_list_entry {
- struct amdgpu_bo *robj;
- struct ttm_validate_buffer tv;
- struct amdgpu_bo_va *bo_va;
- uint32_t priority;
- struct page **user_pages;
- int user_invalidated;
-};
-
-struct amdgpu_bo_va_mapping {
- struct list_head list;
- struct rb_node rb;
- uint64_t start;
- uint64_t last;
- uint64_t __subtree_last;
- uint64_t offset;
- uint64_t flags;
-};
-
-/* bo virtual addresses in a specific vm */
-struct amdgpu_bo_va {
- /* protected by bo being reserved */
- struct list_head bo_list;
- struct dma_fence *last_pt_update;
- unsigned ref_count;
-
- /* protected by vm mutex and spinlock */
- struct list_head vm_status;
-
- /* mappings for this bo_va */
- struct list_head invalids;
- struct list_head valids;
-
- /* constant after initialization */
- struct amdgpu_vm *vm;
- struct amdgpu_bo *bo;
-};
#define AMDGPU_GEM_DOMAIN_MAX 0x3
-
-struct amdgpu_bo {
- /* Protected by tbo.reserved */
- u32 prefered_domains;
- u32 allowed_domains;
- struct ttm_place placements[AMDGPU_GEM_DOMAIN_MAX + 1];
- struct ttm_placement placement;
- struct ttm_buffer_object tbo;
- struct ttm_bo_kmap_obj kmap;
- u64 flags;
- unsigned pin_count;
- void *kptr;
- u64 tiling_flags;
- u64 metadata_flags;
- void *metadata;
- u32 metadata_size;
- unsigned prime_shared_count;
- /* list of all virtual address to which this bo
- * is associated to
- */
- struct list_head va;
- /* Constant after initialization */
- struct drm_gem_object gem_base;
- struct amdgpu_bo *parent;
- struct amdgpu_bo *shadow;
-
- struct ttm_bo_kmap_obj dma_buf_vmap;
- struct amdgpu_mn *mn;
- struct list_head mn_list;
- struct list_head shadow_list;
-};
#define gem_to_amdgpu_bo(gobj) container_of((gobj), struct amdgpu_bo, gem_base)
void amdgpu_gem_object_free(struct drm_gem_object *obj);
@@ -532,49 +469,6 @@ int amdgpu_fence_slab_init(void);
void amdgpu_fence_slab_fini(void);
/*
- * GART structures, functions & helpers
- */
-struct amdgpu_mc;
-
-#define AMDGPU_GPU_PAGE_SIZE 4096
-#define AMDGPU_GPU_PAGE_MASK (AMDGPU_GPU_PAGE_SIZE - 1)
-#define AMDGPU_GPU_PAGE_SHIFT 12
-#define AMDGPU_GPU_PAGE_ALIGN(a) (((a) + AMDGPU_GPU_PAGE_MASK) & ~AMDGPU_GPU_PAGE_MASK)
-
-struct amdgpu_gart {
- dma_addr_t table_addr;
- struct amdgpu_bo *robj;
- void *ptr;
- unsigned num_gpu_pages;
- unsigned num_cpu_pages;
- unsigned table_size;
-#ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
- struct page **pages;
-#endif
- bool ready;
-
- /* Asic default pte flags */
- uint64_t gart_pte_flags;
-
- const struct amdgpu_gart_funcs *gart_funcs;
-};
-
-int amdgpu_gart_table_ram_alloc(struct amdgpu_device *adev);
-void amdgpu_gart_table_ram_free(struct amdgpu_device *adev);
-int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev);
-void amdgpu_gart_table_vram_free(struct amdgpu_device *adev);
-int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev);
-void amdgpu_gart_table_vram_unpin(struct amdgpu_device *adev);
-int amdgpu_gart_init(struct amdgpu_device *adev);
-void amdgpu_gart_fini(struct amdgpu_device *adev);
-int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
- int pages);
-int amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset,
- int pages, struct page **pagelist,
- dma_addr_t *dma_addr, uint64_t flags);
-int amdgpu_ttm_recover_gart(struct amdgpu_device *adev);
-
-/*
* VMHUB structures, functions & helpers
*/
struct amdgpu_vmhub {
@@ -598,22 +492,20 @@ struct amdgpu_mc {
* about vram size near mc fb location */
u64 mc_vram_size;
u64 visible_vram_size;
- u64 gtt_size;
- u64 gtt_start;
- u64 gtt_end;
+ u64 gart_size;
+ u64 gart_start;
+ u64 gart_end;
u64 vram_start;
u64 vram_end;
unsigned vram_width;
u64 real_vram_size;
int vram_mtrr;
- u64 gtt_base_align;
u64 mc_mask;
const struct firmware *fw; /* MC firmware */
uint32_t fw_version;
struct amdgpu_irq_src vm_fault;
uint32_t vram_type;
uint32_t srbm_soft_reset;
- struct amdgpu_mode_mc_save save;
bool prt_warning;
uint64_t stolen_size;
/* apertures */
@@ -719,15 +611,15 @@ typedef enum _AMDGPU_DOORBELL64_ASSIGNMENT
/* overlap the doorbell assignment with VCN as they are mutually exclusive
* VCE engine's doorbell is 32 bit and two VCE ring share one QWORD
*/
- AMDGPU_DOORBELL64_RING0_1 = 0xF8,
- AMDGPU_DOORBELL64_RING2_3 = 0xF9,
- AMDGPU_DOORBELL64_RING4_5 = 0xFA,
- AMDGPU_DOORBELL64_RING6_7 = 0xFB,
+ AMDGPU_DOORBELL64_UVD_RING0_1 = 0xF8,
+ AMDGPU_DOORBELL64_UVD_RING2_3 = 0xF9,
+ AMDGPU_DOORBELL64_UVD_RING4_5 = 0xFA,
+ AMDGPU_DOORBELL64_UVD_RING6_7 = 0xFB,
- AMDGPU_DOORBELL64_UVD_RING0_1 = 0xFC,
- AMDGPU_DOORBELL64_UVD_RING2_3 = 0xFD,
- AMDGPU_DOORBELL64_UVD_RING4_5 = 0xFE,
- AMDGPU_DOORBELL64_UVD_RING6_7 = 0xFF,
+ AMDGPU_DOORBELL64_VCE_RING0_1 = 0xFC,
+ AMDGPU_DOORBELL64_VCE_RING2_3 = 0xFD,
+ AMDGPU_DOORBELL64_VCE_RING4_5 = 0xFE,
+ AMDGPU_DOORBELL64_VCE_RING6_7 = 0xFF,
AMDGPU_DOORBELL64_MAX_ASSIGNMENT = 0xFF,
AMDGPU_DOORBELL64_INVALID = 0xFFFF
@@ -857,6 +749,7 @@ void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr);
struct amdgpu_fpriv {
struct amdgpu_vm vm;
struct amdgpu_bo_va *prt_va;
+ struct amdgpu_bo_va *csa_va;
struct mutex bo_list_lock;
struct idr bo_list_handles;
struct amdgpu_ctx_mgr ctx_mgr;
@@ -866,6 +759,14 @@ struct amdgpu_fpriv {
/*
* residency list
*/
+struct amdgpu_bo_list_entry {
+ struct amdgpu_bo *robj;
+ struct ttm_validate_buffer tv;
+ struct amdgpu_bo_va *bo_va;
+ uint32_t priority;
+ struct page **user_pages;
+ int user_invalidated;
+};
struct amdgpu_bo_list {
struct mutex lock;
@@ -1159,7 +1060,9 @@ struct amdgpu_cs_parser {
struct list_head validated;
struct dma_fence *fence;
uint64_t bytes_moved_threshold;
+ uint64_t bytes_moved_vis_threshold;
uint64_t bytes_moved;
+ uint64_t bytes_moved_vis;
struct amdgpu_bo_list_entry *evictable;
/* user fence */
@@ -1230,8 +1133,6 @@ struct amdgpu_wb {
int amdgpu_wb_get(struct amdgpu_device *adev, u32 *wb);
void amdgpu_wb_free(struct amdgpu_device *adev, u32 wb);
-int amdgpu_wb_get_64bit(struct amdgpu_device *adev, u32 *wb);
-void amdgpu_wb_free_64bit(struct amdgpu_device *adev, u32 wb);
void amdgpu_get_pcie_info(struct amdgpu_device *adev);
@@ -1525,7 +1426,7 @@ struct amdgpu_device {
bool is_atom_fw;
uint8_t *bios;
uint32_t bios_size;
- struct amdgpu_bo *stollen_vga_memory;
+ struct amdgpu_bo *stolen_vga_memory;
uint32_t bios_scratch_reg_offset;
uint32_t bios_scratch[AMDGPU_BIOS_NUM_SCRATCH];
@@ -1557,6 +1458,10 @@ struct amdgpu_device {
spinlock_t gc_cac_idx_lock;
amdgpu_rreg_t gc_cac_rreg;
amdgpu_wreg_t gc_cac_wreg;
+ /* protects concurrent se_cac register access */
+ spinlock_t se_cac_idx_lock;
+ amdgpu_rreg_t se_cac_rreg;
+ amdgpu_wreg_t se_cac_wreg;
/* protects concurrent ENDPOINT (audio) register access */
spinlock_t audio_endpt_idx_lock;
amdgpu_block_rreg_t audio_endpt_rreg;
@@ -1579,9 +1484,6 @@ struct amdgpu_device {
struct amdgpu_mman mman;
struct amdgpu_vram_scratch vram_scratch;
struct amdgpu_wb wb;
- atomic64_t vram_usage;
- atomic64_t vram_vis_usage;
- atomic64_t gtt_usage;
atomic64_t num_bytes_moved;
atomic64_t num_evictions;
atomic64_t num_vram_cpu_page_faults;
@@ -1593,6 +1495,7 @@ struct amdgpu_device {
spinlock_t lock;
s64 last_update_us;
s64 accum_us; /* accumulated microseconds */
+ s64 accum_us_vis; /* for visible VRAM */
u32 log2_max_MBps;
} mm_stats;
@@ -1687,6 +1590,8 @@ struct amdgpu_device {
bool has_hw_reset;
u8 reset_magic[AMDGPU_RESET_MAGIC_NUM];
+ /* record last mm index being written through WREG32*/
+ unsigned long last_mm_index;
};
static inline struct amdgpu_device *amdgpu_ttm_adev(struct ttm_bo_device *bdev)
@@ -1742,6 +1647,8 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v);
#define WREG32_DIDT(reg, v) adev->didt_wreg(adev, (reg), (v))
#define RREG32_GC_CAC(reg) adev->gc_cac_rreg(adev, (reg))
#define WREG32_GC_CAC(reg, v) adev->gc_cac_wreg(adev, (reg), (v))
+#define RREG32_SE_CAC(reg) adev->se_cac_rreg(adev, (reg))
+#define WREG32_SE_CAC(reg, v) adev->se_cac_wreg(adev, (reg), (v))
#define RREG32_AUDIO_ENDPT(block, reg) adev->audio_endpt_rreg(adev, (block), (reg))
#define WREG32_AUDIO_ENDPT(block, reg, v) adev->audio_endpt_wreg(adev, (block), (reg), (v))
#define WREG32_P(reg, val, mask) \
@@ -1792,50 +1699,6 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v);
#define RBIOS16(i) (RBIOS8(i) | (RBIOS8((i)+1) << 8))
#define RBIOS32(i) ((RBIOS16(i)) | (RBIOS16((i)+2) << 16))
-/*
- * RING helpers.
- */
-static inline void amdgpu_ring_write(struct amdgpu_ring *ring, uint32_t v)
-{
- if (ring->count_dw <= 0)
- DRM_ERROR("amdgpu: writing more dwords to the ring than expected!\n");
- ring->ring[ring->wptr++ & ring->buf_mask] = v;
- ring->wptr &= ring->ptr_mask;
- ring->count_dw--;
-}
-
-static inline void amdgpu_ring_write_multiple(struct amdgpu_ring *ring, void *src, int count_dw)
-{
- unsigned occupied, chunk1, chunk2;
- void *dst;
-
- if (unlikely(ring->count_dw < count_dw)) {
- DRM_ERROR("amdgpu: writing more dwords to the ring than expected!\n");
- return;
- }
-
- occupied = ring->wptr & ring->buf_mask;
- dst = (void *)&ring->ring[occupied];
- chunk1 = ring->buf_mask + 1 - occupied;
- chunk1 = (chunk1 >= count_dw) ? count_dw: chunk1;
- chunk2 = count_dw - chunk1;
- chunk1 <<= 2;
- chunk2 <<= 2;
-
- if (chunk1)
- memcpy(dst, src, chunk1);
-
- if (chunk2) {
- src += chunk1;
- dst = (void *)ring->ring;
- memcpy(dst, src, chunk2);
- }
-
- ring->wptr += count_dw;
- ring->wptr &= ring->ptr_mask;
- ring->count_dw -= count_dw;
-}
-
static inline struct amdgpu_sdma_instance *
amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
{
@@ -1898,7 +1761,6 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
#define amdgpu_ih_get_wptr(adev) (adev)->irq.ih_funcs->get_wptr((adev))
#define amdgpu_ih_decode_iv(adev, iv) (adev)->irq.ih_funcs->decode_iv((adev), (iv))
#define amdgpu_ih_set_rptr(adev) (adev)->irq.ih_funcs->set_rptr((adev))
-#define amdgpu_display_set_vga_render_state(adev, r) (adev)->mode_info.funcs->set_vga_render_state((adev), (r))
#define amdgpu_display_vblank_get_counter(adev, crtc) (adev)->mode_info.funcs->vblank_get_counter((adev), (crtc))
#define amdgpu_display_vblank_wait(adev, crtc) (adev)->mode_info.funcs->vblank_wait((adev), (crtc))
#define amdgpu_display_backlight_set_level(adev, e, l) (adev)->mode_info.funcs->backlight_set_level((e), (l))
@@ -1911,8 +1773,6 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
#define amdgpu_display_page_flip_get_scanoutpos(adev, crtc, vbl, pos) (adev)->mode_info.funcs->page_flip_get_scanoutpos((adev), (crtc), (vbl), (pos))
#define amdgpu_display_add_encoder(adev, e, s, c) (adev)->mode_info.funcs->add_encoder((adev), (e), (s), (c))
#define amdgpu_display_add_connector(adev, ci, sd, ct, ib, coi, h, r) (adev)->mode_info.funcs->add_connector((adev), (ci), (sd), (ct), (ib), (coi), (h), (r))
-#define amdgpu_display_stop_mc_access(adev, s) (adev)->mode_info.funcs->stop_mc_access((adev), (s))
-#define amdgpu_display_resume_mc_access(adev, s) (adev)->mode_info.funcs->resume_mc_access((adev), (s))
#define amdgpu_emit_copy_buffer(adev, ib, s, d, b) (adev)->mman.buffer_funcs->emit_copy_buffer((ib), (s), (d), (b))
#define amdgpu_emit_fill_buffer(adev, ib, s, d, b) (adev)->mman.buffer_funcs->emit_fill_buffer((ib), (s), (d), (b))
#define amdgpu_gfx_get_gpu_clock_counter(adev) (adev)->gfx.funcs->get_gpu_clock_counter((adev))
@@ -1927,7 +1787,8 @@ void amdgpu_pci_config_reset(struct amdgpu_device *adev);
bool amdgpu_need_post(struct amdgpu_device *adev);
void amdgpu_update_display_priority(struct amdgpu_device *adev);
-void amdgpu_cs_report_moved_bytes(struct amdgpu_device *adev, u64 num_bytes);
+void amdgpu_cs_report_moved_bytes(struct amdgpu_device *adev, u64 num_bytes,
+ u64 num_vis_bytes);
void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *abo, u32 domain);
bool amdgpu_ttm_bo_is_amdgpu_bo(struct ttm_buffer_object *bo);
int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages);
@@ -1943,7 +1804,7 @@ bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm);
uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm,
struct ttm_mem_reg *mem);
void amdgpu_vram_location(struct amdgpu_device *adev, struct amdgpu_mc *mc, u64 base);
-void amdgpu_gtt_location(struct amdgpu_device *adev, struct amdgpu_mc *mc);
+void amdgpu_gart_location(struct amdgpu_device *adev, struct amdgpu_mc *mc);
void amdgpu_ttm_set_active_vram_size(struct amdgpu_device *adev, u64 size);
int amdgpu_ttm_init(struct amdgpu_device *adev);
void amdgpu_ttm_fini(struct amdgpu_device *adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
index 06879d1..a52795d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
@@ -285,19 +285,20 @@ static int acp_hw_init(void *handle)
return 0;
else if (r)
return r;
+ if (adev->asic_type != CHIP_STONEY) {
+ adev->acp.acp_genpd = kzalloc(sizeof(struct acp_pm_domain), GFP_KERNEL);
+ if (adev->acp.acp_genpd == NULL)
+ return -ENOMEM;
- adev->acp.acp_genpd = kzalloc(sizeof(struct acp_pm_domain), GFP_KERNEL);
- if (adev->acp.acp_genpd == NULL)
- return -ENOMEM;
-
- adev->acp.acp_genpd->gpd.name = "ACP_AUDIO";
- adev->acp.acp_genpd->gpd.power_off = acp_poweroff;
- adev->acp.acp_genpd->gpd.power_on = acp_poweron;
+ adev->acp.acp_genpd->gpd.name = "ACP_AUDIO";
+ adev->acp.acp_genpd->gpd.power_off = acp_poweroff;
+ adev->acp.acp_genpd->gpd.power_on = acp_poweron;
- adev->acp.acp_genpd->cgs_dev = adev->acp.cgs_device;
+ adev->acp.acp_genpd->cgs_dev = adev->acp.cgs_device;
- pm_genpd_init(&adev->acp.acp_genpd->gpd, NULL, false);
+ pm_genpd_init(&adev->acp.acp_genpd->gpd, NULL, false);
+ }
adev->acp.acp_cell = kzalloc(sizeof(struct mfd_cell) * ACP_DEVS,
GFP_KERNEL);
@@ -319,14 +320,29 @@ static int acp_hw_init(void *handle)
return -ENOMEM;
}
- i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET;
+ switch (adev->asic_type) {
+ case CHIP_STONEY:
+ i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
+ DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
+ break;
+ default:
+ i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET;
+ }
i2s_pdata[0].cap = DWC_I2S_PLAY;
i2s_pdata[0].snd_rates = SNDRV_PCM_RATE_8000_96000;
i2s_pdata[0].i2s_reg_comp1 = ACP_I2S_COMP1_PLAY_REG_OFFSET;
i2s_pdata[0].i2s_reg_comp2 = ACP_I2S_COMP2_PLAY_REG_OFFSET;
+ switch (adev->asic_type) {
+ case CHIP_STONEY:
+ i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
+ DW_I2S_QUIRK_COMP_PARAM1 |
+ DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
+ break;
+ default:
+ i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
+ DW_I2S_QUIRK_COMP_PARAM1;
+ }
- i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
- DW_I2S_QUIRK_COMP_PARAM1;
i2s_pdata[1].cap = DWC_I2S_RECORD;
i2s_pdata[1].snd_rates = SNDRV_PCM_RATE_8000_96000;
i2s_pdata[1].i2s_reg_comp1 = ACP_I2S_COMP1_CAP_REG_OFFSET;
@@ -373,12 +389,14 @@ static int acp_hw_init(void *handle)
if (r)
return r;
- for (i = 0; i < ACP_DEVS ; i++) {
- dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i);
- r = pm_genpd_add_device(&adev->acp.acp_genpd->gpd, dev);
- if (r) {
- dev_err(dev, "Failed to add dev to genpd\n");
- return r;
+ if (adev->asic_type != CHIP_STONEY) {
+ for (i = 0; i < ACP_DEVS ; i++) {
+ dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i);
+ r = pm_genpd_add_device(&adev->acp.acp_genpd->gpd, dev);
+ if (r) {
+ dev_err(dev, "Failed to add dev to genpd\n");
+ return r;
+ }
}
}
@@ -398,20 +416,22 @@ static int acp_hw_fini(void *handle)
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
/* return early if no ACP */
- if (!adev->acp.acp_genpd)
+ if (!adev->acp.acp_cell)
return 0;
- for (i = 0; i < ACP_DEVS ; i++) {
- dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i);
- ret = pm_genpd_remove_device(&adev->acp.acp_genpd->gpd, dev);
- /* If removal fails, dont giveup and try rest */
- if (ret)
- dev_err(dev, "remove dev from genpd failed\n");
+ if (adev->acp.acp_genpd) {
+ for (i = 0; i < ACP_DEVS ; i++) {
+ dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i);
+ ret = pm_genpd_remove_device(&adev->acp.acp_genpd->gpd, dev);
+ /* If removal fails, dont giveup and try rest */
+ if (ret)
+ dev_err(dev, "remove dev from genpd failed\n");
+ }
+ kfree(adev->acp.acp_genpd);
}
mfd_remove_devices(adev->acp.parent);
kfree(adev->acp.acp_res);
- kfree(adev->acp.acp_genpd);
kfree(adev->acp.acp_cell);
return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
index ef79551..57afad7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
@@ -30,10 +30,10 @@
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
#include "amdgpu.h"
+#include "amdgpu_pm.h"
#include "amd_acpi.h"
#include "atom.h"
-extern void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev);
/* Call the ATIF method
*/
/**
@@ -289,7 +289,7 @@ out:
* handles it.
* Returns NOTIFY code
*/
-int amdgpu_atif_handler(struct amdgpu_device *adev,
+static int amdgpu_atif_handler(struct amdgpu_device *adev,
struct acpi_bus_event *event)
{
struct amdgpu_atif *atif = &adev->atif;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
index 37971d9..5432af3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
@@ -27,16 +27,15 @@
#include "amdgpu_gfx.h"
#include <linux/module.h>
-const struct kfd2kgd_calls *kfd2kgd;
const struct kgd2kfd_calls *kgd2kfd;
-bool (*kgd2kfd_init_p)(unsigned, const struct kgd2kfd_calls**);
+bool (*kgd2kfd_init_p)(unsigned int, const struct kgd2kfd_calls**);
int amdgpu_amdkfd_init(void)
{
int ret;
#if defined(CONFIG_HSA_AMD_MODULE)
- int (*kgd2kfd_init_p)(unsigned, const struct kgd2kfd_calls**);
+ int (*kgd2kfd_init_p)(unsigned int, const struct kgd2kfd_calls**);
kgd2kfd_init_p = symbol_request(kgd2kfd_init);
@@ -61,8 +60,21 @@ int amdgpu_amdkfd_init(void)
return ret;
}
-bool amdgpu_amdkfd_load_interface(struct amdgpu_device *adev)
+void amdgpu_amdkfd_fini(void)
+{
+ if (kgd2kfd) {
+ kgd2kfd->exit();
+ symbol_put(kgd2kfd_init);
+ }
+}
+
+void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev)
{
+ const struct kfd2kgd_calls *kfd2kgd;
+
+ if (!kgd2kfd)
+ return;
+
switch (adev->asic_type) {
#ifdef CONFIG_DRM_AMDGPU_CIK
case CHIP_KAVERI:
@@ -73,25 +85,12 @@ bool amdgpu_amdkfd_load_interface(struct amdgpu_device *adev)
kfd2kgd = amdgpu_amdkfd_gfx_8_0_get_functions();
break;
default:
- return false;
+ dev_info(adev->dev, "kfd not supported on this ASIC\n");
+ return;
}
- return true;
-}
-
-void amdgpu_amdkfd_fini(void)
-{
- if (kgd2kfd) {
- kgd2kfd->exit();
- symbol_put(kgd2kfd_init);
- }
-}
-
-void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev)
-{
- if (kgd2kfd)
- adev->kfd = kgd2kfd->probe((struct kgd_dev *)adev,
- adev->pdev, kfd2kgd);
+ adev->kfd = kgd2kfd->probe((struct kgd_dev *)adev,
+ adev->pdev, kfd2kgd);
}
void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
@@ -184,7 +183,8 @@ int alloc_gtt_mem(struct kgd_dev *kgd, size_t size,
return -ENOMEM;
r = amdgpu_bo_create(adev, size, PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_GTT,
- AMDGPU_GEM_CREATE_CPU_GTT_USWC, NULL, NULL, &(*mem)->bo);
+ AMDGPU_GEM_CREATE_CPU_GTT_USWC, NULL, NULL, 0,
+ &(*mem)->bo);
if (r) {
dev_err(adev->dev,
"failed to allocate BO for amdkfd (%d)\n", r);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
index 73f83a1..8d689ab 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
@@ -26,6 +26,7 @@
#define AMDGPU_AMDKFD_H_INCLUDED
#include <linux/types.h>
+#include <linux/mmu_context.h>
#include <kgd_kfd_interface.h>
struct amdgpu_device;
@@ -39,8 +40,6 @@ struct kgd_mem {
int amdgpu_amdkfd_init(void);
void amdgpu_amdkfd_fini(void);
-bool amdgpu_amdkfd_load_interface(struct amdgpu_device *adev);
-
void amdgpu_amdkfd_suspend(struct amdgpu_device *adev);
int amdgpu_amdkfd_resume(struct amdgpu_device *adev);
void amdgpu_amdkfd_interrupt(struct amdgpu_device *adev,
@@ -62,4 +61,19 @@ uint64_t get_gpu_clock_counter(struct kgd_dev *kgd);
uint32_t get_max_engine_clock_in_mhz(struct kgd_dev *kgd);
+#define read_user_wptr(mmptr, wptr, dst) \
+ ({ \
+ bool valid = false; \
+ if ((mmptr) && (wptr)) { \
+ if ((mmptr) == current->mm) { \
+ valid = !get_user((dst), (wptr)); \
+ } else if (current->mm == NULL) { \
+ use_mm(mmptr); \
+ valid = !get_user((dst), (wptr)); \
+ unuse_mm(mmptr); \
+ } \
+ } \
+ valid; \
+ })
+
#endif /* AMDGPU_AMDKFD_H_INCLUDED */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
index 5254562..b9dbbf9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
@@ -39,6 +39,12 @@
#include "gmc/gmc_7_1_sh_mask.h"
#include "cik_structs.h"
+enum hqd_dequeue_request_type {
+ NO_ACTION = 0,
+ DRAIN_PIPE,
+ RESET_WAVES
+};
+
enum {
MAX_TRAPID = 8, /* 3 bits in the bitfield. */
MAX_WATCH_ADDRESSES = 4
@@ -96,12 +102,15 @@ static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id,
uint32_t hpd_size, uint64_t hpd_gpu_addr);
static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id);
static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
- uint32_t queue_id, uint32_t __user *wptr);
+ uint32_t queue_id, uint32_t __user *wptr,
+ uint32_t wptr_shift, uint32_t wptr_mask,
+ struct mm_struct *mm);
static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd);
static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
uint32_t pipe_id, uint32_t queue_id);
-static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
+static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd,
+ enum kfd_preempt_type reset_type,
unsigned int utimeout, uint32_t pipe_id,
uint32_t queue_id);
static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd);
@@ -126,6 +135,33 @@ static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd,
static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid);
static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type);
+static void set_scratch_backing_va(struct kgd_dev *kgd,
+ uint64_t va, uint32_t vmid);
+
+/* Because of REG_GET_FIELD() being used, we put this function in the
+ * asic specific file.
+ */
+static int get_tile_config(struct kgd_dev *kgd,
+ struct tile_config *config)
+{
+ struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
+
+ config->gb_addr_config = adev->gfx.config.gb_addr_config;
+ config->num_banks = REG_GET_FIELD(adev->gfx.config.mc_arb_ramcfg,
+ MC_ARB_RAMCFG, NOOFBANK);
+ config->num_ranks = REG_GET_FIELD(adev->gfx.config.mc_arb_ramcfg,
+ MC_ARB_RAMCFG, NOOFRANKS);
+
+ config->tile_config_ptr = adev->gfx.config.tile_mode_array;
+ config->num_tile_configs =
+ ARRAY_SIZE(adev->gfx.config.tile_mode_array);
+ config->macro_tile_config_ptr =
+ adev->gfx.config.macrotile_mode_array;
+ config->num_macro_tile_configs =
+ ARRAY_SIZE(adev->gfx.config.macrotile_mode_array);
+
+ return 0;
+}
static const struct kfd2kgd_calls kfd2kgd = {
.init_gtt_mem_allocation = alloc_gtt_mem,
@@ -150,7 +186,9 @@ static const struct kfd2kgd_calls kfd2kgd = {
.get_atc_vmid_pasid_mapping_pasid = get_atc_vmid_pasid_mapping_pasid,
.get_atc_vmid_pasid_mapping_valid = get_atc_vmid_pasid_mapping_valid,
.write_vmid_invalidate_request = write_vmid_invalidate_request,
- .get_fw_version = get_fw_version
+ .get_fw_version = get_fw_version,
+ .set_scratch_backing_va = set_scratch_backing_va,
+ .get_tile_config = get_tile_config,
};
struct kfd2kgd_calls *amdgpu_amdkfd_gfx_7_get_functions(void)
@@ -186,7 +224,7 @@ static void acquire_queue(struct kgd_dev *kgd, uint32_t pipe_id,
{
struct amdgpu_device *adev = get_amdgpu_device(kgd);
- uint32_t mec = (++pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
+ uint32_t mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
uint32_t pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
lock_srbm(kgd, mec, pipe, queue_id, 0);
@@ -290,20 +328,38 @@ static inline struct cik_sdma_rlc_registers *get_sdma_mqd(void *mqd)
}
static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
- uint32_t queue_id, uint32_t __user *wptr)
+ uint32_t queue_id, uint32_t __user *wptr,
+ uint32_t wptr_shift, uint32_t wptr_mask,
+ struct mm_struct *mm)
{
struct amdgpu_device *adev = get_amdgpu_device(kgd);
- uint32_t wptr_shadow, is_wptr_shadow_valid;
struct cik_mqd *m;
+ uint32_t *mqd_hqd;
+ uint32_t reg, wptr_val, data;
m = get_mqd(mqd);
- is_wptr_shadow_valid = !get_user(wptr_shadow, wptr);
- if (is_wptr_shadow_valid)
- m->cp_hqd_pq_wptr = wptr_shadow;
-
acquire_queue(kgd, pipe_id, queue_id);
- gfx_v7_0_mqd_commit(adev, m);
+
+ /* HQD registers extend from CP_MQD_BASE_ADDR to CP_MQD_CONTROL. */
+ mqd_hqd = &m->cp_mqd_base_addr_lo;
+
+ for (reg = mmCP_MQD_BASE_ADDR; reg <= mmCP_MQD_CONTROL; reg++)
+ WREG32(reg, mqd_hqd[reg - mmCP_MQD_BASE_ADDR]);
+
+ /* Copy userspace write pointer value to register.
+ * Activate doorbell logic to monitor subsequent changes.
+ */
+ data = REG_SET_FIELD(m->cp_hqd_pq_doorbell_control,
+ CP_HQD_PQ_DOORBELL_CONTROL, DOORBELL_EN, 1);
+ WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, data);
+
+ if (read_user_wptr(mm, wptr, wptr_val))
+ WREG32(mmCP_HQD_PQ_WPTR, (wptr_val << wptr_shift) & wptr_mask);
+
+ data = REG_SET_FIELD(m->cp_hqd_active, CP_HQD_ACTIVE, ACTIVE, 1);
+ WREG32(mmCP_HQD_ACTIVE, data);
+
release_queue(kgd);
return 0;
@@ -382,30 +438,99 @@ static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd)
return false;
}
-static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
+static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd,
+ enum kfd_preempt_type reset_type,
unsigned int utimeout, uint32_t pipe_id,
uint32_t queue_id)
{
struct amdgpu_device *adev = get_amdgpu_device(kgd);
uint32_t temp;
- int timeout = utimeout;
+ enum hqd_dequeue_request_type type;
+ unsigned long flags, end_jiffies;
+ int retry;
acquire_queue(kgd, pipe_id, queue_id);
WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, 0);
- WREG32(mmCP_HQD_DEQUEUE_REQUEST, reset_type);
+ switch (reset_type) {
+ case KFD_PREEMPT_TYPE_WAVEFRONT_DRAIN:
+ type = DRAIN_PIPE;
+ break;
+ case KFD_PREEMPT_TYPE_WAVEFRONT_RESET:
+ type = RESET_WAVES;
+ break;
+ default:
+ type = DRAIN_PIPE;
+ break;
+ }
+
+ /* Workaround: If IQ timer is active and the wait time is close to or
+ * equal to 0, dequeueing is not safe. Wait until either the wait time
+ * is larger or timer is cleared. Also, ensure that IQ_REQ_PEND is
+ * cleared before continuing. Also, ensure wait times are set to at
+ * least 0x3.
+ */
+ local_irq_save(flags);
+ preempt_disable();
+ retry = 5000; /* wait for 500 usecs at maximum */
+ while (true) {
+ temp = RREG32(mmCP_HQD_IQ_TIMER);
+ if (REG_GET_FIELD(temp, CP_HQD_IQ_TIMER, PROCESSING_IQ)) {
+ pr_debug("HW is processing IQ\n");
+ goto loop;
+ }
+ if (REG_GET_FIELD(temp, CP_HQD_IQ_TIMER, ACTIVE)) {
+ if (REG_GET_FIELD(temp, CP_HQD_IQ_TIMER, RETRY_TYPE)
+ == 3) /* SEM-rearm is safe */
+ break;
+ /* Wait time 3 is safe for CP, but our MMIO read/write
+ * time is close to 1 microsecond, so check for 10 to
+ * leave more buffer room
+ */
+ if (REG_GET_FIELD(temp, CP_HQD_IQ_TIMER, WAIT_TIME)
+ >= 10)
+ break;
+ pr_debug("IQ timer is active\n");
+ } else
+ break;
+loop:
+ if (!retry) {
+ pr_err("CP HQD IQ timer status time out\n");
+ break;
+ }
+ ndelay(100);
+ --retry;
+ }
+ retry = 1000;
+ while (true) {
+ temp = RREG32(mmCP_HQD_DEQUEUE_REQUEST);
+ if (!(temp & CP_HQD_DEQUEUE_REQUEST__IQ_REQ_PEND_MASK))
+ break;
+ pr_debug("Dequeue request is pending\n");
+ if (!retry) {
+ pr_err("CP HQD dequeue request time out\n");
+ break;
+ }
+ ndelay(100);
+ --retry;
+ }
+ local_irq_restore(flags);
+ preempt_enable();
+
+ WREG32(mmCP_HQD_DEQUEUE_REQUEST, type);
+
+ end_jiffies = (utimeout * HZ / 1000) + jiffies;
while (true) {
temp = RREG32(mmCP_HQD_ACTIVE);
- if (temp & CP_HQD_ACTIVE__ACTIVE_MASK)
+ if (!(temp & CP_HQD_ACTIVE__ACTIVE_MASK))
break;
- if (timeout <= 0) {
- pr_err("kfd: cp queue preemption time out.\n");
+ if (time_after(jiffies, end_jiffies)) {
+ pr_err("cp queue preemption time out\n");
release_queue(kgd);
return -ETIME;
}
- msleep(20);
- timeout -= 20;
+ usleep_range(500, 1000);
}
release_queue(kgd);
@@ -556,6 +681,16 @@ static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid)
WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid);
}
+static void set_scratch_backing_va(struct kgd_dev *kgd,
+ uint64_t va, uint32_t vmid)
+{
+ struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
+
+ lock_srbm(kgd, 0, 0, 0, vmid);
+ WREG32(mmSH_HIDDEN_PRIVATE_BASE_VMID, va);
+ unlock_srbm(kgd);
+}
+
static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type)
{
struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
@@ -566,42 +701,42 @@ static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type)
switch (type) {
case KGD_ENGINE_PFP:
hdr = (const union amdgpu_firmware_header *)
- adev->gfx.pfp_fw->data;
+ adev->gfx.pfp_fw->data;
break;
case KGD_ENGINE_ME:
hdr = (const union amdgpu_firmware_header *)
- adev->gfx.me_fw->data;
+ adev->gfx.me_fw->data;
break;
case KGD_ENGINE_CE:
hdr = (const union amdgpu_firmware_header *)
- adev->gfx.ce_fw->data;
+ adev->gfx.ce_fw->data;
break;
case KGD_ENGINE_MEC1:
hdr = (const union amdgpu_firmware_header *)
- adev->gfx.mec_fw->data;
+ adev->gfx.mec_fw->data;
break;
case KGD_ENGINE_MEC2:
hdr = (const union amdgpu_firmware_header *)
- adev->gfx.mec2_fw->data;
+ adev->gfx.mec2_fw->data;
break;
case KGD_ENGINE_RLC:
hdr = (const union amdgpu_firmware_header *)
- adev->gfx.rlc_fw->data;
+ adev->gfx.rlc_fw->data;
break;
case KGD_ENGINE_SDMA1:
hdr = (const union amdgpu_firmware_header *)
- adev->sdma.instance[0].fw->data;
+ adev->sdma.instance[0].fw->data;
break;
case KGD_ENGINE_SDMA2:
hdr = (const union amdgpu_firmware_header *)
- adev->sdma.instance[1].fw->data;
+ adev->sdma.instance[1].fw->data;
break;
default:
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
index 133d066..fb6e5db 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
@@ -39,6 +39,12 @@
#include "vi_structs.h"
#include "vid.h"
+enum hqd_dequeue_request_type {
+ NO_ACTION = 0,
+ DRAIN_PIPE,
+ RESET_WAVES
+};
+
struct cik_sdma_rlc_registers;
/*
@@ -55,12 +61,15 @@ static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id,
uint32_t hpd_size, uint64_t hpd_gpu_addr);
static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id);
static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
- uint32_t queue_id, uint32_t __user *wptr);
+ uint32_t queue_id, uint32_t __user *wptr,
+ uint32_t wptr_shift, uint32_t wptr_mask,
+ struct mm_struct *mm);
static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd);
static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
uint32_t pipe_id, uint32_t queue_id);
static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd);
-static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
+static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd,
+ enum kfd_preempt_type reset_type,
unsigned int utimeout, uint32_t pipe_id,
uint32_t queue_id);
static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
@@ -85,6 +94,33 @@ static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd,
uint8_t vmid);
static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid);
static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type);
+static void set_scratch_backing_va(struct kgd_dev *kgd,
+ uint64_t va, uint32_t vmid);
+
+/* Because of REG_GET_FIELD() being used, we put this function in the
+ * asic specific file.
+ */
+static int get_tile_config(struct kgd_dev *kgd,
+ struct tile_config *config)
+{
+ struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
+
+ config->gb_addr_config = adev->gfx.config.gb_addr_config;
+ config->num_banks = REG_GET_FIELD(adev->gfx.config.mc_arb_ramcfg,
+ MC_ARB_RAMCFG, NOOFBANK);
+ config->num_ranks = REG_GET_FIELD(adev->gfx.config.mc_arb_ramcfg,
+ MC_ARB_RAMCFG, NOOFRANKS);
+
+ config->tile_config_ptr = adev->gfx.config.tile_mode_array;
+ config->num_tile_configs =
+ ARRAY_SIZE(adev->gfx.config.tile_mode_array);
+ config->macro_tile_config_ptr =
+ adev->gfx.config.macrotile_mode_array;
+ config->num_macro_tile_configs =
+ ARRAY_SIZE(adev->gfx.config.macrotile_mode_array);
+
+ return 0;
+}
static const struct kfd2kgd_calls kfd2kgd = {
.init_gtt_mem_allocation = alloc_gtt_mem,
@@ -111,12 +147,15 @@ static const struct kfd2kgd_calls kfd2kgd = {
.get_atc_vmid_pasid_mapping_valid =
get_atc_vmid_pasid_mapping_valid,
.write_vmid_invalidate_request = write_vmid_invalidate_request,
- .get_fw_version = get_fw_version
+ .get_fw_version = get_fw_version,
+ .set_scratch_backing_va = set_scratch_backing_va,
+ .get_tile_config = get_tile_config,
};
struct kfd2kgd_calls *amdgpu_amdkfd_gfx_8_0_get_functions(void)
{
return (struct kfd2kgd_calls *)&kfd2kgd;
+ return (struct kfd2kgd_calls *)&kfd2kgd;
}
static inline struct amdgpu_device *get_amdgpu_device(struct kgd_dev *kgd)
@@ -147,7 +186,7 @@ static void acquire_queue(struct kgd_dev *kgd, uint32_t pipe_id,
{
struct amdgpu_device *adev = get_amdgpu_device(kgd);
- uint32_t mec = (++pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
+ uint32_t mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
uint32_t pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
lock_srbm(kgd, mec, pipe, queue_id, 0);
@@ -216,7 +255,7 @@ static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id)
uint32_t mec;
uint32_t pipe;
- mec = (++pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
+ mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
lock_srbm(kgd, mec, pipe, 0, 0);
@@ -244,20 +283,67 @@ static inline struct cik_sdma_rlc_registers *get_sdma_mqd(void *mqd)
}
static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
- uint32_t queue_id, uint32_t __user *wptr)
+ uint32_t queue_id, uint32_t __user *wptr,
+ uint32_t wptr_shift, uint32_t wptr_mask,
+ struct mm_struct *mm)
{
- struct vi_mqd *m;
- uint32_t shadow_wptr, valid_wptr;
struct amdgpu_device *adev = get_amdgpu_device(kgd);
+ struct vi_mqd *m;
+ uint32_t *mqd_hqd;
+ uint32_t reg, wptr_val, data;
m = get_mqd(mqd);
- valid_wptr = copy_from_user(&shadow_wptr, wptr, sizeof(shadow_wptr));
- if (valid_wptr == 0)
- m->cp_hqd_pq_wptr = shadow_wptr;
-
acquire_queue(kgd, pipe_id, queue_id);
- gfx_v8_0_mqd_commit(adev, mqd);
+
+ /* HIQ is set during driver init period with vmid set to 0*/
+ if (m->cp_hqd_vmid == 0) {
+ uint32_t value, mec, pipe;
+
+ mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
+ pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
+
+ pr_debug("kfd: set HIQ, mec:%d, pipe:%d, queue:%d.\n",
+ mec, pipe, queue_id);
+ value = RREG32(mmRLC_CP_SCHEDULERS);
+ value = REG_SET_FIELD(value, RLC_CP_SCHEDULERS, scheduler1,
+ ((mec << 5) | (pipe << 3) | queue_id | 0x80));
+ WREG32(mmRLC_CP_SCHEDULERS, value);
+ }
+
+ /* HQD registers extend from CP_MQD_BASE_ADDR to CP_HQD_EOP_WPTR_MEM. */
+ mqd_hqd = &m->cp_mqd_base_addr_lo;
+
+ for (reg = mmCP_MQD_BASE_ADDR; reg <= mmCP_HQD_EOP_CONTROL; reg++)
+ WREG32(reg, mqd_hqd[reg - mmCP_MQD_BASE_ADDR]);
+
+ /* Tonga errata: EOP RPTR/WPTR should be left unmodified.
+ * This is safe since EOP RPTR==WPTR for any inactive HQD
+ * on ASICs that do not support context-save.
+ * EOP writes/reads can start anywhere in the ring.
+ */
+ if (get_amdgpu_device(kgd)->asic_type != CHIP_TONGA) {
+ WREG32(mmCP_HQD_EOP_RPTR, m->cp_hqd_eop_rptr);
+ WREG32(mmCP_HQD_EOP_WPTR, m->cp_hqd_eop_wptr);
+ WREG32(mmCP_HQD_EOP_WPTR_MEM, m->cp_hqd_eop_wptr_mem);
+ }
+
+ for (reg = mmCP_HQD_EOP_EVENTS; reg <= mmCP_HQD_ERROR; reg++)
+ WREG32(reg, mqd_hqd[reg - mmCP_MQD_BASE_ADDR]);
+
+ /* Copy userspace write pointer value to register.
+ * Activate doorbell logic to monitor subsequent changes.
+ */
+ data = REG_SET_FIELD(m->cp_hqd_pq_doorbell_control,
+ CP_HQD_PQ_DOORBELL_CONTROL, DOORBELL_EN, 1);
+ WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, data);
+
+ if (read_user_wptr(mm, wptr, wptr_val))
+ WREG32(mmCP_HQD_PQ_WPTR, (wptr_val << wptr_shift) & wptr_mask);
+
+ data = REG_SET_FIELD(m->cp_hqd_active, CP_HQD_ACTIVE, ACTIVE, 1);
+ WREG32(mmCP_HQD_ACTIVE, data);
+
release_queue(kgd);
return 0;
@@ -308,29 +394,102 @@ static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd)
return false;
}
-static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
+static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd,
+ enum kfd_preempt_type reset_type,
unsigned int utimeout, uint32_t pipe_id,
uint32_t queue_id)
{
struct amdgpu_device *adev = get_amdgpu_device(kgd);
uint32_t temp;
- int timeout = utimeout;
+ enum hqd_dequeue_request_type type;
+ unsigned long flags, end_jiffies;
+ int retry;
+ struct vi_mqd *m = get_mqd(mqd);
acquire_queue(kgd, pipe_id, queue_id);
- WREG32(mmCP_HQD_DEQUEUE_REQUEST, reset_type);
+ if (m->cp_hqd_vmid == 0)
+ WREG32_FIELD(RLC_CP_SCHEDULERS, scheduler1, 0);
+
+ switch (reset_type) {
+ case KFD_PREEMPT_TYPE_WAVEFRONT_DRAIN:
+ type = DRAIN_PIPE;
+ break;
+ case KFD_PREEMPT_TYPE_WAVEFRONT_RESET:
+ type = RESET_WAVES;
+ break;
+ default:
+ type = DRAIN_PIPE;
+ break;
+ }
+ /* Workaround: If IQ timer is active and the wait time is close to or
+ * equal to 0, dequeueing is not safe. Wait until either the wait time
+ * is larger or timer is cleared. Also, ensure that IQ_REQ_PEND is
+ * cleared before continuing. Also, ensure wait times are set to at
+ * least 0x3.
+ */
+ local_irq_save(flags);
+ preempt_disable();
+ retry = 5000; /* wait for 500 usecs at maximum */
+ while (true) {
+ temp = RREG32(mmCP_HQD_IQ_TIMER);
+ if (REG_GET_FIELD(temp, CP_HQD_IQ_TIMER, PROCESSING_IQ)) {
+ pr_debug("HW is processing IQ\n");
+ goto loop;
+ }
+ if (REG_GET_FIELD(temp, CP_HQD_IQ_TIMER, ACTIVE)) {
+ if (REG_GET_FIELD(temp, CP_HQD_IQ_TIMER, RETRY_TYPE)
+ == 3) /* SEM-rearm is safe */
+ break;
+ /* Wait time 3 is safe for CP, but our MMIO read/write
+ * time is close to 1 microsecond, so check for 10 to
+ * leave more buffer room
+ */
+ if (REG_GET_FIELD(temp, CP_HQD_IQ_TIMER, WAIT_TIME)
+ >= 10)
+ break;
+ pr_debug("IQ timer is active\n");
+ } else
+ break;
+loop:
+ if (!retry) {
+ pr_err("CP HQD IQ timer status time out\n");
+ break;
+ }
+ ndelay(100);
+ --retry;
+ }
+ retry = 1000;
+ while (true) {
+ temp = RREG32(mmCP_HQD_DEQUEUE_REQUEST);
+ if (!(temp & CP_HQD_DEQUEUE_REQUEST__IQ_REQ_PEND_MASK))
+ break;
+ pr_debug("Dequeue request is pending\n");
+
+ if (!retry) {
+ pr_err("CP HQD dequeue request time out\n");
+ break;
+ }
+ ndelay(100);
+ --retry;
+ }
+ local_irq_restore(flags);
+ preempt_enable();
+
+ WREG32(mmCP_HQD_DEQUEUE_REQUEST, type);
+
+ end_jiffies = (utimeout * HZ / 1000) + jiffies;
while (true) {
temp = RREG32(mmCP_HQD_ACTIVE);
- if (temp & CP_HQD_ACTIVE__ACTIVE_MASK)
+ if (!(temp & CP_HQD_ACTIVE__ACTIVE_MASK))
break;
- if (timeout <= 0) {
- pr_err("kfd: cp queue preemption time out.\n");
+ if (time_after(jiffies, end_jiffies)) {
+ pr_err("cp queue preemption time out.\n");
release_queue(kgd);
return -ETIME;
}
- msleep(20);
- timeout -= 20;
+ usleep_range(500, 1000);
}
release_queue(kgd);
@@ -444,6 +603,16 @@ static uint32_t kgd_address_watch_get_offset(struct kgd_dev *kgd,
return 0;
}
+static void set_scratch_backing_va(struct kgd_dev *kgd,
+ uint64_t va, uint32_t vmid)
+{
+ struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
+
+ lock_srbm(kgd, 0, 0, 0, vmid);
+ WREG32(mmSH_HIDDEN_PRIVATE_BASE_VMID, va);
+ unlock_srbm(kgd);
+}
+
static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type)
{
struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
@@ -454,42 +623,42 @@ static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type)
switch (type) {
case KGD_ENGINE_PFP:
hdr = (const union amdgpu_firmware_header *)
- adev->gfx.pfp_fw->data;
+ adev->gfx.pfp_fw->data;
break;
case KGD_ENGINE_ME:
hdr = (const union amdgpu_firmware_header *)
- adev->gfx.me_fw->data;
+ adev->gfx.me_fw->data;
break;
case KGD_ENGINE_CE:
hdr = (const union amdgpu_firmware_header *)
- adev->gfx.ce_fw->data;
+ adev->gfx.ce_fw->data;
break;
case KGD_ENGINE_MEC1:
hdr = (const union amdgpu_firmware_header *)
- adev->gfx.mec_fw->data;
+ adev->gfx.mec_fw->data;
break;
case KGD_ENGINE_MEC2:
hdr = (const union amdgpu_firmware_header *)
- adev->gfx.mec2_fw->data;
+ adev->gfx.mec2_fw->data;
break;
case KGD_ENGINE_RLC:
hdr = (const union amdgpu_firmware_header *)
- adev->gfx.rlc_fw->data;
+ adev->gfx.rlc_fw->data;
break;
case KGD_ENGINE_SDMA1:
hdr = (const union amdgpu_firmware_header *)
- adev->sdma.instance[0].fw->data;
+ adev->sdma.instance[0].fw->data;
break;
case KGD_ENGINE_SDMA2:
hdr = (const union amdgpu_firmware_header *)
- adev->sdma.instance[1].fw->data;
+ adev->sdma.instance[1].fw->data;
break;
default:
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
index 1e8e112..ce44358 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
@@ -1686,7 +1686,7 @@ void amdgpu_atombios_scratch_regs_lock(struct amdgpu_device *adev, bool lock)
{
uint32_t bios_6_scratch;
- bios_6_scratch = RREG32(mmBIOS_SCRATCH_6);
+ bios_6_scratch = RREG32(adev->bios_scratch_reg_offset + 6);
if (lock) {
bios_6_scratch |= ATOM_S6_CRITICAL_STATE;
@@ -1696,15 +1696,17 @@ void amdgpu_atombios_scratch_regs_lock(struct amdgpu_device *adev, bool lock)
bios_6_scratch |= ATOM_S6_ACC_MODE;
}
- WREG32(mmBIOS_SCRATCH_6, bios_6_scratch);
+ WREG32(adev->bios_scratch_reg_offset + 6, bios_6_scratch);
}
void amdgpu_atombios_scratch_regs_init(struct amdgpu_device *adev)
{
uint32_t bios_2_scratch, bios_6_scratch;
- bios_2_scratch = RREG32(mmBIOS_SCRATCH_2);
- bios_6_scratch = RREG32(mmBIOS_SCRATCH_6);
+ adev->bios_scratch_reg_offset = mmBIOS_SCRATCH_0;
+
+ bios_2_scratch = RREG32(adev->bios_scratch_reg_offset + 2);
+ bios_6_scratch = RREG32(adev->bios_scratch_reg_offset + 6);
/* let the bios control the backlight */
bios_2_scratch &= ~ATOM_S2_VRI_BRIGHT_ENABLE;
@@ -1715,8 +1717,8 @@ void amdgpu_atombios_scratch_regs_init(struct amdgpu_device *adev)
/* clear the vbios dpms state */
bios_2_scratch &= ~ATOM_S2_DEVICE_DPMS_STATE;
- WREG32(mmBIOS_SCRATCH_2, bios_2_scratch);
- WREG32(mmBIOS_SCRATCH_6, bios_6_scratch);
+ WREG32(adev->bios_scratch_reg_offset + 2, bios_2_scratch);
+ WREG32(adev->bios_scratch_reg_offset + 6, bios_6_scratch);
}
void amdgpu_atombios_scratch_regs_save(struct amdgpu_device *adev)
@@ -1724,7 +1726,7 @@ void amdgpu_atombios_scratch_regs_save(struct amdgpu_device *adev)
int i;
for (i = 0; i < AMDGPU_BIOS_NUM_SCRATCH; i++)
- adev->bios_scratch[i] = RREG32(mmBIOS_SCRATCH_0 + i);
+ adev->bios_scratch[i] = RREG32(adev->bios_scratch_reg_offset + i);
}
void amdgpu_atombios_scratch_regs_restore(struct amdgpu_device *adev)
@@ -1738,20 +1740,30 @@ void amdgpu_atombios_scratch_regs_restore(struct amdgpu_device *adev)
adev->bios_scratch[7] &= ~ATOM_S7_ASIC_INIT_COMPLETE_MASK;
for (i = 0; i < AMDGPU_BIOS_NUM_SCRATCH; i++)
- WREG32(mmBIOS_SCRATCH_0 + i, adev->bios_scratch[i]);
+ WREG32(adev->bios_scratch_reg_offset + i, adev->bios_scratch[i]);
}
void amdgpu_atombios_scratch_regs_engine_hung(struct amdgpu_device *adev,
bool hung)
{
- u32 tmp = RREG32(mmBIOS_SCRATCH_3);
+ u32 tmp = RREG32(adev->bios_scratch_reg_offset + 3);
if (hung)
tmp |= ATOM_S3_ASIC_GUI_ENGINE_HUNG;
else
tmp &= ~ATOM_S3_ASIC_GUI_ENGINE_HUNG;
- WREG32(mmBIOS_SCRATCH_3, tmp);
+ WREG32(adev->bios_scratch_reg_offset + 3, tmp);
+}
+
+bool amdgpu_atombios_scratch_need_asic_init(struct amdgpu_device *adev)
+{
+ u32 tmp = RREG32(adev->bios_scratch_reg_offset + 7);
+
+ if (tmp & ATOM_S7_ASIC_INIT_COMPLETE_MASK)
+ return false;
+ else
+ return true;
}
/* Atom needs data in little endian format
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h
index 38d0fe3..b0d5d1d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h
@@ -200,6 +200,7 @@ void amdgpu_atombios_scratch_regs_save(struct amdgpu_device *adev);
void amdgpu_atombios_scratch_regs_restore(struct amdgpu_device *adev);
void amdgpu_atombios_scratch_regs_engine_hung(struct amdgpu_device *adev,
bool hung);
+bool amdgpu_atombios_scratch_need_asic_init(struct amdgpu_device *adev);
void amdgpu_atombios_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le);
int amdgpu_atombios_get_max_vddc(struct amdgpu_device *adev, u8 voltage_type,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
index 4bdda56..f9ffe8e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
@@ -66,41 +66,6 @@ void amdgpu_atomfirmware_scratch_regs_init(struct amdgpu_device *adev)
}
}
-void amdgpu_atomfirmware_scratch_regs_save(struct amdgpu_device *adev)
-{
- int i;
-
- for (i = 0; i < AMDGPU_BIOS_NUM_SCRATCH; i++)
- adev->bios_scratch[i] = RREG32(adev->bios_scratch_reg_offset + i);
-}
-
-void amdgpu_atomfirmware_scratch_regs_restore(struct amdgpu_device *adev)
-{
- int i;
-
- /*
- * VBIOS will check ASIC_INIT_COMPLETE bit to decide if
- * execute ASIC_Init posting via driver
- */
- adev->bios_scratch[7] &= ~ATOM_S7_ASIC_INIT_COMPLETE_MASK;
-
- for (i = 0; i < AMDGPU_BIOS_NUM_SCRATCH; i++)
- WREG32(adev->bios_scratch_reg_offset + i, adev->bios_scratch[i]);
-}
-
-void amdgpu_atomfirmware_scratch_regs_engine_hung(struct amdgpu_device *adev,
- bool hung)
-{
- u32 tmp = RREG32(adev->bios_scratch_reg_offset + 3);
-
- if (hung)
- tmp |= ATOM_S3_ASIC_GUI_ENGINE_HUNG;
- else
- tmp &= ~ATOM_S3_ASIC_GUI_ENGINE_HUNG;
-
- WREG32(adev->bios_scratch_reg_offset + 3, tmp);
-}
-
int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev)
{
struct atom_context *ctx = adev->mode_info.atom_context;
@@ -130,3 +95,129 @@ int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev)
ctx->scratch_size_bytes = usage_bytes;
return 0;
}
+
+union igp_info {
+ struct atom_integrated_system_info_v1_11 v11;
+};
+
+/*
+ * Return vram width from integrated system info table, if available,
+ * or 0 if not.
+ */
+int amdgpu_atomfirmware_get_vram_width(struct amdgpu_device *adev)
+{
+ struct amdgpu_mode_info *mode_info = &adev->mode_info;
+ int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
+ integratedsysteminfo);
+ u16 data_offset, size;
+ union igp_info *igp_info;
+ u8 frev, crev;
+
+ /* get any igp specific overrides */
+ if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, &size,
+ &frev, &crev, &data_offset)) {
+ igp_info = (union igp_info *)
+ (mode_info->atom_context->bios + data_offset);
+ switch (crev) {
+ case 11:
+ return igp_info->v11.umachannelnumber * 64;
+ default:
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+union firmware_info {
+ struct atom_firmware_info_v3_1 v31;
+};
+
+union smu_info {
+ struct atom_smu_info_v3_1 v31;
+};
+
+union umc_info {
+ struct atom_umc_info_v3_1 v31;
+};
+
+int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev)
+{
+ struct amdgpu_mode_info *mode_info = &adev->mode_info;
+ struct amdgpu_pll *spll = &adev->clock.spll;
+ struct amdgpu_pll *mpll = &adev->clock.mpll;
+ uint8_t frev, crev;
+ uint16_t data_offset;
+ int ret = -EINVAL, index;
+
+ index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
+ firmwareinfo);
+ if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
+ &frev, &crev, &data_offset)) {
+ union firmware_info *firmware_info =
+ (union firmware_info *)(mode_info->atom_context->bios +
+ data_offset);
+
+ adev->clock.default_sclk =
+ le32_to_cpu(firmware_info->v31.bootup_sclk_in10khz);
+ adev->clock.default_mclk =
+ le32_to_cpu(firmware_info->v31.bootup_mclk_in10khz);
+
+ adev->pm.current_sclk = adev->clock.default_sclk;
+ adev->pm.current_mclk = adev->clock.default_mclk;
+
+ /* not technically a clock, but... */
+ adev->mode_info.firmware_flags =
+ le32_to_cpu(firmware_info->v31.firmware_capability);
+
+ ret = 0;
+ }
+
+ index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
+ smu_info);
+ if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
+ &frev, &crev, &data_offset)) {
+ union smu_info *smu_info =
+ (union smu_info *)(mode_info->atom_context->bios +
+ data_offset);
+
+ /* system clock */
+ spll->reference_freq = le32_to_cpu(smu_info->v31.core_refclk_10khz);
+
+ spll->reference_div = 0;
+ spll->min_post_div = 1;
+ spll->max_post_div = 1;
+ spll->min_ref_div = 2;
+ spll->max_ref_div = 0xff;
+ spll->min_feedback_div = 4;
+ spll->max_feedback_div = 0xff;
+ spll->best_vco = 0;
+
+ ret = 0;
+ }
+
+ index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
+ umc_info);
+ if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
+ &frev, &crev, &data_offset)) {
+ union umc_info *umc_info =
+ (union umc_info *)(mode_info->atom_context->bios +
+ data_offset);
+
+ /* memory clock */
+ mpll->reference_freq = le32_to_cpu(umc_info->v31.mem_refclk_10khz);
+
+ mpll->reference_div = 0;
+ mpll->min_post_div = 1;
+ mpll->max_post_div = 1;
+ mpll->min_ref_div = 2;
+ mpll->max_ref_div = 0xff;
+ mpll->min_feedback_div = 4;
+ mpll->max_feedback_div = 0xff;
+ mpll->best_vco = 0;
+
+ ret = 0;
+ }
+
+ return ret;
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h
index a2c3ebe..288b97e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h
@@ -26,10 +26,8 @@
bool amdgpu_atomfirmware_gpu_supports_virtualization(struct amdgpu_device *adev);
void amdgpu_atomfirmware_scratch_regs_init(struct amdgpu_device *adev);
-void amdgpu_atomfirmware_scratch_regs_save(struct amdgpu_device *adev);
-void amdgpu_atomfirmware_scratch_regs_restore(struct amdgpu_device *adev);
-void amdgpu_atomfirmware_scratch_regs_engine_hung(struct amdgpu_device *adev,
- bool hung);
int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev);
+int amdgpu_atomfirmware_get_vram_width(struct amdgpu_device *adev);
+int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev);
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
index 1beae5b..63ec1e1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
@@ -40,7 +40,7 @@ static int amdgpu_benchmark_do_move(struct amdgpu_device *adev, unsigned size,
for (i = 0; i < n; i++) {
struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
r = amdgpu_copy_buffer(ring, saddr, daddr, size, NULL, &fence,
- false);
+ false, false);
if (r)
goto exit_do_move;
r = dma_fence_wait(fence, false);
@@ -81,7 +81,7 @@ static void amdgpu_benchmark_move(struct amdgpu_device *adev, unsigned size,
n = AMDGPU_BENCHMARK_ITERATIONS;
r = amdgpu_bo_create(adev, size, PAGE_SIZE, true, sdomain, 0, NULL,
- NULL, &sobj);
+ NULL, 0, &sobj);
if (r) {
goto out_cleanup;
}
@@ -94,7 +94,7 @@ static void amdgpu_benchmark_move(struct amdgpu_device *adev, unsigned size,
goto out_cleanup;
}
r = amdgpu_bo_create(adev, size, PAGE_SIZE, true, ddomain, 0, NULL,
- NULL, &dobj);
+ NULL, 0, &dobj);
if (r) {
goto out_cleanup;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
index 365e735..c21adf6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
@@ -86,19 +86,6 @@ static bool check_atom_bios(uint8_t *bios, size_t size)
return false;
}
-static bool is_atom_fw(uint8_t *bios)
-{
- uint16_t bios_header_start = bios[0x48] | (bios[0x49] << 8);
- uint8_t frev = bios[bios_header_start + 2];
- uint8_t crev = bios[bios_header_start + 3];
-
- if ((frev < 3) ||
- ((frev == 3) && (crev < 3)))
- return false;
-
- return true;
-}
-
/* If you boot an IGP board with a discrete card as the primary,
* the IGP rom is not accessible via the rom bar as the IGP rom is
* part of the system bios. On boot, the system bios puts a
@@ -117,7 +104,7 @@ static bool igp_read_bios_from_vram(struct amdgpu_device *adev)
adev->bios = NULL;
vram_base = pci_resource_start(adev->pdev, 0);
- bios = ioremap(vram_base, size);
+ bios = ioremap_wc(vram_base, size);
if (!bios) {
return false;
}
@@ -455,6 +442,6 @@ bool amdgpu_get_bios(struct amdgpu_device *adev)
return false;
success:
- adev->is_atom_fw = is_atom_fw(adev->bios);
+ adev->is_atom_fw = (adev->asic_type >= CHIP_VEGA10) ? true : false;
return true;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
index 5e771bc11b..59089e0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
@@ -83,7 +83,7 @@ static int amdgpu_bo_list_create(struct amdgpu_device *adev,
r = idr_alloc(&fpriv->bo_list_handles, list, 1, 0, GFP_KERNEL);
mutex_unlock(&fpriv->bo_list_lock);
if (r < 0) {
- kfree(list);
+ amdgpu_bo_list_free(list);
return r;
}
*id = r;
@@ -136,7 +136,7 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev,
}
bo = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj));
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
usermm = amdgpu_ttm_tt_get_usermm(bo->tbo.ttm);
if (usermm) {
@@ -156,11 +156,11 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev,
entry->tv.bo = &entry->robj->tbo;
entry->tv.shared = !entry->robj->prime_shared_count;
- if (entry->robj->prefered_domains == AMDGPU_GEM_DOMAIN_GDS)
+ if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_GDS)
gds_obj = entry->robj;
- if (entry->robj->prefered_domains == AMDGPU_GEM_DOMAIN_GWS)
+ if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_GWS)
gws_obj = entry->robj;
- if (entry->robj->prefered_domains == AMDGPU_GEM_DOMAIN_OA)
+ if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_OA)
oa_obj = entry->robj;
total_size += amdgpu_bo_size(entry->robj);
@@ -270,7 +270,7 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data,
struct amdgpu_fpriv *fpriv = filp->driver_priv;
union drm_amdgpu_bo_list *args = data;
uint32_t handle = args->in.list_handle;
- const void __user *uptr = (const void*)(uintptr_t)args->in.bo_info_ptr;
+ const void __user *uptr = u64_to_user_ptr(args->in.bo_info_ptr);
struct drm_amdgpu_bo_list_entry *info;
struct amdgpu_bo_list *list;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
index c0a8062..fd435a9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
@@ -124,7 +124,7 @@ static int amdgpu_cgs_alloc_gpu_mem(struct cgs_device *cgs_device,
ret = amdgpu_bo_create_restricted(adev, size, PAGE_SIZE,
true, domain, flags,
NULL, &placement, NULL,
- &obj);
+ 0, &obj);
if (ret) {
DRM_ERROR("(%d) bo create failed\n", ret);
return ret;
@@ -166,7 +166,7 @@ static int amdgpu_cgs_gmap_gpu_mem(struct cgs_device *cgs_device, cgs_handle_t h
r = amdgpu_bo_reserve(obj, true);
if (unlikely(r != 0))
return r;
- r = amdgpu_bo_pin_restricted(obj, obj->prefered_domains,
+ r = amdgpu_bo_pin_restricted(obj, obj->preferred_domains,
min_offset, max_offset, mcaddr);
amdgpu_bo_unreserve(obj);
return r;
@@ -240,6 +240,8 @@ static uint32_t amdgpu_cgs_read_ind_register(struct cgs_device *cgs_device,
return RREG32_DIDT(index);
case CGS_IND_REG_GC_CAC:
return RREG32_GC_CAC(index);
+ case CGS_IND_REG_SE_CAC:
+ return RREG32_SE_CAC(index);
case CGS_IND_REG__AUDIO_ENDPT:
DRM_ERROR("audio endpt register access not implemented.\n");
return 0;
@@ -266,6 +268,8 @@ static void amdgpu_cgs_write_ind_register(struct cgs_device *cgs_device,
return WREG32_DIDT(index, value);
case CGS_IND_REG_GC_CAC:
return WREG32_GC_CAC(index, value);
+ case CGS_IND_REG_SE_CAC:
+ return WREG32_SE_CAC(index, value);
case CGS_IND_REG__AUDIO_ENDPT:
DRM_ERROR("audio endpt register access not implemented.\n");
return;
@@ -610,6 +614,17 @@ static int amdgpu_cgs_enter_safe_mode(struct cgs_device *cgs_device,
return 0;
}
+static void amdgpu_cgs_lock_grbm_idx(struct cgs_device *cgs_device,
+ bool lock)
+{
+ CGS_FUNC_ADEV;
+
+ if (lock)
+ mutex_lock(&adev->grbm_idx_mutex);
+ else
+ mutex_unlock(&adev->grbm_idx_mutex);
+}
+
static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
enum cgs_ucode_id type,
struct cgs_firmware_info *info)
@@ -644,7 +659,7 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
info->version = (uint16_t)le32_to_cpu(header->header.ucode_version);
if (CGS_UCODE_ID_CP_MEC == type)
- info->image_size = (header->jt_offset) << 2;
+ info->image_size = le32_to_cpu(header->jt_offset) << 2;
info->fw_version = amdgpu_get_firmware_version(cgs_device, type);
info->feature_version = (uint16_t)le32_to_cpu(header->ucode_feature_version);
@@ -719,7 +734,13 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
strcpy(fw_name, "amdgpu/polaris12_smc.bin");
break;
case CHIP_VEGA10:
- strcpy(fw_name, "amdgpu/vega10_smc.bin");
+ if ((adev->pdev->device == 0x687f) &&
+ ((adev->pdev->revision == 0xc0) ||
+ (adev->pdev->revision == 0xc1) ||
+ (adev->pdev->revision == 0xc3)))
+ strcpy(fw_name, "amdgpu/vega10_acg_smc.bin");
+ else
+ strcpy(fw_name, "amdgpu/vega10_smc.bin");
break;
default:
DRM_ERROR("SMC firmware not supported\n");
@@ -1117,6 +1138,7 @@ static const struct cgs_ops amdgpu_cgs_ops = {
.query_system_info = amdgpu_cgs_query_system_info,
.is_virtualization_enabled = amdgpu_cgs_is_virtualization_enabled,
.enter_safe_mode = amdgpu_cgs_enter_safe_mode,
+ .lock_grbm_idx = amdgpu_cgs_lock_grbm_idx,
};
static const struct cgs_os_ops amdgpu_cgs_os_ops = {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 5599c01..269b835 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -54,7 +54,7 @@ static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p,
*offset = data->offset;
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
if (amdgpu_ttm_tt_get_usermm(p->uf_entry.robj->tbo.ttm)) {
amdgpu_bo_unref(&p->uf_entry.robj);
@@ -90,7 +90,7 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
}
/* get chunks */
- chunk_array_user = (uint64_t __user *)(uintptr_t)(cs->in.chunks);
+ chunk_array_user = u64_to_user_ptr(cs->in.chunks);
if (copy_from_user(chunk_array, chunk_array_user,
sizeof(uint64_t)*cs->in.num_chunks)) {
ret = -EFAULT;
@@ -110,7 +110,7 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
struct drm_amdgpu_cs_chunk user_chunk;
uint32_t __user *cdata;
- chunk_ptr = (void __user *)(uintptr_t)chunk_array[i];
+ chunk_ptr = u64_to_user_ptr(chunk_array[i]);
if (copy_from_user(&user_chunk, chunk_ptr,
sizeof(struct drm_amdgpu_cs_chunk))) {
ret = -EFAULT;
@@ -121,7 +121,7 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
p->chunks[i].length_dw = user_chunk.length_dw;
size = p->chunks[i].length_dw;
- cdata = (void __user *)(uintptr_t)user_chunk.chunk_data;
+ cdata = u64_to_user_ptr(user_chunk.chunk_data);
p->chunks[i].kdata = kvmalloc_array(size, sizeof(uint32_t), GFP_KERNEL);
if (p->chunks[i].kdata == NULL) {
@@ -223,10 +223,11 @@ static s64 bytes_to_us(struct amdgpu_device *adev, u64 bytes)
* ticks. The accumulated microseconds (us) are converted to bytes and
* returned.
*/
-static u64 amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev)
+static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev,
+ u64 *max_bytes,
+ u64 *max_vis_bytes)
{
s64 time_us, increment_us;
- u64 max_bytes;
u64 free_vram, total_vram, used_vram;
/* Allow a maximum of 200 accumulated ms. This is basically per-IB
@@ -238,11 +239,14 @@ static u64 amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev)
*/
const s64 us_upper_bound = 200000;
- if (!adev->mm_stats.log2_max_MBps)
- return 0;
+ if (!adev->mm_stats.log2_max_MBps) {
+ *max_bytes = 0;
+ *max_vis_bytes = 0;
+ return;
+ }
total_vram = adev->mc.real_vram_size - adev->vram_pin_size;
- used_vram = atomic64_read(&adev->vram_usage);
+ used_vram = amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);
free_vram = used_vram >= total_vram ? 0 : total_vram - used_vram;
spin_lock(&adev->mm_stats.lock);
@@ -280,23 +284,46 @@ static u64 amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev)
adev->mm_stats.accum_us = max(min_us, adev->mm_stats.accum_us);
}
- /* This returns 0 if the driver is in debt to disallow (optional)
+ /* This is set to 0 if the driver is in debt to disallow (optional)
* buffer moves.
*/
- max_bytes = us_to_bytes(adev, adev->mm_stats.accum_us);
+ *max_bytes = us_to_bytes(adev, adev->mm_stats.accum_us);
+
+ /* Do the same for visible VRAM if half of it is free */
+ if (adev->mc.visible_vram_size < adev->mc.real_vram_size) {
+ u64 total_vis_vram = adev->mc.visible_vram_size;
+ u64 used_vis_vram =
+ amdgpu_vram_mgr_vis_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);
+
+ if (used_vis_vram < total_vis_vram) {
+ u64 free_vis_vram = total_vis_vram - used_vis_vram;
+ adev->mm_stats.accum_us_vis = min(adev->mm_stats.accum_us_vis +
+ increment_us, us_upper_bound);
+
+ if (free_vis_vram >= total_vis_vram / 2)
+ adev->mm_stats.accum_us_vis =
+ max(bytes_to_us(adev, free_vis_vram / 2),
+ adev->mm_stats.accum_us_vis);
+ }
+
+ *max_vis_bytes = us_to_bytes(adev, adev->mm_stats.accum_us_vis);
+ } else {
+ *max_vis_bytes = 0;
+ }
spin_unlock(&adev->mm_stats.lock);
- return max_bytes;
}
/* Report how many bytes have really been moved for the last command
* submission. This can result in a debt that can stop buffer migrations
* temporarily.
*/
-void amdgpu_cs_report_moved_bytes(struct amdgpu_device *adev, u64 num_bytes)
+void amdgpu_cs_report_moved_bytes(struct amdgpu_device *adev, u64 num_bytes,
+ u64 num_vis_bytes)
{
spin_lock(&adev->mm_stats.lock);
adev->mm_stats.accum_us -= bytes_to_us(adev, num_bytes);
+ adev->mm_stats.accum_us_vis -= bytes_to_us(adev, num_vis_bytes);
spin_unlock(&adev->mm_stats.lock);
}
@@ -304,7 +331,7 @@ static int amdgpu_cs_bo_validate(struct amdgpu_cs_parser *p,
struct amdgpu_bo *bo)
{
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
- u64 initial_bytes_moved;
+ u64 initial_bytes_moved, bytes_moved;
uint32_t domain;
int r;
@@ -314,17 +341,35 @@ static int amdgpu_cs_bo_validate(struct amdgpu_cs_parser *p,
/* Don't move this buffer if we have depleted our allowance
* to move it. Don't move anything if the threshold is zero.
*/
- if (p->bytes_moved < p->bytes_moved_threshold)
- domain = bo->prefered_domains;
- else
+ if (p->bytes_moved < p->bytes_moved_threshold) {
+ if (adev->mc.visible_vram_size < adev->mc.real_vram_size &&
+ (bo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)) {
+ /* And don't move a CPU_ACCESS_REQUIRED BO to limited
+ * visible VRAM if we've depleted our allowance to do
+ * that.
+ */
+ if (p->bytes_moved_vis < p->bytes_moved_vis_threshold)
+ domain = bo->preferred_domains;
+ else
+ domain = bo->allowed_domains;
+ } else {
+ domain = bo->preferred_domains;
+ }
+ } else {
domain = bo->allowed_domains;
+ }
retry:
amdgpu_ttm_placement_from_domain(bo, domain);
initial_bytes_moved = atomic64_read(&adev->num_bytes_moved);
r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
- p->bytes_moved += atomic64_read(&adev->num_bytes_moved) -
- initial_bytes_moved;
+ bytes_moved = atomic64_read(&adev->num_bytes_moved) -
+ initial_bytes_moved;
+ p->bytes_moved += bytes_moved;
+ if (adev->mc.visible_vram_size < adev->mc.real_vram_size &&
+ bo->tbo.mem.mem_type == TTM_PL_VRAM &&
+ bo->tbo.mem.start < adev->mc.visible_vram_size >> PAGE_SHIFT)
+ p->bytes_moved_vis += bytes_moved;
if (unlikely(r == -ENOMEM) && domain != bo->allowed_domains) {
domain = bo->allowed_domains;
@@ -350,7 +395,8 @@ static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p,
struct amdgpu_bo_list_entry *candidate = p->evictable;
struct amdgpu_bo *bo = candidate->robj;
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
- u64 initial_bytes_moved;
+ u64 initial_bytes_moved, bytes_moved;
+ bool update_bytes_moved_vis;
uint32_t other;
/* If we reached our current BO we can forget it */
@@ -370,10 +416,17 @@ static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p,
/* Good we can try to move this BO somewhere else */
amdgpu_ttm_placement_from_domain(bo, other);
+ update_bytes_moved_vis =
+ adev->mc.visible_vram_size < adev->mc.real_vram_size &&
+ bo->tbo.mem.mem_type == TTM_PL_VRAM &&
+ bo->tbo.mem.start < adev->mc.visible_vram_size >> PAGE_SHIFT;
initial_bytes_moved = atomic64_read(&adev->num_bytes_moved);
r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
- p->bytes_moved += atomic64_read(&adev->num_bytes_moved) -
+ bytes_moved = atomic64_read(&adev->num_bytes_moved) -
initial_bytes_moved;
+ p->bytes_moved += bytes_moved;
+ if (update_bytes_moved_vis)
+ p->bytes_moved_vis += bytes_moved;
if (unlikely(r))
break;
@@ -554,8 +607,10 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
list_splice(&need_pages, &p->validated);
}
- p->bytes_moved_threshold = amdgpu_cs_get_threshold_for_moves(p->adev);
+ amdgpu_cs_get_threshold_for_moves(p->adev, &p->bytes_moved_threshold,
+ &p->bytes_moved_vis_threshold);
p->bytes_moved = 0;
+ p->bytes_moved_vis = 0;
p->evictable = list_last_entry(&p->validated,
struct amdgpu_bo_list_entry,
tv.head);
@@ -579,8 +634,8 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
goto error_validate;
}
- amdgpu_cs_report_moved_bytes(p->adev, p->bytes_moved);
-
+ amdgpu_cs_report_moved_bytes(p->adev, p->bytes_moved,
+ p->bytes_moved_vis);
fpriv->vm.last_eviction_counter =
atomic64_read(&p->adev->num_evictions);
@@ -619,10 +674,8 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
}
error_validate:
- if (r) {
- amdgpu_vm_move_pt_bos_in_lru(p->adev, &fpriv->vm);
+ if (r)
ttm_eu_backoff_reservation(&p->ticket, &p->validated);
- }
error_free_pages:
@@ -670,21 +723,18 @@ static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser *p)
* If error is set than unvalidate buffer, otherwise just free memory
* used by parsing context.
**/
-static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bool backoff)
+static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error,
+ bool backoff)
{
- struct amdgpu_fpriv *fpriv = parser->filp->driver_priv;
unsigned i;
- if (!error) {
- amdgpu_vm_move_pt_bos_in_lru(parser->adev, &fpriv->vm);
-
+ if (!error)
ttm_eu_fence_buffer_objects(&parser->ticket,
&parser->validated,
parser->fence);
- } else if (backoff) {
+ else if (backoff)
ttm_eu_backoff_reservation(&parser->ticket,
&parser->validated);
- }
for (i = 0; i < parser->num_post_dep_syncobjs; i++)
drm_syncobj_put(parser->post_dep_syncobjs[i]);
@@ -737,7 +787,8 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p)
if (amdgpu_sriov_vf(adev)) {
struct dma_fence *f;
- bo_va = vm->csa_bo_va;
+
+ bo_va = fpriv->csa_va;
BUG_ON(!bo_va);
r = amdgpu_vm_bo_update(adev, bo_va, false);
if (r)
@@ -774,7 +825,7 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p)
}
- r = amdgpu_vm_clear_invalids(adev, vm, &p->job->sync);
+ r = amdgpu_vm_clear_moved(adev, vm, &p->job->sync);
if (amdgpu_vm_debug && p->bo_list) {
/* Invalidate all BOs to test for userspace bugs */
@@ -984,7 +1035,7 @@ static int amdgpu_syncobj_lookup_and_add_to_sync(struct amdgpu_cs_parser *p,
{
int r;
struct dma_fence *fence;
- r = drm_syncobj_fence_get(p->filp, handle, &fence);
+ r = drm_syncobj_find_fence(p->filp, handle, &fence);
if (r)
return r;
@@ -1383,7 +1434,7 @@ int amdgpu_cs_wait_fences_ioctl(struct drm_device *dev, void *data,
if (fences == NULL)
return -ENOMEM;
- fences_user = (void __user *)(uintptr_t)(wait->in.fences);
+ fences_user = u64_to_user_ptr(wait->in.fences);
if (copy_from_user(fences, fences_user,
sizeof(struct drm_amdgpu_fence) * fence_count)) {
r = -EFAULT;
@@ -1436,7 +1487,7 @@ amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
addr > mapping->last)
continue;
- *bo = lobj->bo_va->bo;
+ *bo = lobj->bo_va->base.bo;
return mapping;
}
@@ -1445,7 +1496,7 @@ amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
addr > mapping->last)
continue;
- *bo = lobj->bo_va->bo;
+ *bo = lobj->bo_va->base.bo;
return mapping;
}
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 4a8fc15..1a459ac 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -53,6 +53,9 @@
#include "bif/bif_4_1_d.h"
#include <linux/pci.h>
#include <linux/firmware.h>
+#include "amdgpu_vf_error.h"
+
+#include "amdgpu_amdkfd.h"
MODULE_FIRMWARE("amdgpu/vega10_gpu_info.bin");
MODULE_FIRMWARE("amdgpu/raven_gpu_info.bin");
@@ -128,6 +131,10 @@ void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
{
trace_amdgpu_mm_wreg(adev->pdev->device, reg, v);
+ if (adev->asic_type >= CHIP_VEGA10 && reg == 0) {
+ adev->last_mm_index = v;
+ }
+
if (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev)) {
BUG_ON(in_interrupt());
return amdgpu_virt_kiq_wreg(adev, reg, v);
@@ -143,6 +150,10 @@ void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
writel(v, ((void __iomem *)adev->rmmio) + (mmMM_DATA * 4));
spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
}
+
+ if (adev->asic_type >= CHIP_VEGA10 && reg == 1 && adev->last_mm_index == 0x5702C) {
+ udelay(500);
+ }
}
u32 amdgpu_io_rreg(struct amdgpu_device *adev, u32 reg)
@@ -157,6 +168,9 @@ u32 amdgpu_io_rreg(struct amdgpu_device *adev, u32 reg)
void amdgpu_io_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
{
+ if (adev->asic_type >= CHIP_VEGA10 && reg == 0) {
+ adev->last_mm_index = v;
+ }
if ((reg * 4) < adev->rio_mem_size)
iowrite32(v, adev->rio_mem + (reg * 4));
@@ -164,6 +178,10 @@ void amdgpu_io_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
iowrite32((reg * 4), adev->rio_mem + (mmMM_INDEX * 4));
iowrite32(v, adev->rio_mem + (mmMM_DATA * 4));
}
+
+ if (adev->asic_type >= CHIP_VEGA10 && reg == 1 && adev->last_mm_index == 0x5702C) {
+ udelay(500);
+ }
}
/**
@@ -318,51 +336,16 @@ static void amdgpu_block_invalid_wreg(struct amdgpu_device *adev,
static int amdgpu_vram_scratch_init(struct amdgpu_device *adev)
{
- int r;
-
- if (adev->vram_scratch.robj == NULL) {
- r = amdgpu_bo_create(adev, AMDGPU_GPU_PAGE_SIZE,
- PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
- AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL, &adev->vram_scratch.robj);
- if (r) {
- return r;
- }
- }
-
- r = amdgpu_bo_reserve(adev->vram_scratch.robj, false);
- if (unlikely(r != 0))
- return r;
- r = amdgpu_bo_pin(adev->vram_scratch.robj,
- AMDGPU_GEM_DOMAIN_VRAM, &adev->vram_scratch.gpu_addr);
- if (r) {
- amdgpu_bo_unreserve(adev->vram_scratch.robj);
- return r;
- }
- r = amdgpu_bo_kmap(adev->vram_scratch.robj,
- (void **)&adev->vram_scratch.ptr);
- if (r)
- amdgpu_bo_unpin(adev->vram_scratch.robj);
- amdgpu_bo_unreserve(adev->vram_scratch.robj);
-
- return r;
+ return amdgpu_bo_create_kernel(adev, AMDGPU_GPU_PAGE_SIZE,
+ PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
+ &adev->vram_scratch.robj,
+ &adev->vram_scratch.gpu_addr,
+ (void **)&adev->vram_scratch.ptr);
}
static void amdgpu_vram_scratch_fini(struct amdgpu_device *adev)
{
- int r;
-
- if (adev->vram_scratch.robj == NULL) {
- return;
- }
- r = amdgpu_bo_reserve(adev->vram_scratch.robj, true);
- if (likely(r == 0)) {
- amdgpu_bo_kunmap(adev->vram_scratch.robj);
- amdgpu_bo_unpin(adev->vram_scratch.robj);
- amdgpu_bo_unreserve(adev->vram_scratch.robj);
- }
- amdgpu_bo_unref(&adev->vram_scratch.robj);
+ amdgpu_bo_free_kernel(&adev->vram_scratch.robj, NULL, NULL);
}
/**
@@ -521,7 +504,8 @@ static int amdgpu_wb_init(struct amdgpu_device *adev)
int r;
if (adev->wb.wb_obj == NULL) {
- r = amdgpu_bo_create_kernel(adev, AMDGPU_MAX_WB * sizeof(uint32_t),
+ /* AMDGPU_MAX_WB * sizeof(uint32_t) * 8 = AMDGPU_MAX_WB 256bit slots */
+ r = amdgpu_bo_create_kernel(adev, AMDGPU_MAX_WB * sizeof(uint32_t) * 8,
PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT,
&adev->wb.wb_obj, &adev->wb.gpu_addr,
(void **)&adev->wb.wb);
@@ -552,32 +536,10 @@ static int amdgpu_wb_init(struct amdgpu_device *adev)
int amdgpu_wb_get(struct amdgpu_device *adev, u32 *wb)
{
unsigned long offset = find_first_zero_bit(adev->wb.used, adev->wb.num_wb);
- if (offset < adev->wb.num_wb) {
- __set_bit(offset, adev->wb.used);
- *wb = offset;
- return 0;
- } else {
- return -EINVAL;
- }
-}
-/**
- * amdgpu_wb_get_64bit - Allocate a wb entry
- *
- * @adev: amdgpu_device pointer
- * @wb: wb index
- *
- * Allocate a wb slot for use by the driver (all asics).
- * Returns 0 on success or -EINVAL on failure.
- */
-int amdgpu_wb_get_64bit(struct amdgpu_device *adev, u32 *wb)
-{
- unsigned long offset = bitmap_find_next_zero_area_off(adev->wb.used,
- adev->wb.num_wb, 0, 2, 7, 0);
- if ((offset + 1) < adev->wb.num_wb) {
+ if (offset < adev->wb.num_wb) {
__set_bit(offset, adev->wb.used);
- __set_bit(offset + 1, adev->wb.used);
- *wb = offset;
+ *wb = offset * 8; /* convert to dw offset */
return 0;
} else {
return -EINVAL;
@@ -599,22 +561,6 @@ void amdgpu_wb_free(struct amdgpu_device *adev, u32 wb)
}
/**
- * amdgpu_wb_free_64bit - Free a wb entry
- *
- * @adev: amdgpu_device pointer
- * @wb: wb index
- *
- * Free a wb slot allocated for use by the driver (all asics)
- */
-void amdgpu_wb_free_64bit(struct amdgpu_device *adev, u32 wb)
-{
- if ((wb + 1) < adev->wb.num_wb) {
- __clear_bit(wb, adev->wb.used);
- __clear_bit(wb + 1, adev->wb.used);
- }
-}
-
-/**
* amdgpu_vram_location - try to find VRAM location
* @adev: amdgpu device structure holding all necessary informations
* @mc: memory controller structure holding memory informations
@@ -665,7 +611,7 @@ void amdgpu_vram_location(struct amdgpu_device *adev, struct amdgpu_mc *mc, u64
}
/**
- * amdgpu_gtt_location - try to find GTT location
+ * amdgpu_gart_location - try to find GTT location
* @adev: amdgpu device structure holding all necessary informations
* @mc: memory controller structure holding memory informations
*
@@ -676,28 +622,28 @@ void amdgpu_vram_location(struct amdgpu_device *adev, struct amdgpu_mc *mc, u64
*
* FIXME: when reducing GTT size align new size on power of 2.
*/
-void amdgpu_gtt_location(struct amdgpu_device *adev, struct amdgpu_mc *mc)
+void amdgpu_gart_location(struct amdgpu_device *adev, struct amdgpu_mc *mc)
{
u64 size_af, size_bf;
- size_af = ((adev->mc.mc_mask - mc->vram_end) + mc->gtt_base_align) & ~mc->gtt_base_align;
- size_bf = mc->vram_start & ~mc->gtt_base_align;
+ size_af = adev->mc.mc_mask - mc->vram_end;
+ size_bf = mc->vram_start;
if (size_bf > size_af) {
- if (mc->gtt_size > size_bf) {
+ if (mc->gart_size > size_bf) {
dev_warn(adev->dev, "limiting GTT\n");
- mc->gtt_size = size_bf;
+ mc->gart_size = size_bf;
}
- mc->gtt_start = 0;
+ mc->gart_start = 0;
} else {
- if (mc->gtt_size > size_af) {
+ if (mc->gart_size > size_af) {
dev_warn(adev->dev, "limiting GTT\n");
- mc->gtt_size = size_af;
+ mc->gart_size = size_af;
}
- mc->gtt_start = (mc->vram_end + 1 + mc->gtt_base_align) & ~mc->gtt_base_align;
+ mc->gart_start = mc->vram_end + 1;
}
- mc->gtt_end = mc->gtt_start + mc->gtt_size - 1;
+ mc->gart_end = mc->gart_start + mc->gart_size - 1;
dev_info(adev->dev, "GTT: %lluM 0x%016llX - 0x%016llX\n",
- mc->gtt_size >> 20, mc->gtt_start, mc->gtt_end);
+ mc->gart_size >> 20, mc->gart_start, mc->gart_end);
}
/*
@@ -720,7 +666,12 @@ bool amdgpu_need_post(struct amdgpu_device *adev)
adev->has_hw_reset = false;
return true;
}
- /* then check MEM_SIZE, in case the crtcs are off */
+
+ /* bios scratch used on CIK+ */
+ if (adev->asic_type >= CHIP_BONAIRE)
+ return amdgpu_atombios_scratch_need_asic_init(adev);
+
+ /* check MEM_SIZE for older asics */
reg = amdgpu_asic_get_config_memsize(adev);
if ((reg != 0) && (reg != 0xffffffff))
@@ -1031,19 +982,6 @@ static unsigned int amdgpu_vga_set_decode(void *cookie, bool state)
return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
}
-/**
- * amdgpu_check_pot_argument - check that argument is a power of two
- *
- * @arg: value to check
- *
- * Validates that a certain argument is a power of two (all asics).
- * Returns true if argument is valid.
- */
-static bool amdgpu_check_pot_argument(int arg)
-{
- return (arg & (arg - 1)) == 0;
-}
-
static void amdgpu_check_block_size(struct amdgpu_device *adev)
{
/* defines number of bits in page table versus page directory,
@@ -1077,7 +1015,7 @@ static void amdgpu_check_vm_size(struct amdgpu_device *adev)
if (amdgpu_vm_size == -1)
return;
- if (!amdgpu_check_pot_argument(amdgpu_vm_size)) {
+ if (!is_power_of_2(amdgpu_vm_size)) {
dev_warn(adev->dev, "VM size (%d) must be a power of 2\n",
amdgpu_vm_size);
goto def_value;
@@ -1118,19 +1056,31 @@ static void amdgpu_check_arguments(struct amdgpu_device *adev)
dev_warn(adev->dev, "sched jobs (%d) must be at least 4\n",
amdgpu_sched_jobs);
amdgpu_sched_jobs = 4;
- } else if (!amdgpu_check_pot_argument(amdgpu_sched_jobs)){
+ } else if (!is_power_of_2(amdgpu_sched_jobs)){
dev_warn(adev->dev, "sched jobs (%d) must be a power of 2\n",
amdgpu_sched_jobs);
amdgpu_sched_jobs = roundup_pow_of_two(amdgpu_sched_jobs);
}
- if (amdgpu_gart_size != -1) {
+ if (amdgpu_gart_size < 32) {
+ /* gart size must be greater or equal to 32M */
+ dev_warn(adev->dev, "gart size (%d) too small\n",
+ amdgpu_gart_size);
+ amdgpu_gart_size = 32;
+ }
+
+ if (amdgpu_gtt_size != -1 && amdgpu_gtt_size < 32) {
/* gtt size must be greater or equal to 32M */
- if (amdgpu_gart_size < 32) {
- dev_warn(adev->dev, "gart size (%d) too small\n",
- amdgpu_gart_size);
- amdgpu_gart_size = -1;
- }
+ dev_warn(adev->dev, "gtt size (%d) too small\n",
+ amdgpu_gtt_size);
+ amdgpu_gtt_size = -1;
+ }
+
+ /* valid range is between 4 and 9 inclusive */
+ if (amdgpu_vm_fragment_size != -1 &&
+ (amdgpu_vm_fragment_size > 9 || amdgpu_vm_fragment_size < 4)) {
+ dev_warn(adev->dev, "valid range is between 4 and 9\n");
+ amdgpu_vm_fragment_size = -1;
}
amdgpu_check_vm_size(adev);
@@ -1138,7 +1088,7 @@ static void amdgpu_check_arguments(struct amdgpu_device *adev)
amdgpu_check_block_size(adev);
if (amdgpu_vram_page_split != -1 && (amdgpu_vram_page_split < 16 ||
- !amdgpu_check_pot_argument(amdgpu_vram_page_split))) {
+ !is_power_of_2(amdgpu_vram_page_split))) {
dev_warn(adev->dev, "invalid VRAM page split (%d)\n",
amdgpu_vram_page_split);
amdgpu_vram_page_split = 1024;
@@ -1901,7 +1851,8 @@ static int amdgpu_sriov_reinit_late(struct amdgpu_device *adev)
AMD_IP_BLOCK_TYPE_DCE,
AMD_IP_BLOCK_TYPE_GFX,
AMD_IP_BLOCK_TYPE_SDMA,
- AMD_IP_BLOCK_TYPE_VCE,
+ AMD_IP_BLOCK_TYPE_UVD,
+ AMD_IP_BLOCK_TYPE_VCE
};
for (i = 0; i < ARRAY_SIZE(ip_order); i++) {
@@ -2019,7 +1970,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
adev->flags = flags;
adev->asic_type = flags & AMD_ASIC_MASK;
adev->usec_timeout = AMDGPU_MAX_USEC_TIMEOUT;
- adev->mc.gtt_size = 512 * 1024 * 1024;
+ adev->mc.gart_size = 512 * 1024 * 1024;
adev->accel_working = false;
adev->num_rings = 0;
adev->mman.buffer_funcs = NULL;
@@ -2068,6 +2019,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
spin_lock_init(&adev->uvd_ctx_idx_lock);
spin_lock_init(&adev->didt_idx_lock);
spin_lock_init(&adev->gc_cac_idx_lock);
+ spin_lock_init(&adev->se_cac_idx_lock);
spin_lock_init(&adev->audio_endpt_idx_lock);
spin_lock_init(&adev->mm_stats.lock);
@@ -2143,6 +2095,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
r = amdgpu_atombios_init(adev);
if (r) {
dev_err(adev->dev, "amdgpu_atombios_init failed\n");
+ amdgpu_vf_error_put(AMDGIM_ERROR_VF_ATOMBIOS_INIT_FAIL, 0, 0);
goto failed;
}
@@ -2153,6 +2106,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
if (amdgpu_vpost_needed(adev)) {
if (!adev->bios) {
dev_err(adev->dev, "no vBIOS found\n");
+ amdgpu_vf_error_put(AMDGIM_ERROR_VF_NO_VBIOS, 0, 0);
r = -EINVAL;
goto failed;
}
@@ -2160,18 +2114,28 @@ int amdgpu_device_init(struct amdgpu_device *adev,
r = amdgpu_atom_asic_init(adev->mode_info.atom_context);
if (r) {
dev_err(adev->dev, "gpu post error!\n");
+ amdgpu_vf_error_put(AMDGIM_ERROR_VF_GPU_POST_ERROR, 0, 0);
goto failed;
}
} else {
DRM_INFO("GPU post is not needed\n");
}
- if (!adev->is_atom_fw) {
+ if (adev->is_atom_fw) {
+ /* Initialize clocks */
+ r = amdgpu_atomfirmware_get_clock_info(adev);
+ if (r) {
+ dev_err(adev->dev, "amdgpu_atomfirmware_get_clock_info failed\n");
+ amdgpu_vf_error_put(AMDGIM_ERROR_VF_ATOMBIOS_GET_CLOCK_FAIL, 0, 0);
+ goto failed;
+ }
+ } else {
/* Initialize clocks */
r = amdgpu_atombios_get_clock_info(adev);
if (r) {
dev_err(adev->dev, "amdgpu_atombios_get_clock_info failed\n");
- return r;
+ amdgpu_vf_error_put(AMDGIM_ERROR_VF_ATOMBIOS_GET_CLOCK_FAIL, 0, 0);
+ goto failed;
}
/* init i2c buses */
amdgpu_atombios_i2c_init(adev);
@@ -2181,6 +2145,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
r = amdgpu_fence_driver_init(adev);
if (r) {
dev_err(adev->dev, "amdgpu_fence_driver_init failed\n");
+ amdgpu_vf_error_put(AMDGIM_ERROR_VF_FENCE_INIT_FAIL, 0, 0);
goto failed;
}
@@ -2190,6 +2155,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
r = amdgpu_init(adev);
if (r) {
dev_err(adev->dev, "amdgpu_init failed\n");
+ amdgpu_vf_error_put(AMDGIM_ERROR_VF_AMDGPU_INIT_FAIL, 0, 0);
amdgpu_fini(adev);
goto failed;
}
@@ -2209,6 +2175,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
r = amdgpu_ib_pool_init(adev);
if (r) {
dev_err(adev->dev, "IB initialization failed (%d).\n", r);
+ amdgpu_vf_error_put(AMDGIM_ERROR_VF_IB_INIT_FAIL, 0, r);
goto failed;
}
@@ -2253,12 +2220,14 @@ int amdgpu_device_init(struct amdgpu_device *adev,
r = amdgpu_late_init(adev);
if (r) {
dev_err(adev->dev, "amdgpu_late_init failed\n");
+ amdgpu_vf_error_put(AMDGIM_ERROR_VF_AMDGPU_LATE_INIT_FAIL, 0, r);
goto failed;
}
return 0;
failed:
+ amdgpu_vf_error_trans_all(adev);
if (runtime)
vga_switcheroo_fini_domain_pm_ops(adev->dev);
return r;
@@ -2351,6 +2320,8 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon)
}
drm_modeset_unlock_all(dev);
+ amdgpu_amdkfd_suspend(adev);
+
/* unpin the front buffers and cursors */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
@@ -2392,10 +2363,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon)
*/
amdgpu_bo_evict_vram(adev);
- if (adev->is_atom_fw)
- amdgpu_atomfirmware_scratch_regs_save(adev);
- else
- amdgpu_atombios_scratch_regs_save(adev);
+ amdgpu_atombios_scratch_regs_save(adev);
pci_save_state(dev->pdev);
if (suspend) {
/* Shut down the device */
@@ -2444,10 +2412,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon)
if (r)
goto unlock;
}
- if (adev->is_atom_fw)
- amdgpu_atomfirmware_scratch_regs_restore(adev);
- else
- amdgpu_atombios_scratch_regs_restore(adev);
+ amdgpu_atombios_scratch_regs_restore(adev);
/* post card */
if (amdgpu_need_post(adev)) {
@@ -2490,6 +2455,9 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon)
}
}
}
+ r = amdgpu_amdkfd_resume(adev);
+ if (r)
+ return r;
/* blat the mode back in */
if (fbcon) {
@@ -2860,21 +2828,9 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev)
r = amdgpu_suspend(adev);
retry:
- /* Disable fb access */
- if (adev->mode_info.num_crtc) {
- struct amdgpu_mode_mc_save save;
- amdgpu_display_stop_mc_access(adev, &save);
- amdgpu_wait_for_idle(adev, AMD_IP_BLOCK_TYPE_GMC);
- }
- if (adev->is_atom_fw)
- amdgpu_atomfirmware_scratch_regs_save(adev);
- else
- amdgpu_atombios_scratch_regs_save(adev);
+ amdgpu_atombios_scratch_regs_save(adev);
r = amdgpu_asic_reset(adev);
- if (adev->is_atom_fw)
- amdgpu_atomfirmware_scratch_regs_restore(adev);
- else
- amdgpu_atombios_scratch_regs_restore(adev);
+ amdgpu_atombios_scratch_regs_restore(adev);
/* post card */
amdgpu_atom_asic_init(adev->mode_info.atom_context);
@@ -2952,6 +2908,7 @@ out:
}
} else {
dev_err(adev->dev, "asic resume failed (%d).\n", r);
+ amdgpu_vf_error_put(AMDGIM_ERROR_VF_ASIC_RESUME_FAIL, 0, r);
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
if (adev->rings[i] && adev->rings[i]->sched.thread) {
kthread_unpark(adev->rings[i]->sched.thread);
@@ -2962,12 +2919,16 @@ out:
drm_helper_resume_force_mode(adev->ddev);
ttm_bo_unlock_delayed_workqueue(&adev->mman.bdev, resched);
- if (r)
+ if (r) {
/* bad news, how to tell it to userspace ? */
dev_info(adev->dev, "GPU reset failed\n");
- else
+ amdgpu_vf_error_put(AMDGIM_ERROR_VF_GPU_RESET_FAIL, 0, r);
+ }
+ else {
dev_info(adev->dev, "GPU reset successed!\n");
+ }
+ amdgpu_vf_error_trans_all(adev);
return r;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index cdf2ab2..6ad2432 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -482,7 +482,7 @@ static void amdgpu_user_framebuffer_destroy(struct drm_framebuffer *fb)
{
struct amdgpu_framebuffer *amdgpu_fb = to_amdgpu_framebuffer(fb);
- drm_gem_object_unreference_unlocked(amdgpu_fb->obj);
+ drm_gem_object_put_unlocked(amdgpu_fb->obj);
drm_framebuffer_cleanup(fb);
kfree(amdgpu_fb);
}
@@ -542,14 +542,14 @@ amdgpu_user_framebuffer_create(struct drm_device *dev,
amdgpu_fb = kzalloc(sizeof(*amdgpu_fb), GFP_KERNEL);
if (amdgpu_fb == NULL) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ERR_PTR(-ENOMEM);
}
ret = amdgpu_framebuffer_init(dev, amdgpu_fb, mode_cmd, obj);
if (ret) {
kfree(amdgpu_fb);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ERR_PTR(ret);
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index b59f37c..e39ec98 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -68,13 +68,16 @@
* - 3.16.0 - Add reserved vmid support
* - 3.17.0 - Add AMDGPU_NUM_VRAM_CPU_PAGE_FAULTS.
* - 3.18.0 - Export gpu always on cu bitmap
+ * - 3.19.0 - Add support for UVD MJPEG decode
*/
#define KMS_DRIVER_MAJOR 3
-#define KMS_DRIVER_MINOR 18
+#define KMS_DRIVER_MINOR 19
#define KMS_DRIVER_PATCHLEVEL 0
int amdgpu_vram_limit = 0;
-int amdgpu_gart_size = -1; /* auto */
+int amdgpu_vis_vram_limit = 0;
+unsigned amdgpu_gart_size = 256;
+int amdgpu_gtt_size = -1; /* auto */
int amdgpu_moverate = -1; /* auto */
int amdgpu_benchmarking = 0;
int amdgpu_testing = 0;
@@ -92,6 +95,7 @@ unsigned amdgpu_ip_block_mask = 0xffffffff;
int amdgpu_bapm = -1;
int amdgpu_deep_color = 0;
int amdgpu_vm_size = -1;
+int amdgpu_vm_fragment_size = -1;
int amdgpu_vm_block_size = -1;
int amdgpu_vm_fault_stop = 0;
int amdgpu_vm_debug = 0;
@@ -106,6 +110,7 @@ unsigned amdgpu_pcie_gen_cap = 0;
unsigned amdgpu_pcie_lane_cap = 0;
unsigned amdgpu_cg_mask = 0xffffffff;
unsigned amdgpu_pg_mask = 0xffffffff;
+unsigned amdgpu_sdma_phase_quantum = 32;
char *amdgpu_disable_cu = NULL;
char *amdgpu_virtual_display = NULL;
unsigned amdgpu_pp_feature_mask = 0xffffffff;
@@ -120,8 +125,14 @@ int amdgpu_lbpw = -1;
MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing, in megabytes");
module_param_named(vramlimit, amdgpu_vram_limit, int, 0600);
-MODULE_PARM_DESC(gartsize, "Size of PCIE/IGP gart to setup in megabytes (32, 64, etc., -1 = auto)");
-module_param_named(gartsize, amdgpu_gart_size, int, 0600);
+MODULE_PARM_DESC(vis_vramlimit, "Restrict visible VRAM for testing, in megabytes");
+module_param_named(vis_vramlimit, amdgpu_vis_vram_limit, int, 0444);
+
+MODULE_PARM_DESC(gartsize, "Size of PCIE/IGP gart to setup in megabytes (32, 64, etc.)");
+module_param_named(gartsize, amdgpu_gart_size, uint, 0600);
+
+MODULE_PARM_DESC(gttsize, "Size of the GTT domain in megabytes (-1 = auto)");
+module_param_named(gttsize, amdgpu_gtt_size, int, 0600);
MODULE_PARM_DESC(moverate, "Maximum buffer migration rate in MB/s. (32, 64, etc., -1=auto, 0=1=disabled)");
module_param_named(moverate, amdgpu_moverate, int, 0600);
@@ -174,6 +185,9 @@ module_param_named(deep_color, amdgpu_deep_color, int, 0444);
MODULE_PARM_DESC(vm_size, "VM address space size in gigabytes (default 64GB)");
module_param_named(vm_size, amdgpu_vm_size, int, 0444);
+MODULE_PARM_DESC(vm_fragment_size, "VM fragment size in bits (4, 5, etc. 4 = 64K (default), Max 9 = 2M)");
+module_param_named(vm_fragment_size, amdgpu_vm_fragment_size, int, 0444);
+
MODULE_PARM_DESC(vm_block_size, "VM page table size in bits (default depending on vm_size)");
module_param_named(vm_block_size, amdgpu_vm_block_size, int, 0444);
@@ -186,7 +200,7 @@ module_param_named(vm_debug, amdgpu_vm_debug, int, 0644);
MODULE_PARM_DESC(vm_update_mode, "VM update using CPU (0 = never (default except for large BAR(LB)), 1 = Graphics only, 2 = Compute only (default for LB), 3 = Both");
module_param_named(vm_update_mode, amdgpu_vm_update_mode, int, 0444);
-MODULE_PARM_DESC(vram_page_split, "Number of pages after we split VRAM allocations (default 1024, -1 = disable)");
+MODULE_PARM_DESC(vram_page_split, "Number of pages after we split VRAM allocations (default 512, -1 = disable)");
module_param_named(vram_page_split, amdgpu_vram_page_split, int, 0444);
MODULE_PARM_DESC(exp_hw_support, "experimental hw support (1 = enable, 0 = disable (default))");
@@ -199,7 +213,7 @@ MODULE_PARM_DESC(sched_hw_submission, "the max number of HW submissions (default
module_param_named(sched_hw_submission, amdgpu_sched_hw_submission, int, 0444);
MODULE_PARM_DESC(ppfeaturemask, "all power features enabled (default))");
-module_param_named(ppfeaturemask, amdgpu_pp_feature_mask, int, 0444);
+module_param_named(ppfeaturemask, amdgpu_pp_feature_mask, uint, 0444);
MODULE_PARM_DESC(no_evict, "Support pinning request from user space (1 = enable, 0 = disable (default))");
module_param_named(no_evict, amdgpu_no_evict, int, 0444);
@@ -219,6 +233,9 @@ module_param_named(cg_mask, amdgpu_cg_mask, uint, 0444);
MODULE_PARM_DESC(pg_mask, "Powergating flags mask (0 = disable power gating)");
module_param_named(pg_mask, amdgpu_pg_mask, uint, 0444);
+MODULE_PARM_DESC(sdma_phase_quantum, "SDMA context switch phase quantum (x 1K GPU clock cycles, 0 = no change (default 32))");
+module_param_named(sdma_phase_quantum, amdgpu_sdma_phase_quantum, uint, 0444);
+
MODULE_PARM_DESC(disable_cu, "Disable CUs (se.sh.cu,...)");
module_param_named(disable_cu, amdgpu_disable_cu, charp, 0444);
@@ -803,7 +820,6 @@ static struct drm_driver kms_driver = {
.open = amdgpu_driver_open_kms,
.postclose = amdgpu_driver_postclose_kms,
.lastclose = amdgpu_driver_lastclose_kms,
- .set_busid = drm_pci_set_busid,
.unload = amdgpu_driver_unload_kms,
.get_vblank_counter = amdgpu_get_vblank_counter_kms,
.enable_vblank = amdgpu_enable_vblank_kms,
@@ -823,7 +839,6 @@ static struct drm_driver kms_driver = {
.gem_close_object = amdgpu_gem_object_close,
.dumb_create = amdgpu_mode_dumb_create,
.dumb_map_offset = amdgpu_mode_dumb_mmap,
- .dumb_destroy = drm_gem_dumb_destroy,
.fops = &amdgpu_driver_kms_fops,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
index c0d8c6f..9afa9c0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
@@ -118,7 +118,7 @@ static void amdgpufb_destroy_pinned_object(struct drm_gem_object *gobj)
amdgpu_bo_unpin(abo);
amdgpu_bo_unreserve(abo);
}
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
}
static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev,
@@ -245,13 +245,12 @@ static int amdgpufb_create(struct drm_fb_helper *helper,
drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth);
- info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
info->fbops = &amdgpufb_ops;
tmp = amdgpu_bo_gpu_offset(abo) - adev->mc.vram_start;
info->fix.smem_start = adev->mc.aper_base + tmp;
info->fix.smem_len = amdgpu_bo_size(abo);
- info->screen_base = abo->kptr;
+ info->screen_base = amdgpu_bo_kptr(abo);
info->screen_size = amdgpu_bo_size(abo);
drm_fb_helper_fill_var(info, &rfbdev->helper, sizes->fb_width, sizes->fb_height);
@@ -281,7 +280,7 @@ out:
}
if (fb && ret) {
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
drm_framebuffer_unregister_private(fb);
drm_framebuffer_cleanup(fb);
kfree(fb);
@@ -312,31 +311,7 @@ static int amdgpu_fbdev_destroy(struct drm_device *dev, struct amdgpu_fbdev *rfb
return 0;
}
-/** Sets the color ramps on behalf of fbcon */
-static void amdgpu_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno)
-{
- struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
-
- amdgpu_crtc->lut_r[regno] = red >> 6;
- amdgpu_crtc->lut_g[regno] = green >> 6;
- amdgpu_crtc->lut_b[regno] = blue >> 6;
-}
-
-/** Gets the color ramps on behalf of fbcon */
-static void amdgpu_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
- u16 *blue, int regno)
-{
- struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
-
- *red = amdgpu_crtc->lut_r[regno] << 6;
- *green = amdgpu_crtc->lut_g[regno] << 6;
- *blue = amdgpu_crtc->lut_b[regno] << 6;
-}
-
static const struct drm_fb_helper_funcs amdgpu_fb_helper_funcs = {
- .gamma_set = amdgpu_crtc_fb_gamma_set,
- .gamma_get = amdgpu_crtc_fb_gamma_get,
.fb_probe = amdgpufb_create,
};
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
index a57abc1..94c1e2e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
@@ -55,6 +55,19 @@
/*
* Common GART table functions.
*/
+
+/**
+ * amdgpu_gart_set_defaults - set the default gart_size
+ *
+ * @adev: amdgpu_device pointer
+ *
+ * Set the default gart_size based on parameters and available VRAM.
+ */
+void amdgpu_gart_set_defaults(struct amdgpu_device *adev)
+{
+ adev->mc.gart_size = (uint64_t)amdgpu_gart_size << 20;
+}
+
/**
* amdgpu_gart_table_ram_alloc - allocate system ram for gart page table
*
@@ -131,7 +144,7 @@ int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev)
PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM,
AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL, &adev->gart.robj);
+ NULL, NULL, 0, &adev->gart.robj);
if (r) {
return r;
}
@@ -263,6 +276,41 @@ int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
}
/**
+ * amdgpu_gart_map - map dma_addresses into GART entries
+ *
+ * @adev: amdgpu_device pointer
+ * @offset: offset into the GPU's gart aperture
+ * @pages: number of pages to bind
+ * @dma_addr: DMA addresses of pages
+ *
+ * Map the dma_addresses into GART entries (all asics).
+ * Returns 0 for success, -EINVAL for failure.
+ */
+int amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,
+ int pages, dma_addr_t *dma_addr, uint64_t flags,
+ void *dst)
+{
+ uint64_t page_base;
+ unsigned i, j, t;
+
+ if (!adev->gart.ready) {
+ WARN(1, "trying to bind memory to uninitialized GART !\n");
+ return -EINVAL;
+ }
+
+ t = offset / AMDGPU_GPU_PAGE_SIZE;
+
+ for (i = 0; i < pages; i++) {
+ page_base = dma_addr[i];
+ for (j = 0; j < (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE); j++, t++) {
+ amdgpu_gart_set_pte_pde(adev, dst, t, page_base, flags);
+ page_base += AMDGPU_GPU_PAGE_SIZE;
+ }
+ }
+ return 0;
+}
+
+/**
* amdgpu_gart_bind - bind pages into the gart page table
*
* @adev: amdgpu_device pointer
@@ -279,31 +327,30 @@ int amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset,
int pages, struct page **pagelist, dma_addr_t *dma_addr,
uint64_t flags)
{
- unsigned t;
- unsigned p;
- uint64_t page_base;
- int i, j;
+#ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
+ unsigned i,t,p;
+#endif
+ int r;
if (!adev->gart.ready) {
WARN(1, "trying to bind memory to uninitialized GART !\n");
return -EINVAL;
}
+#ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
t = offset / AMDGPU_GPU_PAGE_SIZE;
p = t / (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE);
-
- for (i = 0; i < pages; i++, p++) {
-#ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
+ for (i = 0; i < pages; i++, p++)
adev->gart.pages[p] = pagelist[i];
#endif
- if (adev->gart.ptr) {
- page_base = dma_addr[i];
- for (j = 0; j < (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE); j++, t++) {
- amdgpu_gart_set_pte_pde(adev, adev->gart.ptr, t, page_base, flags);
- page_base += AMDGPU_GPU_PAGE_SIZE;
- }
- }
+
+ if (adev->gart.ptr) {
+ r = amdgpu_gart_map(adev, offset, pages, dma_addr, flags,
+ adev->gart.ptr);
+ if (r)
+ return r;
}
+
mb();
amdgpu_gart_flush_gpu_tlb(adev, 0);
return 0;
@@ -333,8 +380,8 @@ int amdgpu_gart_init(struct amdgpu_device *adev)
if (r)
return r;
/* Compute table size */
- adev->gart.num_cpu_pages = adev->mc.gtt_size / PAGE_SIZE;
- adev->gart.num_gpu_pages = adev->mc.gtt_size / AMDGPU_GPU_PAGE_SIZE;
+ adev->gart.num_cpu_pages = adev->mc.gart_size / PAGE_SIZE;
+ adev->gart.num_gpu_pages = adev->mc.gart_size / AMDGPU_GPU_PAGE_SIZE;
DRM_INFO("GART: num cpu pages %u, num gpu pages %u\n",
adev->gart.num_cpu_pages, adev->gart.num_gpu_pages);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h
new file mode 100644
index 0000000..d4cce69
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __AMDGPU_GART_H__
+#define __AMDGPU_GART_H__
+
+#include <linux/types.h>
+
+/*
+ * GART structures, functions & helpers
+ */
+struct amdgpu_device;
+struct amdgpu_bo;
+struct amdgpu_gart_funcs;
+
+#define AMDGPU_GPU_PAGE_SIZE 4096
+#define AMDGPU_GPU_PAGE_MASK (AMDGPU_GPU_PAGE_SIZE - 1)
+#define AMDGPU_GPU_PAGE_SHIFT 12
+#define AMDGPU_GPU_PAGE_ALIGN(a) (((a) + AMDGPU_GPU_PAGE_MASK) & ~AMDGPU_GPU_PAGE_MASK)
+
+struct amdgpu_gart {
+ dma_addr_t table_addr;
+ struct amdgpu_bo *robj;
+ void *ptr;
+ unsigned num_gpu_pages;
+ unsigned num_cpu_pages;
+ unsigned table_size;
+#ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
+ struct page **pages;
+#endif
+ bool ready;
+
+ /* Asic default pte flags */
+ uint64_t gart_pte_flags;
+
+ const struct amdgpu_gart_funcs *gart_funcs;
+};
+
+void amdgpu_gart_set_defaults(struct amdgpu_device *adev);
+int amdgpu_gart_table_ram_alloc(struct amdgpu_device *adev);
+void amdgpu_gart_table_ram_free(struct amdgpu_device *adev);
+int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev);
+void amdgpu_gart_table_vram_free(struct amdgpu_device *adev);
+int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev);
+void amdgpu_gart_table_vram_unpin(struct amdgpu_device *adev);
+int amdgpu_gart_init(struct amdgpu_device *adev);
+void amdgpu_gart_fini(struct amdgpu_device *adev);
+int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
+ int pages);
+int amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,
+ int pages, dma_addr_t *dma_addr, uint64_t flags,
+ void *dst);
+int amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset,
+ int pages, struct page **pagelist,
+ dma_addr_t *dma_addr, uint64_t flags);
+
+#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index 621f739..7171968 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -49,7 +49,6 @@ int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
struct drm_gem_object **obj)
{
struct amdgpu_bo *robj;
- unsigned long max_size;
int r;
*obj = NULL;
@@ -58,20 +57,9 @@ int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
alignment = PAGE_SIZE;
}
- if (!(initial_domain & (AMDGPU_GEM_DOMAIN_GDS | AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA))) {
- /* Maximum bo size is the unpinned gtt size since we use the gtt to
- * handle vram to system pool migrations.
- */
- max_size = adev->mc.gtt_size - adev->gart_pin_size;
- if (size > max_size) {
- DRM_DEBUG("Allocation size %ldMb bigger than %ldMb limit\n",
- size >> 20, max_size >> 20);
- return -ENOMEM;
- }
- }
retry:
r = amdgpu_bo_create(adev, size, alignment, kernel, initial_domain,
- flags, NULL, NULL, &robj);
+ flags, NULL, NULL, 0, &robj);
if (r) {
if (r != -ERESTARTSYS) {
if (initial_domain == AMDGPU_GEM_DOMAIN_VRAM) {
@@ -103,7 +91,7 @@ void amdgpu_gem_force_release(struct amdgpu_device *adev)
spin_lock(&file->table_lock);
idr_for_each_entry(&file->object_idr, gobj, handle) {
WARN_ONCE(1, "And also active allocations!\n");
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
}
idr_destroy(&file->object_idr);
spin_unlock(&file->table_lock);
@@ -237,9 +225,7 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
if (args->in.domain_flags & ~(AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
AMDGPU_GEM_CREATE_CPU_GTT_USWC |
- AMDGPU_GEM_CREATE_VRAM_CLEARED|
- AMDGPU_GEM_CREATE_SHADOW |
- AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS))
+ AMDGPU_GEM_CREATE_VRAM_CLEARED))
return -EINVAL;
/* reject invalid gem domains */
@@ -275,7 +261,7 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
r = drm_gem_handle_create(filp, gobj, &handle);
/* drop reference from allocate - handle holds it now */
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
if (r)
return r;
@@ -318,7 +304,7 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
return r;
bo = gem_to_amdgpu_bo(gobj);
- bo->prefered_domains = AMDGPU_GEM_DOMAIN_GTT;
+ bo->preferred_domains = AMDGPU_GEM_DOMAIN_GTT;
bo->allowed_domains = AMDGPU_GEM_DOMAIN_GTT;
r = amdgpu_ttm_tt_set_userptr(bo->tbo.ttm, args->addr, args->flags);
if (r)
@@ -353,7 +339,7 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
r = drm_gem_handle_create(filp, gobj, &handle);
/* drop reference from allocate - handle holds it now */
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
if (r)
return r;
@@ -367,7 +353,7 @@ unlock_mmap_sem:
up_read(&current->mm->mmap_sem);
release_object:
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return r;
}
@@ -386,11 +372,11 @@ int amdgpu_mode_dumb_mmap(struct drm_file *filp,
robj = gem_to_amdgpu_bo(gobj);
if (amdgpu_ttm_tt_get_usermm(robj->tbo.ttm) ||
(robj->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)) {
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return -EPERM;
}
*offset_p = amdgpu_bo_mmap_offset(robj);
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return 0;
}
@@ -460,7 +446,7 @@ int amdgpu_gem_wait_idle_ioctl(struct drm_device *dev, void *data,
} else
r = ret;
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return r;
}
@@ -503,7 +489,7 @@ int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data,
unreserve:
amdgpu_bo_unreserve(robj);
out:
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return r;
}
@@ -635,7 +621,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
switch (args->operation) {
case AMDGPU_VA_OP_MAP:
- r = amdgpu_vm_alloc_pts(adev, bo_va->vm, args->va_address,
+ r = amdgpu_vm_alloc_pts(adev, bo_va->base.vm, args->va_address,
args->map_size);
if (r)
goto error_backoff;
@@ -655,7 +641,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
args->map_size);
break;
case AMDGPU_VA_OP_REPLACE:
- r = amdgpu_vm_alloc_pts(adev, bo_va->vm, args->va_address,
+ r = amdgpu_vm_alloc_pts(adev, bo_va->base.vm, args->va_address,
args->map_size);
if (r)
goto error_backoff;
@@ -676,7 +662,7 @@ error_backoff:
ttm_eu_backoff_reservation(&ticket, &list);
error_unref:
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return r;
}
@@ -701,11 +687,11 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,
switch (args->op) {
case AMDGPU_GEM_OP_GET_GEM_CREATE_INFO: {
struct drm_amdgpu_gem_create_in info;
- void __user *out = (void __user *)(uintptr_t)args->value;
+ void __user *out = u64_to_user_ptr(args->value);
info.bo_size = robj->gem_base.size;
info.alignment = robj->tbo.mem.page_alignment << PAGE_SHIFT;
- info.domains = robj->prefered_domains;
+ info.domains = robj->preferred_domains;
info.domain_flags = robj->flags;
amdgpu_bo_unreserve(robj);
if (copy_to_user(out, &info, sizeof(info)))
@@ -723,10 +709,10 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,
amdgpu_bo_unreserve(robj);
break;
}
- robj->prefered_domains = args->value & (AMDGPU_GEM_DOMAIN_VRAM |
+ robj->preferred_domains = args->value & (AMDGPU_GEM_DOMAIN_VRAM |
AMDGPU_GEM_DOMAIN_GTT |
AMDGPU_GEM_DOMAIN_CPU);
- robj->allowed_domains = robj->prefered_domains;
+ robj->allowed_domains = robj->preferred_domains;
if (robj->allowed_domains == AMDGPU_GEM_DOMAIN_VRAM)
robj->allowed_domains |= AMDGPU_GEM_DOMAIN_GTT;
@@ -738,7 +724,7 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,
}
out:
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return r;
}
@@ -766,7 +752,7 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv,
r = drm_gem_handle_create(file_priv, gobj, &handle);
/* drop reference from allocate - handle holds it now */
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
if (r) {
return r;
}
@@ -784,6 +770,7 @@ static int amdgpu_debugfs_gem_bo_info(int id, void *ptr, void *data)
unsigned domain;
const char *placement;
unsigned pin_count;
+ uint64_t offset;
domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type);
switch (domain) {
@@ -798,9 +785,12 @@ static int amdgpu_debugfs_gem_bo_info(int id, void *ptr, void *data)
placement = " CPU";
break;
}
- seq_printf(m, "\t0x%08x: %12ld byte %s @ 0x%010Lx",
- id, amdgpu_bo_size(bo), placement,
- amdgpu_bo_gpu_offset(bo));
+ seq_printf(m, "\t0x%08x: %12ld byte %s",
+ id, amdgpu_bo_size(bo), placement);
+
+ offset = ACCESS_ONCE(bo->tbo.mem.start);
+ if (offset != AMDGPU_BO_INVALID_OFFSET)
+ seq_printf(m, " @ 0x%010Lx", offset);
pin_count = ACCESS_ONCE(bo->pin_count);
if (pin_count)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
index e26108a..4f6c68f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
@@ -125,7 +125,8 @@ void amdgpu_gfx_compute_queue_acquire(struct amdgpu_device *adev)
if (mec >= adev->gfx.mec.num_mec)
break;
- if (adev->gfx.mec.num_mec > 1) {
+ /* FIXME: spreading the queues across pipes causes perf regressions */
+ if (0) {
/* policy: amdgpu owns the first two queues of the first MEC */
if (mec == 0 && queue < 2)
set_bit(i, adev->gfx.mec.queue_bitmap);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
index f7d22c4..9e05e25 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
@@ -28,7 +28,7 @@
struct amdgpu_gtt_mgr {
struct drm_mm mm;
spinlock_t lock;
- uint64_t available;
+ atomic64_t available;
};
/**
@@ -42,15 +42,19 @@ struct amdgpu_gtt_mgr {
static int amdgpu_gtt_mgr_init(struct ttm_mem_type_manager *man,
unsigned long p_size)
{
+ struct amdgpu_device *adev = amdgpu_ttm_adev(man->bdev);
struct amdgpu_gtt_mgr *mgr;
+ uint64_t start, size;
mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
if (!mgr)
return -ENOMEM;
- drm_mm_init(&mgr->mm, 0, p_size);
+ start = AMDGPU_GTT_MAX_TRANSFER_SIZE * AMDGPU_GTT_NUM_TRANSFER_WINDOWS;
+ size = (adev->mc.gart_size >> PAGE_SHIFT) - start;
+ drm_mm_init(&mgr->mm, start, size);
spin_lock_init(&mgr->lock);
- mgr->available = p_size;
+ atomic64_set(&mgr->available, p_size);
man->priv = mgr;
return 0;
}
@@ -81,6 +85,20 @@ static int amdgpu_gtt_mgr_fini(struct ttm_mem_type_manager *man)
}
/**
+ * amdgpu_gtt_mgr_is_allocated - Check if mem has address space
+ *
+ * @mem: the mem object to check
+ *
+ * Check if a mem object has already address space allocated.
+ */
+bool amdgpu_gtt_mgr_is_allocated(struct ttm_mem_reg *mem)
+{
+ struct drm_mm_node *node = mem->mm_node;
+
+ return (node->start != AMDGPU_BO_INVALID_OFFSET);
+}
+
+/**
* amdgpu_gtt_mgr_alloc - allocate new ranges
*
* @man: TTM memory type manager
@@ -95,13 +113,14 @@ int amdgpu_gtt_mgr_alloc(struct ttm_mem_type_manager *man,
const struct ttm_place *place,
struct ttm_mem_reg *mem)
{
+ struct amdgpu_device *adev = amdgpu_ttm_adev(man->bdev);
struct amdgpu_gtt_mgr *mgr = man->priv;
struct drm_mm_node *node = mem->mm_node;
enum drm_mm_insert_mode mode;
unsigned long fpfn, lpfn;
int r;
- if (node->start != AMDGPU_BO_INVALID_OFFSET)
+ if (amdgpu_gtt_mgr_is_allocated(mem))
return 0;
if (place)
@@ -112,7 +131,7 @@ int amdgpu_gtt_mgr_alloc(struct ttm_mem_type_manager *man,
if (place && place->lpfn)
lpfn = place->lpfn;
else
- lpfn = man->size;
+ lpfn = adev->gart.num_cpu_pages;
mode = DRM_MM_INSERT_BEST;
if (place && place->flags & TTM_PL_FLAG_TOPDOWN)
@@ -134,15 +153,6 @@ int amdgpu_gtt_mgr_alloc(struct ttm_mem_type_manager *man,
return r;
}
-void amdgpu_gtt_mgr_print(struct seq_file *m, struct ttm_mem_type_manager *man)
-{
- struct amdgpu_device *adev = amdgpu_ttm_adev(man->bdev);
- struct amdgpu_gtt_mgr *mgr = man->priv;
-
- seq_printf(m, "man size:%llu pages, gtt available:%llu pages, usage:%lluMB\n",
- man->size, mgr->available, (u64)atomic64_read(&adev->gtt_usage) >> 20);
-
-}
/**
* amdgpu_gtt_mgr_new - allocate a new node
*
@@ -163,11 +173,11 @@ static int amdgpu_gtt_mgr_new(struct ttm_mem_type_manager *man,
int r;
spin_lock(&mgr->lock);
- if (mgr->available < mem->num_pages) {
+ if (atomic64_read(&mgr->available) < mem->num_pages) {
spin_unlock(&mgr->lock);
return 0;
}
- mgr->available -= mem->num_pages;
+ atomic64_sub(mem->num_pages, &mgr->available);
spin_unlock(&mgr->lock);
node = kzalloc(sizeof(*node), GFP_KERNEL);
@@ -194,9 +204,7 @@ static int amdgpu_gtt_mgr_new(struct ttm_mem_type_manager *man,
return 0;
err_out:
- spin_lock(&mgr->lock);
- mgr->available += mem->num_pages;
- spin_unlock(&mgr->lock);
+ atomic64_add(mem->num_pages, &mgr->available);
return r;
}
@@ -223,30 +231,47 @@ static void amdgpu_gtt_mgr_del(struct ttm_mem_type_manager *man,
spin_lock(&mgr->lock);
if (node->start != AMDGPU_BO_INVALID_OFFSET)
drm_mm_remove_node(node);
- mgr->available += mem->num_pages;
spin_unlock(&mgr->lock);
+ atomic64_add(mem->num_pages, &mgr->available);
kfree(node);
mem->mm_node = NULL;
}
/**
+ * amdgpu_gtt_mgr_usage - return usage of GTT domain
+ *
+ * @man: TTM memory type manager
+ *
+ * Return how many bytes are used in the GTT domain
+ */
+uint64_t amdgpu_gtt_mgr_usage(struct ttm_mem_type_manager *man)
+{
+ struct amdgpu_gtt_mgr *mgr = man->priv;
+
+ return (u64)(man->size - atomic64_read(&mgr->available)) * PAGE_SIZE;
+}
+
+/**
* amdgpu_gtt_mgr_debug - dump VRAM table
*
* @man: TTM memory type manager
- * @prefix: text prefix
+ * @printer: DRM printer to use
*
* Dump the table content using printk.
*/
static void amdgpu_gtt_mgr_debug(struct ttm_mem_type_manager *man,
- const char *prefix)
+ struct drm_printer *printer)
{
struct amdgpu_gtt_mgr *mgr = man->priv;
- struct drm_printer p = drm_debug_printer(prefix);
spin_lock(&mgr->lock);
- drm_mm_print(&mgr->mm, &p);
+ drm_mm_print(&mgr->mm, printer);
spin_unlock(&mgr->lock);
+
+ drm_printf(printer, "man size:%llu pages, gtt available:%llu pages, usage:%lluMB\n",
+ man->size, (u64)atomic64_read(&mgr->available),
+ amdgpu_gtt_mgr_usage(man) >> 20);
}
const struct ttm_mem_type_manager_func amdgpu_gtt_mgr_func = {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
index f774b3f..659997b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
@@ -130,6 +130,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
unsigned i;
int r = 0;
+ bool need_pipe_sync = false;
if (num_ibs == 0)
return -EINVAL;
@@ -165,15 +166,15 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
if (ring->funcs->emit_pipeline_sync && job &&
((tmp = amdgpu_sync_get_fence(&job->sched_sync)) ||
amdgpu_vm_need_pipeline_sync(ring, job))) {
- amdgpu_ring_emit_pipeline_sync(ring);
+ need_pipe_sync = true;
dma_fence_put(tmp);
}
if (ring->funcs->insert_start)
ring->funcs->insert_start(ring);
- if (vm) {
- r = amdgpu_vm_flush(ring, job);
+ if (job) {
+ r = amdgpu_vm_flush(ring, job, need_pipe_sync);
if (r) {
amdgpu_ring_undo(ring);
return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
index 62da6c5..4bdd851 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
@@ -220,6 +220,10 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
int r = 0;
spin_lock_init(&adev->irq.lock);
+
+ /* Disable vblank irqs aggressively for power-saving */
+ adev->ddev->vblank_disable_immediate = true;
+
r = drm_vblank_init(adev->ddev, adev->mode_info.num_crtc);
if (r) {
return r;
@@ -263,7 +267,6 @@ void amdgpu_irq_fini(struct amdgpu_device *adev)
{
unsigned i, j;
- drm_vblank_cleanup(adev->ddev);
if (adev->irq.installed) {
drm_irq_uninstall(adev->ddev);
adev->irq.installed = false;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index 3d641e1..4510627 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -81,6 +81,8 @@ int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,
r = amdgpu_ib_get(adev, NULL, size, &(*job)->ibs[0]);
if (r)
kfree(*job);
+ else
+ (*job)->vm_pd_addr = adev->gart.table_addr;
return r;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index b0b2310..e162290 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -158,7 +158,6 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags)
"Error during ACPI methods call\n");
}
- amdgpu_amdkfd_load_interface(adev);
amdgpu_amdkfd_device_probe(adev);
amdgpu_amdkfd_device_init(adev);
@@ -456,13 +455,13 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
ui64 = atomic64_read(&adev->num_vram_cpu_page_faults);
return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
case AMDGPU_INFO_VRAM_USAGE:
- ui64 = atomic64_read(&adev->vram_usage);
+ ui64 = amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);
return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
case AMDGPU_INFO_VIS_VRAM_USAGE:
- ui64 = atomic64_read(&adev->vram_vis_usage);
+ ui64 = amdgpu_vram_mgr_vis_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);
return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
case AMDGPU_INFO_GTT_USAGE:
- ui64 = atomic64_read(&adev->gtt_usage);
+ ui64 = amdgpu_gtt_mgr_usage(&adev->mman.bdev.man[TTM_PL_TT]);
return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
case AMDGPU_INFO_GDS_CONFIG: {
struct drm_amdgpu_info_gds gds_info;
@@ -485,7 +484,8 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
vram_gtt.vram_size -= adev->vram_pin_size;
vram_gtt.vram_cpu_accessible_size = adev->mc.visible_vram_size;
vram_gtt.vram_cpu_accessible_size -= (adev->vram_pin_size - adev->invisible_pin_size);
- vram_gtt.gtt_size = adev->mc.gtt_size;
+ vram_gtt.gtt_size = adev->mman.bdev.man[TTM_PL_TT].size;
+ vram_gtt.gtt_size *= PAGE_SIZE;
vram_gtt.gtt_size -= adev->gart_pin_size;
return copy_to_user(out, &vram_gtt,
min((size_t)size, sizeof(vram_gtt))) ? -EFAULT : 0;
@@ -497,7 +497,8 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
mem.vram.total_heap_size = adev->mc.real_vram_size;
mem.vram.usable_heap_size =
adev->mc.real_vram_size - adev->vram_pin_size;
- mem.vram.heap_usage = atomic64_read(&adev->vram_usage);
+ mem.vram.heap_usage =
+ amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);
mem.vram.max_allocation = mem.vram.usable_heap_size * 3 / 4;
mem.cpu_accessible_vram.total_heap_size =
@@ -506,14 +507,16 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
adev->mc.visible_vram_size -
(adev->vram_pin_size - adev->invisible_pin_size);
mem.cpu_accessible_vram.heap_usage =
- atomic64_read(&adev->vram_vis_usage);
+ amdgpu_vram_mgr_vis_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);
mem.cpu_accessible_vram.max_allocation =
mem.cpu_accessible_vram.usable_heap_size * 3 / 4;
- mem.gtt.total_heap_size = adev->mc.gtt_size;
- mem.gtt.usable_heap_size =
- adev->mc.gtt_size - adev->gart_pin_size;
- mem.gtt.heap_usage = atomic64_read(&adev->gtt_usage);
+ mem.gtt.total_heap_size = adev->mman.bdev.man[TTM_PL_TT].size;
+ mem.gtt.total_heap_size *= PAGE_SIZE;
+ mem.gtt.usable_heap_size = mem.gtt.total_heap_size
+ - adev->gart_pin_size;
+ mem.gtt.heap_usage =
+ amdgpu_gtt_mgr_usage(&adev->mman.bdev.man[TTM_PL_TT]);
mem.gtt.max_allocation = mem.gtt.usable_heap_size * 3 / 4;
return copy_to_user(out, &mem,
@@ -571,8 +574,8 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
dev_info.max_engine_clock = amdgpu_dpm_get_sclk(adev, false) * 10;
dev_info.max_memory_clock = amdgpu_dpm_get_mclk(adev, false) * 10;
} else {
- dev_info.max_engine_clock = adev->pm.default_sclk * 10;
- dev_info.max_memory_clock = adev->pm.default_mclk * 10;
+ dev_info.max_engine_clock = adev->clock.default_sclk * 10;
+ dev_info.max_memory_clock = adev->clock.default_mclk * 10;
}
dev_info.enabled_rb_pipes_mask = adev->gfx.config.backend_enable_mask;
dev_info.num_rb_pipes = adev->gfx.config.max_backends_per_se *
@@ -587,10 +590,8 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
dev_info.virtual_address_offset = AMDGPU_VA_RESERVED_SIZE;
dev_info.virtual_address_max = (uint64_t)adev->vm_manager.max_pfn * AMDGPU_GPU_PAGE_SIZE;
dev_info.virtual_address_alignment = max((int)PAGE_SIZE, AMDGPU_GPU_PAGE_SIZE);
- dev_info.pte_fragment_size = (1 << AMDGPU_LOG2_PAGES_PER_FRAG) *
- AMDGPU_GPU_PAGE_SIZE;
+ dev_info.pte_fragment_size = (1 << adev->vm_manager.fragment_size) * AMDGPU_GPU_PAGE_SIZE;
dev_info.gart_page_size = AMDGPU_GPU_PAGE_SIZE;
-
dev_info.cu_active_number = adev->gfx.cu_info.number;
dev_info.cu_ao_mask = adev->gfx.cu_info.ao_cu_mask;
dev_info.ce_ram_size = adev->gfx.ce_ram_size;
@@ -839,7 +840,7 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
}
if (amdgpu_sriov_vf(adev)) {
- r = amdgpu_map_static_csa(adev, &fpriv->vm);
+ r = amdgpu_map_static_csa(adev, &fpriv->vm, &fpriv->csa_va);
if (r)
goto out_suspend;
}
@@ -892,8 +893,8 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
if (amdgpu_sriov_vf(adev)) {
/* TODO: how to handle reserve failure */
BUG_ON(amdgpu_bo_reserve(adev->virt.csa_obj, true));
- amdgpu_vm_bo_rmv(adev, fpriv->vm.csa_bo_va);
- fpriv->vm.csa_bo_va = NULL;
+ amdgpu_vm_bo_rmv(adev, fpriv->csa_va);
+ fpriv->csa_va = NULL;
amdgpu_bo_unreserve(adev->virt.csa_obj);
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
index 6558a3e..e1cde6b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
@@ -147,36 +147,6 @@ static void amdgpu_mn_invalidate_node(struct amdgpu_mn_node *node,
}
/**
- * amdgpu_mn_invalidate_page - callback to notify about mm change
- *
- * @mn: our notifier
- * @mn: the mm this callback is about
- * @address: address of invalidate page
- *
- * Invalidation of a single page. Blocks for all BOs mapping it
- * and unmap them by move them into system domain again.
- */
-static void amdgpu_mn_invalidate_page(struct mmu_notifier *mn,
- struct mm_struct *mm,
- unsigned long address)
-{
- struct amdgpu_mn *rmn = container_of(mn, struct amdgpu_mn, mn);
- struct interval_tree_node *it;
-
- mutex_lock(&rmn->lock);
-
- it = interval_tree_iter_first(&rmn->objects, address, address);
- if (it) {
- struct amdgpu_mn_node *node;
-
- node = container_of(it, struct amdgpu_mn_node, it);
- amdgpu_mn_invalidate_node(node, address, address);
- }
-
- mutex_unlock(&rmn->lock);
-}
-
-/**
* amdgpu_mn_invalidate_range_start - callback to notify about mm change
*
* @mn: our notifier
@@ -215,7 +185,6 @@ static void amdgpu_mn_invalidate_range_start(struct mmu_notifier *mn,
static const struct mmu_notifier_ops amdgpu_mn_ops = {
.release = amdgpu_mn_release,
- .invalidate_page = amdgpu_mn_invalidate_page,
.invalidate_range_start = amdgpu_mn_invalidate_range_start,
};
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 43a9d3a..2af2678 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -257,15 +257,7 @@ struct amdgpu_audio {
int num_pins;
};
-struct amdgpu_mode_mc_save {
- u32 vga_render_control;
- u32 vga_hdp_control;
- bool crtc_enabled[AMDGPU_MAX_CRTCS];
-};
-
struct amdgpu_display_funcs {
- /* vga render */
- void (*set_vga_render_state)(struct amdgpu_device *adev, bool render);
/* display watermarks */
void (*bandwidth_update)(struct amdgpu_device *adev);
/* get frame count */
@@ -300,10 +292,6 @@ struct amdgpu_display_funcs {
uint16_t connector_object_id,
struct amdgpu_hpd *hpd,
struct amdgpu_router *router);
- void (*stop_mc_access)(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save);
- void (*resume_mc_access)(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save);
};
struct amdgpu_mode_info {
@@ -369,7 +357,6 @@ struct amdgpu_atom_ss {
struct amdgpu_crtc {
struct drm_crtc base;
int crtc_id;
- u16 lut_r[256], lut_g[256], lut_b[256];
bool enabled;
bool can_tile;
uint32_t crtc_offset;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index 8ee6965..e7e8991 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -37,55 +37,6 @@
#include "amdgpu.h"
#include "amdgpu_trace.h"
-
-
-static u64 amdgpu_get_vis_part_size(struct amdgpu_device *adev,
- struct ttm_mem_reg *mem)
-{
- if (mem->start << PAGE_SHIFT >= adev->mc.visible_vram_size)
- return 0;
-
- return ((mem->start << PAGE_SHIFT) + mem->size) >
- adev->mc.visible_vram_size ?
- adev->mc.visible_vram_size - (mem->start << PAGE_SHIFT) :
- mem->size;
-}
-
-static void amdgpu_update_memory_usage(struct amdgpu_device *adev,
- struct ttm_mem_reg *old_mem,
- struct ttm_mem_reg *new_mem)
-{
- u64 vis_size;
- if (!adev)
- return;
-
- if (new_mem) {
- switch (new_mem->mem_type) {
- case TTM_PL_TT:
- atomic64_add(new_mem->size, &adev->gtt_usage);
- break;
- case TTM_PL_VRAM:
- atomic64_add(new_mem->size, &adev->vram_usage);
- vis_size = amdgpu_get_vis_part_size(adev, new_mem);
- atomic64_add(vis_size, &adev->vram_vis_usage);
- break;
- }
- }
-
- if (old_mem) {
- switch (old_mem->mem_type) {
- case TTM_PL_TT:
- atomic64_sub(old_mem->size, &adev->gtt_usage);
- break;
- case TTM_PL_VRAM:
- atomic64_sub(old_mem->size, &adev->vram_usage);
- vis_size = amdgpu_get_vis_part_size(adev, old_mem);
- atomic64_sub(vis_size, &adev->vram_vis_usage);
- break;
- }
- }
-}
-
static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo)
{
struct amdgpu_device *adev = amdgpu_ttm_adev(tbo->bdev);
@@ -93,7 +44,7 @@ static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo)
bo = container_of(tbo, struct amdgpu_bo, tbo);
- amdgpu_update_memory_usage(adev, &bo->tbo.mem, NULL);
+ amdgpu_bo_kunmap(bo);
drm_gem_object_release(&bo->gem_base);
amdgpu_bo_unref(&bo->parent);
@@ -219,7 +170,7 @@ static void amdgpu_fill_placement_to_bo(struct amdgpu_bo *bo,
}
/**
- * amdgpu_bo_create_kernel - create BO for kernel use
+ * amdgpu_bo_create_reserved - create reserved BO for kernel use
*
* @adev: amdgpu device object
* @size: size for the new BO
@@ -229,24 +180,30 @@ static void amdgpu_fill_placement_to_bo(struct amdgpu_bo *bo,
* @gpu_addr: GPU addr of the pinned BO
* @cpu_addr: optional CPU address mapping
*
- * Allocates and pins a BO for kernel internal use.
+ * Allocates and pins a BO for kernel internal use, and returns it still
+ * reserved.
*
* Returns 0 on success, negative error code otherwise.
*/
-int amdgpu_bo_create_kernel(struct amdgpu_device *adev,
- unsigned long size, int align,
- u32 domain, struct amdgpu_bo **bo_ptr,
- u64 *gpu_addr, void **cpu_addr)
+int amdgpu_bo_create_reserved(struct amdgpu_device *adev,
+ unsigned long size, int align,
+ u32 domain, struct amdgpu_bo **bo_ptr,
+ u64 *gpu_addr, void **cpu_addr)
{
+ bool free = false;
int r;
- r = amdgpu_bo_create(adev, size, align, true, domain,
- AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
- AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL, bo_ptr);
- if (r) {
- dev_err(adev->dev, "(%d) failed to allocate kernel bo\n", r);
- return r;
+ if (!*bo_ptr) {
+ r = amdgpu_bo_create(adev, size, align, true, domain,
+ AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
+ AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
+ NULL, NULL, 0, bo_ptr);
+ if (r) {
+ dev_err(adev->dev, "(%d) failed to allocate kernel bo\n",
+ r);
+ return r;
+ }
+ free = true;
}
r = amdgpu_bo_reserve(*bo_ptr, false);
@@ -269,20 +226,52 @@ int amdgpu_bo_create_kernel(struct amdgpu_device *adev,
}
}
- amdgpu_bo_unreserve(*bo_ptr);
-
return 0;
error_unreserve:
amdgpu_bo_unreserve(*bo_ptr);
error_free:
- amdgpu_bo_unref(bo_ptr);
+ if (free)
+ amdgpu_bo_unref(bo_ptr);
return r;
}
/**
+ * amdgpu_bo_create_kernel - create BO for kernel use
+ *
+ * @adev: amdgpu device object
+ * @size: size for the new BO
+ * @align: alignment for the new BO
+ * @domain: where to place it
+ * @bo_ptr: resulting BO
+ * @gpu_addr: GPU addr of the pinned BO
+ * @cpu_addr: optional CPU address mapping
+ *
+ * Allocates and pins a BO for kernel internal use.
+ *
+ * Returns 0 on success, negative error code otherwise.
+ */
+int amdgpu_bo_create_kernel(struct amdgpu_device *adev,
+ unsigned long size, int align,
+ u32 domain, struct amdgpu_bo **bo_ptr,
+ u64 *gpu_addr, void **cpu_addr)
+{
+ int r;
+
+ r = amdgpu_bo_create_reserved(adev, size, align, domain, bo_ptr,
+ gpu_addr, cpu_addr);
+
+ if (r)
+ return r;
+
+ amdgpu_bo_unreserve(*bo_ptr);
+
+ return 0;
+}
+
+/**
* amdgpu_bo_free_kernel - free BO for kernel use
*
* @bo: amdgpu BO to free
@@ -317,12 +306,13 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
struct sg_table *sg,
struct ttm_placement *placement,
struct reservation_object *resv,
+ uint64_t init_value,
struct amdgpu_bo **bo_ptr)
{
struct amdgpu_bo *bo;
enum ttm_bo_type type;
unsigned long page_align;
- u64 initial_bytes_moved;
+ u64 initial_bytes_moved, bytes_moved;
size_t acc_size;
int r;
@@ -351,13 +341,13 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
}
INIT_LIST_HEAD(&bo->shadow_list);
INIT_LIST_HEAD(&bo->va);
- bo->prefered_domains = domain & (AMDGPU_GEM_DOMAIN_VRAM |
+ bo->preferred_domains = domain & (AMDGPU_GEM_DOMAIN_VRAM |
AMDGPU_GEM_DOMAIN_GTT |
AMDGPU_GEM_DOMAIN_CPU |
AMDGPU_GEM_DOMAIN_GDS |
AMDGPU_GEM_DOMAIN_GWS |
AMDGPU_GEM_DOMAIN_OA);
- bo->allowed_domains = bo->prefered_domains;
+ bo->allowed_domains = bo->preferred_domains;
if (!kernel && bo->allowed_domains == AMDGPU_GEM_DOMAIN_VRAM)
bo->allowed_domains |= AMDGPU_GEM_DOMAIN_GTT;
@@ -398,8 +388,14 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
r = ttm_bo_init_reserved(&adev->mman.bdev, &bo->tbo, size, type,
&bo->placement, page_align, !kernel, NULL,
acc_size, sg, resv, &amdgpu_ttm_bo_destroy);
- amdgpu_cs_report_moved_bytes(adev,
- atomic64_read(&adev->num_bytes_moved) - initial_bytes_moved);
+ bytes_moved = atomic64_read(&adev->num_bytes_moved) -
+ initial_bytes_moved;
+ if (adev->mc.visible_vram_size < adev->mc.real_vram_size &&
+ bo->tbo.mem.mem_type == TTM_PL_VRAM &&
+ bo->tbo.mem.start < adev->mc.visible_vram_size >> PAGE_SHIFT)
+ amdgpu_cs_report_moved_bytes(adev, bytes_moved, bytes_moved);
+ else
+ amdgpu_cs_report_moved_bytes(adev, bytes_moved, 0);
if (unlikely(r != 0))
return r;
@@ -411,7 +407,7 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
bo->tbo.mem.placement & TTM_PL_FLAG_VRAM) {
struct dma_fence *fence;
- r = amdgpu_fill_buffer(bo, 0, bo->tbo.resv, &fence);
+ r = amdgpu_fill_buffer(bo, init_value, bo->tbo.resv, &fence);
if (unlikely(r))
goto fail_unreserve;
@@ -426,6 +422,10 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
trace_amdgpu_bo_create(bo);
+ /* Treat CPU_ACCESS_REQUIRED only as a hint if given by UMD */
+ if (type == ttm_bo_type_device)
+ bo->flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
+
return 0;
fail_unreserve:
@@ -459,6 +459,7 @@ static int amdgpu_bo_create_shadow(struct amdgpu_device *adev,
AMDGPU_GEM_CREATE_CPU_GTT_USWC,
NULL, &placement,
bo->tbo.resv,
+ 0,
&bo->shadow);
if (!r) {
bo->shadow->parent = amdgpu_bo_ref(bo);
@@ -470,11 +471,15 @@ static int amdgpu_bo_create_shadow(struct amdgpu_device *adev,
return r;
}
+/* init_value will only take effect when flags contains
+ * AMDGPU_GEM_CREATE_VRAM_CLEARED.
+ */
int amdgpu_bo_create(struct amdgpu_device *adev,
unsigned long size, int byte_align,
bool kernel, u32 domain, u64 flags,
struct sg_table *sg,
struct reservation_object *resv,
+ uint64_t init_value,
struct amdgpu_bo **bo_ptr)
{
struct ttm_placement placement = {0};
@@ -489,7 +494,7 @@ int amdgpu_bo_create(struct amdgpu_device *adev,
r = amdgpu_bo_create_restricted(adev, size, byte_align, kernel,
domain, flags, sg, &placement,
- resv, bo_ptr);
+ resv, init_value, bo_ptr);
if (r)
return r;
@@ -535,7 +540,7 @@ int amdgpu_bo_backup_to_shadow(struct amdgpu_device *adev,
r = amdgpu_copy_buffer(ring, bo_addr, shadow_addr,
amdgpu_bo_size(bo), resv, fence,
- direct);
+ direct, false);
if (!r)
amdgpu_bo_fence(bo, *fence, true);
@@ -551,7 +556,7 @@ int amdgpu_bo_validate(struct amdgpu_bo *bo)
if (bo->pin_count)
return 0;
- domain = bo->prefered_domains;
+ domain = bo->preferred_domains;
retry:
amdgpu_ttm_placement_from_domain(bo, domain);
@@ -588,7 +593,7 @@ int amdgpu_bo_restore_from_shadow(struct amdgpu_device *adev,
r = amdgpu_copy_buffer(ring, shadow_addr, bo_addr,
amdgpu_bo_size(bo), resv, fence,
- direct);
+ direct, false);
if (!r)
amdgpu_bo_fence(bo, *fence, true);
@@ -598,16 +603,16 @@ err:
int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr)
{
- bool is_iomem;
+ void *kptr;
long r;
if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)
return -EPERM;
- if (bo->kptr) {
- if (ptr) {
- *ptr = bo->kptr;
- }
+ kptr = amdgpu_bo_kptr(bo);
+ if (kptr) {
+ if (ptr)
+ *ptr = kptr;
return 0;
}
@@ -620,19 +625,23 @@ int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr)
if (r)
return r;
- bo->kptr = ttm_kmap_obj_virtual(&bo->kmap, &is_iomem);
if (ptr)
- *ptr = bo->kptr;
+ *ptr = amdgpu_bo_kptr(bo);
return 0;
}
+void *amdgpu_bo_kptr(struct amdgpu_bo *bo)
+{
+ bool is_iomem;
+
+ return ttm_kmap_obj_virtual(&bo->kmap, &is_iomem);
+}
+
void amdgpu_bo_kunmap(struct amdgpu_bo *bo)
{
- if (bo->kptr == NULL)
- return;
- bo->kptr = NULL;
- ttm_bo_kunmap(&bo->kmap);
+ if (bo->kmap.bo)
+ ttm_bo_kunmap(&bo->kmap);
}
struct amdgpu_bo *amdgpu_bo_ref(struct amdgpu_bo *bo)
@@ -724,15 +733,16 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,
dev_err(adev->dev, "%p pin failed\n", bo);
goto error;
}
- r = amdgpu_ttm_bind(&bo->tbo, &bo->tbo.mem);
- if (unlikely(r)) {
- dev_err(adev->dev, "%p bind failed\n", bo);
- goto error;
- }
bo->pin_count = 1;
- if (gpu_addr != NULL)
+ if (gpu_addr != NULL) {
+ r = amdgpu_ttm_bind(&bo->tbo, &bo->tbo.mem);
+ if (unlikely(r)) {
+ dev_err(adev->dev, "%p bind failed\n", bo);
+ goto error;
+ }
*gpu_addr = amdgpu_bo_gpu_offset(bo);
+ }
if (domain == AMDGPU_GEM_DOMAIN_VRAM) {
adev->vram_pin_size += amdgpu_bo_size(bo);
if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)
@@ -921,6 +931,8 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,
abo = container_of(bo, struct amdgpu_bo, tbo);
amdgpu_vm_bo_invalidate(adev, abo);
+ amdgpu_bo_kunmap(abo);
+
/* remember the eviction */
if (evict)
atomic64_inc(&adev->num_evictions);
@@ -930,8 +942,6 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,
return;
/* move_notify is called before move happens */
- amdgpu_update_memory_usage(adev, &bo->mem, new_mem);
-
trace_amdgpu_ttm_bo_move(abo, new_mem->mem_type, old_mem->mem_type);
}
@@ -939,19 +949,22 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
{
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
struct amdgpu_bo *abo;
- unsigned long offset, size, lpfn;
- int i, r;
+ unsigned long offset, size;
+ int r;
if (!amdgpu_ttm_bo_is_amdgpu_bo(bo))
return 0;
abo = container_of(bo, struct amdgpu_bo, tbo);
+
+ /* Remember that this BO was accessed by the CPU */
+ abo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
+
if (bo->mem.mem_type != TTM_PL_VRAM)
return 0;
size = bo->mem.num_pages << PAGE_SHIFT;
offset = bo->mem.start << PAGE_SHIFT;
- /* TODO: figure out how to map scattered VRAM to the CPU */
if ((offset + size) <= adev->mc.visible_vram_size)
return 0;
@@ -961,26 +974,21 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
/* hurrah the memory is not visible ! */
atomic64_inc(&adev->num_vram_cpu_page_faults);
- amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_VRAM);
- lpfn = adev->mc.visible_vram_size >> PAGE_SHIFT;
- for (i = 0; i < abo->placement.num_placement; i++) {
- /* Force into visible VRAM */
- if ((abo->placements[i].flags & TTM_PL_FLAG_VRAM) &&
- (!abo->placements[i].lpfn ||
- abo->placements[i].lpfn > lpfn))
- abo->placements[i].lpfn = lpfn;
- }
+ amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_VRAM |
+ AMDGPU_GEM_DOMAIN_GTT);
+
+ /* Avoid costly evictions; only set GTT as a busy placement */
+ abo->placement.num_busy_placement = 1;
+ abo->placement.busy_placement = &abo->placements[1];
+
r = ttm_bo_validate(bo, &abo->placement, false, false);
- if (unlikely(r == -ENOMEM)) {
- amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_GTT);
- return ttm_bo_validate(bo, &abo->placement, false, false);
- } else if (unlikely(r != 0)) {
+ if (unlikely(r != 0))
return r;
- }
offset = bo->mem.start << PAGE_SHIFT;
/* this should never happen */
- if ((offset + size) > adev->mc.visible_vram_size)
+ if (bo->mem.mem_type == TTM_PL_VRAM &&
+ (offset + size) > adev->mc.visible_vram_size)
return -EINVAL;
return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
index 3824851..a288fa6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
@@ -33,6 +33,61 @@
#define AMDGPU_BO_INVALID_OFFSET LONG_MAX
+/* bo virtual addresses in a vm */
+struct amdgpu_bo_va_mapping {
+ struct list_head list;
+ struct rb_node rb;
+ uint64_t start;
+ uint64_t last;
+ uint64_t __subtree_last;
+ uint64_t offset;
+ uint64_t flags;
+};
+
+/* User space allocated BO in a VM */
+struct amdgpu_bo_va {
+ struct amdgpu_vm_bo_base base;
+
+ /* protected by bo being reserved */
+ struct dma_fence *last_pt_update;
+ unsigned ref_count;
+
+ /* mappings for this bo_va */
+ struct list_head invalids;
+ struct list_head valids;
+};
+
+struct amdgpu_bo {
+ /* Protected by tbo.reserved */
+ u32 preferred_domains;
+ u32 allowed_domains;
+ struct ttm_place placements[AMDGPU_GEM_DOMAIN_MAX + 1];
+ struct ttm_placement placement;
+ struct ttm_buffer_object tbo;
+ struct ttm_bo_kmap_obj kmap;
+ u64 flags;
+ unsigned pin_count;
+ u64 tiling_flags;
+ u64 metadata_flags;
+ void *metadata;
+ u32 metadata_size;
+ unsigned prime_shared_count;
+ /* list of all virtual address to which this bo is associated to */
+ struct list_head va;
+ /* Constant after initialization */
+ struct drm_gem_object gem_base;
+ struct amdgpu_bo *parent;
+ struct amdgpu_bo *shadow;
+
+ struct ttm_bo_kmap_obj dma_buf_vmap;
+ struct amdgpu_mn *mn;
+
+ union {
+ struct list_head mn_list;
+ struct list_head shadow_list;
+ };
+};
+
/**
* amdgpu_mem_type_to_domain - return domain corresponding to mem_type
* @mem_type: ttm memory type
@@ -120,7 +175,11 @@ static inline u64 amdgpu_bo_mmap_offset(struct amdgpu_bo *bo)
*/
static inline bool amdgpu_bo_gpu_accessible(struct amdgpu_bo *bo)
{
- return bo->tbo.mem.mem_type != TTM_PL_SYSTEM;
+ switch (bo->tbo.mem.mem_type) {
+ case TTM_PL_TT: return amdgpu_ttm_is_bound(bo->tbo.ttm);
+ case TTM_PL_VRAM: return true;
+ default: return false;
+ }
}
int amdgpu_bo_create(struct amdgpu_device *adev,
@@ -128,6 +187,7 @@ int amdgpu_bo_create(struct amdgpu_device *adev,
bool kernel, u32 domain, u64 flags,
struct sg_table *sg,
struct reservation_object *resv,
+ uint64_t init_value,
struct amdgpu_bo **bo_ptr);
int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
unsigned long size, int byte_align,
@@ -135,7 +195,12 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
struct sg_table *sg,
struct ttm_placement *placement,
struct reservation_object *resv,
+ uint64_t init_value,
struct amdgpu_bo **bo_ptr);
+int amdgpu_bo_create_reserved(struct amdgpu_device *adev,
+ unsigned long size, int align,
+ u32 domain, struct amdgpu_bo **bo_ptr,
+ u64 *gpu_addr, void **cpu_addr);
int amdgpu_bo_create_kernel(struct amdgpu_device *adev,
unsigned long size, int align,
u32 domain, struct amdgpu_bo **bo_ptr,
@@ -143,6 +208,7 @@ int amdgpu_bo_create_kernel(struct amdgpu_device *adev,
void amdgpu_bo_free_kernel(struct amdgpu_bo **bo, u64 *gpu_addr,
void **cpu_addr);
int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr);
+void *amdgpu_bo_kptr(struct amdgpu_bo *bo);
void amdgpu_bo_kunmap(struct amdgpu_bo *bo);
struct amdgpu_bo *amdgpu_bo_ref(struct amdgpu_bo *bo);
void amdgpu_bo_unref(struct amdgpu_bo **bo);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.h
index c19c4d1..f21a771 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.h
@@ -30,6 +30,7 @@ struct cg_flag_name
const char *name;
};
+void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev);
int amdgpu_pm_sysfs_init(struct amdgpu_device *adev);
void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev);
void amdgpu_pm_print_power_states(struct amdgpu_device *adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
index 6bdc866..5b3f928 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
@@ -69,7 +69,7 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev,
ww_mutex_lock(&resv->lock, NULL);
ret = amdgpu_bo_create(adev, attach->dmabuf->size, PAGE_SIZE, false,
- AMDGPU_GEM_DOMAIN_GTT, 0, sg, resv, &bo);
+ AMDGPU_GEM_DOMAIN_GTT, 0, sg, resv, 0, &bo);
ww_mutex_unlock(&resv->lock);
if (ret)
return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index 4083be6..8c2204c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -63,8 +63,13 @@ static int psp_sw_init(void *handle)
psp->smu_reload_quirk = psp_v3_1_smu_reload_quirk;
break;
case CHIP_RAVEN:
+#if 0
+ psp->init_microcode = psp_v10_0_init_microcode;
+#endif
psp->prep_cmd_buf = psp_v10_0_prep_cmd_buf;
psp->ring_init = psp_v10_0_ring_init;
+ psp->ring_create = psp_v10_0_ring_create;
+ psp->ring_destroy = psp_v10_0_ring_destroy;
psp->cmd_submit = psp_v10_0_cmd_submit;
psp->compare_sram_data = psp_v10_0_compare_sram_data;
break;
@@ -95,9 +100,8 @@ int psp_wait_for(struct psp_context *psp, uint32_t reg_index,
int i;
struct amdgpu_device *adev = psp->adev;
- val = RREG32(reg_index);
-
for (i = 0; i < adev->usec_timeout; i++) {
+ val = RREG32(reg_index);
if (check_changed) {
if (val != reg_val)
return 0;
@@ -118,33 +122,18 @@ psp_cmd_submit_buf(struct psp_context *psp,
int index)
{
int ret;
- struct amdgpu_bo *cmd_buf_bo;
- uint64_t cmd_buf_mc_addr;
- struct psp_gfx_cmd_resp *cmd_buf_mem;
- struct amdgpu_device *adev = psp->adev;
-
- ret = amdgpu_bo_create_kernel(adev, PSP_CMD_BUFFER_SIZE, PAGE_SIZE,
- AMDGPU_GEM_DOMAIN_VRAM,
- &cmd_buf_bo, &cmd_buf_mc_addr,
- (void **)&cmd_buf_mem);
- if (ret)
- return ret;
- memset(cmd_buf_mem, 0, PSP_CMD_BUFFER_SIZE);
+ memset(psp->cmd_buf_mem, 0, PSP_CMD_BUFFER_SIZE);
- memcpy(cmd_buf_mem, cmd, sizeof(struct psp_gfx_cmd_resp));
+ memcpy(psp->cmd_buf_mem, cmd, sizeof(struct psp_gfx_cmd_resp));
- ret = psp_cmd_submit(psp, ucode, cmd_buf_mc_addr,
+ ret = psp_cmd_submit(psp, ucode, psp->cmd_buf_mc_addr,
fence_mc_addr, index);
while (*((unsigned int *)psp->fence_buf) != index) {
msleep(1);
}
- amdgpu_bo_free_kernel(&cmd_buf_bo,
- &cmd_buf_mc_addr,
- (void **)&cmd_buf_mem);
-
return ret;
}
@@ -352,13 +341,20 @@ static int psp_load_fw(struct amdgpu_device *adev)
&psp->fence_buf_mc_addr,
&psp->fence_buf);
if (ret)
+ goto failed_mem2;
+
+ ret = amdgpu_bo_create_kernel(adev, PSP_CMD_BUFFER_SIZE, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ &psp->cmd_buf_bo, &psp->cmd_buf_mc_addr,
+ (void **)&psp->cmd_buf_mem);
+ if (ret)
goto failed_mem1;
memset(psp->fence_buf, 0, PSP_FENCE_BUFFER_SIZE);
ret = psp_ring_init(psp, PSP_RING_TYPE__KM);
if (ret)
- goto failed_mem1;
+ goto failed_mem;
ret = psp_tmr_init(psp);
if (ret)
@@ -379,9 +375,13 @@ static int psp_load_fw(struct amdgpu_device *adev)
return 0;
failed_mem:
+ amdgpu_bo_free_kernel(&psp->cmd_buf_bo,
+ &psp->cmd_buf_mc_addr,
+ (void **)&psp->cmd_buf_mem);
+failed_mem1:
amdgpu_bo_free_kernel(&psp->fence_buf_bo,
&psp->fence_buf_mc_addr, &psp->fence_buf);
-failed_mem1:
+failed_mem2:
amdgpu_bo_free_kernel(&psp->fw_pri_bo,
&psp->fw_pri_mc_addr, &psp->fw_pri_buf);
failed:
@@ -435,16 +435,15 @@ static int psp_hw_fini(void *handle)
psp_ring_destroy(psp, PSP_RING_TYPE__KM);
- if (psp->tmr_buf)
- amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf);
-
- if (psp->fw_pri_buf)
- amdgpu_bo_free_kernel(&psp->fw_pri_bo,
- &psp->fw_pri_mc_addr, &psp->fw_pri_buf);
-
- if (psp->fence_buf_bo)
- amdgpu_bo_free_kernel(&psp->fence_buf_bo,
- &psp->fence_buf_mc_addr, &psp->fence_buf);
+ amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf);
+ amdgpu_bo_free_kernel(&psp->fw_pri_bo,
+ &psp->fw_pri_mc_addr, &psp->fw_pri_buf);
+ amdgpu_bo_free_kernel(&psp->fence_buf_bo,
+ &psp->fence_buf_mc_addr, &psp->fence_buf);
+ amdgpu_bo_free_kernel(&psp->asd_shared_bo, &psp->asd_shared_mc_addr,
+ &psp->asd_shared_buf);
+ amdgpu_bo_free_kernel(&psp->cmd_buf_bo, &psp->cmd_buf_mc_addr,
+ (void **)&psp->cmd_buf_mem);
kfree(psp->cmd);
psp->cmd = NULL;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
index 1a1c8b4..538fa9d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
@@ -108,6 +108,11 @@ struct psp_context
struct amdgpu_bo *fence_buf_bo;
uint64_t fence_buf_mc_addr;
void *fence_buf;
+
+ /* cmd buffer */
+ struct amdgpu_bo *cmd_buf_bo;
+ uint64_t cmd_buf_mc_addr;
+ struct psp_gfx_cmd_resp *cmd_buf_mem;
};
struct amdgpu_psp_funcs {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
index 75165e0..6c5646b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
@@ -184,32 +184,16 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
return r;
}
- if (ring->funcs->support_64bit_ptrs) {
- r = amdgpu_wb_get_64bit(adev, &ring->rptr_offs);
- if (r) {
- dev_err(adev->dev, "(%d) ring rptr_offs wb alloc failed\n", r);
- return r;
- }
-
- r = amdgpu_wb_get_64bit(adev, &ring->wptr_offs);
- if (r) {
- dev_err(adev->dev, "(%d) ring wptr_offs wb alloc failed\n", r);
- return r;
- }
-
- } else {
- r = amdgpu_wb_get(adev, &ring->rptr_offs);
- if (r) {
- dev_err(adev->dev, "(%d) ring rptr_offs wb alloc failed\n", r);
- return r;
- }
-
- r = amdgpu_wb_get(adev, &ring->wptr_offs);
- if (r) {
- dev_err(adev->dev, "(%d) ring wptr_offs wb alloc failed\n", r);
- return r;
- }
+ r = amdgpu_wb_get(adev, &ring->rptr_offs);
+ if (r) {
+ dev_err(adev->dev, "(%d) ring rptr_offs wb alloc failed\n", r);
+ return r;
+ }
+ r = amdgpu_wb_get(adev, &ring->wptr_offs);
+ if (r) {
+ dev_err(adev->dev, "(%d) ring wptr_offs wb alloc failed\n", r);
+ return r;
}
r = amdgpu_wb_get(adev, &ring->fence_offs);
@@ -277,18 +261,15 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring)
{
ring->ready = false;
- if (ring->funcs->support_64bit_ptrs) {
- amdgpu_wb_free_64bit(ring->adev, ring->cond_exe_offs);
- amdgpu_wb_free_64bit(ring->adev, ring->fence_offs);
- amdgpu_wb_free_64bit(ring->adev, ring->rptr_offs);
- amdgpu_wb_free_64bit(ring->adev, ring->wptr_offs);
- } else {
- amdgpu_wb_free(ring->adev, ring->cond_exe_offs);
- amdgpu_wb_free(ring->adev, ring->fence_offs);
- amdgpu_wb_free(ring->adev, ring->rptr_offs);
- amdgpu_wb_free(ring->adev, ring->wptr_offs);
- }
+ /* Not to finish a ring which is not initialized */
+ if (!(ring->adev) || !(ring->adev->rings[ring->idx]))
+ return;
+
+ amdgpu_wb_free(ring->adev, ring->rptr_offs);
+ amdgpu_wb_free(ring->adev, ring->wptr_offs);
+ amdgpu_wb_free(ring->adev, ring->cond_exe_offs);
+ amdgpu_wb_free(ring->adev, ring->fence_offs);
amdgpu_bo_free_kernel(&ring->ring_obj,
&ring->gpu_addr,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
index bc8dec9..322d2529 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
@@ -212,4 +212,44 @@ static inline void amdgpu_ring_clear_ring(struct amdgpu_ring *ring)
}
+static inline void amdgpu_ring_write(struct amdgpu_ring *ring, uint32_t v)
+{
+ if (ring->count_dw <= 0)
+ DRM_ERROR("amdgpu: writing more dwords to the ring than expected!\n");
+ ring->ring[ring->wptr++ & ring->buf_mask] = v;
+ ring->wptr &= ring->ptr_mask;
+ ring->count_dw--;
+}
+
+static inline void amdgpu_ring_write_multiple(struct amdgpu_ring *ring,
+ void *src, int count_dw)
+{
+ unsigned occupied, chunk1, chunk2;
+ void *dst;
+
+ if (unlikely(ring->count_dw < count_dw))
+ DRM_ERROR("amdgpu: writing more dwords to the ring than expected!\n");
+
+ occupied = ring->wptr & ring->buf_mask;
+ dst = (void *)&ring->ring[occupied];
+ chunk1 = ring->buf_mask + 1 - occupied;
+ chunk1 = (chunk1 >= count_dw) ? count_dw: chunk1;
+ chunk2 = count_dw - chunk1;
+ chunk1 <<= 2;
+ chunk2 <<= 2;
+
+ if (chunk1)
+ memcpy(dst, src, chunk1);
+
+ if (chunk2) {
+ src += chunk1;
+ dst = (void *)ring->ring;
+ memcpy(dst, src, chunk2);
+ }
+
+ ring->wptr += count_dw;
+ ring->wptr &= ring->ptr_mask;
+ ring->count_dw -= count_dw;
+}
+
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
index 5ca75a4..3144400 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
@@ -64,7 +64,7 @@ int amdgpu_sa_bo_manager_init(struct amdgpu_device *adev,
INIT_LIST_HEAD(&sa_manager->flist[i]);
r = amdgpu_bo_create(adev, size, align, true, domain,
- 0, NULL, NULL, &sa_manager->bo);
+ 0, NULL, NULL, 0, &sa_manager->bo);
if (r) {
dev_err(adev->dev, "(%d) failed to allocate bo for manager\n", r);
return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c
index 15510da..ed8c373 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c
@@ -33,7 +33,7 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
struct amdgpu_bo *vram_obj = NULL;
struct amdgpu_bo **gtt_obj = NULL;
- uint64_t gtt_addr, vram_addr;
+ uint64_t gart_addr, vram_addr;
unsigned n, size;
int i, r;
@@ -42,7 +42,7 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
/* Number of tests =
* (Total GTT - IB pool - writeback page - ring buffers) / test size
*/
- n = adev->mc.gtt_size - AMDGPU_IB_POOL_SIZE*64*1024;
+ n = adev->mc.gart_size - AMDGPU_IB_POOL_SIZE*64*1024;
for (i = 0; i < AMDGPU_MAX_RINGS; ++i)
if (adev->rings[i])
n -= adev->rings[i]->ring_size;
@@ -61,7 +61,7 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
r = amdgpu_bo_create(adev, size, PAGE_SIZE, true,
AMDGPU_GEM_DOMAIN_VRAM, 0,
- NULL, NULL, &vram_obj);
+ NULL, NULL, 0, &vram_obj);
if (r) {
DRM_ERROR("Failed to create VRAM object\n");
goto out_cleanup;
@@ -76,13 +76,13 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
}
for (i = 0; i < n; i++) {
void *gtt_map, *vram_map;
- void **gtt_start, **gtt_end;
+ void **gart_start, **gart_end;
void **vram_start, **vram_end;
struct dma_fence *fence = NULL;
r = amdgpu_bo_create(adev, size, PAGE_SIZE, true,
AMDGPU_GEM_DOMAIN_GTT, 0, NULL,
- NULL, gtt_obj + i);
+ NULL, 0, gtt_obj + i);
if (r) {
DRM_ERROR("Failed to create GTT object %d\n", i);
goto out_lclean;
@@ -91,7 +91,7 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
r = amdgpu_bo_reserve(gtt_obj[i], false);
if (unlikely(r != 0))
goto out_lclean_unref;
- r = amdgpu_bo_pin(gtt_obj[i], AMDGPU_GEM_DOMAIN_GTT, &gtt_addr);
+ r = amdgpu_bo_pin(gtt_obj[i], AMDGPU_GEM_DOMAIN_GTT, &gart_addr);
if (r) {
DRM_ERROR("Failed to pin GTT object %d\n", i);
goto out_lclean_unres;
@@ -103,15 +103,15 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
goto out_lclean_unpin;
}
- for (gtt_start = gtt_map, gtt_end = gtt_map + size;
- gtt_start < gtt_end;
- gtt_start++)
- *gtt_start = gtt_start;
+ for (gart_start = gtt_map, gart_end = gtt_map + size;
+ gart_start < gart_end;
+ gart_start++)
+ *gart_start = gart_start;
amdgpu_bo_kunmap(gtt_obj[i]);
- r = amdgpu_copy_buffer(ring, gtt_addr, vram_addr,
- size, NULL, &fence, false);
+ r = amdgpu_copy_buffer(ring, gart_addr, vram_addr,
+ size, NULL, &fence, false, false);
if (r) {
DRM_ERROR("Failed GTT->VRAM copy %d\n", i);
@@ -132,21 +132,21 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
goto out_lclean_unpin;
}
- for (gtt_start = gtt_map, gtt_end = gtt_map + size,
+ for (gart_start = gtt_map, gart_end = gtt_map + size,
vram_start = vram_map, vram_end = vram_map + size;
vram_start < vram_end;
- gtt_start++, vram_start++) {
- if (*vram_start != gtt_start) {
+ gart_start++, vram_start++) {
+ if (*vram_start != gart_start) {
DRM_ERROR("Incorrect GTT->VRAM copy %d: Got 0x%p, "
"expected 0x%p (GTT/VRAM offset "
"0x%16llx/0x%16llx)\n",
- i, *vram_start, gtt_start,
+ i, *vram_start, gart_start,
(unsigned long long)
- (gtt_addr - adev->mc.gtt_start +
- (void*)gtt_start - gtt_map),
+ (gart_addr - adev->mc.gart_start +
+ (void*)gart_start - gtt_map),
(unsigned long long)
(vram_addr - adev->mc.vram_start +
- (void*)gtt_start - gtt_map));
+ (void*)gart_start - gtt_map));
amdgpu_bo_kunmap(vram_obj);
goto out_lclean_unpin;
}
@@ -155,8 +155,8 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
amdgpu_bo_kunmap(vram_obj);
- r = amdgpu_copy_buffer(ring, vram_addr, gtt_addr,
- size, NULL, &fence, false);
+ r = amdgpu_copy_buffer(ring, vram_addr, gart_addr,
+ size, NULL, &fence, false, false);
if (r) {
DRM_ERROR("Failed VRAM->GTT copy %d\n", i);
@@ -177,20 +177,20 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
goto out_lclean_unpin;
}
- for (gtt_start = gtt_map, gtt_end = gtt_map + size,
+ for (gart_start = gtt_map, gart_end = gtt_map + size,
vram_start = vram_map, vram_end = vram_map + size;
- gtt_start < gtt_end;
- gtt_start++, vram_start++) {
- if (*gtt_start != vram_start) {
+ gart_start < gart_end;
+ gart_start++, vram_start++) {
+ if (*gart_start != vram_start) {
DRM_ERROR("Incorrect VRAM->GTT copy %d: Got 0x%p, "
"expected 0x%p (VRAM/GTT offset "
"0x%16llx/0x%16llx)\n",
- i, *gtt_start, vram_start,
+ i, *gart_start, vram_start,
(unsigned long long)
(vram_addr - adev->mc.vram_start +
(void*)vram_start - vram_map),
(unsigned long long)
- (gtt_addr - adev->mc.gtt_start +
+ (gart_addr - adev->mc.gart_start +
(void*)vram_start - vram_map));
amdgpu_bo_kunmap(gtt_obj[i]);
goto out_lclean_unpin;
@@ -200,7 +200,7 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
amdgpu_bo_kunmap(gtt_obj[i]);
DRM_INFO("Tested GTT->VRAM and VRAM->GTT copy for GTT offset 0x%llx\n",
- gtt_addr - adev->mc.gtt_start);
+ gart_addr - adev->mc.gart_start);
continue;
out_lclean_unpin:
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
index 8601904..1c88bd5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
@@ -14,6 +14,62 @@
#define AMDGPU_JOB_GET_TIMELINE_NAME(job) \
job->base.s_fence->finished.ops->get_timeline_name(&job->base.s_fence->finished)
+TRACE_EVENT(amdgpu_ttm_tt_populate,
+ TP_PROTO(struct amdgpu_device *adev, uint64_t dma_address, uint64_t phys_address),
+ TP_ARGS(adev, dma_address, phys_address),
+ TP_STRUCT__entry(
+ __field(uint16_t, domain)
+ __field(uint8_t, bus)
+ __field(uint8_t, slot)
+ __field(uint8_t, func)
+ __field(uint64_t, dma)
+ __field(uint64_t, phys)
+ ),
+ TP_fast_assign(
+ __entry->domain = pci_domain_nr(adev->pdev->bus);
+ __entry->bus = adev->pdev->bus->number;
+ __entry->slot = PCI_SLOT(adev->pdev->devfn);
+ __entry->func = PCI_FUNC(adev->pdev->devfn);
+ __entry->dma = dma_address;
+ __entry->phys = phys_address;
+ ),
+ TP_printk("%04x:%02x:%02x.%x: 0x%llx => 0x%llx",
+ (unsigned)__entry->domain,
+ (unsigned)__entry->bus,
+ (unsigned)__entry->slot,
+ (unsigned)__entry->func,
+ (unsigned long long)__entry->dma,
+ (unsigned long long)__entry->phys)
+);
+
+TRACE_EVENT(amdgpu_ttm_tt_unpopulate,
+ TP_PROTO(struct amdgpu_device *adev, uint64_t dma_address, uint64_t phys_address),
+ TP_ARGS(adev, dma_address, phys_address),
+ TP_STRUCT__entry(
+ __field(uint16_t, domain)
+ __field(uint8_t, bus)
+ __field(uint8_t, slot)
+ __field(uint8_t, func)
+ __field(uint64_t, dma)
+ __field(uint64_t, phys)
+ ),
+ TP_fast_assign(
+ __entry->domain = pci_domain_nr(adev->pdev->bus);
+ __entry->bus = adev->pdev->bus->number;
+ __entry->slot = PCI_SLOT(adev->pdev->devfn);
+ __entry->func = PCI_FUNC(adev->pdev->devfn);
+ __entry->dma = dma_address;
+ __entry->phys = phys_address;
+ ),
+ TP_printk("%04x:%02x:%02x.%x: 0x%llx => 0x%llx",
+ (unsigned)__entry->domain,
+ (unsigned)__entry->bus,
+ (unsigned)__entry->slot,
+ (unsigned)__entry->func,
+ (unsigned long long)__entry->dma,
+ (unsigned long long)__entry->phys)
+);
+
TRACE_EVENT(amdgpu_mm_rreg,
TP_PROTO(unsigned did, uint32_t reg, uint32_t value),
TP_ARGS(did, reg, value),
@@ -105,12 +161,12 @@ TRACE_EVENT(amdgpu_bo_create,
__entry->bo = bo;
__entry->pages = bo->tbo.num_pages;
__entry->type = bo->tbo.mem.mem_type;
- __entry->prefer = bo->prefered_domains;
+ __entry->prefer = bo->preferred_domains;
__entry->allow = bo->allowed_domains;
__entry->visible = bo->flags;
),
- TP_printk("bo=%p, pages=%u, type=%d, prefered=%d, allowed=%d, visible=%d",
+ TP_printk("bo=%p, pages=%u, type=%d, preferred=%d, allowed=%d, visible=%d",
__entry->bo, __entry->pages, __entry->type,
__entry->prefer, __entry->allow, __entry->visible)
);
@@ -224,17 +280,17 @@ TRACE_EVENT(amdgpu_vm_bo_map,
__field(long, start)
__field(long, last)
__field(u64, offset)
- __field(u32, flags)
+ __field(u64, flags)
),
TP_fast_assign(
- __entry->bo = bo_va ? bo_va->bo : NULL;
+ __entry->bo = bo_va ? bo_va->base.bo : NULL;
__entry->start = mapping->start;
__entry->last = mapping->last;
__entry->offset = mapping->offset;
__entry->flags = mapping->flags;
),
- TP_printk("bo=%p, start=%lx, last=%lx, offset=%010llx, flags=%08x",
+ TP_printk("bo=%p, start=%lx, last=%lx, offset=%010llx, flags=%llx",
__entry->bo, __entry->start, __entry->last,
__entry->offset, __entry->flags)
);
@@ -248,17 +304,17 @@ TRACE_EVENT(amdgpu_vm_bo_unmap,
__field(long, start)
__field(long, last)
__field(u64, offset)
- __field(u32, flags)
+ __field(u64, flags)
),
TP_fast_assign(
- __entry->bo = bo_va->bo;
+ __entry->bo = bo_va->base.bo;
__entry->start = mapping->start;
__entry->last = mapping->last;
__entry->offset = mapping->offset;
__entry->flags = mapping->flags;
),
- TP_printk("bo=%p, start=%lx, last=%lx, offset=%010llx, flags=%08x",
+ TP_printk("bo=%p, start=%lx, last=%lx, offset=%010llx, flags=%llx",
__entry->bo, __entry->start, __entry->last,
__entry->offset, __entry->flags)
);
@@ -269,7 +325,7 @@ DECLARE_EVENT_CLASS(amdgpu_vm_mapping,
TP_STRUCT__entry(
__field(u64, soffset)
__field(u64, eoffset)
- __field(u32, flags)
+ __field(u64, flags)
),
TP_fast_assign(
@@ -277,7 +333,7 @@ DECLARE_EVENT_CLASS(amdgpu_vm_mapping,
__entry->eoffset = mapping->last + 1;
__entry->flags = mapping->flags;
),
- TP_printk("soffs=%010llx, eoffs=%010llx, flags=%08x",
+ TP_printk("soffs=%010llx, eoffs=%010llx, flags=%llx",
__entry->soffset, __entry->eoffset, __entry->flags)
);
@@ -293,14 +349,14 @@ DEFINE_EVENT(amdgpu_vm_mapping, amdgpu_vm_bo_mapping,
TRACE_EVENT(amdgpu_vm_set_ptes,
TP_PROTO(uint64_t pe, uint64_t addr, unsigned count,
- uint32_t incr, uint32_t flags),
+ uint32_t incr, uint64_t flags),
TP_ARGS(pe, addr, count, incr, flags),
TP_STRUCT__entry(
__field(u64, pe)
__field(u64, addr)
__field(u32, count)
__field(u32, incr)
- __field(u32, flags)
+ __field(u64, flags)
),
TP_fast_assign(
@@ -310,7 +366,7 @@ TRACE_EVENT(amdgpu_vm_set_ptes,
__entry->incr = incr;
__entry->flags = flags;
),
- TP_printk("pe=%010Lx, addr=%010Lx, incr=%u, flags=%08x, count=%u",
+ TP_printk("pe=%010Lx, addr=%010Lx, incr=%u, flags=%llx, count=%u",
__entry->pe, __entry->addr, __entry->incr,
__entry->flags, __entry->count)
);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index c9b131b..8b2c294 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -43,14 +43,20 @@
#include <linux/pagemap.h>
#include <linux/debugfs.h>
#include "amdgpu.h"
+#include "amdgpu_trace.h"
#include "bif/bif_4_1_d.h"
#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
+static int amdgpu_map_buffer(struct ttm_buffer_object *bo,
+ struct ttm_mem_reg *mem, unsigned num_pages,
+ uint64_t offset, unsigned window,
+ struct amdgpu_ring *ring,
+ uint64_t *addr);
+
static int amdgpu_ttm_debugfs_init(struct amdgpu_device *adev);
static void amdgpu_ttm_debugfs_fini(struct amdgpu_device *adev);
-
/*
* Global memory.
*/
@@ -97,6 +103,8 @@ static int amdgpu_ttm_global_init(struct amdgpu_device *adev)
goto error_bo;
}
+ mutex_init(&adev->mman.gtt_window_lock);
+
ring = adev->mman.buffer_funcs_ring;
rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_KERNEL];
r = amd_sched_entity_init(&ring->sched, &adev->mman.entity,
@@ -123,6 +131,7 @@ static void amdgpu_ttm_global_fini(struct amdgpu_device *adev)
if (adev->mman.mem_global_referenced) {
amd_sched_entity_fini(adev->mman.entity.sched,
&adev->mman.entity);
+ mutex_destroy(&adev->mman.gtt_window_lock);
drm_global_item_unref(&adev->mman.bo_global_ref.ref);
drm_global_item_unref(&adev->mman.mem_global_ref);
adev->mman.mem_global_referenced = false;
@@ -150,7 +159,7 @@ static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
break;
case TTM_PL_TT:
man->func = &amdgpu_gtt_mgr_func;
- man->gpu_offset = adev->mc.gtt_start;
+ man->gpu_offset = adev->mc.gart_start;
man->available_caching = TTM_PL_MASK_CACHING;
man->default_caching = TTM_PL_FLAG_CACHED;
man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | TTM_MEMTYPE_FLAG_CMA;
@@ -186,12 +195,11 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
{
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
struct amdgpu_bo *abo;
- static struct ttm_place placements = {
+ static const struct ttm_place placements = {
.fpfn = 0,
.lpfn = 0,
.flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM
};
- unsigned i;
if (!amdgpu_ttm_bo_is_amdgpu_bo(bo)) {
placement->placement = &placements;
@@ -207,22 +215,36 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
adev->mman.buffer_funcs_ring &&
adev->mman.buffer_funcs_ring->ready == false) {
amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_CPU);
+ } else if (adev->mc.visible_vram_size < adev->mc.real_vram_size &&
+ !(abo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)) {
+ unsigned fpfn = adev->mc.visible_vram_size >> PAGE_SHIFT;
+ struct drm_mm_node *node = bo->mem.mm_node;
+ unsigned long pages_left;
+
+ for (pages_left = bo->mem.num_pages;
+ pages_left;
+ pages_left -= node->size, node++) {
+ if (node->start < fpfn)
+ break;
+ }
+
+ if (!pages_left)
+ goto gtt;
+
+ /* Try evicting to the CPU inaccessible part of VRAM
+ * first, but only set GTT as busy placement, so this
+ * BO will be evicted to GTT rather than causing other
+ * BOs to be evicted from VRAM
+ */
+ amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_VRAM |
+ AMDGPU_GEM_DOMAIN_GTT);
+ abo->placements[0].fpfn = fpfn;
+ abo->placements[0].lpfn = 0;
+ abo->placement.busy_placement = &abo->placements[1];
+ abo->placement.num_busy_placement = 1;
} else {
+gtt:
amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_GTT);
- for (i = 0; i < abo->placement.num_placement; ++i) {
- if (!(abo->placements[i].flags &
- TTM_PL_FLAG_TT))
- continue;
-
- if (abo->placements[i].lpfn)
- continue;
-
- /* set an upper limit to force directly
- * allocating address space for the BO.
- */
- abo->placements[i].lpfn =
- adev->mc.gtt_size >> PAGE_SHIFT;
- }
}
break;
case TTM_PL_TT:
@@ -252,29 +274,18 @@ static void amdgpu_move_null(struct ttm_buffer_object *bo,
new_mem->mm_node = NULL;
}
-static int amdgpu_mm_node_addr(struct ttm_buffer_object *bo,
- struct drm_mm_node *mm_node,
- struct ttm_mem_reg *mem,
- uint64_t *addr)
+static uint64_t amdgpu_mm_node_addr(struct ttm_buffer_object *bo,
+ struct drm_mm_node *mm_node,
+ struct ttm_mem_reg *mem)
{
- int r;
+ uint64_t addr = 0;
- switch (mem->mem_type) {
- case TTM_PL_TT:
- r = amdgpu_ttm_bind(bo, mem);
- if (r)
- return r;
-
- case TTM_PL_VRAM:
- *addr = mm_node->start << PAGE_SHIFT;
- *addr += bo->bdev->man[mem->mem_type].gpu_offset;
- break;
- default:
- DRM_ERROR("Unknown placement %d\n", mem->mem_type);
- return -EINVAL;
+ if (mem->mem_type != TTM_PL_TT ||
+ amdgpu_gtt_mgr_is_allocated(mem)) {
+ addr = mm_node->start << PAGE_SHIFT;
+ addr += bo->bdev->man[mem->mem_type].gpu_offset;
}
-
- return 0;
+ return addr;
}
static int amdgpu_move_blit(struct ttm_buffer_object *bo,
@@ -299,26 +310,40 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
}
old_mm = old_mem->mm_node;
- r = amdgpu_mm_node_addr(bo, old_mm, old_mem, &old_start);
- if (r)
- return r;
old_size = old_mm->size;
-
+ old_start = amdgpu_mm_node_addr(bo, old_mm, old_mem);
new_mm = new_mem->mm_node;
- r = amdgpu_mm_node_addr(bo, new_mm, new_mem, &new_start);
- if (r)
- return r;
new_size = new_mm->size;
+ new_start = amdgpu_mm_node_addr(bo, new_mm, new_mem);
num_pages = new_mem->num_pages;
+ mutex_lock(&adev->mman.gtt_window_lock);
while (num_pages) {
- unsigned long cur_pages = min(old_size, new_size);
+ unsigned long cur_pages = min(min(old_size, new_size),
+ (u64)AMDGPU_GTT_MAX_TRANSFER_SIZE);
+ uint64_t from = old_start, to = new_start;
struct dma_fence *next;
- r = amdgpu_copy_buffer(ring, old_start, new_start,
+ if (old_mem->mem_type == TTM_PL_TT &&
+ !amdgpu_gtt_mgr_is_allocated(old_mem)) {
+ r = amdgpu_map_buffer(bo, old_mem, cur_pages,
+ old_start, 0, ring, &from);
+ if (r)
+ goto error;
+ }
+
+ if (new_mem->mem_type == TTM_PL_TT &&
+ !amdgpu_gtt_mgr_is_allocated(new_mem)) {
+ r = amdgpu_map_buffer(bo, new_mem, cur_pages,
+ new_start, 1, ring, &to);
+ if (r)
+ goto error;
+ }
+
+ r = amdgpu_copy_buffer(ring, from, to,
cur_pages * PAGE_SIZE,
- bo->resv, &next, false);
+ bo->resv, &next, false, true);
if (r)
goto error;
@@ -331,10 +356,7 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
old_size -= cur_pages;
if (!old_size) {
- r = amdgpu_mm_node_addr(bo, ++old_mm, old_mem,
- &old_start);
- if (r)
- goto error;
+ old_start = amdgpu_mm_node_addr(bo, ++old_mm, old_mem);
old_size = old_mm->size;
} else {
old_start += cur_pages * PAGE_SIZE;
@@ -342,22 +364,21 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
new_size -= cur_pages;
if (!new_size) {
- r = amdgpu_mm_node_addr(bo, ++new_mm, new_mem,
- &new_start);
- if (r)
- goto error;
-
+ new_start = amdgpu_mm_node_addr(bo, ++new_mm, new_mem);
new_size = new_mm->size;
} else {
new_start += cur_pages * PAGE_SIZE;
}
}
+ mutex_unlock(&adev->mman.gtt_window_lock);
r = ttm_bo_pipeline_move(bo, fence, evict, new_mem);
dma_fence_put(fence);
return r;
error:
+ mutex_unlock(&adev->mman.gtt_window_lock);
+
if (fence)
dma_fence_wait(fence, false);
dma_fence_put(fence);
@@ -384,7 +405,7 @@ static int amdgpu_move_vram_ram(struct ttm_buffer_object *bo,
placement.num_busy_placement = 1;
placement.busy_placement = &placements;
placements.fpfn = 0;
- placements.lpfn = adev->mc.gtt_size >> PAGE_SHIFT;
+ placements.lpfn = 0;
placements.flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT;
r = ttm_bo_mem_space(bo, &placement, &tmp_mem,
interruptible, no_wait_gpu);
@@ -431,7 +452,7 @@ static int amdgpu_move_ram_vram(struct ttm_buffer_object *bo,
placement.num_busy_placement = 1;
placement.busy_placement = &placements;
placements.fpfn = 0;
- placements.lpfn = adev->mc.gtt_size >> PAGE_SHIFT;
+ placements.lpfn = 0;
placements.flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT;
r = ttm_bo_mem_space(bo, &placement, &tmp_mem,
interruptible, no_wait_gpu);
@@ -507,6 +528,15 @@ memcpy:
}
}
+ if (bo->type == ttm_bo_type_device &&
+ new_mem->mem_type == TTM_PL_VRAM &&
+ old_mem->mem_type != TTM_PL_VRAM) {
+ /* amdgpu_bo_fault_reserve_notify will re-set this if the CPU
+ * accesses the BO after it's moved.
+ */
+ abo->flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
+ }
+
/* update statistics */
atomic64_add((u64)bo->num_pages << PAGE_SHIFT, &adev->num_bytes_moved);
return 0;
@@ -633,6 +663,38 @@ release_pages:
return r;
}
+static void amdgpu_trace_dma_map(struct ttm_tt *ttm)
+{
+ struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
+ struct amdgpu_ttm_tt *gtt = (void *)ttm;
+ unsigned i;
+
+ if (unlikely(trace_amdgpu_ttm_tt_populate_enabled())) {
+ for (i = 0; i < ttm->num_pages; i++) {
+ trace_amdgpu_ttm_tt_populate(
+ adev,
+ gtt->ttm.dma_address[i],
+ page_to_phys(ttm->pages[i]));
+ }
+ }
+}
+
+static void amdgpu_trace_dma_unmap(struct ttm_tt *ttm)
+{
+ struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
+ struct amdgpu_ttm_tt *gtt = (void *)ttm;
+ unsigned i;
+
+ if (unlikely(trace_amdgpu_ttm_tt_unpopulate_enabled())) {
+ for (i = 0; i < ttm->num_pages; i++) {
+ trace_amdgpu_ttm_tt_unpopulate(
+ adev,
+ gtt->ttm.dma_address[i],
+ page_to_phys(ttm->pages[i]));
+ }
+ }
+}
+
/* prepare the sg table with the user pages */
static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
{
@@ -659,6 +721,8 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
gtt->ttm.dma_address, ttm->num_pages);
+ amdgpu_trace_dma_map(ttm);
+
return 0;
release_sg:
@@ -692,14 +756,41 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
put_page(page);
}
+ amdgpu_trace_dma_unmap(ttm);
+
sg_free_table(ttm->sg);
}
+static int amdgpu_ttm_do_bind(struct ttm_tt *ttm, struct ttm_mem_reg *mem)
+{
+ struct amdgpu_ttm_tt *gtt = (void *)ttm;
+ uint64_t flags;
+ int r;
+
+ spin_lock(&gtt->adev->gtt_list_lock);
+ flags = amdgpu_ttm_tt_pte_flags(gtt->adev, ttm, mem);
+ gtt->offset = (u64)mem->start << PAGE_SHIFT;
+ r = amdgpu_gart_bind(gtt->adev, gtt->offset, ttm->num_pages,
+ ttm->pages, gtt->ttm.dma_address, flags);
+
+ if (r) {
+ DRM_ERROR("failed to bind %lu pages at 0x%08llX\n",
+ ttm->num_pages, gtt->offset);
+ goto error_gart_bind;
+ }
+
+ list_add_tail(&gtt->list, &gtt->adev->gtt_list);
+error_gart_bind:
+ spin_unlock(&gtt->adev->gtt_list_lock);
+ return r;
+
+}
+
static int amdgpu_ttm_backend_bind(struct ttm_tt *ttm,
struct ttm_mem_reg *bo_mem)
{
struct amdgpu_ttm_tt *gtt = (void*)ttm;
- int r;
+ int r = 0;
if (gtt->userptr) {
r = amdgpu_ttm_tt_pin_userptr(ttm);
@@ -718,7 +809,10 @@ static int amdgpu_ttm_backend_bind(struct ttm_tt *ttm,
bo_mem->mem_type == AMDGPU_PL_OA)
return -EINVAL;
- return 0;
+ if (amdgpu_gtt_mgr_is_allocated(bo_mem))
+ r = amdgpu_ttm_do_bind(ttm, bo_mem);
+
+ return r;
}
bool amdgpu_ttm_is_bound(struct ttm_tt *ttm)
@@ -731,8 +825,6 @@ bool amdgpu_ttm_is_bound(struct ttm_tt *ttm)
int amdgpu_ttm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *bo_mem)
{
struct ttm_tt *ttm = bo->ttm;
- struct amdgpu_ttm_tt *gtt = (void *)bo->ttm;
- uint64_t flags;
int r;
if (!ttm || amdgpu_ttm_is_bound(ttm))
@@ -745,22 +837,7 @@ int amdgpu_ttm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *bo_mem)
return r;
}
- spin_lock(&gtt->adev->gtt_list_lock);
- flags = amdgpu_ttm_tt_pte_flags(gtt->adev, ttm, bo_mem);
- gtt->offset = (u64)bo_mem->start << PAGE_SHIFT;
- r = amdgpu_gart_bind(gtt->adev, gtt->offset, ttm->num_pages,
- ttm->pages, gtt->ttm.dma_address, flags);
-
- if (r) {
- DRM_ERROR("failed to bind %lu pages at 0x%08llX\n",
- ttm->num_pages, gtt->offset);
- goto error_gart_bind;
- }
-
- list_add_tail(&gtt->list, &gtt->adev->gtt_list);
-error_gart_bind:
- spin_unlock(&gtt->adev->gtt_list_lock);
- return r;
+ return amdgpu_ttm_do_bind(ttm, bo_mem);
}
int amdgpu_ttm_recover_gart(struct amdgpu_device *adev)
@@ -852,7 +929,7 @@ static struct ttm_tt *amdgpu_ttm_tt_create(struct ttm_bo_device *bdev,
static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm)
{
- struct amdgpu_device *adev;
+ struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
struct amdgpu_ttm_tt *gtt = (void *)ttm;
unsigned i;
int r;
@@ -875,14 +952,14 @@ static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm)
drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
gtt->ttm.dma_address, ttm->num_pages);
ttm->state = tt_unbound;
- return 0;
+ r = 0;
+ goto trace_mappings;
}
- adev = amdgpu_ttm_adev(ttm->bdev);
-
#ifdef CONFIG_SWIOTLB
if (swiotlb_nr_tbl()) {
- return ttm_dma_populate(&gtt->ttm, adev->dev);
+ r = ttm_dma_populate(&gtt->ttm, adev->dev);
+ goto trace_mappings;
}
#endif
@@ -905,7 +982,12 @@ static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm)
return -EFAULT;
}
}
- return 0;
+
+ r = 0;
+trace_mappings:
+ if (likely(!r))
+ amdgpu_trace_dma_map(ttm);
+ return r;
}
static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm)
@@ -926,6 +1008,8 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm)
adev = amdgpu_ttm_adev(ttm->bdev);
+ amdgpu_trace_dma_unmap(ttm);
+
#ifdef CONFIG_SWIOTLB
if (swiotlb_nr_tbl()) {
ttm_dma_unpopulate(&gtt->ttm, adev->dev);
@@ -1075,6 +1159,67 @@ static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
return ttm_bo_eviction_valuable(bo, place);
}
+static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo,
+ unsigned long offset,
+ void *buf, int len, int write)
+{
+ struct amdgpu_bo *abo = container_of(bo, struct amdgpu_bo, tbo);
+ struct amdgpu_device *adev = amdgpu_ttm_adev(abo->tbo.bdev);
+ struct drm_mm_node *nodes = abo->tbo.mem.mm_node;
+ uint32_t value = 0;
+ int ret = 0;
+ uint64_t pos;
+ unsigned long flags;
+
+ if (bo->mem.mem_type != TTM_PL_VRAM)
+ return -EIO;
+
+ while (offset >= (nodes->size << PAGE_SHIFT)) {
+ offset -= nodes->size << PAGE_SHIFT;
+ ++nodes;
+ }
+ pos = (nodes->start << PAGE_SHIFT) + offset;
+
+ while (len && pos < adev->mc.mc_vram_size) {
+ uint64_t aligned_pos = pos & ~(uint64_t)3;
+ uint32_t bytes = 4 - (pos & 3);
+ uint32_t shift = (pos & 3) * 8;
+ uint32_t mask = 0xffffffff << shift;
+
+ if (len < bytes) {
+ mask &= 0xffffffff >> (bytes - len) * 8;
+ bytes = len;
+ }
+
+ spin_lock_irqsave(&adev->mmio_idx_lock, flags);
+ WREG32(mmMM_INDEX, ((uint32_t)aligned_pos) | 0x80000000);
+ WREG32(mmMM_INDEX_HI, aligned_pos >> 31);
+ if (!write || mask != 0xffffffff)
+ value = RREG32(mmMM_DATA);
+ if (write) {
+ value &= ~mask;
+ value |= (*(uint32_t *)buf << shift) & mask;
+ WREG32(mmMM_DATA, value);
+ }
+ spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
+ if (!write) {
+ value = (value & mask) >> shift;
+ memcpy(buf, &value, bytes);
+ }
+
+ ret += bytes;
+ buf = (uint8_t *)buf + bytes;
+ pos += bytes;
+ len -= bytes;
+ if (pos >= (nodes->start + nodes->size) << PAGE_SHIFT) {
+ ++nodes;
+ pos = (nodes->start << PAGE_SHIFT);
+ }
+ }
+
+ return ret;
+}
+
static struct ttm_bo_driver amdgpu_bo_driver = {
.ttm_tt_create = &amdgpu_ttm_tt_create,
.ttm_tt_populate = &amdgpu_ttm_tt_populate,
@@ -1090,11 +1235,14 @@ static struct ttm_bo_driver amdgpu_bo_driver = {
.io_mem_reserve = &amdgpu_ttm_io_mem_reserve,
.io_mem_free = &amdgpu_ttm_io_mem_free,
.io_mem_pfn = amdgpu_ttm_io_mem_pfn,
+ .access_memory = &amdgpu_ttm_access_memory
};
int amdgpu_ttm_init(struct amdgpu_device *adev)
{
+ uint64_t gtt_size;
int r;
+ u64 vis_vram_limit;
r = amdgpu_ttm_global_init(adev);
if (r) {
@@ -1118,36 +1266,37 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
DRM_ERROR("Failed initializing VRAM heap.\n");
return r;
}
+
+ /* Reduce size of CPU-visible VRAM if requested */
+ vis_vram_limit = (u64)amdgpu_vis_vram_limit * 1024 * 1024;
+ if (amdgpu_vis_vram_limit > 0 &&
+ vis_vram_limit <= adev->mc.visible_vram_size)
+ adev->mc.visible_vram_size = vis_vram_limit;
+
/* Change the size here instead of the init above so only lpfn is affected */
amdgpu_ttm_set_active_vram_size(adev, adev->mc.visible_vram_size);
- r = amdgpu_bo_create(adev, adev->mc.stolen_size, PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
- AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL, &adev->stollen_vga_memory);
- if (r) {
- return r;
- }
- r = amdgpu_bo_reserve(adev->stollen_vga_memory, false);
+ r = amdgpu_bo_create_kernel(adev, adev->mc.stolen_size, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ &adev->stolen_vga_memory,
+ NULL, NULL);
if (r)
return r;
- r = amdgpu_bo_pin(adev->stollen_vga_memory, AMDGPU_GEM_DOMAIN_VRAM, NULL);
- amdgpu_bo_unreserve(adev->stollen_vga_memory);
- if (r) {
- amdgpu_bo_unref(&adev->stollen_vga_memory);
- return r;
- }
DRM_INFO("amdgpu: %uM of VRAM memory ready\n",
(unsigned) (adev->mc.real_vram_size / (1024 * 1024)));
- r = ttm_bo_init_mm(&adev->mman.bdev, TTM_PL_TT,
- adev->mc.gtt_size >> PAGE_SHIFT);
+
+ if (amdgpu_gtt_size == -1)
+ gtt_size = max((AMDGPU_DEFAULT_GTT_SIZE_MB << 20),
+ adev->mc.mc_vram_size);
+ else
+ gtt_size = (uint64_t)amdgpu_gtt_size << 20;
+ r = ttm_bo_init_mm(&adev->mman.bdev, TTM_PL_TT, gtt_size >> PAGE_SHIFT);
if (r) {
DRM_ERROR("Failed initializing GTT heap.\n");
return r;
}
DRM_INFO("amdgpu: %uM of GTT memory ready.\n",
- (unsigned)(adev->mc.gtt_size / (1024 * 1024)));
+ (unsigned)(gtt_size / (1024 * 1024)));
adev->gds.mem.total_size = adev->gds.mem.total_size << AMDGPU_GDS_SHIFT;
adev->gds.mem.gfx_partition_size = adev->gds.mem.gfx_partition_size << AMDGPU_GDS_SHIFT;
@@ -1203,13 +1352,13 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev)
if (!adev->mman.initialized)
return;
amdgpu_ttm_debugfs_fini(adev);
- if (adev->stollen_vga_memory) {
- r = amdgpu_bo_reserve(adev->stollen_vga_memory, true);
+ if (adev->stolen_vga_memory) {
+ r = amdgpu_bo_reserve(adev->stolen_vga_memory, true);
if (r == 0) {
- amdgpu_bo_unpin(adev->stollen_vga_memory);
- amdgpu_bo_unreserve(adev->stollen_vga_memory);
+ amdgpu_bo_unpin(adev->stolen_vga_memory);
+ amdgpu_bo_unreserve(adev->stolen_vga_memory);
}
- amdgpu_bo_unref(&adev->stollen_vga_memory);
+ amdgpu_bo_unref(&adev->stolen_vga_memory);
}
ttm_bo_clean_mm(&adev->mman.bdev, TTM_PL_VRAM);
ttm_bo_clean_mm(&adev->mman.bdev, TTM_PL_TT);
@@ -1256,12 +1405,77 @@ int amdgpu_mmap(struct file *filp, struct vm_area_struct *vma)
return ttm_bo_mmap(filp, vma, &adev->mman.bdev);
}
-int amdgpu_copy_buffer(struct amdgpu_ring *ring,
- uint64_t src_offset,
- uint64_t dst_offset,
- uint32_t byte_count,
+static int amdgpu_map_buffer(struct ttm_buffer_object *bo,
+ struct ttm_mem_reg *mem, unsigned num_pages,
+ uint64_t offset, unsigned window,
+ struct amdgpu_ring *ring,
+ uint64_t *addr)
+{
+ struct amdgpu_ttm_tt *gtt = (void *)bo->ttm;
+ struct amdgpu_device *adev = ring->adev;
+ struct ttm_tt *ttm = bo->ttm;
+ struct amdgpu_job *job;
+ unsigned num_dw, num_bytes;
+ dma_addr_t *dma_address;
+ struct dma_fence *fence;
+ uint64_t src_addr, dst_addr;
+ uint64_t flags;
+ int r;
+
+ BUG_ON(adev->mman.buffer_funcs->copy_max_bytes <
+ AMDGPU_GTT_MAX_TRANSFER_SIZE * 8);
+
+ *addr = adev->mc.gart_start;
+ *addr += (u64)window * AMDGPU_GTT_MAX_TRANSFER_SIZE *
+ AMDGPU_GPU_PAGE_SIZE;
+
+ num_dw = adev->mman.buffer_funcs->copy_num_dw;
+ while (num_dw & 0x7)
+ num_dw++;
+
+ num_bytes = num_pages * 8;
+
+ r = amdgpu_job_alloc_with_ib(adev, num_dw * 4 + num_bytes, &job);
+ if (r)
+ return r;
+
+ src_addr = num_dw * 4;
+ src_addr += job->ibs[0].gpu_addr;
+
+ dst_addr = adev->gart.table_addr;
+ dst_addr += window * AMDGPU_GTT_MAX_TRANSFER_SIZE * 8;
+ amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_addr,
+ dst_addr, num_bytes);
+
+ amdgpu_ring_pad_ib(ring, &job->ibs[0]);
+ WARN_ON(job->ibs[0].length_dw > num_dw);
+
+ dma_address = &gtt->ttm.dma_address[offset >> PAGE_SHIFT];
+ flags = amdgpu_ttm_tt_pte_flags(adev, ttm, mem);
+ r = amdgpu_gart_map(adev, 0, num_pages, dma_address, flags,
+ &job->ibs[0].ptr[num_dw]);
+ if (r)
+ goto error_free;
+
+ r = amdgpu_job_submit(job, ring, &adev->mman.entity,
+ AMDGPU_FENCE_OWNER_UNDEFINED, &fence);
+ if (r)
+ goto error_free;
+
+ dma_fence_put(fence);
+
+ return r;
+
+error_free:
+ amdgpu_job_free(job);
+ return r;
+}
+
+int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
+ uint64_t dst_offset, uint32_t byte_count,
struct reservation_object *resv,
- struct dma_fence **fence, bool direct_submit)
+ struct dma_fence **fence, bool direct_submit,
+ bool vm_needs_flush)
{
struct amdgpu_device *adev = ring->adev;
struct amdgpu_job *job;
@@ -1283,6 +1497,7 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring,
if (r)
return r;
+ job->vm_needs_flush = vm_needs_flush;
if (resv) {
r = amdgpu_sync_resv(adev, &job->sync, resv,
AMDGPU_FENCE_OWNER_UNDEFINED);
@@ -1327,11 +1542,12 @@ error_free:
}
int amdgpu_fill_buffer(struct amdgpu_bo *bo,
- uint32_t src_data,
+ uint64_t src_data,
struct reservation_object *resv,
struct dma_fence **fence)
{
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
+ /* max_bytes applies to SDMA_OP_PTEPDE as well as SDMA_OP_CONST_FILL*/
uint32_t max_bytes = adev->mman.buffer_funcs->fill_max_bytes;
struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
@@ -1347,6 +1563,12 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
return -EINVAL;
}
+ if (bo->tbo.mem.mem_type == TTM_PL_TT) {
+ r = amdgpu_ttm_bind(&bo->tbo, &bo->tbo.mem);
+ if (r)
+ return r;
+ }
+
num_pages = bo->tbo.num_pages;
mm_node = bo->tbo.mem.mm_node;
num_loops = 0;
@@ -1357,7 +1579,9 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
num_pages -= mm_node->size;
++mm_node;
}
- num_dw = num_loops * adev->mman.buffer_funcs->fill_num_dw;
+
+ /* 10 double words for each SDMA_OP_PTEPDE cmd */
+ num_dw = num_loops * 10;
/* for IB padding */
num_dw += 64;
@@ -1382,16 +1606,16 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
uint32_t byte_count = mm_node->size << PAGE_SHIFT;
uint64_t dst_addr;
- r = amdgpu_mm_node_addr(&bo->tbo, mm_node,
- &bo->tbo.mem, &dst_addr);
- if (r)
- return r;
+ WARN_ONCE(byte_count & 0x7, "size should be a multiple of 8");
+ dst_addr = amdgpu_mm_node_addr(&bo->tbo, mm_node, &bo->tbo.mem);
while (byte_count) {
uint32_t cur_size_in_bytes = min(byte_count, max_bytes);
- amdgpu_emit_fill_buffer(adev, &job->ibs[0], src_data,
- dst_addr, cur_size_in_bytes);
+ amdgpu_vm_set_pte_pde(adev, &job->ibs[0],
+ dst_addr, 0,
+ cur_size_in_bytes >> 3, 0,
+ src_data);
dst_addr += cur_size_in_bytes;
byte_count -= cur_size_in_bytes;
@@ -1417,32 +1641,16 @@ error_free:
#if defined(CONFIG_DEBUG_FS)
-extern void amdgpu_gtt_mgr_print(struct seq_file *m, struct ttm_mem_type_manager
- *man);
static int amdgpu_mm_dump_table(struct seq_file *m, void *data)
{
struct drm_info_node *node = (struct drm_info_node *)m->private;
unsigned ttm_pl = *(int *)node->info_ent->data;
struct drm_device *dev = node->minor->dev;
struct amdgpu_device *adev = dev->dev_private;
- struct drm_mm *mm = (struct drm_mm *)adev->mman.bdev.man[ttm_pl].priv;
- struct ttm_bo_global *glob = adev->mman.bdev.glob;
+ struct ttm_mem_type_manager *man = &adev->mman.bdev.man[ttm_pl];
struct drm_printer p = drm_seq_file_printer(m);
- spin_lock(&glob->lru_lock);
- drm_mm_print(mm, &p);
- spin_unlock(&glob->lru_lock);
- switch (ttm_pl) {
- case TTM_PL_VRAM:
- seq_printf(m, "man size:%llu pages, ram usage:%lluMB, vis usage:%lluMB\n",
- adev->mman.bdev.man[ttm_pl].size,
- (u64)atomic64_read(&adev->vram_usage) >> 20,
- (u64)atomic64_read(&adev->vram_vis_usage) >> 20);
- break;
- case TTM_PL_TT:
- amdgpu_gtt_mgr_print(m, &adev->mman.bdev.man[TTM_PL_TT]);
- break;
- }
+ man->func->debug(man, &p);
return 0;
}
@@ -1574,7 +1782,7 @@ static int amdgpu_ttm_debugfs_init(struct amdgpu_device *adev)
adev, &amdgpu_ttm_gtt_fops);
if (IS_ERR(ent))
return PTR_ERR(ent);
- i_size_write(ent->d_inode, adev->mc.gtt_size);
+ i_size_write(ent->d_inode, adev->mc.gart_size);
adev->mman.gtt = ent;
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
index 6bdede8..f22a475 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
@@ -34,6 +34,9 @@
#define AMDGPU_PL_FLAG_GWS (TTM_PL_FLAG_PRIV << 1)
#define AMDGPU_PL_FLAG_OA (TTM_PL_FLAG_PRIV << 2)
+#define AMDGPU_GTT_MAX_TRANSFER_SIZE 512
+#define AMDGPU_GTT_NUM_TRANSFER_WINDOWS 2
+
struct amdgpu_mman {
struct ttm_bo_global_ref bo_global_ref;
struct drm_global_reference mem_global_ref;
@@ -49,6 +52,8 @@ struct amdgpu_mman {
/* buffer handling */
const struct amdgpu_buffer_funcs *buffer_funcs;
struct amdgpu_ring *buffer_funcs_ring;
+
+ struct mutex gtt_window_lock;
/* Scheduler entity for buffer moves */
struct amd_sched_entity entity;
};
@@ -56,24 +61,29 @@ struct amdgpu_mman {
extern const struct ttm_mem_type_manager_func amdgpu_gtt_mgr_func;
extern const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func;
+bool amdgpu_gtt_mgr_is_allocated(struct ttm_mem_reg *mem);
int amdgpu_gtt_mgr_alloc(struct ttm_mem_type_manager *man,
struct ttm_buffer_object *tbo,
const struct ttm_place *place,
struct ttm_mem_reg *mem);
+uint64_t amdgpu_gtt_mgr_usage(struct ttm_mem_type_manager *man);
+
+uint64_t amdgpu_vram_mgr_usage(struct ttm_mem_type_manager *man);
+uint64_t amdgpu_vram_mgr_vis_usage(struct ttm_mem_type_manager *man);
-int amdgpu_copy_buffer(struct amdgpu_ring *ring,
- uint64_t src_offset,
- uint64_t dst_offset,
- uint32_t byte_count,
+int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
+ uint64_t dst_offset, uint32_t byte_count,
struct reservation_object *resv,
- struct dma_fence **fence, bool direct_submit);
+ struct dma_fence **fence, bool direct_submit,
+ bool vm_needs_flush);
int amdgpu_fill_buffer(struct amdgpu_bo *bo,
- uint32_t src_data,
+ uint64_t src_data,
struct reservation_object *resv,
struct dma_fence **fence);
int amdgpu_mmap(struct file *filp, struct vm_area_struct *vma);
bool amdgpu_ttm_is_bound(struct ttm_tt *ttm);
int amdgpu_ttm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *bo_mem);
+int amdgpu_ttm_recover_gart(struct amdgpu_device *adev);
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
index 4f50eeb..36c7633 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
@@ -275,14 +275,10 @@ amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type)
else
return AMDGPU_FW_LOAD_PSP;
case CHIP_RAVEN:
-#if 0
- if (!load_type)
+ if (load_type != 2)
return AMDGPU_FW_LOAD_DIRECT;
else
return AMDGPU_FW_LOAD_PSP;
-#else
- return AMDGPU_FW_LOAD_DIRECT;
-#endif
default:
DRM_ERROR("Unknow firmware load type\n");
}
@@ -362,8 +358,6 @@ static int amdgpu_ucode_patch_jt(struct amdgpu_firmware_info *ucode,
(le32_to_cpu(header->jt_offset) * 4);
memcpy(dst_addr, src_addr, le32_to_cpu(header->jt_size) * 4);
- ucode->ucode_size += le32_to_cpu(header->jt_size) * 4;
-
return 0;
}
@@ -377,10 +371,15 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev)
struct amdgpu_firmware_info *ucode = NULL;
const struct common_firmware_header *header = NULL;
+ if (!adev->firmware.fw_size) {
+ dev_warn(adev->dev, "No ip firmware need to load\n");
+ return 0;
+ }
+
err = amdgpu_bo_create(adev, adev->firmware.fw_size, PAGE_SIZE, true,
amdgpu_sriov_vf(adev) ? AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT,
AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL, bo);
+ NULL, NULL, 0, bo);
if (err) {
dev_err(adev->dev, "(%d) Firmware buffer allocate failed\n", err);
goto failed;
@@ -459,6 +458,9 @@ int amdgpu_ucode_fini_bo(struct amdgpu_device *adev)
int i;
struct amdgpu_firmware_info *ucode = NULL;
+ if (!adev->firmware.fw_size)
+ return 0;
+
for (i = 0; i < adev->firmware.max_ucodes; i++) {
ucode = &adev->firmware.ucode[i];
if (ucode->fw) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
index 2ca09f1..e19928d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
@@ -588,6 +588,10 @@ static int amdgpu_uvd_cs_msg_decode(struct amdgpu_device *adev, uint32_t *msg,
}
break;
+ case 8: /* MJPEG */
+ min_dpb_size = 0;
+ break;
+
case 16: /* H265 */
image_size = (ALIGN(width, 16) * ALIGN(height, 16) * 3) / 2;
image_size = ALIGN(image_size, 256);
@@ -1051,7 +1055,7 @@ int amdgpu_uvd_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
AMDGPU_GEM_DOMAIN_VRAM,
AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL, &bo);
+ NULL, NULL, 0, &bo);
if (r)
return r;
@@ -1101,7 +1105,7 @@ int amdgpu_uvd_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
AMDGPU_GEM_DOMAIN_VRAM,
AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL, &bo);
+ NULL, NULL, 0, &bo);
if (r)
return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
index b692ad4..c855366 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
@@ -937,9 +937,9 @@ int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring)
unsigned i;
int r, timeout = adev->usec_timeout;
- /* workaround VCE ring test slow issue for sriov*/
+ /* skip ring test for sriov*/
if (amdgpu_sriov_vf(adev))
- timeout *= 10;
+ return 0;
r = amdgpu_ring_alloc(ring, 16);
if (r) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
index 09190fa..041e012 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
@@ -209,9 +209,9 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
if (fences == 0) {
if (adev->pm.dpm_enabled) {
+ /* might be used when with pg/cg
amdgpu_dpm_enable_uvd(adev, false);
- } else {
- amdgpu_asic_set_uvd_clocks(adev, 0, 0);
+ */
}
} else {
schedule_delayed_work(&adev->vcn.idle_work, VCN_IDLE_TIMEOUT);
@@ -223,12 +223,10 @@ void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
struct amdgpu_device *adev = ring->adev;
bool set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work);
- if (set_clocks) {
- if (adev->pm.dpm_enabled) {
- amdgpu_dpm_enable_uvd(adev, true);
- } else {
- amdgpu_asic_set_uvd_clocks(adev, 53300, 40000);
- }
+ if (set_clocks && adev->pm.dpm_enabled) {
+ /* might be used when with pg/cg
+ amdgpu_dpm_enable_uvd(adev, true);
+ */
}
}
@@ -361,7 +359,7 @@ static int amdgpu_vcn_dec_get_create_msg(struct amdgpu_ring *ring, uint32_t hand
AMDGPU_GEM_DOMAIN_VRAM,
AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL, &bo);
+ NULL, NULL, 0, &bo);
if (r)
return r;
@@ -413,7 +411,7 @@ static int amdgpu_vcn_dec_get_destroy_msg(struct amdgpu_ring *ring, uint32_t han
AMDGPU_GEM_DOMAIN_VRAM,
AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL, &bo);
+ NULL, NULL, 0, &bo);
if (r)
return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.c
new file mode 100644
index 0000000..45ac918
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "amdgpu.h"
+#include "amdgpu_vf_error.h"
+#include "mxgpu_ai.h"
+
+#define AMDGPU_VF_ERROR_ENTRY_SIZE 16
+
+/* struct error_entry - amdgpu VF error information. */
+struct amdgpu_vf_error_buffer {
+ int read_count;
+ int write_count;
+ uint16_t code[AMDGPU_VF_ERROR_ENTRY_SIZE];
+ uint16_t flags[AMDGPU_VF_ERROR_ENTRY_SIZE];
+ uint64_t data[AMDGPU_VF_ERROR_ENTRY_SIZE];
+};
+
+struct amdgpu_vf_error_buffer admgpu_vf_errors;
+
+
+void amdgpu_vf_error_put(uint16_t sub_error_code, uint16_t error_flags, uint64_t error_data)
+{
+ int index;
+ uint16_t error_code = AMDGIM_ERROR_CODE(AMDGIM_ERROR_CATEGORY_VF, sub_error_code);
+
+ index = admgpu_vf_errors.write_count % AMDGPU_VF_ERROR_ENTRY_SIZE;
+ admgpu_vf_errors.code [index] = error_code;
+ admgpu_vf_errors.flags [index] = error_flags;
+ admgpu_vf_errors.data [index] = error_data;
+ admgpu_vf_errors.write_count ++;
+}
+
+
+void amdgpu_vf_error_trans_all(struct amdgpu_device *adev)
+{
+ /* u32 pf2vf_flags = 0; */
+ u32 data1, data2, data3;
+ int index;
+
+ if ((NULL == adev) || (!amdgpu_sriov_vf(adev)) || (!adev->virt.ops) || (!adev->virt.ops->trans_msg)) {
+ return;
+ }
+/*
+ TODO: Enable these code when pv2vf_info is merged
+ AMDGPU_FW_VRAM_PF2VF_READ (adev, feature_flags, &pf2vf_flags);
+ if (!(pf2vf_flags & AMDGIM_FEATURE_ERROR_LOG_COLLECT)) {
+ return;
+ }
+*/
+ /* The errors are overlay of array, correct read_count as full. */
+ if (admgpu_vf_errors.write_count - admgpu_vf_errors.read_count > AMDGPU_VF_ERROR_ENTRY_SIZE) {
+ admgpu_vf_errors.read_count = admgpu_vf_errors.write_count - AMDGPU_VF_ERROR_ENTRY_SIZE;
+ }
+
+ while (admgpu_vf_errors.read_count < admgpu_vf_errors.write_count) {
+ index =admgpu_vf_errors.read_count % AMDGPU_VF_ERROR_ENTRY_SIZE;
+ data1 = AMDGIM_ERROR_CODE_FLAGS_TO_MAILBOX (admgpu_vf_errors.code[index], admgpu_vf_errors.flags[index]);
+ data2 = admgpu_vf_errors.data[index] & 0xFFFFFFFF;
+ data3 = (admgpu_vf_errors.data[index] >> 32) & 0xFFFFFFFF;
+
+ adev->virt.ops->trans_msg(adev, IDH_LOG_VF_ERROR, data1, data2, data3);
+ admgpu_vf_errors.read_count ++;
+ }
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.h
new file mode 100644
index 0000000..2a3278e
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __VF_ERROR_H__
+#define __VF_ERROR_H__
+
+#define AMDGIM_ERROR_CODE_FLAGS_TO_MAILBOX(c,f) (((c & 0xFFFF) << 16) | (f & 0xFFFF))
+#define AMDGIM_ERROR_CODE(t,c) (((t&0xF)<<12)|(c&0xFFF))
+
+/* Please keep enum same as AMD GIM driver */
+enum AMDGIM_ERROR_VF {
+ AMDGIM_ERROR_VF_ATOMBIOS_INIT_FAIL = 0,
+ AMDGIM_ERROR_VF_NO_VBIOS,
+ AMDGIM_ERROR_VF_GPU_POST_ERROR,
+ AMDGIM_ERROR_VF_ATOMBIOS_GET_CLOCK_FAIL,
+ AMDGIM_ERROR_VF_FENCE_INIT_FAIL,
+
+ AMDGIM_ERROR_VF_AMDGPU_INIT_FAIL,
+ AMDGIM_ERROR_VF_IB_INIT_FAIL,
+ AMDGIM_ERROR_VF_AMDGPU_LATE_INIT_FAIL,
+ AMDGIM_ERROR_VF_ASIC_RESUME_FAIL,
+ AMDGIM_ERROR_VF_GPU_RESET_FAIL,
+
+ AMDGIM_ERROR_VF_TEST,
+ AMDGIM_ERROR_VF_MAX
+};
+
+enum AMDGIM_ERROR_CATEGORY {
+ AMDGIM_ERROR_CATEGORY_NON_USED = 0,
+ AMDGIM_ERROR_CATEGORY_GIM,
+ AMDGIM_ERROR_CATEGORY_PF,
+ AMDGIM_ERROR_CATEGORY_VF,
+ AMDGIM_ERROR_CATEGORY_VBIOS,
+ AMDGIM_ERROR_CATEGORY_MONITOR,
+
+ AMDGIM_ERROR_CATEGORY_MAX
+};
+
+void amdgpu_vf_error_put(uint16_t sub_error_code, uint16_t error_flags, uint64_t error_data);
+void amdgpu_vf_error_trans_all (struct amdgpu_device *adev);
+
+#endif /* __VF_ERROR_H__ */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
index 8a081e1..ab05121 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
@@ -46,14 +46,14 @@ int amdgpu_allocate_static_csa(struct amdgpu_device *adev)
* address within META_DATA init package to support SRIOV gfx preemption.
*/
-int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm)
+int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,
+ struct amdgpu_bo_va **bo_va)
{
- int r;
- struct amdgpu_bo_va *bo_va;
struct ww_acquire_ctx ticket;
struct list_head list;
struct amdgpu_bo_list_entry pd;
struct ttm_validate_buffer csa_tv;
+ int r;
INIT_LIST_HEAD(&list);
INIT_LIST_HEAD(&csa_tv.head);
@@ -69,34 +69,33 @@ int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm)
return r;
}
- bo_va = amdgpu_vm_bo_add(adev, vm, adev->virt.csa_obj);
- if (!bo_va) {
+ *bo_va = amdgpu_vm_bo_add(adev, vm, adev->virt.csa_obj);
+ if (!*bo_va) {
ttm_eu_backoff_reservation(&ticket, &list);
DRM_ERROR("failed to create bo_va for static CSA\n");
return -ENOMEM;
}
- r = amdgpu_vm_alloc_pts(adev, bo_va->vm, AMDGPU_CSA_VADDR,
- AMDGPU_CSA_SIZE);
+ r = amdgpu_vm_alloc_pts(adev, (*bo_va)->base.vm, AMDGPU_CSA_VADDR,
+ AMDGPU_CSA_SIZE);
if (r) {
DRM_ERROR("failed to allocate pts for static CSA, err=%d\n", r);
- amdgpu_vm_bo_rmv(adev, bo_va);
+ amdgpu_vm_bo_rmv(adev, *bo_va);
ttm_eu_backoff_reservation(&ticket, &list);
return r;
}
- r = amdgpu_vm_bo_map(adev, bo_va, AMDGPU_CSA_VADDR, 0,AMDGPU_CSA_SIZE,
- AMDGPU_PTE_READABLE | AMDGPU_PTE_WRITEABLE |
- AMDGPU_PTE_EXECUTABLE);
+ r = amdgpu_vm_bo_map(adev, *bo_va, AMDGPU_CSA_VADDR, 0, AMDGPU_CSA_SIZE,
+ AMDGPU_PTE_READABLE | AMDGPU_PTE_WRITEABLE |
+ AMDGPU_PTE_EXECUTABLE);
if (r) {
DRM_ERROR("failed to do bo_map on static CSA, err=%d\n", r);
- amdgpu_vm_bo_rmv(adev, bo_va);
+ amdgpu_vm_bo_rmv(adev, *bo_va);
ttm_eu_backoff_reservation(&ticket, &list);
return r;
}
- vm->csa_bo_va = bo_va;
ttm_eu_backoff_reservation(&ticket, &list);
return 0;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
index 9e1062e..afcfb8b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
@@ -43,6 +43,7 @@ struct amdgpu_virt_ops {
int (*req_full_gpu)(struct amdgpu_device *adev, bool init);
int (*rel_full_gpu)(struct amdgpu_device *adev, bool init);
int (*reset_gpu)(struct amdgpu_device *adev);
+ void (*trans_msg)(struct amdgpu_device *adev, u32 req, u32 data1, u32 data2, u32 data3);
};
/* GPU virtualization */
@@ -89,7 +90,8 @@ static inline bool is_virtual_machine(void)
struct amdgpu_vm;
int amdgpu_allocate_static_csa(struct amdgpu_device *adev);
-int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm);
+int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,
+ struct amdgpu_bo_va **bo_va);
void amdgpu_virt_init_setting(struct amdgpu_device *adev);
uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg);
void amdgpu_virt_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 5795f81..6b1343e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -77,8 +77,6 @@ struct amdgpu_pte_update_params {
void (*func)(struct amdgpu_pte_update_params *params, uint64_t pe,
uint64_t addr, unsigned count, uint32_t incr,
uint64_t flags);
- /* indicate update pt or its shadow */
- bool shadow;
/* The next two are used during VM update by CPU
* DMA addresses to use for mapping
* Kernel pointer of PD/PT BO that needs to be updated
@@ -161,11 +159,26 @@ void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm,
*/
static int amdgpu_vm_validate_level(struct amdgpu_vm_pt *parent,
int (*validate)(void *, struct amdgpu_bo *),
- void *param)
+ void *param, bool use_cpu_for_update,
+ struct ttm_bo_global *glob)
{
unsigned i;
int r;
+ if (parent->bo->shadow) {
+ struct amdgpu_bo *shadow = parent->bo->shadow;
+
+ r = amdgpu_ttm_bind(&shadow->tbo, &shadow->tbo.mem);
+ if (r)
+ return r;
+ }
+
+ if (use_cpu_for_update) {
+ r = amdgpu_bo_kmap(parent->bo, NULL);
+ if (r)
+ return r;
+ }
+
if (!parent->entries)
return 0;
@@ -179,11 +192,18 @@ static int amdgpu_vm_validate_level(struct amdgpu_vm_pt *parent,
if (r)
return r;
+ spin_lock(&glob->lru_lock);
+ ttm_bo_move_to_lru_tail(&entry->bo->tbo);
+ if (entry->bo->shadow)
+ ttm_bo_move_to_lru_tail(&entry->bo->shadow->tbo);
+ spin_unlock(&glob->lru_lock);
+
/*
* Recurse into the sub directory. This is harmless because we
* have only a maximum of 5 layers.
*/
- r = amdgpu_vm_validate_level(entry, validate, param);
+ r = amdgpu_vm_validate_level(entry, validate, param,
+ use_cpu_for_update, glob);
if (r)
return r;
}
@@ -214,54 +234,12 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
if (num_evictions == vm->last_eviction_counter)
return 0;
- return amdgpu_vm_validate_level(&vm->root, validate, param);
-}
-
-/**
- * amdgpu_vm_move_level_in_lru - move one level of PT BOs to the LRU tail
- *
- * @adev: amdgpu device instance
- * @vm: vm providing the BOs
- *
- * Move the PT BOs to the tail of the LRU.
- */
-static void amdgpu_vm_move_level_in_lru(struct amdgpu_vm_pt *parent)
-{
- unsigned i;
-
- if (!parent->entries)
- return;
-
- for (i = 0; i <= parent->last_entry_used; ++i) {
- struct amdgpu_vm_pt *entry = &parent->entries[i];
-
- if (!entry->bo)
- continue;
-
- ttm_bo_move_to_lru_tail(&entry->bo->tbo);
- amdgpu_vm_move_level_in_lru(entry);
- }
+ return amdgpu_vm_validate_level(&vm->root, validate, param,
+ vm->use_cpu_for_update,
+ adev->mman.bdev.glob);
}
/**
- * amdgpu_vm_move_pt_bos_in_lru - move the PT BOs to the LRU tail
- *
- * @adev: amdgpu device instance
- * @vm: vm providing the BOs
- *
- * Move the PT BOs to the tail of the LRU.
- */
-void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev,
- struct amdgpu_vm *vm)
-{
- struct ttm_bo_global *glob = adev->mman.bdev.glob;
-
- spin_lock(&glob->lru_lock);
- amdgpu_vm_move_level_in_lru(&vm->root);
- spin_unlock(&glob->lru_lock);
-}
-
- /**
* amdgpu_vm_alloc_levels - allocate the PD/PT levels
*
* @adev: amdgpu_device pointer
@@ -282,6 +260,7 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev,
unsigned pt_idx, from, to;
int r;
u64 flags;
+ uint64_t init_value = 0;
if (!parent->entries) {
unsigned num_entries = amdgpu_vm_num_entries(adev, level);
@@ -315,6 +294,12 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev,
flags |= (AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
AMDGPU_GEM_CREATE_SHADOW);
+ if (vm->pte_support_ats) {
+ init_value = AMDGPU_PTE_SYSTEM;
+ if (level != adev->vm_manager.num_level - 1)
+ init_value |= AMDGPU_PDE_PTE;
+ }
+
/* walk over the address space and allocate the page tables */
for (pt_idx = from; pt_idx <= to; ++pt_idx) {
struct reservation_object *resv = vm->root.bo->tbo.resv;
@@ -327,10 +312,18 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev,
AMDGPU_GPU_PAGE_SIZE, true,
AMDGPU_GEM_DOMAIN_VRAM,
flags,
- NULL, resv, &pt);
+ NULL, resv, init_value, &pt);
if (r)
return r;
+ if (vm->use_cpu_for_update) {
+ r = amdgpu_bo_kmap(pt, NULL);
+ if (r) {
+ amdgpu_bo_unref(&pt);
+ return r;
+ }
+ }
+
/* Keep a reference to the root directory to avoid
* freeing them up in the wrong order.
*/
@@ -424,7 +417,7 @@ static int amdgpu_vm_grab_reserved_vmid_locked(struct amdgpu_vm *vm,
struct dma_fence *updates = sync->last_vm_update;
int r = 0;
struct dma_fence *flushed, *tmp;
- bool needs_flush = false;
+ bool needs_flush = vm->use_cpu_for_update;
flushed = id->flushed_updates;
if ((amdgpu_vm_had_gpu_reset(adev, id)) ||
@@ -545,11 +538,11 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
}
kfree(fences);
- job->vm_needs_flush = false;
+ job->vm_needs_flush = vm->use_cpu_for_update;
/* Check if we can use a VMID already assigned to this VM */
list_for_each_entry_reverse(id, &id_mgr->ids_lru, list) {
struct dma_fence *flushed;
- bool needs_flush = false;
+ bool needs_flush = vm->use_cpu_for_update;
/* Check all the prerequisites to using this VMID */
if (amdgpu_vm_had_gpu_reset(adev, id))
@@ -745,7 +738,7 @@ static bool amdgpu_vm_is_large_bar(struct amdgpu_device *adev)
*
* Emit a VM flush when it is necessary.
*/
-int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job)
+int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_pipe_sync)
{
struct amdgpu_device *adev = ring->adev;
unsigned vmhub = ring->funcs->vmhub;
@@ -767,12 +760,15 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job)
vm_flush_needed = true;
}
- if (!vm_flush_needed && !gds_switch_needed)
+ if (!vm_flush_needed && !gds_switch_needed && !need_pipe_sync)
return 0;
if (ring->funcs->init_cond_exec)
patch_offset = amdgpu_ring_init_cond_exec(ring);
+ if (need_pipe_sync)
+ amdgpu_ring_emit_pipeline_sync(ring);
+
if (ring->funcs->emit_vm_flush && vm_flush_needed) {
struct dma_fence *fence;
@@ -874,8 +870,8 @@ struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm,
{
struct amdgpu_bo_va *bo_va;
- list_for_each_entry(bo_va, &bo->va, bo_list) {
- if (bo_va->vm == vm) {
+ list_for_each_entry(bo_va, &bo->va, base.bo_list) {
+ if (bo_va->base.vm == vm) {
return bo_va;
}
}
@@ -981,6 +977,8 @@ static void amdgpu_vm_cpu_set_ptes(struct amdgpu_pte_update_params *params,
unsigned int i;
uint64_t value;
+ trace_amdgpu_vm_set_ptes(pe, addr, count, incr, flags);
+
for (i = 0; i < count; i++) {
value = params->pages_addr ?
amdgpu_vm_map_gart(params->pages_addr, addr) :
@@ -989,19 +987,16 @@ static void amdgpu_vm_cpu_set_ptes(struct amdgpu_pte_update_params *params,
i, value, flags);
addr += incr;
}
-
- /* Flush HDP */
- mb();
- amdgpu_gart_flush_gpu_tlb(params->adev, 0);
}
-static int amdgpu_vm_bo_wait(struct amdgpu_device *adev, struct amdgpu_bo *bo)
+static int amdgpu_vm_wait_pd(struct amdgpu_device *adev, struct amdgpu_vm *vm,
+ void *owner)
{
struct amdgpu_sync sync;
int r;
amdgpu_sync_create(&sync);
- amdgpu_sync_resv(adev, &sync, bo->tbo.resv, AMDGPU_FENCE_OWNER_VM);
+ amdgpu_sync_resv(adev, &sync, vm->root.bo->tbo.resv, owner);
r = amdgpu_sync_wait(&sync, true);
amdgpu_sync_free(&sync);
@@ -1042,23 +1037,14 @@ static int amdgpu_vm_update_level(struct amdgpu_device *adev,
params.adev = adev;
shadow = parent->bo->shadow;
- WARN_ON(vm->use_cpu_for_update && shadow);
- if (vm->use_cpu_for_update && !shadow) {
- r = amdgpu_bo_kmap(parent->bo, (void **)&pd_addr);
- if (r)
- return r;
- r = amdgpu_vm_bo_wait(adev, parent->bo);
- if (unlikely(r)) {
- amdgpu_bo_kunmap(parent->bo);
+ if (vm->use_cpu_for_update) {
+ pd_addr = (unsigned long)amdgpu_bo_kptr(parent->bo);
+ r = amdgpu_vm_wait_pd(adev, vm, AMDGPU_FENCE_OWNER_VM);
+ if (unlikely(r))
return r;
- }
+
params.func = amdgpu_vm_cpu_set_ptes;
} else {
- if (shadow) {
- r = amdgpu_ttm_bind(&shadow->tbo, &shadow->tbo.mem);
- if (r)
- return r;
- }
ring = container_of(vm->entity.sched, struct amdgpu_ring,
sched);
@@ -1094,21 +1080,14 @@ static int amdgpu_vm_update_level(struct amdgpu_device *adev,
if (bo == NULL)
continue;
- if (bo->shadow) {
- struct amdgpu_bo *pt_shadow = bo->shadow;
-
- r = amdgpu_ttm_bind(&pt_shadow->tbo,
- &pt_shadow->tbo.mem);
- if (r)
- return r;
- }
-
pt = amdgpu_bo_gpu_offset(bo);
pt = amdgpu_gart_get_vm_pde(adev, pt);
- if (parent->entries[pt_idx].addr == pt)
+ /* Don't update huge pages here */
+ if ((parent->entries[pt_idx].addr & AMDGPU_PDE_PTE) ||
+ parent->entries[pt_idx].addr == (pt | AMDGPU_PTE_VALID))
continue;
- parent->entries[pt_idx].addr = pt;
+ parent->entries[pt_idx].addr = pt | AMDGPU_PTE_VALID;
pde = pd_addr + pt_idx * 8;
if (((last_pde + 8 * count) != pde) ||
@@ -1146,28 +1125,29 @@ static int amdgpu_vm_update_level(struct amdgpu_device *adev,
count, incr, AMDGPU_PTE_VALID);
}
- if (params.func == amdgpu_vm_cpu_set_ptes)
- amdgpu_bo_kunmap(parent->bo);
- else if (params.ib->length_dw == 0) {
- amdgpu_job_free(job);
- } else {
- amdgpu_ring_pad_ib(ring, params.ib);
- amdgpu_sync_resv(adev, &job->sync, parent->bo->tbo.resv,
- AMDGPU_FENCE_OWNER_VM);
- if (shadow)
- amdgpu_sync_resv(adev, &job->sync, shadow->tbo.resv,
+ if (!vm->use_cpu_for_update) {
+ if (params.ib->length_dw == 0) {
+ amdgpu_job_free(job);
+ } else {
+ amdgpu_ring_pad_ib(ring, params.ib);
+ amdgpu_sync_resv(adev, &job->sync, parent->bo->tbo.resv,
AMDGPU_FENCE_OWNER_VM);
+ if (shadow)
+ amdgpu_sync_resv(adev, &job->sync,
+ shadow->tbo.resv,
+ AMDGPU_FENCE_OWNER_VM);
+
+ WARN_ON(params.ib->length_dw > ndw);
+ r = amdgpu_job_submit(job, ring, &vm->entity,
+ AMDGPU_FENCE_OWNER_VM, &fence);
+ if (r)
+ goto error_free;
- WARN_ON(params.ib->length_dw > ndw);
- r = amdgpu_job_submit(job, ring, &vm->entity,
- AMDGPU_FENCE_OWNER_VM, &fence);
- if (r)
- goto error_free;
-
- amdgpu_bo_fence(parent->bo, fence, true);
- dma_fence_put(vm->last_dir_update);
- vm->last_dir_update = dma_fence_get(fence);
- dma_fence_put(fence);
+ amdgpu_bo_fence(parent->bo, fence, true);
+ dma_fence_put(vm->last_dir_update);
+ vm->last_dir_update = dma_fence_get(fence);
+ dma_fence_put(fence);
+ }
}
/*
* Recurse into the subdirectories. This recursion is harmless because
@@ -1235,33 +1215,98 @@ int amdgpu_vm_update_directories(struct amdgpu_device *adev,
if (r)
amdgpu_vm_invalidate_level(&vm->root);
+ if (vm->use_cpu_for_update) {
+ /* Flush HDP */
+ mb();
+ amdgpu_gart_flush_gpu_tlb(adev, 0);
+ }
+
return r;
}
/**
- * amdgpu_vm_find_pt - find the page table for an address
+ * amdgpu_vm_find_entry - find the entry for an address
*
* @p: see amdgpu_pte_update_params definition
* @addr: virtual address in question
+ * @entry: resulting entry or NULL
+ * @parent: parent entry
*
- * Find the page table BO for a virtual address, return NULL when none found.
+ * Find the vm_pt entry and it's parent for the given address.
*/
-static struct amdgpu_bo *amdgpu_vm_get_pt(struct amdgpu_pte_update_params *p,
- uint64_t addr)
+void amdgpu_vm_get_entry(struct amdgpu_pte_update_params *p, uint64_t addr,
+ struct amdgpu_vm_pt **entry,
+ struct amdgpu_vm_pt **parent)
{
- struct amdgpu_vm_pt *entry = &p->vm->root;
unsigned idx, level = p->adev->vm_manager.num_level;
- while (entry->entries) {
+ *parent = NULL;
+ *entry = &p->vm->root;
+ while ((*entry)->entries) {
idx = addr >> (p->adev->vm_manager.block_size * level--);
- idx %= amdgpu_bo_size(entry->bo) / 8;
- entry = &entry->entries[idx];
+ idx %= amdgpu_bo_size((*entry)->bo) / 8;
+ *parent = *entry;
+ *entry = &(*entry)->entries[idx];
}
if (level)
- return NULL;
+ *entry = NULL;
+}
+
+/**
+ * amdgpu_vm_handle_huge_pages - handle updating the PD with huge pages
+ *
+ * @p: see amdgpu_pte_update_params definition
+ * @entry: vm_pt entry to check
+ * @parent: parent entry
+ * @nptes: number of PTEs updated with this operation
+ * @dst: destination address where the PTEs should point to
+ * @flags: access flags fro the PTEs
+ *
+ * Check if we can update the PD with a huge page.
+ */
+static void amdgpu_vm_handle_huge_pages(struct amdgpu_pte_update_params *p,
+ struct amdgpu_vm_pt *entry,
+ struct amdgpu_vm_pt *parent,
+ unsigned nptes, uint64_t dst,
+ uint64_t flags)
+{
+ bool use_cpu_update = (p->func == amdgpu_vm_cpu_set_ptes);
+ uint64_t pd_addr, pde;
+
+ /* In the case of a mixed PT the PDE must point to it*/
+ if (p->adev->asic_type < CHIP_VEGA10 ||
+ nptes != AMDGPU_VM_PTE_COUNT(p->adev) ||
+ p->func == amdgpu_vm_do_copy_ptes ||
+ !(flags & AMDGPU_PTE_VALID)) {
+
+ dst = amdgpu_bo_gpu_offset(entry->bo);
+ dst = amdgpu_gart_get_vm_pde(p->adev, dst);
+ flags = AMDGPU_PTE_VALID;
+ } else {
+ /* Set the huge page flag to stop scanning at this PDE */
+ flags |= AMDGPU_PDE_PTE;
+ }
+
+ if (entry->addr == (dst | flags))
+ return;
+
+ entry->addr = (dst | flags);
- return entry->bo;
+ if (use_cpu_update) {
+ pd_addr = (unsigned long)amdgpu_bo_kptr(parent->bo);
+ pde = pd_addr + (entry - parent->entries) * 8;
+ amdgpu_vm_cpu_set_ptes(p, pde, dst, 1, 0, flags);
+ } else {
+ if (parent->bo->shadow) {
+ pd_addr = amdgpu_bo_gpu_offset(parent->bo->shadow);
+ pde = pd_addr + (entry - parent->entries) * 8;
+ amdgpu_vm_do_set_ptes(p, pde, dst, 1, 0, flags);
+ }
+ pd_addr = amdgpu_bo_gpu_offset(parent->bo);
+ pde = pd_addr + (entry - parent->entries) * 8;
+ amdgpu_vm_do_set_ptes(p, pde, dst, 1, 0, flags);
+ }
}
/**
@@ -1287,49 +1332,44 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
uint64_t addr, pe_start;
struct amdgpu_bo *pt;
unsigned nptes;
- int r;
bool use_cpu_update = (params->func == amdgpu_vm_cpu_set_ptes);
-
/* walk over the address space and update the page tables */
- for (addr = start; addr < end; addr += nptes) {
- pt = amdgpu_vm_get_pt(params, addr);
- if (!pt) {
- pr_err("PT not found, aborting update_ptes\n");
- return -EINVAL;
- }
+ for (addr = start; addr < end; addr += nptes,
+ dst += nptes * AMDGPU_GPU_PAGE_SIZE) {
+ struct amdgpu_vm_pt *entry, *parent;
- if (params->shadow) {
- if (WARN_ONCE(use_cpu_update,
- "CPU VM update doesn't suuport shadow pages"))
- return 0;
-
- if (!pt->shadow)
- return 0;
- pt = pt->shadow;
- }
+ amdgpu_vm_get_entry(params, addr, &entry, &parent);
+ if (!entry)
+ return -ENOENT;
if ((addr & ~mask) == (end & ~mask))
nptes = end - addr;
else
nptes = AMDGPU_VM_PTE_COUNT(adev) - (addr & mask);
+ amdgpu_vm_handle_huge_pages(params, entry, parent,
+ nptes, dst, flags);
+ /* We don't need to update PTEs for huge pages */
+ if (entry->addr & AMDGPU_PDE_PTE)
+ continue;
+
+ pt = entry->bo;
if (use_cpu_update) {
- r = amdgpu_bo_kmap(pt, (void *)&pe_start);
- if (r)
- return r;
- } else
+ pe_start = (unsigned long)amdgpu_bo_kptr(pt);
+ } else {
+ if (pt->shadow) {
+ pe_start = amdgpu_bo_gpu_offset(pt->shadow);
+ pe_start += (addr & mask) * 8;
+ params->func(params, pe_start, dst, nptes,
+ AMDGPU_GPU_PAGE_SIZE, flags);
+ }
pe_start = amdgpu_bo_gpu_offset(pt);
+ }
pe_start += (addr & mask) * 8;
-
params->func(params, pe_start, dst, nptes,
AMDGPU_GPU_PAGE_SIZE, flags);
-
- dst += nptes * AMDGPU_GPU_PAGE_SIZE;
-
- if (use_cpu_update)
- amdgpu_bo_kunmap(pt);
}
return 0;
@@ -1370,10 +1410,9 @@ static int amdgpu_vm_frag_ptes(struct amdgpu_pte_update_params *params,
* Userspace can support this by aligning virtual base address and
* allocation size to the fragment size.
*/
-
- /* SI and newer are optimized for 64KB */
- uint64_t frag_flags = AMDGPU_PTE_FRAG(AMDGPU_LOG2_PAGES_PER_FRAG);
- uint64_t frag_align = 1 << AMDGPU_LOG2_PAGES_PER_FRAG;
+ unsigned pages_per_frag = params->adev->vm_manager.fragment_size;
+ uint64_t frag_flags = AMDGPU_PTE_FRAG(pages_per_frag);
+ uint64_t frag_align = 1 << pages_per_frag;
uint64_t frag_start = ALIGN(start, frag_align);
uint64_t frag_end = end & ~(frag_align - 1);
@@ -1445,6 +1484,10 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
params.vm = vm;
params.src = src;
+ /* sync to everything on unmapping */
+ if (!(flags & AMDGPU_PTE_VALID))
+ owner = AMDGPU_FENCE_OWNER_UNDEFINED;
+
if (vm->use_cpu_for_update) {
/* params.src is used as flag to indicate system Memory */
if (pages_addr)
@@ -1453,23 +1496,18 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
/* Wait for PT BOs to be free. PTs share the same resv. object
* as the root PD BO
*/
- r = amdgpu_vm_bo_wait(adev, vm->root.bo);
+ r = amdgpu_vm_wait_pd(adev, vm, owner);
if (unlikely(r))
return r;
params.func = amdgpu_vm_cpu_set_ptes;
params.pages_addr = pages_addr;
- params.shadow = false;
return amdgpu_vm_frag_ptes(&params, start, last + 1,
addr, flags);
}
ring = container_of(vm->entity.sched, struct amdgpu_ring, sched);
- /* sync to everything on unmapping */
- if (!(flags & AMDGPU_PTE_VALID))
- owner = AMDGPU_FENCE_OWNER_UNDEFINED;
-
nptes = last - start + 1;
/*
@@ -1481,6 +1519,9 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
/* padding, etc. */
ndw = 64;
+ /* one PDE write for each huge page */
+ ndw += ((nptes >> adev->vm_manager.block_size) + 1) * 6;
+
if (src) {
/* only copy commands needed */
ndw += ncmds * 7;
@@ -1542,11 +1583,6 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
if (r)
goto error_free;
- params.shadow = true;
- r = amdgpu_vm_frag_ptes(&params, start, last + 1, addr, flags);
- if (r)
- goto error_free;
- params.shadow = false;
r = amdgpu_vm_frag_ptes(&params, start, last + 1, addr, flags);
if (r)
goto error_free;
@@ -1565,6 +1601,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
error_free:
amdgpu_job_free(job);
+ amdgpu_vm_invalidate_level(&vm->root);
return r;
}
@@ -1687,7 +1724,8 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev,
struct amdgpu_bo_va *bo_va,
bool clear)
{
- struct amdgpu_vm *vm = bo_va->vm;
+ struct amdgpu_bo *bo = bo_va->base.bo;
+ struct amdgpu_vm *vm = bo_va->base.vm;
struct amdgpu_bo_va_mapping *mapping;
dma_addr_t *pages_addr = NULL;
uint64_t gtt_flags, flags;
@@ -1696,27 +1734,27 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev,
struct dma_fence *exclusive;
int r;
- if (clear || !bo_va->bo) {
+ if (clear || !bo_va->base.bo) {
mem = NULL;
nodes = NULL;
exclusive = NULL;
} else {
struct ttm_dma_tt *ttm;
- mem = &bo_va->bo->tbo.mem;
+ mem = &bo_va->base.bo->tbo.mem;
nodes = mem->mm_node;
if (mem->mem_type == TTM_PL_TT) {
- ttm = container_of(bo_va->bo->tbo.ttm, struct
- ttm_dma_tt, ttm);
+ ttm = container_of(bo_va->base.bo->tbo.ttm,
+ struct ttm_dma_tt, ttm);
pages_addr = ttm->dma_address;
}
- exclusive = reservation_object_get_excl(bo_va->bo->tbo.resv);
+ exclusive = reservation_object_get_excl(bo->tbo.resv);
}
- if (bo_va->bo) {
- flags = amdgpu_ttm_tt_pte_flags(adev, bo_va->bo->tbo.ttm, mem);
- gtt_flags = (amdgpu_ttm_is_bound(bo_va->bo->tbo.ttm) &&
- adev == amdgpu_ttm_adev(bo_va->bo->tbo.bdev)) ?
+ if (bo) {
+ flags = amdgpu_ttm_tt_pte_flags(adev, bo->tbo.ttm, mem);
+ gtt_flags = (amdgpu_ttm_is_bound(bo->tbo.ttm) &&
+ adev == amdgpu_ttm_adev(bo->tbo.bdev)) ?
flags : 0;
} else {
flags = 0x0;
@@ -1724,7 +1762,7 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev,
}
spin_lock(&vm->status_lock);
- if (!list_empty(&bo_va->vm_status))
+ if (!list_empty(&bo_va->base.vm_status))
list_splice_init(&bo_va->valids, &bo_va->invalids);
spin_unlock(&vm->status_lock);
@@ -1747,11 +1785,17 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev,
spin_lock(&vm->status_lock);
list_splice_init(&bo_va->invalids, &bo_va->valids);
- list_del_init(&bo_va->vm_status);
+ list_del_init(&bo_va->base.vm_status);
if (clear)
- list_add(&bo_va->vm_status, &vm->cleared);
+ list_add(&bo_va->base.vm_status, &vm->cleared);
spin_unlock(&vm->status_lock);
+ if (vm->use_cpu_for_update) {
+ /* Flush HDP */
+ mb();
+ amdgpu_gart_flush_gpu_tlb(adev, 0);
+ }
+
return 0;
}
@@ -1905,15 +1949,19 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
struct amdgpu_bo_va_mapping *mapping;
struct dma_fence *f = NULL;
int r;
+ uint64_t init_pte_value = 0;
while (!list_empty(&vm->freed)) {
mapping = list_first_entry(&vm->freed,
struct amdgpu_bo_va_mapping, list);
list_del(&mapping->list);
+ if (vm->pte_support_ats)
+ init_pte_value = AMDGPU_PTE_SYSTEM;
+
r = amdgpu_vm_bo_update_mapping(adev, NULL, 0, NULL, vm,
mapping->start, mapping->last,
- 0, 0, &f);
+ init_pte_value, 0, &f);
amdgpu_vm_free_mapping(adev, vm, mapping, f);
if (r) {
dma_fence_put(f);
@@ -1933,26 +1981,26 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
}
/**
- * amdgpu_vm_clear_invalids - clear invalidated BOs in the PT
+ * amdgpu_vm_clear_moved - clear moved BOs in the PT
*
* @adev: amdgpu_device pointer
* @vm: requested vm
*
- * Make sure all invalidated BOs are cleared in the PT.
+ * Make sure all moved BOs are cleared in the PT.
* Returns 0 for success.
*
* PTs have to be reserved and mutex must be locked!
*/
-int amdgpu_vm_clear_invalids(struct amdgpu_device *adev,
- struct amdgpu_vm *vm, struct amdgpu_sync *sync)
+int amdgpu_vm_clear_moved(struct amdgpu_device *adev, struct amdgpu_vm *vm,
+ struct amdgpu_sync *sync)
{
struct amdgpu_bo_va *bo_va = NULL;
int r = 0;
spin_lock(&vm->status_lock);
- while (!list_empty(&vm->invalidated)) {
- bo_va = list_first_entry(&vm->invalidated,
- struct amdgpu_bo_va, vm_status);
+ while (!list_empty(&vm->moved)) {
+ bo_va = list_first_entry(&vm->moved,
+ struct amdgpu_bo_va, base.vm_status);
spin_unlock(&vm->status_lock);
r = amdgpu_vm_bo_update(adev, bo_va, true);
@@ -1992,16 +2040,17 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev,
if (bo_va == NULL) {
return NULL;
}
- bo_va->vm = vm;
- bo_va->bo = bo;
+ bo_va->base.vm = vm;
+ bo_va->base.bo = bo;
+ INIT_LIST_HEAD(&bo_va->base.bo_list);
+ INIT_LIST_HEAD(&bo_va->base.vm_status);
+
bo_va->ref_count = 1;
- INIT_LIST_HEAD(&bo_va->bo_list);
INIT_LIST_HEAD(&bo_va->valids);
INIT_LIST_HEAD(&bo_va->invalids);
- INIT_LIST_HEAD(&bo_va->vm_status);
if (bo)
- list_add_tail(&bo_va->bo_list, &bo->va);
+ list_add_tail(&bo_va->base.bo_list, &bo->va);
return bo_va;
}
@@ -2026,7 +2075,8 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,
uint64_t size, uint64_t flags)
{
struct amdgpu_bo_va_mapping *mapping, *tmp;
- struct amdgpu_vm *vm = bo_va->vm;
+ struct amdgpu_bo *bo = bo_va->base.bo;
+ struct amdgpu_vm *vm = bo_va->base.vm;
uint64_t eaddr;
/* validate the parameters */
@@ -2037,7 +2087,7 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,
/* make sure object fit at this offset */
eaddr = saddr + size - 1;
if (saddr >= eaddr ||
- (bo_va->bo && offset + size > amdgpu_bo_size(bo_va->bo)))
+ (bo && offset + size > amdgpu_bo_size(bo)))
return -EINVAL;
saddr /= AMDGPU_GPU_PAGE_SIZE;
@@ -2047,7 +2097,7 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,
if (tmp) {
/* bo and tmp overlap, invalid addr */
dev_err(adev->dev, "bo %p va 0x%010Lx-0x%010Lx conflict with "
- "0x%010Lx-0x%010Lx\n", bo_va->bo, saddr, eaddr,
+ "0x%010Lx-0x%010Lx\n", bo, saddr, eaddr,
tmp->start, tmp->last + 1);
return -EINVAL;
}
@@ -2092,7 +2142,8 @@ int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev,
uint64_t size, uint64_t flags)
{
struct amdgpu_bo_va_mapping *mapping;
- struct amdgpu_vm *vm = bo_va->vm;
+ struct amdgpu_bo *bo = bo_va->base.bo;
+ struct amdgpu_vm *vm = bo_va->base.vm;
uint64_t eaddr;
int r;
@@ -2104,7 +2155,7 @@ int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev,
/* make sure object fit at this offset */
eaddr = saddr + size - 1;
if (saddr >= eaddr ||
- (bo_va->bo && offset + size > amdgpu_bo_size(bo_va->bo)))
+ (bo && offset + size > amdgpu_bo_size(bo)))
return -EINVAL;
/* Allocate all the needed memory */
@@ -2112,7 +2163,7 @@ int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev,
if (!mapping)
return -ENOMEM;
- r = amdgpu_vm_bo_clear_mappings(adev, bo_va->vm, saddr, size);
+ r = amdgpu_vm_bo_clear_mappings(adev, bo_va->base.vm, saddr, size);
if (r) {
kfree(mapping);
return r;
@@ -2152,7 +2203,7 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
uint64_t saddr)
{
struct amdgpu_bo_va_mapping *mapping;
- struct amdgpu_vm *vm = bo_va->vm;
+ struct amdgpu_vm *vm = bo_va->base.vm;
bool valid = true;
saddr /= AMDGPU_GPU_PAGE_SIZE;
@@ -2300,12 +2351,12 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
struct amdgpu_bo_va *bo_va)
{
struct amdgpu_bo_va_mapping *mapping, *next;
- struct amdgpu_vm *vm = bo_va->vm;
+ struct amdgpu_vm *vm = bo_va->base.vm;
- list_del(&bo_va->bo_list);
+ list_del(&bo_va->base.bo_list);
spin_lock(&vm->status_lock);
- list_del(&bo_va->vm_status);
+ list_del(&bo_va->base.vm_status);
spin_unlock(&vm->status_lock);
list_for_each_entry_safe(mapping, next, &bo_va->valids, list) {
@@ -2337,13 +2388,14 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev,
struct amdgpu_bo *bo)
{
- struct amdgpu_bo_va *bo_va;
+ struct amdgpu_vm_bo_base *bo_base;
- list_for_each_entry(bo_va, &bo->va, bo_list) {
- spin_lock(&bo_va->vm->status_lock);
- if (list_empty(&bo_va->vm_status))
- list_add(&bo_va->vm_status, &bo_va->vm->invalidated);
- spin_unlock(&bo_va->vm->status_lock);
+ list_for_each_entry(bo_base, &bo->va, bo_list) {
+ spin_lock(&bo_base->vm->status_lock);
+ if (list_empty(&bo_base->vm_status))
+ list_add(&bo_base->vm_status,
+ &bo_base->vm->moved);
+ spin_unlock(&bo_base->vm->status_lock);
}
}
@@ -2361,12 +2413,26 @@ static uint32_t amdgpu_vm_get_block_size(uint64_t vm_size)
}
/**
- * amdgpu_vm_adjust_size - adjust vm size and block size
+ * amdgpu_vm_set_fragment_size - adjust fragment size in PTE
+ *
+ * @adev: amdgpu_device pointer
+ * @fragment_size_default: the default fragment size if it's set auto
+ */
+void amdgpu_vm_set_fragment_size(struct amdgpu_device *adev, uint32_t fragment_size_default)
+{
+ if (amdgpu_vm_fragment_size == -1)
+ adev->vm_manager.fragment_size = fragment_size_default;
+ else
+ adev->vm_manager.fragment_size = amdgpu_vm_fragment_size;
+}
+
+/**
+ * amdgpu_vm_adjust_size - adjust vm size, block size and fragment size
*
* @adev: amdgpu_device pointer
* @vm_size: the default vm size if it's set auto
*/
-void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint64_t vm_size)
+void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint64_t vm_size, uint32_t fragment_size_default)
{
/* adjust vm size firstly */
if (amdgpu_vm_size == -1)
@@ -2381,8 +2447,11 @@ void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint64_t vm_size)
else
adev->vm_manager.block_size = amdgpu_vm_block_size;
- DRM_INFO("vm size is %llu GB, block size is %u-bit\n",
- adev->vm_manager.vm_size, adev->vm_manager.block_size);
+ amdgpu_vm_set_fragment_size(adev, fragment_size_default);
+
+ DRM_INFO("vm size is %llu GB, block size is %u-bit, fragment size is %u-bit\n",
+ adev->vm_manager.vm_size, adev->vm_manager.block_size,
+ adev->vm_manager.fragment_size);
}
/**
@@ -2404,13 +2473,14 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
struct amd_sched_rq *rq;
int r, i;
u64 flags;
+ uint64_t init_pde_value = 0;
vm->va = RB_ROOT;
vm->client_id = atomic64_inc_return(&adev->vm_manager.client_counter);
for (i = 0; i < AMDGPU_MAX_VMHUBS; i++)
vm->reserved_vmid[i] = NULL;
spin_lock_init(&vm->status_lock);
- INIT_LIST_HEAD(&vm->invalidated);
+ INIT_LIST_HEAD(&vm->moved);
INIT_LIST_HEAD(&vm->cleared);
INIT_LIST_HEAD(&vm->freed);
@@ -2425,10 +2495,17 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
if (r)
return r;
- if (vm_context == AMDGPU_VM_CONTEXT_COMPUTE)
+ vm->pte_support_ats = false;
+
+ if (vm_context == AMDGPU_VM_CONTEXT_COMPUTE) {
vm->use_cpu_for_update = !!(adev->vm_manager.vm_update_mode &
AMDGPU_VM_USE_CPU_FOR_COMPUTE);
- else
+
+ if (adev->asic_type == CHIP_RAVEN) {
+ vm->pte_support_ats = true;
+ init_pde_value = AMDGPU_PTE_SYSTEM | AMDGPU_PDE_PTE;
+ }
+ } else
vm->use_cpu_for_update = !!(adev->vm_manager.vm_update_mode &
AMDGPU_VM_USE_CPU_FOR_GFX);
DRM_DEBUG_DRIVER("VM update mode is %s\n",
@@ -2448,7 +2525,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
r = amdgpu_bo_create(adev, amdgpu_vm_bo_size(adev, 0), align, true,
AMDGPU_GEM_DOMAIN_VRAM,
flags,
- NULL, NULL, &vm->root.bo);
+ NULL, NULL, init_pde_value, &vm->root.bo);
if (r)
goto error_free_sched_entity;
@@ -2457,6 +2534,13 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
goto error_free_root;
vm->last_eviction_counter = atomic64_read(&adev->num_evictions);
+
+ if (vm->use_cpu_for_update) {
+ r = amdgpu_bo_kmap(vm->root.bo, NULL);
+ if (r)
+ goto error_free_root;
+ }
+
amdgpu_bo_unreserve(vm->root.bo);
return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index 936f158..ba6691b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -50,9 +50,6 @@ struct amdgpu_bo_list_entry;
/* PTBs (Page Table Blocks) need to be aligned to 32K */
#define AMDGPU_VM_PTB_ALIGN_SIZE 32768
-/* LOG2 number of continuous pages for the fragment field */
-#define AMDGPU_LOG2_PAGES_PER_FRAG 4
-
#define AMDGPU_PTE_VALID (1ULL << 0)
#define AMDGPU_PTE_SYSTEM (1ULL << 1)
#define AMDGPU_PTE_SNOOPED (1ULL << 2)
@@ -68,6 +65,9 @@ struct amdgpu_bo_list_entry;
/* TILED for VEGA10, reserved for older ASICs */
#define AMDGPU_PTE_PRT (1ULL << 51)
+/* PDE is handled as PTE for VEGA10 */
+#define AMDGPU_PDE_PTE (1ULL << 54)
+
/* VEGA10 only */
#define AMDGPU_PTE_MTYPE(a) ((uint64_t)a << 57)
#define AMDGPU_PTE_MTYPE_MASK AMDGPU_PTE_MTYPE(3ULL)
@@ -94,6 +94,18 @@ struct amdgpu_bo_list_entry;
#define AMDGPU_VM_USE_CPU_FOR_GFX (1 << 0)
#define AMDGPU_VM_USE_CPU_FOR_COMPUTE (1 << 1)
+/* base structure for tracking BO usage in a VM */
+struct amdgpu_vm_bo_base {
+ /* constant after initialization */
+ struct amdgpu_vm *vm;
+ struct amdgpu_bo *bo;
+
+ /* protected by bo being reserved */
+ struct list_head bo_list;
+
+ /* protected by spinlock */
+ struct list_head vm_status;
+};
struct amdgpu_vm_pt {
struct amdgpu_bo *bo;
@@ -112,7 +124,7 @@ struct amdgpu_vm {
spinlock_t status_lock;
/* BOs moved, but not yet updated in the PT */
- struct list_head invalidated;
+ struct list_head moved;
/* BOs cleared in the PT because of a move */
struct list_head cleared;
@@ -135,11 +147,12 @@ struct amdgpu_vm {
u64 client_id;
/* dedicated to vm */
struct amdgpu_vm_id *reserved_vmid[AMDGPU_MAX_VMHUBS];
- /* each VM will map on CSA */
- struct amdgpu_bo_va *csa_bo_va;
/* Flag to indicate if VM tables are updated by CPU or GPU (SDMA) */
bool use_cpu_for_update;
+
+ /* Flag to indicate ATS support from PTE for GFX9 */
+ bool pte_support_ats;
};
struct amdgpu_vm_id {
@@ -182,6 +195,7 @@ struct amdgpu_vm_manager {
uint32_t num_level;
uint64_t vm_size;
uint32_t block_size;
+ uint32_t fragment_size;
/* vram base address for page table entry */
u64 vram_base_offset;
/* vm pte handling */
@@ -214,15 +228,13 @@ void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm,
int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
int (*callback)(void *p, struct amdgpu_bo *bo),
void *param);
-void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev,
- struct amdgpu_vm *vm);
int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
struct amdgpu_vm *vm,
uint64_t saddr, uint64_t size);
int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
struct amdgpu_sync *sync, struct dma_fence *fence,
struct amdgpu_job *job);
-int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job);
+int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_pipe_sync);
void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vmhub,
unsigned vmid);
void amdgpu_vm_reset_all_ids(struct amdgpu_device *adev);
@@ -231,8 +243,8 @@ int amdgpu_vm_update_directories(struct amdgpu_device *adev,
int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
struct amdgpu_vm *vm,
struct dma_fence **fence);
-int amdgpu_vm_clear_invalids(struct amdgpu_device *adev, struct amdgpu_vm *vm,
- struct amdgpu_sync *sync);
+int amdgpu_vm_clear_moved(struct amdgpu_device *adev, struct amdgpu_vm *vm,
+ struct amdgpu_sync *sync);
int amdgpu_vm_bo_update(struct amdgpu_device *adev,
struct amdgpu_bo_va *bo_va,
bool clear);
@@ -259,7 +271,10 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
uint64_t saddr, uint64_t size);
void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
struct amdgpu_bo_va *bo_va);
-void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint64_t vm_size);
+void amdgpu_vm_set_fragment_size(struct amdgpu_device *adev,
+ uint32_t fragment_size_default);
+void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint64_t vm_size,
+ uint32_t fragment_size_default);
int amdgpu_vm_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);
bool amdgpu_vm_need_pipeline_sync(struct amdgpu_ring *ring,
struct amdgpu_job *job);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
index a2c59a0..26e9006 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
@@ -28,6 +28,8 @@
struct amdgpu_vram_mgr {
struct drm_mm mm;
spinlock_t lock;
+ atomic64_t usage;
+ atomic64_t vis_usage;
};
/**
@@ -79,6 +81,27 @@ static int amdgpu_vram_mgr_fini(struct ttm_mem_type_manager *man)
}
/**
+ * amdgpu_vram_mgr_vis_size - Calculate visible node size
+ *
+ * @adev: amdgpu device structure
+ * @node: MM node structure
+ *
+ * Calculate how many bytes of the MM node are inside visible VRAM
+ */
+static u64 amdgpu_vram_mgr_vis_size(struct amdgpu_device *adev,
+ struct drm_mm_node *node)
+{
+ uint64_t start = node->start << PAGE_SHIFT;
+ uint64_t end = (node->size + node->start) << PAGE_SHIFT;
+
+ if (start >= adev->mc.visible_vram_size)
+ return 0;
+
+ return (end > adev->mc.visible_vram_size ?
+ adev->mc.visible_vram_size : end) - start;
+}
+
+/**
* amdgpu_vram_mgr_new - allocate new ranges
*
* @man: TTM memory type manager
@@ -93,11 +116,13 @@ static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man,
const struct ttm_place *place,
struct ttm_mem_reg *mem)
{
+ struct amdgpu_device *adev = amdgpu_ttm_adev(man->bdev);
struct amdgpu_vram_mgr *mgr = man->priv;
struct drm_mm *mm = &mgr->mm;
struct drm_mm_node *nodes;
enum drm_mm_insert_mode mode;
unsigned long lpfn, num_nodes, pages_per_node, pages_left;
+ uint64_t usage = 0, vis_usage = 0;
unsigned i;
int r;
@@ -142,6 +167,9 @@ static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man,
if (unlikely(r))
goto error;
+ usage += nodes[i].size << PAGE_SHIFT;
+ vis_usage += amdgpu_vram_mgr_vis_size(adev, &nodes[i]);
+
/* Calculate a virtual BO start address to easily check if
* everything is CPU accessible.
*/
@@ -155,6 +183,9 @@ static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man,
}
spin_unlock(&mgr->lock);
+ atomic64_add(usage, &mgr->usage);
+ atomic64_add(vis_usage, &mgr->vis_usage);
+
mem->mm_node = nodes;
return 0;
@@ -181,8 +212,10 @@ error:
static void amdgpu_vram_mgr_del(struct ttm_mem_type_manager *man,
struct ttm_mem_reg *mem)
{
+ struct amdgpu_device *adev = amdgpu_ttm_adev(man->bdev);
struct amdgpu_vram_mgr *mgr = man->priv;
struct drm_mm_node *nodes = mem->mm_node;
+ uint64_t usage = 0, vis_usage = 0;
unsigned pages = mem->num_pages;
if (!mem->mm_node)
@@ -192,31 +225,67 @@ static void amdgpu_vram_mgr_del(struct ttm_mem_type_manager *man,
while (pages) {
pages -= nodes->size;
drm_mm_remove_node(nodes);
+ usage += nodes->size << PAGE_SHIFT;
+ vis_usage += amdgpu_vram_mgr_vis_size(adev, nodes);
++nodes;
}
spin_unlock(&mgr->lock);
+ atomic64_sub(usage, &mgr->usage);
+ atomic64_sub(vis_usage, &mgr->vis_usage);
+
kfree(mem->mm_node);
mem->mm_node = NULL;
}
/**
+ * amdgpu_vram_mgr_usage - how many bytes are used in this domain
+ *
+ * @man: TTM memory type manager
+ *
+ * Returns how many bytes are used in this domain.
+ */
+uint64_t amdgpu_vram_mgr_usage(struct ttm_mem_type_manager *man)
+{
+ struct amdgpu_vram_mgr *mgr = man->priv;
+
+ return atomic64_read(&mgr->usage);
+}
+
+/**
+ * amdgpu_vram_mgr_vis_usage - how many bytes are used in the visible part
+ *
+ * @man: TTM memory type manager
+ *
+ * Returns how many bytes are used in the visible part of VRAM
+ */
+uint64_t amdgpu_vram_mgr_vis_usage(struct ttm_mem_type_manager *man)
+{
+ struct amdgpu_vram_mgr *mgr = man->priv;
+
+ return atomic64_read(&mgr->vis_usage);
+}
+
+/**
* amdgpu_vram_mgr_debug - dump VRAM table
*
* @man: TTM memory type manager
- * @prefix: text prefix
+ * @printer: DRM printer to use
*
* Dump the table content using printk.
*/
static void amdgpu_vram_mgr_debug(struct ttm_mem_type_manager *man,
- const char *prefix)
+ struct drm_printer *printer)
{
struct amdgpu_vram_mgr *mgr = man->priv;
- struct drm_printer p = drm_debug_printer(prefix);
spin_lock(&mgr->lock);
- drm_mm_print(&mgr->mm, &p);
+ drm_mm_print(&mgr->mm, printer);
spin_unlock(&mgr->lock);
+
+ drm_printf(printer, "man size:%llu pages, ram usage:%lluMB, vis usage:%lluMB\n",
+ man->size, amdgpu_vram_mgr_usage(man) >> 20,
+ amdgpu_vram_mgr_vis_usage(man) >> 20);
}
const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func = {
diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c
index 37a499a..567c4a5 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik.c
@@ -1824,21 +1824,14 @@ static int cik_common_suspend(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- amdgpu_amdkfd_suspend(adev);
-
return cik_common_hw_fini(adev);
}
static int cik_common_resume(void *handle)
{
- int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- r = cik_common_hw_init(adev);
- if (r)
- return r;
-
- return amdgpu_amdkfd_resume(adev);
+ return cik_common_hw_init(adev);
}
static bool cik_common_is_idle(void *handle)
diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
index c216e16..f508f4d 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
@@ -342,6 +342,63 @@ static void cik_sdma_rlc_stop(struct amdgpu_device *adev)
}
/**
+ * cik_ctx_switch_enable - stop the async dma engines context switch
+ *
+ * @adev: amdgpu_device pointer
+ * @enable: enable/disable the DMA MEs context switch.
+ *
+ * Halt or unhalt the async dma engines context switch (VI).
+ */
+static void cik_ctx_switch_enable(struct amdgpu_device *adev, bool enable)
+{
+ u32 f32_cntl, phase_quantum = 0;
+ int i;
+
+ if (amdgpu_sdma_phase_quantum) {
+ unsigned value = amdgpu_sdma_phase_quantum;
+ unsigned unit = 0;
+
+ while (value > (SDMA0_PHASE0_QUANTUM__VALUE_MASK >>
+ SDMA0_PHASE0_QUANTUM__VALUE__SHIFT)) {
+ value = (value + 1) >> 1;
+ unit++;
+ }
+ if (unit > (SDMA0_PHASE0_QUANTUM__UNIT_MASK >>
+ SDMA0_PHASE0_QUANTUM__UNIT__SHIFT)) {
+ value = (SDMA0_PHASE0_QUANTUM__VALUE_MASK >>
+ SDMA0_PHASE0_QUANTUM__VALUE__SHIFT);
+ unit = (SDMA0_PHASE0_QUANTUM__UNIT_MASK >>
+ SDMA0_PHASE0_QUANTUM__UNIT__SHIFT);
+ WARN_ONCE(1,
+ "clamping sdma_phase_quantum to %uK clock cycles\n",
+ value << unit);
+ }
+ phase_quantum =
+ value << SDMA0_PHASE0_QUANTUM__VALUE__SHIFT |
+ unit << SDMA0_PHASE0_QUANTUM__UNIT__SHIFT;
+ }
+
+ for (i = 0; i < adev->sdma.num_instances; i++) {
+ f32_cntl = RREG32(mmSDMA0_CNTL + sdma_offsets[i]);
+ if (enable) {
+ f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
+ AUTO_CTXSW_ENABLE, 1);
+ if (amdgpu_sdma_phase_quantum) {
+ WREG32(mmSDMA0_PHASE0_QUANTUM + sdma_offsets[i],
+ phase_quantum);
+ WREG32(mmSDMA0_PHASE1_QUANTUM + sdma_offsets[i],
+ phase_quantum);
+ }
+ } else {
+ f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
+ AUTO_CTXSW_ENABLE, 0);
+ }
+
+ WREG32(mmSDMA0_CNTL + sdma_offsets[i], f32_cntl);
+ }
+}
+
+/**
* cik_sdma_enable - stop the async dma engines
*
* @adev: amdgpu_device pointer
@@ -537,6 +594,8 @@ static int cik_sdma_start(struct amdgpu_device *adev)
/* halt the engine before programing */
cik_sdma_enable(adev, false);
+ /* enable sdma ring preemption */
+ cik_ctx_switch_enable(adev, true);
/* start the gfx rings and rlc compute queues */
r = cik_sdma_gfx_resume(adev);
@@ -984,6 +1043,7 @@ static int cik_sdma_hw_fini(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ cik_ctx_switch_enable(adev, false);
cik_sdma_enable(adev, false);
return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
index 9f78c03..4e519dc 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
@@ -484,134 +484,6 @@ static bool dce_v10_0_is_display_hung(struct amdgpu_device *adev)
return true;
}
-static void dce_v10_0_stop_mc_access(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
-{
- u32 crtc_enabled, tmp;
- int i;
-
- save->vga_render_control = RREG32(mmVGA_RENDER_CONTROL);
- save->vga_hdp_control = RREG32(mmVGA_HDP_CONTROL);
-
- /* disable VGA render */
- tmp = RREG32(mmVGA_RENDER_CONTROL);
- tmp = REG_SET_FIELD(tmp, VGA_RENDER_CONTROL, VGA_VSTATUS_CNTL, 0);
- WREG32(mmVGA_RENDER_CONTROL, tmp);
-
- /* blank the display controllers */
- for (i = 0; i < adev->mode_info.num_crtc; i++) {
- crtc_enabled = REG_GET_FIELD(RREG32(mmCRTC_CONTROL + crtc_offsets[i]),
- CRTC_CONTROL, CRTC_MASTER_EN);
- if (crtc_enabled) {
-#if 0
- u32 frame_count;
- int j;
-
- save->crtc_enabled[i] = true;
- tmp = RREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i]);
- if (REG_GET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN) == 0) {
- amdgpu_display_vblank_wait(adev, i);
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1);
- tmp = REG_SET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN, 1);
- WREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
- }
- /* wait for the next frame */
- frame_count = amdgpu_display_vblank_get_counter(adev, i);
- for (j = 0; j < adev->usec_timeout; j++) {
- if (amdgpu_display_vblank_get_counter(adev, i) != frame_count)
- break;
- udelay(1);
- }
- tmp = RREG32(mmGRPH_UPDATE + crtc_offsets[i]);
- if (REG_GET_FIELD(tmp, GRPH_UPDATE, GRPH_UPDATE_LOCK) == 0) {
- tmp = REG_SET_FIELD(tmp, GRPH_UPDATE, GRPH_UPDATE_LOCK, 1);
- WREG32(mmGRPH_UPDATE + crtc_offsets[i], tmp);
- }
- tmp = RREG32(mmMASTER_UPDATE_LOCK + crtc_offsets[i]);
- if (REG_GET_FIELD(tmp, MASTER_UPDATE_LOCK, MASTER_UPDATE_LOCK) == 0) {
- tmp = REG_SET_FIELD(tmp, MASTER_UPDATE_LOCK, MASTER_UPDATE_LOCK, 1);
- WREG32(mmMASTER_UPDATE_LOCK + crtc_offsets[i], tmp);
- }
-#else
- /* XXX this is a hack to avoid strange behavior with EFI on certain systems */
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1);
- tmp = RREG32(mmCRTC_CONTROL + crtc_offsets[i]);
- tmp = REG_SET_FIELD(tmp, CRTC_CONTROL, CRTC_MASTER_EN, 0);
- WREG32(mmCRTC_CONTROL + crtc_offsets[i], tmp);
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
- save->crtc_enabled[i] = false;
- /* ***** */
-#endif
- } else {
- save->crtc_enabled[i] = false;
- }
- }
-}
-
-static void dce_v10_0_resume_mc_access(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
-{
- u32 tmp, frame_count;
- int i, j;
-
- /* update crtc base addresses */
- for (i = 0; i < adev->mode_info.num_crtc; i++) {
- WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i],
- upper_32_bits(adev->mc.vram_start));
- WREG32(mmGRPH_SECONDARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i],
- upper_32_bits(adev->mc.vram_start));
- WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i],
- (u32)adev->mc.vram_start);
- WREG32(mmGRPH_SECONDARY_SURFACE_ADDRESS + crtc_offsets[i],
- (u32)adev->mc.vram_start);
-
- if (save->crtc_enabled[i]) {
- tmp = RREG32(mmMASTER_UPDATE_MODE + crtc_offsets[i]);
- if (REG_GET_FIELD(tmp, MASTER_UPDATE_MODE, MASTER_UPDATE_MODE) != 0) {
- tmp = REG_SET_FIELD(tmp, MASTER_UPDATE_MODE, MASTER_UPDATE_MODE, 0);
- WREG32(mmMASTER_UPDATE_MODE + crtc_offsets[i], tmp);
- }
- tmp = RREG32(mmGRPH_UPDATE + crtc_offsets[i]);
- if (REG_GET_FIELD(tmp, GRPH_UPDATE, GRPH_UPDATE_LOCK)) {
- tmp = REG_SET_FIELD(tmp, GRPH_UPDATE, GRPH_UPDATE_LOCK, 0);
- WREG32(mmGRPH_UPDATE + crtc_offsets[i], tmp);
- }
- tmp = RREG32(mmMASTER_UPDATE_LOCK + crtc_offsets[i]);
- if (REG_GET_FIELD(tmp, MASTER_UPDATE_LOCK, MASTER_UPDATE_LOCK)) {
- tmp = REG_SET_FIELD(tmp, MASTER_UPDATE_LOCK, MASTER_UPDATE_LOCK, 0);
- WREG32(mmMASTER_UPDATE_LOCK + crtc_offsets[i], tmp);
- }
- for (j = 0; j < adev->usec_timeout; j++) {
- tmp = RREG32(mmGRPH_UPDATE + crtc_offsets[i]);
- if (REG_GET_FIELD(tmp, GRPH_UPDATE, GRPH_SURFACE_UPDATE_PENDING) == 0)
- break;
- udelay(1);
- }
- tmp = RREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i]);
- tmp = REG_SET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN, 0);
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1);
- WREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
- /* wait for the next frame */
- frame_count = amdgpu_display_vblank_get_counter(adev, i);
- for (j = 0; j < adev->usec_timeout; j++) {
- if (amdgpu_display_vblank_get_counter(adev, i) != frame_count)
- break;
- udelay(1);
- }
- }
- }
-
- WREG32(mmVGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(adev->mc.vram_start));
- WREG32(mmVGA_MEMORY_BASE_ADDRESS, lower_32_bits(adev->mc.vram_start));
-
- /* Unlock vga access */
- WREG32(mmVGA_HDP_CONTROL, save->vga_hdp_control);
- mdelay(1);
- WREG32(mmVGA_RENDER_CONTROL, save->vga_render_control);
-}
-
static void dce_v10_0_set_vga_render_state(struct amdgpu_device *adev,
bool render)
{
@@ -1867,7 +1739,7 @@ static void dce_v10_0_afmt_setmode(struct drm_encoder *encoder,
dce_v10_0_audio_write_sad_regs(encoder);
dce_v10_0_audio_write_latency_fields(encoder, mode);
- err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+ err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
if (err < 0) {
DRM_ERROR("failed to setup AVI infoframe: %zd\n", err);
return;
@@ -2267,6 +2139,7 @@ static void dce_v10_0_crtc_load_lut(struct drm_crtc *crtc)
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct amdgpu_device *adev = dev->dev_private;
+ u16 *r, *g, *b;
int i;
u32 tmp;
@@ -2304,11 +2177,14 @@ static void dce_v10_0_crtc_load_lut(struct drm_crtc *crtc)
WREG32(mmDC_LUT_WRITE_EN_MASK + amdgpu_crtc->crtc_offset, 0x00000007);
WREG32(mmDC_LUT_RW_INDEX + amdgpu_crtc->crtc_offset, 0);
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
for (i = 0; i < 256; i++) {
WREG32(mmDC_LUT_30_COLOR + amdgpu_crtc->crtc_offset,
- (amdgpu_crtc->lut_r[i] << 20) |
- (amdgpu_crtc->lut_g[i] << 10) |
- (amdgpu_crtc->lut_b[i] << 0));
+ ((*r++ & 0xffc0) << 14) |
+ ((*g++ & 0xffc0) << 4) |
+ (*b++ >> 6));
}
tmp = RREG32(mmDEGAMMA_CONTROL + amdgpu_crtc->crtc_offset);
@@ -2555,7 +2431,7 @@ static int dce_v10_0_crtc_cursor_set2(struct drm_crtc *crtc,
aobj = gem_to_amdgpu_bo(obj);
ret = amdgpu_bo_reserve(aobj, false);
if (ret != 0) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -2563,7 +2439,7 @@ static int dce_v10_0_crtc_cursor_set2(struct drm_crtc *crtc,
amdgpu_bo_unreserve(aobj);
if (ret) {
DRM_ERROR("Failed to pin new cursor BO (%d)\n", ret);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -2597,7 +2473,7 @@ unpin:
amdgpu_bo_unpin(aobj);
amdgpu_bo_unreserve(aobj);
}
- drm_gem_object_unreference_unlocked(amdgpu_crtc->cursor_bo);
+ drm_gem_object_put_unlocked(amdgpu_crtc->cursor_bo);
}
amdgpu_crtc->cursor_bo = obj;
@@ -2624,15 +2500,6 @@ static int dce_v10_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
u16 *blue, uint32_t size,
struct drm_modeset_acquire_ctx *ctx)
{
- struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
- int i;
-
- /* userspace palettes are always correct as is */
- for (i = 0; i < size; i++) {
- amdgpu_crtc->lut_r[i] = red[i] >> 6;
- amdgpu_crtc->lut_g[i] = green[i] >> 6;
- amdgpu_crtc->lut_b[i] = blue[i] >> 6;
- }
dce_v10_0_crtc_load_lut(crtc);
return 0;
@@ -2844,14 +2711,12 @@ static const struct drm_crtc_helper_funcs dce_v10_0_crtc_helper_funcs = {
.mode_set_base_atomic = dce_v10_0_crtc_set_base_atomic,
.prepare = dce_v10_0_crtc_prepare,
.commit = dce_v10_0_crtc_commit,
- .load_lut = dce_v10_0_crtc_load_lut,
.disable = dce_v10_0_crtc_disable,
};
static int dce_v10_0_crtc_init(struct amdgpu_device *adev, int index)
{
struct amdgpu_crtc *amdgpu_crtc;
- int i;
amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) +
(AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
@@ -2869,12 +2734,6 @@ static int dce_v10_0_crtc_init(struct amdgpu_device *adev, int index)
adev->ddev->mode_config.cursor_width = amdgpu_crtc->max_cursor_width;
adev->ddev->mode_config.cursor_height = amdgpu_crtc->max_cursor_height;
- for (i = 0; i < 256; i++) {
- amdgpu_crtc->lut_r[i] = i << 2;
- amdgpu_crtc->lut_g[i] = i << 2;
- amdgpu_crtc->lut_b[i] = i << 2;
- }
-
switch (amdgpu_crtc->crtc_id) {
case 0:
default:
@@ -3025,6 +2884,8 @@ static int dce_v10_0_hw_init(void *handle)
dce_v10_0_init_golden_registers(adev);
+ /* disable vga render */
+ dce_v10_0_set_vga_render_state(adev, false);
/* init dig PHYs, disp eng pll */
amdgpu_atombios_encoder_init_dig(adev);
amdgpu_atombios_crtc_set_disp_eng_pll(adev, adev->clock.default_dispclk);
@@ -3737,7 +3598,6 @@ static void dce_v10_0_encoder_add(struct amdgpu_device *adev,
}
static const struct amdgpu_display_funcs dce_v10_0_display_funcs = {
- .set_vga_render_state = &dce_v10_0_set_vga_render_state,
.bandwidth_update = &dce_v10_0_bandwidth_update,
.vblank_get_counter = &dce_v10_0_vblank_get_counter,
.vblank_wait = &dce_v10_0_vblank_wait,
@@ -3750,8 +3610,6 @@ static const struct amdgpu_display_funcs dce_v10_0_display_funcs = {
.page_flip_get_scanoutpos = &dce_v10_0_crtc_get_scanoutpos,
.add_encoder = &dce_v10_0_encoder_add,
.add_connector = &amdgpu_connector_add,
- .stop_mc_access = &dce_v10_0_stop_mc_access,
- .resume_mc_access = &dce_v10_0_resume_mc_access,
};
static void dce_v10_0_set_display_funcs(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
index 4bcf01d..11edc75 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
@@ -499,79 +499,6 @@ static bool dce_v11_0_is_display_hung(struct amdgpu_device *adev)
return true;
}
-static void dce_v11_0_stop_mc_access(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
-{
- u32 crtc_enabled, tmp;
- int i;
-
- save->vga_render_control = RREG32(mmVGA_RENDER_CONTROL);
- save->vga_hdp_control = RREG32(mmVGA_HDP_CONTROL);
-
- /* disable VGA render */
- tmp = RREG32(mmVGA_RENDER_CONTROL);
- tmp = REG_SET_FIELD(tmp, VGA_RENDER_CONTROL, VGA_VSTATUS_CNTL, 0);
- WREG32(mmVGA_RENDER_CONTROL, tmp);
-
- /* blank the display controllers */
- for (i = 0; i < adev->mode_info.num_crtc; i++) {
- crtc_enabled = REG_GET_FIELD(RREG32(mmCRTC_CONTROL + crtc_offsets[i]),
- CRTC_CONTROL, CRTC_MASTER_EN);
- if (crtc_enabled) {
-#if 1
- save->crtc_enabled[i] = true;
- tmp = RREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i]);
- if (REG_GET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN) == 0) {
- /*it is correct only for RGB ; black is 0*/
- WREG32(mmCRTC_BLANK_DATA_COLOR + crtc_offsets[i], 0);
- tmp = REG_SET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN, 1);
- WREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
- }
-#else
- /* XXX this is a hack to avoid strange behavior with EFI on certain systems */
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1);
- tmp = RREG32(mmCRTC_CONTROL + crtc_offsets[i]);
- tmp = REG_SET_FIELD(tmp, CRTC_CONTROL, CRTC_MASTER_EN, 0);
- WREG32(mmCRTC_CONTROL + crtc_offsets[i], tmp);
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
- save->crtc_enabled[i] = false;
- /* ***** */
-#endif
- } else {
- save->crtc_enabled[i] = false;
- }
- }
-}
-
-static void dce_v11_0_resume_mc_access(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
-{
- u32 tmp;
- int i;
-
- /* update crtc base addresses */
- for (i = 0; i < adev->mode_info.num_crtc; i++) {
- WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i],
- upper_32_bits(adev->mc.vram_start));
- WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i],
- (u32)adev->mc.vram_start);
-
- if (save->crtc_enabled[i]) {
- tmp = RREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i]);
- tmp = REG_SET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN, 0);
- WREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
- }
- }
-
- WREG32(mmVGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(adev->mc.vram_start));
- WREG32(mmVGA_MEMORY_BASE_ADDRESS, lower_32_bits(adev->mc.vram_start));
-
- /* Unlock vga access */
- WREG32(mmVGA_HDP_CONTROL, save->vga_hdp_control);
- mdelay(1);
- WREG32(mmVGA_RENDER_CONTROL, save->vga_render_control);
-}
-
static void dce_v11_0_set_vga_render_state(struct amdgpu_device *adev,
bool render)
{
@@ -1851,7 +1778,7 @@ static void dce_v11_0_afmt_setmode(struct drm_encoder *encoder,
dce_v11_0_audio_write_sad_regs(encoder);
dce_v11_0_audio_write_latency_fields(encoder, mode);
- err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+ err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
if (err < 0) {
DRM_ERROR("failed to setup AVI infoframe: %zd\n", err);
return;
@@ -2251,6 +2178,7 @@ static void dce_v11_0_crtc_load_lut(struct drm_crtc *crtc)
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct amdgpu_device *adev = dev->dev_private;
+ u16 *r, *g, *b;
int i;
u32 tmp;
@@ -2282,11 +2210,14 @@ static void dce_v11_0_crtc_load_lut(struct drm_crtc *crtc)
WREG32(mmDC_LUT_WRITE_EN_MASK + amdgpu_crtc->crtc_offset, 0x00000007);
WREG32(mmDC_LUT_RW_INDEX + amdgpu_crtc->crtc_offset, 0);
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
for (i = 0; i < 256; i++) {
WREG32(mmDC_LUT_30_COLOR + amdgpu_crtc->crtc_offset,
- (amdgpu_crtc->lut_r[i] << 20) |
- (amdgpu_crtc->lut_g[i] << 10) |
- (amdgpu_crtc->lut_b[i] << 0));
+ ((*r++ & 0xffc0) << 14) |
+ ((*g++ & 0xffc0) << 4) |
+ (*b++ >> 6));
}
tmp = RREG32(mmDEGAMMA_CONTROL + amdgpu_crtc->crtc_offset);
@@ -2575,7 +2506,7 @@ static int dce_v11_0_crtc_cursor_set2(struct drm_crtc *crtc,
aobj = gem_to_amdgpu_bo(obj);
ret = amdgpu_bo_reserve(aobj, false);
if (ret != 0) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -2583,7 +2514,7 @@ static int dce_v11_0_crtc_cursor_set2(struct drm_crtc *crtc,
amdgpu_bo_unreserve(aobj);
if (ret) {
DRM_ERROR("Failed to pin new cursor BO (%d)\n", ret);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -2617,7 +2548,7 @@ unpin:
amdgpu_bo_unpin(aobj);
amdgpu_bo_unreserve(aobj);
}
- drm_gem_object_unreference_unlocked(amdgpu_crtc->cursor_bo);
+ drm_gem_object_put_unlocked(amdgpu_crtc->cursor_bo);
}
amdgpu_crtc->cursor_bo = obj;
@@ -2644,15 +2575,6 @@ static int dce_v11_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
u16 *blue, uint32_t size,
struct drm_modeset_acquire_ctx *ctx)
{
- struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
- int i;
-
- /* userspace palettes are always correct as is */
- for (i = 0; i < size; i++) {
- amdgpu_crtc->lut_r[i] = red[i] >> 6;
- amdgpu_crtc->lut_g[i] = green[i] >> 6;
- amdgpu_crtc->lut_b[i] = blue[i] >> 6;
- }
dce_v11_0_crtc_load_lut(crtc);
return 0;
@@ -2892,14 +2814,12 @@ static const struct drm_crtc_helper_funcs dce_v11_0_crtc_helper_funcs = {
.mode_set_base_atomic = dce_v11_0_crtc_set_base_atomic,
.prepare = dce_v11_0_crtc_prepare,
.commit = dce_v11_0_crtc_commit,
- .load_lut = dce_v11_0_crtc_load_lut,
.disable = dce_v11_0_crtc_disable,
};
static int dce_v11_0_crtc_init(struct amdgpu_device *adev, int index)
{
struct amdgpu_crtc *amdgpu_crtc;
- int i;
amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) +
(AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
@@ -2917,12 +2837,6 @@ static int dce_v11_0_crtc_init(struct amdgpu_device *adev, int index)
adev->ddev->mode_config.cursor_width = amdgpu_crtc->max_cursor_width;
adev->ddev->mode_config.cursor_height = amdgpu_crtc->max_cursor_height;
- for (i = 0; i < 256; i++) {
- amdgpu_crtc->lut_r[i] = i << 2;
- amdgpu_crtc->lut_g[i] = i << 2;
- amdgpu_crtc->lut_b[i] = i << 2;
- }
-
switch (amdgpu_crtc->crtc_id) {
case 0:
default:
@@ -3086,6 +3000,8 @@ static int dce_v11_0_hw_init(void *handle)
dce_v11_0_init_golden_registers(adev);
+ /* disable vga render */
+ dce_v11_0_set_vga_render_state(adev, false);
/* init dig PHYs, disp eng pll */
amdgpu_atombios_crtc_powergate_init(adev);
amdgpu_atombios_encoder_init_dig(adev);
@@ -3806,7 +3722,6 @@ static void dce_v11_0_encoder_add(struct amdgpu_device *adev,
}
static const struct amdgpu_display_funcs dce_v11_0_display_funcs = {
- .set_vga_render_state = &dce_v11_0_set_vga_render_state,
.bandwidth_update = &dce_v11_0_bandwidth_update,
.vblank_get_counter = &dce_v11_0_vblank_get_counter,
.vblank_wait = &dce_v11_0_vblank_wait,
@@ -3819,8 +3734,6 @@ static const struct amdgpu_display_funcs dce_v11_0_display_funcs = {
.page_flip_get_scanoutpos = &dce_v11_0_crtc_get_scanoutpos,
.add_encoder = &dce_v11_0_encoder_add,
.add_connector = &amdgpu_connector_add,
- .stop_mc_access = &dce_v11_0_stop_mc_access,
- .resume_mc_access = &dce_v11_0_resume_mc_access,
};
static void dce_v11_0_set_display_funcs(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
index fd134a4..a51e35f 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
@@ -42,6 +42,7 @@
#include "dce/dce_6_0_d.h"
#include "dce/dce_6_0_sh_mask.h"
#include "gca/gfx_7_2_enum.h"
+#include "dce_v6_0.h"
#include "si_enums.h"
static void dce_v6_0_set_display_funcs(struct amdgpu_device *adev);
@@ -392,117 +393,6 @@ static u32 dce_v6_0_hpd_get_gpio_reg(struct amdgpu_device *adev)
return mmDC_GPIO_HPD_A;
}
-static u32 evergreen_get_vblank_counter(struct amdgpu_device* adev, int crtc)
-{
- if (crtc >= adev->mode_info.num_crtc)
- return 0;
- else
- return RREG32(mmCRTC_STATUS_FRAME_COUNT + crtc_offsets[crtc]);
-}
-
-static void dce_v6_0_stop_mc_access(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
-{
- u32 crtc_enabled, tmp, frame_count;
- int i, j;
-
- save->vga_render_control = RREG32(mmVGA_RENDER_CONTROL);
- save->vga_hdp_control = RREG32(mmVGA_HDP_CONTROL);
-
- /* disable VGA render */
- WREG32(mmVGA_RENDER_CONTROL, 0);
-
- /* blank the display controllers */
- for (i = 0; i < adev->mode_info.num_crtc; i++) {
- crtc_enabled = RREG32(mmCRTC_CONTROL + crtc_offsets[i]) & CRTC_CONTROL__CRTC_MASTER_EN_MASK;
- if (crtc_enabled) {
- save->crtc_enabled[i] = true;
- tmp = RREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i]);
-
- if (!(tmp & CRTC_BLANK_CONTROL__CRTC_BLANK_DATA_EN_MASK)) {
- dce_v6_0_vblank_wait(adev, i);
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1);
- tmp |= CRTC_BLANK_CONTROL__CRTC_BLANK_DATA_EN_MASK;
- WREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
- }
- /* wait for the next frame */
- frame_count = evergreen_get_vblank_counter(adev, i);
- for (j = 0; j < adev->usec_timeout; j++) {
- if (evergreen_get_vblank_counter(adev, i) != frame_count)
- break;
- udelay(1);
- }
-
- /* XXX this is a hack to avoid strange behavior with EFI on certain systems */
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1);
- tmp = RREG32(mmCRTC_CONTROL + crtc_offsets[i]);
- tmp &= ~CRTC_CONTROL__CRTC_MASTER_EN_MASK;
- WREG32(mmCRTC_CONTROL + crtc_offsets[i], tmp);
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
- save->crtc_enabled[i] = false;
- /* ***** */
- } else {
- save->crtc_enabled[i] = false;
- }
- }
-}
-
-static void dce_v6_0_resume_mc_access(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
-{
- u32 tmp;
- int i, j;
-
- /* update crtc base addresses */
- for (i = 0; i < adev->mode_info.num_crtc; i++) {
- WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i],
- upper_32_bits(adev->mc.vram_start));
- WREG32(mmGRPH_SECONDARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i],
- upper_32_bits(adev->mc.vram_start));
- WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i],
- (u32)adev->mc.vram_start);
- WREG32(mmGRPH_SECONDARY_SURFACE_ADDRESS + crtc_offsets[i],
- (u32)adev->mc.vram_start);
- }
-
- WREG32(mmVGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(adev->mc.vram_start));
- WREG32(mmVGA_MEMORY_BASE_ADDRESS, (u32)adev->mc.vram_start);
-
- /* unlock regs and wait for update */
- for (i = 0; i < adev->mode_info.num_crtc; i++) {
- if (save->crtc_enabled[i]) {
- tmp = RREG32(mmMASTER_UPDATE_MODE + crtc_offsets[i]);
- if ((tmp & 0x7) != 0) {
- tmp &= ~0x7;
- WREG32(mmMASTER_UPDATE_MODE + crtc_offsets[i], tmp);
- }
- tmp = RREG32(mmGRPH_UPDATE + crtc_offsets[i]);
- if (tmp & GRPH_UPDATE__GRPH_UPDATE_LOCK_MASK) {
- tmp &= ~GRPH_UPDATE__GRPH_UPDATE_LOCK_MASK;
- WREG32(mmGRPH_UPDATE + crtc_offsets[i], tmp);
- }
- tmp = RREG32(mmMASTER_UPDATE_LOCK + crtc_offsets[i]);
- if (tmp & 1) {
- tmp &= ~1;
- WREG32(mmMASTER_UPDATE_LOCK + crtc_offsets[i], tmp);
- }
- for (j = 0; j < adev->usec_timeout; j++) {
- tmp = RREG32(mmGRPH_UPDATE + crtc_offsets[i]);
- if ((tmp & GRPH_UPDATE__GRPH_SURFACE_UPDATE_PENDING_MASK) == 0)
- break;
- udelay(1);
- }
- }
- }
-
- /* Unlock vga access */
- WREG32(mmVGA_HDP_CONTROL, save->vga_hdp_control);
- mdelay(1);
- WREG32(mmVGA_RENDER_CONTROL, save->vga_render_control);
-
-}
-
static void dce_v6_0_set_vga_render_state(struct amdgpu_device *adev,
bool render)
{
@@ -1597,7 +1487,7 @@ static void dce_v6_0_audio_set_avi_infoframe(struct drm_encoder *encoder,
ssize_t err;
u32 tmp;
- err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+ err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
if (err < 0) {
DRM_ERROR("failed to setup AVI infoframe: %zd\n", err);
return;
@@ -2182,6 +2072,7 @@ static void dce_v6_0_crtc_load_lut(struct drm_crtc *crtc)
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct amdgpu_device *adev = dev->dev_private;
+ u16 *r, *g, *b;
int i;
DRM_DEBUG_KMS("%d\n", amdgpu_crtc->crtc_id);
@@ -2211,11 +2102,14 @@ static void dce_v6_0_crtc_load_lut(struct drm_crtc *crtc)
WREG32(mmDC_LUT_WRITE_EN_MASK + amdgpu_crtc->crtc_offset, 0x00000007);
WREG32(mmDC_LUT_RW_INDEX + amdgpu_crtc->crtc_offset, 0);
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
for (i = 0; i < 256; i++) {
WREG32(mmDC_LUT_30_COLOR + amdgpu_crtc->crtc_offset,
- (amdgpu_crtc->lut_r[i] << 20) |
- (amdgpu_crtc->lut_g[i] << 10) |
- (amdgpu_crtc->lut_b[i] << 0));
+ ((*r++ & 0xffc0) << 14) |
+ ((*g++ & 0xffc0) << 4) |
+ (*b++ >> 6));
}
WREG32(mmDEGAMMA_CONTROL + amdgpu_crtc->crtc_offset,
@@ -2428,7 +2322,7 @@ static int dce_v6_0_crtc_cursor_set2(struct drm_crtc *crtc,
aobj = gem_to_amdgpu_bo(obj);
ret = amdgpu_bo_reserve(aobj, false);
if (ret != 0) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -2436,7 +2330,7 @@ static int dce_v6_0_crtc_cursor_set2(struct drm_crtc *crtc,
amdgpu_bo_unreserve(aobj);
if (ret) {
DRM_ERROR("Failed to pin new cursor BO (%d)\n", ret);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -2470,7 +2364,7 @@ unpin:
amdgpu_bo_unpin(aobj);
amdgpu_bo_unreserve(aobj);
}
- drm_gem_object_unreference_unlocked(amdgpu_crtc->cursor_bo);
+ drm_gem_object_put_unlocked(amdgpu_crtc->cursor_bo);
}
amdgpu_crtc->cursor_bo = obj;
@@ -2496,15 +2390,6 @@ static int dce_v6_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
u16 *blue, uint32_t size,
struct drm_modeset_acquire_ctx *ctx)
{
- struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
- int i;
-
- /* userspace palettes are always correct as is */
- for (i = 0; i < size; i++) {
- amdgpu_crtc->lut_r[i] = red[i] >> 6;
- amdgpu_crtc->lut_g[i] = green[i] >> 6;
- amdgpu_crtc->lut_b[i] = blue[i] >> 6;
- }
dce_v6_0_crtc_load_lut(crtc);
return 0;
@@ -2712,14 +2597,12 @@ static const struct drm_crtc_helper_funcs dce_v6_0_crtc_helper_funcs = {
.mode_set_base_atomic = dce_v6_0_crtc_set_base_atomic,
.prepare = dce_v6_0_crtc_prepare,
.commit = dce_v6_0_crtc_commit,
- .load_lut = dce_v6_0_crtc_load_lut,
.disable = dce_v6_0_crtc_disable,
};
static int dce_v6_0_crtc_init(struct amdgpu_device *adev, int index)
{
struct amdgpu_crtc *amdgpu_crtc;
- int i;
amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) +
(AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
@@ -2737,12 +2620,6 @@ static int dce_v6_0_crtc_init(struct amdgpu_device *adev, int index)
adev->ddev->mode_config.cursor_width = amdgpu_crtc->max_cursor_width;
adev->ddev->mode_config.cursor_height = amdgpu_crtc->max_cursor_height;
- for (i = 0; i < 256; i++) {
- amdgpu_crtc->lut_r[i] = i << 2;
- amdgpu_crtc->lut_g[i] = i << 2;
- amdgpu_crtc->lut_b[i] = i << 2;
- }
-
amdgpu_crtc->crtc_offset = crtc_offsets[amdgpu_crtc->crtc_id];
amdgpu_crtc->pll_id = ATOM_PPLL_INVALID;
@@ -2873,6 +2750,8 @@ static int dce_v6_0_hw_init(void *handle)
int i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ /* disable vga render */
+ dce_v6_0_set_vga_render_state(adev, false);
/* init dig PHYs, disp eng pll */
amdgpu_atombios_encoder_init_dig(adev);
amdgpu_atombios_crtc_set_disp_eng_pll(adev, adev->clock.default_dispclk);
@@ -3525,7 +3404,6 @@ static void dce_v6_0_encoder_add(struct amdgpu_device *adev,
}
static const struct amdgpu_display_funcs dce_v6_0_display_funcs = {
- .set_vga_render_state = &dce_v6_0_set_vga_render_state,
.bandwidth_update = &dce_v6_0_bandwidth_update,
.vblank_get_counter = &dce_v6_0_vblank_get_counter,
.vblank_wait = &dce_v6_0_vblank_wait,
@@ -3538,8 +3416,6 @@ static const struct amdgpu_display_funcs dce_v6_0_display_funcs = {
.page_flip_get_scanoutpos = &dce_v6_0_crtc_get_scanoutpos,
.add_encoder = &dce_v6_0_encoder_add,
.add_connector = &amdgpu_connector_add,
- .stop_mc_access = &dce_v6_0_stop_mc_access,
- .resume_mc_access = &dce_v6_0_resume_mc_access,
};
static void dce_v6_0_set_display_funcs(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
index a9e8695..9cf14b8 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
@@ -419,81 +419,6 @@ static bool dce_v8_0_is_display_hung(struct amdgpu_device *adev)
return true;
}
-static void dce_v8_0_stop_mc_access(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
-{
- u32 crtc_enabled, tmp;
- int i;
-
- save->vga_render_control = RREG32(mmVGA_RENDER_CONTROL);
- save->vga_hdp_control = RREG32(mmVGA_HDP_CONTROL);
-
- /* disable VGA render */
- tmp = RREG32(mmVGA_RENDER_CONTROL);
- tmp = REG_SET_FIELD(tmp, VGA_RENDER_CONTROL, VGA_VSTATUS_CNTL, 0);
- WREG32(mmVGA_RENDER_CONTROL, tmp);
-
- /* blank the display controllers */
- for (i = 0; i < adev->mode_info.num_crtc; i++) {
- crtc_enabled = REG_GET_FIELD(RREG32(mmCRTC_CONTROL + crtc_offsets[i]),
- CRTC_CONTROL, CRTC_MASTER_EN);
- if (crtc_enabled) {
-#if 1
- save->crtc_enabled[i] = true;
- tmp = RREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i]);
- if (REG_GET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN) == 0) {
- /*it is correct only for RGB ; black is 0*/
- WREG32(mmCRTC_BLANK_DATA_COLOR + crtc_offsets[i], 0);
- tmp = REG_SET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN, 1);
- WREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
- }
- mdelay(20);
-#else
- /* XXX this is a hack to avoid strange behavior with EFI on certain systems */
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1);
- tmp = RREG32(mmCRTC_CONTROL + crtc_offsets[i]);
- tmp = REG_SET_FIELD(tmp, CRTC_CONTROL, CRTC_MASTER_EN, 0);
- WREG32(mmCRTC_CONTROL + crtc_offsets[i], tmp);
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
- save->crtc_enabled[i] = false;
- /* ***** */
-#endif
- } else {
- save->crtc_enabled[i] = false;
- }
- }
-}
-
-static void dce_v8_0_resume_mc_access(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
-{
- u32 tmp;
- int i;
-
- /* update crtc base addresses */
- for (i = 0; i < adev->mode_info.num_crtc; i++) {
- WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i],
- upper_32_bits(adev->mc.vram_start));
- WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i],
- (u32)adev->mc.vram_start);
-
- if (save->crtc_enabled[i]) {
- tmp = RREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i]);
- tmp = REG_SET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN, 0);
- WREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
- }
- mdelay(20);
- }
-
- WREG32(mmVGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(adev->mc.vram_start));
- WREG32(mmVGA_MEMORY_BASE_ADDRESS, lower_32_bits(adev->mc.vram_start));
-
- /* Unlock vga access */
- WREG32(mmVGA_HDP_CONTROL, save->vga_hdp_control);
- mdelay(1);
- WREG32(mmVGA_RENDER_CONTROL, save->vga_render_control);
-}
-
static void dce_v8_0_set_vga_render_state(struct amdgpu_device *adev,
bool render)
{
@@ -1750,7 +1675,7 @@ static void dce_v8_0_afmt_setmode(struct drm_encoder *encoder,
dce_v8_0_audio_write_sad_regs(encoder);
dce_v8_0_audio_write_latency_fields(encoder, mode);
- err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+ err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
if (err < 0) {
DRM_ERROR("failed to setup AVI infoframe: %zd\n", err);
return;
@@ -2124,6 +2049,7 @@ static void dce_v8_0_crtc_load_lut(struct drm_crtc *crtc)
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct amdgpu_device *adev = dev->dev_private;
+ u16 *r, *g, *b;
int i;
DRM_DEBUG_KMS("%d\n", amdgpu_crtc->crtc_id);
@@ -2153,11 +2079,14 @@ static void dce_v8_0_crtc_load_lut(struct drm_crtc *crtc)
WREG32(mmDC_LUT_WRITE_EN_MASK + amdgpu_crtc->crtc_offset, 0x00000007);
WREG32(mmDC_LUT_RW_INDEX + amdgpu_crtc->crtc_offset, 0);
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
for (i = 0; i < 256; i++) {
WREG32(mmDC_LUT_30_COLOR + amdgpu_crtc->crtc_offset,
- (amdgpu_crtc->lut_r[i] << 20) |
- (amdgpu_crtc->lut_g[i] << 10) |
- (amdgpu_crtc->lut_b[i] << 0));
+ ((*r++ & 0xffc0) << 14) |
+ ((*g++ & 0xffc0) << 4) |
+ (*b++ >> 6));
}
WREG32(mmDEGAMMA_CONTROL + amdgpu_crtc->crtc_offset,
@@ -2406,7 +2335,7 @@ static int dce_v8_0_crtc_cursor_set2(struct drm_crtc *crtc,
aobj = gem_to_amdgpu_bo(obj);
ret = amdgpu_bo_reserve(aobj, false);
if (ret != 0) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -2414,7 +2343,7 @@ static int dce_v8_0_crtc_cursor_set2(struct drm_crtc *crtc,
amdgpu_bo_unreserve(aobj);
if (ret) {
DRM_ERROR("Failed to pin new cursor BO (%d)\n", ret);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -2448,7 +2377,7 @@ unpin:
amdgpu_bo_unpin(aobj);
amdgpu_bo_unreserve(aobj);
}
- drm_gem_object_unreference_unlocked(amdgpu_crtc->cursor_bo);
+ drm_gem_object_put_unlocked(amdgpu_crtc->cursor_bo);
}
amdgpu_crtc->cursor_bo = obj;
@@ -2475,15 +2404,6 @@ static int dce_v8_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
u16 *blue, uint32_t size,
struct drm_modeset_acquire_ctx *ctx)
{
- struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
- int i;
-
- /* userspace palettes are always correct as is */
- for (i = 0; i < size; i++) {
- amdgpu_crtc->lut_r[i] = red[i] >> 6;
- amdgpu_crtc->lut_g[i] = green[i] >> 6;
- amdgpu_crtc->lut_b[i] = blue[i] >> 6;
- }
dce_v8_0_crtc_load_lut(crtc);
return 0;
@@ -2702,14 +2622,12 @@ static const struct drm_crtc_helper_funcs dce_v8_0_crtc_helper_funcs = {
.mode_set_base_atomic = dce_v8_0_crtc_set_base_atomic,
.prepare = dce_v8_0_crtc_prepare,
.commit = dce_v8_0_crtc_commit,
- .load_lut = dce_v8_0_crtc_load_lut,
.disable = dce_v8_0_crtc_disable,
};
static int dce_v8_0_crtc_init(struct amdgpu_device *adev, int index)
{
struct amdgpu_crtc *amdgpu_crtc;
- int i;
amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) +
(AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
@@ -2727,12 +2645,6 @@ static int dce_v8_0_crtc_init(struct amdgpu_device *adev, int index)
adev->ddev->mode_config.cursor_width = amdgpu_crtc->max_cursor_width;
adev->ddev->mode_config.cursor_height = amdgpu_crtc->max_cursor_height;
- for (i = 0; i < 256; i++) {
- amdgpu_crtc->lut_r[i] = i << 2;
- amdgpu_crtc->lut_g[i] = i << 2;
- amdgpu_crtc->lut_b[i] = i << 2;
- }
-
amdgpu_crtc->crtc_offset = crtc_offsets[amdgpu_crtc->crtc_id];
amdgpu_crtc->pll_id = ATOM_PPLL_INVALID;
@@ -2870,6 +2782,8 @@ static int dce_v8_0_hw_init(void *handle)
int i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ /* disable vga render */
+ dce_v8_0_set_vga_render_state(adev, false);
/* init dig PHYs, disp eng pll */
amdgpu_atombios_encoder_init_dig(adev);
amdgpu_atombios_crtc_set_disp_eng_pll(adev, adev->clock.default_dispclk);
@@ -3574,7 +3488,6 @@ static void dce_v8_0_encoder_add(struct amdgpu_device *adev,
}
static const struct amdgpu_display_funcs dce_v8_0_display_funcs = {
- .set_vga_render_state = &dce_v8_0_set_vga_render_state,
.bandwidth_update = &dce_v8_0_bandwidth_update,
.vblank_get_counter = &dce_v8_0_vblank_get_counter,
.vblank_wait = &dce_v8_0_vblank_wait,
@@ -3587,8 +3500,6 @@ static const struct amdgpu_display_funcs dce_v8_0_display_funcs = {
.page_flip_get_scanoutpos = &dce_v8_0_crtc_get_scanoutpos,
.add_encoder = &dce_v8_0_encoder_add,
.add_connector = &amdgpu_connector_add,
- .stop_mc_access = &dce_v8_0_stop_mc_access,
- .resume_mc_access = &dce_v8_0_resume_mc_access,
};
static void dce_v8_0_set_display_funcs(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
index 90bb083..b9ee907 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
@@ -95,62 +95,6 @@ static u32 dce_virtual_hpd_get_gpio_reg(struct amdgpu_device *adev)
return 0;
}
-static void dce_virtual_stop_mc_access(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
-{
- switch (adev->asic_type) {
-#ifdef CONFIG_DRM_AMDGPU_SI
- case CHIP_TAHITI:
- case CHIP_PITCAIRN:
- case CHIP_VERDE:
- case CHIP_OLAND:
- dce_v6_0_disable_dce(adev);
- break;
-#endif
-#ifdef CONFIG_DRM_AMDGPU_CIK
- case CHIP_BONAIRE:
- case CHIP_HAWAII:
- case CHIP_KAVERI:
- case CHIP_KABINI:
- case CHIP_MULLINS:
- dce_v8_0_disable_dce(adev);
- break;
-#endif
- case CHIP_FIJI:
- case CHIP_TONGA:
- dce_v10_0_disable_dce(adev);
- break;
- case CHIP_CARRIZO:
- case CHIP_STONEY:
- case CHIP_POLARIS10:
- case CHIP_POLARIS11:
- case CHIP_POLARIS12:
- dce_v11_0_disable_dce(adev);
- break;
- case CHIP_TOPAZ:
-#ifdef CONFIG_DRM_AMDGPU_SI
- case CHIP_HAINAN:
-#endif
- /* no DCE */
- return;
- default:
- DRM_ERROR("Virtual display unsupported ASIC type: 0x%X\n", adev->asic_type);
- }
-
- return;
-}
-static void dce_virtual_resume_mc_access(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
-{
- return;
-}
-
-static void dce_virtual_set_vga_render_state(struct amdgpu_device *adev,
- bool render)
-{
- return;
-}
-
/**
* dce_virtual_bandwidth_update - program display watermarks
*
@@ -168,16 +112,6 @@ static int dce_virtual_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
u16 *green, u16 *blue, uint32_t size,
struct drm_modeset_acquire_ctx *ctx)
{
- struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
- int i;
-
- /* userspace palettes are always correct as is */
- for (i = 0; i < size; i++) {
- amdgpu_crtc->lut_r[i] = red[i] >> 6;
- amdgpu_crtc->lut_g[i] = green[i] >> 6;
- amdgpu_crtc->lut_b[i] = blue[i] >> 6;
- }
-
return 0;
}
@@ -289,11 +223,6 @@ static int dce_virtual_crtc_set_base(struct drm_crtc *crtc, int x, int y,
return 0;
}
-static void dce_virtual_crtc_load_lut(struct drm_crtc *crtc)
-{
- return;
-}
-
static int dce_virtual_crtc_set_base_atomic(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
int x, int y, enum mode_set_atomic state)
@@ -309,14 +238,12 @@ static const struct drm_crtc_helper_funcs dce_virtual_crtc_helper_funcs = {
.mode_set_base_atomic = dce_virtual_crtc_set_base_atomic,
.prepare = dce_virtual_crtc_prepare,
.commit = dce_virtual_crtc_commit,
- .load_lut = dce_virtual_crtc_load_lut,
.disable = dce_virtual_crtc_disable,
};
static int dce_virtual_crtc_init(struct amdgpu_device *adev, int index)
{
struct amdgpu_crtc *amdgpu_crtc;
- int i;
amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) +
(AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
@@ -329,12 +256,6 @@ static int dce_virtual_crtc_init(struct amdgpu_device *adev, int index)
amdgpu_crtc->crtc_id = index;
adev->mode_info.crtcs[index] = amdgpu_crtc;
- for (i = 0; i < 256; i++) {
- amdgpu_crtc->lut_r[i] = i << 2;
- amdgpu_crtc->lut_g[i] = i << 2;
- amdgpu_crtc->lut_b[i] = i << 2;
- }
-
amdgpu_crtc->pll_id = ATOM_PPLL_INVALID;
amdgpu_crtc->encoder = NULL;
amdgpu_crtc->connector = NULL;
@@ -522,6 +443,47 @@ static int dce_virtual_sw_fini(void *handle)
static int dce_virtual_hw_init(void *handle)
{
+ struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+ switch (adev->asic_type) {
+#ifdef CONFIG_DRM_AMDGPU_SI
+ case CHIP_TAHITI:
+ case CHIP_PITCAIRN:
+ case CHIP_VERDE:
+ case CHIP_OLAND:
+ dce_v6_0_disable_dce(adev);
+ break;
+#endif
+#ifdef CONFIG_DRM_AMDGPU_CIK
+ case CHIP_BONAIRE:
+ case CHIP_HAWAII:
+ case CHIP_KAVERI:
+ case CHIP_KABINI:
+ case CHIP_MULLINS:
+ dce_v8_0_disable_dce(adev);
+ break;
+#endif
+ case CHIP_FIJI:
+ case CHIP_TONGA:
+ dce_v10_0_disable_dce(adev);
+ break;
+ case CHIP_CARRIZO:
+ case CHIP_STONEY:
+ case CHIP_POLARIS11:
+ case CHIP_POLARIS10:
+ dce_v11_0_disable_dce(adev);
+ break;
+ case CHIP_TOPAZ:
+#ifdef CONFIG_DRM_AMDGPU_SI
+ case CHIP_HAINAN:
+#endif
+ /* no DCE */
+ break;
+ case CHIP_VEGA10:
+ break;
+ default:
+ DRM_ERROR("Virtual display unsupported ASIC type: 0x%X\n", adev->asic_type);
+ }
return 0;
}
@@ -677,7 +639,6 @@ static int dce_virtual_connector_encoder_init(struct amdgpu_device *adev,
}
static const struct amdgpu_display_funcs dce_virtual_display_funcs = {
- .set_vga_render_state = &dce_virtual_set_vga_render_state,
.bandwidth_update = &dce_virtual_bandwidth_update,
.vblank_get_counter = &dce_virtual_vblank_get_counter,
.vblank_wait = &dce_virtual_vblank_wait,
@@ -690,8 +651,6 @@ static const struct amdgpu_display_funcs dce_virtual_display_funcs = {
.page_flip_get_scanoutpos = &dce_virtual_crtc_get_scanoutpos,
.add_encoder = NULL,
.add_connector = NULL,
- .stop_mc_access = &dce_virtual_stop_mc_access,
- .resume_mc_access = &dce_virtual_resume_mc_access,
};
static void dce_virtual_set_display_funcs(struct amdgpu_device *adev)
@@ -809,7 +768,7 @@ static const struct amdgpu_irq_src_funcs dce_virtual_crtc_irq_funcs = {
static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev)
{
- adev->crtc_irq.num_types = AMDGPU_CRTC_IRQ_LAST;
+ adev->crtc_irq.num_types = AMDGPU_CRTC_IRQ_VBLANK6 + 1;
adev->crtc_irq.funcs = &dce_virtual_crtc_irq_funcs;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
index 5173ca1..d228f5a 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
@@ -1573,7 +1573,7 @@ static void gfx_v6_0_gpu_init(struct amdgpu_device *adev)
static void gfx_v6_0_scratch_init(struct amdgpu_device *adev)
{
- adev->gfx.scratch.num_reg = 7;
+ adev->gfx.scratch.num_reg = 8;
adev->gfx.scratch.reg_base = mmSCRATCH_REG0;
adev->gfx.scratch.free_mask = (1u << adev->gfx.scratch.num_reg) - 1;
}
@@ -2217,40 +2217,9 @@ static void gfx_v6_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
static void gfx_v6_0_rlc_fini(struct amdgpu_device *adev)
{
- int r;
-
- if (adev->gfx.rlc.save_restore_obj) {
- r = amdgpu_bo_reserve(adev->gfx.rlc.save_restore_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve RLC sr bo failed\n", r);
- amdgpu_bo_unpin(adev->gfx.rlc.save_restore_obj);
- amdgpu_bo_unreserve(adev->gfx.rlc.save_restore_obj);
-
- amdgpu_bo_unref(&adev->gfx.rlc.save_restore_obj);
- adev->gfx.rlc.save_restore_obj = NULL;
- }
-
- if (adev->gfx.rlc.clear_state_obj) {
- r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve RLC c bo failed\n", r);
- amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj);
- amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
-
- amdgpu_bo_unref(&adev->gfx.rlc.clear_state_obj);
- adev->gfx.rlc.clear_state_obj = NULL;
- }
-
- if (adev->gfx.rlc.cp_table_obj) {
- r = amdgpu_bo_reserve(adev->gfx.rlc.cp_table_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve RLC cp table bo failed\n", r);
- amdgpu_bo_unpin(adev->gfx.rlc.cp_table_obj);
- amdgpu_bo_unreserve(adev->gfx.rlc.cp_table_obj);
-
- amdgpu_bo_unref(&adev->gfx.rlc.cp_table_obj);
- adev->gfx.rlc.cp_table_obj = NULL;
- }
+ amdgpu_bo_free_kernel(&adev->gfx.rlc.save_restore_obj, NULL, NULL);
+ amdgpu_bo_free_kernel(&adev->gfx.rlc.clear_state_obj, NULL, NULL);
+ amdgpu_bo_free_kernel(&adev->gfx.rlc.cp_table_obj, NULL, NULL);
}
static int gfx_v6_0_rlc_init(struct amdgpu_device *adev)
@@ -2273,43 +2242,23 @@ static int gfx_v6_0_rlc_init(struct amdgpu_device *adev)
if (src_ptr) {
/* save restore block */
- if (adev->gfx.rlc.save_restore_obj == NULL) {
- r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
- NULL, NULL,
- &adev->gfx.rlc.save_restore_obj);
-
- if (r) {
- dev_warn(adev->dev, "(%d) create RLC sr bo failed\n", r);
- return r;
- }
- }
-
- r = amdgpu_bo_reserve(adev->gfx.rlc.save_restore_obj, false);
- if (unlikely(r != 0)) {
- gfx_v6_0_rlc_fini(adev);
- return r;
- }
- r = amdgpu_bo_pin(adev->gfx.rlc.save_restore_obj, AMDGPU_GEM_DOMAIN_VRAM,
- &adev->gfx.rlc.save_restore_gpu_addr);
+ r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ &adev->gfx.rlc.save_restore_obj,
+ &adev->gfx.rlc.save_restore_gpu_addr,
+ (void **)&adev->gfx.rlc.sr_ptr);
if (r) {
- amdgpu_bo_unreserve(adev->gfx.rlc.save_restore_obj);
- dev_warn(adev->dev, "(%d) pin RLC sr bo failed\n", r);
+ dev_warn(adev->dev, "(%d) create RLC sr bo failed\n",
+ r);
gfx_v6_0_rlc_fini(adev);
return r;
}
- r = amdgpu_bo_kmap(adev->gfx.rlc.save_restore_obj, (void **)&adev->gfx.rlc.sr_ptr);
- if (r) {
- dev_warn(adev->dev, "(%d) map RLC sr bo failed\n", r);
- gfx_v6_0_rlc_fini(adev);
- return r;
- }
/* write the sr buffer */
dst_ptr = adev->gfx.rlc.sr_ptr;
for (i = 0; i < adev->gfx.rlc.reg_list_size; i++)
dst_ptr[i] = cpu_to_le32(src_ptr[i]);
+
amdgpu_bo_kunmap(adev->gfx.rlc.save_restore_obj);
amdgpu_bo_unreserve(adev->gfx.rlc.save_restore_obj);
}
@@ -2319,39 +2268,17 @@ static int gfx_v6_0_rlc_init(struct amdgpu_device *adev)
adev->gfx.rlc.clear_state_size = gfx_v6_0_get_csb_size(adev);
dws = adev->gfx.rlc.clear_state_size + (256 / 4);
- if (adev->gfx.rlc.clear_state_obj == NULL) {
- r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
- NULL, NULL,
- &adev->gfx.rlc.clear_state_obj);
-
- if (r) {
- dev_warn(adev->dev, "(%d) create RLC c bo failed\n", r);
- gfx_v6_0_rlc_fini(adev);
- return r;
- }
- }
- r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false);
- if (unlikely(r != 0)) {
- gfx_v6_0_rlc_fini(adev);
- return r;
- }
- r = amdgpu_bo_pin(adev->gfx.rlc.clear_state_obj, AMDGPU_GEM_DOMAIN_VRAM,
- &adev->gfx.rlc.clear_state_gpu_addr);
+ r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ &adev->gfx.rlc.clear_state_obj,
+ &adev->gfx.rlc.clear_state_gpu_addr,
+ (void **)&adev->gfx.rlc.cs_ptr);
if (r) {
- amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
- dev_warn(adev->dev, "(%d) pin RLC c bo failed\n", r);
+ dev_warn(adev->dev, "(%d) create RLC c bo failed\n", r);
gfx_v6_0_rlc_fini(adev);
return r;
}
- r = amdgpu_bo_kmap(adev->gfx.rlc.clear_state_obj, (void **)&adev->gfx.rlc.cs_ptr);
- if (r) {
- dev_warn(adev->dev, "(%d) map RLC c bo failed\n", r);
- gfx_v6_0_rlc_fini(adev);
- return r;
- }
/* set up the cs buffer */
dst_ptr = adev->gfx.rlc.cs_ptr;
reg_list_mc_addr = adev->gfx.rlc.clear_state_gpu_addr + 256;
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
index 37b45e4..0086876 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
@@ -1823,7 +1823,7 @@ static void gfx_v7_0_setup_rb(struct amdgpu_device *adev)
}
/**
- * gmc_v7_0_init_compute_vmid - gart enable
+ * gfx_v7_0_init_compute_vmid - gart enable
*
* @adev: amdgpu_device pointer
*
@@ -1833,7 +1833,7 @@ static void gfx_v7_0_setup_rb(struct amdgpu_device *adev)
#define DEFAULT_SH_MEM_BASES (0x6000)
#define FIRST_COMPUTE_VMID (8)
#define LAST_COMPUTE_VMID (16)
-static void gmc_v7_0_init_compute_vmid(struct amdgpu_device *adev)
+static void gfx_v7_0_init_compute_vmid(struct amdgpu_device *adev)
{
int i;
uint32_t sh_mem_config;
@@ -1921,6 +1921,7 @@ static void gfx_v7_0_gpu_init(struct amdgpu_device *adev)
ELEMENT_SIZE, 1);
sh_static_mem_cfg = REG_SET_FIELD(sh_static_mem_cfg, SH_STATIC_MEM_CONFIG,
INDEX_STRIDE, 3);
+ WREG32(mmSH_STATIC_MEM_CONFIG, sh_static_mem_cfg);
mutex_lock(&adev->srbm_mutex);
for (i = 0; i < adev->vm_manager.id_mgr[0].num_ids; i++) {
@@ -1934,12 +1935,11 @@ static void gfx_v7_0_gpu_init(struct amdgpu_device *adev)
WREG32(mmSH_MEM_APE1_BASE, 1);
WREG32(mmSH_MEM_APE1_LIMIT, 0);
WREG32(mmSH_MEM_BASES, sh_mem_base);
- WREG32(mmSH_STATIC_MEM_CONFIG, sh_static_mem_cfg);
}
cik_srbm_select(adev, 0, 0, 0, 0);
mutex_unlock(&adev->srbm_mutex);
- gmc_v7_0_init_compute_vmid(adev);
+ gfx_v7_0_init_compute_vmid(adev);
WREG32(mmSX_DEBUG_1, 0x20);
@@ -2021,7 +2021,7 @@ static void gfx_v7_0_gpu_init(struct amdgpu_device *adev)
*/
static void gfx_v7_0_scratch_init(struct amdgpu_device *adev)
{
- adev->gfx.scratch.num_reg = 7;
+ adev->gfx.scratch.num_reg = 8;
adev->gfx.scratch.reg_base = mmSCRATCH_REG0;
adev->gfx.scratch.free_mask = (1u << adev->gfx.scratch.num_reg) - 1;
}
@@ -2774,39 +2774,18 @@ static int gfx_v7_0_cp_compute_load_microcode(struct amdgpu_device *adev)
*/
static void gfx_v7_0_cp_compute_fini(struct amdgpu_device *adev)
{
- int i, r;
+ int i;
for (i = 0; i < adev->gfx.num_compute_rings; i++) {
struct amdgpu_ring *ring = &adev->gfx.compute_ring[i];
- if (ring->mqd_obj) {
- r = amdgpu_bo_reserve(ring->mqd_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve MQD bo failed\n", r);
-
- amdgpu_bo_unpin(ring->mqd_obj);
- amdgpu_bo_unreserve(ring->mqd_obj);
-
- amdgpu_bo_unref(&ring->mqd_obj);
- ring->mqd_obj = NULL;
- }
+ amdgpu_bo_free_kernel(&ring->mqd_obj, NULL, NULL);
}
}
static void gfx_v7_0_mec_fini(struct amdgpu_device *adev)
{
- int r;
-
- if (adev->gfx.mec.hpd_eop_obj) {
- r = amdgpu_bo_reserve(adev->gfx.mec.hpd_eop_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve HPD EOP bo failed\n", r);
- amdgpu_bo_unpin(adev->gfx.mec.hpd_eop_obj);
- amdgpu_bo_unreserve(adev->gfx.mec.hpd_eop_obj);
-
- amdgpu_bo_unref(&adev->gfx.mec.hpd_eop_obj);
- adev->gfx.mec.hpd_eop_obj = NULL;
- }
+ amdgpu_bo_free_kernel(&adev->gfx.mec.hpd_eop_obj, NULL, NULL);
}
static int gfx_v7_0_mec_init(struct amdgpu_device *adev)
@@ -2823,33 +2802,14 @@ static int gfx_v7_0_mec_init(struct amdgpu_device *adev)
/* allocate space for ALL pipes (even the ones we don't own) */
mec_hpd_size = adev->gfx.mec.num_mec * adev->gfx.mec.num_pipe_per_mec
* GFX7_MEC_HPD_SIZE * 2;
- if (adev->gfx.mec.hpd_eop_obj == NULL) {
- r = amdgpu_bo_create(adev,
- mec_hpd_size,
- PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL,
- &adev->gfx.mec.hpd_eop_obj);
- if (r) {
- dev_warn(adev->dev, "(%d) create HDP EOP bo failed\n", r);
- return r;
- }
- }
- r = amdgpu_bo_reserve(adev->gfx.mec.hpd_eop_obj, false);
- if (unlikely(r != 0)) {
- gfx_v7_0_mec_fini(adev);
- return r;
- }
- r = amdgpu_bo_pin(adev->gfx.mec.hpd_eop_obj, AMDGPU_GEM_DOMAIN_GTT,
- &adev->gfx.mec.hpd_eop_gpu_addr);
- if (r) {
- dev_warn(adev->dev, "(%d) pin HDP EOP bo failed\n", r);
- gfx_v7_0_mec_fini(adev);
- return r;
- }
- r = amdgpu_bo_kmap(adev->gfx.mec.hpd_eop_obj, (void **)&hpd);
+ r = amdgpu_bo_create_reserved(adev, mec_hpd_size, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_GTT,
+ &adev->gfx.mec.hpd_eop_obj,
+ &adev->gfx.mec.hpd_eop_gpu_addr,
+ (void **)&hpd);
if (r) {
- dev_warn(adev->dev, "(%d) map HDP EOP bo failed\n", r);
+ dev_warn(adev->dev, "(%d) create, pin or map of HDP EOP bo failed\n", r);
gfx_v7_0_mec_fini(adev);
return r;
}
@@ -3108,32 +3068,12 @@ static int gfx_v7_0_compute_queue_init(struct amdgpu_device *adev, int ring_id)
struct cik_mqd *mqd;
struct amdgpu_ring *ring = &adev->gfx.compute_ring[ring_id];
- if (ring->mqd_obj == NULL) {
- r = amdgpu_bo_create(adev,
- sizeof(struct cik_mqd),
- PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL,
- &ring->mqd_obj);
- if (r) {
- dev_warn(adev->dev, "(%d) create MQD bo failed\n", r);
- return r;
- }
- }
-
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0))
- goto out;
-
- r = amdgpu_bo_pin(ring->mqd_obj, AMDGPU_GEM_DOMAIN_GTT,
- &mqd_gpu_addr);
- if (r) {
- dev_warn(adev->dev, "(%d) pin MQD bo failed\n", r);
- goto out_unreserve;
- }
- r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&mqd);
+ r = amdgpu_bo_create_reserved(adev, sizeof(struct cik_mqd), PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_GTT, &ring->mqd_obj,
+ &mqd_gpu_addr, (void **)&mqd);
if (r) {
- dev_warn(adev->dev, "(%d) map MQD bo failed\n", r);
- goto out_unreserve;
+ dev_warn(adev->dev, "(%d) create MQD bo failed\n", r);
+ return r;
}
mutex_lock(&adev->srbm_mutex);
@@ -3147,9 +3087,7 @@ static int gfx_v7_0_compute_queue_init(struct amdgpu_device *adev, int ring_id)
mutex_unlock(&adev->srbm_mutex);
amdgpu_bo_kunmap(ring->mqd_obj);
-out_unreserve:
amdgpu_bo_unreserve(ring->mqd_obj);
-out:
return 0;
}
@@ -3361,43 +3299,9 @@ static void gfx_v7_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
*/
static void gfx_v7_0_rlc_fini(struct amdgpu_device *adev)
{
- int r;
-
- /* save restore block */
- if (adev->gfx.rlc.save_restore_obj) {
- r = amdgpu_bo_reserve(adev->gfx.rlc.save_restore_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve RLC sr bo failed\n", r);
- amdgpu_bo_unpin(adev->gfx.rlc.save_restore_obj);
- amdgpu_bo_unreserve(adev->gfx.rlc.save_restore_obj);
-
- amdgpu_bo_unref(&adev->gfx.rlc.save_restore_obj);
- adev->gfx.rlc.save_restore_obj = NULL;
- }
-
- /* clear state block */
- if (adev->gfx.rlc.clear_state_obj) {
- r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve RLC c bo failed\n", r);
- amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj);
- amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
-
- amdgpu_bo_unref(&adev->gfx.rlc.clear_state_obj);
- adev->gfx.rlc.clear_state_obj = NULL;
- }
-
- /* clear state block */
- if (adev->gfx.rlc.cp_table_obj) {
- r = amdgpu_bo_reserve(adev->gfx.rlc.cp_table_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve RLC cp table bo failed\n", r);
- amdgpu_bo_unpin(adev->gfx.rlc.cp_table_obj);
- amdgpu_bo_unreserve(adev->gfx.rlc.cp_table_obj);
-
- amdgpu_bo_unref(&adev->gfx.rlc.cp_table_obj);
- adev->gfx.rlc.cp_table_obj = NULL;
- }
+ amdgpu_bo_free_kernel(&adev->gfx.rlc.save_restore_obj, NULL, NULL);
+ amdgpu_bo_free_kernel(&adev->gfx.rlc.clear_state_obj, NULL, NULL);
+ amdgpu_bo_free_kernel(&adev->gfx.rlc.cp_table_obj, NULL, NULL);
}
static int gfx_v7_0_rlc_init(struct amdgpu_device *adev)
@@ -3432,39 +3336,17 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev)
if (src_ptr) {
/* save restore block */
- if (adev->gfx.rlc.save_restore_obj == NULL) {
- r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
- AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL,
- &adev->gfx.rlc.save_restore_obj);
- if (r) {
- dev_warn(adev->dev, "(%d) create RLC sr bo failed\n", r);
- return r;
- }
- }
-
- r = amdgpu_bo_reserve(adev->gfx.rlc.save_restore_obj, false);
- if (unlikely(r != 0)) {
- gfx_v7_0_rlc_fini(adev);
- return r;
- }
- r = amdgpu_bo_pin(adev->gfx.rlc.save_restore_obj, AMDGPU_GEM_DOMAIN_VRAM,
- &adev->gfx.rlc.save_restore_gpu_addr);
+ r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ &adev->gfx.rlc.save_restore_obj,
+ &adev->gfx.rlc.save_restore_gpu_addr,
+ (void **)&adev->gfx.rlc.sr_ptr);
if (r) {
- amdgpu_bo_unreserve(adev->gfx.rlc.save_restore_obj);
- dev_warn(adev->dev, "(%d) pin RLC sr bo failed\n", r);
+ dev_warn(adev->dev, "(%d) create, pin or map of RLC sr bo failed\n", r);
gfx_v7_0_rlc_fini(adev);
return r;
}
- r = amdgpu_bo_kmap(adev->gfx.rlc.save_restore_obj, (void **)&adev->gfx.rlc.sr_ptr);
- if (r) {
- dev_warn(adev->dev, "(%d) map RLC sr bo failed\n", r);
- gfx_v7_0_rlc_fini(adev);
- return r;
- }
/* write the sr buffer */
dst_ptr = adev->gfx.rlc.sr_ptr;
for (i = 0; i < adev->gfx.rlc.reg_list_size; i++)
@@ -3477,39 +3359,17 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev)
/* clear state block */
adev->gfx.rlc.clear_state_size = dws = gfx_v7_0_get_csb_size(adev);
- if (adev->gfx.rlc.clear_state_obj == NULL) {
- r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
- AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL,
- &adev->gfx.rlc.clear_state_obj);
- if (r) {
- dev_warn(adev->dev, "(%d) create RLC c bo failed\n", r);
- gfx_v7_0_rlc_fini(adev);
- return r;
- }
- }
- r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false);
- if (unlikely(r != 0)) {
- gfx_v7_0_rlc_fini(adev);
- return r;
- }
- r = amdgpu_bo_pin(adev->gfx.rlc.clear_state_obj, AMDGPU_GEM_DOMAIN_VRAM,
- &adev->gfx.rlc.clear_state_gpu_addr);
+ r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ &adev->gfx.rlc.clear_state_obj,
+ &adev->gfx.rlc.clear_state_gpu_addr,
+ (void **)&adev->gfx.rlc.cs_ptr);
if (r) {
- amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
- dev_warn(adev->dev, "(%d) pin RLC c bo failed\n", r);
+ dev_warn(adev->dev, "(%d) create RLC c bo failed\n", r);
gfx_v7_0_rlc_fini(adev);
return r;
}
- r = amdgpu_bo_kmap(adev->gfx.rlc.clear_state_obj, (void **)&adev->gfx.rlc.cs_ptr);
- if (r) {
- dev_warn(adev->dev, "(%d) map RLC c bo failed\n", r);
- gfx_v7_0_rlc_fini(adev);
- return r;
- }
/* set up the cs buffer */
dst_ptr = adev->gfx.rlc.cs_ptr;
gfx_v7_0_get_csb_buffer(adev, dst_ptr);
@@ -3518,37 +3378,14 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev)
}
if (adev->gfx.rlc.cp_table_size) {
- if (adev->gfx.rlc.cp_table_obj == NULL) {
- r = amdgpu_bo_create(adev, adev->gfx.rlc.cp_table_size, PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
- AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL,
- &adev->gfx.rlc.cp_table_obj);
- if (r) {
- dev_warn(adev->dev, "(%d) create RLC cp table bo failed\n", r);
- gfx_v7_0_rlc_fini(adev);
- return r;
- }
- }
- r = amdgpu_bo_reserve(adev->gfx.rlc.cp_table_obj, false);
- if (unlikely(r != 0)) {
- dev_warn(adev->dev, "(%d) reserve RLC cp table bo failed\n", r);
- gfx_v7_0_rlc_fini(adev);
- return r;
- }
- r = amdgpu_bo_pin(adev->gfx.rlc.cp_table_obj, AMDGPU_GEM_DOMAIN_VRAM,
- &adev->gfx.rlc.cp_table_gpu_addr);
- if (r) {
- amdgpu_bo_unreserve(adev->gfx.rlc.cp_table_obj);
- dev_warn(adev->dev, "(%d) pin RLC cp_table bo failed\n", r);
- gfx_v7_0_rlc_fini(adev);
- return r;
- }
- r = amdgpu_bo_kmap(adev->gfx.rlc.cp_table_obj, (void **)&adev->gfx.rlc.cp_table_ptr);
+ r = amdgpu_bo_create_reserved(adev, adev->gfx.rlc.cp_table_size,
+ PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
+ &adev->gfx.rlc.cp_table_obj,
+ &adev->gfx.rlc.cp_table_gpu_addr,
+ (void **)&adev->gfx.rlc.cp_table_ptr);
if (r) {
- dev_warn(adev->dev, "(%d) map RLC cp table bo failed\n", r);
+ dev_warn(adev->dev, "(%d) create RLC cp table bo failed\n", r);
gfx_v7_0_rlc_fini(adev);
return r;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
index aa5a50f..832e592 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
@@ -193,8 +193,8 @@ static const u32 tonga_golden_common_all[] =
mmGB_ADDR_CONFIG, 0xffffffff, 0x22011003,
mmSPI_RESOURCE_RESERVE_CU_0, 0xffffffff, 0x00000800,
mmSPI_RESOURCE_RESERVE_CU_1, 0xffffffff, 0x00000800,
- mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00007FBF,
- mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00007FAF
+ mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00FF7FBF,
+ mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00FF7FAF
};
static const u32 tonga_mgcg_cgcg_init[] =
@@ -303,8 +303,8 @@ static const u32 polaris11_golden_common_all[] =
mmGB_ADDR_CONFIG, 0xffffffff, 0x22011002,
mmSPI_RESOURCE_RESERVE_CU_0, 0xffffffff, 0x00000800,
mmSPI_RESOURCE_RESERVE_CU_1, 0xffffffff, 0x00000800,
- mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00007FBF,
- mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00007FAF,
+ mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00FF7FBF,
+ mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00FF7FAF,
};
static const u32 golden_settings_polaris10_a11[] =
@@ -336,8 +336,8 @@ static const u32 polaris10_golden_common_all[] =
mmGB_ADDR_CONFIG, 0xffffffff, 0x22011003,
mmSPI_RESOURCE_RESERVE_CU_0, 0xffffffff, 0x00000800,
mmSPI_RESOURCE_RESERVE_CU_1, 0xffffffff, 0x00000800,
- mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00007FBF,
- mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00007FAF,
+ mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00FF7FBF,
+ mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00FF7FAF,
};
static const u32 fiji_golden_common_all[] =
@@ -348,8 +348,8 @@ static const u32 fiji_golden_common_all[] =
mmGB_ADDR_CONFIG, 0xffffffff, 0x22011003,
mmSPI_RESOURCE_RESERVE_CU_0, 0xffffffff, 0x00000800,
mmSPI_RESOURCE_RESERVE_CU_1, 0xffffffff, 0x00000800,
- mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00007FBF,
- mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00007FAF,
+ mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00FF7FBF,
+ mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00FF7FAF,
mmGRBM_GFX_INDEX, 0xffffffff, 0xe0000000,
mmSPI_CONFIG_CNTL_1, 0x0000000f, 0x00000009,
};
@@ -436,8 +436,8 @@ static const u32 iceland_golden_common_all[] =
mmGB_ADDR_CONFIG, 0xffffffff, 0x22010001,
mmSPI_RESOURCE_RESERVE_CU_0, 0xffffffff, 0x00000800,
mmSPI_RESOURCE_RESERVE_CU_1, 0xffffffff, 0x00000800,
- mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00007FBF,
- mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00007FAF
+ mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00FF7FBF,
+ mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00FF7FAF
};
static const u32 iceland_mgcg_cgcg_init[] =
@@ -532,8 +532,8 @@ static const u32 cz_golden_common_all[] =
mmGB_ADDR_CONFIG, 0xffffffff, 0x22010001,
mmSPI_RESOURCE_RESERVE_CU_0, 0xffffffff, 0x00000800,
mmSPI_RESOURCE_RESERVE_CU_1, 0xffffffff, 0x00000800,
- mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00007FBF,
- mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00007FAF
+ mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00FF7FBF,
+ mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00FF7FAF
};
static const u32 cz_mgcg_cgcg_init[] =
@@ -637,8 +637,8 @@ static const u32 stoney_golden_common_all[] =
mmGB_ADDR_CONFIG, 0xffffffff, 0x12010001,
mmSPI_RESOURCE_RESERVE_CU_0, 0xffffffff, 0x00000800,
mmSPI_RESOURCE_RESERVE_CU_1, 0xffffffff, 0x00000800,
- mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00007FBF,
- mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00007FAF,
+ mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00FF7FBF,
+ mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00FF7FAF,
};
static const u32 stoney_mgcg_cgcg_init[] =
@@ -750,7 +750,7 @@ static void gfx_v8_0_init_golden_registers(struct amdgpu_device *adev)
static void gfx_v8_0_scratch_init(struct amdgpu_device *adev)
{
- adev->gfx.scratch.num_reg = 7;
+ adev->gfx.scratch.num_reg = 8;
adev->gfx.scratch.reg_base = mmSCRATCH_REG0;
adev->gfx.scratch.free_mask = (1u << adev->gfx.scratch.num_reg) - 1;
}
@@ -1238,29 +1238,8 @@ static void cz_init_cp_jump_table(struct amdgpu_device *adev)
static void gfx_v8_0_rlc_fini(struct amdgpu_device *adev)
{
- int r;
-
- /* clear state block */
- if (adev->gfx.rlc.clear_state_obj) {
- r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve RLC cbs bo failed\n", r);
- amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj);
- amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
- amdgpu_bo_unref(&adev->gfx.rlc.clear_state_obj);
- adev->gfx.rlc.clear_state_obj = NULL;
- }
-
- /* jump table block */
- if (adev->gfx.rlc.cp_table_obj) {
- r = amdgpu_bo_reserve(adev->gfx.rlc.cp_table_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve RLC cp table bo failed\n", r);
- amdgpu_bo_unpin(adev->gfx.rlc.cp_table_obj);
- amdgpu_bo_unreserve(adev->gfx.rlc.cp_table_obj);
- amdgpu_bo_unref(&adev->gfx.rlc.cp_table_obj);
- adev->gfx.rlc.cp_table_obj = NULL;
- }
+ amdgpu_bo_free_kernel(&adev->gfx.rlc.clear_state_obj, NULL, NULL);
+ amdgpu_bo_free_kernel(&adev->gfx.rlc.cp_table_obj, NULL, NULL);
}
static int gfx_v8_0_rlc_init(struct amdgpu_device *adev)
@@ -1278,39 +1257,17 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev)
/* clear state block */
adev->gfx.rlc.clear_state_size = dws = gfx_v8_0_get_csb_size(adev);
- if (adev->gfx.rlc.clear_state_obj == NULL) {
- r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
- AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL,
- &adev->gfx.rlc.clear_state_obj);
- if (r) {
- dev_warn(adev->dev, "(%d) create RLC c bo failed\n", r);
- gfx_v8_0_rlc_fini(adev);
- return r;
- }
- }
- r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false);
- if (unlikely(r != 0)) {
- gfx_v8_0_rlc_fini(adev);
- return r;
- }
- r = amdgpu_bo_pin(adev->gfx.rlc.clear_state_obj, AMDGPU_GEM_DOMAIN_VRAM,
- &adev->gfx.rlc.clear_state_gpu_addr);
+ r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ &adev->gfx.rlc.clear_state_obj,
+ &adev->gfx.rlc.clear_state_gpu_addr,
+ (void **)&adev->gfx.rlc.cs_ptr);
if (r) {
- amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
- dev_warn(adev->dev, "(%d) pin RLC cbs bo failed\n", r);
+ dev_warn(adev->dev, "(%d) create RLC c bo failed\n", r);
gfx_v8_0_rlc_fini(adev);
return r;
}
- r = amdgpu_bo_kmap(adev->gfx.rlc.clear_state_obj, (void **)&adev->gfx.rlc.cs_ptr);
- if (r) {
- dev_warn(adev->dev, "(%d) map RLC cbs bo failed\n", r);
- gfx_v8_0_rlc_fini(adev);
- return r;
- }
/* set up the cs buffer */
dst_ptr = adev->gfx.rlc.cs_ptr;
gfx_v8_0_get_csb_buffer(adev, dst_ptr);
@@ -1321,34 +1278,13 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev)
if ((adev->asic_type == CHIP_CARRIZO) ||
(adev->asic_type == CHIP_STONEY)) {
adev->gfx.rlc.cp_table_size = ALIGN(96 * 5 * 4, 2048) + (64 * 1024); /* JT + GDS */
- if (adev->gfx.rlc.cp_table_obj == NULL) {
- r = amdgpu_bo_create(adev, adev->gfx.rlc.cp_table_size, PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
- AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL,
- &adev->gfx.rlc.cp_table_obj);
- if (r) {
- dev_warn(adev->dev, "(%d) create RLC cp table bo failed\n", r);
- return r;
- }
- }
-
- r = amdgpu_bo_reserve(adev->gfx.rlc.cp_table_obj, false);
- if (unlikely(r != 0)) {
- dev_warn(adev->dev, "(%d) reserve RLC cp table bo failed\n", r);
- return r;
- }
- r = amdgpu_bo_pin(adev->gfx.rlc.cp_table_obj, AMDGPU_GEM_DOMAIN_VRAM,
- &adev->gfx.rlc.cp_table_gpu_addr);
- if (r) {
- amdgpu_bo_unreserve(adev->gfx.rlc.cp_table_obj);
- dev_warn(adev->dev, "(%d) pin RLC cp table bo failed\n", r);
- return r;
- }
- r = amdgpu_bo_kmap(adev->gfx.rlc.cp_table_obj, (void **)&adev->gfx.rlc.cp_table_ptr);
+ r = amdgpu_bo_create_reserved(adev, adev->gfx.rlc.cp_table_size,
+ PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
+ &adev->gfx.rlc.cp_table_obj,
+ &adev->gfx.rlc.cp_table_gpu_addr,
+ (void **)&adev->gfx.rlc.cp_table_ptr);
if (r) {
- dev_warn(adev->dev, "(%d) map RLC cp table bo failed\n", r);
+ dev_warn(adev->dev, "(%d) create RLC cp table bo failed\n", r);
return r;
}
@@ -1363,17 +1299,7 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev)
static void gfx_v8_0_mec_fini(struct amdgpu_device *adev)
{
- int r;
-
- if (adev->gfx.mec.hpd_eop_obj) {
- r = amdgpu_bo_reserve(adev->gfx.mec.hpd_eop_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve HPD EOP bo failed\n", r);
- amdgpu_bo_unpin(adev->gfx.mec.hpd_eop_obj);
- amdgpu_bo_unreserve(adev->gfx.mec.hpd_eop_obj);
- amdgpu_bo_unref(&adev->gfx.mec.hpd_eop_obj);
- adev->gfx.mec.hpd_eop_obj = NULL;
- }
+ amdgpu_bo_free_kernel(&adev->gfx.mec.hpd_eop_obj, NULL, NULL);
}
static int gfx_v8_0_mec_init(struct amdgpu_device *adev)
@@ -1389,34 +1315,13 @@ static int gfx_v8_0_mec_init(struct amdgpu_device *adev)
mec_hpd_size = adev->gfx.num_compute_rings * GFX8_MEC_HPD_SIZE;
- if (adev->gfx.mec.hpd_eop_obj == NULL) {
- r = amdgpu_bo_create(adev,
- mec_hpd_size,
- PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL,
- &adev->gfx.mec.hpd_eop_obj);
- if (r) {
- dev_warn(adev->dev, "(%d) create HDP EOP bo failed\n", r);
- return r;
- }
- }
-
- r = amdgpu_bo_reserve(adev->gfx.mec.hpd_eop_obj, false);
- if (unlikely(r != 0)) {
- gfx_v8_0_mec_fini(adev);
- return r;
- }
- r = amdgpu_bo_pin(adev->gfx.mec.hpd_eop_obj, AMDGPU_GEM_DOMAIN_GTT,
- &adev->gfx.mec.hpd_eop_gpu_addr);
+ r = amdgpu_bo_create_reserved(adev, mec_hpd_size, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_GTT,
+ &adev->gfx.mec.hpd_eop_obj,
+ &adev->gfx.mec.hpd_eop_gpu_addr,
+ (void **)&hpd);
if (r) {
- dev_warn(adev->dev, "(%d) pin HDP EOP bo failed\n", r);
- gfx_v8_0_mec_fini(adev);
- return r;
- }
- r = amdgpu_bo_kmap(adev->gfx.mec.hpd_eop_obj, (void **)&hpd);
- if (r) {
- dev_warn(adev->dev, "(%d) map HDP EOP bo failed\n", r);
- gfx_v8_0_mec_fini(adev);
+ dev_warn(adev->dev, "(%d) create HDP EOP bo failed\n", r);
return r;
}
@@ -3802,6 +3707,8 @@ static void gfx_v8_0_gpu_init(struct amdgpu_device *adev)
ELEMENT_SIZE, 1);
sh_static_mem_cfg = REG_SET_FIELD(sh_static_mem_cfg, SH_STATIC_MEM_CONFIG,
INDEX_STRIDE, 3);
+ WREG32(mmSH_STATIC_MEM_CONFIG, sh_static_mem_cfg);
+
mutex_lock(&adev->srbm_mutex);
for (i = 0; i < adev->vm_manager.id_mgr[0].num_ids; i++) {
vi_srbm_select(adev, 0, 0, 0, i);
@@ -3825,7 +3732,6 @@ static void gfx_v8_0_gpu_init(struct amdgpu_device *adev)
WREG32(mmSH_MEM_APE1_BASE, 1);
WREG32(mmSH_MEM_APE1_LIMIT, 0);
- WREG32(mmSH_STATIC_MEM_CONFIG, sh_static_mem_cfg);
}
vi_srbm_select(adev, 0, 0, 0, 0);
mutex_unlock(&adev->srbm_mutex);
@@ -4564,7 +4470,7 @@ static int gfx_v8_0_kiq_kcq_enable(struct amdgpu_device *adev)
/* This situation may be hit in the future if a new HW
* generation exposes more than 64 queues. If so, the
* definition of queue_mask needs updating */
- if (WARN_ON(i > (sizeof(queue_mask)*8))) {
+ if (WARN_ON(i >= (sizeof(queue_mask)*8))) {
DRM_ERROR("Invalid KCQ enabled: %d\n", i);
break;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
index c9b9c88..69182ee 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
@@ -116,7 +116,9 @@ static const u32 golden_settings_gc_9_0[] =
SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_UTCL1_CNTL_2), 0x08000000, 0x08000080,
SOC15_REG_OFFSET(GC, 0, mmRLC_PREWALKER_UTCL1_CNTL), 0x08000000, 0x08000080,
SOC15_REG_OFFSET(GC, 0, mmRLC_SPM_UTCL1_CNTL), 0x08000000, 0x08000080,
+ SOC15_REG_OFFSET(GC, 0, mmSH_MEM_CONFIG), 0x00001000, 0x00001000,
SOC15_REG_OFFSET(GC, 0, mmSPI_CONFIG_CNTL_1), 0x0000000f, 0x01000107,
+ SOC15_REG_OFFSET(GC, 0, mmSQC_CONFIG), 0x03000000, 0x020a2000,
SOC15_REG_OFFSET(GC, 0, mmTA_CNTL_AUX), 0xfffffeef, 0x010b0000,
SOC15_REG_OFFSET(GC, 0, mmTCP_CHAN_STEER_HI), 0xffffffff, 0x4a2c0e68,
SOC15_REG_OFFSET(GC, 0, mmTCP_CHAN_STEER_LO), 0xffffffff, 0xb5d3f197,
@@ -211,7 +213,7 @@ static void gfx_v9_0_init_golden_registers(struct amdgpu_device *adev)
static void gfx_v9_0_scratch_init(struct amdgpu_device *adev)
{
- adev->gfx.scratch.num_reg = 7;
+ adev->gfx.scratch.num_reg = 8;
adev->gfx.scratch.reg_base = SOC15_REG_OFFSET(GC, 0, mmSCRATCH_REG0);
adev->gfx.scratch.free_mask = (1u << adev->gfx.scratch.num_reg) - 1;
}
@@ -772,18 +774,16 @@ static int gfx_v9_0_rlc_init(struct amdgpu_device *adev)
if (cs_data) {
/* clear state block */
adev->gfx.rlc.clear_state_size = dws = gfx_v9_0_get_csb_size(adev);
- if (adev->gfx.rlc.clear_state_obj == NULL) {
- r = amdgpu_bo_create_kernel(adev, dws * 4, PAGE_SIZE,
- AMDGPU_GEM_DOMAIN_VRAM,
- &adev->gfx.rlc.clear_state_obj,
- &adev->gfx.rlc.clear_state_gpu_addr,
- (void **)&adev->gfx.rlc.cs_ptr);
- if (r) {
- dev_err(adev->dev,
- "(%d) failed to create rlc csb bo\n", r);
- gfx_v9_0_rlc_fini(adev);
- return r;
- }
+ r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ &adev->gfx.rlc.clear_state_obj,
+ &adev->gfx.rlc.clear_state_gpu_addr,
+ (void **)&adev->gfx.rlc.cs_ptr);
+ if (r) {
+ dev_err(adev->dev, "(%d) failed to create rlc csb bo\n",
+ r);
+ gfx_v9_0_rlc_fini(adev);
+ return r;
}
/* set up the cs buffer */
dst_ptr = adev->gfx.rlc.cs_ptr;
@@ -795,18 +795,16 @@ static int gfx_v9_0_rlc_init(struct amdgpu_device *adev)
if (adev->asic_type == CHIP_RAVEN) {
/* TODO: double check the cp_table_size for RV */
adev->gfx.rlc.cp_table_size = ALIGN(96 * 5 * 4, 2048) + (64 * 1024); /* JT + GDS */
- if (adev->gfx.rlc.cp_table_obj == NULL) {
- r = amdgpu_bo_create_kernel(adev, adev->gfx.rlc.cp_table_size,
- PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
- &adev->gfx.rlc.cp_table_obj,
- &adev->gfx.rlc.cp_table_gpu_addr,
- (void **)&adev->gfx.rlc.cp_table_ptr);
- if (r) {
- dev_err(adev->dev,
- "(%d) failed to create cp table bo\n", r);
- gfx_v9_0_rlc_fini(adev);
- return r;
- }
+ r = amdgpu_bo_create_reserved(adev, adev->gfx.rlc.cp_table_size,
+ PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
+ &adev->gfx.rlc.cp_table_obj,
+ &adev->gfx.rlc.cp_table_gpu_addr,
+ (void **)&adev->gfx.rlc.cp_table_ptr);
+ if (r) {
+ dev_err(adev->dev,
+ "(%d) failed to create cp table bo\n", r);
+ gfx_v9_0_rlc_fini(adev);
+ return r;
}
rv_init_cp_jump_table(adev);
@@ -821,28 +819,8 @@ static int gfx_v9_0_rlc_init(struct amdgpu_device *adev)
static void gfx_v9_0_mec_fini(struct amdgpu_device *adev)
{
- int r;
-
- if (adev->gfx.mec.hpd_eop_obj) {
- r = amdgpu_bo_reserve(adev->gfx.mec.hpd_eop_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve HPD EOP bo failed\n", r);
- amdgpu_bo_unpin(adev->gfx.mec.hpd_eop_obj);
- amdgpu_bo_unreserve(adev->gfx.mec.hpd_eop_obj);
-
- amdgpu_bo_unref(&adev->gfx.mec.hpd_eop_obj);
- adev->gfx.mec.hpd_eop_obj = NULL;
- }
- if (adev->gfx.mec.mec_fw_obj) {
- r = amdgpu_bo_reserve(adev->gfx.mec.mec_fw_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve mec firmware bo failed\n", r);
- amdgpu_bo_unpin(adev->gfx.mec.mec_fw_obj);
- amdgpu_bo_unreserve(adev->gfx.mec.mec_fw_obj);
-
- amdgpu_bo_unref(&adev->gfx.mec.mec_fw_obj);
- adev->gfx.mec.mec_fw_obj = NULL;
- }
+ amdgpu_bo_free_kernel(&adev->gfx.mec.hpd_eop_obj, NULL, NULL);
+ amdgpu_bo_free_kernel(&adev->gfx.mec.mec_fw_obj, NULL, NULL);
}
static int gfx_v9_0_mec_init(struct amdgpu_device *adev)
@@ -862,33 +840,13 @@ static int gfx_v9_0_mec_init(struct amdgpu_device *adev)
amdgpu_gfx_compute_queue_acquire(adev);
mec_hpd_size = adev->gfx.num_compute_rings * GFX9_MEC_HPD_SIZE;
- if (adev->gfx.mec.hpd_eop_obj == NULL) {
- r = amdgpu_bo_create(adev,
- mec_hpd_size,
- PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL,
- &adev->gfx.mec.hpd_eop_obj);
- if (r) {
- dev_warn(adev->dev, "(%d) create HDP EOP bo failed\n", r);
- return r;
- }
- }
-
- r = amdgpu_bo_reserve(adev->gfx.mec.hpd_eop_obj, false);
- if (unlikely(r != 0)) {
- gfx_v9_0_mec_fini(adev);
- return r;
- }
- r = amdgpu_bo_pin(adev->gfx.mec.hpd_eop_obj, AMDGPU_GEM_DOMAIN_GTT,
- &adev->gfx.mec.hpd_eop_gpu_addr);
+ r = amdgpu_bo_create_reserved(adev, mec_hpd_size, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_GTT,
+ &adev->gfx.mec.hpd_eop_obj,
+ &adev->gfx.mec.hpd_eop_gpu_addr,
+ (void **)&hpd);
if (r) {
- dev_warn(adev->dev, "(%d) pin HDP EOP bo failed\n", r);
- gfx_v9_0_mec_fini(adev);
- return r;
- }
- r = amdgpu_bo_kmap(adev->gfx.mec.hpd_eop_obj, (void **)&hpd);
- if (r) {
- dev_warn(adev->dev, "(%d) map HDP EOP bo failed\n", r);
+ dev_warn(adev->dev, "(%d) create HDP EOP bo failed\n", r);
gfx_v9_0_mec_fini(adev);
return r;
}
@@ -905,42 +863,22 @@ static int gfx_v9_0_mec_init(struct amdgpu_device *adev)
le32_to_cpu(mec_hdr->header.ucode_array_offset_bytes));
fw_size = le32_to_cpu(mec_hdr->header.ucode_size_bytes) / 4;
- if (adev->gfx.mec.mec_fw_obj == NULL) {
- r = amdgpu_bo_create(adev,
- mec_hdr->header.ucode_size_bytes,
- PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL,
- &adev->gfx.mec.mec_fw_obj);
- if (r) {
- dev_warn(adev->dev, "(%d) create mec firmware bo failed\n", r);
- return r;
- }
- }
-
- r = amdgpu_bo_reserve(adev->gfx.mec.mec_fw_obj, false);
- if (unlikely(r != 0)) {
- gfx_v9_0_mec_fini(adev);
- return r;
- }
- r = amdgpu_bo_pin(adev->gfx.mec.mec_fw_obj, AMDGPU_GEM_DOMAIN_GTT,
- &adev->gfx.mec.mec_fw_gpu_addr);
- if (r) {
- dev_warn(adev->dev, "(%d) pin mec firmware bo failed\n", r);
- gfx_v9_0_mec_fini(adev);
- return r;
- }
- r = amdgpu_bo_kmap(adev->gfx.mec.mec_fw_obj, (void **)&fw);
+ r = amdgpu_bo_create_reserved(adev, mec_hdr->header.ucode_size_bytes,
+ PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT,
+ &adev->gfx.mec.mec_fw_obj,
+ &adev->gfx.mec.mec_fw_gpu_addr,
+ (void **)&fw);
if (r) {
- dev_warn(adev->dev, "(%d) map firmware bo failed\n", r);
+ dev_warn(adev->dev, "(%d) create mec firmware bo failed\n", r);
gfx_v9_0_mec_fini(adev);
return r;
}
+
memcpy(fw, fw_data, fw_size);
amdgpu_bo_kunmap(adev->gfx.mec.mec_fw_obj);
amdgpu_bo_unreserve(adev->gfx.mec.mec_fw_obj);
-
return 0;
}
@@ -2219,7 +2157,7 @@ static int gfx_v9_0_cp_gfx_start(struct amdgpu_device *adev)
struct amdgpu_ring *ring = &adev->gfx.gfx_ring[0];
const struct cs_section_def *sect = NULL;
const struct cs_extent_def *ext = NULL;
- int r, i;
+ int r, i, tmp;
/* init the CP */
WREG32_SOC15(GC, 0, mmCP_MAX_CONTEXT, adev->gfx.config.max_hw_contexts - 1);
@@ -2227,7 +2165,7 @@ static int gfx_v9_0_cp_gfx_start(struct amdgpu_device *adev)
gfx_v9_0_cp_gfx_enable(adev, true);
- r = amdgpu_ring_alloc(ring, gfx_v9_0_get_csb_size(adev) + 4);
+ r = amdgpu_ring_alloc(ring, gfx_v9_0_get_csb_size(adev) + 4 + 3);
if (r) {
DRM_ERROR("amdgpu: cp failed to lock ring (%d).\n", r);
return r;
@@ -2265,6 +2203,12 @@ static int gfx_v9_0_cp_gfx_start(struct amdgpu_device *adev)
amdgpu_ring_write(ring, 0x8000);
amdgpu_ring_write(ring, 0x8000);
+ amdgpu_ring_write(ring, PACKET3(PACKET3_SET_UCONFIG_REG,1));
+ tmp = (PACKET3_SET_UCONFIG_REG_INDEX_TYPE |
+ (SOC15_REG_OFFSET(GC, 0, mmVGT_INDEX_TYPE) - PACKET3_SET_UCONFIG_REG_START));
+ amdgpu_ring_write(ring, tmp);
+ amdgpu_ring_write(ring, 0);
+
amdgpu_ring_commit(ring);
return 0;
@@ -2427,7 +2371,7 @@ static int gfx_v9_0_kiq_kcq_enable(struct amdgpu_device *adev)
/* This situation may be hit in the future if a new HW
* generation exposes more than 64 queues. If so, the
* definition of queue_mask needs updating */
- if (WARN_ON(i > (sizeof(queue_mask)*8))) {
+ if (WARN_ON(i >= (sizeof(queue_mask)*8))) {
DRM_ERROR("Invalid KCQ enabled: %d\n", i);
break;
}
@@ -4158,7 +4102,7 @@ static int gfx_v9_0_kiq_irq(struct amdgpu_device *adev,
return 0;
}
-const struct amd_ip_funcs gfx_v9_0_ip_funcs = {
+static const struct amd_ip_funcs gfx_v9_0_ip_funcs = {
.name = "gfx_v9_0",
.early_init = gfx_v9_0_early_init,
.late_init = gfx_v9_0_late_init,
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.h b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.h
index 56ef652..fa5a3fb 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.h
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.h
@@ -24,7 +24,6 @@
#ifndef __GFX_V9_0_H__
#define __GFX_V9_0_H__
-extern const struct amd_ip_funcs gfx_v9_0_ip_funcs;
extern const struct amdgpu_ip_block_version gfx_v9_0_ip_block;
void gfx_v9_0_select_se_sh(struct amdgpu_device *adev, u32 se_num, u32 sh_num);
diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c
index a42f483..4f2788b 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c
@@ -58,14 +58,14 @@ static void gfxhub_v1_0_init_gart_aperture_regs(struct amdgpu_device *adev)
gfxhub_v1_0_init_gart_pt_regs(adev);
WREG32_SOC15(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32,
- (u32)(adev->mc.gtt_start >> 12));
+ (u32)(adev->mc.gart_start >> 12));
WREG32_SOC15(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32,
- (u32)(adev->mc.gtt_start >> 44));
+ (u32)(adev->mc.gart_start >> 44));
WREG32_SOC15(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32,
- (u32)(adev->mc.gtt_end >> 12));
+ (u32)(adev->mc.gart_end >> 12));
WREG32_SOC15(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32,
- (u32)(adev->mc.gtt_end >> 44));
+ (u32)(adev->mc.gart_end >> 44));
}
static void gfxhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev)
@@ -124,12 +124,12 @@ static void gfxhub_v1_0_init_tlb_regs(struct amdgpu_device *adev)
static void gfxhub_v1_0_init_cache_regs(struct amdgpu_device *adev)
{
- uint32_t tmp;
+ uint32_t tmp, field;
/* Setup L2 cache */
tmp = RREG32_SOC15(GC, 0, mmVM_L2_CNTL);
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_CACHE, 1);
- tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING, 0);
+ tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING, 1);
/* XXX for emulation, Refer to closed source code.*/
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, L2_PDE0_CACHE_TAG_GENERATION_MODE,
0);
@@ -143,7 +143,10 @@ static void gfxhub_v1_0_init_cache_regs(struct amdgpu_device *adev)
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL2, INVALIDATE_L2_CACHE, 1);
WREG32_SOC15(GC, 0, mmVM_L2_CNTL2, tmp);
+ field = adev->vm_manager.fragment_size;
tmp = mmVM_L2_CNTL3_DEFAULT;
+ tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, field);
+ tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_FRAGMENT_SIZE, 6);
WREG32_SOC15(GC, 0, mmVM_L2_CNTL3, tmp);
tmp = mmVM_L2_CNTL4_DEFAULT;
@@ -206,6 +209,9 @@ static void gfxhub_v1_0_setup_vmid_config(struct amdgpu_device *adev)
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
PAGE_TABLE_BLOCK_SIZE,
adev->vm_manager.block_size - 9);
+ /* Send no-retry XNACK on fault to suppress VM fault storm. */
+ tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
+ RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, 0);
WREG32_SOC15_OFFSET(GC, 0, mmVM_CONTEXT1_CNTL, i, tmp);
WREG32_SOC15_OFFSET(GC, 0, mmVM_CONTEXT1_PAGE_TABLE_START_ADDR_LO32, i*2, 0);
WREG32_SOC15_OFFSET(GC, 0, mmVM_CONTEXT1_PAGE_TABLE_START_ADDR_HI32, i*2, 0);
diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.h b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.h
index d2dbb08..206e29c 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.h
+++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.h
@@ -30,7 +30,5 @@ void gfxhub_v1_0_set_fault_enable_default(struct amdgpu_device *adev,
bool value);
void gfxhub_v1_0_init(struct amdgpu_device *adev);
u64 gfxhub_v1_0_get_mc_fb_offset(struct amdgpu_device *adev);
-extern const struct amd_ip_funcs gfxhub_v1_0_ip_funcs;
-extern const struct amdgpu_ip_block_version gfxhub_v1_0_ip_block;
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
index d0214d9..12b0c4c 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
@@ -66,14 +66,10 @@ static const u32 crtc_offsets[6] =
SI_CRTC5_REGISTER_OFFSET
};
-static void gmc_v6_0_mc_stop(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
+static void gmc_v6_0_mc_stop(struct amdgpu_device *adev)
{
u32 blackout;
- if (adev->mode_info.num_crtc)
- amdgpu_display_stop_mc_access(adev, save);
-
gmc_v6_0_wait_for_idle((void *)adev);
blackout = RREG32(mmMC_SHARED_BLACKOUT_CNTL);
@@ -90,8 +86,7 @@ static void gmc_v6_0_mc_stop(struct amdgpu_device *adev,
}
-static void gmc_v6_0_mc_resume(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
+static void gmc_v6_0_mc_resume(struct amdgpu_device *adev)
{
u32 tmp;
@@ -103,10 +98,6 @@ static void gmc_v6_0_mc_resume(struct amdgpu_device *adev,
tmp = REG_SET_FIELD(0, BIF_FB_EN, FB_READ_EN, 1);
tmp = REG_SET_FIELD(tmp, BIF_FB_EN, FB_WRITE_EN, 1);
WREG32(mmBIF_FB_EN, tmp);
-
- if (adev->mode_info.num_crtc)
- amdgpu_display_resume_mc_access(adev, save);
-
}
static int gmc_v6_0_init_microcode(struct amdgpu_device *adev)
@@ -228,20 +219,20 @@ static int gmc_v6_0_mc_load_microcode(struct amdgpu_device *adev)
static void gmc_v6_0_vram_gtt_location(struct amdgpu_device *adev,
struct amdgpu_mc *mc)
{
+ u64 base = RREG32(mmMC_VM_FB_LOCATION) & 0xFFFF;
+ base <<= 24;
+
if (mc->mc_vram_size > 0xFFC0000000ULL) {
dev_warn(adev->dev, "limiting VRAM\n");
mc->real_vram_size = 0xFFC0000000ULL;
mc->mc_vram_size = 0xFFC0000000ULL;
}
- amdgpu_vram_location(adev, &adev->mc, 0);
- adev->mc.gtt_base_align = 0;
- amdgpu_gtt_location(adev, mc);
+ amdgpu_vram_location(adev, &adev->mc, base);
+ amdgpu_gart_location(adev, mc);
}
static void gmc_v6_0_mc_program(struct amdgpu_device *adev)
{
- struct amdgpu_mode_mc_save save;
- u32 tmp;
int i, j;
/* Initialize HDP */
@@ -254,16 +245,23 @@ static void gmc_v6_0_mc_program(struct amdgpu_device *adev)
}
WREG32(mmHDP_REG_COHERENCY_FLUSH_CNTL, 0);
- if (adev->mode_info.num_crtc)
- amdgpu_display_set_vga_render_state(adev, false);
-
- gmc_v6_0_mc_stop(adev, &save);
-
if (gmc_v6_0_wait_for_idle((void *)adev)) {
dev_warn(adev->dev, "Wait for MC idle timedout !\n");
}
- WREG32(mmVGA_HDP_CONTROL, VGA_HDP_CONTROL__VGA_MEMORY_DISABLE_MASK);
+ if (adev->mode_info.num_crtc) {
+ u32 tmp;
+
+ /* Lockout access through VGA aperture*/
+ tmp = RREG32(mmVGA_HDP_CONTROL);
+ tmp |= VGA_HDP_CONTROL__VGA_MEMORY_DISABLE_MASK;
+ WREG32(mmVGA_HDP_CONTROL, tmp);
+
+ /* disable VGA render */
+ tmp = RREG32(mmVGA_RENDER_CONTROL);
+ tmp &= ~VGA_VSTATUS_CNTL;
+ WREG32(mmVGA_RENDER_CONTROL, tmp);
+ }
/* Update configuration */
WREG32(mmMC_VM_SYSTEM_APERTURE_LOW_ADDR,
adev->mc.vram_start >> 12);
@@ -271,13 +269,6 @@ static void gmc_v6_0_mc_program(struct amdgpu_device *adev)
adev->mc.vram_end >> 12);
WREG32(mmMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR,
adev->vram_scratch.gpu_addr >> 12);
- tmp = ((adev->mc.vram_end >> 24) & 0xFFFF) << 16;
- tmp |= ((adev->mc.vram_start >> 24) & 0xFFFF);
- WREG32(mmMC_VM_FB_LOCATION, tmp);
- /* XXX double check these! */
- WREG32(mmHDP_NONSURFACE_BASE, (adev->mc.vram_start >> 8));
- WREG32(mmHDP_NONSURFACE_INFO, (2 << 7) | (1 << 30));
- WREG32(mmHDP_NONSURFACE_SIZE, 0x3FFFFFFF);
WREG32(mmMC_VM_AGP_BASE, 0);
WREG32(mmMC_VM_AGP_TOP, 0x0FFFFFFF);
WREG32(mmMC_VM_AGP_BOT, 0x0FFFFFFF);
@@ -285,7 +276,6 @@ static void gmc_v6_0_mc_program(struct amdgpu_device *adev)
if (gmc_v6_0_wait_for_idle((void *)adev)) {
dev_warn(adev->dev, "Wait for MC idle timedout !\n");
}
- gmc_v6_0_mc_resume(adev, &save);
}
static int gmc_v6_0_mc_init(struct amdgpu_device *adev)
@@ -342,15 +332,7 @@ static int gmc_v6_0_mc_init(struct amdgpu_device *adev)
adev->mc.real_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL;
adev->mc.visible_vram_size = adev->mc.aper_size;
- /* unless the user had overridden it, set the gart
- * size equal to the 1024 or vram, whichever is larger.
- */
- if (amdgpu_gart_size == -1)
- adev->mc.gtt_size = max((AMDGPU_DEFAULT_GTT_SIZE_MB << 20),
- adev->mc.mc_vram_size);
- else
- adev->mc.gtt_size = (uint64_t)amdgpu_gart_size << 20;
-
+ amdgpu_gart_set_defaults(adev);
gmc_v6_0_vram_gtt_location(adev, &adev->mc);
return 0;
@@ -479,6 +461,7 @@ static void gmc_v6_0_set_prt(struct amdgpu_device *adev, bool enable)
static int gmc_v6_0_gart_enable(struct amdgpu_device *adev)
{
int r, i;
+ u32 field;
if (adev->gart.robj == NULL) {
dev_err(adev->dev, "No VRAM object for PCIE GART.\n");
@@ -506,13 +489,15 @@ static int gmc_v6_0_gart_enable(struct amdgpu_device *adev)
WREG32(mmVM_L2_CNTL2,
VM_L2_CNTL2__INVALIDATE_ALL_L1_TLBS_MASK |
VM_L2_CNTL2__INVALIDATE_L2_CACHE_MASK);
+
+ field = adev->vm_manager.fragment_size;
WREG32(mmVM_L2_CNTL3,
VM_L2_CNTL3__L2_CACHE_BIGK_ASSOCIATIVITY_MASK |
- (4UL << VM_L2_CNTL3__BANK_SELECT__SHIFT) |
- (4UL << VM_L2_CNTL3__L2_CACHE_BIGK_FRAGMENT_SIZE__SHIFT));
+ (field << VM_L2_CNTL3__BANK_SELECT__SHIFT) |
+ (field << VM_L2_CNTL3__L2_CACHE_BIGK_FRAGMENT_SIZE__SHIFT));
/* setup context0 */
- WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gtt_start >> 12);
- WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, adev->mc.gtt_end >> 12);
+ WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gart_start >> 12);
+ WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, adev->mc.gart_end >> 12);
WREG32(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR, adev->gart.table_addr >> 12);
WREG32(mmVM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
(u32)(adev->dummy_page.addr >> 12));
@@ -559,7 +544,7 @@ static int gmc_v6_0_gart_enable(struct amdgpu_device *adev)
gmc_v6_0_gart_flush_gpu_tlb(adev, 0);
dev_info(adev->dev, "PCIE GART of %uM enabled (table at 0x%016llX).\n",
- (unsigned)(adev->mc.gtt_size >> 20),
+ (unsigned)(adev->mc.gart_size >> 20),
(unsigned long long)adev->gart.table_addr);
adev->gart.ready = true;
return 0;
@@ -829,7 +814,7 @@ static int gmc_v6_0_sw_init(void *handle)
if (r)
return r;
- amdgpu_vm_adjust_size(adev, 64);
+ amdgpu_vm_adjust_size(adev, 64, 4);
adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18;
adev->mc.mc_mask = 0xffffffffffULL;
@@ -987,7 +972,6 @@ static int gmc_v6_0_wait_for_idle(void *handle)
static int gmc_v6_0_soft_reset(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- struct amdgpu_mode_mc_save save;
u32 srbm_soft_reset = 0;
u32 tmp = RREG32(mmSRBM_STATUS);
@@ -1003,7 +987,7 @@ static int gmc_v6_0_soft_reset(void *handle)
}
if (srbm_soft_reset) {
- gmc_v6_0_mc_stop(adev, &save);
+ gmc_v6_0_mc_stop(adev);
if (gmc_v6_0_wait_for_idle(adev)) {
dev_warn(adev->dev, "Wait for GMC idle timed out !\n");
}
@@ -1023,7 +1007,7 @@ static int gmc_v6_0_soft_reset(void *handle)
udelay(50);
- gmc_v6_0_mc_resume(adev, &save);
+ gmc_v6_0_mc_resume(adev);
udelay(50);
}
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
index 7e9ea53..e42c1ad 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
@@ -37,6 +37,9 @@
#include "oss/oss_2_0_d.h"
#include "oss/oss_2_0_sh_mask.h"
+#include "dce/dce_8_0_d.h"
+#include "dce/dce_8_0_sh_mask.h"
+
#include "amdgpu_atombios.h"
static void gmc_v7_0_set_gart_funcs(struct amdgpu_device *adev);
@@ -76,14 +79,10 @@ static void gmc_v7_0_init_golden_registers(struct amdgpu_device *adev)
}
}
-static void gmc_v7_0_mc_stop(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
+static void gmc_v7_0_mc_stop(struct amdgpu_device *adev)
{
u32 blackout;
- if (adev->mode_info.num_crtc)
- amdgpu_display_stop_mc_access(adev, save);
-
gmc_v7_0_wait_for_idle((void *)adev);
blackout = RREG32(mmMC_SHARED_BLACKOUT_CNTL);
@@ -99,8 +98,7 @@ static void gmc_v7_0_mc_stop(struct amdgpu_device *adev,
udelay(100);
}
-static void gmc_v7_0_mc_resume(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
+static void gmc_v7_0_mc_resume(struct amdgpu_device *adev)
{
u32 tmp;
@@ -112,9 +110,6 @@ static void gmc_v7_0_mc_resume(struct amdgpu_device *adev,
tmp = REG_SET_FIELD(0, BIF_FB_EN, FB_READ_EN, 1);
tmp = REG_SET_FIELD(tmp, BIF_FB_EN, FB_WRITE_EN, 1);
WREG32(mmBIF_FB_EN, tmp);
-
- if (adev->mode_info.num_crtc)
- amdgpu_display_resume_mc_access(adev, save);
}
/**
@@ -242,15 +237,17 @@ static int gmc_v7_0_mc_load_microcode(struct amdgpu_device *adev)
static void gmc_v7_0_vram_gtt_location(struct amdgpu_device *adev,
struct amdgpu_mc *mc)
{
+ u64 base = RREG32(mmMC_VM_FB_LOCATION) & 0xFFFF;
+ base <<= 24;
+
if (mc->mc_vram_size > 0xFFC0000000ULL) {
/* leave room for at least 1024M GTT */
dev_warn(adev->dev, "limiting VRAM\n");
mc->real_vram_size = 0xFFC0000000ULL;
mc->mc_vram_size = 0xFFC0000000ULL;
}
- amdgpu_vram_location(adev, &adev->mc, 0);
- adev->mc.gtt_base_align = 0;
- amdgpu_gtt_location(adev, mc);
+ amdgpu_vram_location(adev, &adev->mc, base);
+ amdgpu_gart_location(adev, mc);
}
/**
@@ -263,7 +260,6 @@ static void gmc_v7_0_vram_gtt_location(struct amdgpu_device *adev,
*/
static void gmc_v7_0_mc_program(struct amdgpu_device *adev)
{
- struct amdgpu_mode_mc_save save;
u32 tmp;
int i, j;
@@ -277,13 +273,20 @@ static void gmc_v7_0_mc_program(struct amdgpu_device *adev)
}
WREG32(mmHDP_REG_COHERENCY_FLUSH_CNTL, 0);
- if (adev->mode_info.num_crtc)
- amdgpu_display_set_vga_render_state(adev, false);
-
- gmc_v7_0_mc_stop(adev, &save);
if (gmc_v7_0_wait_for_idle((void *)adev)) {
dev_warn(adev->dev, "Wait for MC idle timedout !\n");
}
+ if (adev->mode_info.num_crtc) {
+ /* Lockout access through VGA aperture*/
+ tmp = RREG32(mmVGA_HDP_CONTROL);
+ tmp = REG_SET_FIELD(tmp, VGA_HDP_CONTROL, VGA_MEMORY_DISABLE, 1);
+ WREG32(mmVGA_HDP_CONTROL, tmp);
+
+ /* disable VGA render */
+ tmp = RREG32(mmVGA_RENDER_CONTROL);
+ tmp = REG_SET_FIELD(tmp, VGA_RENDER_CONTROL, VGA_VSTATUS_CNTL, 0);
+ WREG32(mmVGA_RENDER_CONTROL, tmp);
+ }
/* Update configuration */
WREG32(mmMC_VM_SYSTEM_APERTURE_LOW_ADDR,
adev->mc.vram_start >> 12);
@@ -291,20 +294,12 @@ static void gmc_v7_0_mc_program(struct amdgpu_device *adev)
adev->mc.vram_end >> 12);
WREG32(mmMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR,
adev->vram_scratch.gpu_addr >> 12);
- tmp = ((adev->mc.vram_end >> 24) & 0xFFFF) << 16;
- tmp |= ((adev->mc.vram_start >> 24) & 0xFFFF);
- WREG32(mmMC_VM_FB_LOCATION, tmp);
- /* XXX double check these! */
- WREG32(mmHDP_NONSURFACE_BASE, (adev->mc.vram_start >> 8));
- WREG32(mmHDP_NONSURFACE_INFO, (2 << 7) | (1 << 30));
- WREG32(mmHDP_NONSURFACE_SIZE, 0x3FFFFFFF);
WREG32(mmMC_VM_AGP_BASE, 0);
WREG32(mmMC_VM_AGP_TOP, 0x0FFFFFFF);
WREG32(mmMC_VM_AGP_BOT, 0x0FFFFFFF);
if (gmc_v7_0_wait_for_idle((void *)adev)) {
dev_warn(adev->dev, "Wait for MC idle timedout !\n");
}
- gmc_v7_0_mc_resume(adev, &save);
WREG32(mmBIF_FB_EN, BIF_FB_EN__FB_READ_EN_MASK | BIF_FB_EN__FB_WRITE_EN_MASK);
@@ -391,15 +386,7 @@ static int gmc_v7_0_mc_init(struct amdgpu_device *adev)
if (adev->mc.visible_vram_size > adev->mc.real_vram_size)
adev->mc.visible_vram_size = adev->mc.real_vram_size;
- /* unless the user had overridden it, set the gart
- * size equal to the 1024 or vram, whichever is larger.
- */
- if (amdgpu_gart_size == -1)
- adev->mc.gtt_size = max((AMDGPU_DEFAULT_GTT_SIZE_MB << 20),
- adev->mc.mc_vram_size);
- else
- adev->mc.gtt_size = (uint64_t)amdgpu_gart_size << 20;
-
+ amdgpu_gart_set_defaults(adev);
gmc_v7_0_vram_gtt_location(adev, &adev->mc);
return 0;
@@ -575,7 +562,7 @@ static void gmc_v7_0_set_prt(struct amdgpu_device *adev, bool enable)
static int gmc_v7_0_gart_enable(struct amdgpu_device *adev)
{
int r, i;
- u32 tmp;
+ u32 tmp, field;
if (adev->gart.robj == NULL) {
dev_err(adev->dev, "No VRAM object for PCIE GART.\n");
@@ -605,14 +592,16 @@ static int gmc_v7_0_gart_enable(struct amdgpu_device *adev)
tmp = REG_SET_FIELD(0, VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS, 1);
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL2, INVALIDATE_L2_CACHE, 1);
WREG32(mmVM_L2_CNTL2, tmp);
+
+ field = adev->vm_manager.fragment_size;
tmp = RREG32(mmVM_L2_CNTL3);
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY, 1);
- tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, 4);
- tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_FRAGMENT_SIZE, 4);
+ tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, field);
+ tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_FRAGMENT_SIZE, field);
WREG32(mmVM_L2_CNTL3, tmp);
/* setup context0 */
- WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gtt_start >> 12);
- WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, adev->mc.gtt_end >> 12);
+ WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gart_start >> 12);
+ WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, adev->mc.gart_end >> 12);
WREG32(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR, adev->gart.table_addr >> 12);
WREG32(mmVM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
(u32)(adev->dummy_page.addr >> 12));
@@ -666,7 +655,7 @@ static int gmc_v7_0_gart_enable(struct amdgpu_device *adev)
gmc_v7_0_gart_flush_gpu_tlb(adev, 0);
DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
- (unsigned)(adev->mc.gtt_size >> 20),
+ (unsigned)(adev->mc.gart_size >> 20),
(unsigned long long)adev->gart.table_addr);
adev->gart.ready = true;
return 0;
@@ -961,7 +950,7 @@ static int gmc_v7_0_sw_init(void *handle)
* Currently set to 4GB ((1 << 20) 4k pages).
* Max GPUVM size for cayman and SI is 40 bits.
*/
- amdgpu_vm_adjust_size(adev, 64);
+ amdgpu_vm_adjust_size(adev, 64, 4);
adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18;
/* Set the internal MC address mask
@@ -1138,7 +1127,6 @@ static int gmc_v7_0_wait_for_idle(void *handle)
static int gmc_v7_0_soft_reset(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- struct amdgpu_mode_mc_save save;
u32 srbm_soft_reset = 0;
u32 tmp = RREG32(mmSRBM_STATUS);
@@ -1154,7 +1142,7 @@ static int gmc_v7_0_soft_reset(void *handle)
}
if (srbm_soft_reset) {
- gmc_v7_0_mc_stop(adev, &save);
+ gmc_v7_0_mc_stop(adev);
if (gmc_v7_0_wait_for_idle((void *)adev)) {
dev_warn(adev->dev, "Wait for GMC idle timed out !\n");
}
@@ -1175,7 +1163,7 @@ static int gmc_v7_0_soft_reset(void *handle)
/* Wait a little for things to settle down */
udelay(50);
- gmc_v7_0_mc_resume(adev, &save);
+ gmc_v7_0_mc_resume(adev);
udelay(50);
}
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
index cc9f880..7ca2dae 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
@@ -35,6 +35,9 @@
#include "oss/oss_3_0_d.h"
#include "oss/oss_3_0_sh_mask.h"
+#include "dce/dce_10_0_d.h"
+#include "dce/dce_10_0_sh_mask.h"
+
#include "vid.h"
#include "vi.h"
@@ -161,14 +164,10 @@ static void gmc_v8_0_init_golden_registers(struct amdgpu_device *adev)
}
}
-static void gmc_v8_0_mc_stop(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
+static void gmc_v8_0_mc_stop(struct amdgpu_device *adev)
{
u32 blackout;
- if (adev->mode_info.num_crtc)
- amdgpu_display_stop_mc_access(adev, save);
-
gmc_v8_0_wait_for_idle(adev);
blackout = RREG32(mmMC_SHARED_BLACKOUT_CNTL);
@@ -184,8 +183,7 @@ static void gmc_v8_0_mc_stop(struct amdgpu_device *adev,
udelay(100);
}
-static void gmc_v8_0_mc_resume(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
+static void gmc_v8_0_mc_resume(struct amdgpu_device *adev)
{
u32 tmp;
@@ -197,9 +195,6 @@ static void gmc_v8_0_mc_resume(struct amdgpu_device *adev,
tmp = REG_SET_FIELD(0, BIF_FB_EN, FB_READ_EN, 1);
tmp = REG_SET_FIELD(tmp, BIF_FB_EN, FB_WRITE_EN, 1);
WREG32(mmBIF_FB_EN, tmp);
-
- if (adev->mode_info.num_crtc)
- amdgpu_display_resume_mc_access(adev, save);
}
/**
@@ -404,15 +399,20 @@ static int gmc_v8_0_polaris_mc_load_microcode(struct amdgpu_device *adev)
static void gmc_v8_0_vram_gtt_location(struct amdgpu_device *adev,
struct amdgpu_mc *mc)
{
+ u64 base = 0;
+
+ if (!amdgpu_sriov_vf(adev))
+ base = RREG32(mmMC_VM_FB_LOCATION) & 0xFFFF;
+ base <<= 24;
+
if (mc->mc_vram_size > 0xFFC0000000ULL) {
/* leave room for at least 1024M GTT */
dev_warn(adev->dev, "limiting VRAM\n");
mc->real_vram_size = 0xFFC0000000ULL;
mc->mc_vram_size = 0xFFC0000000ULL;
}
- amdgpu_vram_location(adev, &adev->mc, 0);
- adev->mc.gtt_base_align = 0;
- amdgpu_gtt_location(adev, mc);
+ amdgpu_vram_location(adev, &adev->mc, base);
+ amdgpu_gart_location(adev, mc);
}
/**
@@ -425,7 +425,6 @@ static void gmc_v8_0_vram_gtt_location(struct amdgpu_device *adev,
*/
static void gmc_v8_0_mc_program(struct amdgpu_device *adev)
{
- struct amdgpu_mode_mc_save save;
u32 tmp;
int i, j;
@@ -439,13 +438,20 @@ static void gmc_v8_0_mc_program(struct amdgpu_device *adev)
}
WREG32(mmHDP_REG_COHERENCY_FLUSH_CNTL, 0);
- if (adev->mode_info.num_crtc)
- amdgpu_display_set_vga_render_state(adev, false);
-
- gmc_v8_0_mc_stop(adev, &save);
if (gmc_v8_0_wait_for_idle((void *)adev)) {
dev_warn(adev->dev, "Wait for MC idle timedout !\n");
}
+ if (adev->mode_info.num_crtc) {
+ /* Lockout access through VGA aperture*/
+ tmp = RREG32(mmVGA_HDP_CONTROL);
+ tmp = REG_SET_FIELD(tmp, VGA_HDP_CONTROL, VGA_MEMORY_DISABLE, 1);
+ WREG32(mmVGA_HDP_CONTROL, tmp);
+
+ /* disable VGA render */
+ tmp = RREG32(mmVGA_RENDER_CONTROL);
+ tmp = REG_SET_FIELD(tmp, VGA_RENDER_CONTROL, VGA_VSTATUS_CNTL, 0);
+ WREG32(mmVGA_RENDER_CONTROL, tmp);
+ }
/* Update configuration */
WREG32(mmMC_VM_SYSTEM_APERTURE_LOW_ADDR,
adev->mc.vram_start >> 12);
@@ -453,20 +459,23 @@ static void gmc_v8_0_mc_program(struct amdgpu_device *adev)
adev->mc.vram_end >> 12);
WREG32(mmMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR,
adev->vram_scratch.gpu_addr >> 12);
- tmp = ((adev->mc.vram_end >> 24) & 0xFFFF) << 16;
- tmp |= ((adev->mc.vram_start >> 24) & 0xFFFF);
- WREG32(mmMC_VM_FB_LOCATION, tmp);
- /* XXX double check these! */
- WREG32(mmHDP_NONSURFACE_BASE, (adev->mc.vram_start >> 8));
- WREG32(mmHDP_NONSURFACE_INFO, (2 << 7) | (1 << 30));
- WREG32(mmHDP_NONSURFACE_SIZE, 0x3FFFFFFF);
+
+ if (amdgpu_sriov_vf(adev)) {
+ tmp = ((adev->mc.vram_end >> 24) & 0xFFFF) << 16;
+ tmp |= ((adev->mc.vram_start >> 24) & 0xFFFF);
+ WREG32(mmMC_VM_FB_LOCATION, tmp);
+ /* XXX double check these! */
+ WREG32(mmHDP_NONSURFACE_BASE, (adev->mc.vram_start >> 8));
+ WREG32(mmHDP_NONSURFACE_INFO, (2 << 7) | (1 << 30));
+ WREG32(mmHDP_NONSURFACE_SIZE, 0x3FFFFFFF);
+ }
+
WREG32(mmMC_VM_AGP_BASE, 0);
WREG32(mmMC_VM_AGP_TOP, 0x0FFFFFFF);
WREG32(mmMC_VM_AGP_BOT, 0x0FFFFFFF);
if (gmc_v8_0_wait_for_idle((void *)adev)) {
dev_warn(adev->dev, "Wait for MC idle timedout !\n");
}
- gmc_v8_0_mc_resume(adev, &save);
WREG32(mmBIF_FB_EN, BIF_FB_EN__FB_READ_EN_MASK | BIF_FB_EN__FB_WRITE_EN_MASK);
@@ -553,15 +562,7 @@ static int gmc_v8_0_mc_init(struct amdgpu_device *adev)
if (adev->mc.visible_vram_size > adev->mc.real_vram_size)
adev->mc.visible_vram_size = adev->mc.real_vram_size;
- /* unless the user had overridden it, set the gart
- * size equal to the 1024 or vram, whichever is larger.
- */
- if (amdgpu_gart_size == -1)
- adev->mc.gtt_size = max((AMDGPU_DEFAULT_GTT_SIZE_MB << 20),
- adev->mc.mc_vram_size);
- else
- adev->mc.gtt_size = (uint64_t)amdgpu_gart_size << 20;
-
+ amdgpu_gart_set_defaults(adev);
gmc_v8_0_vram_gtt_location(adev, &adev->mc);
return 0;
@@ -761,7 +762,7 @@ static void gmc_v8_0_set_prt(struct amdgpu_device *adev, bool enable)
static int gmc_v8_0_gart_enable(struct amdgpu_device *adev)
{
int r, i;
- u32 tmp;
+ u32 tmp, field;
if (adev->gart.robj == NULL) {
dev_err(adev->dev, "No VRAM object for PCIE GART.\n");
@@ -792,10 +793,12 @@ static int gmc_v8_0_gart_enable(struct amdgpu_device *adev)
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS, 1);
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL2, INVALIDATE_L2_CACHE, 1);
WREG32(mmVM_L2_CNTL2, tmp);
+
+ field = adev->vm_manager.fragment_size;
tmp = RREG32(mmVM_L2_CNTL3);
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY, 1);
- tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, 4);
- tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_FRAGMENT_SIZE, 4);
+ tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, field);
+ tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_FRAGMENT_SIZE, field);
WREG32(mmVM_L2_CNTL3, tmp);
/* XXX: set to enable PTE/PDE in system memory */
tmp = RREG32(mmVM_L2_CNTL4);
@@ -813,8 +816,8 @@ static int gmc_v8_0_gart_enable(struct amdgpu_device *adev)
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL4, VMC_TAP_CONTEXT1_PTE_REQUEST_SNOOP, 0);
WREG32(mmVM_L2_CNTL4, tmp);
/* setup context0 */
- WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gtt_start >> 12);
- WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, adev->mc.gtt_end >> 12);
+ WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gart_start >> 12);
+ WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, adev->mc.gart_end >> 12);
WREG32(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR, adev->gart.table_addr >> 12);
WREG32(mmVM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
(u32)(adev->dummy_page.addr >> 12));
@@ -869,7 +872,7 @@ static int gmc_v8_0_gart_enable(struct amdgpu_device *adev)
gmc_v8_0_gart_flush_gpu_tlb(adev, 0);
DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
- (unsigned)(adev->mc.gtt_size >> 20),
+ (unsigned)(adev->mc.gart_size >> 20),
(unsigned long long)adev->gart.table_addr);
adev->gart.ready = true;
return 0;
@@ -1045,7 +1048,7 @@ static int gmc_v8_0_sw_init(void *handle)
* Currently set to 4GB ((1 << 20) 4k pages).
* Max GPUVM size for cayman and SI is 40 bits.
*/
- amdgpu_vm_adjust_size(adev, 64);
+ amdgpu_vm_adjust_size(adev, 64, 4);
adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18;
/* Set the internal MC address mask
@@ -1260,7 +1263,7 @@ static int gmc_v8_0_pre_soft_reset(void *handle)
if (!adev->mc.srbm_soft_reset)
return 0;
- gmc_v8_0_mc_stop(adev, &adev->mc.save);
+ gmc_v8_0_mc_stop(adev);
if (gmc_v8_0_wait_for_idle(adev)) {
dev_warn(adev->dev, "Wait for GMC idle timed out !\n");
}
@@ -1306,7 +1309,7 @@ static int gmc_v8_0_post_soft_reset(void *handle)
if (!adev->mc.srbm_soft_reset)
return 0;
- gmc_v8_0_mc_resume(adev, &adev->mc.save);
+ gmc_v8_0_mc_resume(adev);
return 0;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
index 175ba5f..2769c2b 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
@@ -23,11 +23,14 @@
#include <linux/firmware.h>
#include "amdgpu.h"
#include "gmc_v9_0.h"
+#include "amdgpu_atomfirmware.h"
#include "vega10/soc15ip.h"
#include "vega10/HDP/hdp_4_0_offset.h"
#include "vega10/HDP/hdp_4_0_sh_mask.h"
#include "vega10/GC/gc_9_0_sh_mask.h"
+#include "vega10/DC/dce_12_0_offset.h"
+#include "vega10/DC/dce_12_0_sh_mask.h"
#include "vega10/vega10_enum.h"
#include "soc15_common.h"
@@ -419,8 +422,7 @@ static void gmc_v9_0_vram_gtt_location(struct amdgpu_device *adev,
if (!amdgpu_sriov_vf(adev))
base = mmhub_v1_0_get_fb_location(adev);
amdgpu_vram_location(adev, &adev->mc, base);
- adev->mc.gtt_base_align = 0;
- amdgpu_gtt_location(adev, mc);
+ amdgpu_gart_location(adev, mc);
/* base offset of vram pages */
if (adev->flags & AMD_IS_APU)
adev->vm_manager.vram_base_offset = gfxhub_v1_0_get_mc_fb_offset(adev);
@@ -442,43 +444,46 @@ static int gmc_v9_0_mc_init(struct amdgpu_device *adev)
u32 tmp;
int chansize, numchan;
- /* hbm memory channel size */
- chansize = 128;
-
- tmp = RREG32_SOC15(DF, 0, mmDF_CS_AON0_DramBaseAddress0);
- tmp &= DF_CS_AON0_DramBaseAddress0__IntLvNumChan_MASK;
- tmp >>= DF_CS_AON0_DramBaseAddress0__IntLvNumChan__SHIFT;
- switch (tmp) {
- case 0:
- default:
- numchan = 1;
- break;
- case 1:
- numchan = 2;
- break;
- case 2:
- numchan = 0;
- break;
- case 3:
- numchan = 4;
- break;
- case 4:
- numchan = 0;
- break;
- case 5:
- numchan = 8;
- break;
- case 6:
- numchan = 0;
- break;
- case 7:
- numchan = 16;
- break;
- case 8:
- numchan = 2;
- break;
+ adev->mc.vram_width = amdgpu_atomfirmware_get_vram_width(adev);
+ if (!adev->mc.vram_width) {
+ /* hbm memory channel size */
+ chansize = 128;
+
+ tmp = RREG32_SOC15(DF, 0, mmDF_CS_AON0_DramBaseAddress0);
+ tmp &= DF_CS_AON0_DramBaseAddress0__IntLvNumChan_MASK;
+ tmp >>= DF_CS_AON0_DramBaseAddress0__IntLvNumChan__SHIFT;
+ switch (tmp) {
+ case 0:
+ default:
+ numchan = 1;
+ break;
+ case 1:
+ numchan = 2;
+ break;
+ case 2:
+ numchan = 0;
+ break;
+ case 3:
+ numchan = 4;
+ break;
+ case 4:
+ numchan = 0;
+ break;
+ case 5:
+ numchan = 8;
+ break;
+ case 6:
+ numchan = 0;
+ break;
+ case 7:
+ numchan = 16;
+ break;
+ case 8:
+ numchan = 2;
+ break;
+ }
+ adev->mc.vram_width = numchan * chansize;
}
- adev->mc.vram_width = numchan * chansize;
/* Could aper size report 0 ? */
adev->mc.aper_base = pci_resource_start(adev->pdev, 0);
@@ -494,15 +499,7 @@ static int gmc_v9_0_mc_init(struct amdgpu_device *adev)
if (adev->mc.visible_vram_size > adev->mc.real_vram_size)
adev->mc.visible_vram_size = adev->mc.real_vram_size;
- /* unless the user had overridden it, set the gart
- * size equal to the 1024 or vram, whichever is larger.
- */
- if (amdgpu_gart_size == -1)
- adev->mc.gtt_size = max((AMDGPU_DEFAULT_GTT_SIZE_MB << 20),
- adev->mc.mc_vram_size);
- else
- adev->mc.gtt_size = (uint64_t)amdgpu_gart_size << 20;
-
+ amdgpu_gart_set_defaults(adev);
gmc_v9_0_vram_gtt_location(adev, &adev->mc);
return 0;
@@ -537,10 +534,21 @@ static int gmc_v9_0_sw_init(void *handle)
spin_lock_init(&adev->mc.invalidate_lock);
- if (adev->flags & AMD_IS_APU) {
+ switch (adev->asic_type) {
+ case CHIP_RAVEN:
adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
- amdgpu_vm_adjust_size(adev, 64);
- } else {
+ if (adev->rev_id == 0x0 || adev->rev_id == 0x1) {
+ adev->vm_manager.vm_size = 1U << 18;
+ adev->vm_manager.block_size = 9;
+ adev->vm_manager.num_level = 3;
+ amdgpu_vm_set_fragment_size(adev, 9);
+ } else {
+ /* vm_size is 64GB for legacy 2-level page support */
+ amdgpu_vm_adjust_size(adev, 64, 9);
+ adev->vm_manager.num_level = 1;
+ }
+ break;
+ case CHIP_VEGA10:
/* XXX Don't know how to get VRAM type yet. */
adev->mc.vram_type = AMDGPU_VRAM_TYPE_HBM;
/*
@@ -550,11 +558,18 @@ static int gmc_v9_0_sw_init(void *handle)
*/
adev->vm_manager.vm_size = 1U << 18;
adev->vm_manager.block_size = 9;
- DRM_INFO("vm size is %llu GB, block size is %u-bit\n",
- adev->vm_manager.vm_size,
- adev->vm_manager.block_size);
+ adev->vm_manager.num_level = 3;
+ amdgpu_vm_set_fragment_size(adev, 9);
+ break;
+ default:
+ break;
}
+ DRM_INFO("vm size is %llu GB, block size is %u-bit,fragment size is %u-bit\n",
+ adev->vm_manager.vm_size,
+ adev->vm_manager.block_size,
+ adev->vm_manager.fragment_size);
+
/* This interrupt is VMC page fault.*/
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_VMC, 0,
&adev->mc.vm_fault);
@@ -619,11 +634,6 @@ static int gmc_v9_0_sw_init(void *handle)
adev->vm_manager.id_mgr[AMDGPU_GFXHUB].num_ids = AMDGPU_NUM_OF_VMIDS;
adev->vm_manager.id_mgr[AMDGPU_MMHUB].num_ids = AMDGPU_NUM_OF_VMIDS;
- /* TODO: fix num_level for APU when updating vm size and block size */
- if (adev->flags & AMD_IS_APU)
- adev->vm_manager.num_level = 1;
- else
- adev->vm_manager.num_level = 3;
amdgpu_vm_manager_init(adev);
return 0;
@@ -731,7 +741,7 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev)
gmc_v9_0_gart_flush_gpu_tlb(adev, 0);
DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
- (unsigned)(adev->mc.gtt_size >> 20),
+ (unsigned)(adev->mc.gart_size >> 20),
(unsigned long long)adev->gart.table_addr);
adev->gart.ready = true;
return 0;
@@ -745,6 +755,20 @@ static int gmc_v9_0_hw_init(void *handle)
/* The sequence of these two function calls matters.*/
gmc_v9_0_init_golden_registers(adev);
+ if (adev->mode_info.num_crtc) {
+ u32 tmp;
+
+ /* Lockout access through VGA aperture*/
+ tmp = RREG32_SOC15(DCE, 0, mmVGA_HDP_CONTROL);
+ tmp = REG_SET_FIELD(tmp, VGA_HDP_CONTROL, VGA_MEMORY_DISABLE, 1);
+ WREG32_SOC15(DCE, 0, mmVGA_HDP_CONTROL, tmp);
+
+ /* disable VGA render */
+ tmp = RREG32_SOC15(DCE, 0, mmVGA_RENDER_CONTROL);
+ tmp = REG_SET_FIELD(tmp, VGA_RENDER_CONTROL, VGA_VSTATUS_CNTL, 0);
+ WREG32_SOC15(DCE, 0, mmVGA_RENDER_CONTROL, tmp);
+ }
+
r = gmc_v9_0_gart_enable(adev);
return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
index 9804318..4395a4f 100644
--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
@@ -69,14 +69,14 @@ static void mmhub_v1_0_init_gart_aperture_regs(struct amdgpu_device *adev)
mmhub_v1_0_init_gart_pt_regs(adev);
WREG32_SOC15(MMHUB, 0, mmVM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32,
- (u32)(adev->mc.gtt_start >> 12));
+ (u32)(adev->mc.gart_start >> 12));
WREG32_SOC15(MMHUB, 0, mmVM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32,
- (u32)(adev->mc.gtt_start >> 44));
+ (u32)(adev->mc.gart_start >> 44));
WREG32_SOC15(MMHUB, 0, mmVM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32,
- (u32)(adev->mc.gtt_end >> 12));
+ (u32)(adev->mc.gart_end >> 12));
WREG32_SOC15(MMHUB, 0, mmVM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32,
- (u32)(adev->mc.gtt_end >> 44));
+ (u32)(adev->mc.gart_end >> 44));
}
static void mmhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev)
@@ -138,12 +138,12 @@ static void mmhub_v1_0_init_tlb_regs(struct amdgpu_device *adev)
static void mmhub_v1_0_init_cache_regs(struct amdgpu_device *adev)
{
- uint32_t tmp;
+ uint32_t tmp, field;
/* Setup L2 cache */
tmp = RREG32_SOC15(MMHUB, 0, mmVM_L2_CNTL);
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_CACHE, 1);
- tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING, 0);
+ tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING, 1);
/* XXX for emulation, Refer to closed source code.*/
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, L2_PDE0_CACHE_TAG_GENERATION_MODE,
0);
@@ -157,7 +157,10 @@ static void mmhub_v1_0_init_cache_regs(struct amdgpu_device *adev)
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL2, INVALIDATE_L2_CACHE, 1);
WREG32_SOC15(MMHUB, 0, mmVM_L2_CNTL2, tmp);
+ field = adev->vm_manager.fragment_size;
tmp = mmVM_L2_CNTL3_DEFAULT;
+ tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, field);
+ tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_FRAGMENT_SIZE, 6);
WREG32_SOC15(MMHUB, 0, mmVM_L2_CNTL3, tmp);
tmp = mmVM_L2_CNTL4_DEFAULT;
@@ -222,6 +225,9 @@ static void mmhub_v1_0_setup_vmid_config(struct amdgpu_device *adev)
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
PAGE_TABLE_BLOCK_SIZE,
adev->vm_manager.block_size - 9);
+ /* Send no-retry XNACK on fault to suppress VM fault storm. */
+ tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
+ RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, 0);
WREG32_SOC15_OFFSET(MMHUB, 0, mmVM_CONTEXT1_CNTL, i, tmp);
WREG32_SOC15_OFFSET(MMHUB, 0, mmVM_CONTEXT1_PAGE_TABLE_START_ADDR_LO32, i*2, 0);
WREG32_SOC15_OFFSET(MMHUB, 0, mmVM_CONTEXT1_PAGE_TABLE_START_ADDR_HI32, i*2, 0);
@@ -245,28 +251,28 @@ static void mmhub_v1_0_program_invalidation(struct amdgpu_device *adev)
}
struct pctl_data {
- uint32_t index;
- uint32_t data;
+ uint32_t index;
+ uint32_t data;
};
-const struct pctl_data pctl0_data[] = {
- {0x0, 0x7a640},
- {0x9, 0x2a64a},
- {0xd, 0x2a680},
- {0x11, 0x6a684},
- {0x19, 0xea68e},
- {0x29, 0xa69e},
- {0x2b, 0x34a6c0},
- {0x61, 0x83a707},
- {0xe6, 0x8a7a4},
- {0xf0, 0x1a7b8},
- {0xf3, 0xfa7cc},
- {0x104, 0x17a7dd},
- {0x11d, 0xa7dc},
- {0x11f, 0x12a7f5},
- {0x133, 0xa808},
- {0x135, 0x12a810},
- {0x149, 0x7a82c}
+static const struct pctl_data pctl0_data[] = {
+ {0x0, 0x7a640},
+ {0x9, 0x2a64a},
+ {0xd, 0x2a680},
+ {0x11, 0x6a684},
+ {0x19, 0xea68e},
+ {0x29, 0xa69e},
+ {0x2b, 0x34a6c0},
+ {0x61, 0x83a707},
+ {0xe6, 0x8a7a4},
+ {0xf0, 0x1a7b8},
+ {0xf3, 0xfa7cc},
+ {0x104, 0x17a7dd},
+ {0x11d, 0xa7dc},
+ {0x11f, 0x12a7f5},
+ {0x133, 0xa808},
+ {0x135, 0x12a810},
+ {0x149, 0x7a82c}
};
#define PCTL0_DATA_LEN (sizeof(pctl0_data)/sizeof(pctl0_data[0]))
@@ -274,32 +280,39 @@ const struct pctl_data pctl0_data[] = {
#define PCTL0_STCTRL_REG_SAVE_RANGE0_BASE 0xa640
#define PCTL0_STCTRL_REG_SAVE_RANGE0_LIMIT 0xa833
-const struct pctl_data pctl1_data[] = {
- {0x0, 0x39a000},
- {0x3b, 0x44a040},
- {0x81, 0x2a08d},
- {0x85, 0x6ba094},
- {0xf2, 0x18a100},
- {0x10c, 0x4a132},
- {0x112, 0xca141},
- {0x120, 0x2fa158},
- {0x151, 0x17a1d0},
- {0x16a, 0x1a1e9},
- {0x16d, 0x13a1ec},
- {0x182, 0x7a201},
- {0x18b, 0x3a20a},
- {0x190, 0x7a580},
- {0x199, 0xa590},
- {0x19b, 0x4a594},
- {0x1a1, 0x1a59c},
- {0x1a4, 0x7a82c},
- {0x1ad, 0xfa7cc},
- {0x1be, 0x17a7dd},
- {0x1d7, 0x12a810}
+static const struct pctl_data pctl1_data[] = {
+ {0x0, 0x39a000},
+ {0x3b, 0x44a040},
+ {0x81, 0x2a08d},
+ {0x85, 0x6ba094},
+ {0xf2, 0x18a100},
+ {0x10c, 0x4a132},
+ {0x112, 0xca141},
+ {0x120, 0x2fa158},
+ {0x151, 0x17a1d0},
+ {0x16a, 0x1a1e9},
+ {0x16d, 0x13a1ec},
+ {0x182, 0x7a201},
+ {0x18b, 0x3a20a},
+ {0x190, 0x7a580},
+ {0x199, 0xa590},
+ {0x19b, 0x4a594},
+ {0x1a1, 0x1a59c},
+ {0x1a4, 0x7a82c},
+ {0x1ad, 0xfa7cc},
+ {0x1be, 0x17a7dd},
+ {0x1d7, 0x12a810},
+ {0x1eb, 0x4000a7e1},
+ {0x1ec, 0x5000a7f5},
+ {0x1ed, 0x4000a7e2},
+ {0x1ee, 0x5000a7dc},
+ {0x1ef, 0x4000a7e3},
+ {0x1f0, 0x5000a7f6},
+ {0x1f1, 0x5000a7e4}
};
#define PCTL1_DATA_LEN (sizeof(pctl1_data)/sizeof(pctl1_data[0]))
-#define PCTL1_RENG_EXEC_END_PTR 0x1ea
+#define PCTL1_RENG_EXEC_END_PTR 0x1f1
#define PCTL1_STCTRL_REG_SAVE_RANGE0_BASE 0xa000
#define PCTL1_STCTRL_REG_SAVE_RANGE0_LIMIT 0xa20d
#define PCTL1_STCTRL_REG_SAVE_RANGE1_BASE 0xa580
diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.h b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.h
index 57bb940..5d38229 100644
--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.h
+++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.h
@@ -36,7 +36,4 @@ void mmhub_v1_0_initialize_power_gating(struct amdgpu_device *adev);
void mmhub_v1_0_update_power_gating(struct amdgpu_device *adev,
bool enable);
-extern const struct amd_ip_funcs mmhub_v1_0_ip_funcs;
-extern const struct amdgpu_ip_block_version mmhub_v1_0_ip_block;
-
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c
index bde3ca3..2812d88 100644
--- a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c
+++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c
@@ -72,21 +72,6 @@ static void xgpu_ai_mailbox_set_valid(struct amdgpu_device *adev, bool val)
reg);
}
-static void xgpu_ai_mailbox_trans_msg(struct amdgpu_device *adev,
- enum idh_request req)
-{
- u32 reg;
-
- reg = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0,
- mmBIF_BX_PF0_MAILBOX_MSGBUF_TRN_DW0));
- reg = REG_SET_FIELD(reg, BIF_BX_PF0_MAILBOX_MSGBUF_TRN_DW0,
- MSGBUF_DATA, req);
- WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF0_MAILBOX_MSGBUF_TRN_DW0),
- reg);
-
- xgpu_ai_mailbox_set_valid(adev, true);
-}
-
static int xgpu_ai_mailbox_rcv_msg(struct amdgpu_device *adev,
enum idh_event event)
{
@@ -154,13 +139,25 @@ static int xgpu_ai_poll_msg(struct amdgpu_device *adev, enum idh_event event)
return r;
}
-
-static int xgpu_ai_send_access_requests(struct amdgpu_device *adev,
- enum idh_request req)
-{
+static void xgpu_ai_mailbox_trans_msg (struct amdgpu_device *adev,
+ enum idh_request req, u32 data1, u32 data2, u32 data3) {
+ u32 reg;
int r;
- xgpu_ai_mailbox_trans_msg(adev, req);
+ reg = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0,
+ mmBIF_BX_PF0_MAILBOX_MSGBUF_TRN_DW0));
+ reg = REG_SET_FIELD(reg, BIF_BX_PF0_MAILBOX_MSGBUF_TRN_DW0,
+ MSGBUF_DATA, req);
+ WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF0_MAILBOX_MSGBUF_TRN_DW0),
+ reg);
+ WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF0_MAILBOX_MSGBUF_TRN_DW1),
+ data1);
+ WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF0_MAILBOX_MSGBUF_TRN_DW2),
+ data2);
+ WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF0_MAILBOX_MSGBUF_TRN_DW3),
+ data3);
+
+ xgpu_ai_mailbox_set_valid(adev, true);
/* start to poll ack */
r = xgpu_ai_poll_ack(adev);
@@ -168,6 +165,14 @@ static int xgpu_ai_send_access_requests(struct amdgpu_device *adev,
pr_err("Doesn't get ack from pf, continue\n");
xgpu_ai_mailbox_set_valid(adev, false);
+}
+
+static int xgpu_ai_send_access_requests(struct amdgpu_device *adev,
+ enum idh_request req)
+{
+ int r;
+
+ xgpu_ai_mailbox_trans_msg(adev, req, 0, 0, 0);
/* start to check msg if request is idh_req_gpu_init_access */
if (req == IDH_REQ_GPU_INIT_ACCESS ||
@@ -342,4 +347,5 @@ const struct amdgpu_virt_ops xgpu_ai_virt_ops = {
.req_full_gpu = xgpu_ai_request_full_gpu_access,
.rel_full_gpu = xgpu_ai_release_full_gpu_access,
.reset_gpu = xgpu_ai_request_reset,
+ .trans_msg = xgpu_ai_mailbox_trans_msg,
};
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h
index 9aefc44..1e91b9a 100644
--- a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h
+++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h
@@ -31,7 +31,9 @@ enum idh_request {
IDH_REL_GPU_INIT_ACCESS,
IDH_REQ_GPU_FINI_ACCESS,
IDH_REL_GPU_FINI_ACCESS,
- IDH_REQ_GPU_RESET_ACCESS
+ IDH_REQ_GPU_RESET_ACCESS,
+
+ IDH_LOG_VF_ERROR = 200,
};
enum idh_event {
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c
index 171a658..c25a831 100644
--- a/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c
@@ -613,4 +613,5 @@ const struct amdgpu_virt_ops xgpu_vi_virt_ops = {
.req_full_gpu = xgpu_vi_request_full_gpu_access,
.rel_full_gpu = xgpu_vi_release_full_gpu_access,
.reset_gpu = xgpu_vi_request_reset,
+ .trans_msg = NULL, /* Does not need to trans VF errors to host. */
};
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.h b/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.h
index 2db7411..c791d73 100644
--- a/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.h
+++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.h
@@ -32,7 +32,9 @@ enum idh_request {
IDH_REL_GPU_INIT_ACCESS,
IDH_REQ_GPU_FINI_ACCESS,
IDH_REL_GPU_FINI_ACCESS,
- IDH_REQ_GPU_RESET_ACCESS
+ IDH_REQ_GPU_RESET_ACCESS,
+
+ IDH_LOG_VF_ERROR = 200,
};
/* VI mailbox messages data */
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c
index 1e272f7..045988b 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c
@@ -32,6 +32,7 @@
#define smnCPM_CONTROL 0x11180460
#define smnPCIE_CNTL2 0x11180070
+#define smnPCIE_CONFIG_CNTL 0x11180044
u32 nbio_v6_1_get_rev_id(struct amdgpu_device *adev)
{
@@ -67,7 +68,7 @@ void nbio_v6_1_mc_access_enable(struct amdgpu_device *adev, bool enable)
void nbio_v6_1_hdp_flush(struct amdgpu_device *adev)
{
- WREG32_SOC15(NBIO, 0, mmBIF_BX_PF0_HDP_MEM_COHERENCY_FLUSH_CNTL, 0);
+ WREG32_SOC15_NO_KIQ(NBIO, 0, mmBIF_BX_PF0_HDP_MEM_COHERENCY_FLUSH_CNTL, 0);
}
u32 nbio_v6_1_get_memsize(struct amdgpu_device *adev)
@@ -256,3 +257,15 @@ void nbio_v6_1_detect_hw_virt(struct amdgpu_device *adev)
adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE;
}
}
+
+void nbio_v6_1_init_registers(struct amdgpu_device *adev)
+{
+ uint32_t def, data;
+
+ def = data = RREG32_PCIE(smnPCIE_CONFIG_CNTL);
+ data = REG_SET_FIELD(data, PCIE_CONFIG_CNTL, CI_SWUS_MAX_READ_REQUEST_SIZE_MODE, 1);
+ data = REG_SET_FIELD(data, PCIE_CONFIG_CNTL, CI_SWUS_MAX_READ_REQUEST_SIZE_PRIV, 1);
+
+ if (def != data)
+ WREG32_PCIE(smnPCIE_CONFIG_CNTL, data);
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.h b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.h
index f6f8bc0..686e4b4 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.h
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.h
@@ -50,5 +50,6 @@ void nbio_v6_1_update_medium_grain_clock_gating(struct amdgpu_device *adev, bool
void nbio_v6_1_update_medium_grain_light_sleep(struct amdgpu_device *adev, bool enable);
void nbio_v6_1_get_clockgating_state(struct amdgpu_device *adev, u32 *flags);
void nbio_v6_1_detect_hw_virt(struct amdgpu_device *adev);
+void nbio_v6_1_init_registers(struct amdgpu_device *adev);
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c
index aa04632..11b70d6 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c
@@ -65,7 +65,7 @@ void nbio_v7_0_mc_access_enable(struct amdgpu_device *adev, bool enable)
void nbio_v7_0_hdp_flush(struct amdgpu_device *adev)
{
- WREG32_SOC15(NBIO, 0, mmHDP_MEM_COHERENCY_FLUSH_CNTL, 0);
+ WREG32_SOC15_NO_KIQ(NBIO, 0, mmHDP_MEM_COHERENCY_FLUSH_CNTL, 0);
}
u32 nbio_v7_0_get_memsize(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
index 2258323..f7cf994 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
@@ -86,6 +86,52 @@ psp_v10_0_get_fw_type(struct amdgpu_firmware_info *ucode, enum psp_gfx_fw_type *
return 0;
}
+int psp_v10_0_init_microcode(struct psp_context *psp)
+{
+ struct amdgpu_device *adev = psp->adev;
+ const char *chip_name;
+ char fw_name[30];
+ int err = 0;
+ const struct psp_firmware_header_v1_0 *hdr;
+
+ DRM_DEBUG("\n");
+
+ switch (adev->asic_type) {
+ case CHIP_RAVEN:
+ chip_name = "raven";
+ break;
+ default: BUG();
+ }
+
+ snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_asd.bin", chip_name);
+ err = request_firmware(&adev->psp.asd_fw, fw_name, adev->dev);
+ if (err)
+ goto out;
+
+ err = amdgpu_ucode_validate(adev->psp.asd_fw);
+ if (err)
+ goto out;
+
+ hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.asd_fw->data;
+ adev->psp.asd_fw_version = le32_to_cpu(hdr->header.ucode_version);
+ adev->psp.asd_feature_version = le32_to_cpu(hdr->ucode_feature_version);
+ adev->psp.asd_ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes);
+ adev->psp.asd_start_addr = (uint8_t *)hdr +
+ le32_to_cpu(hdr->header.ucode_array_offset_bytes);
+
+ return 0;
+out:
+ if (err) {
+ dev_err(adev->dev,
+ "psp v10.0: Failed to load firmware \"%s\"\n",
+ fw_name);
+ release_firmware(adev->psp.asd_fw);
+ adev->psp.asd_fw = NULL;
+ }
+
+ return err;
+}
+
int psp_v10_0_prep_cmd_buf(struct amdgpu_firmware_info *ucode, struct psp_gfx_cmd_resp *cmd)
{
int ret;
@@ -110,7 +156,6 @@ int psp_v10_0_prep_cmd_buf(struct amdgpu_firmware_info *ucode, struct psp_gfx_cm
int psp_v10_0_ring_init(struct psp_context *psp, enum psp_ring_type ring_type)
{
int ret = 0;
- unsigned int psp_ring_reg = 0;
struct psp_ring *ring;
struct amdgpu_device *adev = psp->adev;
@@ -130,6 +175,16 @@ int psp_v10_0_ring_init(struct psp_context *psp, enum psp_ring_type ring_type)
return ret;
}
+ return 0;
+}
+
+int psp_v10_0_ring_create(struct psp_context *psp, enum psp_ring_type ring_type)
+{
+ int ret = 0;
+ unsigned int psp_ring_reg = 0;
+ struct psp_ring *ring = &psp->km_ring;
+ struct amdgpu_device *adev = psp->adev;
+
/* Write low address of the ring to C2PMSG_69 */
psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr);
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_69, psp_ring_reg);
@@ -143,13 +198,42 @@ int psp_v10_0_ring_init(struct psp_context *psp, enum psp_ring_type ring_type)
psp_ring_reg = ring_type;
psp_ring_reg = psp_ring_reg << 16;
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64, psp_ring_reg);
+
+ /* There might be handshake issue with hardware which needs delay */
+ mdelay(20);
+
/* Wait for response flag (bit 31) in C2PMSG_64 */
- psp_ring_reg = 0;
- while ((psp_ring_reg & 0x80000000) == 0) {
- psp_ring_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64);
- }
+ ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64),
+ 0x80000000, 0x8000FFFF, false);
- return 0;
+ return ret;
+}
+
+int psp_v10_0_ring_destroy(struct psp_context *psp, enum psp_ring_type ring_type)
+{
+ int ret = 0;
+ struct psp_ring *ring;
+ unsigned int psp_ring_reg = 0;
+ struct amdgpu_device *adev = psp->adev;
+
+ ring = &psp->km_ring;
+
+ /* Write the ring destroy command to C2PMSG_64 */
+ psp_ring_reg = 3 << 16;
+ WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64, psp_ring_reg);
+
+ /* There might be handshake issue with hardware which needs delay */
+ mdelay(20);
+
+ /* Wait for response flag (bit 31) in C2PMSG_64 */
+ ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64),
+ 0x80000000, 0x80000000, false);
+
+ amdgpu_bo_free_kernel(&adev->firmware.rbuf,
+ &ring->ring_mem_mc_addr,
+ (void **)&ring->ring_mem);
+
+ return ret;
}
int psp_v10_0_cmd_submit(struct psp_context *psp,
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.h b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.h
index 2022b7b..e76cde2 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.h
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.h
@@ -27,10 +27,15 @@
#include "amdgpu_psp.h"
+extern int psp_v10_0_init_microcode(struct psp_context *psp);
extern int psp_v10_0_prep_cmd_buf(struct amdgpu_firmware_info *ucode,
struct psp_gfx_cmd_resp *cmd);
extern int psp_v10_0_ring_init(struct psp_context *psp,
enum psp_ring_type ring_type);
+extern int psp_v10_0_ring_create(struct psp_context *psp,
+ enum psp_ring_type ring_type);
+extern int psp_v10_0_ring_destroy(struct psp_context *psp,
+ enum psp_ring_type ring_type);
extern int psp_v10_0_cmd_submit(struct psp_context *psp,
struct amdgpu_firmware_info *ucode,
uint64_t cmd_buf_mc_addr, uint64_t fence_mc_addr,
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
index c98d77d..2a535a4 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
@@ -237,11 +237,9 @@ int psp_v3_1_bootloader_load_sos(struct psp_context *psp)
/* there might be handshake issue with hardware which needs delay */
mdelay(20);
-#if 0
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_81),
RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81),
0, true);
-#endif
return ret;
}
@@ -341,10 +339,10 @@ int psp_v3_1_ring_destroy(struct psp_context *psp, enum psp_ring_type ring_type)
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64),
0x80000000, 0x80000000, false);
- if (ring->ring_mem)
- amdgpu_bo_free_kernel(&adev->firmware.rbuf,
- &ring->ring_mem_mc_addr,
- (void **)&ring->ring_mem);
+ amdgpu_bo_free_kernel(&adev->firmware.rbuf,
+ &ring->ring_mem_mc_addr,
+ (void **)&ring->ring_mem);
+
return ret;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
index 1d766ae..b1de44f 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
@@ -551,17 +551,53 @@ static void sdma_v3_0_rlc_stop(struct amdgpu_device *adev)
*/
static void sdma_v3_0_ctx_switch_enable(struct amdgpu_device *adev, bool enable)
{
- u32 f32_cntl;
+ u32 f32_cntl, phase_quantum = 0;
int i;
+ if (amdgpu_sdma_phase_quantum) {
+ unsigned value = amdgpu_sdma_phase_quantum;
+ unsigned unit = 0;
+
+ while (value > (SDMA0_PHASE0_QUANTUM__VALUE_MASK >>
+ SDMA0_PHASE0_QUANTUM__VALUE__SHIFT)) {
+ value = (value + 1) >> 1;
+ unit++;
+ }
+ if (unit > (SDMA0_PHASE0_QUANTUM__UNIT_MASK >>
+ SDMA0_PHASE0_QUANTUM__UNIT__SHIFT)) {
+ value = (SDMA0_PHASE0_QUANTUM__VALUE_MASK >>
+ SDMA0_PHASE0_QUANTUM__VALUE__SHIFT);
+ unit = (SDMA0_PHASE0_QUANTUM__UNIT_MASK >>
+ SDMA0_PHASE0_QUANTUM__UNIT__SHIFT);
+ WARN_ONCE(1,
+ "clamping sdma_phase_quantum to %uK clock cycles\n",
+ value << unit);
+ }
+ phase_quantum =
+ value << SDMA0_PHASE0_QUANTUM__VALUE__SHIFT |
+ unit << SDMA0_PHASE0_QUANTUM__UNIT__SHIFT;
+ }
+
for (i = 0; i < adev->sdma.num_instances; i++) {
f32_cntl = RREG32(mmSDMA0_CNTL + sdma_offsets[i]);
- if (enable)
+ if (enable) {
f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
AUTO_CTXSW_ENABLE, 1);
- else
+ f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
+ ATC_L1_ENABLE, 1);
+ if (amdgpu_sdma_phase_quantum) {
+ WREG32(mmSDMA0_PHASE0_QUANTUM + sdma_offsets[i],
+ phase_quantum);
+ WREG32(mmSDMA0_PHASE1_QUANTUM + sdma_offsets[i],
+ phase_quantum);
+ }
+ } else {
f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
AUTO_CTXSW_ENABLE, 0);
+ f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
+ ATC_L1_ENABLE, 1);
+ }
+
WREG32(mmSDMA0_CNTL + sdma_offsets[i], f32_cntl);
}
}
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
index 4a65697..fd7c72a 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
@@ -291,6 +291,8 @@ static void sdma_v4_0_ring_set_wptr(struct amdgpu_ring *ring)
DRM_DEBUG("Setting write pointer\n");
if (ring->use_doorbell) {
+ u64 *wb = (u64 *)&adev->wb.wb[ring->wptr_offs];
+
DRM_DEBUG("Using doorbell -- "
"wptr_offs == 0x%08x "
"lower_32_bits(ring->wptr) << 2 == 0x%08x "
@@ -299,8 +301,7 @@ static void sdma_v4_0_ring_set_wptr(struct amdgpu_ring *ring)
lower_32_bits(ring->wptr << 2),
upper_32_bits(ring->wptr << 2));
/* XXX check if swapping is necessary on BE */
- adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr << 2);
- adev->wb.wb[ring->wptr_offs + 1] = upper_32_bits(ring->wptr << 2);
+ WRITE_ONCE(*wb, (ring->wptr << 2));
DRM_DEBUG("calling WDOORBELL64(0x%08x, 0x%016llx)\n",
ring->doorbell_index, ring->wptr << 2);
WDOORBELL64(ring->doorbell_index, ring->wptr << 2);
@@ -493,13 +494,45 @@ static void sdma_v4_0_rlc_stop(struct amdgpu_device *adev)
*/
static void sdma_v4_0_ctx_switch_enable(struct amdgpu_device *adev, bool enable)
{
- u32 f32_cntl;
+ u32 f32_cntl, phase_quantum = 0;
int i;
+ if (amdgpu_sdma_phase_quantum) {
+ unsigned value = amdgpu_sdma_phase_quantum;
+ unsigned unit = 0;
+
+ while (value > (SDMA0_PHASE0_QUANTUM__VALUE_MASK >>
+ SDMA0_PHASE0_QUANTUM__VALUE__SHIFT)) {
+ value = (value + 1) >> 1;
+ unit++;
+ }
+ if (unit > (SDMA0_PHASE0_QUANTUM__UNIT_MASK >>
+ SDMA0_PHASE0_QUANTUM__UNIT__SHIFT)) {
+ value = (SDMA0_PHASE0_QUANTUM__VALUE_MASK >>
+ SDMA0_PHASE0_QUANTUM__VALUE__SHIFT);
+ unit = (SDMA0_PHASE0_QUANTUM__UNIT_MASK >>
+ SDMA0_PHASE0_QUANTUM__UNIT__SHIFT);
+ WARN_ONCE(1,
+ "clamping sdma_phase_quantum to %uK clock cycles\n",
+ value << unit);
+ }
+ phase_quantum =
+ value << SDMA0_PHASE0_QUANTUM__VALUE__SHIFT |
+ unit << SDMA0_PHASE0_QUANTUM__UNIT__SHIFT;
+ }
+
for (i = 0; i < adev->sdma.num_instances; i++) {
f32_cntl = RREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_CNTL));
f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
AUTO_CTXSW_ENABLE, enable ? 1 : 0);
+ if (enable && amdgpu_sdma_phase_quantum) {
+ WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_PHASE0_QUANTUM),
+ phase_quantum);
+ WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_PHASE1_QUANTUM),
+ phase_quantum);
+ WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_PHASE2_QUANTUM),
+ phase_quantum);
+ }
WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_CNTL), f32_cntl);
}
@@ -541,12 +574,13 @@ static void sdma_v4_0_enable(struct amdgpu_device *adev, bool enable)
static int sdma_v4_0_gfx_resume(struct amdgpu_device *adev)
{
struct amdgpu_ring *ring;
- u32 rb_cntl, ib_cntl;
+ u32 rb_cntl, ib_cntl, wptr_poll_cntl;
u32 rb_bufsz;
u32 wb_offset;
u32 doorbell;
u32 doorbell_offset;
u32 temp;
+ u64 wptr_gpu_addr;
int i, r;
for (i = 0; i < adev->sdma.num_instances; i++) {
@@ -628,6 +662,19 @@ static int sdma_v4_0_gfx_resume(struct amdgpu_device *adev)
WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_F32_CNTL), temp);
}
+ /* setup the wptr shadow polling */
+ wptr_gpu_addr = adev->wb.gpu_addr + (ring->wptr_offs * 4);
+ WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_WPTR_POLL_ADDR_LO),
+ lower_32_bits(wptr_gpu_addr));
+ WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_WPTR_POLL_ADDR_HI),
+ upper_32_bits(wptr_gpu_addr));
+ wptr_poll_cntl = RREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_WPTR_POLL_CNTL));
+ if (amdgpu_sriov_vf(adev))
+ wptr_poll_cntl = REG_SET_FIELD(wptr_poll_cntl, SDMA0_GFX_RB_WPTR_POLL_CNTL, F32_POLL_ENABLE, 1);
+ else
+ wptr_poll_cntl = REG_SET_FIELD(wptr_poll_cntl, SDMA0_GFX_RB_WPTR_POLL_CNTL, F32_POLL_ENABLE, 0);
+ WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_WPTR_POLL_CNTL), wptr_poll_cntl);
+
/* enable DMA RB */
rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 1);
WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_CNTL), rb_cntl);
@@ -655,6 +702,7 @@ static int sdma_v4_0_gfx_resume(struct amdgpu_device *adev)
if (adev->mman.buffer_funcs_ring == ring)
amdgpu_ttm_set_active_vram_size(adev, adev->mc.real_vram_size);
+
}
return 0;
@@ -751,15 +799,12 @@ static int sdma_v4_0_load_microcode(struct amdgpu_device *adev)
const struct sdma_firmware_header_v1_0 *hdr;
const __le32 *fw_data;
u32 fw_size;
- u32 digest_size = 0;
int i, j;
/* halt the MEs */
sdma_v4_0_enable(adev, false);
for (i = 0; i < adev->sdma.num_instances; i++) {
- uint16_t version_major;
- uint16_t version_minor;
if (!adev->sdma.instance[i].fw)
return -EINVAL;
@@ -767,23 +812,12 @@ static int sdma_v4_0_load_microcode(struct amdgpu_device *adev)
amdgpu_ucode_print_sdma_hdr(&hdr->header);
fw_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
- version_major = le16_to_cpu(hdr->header.header_version_major);
- version_minor = le16_to_cpu(hdr->header.header_version_minor);
-
- if (version_major == 1 && version_minor >= 1) {
- const struct sdma_firmware_header_v1_1 *sdma_v1_1_hdr = (const struct sdma_firmware_header_v1_1 *) hdr;
- digest_size = le32_to_cpu(sdma_v1_1_hdr->digest_size);
- }
-
- fw_size -= digest_size;
-
fw_data = (const __le32 *)
(adev->sdma.instance[i].fw->data +
le32_to_cpu(hdr->header.ucode_array_offset_bytes));
WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_UCODE_ADDR), 0);
-
for (j = 0; j < fw_size; j++)
WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_UCODE_DATA), le32_to_cpup(fw_data++));
diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c
index 4267fa4..8284d5d 100644
--- a/drivers/gpu/drm/amd/amdgpu/si.c
+++ b/drivers/gpu/drm/amd/amdgpu/si.c
@@ -1150,6 +1150,33 @@ static bool si_read_disabled_bios(struct amdgpu_device *adev)
return r;
}
+#define mmROM_INDEX 0x2A
+#define mmROM_DATA 0x2B
+
+static bool si_read_bios_from_rom(struct amdgpu_device *adev,
+ u8 *bios, u32 length_bytes)
+{
+ u32 *dw_ptr;
+ u32 i, length_dw;
+
+ if (bios == NULL)
+ return false;
+ if (length_bytes == 0)
+ return false;
+ /* APU vbios image is part of sbios image */
+ if (adev->flags & AMD_IS_APU)
+ return false;
+
+ dw_ptr = (u32 *)bios;
+ length_dw = ALIGN(length_bytes, 4) / 4;
+ /* set rom index to 0 */
+ WREG32(mmROM_INDEX, 0);
+ for (i = 0; i < length_dw; i++)
+ dw_ptr[i] = RREG32(mmROM_DATA);
+
+ return true;
+}
+
//xxx: not implemented
static int si_asic_reset(struct amdgpu_device *adev)
{
@@ -1206,6 +1233,7 @@ static void si_detect_hw_virtualization(struct amdgpu_device *adev)
static const struct amdgpu_asic_funcs si_asic_funcs =
{
.read_disabled_bios = &si_read_disabled_bios,
+ .read_bios_from_rom = &si_read_bios_from_rom,
.read_register = &si_read_register,
.reset = &si_asic_reset,
.set_vga_state = &si_vga_set_state,
diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c
index a7ad839..d63873f 100644
--- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c
+++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c
@@ -2055,6 +2055,7 @@ static void si_initialize_powertune_defaults(struct amdgpu_device *adev)
case 0x682C:
si_pi->cac_weights = cac_weights_cape_verde_pro;
si_pi->dte_data = dte_data_sun_xt;
+ update_dte_from_pl2 = true;
break;
case 0x6825:
case 0x6827:
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c
index a7341d8..f2c3a49 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15.c
+++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
@@ -25,7 +25,7 @@
#include <linux/module.h>
#include <drm/drmP.h>
#include "amdgpu.h"
-#include "amdgpu_atomfirmware.h"
+#include "amdgpu_atombios.h"
#include "amdgpu_ih.h"
#include "amdgpu_uvd.h"
#include "amdgpu_vce.h"
@@ -62,8 +62,6 @@
#include "dce_virtual.h"
#include "mxgpu_ai.h"
-MODULE_FIRMWARE("amdgpu/vega10_smc.bin");
-
#define mmFabricConfigAccessControl 0x0410
#define mmFabricConfigAccessControl_BASE_IDX 0
#define mmFabricConfigAccessControl_DEFAULT 0x00000000
@@ -198,6 +196,50 @@ static void soc15_didt_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
spin_unlock_irqrestore(&adev->didt_idx_lock, flags);
}
+static u32 soc15_gc_cac_rreg(struct amdgpu_device *adev, u32 reg)
+{
+ unsigned long flags;
+ u32 r;
+
+ spin_lock_irqsave(&adev->gc_cac_idx_lock, flags);
+ WREG32_SOC15(GC, 0, mmGC_CAC_IND_INDEX, (reg));
+ r = RREG32_SOC15(GC, 0, mmGC_CAC_IND_DATA);
+ spin_unlock_irqrestore(&adev->gc_cac_idx_lock, flags);
+ return r;
+}
+
+static void soc15_gc_cac_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&adev->gc_cac_idx_lock, flags);
+ WREG32_SOC15(GC, 0, mmGC_CAC_IND_INDEX, (reg));
+ WREG32_SOC15(GC, 0, mmGC_CAC_IND_DATA, (v));
+ spin_unlock_irqrestore(&adev->gc_cac_idx_lock, flags);
+}
+
+static u32 soc15_se_cac_rreg(struct amdgpu_device *adev, u32 reg)
+{
+ unsigned long flags;
+ u32 r;
+
+ spin_lock_irqsave(&adev->se_cac_idx_lock, flags);
+ WREG32_SOC15(GC, 0, mmSE_CAC_IND_INDEX, (reg));
+ r = RREG32_SOC15(GC, 0, mmSE_CAC_IND_DATA);
+ spin_unlock_irqrestore(&adev->se_cac_idx_lock, flags);
+ return r;
+}
+
+static void soc15_se_cac_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&adev->se_cac_idx_lock, flags);
+ WREG32_SOC15(GC, 0, mmSE_CAC_IND_INDEX, (reg));
+ WREG32_SOC15(GC, 0, mmSE_CAC_IND_DATA, (v));
+ spin_unlock_irqrestore(&adev->se_cac_idx_lock, flags);
+}
+
static u32 soc15_get_config_memsize(struct amdgpu_device *adev)
{
if (adev->flags & AMD_IS_APU)
@@ -392,11 +434,11 @@ static void soc15_gpu_pci_config_reset(struct amdgpu_device *adev)
static int soc15_asic_reset(struct amdgpu_device *adev)
{
- amdgpu_atomfirmware_scratch_regs_engine_hung(adev, true);
+ amdgpu_atombios_scratch_regs_engine_hung(adev, true);
soc15_gpu_pci_config_reset(adev);
- amdgpu_atomfirmware_scratch_regs_engine_hung(adev, false);
+ amdgpu_atombios_scratch_regs_engine_hung(adev, false);
return 0;
}
@@ -524,13 +566,6 @@ static uint32_t soc15_get_rev_id(struct amdgpu_device *adev)
return nbio_v6_1_get_rev_id(adev);
}
-
-int gmc_v9_0_mc_wait_for_idle(struct amdgpu_device *adev)
-{
- /* to be implemented in MC IP*/
- return 0;
-}
-
static const struct amdgpu_asic_funcs soc15_asic_funcs =
{
.read_disabled_bios = &soc15_read_disabled_bios,
@@ -557,6 +592,10 @@ static int soc15_common_early_init(void *handle)
adev->uvd_ctx_wreg = &soc15_uvd_ctx_wreg;
adev->didt_rreg = &soc15_didt_rreg;
adev->didt_wreg = &soc15_didt_wreg;
+ adev->gc_cac_rreg = &soc15_gc_cac_rreg;
+ adev->gc_cac_wreg = &soc15_gc_cac_wreg;
+ adev->se_cac_rreg = &soc15_se_cac_rreg;
+ adev->se_cac_wreg = &soc15_se_cac_wreg;
adev->asic_funcs = &soc15_asic_funcs;
@@ -681,6 +720,9 @@ static int soc15_common_hw_init(void *handle)
soc15_pcie_gen3_enable(adev);
/* enable aspm */
soc15_program_aspm(adev);
+ /* setup nbio registers */
+ if (!(adev->flags & AMD_IS_APU))
+ nbio_v6_1_init_registers(adev);
/* enable the doorbell aperture */
soc15_enable_doorbell_aperture(adev, true);
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15_common.h b/drivers/gpu/drm/amd/amdgpu/soc15_common.h
index e2d330e..7a8e4e2 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15_common.h
+++ b/drivers/gpu/drm/amd/amdgpu/soc15_common.h
@@ -77,6 +77,13 @@ struct nbio_pcie_index_data {
(3 == reg##_BASE_IDX ? ip##_BASE__INST##inst##_SEG3 + reg : \
(ip##_BASE__INST##inst##_SEG4 + reg))))), value)
+#define WREG32_SOC15_NO_KIQ(ip, inst, reg, value) \
+ WREG32_NO_KIQ( (0 == reg##_BASE_IDX ? ip##_BASE__INST##inst##_SEG0 + reg : \
+ (1 == reg##_BASE_IDX ? ip##_BASE__INST##inst##_SEG1 + reg : \
+ (2 == reg##_BASE_IDX ? ip##_BASE__INST##inst##_SEG2 + reg : \
+ (3 == reg##_BASE_IDX ? ip##_BASE__INST##inst##_SEG3 + reg : \
+ (ip##_BASE__INST##inst##_SEG4 + reg))))), value)
+
#define WREG32_SOC15_OFFSET(ip, inst, reg, offset, value) \
WREG32( (0 == reg##_BASE_IDX ? ip##_BASE__INST##inst##_SEG0 + reg : \
(1 == reg##_BASE_IDX ? ip##_BASE__INST##inst##_SEG1 + reg : \
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15d.h b/drivers/gpu/drm/amd/amdgpu/soc15d.h
index e79befd..7f408f8 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15d.h
+++ b/drivers/gpu/drm/amd/amdgpu/soc15d.h
@@ -250,6 +250,7 @@
#define PACKET3_SET_UCONFIG_REG 0x79
#define PACKET3_SET_UCONFIG_REG_START 0x0000c000
#define PACKET3_SET_UCONFIG_REG_END 0x0000c400
+#define PACKET3_SET_UCONFIG_REG_INDEX_TYPE (2 << 28)
#define PACKET3_SCRATCH_RAM_WRITE 0x7D
#define PACKET3_SCRATCH_RAM_READ 0x7E
#define PACKET3_LOAD_CONST_RAM 0x80
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
index 987b958..23a8575 100644
--- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
@@ -165,6 +165,9 @@ static int uvd_v7_0_enc_ring_test_ring(struct amdgpu_ring *ring)
unsigned i;
int r;
+ if (amdgpu_sriov_vf(adev))
+ return 0;
+
r = amdgpu_ring_alloc(ring, 16);
if (r) {
DRM_ERROR("amdgpu: uvd enc failed to lock ring %d (%d).\n",
@@ -432,13 +435,19 @@ static int uvd_v7_0_sw_init(void *handle)
return r;
}
-
for (i = 0; i < adev->uvd.num_enc_rings; ++i) {
ring = &adev->uvd.ring_enc[i];
sprintf(ring->name, "uvd_enc%d", i);
if (amdgpu_sriov_vf(adev)) {
ring->use_doorbell = true;
- ring->doorbell_index = AMDGPU_DOORBELL64_UVD_RING0_1 * 2;
+
+ /* currently only use the first enconding ring for
+ * sriov, so set unused location for other unused rings.
+ */
+ if (i == 0)
+ ring->doorbell_index = AMDGPU_DOORBELL64_UVD_RING0_1 * 2;
+ else
+ ring->doorbell_index = AMDGPU_DOORBELL64_UVD_RING2_3 * 2 + 1;
}
r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.irq, 0);
if (r)
@@ -685,6 +694,11 @@ static int uvd_v7_0_mmsch_start(struct amdgpu_device *adev,
/* 4, set resp to zero */
WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_RESP, 0);
+ WDOORBELL32(adev->uvd.ring_enc[0].doorbell_index, 0);
+ adev->wb.wb[adev->uvd.ring_enc[0].wptr_offs] = 0;
+ adev->uvd.ring_enc[0].wptr = 0;
+ adev->uvd.ring_enc[0].wptr_old = 0;
+
/* 5, kick off the initialization and wait until VCE_MMSCH_VF_MAILBOX_RESP becomes non-zero */
WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_HOST, 0x10000001);
@@ -702,7 +716,6 @@ static int uvd_v7_0_mmsch_start(struct amdgpu_device *adev,
dev_err(adev->dev, "failed to init MMSCH, mmVCE_MMSCH_VF_MAILBOX_RESP = %x\n", data);
return -EBUSY;
}
- WDOORBELL32(adev->uvd.ring_enc[0].doorbell_index, 0);
return 0;
}
@@ -736,11 +749,9 @@ static int uvd_v7_0_sriov_start(struct amdgpu_device *adev)
init_table += header->uvd_table_offset;
ring = &adev->uvd.ring;
+ ring->wptr = 0;
size = AMDGPU_GPU_PAGE_ALIGN(adev->uvd.fw->size + 4);
- /* disable clock gating */
- MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_POWER_STATUS),
- ~UVD_POWER_STATUS__UVD_PG_MODE_MASK, 0);
MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_STATUS),
0xFFFFFFFF, 0x00000004);
/* mc resume*/
@@ -777,12 +788,6 @@ static int uvd_v7_0_sriov_start(struct amdgpu_device *adev)
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_SIZE2),
AMDGPU_UVD_STACK_SIZE + (AMDGPU_UVD_SESSION_SIZE * 40));
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_UDEC_ADDR_CONFIG),
- adev->gfx.config.gb_addr_config);
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_UDEC_DB_ADDR_CONFIG),
- adev->gfx.config.gb_addr_config);
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_UDEC_DBW_ADDR_CONFIG),
- adev->gfx.config.gb_addr_config);
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_GP_SCRATCH4), adev->uvd.max_handles);
/* mc resume end*/
@@ -819,17 +824,6 @@ static int uvd_v7_0_sriov_start(struct amdgpu_device *adev)
UVD_LMI_CTRL__REQ_MODE_MASK |
0x00100000L));
- /* disable byte swapping */
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_SWAP_CNTL), 0);
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_MP_SWAP_CNTL), 0);
-
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_MPC_SET_MUXA0), 0x40c2040);
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_MPC_SET_MUXA1), 0x0);
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_MPC_SET_MUXB0), 0x40c2040);
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_MPC_SET_MUXB1), 0x0);
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_MPC_SET_ALU), 0);
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_MPC_SET_MUX), 0x88);
-
/* take all subblocks out of reset, except VCPU */
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET),
UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
@@ -838,15 +832,6 @@ static int uvd_v7_0_sriov_start(struct amdgpu_device *adev)
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CNTL),
UVD_VCPU_CNTL__CLK_EN_MASK);
- /* enable UMC */
- MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2),
- ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, 0);
-
- /* boot up the VCPU */
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), 0);
-
- MMSCH_V1_0_INSERT_DIRECT_POLL(SOC15_REG_OFFSET(UVD, 0, mmUVD_STATUS), 0x02, 0x02);
-
/* enable master interrupt */
MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN),
~(UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK),
@@ -859,40 +844,31 @@ static int uvd_v7_0_sriov_start(struct amdgpu_device *adev)
/* force RBC into idle state */
size = order_base_2(ring->ring_size);
tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, size);
- tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
- tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_WPTR_POLL_EN, 0);
- tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
- tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_CNTL), tmp);
- /* set the write pointer delay */
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_WPTR_CNTL), 0);
-
- /* set the wb address */
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_RPTR_ADDR),
- (upper_32_bits(ring->gpu_addr) >> 2));
-
- /* programm the RB_BASE for ring buffer */
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW),
- lower_32_bits(ring->gpu_addr));
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH),
- upper_32_bits(ring->gpu_addr));
-
- ring->wptr = 0;
ring = &adev->uvd.ring_enc[0];
+ ring->wptr = 0;
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_BASE_LO), ring->gpu_addr);
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_BASE_HI), upper_32_bits(ring->gpu_addr));
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_SIZE), ring->ring_size / 4);
+ /* boot up the VCPU */
+ MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), 0);
+
+ /* enable UMC */
+ MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2),
+ ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, 0);
+
+ MMSCH_V1_0_INSERT_DIRECT_POLL(SOC15_REG_OFFSET(UVD, 0, mmUVD_STATUS), 0x02, 0x02);
+
/* add end packet */
memcpy((void *)init_table, &end, sizeof(struct mmsch_v1_0_cmd_end));
table_size += sizeof(struct mmsch_v1_0_cmd_end) / 4;
header->uvd_table_size = table_size;
- return uvd_v7_0_mmsch_start(adev, &adev->virt.mm_table);
}
- return -EINVAL; /* already initializaed ? */
+ return uvd_v7_0_mmsch_start(adev, &adev->virt.mm_table);
}
/**
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c
index 1ecd6bb..11134d5 100644
--- a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c
@@ -173,6 +173,11 @@ static int vce_v4_0_mmsch_start(struct amdgpu_device *adev,
/* 4, set resp to zero */
WREG32(SOC15_REG_OFFSET(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_RESP), 0);
+ WDOORBELL32(adev->vce.ring[0].doorbell_index, 0);
+ adev->wb.wb[adev->vce.ring[0].wptr_offs] = 0;
+ adev->vce.ring[0].wptr = 0;
+ adev->vce.ring[0].wptr_old = 0;
+
/* 5, kick off the initialization and wait until VCE_MMSCH_VF_MAILBOX_RESP becomes non-zero */
WREG32(SOC15_REG_OFFSET(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_HOST), 0x10000001);
@@ -190,7 +195,6 @@ static int vce_v4_0_mmsch_start(struct amdgpu_device *adev,
dev_err(adev->dev, "failed to init MMSCH, mmVCE_MMSCH_VF_MAILBOX_RESP = %x\n", data);
return -EBUSY;
}
- WDOORBELL32(adev->vce.ring[0].doorbell_index, 0);
return 0;
}
@@ -274,7 +278,8 @@ static int vce_v4_0_sriov_start(struct amdgpu_device *adev)
MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_LMI_CTRL2), ~0x100, 0);
MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_SYS_INT_EN),
- 0xffffffff, VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK);
+ VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK,
+ VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK);
/* end of MC_RESUME */
MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_STATUS),
@@ -296,11 +301,9 @@ static int vce_v4_0_sriov_start(struct amdgpu_device *adev)
memcpy((void *)init_table, &end, sizeof(struct mmsch_v1_0_cmd_end));
table_size += sizeof(struct mmsch_v1_0_cmd_end) / 4;
header->vce_table_size = table_size;
-
- return vce_v4_0_mmsch_start(adev, &adev->virt.mm_table);
}
- return -EINVAL; /* already initializaed ? */
+ return vce_v4_0_mmsch_start(adev, &adev->virt.mm_table);
}
/**
@@ -443,12 +446,14 @@ static int vce_v4_0_sw_init(void *handle)
if (amdgpu_sriov_vf(adev)) {
/* DOORBELL only works under SRIOV */
ring->use_doorbell = true;
+
+ /* currently only use the first encoding ring for sriov,
+ * so set unused location for other unused rings.
+ */
if (i == 0)
- ring->doorbell_index = AMDGPU_DOORBELL64_RING0_1 * 2;
- else if (i == 1)
- ring->doorbell_index = AMDGPU_DOORBELL64_RING2_3 * 2;
+ ring->doorbell_index = AMDGPU_DOORBELL64_VCE_RING0_1 * 2;
else
- ring->doorbell_index = AMDGPU_DOORBELL64_RING2_3 * 2 + 1;
+ ring->doorbell_index = AMDGPU_DOORBELL64_VCE_RING2_3 * 2 + 1;
}
r = amdgpu_ring_init(adev, ring, 512, &adev->vce.irq, 0);
if (r)
@@ -990,11 +995,13 @@ static int vce_v4_0_set_interrupt_state(struct amdgpu_device *adev,
{
uint32_t val = 0;
- if (state == AMDGPU_IRQ_STATE_ENABLE)
- val |= VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK;
+ if (!amdgpu_sriov_vf(adev)) {
+ if (state == AMDGPU_IRQ_STATE_ENABLE)
+ val |= VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK;
- WREG32_P(SOC15_REG_OFFSET(VCE, 0, mmVCE_SYS_INT_EN), val,
- ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK);
+ WREG32_P(SOC15_REG_OFFSET(VCE, 0, mmVCE_SYS_INT_EN), val,
+ ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK);
+ }
return 0;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
index 6cac291..9ff69b9 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -1028,8 +1028,7 @@ static int vi_common_early_init(void *handle)
/* rev0 hardware requires workarounds to support PG */
adev->pg_flags = 0;
if (adev->rev_id != 0x00 || CZ_REV_BRISTOL(adev->pdev->revision)) {
- adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG |
- AMD_PG_SUPPORT_GFX_SMG |
+ adev->pg_flags |= AMD_PG_SUPPORT_GFX_SMG |
AMD_PG_SUPPORT_GFX_PIPELINE |
AMD_PG_SUPPORT_CP |
AMD_PG_SUPPORT_UVD |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index 6316aad..e4a8c2e 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -142,12 +142,12 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties,
struct kfd_ioctl_create_queue_args *args)
{
if (args->queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) {
- pr_err("kfd: queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n");
+ pr_err("Queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n");
return -EINVAL;
}
if (args->queue_priority > KFD_MAX_QUEUE_PRIORITY) {
- pr_err("kfd: queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n");
+ pr_err("Queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n");
return -EINVAL;
}
@@ -155,26 +155,26 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties,
(!access_ok(VERIFY_WRITE,
(const void __user *) args->ring_base_address,
sizeof(uint64_t)))) {
- pr_err("kfd: can't access ring base address\n");
+ pr_err("Can't access ring base address\n");
return -EFAULT;
}
if (!is_power_of_2(args->ring_size) && (args->ring_size != 0)) {
- pr_err("kfd: ring size must be a power of 2 or 0\n");
+ pr_err("Ring size must be a power of 2 or 0\n");
return -EINVAL;
}
if (!access_ok(VERIFY_WRITE,
(const void __user *) args->read_pointer_address,
sizeof(uint32_t))) {
- pr_err("kfd: can't access read pointer\n");
+ pr_err("Can't access read pointer\n");
return -EFAULT;
}
if (!access_ok(VERIFY_WRITE,
(const void __user *) args->write_pointer_address,
sizeof(uint32_t))) {
- pr_err("kfd: can't access write pointer\n");
+ pr_err("Can't access write pointer\n");
return -EFAULT;
}
@@ -182,7 +182,7 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties,
!access_ok(VERIFY_WRITE,
(const void __user *) args->eop_buffer_address,
sizeof(uint32_t))) {
- pr_debug("kfd: can't access eop buffer");
+ pr_debug("Can't access eop buffer");
return -EFAULT;
}
@@ -190,7 +190,7 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties,
!access_ok(VERIFY_WRITE,
(const void __user *) args->ctx_save_restore_address,
sizeof(uint32_t))) {
- pr_debug("kfd: can't access ctx save restore buffer");
+ pr_debug("Can't access ctx save restore buffer");
return -EFAULT;
}
@@ -219,27 +219,27 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties,
else
q_properties->format = KFD_QUEUE_FORMAT_PM4;
- pr_debug("Queue Percentage (%d, %d)\n",
+ pr_debug("Queue Percentage: %d, %d\n",
q_properties->queue_percent, args->queue_percentage);
- pr_debug("Queue Priority (%d, %d)\n",
+ pr_debug("Queue Priority: %d, %d\n",
q_properties->priority, args->queue_priority);
- pr_debug("Queue Address (0x%llX, 0x%llX)\n",
+ pr_debug("Queue Address: 0x%llX, 0x%llX\n",
q_properties->queue_address, args->ring_base_address);
- pr_debug("Queue Size (0x%llX, %u)\n",
+ pr_debug("Queue Size: 0x%llX, %u\n",
q_properties->queue_size, args->ring_size);
- pr_debug("Queue r/w Pointers (0x%llX, 0x%llX)\n",
- (uint64_t) q_properties->read_ptr,
- (uint64_t) q_properties->write_ptr);
+ pr_debug("Queue r/w Pointers: %p, %p\n",
+ q_properties->read_ptr,
+ q_properties->write_ptr);
- pr_debug("Queue Format (%d)\n", q_properties->format);
+ pr_debug("Queue Format: %d\n", q_properties->format);
- pr_debug("Queue EOP (0x%llX)\n", q_properties->eop_ring_buffer_address);
+ pr_debug("Queue EOP: 0x%llX\n", q_properties->eop_ring_buffer_address);
- pr_debug("Queue CTX save arex (0x%llX)\n",
+ pr_debug("Queue CTX save area: 0x%llX\n",
q_properties->ctx_save_restore_area_address);
return 0;
@@ -257,16 +257,16 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
memset(&q_properties, 0, sizeof(struct queue_properties));
- pr_debug("kfd: creating queue ioctl\n");
+ pr_debug("Creating queue ioctl\n");
err = set_queue_properties_from_user(&q_properties, args);
if (err)
return err;
- pr_debug("kfd: looking for gpu id 0x%x\n", args->gpu_id);
+ pr_debug("Looking for gpu id 0x%x\n", args->gpu_id);
dev = kfd_device_by_id(args->gpu_id);
- if (dev == NULL) {
- pr_debug("kfd: gpu id 0x%x was not found\n", args->gpu_id);
+ if (!dev) {
+ pr_debug("Could not find gpu id 0x%x\n", args->gpu_id);
return -EINVAL;
}
@@ -278,7 +278,7 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
goto err_bind_process;
}
- pr_debug("kfd: creating queue for PASID %d on GPU 0x%x\n",
+ pr_debug("Creating queue for PASID %d on gpu 0x%x\n",
p->pasid,
dev->id);
@@ -296,15 +296,15 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
mutex_unlock(&p->mutex);
- pr_debug("kfd: queue id %d was created successfully\n", args->queue_id);
+ pr_debug("Queue id %d was created successfully\n", args->queue_id);
- pr_debug("ring buffer address == 0x%016llX\n",
+ pr_debug("Ring buffer address == 0x%016llX\n",
args->ring_base_address);
- pr_debug("read ptr address == 0x%016llX\n",
+ pr_debug("Read ptr address == 0x%016llX\n",
args->read_pointer_address);
- pr_debug("write ptr address == 0x%016llX\n",
+ pr_debug("Write ptr address == 0x%016llX\n",
args->write_pointer_address);
return 0;
@@ -321,7 +321,7 @@ static int kfd_ioctl_destroy_queue(struct file *filp, struct kfd_process *p,
int retval;
struct kfd_ioctl_destroy_queue_args *args = data;
- pr_debug("kfd: destroying queue id %d for PASID %d\n",
+ pr_debug("Destroying queue id %d for pasid %d\n",
args->queue_id,
p->pasid);
@@ -341,12 +341,12 @@ static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p,
struct queue_properties properties;
if (args->queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) {
- pr_err("kfd: queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n");
+ pr_err("Queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n");
return -EINVAL;
}
if (args->queue_priority > KFD_MAX_QUEUE_PRIORITY) {
- pr_err("kfd: queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n");
+ pr_err("Queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n");
return -EINVAL;
}
@@ -354,12 +354,12 @@ static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p,
(!access_ok(VERIFY_WRITE,
(const void __user *) args->ring_base_address,
sizeof(uint64_t)))) {
- pr_err("kfd: can't access ring base address\n");
+ pr_err("Can't access ring base address\n");
return -EFAULT;
}
if (!is_power_of_2(args->ring_size) && (args->ring_size != 0)) {
- pr_err("kfd: ring size must be a power of 2 or 0\n");
+ pr_err("Ring size must be a power of 2 or 0\n");
return -EINVAL;
}
@@ -368,7 +368,7 @@ static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p,
properties.queue_percent = args->queue_percentage;
properties.priority = args->queue_priority;
- pr_debug("kfd: updating queue id %d for PASID %d\n",
+ pr_debug("Updating queue id %d for pasid %d\n",
args->queue_id, p->pasid);
mutex_lock(&p->mutex);
@@ -400,7 +400,7 @@ static int kfd_ioctl_set_memory_policy(struct file *filep,
}
dev = kfd_device_by_id(args->gpu_id);
- if (dev == NULL)
+ if (!dev)
return -EINVAL;
mutex_lock(&p->mutex);
@@ -443,7 +443,7 @@ static int kfd_ioctl_dbg_register(struct file *filep,
long status = 0;
dev = kfd_device_by_id(args->gpu_id);
- if (dev == NULL)
+ if (!dev)
return -EINVAL;
if (dev->device_info->asic_family == CHIP_CARRIZO) {
@@ -460,12 +460,11 @@ static int kfd_ioctl_dbg_register(struct file *filep,
*/
pdd = kfd_bind_process_to_device(dev, p);
if (IS_ERR(pdd)) {
- mutex_unlock(&p->mutex);
- mutex_unlock(kfd_get_dbgmgr_mutex());
- return PTR_ERR(pdd);
+ status = PTR_ERR(pdd);
+ goto out;
}
- if (dev->dbgmgr == NULL) {
+ if (!dev->dbgmgr) {
/* In case of a legal call, we have no dbgmgr yet */
create_ok = kfd_dbgmgr_create(&dbgmgr_ptr, dev);
if (create_ok) {
@@ -480,6 +479,7 @@ static int kfd_ioctl_dbg_register(struct file *filep,
status = -EINVAL;
}
+out:
mutex_unlock(&p->mutex);
mutex_unlock(kfd_get_dbgmgr_mutex());
@@ -494,7 +494,7 @@ static int kfd_ioctl_dbg_unregister(struct file *filep,
long status;
dev = kfd_device_by_id(args->gpu_id);
- if (dev == NULL)
+ if (!dev)
return -EINVAL;
if (dev->device_info->asic_family == CHIP_CARRIZO) {
@@ -505,7 +505,7 @@ static int kfd_ioctl_dbg_unregister(struct file *filep,
mutex_lock(kfd_get_dbgmgr_mutex());
status = kfd_dbgmgr_unregister(dev->dbgmgr, p);
- if (status == 0) {
+ if (!status) {
kfd_dbgmgr_destroy(dev->dbgmgr);
dev->dbgmgr = NULL;
}
@@ -539,7 +539,7 @@ static int kfd_ioctl_dbg_address_watch(struct file *filep,
memset((void *) &aw_info, 0, sizeof(struct dbg_address_watch_info));
dev = kfd_device_by_id(args->gpu_id);
- if (dev == NULL)
+ if (!dev)
return -EINVAL;
if (dev->device_info->asic_family == CHIP_CARRIZO) {
@@ -580,8 +580,8 @@ static int kfd_ioctl_dbg_address_watch(struct file *filep,
args_idx += sizeof(aw_info.watch_address) * aw_info.num_watch_points;
if (args_idx >= args->buf_size_in_bytes - sizeof(*args)) {
- kfree(args_buff);
- return -EINVAL;
+ status = -EINVAL;
+ goto out;
}
watch_mask_value = (uint64_t) args_buff[args_idx];
@@ -604,8 +604,8 @@ static int kfd_ioctl_dbg_address_watch(struct file *filep,
}
if (args_idx >= args->buf_size_in_bytes - sizeof(args)) {
- kfree(args_buff);
- return -EINVAL;
+ status = -EINVAL;
+ goto out;
}
/* Currently HSA Event is not supported for DBG */
@@ -617,6 +617,7 @@ static int kfd_ioctl_dbg_address_watch(struct file *filep,
mutex_unlock(kfd_get_dbgmgr_mutex());
+out:
kfree(args_buff);
return status;
@@ -646,7 +647,7 @@ static int kfd_ioctl_dbg_wave_control(struct file *filep,
sizeof(wac_info.trapId);
dev = kfd_device_by_id(args->gpu_id);
- if (dev == NULL)
+ if (!dev)
return -EINVAL;
if (dev->device_info->asic_family == CHIP_CARRIZO) {
@@ -782,8 +783,9 @@ static int kfd_ioctl_get_process_apertures(struct file *filp,
"scratch_limit %llX\n", pdd->scratch_limit);
args->num_of_nodes++;
- } while ((pdd = kfd_get_next_process_device_data(p, pdd)) != NULL &&
- (args->num_of_nodes < NUM_OF_SUPPORTED_GPUS));
+
+ pdd = kfd_get_next_process_device_data(p, pdd);
+ } while (pdd && (args->num_of_nodes < NUM_OF_SUPPORTED_GPUS));
}
mutex_unlock(&p->mutex);
@@ -846,9 +848,84 @@ static int kfd_ioctl_wait_events(struct file *filp, struct kfd_process *p,
return err;
}
+static int kfd_ioctl_set_scratch_backing_va(struct file *filep,
+ struct kfd_process *p, void *data)
+{
+ struct kfd_ioctl_set_scratch_backing_va_args *args = data;
+ struct kfd_process_device *pdd;
+ struct kfd_dev *dev;
+ long err;
+
+ dev = kfd_device_by_id(args->gpu_id);
+ if (!dev)
+ return -EINVAL;
+
+ mutex_lock(&p->mutex);
+
+ pdd = kfd_bind_process_to_device(dev, p);
+ if (IS_ERR(pdd)) {
+ err = PTR_ERR(pdd);
+ goto bind_process_to_device_fail;
+ }
+
+ pdd->qpd.sh_hidden_private_base = args->va_addr;
+
+ mutex_unlock(&p->mutex);
+
+ if (sched_policy == KFD_SCHED_POLICY_NO_HWS && pdd->qpd.vmid != 0)
+ dev->kfd2kgd->set_scratch_backing_va(
+ dev->kgd, args->va_addr, pdd->qpd.vmid);
+
+ return 0;
+
+bind_process_to_device_fail:
+ mutex_unlock(&p->mutex);
+ return err;
+}
+
+static int kfd_ioctl_get_tile_config(struct file *filep,
+ struct kfd_process *p, void *data)
+{
+ struct kfd_ioctl_get_tile_config_args *args = data;
+ struct kfd_dev *dev;
+ struct tile_config config;
+ int err = 0;
+
+ dev = kfd_device_by_id(args->gpu_id);
+
+ dev->kfd2kgd->get_tile_config(dev->kgd, &config);
+
+ args->gb_addr_config = config.gb_addr_config;
+ args->num_banks = config.num_banks;
+ args->num_ranks = config.num_ranks;
+
+ if (args->num_tile_configs > config.num_tile_configs)
+ args->num_tile_configs = config.num_tile_configs;
+ err = copy_to_user((void __user *)args->tile_config_ptr,
+ config.tile_config_ptr,
+ args->num_tile_configs * sizeof(uint32_t));
+ if (err) {
+ args->num_tile_configs = 0;
+ return -EFAULT;
+ }
+
+ if (args->num_macro_tile_configs > config.num_macro_tile_configs)
+ args->num_macro_tile_configs =
+ config.num_macro_tile_configs;
+ err = copy_to_user((void __user *)args->macro_tile_config_ptr,
+ config.macro_tile_config_ptr,
+ args->num_macro_tile_configs * sizeof(uint32_t));
+ if (err) {
+ args->num_macro_tile_configs = 0;
+ return -EFAULT;
+ }
+
+ return 0;
+}
#define AMDKFD_IOCTL_DEF(ioctl, _func, _flags) \
- [_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0, .name = #ioctl}
+ [_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, \
+ .cmd_drv = 0, .name = #ioctl}
/** Ioctl table */
static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {
@@ -899,6 +976,12 @@ static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {
AMDKFD_IOCTL_DEF(AMDKFD_IOC_DBG_WAVE_CONTROL,
kfd_ioctl_dbg_wave_control, 0),
+
+ AMDKFD_IOCTL_DEF(AMDKFD_IOC_SET_SCRATCH_BACKING_VA,
+ kfd_ioctl_set_scratch_backing_va, 0),
+
+ AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_TILE_CONFIG,
+ kfd_ioctl_get_tile_config, 0)
};
#define AMDKFD_CORE_IOCTL_COUNT ARRAY_SIZE(amdkfd_ioctls)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c b/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c
index d5e19b5..0aa021a 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c
@@ -42,8 +42,6 @@
static void dbgdev_address_watch_disable_nodiq(struct kfd_dev *dev)
{
- BUG_ON(!dev || !dev->kfd2kgd);
-
dev->kfd2kgd->address_watch_disable(dev->kgd);
}
@@ -62,7 +60,8 @@ static int dbgdev_diq_submit_ib(struct kfd_dbgdev *dbgdev,
unsigned int *ib_packet_buff;
int status;
- BUG_ON(!dbgdev || !dbgdev->kq || !packet_buff || !size_in_bytes);
+ if (WARN_ON(!size_in_bytes))
+ return -EINVAL;
kq = dbgdev->kq;
@@ -77,8 +76,8 @@ static int dbgdev_diq_submit_ib(struct kfd_dbgdev *dbgdev,
status = kq->ops.acquire_packet_buffer(kq,
pq_packets_size_in_bytes / sizeof(uint32_t),
&ib_packet_buff);
- if (status != 0) {
- pr_err("amdkfd: acquire_packet_buffer failed\n");
+ if (status) {
+ pr_err("acquire_packet_buffer failed\n");
return status;
}
@@ -115,8 +114,8 @@ static int dbgdev_diq_submit_ib(struct kfd_dbgdev *dbgdev,
status = kfd_gtt_sa_allocate(dbgdev->dev, sizeof(uint64_t),
&mem_obj);
- if (status != 0) {
- pr_err("amdkfd: Failed to allocate GART memory\n");
+ if (status) {
+ pr_err("Failed to allocate GART memory\n");
kq->ops.rollback_packet(kq);
return status;
}
@@ -168,8 +167,6 @@ static int dbgdev_diq_submit_ib(struct kfd_dbgdev *dbgdev,
static int dbgdev_register_nodiq(struct kfd_dbgdev *dbgdev)
{
- BUG_ON(!dbgdev);
-
/*
* no action is needed in this case,
* just make sure diq will not be used
@@ -187,14 +184,12 @@ static int dbgdev_register_diq(struct kfd_dbgdev *dbgdev)
struct kernel_queue *kq = NULL;
int status;
- BUG_ON(!dbgdev || !dbgdev->pqm || !dbgdev->dev);
-
status = pqm_create_queue(dbgdev->pqm, dbgdev->dev, NULL,
&properties, 0, KFD_QUEUE_TYPE_DIQ,
&qid);
if (status) {
- pr_err("amdkfd: Failed to create DIQ\n");
+ pr_err("Failed to create DIQ\n");
return status;
}
@@ -202,8 +197,8 @@ static int dbgdev_register_diq(struct kfd_dbgdev *dbgdev)
kq = pqm_get_kernel_queue(dbgdev->pqm, qid);
- if (kq == NULL) {
- pr_err("amdkfd: Error getting DIQ\n");
+ if (!kq) {
+ pr_err("Error getting DIQ\n");
pqm_destroy_queue(dbgdev->pqm, qid);
return -EFAULT;
}
@@ -215,8 +210,6 @@ static int dbgdev_register_diq(struct kfd_dbgdev *dbgdev)
static int dbgdev_unregister_nodiq(struct kfd_dbgdev *dbgdev)
{
- BUG_ON(!dbgdev || !dbgdev->dev);
-
/* disable watch address */
dbgdev_address_watch_disable_nodiq(dbgdev->dev);
return 0;
@@ -227,8 +220,6 @@ static int dbgdev_unregister_diq(struct kfd_dbgdev *dbgdev)
/* todo - disable address watch */
int status;
- BUG_ON(!dbgdev || !dbgdev->pqm || !dbgdev->kq);
-
status = pqm_destroy_queue(dbgdev->pqm,
dbgdev->kq->queue->properties.queue_id);
dbgdev->kq = NULL;
@@ -245,14 +236,12 @@ static void dbgdev_address_watch_set_registers(
{
union ULARGE_INTEGER addr;
- BUG_ON(!adw_info || !addrHi || !addrLo || !cntl);
-
addr.quad_part = 0;
addrHi->u32All = 0;
addrLo->u32All = 0;
cntl->u32All = 0;
- if (adw_info->watch_mask != NULL)
+ if (adw_info->watch_mask)
cntl->bitfields.mask =
(uint32_t) (adw_info->watch_mask[index] &
ADDRESS_WATCH_REG_CNTL_DEFAULT_MASK);
@@ -279,7 +268,7 @@ static void dbgdev_address_watch_set_registers(
}
static int dbgdev_address_watch_nodiq(struct kfd_dbgdev *dbgdev,
- struct dbg_address_watch_info *adw_info)
+ struct dbg_address_watch_info *adw_info)
{
union TCP_WATCH_ADDR_H_BITS addrHi;
union TCP_WATCH_ADDR_L_BITS addrLo;
@@ -287,13 +276,11 @@ static int dbgdev_address_watch_nodiq(struct kfd_dbgdev *dbgdev,
struct kfd_process_device *pdd;
unsigned int i;
- BUG_ON(!dbgdev || !dbgdev->dev || !adw_info);
-
/* taking the vmid for that process on the safe way using pdd */
pdd = kfd_get_process_device_data(dbgdev->dev,
adw_info->process);
if (!pdd) {
- pr_err("amdkfd: Failed to get pdd for wave control no DIQ\n");
+ pr_err("Failed to get pdd for wave control no DIQ\n");
return -EFAULT;
}
@@ -303,17 +290,16 @@ static int dbgdev_address_watch_nodiq(struct kfd_dbgdev *dbgdev,
if ((adw_info->num_watch_points > MAX_WATCH_ADDRESSES) ||
(adw_info->num_watch_points == 0)) {
- pr_err("amdkfd: num_watch_points is invalid\n");
+ pr_err("num_watch_points is invalid\n");
return -EINVAL;
}
- if ((adw_info->watch_mode == NULL) ||
- (adw_info->watch_address == NULL)) {
- pr_err("amdkfd: adw_info fields are not valid\n");
+ if (!adw_info->watch_mode || !adw_info->watch_address) {
+ pr_err("adw_info fields are not valid\n");
return -EINVAL;
}
- for (i = 0 ; i < adw_info->num_watch_points ; i++) {
+ for (i = 0; i < adw_info->num_watch_points; i++) {
dbgdev_address_watch_set_registers(adw_info, &addrHi, &addrLo,
&cntl, i, pdd->qpd.vmid);
@@ -348,7 +334,7 @@ static int dbgdev_address_watch_nodiq(struct kfd_dbgdev *dbgdev,
}
static int dbgdev_address_watch_diq(struct kfd_dbgdev *dbgdev,
- struct dbg_address_watch_info *adw_info)
+ struct dbg_address_watch_info *adw_info)
{
struct pm4__set_config_reg *packets_vec;
union TCP_WATCH_ADDR_H_BITS addrHi;
@@ -363,28 +349,25 @@ static int dbgdev_address_watch_diq(struct kfd_dbgdev *dbgdev,
/* we do not control the vmid in DIQ mode, just a place holder */
unsigned int vmid = 0;
- BUG_ON(!dbgdev || !dbgdev->dev || !adw_info);
-
addrHi.u32All = 0;
addrLo.u32All = 0;
cntl.u32All = 0;
if ((adw_info->num_watch_points > MAX_WATCH_ADDRESSES) ||
(adw_info->num_watch_points == 0)) {
- pr_err("amdkfd: num_watch_points is invalid\n");
+ pr_err("num_watch_points is invalid\n");
return -EINVAL;
}
- if ((NULL == adw_info->watch_mode) ||
- (NULL == adw_info->watch_address)) {
- pr_err("amdkfd: adw_info fields are not valid\n");
+ if (!adw_info->watch_mode || !adw_info->watch_address) {
+ pr_err("adw_info fields are not valid\n");
return -EINVAL;
}
status = kfd_gtt_sa_allocate(dbgdev->dev, ib_size, &mem_obj);
- if (status != 0) {
- pr_err("amdkfd: Failed to allocate GART memory\n");
+ if (status) {
+ pr_err("Failed to allocate GART memory\n");
return status;
}
@@ -442,8 +425,6 @@ static int dbgdev_address_watch_diq(struct kfd_dbgdev *dbgdev,
i,
ADDRESS_WATCH_REG_CNTL);
- aw_reg_add_dword /= sizeof(uint32_t);
-
packets_vec[0].bitfields2.reg_offset =
aw_reg_add_dword - AMD_CONFIG_REG_BASE;
@@ -455,8 +436,6 @@ static int dbgdev_address_watch_diq(struct kfd_dbgdev *dbgdev,
i,
ADDRESS_WATCH_REG_ADDR_HI);
- aw_reg_add_dword /= sizeof(uint32_t);
-
packets_vec[1].bitfields2.reg_offset =
aw_reg_add_dword - AMD_CONFIG_REG_BASE;
packets_vec[1].reg_data[0] = addrHi.u32All;
@@ -467,8 +446,6 @@ static int dbgdev_address_watch_diq(struct kfd_dbgdev *dbgdev,
i,
ADDRESS_WATCH_REG_ADDR_LO);
- aw_reg_add_dword /= sizeof(uint32_t);
-
packets_vec[2].bitfields2.reg_offset =
aw_reg_add_dword - AMD_CONFIG_REG_BASE;
packets_vec[2].reg_data[0] = addrLo.u32All;
@@ -485,8 +462,6 @@ static int dbgdev_address_watch_diq(struct kfd_dbgdev *dbgdev,
i,
ADDRESS_WATCH_REG_CNTL);
- aw_reg_add_dword /= sizeof(uint32_t);
-
packets_vec[3].bitfields2.reg_offset =
aw_reg_add_dword - AMD_CONFIG_REG_BASE;
packets_vec[3].reg_data[0] = cntl.u32All;
@@ -498,8 +473,8 @@ static int dbgdev_address_watch_diq(struct kfd_dbgdev *dbgdev,
packet_buff_uint,
ib_size);
- if (status != 0) {
- pr_err("amdkfd: Failed to submit IB to DIQ\n");
+ if (status) {
+ pr_err("Failed to submit IB to DIQ\n");
break;
}
}
@@ -518,8 +493,6 @@ static int dbgdev_wave_control_set_registers(
union GRBM_GFX_INDEX_BITS reg_gfx_index;
struct HsaDbgWaveMsgAMDGen2 *pMsg;
- BUG_ON(!wac_info || !in_reg_sq_cmd || !in_reg_gfx_index);
-
reg_sq_cmd.u32All = 0;
reg_gfx_index.u32All = 0;
pMsg = &wac_info->dbgWave_msg.DbgWaveMsg.WaveMsgInfoGen2;
@@ -620,18 +593,16 @@ static int dbgdev_wave_control_diq(struct kfd_dbgdev *dbgdev,
struct pm4__set_config_reg *packets_vec;
size_t ib_size = sizeof(struct pm4__set_config_reg) * 3;
- BUG_ON(!dbgdev || !wac_info);
-
reg_sq_cmd.u32All = 0;
status = dbgdev_wave_control_set_registers(wac_info, &reg_sq_cmd,
&reg_gfx_index);
if (status) {
- pr_err("amdkfd: Failed to set wave control registers\n");
+ pr_err("Failed to set wave control registers\n");
return status;
}
- /* we do not control the VMID in DIQ,so reset it to a known value */
+ /* we do not control the VMID in DIQ, so reset it to a known value */
reg_sq_cmd.bits.vm_id = 0;
pr_debug("\t\t %30s\n", "* * * * * * * * * * * * * * * * * *");
@@ -667,7 +638,7 @@ static int dbgdev_wave_control_diq(struct kfd_dbgdev *dbgdev,
status = kfd_gtt_sa_allocate(dbgdev->dev, ib_size, &mem_obj);
if (status != 0) {
- pr_err("amdkfd: Failed to allocate GART memory\n");
+ pr_err("Failed to allocate GART memory\n");
return status;
}
@@ -719,8 +690,8 @@ static int dbgdev_wave_control_diq(struct kfd_dbgdev *dbgdev,
packet_buff_uint,
ib_size);
- if (status != 0)
- pr_err("amdkfd: Failed to submit IB to DIQ\n");
+ if (status)
+ pr_err("Failed to submit IB to DIQ\n");
kfd_gtt_sa_free(dbgdev->dev, mem_obj);
@@ -735,21 +706,19 @@ static int dbgdev_wave_control_nodiq(struct kfd_dbgdev *dbgdev,
union GRBM_GFX_INDEX_BITS reg_gfx_index;
struct kfd_process_device *pdd;
- BUG_ON(!dbgdev || !dbgdev->dev || !wac_info);
-
reg_sq_cmd.u32All = 0;
/* taking the VMID for that process on the safe way using PDD */
pdd = kfd_get_process_device_data(dbgdev->dev, wac_info->process);
if (!pdd) {
- pr_err("amdkfd: Failed to get pdd for wave control no DIQ\n");
+ pr_err("Failed to get pdd for wave control no DIQ\n");
return -EFAULT;
}
status = dbgdev_wave_control_set_registers(wac_info, &reg_sq_cmd,
&reg_gfx_index);
if (status) {
- pr_err("amdkfd: Failed to set wave control registers\n");
+ pr_err("Failed to set wave control registers\n");
return status;
}
@@ -818,12 +787,13 @@ int dbgdev_wave_reset_wavefronts(struct kfd_dev *dev, struct kfd_process *p)
/* Scan all registers in the range ATC_VMID8_PASID_MAPPING ..
* ATC_VMID15_PASID_MAPPING
- * to check which VMID the current process is mapped to. */
+ * to check which VMID the current process is mapped to.
+ */
for (vmid = first_vmid_to_scan; vmid <= last_vmid_to_scan; vmid++) {
if (dev->kfd2kgd->get_atc_vmid_pasid_mapping_valid
(dev->kgd, vmid)) {
- if (dev->kfd2kgd->get_atc_vmid_pasid_mapping_valid
+ if (dev->kfd2kgd->get_atc_vmid_pasid_mapping_pasid
(dev->kgd, vmid) == p->pasid) {
pr_debug("Killing wave fronts of vmid %d and pasid %d\n",
vmid, p->pasid);
@@ -833,7 +803,7 @@ int dbgdev_wave_reset_wavefronts(struct kfd_dev *dev, struct kfd_process *p)
}
if (vmid > last_vmid_to_scan) {
- pr_err("amdkfd: didn't found vmid for pasid (%d)\n", p->pasid);
+ pr_err("Didn't find vmid for pasid %d\n", p->pasid);
return -EFAULT;
}
@@ -860,8 +830,6 @@ int dbgdev_wave_reset_wavefronts(struct kfd_dev *dev, struct kfd_process *p)
void kfd_dbgdev_init(struct kfd_dbgdev *pdbgdev, struct kfd_dev *pdev,
enum DBGDEV_TYPE type)
{
- BUG_ON(!pdbgdev || !pdev);
-
pdbgdev->dev = pdev;
pdbgdev->kq = NULL;
pdbgdev->type = type;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.c b/drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.c
index 56d6763..3da25f7 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.c
@@ -44,8 +44,6 @@ struct mutex *kfd_get_dbgmgr_mutex(void)
static void kfd_dbgmgr_uninitialize(struct kfd_dbgmgr *pmgr)
{
- BUG_ON(!pmgr);
-
kfree(pmgr->dbgdev);
pmgr->dbgdev = NULL;
@@ -55,7 +53,7 @@ static void kfd_dbgmgr_uninitialize(struct kfd_dbgmgr *pmgr)
void kfd_dbgmgr_destroy(struct kfd_dbgmgr *pmgr)
{
- if (pmgr != NULL) {
+ if (pmgr) {
kfd_dbgmgr_uninitialize(pmgr);
kfree(pmgr);
}
@@ -66,12 +64,12 @@ bool kfd_dbgmgr_create(struct kfd_dbgmgr **ppmgr, struct kfd_dev *pdev)
enum DBGDEV_TYPE type = DBGDEV_TYPE_DIQ;
struct kfd_dbgmgr *new_buff;
- BUG_ON(pdev == NULL);
- BUG_ON(!pdev->init_complete);
+ if (WARN_ON(!pdev->init_complete))
+ return false;
new_buff = kfd_alloc_struct(new_buff);
if (!new_buff) {
- pr_err("amdkfd: Failed to allocate dbgmgr instance\n");
+ pr_err("Failed to allocate dbgmgr instance\n");
return false;
}
@@ -79,7 +77,7 @@ bool kfd_dbgmgr_create(struct kfd_dbgmgr **ppmgr, struct kfd_dev *pdev)
new_buff->dev = pdev;
new_buff->dbgdev = kfd_alloc_struct(new_buff->dbgdev);
if (!new_buff->dbgdev) {
- pr_err("amdkfd: Failed to allocate dbgdev instance\n");
+ pr_err("Failed to allocate dbgdev instance\n");
kfree(new_buff);
return false;
}
@@ -96,8 +94,6 @@ bool kfd_dbgmgr_create(struct kfd_dbgmgr **ppmgr, struct kfd_dev *pdev)
long kfd_dbgmgr_register(struct kfd_dbgmgr *pmgr, struct kfd_process *p)
{
- BUG_ON(!p || !pmgr || !pmgr->dbgdev);
-
if (pmgr->pasid != 0) {
pr_debug("H/W debugger is already active using pasid %d\n",
pmgr->pasid);
@@ -118,8 +114,6 @@ long kfd_dbgmgr_register(struct kfd_dbgmgr *pmgr, struct kfd_process *p)
long kfd_dbgmgr_unregister(struct kfd_dbgmgr *pmgr, struct kfd_process *p)
{
- BUG_ON(!p || !pmgr || !pmgr->dbgdev);
-
/* Is the requests coming from the already registered process? */
if (pmgr->pasid != p->pasid) {
pr_debug("H/W debugger is not registered by calling pasid %d\n",
@@ -137,8 +131,6 @@ long kfd_dbgmgr_unregister(struct kfd_dbgmgr *pmgr, struct kfd_process *p)
long kfd_dbgmgr_wave_control(struct kfd_dbgmgr *pmgr,
struct dbg_wave_control_info *wac_info)
{
- BUG_ON(!pmgr || !pmgr->dbgdev || !wac_info);
-
/* Is the requests coming from the already registered process? */
if (pmgr->pasid != wac_info->process->pasid) {
pr_debug("H/W debugger support was not registered for requester pasid %d\n",
@@ -152,9 +144,6 @@ long kfd_dbgmgr_wave_control(struct kfd_dbgmgr *pmgr,
long kfd_dbgmgr_address_watch(struct kfd_dbgmgr *pmgr,
struct dbg_address_watch_info *adw_info)
{
- BUG_ON(!pmgr || !pmgr->dbgdev || !adw_info);
-
-
/* Is the requests coming from the already registered process? */
if (pmgr->pasid != adw_info->process->pasid) {
pr_debug("H/W debugger support was not registered for requester pasid %d\n",
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.h b/drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.h
index 257a745..a04a1fe 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.h
@@ -30,13 +30,11 @@
#pragma pack(push, 4)
enum HSA_DBG_WAVEOP {
- HSA_DBG_WAVEOP_HALT = 1, /* Halts a wavefront */
- HSA_DBG_WAVEOP_RESUME = 2, /* Resumes a wavefront */
- HSA_DBG_WAVEOP_KILL = 3, /* Kills a wavefront */
- HSA_DBG_WAVEOP_DEBUG = 4, /* Causes wavefront to enter
- debug mode */
- HSA_DBG_WAVEOP_TRAP = 5, /* Causes wavefront to take
- a trap */
+ HSA_DBG_WAVEOP_HALT = 1, /* Halts a wavefront */
+ HSA_DBG_WAVEOP_RESUME = 2, /* Resumes a wavefront */
+ HSA_DBG_WAVEOP_KILL = 3, /* Kills a wavefront */
+ HSA_DBG_WAVEOP_DEBUG = 4, /* Causes wavefront to enter dbg mode */
+ HSA_DBG_WAVEOP_TRAP = 5, /* Causes wavefront to take a trap */
HSA_DBG_NUM_WAVEOP = 5,
HSA_DBG_MAX_WAVEOP = 0xFFFFFFFF
};
@@ -81,15 +79,13 @@ struct HsaDbgWaveMsgAMDGen2 {
uint32_t UserData:8; /* user data */
uint32_t ShaderArray:1; /* Shader array */
uint32_t Priv:1; /* Privileged */
- uint32_t Reserved0:4; /* This field is reserved,
- should be 0 */
+ uint32_t Reserved0:4; /* Reserved, should be 0 */
uint32_t WaveId:4; /* wave id */
uint32_t SIMD:2; /* SIMD id */
uint32_t HSACU:4; /* Compute unit */
uint32_t ShaderEngine:2;/* Shader engine */
uint32_t MessageType:2; /* see HSA_DBG_WAVEMSG_TYPE */
- uint32_t Reserved1:4; /* This field is reserved,
- should be 0 */
+ uint32_t Reserved1:4; /* Reserved, should be 0 */
} ui32;
uint32_t Value;
};
@@ -121,20 +117,23 @@ struct HsaDbgWaveMessage {
* in the user mode instruction stream. The OS scheduler event is typically
* associated and signaled by an interrupt issued by the GPU, but other HSA
* system interrupt conditions from other HW (e.g. IOMMUv2) may be surfaced
- * by the KFD by this mechanism, too. */
+ * by the KFD by this mechanism, too.
+ */
/* these are the new definitions for events */
enum HSA_EVENTTYPE {
HSA_EVENTTYPE_SIGNAL = 0, /* user-mode generated GPU signal */
HSA_EVENTTYPE_NODECHANGE = 1, /* HSA node change (attach/detach) */
HSA_EVENTTYPE_DEVICESTATECHANGE = 2, /* HSA device state change
- (start/stop) */
+ * (start/stop)
+ */
HSA_EVENTTYPE_HW_EXCEPTION = 3, /* GPU shader exception event */
HSA_EVENTTYPE_SYSTEM_EVENT = 4, /* GPU SYSCALL with parameter info */
HSA_EVENTTYPE_DEBUG_EVENT = 5, /* GPU signal for debugging */
HSA_EVENTTYPE_PROFILE_EVENT = 6,/* GPU signal for profiling */
HSA_EVENTTYPE_QUEUE_EVENT = 7, /* GPU signal queue idle state
- (EOP pm4) */
+ * (EOP pm4)
+ */
/* ... */
HSA_EVENTTYPE_MAXID,
HSA_EVENTTYPE_TYPE_SIZE = 0xFFFFFFFF
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
index 3f95f7c..61fff25 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
@@ -26,7 +26,7 @@
#include <linux/slab.h>
#include "kfd_priv.h"
#include "kfd_device_queue_manager.h"
-#include "kfd_pm4_headers.h"
+#include "kfd_pm4_headers_vi.h"
#define MQD_SIZE_ALIGNED 768
@@ -98,11 +98,14 @@ static const struct kfd_device_info *lookup_device_info(unsigned short did)
for (i = 0; i < ARRAY_SIZE(supported_devices); i++) {
if (supported_devices[i].did == did) {
- BUG_ON(supported_devices[i].device_info == NULL);
+ WARN_ON(!supported_devices[i].device_info);
return supported_devices[i].device_info;
}
}
+ dev_warn(kfd_device, "DID %04x is missing in supported_devices\n",
+ did);
+
return NULL;
}
@@ -114,8 +117,10 @@ struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd,
const struct kfd_device_info *device_info =
lookup_device_info(pdev->device);
- if (!device_info)
+ if (!device_info) {
+ dev_err(kfd_device, "kgd2kfd_probe failed\n");
return NULL;
+ }
kfd = kzalloc(sizeof(*kfd), GFP_KERNEL);
if (!kfd)
@@ -152,15 +157,16 @@ static bool device_iommu_pasid_init(struct kfd_dev *kfd)
}
if ((iommu_info.flags & required_iommu_flags) != required_iommu_flags) {
- dev_err(kfd_device, "error required iommu flags ats(%i), pri(%i), pasid(%i)\n",
+ dev_err(kfd_device, "error required iommu flags ats %i, pri %i, pasid %i\n",
(iommu_info.flags & AMD_IOMMU_DEVICE_FLAG_ATS_SUP) != 0,
(iommu_info.flags & AMD_IOMMU_DEVICE_FLAG_PRI_SUP) != 0,
- (iommu_info.flags & AMD_IOMMU_DEVICE_FLAG_PASID_SUP) != 0);
+ (iommu_info.flags & AMD_IOMMU_DEVICE_FLAG_PASID_SUP)
+ != 0);
return false;
}
pasid_limit = min_t(unsigned int,
- (unsigned int)1 << kfd->device_info->max_pasid_bits,
+ (unsigned int)(1 << kfd->device_info->max_pasid_bits),
iommu_info.max_pasids);
/*
* last pasid is used for kernel queues doorbells
@@ -211,9 +217,8 @@ static int iommu_invalid_ppr_cb(struct pci_dev *pdev, int pasid,
flags);
dev = kfd_device_by_pci_dev(pdev);
- BUG_ON(dev == NULL);
-
- kfd_signal_iommu_event(dev, pasid, address,
+ if (!WARN_ON(!dev))
+ kfd_signal_iommu_event(dev, pasid, address,
flags & PPR_FAULT_WRITE, flags & PPR_FAULT_EXEC);
return AMD_IOMMU_INV_PRI_RSP_INVALID;
@@ -234,9 +239,9 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
* calculate max size of runlist packet.
* There can be only 2 packets at once
*/
- size += (KFD_MAX_NUM_OF_PROCESSES * sizeof(struct pm4_map_process) +
- max_num_of_queues_per_device *
- sizeof(struct pm4_map_queues) + sizeof(struct pm4_runlist)) * 2;
+ size += (KFD_MAX_NUM_OF_PROCESSES * sizeof(struct pm4_mes_map_process) +
+ max_num_of_queues_per_device * sizeof(struct pm4_mes_map_queues)
+ + sizeof(struct pm4_mes_runlist)) * 2;
/* Add size of HIQ & DIQ */
size += KFD_KERNEL_QUEUE_SIZE * 2;
@@ -247,42 +252,37 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
if (kfd->kfd2kgd->init_gtt_mem_allocation(
kfd->kgd, size, &kfd->gtt_mem,
&kfd->gtt_start_gpu_addr, &kfd->gtt_start_cpu_ptr)){
- dev_err(kfd_device,
- "Could not allocate %d bytes for device (%x:%x)\n",
- size, kfd->pdev->vendor, kfd->pdev->device);
+ dev_err(kfd_device, "Could not allocate %d bytes\n", size);
goto out;
}
- dev_info(kfd_device,
- "Allocated %d bytes on gart for device(%x:%x)\n",
- size, kfd->pdev->vendor, kfd->pdev->device);
+ dev_info(kfd_device, "Allocated %d bytes on gart\n", size);
/* Initialize GTT sa with 512 byte chunk size */
if (kfd_gtt_sa_init(kfd, size, 512) != 0) {
- dev_err(kfd_device,
- "Error initializing gtt sub-allocator\n");
+ dev_err(kfd_device, "Error initializing gtt sub-allocator\n");
goto kfd_gtt_sa_init_error;
}
- kfd_doorbell_init(kfd);
-
- if (kfd_topology_add_device(kfd) != 0) {
+ if (kfd_doorbell_init(kfd)) {
dev_err(kfd_device,
- "Error adding device (%x:%x) to topology\n",
- kfd->pdev->vendor, kfd->pdev->device);
+ "Error initializing doorbell aperture\n");
+ goto kfd_doorbell_error;
+ }
+
+ if (kfd_topology_add_device(kfd)) {
+ dev_err(kfd_device, "Error adding device to topology\n");
goto kfd_topology_add_device_error;
}
if (kfd_interrupt_init(kfd)) {
- dev_err(kfd_device,
- "Error initializing interrupts for device (%x:%x)\n",
- kfd->pdev->vendor, kfd->pdev->device);
+ dev_err(kfd_device, "Error initializing interrupts\n");
goto kfd_interrupt_error;
}
if (!device_iommu_pasid_init(kfd)) {
dev_err(kfd_device,
- "Error initializing iommuv2 for device (%x:%x)\n",
+ "Error initializing iommuv2 for device %x:%x\n",
kfd->pdev->vendor, kfd->pdev->device);
goto device_iommu_pasid_error;
}
@@ -292,15 +292,13 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
kfd->dqm = device_queue_manager_init(kfd);
if (!kfd->dqm) {
- dev_err(kfd_device,
- "Error initializing queue manager for device (%x:%x)\n",
- kfd->pdev->vendor, kfd->pdev->device);
+ dev_err(kfd_device, "Error initializing queue manager\n");
goto device_queue_manager_error;
}
- if (kfd->dqm->ops.start(kfd->dqm) != 0) {
+ if (kfd->dqm->ops.start(kfd->dqm)) {
dev_err(kfd_device,
- "Error starting queuen manager for device (%x:%x)\n",
+ "Error starting queue manager for device %x:%x\n",
kfd->pdev->vendor, kfd->pdev->device);
goto dqm_start_error;
}
@@ -308,10 +306,10 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
kfd->dbgmgr = NULL;
kfd->init_complete = true;
- dev_info(kfd_device, "added device (%x:%x)\n", kfd->pdev->vendor,
+ dev_info(kfd_device, "added device %x:%x\n", kfd->pdev->vendor,
kfd->pdev->device);
- pr_debug("kfd: Starting kfd with the following scheduling policy %d\n",
+ pr_debug("Starting kfd with the following scheduling policy %d\n",
sched_policy);
goto out;
@@ -325,11 +323,13 @@ device_iommu_pasid_error:
kfd_interrupt_error:
kfd_topology_remove_device(kfd);
kfd_topology_add_device_error:
+ kfd_doorbell_fini(kfd);
+kfd_doorbell_error:
kfd_gtt_sa_fini(kfd);
kfd_gtt_sa_init_error:
kfd->kfd2kgd->free_gtt_mem(kfd->kgd, kfd->gtt_mem);
dev_err(kfd_device,
- "device (%x:%x) NOT added due to errors\n",
+ "device %x:%x NOT added due to errors\n",
kfd->pdev->vendor, kfd->pdev->device);
out:
return kfd->init_complete;
@@ -342,6 +342,7 @@ void kgd2kfd_device_exit(struct kfd_dev *kfd)
amd_iommu_free_device(kfd->pdev);
kfd_interrupt_exit(kfd);
kfd_topology_remove_device(kfd);
+ kfd_doorbell_fini(kfd);
kfd_gtt_sa_fini(kfd);
kfd->kfd2kgd->free_gtt_mem(kfd->kgd, kfd->gtt_mem);
}
@@ -351,8 +352,6 @@ void kgd2kfd_device_exit(struct kfd_dev *kfd)
void kgd2kfd_suspend(struct kfd_dev *kfd)
{
- BUG_ON(kfd == NULL);
-
if (kfd->init_complete) {
kfd->dqm->ops.stop(kfd->dqm);
amd_iommu_set_invalidate_ctx_cb(kfd->pdev, NULL);
@@ -366,14 +365,15 @@ int kgd2kfd_resume(struct kfd_dev *kfd)
unsigned int pasid_limit;
int err;
- BUG_ON(kfd == NULL);
-
pasid_limit = kfd_get_pasid_limit();
if (kfd->init_complete) {
err = amd_iommu_init_device(kfd->pdev, pasid_limit);
- if (err < 0)
+ if (err < 0) {
+ dev_err(kfd_device, "failed to initialize iommu\n");
return -ENXIO;
+ }
+
amd_iommu_set_invalidate_ctx_cb(kfd->pdev,
iommu_pasid_shutdown_callback);
amd_iommu_set_invalid_ppr_cb(kfd->pdev, iommu_invalid_ppr_cb);
@@ -402,26 +402,27 @@ void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry)
static int kfd_gtt_sa_init(struct kfd_dev *kfd, unsigned int buf_size,
unsigned int chunk_size)
{
- unsigned int num_of_bits;
+ unsigned int num_of_longs;
- BUG_ON(!kfd);
- BUG_ON(!kfd->gtt_mem);
- BUG_ON(buf_size < chunk_size);
- BUG_ON(buf_size == 0);
- BUG_ON(chunk_size == 0);
+ if (WARN_ON(buf_size < chunk_size))
+ return -EINVAL;
+ if (WARN_ON(buf_size == 0))
+ return -EINVAL;
+ if (WARN_ON(chunk_size == 0))
+ return -EINVAL;
kfd->gtt_sa_chunk_size = chunk_size;
kfd->gtt_sa_num_of_chunks = buf_size / chunk_size;
- num_of_bits = kfd->gtt_sa_num_of_chunks / BITS_PER_BYTE;
- BUG_ON(num_of_bits == 0);
+ num_of_longs = (kfd->gtt_sa_num_of_chunks + BITS_PER_LONG - 1) /
+ BITS_PER_LONG;
- kfd->gtt_sa_bitmap = kzalloc(num_of_bits, GFP_KERNEL);
+ kfd->gtt_sa_bitmap = kcalloc(num_of_longs, sizeof(long), GFP_KERNEL);
if (!kfd->gtt_sa_bitmap)
return -ENOMEM;
- pr_debug("kfd: gtt_sa_num_of_chunks = %d, gtt_sa_bitmap = %p\n",
+ pr_debug("gtt_sa_num_of_chunks = %d, gtt_sa_bitmap = %p\n",
kfd->gtt_sa_num_of_chunks, kfd->gtt_sa_bitmap);
mutex_init(&kfd->gtt_sa_lock);
@@ -455,8 +456,6 @@ int kfd_gtt_sa_allocate(struct kfd_dev *kfd, unsigned int size,
{
unsigned int found, start_search, cur_size;
- BUG_ON(!kfd);
-
if (size == 0)
return -EINVAL;
@@ -467,7 +466,7 @@ int kfd_gtt_sa_allocate(struct kfd_dev *kfd, unsigned int size,
if ((*mem_obj) == NULL)
return -ENOMEM;
- pr_debug("kfd: allocated mem_obj = %p for size = %d\n", *mem_obj, size);
+ pr_debug("Allocated mem_obj = %p for size = %d\n", *mem_obj, size);
start_search = 0;
@@ -479,7 +478,7 @@ kfd_gtt_restart_search:
kfd->gtt_sa_num_of_chunks,
start_search);
- pr_debug("kfd: found = %d\n", found);
+ pr_debug("Found = %d\n", found);
/* If there wasn't any free chunk, bail out */
if (found == kfd->gtt_sa_num_of_chunks)
@@ -497,12 +496,12 @@ kfd_gtt_restart_search:
found,
kfd->gtt_sa_chunk_size);
- pr_debug("kfd: gpu_addr = %p, cpu_addr = %p\n",
+ pr_debug("gpu_addr = %p, cpu_addr = %p\n",
(uint64_t *) (*mem_obj)->gpu_addr, (*mem_obj)->cpu_ptr);
/* If we need only one chunk, mark it as allocated and get out */
if (size <= kfd->gtt_sa_chunk_size) {
- pr_debug("kfd: single bit\n");
+ pr_debug("Single bit\n");
set_bit(found, kfd->gtt_sa_bitmap);
goto kfd_gtt_out;
}
@@ -537,7 +536,7 @@ kfd_gtt_restart_search:
} while (cur_size > 0);
- pr_debug("kfd: range_start = %d, range_end = %d\n",
+ pr_debug("range_start = %d, range_end = %d\n",
(*mem_obj)->range_start, (*mem_obj)->range_end);
/* Mark the chunks as allocated */
@@ -551,7 +550,7 @@ kfd_gtt_out:
return 0;
kfd_gtt_no_free_chunk:
- pr_debug("kfd: allocation failed with mem_obj = %p\n", mem_obj);
+ pr_debug("Allocation failed with mem_obj = %p\n", mem_obj);
mutex_unlock(&kfd->gtt_sa_lock);
kfree(mem_obj);
return -ENOMEM;
@@ -561,13 +560,11 @@ int kfd_gtt_sa_free(struct kfd_dev *kfd, struct kfd_mem_obj *mem_obj)
{
unsigned int bit;
- BUG_ON(!kfd);
-
/* Act like kfree when trying to free a NULL object */
if (!mem_obj)
return 0;
- pr_debug("kfd: free mem_obj = %p, range_start = %d, range_end = %d\n",
+ pr_debug("Free mem_obj = %p, range_start = %d, range_end = %d\n",
mem_obj, mem_obj->range_start, mem_obj->range_end);
mutex_lock(&kfd->gtt_sa_lock);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index 602769c..53a66e8 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -79,20 +79,17 @@ static bool is_pipe_enabled(struct device_queue_manager *dqm, int mec, int pipe)
unsigned int get_queues_num(struct device_queue_manager *dqm)
{
- BUG_ON(!dqm || !dqm->dev);
return bitmap_weight(dqm->dev->shared_resources.queue_bitmap,
KGD_MAX_QUEUES);
}
unsigned int get_queues_per_pipe(struct device_queue_manager *dqm)
{
- BUG_ON(!dqm || !dqm->dev);
return dqm->dev->shared_resources.num_queue_per_pipe;
}
unsigned int get_pipes_per_mec(struct device_queue_manager *dqm)
{
- BUG_ON(!dqm || !dqm->dev);
return dqm->dev->shared_resources.num_pipe_per_mec;
}
@@ -121,7 +118,7 @@ static int allocate_vmid(struct device_queue_manager *dqm,
/* Kaveri kfd vmid's starts from vmid 8 */
allocated_vmid = bit + KFD_VMID_START_OFFSET;
- pr_debug("kfd: vmid allocation %d\n", allocated_vmid);
+ pr_debug("vmid allocation %d\n", allocated_vmid);
qpd->vmid = allocated_vmid;
q->properties.vmid = allocated_vmid;
@@ -152,42 +149,38 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm,
{
int retval;
- BUG_ON(!dqm || !q || !qpd || !allocated_vmid);
-
- pr_debug("kfd: In func %s\n", __func__);
print_queue(q);
mutex_lock(&dqm->lock);
if (dqm->total_queue_count >= max_num_of_queues_per_device) {
- pr_warn("amdkfd: Can't create new usermode queue because %d queues were already created\n",
+ pr_warn("Can't create new usermode queue because %d queues were already created\n",
dqm->total_queue_count);
- mutex_unlock(&dqm->lock);
- return -EPERM;
+ retval = -EPERM;
+ goto out_unlock;
}
if (list_empty(&qpd->queues_list)) {
retval = allocate_vmid(dqm, qpd, q);
- if (retval != 0) {
- mutex_unlock(&dqm->lock);
- return retval;
- }
+ if (retval)
+ goto out_unlock;
}
*allocated_vmid = qpd->vmid;
q->properties.vmid = qpd->vmid;
if (q->properties.type == KFD_QUEUE_TYPE_COMPUTE)
retval = create_compute_queue_nocpsch(dqm, q, qpd);
- if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
+ else if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
retval = create_sdma_queue_nocpsch(dqm, q, qpd);
+ else
+ retval = -EINVAL;
- if (retval != 0) {
+ if (retval) {
if (list_empty(&qpd->queues_list)) {
deallocate_vmid(dqm, qpd, q);
*allocated_vmid = 0;
}
- mutex_unlock(&dqm->lock);
- return retval;
+ goto out_unlock;
}
list_add(&q->list, &qpd->queues_list);
@@ -205,8 +198,9 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm,
pr_debug("Total of %d queues are accountable so far\n",
dqm->total_queue_count);
+out_unlock:
mutex_unlock(&dqm->lock);
- return 0;
+ return retval;
}
static int allocate_hqd(struct device_queue_manager *dqm, struct queue *q)
@@ -216,7 +210,8 @@ static int allocate_hqd(struct device_queue_manager *dqm, struct queue *q)
set = false;
- for (pipe = dqm->next_pipe_to_allocate, i = 0; i < get_pipes_per_mec(dqm);
+ for (pipe = dqm->next_pipe_to_allocate, i = 0;
+ i < get_pipes_per_mec(dqm);
pipe = ((pipe + 1) % get_pipes_per_mec(dqm)), ++i) {
if (!is_pipe_enabled(dqm, 0, pipe))
@@ -239,8 +234,7 @@ static int allocate_hqd(struct device_queue_manager *dqm, struct queue *q)
if (!set)
return -EBUSY;
- pr_debug("kfd: DQM %s hqd slot - pipe (%d) queue(%d)\n",
- __func__, q->pipe, q->queue);
+ pr_debug("hqd slot - pipe %d, queue %d\n", q->pipe, q->queue);
/* horizontal hqd allocation */
dqm->next_pipe_to_allocate = (pipe + 1) % get_pipes_per_mec(dqm);
@@ -260,36 +254,38 @@ static int create_compute_queue_nocpsch(struct device_queue_manager *dqm,
int retval;
struct mqd_manager *mqd;
- BUG_ON(!dqm || !q || !qpd);
-
mqd = dqm->ops.get_mqd_manager(dqm, KFD_MQD_TYPE_COMPUTE);
- if (mqd == NULL)
+ if (!mqd)
return -ENOMEM;
retval = allocate_hqd(dqm, q);
- if (retval != 0)
+ if (retval)
return retval;
retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj,
&q->gart_mqd_addr, &q->properties);
- if (retval != 0) {
- deallocate_hqd(dqm, q);
- return retval;
- }
+ if (retval)
+ goto out_deallocate_hqd;
- pr_debug("kfd: loading mqd to hqd on pipe (%d) queue (%d)\n",
- q->pipe,
- q->queue);
+ pr_debug("Loading mqd to hqd on pipe %d, queue %d\n",
+ q->pipe, q->queue);
- retval = mqd->load_mqd(mqd, q->mqd, q->pipe,
- q->queue, (uint32_t __user *) q->properties.write_ptr);
- if (retval != 0) {
- deallocate_hqd(dqm, q);
- mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj);
- return retval;
- }
+ dqm->dev->kfd2kgd->set_scratch_backing_va(
+ dqm->dev->kgd, qpd->sh_hidden_private_base, qpd->vmid);
+
+ retval = mqd->load_mqd(mqd, q->mqd, q->pipe, q->queue, &q->properties,
+ q->process->mm);
+ if (retval)
+ goto out_uninit_mqd;
return 0;
+
+out_uninit_mqd:
+ mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj);
+out_deallocate_hqd:
+ deallocate_hqd(dqm, q);
+
+ return retval;
}
static int destroy_queue_nocpsch(struct device_queue_manager *dqm,
@@ -299,12 +295,8 @@ static int destroy_queue_nocpsch(struct device_queue_manager *dqm,
int retval;
struct mqd_manager *mqd;
- BUG_ON(!dqm || !q || !q->mqd || !qpd);
-
retval = 0;
- pr_debug("kfd: In Func %s\n", __func__);
-
mutex_lock(&dqm->lock);
if (q->properties.type == KFD_QUEUE_TYPE_COMPUTE) {
@@ -323,7 +315,7 @@ static int destroy_queue_nocpsch(struct device_queue_manager *dqm,
dqm->sdma_queue_count--;
deallocate_sdma_queue(dqm, q->sdma_id);
} else {
- pr_debug("q->properties.type is invalid (%d)\n",
+ pr_debug("q->properties.type %d is invalid\n",
q->properties.type);
retval = -EINVAL;
goto out;
@@ -334,7 +326,7 @@ static int destroy_queue_nocpsch(struct device_queue_manager *dqm,
QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS,
q->pipe, q->queue);
- if (retval != 0)
+ if (retval)
goto out;
mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj);
@@ -364,14 +356,12 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q)
struct mqd_manager *mqd;
bool prev_active = false;
- BUG_ON(!dqm || !q || !q->mqd);
-
mutex_lock(&dqm->lock);
mqd = dqm->ops.get_mqd_manager(dqm,
get_mqd_type_from_queue_type(q->properties.type));
- if (mqd == NULL) {
- mutex_unlock(&dqm->lock);
- return -ENOMEM;
+ if (!mqd) {
+ retval = -ENOMEM;
+ goto out_unlock;
}
if (q->properties.is_active)
@@ -385,12 +375,13 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q)
retval = mqd->update_mqd(mqd, q->mqd, &q->properties);
if ((q->properties.is_active) && (!prev_active))
dqm->queue_count++;
- else if ((!q->properties.is_active) && (prev_active))
+ else if (!q->properties.is_active && prev_active)
dqm->queue_count--;
if (sched_policy != KFD_SCHED_POLICY_NO_HWS)
retval = execute_queues_cpsch(dqm, false);
+out_unlock:
mutex_unlock(&dqm->lock);
return retval;
}
@@ -400,15 +391,16 @@ static struct mqd_manager *get_mqd_manager_nocpsch(
{
struct mqd_manager *mqd;
- BUG_ON(!dqm || type >= KFD_MQD_TYPE_MAX);
+ if (WARN_ON(type >= KFD_MQD_TYPE_MAX))
+ return NULL;
- pr_debug("kfd: In func %s mqd type %d\n", __func__, type);
+ pr_debug("mqd type %d\n", type);
mqd = dqm->mqds[type];
if (!mqd) {
mqd = mqd_manager_init(type, dqm->dev);
- if (mqd == NULL)
- pr_err("kfd: mqd manager is NULL");
+ if (!mqd)
+ pr_err("mqd manager is NULL");
dqm->mqds[type] = mqd;
}
@@ -421,11 +413,7 @@ static int register_process_nocpsch(struct device_queue_manager *dqm,
struct device_process_node *n;
int retval;
- BUG_ON(!dqm || !qpd);
-
- pr_debug("kfd: In func %s\n", __func__);
-
- n = kzalloc(sizeof(struct device_process_node), GFP_KERNEL);
+ n = kzalloc(sizeof(*n), GFP_KERNEL);
if (!n)
return -ENOMEM;
@@ -449,10 +437,6 @@ static int unregister_process_nocpsch(struct device_queue_manager *dqm,
int retval;
struct device_process_node *cur, *next;
- BUG_ON(!dqm || !qpd);
-
- pr_debug("In func %s\n", __func__);
-
pr_debug("qpd->queues_list is %s\n",
list_empty(&qpd->queues_list) ? "empty" : "not empty");
@@ -493,51 +477,39 @@ static void init_interrupts(struct device_queue_manager *dqm)
{
unsigned int i;
- BUG_ON(dqm == NULL);
-
for (i = 0 ; i < get_pipes_per_mec(dqm) ; i++)
if (is_pipe_enabled(dqm, 0, i))
dqm->dev->kfd2kgd->init_interrupts(dqm->dev->kgd, i);
}
-static int init_scheduler(struct device_queue_manager *dqm)
-{
- int retval = 0;
-
- BUG_ON(!dqm);
-
- pr_debug("kfd: In %s\n", __func__);
-
- return retval;
-}
-
static int initialize_nocpsch(struct device_queue_manager *dqm)
{
- int i;
+ int pipe, queue;
- BUG_ON(!dqm);
+ pr_debug("num of pipes: %d\n", get_pipes_per_mec(dqm));
- pr_debug("kfd: In func %s num of pipes: %d\n",
- __func__, get_pipes_per_mec(dqm));
+ dqm->allocated_queues = kcalloc(get_pipes_per_mec(dqm),
+ sizeof(unsigned int), GFP_KERNEL);
+ if (!dqm->allocated_queues)
+ return -ENOMEM;
mutex_init(&dqm->lock);
INIT_LIST_HEAD(&dqm->queues);
dqm->queue_count = dqm->next_pipe_to_allocate = 0;
dqm->sdma_queue_count = 0;
- dqm->allocated_queues = kcalloc(get_pipes_per_mec(dqm),
- sizeof(unsigned int), GFP_KERNEL);
- if (!dqm->allocated_queues) {
- mutex_destroy(&dqm->lock);
- return -ENOMEM;
- }
- for (i = 0; i < get_pipes_per_mec(dqm); i++)
- dqm->allocated_queues[i] = (1 << get_queues_per_pipe(dqm)) - 1;
+ for (pipe = 0; pipe < get_pipes_per_mec(dqm); pipe++) {
+ int pipe_offset = pipe * get_queues_per_pipe(dqm);
+
+ for (queue = 0; queue < get_queues_per_pipe(dqm); queue++)
+ if (test_bit(pipe_offset + queue,
+ dqm->dev->shared_resources.queue_bitmap))
+ dqm->allocated_queues[pipe] |= 1 << queue;
+ }
dqm->vmid_bitmap = (1 << VMID_PER_DEVICE) - 1;
dqm->sdma_bitmap = (1 << CIK_SDMA_QUEUES) - 1;
- init_scheduler(dqm);
return 0;
}
@@ -545,9 +517,7 @@ static void uninitialize_nocpsch(struct device_queue_manager *dqm)
{
int i;
- BUG_ON(!dqm);
-
- BUG_ON(dqm->queue_count > 0 || dqm->processes_count > 0);
+ WARN_ON(dqm->queue_count > 0 || dqm->processes_count > 0);
kfree(dqm->allocated_queues);
for (i = 0 ; i < KFD_MQD_TYPE_MAX ; i++)
@@ -604,33 +574,34 @@ static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm,
return -ENOMEM;
retval = allocate_sdma_queue(dqm, &q->sdma_id);
- if (retval != 0)
+ if (retval)
return retval;
q->properties.sdma_queue_id = q->sdma_id % CIK_SDMA_QUEUES_PER_ENGINE;
q->properties.sdma_engine_id = q->sdma_id / CIK_SDMA_ENGINE_NUM;
- pr_debug("kfd: sdma id is: %d\n", q->sdma_id);
- pr_debug(" sdma queue id: %d\n", q->properties.sdma_queue_id);
- pr_debug(" sdma engine id: %d\n", q->properties.sdma_engine_id);
+ pr_debug("SDMA id is: %d\n", q->sdma_id);
+ pr_debug("SDMA queue id: %d\n", q->properties.sdma_queue_id);
+ pr_debug("SDMA engine id: %d\n", q->properties.sdma_engine_id);
dqm->ops_asic_specific.init_sdma_vm(dqm, q, qpd);
retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj,
&q->gart_mqd_addr, &q->properties);
- if (retval != 0) {
- deallocate_sdma_queue(dqm, q->sdma_id);
- return retval;
- }
+ if (retval)
+ goto out_deallocate_sdma_queue;
- retval = mqd->load_mqd(mqd, q->mqd, 0,
- 0, NULL);
- if (retval != 0) {
- deallocate_sdma_queue(dqm, q->sdma_id);
- mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj);
- return retval;
- }
+ retval = mqd->load_mqd(mqd, q->mqd, 0, 0, &q->properties, NULL);
+ if (retval)
+ goto out_uninit_mqd;
return 0;
+
+out_uninit_mqd:
+ mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj);
+out_deallocate_sdma_queue:
+ deallocate_sdma_queue(dqm, q->sdma_id);
+
+ return retval;
}
/*
@@ -642,10 +613,6 @@ static int set_sched_resources(struct device_queue_manager *dqm)
int i, mec;
struct scheduling_resources res;
- BUG_ON(!dqm);
-
- pr_debug("kfd: In func %s\n", __func__);
-
res.vmid_mask = (1 << VMID_PER_DEVICE) - 1;
res.vmid_mask <<= KFD_VMID_START_OFFSET;
@@ -663,8 +630,9 @@ static int set_sched_resources(struct device_queue_manager *dqm)
/* This situation may be hit in the future if a new HW
* generation exposes more than 64 queues. If so, the
- * definition of res.queue_mask needs updating */
- if (WARN_ON(i > (sizeof(res.queue_mask)*8))) {
+ * definition of res.queue_mask needs updating
+ */
+ if (WARN_ON(i >= (sizeof(res.queue_mask)*8))) {
pr_err("Invalid queue enabled by amdgpu: %d\n", i);
break;
}
@@ -674,9 +642,9 @@ static int set_sched_resources(struct device_queue_manager *dqm)
res.gws_mask = res.oac_mask = res.gds_heap_base =
res.gds_heap_size = 0;
- pr_debug("kfd: scheduling resources:\n"
- " vmid mask: 0x%8X\n"
- " queue mask: 0x%8llX\n",
+ pr_debug("Scheduling resources:\n"
+ "vmid mask: 0x%8X\n"
+ "queue mask: 0x%8llX\n",
res.vmid_mask, res.queue_mask);
return pm_send_set_resources(&dqm->packets, &res);
@@ -686,10 +654,7 @@ static int initialize_cpsch(struct device_queue_manager *dqm)
{
int retval;
- BUG_ON(!dqm);
-
- pr_debug("kfd: In func %s num of pipes: %d\n",
- __func__, get_pipes_per_mec(dqm));
+ pr_debug("num of pipes: %d\n", get_pipes_per_mec(dqm));
mutex_init(&dqm->lock);
INIT_LIST_HEAD(&dqm->queues);
@@ -697,13 +662,9 @@ static int initialize_cpsch(struct device_queue_manager *dqm)
dqm->sdma_queue_count = 0;
dqm->active_runlist = false;
retval = dqm->ops_asic_specific.initialize(dqm);
- if (retval != 0)
- goto fail_init_pipelines;
-
- return 0;
+ if (retval)
+ mutex_destroy(&dqm->lock);
-fail_init_pipelines:
- mutex_destroy(&dqm->lock);
return retval;
}
@@ -712,25 +673,23 @@ static int start_cpsch(struct device_queue_manager *dqm)
struct device_process_node *node;
int retval;
- BUG_ON(!dqm);
-
retval = 0;
retval = pm_init(&dqm->packets, dqm);
- if (retval != 0)
+ if (retval)
goto fail_packet_manager_init;
retval = set_sched_resources(dqm);
- if (retval != 0)
+ if (retval)
goto fail_set_sched_resources;
- pr_debug("kfd: allocating fence memory\n");
+ pr_debug("Allocating fence memory\n");
/* allocate fence memory on the gart */
retval = kfd_gtt_sa_allocate(dqm->dev, sizeof(*dqm->fence_addr),
&dqm->fence_mem);
- if (retval != 0)
+ if (retval)
goto fail_allocate_vidmem;
dqm->fence_addr = dqm->fence_mem->cpu_ptr;
@@ -758,8 +717,6 @@ static int stop_cpsch(struct device_queue_manager *dqm)
struct device_process_node *node;
struct kfd_process_device *pdd;
- BUG_ON(!dqm);
-
destroy_queues_cpsch(dqm, true, true);
list_for_each_entry(node, &dqm->queues, list) {
@@ -776,13 +733,9 @@ static int create_kernel_queue_cpsch(struct device_queue_manager *dqm,
struct kernel_queue *kq,
struct qcm_process_device *qpd)
{
- BUG_ON(!dqm || !kq || !qpd);
-
- pr_debug("kfd: In func %s\n", __func__);
-
mutex_lock(&dqm->lock);
if (dqm->total_queue_count >= max_num_of_queues_per_device) {
- pr_warn("amdkfd: Can't create new kernel queue because %d queues were already created\n",
+ pr_warn("Can't create new kernel queue because %d queues were already created\n",
dqm->total_queue_count);
mutex_unlock(&dqm->lock);
return -EPERM;
@@ -809,10 +762,6 @@ static void destroy_kernel_queue_cpsch(struct device_queue_manager *dqm,
struct kernel_queue *kq,
struct qcm_process_device *qpd)
{
- BUG_ON(!dqm || !kq);
-
- pr_debug("kfd: In %s\n", __func__);
-
mutex_lock(&dqm->lock);
/* here we actually preempt the DIQ */
destroy_queues_cpsch(dqm, true, false);
@@ -844,8 +793,6 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
int retval;
struct mqd_manager *mqd;
- BUG_ON(!dqm || !q || !qpd);
-
retval = 0;
if (allocate_vmid)
@@ -854,7 +801,7 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
mutex_lock(&dqm->lock);
if (dqm->total_queue_count >= max_num_of_queues_per_device) {
- pr_warn("amdkfd: Can't create new usermode queue because %d queues were already created\n",
+ pr_warn("Can't create new usermode queue because %d queues were already created\n",
dqm->total_queue_count);
retval = -EPERM;
goto out;
@@ -866,15 +813,15 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
mqd = dqm->ops.get_mqd_manager(dqm,
get_mqd_type_from_queue_type(q->properties.type));
- if (mqd == NULL) {
- mutex_unlock(&dqm->lock);
- return -ENOMEM;
+ if (!mqd) {
+ retval = -ENOMEM;
+ goto out;
}
dqm->ops_asic_specific.init_sdma_vm(dqm, q, qpd);
retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj,
&q->gart_mqd_addr, &q->properties);
- if (retval != 0)
+ if (retval)
goto out;
list_add(&q->list, &qpd->queues_list);
@@ -884,7 +831,7 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
}
if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
- dqm->sdma_queue_count++;
+ dqm->sdma_queue_count++;
/*
* Unconditionally increment this counter, regardless of the queue's
* type or whether the queue is active.
@@ -903,12 +850,11 @@ int amdkfd_fence_wait_timeout(unsigned int *fence_addr,
unsigned int fence_value,
unsigned long timeout)
{
- BUG_ON(!fence_addr);
timeout += jiffies;
while (*fence_addr != fence_value) {
if (time_after(jiffies, timeout)) {
- pr_err("kfd: qcm fence wait loop timeout expired\n");
+ pr_err("qcm fence wait loop timeout expired\n");
return -ETIME;
}
schedule();
@@ -932,8 +878,6 @@ static int destroy_queues_cpsch(struct device_queue_manager *dqm,
enum kfd_preempt_type_filter preempt_type;
struct kfd_process_device *pdd;
- BUG_ON(!dqm);
-
retval = 0;
if (lock)
@@ -941,7 +885,7 @@ static int destroy_queues_cpsch(struct device_queue_manager *dqm,
if (!dqm->active_runlist)
goto out;
- pr_debug("kfd: Before destroying queues, sdma queue count is : %u\n",
+ pr_debug("Before destroying queues, sdma queue count is : %u\n",
dqm->sdma_queue_count);
if (dqm->sdma_queue_count > 0) {
@@ -955,7 +899,7 @@ static int destroy_queues_cpsch(struct device_queue_manager *dqm,
retval = pm_send_unmap_queue(&dqm->packets, KFD_QUEUE_TYPE_COMPUTE,
preempt_type, 0, false, 0);
- if (retval != 0)
+ if (retval)
goto out;
*dqm->fence_addr = KFD_FENCE_INIT;
@@ -964,7 +908,7 @@ static int destroy_queues_cpsch(struct device_queue_manager *dqm,
/* should be timed out */
retval = amdkfd_fence_wait_timeout(dqm->fence_addr, KFD_FENCE_COMPLETED,
QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS);
- if (retval != 0) {
+ if (retval) {
pdd = kfd_get_process_device_data(dqm->dev,
kfd_get_process(current));
pdd->reset_wavefronts = true;
@@ -983,14 +927,12 @@ static int execute_queues_cpsch(struct device_queue_manager *dqm, bool lock)
{
int retval;
- BUG_ON(!dqm);
-
if (lock)
mutex_lock(&dqm->lock);
retval = destroy_queues_cpsch(dqm, false, false);
- if (retval != 0) {
- pr_err("kfd: the cp might be in an unrecoverable state due to an unsuccessful queues preemption");
+ if (retval) {
+ pr_err("The cp might be in an unrecoverable state due to an unsuccessful queues preemption");
goto out;
}
@@ -1005,8 +947,8 @@ static int execute_queues_cpsch(struct device_queue_manager *dqm, bool lock)
}
retval = pm_send_runlist(&dqm->packets, &dqm->queues);
- if (retval != 0) {
- pr_err("kfd: failed to execute runlist");
+ if (retval) {
+ pr_err("failed to execute runlist");
goto out;
}
dqm->active_runlist = true;
@@ -1025,8 +967,6 @@ static int destroy_queue_cpsch(struct device_queue_manager *dqm,
struct mqd_manager *mqd;
bool preempt_all_queues;
- BUG_ON(!dqm || !qpd || !q);
-
preempt_all_queues = false;
retval = 0;
@@ -1098,8 +1038,6 @@ static bool set_cache_memory_policy(struct device_queue_manager *dqm,
{
bool retval;
- pr_debug("kfd: In func %s\n", __func__);
-
mutex_lock(&dqm->lock);
if (alternate_aperture_size == 0) {
@@ -1120,14 +1058,11 @@ static bool set_cache_memory_policy(struct device_queue_manager *dqm,
uint64_t base = (uintptr_t)alternate_aperture_base;
uint64_t limit = base + alternate_aperture_size - 1;
- if (limit <= base)
- goto out;
-
- if ((base & APE1_FIXED_BITS_MASK) != 0)
- goto out;
-
- if ((limit & APE1_FIXED_BITS_MASK) != APE1_LIMIT_ALIGNMENT)
+ if (limit <= base || (base & APE1_FIXED_BITS_MASK) != 0 ||
+ (limit & APE1_FIXED_BITS_MASK) != APE1_LIMIT_ALIGNMENT) {
+ retval = false;
goto out;
+ }
qpd->sh_mem_ape1_base = base >> 16;
qpd->sh_mem_ape1_limit = limit >> 16;
@@ -1144,27 +1079,22 @@ static bool set_cache_memory_policy(struct device_queue_manager *dqm,
if ((sched_policy == KFD_SCHED_POLICY_NO_HWS) && (qpd->vmid != 0))
program_sh_mem_settings(dqm, qpd);
- pr_debug("kfd: sh_mem_config: 0x%x, ape1_base: 0x%x, ape1_limit: 0x%x\n",
+ pr_debug("sh_mem_config: 0x%x, ape1_base: 0x%x, ape1_limit: 0x%x\n",
qpd->sh_mem_config, qpd->sh_mem_ape1_base,
qpd->sh_mem_ape1_limit);
- mutex_unlock(&dqm->lock);
- return retval;
-
out:
mutex_unlock(&dqm->lock);
- return false;
+ return retval;
}
struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev)
{
struct device_queue_manager *dqm;
- BUG_ON(!dev);
+ pr_debug("Loading device queue manager\n");
- pr_debug("kfd: loading device queue manager\n");
-
- dqm = kzalloc(sizeof(struct device_queue_manager), GFP_KERNEL);
+ dqm = kzalloc(sizeof(*dqm), GFP_KERNEL);
if (!dqm)
return NULL;
@@ -1202,8 +1132,8 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev)
dqm->ops.set_cache_memory_policy = set_cache_memory_policy;
break;
default:
- BUG();
- break;
+ pr_err("Invalid scheduling policy %d\n", sched_policy);
+ goto out_free;
}
switch (dev->device_info->asic_family) {
@@ -1216,18 +1146,16 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev)
break;
}
- if (dqm->ops.initialize(dqm) != 0) {
- kfree(dqm);
- return NULL;
- }
+ if (!dqm->ops.initialize(dqm))
+ return dqm;
- return dqm;
+out_free:
+ kfree(dqm);
+ return NULL;
}
void device_queue_manager_uninit(struct device_queue_manager *dqm)
{
- BUG_ON(!dqm);
-
dqm->ops.uninitialize(dqm);
kfree(dqm);
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c
index 48dc056..72c3cba 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c
@@ -24,6 +24,7 @@
#include "kfd_device_queue_manager.h"
#include "cik_regs.h"
#include "oss/oss_2_4_sh_mask.h"
+#include "gca/gfx_7_2_sh_mask.h"
static bool set_cache_memory_policy_cik(struct device_queue_manager *dqm,
struct qcm_process_device *qpd,
@@ -65,7 +66,7 @@ static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble)
* for LDS/Scratch and GPUVM.
*/
- BUG_ON((top_address_nybble & 1) || top_address_nybble > 0xE ||
+ WARN_ON((top_address_nybble & 1) || top_address_nybble > 0xE ||
top_address_nybble == 0);
return PRIVATE_BASE(top_address_nybble << 12) |
@@ -104,8 +105,6 @@ static int register_process_cik(struct device_queue_manager *dqm,
struct kfd_process_device *pdd;
unsigned int temp;
- BUG_ON(!dqm || !qpd);
-
pdd = qpd_to_pdd(qpd);
/* check if sh_mem_config register already configured */
@@ -125,9 +124,10 @@ static int register_process_cik(struct device_queue_manager *dqm,
} else {
temp = get_sh_mem_bases_nybble_64(pdd);
qpd->sh_mem_bases = compute_sh_mem_bases_64bit(temp);
+ qpd->sh_mem_config |= 1 << SH_MEM_CONFIG__PRIVATE_ATC__SHIFT;
}
- pr_debug("kfd: is32bit process: %d sh_mem_bases nybble: 0x%X and register 0x%X\n",
+ pr_debug("is32bit process: %d sh_mem_bases nybble: 0x%X and register 0x%X\n",
qpd->pqm->process->is_32bit_user_mode, temp, qpd->sh_mem_bases);
return 0;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c
index 7e9cae9..40e9ddd 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c
@@ -67,7 +67,7 @@ static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble)
* for LDS/Scratch and GPUVM.
*/
- BUG_ON((top_address_nybble & 1) || top_address_nybble > 0xE ||
+ WARN_ON((top_address_nybble & 1) || top_address_nybble > 0xE ||
top_address_nybble == 0);
return top_address_nybble << 12 |
@@ -110,8 +110,6 @@ static int register_process_vi(struct device_queue_manager *dqm,
struct kfd_process_device *pdd;
unsigned int temp;
- BUG_ON(!dqm || !qpd);
-
pdd = qpd_to_pdd(qpd);
/* check if sh_mem_config register already configured */
@@ -137,9 +135,11 @@ static int register_process_vi(struct device_queue_manager *dqm,
qpd->sh_mem_bases = compute_sh_mem_bases_64bit(temp);
qpd->sh_mem_config |= SH_MEM_ADDRESS_MODE_HSA64 <<
SH_MEM_CONFIG__ADDRESS_MODE__SHIFT;
+ qpd->sh_mem_config |= 1 <<
+ SH_MEM_CONFIG__PRIVATE_ATC__SHIFT;
}
- pr_debug("kfd: is32bit process: %d sh_mem_bases nybble: 0x%X and register 0x%X\n",
+ pr_debug("is32bit process: %d sh_mem_bases nybble: 0x%X and register 0x%X\n",
qpd->pqm->process->is_32bit_user_mode, temp, qpd->sh_mem_bases);
return 0;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
index 453c5d6..acf4d2a 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
@@ -59,7 +59,7 @@ static inline size_t doorbell_process_allocation(void)
}
/* Doorbell calculations for device init. */
-void kfd_doorbell_init(struct kfd_dev *kfd)
+int kfd_doorbell_init(struct kfd_dev *kfd)
{
size_t doorbell_start_offset;
size_t doorbell_aperture_size;
@@ -95,26 +95,35 @@ void kfd_doorbell_init(struct kfd_dev *kfd)
kfd->doorbell_kernel_ptr = ioremap(kfd->doorbell_base,
doorbell_process_allocation());
- BUG_ON(!kfd->doorbell_kernel_ptr);
+ if (!kfd->doorbell_kernel_ptr)
+ return -ENOMEM;
- pr_debug("kfd: doorbell initialization:\n");
- pr_debug("kfd: doorbell base == 0x%08lX\n",
+ pr_debug("Doorbell initialization:\n");
+ pr_debug("doorbell base == 0x%08lX\n",
(uintptr_t)kfd->doorbell_base);
- pr_debug("kfd: doorbell_id_offset == 0x%08lX\n",
+ pr_debug("doorbell_id_offset == 0x%08lX\n",
kfd->doorbell_id_offset);
- pr_debug("kfd: doorbell_process_limit == 0x%08lX\n",
+ pr_debug("doorbell_process_limit == 0x%08lX\n",
doorbell_process_limit);
- pr_debug("kfd: doorbell_kernel_offset == 0x%08lX\n",
+ pr_debug("doorbell_kernel_offset == 0x%08lX\n",
(uintptr_t)kfd->doorbell_base);
- pr_debug("kfd: doorbell aperture size == 0x%08lX\n",
+ pr_debug("doorbell aperture size == 0x%08lX\n",
kfd->shared_resources.doorbell_aperture_size);
- pr_debug("kfd: doorbell kernel address == 0x%08lX\n",
+ pr_debug("doorbell kernel address == 0x%08lX\n",
(uintptr_t)kfd->doorbell_kernel_ptr);
+
+ return 0;
+}
+
+void kfd_doorbell_fini(struct kfd_dev *kfd)
+{
+ if (kfd->doorbell_kernel_ptr)
+ iounmap(kfd->doorbell_kernel_ptr);
}
int kfd_doorbell_mmap(struct kfd_process *process, struct vm_area_struct *vma)
@@ -131,7 +140,7 @@ int kfd_doorbell_mmap(struct kfd_process *process, struct vm_area_struct *vma)
/* Find kfd device according to gpu id */
dev = kfd_device_by_id(vma->vm_pgoff);
- if (dev == NULL)
+ if (!dev)
return -EINVAL;
/* Calculate physical address of doorbell */
@@ -142,12 +151,11 @@ int kfd_doorbell_mmap(struct kfd_process *process, struct vm_area_struct *vma)
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- pr_debug("kfd: mapping doorbell page in %s\n"
+ pr_debug("Mapping doorbell page\n"
" target user address == 0x%08llX\n"
" physical address == 0x%08llX\n"
" vm_flags == 0x%04lX\n"
" size == 0x%04lX\n",
- __func__,
(unsigned long long) vma->vm_start, address, vma->vm_flags,
doorbell_process_allocation());
@@ -166,8 +174,6 @@ u32 __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd,
{
u32 inx;
- BUG_ON(!kfd || !doorbell_off);
-
mutex_lock(&kfd->doorbell_mutex);
inx = find_first_zero_bit(kfd->doorbell_available_index,
KFD_MAX_NUM_OF_QUEUES_PER_PROCESS);
@@ -185,7 +191,7 @@ u32 __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd,
*doorbell_off = KERNEL_DOORBELL_PASID * (doorbell_process_allocation() /
sizeof(u32)) + inx;
- pr_debug("kfd: get kernel queue doorbell\n"
+ pr_debug("Get kernel queue doorbell\n"
" doorbell offset == 0x%08X\n"
" kernel address == 0x%08lX\n",
*doorbell_off, (uintptr_t)(kfd->doorbell_kernel_ptr + inx));
@@ -197,8 +203,6 @@ void kfd_release_kernel_doorbell(struct kfd_dev *kfd, u32 __iomem *db_addr)
{
unsigned int inx;
- BUG_ON(!kfd || !db_addr);
-
inx = (unsigned int)(db_addr - kfd->doorbell_kernel_ptr);
mutex_lock(&kfd->doorbell_mutex);
@@ -210,7 +214,7 @@ inline void write_kernel_doorbell(u32 __iomem *db, u32 value)
{
if (db) {
writel(value, db);
- pr_debug("writing %d to doorbell address 0x%p\n", value, db);
+ pr_debug("Writing %d to doorbell address 0x%p\n", value, db);
}
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
index d1ce83d..5979158 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
@@ -110,7 +110,7 @@ static bool allocate_free_slot(struct kfd_process *process,
*out_page = page;
*out_slot_index = slot;
- pr_debug("allocated event signal slot in page %p, slot %d\n",
+ pr_debug("Allocated event signal slot in page %p, slot %d\n",
page, slot);
return true;
@@ -155,9 +155,9 @@ static bool allocate_signal_page(struct file *devkfd, struct kfd_process *p)
struct signal_page,
event_pages)->page_index + 1;
- pr_debug("allocated new event signal page at %p, for process %p\n",
+ pr_debug("Allocated new event signal page at %p, for process %p\n",
page, p);
- pr_debug("page index is %d\n", page->page_index);
+ pr_debug("Page index is %d\n", page->page_index);
list_add(&page->event_pages, &p->signal_event_pages);
@@ -194,7 +194,8 @@ static void release_event_notification_slot(struct signal_page *page,
page->free_slots++;
/* We don't free signal pages, they are retained by the process
- * and reused until it exits. */
+ * and reused until it exits.
+ */
}
static struct signal_page *lookup_signal_page_by_index(struct kfd_process *p,
@@ -246,7 +247,7 @@ static u32 make_nonsignal_event_id(struct kfd_process *p)
for (id = p->next_nonsignal_event_id;
id < KFD_LAST_NONSIGNAL_EVENT_ID &&
- lookup_event_by_id(p, id) != NULL;
+ lookup_event_by_id(p, id);
id++)
;
@@ -265,7 +266,7 @@ static u32 make_nonsignal_event_id(struct kfd_process *p)
for (id = KFD_FIRST_NONSIGNAL_EVENT_ID;
id < KFD_LAST_NONSIGNAL_EVENT_ID &&
- lookup_event_by_id(p, id) != NULL;
+ lookup_event_by_id(p, id);
id++)
;
@@ -291,13 +292,13 @@ static int create_signal_event(struct file *devkfd,
struct kfd_event *ev)
{
if (p->signal_event_count == KFD_SIGNAL_EVENT_LIMIT) {
- pr_warn("amdkfd: Signal event wasn't created because limit was reached\n");
+ pr_warn("Signal event wasn't created because limit was reached\n");
return -ENOMEM;
}
if (!allocate_event_notification_slot(devkfd, p, &ev->signal_page,
&ev->signal_slot_index)) {
- pr_warn("amdkfd: Signal event wasn't created because out of kernel memory\n");
+ pr_warn("Signal event wasn't created because out of kernel memory\n");
return -ENOMEM;
}
@@ -309,11 +310,7 @@ static int create_signal_event(struct file *devkfd,
ev->event_id = make_signal_event_id(ev->signal_page,
ev->signal_slot_index);
- pr_debug("signal event number %zu created with id %d, address %p\n",
- p->signal_event_count, ev->event_id,
- ev->user_signal_address);
-
- pr_debug("signal event number %zu created with id %d, address %p\n",
+ pr_debug("Signal event number %zu created with id %d, address %p\n",
p->signal_event_count, ev->event_id,
ev->user_signal_address);
@@ -345,7 +342,7 @@ void kfd_event_init_process(struct kfd_process *p)
static void destroy_event(struct kfd_process *p, struct kfd_event *ev)
{
- if (ev->signal_page != NULL) {
+ if (ev->signal_page) {
release_event_notification_slot(ev->signal_page,
ev->signal_slot_index);
p->signal_event_count--;
@@ -584,7 +581,7 @@ void kfd_signal_event_interrupt(unsigned int pasid, uint32_t partial_id,
* search faster.
*/
struct signal_page *page;
- unsigned i;
+ unsigned int i;
list_for_each_entry(page, &p->signal_event_pages, event_pages)
for (i = 0; i < SLOTS_PER_PAGE; i++)
@@ -816,7 +813,7 @@ int kfd_event_mmap(struct kfd_process *p, struct vm_area_struct *vma)
/* check required size is logical */
if (get_order(KFD_SIGNAL_EVENT_LIMIT * 8) !=
get_order(vma->vm_end - vma->vm_start)) {
- pr_err("amdkfd: event page mmap requested illegal size\n");
+ pr_err("Event page mmap requested illegal size\n");
return -EINVAL;
}
@@ -825,7 +822,7 @@ int kfd_event_mmap(struct kfd_process *p, struct vm_area_struct *vma)
page = lookup_signal_page_by_index(p, page_index);
if (!page) {
/* Probably KFD bug, but mmap is user-accessible. */
- pr_debug("signal page could not be found for page_index %u\n",
+ pr_debug("Signal page could not be found for page_index %u\n",
page_index);
return -EINVAL;
}
@@ -836,7 +833,7 @@ int kfd_event_mmap(struct kfd_process *p, struct vm_area_struct *vma)
vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE
| VM_DONTDUMP | VM_PFNMAP;
- pr_debug("mapping signal page\n");
+ pr_debug("Mapping signal page\n");
pr_debug(" start user address == 0x%08lx\n", vma->vm_start);
pr_debug(" end user address == 0x%08lx\n", vma->vm_end);
pr_debug(" pfn == 0x%016lX\n", pfn);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c
index 2b65510..c59384b 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c
@@ -304,7 +304,7 @@ int kfd_init_apertures(struct kfd_process *process)
id < NUM_OF_SUPPORTED_GPUS) {
pdd = kfd_create_process_device_data(dev, process);
- if (pdd == NULL) {
+ if (!pdd) {
pr_err("Failed to create process device data\n");
return -1;
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c
index 7f134aa..70b3a99c 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c
@@ -179,7 +179,7 @@ static void interrupt_wq(struct work_struct *work)
bool interrupt_is_wanted(struct kfd_dev *dev, const uint32_t *ih_ring_entry)
{
/* integer and bitwise OR so there is no boolean short-circuiting */
- unsigned wanted = 0;
+ unsigned int wanted = 0;
wanted |= dev->device_info->event_interrupt_class->interrupt_isr(dev,
ih_ring_entry);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
index d135cd0..681b639 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
@@ -41,11 +41,11 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
int retval;
union PM4_MES_TYPE_3_HEADER nop;
- BUG_ON(!kq || !dev);
- BUG_ON(type != KFD_QUEUE_TYPE_DIQ && type != KFD_QUEUE_TYPE_HIQ);
+ if (WARN_ON(type != KFD_QUEUE_TYPE_DIQ && type != KFD_QUEUE_TYPE_HIQ))
+ return false;
- pr_debug("amdkfd: In func %s initializing queue type %d size %d\n",
- __func__, KFD_QUEUE_TYPE_HIQ, queue_size);
+ pr_debug("Initializing queue type %d size %d\n", KFD_QUEUE_TYPE_HIQ,
+ queue_size);
memset(&prop, 0, sizeof(prop));
memset(&nop, 0, sizeof(nop));
@@ -63,23 +63,23 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
KFD_MQD_TYPE_HIQ);
break;
default:
- BUG();
- break;
+ pr_err("Invalid queue type %d\n", type);
+ return false;
}
- if (kq->mqd == NULL)
+ if (!kq->mqd)
return false;
prop.doorbell_ptr = kfd_get_kernel_doorbell(dev, &prop.doorbell_off);
- if (prop.doorbell_ptr == NULL) {
- pr_err("amdkfd: error init doorbell");
+ if (!prop.doorbell_ptr) {
+ pr_err("Failed to initialize doorbell");
goto err_get_kernel_doorbell;
}
retval = kfd_gtt_sa_allocate(dev, queue_size, &kq->pq);
if (retval != 0) {
- pr_err("amdkfd: error init pq queues size (%d)\n", queue_size);
+ pr_err("Failed to init pq queues size %d\n", queue_size);
goto err_pq_allocate_vidmem;
}
@@ -87,7 +87,7 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
kq->pq_gpu_addr = kq->pq->gpu_addr;
retval = kq->ops_asic_specific.initialize(kq, dev, type, queue_size);
- if (retval == false)
+ if (!retval)
goto err_eop_allocate_vidmem;
retval = kfd_gtt_sa_allocate(dev, sizeof(*kq->rptr_kernel),
@@ -139,11 +139,12 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
/* assign HIQ to HQD */
if (type == KFD_QUEUE_TYPE_HIQ) {
- pr_debug("assigning hiq to hqd\n");
+ pr_debug("Assigning hiq to hqd\n");
kq->queue->pipe = KFD_CIK_HIQ_PIPE;
kq->queue->queue = KFD_CIK_HIQ_QUEUE;
kq->mqd->load_mqd(kq->mqd, kq->queue->mqd, kq->queue->pipe,
- kq->queue->queue, NULL);
+ kq->queue->queue, &kq->queue->properties,
+ NULL);
} else {
/* allocate fence for DIQ */
@@ -180,8 +181,6 @@ err_get_kernel_doorbell:
static void uninitialize(struct kernel_queue *kq)
{
- BUG_ON(!kq);
-
if (kq->queue->properties.type == KFD_QUEUE_TYPE_HIQ)
kq->mqd->destroy_mqd(kq->mqd,
NULL,
@@ -211,8 +210,6 @@ static int acquire_packet_buffer(struct kernel_queue *kq,
uint32_t wptr, rptr;
unsigned int *queue_address;
- BUG_ON(!kq || !buffer_ptr);
-
rptr = *kq->rptr_kernel;
wptr = *kq->wptr_kernel;
queue_address = (unsigned int *)kq->pq_kernel_addr;
@@ -252,11 +249,7 @@ static void submit_packet(struct kernel_queue *kq)
{
#ifdef DEBUG
int i;
-#endif
-
- BUG_ON(!kq);
-#ifdef DEBUG
for (i = *kq->wptr_kernel; i < kq->pending_wptr; i++) {
pr_debug("0x%2X ", kq->pq_kernel_addr[i]);
if (i % 15 == 0)
@@ -272,7 +265,6 @@ static void submit_packet(struct kernel_queue *kq)
static void rollback_packet(struct kernel_queue *kq)
{
- BUG_ON(!kq);
kq->pending_wptr = *kq->queue->properties.write_ptr;
}
@@ -281,9 +273,7 @@ struct kernel_queue *kernel_queue_init(struct kfd_dev *dev,
{
struct kernel_queue *kq;
- BUG_ON(!dev);
-
- kq = kzalloc(sizeof(struct kernel_queue), GFP_KERNEL);
+ kq = kzalloc(sizeof(*kq), GFP_KERNEL);
if (!kq)
return NULL;
@@ -304,7 +294,7 @@ struct kernel_queue *kernel_queue_init(struct kfd_dev *dev,
}
if (!kq->ops.initialize(kq, dev, type, KFD_KERNEL_QUEUE_SIZE)) {
- pr_err("amdkfd: failed to init kernel queue\n");
+ pr_err("Failed to init kernel queue\n");
kfree(kq);
return NULL;
}
@@ -313,32 +303,37 @@ struct kernel_queue *kernel_queue_init(struct kfd_dev *dev,
void kernel_queue_uninit(struct kernel_queue *kq)
{
- BUG_ON(!kq);
-
kq->ops.uninitialize(kq);
kfree(kq);
}
+/* FIXME: Can this test be removed? */
static __attribute__((unused)) void test_kq(struct kfd_dev *dev)
{
struct kernel_queue *kq;
uint32_t *buffer, i;
int retval;
- BUG_ON(!dev);
-
- pr_err("amdkfd: starting kernel queue test\n");
+ pr_err("Starting kernel queue test\n");
kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_HIQ);
- BUG_ON(!kq);
+ if (unlikely(!kq)) {
+ pr_err(" Failed to initialize HIQ\n");
+ pr_err("Kernel queue test failed\n");
+ return;
+ }
retval = kq->ops.acquire_packet_buffer(kq, 5, &buffer);
- BUG_ON(retval != 0);
+ if (unlikely(retval != 0)) {
+ pr_err(" Failed to acquire packet buffer\n");
+ pr_err("Kernel queue test failed\n");
+ return;
+ }
for (i = 0; i < 5; i++)
buffer[i] = kq->nop_packet;
kq->ops.submit_packet(kq);
- pr_err("amdkfd: ending kernel queue test\n");
+ pr_err("Ending kernel queue test\n");
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_module.c b/drivers/gpu/drm/amd/amdkfd/kfd_module.c
index 850a562..0d73bea 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_module.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_module.c
@@ -61,7 +61,8 @@ MODULE_PARM_DESC(send_sigterm,
static int amdkfd_init_completed;
-int kgd2kfd_init(unsigned interface_version, const struct kgd2kfd_calls **g2f)
+int kgd2kfd_init(unsigned int interface_version,
+ const struct kgd2kfd_calls **g2f)
{
if (!amdkfd_init_completed)
return -EPROBE_DEFER;
@@ -90,7 +91,7 @@ static int __init kfd_module_init(void)
/* Verify module parameters */
if ((sched_policy < KFD_SCHED_POLICY_HWS) ||
(sched_policy > KFD_SCHED_POLICY_NO_HWS)) {
- pr_err("kfd: sched_policy has invalid value\n");
+ pr_err("sched_policy has invalid value\n");
return -1;
}
@@ -98,13 +99,13 @@ static int __init kfd_module_init(void)
if ((max_num_of_queues_per_device < 1) ||
(max_num_of_queues_per_device >
KFD_MAX_NUM_OF_QUEUES_PER_DEVICE)) {
- pr_err("kfd: max_num_of_queues_per_device must be between 1 to KFD_MAX_NUM_OF_QUEUES_PER_DEVICE\n");
+ pr_err("max_num_of_queues_per_device must be between 1 to KFD_MAX_NUM_OF_QUEUES_PER_DEVICE\n");
return -1;
}
err = kfd_pasid_init();
if (err < 0)
- goto err_pasid;
+ return err;
err = kfd_chardev_init();
if (err < 0)
@@ -126,7 +127,6 @@ err_topology:
kfd_chardev_exit();
err_ioctl:
kfd_pasid_exit();
-err_pasid:
return err;
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
index 213a71e..1f3a6ba 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
@@ -67,7 +67,8 @@ struct mqd_manager {
int (*load_mqd)(struct mqd_manager *mm, void *mqd,
uint32_t pipe_id, uint32_t queue_id,
- uint32_t __user *wptr);
+ struct queue_properties *p,
+ struct mm_struct *mms);
int (*update_mqd)(struct mqd_manager *mm, void *mqd,
struct queue_properties *q);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
index 6acc431..44ffd23 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
@@ -44,10 +44,6 @@ static int init_mqd(struct mqd_manager *mm, void **mqd,
struct cik_mqd *m;
int retval;
- BUG_ON(!mm || !q || !mqd);
-
- pr_debug("kfd: In func %s\n", __func__);
-
retval = kfd_gtt_sa_allocate(mm->dev, sizeof(struct cik_mqd),
mqd_mem_obj);
@@ -101,7 +97,7 @@ static int init_mqd(struct mqd_manager *mm, void **mqd,
m->cp_hqd_iq_rptr = AQL_ENABLE;
*mqd = m;
- if (gart_addr != NULL)
+ if (gart_addr)
*gart_addr = addr;
retval = mm->update_mqd(mm, m, q);
@@ -115,8 +111,6 @@ static int init_mqd_sdma(struct mqd_manager *mm, void **mqd,
int retval;
struct cik_sdma_rlc_registers *m;
- BUG_ON(!mm || !mqd || !mqd_mem_obj);
-
retval = kfd_gtt_sa_allocate(mm->dev,
sizeof(struct cik_sdma_rlc_registers),
mqd_mem_obj);
@@ -129,7 +123,7 @@ static int init_mqd_sdma(struct mqd_manager *mm, void **mqd,
memset(m, 0, sizeof(struct cik_sdma_rlc_registers));
*mqd = m;
- if (gart_addr != NULL)
+ if (gart_addr)
*gart_addr = (*mqd_mem_obj)->gpu_addr;
retval = mm->update_mqd(mm, m, q);
@@ -140,27 +134,31 @@ static int init_mqd_sdma(struct mqd_manager *mm, void **mqd,
static void uninit_mqd(struct mqd_manager *mm, void *mqd,
struct kfd_mem_obj *mqd_mem_obj)
{
- BUG_ON(!mm || !mqd);
kfd_gtt_sa_free(mm->dev, mqd_mem_obj);
}
static void uninit_mqd_sdma(struct mqd_manager *mm, void *mqd,
struct kfd_mem_obj *mqd_mem_obj)
{
- BUG_ON(!mm || !mqd);
kfd_gtt_sa_free(mm->dev, mqd_mem_obj);
}
static int load_mqd(struct mqd_manager *mm, void *mqd, uint32_t pipe_id,
- uint32_t queue_id, uint32_t __user *wptr)
+ uint32_t queue_id, struct queue_properties *p,
+ struct mm_struct *mms)
{
- return mm->dev->kfd2kgd->hqd_load
- (mm->dev->kgd, mqd, pipe_id, queue_id, wptr);
+ /* AQL write pointer counts in 64B packets, PM4/CP counts in dwords. */
+ uint32_t wptr_shift = (p->format == KFD_QUEUE_FORMAT_AQL ? 4 : 0);
+ uint32_t wptr_mask = (uint32_t)((p->queue_size / sizeof(uint32_t)) - 1);
+
+ return mm->dev->kfd2kgd->hqd_load(mm->dev->kgd, mqd, pipe_id, queue_id,
+ (uint32_t __user *)p->write_ptr,
+ wptr_shift, wptr_mask, mms);
}
static int load_mqd_sdma(struct mqd_manager *mm, void *mqd,
- uint32_t pipe_id, uint32_t queue_id,
- uint32_t __user *wptr)
+ uint32_t pipe_id, uint32_t queue_id,
+ struct queue_properties *p, struct mm_struct *mms)
{
return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->kgd, mqd);
}
@@ -170,10 +168,6 @@ static int update_mqd(struct mqd_manager *mm, void *mqd,
{
struct cik_mqd *m;
- BUG_ON(!mm || !q || !mqd);
-
- pr_debug("kfd: In func %s\n", __func__);
-
m = get_mqd(mqd);
m->cp_hqd_pq_control = DEFAULT_RPTR_BLOCK_SIZE |
DEFAULT_MIN_AVAIL_SIZE | PQ_ATC_EN;
@@ -188,21 +182,17 @@ static int update_mqd(struct mqd_manager *mm, void *mqd,
m->cp_hqd_pq_base_hi = upper_32_bits((uint64_t)q->queue_address >> 8);
m->cp_hqd_pq_rptr_report_addr_lo = lower_32_bits((uint64_t)q->read_ptr);
m->cp_hqd_pq_rptr_report_addr_hi = upper_32_bits((uint64_t)q->read_ptr);
- m->cp_hqd_pq_doorbell_control = DOORBELL_EN |
- DOORBELL_OFFSET(q->doorbell_off);
+ m->cp_hqd_pq_doorbell_control = DOORBELL_OFFSET(q->doorbell_off);
m->cp_hqd_vmid = q->vmid;
- if (q->format == KFD_QUEUE_FORMAT_AQL) {
+ if (q->format == KFD_QUEUE_FORMAT_AQL)
m->cp_hqd_pq_control |= NO_UPDATE_RPTR;
- }
- m->cp_hqd_active = 0;
q->is_active = false;
if (q->queue_size > 0 &&
q->queue_address != 0 &&
q->queue_percent > 0) {
- m->cp_hqd_active = 1;
q->is_active = true;
}
@@ -214,8 +204,6 @@ static int update_mqd_sdma(struct mqd_manager *mm, void *mqd,
{
struct cik_sdma_rlc_registers *m;
- BUG_ON(!mm || !mqd || !q);
-
m = get_sdma_mqd(mqd);
m->sdma_rlc_rb_cntl = ffs(q->queue_size / sizeof(unsigned int)) <<
SDMA0_RLC0_RB_CNTL__RB_SIZE__SHIFT |
@@ -254,7 +242,7 @@ static int destroy_mqd(struct mqd_manager *mm, void *mqd,
unsigned int timeout, uint32_t pipe_id,
uint32_t queue_id)
{
- return mm->dev->kfd2kgd->hqd_destroy(mm->dev->kgd, type, timeout,
+ return mm->dev->kfd2kgd->hqd_destroy(mm->dev->kgd, mqd, type, timeout,
pipe_id, queue_id);
}
@@ -301,10 +289,6 @@ static int init_mqd_hiq(struct mqd_manager *mm, void **mqd,
struct cik_mqd *m;
int retval;
- BUG_ON(!mm || !q || !mqd || !mqd_mem_obj);
-
- pr_debug("kfd: In func %s\n", __func__);
-
retval = kfd_gtt_sa_allocate(mm->dev, sizeof(struct cik_mqd),
mqd_mem_obj);
@@ -359,10 +343,6 @@ static int update_mqd_hiq(struct mqd_manager *mm, void *mqd,
{
struct cik_mqd *m;
- BUG_ON(!mm || !q || !mqd);
-
- pr_debug("kfd: In func %s\n", __func__);
-
m = get_mqd(mqd);
m->cp_hqd_pq_control = DEFAULT_RPTR_BLOCK_SIZE |
DEFAULT_MIN_AVAIL_SIZE |
@@ -400,8 +380,6 @@ struct cik_sdma_rlc_registers *get_sdma_mqd(void *mqd)
{
struct cik_sdma_rlc_registers *m;
- BUG_ON(!mqd);
-
m = (struct cik_sdma_rlc_registers *)mqd;
return m;
@@ -412,12 +390,10 @@ struct mqd_manager *mqd_manager_init_cik(enum KFD_MQD_TYPE type,
{
struct mqd_manager *mqd;
- BUG_ON(!dev);
- BUG_ON(type >= KFD_MQD_TYPE_MAX);
-
- pr_debug("kfd: In func %s\n", __func__);
+ if (WARN_ON(type >= KFD_MQD_TYPE_MAX))
+ return NULL;
- mqd = kzalloc(sizeof(struct mqd_manager), GFP_KERNEL);
+ mqd = kzalloc(sizeof(*mqd), GFP_KERNEL);
if (!mqd)
return NULL;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
index a9b9882..73cbfe1 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
@@ -85,7 +85,7 @@ static int init_mqd(struct mqd_manager *mm, void **mqd,
m->cp_hqd_iq_rptr = 1;
*mqd = m;
- if (gart_addr != NULL)
+ if (gart_addr)
*gart_addr = addr;
retval = mm->update_mqd(mm, m, q);
@@ -94,10 +94,15 @@ static int init_mqd(struct mqd_manager *mm, void **mqd,
static int load_mqd(struct mqd_manager *mm, void *mqd,
uint32_t pipe_id, uint32_t queue_id,
- uint32_t __user *wptr)
+ struct queue_properties *p, struct mm_struct *mms)
{
- return mm->dev->kfd2kgd->hqd_load
- (mm->dev->kgd, mqd, pipe_id, queue_id, wptr);
+ /* AQL write pointer counts in 64B packets, PM4/CP counts in dwords. */
+ uint32_t wptr_shift = (p->format == KFD_QUEUE_FORMAT_AQL ? 4 : 0);
+ uint32_t wptr_mask = (uint32_t)((p->queue_size / sizeof(uint32_t)) - 1);
+
+ return mm->dev->kfd2kgd->hqd_load(mm->dev->kgd, mqd, pipe_id, queue_id,
+ (uint32_t __user *)p->write_ptr,
+ wptr_shift, wptr_mask, mms);
}
static int __update_mqd(struct mqd_manager *mm, void *mqd,
@@ -106,10 +111,6 @@ static int __update_mqd(struct mqd_manager *mm, void *mqd,
{
struct vi_mqd *m;
- BUG_ON(!mm || !q || !mqd);
-
- pr_debug("kfd: In func %s\n", __func__);
-
m = get_mqd(mqd);
m->cp_hqd_pq_control = 5 << CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE__SHIFT |
@@ -117,7 +118,7 @@ static int __update_mqd(struct mqd_manager *mm, void *mqd,
mtype << CP_HQD_PQ_CONTROL__MTYPE__SHIFT;
m->cp_hqd_pq_control |=
ffs(q->queue_size / sizeof(unsigned int)) - 1 - 1;
- pr_debug("kfd: cp_hqd_pq_control 0x%x\n", m->cp_hqd_pq_control);
+ pr_debug("cp_hqd_pq_control 0x%x\n", m->cp_hqd_pq_control);
m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8);
m->cp_hqd_pq_base_hi = upper_32_bits((uint64_t)q->queue_address >> 8);
@@ -126,10 +127,9 @@ static int __update_mqd(struct mqd_manager *mm, void *mqd,
m->cp_hqd_pq_rptr_report_addr_hi = upper_32_bits((uint64_t)q->read_ptr);
m->cp_hqd_pq_doorbell_control =
- 1 << CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_EN__SHIFT |
q->doorbell_off <<
CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET__SHIFT;
- pr_debug("kfd: cp_hqd_pq_doorbell_control 0x%x\n",
+ pr_debug("cp_hqd_pq_doorbell_control 0x%x\n",
m->cp_hqd_pq_doorbell_control);
m->cp_hqd_eop_control = atc_bit << CP_HQD_EOP_CONTROL__EOP_ATC__SHIFT |
@@ -139,8 +139,15 @@ static int __update_mqd(struct mqd_manager *mm, void *mqd,
3 << CP_HQD_IB_CONTROL__MIN_IB_AVAIL_SIZE__SHIFT |
mtype << CP_HQD_IB_CONTROL__MTYPE__SHIFT;
- m->cp_hqd_eop_control |=
- ffs(q->eop_ring_buffer_size / sizeof(unsigned int)) - 1 - 1;
+ /*
+ * HW does not clamp this field correctly. Maximum EOP queue size
+ * is constrained by per-SE EOP done signal count, which is 8-bit.
+ * Limit is 0xFF EOP entries (= 0x7F8 dwords). CP will not submit
+ * more than (EOP entry count - 1) so a queue size of 0x800 dwords
+ * is safe, giving a maximum field value of 0xA.
+ */
+ m->cp_hqd_eop_control |= min(0xA,
+ ffs(q->eop_ring_buffer_size / sizeof(unsigned int)) - 1 - 1);
m->cp_hqd_eop_base_addr_lo =
lower_32_bits(q->eop_ring_buffer_address >> 8);
m->cp_hqd_eop_base_addr_hi =
@@ -156,12 +163,10 @@ static int __update_mqd(struct mqd_manager *mm, void *mqd,
2 << CP_HQD_PQ_CONTROL__SLOT_BASED_WPTR__SHIFT;
}
- m->cp_hqd_active = 0;
q->is_active = false;
if (q->queue_size > 0 &&
q->queue_address != 0 &&
q->queue_percent > 0) {
- m->cp_hqd_active = 1;
q->is_active = true;
}
@@ -181,14 +186,13 @@ static int destroy_mqd(struct mqd_manager *mm, void *mqd,
uint32_t queue_id)
{
return mm->dev->kfd2kgd->hqd_destroy
- (mm->dev->kgd, type, timeout,
+ (mm->dev->kgd, mqd, type, timeout,
pipe_id, queue_id);
}
static void uninit_mqd(struct mqd_manager *mm, void *mqd,
struct kfd_mem_obj *mqd_mem_obj)
{
- BUG_ON(!mm || !mqd);
kfd_gtt_sa_free(mm->dev, mqd_mem_obj);
}
@@ -238,12 +242,10 @@ struct mqd_manager *mqd_manager_init_vi(enum KFD_MQD_TYPE type,
{
struct mqd_manager *mqd;
- BUG_ON(!dev);
- BUG_ON(type >= KFD_MQD_TYPE_MAX);
-
- pr_debug("kfd: In func %s\n", __func__);
+ if (WARN_ON(type >= KFD_MQD_TYPE_MAX))
+ return NULL;
- mqd = kzalloc(sizeof(struct mqd_manager), GFP_KERNEL);
+ mqd = kzalloc(sizeof(*mqd), GFP_KERNEL);
if (!mqd)
return NULL;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
index 7131998..1d31260 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
@@ -26,7 +26,6 @@
#include "kfd_device_queue_manager.h"
#include "kfd_kernel_queue.h"
#include "kfd_priv.h"
-#include "kfd_pm4_headers.h"
#include "kfd_pm4_headers_vi.h"
#include "kfd_pm4_opcodes.h"
@@ -35,7 +34,8 @@ static inline void inc_wptr(unsigned int *wptr, unsigned int increment_bytes,
{
unsigned int temp = *wptr + increment_bytes / sizeof(uint32_t);
- BUG_ON((temp * sizeof(uint32_t)) > buffer_size_bytes);
+ WARN((temp * sizeof(uint32_t)) > buffer_size_bytes,
+ "Runlist IB overflow");
*wptr = temp;
}
@@ -43,12 +43,12 @@ static unsigned int build_pm4_header(unsigned int opcode, size_t packet_size)
{
union PM4_MES_TYPE_3_HEADER header;
- header.u32all = 0;
+ header.u32All = 0;
header.opcode = opcode;
header.count = packet_size/sizeof(uint32_t) - 2;
header.type = PM4_TYPE_3;
- return header.u32all;
+ return header.u32All;
}
static void pm_calc_rlib_size(struct packet_manager *pm,
@@ -58,8 +58,6 @@ static void pm_calc_rlib_size(struct packet_manager *pm,
unsigned int process_count, queue_count;
unsigned int map_queue_size;
- BUG_ON(!pm || !rlib_size || !over_subscription);
-
process_count = pm->dqm->processes_count;
queue_count = pm->dqm->queue_count;
@@ -67,15 +65,12 @@ static void pm_calc_rlib_size(struct packet_manager *pm,
*over_subscription = false;
if ((process_count > 1) || queue_count > get_queues_num(pm->dqm)) {
*over_subscription = true;
- pr_debug("kfd: over subscribed runlist\n");
+ pr_debug("Over subscribed runlist\n");
}
- map_queue_size =
- (pm->dqm->dev->device_info->asic_family == CHIP_CARRIZO) ?
- sizeof(struct pm4_mes_map_queues) :
- sizeof(struct pm4_map_queues);
+ map_queue_size = sizeof(struct pm4_mes_map_queues);
/* calculate run list ib allocation size */
- *rlib_size = process_count * sizeof(struct pm4_map_process) +
+ *rlib_size = process_count * sizeof(struct pm4_mes_map_process) +
queue_count * map_queue_size;
/*
@@ -83,9 +78,9 @@ static void pm_calc_rlib_size(struct packet_manager *pm,
* when over subscription
*/
if (*over_subscription)
- *rlib_size += sizeof(struct pm4_runlist);
+ *rlib_size += sizeof(struct pm4_mes_runlist);
- pr_debug("kfd: runlist ib size %d\n", *rlib_size);
+ pr_debug("runlist ib size %d\n", *rlib_size);
}
static int pm_allocate_runlist_ib(struct packet_manager *pm,
@@ -96,17 +91,16 @@ static int pm_allocate_runlist_ib(struct packet_manager *pm,
{
int retval;
- BUG_ON(!pm);
- BUG_ON(pm->allocated);
- BUG_ON(is_over_subscription == NULL);
+ if (WARN_ON(pm->allocated))
+ return -EINVAL;
pm_calc_rlib_size(pm, rl_buffer_size, is_over_subscription);
retval = kfd_gtt_sa_allocate(pm->dqm->dev, *rl_buffer_size,
&pm->ib_buffer_obj);
- if (retval != 0) {
- pr_err("kfd: failed to allocate runlist IB\n");
+ if (retval) {
+ pr_err("Failed to allocate runlist IB\n");
return retval;
}
@@ -121,15 +115,16 @@ static int pm_allocate_runlist_ib(struct packet_manager *pm,
static int pm_create_runlist(struct packet_manager *pm, uint32_t *buffer,
uint64_t ib, size_t ib_size_in_dwords, bool chain)
{
- struct pm4_runlist *packet;
+ struct pm4_mes_runlist *packet;
- BUG_ON(!pm || !buffer || !ib);
+ if (WARN_ON(!ib))
+ return -EFAULT;
- packet = (struct pm4_runlist *)buffer;
+ packet = (struct pm4_mes_runlist *)buffer;
- memset(buffer, 0, sizeof(struct pm4_runlist));
- packet->header.u32all = build_pm4_header(IT_RUN_LIST,
- sizeof(struct pm4_runlist));
+ memset(buffer, 0, sizeof(struct pm4_mes_runlist));
+ packet->header.u32All = build_pm4_header(IT_RUN_LIST,
+ sizeof(struct pm4_mes_runlist));
packet->bitfields4.ib_size = ib_size_in_dwords;
packet->bitfields4.chain = chain ? 1 : 0;
@@ -144,20 +139,16 @@ static int pm_create_runlist(struct packet_manager *pm, uint32_t *buffer,
static int pm_create_map_process(struct packet_manager *pm, uint32_t *buffer,
struct qcm_process_device *qpd)
{
- struct pm4_map_process *packet;
+ struct pm4_mes_map_process *packet;
struct queue *cur;
uint32_t num_queues;
- BUG_ON(!pm || !buffer || !qpd);
-
- packet = (struct pm4_map_process *)buffer;
-
- pr_debug("kfd: In func %s\n", __func__);
+ packet = (struct pm4_mes_map_process *)buffer;
- memset(buffer, 0, sizeof(struct pm4_map_process));
+ memset(buffer, 0, sizeof(struct pm4_mes_map_process));
- packet->header.u32all = build_pm4_header(IT_MAP_PROCESS,
- sizeof(struct pm4_map_process));
+ packet->header.u32All = build_pm4_header(IT_MAP_PROCESS,
+ sizeof(struct pm4_mes_map_process));
packet->bitfields2.diq_enable = (qpd->is_debug) ? 1 : 0;
packet->bitfields2.process_quantum = 1;
packet->bitfields2.pasid = qpd->pqm->process->pasid;
@@ -175,27 +166,26 @@ static int pm_create_map_process(struct packet_manager *pm, uint32_t *buffer,
packet->sh_mem_ape1_base = qpd->sh_mem_ape1_base;
packet->sh_mem_ape1_limit = qpd->sh_mem_ape1_limit;
+ /* TODO: scratch support */
+ packet->sh_hidden_private_base_vmid = 0;
+
packet->gds_addr_lo = lower_32_bits(qpd->gds_context_area);
packet->gds_addr_hi = upper_32_bits(qpd->gds_context_area);
return 0;
}
-static int pm_create_map_queue_vi(struct packet_manager *pm, uint32_t *buffer,
+static int pm_create_map_queue(struct packet_manager *pm, uint32_t *buffer,
struct queue *q, bool is_static)
{
struct pm4_mes_map_queues *packet;
bool use_static = is_static;
- BUG_ON(!pm || !buffer || !q);
-
- pr_debug("kfd: In func %s\n", __func__);
-
packet = (struct pm4_mes_map_queues *)buffer;
- memset(buffer, 0, sizeof(struct pm4_map_queues));
+ memset(buffer, 0, sizeof(struct pm4_mes_map_queues));
- packet->header.u32all = build_pm4_header(IT_MAP_QUEUES,
- sizeof(struct pm4_map_queues));
+ packet->header.u32All = build_pm4_header(IT_MAP_QUEUES,
+ sizeof(struct pm4_mes_map_queues));
packet->bitfields2.alloc_format =
alloc_format__mes_map_queues__one_per_pipe_vi;
packet->bitfields2.num_queues = 1;
@@ -223,10 +213,8 @@ static int pm_create_map_queue_vi(struct packet_manager *pm, uint32_t *buffer,
use_static = false; /* no static queues under SDMA */
break;
default:
- pr_err("kfd: in %s queue type %d\n", __func__,
- q->properties.type);
- BUG();
- break;
+ WARN(1, "queue type %d", q->properties.type);
+ return -EINVAL;
}
packet->bitfields3.doorbell_offset =
q->properties.doorbell_off;
@@ -246,68 +234,6 @@ static int pm_create_map_queue_vi(struct packet_manager *pm, uint32_t *buffer,
return 0;
}
-static int pm_create_map_queue(struct packet_manager *pm, uint32_t *buffer,
- struct queue *q, bool is_static)
-{
- struct pm4_map_queues *packet;
- bool use_static = is_static;
-
- BUG_ON(!pm || !buffer || !q);
-
- pr_debug("kfd: In func %s\n", __func__);
-
- packet = (struct pm4_map_queues *)buffer;
- memset(buffer, 0, sizeof(struct pm4_map_queues));
-
- packet->header.u32all = build_pm4_header(IT_MAP_QUEUES,
- sizeof(struct pm4_map_queues));
- packet->bitfields2.alloc_format =
- alloc_format__mes_map_queues__one_per_pipe;
- packet->bitfields2.num_queues = 1;
- packet->bitfields2.queue_sel =
- queue_sel__mes_map_queues__map_to_hws_determined_queue_slots;
-
- packet->bitfields2.vidmem = (q->properties.is_interop) ?
- vidmem__mes_map_queues__uses_video_memory :
- vidmem__mes_map_queues__uses_no_video_memory;
-
- switch (q->properties.type) {
- case KFD_QUEUE_TYPE_COMPUTE:
- case KFD_QUEUE_TYPE_DIQ:
- packet->bitfields2.engine_sel =
- engine_sel__mes_map_queues__compute;
- break;
- case KFD_QUEUE_TYPE_SDMA:
- packet->bitfields2.engine_sel =
- engine_sel__mes_map_queues__sdma0;
- use_static = false; /* no static queues under SDMA */
- break;
- default:
- BUG();
- break;
- }
-
- packet->mes_map_queues_ordinals[0].bitfields3.doorbell_offset =
- q->properties.doorbell_off;
-
- packet->mes_map_queues_ordinals[0].bitfields3.is_static =
- (use_static) ? 1 : 0;
-
- packet->mes_map_queues_ordinals[0].mqd_addr_lo =
- lower_32_bits(q->gart_mqd_addr);
-
- packet->mes_map_queues_ordinals[0].mqd_addr_hi =
- upper_32_bits(q->gart_mqd_addr);
-
- packet->mes_map_queues_ordinals[0].wptr_addr_lo =
- lower_32_bits((uint64_t)q->properties.write_ptr);
-
- packet->mes_map_queues_ordinals[0].wptr_addr_hi =
- upper_32_bits((uint64_t)q->properties.write_ptr);
-
- return 0;
-}
-
static int pm_create_runlist_ib(struct packet_manager *pm,
struct list_head *queues,
uint64_t *rl_gpu_addr,
@@ -322,19 +248,16 @@ static int pm_create_runlist_ib(struct packet_manager *pm,
struct kernel_queue *kq;
bool is_over_subscription;
- BUG_ON(!pm || !queues || !rl_size_bytes || !rl_gpu_addr);
-
rl_wptr = retval = proccesses_mapped = 0;
retval = pm_allocate_runlist_ib(pm, &rl_buffer, rl_gpu_addr,
&alloc_size_bytes, &is_over_subscription);
- if (retval != 0)
+ if (retval)
return retval;
*rl_size_bytes = alloc_size_bytes;
- pr_debug("kfd: In func %s\n", __func__);
- pr_debug("kfd: building runlist ib process count: %d queues count %d\n",
+ pr_debug("Building runlist ib process count: %d queues count %d\n",
pm->dqm->processes_count, pm->dqm->queue_count);
/* build the run list ib packet */
@@ -342,42 +265,35 @@ static int pm_create_runlist_ib(struct packet_manager *pm,
qpd = cur->qpd;
/* build map process packet */
if (proccesses_mapped >= pm->dqm->processes_count) {
- pr_debug("kfd: not enough space left in runlist IB\n");
+ pr_debug("Not enough space left in runlist IB\n");
pm_release_ib(pm);
return -ENOMEM;
}
retval = pm_create_map_process(pm, &rl_buffer[rl_wptr], qpd);
- if (retval != 0)
+ if (retval)
return retval;
proccesses_mapped++;
- inc_wptr(&rl_wptr, sizeof(struct pm4_map_process),
+ inc_wptr(&rl_wptr, sizeof(struct pm4_mes_map_process),
alloc_size_bytes);
list_for_each_entry(kq, &qpd->priv_queue_list, list) {
if (!kq->queue->properties.is_active)
continue;
- pr_debug("kfd: static_queue, mapping kernel q %d, is debug status %d\n",
+ pr_debug("static_queue, mapping kernel q %d, is debug status %d\n",
kq->queue->queue, qpd->is_debug);
- if (pm->dqm->dev->device_info->asic_family ==
- CHIP_CARRIZO)
- retval = pm_create_map_queue_vi(pm,
- &rl_buffer[rl_wptr],
- kq->queue,
- qpd->is_debug);
- else
- retval = pm_create_map_queue(pm,
+ retval = pm_create_map_queue(pm,
&rl_buffer[rl_wptr],
kq->queue,
qpd->is_debug);
- if (retval != 0)
+ if (retval)
return retval;
inc_wptr(&rl_wptr,
- sizeof(struct pm4_map_queues),
+ sizeof(struct pm4_mes_map_queues),
alloc_size_bytes);
}
@@ -385,51 +301,44 @@ static int pm_create_runlist_ib(struct packet_manager *pm,
if (!q->properties.is_active)
continue;
- pr_debug("kfd: static_queue, mapping user queue %d, is debug status %d\n",
+ pr_debug("static_queue, mapping user queue %d, is debug status %d\n",
q->queue, qpd->is_debug);
- if (pm->dqm->dev->device_info->asic_family ==
- CHIP_CARRIZO)
- retval = pm_create_map_queue_vi(pm,
- &rl_buffer[rl_wptr],
- q,
- qpd->is_debug);
- else
- retval = pm_create_map_queue(pm,
+ retval = pm_create_map_queue(pm,
&rl_buffer[rl_wptr],
q,
qpd->is_debug);
- if (retval != 0)
+ if (retval)
return retval;
inc_wptr(&rl_wptr,
- sizeof(struct pm4_map_queues),
+ sizeof(struct pm4_mes_map_queues),
alloc_size_bytes);
}
}
- pr_debug("kfd: finished map process and queues to runlist\n");
+ pr_debug("Finished map process and queues to runlist\n");
if (is_over_subscription)
- pm_create_runlist(pm, &rl_buffer[rl_wptr], *rl_gpu_addr,
- alloc_size_bytes / sizeof(uint32_t), true);
+ retval = pm_create_runlist(pm, &rl_buffer[rl_wptr],
+ *rl_gpu_addr,
+ alloc_size_bytes / sizeof(uint32_t),
+ true);
for (i = 0; i < alloc_size_bytes / sizeof(uint32_t); i++)
pr_debug("0x%2X ", rl_buffer[i]);
pr_debug("\n");
- return 0;
+ return retval;
}
int pm_init(struct packet_manager *pm, struct device_queue_manager *dqm)
{
- BUG_ON(!dqm);
-
pm->dqm = dqm;
mutex_init(&pm->lock);
pm->priv_queue = kernel_queue_init(dqm->dev, KFD_QUEUE_TYPE_HIQ);
- if (pm->priv_queue == NULL) {
+ if (!pm->priv_queue) {
mutex_destroy(&pm->lock);
return -ENOMEM;
}
@@ -440,8 +349,6 @@ int pm_init(struct packet_manager *pm, struct device_queue_manager *dqm)
void pm_uninit(struct packet_manager *pm)
{
- BUG_ON(!pm);
-
mutex_destroy(&pm->lock);
kernel_queue_uninit(pm->priv_queue);
}
@@ -449,25 +356,22 @@ void pm_uninit(struct packet_manager *pm)
int pm_send_set_resources(struct packet_manager *pm,
struct scheduling_resources *res)
{
- struct pm4_set_resources *packet;
-
- BUG_ON(!pm || !res);
-
- pr_debug("kfd: In func %s\n", __func__);
+ struct pm4_mes_set_resources *packet;
+ int retval = 0;
mutex_lock(&pm->lock);
pm->priv_queue->ops.acquire_packet_buffer(pm->priv_queue,
sizeof(*packet) / sizeof(uint32_t),
- (unsigned int **)&packet);
- if (packet == NULL) {
- mutex_unlock(&pm->lock);
- pr_err("kfd: failed to allocate buffer on kernel queue\n");
- return -ENOMEM;
+ (unsigned int **)&packet);
+ if (!packet) {
+ pr_err("Failed to allocate buffer on kernel queue\n");
+ retval = -ENOMEM;
+ goto out;
}
- memset(packet, 0, sizeof(struct pm4_set_resources));
- packet->header.u32all = build_pm4_header(IT_SET_RESOURCES,
- sizeof(struct pm4_set_resources));
+ memset(packet, 0, sizeof(struct pm4_mes_set_resources));
+ packet->header.u32All = build_pm4_header(IT_SET_RESOURCES,
+ sizeof(struct pm4_mes_set_resources));
packet->bitfields2.queue_type =
queue_type__mes_set_resources__hsa_interface_queue_hiq;
@@ -485,9 +389,10 @@ int pm_send_set_resources(struct packet_manager *pm,
pm->priv_queue->ops.submit_packet(pm->priv_queue);
+out:
mutex_unlock(&pm->lock);
- return 0;
+ return retval;
}
int pm_send_runlist(struct packet_manager *pm, struct list_head *dqm_queues)
@@ -497,26 +402,24 @@ int pm_send_runlist(struct packet_manager *pm, struct list_head *dqm_queues)
size_t rl_ib_size, packet_size_dwords;
int retval;
- BUG_ON(!pm || !dqm_queues);
-
retval = pm_create_runlist_ib(pm, dqm_queues, &rl_gpu_ib_addr,
&rl_ib_size);
- if (retval != 0)
+ if (retval)
goto fail_create_runlist_ib;
- pr_debug("kfd: runlist IB address: 0x%llX\n", rl_gpu_ib_addr);
+ pr_debug("runlist IB address: 0x%llX\n", rl_gpu_ib_addr);
- packet_size_dwords = sizeof(struct pm4_runlist) / sizeof(uint32_t);
+ packet_size_dwords = sizeof(struct pm4_mes_runlist) / sizeof(uint32_t);
mutex_lock(&pm->lock);
retval = pm->priv_queue->ops.acquire_packet_buffer(pm->priv_queue,
packet_size_dwords, &rl_buffer);
- if (retval != 0)
+ if (retval)
goto fail_acquire_packet_buffer;
retval = pm_create_runlist(pm, rl_buffer, rl_gpu_ib_addr,
rl_ib_size / sizeof(uint32_t), false);
- if (retval != 0)
+ if (retval)
goto fail_create_runlist;
pm->priv_queue->ops.submit_packet(pm->priv_queue);
@@ -530,8 +433,7 @@ fail_create_runlist:
fail_acquire_packet_buffer:
mutex_unlock(&pm->lock);
fail_create_runlist_ib:
- if (pm->allocated)
- pm_release_ib(pm);
+ pm_release_ib(pm);
return retval;
}
@@ -539,20 +441,21 @@ int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address,
uint32_t fence_value)
{
int retval;
- struct pm4_query_status *packet;
+ struct pm4_mes_query_status *packet;
- BUG_ON(!pm || !fence_address);
+ if (WARN_ON(!fence_address))
+ return -EFAULT;
mutex_lock(&pm->lock);
retval = pm->priv_queue->ops.acquire_packet_buffer(
pm->priv_queue,
- sizeof(struct pm4_query_status) / sizeof(uint32_t),
+ sizeof(struct pm4_mes_query_status) / sizeof(uint32_t),
(unsigned int **)&packet);
- if (retval != 0)
+ if (retval)
goto fail_acquire_packet_buffer;
- packet->header.u32all = build_pm4_header(IT_QUERY_STATUS,
- sizeof(struct pm4_query_status));
+ packet->header.u32All = build_pm4_header(IT_QUERY_STATUS,
+ sizeof(struct pm4_mes_query_status));
packet->bitfields2.context_id = 0;
packet->bitfields2.interrupt_sel =
@@ -566,9 +469,6 @@ int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address,
packet->data_lo = lower_32_bits((uint64_t)fence_value);
pm->priv_queue->ops.submit_packet(pm->priv_queue);
- mutex_unlock(&pm->lock);
-
- return 0;
fail_acquire_packet_buffer:
mutex_unlock(&pm->lock);
@@ -582,24 +482,22 @@ int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type,
{
int retval;
uint32_t *buffer;
- struct pm4_unmap_queues *packet;
-
- BUG_ON(!pm);
+ struct pm4_mes_unmap_queues *packet;
mutex_lock(&pm->lock);
retval = pm->priv_queue->ops.acquire_packet_buffer(
pm->priv_queue,
- sizeof(struct pm4_unmap_queues) / sizeof(uint32_t),
+ sizeof(struct pm4_mes_unmap_queues) / sizeof(uint32_t),
&buffer);
- if (retval != 0)
+ if (retval)
goto err_acquire_packet_buffer;
- packet = (struct pm4_unmap_queues *)buffer;
- memset(buffer, 0, sizeof(struct pm4_unmap_queues));
- pr_debug("kfd: static_queue: unmapping queues: mode is %d , reset is %d , type is %d\n",
+ packet = (struct pm4_mes_unmap_queues *)buffer;
+ memset(buffer, 0, sizeof(struct pm4_mes_unmap_queues));
+ pr_debug("static_queue: unmapping queues: mode is %d , reset is %d , type is %d\n",
mode, reset, type);
- packet->header.u32all = build_pm4_header(IT_UNMAP_QUEUES,
- sizeof(struct pm4_unmap_queues));
+ packet->header.u32All = build_pm4_header(IT_UNMAP_QUEUES,
+ sizeof(struct pm4_mes_unmap_queues));
switch (type) {
case KFD_QUEUE_TYPE_COMPUTE:
case KFD_QUEUE_TYPE_DIQ:
@@ -611,8 +509,9 @@ int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type,
engine_sel__mes_unmap_queues__sdma0 + sdma_engine;
break;
default:
- BUG();
- break;
+ WARN(1, "queue type %d", type);
+ retval = -EINVAL;
+ goto err_invalid;
}
if (reset)
@@ -636,16 +535,17 @@ int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type,
break;
case KFD_PREEMPT_TYPE_FILTER_ALL_QUEUES:
packet->bitfields2.queue_sel =
- queue_sel__mes_unmap_queues__perform_request_on_all_active_queues;
+ queue_sel__mes_unmap_queues__unmap_all_queues;
break;
case KFD_PREEMPT_TYPE_FILTER_DYNAMIC_QUEUES:
/* in this case, we do not preempt static queues */
packet->bitfields2.queue_sel =
- queue_sel__mes_unmap_queues__perform_request_on_dynamic_queues_only;
+ queue_sel__mes_unmap_queues__unmap_all_non_static_queues;
break;
default:
- BUG();
- break;
+ WARN(1, "filter %d", mode);
+ retval = -EINVAL;
+ goto err_invalid;
}
pm->priv_queue->ops.submit_packet(pm->priv_queue);
@@ -653,6 +553,8 @@ int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type,
mutex_unlock(&pm->lock);
return 0;
+err_invalid:
+ pm->priv_queue->ops.rollback_packet(pm->priv_queue);
err_acquire_packet_buffer:
mutex_unlock(&pm->lock);
return retval;
@@ -660,8 +562,6 @@ err_acquire_packet_buffer:
void pm_release_ib(struct packet_manager *pm)
{
- BUG_ON(!pm);
-
mutex_lock(&pm->lock);
if (pm->allocated) {
kfd_gtt_sa_free(pm->dqm->dev, pm->ib_buffer_obj);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c b/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c
index 6cfe7f1..1e06de0 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c
@@ -32,7 +32,8 @@ int kfd_pasid_init(void)
{
pasid_limit = KFD_MAX_NUM_OF_PROCESSES;
- pasid_bitmap = kcalloc(BITS_TO_LONGS(pasid_limit), sizeof(long), GFP_KERNEL);
+ pasid_bitmap = kcalloc(BITS_TO_LONGS(pasid_limit), sizeof(long),
+ GFP_KERNEL);
if (!pasid_bitmap)
return -ENOMEM;
@@ -91,6 +92,6 @@ unsigned int kfd_pasid_alloc(void)
void kfd_pasid_free(unsigned int pasid)
{
- BUG_ON(pasid == 0 || pasid >= pasid_limit);
- clear_bit(pasid, pasid_bitmap);
+ if (!WARN_ON(pasid == 0 || pasid >= pasid_limit))
+ clear_bit(pasid, pasid_bitmap);
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h
index 5b393f3..e50f73d 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h
@@ -28,112 +28,19 @@
#define PM4_MES_HEADER_DEFINED
union PM4_MES_TYPE_3_HEADER {
struct {
- uint32_t reserved1:8; /* < reserved */
- uint32_t opcode:8; /* < IT opcode */
- uint32_t count:14; /* < number of DWORDs - 1
- * in the information body.
- */
- uint32_t type:2; /* < packet identifier.
- * It should be 3 for type 3 packets
- */
+ /* reserved */
+ uint32_t reserved1:8;
+ /* IT opcode */
+ uint32_t opcode:8;
+ /* number of DWORDs - 1 in the information body */
+ uint32_t count:14;
+ /* packet identifier. It should be 3 for type 3 packets */
+ uint32_t type:2;
};
uint32_t u32all;
};
#endif /* PM4_MES_HEADER_DEFINED */
-/* --------------------MES_SET_RESOURCES-------------------- */
-
-#ifndef PM4_MES_SET_RESOURCES_DEFINED
-#define PM4_MES_SET_RESOURCES_DEFINED
-enum set_resources_queue_type_enum {
- queue_type__mes_set_resources__kernel_interface_queue_kiq = 0,
- queue_type__mes_set_resources__hsa_interface_queue_hiq = 1,
- queue_type__mes_set_resources__hsa_debug_interface_queue = 4
-};
-
-struct pm4_set_resources {
- union {
- union PM4_MES_TYPE_3_HEADER header; /* header */
- uint32_t ordinal1;
- };
-
- union {
- struct {
- uint32_t vmid_mask:16;
- uint32_t unmap_latency:8;
- uint32_t reserved1:5;
- enum set_resources_queue_type_enum queue_type:3;
- } bitfields2;
- uint32_t ordinal2;
- };
-
- uint32_t queue_mask_lo;
- uint32_t queue_mask_hi;
- uint32_t gws_mask_lo;
- uint32_t gws_mask_hi;
-
- union {
- struct {
- uint32_t oac_mask:16;
- uint32_t reserved2:16;
- } bitfields7;
- uint32_t ordinal7;
- };
-
- union {
- struct {
- uint32_t gds_heap_base:6;
- uint32_t reserved3:5;
- uint32_t gds_heap_size:6;
- uint32_t reserved4:15;
- } bitfields8;
- uint32_t ordinal8;
- };
-
-};
-#endif
-
-/*--------------------MES_RUN_LIST-------------------- */
-
-#ifndef PM4_MES_RUN_LIST_DEFINED
-#define PM4_MES_RUN_LIST_DEFINED
-
-struct pm4_runlist {
- union {
- union PM4_MES_TYPE_3_HEADER header; /* header */
- uint32_t ordinal1;
- };
-
- union {
- struct {
- uint32_t reserved1:2;
- uint32_t ib_base_lo:30;
- } bitfields2;
- uint32_t ordinal2;
- };
-
- union {
- struct {
- uint32_t ib_base_hi:16;
- uint32_t reserved2:16;
- } bitfields3;
- uint32_t ordinal3;
- };
-
- union {
- struct {
- uint32_t ib_size:20;
- uint32_t chain:1;
- uint32_t offload_polling:1;
- uint32_t reserved3:1;
- uint32_t valid:1;
- uint32_t reserved4:8;
- } bitfields4;
- uint32_t ordinal4;
- };
-
-};
-#endif
/*--------------------MES_MAP_PROCESS-------------------- */
@@ -186,217 +93,58 @@ struct pm4_map_process {
};
#endif
-/*--------------------MES_MAP_QUEUES--------------------*/
-
-#ifndef PM4_MES_MAP_QUEUES_DEFINED
-#define PM4_MES_MAP_QUEUES_DEFINED
-enum map_queues_queue_sel_enum {
- queue_sel__mes_map_queues__map_to_specified_queue_slots = 0,
- queue_sel__mes_map_queues__map_to_hws_determined_queue_slots = 1,
- queue_sel__mes_map_queues__enable_process_queues = 2
-};
+#ifndef PM4_MES_MAP_PROCESS_DEFINED_KV_SCRATCH
+#define PM4_MES_MAP_PROCESS_DEFINED_KV_SCRATCH
-enum map_queues_vidmem_enum {
- vidmem__mes_map_queues__uses_no_video_memory = 0,
- vidmem__mes_map_queues__uses_video_memory = 1
-};
-
-enum map_queues_alloc_format_enum {
- alloc_format__mes_map_queues__one_per_pipe = 0,
- alloc_format__mes_map_queues__all_on_one_pipe = 1
-};
-
-enum map_queues_engine_sel_enum {
- engine_sel__mes_map_queues__compute = 0,
- engine_sel__mes_map_queues__sdma0 = 2,
- engine_sel__mes_map_queues__sdma1 = 3
-};
-
-struct pm4_map_queues {
+struct pm4_map_process_scratch_kv {
union {
- union PM4_MES_TYPE_3_HEADER header; /* header */
- uint32_t ordinal1;
- };
-
- union {
- struct {
- uint32_t reserved1:4;
- enum map_queues_queue_sel_enum queue_sel:2;
- uint32_t reserved2:2;
- uint32_t vmid:4;
- uint32_t reserved3:4;
- enum map_queues_vidmem_enum vidmem:2;
- uint32_t reserved4:6;
- enum map_queues_alloc_format_enum alloc_format:2;
- enum map_queues_engine_sel_enum engine_sel:3;
- uint32_t num_queues:3;
- } bitfields2;
- uint32_t ordinal2;
- };
-
- struct {
- union {
- struct {
- uint32_t is_static:1;
- uint32_t reserved5:1;
- uint32_t doorbell_offset:21;
- uint32_t reserved6:3;
- uint32_t queue:6;
- } bitfields3;
- uint32_t ordinal3;
- };
-
- uint32_t mqd_addr_lo;
- uint32_t mqd_addr_hi;
- uint32_t wptr_addr_lo;
- uint32_t wptr_addr_hi;
-
- } mes_map_queues_ordinals[1]; /* 1..N of these ordinal groups */
-
-};
-#endif
-
-/*--------------------MES_QUERY_STATUS--------------------*/
-
-#ifndef PM4_MES_QUERY_STATUS_DEFINED
-#define PM4_MES_QUERY_STATUS_DEFINED
-enum query_status_interrupt_sel_enum {
- interrupt_sel__mes_query_status__completion_status = 0,
- interrupt_sel__mes_query_status__process_status = 1,
- interrupt_sel__mes_query_status__queue_status = 2
-};
-
-enum query_status_command_enum {
- command__mes_query_status__interrupt_only = 0,
- command__mes_query_status__fence_only_immediate = 1,
- command__mes_query_status__fence_only_after_write_ack = 2,
- command__mes_query_status__fence_wait_for_write_ack_send_interrupt = 3
-};
-
-enum query_status_engine_sel_enum {
- engine_sel__mes_query_status__compute = 0,
- engine_sel__mes_query_status__sdma0_queue = 2,
- engine_sel__mes_query_status__sdma1_queue = 3
-};
-
-struct pm4_query_status {
- union {
- union PM4_MES_TYPE_3_HEADER header; /* header */
- uint32_t ordinal1;
- };
-
- union {
- struct {
- uint32_t context_id:28;
- enum query_status_interrupt_sel_enum interrupt_sel:2;
- enum query_status_command_enum command:2;
- } bitfields2;
- uint32_t ordinal2;
+ union PM4_MES_TYPE_3_HEADER header; /* header */
+ uint32_t ordinal1;
};
union {
struct {
uint32_t pasid:16;
- uint32_t reserved1:16;
- } bitfields3a;
- struct {
- uint32_t reserved2:2;
- uint32_t doorbell_offset:21;
- uint32_t reserved3:3;
- enum query_status_engine_sel_enum engine_sel:3;
- uint32_t reserved4:3;
- } bitfields3b;
- uint32_t ordinal3;
- };
-
- uint32_t addr_lo;
- uint32_t addr_hi;
- uint32_t data_lo;
- uint32_t data_hi;
-};
-#endif
-
-/*--------------------MES_UNMAP_QUEUES--------------------*/
-
-#ifndef PM4_MES_UNMAP_QUEUES_DEFINED
-#define PM4_MES_UNMAP_QUEUES_DEFINED
-enum unmap_queues_action_enum {
- action__mes_unmap_queues__preempt_queues = 0,
- action__mes_unmap_queues__reset_queues = 1,
- action__mes_unmap_queues__disable_process_queues = 2
-};
-
-enum unmap_queues_queue_sel_enum {
- queue_sel__mes_unmap_queues__perform_request_on_specified_queues = 0,
- queue_sel__mes_unmap_queues__perform_request_on_pasid_queues = 1,
- queue_sel__mes_unmap_queues__perform_request_on_all_active_queues = 2,
- queue_sel__mes_unmap_queues__perform_request_on_dynamic_queues_only = 3
-};
-
-enum unmap_queues_engine_sel_enum {
- engine_sel__mes_unmap_queues__compute = 0,
- engine_sel__mes_unmap_queues__sdma0 = 2,
- engine_sel__mes_unmap_queues__sdma1 = 3
-};
-
-struct pm4_unmap_queues {
- union {
- union PM4_MES_TYPE_3_HEADER header; /* header */
- uint32_t ordinal1;
- };
-
- union {
- struct {
- enum unmap_queues_action_enum action:2;
- uint32_t reserved1:2;
- enum unmap_queues_queue_sel_enum queue_sel:2;
- uint32_t reserved2:20;
- enum unmap_queues_engine_sel_enum engine_sel:3;
- uint32_t num_queues:3;
+ uint32_t reserved1:8;
+ uint32_t diq_enable:1;
+ uint32_t process_quantum:7;
} bitfields2;
uint32_t ordinal2;
};
union {
struct {
- uint32_t pasid:16;
- uint32_t reserved3:16;
- } bitfields3a;
- struct {
- uint32_t reserved4:2;
- uint32_t doorbell_offset0:21;
- uint32_t reserved5:9;
- } bitfields3b;
+ uint32_t page_table_base:28;
+ uint32_t reserved2:4;
+ } bitfields3;
uint32_t ordinal3;
};
- union {
- struct {
- uint32_t reserved6:2;
- uint32_t doorbell_offset1:21;
- uint32_t reserved7:9;
- } bitfields4;
- uint32_t ordinal4;
- };
-
- union {
- struct {
- uint32_t reserved8:2;
- uint32_t doorbell_offset2:21;
- uint32_t reserved9:9;
- } bitfields5;
- uint32_t ordinal5;
- };
+ uint32_t reserved3;
+ uint32_t sh_mem_bases;
+ uint32_t sh_mem_config;
+ uint32_t sh_mem_ape1_base;
+ uint32_t sh_mem_ape1_limit;
+ uint32_t sh_hidden_private_base_vmid;
+ uint32_t reserved4;
+ uint32_t reserved5;
+ uint32_t gds_addr_lo;
+ uint32_t gds_addr_hi;
union {
struct {
- uint32_t reserved10:2;
- uint32_t doorbell_offset3:21;
- uint32_t reserved11:9;
- } bitfields6;
- uint32_t ordinal6;
+ uint32_t num_gws:6;
+ uint32_t reserved6:2;
+ uint32_t num_oac:4;
+ uint32_t reserved7:4;
+ uint32_t gds_size:6;
+ uint32_t num_queues:10;
+ } bitfields14;
+ uint32_t ordinal14;
};
+ uint32_t completion_signal_lo32;
+uint32_t completion_signal_hi32;
};
#endif
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_vi.h b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_vi.h
index 08c7219..7c8d9b3 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_vi.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_vi.h
@@ -30,10 +30,12 @@ union PM4_MES_TYPE_3_HEADER {
struct {
uint32_t reserved1 : 8; /* < reserved */
uint32_t opcode : 8; /* < IT opcode */
- uint32_t count : 14;/* < number of DWORDs - 1 in the
- information body. */
- uint32_t type : 2; /* < packet identifier.
- It should be 3 for type 3 packets */
+ uint32_t count : 14;/* < Number of DWORDS - 1 in the
+ * information body
+ */
+ uint32_t type : 2; /* < packet identifier
+ * It should be 3 for type 3 packets
+ */
};
uint32_t u32All;
};
@@ -124,9 +126,10 @@ struct pm4_mes_runlist {
uint32_t ib_size:20;
uint32_t chain:1;
uint32_t offload_polling:1;
- uint32_t reserved3:1;
+ uint32_t reserved2:1;
uint32_t valid:1;
- uint32_t reserved4:8;
+ uint32_t process_cnt:4;
+ uint32_t reserved3:4;
} bitfields4;
uint32_t ordinal4;
};
@@ -141,8 +144,8 @@ struct pm4_mes_runlist {
struct pm4_mes_map_process {
union {
- union PM4_MES_TYPE_3_HEADER header; /* header */
- uint32_t ordinal1;
+ union PM4_MES_TYPE_3_HEADER header; /* header */
+ uint32_t ordinal1;
};
union {
@@ -153,36 +156,48 @@ struct pm4_mes_map_process {
uint32_t process_quantum:7;
} bitfields2;
uint32_t ordinal2;
-};
+ };
union {
struct {
uint32_t page_table_base:28;
- uint32_t reserved2:4;
+ uint32_t reserved3:4;
} bitfields3;
uint32_t ordinal3;
};
+ uint32_t reserved;
+
uint32_t sh_mem_bases;
+ uint32_t sh_mem_config;
uint32_t sh_mem_ape1_base;
uint32_t sh_mem_ape1_limit;
- uint32_t sh_mem_config;
+
+ uint32_t sh_hidden_private_base_vmid;
+
+ uint32_t reserved2;
+ uint32_t reserved3;
+
uint32_t gds_addr_lo;
uint32_t gds_addr_hi;
union {
struct {
uint32_t num_gws:6;
- uint32_t reserved3:2;
+ uint32_t reserved4:2;
uint32_t num_oac:4;
- uint32_t reserved4:4;
+ uint32_t reserved5:4;
uint32_t gds_size:6;
uint32_t num_queues:10;
} bitfields10;
uint32_t ordinal10;
};
+ uint32_t completion_signal_lo;
+ uint32_t completion_signal_hi;
+
};
+
#endif
/*--------------------MES_MAP_QUEUES--------------------*/
@@ -335,7 +350,7 @@ enum mes_unmap_queues_engine_sel_enum {
engine_sel__mes_unmap_queues__sdmal = 3
};
-struct PM4_MES_UNMAP_QUEUES {
+struct pm4_mes_unmap_queues {
union {
union PM4_MES_TYPE_3_HEADER header; /* header */
uint32_t ordinal1;
@@ -395,4 +410,101 @@ struct PM4_MES_UNMAP_QUEUES {
};
#endif
+#ifndef PM4_MEC_RELEASE_MEM_DEFINED
+#define PM4_MEC_RELEASE_MEM_DEFINED
+enum RELEASE_MEM_event_index_enum {
+ event_index___release_mem__end_of_pipe = 5,
+ event_index___release_mem__shader_done = 6
+};
+
+enum RELEASE_MEM_cache_policy_enum {
+ cache_policy___release_mem__lru = 0,
+ cache_policy___release_mem__stream = 1,
+ cache_policy___release_mem__bypass = 2
+};
+
+enum RELEASE_MEM_dst_sel_enum {
+ dst_sel___release_mem__memory_controller = 0,
+ dst_sel___release_mem__tc_l2 = 1,
+ dst_sel___release_mem__queue_write_pointer_register = 2,
+ dst_sel___release_mem__queue_write_pointer_poll_mask_bit = 3
+};
+
+enum RELEASE_MEM_int_sel_enum {
+ int_sel___release_mem__none = 0,
+ int_sel___release_mem__send_interrupt_only = 1,
+ int_sel___release_mem__send_interrupt_after_write_confirm = 2,
+ int_sel___release_mem__send_data_after_write_confirm = 3
+};
+
+enum RELEASE_MEM_data_sel_enum {
+ data_sel___release_mem__none = 0,
+ data_sel___release_mem__send_32_bit_low = 1,
+ data_sel___release_mem__send_64_bit_data = 2,
+ data_sel___release_mem__send_gpu_clock_counter = 3,
+ data_sel___release_mem__send_cp_perfcounter_hi_lo = 4,
+ data_sel___release_mem__store_gds_data_to_memory = 5
+};
+
+struct pm4_mec_release_mem {
+ union {
+ union PM4_MES_TYPE_3_HEADER header; /*header */
+ unsigned int ordinal1;
+ };
+
+ union {
+ struct {
+ unsigned int event_type:6;
+ unsigned int reserved1:2;
+ enum RELEASE_MEM_event_index_enum event_index:4;
+ unsigned int tcl1_vol_action_ena:1;
+ unsigned int tc_vol_action_ena:1;
+ unsigned int reserved2:1;
+ unsigned int tc_wb_action_ena:1;
+ unsigned int tcl1_action_ena:1;
+ unsigned int tc_action_ena:1;
+ unsigned int reserved3:6;
+ unsigned int atc:1;
+ enum RELEASE_MEM_cache_policy_enum cache_policy:2;
+ unsigned int reserved4:5;
+ } bitfields2;
+ unsigned int ordinal2;
+ };
+
+ union {
+ struct {
+ unsigned int reserved5:16;
+ enum RELEASE_MEM_dst_sel_enum dst_sel:2;
+ unsigned int reserved6:6;
+ enum RELEASE_MEM_int_sel_enum int_sel:3;
+ unsigned int reserved7:2;
+ enum RELEASE_MEM_data_sel_enum data_sel:3;
+ } bitfields3;
+ unsigned int ordinal3;
+ };
+
+ union {
+ struct {
+ unsigned int reserved8:2;
+ unsigned int address_lo_32b:30;
+ } bitfields4;
+ struct {
+ unsigned int reserved9:3;
+ unsigned int address_lo_64b:29;
+ } bitfields5;
+ unsigned int ordinal4;
+ };
+
+ unsigned int address_hi;
+
+ unsigned int data_lo;
+
+ unsigned int data_hi;
+};
+#endif
+
+enum {
+ CACHE_FLUSH_AND_INV_TS_EVENT = 0x00000014
+};
+
#endif
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index 4750cab..b397ec7 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -239,11 +239,6 @@ enum kfd_preempt_type_filter {
KFD_PREEMPT_TYPE_FILTER_BY_PASID
};
-enum kfd_preempt_type {
- KFD_PREEMPT_TYPE_WAVEFRONT,
- KFD_PREEMPT_TYPE_WAVEFRONT_RESET
-};
-
/**
* enum kfd_queue_type
*
@@ -294,13 +289,13 @@ enum kfd_queue_format {
* @write_ptr: Defines the number of dwords written to the ring buffer.
*
* @doorbell_ptr: This field aim is to notify the H/W of new packet written to
- * the queue ring buffer. This field should be similar to write_ptr and the user
- * should update this field after he updated the write_ptr.
+ * the queue ring buffer. This field should be similar to write_ptr and the
+ * user should update this field after he updated the write_ptr.
*
* @doorbell_off: The doorbell offset in the doorbell pci-bar.
*
- * @is_interop: Defines if this is a interop queue. Interop queue means that the
- * queue can access both graphics and compute resources.
+ * @is_interop: Defines if this is a interop queue. Interop queue means that
+ * the queue can access both graphics and compute resources.
*
* @is_active: Defines if the queue is active or not.
*
@@ -352,9 +347,10 @@ struct queue_properties {
* @properties: The queue properties.
*
* @mec: Used only in no cp scheduling mode and identifies to micro engine id
- * that the queue should be execute on.
+ * that the queue should be execute on.
*
- * @pipe: Used only in no cp scheduling mode and identifies the queue's pipe id.
+ * @pipe: Used only in no cp scheduling mode and identifies the queue's pipe
+ * id.
*
* @queue: Used only in no cp scheduliong mode and identifies the queue's slot.
*
@@ -436,6 +432,7 @@ struct qcm_process_device {
uint32_t gds_size;
uint32_t num_gws;
uint32_t num_oac;
+ uint32_t sh_hidden_private_base;
};
/* Data that is per-process-per device. */
@@ -520,8 +517,8 @@ struct kfd_process {
struct mutex event_mutex;
/* All events in process hashed by ID, linked on kfd_event.events. */
DECLARE_HASHTABLE(events, 4);
- struct list_head signal_event_pages; /* struct slot_page_header.
- event_pages */
+ /* struct slot_page_header.event_pages */
+ struct list_head signal_event_pages;
u32 next_nonsignal_event_id;
size_t signal_event_count;
};
@@ -559,8 +556,10 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
struct kfd_process *p);
/* Process device data iterator */
-struct kfd_process_device *kfd_get_first_process_device_data(struct kfd_process *p);
-struct kfd_process_device *kfd_get_next_process_device_data(struct kfd_process *p,
+struct kfd_process_device *kfd_get_first_process_device_data(
+ struct kfd_process *p);
+struct kfd_process_device *kfd_get_next_process_device_data(
+ struct kfd_process *p,
struct kfd_process_device *pdd);
bool kfd_has_process_device_data(struct kfd_process *p);
@@ -573,7 +572,8 @@ unsigned int kfd_pasid_alloc(void);
void kfd_pasid_free(unsigned int pasid);
/* Doorbells */
-void kfd_doorbell_init(struct kfd_dev *kfd);
+int kfd_doorbell_init(struct kfd_dev *kfd);
+void kfd_doorbell_fini(struct kfd_dev *kfd);
int kfd_doorbell_mmap(struct kfd_process *process, struct vm_area_struct *vma);
u32 __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd,
unsigned int *doorbell_off);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
index 035bbc9..c74cf22 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
@@ -79,9 +79,7 @@ struct kfd_process *kfd_create_process(const struct task_struct *thread)
{
struct kfd_process *process;
- BUG_ON(!kfd_process_wq);
-
- if (thread->mm == NULL)
+ if (!thread->mm)
return ERR_PTR(-EINVAL);
/* Only the pthreads threading model is supported. */
@@ -101,7 +99,7 @@ struct kfd_process *kfd_create_process(const struct task_struct *thread)
/* A prior open of /dev/kfd could have already created the process. */
process = find_process(thread);
if (process)
- pr_debug("kfd: process already found\n");
+ pr_debug("Process already found\n");
if (!process)
process = create_process(thread);
@@ -117,7 +115,7 @@ struct kfd_process *kfd_get_process(const struct task_struct *thread)
{
struct kfd_process *process;
- if (thread->mm == NULL)
+ if (!thread->mm)
return ERR_PTR(-EINVAL);
/* Only the pthreads threading model is supported. */
@@ -202,10 +200,8 @@ static void kfd_process_destroy_delayed(struct rcu_head *rcu)
struct kfd_process_release_work *work;
struct kfd_process *p;
- BUG_ON(!kfd_process_wq);
-
p = container_of(rcu, struct kfd_process, rcu);
- BUG_ON(atomic_read(&p->mm->mm_count) <= 0);
+ WARN_ON(atomic_read(&p->mm->mm_count) <= 0);
mmdrop(p->mm);
@@ -229,7 +225,8 @@ static void kfd_process_notifier_release(struct mmu_notifier *mn,
* mmu_notifier srcu is read locked
*/
p = container_of(mn, struct kfd_process, mmu_notifier);
- BUG_ON(p->mm != mm);
+ if (WARN_ON(p->mm != mm))
+ return;
mutex_lock(&kfd_processes_mutex);
hash_del_rcu(&p->kfd_processes);
@@ -250,7 +247,7 @@ static void kfd_process_notifier_release(struct mmu_notifier *mn,
kfd_dbgmgr_destroy(pdd->dev->dbgmgr);
if (pdd->reset_wavefronts) {
- pr_warn("amdkfd: Resetting all wave fronts\n");
+ pr_warn("Resetting all wave fronts\n");
dbgdev_wave_reset_wavefronts(pdd->dev, p);
pdd->reset_wavefronts = false;
}
@@ -407,8 +404,6 @@ void kfd_unbind_process_from_device(struct kfd_dev *dev, unsigned int pasid)
struct kfd_process *p;
struct kfd_process_device *pdd;
- BUG_ON(dev == NULL);
-
/*
* Look for the process that matches the pasid. If there is no such
* process, we either released it in amdkfd's own notifier, or there
@@ -449,14 +444,16 @@ void kfd_unbind_process_from_device(struct kfd_dev *dev, unsigned int pasid)
mutex_unlock(&p->mutex);
}
-struct kfd_process_device *kfd_get_first_process_device_data(struct kfd_process *p)
+struct kfd_process_device *kfd_get_first_process_device_data(
+ struct kfd_process *p)
{
return list_first_entry(&p->per_device_data,
struct kfd_process_device,
per_device_list);
}
-struct kfd_process_device *kfd_get_next_process_device_data(struct kfd_process *p,
+struct kfd_process_device *kfd_get_next_process_device_data(
+ struct kfd_process *p,
struct kfd_process_device *pdd)
{
if (list_is_last(&pdd->per_device_list, &p->per_device_data))
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
index 32cdf2b..1cae95e 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
@@ -32,12 +32,9 @@ static inline struct process_queue_node *get_queue_by_qid(
{
struct process_queue_node *pqn;
- BUG_ON(!pqm);
-
list_for_each_entry(pqn, &pqm->queues, process_queue_list) {
- if (pqn->q && pqn->q->properties.queue_id == qid)
- return pqn;
- if (pqn->kq && pqn->kq->queue->properties.queue_id == qid)
+ if ((pqn->q && pqn->q->properties.queue_id == qid) ||
+ (pqn->kq && pqn->kq->queue->properties.queue_id == qid))
return pqn;
}
@@ -49,17 +46,13 @@ static int find_available_queue_slot(struct process_queue_manager *pqm,
{
unsigned long found;
- BUG_ON(!pqm || !qid);
-
- pr_debug("kfd: in %s\n", __func__);
-
found = find_first_zero_bit(pqm->queue_slot_bitmap,
KFD_MAX_NUM_OF_QUEUES_PER_PROCESS);
- pr_debug("kfd: the new slot id %lu\n", found);
+ pr_debug("The new slot id %lu\n", found);
if (found >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS) {
- pr_info("amdkfd: Can not open more queues for process with pasid %d\n",
+ pr_info("Cannot open more queues for process with pasid %d\n",
pqm->process->pasid);
return -ENOMEM;
}
@@ -72,13 +65,11 @@ static int find_available_queue_slot(struct process_queue_manager *pqm,
int pqm_init(struct process_queue_manager *pqm, struct kfd_process *p)
{
- BUG_ON(!pqm);
-
INIT_LIST_HEAD(&pqm->queues);
pqm->queue_slot_bitmap =
kzalloc(DIV_ROUND_UP(KFD_MAX_NUM_OF_QUEUES_PER_PROCESS,
BITS_PER_BYTE), GFP_KERNEL);
- if (pqm->queue_slot_bitmap == NULL)
+ if (!pqm->queue_slot_bitmap)
return -ENOMEM;
pqm->process = p;
@@ -90,10 +81,6 @@ void pqm_uninit(struct process_queue_manager *pqm)
int retval;
struct process_queue_node *pqn, *next;
- BUG_ON(!pqm);
-
- pr_debug("In func %s\n", __func__);
-
list_for_each_entry_safe(pqn, next, &pqm->queues, process_queue_list) {
retval = pqm_destroy_queue(
pqm,
@@ -102,7 +89,7 @@ void pqm_uninit(struct process_queue_manager *pqm)
pqn->kq->queue->properties.queue_id);
if (retval != 0) {
- pr_err("kfd: failed to destroy queue\n");
+ pr_err("failed to destroy queue\n");
return;
}
}
@@ -117,8 +104,6 @@ static int create_cp_queue(struct process_queue_manager *pqm,
{
int retval;
- retval = 0;
-
/* Doorbell initialized in user space*/
q_properties->doorbell_ptr = NULL;
@@ -131,16 +116,13 @@ static int create_cp_queue(struct process_queue_manager *pqm,
retval = init_queue(q, q_properties);
if (retval != 0)
- goto err_init_queue;
+ return retval;
(*q)->device = dev;
(*q)->process = pqm->process;
- pr_debug("kfd: PQM After init queue");
-
- return retval;
+ pr_debug("PQM After init queue");
-err_init_queue:
return retval;
}
@@ -161,8 +143,6 @@ int pqm_create_queue(struct process_queue_manager *pqm,
int num_queues = 0;
struct queue *cur;
- BUG_ON(!pqm || !dev || !properties || !qid);
-
memset(&q_properties, 0, sizeof(struct queue_properties));
memcpy(&q_properties, properties, sizeof(struct queue_properties));
q = NULL;
@@ -185,7 +165,7 @@ int pqm_create_queue(struct process_queue_manager *pqm,
list_for_each_entry(cur, &pdd->qpd.queues_list, list)
num_queues++;
if (num_queues >= dev->device_info->max_no_of_hqd/2)
- return (-ENOSPC);
+ return -ENOSPC;
}
retval = find_available_queue_slot(pqm, qid);
@@ -197,7 +177,7 @@ int pqm_create_queue(struct process_queue_manager *pqm,
dev->dqm->ops.register_process(dev->dqm, &pdd->qpd);
}
- pqn = kzalloc(sizeof(struct process_queue_node), GFP_KERNEL);
+ pqn = kzalloc(sizeof(*pqn), GFP_KERNEL);
if (!pqn) {
retval = -ENOMEM;
goto err_allocate_pqn;
@@ -210,7 +190,7 @@ int pqm_create_queue(struct process_queue_manager *pqm,
if ((sched_policy == KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION) &&
((dev->dqm->processes_count >= VMID_PER_DEVICE) ||
(dev->dqm->queue_count >= get_queues_num(dev->dqm)))) {
- pr_err("kfd: over-subscription is not allowed in radeon_kfd.sched_policy == 1\n");
+ pr_err("Over-subscription is not allowed in radeon_kfd.sched_policy == 1\n");
retval = -EPERM;
goto err_create_queue;
}
@@ -227,7 +207,7 @@ int pqm_create_queue(struct process_queue_manager *pqm,
break;
case KFD_QUEUE_TYPE_DIQ:
kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_DIQ);
- if (kq == NULL) {
+ if (!kq) {
retval = -ENOMEM;
goto err_create_queue;
}
@@ -238,22 +218,22 @@ int pqm_create_queue(struct process_queue_manager *pqm,
kq, &pdd->qpd);
break;
default:
- BUG();
- break;
+ WARN(1, "Invalid queue type %d", type);
+ retval = -EINVAL;
}
if (retval != 0) {
- pr_debug("Error dqm create queue\n");
+ pr_err("DQM create queue failed\n");
goto err_create_queue;
}
- pr_debug("kfd: PQM After DQM create queue\n");
+ pr_debug("PQM After DQM create queue\n");
list_add(&pqn->process_queue_list, &pqm->queues);
if (q) {
*properties = q->properties;
- pr_debug("kfd: PQM done creating queue\n");
+ pr_debug("PQM done creating queue\n");
print_queue_properties(properties);
}
@@ -279,14 +259,11 @@ int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid)
dqm = NULL;
- BUG_ON(!pqm);
retval = 0;
- pr_debug("kfd: In Func %s\n", __func__);
-
pqn = get_queue_by_qid(pqm, qid);
- if (pqn == NULL) {
- pr_err("kfd: queue id does not match any known queue\n");
+ if (!pqn) {
+ pr_err("Queue id does not match any known queue\n");
return -EINVAL;
}
@@ -295,7 +272,8 @@ int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid)
dev = pqn->kq->dev;
if (pqn->q)
dev = pqn->q->device;
- BUG_ON(!dev);
+ if (WARN_ON(!dev))
+ return -ENODEV;
pdd = kfd_get_process_device_data(dev, pqm->process);
if (!pdd) {
@@ -335,12 +313,9 @@ int pqm_update_queue(struct process_queue_manager *pqm, unsigned int qid,
int retval;
struct process_queue_node *pqn;
- BUG_ON(!pqm);
-
pqn = get_queue_by_qid(pqm, qid);
if (!pqn) {
- pr_debug("amdkfd: No queue %d exists for update operation\n",
- qid);
+ pr_debug("No queue %d exists for update operation\n", qid);
return -EFAULT;
}
@@ -363,8 +338,6 @@ struct kernel_queue *pqm_get_kernel_queue(
{
struct process_queue_node *pqn;
- BUG_ON(!pqm);
-
pqn = get_queue_by_qid(pqm, qid);
if (pqn && pqn->kq)
return pqn->kq;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_queue.c
index 0ab1970..a5315d4 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_queue.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_queue.c
@@ -65,17 +65,15 @@ void print_queue(struct queue *q)
int init_queue(struct queue **q, const struct queue_properties *properties)
{
- struct queue *tmp;
+ struct queue *tmp_q;
- BUG_ON(!q);
-
- tmp = kzalloc(sizeof(struct queue), GFP_KERNEL);
- if (!tmp)
+ tmp_q = kzalloc(sizeof(*tmp_q), GFP_KERNEL);
+ if (!tmp_q)
return -ENOMEM;
- memcpy(&tmp->properties, properties, sizeof(struct queue_properties));
+ memcpy(&tmp_q->properties, properties, sizeof(*properties));
- *q = tmp;
+ *q = tmp_q;
return 0;
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
index 1e50647..19ce590 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
@@ -108,9 +108,6 @@ static int kfd_topology_get_crat_acpi(void *crat_image, size_t *size)
static void kfd_populated_cu_info_cpu(struct kfd_topology_device *dev,
struct crat_subtype_computeunit *cu)
{
- BUG_ON(!dev);
- BUG_ON(!cu);
-
dev->node_props.cpu_cores_count = cu->num_cpu_cores;
dev->node_props.cpu_core_id_base = cu->processor_id_low;
if (cu->hsa_capability & CRAT_CU_FLAGS_IOMMU_PRESENT)
@@ -123,9 +120,6 @@ static void kfd_populated_cu_info_cpu(struct kfd_topology_device *dev,
static void kfd_populated_cu_info_gpu(struct kfd_topology_device *dev,
struct crat_subtype_computeunit *cu)
{
- BUG_ON(!dev);
- BUG_ON(!cu);
-
dev->node_props.simd_id_base = cu->processor_id_low;
dev->node_props.simd_count = cu->num_simd_cores;
dev->node_props.lds_size_in_kb = cu->lds_size_in_kb;
@@ -148,8 +142,6 @@ static int kfd_parse_subtype_cu(struct crat_subtype_computeunit *cu)
struct kfd_topology_device *dev;
int i = 0;
- BUG_ON(!cu);
-
pr_info("Found CU entry in CRAT table with proximity_domain=%d caps=%x\n",
cu->proximity_domain, cu->hsa_capability);
list_for_each_entry(dev, &topology_device_list, list) {
@@ -177,8 +169,6 @@ static int kfd_parse_subtype_mem(struct crat_subtype_memory *mem)
struct kfd_topology_device *dev;
int i = 0;
- BUG_ON(!mem);
-
pr_info("Found memory entry in CRAT table with proximity_domain=%d\n",
mem->promixity_domain);
list_for_each_entry(dev, &topology_device_list, list) {
@@ -223,8 +213,6 @@ static int kfd_parse_subtype_cache(struct crat_subtype_cache *cache)
struct kfd_topology_device *dev;
uint32_t id;
- BUG_ON(!cache);
-
id = cache->processor_id_low;
pr_info("Found cache entry in CRAT table with processor_id=%d\n", id);
@@ -274,8 +262,6 @@ static int kfd_parse_subtype_iolink(struct crat_subtype_iolink *iolink)
uint32_t id_from;
uint32_t id_to;
- BUG_ON(!iolink);
-
id_from = iolink->proximity_domain_from;
id_to = iolink->proximity_domain_to;
@@ -323,8 +309,6 @@ static int kfd_parse_subtype(struct crat_subtype_generic *sub_type_hdr)
struct crat_subtype_iolink *iolink;
int ret = 0;
- BUG_ON(!sub_type_hdr);
-
switch (sub_type_hdr->type) {
case CRAT_SUBTYPE_COMPUTEUNIT_AFFINITY:
cu = (struct crat_subtype_computeunit *)sub_type_hdr;
@@ -368,8 +352,6 @@ static void kfd_release_topology_device(struct kfd_topology_device *dev)
struct kfd_cache_properties *cache;
struct kfd_iolink_properties *iolink;
- BUG_ON(!dev);
-
list_del(&dev->list);
while (dev->mem_props.next != &dev->mem_props) {
@@ -416,7 +398,7 @@ static struct kfd_topology_device *kfd_create_topology_device(void)
struct kfd_topology_device *dev;
dev = kfd_alloc_struct(dev);
- if (dev == NULL) {
+ if (!dev) {
pr_err("No memory to allocate a topology device");
return NULL;
}
@@ -666,7 +648,7 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr,
dev->node_props.simd_count);
if (dev->mem_bank_count < dev->node_props.mem_banks_count) {
- pr_info_once("kfd: mem_banks_count truncated from %d to %d\n",
+ pr_info_once("mem_banks_count truncated from %d to %d\n",
dev->node_props.mem_banks_count,
dev->mem_bank_count);
sysfs_show_32bit_prop(buffer, "mem_banks_count",
@@ -763,8 +745,6 @@ static void kfd_remove_sysfs_node_entry(struct kfd_topology_device *dev)
struct kfd_cache_properties *cache;
struct kfd_mem_properties *mem;
- BUG_ON(!dev);
-
if (dev->kobj_iolink) {
list_for_each_entry(iolink, &dev->io_link_props, list)
if (iolink->kobj) {
@@ -819,12 +799,12 @@ static int kfd_build_sysfs_node_entry(struct kfd_topology_device *dev,
int ret;
uint32_t i;
- BUG_ON(!dev);
+ if (WARN_ON(dev->kobj_node))
+ return -EEXIST;
/*
* Creating the sysfs folders
*/
- BUG_ON(dev->kobj_node);
dev->kobj_node = kfd_alloc_struct(dev->kobj_node);
if (!dev->kobj_node)
return -ENOMEM;
@@ -957,7 +937,7 @@ static int kfd_topology_update_sysfs(void)
int ret;
pr_info("Creating topology SYSFS entries\n");
- if (sys_props.kobj_topology == NULL) {
+ if (!sys_props.kobj_topology) {
sys_props.kobj_topology =
kfd_alloc_struct(sys_props.kobj_topology);
if (!sys_props.kobj_topology)
@@ -1117,10 +1097,8 @@ static struct kfd_topology_device *kfd_assign_gpu(struct kfd_dev *gpu)
struct kfd_topology_device *dev;
struct kfd_topology_device *out_dev = NULL;
- BUG_ON(!gpu);
-
list_for_each_entry(dev, &topology_device_list, list)
- if (dev->gpu == NULL && dev->node_props.simd_count > 0) {
+ if (!dev->gpu && (dev->node_props.simd_count > 0)) {
dev->gpu = gpu;
out_dev = dev;
break;
@@ -1143,11 +1121,9 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
struct kfd_topology_device *dev;
int res;
- BUG_ON(!gpu);
-
gpu_id = kfd_generate_gpu_id(gpu);
- pr_debug("kfd: Adding new GPU (ID: 0x%x) to topology\n", gpu_id);
+ pr_debug("Adding new GPU (ID: 0x%x) to topology\n", gpu_id);
down_write(&topology_lock);
/*
@@ -1170,8 +1146,8 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
* GPU vBIOS
*/
- /*
- * Update the SYSFS tree, since we added another topology device
+ /* Update the SYSFS tree, since we added another topology
+ * device
*/
if (kfd_topology_update_sysfs() < 0)
kfd_topology_release_sysfs();
@@ -1190,7 +1166,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
if (dev->gpu->device_info->asic_family == CHIP_CARRIZO) {
dev->node_props.capability |= HSA_CAP_DOORBELL_PACKET_TYPE;
- pr_info("amdkfd: adding doorbell packet type capability\n");
+ pr_info("Adding doorbell packet type capability\n");
}
res = 0;
@@ -1210,8 +1186,6 @@ int kfd_topology_remove_device(struct kfd_dev *gpu)
uint32_t gpu_id;
int res = -ENODEV;
- BUG_ON(!gpu);
-
down_write(&topology_lock);
list_for_each_entry(dev, &topology_device_list, list)
diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
index 0021a1c..837296d 100644
--- a/drivers/gpu/drm/amd/include/atomfirmware.h
+++ b/drivers/gpu/drm/amd/include/atomfirmware.h
@@ -1233,6 +1233,69 @@ struct atom_asic_profiling_info_v4_1
uint32_t phyclk2gfxclk_c;
};
+struct atom_asic_profiling_info_v4_2 {
+ struct atom_common_table_header table_header;
+ uint32_t maxvddc;
+ uint32_t minvddc;
+ uint32_t avfs_meannsigma_acontant0;
+ uint32_t avfs_meannsigma_acontant1;
+ uint32_t avfs_meannsigma_acontant2;
+ uint16_t avfs_meannsigma_dc_tol_sigma;
+ uint16_t avfs_meannsigma_platform_mean;
+ uint16_t avfs_meannsigma_platform_sigma;
+ uint32_t gb_vdroop_table_cksoff_a0;
+ uint32_t gb_vdroop_table_cksoff_a1;
+ uint32_t gb_vdroop_table_cksoff_a2;
+ uint32_t gb_vdroop_table_ckson_a0;
+ uint32_t gb_vdroop_table_ckson_a1;
+ uint32_t gb_vdroop_table_ckson_a2;
+ uint32_t avfsgb_fuse_table_cksoff_m1;
+ uint32_t avfsgb_fuse_table_cksoff_m2;
+ uint32_t avfsgb_fuse_table_cksoff_b;
+ uint32_t avfsgb_fuse_table_ckson_m1;
+ uint32_t avfsgb_fuse_table_ckson_m2;
+ uint32_t avfsgb_fuse_table_ckson_b;
+ uint16_t max_voltage_0_25mv;
+ uint8_t enable_gb_vdroop_table_cksoff;
+ uint8_t enable_gb_vdroop_table_ckson;
+ uint8_t enable_gb_fuse_table_cksoff;
+ uint8_t enable_gb_fuse_table_ckson;
+ uint16_t psm_age_comfactor;
+ uint8_t enable_apply_avfs_cksoff_voltage;
+ uint8_t reserved;
+ uint32_t dispclk2gfxclk_a;
+ uint32_t dispclk2gfxclk_b;
+ uint32_t dispclk2gfxclk_c;
+ uint32_t pixclk2gfxclk_a;
+ uint32_t pixclk2gfxclk_b;
+ uint32_t pixclk2gfxclk_c;
+ uint32_t dcefclk2gfxclk_a;
+ uint32_t dcefclk2gfxclk_b;
+ uint32_t dcefclk2gfxclk_c;
+ uint32_t phyclk2gfxclk_a;
+ uint32_t phyclk2gfxclk_b;
+ uint32_t phyclk2gfxclk_c;
+ uint32_t acg_gb_vdroop_table_a0;
+ uint32_t acg_gb_vdroop_table_a1;
+ uint32_t acg_gb_vdroop_table_a2;
+ uint32_t acg_avfsgb_fuse_table_m1;
+ uint32_t acg_avfsgb_fuse_table_m2;
+ uint32_t acg_avfsgb_fuse_table_b;
+ uint8_t enable_acg_gb_vdroop_table;
+ uint8_t enable_acg_gb_fuse_table;
+ uint32_t acg_dispclk2gfxclk_a;
+ uint32_t acg_dispclk2gfxclk_b;
+ uint32_t acg_dispclk2gfxclk_c;
+ uint32_t acg_pixclk2gfxclk_a;
+ uint32_t acg_pixclk2gfxclk_b;
+ uint32_t acg_pixclk2gfxclk_c;
+ uint32_t acg_dcefclk2gfxclk_a;
+ uint32_t acg_dcefclk2gfxclk_b;
+ uint32_t acg_dcefclk2gfxclk_c;
+ uint32_t acg_phyclk2gfxclk_a;
+ uint32_t acg_phyclk2gfxclk_b;
+ uint32_t acg_phyclk2gfxclk_c;
+};
/*
***************************************************************************
diff --git a/drivers/gpu/drm/amd/include/cgs_common.h b/drivers/gpu/drm/amd/include/cgs_common.h
index 0a94f74..0214f63 100644
--- a/drivers/gpu/drm/amd/include/cgs_common.h
+++ b/drivers/gpu/drm/amd/include/cgs_common.h
@@ -50,6 +50,7 @@ enum cgs_ind_reg {
CGS_IND_REG__UVD_CTX,
CGS_IND_REG__DIDT,
CGS_IND_REG_GC_CAC,
+ CGS_IND_REG_SE_CAC,
CGS_IND_REG__AUDIO_ENDPT
};
@@ -406,6 +407,8 @@ typedef int (*cgs_is_virtualization_enabled_t)(void *cgs_device);
typedef int (*cgs_enter_safe_mode)(struct cgs_device *cgs_device, bool en);
+typedef void (*cgs_lock_grbm_idx)(struct cgs_device *cgs_device, bool lock);
+
struct cgs_ops {
/* memory management calls (similar to KFD interface) */
cgs_alloc_gpu_mem_t alloc_gpu_mem;
@@ -441,6 +444,7 @@ struct cgs_ops {
cgs_query_system_info query_system_info;
cgs_is_virtualization_enabled_t is_virtualization_enabled;
cgs_enter_safe_mode enter_safe_mode;
+ cgs_lock_grbm_idx lock_grbm_idx;
};
struct cgs_os_ops; /* To be define in OS-specific CGS header */
@@ -517,4 +521,6 @@ struct cgs_device
#define cgs_enter_safe_mode(cgs_device, en) \
CGS_CALL(enter_safe_mode, cgs_device, en)
+#define cgs_lock_grbm_idx(cgs_device, lock) \
+ CGS_CALL(lock_grbm_idx, cgs_device, lock)
#endif /* _CGS_COMMON_H */
diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
index 36f3766..94277cb 100644
--- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
+++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
@@ -41,6 +41,11 @@ struct kgd_dev;
struct kgd_mem;
+enum kfd_preempt_type {
+ KFD_PREEMPT_TYPE_WAVEFRONT_DRAIN = 0,
+ KFD_PREEMPT_TYPE_WAVEFRONT_RESET,
+};
+
enum kgd_memory_pool {
KGD_POOL_SYSTEM_CACHEABLE = 1,
KGD_POOL_SYSTEM_WRITECOMBINE = 2,
@@ -82,6 +87,17 @@ struct kgd2kfd_shared_resources {
size_t doorbell_start_offset;
};
+struct tile_config {
+ uint32_t *tile_config_ptr;
+ uint32_t *macro_tile_config_ptr;
+ uint32_t num_tile_configs;
+ uint32_t num_macro_tile_configs;
+
+ uint32_t gb_addr_config;
+ uint32_t num_banks;
+ uint32_t num_ranks;
+};
+
/**
* struct kfd2kgd_calls
*
@@ -123,6 +139,11 @@ struct kgd2kfd_shared_resources {
*
* @get_fw_version: Returns FW versions from the header
*
+ * @set_scratch_backing_va: Sets VA for scratch backing memory of a VMID.
+ * Only used for no cp scheduling mode
+ *
+ * @get_tile_config: Returns GPU-specific tiling mode information
+ *
* This structure contains function pointers to services that the kgd driver
* provides to amdkfd driver.
*
@@ -153,14 +174,16 @@ struct kfd2kgd_calls {
int (*init_interrupts)(struct kgd_dev *kgd, uint32_t pipe_id);
int (*hqd_load)(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
- uint32_t queue_id, uint32_t __user *wptr);
+ uint32_t queue_id, uint32_t __user *wptr,
+ uint32_t wptr_shift, uint32_t wptr_mask,
+ struct mm_struct *mm);
int (*hqd_sdma_load)(struct kgd_dev *kgd, void *mqd);
bool (*hqd_is_occupied)(struct kgd_dev *kgd, uint64_t queue_address,
uint32_t pipe_id, uint32_t queue_id);
- int (*hqd_destroy)(struct kgd_dev *kgd, uint32_t reset_type,
+ int (*hqd_destroy)(struct kgd_dev *kgd, void *mqd, uint32_t reset_type,
unsigned int timeout, uint32_t pipe_id,
uint32_t queue_id);
@@ -192,6 +215,9 @@ struct kfd2kgd_calls {
uint16_t (*get_fw_version)(struct kgd_dev *kgd,
enum kgd_engine_type type);
+ void (*set_scratch_backing_va)(struct kgd_dev *kgd,
+ uint64_t va, uint32_t vmid);
+ int (*get_tile_config)(struct kgd_dev *kgd, struct tile_config *config);
};
/**
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c
index 0b74da3..bc839ff 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c
@@ -1240,13 +1240,18 @@ static int cz_phm_force_dpm_highest(struct pp_hwmgr *hwmgr)
{
struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
- if (cz_hwmgr->sclk_dpm.soft_min_clk !=
- cz_hwmgr->sclk_dpm.soft_max_clk)
- smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
- PPSMC_MSG_SetSclkSoftMin,
- cz_get_sclk_level(hwmgr,
- cz_hwmgr->sclk_dpm.soft_max_clk,
- PPSMC_MSG_SetSclkSoftMin));
+ smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+ PPSMC_MSG_SetSclkSoftMin,
+ cz_get_sclk_level(hwmgr,
+ cz_hwmgr->sclk_dpm.soft_max_clk,
+ PPSMC_MSG_SetSclkSoftMin));
+
+ smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+ PPSMC_MSG_SetSclkSoftMax,
+ cz_get_sclk_level(hwmgr,
+ cz_hwmgr->sclk_dpm.soft_max_clk,
+ PPSMC_MSG_SetSclkSoftMax));
+
return 0;
}
@@ -1292,17 +1297,55 @@ static int cz_phm_force_dpm_lowest(struct pp_hwmgr *hwmgr)
{
struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
- if (cz_hwmgr->sclk_dpm.soft_min_clk !=
- cz_hwmgr->sclk_dpm.soft_max_clk) {
- cz_hwmgr->sclk_dpm.soft_max_clk =
- cz_hwmgr->sclk_dpm.soft_min_clk;
+ smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+ PPSMC_MSG_SetSclkSoftMax,
+ cz_get_sclk_level(hwmgr,
+ cz_hwmgr->sclk_dpm.soft_min_clk,
+ PPSMC_MSG_SetSclkSoftMax));
- smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+ smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+ PPSMC_MSG_SetSclkSoftMin,
+ cz_get_sclk_level(hwmgr,
+ cz_hwmgr->sclk_dpm.soft_min_clk,
+ PPSMC_MSG_SetSclkSoftMin));
+
+ return 0;
+}
+
+static int cz_phm_force_dpm_sclk(struct pp_hwmgr *hwmgr, uint32_t sclk)
+{
+ smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+ PPSMC_MSG_SetSclkSoftMin,
+ cz_get_sclk_level(hwmgr,
+ sclk,
+ PPSMC_MSG_SetSclkSoftMin));
+
+ smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
PPSMC_MSG_SetSclkSoftMax,
cz_get_sclk_level(hwmgr,
- cz_hwmgr->sclk_dpm.soft_max_clk,
+ sclk,
PPSMC_MSG_SetSclkSoftMax));
+ return 0;
+}
+
+static int cz_get_profiling_clk(struct pp_hwmgr *hwmgr, uint32_t *sclk)
+{
+ struct phm_clock_voltage_dependency_table *table =
+ hwmgr->dyn_state.vddc_dependency_on_sclk;
+ int32_t tmp_sclk;
+ int32_t count;
+
+ tmp_sclk = table->entries[table->count-1].clk * 70 / 100;
+
+ for (count = table->count-1; count >= 0; count--) {
+ if (tmp_sclk >= table->entries[count].clk) {
+ tmp_sclk = table->entries[count].clk;
+ *sclk = tmp_sclk;
+ break;
+ }
}
+ if (count < 0)
+ *sclk = table->entries[0].clk;
return 0;
}
@@ -1310,30 +1353,70 @@ static int cz_phm_force_dpm_lowest(struct pp_hwmgr *hwmgr)
static int cz_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
enum amd_dpm_forced_level level)
{
+ uint32_t sclk = 0;
int ret = 0;
+ uint32_t profile_mode_mask = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD |
+ AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK |
+ AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;
+
+ if (level == hwmgr->dpm_level)
+ return ret;
+
+ if (!(hwmgr->dpm_level & profile_mode_mask)) {
+ /* enter profile mode, save current level, disable gfx cg*/
+ if (level & profile_mode_mask) {
+ hwmgr->saved_dpm_level = hwmgr->dpm_level;
+ cgs_set_clockgating_state(hwmgr->device,
+ AMD_IP_BLOCK_TYPE_GFX,
+ AMD_CG_STATE_UNGATE);
+ }
+ } else {
+ /* exit profile mode, restore level, enable gfx cg*/
+ if (!(level & profile_mode_mask)) {
+ if (level == AMD_DPM_FORCED_LEVEL_PROFILE_EXIT)
+ level = hwmgr->saved_dpm_level;
+ cgs_set_clockgating_state(hwmgr->device,
+ AMD_IP_BLOCK_TYPE_GFX,
+ AMD_CG_STATE_GATE);
+ }
+ }
switch (level) {
case AMD_DPM_FORCED_LEVEL_HIGH:
+ case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
ret = cz_phm_force_dpm_highest(hwmgr);
if (ret)
return ret;
+ hwmgr->dpm_level = level;
break;
case AMD_DPM_FORCED_LEVEL_LOW:
+ case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
ret = cz_phm_force_dpm_lowest(hwmgr);
if (ret)
return ret;
+ hwmgr->dpm_level = level;
break;
case AMD_DPM_FORCED_LEVEL_AUTO:
ret = cz_phm_unforce_dpm_levels(hwmgr);
if (ret)
return ret;
+ hwmgr->dpm_level = level;
+ break;
+ case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
+ ret = cz_get_profiling_clk(hwmgr, &sclk);
+ if (ret)
+ return ret;
+ hwmgr->dpm_level = level;
+ cz_phm_force_dpm_sclk(hwmgr, sclk);
+ break;
+ case AMD_DPM_FORCED_LEVEL_MANUAL:
+ hwmgr->dpm_level = level;
break;
+ case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
default:
break;
}
- hwmgr->dpm_level = level;
-
return ret;
}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
index d025653..9547f26 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
@@ -557,9 +557,8 @@ uint16_t phm_find_closest_vddci(struct pp_atomctrl_voltage_table *vddci_table, u
return vddci_table->entries[i].value;
}
- PP_ASSERT_WITH_CODE(false,
- "VDDCI is larger than max VDDCI in VDDCI Voltage Table!",
- return vddci_table->entries[i-1].value);
+ pr_debug("vddci is larger than max value in vddci_table\n");
+ return vddci_table->entries[i-1].value;
}
int phm_find_boot_level(void *table,
@@ -583,26 +582,26 @@ int phm_get_sclk_for_voltage_evv(struct pp_hwmgr *hwmgr,
phm_ppt_v1_voltage_lookup_table *lookup_table,
uint16_t virtual_voltage_id, int32_t *sclk)
{
- uint8_t entryId;
- uint8_t voltageId;
+ uint8_t entry_id;
+ uint8_t voltage_id;
struct phm_ppt_v1_information *table_info =
(struct phm_ppt_v1_information *)(hwmgr->pptable);
PP_ASSERT_WITH_CODE(lookup_table->count != 0, "Lookup table is empty", return -EINVAL);
/* search for leakage voltage ID 0xff01 ~ 0xff08 and sckl */
- for (entryId = 0; entryId < table_info->vdd_dep_on_sclk->count; entryId++) {
- voltageId = table_info->vdd_dep_on_sclk->entries[entryId].vddInd;
- if (lookup_table->entries[voltageId].us_vdd == virtual_voltage_id)
+ for (entry_id = 0; entry_id < table_info->vdd_dep_on_sclk->count; entry_id++) {
+ voltage_id = table_info->vdd_dep_on_sclk->entries[entry_id].vddInd;
+ if (lookup_table->entries[voltage_id].us_vdd == virtual_voltage_id)
break;
}
- PP_ASSERT_WITH_CODE(entryId < table_info->vdd_dep_on_sclk->count,
- "Can't find requested voltage id in vdd_dep_on_sclk table!",
- return -EINVAL;
- );
+ if (entry_id >= table_info->vdd_dep_on_sclk->count) {
+ pr_debug("Can't find requested voltage id in vdd_dep_on_sclk table\n");
+ return -EINVAL;
+ }
- *sclk = table_info->vdd_dep_on_sclk->entries[entryId].clk;
+ *sclk = table_info->vdd_dep_on_sclk->entries[entry_id].clk;
return 0;
}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c
index 720d500..c062844 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c
@@ -142,7 +142,7 @@ int pp_atomfwctrl_get_voltage_table_v4(struct pp_hwmgr *hwmgr,
}
} else if (voltage_mode == VOLTAGE_OBJ_SVID2) {
voltage_table->psi1_enable =
- voltage_object->svid2_voltage_obj.loadline_psi1 & 0x1;
+ (voltage_object->svid2_voltage_obj.loadline_psi1 & 0x20) >> 5;
voltage_table->psi0_enable =
voltage_object->svid2_voltage_obj.psi0_enable & 0x1;
voltage_table->max_vid_step =
@@ -276,7 +276,10 @@ int pp_atomfwctrl_get_avfs_information(struct pp_hwmgr *hwmgr,
struct pp_atomfwctrl_avfs_parameters *param)
{
uint16_t idx;
+ uint8_t format_revision, content_revision;
+
struct atom_asic_profiling_info_v4_1 *profile;
+ struct atom_asic_profiling_info_v4_2 *profile_v4_2;
idx = GetIndexIntoMasterDataTable(asic_profiling_info);
profile = (struct atom_asic_profiling_info_v4_1 *)
@@ -286,76 +289,172 @@ int pp_atomfwctrl_get_avfs_information(struct pp_hwmgr *hwmgr,
if (!profile)
return -1;
- param->ulMaxVddc = le32_to_cpu(profile->maxvddc);
- param->ulMinVddc = le32_to_cpu(profile->minvddc);
- param->ulMeanNsigmaAcontant0 =
- le32_to_cpu(profile->avfs_meannsigma_acontant0);
- param->ulMeanNsigmaAcontant1 =
- le32_to_cpu(profile->avfs_meannsigma_acontant1);
- param->ulMeanNsigmaAcontant2 =
- le32_to_cpu(profile->avfs_meannsigma_acontant2);
- param->usMeanNsigmaDcTolSigma =
- le16_to_cpu(profile->avfs_meannsigma_dc_tol_sigma);
- param->usMeanNsigmaPlatformMean =
- le16_to_cpu(profile->avfs_meannsigma_platform_mean);
- param->usMeanNsigmaPlatformSigma =
- le16_to_cpu(profile->avfs_meannsigma_platform_sigma);
- param->ulGbVdroopTableCksoffA0 =
- le32_to_cpu(profile->gb_vdroop_table_cksoff_a0);
- param->ulGbVdroopTableCksoffA1 =
- le32_to_cpu(profile->gb_vdroop_table_cksoff_a1);
- param->ulGbVdroopTableCksoffA2 =
- le32_to_cpu(profile->gb_vdroop_table_cksoff_a2);
- param->ulGbVdroopTableCksonA0 =
- le32_to_cpu(profile->gb_vdroop_table_ckson_a0);
- param->ulGbVdroopTableCksonA1 =
- le32_to_cpu(profile->gb_vdroop_table_ckson_a1);
- param->ulGbVdroopTableCksonA2 =
- le32_to_cpu(profile->gb_vdroop_table_ckson_a2);
- param->ulGbFuseTableCksoffM1 =
- le32_to_cpu(profile->avfsgb_fuse_table_cksoff_m1);
- param->ulGbFuseTableCksoffM2 =
- le32_to_cpu(profile->avfsgb_fuse_table_cksoff_m2);
- param->ulGbFuseTableCksoffB =
- le32_to_cpu(profile->avfsgb_fuse_table_cksoff_b);
- param->ulGbFuseTableCksonM1 =
- le32_to_cpu(profile->avfsgb_fuse_table_ckson_m1);
- param->ulGbFuseTableCksonM2 =
- le32_to_cpu(profile->avfsgb_fuse_table_ckson_m2);
- param->ulGbFuseTableCksonB =
- le32_to_cpu(profile->avfsgb_fuse_table_ckson_b);
-
- param->ucEnableGbVdroopTableCkson =
- profile->enable_gb_vdroop_table_ckson;
- param->ucEnableGbFuseTableCkson =
- profile->enable_gb_fuse_table_ckson;
- param->usPsmAgeComfactor =
- le16_to_cpu(profile->psm_age_comfactor);
-
- param->ulDispclk2GfxclkM1 =
- le32_to_cpu(profile->dispclk2gfxclk_a);
- param->ulDispclk2GfxclkM2 =
- le32_to_cpu(profile->dispclk2gfxclk_b);
- param->ulDispclk2GfxclkB =
- le32_to_cpu(profile->dispclk2gfxclk_c);
- param->ulDcefclk2GfxclkM1 =
- le32_to_cpu(profile->dcefclk2gfxclk_a);
- param->ulDcefclk2GfxclkM2 =
- le32_to_cpu(profile->dcefclk2gfxclk_b);
- param->ulDcefclk2GfxclkB =
- le32_to_cpu(profile->dcefclk2gfxclk_c);
- param->ulPixelclk2GfxclkM1 =
- le32_to_cpu(profile->pixclk2gfxclk_a);
- param->ulPixelclk2GfxclkM2 =
- le32_to_cpu(profile->pixclk2gfxclk_b);
- param->ulPixelclk2GfxclkB =
- le32_to_cpu(profile->pixclk2gfxclk_c);
- param->ulPhyclk2GfxclkM1 =
- le32_to_cpu(profile->phyclk2gfxclk_a);
- param->ulPhyclk2GfxclkM2 =
- le32_to_cpu(profile->phyclk2gfxclk_b);
- param->ulPhyclk2GfxclkB =
- le32_to_cpu(profile->phyclk2gfxclk_c);
+ format_revision = ((struct atom_common_table_header *)profile)->format_revision;
+ content_revision = ((struct atom_common_table_header *)profile)->content_revision;
+
+ if (format_revision == 4 && content_revision == 1) {
+ param->ulMaxVddc = le32_to_cpu(profile->maxvddc);
+ param->ulMinVddc = le32_to_cpu(profile->minvddc);
+ param->ulMeanNsigmaAcontant0 =
+ le32_to_cpu(profile->avfs_meannsigma_acontant0);
+ param->ulMeanNsigmaAcontant1 =
+ le32_to_cpu(profile->avfs_meannsigma_acontant1);
+ param->ulMeanNsigmaAcontant2 =
+ le32_to_cpu(profile->avfs_meannsigma_acontant2);
+ param->usMeanNsigmaDcTolSigma =
+ le16_to_cpu(profile->avfs_meannsigma_dc_tol_sigma);
+ param->usMeanNsigmaPlatformMean =
+ le16_to_cpu(profile->avfs_meannsigma_platform_mean);
+ param->usMeanNsigmaPlatformSigma =
+ le16_to_cpu(profile->avfs_meannsigma_platform_sigma);
+ param->ulGbVdroopTableCksoffA0 =
+ le32_to_cpu(profile->gb_vdroop_table_cksoff_a0);
+ param->ulGbVdroopTableCksoffA1 =
+ le32_to_cpu(profile->gb_vdroop_table_cksoff_a1);
+ param->ulGbVdroopTableCksoffA2 =
+ le32_to_cpu(profile->gb_vdroop_table_cksoff_a2);
+ param->ulGbVdroopTableCksonA0 =
+ le32_to_cpu(profile->gb_vdroop_table_ckson_a0);
+ param->ulGbVdroopTableCksonA1 =
+ le32_to_cpu(profile->gb_vdroop_table_ckson_a1);
+ param->ulGbVdroopTableCksonA2 =
+ le32_to_cpu(profile->gb_vdroop_table_ckson_a2);
+ param->ulGbFuseTableCksoffM1 =
+ le32_to_cpu(profile->avfsgb_fuse_table_cksoff_m1);
+ param->ulGbFuseTableCksoffM2 =
+ le32_to_cpu(profile->avfsgb_fuse_table_cksoff_m2);
+ param->ulGbFuseTableCksoffB =
+ le32_to_cpu(profile->avfsgb_fuse_table_cksoff_b);
+ param->ulGbFuseTableCksonM1 =
+ le32_to_cpu(profile->avfsgb_fuse_table_ckson_m1);
+ param->ulGbFuseTableCksonM2 =
+ le32_to_cpu(profile->avfsgb_fuse_table_ckson_m2);
+ param->ulGbFuseTableCksonB =
+ le32_to_cpu(profile->avfsgb_fuse_table_ckson_b);
+
+ param->ucEnableGbVdroopTableCkson =
+ profile->enable_gb_vdroop_table_ckson;
+ param->ucEnableGbFuseTableCkson =
+ profile->enable_gb_fuse_table_ckson;
+ param->usPsmAgeComfactor =
+ le16_to_cpu(profile->psm_age_comfactor);
+
+ param->ulDispclk2GfxclkM1 =
+ le32_to_cpu(profile->dispclk2gfxclk_a);
+ param->ulDispclk2GfxclkM2 =
+ le32_to_cpu(profile->dispclk2gfxclk_b);
+ param->ulDispclk2GfxclkB =
+ le32_to_cpu(profile->dispclk2gfxclk_c);
+ param->ulDcefclk2GfxclkM1 =
+ le32_to_cpu(profile->dcefclk2gfxclk_a);
+ param->ulDcefclk2GfxclkM2 =
+ le32_to_cpu(profile->dcefclk2gfxclk_b);
+ param->ulDcefclk2GfxclkB =
+ le32_to_cpu(profile->dcefclk2gfxclk_c);
+ param->ulPixelclk2GfxclkM1 =
+ le32_to_cpu(profile->pixclk2gfxclk_a);
+ param->ulPixelclk2GfxclkM2 =
+ le32_to_cpu(profile->pixclk2gfxclk_b);
+ param->ulPixelclk2GfxclkB =
+ le32_to_cpu(profile->pixclk2gfxclk_c);
+ param->ulPhyclk2GfxclkM1 =
+ le32_to_cpu(profile->phyclk2gfxclk_a);
+ param->ulPhyclk2GfxclkM2 =
+ le32_to_cpu(profile->phyclk2gfxclk_b);
+ param->ulPhyclk2GfxclkB =
+ le32_to_cpu(profile->phyclk2gfxclk_c);
+ param->ulAcgGbVdroopTableA0 = 0;
+ param->ulAcgGbVdroopTableA1 = 0;
+ param->ulAcgGbVdroopTableA2 = 0;
+ param->ulAcgGbFuseTableM1 = 0;
+ param->ulAcgGbFuseTableM2 = 0;
+ param->ulAcgGbFuseTableB = 0;
+ param->ucAcgEnableGbVdroopTable = 0;
+ param->ucAcgEnableGbFuseTable = 0;
+ } else if (format_revision == 4 && content_revision == 2) {
+ profile_v4_2 = (struct atom_asic_profiling_info_v4_2 *)profile;
+ param->ulMaxVddc = le32_to_cpu(profile_v4_2->maxvddc);
+ param->ulMinVddc = le32_to_cpu(profile_v4_2->minvddc);
+ param->ulMeanNsigmaAcontant0 =
+ le32_to_cpu(profile_v4_2->avfs_meannsigma_acontant0);
+ param->ulMeanNsigmaAcontant1 =
+ le32_to_cpu(profile_v4_2->avfs_meannsigma_acontant1);
+ param->ulMeanNsigmaAcontant2 =
+ le32_to_cpu(profile_v4_2->avfs_meannsigma_acontant2);
+ param->usMeanNsigmaDcTolSigma =
+ le16_to_cpu(profile_v4_2->avfs_meannsigma_dc_tol_sigma);
+ param->usMeanNsigmaPlatformMean =
+ le16_to_cpu(profile_v4_2->avfs_meannsigma_platform_mean);
+ param->usMeanNsigmaPlatformSigma =
+ le16_to_cpu(profile_v4_2->avfs_meannsigma_platform_sigma);
+ param->ulGbVdroopTableCksoffA0 =
+ le32_to_cpu(profile_v4_2->gb_vdroop_table_cksoff_a0);
+ param->ulGbVdroopTableCksoffA1 =
+ le32_to_cpu(profile_v4_2->gb_vdroop_table_cksoff_a1);
+ param->ulGbVdroopTableCksoffA2 =
+ le32_to_cpu(profile_v4_2->gb_vdroop_table_cksoff_a2);
+ param->ulGbVdroopTableCksonA0 =
+ le32_to_cpu(profile_v4_2->gb_vdroop_table_ckson_a0);
+ param->ulGbVdroopTableCksonA1 =
+ le32_to_cpu(profile_v4_2->gb_vdroop_table_ckson_a1);
+ param->ulGbVdroopTableCksonA2 =
+ le32_to_cpu(profile_v4_2->gb_vdroop_table_ckson_a2);
+ param->ulGbFuseTableCksoffM1 =
+ le32_to_cpu(profile_v4_2->avfsgb_fuse_table_cksoff_m1);
+ param->ulGbFuseTableCksoffM2 =
+ le32_to_cpu(profile_v4_2->avfsgb_fuse_table_cksoff_m2);
+ param->ulGbFuseTableCksoffB =
+ le32_to_cpu(profile_v4_2->avfsgb_fuse_table_cksoff_b);
+ param->ulGbFuseTableCksonM1 =
+ le32_to_cpu(profile_v4_2->avfsgb_fuse_table_ckson_m1);
+ param->ulGbFuseTableCksonM2 =
+ le32_to_cpu(profile_v4_2->avfsgb_fuse_table_ckson_m2);
+ param->ulGbFuseTableCksonB =
+ le32_to_cpu(profile_v4_2->avfsgb_fuse_table_ckson_b);
+
+ param->ucEnableGbVdroopTableCkson =
+ profile_v4_2->enable_gb_vdroop_table_ckson;
+ param->ucEnableGbFuseTableCkson =
+ profile_v4_2->enable_gb_fuse_table_ckson;
+ param->usPsmAgeComfactor =
+ le16_to_cpu(profile_v4_2->psm_age_comfactor);
+
+ param->ulDispclk2GfxclkM1 =
+ le32_to_cpu(profile_v4_2->dispclk2gfxclk_a);
+ param->ulDispclk2GfxclkM2 =
+ le32_to_cpu(profile_v4_2->dispclk2gfxclk_b);
+ param->ulDispclk2GfxclkB =
+ le32_to_cpu(profile_v4_2->dispclk2gfxclk_c);
+ param->ulDcefclk2GfxclkM1 =
+ le32_to_cpu(profile_v4_2->dcefclk2gfxclk_a);
+ param->ulDcefclk2GfxclkM2 =
+ le32_to_cpu(profile_v4_2->dcefclk2gfxclk_b);
+ param->ulDcefclk2GfxclkB =
+ le32_to_cpu(profile_v4_2->dcefclk2gfxclk_c);
+ param->ulPixelclk2GfxclkM1 =
+ le32_to_cpu(profile_v4_2->pixclk2gfxclk_a);
+ param->ulPixelclk2GfxclkM2 =
+ le32_to_cpu(profile_v4_2->pixclk2gfxclk_b);
+ param->ulPixelclk2GfxclkB =
+ le32_to_cpu(profile_v4_2->pixclk2gfxclk_c);
+ param->ulPhyclk2GfxclkM1 =
+ le32_to_cpu(profile->phyclk2gfxclk_a);
+ param->ulPhyclk2GfxclkM2 =
+ le32_to_cpu(profile_v4_2->phyclk2gfxclk_b);
+ param->ulPhyclk2GfxclkB =
+ le32_to_cpu(profile_v4_2->phyclk2gfxclk_c);
+ param->ulAcgGbVdroopTableA0 = le32_to_cpu(profile_v4_2->acg_gb_vdroop_table_a0);
+ param->ulAcgGbVdroopTableA1 = le32_to_cpu(profile_v4_2->acg_gb_vdroop_table_a1);
+ param->ulAcgGbVdroopTableA2 = le32_to_cpu(profile_v4_2->acg_gb_vdroop_table_a2);
+ param->ulAcgGbFuseTableM1 = le32_to_cpu(profile_v4_2->acg_avfsgb_fuse_table_m1);
+ param->ulAcgGbFuseTableM2 = le32_to_cpu(profile_v4_2->acg_avfsgb_fuse_table_m2);
+ param->ulAcgGbFuseTableB = le32_to_cpu(profile_v4_2->acg_avfsgb_fuse_table_b);
+ param->ucAcgEnableGbVdroopTable = le32_to_cpu(profile_v4_2->enable_acg_gb_vdroop_table);
+ param->ucAcgEnableGbFuseTable = le32_to_cpu(profile_v4_2->enable_acg_gb_fuse_table);
+ } else {
+ pr_info("Invalid VBIOS AVFS ProfilingInfo Revision!\n");
+ return -EINVAL;
+ }
return 0;
}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h
index 81908b5..8e6b1f0 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h
@@ -109,6 +109,14 @@ struct pp_atomfwctrl_avfs_parameters {
uint32_t ulPhyclk2GfxclkM1;
uint32_t ulPhyclk2GfxclkM2;
uint32_t ulPhyclk2GfxclkB;
+ uint32_t ulAcgGbVdroopTableA0;
+ uint32_t ulAcgGbVdroopTableA1;
+ uint32_t ulAcgGbVdroopTableA2;
+ uint32_t ulAcgGbFuseTableM1;
+ uint32_t ulAcgGbFuseTableM2;
+ uint32_t ulAcgGbFuseTableB;
+ uint32_t ucAcgEnableGbVdroopTable;
+ uint32_t ucAcgEnableGbFuseTable;
};
struct pp_atomfwctrl_gpio_parameters {
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c
index 4c7f430..edc5fb6 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c
@@ -265,6 +265,15 @@ static int rv_tf_set_clock_limit(struct pp_hwmgr *hwmgr, void *input,
}
} */
+ if (((hwmgr->uvd_arbiter.vclk_soft_min / 100) != rv_data->vclk_soft_min) ||
+ ((hwmgr->uvd_arbiter.dclk_soft_min / 100) != rv_data->dclk_soft_min)) {
+ rv_data->vclk_soft_min = hwmgr->uvd_arbiter.vclk_soft_min / 100;
+ rv_data->dclk_soft_min = hwmgr->uvd_arbiter.dclk_soft_min / 100;
+ smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+ PPSMC_MSG_SetSoftMinVcn,
+ (rv_data->vclk_soft_min << 16) | rv_data->vclk_soft_min);
+ }
+
if((hwmgr->gfx_arbiter.sclk_hard_min != 0) &&
((hwmgr->gfx_arbiter.sclk_hard_min / 100) != rv_data->soc_actual_hard_min_freq)) {
smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.h
index afb8522..2472b50 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.h
@@ -280,6 +280,8 @@ struct rv_hwmgr {
uint32_t f_actual_hard_min_freq;
uint32_t fabric_actual_soft_min_freq;
+ uint32_t vclk_soft_min;
+ uint32_t dclk_soft_min;
uint32_t gfx_actual_soft_min_freq;
bool vcn_power_gated;
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
index 1f01020..c274323 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
@@ -1962,9 +1962,6 @@ static int smu7_thermal_parameter_init(struct pp_hwmgr *hwmgr)
temp_reg = PHM_SET_FIELD(temp_reg, CNB_PWRMGT_CNTL, DPM_ENABLED, 0x1);
break;
default:
- PP_ASSERT_WITH_CODE(0,
- "Failed to setup PCC HW register! Wrong GPIO assigned for VDDC_PCC_GPIO_PINID!",
- );
break;
}
cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCNB_PWRMGT_CNTL, temp_reg);
@@ -4630,6 +4627,15 @@ static int smu7_set_power_profile_state(struct pp_hwmgr *hwmgr,
static int smu7_avfs_control(struct pp_hwmgr *hwmgr, bool enable)
{
+ struct pp_smumgr *smumgr = (struct pp_smumgr *)(hwmgr->smumgr);
+ struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(smumgr->backend);
+
+ if (smu_data == NULL)
+ return -EINVAL;
+
+ if (smu_data->avfs.avfs_btc_status == AVFS_BTC_NOTSUPPORTED)
+ return 0;
+
if (enable) {
if (!PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device,
CGS_IND_REG__SMC, FEATURE_STATUS, AVS_ON))
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
index 197174e..9d71a25 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
@@ -78,6 +78,8 @@ uint32_t channel_number[] = {1, 2, 0, 4, 0, 8, 0, 16, 2};
#define DF_CS_AON0_DramBaseAddress0__IntLvNumChan_MASK 0x000000F0L
#define DF_CS_AON0_DramBaseAddress0__IntLvAddrSel_MASK 0x00000700L
#define DF_CS_AON0_DramBaseAddress0__DramBaseAddr_MASK 0xFFFFF000L
+static int vega10_force_clock_level(struct pp_hwmgr *hwmgr,
+ enum pp_clock_type type, uint32_t mask);
const ULONG PhwVega10_Magic = (ULONG)(PHM_VIslands_Magic);
@@ -146,6 +148,19 @@ static void vega10_set_default_registry_data(struct pp_hwmgr *hwmgr)
data->registry_data.vr1hot_enabled = 1;
data->registry_data.regulator_hot_gpio_support = 1;
+ data->registry_data.didt_support = 1;
+ if (data->registry_data.didt_support) {
+ data->registry_data.didt_mode = 6;
+ data->registry_data.sq_ramping_support = 1;
+ data->registry_data.db_ramping_support = 0;
+ data->registry_data.td_ramping_support = 0;
+ data->registry_data.tcp_ramping_support = 0;
+ data->registry_data.dbr_ramping_support = 0;
+ data->registry_data.edc_didt_support = 1;
+ data->registry_data.gc_didt_support = 0;
+ data->registry_data.psm_didt_support = 0;
+ }
+
data->display_voltage_mode = PPVEGA10_VEGA10DISPLAYVOLTAGEMODE_DFLT;
data->dcef_clk_quad_eqn_a = PPREGKEY_VEGA10QUADRATICEQUATION_DFLT;
data->dcef_clk_quad_eqn_b = PPREGKEY_VEGA10QUADRATICEQUATION_DFLT;
@@ -223,6 +238,8 @@ static int vega10_set_features_platform_caps(struct pp_hwmgr *hwmgr)
phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_PowerContainment);
phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+ PHM_PlatformCaps_DiDtSupport);
+ phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_SQRamping);
phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_DBRamping);
@@ -230,6 +247,34 @@ static int vega10_set_features_platform_caps(struct pp_hwmgr *hwmgr)
PHM_PlatformCaps_TDRamping);
phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_TCPRamping);
+ phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+ PHM_PlatformCaps_DBRRamping);
+ phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+ PHM_PlatformCaps_DiDtEDCEnable);
+ phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+ PHM_PlatformCaps_GCEDC);
+ phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+ PHM_PlatformCaps_PSM);
+
+ if (data->registry_data.didt_support) {
+ phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DiDtSupport);
+ if (data->registry_data.sq_ramping_support)
+ phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SQRamping);
+ if (data->registry_data.db_ramping_support)
+ phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DBRamping);
+ if (data->registry_data.td_ramping_support)
+ phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_TDRamping);
+ if (data->registry_data.tcp_ramping_support)
+ phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_TCPRamping);
+ if (data->registry_data.dbr_ramping_support)
+ phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DBRRamping);
+ if (data->registry_data.edc_didt_support)
+ phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DiDtEDCEnable);
+ if (data->registry_data.gc_didt_support)
+ phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_GCEDC);
+ if (data->registry_data.psm_didt_support)
+ phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PSM);
+ }
if (data->registry_data.power_containment_support)
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
@@ -321,8 +366,8 @@ static void vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr)
FEATURE_LED_DISPLAY_BIT;
data->smu_features[GNLD_FAN_CONTROL].smu_feature_id =
FEATURE_FAN_CONTROL_BIT;
- data->smu_features[GNLD_VOLTAGE_CONTROLLER].smu_feature_id =
- FEATURE_VOLTAGE_CONTROLLER_BIT;
+ data->smu_features[GNLD_ACG].smu_feature_id = FEATURE_ACG_BIT;
+ data->smu_features[GNLD_DIDT].smu_feature_id = FEATURE_GFX_EDC_BIT;
if (!data->registry_data.prefetcher_dpm_key_disabled)
data->smu_features[GNLD_DPM_PREFETCHER].supported = true;
@@ -386,6 +431,15 @@ static void vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr)
if (data->registry_data.vr0hot_enabled)
data->smu_features[GNLD_VR0HOT].supported = true;
+ smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_GetSmuVersion);
+ vega10_read_arg_from_smc(hwmgr->smumgr, &(data->smu_version));
+ /* ACG firmware has major version 5 */
+ if ((data->smu_version & 0xff000000) == 0x5000000)
+ data->smu_features[GNLD_ACG].supported = true;
+
+ if (data->registry_data.didt_support)
+ data->smu_features[GNLD_DIDT].supported = true;
+
}
#ifdef PPLIB_VEGA10_EVV_SUPPORT
@@ -2222,6 +2276,21 @@ static int vega10_populate_avfs_parameters(struct pp_hwmgr *hwmgr)
pp_table->DisplayClock2Gfxclk[DSPCLK_PHYCLK].m1_shift = 24;
pp_table->DisplayClock2Gfxclk[DSPCLK_PHYCLK].m2_shift = 12;
pp_table->DisplayClock2Gfxclk[DSPCLK_PHYCLK].b_shift = 12;
+
+ pp_table->AcgBtcGbVdroopTable.a0 = avfs_params.ulAcgGbVdroopTableA0;
+ pp_table->AcgBtcGbVdroopTable.a0_shift = 20;
+ pp_table->AcgBtcGbVdroopTable.a1 = avfs_params.ulAcgGbVdroopTableA1;
+ pp_table->AcgBtcGbVdroopTable.a1_shift = 20;
+ pp_table->AcgBtcGbVdroopTable.a2 = avfs_params.ulAcgGbVdroopTableA2;
+ pp_table->AcgBtcGbVdroopTable.a2_shift = 20;
+
+ pp_table->AcgAvfsGb.m1 = avfs_params.ulAcgGbFuseTableM1;
+ pp_table->AcgAvfsGb.m2 = avfs_params.ulAcgGbFuseTableM2;
+ pp_table->AcgAvfsGb.b = avfs_params.ulAcgGbFuseTableB;
+ pp_table->AcgAvfsGb.m1_shift = 0;
+ pp_table->AcgAvfsGb.m2_shift = 0;
+ pp_table->AcgAvfsGb.b_shift = 0;
+
} else {
data->smu_features[GNLD_AVFS].supported = false;
}
@@ -2230,6 +2299,55 @@ static int vega10_populate_avfs_parameters(struct pp_hwmgr *hwmgr)
return 0;
}
+static int vega10_acg_enable(struct pp_hwmgr *hwmgr)
+{
+ struct vega10_hwmgr *data =
+ (struct vega10_hwmgr *)(hwmgr->backend);
+ uint32_t agc_btc_response;
+
+ if (data->smu_features[GNLD_ACG].supported) {
+ if (0 == vega10_enable_smc_features(hwmgr->smumgr, true,
+ data->smu_features[GNLD_DPM_PREFETCHER].smu_feature_bitmap))
+ data->smu_features[GNLD_DPM_PREFETCHER].enabled = true;
+
+ smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_InitializeAcg);
+
+ smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_RunAcgBtc);
+ vega10_read_arg_from_smc(hwmgr->smumgr, &agc_btc_response);
+
+ if (1 == agc_btc_response) {
+ if (1 == data->acg_loop_state)
+ smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_RunAcgInClosedLoop);
+ else if (2 == data->acg_loop_state)
+ smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_RunAcgInOpenLoop);
+ if (0 == vega10_enable_smc_features(hwmgr->smumgr, true,
+ data->smu_features[GNLD_ACG].smu_feature_bitmap))
+ data->smu_features[GNLD_ACG].enabled = true;
+ } else {
+ pr_info("[ACG_Enable] ACG BTC Returned Failed Status!\n");
+ data->smu_features[GNLD_ACG].enabled = false;
+ }
+ }
+
+ return 0;
+}
+
+static int vega10_acg_disable(struct pp_hwmgr *hwmgr)
+{
+ struct vega10_hwmgr *data =
+ (struct vega10_hwmgr *)(hwmgr->backend);
+
+ if (data->smu_features[GNLD_ACG].supported) {
+ if (data->smu_features[GNLD_ACG].enabled) {
+ if (0 == vega10_enable_smc_features(hwmgr->smumgr, false,
+ data->smu_features[GNLD_ACG].smu_feature_bitmap))
+ data->smu_features[GNLD_ACG].enabled = false;
+ }
+ }
+
+ return 0;
+}
+
static int vega10_populate_gpio_parameters(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
@@ -2404,6 +2522,9 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr)
pp_table->DisplayDpmVoltageMode =
(uint8_t)(table_info->uc_dcef_dpm_voltage_mode);
+ data->vddc_voltage_table.psi0_enable = voltage_table.psi0_enable;
+ data->vddc_voltage_table.psi1_enable = voltage_table.psi1_enable;
+
if (data->registry_data.ulv_support &&
table_info->us_ulv_voltage_offset) {
result = vega10_populate_ulv_state(hwmgr);
@@ -2500,7 +2621,7 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr)
result = vega10_avfs_enable(hwmgr, true);
PP_ASSERT_WITH_CODE(!result, "Attempt to enable AVFS feature Failed!",
return result);
-
+ vega10_acg_enable(hwmgr);
vega10_save_default_power_profile(hwmgr);
return 0;
@@ -2832,6 +2953,11 @@ static int vega10_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
PP_ASSERT_WITH_CODE(!tmp_result,
"Failed to start DPM!", result = tmp_result);
+ /* enable didt, do not abort if failed didt */
+ tmp_result = vega10_enable_didt_config(hwmgr);
+ PP_ASSERT(!tmp_result,
+ "Failed to enable didt config!");
+
tmp_result = vega10_enable_power_containment(hwmgr);
PP_ASSERT_WITH_CODE(!tmp_result,
"Failed to enable power containment!",
@@ -3578,10 +3704,22 @@ static void vega10_apply_dal_minimum_voltage_request(
return;
}
+static int vega10_get_soc_index_for_max_uclk(struct pp_hwmgr *hwmgr)
+{
+ struct phm_ppt_v1_clock_voltage_dependency_table *vdd_dep_table_on_mclk;
+ struct phm_ppt_v2_information *table_info =
+ (struct phm_ppt_v2_information *)(hwmgr->pptable);
+
+ vdd_dep_table_on_mclk = table_info->vdd_dep_on_mclk;
+
+ return vdd_dep_table_on_mclk->entries[NUM_UCLK_DPM_LEVELS - 1].vddInd + 1;
+}
+
static int vega10_upload_dpm_bootup_level(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
+ uint32_t socclk_idx;
vega10_apply_dal_minimum_voltage_request(hwmgr);
@@ -3602,13 +3740,22 @@ static int vega10_upload_dpm_bootup_level(struct pp_hwmgr *hwmgr)
if (!data->registry_data.mclk_dpm_key_disabled) {
if (data->smc_state_table.mem_boot_level !=
data->dpm_table.mem_table.dpm_state.soft_min_level) {
+ if (data->smc_state_table.mem_boot_level == NUM_UCLK_DPM_LEVELS - 1) {
+ socclk_idx = vega10_get_soc_index_for_max_uclk(hwmgr);
PP_ASSERT_WITH_CODE(!smum_send_msg_to_smc_with_parameter(
- hwmgr->smumgr,
- PPSMC_MSG_SetSoftMinUclkByIndex,
- data->smc_state_table.mem_boot_level),
- "Failed to set soft min mclk index!",
- return -EINVAL);
-
+ hwmgr->smumgr,
+ PPSMC_MSG_SetSoftMinSocclkByIndex,
+ socclk_idx),
+ "Failed to set soft min uclk index!",
+ return -EINVAL);
+ } else {
+ PP_ASSERT_WITH_CODE(!smum_send_msg_to_smc_with_parameter(
+ hwmgr->smumgr,
+ PPSMC_MSG_SetSoftMinUclkByIndex,
+ data->smc_state_table.mem_boot_level),
+ "Failed to set soft min uclk index!",
+ return -EINVAL);
+ }
data->dpm_table.mem_table.dpm_state.soft_min_level =
data->smc_state_table.mem_boot_level;
}
@@ -4015,7 +4162,7 @@ static int vega10_notify_smc_display_config_after_ps_adjustment(
pr_info("Attempt to set Hard Min for DCEFCLK Failed!");
}
} else {
- pr_info("Cannot find requested DCEFCLK!");
+ pr_debug("Cannot find requested DCEFCLK!");
}
if (min_clocks.memoryClock != 0) {
@@ -4097,34 +4244,30 @@ static int vega10_unforce_dpm_levels(struct pp_hwmgr *hwmgr)
return 0;
}
-static int vega10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
- enum amd_dpm_forced_level level)
+static int vega10_get_profiling_clk_mask(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_level level,
+ uint32_t *sclk_mask, uint32_t *mclk_mask, uint32_t *soc_mask)
{
- int ret = 0;
+ struct phm_ppt_v2_information *table_info =
+ (struct phm_ppt_v2_information *)(hwmgr->pptable);
- switch (level) {
- case AMD_DPM_FORCED_LEVEL_HIGH:
- ret = vega10_force_dpm_highest(hwmgr);
- if (ret)
- return ret;
- break;
- case AMD_DPM_FORCED_LEVEL_LOW:
- ret = vega10_force_dpm_lowest(hwmgr);
- if (ret)
- return ret;
- break;
- case AMD_DPM_FORCED_LEVEL_AUTO:
- ret = vega10_unforce_dpm_levels(hwmgr);
- if (ret)
- return ret;
- break;
- default:
- break;
+ if (table_info->vdd_dep_on_sclk->count > VEGA10_UMD_PSTATE_GFXCLK_LEVEL &&
+ table_info->vdd_dep_on_socclk->count > VEGA10_UMD_PSTATE_SOCCLK_LEVEL &&
+ table_info->vdd_dep_on_mclk->count > VEGA10_UMD_PSTATE_MCLK_LEVEL) {
+ *sclk_mask = VEGA10_UMD_PSTATE_GFXCLK_LEVEL;
+ *soc_mask = VEGA10_UMD_PSTATE_SOCCLK_LEVEL;
+ *mclk_mask = VEGA10_UMD_PSTATE_MCLK_LEVEL;
}
- hwmgr->dpm_level = level;
-
- return ret;
+ if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) {
+ *sclk_mask = 0;
+ } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK) {
+ *mclk_mask = 0;
+ } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) {
+ *sclk_mask = table_info->vdd_dep_on_sclk->count - 1;
+ *soc_mask = table_info->vdd_dep_on_socclk->count - 1;
+ *mclk_mask = table_info->vdd_dep_on_mclk->count - 1;
+ }
+ return 0;
}
static int vega10_set_fan_control_mode(struct pp_hwmgr *hwmgr, uint32_t mode)
@@ -4151,6 +4294,86 @@ static int vega10_set_fan_control_mode(struct pp_hwmgr *hwmgr, uint32_t mode)
return result;
}
+static int vega10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
+ enum amd_dpm_forced_level level)
+{
+ int ret = 0;
+ uint32_t sclk_mask = 0;
+ uint32_t mclk_mask = 0;
+ uint32_t soc_mask = 0;
+ uint32_t profile_mode_mask = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD |
+ AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK |
+ AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK |
+ AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;
+
+ if (level == hwmgr->dpm_level)
+ return ret;
+
+ if (!(hwmgr->dpm_level & profile_mode_mask)) {
+ /* enter profile mode, save current level, disable gfx cg*/
+ if (level & profile_mode_mask) {
+ hwmgr->saved_dpm_level = hwmgr->dpm_level;
+ cgs_set_clockgating_state(hwmgr->device,
+ AMD_IP_BLOCK_TYPE_GFX,
+ AMD_CG_STATE_UNGATE);
+ }
+ } else {
+ /* exit profile mode, restore level, enable gfx cg*/
+ if (!(level & profile_mode_mask)) {
+ if (level == AMD_DPM_FORCED_LEVEL_PROFILE_EXIT)
+ level = hwmgr->saved_dpm_level;
+ cgs_set_clockgating_state(hwmgr->device,
+ AMD_IP_BLOCK_TYPE_GFX,
+ AMD_CG_STATE_GATE);
+ }
+ }
+
+ switch (level) {
+ case AMD_DPM_FORCED_LEVEL_HIGH:
+ ret = vega10_force_dpm_highest(hwmgr);
+ if (ret)
+ return ret;
+ hwmgr->dpm_level = level;
+ break;
+ case AMD_DPM_FORCED_LEVEL_LOW:
+ ret = vega10_force_dpm_lowest(hwmgr);
+ if (ret)
+ return ret;
+ hwmgr->dpm_level = level;
+ break;
+ case AMD_DPM_FORCED_LEVEL_AUTO:
+ ret = vega10_unforce_dpm_levels(hwmgr);
+ if (ret)
+ return ret;
+ hwmgr->dpm_level = level;
+ break;
+ case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
+ case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
+ case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
+ case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
+ ret = vega10_get_profiling_clk_mask(hwmgr, level, &sclk_mask, &mclk_mask, &soc_mask);
+ if (ret)
+ return ret;
+ hwmgr->dpm_level = level;
+ vega10_force_clock_level(hwmgr, PP_SCLK, 1<<sclk_mask);
+ vega10_force_clock_level(hwmgr, PP_MCLK, 1<<mclk_mask);
+ break;
+ case AMD_DPM_FORCED_LEVEL_MANUAL:
+ hwmgr->dpm_level = level;
+ break;
+ case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
+ default:
+ break;
+ }
+
+ if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK && hwmgr->saved_dpm_level != AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)
+ vega10_set_fan_control_mode(hwmgr, AMD_FAN_CTRL_NONE);
+ else if (level != AMD_DPM_FORCED_LEVEL_PROFILE_PEAK && hwmgr->saved_dpm_level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)
+ vega10_set_fan_control_mode(hwmgr, AMD_FAN_CTRL_AUTO);
+
+ return 0;
+}
+
static int vega10_get_fan_control_mode(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
@@ -4396,7 +4619,9 @@ static int vega10_force_clock_level(struct pp_hwmgr *hwmgr,
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
int i;
- if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL)
+ if (hwmgr->dpm_level & (AMD_DPM_FORCED_LEVEL_AUTO |
+ AMD_DPM_FORCED_LEVEL_LOW |
+ AMD_DPM_FORCED_LEVEL_HIGH))
return -EINVAL;
switch (type) {
@@ -4661,6 +4886,10 @@ static int vega10_disable_dpm_tasks(struct pp_hwmgr *hwmgr)
PP_ASSERT_WITH_CODE((tmp_result == 0),
"Failed to disable power containment!", result = tmp_result);
+ tmp_result = vega10_disable_didt_config(hwmgr);
+ PP_ASSERT_WITH_CODE((tmp_result == 0),
+ "Failed to disable didt config!", result = tmp_result);
+
tmp_result = vega10_avfs_enable(hwmgr, false);
PP_ASSERT_WITH_CODE((tmp_result == 0),
"Failed to disable AVFS!", result = tmp_result);
@@ -4677,6 +4906,9 @@ static int vega10_disable_dpm_tasks(struct pp_hwmgr *hwmgr)
PP_ASSERT_WITH_CODE((tmp_result == 0),
"Failed to disable ulv!", result = tmp_result);
+ tmp_result = vega10_acg_disable(hwmgr);
+ PP_ASSERT_WITH_CODE((tmp_result == 0),
+ "Failed to disable acg!", result = tmp_result);
return result;
}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h
index 6e5c5b9..676cd77 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h
@@ -64,7 +64,9 @@ enum {
GNLD_FW_CTF,
GNLD_LED_DISPLAY,
GNLD_FAN_CONTROL,
- GNLD_VOLTAGE_CONTROLLER,
+ GNLD_FEATURE_FAST_PPT_BIT,
+ GNLD_DIDT,
+ GNLD_ACG,
GNLD_FEATURES_MAX
};
@@ -230,7 +232,9 @@ struct vega10_registry_data {
uint8_t cac_support;
uint8_t clock_stretcher_support;
uint8_t db_ramping_support;
+ uint8_t didt_mode;
uint8_t didt_support;
+ uint8_t edc_didt_support;
uint8_t dynamic_state_patching_support;
uint8_t enable_pkg_pwr_tracking_feature;
uint8_t enable_tdc_limit_feature;
@@ -263,6 +267,9 @@ struct vega10_registry_data {
uint8_t tcp_ramping_support;
uint8_t tdc_support;
uint8_t td_ramping_support;
+ uint8_t dbr_ramping_support;
+ uint8_t gc_didt_support;
+ uint8_t psm_didt_support;
uint8_t thermal_out_gpio_support;
uint8_t thermal_support;
uint8_t fw_ctf_enabled;
@@ -381,6 +388,8 @@ struct vega10_hwmgr {
struct vega10_smc_state_table smc_state_table;
uint32_t config_telemetry;
+ uint32_t smu_version;
+ uint32_t acg_loop_state;
};
#define VEGA10_DPM2_NEAR_TDP_DEC 10
@@ -425,6 +434,10 @@ struct vega10_hwmgr {
#define PPVEGA10_VEGA10UCLKCLKAVERAGEALPHA_DFLT 25 /* 10% * 255 = 25 */
#define PPVEGA10_VEGA10GFXACTIVITYAVERAGEALPHA_DFLT 25 /* 10% * 255 = 25 */
+#define VEGA10_UMD_PSTATE_GFXCLK_LEVEL 0x3
+#define VEGA10_UMD_PSTATE_SOCCLK_LEVEL 0x3
+#define VEGA10_UMD_PSTATE_MCLK_LEVEL 0x2
+
extern int tonga_initializa_dynamic_state_adjustment_rule_settings(struct pp_hwmgr *hwmgr);
extern int tonga_hwmgr_backend_fini(struct pp_hwmgr *hwmgr);
extern int tonga_get_mc_microcode_version (struct pp_hwmgr *hwmgr);
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c
index 3f72268..e7fa670 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c
@@ -26,7 +26,1298 @@
#include "vega10_powertune.h"
#include "vega10_smumgr.h"
#include "vega10_ppsmc.h"
+#include "vega10_inc.h"
#include "pp_debug.h"
+#include "pp_soc15.h"
+
+static const struct vega10_didt_config_reg SEDiDtTuningCtrlConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* DIDT_SQ */
+ { ixDIDT_SQ_TUNING_CTRL, DIDT_SQ_TUNING_CTRL__MAX_POWER_DELTA_HI_MASK, DIDT_SQ_TUNING_CTRL__MAX_POWER_DELTA_HI__SHIFT, 0x3853 },
+ { ixDIDT_SQ_TUNING_CTRL, DIDT_SQ_TUNING_CTRL__MAX_POWER_DELTA_LO_MASK, DIDT_SQ_TUNING_CTRL__MAX_POWER_DELTA_LO__SHIFT, 0x3153 },
+
+ /* DIDT_TD */
+ { ixDIDT_TD_TUNING_CTRL, DIDT_TD_TUNING_CTRL__MAX_POWER_DELTA_HI_MASK, DIDT_TD_TUNING_CTRL__MAX_POWER_DELTA_HI__SHIFT, 0x0dde },
+ { ixDIDT_TD_TUNING_CTRL, DIDT_TD_TUNING_CTRL__MAX_POWER_DELTA_LO_MASK, DIDT_TD_TUNING_CTRL__MAX_POWER_DELTA_LO__SHIFT, 0x0dde },
+
+ /* DIDT_TCP */
+ { ixDIDT_TCP_TUNING_CTRL, DIDT_TCP_TUNING_CTRL__MAX_POWER_DELTA_HI_MASK, DIDT_TCP_TUNING_CTRL__MAX_POWER_DELTA_HI__SHIFT, 0x3dde },
+ { ixDIDT_TCP_TUNING_CTRL, DIDT_TCP_TUNING_CTRL__MAX_POWER_DELTA_LO_MASK, DIDT_TCP_TUNING_CTRL__MAX_POWER_DELTA_LO__SHIFT, 0x3dde },
+
+ /* DIDT_DB */
+ { ixDIDT_DB_TUNING_CTRL, DIDT_DB_TUNING_CTRL__MAX_POWER_DELTA_HI_MASK, DIDT_DB_TUNING_CTRL__MAX_POWER_DELTA_HI__SHIFT, 0x3dde },
+ { ixDIDT_DB_TUNING_CTRL, DIDT_DB_TUNING_CTRL__MAX_POWER_DELTA_LO_MASK, DIDT_DB_TUNING_CTRL__MAX_POWER_DELTA_LO__SHIFT, 0x3dde },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg SEDiDtCtrl3Config_vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /*DIDT_SQ_CTRL3 */
+ { ixDIDT_SQ_CTRL3, DIDT_SQ_CTRL3__GC_DIDT_ENABLE_MASK, DIDT_SQ_CTRL3__GC_DIDT_ENABLE__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL3, DIDT_SQ_CTRL3__GC_DIDT_CLK_EN_OVERRIDE_MASK, DIDT_SQ_CTRL3__GC_DIDT_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL3, DIDT_SQ_CTRL3__THROTTLE_POLICY_MASK, DIDT_SQ_CTRL3__THROTTLE_POLICY__SHIFT, 0x0003 },
+ { ixDIDT_SQ_CTRL3, DIDT_SQ_CTRL3__DIDT_TRIGGER_THROTTLE_LOWBIT_MASK, DIDT_SQ_CTRL3__DIDT_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL3, DIDT_SQ_CTRL3__DIDT_POWER_LEVEL_LOWBIT_MASK, DIDT_SQ_CTRL3__DIDT_POWER_LEVEL_LOWBIT__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL3, DIDT_SQ_CTRL3__DIDT_STALL_PATTERN_BIT_NUMS_MASK, DIDT_SQ_CTRL3__DIDT_STALL_PATTERN_BIT_NUMS__SHIFT, 0x0003 },
+ { ixDIDT_SQ_CTRL3, DIDT_SQ_CTRL3__GC_DIDT_LEVEL_COMB_EN_MASK, DIDT_SQ_CTRL3__GC_DIDT_LEVEL_COMB_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL3, DIDT_SQ_CTRL3__SE_DIDT_LEVEL_COMB_EN_MASK, DIDT_SQ_CTRL3__SE_DIDT_LEVEL_COMB_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL3, DIDT_SQ_CTRL3__QUALIFY_STALL_EN_MASK, DIDT_SQ_CTRL3__QUALIFY_STALL_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL3, DIDT_SQ_CTRL3__DIDT_STALL_SEL_MASK, DIDT_SQ_CTRL3__DIDT_STALL_SEL__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL3, DIDT_SQ_CTRL3__DIDT_FORCE_STALL_MASK, DIDT_SQ_CTRL3__DIDT_FORCE_STALL__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL3, DIDT_SQ_CTRL3__DIDT_STALL_DELAY_EN_MASK, DIDT_SQ_CTRL3__DIDT_STALL_DELAY_EN__SHIFT, 0x0000 },
+
+ /*DIDT_TCP_CTRL3 */
+ { ixDIDT_TCP_CTRL3, DIDT_TCP_CTRL3__GC_DIDT_ENABLE_MASK, DIDT_TCP_CTRL3__GC_DIDT_ENABLE__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL3, DIDT_TCP_CTRL3__GC_DIDT_CLK_EN_OVERRIDE_MASK, DIDT_TCP_CTRL3__GC_DIDT_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL3, DIDT_TCP_CTRL3__THROTTLE_POLICY_MASK, DIDT_TCP_CTRL3__THROTTLE_POLICY__SHIFT, 0x0003 },
+ { ixDIDT_TCP_CTRL3, DIDT_TCP_CTRL3__DIDT_TRIGGER_THROTTLE_LOWBIT_MASK, DIDT_TCP_CTRL3__DIDT_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL3, DIDT_TCP_CTRL3__DIDT_POWER_LEVEL_LOWBIT_MASK, DIDT_TCP_CTRL3__DIDT_POWER_LEVEL_LOWBIT__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL3, DIDT_TCP_CTRL3__DIDT_STALL_PATTERN_BIT_NUMS_MASK, DIDT_TCP_CTRL3__DIDT_STALL_PATTERN_BIT_NUMS__SHIFT, 0x0003 },
+ { ixDIDT_TCP_CTRL3, DIDT_TCP_CTRL3__GC_DIDT_LEVEL_COMB_EN_MASK, DIDT_TCP_CTRL3__GC_DIDT_LEVEL_COMB_EN__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL3, DIDT_TCP_CTRL3__SE_DIDT_LEVEL_COMB_EN_MASK, DIDT_TCP_CTRL3__SE_DIDT_LEVEL_COMB_EN__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL3, DIDT_TCP_CTRL3__QUALIFY_STALL_EN_MASK, DIDT_TCP_CTRL3__QUALIFY_STALL_EN__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL3, DIDT_TCP_CTRL3__DIDT_STALL_SEL_MASK, DIDT_TCP_CTRL3__DIDT_STALL_SEL__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL3, DIDT_TCP_CTRL3__DIDT_FORCE_STALL_MASK, DIDT_TCP_CTRL3__DIDT_FORCE_STALL__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL3, DIDT_TCP_CTRL3__DIDT_STALL_DELAY_EN_MASK, DIDT_TCP_CTRL3__DIDT_STALL_DELAY_EN__SHIFT, 0x0000 },
+
+ /*DIDT_TD_CTRL3 */
+ { ixDIDT_TD_CTRL3, DIDT_TD_CTRL3__GC_DIDT_ENABLE_MASK, DIDT_TD_CTRL3__GC_DIDT_ENABLE__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL3, DIDT_TD_CTRL3__GC_DIDT_CLK_EN_OVERRIDE_MASK, DIDT_TD_CTRL3__GC_DIDT_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL3, DIDT_TD_CTRL3__THROTTLE_POLICY_MASK, DIDT_TD_CTRL3__THROTTLE_POLICY__SHIFT, 0x0003 },
+ { ixDIDT_TD_CTRL3, DIDT_TD_CTRL3__DIDT_TRIGGER_THROTTLE_LOWBIT_MASK, DIDT_TD_CTRL3__DIDT_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL3, DIDT_TD_CTRL3__DIDT_POWER_LEVEL_LOWBIT_MASK, DIDT_TD_CTRL3__DIDT_POWER_LEVEL_LOWBIT__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL3, DIDT_TD_CTRL3__DIDT_STALL_PATTERN_BIT_NUMS_MASK, DIDT_TD_CTRL3__DIDT_STALL_PATTERN_BIT_NUMS__SHIFT, 0x0003 },
+ { ixDIDT_TD_CTRL3, DIDT_TD_CTRL3__GC_DIDT_LEVEL_COMB_EN_MASK, DIDT_TD_CTRL3__GC_DIDT_LEVEL_COMB_EN__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL3, DIDT_TD_CTRL3__SE_DIDT_LEVEL_COMB_EN_MASK, DIDT_TD_CTRL3__SE_DIDT_LEVEL_COMB_EN__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL3, DIDT_TD_CTRL3__QUALIFY_STALL_EN_MASK, DIDT_TD_CTRL3__QUALIFY_STALL_EN__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL3, DIDT_TD_CTRL3__DIDT_STALL_SEL_MASK, DIDT_TD_CTRL3__DIDT_STALL_SEL__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL3, DIDT_TD_CTRL3__DIDT_FORCE_STALL_MASK, DIDT_TD_CTRL3__DIDT_FORCE_STALL__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL3, DIDT_TD_CTRL3__DIDT_STALL_DELAY_EN_MASK, DIDT_TD_CTRL3__DIDT_STALL_DELAY_EN__SHIFT, 0x0000 },
+
+ /*DIDT_DB_CTRL3 */
+ { ixDIDT_DB_CTRL3, DIDT_DB_CTRL3__GC_DIDT_ENABLE_MASK, DIDT_DB_CTRL3__GC_DIDT_ENABLE__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL3, DIDT_DB_CTRL3__GC_DIDT_CLK_EN_OVERRIDE_MASK, DIDT_DB_CTRL3__GC_DIDT_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL3, DIDT_DB_CTRL3__THROTTLE_POLICY_MASK, DIDT_DB_CTRL3__THROTTLE_POLICY__SHIFT, 0x0003 },
+ { ixDIDT_DB_CTRL3, DIDT_DB_CTRL3__DIDT_TRIGGER_THROTTLE_LOWBIT_MASK, DIDT_DB_CTRL3__DIDT_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL3, DIDT_DB_CTRL3__DIDT_POWER_LEVEL_LOWBIT_MASK, DIDT_DB_CTRL3__DIDT_POWER_LEVEL_LOWBIT__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL3, DIDT_DB_CTRL3__DIDT_STALL_PATTERN_BIT_NUMS_MASK, DIDT_DB_CTRL3__DIDT_STALL_PATTERN_BIT_NUMS__SHIFT, 0x0003 },
+ { ixDIDT_DB_CTRL3, DIDT_DB_CTRL3__GC_DIDT_LEVEL_COMB_EN_MASK, DIDT_DB_CTRL3__GC_DIDT_LEVEL_COMB_EN__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL3, DIDT_DB_CTRL3__SE_DIDT_LEVEL_COMB_EN_MASK, DIDT_DB_CTRL3__SE_DIDT_LEVEL_COMB_EN__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL3, DIDT_DB_CTRL3__QUALIFY_STALL_EN_MASK, DIDT_DB_CTRL3__QUALIFY_STALL_EN__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL3, DIDT_DB_CTRL3__DIDT_STALL_SEL_MASK, DIDT_DB_CTRL3__DIDT_STALL_SEL__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL3, DIDT_DB_CTRL3__DIDT_FORCE_STALL_MASK, DIDT_DB_CTRL3__DIDT_FORCE_STALL__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL3, DIDT_DB_CTRL3__DIDT_STALL_DELAY_EN_MASK, DIDT_DB_CTRL3__DIDT_STALL_DELAY_EN__SHIFT, 0x0000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg SEDiDtCtrl2Config_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* DIDT_SQ */
+ { ixDIDT_SQ_CTRL2, DIDT_SQ_CTRL2__MAX_POWER_DELTA_MASK, DIDT_SQ_CTRL2__MAX_POWER_DELTA__SHIFT, 0x3853 },
+ { ixDIDT_SQ_CTRL2, DIDT_SQ_CTRL2__SHORT_TERM_INTERVAL_SIZE_MASK, DIDT_SQ_CTRL2__SHORT_TERM_INTERVAL_SIZE__SHIFT, 0x00c0 },
+ { ixDIDT_SQ_CTRL2, DIDT_SQ_CTRL2__LONG_TERM_INTERVAL_RATIO_MASK, DIDT_SQ_CTRL2__LONG_TERM_INTERVAL_RATIO__SHIFT, 0x0000 },
+
+ /* DIDT_TD */
+ { ixDIDT_TD_CTRL2, DIDT_TD_CTRL2__MAX_POWER_DELTA_MASK, DIDT_TD_CTRL2__MAX_POWER_DELTA__SHIFT, 0x3fff },
+ { ixDIDT_TD_CTRL2, DIDT_TD_CTRL2__SHORT_TERM_INTERVAL_SIZE_MASK, DIDT_TD_CTRL2__SHORT_TERM_INTERVAL_SIZE__SHIFT, 0x00c0 },
+ { ixDIDT_TD_CTRL2, DIDT_TD_CTRL2__LONG_TERM_INTERVAL_RATIO_MASK, DIDT_TD_CTRL2__LONG_TERM_INTERVAL_RATIO__SHIFT, 0x0001 },
+
+ /* DIDT_TCP */
+ { ixDIDT_TCP_CTRL2, DIDT_TCP_CTRL2__MAX_POWER_DELTA_MASK, DIDT_TCP_CTRL2__MAX_POWER_DELTA__SHIFT, 0x3dde },
+ { ixDIDT_TCP_CTRL2, DIDT_TCP_CTRL2__SHORT_TERM_INTERVAL_SIZE_MASK, DIDT_TCP_CTRL2__SHORT_TERM_INTERVAL_SIZE__SHIFT, 0x00c0 },
+ { ixDIDT_TCP_CTRL2, DIDT_TCP_CTRL2__LONG_TERM_INTERVAL_RATIO_MASK, DIDT_TCP_CTRL2__LONG_TERM_INTERVAL_RATIO__SHIFT, 0x0001 },
+
+ /* DIDT_DB */
+ { ixDIDT_DB_CTRL2, DIDT_DB_CTRL2__MAX_POWER_DELTA_MASK, DIDT_DB_CTRL2__MAX_POWER_DELTA__SHIFT, 0x3dde },
+ { ixDIDT_DB_CTRL2, DIDT_DB_CTRL2__SHORT_TERM_INTERVAL_SIZE_MASK, DIDT_DB_CTRL2__SHORT_TERM_INTERVAL_SIZE__SHIFT, 0x00c0 },
+ { ixDIDT_DB_CTRL2, DIDT_DB_CTRL2__LONG_TERM_INTERVAL_RATIO_MASK, DIDT_DB_CTRL2__LONG_TERM_INTERVAL_RATIO__SHIFT, 0x0001 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg SEDiDtCtrl1Config_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* DIDT_SQ */
+ { ixDIDT_SQ_CTRL1, DIDT_SQ_CTRL1__MIN_POWER_MASK, DIDT_SQ_CTRL1__MIN_POWER__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL1, DIDT_SQ_CTRL1__MAX_POWER_MASK, DIDT_SQ_CTRL1__MAX_POWER__SHIFT, 0xffff },
+ /* DIDT_TD */
+ { ixDIDT_TD_CTRL1, DIDT_TD_CTRL1__MIN_POWER_MASK, DIDT_TD_CTRL1__MIN_POWER__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL1, DIDT_TD_CTRL1__MAX_POWER_MASK, DIDT_TD_CTRL1__MAX_POWER__SHIFT, 0xffff },
+ /* DIDT_TCP */
+ { ixDIDT_TCP_CTRL1, DIDT_TCP_CTRL1__MIN_POWER_MASK, DIDT_TCP_CTRL1__MIN_POWER__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL1, DIDT_TCP_CTRL1__MAX_POWER_MASK, DIDT_TCP_CTRL1__MAX_POWER__SHIFT, 0xffff },
+ /* DIDT_DB */
+ { ixDIDT_DB_CTRL1, DIDT_DB_CTRL1__MIN_POWER_MASK, DIDT_DB_CTRL1__MIN_POWER__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL1, DIDT_DB_CTRL1__MAX_POWER_MASK, DIDT_DB_CTRL1__MAX_POWER__SHIFT, 0xffff },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+
+static const struct vega10_didt_config_reg SEDiDtWeightConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* DIDT_SQ */
+ { ixDIDT_SQ_WEIGHT0_3, 0xFFFFFFFF, 0, 0x2B363B1A },
+ { ixDIDT_SQ_WEIGHT4_7, 0xFFFFFFFF, 0, 0x270B2432 },
+ { ixDIDT_SQ_WEIGHT8_11, 0xFFFFFFFF, 0, 0x00000018 },
+
+ /* DIDT_TD */
+ { ixDIDT_TD_WEIGHT0_3, 0xFFFFFFFF, 0, 0x2B1D220F },
+ { ixDIDT_TD_WEIGHT4_7, 0xFFFFFFFF, 0, 0x00007558 },
+ { ixDIDT_TD_WEIGHT8_11, 0xFFFFFFFF, 0, 0x00000000 },
+
+ /* DIDT_TCP */
+ { ixDIDT_TCP_WEIGHT0_3, 0xFFFFFFFF, 0, 0x5ACE160D },
+ { ixDIDT_TCP_WEIGHT4_7, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TCP_WEIGHT8_11, 0xFFFFFFFF, 0, 0x00000000 },
+
+ /* DIDT_DB */
+ { ixDIDT_DB_WEIGHT0_3, 0xFFFFFFFF, 0, 0x0E152A0F },
+ { ixDIDT_DB_WEIGHT4_7, 0xFFFFFFFF, 0, 0x09061813 },
+ { ixDIDT_DB_WEIGHT8_11, 0xFFFFFFFF, 0, 0x00000013 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg SEDiDtCtrl0Config_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* DIDT_SQ */
+ { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__DIDT_CTRL_EN_MASK, DIDT_SQ_CTRL0__DIDT_CTRL_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__PHASE_OFFSET_MASK, DIDT_SQ_CTRL0__PHASE_OFFSET__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__DIDT_CTRL_RST_MASK, DIDT_SQ_CTRL0__DIDT_CTRL_RST__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK, DIDT_SQ_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__DIDT_STALL_CTRL_EN_MASK, DIDT_SQ_CTRL0__DIDT_STALL_CTRL_EN__SHIFT, 0x0001 },
+ { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__DIDT_TUNING_CTRL_EN_MASK, DIDT_SQ_CTRL0__DIDT_TUNING_CTRL_EN__SHIFT, 0x0001 },
+ { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__DIDT_STALL_AUTO_RELEASE_EN_MASK, DIDT_SQ_CTRL0__DIDT_STALL_AUTO_RELEASE_EN__SHIFT, 0x0001 },
+ { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__DIDT_HI_POWER_THRESHOLD_MASK, DIDT_SQ_CTRL0__DIDT_HI_POWER_THRESHOLD__SHIFT, 0xffff },
+ { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__DIDT_AUTO_MPD_EN_MASK, DIDT_SQ_CTRL0__DIDT_AUTO_MPD_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__DIDT_STALL_EVENT_EN_MASK, DIDT_SQ_CTRL0__DIDT_STALL_EVENT_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__DIDT_STALL_EVENT_COUNTER_CLEAR_MASK, DIDT_SQ_CTRL0__DIDT_STALL_EVENT_COUNTER_CLEAR__SHIFT, 0x0000 },
+ /* DIDT_TD */
+ { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__DIDT_CTRL_EN_MASK, DIDT_TD_CTRL0__DIDT_CTRL_EN__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__PHASE_OFFSET_MASK, DIDT_TD_CTRL0__PHASE_OFFSET__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__DIDT_CTRL_RST_MASK, DIDT_TD_CTRL0__DIDT_CTRL_RST__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK, DIDT_TD_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__DIDT_STALL_CTRL_EN_MASK, DIDT_TD_CTRL0__DIDT_STALL_CTRL_EN__SHIFT, 0x0001 },
+ { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__DIDT_TUNING_CTRL_EN_MASK, DIDT_TD_CTRL0__DIDT_TUNING_CTRL_EN__SHIFT, 0x0001 },
+ { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__DIDT_STALL_AUTO_RELEASE_EN_MASK, DIDT_TD_CTRL0__DIDT_STALL_AUTO_RELEASE_EN__SHIFT, 0x0001 },
+ { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__DIDT_HI_POWER_THRESHOLD_MASK, DIDT_TD_CTRL0__DIDT_HI_POWER_THRESHOLD__SHIFT, 0xffff },
+ { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__DIDT_AUTO_MPD_EN_MASK, DIDT_TD_CTRL0__DIDT_AUTO_MPD_EN__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__DIDT_STALL_EVENT_EN_MASK, DIDT_TD_CTRL0__DIDT_STALL_EVENT_EN__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__DIDT_STALL_EVENT_COUNTER_CLEAR_MASK, DIDT_TD_CTRL0__DIDT_STALL_EVENT_COUNTER_CLEAR__SHIFT, 0x0000 },
+ /* DIDT_TCP */
+ { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__DIDT_CTRL_EN_MASK, DIDT_TCP_CTRL0__DIDT_CTRL_EN__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__PHASE_OFFSET_MASK, DIDT_TCP_CTRL0__PHASE_OFFSET__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__DIDT_CTRL_RST_MASK, DIDT_TCP_CTRL0__DIDT_CTRL_RST__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK, DIDT_TCP_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__DIDT_STALL_CTRL_EN_MASK, DIDT_TCP_CTRL0__DIDT_STALL_CTRL_EN__SHIFT, 0x0001 },
+ { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__DIDT_TUNING_CTRL_EN_MASK, DIDT_TCP_CTRL0__DIDT_TUNING_CTRL_EN__SHIFT, 0x0001 },
+ { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__DIDT_STALL_AUTO_RELEASE_EN_MASK, DIDT_TCP_CTRL0__DIDT_STALL_AUTO_RELEASE_EN__SHIFT, 0x0001 },
+ { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__DIDT_HI_POWER_THRESHOLD_MASK, DIDT_TCP_CTRL0__DIDT_HI_POWER_THRESHOLD__SHIFT, 0xffff },
+ { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__DIDT_AUTO_MPD_EN_MASK, DIDT_TCP_CTRL0__DIDT_AUTO_MPD_EN__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__DIDT_STALL_EVENT_EN_MASK, DIDT_TCP_CTRL0__DIDT_STALL_EVENT_EN__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__DIDT_STALL_EVENT_COUNTER_CLEAR_MASK, DIDT_TCP_CTRL0__DIDT_STALL_EVENT_COUNTER_CLEAR__SHIFT, 0x0000 },
+ /* DIDT_DB */
+ { ixDIDT_DB_CTRL0, DIDT_DB_CTRL0__DIDT_CTRL_EN_MASK, DIDT_DB_CTRL0__DIDT_CTRL_EN__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL0, DIDT_DB_CTRL0__PHASE_OFFSET_MASK, DIDT_DB_CTRL0__PHASE_OFFSET__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL0, DIDT_DB_CTRL0__DIDT_CTRL_RST_MASK, DIDT_DB_CTRL0__DIDT_CTRL_RST__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL0, DIDT_DB_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK, DIDT_DB_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL0, DIDT_DB_CTRL0__DIDT_STALL_CTRL_EN_MASK, DIDT_DB_CTRL0__DIDT_STALL_CTRL_EN__SHIFT, 0x0001 },
+ { ixDIDT_DB_CTRL0, DIDT_DB_CTRL0__DIDT_TUNING_CTRL_EN_MASK, DIDT_DB_CTRL0__DIDT_TUNING_CTRL_EN__SHIFT, 0x0001 },
+ { ixDIDT_DB_CTRL0, DIDT_DB_CTRL0__DIDT_STALL_AUTO_RELEASE_EN_MASK, DIDT_DB_CTRL0__DIDT_STALL_AUTO_RELEASE_EN__SHIFT, 0x0001 },
+ { ixDIDT_DB_CTRL0, DIDT_DB_CTRL0__DIDT_HI_POWER_THRESHOLD_MASK, DIDT_DB_CTRL0__DIDT_HI_POWER_THRESHOLD__SHIFT, 0xffff },
+ { ixDIDT_DB_CTRL0, DIDT_DB_CTRL0__DIDT_AUTO_MPD_EN_MASK, DIDT_DB_CTRL0__DIDT_AUTO_MPD_EN__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL0, DIDT_DB_CTRL0__DIDT_STALL_EVENT_EN_MASK, DIDT_DB_CTRL0__DIDT_STALL_EVENT_EN__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL0, DIDT_DB_CTRL0__DIDT_STALL_EVENT_COUNTER_CLEAR_MASK, DIDT_DB_CTRL0__DIDT_STALL_EVENT_COUNTER_CLEAR__SHIFT, 0x0000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+
+static const struct vega10_didt_config_reg SEDiDtStallCtrlConfig_vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* DIDT_SQ */
+ { ixDIDT_SQ_STALL_CTRL, DIDT_SQ_STALL_CTRL__DIDT_STALL_DELAY_HI_MASK, DIDT_SQ_STALL_CTRL__DIDT_STALL_DELAY_HI__SHIFT, 0x0004 },
+ { ixDIDT_SQ_STALL_CTRL, DIDT_SQ_STALL_CTRL__DIDT_STALL_DELAY_LO_MASK, DIDT_SQ_STALL_CTRL__DIDT_STALL_DELAY_LO__SHIFT, 0x0004 },
+ { ixDIDT_SQ_STALL_CTRL, DIDT_SQ_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_HI_MASK, DIDT_SQ_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_HI__SHIFT, 0x000a },
+ { ixDIDT_SQ_STALL_CTRL, DIDT_SQ_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_LO_MASK, DIDT_SQ_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_LO__SHIFT, 0x000a },
+
+ /* DIDT_TD */
+ { ixDIDT_TD_STALL_CTRL, DIDT_TD_STALL_CTRL__DIDT_STALL_DELAY_HI_MASK, DIDT_TD_STALL_CTRL__DIDT_STALL_DELAY_HI__SHIFT, 0x0001 },
+ { ixDIDT_TD_STALL_CTRL, DIDT_TD_STALL_CTRL__DIDT_STALL_DELAY_LO_MASK, DIDT_TD_STALL_CTRL__DIDT_STALL_DELAY_LO__SHIFT, 0x0001 },
+ { ixDIDT_TD_STALL_CTRL, DIDT_TD_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_HI_MASK, DIDT_TD_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_HI__SHIFT, 0x000a },
+ { ixDIDT_TD_STALL_CTRL, DIDT_TD_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_LO_MASK, DIDT_TD_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_LO__SHIFT, 0x000a },
+
+ /* DIDT_TCP */
+ { ixDIDT_TCP_STALL_CTRL, DIDT_TCP_STALL_CTRL__DIDT_STALL_DELAY_HI_MASK, DIDT_TCP_STALL_CTRL__DIDT_STALL_DELAY_HI__SHIFT, 0x0001 },
+ { ixDIDT_TCP_STALL_CTRL, DIDT_TCP_STALL_CTRL__DIDT_STALL_DELAY_LO_MASK, DIDT_TCP_STALL_CTRL__DIDT_STALL_DELAY_LO__SHIFT, 0x0001 },
+ { ixDIDT_TCP_STALL_CTRL, DIDT_TCP_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_HI_MASK, DIDT_TCP_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_HI__SHIFT, 0x000a },
+ { ixDIDT_TCP_STALL_CTRL, DIDT_TCP_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_LO_MASK, DIDT_TCP_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_LO__SHIFT, 0x000a },
+
+ /* DIDT_DB */
+ { ixDIDT_DB_STALL_CTRL, DIDT_DB_STALL_CTRL__DIDT_STALL_DELAY_HI_MASK, DIDT_DB_STALL_CTRL__DIDT_STALL_DELAY_HI__SHIFT, 0x0004 },
+ { ixDIDT_DB_STALL_CTRL, DIDT_DB_STALL_CTRL__DIDT_STALL_DELAY_LO_MASK, DIDT_DB_STALL_CTRL__DIDT_STALL_DELAY_LO__SHIFT, 0x0004 },
+ { ixDIDT_DB_STALL_CTRL, DIDT_DB_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_HI_MASK, DIDT_DB_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_HI__SHIFT, 0x000a },
+ { ixDIDT_DB_STALL_CTRL, DIDT_DB_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_LO_MASK, DIDT_DB_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_LO__SHIFT, 0x000a },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg SEDiDtStallPatternConfig_vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* DIDT_SQ_STALL_PATTERN_1_2 */
+ { ixDIDT_SQ_STALL_PATTERN_1_2, DIDT_SQ_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_1_MASK, DIDT_SQ_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_1__SHIFT, 0x0001 },
+ { ixDIDT_SQ_STALL_PATTERN_1_2, DIDT_SQ_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_2_MASK, DIDT_SQ_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_2__SHIFT, 0x0001 },
+
+ /* DIDT_SQ_STALL_PATTERN_3_4 */
+ { ixDIDT_SQ_STALL_PATTERN_3_4, DIDT_SQ_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_3_MASK, DIDT_SQ_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_3__SHIFT, 0x0001 },
+ { ixDIDT_SQ_STALL_PATTERN_3_4, DIDT_SQ_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_4_MASK, DIDT_SQ_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_4__SHIFT, 0x0001 },
+
+ /* DIDT_SQ_STALL_PATTERN_5_6 */
+ { ixDIDT_SQ_STALL_PATTERN_5_6, DIDT_SQ_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_5_MASK, DIDT_SQ_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_5__SHIFT, 0x0000 },
+ { ixDIDT_SQ_STALL_PATTERN_5_6, DIDT_SQ_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_6_MASK, DIDT_SQ_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_6__SHIFT, 0x0000 },
+
+ /* DIDT_SQ_STALL_PATTERN_7 */
+ { ixDIDT_SQ_STALL_PATTERN_7, DIDT_SQ_STALL_PATTERN_7__DIDT_STALL_PATTERN_7_MASK, DIDT_SQ_STALL_PATTERN_7__DIDT_STALL_PATTERN_7__SHIFT, 0x0000 },
+
+ /* DIDT_TCP_STALL_PATTERN_1_2 */
+ { ixDIDT_TCP_STALL_PATTERN_1_2, DIDT_TCP_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_1_MASK, DIDT_TCP_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_1__SHIFT, 0x0001 },
+ { ixDIDT_TCP_STALL_PATTERN_1_2, DIDT_TCP_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_2_MASK, DIDT_TCP_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_2__SHIFT, 0x0001 },
+
+ /* DIDT_TCP_STALL_PATTERN_3_4 */
+ { ixDIDT_TCP_STALL_PATTERN_3_4, DIDT_TCP_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_3_MASK, DIDT_TCP_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_3__SHIFT, 0x0001 },
+ { ixDIDT_TCP_STALL_PATTERN_3_4, DIDT_TCP_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_4_MASK, DIDT_TCP_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_4__SHIFT, 0x0001 },
+
+ /* DIDT_TCP_STALL_PATTERN_5_6 */
+ { ixDIDT_TCP_STALL_PATTERN_5_6, DIDT_TCP_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_5_MASK, DIDT_TCP_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_5__SHIFT, 0x0000 },
+ { ixDIDT_TCP_STALL_PATTERN_5_6, DIDT_TCP_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_6_MASK, DIDT_TCP_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_6__SHIFT, 0x0000 },
+
+ /* DIDT_TCP_STALL_PATTERN_7 */
+ { ixDIDT_TCP_STALL_PATTERN_7, DIDT_TCP_STALL_PATTERN_7__DIDT_STALL_PATTERN_7_MASK, DIDT_TCP_STALL_PATTERN_7__DIDT_STALL_PATTERN_7__SHIFT, 0x0000 },
+
+ /* DIDT_TD_STALL_PATTERN_1_2 */
+ { ixDIDT_TD_STALL_PATTERN_1_2, DIDT_TD_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_1_MASK, DIDT_TD_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_1__SHIFT, 0x0001 },
+ { ixDIDT_TD_STALL_PATTERN_1_2, DIDT_TD_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_2_MASK, DIDT_TD_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_2__SHIFT, 0x0001 },
+
+ /* DIDT_TD_STALL_PATTERN_3_4 */
+ { ixDIDT_TD_STALL_PATTERN_3_4, DIDT_TD_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_3_MASK, DIDT_TD_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_3__SHIFT, 0x0001 },
+ { ixDIDT_TD_STALL_PATTERN_3_4, DIDT_TD_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_4_MASK, DIDT_TD_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_4__SHIFT, 0x0001 },
+
+ /* DIDT_TD_STALL_PATTERN_5_6 */
+ { ixDIDT_TD_STALL_PATTERN_5_6, DIDT_TD_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_5_MASK, DIDT_TD_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_5__SHIFT, 0x0000 },
+ { ixDIDT_TD_STALL_PATTERN_5_6, DIDT_TD_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_6_MASK, DIDT_TD_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_6__SHIFT, 0x0000 },
+
+ /* DIDT_TD_STALL_PATTERN_7 */
+ { ixDIDT_TD_STALL_PATTERN_7, DIDT_TD_STALL_PATTERN_7__DIDT_STALL_PATTERN_7_MASK, DIDT_TD_STALL_PATTERN_7__DIDT_STALL_PATTERN_7__SHIFT, 0x0000 },
+
+ /* DIDT_DB_STALL_PATTERN_1_2 */
+ { ixDIDT_DB_STALL_PATTERN_1_2, DIDT_DB_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_1_MASK, DIDT_DB_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_1__SHIFT, 0x0001 },
+ { ixDIDT_DB_STALL_PATTERN_1_2, DIDT_DB_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_2_MASK, DIDT_DB_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_2__SHIFT, 0x0001 },
+
+ /* DIDT_DB_STALL_PATTERN_3_4 */
+ { ixDIDT_DB_STALL_PATTERN_3_4, DIDT_DB_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_3_MASK, DIDT_DB_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_3__SHIFT, 0x0001 },
+ { ixDIDT_DB_STALL_PATTERN_3_4, DIDT_DB_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_4_MASK, DIDT_DB_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_4__SHIFT, 0x0001 },
+
+ /* DIDT_DB_STALL_PATTERN_5_6 */
+ { ixDIDT_DB_STALL_PATTERN_5_6, DIDT_DB_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_5_MASK, DIDT_DB_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_5__SHIFT, 0x0000 },
+ { ixDIDT_DB_STALL_PATTERN_5_6, DIDT_DB_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_6_MASK, DIDT_DB_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_6__SHIFT, 0x0000 },
+
+ /* DIDT_DB_STALL_PATTERN_7 */
+ { ixDIDT_DB_STALL_PATTERN_7, DIDT_DB_STALL_PATTERN_7__DIDT_STALL_PATTERN_7_MASK, DIDT_DB_STALL_PATTERN_7__DIDT_STALL_PATTERN_7__SHIFT, 0x0000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg SELCacConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* SQ */
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x00060021 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x00860021 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x01060021 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x01860021 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x02060021 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x02860021 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x03060021 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x03860021 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x04060021 },
+ /* TD */
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x000E0020 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x008E0020 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x010E0020 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x018E0020 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x020E0020 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x028E0020 },
+ /* TCP */
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x001c0020 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x009c0020 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x011c0020 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x019c0020 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x021c0020 },
+ /* DB */
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x00200008 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x00820008 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x01020008 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x01820008 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+
+static const struct vega10_didt_config_reg SEEDCStallPatternConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* SQ */
+ { ixDIDT_SQ_EDC_STALL_PATTERN_1_2, 0xFFFFFFFF, 0, 0x00030001 },
+ { ixDIDT_SQ_EDC_STALL_PATTERN_3_4, 0xFFFFFFFF, 0, 0x000F0007 },
+ { ixDIDT_SQ_EDC_STALL_PATTERN_5_6, 0xFFFFFFFF, 0, 0x003F001F },
+ { ixDIDT_SQ_EDC_STALL_PATTERN_7, 0xFFFFFFFF, 0, 0x0000007F },
+ /* TD */
+ { ixDIDT_TD_EDC_STALL_PATTERN_1_2, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TD_EDC_STALL_PATTERN_3_4, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TD_EDC_STALL_PATTERN_5_6, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TD_EDC_STALL_PATTERN_7, 0xFFFFFFFF, 0, 0x00000000 },
+ /* TCP */
+ { ixDIDT_TCP_EDC_STALL_PATTERN_1_2, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TCP_EDC_STALL_PATTERN_3_4, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TCP_EDC_STALL_PATTERN_5_6, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TCP_EDC_STALL_PATTERN_7, 0xFFFFFFFF, 0, 0x00000000 },
+ /* DB */
+ { ixDIDT_DB_EDC_STALL_PATTERN_1_2, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_DB_EDC_STALL_PATTERN_3_4, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_DB_EDC_STALL_PATTERN_5_6, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_DB_EDC_STALL_PATTERN_7, 0xFFFFFFFF, 0, 0x00000000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg SEEDCForceStallPatternConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* SQ */
+ { ixDIDT_SQ_EDC_STALL_PATTERN_1_2, 0xFFFFFFFF, 0, 0x00000015 },
+ { ixDIDT_SQ_EDC_STALL_PATTERN_3_4, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_SQ_EDC_STALL_PATTERN_5_6, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_SQ_EDC_STALL_PATTERN_7, 0xFFFFFFFF, 0, 0x00000000 },
+ /* TD */
+ { ixDIDT_TD_EDC_STALL_PATTERN_1_2, 0xFFFFFFFF, 0, 0x00000015 },
+ { ixDIDT_TD_EDC_STALL_PATTERN_3_4, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TD_EDC_STALL_PATTERN_5_6, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TD_EDC_STALL_PATTERN_7, 0xFFFFFFFF, 0, 0x00000000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg SEEDCStallDelayConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* SQ */
+ { ixDIDT_SQ_EDC_STALL_DELAY_1, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_2, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_3, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_4, 0xFFFFFFFF, 0, 0x00000000 },
+ /* TD */
+ { ixDIDT_TD_EDC_STALL_DELAY_1, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TD_EDC_STALL_DELAY_2, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TD_EDC_STALL_DELAY_3, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TD_EDC_STALL_DELAY_4, 0xFFFFFFFF, 0, 0x00000000 },
+ /* TCP */
+ { ixDIDT_TCP_EDC_STALL_DELAY_1, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TCP_EDC_STALL_DELAY_2, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TCP_EDC_STALL_DELAY_3, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TCP_EDC_STALL_DELAY_4, 0xFFFFFFFF, 0, 0x00000000 },
+ /* DB */
+ { ixDIDT_DB_EDC_STALL_DELAY_1, 0xFFFFFFFF, 0, 0x00000000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg SEEDCThresholdConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ { ixDIDT_SQ_EDC_THRESHOLD, 0xFFFFFFFF, 0, 0x0000010E },
+ { ixDIDT_TD_EDC_THRESHOLD, 0xFFFFFFFF, 0, 0xFFFFFFFF },
+ { ixDIDT_TCP_EDC_THRESHOLD, 0xFFFFFFFF, 0, 0xFFFFFFFF },
+ { ixDIDT_DB_EDC_THRESHOLD, 0xFFFFFFFF, 0, 0xFFFFFFFF },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg SEEDCCtrlResetConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* SQ */
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_EN_MASK, DIDT_SQ_EDC_CTRL__EDC_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_SW_RST_MASK, DIDT_SQ_EDC_CTRL__EDC_SW_RST__SHIFT, 0x0001 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_CLK_EN_OVERRIDE_MASK, DIDT_SQ_EDC_CTRL__EDC_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_FORCE_STALL_MASK, DIDT_SQ_EDC_CTRL__EDC_FORCE_STALL__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT_MASK, DIDT_SQ_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_STALL_PATTERN_BIT_NUMS_MASK, DIDT_SQ_EDC_CTRL__EDC_STALL_PATTERN_BIT_NUMS__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA_MASK, DIDT_SQ_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_EN_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_STALL_POLICY_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_STALL_POLICY__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_LEVEL_COMB_EN_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_LEVEL_COMB_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__SE_EDC_LEVEL_COMB_EN_MASK, DIDT_SQ_EDC_CTRL__SE_EDC_LEVEL_COMB_EN__SHIFT, 0x0000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg SEEDCCtrlConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* SQ */
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_EN_MASK, DIDT_SQ_EDC_CTRL__EDC_EN__SHIFT, 0x0001 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_SW_RST_MASK, DIDT_SQ_EDC_CTRL__EDC_SW_RST__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_CLK_EN_OVERRIDE_MASK, DIDT_SQ_EDC_CTRL__EDC_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_FORCE_STALL_MASK, DIDT_SQ_EDC_CTRL__EDC_FORCE_STALL__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT_MASK, DIDT_SQ_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0004 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_STALL_PATTERN_BIT_NUMS_MASK, DIDT_SQ_EDC_CTRL__EDC_STALL_PATTERN_BIT_NUMS__SHIFT, 0x0006 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA_MASK, DIDT_SQ_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_EN_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_STALL_POLICY_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_STALL_POLICY__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_LEVEL_COMB_EN_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_LEVEL_COMB_EN__SHIFT, 0x0001 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__SE_EDC_LEVEL_COMB_EN_MASK, DIDT_SQ_EDC_CTRL__SE_EDC_LEVEL_COMB_EN__SHIFT, 0x0000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg SEEDCCtrlForceStallConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* SQ */
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_EN_MASK, DIDT_SQ_EDC_CTRL__EDC_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_SW_RST_MASK, DIDT_SQ_EDC_CTRL__EDC_SW_RST__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_CLK_EN_OVERRIDE_MASK, DIDT_SQ_EDC_CTRL__EDC_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_FORCE_STALL_MASK, DIDT_SQ_EDC_CTRL__EDC_FORCE_STALL__SHIFT, 0x0001 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT_MASK, DIDT_SQ_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0001 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_STALL_PATTERN_BIT_NUMS_MASK, DIDT_SQ_EDC_CTRL__EDC_STALL_PATTERN_BIT_NUMS__SHIFT, 0x000C },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA_MASK, DIDT_SQ_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_EN_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_STALL_POLICY_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_STALL_POLICY__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_LEVEL_COMB_EN_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_LEVEL_COMB_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__SE_EDC_LEVEL_COMB_EN_MASK, DIDT_SQ_EDC_CTRL__SE_EDC_LEVEL_COMB_EN__SHIFT, 0x0001 },
+
+ /* TD */
+ { ixDIDT_TD_EDC_CTRL, DIDT_TD_EDC_CTRL__EDC_EN_MASK, DIDT_TD_EDC_CTRL__EDC_EN__SHIFT, 0x0000 },
+ { ixDIDT_TD_EDC_CTRL, DIDT_TD_EDC_CTRL__EDC_SW_RST_MASK, DIDT_TD_EDC_CTRL__EDC_SW_RST__SHIFT, 0x0000 },
+ { ixDIDT_TD_EDC_CTRL, DIDT_TD_EDC_CTRL__EDC_CLK_EN_OVERRIDE_MASK, DIDT_TD_EDC_CTRL__EDC_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_TD_EDC_CTRL, DIDT_TD_EDC_CTRL__EDC_FORCE_STALL_MASK, DIDT_TD_EDC_CTRL__EDC_FORCE_STALL__SHIFT, 0x0001 },
+ { ixDIDT_TD_EDC_CTRL, DIDT_TD_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT_MASK, DIDT_TD_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0001 },
+ { ixDIDT_TD_EDC_CTRL, DIDT_TD_EDC_CTRL__EDC_STALL_PATTERN_BIT_NUMS_MASK, DIDT_TD_EDC_CTRL__EDC_STALL_PATTERN_BIT_NUMS__SHIFT, 0x000E },
+ { ixDIDT_TD_EDC_CTRL, DIDT_TD_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA_MASK, DIDT_TD_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA__SHIFT, 0x0000 },
+ { ixDIDT_TD_EDC_CTRL, DIDT_TD_EDC_CTRL__GC_EDC_EN_MASK, DIDT_TD_EDC_CTRL__GC_EDC_EN__SHIFT, 0x0000 },
+ { ixDIDT_TD_EDC_CTRL, DIDT_TD_EDC_CTRL__GC_EDC_STALL_POLICY_MASK, DIDT_TD_EDC_CTRL__GC_EDC_STALL_POLICY__SHIFT, 0x0000 },
+ { ixDIDT_TD_EDC_CTRL, DIDT_TD_EDC_CTRL__GC_EDC_LEVEL_COMB_EN_MASK, DIDT_TD_EDC_CTRL__GC_EDC_LEVEL_COMB_EN__SHIFT, 0x0000 },
+ { ixDIDT_TD_EDC_CTRL, DIDT_TD_EDC_CTRL__SE_EDC_LEVEL_COMB_EN_MASK, DIDT_TD_EDC_CTRL__SE_EDC_LEVEL_COMB_EN__SHIFT, 0x0001 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg GCDiDtDroopCtrlConfig_vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ { mmGC_DIDT_DROOP_CTRL, GC_DIDT_DROOP_CTRL__DIDT_DROOP_LEVEL_EN_MASK, GC_DIDT_DROOP_CTRL__DIDT_DROOP_LEVEL_EN__SHIFT, 0x0000 },
+ { mmGC_DIDT_DROOP_CTRL, GC_DIDT_DROOP_CTRL__DIDT_DROOP_THRESHOLD_MASK, GC_DIDT_DROOP_CTRL__DIDT_DROOP_THRESHOLD__SHIFT, 0x0000 },
+ { mmGC_DIDT_DROOP_CTRL, GC_DIDT_DROOP_CTRL__DIDT_DROOP_LEVEL_INDEX_MASK, GC_DIDT_DROOP_CTRL__DIDT_DROOP_LEVEL_INDEX__SHIFT, 0x0000 },
+ { mmGC_DIDT_DROOP_CTRL, GC_DIDT_DROOP_CTRL__DIDT_LEVEL_SEL_MASK, GC_DIDT_DROOP_CTRL__DIDT_LEVEL_SEL__SHIFT, 0x0000 },
+ { mmGC_DIDT_DROOP_CTRL, GC_DIDT_DROOP_CTRL__DIDT_DROOP_LEVEL_OVERFLOW_MASK, GC_DIDT_DROOP_CTRL__DIDT_DROOP_LEVEL_OVERFLOW__SHIFT, 0x0000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg GCDiDtCtrl0Config_vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ { mmGC_DIDT_CTRL0, GC_DIDT_CTRL0__DIDT_CTRL_EN_MASK, GC_DIDT_CTRL0__DIDT_CTRL_EN__SHIFT, 0x0000 },
+ { mmGC_DIDT_CTRL0, GC_DIDT_CTRL0__PHASE_OFFSET_MASK, GC_DIDT_CTRL0__PHASE_OFFSET__SHIFT, 0x0000 },
+ { mmGC_DIDT_CTRL0, GC_DIDT_CTRL0__DIDT_SW_RST_MASK, GC_DIDT_CTRL0__DIDT_SW_RST__SHIFT, 0x0000 },
+ { mmGC_DIDT_CTRL0, GC_DIDT_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK, GC_DIDT_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { mmGC_DIDT_CTRL0, GC_DIDT_CTRL0__DIDT_TRIGGER_THROTTLE_LOWBIT_MASK, GC_DIDT_CTRL0__DIDT_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0000 },
+ { 0xFFFFFFFF } /* End of list */
+};
+
+
+static const struct vega10_didt_config_reg PSMSEEDCStallPatternConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* SQ EDC STALL PATTERNs */
+ { ixDIDT_SQ_EDC_STALL_PATTERN_1_2, DIDT_SQ_EDC_STALL_PATTERN_1_2__EDC_STALL_PATTERN_1_MASK, DIDT_SQ_EDC_STALL_PATTERN_1_2__EDC_STALL_PATTERN_1__SHIFT, 0x0101 },
+ { ixDIDT_SQ_EDC_STALL_PATTERN_1_2, DIDT_SQ_EDC_STALL_PATTERN_1_2__EDC_STALL_PATTERN_2_MASK, DIDT_SQ_EDC_STALL_PATTERN_1_2__EDC_STALL_PATTERN_2__SHIFT, 0x0101 },
+ { ixDIDT_SQ_EDC_STALL_PATTERN_3_4, DIDT_SQ_EDC_STALL_PATTERN_3_4__EDC_STALL_PATTERN_3_MASK, DIDT_SQ_EDC_STALL_PATTERN_3_4__EDC_STALL_PATTERN_3__SHIFT, 0x1111 },
+ { ixDIDT_SQ_EDC_STALL_PATTERN_3_4, DIDT_SQ_EDC_STALL_PATTERN_3_4__EDC_STALL_PATTERN_4_MASK, DIDT_SQ_EDC_STALL_PATTERN_3_4__EDC_STALL_PATTERN_4__SHIFT, 0x1111 },
+
+ { ixDIDT_SQ_EDC_STALL_PATTERN_5_6, DIDT_SQ_EDC_STALL_PATTERN_5_6__EDC_STALL_PATTERN_5_MASK, DIDT_SQ_EDC_STALL_PATTERN_5_6__EDC_STALL_PATTERN_5__SHIFT, 0x1515 },
+ { ixDIDT_SQ_EDC_STALL_PATTERN_5_6, DIDT_SQ_EDC_STALL_PATTERN_5_6__EDC_STALL_PATTERN_6_MASK, DIDT_SQ_EDC_STALL_PATTERN_5_6__EDC_STALL_PATTERN_6__SHIFT, 0x1515 },
+
+ { ixDIDT_SQ_EDC_STALL_PATTERN_7, DIDT_SQ_EDC_STALL_PATTERN_7__EDC_STALL_PATTERN_7_MASK, DIDT_SQ_EDC_STALL_PATTERN_7__EDC_STALL_PATTERN_7__SHIFT, 0x5555 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg PSMSEEDCStallDelayConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* SQ EDC STALL DELAYs */
+ { ixDIDT_SQ_EDC_STALL_DELAY_1, DIDT_SQ_EDC_STALL_DELAY_1__EDC_STALL_DELAY_SQ0_MASK, DIDT_SQ_EDC_STALL_DELAY_1__EDC_STALL_DELAY_SQ0__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_1, DIDT_SQ_EDC_STALL_DELAY_1__EDC_STALL_DELAY_SQ1_MASK, DIDT_SQ_EDC_STALL_DELAY_1__EDC_STALL_DELAY_SQ1__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_1, DIDT_SQ_EDC_STALL_DELAY_1__EDC_STALL_DELAY_SQ2_MASK, DIDT_SQ_EDC_STALL_DELAY_1__EDC_STALL_DELAY_SQ2__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_1, DIDT_SQ_EDC_STALL_DELAY_1__EDC_STALL_DELAY_SQ3_MASK, DIDT_SQ_EDC_STALL_DELAY_1__EDC_STALL_DELAY_SQ3__SHIFT, 0x0000 },
+
+ { ixDIDT_SQ_EDC_STALL_DELAY_2, DIDT_SQ_EDC_STALL_DELAY_2__EDC_STALL_DELAY_SQ4_MASK, DIDT_SQ_EDC_STALL_DELAY_2__EDC_STALL_DELAY_SQ4__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_2, DIDT_SQ_EDC_STALL_DELAY_2__EDC_STALL_DELAY_SQ5_MASK, DIDT_SQ_EDC_STALL_DELAY_2__EDC_STALL_DELAY_SQ5__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_2, DIDT_SQ_EDC_STALL_DELAY_2__EDC_STALL_DELAY_SQ6_MASK, DIDT_SQ_EDC_STALL_DELAY_2__EDC_STALL_DELAY_SQ6__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_2, DIDT_SQ_EDC_STALL_DELAY_2__EDC_STALL_DELAY_SQ7_MASK, DIDT_SQ_EDC_STALL_DELAY_2__EDC_STALL_DELAY_SQ7__SHIFT, 0x0000 },
+
+ { ixDIDT_SQ_EDC_STALL_DELAY_3, DIDT_SQ_EDC_STALL_DELAY_3__EDC_STALL_DELAY_SQ8_MASK, DIDT_SQ_EDC_STALL_DELAY_3__EDC_STALL_DELAY_SQ8__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_3, DIDT_SQ_EDC_STALL_DELAY_3__EDC_STALL_DELAY_SQ9_MASK, DIDT_SQ_EDC_STALL_DELAY_3__EDC_STALL_DELAY_SQ9__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_3, DIDT_SQ_EDC_STALL_DELAY_3__EDC_STALL_DELAY_SQ10_MASK, DIDT_SQ_EDC_STALL_DELAY_3__EDC_STALL_DELAY_SQ10__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_3, DIDT_SQ_EDC_STALL_DELAY_3__EDC_STALL_DELAY_SQ11_MASK, DIDT_SQ_EDC_STALL_DELAY_3__EDC_STALL_DELAY_SQ11__SHIFT, 0x0000 },
+
+ { ixDIDT_SQ_EDC_STALL_DELAY_4, DIDT_SQ_EDC_STALL_DELAY_4__EDC_STALL_DELAY_SQ12_MASK, DIDT_SQ_EDC_STALL_DELAY_4__EDC_STALL_DELAY_SQ12__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_4, DIDT_SQ_EDC_STALL_DELAY_4__EDC_STALL_DELAY_SQ12_MASK, DIDT_SQ_EDC_STALL_DELAY_4__EDC_STALL_DELAY_SQ13__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_4, DIDT_SQ_EDC_STALL_DELAY_4__EDC_STALL_DELAY_SQ14_MASK, DIDT_SQ_EDC_STALL_DELAY_4__EDC_STALL_DELAY_SQ14__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_4, DIDT_SQ_EDC_STALL_DELAY_4__EDC_STALL_DELAY_SQ15_MASK, DIDT_SQ_EDC_STALL_DELAY_4__EDC_STALL_DELAY_SQ15__SHIFT, 0x0000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg PSMSEEDCThresholdConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* SQ EDC THRESHOLD */
+ { ixDIDT_SQ_EDC_THRESHOLD, DIDT_SQ_EDC_THRESHOLD__EDC_THRESHOLD_MASK, DIDT_SQ_EDC_THRESHOLD__EDC_THRESHOLD__SHIFT, 0x0000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg PSMSEEDCCtrlResetConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* SQ EDC CTRL */
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_EN_MASK, DIDT_SQ_EDC_CTRL__EDC_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_SW_RST_MASK, DIDT_SQ_EDC_CTRL__EDC_SW_RST__SHIFT, 0x0001 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_CLK_EN_OVERRIDE_MASK, DIDT_SQ_EDC_CTRL__EDC_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_FORCE_STALL_MASK, DIDT_SQ_EDC_CTRL__EDC_FORCE_STALL__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT_MASK, DIDT_SQ_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_STALL_PATTERN_BIT_NUMS_MASK, DIDT_SQ_EDC_CTRL__EDC_STALL_PATTERN_BIT_NUMS__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA_MASK, DIDT_SQ_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_EN_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_STALL_POLICY_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_STALL_POLICY__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_LEVEL_COMB_EN_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_LEVEL_COMB_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__SE_EDC_LEVEL_COMB_EN_MASK, DIDT_SQ_EDC_CTRL__SE_EDC_LEVEL_COMB_EN__SHIFT, 0x0000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg PSMSEEDCCtrlConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* SQ EDC CTRL */
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_EN_MASK, DIDT_SQ_EDC_CTRL__EDC_EN__SHIFT, 0x0001 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_SW_RST_MASK, DIDT_SQ_EDC_CTRL__EDC_SW_RST__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_CLK_EN_OVERRIDE_MASK, DIDT_SQ_EDC_CTRL__EDC_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_FORCE_STALL_MASK, DIDT_SQ_EDC_CTRL__EDC_FORCE_STALL__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT_MASK, DIDT_SQ_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_STALL_PATTERN_BIT_NUMS_MASK, DIDT_SQ_EDC_CTRL__EDC_STALL_PATTERN_BIT_NUMS__SHIFT, 0x000E },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA_MASK, DIDT_SQ_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_EN_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_EN__SHIFT, 0x0001 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_STALL_POLICY_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_STALL_POLICY__SHIFT, 0x0003 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_LEVEL_COMB_EN_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_LEVEL_COMB_EN__SHIFT, 0x0001 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__SE_EDC_LEVEL_COMB_EN_MASK, DIDT_SQ_EDC_CTRL__SE_EDC_LEVEL_COMB_EN__SHIFT, 0x0000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg PSMGCEDCThresholdConfig_vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ { mmGC_EDC_THRESHOLD, GC_EDC_THRESHOLD__EDC_THRESHOLD_MASK, GC_EDC_THRESHOLD__EDC_THRESHOLD__SHIFT, 0x0000000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg PSMGCEDCDroopCtrlConfig_vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ { mmGC_EDC_DROOP_CTRL, GC_EDC_DROOP_CTRL__EDC_DROOP_LEVEL_EN_MASK, GC_EDC_DROOP_CTRL__EDC_DROOP_LEVEL_EN__SHIFT, 0x0001 },
+ { mmGC_EDC_DROOP_CTRL, GC_EDC_DROOP_CTRL__EDC_DROOP_THRESHOLD_MASK, GC_EDC_DROOP_CTRL__EDC_DROOP_THRESHOLD__SHIFT, 0x0384 },
+ { mmGC_EDC_DROOP_CTRL, GC_EDC_DROOP_CTRL__EDC_DROOP_LEVEL_INDEX_MASK, GC_EDC_DROOP_CTRL__EDC_DROOP_LEVEL_INDEX__SHIFT, 0x0001 },
+ { mmGC_EDC_DROOP_CTRL, GC_EDC_DROOP_CTRL__AVG_PSM_SEL_MASK, GC_EDC_DROOP_CTRL__AVG_PSM_SEL__SHIFT, 0x0001 },
+ { mmGC_EDC_DROOP_CTRL, GC_EDC_DROOP_CTRL__EDC_LEVEL_SEL_MASK, GC_EDC_DROOP_CTRL__EDC_LEVEL_SEL__SHIFT, 0x0001 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg PSMGCEDCCtrlResetConfig_vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ { mmGC_EDC_CTRL, GC_EDC_CTRL__EDC_EN_MASK, GC_EDC_CTRL__EDC_EN__SHIFT, 0x0000 },
+ { mmGC_EDC_CTRL, GC_EDC_CTRL__EDC_SW_RST_MASK, GC_EDC_CTRL__EDC_SW_RST__SHIFT, 0x0001 },
+ { mmGC_EDC_CTRL, GC_EDC_CTRL__EDC_CLK_EN_OVERRIDE_MASK, GC_EDC_CTRL__EDC_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { mmGC_EDC_CTRL, GC_EDC_CTRL__EDC_FORCE_STALL_MASK, GC_EDC_CTRL__EDC_FORCE_STALL__SHIFT, 0x0000 },
+ { mmGC_EDC_CTRL, GC_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT_MASK, GC_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0000 },
+ { mmGC_EDC_CTRL, GC_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA_MASK, GC_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA__SHIFT, 0x0000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg PSMGCEDCCtrlConfig_vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ { mmGC_EDC_CTRL, GC_EDC_CTRL__EDC_EN_MASK, GC_EDC_CTRL__EDC_EN__SHIFT, 0x0001 },
+ { mmGC_EDC_CTRL, GC_EDC_CTRL__EDC_SW_RST_MASK, GC_EDC_CTRL__EDC_SW_RST__SHIFT, 0x0000 },
+ { mmGC_EDC_CTRL, GC_EDC_CTRL__EDC_CLK_EN_OVERRIDE_MASK, GC_EDC_CTRL__EDC_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { mmGC_EDC_CTRL, GC_EDC_CTRL__EDC_FORCE_STALL_MASK, GC_EDC_CTRL__EDC_FORCE_STALL__SHIFT, 0x0000 },
+ { mmGC_EDC_CTRL, GC_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT_MASK, GC_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0000 },
+ { mmGC_EDC_CTRL, GC_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA_MASK, GC_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA__SHIFT, 0x0000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg AvfsPSMResetConfig_vega10[]=
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ { 0x16A02, 0xFFFFFFFF, 0x0, 0x0000005F },
+ { 0x16A05, 0xFFFFFFFF, 0x0, 0x00000001 },
+ { 0x16A06, 0x00000001, 0x0, 0x02000000 },
+ { 0x16A01, 0xFFFFFFFF, 0x0, 0x00003027 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg AvfsPSMInitConfig_vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ { 0x16A05, 0xFFFFFFFF, 0x18, 0x00000001 },
+ { 0x16A05, 0xFFFFFFFF, 0x8, 0x00000003 },
+ { 0x16A05, 0xFFFFFFFF, 0xa, 0x00000006 },
+ { 0x16A05, 0xFFFFFFFF, 0x7, 0x00000000 },
+ { 0x16A06, 0xFFFFFFFF, 0x18, 0x00000001 },
+ { 0x16A06, 0xFFFFFFFF, 0x19, 0x00000001 },
+ { 0x16A01, 0xFFFFFFFF, 0x0, 0x00003027 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static int vega10_program_didt_config_registers(struct pp_hwmgr *hwmgr, const struct vega10_didt_config_reg *config_regs, enum vega10_didt_config_reg_type reg_type)
+{
+ uint32_t data;
+
+ PP_ASSERT_WITH_CODE((config_regs != NULL), "[vega10_program_didt_config_registers] Invalid config register table!", return -EINVAL);
+
+ while (config_regs->offset != 0xFFFFFFFF) {
+ switch (reg_type) {
+ case VEGA10_CONFIGREG_DIDT:
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, config_regs->offset);
+ data &= ~config_regs->mask;
+ data |= ((config_regs->value << config_regs->shift) & config_regs->mask);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, config_regs->offset, data);
+ break;
+ case VEGA10_CONFIGREG_GCCAC:
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG_GC_CAC, config_regs->offset);
+ data &= ~config_regs->mask;
+ data |= ((config_regs->value << config_regs->shift) & config_regs->mask);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG_GC_CAC, config_regs->offset, data);
+ break;
+ case VEGA10_CONFIGREG_SECAC:
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG_SE_CAC, config_regs->offset);
+ data &= ~config_regs->mask;
+ data |= ((config_regs->value << config_regs->shift) & config_regs->mask);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG_SE_CAC, config_regs->offset, data);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ config_regs++;
+ }
+
+ return 0;
+}
+
+static int vega10_program_gc_didt_config_registers(struct pp_hwmgr *hwmgr, const struct vega10_didt_config_reg *config_regs)
+{
+ uint32_t data;
+
+ while (config_regs->offset != 0xFFFFFFFF) {
+ data = cgs_read_register(hwmgr->device, config_regs->offset);
+ data &= ~config_regs->mask;
+ data |= ((config_regs->value << config_regs->shift) & config_regs->mask);
+ cgs_write_register(hwmgr->device, config_regs->offset, data);
+ config_regs++;
+ }
+
+ return 0;
+}
+
+static void vega10_didt_set_mask(struct pp_hwmgr *hwmgr, const bool enable)
+{
+ uint32_t data;
+ int result;
+ uint32_t en = (enable ? 1 : 0);
+ uint32_t didt_block_info = SQ_IR_MASK | TCP_IR_MASK | TD_PCC_MASK;
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SQRamping)) {
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_SQ_CTRL0);
+ data &= ~DIDT_SQ_CTRL0__DIDT_CTRL_EN_MASK;
+ data |= ((en << DIDT_SQ_CTRL0__DIDT_CTRL_EN__SHIFT) & DIDT_SQ_CTRL0__DIDT_CTRL_EN_MASK);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_SQ_CTRL0, data);
+ didt_block_info &= ~SQ_Enable_MASK;
+ didt_block_info |= en << SQ_Enable_SHIFT;
+ }
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DBRamping)) {
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_DB_CTRL0);
+ data &= ~DIDT_DB_CTRL0__DIDT_CTRL_EN_MASK;
+ data |= ((en << DIDT_DB_CTRL0__DIDT_CTRL_EN__SHIFT) & DIDT_DB_CTRL0__DIDT_CTRL_EN_MASK);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_DB_CTRL0, data);
+ didt_block_info &= ~DB_Enable_MASK;
+ didt_block_info |= en << DB_Enable_SHIFT;
+ }
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_TDRamping)) {
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_TD_CTRL0);
+ data &= ~DIDT_TD_CTRL0__DIDT_CTRL_EN_MASK;
+ data |= ((en << DIDT_TD_CTRL0__DIDT_CTRL_EN__SHIFT) & DIDT_TD_CTRL0__DIDT_CTRL_EN_MASK);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_TD_CTRL0, data);
+ didt_block_info &= ~TD_Enable_MASK;
+ didt_block_info |= en << TD_Enable_SHIFT;
+ }
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_TCPRamping)) {
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_TCP_CTRL0);
+ data &= ~DIDT_TCP_CTRL0__DIDT_CTRL_EN_MASK;
+ data |= ((en << DIDT_TCP_CTRL0__DIDT_CTRL_EN__SHIFT) & DIDT_TCP_CTRL0__DIDT_CTRL_EN_MASK);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_TCP_CTRL0, data);
+ didt_block_info &= ~TCP_Enable_MASK;
+ didt_block_info |= en << TCP_Enable_SHIFT;
+ }
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DBRRamping)) {
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_DBR_CTRL0);
+ data &= ~DIDT_DBR_CTRL0__DIDT_CTRL_EN_MASK;
+ data |= ((en << DIDT_DBR_CTRL0__DIDT_CTRL_EN__SHIFT) & DIDT_DBR_CTRL0__DIDT_CTRL_EN_MASK);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_DBR_CTRL0, data);
+ }
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DiDtEDCEnable)) {
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SQRamping)) {
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_SQ_EDC_CTRL);
+ data &= ~DIDT_SQ_EDC_CTRL__EDC_EN_MASK;
+ data |= ((en << DIDT_SQ_EDC_CTRL__EDC_EN__SHIFT) & DIDT_SQ_EDC_CTRL__EDC_EN_MASK);
+ data &= ~DIDT_SQ_EDC_CTRL__EDC_SW_RST_MASK;
+ data |= ((~en << DIDT_SQ_EDC_CTRL__EDC_SW_RST__SHIFT) & DIDT_SQ_EDC_CTRL__EDC_SW_RST_MASK);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_SQ_EDC_CTRL, data);
+ }
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DBRamping)) {
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_DB_EDC_CTRL);
+ data &= ~DIDT_DB_EDC_CTRL__EDC_EN_MASK;
+ data |= ((en << DIDT_DB_EDC_CTRL__EDC_EN__SHIFT) & DIDT_DB_EDC_CTRL__EDC_EN_MASK);
+ data &= ~DIDT_DB_EDC_CTRL__EDC_SW_RST_MASK;
+ data |= ((~en << DIDT_DB_EDC_CTRL__EDC_SW_RST__SHIFT) & DIDT_DB_EDC_CTRL__EDC_SW_RST_MASK);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_DB_EDC_CTRL, data);
+ }
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_TDRamping)) {
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_TD_EDC_CTRL);
+ data &= ~DIDT_TD_EDC_CTRL__EDC_EN_MASK;
+ data |= ((en << DIDT_TD_EDC_CTRL__EDC_EN__SHIFT) & DIDT_TD_EDC_CTRL__EDC_EN_MASK);
+ data &= ~DIDT_TD_EDC_CTRL__EDC_SW_RST_MASK;
+ data |= ((~en << DIDT_TD_EDC_CTRL__EDC_SW_RST__SHIFT) & DIDT_TD_EDC_CTRL__EDC_SW_RST_MASK);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_TD_EDC_CTRL, data);
+ }
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_TCPRamping)) {
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_TCP_EDC_CTRL);
+ data &= ~DIDT_TCP_EDC_CTRL__EDC_EN_MASK;
+ data |= ((en << DIDT_TCP_EDC_CTRL__EDC_EN__SHIFT) & DIDT_TCP_EDC_CTRL__EDC_EN_MASK);
+ data &= ~DIDT_TCP_EDC_CTRL__EDC_SW_RST_MASK;
+ data |= ((~en << DIDT_TCP_EDC_CTRL__EDC_SW_RST__SHIFT) & DIDT_TCP_EDC_CTRL__EDC_SW_RST_MASK);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_TCP_EDC_CTRL, data);
+ }
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DBRRamping)) {
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_DBR_EDC_CTRL);
+ data &= ~DIDT_DBR_EDC_CTRL__EDC_EN_MASK;
+ data |= ((en << DIDT_DBR_EDC_CTRL__EDC_EN__SHIFT) & DIDT_DBR_EDC_CTRL__EDC_EN_MASK);
+ data &= ~DIDT_DBR_EDC_CTRL__EDC_SW_RST_MASK;
+ data |= ((~en << DIDT_DBR_EDC_CTRL__EDC_SW_RST__SHIFT) & DIDT_DBR_EDC_CTRL__EDC_SW_RST_MASK);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_DBR_EDC_CTRL, data);
+ }
+ }
+
+ if (enable) {
+ /* For Vega10, SMC does not support any mask yet. */
+ result = smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, PPSMC_MSG_ConfigureGfxDidt, didt_block_info);
+ PP_ASSERT((0 == result), "[EnableDiDtConfig] SMC Configure Gfx Didt Failed!");
+ }
+}
+
+static int vega10_enable_cac_driving_se_didt_config(struct pp_hwmgr *hwmgr)
+{
+ int result;
+ uint32_t num_se = 0, count, data;
+ struct cgs_system_info sys_info = {0};
+ uint32_t reg;
+
+ sys_info.size = sizeof(struct cgs_system_info);
+ sys_info.info_id = CGS_SYSTEM_INFO_GFX_SE_INFO;
+ if (cgs_query_system_info(hwmgr->device, &sys_info) == 0)
+ num_se = sys_info.value;
+
+ cgs_enter_safe_mode(hwmgr->device, true);
+
+ cgs_lock_grbm_idx(hwmgr->device, true);
+ reg = soc15_get_register_offset(GC_HWID, 0, mmGRBM_GFX_INDEX_BASE_IDX, mmGRBM_GFX_INDEX);
+ for (count = 0; count < num_se; count++) {
+ data = GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK | GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | ( count << GRBM_GFX_INDEX__SE_INDEX__SHIFT);
+ cgs_write_register(hwmgr->device, reg, data);
+
+ result = vega10_program_didt_config_registers(hwmgr, SEDiDtStallCtrlConfig_vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEDiDtStallPatternConfig_vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEDiDtWeightConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEDiDtCtrl1Config_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEDiDtCtrl2Config_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEDiDtCtrl3Config_vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEDiDtTuningCtrlConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SELCacConfig_Vega10, VEGA10_CONFIGREG_SECAC);
+ result |= vega10_program_didt_config_registers(hwmgr, SEDiDtCtrl0Config_Vega10, VEGA10_CONFIGREG_DIDT);
+
+ if (0 != result)
+ break;
+ }
+ cgs_write_register(hwmgr->device, reg, 0xE0000000);
+ cgs_lock_grbm_idx(hwmgr->device, false);
+
+ vega10_didt_set_mask(hwmgr, true);
+
+ cgs_enter_safe_mode(hwmgr->device, false);
+
+ return 0;
+}
+
+static int vega10_disable_cac_driving_se_didt_config(struct pp_hwmgr *hwmgr)
+{
+ cgs_enter_safe_mode(hwmgr->device, true);
+
+ vega10_didt_set_mask(hwmgr, false);
+
+ cgs_enter_safe_mode(hwmgr->device, false);
+
+ return 0;
+}
+
+static int vega10_enable_psm_gc_didt_config(struct pp_hwmgr *hwmgr)
+{
+ int result;
+ uint32_t num_se = 0, count, data;
+ struct cgs_system_info sys_info = {0};
+ uint32_t reg;
+
+ sys_info.size = sizeof(struct cgs_system_info);
+ sys_info.info_id = CGS_SYSTEM_INFO_GFX_SE_INFO;
+ if (cgs_query_system_info(hwmgr->device, &sys_info) == 0)
+ num_se = sys_info.value;
+
+ cgs_enter_safe_mode(hwmgr->device, true);
+
+ cgs_lock_grbm_idx(hwmgr->device, true);
+ reg = soc15_get_register_offset(GC_HWID, 0, mmGRBM_GFX_INDEX_BASE_IDX, mmGRBM_GFX_INDEX);
+ for (count = 0; count < num_se; count++) {
+ data = GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK | GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | ( count << GRBM_GFX_INDEX__SE_INDEX__SHIFT);
+ cgs_write_register(hwmgr->device, reg, data);
+
+ result = vega10_program_didt_config_registers(hwmgr, SEDiDtStallCtrlConfig_vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEDiDtStallPatternConfig_vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEDiDtCtrl3Config_vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEDiDtCtrl0Config_Vega10, VEGA10_CONFIGREG_DIDT);
+ if (0 != result)
+ break;
+ }
+ cgs_write_register(hwmgr->device, reg, 0xE0000000);
+ cgs_lock_grbm_idx(hwmgr->device, false);
+
+ vega10_didt_set_mask(hwmgr, true);
+
+ cgs_enter_safe_mode(hwmgr->device, false);
+
+ vega10_program_gc_didt_config_registers(hwmgr, GCDiDtDroopCtrlConfig_vega10);
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_GCEDC))
+ vega10_program_gc_didt_config_registers(hwmgr, GCDiDtCtrl0Config_vega10);
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PSM))
+ vega10_program_gc_didt_config_registers(hwmgr, AvfsPSMInitConfig_vega10);
+
+ return 0;
+}
+
+static int vega10_disable_psm_gc_didt_config(struct pp_hwmgr *hwmgr)
+{
+ uint32_t data;
+
+ cgs_enter_safe_mode(hwmgr->device, true);
+
+ vega10_didt_set_mask(hwmgr, false);
+
+ cgs_enter_safe_mode(hwmgr->device, false);
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_GCEDC)) {
+ data = 0x00000000;
+ cgs_write_register(hwmgr->device, mmGC_DIDT_CTRL0, data);
+ }
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PSM))
+ vega10_program_gc_didt_config_registers(hwmgr, AvfsPSMResetConfig_vega10);
+
+ return 0;
+}
+
+static int vega10_enable_se_edc_config(struct pp_hwmgr *hwmgr)
+{
+ int result;
+ uint32_t num_se = 0, count, data;
+ struct cgs_system_info sys_info = {0};
+ uint32_t reg;
+
+ sys_info.size = sizeof(struct cgs_system_info);
+ sys_info.info_id = CGS_SYSTEM_INFO_GFX_SE_INFO;
+ if (cgs_query_system_info(hwmgr->device, &sys_info) == 0)
+ num_se = sys_info.value;
+
+ cgs_enter_safe_mode(hwmgr->device, true);
+
+ cgs_lock_grbm_idx(hwmgr->device, true);
+ reg = soc15_get_register_offset(GC_HWID, 0, mmGRBM_GFX_INDEX_BASE_IDX, mmGRBM_GFX_INDEX);
+ for (count = 0; count < num_se; count++) {
+ data = GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK | GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | ( count << GRBM_GFX_INDEX__SE_INDEX__SHIFT);
+ cgs_write_register(hwmgr->device, reg, data);
+ result = vega10_program_didt_config_registers(hwmgr, SEDiDtWeightConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEEDCStallPatternConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEEDCStallDelayConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEEDCThresholdConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEEDCCtrlResetConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEEDCCtrlConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+
+ if (0 != result)
+ break;
+ }
+ cgs_write_register(hwmgr->device, reg, 0xE0000000);
+ cgs_lock_grbm_idx(hwmgr->device, false);
+
+ vega10_didt_set_mask(hwmgr, true);
+
+ cgs_enter_safe_mode(hwmgr->device, false);
+
+ return 0;
+}
+
+static int vega10_disable_se_edc_config(struct pp_hwmgr *hwmgr)
+{
+ cgs_enter_safe_mode(hwmgr->device, true);
+
+ vega10_didt_set_mask(hwmgr, false);
+
+ cgs_enter_safe_mode(hwmgr->device, false);
+
+ return 0;
+}
+
+static int vega10_enable_psm_gc_edc_config(struct pp_hwmgr *hwmgr)
+{
+ int result;
+ uint32_t num_se = 0;
+ uint32_t count, data;
+ struct cgs_system_info sys_info = {0};
+ uint32_t reg;
+
+ sys_info.size = sizeof(struct cgs_system_info);
+ sys_info.info_id = CGS_SYSTEM_INFO_GFX_SE_INFO;
+ if (cgs_query_system_info(hwmgr->device, &sys_info) == 0)
+ num_se = sys_info.value;
+
+ cgs_enter_safe_mode(hwmgr->device, true);
+
+ vega10_program_gc_didt_config_registers(hwmgr, AvfsPSMResetConfig_vega10);
+
+ cgs_lock_grbm_idx(hwmgr->device, true);
+ reg = soc15_get_register_offset(GC_HWID, 0, mmGRBM_GFX_INDEX_BASE_IDX, mmGRBM_GFX_INDEX);
+ for (count = 0; count < num_se; count++) {
+ data = GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK | GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | ( count << GRBM_GFX_INDEX__SE_INDEX__SHIFT);
+ cgs_write_register(hwmgr->device, reg, data);
+ result |= vega10_program_didt_config_registers(hwmgr, PSMSEEDCStallPatternConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, PSMSEEDCStallDelayConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, PSMSEEDCCtrlResetConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, PSMSEEDCCtrlConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+
+ if (0 != result)
+ break;
+ }
+ cgs_write_register(hwmgr->device, reg, 0xE0000000);
+ cgs_lock_grbm_idx(hwmgr->device, false);
+
+ vega10_didt_set_mask(hwmgr, true);
+
+ cgs_enter_safe_mode(hwmgr->device, false);
+
+ vega10_program_gc_didt_config_registers(hwmgr, PSMGCEDCDroopCtrlConfig_vega10);
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_GCEDC)) {
+ vega10_program_gc_didt_config_registers(hwmgr, PSMGCEDCCtrlResetConfig_vega10);
+ vega10_program_gc_didt_config_registers(hwmgr, PSMGCEDCCtrlConfig_vega10);
+ }
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PSM))
+ vega10_program_gc_didt_config_registers(hwmgr, AvfsPSMInitConfig_vega10);
+
+ return 0;
+}
+
+static int vega10_disable_psm_gc_edc_config(struct pp_hwmgr *hwmgr)
+{
+ uint32_t data;
+
+ cgs_enter_safe_mode(hwmgr->device, true);
+
+ vega10_didt_set_mask(hwmgr, false);
+
+ cgs_enter_safe_mode(hwmgr->device, false);
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_GCEDC)) {
+ data = 0x00000000;
+ cgs_write_register(hwmgr->device, mmGC_EDC_CTRL, data);
+ }
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PSM))
+ vega10_program_gc_didt_config_registers(hwmgr, AvfsPSMResetConfig_vega10);
+
+ return 0;
+}
+
+static int vega10_enable_se_edc_force_stall_config(struct pp_hwmgr *hwmgr)
+{
+ uint32_t reg;
+ int result;
+
+ cgs_enter_safe_mode(hwmgr->device, true);
+
+ cgs_lock_grbm_idx(hwmgr->device, true);
+ reg = soc15_get_register_offset(GC_HWID, 0, mmGRBM_GFX_INDEX_BASE_IDX, mmGRBM_GFX_INDEX);
+ cgs_write_register(hwmgr->device, reg, 0xE0000000);
+ cgs_lock_grbm_idx(hwmgr->device, false);
+
+ result = vega10_program_didt_config_registers(hwmgr, SEEDCForceStallPatternConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEEDCCtrlForceStallConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+ if (0 != result)
+ return result;
+
+ vega10_didt_set_mask(hwmgr, false);
+
+ cgs_enter_safe_mode(hwmgr->device, false);
+
+ return 0;
+}
+
+static int vega10_disable_se_edc_force_stall_config(struct pp_hwmgr *hwmgr)
+{
+ int result;
+
+ result = vega10_disable_se_edc_config(hwmgr);
+ PP_ASSERT_WITH_CODE((0 == result), "[DisableDiDtConfig] Pre DIDT disable clock gating failed!", return result);
+
+ return 0;
+}
+
+int vega10_enable_didt_config(struct pp_hwmgr *hwmgr)
+{
+ int result = 0;
+ struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
+
+ if (data->smu_features[GNLD_DIDT].supported) {
+ if (data->smu_features[GNLD_DIDT].enabled)
+ PP_DBG_LOG("[EnableDiDtConfig] Feature DiDt Already enabled!\n");
+
+ switch (data->registry_data.didt_mode) {
+ case 0:
+ result = vega10_enable_cac_driving_se_didt_config(hwmgr);
+ PP_ASSERT_WITH_CODE((0 == result), "[EnableDiDt] Attempt to enable DiDt Mode 0 Failed!", return result);
+ break;
+ case 2:
+ result = vega10_enable_psm_gc_didt_config(hwmgr);
+ PP_ASSERT_WITH_CODE((0 == result), "[EnableDiDt] Attempt to enable DiDt Mode 2 Failed!", return result);
+ break;
+ case 3:
+ result = vega10_enable_se_edc_config(hwmgr);
+ PP_ASSERT_WITH_CODE((0 == result), "[EnableDiDt] Attempt to enable DiDt Mode 3 Failed!", return result);
+ break;
+ case 1:
+ case 4:
+ case 5:
+ result = vega10_enable_psm_gc_edc_config(hwmgr);
+ PP_ASSERT_WITH_CODE((0 == result), "[EnableDiDt] Attempt to enable DiDt Mode 5 Failed!", return result);
+ break;
+ case 6:
+ result = vega10_enable_se_edc_force_stall_config(hwmgr);
+ PP_ASSERT_WITH_CODE((0 == result), "[EnableDiDt] Attempt to enable DiDt Mode 6 Failed!", return result);
+ break;
+ default:
+ result = -EINVAL;
+ break;
+ }
+
+ if (0 == result) {
+ PP_ASSERT_WITH_CODE((!vega10_enable_smc_features(hwmgr->smumgr, true, data->smu_features[GNLD_DIDT].smu_feature_bitmap)),
+ "[EnableDiDtConfig] Attempt to Enable DiDt feature Failed!", return result);
+ data->smu_features[GNLD_DIDT].enabled = true;
+ }
+ }
+
+ return result;
+}
+
+int vega10_disable_didt_config(struct pp_hwmgr *hwmgr)
+{
+ int result = 0;
+ struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
+
+ if (data->smu_features[GNLD_DIDT].supported) {
+ if (!data->smu_features[GNLD_DIDT].enabled)
+ PP_DBG_LOG("[DisableDiDtConfig] Feature DiDt Already Disabled!\n");
+
+ switch (data->registry_data.didt_mode) {
+ case 0:
+ result = vega10_disable_cac_driving_se_didt_config(hwmgr);
+ PP_ASSERT_WITH_CODE((0 == result), "[DisableDiDt] Attempt to disable DiDt Mode 0 Failed!", return result);
+ break;
+ case 2:
+ result = vega10_disable_psm_gc_didt_config(hwmgr);
+ PP_ASSERT_WITH_CODE((0 == result), "[DisableDiDt] Attempt to disable DiDt Mode 2 Failed!", return result);
+ break;
+ case 3:
+ result = vega10_disable_se_edc_config(hwmgr);
+ PP_ASSERT_WITH_CODE((0 == result), "[DisableDiDt] Attempt to disable DiDt Mode 3 Failed!", return result);
+ break;
+ case 1:
+ case 4:
+ case 5:
+ result = vega10_disable_psm_gc_edc_config(hwmgr);
+ PP_ASSERT_WITH_CODE((0 == result), "[DisableDiDt] Attempt to disable DiDt Mode 5 Failed!", return result);
+ break;
+ case 6:
+ result = vega10_disable_se_edc_force_stall_config(hwmgr);
+ PP_ASSERT_WITH_CODE((0 == result), "[DisableDiDt] Attempt to disable DiDt Mode 6 Failed!", return result);
+ break;
+ default:
+ result = -EINVAL;
+ break;
+ }
+
+ if (0 == result) {
+ PP_ASSERT_WITH_CODE((0 != vega10_enable_smc_features(hwmgr->smumgr, false, data->smu_features[GNLD_DIDT].smu_feature_bitmap)),
+ "[DisableDiDtConfig] Attempt to Disable DiDt feature Failed!", return result);
+ data->smu_features[GNLD_DIDT].enabled = false;
+ }
+ }
+
+ return result;
+}
void vega10_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr)
{
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.h
index 9ecaa27..b95771a 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.h
@@ -31,6 +31,12 @@ enum vega10_pt_config_reg_type {
VEGA10_CONFIGREG_MAX
};
+enum vega10_didt_config_reg_type {
+ VEGA10_CONFIGREG_DIDT = 0,
+ VEGA10_CONFIGREG_GCCAC,
+ VEGA10_CONFIGREG_SECAC
+};
+
/* PowerContainment Features */
#define POWERCONTAINMENT_FEATURE_DTE 0x00000001
#define POWERCONTAINMENT_FEATURE_TDCLimit 0x00000002
@@ -44,6 +50,13 @@ struct vega10_pt_config_reg {
enum vega10_pt_config_reg_type type;
};
+struct vega10_didt_config_reg {
+ uint32_t offset;
+ uint32_t mask;
+ uint32_t shift;
+ uint32_t value;
+};
+
struct vega10_pt_defaults {
uint8_t SviLoadLineEn;
uint8_t SviLoadLineVddC;
@@ -62,5 +75,8 @@ int vega10_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n);
int vega10_power_control_set_level(struct pp_hwmgr *hwmgr);
int vega10_disable_power_containment(struct pp_hwmgr *hwmgr);
+int vega10_enable_didt_config(struct pp_hwmgr *hwmgr);
+int vega10_disable_didt_config(struct pp_hwmgr *hwmgr);
+
#endif /* _VEGA10_POWERTUNE_H_ */
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c
index 1623644..e343df1 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c
@@ -31,6 +31,8 @@
#include "cgs_common.h"
#include "vega10_pptable.h"
+#define NUM_DSPCLK_LEVELS 8
+
static void set_hw_cap(struct pp_hwmgr *hwmgr, bool enable,
enum phm_platform_caps cap)
{
@@ -644,11 +646,11 @@ static int get_gfxclk_voltage_dependency_table(
return 0;
}
-static int get_dcefclk_voltage_dependency_table(
+static int get_pix_clk_voltage_dependency_table(
struct pp_hwmgr *hwmgr,
struct phm_ppt_v1_clock_voltage_dependency_table
**pp_vega10_clk_dep_table,
- const ATOM_Vega10_DCEFCLK_Dependency_Table *clk_dep_table)
+ const ATOM_Vega10_PIXCLK_Dependency_Table *clk_dep_table)
{
uint32_t table_size, i;
struct phm_ppt_v1_clock_voltage_dependency_table
@@ -681,6 +683,76 @@ static int get_dcefclk_voltage_dependency_table(
return 0;
}
+static int get_dcefclk_voltage_dependency_table(
+ struct pp_hwmgr *hwmgr,
+ struct phm_ppt_v1_clock_voltage_dependency_table
+ **pp_vega10_clk_dep_table,
+ const ATOM_Vega10_DCEFCLK_Dependency_Table *clk_dep_table)
+{
+ uint32_t table_size, i;
+ uint8_t num_entries;
+ struct phm_ppt_v1_clock_voltage_dependency_table
+ *clk_table;
+ struct cgs_system_info sys_info = {0};
+ uint32_t dev_id;
+ uint32_t rev_id;
+
+ PP_ASSERT_WITH_CODE((clk_dep_table->ucNumEntries != 0),
+ "Invalid PowerPlay Table!", return -1);
+
+/*
+ * workaround needed to add another DPM level for pioneer cards
+ * as VBIOS is locked down.
+ * This DPM level was added to support 3DPM monitors @ 4K120Hz
+ *
+ */
+ sys_info.size = sizeof(struct cgs_system_info);
+ sys_info.info_id = CGS_SYSTEM_INFO_PCIE_DEV;
+ cgs_query_system_info(hwmgr->device, &sys_info);
+ dev_id = (uint32_t)sys_info.value;
+
+ sys_info.size = sizeof(struct cgs_system_info);
+ sys_info.info_id = CGS_SYSTEM_INFO_PCIE_REV;
+ cgs_query_system_info(hwmgr->device, &sys_info);
+ rev_id = (uint32_t)sys_info.value;
+
+ if (dev_id == 0x6863 && rev_id == 0 &&
+ clk_dep_table->entries[clk_dep_table->ucNumEntries - 1].ulClk < 90000)
+ num_entries = clk_dep_table->ucNumEntries + 1 > NUM_DSPCLK_LEVELS ?
+ NUM_DSPCLK_LEVELS : clk_dep_table->ucNumEntries + 1;
+ else
+ num_entries = clk_dep_table->ucNumEntries;
+
+
+ table_size = sizeof(uint32_t) +
+ sizeof(phm_ppt_v1_clock_voltage_dependency_record) *
+ num_entries;
+
+ clk_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)
+ kzalloc(table_size, GFP_KERNEL);
+
+ if (!clk_table)
+ return -ENOMEM;
+
+ clk_table->count = (uint32_t)num_entries;
+
+ for (i = 0; i < clk_dep_table->ucNumEntries; i++) {
+ clk_table->entries[i].vddInd =
+ clk_dep_table->entries[i].ucVddInd;
+ clk_table->entries[i].clk =
+ le32_to_cpu(clk_dep_table->entries[i].ulClk);
+ }
+
+ if (i < num_entries) {
+ clk_table->entries[i].vddInd = clk_dep_table->entries[i-1].ucVddInd;
+ clk_table->entries[i].clk = 90000;
+ }
+
+ *pp_vega10_clk_dep_table = clk_table;
+
+ return 0;
+}
+
static int get_pcie_table(struct pp_hwmgr *hwmgr,
struct phm_ppt_v1_pcie_table **vega10_pcie_table,
const Vega10_PPTable_Generic_SubTable_Header *table)
@@ -862,21 +934,21 @@ static int init_powerplay_extended_tables(
gfxclk_dep_table);
if (!result && powerplay_table->usPixclkDependencyTableOffset)
- result = get_dcefclk_voltage_dependency_table(hwmgr,
+ result = get_pix_clk_voltage_dependency_table(hwmgr,
&pp_table_info->vdd_dep_on_pixclk,
- (const ATOM_Vega10_DCEFCLK_Dependency_Table*)
+ (const ATOM_Vega10_PIXCLK_Dependency_Table*)
pixclk_dep_table);
if (!result && powerplay_table->usPhyClkDependencyTableOffset)
- result = get_dcefclk_voltage_dependency_table(hwmgr,
+ result = get_pix_clk_voltage_dependency_table(hwmgr,
&pp_table_info->vdd_dep_on_phyclk,
- (const ATOM_Vega10_DCEFCLK_Dependency_Table *)
+ (const ATOM_Vega10_PIXCLK_Dependency_Table *)
phyclk_dep_table);
if (!result && powerplay_table->usDispClkDependencyTableOffset)
- result = get_dcefclk_voltage_dependency_table(hwmgr,
+ result = get_pix_clk_voltage_dependency_table(hwmgr,
&pp_table_info->vdd_dep_on_dispclk,
- (const ATOM_Vega10_DCEFCLK_Dependency_Table *)
+ (const ATOM_Vega10_PIXCLK_Dependency_Table *)
dispclk_dep_table);
if (!result && powerplay_table->usDcefclkDependencyTableOffset)
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c
index e7ab8eb..d442434 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c
@@ -321,10 +321,7 @@ int vega10_fan_ctrl_reset_fan_speed_to_default(struct pp_hwmgr *hwmgr)
if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_MicrocodeFanControl)) {
- result = vega10_fan_ctrl_set_static_mode(hwmgr,
- FDO_PWM_MODE_STATIC);
- if (!result)
- result = vega10_fan_ctrl_start_smc_fan_control(hwmgr);
+ result = vega10_fan_ctrl_start_smc_fan_control(hwmgr);
} else
result = vega10_fan_ctrl_set_default_mode(hwmgr);
@@ -633,7 +630,6 @@ int tf_vega10_thermal_start_smc_fan_control(struct pp_hwmgr *hwmgr,
if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_MicrocodeFanControl)) {
vega10_fan_ctrl_start_smc_fan_control(hwmgr);
- vega10_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC);
}
return 0;
diff --git a/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h b/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h
index a1ebe10..a4c8b09 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h
@@ -164,9 +164,14 @@ enum phm_platform_caps {
PHM_PlatformCaps_EnablePlatformPowerManagement, /* indicates that Platform Power Management feature is supported */
PHM_PlatformCaps_SurpriseRemoval, /* indicates that surprise removal feature is requested */
PHM_PlatformCaps_NewCACVoltage, /* indicates new CAC voltage table support */
+ PHM_PlatformCaps_DiDtSupport, /* for dI/dT feature */
PHM_PlatformCaps_DBRamping, /* for dI/dT feature */
PHM_PlatformCaps_TDRamping, /* for dI/dT feature */
PHM_PlatformCaps_TCPRamping, /* for dI/dT feature */
+ PHM_PlatformCaps_DBRRamping, /* for dI/dT feature */
+ PHM_PlatformCaps_DiDtEDCEnable, /* for dI/dT feature */
+ PHM_PlatformCaps_GCEDC, /* for dI/dT feature */
+ PHM_PlatformCaps_PSM, /* for dI/dT feature */
PHM_PlatformCaps_EnableSMU7ThermalManagement, /* SMC will manage thermal events */
PHM_PlatformCaps_FPS, /* FPS support */
PHM_PlatformCaps_ACP, /* ACP support */
diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
index 47e57bd..91b0105 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
@@ -128,6 +128,8 @@ struct phm_uvd_arbiter {
uint32_t dclk;
uint32_t vclk_ceiling;
uint32_t dclk_ceiling;
+ uint32_t vclk_soft_min;
+ uint32_t dclk_soft_min;
};
struct phm_vce_arbiter {
diff --git a/drivers/gpu/drm/amd/powerplay/inc/pp_debug.h b/drivers/gpu/drm/amd/powerplay/inc/pp_debug.h
index f3f9ebb..822cd8b 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/pp_debug.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/pp_debug.h
@@ -42,6 +42,12 @@
} \
} while (0)
+#define PP_ASSERT(cond, msg) \
+ do { \
+ if (!(cond)) { \
+ pr_warn("%s\n", msg); \
+ } \
+ } while (0)
#define PP_DBG_LOG(fmt, ...) \
do { \
diff --git a/drivers/gpu/drm/amd/powerplay/inc/pp_soc15.h b/drivers/gpu/drm/amd/powerplay/inc/pp_soc15.h
index 227d999..a511611 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/pp_soc15.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/pp_soc15.h
@@ -41,6 +41,8 @@ inline static uint32_t soc15_get_register_offset(
reg = MP1_BASE.instance[inst].segment[segment] + offset;
else if (hw_id == DF_HWID)
reg = DF_BASE.instance[inst].segment[segment] + offset;
+ else if (hw_id == GC_HWID)
+ reg = GC_BASE.instance[inst].segment[segment] + offset;
return reg;
}
diff --git a/drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h b/drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h
index e0e106f..901c960c 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h
@@ -66,7 +66,12 @@
#define PPSMC_MSG_SetMinVddcrSocVoltage 0x22
#define PPSMC_MSG_SetMinVideoFclkFreq 0x23
#define PPSMC_MSG_SetMinDeepSleepDcefclk 0x24
-#define PPSMC_Message_Count 0x25
+#define PPSMC_MSG_ForcePowerDownGfx 0x25
+#define PPSMC_MSG_SetPhyclkVoltageByFreq 0x26
+#define PPSMC_MSG_SetDppclkVoltageByFreq 0x27
+#define PPSMC_MSG_SetSoftMinVcn 0x28
+#define PPSMC_Message_Count 0x29
+
typedef uint16_t PPSMC_Result;
typedef int PPSMC_Msg;
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu9.h b/drivers/gpu/drm/amd/powerplay/inc/smu9.h
index 9ef2490..550ed67 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/smu9.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/smu9.h
@@ -55,9 +55,9 @@
#define FEATURE_FW_CTF_BIT 23
#define FEATURE_LED_DISPLAY_BIT 24
#define FEATURE_FAN_CONTROL_BIT 25
-#define FEATURE_VOLTAGE_CONTROLLER_BIT 26
-#define FEATURE_SPARE_27_BIT 27
-#define FEATURE_SPARE_28_BIT 28
+#define FEATURE_FAST_PPT_BIT 26
+#define FEATURE_GFX_EDC_BIT 27
+#define FEATURE_ACG_BIT 28
#define FEATURE_SPARE_29_BIT 29
#define FEATURE_SPARE_30_BIT 30
#define FEATURE_SPARE_31_BIT 31
@@ -90,9 +90,10 @@
#define FFEATURE_FW_CTF_MASK (1 << FEATURE_FW_CTF_BIT )
#define FFEATURE_LED_DISPLAY_MASK (1 << FEATURE_LED_DISPLAY_BIT )
#define FFEATURE_FAN_CONTROL_MASK (1 << FEATURE_FAN_CONTROL_BIT )
-#define FFEATURE_VOLTAGE_CONTROLLER_MASK (1 << FEATURE_VOLTAGE_CONTROLLER_BIT )
-#define FFEATURE_SPARE_27_MASK (1 << FEATURE_SPARE_27_BIT )
-#define FFEATURE_SPARE_28_MASK (1 << FEATURE_SPARE_28_BIT )
+
+#define FEATURE_FAST_PPT_MASK (1 << FAST_PPT_BIT )
+#define FEATURE_GFX_EDC_MASK (1 << FEATURE_GFX_EDC_BIT )
+#define FEATURE_ACG_MASK (1 << FEATURE_ACG_BIT )
#define FFEATURE_SPARE_29_MASK (1 << FEATURE_SPARE_29_BIT )
#define FFEATURE_SPARE_30_MASK (1 << FEATURE_SPARE_30_BIT )
#define FFEATURE_SPARE_31_MASK (1 << FEATURE_SPARE_31_BIT )
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu9_driver_if.h b/drivers/gpu/drm/amd/powerplay/inc/smu9_driver_if.h
index 532186b..f6d6c61 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/smu9_driver_if.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/smu9_driver_if.h
@@ -312,7 +312,10 @@ typedef struct {
PllSetting_t GfxBoostState;
- uint32_t Reserved[14];
+ uint8_t AcgEnable[NUM_GFXCLK_DPM_LEVELS];
+ GbVdroopTable_t AcgBtcGbVdroopTable;
+ QuadraticInt_t AcgAvfsGb;
+ uint32_t Reserved[4];
/* Padding - ignore */
uint32_t MmHubPadding[7]; /* SMU internal use */
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smumgr.h b/drivers/gpu/drm/amd/powerplay/inc/smumgr.h
index 976e942..5d61cc9 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/smumgr.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/smumgr.h
@@ -131,6 +131,7 @@ struct pp_smumgr_func {
bool (*is_dpm_running)(struct pp_hwmgr *hwmgr);
int (*populate_requested_graphic_levels)(struct pp_hwmgr *hwmgr,
struct amd_pp_profile *request);
+ bool (*is_hw_avfs_present)(struct pp_smumgr *smumgr);
};
struct pp_smumgr {
@@ -202,6 +203,8 @@ extern bool smum_is_dpm_running(struct pp_hwmgr *hwmgr);
extern int smum_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr,
struct amd_pp_profile *request);
+extern bool smum_is_hw_avfs_present(struct pp_smumgr *smumgr);
+
#define SMUM_FIELD_SHIFT(reg, field) reg##__##field##__SHIFT
#define SMUM_FIELD_MASK(reg, field) reg##__##field##_MASK
diff --git a/drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h b/drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h
index b4af9e8..cb070eb 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h
@@ -124,6 +124,10 @@ typedef uint16_t PPSMC_Result;
#define PPSMC_MSG_NumOfDisplays 0x56
#define PPSMC_MSG_ReadSerialNumTop32 0x58
#define PPSMC_MSG_ReadSerialNumBottom32 0x59
+#define PPSMC_MSG_RunAcgBtc 0x5C
+#define PPSMC_MSG_RunAcgInClosedLoop 0x5D
+#define PPSMC_MSG_RunAcgInOpenLoop 0x5E
+#define PPSMC_MSG_InitializeAcg 0x5F
#define PPSMC_MSG_GetCurrPkgPwr 0x61
#define PPSMC_Message_Count 0x62
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.c b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.c
index 6a320b2..8712f09 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.c
@@ -2129,6 +2129,25 @@ int fiji_thermal_setup_fan_table(struct pp_hwmgr *hwmgr)
return 0;
}
+
+int fiji_thermal_avfs_enable(struct pp_hwmgr *hwmgr)
+{
+ int ret;
+ struct pp_smumgr *smumgr = (struct pp_smumgr *)(hwmgr->smumgr);
+ struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(smumgr->backend);
+
+ if (smu_data->avfs.avfs_btc_status != AVFS_BTC_ENABLEAVFS)
+ return 0;
+
+ ret = smum_send_msg_to_smc(smumgr, PPSMC_MSG_EnableAvfs);
+
+ if (!ret)
+ /* If this param is not changed, this function could fire unnecessarily */
+ smu_data->avfs.avfs_btc_status = AVFS_BTC_COMPLETED_PREVIOUSLY;
+
+ return ret;
+}
+
static int fiji_program_mem_timing_parameters(struct pp_hwmgr *hwmgr)
{
struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.h b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.h
index 0e9e1f2..d9c72d9 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.h
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.h
@@ -48,5 +48,6 @@ int fiji_initialize_mc_reg_table(struct pp_hwmgr *hwmgr);
bool fiji_is_dpm_running(struct pp_hwmgr *hwmgr);
int fiji_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr,
struct amd_pp_profile *request);
+int fiji_thermal_avfs_enable(struct pp_hwmgr *hwmgr);
#endif
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c
index a1cb785..6ae948f 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c
@@ -161,56 +161,47 @@ static int fiji_start_smu_in_non_protection_mode(struct pp_smumgr *smumgr)
static int fiji_setup_pwr_virus(struct pp_smumgr *smumgr)
{
- int i, result = -1;
+ int i;
+ int result = -EINVAL;
uint32_t reg, data;
- const PWR_Command_Table *virus = PwrVirusTable;
- struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend);
- priv->avfs.AvfsBtcStatus = AVFS_LOAD_VIRUS;
- for (i = 0; (i < PWR_VIRUS_TABLE_SIZE); i++) {
- switch (virus->command) {
+ const PWR_Command_Table *pvirus = PwrVirusTable;
+ struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(smumgr->backend);
+
+ for (i = 0; i < PWR_VIRUS_TABLE_SIZE; i++) {
+ switch (pvirus->command) {
case PwrCmdWrite:
- reg = virus->reg;
- data = virus->data;
+ reg = pvirus->reg;
+ data = pvirus->data;
cgs_write_register(smumgr->device, reg, data);
break;
+
case PwrCmdEnd:
- priv->avfs.AvfsBtcStatus = AVFS_BTC_VIRUS_LOADED;
result = 0;
break;
+
default:
- pr_err("Table Exit with Invalid Command!");
- priv->avfs.AvfsBtcStatus = AVFS_BTC_VIRUS_FAIL;
- result = -1;
+ pr_info("Table Exit with Invalid Command!");
+ smu_data->avfs.avfs_btc_status = AVFS_BTC_VIRUS_FAIL;
+ result = -EINVAL;
break;
}
- virus++;
+ pvirus++;
}
+
return result;
}
static int fiji_start_avfs_btc(struct pp_smumgr *smumgr)
{
int result = 0;
- struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend);
+ struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(smumgr->backend);
- priv->avfs.AvfsBtcStatus = AVFS_BTC_STARTED;
- if (priv->avfs.AvfsBtcParam) {
- if (!smum_send_msg_to_smc_with_parameter(smumgr,
- PPSMC_MSG_PerformBtc, priv->avfs.AvfsBtcParam)) {
- if (!smum_send_msg_to_smc(smumgr, PPSMC_MSG_EnableAvfs)) {
- priv->avfs.AvfsBtcStatus = AVFS_BTC_COMPLETED_UNSAVED;
- result = 0;
- } else {
- pr_err("[AVFS][fiji_start_avfs_btc] Attempt"
- " to Enable AVFS Failed!");
- smum_send_msg_to_smc(smumgr, PPSMC_MSG_DisableAvfs);
- result = -1;
- }
- } else {
- pr_err("[AVFS][fiji_start_avfs_btc] "
- "PerformBTC SMU msg failed");
- result = -1;
+ if (0 != smu_data->avfs.avfs_btc_param) {
+ if (0 != smu7_send_msg_to_smc_with_parameter(smumgr,
+ PPSMC_MSG_PerformBtc, smu_data->avfs.avfs_btc_param)) {
+ pr_info("[AVFS][Fiji_PerformBtc] PerformBTC SMU msg failed");
+ result = -EINVAL;
}
}
/* Soft-Reset to reset the engine before loading uCode */
@@ -224,42 +215,6 @@ static int fiji_start_avfs_btc(struct pp_smumgr *smumgr)
return result;
}
-static int fiji_setup_pm_fuse_for_avfs(struct pp_smumgr *smumgr)
-{
- int result = 0;
- uint32_t table_start;
- uint32_t charz_freq_addr, inversion_voltage_addr, charz_freq;
- uint16_t inversion_voltage;
-
- charz_freq = 0x30750000; /* In 10KHz units 0x00007530 Actual value */
- inversion_voltage = 0x1A04; /* mV Q14.2 0x41A Actual value */
-
- PP_ASSERT_WITH_CODE(0 == smu7_read_smc_sram_dword(smumgr,
- SMU7_FIRMWARE_HEADER_LOCATION + offsetof(SMU73_Firmware_Header,
- PmFuseTable), &table_start, 0x40000),
- "[AVFS][Fiji_SetupGfxLvlStruct] SMU could not communicate "
- "starting address of PmFuse structure",
- return -1;);
-
- charz_freq_addr = table_start +
- offsetof(struct SMU73_Discrete_PmFuses, PsmCharzFreq);
- inversion_voltage_addr = table_start +
- offsetof(struct SMU73_Discrete_PmFuses, InversionVoltage);
-
- result = smu7_copy_bytes_to_smc(smumgr, charz_freq_addr,
- (uint8_t *)(&charz_freq), sizeof(charz_freq), 0x40000);
- PP_ASSERT_WITH_CODE(0 == result,
- "[AVFS][fiji_setup_pm_fuse_for_avfs] charz_freq could not "
- "be populated.", return -1;);
-
- result = smu7_copy_bytes_to_smc(smumgr, inversion_voltage_addr,
- (uint8_t *)(&inversion_voltage), sizeof(inversion_voltage), 0x40000);
- PP_ASSERT_WITH_CODE(0 == result, "[AVFS][fiji_setup_pm_fuse_for_avfs] "
- "charz_freq could not be populated.", return -1;);
-
- return result;
-}
-
static int fiji_setup_graphics_level_structure(struct pp_smumgr *smumgr)
{
int32_t vr_config;
@@ -298,93 +253,41 @@ static int fiji_setup_graphics_level_structure(struct pp_smumgr *smumgr)
return 0;
}
-/* Work in Progress */
-static int fiji_restore_vft_table(struct pp_smumgr *smumgr)
-{
- struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend);
-
- if (AVFS_BTC_COMPLETED_SAVED == priv->avfs.AvfsBtcStatus) {
- priv->avfs.AvfsBtcStatus = AVFS_BTC_COMPLETED_RESTORED;
- return 0;
- } else
- return -EINVAL;
-}
-
-/* Work in Progress */
-static int fiji_save_vft_table(struct pp_smumgr *smumgr)
-{
- struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend);
-
- if (AVFS_BTC_COMPLETED_SAVED == priv->avfs.AvfsBtcStatus) {
- priv->avfs.AvfsBtcStatus = AVFS_BTC_COMPLETED_RESTORED;
- return 0;
- } else
- return -EINVAL;
-}
-
static int fiji_avfs_event_mgr(struct pp_smumgr *smumgr, bool smu_started)
{
- struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend);
+ struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(smumgr->backend);
- switch (priv->avfs.AvfsBtcStatus) {
- case AVFS_BTC_COMPLETED_SAVED: /*S3 State - Pre SMU Start */
- priv->avfs.AvfsBtcStatus = AVFS_BTC_RESTOREVFT_FAILED;
- PP_ASSERT_WITH_CODE(0 == fiji_restore_vft_table(smumgr),
- "[AVFS][fiji_avfs_event_mgr] Could not Copy Graphics "
- "Level table over to SMU",
- return -1;);
- priv->avfs.AvfsBtcStatus = AVFS_BTC_COMPLETED_RESTORED;
- break;
- case AVFS_BTC_COMPLETED_RESTORED: /*S3 State - Post SMU Start*/
- priv->avfs.AvfsBtcStatus = AVFS_BTC_SMUMSG_ERROR;
- PP_ASSERT_WITH_CODE(0 == smum_send_msg_to_smc(smumgr,
- 0x666),
- "[AVFS][fiji_avfs_event_mgr] SMU did not respond "
- "correctly to VftTableIsValid Msg",
- return -1;);
- priv->avfs.AvfsBtcStatus = AVFS_BTC_SMUMSG_ERROR;
- PP_ASSERT_WITH_CODE(0 == smum_send_msg_to_smc(smumgr,
- PPSMC_MSG_EnableAvfs),
- "[AVFS][fiji_avfs_event_mgr] SMU did not respond "
- "correctly to EnableAvfs Message Msg",
- return -1;);
- priv->avfs.AvfsBtcStatus = AVFS_BTC_COMPLETED_SAVED;
+ switch (smu_data->avfs.avfs_btc_status) {
+ case AVFS_BTC_COMPLETED_PREVIOUSLY:
break;
+
case AVFS_BTC_BOOT: /*Cold Boot State - Post SMU Start*/
if (!smu_started)
break;
- priv->avfs.AvfsBtcStatus = AVFS_BTC_FAILED;
- PP_ASSERT_WITH_CODE(0 == fiji_setup_pm_fuse_for_avfs(smumgr),
- "[AVFS][fiji_avfs_event_mgr] Failure at "
- "fiji_setup_pm_fuse_for_avfs",
- return -1;);
- priv->avfs.AvfsBtcStatus = AVFS_BTC_DPMTABLESETUP_FAILED;
+ smu_data->avfs.avfs_btc_status = AVFS_BTC_FAILED;
PP_ASSERT_WITH_CODE(0 == fiji_setup_graphics_level_structure(smumgr),
"[AVFS][fiji_avfs_event_mgr] Could not Copy Graphics Level"
" table over to SMU",
- return -1;);
- priv->avfs.AvfsBtcStatus = AVFS_BTC_VIRUS_FAIL;
+ return -EINVAL;);
+ smu_data->avfs.avfs_btc_status = AVFS_BTC_VIRUS_FAIL;
PP_ASSERT_WITH_CODE(0 == fiji_setup_pwr_virus(smumgr),
"[AVFS][fiji_avfs_event_mgr] Could not setup "
"Pwr Virus for AVFS ",
- return -1;);
- priv->avfs.AvfsBtcStatus = AVFS_BTC_FAILED;
+ return -EINVAL;);
+ smu_data->avfs.avfs_btc_status = AVFS_BTC_FAILED;
PP_ASSERT_WITH_CODE(0 == fiji_start_avfs_btc(smumgr),
"[AVFS][fiji_avfs_event_mgr] Failure at "
"fiji_start_avfs_btc. AVFS Disabled",
- return -1;);
- priv->avfs.AvfsBtcStatus = AVFS_BTC_SAVEVFT_FAILED;
- PP_ASSERT_WITH_CODE(0 == fiji_save_vft_table(smumgr),
- "[AVFS][fiji_avfs_event_mgr] Could not save VFT Table",
- return -1;);
- priv->avfs.AvfsBtcStatus = AVFS_BTC_COMPLETED_SAVED;
+ return -EINVAL;);
+
+ smu_data->avfs.avfs_btc_status = AVFS_BTC_ENABLEAVFS;
break;
case AVFS_BTC_DISABLED: /* Do nothing */
- break;
case AVFS_BTC_NOTSUPPORTED: /* Do nothing */
+ case AVFS_BTC_ENABLEAVFS:
break;
default:
- pr_err("[AVFS] Something is broken. See log!");
+ pr_err("AVFS failed status is %x !\n", smu_data->avfs.avfs_btc_status);
break;
}
return 0;
@@ -477,19 +380,6 @@ static int fiji_smu_init(struct pp_smumgr *smumgr)
if (smu7_init(smumgr))
return -EINVAL;
- fiji_priv->avfs.AvfsBtcStatus = AVFS_BTC_BOOT;
- if (fiji_is_hw_avfs_present(smumgr))
- /* AVFS Parameter
- * 0 - BTC DC disabled, BTC AC disabled
- * 1 - BTC DC enabled, BTC AC disabled
- * 2 - BTC DC disabled, BTC AC enabled
- * 3 - BTC DC enabled, BTC AC enabled
- * Default is 0 - BTC DC disabled, BTC AC disabled
- */
- fiji_priv->avfs.AvfsBtcParam = 0;
- else
- fiji_priv->avfs.AvfsBtcStatus = AVFS_BTC_NOTSUPPORTED;
-
for (i = 0; i < SMU73_MAX_LEVELS_GRAPHICS; i++)
fiji_priv->activity_target[i] = 30;
@@ -514,10 +404,12 @@ const struct pp_smumgr_func fiji_smu_funcs = {
.init_smc_table = fiji_init_smc_table,
.update_sclk_threshold = fiji_update_sclk_threshold,
.thermal_setup_fan_table = fiji_thermal_setup_fan_table,
+ .thermal_avfs_enable = fiji_thermal_avfs_enable,
.populate_all_graphic_levels = fiji_populate_all_graphic_levels,
.populate_all_memory_levels = fiji_populate_all_memory_levels,
.get_mac_definition = fiji_get_mac_definition,
.initialize_mc_reg_table = fiji_initialize_mc_reg_table,
.is_dpm_running = fiji_is_dpm_running,
.populate_requested_graphic_levels = fiji_populate_requested_graphic_levels,
+ .is_hw_avfs_present = fiji_is_hw_avfs_present,
};
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.h b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.h
index adcbdfb..175bf9f 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.h
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.h
@@ -28,17 +28,8 @@
#include "smu7_smumgr.h"
-
-struct fiji_smu_avfs {
- enum AVFS_BTC_STATUS AvfsBtcStatus;
- uint32_t AvfsBtcParam;
-};
-
-
struct fiji_smumgr {
struct smu7_smumgr smu7_data;
-
- struct fiji_smu_avfs avfs;
struct SMU73_Discrete_DpmTable smc_state_table;
struct SMU73_Discrete_Ulv ulv_setting;
struct SMU73_Discrete_PmFuses power_tune_table;
@@ -47,7 +38,5 @@ struct fiji_smumgr {
};
-
-
#endif
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.c
index f68e759..99a00bd 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.c
@@ -1498,7 +1498,7 @@ static int polaris10_populate_avfs_parameters(struct pp_hwmgr *hwmgr)
table_info->vdd_dep_on_sclk;
- if (smu_data->avfs.avfs_btc_status == AVFS_BTC_NOTSUPPORTED)
+ if (((struct smu7_smumgr *)smu_data)->avfs.avfs_btc_status == AVFS_BTC_NOTSUPPORTED)
return result;
result = atomctrl_get_avfs_information(hwmgr, &avfs_params);
@@ -1889,7 +1889,7 @@ int polaris10_thermal_avfs_enable(struct pp_hwmgr *hwmgr)
{
int ret;
struct pp_smumgr *smumgr = (struct pp_smumgr *)(hwmgr->smumgr);
- struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(smumgr->backend);
+ struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(smumgr->backend);
struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
if (smu_data->avfs.avfs_btc_status == AVFS_BTC_NOTSUPPORTED)
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
index 9616ced..75f43da 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
@@ -60,16 +60,14 @@ static const SMU74_Discrete_GraphicsLevel avfs_graphics_level_polaris10[8] = {
static const SMU74_Discrete_MemoryLevel avfs_memory_level_polaris10 = {
0x100ea446, 0, 0x30750000, 0x01, 0x01, 0x01, 0x00, 0x00, 0x64, 0x00, 0x00, 0x1f00, 0x00, 0x00};
-
static int polaris10_setup_pwr_virus(struct pp_smumgr *smumgr)
{
int i;
- int result = -1;
+ int result = -EINVAL;
uint32_t reg, data;
const PWR_Command_Table *pvirus = pwr_virus_table;
- struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(smumgr->backend);
-
+ struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(smumgr->backend);
for (i = 0; i < PWR_VIRUS_TABLE_SIZE; i++) {
switch (pvirus->command) {
@@ -86,7 +84,7 @@ static int polaris10_setup_pwr_virus(struct pp_smumgr *smumgr)
default:
pr_info("Table Exit with Invalid Command!");
smu_data->avfs.avfs_btc_status = AVFS_BTC_VIRUS_FAIL;
- result = -1;
+ result = -EINVAL;
break;
}
pvirus++;
@@ -98,7 +96,7 @@ static int polaris10_setup_pwr_virus(struct pp_smumgr *smumgr)
static int polaris10_perform_btc(struct pp_smumgr *smumgr)
{
int result = 0;
- struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(smumgr->backend);
+ struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(smumgr->backend);
if (0 != smu_data->avfs.avfs_btc_param) {
if (0 != smu7_send_msg_to_smc_with_parameter(smumgr, PPSMC_MSG_PerformBtc, smu_data->avfs.avfs_btc_param)) {
@@ -172,10 +170,11 @@ static int polaris10_setup_graphics_level_structure(struct pp_smumgr *smumgr)
return 0;
}
+
static int
polaris10_avfs_event_mgr(struct pp_smumgr *smumgr, bool SMU_VFT_INTACT)
{
- struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(smumgr->backend);
+ struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(smumgr->backend);
switch (smu_data->avfs.avfs_btc_status) {
case AVFS_BTC_COMPLETED_PREVIOUSLY:
@@ -185,30 +184,31 @@ polaris10_avfs_event_mgr(struct pp_smumgr *smumgr, bool SMU_VFT_INTACT)
smu_data->avfs.avfs_btc_status = AVFS_BTC_DPMTABLESETUP_FAILED;
PP_ASSERT_WITH_CODE(0 == polaris10_setup_graphics_level_structure(smumgr),
- "[AVFS][Polaris10_AVFSEventMgr] Could not Copy Graphics Level table over to SMU",
- return -1);
+ "[AVFS][Polaris10_AVFSEventMgr] Could not Copy Graphics Level table over to SMU",
+ return -EINVAL);
if (smu_data->avfs.avfs_btc_param > 1) {
pr_info("[AVFS][Polaris10_AVFSEventMgr] AC BTC has not been successfully verified on Fiji. There may be in this setting.");
smu_data->avfs.avfs_btc_status = AVFS_BTC_VIRUS_FAIL;
- PP_ASSERT_WITH_CODE(-1 == polaris10_setup_pwr_virus(smumgr),
+ PP_ASSERT_WITH_CODE(0 == polaris10_setup_pwr_virus(smumgr),
"[AVFS][Polaris10_AVFSEventMgr] Could not setup Pwr Virus for AVFS ",
- return -1);
+ return -EINVAL);
}
smu_data->avfs.avfs_btc_status = AVFS_BTC_FAILED;
PP_ASSERT_WITH_CODE(0 == polaris10_perform_btc(smumgr),
"[AVFS][Polaris10_AVFSEventMgr] Failure at SmuPolaris10_PerformBTC. AVFS Disabled",
- return -1);
-
+ return -EINVAL);
+ smu_data->avfs.avfs_btc_status = AVFS_BTC_ENABLEAVFS;
break;
case AVFS_BTC_DISABLED:
+ case AVFS_BTC_ENABLEAVFS:
case AVFS_BTC_NOTSUPPORTED:
break;
default:
- pr_info("[AVFS] Something is broken. See log!");
+ pr_err("AVFS failed status is %x!\n", smu_data->avfs.avfs_btc_status);
break;
}
@@ -376,11 +376,6 @@ static int polaris10_smu_init(struct pp_smumgr *smumgr)
if (smu7_init(smumgr))
return -EINVAL;
- if (polaris10_is_hw_avfs_present(smumgr))
- smu_data->avfs.avfs_btc_status = AVFS_BTC_BOOT;
- else
- smu_data->avfs.avfs_btc_status = AVFS_BTC_NOTSUPPORTED;
-
for (i = 0; i < SMU74_MAX_LEVELS_GRAPHICS; i++)
smu_data->activity_target[i] = PPPOLARIS10_TARGETACTIVITY_DFLT;
@@ -410,4 +405,5 @@ const struct pp_smumgr_func polaris10_smu_funcs = {
.get_mac_definition = polaris10_get_mac_definition,
.is_dpm_running = polaris10_is_dpm_running,
.populate_requested_graphic_levels = polaris10_populate_requested_graphic_levels,
+ .is_hw_avfs_present = polaris10_is_hw_avfs_present,
};
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.h b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.h
index 49ebf1d..5e19c24 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.h
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.h
@@ -32,11 +32,6 @@
#define SMC_RAM_END 0x40000
-struct polaris10_avfs {
- enum AVFS_BTC_STATUS avfs_btc_status;
- uint32_t avfs_btc_param;
-};
-
struct polaris10_pt_defaults {
uint8_t SviLoadLineEn;
uint8_t SviLoadLineVddC;
@@ -51,8 +46,6 @@ struct polaris10_pt_defaults {
uint16_t BAPMTI_RC[SMU74_DTE_ITERATIONS * SMU74_DTE_SOURCES * SMU74_DTE_SINKS];
};
-
-
struct polaris10_range_table {
uint32_t trans_lower_frequency; /* in 10khz */
uint32_t trans_upper_frequency;
@@ -61,14 +54,13 @@ struct polaris10_range_table {
struct polaris10_smumgr {
struct smu7_smumgr smu7_data;
uint8_t protected_mode;
- struct polaris10_avfs avfs;
SMU74_Discrete_DpmTable smc_state_table;
struct SMU74_Discrete_Ulv ulv_setting;
struct SMU74_Discrete_PmFuses power_tune_table;
struct polaris10_range_table range_table[NUM_SCLK_RANGE];
const struct polaris10_pt_defaults *power_tune_defaults;
- uint32_t activity_target[SMU74_MAX_LEVELS_GRAPHICS];
- uint32_t bif_sclk_table[SMU74_MAX_LEVELS_LINK];
+ uint32_t activity_target[SMU74_MAX_LEVELS_GRAPHICS];
+ uint32_t bif_sclk_table[SMU74_MAX_LEVELS_LINK];
};
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c
index 35ac276..76347ff 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c
@@ -540,7 +540,6 @@ int smu7_upload_smu_firmware_image(struct pp_smumgr *smumgr)
return result;
}
-
int smu7_init(struct pp_smumgr *smumgr)
{
struct smu7_smumgr *smu_data;
@@ -596,6 +595,11 @@ int smu7_init(struct pp_smumgr *smumgr)
(cgs_handle_t)smu_data->smu_buffer.handle);
return -EINVAL);
+ if (smum_is_hw_avfs_present(smumgr))
+ smu_data->avfs.avfs_btc_status = AVFS_BTC_BOOT;
+ else
+ smu_data->avfs.avfs_btc_status = AVFS_BTC_NOTSUPPORTED;
+
return 0;
}
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h
index 919be43..ee5e32d 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h
@@ -37,6 +37,11 @@ struct smu7_buffer_entry {
unsigned long handle;
};
+struct smu7_avfs {
+ enum AVFS_BTC_STATUS avfs_btc_status;
+ uint32_t avfs_btc_param;
+};
+
struct smu7_smumgr {
uint8_t *header;
uint8_t *mec_image;
@@ -50,7 +55,8 @@ struct smu7_smumgr {
uint32_t arb_table_start;
uint32_t ulv_setting_starts;
uint8_t security_hard_key;
- uint32_t acpi_optimization;
+ uint32_t acpi_optimization;
+ struct smu7_avfs avfs;
};
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c
index bcc61ff..3bdf647 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c
@@ -43,7 +43,8 @@ MODULE_FIRMWARE("amdgpu/polaris11_smc.bin");
MODULE_FIRMWARE("amdgpu/polaris11_smc_sk.bin");
MODULE_FIRMWARE("amdgpu/polaris11_k_smc.bin");
MODULE_FIRMWARE("amdgpu/polaris12_smc.bin");
-
+MODULE_FIRMWARE("amdgpu/vega10_smc.bin");
+MODULE_FIRMWARE("amdgpu/vega10_acg_smc.bin");
int smum_early_init(struct pp_instance *handle)
{
@@ -403,3 +404,11 @@ int smum_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr,
return 0;
}
+
+bool smum_is_hw_avfs_present(struct pp_smumgr *smumgr)
+{
+ if (smumgr->smumgr_funcs->is_hw_avfs_present)
+ return smumgr->smumgr_funcs->is_hw_avfs_present(smumgr);
+
+ return false;
+}
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c
index 2696784..408514c 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c
@@ -356,6 +356,9 @@ int vega10_set_tools_address(struct pp_smumgr *smumgr)
static int vega10_verify_smc_interface(struct pp_smumgr *smumgr)
{
uint32_t smc_driver_if_version;
+ struct cgs_system_info sys_info = {0};
+ uint32_t dev_id;
+ uint32_t rev_id;
PP_ASSERT_WITH_CODE(!vega10_send_msg_to_smc(smumgr,
PPSMC_MSG_GetDriverIfVersion),
@@ -363,12 +366,27 @@ static int vega10_verify_smc_interface(struct pp_smumgr *smumgr)
return -EINVAL);
vega10_read_arg_from_smc(smumgr, &smc_driver_if_version);
- if (smc_driver_if_version != SMU9_DRIVER_IF_VERSION) {
- pr_err("Your firmware(0x%x) doesn't match \
- SMU9_DRIVER_IF_VERSION(0x%x). \
- Please update your firmware!\n",
- smc_driver_if_version, SMU9_DRIVER_IF_VERSION);
- return -EINVAL;
+ sys_info.size = sizeof(struct cgs_system_info);
+ sys_info.info_id = CGS_SYSTEM_INFO_PCIE_DEV;
+ cgs_query_system_info(smumgr->device, &sys_info);
+ dev_id = (uint32_t)sys_info.value;
+
+ sys_info.size = sizeof(struct cgs_system_info);
+ sys_info.info_id = CGS_SYSTEM_INFO_PCIE_REV;
+ cgs_query_system_info(smumgr->device, &sys_info);
+ rev_id = (uint32_t)sys_info.value;
+
+ if (!((dev_id == 0x687f) &&
+ ((rev_id == 0xc0) ||
+ (rev_id == 0xc1) ||
+ (rev_id == 0xc3)))) {
+ if (smc_driver_if_version != SMU9_DRIVER_IF_VERSION) {
+ pr_err("Your firmware(0x%x) doesn't match \
+ SMU9_DRIVER_IF_VERSION(0x%x). \
+ Please update your firmware!\n",
+ smc_driver_if_version, SMU9_DRIVER_IF_VERSION);
+ return -EINVAL;
+ }
}
return 0;
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h b/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h
index dbd4fd3a..8bd3810 100644
--- a/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h
+++ b/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h
@@ -16,16 +16,16 @@ TRACE_EVENT(amd_sched_job,
TP_ARGS(sched_job),
TP_STRUCT__entry(
__field(struct amd_sched_entity *, entity)
- __field(struct amd_sched_job *, sched_job)
__field(struct dma_fence *, fence)
__field(const char *, name)
+ __field(uint64_t, id)
__field(u32, job_count)
__field(int, hw_job_count)
),
TP_fast_assign(
__entry->entity = sched_job->s_entity;
- __entry->sched_job = sched_job;
+ __entry->id = sched_job->id;
__entry->fence = &sched_job->s_fence->finished;
__entry->name = sched_job->sched->name;
__entry->job_count = kfifo_len(
@@ -33,8 +33,9 @@ TRACE_EVENT(amd_sched_job,
__entry->hw_job_count = atomic_read(
&sched_job->sched->hw_rq_count);
),
- TP_printk("entity=%p, sched job=%p, fence=%p, ring=%s, job count:%u, hw job count:%d",
- __entry->entity, __entry->sched_job, __entry->fence, __entry->name,
+ TP_printk("entity=%p, id=%llu, fence=%p, ring=%s, job count:%u, hw job count:%d",
+ __entry->entity, __entry->id,
+ __entry->fence, __entry->name,
__entry->job_count, __entry->hw_job_count)
);
diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c
index ad9a959..16903dc 100644
--- a/drivers/gpu/drm/arc/arcpgu_crtc.c
+++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
@@ -64,6 +64,20 @@ static const struct drm_crtc_funcs arc_pgu_crtc_funcs = {
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
};
+static enum drm_mode_status arc_pgu_crtc_mode_valid(struct drm_crtc *crtc,
+ const struct drm_display_mode *mode)
+{
+ struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
+ long rate, clk_rate = mode->clock * 1000;
+ long diff = clk_rate / 200; /* +-0.5% allowed by HDMI spec */
+
+ rate = clk_round_rate(arcpgu->clk, clk_rate);
+ if ((max(rate, clk_rate) - min(rate, clk_rate) < diff) && (rate > 0))
+ return MODE_OK;
+
+ return MODE_NOCLOCK;
+}
+
static void arc_pgu_crtc_mode_set_nofb(struct drm_crtc *crtc)
{
struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
@@ -106,7 +120,8 @@ static void arc_pgu_crtc_mode_set_nofb(struct drm_crtc *crtc)
clk_set_rate(arcpgu->clk, m->crtc_clock * 1000);
}
-static void arc_pgu_crtc_enable(struct drm_crtc *crtc)
+static void arc_pgu_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
@@ -116,7 +131,8 @@ static void arc_pgu_crtc_enable(struct drm_crtc *crtc)
ARCPGU_CTRL_ENABLE_MASK);
}
-static void arc_pgu_crtc_disable(struct drm_crtc *crtc)
+static void arc_pgu_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
@@ -129,20 +145,6 @@ static void arc_pgu_crtc_disable(struct drm_crtc *crtc)
~ARCPGU_CTRL_ENABLE_MASK);
}
-static int arc_pgu_crtc_atomic_check(struct drm_crtc *crtc,
- struct drm_crtc_state *state)
-{
- struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
- struct drm_display_mode *mode = &state->adjusted_mode;
- long rate, clk_rate = mode->clock * 1000;
-
- rate = clk_round_rate(arcpgu->clk, clk_rate);
- if (rate != clk_rate)
- return -EINVAL;
-
- return 0;
-}
-
static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
struct drm_crtc_state *state)
{
@@ -158,15 +160,13 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
}
static const struct drm_crtc_helper_funcs arc_pgu_crtc_helper_funcs = {
+ .mode_valid = arc_pgu_crtc_mode_valid,
.mode_set = drm_helper_crtc_mode_set,
.mode_set_base = drm_helper_crtc_mode_set_base,
.mode_set_nofb = arc_pgu_crtc_mode_set_nofb,
- .enable = arc_pgu_crtc_enable,
- .disable = arc_pgu_crtc_disable,
- .prepare = arc_pgu_crtc_disable,
- .commit = arc_pgu_crtc_enable,
- .atomic_check = arc_pgu_crtc_atomic_check,
.atomic_begin = arc_pgu_crtc_atomic_begin,
+ .atomic_enable = arc_pgu_crtc_atomic_enable,
+ .atomic_disable = arc_pgu_crtc_atomic_disable,
};
static void arc_pgu_plane_atomic_update(struct drm_plane *plane,
@@ -218,6 +218,7 @@ static struct drm_plane *arc_pgu_plane_init(struct drm_device *drm)
ret = drm_universal_plane_init(drm, plane, 0xff, &arc_pgu_plane_funcs,
formats, ARRAY_SIZE(formats),
+ NULL,
DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret)
return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c
index 3e43a5d..289eda5 100644
--- a/drivers/gpu/drm/arc/arcpgu_drv.c
+++ b/drivers/gpu/drm/arc/arcpgu_drv.c
@@ -31,7 +31,7 @@ static void arcpgu_fb_output_poll_changed(struct drm_device *dev)
drm_fbdev_cma_hotplug_event(arcpgu->fbdev);
}
-static struct drm_mode_config_funcs arcpgu_drm_modecfg_funcs = {
+static const struct drm_mode_config_funcs arcpgu_drm_modecfg_funcs = {
.fb_create = drm_fb_cma_create,
.output_poll_changed = arcpgu_fb_output_poll_changed,
.atomic_check = drm_atomic_helper_check,
@@ -48,29 +48,7 @@ static void arcpgu_setup_mode_config(struct drm_device *drm)
drm->mode_config.funcs = &arcpgu_drm_modecfg_funcs;
}
-static int arcpgu_gem_mmap(struct file *filp, struct vm_area_struct *vma)
-{
- int ret;
-
- ret = drm_gem_mmap(filp, vma);
- if (ret)
- return ret;
-
- vma->vm_page_prot = pgprot_noncached(vm_get_page_prot(vma->vm_flags));
- return 0;
-}
-
-static const struct file_operations arcpgu_drm_ops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
- .unlocked_ioctl = drm_ioctl,
- .compat_ioctl = drm_compat_ioctl,
- .poll = drm_poll,
- .read = drm_read,
- .llseek = no_llseek,
- .mmap = arcpgu_gem_mmap,
-};
+DEFINE_DRM_GEM_CMA_FOPS(arcpgu_drm_ops);
static void arcpgu_lastclose(struct drm_device *drm)
{
@@ -142,7 +120,7 @@ static int arcpgu_load(struct drm_device *drm)
return -ENODEV;
}
- platform_set_drvdata(pdev, arcpgu);
+ platform_set_drvdata(pdev, drm);
return 0;
}
@@ -160,11 +138,37 @@ static int arcpgu_unload(struct drm_device *drm)
return 0;
}
+#ifdef CONFIG_DEBUG_FS
+static int arcpgu_show_pxlclock(struct seq_file *m, void *arg)
+{
+ struct drm_info_node *node = (struct drm_info_node *)m->private;
+ struct drm_device *drm = node->minor->dev;
+ struct arcpgu_drm_private *arcpgu = drm->dev_private;
+ unsigned long clkrate = clk_get_rate(arcpgu->clk);
+ unsigned long mode_clock = arcpgu->crtc.mode.crtc_clock * 1000;
+
+ seq_printf(m, "hw : %lu\n", clkrate);
+ seq_printf(m, "mode: %lu\n", mode_clock);
+ return 0;
+}
+
+static struct drm_info_list arcpgu_debugfs_list[] = {
+ { "clocks", arcpgu_show_pxlclock, 0 },
+ { "fb", drm_fb_cma_debugfs_show, 0 },
+};
+
+static int arcpgu_debugfs_init(struct drm_minor *minor)
+{
+ return drm_debugfs_create_files(arcpgu_debugfs_list,
+ ARRAY_SIZE(arcpgu_debugfs_list), minor->debugfs_root, minor);
+}
+#endif
+
static struct drm_driver arcpgu_drm_driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
DRIVER_ATOMIC,
.lastclose = arcpgu_lastclose,
- .name = "drm-arcpgu",
+ .name = "arcpgu",
.desc = "ARC PGU Controller",
.date = "20160219",
.major = 1,
@@ -172,8 +176,6 @@ static struct drm_driver arcpgu_drm_driver = {
.patchlevel = 0,
.fops = &arcpgu_drm_ops,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_free_object_unlocked = drm_gem_cma_free_object,
@@ -185,6 +187,9 @@ static struct drm_driver arcpgu_drm_driver = {
.gem_prime_vmap = drm_gem_cma_prime_vmap,
.gem_prime_vunmap = drm_gem_cma_prime_vunmap,
.gem_prime_mmap = drm_gem_cma_prime_mmap,
+#ifdef CONFIG_DEBUG_FS
+ .debugfs_init = arcpgu_debugfs_init,
+#endif
};
static int arcpgu_probe(struct platform_device *pdev)
diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
index d67b6f1..72b22b8 100644
--- a/drivers/gpu/drm/arm/hdlcd_crtc.c
+++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
@@ -165,7 +165,8 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc)
clk_set_rate(hdlcd->clk, m->crtc_clock * 1000);
}
-static void hdlcd_crtc_enable(struct drm_crtc *crtc)
+static void hdlcd_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
@@ -175,7 +176,8 @@ static void hdlcd_crtc_enable(struct drm_crtc *crtc)
drm_crtc_vblank_on(crtc);
}
-static void hdlcd_crtc_disable(struct drm_crtc *crtc)
+static void hdlcd_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
@@ -218,10 +220,10 @@ static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc,
}
static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = {
- .enable = hdlcd_crtc_enable,
- .disable = hdlcd_crtc_disable,
.atomic_check = hdlcd_crtc_atomic_check,
.atomic_begin = hdlcd_crtc_atomic_begin,
+ .atomic_enable = hdlcd_crtc_atomic_enable,
+ .atomic_disable = hdlcd_crtc_atomic_disable,
};
static int hdlcd_plane_atomic_check(struct drm_plane *plane,
@@ -313,6 +315,7 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm)
ret = drm_universal_plane_init(drm, plane, 0xff, &hdlcd_plane_funcs,
formats, ARRAY_SIZE(formats),
+ NULL,
DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret) {
return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index d3da87f..f9bda7b 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -253,8 +253,6 @@ static struct drm_driver hdlcd_driver = {
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_export = drm_gem_prime_export,
@@ -343,7 +341,6 @@ err_register:
}
err_fbdev:
drm_kms_helper_poll_fini(drm);
- drm_vblank_cleanup(drm);
err_vblank:
pm_runtime_disable(drm->dev);
err_pm_active:
@@ -375,7 +372,6 @@ static void hdlcd_drm_unbind(struct device *dev)
component_unbind_all(dev, drm);
of_node_put(hdlcd->crtc.port);
hdlcd->crtc.port = NULL;
- drm_vblank_cleanup(drm);
pm_runtime_get_sync(drm->dev);
drm_irq_uninstall(drm);
pm_runtime_put_sync(drm->dev);
diff --git a/drivers/gpu/drm/arm/malidp_crtc.c b/drivers/gpu/drm/arm/malidp_crtc.c
index 4bb38a2..3615d18 100644
--- a/drivers/gpu/drm/arm/malidp_crtc.c
+++ b/drivers/gpu/drm/arm/malidp_crtc.c
@@ -46,7 +46,8 @@ static enum drm_mode_status malidp_crtc_mode_valid(struct drm_crtc *crtc,
return MODE_OK;
}
-static void malidp_crtc_enable(struct drm_crtc *crtc)
+static void malidp_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct malidp_drm *malidp = crtc_to_malidp_device(crtc);
struct malidp_hw_device *hwdev = malidp->dev;
@@ -69,7 +70,8 @@ static void malidp_crtc_enable(struct drm_crtc *crtc)
drm_crtc_vblank_on(crtc);
}
-static void malidp_crtc_disable(struct drm_crtc *crtc)
+static void malidp_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct malidp_drm *malidp = crtc_to_malidp_device(crtc);
struct malidp_hw_device *hwdev = malidp->dev;
@@ -408,9 +410,9 @@ static int malidp_crtc_atomic_check(struct drm_crtc *crtc,
static const struct drm_crtc_helper_funcs malidp_crtc_helper_funcs = {
.mode_valid = malidp_crtc_mode_valid,
- .enable = malidp_crtc_enable,
- .disable = malidp_crtc_disable,
.atomic_check = malidp_crtc_atomic_check,
+ .atomic_enable = malidp_crtc_atomic_enable,
+ .atomic_disable = malidp_crtc_atomic_disable,
};
static struct drm_crtc_state *malidp_crtc_duplicate_state(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index 01b13d2..1a57cc2 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -225,7 +225,7 @@ static void malidp_atomic_commit_tail(struct drm_atomic_state *state)
drm_atomic_helper_commit_modeset_disables(drm, state);
- for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
+ for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) {
malidp_atomic_commit_update_gamma(crtc, old_crtc_state);
malidp_atomic_commit_update_coloradj(crtc, old_crtc_state);
malidp_atomic_commit_se_config(crtc, old_crtc_state);
@@ -331,8 +331,6 @@ static struct drm_driver malidp_driver = {
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_export = drm_gem_prime_export,
diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c
index 600fa7b..94e7e3f 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -128,7 +128,6 @@ static void malidp_plane_atomic_print_state(struct drm_printer *p,
static const struct drm_plane_funcs malidp_de_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
- .set_property = drm_atomic_helper_plane_set_property,
.destroy = malidp_de_plane_destroy,
.reset = malidp_plane_reset,
.atomic_duplicate_state = malidp_duplicate_plane_state,
@@ -398,7 +397,7 @@ int malidp_de_planes_init(struct drm_device *drm)
DRM_PLANE_TYPE_OVERLAY;
ret = drm_universal_plane_init(drm, &plane->base, crtcs,
&malidp_de_plane_funcs, formats,
- n, plane_type, NULL);
+ n, NULL, plane_type, NULL);
if (ret < 0)
goto cleanup;
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 4fe19fd..2a4d163 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -334,16 +334,6 @@ static void armada_drm_vblank_off(struct armada_crtc *dcrtc)
armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary);
}
-void armada_drm_crtc_gamma_set(struct drm_crtc *crtc, u16 r, u16 g, u16 b,
- int idx)
-{
-}
-
-void armada_drm_crtc_gamma_get(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
- int idx)
-{
-}
-
/* The mode_config.mutex will be held for this call */
static void armada_drm_crtc_dpms(struct drm_crtc *crtc, int dpms)
{
@@ -1150,13 +1140,13 @@ int armada_drm_plane_init(struct armada_plane *plane)
return 0;
}
-static struct drm_prop_enum_list armada_drm_csc_yuv_enum_list[] = {
+static const struct drm_prop_enum_list armada_drm_csc_yuv_enum_list[] = {
{ CSC_AUTO, "Auto" },
{ CSC_YUV_CCIR601, "CCIR601" },
{ CSC_YUV_CCIR709, "CCIR709" },
};
-static struct drm_prop_enum_list armada_drm_csc_rgb_enum_list[] = {
+static const struct drm_prop_enum_list armada_drm_csc_rgb_enum_list[] = {
{ CSC_AUTO, "Auto" },
{ CSC_RGB_COMPUTER, "Computer system" },
{ CSC_RGB_STUDIO, "Studio" },
@@ -1269,6 +1259,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
&armada_primary_plane_funcs,
armada_primary_formats,
ARRAY_SIZE(armada_primary_formats),
+ NULL,
DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret) {
kfree(primary);
@@ -1329,8 +1320,7 @@ armada_lcd_bind(struct device *dev, struct device *master, void *data)
port = of_get_child_by_name(parent, "port");
of_node_put(np);
if (!port) {
- dev_err(dev, "no port node found in %s\n",
- parent->full_name);
+ dev_err(dev, "no port node found in %pOF\n", parent);
return -ENXIO;
}
@@ -1364,7 +1354,7 @@ static int armada_lcd_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id armada_lcd_of_match[] = {
+static const struct of_device_id armada_lcd_of_match[] = {
{
.compatible = "marvell,dove-lcd",
.data = &armada510_ops,
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 7e8906d..bab11f4 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -102,8 +102,6 @@ struct armada_crtc {
};
#define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc)
-void armada_drm_crtc_gamma_set(struct drm_crtc *, u16, u16, u16, int);
-void armada_drm_crtc_gamma_get(struct drm_crtc *, u16 *, u16 *, u16 *, int);
void armada_drm_crtc_update_regs(struct armada_crtc *, struct armada_regs *);
void armada_drm_crtc_plane_disable(struct armada_crtc *dcrtc,
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index e618fab..0b3227c 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -232,8 +232,8 @@ static void armada_add_endpoints(struct device *dev,
of_node_put(remote);
continue;
} else if (!of_device_is_available(remote->parent)) {
- dev_warn(dev, "parent device of %s is not available\n",
- remote->full_name);
+ dev_warn(dev, "parent device of %pOF is not available\n",
+ remote);
of_node_put(remote);
continue;
}
diff --git a/drivers/gpu/drm/armada/armada_fbdev.c b/drivers/gpu/drm/armada/armada_fbdev.c
index 602dfea..29c7d04 100644
--- a/drivers/gpu/drm/armada/armada_fbdev.c
+++ b/drivers/gpu/drm/armada/armada_fbdev.c
@@ -81,7 +81,6 @@ static int armada_fb_create(struct drm_fb_helper *fbh,
strlcpy(info->fix.id, "armada-drmfb", sizeof(info->fix.id));
info->par = fbh;
- info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
info->fbops = &armada_fb_ops;
info->fix.smem_start = obj->phys_addr;
info->fix.smem_len = obj->obj.size;
@@ -118,8 +117,6 @@ static int armada_fb_probe(struct drm_fb_helper *fbh,
}
static const struct drm_fb_helper_funcs armada_fb_helper_funcs = {
- .gamma_set = armada_drm_crtc_gamma_set,
- .gamma_get = armada_drm_crtc_gamma_get,
.fb_probe = armada_fb_probe,
};
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index e9a29df..edc4491 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -388,7 +388,7 @@ static const uint32_t armada_ovl_formats[] = {
DRM_FORMAT_BGR565,
};
-static struct drm_prop_enum_list armada_drm_colorkey_enum_list[] = {
+static const struct drm_prop_enum_list armada_drm_colorkey_enum_list[] = {
{ CKMODE_DISABLE, "disabled" },
{ CKMODE_Y, "Y component" },
{ CKMODE_U, "U component" },
@@ -460,6 +460,7 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
&armada_ovl_plane_funcs,
armada_ovl_formats,
ARRAY_SIZE(armada_ovl_formats),
+ NULL,
DRM_PLANE_TYPE_OVERLAY, NULL);
if (ret) {
kfree(dplane);
diff --git a/drivers/gpu/drm/ast/ast_dp501.c b/drivers/gpu/drm/ast/ast_dp501.c
index 76f07f3..749646a 100644
--- a/drivers/gpu/drm/ast/ast_dp501.c
+++ b/drivers/gpu/drm/ast/ast_dp501.c
@@ -4,16 +4,11 @@
#include "ast_drv.h"
MODULE_FIRMWARE("ast_dp501_fw.bin");
-int ast_load_dp501_microcode(struct drm_device *dev)
+static int ast_load_dp501_microcode(struct drm_device *dev)
{
struct ast_private *ast = dev->dev_private;
- static char *fw_name = "ast_dp501_fw.bin";
- int err;
- err = request_firmware(&ast->dp501_fw, fw_name, dev->dev);
- if (err)
- return err;
- return 0;
+ return request_firmware(&ast->dp501_fw, "ast_dp501_fw.bin", dev->dev);
}
static void send_ack(struct ast_private *ast)
@@ -187,7 +182,7 @@ bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size)
return false;
}
-bool ast_launch_m68k(struct drm_device *dev)
+static bool ast_launch_m68k(struct drm_device *dev)
{
struct ast_private *ast = dev->dev_private;
u32 i, data, len = 0;
@@ -201,7 +196,11 @@ bool ast_launch_m68k(struct drm_device *dev)
if (ast->dp501_fw_addr) {
fw_addr = ast->dp501_fw_addr;
len = 32*1024;
- } else if (ast->dp501_fw) {
+ } else {
+ if (!ast->dp501_fw &&
+ ast_load_dp501_microcode(dev) < 0)
+ return false;
+
fw_addr = (u8 *)ast->dp501_fw->data;
len = ast->dp501_fw->size;
}
@@ -432,3 +431,11 @@ void ast_init_3rdtx(struct drm_device *dev)
}
}
}
+
+void ast_release_firmware(struct drm_device *dev)
+{
+ struct ast_private *ast = dev->dev_private;
+
+ release_firmware(ast->dp501_fw);
+ ast->dp501_fw = NULL;
+}
diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
index fd7c9ee..69dab82 100644
--- a/drivers/gpu/drm/ast/ast_drv.c
+++ b/drivers/gpu/drm/ast/ast_drv.c
@@ -197,7 +197,6 @@ static struct drm_driver driver = {
.load = ast_driver_load,
.unload = ast_driver_unload,
- .set_busid = drm_pci_set_busid,
.fops = &ast_fops,
.name = DRIVER_NAME,
@@ -210,7 +209,6 @@ static struct drm_driver driver = {
.gem_free_object_unlocked = ast_gem_free_object,
.dumb_create = ast_dumb_create,
.dumb_map_offset = ast_dumb_mmap_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
};
@@ -221,11 +219,11 @@ static int __init ast_init(void)
if (ast_modeset == 0)
return -EINVAL;
- return drm_pci_init(&driver, &ast_pci_driver);
+ return pci_register_driver(&ast_pci_driver);
}
static void __exit ast_exit(void)
{
- drm_pci_exit(&driver, &ast_pci_driver);
+ pci_unregister_driver(&ast_pci_driver);
}
module_init(ast_init);
diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index 8880f0b..e6c4cd3 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -245,7 +245,6 @@ struct ast_connector {
struct ast_crtc {
struct drm_crtc base;
- u8 lut_r[256], lut_g[256], lut_b[256];
struct drm_gem_object *cursor_bo;
uint64_t cursor_addr;
int cursor_width, cursor_height;
@@ -401,11 +400,10 @@ void ast_post_gpu(struct drm_device *dev);
u32 ast_mindwm(struct ast_private *ast, u32 r);
void ast_moutdwm(struct ast_private *ast, u32 r, u32 v);
/* ast dp501 */
-int ast_load_dp501_microcode(struct drm_device *dev);
void ast_set_dp501_video_output(struct drm_device *dev, u8 mode);
-bool ast_launch_m68k(struct drm_device *dev);
bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size);
bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata);
u8 ast_get_dp501_max_clk(struct drm_device *dev);
void ast_init_3rdtx(struct drm_device *dev);
+void ast_release_firmware(struct drm_device *dev);
#endif
diff --git a/drivers/gpu/drm/ast/ast_fb.c b/drivers/gpu/drm/ast/ast_fb.c
index 4ad4acd..0cd827e 100644
--- a/drivers/gpu/drm/ast/ast_fb.c
+++ b/drivers/gpu/drm/ast/ast_fb.c
@@ -231,7 +231,6 @@ static int astfb_create(struct drm_fb_helper *helper,
strcpy(info->fix.id, "astdrmfb");
- info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
info->fbops = &astfb_ops;
info->apertures->ranges[0].base = pci_resource_start(dev->pdev, 0);
@@ -255,27 +254,7 @@ out:
return ret;
}
-static void ast_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno)
-{
- struct ast_crtc *ast_crtc = to_ast_crtc(crtc);
- ast_crtc->lut_r[regno] = red >> 8;
- ast_crtc->lut_g[regno] = green >> 8;
- ast_crtc->lut_b[regno] = blue >> 8;
-}
-
-static void ast_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
- u16 *blue, int regno)
-{
- struct ast_crtc *ast_crtc = to_ast_crtc(crtc);
- *red = ast_crtc->lut_r[regno] << 8;
- *green = ast_crtc->lut_g[regno] << 8;
- *blue = ast_crtc->lut_b[regno] << 8;
-}
-
static const struct drm_fb_helper_funcs ast_fb_helper_funcs = {
- .gamma_set = ast_fb_gamma_set,
- .gamma_get = ast_fb_gamma_get,
.fb_probe = astfb_create,
};
@@ -287,7 +266,7 @@ static void ast_fbdev_destroy(struct drm_device *dev,
drm_fb_helper_unregister_fbi(&afbdev->helper);
if (afb->obj) {
- drm_gem_object_unreference_unlocked(afb->obj);
+ drm_gem_object_put_unlocked(afb->obj);
afb->obj = NULL;
}
drm_fb_helper_fini(&afbdev->helper);
diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
index 262c2c0..dac3558 100644
--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
@@ -387,9 +387,9 @@ static void ast_user_framebuffer_destroy(struct drm_framebuffer *fb)
{
struct ast_framebuffer *ast_fb = to_ast_framebuffer(fb);
- drm_gem_object_unreference_unlocked(ast_fb->obj);
+ drm_gem_object_put_unlocked(ast_fb->obj);
drm_framebuffer_cleanup(fb);
- kfree(fb);
+ kfree(ast_fb);
}
static const struct drm_framebuffer_funcs ast_fb_funcs = {
@@ -429,13 +429,13 @@ ast_user_framebuffer_create(struct drm_device *dev,
ast_fb = kzalloc(sizeof(*ast_fb), GFP_KERNEL);
if (!ast_fb) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ERR_PTR(-ENOMEM);
}
ret = ast_framebuffer_init(dev, ast_fb, mode_cmd, obj);
if (ret) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
kfree(ast_fb);
return ERR_PTR(ret);
}
@@ -576,6 +576,7 @@ void ast_driver_unload(struct drm_device *dev)
{
struct ast_private *ast = dev->dev_private;
+ ast_release_firmware(dev);
kfree(ast->dp501_fw_addr);
ast_mode_fini(dev);
ast_fbdev_fini(dev);
@@ -627,7 +628,7 @@ int ast_dumb_create(struct drm_file *file,
return ret;
ret = drm_gem_handle_create(file, gobj, &handle);
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
if (ret)
return ret;
@@ -675,7 +676,7 @@ ast_dumb_mmap_offset(struct drm_file *file,
bo = gem_to_ast_bo(obj);
*offset = ast_bo_mmap_offset(bo);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return 0;
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index aaef0a6..6f3849e 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -63,15 +63,18 @@ static inline void ast_load_palette_index(struct ast_private *ast,
static void ast_crtc_load_lut(struct drm_crtc *crtc)
{
struct ast_private *ast = crtc->dev->dev_private;
- struct ast_crtc *ast_crtc = to_ast_crtc(crtc);
+ u16 *r, *g, *b;
int i;
if (!crtc->enabled)
return;
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
+
for (i = 0; i < 256; i++)
- ast_load_palette_index(ast, i, ast_crtc->lut_r[i],
- ast_crtc->lut_g[i], ast_crtc->lut_b[i]);
+ ast_load_palette_index(ast, i, *r++ >> 8, *g++ >> 8, *b++ >> 8);
}
static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mode *mode,
@@ -613,7 +616,23 @@ static int ast_crtc_mode_set(struct drm_crtc *crtc,
static void ast_crtc_disable(struct drm_crtc *crtc)
{
+ int ret;
+ DRM_DEBUG_KMS("\n");
+ ast_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+ if (crtc->primary->fb) {
+ struct ast_framebuffer *ast_fb = to_ast_framebuffer(crtc->primary->fb);
+ struct drm_gem_object *obj = ast_fb->obj;
+ struct ast_bo *bo = gem_to_ast_bo(obj);
+
+ ret = ast_bo_reserve(bo, false);
+ if (ret)
+ return;
+
+ ast_bo_push_sysram(bo);
+ ast_bo_unreserve(bo);
+ }
+ crtc->primary->fb = NULL;
}
static void ast_crtc_prepare(struct drm_crtc *crtc)
@@ -633,7 +652,6 @@ static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = {
.mode_set = ast_crtc_mode_set,
.mode_set_base = ast_crtc_mode_set_base,
.disable = ast_crtc_disable,
- .load_lut = ast_crtc_load_lut,
.prepare = ast_crtc_prepare,
.commit = ast_crtc_commit,
@@ -648,15 +666,6 @@ static int ast_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
u16 *blue, uint32_t size,
struct drm_modeset_acquire_ctx *ctx)
{
- struct ast_crtc *ast_crtc = to_ast_crtc(crtc);
- int i;
-
- /* userspace palettes are always correct as is */
- for (i = 0; i < size; i++) {
- ast_crtc->lut_r[i] = red[i] >> 8;
- ast_crtc->lut_g[i] = green[i] >> 8;
- ast_crtc->lut_b[i] = blue[i] >> 8;
- }
ast_crtc_load_lut(crtc);
return 0;
@@ -681,7 +690,6 @@ static const struct drm_crtc_funcs ast_crtc_funcs = {
static int ast_crtc_init(struct drm_device *dev)
{
struct ast_crtc *crtc;
- int i;
crtc = kzalloc(sizeof(struct ast_crtc), GFP_KERNEL);
if (!crtc)
@@ -690,12 +698,6 @@ static int ast_crtc_init(struct drm_device *dev)
drm_crtc_init(dev, &crtc->base, &ast_crtc_funcs);
drm_mode_crtc_set_gamma_size(&crtc->base, 256);
drm_crtc_helper_add(&crtc->base, &ast_crtc_helper_funcs);
-
- for (i = 0; i < 256; i++) {
- crtc->lut_r[i] = i;
- crtc->lut_g[i] = i;
- crtc->lut_b[i] = i;
- }
return 0;
}
@@ -948,7 +950,7 @@ static void ast_cursor_fini(struct drm_device *dev)
{
struct ast_private *ast = dev->dev_private;
ttm_bo_kunmap(&ast->cache_kmap);
- drm_gem_object_unreference_unlocked(ast->cursor_cache);
+ drm_gem_object_put_unlocked(ast->cursor_cache);
}
int ast_mode_init(struct drm_device *dev)
@@ -1213,10 +1215,10 @@ static int ast_cursor_set(struct drm_crtc *crtc,
ast_show_cursor(crtc);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return 0;
fail:
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
diff --git a/drivers/gpu/drm/ast/ast_ttm.c b/drivers/gpu/drm/ast/ast_ttm.c
index 5808498..696a15d 100644
--- a/drivers/gpu/drm/ast/ast_ttm.c
+++ b/drivers/gpu/drm/ast/ast_ttm.c
@@ -323,10 +323,8 @@ int ast_bo_create(struct drm_device *dev, int size, int align,
return -ENOMEM;
ret = drm_gem_object_init(dev, &astbo->gem, size);
- if (ret) {
- kfree(astbo);
- return ret;
- }
+ if (ret)
+ goto error;
astbo->bo.bdev = &ast->ttm.bdev;
@@ -340,10 +338,13 @@ int ast_bo_create(struct drm_device *dev, int size, int align,
align >> PAGE_SHIFT, false, NULL, acc_size,
NULL, NULL, ast_bo_ttm_destroy);
if (ret)
- return ret;
+ goto error;
*pastbo = astbo;
return 0;
+error:
+ kfree(astbo);
+ return ret;
}
static inline u64 ast_bo_gpu_offset(struct ast_bo *bo)
@@ -376,7 +377,7 @@ int ast_bo_pin(struct ast_bo *bo, u32 pl_flag, u64 *gpu_addr)
int ast_bo_unpin(struct ast_bo *bo)
{
- int i, ret;
+ int i;
if (!bo->pin_count) {
DRM_ERROR("unpin bad %p\n", bo);
return 0;
@@ -387,11 +388,7 @@ int ast_bo_unpin(struct ast_bo *bo)
for (i = 0; i < bo->placement.num_placement ; i++)
bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
- ret = ttm_bo_validate(&bo->bo, &bo->placement, false, false);
- if (ret)
- return ret;
-
- return 0;
+ return ttm_bo_validate(&bo->bo, &bo->placement, false, false);
}
int ast_bo_push_sysram(struct ast_bo *bo)
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
index 5348985..d732810 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
@@ -149,7 +149,8 @@ atmel_hlcdc_crtc_mode_valid(struct drm_crtc *c,
return atmel_hlcdc_dc_mode_valid(crtc->dc, mode);
}
-static void atmel_hlcdc_crtc_disable(struct drm_crtc *c)
+static void atmel_hlcdc_crtc_atomic_disable(struct drm_crtc *c,
+ struct drm_crtc_state *old_state)
{
struct drm_device *dev = c->dev;
struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c);
@@ -183,7 +184,8 @@ static void atmel_hlcdc_crtc_disable(struct drm_crtc *c)
pm_runtime_put_sync(dev->dev);
}
-static void atmel_hlcdc_crtc_enable(struct drm_crtc *c)
+static void atmel_hlcdc_crtc_atomic_enable(struct drm_crtc *c,
+ struct drm_crtc_state *old_state)
{
struct drm_device *dev = c->dev;
struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c);
@@ -235,7 +237,7 @@ static int atmel_hlcdc_crtc_select_output_mode(struct drm_crtc_state *state)
crtc = drm_crtc_to_atmel_hlcdc_crtc(state->crtc);
- for_each_connector_in_state(state->state, connector, cstate, i) {
+ for_each_new_connector_in_state(state->state, connector, cstate, i) {
struct drm_display_info *info = &connector->display_info;
unsigned int supported_fmts = 0;
int j;
@@ -319,11 +321,11 @@ static const struct drm_crtc_helper_funcs lcdc_crtc_helper_funcs = {
.mode_set = drm_helper_crtc_mode_set,
.mode_set_nofb = atmel_hlcdc_crtc_mode_set_nofb,
.mode_set_base = drm_helper_crtc_mode_set_base,
- .disable = atmel_hlcdc_crtc_disable,
- .enable = atmel_hlcdc_crtc_enable,
.atomic_check = atmel_hlcdc_crtc_atomic_check,
.atomic_begin = atmel_hlcdc_crtc_atomic_begin,
.atomic_flush = atmel_hlcdc_crtc_atomic_flush,
+ .atomic_enable = atmel_hlcdc_crtc_atomic_enable,
+ .atomic_disable = atmel_hlcdc_crtc_atomic_disable,
};
static void atmel_hlcdc_crtc_destroy(struct drm_crtc *c)
@@ -429,6 +431,7 @@ static const struct drm_crtc_funcs atmel_hlcdc_crtc_funcs = {
.atomic_destroy_state = atmel_hlcdc_crtc_destroy_state,
.enable_vblank = atmel_hlcdc_crtc_enable_vblank,
.disable_vblank = atmel_hlcdc_crtc_disable_vblank,
+ .gamma_set = drm_atomic_helper_legacy_gamma_set,
};
int atmel_hlcdc_crtc_create(struct drm_device *dev)
@@ -484,6 +487,10 @@ int atmel_hlcdc_crtc_create(struct drm_device *dev)
drm_crtc_helper_add(&crtc->base, &lcdc_crtc_helper_funcs);
drm_crtc_vblank_reset(&crtc->base);
+ drm_mode_crtc_set_gamma_size(&crtc->base, ATMEL_HLCDC_CLUT_SIZE);
+ drm_crtc_enable_color_mgmt(&crtc->base, 0, false,
+ ATMEL_HLCDC_CLUT_SIZE);
+
dc->crtc = &crtc->base;
return 0;
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
index 30dbffd..74d66e1 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
@@ -42,6 +42,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9n12_layers[] = {
.default_color = 3,
.general_config = 4,
},
+ .clut_offset = 0x400,
},
};
@@ -73,6 +74,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = {
.disc_pos = 5,
.disc_size = 6,
},
+ .clut_offset = 0x400,
},
{
.name = "overlay1",
@@ -91,6 +93,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = {
.chroma_key_mask = 8,
.general_config = 9,
},
+ .clut_offset = 0x800,
},
{
.name = "high-end-overlay",
@@ -112,6 +115,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = {
.scaler_config = 13,
.csc = 14,
},
+ .clut_offset = 0x1000,
},
{
.name = "cursor",
@@ -131,6 +135,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = {
.chroma_key_mask = 8,
.general_config = 9,
},
+ .clut_offset = 0x1400,
},
};
@@ -162,6 +167,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
.disc_pos = 5,
.disc_size = 6,
},
+ .clut_offset = 0x600,
},
{
.name = "overlay1",
@@ -180,6 +186,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
.chroma_key_mask = 8,
.general_config = 9,
},
+ .clut_offset = 0xa00,
},
{
.name = "overlay2",
@@ -198,6 +205,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
.chroma_key_mask = 8,
.general_config = 9,
},
+ .clut_offset = 0xe00,
},
{
.name = "high-end-overlay",
@@ -223,6 +231,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
},
.csc = 14,
},
+ .clut_offset = 0x1200,
},
{
.name = "cursor",
@@ -244,6 +253,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
.general_config = 9,
.scaler_config = 13,
},
+ .clut_offset = 0x1600,
},
};
@@ -275,6 +285,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = {
.disc_pos = 5,
.disc_size = 6,
},
+ .clut_offset = 0x600,
},
{
.name = "overlay1",
@@ -293,6 +304,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = {
.chroma_key_mask = 8,
.general_config = 9,
},
+ .clut_offset = 0xa00,
},
{
.name = "overlay2",
@@ -311,6 +323,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = {
.chroma_key_mask = 8,
.general_config = 9,
},
+ .clut_offset = 0xe00,
},
{
.name = "high-end-overlay",
@@ -336,6 +349,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = {
},
.csc = 14,
},
+ .clut_offset = 0x1200,
},
};
@@ -451,8 +465,7 @@ static void atmel_hlcdc_fb_output_poll_changed(struct drm_device *dev)
{
struct atmel_hlcdc_dc *dc = dev->dev_private;
- if (dc->fbdev)
- drm_fbdev_cma_hotplug_event(dc->fbdev);
+ drm_fbdev_cma_hotplug_event(dc->fbdev);
}
struct atmel_hlcdc_dc_commit {
@@ -526,14 +539,13 @@ static int atmel_hlcdc_dc_atomic_commit(struct drm_device *dev,
dc->commit.pending = true;
spin_unlock(&dc->commit.wait.lock);
- if (ret) {
- kfree(commit);
- goto error;
- }
+ if (ret)
+ goto err_free;
- /* Swap the state, this is the point of no return. */
- drm_atomic_helper_swap_state(state, true);
+ /* We have our own synchronization through the commit lock. */
+ BUG_ON(drm_atomic_helper_swap_state(state, false) < 0);
+ /* Swap state succeeded, this is the point of no return. */
drm_atomic_state_get(state);
if (async)
queue_work(dc->wq, &commit->work);
@@ -542,6 +554,8 @@ static int atmel_hlcdc_dc_atomic_commit(struct drm_device *dev,
return 0;
+err_free:
+ kfree(commit);
error:
drm_atomic_helper_cleanup_planes(dev, state);
return ret;
@@ -747,8 +761,6 @@ static struct drm_driver atmel_hlcdc_dc_driver = {
.gem_prime_vunmap = drm_gem_cma_prime_vunmap,
.gem_prime_mmap = drm_gem_cma_prime_mmap,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.fops = &fops,
.name = "atmel-hlcdc",
.desc = "Atmel HLCD Controller DRM",
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
index b0596a8..4237b04 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
@@ -88,6 +88,11 @@
#define ATMEL_HLCDC_YUV422SWP BIT(17)
#define ATMEL_HLCDC_DSCALEOPT BIT(20)
+#define ATMEL_HLCDC_C1_MODE ATMEL_HLCDC_CLUT_MODE(0)
+#define ATMEL_HLCDC_C2_MODE ATMEL_HLCDC_CLUT_MODE(1)
+#define ATMEL_HLCDC_C4_MODE ATMEL_HLCDC_CLUT_MODE(2)
+#define ATMEL_HLCDC_C8_MODE ATMEL_HLCDC_CLUT_MODE(3)
+
#define ATMEL_HLCDC_XRGB4444_MODE ATMEL_HLCDC_RGB_MODE(0)
#define ATMEL_HLCDC_ARGB4444_MODE ATMEL_HLCDC_RGB_MODE(1)
#define ATMEL_HLCDC_RGBA4444_MODE ATMEL_HLCDC_RGB_MODE(2)
@@ -142,6 +147,8 @@
#define ATMEL_HLCDC_DMA_CHANNEL_DSCR_DONE BIT(2)
#define ATMEL_HLCDC_DMA_CHANNEL_DSCR_OVERRUN BIT(3)
+#define ATMEL_HLCDC_CLUT_SIZE 256
+
#define ATMEL_HLCDC_MAX_LAYERS 6
/**
@@ -259,6 +266,7 @@ struct atmel_hlcdc_layer_desc {
int id;
int regs_offset;
int cfgs_offset;
+ int clut_offset;
struct atmel_hlcdc_formats *formats;
struct atmel_hlcdc_layer_cfg_layout layout;
int max_width;
@@ -414,6 +422,14 @@ static inline u32 atmel_hlcdc_layer_read_cfg(struct atmel_hlcdc_layer *layer,
(cfgid * sizeof(u32)));
}
+static inline void atmel_hlcdc_layer_write_clut(struct atmel_hlcdc_layer *layer,
+ unsigned int c, u32 val)
+{
+ regmap_write(layer->regmap,
+ layer->desc->clut_offset + c * sizeof(u32),
+ val);
+}
+
static inline void atmel_hlcdc_layer_init(struct atmel_hlcdc_layer *layer,
const struct atmel_hlcdc_layer_desc *desc,
struct regmap *regmap)
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
index 1124200..703c2d1 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
@@ -83,6 +83,7 @@ drm_plane_state_to_atmel_hlcdc_plane_state(struct drm_plane_state *s)
#define SUBPIXEL_MASK 0xffff
static uint32_t rgb_formats[] = {
+ DRM_FORMAT_C8,
DRM_FORMAT_XRGB4444,
DRM_FORMAT_ARGB4444,
DRM_FORMAT_RGBA4444,
@@ -100,6 +101,7 @@ struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_formats = {
};
static uint32_t rgb_and_yuv_formats[] = {
+ DRM_FORMAT_C8,
DRM_FORMAT_XRGB4444,
DRM_FORMAT_ARGB4444,
DRM_FORMAT_RGBA4444,
@@ -128,6 +130,9 @@ struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_and_yuv_formats = {
static int atmel_hlcdc_format_to_plane_mode(u32 format, u32 *mode)
{
switch (format) {
+ case DRM_FORMAT_C8:
+ *mode = ATMEL_HLCDC_C8_MODE;
+ break;
case DRM_FORMAT_XRGB4444:
*mode = ATMEL_HLCDC_XRGB4444_MODE;
break;
@@ -424,6 +429,29 @@ static void atmel_hlcdc_plane_update_format(struct atmel_hlcdc_plane *plane,
ATMEL_HLCDC_LAYER_FORMAT_CFG, cfg);
}
+static void atmel_hlcdc_plane_update_clut(struct atmel_hlcdc_plane *plane)
+{
+ struct drm_crtc *crtc = plane->base.crtc;
+ struct drm_color_lut *lut;
+ int idx;
+
+ if (!crtc || !crtc->state)
+ return;
+
+ if (!crtc->state->color_mgmt_changed || !crtc->state->gamma_lut)
+ return;
+
+ lut = (struct drm_color_lut *)crtc->state->gamma_lut->data;
+
+ for (idx = 0; idx < ATMEL_HLCDC_CLUT_SIZE; idx++, lut++) {
+ u32 val = ((lut->red << 8) & 0xff0000) |
+ (lut->green & 0xff00) |
+ (lut->blue >> 8);
+
+ atmel_hlcdc_layer_write_clut(&plane->layer, idx, val);
+ }
+}
+
static void atmel_hlcdc_plane_update_buffers(struct atmel_hlcdc_plane *plane,
struct atmel_hlcdc_plane_state *state)
{
@@ -768,6 +796,7 @@ static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p,
atmel_hlcdc_plane_update_pos_and_size(plane, state);
atmel_hlcdc_plane_update_general_settings(plane, state);
atmel_hlcdc_plane_update_format(plane, state);
+ atmel_hlcdc_plane_update_clut(plane);
atmel_hlcdc_plane_update_buffers(plane, state);
atmel_hlcdc_plane_update_disc_area(plane, state);
@@ -809,7 +838,7 @@ static void atmel_hlcdc_plane_destroy(struct drm_plane *p)
struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
if (plane->base.fb)
- drm_framebuffer_unreference(plane->base.fb);
+ drm_framebuffer_put(plane->base.fb);
drm_plane_cleanup(p);
}
@@ -911,7 +940,7 @@ void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane)
desc->name);
}
-static struct drm_plane_helper_funcs atmel_hlcdc_layer_plane_helper_funcs = {
+static const struct drm_plane_helper_funcs atmel_hlcdc_layer_plane_helper_funcs = {
.atomic_check = atmel_hlcdc_plane_atomic_check,
.atomic_update = atmel_hlcdc_plane_atomic_update,
.atomic_disable = atmel_hlcdc_plane_atomic_disable,
@@ -958,7 +987,7 @@ static void atmel_hlcdc_plane_reset(struct drm_plane *p)
state = drm_plane_state_to_atmel_hlcdc_plane_state(p->state);
if (state->base.fb)
- drm_framebuffer_unreference(state->base.fb);
+ drm_framebuffer_put(state->base.fb);
kfree(state);
p->state = NULL;
@@ -996,7 +1025,7 @@ atmel_hlcdc_plane_atomic_duplicate_state(struct drm_plane *p)
}
if (copy->base.fb)
- drm_framebuffer_reference(copy->base.fb);
+ drm_framebuffer_get(copy->base.fb);
return &copy->base;
}
@@ -1015,15 +1044,14 @@ static void atmel_hlcdc_plane_atomic_destroy_state(struct drm_plane *p,
}
if (s->fb)
- drm_framebuffer_unreference(s->fb);
+ drm_framebuffer_put(s->fb);
kfree(state);
}
-static struct drm_plane_funcs layer_plane_funcs = {
+static const struct drm_plane_funcs layer_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
- .set_property = drm_atomic_helper_plane_set_property,
.destroy = atmel_hlcdc_plane_destroy,
.reset = atmel_hlcdc_plane_reset,
.atomic_duplicate_state = atmel_hlcdc_plane_atomic_duplicate_state,
@@ -1058,7 +1086,8 @@ static int atmel_hlcdc_plane_create(struct drm_device *dev,
ret = drm_universal_plane_init(dev, &plane->base, 0,
&layer_plane_funcs,
desc->formats->formats,
- desc->formats->nformats, type, NULL);
+ desc->formats->nformats,
+ NULL, type, NULL);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c
index aa34251..7b203184 100644
--- a/drivers/gpu/drm/bochs/bochs_drv.c
+++ b/drivers/gpu/drm/bochs/bochs_drv.c
@@ -84,7 +84,6 @@ static struct drm_driver bochs_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET,
.load = bochs_load,
.unload = bochs_unload,
- .set_busid = drm_pci_set_busid,
.fops = &bochs_fops,
.name = "bochs-drm",
.desc = "bochs dispi vga interface (qemu stdvga)",
@@ -94,7 +93,6 @@ static struct drm_driver bochs_driver = {
.gem_free_object_unlocked = bochs_gem_free_object,
.dumb_create = bochs_dumb_create,
.dumb_map_offset = bochs_dumb_mmap_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
};
/* ---------------------------------------------------------------------- */
@@ -224,12 +222,12 @@ static int __init bochs_init(void)
if (bochs_modeset == 0)
return -EINVAL;
- return drm_pci_init(&bochs_driver, &bochs_pci_driver);
+ return pci_register_driver(&bochs_pci_driver);
}
static void __exit bochs_exit(void)
{
- drm_pci_exit(&bochs_driver, &bochs_pci_driver);
+ pci_unregister_driver(&bochs_pci_driver);
}
module_init(bochs_init);
diff --git a/drivers/gpu/drm/bochs/bochs_fbdev.c b/drivers/gpu/drm/bochs/bochs_fbdev.c
index c38deff..14eb8d0 100644
--- a/drivers/gpu/drm/bochs/bochs_fbdev.c
+++ b/drivers/gpu/drm/bochs/bochs_fbdev.c
@@ -23,9 +23,9 @@ static int bochsfb_mmap(struct fb_info *info,
static struct fb_ops bochsfb_ops = {
.owner = THIS_MODULE,
DRM_FB_HELPER_DEFAULT_OPS,
- .fb_fillrect = drm_fb_helper_sys_fillrect,
- .fb_copyarea = drm_fb_helper_sys_copyarea,
- .fb_imageblit = drm_fb_helper_sys_imageblit,
+ .fb_fillrect = drm_fb_helper_cfb_fillrect,
+ .fb_copyarea = drm_fb_helper_cfb_copyarea,
+ .fb_imageblit = drm_fb_helper_cfb_imageblit,
.fb_mmap = bochsfb_mmap,
};
@@ -118,7 +118,6 @@ static int bochsfb_create(struct drm_fb_helper *helper,
strcpy(info->fix.id, "bochsdrmfb");
- info->flags = FBINFO_DEFAULT;
info->fbops = &bochsfb_ops;
drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth);
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index f75ab62..b2431ae 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -785,8 +785,7 @@ adv7511_connector_detect(struct drm_connector *connector, bool force)
return adv7511_detect(adv, connector);
}
-static struct drm_connector_funcs adv7511_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
+static const struct drm_connector_funcs adv7511_connector_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = adv7511_connector_detect,
.destroy = drm_connector_cleanup,
@@ -857,7 +856,7 @@ static int adv7511_bridge_attach(struct drm_bridge *bridge)
return ret;
}
-static struct drm_bridge_funcs adv7511_bridge_funcs = {
+static const struct drm_bridge_funcs adv7511_bridge_funcs = {
.enable = adv7511_bridge_enable,
.disable = adv7511_bridge_disable,
.mode_set = adv7511_bridge_mode_set,
@@ -1126,11 +1125,7 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
adv7511->bridge.funcs = &adv7511_bridge_funcs;
adv7511->bridge.of_node = dev->of_node;
- ret = drm_bridge_add(&adv7511->bridge);
- if (ret) {
- dev_err(dev, "failed to add adv7511 bridge\n");
- goto err_unregister_cec;
- }
+ drm_bridge_add(&adv7511->bridge);
adv7511_audio_init(dev, adv7511);
diff --git a/drivers/gpu/drm/bridge/analogix-anx78xx.c b/drivers/gpu/drm/bridge/analogix-anx78xx.c
index 9006578..9385eb0 100644
--- a/drivers/gpu/drm/bridge/analogix-anx78xx.c
+++ b/drivers/gpu/drm/bridge/analogix-anx78xx.c
@@ -1002,7 +1002,6 @@ static enum drm_connector_status anx78xx_detect(struct drm_connector *connector,
}
static const struct drm_connector_funcs anx78xx_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = anx78xx_detect,
.destroy = drm_connector_cleanup,
@@ -1097,7 +1096,8 @@ static void anx78xx_bridge_mode_set(struct drm_bridge *bridge,
mutex_lock(&anx78xx->lock);
- err = drm_hdmi_avi_infoframe_from_display_mode(&frame, adjusted_mode);
+ err = drm_hdmi_avi_infoframe_from_display_mode(&frame, adjusted_mode,
+ false);
if (err) {
DRM_ERROR("Failed to setup AVI infoframe: %d\n", err);
goto unlock;
@@ -1438,11 +1438,7 @@ static int anx78xx_i2c_probe(struct i2c_client *client,
anx78xx->bridge.funcs = &anx78xx_bridge_funcs;
- err = drm_bridge_add(&anx78xx->bridge);
- if (err < 0) {
- DRM_ERROR("Failed to add drm bridge: %d\n", err);
- goto err_poweroff;
- }
+ drm_bridge_add(&anx78xx->bridge);
/* If cable is pulled out, just poweroff and wait for HPD event */
if (!gpiod_get_value(anx78xx->pdata.gpiod_hpd))
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 4c758ed..5dd3f1c 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1005,7 +1005,6 @@ analogix_dp_detect(struct drm_connector *connector, bool force)
}
static const struct drm_connector_funcs analogix_dp_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = analogix_dp_detect,
.destroy = drm_connector_cleanup,
diff --git a/drivers/gpu/drm/bridge/dumb-vga-dac.c b/drivers/gpu/drm/bridge/dumb-vga-dac.c
index 831a606..de5e7de 100644
--- a/drivers/gpu/drm/bridge/dumb-vga-dac.c
+++ b/drivers/gpu/drm/bridge/dumb-vga-dac.c
@@ -92,7 +92,6 @@ dumb_vga_connector_detect(struct drm_connector *connector, bool force)
}
static const struct drm_connector_funcs dumb_vga_con_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = dumb_vga_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
@@ -177,7 +176,6 @@ static struct i2c_adapter *dumb_vga_retrieve_ddc(struct device *dev)
static int dumb_vga_probe(struct platform_device *pdev)
{
struct dumb_vga *vga;
- int ret;
vga = devm_kzalloc(&pdev->dev, sizeof(*vga), GFP_KERNEL);
if (!vga)
@@ -186,7 +184,7 @@ static int dumb_vga_probe(struct platform_device *pdev)
vga->vdd = devm_regulator_get_optional(&pdev->dev, "vdd");
if (IS_ERR(vga->vdd)) {
- ret = PTR_ERR(vga->vdd);
+ int ret = PTR_ERR(vga->vdd);
if (ret == -EPROBE_DEFER)
return -EPROBE_DEFER;
vga->vdd = NULL;
@@ -207,11 +205,9 @@ static int dumb_vga_probe(struct platform_device *pdev)
vga->bridge.funcs = &dumb_vga_bridge_funcs;
vga->bridge.of_node = pdev->dev.of_node;
- ret = drm_bridge_add(&vga->bridge);
- if (ret && !IS_ERR(vga->ddc))
- i2c_put_adapter(vga->ddc);
+ drm_bridge_add(&vga->bridge);
- return ret;
+ return 0;
}
static int dumb_vga_remove(struct platform_device *pdev)
diff --git a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
index 11f1108..7ccadba 100644
--- a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
+++ b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
@@ -193,7 +193,6 @@ static enum drm_connector_status ge_b850v3_lvds_detect(
}
static const struct drm_connector_funcs ge_b850v3_lvds_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = ge_b850v3_lvds_detect,
.destroy = drm_connector_cleanup,
diff --git a/drivers/gpu/drm/bridge/nxp-ptn3460.c b/drivers/gpu/drm/bridge/nxp-ptn3460.c
index 4f64e71..d64a328 100644
--- a/drivers/gpu/drm/bridge/nxp-ptn3460.c
+++ b/drivers/gpu/drm/bridge/nxp-ptn3460.c
@@ -238,7 +238,6 @@ static const struct drm_connector_helper_funcs ptn3460_connector_helper_funcs =
};
static const struct drm_connector_funcs ptn3460_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
.reset = drm_atomic_helper_connector_reset,
@@ -332,11 +331,7 @@ static int ptn3460_probe(struct i2c_client *client,
ptn_bridge->bridge.funcs = &ptn3460_bridge_funcs;
ptn_bridge->bridge.of_node = dev->of_node;
- ret = drm_bridge_add(&ptn_bridge->bridge);
- if (ret) {
- DRM_ERROR("Failed to add bridge\n");
- return ret;
- }
+ drm_bridge_add(&ptn_bridge->bridge);
i2c_set_clientdata(client, ptn_bridge);
diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c
index 67fe19e..e0cca19 100644
--- a/drivers/gpu/drm/bridge/panel.c
+++ b/drivers/gpu/drm/bridge/panel.c
@@ -50,7 +50,6 @@ panel_bridge_connector_helper_funcs = {
};
static const struct drm_connector_funcs panel_bridge_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.reset = drm_atomic_helper_connector_reset,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
@@ -158,7 +157,6 @@ struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel,
u32 connector_type)
{
struct panel_bridge *panel_bridge;
- int ret;
if (!panel)
return ERR_PTR(-EINVAL);
@@ -176,9 +174,7 @@ struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel,
panel_bridge->bridge.of_node = panel->dev->of_node;
#endif
- ret = drm_bridge_add(&panel_bridge->bridge);
- if (ret)
- return ERR_PTR(ret);
+ drm_bridge_add(&panel_bridge->bridge);
return &panel_bridge->bridge;
}
@@ -198,3 +194,33 @@ void drm_panel_bridge_remove(struct drm_bridge *bridge)
devm_kfree(panel_bridge->panel->dev, bridge);
}
EXPORT_SYMBOL(drm_panel_bridge_remove);
+
+static void devm_drm_panel_bridge_release(struct device *dev, void *res)
+{
+ struct drm_bridge **bridge = res;
+
+ drm_panel_bridge_remove(*bridge);
+}
+
+struct drm_bridge *devm_drm_panel_bridge_add(struct device *dev,
+ struct drm_panel *panel,
+ u32 connector_type)
+{
+ struct drm_bridge **ptr, *bridge;
+
+ ptr = devres_alloc(devm_drm_panel_bridge_release, sizeof(*ptr),
+ GFP_KERNEL);
+ if (!ptr)
+ return ERR_PTR(-ENOMEM);
+
+ bridge = drm_panel_bridge_add(panel, connector_type);
+ if (!IS_ERR(bridge)) {
+ *ptr = bridge;
+ devres_add(dev, ptr);
+ } else {
+ devres_free(ptr);
+ }
+
+ return bridge;
+}
+EXPORT_SYMBOL(devm_drm_panel_bridge_add);
diff --git a/drivers/gpu/drm/bridge/parade-ps8622.c b/drivers/gpu/drm/bridge/parade-ps8622.c
index 6f22f9f..81198f5 100644
--- a/drivers/gpu/drm/bridge/parade-ps8622.c
+++ b/drivers/gpu/drm/bridge/parade-ps8622.c
@@ -476,7 +476,6 @@ static const struct drm_connector_helper_funcs ps8622_connector_helper_funcs = {
};
static const struct drm_connector_funcs ps8622_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
.reset = drm_atomic_helper_connector_reset,
@@ -598,11 +597,7 @@ static int ps8622_probe(struct i2c_client *client,
ps8622->bridge.funcs = &ps8622_bridge_funcs;
ps8622->bridge.of_node = dev->of_node;
- ret = drm_bridge_add(&ps8622->bridge);
- if (ret) {
- DRM_ERROR("Failed to add bridge\n");
- return ret;
- }
+ drm_bridge_add(&ps8622->bridge);
i2c_set_clientdata(client, ps8622);
diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c
index 9b87067..b1ab4ab 100644
--- a/drivers/gpu/drm/bridge/sii902x.c
+++ b/drivers/gpu/drm/bridge/sii902x.c
@@ -124,7 +124,6 @@ sii902x_connector_detect(struct drm_connector *connector, bool force)
}
static const struct drm_connector_funcs sii902x_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = sii902x_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
@@ -269,7 +268,7 @@ static void sii902x_bridge_mode_set(struct drm_bridge *bridge,
if (ret)
return;
- ret = drm_hdmi_avi_infoframe_from_display_mode(&frame, adj);
+ ret = drm_hdmi_avi_infoframe_from_display_mode(&frame, adj, false);
if (ret < 0) {
DRM_ERROR("couldn't fill AVI infoframe\n");
return;
@@ -418,11 +417,7 @@ static int sii902x_probe(struct i2c_client *client,
sii902x->bridge.funcs = &sii902x_bridge_funcs;
sii902x->bridge.of_node = dev->of_node;
- ret = drm_bridge_add(&sii902x->bridge);
- if (ret) {
- dev_err(dev, "Failed to add drm_bridge\n");
- return ret;
- }
+ drm_bridge_add(&sii902x->bridge);
i2c_set_clientdata(client, sii902x);
diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index 2d51a22..5131bfb 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -597,9 +597,9 @@ static void sii8620_mt_read_devcap(struct sii8620 *ctx, bool xdevcap)
static void sii8620_mt_read_devcap_reg_recv(struct sii8620 *ctx,
struct sii8620_mt_msg *msg)
{
- u8 reg = msg->reg[0] & 0x7f;
+ u8 reg = msg->reg[1] & 0x7f;
- if (msg->reg[0] & 0x80)
+ if (msg->reg[1] & 0x80)
ctx->xdevcap[reg] = msg->ret;
else
ctx->devcap[reg] = msg->ret;
diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig
index 53e78d0..3cc53b4 100644
--- a/drivers/gpu/drm/bridge/synopsys/Kconfig
+++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
@@ -2,6 +2,7 @@ config DRM_DW_HDMI
tristate
select DRM_KMS_HELPER
select REGMAP_MMIO
+ select CEC_CORE if CEC_NOTIFIER
config DRM_DW_HDMI_AHB_AUDIO
tristate "Synopsys Designware AHB Audio interface"
@@ -22,3 +23,18 @@ config DRM_DW_HDMI_I2S_AUDIO
help
Support the I2S Audio interface which is part of the Synopsys
Designware HDMI block.
+
+config DRM_DW_HDMI_CEC
+ tristate "Synopsis Designware CEC interface"
+ depends on DRM_DW_HDMI
+ select CEC_CORE
+ select CEC_NOTIFIER
+ help
+ Support the CE interface which is part of the Synopsys
+ Designware HDMI block.
+
+config DRM_DW_MIPI_DSI
+ tristate
+ select DRM_KMS_HELPER
+ select DRM_MIPI_DSI
+ select DRM_PANEL_BRIDGE
diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile b/drivers/gpu/drm/bridge/synopsys/Makefile
index 17aa7a6..5dad97d 100644
--- a/drivers/gpu/drm/bridge/synopsys/Makefile
+++ b/drivers/gpu/drm/bridge/synopsys/Makefile
@@ -3,3 +3,6 @@
obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
+obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
+
+obj-$(CONFIG_DRM_DW_MIPI_DSI) += dw-mipi-dsi.o
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
index 8f2d137..cf3f0ca 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
@@ -517,7 +517,7 @@ static snd_pcm_uframes_t dw_hdmi_pointer(struct snd_pcm_substream *substream)
return bytes_to_frames(runtime, dw->buf_offset);
}
-static struct snd_pcm_ops snd_dw_hdmi_ops = {
+static const struct snd_pcm_ops snd_dw_hdmi_ops = {
.open = dw_hdmi_open,
.close = dw_hdmi_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
new file mode 100644
index 0000000..6c32351
--- /dev/null
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
@@ -0,0 +1,327 @@
+/*
+ * Designware HDMI CEC driver
+ *
+ * Copyright (C) 2015-2017 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+#include <drm/drm_edid.h>
+
+#include <media/cec.h>
+#include <media/cec-notifier.h>
+
+#include "dw-hdmi-cec.h"
+
+enum {
+ HDMI_IH_CEC_STAT0 = 0x0106,
+ HDMI_IH_MUTE_CEC_STAT0 = 0x0186,
+
+ HDMI_CEC_CTRL = 0x7d00,
+ CEC_CTRL_START = BIT(0),
+ CEC_CTRL_FRAME_TYP = 3 << 1,
+ CEC_CTRL_RETRY = 0 << 1,
+ CEC_CTRL_NORMAL = 1 << 1,
+ CEC_CTRL_IMMED = 2 << 1,
+
+ HDMI_CEC_STAT = 0x7d01,
+ CEC_STAT_DONE = BIT(0),
+ CEC_STAT_EOM = BIT(1),
+ CEC_STAT_NACK = BIT(2),
+ CEC_STAT_ARBLOST = BIT(3),
+ CEC_STAT_ERROR_INIT = BIT(4),
+ CEC_STAT_ERROR_FOLL = BIT(5),
+ CEC_STAT_WAKEUP = BIT(6),
+
+ HDMI_CEC_MASK = 0x7d02,
+ HDMI_CEC_POLARITY = 0x7d03,
+ HDMI_CEC_INT = 0x7d04,
+ HDMI_CEC_ADDR_L = 0x7d05,
+ HDMI_CEC_ADDR_H = 0x7d06,
+ HDMI_CEC_TX_CNT = 0x7d07,
+ HDMI_CEC_RX_CNT = 0x7d08,
+ HDMI_CEC_TX_DATA0 = 0x7d10,
+ HDMI_CEC_RX_DATA0 = 0x7d20,
+ HDMI_CEC_LOCK = 0x7d30,
+ HDMI_CEC_WKUPCTRL = 0x7d31,
+};
+
+struct dw_hdmi_cec {
+ struct dw_hdmi *hdmi;
+ const struct dw_hdmi_cec_ops *ops;
+ u32 addresses;
+ struct cec_adapter *adap;
+ struct cec_msg rx_msg;
+ unsigned int tx_status;
+ bool tx_done;
+ bool rx_done;
+ struct cec_notifier *notify;
+ int irq;
+};
+
+static void dw_hdmi_write(struct dw_hdmi_cec *cec, u8 val, int offset)
+{
+ cec->ops->write(cec->hdmi, val, offset);
+}
+
+static u8 dw_hdmi_read(struct dw_hdmi_cec *cec, int offset)
+{
+ return cec->ops->read(cec->hdmi, offset);
+}
+
+static int dw_hdmi_cec_log_addr(struct cec_adapter *adap, u8 logical_addr)
+{
+ struct dw_hdmi_cec *cec = cec_get_drvdata(adap);
+
+ if (logical_addr == CEC_LOG_ADDR_INVALID)
+ cec->addresses = 0;
+ else
+ cec->addresses |= BIT(logical_addr) | BIT(15);
+
+ dw_hdmi_write(cec, cec->addresses & 255, HDMI_CEC_ADDR_L);
+ dw_hdmi_write(cec, cec->addresses >> 8, HDMI_CEC_ADDR_H);
+
+ return 0;
+}
+
+static int dw_hdmi_cec_transmit(struct cec_adapter *adap, u8 attempts,
+ u32 signal_free_time, struct cec_msg *msg)
+{
+ struct dw_hdmi_cec *cec = cec_get_drvdata(adap);
+ unsigned int i, ctrl;
+
+ switch (signal_free_time) {
+ case CEC_SIGNAL_FREE_TIME_RETRY:
+ ctrl = CEC_CTRL_RETRY;
+ break;
+ case CEC_SIGNAL_FREE_TIME_NEW_INITIATOR:
+ default:
+ ctrl = CEC_CTRL_NORMAL;
+ break;
+ case CEC_SIGNAL_FREE_TIME_NEXT_XFER:
+ ctrl = CEC_CTRL_IMMED;
+ break;
+ }
+
+ for (i = 0; i < msg->len; i++)
+ dw_hdmi_write(cec, msg->msg[i], HDMI_CEC_TX_DATA0 + i);
+
+ dw_hdmi_write(cec, msg->len, HDMI_CEC_TX_CNT);
+ dw_hdmi_write(cec, ctrl | CEC_CTRL_START, HDMI_CEC_CTRL);
+
+ return 0;
+}
+
+static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data)
+{
+ struct cec_adapter *adap = data;
+ struct dw_hdmi_cec *cec = cec_get_drvdata(adap);
+ unsigned int stat = dw_hdmi_read(cec, HDMI_IH_CEC_STAT0);
+ irqreturn_t ret = IRQ_HANDLED;
+
+ if (stat == 0)
+ return IRQ_NONE;
+
+ dw_hdmi_write(cec, stat, HDMI_IH_CEC_STAT0);
+
+ if (stat & CEC_STAT_ERROR_INIT) {
+ cec->tx_status = CEC_TX_STATUS_ERROR;
+ cec->tx_done = true;
+ ret = IRQ_WAKE_THREAD;
+ } else if (stat & CEC_STAT_DONE) {
+ cec->tx_status = CEC_TX_STATUS_OK;
+ cec->tx_done = true;
+ ret = IRQ_WAKE_THREAD;
+ } else if (stat & CEC_STAT_NACK) {
+ cec->tx_status = CEC_TX_STATUS_NACK;
+ cec->tx_done = true;
+ ret = IRQ_WAKE_THREAD;
+ }
+
+ if (stat & CEC_STAT_EOM) {
+ unsigned int len, i;
+
+ len = dw_hdmi_read(cec, HDMI_CEC_RX_CNT);
+ if (len > sizeof(cec->rx_msg.msg))
+ len = sizeof(cec->rx_msg.msg);
+
+ for (i = 0; i < len; i++)
+ cec->rx_msg.msg[i] =
+ dw_hdmi_read(cec, HDMI_CEC_RX_DATA0 + i);
+
+ dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
+
+ cec->rx_msg.len = len;
+ smp_wmb();
+ cec->rx_done = true;
+
+ ret = IRQ_WAKE_THREAD;
+ }
+
+ return ret;
+}
+
+static irqreturn_t dw_hdmi_cec_thread(int irq, void *data)
+{
+ struct cec_adapter *adap = data;
+ struct dw_hdmi_cec *cec = cec_get_drvdata(adap);
+
+ if (cec->tx_done) {
+ cec->tx_done = false;
+ cec_transmit_attempt_done(adap, cec->tx_status);
+ }
+ if (cec->rx_done) {
+ cec->rx_done = false;
+ smp_rmb();
+ cec_received_msg(adap, &cec->rx_msg);
+ }
+ return IRQ_HANDLED;
+}
+
+static int dw_hdmi_cec_enable(struct cec_adapter *adap, bool enable)
+{
+ struct dw_hdmi_cec *cec = cec_get_drvdata(adap);
+
+ if (!enable) {
+ dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
+ dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
+ dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
+
+ cec->ops->disable(cec->hdmi);
+ } else {
+ unsigned int irqs;
+
+ dw_hdmi_write(cec, 0, HDMI_CEC_CTRL);
+ dw_hdmi_write(cec, ~0, HDMI_IH_CEC_STAT0);
+ dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
+
+ dw_hdmi_cec_log_addr(cec->adap, CEC_LOG_ADDR_INVALID);
+
+ cec->ops->enable(cec->hdmi);
+
+ irqs = CEC_STAT_ERROR_INIT | CEC_STAT_NACK | CEC_STAT_EOM |
+ CEC_STAT_DONE;
+ dw_hdmi_write(cec, irqs, HDMI_CEC_POLARITY);
+ dw_hdmi_write(cec, ~irqs, HDMI_CEC_MASK);
+ dw_hdmi_write(cec, ~irqs, HDMI_IH_MUTE_CEC_STAT0);
+ }
+ return 0;
+}
+
+static const struct cec_adap_ops dw_hdmi_cec_ops = {
+ .adap_enable = dw_hdmi_cec_enable,
+ .adap_log_addr = dw_hdmi_cec_log_addr,
+ .adap_transmit = dw_hdmi_cec_transmit,
+};
+
+static void dw_hdmi_cec_del(void *data)
+{
+ struct dw_hdmi_cec *cec = data;
+
+ cec_delete_adapter(cec->adap);
+}
+
+static int dw_hdmi_cec_probe(struct platform_device *pdev)
+{
+ struct dw_hdmi_cec_data *data = dev_get_platdata(&pdev->dev);
+ struct dw_hdmi_cec *cec;
+ int ret;
+
+ if (!data)
+ return -ENXIO;
+
+ /*
+ * Our device is just a convenience - we want to link to the real
+ * hardware device here, so that userspace can see the association
+ * between the HDMI hardware and its associated CEC chardev.
+ */
+ cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL);
+ if (!cec)
+ return -ENOMEM;
+
+ cec->irq = data->irq;
+ cec->ops = data->ops;
+ cec->hdmi = data->hdmi;
+
+ platform_set_drvdata(pdev, cec);
+
+ dw_hdmi_write(cec, 0, HDMI_CEC_TX_CNT);
+ dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
+ dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
+ dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
+
+ cec->adap = cec_allocate_adapter(&dw_hdmi_cec_ops, cec, "dw_hdmi",
+ CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT |
+ CEC_CAP_RC | CEC_CAP_PASSTHROUGH,
+ CEC_MAX_LOG_ADDRS);
+ if (IS_ERR(cec->adap))
+ return PTR_ERR(cec->adap);
+
+ /* override the module pointer */
+ cec->adap->owner = THIS_MODULE;
+
+ ret = devm_add_action(&pdev->dev, dw_hdmi_cec_del, cec);
+ if (ret) {
+ cec_delete_adapter(cec->adap);
+ return ret;
+ }
+
+ ret = devm_request_threaded_irq(&pdev->dev, cec->irq,
+ dw_hdmi_cec_hardirq,
+ dw_hdmi_cec_thread, IRQF_SHARED,
+ "dw-hdmi-cec", cec->adap);
+ if (ret < 0)
+ return ret;
+
+ cec->notify = cec_notifier_get(pdev->dev.parent);
+ if (!cec->notify)
+ return -ENOMEM;
+
+ ret = cec_register_adapter(cec->adap, pdev->dev.parent);
+ if (ret < 0) {
+ cec_notifier_put(cec->notify);
+ return ret;
+ }
+
+ /*
+ * CEC documentation says we must not call cec_delete_adapter
+ * after a successful call to cec_register_adapter().
+ */
+ devm_remove_action(&pdev->dev, dw_hdmi_cec_del, cec);
+
+ cec_register_cec_notifier(cec->adap, cec->notify);
+
+ return 0;
+}
+
+static int dw_hdmi_cec_remove(struct platform_device *pdev)
+{
+ struct dw_hdmi_cec *cec = platform_get_drvdata(pdev);
+
+ cec_unregister_adapter(cec->adap);
+ cec_notifier_put(cec->notify);
+
+ return 0;
+}
+
+static struct platform_driver dw_hdmi_cec_driver = {
+ .probe = dw_hdmi_cec_probe,
+ .remove = dw_hdmi_cec_remove,
+ .driver = {
+ .name = "dw-hdmi-cec",
+ },
+};
+module_platform_driver(dw_hdmi_cec_driver);
+
+MODULE_AUTHOR("Russell King <rmk+kernel@armlinux.org.uk>");
+MODULE_DESCRIPTION("Synopsys Designware HDMI CEC driver for i.MX");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS(PLATFORM_MODULE_PREFIX "dw-hdmi-cec");
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
new file mode 100644
index 0000000..cf4dc12
--- /dev/null
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
@@ -0,0 +1,19 @@
+#ifndef DW_HDMI_CEC_H
+#define DW_HDMI_CEC_H
+
+struct dw_hdmi;
+
+struct dw_hdmi_cec_ops {
+ void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
+ u8 (*read)(struct dw_hdmi *hdmi, int offset);
+ void (*enable)(struct dw_hdmi *hdmi);
+ void (*disable)(struct dw_hdmi *hdmi);
+};
+
+struct dw_hdmi_cec_data {
+ struct dw_hdmi *hdmi;
+ const struct dw_hdmi_cec_ops *ops;
+ int irq;
+};
+
+#endif
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
index b2cf59f..3b7e5c5 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
@@ -1,7 +1,8 @@
/*
* dw-hdmi-i2s-audio.c
*
- * Copyright (c) 2016 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ * Copyright (c) 2017 Renesas Solutions Corp.
+ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index ead1124..bf14214 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -35,8 +35,12 @@
#include "dw-hdmi.h"
#include "dw-hdmi-audio.h"
+#include "dw-hdmi-cec.h"
+
+#include <media/cec-notifier.h>
#define DDC_SEGMENT_ADDR 0x30
+
#define HDMI_EDID_LEN 512
enum hdmi_datamap {
@@ -130,6 +134,7 @@ struct dw_hdmi {
unsigned int version;
struct platform_device *audio;
+ struct platform_device *cec;
struct device *dev;
struct clk *isfr_clk;
struct clk *iahb_clk;
@@ -163,6 +168,7 @@ struct dw_hdmi {
bool bridge_is_on; /* indicates the bridge is on */
bool rxsense; /* rxsense state */
u8 phy_mask; /* desired phy int mask settings */
+ u8 mc_clkdis; /* clock disable register */
spinlock_t audio_lock;
struct mutex audio_mutex;
@@ -175,6 +181,8 @@ struct dw_hdmi {
struct regmap *regm;
void (*enable_audio)(struct dw_hdmi *hdmi);
void (*disable_audio)(struct dw_hdmi *hdmi);
+
+ struct cec_notifier *cec_notifier;
};
#define HDMI_IH_PHY_STAT0_RX_SENSE \
@@ -546,8 +554,11 @@ EXPORT_SYMBOL_GPL(dw_hdmi_set_sample_rate);
static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi, bool enable)
{
- hdmi_modb(hdmi, enable ? 0 : HDMI_MC_CLKDIS_AUDCLK_DISABLE,
- HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS);
+ if (enable)
+ hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE;
+ else
+ hdmi->mc_clkdis |= HDMI_MC_CLKDIS_AUDCLK_DISABLE;
+ hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
}
static void dw_hdmi_ahb_audio_enable(struct dw_hdmi *hdmi)
@@ -1317,7 +1328,7 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
u8 val;
/* Initialise info frame from DRM mode */
- drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+ drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
if (hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format))
frame.colorspace = HDMI_COLORSPACE_YUV444;
@@ -1569,8 +1580,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
/* HDMI Initialization Step B.4 */
static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
{
- u8 clkdis;
-
/* control period minimum duration */
hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR);
hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR);
@@ -1582,17 +1591,21 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM);
/* Enable pixel clock and tmds data path */
- clkdis = 0x7F;
- clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
- hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
+ hdmi->mc_clkdis |= HDMI_MC_CLKDIS_HDCPCLK_DISABLE |
+ HDMI_MC_CLKDIS_CSCCLK_DISABLE |
+ HDMI_MC_CLKDIS_AUDCLK_DISABLE |
+ HDMI_MC_CLKDIS_PREPCLK_DISABLE |
+ HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
+ hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
+ hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
- clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
- hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
+ hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
+ hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
/* Enable csc path */
if (is_color_space_conversion(hdmi)) {
- clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
- hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
+ hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
+ hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
}
/* Enable color space conversion if needed */
@@ -1783,7 +1796,6 @@ static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK);
hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK);
hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK);
- hdmi_writeb(hdmi, 0xff, HDMI_CEC_MASK);
hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT);
hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT);
@@ -1896,6 +1908,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
drm_mode_connector_update_edid_property(connector, edid);
+ cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
ret = drm_add_edid_modes(connector, edid);
/* Store the ELD */
drm_edid_to_eld(connector, edid);
@@ -1920,7 +1933,6 @@ static void dw_hdmi_connector_force(struct drm_connector *connector)
}
static const struct drm_connector_funcs dw_hdmi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = dw_hdmi_connector_detect,
.destroy = drm_connector_cleanup,
@@ -2119,11 +2131,16 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
* ask the source to re-read the EDID.
*/
if (intr_stat &
- (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD))
+ (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
__dw_hdmi_setup_rx_sense(hdmi,
phy_stat & HDMI_PHY_HPD,
phy_stat & HDMI_PHY_RX_SENSE);
+ if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
+ cec_notifier_set_phys_addr(hdmi->cec_notifier,
+ CEC_PHYS_ADDR_INVALID);
+ }
+
if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
dev_dbg(hdmi->dev, "EVENT=%s\n",
phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
@@ -2170,6 +2187,7 @@ static const struct dw_hdmi_phy_data dw_hdmi_phys[] = {
.name = "DWC HDMI 2.0 TX PHY",
.gen = 2,
.has_svsret = true,
+ .configure = hdmi_phy_configure_dwc_hdmi_3d_tx,
}, {
.type = DW_HDMI_PHY_VENDOR_PHY,
.name = "Vendor PHY",
@@ -2219,6 +2237,29 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
return -ENODEV;
}
+static void dw_hdmi_cec_enable(struct dw_hdmi *hdmi)
+{
+ mutex_lock(&hdmi->mutex);
+ hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
+ hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
+ mutex_unlock(&hdmi->mutex);
+}
+
+static void dw_hdmi_cec_disable(struct dw_hdmi *hdmi)
+{
+ mutex_lock(&hdmi->mutex);
+ hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
+ hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
+ mutex_unlock(&hdmi->mutex);
+}
+
+static const struct dw_hdmi_cec_ops dw_hdmi_cec_ops = {
+ .write = hdmi_writeb,
+ .read = hdmi_readb,
+ .enable = dw_hdmi_cec_enable,
+ .disable = dw_hdmi_cec_disable,
+};
+
static const struct regmap_config hdmi_regmap_8bit_config = {
.reg_bits = 32,
.val_bits = 8,
@@ -2241,6 +2282,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
struct device_node *np = dev->of_node;
struct platform_device_info pdevinfo;
struct device_node *ddc_node;
+ struct dw_hdmi_cec_data cec;
struct dw_hdmi *hdmi;
struct resource *iores = NULL;
int irq;
@@ -2261,6 +2303,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
hdmi->disabled = true;
hdmi->rxsense = true;
hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE);
+ hdmi->mc_clkdis = 0x7f;
mutex_init(&hdmi->mutex);
mutex_init(&hdmi->audio_mutex);
@@ -2376,6 +2419,12 @@ __dw_hdmi_probe(struct platform_device *pdev,
if (ret)
goto err_iahb;
+ hdmi->cec_notifier = cec_notifier_get(dev);
+ if (!hdmi->cec_notifier) {
+ ret = -ENOMEM;
+ goto err_iahb;
+ }
+
/*
* To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
* N and cts values before enabling phy
@@ -2438,6 +2487,19 @@ __dw_hdmi_probe(struct platform_device *pdev,
hdmi->audio = platform_device_register_full(&pdevinfo);
}
+ if (config0 & HDMI_CONFIG0_CEC) {
+ cec.hdmi = hdmi;
+ cec.ops = &dw_hdmi_cec_ops;
+ cec.irq = irq;
+
+ pdevinfo.name = "dw-hdmi-cec";
+ pdevinfo.data = &cec;
+ pdevinfo.size_data = sizeof(cec);
+ pdevinfo.dma_mask = 0;
+
+ hdmi->cec = platform_device_register_full(&pdevinfo);
+ }
+
/* Reset HDMI DDC I2C master controller and mute I2CM interrupts */
if (hdmi->i2c)
dw_hdmi_i2c_init(hdmi);
@@ -2452,6 +2514,9 @@ err_iahb:
hdmi->ddc = NULL;
}
+ if (hdmi->cec_notifier)
+ cec_notifier_put(hdmi->cec_notifier);
+
clk_disable_unprepare(hdmi->iahb_clk);
err_isfr:
clk_disable_unprepare(hdmi->isfr_clk);
@@ -2465,10 +2530,15 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
{
if (hdmi->audio && !IS_ERR(hdmi->audio))
platform_device_unregister(hdmi->audio);
+ if (!IS_ERR(hdmi->cec))
+ platform_device_unregister(hdmi->cec);
/* Disable all interrupts */
hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
+ if (hdmi->cec_notifier)
+ cec_notifier_put(hdmi->cec_notifier);
+
clk_disable_unprepare(hdmi->iahb_clk);
clk_disable_unprepare(hdmi->isfr_clk);
@@ -2485,17 +2555,12 @@ int dw_hdmi_probe(struct platform_device *pdev,
const struct dw_hdmi_plat_data *plat_data)
{
struct dw_hdmi *hdmi;
- int ret;
hdmi = __dw_hdmi_probe(pdev, plat_data);
if (IS_ERR(hdmi))
return PTR_ERR(hdmi);
- ret = drm_bridge_add(&hdmi->bridge);
- if (ret < 0) {
- __dw_hdmi_remove(hdmi);
- return ret;
- }
+ drm_bridge_add(&hdmi->bridge);
return 0;
}
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
index c59f87e..9d90eb9 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
@@ -478,51 +478,6 @@
#define HDMI_A_PRESETUP 0x501A
#define HDMI_A_SRM_BASE 0x5020
-/* CEC Engine Registers */
-#define HDMI_CEC_CTRL 0x7D00
-#define HDMI_CEC_STAT 0x7D01
-#define HDMI_CEC_MASK 0x7D02
-#define HDMI_CEC_POLARITY 0x7D03
-#define HDMI_CEC_INT 0x7D04
-#define HDMI_CEC_ADDR_L 0x7D05
-#define HDMI_CEC_ADDR_H 0x7D06
-#define HDMI_CEC_TX_CNT 0x7D07
-#define HDMI_CEC_RX_CNT 0x7D08
-#define HDMI_CEC_TX_DATA0 0x7D10
-#define HDMI_CEC_TX_DATA1 0x7D11
-#define HDMI_CEC_TX_DATA2 0x7D12
-#define HDMI_CEC_TX_DATA3 0x7D13
-#define HDMI_CEC_TX_DATA4 0x7D14
-#define HDMI_CEC_TX_DATA5 0x7D15
-#define HDMI_CEC_TX_DATA6 0x7D16
-#define HDMI_CEC_TX_DATA7 0x7D17
-#define HDMI_CEC_TX_DATA8 0x7D18
-#define HDMI_CEC_TX_DATA9 0x7D19
-#define HDMI_CEC_TX_DATA10 0x7D1a
-#define HDMI_CEC_TX_DATA11 0x7D1b
-#define HDMI_CEC_TX_DATA12 0x7D1c
-#define HDMI_CEC_TX_DATA13 0x7D1d
-#define HDMI_CEC_TX_DATA14 0x7D1e
-#define HDMI_CEC_TX_DATA15 0x7D1f
-#define HDMI_CEC_RX_DATA0 0x7D20
-#define HDMI_CEC_RX_DATA1 0x7D21
-#define HDMI_CEC_RX_DATA2 0x7D22
-#define HDMI_CEC_RX_DATA3 0x7D23
-#define HDMI_CEC_RX_DATA4 0x7D24
-#define HDMI_CEC_RX_DATA5 0x7D25
-#define HDMI_CEC_RX_DATA6 0x7D26
-#define HDMI_CEC_RX_DATA7 0x7D27
-#define HDMI_CEC_RX_DATA8 0x7D28
-#define HDMI_CEC_RX_DATA9 0x7D29
-#define HDMI_CEC_RX_DATA10 0x7D2a
-#define HDMI_CEC_RX_DATA11 0x7D2b
-#define HDMI_CEC_RX_DATA12 0x7D2c
-#define HDMI_CEC_RX_DATA13 0x7D2d
-#define HDMI_CEC_RX_DATA14 0x7D2e
-#define HDMI_CEC_RX_DATA15 0x7D2f
-#define HDMI_CEC_LOCK 0x7D30
-#define HDMI_CEC_WKUPCTRL 0x7D31
-
/* I2C Master Registers (E-DDC) */
#define HDMI_I2CM_SLAVE 0x7E00
#define HDMI_I2CM_ADDRESS 0x7E01
@@ -555,6 +510,7 @@ enum {
/* CONFIG0_ID field values */
HDMI_CONFIG0_I2S = 0x10,
+ HDMI_CONFIG0_CEC = 0x02,
/* CONFIG1_ID field values */
HDMI_CONFIG1_AHB = 0x01,
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
new file mode 100644
index 0000000..63c7a01
--- /dev/null
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -0,0 +1,981 @@
+/*
+ * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
+ * Copyright (C) STMicroelectronics SA 2017
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Modified by Philippe Cornu <philippe.cornu@st.com>
+ * This generic Synopsys DesignWare MIPI DSI host driver is based on the
+ * Rockchip version from rockchip/dw-mipi-dsi.c with phy & bridge APIs.
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_of.h>
+#include <drm/bridge/dw_mipi_dsi.h>
+#include <video/mipi_display.h>
+
+#define DSI_VERSION 0x00
+#define DSI_PWR_UP 0x04
+#define RESET 0
+#define POWERUP BIT(0)
+
+#define DSI_CLKMGR_CFG 0x08
+#define TO_CLK_DIVIDSION(div) (((div) & 0xff) << 8)
+#define TX_ESC_CLK_DIVIDSION(div) (((div) & 0xff) << 0)
+
+#define DSI_DPI_VCID 0x0c
+#define DPI_VID(vid) (((vid) & 0x3) << 0)
+
+#define DSI_DPI_COLOR_CODING 0x10
+#define EN18_LOOSELY BIT(8)
+#define DPI_COLOR_CODING_16BIT_1 0x0
+#define DPI_COLOR_CODING_16BIT_2 0x1
+#define DPI_COLOR_CODING_16BIT_3 0x2
+#define DPI_COLOR_CODING_18BIT_1 0x3
+#define DPI_COLOR_CODING_18BIT_2 0x4
+#define DPI_COLOR_CODING_24BIT 0x5
+
+#define DSI_DPI_CFG_POL 0x14
+#define COLORM_ACTIVE_LOW BIT(4)
+#define SHUTD_ACTIVE_LOW BIT(3)
+#define HSYNC_ACTIVE_LOW BIT(2)
+#define VSYNC_ACTIVE_LOW BIT(1)
+#define DATAEN_ACTIVE_LOW BIT(0)
+
+#define DSI_DPI_LP_CMD_TIM 0x18
+#define OUTVACT_LPCMD_TIME(p) (((p) & 0xff) << 16)
+#define INVACT_LPCMD_TIME(p) ((p) & 0xff)
+
+#define DSI_DBI_CFG 0x20
+#define DSI_DBI_CMDSIZE 0x28
+
+#define DSI_PCKHDL_CFG 0x2c
+#define EN_CRC_RX BIT(4)
+#define EN_ECC_RX BIT(3)
+#define EN_BTA BIT(2)
+#define EN_EOTP_RX BIT(1)
+#define EN_EOTP_TX BIT(0)
+
+#define DSI_MODE_CFG 0x34
+#define ENABLE_VIDEO_MODE 0
+#define ENABLE_CMD_MODE BIT(0)
+
+#define DSI_VID_MODE_CFG 0x38
+#define FRAME_BTA_ACK BIT(14)
+#define ENABLE_LOW_POWER (0x3f << 8)
+#define ENABLE_LOW_POWER_MASK (0x3f << 8)
+#define VID_MODE_TYPE_NON_BURST_SYNC_PULSES 0x0
+#define VID_MODE_TYPE_NON_BURST_SYNC_EVENTS 0x1
+#define VID_MODE_TYPE_BURST 0x2
+#define VID_MODE_TYPE_MASK 0x3
+
+#define DSI_VID_PKT_SIZE 0x3c
+#define VID_PKT_SIZE(p) (((p) & 0x3fff) << 0)
+#define VID_PKT_MAX_SIZE 0x3fff
+
+#define DSI_VID_HSA_TIME 0x48
+#define DSI_VID_HBP_TIME 0x4c
+#define DSI_VID_HLINE_TIME 0x50
+#define DSI_VID_VSA_LINES 0x54
+#define DSI_VID_VBP_LINES 0x58
+#define DSI_VID_VFP_LINES 0x5c
+#define DSI_VID_VACTIVE_LINES 0x60
+#define DSI_CMD_MODE_CFG 0x68
+#define MAX_RD_PKT_SIZE_LP BIT(24)
+#define DCS_LW_TX_LP BIT(19)
+#define DCS_SR_0P_TX_LP BIT(18)
+#define DCS_SW_1P_TX_LP BIT(17)
+#define DCS_SW_0P_TX_LP BIT(16)
+#define GEN_LW_TX_LP BIT(14)
+#define GEN_SR_2P_TX_LP BIT(13)
+#define GEN_SR_1P_TX_LP BIT(12)
+#define GEN_SR_0P_TX_LP BIT(11)
+#define GEN_SW_2P_TX_LP BIT(10)
+#define GEN_SW_1P_TX_LP BIT(9)
+#define GEN_SW_0P_TX_LP BIT(8)
+#define EN_ACK_RQST BIT(1)
+#define EN_TEAR_FX BIT(0)
+
+#define CMD_MODE_ALL_LP (MAX_RD_PKT_SIZE_LP | \
+ DCS_LW_TX_LP | \
+ DCS_SR_0P_TX_LP | \
+ DCS_SW_1P_TX_LP | \
+ DCS_SW_0P_TX_LP | \
+ GEN_LW_TX_LP | \
+ GEN_SR_2P_TX_LP | \
+ GEN_SR_1P_TX_LP | \
+ GEN_SR_0P_TX_LP | \
+ GEN_SW_2P_TX_LP | \
+ GEN_SW_1P_TX_LP | \
+ GEN_SW_0P_TX_LP)
+
+#define DSI_GEN_HDR 0x6c
+#define GEN_HDATA(data) (((data) & 0xffff) << 8)
+#define GEN_HDATA_MASK (0xffff << 8)
+#define GEN_HTYPE(type) (((type) & 0xff) << 0)
+#define GEN_HTYPE_MASK 0xff
+
+#define DSI_GEN_PLD_DATA 0x70
+
+#define DSI_CMD_PKT_STATUS 0x74
+#define GEN_CMD_EMPTY BIT(0)
+#define GEN_CMD_FULL BIT(1)
+#define GEN_PLD_W_EMPTY BIT(2)
+#define GEN_PLD_W_FULL BIT(3)
+#define GEN_PLD_R_EMPTY BIT(4)
+#define GEN_PLD_R_FULL BIT(5)
+#define GEN_RD_CMD_BUSY BIT(6)
+
+#define DSI_TO_CNT_CFG 0x78
+#define HSTX_TO_CNT(p) (((p) & 0xffff) << 16)
+#define LPRX_TO_CNT(p) ((p) & 0xffff)
+
+#define DSI_BTA_TO_CNT 0x8c
+#define DSI_LPCLK_CTRL 0x94
+#define AUTO_CLKLANE_CTRL BIT(1)
+#define PHY_TXREQUESTCLKHS BIT(0)
+
+#define DSI_PHY_TMR_LPCLK_CFG 0x98
+#define PHY_CLKHS2LP_TIME(lbcc) (((lbcc) & 0x3ff) << 16)
+#define PHY_CLKLP2HS_TIME(lbcc) ((lbcc) & 0x3ff)
+
+#define DSI_PHY_TMR_CFG 0x9c
+#define PHY_HS2LP_TIME(lbcc) (((lbcc) & 0xff) << 24)
+#define PHY_LP2HS_TIME(lbcc) (((lbcc) & 0xff) << 16)
+#define MAX_RD_TIME(lbcc) ((lbcc) & 0x7fff)
+
+#define DSI_PHY_RSTZ 0xa0
+#define PHY_DISFORCEPLL 0
+#define PHY_ENFORCEPLL BIT(3)
+#define PHY_DISABLECLK 0
+#define PHY_ENABLECLK BIT(2)
+#define PHY_RSTZ 0
+#define PHY_UNRSTZ BIT(1)
+#define PHY_SHUTDOWNZ 0
+#define PHY_UNSHUTDOWNZ BIT(0)
+
+#define DSI_PHY_IF_CFG 0xa4
+#define N_LANES(n) ((((n) - 1) & 0x3) << 0)
+#define PHY_STOP_WAIT_TIME(cycle) (((cycle) & 0xff) << 8)
+
+#define DSI_PHY_STATUS 0xb0
+#define LOCK BIT(0)
+#define STOP_STATE_CLK_LANE BIT(2)
+
+#define DSI_PHY_TST_CTRL0 0xb4
+#define PHY_TESTCLK BIT(1)
+#define PHY_UNTESTCLK 0
+#define PHY_TESTCLR BIT(0)
+#define PHY_UNTESTCLR 0
+
+#define DSI_PHY_TST_CTRL1 0xb8
+#define PHY_TESTEN BIT(16)
+#define PHY_UNTESTEN 0
+#define PHY_TESTDOUT(n) (((n) & 0xff) << 8)
+#define PHY_TESTDIN(n) (((n) & 0xff) << 0)
+
+#define DSI_INT_ST0 0xbc
+#define DSI_INT_ST1 0xc0
+#define DSI_INT_MSK0 0xc4
+#define DSI_INT_MSK1 0xc8
+
+#define PHY_STATUS_TIMEOUT_US 10000
+#define CMD_PKT_STATUS_TIMEOUT_US 20000
+
+struct dw_mipi_dsi {
+ struct drm_bridge bridge;
+ struct mipi_dsi_host dsi_host;
+ struct drm_bridge *panel_bridge;
+ bool is_panel_bridge;
+ struct device *dev;
+ void __iomem *base;
+
+ struct clk *pclk;
+
+ unsigned int lane_mbps; /* per lane */
+ u32 channel;
+ u32 lanes;
+ u32 format;
+ unsigned long mode_flags;
+
+ const struct dw_mipi_dsi_plat_data *plat_data;
+};
+
+/*
+ * The controller should generate 2 frames before
+ * preparing the peripheral.
+ */
+static void dw_mipi_dsi_wait_for_two_frames(struct drm_display_mode *mode)
+{
+ int refresh, two_frames;
+
+ refresh = drm_mode_vrefresh(mode);
+ two_frames = DIV_ROUND_UP(MSEC_PER_SEC, refresh) * 2;
+ msleep(two_frames);
+}
+
+static inline struct dw_mipi_dsi *host_to_dsi(struct mipi_dsi_host *host)
+{
+ return container_of(host, struct dw_mipi_dsi, dsi_host);
+}
+
+static inline struct dw_mipi_dsi *bridge_to_dsi(struct drm_bridge *bridge)
+{
+ return container_of(bridge, struct dw_mipi_dsi, bridge);
+}
+
+static inline void dsi_write(struct dw_mipi_dsi *dsi, u32 reg, u32 val)
+{
+ writel(val, dsi->base + reg);
+}
+
+static inline u32 dsi_read(struct dw_mipi_dsi *dsi, u32 reg)
+{
+ return readl(dsi->base + reg);
+}
+
+static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
+ struct mipi_dsi_device *device)
+{
+ struct dw_mipi_dsi *dsi = host_to_dsi(host);
+ struct drm_bridge *bridge;
+ struct drm_panel *panel;
+ int ret;
+
+ if (device->lanes > dsi->plat_data->max_data_lanes) {
+ dev_err(dsi->dev, "the number of data lanes(%u) is too many\n",
+ device->lanes);
+ return -EINVAL;
+ }
+
+ dsi->lanes = device->lanes;
+ dsi->channel = device->channel;
+ dsi->format = device->format;
+ dsi->mode_flags = device->mode_flags;
+
+ ret = drm_of_find_panel_or_bridge(host->dev->of_node, 1, 0,
+ &panel, &bridge);
+ if (ret)
+ return ret;
+
+ if (panel) {
+ bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_DSI);
+ if (IS_ERR(bridge))
+ return PTR_ERR(bridge);
+ dsi->is_panel_bridge = true;
+ }
+
+ dsi->panel_bridge = bridge;
+
+ drm_bridge_add(&dsi->bridge);
+
+ return 0;
+}
+
+static int dw_mipi_dsi_host_detach(struct mipi_dsi_host *host,
+ struct mipi_dsi_device *device)
+{
+ struct dw_mipi_dsi *dsi = host_to_dsi(host);
+
+ if (dsi->is_panel_bridge)
+ drm_panel_bridge_remove(dsi->panel_bridge);
+
+ drm_bridge_remove(&dsi->bridge);
+
+ return 0;
+}
+
+static void dw_mipi_message_config(struct dw_mipi_dsi *dsi,
+ const struct mipi_dsi_msg *msg)
+{
+ bool lpm = msg->flags & MIPI_DSI_MSG_USE_LPM;
+ u32 val = 0;
+
+ if (msg->flags & MIPI_DSI_MSG_REQ_ACK)
+ val |= EN_ACK_RQST;
+ if (lpm)
+ val |= CMD_MODE_ALL_LP;
+
+ dsi_write(dsi, DSI_LPCLK_CTRL, lpm ? 0 : PHY_TXREQUESTCLKHS);
+ dsi_write(dsi, DSI_CMD_MODE_CFG, val);
+}
+
+static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)
+{
+ int ret;
+ u32 val, mask;
+
+ ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
+ val, !(val & GEN_CMD_FULL), 1000,
+ CMD_PKT_STATUS_TIMEOUT_US);
+ if (ret < 0) {
+ dev_err(dsi->dev, "failed to get available command FIFO\n");
+ return ret;
+ }
+
+ dsi_write(dsi, DSI_GEN_HDR, hdr_val);
+
+ mask = GEN_CMD_EMPTY | GEN_PLD_W_EMPTY;
+ ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
+ val, (val & mask) == mask,
+ 1000, CMD_PKT_STATUS_TIMEOUT_US);
+ if (ret < 0) {
+ dev_err(dsi->dev, "failed to write command FIFO\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int dw_mipi_dsi_dcs_short_write(struct dw_mipi_dsi *dsi,
+ const struct mipi_dsi_msg *msg)
+{
+ const u8 *tx_buf = msg->tx_buf;
+ u16 data = 0;
+ u32 val;
+
+ if (msg->tx_len > 0)
+ data |= tx_buf[0];
+ if (msg->tx_len > 1)
+ data |= tx_buf[1] << 8;
+
+ if (msg->tx_len > 2) {
+ dev_err(dsi->dev, "too long tx buf length %zu for short write\n",
+ msg->tx_len);
+ return -EINVAL;
+ }
+
+ val = GEN_HDATA(data) | GEN_HTYPE(msg->type);
+ return dw_mipi_dsi_gen_pkt_hdr_write(dsi, val);
+}
+
+static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,
+ const struct mipi_dsi_msg *msg)
+{
+ const u8 *tx_buf = msg->tx_buf;
+ int len = msg->tx_len, pld_data_bytes = sizeof(u32), ret;
+ u32 hdr_val = GEN_HDATA(msg->tx_len) | GEN_HTYPE(msg->type);
+ u32 remainder;
+ u32 val;
+
+ if (msg->tx_len < 3) {
+ dev_err(dsi->dev, "wrong tx buf length %zu for long write\n",
+ msg->tx_len);
+ return -EINVAL;
+ }
+
+ while (DIV_ROUND_UP(len, pld_data_bytes)) {
+ if (len < pld_data_bytes) {
+ remainder = 0;
+ memcpy(&remainder, tx_buf, len);
+ dsi_write(dsi, DSI_GEN_PLD_DATA, remainder);
+ len = 0;
+ } else {
+ memcpy(&remainder, tx_buf, pld_data_bytes);
+ dsi_write(dsi, DSI_GEN_PLD_DATA, remainder);
+ tx_buf += pld_data_bytes;
+ len -= pld_data_bytes;
+ }
+
+ ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
+ val, !(val & GEN_PLD_W_FULL), 1000,
+ CMD_PKT_STATUS_TIMEOUT_US);
+ if (ret < 0) {
+ dev_err(dsi->dev,
+ "failed to get available write payload FIFO\n");
+ return ret;
+ }
+ }
+
+ return dw_mipi_dsi_gen_pkt_hdr_write(dsi, hdr_val);
+}
+
+static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host,
+ const struct mipi_dsi_msg *msg)
+{
+ struct dw_mipi_dsi *dsi = host_to_dsi(host);
+ int ret;
+
+ /*
+ * TODO dw drv improvements
+ * use mipi_dsi_create_packet() instead of all following
+ * functions and code (no switch cases, no
+ * dw_mipi_dsi_dcs_short_write(), only the loop in long_write...)
+ * and use packet.header...
+ */
+ dw_mipi_message_config(dsi, msg);
+
+ switch (msg->type) {
+ case MIPI_DSI_DCS_SHORT_WRITE:
+ case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
+ case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
+ ret = dw_mipi_dsi_dcs_short_write(dsi, msg);
+ break;
+ case MIPI_DSI_DCS_LONG_WRITE:
+ ret = dw_mipi_dsi_dcs_long_write(dsi, msg);
+ break;
+ default:
+ dev_err(dsi->dev, "unsupported message type 0x%02x\n",
+ msg->type);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static const struct mipi_dsi_host_ops dw_mipi_dsi_host_ops = {
+ .attach = dw_mipi_dsi_host_attach,
+ .detach = dw_mipi_dsi_host_detach,
+ .transfer = dw_mipi_dsi_host_transfer,
+};
+
+static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi)
+{
+ u32 val;
+
+ /*
+ * TODO dw drv improvements
+ * enabling low power is panel-dependent, we should use the
+ * panel configuration here...
+ */
+ val = ENABLE_LOW_POWER;
+
+ if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
+ val |= VID_MODE_TYPE_BURST;
+ else if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
+ val |= VID_MODE_TYPE_NON_BURST_SYNC_PULSES;
+ else
+ val |= VID_MODE_TYPE_NON_BURST_SYNC_EVENTS;
+
+ dsi_write(dsi, DSI_VID_MODE_CFG, val);
+}
+
+static void dw_mipi_dsi_set_mode(struct dw_mipi_dsi *dsi,
+ unsigned long mode_flags)
+{
+ dsi_write(dsi, DSI_PWR_UP, RESET);
+
+ if (mode_flags & MIPI_DSI_MODE_VIDEO) {
+ dsi_write(dsi, DSI_MODE_CFG, ENABLE_VIDEO_MODE);
+ dw_mipi_dsi_video_mode_config(dsi);
+ dsi_write(dsi, DSI_LPCLK_CTRL, PHY_TXREQUESTCLKHS);
+ } else {
+ dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE);
+ }
+
+ dsi_write(dsi, DSI_PWR_UP, POWERUP);
+}
+
+static void dw_mipi_dsi_disable(struct dw_mipi_dsi *dsi)
+{
+ dsi_write(dsi, DSI_PWR_UP, RESET);
+ dsi_write(dsi, DSI_PHY_RSTZ, PHY_RSTZ);
+}
+
+static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi)
+{
+ /*
+ * The maximum permitted escape clock is 20MHz and it is derived from
+ * lanebyteclk, which is running at "lane_mbps / 8". Thus we want:
+ *
+ * (lane_mbps >> 3) / esc_clk_division < 20
+ * which is:
+ * (lane_mbps >> 3) / 20 > esc_clk_division
+ */
+ u32 esc_clk_division = (dsi->lane_mbps >> 3) / 20 + 1;
+
+ dsi_write(dsi, DSI_PWR_UP, RESET);
+
+ /*
+ * TODO dw drv improvements
+ * timeout clock division should be computed with the
+ * high speed transmission counter timeout and byte lane...
+ */
+ dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVIDSION(10) |
+ TX_ESC_CLK_DIVIDSION(esc_clk_division));
+}
+
+static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi,
+ struct drm_display_mode *mode)
+{
+ u32 val = 0, color = 0;
+
+ switch (dsi->format) {
+ case MIPI_DSI_FMT_RGB888:
+ color = DPI_COLOR_CODING_24BIT;
+ break;
+ case MIPI_DSI_FMT_RGB666:
+ color = DPI_COLOR_CODING_18BIT_2 | EN18_LOOSELY;
+ break;
+ case MIPI_DSI_FMT_RGB666_PACKED:
+ color = DPI_COLOR_CODING_18BIT_1;
+ break;
+ case MIPI_DSI_FMT_RGB565:
+ color = DPI_COLOR_CODING_16BIT_1;
+ break;
+ }
+
+ if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+ val |= VSYNC_ACTIVE_LOW;
+ if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+ val |= HSYNC_ACTIVE_LOW;
+
+ dsi_write(dsi, DSI_DPI_VCID, DPI_VID(dsi->channel));
+ dsi_write(dsi, DSI_DPI_COLOR_CODING, color);
+ dsi_write(dsi, DSI_DPI_CFG_POL, val);
+ /*
+ * TODO dw drv improvements
+ * largest packet sizes during hfp or during vsa/vpb/vfp
+ * should be computed according to byte lane, lane number and only
+ * if sending lp cmds in high speed is enable (PHY_TXREQUESTCLKHS)
+ */
+ dsi_write(dsi, DSI_DPI_LP_CMD_TIM, OUTVACT_LPCMD_TIME(4)
+ | INVACT_LPCMD_TIME(4));
+}
+
+static void dw_mipi_dsi_packet_handler_config(struct dw_mipi_dsi *dsi)
+{
+ dsi_write(dsi, DSI_PCKHDL_CFG, EN_CRC_RX | EN_ECC_RX | EN_BTA);
+}
+
+static void dw_mipi_dsi_video_packet_config(struct dw_mipi_dsi *dsi,
+ struct drm_display_mode *mode)
+{
+ /*
+ * TODO dw drv improvements
+ * only burst mode is supported here. For non-burst video modes,
+ * we should compute DSI_VID_PKT_SIZE, DSI_VCCR.NUMC &
+ * DSI_VNPCR.NPSIZE... especially because this driver supports
+ * non-burst video modes, see dw_mipi_dsi_video_mode_config()...
+ */
+ dsi_write(dsi, DSI_VID_PKT_SIZE, VID_PKT_SIZE(mode->hdisplay));
+}
+
+static void dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi)
+{
+ /*
+ * TODO dw drv improvements
+ * compute high speed transmission counter timeout according
+ * to the timeout clock division (TO_CLK_DIVIDSION) and byte lane...
+ */
+ dsi_write(dsi, DSI_TO_CNT_CFG, HSTX_TO_CNT(1000) | LPRX_TO_CNT(1000));
+ /*
+ * TODO dw drv improvements
+ * the Bus-Turn-Around Timeout Counter should be computed
+ * according to byte lane...
+ */
+ dsi_write(dsi, DSI_BTA_TO_CNT, 0xd00);
+ dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE);
+}
+
+/* Get lane byte clock cycles. */
+static u32 dw_mipi_dsi_get_hcomponent_lbcc(struct dw_mipi_dsi *dsi,
+ struct drm_display_mode *mode,
+ u32 hcomponent)
+{
+ u32 frac, lbcc;
+
+ lbcc = hcomponent * dsi->lane_mbps * MSEC_PER_SEC / 8;
+
+ frac = lbcc % mode->clock;
+ lbcc = lbcc / mode->clock;
+ if (frac)
+ lbcc++;
+
+ return lbcc;
+}
+
+static void dw_mipi_dsi_line_timer_config(struct dw_mipi_dsi *dsi,
+ struct drm_display_mode *mode)
+{
+ u32 htotal, hsa, hbp, lbcc;
+
+ htotal = mode->htotal;
+ hsa = mode->hsync_end - mode->hsync_start;
+ hbp = mode->htotal - mode->hsync_end;
+
+ /*
+ * TODO dw drv improvements
+ * computations below may be improved...
+ */
+ lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, mode, htotal);
+ dsi_write(dsi, DSI_VID_HLINE_TIME, lbcc);
+
+ lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, mode, hsa);
+ dsi_write(dsi, DSI_VID_HSA_TIME, lbcc);
+
+ lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, mode, hbp);
+ dsi_write(dsi, DSI_VID_HBP_TIME, lbcc);
+}
+
+static void dw_mipi_dsi_vertical_timing_config(struct dw_mipi_dsi *dsi,
+ struct drm_display_mode *mode)
+{
+ u32 vactive, vsa, vfp, vbp;
+
+ vactive = mode->vdisplay;
+ vsa = mode->vsync_end - mode->vsync_start;
+ vfp = mode->vsync_start - mode->vdisplay;
+ vbp = mode->vtotal - mode->vsync_end;
+
+ dsi_write(dsi, DSI_VID_VACTIVE_LINES, vactive);
+ dsi_write(dsi, DSI_VID_VSA_LINES, vsa);
+ dsi_write(dsi, DSI_VID_VFP_LINES, vfp);
+ dsi_write(dsi, DSI_VID_VBP_LINES, vbp);
+}
+
+static void dw_mipi_dsi_dphy_timing_config(struct dw_mipi_dsi *dsi)
+{
+ /*
+ * TODO dw drv improvements
+ * data & clock lane timers should be computed according to panel
+ * blankings and to the automatic clock lane control mode...
+ * note: DSI_PHY_TMR_CFG.MAX_RD_TIME should be in line with
+ * DSI_CMD_MODE_CFG.MAX_RD_PKT_SIZE_LP (see CMD_MODE_ALL_LP)
+ */
+ dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME(0x40)
+ | PHY_LP2HS_TIME(0x40) | MAX_RD_TIME(10000));
+
+ dsi_write(dsi, DSI_PHY_TMR_LPCLK_CFG, PHY_CLKHS2LP_TIME(0x40)
+ | PHY_CLKLP2HS_TIME(0x40));
+}
+
+static void dw_mipi_dsi_dphy_interface_config(struct dw_mipi_dsi *dsi)
+{
+ /*
+ * TODO dw drv improvements
+ * stop wait time should be the maximum between host dsi
+ * and panel stop wait times
+ */
+ dsi_write(dsi, DSI_PHY_IF_CFG, PHY_STOP_WAIT_TIME(0x20) |
+ N_LANES(dsi->lanes));
+}
+
+static void dw_mipi_dsi_dphy_init(struct dw_mipi_dsi *dsi)
+{
+ /* Clear PHY state */
+ dsi_write(dsi, DSI_PHY_RSTZ, PHY_DISFORCEPLL | PHY_DISABLECLK
+ | PHY_RSTZ | PHY_SHUTDOWNZ);
+ dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR);
+ dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLR);
+ dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR);
+}
+
+static void dw_mipi_dsi_dphy_enable(struct dw_mipi_dsi *dsi)
+{
+ u32 val;
+ int ret;
+
+ dsi_write(dsi, DSI_PHY_RSTZ, PHY_ENFORCEPLL | PHY_ENABLECLK |
+ PHY_UNRSTZ | PHY_UNSHUTDOWNZ);
+
+ ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS,
+ val, val & LOCK, 1000, PHY_STATUS_TIMEOUT_US);
+ if (ret < 0)
+ DRM_DEBUG_DRIVER("failed to wait phy lock state\n");
+
+ ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS,
+ val, val & STOP_STATE_CLK_LANE, 1000,
+ PHY_STATUS_TIMEOUT_US);
+ if (ret < 0)
+ DRM_DEBUG_DRIVER("failed to wait phy clk lane stop state\n");
+}
+
+static void dw_mipi_dsi_clear_err(struct dw_mipi_dsi *dsi)
+{
+ dsi_read(dsi, DSI_INT_ST0);
+ dsi_read(dsi, DSI_INT_ST1);
+ dsi_write(dsi, DSI_INT_MSK0, 0);
+ dsi_write(dsi, DSI_INT_MSK1, 0);
+}
+
+static void dw_mipi_dsi_bridge_post_disable(struct drm_bridge *bridge)
+{
+ struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
+
+ /*
+ * Switch to command mode before panel-bridge post_disable &
+ * panel unprepare.
+ * Note: panel-bridge disable & panel disable has been called
+ * before by the drm framework.
+ */
+ dw_mipi_dsi_set_mode(dsi, 0);
+
+ /*
+ * TODO Only way found to call panel-bridge post_disable &
+ * panel unprepare before the dsi "final" disable...
+ * This needs to be fixed in the drm_bridge framework and the API
+ * needs to be updated to manage our own call chains...
+ */
+ dsi->panel_bridge->funcs->post_disable(dsi->panel_bridge);
+
+ dw_mipi_dsi_disable(dsi);
+ clk_disable_unprepare(dsi->pclk);
+ pm_runtime_put(dsi->dev);
+}
+
+void dw_mipi_dsi_bridge_mode_set(struct drm_bridge *bridge,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
+ const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops;
+ void *priv_data = dsi->plat_data->priv_data;
+ int ret;
+
+ clk_prepare_enable(dsi->pclk);
+
+ ret = phy_ops->get_lane_mbps(priv_data, mode, dsi->mode_flags,
+ dsi->lanes, dsi->format, &dsi->lane_mbps);
+ if (ret)
+ DRM_DEBUG_DRIVER("Phy get_lane_mbps() failed\n");
+
+ pm_runtime_get_sync(dsi->dev);
+ dw_mipi_dsi_init(dsi);
+ dw_mipi_dsi_dpi_config(dsi, mode);
+ dw_mipi_dsi_packet_handler_config(dsi);
+ dw_mipi_dsi_video_mode_config(dsi);
+ dw_mipi_dsi_video_packet_config(dsi, mode);
+ dw_mipi_dsi_command_mode_config(dsi);
+ dw_mipi_dsi_line_timer_config(dsi, mode);
+ dw_mipi_dsi_vertical_timing_config(dsi, mode);
+
+ dw_mipi_dsi_dphy_init(dsi);
+ dw_mipi_dsi_dphy_timing_config(dsi);
+ dw_mipi_dsi_dphy_interface_config(dsi);
+
+ dw_mipi_dsi_clear_err(dsi);
+
+ ret = phy_ops->init(priv_data);
+ if (ret)
+ DRM_DEBUG_DRIVER("Phy init() failed\n");
+
+ dw_mipi_dsi_dphy_enable(dsi);
+
+ dw_mipi_dsi_wait_for_two_frames(mode);
+
+ /* Switch to cmd mode for panel-bridge pre_enable & panel prepare */
+ dw_mipi_dsi_set_mode(dsi, 0);
+}
+
+static void dw_mipi_dsi_bridge_enable(struct drm_bridge *bridge)
+{
+ struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
+
+ /* Switch to video mode for panel-bridge enable & panel enable */
+ dw_mipi_dsi_set_mode(dsi, MIPI_DSI_MODE_VIDEO);
+}
+
+static enum drm_mode_status
+dw_mipi_dsi_bridge_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_mode *mode)
+{
+ struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
+ const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data;
+ enum drm_mode_status mode_status = MODE_OK;
+
+ if (pdata->mode_valid)
+ mode_status = pdata->mode_valid(pdata->priv_data, mode);
+
+ return mode_status;
+}
+
+static int dw_mipi_dsi_bridge_attach(struct drm_bridge *bridge)
+{
+ struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
+
+ if (!bridge->encoder) {
+ DRM_ERROR("Parent encoder object not found\n");
+ return -ENODEV;
+ }
+
+ /* Set the encoder type as caller does not know it */
+ bridge->encoder->encoder_type = DRM_MODE_ENCODER_DSI;
+
+ /* Attach the panel-bridge to the dsi bridge */
+ return drm_bridge_attach(bridge->encoder, dsi->panel_bridge, bridge);
+}
+
+static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = {
+ .mode_set = dw_mipi_dsi_bridge_mode_set,
+ .enable = dw_mipi_dsi_bridge_enable,
+ .post_disable = dw_mipi_dsi_bridge_post_disable,
+ .mode_valid = dw_mipi_dsi_bridge_mode_valid,
+ .attach = dw_mipi_dsi_bridge_attach,
+};
+
+static struct dw_mipi_dsi *
+__dw_mipi_dsi_probe(struct platform_device *pdev,
+ const struct dw_mipi_dsi_plat_data *plat_data)
+{
+ struct device *dev = &pdev->dev;
+ struct reset_control *apb_rst;
+ struct dw_mipi_dsi *dsi;
+ struct resource *res;
+ int ret;
+
+ dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
+ if (!dsi)
+ return ERR_PTR(-ENOMEM);
+
+ dsi->dev = dev;
+ dsi->plat_data = plat_data;
+
+ if (!plat_data->phy_ops->init || !plat_data->phy_ops->get_lane_mbps) {
+ DRM_ERROR("Phy not properly configured\n");
+ return ERR_PTR(-ENODEV);
+ }
+
+ if (!plat_data->base) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return ERR_PTR(-ENODEV);
+
+ dsi->base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(dsi->base))
+ return ERR_PTR(-ENODEV);
+
+ } else {
+ dsi->base = plat_data->base;
+ }
+
+ dsi->pclk = devm_clk_get(dev, "pclk");
+ if (IS_ERR(dsi->pclk)) {
+ ret = PTR_ERR(dsi->pclk);
+ dev_err(dev, "Unable to get pclk: %d\n", ret);
+ return ERR_PTR(ret);
+ }
+
+ /*
+ * Note that the reset was not defined in the initial device tree, so
+ * we have to be prepared for it not being found.
+ */
+ apb_rst = devm_reset_control_get(dev, "apb");
+ if (IS_ERR(apb_rst)) {
+ ret = PTR_ERR(apb_rst);
+ if (ret == -ENOENT) {
+ apb_rst = NULL;
+ } else {
+ dev_err(dev, "Unable to get reset control: %d\n", ret);
+ return ERR_PTR(ret);
+ }
+ }
+
+ if (apb_rst) {
+ ret = clk_prepare_enable(dsi->pclk);
+ if (ret) {
+ dev_err(dev, "%s: Failed to enable pclk\n", __func__);
+ return ERR_PTR(ret);
+ }
+
+ reset_control_assert(apb_rst);
+ usleep_range(10, 20);
+ reset_control_deassert(apb_rst);
+
+ clk_disable_unprepare(dsi->pclk);
+ }
+
+ pm_runtime_enable(dev);
+
+ dsi->dsi_host.ops = &dw_mipi_dsi_host_ops;
+ dsi->dsi_host.dev = dev;
+ ret = mipi_dsi_host_register(&dsi->dsi_host);
+ if (ret) {
+ dev_err(dev, "Failed to register MIPI host: %d\n", ret);
+ return ERR_PTR(ret);
+ }
+
+ dsi->bridge.driver_private = dsi;
+ dsi->bridge.funcs = &dw_mipi_dsi_bridge_funcs;
+#ifdef CONFIG_OF
+ dsi->bridge.of_node = pdev->dev.of_node;
+#endif
+
+ dev_set_drvdata(dev, dsi);
+
+ return dsi;
+}
+
+static void __dw_mipi_dsi_remove(struct dw_mipi_dsi *dsi)
+{
+ pm_runtime_disable(dsi->dev);
+}
+
+/*
+ * Probe/remove API, used from platforms based on the DRM bridge API.
+ */
+int dw_mipi_dsi_probe(struct platform_device *pdev,
+ const struct dw_mipi_dsi_plat_data *plat_data)
+{
+ struct dw_mipi_dsi *dsi;
+
+ dsi = __dw_mipi_dsi_probe(pdev, plat_data);
+ if (IS_ERR(dsi))
+ return PTR_ERR(dsi);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dw_mipi_dsi_probe);
+
+void dw_mipi_dsi_remove(struct platform_device *pdev)
+{
+ struct dw_mipi_dsi *dsi = platform_get_drvdata(pdev);
+
+ mipi_dsi_host_unregister(&dsi->dsi_host);
+
+ __dw_mipi_dsi_remove(dsi);
+}
+EXPORT_SYMBOL_GPL(dw_mipi_dsi_remove);
+
+/*
+ * Bind/unbind API, used from platforms based on the component framework.
+ */
+int dw_mipi_dsi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
+ const struct dw_mipi_dsi_plat_data *plat_data)
+{
+ struct dw_mipi_dsi *dsi;
+ int ret;
+
+ dsi = __dw_mipi_dsi_probe(pdev, plat_data);
+ if (IS_ERR(dsi))
+ return PTR_ERR(dsi);
+
+ ret = drm_bridge_attach(encoder, &dsi->bridge, NULL);
+ if (ret) {
+ dw_mipi_dsi_remove(pdev);
+ DRM_ERROR("Failed to initialize bridge with drm\n");
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dw_mipi_dsi_bind);
+
+void dw_mipi_dsi_unbind(struct device *dev)
+{
+ struct dw_mipi_dsi *dsi = dev_get_drvdata(dev);
+
+ __dw_mipi_dsi_remove(dsi);
+}
+EXPORT_SYMBOL_GPL(dw_mipi_dsi_unbind);
+
+MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
+MODULE_AUTHOR("Philippe Cornu <philippe.cornu@st.com>");
+MODULE_DESCRIPTION("DW MIPI DSI host controller driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:dw-mipi-dsi");
diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
index 0529e50..8571cfd 100644
--- a/drivers/gpu/drm/bridge/tc358767.c
+++ b/drivers/gpu/drm/bridge/tc358767.c
@@ -1160,7 +1160,6 @@ static const struct drm_connector_helper_funcs tc_connector_helper_funcs = {
};
static const struct drm_connector_funcs tc_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
.reset = drm_atomic_helper_connector_reset,
@@ -1325,11 +1324,7 @@ static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id)
tc->bridge.funcs = &tc_bridge_funcs;
tc->bridge.of_node = dev->of_node;
- ret = drm_bridge_add(&tc->bridge);
- if (ret) {
- dev_err(dev, "Failed to add drm_bridge: %d\n", ret);
- goto err_unregister_aux;
- }
+ drm_bridge_add(&tc->bridge);
i2c_set_clientdata(client, tc);
diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c b/drivers/gpu/drm/bridge/ti-tfp410.c
index eee4efd..acb8570 100644
--- a/drivers/gpu/drm/bridge/ti-tfp410.c
+++ b/drivers/gpu/drm/bridge/ti-tfp410.c
@@ -102,7 +102,6 @@ tfp410_connector_detect(struct drm_connector *connector, bool force)
}
static const struct drm_connector_funcs tfp410_con_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = tfp410_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
@@ -237,11 +236,7 @@ static int tfp410_init(struct device *dev)
}
}
- ret = drm_bridge_add(&dvi->bridge);
- if (ret) {
- dev_err(dev, "drm_bridge_add() failed: %d\n", ret);
- goto fail;
- }
+ drm_bridge_add(&dvi->bridge);
return 0;
fail:
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c
index d893ea2..69c4e35 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.c
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.c
@@ -132,7 +132,6 @@ static struct drm_driver driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM,
.load = cirrus_driver_load,
.unload = cirrus_driver_unload,
- .set_busid = drm_pci_set_busid,
.fops = &cirrus_driver_fops,
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
@@ -143,7 +142,6 @@ static struct drm_driver driver = {
.gem_free_object_unlocked = cirrus_gem_free_object,
.dumb_create = cirrus_dumb_create,
.dumb_map_offset = cirrus_dumb_mmap_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
};
static const struct dev_pm_ops cirrus_pm_ops = {
@@ -166,12 +164,12 @@ static int __init cirrus_init(void)
if (cirrus_modeset == 0)
return -EINVAL;
- return drm_pci_init(&driver, &cirrus_pci_driver);
+ return pci_register_driver(&cirrus_pci_driver);
}
static void __exit cirrus_exit(void)
{
- drm_pci_exit(&driver, &cirrus_pci_driver);
+ pci_unregister_driver(&cirrus_pci_driver);
}
module_init(cirrus_init);
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.h b/drivers/gpu/drm/cirrus/cirrus_drv.h
index 8690352..be2d7e48 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.h
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.h
@@ -96,7 +96,6 @@
struct cirrus_crtc {
struct drm_crtc base;
- u8 lut_r[256], lut_g[256], lut_b[256];
int last_dpms;
bool enabled;
};
@@ -180,13 +179,6 @@ cirrus_bo(struct ttm_buffer_object *bo)
#define to_cirrus_obj(x) container_of(x, struct cirrus_gem_object, base)
#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
- /* cirrus_mode.c */
-void cirrus_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno);
-void cirrus_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
- u16 *blue, int regno);
-
-
/* cirrus_main.c */
int cirrus_device_init(struct cirrus_device *cdev,
struct drm_device *ddev,
diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
index 7fa58ee..32fbfba 100644
--- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c
+++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
@@ -215,7 +215,6 @@ static int cirrusfb_create(struct drm_fb_helper *helper,
strcpy(info->fix.id, "cirrusdrmfb");
- info->flags = FBINFO_DEFAULT;
info->fbops = &cirrusfb_ops;
drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth);
@@ -252,7 +251,7 @@ static int cirrus_fbdev_destroy(struct drm_device *dev,
drm_fb_helper_unregister_fbi(&gfbdev->helper);
if (gfb->obj) {
- drm_gem_object_unreference_unlocked(gfb->obj);
+ drm_gem_object_put_unlocked(gfb->obj);
gfb->obj = NULL;
}
@@ -265,8 +264,6 @@ static int cirrus_fbdev_destroy(struct drm_device *dev,
}
static const struct drm_fb_helper_funcs cirrus_fb_helper_funcs = {
- .gamma_set = cirrus_crtc_fb_gamma_set,
- .gamma_get = cirrus_crtc_fb_gamma_get,
.fb_probe = cirrusfb_create,
};
diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c
index e7fc95f..b5f5285 100644
--- a/drivers/gpu/drm/cirrus/cirrus_main.c
+++ b/drivers/gpu/drm/cirrus/cirrus_main.c
@@ -18,7 +18,7 @@ static void cirrus_user_framebuffer_destroy(struct drm_framebuffer *fb)
{
struct cirrus_framebuffer *cirrus_fb = to_cirrus_framebuffer(fb);
- drm_gem_object_unreference_unlocked(cirrus_fb->obj);
+ drm_gem_object_put_unlocked(cirrus_fb->obj);
drm_framebuffer_cleanup(fb);
kfree(fb);
}
@@ -67,13 +67,13 @@ cirrus_user_framebuffer_create(struct drm_device *dev,
cirrus_fb = kzalloc(sizeof(*cirrus_fb), GFP_KERNEL);
if (!cirrus_fb) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ERR_PTR(-ENOMEM);
}
ret = cirrus_framebuffer_init(dev, cirrus_fb, mode_cmd, obj);
if (ret) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
kfree(cirrus_fb);
return ERR_PTR(ret);
}
@@ -261,7 +261,7 @@ int cirrus_dumb_create(struct drm_file *file,
return ret;
ret = drm_gem_handle_create(file, gobj, &handle);
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
if (ret)
return ret;
@@ -310,7 +310,7 @@ cirrus_dumb_mmap_offset(struct drm_file *file,
bo = gem_to_cirrus_bo(obj);
*offset = cirrus_bo_mmap_offset(bo);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return 0;
}
diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
index 53f6f0f..a4c4a46 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -31,25 +31,6 @@
* This file contains setup code for the CRTC.
*/
-static void cirrus_crtc_load_lut(struct drm_crtc *crtc)
-{
- struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc);
- struct drm_device *dev = crtc->dev;
- struct cirrus_device *cdev = dev->dev_private;
- int i;
-
- if (!crtc->enabled)
- return;
-
- for (i = 0; i < CIRRUS_LUT_SIZE; i++) {
- /* VGA registers */
- WREG8(PALETTE_INDEX, i);
- WREG8(PALETTE_DATA, cirrus_crtc->lut_r[i]);
- WREG8(PALETTE_DATA, cirrus_crtc->lut_g[i]);
- WREG8(PALETTE_DATA, cirrus_crtc->lut_b[i]);
- }
-}
-
/*
* The DRM core requires DPMS functions, but they make little sense in our
* case and so are just stubs
@@ -330,15 +311,25 @@ static int cirrus_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
u16 *blue, uint32_t size,
struct drm_modeset_acquire_ctx *ctx)
{
- struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
+ struct cirrus_device *cdev = dev->dev_private;
+ u16 *r, *g, *b;
int i;
- for (i = 0; i < size; i++) {
- cirrus_crtc->lut_r[i] = red[i];
- cirrus_crtc->lut_g[i] = green[i];
- cirrus_crtc->lut_b[i] = blue[i];
+ if (!crtc->enabled)
+ return 0;
+
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
+
+ for (i = 0; i < CIRRUS_LUT_SIZE; i++) {
+ /* VGA registers */
+ WREG8(PALETTE_INDEX, i);
+ WREG8(PALETTE_DATA, *r++ >> 8);
+ WREG8(PALETTE_DATA, *g++ >> 8);
+ WREG8(PALETTE_DATA, *b++ >> 8);
}
- cirrus_crtc_load_lut(crtc);
return 0;
}
@@ -365,7 +356,6 @@ static const struct drm_crtc_helper_funcs cirrus_helper_funcs = {
.mode_set_base = cirrus_crtc_mode_set_base,
.prepare = cirrus_crtc_prepare,
.commit = cirrus_crtc_commit,
- .load_lut = cirrus_crtc_load_lut,
};
/* CRTC setup */
@@ -373,7 +363,6 @@ static void cirrus_crtc_init(struct drm_device *dev)
{
struct cirrus_device *cdev = dev->dev_private;
struct cirrus_crtc *cirrus_crtc;
- int i;
cirrus_crtc = kzalloc(sizeof(struct cirrus_crtc) +
(CIRRUSFB_CONN_LIMIT * sizeof(struct drm_connector *)),
@@ -387,37 +376,9 @@ static void cirrus_crtc_init(struct drm_device *dev)
drm_mode_crtc_set_gamma_size(&cirrus_crtc->base, CIRRUS_LUT_SIZE);
cdev->mode_info.crtc = cirrus_crtc;
- for (i = 0; i < CIRRUS_LUT_SIZE; i++) {
- cirrus_crtc->lut_r[i] = i;
- cirrus_crtc->lut_g[i] = i;
- cirrus_crtc->lut_b[i] = i;
- }
-
drm_crtc_helper_add(&cirrus_crtc->base, &cirrus_helper_funcs);
}
-/** Sets the color ramps on behalf of fbcon */
-void cirrus_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno)
-{
- struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc);
-
- cirrus_crtc->lut_r[regno] = red;
- cirrus_crtc->lut_g[regno] = green;
- cirrus_crtc->lut_b[regno] = blue;
-}
-
-/** Gets the color ramps on behalf of fbcon */
-void cirrus_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
- u16 *blue, int regno)
-{
- struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc);
-
- *red = cirrus_crtc->lut_r[regno];
- *green = cirrus_crtc->lut_g[regno];
- *blue = cirrus_crtc->lut_b[regno];
-}
-
static void cirrus_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index aed25c4..2fd383d 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -29,7 +29,6 @@
#include <drm/drmP.h>
#include <drm/drm_atomic.h>
#include <drm/drm_mode.h>
-#include <drm/drm_plane_helper.h>
#include <drm/drm_print.h>
#include <linux/sync_file.h>
@@ -188,12 +187,15 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
}
for (i = 0; i < state->num_private_objs; i++) {
- void *obj_state = state->private_objs[i].obj_state;
+ struct drm_private_obj *obj = state->private_objs[i].ptr;
- state->private_objs[i].funcs->destroy_state(obj_state);
- state->private_objs[i].obj = NULL;
- state->private_objs[i].obj_state = NULL;
- state->private_objs[i].funcs = NULL;
+ if (!obj)
+ continue;
+
+ obj->funcs->atomic_destroy_state(obj,
+ state->private_objs[i].state);
+ state->private_objs[i].ptr = NULL;
+ state->private_objs[i].state = NULL;
}
state->num_private_objs = 0;
@@ -409,34 +411,6 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state,
}
EXPORT_SYMBOL(drm_atomic_set_mode_prop_for_crtc);
-/**
- * drm_atomic_replace_property_blob - replace a blob property
- * @blob: a pointer to the member blob to be replaced
- * @new_blob: the new blob to replace with
- * @replaced: whether the blob has been replaced
- *
- * RETURNS:
- * Zero on success, error code on failure
- */
-static void
-drm_atomic_replace_property_blob(struct drm_property_blob **blob,
- struct drm_property_blob *new_blob,
- bool *replaced)
-{
- struct drm_property_blob *old_blob = *blob;
-
- if (old_blob == new_blob)
- return;
-
- drm_property_blob_put(old_blob);
- if (new_blob)
- drm_property_blob_get(new_blob);
- *blob = new_blob;
- *replaced = true;
-
- return;
-}
-
static int
drm_atomic_replace_property_blob_from_id(struct drm_device *dev,
struct drm_property_blob **blob,
@@ -457,7 +431,7 @@ drm_atomic_replace_property_blob_from_id(struct drm_device *dev,
}
}
- drm_atomic_replace_property_blob(blob, new_blob, replaced);
+ *replaced |= drm_property_replace_blob(blob, new_blob);
drm_property_blob_put(new_blob);
return 0;
@@ -739,7 +713,7 @@ EXPORT_SYMBOL(drm_atomic_get_plane_state);
* RETURNS:
* Zero on success, error code on failure
*/
-int drm_atomic_plane_set_property(struct drm_plane *plane,
+static int drm_atomic_plane_set_property(struct drm_plane *plane,
struct drm_plane_state *state, struct drm_property *property,
uint64_t val)
{
@@ -796,7 +770,6 @@ int drm_atomic_plane_set_property(struct drm_plane *plane,
return 0;
}
-EXPORT_SYMBOL(drm_atomic_plane_set_property);
/**
* drm_atomic_plane_get_property - get property value from plane state
@@ -991,11 +964,44 @@ static void drm_atomic_plane_print_state(struct drm_printer *p,
}
/**
+ * drm_atomic_private_obj_init - initialize private object
+ * @obj: private object
+ * @state: initial private object state
+ * @funcs: pointer to the struct of function pointers that identify the object
+ * type
+ *
+ * Initialize the private object, which can be embedded into any
+ * driver private object that needs its own atomic state.
+ */
+void
+drm_atomic_private_obj_init(struct drm_private_obj *obj,
+ struct drm_private_state *state,
+ const struct drm_private_state_funcs *funcs)
+{
+ memset(obj, 0, sizeof(*obj));
+
+ obj->state = state;
+ obj->funcs = funcs;
+}
+EXPORT_SYMBOL(drm_atomic_private_obj_init);
+
+/**
+ * drm_atomic_private_obj_fini - finalize private object
+ * @obj: private object
+ *
+ * Finalize the private object.
+ */
+void
+drm_atomic_private_obj_fini(struct drm_private_obj *obj)
+{
+ obj->funcs->atomic_destroy_state(obj, obj->state);
+}
+EXPORT_SYMBOL(drm_atomic_private_obj_fini);
+
+/**
* drm_atomic_get_private_obj_state - get private object state
* @state: global atomic state
* @obj: private object to get the state for
- * @funcs: pointer to the struct of function pointers that identify the object
- * type
*
* This function returns the private object state for the given private object,
* allocating the state if needed. It does not grab any locks as the caller is
@@ -1005,18 +1011,18 @@ static void drm_atomic_plane_print_state(struct drm_printer *p,
*
* Either the allocated state or the error code encoded into a pointer.
*/
-void *
-drm_atomic_get_private_obj_state(struct drm_atomic_state *state, void *obj,
- const struct drm_private_state_funcs *funcs)
+struct drm_private_state *
+drm_atomic_get_private_obj_state(struct drm_atomic_state *state,
+ struct drm_private_obj *obj)
{
int index, num_objs, i;
size_t size;
struct __drm_private_objs_state *arr;
+ struct drm_private_state *obj_state;
for (i = 0; i < state->num_private_objs; i++)
- if (obj == state->private_objs[i].obj &&
- state->private_objs[i].obj_state)
- return state->private_objs[i].obj_state;
+ if (obj == state->private_objs[i].ptr)
+ return state->private_objs[i].state;
num_objs = state->num_private_objs + 1;
size = sizeof(*state->private_objs) * num_objs;
@@ -1028,18 +1034,21 @@ drm_atomic_get_private_obj_state(struct drm_atomic_state *state, void *obj,
index = state->num_private_objs;
memset(&state->private_objs[index], 0, sizeof(*state->private_objs));
- state->private_objs[index].obj_state = funcs->duplicate_state(state, obj);
- if (!state->private_objs[index].obj_state)
+ obj_state = obj->funcs->atomic_duplicate_state(obj);
+ if (!obj_state)
return ERR_PTR(-ENOMEM);
- state->private_objs[index].obj = obj;
- state->private_objs[index].funcs = funcs;
+ state->private_objs[index].state = obj_state;
+ state->private_objs[index].old_state = obj->state;
+ state->private_objs[index].new_state = obj_state;
+ state->private_objs[index].ptr = obj;
+
state->num_private_objs = num_objs;
- DRM_DEBUG_ATOMIC("Added new private object state %p to %p\n",
- state->private_objs[index].obj_state, state);
+ DRM_DEBUG_ATOMIC("Added new private object %p state %p to %p\n",
+ obj, obj_state, state);
- return state->private_objs[index].obj_state;
+ return obj_state;
}
EXPORT_SYMBOL(drm_atomic_get_private_obj_state);
@@ -1135,7 +1144,7 @@ EXPORT_SYMBOL(drm_atomic_get_connector_state);
* RETURNS:
* Zero on success, error code on failure
*/
-int drm_atomic_connector_set_property(struct drm_connector *connector,
+static int drm_atomic_connector_set_property(struct drm_connector *connector,
struct drm_connector_state *state, struct drm_property *property,
uint64_t val)
{
@@ -1202,7 +1211,6 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
return 0;
}
-EXPORT_SYMBOL(drm_atomic_connector_set_property);
static void drm_atomic_connector_print_state(struct drm_printer *p,
const struct drm_connector_state *state)
@@ -1580,38 +1588,6 @@ drm_atomic_add_affected_planes(struct drm_atomic_state *state,
EXPORT_SYMBOL(drm_atomic_add_affected_planes);
/**
- * drm_atomic_legacy_backoff - locking backoff for legacy ioctls
- * @state: atomic state
- *
- * This function should be used by legacy entry points which don't understand
- * -EDEADLK semantics. For simplicity this one will grab all modeset locks after
- * the slowpath completed.
- */
-void drm_atomic_legacy_backoff(struct drm_atomic_state *state)
-{
- struct drm_device *dev = state->dev;
- int ret;
- bool global = false;
-
- if (WARN_ON(dev->mode_config.acquire_ctx == state->acquire_ctx)) {
- global = true;
-
- dev->mode_config.acquire_ctx = NULL;
- }
-
-retry:
- drm_modeset_backoff(state->acquire_ctx);
-
- ret = drm_modeset_lock_all_ctx(dev, state->acquire_ctx);
- if (ret)
- goto retry;
-
- if (global)
- dev->mode_config.acquire_ctx = state->acquire_ctx;
-}
-EXPORT_SYMBOL(drm_atomic_legacy_backoff);
-
-/**
* drm_atomic_check_only - check whether a given config would work
* @state: atomic configuration to check
*
@@ -1857,9 +1833,60 @@ static struct drm_pending_vblank_event *create_vblank_event(
return e;
}
-static int atomic_set_prop(struct drm_atomic_state *state,
- struct drm_mode_object *obj, struct drm_property *prop,
- uint64_t prop_value)
+int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state,
+ struct drm_connector *connector,
+ int mode)
+{
+ struct drm_connector *tmp_connector;
+ struct drm_connector_state *new_conn_state;
+ struct drm_crtc *crtc;
+ struct drm_crtc_state *crtc_state;
+ int i, ret, old_mode = connector->dpms;
+ bool active = false;
+
+ ret = drm_modeset_lock(&state->dev->mode_config.connection_mutex,
+ state->acquire_ctx);
+ if (ret)
+ return ret;
+
+ if (mode != DRM_MODE_DPMS_ON)
+ mode = DRM_MODE_DPMS_OFF;
+ connector->dpms = mode;
+
+ crtc = connector->state->crtc;
+ if (!crtc)
+ goto out;
+ ret = drm_atomic_add_affected_connectors(state, crtc);
+ if (ret)
+ goto out;
+
+ crtc_state = drm_atomic_get_crtc_state(state, crtc);
+ if (IS_ERR(crtc_state)) {
+ ret = PTR_ERR(crtc_state);
+ goto out;
+ }
+
+ for_each_new_connector_in_state(state, tmp_connector, new_conn_state, i) {
+ if (new_conn_state->crtc != crtc)
+ continue;
+ if (tmp_connector->dpms == DRM_MODE_DPMS_ON) {
+ active = true;
+ break;
+ }
+ }
+
+ crtc_state->active = active;
+ ret = drm_atomic_commit(state);
+out:
+ if (ret != 0)
+ connector->dpms = old_mode;
+ return ret;
+}
+
+int drm_atomic_set_property(struct drm_atomic_state *state,
+ struct drm_mode_object *obj,
+ struct drm_property *prop,
+ uint64_t prop_value)
{
struct drm_mode_object *ref;
int ret;
@@ -2042,7 +2069,7 @@ static int prepare_crtc_signaling(struct drm_device *dev,
{
struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state;
- int i, ret;
+ int i, c = 0, ret;
if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY)
return 0;
@@ -2103,8 +2130,17 @@ static int prepare_crtc_signaling(struct drm_device *dev,
crtc_state->event->base.fence = fence;
}
+
+ c++;
}
+ /*
+ * Having this flag means user mode pends on event which will never
+ * reach due to lack of at least one CRTC for signaling
+ */
+ if (c == 0 && (arg->flags & DRM_MODE_PAGE_FLIP_EVENT))
+ return -EINVAL;
+
return 0;
}
@@ -2272,7 +2308,8 @@ retry:
goto out;
}
- ret = atomic_set_prop(state, obj, prop, prop_value);
+ ret = drm_atomic_set_property(state, obj, prop,
+ prop_value);
if (ret) {
drm_mode_object_put(obj);
goto out;
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 86d3093..4e53aae 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -795,6 +795,9 @@ int drm_atomic_helper_check(struct drm_device *dev,
if (ret)
return ret;
+ if (state->legacy_cursor_update)
+ state->async_update = !drm_atomic_helper_async_check(dev, state);
+
return ret;
}
EXPORT_SYMBOL(drm_atomic_helper_check);
@@ -918,16 +921,12 @@ drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev,
crtc = new_conn_state->crtc;
if ((!crtc && old_conn_state->crtc) ||
(crtc && drm_atomic_crtc_needs_modeset(crtc->state))) {
- struct drm_property *dpms_prop =
- dev->mode_config.dpms_property;
int mode = DRM_MODE_DPMS_OFF;
if (crtc && crtc->state->active)
mode = DRM_MODE_DPMS_ON;
connector->dpms = mode;
- drm_object_property_set_value(&connector->base,
- dpms_prop, mode);
}
}
@@ -1069,12 +1068,13 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
struct drm_atomic_state *old_state)
{
struct drm_crtc *crtc;
+ struct drm_crtc_state *old_crtc_state;
struct drm_crtc_state *new_crtc_state;
struct drm_connector *connector;
struct drm_connector_state *new_conn_state;
int i;
- for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
+ for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
const struct drm_crtc_helper_funcs *funcs;
/* Need to filter out CRTCs where only planes change. */
@@ -1090,8 +1090,8 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
DRM_DEBUG_ATOMIC("enabling [CRTC:%d:%s]\n",
crtc->base.id, crtc->name);
- if (funcs->enable)
- funcs->enable(crtc);
+ if (funcs->atomic_enable)
+ funcs->atomic_enable(crtc, old_crtc_state);
else
funcs->commit(crtc);
}
@@ -1191,9 +1191,13 @@ EXPORT_SYMBOL(drm_atomic_helper_wait_for_fences);
*
* Helper to, after atomic commit, wait for vblanks on all effected
* crtcs (ie. before cleaning up old framebuffers using
- * drm_atomic_helper_cleanup_planes()). It will only wait on crtcs where the
+ * drm_atomic_helper_cleanup_planes()). It will only wait on CRTCs where the
* framebuffers have actually changed to optimize for the legacy cursor and
* plane update use-case.
+ *
+ * Drivers using the nonblocking commit tracking support initialized by calling
+ * drm_atomic_helper_setup_commit() should look at
+ * drm_atomic_helper_wait_for_flip_done() as an alternative.
*/
void
drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
@@ -1241,27 +1245,54 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks);
/**
+ * drm_atomic_helper_wait_for_flip_done - wait for all page flips to be done
+ * @dev: DRM device
+ * @old_state: atomic state object with old state structures
+ *
+ * Helper to, after atomic commit, wait for page flips on all effected
+ * crtcs (ie. before cleaning up old framebuffers using
+ * drm_atomic_helper_cleanup_planes()). Compared to
+ * drm_atomic_helper_wait_for_vblanks() this waits for the completion of on all
+ * CRTCs, assuming that cursors-only updates are signalling their completion
+ * immediately (or using a different path).
+ *
+ * This requires that drivers use the nonblocking commit tracking support
+ * initialized using drm_atomic_helper_setup_commit().
+ */
+void drm_atomic_helper_wait_for_flip_done(struct drm_device *dev,
+ struct drm_atomic_state *old_state)
+{
+ struct drm_crtc_state *unused;
+ struct drm_crtc *crtc;
+ int i;
+
+ for_each_new_crtc_in_state(old_state, crtc, unused, i) {
+ struct drm_crtc_commit *commit = old_state->crtcs[i].commit;
+ int ret;
+
+ if (!commit)
+ continue;
+
+ ret = wait_for_completion_timeout(&commit->flip_done, 10 * HZ);
+ if (ret == 0)
+ DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n",
+ crtc->base.id, crtc->name);
+ }
+}
+EXPORT_SYMBOL(drm_atomic_helper_wait_for_flip_done);
+
+/**
* drm_atomic_helper_commit_tail - commit atomic update to hardware
* @old_state: atomic state object with old state structures
*
* This is the default implementation for the
- * &drm_mode_config_helper_funcs.atomic_commit_tail hook.
+ * &drm_mode_config_helper_funcs.atomic_commit_tail hook, for drivers
+ * that do not support runtime_pm or do not need the CRTC to be
+ * enabled to perform a commit. Otherwise, see
+ * drm_atomic_helper_commit_tail_rpm().
*
* Note that the default ordering of how the various stages are called is to
- * match the legacy modeset helper library closest. One peculiarity of that is
- * that it doesn't mesh well with runtime PM at all.
- *
- * For drivers supporting runtime PM the recommended sequence is instead ::
- *
- * drm_atomic_helper_commit_modeset_disables(dev, old_state);
- *
- * drm_atomic_helper_commit_modeset_enables(dev, old_state);
- *
- * drm_atomic_helper_commit_planes(dev, old_state,
- * DRM_PLANE_COMMIT_ACTIVE_ONLY);
- *
- * for committing the atomic update to hardware. See the kerneldoc entries for
- * these three functions for more details.
+ * match the legacy modeset helper library closest.
*/
void drm_atomic_helper_commit_tail(struct drm_atomic_state *old_state)
{
@@ -1281,6 +1312,35 @@ void drm_atomic_helper_commit_tail(struct drm_atomic_state *old_state)
}
EXPORT_SYMBOL(drm_atomic_helper_commit_tail);
+/**
+ * drm_atomic_helper_commit_tail_rpm - commit atomic update to hardware
+ * @old_state: new modeset state to be committed
+ *
+ * This is an alternative implementation for the
+ * &drm_mode_config_helper_funcs.atomic_commit_tail hook, for drivers
+ * that support runtime_pm or need the CRTC to be enabled to perform a
+ * commit. Otherwise, one should use the default implementation
+ * drm_atomic_helper_commit_tail().
+ */
+void drm_atomic_helper_commit_tail_rpm(struct drm_atomic_state *old_state)
+{
+ struct drm_device *dev = old_state->dev;
+
+ drm_atomic_helper_commit_modeset_disables(dev, old_state);
+
+ drm_atomic_helper_commit_modeset_enables(dev, old_state);
+
+ drm_atomic_helper_commit_planes(dev, old_state,
+ DRM_PLANE_COMMIT_ACTIVE_ONLY);
+
+ drm_atomic_helper_commit_hw_done(old_state);
+
+ drm_atomic_helper_wait_for_vblanks(dev, old_state);
+
+ drm_atomic_helper_cleanup_planes(dev, old_state);
+}
+EXPORT_SYMBOL(drm_atomic_helper_commit_tail_rpm);
+
static void commit_tail(struct drm_atomic_state *old_state)
{
struct drm_device *dev = old_state->dev;
@@ -1311,6 +1371,114 @@ static void commit_work(struct work_struct *work)
}
/**
+ * drm_atomic_helper_async_check - check if state can be commited asynchronously
+ * @dev: DRM device
+ * @state: the driver state object
+ *
+ * This helper will check if it is possible to commit the state asynchronously.
+ * Async commits are not supposed to swap the states like normal sync commits
+ * but just do in-place changes on the current state.
+ *
+ * It will return 0 if the commit can happen in an asynchronous fashion or error
+ * if not. Note that error just mean it can't be commited asynchronously, if it
+ * fails the commit should be treated like a normal synchronous commit.
+ */
+int drm_atomic_helper_async_check(struct drm_device *dev,
+ struct drm_atomic_state *state)
+{
+ struct drm_crtc *crtc;
+ struct drm_crtc_state *crtc_state;
+ struct drm_crtc_commit *commit;
+ struct drm_plane *__plane, *plane = NULL;
+ struct drm_plane_state *__plane_state, *plane_state = NULL;
+ const struct drm_plane_helper_funcs *funcs;
+ int i, j, n_planes = 0;
+
+ for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
+ if (drm_atomic_crtc_needs_modeset(crtc_state))
+ return -EINVAL;
+ }
+
+ for_each_new_plane_in_state(state, __plane, __plane_state, i) {
+ n_planes++;
+ plane = __plane;
+ plane_state = __plane_state;
+ }
+
+ /* FIXME: we support only single plane updates for now */
+ if (!plane || n_planes != 1)
+ return -EINVAL;
+
+ if (!plane_state->crtc)
+ return -EINVAL;
+
+ funcs = plane->helper_private;
+ if (!funcs->atomic_async_update)
+ return -EINVAL;
+
+ if (plane_state->fence)
+ return -EINVAL;
+
+ /*
+ * Don't do an async update if there is an outstanding commit modifying
+ * the plane. This prevents our async update's changes from getting
+ * overridden by a previous synchronous update's state.
+ */
+ for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
+ if (plane->crtc != crtc)
+ continue;
+
+ spin_lock(&crtc->commit_lock);
+ commit = list_first_entry_or_null(&crtc->commit_list,
+ struct drm_crtc_commit,
+ commit_entry);
+ if (!commit) {
+ spin_unlock(&crtc->commit_lock);
+ continue;
+ }
+ spin_unlock(&crtc->commit_lock);
+
+ if (!crtc->state->state)
+ continue;
+
+ for_each_plane_in_state(crtc->state->state, __plane,
+ __plane_state, j) {
+ if (__plane == plane)
+ return -EINVAL;
+ }
+ }
+
+ return funcs->atomic_async_check(plane, plane_state);
+}
+EXPORT_SYMBOL(drm_atomic_helper_async_check);
+
+/**
+ * drm_atomic_helper_async_commit - commit state asynchronously
+ * @dev: DRM device
+ * @state: the driver state object
+ *
+ * This function commits a state asynchronously, i.e., not vblank
+ * synchronized. It should be used on a state only when
+ * drm_atomic_async_check() succeeds. Async commits are not supposed to swap
+ * the states like normal sync commits, but just do in-place changes on the
+ * current state.
+ */
+void drm_atomic_helper_async_commit(struct drm_device *dev,
+ struct drm_atomic_state *state)
+{
+ struct drm_plane *plane;
+ struct drm_plane_state *plane_state;
+ const struct drm_plane_helper_funcs *funcs;
+ int i;
+
+ for_each_new_plane_in_state(state, plane, plane_state, i) {
+ funcs = plane->helper_private;
+ funcs->atomic_async_update(plane, plane_state);
+ }
+}
+EXPORT_SYMBOL(drm_atomic_helper_async_commit);
+
+/**
* drm_atomic_helper_commit - commit validated state object
* @dev: DRM device
* @state: the driver state object
@@ -1334,6 +1502,17 @@ int drm_atomic_helper_commit(struct drm_device *dev,
{
int ret;
+ if (state->async_update) {
+ ret = drm_atomic_helper_prepare_planes(dev, state);
+ if (ret)
+ return ret;
+
+ drm_atomic_helper_async_commit(dev, state);
+ drm_atomic_helper_cleanup_planes(dev, state);
+
+ return 0;
+ }
+
ret = drm_atomic_helper_setup_commit(state, nonblock);
if (ret)
return ret;
@@ -1346,10 +1525,8 @@ int drm_atomic_helper_commit(struct drm_device *dev,
if (!nonblock) {
ret = drm_atomic_helper_wait_for_fences(dev, state, true);
- if (ret) {
- drm_atomic_helper_cleanup_planes(dev, state);
- return ret;
- }
+ if (ret)
+ goto err;
}
/*
@@ -1358,7 +1535,9 @@ int drm_atomic_helper_commit(struct drm_device *dev,
* the software side now.
*/
- drm_atomic_helper_swap_state(state, true);
+ ret = drm_atomic_helper_swap_state(state, true);
+ if (ret)
+ goto err;
/*
* Everything below can be run asynchronously without the need to grab
@@ -1387,6 +1566,10 @@ int drm_atomic_helper_commit(struct drm_device *dev,
commit_tail(state);
return 0;
+
+err:
+ drm_atomic_helper_cleanup_planes(dev, state);
+ return ret;
}
EXPORT_SYMBOL(drm_atomic_helper_commit);
@@ -1680,9 +1863,7 @@ void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *old_state)
/* backend must have consumed any event by now */
WARN_ON(new_crtc_state->event);
- spin_lock(&crtc->commit_lock);
complete_all(&commit->hw_done);
- spin_unlock(&crtc->commit_lock);
}
}
EXPORT_SYMBOL(drm_atomic_helper_commit_hw_done);
@@ -1711,7 +1892,6 @@ void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *old_state)
if (WARN_ON(!commit))
continue;
- spin_lock(&crtc->commit_lock);
complete_all(&commit->cleanup_done);
WARN_ON(!try_wait_for_completion(&commit->hw_done));
@@ -1721,8 +1901,6 @@ void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *old_state)
if (try_wait_for_completion(&commit->flip_done))
goto del_commit;
- spin_unlock(&crtc->commit_lock);
-
/* We must wait for the vblank event to signal our completion
* before releasing our reference, since the vblank work does
* not hold a reference of its own. */
@@ -1732,8 +1910,8 @@ void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *old_state)
DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n",
crtc->base.id, crtc->name);
- spin_lock(&crtc->commit_lock);
del_commit:
+ spin_lock(&crtc->commit_lock);
list_del(&commit->commit_entry);
spin_unlock(&crtc->commit_lock);
}
@@ -2069,14 +2247,14 @@ EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
/**
* drm_atomic_helper_swap_state - store atomic state into current sw state
* @state: atomic state
- * @stall: stall for proceeding commits
+ * @stall: stall for preceeding commits
*
* This function stores the atomic state into the current state pointers in all
* driver objects. It should be called after all failing steps have been done
* and succeeded, but before the actual hardware state is committed.
*
* For cleanup and error recovery the current state for all changed objects will
- * be swaped into @state.
+ * be swapped into @state.
*
* With that sequence it fits perfectly into the plane prepare/cleanup sequence:
*
@@ -2095,12 +2273,16 @@ EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
* the &drm_plane.state, &drm_crtc.state or &drm_connector.state pointer. With
* the current atomic helpers this is almost always the case, since the helpers
* don't pass the right state structures to the callbacks.
+ *
+ * Returns:
+ *
+ * Returns 0 on success. Can return -ERESTARTSYS when @stall is true and the
+ * waiting for the previous commits has been interrupted.
*/
-void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
+int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
bool stall)
{
- int i;
- long ret;
+ int i, ret;
struct drm_connector *connector;
struct drm_connector_state *old_conn_state, *new_conn_state;
struct drm_crtc *crtc;
@@ -2108,8 +2290,8 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
struct drm_plane *plane;
struct drm_plane_state *old_plane_state, *new_plane_state;
struct drm_crtc_commit *commit;
- void *obj, *obj_state;
- const struct drm_private_state_funcs *funcs;
+ struct drm_private_obj *obj;
+ struct drm_private_state *old_obj_state, *new_obj_state;
if (stall) {
for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
@@ -2123,12 +2305,11 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
if (!commit)
continue;
- ret = wait_for_completion_timeout(&commit->hw_done,
- 10*HZ);
- if (ret == 0)
- DRM_ERROR("[CRTC:%d:%s] hw_done timed out\n",
- crtc->base.id, crtc->name);
+ ret = wait_for_completion_interruptible(&commit->hw_done);
drm_crtc_commit_put(commit);
+
+ if (ret)
+ return ret;
}
}
@@ -2171,8 +2352,17 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
plane->state = new_plane_state;
}
- __for_each_private_obj(state, obj, obj_state, i, funcs)
- funcs->swap_state(obj, &state->private_objs[i].obj_state);
+ for_each_oldnew_private_obj_in_state(state, obj, old_obj_state, new_obj_state, i) {
+ WARN_ON(obj->state != old_obj_state);
+
+ old_obj_state->state = state;
+ new_obj_state->state = NULL;
+
+ state->private_objs[i].state = old_obj_state;
+ obj->state = new_obj_state;
+ }
+
+ return 0;
}
EXPORT_SYMBOL(drm_atomic_helper_swap_state);
@@ -2526,6 +2716,7 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
struct drm_plane *plane;
struct drm_crtc_state *crtc_state;
struct drm_crtc *crtc;
+ unsigned plane_mask = 0;
int ret, i;
state = drm_atomic_state_alloc(dev);
@@ -2556,22 +2747,26 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
goto free;
}
- for_each_connector_in_state(state, conn, conn_state, i) {
+ for_each_new_connector_in_state(state, conn, conn_state, i) {
ret = drm_atomic_set_crtc_for_connector(conn_state, NULL);
if (ret < 0)
goto free;
}
- for_each_plane_in_state(state, plane, plane_state, i) {
+ for_each_new_plane_in_state(state, plane, plane_state, i) {
ret = drm_atomic_set_crtc_for_plane(plane_state, NULL);
if (ret < 0)
goto free;
drm_atomic_set_fb_for_plane(plane_state, NULL);
+ plane_mask |= BIT(drm_plane_index(plane));
+ plane->old_fb = plane->fb;
}
ret = drm_atomic_commit(state);
free:
+ if (plane_mask)
+ drm_atomic_clean_old_fb(dev, plane_mask, ret);
drm_atomic_state_put(state);
return ret;
}
@@ -2702,11 +2897,16 @@ int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state,
struct drm_connector_state *new_conn_state;
struct drm_crtc *crtc;
struct drm_crtc_state *new_crtc_state;
+ unsigned plane_mask = 0;
+ struct drm_device *dev = state->dev;
+ int ret;
state->acquire_ctx = ctx;
- for_each_new_plane_in_state(state, plane, new_plane_state, i)
+ for_each_new_plane_in_state(state, plane, new_plane_state, i) {
+ plane_mask |= BIT(drm_plane_index(plane));
state->planes[i].old_state = plane->state;
+ }
for_each_new_crtc_in_state(state, crtc, new_crtc_state, i)
state->crtcs[i].old_state = crtc->state;
@@ -2714,7 +2914,11 @@ int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state,
for_each_new_connector_in_state(state, connector, new_conn_state, i)
state->connectors[i].old_state = connector->state;
- return drm_atomic_commit(state);
+ ret = drm_atomic_commit(state);
+ if (plane_mask)
+ drm_atomic_clean_old_fb(dev, plane_mask, ret);
+
+ return ret;
}
EXPORT_SYMBOL(drm_atomic_helper_commit_duplicated_state);
@@ -2763,177 +2967,11 @@ out:
}
EXPORT_SYMBOL(drm_atomic_helper_resume);
-/**
- * drm_atomic_helper_crtc_set_property - helper for crtc properties
- * @crtc: DRM crtc
- * @property: DRM property
- * @val: value of property
- *
- * Provides a default crtc set_property handler using the atomic driver
- * interface.
- *
- * RETURNS:
- * Zero on success, error code on failure
- */
-int
-drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc,
- struct drm_property *property,
- uint64_t val)
-{
- struct drm_atomic_state *state;
- struct drm_crtc_state *crtc_state;
- int ret = 0;
-
- state = drm_atomic_state_alloc(crtc->dev);
- if (!state)
- return -ENOMEM;
-
- /* ->set_property is always called with all locks held. */
- state->acquire_ctx = crtc->dev->mode_config.acquire_ctx;
-retry:
- crtc_state = drm_atomic_get_crtc_state(state, crtc);
- if (IS_ERR(crtc_state)) {
- ret = PTR_ERR(crtc_state);
- goto fail;
- }
-
- ret = drm_atomic_crtc_set_property(crtc, crtc_state,
- property, val);
- if (ret)
- goto fail;
-
- ret = drm_atomic_commit(state);
-fail:
- if (ret == -EDEADLK)
- goto backoff;
-
- drm_atomic_state_put(state);
- return ret;
-
-backoff:
- drm_atomic_state_clear(state);
- drm_atomic_legacy_backoff(state);
-
- goto retry;
-}
-EXPORT_SYMBOL(drm_atomic_helper_crtc_set_property);
-
-/**
- * drm_atomic_helper_plane_set_property - helper for plane properties
- * @plane: DRM plane
- * @property: DRM property
- * @val: value of property
- *
- * Provides a default plane set_property handler using the atomic driver
- * interface.
- *
- * RETURNS:
- * Zero on success, error code on failure
- */
-int
-drm_atomic_helper_plane_set_property(struct drm_plane *plane,
- struct drm_property *property,
- uint64_t val)
-{
- struct drm_atomic_state *state;
- struct drm_plane_state *plane_state;
- int ret = 0;
-
- state = drm_atomic_state_alloc(plane->dev);
- if (!state)
- return -ENOMEM;
-
- /* ->set_property is always called with all locks held. */
- state->acquire_ctx = plane->dev->mode_config.acquire_ctx;
-retry:
- plane_state = drm_atomic_get_plane_state(state, plane);
- if (IS_ERR(plane_state)) {
- ret = PTR_ERR(plane_state);
- goto fail;
- }
-
- ret = drm_atomic_plane_set_property(plane, plane_state,
- property, val);
- if (ret)
- goto fail;
-
- ret = drm_atomic_commit(state);
-fail:
- if (ret == -EDEADLK)
- goto backoff;
-
- drm_atomic_state_put(state);
- return ret;
-
-backoff:
- drm_atomic_state_clear(state);
- drm_atomic_legacy_backoff(state);
-
- goto retry;
-}
-EXPORT_SYMBOL(drm_atomic_helper_plane_set_property);
-
-/**
- * drm_atomic_helper_connector_set_property - helper for connector properties
- * @connector: DRM connector
- * @property: DRM property
- * @val: value of property
- *
- * Provides a default connector set_property handler using the atomic driver
- * interface.
- *
- * RETURNS:
- * Zero on success, error code on failure
- */
-int
-drm_atomic_helper_connector_set_property(struct drm_connector *connector,
- struct drm_property *property,
- uint64_t val)
-{
- struct drm_atomic_state *state;
- struct drm_connector_state *connector_state;
- int ret = 0;
-
- state = drm_atomic_state_alloc(connector->dev);
- if (!state)
- return -ENOMEM;
-
- /* ->set_property is always called with all locks held. */
- state->acquire_ctx = connector->dev->mode_config.acquire_ctx;
-retry:
- connector_state = drm_atomic_get_connector_state(state, connector);
- if (IS_ERR(connector_state)) {
- ret = PTR_ERR(connector_state);
- goto fail;
- }
-
- ret = drm_atomic_connector_set_property(connector, connector_state,
- property, val);
- if (ret)
- goto fail;
-
- ret = drm_atomic_commit(state);
-fail:
- if (ret == -EDEADLK)
- goto backoff;
-
- drm_atomic_state_put(state);
- return ret;
-
-backoff:
- drm_atomic_state_clear(state);
- drm_atomic_legacy_backoff(state);
-
- goto retry;
-}
-EXPORT_SYMBOL(drm_atomic_helper_connector_set_property);
-
-static int page_flip_common(
- struct drm_atomic_state *state,
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_pending_vblank_event *event,
- uint32_t flags)
+static int page_flip_common(struct drm_atomic_state *state,
+ struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ struct drm_pending_vblank_event *event,
+ uint32_t flags)
{
struct drm_plane *plane = crtc->primary;
struct drm_plane_state *plane_state;
@@ -3027,13 +3065,12 @@ EXPORT_SYMBOL(drm_atomic_helper_page_flip);
* Returns:
* Returns 0 on success, negative errno numbers on failure.
*/
-int drm_atomic_helper_page_flip_target(
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_pending_vblank_event *event,
- uint32_t flags,
- uint32_t target,
- struct drm_modeset_acquire_ctx *ctx)
+int drm_atomic_helper_page_flip_target(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ struct drm_pending_vblank_event *event,
+ uint32_t flags,
+ uint32_t target,
+ struct drm_modeset_acquire_ctx *ctx)
{
struct drm_plane *plane = crtc->primary;
struct drm_atomic_state *state;
@@ -3065,85 +3102,6 @@ fail:
EXPORT_SYMBOL(drm_atomic_helper_page_flip_target);
/**
- * drm_atomic_helper_connector_dpms() - connector dpms helper implementation
- * @connector: affected connector
- * @mode: DPMS mode
- *
- * This is the main helper function provided by the atomic helper framework for
- * implementing the legacy DPMS connector interface. It computes the new desired
- * &drm_crtc_state.active state for the corresponding CRTC (if the connector is
- * enabled) and updates it.
- *
- * Returns:
- * Returns 0 on success, negative errno numbers on failure.
- */
-int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
- int mode)
-{
- struct drm_mode_config *config = &connector->dev->mode_config;
- struct drm_atomic_state *state;
- struct drm_crtc_state *crtc_state;
- struct drm_crtc *crtc;
- struct drm_connector *tmp_connector;
- struct drm_connector_list_iter conn_iter;
- int ret;
- bool active = false;
- int old_mode = connector->dpms;
-
- if (mode != DRM_MODE_DPMS_ON)
- mode = DRM_MODE_DPMS_OFF;
-
- connector->dpms = mode;
- crtc = connector->state->crtc;
-
- if (!crtc)
- return 0;
-
- state = drm_atomic_state_alloc(connector->dev);
- if (!state)
- return -ENOMEM;
-
- state->acquire_ctx = crtc->dev->mode_config.acquire_ctx;
-retry:
- crtc_state = drm_atomic_get_crtc_state(state, crtc);
- if (IS_ERR(crtc_state)) {
- ret = PTR_ERR(crtc_state);
- goto fail;
- }
-
- WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
-
- drm_connector_list_iter_begin(connector->dev, &conn_iter);
- drm_for_each_connector_iter(tmp_connector, &conn_iter) {
- if (tmp_connector->state->crtc != crtc)
- continue;
-
- if (tmp_connector->dpms == DRM_MODE_DPMS_ON) {
- active = true;
- break;
- }
- }
- drm_connector_list_iter_end(&conn_iter);
- crtc_state->active = active;
-
- ret = drm_atomic_commit(state);
-fail:
- if (ret == -EDEADLK)
- goto backoff;
- if (ret != 0)
- connector->dpms = old_mode;
- drm_atomic_state_put(state);
- return ret;
-
-backoff:
- drm_atomic_state_clear(state);
- drm_atomic_legacy_backoff(state);
-
- goto retry;
-}
-EXPORT_SYMBOL(drm_atomic_helper_connector_dpms);
-
-/**
* drm_atomic_helper_best_encoder - Helper for
* &drm_connector_helper_funcs.best_encoder callback
* @connector: Connector control structure
@@ -3612,12 +3570,12 @@ int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
struct drm_modeset_acquire_ctx *ctx)
{
struct drm_device *dev = crtc->dev;
- struct drm_mode_config *config = &dev->mode_config;
struct drm_atomic_state *state;
struct drm_crtc_state *crtc_state;
struct drm_property_blob *blob = NULL;
struct drm_color_lut *blob_data;
int i, ret = 0;
+ bool replaced;
state = drm_atomic_state_alloc(crtc->dev);
if (!state)
@@ -3648,20 +3606,10 @@ int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
}
/* Reset DEGAMMA_LUT and CTM properties. */
- ret = drm_atomic_crtc_set_property(crtc, crtc_state,
- config->degamma_lut_property, 0);
- if (ret)
- goto fail;
-
- ret = drm_atomic_crtc_set_property(crtc, crtc_state,
- config->ctm_property, 0);
- if (ret)
- goto fail;
-
- ret = drm_atomic_crtc_set_property(crtc, crtc_state,
- config->gamma_lut_property, blob->base.id);
- if (ret)
- goto fail;
+ replaced = drm_property_replace_blob(&crtc_state->degamma_lut, NULL);
+ replaced |= drm_property_replace_blob(&crtc_state->ctm, NULL);
+ replaced |= drm_property_replace_blob(&crtc_state->gamma_lut, blob);
+ crtc_state->color_mgmt_changed |= replaced;
ret = drm_atomic_commit(state);
@@ -3671,3 +3619,18 @@ fail:
return ret;
}
EXPORT_SYMBOL(drm_atomic_helper_legacy_gamma_set);
+
+/**
+ * __drm_atomic_helper_private_duplicate_state - copy atomic private state
+ * @obj: CRTC object
+ * @state: new private object state
+ *
+ * Copies atomic state from a private objects's current state and resets inferred values.
+ * This is useful for drivers that subclass the private state.
+ */
+void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj,
+ struct drm_private_state *state)
+{
+ memcpy(state, obj->state, sizeof(*state));
+}
+EXPORT_SYMBOL(__drm_atomic_helper_private_obj_duplicate_state);
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index 3eda500..fe09827 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -128,6 +128,9 @@ EXPORT_SYMBOL(drm_color_lut_extract);
* optional. The gamma and degamma properties are only attached if
* their size is not 0 and ctm_property is only attached if has_ctm is
* true.
+ *
+ * Drivers should use drm_atomic_helper_legacy_gamma_set() to implement the
+ * legacy &drm_crtc_funcs.gamma_set callback.
*/
void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc,
uint degamma_lut_size,
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 8072e6e..ba9f36c 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -717,9 +717,9 @@ DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
* drivers, it remaps to controlling the "ACTIVE" property on the CRTC the
* connector is linked to. Drivers should never set this property directly,
* it is handled by the DRM core by calling the &drm_connector_funcs.dpms
- * callback. Atomic drivers should implement this hook using
- * drm_atomic_helper_connector_dpms(). This is the only property standard
- * connector property that userspace can change.
+ * callback. For atomic drivers the remapping to the "ACTIVE" property is
+ * implemented in the DRM core. This is the only standard connector
+ * property that userspace can change.
* PATH:
* Connector path property to identify how this sink is physically
* connected. Used by DP MST. This should be set by calling
@@ -1225,7 +1225,6 @@ int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
} else if (connector->funcs->set_property)
ret = connector->funcs->set_property(connector, property, value);
- /* store the property value if successful */
if (!ret)
drm_object_property_set_value(&connector->base, property, value);
return ret;
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 4afdf79..eab36a4 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -863,8 +863,7 @@ static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
* provided by the driver.
*
* This function is deprecated. New drivers must implement atomic modeset
- * support, for which this function is unsuitable. Instead drivers should use
- * drm_atomic_helper_connector_dpms().
+ * support, where DPMS is handled in the DRM core.
*
* Returns:
* Always returns 0.
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index d077c54..a435820 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -178,6 +178,13 @@ struct drm_minor;
int drm_atomic_debugfs_init(struct drm_minor *minor);
#endif
+int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state,
+ struct drm_connector *connector,
+ int mode);
+int drm_atomic_set_property(struct drm_atomic_state *state,
+ struct drm_mode_object *obj,
+ struct drm_property *prop,
+ uint64_t prop_value);
int drm_atomic_get_property(struct drm_mode_object *obj,
struct drm_property *property, uint64_t *val);
int drm_mode_atomic_ioctl(struct drm_device *dev,
diff --git a/drivers/gpu/drm/drm_debugfs_crc.c b/drivers/gpu/drm/drm_debugfs_crc.c
index 1722d8f..f9e26dd 100644
--- a/drivers/gpu/drm/drm_debugfs_crc.c
+++ b/drivers/gpu/drm/drm_debugfs_crc.c
@@ -136,21 +136,51 @@ static int crtc_crc_data_count(struct drm_crtc_crc *crc)
return CIRC_CNT(crc->head, crc->tail, DRM_CRC_ENTRIES_NR);
}
+static void crtc_crc_cleanup(struct drm_crtc_crc *crc)
+{
+ kfree(crc->entries);
+ crc->entries = NULL;
+ crc->head = 0;
+ crc->tail = 0;
+ crc->values_cnt = 0;
+ crc->opened = false;
+}
+
static int crtc_crc_open(struct inode *inode, struct file *filep)
{
struct drm_crtc *crtc = inode->i_private;
struct drm_crtc_crc *crc = &crtc->crc;
struct drm_crtc_crc_entry *entries = NULL;
size_t values_cnt;
- int ret;
+ int ret = 0;
- if (crc->opened)
- return -EBUSY;
+ if (drm_drv_uses_atomic_modeset(crtc->dev)) {
+ ret = drm_modeset_lock_interruptible(&crtc->mutex, NULL);
+ if (ret)
+ return ret;
+
+ if (!crtc->state->active)
+ ret = -EIO;
+ drm_modeset_unlock(&crtc->mutex);
+
+ if (ret)
+ return ret;
+ }
+
+ spin_lock_irq(&crc->lock);
+ if (!crc->opened)
+ crc->opened = true;
+ else
+ ret = -EBUSY;
+ spin_unlock_irq(&crc->lock);
- ret = crtc->funcs->set_crc_source(crtc, crc->source, &values_cnt);
if (ret)
return ret;
+ ret = crtc->funcs->set_crc_source(crtc, crc->source, &values_cnt);
+ if (ret)
+ goto err;
+
if (WARN_ON(values_cnt > DRM_MAX_CRC_NR)) {
ret = -EINVAL;
goto err_disable;
@@ -170,7 +200,6 @@ static int crtc_crc_open(struct inode *inode, struct file *filep)
spin_lock_irq(&crc->lock);
crc->entries = entries;
crc->values_cnt = values_cnt;
- crc->opened = true;
/*
* Only return once we got a first frame, so userspace doesn't have to
@@ -182,12 +211,17 @@ static int crtc_crc_open(struct inode *inode, struct file *filep)
crc->lock);
spin_unlock_irq(&crc->lock);
- WARN_ON(ret);
+ if (ret)
+ goto err_disable;
return 0;
err_disable:
crtc->funcs->set_crc_source(crtc, NULL, &values_cnt);
+err:
+ spin_lock_irq(&crc->lock);
+ crtc_crc_cleanup(crc);
+ spin_unlock_irq(&crc->lock);
return ret;
}
@@ -197,17 +231,12 @@ static int crtc_crc_release(struct inode *inode, struct file *filep)
struct drm_crtc_crc *crc = &crtc->crc;
size_t values_cnt;
+ crtc->funcs->set_crc_source(crtc, NULL, &values_cnt);
+
spin_lock_irq(&crc->lock);
- kfree(crc->entries);
- crc->entries = NULL;
- crc->head = 0;
- crc->tail = 0;
- crc->values_cnt = 0;
- crc->opened = false;
+ crtc_crc_cleanup(crc);
spin_unlock_irq(&crc->lock);
- crtc->funcs->set_crc_source(crtc, NULL, &values_cnt);
-
return 0;
}
@@ -334,7 +363,7 @@ int drm_crtc_add_crc_entry(struct drm_crtc *crtc, bool has_frame,
spin_lock(&crc->lock);
/* Caller may not have noticed yet that userspace has stopped reading */
- if (!crc->opened) {
+ if (!crc->entries) {
spin_unlock(&crc->lock);
return -EINVAL;
}
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index ae5f068..41b492f 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -31,6 +31,8 @@
#include <drm/drmP.h>
#include <drm/drm_fixed.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
/**
* DOC: dp mst helper
@@ -1342,15 +1344,17 @@ static void drm_dp_mst_link_probe_work(struct work_struct *work)
static bool drm_dp_validate_guid(struct drm_dp_mst_topology_mgr *mgr,
u8 *guid)
{
- static u8 zero_guid[16];
+ u64 salt;
- if (!memcmp(guid, zero_guid, 16)) {
- u64 salt = get_jiffies_64();
- memcpy(&guid[0], &salt, sizeof(u64));
- memcpy(&guid[8], &salt, sizeof(u64));
- return false;
- }
- return true;
+ if (memchr_inv(guid, 0, 16))
+ return true;
+
+ salt = get_jiffies_64();
+
+ memcpy(&guid[0], &salt, sizeof(u64));
+ memcpy(&guid[8], &salt, sizeof(u64));
+
+ return false;
}
#if 0
@@ -2540,8 +2544,8 @@ int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state,
int req_slots;
topology_state = drm_atomic_get_mst_topology_state(state, mgr);
- if (topology_state == NULL)
- return -ENOMEM;
+ if (IS_ERR(topology_state))
+ return PTR_ERR(topology_state);
port = drm_dp_get_validated_port_ref(mgr, port);
if (port == NULL)
@@ -2580,8 +2584,8 @@ int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
struct drm_dp_mst_topology_state *topology_state;
topology_state = drm_atomic_get_mst_topology_state(state, mgr);
- if (topology_state == NULL)
- return -ENOMEM;
+ if (IS_ERR(topology_state))
+ return PTR_ERR(topology_state);
/* We cannot rely on port->vcpi.num_slots to update
* topology_state->avail_slots as the port may not exist if the parent
@@ -3017,41 +3021,32 @@ static void drm_dp_destroy_connector_work(struct work_struct *work)
(*mgr->cbs->hotplug)(mgr);
}
-void *drm_dp_mst_duplicate_state(struct drm_atomic_state *state, void *obj)
+static struct drm_private_state *
+drm_dp_mst_duplicate_state(struct drm_private_obj *obj)
{
- struct drm_dp_mst_topology_mgr *mgr = obj;
- struct drm_dp_mst_topology_state *new_mst_state;
+ struct drm_dp_mst_topology_state *state;
- if (WARN_ON(!mgr->state))
+ state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL);
+ if (!state)
return NULL;
- new_mst_state = kmemdup(mgr->state, sizeof(*new_mst_state), GFP_KERNEL);
- if (new_mst_state)
- new_mst_state->state = state;
- return new_mst_state;
-}
-
-void drm_dp_mst_swap_state(void *obj, void **obj_state_ptr)
-{
- struct drm_dp_mst_topology_mgr *mgr = obj;
- struct drm_dp_mst_topology_state **topology_state_ptr;
-
- topology_state_ptr = (struct drm_dp_mst_topology_state **)obj_state_ptr;
+ __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base);
- mgr->state->state = (*topology_state_ptr)->state;
- swap(*topology_state_ptr, mgr->state);
- mgr->state->state = NULL;
+ return &state->base;
}
-void drm_dp_mst_destroy_state(void *obj_state)
+static void drm_dp_mst_destroy_state(struct drm_private_obj *obj,
+ struct drm_private_state *state)
{
- kfree(obj_state);
+ struct drm_dp_mst_topology_state *mst_state =
+ to_dp_mst_topology_state(state);
+
+ kfree(mst_state);
}
static const struct drm_private_state_funcs mst_state_funcs = {
- .duplicate_state = drm_dp_mst_duplicate_state,
- .swap_state = drm_dp_mst_swap_state,
- .destroy_state = drm_dp_mst_destroy_state,
+ .atomic_duplicate_state = drm_dp_mst_duplicate_state,
+ .atomic_destroy_state = drm_dp_mst_destroy_state,
};
/**
@@ -3075,8 +3070,7 @@ struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct drm_a
struct drm_device *dev = mgr->dev;
WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
- return drm_atomic_get_private_obj_state(state, mgr,
- &mst_state_funcs);
+ return to_dp_mst_topology_state(drm_atomic_get_private_obj_state(state, &mgr->base));
}
EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
@@ -3096,6 +3090,8 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
int max_dpcd_transaction_bytes,
int max_payloads, int conn_base_id)
{
+ struct drm_dp_mst_topology_state *mst_state;
+
mutex_init(&mgr->lock);
mutex_init(&mgr->qlock);
mutex_init(&mgr->payload_lock);
@@ -3124,14 +3120,18 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
if (test_calc_pbn_mode() < 0)
DRM_ERROR("MST PBN self-test failed\n");
- mgr->state = kzalloc(sizeof(*mgr->state), GFP_KERNEL);
- if (mgr->state == NULL)
+ mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
+ if (mst_state == NULL)
return -ENOMEM;
- mgr->state->mgr = mgr;
+
+ mst_state->mgr = mgr;
/* max. time slots - one slot for MTP header */
- mgr->state->avail_slots = 63;
- mgr->funcs = &mst_state_funcs;
+ mst_state->avail_slots = 63;
+
+ drm_atomic_private_obj_init(&mgr->base,
+ &mst_state->base,
+ &mst_state_funcs);
return 0;
}
@@ -3153,8 +3153,7 @@ void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr)
mutex_unlock(&mgr->payload_lock);
mgr->dev = NULL;
mgr->aux = NULL;
- kfree(mgr->state);
- mgr->state = NULL;
+ drm_atomic_private_obj_fini(&mgr->base);
mgr->funcs = NULL;
}
EXPORT_SYMBOL(drm_dp_mst_topology_mgr_destroy);
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 37b8ad3..be38ac7 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -63,6 +63,15 @@ module_param_named(debug, drm_debug, int, 0600);
static DEFINE_SPINLOCK(drm_minor_lock);
static struct idr drm_minors_idr;
+/*
+ * If the drm core fails to init for whatever reason,
+ * we should prevent any drivers from registering with it.
+ * It's best to check this at drm_dev_init(), as some drivers
+ * prefer to embed struct drm_device into their own device
+ * structure and call drm_dev_init() themselves.
+ */
+static bool drm_core_init_complete = false;
+
static struct dentry *drm_debugfs_root;
#define DRM_PRINTK_FMT "[" DRM_NAME ":%s]%s %pV"
@@ -282,7 +291,7 @@ struct drm_minor *drm_minor_acquire(unsigned int minor_id)
if (!minor) {
return ERR_PTR(-ENODEV);
- } else if (drm_device_is_unplugged(minor->dev)) {
+ } else if (drm_dev_is_unplugged(minor->dev)) {
drm_dev_unref(minor->dev);
return ERR_PTR(-ENODEV);
}
@@ -355,26 +364,32 @@ void drm_put_dev(struct drm_device *dev)
}
EXPORT_SYMBOL(drm_put_dev);
-void drm_unplug_dev(struct drm_device *dev)
+static void drm_device_set_unplugged(struct drm_device *dev)
{
- /* for a USB device */
- if (drm_core_check_feature(dev, DRIVER_MODESET))
- drm_modeset_unregister_all(dev);
+ smp_wmb();
+ atomic_set(&dev->unplugged, 1);
+}
- drm_minor_unregister(dev, DRM_MINOR_PRIMARY);
- drm_minor_unregister(dev, DRM_MINOR_RENDER);
- drm_minor_unregister(dev, DRM_MINOR_CONTROL);
+/**
+ * drm_dev_unplug - unplug a DRM device
+ * @dev: DRM device
+ *
+ * This unplugs a hotpluggable DRM device, which makes it inaccessible to
+ * userspace operations. Entry-points can use drm_dev_is_unplugged(). This
+ * essentially unregisters the device like drm_dev_unregister(), but can be
+ * called while there are still open users of @dev.
+ */
+void drm_dev_unplug(struct drm_device *dev)
+{
+ drm_dev_unregister(dev);
mutex_lock(&drm_global_mutex);
-
drm_device_set_unplugged(dev);
-
- if (dev->open_count == 0) {
- drm_put_dev(dev);
- }
+ if (dev->open_count == 0)
+ drm_dev_unref(dev);
mutex_unlock(&drm_global_mutex);
}
-EXPORT_SYMBOL(drm_unplug_dev);
+EXPORT_SYMBOL(drm_dev_unplug);
/*
* DRM internal mount
@@ -484,6 +499,11 @@ int drm_dev_init(struct drm_device *dev,
{
int ret;
+ if (!drm_core_init_complete) {
+ DRM_ERROR("DRM core is not initialized\n");
+ return -ENODEV;
+ }
+
kref_init(&dev->ref);
dev->dev = parent;
dev->driver = driver;
@@ -821,6 +841,9 @@ EXPORT_SYMBOL(drm_dev_register);
* drm_dev_register() but does not deallocate the device. The caller must call
* drm_dev_unref() to drop their final reference.
*
+ * A special form of unregistering for hotpluggable devices is drm_dev_unplug(),
+ * which can be called while there are still open users of @dev.
+ *
* This should be called first in the device teardown code to make sure
* userspace can't access the device instance any more.
*/
@@ -828,7 +851,8 @@ void drm_dev_unregister(struct drm_device *dev)
{
struct drm_map_list *r_list, *list_temp;
- drm_lastclose(dev);
+ if (drm_core_check_feature(dev, DRIVER_LEGACY))
+ drm_lastclose(dev);
dev->registered = false;
@@ -966,6 +990,8 @@ static int __init drm_core_init(void)
if (ret < 0)
goto error;
+ drm_core_init_complete = true;
+
DRM_DEBUG("Initialized\n");
return 0;
diff --git a/drivers/gpu/drm/drm_dumb_buffers.c b/drivers/gpu/drm/drm_dumb_buffers.c
index 10307cc..39ac15c 100644
--- a/drivers/gpu/drm/drm_dumb_buffers.c
+++ b/drivers/gpu/drm/drm_dumb_buffers.c
@@ -24,6 +24,7 @@
*/
#include <drm/drmP.h>
+#include <drm/drm_gem.h>
#include "drm_crtc_internal.h"
@@ -42,9 +43,10 @@
* create dumb buffers suitable for scanout, which can then be used to create
* KMS frame buffers.
*
- * To support dumb objects drivers must implement the &drm_driver.dumb_create,
- * &drm_driver.dumb_destroy and &drm_driver.dumb_map_offset operations. See
- * there for further details.
+ * To support dumb objects drivers must implement the &drm_driver.dumb_create
+ * operation. &drm_driver.dumb_destroy defaults to drm_gem_dumb_destroy() if
+ * not set and &drm_driver.dumb_map_offset defaults to
+ * drm_gem_dumb_map_offset(). See the callbacks for further details.
*
* Note that dumb objects may not be used for gpu acceleration, as has been
* attempted on some ARM embedded platforms. Such drivers really must have
@@ -108,11 +110,16 @@ int drm_mode_mmap_dumb_ioctl(struct drm_device *dev,
{
struct drm_mode_map_dumb *args = data;
- /* call driver ioctl to get mmap offset */
- if (!dev->driver->dumb_map_offset)
+ if (!dev->driver->dumb_create)
return -ENOSYS;
- return dev->driver->dumb_map_offset(file_priv, dev, args->handle, &args->offset);
+ if (dev->driver->dumb_map_offset)
+ return dev->driver->dumb_map_offset(file_priv, dev,
+ args->handle,
+ &args->offset);
+ else
+ return drm_gem_dumb_map_offset(file_priv, dev, args->handle,
+ &args->offset);
}
int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
@@ -120,9 +127,12 @@ int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
{
struct drm_mode_destroy_dumb *args = data;
- if (!dev->driver->dumb_destroy)
+ if (!dev->driver->dumb_create)
return -ENOSYS;
- return dev->driver->dumb_destroy(file_priv, dev, args->handle);
+ if (dev->driver->dumb_destroy)
+ return dev->driver->dumb_destroy(file_priv, dev, args->handle);
+ else
+ return drm_gem_dumb_destroy(file_priv, dev, args->handle);
}
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 2e55599..6bb6337 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1006,6 +1006,221 @@ static const struct drm_display_mode edid_cea_modes[] = {
2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
.vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+ /* 65 - 1280x720@24Hz */
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 59400, 1280, 3040,
+ 3080, 3300, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 66 - 1280x720@25Hz */
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3700,
+ 3740, 3960, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 67 - 1280x720@30Hz */
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3040,
+ 3080, 3300, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 68 - 1280x720@50Hz */
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1720,
+ 1760, 1980, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 69 - 1280x720@60Hz */
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
+ 1430, 1650, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 70 - 1280x720@100Hz */
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1720,
+ 1760, 1980, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 71 - 1280x720@120Hz */
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1390,
+ 1430, 1650, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 72 - 1920x1080@24Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2558,
+ 2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 73 - 1920x1080@25Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
+ 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 74 - 1920x1080@30Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
+ 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 75 - 1920x1080@50Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
+ 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 76 - 1920x1080@60Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
+ 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 77 - 1920x1080@100Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2448,
+ 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 78 - 1920x1080@120Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2008,
+ 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 79 - 1680x720@24Hz */
+ { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 59400, 1680, 3040,
+ 3080, 3300, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 80 - 1680x720@25Hz */
+ { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 59400, 1680, 2908,
+ 2948, 3168, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 81 - 1680x720@30Hz */
+ { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 59400, 1680, 2380,
+ 2420, 2640, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 82 - 1680x720@50Hz */
+ { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 82500, 1680, 1940,
+ 1980, 2200, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 83 - 1680x720@60Hz */
+ { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 99000, 1680, 1940,
+ 1980, 2200, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 84 - 1680x720@100Hz */
+ { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 165000, 1680, 1740,
+ 1780, 2000, 0, 720, 725, 730, 825, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 85 - 1680x720@120Hz */
+ { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 198000, 1680, 1740,
+ 1780, 2000, 0, 720, 725, 730, 825, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 86 - 2560x1080@24Hz */
+ { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 99000, 2560, 3558,
+ 3602, 3750, 0, 1080, 1084, 1089, 1100, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 87 - 2560x1080@25Hz */
+ { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 90000, 2560, 3008,
+ 3052, 3200, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 88 - 2560x1080@30Hz */
+ { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 118800, 2560, 3328,
+ 3372, 3520, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 89 - 2560x1080@50Hz */
+ { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 185625, 2560, 3108,
+ 3152, 3300, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 90 - 2560x1080@60Hz */
+ { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 198000, 2560, 2808,
+ 2852, 3000, 0, 1080, 1084, 1089, 1100, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 91 - 2560x1080@100Hz */
+ { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 371250, 2560, 2778,
+ 2822, 2970, 0, 1080, 1084, 1089, 1250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 92 - 2560x1080@120Hz */
+ { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 495000, 2560, 3108,
+ 3152, 3300, 0, 1080, 1084, 1089, 1250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 93 - 3840x2160p@24Hz 16:9 */
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 5116,
+ 5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+ /* 94 - 3840x2160p@25Hz 16:9 */
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4896,
+ 4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+ /* 95 - 3840x2160p@30Hz 16:9 */
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4016,
+ 4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+ /* 96 - 3840x2160p@50Hz 16:9 */
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4896,
+ 4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+ /* 97 - 3840x2160p@60Hz 16:9 */
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4016,
+ 4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+ /* 98 - 4096x2160p@24Hz 256:135 */
+ { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000, 4096, 5116,
+ 5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
+ /* 99 - 4096x2160p@25Hz 256:135 */
+ { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000, 4096, 5064,
+ 5152, 5280, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
+ /* 100 - 4096x2160p@30Hz 256:135 */
+ { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000, 4096, 4184,
+ 4272, 4400, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
+ /* 101 - 4096x2160p@50Hz 256:135 */
+ { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 594000, 4096, 5064,
+ 5152, 5280, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
+ /* 102 - 4096x2160p@60Hz 256:135 */
+ { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 594000, 4096, 4184,
+ 4272, 4400, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
+ /* 103 - 3840x2160p@24Hz 64:27 */
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 5116,
+ 5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 104 - 3840x2160p@25Hz 64:27 */
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4896,
+ 4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 105 - 3840x2160p@30Hz 64:27 */
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4016,
+ 4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 106 - 3840x2160p@50Hz 64:27 */
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4896,
+ 4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 107 - 3840x2160p@60Hz 64:27 */
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4016,
+ 4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
};
/*
@@ -2566,7 +2781,10 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid,
#define VIDEO_BLOCK 0x02
#define VENDOR_BLOCK 0x03
#define SPEAKER_BLOCK 0x04
-#define VIDEO_CAPABILITY_BLOCK 0x07
+#define USE_EXTENDED_TAG 0x07
+#define EXT_VIDEO_CAPABILITY_BLOCK 0x00
+#define EXT_VIDEO_DATA_BLOCK_420 0x0E
+#define EXT_VIDEO_CAP_BLOCK_Y420CMDB 0x0F
#define EDID_BASIC_AUDIO (1 << 6)
#define EDID_CEA_YCRCB444 (1 << 5)
#define EDID_CEA_YCRCB422 (1 << 4)
@@ -2902,6 +3120,15 @@ add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid)
return modes;
}
+static u8 svd_to_vic(u8 svd)
+{
+ /* 0-6 bit vic, 7th bit native mode indicator */
+ if ((svd >= 1 && svd <= 64) || (svd >= 129 && svd <= 192))
+ return svd & 127;
+
+ return svd;
+}
+
static struct drm_display_mode *
drm_display_mode_from_vic_index(struct drm_connector *connector,
const u8 *video_db, u8 video_len,
@@ -2915,7 +3142,7 @@ drm_display_mode_from_vic_index(struct drm_connector *connector,
return NULL;
/* CEA modes are numbered 1..127 */
- vic = (video_db[video_index] & 127);
+ vic = svd_to_vic(video_db[video_index]);
if (!drm_valid_cea_vic(vic))
return NULL;
@@ -2928,15 +3155,85 @@ drm_display_mode_from_vic_index(struct drm_connector *connector,
return newmode;
}
+/*
+ * do_y420vdb_modes - Parse YCBCR 420 only modes
+ * @connector: connector corresponding to the HDMI sink
+ * @svds: start of the data block of CEA YCBCR 420 VDB
+ * @len: length of the CEA YCBCR 420 VDB
+ *
+ * Parse the CEA-861-F YCBCR 420 Video Data Block (Y420VDB)
+ * which contains modes which can be supported in YCBCR 420
+ * output format only.
+ */
+static int do_y420vdb_modes(struct drm_connector *connector,
+ const u8 *svds, u8 svds_len)
+{
+ int modes = 0, i;
+ struct drm_device *dev = connector->dev;
+ struct drm_display_info *info = &connector->display_info;
+ struct drm_hdmi_info *hdmi = &info->hdmi;
+
+ for (i = 0; i < svds_len; i++) {
+ u8 vic = svd_to_vic(svds[i]);
+ struct drm_display_mode *newmode;
+
+ if (!drm_valid_cea_vic(vic))
+ continue;
+
+ newmode = drm_mode_duplicate(dev, &edid_cea_modes[vic]);
+ if (!newmode)
+ break;
+ bitmap_set(hdmi->y420_vdb_modes, vic, 1);
+ drm_mode_probed_add(connector, newmode);
+ modes++;
+ }
+
+ if (modes > 0)
+ info->color_formats |= DRM_COLOR_FORMAT_YCRCB420;
+ return modes;
+}
+
+/*
+ * drm_add_cmdb_modes - Add a YCBCR 420 mode into bitmap
+ * @connector: connector corresponding to the HDMI sink
+ * @vic: CEA vic for the video mode to be added in the map
+ *
+ * Makes an entry for a videomode in the YCBCR 420 bitmap
+ */
+static void
+drm_add_cmdb_modes(struct drm_connector *connector, u8 svd)
+{
+ u8 vic = svd_to_vic(svd);
+ struct drm_hdmi_info *hdmi = &connector->display_info.hdmi;
+
+ if (!drm_valid_cea_vic(vic))
+ return;
+
+ bitmap_set(hdmi->y420_cmdb_modes, vic, 1);
+}
+
static int
do_cea_modes(struct drm_connector *connector, const u8 *db, u8 len)
{
int i, modes = 0;
+ struct drm_hdmi_info *hdmi = &connector->display_info.hdmi;
for (i = 0; i < len; i++) {
struct drm_display_mode *mode;
mode = drm_display_mode_from_vic_index(connector, db, len, i);
if (mode) {
+ /*
+ * YCBCR420 capability block contains a bitmap which
+ * gives the index of CEA modes from CEA VDB, which
+ * can support YCBCR 420 sampling output also (apart
+ * from RGB/YCBCR444 etc).
+ * For example, if the bit 0 in bitmap is set,
+ * first mode in VDB can support YCBCR420 output too.
+ * Add YCBCR420 modes only if sink is HDMI 2.0 capable.
+ */
+ if (i < 64 && hdmi->y420_cmdb_map & (1ULL << i))
+ drm_add_cmdb_modes(connector, db[i]);
+
drm_mode_probed_add(connector, mode);
modes++;
}
@@ -3218,6 +3515,12 @@ cea_db_payload_len(const u8 *db)
}
static int
+cea_db_extended_tag(const u8 *db)
+{
+ return db[1];
+}
+
+static int
cea_db_tag(const u8 *db)
{
return db[0] >> 5;
@@ -3272,9 +3575,77 @@ static bool cea_db_is_hdmi_forum_vsdb(const u8 *db)
return oui == HDMI_FORUM_IEEE_OUI;
}
+static bool cea_db_is_y420cmdb(const u8 *db)
+{
+ if (cea_db_tag(db) != USE_EXTENDED_TAG)
+ return false;
+
+ if (!cea_db_payload_len(db))
+ return false;
+
+ if (cea_db_extended_tag(db) != EXT_VIDEO_CAP_BLOCK_Y420CMDB)
+ return false;
+
+ return true;
+}
+
+static bool cea_db_is_y420vdb(const u8 *db)
+{
+ if (cea_db_tag(db) != USE_EXTENDED_TAG)
+ return false;
+
+ if (!cea_db_payload_len(db))
+ return false;
+
+ if (cea_db_extended_tag(db) != EXT_VIDEO_DATA_BLOCK_420)
+ return false;
+
+ return true;
+}
+
#define for_each_cea_db(cea, i, start, end) \
for ((i) = (start); (i) < (end) && (i) + cea_db_payload_len(&(cea)[(i)]) < (end); (i) += cea_db_payload_len(&(cea)[(i)]) + 1)
+static void drm_parse_y420cmdb_bitmap(struct drm_connector *connector,
+ const u8 *db)
+{
+ struct drm_display_info *info = &connector->display_info;
+ struct drm_hdmi_info *hdmi = &info->hdmi;
+ u8 map_len = cea_db_payload_len(db) - 1;
+ u8 count;
+ u64 map = 0;
+
+ if (map_len == 0) {
+ /* All CEA modes support ycbcr420 sampling also.*/
+ hdmi->y420_cmdb_map = U64_MAX;
+ info->color_formats |= DRM_COLOR_FORMAT_YCRCB420;
+ return;
+ }
+
+ /*
+ * This map indicates which of the existing CEA block modes
+ * from VDB can support YCBCR420 output too. So if bit=0 is
+ * set, first mode from VDB can support YCBCR420 output too.
+ * We will parse and keep this map, before parsing VDB itself
+ * to avoid going through the same block again and again.
+ *
+ * Spec is not clear about max possible size of this block.
+ * Clamping max bitmap block size at 8 bytes. Every byte can
+ * address 8 CEA modes, in this way this map can address
+ * 8*8 = first 64 SVDs.
+ */
+ if (WARN_ON_ONCE(map_len > 8))
+ map_len = 8;
+
+ for (count = 0; count < map_len; count++)
+ map |= (u64)db[2 + count] << (8 * count);
+
+ if (map)
+ info->color_formats |= DRM_COLOR_FORMAT_YCRCB420;
+
+ hdmi->y420_cmdb_map = map;
+}
+
static int
add_cea_modes(struct drm_connector *connector, struct edid *edid)
{
@@ -3297,10 +3668,16 @@ add_cea_modes(struct drm_connector *connector, struct edid *edid)
video = db + 1;
video_len = dbl;
modes += do_cea_modes(connector, video, dbl);
- }
- else if (cea_db_is_hdmi_vsdb(db)) {
+ } else if (cea_db_is_hdmi_vsdb(db)) {
hdmi = db;
hdmi_len = dbl;
+ } else if (cea_db_is_y420vdb(db)) {
+ const u8 *vdb420 = &db[2];
+
+ /* Add 4:2:0(only) modes present in EDID */
+ modes += do_y420vdb_modes(connector,
+ vdb420,
+ dbl - 1);
}
}
}
@@ -3793,8 +4170,10 @@ bool drm_rgb_quant_range_selectable(struct edid *edid)
return false;
for_each_cea_db(edid_ext, i, start, end) {
- if (cea_db_tag(&edid_ext[i]) == VIDEO_CAPABILITY_BLOCK &&
- cea_db_payload_len(&edid_ext[i]) == 2) {
+ if (cea_db_tag(&edid_ext[i]) == USE_EXTENDED_TAG &&
+ cea_db_payload_len(&edid_ext[i]) == 2 &&
+ cea_db_extended_tag(&edid_ext[i]) ==
+ EXT_VIDEO_CAPABILITY_BLOCK) {
DRM_DEBUG_KMS("CEA VCDB 0x%02x\n", edid_ext[i + 2]);
return edid_ext[i + 2] & EDID_CEA_VCDB_QS;
}
@@ -3823,6 +4202,16 @@ drm_default_rgb_quant_range(const struct drm_display_mode *mode)
}
EXPORT_SYMBOL(drm_default_rgb_quant_range);
+static void drm_parse_ycbcr420_deep_color_info(struct drm_connector *connector,
+ const u8 *db)
+{
+ u8 dc_mask;
+ struct drm_hdmi_info *hdmi = &connector->display_info.hdmi;
+
+ dc_mask = db[7] & DRM_EDID_YCBCR420_DC_MASK;
+ hdmi->y420_dc_modes |= dc_mask;
+}
+
static void drm_parse_hdmi_forum_vsdb(struct drm_connector *connector,
const u8 *hf_vsdb)
{
@@ -3863,6 +4252,8 @@ static void drm_parse_hdmi_forum_vsdb(struct drm_connector *connector,
scdc->scrambling.low_rates = true;
}
}
+
+ drm_parse_ycbcr420_deep_color_info(connector, hf_vsdb);
}
static void drm_parse_hdmi_deep_color_info(struct drm_connector *connector,
@@ -3981,6 +4372,8 @@ static void drm_parse_cea_ext(struct drm_connector *connector,
drm_parse_hdmi_vsdb_video(connector, db);
if (cea_db_is_hdmi_forum_vsdb(db))
drm_parse_hdmi_forum_vsdb(connector, db);
+ if (cea_db_is_y420cmdb(db))
+ drm_parse_y420cmdb_bitmap(connector, db);
}
}
@@ -4215,6 +4608,13 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
quirks = edid_get_quirks(edid);
/*
+ * CEA-861-F adds ycbcr capability map block, for HDMI 2.0 sinks.
+ * To avoid multiple parsing of same block, lets parse that map
+ * from sink info, before parsing CEA modes.
+ */
+ drm_add_display_info(connector, edid);
+
+ /*
* EDID spec says modes should be preferred in this order:
* - preferred detailed mode
* - other detailed modes from base block
@@ -4241,8 +4641,6 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75))
edid_fixup_preferred(connector, quirks);
- drm_add_display_info(connector, edid);
-
if (quirks & EDID_QUIRK_FORCE_6BPC)
connector->display_info.bpc = 6;
@@ -4334,12 +4732,14 @@ EXPORT_SYMBOL(drm_set_preferred_mode);
* data from a DRM display mode
* @frame: HDMI AVI infoframe
* @mode: DRM display mode
+ * @is_hdmi2_sink: Sink is HDMI 2.0 compliant
*
* Return: 0 on success or a negative error code on failure.
*/
int
drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
- const struct drm_display_mode *mode)
+ const struct drm_display_mode *mode,
+ bool is_hdmi2_sink)
{
int err;
@@ -4355,6 +4755,28 @@ drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
frame->video_code = drm_match_cea_mode(mode);
+ /*
+ * HDMI 1.4 VIC range: 1 <= VIC <= 64 (CEA-861-D) but
+ * HDMI 2.0 VIC range: 1 <= VIC <= 107 (CEA-861-F). So we
+ * have to make sure we dont break HDMI 1.4 sinks.
+ */
+ if (!is_hdmi2_sink && frame->video_code > 64)
+ frame->video_code = 0;
+
+ /*
+ * HDMI spec says if a mode is found in HDMI 1.4b 4K modes
+ * we should send its VIC in vendor infoframes, else send the
+ * VIC in AVI infoframes. Lets check if this mode is present in
+ * HDMI 1.4b 4K modes
+ */
+ if (frame->video_code) {
+ u8 vendor_if_vic = drm_match_hdmi_mode(mode);
+ bool is_s3d = mode->flags & DRM_MODE_FLAG_3D_MASK;
+
+ if (drm_valid_hdmi_vic(vendor_if_vic) && !is_s3d)
+ frame->video_code = 0;
+ }
+
frame->picture_aspect = HDMI_PICTURE_ASPECT_NONE;
/*
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c
index 53f9bdf..f2ee883 100644
--- a/drivers/gpu/drm/drm_fb_cma_helper.c
+++ b/drivers/gpu/drm/drm_fb_cma_helper.c
@@ -18,27 +18,17 @@
*/
#include <drm/drmP.h>
-#include <drm/drm_atomic.h>
-#include <drm/drm_crtc.h>
#include <drm/drm_fb_helper.h>
-#include <drm/drm_crtc_helper.h>
+#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_fb_cma_helper.h>
-#include <linux/dma-buf.h>
-#include <linux/dma-mapping.h>
#include <linux/module.h>
-#include <linux/reservation.h>
#define DEFAULT_FBDEFIO_DELAY_MS 50
-struct drm_fb_cma {
- struct drm_framebuffer fb;
- struct drm_gem_cma_object *obj[4];
-};
-
struct drm_fbdev_cma {
struct drm_fb_helper fb_helper;
- struct drm_fb_cma *fb;
const struct drm_framebuffer_funcs *fb_funcs;
};
@@ -90,69 +80,19 @@ static inline struct drm_fbdev_cma *to_fbdev_cma(struct drm_fb_helper *helper)
return container_of(helper, struct drm_fbdev_cma, fb_helper);
}
-static inline struct drm_fb_cma *to_fb_cma(struct drm_framebuffer *fb)
-{
- return container_of(fb, struct drm_fb_cma, fb);
-}
-
void drm_fb_cma_destroy(struct drm_framebuffer *fb)
{
- struct drm_fb_cma *fb_cma = to_fb_cma(fb);
- int i;
-
- for (i = 0; i < 4; i++) {
- if (fb_cma->obj[i])
- drm_gem_object_put_unlocked(&fb_cma->obj[i]->base);
- }
-
- drm_framebuffer_cleanup(fb);
- kfree(fb_cma);
+ drm_gem_fb_destroy(fb);
}
EXPORT_SYMBOL(drm_fb_cma_destroy);
int drm_fb_cma_create_handle(struct drm_framebuffer *fb,
struct drm_file *file_priv, unsigned int *handle)
{
- struct drm_fb_cma *fb_cma = to_fb_cma(fb);
-
- return drm_gem_handle_create(file_priv,
- &fb_cma->obj[0]->base, handle);
+ return drm_gem_fb_create_handle(fb, file_priv, handle);
}
EXPORT_SYMBOL(drm_fb_cma_create_handle);
-static struct drm_framebuffer_funcs drm_fb_cma_funcs = {
- .destroy = drm_fb_cma_destroy,
- .create_handle = drm_fb_cma_create_handle,
-};
-
-static struct drm_fb_cma *drm_fb_cma_alloc(struct drm_device *dev,
- const struct drm_mode_fb_cmd2 *mode_cmd,
- struct drm_gem_cma_object **obj,
- unsigned int num_planes, const struct drm_framebuffer_funcs *funcs)
-{
- struct drm_fb_cma *fb_cma;
- int ret;
- int i;
-
- fb_cma = kzalloc(sizeof(*fb_cma), GFP_KERNEL);
- if (!fb_cma)
- return ERR_PTR(-ENOMEM);
-
- drm_helper_mode_fill_fb_struct(dev, &fb_cma->fb, mode_cmd);
-
- for (i = 0; i < num_planes; i++)
- fb_cma->obj[i] = obj[i];
-
- ret = drm_framebuffer_init(dev, &fb_cma->fb, funcs);
- if (ret) {
- dev_err(dev->dev, "Failed to initialize framebuffer: %d\n", ret);
- kfree(fb_cma);
- return ERR_PTR(ret);
- }
-
- return fb_cma;
-}
-
/**
* drm_fb_cma_create_with_funcs() - helper function for the
* &drm_mode_config_funcs.fb_create
@@ -170,53 +110,7 @@ struct drm_framebuffer *drm_fb_cma_create_with_funcs(struct drm_device *dev,
struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd,
const struct drm_framebuffer_funcs *funcs)
{
- const struct drm_format_info *info;
- struct drm_fb_cma *fb_cma;
- struct drm_gem_cma_object *objs[4];
- struct drm_gem_object *obj;
- int ret;
- int i;
-
- info = drm_get_format_info(dev, mode_cmd);
- if (!info)
- return ERR_PTR(-EINVAL);
-
- for (i = 0; i < info->num_planes; i++) {
- unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
- unsigned int height = mode_cmd->height / (i ? info->vsub : 1);
- unsigned int min_size;
-
- obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]);
- if (!obj) {
- dev_err(dev->dev, "Failed to lookup GEM object\n");
- ret = -ENOENT;
- goto err_gem_object_put;
- }
-
- min_size = (height - 1) * mode_cmd->pitches[i]
- + width * info->cpp[i]
- + mode_cmd->offsets[i];
-
- if (obj->size < min_size) {
- drm_gem_object_put_unlocked(obj);
- ret = -EINVAL;
- goto err_gem_object_put;
- }
- objs[i] = to_drm_gem_cma_obj(obj);
- }
-
- fb_cma = drm_fb_cma_alloc(dev, mode_cmd, objs, i, funcs);
- if (IS_ERR(fb_cma)) {
- ret = PTR_ERR(fb_cma);
- goto err_gem_object_put;
- }
-
- return &fb_cma->fb;
-
-err_gem_object_put:
- for (i--; i >= 0; i--)
- drm_gem_object_put_unlocked(&objs[i]->base);
- return ERR_PTR(ret);
+ return drm_gem_fb_create_with_funcs(dev, file_priv, mode_cmd, funcs);
}
EXPORT_SYMBOL_GPL(drm_fb_cma_create_with_funcs);
@@ -233,8 +127,7 @@ EXPORT_SYMBOL_GPL(drm_fb_cma_create_with_funcs);
struct drm_framebuffer *drm_fb_cma_create(struct drm_device *dev,
struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd)
{
- return drm_fb_cma_create_with_funcs(dev, file_priv, mode_cmd,
- &drm_fb_cma_funcs);
+ return drm_gem_fb_create(dev, file_priv, mode_cmd);
}
EXPORT_SYMBOL_GPL(drm_fb_cma_create);
@@ -250,12 +143,13 @@ EXPORT_SYMBOL_GPL(drm_fb_cma_create);
struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct drm_framebuffer *fb,
unsigned int plane)
{
- struct drm_fb_cma *fb_cma = to_fb_cma(fb);
+ struct drm_gem_object *gem;
- if (plane >= 4)
+ gem = drm_gem_fb_get_obj(fb, plane);
+ if (!gem)
return NULL;
- return fb_cma->obj[plane];
+ return to_drm_gem_cma_obj(gem);
}
EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_obj);
@@ -272,13 +166,14 @@ dma_addr_t drm_fb_cma_get_gem_addr(struct drm_framebuffer *fb,
struct drm_plane_state *state,
unsigned int plane)
{
- struct drm_fb_cma *fb_cma = to_fb_cma(fb);
+ struct drm_gem_cma_object *obj;
dma_addr_t paddr;
- if (plane >= 4)
+ obj = drm_fb_cma_get_gem_obj(fb, plane);
+ if (!obj)
return 0;
- paddr = fb_cma->obj[plane]->paddr + fb->offsets[plane];
+ paddr = obj->paddr + fb->offsets[plane];
paddr += fb->format->cpp[plane] * (state->src_x >> 16);
paddr += fb->pitches[plane] * (state->src_y >> 16);
@@ -302,26 +197,13 @@ EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_addr);
int drm_fb_cma_prepare_fb(struct drm_plane *plane,
struct drm_plane_state *state)
{
- struct dma_buf *dma_buf;
- struct dma_fence *fence;
-
- if ((plane->state->fb == state->fb) || !state->fb)
- return 0;
-
- dma_buf = drm_fb_cma_get_gem_obj(state->fb, 0)->base.dma_buf;
- if (dma_buf) {
- fence = reservation_object_get_excl_rcu(dma_buf->resv);
- drm_atomic_set_fence_for_plane(state, fence);
- }
-
- return 0;
+ return drm_gem_fb_prepare_fb(plane, state);
}
EXPORT_SYMBOL_GPL(drm_fb_cma_prepare_fb);
#ifdef CONFIG_DEBUG_FS
static void drm_fb_cma_describe(struct drm_framebuffer *fb, struct seq_file *m)
{
- struct drm_fb_cma *fb_cma = to_fb_cma(fb);
int i;
seq_printf(m, "fb: %dx%d@%4.4s\n", fb->width, fb->height,
@@ -330,7 +212,7 @@ static void drm_fb_cma_describe(struct drm_framebuffer *fb, struct seq_file *m)
for (i = 0; i < fb->format->num_planes; i++) {
seq_printf(m, " %d: offset=%d pitch=%d, obj: ",
i, fb->offsets[i], fb->pitches[i]);
- drm_gem_cma_describe(fb_cma->obj[i], m);
+ drm_gem_cma_describe(drm_fb_cma_get_gem_obj(fb, i), m);
}
}
@@ -431,7 +313,6 @@ drm_fbdev_cma_create(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes)
{
struct drm_fbdev_cma *fbdev_cma = to_fbdev_cma(helper);
- struct drm_mode_fb_cmd2 mode_cmd = { 0 };
struct drm_device *dev = helper->dev;
struct drm_gem_cma_object *obj;
struct drm_framebuffer *fb;
@@ -446,14 +327,7 @@ drm_fbdev_cma_create(struct drm_fb_helper *helper,
sizes->surface_bpp);
bytes_per_pixel = DIV_ROUND_UP(sizes->surface_bpp, 8);
-
- mode_cmd.width = sizes->surface_width;
- mode_cmd.height = sizes->surface_height;
- mode_cmd.pitches[0] = sizes->surface_width * bytes_per_pixel;
- mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
- sizes->surface_depth);
-
- size = mode_cmd.pitches[0] * mode_cmd.height;
+ size = sizes->surface_width * sizes->surface_height * bytes_per_pixel;
obj = drm_gem_cma_create(dev, size);
if (IS_ERR(obj))
return -ENOMEM;
@@ -464,15 +338,14 @@ drm_fbdev_cma_create(struct drm_fb_helper *helper,
goto err_gem_free_object;
}
- fbdev_cma->fb = drm_fb_cma_alloc(dev, &mode_cmd, &obj, 1,
- fbdev_cma->fb_funcs);
- if (IS_ERR(fbdev_cma->fb)) {
+ fb = drm_gem_fbdev_fb_create(dev, sizes, 0, &obj->base,
+ fbdev_cma->fb_funcs);
+ if (IS_ERR(fb)) {
dev_err(dev->dev, "Failed to allocate DRM framebuffer.\n");
- ret = PTR_ERR(fbdev_cma->fb);
+ ret = PTR_ERR(fb);
goto err_fb_info_destroy;
}
- fb = &fbdev_cma->fb->fb;
helper->fb = fb;
fbi->par = helper;
@@ -500,7 +373,7 @@ drm_fbdev_cma_create(struct drm_fb_helper *helper,
return 0;
err_cma_destroy:
- drm_framebuffer_remove(&fbdev_cma->fb->fb);
+ drm_framebuffer_remove(fb);
err_fb_info_destroy:
drm_fb_helper_fini(helper);
err_gem_free_object:
@@ -570,6 +443,11 @@ err_free:
}
EXPORT_SYMBOL_GPL(drm_fbdev_cma_init_with_funcs);
+static const struct drm_framebuffer_funcs drm_fb_cma_funcs = {
+ .destroy = drm_gem_fb_destroy,
+ .create_handle = drm_gem_fb_create_handle,
+};
+
/**
* drm_fbdev_cma_init() - Allocate and initializes a drm_fbdev_cma struct
* @dev: DRM device
@@ -597,8 +475,8 @@ void drm_fbdev_cma_fini(struct drm_fbdev_cma *fbdev_cma)
if (fbdev_cma->fb_helper.fbdev)
drm_fbdev_cma_defio_fini(fbdev_cma->fb_helper.fbdev);
- if (fbdev_cma->fb)
- drm_framebuffer_remove(&fbdev_cma->fb->fb);
+ if (fbdev_cma->fb_helper.fb)
+ drm_framebuffer_remove(fbdev_cma->fb_helper.fb);
drm_fb_helper_fini(&fbdev_cma->fb_helper);
kfree(fbdev_cma);
@@ -640,7 +518,7 @@ EXPORT_SYMBOL_GPL(drm_fbdev_cma_hotplug_event);
* Calls drm_fb_helper_set_suspend, which is a wrapper around
* fb_set_suspend implemented by fbdev core.
*/
-void drm_fbdev_cma_set_suspend(struct drm_fbdev_cma *fbdev_cma, int state)
+void drm_fbdev_cma_set_suspend(struct drm_fbdev_cma *fbdev_cma, bool state)
{
if (fbdev_cma)
drm_fb_helper_set_suspend(&fbdev_cma->fb_helper, state);
@@ -657,7 +535,7 @@ EXPORT_SYMBOL(drm_fbdev_cma_set_suspend);
* fb_set_suspend implemented by fbdev core.
*/
void drm_fbdev_cma_set_suspend_unlocked(struct drm_fbdev_cma *fbdev_cma,
- int state)
+ bool state)
{
if (fbdev_cma)
drm_fb_helper_set_suspend_unlocked(&fbdev_cma->fb_helper,
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 574af01..1b8f013 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -106,11 +106,11 @@ static DEFINE_MUTEX(kernel_fb_helper_lock);
*/
#define drm_fb_helper_for_each_connector(fbh, i__) \
- for (({ lockdep_assert_held(&(fbh)->dev->mode_config.mutex); }), \
+ for (({ lockdep_assert_held(&(fbh)->lock); }), \
i__ = 0; i__ < (fbh)->connector_count; i__++)
-int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper,
- struct drm_connector *connector)
+static int __drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper,
+ struct drm_connector *connector)
{
struct drm_fb_helper_connector *fb_conn;
struct drm_fb_helper_connector **temp;
@@ -119,7 +119,7 @@ int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper,
if (!drm_fbdev_emulation)
return 0;
- WARN_ON(!mutex_is_locked(&fb_helper->dev->mode_config.mutex));
+ lockdep_assert_held(&fb_helper->lock);
count = fb_helper->connector_count + 1;
@@ -141,8 +141,21 @@ int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper,
drm_connector_get(connector);
fb_conn->connector = connector;
fb_helper->connector_info[fb_helper->connector_count++] = fb_conn;
+
return 0;
}
+
+int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper,
+ struct drm_connector *connector)
+{
+ int err;
+
+ mutex_lock(&fb_helper->lock);
+ err = __drm_fb_helper_add_one_connector(fb_helper, connector);
+ mutex_unlock(&fb_helper->lock);
+
+ return err;
+}
EXPORT_SYMBOL(drm_fb_helper_add_one_connector);
/**
@@ -169,11 +182,10 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
if (!drm_fbdev_emulation)
return 0;
- mutex_lock(&dev->mode_config.mutex);
+ mutex_lock(&fb_helper->lock);
drm_connector_list_iter_begin(dev, &conn_iter);
drm_for_each_connector_iter(connector, &conn_iter) {
- ret = drm_fb_helper_add_one_connector(fb_helper, connector);
-
+ ret = __drm_fb_helper_add_one_connector(fb_helper, connector);
if (ret)
goto fail;
}
@@ -192,14 +204,14 @@ fail:
fb_helper->connector_count = 0;
out:
drm_connector_list_iter_end(&conn_iter);
- mutex_unlock(&dev->mode_config.mutex);
+ mutex_unlock(&fb_helper->lock);
return ret;
}
EXPORT_SYMBOL(drm_fb_helper_single_add_all_connectors);
-int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
- struct drm_connector *connector)
+static int __drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
+ struct drm_connector *connector)
{
struct drm_fb_helper_connector *fb_helper_connector;
int i, j;
@@ -207,9 +219,9 @@ int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
if (!drm_fbdev_emulation)
return 0;
- WARN_ON(!mutex_is_locked(&fb_helper->dev->mode_config.mutex));
+ lockdep_assert_held(&fb_helper->lock);
- for (i = 0; i < fb_helper->connector_count; i++) {
+ drm_fb_helper_for_each_connector(fb_helper, i) {
if (fb_helper->connector_info[i]->connector == connector)
break;
}
@@ -227,23 +239,19 @@ int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
return 0;
}
-EXPORT_SYMBOL(drm_fb_helper_remove_one_connector);
-static void drm_fb_helper_save_lut_atomic(struct drm_crtc *crtc, struct drm_fb_helper *helper)
+int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
+ struct drm_connector *connector)
{
- uint16_t *r_base, *g_base, *b_base;
- int i;
-
- if (helper->funcs->gamma_get == NULL)
- return;
+ int err;
- r_base = crtc->gamma_store;
- g_base = r_base + crtc->gamma_size;
- b_base = g_base + crtc->gamma_size;
+ mutex_lock(&fb_helper->lock);
+ err = __drm_fb_helper_remove_one_connector(fb_helper, connector);
+ mutex_unlock(&fb_helper->lock);
- for (i = 0; i < crtc->gamma_size; i++)
- helper->funcs->gamma_get(crtc, &r_base[i], &g_base[i], &b_base[i], i);
+ return err;
}
+EXPORT_SYMBOL(drm_fb_helper_remove_one_connector);
static void drm_fb_helper_restore_lut_atomic(struct drm_crtc *crtc)
{
@@ -285,7 +293,6 @@ int drm_fb_helper_debug_enter(struct fb_info *info)
if (drm_drv_uses_atomic_modeset(mode_set->crtc->dev))
continue;
- drm_fb_helper_save_lut_atomic(mode_set->crtc, helper);
funcs->mode_set_base_atomic(mode_set->crtc,
mode_set->fb,
mode_set->x,
@@ -298,20 +305,6 @@ int drm_fb_helper_debug_enter(struct fb_info *info)
}
EXPORT_SYMBOL(drm_fb_helper_debug_enter);
-/* Find the real fb for a given fb helper CRTC */
-static struct drm_framebuffer *drm_mode_config_fb(struct drm_crtc *crtc)
-{
- struct drm_device *dev = crtc->dev;
- struct drm_crtc *c;
-
- drm_for_each_crtc(c, dev) {
- if (crtc->base.id == c->base.id)
- return c->primary->fb;
- }
-
- return NULL;
-}
-
/**
* drm_fb_helper_debug_leave - implementation for &fb_ops.fb_debug_leave
* @info: fbdev registered by the helper
@@ -328,8 +321,11 @@ int drm_fb_helper_debug_leave(struct fb_info *info)
struct drm_mode_set *mode_set = &helper->crtc_info[i].mode_set;
crtc = mode_set->crtc;
+ if (drm_drv_uses_atomic_modeset(crtc->dev))
+ continue;
+
funcs = crtc->helper_private;
- fb = drm_mode_config_fb(crtc);
+ fb = crtc->primary->fb;
if (!crtc->enabled)
continue;
@@ -342,9 +338,6 @@ int drm_fb_helper_debug_leave(struct fb_info *info)
if (funcs->mode_set_base_atomic == NULL)
continue;
- if (drm_drv_uses_atomic_modeset(crtc->dev))
- continue;
-
drm_fb_helper_restore_lut_atomic(mode_set->crtc);
funcs->mode_set_base_atomic(mode_set->crtc, fb, crtc->x,
crtc->y, LEAVE_ATOMIC_MODE_SET);
@@ -354,19 +347,24 @@ int drm_fb_helper_debug_leave(struct fb_info *info)
}
EXPORT_SYMBOL(drm_fb_helper_debug_leave);
-static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper)
+static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool active)
{
struct drm_device *dev = fb_helper->dev;
struct drm_plane *plane;
struct drm_atomic_state *state;
int i, ret;
unsigned int plane_mask;
+ struct drm_modeset_acquire_ctx ctx;
+
+ drm_modeset_acquire_init(&ctx, 0);
state = drm_atomic_state_alloc(dev);
- if (!state)
- return -ENOMEM;
+ if (!state) {
+ ret = -ENOMEM;
+ goto out_ctx;
+ }
- state->acquire_ctx = dev->mode_config.acquire_ctx;
+ state->acquire_ctx = &ctx;
retry:
plane_mask = 0;
drm_for_each_plane(plane, dev) {
@@ -375,7 +373,7 @@ retry:
plane_state = drm_atomic_get_plane_state(state, plane);
if (IS_ERR(plane_state)) {
ret = PTR_ERR(plane_state);
- goto fail;
+ goto out_state;
}
plane_state->rotation = DRM_MODE_ROTATE_0;
@@ -389,7 +387,7 @@ retry:
ret = __drm_atomic_helper_disable_plane(plane, plane_state);
if (ret != 0)
- goto fail;
+ goto out_state;
}
for (i = 0; i < fb_helper->crtc_count; i++) {
@@ -397,23 +395,38 @@ retry:
ret = __drm_atomic_helper_set_config(mode_set, state);
if (ret != 0)
- goto fail;
+ goto out_state;
+
+ /*
+ * __drm_atomic_helper_set_config() sets active when a
+ * mode is set, unconditionally clear it if we force DPMS off
+ */
+ if (!active) {
+ struct drm_crtc *crtc = mode_set->crtc;
+ struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+
+ crtc_state->active = false;
+ }
}
ret = drm_atomic_commit(state);
-fail:
+out_state:
drm_atomic_clean_old_fb(dev, plane_mask, ret);
if (ret == -EDEADLK)
goto backoff;
drm_atomic_state_put(state);
+out_ctx:
+ drm_modeset_drop_locks(&ctx);
+ drm_modeset_acquire_fini(&ctx);
+
return ret;
backoff:
drm_atomic_state_clear(state);
- drm_atomic_legacy_backoff(state);
+ drm_modeset_backoff(&ctx);
goto retry;
}
@@ -422,8 +435,9 @@ static int restore_fbdev_mode_legacy(struct drm_fb_helper *fb_helper)
{
struct drm_device *dev = fb_helper->dev;
struct drm_plane *plane;
- int i;
+ int i, ret = 0;
+ drm_modeset_lock_all(fb_helper->dev);
drm_for_each_plane(plane, dev) {
if (plane->type != DRM_PLANE_TYPE_PRIMARY)
drm_plane_force_disable(plane);
@@ -437,34 +451,33 @@ static int restore_fbdev_mode_legacy(struct drm_fb_helper *fb_helper)
for (i = 0; i < fb_helper->crtc_count; i++) {
struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set;
struct drm_crtc *crtc = mode_set->crtc;
- int ret;
if (crtc->funcs->cursor_set2) {
ret = crtc->funcs->cursor_set2(crtc, NULL, 0, 0, 0, 0, 0);
if (ret)
- return ret;
+ goto out;
} else if (crtc->funcs->cursor_set) {
ret = crtc->funcs->cursor_set(crtc, NULL, 0, 0, 0);
if (ret)
- return ret;
+ goto out;
}
ret = drm_mode_set_config_internal(mode_set);
if (ret)
- return ret;
+ goto out;
}
+out:
+ drm_modeset_unlock_all(fb_helper->dev);
- return 0;
+ return ret;
}
static int restore_fbdev_mode(struct drm_fb_helper *fb_helper)
{
struct drm_device *dev = fb_helper->dev;
- drm_warn_on_modeset_not_all_locked(dev);
-
if (drm_drv_uses_atomic_modeset(dev))
- return restore_fbdev_mode_atomic(fb_helper);
+ return restore_fbdev_mode_atomic(fb_helper, true);
else
return restore_fbdev_mode_legacy(fb_helper);
}
@@ -482,23 +495,26 @@ static int restore_fbdev_mode(struct drm_fb_helper *fb_helper)
*/
int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper)
{
- struct drm_device *dev = fb_helper->dev;
bool do_delayed;
int ret;
if (!drm_fbdev_emulation)
return -ENODEV;
- drm_modeset_lock_all(dev);
+ if (READ_ONCE(fb_helper->deferred_setup))
+ return 0;
+
+ mutex_lock(&fb_helper->lock);
ret = restore_fbdev_mode(fb_helper);
do_delayed = fb_helper->delayed_hotplug;
if (do_delayed)
fb_helper->delayed_hotplug = false;
- drm_modeset_unlock_all(dev);
+ mutex_unlock(&fb_helper->lock);
if (do_delayed)
drm_fb_helper_hotplug_event(fb_helper);
+
return ret;
}
EXPORT_SYMBOL(drm_fb_helper_restore_fbdev_mode_unlocked);
@@ -517,10 +533,12 @@ static bool drm_fb_helper_is_bound(struct drm_fb_helper *fb_helper)
return false;
drm_for_each_crtc(crtc, dev) {
+ drm_modeset_lock(&crtc->mutex, NULL);
if (crtc->primary->fb)
crtcs_bound++;
if (crtc->primary->fb == fb_helper->fb)
bound++;
+ drm_modeset_unlock(&crtc->mutex);
}
if (bound < crtcs_bound)
@@ -548,11 +566,11 @@ static bool drm_fb_helper_force_kernel_mode(void)
if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
continue;
- drm_modeset_lock_all(dev);
+ mutex_lock(&helper->lock);
ret = restore_fbdev_mode(helper);
if (ret)
error = true;
- drm_modeset_unlock_all(dev);
+ mutex_unlock(&helper->lock);
}
return error;
}
@@ -581,23 +599,14 @@ static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = {
static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { };
#endif
-static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
+static void dpms_legacy(struct drm_fb_helper *fb_helper, int dpms_mode)
{
- struct drm_fb_helper *fb_helper = info->par;
struct drm_device *dev = fb_helper->dev;
struct drm_crtc *crtc;
struct drm_connector *connector;
int i, j;
- /*
- * For each CRTC in this fb, turn the connectors on/off.
- */
drm_modeset_lock_all(dev);
- if (!drm_fb_helper_is_bound(fb_helper)) {
- drm_modeset_unlock_all(dev);
- return;
- }
-
for (i = 0; i < fb_helper->crtc_count; i++) {
crtc = fb_helper->crtc_info[i].mode_set.crtc;
@@ -615,6 +624,26 @@ static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
drm_modeset_unlock_all(dev);
}
+static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
+{
+ struct drm_fb_helper *fb_helper = info->par;
+
+ /*
+ * For each CRTC in this fb, turn the connectors on/off.
+ */
+ mutex_lock(&fb_helper->lock);
+ if (!drm_fb_helper_is_bound(fb_helper)) {
+ mutex_unlock(&fb_helper->lock);
+ return;
+ }
+
+ if (drm_drv_uses_atomic_modeset(fb_helper->dev))
+ restore_fbdev_mode_atomic(fb_helper, dpms_mode == DRM_MODE_DPMS_ON);
+ else
+ dpms_legacy(fb_helper, dpms_mode);
+ mutex_unlock(&fb_helper->lock);
+}
+
/**
* drm_fb_helper_blank - implementation for &fb_ops.fb_blank
* @blank: desired blanking state
@@ -734,6 +763,7 @@ void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
INIT_WORK(&helper->resume_work, drm_fb_helper_resume_worker);
INIT_WORK(&helper->dirty_work, drm_fb_helper_dirty_work);
helper->dirty_clip.x1 = helper->dirty_clip.y1 = ~0;
+ mutex_init(&helper->lock);
helper->funcs = funcs;
helper->dev = dev;
}
@@ -899,6 +929,7 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
}
mutex_unlock(&kernel_fb_helper_lock);
+ mutex_destroy(&fb_helper->lock);
drm_fb_helper_crtc_free(fb_helper);
}
@@ -1167,22 +1198,23 @@ void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper,
}
EXPORT_SYMBOL(drm_fb_helper_set_suspend_unlocked);
-static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, u16 regno, struct fb_info *info)
+static int setcmap_pseudo_palette(struct fb_cmap *cmap, struct fb_info *info)
{
- struct drm_fb_helper *fb_helper = info->par;
- struct drm_framebuffer *fb = fb_helper->fb;
+ u32 *palette = (u32 *)info->pseudo_palette;
+ int i;
- if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
- u32 *palette;
+ if (cmap->start + cmap->len > 16)
+ return -EINVAL;
+
+ for (i = 0; i < cmap->len; ++i) {
+ u16 red = cmap->red[i];
+ u16 green = cmap->green[i];
+ u16 blue = cmap->blue[i];
u32 value;
- /* place color in psuedopalette */
- if (regno > 16)
- return -EINVAL;
- palette = (u32 *)info->pseudo_palette;
- red >>= (16 - info->var.red.length);
- green >>= (16 - info->var.green.length);
- blue >>= (16 - info->var.blue.length);
+
+ red >>= 16 - info->var.red.length;
+ green >>= 16 - info->var.green.length;
+ blue >>= 16 - info->var.blue.length;
value = (red << info->var.red.offset) |
(green << info->var.green.offset) |
(blue << info->var.blue.offset);
@@ -1192,23 +1224,169 @@ static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green,
mask <<= info->var.transp.offset;
value |= mask;
}
- palette[regno] = value;
- return 0;
+ palette[cmap->start + i] = value;
}
- /*
- * The driver really shouldn't advertise pseudo/directcolor
- * visuals if it can't deal with the palette.
- */
- if (WARN_ON(!fb_helper->funcs->gamma_set ||
- !fb_helper->funcs->gamma_get))
- return -EINVAL;
+ return 0;
+}
+
+static int setcmap_legacy(struct fb_cmap *cmap, struct fb_info *info)
+{
+ struct drm_fb_helper *fb_helper = info->par;
+ struct drm_crtc *crtc;
+ u16 *r, *g, *b;
+ int i, ret = 0;
- WARN_ON(fb->format->cpp[0] != 1);
+ drm_modeset_lock_all(fb_helper->dev);
+ for (i = 0; i < fb_helper->crtc_count; i++) {
+ crtc = fb_helper->crtc_info[i].mode_set.crtc;
+ if (!crtc->funcs->gamma_set || !crtc->gamma_size)
+ return -EINVAL;
- fb_helper->funcs->gamma_set(crtc, red, green, blue, regno);
+ if (cmap->start + cmap->len > crtc->gamma_size)
+ return -EINVAL;
- return 0;
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
+
+ memcpy(r + cmap->start, cmap->red, cmap->len * sizeof(*r));
+ memcpy(g + cmap->start, cmap->green, cmap->len * sizeof(*g));
+ memcpy(b + cmap->start, cmap->blue, cmap->len * sizeof(*b));
+
+ ret = crtc->funcs->gamma_set(crtc, r, g, b,
+ crtc->gamma_size, NULL);
+ if (ret)
+ return ret;
+ }
+ drm_modeset_unlock_all(fb_helper->dev);
+
+ return ret;
+}
+
+static struct drm_property_blob *setcmap_new_gamma_lut(struct drm_crtc *crtc,
+ struct fb_cmap *cmap)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_property_blob *gamma_lut;
+ struct drm_color_lut *lut;
+ int size = crtc->gamma_size;
+ int i;
+
+ if (!size || cmap->start + cmap->len > size)
+ return ERR_PTR(-EINVAL);
+
+ gamma_lut = drm_property_create_blob(dev, sizeof(*lut) * size, NULL);
+ if (IS_ERR(gamma_lut))
+ return gamma_lut;
+
+ lut = (struct drm_color_lut *)gamma_lut->data;
+ if (cmap->start || cmap->len != size) {
+ u16 *r = crtc->gamma_store;
+ u16 *g = r + crtc->gamma_size;
+ u16 *b = g + crtc->gamma_size;
+
+ for (i = 0; i < cmap->start; i++) {
+ lut[i].red = r[i];
+ lut[i].green = g[i];
+ lut[i].blue = b[i];
+ }
+ for (i = cmap->start + cmap->len; i < size; i++) {
+ lut[i].red = r[i];
+ lut[i].green = g[i];
+ lut[i].blue = b[i];
+ }
+ }
+
+ for (i = 0; i < cmap->len; i++) {
+ lut[cmap->start + i].red = cmap->red[i];
+ lut[cmap->start + i].green = cmap->green[i];
+ lut[cmap->start + i].blue = cmap->blue[i];
+ }
+
+ return gamma_lut;
+}
+
+static int setcmap_atomic(struct fb_cmap *cmap, struct fb_info *info)
+{
+ struct drm_fb_helper *fb_helper = info->par;
+ struct drm_device *dev = fb_helper->dev;
+ struct drm_property_blob *gamma_lut = NULL;
+ struct drm_modeset_acquire_ctx ctx;
+ struct drm_crtc_state *crtc_state;
+ struct drm_atomic_state *state;
+ struct drm_crtc *crtc;
+ u16 *r, *g, *b;
+ int i, ret = 0;
+ bool replaced;
+
+ drm_modeset_acquire_init(&ctx, 0);
+
+ state = drm_atomic_state_alloc(dev);
+ if (!state) {
+ ret = -ENOMEM;
+ goto out_ctx;
+ }
+
+ state->acquire_ctx = &ctx;
+retry:
+ for (i = 0; i < fb_helper->crtc_count; i++) {
+ crtc = fb_helper->crtc_info[i].mode_set.crtc;
+
+ if (!gamma_lut)
+ gamma_lut = setcmap_new_gamma_lut(crtc, cmap);
+ if (IS_ERR(gamma_lut)) {
+ ret = PTR_ERR(gamma_lut);
+ gamma_lut = NULL;
+ goto out_state;
+ }
+
+ crtc_state = drm_atomic_get_crtc_state(state, crtc);
+ if (IS_ERR(crtc_state)) {
+ ret = PTR_ERR(crtc_state);
+ goto out_state;
+ }
+
+ replaced = drm_property_replace_blob(&crtc_state->degamma_lut,
+ NULL);
+ replaced |= drm_property_replace_blob(&crtc_state->ctm, NULL);
+ replaced |= drm_property_replace_blob(&crtc_state->gamma_lut,
+ gamma_lut);
+ crtc_state->color_mgmt_changed |= replaced;
+ }
+
+ ret = drm_atomic_commit(state);
+ if (ret)
+ goto out_state;
+
+ for (i = 0; i < fb_helper->crtc_count; i++) {
+ crtc = fb_helper->crtc_info[i].mode_set.crtc;
+
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
+
+ memcpy(r + cmap->start, cmap->red, cmap->len * sizeof(*r));
+ memcpy(g + cmap->start, cmap->green, cmap->len * sizeof(*g));
+ memcpy(b + cmap->start, cmap->blue, cmap->len * sizeof(*b));
+ }
+
+out_state:
+ if (ret == -EDEADLK)
+ goto backoff;
+
+ drm_property_blob_put(gamma_lut);
+ drm_atomic_state_put(state);
+out_ctx:
+ drm_modeset_drop_locks(&ctx);
+ drm_modeset_acquire_fini(&ctx);
+
+ return ret;
+
+backoff:
+ drm_atomic_state_clear(state);
+ drm_modeset_backoff(&ctx);
+ goto retry;
}
/**
@@ -1219,52 +1397,29 @@ static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green,
int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info)
{
struct drm_fb_helper *fb_helper = info->par;
- struct drm_device *dev = fb_helper->dev;
- const struct drm_crtc_helper_funcs *crtc_funcs;
- u16 *red, *green, *blue, *transp;
- struct drm_crtc *crtc;
- int i, j, rc = 0;
- int start;
+ int ret;
if (oops_in_progress)
return -EBUSY;
- drm_modeset_lock_all(dev);
+ mutex_lock(&fb_helper->lock);
+
if (!drm_fb_helper_is_bound(fb_helper)) {
- drm_modeset_unlock_all(dev);
- return -EBUSY;
+ ret = -EBUSY;
+ goto out;
}
- for (i = 0; i < fb_helper->crtc_count; i++) {
- crtc = fb_helper->crtc_info[i].mode_set.crtc;
- crtc_funcs = crtc->helper_private;
-
- red = cmap->red;
- green = cmap->green;
- blue = cmap->blue;
- transp = cmap->transp;
- start = cmap->start;
-
- for (j = 0; j < cmap->len; j++) {
- u16 hred, hgreen, hblue, htransp = 0xffff;
-
- hred = *red++;
- hgreen = *green++;
- hblue = *blue++;
+ if (info->fix.visual == FB_VISUAL_TRUECOLOR)
+ ret = setcmap_pseudo_palette(cmap, info);
+ else if (drm_drv_uses_atomic_modeset(fb_helper->dev))
+ ret = setcmap_atomic(cmap, info);
+ else
+ ret = setcmap_legacy(cmap, info);
- if (transp)
- htransp = *transp++;
+out:
+ mutex_unlock(&fb_helper->lock);
- rc = setcolreg(crtc, hred, hgreen, hblue, start++, info);
- if (rc)
- goto out;
- }
- if (crtc_funcs->load_lut)
- crtc_funcs->load_lut(crtc);
- }
- out:
- drm_modeset_unlock_all(dev);
- return rc;
+ return ret;
}
EXPORT_SYMBOL(drm_fb_helper_setcmap);
@@ -1281,12 +1436,11 @@ int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd,
unsigned long arg)
{
struct drm_fb_helper *fb_helper = info->par;
- struct drm_device *dev = fb_helper->dev;
struct drm_mode_set *mode_set;
struct drm_crtc *crtc;
int ret = 0;
- mutex_lock(&dev->mode_config.mutex);
+ mutex_lock(&fb_helper->lock);
if (!drm_fb_helper_is_bound(fb_helper)) {
ret = -EBUSY;
goto unlock;
@@ -1331,7 +1485,7 @@ int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd,
}
unlock:
- mutex_unlock(&dev->mode_config.mutex);
+ mutex_unlock(&fb_helper->lock);
return ret;
}
EXPORT_SYMBOL(drm_fb_helper_ioctl);
@@ -1463,61 +1617,36 @@ int drm_fb_helper_set_par(struct fb_info *info)
}
EXPORT_SYMBOL(drm_fb_helper_set_par);
-static int pan_display_atomic(struct fb_var_screeninfo *var,
- struct fb_info *info)
+static void pan_set(struct drm_fb_helper *fb_helper, int x, int y)
{
- struct drm_fb_helper *fb_helper = info->par;
- struct drm_device *dev = fb_helper->dev;
- struct drm_atomic_state *state;
- struct drm_plane *plane;
- int i, ret;
- unsigned int plane_mask;
-
- state = drm_atomic_state_alloc(dev);
- if (!state)
- return -ENOMEM;
+ int i;
- state->acquire_ctx = dev->mode_config.acquire_ctx;
-retry:
- plane_mask = 0;
for (i = 0; i < fb_helper->crtc_count; i++) {
struct drm_mode_set *mode_set;
mode_set = &fb_helper->crtc_info[i].mode_set;
- mode_set->x = var->xoffset;
- mode_set->y = var->yoffset;
-
- ret = __drm_atomic_helper_set_config(mode_set, state);
- if (ret != 0)
- goto fail;
-
- plane = mode_set->crtc->primary;
- plane_mask |= (1 << drm_plane_index(plane));
- plane->old_fb = plane->fb;
+ mode_set->x = x;
+ mode_set->y = y;
}
+}
- ret = drm_atomic_commit(state);
- if (ret != 0)
- goto fail;
+static int pan_display_atomic(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ struct drm_fb_helper *fb_helper = info->par;
+ int ret;
- info->var.xoffset = var->xoffset;
- info->var.yoffset = var->yoffset;
+ pan_set(fb_helper, var->xoffset, var->yoffset);
-fail:
- drm_atomic_clean_old_fb(dev, plane_mask, ret);
+ ret = restore_fbdev_mode_atomic(fb_helper, true);
+ if (!ret) {
+ info->var.xoffset = var->xoffset;
+ info->var.yoffset = var->yoffset;
+ } else
+ pan_set(fb_helper, info->var.xoffset, info->var.yoffset);
- if (ret == -EDEADLK)
- goto backoff;
-
- drm_atomic_state_put(state);
return ret;
-
-backoff:
- drm_atomic_state_clear(state);
- drm_atomic_legacy_backoff(state);
-
- goto retry;
}
static int pan_display_legacy(struct fb_var_screeninfo *var,
@@ -1528,6 +1657,7 @@ static int pan_display_legacy(struct fb_var_screeninfo *var,
int ret = 0;
int i;
+ drm_modeset_lock_all(fb_helper->dev);
for (i = 0; i < fb_helper->crtc_count; i++) {
modeset = &fb_helper->crtc_info[i].mode_set;
@@ -1542,6 +1672,7 @@ static int pan_display_legacy(struct fb_var_screeninfo *var,
}
}
}
+ drm_modeset_unlock_all(fb_helper->dev);
return ret;
}
@@ -1561,9 +1692,9 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
if (oops_in_progress)
return -EBUSY;
- drm_modeset_lock_all(dev);
+ mutex_lock(&fb_helper->lock);
if (!drm_fb_helper_is_bound(fb_helper)) {
- drm_modeset_unlock_all(dev);
+ mutex_unlock(&fb_helper->lock);
return -EBUSY;
}
@@ -1571,7 +1702,7 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
ret = pan_display_atomic(var, info);
else
ret = pan_display_legacy(var, info);
- drm_modeset_unlock_all(dev);
+ mutex_unlock(&fb_helper->lock);
return ret;
}
@@ -1579,8 +1710,7 @@ EXPORT_SYMBOL(drm_fb_helper_pan_display);
/*
* Allocates the backing storage and sets up the fbdev info structure through
- * the ->fb_probe callback and then registers the fbdev and sets up the panic
- * notifier.
+ * the ->fb_probe callback.
*/
static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
int preferred_bpp)
@@ -1678,13 +1808,8 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
}
if (crtc_count == 0 || sizes.fb_width == -1 || sizes.fb_height == -1) {
- /*
- * hmm everyone went away - assume VGA cable just fell out
- * and will come back later.
- */
- DRM_INFO("Cannot find any crtc or sizes - going 1024x768\n");
- sizes.fb_width = sizes.surface_width = 1024;
- sizes.fb_height = sizes.surface_height = 768;
+ DRM_INFO("Cannot find any crtc or sizes\n");
+ return -EAGAIN;
}
/* Handle our overallocation */
@@ -1696,17 +1821,6 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
if (ret < 0)
return ret;
- /*
- * Set the fb pointer - usually drm_setup_crtcs does this for hotplug
- * events, but at init time drm_setup_crtcs needs to be called before
- * the fb is allocated (since we need to figure out the desired size of
- * the fb before we can allocate it ...). Hence we need to fix things up
- * here again.
- */
- for (i = 0; i < fb_helper->crtc_count; i++)
- if (fb_helper->crtc_info[i].mode_set.num_connectors)
- fb_helper->crtc_info[i].mode_set.fb = fb_helper->fb;
-
return 0;
}
@@ -1768,8 +1882,6 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helpe
info->var.xoffset = 0;
info->var.yoffset = 0;
info->var.activate = FB_ACTIVATE_NOW;
- info->var.height = -1;
- info->var.width = -1;
switch (fb->format->depth) {
case 8:
@@ -1831,12 +1943,11 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helpe
EXPORT_SYMBOL(drm_fb_helper_fill_var);
static int drm_fb_helper_probe_connector_modes(struct drm_fb_helper *fb_helper,
- uint32_t maxX,
- uint32_t maxY)
+ uint32_t maxX,
+ uint32_t maxY)
{
struct drm_connector *connector;
- int count = 0;
- int i;
+ int i, count = 0;
drm_fb_helper_for_each_connector(fb_helper, i) {
connector = fb_helper->connector_info[i]->connector;
@@ -2234,11 +2345,8 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
int i;
DRM_DEBUG_KMS("\n");
- if (drm_fb_helper_probe_connector_modes(fb_helper, width, height) == 0)
- DRM_DEBUG_KMS("No connectors reported connected with modes\n");
-
/* prevent concurrent modification of connector_count by hotplug */
- lockdep_assert_held(&fb_helper->dev->mode_config.mutex);
+ lockdep_assert_held(&fb_helper->lock);
crtcs = kcalloc(fb_helper->connector_count,
sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL);
@@ -2253,6 +2361,9 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
goto out;
}
+ mutex_lock(&fb_helper->dev->mode_config.mutex);
+ if (drm_fb_helper_probe_connector_modes(fb_helper, width, height) == 0)
+ DRM_DEBUG_KMS("No connectors reported connected with modes\n");
drm_enable_connectors(fb_helper, enabled);
if (!(fb_helper->funcs->initial_config &&
@@ -2274,6 +2385,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
drm_pick_crtcs(fb_helper, crtcs, modes, 0, width, height);
}
+ mutex_unlock(&fb_helper->dev->mode_config.mutex);
/* need to set the modesets up here for use later */
/* fill out the connector<->crtc mappings into the modesets */
@@ -2285,9 +2397,9 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
struct drm_display_mode *mode = modes[i];
struct drm_fb_helper_crtc *fb_crtc = crtcs[i];
struct drm_fb_offset *offset = &offsets[i];
- struct drm_mode_set *modeset = &fb_crtc->mode_set;
if (mode && fb_crtc) {
+ struct drm_mode_set *modeset = &fb_crtc->mode_set;
struct drm_connector *connector =
fb_helper->connector_info[i]->connector;
@@ -2301,7 +2413,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
fb_crtc->desired_mode);
drm_connector_get(connector);
modeset->connectors[modeset->num_connectors++] = connector;
- modeset->fb = fb_helper->fb;
modeset->x = offset->x;
modeset->y = offset->y;
}
@@ -2313,6 +2424,91 @@ out:
kfree(enabled);
}
+/*
+ * This is a continuation of drm_setup_crtcs() that sets up anything related
+ * to the framebuffer. During initialization, drm_setup_crtcs() is called before
+ * the framebuffer has been allocated (fb_helper->fb and fb_helper->fbdev).
+ * So, any setup that touches those fields needs to be done here instead of in
+ * drm_setup_crtcs().
+ */
+static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper)
+{
+ struct fb_info *info = fb_helper->fbdev;
+ int i;
+
+ for (i = 0; i < fb_helper->crtc_count; i++)
+ if (fb_helper->crtc_info[i].mode_set.num_connectors)
+ fb_helper->crtc_info[i].mode_set.fb = fb_helper->fb;
+
+ mutex_lock(&fb_helper->dev->mode_config.mutex);
+ drm_fb_helper_for_each_connector(fb_helper, i) {
+ struct drm_connector *connector =
+ fb_helper->connector_info[i]->connector;
+
+ /* use first connected connector for the physical dimensions */
+ if (connector->status == connector_status_connected) {
+ info->var.width = connector->display_info.width_mm;
+ info->var.height = connector->display_info.height_mm;
+ break;
+ }
+ }
+ mutex_unlock(&fb_helper->dev->mode_config.mutex);
+}
+
+/* Note: Drops fb_helper->lock before returning. */
+static int
+__drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper,
+ int bpp_sel)
+{
+ struct drm_device *dev = fb_helper->dev;
+ struct fb_info *info;
+ unsigned int width, height;
+ int ret;
+
+ width = dev->mode_config.max_width;
+ height = dev->mode_config.max_height;
+
+ drm_setup_crtcs(fb_helper, width, height);
+ ret = drm_fb_helper_single_fb_probe(fb_helper, bpp_sel);
+ if (ret < 0) {
+ if (ret == -EAGAIN) {
+ fb_helper->preferred_bpp = bpp_sel;
+ fb_helper->deferred_setup = true;
+ ret = 0;
+ }
+ mutex_unlock(&fb_helper->lock);
+
+ return ret;
+ }
+ drm_setup_crtcs_fb(fb_helper);
+
+ fb_helper->deferred_setup = false;
+
+ info = fb_helper->fbdev;
+ info->var.pixclock = 0;
+
+ /* Need to drop locks to avoid recursive deadlock in
+ * register_framebuffer. This is ok because the only thing left to do is
+ * register the fbdev emulation instance in kernel_fb_helper_list. */
+ mutex_unlock(&fb_helper->lock);
+
+ ret = register_framebuffer(info);
+ if (ret < 0)
+ return ret;
+
+ dev_info(dev->dev, "fb%d: %s frame buffer device\n",
+ info->node, info->fix.id);
+
+ mutex_lock(&kernel_fb_helper_lock);
+ if (list_empty(&kernel_fb_helper_list))
+ register_sysrq_key('v', &sysrq_drm_fb_helper_restore_op);
+
+ list_add(&fb_helper->kernel_fb_list, &kernel_fb_helper_list);
+ mutex_unlock(&kernel_fb_helper_lock);
+
+ return 0;
+}
+
/**
* drm_fb_helper_initial_config - setup a sane initial connector configuration
* @fb_helper: fb_helper device struct
@@ -2357,39 +2553,15 @@ out:
*/
int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel)
{
- struct drm_device *dev = fb_helper->dev;
- struct fb_info *info;
int ret;
if (!drm_fbdev_emulation)
return 0;
- mutex_lock(&dev->mode_config.mutex);
- drm_setup_crtcs(fb_helper,
- dev->mode_config.max_width,
- dev->mode_config.max_height);
- ret = drm_fb_helper_single_fb_probe(fb_helper, bpp_sel);
- mutex_unlock(&dev->mode_config.mutex);
- if (ret)
- return ret;
+ mutex_lock(&fb_helper->lock);
+ ret = __drm_fb_helper_initial_config_and_unlock(fb_helper, bpp_sel);
- info = fb_helper->fbdev;
- info->var.pixclock = 0;
- ret = register_framebuffer(info);
- if (ret < 0)
- return ret;
-
- dev_info(dev->dev, "fb%d: %s frame buffer device\n",
- info->node, info->fix.id);
-
- mutex_lock(&kernel_fb_helper_lock);
- if (list_empty(&kernel_fb_helper_list))
- register_sysrq_key('v', &sysrq_drm_fb_helper_restore_op);
-
- list_add(&fb_helper->kernel_fb_list, &kernel_fb_helper_list);
- mutex_unlock(&kernel_fb_helper_lock);
-
- return 0;
+ return ret;
}
EXPORT_SYMBOL(drm_fb_helper_initial_config);
@@ -2416,22 +2588,29 @@ EXPORT_SYMBOL(drm_fb_helper_initial_config);
*/
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
{
- struct drm_device *dev = fb_helper->dev;
+ int err = 0;
if (!drm_fbdev_emulation)
return 0;
- mutex_lock(&dev->mode_config.mutex);
+ mutex_lock(&fb_helper->lock);
+ if (fb_helper->deferred_setup) {
+ err = __drm_fb_helper_initial_config_and_unlock(fb_helper,
+ fb_helper->preferred_bpp);
+ return err;
+ }
+
if (!fb_helper->fb || !drm_fb_helper_is_bound(fb_helper)) {
fb_helper->delayed_hotplug = true;
- mutex_unlock(&dev->mode_config.mutex);
- return 0;
+ mutex_unlock(&fb_helper->lock);
+ return err;
}
+
DRM_DEBUG_KMS("\n");
drm_setup_crtcs(fb_helper, fb_helper->fb->width, fb_helper->fb->height);
-
- mutex_unlock(&dev->mode_config.mutex);
+ drm_setup_crtcs_fb(fb_helper);
+ mutex_unlock(&fb_helper->lock);
drm_fb_helper_set_par(fb_helper->fbdev);
diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
index 84f3a24..b3c6e99 100644
--- a/drivers/gpu/drm/drm_file.c
+++ b/drivers/gpu/drm/drm_file.c
@@ -75,7 +75,7 @@ DEFINE_MUTEX(drm_global_mutex);
* for drivers which use the CMA GEM helpers it's drm_gem_cma_mmap().
*
* No other file operations are supported by the DRM userspace API. Overall the
- * following is an example #file_operations structure::
+ * following is an example &file_operations structure::
*
* static const example_drm_fops = {
* .owner = THIS_MODULE,
@@ -92,6 +92,11 @@ DEFINE_MUTEX(drm_global_mutex);
* For plain GEM based drivers there is the DEFINE_DRM_GEM_FOPS() macro, and for
* CMA based drivers there is the DEFINE_DRM_GEM_CMA_FOPS() macro to make this
* simpler.
+ *
+ * The driver's &file_operations must be stored in &drm_driver.fops.
+ *
+ * For driver-private IOCTL handling see the more detailed discussion in
+ * :ref:`IOCTL support in the userland interfaces chapter<drm_driver_ioctl>`.
*/
static int drm_open_helper(struct file *filp, struct drm_minor *minor);
@@ -431,7 +436,7 @@ int drm_release(struct inode *inode, struct file *filp)
if (!--dev->open_count) {
drm_lastclose(dev);
- if (drm_device_is_unplugged(dev))
+ if (drm_dev_is_unplugged(dev))
drm_put_dev(dev);
}
mutex_unlock(&drm_global_mutex);
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index b3ef4f1..af27984 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -817,7 +817,7 @@ retry:
plane->old_fb = plane->fb;
}
- for_each_connector_in_state(state, conn, conn_state, i) {
+ for_each_new_connector_in_state(state, conn, conn_state, i) {
ret = drm_atomic_set_crtc_for_connector(conn_state, NULL);
if (ret)
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index cdaac37..c55f338 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -36,6 +36,7 @@
#include <linux/pagemap.h>
#include <linux/shmem_fs.h>
#include <linux/dma-buf.h>
+#include <linux/mem_encrypt.h>
#include <drm/drmP.h>
#include <drm/drm_vma_manager.h>
#include <drm/drm_gem.h>
@@ -311,6 +312,41 @@ drm_gem_handle_delete(struct drm_file *filp, u32 handle)
EXPORT_SYMBOL(drm_gem_handle_delete);
/**
+ * drm_gem_dumb_map_offset - return the fake mmap offset for a gem object
+ * @file: drm file-private structure containing the gem object
+ * @dev: corresponding drm_device
+ * @handle: gem object handle
+ * @offset: return location for the fake mmap offset
+ *
+ * This implements the &drm_driver.dumb_map_offset kms driver callback for
+ * drivers which use gem to manage their backing storage.
+ *
+ * Returns:
+ * 0 on success or a negative error code on failure.
+ */
+int drm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
+ u32 handle, u64 *offset)
+{
+ struct drm_gem_object *obj;
+ int ret;
+
+ obj = drm_gem_object_lookup(file, handle);
+ if (!obj)
+ return -ENOENT;
+
+ ret = drm_gem_create_mmap_offset(obj);
+ if (ret)
+ goto out;
+
+ *offset = drm_vma_node_offset_addr(&obj->vma_node);
+out:
+ drm_gem_object_put_unlocked(obj);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(drm_gem_dumb_map_offset);
+
+/**
* drm_gem_dumb_destroy - dumb fb callback helper for gem based drivers
* @file: drm file-private structure to remove the dumb handle from
* @dev: corresponding drm_device
@@ -826,13 +862,15 @@ drm_gem_object_put_unlocked(struct drm_gem_object *obj)
return;
dev = obj->dev;
- might_lock(&dev->struct_mutex);
- if (dev->driver->gem_free_object_unlocked)
+ if (dev->driver->gem_free_object_unlocked) {
kref_put(&obj->refcount, drm_gem_object_free);
- else if (kref_put_mutex(&obj->refcount, drm_gem_object_free,
+ } else {
+ might_lock(&dev->struct_mutex);
+ if (kref_put_mutex(&obj->refcount, drm_gem_object_free,
&dev->struct_mutex))
- mutex_unlock(&dev->struct_mutex);
+ mutex_unlock(&dev->struct_mutex);
+ }
}
EXPORT_SYMBOL(drm_gem_object_put_unlocked);
@@ -928,6 +966,7 @@ int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size,
vma->vm_ops = dev->driver->gem_vm_ops;
vma->vm_private_data = obj;
vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+ vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
/* Take a ref for this mapping of the object, so that the fault
* handler can dereference the mmap offset's pointer to the object.
@@ -964,7 +1003,7 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
struct drm_vma_offset_node *node;
int ret;
- if (drm_device_is_unplugged(dev))
+ if (drm_dev_is_unplugged(dev))
return -ENODEV;
drm_vma_offset_lock_lookup(dev->vma_offset_manager);
diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c
index bc28e75..373e33f 100644
--- a/drivers/gpu/drm/drm_gem_cma_helper.c
+++ b/drivers/gpu/drm/drm_gem_cma_helper.c
@@ -177,7 +177,7 @@ drm_gem_cma_create_with_handle(struct drm_file *file_priv,
* This function frees the backing memory of the CMA GEM object, cleans up the
* GEM object state and frees the memory used to store the object itself.
* Drivers using the CMA helpers should set this as their
- * &drm_driver.gem_free_object callback.
+ * &drm_driver.gem_free_object_unlocked callback.
*/
void drm_gem_cma_free_object(struct drm_gem_object *gem_obj)
{
@@ -264,41 +264,6 @@ int drm_gem_cma_dumb_create(struct drm_file *file_priv,
}
EXPORT_SYMBOL_GPL(drm_gem_cma_dumb_create);
-/**
- * drm_gem_cma_dumb_map_offset - return the fake mmap offset for a CMA GEM
- * object
- * @file_priv: DRM file-private structure containing the GEM object
- * @drm: DRM device
- * @handle: GEM object handle
- * @offset: return location for the fake mmap offset
- *
- * This function look up an object by its handle and returns the fake mmap
- * offset associated with it. Drivers using the CMA helpers should set this
- * as their &drm_driver.dumb_map_offset callback.
- *
- * Returns:
- * 0 on success or a negative error code on failure.
- */
-int drm_gem_cma_dumb_map_offset(struct drm_file *file_priv,
- struct drm_device *drm, u32 handle,
- u64 *offset)
-{
- struct drm_gem_object *gem_obj;
-
- gem_obj = drm_gem_object_lookup(file_priv, handle);
- if (!gem_obj) {
- dev_err(drm->dev, "failed to lookup GEM object\n");
- return -EINVAL;
- }
-
- *offset = drm_vma_node_offset_addr(&gem_obj->vma_node);
-
- drm_gem_object_put_unlocked(gem_obj);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(drm_gem_cma_dumb_map_offset);
-
const struct vm_operations_struct drm_gem_cma_vm_ops = {
.open = drm_gem_vm_open,
.close = drm_gem_vm_close,
@@ -390,7 +355,7 @@ unsigned long drm_gem_cma_get_unmapped_area(struct file *filp,
struct drm_device *dev = priv->minor->dev;
struct drm_vma_offset_node *node;
- if (drm_device_is_unplugged(dev))
+ if (drm_dev_is_unplugged(dev))
return -ENODEV;
drm_vma_offset_lock_lookup(dev->vma_offset_manager);
diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
new file mode 100644
index 0000000..d54a083
--- /dev/null
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -0,0 +1,283 @@
+/*
+ * drm gem framebuffer helper functions
+ *
+ * Copyright (C) 2017 Noralf Trønnes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/dma-buf.h>
+#include <linux/dma-fence.h>
+#include <linux/reservation.h>
+#include <linux/slab.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_framebuffer.h>
+#include <drm/drm_gem.h>
+#include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_modeset_helper.h>
+
+/**
+ * DOC: overview
+ *
+ * This library provides helpers for drivers that don't subclass
+ * &drm_framebuffer and and use &drm_gem_object for their backing storage.
+ *
+ * Drivers without additional needs to validate framebuffers can simply use
+ * drm_gem_fb_create() and everything is wired up automatically. But all
+ * parts can be used individually.
+ */
+
+/**
+ * drm_gem_fb_get_obj() - Get GEM object for framebuffer
+ * @fb: The framebuffer
+ * @plane: Which plane
+ *
+ * Returns the GEM object for given framebuffer.
+ */
+struct drm_gem_object *drm_gem_fb_get_obj(struct drm_framebuffer *fb,
+ unsigned int plane)
+{
+ if (plane >= 4)
+ return NULL;
+
+ return fb->obj[plane];
+}
+EXPORT_SYMBOL_GPL(drm_gem_fb_get_obj);
+
+static struct drm_framebuffer *
+drm_gem_fb_alloc(struct drm_device *dev,
+ const struct drm_mode_fb_cmd2 *mode_cmd,
+ struct drm_gem_object **obj, unsigned int num_planes,
+ const struct drm_framebuffer_funcs *funcs)
+{
+ struct drm_framebuffer *fb;
+ int ret, i;
+
+ fb = kzalloc(sizeof(*fb), GFP_KERNEL);
+ if (!fb)
+ return ERR_PTR(-ENOMEM);
+
+ drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);
+
+ for (i = 0; i < num_planes; i++)
+ fb->obj[i] = obj[i];
+
+ ret = drm_framebuffer_init(dev, fb, funcs);
+ if (ret) {
+ DRM_DEV_ERROR(dev->dev, "Failed to init framebuffer: %d\n",
+ ret);
+ kfree(fb);
+ return ERR_PTR(ret);
+ }
+
+ return fb;
+}
+
+/**
+ * drm_gem_fb_destroy - Free GEM backed framebuffer
+ * @fb: DRM framebuffer
+ *
+ * Frees a GEM backed framebuffer with its backing buffer(s) and the structure
+ * itself. Drivers can use this as their &drm_framebuffer_funcs->destroy
+ * callback.
+ */
+void drm_gem_fb_destroy(struct drm_framebuffer *fb)
+{
+ int i;
+
+ for (i = 0; i < 4; i++)
+ drm_gem_object_put_unlocked(fb->obj[i]);
+
+ drm_framebuffer_cleanup(fb);
+ kfree(fb);
+}
+EXPORT_SYMBOL(drm_gem_fb_destroy);
+
+/**
+ * drm_gem_fb_create_handle - Create handle for GEM backed framebuffer
+ * @fb: DRM framebuffer
+ * @file: drm file
+ * @handle: handle created
+ *
+ * Drivers can use this as their &drm_framebuffer_funcs->create_handle
+ * callback.
+ *
+ * Returns:
+ * 0 on success or a negative error code on failure.
+ */
+int drm_gem_fb_create_handle(struct drm_framebuffer *fb, struct drm_file *file,
+ unsigned int *handle)
+{
+ return drm_gem_handle_create(file, fb->obj[0], handle);
+}
+EXPORT_SYMBOL(drm_gem_fb_create_handle);
+
+/**
+ * drm_gem_fb_create_with_funcs() - helper function for the
+ * &drm_mode_config_funcs.fb_create
+ * callback
+ * @dev: DRM device
+ * @file: drm file for the ioctl call
+ * @mode_cmd: metadata from the userspace fb creation request
+ * @funcs: vtable to be used for the new framebuffer object
+ *
+ * This can be used to set &drm_framebuffer_funcs for drivers that need the
+ * &drm_framebuffer_funcs.dirty callback. Use drm_gem_fb_create() if you don't
+ * need to change &drm_framebuffer_funcs.
+ * The function does buffer size validation.
+ */
+struct drm_framebuffer *
+drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file,
+ const struct drm_mode_fb_cmd2 *mode_cmd,
+ const struct drm_framebuffer_funcs *funcs)
+{
+ const struct drm_format_info *info;
+ struct drm_gem_object *objs[4];
+ struct drm_framebuffer *fb;
+ int ret, i;
+
+ info = drm_get_format_info(dev, mode_cmd);
+ if (!info)
+ return ERR_PTR(-EINVAL);
+
+ for (i = 0; i < info->num_planes; i++) {
+ unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
+ unsigned int height = mode_cmd->height / (i ? info->vsub : 1);
+ unsigned int min_size;
+
+ objs[i] = drm_gem_object_lookup(file, mode_cmd->handles[i]);
+ if (!objs[i]) {
+ DRM_DEV_ERROR(dev->dev, "Failed to lookup GEM\n");
+ ret = -ENOENT;
+ goto err_gem_object_put;
+ }
+
+ min_size = (height - 1) * mode_cmd->pitches[i]
+ + width * info->cpp[i]
+ + mode_cmd->offsets[i];
+
+ if (objs[i]->size < min_size) {
+ drm_gem_object_put_unlocked(objs[i]);
+ ret = -EINVAL;
+ goto err_gem_object_put;
+ }
+ }
+
+ fb = drm_gem_fb_alloc(dev, mode_cmd, objs, i, funcs);
+ if (IS_ERR(fb)) {
+ ret = PTR_ERR(fb);
+ goto err_gem_object_put;
+ }
+
+ return fb;
+
+err_gem_object_put:
+ for (i--; i >= 0; i--)
+ drm_gem_object_put_unlocked(objs[i]);
+
+ return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(drm_gem_fb_create_with_funcs);
+
+static const struct drm_framebuffer_funcs drm_gem_fb_funcs = {
+ .destroy = drm_gem_fb_destroy,
+ .create_handle = drm_gem_fb_create_handle,
+};
+
+/**
+ * drm_gem_fb_create() - &drm_mode_config_funcs.fb_create callback function
+ * @dev: DRM device
+ * @file: drm file for the ioctl call
+ * @mode_cmd: metadata from the userspace fb creation request
+ *
+ * If your hardware has special alignment or pitch requirements these should be
+ * checked before calling this function. The function does buffer size
+ * validation. Use drm_gem_fb_create_with_funcs() if you need to set
+ * &drm_framebuffer_funcs.dirty.
+ */
+struct drm_framebuffer *
+drm_gem_fb_create(struct drm_device *dev, struct drm_file *file,
+ const struct drm_mode_fb_cmd2 *mode_cmd)
+{
+ return drm_gem_fb_create_with_funcs(dev, file, mode_cmd,
+ &drm_gem_fb_funcs);
+}
+EXPORT_SYMBOL_GPL(drm_gem_fb_create);
+
+/**
+ * drm_gem_fb_prepare_fb() - Prepare gem framebuffer
+ * @plane: Which plane
+ * @state: Plane state attach fence to
+ *
+ * This can be used as the &drm_plane_helper_funcs.prepare_fb hook.
+ *
+ * This function checks if the plane FB has an dma-buf attached, extracts
+ * the exclusive fence and attaches it to plane state for the atomic helper
+ * to wait on.
+ *
+ * There is no need for &drm_plane_helper_funcs.cleanup_fb hook for simple
+ * gem based framebuffer drivers which have their buffers always pinned in
+ * memory.
+ */
+int drm_gem_fb_prepare_fb(struct drm_plane *plane,
+ struct drm_plane_state *state)
+{
+ struct dma_buf *dma_buf;
+ struct dma_fence *fence;
+
+ if ((plane->state->fb == state->fb) || !state->fb)
+ return 0;
+
+ dma_buf = drm_gem_fb_get_obj(state->fb, 0)->dma_buf;
+ if (dma_buf) {
+ fence = reservation_object_get_excl_rcu(dma_buf->resv);
+ drm_atomic_set_fence_for_plane(state, fence);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(drm_gem_fb_prepare_fb);
+
+/**
+ * drm_gem_fbdev_fb_create - Create a drm_framebuffer for fbdev emulation
+ * @dev: DRM device
+ * @sizes: fbdev size description
+ * @pitch_align: optional pitch alignment
+ * @obj: GEM object backing the framebuffer
+ * @funcs: vtable to be used for the new framebuffer object
+ *
+ * This function creates a framebuffer for use with fbdev emulation.
+ *
+ * Returns:
+ * Pointer to a drm_framebuffer on success or an error pointer on failure.
+ */
+struct drm_framebuffer *
+drm_gem_fbdev_fb_create(struct drm_device *dev,
+ struct drm_fb_helper_surface_size *sizes,
+ unsigned int pitch_align, struct drm_gem_object *obj,
+ const struct drm_framebuffer_funcs *funcs)
+{
+ struct drm_mode_fb_cmd2 mode_cmd = { 0 };
+
+ mode_cmd.width = sizes->surface_width;
+ mode_cmd.height = sizes->surface_height;
+ mode_cmd.pitches[0] = sizes->surface_width *
+ DIV_ROUND_UP(sizes->surface_bpp, 8);
+ if (pitch_align)
+ mode_cmd.pitches[0] = roundup(mode_cmd.pitches[0],
+ pitch_align);
+ mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
+ sizes->surface_depth);
+ if (obj->size < mode_cmd.pitches[0] * mode_cmd.height)
+ return ERR_PTR(-EINVAL);
+
+ return drm_gem_fb_alloc(dev, &mode_cmd, &obj, 1, funcs);
+}
+EXPORT_SYMBOL(drm_gem_fbdev_fb_create);
diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index 5edc24b..fbc3f30 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -32,6 +32,7 @@ void drm_lastclose(struct drm_device *dev);
int drm_irq_by_busid(struct drm_device *dev, void *data,
struct drm_file *file_priv);
void drm_pci_agp_destroy(struct drm_device *dev);
+int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master);
/* drm_prime.c */
int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data,
@@ -56,14 +57,19 @@ int drm_gem_name_info(struct seq_file *m, void *data);
/* drm_vblank.c */
extern unsigned int drm_timestamp_monotonic;
void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe);
+void drm_vblank_cleanup(struct drm_device *dev);
+
+/* IOCTLS */
+int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *filp);
+int drm_legacy_modeset_ctl_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+
+/* drm_irq.c */
/* IOCTLS */
-int drm_wait_vblank(struct drm_device *dev, void *data,
- struct drm_file *filp);
int drm_legacy_irq_control(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-int drm_legacy_modeset_ctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
/* drm_auth.c */
int drm_getmagic(struct drm_device *dev, void *data,
@@ -161,3 +167,9 @@ int drm_syncobj_handle_to_fd_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_private);
int drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_private);
+int drm_syncobj_wait_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_private);
+int drm_syncobj_reset_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_private);
+int drm_syncobj_signal_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_private);
diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c
index d1f2028..f8e96e6 100644
--- a/drivers/gpu/drm/drm_ioc32.c
+++ b/drivers/gpu/drm/drm_ioc32.c
@@ -842,7 +842,7 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd,
req.request.type = req32.request.type;
req.request.sequence = req32.request.sequence;
req.request.signal = req32.request.signal;
- err = drm_ioctl_kernel(file, drm_wait_vblank, &req, DRM_UNLOCKED);
+ err = drm_ioctl_kernel(file, drm_wait_vblank_ioctl, &req, DRM_UNLOCKED);
if (err)
return err;
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index f1eb326..a9ae6dd 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -143,8 +143,8 @@ static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv)
if (master->unique != NULL)
drm_unset_busid(dev, master);
- if (dev->driver->set_busid) {
- ret = dev->driver->set_busid(dev, master);
+ if (dev->dev && dev_is_pci(dev->dev)) {
+ ret = drm_pci_set_busid(dev, master);
if (ret) {
drm_unset_busid(dev, master);
return ret;
@@ -603,9 +603,9 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_legacy_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_legacy_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank_ioctl, DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_legacy_modeset_ctl, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_legacy_modeset_ctl_ioctl, 0),
DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
@@ -657,6 +657,12 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, drm_syncobj_fd_to_handle_ioctl,
DRM_UNLOCKED|DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_WAIT, drm_syncobj_wait_ioctl,
+ DRM_UNLOCKED|DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_RESET, drm_syncobj_reset_ioctl,
+ DRM_UNLOCKED|DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl,
+ DRM_UNLOCKED|DRM_RENDER_ALLOW),
};
#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
@@ -695,7 +701,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
*
* DRM driver private IOCTL must be in the range from DRM_COMMAND_BASE to
* DRM_COMMAND_END. Finally you need an array of &struct drm_ioctl_desc to wire
- * up the handlers and set the access rights:
+ * up the handlers and set the access rights::
*
* static const struct drm_ioctl_desc my_driver_ioctls[] = {
* DRM_IOCTL_DEF_DRV(MY_DRIVER_OPERATION, my_driver_operation,
@@ -704,6 +710,9 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
*
* And then assign this to the &drm_driver.ioctls field in your driver
* structure.
+ *
+ * See the separate chapter on :ref:`file operations<drm_driver_fops>` for how
+ * the driver-specific IOCTLs are wired up.
*/
long drm_ioctl_kernel(struct file *file, drm_ioctl_t *func, void *kdata,
@@ -713,7 +722,7 @@ long drm_ioctl_kernel(struct file *file, drm_ioctl_t *func, void *kdata,
struct drm_device *dev = file_priv->minor->dev;
int retcode;
- if (drm_device_is_unplugged(dev))
+ if (drm_dev_is_unplugged(dev))
return -ENODEV;
retcode = drm_ioctl_permit(flags, file_priv);
@@ -762,7 +771,7 @@ long drm_ioctl(struct file *filp,
dev = file_priv->minor->dev;
- if (drm_device_is_unplugged(dev))
+ if (drm_dev_is_unplugged(dev))
return -ENODEV;
is_driver_ioctl = nr >= DRM_COMMAND_BASE && nr < DRM_COMMAND_END;
diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 1160a57..4b47226 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -165,14 +165,14 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
u32 reg;
if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
- dev_err(dev, "modalias failure on %s\n", node->full_name);
+ dev_err(dev, "modalias failure on %pOF\n", node);
return ERR_PTR(-EINVAL);
}
ret = of_property_read_u32(node, "reg", &reg);
if (ret) {
- dev_err(dev, "device node %s has no valid reg property: %d\n",
- node->full_name, ret);
+ dev_err(dev, "device node %pOF has no valid reg property: %d\n",
+ node, ret);
return ERR_PTR(-EINVAL);
}
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index d986225..74f6ff5 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -337,6 +337,13 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)
return -ENOMEM;
dev->mode_config.gamma_lut_size_property = prop;
+ prop = drm_property_create(dev,
+ DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB,
+ "IN_FORMATS", 0);
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.modifiers_property = prop;
+
return 0;
}
diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c
index da9a9ad..1055533 100644
--- a/drivers/gpu/drm/drm_mode_object.c
+++ b/drivers/gpu/drm/drm_mode_object.c
@@ -233,6 +233,9 @@ int drm_object_property_set_value(struct drm_mode_object *obj,
{
int i;
+ WARN_ON(drm_drv_uses_atomic_modeset(property->dev) &&
+ !(property->flags & DRM_MODE_PROP_IMMUTABLE));
+
for (i = 0; i < obj->properties->count; i++) {
if (obj->properties->properties[i] == property) {
obj->properties->values[i] = val;
@@ -244,24 +247,7 @@ int drm_object_property_set_value(struct drm_mode_object *obj,
}
EXPORT_SYMBOL(drm_object_property_set_value);
-/**
- * drm_object_property_get_value - retrieve the value of a property
- * @obj: drm mode object to get property value from
- * @property: property to retrieve
- * @val: storage for the property value
- *
- * This function retrieves the softare state of the given property for the given
- * property. Since there is no driver callback to retrieve the current property
- * value this might be out of sync with the hardware, depending upon the driver
- * and property.
- *
- * Atomic drivers should never call this function directly, the core will read
- * out property values through the various ->atomic_get_property callbacks.
- *
- * Returns:
- * Zero on success, error code on failure.
- */
-int drm_object_property_get_value(struct drm_mode_object *obj,
+int __drm_object_property_get_value(struct drm_mode_object *obj,
struct drm_property *property, uint64_t *val)
{
int i;
@@ -284,6 +270,31 @@ int drm_object_property_get_value(struct drm_mode_object *obj,
return -EINVAL;
}
+
+/**
+ * drm_object_property_get_value - retrieve the value of a property
+ * @obj: drm mode object to get property value from
+ * @property: property to retrieve
+ * @val: storage for the property value
+ *
+ * This function retrieves the softare state of the given property for the given
+ * property. Since there is no driver callback to retrieve the current property
+ * value this might be out of sync with the hardware, depending upon the driver
+ * and property.
+ *
+ * Atomic drivers should never call this function directly, the core will read
+ * out property values through the various ->atomic_get_property callbacks.
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drm_object_property_get_value(struct drm_mode_object *obj,
+ struct drm_property *property, uint64_t *val)
+{
+ WARN_ON(drm_drv_uses_atomic_modeset(property->dev));
+
+ return __drm_object_property_get_value(obj, property, val);
+}
EXPORT_SYMBOL(drm_object_property_get_value);
/* helper for getconnector and getproperties ioctls */
@@ -302,7 +313,7 @@ int drm_mode_object_get_properties(struct drm_mode_object *obj, bool atomic,
continue;
if (*arg_count_props > count) {
- ret = drm_object_property_get_value(obj, prop, &val);
+ ret = __drm_object_property_get_value(obj, prop, &val);
if (ret)
return ret;
@@ -381,6 +392,83 @@ struct drm_property *drm_mode_obj_find_prop_id(struct drm_mode_object *obj,
return NULL;
}
+static int set_property_legacy(struct drm_mode_object *obj,
+ struct drm_property *prop,
+ uint64_t prop_value)
+{
+ struct drm_device *dev = prop->dev;
+ struct drm_mode_object *ref;
+ int ret = -EINVAL;
+
+ if (!drm_property_change_valid_get(prop, prop_value, &ref))
+ return -EINVAL;
+
+ drm_modeset_lock_all(dev);
+ switch (obj->type) {
+ case DRM_MODE_OBJECT_CONNECTOR:
+ ret = drm_mode_connector_set_obj_prop(obj, prop,
+ prop_value);
+ break;
+ case DRM_MODE_OBJECT_CRTC:
+ ret = drm_mode_crtc_set_obj_prop(obj, prop, prop_value);
+ break;
+ case DRM_MODE_OBJECT_PLANE:
+ ret = drm_mode_plane_set_obj_prop(obj_to_plane(obj),
+ prop, prop_value);
+ break;
+ }
+ drm_property_change_valid_put(prop, ref);
+ drm_modeset_unlock_all(dev);
+
+ return ret;
+}
+
+static int set_property_atomic(struct drm_mode_object *obj,
+ struct drm_property *prop,
+ uint64_t prop_value)
+{
+ struct drm_device *dev = prop->dev;
+ struct drm_atomic_state *state;
+ struct drm_modeset_acquire_ctx ctx;
+ int ret;
+
+ drm_modeset_acquire_init(&ctx, 0);
+
+ state = drm_atomic_state_alloc(dev);
+ if (!state)
+ return -ENOMEM;
+ state->acquire_ctx = &ctx;
+retry:
+ if (prop == state->dev->mode_config.dpms_property) {
+ if (obj->type != DRM_MODE_OBJECT_CONNECTOR) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = drm_atomic_connector_commit_dpms(state,
+ obj_to_connector(obj),
+ prop_value);
+ } else {
+ ret = drm_atomic_set_property(state, obj, prop, prop_value);
+ if (ret)
+ goto out;
+ ret = drm_atomic_commit(state);
+ }
+out:
+ if (ret == -EDEADLK) {
+ drm_atomic_state_clear(state);
+ drm_modeset_backoff(&ctx);
+ goto retry;
+ }
+
+ drm_atomic_state_put(state);
+
+ drm_modeset_drop_locks(&ctx);
+ drm_modeset_acquire_fini(&ctx);
+
+ return ret;
+}
+
int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
@@ -388,18 +476,13 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
struct drm_mode_object *arg_obj;
struct drm_property *property;
int ret = -EINVAL;
- struct drm_mode_object *ref;
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- drm_modeset_lock_all(dev);
-
arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
- if (!arg_obj) {
- ret = -ENOENT;
- goto out;
- }
+ if (!arg_obj)
+ return -ENOENT;
if (!arg_obj->properties)
goto out_unref;
@@ -408,28 +491,12 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
if (!property)
goto out_unref;
- if (!drm_property_change_valid_get(property, arg->value, &ref))
- goto out_unref;
-
- switch (arg_obj->type) {
- case DRM_MODE_OBJECT_CONNECTOR:
- ret = drm_mode_connector_set_obj_prop(arg_obj, property,
- arg->value);
- break;
- case DRM_MODE_OBJECT_CRTC:
- ret = drm_mode_crtc_set_obj_prop(arg_obj, property, arg->value);
- break;
- case DRM_MODE_OBJECT_PLANE:
- ret = drm_mode_plane_set_obj_prop(obj_to_plane(arg_obj),
- property, arg->value);
- break;
- }
-
- drm_property_change_valid_put(property, ref);
+ if (drm_drv_uses_atomic_modeset(property->dev))
+ ret = set_property_atomic(arg_obj, property, arg->value);
+ else
+ ret = set_property_legacy(arg_obj, property, arg->value);
out_unref:
drm_mode_object_put(arg_obj);
-out:
- drm_modeset_unlock_all(dev);
return ret;
}
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index f2493b9..4a3f68a 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -709,8 +709,8 @@ int of_get_drm_display_mode(struct device_node *np,
if (bus_flags)
drm_bus_flags_from_videomode(&vm, bus_flags);
- pr_debug("%s: got %dx%d display mode from %s\n",
- of_node_full_name(np), vm.hactive, vm.vactive, np->name);
+ pr_debug("%pOF: got %dx%d display mode from %s\n",
+ np, vm.hactive, vm.vactive, np->name);
drm_mode_debug_printmodeline(dmode);
return 0;
@@ -1083,6 +1083,34 @@ drm_mode_validate_size(const struct drm_display_mode *mode,
}
EXPORT_SYMBOL(drm_mode_validate_size);
+/**
+ * drm_mode_validate_ycbcr420 - add 'ycbcr420-only' modes only when allowed
+ * @mode: mode to check
+ * @connector: drm connector under action
+ *
+ * This function is a helper which can be used to filter out any YCBCR420
+ * only mode, when the source doesn't support it.
+ *
+ * Returns:
+ * The mode status
+ */
+enum drm_mode_status
+drm_mode_validate_ycbcr420(const struct drm_display_mode *mode,
+ struct drm_connector *connector)
+{
+ u8 vic = drm_match_cea_mode(mode);
+ enum drm_mode_status status = MODE_OK;
+ struct drm_hdmi_info *hdmi = &connector->display_info.hdmi;
+
+ if (test_bit(vic, hdmi->y420_vdb_modes)) {
+ if (!connector->ycbcr_420_allowed)
+ status = MODE_NO_420;
+ }
+
+ return status;
+}
+EXPORT_SYMBOL(drm_mode_validate_ycbcr420);
+
#define MODE_STATUS(status) [MODE_ ## status + 3] = #status
static const char * const drm_mode_status_names[] = {
@@ -1122,6 +1150,7 @@ static const char * const drm_mode_status_names[] = {
MODE_STATUS(ONE_SIZE),
MODE_STATUS(NO_REDUCED),
MODE_STATUS(NO_STEREO),
+ MODE_STATUS(NO_420),
MODE_STATUS(STALE),
MODE_STATUS(BAD),
MODE_STATUS(ERROR),
@@ -1576,3 +1605,61 @@ int drm_mode_convert_umode(struct drm_display_mode *out,
out:
return ret;
}
+
+/**
+ * drm_mode_is_420_only - if a given videomode can be only supported in YCBCR420
+ * output format
+ *
+ * @display: display under action
+ * @mode: video mode to be tested.
+ *
+ * Returns:
+ * true if the mode can be supported in YCBCR420 format
+ * false if not.
+ */
+bool drm_mode_is_420_only(const struct drm_display_info *display,
+ const struct drm_display_mode *mode)
+{
+ u8 vic = drm_match_cea_mode(mode);
+
+ return test_bit(vic, display->hdmi.y420_vdb_modes);
+}
+EXPORT_SYMBOL(drm_mode_is_420_only);
+
+/**
+ * drm_mode_is_420_also - if a given videomode can be supported in YCBCR420
+ * output format also (along with RGB/YCBCR444/422)
+ *
+ * @display: display under action.
+ * @mode: video mode to be tested.
+ *
+ * Returns:
+ * true if the mode can be support YCBCR420 format
+ * false if not.
+ */
+bool drm_mode_is_420_also(const struct drm_display_info *display,
+ const struct drm_display_mode *mode)
+{
+ u8 vic = drm_match_cea_mode(mode);
+
+ return test_bit(vic, display->hdmi.y420_cmdb_modes);
+}
+EXPORT_SYMBOL(drm_mode_is_420_also);
+/**
+ * drm_mode_is_420 - if a given videomode can be supported in YCBCR420
+ * output format
+ *
+ * @display: display under action.
+ * @mode: video mode to be tested.
+ *
+ * Returns:
+ * true if the mode can be supported in YCBCR420 format
+ * false if not.
+ */
+bool drm_mode_is_420(const struct drm_display_info *display,
+ const struct drm_display_mode *mode)
+{
+ return drm_mode_is_420_only(display, mode) ||
+ drm_mode_is_420_also(display, mode);
+}
+EXPORT_SYMBOL(drm_mode_is_420);
diff --git a/drivers/gpu/drm/drm_modeset_helper.c b/drivers/gpu/drm/drm_modeset_helper.c
index 2b33825..9cb1eed 100644
--- a/drivers/gpu/drm/drm_modeset_helper.c
+++ b/drivers/gpu/drm/drm_modeset_helper.c
@@ -124,6 +124,7 @@ static struct drm_plane *create_primary_plane(struct drm_device *dev)
&drm_primary_helper_funcs,
safe_modeset_formats,
ARRAY_SIZE(safe_modeset_formats),
+ NULL,
DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret) {
kfree(primary);
diff --git a/drivers/gpu/drm/drm_modeset_lock.c b/drivers/gpu/drm/drm_modeset_lock.c
index 64ef09a..af4e906 100644
--- a/drivers/gpu/drm/drm_modeset_lock.c
+++ b/drivers/gpu/drm/drm_modeset_lock.c
@@ -52,7 +52,12 @@
* drm_modeset_drop_locks(&ctx);
* drm_modeset_acquire_fini(&ctx);
*
- * On top of of these per-object locks using &ww_mutex there's also an overall
+ * If all that is needed is a single modeset lock, then the &struct
+ * drm_modeset_acquire_ctx is not needed and the locking can be simplified
+ * by passing a NULL instead of ctx in the drm_modeset_lock()
+ * call and, when done, by calling drm_modeset_unlock().
+ *
+ * On top of these per-object locks using &ww_mutex there's also an overall
* &drm_mode_config.mutex, for protecting everything else. Mostly this means
* probe state of connectors, and preventing hotplug add/removal of connectors.
*
@@ -313,11 +318,14 @@ EXPORT_SYMBOL(drm_modeset_lock_init);
* @lock: lock to take
* @ctx: acquire ctx
*
- * If ctx is not NULL, then its ww acquire context is used and the
+ * If @ctx is not NULL, then its ww acquire context is used and the
* lock will be tracked by the context and can be released by calling
* drm_modeset_drop_locks(). If -EDEADLK is returned, this means a
* deadlock scenario has been detected and it is an error to attempt
* to take any more locks without first calling drm_modeset_backoff().
+ *
+ * If @ctx is NULL then the function call behaves like a normal,
+ * non-nesting mutex_lock() call.
*/
int drm_modeset_lock(struct drm_modeset_lock *lock,
struct drm_modeset_acquire_ctx *ctx)
diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
index 2120f33..8dafbdf 100644
--- a/drivers/gpu/drm/drm_of.c
+++ b/drivers/gpu/drm/drm_of.c
@@ -160,8 +160,8 @@ int drm_of_component_probe(struct device *dev,
of_node_put(remote);
continue;
} else if (!of_device_is_available(remote->parent)) {
- dev_warn(dev, "parent device of %s is not available\n",
- remote->full_name);
+ dev_warn(dev, "parent device of %pOF is not available\n",
+ remote);
of_node_put(remote);
continue;
}
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c
index 1eb4fc3..1235c98 100644
--- a/drivers/gpu/drm/drm_pci.c
+++ b/drivers/gpu/drm/drm_pci.c
@@ -149,7 +149,6 @@ int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master)
master->unique_len = strlen(master->unique);
return 0;
}
-EXPORT_SYMBOL(drm_pci_set_busid);
static int drm_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *p)
{
@@ -281,20 +280,15 @@ err_free:
EXPORT_SYMBOL(drm_get_pci_dev);
/**
- * drm_pci_init - Register matching PCI devices with the DRM subsystem
+ * drm_legacy_pci_init - shadow-attach a legacy DRM PCI driver
* @driver: DRM device driver
* @pdriver: PCI device driver
*
- * Initializes a drm_device structures, registering the stubs and initializing
- * the AGP device.
- *
- * NOTE: This function is deprecated. Modern modesetting drm drivers should use
- * pci_register_driver() directly, this function only provides shadow-binding
- * support for old legacy drivers on top of that core pci function.
+ * This is only used by legacy dri1 drivers and deprecated.
*
* Return: 0 on success or a negative error code on failure.
*/
-int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
+int drm_legacy_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
{
struct pci_dev *pdev = NULL;
const struct pci_device_id *pid;
@@ -302,8 +296,8 @@ int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
DRM_DEBUG("\n");
- if (!(driver->driver_features & DRIVER_LEGACY))
- return pci_register_driver(pdriver);
+ if (WARN_ON(!(driver->driver_features & DRIVER_LEGACY)))
+ return -EINVAL;
/* If not using KMS, fall back to stealth mode manual scanning. */
INIT_LIST_HEAD(&driver->legacy_dev_list);
@@ -330,6 +324,7 @@ int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
}
return 0;
}
+EXPORT_SYMBOL(drm_legacy_pci_init);
int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *mask)
{
@@ -391,11 +386,6 @@ EXPORT_SYMBOL(drm_pcie_get_max_link_width);
#else
-int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
-{
- return -1;
-}
-
void drm_pci_agp_destroy(struct drm_device *dev) {}
int drm_irq_by_busid(struct drm_device *dev, void *data,
@@ -405,27 +395,21 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
}
#endif
-EXPORT_SYMBOL(drm_pci_init);
-
/**
- * drm_pci_exit - Unregister matching PCI devices from the DRM subsystem
+ * drm_legacy_pci_exit - unregister shadow-attach legacy DRM driver
* @driver: DRM device driver
* @pdriver: PCI device driver
*
- * Unregisters one or more devices matched by a PCI driver from the DRM
- * subsystem.
- *
- * NOTE: This function is deprecated. Modern modesetting drm drivers should use
- * pci_unregister_driver() directly, this function only provides shadow-binding
- * support for old legacy drivers on top of that core pci function.
+ * Unregister a DRM driver shadow-attached through drm_legacy_pci_init(). This
+ * is deprecated and only used by dri1 drivers.
*/
-void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver)
+void drm_legacy_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver)
{
struct drm_device *dev, *tmp;
DRM_DEBUG("\n");
if (!(driver->driver_features & DRIVER_LEGACY)) {
- pci_unregister_driver(pdriver);
+ WARN_ON(1);
} else {
list_for_each_entry_safe(dev, tmp, &driver->legacy_dev_list,
legacy_dev_list) {
@@ -435,4 +419,4 @@ void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver)
}
DRM_INFO("Module unloaded\n");
}
-EXPORT_SYMBOL(drm_pci_exit);
+EXPORT_SYMBOL(drm_legacy_pci_exit);
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index e40c12f..7a00351 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -62,6 +62,87 @@ static unsigned int drm_num_planes(struct drm_device *dev)
return num;
}
+static inline u32 *
+formats_ptr(struct drm_format_modifier_blob *blob)
+{
+ return (u32 *)(((char *)blob) + blob->formats_offset);
+}
+
+static inline struct drm_format_modifier *
+modifiers_ptr(struct drm_format_modifier_blob *blob)
+{
+ return (struct drm_format_modifier *)(((char *)blob) + blob->modifiers_offset);
+}
+
+static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane)
+{
+ const struct drm_mode_config *config = &dev->mode_config;
+ struct drm_property_blob *blob;
+ struct drm_format_modifier *mod;
+ size_t blob_size, formats_size, modifiers_size;
+ struct drm_format_modifier_blob *blob_data;
+ unsigned int i, j;
+
+ formats_size = sizeof(__u32) * plane->format_count;
+ if (WARN_ON(!formats_size)) {
+ /* 0 formats are never expected */
+ return 0;
+ }
+
+ modifiers_size =
+ sizeof(struct drm_format_modifier) * plane->modifier_count;
+
+ blob_size = sizeof(struct drm_format_modifier_blob);
+ /* Modifiers offset is a pointer to a struct with a 64 bit field so it
+ * should be naturally aligned to 8B.
+ */
+ BUILD_BUG_ON(sizeof(struct drm_format_modifier_blob) % 8);
+ blob_size += ALIGN(formats_size, 8);
+ blob_size += modifiers_size;
+
+ blob = drm_property_create_blob(dev, blob_size, NULL);
+ if (IS_ERR(blob))
+ return -1;
+
+ blob_data = (struct drm_format_modifier_blob *)blob->data;
+ blob_data->version = FORMAT_BLOB_CURRENT;
+ blob_data->count_formats = plane->format_count;
+ blob_data->formats_offset = sizeof(struct drm_format_modifier_blob);
+ blob_data->count_modifiers = plane->modifier_count;
+
+ blob_data->modifiers_offset =
+ ALIGN(blob_data->formats_offset + formats_size, 8);
+
+ memcpy(formats_ptr(blob_data), plane->format_types, formats_size);
+
+ /* If we can't determine support, just bail */
+ if (!plane->funcs->format_mod_supported)
+ goto done;
+
+ mod = modifiers_ptr(blob_data);
+ for (i = 0; i < plane->modifier_count; i++) {
+ for (j = 0; j < plane->format_count; j++) {
+ if (plane->funcs->format_mod_supported(plane,
+ plane->format_types[j],
+ plane->modifiers[i])) {
+
+ mod->formats |= 1ULL << j;
+ }
+ }
+
+ mod->modifier = plane->modifiers[i];
+ mod->offset = 0;
+ mod->pad = 0;
+ mod++;
+ }
+
+done:
+ drm_object_attach_property(&plane->base, config->modifiers_property,
+ blob->base.id);
+
+ return 0;
+}
+
/**
* drm_universal_plane_init - Initialize a new universal plane object
* @dev: DRM device
@@ -70,6 +151,8 @@ static unsigned int drm_num_planes(struct drm_device *dev)
* @funcs: callbacks for the new plane
* @formats: array of supported formats (DRM_FORMAT\_\*)
* @format_count: number of elements in @formats
+ * @format_modifiers: array of struct drm_format modifiers terminated by
+ * DRM_FORMAT_MOD_INVALID
* @type: type of plane (overlay, primary, cursor)
* @name: printf style format string for the plane name, or NULL for default name
*
@@ -82,10 +165,12 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
uint32_t possible_crtcs,
const struct drm_plane_funcs *funcs,
const uint32_t *formats, unsigned int format_count,
+ const uint64_t *format_modifiers,
enum drm_plane_type type,
const char *name, ...)
{
struct drm_mode_config *config = &dev->mode_config;
+ unsigned int format_modifier_count = 0;
int ret;
ret = drm_mode_object_add(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
@@ -105,6 +190,31 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
return -ENOMEM;
}
+ /*
+ * First driver to need more than 64 formats needs to fix this. Each
+ * format is encoded as a bit and the current code only supports a u64.
+ */
+ if (WARN_ON(format_count > 64))
+ return -EINVAL;
+
+ if (format_modifiers) {
+ const uint64_t *temp_modifiers = format_modifiers;
+ while (*temp_modifiers++ != DRM_FORMAT_MOD_INVALID)
+ format_modifier_count++;
+ }
+
+ plane->modifier_count = format_modifier_count;
+ plane->modifiers = kmalloc_array(format_modifier_count,
+ sizeof(format_modifiers[0]),
+ GFP_KERNEL);
+
+ if (format_modifier_count && !plane->modifiers) {
+ DRM_DEBUG_KMS("out of memory when allocating plane\n");
+ kfree(plane->format_types);
+ drm_mode_object_unregister(dev, &plane->base);
+ return -ENOMEM;
+ }
+
if (name) {
va_list ap;
@@ -117,12 +227,15 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
}
if (!plane->name) {
kfree(plane->format_types);
+ kfree(plane->modifiers);
drm_mode_object_unregister(dev, &plane->base);
return -ENOMEM;
}
memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
plane->format_count = format_count;
+ memcpy(plane->modifiers, format_modifiers,
+ format_modifier_count * sizeof(format_modifiers[0]));
plane->possible_crtcs = possible_crtcs;
plane->type = type;
@@ -149,6 +262,9 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
drm_object_attach_property(&plane->base, config->prop_src_h, 0);
}
+ if (config->allow_fb_modifiers)
+ create_in_format_blob(dev, plane);
+
return 0;
}
EXPORT_SYMBOL(drm_universal_plane_init);
@@ -205,7 +321,8 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
type = is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
return drm_universal_plane_init(dev, plane, possible_crtcs, funcs,
- formats, format_count, type, NULL);
+ formats, format_count,
+ NULL, type, NULL);
}
EXPORT_SYMBOL(drm_plane_init);
@@ -224,6 +341,7 @@ void drm_plane_cleanup(struct drm_plane *plane)
drm_modeset_lock_fini(&plane->mutex);
kfree(plane->format_types);
+ kfree(plane->modifiers);
drm_mode_object_unregister(dev, &plane->base);
BUG_ON(list_empty(&plane->head));
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index 00e6832..904966c 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -528,6 +528,10 @@ retry:
if (mode->status == MODE_OK)
mode->status = drm_mode_validate_pipeline(mode,
connector);
+
+ if (mode->status == MODE_OK)
+ mode->status = drm_mode_validate_ycbcr420(mode,
+ connector);
}
prune:
diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c
index 3e88fa2..bc51282 100644
--- a/drivers/gpu/drm/drm_property.c
+++ b/drivers/gpu/drm/drm_property.c
@@ -709,6 +709,29 @@ err_created:
}
EXPORT_SYMBOL(drm_property_replace_global_blob);
+/**
+ * drm_property_replace_blob - replace a blob property
+ * @blob: a pointer to the member blob to be replaced
+ * @new_blob: the new blob to replace with
+ *
+ * Return: true if the blob was in fact replaced.
+ */
+bool drm_property_replace_blob(struct drm_property_blob **blob,
+ struct drm_property_blob *new_blob)
+{
+ struct drm_property_blob *old_blob = *blob;
+
+ if (old_blob == new_blob)
+ return false;
+
+ drm_property_blob_put(old_blob);
+ if (new_blob)
+ drm_property_blob_get(new_blob);
+ *blob = new_blob;
+ return true;
+}
+EXPORT_SYMBOL(drm_property_replace_blob);
+
int drm_mode_getblob_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
diff --git a/drivers/gpu/drm/drm_scdc_helper.c b/drivers/gpu/drm/drm_scdc_helper.c
index 3cd96a9..7d1b0f0 100644
--- a/drivers/gpu/drm/drm_scdc_helper.c
+++ b/drivers/gpu/drm/drm_scdc_helper.c
@@ -194,19 +194,26 @@ EXPORT_SYMBOL(drm_scdc_set_scrambling);
* @adapter: I2C adapter for DDC channel
* @set: ret or reset the high clock ratio
*
- * TMDS clock ratio calculations go like this:
- * TMDS character = 10 bit TMDS encoded value
- * TMDS character rate = The rate at which TMDS characters are transmitted(Mcsc)
- * TMDS bit rate = 10x TMDS character rate
- * As per the spec:
- * TMDS clock rate for pixel clock < 340 MHz = 1x the character rate
- * = 1/10 pixel clock rate
- * TMDS clock rate for pixel clock > 340 MHz = 0.25x the character rate
- * = 1/40 pixel clock rate
- *
- * Writes to the TMDS config register over SCDC channel, and:
- * sets TMDS clock ratio to 1/40 when set = 1
- * sets TMDS clock ratio to 1/10 when set = 0
+ *
+ * TMDS clock ratio calculations go like this:
+ * TMDS character = 10 bit TMDS encoded value
+ *
+ * TMDS character rate = The rate at which TMDS characters are
+ * transmitted (Mcsc)
+ *
+ * TMDS bit rate = 10x TMDS character rate
+ *
+ * As per the spec:
+ * TMDS clock rate for pixel clock < 340 MHz = 1x the character
+ * rate = 1/10 pixel clock rate
+ *
+ * TMDS clock rate for pixel clock > 340 MHz = 0.25x the character
+ * rate = 1/40 pixel clock rate
+ *
+ * Writes to the TMDS config register over SCDC channel, and:
+ * sets TMDS clock ratio to 1/40 when set = 1
+ *
+ * sets TMDS clock ratio to 1/10 when set = 0
*
* Returns:
* True if write is successful, false otherwise.
diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c b/drivers/gpu/drm/drm_simple_kms_helper.c
index e084f9f..dc9fd10 100644
--- a/drivers/gpu/drm/drm_simple_kms_helper.c
+++ b/drivers/gpu/drm/drm_simple_kms_helper.c
@@ -37,10 +37,18 @@ static const struct drm_encoder_funcs drm_simple_kms_encoder_funcs = {
static int drm_simple_kms_crtc_check(struct drm_crtc *crtc,
struct drm_crtc_state *state)
{
+ bool has_primary = state->plane_mask &
+ BIT(drm_plane_index(crtc->primary));
+
+ /* We always want to have an active plane with an active CRTC */
+ if (has_primary != state->enable)
+ return -EINVAL;
+
return drm_atomic_add_affected_planes(state->state, crtc);
}
-static void drm_simple_kms_crtc_enable(struct drm_crtc *crtc)
+static void drm_simple_kms_crtc_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct drm_simple_display_pipe *pipe;
@@ -51,7 +59,8 @@ static void drm_simple_kms_crtc_enable(struct drm_crtc *crtc)
pipe->funcs->enable(pipe, crtc->state);
}
-static void drm_simple_kms_crtc_disable(struct drm_crtc *crtc)
+static void drm_simple_kms_crtc_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct drm_simple_display_pipe *pipe;
@@ -64,8 +73,8 @@ static void drm_simple_kms_crtc_disable(struct drm_crtc *crtc)
static const struct drm_crtc_helper_funcs drm_simple_kms_crtc_helper_funcs = {
.atomic_check = drm_simple_kms_crtc_check,
- .disable = drm_simple_kms_crtc_disable,
- .enable = drm_simple_kms_crtc_enable,
+ .atomic_enable = drm_simple_kms_crtc_enable,
+ .atomic_disable = drm_simple_kms_crtc_disable,
};
static const struct drm_crtc_funcs drm_simple_kms_crtc_funcs = {
@@ -88,9 +97,6 @@ static int drm_simple_kms_plane_atomic_check(struct drm_plane *plane,
pipe = container_of(plane, struct drm_simple_display_pipe, plane);
crtc_state = drm_atomic_get_new_crtc_state(plane_state->state,
&pipe->crtc);
- if (crtc_state->enable != !!plane_state->crtc)
- return -EINVAL; /* plane must match crtc enable state */
-
if (!crtc_state->enable)
return 0; /* nothing to check when disabling or disabled */
@@ -193,6 +199,7 @@ EXPORT_SYMBOL(drm_simple_display_pipe_attach_bridge);
* @funcs: callbacks for the display pipe (optional)
* @formats: array of supported formats (DRM_FORMAT\_\*)
* @format_count: number of elements in @formats
+ * @format_modifiers: array of formats modifiers
* @connector: connector to attach and register (optional)
*
* Sets up a display pipeline which consist of a really simple
@@ -213,6 +220,7 @@ int drm_simple_display_pipe_init(struct drm_device *dev,
struct drm_simple_display_pipe *pipe,
const struct drm_simple_display_pipe_funcs *funcs,
const uint32_t *formats, unsigned int format_count,
+ const uint64_t *format_modifiers,
struct drm_connector *connector)
{
struct drm_encoder *encoder = &pipe->encoder;
@@ -227,6 +235,7 @@ int drm_simple_display_pipe_init(struct drm_device *dev,
ret = drm_universal_plane_init(dev, plane, 0,
&drm_simple_kms_plane_funcs,
formats, format_count,
+ format_modifiers,
DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 789ba0b..0422b8c 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -1,5 +1,7 @@
/*
* Copyright 2017 Red Hat
+ * Parts ported from amdgpu (fence wait code).
+ * Copyright 2016 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -31,6 +33,9 @@
* that contain an optional fence. The fence can be updated with a new
* fence, or be NULL.
*
+ * syncobj's can be waited upon, where it will wait for the underlying
+ * fence.
+ *
* syncobj's can be export to fd's and back, these fd's are opaque and
* have no other use case, except passing the syncobj between processes.
*
@@ -46,6 +51,7 @@
#include <linux/fs.h>
#include <linux/anon_inodes.h>
#include <linux/sync_file.h>
+#include <linux/sched/signal.h>
#include "drm_internal.h"
#include <drm/drm_syncobj.h>
@@ -75,6 +81,75 @@ struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private,
}
EXPORT_SYMBOL(drm_syncobj_find);
+static void drm_syncobj_add_callback_locked(struct drm_syncobj *syncobj,
+ struct drm_syncobj_cb *cb,
+ drm_syncobj_func_t func)
+{
+ cb->func = func;
+ list_add_tail(&cb->node, &syncobj->cb_list);
+}
+
+static int drm_syncobj_fence_get_or_add_callback(struct drm_syncobj *syncobj,
+ struct dma_fence **fence,
+ struct drm_syncobj_cb *cb,
+ drm_syncobj_func_t func)
+{
+ int ret;
+
+ *fence = drm_syncobj_fence_get(syncobj);
+ if (*fence)
+ return 1;
+
+ spin_lock(&syncobj->lock);
+ /* We've already tried once to get a fence and failed. Now that we
+ * have the lock, try one more time just to be sure we don't add a
+ * callback when a fence has already been set.
+ */
+ if (syncobj->fence) {
+ *fence = dma_fence_get(syncobj->fence);
+ ret = 1;
+ } else {
+ *fence = NULL;
+ drm_syncobj_add_callback_locked(syncobj, cb, func);
+ ret = 0;
+ }
+ spin_unlock(&syncobj->lock);
+
+ return ret;
+}
+
+/**
+ * drm_syncobj_add_callback - adds a callback to syncobj::cb_list
+ * @syncobj: Sync object to which to add the callback
+ * @cb: Callback to add
+ * @func: Func to use when initializing the drm_syncobj_cb struct
+ *
+ * This adds a callback to be called next time the fence is replaced
+ */
+void drm_syncobj_add_callback(struct drm_syncobj *syncobj,
+ struct drm_syncobj_cb *cb,
+ drm_syncobj_func_t func)
+{
+ spin_lock(&syncobj->lock);
+ drm_syncobj_add_callback_locked(syncobj, cb, func);
+ spin_unlock(&syncobj->lock);
+}
+EXPORT_SYMBOL(drm_syncobj_add_callback);
+
+/**
+ * drm_syncobj_add_callback - removes a callback to syncobj::cb_list
+ * @syncobj: Sync object from which to remove the callback
+ * @cb: Callback to remove
+ */
+void drm_syncobj_remove_callback(struct drm_syncobj *syncobj,
+ struct drm_syncobj_cb *cb)
+{
+ spin_lock(&syncobj->lock);
+ list_del_init(&cb->node);
+ spin_unlock(&syncobj->lock);
+}
+EXPORT_SYMBOL(drm_syncobj_remove_callback);
+
/**
* drm_syncobj_replace_fence - replace fence in a sync object.
* @syncobj: Sync object to replace fence in
@@ -86,18 +161,75 @@ void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,
struct dma_fence *fence)
{
struct dma_fence *old_fence;
+ struct drm_syncobj_cb *cur, *tmp;
if (fence)
dma_fence_get(fence);
- old_fence = xchg(&syncobj->fence, fence);
+
+ spin_lock(&syncobj->lock);
+
+ old_fence = syncobj->fence;
+ syncobj->fence = fence;
+
+ if (fence != old_fence) {
+ list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node) {
+ list_del_init(&cur->node);
+ cur->func(syncobj, cur);
+ }
+ }
+
+ spin_unlock(&syncobj->lock);
dma_fence_put(old_fence);
}
EXPORT_SYMBOL(drm_syncobj_replace_fence);
-int drm_syncobj_fence_get(struct drm_file *file_private,
- u32 handle,
- struct dma_fence **fence)
+struct drm_syncobj_null_fence {
+ struct dma_fence base;
+ spinlock_t lock;
+};
+
+static const char *drm_syncobj_null_fence_get_name(struct dma_fence *fence)
+{
+ return "syncobjnull";
+}
+
+static bool drm_syncobj_null_fence_enable_signaling(struct dma_fence *fence)
+{
+ dma_fence_enable_sw_signaling(fence);
+ return !dma_fence_is_signaled(fence);
+}
+
+static const struct dma_fence_ops drm_syncobj_null_fence_ops = {
+ .get_driver_name = drm_syncobj_null_fence_get_name,
+ .get_timeline_name = drm_syncobj_null_fence_get_name,
+ .enable_signaling = drm_syncobj_null_fence_enable_signaling,
+ .wait = dma_fence_default_wait,
+ .release = NULL,
+};
+
+static int drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj)
+{
+ struct drm_syncobj_null_fence *fence;
+ fence = kzalloc(sizeof(*fence), GFP_KERNEL);
+ if (fence == NULL)
+ return -ENOMEM;
+
+ spin_lock_init(&fence->lock);
+ dma_fence_init(&fence->base, &drm_syncobj_null_fence_ops,
+ &fence->lock, 0, 0);
+ dma_fence_signal(&fence->base);
+
+ drm_syncobj_replace_fence(syncobj, &fence->base);
+
+ dma_fence_put(&fence->base);
+
+ return 0;
+}
+
+int drm_syncobj_find_fence(struct drm_file *file_private,
+ u32 handle,
+ struct dma_fence **fence)
{
struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle);
int ret = 0;
@@ -105,14 +237,14 @@ int drm_syncobj_fence_get(struct drm_file *file_private,
if (!syncobj)
return -ENOENT;
- *fence = dma_fence_get(syncobj->fence);
+ *fence = drm_syncobj_fence_get(syncobj);
if (!*fence) {
ret = -EINVAL;
}
drm_syncobj_put(syncobj);
return ret;
}
-EXPORT_SYMBOL(drm_syncobj_fence_get);
+EXPORT_SYMBOL(drm_syncobj_find_fence);
/**
* drm_syncobj_free - free a sync object.
@@ -125,13 +257,13 @@ void drm_syncobj_free(struct kref *kref)
struct drm_syncobj *syncobj = container_of(kref,
struct drm_syncobj,
refcount);
- dma_fence_put(syncobj->fence);
+ drm_syncobj_replace_fence(syncobj, NULL);
kfree(syncobj);
}
EXPORT_SYMBOL(drm_syncobj_free);
static int drm_syncobj_create(struct drm_file *file_private,
- u32 *handle)
+ u32 *handle, uint32_t flags)
{
int ret;
struct drm_syncobj *syncobj;
@@ -141,6 +273,16 @@ static int drm_syncobj_create(struct drm_file *file_private,
return -ENOMEM;
kref_init(&syncobj->refcount);
+ INIT_LIST_HEAD(&syncobj->cb_list);
+ spin_lock_init(&syncobj->lock);
+
+ if (flags & DRM_SYNCOBJ_CREATE_SIGNALED) {
+ ret = drm_syncobj_assign_null_handle(syncobj);
+ if (ret < 0) {
+ drm_syncobj_put(syncobj);
+ return ret;
+ }
+ }
idr_preload(GFP_KERNEL);
spin_lock(&file_private->syncobj_table_lock);
@@ -307,7 +449,7 @@ int drm_syncobj_export_sync_file(struct drm_file *file_private,
if (fd < 0)
return fd;
- ret = drm_syncobj_fence_get(file_private, handle, &fence);
+ ret = drm_syncobj_find_fence(file_private, handle, &fence);
if (ret)
goto err_put_fd;
@@ -330,7 +472,6 @@ err_put_fd:
}
/**
* drm_syncobj_open - initalizes syncobj file-private structures at devnode open time
- * @dev: drm_device which is being opened by userspace
* @file_private: drm file-private structure to set up
*
* Called at device open time, sets up the structure for handling refcounting
@@ -354,7 +495,6 @@ drm_syncobj_release_handle(int id, void *ptr, void *data)
/**
* drm_syncobj_release - release file-private sync object resources
- * @dev: drm_device which is being closed by userspace
* @file_private: drm file-private structure to clean up
*
* Called at close time when the filp is going away.
@@ -379,11 +519,11 @@ drm_syncobj_create_ioctl(struct drm_device *dev, void *data,
return -ENODEV;
/* no valid flags yet */
- if (args->flags)
+ if (args->flags & ~DRM_SYNCOBJ_CREATE_SIGNALED)
return -EINVAL;
return drm_syncobj_create(file_private,
- &args->handle);
+ &args->handle, args->flags);
}
int
@@ -449,3 +589,368 @@ drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, void *data,
return drm_syncobj_fd_to_handle(file_private, args->fd,
&args->handle);
}
+
+struct syncobj_wait_entry {
+ struct task_struct *task;
+ struct dma_fence *fence;
+ struct dma_fence_cb fence_cb;
+ struct drm_syncobj_cb syncobj_cb;
+};
+
+static void syncobj_wait_fence_func(struct dma_fence *fence,
+ struct dma_fence_cb *cb)
+{
+ struct syncobj_wait_entry *wait =
+ container_of(cb, struct syncobj_wait_entry, fence_cb);
+
+ wake_up_process(wait->task);
+}
+
+static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj,
+ struct drm_syncobj_cb *cb)
+{
+ struct syncobj_wait_entry *wait =
+ container_of(cb, struct syncobj_wait_entry, syncobj_cb);
+
+ /* This happens inside the syncobj lock */
+ wait->fence = dma_fence_get(syncobj->fence);
+ wake_up_process(wait->task);
+}
+
+static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
+ uint32_t count,
+ uint32_t flags,
+ signed long timeout,
+ uint32_t *idx)
+{
+ struct syncobj_wait_entry *entries;
+ struct dma_fence *fence;
+ signed long ret;
+ uint32_t signaled_count, i;
+
+ entries = kcalloc(count, sizeof(*entries), GFP_KERNEL);
+ if (!entries)
+ return -ENOMEM;
+
+ /* Walk the list of sync objects and initialize entries. We do
+ * this up-front so that we can properly return -EINVAL if there is
+ * a syncobj with a missing fence and then never have the chance of
+ * returning -EINVAL again.
+ */
+ signaled_count = 0;
+ for (i = 0; i < count; ++i) {
+ entries[i].task = current;
+ entries[i].fence = drm_syncobj_fence_get(syncobjs[i]);
+ if (!entries[i].fence) {
+ if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) {
+ continue;
+ } else {
+ ret = -EINVAL;
+ goto cleanup_entries;
+ }
+ }
+
+ if (dma_fence_is_signaled(entries[i].fence)) {
+ if (signaled_count == 0 && idx)
+ *idx = i;
+ signaled_count++;
+ }
+ }
+
+ /* Initialize ret to the max of timeout and 1. That way, the
+ * default return value indicates a successful wait and not a
+ * timeout.
+ */
+ ret = max_t(signed long, timeout, 1);
+
+ if (signaled_count == count ||
+ (signaled_count > 0 &&
+ !(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL)))
+ goto cleanup_entries;
+
+ /* There's a very annoying laxness in the dma_fence API here, in
+ * that backends are not required to automatically report when a
+ * fence is signaled prior to fence->ops->enable_signaling() being
+ * called. So here if we fail to match signaled_count, we need to
+ * fallthough and try a 0 timeout wait!
+ */
+
+ if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) {
+ for (i = 0; i < count; ++i) {
+ drm_syncobj_fence_get_or_add_callback(syncobjs[i],
+ &entries[i].fence,
+ &entries[i].syncobj_cb,
+ syncobj_wait_syncobj_func);
+ }
+ }
+
+ do {
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ signaled_count = 0;
+ for (i = 0; i < count; ++i) {
+ fence = entries[i].fence;
+ if (!fence)
+ continue;
+
+ if (dma_fence_is_signaled(fence) ||
+ (!entries[i].fence_cb.func &&
+ dma_fence_add_callback(fence,
+ &entries[i].fence_cb,
+ syncobj_wait_fence_func))) {
+ /* The fence has been signaled */
+ if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL) {
+ signaled_count++;
+ } else {
+ if (idx)
+ *idx = i;
+ goto done_waiting;
+ }
+ }
+ }
+
+ if (signaled_count == count)
+ goto done_waiting;
+
+ if (timeout == 0) {
+ /* If we are doing a 0 timeout wait and we got
+ * here, then we just timed out.
+ */
+ ret = 0;
+ goto done_waiting;
+ }
+
+ ret = schedule_timeout(ret);
+
+ if (ret > 0 && signal_pending(current))
+ ret = -ERESTARTSYS;
+ } while (ret > 0);
+
+done_waiting:
+ __set_current_state(TASK_RUNNING);
+
+cleanup_entries:
+ for (i = 0; i < count; ++i) {
+ if (entries[i].syncobj_cb.func)
+ drm_syncobj_remove_callback(syncobjs[i],
+ &entries[i].syncobj_cb);
+ if (entries[i].fence_cb.func)
+ dma_fence_remove_callback(entries[i].fence,
+ &entries[i].fence_cb);
+ dma_fence_put(entries[i].fence);
+ }
+ kfree(entries);
+
+ return ret;
+}
+
+/**
+ * drm_timeout_abs_to_jiffies - calculate jiffies timeout from absolute value
+ *
+ * @timeout_nsec: timeout nsec component in ns, 0 for poll
+ *
+ * Calculate the timeout in jiffies from an absolute time in sec/nsec.
+ */
+static signed long drm_timeout_abs_to_jiffies(int64_t timeout_nsec)
+{
+ ktime_t abs_timeout, now;
+ u64 timeout_ns, timeout_jiffies64;
+
+ /* make 0 timeout means poll - absolute 0 doesn't seem valid */
+ if (timeout_nsec == 0)
+ return 0;
+
+ abs_timeout = ns_to_ktime(timeout_nsec);
+ now = ktime_get();
+
+ if (!ktime_after(abs_timeout, now))
+ return 0;
+
+ timeout_ns = ktime_to_ns(ktime_sub(abs_timeout, now));
+
+ timeout_jiffies64 = nsecs_to_jiffies64(timeout_ns);
+ /* clamp timeout to avoid infinite timeout */
+ if (timeout_jiffies64 >= MAX_SCHEDULE_TIMEOUT - 1)
+ return MAX_SCHEDULE_TIMEOUT - 1;
+
+ return timeout_jiffies64 + 1;
+}
+
+static int drm_syncobj_array_wait(struct drm_device *dev,
+ struct drm_file *file_private,
+ struct drm_syncobj_wait *wait,
+ struct drm_syncobj **syncobjs)
+{
+ signed long timeout = drm_timeout_abs_to_jiffies(wait->timeout_nsec);
+ signed long ret = 0;
+ uint32_t first = ~0;
+
+ ret = drm_syncobj_array_wait_timeout(syncobjs,
+ wait->count_handles,
+ wait->flags,
+ timeout, &first);
+ if (ret < 0)
+ return ret;
+
+ wait->first_signaled = first;
+ if (ret == 0)
+ return -ETIME;
+ return 0;
+}
+
+static int drm_syncobj_array_find(struct drm_file *file_private,
+ void *user_handles, uint32_t count_handles,
+ struct drm_syncobj ***syncobjs_out)
+{
+ uint32_t i, *handles;
+ struct drm_syncobj **syncobjs;
+ int ret;
+
+ handles = kmalloc_array(count_handles, sizeof(*handles), GFP_KERNEL);
+ if (handles == NULL)
+ return -ENOMEM;
+
+ if (copy_from_user(handles, user_handles,
+ sizeof(uint32_t) * count_handles)) {
+ ret = -EFAULT;
+ goto err_free_handles;
+ }
+
+ syncobjs = kmalloc_array(count_handles, sizeof(*syncobjs), GFP_KERNEL);
+ if (syncobjs == NULL) {
+ ret = -ENOMEM;
+ goto err_free_handles;
+ }
+
+ for (i = 0; i < count_handles; i++) {
+ syncobjs[i] = drm_syncobj_find(file_private, handles[i]);
+ if (!syncobjs[i]) {
+ ret = -ENOENT;
+ goto err_put_syncobjs;
+ }
+ }
+
+ kfree(handles);
+ *syncobjs_out = syncobjs;
+ return 0;
+
+err_put_syncobjs:
+ while (i-- > 0)
+ drm_syncobj_put(syncobjs[i]);
+ kfree(syncobjs);
+err_free_handles:
+ kfree(handles);
+
+ return ret;
+}
+
+static void drm_syncobj_array_free(struct drm_syncobj **syncobjs,
+ uint32_t count)
+{
+ uint32_t i;
+ for (i = 0; i < count; i++)
+ drm_syncobj_put(syncobjs[i]);
+ kfree(syncobjs);
+}
+
+int
+drm_syncobj_wait_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_private)
+{
+ struct drm_syncobj_wait *args = data;
+ struct drm_syncobj **syncobjs;
+ int ret = 0;
+
+ if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
+ return -ENODEV;
+
+ if (args->flags & ~(DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL |
+ DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT))
+ return -EINVAL;
+
+ if (args->count_handles == 0)
+ return -EINVAL;
+
+ ret = drm_syncobj_array_find(file_private,
+ u64_to_user_ptr(args->handles),
+ args->count_handles,
+ &syncobjs);
+ if (ret < 0)
+ return ret;
+
+ ret = drm_syncobj_array_wait(dev, file_private,
+ args, syncobjs);
+
+ drm_syncobj_array_free(syncobjs, args->count_handles);
+
+ return ret;
+}
+
+int
+drm_syncobj_reset_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_private)
+{
+ struct drm_syncobj_array *args = data;
+ struct drm_syncobj **syncobjs;
+ uint32_t i;
+ int ret;
+
+ if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
+ return -ENODEV;
+
+ if (args->pad != 0)
+ return -EINVAL;
+
+ if (args->count_handles == 0)
+ return -EINVAL;
+
+ ret = drm_syncobj_array_find(file_private,
+ u64_to_user_ptr(args->handles),
+ args->count_handles,
+ &syncobjs);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < args->count_handles; i++)
+ drm_syncobj_replace_fence(syncobjs[i], NULL);
+
+ drm_syncobj_array_free(syncobjs, args->count_handles);
+
+ return 0;
+}
+
+int
+drm_syncobj_signal_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_private)
+{
+ struct drm_syncobj_array *args = data;
+ struct drm_syncobj **syncobjs;
+ uint32_t i;
+ int ret;
+
+ if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
+ return -ENODEV;
+
+ if (args->pad != 0)
+ return -EINVAL;
+
+ if (args->count_handles == 0)
+ return -EINVAL;
+
+ ret = drm_syncobj_array_find(file_private,
+ u64_to_user_ptr(args->handles),
+ args->count_handles,
+ &syncobjs);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < args->count_handles; i++) {
+ ret = drm_syncobj_assign_null_handle(syncobjs[i]);
+ if (ret < 0)
+ break;
+ }
+
+ drm_syncobj_array_free(syncobjs, args->count_handles);
+
+ return ret;
+}
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index e9f33cd..70f2b95 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -31,6 +31,41 @@
#include "drm_trace.h"
#include "drm_internal.h"
+/**
+ * DOC: vblank handling
+ *
+ * Vertical blanking plays a major role in graphics rendering. To achieve
+ * tear-free display, users must synchronize page flips and/or rendering to
+ * vertical blanking. The DRM API offers ioctls to perform page flips
+ * synchronized to vertical blanking and wait for vertical blanking.
+ *
+ * The DRM core handles most of the vertical blanking management logic, which
+ * involves filtering out spurious interrupts, keeping race-free blanking
+ * counters, coping with counter wrap-around and resets and keeping use counts.
+ * It relies on the driver to generate vertical blanking interrupts and
+ * optionally provide a hardware vertical blanking counter.
+ *
+ * Drivers must initialize the vertical blanking handling core with a call to
+ * drm_vblank_init(). Minimally, a driver needs to implement
+ * &drm_crtc_funcs.enable_vblank and &drm_crtc_funcs.disable_vblank plus call
+ * drm_crtc_handle_vblank() in it's vblank interrupt handler for working vblank
+ * support.
+ *
+ * Vertical blanking interrupts can be enabled by the DRM core or by drivers
+ * themselves (for instance to handle page flipping operations). The DRM core
+ * maintains a vertical blanking use count to ensure that the interrupts are not
+ * disabled while a user still needs them. To increment the use count, drivers
+ * call drm_crtc_vblank_get() and release the vblank reference again with
+ * drm_crtc_vblank_put(). In between these two calls vblank interrupts are
+ * guaranteed to be enabled.
+ *
+ * On many hardware disabling the vblank interrupt cannot be done in a race-free
+ * manner, see &drm_driver.vblank_disable_immediate and
+ * &drm_driver.max_vblank_count. In that case the vblank core only disables the
+ * vblanks after a timer has expired, which can be configured through the
+ * ``vblankoffdelay`` module parameter.
+ */
+
/* Retry timestamp calculation up to 3 times to satisfy
* drm_timestamp_precision before giving up.
*/
@@ -259,16 +294,17 @@ static u32 drm_vblank_count(struct drm_device *dev, unsigned int pipe)
}
/**
- * drm_accurate_vblank_count - retrieve the master vblank counter
+ * drm_crtc_accurate_vblank_count - retrieve the master vblank counter
* @crtc: which counter to retrieve
*
- * This function is similar to @drm_crtc_vblank_count but this
- * function interpolates to handle a race with vblank irq's.
+ * This function is similar to drm_crtc_vblank_count() but this function
+ * interpolates to handle a race with vblank interrupts using the high precision
+ * timestamping support.
*
- * This is mostly useful for hardware that can obtain the scanout
- * position, but doesn't have a frame counter.
+ * This is mostly useful for hardware that can obtain the scanout position, but
+ * doesn't have a hardware frame counter.
*/
-u32 drm_accurate_vblank_count(struct drm_crtc *crtc)
+u32 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
unsigned int pipe = drm_crtc_index(crtc);
@@ -287,7 +323,7 @@ u32 drm_accurate_vblank_count(struct drm_crtc *crtc)
return vblank;
}
-EXPORT_SYMBOL(drm_accurate_vblank_count);
+EXPORT_SYMBOL(drm_crtc_accurate_vblank_count);
static void __disable_vblank(struct drm_device *dev, unsigned int pipe)
{
@@ -358,15 +394,6 @@ static void vblank_disable_fn(unsigned long arg)
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
}
-/**
- * drm_vblank_cleanup - cleanup vblank support
- * @dev: DRM device
- *
- * This function cleans up any resources allocated in drm_vblank_init.
- *
- * Drivers which don't use drm_irq_install() need to set &drm_device.irq_enabled
- * themselves, to signal to the DRM core that vblank interrupts are enabled.
- */
void drm_vblank_cleanup(struct drm_device *dev)
{
unsigned int pipe;
@@ -388,7 +415,6 @@ void drm_vblank_cleanup(struct drm_device *dev)
dev->num_crtcs = 0;
}
-EXPORT_SYMBOL(drm_vblank_cleanup);
/**
* drm_vblank_init - initialize vblank support
@@ -396,6 +422,8 @@ EXPORT_SYMBOL(drm_vblank_cleanup);
* @num_crtcs: number of CRTCs supported by @dev
*
* This function initializes vblank support for @num_crtcs display pipelines.
+ * Cleanup is handled by the DRM core, or through calling drm_dev_fini() for
+ * drivers with a &drm_driver.release callback.
*
* Returns:
* Zero on success or a negative error code on failure.
@@ -468,11 +496,11 @@ EXPORT_SYMBOL(drm_crtc_vblank_waitqueue);
* @crtc: drm_crtc whose timestamp constants should be updated.
* @mode: display mode containing the scanout timings
*
- * Calculate and store various constants which are later
- * needed by vblank and swap-completion timestamping, e.g,
- * by drm_calc_vbltimestamp_from_scanoutpos(). They are
- * derived from CRTC's true scanout timing, so they take
- * things like panel scaling or other adjustments into account.
+ * Calculate and store various constants which are later needed by vblank and
+ * swap-completion timestamping, e.g, by
+ * drm_calc_vbltimestamp_from_scanoutpos(). They are derived from CRTC's true
+ * scanout timing, so they take things like panel scaling or other adjustments
+ * into account.
*/
void drm_calc_timestamping_constants(struct drm_crtc *crtc,
const struct drm_display_mode *mode)
@@ -535,25 +563,14 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants);
* if flag is set.
*
* Implements calculation of exact vblank timestamps from given drm_display_mode
- * timings and current video scanout position of a CRTC. This can be called from
- * within get_vblank_timestamp() implementation of a kms driver to implement the
- * actual timestamping.
- *
- * Should return timestamps conforming to the OML_sync_control OpenML
- * extension specification. The timestamp corresponds to the end of
- * the vblank interval, aka start of scanout of topmost-leftmost display
- * pixel in the following video frame.
+ * timings and current video scanout position of a CRTC. This can be directly
+ * used as the &drm_driver.get_vblank_timestamp implementation of a kms driver
+ * if &drm_driver.get_scanout_position is implemented.
*
- * Requires support for optional dev->driver->get_scanout_position()
- * in kms driver, plus a bit of setup code to provide a drm_display_mode
- * that corresponds to the true scanout timing.
- *
- * The current implementation only handles standard video modes. It
- * returns as no operation if a doublescan or interlaced video mode is
- * active. Higher level code is expected to handle this.
- *
- * This function can be used to implement the &drm_driver.get_vblank_timestamp
- * directly, if the driver implements the &drm_driver.get_scanout_position hook.
+ * The current implementation only handles standard video modes. For double scan
+ * and interlaced modes the driver is supposed to adjust the hardware mode
+ * (taken from &drm_crtc_state.adjusted mode for atomic modeset drivers) to
+ * match the scanout position reported.
*
* Note that atomic drivers must call drm_calc_timestamping_constants() before
* enabling a CRTC. The atomic helpers already take care of that in
@@ -738,7 +755,9 @@ drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe,
*
* Fetches the "cooked" vblank count value that represents the number of
* vblank events since the system was booted, including lost events due to
- * modesetting activity.
+ * modesetting activity. Note that this timer isn't correct against a racing
+ * vblank interrupt (since it only reports the software vblank counter), see
+ * drm_crtc_accurate_vblank_count() for such use-cases.
*
* Returns:
* The software vblank counter.
@@ -749,20 +768,6 @@ u32 drm_crtc_vblank_count(struct drm_crtc *crtc)
}
EXPORT_SYMBOL(drm_crtc_vblank_count);
-/**
- * drm_vblank_count_and_time - retrieve "cooked" vblank counter value and the
- * system timestamp corresponding to that vblank counter value.
- * @dev: DRM device
- * @pipe: index of CRTC whose counter to retrieve
- * @vblanktime: Pointer to struct timeval to receive the vblank timestamp.
- *
- * Fetches the "cooked" vblank count value that represents the number of
- * vblank events since the system was booted, including lost events due to
- * modesetting activity. Returns corresponding system timestamp of the time
- * of the vblank interval that corresponds to the current vblank counter value.
- *
- * This is the legacy version of drm_crtc_vblank_count_and_time().
- */
static u32 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe,
struct timeval *vblanktime)
{
@@ -831,7 +836,7 @@ static void send_vblank_event(struct drm_device *dev,
* NOTE: Drivers using this to send out the &drm_crtc_state.event as part of an
* atomic commit must ensure that the next vblank happens at exactly the same
* time as the atomic commit is committed to the hardware. This function itself
- * does **not** protect again the next vblank interrupt racing with either this
+ * does **not** protect against the next vblank interrupt racing with either this
* function call or the atomic commit operation. A possible sequence could be:
*
* 1. Driver commits new hardware state into vblank-synchronized registers.
@@ -852,8 +857,8 @@ static void send_vblank_event(struct drm_device *dev,
* handler by calling drm_crtc_send_vblank_event() and make sure that there's no
* possible race with the hardware committing the atomic update.
*
- * Caller must hold event lock. Caller must also hold a vblank reference for
- * the event @e, which will be dropped when the next vblank arrives.
+ * Caller must hold a vblank reference for the event @e, which will be dropped
+ * when the next vblank arrives.
*/
void drm_crtc_arm_vblank_event(struct drm_crtc *crtc,
struct drm_pending_vblank_event *e)
@@ -913,14 +918,6 @@ static int __enable_vblank(struct drm_device *dev, unsigned int pipe)
return dev->driver->enable_vblank(dev, pipe);
}
-/**
- * drm_vblank_enable - enable the vblank interrupt on a CRTC
- * @dev: DRM device
- * @pipe: CRTC index
- *
- * Returns:
- * Zero on success or a negative error code on failure.
- */
static int drm_vblank_enable(struct drm_device *dev, unsigned int pipe)
{
struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
@@ -958,19 +955,6 @@ static int drm_vblank_enable(struct drm_device *dev, unsigned int pipe)
return ret;
}
-/**
- * drm_vblank_get - get a reference count on vblank events
- * @dev: DRM device
- * @pipe: index of CRTC to own
- *
- * Acquire a reference count on vblank events to avoid having them disabled
- * while in use.
- *
- * This is the legacy version of drm_crtc_vblank_get().
- *
- * Returns:
- * Zero on success or a negative error code on failure.
- */
static int drm_vblank_get(struct drm_device *dev, unsigned int pipe)
{
struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
@@ -1014,16 +998,6 @@ int drm_crtc_vblank_get(struct drm_crtc *crtc)
}
EXPORT_SYMBOL(drm_crtc_vblank_get);
-/**
- * drm_vblank_put - release ownership of vblank events
- * @dev: DRM device
- * @pipe: index of CRTC to release
- *
- * Release ownership of a given vblank counter, turning off interrupts
- * if possible. Disable interrupts after drm_vblank_offdelay milliseconds.
- *
- * This is the legacy version of drm_crtc_vblank_put().
- */
static void drm_vblank_put(struct drm_device *dev, unsigned int pipe)
{
struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
@@ -1067,6 +1041,8 @@ EXPORT_SYMBOL(drm_crtc_vblank_put);
* This waits for one vblank to pass on @pipe, using the irq driver interfaces.
* It is a failure to call this when the vblank irq for @pipe is disabled, e.g.
* due to lack of driver support or because the crtc is off.
+ *
+ * This is the legacy version of drm_crtc_wait_one_vblank().
*/
void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe)
{
@@ -1116,7 +1092,7 @@ EXPORT_SYMBOL(drm_crtc_wait_one_vblank);
* stored so that drm_vblank_on can restore it again.
*
* Drivers must use this function when the hardware vblank counter can get
- * reset, e.g. when suspending.
+ * reset, e.g. when suspending or disabling the @crtc in general.
*/
void drm_crtc_vblank_off(struct drm_crtc *crtc)
{
@@ -1184,6 +1160,8 @@ EXPORT_SYMBOL(drm_crtc_vblank_off);
* drm_crtc_vblank_on() functions. The difference compared to
* drm_crtc_vblank_off() is that this function doesn't save the vblank counter
* and hence doesn't need to call any driver hooks.
+ *
+ * This is useful for recovering driver state e.g. on driver load, or on resume.
*/
void drm_crtc_vblank_reset(struct drm_crtc *crtc)
{
@@ -1212,9 +1190,10 @@ EXPORT_SYMBOL(drm_crtc_vblank_reset);
* @crtc: CRTC in question
*
* This functions restores the vblank interrupt state captured with
- * drm_crtc_vblank_off() again. Note that calls to drm_crtc_vblank_on() and
- * drm_crtc_vblank_off() can be unbalanced and so can also be unconditionally called
- * in driver load code to reflect the current hardware state of the crtc.
+ * drm_crtc_vblank_off() again and is generally called when enabling @crtc. Note
+ * that calls to drm_crtc_vblank_on() and drm_crtc_vblank_off() can be
+ * unbalanced and so can also be unconditionally called in driver load code to
+ * reflect the current hardware state of the crtc.
*/
void drm_crtc_vblank_on(struct drm_crtc *crtc)
{
@@ -1299,8 +1278,8 @@ static void drm_legacy_vblank_post_modeset(struct drm_device *dev,
}
}
-int drm_legacy_modeset_ctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
+int drm_legacy_modeset_ctl_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
struct drm_modeset_ctl *modeset = data;
unsigned int pipe;
@@ -1419,22 +1398,8 @@ static bool drm_wait_vblank_is_query(union drm_wait_vblank *vblwait)
_DRM_VBLANK_NEXTONMISS));
}
-/*
- * Wait for VBLANK.
- *
- * \param inode device inode.
- * \param file_priv DRM file private.
- * \param cmd command.
- * \param data user argument, pointing to a drm_wait_vblank structure.
- * \return zero on success or a negative number on failure.
- *
- * This function enables the vblank interrupt on the pipe requested, then
- * sleeps waiting for the requested sequence number to occur, and drops
- * the vblank interrupt refcount afterwards. (vblank IRQ disable follows that
- * after a timeout with no further vblank waits scheduled).
- */
-int drm_wait_vblank(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
+int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
struct drm_vblank_crtc *vblank;
union drm_wait_vblank *vblwait = data;
diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c
index 1170b32..2660543 100644
--- a/drivers/gpu/drm/drm_vm.c
+++ b/drivers/gpu/drm/drm_vm.c
@@ -40,6 +40,7 @@
#include <linux/efi.h>
#include <linux/slab.h>
#endif
+#include <linux/mem_encrypt.h>
#include <asm/pgtable.h>
#include "drm_internal.h"
#include "drm_legacy.h"
@@ -58,6 +59,9 @@ static pgprot_t drm_io_prot(struct drm_local_map *map,
{
pgprot_t tmp = vm_get_page_prot(vma->vm_flags);
+ /* We don't want graphics memory to be mapped encrypted */
+ tmp = pgprot_decrypted(tmp);
+
#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__)
if (map->type == _DRM_REGISTERS && !(map->flags & _DRM_WRITE_COMBINING))
tmp = pgprot_noncached(tmp);
@@ -631,7 +635,7 @@ int drm_legacy_mmap(struct file *filp, struct vm_area_struct *vma)
struct drm_device *dev = priv->minor->dev;
int ret;
- if (drm_device_is_unplugged(dev))
+ if (drm_dev_is_unplugged(dev))
return -ENODEV;
mutex_lock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/etnaviv/Kconfig b/drivers/gpu/drm/etnaviv/Kconfig
index 71cee4e..38b477b 100644
--- a/drivers/gpu/drm/etnaviv/Kconfig
+++ b/drivers/gpu/drm/etnaviv/Kconfig
@@ -10,6 +10,8 @@ config DRM_ETNAVIV
select IOMMU_API
select IOMMU_SUPPORT
select WANT_DEV_COREDUMP
+ select CMA if HAVE_DMA_CONTIGUOUS
+ select DMA_CMA if HAVE_DMA_CONTIGUOUS
help
DRM driver for Vivante GPUs.
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
index 91e17ae..2cb4773 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
@@ -316,7 +316,7 @@ static int etnaviv_ioctl_gem_cpu_prep(struct drm_device *dev, void *data,
ret = etnaviv_gem_cpu_prep(obj, args->op, &TS(args->timeout));
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -337,7 +337,7 @@ static int etnaviv_ioctl_gem_cpu_fini(struct drm_device *dev, void *data,
ret = etnaviv_gem_cpu_fini(obj);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -357,7 +357,7 @@ static int etnaviv_ioctl_gem_info(struct drm_device *dev, void *data,
return -ENOENT;
ret = etnaviv_gem_mmap_offset(obj, &args->offset);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -446,7 +446,7 @@ static int etnaviv_ioctl_gem_wait(struct drm_device *dev, void *data,
ret = etnaviv_gem_wait_bo(gpu, obj, timeout);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
index 9a3bea7..5a63459 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
@@ -68,7 +68,7 @@ static int etnaviv_gem_shmem_get_pages(struct etnaviv_gem_object *etnaviv_obj)
struct page **p = drm_gem_get_pages(&etnaviv_obj->base);
if (IS_ERR(p)) {
- dev_err(dev->dev, "could not get pages: %ld\n", PTR_ERR(p));
+ dev_dbg(dev->dev, "could not get pages: %ld\n", PTR_ERR(p));
return PTR_ERR(p);
}
@@ -265,7 +265,7 @@ void etnaviv_gem_mapping_reference(struct etnaviv_vram_mapping *mapping)
{
struct etnaviv_gem_object *etnaviv_obj = mapping->object;
- drm_gem_object_reference(&etnaviv_obj->base);
+ drm_gem_object_get(&etnaviv_obj->base);
mutex_lock(&etnaviv_obj->lock);
WARN_ON(mapping->use == 0);
@@ -282,7 +282,7 @@ void etnaviv_gem_mapping_unreference(struct etnaviv_vram_mapping *mapping)
mapping->use -= 1;
mutex_unlock(&etnaviv_obj->lock);
- drm_gem_object_unreference_unlocked(&etnaviv_obj->base);
+ drm_gem_object_put_unlocked(&etnaviv_obj->base);
}
struct etnaviv_vram_mapping *etnaviv_gem_mapping_get(
@@ -358,7 +358,7 @@ out:
return ERR_PTR(ret);
/* Take a reference on the object */
- drm_gem_object_reference(obj);
+ drm_gem_object_get(obj);
return mapping;
}
@@ -413,6 +413,16 @@ int etnaviv_gem_cpu_prep(struct drm_gem_object *obj, u32 op,
bool write = !!(op & ETNA_PREP_WRITE);
int ret;
+ if (!etnaviv_obj->sgt) {
+ void *ret;
+
+ mutex_lock(&etnaviv_obj->lock);
+ ret = etnaviv_gem_get_pages(etnaviv_obj);
+ mutex_unlock(&etnaviv_obj->lock);
+ if (IS_ERR(ret))
+ return PTR_ERR(ret);
+ }
+
if (op & ETNA_PREP_NOSYNC) {
if (!reservation_object_test_signaled_rcu(etnaviv_obj->resv,
write))
@@ -427,16 +437,6 @@ int etnaviv_gem_cpu_prep(struct drm_gem_object *obj, u32 op,
}
if (etnaviv_obj->flags & ETNA_BO_CACHED) {
- if (!etnaviv_obj->sgt) {
- void *ret;
-
- mutex_lock(&etnaviv_obj->lock);
- ret = etnaviv_gem_get_pages(etnaviv_obj);
- mutex_unlock(&etnaviv_obj->lock);
- if (IS_ERR(ret))
- return PTR_ERR(ret);
- }
-
dma_sync_sg_for_cpu(dev->dev, etnaviv_obj->sgt->sgl,
etnaviv_obj->sgt->nents,
etnaviv_op_to_dma_dir(op));
@@ -662,7 +662,8 @@ static struct drm_gem_object *__etnaviv_gem_new(struct drm_device *dev,
* going to pin these pages.
*/
mapping = obj->filp->f_mapping;
- mapping_set_gfp_mask(mapping, GFP_HIGHUSER);
+ mapping_set_gfp_mask(mapping, GFP_HIGHUSER |
+ __GFP_RETRY_MAYFAIL | __GFP_NOWARN);
}
if (ret)
@@ -671,7 +672,7 @@ static struct drm_gem_object *__etnaviv_gem_new(struct drm_device *dev,
return obj;
fail:
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ERR_PTR(ret);
}
@@ -688,14 +689,14 @@ int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file,
ret = etnaviv_gem_obj_add(dev, obj);
if (ret < 0) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
ret = drm_gem_handle_create(file, obj, handle);
/* drop reference from allocate - handle holds it now */
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -712,7 +713,7 @@ struct drm_gem_object *etnaviv_gem_new(struct drm_device *dev,
ret = etnaviv_gem_obj_add(dev, obj);
if (ret < 0) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ERR_PTR(ret);
}
@@ -800,7 +801,7 @@ static void __etnaviv_gem_userptr_get_pages(struct work_struct *_work)
}
mutex_unlock(&etnaviv_obj->lock);
- drm_gem_object_unreference_unlocked(&etnaviv_obj->base);
+ drm_gem_object_put_unlocked(&etnaviv_obj->base);
mmput(work->mm);
put_task_struct(work->task);
@@ -858,7 +859,7 @@ static int etnaviv_gem_userptr_get_pages(struct etnaviv_gem_object *etnaviv_obj)
}
get_task_struct(current);
- drm_gem_object_reference(&etnaviv_obj->base);
+ drm_gem_object_get(&etnaviv_obj->base);
work->mm = mm;
work->task = current;
@@ -924,6 +925,6 @@ int etnaviv_gem_new_userptr(struct drm_device *dev, struct drm_file *file,
ret = drm_gem_handle_create(file, &etnaviv_obj->base, handle);
unreference:
/* drop reference from allocate - handle holds it now */
- drm_gem_object_unreference_unlocked(&etnaviv_obj->base);
+ drm_gem_object_put_unlocked(&etnaviv_obj->base);
return ret;
}
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c
index e5da4f23..ae88472 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c
@@ -146,7 +146,7 @@ struct drm_gem_object *etnaviv_gem_prime_import_sg_table(struct drm_device *dev,
return &etnaviv_obj->base;
fail:
- drm_gem_object_unreference_unlocked(&etnaviv_obj->base);
+ drm_gem_object_put_unlocked(&etnaviv_obj->base);
return ERR_PTR(ret);
}
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
index 6463fc2..a7ff2e4 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
@@ -88,7 +88,7 @@ static int submit_lookup_objects(struct etnaviv_gem_submit *submit,
* Take a refcount on the object. The file table lock
* prevents the object_idr's refcount on this being dropped.
*/
- drm_gem_object_reference(obj);
+ drm_gem_object_get(obj);
submit->bos[i].obj = to_etnaviv_bo(obj);
}
@@ -291,7 +291,7 @@ static void submit_cleanup(struct etnaviv_gem_submit *submit)
struct etnaviv_gem_object *etnaviv_obj = submit->bos[i].obj;
submit_unlock_object(submit, i);
- drm_gem_object_unreference_unlocked(&etnaviv_obj->base);
+ drm_gem_object_put_unlocked(&etnaviv_obj->base);
}
ww_acquire_fini(&submit->ticket);
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
index ada45fd..fc9a6a8 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
@@ -1622,10 +1622,12 @@ static int etnaviv_gpu_bind(struct device *dev, struct device *master,
struct etnaviv_gpu *gpu = dev_get_drvdata(dev);
int ret;
- gpu->cooling = thermal_of_cooling_device_register(dev->of_node,
+ if (IS_ENABLED(CONFIG_THERMAL)) {
+ gpu->cooling = thermal_of_cooling_device_register(dev->of_node,
(char *)dev_name(dev), gpu, &cooling_ops);
- if (IS_ERR(gpu->cooling))
- return PTR_ERR(gpu->cooling);
+ if (IS_ERR(gpu->cooling))
+ return PTR_ERR(gpu->cooling);
+ }
#ifdef CONFIG_PM
ret = pm_runtime_get_sync(gpu->dev);
diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
index 5792ca8..730b8d9 100644
--- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
@@ -13,6 +13,7 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/component.h>
+#include <linux/iopoll.h>
#include <linux/mfd/syscon.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
@@ -33,9 +34,8 @@
#define WINDOWS_NR 3
#define MIN_FB_WIDTH_FOR_16WORD_BURST 128
-#define IFTYPE_I80 (1 << 0)
-#define I80_HW_TRG (1 << 1)
-#define IFTYPE_HDMI (1 << 2)
+#define I80_HW_TRG (1 << 0)
+#define IFTYPE_HDMI (1 << 1)
static const char * const decon_clks_name[] = {
"pclk",
@@ -57,6 +57,8 @@ struct decon_context {
struct regmap *sysreg;
struct clk *clks[ARRAY_SIZE(decon_clks_name)];
unsigned int irq;
+ unsigned int irq_vsync;
+ unsigned int irq_lcd_sys;
unsigned int te_irq;
unsigned long out_type;
int first_win;
@@ -90,7 +92,7 @@ static int decon_enable_vblank(struct exynos_drm_crtc *crtc)
u32 val;
val = VIDINTCON0_INTEN;
- if (ctx->out_type & IFTYPE_I80)
+ if (crtc->i80_mode)
val |= VIDINTCON0_FRAMEDONE;
else
val |= VIDINTCON0_INTFRMEN | VIDINTCON0_FRAMESEL_FP;
@@ -139,7 +141,7 @@ static u32 decon_get_frame_count(struct decon_context *ctx, bool end)
switch (status & (VIDCON1_VSTATUS_MASK | VIDCON1_I80_ACTIVE)) {
case VIDCON1_VSTATUS_VS:
- if (!(ctx->out_type & IFTYPE_I80))
+ if (!(ctx->crtc->i80_mode))
--frm;
break;
case VIDCON1_VSTATUS_BP:
@@ -166,7 +168,7 @@ static u32 decon_get_vblank_counter(struct exynos_drm_crtc *crtc)
static void decon_setup_trigger(struct decon_context *ctx)
{
- if (!(ctx->out_type & (IFTYPE_I80 | I80_HW_TRG)))
+ if (!ctx->crtc->i80_mode && !(ctx->out_type & I80_HW_TRG))
return;
if (!(ctx->out_type & I80_HW_TRG)) {
@@ -206,7 +208,7 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
val = VIDOUT_LCD_ON;
if (interlaced)
val |= VIDOUT_INTERLACE_EN_F;
- if (ctx->out_type & IFTYPE_I80) {
+ if (crtc->i80_mode) {
val |= VIDOUT_COMMAND_IF;
} else {
val |= VIDOUT_RGB_IF;
@@ -222,7 +224,7 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
VIDTCON2_HOZVAL(m->hdisplay - 1);
writel(val, ctx->addr + DECON_VIDTCON2);
- if (!(ctx->out_type & IFTYPE_I80)) {
+ if (!crtc->i80_mode) {
int vbp = m->crtc_vtotal - m->crtc_vsync_end;
int vfp = m->crtc_vsync_start - m->crtc_vdisplay;
@@ -277,16 +279,14 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win,
val |= WINCONx_BURSTLEN_16WORD;
break;
case DRM_FORMAT_ARGB8888:
+ default:
val |= WINCONx_BPPMODE_32BPP_A8888;
val |= WINCONx_WSWP_F | WINCONx_BLD_PIX_F | WINCONx_ALPHA_SEL_F;
val |= WINCONx_BURSTLEN_16WORD;
break;
- default:
- DRM_ERROR("Proper pixel format is not set\n");
- return;
}
- DRM_DEBUG_KMS("bpp = %u\n", fb->format->cpp[0] * 8);
+ DRM_DEBUG_KMS("cpp = %u\n", fb->format->cpp[0]);
/*
* In case of exynos, setting dma-burst to 16Word causes permanent
@@ -329,7 +329,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
struct decon_context *ctx = crtc->ctx;
struct drm_framebuffer *fb = state->base.fb;
unsigned int win = plane->index;
- unsigned int bpp = fb->format->cpp[0];
+ unsigned int cpp = fb->format->cpp[0];
unsigned int pitch = fb->pitches[0];
dma_addr_t dma_addr = exynos_drm_fb_dma_addr(fb, 0);
u32 val;
@@ -365,11 +365,11 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
writel(val, ctx->addr + DECON_VIDW0xADD1B0(win));
if (!(ctx->out_type & IFTYPE_HDMI))
- val = BIT_VAL(pitch - state->crtc.w * bpp, 27, 14)
- | BIT_VAL(state->crtc.w * bpp, 13, 0);
+ val = BIT_VAL(pitch - state->crtc.w * cpp, 27, 14)
+ | BIT_VAL(state->crtc.w * cpp, 13, 0);
else
- val = BIT_VAL(pitch - state->crtc.w * bpp, 29, 15)
- | BIT_VAL(state->crtc.w * bpp, 14, 0);
+ val = BIT_VAL(pitch - state->crtc.w * cpp, 29, 15)
+ | BIT_VAL(state->crtc.w * cpp, 14, 0);
writel(val, ctx->addr + DECON_VIDW0xADD2(win));
decon_win_set_pixfmt(ctx, win, fb);
@@ -407,24 +407,19 @@ static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
static void decon_swreset(struct decon_context *ctx)
{
- unsigned int tries;
unsigned long flags;
+ u32 val;
+ int ret;
writel(0, ctx->addr + DECON_VIDCON0);
- for (tries = 2000; tries; --tries) {
- if (~readl(ctx->addr + DECON_VIDCON0) & VIDCON0_STOP_STATUS)
- break;
- udelay(10);
- }
+ readl_poll_timeout(ctx->addr + DECON_VIDCON0, val,
+ ~val & VIDCON0_STOP_STATUS, 12, 20000);
writel(VIDCON0_SWRESET, ctx->addr + DECON_VIDCON0);
- for (tries = 2000; tries; --tries) {
- if (~readl(ctx->addr + DECON_VIDCON0) & VIDCON0_SWRESET)
- break;
- udelay(10);
- }
+ ret = readl_poll_timeout(ctx->addr + DECON_VIDCON0, val,
+ ~val & VIDCON0_SWRESET, 12, 20000);
- WARN(tries == 0, "failed to software reset DECON\n");
+ WARN(ret < 0, "failed to software reset DECON\n");
spin_lock_irqsave(&ctx->vblank_lock, flags);
ctx->frame_id = 0;
@@ -515,6 +510,22 @@ err:
clk_disable_unprepare(ctx->clks[i]);
}
+static enum drm_mode_status decon_mode_valid(struct exynos_drm_crtc *crtc,
+ const struct drm_display_mode *mode)
+{
+ struct decon_context *ctx = crtc->ctx;
+
+ ctx->irq = crtc->i80_mode ? ctx->irq_lcd_sys : ctx->irq_vsync;
+
+ if (ctx->irq)
+ return MODE_OK;
+
+ dev_info(ctx->dev, "Sink requires %s mode, but appropriate interrupt is not provided.\n",
+ crtc->i80_mode ? "command" : "video");
+
+ return MODE_BAD;
+}
+
static const struct exynos_drm_crtc_ops decon_crtc_ops = {
.enable = decon_enable,
.disable = decon_disable,
@@ -524,6 +535,7 @@ static const struct exynos_drm_crtc_ops decon_crtc_ops = {
.atomic_begin = decon_atomic_begin,
.update_plane = decon_update_plane,
.disable_plane = decon_disable_plane,
+ .mode_valid = decon_mode_valid,
.atomic_flush = decon_atomic_flush,
};
@@ -674,19 +686,22 @@ static const struct of_device_id exynos5433_decon_driver_dt_match[] = {
MODULE_DEVICE_TABLE(of, exynos5433_decon_driver_dt_match);
static int decon_conf_irq(struct decon_context *ctx, const char *name,
- irq_handler_t handler, unsigned long int flags, bool required)
+ irq_handler_t handler, unsigned long int flags)
{
struct platform_device *pdev = to_platform_device(ctx->dev);
int ret, irq = platform_get_irq_byname(pdev, name);
if (irq < 0) {
- if (irq == -EPROBE_DEFER)
+ switch (irq) {
+ case -EPROBE_DEFER:
return irq;
- if (required)
- dev_err(ctx->dev, "cannot get %s IRQ\n", name);
- else
- irq = 0;
- return irq;
+ case -ENODATA:
+ case -ENXIO:
+ return 0;
+ default:
+ dev_err(ctx->dev, "IRQ %s get failed, %d\n", name, irq);
+ return irq;
+ }
}
irq_set_status_flags(irq, IRQ_NOAUTOEN);
ret = devm_request_irq(ctx->dev, irq, handler, flags, "drm_decon", ctx);
@@ -714,11 +729,8 @@ static int exynos5433_decon_probe(struct platform_device *pdev)
ctx->out_type = (unsigned long)of_device_get_match_data(dev);
spin_lock_init(&ctx->vblank_lock);
- if (ctx->out_type & IFTYPE_HDMI) {
+ if (ctx->out_type & IFTYPE_HDMI)
ctx->first_win = 1;
- } else if (of_get_child_by_name(dev->of_node, "i80-if-timings")) {
- ctx->out_type |= IFTYPE_I80;
- }
for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
struct clk *clk;
@@ -742,25 +754,23 @@ static int exynos5433_decon_probe(struct platform_device *pdev)
return PTR_ERR(ctx->addr);
}
- if (ctx->out_type & IFTYPE_I80) {
- ret = decon_conf_irq(ctx, "lcd_sys", decon_irq_handler, 0, true);
- if (ret < 0)
- return ret;
- ctx->irq = ret;
+ ret = decon_conf_irq(ctx, "vsync", decon_irq_handler, 0);
+ if (ret < 0)
+ return ret;
+ ctx->irq_vsync = ret;
- ret = decon_conf_irq(ctx, "te", decon_te_irq_handler,
- IRQF_TRIGGER_RISING, false);
- if (ret < 0)
- return ret;
- if (ret) {
- ctx->te_irq = ret;
- ctx->out_type &= ~I80_HW_TRG;
- }
- } else {
- ret = decon_conf_irq(ctx, "vsync", decon_irq_handler, 0, true);
- if (ret < 0)
+ ret = decon_conf_irq(ctx, "lcd_sys", decon_irq_handler, 0);
+ if (ret < 0)
+ return ret;
+ ctx->irq_lcd_sys = ret;
+
+ ret = decon_conf_irq(ctx, "te", decon_te_irq_handler,
+ IRQF_TRIGGER_RISING);
+ if (ret < 0)
return ret;
- ctx->irq = ret;
+ if (ret) {
+ ctx->te_irq = ret;
+ ctx->out_type &= ~I80_HW_TRG;
}
if (ctx->out_type & I80_HW_TRG) {
diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
index 3e88269..615efcf 100644
--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -309,19 +309,14 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win,
val |= WINCONx_BURSTLEN_16WORD;
break;
case DRM_FORMAT_BGRA8888:
+ default:
val |= WINCONx_BPPMODE_32BPP_BGRA | WINCONx_BLD_PIX |
WINCONx_ALPHA_SEL;
val |= WINCONx_BURSTLEN_16WORD;
break;
- default:
- DRM_DEBUG_KMS("invalid pixel size so using unpacked 24bpp.\n");
-
- val |= WINCONx_BPPMODE_24BPP_xRGB;
- val |= WINCONx_BURSTLEN_16WORD;
- break;
}
- DRM_DEBUG_KMS("bpp = %d\n", fb->format->cpp[0] * 8);
+ DRM_DEBUG_KMS("cpp = %d\n", fb->format->cpp[0]);
/*
* In case of exynos, setting dma-burst to 16Word causes permanent
@@ -398,7 +393,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
unsigned int last_x;
unsigned int last_y;
unsigned int win = plane->index;
- unsigned int bpp = fb->format->cpp[0];
+ unsigned int cpp = fb->format->cpp[0];
unsigned int pitch = fb->pitches[0];
if (ctx->suspended)
@@ -418,7 +413,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
val = (unsigned long)exynos_drm_fb_dma_addr(fb, 0);
writel(val, ctx->regs + VIDW_BUF_START(win));
- padding = (pitch / bpp) - fb->width;
+ padding = (pitch / cpp) - fb->width;
/* buffer size */
writel(fb->width + padding, ctx->regs + VIDW_WHOLE_X(win));
diff --git a/drivers/gpu/drm/exynos/exynos_dp.c b/drivers/gpu/drm/exynos/exynos_dp.c
index 385537b..39629e7 100644
--- a/drivers/gpu/drm/exynos/exynos_dp.c
+++ b/drivers/gpu/drm/exynos/exynos_dp.c
@@ -155,7 +155,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
struct exynos_dp_device *dp = dev_get_drvdata(dev);
struct drm_encoder *encoder = &dp->encoder;
struct drm_device *drm_dev = data;
- int pipe, ret;
+ int ret;
/*
* Just like the probe function said, we don't need the
@@ -179,20 +179,15 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
return ret;
}
- pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev,
- EXYNOS_DISPLAY_TYPE_LCD);
- if (pipe < 0)
- return pipe;
-
- encoder->possible_crtcs = 1 << pipe;
-
- DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
-
drm_encoder_init(drm_dev, encoder, &exynos_dp_encoder_funcs,
DRM_MODE_ENCODER_TMDS, NULL);
drm_encoder_helper_add(encoder, &exynos_dp_encoder_helper_funcs);
+ ret = exynos_drm_set_possible_crtcs(encoder, EXYNOS_DISPLAY_TYPE_LCD);
+ if (ret < 0)
+ return ret;
+
dp->plat_data.encoder = encoder;
return analogix_dp_bind(dev, dp->drm_dev, &dp->plat_data);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c
index edbd98f..b0c0621 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_core.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_core.c
@@ -13,6 +13,7 @@
*/
#include <drm/drmP.h>
+
#include "exynos_drm_drv.h"
#include "exynos_drm_crtc.h"
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index d72777f..6ce0821 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -16,12 +16,14 @@
#include <drm/drm_crtc_helper.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
+#include <drm/drm_encoder.h>
#include "exynos_drm_crtc.h"
#include "exynos_drm_drv.h"
#include "exynos_drm_plane.h"
-static void exynos_drm_crtc_enable(struct drm_crtc *crtc)
+static void exynos_drm_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
@@ -31,7 +33,8 @@ static void exynos_drm_crtc_enable(struct drm_crtc *crtc)
drm_crtc_vblank_on(crtc);
}
-static void exynos_drm_crtc_disable(struct drm_crtc *crtc)
+static void exynos_drm_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
@@ -81,12 +84,24 @@ static void exynos_crtc_atomic_flush(struct drm_crtc *crtc,
exynos_crtc->ops->atomic_flush(exynos_crtc);
}
+static enum drm_mode_status exynos_crtc_mode_valid(struct drm_crtc *crtc,
+ const struct drm_display_mode *mode)
+{
+ struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
+
+ if (exynos_crtc->ops->mode_valid)
+ return exynos_crtc->ops->mode_valid(exynos_crtc, mode);
+
+ return MODE_OK;
+}
+
static const struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = {
- .enable = exynos_drm_crtc_enable,
- .disable = exynos_drm_crtc_disable,
+ .mode_valid = exynos_crtc_mode_valid,
.atomic_check = exynos_crtc_atomic_check,
.atomic_begin = exynos_crtc_atomic_begin,
.atomic_flush = exynos_crtc_atomic_flush,
+ .atomic_enable = exynos_drm_crtc_atomic_enable,
+ .atomic_disable = exynos_drm_crtc_atomic_disable,
};
void exynos_crtc_handle_event(struct exynos_drm_crtc *exynos_crtc)
@@ -189,16 +204,30 @@ err_crtc:
return ERR_PTR(ret);
}
-int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
+struct exynos_drm_crtc *exynos_drm_crtc_get_by_type(struct drm_device *drm_dev,
enum exynos_drm_output_type out_type)
{
struct drm_crtc *crtc;
drm_for_each_crtc(crtc, drm_dev)
if (to_exynos_crtc(crtc)->type == out_type)
- return drm_crtc_index(crtc);
+ return to_exynos_crtc(crtc);
- return -EPERM;
+ return ERR_PTR(-EPERM);
+}
+
+int exynos_drm_set_possible_crtcs(struct drm_encoder *encoder,
+ enum exynos_drm_output_type out_type)
+{
+ struct exynos_drm_crtc *crtc = exynos_drm_crtc_get_by_type(encoder->dev,
+ out_type);
+
+ if (IS_ERR(crtc))
+ return PTR_ERR(crtc);
+
+ encoder->possible_crtcs = drm_crtc_mask(&crtc->base);
+
+ return 0;
}
void exynos_drm_crtc_te_handler(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.h b/drivers/gpu/drm/exynos/exynos_drm_crtc.h
index ef58b64..dec4461 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.h
@@ -15,21 +15,25 @@
#ifndef _EXYNOS_DRM_CRTC_H_
#define _EXYNOS_DRM_CRTC_H_
+
#include "exynos_drm_drv.h"
struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
struct drm_plane *plane,
- enum exynos_drm_output_type type,
+ enum exynos_drm_output_type out_type,
const struct exynos_drm_crtc_ops *ops,
void *context);
void exynos_drm_crtc_wait_pending_update(struct exynos_drm_crtc *exynos_crtc);
void exynos_drm_crtc_finish_update(struct exynos_drm_crtc *exynos_crtc,
struct exynos_drm_plane *exynos_plane);
-/* This function gets pipe value to crtc device matched with out_type. */
-int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
+/* This function gets crtc device matched with out_type. */
+struct exynos_drm_crtc *exynos_drm_crtc_get_by_type(struct drm_device *drm_dev,
enum exynos_drm_output_type out_type);
+int exynos_drm_set_possible_crtcs(struct drm_encoder *encoder,
+ enum exynos_drm_output_type out_type);
+
/*
* This function calls the crtc device(manager)'s te_handler() callback
* to trigger to transfer video image at the tearing effect synchronization
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
index 63abcd2..66945e0 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
@@ -59,7 +59,6 @@ static void exynos_dpi_connector_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs exynos_dpi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = exynos_dpi_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = exynos_dpi_connector_destroy,
@@ -203,19 +202,15 @@ int exynos_dpi_bind(struct drm_device *dev, struct drm_encoder *encoder)
{
int ret;
- ret = exynos_drm_crtc_get_pipe_from_type(dev, EXYNOS_DISPLAY_TYPE_LCD);
- if (ret < 0)
- return ret;
-
- encoder->possible_crtcs = 1 << ret;
-
- DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
-
drm_encoder_init(dev, encoder, &exynos_dpi_encoder_funcs,
DRM_MODE_ENCODER_TMDS, NULL);
drm_encoder_helper_add(encoder, &exynos_dpi_encoder_helper_funcs);
+ ret = exynos_drm_set_possible_crtcs(encoder, EXYNOS_DISPLAY_TYPE_LCD);
+ if (ret < 0)
+ return ret;
+
ret = exynos_dpi_create_connector(encoder);
if (ret) {
DRM_ERROR("failed to create connector ret = %d\n", ret);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 242bd50..b1f7299 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -145,8 +145,6 @@ static struct drm_driver exynos_drm_driver = {
.gem_free_object_unlocked = exynos_drm_gem_free_object,
.gem_vm_ops = &exynos_drm_gem_vm_ops,
.dumb_create = exynos_drm_gem_dumb_create,
- .dumb_map_offset = exynos_drm_gem_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_export = drm_gem_prime_export,
@@ -395,8 +393,9 @@ static int exynos_drm_bind(struct device *dev)
/* init kms poll for handling hpd */
drm_kms_helper_poll_init(drm);
- /* force connectors detection */
- drm_helper_hpd_irq_event(drm);
+ ret = exynos_drm_fbdev_init(drm);
+ if (ret)
+ goto err_cleanup_poll;
/* register the DRM device */
ret = drm_dev_register(drm, 0);
@@ -407,6 +406,7 @@ static int exynos_drm_bind(struct device *dev)
err_cleanup_fbdev:
exynos_drm_fbdev_fini(drm);
+err_cleanup_poll:
drm_kms_helper_poll_fini(drm);
exynos_drm_device_subdrv_remove(drm);
err_unbind_all:
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index a93de32..cf131c2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -91,6 +91,7 @@ struct exynos_drm_plane {
#define EXYNOS_DRM_PLANE_CAP_DOUBLE (1 << 0)
#define EXYNOS_DRM_PLANE_CAP_SCALE (1 << 1)
#define EXYNOS_DRM_PLANE_CAP_ZPOS (1 << 2)
+#define EXYNOS_DRM_PLANE_CAP_TILE (1 << 3)
/*
* Exynos DRM plane configuration structure.
@@ -117,6 +118,7 @@ struct exynos_drm_plane_config {
* @disable: disable the device
* @enable_vblank: specific driver callback for enabling vblank interrupt.
* @disable_vblank: specific driver callback for disabling vblank interrupt.
+ * @mode_valid: specific driver callback for mode validation
* @atomic_check: validate state
* @atomic_begin: prepare device to receive an update
* @atomic_flush: mark the end of device update
@@ -132,6 +134,8 @@ struct exynos_drm_crtc_ops {
int (*enable_vblank)(struct exynos_drm_crtc *crtc);
void (*disable_vblank)(struct exynos_drm_crtc *crtc);
u32 (*get_vblank_counter)(struct exynos_drm_crtc *crtc);
+ enum drm_mode_status (*mode_valid)(struct exynos_drm_crtc *crtc,
+ const struct drm_display_mode *mode);
int (*atomic_check)(struct exynos_drm_crtc *crtc,
struct drm_crtc_state *state);
void (*atomic_begin)(struct exynos_drm_crtc *crtc);
@@ -162,6 +166,7 @@ struct exynos_drm_crtc {
const struct exynos_drm_crtc_ops *ops;
void *ctx;
struct exynos_drm_clk *pipe_clk;
+ bool i80_mode : 1;
};
static inline void exynos_drm_pipe_clk_enable(struct exynos_drm_crtc *crtc,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index b6a46d9..7904ffa 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -254,7 +254,6 @@ struct exynos_dsi {
struct drm_encoder encoder;
struct mipi_dsi_host dsi_host;
struct drm_connector connector;
- struct device_node *panel_node;
struct drm_panel *panel;
struct device *dev;
@@ -1329,12 +1328,13 @@ static int exynos_dsi_init(struct exynos_dsi *dsi)
return 0;
}
-static int exynos_dsi_register_te_irq(struct exynos_dsi *dsi)
+static int exynos_dsi_register_te_irq(struct exynos_dsi *dsi,
+ struct device *panel)
{
int ret;
int te_gpio_irq;
- dsi->te_gpio = of_get_named_gpio(dsi->panel_node, "te-gpios", 0);
+ dsi->te_gpio = of_get_named_gpio(panel->of_node, "te-gpios", 0);
if (dsi->te_gpio == -ENOENT)
return 0;
@@ -1374,85 +1374,6 @@ static void exynos_dsi_unregister_te_irq(struct exynos_dsi *dsi)
}
}
-static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
- struct mipi_dsi_device *device)
-{
- struct exynos_dsi *dsi = host_to_dsi(host);
-
- dsi->lanes = device->lanes;
- dsi->format = device->format;
- dsi->mode_flags = device->mode_flags;
- dsi->panel_node = device->dev.of_node;
-
- /*
- * This is a temporary solution and should be made by more generic way.
- *
- * If attached panel device is for command mode one, dsi should register
- * TE interrupt handler.
- */
- if (!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO)) {
- int ret = exynos_dsi_register_te_irq(dsi);
-
- if (ret)
- return ret;
- }
-
- if (dsi->connector.dev)
- drm_helper_hpd_irq_event(dsi->connector.dev);
-
- return 0;
-}
-
-static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
- struct mipi_dsi_device *device)
-{
- struct exynos_dsi *dsi = host_to_dsi(host);
-
- exynos_dsi_unregister_te_irq(dsi);
-
- dsi->panel_node = NULL;
-
- if (dsi->connector.dev)
- drm_helper_hpd_irq_event(dsi->connector.dev);
-
- return 0;
-}
-
-static ssize_t exynos_dsi_host_transfer(struct mipi_dsi_host *host,
- const struct mipi_dsi_msg *msg)
-{
- struct exynos_dsi *dsi = host_to_dsi(host);
- struct exynos_dsi_transfer xfer;
- int ret;
-
- if (!(dsi->state & DSIM_STATE_ENABLED))
- return -EINVAL;
-
- if (!(dsi->state & DSIM_STATE_INITIALIZED)) {
- ret = exynos_dsi_init(dsi);
- if (ret)
- return ret;
- dsi->state |= DSIM_STATE_INITIALIZED;
- }
-
- ret = mipi_dsi_create_packet(&xfer.packet, msg);
- if (ret < 0)
- return ret;
-
- xfer.rx_len = msg->rx_len;
- xfer.rx_payload = msg->rx_buf;
- xfer.flags = msg->flags;
-
- ret = exynos_dsi_transfer(dsi, &xfer);
- return (ret < 0) ? ret : xfer.rx_done;
-}
-
-static const struct mipi_dsi_host_ops exynos_dsi_ops = {
- .attach = exynos_dsi_host_attach,
- .detach = exynos_dsi_host_detach,
- .transfer = exynos_dsi_host_transfer,
-};
-
static void exynos_dsi_enable(struct drm_encoder *encoder)
{
struct exynos_dsi *dsi = encoder_to_dsi(encoder);
@@ -1508,25 +1429,7 @@ static void exynos_dsi_disable(struct drm_encoder *encoder)
static enum drm_connector_status
exynos_dsi_detect(struct drm_connector *connector, bool force)
{
- struct exynos_dsi *dsi = connector_to_dsi(connector);
-
- if (!dsi->panel) {
- dsi->panel = of_drm_find_panel(dsi->panel_node);
- if (dsi->panel)
- drm_panel_attach(dsi->panel, &dsi->connector);
- } else if (!dsi->panel_node) {
- struct drm_encoder *encoder;
-
- encoder = platform_get_drvdata(to_platform_device(dsi->dev));
- exynos_dsi_disable(encoder);
- drm_panel_detach(dsi->panel);
- dsi->panel = NULL;
- }
-
- if (dsi->panel)
- return connector_status_connected;
-
- return connector_status_disconnected;
+ return connector->status;
}
static void exynos_dsi_connector_destroy(struct drm_connector *connector)
@@ -1537,7 +1440,6 @@ static void exynos_dsi_connector_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs exynos_dsi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = exynos_dsi_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = exynos_dsi_connector_destroy,
@@ -1576,6 +1478,7 @@ static int exynos_dsi_create_connector(struct drm_encoder *encoder)
return ret;
}
+ connector->status = connector_status_disconnected;
drm_connector_helper_add(connector, &exynos_dsi_connector_helper_funcs);
drm_mode_connector_attach_encoder(connector, encoder);
@@ -1612,14 +1515,112 @@ static const struct drm_encoder_funcs exynos_dsi_encoder_funcs = {
MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);
+static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
+ struct mipi_dsi_device *device)
+{
+ struct exynos_dsi *dsi = host_to_dsi(host);
+ struct drm_device *drm = dsi->connector.dev;
+
+ /*
+ * This is a temporary solution and should be made by more generic way.
+ *
+ * If attached panel device is for command mode one, dsi should register
+ * TE interrupt handler.
+ */
+ if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {
+ int ret = exynos_dsi_register_te_irq(dsi, &device->dev);
+ if (ret)
+ return ret;
+ }
+
+ mutex_lock(&drm->mode_config.mutex);
+
+ dsi->lanes = device->lanes;
+ dsi->format = device->format;
+ dsi->mode_flags = device->mode_flags;
+ dsi->panel = of_drm_find_panel(device->dev.of_node);
+ if (dsi->panel) {
+ drm_panel_attach(dsi->panel, &dsi->connector);
+ dsi->connector.status = connector_status_connected;
+ }
+ exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode =
+ !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO);
+
+ mutex_unlock(&drm->mode_config.mutex);
+
+ if (drm->mode_config.poll_enabled)
+ drm_kms_helper_hotplug_event(drm);
+
+ return 0;
+}
+
+static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
+ struct mipi_dsi_device *device)
+{
+ struct exynos_dsi *dsi = host_to_dsi(host);
+ struct drm_device *drm = dsi->connector.dev;
+
+ mutex_lock(&drm->mode_config.mutex);
+
+ if (dsi->panel) {
+ exynos_dsi_disable(&dsi->encoder);
+ drm_panel_detach(dsi->panel);
+ dsi->panel = NULL;
+ dsi->connector.status = connector_status_disconnected;
+ }
+
+ mutex_unlock(&drm->mode_config.mutex);
+
+ if (drm->mode_config.poll_enabled)
+ drm_kms_helper_hotplug_event(drm);
+
+ exynos_dsi_unregister_te_irq(dsi);
+
+ return 0;
+}
+
+static ssize_t exynos_dsi_host_transfer(struct mipi_dsi_host *host,
+ const struct mipi_dsi_msg *msg)
+{
+ struct exynos_dsi *dsi = host_to_dsi(host);
+ struct exynos_dsi_transfer xfer;
+ int ret;
+
+ if (!(dsi->state & DSIM_STATE_ENABLED))
+ return -EINVAL;
+
+ if (!(dsi->state & DSIM_STATE_INITIALIZED)) {
+ ret = exynos_dsi_init(dsi);
+ if (ret)
+ return ret;
+ dsi->state |= DSIM_STATE_INITIALIZED;
+ }
+
+ ret = mipi_dsi_create_packet(&xfer.packet, msg);
+ if (ret < 0)
+ return ret;
+
+ xfer.rx_len = msg->rx_len;
+ xfer.rx_payload = msg->rx_buf;
+ xfer.flags = msg->flags;
+
+ ret = exynos_dsi_transfer(dsi, &xfer);
+ return (ret < 0) ? ret : xfer.rx_done;
+}
+
+static const struct mipi_dsi_host_ops exynos_dsi_ops = {
+ .attach = exynos_dsi_host_attach,
+ .detach = exynos_dsi_host_detach,
+ .transfer = exynos_dsi_host_transfer,
+};
+
static int exynos_dsi_of_read_u32(const struct device_node *np,
const char *propname, u32 *out_value)
{
int ret = of_property_read_u32(np, propname, out_value);
if (ret < 0)
- pr_err("%s: failed to get '%s' property\n", np->full_name,
- propname);
+ pr_err("%pOF: failed to get '%s' property\n", np, propname);
return ret;
}
@@ -1664,20 +1665,15 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
struct drm_bridge *bridge;
int ret;
- ret = exynos_drm_crtc_get_pipe_from_type(drm_dev,
- EXYNOS_DISPLAY_TYPE_LCD);
- if (ret < 0)
- return ret;
-
- encoder->possible_crtcs = 1 << ret;
-
- DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
-
drm_encoder_init(drm_dev, encoder, &exynos_dsi_encoder_funcs,
DRM_MODE_ENCODER_TMDS, NULL);
drm_encoder_helper_add(encoder, &exynos_dsi_encoder_helper_funcs);
+ ret = exynos_drm_set_possible_crtcs(encoder, EXYNOS_DISPLAY_TYPE_LCD);
+ if (ret < 0)
+ return ret;
+
ret = exynos_dsi_create_connector(encoder);
if (ret) {
DRM_ERROR("failed to create connector ret = %d\n", ret);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index 73217c28..8208df5 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -199,33 +199,8 @@ dma_addr_t exynos_drm_fb_dma_addr(struct drm_framebuffer *fb, int index)
return exynos_fb->dma_addr[index];
}
-static void exynos_drm_atomic_commit_tail(struct drm_atomic_state *state)
-{
- struct drm_device *dev = state->dev;
-
- drm_atomic_helper_commit_modeset_disables(dev, state);
-
- drm_atomic_helper_commit_modeset_enables(dev, state);
-
- /*
- * Exynos can't update planes with CRTCs and encoders disabled,
- * its updates routines, specially for FIMD, requires the clocks
- * to be enabled. So it is necessary to handle the modeset operations
- * *before* the commit_planes() step, this way it will always
- * have the relevant clocks enabled to perform the update.
- */
- drm_atomic_helper_commit_planes(dev, state,
- DRM_PLANE_COMMIT_ACTIVE_ONLY);
-
- drm_atomic_helper_commit_hw_done(state);
-
- drm_atomic_helper_wait_for_vblanks(dev, state);
-
- drm_atomic_helper_cleanup_planes(dev, state);
-}
-
static struct drm_mode_config_helper_funcs exynos_drm_mode_config_helpers = {
- .atomic_commit_tail = exynos_drm_atomic_commit_tail,
+ .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
};
static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = {
@@ -250,4 +225,6 @@ void exynos_drm_mode_config_init(struct drm_device *dev)
dev->mode_config.funcs = &exynos_drm_mode_config_funcs;
dev->mode_config.helper_private = &exynos_drm_mode_config_helpers;
+
+ dev->mode_config.allow_fb_modifiers = true;
}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index 6415312..c3a0684 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -183,24 +183,6 @@ static const struct drm_fb_helper_funcs exynos_drm_fb_helper_funcs = {
.fb_probe = exynos_drm_fbdev_create,
};
-static bool exynos_drm_fbdev_is_anything_connected(struct drm_device *dev)
-{
- struct drm_connector *connector;
- bool ret = false;
-
- mutex_lock(&dev->mode_config.mutex);
- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
- if (connector->status != connector_status_connected)
- continue;
-
- ret = true;
- break;
- }
- mutex_unlock(&dev->mode_config.mutex);
-
- return ret;
-}
-
int exynos_drm_fbdev_init(struct drm_device *dev)
{
struct exynos_drm_fbdev *fbdev;
@@ -211,9 +193,6 @@ int exynos_drm_fbdev_init(struct drm_device *dev)
if (!dev->mode_config.num_crtc || !dev->mode_config.num_connector)
return 0;
- if (!exynos_drm_fbdev_is_anything_connected(dev))
- return 0;
-
fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL);
if (!fbdev)
return -ENOMEM;
@@ -304,8 +283,5 @@ void exynos_drm_output_poll_changed(struct drm_device *dev)
struct exynos_drm_private *private = dev->dev_private;
struct drm_fb_helper *fb_helper = private->fb_helper;
- if (fb_helper)
- drm_fb_helper_hotplug_event(fb_helper);
- else
- exynos_drm_fbdev_init(dev);
+ drm_fb_helper_hotplug_event(fb_helper);
}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 60f93ca..d42ae2b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -583,18 +583,12 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win,
val |= WINCONx_BURSTLEN_16WORD;
break;
case DRM_FORMAT_ARGB8888:
+ default:
val |= WINCON1_BPPMODE_25BPP_A1888
| WINCON1_BLD_PIX | WINCON1_ALPHA_SEL;
val |= WINCONx_WSWP;
val |= WINCONx_BURSTLEN_16WORD;
break;
- default:
- DRM_DEBUG_KMS("invalid pixel size so using unpacked 24bpp.\n");
-
- val |= WINCON0_BPPMODE_24BPP_888;
- val |= WINCONx_WSWP;
- val |= WINCONx_BURSTLEN_16WORD;
- break;
}
/*
@@ -718,13 +712,13 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc,
unsigned long val, size, offset;
unsigned int last_x, last_y, buf_offsize, line_size;
unsigned int win = plane->index;
- unsigned int bpp = fb->format->cpp[0];
+ unsigned int cpp = fb->format->cpp[0];
unsigned int pitch = fb->pitches[0];
if (ctx->suspended)
return;
- offset = state->src.x * bpp;
+ offset = state->src.x * cpp;
offset += state->src.y * pitch;
/* buffer start address */
@@ -743,8 +737,8 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc,
state->crtc.w, state->crtc.h);
/* buffer size */
- buf_offsize = pitch - (state->crtc.w * bpp);
- line_size = state->crtc.w * bpp;
+ buf_offsize = pitch - (state->crtc.w * cpp);
+ line_size = state->crtc.w * cpp;
val = VIDW_BUF_SIZE_OFFSET(buf_offsize) |
VIDW_BUF_SIZE_PAGEWIDTH(line_size) |
VIDW_BUF_SIZE_OFFSET_E(buf_offsize) |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index c23479b..077de01 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -286,8 +286,8 @@ int exynos_drm_gem_map_ioctl(struct drm_device *dev, void *data,
{
struct drm_exynos_gem_map *args = data;
- return exynos_drm_gem_dumb_map_offset(file_priv, dev, args->handle,
- &args->offset);
+ return drm_gem_dumb_map_offset(file_priv, dev, args->handle,
+ &args->offset);
}
dma_addr_t *exynos_drm_gem_get_dma_addr(struct drm_device *dev,
@@ -422,32 +422,6 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv,
return 0;
}
-int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv,
- struct drm_device *dev, uint32_t handle,
- uint64_t *offset)
-{
- struct drm_gem_object *obj;
- int ret = 0;
-
- /*
- * get offset of memory allocated for drm framebuffer.
- * - this callback would be called by user application
- * with DRM_IOCTL_MODE_MAP_DUMB command.
- */
-
- obj = drm_gem_object_lookup(file_priv, handle);
- if (!obj) {
- DRM_ERROR("failed to lookup gem object.\n");
- return -EINVAL;
- }
-
- *offset = drm_vma_node_offset_addr(&obj->vma_node);
- DRM_DEBUG_KMS("offset = 0x%lx\n", (unsigned long)*offset);
-
- drm_gem_object_unreference_unlocked(obj);
- return ret;
-}
-
int exynos_drm_gem_fault(struct vm_fault *vmf)
{
struct vm_area_struct *vma = vmf->vma;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index 8545725..e86d1a9 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -110,11 +110,6 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv,
struct drm_device *dev,
struct drm_mode_create_dumb *args);
-/* map memory region for drm framebuffer to user space. */
-int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv,
- struct drm_device *dev, uint32_t handle,
- uint64_t *offset);
-
/* page fault handler and mmap fault address(virtual) to physical memory. */
int exynos_drm_gem_fault(struct vm_fault *vmf);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c b/drivers/gpu/drm/exynos/exynos_drm_mic.c
index 16bbee8..ba4a32b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_mic.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c
@@ -21,9 +21,12 @@
#include <linux/component.h>
#include <linux/pm_runtime.h>
#include <drm/drmP.h>
+#include <drm/drm_encoder.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
+#include "exynos_drm_drv.h"
+
/* Sysreg registers for MIC */
#define DSD_CFG_MUX 0x1004
#define MIC0_RGB_MUX (1 << 0)
@@ -85,12 +88,6 @@
#define MIC_BS_SIZE_2D(x) ((x) & 0x3fff)
-enum {
- ENDPOINT_DECON_NODE,
- ENDPOINT_DSI_NODE,
- NUM_ENDPOINTS
-};
-
static char *clk_names[] = { "pclk_mic0", "sclk_rgb_vclk_to_mic0" };
#define NUM_CLKS ARRAY_SIZE(clk_names)
static DEFINE_MUTEX(mic_mutex);
@@ -229,36 +226,6 @@ static void mic_set_reg_on(struct exynos_mic *mic, bool enable)
writel(reg, mic->reg + MIC_OP);
}
-static int parse_dt(struct exynos_mic *mic)
-{
- int ret = 0, i, j;
- struct device_node *remote_node;
- struct device_node *nodes[3];
-
- /*
- * The order of endpoints does matter.
- * The first node must be for decon and the second one must be for dsi.
- */
- for (i = 0, j = 0; i < NUM_ENDPOINTS; i++) {
- remote_node = of_graph_get_remote_node(mic->dev->of_node, i, 0);
- if (!remote_node) {
- ret = -EPIPE;
- goto exit;
- }
- nodes[j++] = remote_node;
-
- if (i == ENDPOINT_DECON_NODE &&
- of_get_child_by_name(remote_node, "i80-if-timings"))
- mic->i80_mode = 1;
- }
-
-exit:
- while (--j > -1)
- of_node_put(nodes[j]);
-
- return ret;
-}
-
static void mic_disable(struct drm_bridge *bridge) { }
static void mic_post_disable(struct drm_bridge *bridge)
@@ -286,6 +253,7 @@ static void mic_mode_set(struct drm_bridge *bridge,
mutex_lock(&mic_mutex);
drm_display_mode_to_videomode(mode, &mic->vm);
+ mic->i80_mode = to_exynos_crtc(bridge->encoder->crtc)->i80_mode;
mutex_unlock(&mic_mutex);
}
@@ -417,10 +385,6 @@ static int exynos_mic_probe(struct platform_device *pdev)
mic->dev = dev;
- ret = parse_dt(mic);
- if (ret)
- goto err;
-
ret = of_address_to_resource(dev->of_node, 0, &res);
if (ret) {
DRM_ERROR("mic: Failed to get mem region for MIC\n");
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index 611b6fd..d2a90da 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -173,13 +173,35 @@ static struct drm_plane_funcs exynos_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = drm_plane_cleanup,
- .set_property = drm_atomic_helper_plane_set_property,
.reset = exynos_drm_plane_reset,
.atomic_duplicate_state = exynos_drm_plane_duplicate_state,
.atomic_destroy_state = exynos_drm_plane_destroy_state,
};
static int
+exynos_drm_plane_check_format(const struct exynos_drm_plane_config *config,
+ struct exynos_drm_plane_state *state)
+{
+ struct drm_framebuffer *fb = state->base.fb;
+
+ switch (fb->modifier) {
+ case DRM_FORMAT_MOD_SAMSUNG_64_32_TILE:
+ if (!(config->capabilities & EXYNOS_DRM_PLANE_CAP_TILE))
+ return -ENOTSUPP;
+ break;
+
+ case DRM_FORMAT_MOD_LINEAR:
+ break;
+
+ default:
+ DRM_ERROR("unsupported pixel format modifier");
+ return -ENOTSUPP;
+ }
+
+ return 0;
+}
+
+static int
exynos_drm_plane_check_size(const struct exynos_drm_plane_config *config,
struct exynos_drm_plane_state *state)
{
@@ -223,6 +245,10 @@ static int exynos_plane_atomic_check(struct drm_plane *plane,
/* translate state into exynos_state */
exynos_plane_mode_set(exynos_state);
+ ret = exynos_drm_plane_check_format(exynos_plane->config, exynos_state);
+ if (ret)
+ return ret;
+
ret = exynos_drm_plane_check_size(exynos_plane->config, exynos_state);
return ret;
}
@@ -283,7 +309,7 @@ int exynos_plane_init(struct drm_device *dev,
&exynos_plane_funcs,
config->pixel_formats,
config->num_pixel_formats,
- config->type, NULL);
+ NULL, config->type, NULL);
if (err) {
DRM_ERROR("failed to initialize plane\n");
return err;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index cb8a728..53e03f8 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -289,7 +289,6 @@ static void vidi_connector_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs vidi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = vidi_detect,
.destroy = vidi_connector_destroy,
@@ -382,7 +381,7 @@ static int vidi_bind(struct device *dev, struct device *master, void *data)
struct exynos_drm_plane *exynos_plane;
struct exynos_drm_plane_config plane_config = { 0 };
unsigned int i;
- int pipe, ret;
+ int ret;
ctx->drm_dev = drm_dev;
@@ -407,20 +406,15 @@ static int vidi_bind(struct device *dev, struct device *master, void *data)
return PTR_ERR(ctx->crtc);
}
- pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev,
- EXYNOS_DISPLAY_TYPE_VIDI);
- if (pipe < 0)
- return pipe;
-
- encoder->possible_crtcs = 1 << pipe;
-
- DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
-
drm_encoder_init(drm_dev, encoder, &exynos_vidi_encoder_funcs,
DRM_MODE_ENCODER_TMDS, NULL);
drm_encoder_helper_add(encoder, &exynos_vidi_encoder_helper_funcs);
+ ret = exynos_drm_set_possible_crtcs(encoder, EXYNOS_DISPLAY_TYPE_VIDI);
+ if (ret < 0)
+ return ret;
+
ret = vidi_create_connector(encoder);
if (ret) {
DRM_ERROR("failed to create connector ret = %d\n", ret);
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index d3b69d6..214fa5e 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -784,7 +784,7 @@ static void hdmi_reg_infoframes(struct hdmi_context *hdata)
}
ret = drm_hdmi_avi_infoframe_from_display_mode(&frm.avi,
- &hdata->current_mode);
+ &hdata->current_mode, false);
if (!ret)
ret = hdmi_avi_infoframe_pack(&frm.avi, buf, sizeof(buf));
if (ret > 0) {
@@ -835,7 +835,6 @@ static void hdmi_connector_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs hdmi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = hdmi_detect,
.destroy = hdmi_connector_destroy,
@@ -1698,32 +1697,25 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data)
struct drm_device *drm_dev = data;
struct hdmi_context *hdata = dev_get_drvdata(dev);
struct drm_encoder *encoder = &hdata->encoder;
- struct exynos_drm_crtc *exynos_crtc;
- struct drm_crtc *crtc;
- int ret, pipe;
+ struct exynos_drm_crtc *crtc;
+ int ret;
hdata->drm_dev = drm_dev;
- pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev,
- EXYNOS_DISPLAY_TYPE_HDMI);
- if (pipe < 0)
- return pipe;
-
hdata->phy_clk.enable = hdmiphy_clk_enable;
- crtc = drm_crtc_from_index(drm_dev, pipe);
- exynos_crtc = to_exynos_crtc(crtc);
- exynos_crtc->pipe_clk = &hdata->phy_clk;
-
- encoder->possible_crtcs = 1 << pipe;
-
- DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
-
drm_encoder_init(drm_dev, encoder, &exynos_hdmi_encoder_funcs,
DRM_MODE_ENCODER_TMDS, NULL);
drm_encoder_helper_add(encoder, &exynos_hdmi_encoder_helper_funcs);
+ ret = exynos_drm_set_possible_crtcs(encoder, EXYNOS_DISPLAY_TYPE_HDMI);
+ if (ret < 0)
+ return ret;
+
+ crtc = exynos_drm_crtc_get_by_type(drm_dev, EXYNOS_DISPLAY_TYPE_HDMI);
+ crtc->pipe_clk = &hdata->phy_clk;
+
ret = hdmi_create_connector(encoder);
if (ret) {
DRM_ERROR("failed to create connector ret = %d\n", ret);
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index a998a8d..0027554 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -148,7 +148,8 @@ static const struct exynos_drm_plane_config plane_configs[MIXER_WIN_NR] = {
.pixel_formats = vp_formats,
.num_pixel_formats = ARRAY_SIZE(vp_formats),
.capabilities = EXYNOS_DRM_PLANE_CAP_SCALE |
- EXYNOS_DRM_PLANE_CAP_ZPOS,
+ EXYNOS_DRM_PLANE_CAP_ZPOS |
+ EXYNOS_DRM_PLANE_CAP_TILE,
},
};
@@ -483,29 +484,18 @@ static void vp_video_buffer(struct mixer_context *ctx,
unsigned int priority = state->base.normalized_zpos + 1;
unsigned long flags;
dma_addr_t luma_addr[2], chroma_addr[2];
- bool tiled_mode = false;
- bool crcb_mode = false;
+ bool is_tiled, is_nv21;
u32 val;
- switch (fb->format->format) {
- case DRM_FORMAT_NV12:
- crcb_mode = false;
- break;
- case DRM_FORMAT_NV21:
- crcb_mode = true;
- break;
- default:
- DRM_ERROR("pixel format for vp is wrong [%d].\n",
- fb->format->format);
- return;
- }
+ is_nv21 = (fb->format->format == DRM_FORMAT_NV21);
+ is_tiled = (fb->modifier == DRM_FORMAT_MOD_SAMSUNG_64_32_TILE);
luma_addr[0] = exynos_drm_fb_dma_addr(fb, 0);
chroma_addr[0] = exynos_drm_fb_dma_addr(fb, 1);
if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
__set_bit(MXR_BIT_INTERLACE, &ctx->flags);
- if (tiled_mode) {
+ if (is_tiled) {
luma_addr[1] = luma_addr[0] + 0x40;
chroma_addr[1] = chroma_addr[0] + 0x40;
} else {
@@ -525,14 +515,14 @@ static void vp_video_buffer(struct mixer_context *ctx,
vp_reg_writemask(res, VP_MODE, val, VP_MODE_LINE_SKIP);
/* setup format */
- val = (crcb_mode ? VP_MODE_NV21 : VP_MODE_NV12);
- val |= (tiled_mode ? VP_MODE_MEM_TILED : VP_MODE_MEM_LINEAR);
+ val = (is_nv21 ? VP_MODE_NV21 : VP_MODE_NV12);
+ val |= (is_tiled ? VP_MODE_MEM_TILED : VP_MODE_MEM_LINEAR);
vp_reg_writemask(res, VP_MODE, val, VP_MODE_FMT_MASK);
/* setting size of input image */
vp_reg_write(res, VP_IMG_SIZE_Y, VP_IMG_HSIZE(fb->pitches[0]) |
VP_IMG_VSIZE(fb->height));
- /* chroma height has to reduced by 2 to avoid chroma distorions */
+ /* chroma plane for NV12/NV21 is half the height of the luma plane */
vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(fb->pitches[0]) |
VP_IMG_VSIZE(fb->height / 2));
@@ -594,7 +584,7 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
unsigned long flags;
unsigned int win = plane->index;
unsigned int x_ratio = 0, y_ratio = 0;
- unsigned int src_x_offset, src_y_offset, dst_x_offset, dst_y_offset;
+ unsigned int dst_x_offset, dst_y_offset;
dma_addr_t dma_addr;
unsigned int fmt;
u32 val;
@@ -616,12 +606,9 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
case DRM_FORMAT_XRGB8888:
case DRM_FORMAT_ARGB8888:
+ default:
fmt = MXR_FORMAT_ARGB8888;
break;
-
- default:
- DRM_DEBUG_KMS("pixelformat unsupported by mixer\n");
- return;
}
/* ratio is already checked by common plane code */
@@ -631,12 +618,10 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
dst_x_offset = state->crtc.x;
dst_y_offset = state->crtc.y;
- /* converting dma address base and source offset */
+ /* translate dma address base s.t. the source image offset is zero */
dma_addr = exynos_drm_fb_dma_addr(fb, 0)
+ (state->src.x * fb->format->cpp[0])
+ (state->src.y * fb->pitches[0]);
- src_x_offset = 0;
- src_y_offset = 0;
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
__set_bit(MXR_BIT_INTERLACE, &ctx->flags);
@@ -667,11 +652,6 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
val |= MXR_GRP_WH_V_SCALE(y_ratio);
mixer_reg_write(res, MXR_GRAPHIC_WH(win), val);
- /* setup offsets in source image */
- val = MXR_GRP_SXY_SX(src_x_offset);
- val |= MXR_GRP_SXY_SY(src_y_offset);
- mixer_reg_write(res, MXR_GRAPHIC_SXY(win), val);
-
/* setup offsets in display image */
val = MXR_GRP_DXY_DX(dst_x_offset);
val |= MXR_GRP_DXY_DY(dst_y_offset);
@@ -748,6 +728,10 @@ static void mixer_win_reset(struct mixer_context *ctx)
if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags))
mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE);
+ /* set all source image offsets to zero */
+ mixer_reg_write(res, MXR_GRAPHIC_SXY(0), 0);
+ mixer_reg_write(res, MXR_GRAPHIC_SXY(1), 0);
+
spin_unlock_irqrestore(&res->reg_slock, flags);
}
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
index cc4e944..0e37524 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
@@ -63,7 +63,8 @@ static void fsl_dcu_drm_crtc_atomic_disable(struct drm_crtc *crtc,
clk_disable_unprepare(fsl_dev->pix_clk);
}
-static void fsl_dcu_drm_crtc_enable(struct drm_crtc *crtc)
+static void fsl_dcu_drm_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct drm_device *dev = crtc->dev;
struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
@@ -133,7 +134,7 @@ static void fsl_dcu_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
static const struct drm_crtc_helper_funcs fsl_dcu_drm_crtc_helper_funcs = {
.atomic_disable = fsl_dcu_drm_crtc_atomic_disable,
.atomic_flush = fsl_dcu_drm_crtc_atomic_flush,
- .enable = fsl_dcu_drm_crtc_enable,
+ .atomic_enable = fsl_dcu_drm_crtc_atomic_enable,
.mode_set_nofb = fsl_dcu_drm_crtc_mode_set_nofb,
};
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
index 5cbde19..58e9e06 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
@@ -176,8 +176,6 @@ static struct drm_driver fsl_dcu_drm_driver = {
.gem_prime_vunmap = drm_gem_cma_prime_vunmap,
.gem_prime_mmap = drm_gem_cma_prime_mmap,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.fops = &fsl_dcu_drm_fops,
.name = "fsl-dcu-drm",
.desc = "Freescale DCU DRM",
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c
index 0a20723..9554b24 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c
@@ -224,7 +224,7 @@ struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device *dev)
&fsl_dcu_drm_plane_funcs,
fsl_dcu_drm_plane_formats,
ARRAY_SIZE(fsl_dcu_drm_plane_formats),
- DRM_PLANE_TYPE_PRIMARY, NULL);
+ NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret) {
kfree(primary);
primary = NULL;
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
index dcbf3c0..edd7d81 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
@@ -63,7 +63,6 @@ static const struct drm_connector_funcs fsl_dcu_drm_connector_funcs = {
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
.destroy = fsl_dcu_drm_connector_destroy,
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.reset = drm_atomic_helper_connector_reset,
};
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index 7da70b6..2570c7f 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -479,26 +479,6 @@ static struct drm_framebuffer *psb_user_framebuffer_create
return psb_framebuffer_create(dev, cmd, r);
}
-static void psbfb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno)
-{
- struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
-
- gma_crtc->lut_r[regno] = red >> 8;
- gma_crtc->lut_g[regno] = green >> 8;
- gma_crtc->lut_b[regno] = blue >> 8;
-}
-
-static void psbfb_gamma_get(struct drm_crtc *crtc, u16 *red,
- u16 *green, u16 *blue, int regno)
-{
- struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
-
- *red = gma_crtc->lut_r[regno] << 8;
- *green = gma_crtc->lut_g[regno] << 8;
- *blue = gma_crtc->lut_b[regno] << 8;
-}
-
static int psbfb_probe(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes)
{
@@ -525,8 +505,6 @@ static int psbfb_probe(struct drm_fb_helper *helper,
}
static const struct drm_fb_helper_funcs psb_fb_helper_funcs = {
- .gamma_set = psbfb_gamma_set,
- .gamma_get = psbfb_gamma_get,
.fb_probe = psbfb_probe,
};
diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c
index 7da061a..1312397 100644
--- a/drivers/gpu/drm/gma500/gem.c
+++ b/drivers/gpu/drm/gma500/gem.c
@@ -48,36 +48,6 @@ int psb_gem_get_aperture(struct drm_device *dev, void *data,
}
/**
- * psb_gem_dumb_map_gtt - buffer mapping for dumb interface
- * @file: our drm client file
- * @dev: drm device
- * @handle: GEM handle to the object (from dumb_create)
- *
- * Do the necessary setup to allow the mapping of the frame buffer
- * into user memory. We don't have to do much here at the moment.
- */
-int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
- uint32_t handle, uint64_t *offset)
-{
- int ret = 0;
- struct drm_gem_object *obj;
-
- /* GEM does all our handle to object mapping */
- obj = drm_gem_object_lookup(file, handle);
- if (obj == NULL)
- return -ENOENT;
-
- /* Make it mmapable */
- ret = drm_gem_create_mmap_offset(obj);
- if (ret)
- goto out;
- *offset = drm_vma_node_offset_addr(&obj->vma_node);
-out:
- drm_gem_object_unreference_unlocked(obj);
- return ret;
-}
-
-/**
* psb_gem_create - create a mappable object
* @file: the DRM file of the client
* @dev: our device
diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c
index e7fd356..f3c48a2 100644
--- a/drivers/gpu/drm/gma500/gma_display.c
+++ b/drivers/gpu/drm/gma500/gma_display.c
@@ -144,33 +144,32 @@ void gma_crtc_load_lut(struct drm_crtc *crtc)
struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
const struct psb_offset *map = &dev_priv->regmap[gma_crtc->pipe];
int palreg = map->palette;
+ u16 *r, *g, *b;
int i;
/* The clocks have to be on to load the palette. */
if (!crtc->enabled)
return;
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
+
if (gma_power_begin(dev, false)) {
for (i = 0; i < 256; i++) {
REG_WRITE(palreg + 4 * i,
- ((gma_crtc->lut_r[i] +
- gma_crtc->lut_adj[i]) << 16) |
- ((gma_crtc->lut_g[i] +
- gma_crtc->lut_adj[i]) << 8) |
- (gma_crtc->lut_b[i] +
- gma_crtc->lut_adj[i]));
+ (((*r++ >> 8) + gma_crtc->lut_adj[i]) << 16) |
+ (((*g++ >> 8) + gma_crtc->lut_adj[i]) << 8) |
+ ((*b++ >> 8) + gma_crtc->lut_adj[i]));
}
gma_power_end(dev);
} else {
for (i = 0; i < 256; i++) {
/* FIXME: Why pipe[0] and not pipe[..._crtc->pipe]? */
dev_priv->regs.pipe[0].palette[i] =
- ((gma_crtc->lut_r[i] +
- gma_crtc->lut_adj[i]) << 16) |
- ((gma_crtc->lut_g[i] +
- gma_crtc->lut_adj[i]) << 8) |
- (gma_crtc->lut_b[i] +
- gma_crtc->lut_adj[i]);
+ (((*r++ >> 8) + gma_crtc->lut_adj[i]) << 16) |
+ (((*g++ >> 8) + gma_crtc->lut_adj[i]) << 8) |
+ ((*b++ >> 8) + gma_crtc->lut_adj[i]);
}
}
@@ -180,15 +179,6 @@ int gma_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, u16 *blue,
u32 size,
struct drm_modeset_acquire_ctx *ctx)
{
- struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
- int i;
-
- for (i = 0; i < size; i++) {
- gma_crtc->lut_r[i] = red[i] >> 8;
- gma_crtc->lut_g[i] = green[i] >> 8;
- gma_crtc->lut_b[i] = blue[i] >> 8;
- }
-
gma_crtc_load_lut(crtc);
return 0;
diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c b/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c
index 1616af2..c50534c 100644
--- a/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c
+++ b/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c
@@ -520,7 +520,7 @@ static int __read_panel_data(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
u8 *data, u16 len, u32 *data_out, u16 len_out, bool hs)
{
unsigned long flags;
- struct drm_device *dev = sender->dev;
+ struct drm_device *dev;
int i;
u32 gen_data_reg;
int retry = MDFLD_DSI_READ_MAX_COUNT;
@@ -530,6 +530,8 @@ static int __read_panel_data(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
return -EINVAL;
}
+ dev = sender->dev;
+
/**
* do reading.
* 0) send out generic read request
diff --git a/drivers/gpu/drm/gma500/mdfld_intel_display.c b/drivers/gpu/drm/gma500/mdfld_intel_display.c
index 63c6e08..531e4450 100644
--- a/drivers/gpu/drm/gma500/mdfld_intel_display.c
+++ b/drivers/gpu/drm/gma500/mdfld_intel_display.c
@@ -737,11 +737,7 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc,
sizeof(struct drm_display_mode));
list_for_each_entry(connector, &mode_config->connector_list, head) {
- if (!connector)
- continue;
-
encoder = connector->encoder;
-
if (!encoder)
continue;
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index 1f9b35a..37a3be7 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -480,7 +480,6 @@ static struct drm_driver driver = {
.load = psb_driver_load,
.unload = psb_driver_unload,
.lastclose = psb_driver_lastclose,
- .set_busid = drm_pci_set_busid,
.num_ioctls = ARRAY_SIZE(psb_ioctls),
.irq_preinstall = psb_irq_preinstall,
@@ -495,8 +494,6 @@ static struct drm_driver driver = {
.gem_vm_ops = &psb_gem_vm_ops,
.dumb_create = psb_gem_dumb_create,
- .dumb_map_offset = psb_gem_dumb_map_gtt,
- .dumb_destroy = drm_gem_dumb_destroy,
.ioctls = psb_ioctls,
.fops = &psb_gem_fops,
.name = DRIVER_NAME,
@@ -517,12 +514,12 @@ static struct pci_driver psb_pci_driver = {
static int __init psb_init(void)
{
- return drm_pci_init(&driver, &psb_pci_driver);
+ return pci_register_driver(&psb_pci_driver);
}
static void __exit psb_exit(void)
{
- drm_pci_exit(&driver, &psb_pci_driver);
+ pci_unregister_driver(&psb_pci_driver);
}
late_initcall(psb_init);
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index 8366708..821497d 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -750,8 +750,6 @@ extern int psb_gem_get_aperture(struct drm_device *dev, void *data,
struct drm_file *file);
extern int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
struct drm_mode_create_dumb *args);
-extern int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
- uint32_t handle, uint64_t *offset);
extern int psb_gem_fault(struct vm_fault *vmf);
/* psb_device.c */
diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c
index 7b6c849..8762efa 100644
--- a/drivers/gpu/drm/gma500/psb_intel_display.c
+++ b/drivers/gpu/drm/gma500/psb_intel_display.c
@@ -518,13 +518,8 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe,
gma_crtc->pipe = pipe;
gma_crtc->plane = pipe;
- for (i = 0; i < 256; i++) {
- gma_crtc->lut_r[i] = i;
- gma_crtc->lut_g[i] = i;
- gma_crtc->lut_b[i] = i;
-
+ for (i = 0; i < 256; i++)
gma_crtc->lut_adj[i] = 0;
- }
gma_crtc->mode_dev = mode_dev;
gma_crtc->cursor_addr = 0;
diff --git a/drivers/gpu/drm/gma500/psb_intel_drv.h b/drivers/gpu/drm/gma500/psb_intel_drv.h
index 6a10215..e8e4ea1 100644
--- a/drivers/gpu/drm/gma500/psb_intel_drv.h
+++ b/drivers/gpu/drm/gma500/psb_intel_drv.h
@@ -172,7 +172,6 @@ struct gma_crtc {
int plane;
uint32_t cursor_addr;
struct gtt_range *cursor_gt;
- u8 lut_r[256], lut_g[256], lut_b[256];
u8 lut_adj[256];
struct psb_intel_framebuffer *fbdev_fb;
/* a mode_set for fbdev users on this crtc */
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
index 59542bd..a956545 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
@@ -150,7 +150,6 @@ static const u32 channel_formats1[] = {
static struct drm_plane_funcs hibmc_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
- .set_property = drm_atomic_helper_plane_set_property,
.destroy = drm_plane_cleanup,
.reset = drm_atomic_helper_plane_reset,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
@@ -181,6 +180,7 @@ static struct drm_plane *hibmc_plane_init(struct hibmc_drm_private *priv)
ret = drm_universal_plane_init(dev, plane, 1, &hibmc_plane_funcs,
channel_formats1,
ARRAY_SIZE(channel_formats1),
+ NULL,
DRM_PLANE_TYPE_PRIMARY,
NULL);
if (ret) {
@@ -192,7 +192,8 @@ static struct drm_plane *hibmc_plane_init(struct hibmc_drm_private *priv)
return plane;
}
-static void hibmc_crtc_enable(struct drm_crtc *crtc)
+static void hibmc_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
unsigned int reg;
struct hibmc_drm_private *priv = crtc->dev->dev_private;
@@ -209,7 +210,8 @@ static void hibmc_crtc_enable(struct drm_crtc *crtc)
drm_crtc_vblank_on(crtc);
}
-static void hibmc_crtc_disable(struct drm_crtc *crtc)
+static void hibmc_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
unsigned int reg;
struct hibmc_drm_private *priv = crtc->dev->dev_private;
@@ -453,11 +455,11 @@ static const struct drm_crtc_funcs hibmc_crtc_funcs = {
};
static const struct drm_crtc_helper_funcs hibmc_crtc_helper_funcs = {
- .enable = hibmc_crtc_enable,
- .disable = hibmc_crtc_disable,
.mode_set_nofb = hibmc_crtc_mode_set_nofb,
.atomic_begin = hibmc_crtc_atomic_begin,
.atomic_flush = hibmc_crtc_atomic_flush,
+ .atomic_enable = hibmc_crtc_atomic_enable,
+ .atomic_disable = hibmc_crtc_atomic_disable,
};
int hibmc_de_init(struct hibmc_drm_private *priv)
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
index 2ffdbf9..d4f6f1f 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
@@ -67,7 +67,6 @@ static struct drm_driver hibmc_driver = {
.gem_free_object_unlocked = hibmc_gem_free_object,
.dumb_create = hibmc_dumb_create,
.dumb_map_offset = hibmc_dumb_mmap_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.irq_handler = hibmc_drm_interrupt,
};
@@ -276,11 +275,12 @@ static int hibmc_unload(struct drm_device *dev)
hibmc_fbdev_fini(priv);
+ drm_atomic_helper_shutdown(dev);
+
if (dev->irq_enabled)
drm_irq_uninstall(dev);
if (priv->msi_enabled)
pci_disable_msi(dev->pdev);
- drm_vblank_cleanup(dev);
hibmc_kms_fini(priv);
hibmc_mm_fini(priv);
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c
index f5ac80d..b92595c 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c
@@ -131,7 +131,6 @@ static int hibmc_drm_fb_create(struct drm_fb_helper *helper,
strcpy(info->fix.id, "hibmcdrmfb");
- info->flags = FBINFO_DEFAULT;
info->fbops = &hibmc_drm_fb_ops;
drm_fb_helper_fill_fix(info, hi_fbdev->fb->fb.pitches[0],
@@ -158,7 +157,7 @@ out_unpin_bo:
out_unreserve_ttm_bo:
ttm_bo_unreserve(&bo->bo);
out_unref_gem:
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return ret;
}
@@ -173,7 +172,7 @@ static void hibmc_fbdev_destroy(struct hibmc_fbdev *fbdev)
drm_fb_helper_fini(fbh);
if (gfb)
- drm_framebuffer_unreference(&gfb->fb);
+ drm_framebuffer_put(&gfb->fb);
}
static const struct drm_fb_helper_funcs hibmc_fbdev_helper_funcs = {
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
index 12a1855..ec4dd9d 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
@@ -47,7 +47,6 @@ static const struct drm_connector_helper_funcs
};
static const struct drm_connector_funcs hibmc_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
.reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c
index ac457c7..3518167 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c
@@ -444,7 +444,7 @@ int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev,
}
ret = drm_gem_handle_create(file, gobj, &handle);
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
if (ret) {
DRM_ERROR("failed to unreference GEM object: %d\n", ret);
return ret;
@@ -479,7 +479,7 @@ int hibmc_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev,
bo = gem_to_hibmc_bo(obj);
*offset = hibmc_bo_mmap_offset(bo);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return 0;
}
@@ -487,7 +487,7 @@ static void hibmc_user_framebuffer_destroy(struct drm_framebuffer *fb)
{
struct hibmc_framebuffer *hibmc_fb = to_hibmc_framebuffer(fb);
- drm_gem_object_unreference_unlocked(hibmc_fb->obj);
+ drm_gem_object_put_unlocked(hibmc_fb->obj);
drm_framebuffer_cleanup(fb);
kfree(hibmc_fb);
}
@@ -543,7 +543,7 @@ hibmc_user_framebuffer_create(struct drm_device *dev,
hibmc_fb = hibmc_framebuffer_init(dev, mode_cmd, obj);
if (IS_ERR(hibmc_fb)) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ERR_PTR((long)hibmc_fb);
}
return &hibmc_fb->fb;
diff --git a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
index f77dcfa..b4c7af3 100644
--- a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
+++ b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
@@ -603,6 +603,72 @@ static void dsi_encoder_enable(struct drm_encoder *encoder)
dsi->enable = true;
}
+static enum drm_mode_status dsi_encoder_phy_mode_valid(
+ struct drm_encoder *encoder,
+ const struct drm_display_mode *mode)
+{
+ struct dw_dsi *dsi = encoder_to_dsi(encoder);
+ struct mipi_phy_params phy;
+ u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
+ u32 req_kHz, act_kHz, lane_byte_clk_kHz;
+
+ /* Calculate the lane byte clk using the adjusted mode clk */
+ memset(&phy, 0, sizeof(phy));
+ req_kHz = mode->clock * bpp / dsi->lanes;
+ act_kHz = dsi_calc_phy_rate(req_kHz, &phy);
+ lane_byte_clk_kHz = act_kHz / 8;
+
+ DRM_DEBUG_DRIVER("Checking mode %ix%i-%i@%i clock: %i...",
+ mode->hdisplay, mode->vdisplay, bpp,
+ drm_mode_vrefresh(mode), mode->clock);
+
+ /*
+ * Make sure the adjusted mode clock and the lane byte clk
+ * have a common denominator base frequency
+ */
+ if (mode->clock/dsi->lanes == lane_byte_clk_kHz/3) {
+ DRM_DEBUG_DRIVER("OK!\n");
+ return MODE_OK;
+ }
+
+ DRM_DEBUG_DRIVER("BAD!\n");
+ return MODE_BAD;
+}
+
+static enum drm_mode_status dsi_encoder_mode_valid(struct drm_encoder *encoder,
+ const struct drm_display_mode *mode)
+
+{
+ const struct drm_crtc_helper_funcs *crtc_funcs = NULL;
+ struct drm_crtc *crtc = NULL;
+ struct drm_display_mode adj_mode;
+ enum drm_mode_status ret;
+
+ /*
+ * The crtc might adjust the mode, so go through the
+ * possible crtcs (technically just one) and call
+ * mode_fixup to figure out the adjusted mode before we
+ * validate it.
+ */
+ drm_for_each_crtc(crtc, encoder->dev) {
+ /*
+ * reset adj_mode to the mode value each time,
+ * so we don't adjust the mode twice
+ */
+ drm_mode_copy(&adj_mode, mode);
+
+ crtc_funcs = crtc->helper_private;
+ if (crtc_funcs && crtc_funcs->mode_fixup)
+ if (!crtc_funcs->mode_fixup(crtc, mode, &adj_mode))
+ return MODE_BAD;
+
+ ret = dsi_encoder_phy_mode_valid(encoder, &adj_mode);
+ if (ret != MODE_OK)
+ return ret;
+ }
+ return MODE_OK;
+}
+
static void dsi_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adj_mode)
@@ -622,6 +688,7 @@ static int dsi_encoder_atomic_check(struct drm_encoder *encoder,
static const struct drm_encoder_helper_funcs dw_encoder_helper_funcs = {
.atomic_check = dsi_encoder_atomic_check,
+ .mode_valid = dsi_encoder_mode_valid,
.mode_set = dsi_encoder_mode_set,
.enable = dsi_encoder_enable,
.disable = dsi_encoder_disable
diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
index c96c228..9823477 100644
--- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
+++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
@@ -178,6 +178,19 @@ static void ade_init(struct ade_hw_ctx *ctx)
FRM_END_START_MASK, REG_EFFECTIVE_IN_ADEEN_FRMEND);
}
+static bool ade_crtc_mode_fixup(struct drm_crtc *crtc,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct ade_crtc *acrtc = to_ade_crtc(crtc);
+ struct ade_hw_ctx *ctx = acrtc->ctx;
+
+ adjusted_mode->clock =
+ clk_round_rate(ctx->ade_pix_clk, mode->clock * 1000) / 1000;
+ return true;
+}
+
+
static void ade_set_pix_clk(struct ade_hw_ctx *ctx,
struct drm_display_mode *mode,
struct drm_display_mode *adj_mode)
@@ -467,7 +480,8 @@ static void ade_dump_regs(void __iomem *base)
static void ade_dump_regs(void __iomem *base) { }
#endif
-static void ade_crtc_enable(struct drm_crtc *crtc)
+static void ade_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct ade_crtc *acrtc = to_ade_crtc(crtc);
struct ade_hw_ctx *ctx = acrtc->ctx;
@@ -489,7 +503,8 @@ static void ade_crtc_enable(struct drm_crtc *crtc)
acrtc->enable = true;
}
-static void ade_crtc_disable(struct drm_crtc *crtc)
+static void ade_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct ade_crtc *acrtc = to_ade_crtc(crtc);
struct ade_hw_ctx *ctx = acrtc->ctx;
@@ -553,11 +568,12 @@ static void ade_crtc_atomic_flush(struct drm_crtc *crtc,
}
static const struct drm_crtc_helper_funcs ade_crtc_helper_funcs = {
- .enable = ade_crtc_enable,
- .disable = ade_crtc_disable,
+ .mode_fixup = ade_crtc_mode_fixup,
.mode_set_nofb = ade_crtc_mode_set_nofb,
.atomic_begin = ade_crtc_atomic_begin,
.atomic_flush = ade_crtc_atomic_flush,
+ .atomic_enable = ade_crtc_atomic_enable,
+ .atomic_disable = ade_crtc_atomic_disable,
};
static const struct drm_crtc_funcs ade_crtc_funcs = {
@@ -565,7 +581,6 @@ static const struct drm_crtc_funcs ade_crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
.page_flip = drm_atomic_helper_page_flip,
.reset = drm_atomic_helper_crtc_reset,
- .set_property = drm_atomic_helper_crtc_set_property,
.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
.enable_vblank = ade_crtc_enable_vblank,
@@ -583,8 +598,7 @@ static int ade_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
*/
port = of_get_child_by_name(dev->dev->of_node, "port");
if (!port) {
- DRM_ERROR("no port node found in %s\n",
- dev->dev->of_node->full_name);
+ DRM_ERROR("no port node found in %pOF\n", dev->dev->of_node);
return -EINVAL;
}
of_node_put(port);
@@ -889,7 +903,6 @@ static const struct drm_plane_helper_funcs ade_plane_helper_funcs = {
static struct drm_plane_funcs ade_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
- .set_property = drm_atomic_helper_plane_set_property,
.destroy = drm_plane_cleanup,
.reset = drm_atomic_helper_plane_reset,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
@@ -909,7 +922,7 @@ static int ade_plane_init(struct drm_device *dev, struct ade_plane *aplane,
return ret;
ret = drm_universal_plane_init(dev, &aplane->base, 1, &ade_plane_funcs,
- fmts, fmts_cnt, type, NULL);
+ fmts, fmts_cnt, NULL, type, NULL);
if (ret) {
DRM_ERROR("fail to init plane, ch=%d\n", aplane->ch);
return ret;
diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
index 9c90367..e27352c 100644
--- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
@@ -34,14 +34,12 @@ static int kirin_drm_kms_cleanup(struct drm_device *dev)
{
struct kirin_drm_private *priv = dev->dev_private;
-#ifdef CONFIG_DRM_FBDEV_EMULATION
if (priv->fbdev) {
drm_fbdev_cma_fini(priv->fbdev);
priv->fbdev = NULL;
}
-#endif
+
drm_kms_helper_poll_fini(dev);
- drm_vblank_cleanup(dev);
dc_ops->cleanup(to_platform_device(dev->dev));
drm_mode_config_cleanup(dev);
devm_kfree(dev->dev, priv);
@@ -50,27 +48,16 @@ static int kirin_drm_kms_cleanup(struct drm_device *dev)
return 0;
}
-#ifdef CONFIG_DRM_FBDEV_EMULATION
static void kirin_fbdev_output_poll_changed(struct drm_device *dev)
{
struct kirin_drm_private *priv = dev->dev_private;
- if (priv->fbdev) {
- drm_fbdev_cma_hotplug_event(priv->fbdev);
- } else {
- priv->fbdev = drm_fbdev_cma_init(dev, 32,
- dev->mode_config.num_connector);
- if (IS_ERR(priv->fbdev))
- priv->fbdev = NULL;
- }
+ drm_fbdev_cma_hotplug_event(priv->fbdev);
}
-#endif
static const struct drm_mode_config_funcs kirin_drm_mode_config_funcs = {
.fb_create = drm_fb_cma_create,
-#ifdef CONFIG_DRM_FBDEV_EMULATION
.output_poll_changed = kirin_fbdev_output_poll_changed,
-#endif
.atomic_check = drm_atomic_helper_check,
.atomic_commit = drm_atomic_helper_commit,
};
@@ -129,11 +116,18 @@ static int kirin_drm_kms_init(struct drm_device *dev)
/* init kms poll for handling hpd */
drm_kms_helper_poll_init(dev);
- /* force detection after connectors init */
- (void)drm_helper_hpd_irq_event(dev);
+ priv->fbdev = drm_fbdev_cma_init(dev, 32,
+ dev->mode_config.num_connector);
+ if (IS_ERR(priv->fbdev)) {
+ DRM_ERROR("failed to initialize fbdev.\n");
+ ret = PTR_ERR(priv->fbdev);
+ goto err_cleanup_poll;
+ }
return 0;
+err_cleanup_poll:
+ drm_kms_helper_poll_fini(dev);
err_unbind_all:
component_unbind_all(dev->dev, dev);
err_dc_cleanup:
@@ -163,8 +157,6 @@ static struct drm_driver kirin_drm_driver = {
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = kirin_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h
index 7f60c649..56cb62d 100644
--- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h
+++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h
@@ -20,9 +20,7 @@ struct kirin_dc_ops {
};
struct kirin_drm_private {
-#ifdef CONFIG_DRM_FBDEV_EMULATION
struct drm_fbdev_cma *fbdev;
-#endif
};
extern const struct kirin_dc_ops ade_dc_ops;
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index 86f47e1..54e3255 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -712,7 +712,7 @@ tda998x_write_avi(struct tda998x_priv *priv, struct drm_display_mode *mode)
{
union hdmi_infoframe frame;
- drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode);
+ drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode, false);
frame.avi.quantization_range = HDMI_QUANTIZATION_RANGE_FULL;
tda998x_write_if(priv, DIP_IF_FLAGS_IF2, REG_IF2_HB0, &frame);
@@ -969,14 +969,6 @@ static int tda998x_audio_codec_init(struct tda998x_priv *priv,
/* DRM connector functions */
-static int tda998x_connector_dpms(struct drm_connector *connector, int mode)
-{
- if (drm_core_check_feature(connector->dev, DRIVER_ATOMIC))
- return drm_atomic_helper_connector_dpms(connector, mode);
- else
- return drm_helper_connector_dpms(connector, mode);
-}
-
static int tda998x_connector_fill_modes(struct drm_connector *connector,
uint32_t maxX, uint32_t maxY)
{
@@ -1014,7 +1006,7 @@ static void tda998x_connector_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs tda998x_connector_funcs = {
- .dpms = tda998x_connector_dpms,
+ .dpms = drm_helper_connector_dpms,
.reset = drm_atomic_helper_connector_reset,
.fill_modes = tda998x_connector_fill_modes,
.detect = tda998x_connector_detect,
diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c
index 37fd090..c69d5c4 100644
--- a/drivers/gpu/drm/i810/i810_drv.c
+++ b/drivers/gpu/drm/i810/i810_drv.c
@@ -59,7 +59,6 @@ static struct drm_driver driver = {
.load = i810_driver_load,
.lastclose = i810_driver_lastclose,
.preclose = i810_driver_preclose,
- .set_busid = drm_pci_set_busid,
.dma_quiescent = i810_driver_dma_quiescent,
.ioctls = i810_ioctls,
.fops = &i810_driver_fops,
@@ -83,12 +82,12 @@ static int __init i810_init(void)
return -EINVAL;
}
driver.num_ioctls = i810_max_ioctl;
- return drm_pci_init(&driver, &i810_pci_driver);
+ return drm_legacy_pci_init(&driver, &i810_pci_driver);
}
static void __exit i810_exit(void)
{
- drm_pci_exit(&driver, &i810_pci_driver);
+ drm_legacy_pci_exit(&driver, &i810_pci_driver);
}
module_init(i810_init);
diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index a5cd5da..e9e64e8 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -21,6 +21,7 @@ config DRM_I915
select ACPI_BUTTON if ACPI
select SYNC_FILE
select IOSF_MBI
+ select CRC32
help
Choose this option if you have a system that has "Intel Graphics
Media Accelerator" or "HD Graphics" integrated graphics,
diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug
index 78c5c04..aed7d20 100644
--- a/drivers/gpu/drm/i915/Kconfig.debug
+++ b/drivers/gpu/drm/i915/Kconfig.debug
@@ -25,6 +25,7 @@ config DRM_I915_DEBUG
select DRM_VGEM # used by igt/prime_vgem (dmabuf interop checks)
select DRM_DEBUG_MM if DRM=y
select DRM_DEBUG_MM_SELFTEST
+ select SW_SYNC # signaling validation framework (igt/syncobj*)
select DRM_I915_SW_FENCE_DEBUG_OBJECTS
select DRM_I915_SELFTEST
default n
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index f822731..892f52b 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -39,6 +39,7 @@ i915-y += i915_cmd_parser.o \
i915_gem_gtt.o \
i915_gem_internal.o \
i915_gem.o \
+ i915_gem_object.o \
i915_gem_render_state.o \
i915_gem_request.o \
i915_gem_shrinker.o \
diff --git a/drivers/gpu/drm/i915/gvt/aperture_gm.c b/drivers/gpu/drm/i915/gvt/aperture_gm.c
index 325618d..ca3d192 100644
--- a/drivers/gpu/drm/i915/gvt/aperture_gm.c
+++ b/drivers/gpu/drm/i915/gvt/aperture_gm.c
@@ -285,8 +285,8 @@ static int alloc_resource(struct intel_vgpu *vgpu,
return 0;
no_enough_resource:
- gvt_vgpu_err("fail to allocate resource %s\n", item);
- gvt_vgpu_err("request %luMB avail %luMB max %luMB taken %luMB\n",
+ gvt_err("fail to allocate resource %s\n", item);
+ gvt_err("request %luMB avail %luMB max %luMB taken %luMB\n",
BYTES_TO_MB(request), BYTES_TO_MB(avail),
BYTES_TO_MB(max), BYTES_TO_MB(taken));
return -ENOSPC;
diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c
index e556a46..21c36e2 100644
--- a/drivers/gpu/drm/i915/gvt/cmd_parser.c
+++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c
@@ -1382,13 +1382,13 @@ static inline int cmd_address_audit(struct parser_exec_state *s,
ret = -EINVAL;
goto err;
}
- } else if ((!vgpu_gmadr_is_valid(s->vgpu, guest_gma)) ||
- (!vgpu_gmadr_is_valid(s->vgpu,
- guest_gma + op_size - 1))) {
+ } else if (!intel_gvt_ggtt_validate_range(vgpu, guest_gma, op_size)) {
ret = -EINVAL;
goto err;
}
+
return 0;
+
err:
gvt_vgpu_err("cmd_parser: Malicious %s detected, addr=0x%lx, len=%d!\n",
s->info->name, guest_gma, op_size);
@@ -2647,7 +2647,7 @@ static int shadow_workload_ring_buffer(struct intel_vgpu_workload *workload)
return 0;
}
-int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload)
+int intel_gvt_scan_and_shadow_ringbuffer(struct intel_vgpu_workload *workload)
{
int ret;
struct intel_vgpu *vgpu = workload->vgpu;
diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.h b/drivers/gpu/drm/i915/gvt/cmd_parser.h
index bed3351..2867036 100644
--- a/drivers/gpu/drm/i915/gvt/cmd_parser.h
+++ b/drivers/gpu/drm/i915/gvt/cmd_parser.h
@@ -42,7 +42,7 @@ void intel_gvt_clean_cmd_parser(struct intel_gvt *gvt);
int intel_gvt_init_cmd_parser(struct intel_gvt *gvt);
-int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload);
+int intel_gvt_scan_and_shadow_ringbuffer(struct intel_vgpu_workload *workload);
int intel_gvt_scan_and_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx);
diff --git a/drivers/gpu/drm/i915/gvt/display.c b/drivers/gpu/drm/i915/gvt/display.c
index 7cb0818..3c31843 100644
--- a/drivers/gpu/drm/i915/gvt/display.c
+++ b/drivers/gpu/drm/i915/gvt/display.c
@@ -178,9 +178,9 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
SDE_PORTE_HOTPLUG_SPT);
vgpu_vreg(vgpu, SKL_FUSE_STATUS) |=
SKL_FUSE_DOWNLOAD_STATUS |
- SKL_FUSE_PG0_DIST_STATUS |
- SKL_FUSE_PG1_DIST_STATUS |
- SKL_FUSE_PG2_DIST_STATUS;
+ SKL_FUSE_PG_DIST_STATUS(SKL_PG0) |
+ SKL_FUSE_PG_DIST_STATUS(SKL_PG1) |
+ SKL_FUSE_PG_DIST_STATUS(SKL_PG2);
vgpu_vreg(vgpu, LCPLL1_CTL) |=
LCPLL_PLL_ENABLE |
LCPLL_PLL_LOCK;
diff --git a/drivers/gpu/drm/i915/gvt/execlist.c b/drivers/gpu/drm/i915/gvt/execlist.c
index 1648887..91b4300 100644
--- a/drivers/gpu/drm/i915/gvt/execlist.c
+++ b/drivers/gpu/drm/i915/gvt/execlist.c
@@ -622,6 +622,7 @@ static int submit_context(struct intel_vgpu *vgpu, int ring_id,
struct list_head *q = workload_q_head(vgpu, ring_id);
struct intel_vgpu_workload *last_workload = get_last_workload(q);
struct intel_vgpu_workload *workload = NULL;
+ struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
u64 ring_context_gpa;
u32 head, tail, start, ctl, ctx_ctl, per_ctx, indirect_ctx;
int ret;
@@ -685,6 +686,7 @@ static int submit_context(struct intel_vgpu *vgpu, int ring_id,
workload->complete = complete_execlist_workload;
workload->status = -EINPROGRESS;
workload->emulate_schedule_in = emulate_schedule_in;
+ workload->shadowed = false;
if (ring_id == RCS) {
intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa +
@@ -718,6 +720,17 @@ static int submit_context(struct intel_vgpu *vgpu, int ring_id,
return ret;
}
+ /* Only scan and shadow the first workload in the queue
+ * as there is only one pre-allocated buf-obj for shadow.
+ */
+ if (list_empty(workload_q_head(vgpu, ring_id))) {
+ intel_runtime_pm_get(dev_priv);
+ mutex_lock(&dev_priv->drm.struct_mutex);
+ intel_gvt_scan_and_shadow_workload(workload);
+ mutex_unlock(&dev_priv->drm.struct_mutex);
+ intel_runtime_pm_put(dev_priv);
+ }
+
queue_workload(workload);
return 0;
}
@@ -800,6 +813,8 @@ static void clean_workloads(struct intel_vgpu *vgpu, unsigned long engine_mask)
list_del_init(&pos->list);
free_workload(pos);
}
+
+ clear_bit(engine->id, vgpu->shadow_ctx_desc_updated);
}
}
diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
index 6166e34..e6dfc33 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.c
+++ b/drivers/gpu/drm/i915/gvt/gtt.c
@@ -259,7 +259,7 @@ static void write_pte64(struct drm_i915_private *dev_priv,
writeq(pte, addr);
}
-static inline struct intel_gvt_gtt_entry *gtt_get_entry64(void *pt,
+static inline int gtt_get_entry64(void *pt,
struct intel_gvt_gtt_entry *e,
unsigned long index, bool hypervisor_access, unsigned long gpa,
struct intel_vgpu *vgpu)
@@ -268,22 +268,23 @@ static inline struct intel_gvt_gtt_entry *gtt_get_entry64(void *pt,
int ret;
if (WARN_ON(info->gtt_entry_size != 8))
- return e;
+ return -EINVAL;
if (hypervisor_access) {
ret = intel_gvt_hypervisor_read_gpa(vgpu, gpa +
(index << info->gtt_entry_size_shift),
&e->val64, 8);
- WARN_ON(ret);
+ if (WARN_ON(ret))
+ return ret;
} else if (!pt) {
e->val64 = read_pte64(vgpu->gvt->dev_priv, index);
} else {
e->val64 = *((u64 *)pt + index);
}
- return e;
+ return 0;
}
-static inline struct intel_gvt_gtt_entry *gtt_set_entry64(void *pt,
+static inline int gtt_set_entry64(void *pt,
struct intel_gvt_gtt_entry *e,
unsigned long index, bool hypervisor_access, unsigned long gpa,
struct intel_vgpu *vgpu)
@@ -292,19 +293,20 @@ static inline struct intel_gvt_gtt_entry *gtt_set_entry64(void *pt,
int ret;
if (WARN_ON(info->gtt_entry_size != 8))
- return e;
+ return -EINVAL;
if (hypervisor_access) {
ret = intel_gvt_hypervisor_write_gpa(vgpu, gpa +
(index << info->gtt_entry_size_shift),
&e->val64, 8);
- WARN_ON(ret);
+ if (WARN_ON(ret))
+ return ret;
} else if (!pt) {
write_pte64(vgpu->gvt->dev_priv, index, e->val64);
} else {
*((u64 *)pt + index) = e->val64;
}
- return e;
+ return 0;
}
#define GTT_HAW 46
@@ -445,21 +447,25 @@ static int gtt_entry_p2m(struct intel_vgpu *vgpu, struct intel_gvt_gtt_entry *p,
/*
* MM helpers.
*/
-struct intel_gvt_gtt_entry *intel_vgpu_mm_get_entry(struct intel_vgpu_mm *mm,
+int intel_vgpu_mm_get_entry(struct intel_vgpu_mm *mm,
void *page_table, struct intel_gvt_gtt_entry *e,
unsigned long index)
{
struct intel_gvt *gvt = mm->vgpu->gvt;
struct intel_gvt_gtt_pte_ops *ops = gvt->gtt.pte_ops;
+ int ret;
e->type = mm->page_table_entry_type;
- ops->get_entry(page_table, e, index, false, 0, mm->vgpu);
+ ret = ops->get_entry(page_table, e, index, false, 0, mm->vgpu);
+ if (ret)
+ return ret;
+
ops->test_pse(e);
- return e;
+ return 0;
}
-struct intel_gvt_gtt_entry *intel_vgpu_mm_set_entry(struct intel_vgpu_mm *mm,
+int intel_vgpu_mm_set_entry(struct intel_vgpu_mm *mm,
void *page_table, struct intel_gvt_gtt_entry *e,
unsigned long index)
{
@@ -472,7 +478,7 @@ struct intel_gvt_gtt_entry *intel_vgpu_mm_set_entry(struct intel_vgpu_mm *mm,
/*
* PPGTT shadow page table helpers.
*/
-static inline struct intel_gvt_gtt_entry *ppgtt_spt_get_entry(
+static inline int ppgtt_spt_get_entry(
struct intel_vgpu_ppgtt_spt *spt,
void *page_table, int type,
struct intel_gvt_gtt_entry *e, unsigned long index,
@@ -480,20 +486,24 @@ static inline struct intel_gvt_gtt_entry *ppgtt_spt_get_entry(
{
struct intel_gvt *gvt = spt->vgpu->gvt;
struct intel_gvt_gtt_pte_ops *ops = gvt->gtt.pte_ops;
+ int ret;
e->type = get_entry_type(type);
if (WARN(!gtt_type_is_entry(e->type), "invalid entry type\n"))
- return e;
+ return -EINVAL;
- ops->get_entry(page_table, e, index, guest,
+ ret = ops->get_entry(page_table, e, index, guest,
spt->guest_page.gfn << GTT_PAGE_SHIFT,
spt->vgpu);
+ if (ret)
+ return ret;
+
ops->test_pse(e);
- return e;
+ return 0;
}
-static inline struct intel_gvt_gtt_entry *ppgtt_spt_set_entry(
+static inline int ppgtt_spt_set_entry(
struct intel_vgpu_ppgtt_spt *spt,
void *page_table, int type,
struct intel_gvt_gtt_entry *e, unsigned long index,
@@ -503,7 +513,7 @@ static inline struct intel_gvt_gtt_entry *ppgtt_spt_set_entry(
struct intel_gvt_gtt_pte_ops *ops = gvt->gtt.pte_ops;
if (WARN(!gtt_type_is_entry(e->type), "invalid entry type\n"))
- return e;
+ return -EINVAL;
return ops->set_entry(page_table, e, index, guest,
spt->guest_page.gfn << GTT_PAGE_SHIFT,
@@ -792,13 +802,13 @@ static struct intel_vgpu_ppgtt_spt *ppgtt_find_shadow_page(
#define for_each_present_guest_entry(spt, e, i) \
for (i = 0; i < pt_entries(spt); i++) \
- if (spt->vgpu->gvt->gtt.pte_ops->test_present( \
- ppgtt_get_guest_entry(spt, e, i)))
+ if (!ppgtt_get_guest_entry(spt, e, i) && \
+ spt->vgpu->gvt->gtt.pte_ops->test_present(e))
#define for_each_present_shadow_entry(spt, e, i) \
for (i = 0; i < pt_entries(spt); i++) \
- if (spt->vgpu->gvt->gtt.pte_ops->test_present( \
- ppgtt_get_shadow_entry(spt, e, i)))
+ if (!ppgtt_get_shadow_entry(spt, e, i) && \
+ spt->vgpu->gvt->gtt.pte_ops->test_present(e))
static void ppgtt_get_shadow_page(struct intel_vgpu_ppgtt_spt *spt)
{
@@ -979,29 +989,26 @@ fail:
}
static int ppgtt_handle_guest_entry_removal(struct intel_vgpu_guest_page *gpt,
- unsigned long index)
+ struct intel_gvt_gtt_entry *se, unsigned long index)
{
struct intel_vgpu_ppgtt_spt *spt = guest_page_to_ppgtt_spt(gpt);
struct intel_vgpu_shadow_page *sp = &spt->shadow_page;
struct intel_vgpu *vgpu = spt->vgpu;
struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops;
- struct intel_gvt_gtt_entry e;
int ret;
- ppgtt_get_shadow_entry(spt, &e, index);
-
- trace_gpt_change(spt->vgpu->id, "remove", spt, sp->type, e.val64,
+ trace_gpt_change(spt->vgpu->id, "remove", spt, sp->type, se->val64,
index);
- if (!ops->test_present(&e))
+ if (!ops->test_present(se))
return 0;
- if (ops->get_pfn(&e) == vgpu->gtt.scratch_pt[sp->type].page_mfn)
+ if (ops->get_pfn(se) == vgpu->gtt.scratch_pt[sp->type].page_mfn)
return 0;
- if (gtt_type_is_pt(get_next_pt_type(e.type))) {
+ if (gtt_type_is_pt(get_next_pt_type(se->type))) {
struct intel_vgpu_ppgtt_spt *s =
- ppgtt_find_shadow_page(vgpu, ops->get_pfn(&e));
+ ppgtt_find_shadow_page(vgpu, ops->get_pfn(se));
if (!s) {
gvt_vgpu_err("fail to find guest page\n");
ret = -ENXIO;
@@ -1011,12 +1018,10 @@ static int ppgtt_handle_guest_entry_removal(struct intel_vgpu_guest_page *gpt,
if (ret)
goto fail;
}
- ops->set_pfn(&e, vgpu->gtt.scratch_pt[sp->type].page_mfn);
- ppgtt_set_shadow_entry(spt, &e, index);
return 0;
fail:
gvt_vgpu_err("fail: shadow page %p guest entry 0x%llx type %d\n",
- spt, e.val64, e.type);
+ spt, se->val64, se->type);
return ret;
}
@@ -1236,22 +1241,37 @@ static int ppgtt_handle_guest_write_page_table(
{
struct intel_vgpu_ppgtt_spt *spt = guest_page_to_ppgtt_spt(gpt);
struct intel_vgpu *vgpu = spt->vgpu;
+ int type = spt->shadow_page.type;
struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops;
+ struct intel_gvt_gtt_entry se;
int ret;
int new_present;
new_present = ops->test_present(we);
- ret = ppgtt_handle_guest_entry_removal(gpt, index);
- if (ret)
- goto fail;
+ /*
+ * Adding the new entry first and then removing the old one, that can
+ * guarantee the ppgtt table is validated during the window between
+ * adding and removal.
+ */
+ ppgtt_get_shadow_entry(spt, &se, index);
if (new_present) {
ret = ppgtt_handle_guest_entry_add(gpt, we, index);
if (ret)
goto fail;
}
+
+ ret = ppgtt_handle_guest_entry_removal(gpt, &se, index);
+ if (ret)
+ goto fail;
+
+ if (!new_present) {
+ ops->set_pfn(&se, vgpu->gtt.scratch_pt[type].page_mfn);
+ ppgtt_set_shadow_entry(spt, &se, index);
+ }
+
return 0;
fail:
gvt_vgpu_err("fail: shadow page %p guest entry 0x%llx type %d.\n",
@@ -1323,7 +1343,7 @@ static int ppgtt_handle_guest_write_page_table_bytes(void *gp,
struct intel_vgpu *vgpu = spt->vgpu;
struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops;
const struct intel_gvt_device_info *info = &vgpu->gvt->device_info;
- struct intel_gvt_gtt_entry we;
+ struct intel_gvt_gtt_entry we, se;
unsigned long index;
int ret;
@@ -1339,7 +1359,8 @@ static int ppgtt_handle_guest_write_page_table_bytes(void *gp,
return ret;
} else {
if (!test_bit(index, spt->post_shadow_bitmap)) {
- ret = ppgtt_handle_guest_entry_removal(gpt, index);
+ ppgtt_get_shadow_entry(spt, &se, index);
+ ret = ppgtt_handle_guest_entry_removal(gpt, &se, index);
if (ret)
return ret;
}
@@ -1713,8 +1734,10 @@ unsigned long intel_vgpu_gma_to_gpa(struct intel_vgpu_mm *mm, unsigned long gma)
if (!vgpu_gmadr_is_valid(vgpu, gma))
goto err;
- ggtt_get_guest_entry(mm, &e,
- gma_ops->gma_to_ggtt_pte_index(gma));
+ ret = ggtt_get_guest_entry(mm, &e,
+ gma_ops->gma_to_ggtt_pte_index(gma));
+ if (ret)
+ goto err;
gpa = (pte_ops->get_pfn(&e) << GTT_PAGE_SHIFT)
+ (gma & ~GTT_PAGE_MASK);
@@ -1724,7 +1747,9 @@ unsigned long intel_vgpu_gma_to_gpa(struct intel_vgpu_mm *mm, unsigned long gma)
switch (mm->page_table_level) {
case 4:
- ppgtt_get_shadow_root_entry(mm, &e, 0);
+ ret = ppgtt_get_shadow_root_entry(mm, &e, 0);
+ if (ret)
+ goto err;
gma_index[0] = gma_ops->gma_to_pml4_index(gma);
gma_index[1] = gma_ops->gma_to_l4_pdp_index(gma);
gma_index[2] = gma_ops->gma_to_pde_index(gma);
@@ -1732,15 +1757,19 @@ unsigned long intel_vgpu_gma_to_gpa(struct intel_vgpu_mm *mm, unsigned long gma)
index = 4;
break;
case 3:
- ppgtt_get_shadow_root_entry(mm, &e,
+ ret = ppgtt_get_shadow_root_entry(mm, &e,
gma_ops->gma_to_l3_pdp_index(gma));
+ if (ret)
+ goto err;
gma_index[0] = gma_ops->gma_to_pde_index(gma);
gma_index[1] = gma_ops->gma_to_pte_index(gma);
index = 2;
break;
case 2:
- ppgtt_get_shadow_root_entry(mm, &e,
+ ret = ppgtt_get_shadow_root_entry(mm, &e,
gma_ops->gma_to_pde_index(gma));
+ if (ret)
+ goto err;
gma_index[0] = gma_ops->gma_to_pte_index(gma);
index = 1;
break;
@@ -1755,6 +1784,11 @@ unsigned long intel_vgpu_gma_to_gpa(struct intel_vgpu_mm *mm, unsigned long gma)
(i == index - 1));
if (ret)
goto err;
+
+ if (!pte_ops->test_present(&e)) {
+ gvt_dbg_core("GMA 0x%lx is not present\n", gma);
+ goto err;
+ }
}
gpa = (pte_ops->get_pfn(&e) << GTT_PAGE_SHIFT)
@@ -2329,13 +2363,12 @@ void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu)
/**
* intel_vgpu_reset_gtt - reset the all GTT related status
* @vgpu: a vGPU
- * @dmlr: true for vGPU Device Model Level Reset, false for GT Reset
*
* This function is called from vfio core to reset reset all
* GTT related status, including GGTT, PPGTT, scratch page.
*
*/
-void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu, bool dmlr)
+void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu)
{
int i;
@@ -2347,9 +2380,6 @@ void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu, bool dmlr)
*/
intel_vgpu_free_mm(vgpu, INTEL_GVT_MM_PPGTT);
- if (!dmlr)
- return;
-
intel_vgpu_reset_ggtt(vgpu);
/* clear scratch page for security */
diff --git a/drivers/gpu/drm/i915/gvt/gtt.h b/drivers/gpu/drm/i915/gvt/gtt.h
index f88eb5e..30a4c8d 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.h
+++ b/drivers/gpu/drm/i915/gvt/gtt.h
@@ -49,14 +49,18 @@ struct intel_gvt_gtt_entry {
};
struct intel_gvt_gtt_pte_ops {
- struct intel_gvt_gtt_entry *(*get_entry)(void *pt,
- struct intel_gvt_gtt_entry *e,
- unsigned long index, bool hypervisor_access, unsigned long gpa,
- struct intel_vgpu *vgpu);
- struct intel_gvt_gtt_entry *(*set_entry)(void *pt,
- struct intel_gvt_gtt_entry *e,
- unsigned long index, bool hypervisor_access, unsigned long gpa,
- struct intel_vgpu *vgpu);
+ int (*get_entry)(void *pt,
+ struct intel_gvt_gtt_entry *e,
+ unsigned long index,
+ bool hypervisor_access,
+ unsigned long gpa,
+ struct intel_vgpu *vgpu);
+ int (*set_entry)(void *pt,
+ struct intel_gvt_gtt_entry *e,
+ unsigned long index,
+ bool hypervisor_access,
+ unsigned long gpa,
+ struct intel_vgpu *vgpu);
bool (*test_present)(struct intel_gvt_gtt_entry *e);
void (*clear_present)(struct intel_gvt_gtt_entry *e);
bool (*test_pse)(struct intel_gvt_gtt_entry *e);
@@ -143,12 +147,12 @@ struct intel_vgpu_mm {
struct intel_vgpu *vgpu;
};
-extern struct intel_gvt_gtt_entry *intel_vgpu_mm_get_entry(
+extern int intel_vgpu_mm_get_entry(
struct intel_vgpu_mm *mm,
void *page_table, struct intel_gvt_gtt_entry *e,
unsigned long index);
-extern struct intel_gvt_gtt_entry *intel_vgpu_mm_set_entry(
+extern int intel_vgpu_mm_set_entry(
struct intel_vgpu_mm *mm,
void *page_table, struct intel_gvt_gtt_entry *e,
unsigned long index);
@@ -208,7 +212,7 @@ extern void intel_vgpu_clean_gtt(struct intel_vgpu *vgpu);
void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu);
extern int intel_gvt_init_gtt(struct intel_gvt *gvt);
-extern void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu, bool dmlr);
+void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu);
extern void intel_gvt_clean_gtt(struct intel_gvt *gvt);
extern struct intel_vgpu_mm *intel_gvt_find_ppgtt_mm(struct intel_vgpu *vgpu,
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index 2964a4d..44b719e 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -167,6 +167,7 @@ struct intel_vgpu {
atomic_t running_workload_num;
DECLARE_BITMAP(tlb_handle_pending, I915_NUM_ENGINES);
struct i915_gem_context *shadow_ctx;
+ DECLARE_BITMAP(shadow_ctx_desc_updated, I915_NUM_ENGINES);
#if IS_ENABLED(CONFIG_DRM_I915_GVT_KVMGT)
struct {
@@ -482,6 +483,8 @@ int intel_vgpu_init_opregion(struct intel_vgpu *vgpu, u32 gpa);
int intel_vgpu_emulate_opregion_request(struct intel_vgpu *vgpu, u32 swsci);
void populate_pvinfo_page(struct intel_vgpu *vgpu);
+int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload);
+
struct intel_gvt_ops {
int (*emulate_cfg_read)(struct intel_vgpu *, unsigned int, void *,
unsigned int);
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c
index feed992..3502a59 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -113,9 +113,17 @@ static int new_mmio_info(struct intel_gvt *gvt,
info->offset = i;
p = find_mmio_info(gvt, info->offset);
- if (p)
- gvt_err("dup mmio definition offset %x\n",
+ if (p) {
+ WARN(1, "dup mmio definition offset %x\n",
info->offset);
+ kfree(info);
+
+ /* We return -EEXIST here to make GVT-g load fail.
+ * So duplicated MMIO can be found as soon as
+ * possible.
+ */
+ return -EEXIST;
+ }
info->ro_mask = ro_mask;
info->device = device;
@@ -1222,10 +1230,12 @@ static int power_well_ctl_mmio_write(struct intel_vgpu *vgpu,
{
write_vreg(vgpu, offset, p_data, bytes);
- if (vgpu_vreg(vgpu, offset) & HSW_PWR_WELL_ENABLE_REQUEST)
- vgpu_vreg(vgpu, offset) |= HSW_PWR_WELL_STATE_ENABLED;
+ if (vgpu_vreg(vgpu, offset) & HSW_PWR_WELL_CTL_REQ(HSW_DISP_PW_GLOBAL))
+ vgpu_vreg(vgpu, offset) |=
+ HSW_PWR_WELL_CTL_STATE(HSW_DISP_PW_GLOBAL);
else
- vgpu_vreg(vgpu, offset) &= ~HSW_PWR_WELL_STATE_ENABLED;
+ vgpu_vreg(vgpu, offset) &=
+ ~HSW_PWR_WELL_CTL_STATE(HSW_DISP_PW_GLOBAL);
return 0;
}
@@ -2242,10 +2252,17 @@ static int init_generic_mmio_info(struct intel_gvt *gvt)
MMIO_D(GEN6_RC6p_THRESHOLD, D_ALL);
MMIO_D(GEN6_RC6pp_THRESHOLD, D_ALL);
MMIO_D(GEN6_PMINTRMSK, D_ALL);
- MMIO_DH(HSW_PWR_WELL_BIOS, D_BDW, NULL, power_well_ctl_mmio_write);
- MMIO_DH(HSW_PWR_WELL_DRIVER, D_BDW, NULL, power_well_ctl_mmio_write);
- MMIO_DH(HSW_PWR_WELL_KVMR, D_BDW, NULL, power_well_ctl_mmio_write);
- MMIO_DH(HSW_PWR_WELL_DEBUG, D_BDW, NULL, power_well_ctl_mmio_write);
+ /*
+ * Use an arbitrary power well controlled by the PWR_WELL_CTL
+ * register.
+ */
+ MMIO_DH(HSW_PWR_WELL_CTL_BIOS(HSW_DISP_PW_GLOBAL), D_BDW, NULL,
+ power_well_ctl_mmio_write);
+ MMIO_DH(HSW_PWR_WELL_CTL_DRIVER(HSW_DISP_PW_GLOBAL), D_BDW, NULL,
+ power_well_ctl_mmio_write);
+ MMIO_DH(HSW_PWR_WELL_CTL_KVMR, D_BDW, NULL, power_well_ctl_mmio_write);
+ MMIO_DH(HSW_PWR_WELL_CTL_DEBUG(HSW_DISP_PW_GLOBAL), D_BDW, NULL,
+ power_well_ctl_mmio_write);
MMIO_DH(HSW_PWR_WELL_CTL5, D_BDW, NULL, power_well_ctl_mmio_write);
MMIO_DH(HSW_PWR_WELL_CTL6, D_BDW, NULL, power_well_ctl_mmio_write);
@@ -2581,7 +2598,6 @@ static int init_broadwell_mmio_info(struct intel_gvt *gvt)
MMIO_F(0x24d0, 48, F_CMD_ACCESS, 0, 0, D_BDW_PLUS,
NULL, force_nonpriv_write);
- MMIO_D(0x22040, D_BDW_PLUS);
MMIO_D(0x44484, D_BDW_PLUS);
MMIO_D(0x4448c, D_BDW_PLUS);
@@ -2636,9 +2652,13 @@ static int init_skl_mmio_info(struct intel_gvt *gvt)
MMIO_F(_DPD_AUX_CH_CTL, 6 * 4, 0, 0, 0, D_SKL_PLUS, NULL,
dp_aux_ch_ctl_mmio_write);
- MMIO_D(HSW_PWR_WELL_BIOS, D_SKL_PLUS);
- MMIO_DH(HSW_PWR_WELL_DRIVER, D_SKL_PLUS, NULL,
- skl_power_well_ctl_write);
+ /*
+ * Use an arbitrary power well controlled by the PWR_WELL_CTL
+ * register.
+ */
+ MMIO_D(HSW_PWR_WELL_CTL_BIOS(SKL_DISP_PW_MISC_IO), D_SKL_PLUS);
+ MMIO_DH(HSW_PWR_WELL_CTL_DRIVER(SKL_DISP_PW_MISC_IO), D_SKL_PLUS, NULL,
+ skl_power_well_ctl_write);
MMIO_DH(GEN6_PCODE_MAILBOX, D_SKL_PLUS, NULL, mailbox_write);
MMIO_D(0xa210, D_SKL_PLUS);
@@ -2831,7 +2851,6 @@ static int init_skl_mmio_info(struct intel_gvt *gvt)
MMIO_D(0x320f0, D_SKL | D_KBL);
MMIO_DFH(_REG_VCS2_EXCC, D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL);
- MMIO_DFH(_REG_VECS_EXCC, D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL);
MMIO_D(0x70034, D_SKL_PLUS);
MMIO_D(0x71034, D_SKL_PLUS);
MMIO_D(0x72034, D_SKL_PLUS);
@@ -2849,10 +2868,7 @@ static int init_skl_mmio_info(struct intel_gvt *gvt)
NULL, NULL);
MMIO_D(0x4ab8, D_KBL);
- MMIO_D(0x940c, D_SKL_PLUS);
MMIO_D(0x2248, D_SKL_PLUS | D_KBL);
- MMIO_D(0x4ab0, D_SKL | D_KBL);
- MMIO_D(0x20d4, D_SKL | D_KBL);
return 0;
}
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index fd0c85f..83e88c7 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1170,10 +1170,27 @@ vgpu_id_show(struct device *dev, struct device_attribute *attr,
return sprintf(buf, "\n");
}
+static ssize_t
+hw_id_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct mdev_device *mdev = mdev_from_dev(dev);
+
+ if (mdev) {
+ struct intel_vgpu *vgpu = (struct intel_vgpu *)
+ mdev_get_drvdata(mdev);
+ return sprintf(buf, "%u\n",
+ vgpu->shadow_ctx->hw_id);
+ }
+ return sprintf(buf, "\n");
+}
+
static DEVICE_ATTR_RO(vgpu_id);
+static DEVICE_ATTR_RO(hw_id);
static struct attribute *intel_vgpu_attrs[] = {
&dev_attr_vgpu_id.attr,
+ &dev_attr_hw_id.attr,
NULL
};
diff --git a/drivers/gpu/drm/i915/gvt/render.c b/drivers/gpu/drm/i915/gvt/render.c
index 504e57c..2ea5422 100644
--- a/drivers/gpu/drm/i915/gvt/render.c
+++ b/drivers/gpu/drm/i915/gvt/render.c
@@ -207,18 +207,16 @@ static void load_mocs(struct intel_vgpu *vgpu, int ring_id)
offset.reg = regs[ring_id];
for (i = 0; i < 64; i++) {
- gen9_render_mocs[ring_id][i] = I915_READ(offset);
+ gen9_render_mocs[ring_id][i] = I915_READ_FW(offset);
I915_WRITE(offset, vgpu_vreg(vgpu, offset));
- POSTING_READ(offset);
offset.reg += 4;
}
if (ring_id == RCS) {
l3_offset.reg = 0xb020;
for (i = 0; i < 32; i++) {
- gen9_render_mocs_L3[i] = I915_READ(l3_offset);
- I915_WRITE(l3_offset, vgpu_vreg(vgpu, l3_offset));
- POSTING_READ(l3_offset);
+ gen9_render_mocs_L3[i] = I915_READ_FW(l3_offset);
+ I915_WRITE_FW(l3_offset, vgpu_vreg(vgpu, l3_offset));
l3_offset.reg += 4;
}
}
@@ -242,18 +240,16 @@ static void restore_mocs(struct intel_vgpu *vgpu, int ring_id)
offset.reg = regs[ring_id];
for (i = 0; i < 64; i++) {
- vgpu_vreg(vgpu, offset) = I915_READ(offset);
- I915_WRITE(offset, gen9_render_mocs[ring_id][i]);
- POSTING_READ(offset);
+ vgpu_vreg(vgpu, offset) = I915_READ_FW(offset);
+ I915_WRITE_FW(offset, gen9_render_mocs[ring_id][i]);
offset.reg += 4;
}
if (ring_id == RCS) {
l3_offset.reg = 0xb020;
for (i = 0; i < 32; i++) {
- vgpu_vreg(vgpu, l3_offset) = I915_READ(l3_offset);
- I915_WRITE(l3_offset, gen9_render_mocs_L3[i]);
- POSTING_READ(l3_offset);
+ vgpu_vreg(vgpu, l3_offset) = I915_READ_FW(l3_offset);
+ I915_WRITE_FW(l3_offset, gen9_render_mocs_L3[i]);
l3_offset.reg += 4;
}
}
@@ -272,6 +268,7 @@ static void switch_mmio_to_vgpu(struct intel_vgpu *vgpu, int ring_id)
u32 ctx_ctrl = reg_state[CTX_CONTEXT_CONTROL_VAL];
u32 inhibit_mask =
_MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT);
+ i915_reg_t last_reg = _MMIO(0);
if (IS_SKYLAKE(vgpu->gvt->dev_priv)
|| IS_KABYLAKE(vgpu->gvt->dev_priv)) {
@@ -287,7 +284,7 @@ static void switch_mmio_to_vgpu(struct intel_vgpu *vgpu, int ring_id)
if (mmio->ring_id != ring_id)
continue;
- mmio->value = I915_READ(mmio->reg);
+ mmio->value = I915_READ_FW(mmio->reg);
/*
* if it is an inhibit context, load in_context mmio
@@ -304,13 +301,18 @@ static void switch_mmio_to_vgpu(struct intel_vgpu *vgpu, int ring_id)
else
v = vgpu_vreg(vgpu, mmio->reg);
- I915_WRITE(mmio->reg, v);
- POSTING_READ(mmio->reg);
+ I915_WRITE_FW(mmio->reg, v);
+ last_reg = mmio->reg;
trace_render_mmio(vgpu->id, "load",
i915_mmio_reg_offset(mmio->reg),
mmio->value, v);
}
+
+ /* Make sure the swiched MMIOs has taken effect. */
+ if (likely(INTEL_GVT_MMIO_OFFSET(last_reg)))
+ I915_READ_FW(last_reg);
+
handle_tlb_pending_event(vgpu, ring_id);
}
@@ -319,6 +321,7 @@ static void switch_mmio_to_host(struct intel_vgpu *vgpu, int ring_id)
{
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
struct render_mmio *mmio;
+ i915_reg_t last_reg = _MMIO(0);
u32 v;
int i, array_size;
@@ -335,7 +338,7 @@ static void switch_mmio_to_host(struct intel_vgpu *vgpu, int ring_id)
if (mmio->ring_id != ring_id)
continue;
- vgpu_vreg(vgpu, mmio->reg) = I915_READ(mmio->reg);
+ vgpu_vreg(vgpu, mmio->reg) = I915_READ_FW(mmio->reg);
if (mmio->mask) {
vgpu_vreg(vgpu, mmio->reg) &= ~(mmio->mask << 16);
@@ -346,13 +349,17 @@ static void switch_mmio_to_host(struct intel_vgpu *vgpu, int ring_id)
if (mmio->in_context)
continue;
- I915_WRITE(mmio->reg, v);
- POSTING_READ(mmio->reg);
+ I915_WRITE_FW(mmio->reg, v);
+ last_reg = mmio->reg;
trace_render_mmio(vgpu->id, "restore",
i915_mmio_reg_offset(mmio->reg),
mmio->value, v);
}
+
+ /* Make sure the swiched MMIOs has taken effect. */
+ if (likely(INTEL_GVT_MMIO_OFFSET(last_reg)))
+ I915_READ_FW(last_reg);
}
/**
@@ -367,12 +374,23 @@ static void switch_mmio_to_host(struct intel_vgpu *vgpu, int ring_id)
void intel_gvt_switch_mmio(struct intel_vgpu *pre,
struct intel_vgpu *next, int ring_id)
{
+ struct drm_i915_private *dev_priv;
+
if (WARN_ON(!pre && !next))
return;
gvt_dbg_render("switch ring %d from %s to %s\n", ring_id,
pre ? "vGPU" : "host", next ? "vGPU" : "HOST");
+ dev_priv = pre ? pre->gvt->dev_priv : next->gvt->dev_priv;
+
+ /**
+ * We are using raw mmio access wrapper to improve the
+ * performace for batch mmio read/write, so we need
+ * handle forcewake mannually.
+ */
+ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
/**
* TODO: Optimize for vGPU to vGPU switch by merging
* switch_mmio_to_host() and switch_mmio_to_vgpu().
@@ -382,4 +400,6 @@ void intel_gvt_switch_mmio(struct intel_vgpu *pre,
if (next)
switch_mmio_to_vgpu(next, ring_id);
+
+ intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
}
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c
index 22e08eb..391800d 100644
--- a/drivers/gpu/drm/i915/gvt/scheduler.c
+++ b/drivers/gpu/drm/i915/gvt/scheduler.c
@@ -184,41 +184,52 @@ static int shadow_context_status_change(struct notifier_block *nb,
return NOTIFY_OK;
}
-static int dispatch_workload(struct intel_vgpu_workload *workload)
+static void shadow_context_descriptor_update(struct i915_gem_context *ctx,
+ struct intel_engine_cs *engine)
+{
+ struct intel_context *ce = &ctx->engine[engine->id];
+ u64 desc = 0;
+
+ desc = ce->lrc_desc;
+
+ /* Update bits 0-11 of the context descriptor which includes flags
+ * like GEN8_CTX_* cached in desc_template
+ */
+ desc &= U64_MAX << 12;
+ desc |= ctx->desc_template & ((1ULL << 12) - 1);
+
+ ce->lrc_desc = desc;
+}
+
+/**
+ * intel_gvt_scan_and_shadow_workload - audit the workload by scanning and
+ * shadow it as well, include ringbuffer,wa_ctx and ctx.
+ * @workload: an abstract entity for each execlist submission.
+ *
+ * This function is called before the workload submitting to i915, to make
+ * sure the content of the workload is valid.
+ */
+int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload)
{
int ring_id = workload->ring_id;
struct i915_gem_context *shadow_ctx = workload->vgpu->shadow_ctx;
struct drm_i915_private *dev_priv = workload->vgpu->gvt->dev_priv;
- struct intel_engine_cs *engine = dev_priv->engine[ring_id];
struct drm_i915_gem_request *rq;
struct intel_vgpu *vgpu = workload->vgpu;
- struct intel_ring *ring;
int ret;
- gvt_dbg_sched("ring id %d prepare to dispatch workload %p\n",
- ring_id, workload);
+ lockdep_assert_held(&dev_priv->drm.struct_mutex);
+
+ if (workload->shadowed)
+ return 0;
shadow_ctx->desc_template &= ~(0x3 << GEN8_CTX_ADDRESSING_MODE_SHIFT);
shadow_ctx->desc_template |= workload->ctx_desc.addressing_mode <<
GEN8_CTX_ADDRESSING_MODE_SHIFT;
- mutex_lock(&dev_priv->drm.struct_mutex);
-
- /* pin shadow context by gvt even the shadow context will be pinned
- * when i915 alloc request. That is because gvt will update the guest
- * context from shadow context when workload is completed, and at that
- * moment, i915 may already unpined the shadow context to make the
- * shadow_ctx pages invalid. So gvt need to pin itself. After update
- * the guest context, gvt can unpin the shadow_ctx safely.
- */
- ring = engine->context_pin(engine, shadow_ctx);
- if (IS_ERR(ring)) {
- ret = PTR_ERR(ring);
- gvt_vgpu_err("fail to pin shadow context\n");
- workload->status = ret;
- mutex_unlock(&dev_priv->drm.struct_mutex);
- return ret;
- }
+ if (!test_and_set_bit(ring_id, vgpu->shadow_ctx_desc_updated))
+ shadow_context_descriptor_update(shadow_ctx,
+ dev_priv->engine[ring_id]);
rq = i915_gem_request_alloc(dev_priv->engine[ring_id], shadow_ctx);
if (IS_ERR(rq)) {
@@ -231,7 +242,7 @@ static int dispatch_workload(struct intel_vgpu_workload *workload)
workload->req = i915_gem_request_get(rq);
- ret = intel_gvt_scan_and_shadow_workload(workload);
+ ret = intel_gvt_scan_and_shadow_ringbuffer(workload);
if (ret)
goto out;
@@ -246,25 +257,61 @@ static int dispatch_workload(struct intel_vgpu_workload *workload)
if (ret)
goto out;
+ workload->shadowed = true;
+
+out:
+ return ret;
+}
+
+static int dispatch_workload(struct intel_vgpu_workload *workload)
+{
+ int ring_id = workload->ring_id;
+ struct i915_gem_context *shadow_ctx = workload->vgpu->shadow_ctx;
+ struct drm_i915_private *dev_priv = workload->vgpu->gvt->dev_priv;
+ struct intel_engine_cs *engine = dev_priv->engine[ring_id];
+ struct intel_vgpu *vgpu = workload->vgpu;
+ struct intel_ring *ring;
+ int ret = 0;
+
+ gvt_dbg_sched("ring id %d prepare to dispatch workload %p\n",
+ ring_id, workload);
+
+ mutex_lock(&dev_priv->drm.struct_mutex);
+
+ ret = intel_gvt_scan_and_shadow_workload(workload);
+ if (ret)
+ goto out;
+
if (workload->prepare) {
ret = workload->prepare(workload);
if (ret)
goto out;
}
- gvt_dbg_sched("ring id %d submit workload to i915 %p\n",
- ring_id, workload->req);
+ /* pin shadow context by gvt even the shadow context will be pinned
+ * when i915 alloc request. That is because gvt will update the guest
+ * context from shadow context when workload is completed, and at that
+ * moment, i915 may already unpined the shadow context to make the
+ * shadow_ctx pages invalid. So gvt need to pin itself. After update
+ * the guest context, gvt can unpin the shadow_ctx safely.
+ */
+ ring = engine->context_pin(engine, shadow_ctx);
+ if (IS_ERR(ring)) {
+ ret = PTR_ERR(ring);
+ gvt_vgpu_err("fail to pin shadow context\n");
+ goto out;
+ }
- ret = 0;
- workload->dispatched = true;
out:
if (ret)
workload->status = ret;
- if (!IS_ERR_OR_NULL(rq))
- i915_add_request(rq);
- else
- engine->context_unpin(engine, shadow_ctx);
+ if (!IS_ERR_OR_NULL(workload->req)) {
+ gvt_dbg_sched("ring id %d submit workload to i915 %p\n",
+ ring_id, workload->req);
+ i915_add_request(workload->req);
+ workload->dispatched = true;
+ }
mutex_unlock(&dev_priv->drm.struct_mutex);
return ret;
@@ -617,7 +664,7 @@ err:
void intel_vgpu_clean_gvt_context(struct intel_vgpu *vgpu)
{
- i915_gem_context_put_unlocked(vgpu->shadow_ctx);
+ i915_gem_context_put(vgpu->shadow_ctx);
}
int intel_vgpu_init_gvt_context(struct intel_vgpu *vgpu)
@@ -631,5 +678,7 @@ int intel_vgpu_init_gvt_context(struct intel_vgpu *vgpu)
vgpu->shadow_ctx->engine[RCS].initialised = true;
+ bitmap_zero(vgpu->shadow_ctx_desc_updated, I915_NUM_ENGINES);
+
return 0;
}
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.h b/drivers/gpu/drm/i915/gvt/scheduler.h
index 9b6bf51..0d431a9 100644
--- a/drivers/gpu/drm/i915/gvt/scheduler.h
+++ b/drivers/gpu/drm/i915/gvt/scheduler.h
@@ -82,6 +82,7 @@ struct intel_vgpu_workload {
struct drm_i915_gem_request *req;
/* if this workload has been dispatched to i915? */
bool dispatched;
+ bool shadowed;
int status;
struct intel_vgpu_mm *shadow_mm;
diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c
index 3deadcb..02c61a1 100644
--- a/drivers/gpu/drm/i915/gvt/vgpu.c
+++ b/drivers/gpu/drm/i915/gvt/vgpu.c
@@ -43,6 +43,7 @@ void populate_pvinfo_page(struct intel_vgpu *vgpu)
vgpu_vreg(vgpu, vgtif_reg(version_minor)) = 0;
vgpu_vreg(vgpu, vgtif_reg(display_ready)) = 0;
vgpu_vreg(vgpu, vgtif_reg(vgt_id)) = vgpu->id;
+ vgpu_vreg(vgpu, vgtif_reg(vgt_caps)) = VGT_CAPS_FULL_48BIT_PPGTT;
vgpu_vreg(vgpu, vgtif_reg(avail_rs.mappable_gmadr.base)) =
vgpu_aperture_gmadr_base(vgpu);
vgpu_vreg(vgpu, vgtif_reg(avail_rs.mappable_gmadr.size)) =
@@ -504,11 +505,11 @@ void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr,
/* full GPU reset or device model level reset */
if (engine_mask == ALL_ENGINES || dmlr) {
- intel_vgpu_reset_gtt(vgpu, dmlr);
-
/*fence will not be reset during virtual reset */
- if (dmlr)
+ if (dmlr) {
+ intel_vgpu_reset_gtt(vgpu);
intel_vgpu_reset_resource(vgpu);
+ }
intel_vgpu_reset_mmio(vgpu, dmlr);
populate_pvinfo_page(vgpu);
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index d1bd53b..a36216b 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -28,6 +28,7 @@
#include <linux/debugfs.h>
#include <linux/sort.h>
+#include <linux/sched/mm.h>
#include "intel_drv.h"
static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node)
@@ -543,75 +544,6 @@ static int i915_gem_gtt_info(struct seq_file *m, void *data)
return 0;
}
-static int i915_gem_pageflip_info(struct seq_file *m, void *data)
-{
- struct drm_i915_private *dev_priv = node_to_i915(m->private);
- struct drm_device *dev = &dev_priv->drm;
- struct intel_crtc *crtc;
- int ret;
-
- ret = mutex_lock_interruptible(&dev->struct_mutex);
- if (ret)
- return ret;
-
- for_each_intel_crtc(dev, crtc) {
- const char pipe = pipe_name(crtc->pipe);
- const char plane = plane_name(crtc->plane);
- struct intel_flip_work *work;
-
- spin_lock_irq(&dev->event_lock);
- work = crtc->flip_work;
- if (work == NULL) {
- seq_printf(m, "No flip due on pipe %c (plane %c)\n",
- pipe, plane);
- } else {
- u32 pending;
- u32 addr;
-
- pending = atomic_read(&work->pending);
- if (pending) {
- seq_printf(m, "Flip ioctl preparing on pipe %c (plane %c)\n",
- pipe, plane);
- } else {
- seq_printf(m, "Flip pending (waiting for vsync) on pipe %c (plane %c)\n",
- pipe, plane);
- }
- if (work->flip_queued_req) {
- struct intel_engine_cs *engine = work->flip_queued_req->engine;
-
- seq_printf(m, "Flip queued on %s at seqno %x, last submitted seqno %x [current breadcrumb %x], completed? %d\n",
- engine->name,
- work->flip_queued_req->global_seqno,
- intel_engine_last_submit(engine),
- intel_engine_get_seqno(engine),
- i915_gem_request_completed(work->flip_queued_req));
- } else
- seq_printf(m, "Flip not associated with any ring\n");
- seq_printf(m, "Flip queued on frame %d, (was ready on frame %d), now %d\n",
- work->flip_queued_vblank,
- work->flip_ready_vblank,
- intel_crtc_get_vblank_counter(crtc));
- seq_printf(m, "%d prepares\n", atomic_read(&work->pending));
-
- if (INTEL_GEN(dev_priv) >= 4)
- addr = I915_HI_DISPBASE(I915_READ(DSPSURF(crtc->plane)));
- else
- addr = I915_READ(DSPADDR(crtc->plane));
- seq_printf(m, "Current scanout address 0x%08x\n", addr);
-
- if (work->pending_flip_obj) {
- seq_printf(m, "New framebuffer address 0x%08lx\n", (long)work->gtt_offset);
- seq_printf(m, "MMIO update completed? %d\n", addr == work->gtt_offset);
- }
- }
- spin_unlock_irq(&dev->event_lock);
- }
-
- mutex_unlock(&dev->struct_mutex);
-
- return 0;
-}
-
static int i915_gem_batch_pool_info(struct seq_file *m, void *data)
{
struct drm_i915_private *dev_priv = node_to_i915(m->private);
@@ -1159,7 +1091,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
reqf = I915_READ(GEN6_RPNSWREQ);
- if (IS_GEN9(dev_priv))
+ if (INTEL_GEN(dev_priv) >= 9)
reqf >>= 23;
else {
reqf &= ~GEN6_TURBO_DISABLE;
@@ -1181,7 +1113,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
rpdownei = I915_READ(GEN6_RP_CUR_DOWN_EI) & GEN6_CURIAVG_MASK;
rpcurdown = I915_READ(GEN6_RP_CUR_DOWN) & GEN6_CURBSYTAVG_MASK;
rpprevdown = I915_READ(GEN6_RP_PREV_DOWN) & GEN6_CURBSYTAVG_MASK;
- if (IS_GEN9(dev_priv))
+ if (INTEL_GEN(dev_priv) >= 9)
cagf = (rpstat & GEN9_CAGF_MASK) >> GEN9_CAGF_SHIFT;
else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
cagf = (rpstat & HSW_CAGF_MASK) >> HSW_CAGF_SHIFT;
@@ -1210,7 +1142,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
dev_priv->rps.pm_intrmsk_mbz);
seq_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status);
seq_printf(m, "Render p-state ratio: %d\n",
- (gt_perf_status & (IS_GEN9(dev_priv) ? 0x1ff00 : 0xff00)) >> 8);
+ (gt_perf_status & (INTEL_GEN(dev_priv) >= 9 ? 0x1ff00 : 0xff00)) >> 8);
seq_printf(m, "Render p-state VID: %d\n",
gt_perf_status & 0xff);
seq_printf(m, "Render p-state limit: %d\n",
@@ -1241,18 +1173,21 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
max_freq = (IS_GEN9_LP(dev_priv) ? rp_state_cap >> 0 :
rp_state_cap >> 16) & 0xff;
- max_freq *= (IS_GEN9_BC(dev_priv) ? GEN9_FREQ_SCALER : 1);
+ max_freq *= (IS_GEN9_BC(dev_priv) ||
+ IS_CANNONLAKE(dev_priv) ? GEN9_FREQ_SCALER : 1);
seq_printf(m, "Lowest (RPN) frequency: %dMHz\n",
intel_gpu_freq(dev_priv, max_freq));
max_freq = (rp_state_cap & 0xff00) >> 8;
- max_freq *= (IS_GEN9_BC(dev_priv) ? GEN9_FREQ_SCALER : 1);
+ max_freq *= (IS_GEN9_BC(dev_priv) ||
+ IS_CANNONLAKE(dev_priv) ? GEN9_FREQ_SCALER : 1);
seq_printf(m, "Nominal (RP1) frequency: %dMHz\n",
intel_gpu_freq(dev_priv, max_freq));
max_freq = (IS_GEN9_LP(dev_priv) ? rp_state_cap >> 16 :
rp_state_cap >> 0) & 0xff;
- max_freq *= (IS_GEN9_BC(dev_priv) ? GEN9_FREQ_SCALER : 1);
+ max_freq *= (IS_GEN9_BC(dev_priv) ||
+ IS_CANNONLAKE(dev_priv) ? GEN9_FREQ_SCALER : 1);
seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n",
intel_gpu_freq(dev_priv, max_freq));
seq_printf(m, "Max overclocked frequency: %dMHz\n",
@@ -1407,6 +1342,23 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused)
return 0;
}
+static int i915_reset_info(struct seq_file *m, void *unused)
+{
+ struct drm_i915_private *dev_priv = node_to_i915(m->private);
+ struct i915_gpu_error *error = &dev_priv->gpu_error;
+ struct intel_engine_cs *engine;
+ enum intel_engine_id id;
+
+ seq_printf(m, "full gpu reset = %u\n", i915_reset_count(error));
+
+ for_each_engine(engine, dev_priv, id) {
+ seq_printf(m, "%s = %u\n", engine->name,
+ i915_reset_engine_count(error, engine));
+ }
+
+ return 0;
+}
+
static int ironlake_drpc_info(struct seq_file *m)
{
struct drm_i915_private *dev_priv = node_to_i915(m->private);
@@ -1838,7 +1790,7 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused)
if (ret)
goto out;
- if (IS_GEN9_BC(dev_priv)) {
+ if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
/* Convert GT frequency to 50 HZ units */
min_gpu_freq =
dev_priv->rps.min_freq_softlimit / GEN9_FREQ_SCALER;
@@ -1858,7 +1810,8 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused)
&ia_freq);
seq_printf(m, "%d\t\t%d\t\t\t\t%d\n",
intel_gpu_freq(dev_priv, (gpu_freq *
- (IS_GEN9_BC(dev_priv) ?
+ (IS_GEN9_BC(dev_priv) ||
+ IS_CANNONLAKE(dev_priv) ?
GEN9_FREQ_SCALER : 1))),
((ia_freq >> 0) & 0xff) * 100,
((ia_freq >> 8) & 0xff) * 100);
@@ -1914,7 +1867,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
return ret;
#ifdef CONFIG_DRM_FBDEV_EMULATION
- if (dev_priv->fbdev) {
+ if (dev_priv->fbdev && dev_priv->fbdev->helper.fb) {
fbdev_fb = to_intel_framebuffer(dev_priv->fbdev->helper.fb);
seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, modifier 0x%llx, refcount %d, obj ",
@@ -1970,7 +1923,7 @@ static int i915_context_status(struct seq_file *m, void *unused)
if (ret)
return ret;
- list_for_each_entry(ctx, &dev_priv->context_list, link) {
+ list_for_each_entry(ctx, &dev_priv->contexts.list, link) {
seq_printf(m, "HW context %u ", ctx->hw_id);
if (ctx->pid) {
struct task_struct *task;
@@ -2002,12 +1955,6 @@ static int i915_context_status(struct seq_file *m, void *unused)
seq_putc(m, '\n');
}
- seq_printf(m,
- "\tvma hashtable size=%u (actual %lu), count=%u\n",
- ctx->vma_lut.ht_size,
- BIT(ctx->vma_lut.ht_bits),
- ctx->vma_lut.ht_count);
-
seq_putc(m, '\n');
}
@@ -2076,7 +2023,7 @@ static int i915_dump_lrc(struct seq_file *m, void *unused)
if (ret)
return ret;
- list_for_each_entry(ctx, &dev_priv->context_list, link)
+ list_for_each_entry(ctx, &dev_priv->contexts.list, link)
for_each_engine(engine, dev_priv, id)
i915_dump_lrc_obj(m, ctx, engine);
@@ -2310,6 +2257,8 @@ static int i915_rps_boost_info(struct seq_file *m, void *data)
seq_printf(m, "GPU busy? %s [%d requests]\n",
yesno(dev_priv->gt.awake), dev_priv->gt.active_requests);
seq_printf(m, "CPU waiting? %d\n", count_irq_waiters(dev_priv));
+ seq_printf(m, "Boosts outstanding? %d\n",
+ atomic_read(&dev_priv->rps.num_waiters));
seq_printf(m, "Frequency requested %d\n",
intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq));
seq_printf(m, " min hard:%d, soft:%d; max soft:%d, hard:%d\n",
@@ -2323,22 +2272,20 @@ static int i915_rps_boost_info(struct seq_file *m, void *data)
intel_gpu_freq(dev_priv, dev_priv->rps.boost_freq));
mutex_lock(&dev->filelist_mutex);
- spin_lock(&dev_priv->rps.client_lock);
list_for_each_entry_reverse(file, &dev->filelist, lhead) {
struct drm_i915_file_private *file_priv = file->driver_priv;
struct task_struct *task;
rcu_read_lock();
task = pid_task(file->pid, PIDTYPE_PID);
- seq_printf(m, "%s [%d]: %d boosts%s\n",
+ seq_printf(m, "%s [%d]: %d boosts\n",
task ? task->comm : "<unknown>",
task ? task->pid : -1,
- file_priv->rps.boosts,
- list_empty(&file_priv->rps.link) ? "" : ", active");
+ atomic_read(&file_priv->rps.boosts));
rcu_read_unlock();
}
- seq_printf(m, "Kernel (anonymous) boosts: %d\n", dev_priv->rps.boosts);
- spin_unlock(&dev_priv->rps.client_lock);
+ seq_printf(m, "Kernel (anonymous) boosts: %d\n",
+ atomic_read(&dev_priv->rps.boosts));
mutex_unlock(&dev->filelist_mutex);
if (INTEL_GEN(dev_priv) >= 6 &&
@@ -2831,7 +2778,7 @@ out:
static int i915_energy_uJ(struct seq_file *m, void *data)
{
struct drm_i915_private *dev_priv = node_to_i915(m->private);
- u64 power;
+ unsigned long long power;
u32 units;
if (INTEL_GEN(dev_priv) < 6)
@@ -2839,15 +2786,18 @@ static int i915_energy_uJ(struct seq_file *m, void *data)
intel_runtime_pm_get(dev_priv);
- rdmsrl(MSR_RAPL_POWER_UNIT, power);
- power = (power & 0x1f00) >> 8;
- units = 1000000 / (1 << power); /* convert to uJ */
+ if (rdmsrl_safe(MSR_RAPL_POWER_UNIT, &power)) {
+ intel_runtime_pm_put(dev_priv);
+ return -ENODEV;
+ }
+
+ units = (power & 0x1f00) >> 8;
power = I915_READ(MCH_SECP_NRG_STTS);
- power *= units;
+ power = (1000000 * power) >> units; /* convert to uJ */
intel_runtime_pm_put(dev_priv);
- seq_printf(m, "%llu", (long long unsigned)power);
+ seq_printf(m, "%llu", power);
return 0;
}
@@ -3289,6 +3239,7 @@ static int i915_display_info(struct seq_file *m, void *unused)
static int i915_engine_info(struct seq_file *m, void *unused)
{
struct drm_i915_private *dev_priv = node_to_i915(m->private);
+ struct i915_gpu_error *error = &dev_priv->gpu_error;
struct intel_engine_cs *engine;
enum intel_engine_id id;
@@ -3312,6 +3263,8 @@ static int i915_engine_info(struct seq_file *m, void *unused)
engine->hangcheck.seqno,
jiffies_to_msecs(jiffies - engine->hangcheck.action_timestamp),
engine->timeline->inflight_seqnos);
+ seq_printf(m, "\tReset count: %d\n",
+ i915_reset_engine_count(error, engine));
rcu_read_lock();
@@ -3370,8 +3323,10 @@ static int i915_engine_info(struct seq_file *m, void *unused)
ptr = I915_READ(RING_CONTEXT_STATUS_PTR(engine));
read = GEN8_CSB_READ_PTR(ptr);
write = GEN8_CSB_WRITE_PTR(ptr);
- seq_printf(m, "\tExeclist CSB read %d, write %d\n",
- read, write);
+ seq_printf(m, "\tExeclist CSB read %d, write %d, interrupt posted? %s\n",
+ read, write,
+ yesno(test_bit(ENGINE_IRQ_EXECLIST,
+ &engine->irq_posted)));
if (read >= GEN8_CSB_ENTRIES)
read = 0;
if (write >= GEN8_CSB_ENTRIES)
@@ -3758,13 +3713,18 @@ static ssize_t i915_displayport_test_active_write(struct file *file,
drm_connector_list_iter_begin(dev, &conn_iter);
drm_for_each_connector_iter(connector, &conn_iter) {
+ struct intel_encoder *encoder;
+
if (connector->connector_type !=
DRM_MODE_CONNECTOR_DisplayPort)
continue;
- if (connector->status == connector_status_connected &&
- connector->encoder != NULL) {
- intel_dp = enc_to_intel_dp(connector->encoder);
+ encoder = to_intel_encoder(connector->encoder);
+ if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
+ continue;
+
+ if (encoder && connector->status == connector_status_connected) {
+ intel_dp = enc_to_intel_dp(&encoder->base);
status = kstrtoint(input_buffer, 10, &val);
if (status < 0)
break;
@@ -3796,13 +3756,18 @@ static int i915_displayport_test_active_show(struct seq_file *m, void *data)
drm_connector_list_iter_begin(dev, &conn_iter);
drm_for_each_connector_iter(connector, &conn_iter) {
+ struct intel_encoder *encoder;
+
if (connector->connector_type !=
DRM_MODE_CONNECTOR_DisplayPort)
continue;
- if (connector->status == connector_status_connected &&
- connector->encoder != NULL) {
- intel_dp = enc_to_intel_dp(connector->encoder);
+ encoder = to_intel_encoder(connector->encoder);
+ if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
+ continue;
+
+ if (encoder && connector->status == connector_status_connected) {
+ intel_dp = enc_to_intel_dp(&encoder->base);
if (intel_dp->compliance.test_active)
seq_puts(m, "1");
else
@@ -3842,13 +3807,18 @@ static int i915_displayport_test_data_show(struct seq_file *m, void *data)
drm_connector_list_iter_begin(dev, &conn_iter);
drm_for_each_connector_iter(connector, &conn_iter) {
+ struct intel_encoder *encoder;
+
if (connector->connector_type !=
DRM_MODE_CONNECTOR_DisplayPort)
continue;
- if (connector->status == connector_status_connected &&
- connector->encoder != NULL) {
- intel_dp = enc_to_intel_dp(connector->encoder);
+ encoder = to_intel_encoder(connector->encoder);
+ if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
+ continue;
+
+ if (encoder && connector->status == connector_status_connected) {
+ intel_dp = enc_to_intel_dp(&encoder->base);
if (intel_dp->compliance.test_type ==
DP_TEST_LINK_EDID_READ)
seq_printf(m, "%lx",
@@ -3895,13 +3865,18 @@ static int i915_displayport_test_type_show(struct seq_file *m, void *data)
drm_connector_list_iter_begin(dev, &conn_iter);
drm_for_each_connector_iter(connector, &conn_iter) {
+ struct intel_encoder *encoder;
+
if (connector->connector_type !=
DRM_MODE_CONNECTOR_DisplayPort)
continue;
- if (connector->status == connector_status_connected &&
- connector->encoder != NULL) {
- intel_dp = enc_to_intel_dp(connector->encoder);
+ encoder = to_intel_encoder(connector->encoder);
+ if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
+ continue;
+
+ if (encoder && connector->status == connector_status_connected) {
+ intel_dp = enc_to_intel_dp(&encoder->base);
seq_printf(m, "%02lx", intel_dp->compliance.test_type);
} else
seq_puts(m, "0");
@@ -4331,7 +4306,7 @@ i915_drop_caches_set(void *data, u64 val)
mutex_unlock(&dev->struct_mutex);
}
- lockdep_set_current_reclaim_state(GFP_KERNEL);
+ fs_reclaim_acquire(GFP_KERNEL);
if (val & DROP_BOUND)
i915_gem_shrink(dev_priv, LONG_MAX, I915_SHRINK_BOUND);
@@ -4340,7 +4315,7 @@ i915_drop_caches_set(void *data, u64 val)
if (val & DROP_SHRINK_ALL)
i915_gem_shrink_all(dev_priv);
- lockdep_clear_current_reclaim_state();
+ fs_reclaim_release(GFP_KERNEL);
if (val & DROP_FREED) {
synchronize_rcu();
@@ -4810,7 +4785,6 @@ static const struct drm_info_list i915_debugfs_list[] = {
{"i915_gem_gtt", i915_gem_gtt_info, 0},
{"i915_gem_pin_display", i915_gem_gtt_info, 0, (void *)1},
{"i915_gem_stolen", i915_gem_stolen_list_info },
- {"i915_gem_pageflip", i915_gem_pageflip_info, 0},
{"i915_gem_request", i915_gem_request_info, 0},
{"i915_gem_seqno", i915_gem_seqno_info, 0},
{"i915_gem_fence_regs", i915_gem_fence_regs_info, 0},
@@ -4824,6 +4798,7 @@ static const struct drm_info_list i915_debugfs_list[] = {
{"i915_huc_load_status", i915_huc_load_status_info, 0},
{"i915_frequency_info", i915_frequency_info, 0},
{"i915_hangcheck_info", i915_hangcheck_info, 0},
+ {"i915_reset_info", i915_reset_info, 0},
{"i915_drpc_info", i915_drpc_info, 0},
{"i915_emon_status", i915_emon_status, 0},
{"i915_ring_freq_table", i915_ring_freq_table, 0},
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index fc307e03..4310022 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -132,9 +132,13 @@ static enum intel_pch intel_virt_detect_pch(struct drm_i915_private *dev_priv)
DRM_DEBUG_KMS("Assuming Ibex Peak PCH\n");
} else if (IS_GEN6(dev_priv) || IS_IVYBRIDGE(dev_priv)) {
ret = PCH_CPT;
- DRM_DEBUG_KMS("Assuming CouarPoint PCH\n");
+ DRM_DEBUG_KMS("Assuming CougarPoint PCH\n");
} else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
ret = PCH_LPT;
+ if (IS_HSW_ULT(dev_priv) || IS_BDW_ULT(dev_priv))
+ dev_priv->pch_id = INTEL_PCH_LPT_LP_DEVICE_ID_TYPE;
+ else
+ dev_priv->pch_id = INTEL_PCH_LPT_DEVICE_ID_TYPE;
DRM_DEBUG_KMS("Assuming LynxPoint PCH\n");
} else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
ret = PCH_SPT;
@@ -173,29 +177,25 @@ static void intel_detect_pch(struct drm_i915_private *dev_priv)
while ((pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, pch))) {
if (pch->vendor == PCI_VENDOR_ID_INTEL) {
unsigned short id = pch->device & INTEL_PCH_DEVICE_ID_MASK;
- unsigned short id_ext = pch->device &
- INTEL_PCH_DEVICE_ID_MASK_EXT;
+
+ dev_priv->pch_id = id;
if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) {
- dev_priv->pch_id = id;
dev_priv->pch_type = PCH_IBX;
DRM_DEBUG_KMS("Found Ibex Peak PCH\n");
WARN_ON(!IS_GEN5(dev_priv));
} else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) {
- dev_priv->pch_id = id;
dev_priv->pch_type = PCH_CPT;
DRM_DEBUG_KMS("Found CougarPoint PCH\n");
- WARN_ON(!(IS_GEN6(dev_priv) ||
- IS_IVYBRIDGE(dev_priv)));
+ WARN_ON(!IS_GEN6(dev_priv) &&
+ !IS_IVYBRIDGE(dev_priv));
} else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) {
/* PantherPoint is CPT compatible */
- dev_priv->pch_id = id;
dev_priv->pch_type = PCH_CPT;
DRM_DEBUG_KMS("Found PantherPoint PCH\n");
- WARN_ON(!(IS_GEN6(dev_priv) ||
- IS_IVYBRIDGE(dev_priv)));
+ WARN_ON(!IS_GEN6(dev_priv) &&
+ !IS_IVYBRIDGE(dev_priv));
} else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) {
- dev_priv->pch_id = id;
dev_priv->pch_type = PCH_LPT;
DRM_DEBUG_KMS("Found LynxPoint PCH\n");
WARN_ON(!IS_HASWELL(dev_priv) &&
@@ -203,51 +203,60 @@ static void intel_detect_pch(struct drm_i915_private *dev_priv)
WARN_ON(IS_HSW_ULT(dev_priv) ||
IS_BDW_ULT(dev_priv));
} else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) {
- dev_priv->pch_id = id;
dev_priv->pch_type = PCH_LPT;
DRM_DEBUG_KMS("Found LynxPoint LP PCH\n");
WARN_ON(!IS_HASWELL(dev_priv) &&
!IS_BROADWELL(dev_priv));
WARN_ON(!IS_HSW_ULT(dev_priv) &&
!IS_BDW_ULT(dev_priv));
+ } else if (id == INTEL_PCH_WPT_DEVICE_ID_TYPE) {
+ /* WildcatPoint is LPT compatible */
+ dev_priv->pch_type = PCH_LPT;
+ DRM_DEBUG_KMS("Found WildcatPoint PCH\n");
+ WARN_ON(!IS_HASWELL(dev_priv) &&
+ !IS_BROADWELL(dev_priv));
+ WARN_ON(IS_HSW_ULT(dev_priv) ||
+ IS_BDW_ULT(dev_priv));
+ } else if (id == INTEL_PCH_WPT_LP_DEVICE_ID_TYPE) {
+ /* WildcatPoint is LPT compatible */
+ dev_priv->pch_type = PCH_LPT;
+ DRM_DEBUG_KMS("Found WildcatPoint LP PCH\n");
+ WARN_ON(!IS_HASWELL(dev_priv) &&
+ !IS_BROADWELL(dev_priv));
+ WARN_ON(!IS_HSW_ULT(dev_priv) &&
+ !IS_BDW_ULT(dev_priv));
} else if (id == INTEL_PCH_SPT_DEVICE_ID_TYPE) {
- dev_priv->pch_id = id;
dev_priv->pch_type = PCH_SPT;
DRM_DEBUG_KMS("Found SunrisePoint PCH\n");
WARN_ON(!IS_SKYLAKE(dev_priv) &&
!IS_KABYLAKE(dev_priv));
- } else if (id_ext == INTEL_PCH_SPT_LP_DEVICE_ID_TYPE) {
- dev_priv->pch_id = id_ext;
+ } else if (id == INTEL_PCH_SPT_LP_DEVICE_ID_TYPE) {
dev_priv->pch_type = PCH_SPT;
DRM_DEBUG_KMS("Found SunrisePoint LP PCH\n");
WARN_ON(!IS_SKYLAKE(dev_priv) &&
!IS_KABYLAKE(dev_priv));
} else if (id == INTEL_PCH_KBP_DEVICE_ID_TYPE) {
- dev_priv->pch_id = id;
dev_priv->pch_type = PCH_KBP;
- DRM_DEBUG_KMS("Found KabyPoint PCH\n");
+ DRM_DEBUG_KMS("Found Kaby Lake PCH (KBP)\n");
WARN_ON(!IS_SKYLAKE(dev_priv) &&
!IS_KABYLAKE(dev_priv));
} else if (id == INTEL_PCH_CNP_DEVICE_ID_TYPE) {
- dev_priv->pch_id = id;
dev_priv->pch_type = PCH_CNP;
- DRM_DEBUG_KMS("Found CannonPoint PCH\n");
+ DRM_DEBUG_KMS("Found Cannon Lake PCH (CNP)\n");
WARN_ON(!IS_CANNONLAKE(dev_priv) &&
!IS_COFFEELAKE(dev_priv));
- } else if (id_ext == INTEL_PCH_CNP_LP_DEVICE_ID_TYPE) {
- dev_priv->pch_id = id_ext;
+ } else if (id == INTEL_PCH_CNP_LP_DEVICE_ID_TYPE) {
dev_priv->pch_type = PCH_CNP;
- DRM_DEBUG_KMS("Found CannonPoint LP PCH\n");
+ DRM_DEBUG_KMS("Found Cannon Lake LP PCH (CNP-LP)\n");
WARN_ON(!IS_CANNONLAKE(dev_priv) &&
!IS_COFFEELAKE(dev_priv));
- } else if ((id == INTEL_PCH_P2X_DEVICE_ID_TYPE) ||
- (id == INTEL_PCH_P3X_DEVICE_ID_TYPE) ||
- ((id == INTEL_PCH_QEMU_DEVICE_ID_TYPE) &&
+ } else if (id == INTEL_PCH_P2X_DEVICE_ID_TYPE ||
+ id == INTEL_PCH_P3X_DEVICE_ID_TYPE ||
+ (id == INTEL_PCH_QEMU_DEVICE_ID_TYPE &&
pch->subsystem_vendor ==
PCI_SUBVENDOR_ID_REDHAT_QUMRANET &&
pch->subsystem_device ==
PCI_SUBDEVICE_ID_QEMU)) {
- dev_priv->pch_id = id;
dev_priv->pch_type =
intel_virt_detect_pch(dev_priv);
} else
@@ -331,6 +340,8 @@ static int i915_getparam(struct drm_device *dev, void *data,
break;
case I915_PARAM_HAS_GPU_RESET:
value = i915.enable_hangcheck && intel_has_gpu_reset(dev_priv);
+ if (value && intel_has_reset_engine(dev_priv))
+ value = 2;
break;
case I915_PARAM_HAS_RESOURCE_STREAMER:
value = HAS_RESOURCE_STREAMER(dev_priv);
@@ -377,6 +388,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
case I915_PARAM_HAS_EXEC_FENCE:
case I915_PARAM_HAS_EXEC_CAPTURE:
case I915_PARAM_HAS_EXEC_BATCH_FIRST:
+ case I915_PARAM_HAS_EXEC_FENCE_ARRAY:
/* For the time being all of these are always true;
* if some supported hardware does not have one of these
* features this value needs to be provided from
@@ -585,16 +597,19 @@ static const struct vga_switcheroo_client_ops i915_switcheroo_ops = {
static void i915_gem_fini(struct drm_i915_private *dev_priv)
{
+ /* Flush any outstanding unpin_work. */
+ i915_gem_drain_workqueue(dev_priv);
+
mutex_lock(&dev_priv->drm.struct_mutex);
intel_uc_fini_hw(dev_priv);
i915_gem_cleanup_engines(dev_priv);
- i915_gem_context_fini(dev_priv);
+ i915_gem_contexts_fini(dev_priv);
i915_gem_cleanup_userptr(dev_priv);
mutex_unlock(&dev_priv->drm.struct_mutex);
i915_gem_drain_freed_objects(dev_priv);
- WARN_ON(!list_empty(&dev_priv->context_list));
+ WARN_ON(!list_empty(&dev_priv->contexts.list));
}
static int i915_load_modeset_init(struct drm_device *dev)
@@ -862,7 +877,6 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv,
spin_lock_init(&dev_priv->uncore.lock);
spin_lock_init(&dev_priv->mm.object_stat_lock);
- spin_lock_init(&dev_priv->mmio_flip_lock);
mutex_init(&dev_priv->sb_lock);
mutex_init(&dev_priv->modeset_restore_lock);
mutex_init(&dev_priv->av_mutex);
@@ -1227,6 +1241,7 @@ static void i915_driver_register(struct drm_i915_private *dev_priv)
*/
static void i915_driver_unregister(struct drm_i915_private *dev_priv)
{
+ intel_fbdev_unregister(dev_priv);
intel_audio_deinit(dev_priv);
intel_gpu_ips_teardown();
@@ -1319,7 +1334,7 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent)
ret = i915_load_modeset_init(&dev_priv->drm);
if (ret < 0)
- goto out_cleanup_vblank;
+ goto out_cleanup_hw;
i915_driver_register(dev_priv);
@@ -1336,8 +1351,6 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent)
return 0;
-out_cleanup_vblank:
- drm_vblank_cleanup(&dev_priv->drm);
out_cleanup_hw:
i915_driver_cleanup_hw(dev_priv);
out_cleanup_mmio:
@@ -1360,7 +1373,7 @@ void i915_driver_unload(struct drm_device *dev)
struct drm_i915_private *dev_priv = to_i915(dev);
struct pci_dev *pdev = dev_priv->drm.pdev;
- intel_fbdev_fini(dev);
+ i915_driver_unregister(dev_priv);
if (i915_gem_suspend(dev_priv))
DRM_ERROR("failed to idle hardware; continuing to unload!\n");
@@ -1371,10 +1384,6 @@ void i915_driver_unload(struct drm_device *dev)
intel_gvt_cleanup(dev_priv);
- i915_driver_unregister(dev_priv);
-
- drm_vblank_cleanup(dev);
-
intel_modeset_cleanup(dev);
/*
@@ -1400,9 +1409,6 @@ void i915_driver_unload(struct drm_device *dev)
cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work);
i915_reset_error_state(dev_priv);
- /* Flush any outstanding unpin_work. */
- drain_workqueue(dev_priv->wq);
-
i915_gem_fini(dev_priv);
intel_uc_fini_fw(dev_priv);
intel_fbc_cleanup_cfb(dev_priv);
@@ -1427,9 +1433,10 @@ static void i915_driver_release(struct drm_device *dev)
static int i915_driver_open(struct drm_device *dev, struct drm_file *file)
{
+ struct drm_i915_private *i915 = to_i915(dev);
int ret;
- ret = i915_gem_open(dev, file);
+ ret = i915_gem_open(i915, file);
if (ret)
return ret;
@@ -1459,7 +1466,7 @@ static void i915_driver_postclose(struct drm_device *dev, struct drm_file *file)
struct drm_i915_file_private *file_priv = file->driver_priv;
mutex_lock(&dev->struct_mutex);
- i915_gem_context_close(dev, file);
+ i915_gem_context_close(file);
i915_gem_release(dev, file);
mutex_unlock(&dev->struct_mutex);
@@ -1825,7 +1832,8 @@ static int i915_resume_switcheroo(struct drm_device *dev)
/**
* i915_reset - reset chip after a hang
- * @dev_priv: device private to reset
+ * @i915: #drm_i915_private to reset
+ * @flags: Instructions
*
* Reset the chip. Useful if a hang is detected. Marks the device as wedged
* on failure.
@@ -1840,33 +1848,34 @@ static int i915_resume_switcheroo(struct drm_device *dev)
* - re-init interrupt state
* - re-init display
*/
-void i915_reset(struct drm_i915_private *dev_priv)
+void i915_reset(struct drm_i915_private *i915, unsigned int flags)
{
- struct i915_gpu_error *error = &dev_priv->gpu_error;
+ struct i915_gpu_error *error = &i915->gpu_error;
int ret;
- lockdep_assert_held(&dev_priv->drm.struct_mutex);
+ lockdep_assert_held(&i915->drm.struct_mutex);
GEM_BUG_ON(!test_bit(I915_RESET_BACKOFF, &error->flags));
if (!test_bit(I915_RESET_HANDOFF, &error->flags))
return;
/* Clear any previous failed attempts at recovery. Time to try again. */
- if (!i915_gem_unset_wedged(dev_priv))
+ if (!i915_gem_unset_wedged(i915))
goto wakeup;
+ if (!(flags & I915_RESET_QUIET))
+ dev_notice(i915->drm.dev, "Resetting chip after gpu hang\n");
error->reset_count++;
- pr_notice("drm/i915: Resetting chip after gpu hang\n");
- disable_irq(dev_priv->drm.irq);
- ret = i915_gem_reset_prepare(dev_priv);
+ disable_irq(i915->drm.irq);
+ ret = i915_gem_reset_prepare(i915);
if (ret) {
DRM_ERROR("GPU recovery failed\n");
- intel_gpu_reset(dev_priv, ALL_ENGINES);
+ intel_gpu_reset(i915, ALL_ENGINES);
goto error;
}
- ret = intel_gpu_reset(dev_priv, ALL_ENGINES);
+ ret = intel_gpu_reset(i915, ALL_ENGINES);
if (ret) {
if (ret != -ENODEV)
DRM_ERROR("Failed to reset chip: %i\n", ret);
@@ -1875,8 +1884,8 @@ void i915_reset(struct drm_i915_private *dev_priv)
goto error;
}
- i915_gem_reset(dev_priv);
- intel_overlay_reset(dev_priv);
+ i915_gem_reset(i915);
+ intel_overlay_reset(i915);
/* Ok, now get things going again... */
@@ -1892,17 +1901,17 @@ void i915_reset(struct drm_i915_private *dev_priv)
* was running at the time of the reset (i.e. we weren't VT
* switched away).
*/
- ret = i915_gem_init_hw(dev_priv);
+ ret = i915_gem_init_hw(i915);
if (ret) {
DRM_ERROR("Failed hw init on reset %d\n", ret);
goto error;
}
- i915_queue_hangcheck(dev_priv);
+ i915_queue_hangcheck(i915);
finish:
- i915_gem_reset_finish(dev_priv);
- enable_irq(dev_priv->drm.irq);
+ i915_gem_reset_finish(i915);
+ enable_irq(i915->drm.irq);
wakeup:
clear_bit(I915_RESET_HANDOFF, &error->flags);
@@ -1910,10 +1919,74 @@ wakeup:
return;
error:
- i915_gem_set_wedged(dev_priv);
+ i915_gem_set_wedged(i915);
+ i915_gem_retire_requests(i915);
goto finish;
}
+/**
+ * i915_reset_engine - reset GPU engine to recover from a hang
+ * @engine: engine to reset
+ * @flags: options
+ *
+ * Reset a specific GPU engine. Useful if a hang is detected.
+ * Returns zero on successful reset or otherwise an error code.
+ *
+ * Procedure is:
+ * - identifies the request that caused the hang and it is dropped
+ * - reset engine (which will force the engine to idle)
+ * - re-init/configure engine
+ */
+int i915_reset_engine(struct intel_engine_cs *engine, unsigned int flags)
+{
+ struct i915_gpu_error *error = &engine->i915->gpu_error;
+ struct drm_i915_gem_request *active_request;
+ int ret;
+
+ GEM_BUG_ON(!test_bit(I915_RESET_ENGINE + engine->id, &error->flags));
+
+ if (!(flags & I915_RESET_QUIET)) {
+ dev_notice(engine->i915->drm.dev,
+ "Resetting %s after gpu hang\n", engine->name);
+ }
+ error->reset_engine_count[engine->id]++;
+
+ active_request = i915_gem_reset_prepare_engine(engine);
+ if (IS_ERR(active_request)) {
+ DRM_DEBUG_DRIVER("Previous reset failed, promote to full reset\n");
+ ret = PTR_ERR(active_request);
+ goto out;
+ }
+
+ ret = intel_gpu_reset(engine->i915, intel_engine_flag(engine));
+ if (ret) {
+ /* If we fail here, we expect to fallback to a global reset */
+ DRM_DEBUG_DRIVER("Failed to reset %s, ret=%d\n",
+ engine->name, ret);
+ goto out;
+ }
+
+ /*
+ * The request that caused the hang is stuck on elsp, we know the
+ * active request and can drop it, adjust head to skip the offending
+ * request to resume executing remaining requests in the queue.
+ */
+ i915_gem_reset_engine(engine, active_request);
+
+ /*
+ * The engine and its registers (and workarounds in case of render)
+ * have been reset to their default values. Follow the init_ring
+ * process to program RING_MODE, HWSP and re-enable submission.
+ */
+ ret = engine->init_hw(engine);
+ if (ret)
+ goto out;
+
+out:
+ i915_gem_reset_finish_engine(engine);
+ return ret;
+}
+
static int i915_pm_suspend(struct device *kdev)
{
struct pci_dev *pdev = to_pci_dev(kdev);
@@ -2657,6 +2730,8 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_GETPARAM, i915_gem_context_getparam_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_SETPARAM, i915_gem_context_setparam_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_PERF_OPEN, i915_perf_open_ioctl, DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(I915_PERF_ADD_CONFIG, i915_perf_add_config_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(I915_PERF_REMOVE_CONFIG, i915_perf_remove_config_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
};
static struct drm_driver driver = {
@@ -2665,12 +2740,11 @@ static struct drm_driver driver = {
*/
.driver_features =
DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME |
- DRIVER_RENDER | DRIVER_MODESET | DRIVER_ATOMIC,
+ DRIVER_RENDER | DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_SYNCOBJ,
.release = i915_driver_release,
.open = i915_driver_open,
.lastclose = i915_driver_lastclose,
.postclose = i915_driver_postclose,
- .set_busid = drm_pci_set_busid,
.gem_close_object = i915_gem_close_object,
.gem_free_object_unlocked = i915_gem_free_object,
@@ -2683,7 +2757,6 @@ static struct drm_driver driver = {
.dumb_create = i915_gem_dumb_create,
.dumb_map_offset = i915_gem_mmap_gtt,
- .dumb_destroy = drm_gem_dumb_destroy,
.ioctls = i915_ioctls,
.num_ioctls = ARRAY_SIZE(i915_ioctls),
.fops = &i915_driver_fops,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e1f7c97..60267e3 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -80,8 +80,8 @@
#define DRIVER_NAME "i915"
#define DRIVER_DESC "Intel Graphics"
-#define DRIVER_DATE "20170619"
-#define DRIVER_TIMESTAMP 1497857498
+#define DRIVER_DATE "20170818"
+#define DRIVER_TIMESTAMP 1503088845
/* Use I915_STATE_WARN(x) and I915_STATE_WARN_ON() (rather than WARN() and
* WARN_ON()) for hw state sanity checks to check for unexpected conditions
@@ -122,7 +122,7 @@ static inline bool is_fixed16_zero(uint_fixed_16_16_t val)
return false;
}
-static inline uint_fixed_16_16_t u32_to_fixed_16_16(uint32_t val)
+static inline uint_fixed_16_16_t u32_to_fixed16(uint32_t val)
{
uint_fixed_16_16_t fp;
@@ -132,17 +132,17 @@ static inline uint_fixed_16_16_t u32_to_fixed_16_16(uint32_t val)
return fp;
}
-static inline uint32_t fixed_16_16_to_u32_round_up(uint_fixed_16_16_t fp)
+static inline uint32_t fixed16_to_u32_round_up(uint_fixed_16_16_t fp)
{
return DIV_ROUND_UP(fp.val, 1 << 16);
}
-static inline uint32_t fixed_16_16_to_u32(uint_fixed_16_16_t fp)
+static inline uint32_t fixed16_to_u32(uint_fixed_16_16_t fp)
{
return fp.val >> 16;
}
-static inline uint_fixed_16_16_t min_fixed_16_16(uint_fixed_16_16_t min1,
+static inline uint_fixed_16_16_t min_fixed16(uint_fixed_16_16_t min1,
uint_fixed_16_16_t min2)
{
uint_fixed_16_16_t min;
@@ -151,7 +151,7 @@ static inline uint_fixed_16_16_t min_fixed_16_16(uint_fixed_16_16_t min1,
return min;
}
-static inline uint_fixed_16_16_t max_fixed_16_16(uint_fixed_16_16_t max1,
+static inline uint_fixed_16_16_t max_fixed16(uint_fixed_16_16_t max1,
uint_fixed_16_16_t max2)
{
uint_fixed_16_16_t max;
@@ -160,6 +160,14 @@ static inline uint_fixed_16_16_t max_fixed_16_16(uint_fixed_16_16_t max1,
return max;
}
+static inline uint_fixed_16_16_t clamp_u64_to_fixed16(uint64_t val)
+{
+ uint_fixed_16_16_t fp;
+ WARN_ON(val >> 32);
+ fp.val = clamp_t(uint32_t, val, 0, ~0);
+ return fp;
+}
+
static inline uint32_t div_round_up_fixed16(uint_fixed_16_16_t val,
uint_fixed_16_16_t d)
{
@@ -170,48 +178,30 @@ static inline uint32_t mul_round_up_u32_fixed16(uint32_t val,
uint_fixed_16_16_t mul)
{
uint64_t intermediate_val;
- uint32_t result;
intermediate_val = (uint64_t) val * mul.val;
intermediate_val = DIV_ROUND_UP_ULL(intermediate_val, 1 << 16);
WARN_ON(intermediate_val >> 32);
- result = clamp_t(uint32_t, intermediate_val, 0, ~0);
- return result;
+ return clamp_t(uint32_t, intermediate_val, 0, ~0);
}
static inline uint_fixed_16_16_t mul_fixed16(uint_fixed_16_16_t val,
uint_fixed_16_16_t mul)
{
uint64_t intermediate_val;
- uint_fixed_16_16_t fp;
intermediate_val = (uint64_t) val.val * mul.val;
intermediate_val = intermediate_val >> 16;
- WARN_ON(intermediate_val >> 32);
- fp.val = clamp_t(uint32_t, intermediate_val, 0, ~0);
- return fp;
+ return clamp_u64_to_fixed16(intermediate_val);
}
-static inline uint_fixed_16_16_t fixed_16_16_div(uint32_t val, uint32_t d)
+static inline uint_fixed_16_16_t div_fixed16(uint32_t val, uint32_t d)
{
- uint_fixed_16_16_t fp, res;
-
- fp = u32_to_fixed_16_16(val);
- res.val = DIV_ROUND_UP(fp.val, d);
- return res;
-}
-
-static inline uint_fixed_16_16_t fixed_16_16_div_u64(uint32_t val, uint32_t d)
-{
- uint_fixed_16_16_t res;
uint64_t interm_val;
interm_val = (uint64_t)val << 16;
interm_val = DIV_ROUND_UP_ULL(interm_val, d);
- WARN_ON(interm_val >> 32);
- res.val = (uint32_t) interm_val;
-
- return res;
+ return clamp_u64_to_fixed16(interm_val);
}
static inline uint32_t div_round_up_u32_fixed16(uint32_t val,
@@ -225,16 +215,32 @@ static inline uint32_t div_round_up_u32_fixed16(uint32_t val,
return clamp_t(uint32_t, interm_val, 0, ~0);
}
-static inline uint_fixed_16_16_t mul_u32_fixed_16_16(uint32_t val,
+static inline uint_fixed_16_16_t mul_u32_fixed16(uint32_t val,
uint_fixed_16_16_t mul)
{
uint64_t intermediate_val;
- uint_fixed_16_16_t fp;
intermediate_val = (uint64_t) val * mul.val;
- WARN_ON(intermediate_val >> 32);
- fp.val = (uint32_t) intermediate_val;
- return fp;
+ return clamp_u64_to_fixed16(intermediate_val);
+}
+
+static inline uint_fixed_16_16_t add_fixed16(uint_fixed_16_16_t add1,
+ uint_fixed_16_16_t add2)
+{
+ uint64_t interm_sum;
+
+ interm_sum = (uint64_t) add1.val + add2.val;
+ return clamp_u64_to_fixed16(interm_sum);
+}
+
+static inline uint_fixed_16_16_t add_fixed16_u32(uint_fixed_16_16_t add1,
+ uint32_t add2)
+{
+ uint64_t interm_sum;
+ uint_fixed_16_16_t interm_add2 = u32_to_fixed16(add2);
+
+ interm_sum = (uint64_t) add1.val + interm_add2.val;
+ return clamp_u64_to_fixed16(interm_sum);
}
static inline const char *yesno(bool v)
@@ -584,8 +590,7 @@ struct drm_i915_file_private {
struct idr context_idr;
struct intel_rps_client {
- struct list_head link;
- unsigned boosts;
+ atomic_t boosts;
} rps;
unsigned int bsd_engine;
@@ -597,7 +602,7 @@ struct drm_i915_file_private {
* to limit the badly behaving clients access to gpu.
*/
#define I915_MAX_CLIENT_CONTEXT_BANS 3
- int context_bans;
+ atomic_t context_bans;
};
/* Used by dp and fdi links */
@@ -641,6 +646,7 @@ struct intel_opregion {
u32 swsci_sbcb_sub_functions;
struct opregion_asle *asle;
void *rvda;
+ void *vbt_firmware;
const void *vbt;
u32 vbt_size;
u32 *lid_state;
@@ -710,11 +716,6 @@ struct drm_i915_display_funcs {
void (*fdi_link_train)(struct intel_crtc *crtc,
const struct intel_crtc_state *crtc_state);
void (*init_clock_gating)(struct drm_i915_private *dev_priv);
- int (*queue_flip)(struct drm_device *dev, struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_i915_gem_object *obj,
- struct drm_i915_gem_request *req,
- uint32_t flags);
void (*hpd_irq_setup)(struct drm_i915_private *dev_priv);
/* clock updates for mode set */
/* cursor updates */
@@ -753,6 +754,7 @@ struct intel_csr {
func(has_csr); \
func(has_ddi); \
func(has_dp_mst); \
+ func(has_reset_engine); \
func(has_fbc); \
func(has_fpga_dbg); \
func(has_full_ppgtt); \
@@ -917,6 +919,7 @@ struct i915_gpu_state {
enum intel_engine_hangcheck_action hangcheck_action;
struct i915_address_space *vm;
int num_requests;
+ u32 reset_count;
/* position of active request inside the ring */
u32 rq_head, rq_post, rq_tail;
@@ -1056,6 +1059,11 @@ struct intel_fbc {
bool underrun_detected;
struct work_struct underrun_work;
+ /*
+ * Due to the atomic rules we can't access some structures without the
+ * appropriate locking, so we cache information here in order to avoid
+ * these problems.
+ */
struct intel_fbc_state_cache {
struct i915_vma *vma;
@@ -1077,6 +1085,13 @@ struct intel_fbc {
} fb;
} state_cache;
+ /*
+ * This structure contains everything that's relevant to program the
+ * hardware registers. When we want to figure out if we need to disable
+ * and re-enable FBC for a new configuration we just check if there's
+ * something different in the struct. The genx_fbc_activate functions
+ * are supposed to read from it in order to program the registers.
+ */
struct intel_fbc_reg_params {
struct i915_vma *vma;
@@ -1149,11 +1164,11 @@ struct i915_psr {
enum intel_pch {
PCH_NONE = 0, /* No PCH present */
PCH_IBX, /* Ibexpeak PCH */
- PCH_CPT, /* Cougarpoint PCH */
- PCH_LPT, /* Lynxpoint PCH */
+ PCH_CPT, /* Cougarpoint/Pantherpoint PCH */
+ PCH_LPT, /* Lynxpoint/Wildcatpoint PCH */
PCH_SPT, /* Sunrisepoint PCH */
- PCH_KBP, /* Kabypoint PCH */
- PCH_CNP, /* Cannonpoint PCH */
+ PCH_KBP, /* Kaby Lake PCH */
+ PCH_CNP, /* Cannon Lake PCH */
PCH_NOP,
};
@@ -1166,6 +1181,7 @@ enum intel_sbi_destination {
#define QUIRK_INVERT_BRIGHTNESS (1<<2)
#define QUIRK_BACKLIGHT_PRESENT (1<<3)
#define QUIRK_PIN_SWIZZLED_PAGES (1<<5)
+#define QUIRK_INCREASE_T12_DELAY (1<<6)
struct intel_fbdev;
struct intel_fbc_work;
@@ -1301,13 +1317,10 @@ struct intel_gen6_power_mgmt {
int last_adj;
enum { LOW_POWER, BETWEEN, HIGH_POWER } power;
- spinlock_t client_lock;
- struct list_head clients;
- bool client_boost;
-
bool enabled;
struct delayed_work autoenable_work;
- unsigned boosts;
+ atomic_t num_waiters;
+ atomic_t boosts;
/* manual wa residency calculations */
struct intel_rps_ei ei;
@@ -1383,12 +1396,23 @@ struct i915_power_well {
bool hw_enabled;
u64 domains;
/* unique identifier for this power well */
- unsigned long id;
+ enum i915_power_well_id id;
/*
* Arbitraty data associated with this power well. Platform and power
* well specific.
*/
- unsigned long data;
+ union {
+ struct {
+ enum dpio_phy phy;
+ } bxt;
+ struct {
+ /* Mask of pipes whose IRQ logic is backed by the pw */
+ u8 irq_pipe_mask;
+ /* The pw is backing the VGA functionality */
+ bool has_vga:1;
+ bool has_fuses:1;
+ } hsw;
+ };
const struct i915_power_well_ops *ops;
};
@@ -1505,6 +1529,8 @@ struct i915_gpu_error {
/* Protected by the above dev->gpu_error.lock. */
struct i915_gpu_state *first_error;
+ atomic_t pending_fb_pin;
+
unsigned long missed_irq_rings;
/**
@@ -1550,6 +1576,12 @@ struct i915_gpu_error {
* inspect the bit and do the reset directly, otherwise the worker
* waits for the struct_mutex.
*
+ * #I915_RESET_ENGINE[num_engines] - Since the driver doesn't need to
+ * acquire the struct_mutex to reset an engine, we need an explicit
+ * flag to prevent two concurrent reset attempts in the same engine.
+ * As the number of engines continues to grow, allocate the flags from
+ * the most significant bits.
+ *
* #I915_WEDGED - If reset fails and we can no longer use the GPU,
* we set the #I915_WEDGED bit. Prior to command submission, e.g.
* i915_gem_request_alloc(), this bit is checked and the sequence
@@ -1558,7 +1590,12 @@ struct i915_gpu_error {
unsigned long flags;
#define I915_RESET_BACKOFF 0
#define I915_RESET_HANDOFF 1
+#define I915_RESET_MODESET 2
#define I915_WEDGED (BITS_PER_LONG - 1)
+#define I915_RESET_ENGINE (I915_WEDGED - I915_NUM_ENGINES)
+
+ /** Number of times an engine has been reset */
+ u32 reset_engine_count[I915_NUM_ENGINES];
/**
* Waitqueue to signal when a hang is detected. Used to for waiters
@@ -1869,6 +1906,7 @@ struct i915_workarounds {
struct i915_virtual_gpu {
bool active;
+ u32 caps;
};
/* used in computing the new watermarks state */
@@ -1888,6 +1926,24 @@ struct i915_oa_reg {
u32 value;
};
+struct i915_oa_config {
+ char uuid[UUID_STRING_LEN + 1];
+ int id;
+
+ const struct i915_oa_reg *mux_regs;
+ u32 mux_regs_len;
+ const struct i915_oa_reg *b_counter_regs;
+ u32 b_counter_regs_len;
+ const struct i915_oa_reg *flex_regs;
+ u32 flex_regs_len;
+
+ struct attribute_group sysfs_metric;
+ struct attribute *attrs[2];
+ struct device_attribute sysfs_metric_id;
+
+ atomic_t ref_count;
+};
+
struct i915_perf_stream;
/**
@@ -2000,6 +2056,11 @@ struct i915_perf_stream {
* type of configured stream.
*/
const struct i915_perf_stream_ops *ops;
+
+ /**
+ * @oa_config: The OA configuration used by the stream.
+ */
+ struct i915_oa_config *oa_config;
};
/**
@@ -2007,6 +2068,25 @@ struct i915_perf_stream {
*/
struct i915_oa_ops {
/**
+ * @is_valid_b_counter_reg: Validates register's address for
+ * programming boolean counters for a particular platform.
+ */
+ bool (*is_valid_b_counter_reg)(struct drm_i915_private *dev_priv,
+ u32 addr);
+
+ /**
+ * @is_valid_mux_reg: Validates register's address for programming mux
+ * for a particular platform.
+ */
+ bool (*is_valid_mux_reg)(struct drm_i915_private *dev_priv, u32 addr);
+
+ /**
+ * @is_valid_flex_reg: Validates register's address for programming
+ * flex EU filtering for a particular platform.
+ */
+ bool (*is_valid_flex_reg)(struct drm_i915_private *dev_priv, u32 addr);
+
+ /**
* @init_oa_buffer: Resets the head and tail pointers of the
* circular buffer for periodic OA reports.
*
@@ -2024,20 +2104,13 @@ struct i915_oa_ops {
void (*init_oa_buffer)(struct drm_i915_private *dev_priv);
/**
- * @select_metric_set: The auto generated code that checks whether a
- * requested OA config is applicable to the system and if so sets up
- * the mux, oa and flex eu register config pointers according to the
- * current dev_priv->perf.oa.metrics_set.
- */
- int (*select_metric_set)(struct drm_i915_private *dev_priv);
-
- /**
* @enable_metric_set: Selects and applies any MUX configuration to set
* up the Boolean and Custom (B/C) counters that are part of the
* counter reports being sampled. May apply system constraints such as
* disabling EU clock gating as required.
*/
- int (*enable_metric_set)(struct drm_i915_private *dev_priv);
+ int (*enable_metric_set)(struct drm_i915_private *dev_priv,
+ const struct i915_oa_config *oa_config);
/**
* @disable_metric_set: Remove system constraints associated with using
@@ -2083,6 +2156,7 @@ struct drm_i915_private {
struct kmem_cache *objects;
struct kmem_cache *vmas;
+ struct kmem_cache *luts;
struct kmem_cache *requests;
struct kmem_cache *dependencies;
struct kmem_cache *priorities;
@@ -2133,9 +2207,6 @@ struct drm_i915_private {
/* protects the irq masks */
spinlock_t irq_lock;
- /* protects the mmio flip data */
- spinlock_t mmio_flip_lock;
-
bool display_irqs_enabled;
/* To control wakeup latency, e.g. for irq-driven dp aux transfers. */
@@ -2236,18 +2307,10 @@ struct drm_i915_private {
DECLARE_HASHTABLE(mm_structs, 7);
struct mutex mm_lock;
- /* The hw wants to have a stable context identifier for the lifetime
- * of the context (for OA, PASID, faults, etc). This is limited
- * in execlists to 21 bits.
- */
- struct ida context_hw_ida;
-#define MAX_CONTEXT_HW_ID (1<<21) /* exclusive */
-
/* Kernel Modesetting */
struct intel_crtc *plane_to_crtc_mapping[I915_MAX_PIPES];
struct intel_crtc *pipe_to_crtc_mapping[I915_MAX_PIPES];
- wait_queue_head_t pending_flip_queue;
#ifdef CONFIG_DEBUG_FS
struct intel_pipe_crc pipe_crc[I915_MAX_PIPES];
@@ -2303,11 +2366,9 @@ struct drm_i915_private {
struct drm_i915_gem_object *vlv_pctx;
-#ifdef CONFIG_DRM_FBDEV_EMULATION
/* list of fbdev register on this device */
struct intel_fbdev *fbdev;
struct work_struct fbdev_suspend_work;
-#endif
struct drm_property *broadcast_rgb_property;
struct drm_property *force_audio_property;
@@ -2321,7 +2382,18 @@ struct drm_i915_private {
*/
struct mutex av_mutex;
- struct list_head context_list;
+ struct {
+ struct list_head list;
+ struct llist_head free_list;
+ struct work_struct free_work;
+
+ /* The hw wants to have a stable context identifier for the
+ * lifetime of the context (for OA, PASID, faults, etc).
+ * This is limited in execlists to 21 bits.
+ */
+ struct ida hw_ida;
+#define MAX_CONTEXT_HW_ID (1<<21) /* exclusive */
+ } contexts;
u32 fdi_rx_config;
@@ -2399,10 +2471,32 @@ struct drm_i915_private {
struct kobject *metrics_kobj;
struct ctl_table_header *sysctl_header;
+ /*
+ * Lock associated with adding/modifying/removing OA configs
+ * in dev_priv->perf.metrics_idr.
+ */
+ struct mutex metrics_lock;
+
+ /*
+ * List of dynamic configurations, you need to hold
+ * dev_priv->perf.metrics_lock to access it.
+ */
+ struct idr metrics_idr;
+
+ /*
+ * Lock associated with anything below within this structure
+ * except exclusive_stream.
+ */
struct mutex lock;
struct list_head streams;
struct {
+ /*
+ * The stream currently using the OA unit. If accessed
+ * outside a syscall associated to its file
+ * descriptor, you need to hold
+ * dev_priv->drm.struct_mutex.
+ */
struct i915_perf_stream *exclusive_stream;
u32 specific_ctx_id;
@@ -2421,16 +2515,7 @@ struct drm_i915_private {
int period_exponent;
int timestamp_frequency;
- int metrics_set;
-
- const struct i915_oa_reg *mux_regs[6];
- int mux_regs_lens[6];
- int n_mux_configs;
-
- const struct i915_oa_reg *b_counter_regs;
- int b_counter_regs_len;
- const struct i915_oa_reg *flex_regs;
- int flex_regs_len;
+ struct i915_oa_config test_config;
struct {
struct i915_vma *vma;
@@ -2517,7 +2602,6 @@ struct drm_i915_private {
struct i915_oa_ops ops;
const struct i915_oa_format *oa_formats;
- int n_builtin_sets;
} oa;
} perf;
@@ -2996,16 +3080,17 @@ intel_info(const struct drm_i915_private *dev_priv)
#define HAS_POOLED_EU(dev_priv) ((dev_priv)->info.has_pooled_eu)
-#define INTEL_PCH_DEVICE_ID_MASK 0xff00
-#define INTEL_PCH_DEVICE_ID_MASK_EXT 0xff80
+#define INTEL_PCH_DEVICE_ID_MASK 0xff80
#define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00
#define INTEL_PCH_CPT_DEVICE_ID_TYPE 0x1c00
#define INTEL_PCH_PPT_DEVICE_ID_TYPE 0x1e00
#define INTEL_PCH_LPT_DEVICE_ID_TYPE 0x8c00
#define INTEL_PCH_LPT_LP_DEVICE_ID_TYPE 0x9c00
+#define INTEL_PCH_WPT_DEVICE_ID_TYPE 0x8c80
+#define INTEL_PCH_WPT_LP_DEVICE_ID_TYPE 0x9c80
#define INTEL_PCH_SPT_DEVICE_ID_TYPE 0xA100
#define INTEL_PCH_SPT_LP_DEVICE_ID_TYPE 0x9D00
-#define INTEL_PCH_KBP_DEVICE_ID_TYPE 0xA200
+#define INTEL_PCH_KBP_DEVICE_ID_TYPE 0xA280
#define INTEL_PCH_CNP_DEVICE_ID_TYPE 0xA300
#define INTEL_PCH_CNP_LP_DEVICE_ID_TYPE 0x9D80
#define INTEL_PCH_P2X_DEVICE_ID_TYPE 0x7100
@@ -3020,9 +3105,11 @@ intel_info(const struct drm_i915_private *dev_priv)
#define HAS_PCH_SPT(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_SPT)
#define HAS_PCH_LPT(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_LPT)
#define HAS_PCH_LPT_LP(dev_priv) \
- ((dev_priv)->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE)
+ ((dev_priv)->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE || \
+ (dev_priv)->pch_id == INTEL_PCH_WPT_LP_DEVICE_ID_TYPE)
#define HAS_PCH_LPT_H(dev_priv) \
- ((dev_priv)->pch_id == INTEL_PCH_LPT_DEVICE_ID_TYPE)
+ ((dev_priv)->pch_id == INTEL_PCH_LPT_DEVICE_ID_TYPE || \
+ (dev_priv)->pch_id == INTEL_PCH_WPT_DEVICE_ID_TYPE)
#define HAS_PCH_CPT(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_CPT)
#define HAS_PCH_IBX(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_IBX)
#define HAS_PCH_NOP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_NOP)
@@ -3088,7 +3175,13 @@ extern int i915_driver_load(struct pci_dev *pdev,
extern void i915_driver_unload(struct drm_device *dev);
extern int intel_gpu_reset(struct drm_i915_private *dev_priv, u32 engine_mask);
extern bool intel_has_gpu_reset(struct drm_i915_private *dev_priv);
-extern void i915_reset(struct drm_i915_private *dev_priv);
+
+#define I915_RESET_QUIET BIT(0)
+extern void i915_reset(struct drm_i915_private *i915, unsigned int flags);
+extern int i915_reset_engine(struct intel_engine_cs *engine,
+ unsigned int flags);
+
+extern bool intel_has_reset_engine(struct drm_i915_private *dev_priv);
extern int intel_guc_reset(struct drm_i915_private *dev_priv);
extern void intel_engine_init_hangcheck(struct intel_engine_cs *engine);
extern void intel_hangcheck_init(struct drm_i915_private *dev_priv);
@@ -3107,7 +3200,8 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv,
void intel_hpd_init(struct drm_i915_private *dev_priv);
void intel_hpd_init_work(struct drm_i915_private *dev_priv);
void intel_hpd_cancel_work(struct drm_i915_private *dev_priv);
-bool intel_hpd_pin_to_port(enum hpd_pin pin, enum port *port);
+enum port intel_hpd_pin_to_port(enum hpd_pin pin);
+enum hpd_pin intel_hpd_pin(enum port port);
bool intel_hpd_disable(struct drm_i915_private *dev_priv, enum hpd_pin pin);
void intel_hpd_enable(struct drm_i915_private *dev_priv, enum hpd_pin pin);
@@ -3276,6 +3370,26 @@ static inline void i915_gem_drain_freed_objects(struct drm_i915_private *i915)
} while (flush_work(&i915->mm.free_work));
}
+static inline void i915_gem_drain_workqueue(struct drm_i915_private *i915)
+{
+ /*
+ * Similar to objects above (see i915_gem_drain_freed-objects), in
+ * general we have workers that are armed by RCU and then rearm
+ * themselves in their callbacks. To be paranoid, we need to
+ * drain the workqueue a second time after waiting for the RCU
+ * grace period so that we catch work queued via RCU from the first
+ * pass. As neither drain_workqueue() nor flush_workqueue() report
+ * a result, we make an assumption that we only don't require more
+ * than 2 passes to catch all recursive RCU delayed work.
+ *
+ */
+ int pass = 2;
+ do {
+ rcu_barrier();
+ drain_workqueue(i915->wq);
+ } while (--pass);
+}
+
struct i915_vma * __must_check
i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
const struct i915_ggtt_view *view,
@@ -3461,11 +3575,22 @@ static inline u32 i915_reset_count(struct i915_gpu_error *error)
return READ_ONCE(error->reset_count);
}
+static inline u32 i915_reset_engine_count(struct i915_gpu_error *error,
+ struct intel_engine_cs *engine)
+{
+ return READ_ONCE(error->reset_engine_count[engine->id]);
+}
+
+struct drm_i915_gem_request *
+i915_gem_reset_prepare_engine(struct intel_engine_cs *engine);
int i915_gem_reset_prepare(struct drm_i915_private *dev_priv);
void i915_gem_reset(struct drm_i915_private *dev_priv);
+void i915_gem_reset_finish_engine(struct intel_engine_cs *engine);
void i915_gem_reset_finish(struct drm_i915_private *dev_priv);
void i915_gem_set_wedged(struct drm_i915_private *dev_priv);
bool i915_gem_unset_wedged(struct drm_i915_private *dev_priv);
+void i915_gem_reset_engine(struct intel_engine_cs *engine,
+ struct drm_i915_gem_request *request);
void i915_gem_init_mmio(struct drm_i915_private *i915);
int __must_check i915_gem_init(struct drm_i915_private *dev_priv);
@@ -3499,7 +3624,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
void i915_gem_object_unpin_from_display_plane(struct i915_vma *vma);
int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj,
int align);
-int i915_gem_open(struct drm_device *dev, struct drm_file *file);
+int i915_gem_open(struct drm_i915_private *i915, struct drm_file *file);
void i915_gem_release(struct drm_device *dev, struct drm_file *file);
int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
@@ -3531,38 +3656,23 @@ void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj,
struct sg_table *pages);
static inline struct i915_gem_context *
-i915_gem_context_lookup(struct drm_i915_file_private *file_priv, u32 id)
+__i915_gem_context_lookup_rcu(struct drm_i915_file_private *file_priv, u32 id)
{
- struct i915_gem_context *ctx;
-
- lockdep_assert_held(&file_priv->dev_priv->drm.struct_mutex);
-
- ctx = idr_find(&file_priv->context_idr, id);
- if (!ctx)
- return ERR_PTR(-ENOENT);
-
- return ctx;
+ return idr_find(&file_priv->context_idr, id);
}
static inline struct i915_gem_context *
-i915_gem_context_get(struct i915_gem_context *ctx)
-{
- kref_get(&ctx->ref);
- return ctx;
-}
-
-static inline void i915_gem_context_put(struct i915_gem_context *ctx)
+i915_gem_context_lookup(struct drm_i915_file_private *file_priv, u32 id)
{
- lockdep_assert_held(&ctx->i915->drm.struct_mutex);
- kref_put(&ctx->ref, i915_gem_context_free);
-}
+ struct i915_gem_context *ctx;
-static inline void i915_gem_context_put_unlocked(struct i915_gem_context *ctx)
-{
- struct mutex *lock = &ctx->i915->drm.struct_mutex;
+ rcu_read_lock();
+ ctx = __i915_gem_context_lookup_rcu(file_priv, id);
+ if (ctx && !kref_get_unless_zero(&ctx->ref))
+ ctx = NULL;
+ rcu_read_unlock();
- if (kref_put_mutex(&ctx->ref, i915_gem_context_free, lock))
- mutex_unlock(lock);
+ return ctx;
}
static inline struct intel_timeline *
@@ -3577,6 +3687,10 @@ i915_gem_context_lookup_timeline(struct i915_gem_context *ctx,
int i915_perf_open_ioctl(struct drm_device *dev, void *data,
struct drm_file *file);
+int i915_perf_add_config_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file);
+int i915_perf_remove_config_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file);
void i915_oa_init_reg_state(struct intel_engine_cs *engine,
struct i915_gem_context *ctx,
uint32_t *reg_state);
@@ -4064,6 +4178,11 @@ static inline unsigned long msecs_to_jiffies_timeout(const unsigned int m)
static inline unsigned long nsecs_to_jiffies_timeout(const u64 n)
{
+ /* nsecs_to_jiffies64() does not guard against overflow */
+ if (NSEC_PER_SEC % HZ &&
+ div_u64(n, NSEC_PER_SEC) >= MAX_JIFFY_OFFSET / HZ)
+ return MAX_JIFFY_OFFSET;
+
return min_t(u64, MAX_JIFFY_OFFSET, nsecs_to_jiffies64(n) + 1);
}
@@ -4210,10 +4329,11 @@ int remap_io_mapping(struct vm_area_struct *vma,
unsigned long addr, unsigned long pfn, unsigned long size,
struct io_mapping *iomap);
-static inline bool i915_gem_object_is_coherent(struct drm_i915_gem_object *obj)
+static inline bool
+intel_engine_can_store_dword(struct intel_engine_cs *engine)
{
- return (obj->cache_level != I915_CACHE_NONE ||
- HAS_LLC(to_i915(obj->base.dev)));
+ return __intel_engine_can_store_dword(INTEL_GEN(engine->i915),
+ engine->class);
}
#endif
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 969bac8..b9e8e0d 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -52,7 +52,7 @@ static bool cpu_write_needs_clflush(struct drm_i915_gem_object *obj)
if (obj->cache_dirty)
return false;
- if (!obj->cache_coherent)
+ if (!(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE))
return true;
return obj->pin_display;
@@ -253,7 +253,7 @@ __i915_gem_object_release_shmem(struct drm_i915_gem_object *obj,
if (needs_clflush &&
(obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0 &&
- !obj->cache_coherent)
+ !(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ))
drm_clflush_sg(pages);
__start_cpu_write(obj);
@@ -388,7 +388,7 @@ i915_gem_object_wait_fence(struct dma_fence *fence,
*/
if (rps) {
if (INTEL_GEN(rq->i915) >= 6)
- gen6_rps_boost(rq->i915, rps, rq->emitted_jiffies);
+ gen6_rps_boost(rq, rps);
else
rps = NULL;
}
@@ -399,22 +399,6 @@ out:
if (flags & I915_WAIT_LOCKED && i915_gem_request_completed(rq))
i915_gem_request_retire_upto(rq);
- if (rps && i915_gem_request_global_seqno(rq) == intel_engine_last_submit(rq->engine)) {
- /* The GPU is now idle and this client has stalled.
- * Since no other client has submitted a request in the
- * meantime, assume that this client is the only one
- * supplying work to the GPU but is unable to keep that
- * work supplied because it is waiting. Since the GPU is
- * then never kept fully busy, RPS autoclocking will
- * keep the clocks relatively low, causing further delays.
- * Compensate by giving the synchronous client credit for
- * a waitboost next time.
- */
- spin_lock(&rq->i915->rps.client_lock);
- list_del_init(&rps->link);
- spin_unlock(&rq->i915->rps.client_lock);
- }
-
return timeout;
}
@@ -577,46 +561,6 @@ static struct intel_rps_client *to_rps_client(struct drm_file *file)
return &fpriv->rps;
}
-int
-i915_gem_object_attach_phys(struct drm_i915_gem_object *obj,
- int align)
-{
- int ret;
-
- if (align > obj->base.size)
- return -EINVAL;
-
- if (obj->ops == &i915_gem_phys_ops)
- return 0;
-
- if (obj->mm.madv != I915_MADV_WILLNEED)
- return -EFAULT;
-
- if (obj->base.filp == NULL)
- return -EINVAL;
-
- ret = i915_gem_object_unbind(obj);
- if (ret)
- return ret;
-
- __i915_gem_object_put_pages(obj, I915_MM_NORMAL);
- if (obj->mm.pages)
- return -EBUSY;
-
- GEM_BUG_ON(obj->ops != &i915_gem_object_ops);
- obj->ops = &i915_gem_phys_ops;
-
- ret = i915_gem_object_pin_pages(obj);
- if (ret)
- goto err_xfer;
-
- return 0;
-
-err_xfer:
- obj->ops = &i915_gem_object_ops;
- return ret;
-}
-
static int
i915_gem_phys_pwrite(struct drm_i915_gem_object *obj,
struct drm_i915_gem_pwrite *args,
@@ -856,7 +800,8 @@ int i915_gem_obj_prepare_shmem_read(struct drm_i915_gem_object *obj,
if (ret)
return ret;
- if (obj->cache_coherent || !static_cpu_has(X86_FEATURE_CLFLUSH)) {
+ if (obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ ||
+ !static_cpu_has(X86_FEATURE_CLFLUSH)) {
ret = i915_gem_object_set_to_cpu_domain(obj, false);
if (ret)
goto err_unpin;
@@ -908,7 +853,8 @@ int i915_gem_obj_prepare_shmem_write(struct drm_i915_gem_object *obj,
if (ret)
return ret;
- if (obj->cache_coherent || !static_cpu_has(X86_FEATURE_CLFLUSH)) {
+ if (obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE ||
+ !static_cpu_has(X86_FEATURE_CLFLUSH)) {
ret = i915_gem_object_set_to_cpu_domain(obj, true);
if (ret)
goto err_unpin;
@@ -2756,34 +2702,38 @@ i915_gem_object_pwrite_gtt(struct drm_i915_gem_object *obj,
return 0;
}
-static bool ban_context(const struct i915_gem_context *ctx)
+static bool ban_context(const struct i915_gem_context *ctx,
+ unsigned int score)
{
return (i915_gem_context_is_bannable(ctx) &&
- ctx->ban_score >= CONTEXT_SCORE_BAN_THRESHOLD);
+ score >= CONTEXT_SCORE_BAN_THRESHOLD);
}
static void i915_gem_context_mark_guilty(struct i915_gem_context *ctx)
{
- ctx->guilty_count++;
- ctx->ban_score += CONTEXT_SCORE_GUILTY;
- if (ban_context(ctx))
- i915_gem_context_set_banned(ctx);
+ unsigned int score;
+ bool banned;
- DRM_DEBUG_DRIVER("context %s marked guilty (score %d) banned? %s\n",
- ctx->name, ctx->ban_score,
- yesno(i915_gem_context_is_banned(ctx)));
+ atomic_inc(&ctx->guilty_count);
- if (!i915_gem_context_is_banned(ctx) || IS_ERR_OR_NULL(ctx->file_priv))
+ score = atomic_add_return(CONTEXT_SCORE_GUILTY, &ctx->ban_score);
+ banned = ban_context(ctx, score);
+ DRM_DEBUG_DRIVER("context %s marked guilty (score %d) banned? %s\n",
+ ctx->name, score, yesno(banned));
+ if (!banned)
return;
- ctx->file_priv->context_bans++;
- DRM_DEBUG_DRIVER("client %s has had %d context banned\n",
- ctx->name, ctx->file_priv->context_bans);
+ i915_gem_context_set_banned(ctx);
+ if (!IS_ERR_OR_NULL(ctx->file_priv)) {
+ atomic_inc(&ctx->file_priv->context_bans);
+ DRM_DEBUG_DRIVER("client %s has had %d context banned\n",
+ ctx->name, atomic_read(&ctx->file_priv->context_bans));
+ }
}
static void i915_gem_context_mark_innocent(struct i915_gem_context *ctx)
{
- ctx->active_count++;
+ atomic_inc(&ctx->active_count);
}
struct drm_i915_gem_request *
@@ -2832,46 +2782,62 @@ static bool engine_stalled(struct intel_engine_cs *engine)
return true;
}
+/*
+ * Ensure irq handler finishes, and not run again.
+ * Also return the active request so that we only search for it once.
+ */
+struct drm_i915_gem_request *
+i915_gem_reset_prepare_engine(struct intel_engine_cs *engine)
+{
+ struct drm_i915_gem_request *request = NULL;
+
+ /* Prevent the signaler thread from updating the request
+ * state (by calling dma_fence_signal) as we are processing
+ * the reset. The write from the GPU of the seqno is
+ * asynchronous and the signaler thread may see a different
+ * value to us and declare the request complete, even though
+ * the reset routine have picked that request as the active
+ * (incomplete) request. This conflict is not handled
+ * gracefully!
+ */
+ kthread_park(engine->breadcrumbs.signaler);
+
+ /* Prevent request submission to the hardware until we have
+ * completed the reset in i915_gem_reset_finish(). If a request
+ * is completed by one engine, it may then queue a request
+ * to a second via its engine->irq_tasklet *just* as we are
+ * calling engine->init_hw() and also writing the ELSP.
+ * Turning off the engine->irq_tasklet until the reset is over
+ * prevents the race.
+ */
+ tasklet_kill(&engine->irq_tasklet);
+ tasklet_disable(&engine->irq_tasklet);
+
+ if (engine->irq_seqno_barrier)
+ engine->irq_seqno_barrier(engine);
+
+ request = i915_gem_find_active_request(engine);
+ if (request && request->fence.error == -EIO)
+ request = ERR_PTR(-EIO); /* Previous reset failed! */
+
+ return request;
+}
+
int i915_gem_reset_prepare(struct drm_i915_private *dev_priv)
{
struct intel_engine_cs *engine;
+ struct drm_i915_gem_request *request;
enum intel_engine_id id;
int err = 0;
- /* Ensure irq handler finishes, and not run again. */
for_each_engine(engine, dev_priv, id) {
- struct drm_i915_gem_request *request;
-
- /* Prevent the signaler thread from updating the request
- * state (by calling dma_fence_signal) as we are processing
- * the reset. The write from the GPU of the seqno is
- * asynchronous and the signaler thread may see a different
- * value to us and declare the request complete, even though
- * the reset routine have picked that request as the active
- * (incomplete) request. This conflict is not handled
- * gracefully!
- */
- kthread_park(engine->breadcrumbs.signaler);
-
- /* Prevent request submission to the hardware until we have
- * completed the reset in i915_gem_reset_finish(). If a request
- * is completed by one engine, it may then queue a request
- * to a second via its engine->irq_tasklet *just* as we are
- * calling engine->init_hw() and also writing the ELSP.
- * Turning off the engine->irq_tasklet until the reset is over
- * prevents the race.
- */
- tasklet_kill(&engine->irq_tasklet);
- tasklet_disable(&engine->irq_tasklet);
-
- if (engine->irq_seqno_barrier)
- engine->irq_seqno_barrier(engine);
-
- if (engine_stalled(engine)) {
- request = i915_gem_find_active_request(engine);
- if (request && request->fence.error == -EIO)
- err = -EIO; /* Previous reset failed! */
+ request = i915_gem_reset_prepare_engine(engine);
+ if (IS_ERR(request)) {
+ err = PTR_ERR(request);
+ continue;
}
+
+ engine->hangcheck.active_request = request;
}
i915_gem_revoke_fences(dev_priv);
@@ -2921,12 +2887,11 @@ static void engine_skip_context(struct drm_i915_gem_request *request)
spin_unlock_irqrestore(&engine->timeline->lock, flags);
}
-/* Returns true if the request was guilty of hang */
-static bool i915_gem_reset_request(struct drm_i915_gem_request *request)
+/* Returns the request if it was guilty of the hang */
+static struct drm_i915_gem_request *
+i915_gem_reset_request(struct intel_engine_cs *engine,
+ struct drm_i915_gem_request *request)
{
- /* Read once and return the resolution */
- const bool guilty = engine_stalled(request->engine);
-
/* The guilty request will get skipped on a hung engine.
*
* Users of client default contexts do not rely on logical
@@ -2948,29 +2913,47 @@ static bool i915_gem_reset_request(struct drm_i915_gem_request *request)
* subsequent hangs.
*/
- if (guilty) {
+ if (engine_stalled(engine)) {
i915_gem_context_mark_guilty(request->ctx);
skip_request(request);
+
+ /* If this context is now banned, skip all pending requests. */
+ if (i915_gem_context_is_banned(request->ctx))
+ engine_skip_context(request);
} else {
- i915_gem_context_mark_innocent(request->ctx);
- dma_fence_set_error(&request->fence, -EAGAIN);
+ /*
+ * Since this is not the hung engine, it may have advanced
+ * since the hang declaration. Double check by refinding
+ * the active request at the time of the reset.
+ */
+ request = i915_gem_find_active_request(engine);
+ if (request) {
+ i915_gem_context_mark_innocent(request->ctx);
+ dma_fence_set_error(&request->fence, -EAGAIN);
+
+ /* Rewind the engine to replay the incomplete rq */
+ spin_lock_irq(&engine->timeline->lock);
+ request = list_prev_entry(request, link);
+ if (&request->link == &engine->timeline->requests)
+ request = NULL;
+ spin_unlock_irq(&engine->timeline->lock);
+ }
}
- return guilty;
+ return request;
}
-static void i915_gem_reset_engine(struct intel_engine_cs *engine)
+void i915_gem_reset_engine(struct intel_engine_cs *engine,
+ struct drm_i915_gem_request *request)
{
- struct drm_i915_gem_request *request;
+ engine->irq_posted = 0;
- request = i915_gem_find_active_request(engine);
- if (request && i915_gem_reset_request(request)) {
+ if (request)
+ request = i915_gem_reset_request(engine, request);
+
+ if (request) {
DRM_DEBUG_DRIVER("resetting %s to restart from tail of request 0x%x\n",
engine->name, request->global_seqno);
-
- /* If this context is now banned, skip all pending requests. */
- if (i915_gem_context_is_banned(request->ctx))
- engine_skip_context(request);
}
/* Setup the CS to resume from the breadcrumb of the hung request */
@@ -2989,7 +2972,7 @@ void i915_gem_reset(struct drm_i915_private *dev_priv)
for_each_engine(engine, dev_priv, id) {
struct i915_gem_context *ctx;
- i915_gem_reset_engine(engine);
+ i915_gem_reset_engine(engine, engine->hangcheck.active_request);
ctx = fetch_and_zero(&engine->last_retired_context);
if (ctx)
engine->context_unpin(engine, ctx);
@@ -3005,6 +2988,12 @@ void i915_gem_reset(struct drm_i915_private *dev_priv)
}
}
+void i915_gem_reset_finish_engine(struct intel_engine_cs *engine)
+{
+ tasklet_enable(&engine->irq_tasklet);
+ kthread_unpark(engine->breadcrumbs.signaler);
+}
+
void i915_gem_reset_finish(struct drm_i915_private *dev_priv)
{
struct intel_engine_cs *engine;
@@ -3013,13 +3002,14 @@ void i915_gem_reset_finish(struct drm_i915_private *dev_priv)
lockdep_assert_held(&dev_priv->drm.struct_mutex);
for_each_engine(engine, dev_priv, id) {
- tasklet_enable(&engine->irq_tasklet);
- kthread_unpark(engine->breadcrumbs.signaler);
+ engine->hangcheck.active_request = NULL;
+ i915_gem_reset_finish_engine(engine);
}
}
static void nop_submit_request(struct drm_i915_gem_request *request)
{
+ GEM_BUG_ON(!i915_terminally_wedged(&request->i915->gpu_error));
dma_fence_set_error(&request->fence, -EIO);
i915_gem_request_submit(request);
intel_engine_init_global_seqno(request->engine, request->global_seqno);
@@ -3041,16 +3031,10 @@ static void engine_set_wedged(struct intel_engine_cs *engine)
/* Mark all executing requests as skipped */
spin_lock_irqsave(&engine->timeline->lock, flags);
list_for_each_entry(request, &engine->timeline->requests, link)
- dma_fence_set_error(&request->fence, -EIO);
+ if (!i915_gem_request_completed(request))
+ dma_fence_set_error(&request->fence, -EIO);
spin_unlock_irqrestore(&engine->timeline->lock, flags);
- /* Mark all pending requests as complete so that any concurrent
- * (lockless) lookup doesn't try and wait upon the request as we
- * reset it.
- */
- intel_engine_init_global_seqno(engine,
- intel_engine_last_submit(engine));
-
/*
* Clear the execlists queue up before freeing the requests, as those
* are the ones that keep the context and ringbuffer backing objects
@@ -3071,7 +3055,21 @@ static void engine_set_wedged(struct intel_engine_cs *engine)
engine->execlist_first = NULL;
spin_unlock_irqrestore(&engine->timeline->lock, flags);
+
+ /* The port is checked prior to scheduling a tasklet, but
+ * just in case we have suspended the tasklet to do the
+ * wedging make sure that when it wakes, it decides there
+ * is no work to do by clearing the irq_posted bit.
+ */
+ clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted);
}
+
+ /* Mark all pending requests as complete so that any concurrent
+ * (lockless) lookup doesn't try and wait upon the request as we
+ * reset it.
+ */
+ intel_engine_init_global_seqno(engine,
+ intel_engine_last_submit(engine));
}
static int __i915_gem_set_wedged_BKL(void *data)
@@ -3083,25 +3081,15 @@ static int __i915_gem_set_wedged_BKL(void *data)
for_each_engine(engine, i915, id)
engine_set_wedged(engine);
+ set_bit(I915_WEDGED, &i915->gpu_error.flags);
+ wake_up_all(&i915->gpu_error.reset_queue);
+
return 0;
}
void i915_gem_set_wedged(struct drm_i915_private *dev_priv)
{
- lockdep_assert_held(&dev_priv->drm.struct_mutex);
- set_bit(I915_WEDGED, &dev_priv->gpu_error.flags);
-
- /* Retire completed requests first so the list of inflight/incomplete
- * requests is accurate and we don't try and mark successful requests
- * as in error during __i915_gem_set_wedged_BKL().
- */
- i915_gem_retire_requests(dev_priv);
-
stop_machine(__i915_gem_set_wedged_BKL, dev_priv, NULL);
-
- i915_gem_context_lost(dev_priv);
-
- mod_delayed_work(dev_priv->wq, &dev_priv->gt.idle_work, 0);
}
bool i915_gem_unset_wedged(struct drm_i915_private *i915)
@@ -3156,6 +3144,7 @@ bool i915_gem_unset_wedged(struct drm_i915_private *i915)
* context and do not require stop_machine().
*/
intel_engines_reset_default_submission(i915);
+ i915_gem_contexts_lost(i915);
smp_mb__before_atomic(); /* complete takeover before enabling execbuf */
clear_bit(I915_WEDGED, &i915->gpu_error.flags);
@@ -3253,25 +3242,33 @@ out_rearm:
void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file)
{
+ struct drm_i915_private *i915 = to_i915(gem->dev);
struct drm_i915_gem_object *obj = to_intel_bo(gem);
struct drm_i915_file_private *fpriv = file->driver_priv;
- struct i915_vma *vma, *vn;
+ struct i915_lut_handle *lut, *ln;
- mutex_lock(&obj->base.dev->struct_mutex);
- list_for_each_entry_safe(vma, vn, &obj->vma_list, obj_link)
- if (vma->vm->file == fpriv)
+ mutex_lock(&i915->drm.struct_mutex);
+
+ list_for_each_entry_safe(lut, ln, &obj->lut_list, obj_link) {
+ struct i915_gem_context *ctx = lut->ctx;
+ struct i915_vma *vma;
+
+ if (ctx->file_priv != fpriv)
+ continue;
+
+ vma = radix_tree_delete(&ctx->handles_vma, lut->handle);
+
+ if (!i915_vma_is_ggtt(vma))
i915_vma_close(vma);
- vma = obj->vma_hashed;
- if (vma && vma->ctx->file_priv == fpriv)
- i915_vma_unlink_ctx(vma);
+ list_del(&lut->obj_link);
+ list_del(&lut->ctx_link);
- if (i915_gem_object_is_active(obj) &&
- !i915_gem_object_has_active_reference(obj)) {
- i915_gem_object_set_active_reference(obj);
- i915_gem_object_get(obj);
+ kmem_cache_free(i915->luts, lut);
+ __i915_gem_object_release_unless_active(obj);
}
- mutex_unlock(&obj->base.dev->struct_mutex);
+
+ mutex_unlock(&i915->drm.struct_mutex);
}
static unsigned long to_wait_timeout(s64 timeout_ns)
@@ -3297,7 +3294,7 @@ static unsigned long to_wait_timeout(s64 timeout_ns)
* -ERESTARTSYS: signal interrupted the wait
* -ENONENT: object doesn't exist
* Also possible, but rare:
- * -EAGAIN: GPU wedged
+ * -EAGAIN: incomplete, restart syscall
* -ENOMEM: damn
* -ENODEV: Internal IRQ fail
* -E?: The add request failed
@@ -3345,6 +3342,10 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
*/
if (ret == -ETIME && !nsecs_to_jiffies(args->timeout_ns))
args->timeout_ns = 0;
+
+ /* Asked to wait beyond the jiffie/scheduler precision? */
+ if (ret == -ETIME && args->timeout_ns)
+ ret = -EAGAIN;
}
i915_gem_object_put(obj);
@@ -3686,8 +3687,7 @@ restart:
list_for_each_entry(vma, &obj->vma_list, obj_link)
vma->node.color = cache_level;
- obj->cache_level = cache_level;
- obj->cache_coherent = i915_gem_object_is_coherent(obj);
+ i915_gem_object_set_cache_coherency(obj, cache_level);
obj->cache_dirty = true; /* Always invalidate stale cachelines */
return 0;
@@ -4260,6 +4260,7 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
INIT_LIST_HEAD(&obj->global_link);
INIT_LIST_HEAD(&obj->userfault_link);
INIT_LIST_HEAD(&obj->vma_list);
+ INIT_LIST_HEAD(&obj->lut_list);
INIT_LIST_HEAD(&obj->batch_pool_link);
obj->ops = ops;
@@ -4292,6 +4293,7 @@ i915_gem_object_create(struct drm_i915_private *dev_priv, u64 size)
{
struct drm_i915_gem_object *obj;
struct address_space *mapping;
+ unsigned int cache_level;
gfp_t mask;
int ret;
@@ -4330,7 +4332,7 @@ i915_gem_object_create(struct drm_i915_private *dev_priv, u64 size)
obj->base.write_domain = I915_GEM_DOMAIN_CPU;
obj->base.read_domains = I915_GEM_DOMAIN_CPU;
- if (HAS_LLC(dev_priv)) {
+ if (HAS_LLC(dev_priv))
/* On some devices, we can have the GPU use the LLC (the CPU
* cache) for about a 10% performance improvement
* compared to uncached. Graphics requests other than
@@ -4343,12 +4345,11 @@ i915_gem_object_create(struct drm_i915_private *dev_priv, u64 size)
* However, we maintain the display planes as UC, and so
* need to rebind when first used as such.
*/
- obj->cache_level = I915_CACHE_LLC;
- } else
- obj->cache_level = I915_CACHE_NONE;
+ cache_level = I915_CACHE_LLC;
+ else
+ cache_level = I915_CACHE_NONE;
- obj->cache_coherent = i915_gem_object_is_coherent(obj);
- obj->cache_dirty = !obj->cache_coherent;
+ i915_gem_object_set_cache_coherency(obj, cache_level);
trace_i915_gem_object_create(obj);
@@ -4503,8 +4504,8 @@ void __i915_gem_object_release_unless_active(struct drm_i915_gem_object *obj)
{
lockdep_assert_held(&obj->base.dev->struct_mutex);
- GEM_BUG_ON(i915_gem_object_has_active_reference(obj));
- if (i915_gem_object_is_active(obj))
+ if (!i915_gem_object_has_active_reference(obj) &&
+ i915_gem_object_is_active(obj))
i915_gem_object_set_active_reference(obj);
else
i915_gem_object_put(obj);
@@ -4565,7 +4566,7 @@ int i915_gem_suspend(struct drm_i915_private *dev_priv)
goto err_unlock;
assert_kernel_context_is_current(dev_priv);
- i915_gem_context_lost(dev_priv);
+ i915_gem_contexts_lost(dev_priv);
mutex_unlock(&dev->struct_mutex);
intel_guc_suspend(dev_priv);
@@ -4579,8 +4580,6 @@ int i915_gem_suspend(struct drm_i915_private *dev_priv)
while (flush_delayed_work(&dev_priv->gt.idle_work))
;
- i915_gem_drain_freed_objects(dev_priv);
-
/* Assert that we sucessfully flushed all the work and
* reset the GPU back to its idle, low power state.
*/
@@ -4812,7 +4811,7 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
if (ret)
goto out_unlock;
- ret = i915_gem_context_init(dev_priv);
+ ret = i915_gem_contexts_init(dev_priv);
if (ret)
goto out_unlock;
@@ -4898,12 +4897,16 @@ i915_gem_load_init(struct drm_i915_private *dev_priv)
if (!dev_priv->vmas)
goto err_objects;
+ dev_priv->luts = KMEM_CACHE(i915_lut_handle, 0);
+ if (!dev_priv->luts)
+ goto err_vmas;
+
dev_priv->requests = KMEM_CACHE(drm_i915_gem_request,
SLAB_HWCACHE_ALIGN |
SLAB_RECLAIM_ACCOUNT |
SLAB_TYPESAFE_BY_RCU);
if (!dev_priv->requests)
- goto err_vmas;
+ goto err_luts;
dev_priv->dependencies = KMEM_CACHE(i915_dependency,
SLAB_HWCACHE_ALIGN |
@@ -4922,7 +4925,6 @@ i915_gem_load_init(struct drm_i915_private *dev_priv)
if (err)
goto err_priorities;
- INIT_LIST_HEAD(&dev_priv->context_list);
INIT_WORK(&dev_priv->mm.free_work, __i915_gem_free_work);
init_llist_head(&dev_priv->mm.free_list);
INIT_LIST_HEAD(&dev_priv->mm.unbound_list);
@@ -4936,8 +4938,6 @@ i915_gem_load_init(struct drm_i915_private *dev_priv)
init_waitqueue_head(&dev_priv->gpu_error.wait_queue);
init_waitqueue_head(&dev_priv->gpu_error.reset_queue);
- init_waitqueue_head(&dev_priv->pending_flip_queue);
-
atomic_set(&dev_priv->mm.bsd_engine_dispatch_index, 0);
spin_lock_init(&dev_priv->fb_tracking.lock);
@@ -4950,6 +4950,8 @@ err_dependencies:
kmem_cache_destroy(dev_priv->dependencies);
err_requests:
kmem_cache_destroy(dev_priv->requests);
+err_luts:
+ kmem_cache_destroy(dev_priv->luts);
err_vmas:
kmem_cache_destroy(dev_priv->vmas);
err_objects:
@@ -4972,6 +4974,7 @@ void i915_gem_load_cleanup(struct drm_i915_private *dev_priv)
kmem_cache_destroy(dev_priv->priorities);
kmem_cache_destroy(dev_priv->dependencies);
kmem_cache_destroy(dev_priv->requests);
+ kmem_cache_destroy(dev_priv->luts);
kmem_cache_destroy(dev_priv->vmas);
kmem_cache_destroy(dev_priv->objects);
@@ -5038,15 +5041,9 @@ void i915_gem_release(struct drm_device *dev, struct drm_file *file)
list_for_each_entry(request, &file_priv->mm.request_list, client_link)
request->file_priv = NULL;
spin_unlock(&file_priv->mm.lock);
-
- if (!list_empty(&file_priv->rps.link)) {
- spin_lock(&to_i915(dev)->rps.client_lock);
- list_del(&file_priv->rps.link);
- spin_unlock(&to_i915(dev)->rps.client_lock);
- }
}
-int i915_gem_open(struct drm_device *dev, struct drm_file *file)
+int i915_gem_open(struct drm_i915_private *i915, struct drm_file *file)
{
struct drm_i915_file_private *file_priv;
int ret;
@@ -5058,16 +5055,15 @@ int i915_gem_open(struct drm_device *dev, struct drm_file *file)
return -ENOMEM;
file->driver_priv = file_priv;
- file_priv->dev_priv = to_i915(dev);
+ file_priv->dev_priv = i915;
file_priv->file = file;
- INIT_LIST_HEAD(&file_priv->rps.link);
spin_lock_init(&file_priv->mm.lock);
INIT_LIST_HEAD(&file_priv->mm.request_list);
file_priv->bsd_engine = -1;
- ret = i915_gem_context_open(dev, file);
+ ret = i915_gem_context_open(i915, file);
if (ret)
kfree(file_priv);
@@ -5311,6 +5307,64 @@ i915_gem_object_get_dma_address(struct drm_i915_gem_object *obj,
return sg_dma_address(sg) + (offset << PAGE_SHIFT);
}
+int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, int align)
+{
+ struct sg_table *pages;
+ int err;
+
+ if (align > obj->base.size)
+ return -EINVAL;
+
+ if (obj->ops == &i915_gem_phys_ops)
+ return 0;
+
+ if (obj->ops != &i915_gem_object_ops)
+ return -EINVAL;
+
+ err = i915_gem_object_unbind(obj);
+ if (err)
+ return err;
+
+ mutex_lock(&obj->mm.lock);
+
+ if (obj->mm.madv != I915_MADV_WILLNEED) {
+ err = -EFAULT;
+ goto err_unlock;
+ }
+
+ if (obj->mm.quirked) {
+ err = -EFAULT;
+ goto err_unlock;
+ }
+
+ if (obj->mm.mapping) {
+ err = -EBUSY;
+ goto err_unlock;
+ }
+
+ pages = obj->mm.pages;
+ obj->ops = &i915_gem_phys_ops;
+
+ err = ____i915_gem_object_get_pages(obj);
+ if (err)
+ goto err_xfer;
+
+ /* Perma-pin (until release) the physical set of pages */
+ __i915_gem_object_pin_pages(obj);
+
+ if (!IS_ERR_OR_NULL(pages))
+ i915_gem_object_ops.put_pages(obj, pages);
+ mutex_unlock(&obj->mm.lock);
+ return 0;
+
+err_xfer:
+ obj->ops = &i915_gem_object_ops;
+ obj->mm.pages = pages;
+err_unlock:
+ mutex_unlock(&obj->mm.lock);
+ return err;
+}
+
#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
#include "selftests/scatterlist.c"
#include "selftests/mock_gem_device.c"
diff --git a/drivers/gpu/drm/i915/i915_gem_clflush.c b/drivers/gpu/drm/i915/i915_gem_clflush.c
index 348b29a..8a04d33 100644
--- a/drivers/gpu/drm/i915/i915_gem_clflush.c
+++ b/drivers/gpu/drm/i915/i915_gem_clflush.c
@@ -139,7 +139,8 @@ bool i915_gem_clflush_object(struct drm_i915_gem_object *obj,
* snooping behaviour occurs naturally as the result of our domain
* tracking.
*/
- if (!(flags & I915_CLFLUSH_FORCE) && obj->cache_coherent)
+ if (!(flags & I915_CLFLUSH_FORCE) &&
+ obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ)
return false;
trace_i915_gem_object_clflush(obj);
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index e1e971e..58a2a44 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -93,81 +93,37 @@
#define ALL_L3_SLICES(dev) (1 << NUM_L3_SLICES(dev)) - 1
-/* Initial size (as log2) to preallocate the handle->object hashtable */
-#define VMA_HT_BITS 2u /* 4 x 2 pointers, 64 bytes minimum */
-
-static void resize_vma_ht(struct work_struct *work)
+static void lut_close(struct i915_gem_context *ctx)
{
- struct i915_gem_context_vma_lut *lut =
- container_of(work, typeof(*lut), resize);
- unsigned int bits, new_bits, size, i;
- struct hlist_head *new_ht;
-
- GEM_BUG_ON(!(lut->ht_size & I915_CTX_RESIZE_IN_PROGRESS));
-
- bits = 1 + ilog2(4*lut->ht_count/3 + 1);
- new_bits = min_t(unsigned int,
- max(bits, VMA_HT_BITS),
- sizeof(unsigned int) * BITS_PER_BYTE - 1);
- if (new_bits == lut->ht_bits)
- goto out;
-
- new_ht = kzalloc(sizeof(*new_ht)<<new_bits, GFP_KERNEL | __GFP_NOWARN);
- if (!new_ht)
- new_ht = vzalloc(sizeof(*new_ht)<<new_bits);
- if (!new_ht)
- /* Pretend resize succeeded and stop calling us for a bit! */
- goto out;
+ struct i915_lut_handle *lut, *ln;
+ struct radix_tree_iter iter;
+ void __rcu **slot;
- size = BIT(lut->ht_bits);
- for (i = 0; i < size; i++) {
- struct i915_vma *vma;
- struct hlist_node *tmp;
-
- hlist_for_each_entry_safe(vma, tmp, &lut->ht[i], ctx_node)
- hlist_add_head(&vma->ctx_node,
- &new_ht[hash_32(vma->ctx_handle,
- new_bits)]);
+ list_for_each_entry_safe(lut, ln, &ctx->handles_list, ctx_link) {
+ list_del(&lut->obj_link);
+ kmem_cache_free(ctx->i915->luts, lut);
}
- kvfree(lut->ht);
- lut->ht = new_ht;
- lut->ht_bits = new_bits;
-out:
- smp_store_release(&lut->ht_size, BIT(bits));
- GEM_BUG_ON(lut->ht_size & I915_CTX_RESIZE_IN_PROGRESS);
-}
-static void vma_lut_free(struct i915_gem_context *ctx)
-{
- struct i915_gem_context_vma_lut *lut = &ctx->vma_lut;
- unsigned int i, size;
+ radix_tree_for_each_slot(slot, &ctx->handles_vma, &iter, 0) {
+ struct i915_vma *vma = rcu_dereference_raw(*slot);
+ struct drm_i915_gem_object *obj = vma->obj;
- if (lut->ht_size & I915_CTX_RESIZE_IN_PROGRESS)
- cancel_work_sync(&lut->resize);
+ radix_tree_iter_delete(&ctx->handles_vma, &iter, slot);
- size = BIT(lut->ht_bits);
- for (i = 0; i < size; i++) {
- struct i915_vma *vma;
+ if (!i915_vma_is_ggtt(vma))
+ i915_vma_close(vma);
- hlist_for_each_entry(vma, &lut->ht[i], ctx_node) {
- vma->obj->vma_hashed = NULL;
- vma->ctx = NULL;
- i915_vma_put(vma);
- }
+ __i915_gem_object_release_unless_active(obj);
}
- kvfree(lut->ht);
}
-void i915_gem_context_free(struct kref *ctx_ref)
+static void i915_gem_context_free(struct i915_gem_context *ctx)
{
- struct i915_gem_context *ctx = container_of(ctx_ref, typeof(*ctx), ref);
int i;
lockdep_assert_held(&ctx->i915->drm.struct_mutex);
- trace_i915_context_free(ctx);
GEM_BUG_ON(!i915_gem_context_is_closed(ctx));
- vma_lut_free(ctx);
i915_ppgtt_put(ctx->ppgtt);
for (i = 0; i < I915_NUM_ENGINES; i++) {
@@ -188,15 +144,64 @@ void i915_gem_context_free(struct kref *ctx_ref)
list_del(&ctx->link);
- ida_simple_remove(&ctx->i915->context_hw_ida, ctx->hw_id);
- kfree(ctx);
+ ida_simple_remove(&ctx->i915->contexts.hw_ida, ctx->hw_id);
+ kfree_rcu(ctx, rcu);
+}
+
+static void contexts_free(struct drm_i915_private *i915)
+{
+ struct llist_node *freed = llist_del_all(&i915->contexts.free_list);
+ struct i915_gem_context *ctx, *cn;
+
+ lockdep_assert_held(&i915->drm.struct_mutex);
+
+ llist_for_each_entry_safe(ctx, cn, freed, free_link)
+ i915_gem_context_free(ctx);
+}
+
+static void contexts_free_first(struct drm_i915_private *i915)
+{
+ struct i915_gem_context *ctx;
+ struct llist_node *freed;
+
+ lockdep_assert_held(&i915->drm.struct_mutex);
+
+ freed = llist_del_first(&i915->contexts.free_list);
+ if (!freed)
+ return;
+
+ ctx = container_of(freed, typeof(*ctx), free_link);
+ i915_gem_context_free(ctx);
+}
+
+static void contexts_free_worker(struct work_struct *work)
+{
+ struct drm_i915_private *i915 =
+ container_of(work, typeof(*i915), contexts.free_work);
+
+ mutex_lock(&i915->drm.struct_mutex);
+ contexts_free(i915);
+ mutex_unlock(&i915->drm.struct_mutex);
+}
+
+void i915_gem_context_release(struct kref *ref)
+{
+ struct i915_gem_context *ctx = container_of(ref, typeof(*ctx), ref);
+ struct drm_i915_private *i915 = ctx->i915;
+
+ trace_i915_context_free(ctx);
+ if (llist_add(&ctx->free_link, &i915->contexts.free_list))
+ queue_work(i915->wq, &i915->contexts.free_work);
}
static void context_close(struct i915_gem_context *ctx)
{
i915_gem_context_set_closed(ctx);
+
+ lut_close(ctx);
if (ctx->ppgtt)
i915_ppgtt_close(&ctx->ppgtt->base);
+
ctx->file_priv = ERR_PTR(-EBADF);
i915_gem_context_put(ctx);
}
@@ -205,7 +210,7 @@ static int assign_hw_id(struct drm_i915_private *dev_priv, unsigned *out)
{
int ret;
- ret = ida_simple_get(&dev_priv->context_hw_ida,
+ ret = ida_simple_get(&dev_priv->contexts.hw_ida,
0, MAX_CONTEXT_HW_ID, GFP_KERNEL);
if (ret < 0) {
/* Contexts are only released when no longer active.
@@ -213,7 +218,7 @@ static int assign_hw_id(struct drm_i915_private *dev_priv, unsigned *out)
* stale contexts and try again.
*/
i915_gem_retire_requests(dev_priv);
- ret = ida_simple_get(&dev_priv->context_hw_ida,
+ ret = ida_simple_get(&dev_priv->contexts.hw_ida,
0, MAX_CONTEXT_HW_ID, GFP_KERNEL);
if (ret < 0)
return ret;
@@ -265,20 +270,12 @@ __create_hw_context(struct drm_i915_private *dev_priv,
}
kref_init(&ctx->ref);
- list_add_tail(&ctx->link, &dev_priv->context_list);
+ list_add_tail(&ctx->link, &dev_priv->contexts.list);
ctx->i915 = dev_priv;
ctx->priority = I915_PRIORITY_NORMAL;
- ctx->vma_lut.ht_bits = VMA_HT_BITS;
- ctx->vma_lut.ht_size = BIT(VMA_HT_BITS);
- BUILD_BUG_ON(BIT(VMA_HT_BITS) == I915_CTX_RESIZE_IN_PROGRESS);
- ctx->vma_lut.ht = kcalloc(ctx->vma_lut.ht_size,
- sizeof(*ctx->vma_lut.ht),
- GFP_KERNEL);
- if (!ctx->vma_lut.ht)
- goto err_out;
-
- INIT_WORK(&ctx->vma_lut.resize, resize_vma_ht);
+ INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL);
+ INIT_LIST_HEAD(&ctx->handles_list);
/* Default context will never have a file_priv */
ret = DEFAULT_CONTEXT_HANDLE;
@@ -328,8 +325,6 @@ err_pid:
put_pid(ctx->pid);
idr_remove(&file_priv->context_idr, ctx->user_handle);
err_lut:
- kvfree(ctx->vma_lut.ht);
-err_out:
context_close(ctx);
return ERR_PTR(ret);
}
@@ -354,6 +349,9 @@ i915_gem_create_context(struct drm_i915_private *dev_priv,
lockdep_assert_held(&dev_priv->drm.struct_mutex);
+ /* Reap the most stale context */
+ contexts_free_first(dev_priv);
+
ctx = __create_hw_context(dev_priv, file_priv);
if (IS_ERR(ctx))
return ctx;
@@ -418,7 +416,7 @@ out:
return ctx;
}
-int i915_gem_context_init(struct drm_i915_private *dev_priv)
+int i915_gem_contexts_init(struct drm_i915_private *dev_priv)
{
struct i915_gem_context *ctx;
@@ -427,6 +425,10 @@ int i915_gem_context_init(struct drm_i915_private *dev_priv)
if (WARN_ON(dev_priv->kernel_context))
return 0;
+ INIT_LIST_HEAD(&dev_priv->contexts.list);
+ INIT_WORK(&dev_priv->contexts.free_work, contexts_free_worker);
+ init_llist_head(&dev_priv->contexts.free_list);
+
if (intel_vgpu_active(dev_priv) &&
HAS_LOGICAL_RING_CONTEXTS(dev_priv)) {
if (!i915.enable_execlists) {
@@ -437,7 +439,7 @@ int i915_gem_context_init(struct drm_i915_private *dev_priv)
/* Using the simple ida interface, the max is limited by sizeof(int) */
BUILD_BUG_ON(MAX_CONTEXT_HW_ID > INT_MAX);
- ida_init(&dev_priv->context_hw_ida);
+ ida_init(&dev_priv->contexts.hw_ida);
ctx = i915_gem_create_context(dev_priv, NULL);
if (IS_ERR(ctx)) {
@@ -463,7 +465,7 @@ int i915_gem_context_init(struct drm_i915_private *dev_priv)
return 0;
}
-void i915_gem_context_lost(struct drm_i915_private *dev_priv)
+void i915_gem_contexts_lost(struct drm_i915_private *dev_priv)
{
struct intel_engine_cs *engine;
enum intel_engine_id id;
@@ -484,7 +486,7 @@ void i915_gem_context_lost(struct drm_i915_private *dev_priv)
if (!i915.enable_execlists) {
struct i915_gem_context *ctx;
- list_for_each_entry(ctx, &dev_priv->context_list, link) {
+ list_for_each_entry(ctx, &dev_priv->contexts.list, link) {
if (!i915_gem_context_is_default(ctx))
continue;
@@ -503,18 +505,20 @@ void i915_gem_context_lost(struct drm_i915_private *dev_priv)
}
}
-void i915_gem_context_fini(struct drm_i915_private *dev_priv)
+void i915_gem_contexts_fini(struct drm_i915_private *i915)
{
- struct i915_gem_context *dctx = dev_priv->kernel_context;
-
- lockdep_assert_held(&dev_priv->drm.struct_mutex);
+ struct i915_gem_context *ctx;
- GEM_BUG_ON(!i915_gem_context_is_kernel(dctx));
+ lockdep_assert_held(&i915->drm.struct_mutex);
- context_close(dctx);
- dev_priv->kernel_context = NULL;
+ /* Keep the context so that we can free it immediately ourselves */
+ ctx = i915_gem_context_get(fetch_and_zero(&i915->kernel_context));
+ GEM_BUG_ON(!i915_gem_context_is_kernel(ctx));
+ context_close(ctx);
+ i915_gem_context_free(ctx);
- ida_destroy(&dev_priv->context_hw_ida);
+ /* Must free all deferred contexts (via flush_workqueue) first */
+ ida_destroy(&i915->contexts.hw_ida);
}
static int context_idr_cleanup(int id, void *p, void *data)
@@ -525,32 +529,32 @@ static int context_idr_cleanup(int id, void *p, void *data)
return 0;
}
-int i915_gem_context_open(struct drm_device *dev, struct drm_file *file)
+int i915_gem_context_open(struct drm_i915_private *i915,
+ struct drm_file *file)
{
struct drm_i915_file_private *file_priv = file->driver_priv;
struct i915_gem_context *ctx;
idr_init(&file_priv->context_idr);
- mutex_lock(&dev->struct_mutex);
- ctx = i915_gem_create_context(to_i915(dev), file_priv);
- mutex_unlock(&dev->struct_mutex);
-
- GEM_BUG_ON(i915_gem_context_is_kernel(ctx));
-
+ mutex_lock(&i915->drm.struct_mutex);
+ ctx = i915_gem_create_context(i915, file_priv);
+ mutex_unlock(&i915->drm.struct_mutex);
if (IS_ERR(ctx)) {
idr_destroy(&file_priv->context_idr);
return PTR_ERR(ctx);
}
+ GEM_BUG_ON(i915_gem_context_is_kernel(ctx));
+
return 0;
}
-void i915_gem_context_close(struct drm_device *dev, struct drm_file *file)
+void i915_gem_context_close(struct drm_file *file)
{
struct drm_i915_file_private *file_priv = file->driver_priv;
- lockdep_assert_held(&dev->struct_mutex);
+ lockdep_assert_held(&file_priv->dev_priv->drm.struct_mutex);
idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL);
idr_destroy(&file_priv->context_idr);
@@ -925,7 +929,7 @@ int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv)
static bool client_is_banned(struct drm_i915_file_private *file_priv)
{
- return file_priv->context_bans > I915_MAX_CLIENT_CONTEXT_BANS;
+ return atomic_read(&file_priv->context_bans) > I915_MAX_CLIENT_CONTEXT_BANS;
}
int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
@@ -982,20 +986,19 @@ int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
if (args->ctx_id == DEFAULT_CONTEXT_HANDLE)
return -ENOENT;
- ret = i915_mutex_lock_interruptible(dev);
- if (ret)
- return ret;
-
ctx = i915_gem_context_lookup(file_priv, args->ctx_id);
- if (IS_ERR(ctx)) {
- mutex_unlock(&dev->struct_mutex);
- return PTR_ERR(ctx);
- }
+ if (!ctx)
+ return -ENOENT;
+
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ goto out;
__destroy_hw_context(ctx, file_priv);
mutex_unlock(&dev->struct_mutex);
- DRM_DEBUG("HW context %d destroyed\n", args->ctx_id);
+out:
+ i915_gem_context_put(ctx);
return 0;
}
@@ -1005,17 +1008,11 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
struct drm_i915_file_private *file_priv = file->driver_priv;
struct drm_i915_gem_context_param *args = data;
struct i915_gem_context *ctx;
- int ret;
-
- ret = i915_mutex_lock_interruptible(dev);
- if (ret)
- return ret;
+ int ret = 0;
ctx = i915_gem_context_lookup(file_priv, args->ctx_id);
- if (IS_ERR(ctx)) {
- mutex_unlock(&dev->struct_mutex);
- return PTR_ERR(ctx);
- }
+ if (!ctx)
+ return -ENOENT;
args->size = 0;
switch (args->param) {
@@ -1043,8 +1040,8 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
ret = -EINVAL;
break;
}
- mutex_unlock(&dev->struct_mutex);
+ i915_gem_context_put(ctx);
return ret;
}
@@ -1056,15 +1053,13 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
struct i915_gem_context *ctx;
int ret;
+ ctx = i915_gem_context_lookup(file_priv, args->ctx_id);
+ if (!ctx)
+ return -ENOENT;
+
ret = i915_mutex_lock_interruptible(dev);
if (ret)
- return ret;
-
- ctx = i915_gem_context_lookup(file_priv, args->ctx_id);
- if (IS_ERR(ctx)) {
- mutex_unlock(&dev->struct_mutex);
- return PTR_ERR(ctx);
- }
+ goto out;
switch (args->param) {
case I915_CONTEXT_PARAM_BAN_PERIOD:
@@ -1102,6 +1097,8 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
}
mutex_unlock(&dev->struct_mutex);
+out:
+ i915_gem_context_put(ctx);
return ret;
}
@@ -1116,27 +1113,31 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device *dev,
if (args->flags || args->pad)
return -EINVAL;
- ret = i915_mutex_lock_interruptible(dev);
- if (ret)
- return ret;
+ ret = -ENOENT;
+ rcu_read_lock();
+ ctx = __i915_gem_context_lookup_rcu(file->driver_priv, args->ctx_id);
+ if (!ctx)
+ goto out;
- ctx = i915_gem_context_lookup(file->driver_priv, args->ctx_id);
- if (IS_ERR(ctx)) {
- mutex_unlock(&dev->struct_mutex);
- return PTR_ERR(ctx);
- }
+ /*
+ * We opt for unserialised reads here. This may result in tearing
+ * in the extremely unlikely event of a GPU hang on this context
+ * as we are querying them. If we need that extra layer of protection,
+ * we should wrap the hangstats with a seqlock.
+ */
if (capable(CAP_SYS_ADMIN))
args->reset_count = i915_reset_count(&dev_priv->gpu_error);
else
args->reset_count = 0;
- args->batch_active = ctx->guilty_count;
- args->batch_pending = ctx->active_count;
-
- mutex_unlock(&dev->struct_mutex);
+ args->batch_active = atomic_read(&ctx->guilty_count);
+ args->batch_pending = atomic_read(&ctx->active_count);
- return 0;
+ ret = 0;
+out:
+ rcu_read_unlock();
+ return ret;
}
#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h
index 82c99ba..44688e2 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/i915_gem_context.h
@@ -27,6 +27,7 @@
#include <linux/bitops.h>
#include <linux/list.h>
+#include <linux/radix-tree.h>
struct pid;
@@ -86,6 +87,7 @@ struct i915_gem_context {
/** link: place with &drm_i915_private.context_list */
struct list_head link;
+ struct llist_node free_link;
/**
* @ref: reference count
@@ -99,6 +101,11 @@ struct i915_gem_context {
struct kref ref;
/**
+ * @rcu: rcu_head for deferred freeing.
+ */
+ struct rcu_head rcu;
+
+ /**
* @flags: small set of booleans
*/
unsigned long flags;
@@ -143,32 +150,6 @@ struct i915_gem_context {
/** ggtt_offset_bias: placement restriction for context objects */
u32 ggtt_offset_bias;
- struct i915_gem_context_vma_lut {
- /** ht_size: last request size to allocate the hashtable for. */
- unsigned int ht_size;
-#define I915_CTX_RESIZE_IN_PROGRESS BIT(0)
- /** ht_bits: real log2(size) of hashtable. */
- unsigned int ht_bits;
- /** ht_count: current number of entries inside the hashtable */
- unsigned int ht_count;
-
- /** ht: the array of buckets comprising the simple hashtable */
- struct hlist_head *ht;
-
- /**
- * resize: After an execbuf completes, we check the load factor
- * of the hashtable. If the hashtable is too full, or too empty,
- * we schedule a task to resize the hashtable. During the
- * resize, the entries are moved between different buckets and
- * so we cannot simultaneously read the hashtable as it is
- * being resized (unlike rhashtable). Therefore we treat the
- * active work as a strong barrier, pausing a subsequent
- * execbuf to wait for the resize worker to complete, if
- * required.
- */
- struct work_struct resize;
- } vma_lut;
-
/** engine: per-engine logical HW state */
struct intel_context {
struct i915_vma *state;
@@ -185,20 +166,32 @@ struct i915_gem_context {
u32 desc_template;
/** guilty_count: How many times this context has caused a GPU hang. */
- unsigned int guilty_count;
+ atomic_t guilty_count;
/**
* @active_count: How many times this context was active during a GPU
* hang, but did not cause it.
*/
- unsigned int active_count;
+ atomic_t active_count;
#define CONTEXT_SCORE_GUILTY 10
#define CONTEXT_SCORE_BAN_THRESHOLD 40
/** ban_score: Accumulated score of all hangs caused by this context. */
- int ban_score;
+ atomic_t ban_score;
/** remap_slice: Bitmask of cache lines that need remapping */
u8 remap_slice;
+
+ /** handles_vma: rbtree to look up our context specific obj/vma for
+ * the user handle. (user handles are per fd, but the binding is
+ * per vm, which may be one per context or shared with the global GTT)
+ */
+ struct radix_tree_root handles_vma;
+
+ /** handles_list: reverse list of all the rbtree entries in use for
+ * this context, which allows us to free all the allocations on
+ * context close.
+ */
+ struct list_head handles_list;
};
static inline bool i915_gem_context_is_closed(const struct i915_gem_context *ctx)
@@ -273,14 +266,18 @@ static inline bool i915_gem_context_is_kernel(struct i915_gem_context *ctx)
}
/* i915_gem_context.c */
-int __must_check i915_gem_context_init(struct drm_i915_private *dev_priv);
-void i915_gem_context_lost(struct drm_i915_private *dev_priv);
-void i915_gem_context_fini(struct drm_i915_private *dev_priv);
-int i915_gem_context_open(struct drm_device *dev, struct drm_file *file);
-void i915_gem_context_close(struct drm_device *dev, struct drm_file *file);
+int __must_check i915_gem_contexts_init(struct drm_i915_private *dev_priv);
+void i915_gem_contexts_lost(struct drm_i915_private *dev_priv);
+void i915_gem_contexts_fini(struct drm_i915_private *dev_priv);
+
+int i915_gem_context_open(struct drm_i915_private *i915,
+ struct drm_file *file);
+void i915_gem_context_close(struct drm_file *file);
+
int i915_switch_context(struct drm_i915_gem_request *req);
int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv);
-void i915_gem_context_free(struct kref *ctx_ref);
+
+void i915_gem_context_release(struct kref *ctx_ref);
struct i915_gem_context *
i915_gem_context_create_gvt(struct drm_device *dev);
@@ -295,4 +292,16 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
int i915_gem_context_reset_stats_ioctl(struct drm_device *dev, void *data,
struct drm_file *file);
+static inline struct i915_gem_context *
+i915_gem_context_get(struct i915_gem_context *ctx)
+{
+ kref_get(&ctx->ref);
+ return ctx;
+}
+
+static inline void i915_gem_context_put(struct i915_gem_context *ctx)
+{
+ kref_put(&ctx->ref, i915_gem_context_release);
+}
+
#endif /* !__I915_GEM_CONTEXT_H__ */
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
index a193f1b..4df039e 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -318,8 +318,8 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
/* Overlap of objects in the same batch? */
if (i915_vma_is_pinned(vma)) {
ret = -ENOSPC;
- if (vma->exec_entry &&
- vma->exec_entry->flags & EXEC_OBJECT_PINNED)
+ if (vma->exec_flags &&
+ *vma->exec_flags & EXEC_OBJECT_PINNED)
ret = -EINVAL;
break;
}
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index e9503f6..4c20162 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -32,6 +32,7 @@
#include <linux/uaccess.h>
#include <drm/drmP.h>
+#include <drm/drm_syncobj.h>
#include <drm/i915_drm.h>
#include "i915_drv.h"
@@ -191,6 +192,8 @@ struct i915_execbuffer {
struct drm_file *file; /** per-file lookup tables and limits */
struct drm_i915_gem_execbuffer2 *args; /** ioctl parameters */
struct drm_i915_gem_exec_object2 *exec; /** ioctl execobj[] */
+ struct i915_vma **vma;
+ unsigned int *flags;
struct intel_engine_cs *engine; /** engine to queue the request to */
struct i915_gem_context *ctx; /** context for building the request */
@@ -244,13 +247,7 @@ struct i915_execbuffer {
struct hlist_head *buckets; /** ht for relocation handles */
};
-/*
- * As an alternative to creating a hashtable of handle-to-vma for a batch,
- * we used the last available reserved field in the execobject[] and stash
- * a link from the execobj to its vma.
- */
-#define __exec_to_vma(ee) (ee)->rsvd2
-#define exec_to_vma(ee) u64_to_ptr(struct i915_vma, __exec_to_vma(ee))
+#define exec_entry(EB, VMA) (&(EB)->exec[(VMA)->exec_flags - (EB)->flags])
/*
* Used to convert any address to canonical form.
@@ -319,85 +316,82 @@ static int eb_create(struct i915_execbuffer *eb)
static bool
eb_vma_misplaced(const struct drm_i915_gem_exec_object2 *entry,
- const struct i915_vma *vma)
+ const struct i915_vma *vma,
+ unsigned int flags)
{
- if (!(entry->flags & __EXEC_OBJECT_HAS_PIN))
- return true;
-
if (vma->node.size < entry->pad_to_size)
return true;
if (entry->alignment && !IS_ALIGNED(vma->node.start, entry->alignment))
return true;
- if (entry->flags & EXEC_OBJECT_PINNED &&
+ if (flags & EXEC_OBJECT_PINNED &&
vma->node.start != entry->offset)
return true;
- if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS &&
+ if (flags & __EXEC_OBJECT_NEEDS_BIAS &&
vma->node.start < BATCH_OFFSET_BIAS)
return true;
- if (!(entry->flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS) &&
+ if (!(flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS) &&
(vma->node.start + vma->node.size - 1) >> 32)
return true;
return false;
}
-static inline void
+static inline bool
eb_pin_vma(struct i915_execbuffer *eb,
- struct drm_i915_gem_exec_object2 *entry,
+ const struct drm_i915_gem_exec_object2 *entry,
struct i915_vma *vma)
{
- u64 flags;
+ unsigned int exec_flags = *vma->exec_flags;
+ u64 pin_flags;
if (vma->node.size)
- flags = vma->node.start;
+ pin_flags = vma->node.start;
else
- flags = entry->offset & PIN_OFFSET_MASK;
+ pin_flags = entry->offset & PIN_OFFSET_MASK;
- flags |= PIN_USER | PIN_NOEVICT | PIN_OFFSET_FIXED;
- if (unlikely(entry->flags & EXEC_OBJECT_NEEDS_GTT))
- flags |= PIN_GLOBAL;
+ pin_flags |= PIN_USER | PIN_NOEVICT | PIN_OFFSET_FIXED;
+ if (unlikely(exec_flags & EXEC_OBJECT_NEEDS_GTT))
+ pin_flags |= PIN_GLOBAL;
- if (unlikely(i915_vma_pin(vma, 0, 0, flags)))
- return;
+ if (unlikely(i915_vma_pin(vma, 0, 0, pin_flags)))
+ return false;
- if (unlikely(entry->flags & EXEC_OBJECT_NEEDS_FENCE)) {
+ if (unlikely(exec_flags & EXEC_OBJECT_NEEDS_FENCE)) {
if (unlikely(i915_vma_get_fence(vma))) {
i915_vma_unpin(vma);
- return;
+ return false;
}
if (i915_vma_pin_fence(vma))
- entry->flags |= __EXEC_OBJECT_HAS_FENCE;
+ exec_flags |= __EXEC_OBJECT_HAS_FENCE;
}
- entry->flags |= __EXEC_OBJECT_HAS_PIN;
+ *vma->exec_flags = exec_flags | __EXEC_OBJECT_HAS_PIN;
+ return !eb_vma_misplaced(entry, vma, exec_flags);
}
-static inline void
-__eb_unreserve_vma(struct i915_vma *vma,
- const struct drm_i915_gem_exec_object2 *entry)
+static inline void __eb_unreserve_vma(struct i915_vma *vma, unsigned int flags)
{
- GEM_BUG_ON(!(entry->flags & __EXEC_OBJECT_HAS_PIN));
+ GEM_BUG_ON(!(flags & __EXEC_OBJECT_HAS_PIN));
- if (unlikely(entry->flags & __EXEC_OBJECT_HAS_FENCE))
+ if (unlikely(flags & __EXEC_OBJECT_HAS_FENCE))
i915_vma_unpin_fence(vma);
__i915_vma_unpin(vma);
}
static inline void
-eb_unreserve_vma(struct i915_vma *vma,
- struct drm_i915_gem_exec_object2 *entry)
+eb_unreserve_vma(struct i915_vma *vma, unsigned int *flags)
{
- if (!(entry->flags & __EXEC_OBJECT_HAS_PIN))
+ if (!(*flags & __EXEC_OBJECT_HAS_PIN))
return;
- __eb_unreserve_vma(vma, entry);
- entry->flags &= ~__EXEC_OBJECT_RESERVED;
+ __eb_unreserve_vma(vma, *flags);
+ *flags &= ~__EXEC_OBJECT_RESERVED;
}
static int
@@ -427,7 +421,7 @@ eb_validate_vma(struct i915_execbuffer *eb,
entry->pad_to_size = 0;
}
- if (unlikely(vma->exec_entry)) {
+ if (unlikely(vma->exec_flags)) {
DRM_DEBUG("Object [handle %d, index %d] appears more than once in object list\n",
entry->handle, (int)(entry - eb->exec));
return -EINVAL;
@@ -440,14 +434,25 @@ eb_validate_vma(struct i915_execbuffer *eb,
*/
entry->offset = gen8_noncanonical_addr(entry->offset);
+ if (!eb->reloc_cache.has_fence) {
+ entry->flags &= ~EXEC_OBJECT_NEEDS_FENCE;
+ } else {
+ if ((entry->flags & EXEC_OBJECT_NEEDS_FENCE ||
+ eb->reloc_cache.needs_unfenced) &&
+ i915_gem_object_is_tiled(vma->obj))
+ entry->flags |= EXEC_OBJECT_NEEDS_GTT | __EXEC_OBJECT_NEEDS_MAP;
+ }
+
+ if (!(entry->flags & EXEC_OBJECT_PINNED))
+ entry->flags |= eb->context_flags;
+
return 0;
}
static int
-eb_add_vma(struct i915_execbuffer *eb,
- struct drm_i915_gem_exec_object2 *entry,
- struct i915_vma *vma)
+eb_add_vma(struct i915_execbuffer *eb, unsigned int i, struct i915_vma *vma)
{
+ struct drm_i915_gem_exec_object2 *entry = &eb->exec[i];
int err;
GEM_BUG_ON(i915_vma_is_closed(vma));
@@ -468,40 +473,28 @@ eb_add_vma(struct i915_execbuffer *eb,
if (entry->relocation_count)
list_add_tail(&vma->reloc_link, &eb->relocs);
- if (!eb->reloc_cache.has_fence) {
- entry->flags &= ~EXEC_OBJECT_NEEDS_FENCE;
- } else {
- if ((entry->flags & EXEC_OBJECT_NEEDS_FENCE ||
- eb->reloc_cache.needs_unfenced) &&
- i915_gem_object_is_tiled(vma->obj))
- entry->flags |= EXEC_OBJECT_NEEDS_GTT | __EXEC_OBJECT_NEEDS_MAP;
- }
-
- if (!(entry->flags & EXEC_OBJECT_PINNED))
- entry->flags |= eb->context_flags;
-
/*
* Stash a pointer from the vma to execobj, so we can query its flags,
* size, alignment etc as provided by the user. Also we stash a pointer
* to the vma inside the execobj so that we can use a direct lookup
* to find the right target VMA when doing relocations.
*/
- vma->exec_entry = entry;
- __exec_to_vma(entry) = (uintptr_t)vma;
+ eb->vma[i] = vma;
+ eb->flags[i] = entry->flags;
+ vma->exec_flags = &eb->flags[i];
err = 0;
- eb_pin_vma(eb, entry, vma);
- if (eb_vma_misplaced(entry, vma)) {
- eb_unreserve_vma(vma, entry);
-
- list_add_tail(&vma->exec_link, &eb->unbound);
- if (drm_mm_node_allocated(&vma->node))
- err = i915_vma_unbind(vma);
- } else {
+ if (eb_pin_vma(eb, entry, vma)) {
if (entry->offset != vma->node.start) {
entry->offset = vma->node.start | UPDATE;
eb->args->flags |= __EXEC_HAS_RELOC;
}
+ } else {
+ eb_unreserve_vma(vma, vma->exec_flags);
+
+ list_add_tail(&vma->exec_link, &eb->unbound);
+ if (drm_mm_node_allocated(&vma->node))
+ err = i915_vma_unbind(vma);
}
return err;
}
@@ -526,32 +519,35 @@ static inline int use_cpu_reloc(const struct reloc_cache *cache,
static int eb_reserve_vma(const struct i915_execbuffer *eb,
struct i915_vma *vma)
{
- struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
- u64 flags;
+ struct drm_i915_gem_exec_object2 *entry = exec_entry(eb, vma);
+ unsigned int exec_flags = *vma->exec_flags;
+ u64 pin_flags;
int err;
- flags = PIN_USER | PIN_NONBLOCK;
- if (entry->flags & EXEC_OBJECT_NEEDS_GTT)
- flags |= PIN_GLOBAL;
+ pin_flags = PIN_USER | PIN_NONBLOCK;
+ if (exec_flags & EXEC_OBJECT_NEEDS_GTT)
+ pin_flags |= PIN_GLOBAL;
/*
* Wa32bitGeneralStateOffset & Wa32bitInstructionBaseOffset,
* limit address to the first 4GBs for unflagged objects.
*/
- if (!(entry->flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS))
- flags |= PIN_ZONE_4G;
+ if (!(exec_flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS))
+ pin_flags |= PIN_ZONE_4G;
- if (entry->flags & __EXEC_OBJECT_NEEDS_MAP)
- flags |= PIN_MAPPABLE;
+ if (exec_flags & __EXEC_OBJECT_NEEDS_MAP)
+ pin_flags |= PIN_MAPPABLE;
- if (entry->flags & EXEC_OBJECT_PINNED) {
- flags |= entry->offset | PIN_OFFSET_FIXED;
- flags &= ~PIN_NONBLOCK; /* force overlapping PINNED checks */
- } else if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS) {
- flags |= BATCH_OFFSET_BIAS | PIN_OFFSET_BIAS;
+ if (exec_flags & EXEC_OBJECT_PINNED) {
+ pin_flags |= entry->offset | PIN_OFFSET_FIXED;
+ pin_flags &= ~PIN_NONBLOCK; /* force overlapping checks */
+ } else if (exec_flags & __EXEC_OBJECT_NEEDS_BIAS) {
+ pin_flags |= BATCH_OFFSET_BIAS | PIN_OFFSET_BIAS;
}
- err = i915_vma_pin(vma, entry->pad_to_size, entry->alignment, flags);
+ err = i915_vma_pin(vma,
+ entry->pad_to_size, entry->alignment,
+ pin_flags);
if (err)
return err;
@@ -560,7 +556,7 @@ static int eb_reserve_vma(const struct i915_execbuffer *eb,
eb->args->flags |= __EXEC_HAS_RELOC;
}
- if (unlikely(entry->flags & EXEC_OBJECT_NEEDS_FENCE)) {
+ if (unlikely(exec_flags & EXEC_OBJECT_NEEDS_FENCE)) {
err = i915_vma_get_fence(vma);
if (unlikely(err)) {
i915_vma_unpin(vma);
@@ -568,11 +564,11 @@ static int eb_reserve_vma(const struct i915_execbuffer *eb,
}
if (i915_vma_pin_fence(vma))
- entry->flags |= __EXEC_OBJECT_HAS_FENCE;
+ exec_flags |= __EXEC_OBJECT_HAS_FENCE;
}
- entry->flags |= __EXEC_OBJECT_HAS_PIN;
- GEM_BUG_ON(eb_vma_misplaced(entry, vma));
+ *vma->exec_flags = exec_flags | __EXEC_OBJECT_HAS_PIN;
+ GEM_BUG_ON(eb_vma_misplaced(entry, vma, exec_flags));
return 0;
}
@@ -614,18 +610,18 @@ static int eb_reserve(struct i915_execbuffer *eb)
INIT_LIST_HEAD(&eb->unbound);
INIT_LIST_HEAD(&last);
for (i = 0; i < count; i++) {
- struct drm_i915_gem_exec_object2 *entry = &eb->exec[i];
+ unsigned int flags = eb->flags[i];
+ struct i915_vma *vma = eb->vma[i];
- if (entry->flags & EXEC_OBJECT_PINNED &&
- entry->flags & __EXEC_OBJECT_HAS_PIN)
+ if (flags & EXEC_OBJECT_PINNED &&
+ flags & __EXEC_OBJECT_HAS_PIN)
continue;
- vma = exec_to_vma(entry);
- eb_unreserve_vma(vma, entry);
+ eb_unreserve_vma(vma, &eb->flags[i]);
- if (entry->flags & EXEC_OBJECT_PINNED)
+ if (flags & EXEC_OBJECT_PINNED)
list_add(&vma->exec_link, &eb->unbound);
- else if (entry->flags & __EXEC_OBJECT_NEEDS_MAP)
+ else if (flags & __EXEC_OBJECT_NEEDS_MAP)
list_add_tail(&vma->exec_link, &eb->unbound);
else
list_add_tail(&vma->exec_link, &last);
@@ -649,19 +645,6 @@ static int eb_reserve(struct i915_execbuffer *eb)
} while (1);
}
-static inline struct hlist_head *
-ht_head(const struct i915_gem_context_vma_lut *lut, u32 handle)
-{
- return &lut->ht[hash_32(handle, lut->ht_bits)];
-}
-
-static inline bool
-ht_needs_resize(const struct i915_gem_context_vma_lut *lut)
-{
- return (4*lut->ht_count > 3*lut->ht_size ||
- 4*lut->ht_count + 1 < lut->ht_size);
-}
-
static unsigned int eb_batch_index(const struct i915_execbuffer *eb)
{
if (eb->args->flags & I915_EXEC_BATCH_FIRST)
@@ -675,16 +658,10 @@ static int eb_select_context(struct i915_execbuffer *eb)
struct i915_gem_context *ctx;
ctx = i915_gem_context_lookup(eb->file->driver_priv, eb->args->rsvd1);
- if (unlikely(IS_ERR(ctx)))
- return PTR_ERR(ctx);
-
- if (unlikely(i915_gem_context_is_banned(ctx))) {
- DRM_DEBUG("Context %u tried to submit while banned\n",
- ctx->user_handle);
- return -EIO;
- }
+ if (unlikely(!ctx))
+ return -ENOENT;
- eb->ctx = i915_gem_context_get(ctx);
+ eb->ctx = ctx;
eb->vm = ctx->ppgtt ? &ctx->ppgtt->base : &eb->i915->ggtt.base;
eb->context_flags = 0;
@@ -696,132 +673,74 @@ static int eb_select_context(struct i915_execbuffer *eb)
static int eb_lookup_vmas(struct i915_execbuffer *eb)
{
-#define INTERMEDIATE BIT(0)
- const unsigned int count = eb->buffer_count;
- struct i915_gem_context_vma_lut *lut = &eb->ctx->vma_lut;
- struct i915_vma *vma;
- struct idr *idr;
+ struct radix_tree_root *handles_vma = &eb->ctx->handles_vma;
+ struct drm_i915_gem_object *uninitialized_var(obj);
unsigned int i;
- int slow_pass = -1;
int err;
- INIT_LIST_HEAD(&eb->relocs);
- INIT_LIST_HEAD(&eb->unbound);
-
- if (unlikely(lut->ht_size & I915_CTX_RESIZE_IN_PROGRESS))
- flush_work(&lut->resize);
- GEM_BUG_ON(lut->ht_size & I915_CTX_RESIZE_IN_PROGRESS);
-
- for (i = 0; i < count; i++) {
- __exec_to_vma(&eb->exec[i]) = 0;
-
- hlist_for_each_entry(vma,
- ht_head(lut, eb->exec[i].handle),
- ctx_node) {
- if (vma->ctx_handle != eb->exec[i].handle)
- continue;
-
- err = eb_add_vma(eb, &eb->exec[i], vma);
- if (unlikely(err))
- return err;
-
- goto next_vma;
- }
+ if (unlikely(i915_gem_context_is_closed(eb->ctx)))
+ return -ENOENT;
- if (slow_pass < 0)
- slow_pass = i;
-next_vma: ;
- }
+ if (unlikely(i915_gem_context_is_banned(eb->ctx)))
+ return -EIO;
- if (slow_pass < 0)
- goto out;
+ INIT_LIST_HEAD(&eb->relocs);
+ INIT_LIST_HEAD(&eb->unbound);
- spin_lock(&eb->file->table_lock);
- /*
- * Grab a reference to the object and release the lock so we can lookup
- * or create the VMA without using GFP_ATOMIC
- */
- idr = &eb->file->object_idr;
- for (i = slow_pass; i < count; i++) {
- struct drm_i915_gem_object *obj;
+ for (i = 0; i < eb->buffer_count; i++) {
+ u32 handle = eb->exec[i].handle;
+ struct i915_lut_handle *lut;
+ struct i915_vma *vma;
- if (__exec_to_vma(&eb->exec[i]))
- continue;
+ vma = radix_tree_lookup(handles_vma, handle);
+ if (likely(vma))
+ goto add_vma;
- obj = to_intel_bo(idr_find(idr, eb->exec[i].handle));
+ obj = i915_gem_object_lookup(eb->file, handle);
if (unlikely(!obj)) {
- spin_unlock(&eb->file->table_lock);
- DRM_DEBUG("Invalid object handle %d at index %d\n",
- eb->exec[i].handle, i);
err = -ENOENT;
- goto err;
+ goto err_vma;
}
- __exec_to_vma(&eb->exec[i]) = INTERMEDIATE | (uintptr_t)obj;
- }
- spin_unlock(&eb->file->table_lock);
-
- for (i = slow_pass; i < count; i++) {
- struct drm_i915_gem_object *obj;
-
- if (!(__exec_to_vma(&eb->exec[i]) & INTERMEDIATE))
- continue;
-
- /*
- * NOTE: We can leak any vmas created here when something fails
- * later on. But that's no issue since vma_unbind can deal with
- * vmas which are not actually bound. And since only
- * lookup_or_create exists as an interface to get at the vma
- * from the (obj, vm) we don't run the risk of creating
- * duplicated vmas for the same vm.
- */
- obj = u64_to_ptr(typeof(*obj),
- __exec_to_vma(&eb->exec[i]) & ~INTERMEDIATE);
vma = i915_vma_instance(obj, eb->vm, NULL);
if (unlikely(IS_ERR(vma))) {
- DRM_DEBUG("Failed to lookup VMA\n");
err = PTR_ERR(vma);
- goto err;
+ goto err_obj;
}
- /* First come, first served */
- if (!vma->ctx) {
- vma->ctx = eb->ctx;
- vma->ctx_handle = eb->exec[i].handle;
- hlist_add_head(&vma->ctx_node,
- ht_head(lut, eb->exec[i].handle));
- lut->ht_count++;
- lut->ht_size |= I915_CTX_RESIZE_IN_PROGRESS;
- if (i915_vma_is_ggtt(vma)) {
- GEM_BUG_ON(obj->vma_hashed);
- obj->vma_hashed = vma;
- }
+ lut = kmem_cache_alloc(eb->i915->luts, GFP_KERNEL);
+ if (unlikely(!lut)) {
+ err = -ENOMEM;
+ goto err_obj;
+ }
- i915_vma_get(vma);
+ err = radix_tree_insert(handles_vma, handle, vma);
+ if (unlikely(err)) {
+ kfree(lut);
+ goto err_obj;
}
- err = eb_add_vma(eb, &eb->exec[i], vma);
- if (unlikely(err))
- goto err;
+ list_add(&lut->obj_link, &obj->lut_list);
+ list_add(&lut->ctx_link, &eb->ctx->handles_list);
+ lut->ctx = eb->ctx;
+ lut->handle = handle;
- /* Only after we validated the user didn't use our bits */
- if (vma->ctx != eb->ctx) {
- i915_vma_get(vma);
- eb->exec[i].flags |= __EXEC_OBJECT_HAS_REF;
- }
- }
+ /* transfer ref to ctx */
+ obj = NULL;
- if (lut->ht_size & I915_CTX_RESIZE_IN_PROGRESS) {
- if (ht_needs_resize(lut))
- queue_work(system_highpri_wq, &lut->resize);
- else
- lut->ht_size &= ~I915_CTX_RESIZE_IN_PROGRESS;
+add_vma:
+ err = eb_add_vma(eb, i, vma);
+ if (unlikely(err))
+ goto err_obj;
+
+ GEM_BUG_ON(vma != eb->vma[i]);
+ GEM_BUG_ON(vma->exec_flags != &eb->flags[i]);
}
-out:
/* take note of the batch buffer before we might reorder the lists */
i = eb_batch_index(eb);
- eb->batch = exec_to_vma(&eb->exec[i]);
+ eb->batch = eb->vma[i];
+ GEM_BUG_ON(eb->batch->exec_flags != &eb->flags[i]);
/*
* SNA is doing fancy tricks with compressing batch buffers, which leads
@@ -832,22 +751,20 @@ out:
* Note that actual hangs have only been observed on gen7, but for
* paranoia do it everywhere.
*/
- if (!(eb->exec[i].flags & EXEC_OBJECT_PINNED))
- eb->exec[i].flags |= __EXEC_OBJECT_NEEDS_BIAS;
+ if (!(eb->flags[i] & EXEC_OBJECT_PINNED))
+ eb->flags[i] |= __EXEC_OBJECT_NEEDS_BIAS;
if (eb->reloc_cache.has_fence)
- eb->exec[i].flags |= EXEC_OBJECT_NEEDS_FENCE;
+ eb->flags[i] |= EXEC_OBJECT_NEEDS_FENCE;
eb->args->flags |= __EXEC_VALIDATED;
return eb_reserve(eb);
-err:
- for (i = slow_pass; i < count; i++) {
- if (__exec_to_vma(&eb->exec[i]) & INTERMEDIATE)
- __exec_to_vma(&eb->exec[i]) = 0;
- }
- lut->ht_size &= ~I915_CTX_RESIZE_IN_PROGRESS;
+err_obj:
+ if (obj)
+ i915_gem_object_put(obj);
+err_vma:
+ eb->vma[i] = NULL;
return err;
-#undef INTERMEDIATE
}
static struct i915_vma *
@@ -856,7 +773,7 @@ eb_get_vma(const struct i915_execbuffer *eb, unsigned long handle)
if (eb->lut_size < 0) {
if (handle >= -eb->lut_size)
return NULL;
- return exec_to_vma(&eb->exec[handle]);
+ return eb->vma[handle];
} else {
struct hlist_head *head;
struct i915_vma *vma;
@@ -876,24 +793,21 @@ static void eb_release_vmas(const struct i915_execbuffer *eb)
unsigned int i;
for (i = 0; i < count; i++) {
- struct drm_i915_gem_exec_object2 *entry = &eb->exec[i];
- struct i915_vma *vma = exec_to_vma(entry);
+ struct i915_vma *vma = eb->vma[i];
+ unsigned int flags = eb->flags[i];
if (!vma)
- continue;
+ break;
- GEM_BUG_ON(vma->exec_entry != entry);
- vma->exec_entry = NULL;
- __exec_to_vma(entry) = 0;
+ GEM_BUG_ON(vma->exec_flags != &eb->flags[i]);
+ vma->exec_flags = NULL;
+ eb->vma[i] = NULL;
- if (entry->flags & __EXEC_OBJECT_HAS_PIN)
- __eb_unreserve_vma(vma, entry);
+ if (flags & __EXEC_OBJECT_HAS_PIN)
+ __eb_unreserve_vma(vma, flags);
- if (entry->flags & __EXEC_OBJECT_HAS_REF)
+ if (flags & __EXEC_OBJECT_HAS_REF)
i915_vma_put(vma);
-
- entry->flags &=
- ~(__EXEC_OBJECT_RESERVED | __EXEC_OBJECT_HAS_REF);
}
}
@@ -1266,7 +1180,9 @@ relocate_entry(struct i915_vma *vma,
if (!eb->reloc_cache.vaddr &&
(DBG_FORCE_RELOC == FORCE_GPU_RELOC ||
- !reservation_object_test_signaled_rcu(vma->resv, true))) {
+ !reservation_object_test_signaled_rcu(vma->resv, true)) &&
+ __intel_engine_can_store_dword(eb->reloc_cache.gen,
+ eb->engine->class)) {
const unsigned int gen = eb->reloc_cache.gen;
unsigned int len;
u32 *batch;
@@ -1276,10 +1192,8 @@ relocate_entry(struct i915_vma *vma,
len = offset & 7 ? 8 : 5;
else if (gen >= 4)
len = 4;
- else if (gen >= 3)
+ else
len = 3;
- else /* On gen2 MI_STORE_DWORD_IMM uses a physical address */
- goto repeat;
batch = reloc_gpu(eb, vma, len);
if (IS_ERR(batch))
@@ -1382,7 +1296,7 @@ eb_relocate_entry(struct i915_execbuffer *eb,
}
if (reloc->write_domain) {
- target->exec_entry->flags |= EXEC_OBJECT_WRITE;
+ *target->exec_flags |= EXEC_OBJECT_WRITE;
/*
* Sandybridge PPGTT errata: We need a global gtt mapping
@@ -1432,9 +1346,9 @@ eb_relocate_entry(struct i915_execbuffer *eb,
* patching using the GPU (though that should be serialised by the
* timeline). To be completely sure, and since we are required to
* do relocations we are already stalling, disable the user's opt
- * of our synchronisation.
+ * out of our synchronisation.
*/
- vma->exec_entry->flags &= ~EXEC_OBJECT_ASYNC;
+ *vma->exec_flags &= ~EXEC_OBJECT_ASYNC;
/* and update the user's relocation entry */
return relocate_entry(vma, reloc, eb, target);
@@ -1445,7 +1359,7 @@ static int eb_relocate_vma(struct i915_execbuffer *eb, struct i915_vma *vma)
#define N_RELOC(x) ((x) / sizeof(struct drm_i915_gem_relocation_entry))
struct drm_i915_gem_relocation_entry stack[N_RELOC(512)];
struct drm_i915_gem_relocation_entry __user *urelocs;
- const struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
+ const struct drm_i915_gem_exec_object2 *entry = exec_entry(eb, vma);
unsigned int remain;
urelocs = u64_to_user_ptr(entry->relocs_ptr);
@@ -1528,7 +1442,7 @@ out:
static int
eb_relocate_vma_slow(struct i915_execbuffer *eb, struct i915_vma *vma)
{
- const struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
+ const struct drm_i915_gem_exec_object2 *entry = exec_entry(eb, vma);
struct drm_i915_gem_relocation_entry *relocs =
u64_to_ptr(typeof(*relocs), entry->relocs_ptr);
unsigned int i;
@@ -1732,6 +1646,8 @@ repeat:
if (err)
goto err;
+ GEM_BUG_ON(!eb->batch);
+
list_for_each_entry(vma, &eb->relocs, reloc_link) {
if (!have_copy) {
pagefault_disable();
@@ -1825,11 +1741,11 @@ static int eb_move_to_gpu(struct i915_execbuffer *eb)
int err;
for (i = 0; i < count; i++) {
- struct drm_i915_gem_exec_object2 *entry = &eb->exec[i];
- struct i915_vma *vma = exec_to_vma(entry);
+ unsigned int flags = eb->flags[i];
+ struct i915_vma *vma = eb->vma[i];
struct drm_i915_gem_object *obj = vma->obj;
- if (entry->flags & EXEC_OBJECT_CAPTURE) {
+ if (flags & EXEC_OBJECT_CAPTURE) {
struct i915_gem_capture_list *capture;
capture = kmalloc(sizeof(*capture), GFP_KERNEL);
@@ -1837,35 +1753,47 @@ static int eb_move_to_gpu(struct i915_execbuffer *eb)
return -ENOMEM;
capture->next = eb->request->capture_list;
- capture->vma = vma;
+ capture->vma = eb->vma[i];
eb->request->capture_list = capture;
}
- if (unlikely(obj->cache_dirty && !obj->cache_coherent)) {
+ /*
+ * If the GPU is not _reading_ through the CPU cache, we need
+ * to make sure that any writes (both previous GPU writes from
+ * before a change in snooping levels and normal CPU writes)
+ * caught in that cache are flushed to main memory.
+ *
+ * We want to say
+ * obj->cache_dirty &&
+ * !(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ)
+ * but gcc's optimiser doesn't handle that as well and emits
+ * two jumps instead of one. Maybe one day...
+ */
+ if (unlikely(obj->cache_dirty & ~obj->cache_coherent)) {
if (i915_gem_clflush_object(obj, 0))
- entry->flags &= ~EXEC_OBJECT_ASYNC;
+ flags &= ~EXEC_OBJECT_ASYNC;
}
- if (entry->flags & EXEC_OBJECT_ASYNC)
- goto skip_flushes;
+ if (flags & EXEC_OBJECT_ASYNC)
+ continue;
err = i915_gem_request_await_object
- (eb->request, obj, entry->flags & EXEC_OBJECT_WRITE);
+ (eb->request, obj, flags & EXEC_OBJECT_WRITE);
if (err)
return err;
-
-skip_flushes:
- i915_vma_move_to_active(vma, eb->request, entry->flags);
- __eb_unreserve_vma(vma, entry);
- vma->exec_entry = NULL;
}
for (i = 0; i < count; i++) {
- const struct drm_i915_gem_exec_object2 *entry = &eb->exec[i];
- struct i915_vma *vma = exec_to_vma(entry);
+ unsigned int flags = eb->flags[i];
+ struct i915_vma *vma = eb->vma[i];
- eb_export_fence(vma, eb->request, entry->flags);
- if (unlikely(entry->flags & __EXEC_OBJECT_HAS_REF))
+ i915_vma_move_to_active(vma, eb->request, flags);
+ eb_export_fence(vma, eb->request, flags);
+
+ __eb_unreserve_vma(vma, flags);
+ vma->exec_flags = NULL;
+
+ if (unlikely(flags & __EXEC_OBJECT_HAS_REF))
i915_vma_put(vma);
}
eb->exec = NULL;
@@ -1883,8 +1811,10 @@ static bool i915_gem_check_execbuffer(struct drm_i915_gem_execbuffer2 *exec)
return false;
/* Kernel clipping was a DRI1 misfeature */
- if (exec->num_cliprects || exec->cliprects_ptr)
- return false;
+ if (!(exec->flags & I915_EXEC_FENCE_ARRAY)) {
+ if (exec->num_cliprects || exec->cliprects_ptr)
+ return false;
+ }
if (exec->DR4 == 0xffffffff) {
DRM_DEBUG("UXA submitting garbage DR4, fixing up\n");
@@ -1992,11 +1922,11 @@ static struct i915_vma *eb_parse(struct i915_execbuffer *eb, bool is_master)
if (IS_ERR(vma))
goto out;
- vma->exec_entry =
- memset(&eb->exec[eb->buffer_count++],
- 0, sizeof(*vma->exec_entry));
- vma->exec_entry->flags = __EXEC_OBJECT_HAS_PIN | __EXEC_OBJECT_HAS_REF;
- __exec_to_vma(vma->exec_entry) = (uintptr_t)i915_vma_get(vma);
+ eb->vma[eb->buffer_count] = i915_vma_get(vma);
+ eb->flags[eb->buffer_count] =
+ __EXEC_OBJECT_HAS_PIN | __EXEC_OBJECT_HAS_REF;
+ vma->exec_flags = &eb->flags[eb->buffer_count];
+ eb->buffer_count++;
out:
i915_gem_object_unpin_pages(shadow_batch_obj);
@@ -2115,11 +2045,129 @@ eb_select_engine(struct drm_i915_private *dev_priv,
return engine;
}
+static void
+__free_fence_array(struct drm_syncobj **fences, unsigned int n)
+{
+ while (n--)
+ drm_syncobj_put(ptr_mask_bits(fences[n], 2));
+ kvfree(fences);
+}
+
+static struct drm_syncobj **
+get_fence_array(struct drm_i915_gem_execbuffer2 *args,
+ struct drm_file *file)
+{
+ const unsigned int nfences = args->num_cliprects;
+ struct drm_i915_gem_exec_fence __user *user;
+ struct drm_syncobj **fences;
+ unsigned int n;
+ int err;
+
+ if (!(args->flags & I915_EXEC_FENCE_ARRAY))
+ return NULL;
+
+ if (nfences > SIZE_MAX / sizeof(*fences))
+ return ERR_PTR(-EINVAL);
+
+ user = u64_to_user_ptr(args->cliprects_ptr);
+ if (!access_ok(VERIFY_READ, user, nfences * 2 * sizeof(u32)))
+ return ERR_PTR(-EFAULT);
+
+ fences = kvmalloc_array(args->num_cliprects, sizeof(*fences),
+ __GFP_NOWARN | GFP_TEMPORARY);
+ if (!fences)
+ return ERR_PTR(-ENOMEM);
+
+ for (n = 0; n < nfences; n++) {
+ struct drm_i915_gem_exec_fence fence;
+ struct drm_syncobj *syncobj;
+
+ if (__copy_from_user(&fence, user++, sizeof(fence))) {
+ err = -EFAULT;
+ goto err;
+ }
+
+ syncobj = drm_syncobj_find(file, fence.handle);
+ if (!syncobj) {
+ DRM_DEBUG("Invalid syncobj handle provided\n");
+ err = -ENOENT;
+ goto err;
+ }
+
+ fences[n] = ptr_pack_bits(syncobj, fence.flags, 2);
+ }
+
+ return fences;
+
+err:
+ __free_fence_array(fences, n);
+ return ERR_PTR(err);
+}
+
+static void
+put_fence_array(struct drm_i915_gem_execbuffer2 *args,
+ struct drm_syncobj **fences)
+{
+ if (fences)
+ __free_fence_array(fences, args->num_cliprects);
+}
+
+static int
+await_fence_array(struct i915_execbuffer *eb,
+ struct drm_syncobj **fences)
+{
+ const unsigned int nfences = eb->args->num_cliprects;
+ unsigned int n;
+ int err;
+
+ for (n = 0; n < nfences; n++) {
+ struct drm_syncobj *syncobj;
+ struct dma_fence *fence;
+ unsigned int flags;
+
+ syncobj = ptr_unpack_bits(fences[n], &flags, 2);
+ if (!(flags & I915_EXEC_FENCE_WAIT))
+ continue;
+
+ fence = drm_syncobj_fence_get(syncobj);
+ if (!fence)
+ return -EINVAL;
+
+ err = i915_gem_request_await_dma_fence(eb->request, fence);
+ dma_fence_put(fence);
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
+}
+
+static void
+signal_fence_array(struct i915_execbuffer *eb,
+ struct drm_syncobj **fences)
+{
+ const unsigned int nfences = eb->args->num_cliprects;
+ struct dma_fence * const fence = &eb->request->fence;
+ unsigned int n;
+
+ for (n = 0; n < nfences; n++) {
+ struct drm_syncobj *syncobj;
+ unsigned int flags;
+
+ syncobj = ptr_unpack_bits(fences[n], &flags, 2);
+ if (!(flags & I915_EXEC_FENCE_SIGNAL))
+ continue;
+
+ drm_syncobj_replace_fence(syncobj, fence);
+ }
+}
+
static int
i915_gem_do_execbuffer(struct drm_device *dev,
struct drm_file *file,
struct drm_i915_gem_execbuffer2 *args,
- struct drm_i915_gem_exec_object2 *exec)
+ struct drm_i915_gem_exec_object2 *exec,
+ struct drm_syncobj **fences)
{
struct i915_execbuffer eb;
struct dma_fence *in_fence = NULL;
@@ -2135,8 +2183,12 @@ i915_gem_do_execbuffer(struct drm_device *dev,
eb.args = args;
if (DBG_FORCE_RELOC || !(args->flags & I915_EXEC_NO_RELOC))
args->flags |= __EXEC_HAS_RELOC;
+
eb.exec = exec;
- eb.ctx = NULL;
+ eb.vma = (struct i915_vma **)(exec + args->buffer_count + 1);
+ eb.vma[0] = NULL;
+ eb.flags = (unsigned int *)(eb.vma + args->buffer_count + 1);
+
eb.invalid_flags = __EXEC_OBJECT_UNKNOWN_FLAGS;
if (USES_FULL_PPGTT(eb.i915))
eb.invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
@@ -2194,6 +2246,10 @@ i915_gem_do_execbuffer(struct drm_device *dev,
GEM_BUG_ON(!eb.lut_size);
+ err = eb_select_context(&eb);
+ if (unlikely(err))
+ goto err_destroy;
+
/*
* Take a local wakeref for preparing to dispatch the execbuf as
* we expect to access the hardware fairly frequently in the
@@ -2202,14 +2258,11 @@ i915_gem_do_execbuffer(struct drm_device *dev,
* 100ms.
*/
intel_runtime_pm_get(eb.i915);
+
err = i915_mutex_lock_interruptible(dev);
if (err)
goto err_rpm;
- err = eb_select_context(&eb);
- if (unlikely(err))
- goto err_unlock;
-
err = eb_relocate(&eb);
if (err) {
/*
@@ -2223,7 +2276,7 @@ i915_gem_do_execbuffer(struct drm_device *dev,
goto err_vma;
}
- if (unlikely(eb.batch->exec_entry->flags & EXEC_OBJECT_WRITE)) {
+ if (unlikely(*eb.batch->exec_flags & EXEC_OBJECT_WRITE)) {
DRM_DEBUG("Attempting to use self-modifying batch buffer\n");
err = -EINVAL;
goto err_vma;
@@ -2305,6 +2358,12 @@ i915_gem_do_execbuffer(struct drm_device *dev,
goto err_request;
}
+ if (fences) {
+ err = await_fence_array(&eb, fences);
+ if (err)
+ goto err_request;
+ }
+
if (out_fence_fd != -1) {
out_fence = sync_file_create(&eb.request->fence);
if (!out_fence) {
@@ -2328,6 +2387,9 @@ err_request:
__i915_add_request(eb.request, err == 0);
add_to_client(eb.request, file);
+ if (fences)
+ signal_fence_array(&eb, fences);
+
if (out_fence) {
if (err == 0) {
fd_install(out_fence_fd, out_fence->file);
@@ -2345,11 +2407,11 @@ err_batch_unpin:
err_vma:
if (eb.exec)
eb_release_vmas(&eb);
- i915_gem_context_put(eb.ctx);
-err_unlock:
mutex_unlock(&dev->struct_mutex);
err_rpm:
intel_runtime_pm_put(eb.i915);
+ i915_gem_context_put(eb.ctx);
+err_destroy:
eb_destroy(&eb);
err_out_fence:
if (out_fence_fd != -1)
@@ -2367,7 +2429,9 @@ int
i915_gem_execbuffer(struct drm_device *dev, void *data,
struct drm_file *file)
{
- const size_t sz = sizeof(struct drm_i915_gem_exec_object2);
+ const size_t sz = (sizeof(struct drm_i915_gem_exec_object2) +
+ sizeof(struct i915_vma *) +
+ sizeof(unsigned int));
struct drm_i915_gem_execbuffer *args = data;
struct drm_i915_gem_execbuffer2 exec2;
struct drm_i915_gem_exec_object *exec_list = NULL;
@@ -2429,7 +2493,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
exec2_list[i].flags = 0;
}
- err = i915_gem_do_execbuffer(dev, file, &exec2, exec2_list);
+ err = i915_gem_do_execbuffer(dev, file, &exec2, exec2_list, NULL);
if (exec2.flags & __EXEC_HAS_RELOC) {
struct drm_i915_gem_exec_object __user *user_exec_list =
u64_to_user_ptr(args->buffers_ptr);
@@ -2458,9 +2522,12 @@ int
i915_gem_execbuffer2(struct drm_device *dev, void *data,
struct drm_file *file)
{
- const size_t sz = sizeof(struct drm_i915_gem_exec_object2);
+ const size_t sz = (sizeof(struct drm_i915_gem_exec_object2) +
+ sizeof(struct i915_vma *) +
+ sizeof(unsigned int));
struct drm_i915_gem_execbuffer2 *args = data;
struct drm_i915_gem_exec_object2 *exec2_list;
+ struct drm_syncobj **fences = NULL;
int err;
if (args->buffer_count < 1 || args->buffer_count > SIZE_MAX / sz - 1) {
@@ -2487,7 +2554,15 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,
return -EFAULT;
}
- err = i915_gem_do_execbuffer(dev, file, args, exec2_list);
+ if (args->flags & I915_EXEC_FENCE_ARRAY) {
+ fences = get_fence_array(args, file);
+ if (IS_ERR(fences)) {
+ kvfree(exec2_list);
+ return PTR_ERR(fences);
+ }
+ }
+
+ err = i915_gem_do_execbuffer(dev, file, args, exec2_list, fences);
/*
* Now that we have begun execution of the batchbuffer, we ignore
@@ -2517,6 +2592,7 @@ end_user:
}
args->flags &= ~__I915_EXEC_UNKNOWN_FLAGS;
+ put_fence_array(args, fences);
kvfree(exec2_list);
return err;
}
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 61fc7e9..d60f38a 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -144,9 +144,9 @@ int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv,
has_full_48bit_ppgtt = dev_priv->info.has_full_48bit_ppgtt;
if (intel_vgpu_active(dev_priv)) {
- /* emulation is too hard */
+ /* GVT-g has no support for 32bit ppgtt */
has_full_ppgtt = false;
- has_full_48bit_ppgtt = false;
+ has_full_48bit_ppgtt = intel_vgpu_has_full_48bit_ppgtt(dev_priv);
}
if (!has_aliasing_ppgtt)
@@ -180,10 +180,15 @@ int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv,
return 0;
}
- if (INTEL_GEN(dev_priv) >= 8 && i915.enable_execlists && has_full_ppgtt)
- return has_full_48bit_ppgtt ? 3 : 2;
- else
- return has_aliasing_ppgtt ? 1 : 0;
+ if (INTEL_GEN(dev_priv) >= 8 && i915.enable_execlists) {
+ if (has_full_48bit_ppgtt)
+ return 3;
+
+ if (has_full_ppgtt)
+ return 2;
+ }
+
+ return has_aliasing_ppgtt ? 1 : 0;
}
static int ppgtt_bind_vma(struct i915_vma *vma,
@@ -207,8 +212,7 @@ static int ppgtt_bind_vma(struct i915_vma *vma,
if (vma->obj->gt_ro)
pte_flags |= PTE_READ_ONLY;
- vma->vm->insert_entries(vma->vm, vma->pages, vma->node.start,
- cache_level, pte_flags);
+ vma->vm->insert_entries(vma->vm, vma, cache_level, pte_flags);
return 0;
}
@@ -907,37 +911,35 @@ gen8_ppgtt_insert_pte_entries(struct i915_hw_ppgtt *ppgtt,
}
static void gen8_ppgtt_insert_3lvl(struct i915_address_space *vm,
- struct sg_table *pages,
- u64 start,
+ struct i915_vma *vma,
enum i915_cache_level cache_level,
u32 unused)
{
struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
struct sgt_dma iter = {
- .sg = pages->sgl,
+ .sg = vma->pages->sgl,
.dma = sg_dma_address(iter.sg),
.max = iter.dma + iter.sg->length,
};
- struct gen8_insert_pte idx = gen8_insert_pte(start);
+ struct gen8_insert_pte idx = gen8_insert_pte(vma->node.start);
gen8_ppgtt_insert_pte_entries(ppgtt, &ppgtt->pdp, &iter, &idx,
cache_level);
}
static void gen8_ppgtt_insert_4lvl(struct i915_address_space *vm,
- struct sg_table *pages,
- u64 start,
+ struct i915_vma *vma,
enum i915_cache_level cache_level,
u32 unused)
{
struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
struct sgt_dma iter = {
- .sg = pages->sgl,
+ .sg = vma->pages->sgl,
.dma = sg_dma_address(iter.sg),
.max = iter.dma + iter.sg->length,
};
struct i915_page_directory_pointer **pdps = ppgtt->pml4.pdps;
- struct gen8_insert_pte idx = gen8_insert_pte(start);
+ struct gen8_insert_pte idx = gen8_insert_pte(vma->node.start);
while (gen8_ppgtt_insert_pte_entries(ppgtt, pdps[idx.pml4e++], &iter,
&idx, cache_level))
@@ -1621,13 +1623,12 @@ static void gen6_ppgtt_clear_range(struct i915_address_space *vm,
}
static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
- struct sg_table *pages,
- u64 start,
+ struct i915_vma *vma,
enum i915_cache_level cache_level,
u32 flags)
{
struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
- unsigned first_entry = start >> PAGE_SHIFT;
+ unsigned first_entry = vma->node.start >> PAGE_SHIFT;
unsigned act_pt = first_entry / GEN6_PTES;
unsigned act_pte = first_entry % GEN6_PTES;
const u32 pte_encode = vm->pte_encode(0, cache_level, flags);
@@ -1635,7 +1636,7 @@ static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
gen6_pte_t *vaddr;
vaddr = kmap_atomic_px(ppgtt->pd.page_table[act_pt]);
- iter.sg = pages->sgl;
+ iter.sg = vma->pages->sgl;
iter.dma = sg_dma_address(iter.sg);
iter.max = iter.dma + iter.sg->length;
do {
@@ -2090,8 +2091,7 @@ static void gen8_ggtt_insert_page(struct i915_address_space *vm,
}
static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
- struct sg_table *st,
- u64 start,
+ struct i915_vma *vma,
enum i915_cache_level level,
u32 unused)
{
@@ -2102,8 +2102,8 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
dma_addr_t addr;
gtt_entries = (gen8_pte_t __iomem *)ggtt->gsm;
- gtt_entries += start >> PAGE_SHIFT;
- for_each_sgt_dma(addr, sgt_iter, st)
+ gtt_entries += vma->node.start >> PAGE_SHIFT;
+ for_each_sgt_dma(addr, sgt_iter, vma->pages)
gen8_set_pte(gtt_entries++, pte_encode | addr);
wmb();
@@ -2137,17 +2137,16 @@ static void gen6_ggtt_insert_page(struct i915_address_space *vm,
* mapped BAR (dev_priv->mm.gtt->gtt).
*/
static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
- struct sg_table *st,
- u64 start,
+ struct i915_vma *vma,
enum i915_cache_level level,
u32 flags)
{
struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
gen6_pte_t __iomem *entries = (gen6_pte_t __iomem *)ggtt->gsm;
- unsigned int i = start >> PAGE_SHIFT;
+ unsigned int i = vma->node.start >> PAGE_SHIFT;
struct sgt_iter iter;
dma_addr_t addr;
- for_each_sgt_dma(addr, iter, st)
+ for_each_sgt_dma(addr, iter, vma->pages)
iowrite32(vm->pte_encode(addr, level, flags), &entries[i++]);
wmb();
@@ -2229,8 +2228,7 @@ static void bxt_vtd_ggtt_insert_page__BKL(struct i915_address_space *vm,
struct insert_entries {
struct i915_address_space *vm;
- struct sg_table *st;
- u64 start;
+ struct i915_vma *vma;
enum i915_cache_level level;
};
@@ -2238,19 +2236,18 @@ static int bxt_vtd_ggtt_insert_entries__cb(void *_arg)
{
struct insert_entries *arg = _arg;
- gen8_ggtt_insert_entries(arg->vm, arg->st, arg->start, arg->level, 0);
+ gen8_ggtt_insert_entries(arg->vm, arg->vma, arg->level, 0);
bxt_vtd_ggtt_wa(arg->vm);
return 0;
}
static void bxt_vtd_ggtt_insert_entries__BKL(struct i915_address_space *vm,
- struct sg_table *st,
- u64 start,
+ struct i915_vma *vma,
enum i915_cache_level level,
u32 unused)
{
- struct insert_entries arg = { vm, st, start, level };
+ struct insert_entries arg = { vm, vma, level };
stop_machine(bxt_vtd_ggtt_insert_entries__cb, &arg, NULL);
}
@@ -2316,15 +2313,15 @@ static void i915_ggtt_insert_page(struct i915_address_space *vm,
}
static void i915_ggtt_insert_entries(struct i915_address_space *vm,
- struct sg_table *pages,
- u64 start,
+ struct i915_vma *vma,
enum i915_cache_level cache_level,
u32 unused)
{
unsigned int flags = (cache_level == I915_CACHE_NONE) ?
AGP_USER_MEMORY : AGP_USER_CACHED_MEMORY;
- intel_gtt_insert_sg_entries(pages, start >> PAGE_SHIFT, flags);
+ intel_gtt_insert_sg_entries(vma->pages, vma->node.start >> PAGE_SHIFT,
+ flags);
}
static void i915_ggtt_clear_range(struct i915_address_space *vm,
@@ -2353,8 +2350,7 @@ static int ggtt_bind_vma(struct i915_vma *vma,
pte_flags |= PTE_READ_ONLY;
intel_runtime_pm_get(i915);
- vma->vm->insert_entries(vma->vm, vma->pages, vma->node.start,
- cache_level, pte_flags);
+ vma->vm->insert_entries(vma->vm, vma, cache_level, pte_flags);
intel_runtime_pm_put(i915);
/*
@@ -2407,16 +2403,13 @@ static int aliasing_gtt_bind_vma(struct i915_vma *vma,
goto err_pages;
}
- appgtt->base.insert_entries(&appgtt->base,
- vma->pages, vma->node.start,
- cache_level, pte_flags);
+ appgtt->base.insert_entries(&appgtt->base, vma, cache_level,
+ pte_flags);
}
if (flags & I915_VMA_GLOBAL_BIND) {
intel_runtime_pm_get(i915);
- vma->vm->insert_entries(vma->vm,
- vma->pages, vma->node.start,
- cache_level, pte_flags);
+ vma->vm->insert_entries(vma->vm, vma, cache_level, pte_flags);
intel_runtime_pm_put(i915);
}
@@ -2749,6 +2742,24 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, u64 size)
return 0;
}
+static void cnl_setup_private_ppat(struct drm_i915_private *dev_priv)
+{
+ /* XXX: spec is unclear if this is still needed for CNL+ */
+ if (!USES_PPGTT(dev_priv)) {
+ I915_WRITE(GEN10_PAT_INDEX(0), GEN8_PPAT_UC);
+ return;
+ }
+
+ I915_WRITE(GEN10_PAT_INDEX(0), GEN8_PPAT_WB | GEN8_PPAT_LLC);
+ I915_WRITE(GEN10_PAT_INDEX(1), GEN8_PPAT_WC | GEN8_PPAT_LLCELLC);
+ I915_WRITE(GEN10_PAT_INDEX(2), GEN8_PPAT_WT | GEN8_PPAT_LLCELLC);
+ I915_WRITE(GEN10_PAT_INDEX(3), GEN8_PPAT_UC);
+ I915_WRITE(GEN10_PAT_INDEX(4), GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(0));
+ I915_WRITE(GEN10_PAT_INDEX(5), GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(1));
+ I915_WRITE(GEN10_PAT_INDEX(6), GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(2));
+ I915_WRITE(GEN10_PAT_INDEX(7), GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(3));
+}
+
/* The GGTT and PPGTT need a private PPAT setup in order to handle cacheability
* bits. When using advanced contexts each context stores its own PAT, but
* writing this data shouldn't be harmful even in those cases. */
@@ -2863,7 +2874,9 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
ggtt->base.total = (size / sizeof(gen8_pte_t)) << PAGE_SHIFT;
- if (IS_CHERRYVIEW(dev_priv) || IS_GEN9_LP(dev_priv))
+ if (INTEL_GEN(dev_priv) >= 10)
+ cnl_setup_private_ppat(dev_priv);
+ else if (IS_CHERRYVIEW(dev_priv) || IS_GEN9_LP(dev_priv))
chv_setup_private_ppat(dev_priv);
else
bdw_setup_private_ppat(dev_priv);
@@ -3145,7 +3158,9 @@ void i915_gem_restore_gtt_mappings(struct drm_i915_private *dev_priv)
ggtt->base.closed = false;
if (INTEL_GEN(dev_priv) >= 8) {
- if (IS_CHERRYVIEW(dev_priv) || IS_GEN9_LP(dev_priv))
+ if (INTEL_GEN(dev_priv) >= 10)
+ cnl_setup_private_ppat(dev_priv);
+ else if (IS_CHERRYVIEW(dev_priv) || IS_GEN9_LP(dev_priv))
chv_setup_private_ppat(dev_priv);
else
bdw_setup_private_ppat(dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 1b2a56c..b4e3aa7 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -313,8 +313,7 @@ struct i915_address_space {
enum i915_cache_level cache_level,
u32 flags);
void (*insert_entries)(struct i915_address_space *vm,
- struct sg_table *st,
- u64 start,
+ struct i915_vma *vma,
enum i915_cache_level cache_level,
u32 flags);
void (*cleanup)(struct i915_address_space *vm);
diff --git a/drivers/gpu/drm/i915/i915_gem_internal.c b/drivers/gpu/drm/i915/i915_gem_internal.c
index 568bf83..c1f64dd 100644
--- a/drivers/gpu/drm/i915/i915_gem_internal.c
+++ b/drivers/gpu/drm/i915/i915_gem_internal.c
@@ -174,6 +174,7 @@ i915_gem_object_create_internal(struct drm_i915_private *i915,
phys_addr_t size)
{
struct drm_i915_gem_object *obj;
+ unsigned int cache_level;
GEM_BUG_ON(!size);
GEM_BUG_ON(!IS_ALIGNED(size, PAGE_SIZE));
@@ -190,9 +191,9 @@ i915_gem_object_create_internal(struct drm_i915_private *i915,
obj->base.read_domains = I915_GEM_DOMAIN_CPU;
obj->base.write_domain = I915_GEM_DOMAIN_CPU;
- obj->cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE;
- obj->cache_coherent = i915_gem_object_is_coherent(obj);
- obj->cache_dirty = !obj->cache_coherent;
+
+ cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE;
+ i915_gem_object_set_cache_coherency(obj, cache_level);
return obj;
}
diff --git a/drivers/gpu/drm/i915/i915_gem_object.c b/drivers/gpu/drm/i915/i915_gem_object.c
new file mode 100644
index 0000000..aab8cdd
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_gem_object.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "i915_drv.h"
+#include "i915_gem_object.h"
+
+/**
+ * Mark up the object's coherency levels for a given cache_level
+ * @obj: #drm_i915_gem_object
+ * @cache_level: cache level
+ */
+void i915_gem_object_set_cache_coherency(struct drm_i915_gem_object *obj,
+ unsigned int cache_level)
+{
+ obj->cache_level = cache_level;
+
+ if (cache_level != I915_CACHE_NONE)
+ obj->cache_coherent = (I915_BO_CACHE_COHERENT_FOR_READ |
+ I915_BO_CACHE_COHERENT_FOR_WRITE);
+ else if (HAS_LLC(to_i915(obj->base.dev)))
+ obj->cache_coherent = I915_BO_CACHE_COHERENT_FOR_READ;
+ else
+ obj->cache_coherent = 0;
+
+ obj->cache_dirty =
+ !(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE);
+}
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
index 5b19a49..c30d8f8 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -33,8 +33,24 @@
#include <drm/i915_drm.h>
+#include "i915_gem_request.h"
#include "i915_selftest.h"
+struct drm_i915_gem_object;
+
+/*
+ * struct i915_lut_handle tracks the fast lookups from handle to vma used
+ * for execbuf. Although we use a radixtree for that mapping, in order to
+ * remove them as the object or context is closed, we need a secondary list
+ * and a translation entry (i915_lut_handle).
+ */
+struct i915_lut_handle {
+ struct list_head obj_link;
+ struct list_head ctx_link;
+ struct i915_gem_context *ctx;
+ u32 handle;
+};
+
struct drm_i915_gem_object_ops {
unsigned int flags;
#define I915_GEM_OBJECT_HAS_STRUCT_PAGE BIT(0)
@@ -86,7 +102,15 @@ struct drm_i915_gem_object {
* They are also added to @vma_list for easy iteration.
*/
struct rb_root vma_tree;
- struct i915_vma *vma_hashed;
+
+ /**
+ * @lut_list: List of vma lookup entries in use for this object.
+ *
+ * If this object is closed, we need to remove all of its VMA from
+ * the fast lookup index in associated contexts; @lut_list provides
+ * this translation from object to context->handles_vma.
+ */
+ struct list_head lut_list;
/** Stolen memory for this object, instead of being backed by shmem. */
struct drm_mm_node *stolen;
@@ -118,8 +142,10 @@ struct drm_i915_gem_object {
*/
unsigned long gt_ro:1;
unsigned int cache_level:3;
+ unsigned int cache_coherent:2;
+#define I915_BO_CACHE_COHERENT_FOR_READ BIT(0)
+#define I915_BO_CACHE_COHERENT_FOR_WRITE BIT(1)
unsigned int cache_dirty:1;
- unsigned int cache_coherent:1;
atomic_t frontbuffer_bits;
unsigned int frontbuffer_ggtt_origin; /* write once */
@@ -391,6 +417,8 @@ i915_gem_object_last_write_engine(struct drm_i915_gem_object *obj)
return engine;
}
+void i915_gem_object_set_cache_coherency(struct drm_i915_gem_object *obj,
+ unsigned int cache_level);
void i915_gem_object_flush_if_display(struct drm_i915_gem_object *obj);
#endif
diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index 8c59c79..813a3b5 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -213,6 +213,10 @@ static int reset_all_global_seqno(struct drm_i915_private *i915, u32 seqno)
cond_resched();
}
+ /* Check we are idle before we fiddle with hw state! */
+ GEM_BUG_ON(!intel_engine_is_idle(engine));
+ GEM_BUG_ON(i915_gem_active_isset(&engine->timeline->last_request));
+
/* Finally reset hw state */
intel_engine_init_global_seqno(engine, seqno);
tl->seqno = seqno;
@@ -240,27 +244,60 @@ int i915_gem_set_global_seqno(struct drm_device *dev, u32 seqno)
return reset_all_global_seqno(dev_priv, seqno - 1);
}
-static int reserve_seqno(struct intel_engine_cs *engine)
+static void mark_busy(struct drm_i915_private *i915)
{
+ if (i915->gt.awake)
+ return;
+
+ GEM_BUG_ON(!i915->gt.active_requests);
+
+ intel_runtime_pm_get_noresume(i915);
+ i915->gt.awake = true;
+
+ intel_enable_gt_powersave(i915);
+ i915_update_gfx_val(i915);
+ if (INTEL_GEN(i915) >= 6)
+ gen6_rps_busy(i915);
+
+ queue_delayed_work(i915->wq,
+ &i915->gt.retire_work,
+ round_jiffies_up_relative(HZ));
+}
+
+static int reserve_engine(struct intel_engine_cs *engine)
+{
+ struct drm_i915_private *i915 = engine->i915;
u32 active = ++engine->timeline->inflight_seqnos;
u32 seqno = engine->timeline->seqno;
int ret;
/* Reservation is fine until we need to wrap around */
- if (likely(!add_overflows(seqno, active)))
- return 0;
-
- ret = reset_all_global_seqno(engine->i915, 0);
- if (ret) {
- engine->timeline->inflight_seqnos--;
- return ret;
+ if (unlikely(add_overflows(seqno, active))) {
+ ret = reset_all_global_seqno(i915, 0);
+ if (ret) {
+ engine->timeline->inflight_seqnos--;
+ return ret;
+ }
}
+ if (!i915->gt.active_requests++)
+ mark_busy(i915);
+
return 0;
}
-static void unreserve_seqno(struct intel_engine_cs *engine)
+static void unreserve_engine(struct intel_engine_cs *engine)
{
+ struct drm_i915_private *i915 = engine->i915;
+
+ if (!--i915->gt.active_requests) {
+ /* Cancel the mark_busy() from our reserve_engine() */
+ GEM_BUG_ON(!i915->gt.awake);
+ mod_delayed_work(i915->wq,
+ &i915->gt.idle_work,
+ msecs_to_jiffies(100));
+ }
+
GEM_BUG_ON(!engine->timeline->inflight_seqnos);
engine->timeline->inflight_seqnos--;
}
@@ -329,13 +366,7 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request)
list_del_init(&request->link);
spin_unlock_irq(&engine->timeline->lock);
- if (!--request->i915->gt.active_requests) {
- GEM_BUG_ON(!request->i915->gt.awake);
- mod_delayed_work(request->i915->wq,
- &request->i915->gt.idle_work,
- msecs_to_jiffies(100));
- }
- unreserve_seqno(request->engine);
+ unreserve_engine(request->engine);
advance_ring(request);
free_capture_list(request);
@@ -370,8 +401,7 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request)
i915_gem_request_remove_from_client(request);
/* Retirement decays the ban score as it is a sign of ctx progress */
- if (request->ctx->ban_score > 0)
- request->ctx->ban_score--;
+ atomic_dec_if_positive(&request->ctx->ban_score);
/* The backing object for the context is done after switching to the
* *next* context. Therefore we cannot retire the previous context until
@@ -384,7 +414,11 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request)
engine->context_unpin(engine, engine->last_retired_context);
engine->last_retired_context = request->ctx;
- dma_fence_signal(&request->fence);
+ spin_lock_irq(&request->lock);
+ if (request->waitboost)
+ atomic_dec(&request->i915->rps.num_waiters);
+ dma_fence_signal_locked(&request->fence);
+ spin_unlock_irq(&request->lock);
i915_priotree_fini(request->i915, &request->priotree);
i915_gem_request_put(request);
@@ -568,7 +602,7 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
return ERR_CAST(ring);
GEM_BUG_ON(!ring);
- ret = reserve_seqno(engine);
+ ret = reserve_engine(engine);
if (ret)
goto err_unpin;
@@ -639,6 +673,7 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
req->file_priv = NULL;
req->batch = NULL;
req->capture_list = NULL;
+ req->waitboost = false;
/*
* Reserve space in the ring buffer for all the commands required to
@@ -673,7 +708,7 @@ err_ctx:
kmem_cache_free(dev_priv->requests, req);
err_unreserve:
- unreserve_seqno(engine);
+ unreserve_engine(engine);
err_unpin:
engine->context_unpin(engine, ctx);
return ERR_PTR(ret);
@@ -855,28 +890,6 @@ i915_gem_request_await_object(struct drm_i915_gem_request *to,
return ret;
}
-static void i915_gem_mark_busy(const struct intel_engine_cs *engine)
-{
- struct drm_i915_private *dev_priv = engine->i915;
-
- if (dev_priv->gt.awake)
- return;
-
- GEM_BUG_ON(!dev_priv->gt.active_requests);
-
- intel_runtime_pm_get_noresume(dev_priv);
- dev_priv->gt.awake = true;
-
- intel_enable_gt_powersave(dev_priv);
- i915_update_gfx_val(dev_priv);
- if (INTEL_GEN(dev_priv) >= 6)
- gen6_rps_busy(dev_priv);
-
- queue_delayed_work(dev_priv->wq,
- &dev_priv->gt.retire_work,
- round_jiffies_up_relative(HZ));
-}
-
/*
* NB: This function is not allowed to fail. Doing so would mean the the
* request is not being tracked for completion but the work itself is
@@ -958,9 +971,6 @@ void __i915_add_request(struct drm_i915_gem_request *request, bool flush_caches)
list_add_tail(&request->ring_link, &ring->request_list);
request->emitted_jiffies = jiffies;
- if (!request->i915->gt.active_requests++)
- i915_gem_mark_busy(engine);
-
/* Let the backend know a new request has arrived that may need
* to adjust the existing execution schedule due to a high priority
* request - i.e. we may want to preempt the current request in order
@@ -1063,7 +1073,7 @@ static bool __i915_wait_request_check_and_reset(struct drm_i915_gem_request *req
return false;
__set_current_state(TASK_RUNNING);
- i915_reset(request->i915);
+ i915_reset(request->i915, 0);
return true;
}
diff --git a/drivers/gpu/drm/i915/i915_gem_request.h b/drivers/gpu/drm/i915/i915_gem_request.h
index 7579b97..49a4c89 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.h
+++ b/drivers/gpu/drm/i915/i915_gem_request.h
@@ -184,6 +184,8 @@ struct drm_i915_gem_request {
/** Time at which this request was emitted, in jiffies. */
unsigned long emitted_jiffies;
+ bool waitboost;
+
/** engine->request_list entry for this request */
struct list_head link;
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index a817b3e..507c9f0 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -254,9 +254,10 @@ static dma_addr_t i915_stolen_to_dma(struct drm_i915_private *dev_priv)
* This is a BIOS w/a: Some BIOS wrap stolen in the root
* PCI bus, but have an off-by-one error. Hence retry the
* reservation starting from 1 instead of 0.
+ * There's also BIOS with off-by-one on the other end.
*/
r = devm_request_mem_region(dev_priv->drm.dev, base + 1,
- ggtt->stolen_size - 1,
+ ggtt->stolen_size - 2,
"Graphics Stolen Memory");
/*
* GEN3 firmware likes to smash pci bridges into the stolen
@@ -579,6 +580,7 @@ _i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
struct drm_mm_node *stolen)
{
struct drm_i915_gem_object *obj;
+ unsigned int cache_level;
obj = i915_gem_object_alloc(dev_priv);
if (obj == NULL)
@@ -589,8 +591,8 @@ _i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
obj->stolen = stolen;
obj->base.read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT;
- obj->cache_level = HAS_LLC(dev_priv) ? I915_CACHE_LLC : I915_CACHE_NONE;
- obj->cache_coherent = true; /* assumptions! more like cache_oblivious */
+ cache_level = HAS_LLC(dev_priv) ? I915_CACHE_LLC : I915_CACHE_NONE;
+ i915_gem_object_set_cache_coherency(obj, cache_level);
if (i915_gem_object_pin_pages(obj))
goto cleanup;
diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c
index ccd09e8..f152a38 100644
--- a/drivers/gpu/drm/i915/i915_gem_userptr.c
+++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
@@ -804,9 +804,7 @@ i915_gem_userptr_ioctl(struct drm_device *dev, void *data, struct drm_file *file
i915_gem_object_init(obj, &i915_gem_userptr_ops);
obj->base.read_domains = I915_GEM_DOMAIN_CPU;
obj->base.write_domain = I915_GEM_DOMAIN_CPU;
- obj->cache_level = I915_CACHE_LLC;
- obj->cache_coherent = i915_gem_object_is_coherent(obj);
- obj->cache_dirty = !obj->cache_coherent;
+ i915_gem_object_set_cache_coherency(obj, I915_CACHE_LLC);
obj->userptr.ptr = args->user_ptr;
obj->userptr.read_only = !!(args->flags & I915_USERPTR_READ_ONLY);
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index e18f350..ed5a1eb 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -463,6 +463,7 @@ static void error_print_engine(struct drm_i915_error_state_buf *m,
err_printf(m, " hangcheck action timestamp: %lu, %u ms ago\n",
ee->hangcheck_timestamp,
jiffies_to_msecs(jiffies - ee->hangcheck_timestamp));
+ err_printf(m, " engine reset count: %u\n", ee->reset_count);
error_print_request(m, " ELSP[0]: ", &ee->execlist[0]);
error_print_request(m, " ELSP[1]: ", &ee->execlist[1]);
@@ -1236,6 +1237,8 @@ static void error_record_engine_registers(struct i915_gpu_state *error,
ee->hangcheck_timestamp = engine->hangcheck.action_timestamp;
ee->hangcheck_action = engine->hangcheck.action;
ee->hangcheck_stalled = engine->hangcheck.stalled;
+ ee->reset_count = i915_reset_engine_count(&dev_priv->gpu_error,
+ engine);
if (USES_PPGTT(dev_priv)) {
int i;
@@ -1263,7 +1266,7 @@ static void record_request(struct drm_i915_gem_request *request,
struct drm_i915_error_request *erq)
{
erq->context = request->ctx->hw_id;
- erq->ban_score = request->ctx->ban_score;
+ erq->ban_score = atomic_read(&request->ctx->ban_score);
erq->seqno = request->global_seqno;
erq->jiffies = request->emitted_jiffies;
erq->head = request->head;
@@ -1354,9 +1357,9 @@ static void record_context(struct drm_i915_error_context *e,
e->handle = ctx->user_handle;
e->hw_id = ctx->hw_id;
- e->ban_score = ctx->ban_score;
- e->guilty = ctx->guilty_count;
- e->active = ctx->active_count;
+ e->ban_score = atomic_read(&ctx->ban_score);
+ e->guilty = atomic_read(&ctx->guilty_count);
+ e->active = atomic_read(&ctx->active_count);
}
static void request_record_user_bo(struct drm_i915_gem_request *request,
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 4cd9ee1..e21ce9c 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -275,17 +275,17 @@ void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask)
static i915_reg_t gen6_pm_iir(struct drm_i915_private *dev_priv)
{
- return INTEL_INFO(dev_priv)->gen >= 8 ? GEN8_GT_IIR(2) : GEN6_PMIIR;
+ return INTEL_GEN(dev_priv) >= 8 ? GEN8_GT_IIR(2) : GEN6_PMIIR;
}
static i915_reg_t gen6_pm_imr(struct drm_i915_private *dev_priv)
{
- return INTEL_INFO(dev_priv)->gen >= 8 ? GEN8_GT_IMR(2) : GEN6_PMIMR;
+ return INTEL_GEN(dev_priv) >= 8 ? GEN8_GT_IMR(2) : GEN6_PMIMR;
}
static i915_reg_t gen6_pm_ier(struct drm_i915_private *dev_priv)
{
- return INTEL_INFO(dev_priv)->gen >= 8 ? GEN8_GT_IER(2) : GEN6_PMIER;
+ return INTEL_GEN(dev_priv) >= 8 ? GEN8_GT_IER(2) : GEN6_PMIER;
}
/**
@@ -1091,18 +1091,6 @@ static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir)
return events;
}
-static bool any_waiters(struct drm_i915_private *dev_priv)
-{
- struct intel_engine_cs *engine;
- enum intel_engine_id id;
-
- for_each_engine(engine, dev_priv, id)
- if (intel_engine_has_waiter(engine))
- return true;
-
- return false;
-}
-
static void gen6_pm_rps_work(struct work_struct *work)
{
struct drm_i915_private *dev_priv =
@@ -1114,7 +1102,7 @@ static void gen6_pm_rps_work(struct work_struct *work)
spin_lock_irq(&dev_priv->irq_lock);
if (dev_priv->rps.interrupts_enabled) {
pm_iir = fetch_and_zero(&dev_priv->rps.pm_iir);
- client_boost = fetch_and_zero(&dev_priv->rps.client_boost);
+ client_boost = atomic_read(&dev_priv->rps.num_waiters);
}
spin_unlock_irq(&dev_priv->irq_lock);
@@ -1131,7 +1119,7 @@ static void gen6_pm_rps_work(struct work_struct *work)
new_delay = dev_priv->rps.cur_freq;
min = dev_priv->rps.min_freq_softlimit;
max = dev_priv->rps.max_freq_softlimit;
- if (client_boost || any_waiters(dev_priv))
+ if (client_boost)
max = dev_priv->rps.max_freq;
if (client_boost && new_delay < dev_priv->rps.boost_freq) {
new_delay = dev_priv->rps.boost_freq;
@@ -1144,7 +1132,7 @@ static void gen6_pm_rps_work(struct work_struct *work)
if (new_delay >= dev_priv->rps.max_freq_softlimit)
adj = 0;
- } else if (client_boost || any_waiters(dev_priv)) {
+ } else if (client_boost) {
adj = 0;
} else if (pm_iir & GEN6_PM_RP_DOWN_TIMEOUT) {
if (dev_priv->rps.cur_freq > dev_priv->rps.efficient_freq)
@@ -1513,7 +1501,8 @@ static void intel_get_hpd_pins(u32 *pin_mask, u32 *long_mask,
*pin_mask |= BIT(i);
- if (!intel_hpd_pin_to_port(i, &port))
+ port = intel_hpd_pin_to_port(i);
+ if (port == PORT_NONE)
continue;
if (long_pulse_detect(port, dig_hotplug_reg))
@@ -1603,7 +1592,7 @@ static void display_pipe_crc_irq_handler(struct drm_i915_private *dev_priv,
crcs[3] = crc3;
crcs[4] = crc4;
drm_crtc_add_crc_entry(&crtc->base, true,
- drm_accurate_vblank_count(&crtc->base),
+ drm_crtc_accurate_vblank_count(&crtc->base),
crcs);
}
}
@@ -1673,7 +1662,7 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir)
spin_unlock(&dev_priv->irq_lock);
}
- if (INTEL_INFO(dev_priv)->gen >= 8)
+ if (INTEL_GEN(dev_priv) >= 8)
return;
if (HAS_VEBOX(dev_priv)) {
@@ -1720,18 +1709,6 @@ static void gen9_guc_irq_handler(struct drm_i915_private *dev_priv, u32 gt_iir)
}
}
-static bool intel_pipe_handle_vblank(struct drm_i915_private *dev_priv,
- enum pipe pipe)
-{
- bool ret;
-
- ret = drm_handle_vblank(&dev_priv->drm, pipe);
- if (ret)
- intel_finish_page_flip_mmio(dev_priv, pipe);
-
- return ret;
-}
-
static void valleyview_pipestat_irq_ack(struct drm_i915_private *dev_priv,
u32 iir, u32 pipe_stats[I915_MAX_PIPES])
{
@@ -1796,12 +1773,8 @@ static void valleyview_pipestat_irq_handler(struct drm_i915_private *dev_priv,
enum pipe pipe;
for_each_pipe(dev_priv, pipe) {
- if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS &&
- intel_pipe_handle_vblank(dev_priv, pipe))
- intel_check_page_flip(dev_priv, pipe);
-
- if (pipe_stats[pipe] & PLANE_FLIP_DONE_INT_STATUS_VLV)
- intel_finish_page_flip_cs(dev_priv, pipe);
+ if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS)
+ drm_handle_vblank(&dev_priv->drm, pipe);
if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
i9xx_pipe_crc_irq_handler(dev_priv, pipe);
@@ -2098,10 +2071,10 @@ static void ibx_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir)
DRM_DEBUG_DRIVER("PCH transcoder CRC error interrupt\n");
if (pch_iir & SDE_TRANSA_FIFO_UNDER)
- intel_pch_fifo_underrun_irq_handler(dev_priv, TRANSCODER_A);
+ intel_pch_fifo_underrun_irq_handler(dev_priv, PIPE_A);
if (pch_iir & SDE_TRANSB_FIFO_UNDER)
- intel_pch_fifo_underrun_irq_handler(dev_priv, TRANSCODER_B);
+ intel_pch_fifo_underrun_irq_handler(dev_priv, PIPE_B);
}
static void ivb_err_int_handler(struct drm_i915_private *dev_priv)
@@ -2135,13 +2108,13 @@ static void cpt_serr_int_handler(struct drm_i915_private *dev_priv)
DRM_ERROR("PCH poison interrupt\n");
if (serr_int & SERR_INT_TRANS_A_FIFO_UNDERRUN)
- intel_pch_fifo_underrun_irq_handler(dev_priv, TRANSCODER_A);
+ intel_pch_fifo_underrun_irq_handler(dev_priv, PIPE_A);
if (serr_int & SERR_INT_TRANS_B_FIFO_UNDERRUN)
- intel_pch_fifo_underrun_irq_handler(dev_priv, TRANSCODER_B);
+ intel_pch_fifo_underrun_irq_handler(dev_priv, PIPE_B);
if (serr_int & SERR_INT_TRANS_C_FIFO_UNDERRUN)
- intel_pch_fifo_underrun_irq_handler(dev_priv, TRANSCODER_C);
+ intel_pch_fifo_underrun_irq_handler(dev_priv, PIPE_C);
I915_WRITE(SERR_INT, serr_int);
}
@@ -2253,19 +2226,14 @@ static void ilk_display_irq_handler(struct drm_i915_private *dev_priv,
DRM_ERROR("Poison interrupt\n");
for_each_pipe(dev_priv, pipe) {
- if (de_iir & DE_PIPE_VBLANK(pipe) &&
- intel_pipe_handle_vblank(dev_priv, pipe))
- intel_check_page_flip(dev_priv, pipe);
+ if (de_iir & DE_PIPE_VBLANK(pipe))
+ drm_handle_vblank(&dev_priv->drm, pipe);
if (de_iir & DE_PIPE_FIFO_UNDERRUN(pipe))
intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe);
if (de_iir & DE_PIPE_CRC_DONE(pipe))
i9xx_pipe_crc_irq_handler(dev_priv, pipe);
-
- /* plane/pipes map 1:1 on ilk+ */
- if (de_iir & DE_PLANE_FLIP_DONE(pipe))
- intel_finish_page_flip_cs(dev_priv, pipe);
}
/* check event from PCH */
@@ -2304,13 +2272,8 @@ static void ivb_display_irq_handler(struct drm_i915_private *dev_priv,
intel_opregion_asle_intr(dev_priv);
for_each_pipe(dev_priv, pipe) {
- if (de_iir & (DE_PIPE_VBLANK_IVB(pipe)) &&
- intel_pipe_handle_vblank(dev_priv, pipe))
- intel_check_page_flip(dev_priv, pipe);
-
- /* plane/pipes map 1:1 on ilk+ */
- if (de_iir & DE_PLANE_FLIP_DONE_IVB(pipe))
- intel_finish_page_flip_cs(dev_priv, pipe);
+ if (de_iir & (DE_PIPE_VBLANK_IVB(pipe)))
+ drm_handle_vblank(&dev_priv->drm, pipe);
}
/* check event from PCH */
@@ -2452,7 +2415,7 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
ret = IRQ_HANDLED;
tmp_mask = GEN8_AUX_CHANNEL_A;
- if (INTEL_INFO(dev_priv)->gen >= 9)
+ if (INTEL_GEN(dev_priv) >= 9)
tmp_mask |= GEN9_AUX_CHANNEL_B |
GEN9_AUX_CHANNEL_C |
GEN9_AUX_CHANNEL_D;
@@ -2491,7 +2454,7 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
}
for_each_pipe(dev_priv, pipe) {
- u32 flip_done, fault_errors;
+ u32 fault_errors;
if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe)))
continue;
@@ -2505,18 +2468,8 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
ret = IRQ_HANDLED;
I915_WRITE(GEN8_DE_PIPE_IIR(pipe), iir);
- if (iir & GEN8_PIPE_VBLANK &&
- intel_pipe_handle_vblank(dev_priv, pipe))
- intel_check_page_flip(dev_priv, pipe);
-
- flip_done = iir;
- if (INTEL_INFO(dev_priv)->gen >= 9)
- flip_done &= GEN9_PIPE_PLANE1_FLIP_DONE;
- else
- flip_done &= GEN8_PIPE_PRIMARY_FLIP_DONE;
-
- if (flip_done)
- intel_finish_page_flip_cs(dev_priv, pipe);
+ if (iir & GEN8_PIPE_VBLANK)
+ drm_handle_vblank(&dev_priv->drm, pipe);
if (iir & GEN8_PIPE_CDCLK_CRC_DONE)
hsw_pipe_crc_irq_handler(dev_priv, pipe);
@@ -2525,7 +2478,7 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe);
fault_errors = iir;
- if (INTEL_INFO(dev_priv)->gen >= 9)
+ if (INTEL_GEN(dev_priv) >= 9)
fault_errors &= GEN9_DE_PIPE_IRQ_FAULT_ERRORS;
else
fault_errors &= GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
@@ -2599,86 +2552,93 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
return ret;
}
+struct wedge_me {
+ struct delayed_work work;
+ struct drm_i915_private *i915;
+ const char *name;
+};
+
+static void wedge_me(struct work_struct *work)
+{
+ struct wedge_me *w = container_of(work, typeof(*w), work.work);
+
+ dev_err(w->i915->drm.dev,
+ "%s timed out, cancelling all in-flight rendering.\n",
+ w->name);
+ i915_gem_set_wedged(w->i915);
+}
+
+static void __init_wedge(struct wedge_me *w,
+ struct drm_i915_private *i915,
+ long timeout,
+ const char *name)
+{
+ w->i915 = i915;
+ w->name = name;
+
+ INIT_DELAYED_WORK_ONSTACK(&w->work, wedge_me);
+ schedule_delayed_work(&w->work, timeout);
+}
+
+static void __fini_wedge(struct wedge_me *w)
+{
+ cancel_delayed_work_sync(&w->work);
+ destroy_delayed_work_on_stack(&w->work);
+ w->i915 = NULL;
+}
+
+#define i915_wedge_on_timeout(W, DEV, TIMEOUT) \
+ for (__init_wedge((W), (DEV), (TIMEOUT), __func__); \
+ (W)->i915; \
+ __fini_wedge((W)))
+
/**
- * i915_reset_and_wakeup - do process context error handling work
+ * i915_reset_device - do process context error handling work
* @dev_priv: i915 device private
*
* Fire an error uevent so userspace can see that a hang or error
* was detected.
*/
-static void i915_reset_and_wakeup(struct drm_i915_private *dev_priv)
+static void i915_reset_device(struct drm_i915_private *dev_priv)
{
struct kobject *kobj = &dev_priv->drm.primary->kdev->kobj;
char *error_event[] = { I915_ERROR_UEVENT "=1", NULL };
char *reset_event[] = { I915_RESET_UEVENT "=1", NULL };
char *reset_done_event[] = { I915_ERROR_UEVENT "=0", NULL };
+ struct wedge_me w;
kobject_uevent_env(kobj, KOBJ_CHANGE, error_event);
DRM_DEBUG_DRIVER("resetting chip\n");
kobject_uevent_env(kobj, KOBJ_CHANGE, reset_event);
- intel_prepare_reset(dev_priv);
+ /* Use a watchdog to ensure that our reset completes */
+ i915_wedge_on_timeout(&w, dev_priv, 5*HZ) {
+ intel_prepare_reset(dev_priv);
- set_bit(I915_RESET_HANDOFF, &dev_priv->gpu_error.flags);
- wake_up_all(&dev_priv->gpu_error.wait_queue);
+ /* Signal that locked waiters should reset the GPU */
+ set_bit(I915_RESET_HANDOFF, &dev_priv->gpu_error.flags);
+ wake_up_all(&dev_priv->gpu_error.wait_queue);
- do {
- /*
- * All state reset _must_ be completed before we update the
- * reset counter, for otherwise waiters might miss the reset
- * pending state and not properly drop locks, resulting in
- * deadlocks with the reset work.
+ /* Wait for anyone holding the lock to wakeup, without
+ * blocking indefinitely on struct_mutex.
*/
- if (mutex_trylock(&dev_priv->drm.struct_mutex)) {
- i915_reset(dev_priv);
- mutex_unlock(&dev_priv->drm.struct_mutex);
- }
-
- /* We need to wait for anyone holding the lock to wakeup */
- } while (wait_on_bit_timeout(&dev_priv->gpu_error.flags,
- I915_RESET_HANDOFF,
- TASK_UNINTERRUPTIBLE,
- HZ));
+ do {
+ if (mutex_trylock(&dev_priv->drm.struct_mutex)) {
+ i915_reset(dev_priv, 0);
+ mutex_unlock(&dev_priv->drm.struct_mutex);
+ }
+ } while (wait_on_bit_timeout(&dev_priv->gpu_error.flags,
+ I915_RESET_HANDOFF,
+ TASK_UNINTERRUPTIBLE,
+ 1));
- intel_finish_reset(dev_priv);
+ intel_finish_reset(dev_priv);
+ }
if (!test_bit(I915_WEDGED, &dev_priv->gpu_error.flags))
kobject_uevent_env(kobj,
KOBJ_CHANGE, reset_done_event);
-
- /*
- * Note: The wake_up also serves as a memory barrier so that
- * waiters see the updated value of the dev_priv->gpu_error.
- */
- clear_bit(I915_RESET_BACKOFF, &dev_priv->gpu_error.flags);
- wake_up_all(&dev_priv->gpu_error.reset_queue);
-}
-
-static inline void
-i915_err_print_instdone(struct drm_i915_private *dev_priv,
- struct intel_instdone *instdone)
-{
- int slice;
- int subslice;
-
- pr_err(" INSTDONE: 0x%08x\n", instdone->instdone);
-
- if (INTEL_GEN(dev_priv) <= 3)
- return;
-
- pr_err(" SC_INSTDONE: 0x%08x\n", instdone->slice_common);
-
- if (INTEL_GEN(dev_priv) <= 6)
- return;
-
- for_each_instdone_slice_subslice(dev_priv, slice, subslice)
- pr_err(" SAMPLER_INSTDONE[%d][%d]: 0x%08x\n",
- slice, subslice, instdone->sampler[slice][subslice]);
-
- for_each_instdone_slice_subslice(dev_priv, slice, subslice)
- pr_err(" ROW_INSTDONE[%d][%d]: 0x%08x\n",
- slice, subslice, instdone->row[slice][subslice]);
}
static void i915_clear_error_registers(struct drm_i915_private *dev_priv)
@@ -2722,6 +2682,8 @@ void i915_handle_error(struct drm_i915_private *dev_priv,
u32 engine_mask,
const char *fmt, ...)
{
+ struct intel_engine_cs *engine;
+ unsigned int tmp;
va_list args;
char error_msg[80];
@@ -2741,14 +2703,56 @@ void i915_handle_error(struct drm_i915_private *dev_priv,
i915_capture_error_state(dev_priv, engine_mask, error_msg);
i915_clear_error_registers(dev_priv);
+ /*
+ * Try engine reset when available. We fall back to full reset if
+ * single reset fails.
+ */
+ if (intel_has_reset_engine(dev_priv)) {
+ for_each_engine_masked(engine, dev_priv, engine_mask, tmp) {
+ BUILD_BUG_ON(I915_RESET_MODESET >= I915_RESET_ENGINE);
+ if (test_and_set_bit(I915_RESET_ENGINE + engine->id,
+ &dev_priv->gpu_error.flags))
+ continue;
+
+ if (i915_reset_engine(engine, 0) == 0)
+ engine_mask &= ~intel_engine_flag(engine);
+
+ clear_bit(I915_RESET_ENGINE + engine->id,
+ &dev_priv->gpu_error.flags);
+ wake_up_bit(&dev_priv->gpu_error.flags,
+ I915_RESET_ENGINE + engine->id);
+ }
+ }
+
if (!engine_mask)
goto out;
- if (test_and_set_bit(I915_RESET_BACKOFF,
- &dev_priv->gpu_error.flags))
+ /* Full reset needs the mutex, stop any other user trying to do so. */
+ if (test_and_set_bit(I915_RESET_BACKOFF, &dev_priv->gpu_error.flags)) {
+ wait_event(dev_priv->gpu_error.reset_queue,
+ !test_bit(I915_RESET_BACKOFF,
+ &dev_priv->gpu_error.flags));
goto out;
+ }
+
+ /* Prevent any other reset-engine attempt. */
+ for_each_engine(engine, dev_priv, tmp) {
+ while (test_and_set_bit(I915_RESET_ENGINE + engine->id,
+ &dev_priv->gpu_error.flags))
+ wait_on_bit(&dev_priv->gpu_error.flags,
+ I915_RESET_ENGINE + engine->id,
+ TASK_UNINTERRUPTIBLE);
+ }
+
+ i915_reset_device(dev_priv);
- i915_reset_and_wakeup(dev_priv);
+ for_each_engine(engine, dev_priv, tmp) {
+ clear_bit(I915_RESET_ENGINE + engine->id,
+ &dev_priv->gpu_error.flags);
+ }
+
+ clear_bit(I915_RESET_BACKOFF, &dev_priv->gpu_error.flags);
+ wake_up_all(&dev_priv->gpu_error.reset_queue);
out:
intel_runtime_pm_put(dev_priv);
@@ -3009,7 +3013,7 @@ static void gen8_irq_reset(struct drm_device *dev)
}
void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv,
- unsigned int pipe_mask)
+ u8 pipe_mask)
{
uint32_t extra_ier = GEN8_PIPE_VBLANK | GEN8_PIPE_FIFO_UNDERRUN;
enum pipe pipe;
@@ -3023,7 +3027,7 @@ void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv,
}
void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv,
- unsigned int pipe_mask)
+ u8 pipe_mask)
{
enum pipe pipe;
@@ -3427,7 +3431,7 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
u32 de_misc_masked = GEN8_DE_MISC_GSE;
enum pipe pipe;
- if (INTEL_INFO(dev_priv)->gen >= 9) {
+ if (INTEL_GEN(dev_priv) >= 9) {
de_pipe_masked |= GEN9_PIPE_PLANE1_FLIP_DONE |
GEN9_DE_PIPE_IRQ_FAULT_ERRORS;
de_port_masked |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C |
@@ -3610,34 +3614,6 @@ static int i8xx_irq_postinstall(struct drm_device *dev)
/*
* Returns true when a page flip has completed.
*/
-static bool i8xx_handle_vblank(struct drm_i915_private *dev_priv,
- int plane, int pipe, u32 iir)
-{
- u16 flip_pending = DISPLAY_PLANE_FLIP_PENDING(plane);
-
- if (!intel_pipe_handle_vblank(dev_priv, pipe))
- return false;
-
- if ((iir & flip_pending) == 0)
- goto check_page_flip;
-
- /* We detect FlipDone by looking for the change in PendingFlip from '1'
- * to '0' on the following vblank, i.e. IIR has the Pendingflip
- * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence
- * the flip is completed (no longer pending). Since this doesn't raise
- * an interrupt per se, we watch for the change at vblank.
- */
- if (I915_READ16(ISR) & flip_pending)
- goto check_page_flip;
-
- intel_finish_page_flip_cs(dev_priv, pipe);
- return true;
-
-check_page_flip:
- intel_check_page_flip(dev_priv, pipe);
- return false;
-}
-
static irqreturn_t i8xx_irq_handler(int irq, void *arg)
{
struct drm_device *dev = arg;
@@ -3645,9 +3621,6 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
u16 iir, new_iir;
u32 pipe_stats[2];
int pipe;
- u16 flip_mask =
- I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
- I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
irqreturn_t ret;
if (!intel_irqs_enabled(dev_priv))
@@ -3661,7 +3634,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
if (iir == 0)
goto out;
- while (iir & ~flip_mask) {
+ while (iir) {
/* Can't rely on pipestat interrupt bit in iir as it might
* have been cleared after the pipestat interrupt was received.
* It doesn't set the bit in iir again, but it still produces
@@ -3683,7 +3656,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
}
spin_unlock(&dev_priv->irq_lock);
- I915_WRITE16(IIR, iir & ~flip_mask);
+ I915_WRITE16(IIR, iir);
new_iir = I915_READ16(IIR); /* Flush posted writes */
if (iir & I915_USER_INTERRUPT)
@@ -3694,9 +3667,8 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
if (HAS_FBC(dev_priv))
plane = !plane;
- if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS &&
- i8xx_handle_vblank(dev_priv, plane, pipe, iir))
- flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(plane);
+ if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS)
+ drm_handle_vblank(&dev_priv->drm, pipe);
if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
i9xx_pipe_crc_irq_handler(dev_priv, pipe);
@@ -3796,45 +3768,11 @@ static int i915_irq_postinstall(struct drm_device *dev)
return 0;
}
-/*
- * Returns true when a page flip has completed.
- */
-static bool i915_handle_vblank(struct drm_i915_private *dev_priv,
- int plane, int pipe, u32 iir)
-{
- u32 flip_pending = DISPLAY_PLANE_FLIP_PENDING(plane);
-
- if (!intel_pipe_handle_vblank(dev_priv, pipe))
- return false;
-
- if ((iir & flip_pending) == 0)
- goto check_page_flip;
-
- /* We detect FlipDone by looking for the change in PendingFlip from '1'
- * to '0' on the following vblank, i.e. IIR has the Pendingflip
- * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence
- * the flip is completed (no longer pending). Since this doesn't raise
- * an interrupt per se, we watch for the change at vblank.
- */
- if (I915_READ(ISR) & flip_pending)
- goto check_page_flip;
-
- intel_finish_page_flip_cs(dev_priv, pipe);
- return true;
-
-check_page_flip:
- intel_check_page_flip(dev_priv, pipe);
- return false;
-}
-
static irqreturn_t i915_irq_handler(int irq, void *arg)
{
struct drm_device *dev = arg;
struct drm_i915_private *dev_priv = to_i915(dev);
u32 iir, new_iir, pipe_stats[I915_MAX_PIPES];
- u32 flip_mask =
- I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
- I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
int pipe, ret = IRQ_NONE;
if (!intel_irqs_enabled(dev_priv))
@@ -3845,7 +3783,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
iir = I915_READ(IIR);
do {
- bool irq_received = (iir & ~flip_mask) != 0;
+ bool irq_received = (iir) != 0;
bool blc_event = false;
/* Can't rely on pipestat interrupt bit in iir as it might
@@ -3880,7 +3818,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
i9xx_hpd_irq_handler(dev_priv, hotplug_status);
}
- I915_WRITE(IIR, iir & ~flip_mask);
+ I915_WRITE(IIR, iir);
new_iir = I915_READ(IIR); /* Flush posted writes */
if (iir & I915_USER_INTERRUPT)
@@ -3891,9 +3829,8 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
if (HAS_FBC(dev_priv))
plane = !plane;
- if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS &&
- i915_handle_vblank(dev_priv, plane, pipe, iir))
- flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(plane);
+ if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS)
+ drm_handle_vblank(&dev_priv->drm, pipe);
if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
blc_event = true;
@@ -3926,7 +3863,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
*/
ret = IRQ_HANDLED;
iir = new_iir;
- } while (iir & ~flip_mask);
+ } while (iir);
enable_rpm_wakeref_asserts(dev_priv);
@@ -4061,9 +3998,6 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
u32 iir, new_iir;
u32 pipe_stats[I915_MAX_PIPES];
int ret = IRQ_NONE, pipe;
- u32 flip_mask =
- I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
- I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
if (!intel_irqs_enabled(dev_priv))
return IRQ_NONE;
@@ -4074,7 +4008,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
iir = I915_READ(IIR);
for (;;) {
- bool irq_received = (iir & ~flip_mask) != 0;
+ bool irq_received = (iir) != 0;
bool blc_event = false;
/* Can't rely on pipestat interrupt bit in iir as it might
@@ -4112,7 +4046,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
i9xx_hpd_irq_handler(dev_priv, hotplug_status);
}
- I915_WRITE(IIR, iir & ~flip_mask);
+ I915_WRITE(IIR, iir);
new_iir = I915_READ(IIR); /* Flush posted writes */
if (iir & I915_USER_INTERRUPT)
@@ -4121,9 +4055,8 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
notify_ring(dev_priv->engine[VCS]);
for_each_pipe(dev_priv, pipe) {
- if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS &&
- i915_handle_vblank(dev_priv, pipe, pipe, iir))
- flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(pipe);
+ if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS)
+ drm_handle_vblank(&dev_priv->drm, pipe);
if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
blc_event = true;
@@ -4225,16 +4158,16 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
*
* TODO: verify if this can be reproduced on VLV,CHV.
*/
- if (INTEL_INFO(dev_priv)->gen <= 7)
+ if (INTEL_GEN(dev_priv) <= 7)
dev_priv->rps.pm_intrmsk_mbz |= GEN6_PM_RP_UP_EI_EXPIRED;
- if (INTEL_INFO(dev_priv)->gen >= 8)
+ if (INTEL_GEN(dev_priv) >= 8)
dev_priv->rps.pm_intrmsk_mbz |= GEN8_PMINTR_DISABLE_REDIRECT_TO_GUC;
if (IS_GEN2(dev_priv)) {
/* Gen2 doesn't have a hardware frame counter */
dev->max_vblank_count = 0;
- } else if (IS_G4X(dev_priv) || INTEL_INFO(dev_priv)->gen >= 5) {
+ } else if (IS_G4X(dev_priv) || INTEL_GEN(dev_priv) >= 5) {
dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */
dev->driver->get_vblank_counter = g4x_get_vblank_counter;
} else {
@@ -4281,7 +4214,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
dev->driver->enable_vblank = i965_enable_vblank;
dev->driver->disable_vblank = i965_disable_vblank;
dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup;
- } else if (INTEL_INFO(dev_priv)->gen >= 8) {
+ } else if (INTEL_GEN(dev_priv) >= 8) {
dev->driver->irq_handler = gen8_irq_handler;
dev->driver->irq_preinstall = gen8_irq_reset;
dev->driver->irq_postinstall = gen8_irq_postinstall;
diff --git a/drivers/gpu/drm/i915/i915_oa_bdw.c b/drivers/gpu/drm/i915/i915_oa_bdw.c
index d4462c2..abdf4d0 100644
--- a/drivers/gpu/drm/i915/i915_oa_bdw.c
+++ b/drivers/gpu/drm/i915/i915_oa_bdw.c
@@ -31,3981 +31,6 @@
#include "i915_drv.h"
#include "i915_oa_bdw.h"
-enum metric_set_id {
- METRIC_SET_ID_RENDER_BASIC = 1,
- METRIC_SET_ID_COMPUTE_BASIC,
- METRIC_SET_ID_RENDER_PIPE_PROFILE,
- METRIC_SET_ID_MEMORY_READS,
- METRIC_SET_ID_MEMORY_WRITES,
- METRIC_SET_ID_COMPUTE_EXTENDED,
- METRIC_SET_ID_COMPUTE_L3_CACHE,
- METRIC_SET_ID_DATA_PORT_READS_COALESCING,
- METRIC_SET_ID_DATA_PORT_WRITES_COALESCING,
- METRIC_SET_ID_HDC_AND_SF,
- METRIC_SET_ID_L3_1,
- METRIC_SET_ID_L3_2,
- METRIC_SET_ID_L3_3,
- METRIC_SET_ID_L3_4,
- METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND,
- METRIC_SET_ID_SAMPLER_1,
- METRIC_SET_ID_SAMPLER_2,
- METRIC_SET_ID_TDL_1,
- METRIC_SET_ID_TDL_2,
- METRIC_SET_ID_COMPUTE_EXTRA,
- METRIC_SET_ID_VME_PIPE,
- METRIC_SET_ID_TEST_OA,
-};
-
-int i915_oa_n_builtin_metric_sets_bdw = 22;
-
-static const struct i915_oa_reg b_counter_config_render_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_render_basic_0_slices_0x01[] = {
- { _MMIO(0x9888), 0x143f000f },
- { _MMIO(0x9888), 0x14110014 },
- { _MMIO(0x9888), 0x14310014 },
- { _MMIO(0x9888), 0x14bf000f },
- { _MMIO(0x9888), 0x118a0317 },
- { _MMIO(0x9888), 0x13837be0 },
- { _MMIO(0x9888), 0x3b800060 },
- { _MMIO(0x9888), 0x3d800005 },
- { _MMIO(0x9888), 0x005c4000 },
- { _MMIO(0x9888), 0x065c8000 },
- { _MMIO(0x9888), 0x085cc000 },
- { _MMIO(0x9888), 0x003d8000 },
- { _MMIO(0x9888), 0x183d0800 },
- { _MMIO(0x9888), 0x0a3f0023 },
- { _MMIO(0x9888), 0x103f0000 },
- { _MMIO(0x9888), 0x00584000 },
- { _MMIO(0x9888), 0x08584000 },
- { _MMIO(0x9888), 0x0a5a4000 },
- { _MMIO(0x9888), 0x005b4000 },
- { _MMIO(0x9888), 0x0e5b8000 },
- { _MMIO(0x9888), 0x185b2400 },
- { _MMIO(0x9888), 0x0a1d4000 },
- { _MMIO(0x9888), 0x0c1f0800 },
- { _MMIO(0x9888), 0x0e1faa00 },
- { _MMIO(0x9888), 0x00384000 },
- { _MMIO(0x9888), 0x0e384000 },
- { _MMIO(0x9888), 0x16384000 },
- { _MMIO(0x9888), 0x18380001 },
- { _MMIO(0x9888), 0x00392000 },
- { _MMIO(0x9888), 0x06398000 },
- { _MMIO(0x9888), 0x0839a000 },
- { _MMIO(0x9888), 0x0a391000 },
- { _MMIO(0x9888), 0x00104000 },
- { _MMIO(0x9888), 0x08104000 },
- { _MMIO(0x9888), 0x00110030 },
- { _MMIO(0x9888), 0x08110031 },
- { _MMIO(0x9888), 0x10110000 },
- { _MMIO(0x9888), 0x00134000 },
- { _MMIO(0x9888), 0x16130020 },
- { _MMIO(0x9888), 0x06308000 },
- { _MMIO(0x9888), 0x08308000 },
- { _MMIO(0x9888), 0x06311800 },
- { _MMIO(0x9888), 0x08311880 },
- { _MMIO(0x9888), 0x10310000 },
- { _MMIO(0x9888), 0x0e334000 },
- { _MMIO(0x9888), 0x16330080 },
- { _MMIO(0x9888), 0x0abf1180 },
- { _MMIO(0x9888), 0x10bf0000 },
- { _MMIO(0x9888), 0x0ada8000 },
- { _MMIO(0x9888), 0x0a9d8000 },
- { _MMIO(0x9888), 0x109f0002 },
- { _MMIO(0x9888), 0x0ab94000 },
- { _MMIO(0x9888), 0x0d888000 },
- { _MMIO(0x9888), 0x038a0380 },
- { _MMIO(0x9888), 0x058a000e },
- { _MMIO(0x9888), 0x018a8000 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x198a8000 },
- { _MMIO(0x9888), 0x1b8a00a0 },
- { _MMIO(0x9888), 0x078a0000 },
- { _MMIO(0x9888), 0x098a0000 },
- { _MMIO(0x9888), 0x238b2820 },
- { _MMIO(0x9888), 0x258b2550 },
- { _MMIO(0x9888), 0x198c1000 },
- { _MMIO(0x9888), 0x0b8d8000 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaa0 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x0d831021 },
- { _MMIO(0x9888), 0x0f83572f },
- { _MMIO(0x9888), 0x01835680 },
- { _MMIO(0x9888), 0x0383002c },
- { _MMIO(0x9888), 0x11830000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830001 },
- { _MMIO(0x9888), 0x05830000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x05844000 },
- { _MMIO(0x9888), 0x1b80c137 },
- { _MMIO(0x9888), 0x1d80c147 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x17808000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x15804000 },
- { _MMIO(0x9888), 0x4d801110 },
- { _MMIO(0x9888), 0x4f800331 },
- { _MMIO(0x9888), 0x43800802 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45801465 },
- { _MMIO(0x9888), 0x53801111 },
- { _MMIO(0x9888), 0x478014a5 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800ca5 },
- { _MMIO(0x9888), 0x41800003 },
-};
-
-static const struct i915_oa_reg mux_config_render_basic_1_slices_0x02[] = {
- { _MMIO(0x9888), 0x143f000f },
- { _MMIO(0x9888), 0x14bf000f },
- { _MMIO(0x9888), 0x14910014 },
- { _MMIO(0x9888), 0x14b10014 },
- { _MMIO(0x9888), 0x118a0317 },
- { _MMIO(0x9888), 0x13837be0 },
- { _MMIO(0x9888), 0x3b800060 },
- { _MMIO(0x9888), 0x3d800005 },
- { _MMIO(0x9888), 0x0a3f0023 },
- { _MMIO(0x9888), 0x103f0000 },
- { _MMIO(0x9888), 0x0a5a4000 },
- { _MMIO(0x9888), 0x0a1d4000 },
- { _MMIO(0x9888), 0x0e1f8000 },
- { _MMIO(0x9888), 0x0a391000 },
- { _MMIO(0x9888), 0x00dc4000 },
- { _MMIO(0x9888), 0x06dc8000 },
- { _MMIO(0x9888), 0x08dcc000 },
- { _MMIO(0x9888), 0x00bd8000 },
- { _MMIO(0x9888), 0x18bd0800 },
- { _MMIO(0x9888), 0x0abf1180 },
- { _MMIO(0x9888), 0x10bf0000 },
- { _MMIO(0x9888), 0x00d84000 },
- { _MMIO(0x9888), 0x08d84000 },
- { _MMIO(0x9888), 0x0ada8000 },
- { _MMIO(0x9888), 0x00db4000 },
- { _MMIO(0x9888), 0x0edb8000 },
- { _MMIO(0x9888), 0x18db2400 },
- { _MMIO(0x9888), 0x0a9d8000 },
- { _MMIO(0x9888), 0x0c9f0800 },
- { _MMIO(0x9888), 0x0e9f2a00 },
- { _MMIO(0x9888), 0x109f0002 },
- { _MMIO(0x9888), 0x00b84000 },
- { _MMIO(0x9888), 0x0eb84000 },
- { _MMIO(0x9888), 0x16b84000 },
- { _MMIO(0x9888), 0x18b80001 },
- { _MMIO(0x9888), 0x00b92000 },
- { _MMIO(0x9888), 0x06b98000 },
- { _MMIO(0x9888), 0x08b9a000 },
- { _MMIO(0x9888), 0x0ab94000 },
- { _MMIO(0x9888), 0x00904000 },
- { _MMIO(0x9888), 0x08904000 },
- { _MMIO(0x9888), 0x00910030 },
- { _MMIO(0x9888), 0x08910031 },
- { _MMIO(0x9888), 0x10910000 },
- { _MMIO(0x9888), 0x00934000 },
- { _MMIO(0x9888), 0x16930020 },
- { _MMIO(0x9888), 0x06b08000 },
- { _MMIO(0x9888), 0x08b08000 },
- { _MMIO(0x9888), 0x06b11800 },
- { _MMIO(0x9888), 0x08b11880 },
- { _MMIO(0x9888), 0x10b10000 },
- { _MMIO(0x9888), 0x0eb34000 },
- { _MMIO(0x9888), 0x16b30080 },
- { _MMIO(0x9888), 0x01888000 },
- { _MMIO(0x9888), 0x0d88b800 },
- { _MMIO(0x9888), 0x038a0380 },
- { _MMIO(0x9888), 0x058a000e },
- { _MMIO(0x9888), 0x1b8a0080 },
- { _MMIO(0x9888), 0x078a0000 },
- { _MMIO(0x9888), 0x098a0000 },
- { _MMIO(0x9888), 0x238b2840 },
- { _MMIO(0x9888), 0x258b26a0 },
- { _MMIO(0x9888), 0x018c4000 },
- { _MMIO(0x9888), 0x0f8c4000 },
- { _MMIO(0x9888), 0x178c2000 },
- { _MMIO(0x9888), 0x198c1100 },
- { _MMIO(0x9888), 0x018d2000 },
- { _MMIO(0x9888), 0x078d8000 },
- { _MMIO(0x9888), 0x098da000 },
- { _MMIO(0x9888), 0x0b8d8000 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaa0 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x0d831021 },
- { _MMIO(0x9888), 0x0f83572f },
- { _MMIO(0x9888), 0x01835680 },
- { _MMIO(0x9888), 0x0383002c },
- { _MMIO(0x9888), 0x11830000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830001 },
- { _MMIO(0x9888), 0x05830000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x05844000 },
- { _MMIO(0x9888), 0x1b80c137 },
- { _MMIO(0x9888), 0x1d80c147 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x17808000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x15804000 },
- { _MMIO(0x9888), 0x4d801550 },
- { _MMIO(0x9888), 0x4f800331 },
- { _MMIO(0x9888), 0x43800802 },
- { _MMIO(0x9888), 0x51800400 },
- { _MMIO(0x9888), 0x458004a1 },
- { _MMIO(0x9888), 0x53805555 },
- { _MMIO(0x9888), 0x47800421 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f801421 },
- { _MMIO(0x9888), 0x41800845 },
-};
-
-static int
-get_render_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 2);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 2);
-
- if (INTEL_INFO(dev_priv)->sseu.slice_mask & 0x01) {
- regs[n] = mux_config_render_basic_0_slices_0x01;
- lens[n] = ARRAY_SIZE(mux_config_render_basic_0_slices_0x01);
- n++;
- }
- if (INTEL_INFO(dev_priv)->sseu.slice_mask & 0x02) {
- regs[n] = mux_config_render_basic_1_slices_0x02;
- lens[n] = ARRAY_SIZE(mux_config_render_basic_1_slices_0x02);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_basic_0_slices_0x01[] = {
- { _MMIO(0x9888), 0x105c00e0 },
- { _MMIO(0x9888), 0x105800e0 },
- { _MMIO(0x9888), 0x103800e0 },
- { _MMIO(0x9888), 0x3580001a },
- { _MMIO(0x9888), 0x3b800060 },
- { _MMIO(0x9888), 0x3d800005 },
- { _MMIO(0x9888), 0x065c2100 },
- { _MMIO(0x9888), 0x0a5c0041 },
- { _MMIO(0x9888), 0x0c5c6600 },
- { _MMIO(0x9888), 0x005c6580 },
- { _MMIO(0x9888), 0x085c8000 },
- { _MMIO(0x9888), 0x0e5c8000 },
- { _MMIO(0x9888), 0x00580042 },
- { _MMIO(0x9888), 0x08582080 },
- { _MMIO(0x9888), 0x0c58004c },
- { _MMIO(0x9888), 0x0e582580 },
- { _MMIO(0x9888), 0x005b4000 },
- { _MMIO(0x9888), 0x185b1000 },
- { _MMIO(0x9888), 0x1a5b0104 },
- { _MMIO(0x9888), 0x0c1fa800 },
- { _MMIO(0x9888), 0x0e1faa00 },
- { _MMIO(0x9888), 0x101f02aa },
- { _MMIO(0x9888), 0x08380042 },
- { _MMIO(0x9888), 0x0a382080 },
- { _MMIO(0x9888), 0x0e38404c },
- { _MMIO(0x9888), 0x0238404b },
- { _MMIO(0x9888), 0x00384000 },
- { _MMIO(0x9888), 0x16380000 },
- { _MMIO(0x9888), 0x18381145 },
- { _MMIO(0x9888), 0x04380000 },
- { _MMIO(0x9888), 0x0039a000 },
- { _MMIO(0x9888), 0x06398000 },
- { _MMIO(0x9888), 0x0839a000 },
- { _MMIO(0x9888), 0x0a39a000 },
- { _MMIO(0x9888), 0x0c39a000 },
- { _MMIO(0x9888), 0x0e39a000 },
- { _MMIO(0x9888), 0x02392000 },
- { _MMIO(0x9888), 0x018a8000 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x198a8000 },
- { _MMIO(0x9888), 0x1b8aaaa0 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x238b02a0 },
- { _MMIO(0x9888), 0x258b5550 },
- { _MMIO(0x9888), 0x278b0015 },
- { _MMIO(0x9888), 0x1f850a80 },
- { _MMIO(0x9888), 0x2185aaa0 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x03844000 },
- { _MMIO(0x9888), 0x17808137 },
- { _MMIO(0x9888), 0x1980c147 },
- { _MMIO(0x9888), 0x1b80c0e5 },
- { _MMIO(0x9888), 0x1d80c0e3 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x13804000 },
- { _MMIO(0x9888), 0x15800000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d801000 },
- { _MMIO(0x9888), 0x4f800111 },
- { _MMIO(0x9888), 0x43800062 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800062 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800062 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f801062 },
- { _MMIO(0x9888), 0x41801084 },
-};
-
-static const struct i915_oa_reg mux_config_compute_basic_2_slices_0x02[] = {
- { _MMIO(0x9888), 0x10dc00e0 },
- { _MMIO(0x9888), 0x10d800e0 },
- { _MMIO(0x9888), 0x10b800e0 },
- { _MMIO(0x9888), 0x3580001a },
- { _MMIO(0x9888), 0x3b800060 },
- { _MMIO(0x9888), 0x3d800005 },
- { _MMIO(0x9888), 0x06dc2100 },
- { _MMIO(0x9888), 0x0adc0041 },
- { _MMIO(0x9888), 0x0cdc6600 },
- { _MMIO(0x9888), 0x00dc6580 },
- { _MMIO(0x9888), 0x08dc8000 },
- { _MMIO(0x9888), 0x0edc8000 },
- { _MMIO(0x9888), 0x00d80042 },
- { _MMIO(0x9888), 0x08d82080 },
- { _MMIO(0x9888), 0x0cd8004c },
- { _MMIO(0x9888), 0x0ed82580 },
- { _MMIO(0x9888), 0x00db4000 },
- { _MMIO(0x9888), 0x18db1000 },
- { _MMIO(0x9888), 0x1adb0104 },
- { _MMIO(0x9888), 0x0c9fa800 },
- { _MMIO(0x9888), 0x0e9faa00 },
- { _MMIO(0x9888), 0x109f02aa },
- { _MMIO(0x9888), 0x08b80042 },
- { _MMIO(0x9888), 0x0ab82080 },
- { _MMIO(0x9888), 0x0eb8404c },
- { _MMIO(0x9888), 0x02b8404b },
- { _MMIO(0x9888), 0x00b84000 },
- { _MMIO(0x9888), 0x16b80000 },
- { _MMIO(0x9888), 0x18b81145 },
- { _MMIO(0x9888), 0x04b80000 },
- { _MMIO(0x9888), 0x00b9a000 },
- { _MMIO(0x9888), 0x06b98000 },
- { _MMIO(0x9888), 0x08b9a000 },
- { _MMIO(0x9888), 0x0ab9a000 },
- { _MMIO(0x9888), 0x0cb9a000 },
- { _MMIO(0x9888), 0x0eb9a000 },
- { _MMIO(0x9888), 0x02b92000 },
- { _MMIO(0x9888), 0x01888000 },
- { _MMIO(0x9888), 0x0d88f800 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x03888000 },
- { _MMIO(0x9888), 0x05888000 },
- { _MMIO(0x9888), 0x238b0540 },
- { _MMIO(0x9888), 0x258baaa0 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x018c4000 },
- { _MMIO(0x9888), 0x0f8c4000 },
- { _MMIO(0x9888), 0x178c2000 },
- { _MMIO(0x9888), 0x198c5500 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x038c4000 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x018da000 },
- { _MMIO(0x9888), 0x078d8000 },
- { _MMIO(0x9888), 0x098da000 },
- { _MMIO(0x9888), 0x0b8da000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x038d2000 },
- { _MMIO(0x9888), 0x1f850a80 },
- { _MMIO(0x9888), 0x2185aaa0 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x03844000 },
- { _MMIO(0x9888), 0x17808137 },
- { _MMIO(0x9888), 0x1980c147 },
- { _MMIO(0x9888), 0x1b80c0e5 },
- { _MMIO(0x9888), 0x1d80c0e3 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x13804000 },
- { _MMIO(0x9888), 0x15800000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d805000 },
- { _MMIO(0x9888), 0x4f800555 },
- { _MMIO(0x9888), 0x43800062 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800062 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800062 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800062 },
- { _MMIO(0x9888), 0x41800000 },
-};
-
-static int
-get_compute_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 2);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 2);
-
- if (INTEL_INFO(dev_priv)->sseu.slice_mask & 0x01) {
- regs[n] = mux_config_compute_basic_0_slices_0x01;
- lens[n] = ARRAY_SIZE(mux_config_compute_basic_0_slices_0x01);
- n++;
- }
- if (INTEL_INFO(dev_priv)->sseu.slice_mask & 0x02) {
- regs[n] = mux_config_compute_basic_2_slices_0x02;
- lens[n] = ARRAY_SIZE(mux_config_compute_basic_2_slices_0x02);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007ffea },
- { _MMIO(0x2774), 0x00007ffc },
- { _MMIO(0x2778), 0x0007affa },
- { _MMIO(0x277c), 0x0000f5fd },
- { _MMIO(0x2780), 0x00079ffa },
- { _MMIO(0x2784), 0x0000f3fb },
- { _MMIO(0x2788), 0x0007bf7a },
- { _MMIO(0x278c), 0x0000f7e7 },
- { _MMIO(0x2790), 0x0007fefa },
- { _MMIO(0x2794), 0x0000f7cf },
- { _MMIO(0x2798), 0x00077ffa },
- { _MMIO(0x279c), 0x0000efdf },
- { _MMIO(0x27a0), 0x0006fffa },
- { _MMIO(0x27a4), 0x0000cfbf },
- { _MMIO(0x27a8), 0x0003fffa },
- { _MMIO(0x27ac), 0x00005f7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_render_pipe_profile[] = {
- { _MMIO(0x9888), 0x0a1e0000 },
- { _MMIO(0x9888), 0x0c1f000f },
- { _MMIO(0x9888), 0x10176800 },
- { _MMIO(0x9888), 0x1191001f },
- { _MMIO(0x9888), 0x0b880320 },
- { _MMIO(0x9888), 0x01890c40 },
- { _MMIO(0x9888), 0x118a1c00 },
- { _MMIO(0x9888), 0x118d7c00 },
- { _MMIO(0x9888), 0x118e0020 },
- { _MMIO(0x9888), 0x118f4c00 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x13900001 },
- { _MMIO(0x9888), 0x065c4000 },
- { _MMIO(0x9888), 0x0c3d8000 },
- { _MMIO(0x9888), 0x06584000 },
- { _MMIO(0x9888), 0x0c5b4000 },
- { _MMIO(0x9888), 0x081e0040 },
- { _MMIO(0x9888), 0x0e1e0000 },
- { _MMIO(0x9888), 0x021f5400 },
- { _MMIO(0x9888), 0x001f0000 },
- { _MMIO(0x9888), 0x101f0010 },
- { _MMIO(0x9888), 0x0e1f0080 },
- { _MMIO(0x9888), 0x0c384000 },
- { _MMIO(0x9888), 0x06392000 },
- { _MMIO(0x9888), 0x0c13c000 },
- { _MMIO(0x9888), 0x06164000 },
- { _MMIO(0x9888), 0x06170012 },
- { _MMIO(0x9888), 0x00170000 },
- { _MMIO(0x9888), 0x01910005 },
- { _MMIO(0x9888), 0x07880002 },
- { _MMIO(0x9888), 0x01880c00 },
- { _MMIO(0x9888), 0x0f880000 },
- { _MMIO(0x9888), 0x0d880000 },
- { _MMIO(0x9888), 0x05880000 },
- { _MMIO(0x9888), 0x09890032 },
- { _MMIO(0x9888), 0x078a0800 },
- { _MMIO(0x9888), 0x0f8a0a00 },
- { _MMIO(0x9888), 0x198a4000 },
- { _MMIO(0x9888), 0x1b8a2000 },
- { _MMIO(0x9888), 0x1d8a0000 },
- { _MMIO(0x9888), 0x038a4000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x238b54c0 },
- { _MMIO(0x9888), 0x258baa55 },
- { _MMIO(0x9888), 0x278b0019 },
- { _MMIO(0x9888), 0x198c0100 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x0f8d0015 },
- { _MMIO(0x9888), 0x018d1000 },
- { _MMIO(0x9888), 0x098d8000 },
- { _MMIO(0x9888), 0x0b8df000 },
- { _MMIO(0x9888), 0x0d8d3000 },
- { _MMIO(0x9888), 0x038de000 },
- { _MMIO(0x9888), 0x058d3000 },
- { _MMIO(0x9888), 0x0d8e0004 },
- { _MMIO(0x9888), 0x058e000c },
- { _MMIO(0x9888), 0x098e0000 },
- { _MMIO(0x9888), 0x078e0000 },
- { _MMIO(0x9888), 0x038e0000 },
- { _MMIO(0x9888), 0x0b8f0020 },
- { _MMIO(0x9888), 0x198f0c00 },
- { _MMIO(0x9888), 0x078f8000 },
- { _MMIO(0x9888), 0x098f4000 },
- { _MMIO(0x9888), 0x0b900980 },
- { _MMIO(0x9888), 0x03900d80 },
- { _MMIO(0x9888), 0x01900000 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaaa },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x0784c000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x1780c000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d801111 },
- { _MMIO(0x9888), 0x3d800800 },
- { _MMIO(0x9888), 0x4f801011 },
- { _MMIO(0x9888), 0x43800443 },
- { _MMIO(0x9888), 0x51801111 },
- { _MMIO(0x9888), 0x45800422 },
- { _MMIO(0x9888), 0x53801111 },
- { _MMIO(0x9888), 0x47800c60 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800422 },
- { _MMIO(0x9888), 0x41800021 },
-};
-
-static int
-get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_pipe_profile;
- lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_reads[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f872 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_reads[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_reads[] = {
- { _MMIO(0x9888), 0x198b0343 },
- { _MMIO(0x9888), 0x13845800 },
- { _MMIO(0x9888), 0x15840018 },
- { _MMIO(0x9888), 0x3580001a },
- { _MMIO(0x9888), 0x038b6300 },
- { _MMIO(0x9888), 0x058b6b62 },
- { _MMIO(0x9888), 0x078b006a },
- { _MMIO(0x9888), 0x118b0000 },
- { _MMIO(0x9888), 0x238b0000 },
- { _MMIO(0x9888), 0x258b0000 },
- { _MMIO(0x9888), 0x1f85a080 },
- { _MMIO(0x9888), 0x2185aaaa },
- { _MMIO(0x9888), 0x2385000a },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x01840018 },
- { _MMIO(0x9888), 0x07844c80 },
- { _MMIO(0x9888), 0x09840d9a },
- { _MMIO(0x9888), 0x0b840e9c },
- { _MMIO(0x9888), 0x0d840f9e },
- { _MMIO(0x9888), 0x0f840010 },
- { _MMIO(0x9888), 0x11840000 },
- { _MMIO(0x9888), 0x03848000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x2f8000e5 },
- { _MMIO(0x9888), 0x138080e3 },
- { _MMIO(0x9888), 0x1580c0e1 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x11804000 },
- { _MMIO(0x9888), 0x1780c000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f804000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3d800800 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800842 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800842 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47801042 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800084 },
- { _MMIO(0x9888), 0x41800000 },
-};
-
-static int
-get_memory_reads_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_reads;
- lens[n] = ARRAY_SIZE(mux_config_memory_reads);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_writes[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f822 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_writes[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_writes[] = {
- { _MMIO(0x9888), 0x198b0343 },
- { _MMIO(0x9888), 0x13845400 },
- { _MMIO(0x9888), 0x3580001a },
- { _MMIO(0x9888), 0x3d800805 },
- { _MMIO(0x9888), 0x038b6300 },
- { _MMIO(0x9888), 0x058b6b62 },
- { _MMIO(0x9888), 0x078b006a },
- { _MMIO(0x9888), 0x118b0000 },
- { _MMIO(0x9888), 0x238b0000 },
- { _MMIO(0x9888), 0x258b0000 },
- { _MMIO(0x9888), 0x1f85a080 },
- { _MMIO(0x9888), 0x2185aaaa },
- { _MMIO(0x9888), 0x23850002 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x01840010 },
- { _MMIO(0x9888), 0x07844880 },
- { _MMIO(0x9888), 0x09840992 },
- { _MMIO(0x9888), 0x0b840a94 },
- { _MMIO(0x9888), 0x0d840b96 },
- { _MMIO(0x9888), 0x11840000 },
- { _MMIO(0x9888), 0x03848000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x2d800147 },
- { _MMIO(0x9888), 0x2f8000e5 },
- { _MMIO(0x9888), 0x138080e3 },
- { _MMIO(0x9888), 0x1580c0e1 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x11804000 },
- { _MMIO(0x9888), 0x1780c000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f800000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800842 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800842 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47801082 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800084 },
- { _MMIO(0x9888), 0x41800000 },
-};
-
-static int
-get_memory_writes_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_writes;
- lens[n] = ARRAY_SIZE(mux_config_memory_writes);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extended[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fc2a },
- { _MMIO(0x2774), 0x0000bf00 },
- { _MMIO(0x2778), 0x0007fc6a },
- { _MMIO(0x277c), 0x0000bf00 },
- { _MMIO(0x2780), 0x0007fc92 },
- { _MMIO(0x2784), 0x0000bf00 },
- { _MMIO(0x2788), 0x0007fca2 },
- { _MMIO(0x278c), 0x0000bf00 },
- { _MMIO(0x2790), 0x0007fc32 },
- { _MMIO(0x2794), 0x0000bf00 },
- { _MMIO(0x2798), 0x0007fc9a },
- { _MMIO(0x279c), 0x0000bf00 },
- { _MMIO(0x27a0), 0x0007fe6a },
- { _MMIO(0x27a4), 0x0000bf00 },
- { _MMIO(0x27a8), 0x0007fe7a },
- { _MMIO(0x27ac), 0x0000bf00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extended[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended_0_subslices_0x01[] = {
- { _MMIO(0x9888), 0x143d0160 },
- { _MMIO(0x9888), 0x163d2800 },
- { _MMIO(0x9888), 0x183d0120 },
- { _MMIO(0x9888), 0x105800e0 },
- { _MMIO(0x9888), 0x005cc000 },
- { _MMIO(0x9888), 0x065c8000 },
- { _MMIO(0x9888), 0x085cc000 },
- { _MMIO(0x9888), 0x0a5cc000 },
- { _MMIO(0x9888), 0x0c5cc000 },
- { _MMIO(0x9888), 0x0e5cc000 },
- { _MMIO(0x9888), 0x025cc000 },
- { _MMIO(0x9888), 0x045cc000 },
- { _MMIO(0x9888), 0x003d0011 },
- { _MMIO(0x9888), 0x063d0900 },
- { _MMIO(0x9888), 0x083d0a13 },
- { _MMIO(0x9888), 0x0a3d0b15 },
- { _MMIO(0x9888), 0x0c3d2317 },
- { _MMIO(0x9888), 0x043d21b7 },
- { _MMIO(0x9888), 0x103d0000 },
- { _MMIO(0x9888), 0x0e3d0000 },
- { _MMIO(0x9888), 0x1a3d0000 },
- { _MMIO(0x9888), 0x0e5825c1 },
- { _MMIO(0x9888), 0x00586100 },
- { _MMIO(0x9888), 0x0258204c },
- { _MMIO(0x9888), 0x06588000 },
- { _MMIO(0x9888), 0x0858c000 },
- { _MMIO(0x9888), 0x0a58c000 },
- { _MMIO(0x9888), 0x0c58c000 },
- { _MMIO(0x9888), 0x0458c000 },
- { _MMIO(0x9888), 0x005b4000 },
- { _MMIO(0x9888), 0x0e5b4000 },
- { _MMIO(0x9888), 0x185b5400 },
- { _MMIO(0x9888), 0x1a5b0155 },
- { _MMIO(0x9888), 0x025b4000 },
- { _MMIO(0x9888), 0x045b4000 },
- { _MMIO(0x9888), 0x065b4000 },
- { _MMIO(0x9888), 0x085b4000 },
- { _MMIO(0x9888), 0x0a5b4000 },
- { _MMIO(0x9888), 0x0c1fa800 },
- { _MMIO(0x9888), 0x0e1faa2a },
- { _MMIO(0x9888), 0x101f02aa },
- { _MMIO(0x9888), 0x00384000 },
- { _MMIO(0x9888), 0x0e384000 },
- { _MMIO(0x9888), 0x16384000 },
- { _MMIO(0x9888), 0x18381555 },
- { _MMIO(0x9888), 0x02384000 },
- { _MMIO(0x9888), 0x04384000 },
- { _MMIO(0x9888), 0x06384000 },
- { _MMIO(0x9888), 0x08384000 },
- { _MMIO(0x9888), 0x0a384000 },
- { _MMIO(0x9888), 0x0039a000 },
- { _MMIO(0x9888), 0x06398000 },
- { _MMIO(0x9888), 0x0839a000 },
- { _MMIO(0x9888), 0x0a39a000 },
- { _MMIO(0x9888), 0x0c39a000 },
- { _MMIO(0x9888), 0x0e39a000 },
- { _MMIO(0x9888), 0x0239a000 },
- { _MMIO(0x9888), 0x0439a000 },
- { _MMIO(0x9888), 0x018a8000 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x198a8000 },
- { _MMIO(0x9888), 0x1b8aaaa0 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x238b2aa0 },
- { _MMIO(0x9888), 0x258b5551 },
- { _MMIO(0x9888), 0x278b0015 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaa2 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x17808000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3d800000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800000 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800420 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800421 },
- { _MMIO(0x9888), 0x41800000 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended_2_subslices_0x02[] = {
- { _MMIO(0x9888), 0x105c00e0 },
- { _MMIO(0x9888), 0x145b0160 },
- { _MMIO(0x9888), 0x165b2800 },
- { _MMIO(0x9888), 0x185b0120 },
- { _MMIO(0x9888), 0x0e5c25c1 },
- { _MMIO(0x9888), 0x005c6100 },
- { _MMIO(0x9888), 0x025c204c },
- { _MMIO(0x9888), 0x065c8000 },
- { _MMIO(0x9888), 0x085cc000 },
- { _MMIO(0x9888), 0x0a5cc000 },
- { _MMIO(0x9888), 0x0c5cc000 },
- { _MMIO(0x9888), 0x045cc000 },
- { _MMIO(0x9888), 0x005b0011 },
- { _MMIO(0x9888), 0x065b0900 },
- { _MMIO(0x9888), 0x085b0a13 },
- { _MMIO(0x9888), 0x0a5b0b15 },
- { _MMIO(0x9888), 0x0c5b2317 },
- { _MMIO(0x9888), 0x045b21b7 },
- { _MMIO(0x9888), 0x105b0000 },
- { _MMIO(0x9888), 0x0e5b0000 },
- { _MMIO(0x9888), 0x1a5b0000 },
- { _MMIO(0x9888), 0x0c1fa800 },
- { _MMIO(0x9888), 0x0e1faa2a },
- { _MMIO(0x9888), 0x101f02aa },
- { _MMIO(0x9888), 0x00384000 },
- { _MMIO(0x9888), 0x0e384000 },
- { _MMIO(0x9888), 0x16384000 },
- { _MMIO(0x9888), 0x18381555 },
- { _MMIO(0x9888), 0x02384000 },
- { _MMIO(0x9888), 0x04384000 },
- { _MMIO(0x9888), 0x06384000 },
- { _MMIO(0x9888), 0x08384000 },
- { _MMIO(0x9888), 0x0a384000 },
- { _MMIO(0x9888), 0x0039a000 },
- { _MMIO(0x9888), 0x06398000 },
- { _MMIO(0x9888), 0x0839a000 },
- { _MMIO(0x9888), 0x0a39a000 },
- { _MMIO(0x9888), 0x0c39a000 },
- { _MMIO(0x9888), 0x0e39a000 },
- { _MMIO(0x9888), 0x0239a000 },
- { _MMIO(0x9888), 0x0439a000 },
- { _MMIO(0x9888), 0x018a8000 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x198a8000 },
- { _MMIO(0x9888), 0x1b8aaaa0 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x238b2aa0 },
- { _MMIO(0x9888), 0x258b5551 },
- { _MMIO(0x9888), 0x278b0015 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaa2 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x17808000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3d800000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800000 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800420 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800421 },
- { _MMIO(0x9888), 0x41800000 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended_4_subslices_0x04[] = {
- { _MMIO(0x9888), 0x103800e0 },
- { _MMIO(0x9888), 0x143a0160 },
- { _MMIO(0x9888), 0x163a2800 },
- { _MMIO(0x9888), 0x183a0120 },
- { _MMIO(0x9888), 0x0c1fa800 },
- { _MMIO(0x9888), 0x0e1faa2a },
- { _MMIO(0x9888), 0x101f02aa },
- { _MMIO(0x9888), 0x0e38a5c1 },
- { _MMIO(0x9888), 0x0038a100 },
- { _MMIO(0x9888), 0x0238204c },
- { _MMIO(0x9888), 0x16388000 },
- { _MMIO(0x9888), 0x183802aa },
- { _MMIO(0x9888), 0x04380000 },
- { _MMIO(0x9888), 0x06380000 },
- { _MMIO(0x9888), 0x08388000 },
- { _MMIO(0x9888), 0x0a388000 },
- { _MMIO(0x9888), 0x0039a000 },
- { _MMIO(0x9888), 0x06398000 },
- { _MMIO(0x9888), 0x0839a000 },
- { _MMIO(0x9888), 0x0a39a000 },
- { _MMIO(0x9888), 0x0c39a000 },
- { _MMIO(0x9888), 0x0e39a000 },
- { _MMIO(0x9888), 0x0239a000 },
- { _MMIO(0x9888), 0x0439a000 },
- { _MMIO(0x9888), 0x003a0011 },
- { _MMIO(0x9888), 0x063a0900 },
- { _MMIO(0x9888), 0x083a0a13 },
- { _MMIO(0x9888), 0x0a3a0b15 },
- { _MMIO(0x9888), 0x0c3a2317 },
- { _MMIO(0x9888), 0x043a21b7 },
- { _MMIO(0x9888), 0x103a0000 },
- { _MMIO(0x9888), 0x0e3a0000 },
- { _MMIO(0x9888), 0x1a3a0000 },
- { _MMIO(0x9888), 0x018a8000 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x198a8000 },
- { _MMIO(0x9888), 0x1b8aaaa0 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x238b2aa0 },
- { _MMIO(0x9888), 0x258b5551 },
- { _MMIO(0x9888), 0x278b0015 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaa2 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x17808000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3d800000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800000 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800420 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800421 },
- { _MMIO(0x9888), 0x41800000 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended_1_subslices_0x08[] = {
- { _MMIO(0x9888), 0x14bd0160 },
- { _MMIO(0x9888), 0x16bd2800 },
- { _MMIO(0x9888), 0x18bd0120 },
- { _MMIO(0x9888), 0x10d800e0 },
- { _MMIO(0x9888), 0x00dcc000 },
- { _MMIO(0x9888), 0x06dc8000 },
- { _MMIO(0x9888), 0x08dcc000 },
- { _MMIO(0x9888), 0x0adcc000 },
- { _MMIO(0x9888), 0x0cdcc000 },
- { _MMIO(0x9888), 0x0edcc000 },
- { _MMIO(0x9888), 0x02dcc000 },
- { _MMIO(0x9888), 0x04dcc000 },
- { _MMIO(0x9888), 0x00bd0011 },
- { _MMIO(0x9888), 0x06bd0900 },
- { _MMIO(0x9888), 0x08bd0a13 },
- { _MMIO(0x9888), 0x0abd0b15 },
- { _MMIO(0x9888), 0x0cbd2317 },
- { _MMIO(0x9888), 0x04bd21b7 },
- { _MMIO(0x9888), 0x10bd0000 },
- { _MMIO(0x9888), 0x0ebd0000 },
- { _MMIO(0x9888), 0x1abd0000 },
- { _MMIO(0x9888), 0x0ed825c1 },
- { _MMIO(0x9888), 0x00d86100 },
- { _MMIO(0x9888), 0x02d8204c },
- { _MMIO(0x9888), 0x06d88000 },
- { _MMIO(0x9888), 0x08d8c000 },
- { _MMIO(0x9888), 0x0ad8c000 },
- { _MMIO(0x9888), 0x0cd8c000 },
- { _MMIO(0x9888), 0x04d8c000 },
- { _MMIO(0x9888), 0x00db4000 },
- { _MMIO(0x9888), 0x0edb4000 },
- { _MMIO(0x9888), 0x18db5400 },
- { _MMIO(0x9888), 0x1adb0155 },
- { _MMIO(0x9888), 0x02db4000 },
- { _MMIO(0x9888), 0x04db4000 },
- { _MMIO(0x9888), 0x06db4000 },
- { _MMIO(0x9888), 0x08db4000 },
- { _MMIO(0x9888), 0x0adb4000 },
- { _MMIO(0x9888), 0x0c9fa800 },
- { _MMIO(0x9888), 0x0e9faa2a },
- { _MMIO(0x9888), 0x109f02aa },
- { _MMIO(0x9888), 0x00b84000 },
- { _MMIO(0x9888), 0x0eb84000 },
- { _MMIO(0x9888), 0x16b84000 },
- { _MMIO(0x9888), 0x18b81555 },
- { _MMIO(0x9888), 0x02b84000 },
- { _MMIO(0x9888), 0x04b84000 },
- { _MMIO(0x9888), 0x06b84000 },
- { _MMIO(0x9888), 0x08b84000 },
- { _MMIO(0x9888), 0x0ab84000 },
- { _MMIO(0x9888), 0x00b9a000 },
- { _MMIO(0x9888), 0x06b98000 },
- { _MMIO(0x9888), 0x08b9a000 },
- { _MMIO(0x9888), 0x0ab9a000 },
- { _MMIO(0x9888), 0x0cb9a000 },
- { _MMIO(0x9888), 0x0eb9a000 },
- { _MMIO(0x9888), 0x02b9a000 },
- { _MMIO(0x9888), 0x04b9a000 },
- { _MMIO(0x9888), 0x01888000 },
- { _MMIO(0x9888), 0x0d88f800 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x03888000 },
- { _MMIO(0x9888), 0x05888000 },
- { _MMIO(0x9888), 0x07888000 },
- { _MMIO(0x9888), 0x09888000 },
- { _MMIO(0x9888), 0x0b888000 },
- { _MMIO(0x9888), 0x238b5540 },
- { _MMIO(0x9888), 0x258baaa2 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x018c4000 },
- { _MMIO(0x9888), 0x0f8c4000 },
- { _MMIO(0x9888), 0x178c2000 },
- { _MMIO(0x9888), 0x198c5500 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x038c4000 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x078c4000 },
- { _MMIO(0x9888), 0x098c4000 },
- { _MMIO(0x9888), 0x0b8c4000 },
- { _MMIO(0x9888), 0x018da000 },
- { _MMIO(0x9888), 0x078d8000 },
- { _MMIO(0x9888), 0x098da000 },
- { _MMIO(0x9888), 0x0b8da000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x038da000 },
- { _MMIO(0x9888), 0x058da000 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaa2 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x17808000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3d800000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800000 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800420 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800421 },
- { _MMIO(0x9888), 0x41800000 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended_3_subslices_0x10[] = {
- { _MMIO(0x9888), 0x10dc00e0 },
- { _MMIO(0x9888), 0x14db0160 },
- { _MMIO(0x9888), 0x16db2800 },
- { _MMIO(0x9888), 0x18db0120 },
- { _MMIO(0x9888), 0x0edc25c1 },
- { _MMIO(0x9888), 0x00dc6100 },
- { _MMIO(0x9888), 0x02dc204c },
- { _MMIO(0x9888), 0x06dc8000 },
- { _MMIO(0x9888), 0x08dcc000 },
- { _MMIO(0x9888), 0x0adcc000 },
- { _MMIO(0x9888), 0x0cdcc000 },
- { _MMIO(0x9888), 0x04dcc000 },
- { _MMIO(0x9888), 0x00db0011 },
- { _MMIO(0x9888), 0x06db0900 },
- { _MMIO(0x9888), 0x08db0a13 },
- { _MMIO(0x9888), 0x0adb0b15 },
- { _MMIO(0x9888), 0x0cdb2317 },
- { _MMIO(0x9888), 0x04db21b7 },
- { _MMIO(0x9888), 0x10db0000 },
- { _MMIO(0x9888), 0x0edb0000 },
- { _MMIO(0x9888), 0x1adb0000 },
- { _MMIO(0x9888), 0x0c9fa800 },
- { _MMIO(0x9888), 0x0e9faa2a },
- { _MMIO(0x9888), 0x109f02aa },
- { _MMIO(0x9888), 0x00b84000 },
- { _MMIO(0x9888), 0x0eb84000 },
- { _MMIO(0x9888), 0x16b84000 },
- { _MMIO(0x9888), 0x18b81555 },
- { _MMIO(0x9888), 0x02b84000 },
- { _MMIO(0x9888), 0x04b84000 },
- { _MMIO(0x9888), 0x06b84000 },
- { _MMIO(0x9888), 0x08b84000 },
- { _MMIO(0x9888), 0x0ab84000 },
- { _MMIO(0x9888), 0x00b9a000 },
- { _MMIO(0x9888), 0x06b98000 },
- { _MMIO(0x9888), 0x08b9a000 },
- { _MMIO(0x9888), 0x0ab9a000 },
- { _MMIO(0x9888), 0x0cb9a000 },
- { _MMIO(0x9888), 0x0eb9a000 },
- { _MMIO(0x9888), 0x02b9a000 },
- { _MMIO(0x9888), 0x04b9a000 },
- { _MMIO(0x9888), 0x01888000 },
- { _MMIO(0x9888), 0x0d88f800 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x03888000 },
- { _MMIO(0x9888), 0x05888000 },
- { _MMIO(0x9888), 0x07888000 },
- { _MMIO(0x9888), 0x09888000 },
- { _MMIO(0x9888), 0x0b888000 },
- { _MMIO(0x9888), 0x238b5540 },
- { _MMIO(0x9888), 0x258baaa2 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x018c4000 },
- { _MMIO(0x9888), 0x0f8c4000 },
- { _MMIO(0x9888), 0x178c2000 },
- { _MMIO(0x9888), 0x198c5500 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x038c4000 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x078c4000 },
- { _MMIO(0x9888), 0x098c4000 },
- { _MMIO(0x9888), 0x0b8c4000 },
- { _MMIO(0x9888), 0x018da000 },
- { _MMIO(0x9888), 0x078d8000 },
- { _MMIO(0x9888), 0x098da000 },
- { _MMIO(0x9888), 0x0b8da000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x038da000 },
- { _MMIO(0x9888), 0x058da000 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaa2 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x17808000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3d800000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800000 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800420 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800421 },
- { _MMIO(0x9888), 0x41800000 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended_5_subslices_0x20[] = {
- { _MMIO(0x9888), 0x10b800e0 },
- { _MMIO(0x9888), 0x14ba0160 },
- { _MMIO(0x9888), 0x16ba2800 },
- { _MMIO(0x9888), 0x18ba0120 },
- { _MMIO(0x9888), 0x0c9fa800 },
- { _MMIO(0x9888), 0x0e9faa2a },
- { _MMIO(0x9888), 0x109f02aa },
- { _MMIO(0x9888), 0x0eb8a5c1 },
- { _MMIO(0x9888), 0x00b8a100 },
- { _MMIO(0x9888), 0x02b8204c },
- { _MMIO(0x9888), 0x16b88000 },
- { _MMIO(0x9888), 0x18b802aa },
- { _MMIO(0x9888), 0x04b80000 },
- { _MMIO(0x9888), 0x06b80000 },
- { _MMIO(0x9888), 0x08b88000 },
- { _MMIO(0x9888), 0x0ab88000 },
- { _MMIO(0x9888), 0x00b9a000 },
- { _MMIO(0x9888), 0x06b98000 },
- { _MMIO(0x9888), 0x08b9a000 },
- { _MMIO(0x9888), 0x0ab9a000 },
- { _MMIO(0x9888), 0x0cb9a000 },
- { _MMIO(0x9888), 0x0eb9a000 },
- { _MMIO(0x9888), 0x02b9a000 },
- { _MMIO(0x9888), 0x04b9a000 },
- { _MMIO(0x9888), 0x00ba0011 },
- { _MMIO(0x9888), 0x06ba0900 },
- { _MMIO(0x9888), 0x08ba0a13 },
- { _MMIO(0x9888), 0x0aba0b15 },
- { _MMIO(0x9888), 0x0cba2317 },
- { _MMIO(0x9888), 0x04ba21b7 },
- { _MMIO(0x9888), 0x10ba0000 },
- { _MMIO(0x9888), 0x0eba0000 },
- { _MMIO(0x9888), 0x1aba0000 },
- { _MMIO(0x9888), 0x01888000 },
- { _MMIO(0x9888), 0x0d88f800 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x03888000 },
- { _MMIO(0x9888), 0x05888000 },
- { _MMIO(0x9888), 0x07888000 },
- { _MMIO(0x9888), 0x09888000 },
- { _MMIO(0x9888), 0x0b888000 },
- { _MMIO(0x9888), 0x238b5540 },
- { _MMIO(0x9888), 0x258baaa2 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x018c4000 },
- { _MMIO(0x9888), 0x0f8c4000 },
- { _MMIO(0x9888), 0x178c2000 },
- { _MMIO(0x9888), 0x198c5500 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x038c4000 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x078c4000 },
- { _MMIO(0x9888), 0x098c4000 },
- { _MMIO(0x9888), 0x0b8c4000 },
- { _MMIO(0x9888), 0x018da000 },
- { _MMIO(0x9888), 0x078d8000 },
- { _MMIO(0x9888), 0x098da000 },
- { _MMIO(0x9888), 0x0b8da000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x038da000 },
- { _MMIO(0x9888), 0x058da000 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaa2 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x17808000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3d800000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800000 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800420 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800421 },
- { _MMIO(0x9888), 0x41800000 },
-};
-
-static int
-get_compute_extended_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 6);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 6);
-
- if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x01) {
- regs[n] = mux_config_compute_extended_0_subslices_0x01;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended_0_subslices_0x01);
- n++;
- }
- if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x08) {
- regs[n] = mux_config_compute_extended_1_subslices_0x08;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended_1_subslices_0x08);
- n++;
- }
- if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x02) {
- regs[n] = mux_config_compute_extended_2_subslices_0x02;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended_2_subslices_0x02);
- n++;
- }
- if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x10) {
- regs[n] = mux_config_compute_extended_3_subslices_0x10;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended_3_subslices_0x10);
- n++;
- }
- if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x04) {
- regs[n] = mux_config_compute_extended_4_subslices_0x04;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended_4_subslices_0x04);
- n++;
- }
- if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x20) {
- regs[n] = mux_config_compute_extended_5_subslices_0x20;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended_5_subslices_0x20);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_l3_cache[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fffa },
- { _MMIO(0x2774), 0x0000fefe },
- { _MMIO(0x2778), 0x0007fffa },
- { _MMIO(0x277c), 0x0000fefd },
- { _MMIO(0x2790), 0x0007fffa },
- { _MMIO(0x2794), 0x0000fbef },
- { _MMIO(0x2798), 0x0007fffa },
- { _MMIO(0x279c), 0x0000fbdf },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_l3_cache[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00101100 },
- { _MMIO(0xe45c), 0x00201200 },
- { _MMIO(0xe55c), 0x00301300 },
- { _MMIO(0xe65c), 0x00401400 },
-};
-
-static const struct i915_oa_reg mux_config_compute_l3_cache[] = {
- { _MMIO(0x9888), 0x143f00b3 },
- { _MMIO(0x9888), 0x14bf00b3 },
- { _MMIO(0x9888), 0x138303c0 },
- { _MMIO(0x9888), 0x3b800060 },
- { _MMIO(0x9888), 0x3d800805 },
- { _MMIO(0x9888), 0x003f0029 },
- { _MMIO(0x9888), 0x063f1400 },
- { _MMIO(0x9888), 0x083f1225 },
- { _MMIO(0x9888), 0x0e3f1327 },
- { _MMIO(0x9888), 0x103f0000 },
- { _MMIO(0x9888), 0x005a4000 },
- { _MMIO(0x9888), 0x065a8000 },
- { _MMIO(0x9888), 0x085ac000 },
- { _MMIO(0x9888), 0x0e5ac000 },
- { _MMIO(0x9888), 0x001d4000 },
- { _MMIO(0x9888), 0x061d8000 },
- { _MMIO(0x9888), 0x081dc000 },
- { _MMIO(0x9888), 0x0e1dc000 },
- { _MMIO(0x9888), 0x0c1f0800 },
- { _MMIO(0x9888), 0x0e1f2a00 },
- { _MMIO(0x9888), 0x101f0280 },
- { _MMIO(0x9888), 0x00391000 },
- { _MMIO(0x9888), 0x06394000 },
- { _MMIO(0x9888), 0x08395000 },
- { _MMIO(0x9888), 0x0e395000 },
- { _MMIO(0x9888), 0x0abf1429 },
- { _MMIO(0x9888), 0x0cbf1225 },
- { _MMIO(0x9888), 0x00bf1380 },
- { _MMIO(0x9888), 0x02bf0026 },
- { _MMIO(0x9888), 0x10bf0000 },
- { _MMIO(0x9888), 0x0adac000 },
- { _MMIO(0x9888), 0x0cdac000 },
- { _MMIO(0x9888), 0x00da8000 },
- { _MMIO(0x9888), 0x02da4000 },
- { _MMIO(0x9888), 0x0a9dc000 },
- { _MMIO(0x9888), 0x0c9dc000 },
- { _MMIO(0x9888), 0x009d8000 },
- { _MMIO(0x9888), 0x029d4000 },
- { _MMIO(0x9888), 0x0e9f8000 },
- { _MMIO(0x9888), 0x109f002a },
- { _MMIO(0x9888), 0x0c9fa000 },
- { _MMIO(0x9888), 0x0ab95000 },
- { _MMIO(0x9888), 0x0cb95000 },
- { _MMIO(0x9888), 0x00b94000 },
- { _MMIO(0x9888), 0x02b91000 },
- { _MMIO(0x9888), 0x0d88c000 },
- { _MMIO(0x9888), 0x0f880003 },
- { _MMIO(0x9888), 0x03888000 },
- { _MMIO(0x9888), 0x05888000 },
- { _MMIO(0x9888), 0x018a8000 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x198a8000 },
- { _MMIO(0x9888), 0x1b8a8020 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x238b0520 },
- { _MMIO(0x9888), 0x258ba950 },
- { _MMIO(0x9888), 0x278b0016 },
- { _MMIO(0x9888), 0x198c5400 },
- { _MMIO(0x9888), 0x1b8c0001 },
- { _MMIO(0x9888), 0x038c4000 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x0b8da000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x018d8000 },
- { _MMIO(0x9888), 0x038d2000 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaa0 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x03835180 },
- { _MMIO(0x9888), 0x05834022 },
- { _MMIO(0x9888), 0x11830000 },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x07830000 },
- { _MMIO(0x9888), 0x09830000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x05844000 },
- { _MMIO(0x9888), 0x1b80c137 },
- { _MMIO(0x9888), 0x1d80c147 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x17808000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x15804000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d801000 },
- { _MMIO(0x9888), 0x4f800111 },
- { _MMIO(0x9888), 0x43800842 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800840 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800800 },
- { _MMIO(0x9888), 0x418014a2 },
-};
-
-static int
-get_compute_l3_cache_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_l3_cache;
- lens[n] = ARRAY_SIZE(mux_config_compute_l3_cache);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_data_port_reads_coalescing[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0xba98ba98 },
- { _MMIO(0x2748), 0xba98ba98 },
- { _MMIO(0x2744), 0x00003377 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fff2 },
- { _MMIO(0x2774), 0x00007ff0 },
- { _MMIO(0x2778), 0x0007ffe2 },
- { _MMIO(0x277c), 0x00007ff0 },
- { _MMIO(0x2780), 0x0007ffc2 },
- { _MMIO(0x2784), 0x00007ff0 },
- { _MMIO(0x2788), 0x0007ff82 },
- { _MMIO(0x278c), 0x00007ff0 },
- { _MMIO(0x2790), 0x0007fffa },
- { _MMIO(0x2794), 0x0000bfef },
- { _MMIO(0x2798), 0x0007fffa },
- { _MMIO(0x279c), 0x0000bfdf },
- { _MMIO(0x27a0), 0x0007fffa },
- { _MMIO(0x27a4), 0x0000bfbf },
- { _MMIO(0x27a8), 0x0007fffa },
- { _MMIO(0x27ac), 0x0000bf7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_data_port_reads_coalescing[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_data_port_reads_coalescing_0_subslices_0x01[] = {
- { _MMIO(0x9888), 0x103d0005 },
- { _MMIO(0x9888), 0x163d240b },
- { _MMIO(0x9888), 0x1058022f },
- { _MMIO(0x9888), 0x185b5520 },
- { _MMIO(0x9888), 0x198b0003 },
- { _MMIO(0x9888), 0x005cc000 },
- { _MMIO(0x9888), 0x065cc000 },
- { _MMIO(0x9888), 0x085cc000 },
- { _MMIO(0x9888), 0x0a5cc000 },
- { _MMIO(0x9888), 0x0c5cc000 },
- { _MMIO(0x9888), 0x0e5cc000 },
- { _MMIO(0x9888), 0x025c4000 },
- { _MMIO(0x9888), 0x045c8000 },
- { _MMIO(0x9888), 0x003d0000 },
- { _MMIO(0x9888), 0x063d00b0 },
- { _MMIO(0x9888), 0x083d0182 },
- { _MMIO(0x9888), 0x0a3d10a0 },
- { _MMIO(0x9888), 0x0c3d11a2 },
- { _MMIO(0x9888), 0x0e3d0000 },
- { _MMIO(0x9888), 0x183d0000 },
- { _MMIO(0x9888), 0x1a3d0000 },
- { _MMIO(0x9888), 0x0e582242 },
- { _MMIO(0x9888), 0x00586700 },
- { _MMIO(0x9888), 0x0258004f },
- { _MMIO(0x9888), 0x0658c000 },
- { _MMIO(0x9888), 0x0858c000 },
- { _MMIO(0x9888), 0x0a58c000 },
- { _MMIO(0x9888), 0x0c58c000 },
- { _MMIO(0x9888), 0x045b6300 },
- { _MMIO(0x9888), 0x105b0000 },
- { _MMIO(0x9888), 0x005b4000 },
- { _MMIO(0x9888), 0x0e5b4000 },
- { _MMIO(0x9888), 0x1a5b0155 },
- { _MMIO(0x9888), 0x025b4000 },
- { _MMIO(0x9888), 0x0a5b0000 },
- { _MMIO(0x9888), 0x0c5b4000 },
- { _MMIO(0x9888), 0x0c1fa800 },
- { _MMIO(0x9888), 0x0e1faaa0 },
- { _MMIO(0x9888), 0x101f02aa },
- { _MMIO(0x9888), 0x00384000 },
- { _MMIO(0x9888), 0x0e384000 },
- { _MMIO(0x9888), 0x16384000 },
- { _MMIO(0x9888), 0x18381555 },
- { _MMIO(0x9888), 0x02384000 },
- { _MMIO(0x9888), 0x04384000 },
- { _MMIO(0x9888), 0x0a384000 },
- { _MMIO(0x9888), 0x0c384000 },
- { _MMIO(0x9888), 0x0039a000 },
- { _MMIO(0x9888), 0x0639a000 },
- { _MMIO(0x9888), 0x0839a000 },
- { _MMIO(0x9888), 0x0a39a000 },
- { _MMIO(0x9888), 0x0c39a000 },
- { _MMIO(0x9888), 0x0e39a000 },
- { _MMIO(0x9888), 0x02392000 },
- { _MMIO(0x9888), 0x04398000 },
- { _MMIO(0x9888), 0x018a8000 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x198a8000 },
- { _MMIO(0x9888), 0x1b8aaaa0 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x038b6300 },
- { _MMIO(0x9888), 0x058b0062 },
- { _MMIO(0x9888), 0x118b0000 },
- { _MMIO(0x9888), 0x238b02a0 },
- { _MMIO(0x9888), 0x258b5555 },
- { _MMIO(0x9888), 0x278b0015 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaaa },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x0784c000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x1780c000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d801000 },
- { _MMIO(0x9888), 0x3d800000 },
- { _MMIO(0x9888), 0x4f800001 },
- { _MMIO(0x9888), 0x43800000 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800420 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800421 },
- { _MMIO(0x9888), 0x41800041 },
-};
-
-static int
-get_data_port_reads_coalescing_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x01) {
- regs[n] = mux_config_data_port_reads_coalescing_0_subslices_0x01;
- lens[n] = ARRAY_SIZE(mux_config_data_port_reads_coalescing_0_subslices_0x01);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_data_port_writes_coalescing[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0xba98ba98 },
- { _MMIO(0x2748), 0xba98ba98 },
- { _MMIO(0x2744), 0x00003377 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007ff72 },
- { _MMIO(0x2774), 0x0000bfd0 },
- { _MMIO(0x2778), 0x0007ff62 },
- { _MMIO(0x277c), 0x0000bfd0 },
- { _MMIO(0x2780), 0x0007ff42 },
- { _MMIO(0x2784), 0x0000bfd0 },
- { _MMIO(0x2788), 0x0007ff02 },
- { _MMIO(0x278c), 0x0000bfd0 },
- { _MMIO(0x2790), 0x0005fff2 },
- { _MMIO(0x2794), 0x0000bfd0 },
- { _MMIO(0x2798), 0x0005ffe2 },
- { _MMIO(0x279c), 0x0000bfd0 },
- { _MMIO(0x27a0), 0x0005ffc2 },
- { _MMIO(0x27a4), 0x0000bfd0 },
- { _MMIO(0x27a8), 0x0005ff82 },
- { _MMIO(0x27ac), 0x0000bfd0 },
-};
-
-static const struct i915_oa_reg flex_eu_config_data_port_writes_coalescing[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_data_port_writes_coalescing_0_subslices_0x01[] = {
- { _MMIO(0x9888), 0x103d0005 },
- { _MMIO(0x9888), 0x143d0120 },
- { _MMIO(0x9888), 0x163d2400 },
- { _MMIO(0x9888), 0x1058022f },
- { _MMIO(0x9888), 0x105b0000 },
- { _MMIO(0x9888), 0x198b0003 },
- { _MMIO(0x9888), 0x005cc000 },
- { _MMIO(0x9888), 0x065cc000 },
- { _MMIO(0x9888), 0x085cc000 },
- { _MMIO(0x9888), 0x0a5cc000 },
- { _MMIO(0x9888), 0x0e5cc000 },
- { _MMIO(0x9888), 0x025c4000 },
- { _MMIO(0x9888), 0x045c8000 },
- { _MMIO(0x9888), 0x003d0000 },
- { _MMIO(0x9888), 0x063d0094 },
- { _MMIO(0x9888), 0x083d0182 },
- { _MMIO(0x9888), 0x0a3d1814 },
- { _MMIO(0x9888), 0x0e3d0000 },
- { _MMIO(0x9888), 0x183d0000 },
- { _MMIO(0x9888), 0x1a3d0000 },
- { _MMIO(0x9888), 0x0c3d0000 },
- { _MMIO(0x9888), 0x0e582242 },
- { _MMIO(0x9888), 0x00586700 },
- { _MMIO(0x9888), 0x0258004f },
- { _MMIO(0x9888), 0x0658c000 },
- { _MMIO(0x9888), 0x0858c000 },
- { _MMIO(0x9888), 0x0a58c000 },
- { _MMIO(0x9888), 0x045b6a80 },
- { _MMIO(0x9888), 0x005b4000 },
- { _MMIO(0x9888), 0x0e5b4000 },
- { _MMIO(0x9888), 0x185b5400 },
- { _MMIO(0x9888), 0x1a5b0141 },
- { _MMIO(0x9888), 0x025b4000 },
- { _MMIO(0x9888), 0x0a5b0000 },
- { _MMIO(0x9888), 0x0c5b4000 },
- { _MMIO(0x9888), 0x0c1fa800 },
- { _MMIO(0x9888), 0x0e1faaa0 },
- { _MMIO(0x9888), 0x101f0282 },
- { _MMIO(0x9888), 0x00384000 },
- { _MMIO(0x9888), 0x0e384000 },
- { _MMIO(0x9888), 0x16384000 },
- { _MMIO(0x9888), 0x18381415 },
- { _MMIO(0x9888), 0x02384000 },
- { _MMIO(0x9888), 0x04384000 },
- { _MMIO(0x9888), 0x0a384000 },
- { _MMIO(0x9888), 0x0c384000 },
- { _MMIO(0x9888), 0x0039a000 },
- { _MMIO(0x9888), 0x0639a000 },
- { _MMIO(0x9888), 0x0839a000 },
- { _MMIO(0x9888), 0x0a39a000 },
- { _MMIO(0x9888), 0x0e39a000 },
- { _MMIO(0x9888), 0x02392000 },
- { _MMIO(0x9888), 0x04398000 },
- { _MMIO(0x9888), 0x018a8000 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x198a8000 },
- { _MMIO(0x9888), 0x1b8a82a0 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x038b6300 },
- { _MMIO(0x9888), 0x058b0062 },
- { _MMIO(0x9888), 0x118b0000 },
- { _MMIO(0x9888), 0x238b02a0 },
- { _MMIO(0x9888), 0x258b1555 },
- { _MMIO(0x9888), 0x278b0014 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x21852aaa },
- { _MMIO(0x9888), 0x23850028 },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830141 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x0784c000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x1780c000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d801000 },
- { _MMIO(0x9888), 0x3d800000 },
- { _MMIO(0x9888), 0x4f800001 },
- { _MMIO(0x9888), 0x43800000 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800420 },
- { _MMIO(0x9888), 0x3f800421 },
- { _MMIO(0x9888), 0x41800041 },
-};
-
-static int
-get_data_port_writes_coalescing_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x01) {
- regs[n] = mux_config_data_port_writes_coalescing_0_subslices_0x01;
- lens[n] = ARRAY_SIZE(mux_config_data_port_writes_coalescing_0_subslices_0x01);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x10800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fff7 },
-};
-
-static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_hdc_and_sf[] = {
- { _MMIO(0x9888), 0x105c0232 },
- { _MMIO(0x9888), 0x10580232 },
- { _MMIO(0x9888), 0x10380232 },
- { _MMIO(0x9888), 0x10dc0232 },
- { _MMIO(0x9888), 0x10d80232 },
- { _MMIO(0x9888), 0x10b80232 },
- { _MMIO(0x9888), 0x118e4400 },
- { _MMIO(0x9888), 0x025c6080 },
- { _MMIO(0x9888), 0x045c004b },
- { _MMIO(0x9888), 0x005c8000 },
- { _MMIO(0x9888), 0x00582080 },
- { _MMIO(0x9888), 0x0258004b },
- { _MMIO(0x9888), 0x025b4000 },
- { _MMIO(0x9888), 0x045b4000 },
- { _MMIO(0x9888), 0x0c1fa000 },
- { _MMIO(0x9888), 0x0e1f00aa },
- { _MMIO(0x9888), 0x04386080 },
- { _MMIO(0x9888), 0x0638404b },
- { _MMIO(0x9888), 0x02384000 },
- { _MMIO(0x9888), 0x08384000 },
- { _MMIO(0x9888), 0x0a380000 },
- { _MMIO(0x9888), 0x0c380000 },
- { _MMIO(0x9888), 0x00398000 },
- { _MMIO(0x9888), 0x0239a000 },
- { _MMIO(0x9888), 0x0439a000 },
- { _MMIO(0x9888), 0x06392000 },
- { _MMIO(0x9888), 0x0cdc25c1 },
- { _MMIO(0x9888), 0x0adcc000 },
- { _MMIO(0x9888), 0x0ad825c1 },
- { _MMIO(0x9888), 0x18db4000 },
- { _MMIO(0x9888), 0x1adb0001 },
- { _MMIO(0x9888), 0x0e9f8000 },
- { _MMIO(0x9888), 0x109f02aa },
- { _MMIO(0x9888), 0x0eb825c1 },
- { _MMIO(0x9888), 0x18b80154 },
- { _MMIO(0x9888), 0x0ab9a000 },
- { _MMIO(0x9888), 0x0cb9a000 },
- { _MMIO(0x9888), 0x0eb9a000 },
- { _MMIO(0x9888), 0x0d88c000 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x258baa05 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x238b2a80 },
- { _MMIO(0x9888), 0x198c5400 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x098dc000 },
- { _MMIO(0x9888), 0x0b8da000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x098e05c0 },
- { _MMIO(0x9888), 0x058e0000 },
- { _MMIO(0x9888), 0x198f0020 },
- { _MMIO(0x9888), 0x2185aa0a },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x19835000 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x09848000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x19808000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x51800040 },
- { _MMIO(0x9888), 0x43800400 },
- { _MMIO(0x9888), 0x45800800 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800c62 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f801042 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x418014a4 },
-};
-
-static int
-get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_hdc_and_sf;
- lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_1[] = {
- { _MMIO(0x9888), 0x10bf03da },
- { _MMIO(0x9888), 0x14bf0001 },
- { _MMIO(0x9888), 0x12980340 },
- { _MMIO(0x9888), 0x12990340 },
- { _MMIO(0x9888), 0x0cbf1187 },
- { _MMIO(0x9888), 0x0ebf1205 },
- { _MMIO(0x9888), 0x00bf0500 },
- { _MMIO(0x9888), 0x02bf042b },
- { _MMIO(0x9888), 0x04bf002c },
- { _MMIO(0x9888), 0x0cdac000 },
- { _MMIO(0x9888), 0x0edac000 },
- { _MMIO(0x9888), 0x00da8000 },
- { _MMIO(0x9888), 0x02dac000 },
- { _MMIO(0x9888), 0x04da4000 },
- { _MMIO(0x9888), 0x04983400 },
- { _MMIO(0x9888), 0x10980000 },
- { _MMIO(0x9888), 0x06990034 },
- { _MMIO(0x9888), 0x10990000 },
- { _MMIO(0x9888), 0x0c9dc000 },
- { _MMIO(0x9888), 0x0e9dc000 },
- { _MMIO(0x9888), 0x009d8000 },
- { _MMIO(0x9888), 0x029dc000 },
- { _MMIO(0x9888), 0x049d4000 },
- { _MMIO(0x9888), 0x109f02a8 },
- { _MMIO(0x9888), 0x0c9fa000 },
- { _MMIO(0x9888), 0x0e9f00ba },
- { _MMIO(0x9888), 0x0cb88000 },
- { _MMIO(0x9888), 0x0cb95000 },
- { _MMIO(0x9888), 0x0eb95000 },
- { _MMIO(0x9888), 0x00b94000 },
- { _MMIO(0x9888), 0x02b95000 },
- { _MMIO(0x9888), 0x04b91000 },
- { _MMIO(0x9888), 0x06b92000 },
- { _MMIO(0x9888), 0x0cba4000 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x03888000 },
- { _MMIO(0x9888), 0x05888000 },
- { _MMIO(0x9888), 0x07888000 },
- { _MMIO(0x9888), 0x09888000 },
- { _MMIO(0x9888), 0x0b888000 },
- { _MMIO(0x9888), 0x0d880400 },
- { _MMIO(0x9888), 0x258b800a },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x238b5500 },
- { _MMIO(0x9888), 0x198c4000 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x038c4000 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x078c4000 },
- { _MMIO(0x9888), 0x098c4000 },
- { _MMIO(0x9888), 0x0b8c4000 },
- { _MMIO(0x9888), 0x0d8c4000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x018d8000 },
- { _MMIO(0x9888), 0x038da000 },
- { _MMIO(0x9888), 0x058da000 },
- { _MMIO(0x9888), 0x078d2000 },
- { _MMIO(0x9888), 0x2185800a },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x1b830154 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x47800000 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f800000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41800060 },
-};
-
-static int
-get_l3_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_1;
- lens[n] = ARRAY_SIZE(mux_config_l3_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_2[] = {
- { _MMIO(0x9888), 0x103f03da },
- { _MMIO(0x9888), 0x143f0001 },
- { _MMIO(0x9888), 0x12180340 },
- { _MMIO(0x9888), 0x12190340 },
- { _MMIO(0x9888), 0x0c3f1187 },
- { _MMIO(0x9888), 0x0e3f1205 },
- { _MMIO(0x9888), 0x003f0500 },
- { _MMIO(0x9888), 0x023f042b },
- { _MMIO(0x9888), 0x043f002c },
- { _MMIO(0x9888), 0x0c5ac000 },
- { _MMIO(0x9888), 0x0e5ac000 },
- { _MMIO(0x9888), 0x005a8000 },
- { _MMIO(0x9888), 0x025ac000 },
- { _MMIO(0x9888), 0x045a4000 },
- { _MMIO(0x9888), 0x04183400 },
- { _MMIO(0x9888), 0x10180000 },
- { _MMIO(0x9888), 0x06190034 },
- { _MMIO(0x9888), 0x10190000 },
- { _MMIO(0x9888), 0x0c1dc000 },
- { _MMIO(0x9888), 0x0e1dc000 },
- { _MMIO(0x9888), 0x001d8000 },
- { _MMIO(0x9888), 0x021dc000 },
- { _MMIO(0x9888), 0x041d4000 },
- { _MMIO(0x9888), 0x101f02a8 },
- { _MMIO(0x9888), 0x0c1fa000 },
- { _MMIO(0x9888), 0x0e1f00ba },
- { _MMIO(0x9888), 0x0c388000 },
- { _MMIO(0x9888), 0x0c395000 },
- { _MMIO(0x9888), 0x0e395000 },
- { _MMIO(0x9888), 0x00394000 },
- { _MMIO(0x9888), 0x02395000 },
- { _MMIO(0x9888), 0x04391000 },
- { _MMIO(0x9888), 0x06392000 },
- { _MMIO(0x9888), 0x0c3a4000 },
- { _MMIO(0x9888), 0x1b8aa800 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x258b4005 },
- { _MMIO(0x9888), 0x278b0015 },
- { _MMIO(0x9888), 0x238b2a80 },
- { _MMIO(0x9888), 0x2185800a },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x1b830154 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x47800000 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f800000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41800060 },
-};
-
-static int
-get_l3_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_2;
- lens[n] = ARRAY_SIZE(mux_config_l3_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_3[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_3[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_3[] = {
- { _MMIO(0x9888), 0x121b0340 },
- { _MMIO(0x9888), 0x103f0274 },
- { _MMIO(0x9888), 0x123f0000 },
- { _MMIO(0x9888), 0x129b0340 },
- { _MMIO(0x9888), 0x10bf0274 },
- { _MMIO(0x9888), 0x12bf0000 },
- { _MMIO(0x9888), 0x041b3400 },
- { _MMIO(0x9888), 0x101b0000 },
- { _MMIO(0x9888), 0x045c8000 },
- { _MMIO(0x9888), 0x0a3d4000 },
- { _MMIO(0x9888), 0x003f0080 },
- { _MMIO(0x9888), 0x023f0793 },
- { _MMIO(0x9888), 0x043f0014 },
- { _MMIO(0x9888), 0x04588000 },
- { _MMIO(0x9888), 0x005a8000 },
- { _MMIO(0x9888), 0x025ac000 },
- { _MMIO(0x9888), 0x045a4000 },
- { _MMIO(0x9888), 0x0a5b4000 },
- { _MMIO(0x9888), 0x001d8000 },
- { _MMIO(0x9888), 0x021dc000 },
- { _MMIO(0x9888), 0x041d4000 },
- { _MMIO(0x9888), 0x0c1fa000 },
- { _MMIO(0x9888), 0x0e1f002a },
- { _MMIO(0x9888), 0x0a384000 },
- { _MMIO(0x9888), 0x00394000 },
- { _MMIO(0x9888), 0x02395000 },
- { _MMIO(0x9888), 0x04399000 },
- { _MMIO(0x9888), 0x069b0034 },
- { _MMIO(0x9888), 0x109b0000 },
- { _MMIO(0x9888), 0x06dc4000 },
- { _MMIO(0x9888), 0x0cbd4000 },
- { _MMIO(0x9888), 0x0cbf0981 },
- { _MMIO(0x9888), 0x0ebf0a0f },
- { _MMIO(0x9888), 0x06d84000 },
- { _MMIO(0x9888), 0x0cdac000 },
- { _MMIO(0x9888), 0x0edac000 },
- { _MMIO(0x9888), 0x0cdb4000 },
- { _MMIO(0x9888), 0x0c9dc000 },
- { _MMIO(0x9888), 0x0e9dc000 },
- { _MMIO(0x9888), 0x109f02a8 },
- { _MMIO(0x9888), 0x0e9f0080 },
- { _MMIO(0x9888), 0x0cb84000 },
- { _MMIO(0x9888), 0x0cb95000 },
- { _MMIO(0x9888), 0x0eb95000 },
- { _MMIO(0x9888), 0x06b92000 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x0d880400 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x258b8009 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x238b2a80 },
- { _MMIO(0x9888), 0x198c4000 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x0d8c4000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x078d2000 },
- { _MMIO(0x9888), 0x2185800a },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x1b830154 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x45800c00 },
- { _MMIO(0x9888), 0x47800c63 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f8014a5 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41800045 },
-};
-
-static int
-get_l3_3_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_3;
- lens[n] = ARRAY_SIZE(mux_config_l3_3);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_4[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_4[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_4[] = {
- { _MMIO(0x9888), 0x121a0340 },
- { _MMIO(0x9888), 0x103f0017 },
- { _MMIO(0x9888), 0x123f0020 },
- { _MMIO(0x9888), 0x129a0340 },
- { _MMIO(0x9888), 0x10bf0017 },
- { _MMIO(0x9888), 0x12bf0020 },
- { _MMIO(0x9888), 0x041a3400 },
- { _MMIO(0x9888), 0x101a0000 },
- { _MMIO(0x9888), 0x043b8000 },
- { _MMIO(0x9888), 0x0a3e0010 },
- { _MMIO(0x9888), 0x003f0200 },
- { _MMIO(0x9888), 0x023f0113 },
- { _MMIO(0x9888), 0x043f0014 },
- { _MMIO(0x9888), 0x02592000 },
- { _MMIO(0x9888), 0x005a8000 },
- { _MMIO(0x9888), 0x025ac000 },
- { _MMIO(0x9888), 0x045a4000 },
- { _MMIO(0x9888), 0x0a1c8000 },
- { _MMIO(0x9888), 0x001d8000 },
- { _MMIO(0x9888), 0x021dc000 },
- { _MMIO(0x9888), 0x041d4000 },
- { _MMIO(0x9888), 0x0a1e8000 },
- { _MMIO(0x9888), 0x0c1fa000 },
- { _MMIO(0x9888), 0x0e1f001a },
- { _MMIO(0x9888), 0x00394000 },
- { _MMIO(0x9888), 0x02395000 },
- { _MMIO(0x9888), 0x04391000 },
- { _MMIO(0x9888), 0x069a0034 },
- { _MMIO(0x9888), 0x109a0000 },
- { _MMIO(0x9888), 0x06bb4000 },
- { _MMIO(0x9888), 0x0abe0040 },
- { _MMIO(0x9888), 0x0cbf0984 },
- { _MMIO(0x9888), 0x0ebf0a02 },
- { _MMIO(0x9888), 0x02d94000 },
- { _MMIO(0x9888), 0x0cdac000 },
- { _MMIO(0x9888), 0x0edac000 },
- { _MMIO(0x9888), 0x0c9c0400 },
- { _MMIO(0x9888), 0x0c9dc000 },
- { _MMIO(0x9888), 0x0e9dc000 },
- { _MMIO(0x9888), 0x0c9e0400 },
- { _MMIO(0x9888), 0x109f02a8 },
- { _MMIO(0x9888), 0x0e9f0040 },
- { _MMIO(0x9888), 0x0cb95000 },
- { _MMIO(0x9888), 0x0eb95000 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x0d880400 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x258b8009 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x238b2a80 },
- { _MMIO(0x9888), 0x198c4000 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x0d8c4000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x078d2000 },
- { _MMIO(0x9888), 0x2185800a },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x1b830154 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x45800800 },
- { _MMIO(0x9888), 0x47800842 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f801084 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41800044 },
-};
-
-static int
-get_l3_4_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_4;
- lens[n] = ARRAY_SIZE(mux_config_l3_4);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00006000 },
- { _MMIO(0x2774), 0x0000f3ff },
- { _MMIO(0x2778), 0x00001800 },
- { _MMIO(0x277c), 0x0000fcff },
- { _MMIO(0x2780), 0x00000600 },
- { _MMIO(0x2784), 0x0000ff3f },
- { _MMIO(0x2788), 0x00000180 },
- { _MMIO(0x278c), 0x0000ffcf },
- { _MMIO(0x2790), 0x00000060 },
- { _MMIO(0x2794), 0x0000fff3 },
- { _MMIO(0x2798), 0x00000018 },
- { _MMIO(0x279c), 0x0000fffc },
-};
-
-static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x9888), 0x143b000e },
- { _MMIO(0x9888), 0x043c55c0 },
- { _MMIO(0x9888), 0x0a1e0280 },
- { _MMIO(0x9888), 0x0c1e0408 },
- { _MMIO(0x9888), 0x10390000 },
- { _MMIO(0x9888), 0x12397a1f },
- { _MMIO(0x9888), 0x14bb000e },
- { _MMIO(0x9888), 0x04bc5000 },
- { _MMIO(0x9888), 0x0a9e0296 },
- { _MMIO(0x9888), 0x0c9e0008 },
- { _MMIO(0x9888), 0x10b90000 },
- { _MMIO(0x9888), 0x12b97a1f },
- { _MMIO(0x9888), 0x063b0042 },
- { _MMIO(0x9888), 0x103b0000 },
- { _MMIO(0x9888), 0x083c0000 },
- { _MMIO(0x9888), 0x0a3e0040 },
- { _MMIO(0x9888), 0x043f8000 },
- { _MMIO(0x9888), 0x02594000 },
- { _MMIO(0x9888), 0x045a8000 },
- { _MMIO(0x9888), 0x0c1c0400 },
- { _MMIO(0x9888), 0x041d8000 },
- { _MMIO(0x9888), 0x081e02c0 },
- { _MMIO(0x9888), 0x0e1e0000 },
- { _MMIO(0x9888), 0x0c1fa800 },
- { _MMIO(0x9888), 0x0e1f0260 },
- { _MMIO(0x9888), 0x101f0014 },
- { _MMIO(0x9888), 0x003905e0 },
- { _MMIO(0x9888), 0x06390bc0 },
- { _MMIO(0x9888), 0x02390018 },
- { _MMIO(0x9888), 0x04394000 },
- { _MMIO(0x9888), 0x04bb0042 },
- { _MMIO(0x9888), 0x10bb0000 },
- { _MMIO(0x9888), 0x02bc05c0 },
- { _MMIO(0x9888), 0x08bc0000 },
- { _MMIO(0x9888), 0x0abe0004 },
- { _MMIO(0x9888), 0x02bf8000 },
- { _MMIO(0x9888), 0x02d91000 },
- { _MMIO(0x9888), 0x02da8000 },
- { _MMIO(0x9888), 0x089c8000 },
- { _MMIO(0x9888), 0x029d8000 },
- { _MMIO(0x9888), 0x089e8000 },
- { _MMIO(0x9888), 0x0e9e0000 },
- { _MMIO(0x9888), 0x0e9fa806 },
- { _MMIO(0x9888), 0x109f0142 },
- { _MMIO(0x9888), 0x08b90617 },
- { _MMIO(0x9888), 0x0ab90be0 },
- { _MMIO(0x9888), 0x02b94000 },
- { _MMIO(0x9888), 0x0d88f000 },
- { _MMIO(0x9888), 0x0f88000c },
- { _MMIO(0x9888), 0x07888000 },
- { _MMIO(0x9888), 0x09888000 },
- { _MMIO(0x9888), 0x018a8000 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x1b8a2800 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x238b52a0 },
- { _MMIO(0x9888), 0x258b6a95 },
- { _MMIO(0x9888), 0x278b0029 },
- { _MMIO(0x9888), 0x178c2000 },
- { _MMIO(0x9888), 0x198c1500 },
- { _MMIO(0x9888), 0x1b8c0014 },
- { _MMIO(0x9888), 0x078c4000 },
- { _MMIO(0x9888), 0x098c4000 },
- { _MMIO(0x9888), 0x098da000 },
- { _MMIO(0x9888), 0x0b8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x038d8000 },
- { _MMIO(0x9888), 0x058d2000 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaaa },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x0784c000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x1780c000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x4d800444 },
- { _MMIO(0x9888), 0x3d800000 },
- { _MMIO(0x9888), 0x4f804000 },
- { _MMIO(0x9888), 0x43801080 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800084 },
- { _MMIO(0x9888), 0x53800044 },
- { _MMIO(0x9888), 0x47801080 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800000 },
- { _MMIO(0x9888), 0x41800840 },
-};
-
-static int
-get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_rasterizer_and_pixel_backend;
- lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_sampler_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x70800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x0000c000 },
- { _MMIO(0x2774), 0x0000e7ff },
- { _MMIO(0x2778), 0x00003000 },
- { _MMIO(0x277c), 0x0000f9ff },
- { _MMIO(0x2780), 0x00000c00 },
- { _MMIO(0x2784), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_sampler_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_sampler_1[] = {
- { _MMIO(0x9888), 0x18921400 },
- { _MMIO(0x9888), 0x149500ab },
- { _MMIO(0x9888), 0x18b21400 },
- { _MMIO(0x9888), 0x14b500ab },
- { _MMIO(0x9888), 0x18d21400 },
- { _MMIO(0x9888), 0x14d500ab },
- { _MMIO(0x9888), 0x0cdc8000 },
- { _MMIO(0x9888), 0x0edc4000 },
- { _MMIO(0x9888), 0x02dcc000 },
- { _MMIO(0x9888), 0x04dcc000 },
- { _MMIO(0x9888), 0x1abd00a0 },
- { _MMIO(0x9888), 0x0abd8000 },
- { _MMIO(0x9888), 0x0cd88000 },
- { _MMIO(0x9888), 0x0ed84000 },
- { _MMIO(0x9888), 0x04d88000 },
- { _MMIO(0x9888), 0x1adb0050 },
- { _MMIO(0x9888), 0x04db8000 },
- { _MMIO(0x9888), 0x06db8000 },
- { _MMIO(0x9888), 0x08db8000 },
- { _MMIO(0x9888), 0x0adb4000 },
- { _MMIO(0x9888), 0x109f02a0 },
- { _MMIO(0x9888), 0x0c9fa000 },
- { _MMIO(0x9888), 0x0e9f00aa },
- { _MMIO(0x9888), 0x18b82500 },
- { _MMIO(0x9888), 0x02b88000 },
- { _MMIO(0x9888), 0x04b84000 },
- { _MMIO(0x9888), 0x06b84000 },
- { _MMIO(0x9888), 0x08b84000 },
- { _MMIO(0x9888), 0x0ab84000 },
- { _MMIO(0x9888), 0x0cb88000 },
- { _MMIO(0x9888), 0x0cb98000 },
- { _MMIO(0x9888), 0x0eb9a000 },
- { _MMIO(0x9888), 0x00b98000 },
- { _MMIO(0x9888), 0x02b9a000 },
- { _MMIO(0x9888), 0x04b9a000 },
- { _MMIO(0x9888), 0x06b92000 },
- { _MMIO(0x9888), 0x1aba0200 },
- { _MMIO(0x9888), 0x02ba8000 },
- { _MMIO(0x9888), 0x0cba8000 },
- { _MMIO(0x9888), 0x04908000 },
- { _MMIO(0x9888), 0x04918000 },
- { _MMIO(0x9888), 0x04927300 },
- { _MMIO(0x9888), 0x10920000 },
- { _MMIO(0x9888), 0x1893000a },
- { _MMIO(0x9888), 0x0a934000 },
- { _MMIO(0x9888), 0x0a946000 },
- { _MMIO(0x9888), 0x0c959000 },
- { _MMIO(0x9888), 0x0e950098 },
- { _MMIO(0x9888), 0x10950000 },
- { _MMIO(0x9888), 0x04b04000 },
- { _MMIO(0x9888), 0x04b14000 },
- { _MMIO(0x9888), 0x04b20073 },
- { _MMIO(0x9888), 0x10b20000 },
- { _MMIO(0x9888), 0x04b38000 },
- { _MMIO(0x9888), 0x06b38000 },
- { _MMIO(0x9888), 0x08b34000 },
- { _MMIO(0x9888), 0x04b4c000 },
- { _MMIO(0x9888), 0x02b59890 },
- { _MMIO(0x9888), 0x10b50000 },
- { _MMIO(0x9888), 0x06d04000 },
- { _MMIO(0x9888), 0x06d14000 },
- { _MMIO(0x9888), 0x06d20073 },
- { _MMIO(0x9888), 0x10d20000 },
- { _MMIO(0x9888), 0x18d30020 },
- { _MMIO(0x9888), 0x02d38000 },
- { _MMIO(0x9888), 0x0cd34000 },
- { _MMIO(0x9888), 0x0ad48000 },
- { _MMIO(0x9888), 0x04d42000 },
- { _MMIO(0x9888), 0x0ed59000 },
- { _MMIO(0x9888), 0x00d59800 },
- { _MMIO(0x9888), 0x10d50000 },
- { _MMIO(0x9888), 0x0f88000e },
- { _MMIO(0x9888), 0x03888000 },
- { _MMIO(0x9888), 0x05888000 },
- { _MMIO(0x9888), 0x07888000 },
- { _MMIO(0x9888), 0x09888000 },
- { _MMIO(0x9888), 0x0b888000 },
- { _MMIO(0x9888), 0x0d880400 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x238b5500 },
- { _MMIO(0x9888), 0x258b000a },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x038c4000 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x078c4000 },
- { _MMIO(0x9888), 0x098c4000 },
- { _MMIO(0x9888), 0x0b8c4000 },
- { _MMIO(0x9888), 0x0d8c4000 },
- { _MMIO(0x9888), 0x0d8d8000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x018d8000 },
- { _MMIO(0x9888), 0x038da000 },
- { _MMIO(0x9888), 0x058da000 },
- { _MMIO(0x9888), 0x078d2000 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x2185000a },
- { _MMIO(0x9888), 0x1b830150 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0d848000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x1d808000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47801021 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f800c64 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41800c02 },
-};
-
-static int
-get_sampler_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_sampler_1;
- lens[n] = ARRAY_SIZE(mux_config_sampler_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_sampler_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x70800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x0000c000 },
- { _MMIO(0x2774), 0x0000e7ff },
- { _MMIO(0x2778), 0x00003000 },
- { _MMIO(0x277c), 0x0000f9ff },
- { _MMIO(0x2780), 0x00000c00 },
- { _MMIO(0x2784), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_sampler_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_sampler_2[] = {
- { _MMIO(0x9888), 0x18121400 },
- { _MMIO(0x9888), 0x141500ab },
- { _MMIO(0x9888), 0x18321400 },
- { _MMIO(0x9888), 0x143500ab },
- { _MMIO(0x9888), 0x18521400 },
- { _MMIO(0x9888), 0x145500ab },
- { _MMIO(0x9888), 0x0c5c8000 },
- { _MMIO(0x9888), 0x0e5c4000 },
- { _MMIO(0x9888), 0x025cc000 },
- { _MMIO(0x9888), 0x045cc000 },
- { _MMIO(0x9888), 0x1a3d00a0 },
- { _MMIO(0x9888), 0x0a3d8000 },
- { _MMIO(0x9888), 0x0c588000 },
- { _MMIO(0x9888), 0x0e584000 },
- { _MMIO(0x9888), 0x04588000 },
- { _MMIO(0x9888), 0x1a5b0050 },
- { _MMIO(0x9888), 0x045b8000 },
- { _MMIO(0x9888), 0x065b8000 },
- { _MMIO(0x9888), 0x085b8000 },
- { _MMIO(0x9888), 0x0a5b4000 },
- { _MMIO(0x9888), 0x101f02a0 },
- { _MMIO(0x9888), 0x0c1fa000 },
- { _MMIO(0x9888), 0x0e1f00aa },
- { _MMIO(0x9888), 0x18382500 },
- { _MMIO(0x9888), 0x02388000 },
- { _MMIO(0x9888), 0x04384000 },
- { _MMIO(0x9888), 0x06384000 },
- { _MMIO(0x9888), 0x08384000 },
- { _MMIO(0x9888), 0x0a384000 },
- { _MMIO(0x9888), 0x0c388000 },
- { _MMIO(0x9888), 0x0c398000 },
- { _MMIO(0x9888), 0x0e39a000 },
- { _MMIO(0x9888), 0x00398000 },
- { _MMIO(0x9888), 0x0239a000 },
- { _MMIO(0x9888), 0x0439a000 },
- { _MMIO(0x9888), 0x06392000 },
- { _MMIO(0x9888), 0x1a3a0200 },
- { _MMIO(0x9888), 0x023a8000 },
- { _MMIO(0x9888), 0x0c3a8000 },
- { _MMIO(0x9888), 0x04108000 },
- { _MMIO(0x9888), 0x04118000 },
- { _MMIO(0x9888), 0x04127300 },
- { _MMIO(0x9888), 0x10120000 },
- { _MMIO(0x9888), 0x1813000a },
- { _MMIO(0x9888), 0x0a134000 },
- { _MMIO(0x9888), 0x0a146000 },
- { _MMIO(0x9888), 0x0c159000 },
- { _MMIO(0x9888), 0x0e150098 },
- { _MMIO(0x9888), 0x10150000 },
- { _MMIO(0x9888), 0x04304000 },
- { _MMIO(0x9888), 0x04314000 },
- { _MMIO(0x9888), 0x04320073 },
- { _MMIO(0x9888), 0x10320000 },
- { _MMIO(0x9888), 0x04338000 },
- { _MMIO(0x9888), 0x06338000 },
- { _MMIO(0x9888), 0x08334000 },
- { _MMIO(0x9888), 0x0434c000 },
- { _MMIO(0x9888), 0x02359890 },
- { _MMIO(0x9888), 0x10350000 },
- { _MMIO(0x9888), 0x06504000 },
- { _MMIO(0x9888), 0x06514000 },
- { _MMIO(0x9888), 0x06520073 },
- { _MMIO(0x9888), 0x10520000 },
- { _MMIO(0x9888), 0x18530020 },
- { _MMIO(0x9888), 0x02538000 },
- { _MMIO(0x9888), 0x0c534000 },
- { _MMIO(0x9888), 0x0a548000 },
- { _MMIO(0x9888), 0x04542000 },
- { _MMIO(0x9888), 0x0e559000 },
- { _MMIO(0x9888), 0x00559800 },
- { _MMIO(0x9888), 0x10550000 },
- { _MMIO(0x9888), 0x1b8aa000 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x278b0015 },
- { _MMIO(0x9888), 0x238b2a80 },
- { _MMIO(0x9888), 0x258b0005 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x2185000a },
- { _MMIO(0x9888), 0x1b830150 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0d848000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x1d808000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47801021 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f800c64 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41800c02 },
-};
-
-static int
-get_sampler_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_sampler_2;
- lens[n] = ARRAY_SIZE(mux_config_sampler_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fdff },
- { _MMIO(0x2778), 0x00000000 },
- { _MMIO(0x277c), 0x0000fe7f },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000ffbf },
- { _MMIO(0x2788), 0x00000000 },
- { _MMIO(0x278c), 0x0000ffcf },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000fff7 },
- { _MMIO(0x2798), 0x00000000 },
- { _MMIO(0x279c), 0x0000fff9 },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_1[] = {
- { _MMIO(0x9888), 0x16154d60 },
- { _MMIO(0x9888), 0x16352e60 },
- { _MMIO(0x9888), 0x16554d60 },
- { _MMIO(0x9888), 0x16950000 },
- { _MMIO(0x9888), 0x16b50000 },
- { _MMIO(0x9888), 0x16d50000 },
- { _MMIO(0x9888), 0x005c8000 },
- { _MMIO(0x9888), 0x045cc000 },
- { _MMIO(0x9888), 0x065c4000 },
- { _MMIO(0x9888), 0x083d8000 },
- { _MMIO(0x9888), 0x0a3d8000 },
- { _MMIO(0x9888), 0x0458c000 },
- { _MMIO(0x9888), 0x025b8000 },
- { _MMIO(0x9888), 0x085b4000 },
- { _MMIO(0x9888), 0x0a5b4000 },
- { _MMIO(0x9888), 0x0c5b8000 },
- { _MMIO(0x9888), 0x0c1fa000 },
- { _MMIO(0x9888), 0x0e1f00aa },
- { _MMIO(0x9888), 0x02384000 },
- { _MMIO(0x9888), 0x04388000 },
- { _MMIO(0x9888), 0x06388000 },
- { _MMIO(0x9888), 0x08384000 },
- { _MMIO(0x9888), 0x0a384000 },
- { _MMIO(0x9888), 0x0c384000 },
- { _MMIO(0x9888), 0x00398000 },
- { _MMIO(0x9888), 0x0239a000 },
- { _MMIO(0x9888), 0x0439a000 },
- { _MMIO(0x9888), 0x06392000 },
- { _MMIO(0x9888), 0x043a8000 },
- { _MMIO(0x9888), 0x063a8000 },
- { _MMIO(0x9888), 0x08138000 },
- { _MMIO(0x9888), 0x0a138000 },
- { _MMIO(0x9888), 0x06143000 },
- { _MMIO(0x9888), 0x0415cfc7 },
- { _MMIO(0x9888), 0x10150000 },
- { _MMIO(0x9888), 0x02338000 },
- { _MMIO(0x9888), 0x0c338000 },
- { _MMIO(0x9888), 0x04342000 },
- { _MMIO(0x9888), 0x06344000 },
- { _MMIO(0x9888), 0x0035c700 },
- { _MMIO(0x9888), 0x063500cf },
- { _MMIO(0x9888), 0x10350000 },
- { _MMIO(0x9888), 0x04538000 },
- { _MMIO(0x9888), 0x06538000 },
- { _MMIO(0x9888), 0x0454c000 },
- { _MMIO(0x9888), 0x0255cfc7 },
- { _MMIO(0x9888), 0x10550000 },
- { _MMIO(0x9888), 0x06dc8000 },
- { _MMIO(0x9888), 0x08dc4000 },
- { _MMIO(0x9888), 0x0cdcc000 },
- { _MMIO(0x9888), 0x0edcc000 },
- { _MMIO(0x9888), 0x1abd00a8 },
- { _MMIO(0x9888), 0x0cd8c000 },
- { _MMIO(0x9888), 0x0ed84000 },
- { _MMIO(0x9888), 0x0edb8000 },
- { _MMIO(0x9888), 0x18db0800 },
- { _MMIO(0x9888), 0x1adb0254 },
- { _MMIO(0x9888), 0x0e9faa00 },
- { _MMIO(0x9888), 0x109f02aa },
- { _MMIO(0x9888), 0x0eb84000 },
- { _MMIO(0x9888), 0x16b84000 },
- { _MMIO(0x9888), 0x18b8156a },
- { _MMIO(0x9888), 0x06b98000 },
- { _MMIO(0x9888), 0x08b9a000 },
- { _MMIO(0x9888), 0x0ab9a000 },
- { _MMIO(0x9888), 0x0cb9a000 },
- { _MMIO(0x9888), 0x0eb9a000 },
- { _MMIO(0x9888), 0x18baa000 },
- { _MMIO(0x9888), 0x1aba0002 },
- { _MMIO(0x9888), 0x16934000 },
- { _MMIO(0x9888), 0x1893000a },
- { _MMIO(0x9888), 0x0a947000 },
- { _MMIO(0x9888), 0x0c95c5c1 },
- { _MMIO(0x9888), 0x0e9500c3 },
- { _MMIO(0x9888), 0x10950000 },
- { _MMIO(0x9888), 0x0eb38000 },
- { _MMIO(0x9888), 0x16b30040 },
- { _MMIO(0x9888), 0x18b30020 },
- { _MMIO(0x9888), 0x06b48000 },
- { _MMIO(0x9888), 0x08b41000 },
- { _MMIO(0x9888), 0x0ab48000 },
- { _MMIO(0x9888), 0x06b5c500 },
- { _MMIO(0x9888), 0x08b500c3 },
- { _MMIO(0x9888), 0x0eb5c100 },
- { _MMIO(0x9888), 0x10b50000 },
- { _MMIO(0x9888), 0x16d31500 },
- { _MMIO(0x9888), 0x08d4e000 },
- { _MMIO(0x9888), 0x08d5c100 },
- { _MMIO(0x9888), 0x0ad5c3c5 },
- { _MMIO(0x9888), 0x10d50000 },
- { _MMIO(0x9888), 0x0d88f800 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x258baaa5 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x238b2a80 },
- { _MMIO(0x9888), 0x0f8c4000 },
- { _MMIO(0x9888), 0x178c2000 },
- { _MMIO(0x9888), 0x198c5500 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x078d8000 },
- { _MMIO(0x9888), 0x098da000 },
- { _MMIO(0x9888), 0x0b8da000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x2185aaaa },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0784c000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1780c000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800c42 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800063 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800800 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f8014a4 },
- { _MMIO(0x9888), 0x41801042 },
-};
-
-static int
-get_tdl_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_1;
- lens[n] = ARRAY_SIZE(mux_config_tdl_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fdff },
- { _MMIO(0x2778), 0x00000000 },
- { _MMIO(0x277c), 0x0000fe7f },
- { _MMIO(0x2780), 0x00000000 },
- { _MMIO(0x2784), 0x0000ff9f },
- { _MMIO(0x2788), 0x00000000 },
- { _MMIO(0x278c), 0x0000ffe7 },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000fffb },
- { _MMIO(0x2798), 0x00000002 },
- { _MMIO(0x279c), 0x0000fffd },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_2[] = {
- { _MMIO(0x9888), 0x16150000 },
- { _MMIO(0x9888), 0x16350000 },
- { _MMIO(0x9888), 0x16550000 },
- { _MMIO(0x9888), 0x16952e60 },
- { _MMIO(0x9888), 0x16b54d60 },
- { _MMIO(0x9888), 0x16d52e60 },
- { _MMIO(0x9888), 0x065c8000 },
- { _MMIO(0x9888), 0x085cc000 },
- { _MMIO(0x9888), 0x0a5cc000 },
- { _MMIO(0x9888), 0x0c5c4000 },
- { _MMIO(0x9888), 0x0e3d8000 },
- { _MMIO(0x9888), 0x183da000 },
- { _MMIO(0x9888), 0x06588000 },
- { _MMIO(0x9888), 0x08588000 },
- { _MMIO(0x9888), 0x0a584000 },
- { _MMIO(0x9888), 0x0e5b4000 },
- { _MMIO(0x9888), 0x185b5800 },
- { _MMIO(0x9888), 0x1a5b000a },
- { _MMIO(0x9888), 0x0e1faa00 },
- { _MMIO(0x9888), 0x101f02aa },
- { _MMIO(0x9888), 0x0e384000 },
- { _MMIO(0x9888), 0x16384000 },
- { _MMIO(0x9888), 0x18382a55 },
- { _MMIO(0x9888), 0x06398000 },
- { _MMIO(0x9888), 0x0839a000 },
- { _MMIO(0x9888), 0x0a39a000 },
- { _MMIO(0x9888), 0x0c39a000 },
- { _MMIO(0x9888), 0x0e39a000 },
- { _MMIO(0x9888), 0x1a3a02a0 },
- { _MMIO(0x9888), 0x0e138000 },
- { _MMIO(0x9888), 0x16130500 },
- { _MMIO(0x9888), 0x06148000 },
- { _MMIO(0x9888), 0x08146000 },
- { _MMIO(0x9888), 0x0615c100 },
- { _MMIO(0x9888), 0x0815c500 },
- { _MMIO(0x9888), 0x0a1500c3 },
- { _MMIO(0x9888), 0x10150000 },
- { _MMIO(0x9888), 0x16335040 },
- { _MMIO(0x9888), 0x08349000 },
- { _MMIO(0x9888), 0x0a341000 },
- { _MMIO(0x9888), 0x083500c1 },
- { _MMIO(0x9888), 0x0a35c500 },
- { _MMIO(0x9888), 0x0c3500c3 },
- { _MMIO(0x9888), 0x10350000 },
- { _MMIO(0x9888), 0x1853002a },
- { _MMIO(0x9888), 0x0a54e000 },
- { _MMIO(0x9888), 0x0c55c500 },
- { _MMIO(0x9888), 0x0e55c1c3 },
- { _MMIO(0x9888), 0x10550000 },
- { _MMIO(0x9888), 0x00dc8000 },
- { _MMIO(0x9888), 0x02dcc000 },
- { _MMIO(0x9888), 0x04dc4000 },
- { _MMIO(0x9888), 0x04bd8000 },
- { _MMIO(0x9888), 0x06bd8000 },
- { _MMIO(0x9888), 0x02d8c000 },
- { _MMIO(0x9888), 0x02db8000 },
- { _MMIO(0x9888), 0x04db4000 },
- { _MMIO(0x9888), 0x06db4000 },
- { _MMIO(0x9888), 0x08db8000 },
- { _MMIO(0x9888), 0x0c9fa000 },
- { _MMIO(0x9888), 0x0e9f00aa },
- { _MMIO(0x9888), 0x02b84000 },
- { _MMIO(0x9888), 0x04b84000 },
- { _MMIO(0x9888), 0x06b84000 },
- { _MMIO(0x9888), 0x08b84000 },
- { _MMIO(0x9888), 0x0ab88000 },
- { _MMIO(0x9888), 0x0cb88000 },
- { _MMIO(0x9888), 0x00b98000 },
- { _MMIO(0x9888), 0x02b9a000 },
- { _MMIO(0x9888), 0x04b9a000 },
- { _MMIO(0x9888), 0x06b92000 },
- { _MMIO(0x9888), 0x0aba8000 },
- { _MMIO(0x9888), 0x0cba8000 },
- { _MMIO(0x9888), 0x04938000 },
- { _MMIO(0x9888), 0x06938000 },
- { _MMIO(0x9888), 0x0494c000 },
- { _MMIO(0x9888), 0x0295cfc7 },
- { _MMIO(0x9888), 0x10950000 },
- { _MMIO(0x9888), 0x02b38000 },
- { _MMIO(0x9888), 0x08b38000 },
- { _MMIO(0x9888), 0x04b42000 },
- { _MMIO(0x9888), 0x06b41000 },
- { _MMIO(0x9888), 0x00b5c700 },
- { _MMIO(0x9888), 0x04b500cf },
- { _MMIO(0x9888), 0x10b50000 },
- { _MMIO(0x9888), 0x0ad38000 },
- { _MMIO(0x9888), 0x0cd38000 },
- { _MMIO(0x9888), 0x06d46000 },
- { _MMIO(0x9888), 0x04d5c700 },
- { _MMIO(0x9888), 0x06d500cf },
- { _MMIO(0x9888), 0x10d50000 },
- { _MMIO(0x9888), 0x03888000 },
- { _MMIO(0x9888), 0x05888000 },
- { _MMIO(0x9888), 0x07888000 },
- { _MMIO(0x9888), 0x09888000 },
- { _MMIO(0x9888), 0x0b888000 },
- { _MMIO(0x9888), 0x0d880400 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x198a8000 },
- { _MMIO(0x9888), 0x1b8aaaa0 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x258b555a },
- { _MMIO(0x9888), 0x278b0015 },
- { _MMIO(0x9888), 0x238b5500 },
- { _MMIO(0x9888), 0x038c4000 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x078c4000 },
- { _MMIO(0x9888), 0x098c4000 },
- { _MMIO(0x9888), 0x0b8c4000 },
- { _MMIO(0x9888), 0x0d8c4000 },
- { _MMIO(0x9888), 0x018d8000 },
- { _MMIO(0x9888), 0x038da000 },
- { _MMIO(0x9888), 0x058da000 },
- { _MMIO(0x9888), 0x078d2000 },
- { _MMIO(0x9888), 0x2185aaaa },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0784c000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1780c000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800882 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45801082 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x478014a5 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f800002 },
- { _MMIO(0x9888), 0x41800c62 },
-};
-
-static int
-get_tdl_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_2;
- lens[n] = ARRAY_SIZE(mux_config_tdl_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extra[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extra[] = {
- { _MMIO(0xe458), 0x00001000 },
- { _MMIO(0xe558), 0x00003002 },
- { _MMIO(0xe658), 0x00005004 },
- { _MMIO(0xe758), 0x00011010 },
- { _MMIO(0xe45c), 0x00050012 },
- { _MMIO(0xe55c), 0x00052051 },
- { _MMIO(0xe65c), 0x00000008 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extra[] = {
- { _MMIO(0x9888), 0x161503e0 },
- { _MMIO(0x9888), 0x163503e0 },
- { _MMIO(0x9888), 0x165503e0 },
- { _MMIO(0x9888), 0x169503e0 },
- { _MMIO(0x9888), 0x16b503e0 },
- { _MMIO(0x9888), 0x16d503e0 },
- { _MMIO(0x9888), 0x045cc000 },
- { _MMIO(0x9888), 0x083d8000 },
- { _MMIO(0x9888), 0x04584000 },
- { _MMIO(0x9888), 0x085b4000 },
- { _MMIO(0x9888), 0x0a5b8000 },
- { _MMIO(0x9888), 0x0e1f00a8 },
- { _MMIO(0x9888), 0x08384000 },
- { _MMIO(0x9888), 0x0a384000 },
- { _MMIO(0x9888), 0x0c388000 },
- { _MMIO(0x9888), 0x0439a000 },
- { _MMIO(0x9888), 0x06392000 },
- { _MMIO(0x9888), 0x0c3a8000 },
- { _MMIO(0x9888), 0x08138000 },
- { _MMIO(0x9888), 0x06141000 },
- { _MMIO(0x9888), 0x041500c3 },
- { _MMIO(0x9888), 0x10150000 },
- { _MMIO(0x9888), 0x0a338000 },
- { _MMIO(0x9888), 0x06342000 },
- { _MMIO(0x9888), 0x0435c300 },
- { _MMIO(0x9888), 0x10350000 },
- { _MMIO(0x9888), 0x0c538000 },
- { _MMIO(0x9888), 0x06544000 },
- { _MMIO(0x9888), 0x065500c3 },
- { _MMIO(0x9888), 0x10550000 },
- { _MMIO(0x9888), 0x00dc8000 },
- { _MMIO(0x9888), 0x02dc4000 },
- { _MMIO(0x9888), 0x02bd8000 },
- { _MMIO(0x9888), 0x00d88000 },
- { _MMIO(0x9888), 0x02db4000 },
- { _MMIO(0x9888), 0x04db8000 },
- { _MMIO(0x9888), 0x0c9fa000 },
- { _MMIO(0x9888), 0x0e9f0002 },
- { _MMIO(0x9888), 0x02b84000 },
- { _MMIO(0x9888), 0x04b84000 },
- { _MMIO(0x9888), 0x06b88000 },
- { _MMIO(0x9888), 0x00b98000 },
- { _MMIO(0x9888), 0x02b9a000 },
- { _MMIO(0x9888), 0x06ba8000 },
- { _MMIO(0x9888), 0x02938000 },
- { _MMIO(0x9888), 0x04942000 },
- { _MMIO(0x9888), 0x0095c300 },
- { _MMIO(0x9888), 0x10950000 },
- { _MMIO(0x9888), 0x04b38000 },
- { _MMIO(0x9888), 0x04b44000 },
- { _MMIO(0x9888), 0x02b500c3 },
- { _MMIO(0x9888), 0x10b50000 },
- { _MMIO(0x9888), 0x06d38000 },
- { _MMIO(0x9888), 0x04d48000 },
- { _MMIO(0x9888), 0x02d5c300 },
- { _MMIO(0x9888), 0x10d50000 },
- { _MMIO(0x9888), 0x03888000 },
- { _MMIO(0x9888), 0x05888000 },
- { _MMIO(0x9888), 0x07888000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x238b3500 },
- { _MMIO(0x9888), 0x258b0005 },
- { _MMIO(0x9888), 0x038c4000 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x078c4000 },
- { _MMIO(0x9888), 0x018d8000 },
- { _MMIO(0x9888), 0x038da000 },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x2185000a },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f800c40 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41801482 },
- { _MMIO(0x9888), 0x31800000 },
-};
-
-static int
-get_compute_extra_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extra;
- lens[n] = ARRAY_SIZE(mux_config_compute_extra);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_vme_pipe[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00100030 },
- { _MMIO(0x2774), 0x0000fff9 },
- { _MMIO(0x2778), 0x00000002 },
- { _MMIO(0x277c), 0x0000fffc },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000fff3 },
- { _MMIO(0x2788), 0x00100180 },
- { _MMIO(0x278c), 0x0000ffcf },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000ffcf },
- { _MMIO(0x2798), 0x00000002 },
- { _MMIO(0x279c), 0x0000ff3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_vme_pipe[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00008003 },
-};
-
-static const struct i915_oa_reg mux_config_vme_pipe[] = {
- { _MMIO(0x9888), 0x14100812 },
- { _MMIO(0x9888), 0x14125800 },
- { _MMIO(0x9888), 0x161200c0 },
- { _MMIO(0x9888), 0x14300812 },
- { _MMIO(0x9888), 0x14325800 },
- { _MMIO(0x9888), 0x163200c0 },
- { _MMIO(0x9888), 0x005c4000 },
- { _MMIO(0x9888), 0x065c8000 },
- { _MMIO(0x9888), 0x085cc000 },
- { _MMIO(0x9888), 0x0a5cc000 },
- { _MMIO(0x9888), 0x0c5cc000 },
- { _MMIO(0x9888), 0x003d8000 },
- { _MMIO(0x9888), 0x0e3d8000 },
- { _MMIO(0x9888), 0x183d2800 },
- { _MMIO(0x9888), 0x00584000 },
- { _MMIO(0x9888), 0x06588000 },
- { _MMIO(0x9888), 0x0858c000 },
- { _MMIO(0x9888), 0x005b4000 },
- { _MMIO(0x9888), 0x0e5b4000 },
- { _MMIO(0x9888), 0x185b9400 },
- { _MMIO(0x9888), 0x1a5b002a },
- { _MMIO(0x9888), 0x0c1f0800 },
- { _MMIO(0x9888), 0x0e1faa00 },
- { _MMIO(0x9888), 0x101f002a },
- { _MMIO(0x9888), 0x00384000 },
- { _MMIO(0x9888), 0x0e384000 },
- { _MMIO(0x9888), 0x16384000 },
- { _MMIO(0x9888), 0x18380155 },
- { _MMIO(0x9888), 0x00392000 },
- { _MMIO(0x9888), 0x06398000 },
- { _MMIO(0x9888), 0x0839a000 },
- { _MMIO(0x9888), 0x0a39a000 },
- { _MMIO(0x9888), 0x0c39a000 },
- { _MMIO(0x9888), 0x00100047 },
- { _MMIO(0x9888), 0x06101a80 },
- { _MMIO(0x9888), 0x10100000 },
- { _MMIO(0x9888), 0x0810c000 },
- { _MMIO(0x9888), 0x0811c000 },
- { _MMIO(0x9888), 0x08126151 },
- { _MMIO(0x9888), 0x10120000 },
- { _MMIO(0x9888), 0x00134000 },
- { _MMIO(0x9888), 0x0e134000 },
- { _MMIO(0x9888), 0x161300a0 },
- { _MMIO(0x9888), 0x0a301ac7 },
- { _MMIO(0x9888), 0x10300000 },
- { _MMIO(0x9888), 0x0c30c000 },
- { _MMIO(0x9888), 0x0c31c000 },
- { _MMIO(0x9888), 0x0c326151 },
- { _MMIO(0x9888), 0x10320000 },
- { _MMIO(0x9888), 0x16332a00 },
- { _MMIO(0x9888), 0x18330001 },
- { _MMIO(0x9888), 0x018a8000 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x198a8000 },
- { _MMIO(0x9888), 0x1b8a2aa0 },
- { _MMIO(0x9888), 0x238b0020 },
- { _MMIO(0x9888), 0x258b5550 },
- { _MMIO(0x9888), 0x278b0001 },
- { _MMIO(0x9888), 0x1f850080 },
- { _MMIO(0x9888), 0x2185aaa0 },
- { _MMIO(0x9888), 0x23850002 },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830015 },
- { _MMIO(0x9888), 0x01844000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x11804000 },
- { _MMIO(0x9888), 0x17808000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3d800800 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800002 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800884 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800002 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
-};
-
-static int
-get_vme_pipe_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_vme_pipe;
- lens[n] = ARRAY_SIZE(mux_config_vme_pipe);
- n++;
-
- return n;
-}
-
static const struct i915_oa_reg b_counter_config_test_oa[] = {
{ _MMIO(0x2740), 0x00000000 },
{ _MMIO(0x2744), 0x00800000 },
@@ -4035,6 +60,7 @@ static const struct i915_oa_reg flex_eu_config_test_oa[] = {
};
static const struct i915_oa_reg mux_config_test_oa[] = {
+ { _MMIO(0x9840), 0x000000a0 },
{ _MMIO(0x9888), 0x198b0000 },
{ _MMIO(0x9888), 0x078b0066 },
{ _MMIO(0x9888), 0x118b0000 },
@@ -4047,1330 +73,38 @@ static const struct i915_oa_reg mux_config_test_oa[] = {
{ _MMIO(0x9888), 0x4f800000 },
{ _MMIO(0x9888), 0x41800000 },
{ _MMIO(0x9888), 0x31800000 },
-};
-
-static int
-get_test_oa_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_test_oa;
- lens[n] = ARRAY_SIZE(mux_config_test_oa);
- n++;
-
- return n;
-}
-
-int i915_oa_select_metric_set_bdw(struct drm_i915_private *dev_priv)
-{
- dev_priv->perf.oa.n_mux_configs = 0;
- dev_priv->perf.oa.b_counter_regs = NULL;
- dev_priv->perf.oa.b_counter_regs_len = 0;
- dev_priv->perf.oa.flex_regs = NULL;
- dev_priv->perf.oa.flex_regs_len = 0;
-
- switch (dev_priv->perf.oa.metrics_set) {
- case METRIC_SET_ID_RENDER_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_render_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_basic);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_basic);
-
- return 0;
- case METRIC_SET_ID_RENDER_PIPE_PROFILE:
- dev_priv->perf.oa.n_mux_configs =
- get_render_pipe_profile_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_pipe_profile;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_pipe_profile);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_pipe_profile;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_pipe_profile);
-
- return 0;
- case METRIC_SET_ID_MEMORY_READS:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_reads_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_reads;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_reads);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_reads;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_reads);
-
- return 0;
- case METRIC_SET_ID_MEMORY_WRITES:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_writes_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_writes;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_writes);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_writes;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_writes);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTENDED:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extended_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extended;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extended);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extended;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extended);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_L3_CACHE:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_l3_cache_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_L3_CACHE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_l3_cache;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_l3_cache);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_l3_cache;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_l3_cache);
-
- return 0;
- case METRIC_SET_ID_DATA_PORT_READS_COALESCING:
- dev_priv->perf.oa.n_mux_configs =
- get_data_port_reads_coalescing_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"DATA_PORT_READS_COALESCING\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_data_port_reads_coalescing;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_data_port_reads_coalescing);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_data_port_reads_coalescing;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_data_port_reads_coalescing);
-
- return 0;
- case METRIC_SET_ID_DATA_PORT_WRITES_COALESCING:
- dev_priv->perf.oa.n_mux_configs =
- get_data_port_writes_coalescing_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"DATA_PORT_WRITES_COALESCING\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_data_port_writes_coalescing;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_data_port_writes_coalescing);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_data_port_writes_coalescing;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_data_port_writes_coalescing);
-
- return 0;
- case METRIC_SET_ID_HDC_AND_SF:
- dev_priv->perf.oa.n_mux_configs =
- get_hdc_and_sf_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_hdc_and_sf;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_hdc_and_sf);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_hdc_and_sf;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_hdc_and_sf);
-
- return 0;
- case METRIC_SET_ID_L3_1:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_1);
-
- return 0;
- case METRIC_SET_ID_L3_2:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_2);
-
- return 0;
- case METRIC_SET_ID_L3_3:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_3_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_3\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_3;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_3);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_3;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_3);
-
- return 0;
- case METRIC_SET_ID_L3_4:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_4_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_4\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_4;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_4);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_4;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_4);
-
- return 0;
- case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND:
- dev_priv->perf.oa.n_mux_configs =
- get_rasterizer_and_pixel_backend_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend);
-
- return 0;
- case METRIC_SET_ID_SAMPLER_1:
- dev_priv->perf.oa.n_mux_configs =
- get_sampler_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_sampler_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_sampler_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_sampler_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_sampler_1);
-
- return 0;
- case METRIC_SET_ID_SAMPLER_2:
- dev_priv->perf.oa.n_mux_configs =
- get_sampler_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_sampler_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_sampler_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_sampler_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_sampler_2);
-
- return 0;
- case METRIC_SET_ID_TDL_1:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_1);
-
- return 0;
- case METRIC_SET_ID_TDL_2:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_2);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTRA:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extra_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTRA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extra;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extra);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extra;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extra);
-
- return 0;
- case METRIC_SET_ID_VME_PIPE:
- dev_priv->perf.oa.n_mux_configs =
- get_vme_pipe_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"VME_PIPE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_vme_pipe;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_vme_pipe);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_vme_pipe;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_vme_pipe);
-
- return 0;
- case METRIC_SET_ID_TEST_OA:
- dev_priv->perf.oa.n_mux_configs =
- get_test_oa_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_test_oa;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_test_oa);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_test_oa;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_test_oa);
-
- return 0;
- default:
- return -ENODEV;
- }
-}
-
-static ssize_t
-show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC);
-}
-
-static struct device_attribute dev_attr_render_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_basic[] = {
- &dev_attr_render_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_basic = {
- .name = "b541bd57-0e0f-4154-b4c0-5858010a2bf7",
- .attrs = attrs_render_basic,
-};
-
-static ssize_t
-show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC);
-}
-
-static struct device_attribute dev_attr_compute_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_basic[] = {
- &dev_attr_compute_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_basic = {
- .name = "35fbc9b2-a891-40a6-a38d-022bb7057552",
- .attrs = attrs_compute_basic,
-};
-
-static ssize_t
-show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE);
-}
-
-static struct device_attribute dev_attr_render_pipe_profile_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_pipe_profile_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_pipe_profile[] = {
- &dev_attr_render_pipe_profile_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_pipe_profile = {
- .name = "233d0544-fff7-4281-8291-e02f222aff72",
- .attrs = attrs_render_pipe_profile,
-};
-
-static ssize_t
-show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS);
-}
-
-static struct device_attribute dev_attr_memory_reads_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_reads_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_reads[] = {
- &dev_attr_memory_reads_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_reads = {
- .name = "2b255d48-2117-4fef-a8f7-f151e1d25a2c",
- .attrs = attrs_memory_reads,
-};
-
-static ssize_t
-show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES);
-}
-
-static struct device_attribute dev_attr_memory_writes_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_writes_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_writes[] = {
- &dev_attr_memory_writes_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_writes = {
- .name = "f7fd3220-b466-4a4d-9f98-b0caf3f2394c",
- .attrs = attrs_memory_writes,
-};
-
-static ssize_t
-show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED);
-}
-
-static struct device_attribute dev_attr_compute_extended_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extended_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extended[] = {
- &dev_attr_compute_extended_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extended = {
- .name = "e99ccaca-821c-4df9-97a7-96bdb7204e43",
- .attrs = attrs_compute_extended,
-};
-
-static ssize_t
-show_compute_l3_cache_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_L3_CACHE);
-}
-
-static struct device_attribute dev_attr_compute_l3_cache_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_l3_cache_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_l3_cache[] = {
- &dev_attr_compute_l3_cache_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_l3_cache = {
- .name = "27a364dc-8225-4ecb-b607-d6f1925598d9",
- .attrs = attrs_compute_l3_cache,
-};
-
-static ssize_t
-show_data_port_reads_coalescing_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_DATA_PORT_READS_COALESCING);
-}
-
-static struct device_attribute dev_attr_data_port_reads_coalescing_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_data_port_reads_coalescing_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_data_port_reads_coalescing[] = {
- &dev_attr_data_port_reads_coalescing_id.attr,
- NULL,
-};
-
-static struct attribute_group group_data_port_reads_coalescing = {
- .name = "857fc630-2f09-4804-85f1-084adfadd5ab",
- .attrs = attrs_data_port_reads_coalescing,
-};
-
-static ssize_t
-show_data_port_writes_coalescing_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_DATA_PORT_WRITES_COALESCING);
-}
-
-static struct device_attribute dev_attr_data_port_writes_coalescing_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_data_port_writes_coalescing_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_data_port_writes_coalescing[] = {
- &dev_attr_data_port_writes_coalescing_id.attr,
- NULL,
-};
-
-static struct attribute_group group_data_port_writes_coalescing = {
- .name = "343ebc99-4a55-414c-8c17-d8e259cf5e20",
- .attrs = attrs_data_port_writes_coalescing,
-};
-
-static ssize_t
-show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF);
-}
-
-static struct device_attribute dev_attr_hdc_and_sf_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_hdc_and_sf_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_hdc_and_sf[] = {
- &dev_attr_hdc_and_sf_id.attr,
- NULL,
-};
-
-static struct attribute_group group_hdc_and_sf = {
- .name = "7bdafd88-a4fa-4ed5-bc09-1a977aa5be3e",
- .attrs = attrs_hdc_and_sf,
-};
-
-static ssize_t
-show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1);
-}
-
-static struct device_attribute dev_attr_l3_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_1[] = {
- &dev_attr_l3_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_1 = {
- .name = "9385ebb2-f34f-4aa5-aec5-7e9cbbea0f0b",
- .attrs = attrs_l3_1,
-};
-
-static ssize_t
-show_l3_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_2);
-}
-
-static struct device_attribute dev_attr_l3_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_2[] = {
- &dev_attr_l3_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_2 = {
- .name = "446ae59b-ff2e-41c9-b49e-0184a54bf00a",
- .attrs = attrs_l3_2,
-};
-
-static ssize_t
-show_l3_3_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_3);
-}
-
-static struct device_attribute dev_attr_l3_3_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_3_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_3[] = {
- &dev_attr_l3_3_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_3 = {
- .name = "84a7956f-1ea4-4d0d-837f-e39a0376e38c",
- .attrs = attrs_l3_3,
-};
-
-static ssize_t
-show_l3_4_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_4);
-}
-
-static struct device_attribute dev_attr_l3_4_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_4_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_4[] = {
- &dev_attr_l3_4_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_4 = {
- .name = "92b493d9-df18-4bed-be06-5cac6f2a6f5f",
- .attrs = attrs_l3_4,
-};
-
-static ssize_t
-show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND);
-}
-
-static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_rasterizer_and_pixel_backend_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_rasterizer_and_pixel_backend[] = {
- &dev_attr_rasterizer_and_pixel_backend_id.attr,
- NULL,
-};
-
-static struct attribute_group group_rasterizer_and_pixel_backend = {
- .name = "14345c35-cc46-40d0-bb04-6ed1fbb43679",
- .attrs = attrs_rasterizer_and_pixel_backend,
-};
-
-static ssize_t
-show_sampler_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER_1);
-}
-
-static struct device_attribute dev_attr_sampler_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_sampler_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_sampler_1[] = {
- &dev_attr_sampler_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_sampler_1 = {
- .name = "f0c6ba37-d3d3-4211-91b5-226730312a54",
- .attrs = attrs_sampler_1,
-};
-
-static ssize_t
-show_sampler_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER_2);
-}
-
-static struct device_attribute dev_attr_sampler_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_sampler_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_sampler_2[] = {
- &dev_attr_sampler_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_sampler_2 = {
- .name = "30bf3702-48cf-4bca-b412-7cf50bb2f564",
- .attrs = attrs_sampler_2,
-};
-
-static ssize_t
-show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1);
-}
-
-static struct device_attribute dev_attr_tdl_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_1[] = {
- &dev_attr_tdl_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_1 = {
- .name = "238bec85-df05-44f3-b905-d166712f2451",
- .attrs = attrs_tdl_1,
-};
-
-static ssize_t
-show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2);
-}
-
-static struct device_attribute dev_attr_tdl_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_2[] = {
- &dev_attr_tdl_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_2 = {
- .name = "24bf02cd-8693-4583-981c-c4165b33da01",
- .attrs = attrs_tdl_2,
-};
-
-static ssize_t
-show_compute_extra_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTRA);
-}
-
-static struct device_attribute dev_attr_compute_extra_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extra_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extra[] = {
- &dev_attr_compute_extra_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extra = {
- .name = "8fb61ba2-2fbb-454c-a136-2dec5a8a595e",
- .attrs = attrs_compute_extra,
-};
-
-static ssize_t
-show_vme_pipe_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_VME_PIPE);
-}
-
-static struct device_attribute dev_attr_vme_pipe_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_vme_pipe_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_vme_pipe[] = {
- &dev_attr_vme_pipe_id.attr,
- NULL,
-};
-
-static struct attribute_group group_vme_pipe = {
- .name = "e1743ca0-7fc8-410b-a066-de7bbb9280b7",
- .attrs = attrs_vme_pipe,
+ { _MMIO(0x9840), 0x00000080 },
};
static ssize_t
show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA);
+ return sprintf(buf, "1\n");
}
-static struct device_attribute dev_attr_test_oa_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_test_oa_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_test_oa[] = {
- &dev_attr_test_oa_id.attr,
- NULL,
-};
-
-static struct attribute_group group_test_oa = {
- .name = "d6de6f55-e526-4f79-a6a6-d7315c09044e",
- .attrs = attrs_test_oa,
-};
-
-int
-i915_perf_register_sysfs_bdw(struct drm_i915_private *dev_priv)
+void
+i915_perf_load_test_config_bdw(struct drm_i915_private *dev_priv)
{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
- int ret = 0;
+ strncpy(dev_priv->perf.oa.test_config.uuid,
+ "d6de6f55-e526-4f79-a6a6-d7315c09044e",
+ UUID_STRING_LEN);
+ dev_priv->perf.oa.test_config.id = 1;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (ret)
- goto error_render_basic;
- }
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (ret)
- goto error_compute_basic;
- }
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (ret)
- goto error_render_pipe_profile;
- }
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (ret)
- goto error_memory_reads;
- }
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (ret)
- goto error_memory_writes;
- }
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (ret)
- goto error_compute_extended;
- }
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (ret)
- goto error_compute_l3_cache;
- }
- if (get_data_port_reads_coalescing_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_data_port_reads_coalescing);
- if (ret)
- goto error_data_port_reads_coalescing;
- }
- if (get_data_port_writes_coalescing_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_data_port_writes_coalescing);
- if (ret)
- goto error_data_port_writes_coalescing;
- }
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (ret)
- goto error_hdc_and_sf;
- }
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (ret)
- goto error_l3_1;
- }
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (ret)
- goto error_l3_2;
- }
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (ret)
- goto error_l3_3;
- }
- if (get_l3_4_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_4);
- if (ret)
- goto error_l3_4;
- }
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (ret)
- goto error_rasterizer_and_pixel_backend;
- }
- if (get_sampler_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler_1);
- if (ret)
- goto error_sampler_1;
- }
- if (get_sampler_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler_2);
- if (ret)
- goto error_sampler_2;
- }
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (ret)
- goto error_tdl_1;
- }
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (ret)
- goto error_tdl_2;
- }
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (ret)
- goto error_compute_extra;
- }
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
- if (ret)
- goto error_vme_pipe;
- }
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa);
- if (ret)
- goto error_test_oa;
- }
+ dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
+ dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
- return 0;
+ dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
+ dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-error_test_oa:
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
-error_vme_pipe:
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
-error_compute_extra:
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
-error_tdl_2:
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
-error_tdl_1:
- if (get_sampler_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_2);
-error_sampler_2:
- if (get_sampler_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_1);
-error_sampler_1:
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
-error_rasterizer_and_pixel_backend:
- if (get_l3_4_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_4);
-error_l3_4:
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
-error_l3_3:
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
-error_l3_2:
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
-error_l3_1:
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
-error_hdc_and_sf:
- if (get_data_port_writes_coalescing_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_data_port_writes_coalescing);
-error_data_port_writes_coalescing:
- if (get_data_port_reads_coalescing_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_data_port_reads_coalescing);
-error_data_port_reads_coalescing:
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
-error_compute_l3_cache:
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
-error_compute_extended:
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
-error_memory_writes:
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
-error_memory_reads:
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
-error_render_pipe_profile:
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
-error_compute_basic:
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
-error_render_basic:
- return ret;
-}
+ dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
+ dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-void
-i915_perf_unregister_sysfs_bdw(struct drm_i915_private *dev_priv)
-{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
+ dev_priv->perf.oa.test_config.sysfs_metric.name = "d6de6f55-e526-4f79-a6a6-d7315c09044e";
+ dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+
+ dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (get_data_port_reads_coalescing_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_data_port_reads_coalescing);
- if (get_data_port_writes_coalescing_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_data_port_writes_coalescing);
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (get_l3_4_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_4);
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (get_sampler_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_1);
- if (get_sampler_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_2);
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa);
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
+ dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
}
diff --git a/drivers/gpu/drm/i915/i915_oa_bdw.h b/drivers/gpu/drm/i915/i915_oa_bdw.h
index 6363ff9..b812d16 100644
--- a/drivers/gpu/drm/i915/i915_oa_bdw.h
+++ b/drivers/gpu/drm/i915/i915_oa_bdw.h
@@ -29,12 +29,6 @@
#ifndef __I915_OA_BDW_H__
#define __I915_OA_BDW_H__
-extern int i915_oa_n_builtin_metric_sets_bdw;
-
-extern int i915_oa_select_metric_set_bdw(struct drm_i915_private *dev_priv);
-
-extern int i915_perf_register_sysfs_bdw(struct drm_i915_private *dev_priv);
-
-extern void i915_perf_unregister_sysfs_bdw(struct drm_i915_private *dev_priv);
+extern void i915_perf_load_test_config_bdw(struct drm_i915_private *dev_priv);
#endif
diff --git a/drivers/gpu/drm/i915/i915_oa_bxt.c b/drivers/gpu/drm/i915/i915_oa_bxt.c
index 93864d8..b69b900 100644
--- a/drivers/gpu/drm/i915/i915_oa_bxt.c
+++ b/drivers/gpu/drm/i915/i915_oa_bxt.c
@@ -31,1702 +31,6 @@
#include "i915_drv.h"
#include "i915_oa_bxt.h"
-enum metric_set_id {
- METRIC_SET_ID_RENDER_BASIC = 1,
- METRIC_SET_ID_COMPUTE_BASIC,
- METRIC_SET_ID_RENDER_PIPE_PROFILE,
- METRIC_SET_ID_MEMORY_READS,
- METRIC_SET_ID_MEMORY_WRITES,
- METRIC_SET_ID_COMPUTE_EXTENDED,
- METRIC_SET_ID_COMPUTE_L3_CACHE,
- METRIC_SET_ID_HDC_AND_SF,
- METRIC_SET_ID_L3_1,
- METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND,
- METRIC_SET_ID_SAMPLER,
- METRIC_SET_ID_TDL_1,
- METRIC_SET_ID_TDL_2,
- METRIC_SET_ID_COMPUTE_EXTRA,
- METRIC_SET_ID_TEST_OA,
-};
-
-int i915_oa_n_builtin_metric_sets_bxt = 15;
-
-static const struct i915_oa_reg b_counter_config_render_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_render_basic_0_sku_gte_0x03[] = {
- { _MMIO(0x9888), 0x166c00f0 },
- { _MMIO(0x9888), 0x12120280 },
- { _MMIO(0x9888), 0x12320280 },
- { _MMIO(0x9888), 0x11930317 },
- { _MMIO(0x9888), 0x159303df },
- { _MMIO(0x9888), 0x3f900c00 },
- { _MMIO(0x9888), 0x419000a0 },
- { _MMIO(0x9888), 0x002d1000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x082d5000 },
- { _MMIO(0x9888), 0x0a2d1000 },
- { _MMIO(0x9888), 0x0c2e0800 },
- { _MMIO(0x9888), 0x0e2e5900 },
- { _MMIO(0x9888), 0x0a4c8000 },
- { _MMIO(0x9888), 0x0c4c8000 },
- { _MMIO(0x9888), 0x0e4c4000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e2000 },
- { _MMIO(0x9888), 0x1c4f0010 },
- { _MMIO(0x9888), 0x0a6c0053 },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1a0fcc00 },
- { _MMIO(0x9888), 0x1c0f0002 },
- { _MMIO(0x9888), 0x1c2c0040 },
- { _MMIO(0x9888), 0x00101000 },
- { _MMIO(0x9888), 0x04101000 },
- { _MMIO(0x9888), 0x00114000 },
- { _MMIO(0x9888), 0x08114000 },
- { _MMIO(0x9888), 0x00120020 },
- { _MMIO(0x9888), 0x08120021 },
- { _MMIO(0x9888), 0x00141000 },
- { _MMIO(0x9888), 0x08141000 },
- { _MMIO(0x9888), 0x02308000 },
- { _MMIO(0x9888), 0x04302000 },
- { _MMIO(0x9888), 0x06318000 },
- { _MMIO(0x9888), 0x08318000 },
- { _MMIO(0x9888), 0x06320800 },
- { _MMIO(0x9888), 0x08320840 },
- { _MMIO(0x9888), 0x00320000 },
- { _MMIO(0x9888), 0x06344000 },
- { _MMIO(0x9888), 0x08344000 },
- { _MMIO(0x9888), 0x0d931831 },
- { _MMIO(0x9888), 0x0f939f3f },
- { _MMIO(0x9888), 0x01939e80 },
- { _MMIO(0x9888), 0x039303bc },
- { _MMIO(0x9888), 0x0593000e },
- { _MMIO(0x9888), 0x1993002a },
- { _MMIO(0x9888), 0x07930000 },
- { _MMIO(0x9888), 0x09930000 },
- { _MMIO(0x9888), 0x1d900177 },
- { _MMIO(0x9888), 0x1f900187 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x23904000 },
- { _MMIO(0x9888), 0x25904000 },
- { _MMIO(0x9888), 0x27904000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x53901110 },
- { _MMIO(0x9888), 0x43900423 },
- { _MMIO(0x9888), 0x55900111 },
- { _MMIO(0x9888), 0x47900c02 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900020 },
- { _MMIO(0x9888), 0x59901111 },
- { _MMIO(0x9888), 0x4b900421 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900001 },
- { _MMIO(0x9888), 0x45900821 },
-};
-
-static int
-get_render_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- if (dev_priv->drm.pdev->revision >= 0x03) {
- regs[n] = mux_config_render_basic_0_sku_gte_0x03;
- lens[n] = ARRAY_SIZE(mux_config_render_basic_0_sku_gte_0x03);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_basic[] = {
- { _MMIO(0x9888), 0x104f00e0 },
- { _MMIO(0x9888), 0x124f1c00 },
- { _MMIO(0x9888), 0x39900340 },
- { _MMIO(0x9888), 0x3f900c00 },
- { _MMIO(0x9888), 0x41900000 },
- { _MMIO(0x9888), 0x002d5000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x082d4000 },
- { _MMIO(0x9888), 0x0a2d1000 },
- { _MMIO(0x9888), 0x0c2d5000 },
- { _MMIO(0x9888), 0x0e2d4000 },
- { _MMIO(0x9888), 0x0c2e1400 },
- { _MMIO(0x9888), 0x0e2e5100 },
- { _MMIO(0x9888), 0x102e0114 },
- { _MMIO(0x9888), 0x044cc000 },
- { _MMIO(0x9888), 0x0a4c8000 },
- { _MMIO(0x9888), 0x0c4c8000 },
- { _MMIO(0x9888), 0x0e4c4000 },
- { _MMIO(0x9888), 0x104c8000 },
- { _MMIO(0x9888), 0x124c8000 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x004ea000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e2000 },
- { _MMIO(0x9888), 0x0c4ea000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x004f6b42 },
- { _MMIO(0x9888), 0x064f6200 },
- { _MMIO(0x9888), 0x084f4100 },
- { _MMIO(0x9888), 0x0a4f0061 },
- { _MMIO(0x9888), 0x0c4f6c4c },
- { _MMIO(0x9888), 0x0e4f4b00 },
- { _MMIO(0x9888), 0x1a4f0000 },
- { _MMIO(0x9888), 0x1c4f0000 },
- { _MMIO(0x9888), 0x180f5000 },
- { _MMIO(0x9888), 0x1a0f8800 },
- { _MMIO(0x9888), 0x1c0f08a2 },
- { _MMIO(0x9888), 0x182c4000 },
- { _MMIO(0x9888), 0x1c2c1451 },
- { _MMIO(0x9888), 0x1e2c0001 },
- { _MMIO(0x9888), 0x1a2c0010 },
- { _MMIO(0x9888), 0x01938000 },
- { _MMIO(0x9888), 0x0f938000 },
- { _MMIO(0x9888), 0x19938a28 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x19900177 },
- { _MMIO(0x9888), 0x1b900178 },
- { _MMIO(0x9888), 0x1d900125 },
- { _MMIO(0x9888), 0x1f900123 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x25904000 },
- { _MMIO(0x9888), 0x27904000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x53901000 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x55900111 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900000 },
- { _MMIO(0x9888), 0x45900000 },
-};
-
-static int
-get_compute_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_basic;
- lens[n] = ARRAY_SIZE(mux_config_compute_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007ffea },
- { _MMIO(0x2774), 0x00007ffc },
- { _MMIO(0x2778), 0x0007affa },
- { _MMIO(0x277c), 0x0000f5fd },
- { _MMIO(0x2780), 0x00079ffa },
- { _MMIO(0x2784), 0x0000f3fb },
- { _MMIO(0x2788), 0x0007bf7a },
- { _MMIO(0x278c), 0x0000f7e7 },
- { _MMIO(0x2790), 0x0007fefa },
- { _MMIO(0x2794), 0x0000f7cf },
- { _MMIO(0x2798), 0x00077ffa },
- { _MMIO(0x279c), 0x0000efdf },
- { _MMIO(0x27a0), 0x0006fffa },
- { _MMIO(0x27a4), 0x0000cfbf },
- { _MMIO(0x27a8), 0x0003fffa },
- { _MMIO(0x27ac), 0x00005f7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_render_pipe_profile[] = {
- { _MMIO(0x9888), 0x0c2e001f },
- { _MMIO(0x9888), 0x0a2f0000 },
- { _MMIO(0x9888), 0x10186800 },
- { _MMIO(0x9888), 0x11810019 },
- { _MMIO(0x9888), 0x15810013 },
- { _MMIO(0x9888), 0x13820020 },
- { _MMIO(0x9888), 0x11830020 },
- { _MMIO(0x9888), 0x17840000 },
- { _MMIO(0x9888), 0x11860007 },
- { _MMIO(0x9888), 0x21860000 },
- { _MMIO(0x9888), 0x178703e0 },
- { _MMIO(0x9888), 0x0c2d8000 },
- { _MMIO(0x9888), 0x042d4000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x022e5400 },
- { _MMIO(0x9888), 0x002e0000 },
- { _MMIO(0x9888), 0x0e2e0080 },
- { _MMIO(0x9888), 0x082f0040 },
- { _MMIO(0x9888), 0x002f0000 },
- { _MMIO(0x9888), 0x06143000 },
- { _MMIO(0x9888), 0x06174000 },
- { _MMIO(0x9888), 0x06180012 },
- { _MMIO(0x9888), 0x00180000 },
- { _MMIO(0x9888), 0x0d804000 },
- { _MMIO(0x9888), 0x0f804000 },
- { _MMIO(0x9888), 0x05804000 },
- { _MMIO(0x9888), 0x09810200 },
- { _MMIO(0x9888), 0x0b810030 },
- { _MMIO(0x9888), 0x03810003 },
- { _MMIO(0x9888), 0x21819140 },
- { _MMIO(0x9888), 0x23819050 },
- { _MMIO(0x9888), 0x25810018 },
- { _MMIO(0x9888), 0x0b820980 },
- { _MMIO(0x9888), 0x03820d80 },
- { _MMIO(0x9888), 0x11820000 },
- { _MMIO(0x9888), 0x0182c000 },
- { _MMIO(0x9888), 0x07828000 },
- { _MMIO(0x9888), 0x09824000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x0d830004 },
- { _MMIO(0x9888), 0x0583000c },
- { _MMIO(0x9888), 0x0f831000 },
- { _MMIO(0x9888), 0x01848072 },
- { _MMIO(0x9888), 0x11840000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x09844000 },
- { _MMIO(0x9888), 0x0f848000 },
- { _MMIO(0x9888), 0x07860000 },
- { _MMIO(0x9888), 0x09860092 },
- { _MMIO(0x9888), 0x0f860400 },
- { _MMIO(0x9888), 0x01869100 },
- { _MMIO(0x9888), 0x0f870065 },
- { _MMIO(0x9888), 0x01870000 },
- { _MMIO(0x9888), 0x19930800 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x1b952000 },
- { _MMIO(0x9888), 0x1d955055 },
- { _MMIO(0x9888), 0x1f951455 },
- { _MMIO(0x9888), 0x0992a000 },
- { _MMIO(0x9888), 0x0f928000 },
- { _MMIO(0x9888), 0x1192a800 },
- { _MMIO(0x9888), 0x1392028a },
- { _MMIO(0x9888), 0x0b92a000 },
- { _MMIO(0x9888), 0x0d922000 },
- { _MMIO(0x9888), 0x13908000 },
- { _MMIO(0x9888), 0x21908000 },
- { _MMIO(0x9888), 0x23908000 },
- { _MMIO(0x9888), 0x25908000 },
- { _MMIO(0x9888), 0x27908000 },
- { _MMIO(0x9888), 0x29908000 },
- { _MMIO(0x9888), 0x2b908000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f908000 },
- { _MMIO(0x9888), 0x31908000 },
- { _MMIO(0x9888), 0x15908000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900c01 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900863 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900061 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900000 },
- { _MMIO(0x9888), 0x45900c22 },
-};
-
-static int
-get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_pipe_profile;
- lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_reads[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f872 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_reads[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_reads[] = {
- { _MMIO(0x9888), 0x19800343 },
- { _MMIO(0x9888), 0x39900340 },
- { _MMIO(0x9888), 0x3f901000 },
- { _MMIO(0x9888), 0x41900003 },
- { _MMIO(0x9888), 0x03803180 },
- { _MMIO(0x9888), 0x058035e2 },
- { _MMIO(0x9888), 0x0780006a },
- { _MMIO(0x9888), 0x11800000 },
- { _MMIO(0x9888), 0x2181a000 },
- { _MMIO(0x9888), 0x2381000a },
- { _MMIO(0x9888), 0x1d950550 },
- { _MMIO(0x9888), 0x0b928000 },
- { _MMIO(0x9888), 0x0d92a000 },
- { _MMIO(0x9888), 0x0f922000 },
- { _MMIO(0x9888), 0x13900170 },
- { _MMIO(0x9888), 0x21900171 },
- { _MMIO(0x9888), 0x23900172 },
- { _MMIO(0x9888), 0x25900173 },
- { _MMIO(0x9888), 0x27900174 },
- { _MMIO(0x9888), 0x29900175 },
- { _MMIO(0x9888), 0x2b900176 },
- { _MMIO(0x9888), 0x2d900177 },
- { _MMIO(0x9888), 0x2f90017f },
- { _MMIO(0x9888), 0x31900125 },
- { _MMIO(0x9888), 0x15900123 },
- { _MMIO(0x9888), 0x17900121 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43901084 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47901080 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49901084 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b901084 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900004 },
- { _MMIO(0x9888), 0x45900000 },
-};
-
-static int
-get_memory_reads_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_reads;
- lens[n] = ARRAY_SIZE(mux_config_memory_reads);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_writes[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f822 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_writes[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_writes[] = {
- { _MMIO(0x9888), 0x19800343 },
- { _MMIO(0x9888), 0x39900340 },
- { _MMIO(0x9888), 0x3f900000 },
- { _MMIO(0x9888), 0x41900080 },
- { _MMIO(0x9888), 0x03803180 },
- { _MMIO(0x9888), 0x058035e2 },
- { _MMIO(0x9888), 0x0780006a },
- { _MMIO(0x9888), 0x11800000 },
- { _MMIO(0x9888), 0x2181a000 },
- { _MMIO(0x9888), 0x2381000a },
- { _MMIO(0x9888), 0x1d950550 },
- { _MMIO(0x9888), 0x0b928000 },
- { _MMIO(0x9888), 0x0d92a000 },
- { _MMIO(0x9888), 0x0f922000 },
- { _MMIO(0x9888), 0x13900180 },
- { _MMIO(0x9888), 0x21900181 },
- { _MMIO(0x9888), 0x23900182 },
- { _MMIO(0x9888), 0x25900183 },
- { _MMIO(0x9888), 0x27900184 },
- { _MMIO(0x9888), 0x29900185 },
- { _MMIO(0x9888), 0x2b900186 },
- { _MMIO(0x9888), 0x2d900187 },
- { _MMIO(0x9888), 0x2f900170 },
- { _MMIO(0x9888), 0x31900125 },
- { _MMIO(0x9888), 0x15900123 },
- { _MMIO(0x9888), 0x17900121 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43901084 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47901080 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49901084 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b901084 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900004 },
- { _MMIO(0x9888), 0x45900000 },
-};
-
-static int
-get_memory_writes_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_writes;
- lens[n] = ARRAY_SIZE(mux_config_memory_writes);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extended[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fc2a },
- { _MMIO(0x2774), 0x0000bf00 },
- { _MMIO(0x2778), 0x0007fc6a },
- { _MMIO(0x277c), 0x0000bf00 },
- { _MMIO(0x2780), 0x0007fc92 },
- { _MMIO(0x2784), 0x0000bf00 },
- { _MMIO(0x2788), 0x0007fca2 },
- { _MMIO(0x278c), 0x0000bf00 },
- { _MMIO(0x2790), 0x0007fc32 },
- { _MMIO(0x2794), 0x0000bf00 },
- { _MMIO(0x2798), 0x0007fc9a },
- { _MMIO(0x279c), 0x0000bf00 },
- { _MMIO(0x27a0), 0x0007fe6a },
- { _MMIO(0x27a4), 0x0000bf00 },
- { _MMIO(0x27a8), 0x0007fe7a },
- { _MMIO(0x27ac), 0x0000bf00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extended[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended[] = {
- { _MMIO(0x9888), 0x104f00e0 },
- { _MMIO(0x9888), 0x141c0160 },
- { _MMIO(0x9888), 0x161c0015 },
- { _MMIO(0x9888), 0x181c0120 },
- { _MMIO(0x9888), 0x002d5000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x082d5000 },
- { _MMIO(0x9888), 0x0a2d5000 },
- { _MMIO(0x9888), 0x0c2d5000 },
- { _MMIO(0x9888), 0x0e2d5000 },
- { _MMIO(0x9888), 0x022d5000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x0c2e5400 },
- { _MMIO(0x9888), 0x0e2e5515 },
- { _MMIO(0x9888), 0x102e0155 },
- { _MMIO(0x9888), 0x044cc000 },
- { _MMIO(0x9888), 0x0a4c8000 },
- { _MMIO(0x9888), 0x0c4cc000 },
- { _MMIO(0x9888), 0x0e4cc000 },
- { _MMIO(0x9888), 0x104c8000 },
- { _MMIO(0x9888), 0x124c8000 },
- { _MMIO(0x9888), 0x144c8000 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x064cc000 },
- { _MMIO(0x9888), 0x084cc000 },
- { _MMIO(0x9888), 0x004ea000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084ea000 },
- { _MMIO(0x9888), 0x0a4ea000 },
- { _MMIO(0x9888), 0x0c4ea000 },
- { _MMIO(0x9888), 0x0e4ea000 },
- { _MMIO(0x9888), 0x024ea000 },
- { _MMIO(0x9888), 0x044ea000 },
- { _MMIO(0x9888), 0x0e4f4b41 },
- { _MMIO(0x9888), 0x004f4200 },
- { _MMIO(0x9888), 0x024f404c },
- { _MMIO(0x9888), 0x1c4f0000 },
- { _MMIO(0x9888), 0x1a4f0000 },
- { _MMIO(0x9888), 0x001b4000 },
- { _MMIO(0x9888), 0x061b8000 },
- { _MMIO(0x9888), 0x081bc000 },
- { _MMIO(0x9888), 0x0a1bc000 },
- { _MMIO(0x9888), 0x0c1bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x001c0031 },
- { _MMIO(0x9888), 0x061c1900 },
- { _MMIO(0x9888), 0x081c1a33 },
- { _MMIO(0x9888), 0x0a1c1b35 },
- { _MMIO(0x9888), 0x0c1c3337 },
- { _MMIO(0x9888), 0x041c31c7 },
- { _MMIO(0x9888), 0x180f5000 },
- { _MMIO(0x9888), 0x1a0fa8aa },
- { _MMIO(0x9888), 0x1c0f0aaa },
- { _MMIO(0x9888), 0x182c8000 },
- { _MMIO(0x9888), 0x1c2c6aaa },
- { _MMIO(0x9888), 0x1e2c0001 },
- { _MMIO(0x9888), 0x1a2c2950 },
- { _MMIO(0x9888), 0x01938000 },
- { _MMIO(0x9888), 0x0f938000 },
- { _MMIO(0x9888), 0x1993aaaa },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x23904000 },
- { _MMIO(0x9888), 0x25904000 },
- { _MMIO(0x9888), 0x27904000 },
- { _MMIO(0x9888), 0x29904000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900420 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900400 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900001 },
- { _MMIO(0x9888), 0x45900001 },
-};
-
-static int
-get_compute_extended_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extended;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_l3_cache[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fffa },
- { _MMIO(0x2774), 0x0000fefe },
- { _MMIO(0x2778), 0x0007fffa },
- { _MMIO(0x277c), 0x0000fefd },
- { _MMIO(0x2790), 0x0007fffa },
- { _MMIO(0x2794), 0x0000fbef },
- { _MMIO(0x2798), 0x0007fffa },
- { _MMIO(0x279c), 0x0000fbdf },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_l3_cache[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00101100 },
- { _MMIO(0xe45c), 0x00201200 },
- { _MMIO(0xe55c), 0x00301300 },
- { _MMIO(0xe65c), 0x00401400 },
-};
-
-static const struct i915_oa_reg mux_config_compute_l3_cache[] = {
- { _MMIO(0x9888), 0x166c03b0 },
- { _MMIO(0x9888), 0x1593001e },
- { _MMIO(0x9888), 0x3f900c00 },
- { _MMIO(0x9888), 0x41900000 },
- { _MMIO(0x9888), 0x002d1000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x082d5000 },
- { _MMIO(0x9888), 0x0e2d5000 },
- { _MMIO(0x9888), 0x0c2e0400 },
- { _MMIO(0x9888), 0x0e2e1500 },
- { _MMIO(0x9888), 0x102e0140 },
- { _MMIO(0x9888), 0x044c4000 },
- { _MMIO(0x9888), 0x0a4c8000 },
- { _MMIO(0x9888), 0x0c4cc000 },
- { _MMIO(0x9888), 0x144c8000 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x004e2000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084ea000 },
- { _MMIO(0x9888), 0x0e4ea000 },
- { _MMIO(0x9888), 0x1a4f4001 },
- { _MMIO(0x9888), 0x1c4f5005 },
- { _MMIO(0x9888), 0x006c0051 },
- { _MMIO(0x9888), 0x066c5000 },
- { _MMIO(0x9888), 0x086c5c5d },
- { _MMIO(0x9888), 0x0e6c5e5f },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x146c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x180f1000 },
- { _MMIO(0x9888), 0x1a0fa800 },
- { _MMIO(0x9888), 0x1c0f0a00 },
- { _MMIO(0x9888), 0x182c4000 },
- { _MMIO(0x9888), 0x1c2c4015 },
- { _MMIO(0x9888), 0x1e2c0001 },
- { _MMIO(0x9888), 0x03931980 },
- { _MMIO(0x9888), 0x05930032 },
- { _MMIO(0x9888), 0x11930000 },
- { _MMIO(0x9888), 0x01938000 },
- { _MMIO(0x9888), 0x0f938000 },
- { _MMIO(0x9888), 0x1993a00a },
- { _MMIO(0x9888), 0x07930000 },
- { _MMIO(0x9888), 0x09930000 },
- { _MMIO(0x9888), 0x1d900177 },
- { _MMIO(0x9888), 0x1f900178 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x23904000 },
- { _MMIO(0x9888), 0x25904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x53901000 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x55900111 },
- { _MMIO(0x9888), 0x47900001 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x4d900000 },
- { _MMIO(0x9888), 0x45900400 },
-};
-
-static int
-get_compute_l3_cache_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_l3_cache;
- lens[n] = ARRAY_SIZE(mux_config_compute_l3_cache);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x10800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fdff },
-};
-
-static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_hdc_and_sf[] = {
- { _MMIO(0x9888), 0x104f0232 },
- { _MMIO(0x9888), 0x124f4640 },
- { _MMIO(0x9888), 0x11834400 },
- { _MMIO(0x9888), 0x022d4000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x0e2e0055 },
- { _MMIO(0x9888), 0x064c8000 },
- { _MMIO(0x9888), 0x084cc000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x024e8000 },
- { _MMIO(0x9888), 0x044ea000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x024f6100 },
- { _MMIO(0x9888), 0x044f416b },
- { _MMIO(0x9888), 0x064f004b },
- { _MMIO(0x9888), 0x1a4f0000 },
- { _MMIO(0x9888), 0x1a0f02a8 },
- { _MMIO(0x9888), 0x1a2c5500 },
- { _MMIO(0x9888), 0x0f808000 },
- { _MMIO(0x9888), 0x25810020 },
- { _MMIO(0x9888), 0x0f8305c0 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x1f951000 },
- { _MMIO(0x9888), 0x13920200 },
- { _MMIO(0x9888), 0x31908000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4d900003 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_hdc_and_sf;
- lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_1_0_sku_gte_0x03[] = {
- { _MMIO(0x9888), 0x12643400 },
- { _MMIO(0x9888), 0x12653400 },
- { _MMIO(0x9888), 0x106c6800 },
- { _MMIO(0x9888), 0x126c001e },
- { _MMIO(0x9888), 0x166c0010 },
- { _MMIO(0x9888), 0x0c2d5000 },
- { _MMIO(0x9888), 0x0e2d5000 },
- { _MMIO(0x9888), 0x002d4000 },
- { _MMIO(0x9888), 0x022d5000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x102e0154 },
- { _MMIO(0x9888), 0x0c2e5000 },
- { _MMIO(0x9888), 0x0e2e0055 },
- { _MMIO(0x9888), 0x104c8000 },
- { _MMIO(0x9888), 0x124c8000 },
- { _MMIO(0x9888), 0x144c8000 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x044c8000 },
- { _MMIO(0x9888), 0x064cc000 },
- { _MMIO(0x9888), 0x084cc000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x0c4ea000 },
- { _MMIO(0x9888), 0x0e4ea000 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x024ea000 },
- { _MMIO(0x9888), 0x044ea000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x1c4f5500 },
- { _MMIO(0x9888), 0x1a4f1554 },
- { _MMIO(0x9888), 0x0a640024 },
- { _MMIO(0x9888), 0x10640000 },
- { _MMIO(0x9888), 0x04640000 },
- { _MMIO(0x9888), 0x0c650024 },
- { _MMIO(0x9888), 0x10650000 },
- { _MMIO(0x9888), 0x06650000 },
- { _MMIO(0x9888), 0x0c6c5327 },
- { _MMIO(0x9888), 0x0e6c5425 },
- { _MMIO(0x9888), 0x006c2a00 },
- { _MMIO(0x9888), 0x026c285b },
- { _MMIO(0x9888), 0x046c005c },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1a6c0900 },
- { _MMIO(0x9888), 0x1c0f0aa0 },
- { _MMIO(0x9888), 0x180f4000 },
- { _MMIO(0x9888), 0x1a0f02aa },
- { _MMIO(0x9888), 0x1c2c5400 },
- { _MMIO(0x9888), 0x1e2c0001 },
- { _MMIO(0x9888), 0x1a2c5550 },
- { _MMIO(0x9888), 0x1993aa00 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900421 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900001 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900420 },
- { _MMIO(0x9888), 0x45900021 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900000 },
-};
-
-static const struct i915_oa_reg mux_config_l3_1_0_sku_lt_0x03[] = {
- { _MMIO(0x9888), 0x14640340 },
- { _MMIO(0x9888), 0x14650340 },
- { _MMIO(0x9888), 0x106c6800 },
- { _MMIO(0x9888), 0x126c001e },
- { _MMIO(0x9888), 0x166c0010 },
- { _MMIO(0x9888), 0x0c2d5000 },
- { _MMIO(0x9888), 0x0e2d5000 },
- { _MMIO(0x9888), 0x002d4000 },
- { _MMIO(0x9888), 0x022d5000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x102e0154 },
- { _MMIO(0x9888), 0x0c2e5000 },
- { _MMIO(0x9888), 0x0e2e0055 },
- { _MMIO(0x9888), 0x104c8000 },
- { _MMIO(0x9888), 0x124c8000 },
- { _MMIO(0x9888), 0x144c8000 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x044c8000 },
- { _MMIO(0x9888), 0x064cc000 },
- { _MMIO(0x9888), 0x084cc000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x0c4ea000 },
- { _MMIO(0x9888), 0x0e4ea000 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x024ea000 },
- { _MMIO(0x9888), 0x044ea000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x1c4f5500 },
- { _MMIO(0x9888), 0x1a4f1554 },
- { _MMIO(0x9888), 0x04642400 },
- { _MMIO(0x9888), 0x22640000 },
- { _MMIO(0x9888), 0x1a640000 },
- { _MMIO(0x9888), 0x06650024 },
- { _MMIO(0x9888), 0x22650000 },
- { _MMIO(0x9888), 0x1c650000 },
- { _MMIO(0x9888), 0x0c6c5327 },
- { _MMIO(0x9888), 0x0e6c5425 },
- { _MMIO(0x9888), 0x006c2a00 },
- { _MMIO(0x9888), 0x026c285b },
- { _MMIO(0x9888), 0x046c005c },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1a6c0900 },
- { _MMIO(0x9888), 0x1c0f0aa0 },
- { _MMIO(0x9888), 0x180f4000 },
- { _MMIO(0x9888), 0x1a0f02aa },
- { _MMIO(0x9888), 0x1c2c5400 },
- { _MMIO(0x9888), 0x1e2c0001 },
- { _MMIO(0x9888), 0x1a2c5550 },
- { _MMIO(0x9888), 0x1993aa00 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900421 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900001 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900420 },
- { _MMIO(0x9888), 0x45900021 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900000 },
-};
-
-static int
-get_l3_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 2);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 2);
-
- if (dev_priv->drm.pdev->revision >= 0x03) {
- regs[n] = mux_config_l3_1_0_sku_gte_0x03;
- lens[n] = ARRAY_SIZE(mux_config_l3_1_0_sku_gte_0x03);
- n++;
- }
- if (dev_priv->drm.pdev->revision < 0x03) {
- regs[n] = mux_config_l3_1_0_sku_lt_0x03;
- lens[n] = ARRAY_SIZE(mux_config_l3_1_0_sku_lt_0x03);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000efff },
- { _MMIO(0x2778), 0x00006000 },
- { _MMIO(0x277c), 0x0000f3ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x9888), 0x102d7800 },
- { _MMIO(0x9888), 0x122d79e0 },
- { _MMIO(0x9888), 0x0c2f0004 },
- { _MMIO(0x9888), 0x100e3800 },
- { _MMIO(0x9888), 0x180f0005 },
- { _MMIO(0x9888), 0x002d0940 },
- { _MMIO(0x9888), 0x022d802f },
- { _MMIO(0x9888), 0x042d4013 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x0e2e0050 },
- { _MMIO(0x9888), 0x022f0010 },
- { _MMIO(0x9888), 0x002f0000 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x040e0480 },
- { _MMIO(0x9888), 0x000e0000 },
- { _MMIO(0x9888), 0x060f0027 },
- { _MMIO(0x9888), 0x100f0000 },
- { _MMIO(0x9888), 0x1a0f0040 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x439014a0 },
- { _MMIO(0x9888), 0x459000a4 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900001 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_rasterizer_and_pixel_backend;
- lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_sampler[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x70800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x0000c000 },
- { _MMIO(0x2774), 0x0000e7ff },
- { _MMIO(0x2778), 0x00003000 },
- { _MMIO(0x277c), 0x0000f9ff },
- { _MMIO(0x2780), 0x00000c00 },
- { _MMIO(0x2784), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_sampler[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_sampler[] = {
- { _MMIO(0x9888), 0x121300a0 },
- { _MMIO(0x9888), 0x141600ab },
- { _MMIO(0x9888), 0x123300a0 },
- { _MMIO(0x9888), 0x143600ab },
- { _MMIO(0x9888), 0x125300a0 },
- { _MMIO(0x9888), 0x145600ab },
- { _MMIO(0x9888), 0x0c2d4000 },
- { _MMIO(0x9888), 0x0e2d5000 },
- { _MMIO(0x9888), 0x002d4000 },
- { _MMIO(0x9888), 0x022d5000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x102e01a0 },
- { _MMIO(0x9888), 0x0c2e5000 },
- { _MMIO(0x9888), 0x0e2e0065 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x044c8000 },
- { _MMIO(0x9888), 0x064cc000 },
- { _MMIO(0x9888), 0x084c4000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x024ea000 },
- { _MMIO(0x9888), 0x044e2000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x1c0f0800 },
- { _MMIO(0x9888), 0x180f4000 },
- { _MMIO(0x9888), 0x1a0f023f },
- { _MMIO(0x9888), 0x1e2c0003 },
- { _MMIO(0x9888), 0x1a2cc030 },
- { _MMIO(0x9888), 0x04132180 },
- { _MMIO(0x9888), 0x02130000 },
- { _MMIO(0x9888), 0x0c148000 },
- { _MMIO(0x9888), 0x0e142000 },
- { _MMIO(0x9888), 0x04148000 },
- { _MMIO(0x9888), 0x1e150140 },
- { _MMIO(0x9888), 0x1c150040 },
- { _MMIO(0x9888), 0x0c163000 },
- { _MMIO(0x9888), 0x0e160068 },
- { _MMIO(0x9888), 0x10160000 },
- { _MMIO(0x9888), 0x18160000 },
- { _MMIO(0x9888), 0x0a164000 },
- { _MMIO(0x9888), 0x04330043 },
- { _MMIO(0x9888), 0x02330000 },
- { _MMIO(0x9888), 0x0234a000 },
- { _MMIO(0x9888), 0x04342000 },
- { _MMIO(0x9888), 0x1c350015 },
- { _MMIO(0x9888), 0x02363460 },
- { _MMIO(0x9888), 0x10360000 },
- { _MMIO(0x9888), 0x04360000 },
- { _MMIO(0x9888), 0x06360000 },
- { _MMIO(0x9888), 0x08364000 },
- { _MMIO(0x9888), 0x06530043 },
- { _MMIO(0x9888), 0x02530000 },
- { _MMIO(0x9888), 0x0e548000 },
- { _MMIO(0x9888), 0x00548000 },
- { _MMIO(0x9888), 0x06542000 },
- { _MMIO(0x9888), 0x1e550400 },
- { _MMIO(0x9888), 0x1a552000 },
- { _MMIO(0x9888), 0x1c550100 },
- { _MMIO(0x9888), 0x0e563000 },
- { _MMIO(0x9888), 0x00563400 },
- { _MMIO(0x9888), 0x10560000 },
- { _MMIO(0x9888), 0x18560000 },
- { _MMIO(0x9888), 0x02560000 },
- { _MMIO(0x9888), 0x0c564000 },
- { _MMIO(0x9888), 0x1993a800 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b9014a0 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900001 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900820 },
- { _MMIO(0x9888), 0x45901022 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900000 },
-};
-
-static int
-get_sampler_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_sampler;
- lens[n] = ARRAY_SIZE(mux_config_sampler);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x00007fff },
- { _MMIO(0x2778), 0x00000000 },
- { _MMIO(0x277c), 0x00009fff },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000efff },
- { _MMIO(0x2788), 0x00000000 },
- { _MMIO(0x278c), 0x0000f3ff },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000fdff },
- { _MMIO(0x2798), 0x00000000 },
- { _MMIO(0x279c), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_1[] = {
- { _MMIO(0x9888), 0x141a0000 },
- { _MMIO(0x9888), 0x143a0000 },
- { _MMIO(0x9888), 0x145a0000 },
- { _MMIO(0x9888), 0x0c2d4000 },
- { _MMIO(0x9888), 0x0e2d5000 },
- { _MMIO(0x9888), 0x002d4000 },
- { _MMIO(0x9888), 0x022d5000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x102e0150 },
- { _MMIO(0x9888), 0x0c2e5000 },
- { _MMIO(0x9888), 0x0e2e006a },
- { _MMIO(0x9888), 0x124c8000 },
- { _MMIO(0x9888), 0x144c8000 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x044c8000 },
- { _MMIO(0x9888), 0x064c4000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x0c4e8000 },
- { _MMIO(0x9888), 0x0e4ea000 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x024e2000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x1c0f0bc0 },
- { _MMIO(0x9888), 0x180f4000 },
- { _MMIO(0x9888), 0x1a0f0302 },
- { _MMIO(0x9888), 0x1e2c0003 },
- { _MMIO(0x9888), 0x1a2c00f0 },
- { _MMIO(0x9888), 0x021a3080 },
- { _MMIO(0x9888), 0x041a31e5 },
- { _MMIO(0x9888), 0x02148000 },
- { _MMIO(0x9888), 0x0414a000 },
- { _MMIO(0x9888), 0x1c150054 },
- { _MMIO(0x9888), 0x06168000 },
- { _MMIO(0x9888), 0x08168000 },
- { _MMIO(0x9888), 0x0a168000 },
- { _MMIO(0x9888), 0x0c3a3280 },
- { _MMIO(0x9888), 0x0e3a0063 },
- { _MMIO(0x9888), 0x063a0061 },
- { _MMIO(0x9888), 0x023a0000 },
- { _MMIO(0x9888), 0x0c348000 },
- { _MMIO(0x9888), 0x0e342000 },
- { _MMIO(0x9888), 0x06342000 },
- { _MMIO(0x9888), 0x1e350140 },
- { _MMIO(0x9888), 0x1c350100 },
- { _MMIO(0x9888), 0x18360028 },
- { _MMIO(0x9888), 0x0c368000 },
- { _MMIO(0x9888), 0x0e5a3080 },
- { _MMIO(0x9888), 0x005a3280 },
- { _MMIO(0x9888), 0x025a0063 },
- { _MMIO(0x9888), 0x0e548000 },
- { _MMIO(0x9888), 0x00548000 },
- { _MMIO(0x9888), 0x02542000 },
- { _MMIO(0x9888), 0x1e550400 },
- { _MMIO(0x9888), 0x1a552000 },
- { _MMIO(0x9888), 0x1c550001 },
- { _MMIO(0x9888), 0x18560080 },
- { _MMIO(0x9888), 0x02568000 },
- { _MMIO(0x9888), 0x04568000 },
- { _MMIO(0x9888), 0x1993a800 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900420 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x45901084 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900001 },
-};
-
-static int
-get_tdl_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_1;
- lens[n] = ARRAY_SIZE(mux_config_tdl_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_2[] = {
- { _MMIO(0x9888), 0x141a026b },
- { _MMIO(0x9888), 0x143a0173 },
- { _MMIO(0x9888), 0x145a026b },
- { _MMIO(0x9888), 0x002d4000 },
- { _MMIO(0x9888), 0x022d5000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x0c2e5000 },
- { _MMIO(0x9888), 0x0e2e0069 },
- { _MMIO(0x9888), 0x044c8000 },
- { _MMIO(0x9888), 0x064cc000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x024ea000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x180f6000 },
- { _MMIO(0x9888), 0x1a0f030a },
- { _MMIO(0x9888), 0x1a2c03c0 },
- { _MMIO(0x9888), 0x041a37e7 },
- { _MMIO(0x9888), 0x021a0000 },
- { _MMIO(0x9888), 0x0414a000 },
- { _MMIO(0x9888), 0x1c150050 },
- { _MMIO(0x9888), 0x08168000 },
- { _MMIO(0x9888), 0x0a168000 },
- { _MMIO(0x9888), 0x003a3380 },
- { _MMIO(0x9888), 0x063a006f },
- { _MMIO(0x9888), 0x023a0000 },
- { _MMIO(0x9888), 0x00348000 },
- { _MMIO(0x9888), 0x06342000 },
- { _MMIO(0x9888), 0x1a352000 },
- { _MMIO(0x9888), 0x1c350100 },
- { _MMIO(0x9888), 0x02368000 },
- { _MMIO(0x9888), 0x0c368000 },
- { _MMIO(0x9888), 0x025a37e7 },
- { _MMIO(0x9888), 0x0254a000 },
- { _MMIO(0x9888), 0x1c550005 },
- { _MMIO(0x9888), 0x04568000 },
- { _MMIO(0x9888), 0x06568000 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900020 },
- { _MMIO(0x9888), 0x45901080 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900001 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_tdl_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_2;
- lens[n] = ARRAY_SIZE(mux_config_tdl_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extra[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extra[] = {
- { _MMIO(0xe458), 0x00001000 },
- { _MMIO(0xe558), 0x00003002 },
- { _MMIO(0xe658), 0x00005004 },
- { _MMIO(0xe758), 0x00011010 },
- { _MMIO(0xe45c), 0x00050012 },
- { _MMIO(0xe55c), 0x00052051 },
- { _MMIO(0xe65c), 0x00000008 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extra[] = {
- { _MMIO(0x9888), 0x141a001f },
- { _MMIO(0x9888), 0x143a001f },
- { _MMIO(0x9888), 0x145a001f },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x0e2e0094 },
- { _MMIO(0x9888), 0x084cc000 },
- { _MMIO(0x9888), 0x044ea000 },
- { _MMIO(0x9888), 0x1a0f00e0 },
- { _MMIO(0x9888), 0x1a2c0c00 },
- { _MMIO(0x9888), 0x061a0063 },
- { _MMIO(0x9888), 0x021a0000 },
- { _MMIO(0x9888), 0x06142000 },
- { _MMIO(0x9888), 0x1c150100 },
- { _MMIO(0x9888), 0x0c168000 },
- { _MMIO(0x9888), 0x043a3180 },
- { _MMIO(0x9888), 0x023a0000 },
- { _MMIO(0x9888), 0x04348000 },
- { _MMIO(0x9888), 0x1c350040 },
- { _MMIO(0x9888), 0x0a368000 },
- { _MMIO(0x9888), 0x045a0063 },
- { _MMIO(0x9888), 0x025a0000 },
- { _MMIO(0x9888), 0x04542000 },
- { _MMIO(0x9888), 0x1c550010 },
- { _MMIO(0x9888), 0x08568000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900400 },
- { _MMIO(0x9888), 0x47900004 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_compute_extra_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extra;
- lens[n] = ARRAY_SIZE(mux_config_compute_extra);
- n++;
-
- return n;
-}
-
static const struct i915_oa_reg b_counter_config_test_oa[] = {
{ _MMIO(0x2740), 0x00000000 },
{ _MMIO(0x2744), 0x00800000 },
@@ -1756,6 +60,7 @@ static const struct i915_oa_reg flex_eu_config_test_oa[] = {
};
static const struct i915_oa_reg mux_config_test_oa[] = {
+ { _MMIO(0x9840), 0x00000080 },
{ _MMIO(0x9888), 0x19800000 },
{ _MMIO(0x9888), 0x07800063 },
{ _MMIO(0x9888), 0x11800000 },
@@ -1769,922 +74,35 @@ static const struct i915_oa_reg mux_config_test_oa[] = {
{ _MMIO(0x9888), 0x33900000 },
};
-static int
-get_test_oa_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_test_oa;
- lens[n] = ARRAY_SIZE(mux_config_test_oa);
- n++;
-
- return n;
-}
-
-int i915_oa_select_metric_set_bxt(struct drm_i915_private *dev_priv)
-{
- dev_priv->perf.oa.n_mux_configs = 0;
- dev_priv->perf.oa.b_counter_regs = NULL;
- dev_priv->perf.oa.b_counter_regs_len = 0;
- dev_priv->perf.oa.flex_regs = NULL;
- dev_priv->perf.oa.flex_regs_len = 0;
-
- switch (dev_priv->perf.oa.metrics_set) {
- case METRIC_SET_ID_RENDER_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_render_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_basic);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_basic);
-
- return 0;
- case METRIC_SET_ID_RENDER_PIPE_PROFILE:
- dev_priv->perf.oa.n_mux_configs =
- get_render_pipe_profile_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_pipe_profile;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_pipe_profile);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_pipe_profile;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_pipe_profile);
-
- return 0;
- case METRIC_SET_ID_MEMORY_READS:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_reads_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_reads;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_reads);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_reads;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_reads);
-
- return 0;
- case METRIC_SET_ID_MEMORY_WRITES:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_writes_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_writes;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_writes);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_writes;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_writes);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTENDED:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extended_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extended;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extended);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extended;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extended);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_L3_CACHE:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_l3_cache_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_L3_CACHE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_l3_cache;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_l3_cache);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_l3_cache;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_l3_cache);
-
- return 0;
- case METRIC_SET_ID_HDC_AND_SF:
- dev_priv->perf.oa.n_mux_configs =
- get_hdc_and_sf_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_hdc_and_sf;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_hdc_and_sf);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_hdc_and_sf;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_hdc_and_sf);
-
- return 0;
- case METRIC_SET_ID_L3_1:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_1);
-
- return 0;
- case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND:
- dev_priv->perf.oa.n_mux_configs =
- get_rasterizer_and_pixel_backend_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend);
-
- return 0;
- case METRIC_SET_ID_SAMPLER:
- dev_priv->perf.oa.n_mux_configs =
- get_sampler_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_sampler;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_sampler);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_sampler;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_sampler);
-
- return 0;
- case METRIC_SET_ID_TDL_1:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_1);
-
- return 0;
- case METRIC_SET_ID_TDL_2:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_2);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTRA:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extra_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTRA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extra;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extra);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extra;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extra);
-
- return 0;
- case METRIC_SET_ID_TEST_OA:
- dev_priv->perf.oa.n_mux_configs =
- get_test_oa_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_test_oa;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_test_oa);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_test_oa;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_test_oa);
-
- return 0;
- default:
- return -ENODEV;
- }
-}
-
-static ssize_t
-show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC);
-}
-
-static struct device_attribute dev_attr_render_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_basic[] = {
- &dev_attr_render_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_basic = {
- .name = "22b9519a-e9ba-4c41-8b54-f4f8ca14fa0a",
- .attrs = attrs_render_basic,
-};
-
-static ssize_t
-show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC);
-}
-
-static struct device_attribute dev_attr_compute_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_basic[] = {
- &dev_attr_compute_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_basic = {
- .name = "012d72cf-82a9-4d25-8ddf-74076fd30797",
- .attrs = attrs_compute_basic,
-};
-
-static ssize_t
-show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE);
-}
-
-static struct device_attribute dev_attr_render_pipe_profile_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_pipe_profile_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_pipe_profile[] = {
- &dev_attr_render_pipe_profile_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_pipe_profile = {
- .name = "ce416533-e49e-4211-80af-ec513590a914",
- .attrs = attrs_render_pipe_profile,
-};
-
-static ssize_t
-show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS);
-}
-
-static struct device_attribute dev_attr_memory_reads_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_reads_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_reads[] = {
- &dev_attr_memory_reads_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_reads = {
- .name = "398e2452-18d7-42d0-b241-e4d0a9148ada",
- .attrs = attrs_memory_reads,
-};
-
-static ssize_t
-show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES);
-}
-
-static struct device_attribute dev_attr_memory_writes_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_writes_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_writes[] = {
- &dev_attr_memory_writes_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_writes = {
- .name = "d324a0d6-7269-4847-a5c2-6f71ddc7fed5",
- .attrs = attrs_memory_writes,
-};
-
-static ssize_t
-show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED);
-}
-
-static struct device_attribute dev_attr_compute_extended_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extended_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extended[] = {
- &dev_attr_compute_extended_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extended = {
- .name = "caf3596a-7bb1-4dec-b3b3-2a080d283b49",
- .attrs = attrs_compute_extended,
-};
-
-static ssize_t
-show_compute_l3_cache_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_L3_CACHE);
-}
-
-static struct device_attribute dev_attr_compute_l3_cache_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_l3_cache_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_l3_cache[] = {
- &dev_attr_compute_l3_cache_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_l3_cache = {
- .name = "49b956e2-d5b9-47e0-9d8a-cee5e8cec527",
- .attrs = attrs_compute_l3_cache,
-};
-
-static ssize_t
-show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF);
-}
-
-static struct device_attribute dev_attr_hdc_and_sf_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_hdc_and_sf_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_hdc_and_sf[] = {
- &dev_attr_hdc_and_sf_id.attr,
- NULL,
-};
-
-static struct attribute_group group_hdc_and_sf = {
- .name = "f64ef50a-bdba-4b35-8f09-203c13d8ee5a",
- .attrs = attrs_hdc_and_sf,
-};
-
-static ssize_t
-show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1);
-}
-
-static struct device_attribute dev_attr_l3_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_1[] = {
- &dev_attr_l3_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_1 = {
- .name = "00ad5a41-7eab-4f7a-9103-49d411c67219",
- .attrs = attrs_l3_1,
-};
-
-static ssize_t
-show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND);
-}
-
-static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_rasterizer_and_pixel_backend_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_rasterizer_and_pixel_backend[] = {
- &dev_attr_rasterizer_and_pixel_backend_id.attr,
- NULL,
-};
-
-static struct attribute_group group_rasterizer_and_pixel_backend = {
- .name = "46dc44ca-491c-4cc1-a951-e7b3e62bf02b",
- .attrs = attrs_rasterizer_and_pixel_backend,
-};
-
-static ssize_t
-show_sampler_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER);
-}
-
-static struct device_attribute dev_attr_sampler_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_sampler_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_sampler[] = {
- &dev_attr_sampler_id.attr,
- NULL,
-};
-
-static struct attribute_group group_sampler = {
- .name = "8364e2a8-af63-40af-b0d5-42969a255654",
- .attrs = attrs_sampler,
-};
-
-static ssize_t
-show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1);
-}
-
-static struct device_attribute dev_attr_tdl_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_1[] = {
- &dev_attr_tdl_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_1 = {
- .name = "175c8092-cb25-4d1e-8dc7-b4fdd39e2d92",
- .attrs = attrs_tdl_1,
-};
-
-static ssize_t
-show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2);
-}
-
-static struct device_attribute dev_attr_tdl_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_2[] = {
- &dev_attr_tdl_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_2 = {
- .name = "d260f03f-b34d-4b49-a44e-436819117332",
- .attrs = attrs_tdl_2,
-};
-
-static ssize_t
-show_compute_extra_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTRA);
-}
-
-static struct device_attribute dev_attr_compute_extra_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extra_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extra[] = {
- &dev_attr_compute_extra_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extra = {
- .name = "fa6ecf21-2cb8-4d0b-9308-6e4a7b4ca87a",
- .attrs = attrs_compute_extra,
-};
-
static ssize_t
show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA);
+ return sprintf(buf, "1\n");
}
-static struct device_attribute dev_attr_test_oa_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_test_oa_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_test_oa[] = {
- &dev_attr_test_oa_id.attr,
- NULL,
-};
-
-static struct attribute_group group_test_oa = {
- .name = "5ee72f5c-092f-421e-8b70-225f7c3e9612",
- .attrs = attrs_test_oa,
-};
-
-int
-i915_perf_register_sysfs_bxt(struct drm_i915_private *dev_priv)
+void
+i915_perf_load_test_config_bxt(struct drm_i915_private *dev_priv)
{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
- int ret = 0;
+ strncpy(dev_priv->perf.oa.test_config.uuid,
+ "5ee72f5c-092f-421e-8b70-225f7c3e9612",
+ UUID_STRING_LEN);
+ dev_priv->perf.oa.test_config.id = 1;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (ret)
- goto error_render_basic;
- }
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (ret)
- goto error_compute_basic;
- }
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (ret)
- goto error_render_pipe_profile;
- }
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (ret)
- goto error_memory_reads;
- }
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (ret)
- goto error_memory_writes;
- }
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (ret)
- goto error_compute_extended;
- }
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (ret)
- goto error_compute_l3_cache;
- }
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (ret)
- goto error_hdc_and_sf;
- }
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (ret)
- goto error_l3_1;
- }
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (ret)
- goto error_rasterizer_and_pixel_backend;
- }
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (ret)
- goto error_sampler;
- }
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (ret)
- goto error_tdl_1;
- }
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (ret)
- goto error_tdl_2;
- }
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (ret)
- goto error_compute_extra;
- }
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa);
- if (ret)
- goto error_test_oa;
- }
+ dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
+ dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
- return 0;
+ dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
+ dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-error_test_oa:
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
-error_compute_extra:
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
-error_tdl_2:
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
-error_tdl_1:
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
-error_sampler:
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
-error_rasterizer_and_pixel_backend:
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
-error_l3_1:
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
-error_hdc_and_sf:
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
-error_compute_l3_cache:
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
-error_compute_extended:
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
-error_memory_writes:
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
-error_memory_reads:
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
-error_render_pipe_profile:
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
-error_compute_basic:
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
-error_render_basic:
- return ret;
-}
+ dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
+ dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-void
-i915_perf_unregister_sysfs_bxt(struct drm_i915_private *dev_priv)
-{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
+ dev_priv->perf.oa.test_config.sysfs_metric.name = "5ee72f5c-092f-421e-8b70-225f7c3e9612";
+ dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+
+ dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa);
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
+ dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
}
diff --git a/drivers/gpu/drm/i915/i915_oa_bxt.h b/drivers/gpu/drm/i915/i915_oa_bxt.h
index 6cf7ba7..690b963 100644
--- a/drivers/gpu/drm/i915/i915_oa_bxt.h
+++ b/drivers/gpu/drm/i915/i915_oa_bxt.h
@@ -29,12 +29,6 @@
#ifndef __I915_OA_BXT_H__
#define __I915_OA_BXT_H__
-extern int i915_oa_n_builtin_metric_sets_bxt;
-
-extern int i915_oa_select_metric_set_bxt(struct drm_i915_private *dev_priv);
-
-extern int i915_perf_register_sysfs_bxt(struct drm_i915_private *dev_priv);
-
-extern void i915_perf_unregister_sysfs_bxt(struct drm_i915_private *dev_priv);
+extern void i915_perf_load_test_config_bxt(struct drm_i915_private *dev_priv);
#endif
diff --git a/drivers/gpu/drm/i915/i915_oa_chv.c b/drivers/gpu/drm/i915/i915_oa_chv.c
index aa6bece..322a3f9 100644
--- a/drivers/gpu/drm/i915/i915_oa_chv.c
+++ b/drivers/gpu/drm/i915/i915_oa_chv.c
@@ -31,1943 +31,6 @@
#include "i915_drv.h"
#include "i915_oa_chv.h"
-enum metric_set_id {
- METRIC_SET_ID_RENDER_BASIC = 1,
- METRIC_SET_ID_COMPUTE_BASIC,
- METRIC_SET_ID_RENDER_PIPE_PROFILE,
- METRIC_SET_ID_HDC_AND_SF,
- METRIC_SET_ID_L3_1,
- METRIC_SET_ID_L3_2,
- METRIC_SET_ID_L3_3,
- METRIC_SET_ID_L3_4,
- METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND,
- METRIC_SET_ID_SAMPLER_1,
- METRIC_SET_ID_SAMPLER_2,
- METRIC_SET_ID_TDL_1,
- METRIC_SET_ID_TDL_2,
- METRIC_SET_ID_TEST_OA,
-};
-
-int i915_oa_n_builtin_metric_sets_chv = 14;
-
-static const struct i915_oa_reg b_counter_config_render_basic[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_render_basic[] = {
- { _MMIO(0x9888), 0x59800000 },
- { _MMIO(0x9888), 0x59800001 },
- { _MMIO(0x9888), 0x285a0006 },
- { _MMIO(0x9888), 0x2c110014 },
- { _MMIO(0x9888), 0x2e110000 },
- { _MMIO(0x9888), 0x2c310014 },
- { _MMIO(0x9888), 0x2e310000 },
- { _MMIO(0x9888), 0x2b8303df },
- { _MMIO(0x9888), 0x3580024f },
- { _MMIO(0x9888), 0x00580888 },
- { _MMIO(0x9888), 0x1e5a0015 },
- { _MMIO(0x9888), 0x205a0014 },
- { _MMIO(0x9888), 0x045a0000 },
- { _MMIO(0x9888), 0x025a0000 },
- { _MMIO(0x9888), 0x02180500 },
- { _MMIO(0x9888), 0x00190555 },
- { _MMIO(0x9888), 0x021d0500 },
- { _MMIO(0x9888), 0x021f0a00 },
- { _MMIO(0x9888), 0x00380444 },
- { _MMIO(0x9888), 0x02390500 },
- { _MMIO(0x9888), 0x003a0666 },
- { _MMIO(0x9888), 0x00100111 },
- { _MMIO(0x9888), 0x06110030 },
- { _MMIO(0x9888), 0x0a110031 },
- { _MMIO(0x9888), 0x0e110046 },
- { _MMIO(0x9888), 0x04110000 },
- { _MMIO(0x9888), 0x00110000 },
- { _MMIO(0x9888), 0x00130111 },
- { _MMIO(0x9888), 0x00300444 },
- { _MMIO(0x9888), 0x08310030 },
- { _MMIO(0x9888), 0x0c310031 },
- { _MMIO(0x9888), 0x10310046 },
- { _MMIO(0x9888), 0x04310000 },
- { _MMIO(0x9888), 0x00310000 },
- { _MMIO(0x9888), 0x00330444 },
- { _MMIO(0x9888), 0x038a0a00 },
- { _MMIO(0x9888), 0x018b0fff },
- { _MMIO(0x9888), 0x038b0a00 },
- { _MMIO(0x9888), 0x01855000 },
- { _MMIO(0x9888), 0x03850055 },
- { _MMIO(0x9888), 0x13830021 },
- { _MMIO(0x9888), 0x15830020 },
- { _MMIO(0x9888), 0x1783002f },
- { _MMIO(0x9888), 0x1983002e },
- { _MMIO(0x9888), 0x1b83002d },
- { _MMIO(0x9888), 0x1d83002c },
- { _MMIO(0x9888), 0x05830000 },
- { _MMIO(0x9888), 0x01840555 },
- { _MMIO(0x9888), 0x03840500 },
- { _MMIO(0x9888), 0x23800074 },
- { _MMIO(0x9888), 0x2580007d },
- { _MMIO(0x9888), 0x05800000 },
- { _MMIO(0x9888), 0x01805000 },
- { _MMIO(0x9888), 0x03800055 },
- { _MMIO(0x9888), 0x01865000 },
- { _MMIO(0x9888), 0x03860055 },
- { _MMIO(0x9888), 0x01875000 },
- { _MMIO(0x9888), 0x03870055 },
- { _MMIO(0x9888), 0x418000aa },
- { _MMIO(0x9888), 0x4380000a },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x4780000a },
- { _MMIO(0x9888), 0x49800000 },
- { _MMIO(0x9888), 0x4b800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x55800000 },
- { _MMIO(0x9888), 0x57800000 },
- { _MMIO(0x9888), 0x59800000 },
-};
-
-static int
-get_render_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_basic;
- lens[n] = ARRAY_SIZE(mux_config_render_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_basic[] = {
- { _MMIO(0x9888), 0x59800000 },
- { _MMIO(0x9888), 0x59800001 },
- { _MMIO(0x9888), 0x2e5800e0 },
- { _MMIO(0x9888), 0x2e3800e0 },
- { _MMIO(0x9888), 0x3580024f },
- { _MMIO(0x9888), 0x3d800140 },
- { _MMIO(0x9888), 0x08580042 },
- { _MMIO(0x9888), 0x0c580040 },
- { _MMIO(0x9888), 0x1058004c },
- { _MMIO(0x9888), 0x1458004b },
- { _MMIO(0x9888), 0x04580000 },
- { _MMIO(0x9888), 0x00580000 },
- { _MMIO(0x9888), 0x00195555 },
- { _MMIO(0x9888), 0x06380042 },
- { _MMIO(0x9888), 0x0a380040 },
- { _MMIO(0x9888), 0x0e38004c },
- { _MMIO(0x9888), 0x1238004b },
- { _MMIO(0x9888), 0x04380000 },
- { _MMIO(0x9888), 0x00384444 },
- { _MMIO(0x9888), 0x003a5555 },
- { _MMIO(0x9888), 0x018bffff },
- { _MMIO(0x9888), 0x01845555 },
- { _MMIO(0x9888), 0x17800074 },
- { _MMIO(0x9888), 0x1980007d },
- { _MMIO(0x9888), 0x1b80007c },
- { _MMIO(0x9888), 0x1d8000b6 },
- { _MMIO(0x9888), 0x1f8000b7 },
- { _MMIO(0x9888), 0x05800000 },
- { _MMIO(0x9888), 0x03800000 },
- { _MMIO(0x9888), 0x418000aa },
- { _MMIO(0x9888), 0x438000aa },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x47800000 },
- { _MMIO(0x9888), 0x4980012a },
- { _MMIO(0x9888), 0x4b80012a },
- { _MMIO(0x9888), 0x4d80012a },
- { _MMIO(0x9888), 0x4f80012a },
- { _MMIO(0x9888), 0x518001ce },
- { _MMIO(0x9888), 0x538001ce },
- { _MMIO(0x9888), 0x5580000e },
- { _MMIO(0x9888), 0x59800000 },
-};
-
-static int
-get_compute_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_basic;
- lens[n] = ARRAY_SIZE(mux_config_compute_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2770), 0x0007ffea },
- { _MMIO(0x2774), 0x00007ffc },
- { _MMIO(0x2778), 0x0007affa },
- { _MMIO(0x277c), 0x0000f5fd },
- { _MMIO(0x2780), 0x00079ffa },
- { _MMIO(0x2784), 0x0000f3fb },
- { _MMIO(0x2788), 0x0007bf7a },
- { _MMIO(0x278c), 0x0000f7e7 },
- { _MMIO(0x2790), 0x0007fefa },
- { _MMIO(0x2794), 0x0000f7cf },
- { _MMIO(0x2798), 0x00077ffa },
- { _MMIO(0x279c), 0x0000efdf },
- { _MMIO(0x27a0), 0x0006fffa },
- { _MMIO(0x27a4), 0x0000cfbf },
- { _MMIO(0x27a8), 0x0003fffa },
- { _MMIO(0x27ac), 0x00005f7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_render_pipe_profile[] = {
- { _MMIO(0x9888), 0x59800000 },
- { _MMIO(0x9888), 0x59800001 },
- { _MMIO(0x9888), 0x261e0000 },
- { _MMIO(0x9888), 0x281f000f },
- { _MMIO(0x9888), 0x2817001a },
- { _MMIO(0x9888), 0x2791001f },
- { _MMIO(0x9888), 0x27880019 },
- { _MMIO(0x9888), 0x2d890000 },
- { _MMIO(0x9888), 0x278a0007 },
- { _MMIO(0x9888), 0x298d001f },
- { _MMIO(0x9888), 0x278e0020 },
- { _MMIO(0x9888), 0x2b8f0012 },
- { _MMIO(0x9888), 0x29900000 },
- { _MMIO(0x9888), 0x00184000 },
- { _MMIO(0x9888), 0x02181000 },
- { _MMIO(0x9888), 0x02194000 },
- { _MMIO(0x9888), 0x141e0002 },
- { _MMIO(0x9888), 0x041e0000 },
- { _MMIO(0x9888), 0x001e0000 },
- { _MMIO(0x9888), 0x221f0015 },
- { _MMIO(0x9888), 0x041f0000 },
- { _MMIO(0x9888), 0x001f4000 },
- { _MMIO(0x9888), 0x021f0000 },
- { _MMIO(0x9888), 0x023a8000 },
- { _MMIO(0x9888), 0x0213c000 },
- { _MMIO(0x9888), 0x02164000 },
- { _MMIO(0x9888), 0x24170012 },
- { _MMIO(0x9888), 0x04170000 },
- { _MMIO(0x9888), 0x07910005 },
- { _MMIO(0x9888), 0x05910000 },
- { _MMIO(0x9888), 0x01911500 },
- { _MMIO(0x9888), 0x03910501 },
- { _MMIO(0x9888), 0x0d880002 },
- { _MMIO(0x9888), 0x1d880003 },
- { _MMIO(0x9888), 0x05880000 },
- { _MMIO(0x9888), 0x0b890032 },
- { _MMIO(0x9888), 0x1b890031 },
- { _MMIO(0x9888), 0x05890000 },
- { _MMIO(0x9888), 0x01890040 },
- { _MMIO(0x9888), 0x03890040 },
- { _MMIO(0x9888), 0x098a0000 },
- { _MMIO(0x9888), 0x198a0004 },
- { _MMIO(0x9888), 0x058a0000 },
- { _MMIO(0x9888), 0x018a8050 },
- { _MMIO(0x9888), 0x038a2050 },
- { _MMIO(0x9888), 0x018b95a9 },
- { _MMIO(0x9888), 0x038be5a9 },
- { _MMIO(0x9888), 0x018c1500 },
- { _MMIO(0x9888), 0x038c0501 },
- { _MMIO(0x9888), 0x178d0015 },
- { _MMIO(0x9888), 0x058d0000 },
- { _MMIO(0x9888), 0x138e0004 },
- { _MMIO(0x9888), 0x218e000c },
- { _MMIO(0x9888), 0x058e0000 },
- { _MMIO(0x9888), 0x018e0500 },
- { _MMIO(0x9888), 0x038e0101 },
- { _MMIO(0x9888), 0x0f8f0027 },
- { _MMIO(0x9888), 0x058f0000 },
- { _MMIO(0x9888), 0x018f0000 },
- { _MMIO(0x9888), 0x038f0001 },
- { _MMIO(0x9888), 0x11900013 },
- { _MMIO(0x9888), 0x1f900017 },
- { _MMIO(0x9888), 0x05900000 },
- { _MMIO(0x9888), 0x01900100 },
- { _MMIO(0x9888), 0x03900001 },
- { _MMIO(0x9888), 0x01845555 },
- { _MMIO(0x9888), 0x03845555 },
- { _MMIO(0x9888), 0x418000aa },
- { _MMIO(0x9888), 0x438000aa },
- { _MMIO(0x9888), 0x458000aa },
- { _MMIO(0x9888), 0x478000aa },
- { _MMIO(0x9888), 0x4980018c },
- { _MMIO(0x9888), 0x4b80014b },
- { _MMIO(0x9888), 0x4d800128 },
- { _MMIO(0x9888), 0x4f80012a },
- { _MMIO(0x9888), 0x51800187 },
- { _MMIO(0x9888), 0x5380014b },
- { _MMIO(0x9888), 0x55800149 },
- { _MMIO(0x9888), 0x5780010a },
- { _MMIO(0x9888), 0x59800000 },
-};
-
-static int
-get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_pipe_profile;
- lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x10800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fff7 },
-};
-
-static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_hdc_and_sf[] = {
- { _MMIO(0x9888), 0x105c0232 },
- { _MMIO(0x9888), 0x10580232 },
- { _MMIO(0x9888), 0x10380232 },
- { _MMIO(0x9888), 0x10dc0232 },
- { _MMIO(0x9888), 0x10d80232 },
- { _MMIO(0x9888), 0x10b80232 },
- { _MMIO(0x9888), 0x118e4400 },
- { _MMIO(0x9888), 0x025c6080 },
- { _MMIO(0x9888), 0x045c004b },
- { _MMIO(0x9888), 0x005c8000 },
- { _MMIO(0x9888), 0x00582080 },
- { _MMIO(0x9888), 0x0258004b },
- { _MMIO(0x9888), 0x025b4000 },
- { _MMIO(0x9888), 0x045b4000 },
- { _MMIO(0x9888), 0x0c1fa000 },
- { _MMIO(0x9888), 0x0e1f00aa },
- { _MMIO(0x9888), 0x04386080 },
- { _MMIO(0x9888), 0x0638404b },
- { _MMIO(0x9888), 0x02384000 },
- { _MMIO(0x9888), 0x08384000 },
- { _MMIO(0x9888), 0x0a380000 },
- { _MMIO(0x9888), 0x0c380000 },
- { _MMIO(0x9888), 0x00398000 },
- { _MMIO(0x9888), 0x0239a000 },
- { _MMIO(0x9888), 0x0439a000 },
- { _MMIO(0x9888), 0x06392000 },
- { _MMIO(0x9888), 0x0cdc25c1 },
- { _MMIO(0x9888), 0x0adcc000 },
- { _MMIO(0x9888), 0x0ad825c1 },
- { _MMIO(0x9888), 0x18db4000 },
- { _MMIO(0x9888), 0x1adb0001 },
- { _MMIO(0x9888), 0x0e9f8000 },
- { _MMIO(0x9888), 0x109f02aa },
- { _MMIO(0x9888), 0x0eb825c1 },
- { _MMIO(0x9888), 0x18b80154 },
- { _MMIO(0x9888), 0x0ab9a000 },
- { _MMIO(0x9888), 0x0cb9a000 },
- { _MMIO(0x9888), 0x0eb9a000 },
- { _MMIO(0x9888), 0x0d88c000 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x258baa05 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x238b2a80 },
- { _MMIO(0x9888), 0x198c5400 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x098dc000 },
- { _MMIO(0x9888), 0x0b8da000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x098e05c0 },
- { _MMIO(0x9888), 0x058e0000 },
- { _MMIO(0x9888), 0x198f0020 },
- { _MMIO(0x9888), 0x2185aa0a },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x19835000 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x09848000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x19808000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x51800040 },
- { _MMIO(0x9888), 0x43800400 },
- { _MMIO(0x9888), 0x45800800 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800c62 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f801042 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x418014a4 },
-};
-
-static int
-get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_hdc_and_sf;
- lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_1[] = {
- { _MMIO(0x9888), 0x10bf03da },
- { _MMIO(0x9888), 0x14bf0001 },
- { _MMIO(0x9888), 0x12980340 },
- { _MMIO(0x9888), 0x12990340 },
- { _MMIO(0x9888), 0x0cbf1187 },
- { _MMIO(0x9888), 0x0ebf1205 },
- { _MMIO(0x9888), 0x00bf0500 },
- { _MMIO(0x9888), 0x02bf042b },
- { _MMIO(0x9888), 0x04bf002c },
- { _MMIO(0x9888), 0x0cdac000 },
- { _MMIO(0x9888), 0x0edac000 },
- { _MMIO(0x9888), 0x00da8000 },
- { _MMIO(0x9888), 0x02dac000 },
- { _MMIO(0x9888), 0x04da4000 },
- { _MMIO(0x9888), 0x04983400 },
- { _MMIO(0x9888), 0x10980000 },
- { _MMIO(0x9888), 0x06990034 },
- { _MMIO(0x9888), 0x10990000 },
- { _MMIO(0x9888), 0x0c9dc000 },
- { _MMIO(0x9888), 0x0e9dc000 },
- { _MMIO(0x9888), 0x009d8000 },
- { _MMIO(0x9888), 0x029dc000 },
- { _MMIO(0x9888), 0x049d4000 },
- { _MMIO(0x9888), 0x109f02a8 },
- { _MMIO(0x9888), 0x0c9fa000 },
- { _MMIO(0x9888), 0x0e9f00ba },
- { _MMIO(0x9888), 0x0cb88000 },
- { _MMIO(0x9888), 0x0cb95000 },
- { _MMIO(0x9888), 0x0eb95000 },
- { _MMIO(0x9888), 0x00b94000 },
- { _MMIO(0x9888), 0x02b95000 },
- { _MMIO(0x9888), 0x04b91000 },
- { _MMIO(0x9888), 0x06b92000 },
- { _MMIO(0x9888), 0x0cba4000 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x03888000 },
- { _MMIO(0x9888), 0x05888000 },
- { _MMIO(0x9888), 0x07888000 },
- { _MMIO(0x9888), 0x09888000 },
- { _MMIO(0x9888), 0x0b888000 },
- { _MMIO(0x9888), 0x0d880400 },
- { _MMIO(0x9888), 0x258b800a },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x238b5500 },
- { _MMIO(0x9888), 0x198c4000 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x038c4000 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x078c4000 },
- { _MMIO(0x9888), 0x098c4000 },
- { _MMIO(0x9888), 0x0b8c4000 },
- { _MMIO(0x9888), 0x0d8c4000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x018d8000 },
- { _MMIO(0x9888), 0x038da000 },
- { _MMIO(0x9888), 0x058da000 },
- { _MMIO(0x9888), 0x078d2000 },
- { _MMIO(0x9888), 0x2185800a },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x1b830154 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x47800000 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f800000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41800060 },
-};
-
-static int
-get_l3_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_1;
- lens[n] = ARRAY_SIZE(mux_config_l3_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_2[] = {
- { _MMIO(0x9888), 0x103f03da },
- { _MMIO(0x9888), 0x143f0001 },
- { _MMIO(0x9888), 0x12180340 },
- { _MMIO(0x9888), 0x12190340 },
- { _MMIO(0x9888), 0x0c3f1187 },
- { _MMIO(0x9888), 0x0e3f1205 },
- { _MMIO(0x9888), 0x003f0500 },
- { _MMIO(0x9888), 0x023f042b },
- { _MMIO(0x9888), 0x043f002c },
- { _MMIO(0x9888), 0x0c5ac000 },
- { _MMIO(0x9888), 0x0e5ac000 },
- { _MMIO(0x9888), 0x005a8000 },
- { _MMIO(0x9888), 0x025ac000 },
- { _MMIO(0x9888), 0x045a4000 },
- { _MMIO(0x9888), 0x04183400 },
- { _MMIO(0x9888), 0x10180000 },
- { _MMIO(0x9888), 0x06190034 },
- { _MMIO(0x9888), 0x10190000 },
- { _MMIO(0x9888), 0x0c1dc000 },
- { _MMIO(0x9888), 0x0e1dc000 },
- { _MMIO(0x9888), 0x001d8000 },
- { _MMIO(0x9888), 0x021dc000 },
- { _MMIO(0x9888), 0x041d4000 },
- { _MMIO(0x9888), 0x101f02a8 },
- { _MMIO(0x9888), 0x0c1fa000 },
- { _MMIO(0x9888), 0x0e1f00ba },
- { _MMIO(0x9888), 0x0c388000 },
- { _MMIO(0x9888), 0x0c395000 },
- { _MMIO(0x9888), 0x0e395000 },
- { _MMIO(0x9888), 0x00394000 },
- { _MMIO(0x9888), 0x02395000 },
- { _MMIO(0x9888), 0x04391000 },
- { _MMIO(0x9888), 0x06392000 },
- { _MMIO(0x9888), 0x0c3a4000 },
- { _MMIO(0x9888), 0x1b8aa800 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x258b4005 },
- { _MMIO(0x9888), 0x278b0015 },
- { _MMIO(0x9888), 0x238b2a80 },
- { _MMIO(0x9888), 0x2185800a },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x1b830154 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x47800000 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f800000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41800060 },
-};
-
-static int
-get_l3_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_2;
- lens[n] = ARRAY_SIZE(mux_config_l3_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_3[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_3[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_3[] = {
- { _MMIO(0x9888), 0x121b0340 },
- { _MMIO(0x9888), 0x103f0274 },
- { _MMIO(0x9888), 0x123f0000 },
- { _MMIO(0x9888), 0x129b0340 },
- { _MMIO(0x9888), 0x10bf0274 },
- { _MMIO(0x9888), 0x12bf0000 },
- { _MMIO(0x9888), 0x041b3400 },
- { _MMIO(0x9888), 0x101b0000 },
- { _MMIO(0x9888), 0x045c8000 },
- { _MMIO(0x9888), 0x0a3d4000 },
- { _MMIO(0x9888), 0x003f0080 },
- { _MMIO(0x9888), 0x023f0793 },
- { _MMIO(0x9888), 0x043f0014 },
- { _MMIO(0x9888), 0x04588000 },
- { _MMIO(0x9888), 0x005a8000 },
- { _MMIO(0x9888), 0x025ac000 },
- { _MMIO(0x9888), 0x045a4000 },
- { _MMIO(0x9888), 0x0a5b4000 },
- { _MMIO(0x9888), 0x001d8000 },
- { _MMIO(0x9888), 0x021dc000 },
- { _MMIO(0x9888), 0x041d4000 },
- { _MMIO(0x9888), 0x0c1fa000 },
- { _MMIO(0x9888), 0x0e1f002a },
- { _MMIO(0x9888), 0x0a384000 },
- { _MMIO(0x9888), 0x00394000 },
- { _MMIO(0x9888), 0x02395000 },
- { _MMIO(0x9888), 0x04399000 },
- { _MMIO(0x9888), 0x069b0034 },
- { _MMIO(0x9888), 0x109b0000 },
- { _MMIO(0x9888), 0x06dc4000 },
- { _MMIO(0x9888), 0x0cbd4000 },
- { _MMIO(0x9888), 0x0cbf0981 },
- { _MMIO(0x9888), 0x0ebf0a0f },
- { _MMIO(0x9888), 0x06d84000 },
- { _MMIO(0x9888), 0x0cdac000 },
- { _MMIO(0x9888), 0x0edac000 },
- { _MMIO(0x9888), 0x0cdb4000 },
- { _MMIO(0x9888), 0x0c9dc000 },
- { _MMIO(0x9888), 0x0e9dc000 },
- { _MMIO(0x9888), 0x109f02a8 },
- { _MMIO(0x9888), 0x0e9f0080 },
- { _MMIO(0x9888), 0x0cb84000 },
- { _MMIO(0x9888), 0x0cb95000 },
- { _MMIO(0x9888), 0x0eb95000 },
- { _MMIO(0x9888), 0x06b92000 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x0d880400 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x258b8009 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x238b2a80 },
- { _MMIO(0x9888), 0x198c4000 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x0d8c4000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x078d2000 },
- { _MMIO(0x9888), 0x2185800a },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x1b830154 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x45800c00 },
- { _MMIO(0x9888), 0x47800c63 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f8014a5 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41800045 },
-};
-
-static int
-get_l3_3_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_3;
- lens[n] = ARRAY_SIZE(mux_config_l3_3);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_4[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_4[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_4[] = {
- { _MMIO(0x9888), 0x121a0340 },
- { _MMIO(0x9888), 0x103f0017 },
- { _MMIO(0x9888), 0x123f0020 },
- { _MMIO(0x9888), 0x129a0340 },
- { _MMIO(0x9888), 0x10bf0017 },
- { _MMIO(0x9888), 0x12bf0020 },
- { _MMIO(0x9888), 0x041a3400 },
- { _MMIO(0x9888), 0x101a0000 },
- { _MMIO(0x9888), 0x043b8000 },
- { _MMIO(0x9888), 0x0a3e0010 },
- { _MMIO(0x9888), 0x003f0200 },
- { _MMIO(0x9888), 0x023f0113 },
- { _MMIO(0x9888), 0x043f0014 },
- { _MMIO(0x9888), 0x02592000 },
- { _MMIO(0x9888), 0x005a8000 },
- { _MMIO(0x9888), 0x025ac000 },
- { _MMIO(0x9888), 0x045a4000 },
- { _MMIO(0x9888), 0x0a1c8000 },
- { _MMIO(0x9888), 0x001d8000 },
- { _MMIO(0x9888), 0x021dc000 },
- { _MMIO(0x9888), 0x041d4000 },
- { _MMIO(0x9888), 0x0a1e8000 },
- { _MMIO(0x9888), 0x0c1fa000 },
- { _MMIO(0x9888), 0x0e1f001a },
- { _MMIO(0x9888), 0x00394000 },
- { _MMIO(0x9888), 0x02395000 },
- { _MMIO(0x9888), 0x04391000 },
- { _MMIO(0x9888), 0x069a0034 },
- { _MMIO(0x9888), 0x109a0000 },
- { _MMIO(0x9888), 0x06bb4000 },
- { _MMIO(0x9888), 0x0abe0040 },
- { _MMIO(0x9888), 0x0cbf0984 },
- { _MMIO(0x9888), 0x0ebf0a02 },
- { _MMIO(0x9888), 0x02d94000 },
- { _MMIO(0x9888), 0x0cdac000 },
- { _MMIO(0x9888), 0x0edac000 },
- { _MMIO(0x9888), 0x0c9c0400 },
- { _MMIO(0x9888), 0x0c9dc000 },
- { _MMIO(0x9888), 0x0e9dc000 },
- { _MMIO(0x9888), 0x0c9e0400 },
- { _MMIO(0x9888), 0x109f02a8 },
- { _MMIO(0x9888), 0x0e9f0040 },
- { _MMIO(0x9888), 0x0cb95000 },
- { _MMIO(0x9888), 0x0eb95000 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x0d880400 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x258b8009 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x238b2a80 },
- { _MMIO(0x9888), 0x198c4000 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x0d8c4000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x078d2000 },
- { _MMIO(0x9888), 0x2185800a },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x1b830154 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x45800800 },
- { _MMIO(0x9888), 0x47800842 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f801084 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41800044 },
-};
-
-static int
-get_l3_4_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_4;
- lens[n] = ARRAY_SIZE(mux_config_l3_4);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00006000 },
- { _MMIO(0x2774), 0x0000f3ff },
- { _MMIO(0x2778), 0x00001800 },
- { _MMIO(0x277c), 0x0000fcff },
- { _MMIO(0x2780), 0x00000600 },
- { _MMIO(0x2784), 0x0000ff3f },
- { _MMIO(0x2788), 0x00000180 },
- { _MMIO(0x278c), 0x0000ffcf },
- { _MMIO(0x2790), 0x00000060 },
- { _MMIO(0x2794), 0x0000fff3 },
- { _MMIO(0x2798), 0x00000018 },
- { _MMIO(0x279c), 0x0000fffc },
-};
-
-static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x9888), 0x143b000e },
- { _MMIO(0x9888), 0x043c55c0 },
- { _MMIO(0x9888), 0x0a1e0280 },
- { _MMIO(0x9888), 0x0c1e0408 },
- { _MMIO(0x9888), 0x10390000 },
- { _MMIO(0x9888), 0x12397a1f },
- { _MMIO(0x9888), 0x14bb000e },
- { _MMIO(0x9888), 0x04bc5000 },
- { _MMIO(0x9888), 0x0a9e0296 },
- { _MMIO(0x9888), 0x0c9e0008 },
- { _MMIO(0x9888), 0x10b90000 },
- { _MMIO(0x9888), 0x12b97a1f },
- { _MMIO(0x9888), 0x063b0042 },
- { _MMIO(0x9888), 0x103b0000 },
- { _MMIO(0x9888), 0x083c0000 },
- { _MMIO(0x9888), 0x0a3e0040 },
- { _MMIO(0x9888), 0x043f8000 },
- { _MMIO(0x9888), 0x02594000 },
- { _MMIO(0x9888), 0x045a8000 },
- { _MMIO(0x9888), 0x0c1c0400 },
- { _MMIO(0x9888), 0x041d8000 },
- { _MMIO(0x9888), 0x081e02c0 },
- { _MMIO(0x9888), 0x0e1e0000 },
- { _MMIO(0x9888), 0x0c1fa800 },
- { _MMIO(0x9888), 0x0e1f0260 },
- { _MMIO(0x9888), 0x101f0014 },
- { _MMIO(0x9888), 0x003905e0 },
- { _MMIO(0x9888), 0x06390bc0 },
- { _MMIO(0x9888), 0x02390018 },
- { _MMIO(0x9888), 0x04394000 },
- { _MMIO(0x9888), 0x04bb0042 },
- { _MMIO(0x9888), 0x10bb0000 },
- { _MMIO(0x9888), 0x02bc05c0 },
- { _MMIO(0x9888), 0x08bc0000 },
- { _MMIO(0x9888), 0x0abe0004 },
- { _MMIO(0x9888), 0x02bf8000 },
- { _MMIO(0x9888), 0x02d91000 },
- { _MMIO(0x9888), 0x02da8000 },
- { _MMIO(0x9888), 0x089c8000 },
- { _MMIO(0x9888), 0x029d8000 },
- { _MMIO(0x9888), 0x089e8000 },
- { _MMIO(0x9888), 0x0e9e0000 },
- { _MMIO(0x9888), 0x0e9fa806 },
- { _MMIO(0x9888), 0x109f0142 },
- { _MMIO(0x9888), 0x08b90617 },
- { _MMIO(0x9888), 0x0ab90be0 },
- { _MMIO(0x9888), 0x02b94000 },
- { _MMIO(0x9888), 0x0d88f000 },
- { _MMIO(0x9888), 0x0f88000c },
- { _MMIO(0x9888), 0x07888000 },
- { _MMIO(0x9888), 0x09888000 },
- { _MMIO(0x9888), 0x018a8000 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x1b8a2800 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x238b52a0 },
- { _MMIO(0x9888), 0x258b6a95 },
- { _MMIO(0x9888), 0x278b0029 },
- { _MMIO(0x9888), 0x178c2000 },
- { _MMIO(0x9888), 0x198c1500 },
- { _MMIO(0x9888), 0x1b8c0014 },
- { _MMIO(0x9888), 0x078c4000 },
- { _MMIO(0x9888), 0x098c4000 },
- { _MMIO(0x9888), 0x098da000 },
- { _MMIO(0x9888), 0x0b8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x038d8000 },
- { _MMIO(0x9888), 0x058d2000 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaaa },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x0784c000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x1780c000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x4d800444 },
- { _MMIO(0x9888), 0x3d800000 },
- { _MMIO(0x9888), 0x4f804000 },
- { _MMIO(0x9888), 0x43801080 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800084 },
- { _MMIO(0x9888), 0x53800044 },
- { _MMIO(0x9888), 0x47801080 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800000 },
- { _MMIO(0x9888), 0x41800840 },
-};
-
-static int
-get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_rasterizer_and_pixel_backend;
- lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_sampler_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x70800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x0000c000 },
- { _MMIO(0x2774), 0x0000e7ff },
- { _MMIO(0x2778), 0x00003000 },
- { _MMIO(0x277c), 0x0000f9ff },
- { _MMIO(0x2780), 0x00000c00 },
- { _MMIO(0x2784), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_sampler_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_sampler_1[] = {
- { _MMIO(0x9888), 0x18921400 },
- { _MMIO(0x9888), 0x149500ab },
- { _MMIO(0x9888), 0x18b21400 },
- { _MMIO(0x9888), 0x14b500ab },
- { _MMIO(0x9888), 0x18d21400 },
- { _MMIO(0x9888), 0x14d500ab },
- { _MMIO(0x9888), 0x0cdc8000 },
- { _MMIO(0x9888), 0x0edc4000 },
- { _MMIO(0x9888), 0x02dcc000 },
- { _MMIO(0x9888), 0x04dcc000 },
- { _MMIO(0x9888), 0x1abd00a0 },
- { _MMIO(0x9888), 0x0abd8000 },
- { _MMIO(0x9888), 0x0cd88000 },
- { _MMIO(0x9888), 0x0ed84000 },
- { _MMIO(0x9888), 0x04d88000 },
- { _MMIO(0x9888), 0x1adb0050 },
- { _MMIO(0x9888), 0x04db8000 },
- { _MMIO(0x9888), 0x06db8000 },
- { _MMIO(0x9888), 0x08db8000 },
- { _MMIO(0x9888), 0x0adb4000 },
- { _MMIO(0x9888), 0x109f02a0 },
- { _MMIO(0x9888), 0x0c9fa000 },
- { _MMIO(0x9888), 0x0e9f00aa },
- { _MMIO(0x9888), 0x18b82500 },
- { _MMIO(0x9888), 0x02b88000 },
- { _MMIO(0x9888), 0x04b84000 },
- { _MMIO(0x9888), 0x06b84000 },
- { _MMIO(0x9888), 0x08b84000 },
- { _MMIO(0x9888), 0x0ab84000 },
- { _MMIO(0x9888), 0x0cb88000 },
- { _MMIO(0x9888), 0x0cb98000 },
- { _MMIO(0x9888), 0x0eb9a000 },
- { _MMIO(0x9888), 0x00b98000 },
- { _MMIO(0x9888), 0x02b9a000 },
- { _MMIO(0x9888), 0x04b9a000 },
- { _MMIO(0x9888), 0x06b92000 },
- { _MMIO(0x9888), 0x1aba0200 },
- { _MMIO(0x9888), 0x02ba8000 },
- { _MMIO(0x9888), 0x0cba8000 },
- { _MMIO(0x9888), 0x04908000 },
- { _MMIO(0x9888), 0x04918000 },
- { _MMIO(0x9888), 0x04927300 },
- { _MMIO(0x9888), 0x10920000 },
- { _MMIO(0x9888), 0x1893000a },
- { _MMIO(0x9888), 0x0a934000 },
- { _MMIO(0x9888), 0x0a946000 },
- { _MMIO(0x9888), 0x0c959000 },
- { _MMIO(0x9888), 0x0e950098 },
- { _MMIO(0x9888), 0x10950000 },
- { _MMIO(0x9888), 0x04b04000 },
- { _MMIO(0x9888), 0x04b14000 },
- { _MMIO(0x9888), 0x04b20073 },
- { _MMIO(0x9888), 0x10b20000 },
- { _MMIO(0x9888), 0x04b38000 },
- { _MMIO(0x9888), 0x06b38000 },
- { _MMIO(0x9888), 0x08b34000 },
- { _MMIO(0x9888), 0x04b4c000 },
- { _MMIO(0x9888), 0x02b59890 },
- { _MMIO(0x9888), 0x10b50000 },
- { _MMIO(0x9888), 0x06d04000 },
- { _MMIO(0x9888), 0x06d14000 },
- { _MMIO(0x9888), 0x06d20073 },
- { _MMIO(0x9888), 0x10d20000 },
- { _MMIO(0x9888), 0x18d30020 },
- { _MMIO(0x9888), 0x02d38000 },
- { _MMIO(0x9888), 0x0cd34000 },
- { _MMIO(0x9888), 0x0ad48000 },
- { _MMIO(0x9888), 0x04d42000 },
- { _MMIO(0x9888), 0x0ed59000 },
- { _MMIO(0x9888), 0x00d59800 },
- { _MMIO(0x9888), 0x10d50000 },
- { _MMIO(0x9888), 0x0f88000e },
- { _MMIO(0x9888), 0x03888000 },
- { _MMIO(0x9888), 0x05888000 },
- { _MMIO(0x9888), 0x07888000 },
- { _MMIO(0x9888), 0x09888000 },
- { _MMIO(0x9888), 0x0b888000 },
- { _MMIO(0x9888), 0x0d880400 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x238b5500 },
- { _MMIO(0x9888), 0x258b000a },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x038c4000 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x078c4000 },
- { _MMIO(0x9888), 0x098c4000 },
- { _MMIO(0x9888), 0x0b8c4000 },
- { _MMIO(0x9888), 0x0d8c4000 },
- { _MMIO(0x9888), 0x0d8d8000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x018d8000 },
- { _MMIO(0x9888), 0x038da000 },
- { _MMIO(0x9888), 0x058da000 },
- { _MMIO(0x9888), 0x078d2000 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x2185000a },
- { _MMIO(0x9888), 0x1b830150 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0d848000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x1d808000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47801021 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f800c64 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41800c02 },
-};
-
-static int
-get_sampler_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_sampler_1;
- lens[n] = ARRAY_SIZE(mux_config_sampler_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_sampler_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x70800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x0000c000 },
- { _MMIO(0x2774), 0x0000e7ff },
- { _MMIO(0x2778), 0x00003000 },
- { _MMIO(0x277c), 0x0000f9ff },
- { _MMIO(0x2780), 0x00000c00 },
- { _MMIO(0x2784), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_sampler_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_sampler_2[] = {
- { _MMIO(0x9888), 0x18121400 },
- { _MMIO(0x9888), 0x141500ab },
- { _MMIO(0x9888), 0x18321400 },
- { _MMIO(0x9888), 0x143500ab },
- { _MMIO(0x9888), 0x18521400 },
- { _MMIO(0x9888), 0x145500ab },
- { _MMIO(0x9888), 0x0c5c8000 },
- { _MMIO(0x9888), 0x0e5c4000 },
- { _MMIO(0x9888), 0x025cc000 },
- { _MMIO(0x9888), 0x045cc000 },
- { _MMIO(0x9888), 0x1a3d00a0 },
- { _MMIO(0x9888), 0x0a3d8000 },
- { _MMIO(0x9888), 0x0c588000 },
- { _MMIO(0x9888), 0x0e584000 },
- { _MMIO(0x9888), 0x04588000 },
- { _MMIO(0x9888), 0x1a5b0050 },
- { _MMIO(0x9888), 0x045b8000 },
- { _MMIO(0x9888), 0x065b8000 },
- { _MMIO(0x9888), 0x085b8000 },
- { _MMIO(0x9888), 0x0a5b4000 },
- { _MMIO(0x9888), 0x101f02a0 },
- { _MMIO(0x9888), 0x0c1fa000 },
- { _MMIO(0x9888), 0x0e1f00aa },
- { _MMIO(0x9888), 0x18382500 },
- { _MMIO(0x9888), 0x02388000 },
- { _MMIO(0x9888), 0x04384000 },
- { _MMIO(0x9888), 0x06384000 },
- { _MMIO(0x9888), 0x08384000 },
- { _MMIO(0x9888), 0x0a384000 },
- { _MMIO(0x9888), 0x0c388000 },
- { _MMIO(0x9888), 0x0c398000 },
- { _MMIO(0x9888), 0x0e39a000 },
- { _MMIO(0x9888), 0x00398000 },
- { _MMIO(0x9888), 0x0239a000 },
- { _MMIO(0x9888), 0x0439a000 },
- { _MMIO(0x9888), 0x06392000 },
- { _MMIO(0x9888), 0x1a3a0200 },
- { _MMIO(0x9888), 0x023a8000 },
- { _MMIO(0x9888), 0x0c3a8000 },
- { _MMIO(0x9888), 0x04108000 },
- { _MMIO(0x9888), 0x04118000 },
- { _MMIO(0x9888), 0x04127300 },
- { _MMIO(0x9888), 0x10120000 },
- { _MMIO(0x9888), 0x1813000a },
- { _MMIO(0x9888), 0x0a134000 },
- { _MMIO(0x9888), 0x0a146000 },
- { _MMIO(0x9888), 0x0c159000 },
- { _MMIO(0x9888), 0x0e150098 },
- { _MMIO(0x9888), 0x10150000 },
- { _MMIO(0x9888), 0x04304000 },
- { _MMIO(0x9888), 0x04314000 },
- { _MMIO(0x9888), 0x04320073 },
- { _MMIO(0x9888), 0x10320000 },
- { _MMIO(0x9888), 0x04338000 },
- { _MMIO(0x9888), 0x06338000 },
- { _MMIO(0x9888), 0x08334000 },
- { _MMIO(0x9888), 0x0434c000 },
- { _MMIO(0x9888), 0x02359890 },
- { _MMIO(0x9888), 0x10350000 },
- { _MMIO(0x9888), 0x06504000 },
- { _MMIO(0x9888), 0x06514000 },
- { _MMIO(0x9888), 0x06520073 },
- { _MMIO(0x9888), 0x10520000 },
- { _MMIO(0x9888), 0x18530020 },
- { _MMIO(0x9888), 0x02538000 },
- { _MMIO(0x9888), 0x0c534000 },
- { _MMIO(0x9888), 0x0a548000 },
- { _MMIO(0x9888), 0x04542000 },
- { _MMIO(0x9888), 0x0e559000 },
- { _MMIO(0x9888), 0x00559800 },
- { _MMIO(0x9888), 0x10550000 },
- { _MMIO(0x9888), 0x1b8aa000 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x278b0015 },
- { _MMIO(0x9888), 0x238b2a80 },
- { _MMIO(0x9888), 0x258b0005 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x2185000a },
- { _MMIO(0x9888), 0x1b830150 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0d848000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x1d808000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47801021 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f800c64 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41800c02 },
-};
-
-static int
-get_sampler_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_sampler_2;
- lens[n] = ARRAY_SIZE(mux_config_sampler_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fdff },
- { _MMIO(0x2778), 0x00000000 },
- { _MMIO(0x277c), 0x0000fe7f },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000ffbf },
- { _MMIO(0x2788), 0x00000000 },
- { _MMIO(0x278c), 0x0000ffcf },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000fff7 },
- { _MMIO(0x2798), 0x00000000 },
- { _MMIO(0x279c), 0x0000fff9 },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_1[] = {
- { _MMIO(0x9888), 0x16154d60 },
- { _MMIO(0x9888), 0x16352e60 },
- { _MMIO(0x9888), 0x16554d60 },
- { _MMIO(0x9888), 0x16950000 },
- { _MMIO(0x9888), 0x16b50000 },
- { _MMIO(0x9888), 0x16d50000 },
- { _MMIO(0x9888), 0x005c8000 },
- { _MMIO(0x9888), 0x045cc000 },
- { _MMIO(0x9888), 0x065c4000 },
- { _MMIO(0x9888), 0x083d8000 },
- { _MMIO(0x9888), 0x0a3d8000 },
- { _MMIO(0x9888), 0x0458c000 },
- { _MMIO(0x9888), 0x025b8000 },
- { _MMIO(0x9888), 0x085b4000 },
- { _MMIO(0x9888), 0x0a5b4000 },
- { _MMIO(0x9888), 0x0c5b8000 },
- { _MMIO(0x9888), 0x0c1fa000 },
- { _MMIO(0x9888), 0x0e1f00aa },
- { _MMIO(0x9888), 0x02384000 },
- { _MMIO(0x9888), 0x04388000 },
- { _MMIO(0x9888), 0x06388000 },
- { _MMIO(0x9888), 0x08384000 },
- { _MMIO(0x9888), 0x0a384000 },
- { _MMIO(0x9888), 0x0c384000 },
- { _MMIO(0x9888), 0x00398000 },
- { _MMIO(0x9888), 0x0239a000 },
- { _MMIO(0x9888), 0x0439a000 },
- { _MMIO(0x9888), 0x06392000 },
- { _MMIO(0x9888), 0x043a8000 },
- { _MMIO(0x9888), 0x063a8000 },
- { _MMIO(0x9888), 0x08138000 },
- { _MMIO(0x9888), 0x0a138000 },
- { _MMIO(0x9888), 0x06143000 },
- { _MMIO(0x9888), 0x0415cfc7 },
- { _MMIO(0x9888), 0x10150000 },
- { _MMIO(0x9888), 0x02338000 },
- { _MMIO(0x9888), 0x0c338000 },
- { _MMIO(0x9888), 0x04342000 },
- { _MMIO(0x9888), 0x06344000 },
- { _MMIO(0x9888), 0x0035c700 },
- { _MMIO(0x9888), 0x063500cf },
- { _MMIO(0x9888), 0x10350000 },
- { _MMIO(0x9888), 0x04538000 },
- { _MMIO(0x9888), 0x06538000 },
- { _MMIO(0x9888), 0x0454c000 },
- { _MMIO(0x9888), 0x0255cfc7 },
- { _MMIO(0x9888), 0x10550000 },
- { _MMIO(0x9888), 0x06dc8000 },
- { _MMIO(0x9888), 0x08dc4000 },
- { _MMIO(0x9888), 0x0cdcc000 },
- { _MMIO(0x9888), 0x0edcc000 },
- { _MMIO(0x9888), 0x1abd00a8 },
- { _MMIO(0x9888), 0x0cd8c000 },
- { _MMIO(0x9888), 0x0ed84000 },
- { _MMIO(0x9888), 0x0edb8000 },
- { _MMIO(0x9888), 0x18db0800 },
- { _MMIO(0x9888), 0x1adb0254 },
- { _MMIO(0x9888), 0x0e9faa00 },
- { _MMIO(0x9888), 0x109f02aa },
- { _MMIO(0x9888), 0x0eb84000 },
- { _MMIO(0x9888), 0x16b84000 },
- { _MMIO(0x9888), 0x18b8156a },
- { _MMIO(0x9888), 0x06b98000 },
- { _MMIO(0x9888), 0x08b9a000 },
- { _MMIO(0x9888), 0x0ab9a000 },
- { _MMIO(0x9888), 0x0cb9a000 },
- { _MMIO(0x9888), 0x0eb9a000 },
- { _MMIO(0x9888), 0x18baa000 },
- { _MMIO(0x9888), 0x1aba0002 },
- { _MMIO(0x9888), 0x16934000 },
- { _MMIO(0x9888), 0x1893000a },
- { _MMIO(0x9888), 0x0a947000 },
- { _MMIO(0x9888), 0x0c95c5c1 },
- { _MMIO(0x9888), 0x0e9500c3 },
- { _MMIO(0x9888), 0x10950000 },
- { _MMIO(0x9888), 0x0eb38000 },
- { _MMIO(0x9888), 0x16b30040 },
- { _MMIO(0x9888), 0x18b30020 },
- { _MMIO(0x9888), 0x06b48000 },
- { _MMIO(0x9888), 0x08b41000 },
- { _MMIO(0x9888), 0x0ab48000 },
- { _MMIO(0x9888), 0x06b5c500 },
- { _MMIO(0x9888), 0x08b500c3 },
- { _MMIO(0x9888), 0x0eb5c100 },
- { _MMIO(0x9888), 0x10b50000 },
- { _MMIO(0x9888), 0x16d31500 },
- { _MMIO(0x9888), 0x08d4e000 },
- { _MMIO(0x9888), 0x08d5c100 },
- { _MMIO(0x9888), 0x0ad5c3c5 },
- { _MMIO(0x9888), 0x10d50000 },
- { _MMIO(0x9888), 0x0d88f800 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x258baaa5 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x238b2a80 },
- { _MMIO(0x9888), 0x0f8c4000 },
- { _MMIO(0x9888), 0x178c2000 },
- { _MMIO(0x9888), 0x198c5500 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x078d8000 },
- { _MMIO(0x9888), 0x098da000 },
- { _MMIO(0x9888), 0x0b8da000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x2185aaaa },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0784c000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1780c000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800c42 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800063 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800800 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f8014a4 },
- { _MMIO(0x9888), 0x41801042 },
-};
-
-static int
-get_tdl_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_1;
- lens[n] = ARRAY_SIZE(mux_config_tdl_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fdff },
- { _MMIO(0x2778), 0x00000000 },
- { _MMIO(0x277c), 0x0000fe7f },
- { _MMIO(0x2780), 0x00000000 },
- { _MMIO(0x2784), 0x0000ff9f },
- { _MMIO(0x2788), 0x00000000 },
- { _MMIO(0x278c), 0x0000ffe7 },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000fffb },
- { _MMIO(0x2798), 0x00000002 },
- { _MMIO(0x279c), 0x0000fffd },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_2[] = {
- { _MMIO(0x9888), 0x16150000 },
- { _MMIO(0x9888), 0x16350000 },
- { _MMIO(0x9888), 0x16550000 },
- { _MMIO(0x9888), 0x16952e60 },
- { _MMIO(0x9888), 0x16b54d60 },
- { _MMIO(0x9888), 0x16d52e60 },
- { _MMIO(0x9888), 0x065c8000 },
- { _MMIO(0x9888), 0x085cc000 },
- { _MMIO(0x9888), 0x0a5cc000 },
- { _MMIO(0x9888), 0x0c5c4000 },
- { _MMIO(0x9888), 0x0e3d8000 },
- { _MMIO(0x9888), 0x183da000 },
- { _MMIO(0x9888), 0x06588000 },
- { _MMIO(0x9888), 0x08588000 },
- { _MMIO(0x9888), 0x0a584000 },
- { _MMIO(0x9888), 0x0e5b4000 },
- { _MMIO(0x9888), 0x185b5800 },
- { _MMIO(0x9888), 0x1a5b000a },
- { _MMIO(0x9888), 0x0e1faa00 },
- { _MMIO(0x9888), 0x101f02aa },
- { _MMIO(0x9888), 0x0e384000 },
- { _MMIO(0x9888), 0x16384000 },
- { _MMIO(0x9888), 0x18382a55 },
- { _MMIO(0x9888), 0x06398000 },
- { _MMIO(0x9888), 0x0839a000 },
- { _MMIO(0x9888), 0x0a39a000 },
- { _MMIO(0x9888), 0x0c39a000 },
- { _MMIO(0x9888), 0x0e39a000 },
- { _MMIO(0x9888), 0x1a3a02a0 },
- { _MMIO(0x9888), 0x0e138000 },
- { _MMIO(0x9888), 0x16130500 },
- { _MMIO(0x9888), 0x06148000 },
- { _MMIO(0x9888), 0x08146000 },
- { _MMIO(0x9888), 0x0615c100 },
- { _MMIO(0x9888), 0x0815c500 },
- { _MMIO(0x9888), 0x0a1500c3 },
- { _MMIO(0x9888), 0x10150000 },
- { _MMIO(0x9888), 0x16335040 },
- { _MMIO(0x9888), 0x08349000 },
- { _MMIO(0x9888), 0x0a341000 },
- { _MMIO(0x9888), 0x083500c1 },
- { _MMIO(0x9888), 0x0a35c500 },
- { _MMIO(0x9888), 0x0c3500c3 },
- { _MMIO(0x9888), 0x10350000 },
- { _MMIO(0x9888), 0x1853002a },
- { _MMIO(0x9888), 0x0a54e000 },
- { _MMIO(0x9888), 0x0c55c500 },
- { _MMIO(0x9888), 0x0e55c1c3 },
- { _MMIO(0x9888), 0x10550000 },
- { _MMIO(0x9888), 0x00dc8000 },
- { _MMIO(0x9888), 0x02dcc000 },
- { _MMIO(0x9888), 0x04dc4000 },
- { _MMIO(0x9888), 0x04bd8000 },
- { _MMIO(0x9888), 0x06bd8000 },
- { _MMIO(0x9888), 0x02d8c000 },
- { _MMIO(0x9888), 0x02db8000 },
- { _MMIO(0x9888), 0x04db4000 },
- { _MMIO(0x9888), 0x06db4000 },
- { _MMIO(0x9888), 0x08db8000 },
- { _MMIO(0x9888), 0x0c9fa000 },
- { _MMIO(0x9888), 0x0e9f00aa },
- { _MMIO(0x9888), 0x02b84000 },
- { _MMIO(0x9888), 0x04b84000 },
- { _MMIO(0x9888), 0x06b84000 },
- { _MMIO(0x9888), 0x08b84000 },
- { _MMIO(0x9888), 0x0ab88000 },
- { _MMIO(0x9888), 0x0cb88000 },
- { _MMIO(0x9888), 0x00b98000 },
- { _MMIO(0x9888), 0x02b9a000 },
- { _MMIO(0x9888), 0x04b9a000 },
- { _MMIO(0x9888), 0x06b92000 },
- { _MMIO(0x9888), 0x0aba8000 },
- { _MMIO(0x9888), 0x0cba8000 },
- { _MMIO(0x9888), 0x04938000 },
- { _MMIO(0x9888), 0x06938000 },
- { _MMIO(0x9888), 0x0494c000 },
- { _MMIO(0x9888), 0x0295cfc7 },
- { _MMIO(0x9888), 0x10950000 },
- { _MMIO(0x9888), 0x02b38000 },
- { _MMIO(0x9888), 0x08b38000 },
- { _MMIO(0x9888), 0x04b42000 },
- { _MMIO(0x9888), 0x06b41000 },
- { _MMIO(0x9888), 0x00b5c700 },
- { _MMIO(0x9888), 0x04b500cf },
- { _MMIO(0x9888), 0x10b50000 },
- { _MMIO(0x9888), 0x0ad38000 },
- { _MMIO(0x9888), 0x0cd38000 },
- { _MMIO(0x9888), 0x06d46000 },
- { _MMIO(0x9888), 0x04d5c700 },
- { _MMIO(0x9888), 0x06d500cf },
- { _MMIO(0x9888), 0x10d50000 },
- { _MMIO(0x9888), 0x03888000 },
- { _MMIO(0x9888), 0x05888000 },
- { _MMIO(0x9888), 0x07888000 },
- { _MMIO(0x9888), 0x09888000 },
- { _MMIO(0x9888), 0x0b888000 },
- { _MMIO(0x9888), 0x0d880400 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x198a8000 },
- { _MMIO(0x9888), 0x1b8aaaa0 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x258b555a },
- { _MMIO(0x9888), 0x278b0015 },
- { _MMIO(0x9888), 0x238b5500 },
- { _MMIO(0x9888), 0x038c4000 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x078c4000 },
- { _MMIO(0x9888), 0x098c4000 },
- { _MMIO(0x9888), 0x0b8c4000 },
- { _MMIO(0x9888), 0x0d8c4000 },
- { _MMIO(0x9888), 0x018d8000 },
- { _MMIO(0x9888), 0x038da000 },
- { _MMIO(0x9888), 0x058da000 },
- { _MMIO(0x9888), 0x078d2000 },
- { _MMIO(0x9888), 0x2185aaaa },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0784c000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1780c000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800882 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45801082 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x478014a5 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f800002 },
- { _MMIO(0x9888), 0x41800c62 },
-};
-
-static int
-get_tdl_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_2;
- lens[n] = ARRAY_SIZE(mux_config_tdl_2);
- n++;
-
- return n;
-}
-
static const struct i915_oa_reg b_counter_config_test_oa[] = {
{ _MMIO(0x2740), 0x00000000 },
{ _MMIO(0x2744), 0x00800000 },
@@ -1997,6 +60,7 @@ static const struct i915_oa_reg flex_eu_config_test_oa[] = {
};
static const struct i915_oa_reg mux_config_test_oa[] = {
+ { _MMIO(0x9840), 0x000000a0 },
{ _MMIO(0x9888), 0x59800000 },
{ _MMIO(0x9888), 0x59800001 },
{ _MMIO(0x9888), 0x338b0000 },
@@ -2008,866 +72,38 @@ static const struct i915_oa_reg mux_config_test_oa[] = {
{ _MMIO(0x9888), 0x57800000 },
{ _MMIO(0x1823a4), 0x00000000 },
{ _MMIO(0x9888), 0x59800000 },
-};
-
-static int
-get_test_oa_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_test_oa;
- lens[n] = ARRAY_SIZE(mux_config_test_oa);
- n++;
-
- return n;
-}
-
-int i915_oa_select_metric_set_chv(struct drm_i915_private *dev_priv)
-{
- dev_priv->perf.oa.n_mux_configs = 0;
- dev_priv->perf.oa.b_counter_regs = NULL;
- dev_priv->perf.oa.b_counter_regs_len = 0;
- dev_priv->perf.oa.flex_regs = NULL;
- dev_priv->perf.oa.flex_regs_len = 0;
-
- switch (dev_priv->perf.oa.metrics_set) {
- case METRIC_SET_ID_RENDER_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_render_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_basic);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_basic);
-
- return 0;
- case METRIC_SET_ID_RENDER_PIPE_PROFILE:
- dev_priv->perf.oa.n_mux_configs =
- get_render_pipe_profile_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_pipe_profile;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_pipe_profile);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_pipe_profile;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_pipe_profile);
-
- return 0;
- case METRIC_SET_ID_HDC_AND_SF:
- dev_priv->perf.oa.n_mux_configs =
- get_hdc_and_sf_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_hdc_and_sf;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_hdc_and_sf);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_hdc_and_sf;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_hdc_and_sf);
-
- return 0;
- case METRIC_SET_ID_L3_1:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_1);
-
- return 0;
- case METRIC_SET_ID_L3_2:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_2);
-
- return 0;
- case METRIC_SET_ID_L3_3:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_3_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_3\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_3;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_3);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_3;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_3);
-
- return 0;
- case METRIC_SET_ID_L3_4:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_4_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_4\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_4;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_4);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_4;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_4);
-
- return 0;
- case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND:
- dev_priv->perf.oa.n_mux_configs =
- get_rasterizer_and_pixel_backend_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend);
-
- return 0;
- case METRIC_SET_ID_SAMPLER_1:
- dev_priv->perf.oa.n_mux_configs =
- get_sampler_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_sampler_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_sampler_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_sampler_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_sampler_1);
-
- return 0;
- case METRIC_SET_ID_SAMPLER_2:
- dev_priv->perf.oa.n_mux_configs =
- get_sampler_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_sampler_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_sampler_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_sampler_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_sampler_2);
-
- return 0;
- case METRIC_SET_ID_TDL_1:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_1);
-
- return 0;
- case METRIC_SET_ID_TDL_2:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_2);
-
- return 0;
- case METRIC_SET_ID_TEST_OA:
- dev_priv->perf.oa.n_mux_configs =
- get_test_oa_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_test_oa;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_test_oa);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_test_oa;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_test_oa);
-
- return 0;
- default:
- return -ENODEV;
- }
-}
-
-static ssize_t
-show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC);
-}
-
-static struct device_attribute dev_attr_render_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_basic[] = {
- &dev_attr_render_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_basic = {
- .name = "9d8a3af5-c02c-4a4a-b947-f1672469e0fb",
- .attrs = attrs_render_basic,
-};
-
-static ssize_t
-show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC);
-}
-
-static struct device_attribute dev_attr_compute_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_basic[] = {
- &dev_attr_compute_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_basic = {
- .name = "f522a89c-ecd1-4522-8331-3383c54af5f5",
- .attrs = attrs_compute_basic,
-};
-
-static ssize_t
-show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE);
-}
-
-static struct device_attribute dev_attr_render_pipe_profile_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_pipe_profile_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_pipe_profile[] = {
- &dev_attr_render_pipe_profile_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_pipe_profile = {
- .name = "a9ccc03d-a943-4e6b-9cd6-13e063075927",
- .attrs = attrs_render_pipe_profile,
-};
-
-static ssize_t
-show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF);
-}
-
-static struct device_attribute dev_attr_hdc_and_sf_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_hdc_and_sf_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_hdc_and_sf[] = {
- &dev_attr_hdc_and_sf_id.attr,
- NULL,
-};
-
-static struct attribute_group group_hdc_and_sf = {
- .name = "2cf0c064-68df-4fac-9b3f-57f51ca8a069",
- .attrs = attrs_hdc_and_sf,
-};
-
-static ssize_t
-show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1);
-}
-
-static struct device_attribute dev_attr_l3_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_1[] = {
- &dev_attr_l3_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_1 = {
- .name = "78a87ff9-543a-49ce-95ea-26d86071ea93",
- .attrs = attrs_l3_1,
-};
-
-static ssize_t
-show_l3_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_2);
-}
-
-static struct device_attribute dev_attr_l3_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_2[] = {
- &dev_attr_l3_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_2 = {
- .name = "9f2cece5-7bfe-4320-ad66-8c7cc526bec5",
- .attrs = attrs_l3_2,
-};
-
-static ssize_t
-show_l3_3_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_3);
-}
-
-static struct device_attribute dev_attr_l3_3_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_3_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_3[] = {
- &dev_attr_l3_3_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_3 = {
- .name = "d890ef38-d309-47e4-b8b5-aa779bb19ab0",
- .attrs = attrs_l3_3,
-};
-
-static ssize_t
-show_l3_4_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_4);
-}
-
-static struct device_attribute dev_attr_l3_4_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_4_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_4[] = {
- &dev_attr_l3_4_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_4 = {
- .name = "5fdff4a6-9dc8-45e1-bfda-ef54869fbdd4",
- .attrs = attrs_l3_4,
-};
-
-static ssize_t
-show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND);
-}
-
-static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_rasterizer_and_pixel_backend_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_rasterizer_and_pixel_backend[] = {
- &dev_attr_rasterizer_and_pixel_backend_id.attr,
- NULL,
-};
-
-static struct attribute_group group_rasterizer_and_pixel_backend = {
- .name = "2c0e45e1-7e2c-4a14-ae00-0b7ec868b8aa",
- .attrs = attrs_rasterizer_and_pixel_backend,
-};
-
-static ssize_t
-show_sampler_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER_1);
-}
-
-static struct device_attribute dev_attr_sampler_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_sampler_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_sampler_1[] = {
- &dev_attr_sampler_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_sampler_1 = {
- .name = "71148d78-baf5-474f-878a-e23158d0265d",
- .attrs = attrs_sampler_1,
-};
-
-static ssize_t
-show_sampler_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER_2);
-}
-
-static struct device_attribute dev_attr_sampler_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_sampler_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_sampler_2[] = {
- &dev_attr_sampler_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_sampler_2 = {
- .name = "b996a2b7-c59c-492d-877a-8cd54fd6df84",
- .attrs = attrs_sampler_2,
-};
-
-static ssize_t
-show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1);
-}
-
-static struct device_attribute dev_attr_tdl_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_1[] = {
- &dev_attr_tdl_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_1 = {
- .name = "eb2fecba-b431-42e7-8261-fe9429a6e67a",
- .attrs = attrs_tdl_1,
-};
-
-static ssize_t
-show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2);
-}
-
-static struct device_attribute dev_attr_tdl_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_2[] = {
- &dev_attr_tdl_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_2 = {
- .name = "60749470-a648-4a4b-9f10-dbfe1e36e44d",
- .attrs = attrs_tdl_2,
+ { _MMIO(0x9840), 0x00000080 },
};
static ssize_t
show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA);
+ return sprintf(buf, "1\n");
}
-static struct device_attribute dev_attr_test_oa_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_test_oa_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_test_oa[] = {
- &dev_attr_test_oa_id.attr,
- NULL,
-};
-
-static struct attribute_group group_test_oa = {
- .name = "4a534b07-cba3-414d-8d60-874830e883aa",
- .attrs = attrs_test_oa,
-};
-
-int
-i915_perf_register_sysfs_chv(struct drm_i915_private *dev_priv)
+void
+i915_perf_load_test_config_chv(struct drm_i915_private *dev_priv)
{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
- int ret = 0;
+ strncpy(dev_priv->perf.oa.test_config.uuid,
+ "4a534b07-cba3-414d-8d60-874830e883aa",
+ UUID_STRING_LEN);
+ dev_priv->perf.oa.test_config.id = 1;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (ret)
- goto error_render_basic;
- }
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (ret)
- goto error_compute_basic;
- }
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (ret)
- goto error_render_pipe_profile;
- }
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (ret)
- goto error_hdc_and_sf;
- }
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (ret)
- goto error_l3_1;
- }
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (ret)
- goto error_l3_2;
- }
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (ret)
- goto error_l3_3;
- }
- if (get_l3_4_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_4);
- if (ret)
- goto error_l3_4;
- }
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (ret)
- goto error_rasterizer_and_pixel_backend;
- }
- if (get_sampler_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler_1);
- if (ret)
- goto error_sampler_1;
- }
- if (get_sampler_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler_2);
- if (ret)
- goto error_sampler_2;
- }
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (ret)
- goto error_tdl_1;
- }
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (ret)
- goto error_tdl_2;
- }
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa);
- if (ret)
- goto error_test_oa;
- }
+ dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
+ dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
- return 0;
+ dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
+ dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-error_test_oa:
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
-error_tdl_2:
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
-error_tdl_1:
- if (get_sampler_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_2);
-error_sampler_2:
- if (get_sampler_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_1);
-error_sampler_1:
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
-error_rasterizer_and_pixel_backend:
- if (get_l3_4_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_4);
-error_l3_4:
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
-error_l3_3:
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
-error_l3_2:
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
-error_l3_1:
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
-error_hdc_and_sf:
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
-error_render_pipe_profile:
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
-error_compute_basic:
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
-error_render_basic:
- return ret;
-}
+ dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
+ dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-void
-i915_perf_unregister_sysfs_chv(struct drm_i915_private *dev_priv)
-{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
+ dev_priv->perf.oa.test_config.sysfs_metric.name = "4a534b07-cba3-414d-8d60-874830e883aa";
+ dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+
+ dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (get_l3_4_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_4);
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (get_sampler_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_1);
- if (get_sampler_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_2);
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa);
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
+ dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
}
diff --git a/drivers/gpu/drm/i915/i915_oa_chv.h b/drivers/gpu/drm/i915/i915_oa_chv.h
index 8b8bdc2..b962249 100644
--- a/drivers/gpu/drm/i915/i915_oa_chv.h
+++ b/drivers/gpu/drm/i915/i915_oa_chv.h
@@ -29,12 +29,6 @@
#ifndef __I915_OA_CHV_H__
#define __I915_OA_CHV_H__
-extern int i915_oa_n_builtin_metric_sets_chv;
-
-extern int i915_oa_select_metric_set_chv(struct drm_i915_private *dev_priv);
-
-extern int i915_perf_register_sysfs_chv(struct drm_i915_private *dev_priv);
-
-extern void i915_perf_unregister_sysfs_chv(struct drm_i915_private *dev_priv);
+extern void i915_perf_load_test_config_chv(struct drm_i915_private *dev_priv);
#endif
diff --git a/drivers/gpu/drm/i915/i915_oa_glk.c b/drivers/gpu/drm/i915/i915_oa_glk.c
index 2f356d5..4ee527e 100644
--- a/drivers/gpu/drm/i915/i915_oa_glk.c
+++ b/drivers/gpu/drm/i915/i915_oa_glk.c
@@ -31,1614 +31,6 @@
#include "i915_drv.h"
#include "i915_oa_glk.h"
-enum metric_set_id {
- METRIC_SET_ID_RENDER_BASIC = 1,
- METRIC_SET_ID_COMPUTE_BASIC,
- METRIC_SET_ID_RENDER_PIPE_PROFILE,
- METRIC_SET_ID_MEMORY_READS,
- METRIC_SET_ID_MEMORY_WRITES,
- METRIC_SET_ID_COMPUTE_EXTENDED,
- METRIC_SET_ID_COMPUTE_L3_CACHE,
- METRIC_SET_ID_HDC_AND_SF,
- METRIC_SET_ID_L3_1,
- METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND,
- METRIC_SET_ID_SAMPLER,
- METRIC_SET_ID_TDL_1,
- METRIC_SET_ID_TDL_2,
- METRIC_SET_ID_COMPUTE_EXTRA,
- METRIC_SET_ID_TEST_OA,
-};
-
-int i915_oa_n_builtin_metric_sets_glk = 15;
-
-static const struct i915_oa_reg b_counter_config_render_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_render_basic[] = {
- { _MMIO(0x9888), 0x166c00f0 },
- { _MMIO(0x9888), 0x12120280 },
- { _MMIO(0x9888), 0x12320280 },
- { _MMIO(0x9888), 0x11930317 },
- { _MMIO(0x9888), 0x159303df },
- { _MMIO(0x9888), 0x3f900c00 },
- { _MMIO(0x9888), 0x419000a0 },
- { _MMIO(0x9888), 0x002d1000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x082d5000 },
- { _MMIO(0x9888), 0x0a2d1000 },
- { _MMIO(0x9888), 0x0c2e0800 },
- { _MMIO(0x9888), 0x0e2e5900 },
- { _MMIO(0x9888), 0x0a4c8000 },
- { _MMIO(0x9888), 0x0c4c8000 },
- { _MMIO(0x9888), 0x0e4c4000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e2000 },
- { _MMIO(0x9888), 0x1c4f0010 },
- { _MMIO(0x9888), 0x0a6c0053 },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1a0fcc00 },
- { _MMIO(0x9888), 0x1c0f0002 },
- { _MMIO(0x9888), 0x1c2c0040 },
- { _MMIO(0x9888), 0x00101000 },
- { _MMIO(0x9888), 0x04101000 },
- { _MMIO(0x9888), 0x00114000 },
- { _MMIO(0x9888), 0x08114000 },
- { _MMIO(0x9888), 0x00120020 },
- { _MMIO(0x9888), 0x08120021 },
- { _MMIO(0x9888), 0x00141000 },
- { _MMIO(0x9888), 0x08141000 },
- { _MMIO(0x9888), 0x02308000 },
- { _MMIO(0x9888), 0x04302000 },
- { _MMIO(0x9888), 0x06318000 },
- { _MMIO(0x9888), 0x08318000 },
- { _MMIO(0x9888), 0x06320800 },
- { _MMIO(0x9888), 0x08320840 },
- { _MMIO(0x9888), 0x00320000 },
- { _MMIO(0x9888), 0x06344000 },
- { _MMIO(0x9888), 0x08344000 },
- { _MMIO(0x9888), 0x0d931831 },
- { _MMIO(0x9888), 0x0f939f3f },
- { _MMIO(0x9888), 0x01939e80 },
- { _MMIO(0x9888), 0x039303bc },
- { _MMIO(0x9888), 0x0593000e },
- { _MMIO(0x9888), 0x1993002a },
- { _MMIO(0x9888), 0x07930000 },
- { _MMIO(0x9888), 0x09930000 },
- { _MMIO(0x9888), 0x1d900177 },
- { _MMIO(0x9888), 0x1f900187 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x23904000 },
- { _MMIO(0x9888), 0x25904000 },
- { _MMIO(0x9888), 0x27904000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x53901110 },
- { _MMIO(0x9888), 0x43900423 },
- { _MMIO(0x9888), 0x55900111 },
- { _MMIO(0x9888), 0x47900c02 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900020 },
- { _MMIO(0x9888), 0x59901111 },
- { _MMIO(0x9888), 0x4b900421 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900001 },
- { _MMIO(0x9888), 0x45900821 },
-};
-
-static int
-get_render_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_basic;
- lens[n] = ARRAY_SIZE(mux_config_render_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_basic[] = {
- { _MMIO(0x9888), 0x104f00e0 },
- { _MMIO(0x9888), 0x124f1c00 },
- { _MMIO(0x9888), 0x39900340 },
- { _MMIO(0x9888), 0x3f900c00 },
- { _MMIO(0x9888), 0x41900000 },
- { _MMIO(0x9888), 0x002d5000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x082d4000 },
- { _MMIO(0x9888), 0x0a2d1000 },
- { _MMIO(0x9888), 0x0c2d5000 },
- { _MMIO(0x9888), 0x0e2d4000 },
- { _MMIO(0x9888), 0x0c2e1400 },
- { _MMIO(0x9888), 0x0e2e5100 },
- { _MMIO(0x9888), 0x102e0114 },
- { _MMIO(0x9888), 0x044cc000 },
- { _MMIO(0x9888), 0x0a4c8000 },
- { _MMIO(0x9888), 0x0c4c8000 },
- { _MMIO(0x9888), 0x0e4c4000 },
- { _MMIO(0x9888), 0x104c8000 },
- { _MMIO(0x9888), 0x124c8000 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x004ea000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e2000 },
- { _MMIO(0x9888), 0x0c4ea000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x004f6b42 },
- { _MMIO(0x9888), 0x064f6200 },
- { _MMIO(0x9888), 0x084f4100 },
- { _MMIO(0x9888), 0x0a4f0061 },
- { _MMIO(0x9888), 0x0c4f6c4c },
- { _MMIO(0x9888), 0x0e4f4b00 },
- { _MMIO(0x9888), 0x1a4f0000 },
- { _MMIO(0x9888), 0x1c4f0000 },
- { _MMIO(0x9888), 0x180f5000 },
- { _MMIO(0x9888), 0x1a0f8800 },
- { _MMIO(0x9888), 0x1c0f08a2 },
- { _MMIO(0x9888), 0x182c4000 },
- { _MMIO(0x9888), 0x1c2c1451 },
- { _MMIO(0x9888), 0x1e2c0001 },
- { _MMIO(0x9888), 0x1a2c0010 },
- { _MMIO(0x9888), 0x01938000 },
- { _MMIO(0x9888), 0x0f938000 },
- { _MMIO(0x9888), 0x19938a28 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x19900177 },
- { _MMIO(0x9888), 0x1b900178 },
- { _MMIO(0x9888), 0x1d900125 },
- { _MMIO(0x9888), 0x1f900123 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x25904000 },
- { _MMIO(0x9888), 0x27904000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x53901000 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x55900111 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900000 },
- { _MMIO(0x9888), 0x45900000 },
-};
-
-static int
-get_compute_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_basic;
- lens[n] = ARRAY_SIZE(mux_config_compute_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007ffea },
- { _MMIO(0x2774), 0x00007ffc },
- { _MMIO(0x2778), 0x0007affa },
- { _MMIO(0x277c), 0x0000f5fd },
- { _MMIO(0x2780), 0x00079ffa },
- { _MMIO(0x2784), 0x0000f3fb },
- { _MMIO(0x2788), 0x0007bf7a },
- { _MMIO(0x278c), 0x0000f7e7 },
- { _MMIO(0x2790), 0x0007fefa },
- { _MMIO(0x2794), 0x0000f7cf },
- { _MMIO(0x2798), 0x00077ffa },
- { _MMIO(0x279c), 0x0000efdf },
- { _MMIO(0x27a0), 0x0006fffa },
- { _MMIO(0x27a4), 0x0000cfbf },
- { _MMIO(0x27a8), 0x0003fffa },
- { _MMIO(0x27ac), 0x00005f7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_render_pipe_profile[] = {
- { _MMIO(0x9888), 0x0c2e001f },
- { _MMIO(0x9888), 0x0a2f0000 },
- { _MMIO(0x9888), 0x10186800 },
- { _MMIO(0x9888), 0x11810019 },
- { _MMIO(0x9888), 0x15810013 },
- { _MMIO(0x9888), 0x13820020 },
- { _MMIO(0x9888), 0x11830020 },
- { _MMIO(0x9888), 0x17840000 },
- { _MMIO(0x9888), 0x11860007 },
- { _MMIO(0x9888), 0x21860000 },
- { _MMIO(0x9888), 0x178703e0 },
- { _MMIO(0x9888), 0x0c2d8000 },
- { _MMIO(0x9888), 0x042d4000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x022e5400 },
- { _MMIO(0x9888), 0x002e0000 },
- { _MMIO(0x9888), 0x0e2e0080 },
- { _MMIO(0x9888), 0x082f0040 },
- { _MMIO(0x9888), 0x002f0000 },
- { _MMIO(0x9888), 0x06143000 },
- { _MMIO(0x9888), 0x06174000 },
- { _MMIO(0x9888), 0x06180012 },
- { _MMIO(0x9888), 0x00180000 },
- { _MMIO(0x9888), 0x0d804000 },
- { _MMIO(0x9888), 0x0f804000 },
- { _MMIO(0x9888), 0x05804000 },
- { _MMIO(0x9888), 0x09810200 },
- { _MMIO(0x9888), 0x0b810030 },
- { _MMIO(0x9888), 0x03810003 },
- { _MMIO(0x9888), 0x21819140 },
- { _MMIO(0x9888), 0x23819050 },
- { _MMIO(0x9888), 0x25810018 },
- { _MMIO(0x9888), 0x0b820980 },
- { _MMIO(0x9888), 0x03820d80 },
- { _MMIO(0x9888), 0x11820000 },
- { _MMIO(0x9888), 0x0182c000 },
- { _MMIO(0x9888), 0x07828000 },
- { _MMIO(0x9888), 0x09824000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x0d830004 },
- { _MMIO(0x9888), 0x0583000c },
- { _MMIO(0x9888), 0x0f831000 },
- { _MMIO(0x9888), 0x01848072 },
- { _MMIO(0x9888), 0x11840000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x09844000 },
- { _MMIO(0x9888), 0x0f848000 },
- { _MMIO(0x9888), 0x07860000 },
- { _MMIO(0x9888), 0x09860092 },
- { _MMIO(0x9888), 0x0f860400 },
- { _MMIO(0x9888), 0x01869100 },
- { _MMIO(0x9888), 0x0f870065 },
- { _MMIO(0x9888), 0x01870000 },
- { _MMIO(0x9888), 0x19930800 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x1b952000 },
- { _MMIO(0x9888), 0x1d955055 },
- { _MMIO(0x9888), 0x1f951455 },
- { _MMIO(0x9888), 0x0992a000 },
- { _MMIO(0x9888), 0x0f928000 },
- { _MMIO(0x9888), 0x1192a800 },
- { _MMIO(0x9888), 0x1392028a },
- { _MMIO(0x9888), 0x0b92a000 },
- { _MMIO(0x9888), 0x0d922000 },
- { _MMIO(0x9888), 0x13908000 },
- { _MMIO(0x9888), 0x21908000 },
- { _MMIO(0x9888), 0x23908000 },
- { _MMIO(0x9888), 0x25908000 },
- { _MMIO(0x9888), 0x27908000 },
- { _MMIO(0x9888), 0x29908000 },
- { _MMIO(0x9888), 0x2b908000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f908000 },
- { _MMIO(0x9888), 0x31908000 },
- { _MMIO(0x9888), 0x15908000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900c01 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900863 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900061 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900000 },
- { _MMIO(0x9888), 0x45900c22 },
-};
-
-static int
-get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_pipe_profile;
- lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_reads[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f872 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_reads[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_reads[] = {
- { _MMIO(0x9888), 0x19800343 },
- { _MMIO(0x9888), 0x39900340 },
- { _MMIO(0x9888), 0x3f901000 },
- { _MMIO(0x9888), 0x41900003 },
- { _MMIO(0x9888), 0x03803180 },
- { _MMIO(0x9888), 0x058035e2 },
- { _MMIO(0x9888), 0x0780006a },
- { _MMIO(0x9888), 0x11800000 },
- { _MMIO(0x9888), 0x2181a000 },
- { _MMIO(0x9888), 0x2381000a },
- { _MMIO(0x9888), 0x1d950550 },
- { _MMIO(0x9888), 0x0b928000 },
- { _MMIO(0x9888), 0x0d92a000 },
- { _MMIO(0x9888), 0x0f922000 },
- { _MMIO(0x9888), 0x13900170 },
- { _MMIO(0x9888), 0x21900171 },
- { _MMIO(0x9888), 0x23900172 },
- { _MMIO(0x9888), 0x25900173 },
- { _MMIO(0x9888), 0x27900174 },
- { _MMIO(0x9888), 0x29900175 },
- { _MMIO(0x9888), 0x2b900176 },
- { _MMIO(0x9888), 0x2d900177 },
- { _MMIO(0x9888), 0x2f90017f },
- { _MMIO(0x9888), 0x31900125 },
- { _MMIO(0x9888), 0x15900123 },
- { _MMIO(0x9888), 0x17900121 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43901084 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47901080 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49901084 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b901084 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900004 },
- { _MMIO(0x9888), 0x45900000 },
-};
-
-static int
-get_memory_reads_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_reads;
- lens[n] = ARRAY_SIZE(mux_config_memory_reads);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_writes[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f822 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_writes[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_writes[] = {
- { _MMIO(0x9888), 0x19800343 },
- { _MMIO(0x9888), 0x39900340 },
- { _MMIO(0x9888), 0x3f900000 },
- { _MMIO(0x9888), 0x41900080 },
- { _MMIO(0x9888), 0x03803180 },
- { _MMIO(0x9888), 0x058035e2 },
- { _MMIO(0x9888), 0x0780006a },
- { _MMIO(0x9888), 0x11800000 },
- { _MMIO(0x9888), 0x2181a000 },
- { _MMIO(0x9888), 0x2381000a },
- { _MMIO(0x9888), 0x1d950550 },
- { _MMIO(0x9888), 0x0b928000 },
- { _MMIO(0x9888), 0x0d92a000 },
- { _MMIO(0x9888), 0x0f922000 },
- { _MMIO(0x9888), 0x13900180 },
- { _MMIO(0x9888), 0x21900181 },
- { _MMIO(0x9888), 0x23900182 },
- { _MMIO(0x9888), 0x25900183 },
- { _MMIO(0x9888), 0x27900184 },
- { _MMIO(0x9888), 0x29900185 },
- { _MMIO(0x9888), 0x2b900186 },
- { _MMIO(0x9888), 0x2d900187 },
- { _MMIO(0x9888), 0x2f900170 },
- { _MMIO(0x9888), 0x31900125 },
- { _MMIO(0x9888), 0x15900123 },
- { _MMIO(0x9888), 0x17900121 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43901084 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47901080 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49901084 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b901084 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900004 },
- { _MMIO(0x9888), 0x45900000 },
-};
-
-static int
-get_memory_writes_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_writes;
- lens[n] = ARRAY_SIZE(mux_config_memory_writes);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extended[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fc2a },
- { _MMIO(0x2774), 0x0000bf00 },
- { _MMIO(0x2778), 0x0007fc6a },
- { _MMIO(0x277c), 0x0000bf00 },
- { _MMIO(0x2780), 0x0007fc92 },
- { _MMIO(0x2784), 0x0000bf00 },
- { _MMIO(0x2788), 0x0007fca2 },
- { _MMIO(0x278c), 0x0000bf00 },
- { _MMIO(0x2790), 0x0007fc32 },
- { _MMIO(0x2794), 0x0000bf00 },
- { _MMIO(0x2798), 0x0007fc9a },
- { _MMIO(0x279c), 0x0000bf00 },
- { _MMIO(0x27a0), 0x0007fe6a },
- { _MMIO(0x27a4), 0x0000bf00 },
- { _MMIO(0x27a8), 0x0007fe7a },
- { _MMIO(0x27ac), 0x0000bf00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extended[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended[] = {
- { _MMIO(0x9888), 0x104f00e0 },
- { _MMIO(0x9888), 0x141c0160 },
- { _MMIO(0x9888), 0x161c0015 },
- { _MMIO(0x9888), 0x181c0120 },
- { _MMIO(0x9888), 0x002d5000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x082d5000 },
- { _MMIO(0x9888), 0x0a2d5000 },
- { _MMIO(0x9888), 0x0c2d5000 },
- { _MMIO(0x9888), 0x0e2d5000 },
- { _MMIO(0x9888), 0x022d5000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x0c2e5400 },
- { _MMIO(0x9888), 0x0e2e5515 },
- { _MMIO(0x9888), 0x102e0155 },
- { _MMIO(0x9888), 0x044cc000 },
- { _MMIO(0x9888), 0x0a4c8000 },
- { _MMIO(0x9888), 0x0c4cc000 },
- { _MMIO(0x9888), 0x0e4cc000 },
- { _MMIO(0x9888), 0x104c8000 },
- { _MMIO(0x9888), 0x124c8000 },
- { _MMIO(0x9888), 0x144c8000 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x064cc000 },
- { _MMIO(0x9888), 0x084cc000 },
- { _MMIO(0x9888), 0x004ea000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084ea000 },
- { _MMIO(0x9888), 0x0a4ea000 },
- { _MMIO(0x9888), 0x0c4ea000 },
- { _MMIO(0x9888), 0x0e4ea000 },
- { _MMIO(0x9888), 0x024ea000 },
- { _MMIO(0x9888), 0x044ea000 },
- { _MMIO(0x9888), 0x0e4f4b41 },
- { _MMIO(0x9888), 0x004f4200 },
- { _MMIO(0x9888), 0x024f404c },
- { _MMIO(0x9888), 0x1c4f0000 },
- { _MMIO(0x9888), 0x1a4f0000 },
- { _MMIO(0x9888), 0x001b4000 },
- { _MMIO(0x9888), 0x061b8000 },
- { _MMIO(0x9888), 0x081bc000 },
- { _MMIO(0x9888), 0x0a1bc000 },
- { _MMIO(0x9888), 0x0c1bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x001c0031 },
- { _MMIO(0x9888), 0x061c1900 },
- { _MMIO(0x9888), 0x081c1a33 },
- { _MMIO(0x9888), 0x0a1c1b35 },
- { _MMIO(0x9888), 0x0c1c3337 },
- { _MMIO(0x9888), 0x041c31c7 },
- { _MMIO(0x9888), 0x180f5000 },
- { _MMIO(0x9888), 0x1a0fa8aa },
- { _MMIO(0x9888), 0x1c0f0aaa },
- { _MMIO(0x9888), 0x182c8000 },
- { _MMIO(0x9888), 0x1c2c6aaa },
- { _MMIO(0x9888), 0x1e2c0001 },
- { _MMIO(0x9888), 0x1a2c2950 },
- { _MMIO(0x9888), 0x01938000 },
- { _MMIO(0x9888), 0x0f938000 },
- { _MMIO(0x9888), 0x1993aaaa },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x23904000 },
- { _MMIO(0x9888), 0x25904000 },
- { _MMIO(0x9888), 0x27904000 },
- { _MMIO(0x9888), 0x29904000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900420 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900400 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900001 },
- { _MMIO(0x9888), 0x45900001 },
-};
-
-static int
-get_compute_extended_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extended;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_l3_cache[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fffa },
- { _MMIO(0x2774), 0x0000fefe },
- { _MMIO(0x2778), 0x0007fffa },
- { _MMIO(0x277c), 0x0000fefd },
- { _MMIO(0x2790), 0x0007fffa },
- { _MMIO(0x2794), 0x0000fbef },
- { _MMIO(0x2798), 0x0007fffa },
- { _MMIO(0x279c), 0x0000fbdf },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_l3_cache[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00101100 },
- { _MMIO(0xe45c), 0x00201200 },
- { _MMIO(0xe55c), 0x00301300 },
- { _MMIO(0xe65c), 0x00401400 },
-};
-
-static const struct i915_oa_reg mux_config_compute_l3_cache[] = {
- { _MMIO(0x9888), 0x166c03b0 },
- { _MMIO(0x9888), 0x1593001e },
- { _MMIO(0x9888), 0x3f900c00 },
- { _MMIO(0x9888), 0x41900000 },
- { _MMIO(0x9888), 0x002d1000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x082d5000 },
- { _MMIO(0x9888), 0x0e2d5000 },
- { _MMIO(0x9888), 0x0c2e0400 },
- { _MMIO(0x9888), 0x0e2e1500 },
- { _MMIO(0x9888), 0x102e0140 },
- { _MMIO(0x9888), 0x044c4000 },
- { _MMIO(0x9888), 0x0a4c8000 },
- { _MMIO(0x9888), 0x0c4cc000 },
- { _MMIO(0x9888), 0x144c8000 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x004e2000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084ea000 },
- { _MMIO(0x9888), 0x0e4ea000 },
- { _MMIO(0x9888), 0x1a4f4001 },
- { _MMIO(0x9888), 0x1c4f5005 },
- { _MMIO(0x9888), 0x006c0051 },
- { _MMIO(0x9888), 0x066c5000 },
- { _MMIO(0x9888), 0x086c5c5d },
- { _MMIO(0x9888), 0x0e6c5e5f },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x146c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x180f1000 },
- { _MMIO(0x9888), 0x1a0fa800 },
- { _MMIO(0x9888), 0x1c0f0a00 },
- { _MMIO(0x9888), 0x182c4000 },
- { _MMIO(0x9888), 0x1c2c4015 },
- { _MMIO(0x9888), 0x1e2c0001 },
- { _MMIO(0x9888), 0x03931980 },
- { _MMIO(0x9888), 0x05930032 },
- { _MMIO(0x9888), 0x11930000 },
- { _MMIO(0x9888), 0x01938000 },
- { _MMIO(0x9888), 0x0f938000 },
- { _MMIO(0x9888), 0x1993a00a },
- { _MMIO(0x9888), 0x07930000 },
- { _MMIO(0x9888), 0x09930000 },
- { _MMIO(0x9888), 0x1d900177 },
- { _MMIO(0x9888), 0x1f900178 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x23904000 },
- { _MMIO(0x9888), 0x25904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x53901000 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x55900111 },
- { _MMIO(0x9888), 0x47900001 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x4d900000 },
- { _MMIO(0x9888), 0x45900400 },
-};
-
-static int
-get_compute_l3_cache_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_l3_cache;
- lens[n] = ARRAY_SIZE(mux_config_compute_l3_cache);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x10800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fdff },
-};
-
-static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_hdc_and_sf[] = {
- { _MMIO(0x9888), 0x104f0232 },
- { _MMIO(0x9888), 0x124f4640 },
- { _MMIO(0x9888), 0x11834400 },
- { _MMIO(0x9888), 0x022d4000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x0e2e0055 },
- { _MMIO(0x9888), 0x064c8000 },
- { _MMIO(0x9888), 0x084cc000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x024e8000 },
- { _MMIO(0x9888), 0x044ea000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x024f6100 },
- { _MMIO(0x9888), 0x044f416b },
- { _MMIO(0x9888), 0x064f004b },
- { _MMIO(0x9888), 0x1a4f0000 },
- { _MMIO(0x9888), 0x1a0f02a8 },
- { _MMIO(0x9888), 0x1a2c5500 },
- { _MMIO(0x9888), 0x0f808000 },
- { _MMIO(0x9888), 0x25810020 },
- { _MMIO(0x9888), 0x0f8305c0 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x1f951000 },
- { _MMIO(0x9888), 0x13920200 },
- { _MMIO(0x9888), 0x31908000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4d900003 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_hdc_and_sf;
- lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_1[] = {
- { _MMIO(0x9888), 0x12643400 },
- { _MMIO(0x9888), 0x12653400 },
- { _MMIO(0x9888), 0x106c6800 },
- { _MMIO(0x9888), 0x126c001e },
- { _MMIO(0x9888), 0x166c0010 },
- { _MMIO(0x9888), 0x0c2d5000 },
- { _MMIO(0x9888), 0x0e2d5000 },
- { _MMIO(0x9888), 0x002d4000 },
- { _MMIO(0x9888), 0x022d5000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x102e0154 },
- { _MMIO(0x9888), 0x0c2e5000 },
- { _MMIO(0x9888), 0x0e2e0055 },
- { _MMIO(0x9888), 0x104c8000 },
- { _MMIO(0x9888), 0x124c8000 },
- { _MMIO(0x9888), 0x144c8000 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x044c8000 },
- { _MMIO(0x9888), 0x064cc000 },
- { _MMIO(0x9888), 0x084cc000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x0c4ea000 },
- { _MMIO(0x9888), 0x0e4ea000 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x024ea000 },
- { _MMIO(0x9888), 0x044ea000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x1c4f5500 },
- { _MMIO(0x9888), 0x1a4f1554 },
- { _MMIO(0x9888), 0x0a640024 },
- { _MMIO(0x9888), 0x10640000 },
- { _MMIO(0x9888), 0x04640000 },
- { _MMIO(0x9888), 0x0c650024 },
- { _MMIO(0x9888), 0x10650000 },
- { _MMIO(0x9888), 0x06650000 },
- { _MMIO(0x9888), 0x0c6c5327 },
- { _MMIO(0x9888), 0x0e6c5425 },
- { _MMIO(0x9888), 0x006c2a00 },
- { _MMIO(0x9888), 0x026c285b },
- { _MMIO(0x9888), 0x046c005c },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1a6c0900 },
- { _MMIO(0x9888), 0x1c0f0aa0 },
- { _MMIO(0x9888), 0x180f4000 },
- { _MMIO(0x9888), 0x1a0f02aa },
- { _MMIO(0x9888), 0x1c2c5400 },
- { _MMIO(0x9888), 0x1e2c0001 },
- { _MMIO(0x9888), 0x1a2c5550 },
- { _MMIO(0x9888), 0x1993aa00 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900421 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900001 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900420 },
- { _MMIO(0x9888), 0x45900021 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900000 },
-};
-
-static int
-get_l3_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_1;
- lens[n] = ARRAY_SIZE(mux_config_l3_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000efff },
- { _MMIO(0x2778), 0x00006000 },
- { _MMIO(0x277c), 0x0000f3ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x9888), 0x102d7800 },
- { _MMIO(0x9888), 0x122d79e0 },
- { _MMIO(0x9888), 0x0c2f0004 },
- { _MMIO(0x9888), 0x100e3800 },
- { _MMIO(0x9888), 0x180f0005 },
- { _MMIO(0x9888), 0x002d0940 },
- { _MMIO(0x9888), 0x022d802f },
- { _MMIO(0x9888), 0x042d4013 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x0e2e0050 },
- { _MMIO(0x9888), 0x022f0010 },
- { _MMIO(0x9888), 0x002f0000 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x040e0480 },
- { _MMIO(0x9888), 0x000e0000 },
- { _MMIO(0x9888), 0x060f0027 },
- { _MMIO(0x9888), 0x100f0000 },
- { _MMIO(0x9888), 0x1a0f0040 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x439014a0 },
- { _MMIO(0x9888), 0x459000a4 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900001 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_rasterizer_and_pixel_backend;
- lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_sampler[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x70800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x0000c000 },
- { _MMIO(0x2774), 0x0000e7ff },
- { _MMIO(0x2778), 0x00003000 },
- { _MMIO(0x277c), 0x0000f9ff },
- { _MMIO(0x2780), 0x00000c00 },
- { _MMIO(0x2784), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_sampler[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_sampler[] = {
- { _MMIO(0x9888), 0x121300a0 },
- { _MMIO(0x9888), 0x141600ab },
- { _MMIO(0x9888), 0x123300a0 },
- { _MMIO(0x9888), 0x143600ab },
- { _MMIO(0x9888), 0x125300a0 },
- { _MMIO(0x9888), 0x145600ab },
- { _MMIO(0x9888), 0x0c2d4000 },
- { _MMIO(0x9888), 0x0e2d5000 },
- { _MMIO(0x9888), 0x002d4000 },
- { _MMIO(0x9888), 0x022d5000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x102e01a0 },
- { _MMIO(0x9888), 0x0c2e5000 },
- { _MMIO(0x9888), 0x0e2e0065 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x044c8000 },
- { _MMIO(0x9888), 0x064cc000 },
- { _MMIO(0x9888), 0x084c4000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x024ea000 },
- { _MMIO(0x9888), 0x044e2000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x1c0f0800 },
- { _MMIO(0x9888), 0x180f4000 },
- { _MMIO(0x9888), 0x1a0f023f },
- { _MMIO(0x9888), 0x1e2c0003 },
- { _MMIO(0x9888), 0x1a2cc030 },
- { _MMIO(0x9888), 0x04132180 },
- { _MMIO(0x9888), 0x02130000 },
- { _MMIO(0x9888), 0x0c148000 },
- { _MMIO(0x9888), 0x0e142000 },
- { _MMIO(0x9888), 0x04148000 },
- { _MMIO(0x9888), 0x1e150140 },
- { _MMIO(0x9888), 0x1c150040 },
- { _MMIO(0x9888), 0x0c163000 },
- { _MMIO(0x9888), 0x0e160068 },
- { _MMIO(0x9888), 0x10160000 },
- { _MMIO(0x9888), 0x18160000 },
- { _MMIO(0x9888), 0x0a164000 },
- { _MMIO(0x9888), 0x04330043 },
- { _MMIO(0x9888), 0x02330000 },
- { _MMIO(0x9888), 0x0234a000 },
- { _MMIO(0x9888), 0x04342000 },
- { _MMIO(0x9888), 0x1c350015 },
- { _MMIO(0x9888), 0x02363460 },
- { _MMIO(0x9888), 0x10360000 },
- { _MMIO(0x9888), 0x04360000 },
- { _MMIO(0x9888), 0x06360000 },
- { _MMIO(0x9888), 0x08364000 },
- { _MMIO(0x9888), 0x06530043 },
- { _MMIO(0x9888), 0x02530000 },
- { _MMIO(0x9888), 0x0e548000 },
- { _MMIO(0x9888), 0x00548000 },
- { _MMIO(0x9888), 0x06542000 },
- { _MMIO(0x9888), 0x1e550400 },
- { _MMIO(0x9888), 0x1a552000 },
- { _MMIO(0x9888), 0x1c550100 },
- { _MMIO(0x9888), 0x0e563000 },
- { _MMIO(0x9888), 0x00563400 },
- { _MMIO(0x9888), 0x10560000 },
- { _MMIO(0x9888), 0x18560000 },
- { _MMIO(0x9888), 0x02560000 },
- { _MMIO(0x9888), 0x0c564000 },
- { _MMIO(0x9888), 0x1993a800 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b9014a0 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900001 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900820 },
- { _MMIO(0x9888), 0x45901022 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900000 },
-};
-
-static int
-get_sampler_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_sampler;
- lens[n] = ARRAY_SIZE(mux_config_sampler);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x00007fff },
- { _MMIO(0x2778), 0x00000000 },
- { _MMIO(0x277c), 0x00009fff },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000efff },
- { _MMIO(0x2788), 0x00000000 },
- { _MMIO(0x278c), 0x0000f3ff },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000fdff },
- { _MMIO(0x2798), 0x00000000 },
- { _MMIO(0x279c), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_1[] = {
- { _MMIO(0x9888), 0x141a0000 },
- { _MMIO(0x9888), 0x143a0000 },
- { _MMIO(0x9888), 0x145a0000 },
- { _MMIO(0x9888), 0x0c2d4000 },
- { _MMIO(0x9888), 0x0e2d5000 },
- { _MMIO(0x9888), 0x002d4000 },
- { _MMIO(0x9888), 0x022d5000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x102e0150 },
- { _MMIO(0x9888), 0x0c2e5000 },
- { _MMIO(0x9888), 0x0e2e006a },
- { _MMIO(0x9888), 0x124c8000 },
- { _MMIO(0x9888), 0x144c8000 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x044c8000 },
- { _MMIO(0x9888), 0x064c4000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x0c4e8000 },
- { _MMIO(0x9888), 0x0e4ea000 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x024e2000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x1c0f0bc0 },
- { _MMIO(0x9888), 0x180f4000 },
- { _MMIO(0x9888), 0x1a0f0302 },
- { _MMIO(0x9888), 0x1e2c0003 },
- { _MMIO(0x9888), 0x1a2c00f0 },
- { _MMIO(0x9888), 0x021a3080 },
- { _MMIO(0x9888), 0x041a31e5 },
- { _MMIO(0x9888), 0x02148000 },
- { _MMIO(0x9888), 0x0414a000 },
- { _MMIO(0x9888), 0x1c150054 },
- { _MMIO(0x9888), 0x06168000 },
- { _MMIO(0x9888), 0x08168000 },
- { _MMIO(0x9888), 0x0a168000 },
- { _MMIO(0x9888), 0x0c3a3280 },
- { _MMIO(0x9888), 0x0e3a0063 },
- { _MMIO(0x9888), 0x063a0061 },
- { _MMIO(0x9888), 0x023a0000 },
- { _MMIO(0x9888), 0x0c348000 },
- { _MMIO(0x9888), 0x0e342000 },
- { _MMIO(0x9888), 0x06342000 },
- { _MMIO(0x9888), 0x1e350140 },
- { _MMIO(0x9888), 0x1c350100 },
- { _MMIO(0x9888), 0x18360028 },
- { _MMIO(0x9888), 0x0c368000 },
- { _MMIO(0x9888), 0x0e5a3080 },
- { _MMIO(0x9888), 0x005a3280 },
- { _MMIO(0x9888), 0x025a0063 },
- { _MMIO(0x9888), 0x0e548000 },
- { _MMIO(0x9888), 0x00548000 },
- { _MMIO(0x9888), 0x02542000 },
- { _MMIO(0x9888), 0x1e550400 },
- { _MMIO(0x9888), 0x1a552000 },
- { _MMIO(0x9888), 0x1c550001 },
- { _MMIO(0x9888), 0x18560080 },
- { _MMIO(0x9888), 0x02568000 },
- { _MMIO(0x9888), 0x04568000 },
- { _MMIO(0x9888), 0x1993a800 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900420 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x45901084 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900001 },
-};
-
-static int
-get_tdl_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_1;
- lens[n] = ARRAY_SIZE(mux_config_tdl_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_2[] = {
- { _MMIO(0x9888), 0x141a026b },
- { _MMIO(0x9888), 0x143a0173 },
- { _MMIO(0x9888), 0x145a026b },
- { _MMIO(0x9888), 0x002d4000 },
- { _MMIO(0x9888), 0x022d5000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x0c2e5000 },
- { _MMIO(0x9888), 0x0e2e0069 },
- { _MMIO(0x9888), 0x044c8000 },
- { _MMIO(0x9888), 0x064cc000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x024ea000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x180f6000 },
- { _MMIO(0x9888), 0x1a0f030a },
- { _MMIO(0x9888), 0x1a2c03c0 },
- { _MMIO(0x9888), 0x041a37e7 },
- { _MMIO(0x9888), 0x021a0000 },
- { _MMIO(0x9888), 0x0414a000 },
- { _MMIO(0x9888), 0x1c150050 },
- { _MMIO(0x9888), 0x08168000 },
- { _MMIO(0x9888), 0x0a168000 },
- { _MMIO(0x9888), 0x003a3380 },
- { _MMIO(0x9888), 0x063a006f },
- { _MMIO(0x9888), 0x023a0000 },
- { _MMIO(0x9888), 0x00348000 },
- { _MMIO(0x9888), 0x06342000 },
- { _MMIO(0x9888), 0x1a352000 },
- { _MMIO(0x9888), 0x1c350100 },
- { _MMIO(0x9888), 0x02368000 },
- { _MMIO(0x9888), 0x0c368000 },
- { _MMIO(0x9888), 0x025a37e7 },
- { _MMIO(0x9888), 0x0254a000 },
- { _MMIO(0x9888), 0x1c550005 },
- { _MMIO(0x9888), 0x04568000 },
- { _MMIO(0x9888), 0x06568000 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900020 },
- { _MMIO(0x9888), 0x45901080 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900001 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_tdl_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_2;
- lens[n] = ARRAY_SIZE(mux_config_tdl_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extra[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extra[] = {
- { _MMIO(0xe458), 0x00001000 },
- { _MMIO(0xe558), 0x00003002 },
- { _MMIO(0xe658), 0x00005004 },
- { _MMIO(0xe758), 0x00011010 },
- { _MMIO(0xe45c), 0x00050012 },
- { _MMIO(0xe55c), 0x00052051 },
- { _MMIO(0xe65c), 0x00000008 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extra[] = {
- { _MMIO(0x9888), 0x141a001f },
- { _MMIO(0x9888), 0x143a001f },
- { _MMIO(0x9888), 0x145a001f },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x0e2e0094 },
- { _MMIO(0x9888), 0x084cc000 },
- { _MMIO(0x9888), 0x044ea000 },
- { _MMIO(0x9888), 0x1a0f00e0 },
- { _MMIO(0x9888), 0x1a2c0c00 },
- { _MMIO(0x9888), 0x061a0063 },
- { _MMIO(0x9888), 0x021a0000 },
- { _MMIO(0x9888), 0x06142000 },
- { _MMIO(0x9888), 0x1c150100 },
- { _MMIO(0x9888), 0x0c168000 },
- { _MMIO(0x9888), 0x043a3180 },
- { _MMIO(0x9888), 0x023a0000 },
- { _MMIO(0x9888), 0x04348000 },
- { _MMIO(0x9888), 0x1c350040 },
- { _MMIO(0x9888), 0x0a368000 },
- { _MMIO(0x9888), 0x045a0063 },
- { _MMIO(0x9888), 0x025a0000 },
- { _MMIO(0x9888), 0x04542000 },
- { _MMIO(0x9888), 0x1c550010 },
- { _MMIO(0x9888), 0x08568000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900400 },
- { _MMIO(0x9888), 0x47900004 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_compute_extra_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extra;
- lens[n] = ARRAY_SIZE(mux_config_compute_extra);
- n++;
-
- return n;
-}
-
static const struct i915_oa_reg b_counter_config_test_oa[] = {
{ _MMIO(0x2740), 0x00000000 },
{ _MMIO(0x2744), 0x00800000 },
@@ -1668,6 +60,7 @@ static const struct i915_oa_reg flex_eu_config_test_oa[] = {
};
static const struct i915_oa_reg mux_config_test_oa[] = {
+ { _MMIO(0x9840), 0x00000080 },
{ _MMIO(0x9888), 0x19800000 },
{ _MMIO(0x9888), 0x07800063 },
{ _MMIO(0x9888), 0x11800000 },
@@ -1681,922 +74,35 @@ static const struct i915_oa_reg mux_config_test_oa[] = {
{ _MMIO(0x9888), 0x33900000 },
};
-static int
-get_test_oa_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_test_oa;
- lens[n] = ARRAY_SIZE(mux_config_test_oa);
- n++;
-
- return n;
-}
-
-int i915_oa_select_metric_set_glk(struct drm_i915_private *dev_priv)
-{
- dev_priv->perf.oa.n_mux_configs = 0;
- dev_priv->perf.oa.b_counter_regs = NULL;
- dev_priv->perf.oa.b_counter_regs_len = 0;
- dev_priv->perf.oa.flex_regs = NULL;
- dev_priv->perf.oa.flex_regs_len = 0;
-
- switch (dev_priv->perf.oa.metrics_set) {
- case METRIC_SET_ID_RENDER_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_render_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_basic);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_basic);
-
- return 0;
- case METRIC_SET_ID_RENDER_PIPE_PROFILE:
- dev_priv->perf.oa.n_mux_configs =
- get_render_pipe_profile_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_pipe_profile;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_pipe_profile);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_pipe_profile;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_pipe_profile);
-
- return 0;
- case METRIC_SET_ID_MEMORY_READS:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_reads_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_reads;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_reads);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_reads;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_reads);
-
- return 0;
- case METRIC_SET_ID_MEMORY_WRITES:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_writes_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_writes;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_writes);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_writes;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_writes);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTENDED:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extended_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extended;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extended);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extended;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extended);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_L3_CACHE:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_l3_cache_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_L3_CACHE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_l3_cache;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_l3_cache);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_l3_cache;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_l3_cache);
-
- return 0;
- case METRIC_SET_ID_HDC_AND_SF:
- dev_priv->perf.oa.n_mux_configs =
- get_hdc_and_sf_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_hdc_and_sf;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_hdc_and_sf);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_hdc_and_sf;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_hdc_and_sf);
-
- return 0;
- case METRIC_SET_ID_L3_1:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_1);
-
- return 0;
- case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND:
- dev_priv->perf.oa.n_mux_configs =
- get_rasterizer_and_pixel_backend_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend);
-
- return 0;
- case METRIC_SET_ID_SAMPLER:
- dev_priv->perf.oa.n_mux_configs =
- get_sampler_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_sampler;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_sampler);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_sampler;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_sampler);
-
- return 0;
- case METRIC_SET_ID_TDL_1:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_1);
-
- return 0;
- case METRIC_SET_ID_TDL_2:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_2);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTRA:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extra_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTRA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extra;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extra);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extra;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extra);
-
- return 0;
- case METRIC_SET_ID_TEST_OA:
- dev_priv->perf.oa.n_mux_configs =
- get_test_oa_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_test_oa;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_test_oa);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_test_oa;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_test_oa);
-
- return 0;
- default:
- return -ENODEV;
- }
-}
-
-static ssize_t
-show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC);
-}
-
-static struct device_attribute dev_attr_render_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_basic[] = {
- &dev_attr_render_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_basic = {
- .name = "d72df5c7-5b4a-4274-a43f-00b0fd51fc68",
- .attrs = attrs_render_basic,
-};
-
-static ssize_t
-show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC);
-}
-
-static struct device_attribute dev_attr_compute_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_basic[] = {
- &dev_attr_compute_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_basic = {
- .name = "814285f6-354d-41d2-ba49-e24e622714a0",
- .attrs = attrs_compute_basic,
-};
-
-static ssize_t
-show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE);
-}
-
-static struct device_attribute dev_attr_render_pipe_profile_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_pipe_profile_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_pipe_profile[] = {
- &dev_attr_render_pipe_profile_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_pipe_profile = {
- .name = "07d397a6-b3e6-49f6-9433-a4f293d55978",
- .attrs = attrs_render_pipe_profile,
-};
-
-static ssize_t
-show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS);
-}
-
-static struct device_attribute dev_attr_memory_reads_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_reads_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_reads[] = {
- &dev_attr_memory_reads_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_reads = {
- .name = "1a356946-5428-450b-a2f0-89f8783a302d",
- .attrs = attrs_memory_reads,
-};
-
-static ssize_t
-show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES);
-}
-
-static struct device_attribute dev_attr_memory_writes_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_writes_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_writes[] = {
- &dev_attr_memory_writes_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_writes = {
- .name = "5299be9d-7a61-4c99-9f81-f87e6c5aaca9",
- .attrs = attrs_memory_writes,
-};
-
-static ssize_t
-show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED);
-}
-
-static struct device_attribute dev_attr_compute_extended_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extended_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extended[] = {
- &dev_attr_compute_extended_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extended = {
- .name = "bc9bcff2-459a-4cbc-986d-a84b077153f3",
- .attrs = attrs_compute_extended,
-};
-
-static ssize_t
-show_compute_l3_cache_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_L3_CACHE);
-}
-
-static struct device_attribute dev_attr_compute_l3_cache_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_l3_cache_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_l3_cache[] = {
- &dev_attr_compute_l3_cache_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_l3_cache = {
- .name = "88ec931f-5b4a-453a-9db6-a61232b6143d",
- .attrs = attrs_compute_l3_cache,
-};
-
-static ssize_t
-show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF);
-}
-
-static struct device_attribute dev_attr_hdc_and_sf_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_hdc_and_sf_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_hdc_and_sf[] = {
- &dev_attr_hdc_and_sf_id.attr,
- NULL,
-};
-
-static struct attribute_group group_hdc_and_sf = {
- .name = "530d176d-2a18-4014-adf8-1500c6c60835",
- .attrs = attrs_hdc_and_sf,
-};
-
-static ssize_t
-show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1);
-}
-
-static struct device_attribute dev_attr_l3_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_1[] = {
- &dev_attr_l3_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_1 = {
- .name = "fdee5a5a-f23c-43d1-aa73-f6257c71671d",
- .attrs = attrs_l3_1,
-};
-
-static ssize_t
-show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND);
-}
-
-static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_rasterizer_and_pixel_backend_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_rasterizer_and_pixel_backend[] = {
- &dev_attr_rasterizer_and_pixel_backend_id.attr,
- NULL,
-};
-
-static struct attribute_group group_rasterizer_and_pixel_backend = {
- .name = "6617623e-ca73-4791-b2b7-ddedd0846a0c",
- .attrs = attrs_rasterizer_and_pixel_backend,
-};
-
-static ssize_t
-show_sampler_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER);
-}
-
-static struct device_attribute dev_attr_sampler_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_sampler_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_sampler[] = {
- &dev_attr_sampler_id.attr,
- NULL,
-};
-
-static struct attribute_group group_sampler = {
- .name = "f3b2ea63-e82e-4234-b418-44dd20dd34d0",
- .attrs = attrs_sampler,
-};
-
-static ssize_t
-show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1);
-}
-
-static struct device_attribute dev_attr_tdl_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_1[] = {
- &dev_attr_tdl_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_1 = {
- .name = "14411d35-cbf6-4f5e-b68b-190faf9a1a83",
- .attrs = attrs_tdl_1,
-};
-
-static ssize_t
-show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2);
-}
-
-static struct device_attribute dev_attr_tdl_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_2[] = {
- &dev_attr_tdl_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_2 = {
- .name = "ffa3f263-0478-4724-8c9f-c911c5ec0f1d",
- .attrs = attrs_tdl_2,
-};
-
-static ssize_t
-show_compute_extra_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTRA);
-}
-
-static struct device_attribute dev_attr_compute_extra_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extra_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extra[] = {
- &dev_attr_compute_extra_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extra = {
- .name = "15274c82-27d2-4819-876a-7cb1a2c59ba4",
- .attrs = attrs_compute_extra,
-};
-
static ssize_t
show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA);
+ return sprintf(buf, "1\n");
}
-static struct device_attribute dev_attr_test_oa_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_test_oa_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_test_oa[] = {
- &dev_attr_test_oa_id.attr,
- NULL,
-};
-
-static struct attribute_group group_test_oa = {
- .name = "dd3fd789-e783-4204-8cd0-b671bbccb0cf",
- .attrs = attrs_test_oa,
-};
-
-int
-i915_perf_register_sysfs_glk(struct drm_i915_private *dev_priv)
+void
+i915_perf_load_test_config_glk(struct drm_i915_private *dev_priv)
{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
- int ret = 0;
+ strncpy(dev_priv->perf.oa.test_config.uuid,
+ "dd3fd789-e783-4204-8cd0-b671bbccb0cf",
+ UUID_STRING_LEN);
+ dev_priv->perf.oa.test_config.id = 1;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (ret)
- goto error_render_basic;
- }
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (ret)
- goto error_compute_basic;
- }
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (ret)
- goto error_render_pipe_profile;
- }
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (ret)
- goto error_memory_reads;
- }
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (ret)
- goto error_memory_writes;
- }
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (ret)
- goto error_compute_extended;
- }
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (ret)
- goto error_compute_l3_cache;
- }
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (ret)
- goto error_hdc_and_sf;
- }
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (ret)
- goto error_l3_1;
- }
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (ret)
- goto error_rasterizer_and_pixel_backend;
- }
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (ret)
- goto error_sampler;
- }
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (ret)
- goto error_tdl_1;
- }
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (ret)
- goto error_tdl_2;
- }
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (ret)
- goto error_compute_extra;
- }
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa);
- if (ret)
- goto error_test_oa;
- }
+ dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
+ dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
- return 0;
+ dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
+ dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-error_test_oa:
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
-error_compute_extra:
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
-error_tdl_2:
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
-error_tdl_1:
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
-error_sampler:
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
-error_rasterizer_and_pixel_backend:
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
-error_l3_1:
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
-error_hdc_and_sf:
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
-error_compute_l3_cache:
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
-error_compute_extended:
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
-error_memory_writes:
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
-error_memory_reads:
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
-error_render_pipe_profile:
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
-error_compute_basic:
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
-error_render_basic:
- return ret;
-}
+ dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
+ dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-void
-i915_perf_unregister_sysfs_glk(struct drm_i915_private *dev_priv)
-{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
+ dev_priv->perf.oa.test_config.sysfs_metric.name = "dd3fd789-e783-4204-8cd0-b671bbccb0cf";
+ dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+
+ dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa);
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
+ dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
}
diff --git a/drivers/gpu/drm/i915/i915_oa_glk.h b/drivers/gpu/drm/i915/i915_oa_glk.h
index 5511bb1..63bd113 100644
--- a/drivers/gpu/drm/i915/i915_oa_glk.h
+++ b/drivers/gpu/drm/i915/i915_oa_glk.h
@@ -29,12 +29,6 @@
#ifndef __I915_OA_GLK_H__
#define __I915_OA_GLK_H__
-extern int i915_oa_n_builtin_metric_sets_glk;
-
-extern int i915_oa_select_metric_set_glk(struct drm_i915_private *dev_priv);
-
-extern int i915_perf_register_sysfs_glk(struct drm_i915_private *dev_priv);
-
-extern void i915_perf_unregister_sysfs_glk(struct drm_i915_private *dev_priv);
+extern void i915_perf_load_test_config_glk(struct drm_i915_private *dev_priv);
#endif
diff --git a/drivers/gpu/drm/i915/i915_oa_hsw.c b/drivers/gpu/drm/i915/i915_oa_hsw.c
index 10f169f..56b0377 100644
--- a/drivers/gpu/drm/i915/i915_oa_hsw.c
+++ b/drivers/gpu/drm/i915/i915_oa_hsw.c
@@ -31,17 +31,6 @@
#include "i915_drv.h"
#include "i915_oa_hsw.h"
-enum metric_set_id {
- METRIC_SET_ID_RENDER_BASIC = 1,
- METRIC_SET_ID_COMPUTE_BASIC,
- METRIC_SET_ID_COMPUTE_EXTENDED,
- METRIC_SET_ID_MEMORY_READS,
- METRIC_SET_ID_MEMORY_WRITES,
- METRIC_SET_ID_SAMPLER_BALANCE,
-};
-
-int i915_oa_n_builtin_metric_sets_hsw = 6;
-
static const struct i915_oa_reg b_counter_config_render_basic[] = {
{ _MMIO(0x2724), 0x00800000 },
{ _MMIO(0x2720), 0x00000000 },
@@ -53,6 +42,7 @@ static const struct i915_oa_reg flex_eu_config_render_basic[] = {
};
static const struct i915_oa_reg mux_config_render_basic[] = {
+ { _MMIO(0x9840), 0x00000080 },
{ _MMIO(0x253a4), 0x01600000 },
{ _MMIO(0x25440), 0x00100000 },
{ _MMIO(0x25128), 0x00000000 },
@@ -114,750 +104,35 @@ static const struct i915_oa_reg mux_config_render_basic[] = {
{ _MMIO(0x25428), 0x00042049 },
};
-static int
-get_render_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_basic;
- lens[n] = ARRAY_SIZE(mux_config_render_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2718), 0xaaaaaaaa },
- { _MMIO(0x271c), 0xaaaaaaaa },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2728), 0xaaaaaaaa },
- { _MMIO(0x272c), 0xaaaaaaaa },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00000000 },
- { _MMIO(0x2748), 0x00000000 },
- { _MMIO(0x274c), 0x00000000 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2754), 0x00000000 },
- { _MMIO(0x2758), 0x00000000 },
- { _MMIO(0x275c), 0x00000000 },
- { _MMIO(0x236c), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_basic[] = {
-};
-
-static const struct i915_oa_reg mux_config_compute_basic[] = {
- { _MMIO(0x253a4), 0x00000000 },
- { _MMIO(0x2681c), 0x01f00800 },
- { _MMIO(0x26820), 0x00001000 },
- { _MMIO(0x2781c), 0x01f00800 },
- { _MMIO(0x26520), 0x00000007 },
- { _MMIO(0x265a0), 0x00000007 },
- { _MMIO(0x25380), 0x00000010 },
- { _MMIO(0x2538c), 0x00300000 },
- { _MMIO(0x25384), 0xaa8aaaaa },
- { _MMIO(0x25404), 0xffffffff },
- { _MMIO(0x26800), 0x00004202 },
- { _MMIO(0x26808), 0x00605817 },
- { _MMIO(0x2680c), 0x10001005 },
- { _MMIO(0x26804), 0x00000000 },
- { _MMIO(0x27800), 0x00000102 },
- { _MMIO(0x27808), 0x0c0701e0 },
- { _MMIO(0x2780c), 0x000200a0 },
- { _MMIO(0x27804), 0x00000000 },
- { _MMIO(0x26484), 0x44000000 },
- { _MMIO(0x26704), 0x44000000 },
- { _MMIO(0x26500), 0x00000006 },
- { _MMIO(0x26510), 0x00000001 },
- { _MMIO(0x26504), 0x88000000 },
- { _MMIO(0x26580), 0x00000006 },
- { _MMIO(0x26590), 0x00000020 },
- { _MMIO(0x26584), 0x00000000 },
- { _MMIO(0x26104), 0x55822222 },
- { _MMIO(0x26184), 0xaa866666 },
- { _MMIO(0x25420), 0x08320c83 },
- { _MMIO(0x25424), 0x06820c83 },
- { _MMIO(0x2541c), 0x00000000 },
- { _MMIO(0x25428), 0x00000c03 },
-};
-
-static int
-get_compute_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_basic;
- lens[n] = ARRAY_SIZE(mux_config_compute_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extended[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2770), 0x0007fe2a },
- { _MMIO(0x2774), 0x0000ff00 },
- { _MMIO(0x2778), 0x0007fe6a },
- { _MMIO(0x277c), 0x0000ff00 },
- { _MMIO(0x2780), 0x0007fe92 },
- { _MMIO(0x2784), 0x0000ff00 },
- { _MMIO(0x2788), 0x0007fea2 },
- { _MMIO(0x278c), 0x0000ff00 },
- { _MMIO(0x2790), 0x0007fe32 },
- { _MMIO(0x2794), 0x0000ff00 },
- { _MMIO(0x2798), 0x0007fe9a },
- { _MMIO(0x279c), 0x0000ff00 },
- { _MMIO(0x27a0), 0x0007ff23 },
- { _MMIO(0x27a4), 0x0000ff00 },
- { _MMIO(0x27a8), 0x0007fff3 },
- { _MMIO(0x27ac), 0x0000fffe },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extended[] = {
-};
-
-static const struct i915_oa_reg mux_config_compute_extended[] = {
- { _MMIO(0x2681c), 0x3eb00800 },
- { _MMIO(0x26820), 0x00900000 },
- { _MMIO(0x25384), 0x02aaaaaa },
- { _MMIO(0x25404), 0x03ffffff },
- { _MMIO(0x26800), 0x00142284 },
- { _MMIO(0x26808), 0x0e629062 },
- { _MMIO(0x2680c), 0x3f6f55cb },
- { _MMIO(0x26810), 0x00000014 },
- { _MMIO(0x26804), 0x00000000 },
- { _MMIO(0x26104), 0x02aaaaaa },
- { _MMIO(0x26184), 0x02aaaaaa },
- { _MMIO(0x25420), 0x00000000 },
- { _MMIO(0x25424), 0x00000000 },
- { _MMIO(0x2541c), 0x00000000 },
- { _MMIO(0x25428), 0x00000000 },
-};
-
-static int
-get_compute_extended_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extended;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_reads[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x76543298 },
- { _MMIO(0x2748), 0x98989898 },
- { _MMIO(0x2744), 0x000000e4 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x98a98a98 },
- { _MMIO(0x2758), 0x88888888 },
- { _MMIO(0x2754), 0x000c5500 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fc00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fc00 },
- { _MMIO(0x2780), 0x0007f872 },
- { _MMIO(0x2784), 0x0000fc00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fc00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fc00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fc00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fc00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fc00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_reads[] = {
-};
-
-static const struct i915_oa_reg mux_config_memory_reads[] = {
- { _MMIO(0x253a4), 0x34300000 },
- { _MMIO(0x25440), 0x2d800000 },
- { _MMIO(0x25444), 0x00000008 },
- { _MMIO(0x25128), 0x0e600000 },
- { _MMIO(0x25380), 0x00000450 },
- { _MMIO(0x25390), 0x00052c43 },
- { _MMIO(0x25384), 0x00000000 },
- { _MMIO(0x25400), 0x00006144 },
- { _MMIO(0x25408), 0x0a418820 },
- { _MMIO(0x2540c), 0x000820e6 },
- { _MMIO(0x25404), 0xff500000 },
- { _MMIO(0x25100), 0x000005d6 },
- { _MMIO(0x2510c), 0x0ef00000 },
- { _MMIO(0x25104), 0x00000000 },
- { _MMIO(0x25420), 0x02108421 },
- { _MMIO(0x25424), 0x00008421 },
- { _MMIO(0x2541c), 0x00000000 },
- { _MMIO(0x25428), 0x00000000 },
-};
-
-static int
-get_memory_reads_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_reads;
- lens[n] = ARRAY_SIZE(mux_config_memory_reads);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_writes[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x76543298 },
- { _MMIO(0x2748), 0x98989898 },
- { _MMIO(0x2744), 0x000000e4 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0xbabababa },
- { _MMIO(0x2758), 0x88888888 },
- { _MMIO(0x2754), 0x000c5500 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fc00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fc00 },
- { _MMIO(0x2780), 0x0007f822 },
- { _MMIO(0x2784), 0x0000fc00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fc00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fc00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fc00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fc00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fc00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_writes[] = {
-};
-
-static const struct i915_oa_reg mux_config_memory_writes[] = {
- { _MMIO(0x253a4), 0x34300000 },
- { _MMIO(0x25440), 0x01500000 },
- { _MMIO(0x25444), 0x00000120 },
- { _MMIO(0x25128), 0x0c200000 },
- { _MMIO(0x25380), 0x00000450 },
- { _MMIO(0x25390), 0x00052c43 },
- { _MMIO(0x25384), 0x00000000 },
- { _MMIO(0x25400), 0x00007184 },
- { _MMIO(0x25408), 0x0a418820 },
- { _MMIO(0x2540c), 0x000820e6 },
- { _MMIO(0x25404), 0xff500000 },
- { _MMIO(0x25100), 0x000005d6 },
- { _MMIO(0x2510c), 0x1e700000 },
- { _MMIO(0x25104), 0x00000000 },
- { _MMIO(0x25420), 0x02108421 },
- { _MMIO(0x25424), 0x00008421 },
- { _MMIO(0x2541c), 0x00000000 },
- { _MMIO(0x25428), 0x00000000 },
-};
-
-static int
-get_memory_writes_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_writes;
- lens[n] = ARRAY_SIZE(mux_config_memory_writes);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_sampler_balance[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_sampler_balance[] = {
-};
-
-static const struct i915_oa_reg mux_config_sampler_balance[] = {
- { _MMIO(0x2eb9c), 0x01906400 },
- { _MMIO(0x2fb9c), 0x01906400 },
- { _MMIO(0x253a4), 0x00000000 },
- { _MMIO(0x26b9c), 0x01906400 },
- { _MMIO(0x27b9c), 0x01906400 },
- { _MMIO(0x27104), 0x00a00000 },
- { _MMIO(0x27184), 0x00a50000 },
- { _MMIO(0x2e804), 0x00500000 },
- { _MMIO(0x2e984), 0x00500000 },
- { _MMIO(0x2eb04), 0x00500000 },
- { _MMIO(0x2eb80), 0x00000084 },
- { _MMIO(0x2eb8c), 0x14200000 },
- { _MMIO(0x2eb84), 0x00000000 },
- { _MMIO(0x2f804), 0x00050000 },
- { _MMIO(0x2f984), 0x00050000 },
- { _MMIO(0x2fb04), 0x00050000 },
- { _MMIO(0x2fb80), 0x00000084 },
- { _MMIO(0x2fb8c), 0x00050800 },
- { _MMIO(0x2fb84), 0x00000000 },
- { _MMIO(0x25380), 0x00000010 },
- { _MMIO(0x2538c), 0x000000c0 },
- { _MMIO(0x25384), 0xaa550000 },
- { _MMIO(0x25404), 0xffffc000 },
- { _MMIO(0x26804), 0x50000000 },
- { _MMIO(0x26984), 0x50000000 },
- { _MMIO(0x26b04), 0x50000000 },
- { _MMIO(0x26b80), 0x00000084 },
- { _MMIO(0x26b90), 0x00050800 },
- { _MMIO(0x26b84), 0x00000000 },
- { _MMIO(0x27804), 0x05000000 },
- { _MMIO(0x27984), 0x05000000 },
- { _MMIO(0x27b04), 0x05000000 },
- { _MMIO(0x27b80), 0x00000084 },
- { _MMIO(0x27b90), 0x00000142 },
- { _MMIO(0x27b84), 0x00000000 },
- { _MMIO(0x26104), 0xa0000000 },
- { _MMIO(0x26184), 0xa5000000 },
- { _MMIO(0x25424), 0x00008620 },
- { _MMIO(0x2541c), 0x00000000 },
- { _MMIO(0x25428), 0x0004a54a },
-};
-
-static int
-get_sampler_balance_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_sampler_balance;
- lens[n] = ARRAY_SIZE(mux_config_sampler_balance);
- n++;
-
- return n;
-}
-
-int i915_oa_select_metric_set_hsw(struct drm_i915_private *dev_priv)
-{
- dev_priv->perf.oa.n_mux_configs = 0;
- dev_priv->perf.oa.b_counter_regs = NULL;
- dev_priv->perf.oa.b_counter_regs_len = 0;
-
- switch (dev_priv->perf.oa.metrics_set) {
- case METRIC_SET_ID_RENDER_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_render_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_basic);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_basic);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTENDED:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extended_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extended;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extended);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extended;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extended);
-
- return 0;
- case METRIC_SET_ID_MEMORY_READS:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_reads_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_reads;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_reads);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_reads;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_reads);
-
- return 0;
- case METRIC_SET_ID_MEMORY_WRITES:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_writes_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_writes;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_writes);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_writes;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_writes);
-
- return 0;
- case METRIC_SET_ID_SAMPLER_BALANCE:
- dev_priv->perf.oa.n_mux_configs =
- get_sampler_balance_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER_BALANCE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_sampler_balance;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_sampler_balance);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_sampler_balance;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_sampler_balance);
-
- return 0;
- default:
- return -ENODEV;
- }
-}
-
static ssize_t
show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC);
-}
-
-static struct device_attribute dev_attr_render_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_basic[] = {
- &dev_attr_render_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_basic = {
- .name = "403d8832-1a27-4aa6-a64e-f5389ce7b212",
- .attrs = attrs_render_basic,
-};
-
-static ssize_t
-show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC);
-}
-
-static struct device_attribute dev_attr_compute_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_basic[] = {
- &dev_attr_compute_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_basic = {
- .name = "39ad14bc-2380-45c4-91eb-fbcb3aa7ae7b",
- .attrs = attrs_compute_basic,
-};
-
-static ssize_t
-show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED);
+ return sprintf(buf, "1\n");
}
-static struct device_attribute dev_attr_compute_extended_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extended_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extended[] = {
- &dev_attr_compute_extended_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extended = {
- .name = "3865be28-6982-49fe-9494-e4d1b4795413",
- .attrs = attrs_compute_extended,
-};
-
-static ssize_t
-show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS);
-}
-
-static struct device_attribute dev_attr_memory_reads_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_reads_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_reads[] = {
- &dev_attr_memory_reads_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_reads = {
- .name = "bb5ed49b-2497-4095-94f6-26ba294db88a",
- .attrs = attrs_memory_reads,
-};
-
-static ssize_t
-show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES);
-}
-
-static struct device_attribute dev_attr_memory_writes_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_writes_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_writes[] = {
- &dev_attr_memory_writes_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_writes = {
- .name = "3358d639-9b5f-45ab-976d-9b08cbfc6240",
- .attrs = attrs_memory_writes,
-};
-
-static ssize_t
-show_sampler_balance_id(struct device *kdev, struct device_attribute *attr, char *buf)
+void
+i915_perf_load_test_config_hsw(struct drm_i915_private *dev_priv)
{
- return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER_BALANCE);
-}
-
-static struct device_attribute dev_attr_sampler_balance_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_sampler_balance_id,
- .store = NULL,
-};
+ strncpy(dev_priv->perf.oa.test_config.uuid,
+ "403d8832-1a27-4aa6-a64e-f5389ce7b212",
+ UUID_STRING_LEN);
+ dev_priv->perf.oa.test_config.id = 1;
-static struct attribute *attrs_sampler_balance[] = {
- &dev_attr_sampler_balance_id.attr,
- NULL,
-};
+ dev_priv->perf.oa.test_config.mux_regs = mux_config_render_basic;
+ dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_render_basic);
-static struct attribute_group group_sampler_balance = {
- .name = "bc274488-b4b6-40c7-90da-b77d7ad16189",
- .attrs = attrs_sampler_balance,
-};
+ dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_render_basic;
+ dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_render_basic);
-int
-i915_perf_register_sysfs_hsw(struct drm_i915_private *dev_priv)
-{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
- int ret = 0;
+ dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_render_basic;
+ dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_render_basic);
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (ret)
- goto error_render_basic;
- }
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (ret)
- goto error_compute_basic;
- }
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (ret)
- goto error_compute_extended;
- }
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (ret)
- goto error_memory_reads;
- }
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (ret)
- goto error_memory_writes;
- }
- if (get_sampler_balance_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler_balance);
- if (ret)
- goto error_sampler_balance;
- }
+ dev_priv->perf.oa.test_config.sysfs_metric.name = "403d8832-1a27-4aa6-a64e-f5389ce7b212";
+ dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
- return 0;
-
-error_sampler_balance:
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
-error_memory_writes:
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
-error_memory_reads:
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
-error_compute_extended:
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
-error_compute_basic:
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
-error_render_basic:
- return ret;
-}
-
-void
-i915_perf_unregister_sysfs_hsw(struct drm_i915_private *dev_priv)
-{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
+ dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (get_sampler_balance_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_balance);
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
+ dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_render_basic_id;
}
diff --git a/drivers/gpu/drm/i915/i915_oa_hsw.h b/drivers/gpu/drm/i915/i915_oa_hsw.h
index 6fe7e06..74d0343 100644
--- a/drivers/gpu/drm/i915/i915_oa_hsw.h
+++ b/drivers/gpu/drm/i915/i915_oa_hsw.h
@@ -29,12 +29,6 @@
#ifndef __I915_OA_HSW_H__
#define __I915_OA_HSW_H__
-extern int i915_oa_n_builtin_metric_sets_hsw;
-
-extern int i915_oa_select_metric_set_hsw(struct drm_i915_private *dev_priv);
-
-extern int i915_perf_register_sysfs_hsw(struct drm_i915_private *dev_priv);
-
-extern void i915_perf_unregister_sysfs_hsw(struct drm_i915_private *dev_priv);
+extern void i915_perf_load_test_config_hsw(struct drm_i915_private *dev_priv);
#endif
diff --git a/drivers/gpu/drm/i915/i915_oa_kblgt2.c b/drivers/gpu/drm/i915/i915_oa_kblgt2.c
index 87dbd0a..b6e7cc7 100644
--- a/drivers/gpu/drm/i915/i915_oa_kblgt2.c
+++ b/drivers/gpu/drm/i915/i915_oa_kblgt2.c
@@ -31,1828 +31,6 @@
#include "i915_drv.h"
#include "i915_oa_kblgt2.h"
-enum metric_set_id {
- METRIC_SET_ID_RENDER_BASIC = 1,
- METRIC_SET_ID_COMPUTE_BASIC,
- METRIC_SET_ID_RENDER_PIPE_PROFILE,
- METRIC_SET_ID_MEMORY_READS,
- METRIC_SET_ID_MEMORY_WRITES,
- METRIC_SET_ID_COMPUTE_EXTENDED,
- METRIC_SET_ID_COMPUTE_L3_CACHE,
- METRIC_SET_ID_HDC_AND_SF,
- METRIC_SET_ID_L3_1,
- METRIC_SET_ID_L3_2,
- METRIC_SET_ID_L3_3,
- METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND,
- METRIC_SET_ID_SAMPLER,
- METRIC_SET_ID_TDL_1,
- METRIC_SET_ID_TDL_2,
- METRIC_SET_ID_COMPUTE_EXTRA,
- METRIC_SET_ID_VME_PIPE,
- METRIC_SET_ID_TEST_OA,
-};
-
-int i915_oa_n_builtin_metric_sets_kblgt2 = 18;
-
-static const struct i915_oa_reg b_counter_config_render_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_render_basic[] = {
- { _MMIO(0x9888), 0x166c01e0 },
- { _MMIO(0x9888), 0x12170280 },
- { _MMIO(0x9888), 0x12370280 },
- { _MMIO(0x9888), 0x11930317 },
- { _MMIO(0x9888), 0x159303df },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x1a4e0080 },
- { _MMIO(0x9888), 0x0a6c0053 },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x0a1b4000 },
- { _MMIO(0x9888), 0x1c1c0001 },
- { _MMIO(0x9888), 0x002f1000 },
- { _MMIO(0x9888), 0x042f1000 },
- { _MMIO(0x9888), 0x004c4000 },
- { _MMIO(0x9888), 0x0a4c8400 },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0d2000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f6600 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x162c2200 },
- { _MMIO(0x9888), 0x062d8000 },
- { _MMIO(0x9888), 0x082d8000 },
- { _MMIO(0x9888), 0x00133000 },
- { _MMIO(0x9888), 0x08133000 },
- { _MMIO(0x9888), 0x00170020 },
- { _MMIO(0x9888), 0x08170021 },
- { _MMIO(0x9888), 0x10170000 },
- { _MMIO(0x9888), 0x0633c000 },
- { _MMIO(0x9888), 0x0833c000 },
- { _MMIO(0x9888), 0x06370800 },
- { _MMIO(0x9888), 0x08370840 },
- { _MMIO(0x9888), 0x10370000 },
- { _MMIO(0x9888), 0x0d933031 },
- { _MMIO(0x9888), 0x0f933e3f },
- { _MMIO(0x9888), 0x01933d00 },
- { _MMIO(0x9888), 0x0393073c },
- { _MMIO(0x9888), 0x0593000e },
- { _MMIO(0x9888), 0x1d930000 },
- { _MMIO(0x9888), 0x19930000 },
- { _MMIO(0x9888), 0x1b930000 },
- { _MMIO(0x9888), 0x1d900157 },
- { _MMIO(0x9888), 0x1f900158 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x2b908000 },
- { _MMIO(0x9888), 0x2d908000 },
- { _MMIO(0x9888), 0x2f908000 },
- { _MMIO(0x9888), 0x31908000 },
- { _MMIO(0x9888), 0x15908000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1190001f },
- { _MMIO(0x9888), 0x51904400 },
- { _MMIO(0x9888), 0x41900020 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900c21 },
- { _MMIO(0x9888), 0x47900061 },
- { _MMIO(0x9888), 0x57904440 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x59900004 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x53904444 },
-};
-
-static int
-get_render_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_basic;
- lens[n] = ARRAY_SIZE(mux_config_render_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_basic[] = {
- { _MMIO(0x9888), 0x104f00e0 },
- { _MMIO(0x9888), 0x124f1c00 },
- { _MMIO(0x9888), 0x106c00e0 },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x1a4e0820 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x064f0900 },
- { _MMIO(0x9888), 0x084f0032 },
- { _MMIO(0x9888), 0x0a4f1891 },
- { _MMIO(0x9888), 0x0c4f0e00 },
- { _MMIO(0x9888), 0x0e4f003c },
- { _MMIO(0x9888), 0x004f0d80 },
- { _MMIO(0x9888), 0x024f003b },
- { _MMIO(0x9888), 0x006c0002 },
- { _MMIO(0x9888), 0x086c0100 },
- { _MMIO(0x9888), 0x0c6c000c },
- { _MMIO(0x9888), 0x0e6c0b00 },
- { _MMIO(0x9888), 0x186c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x001b4000 },
- { _MMIO(0x9888), 0x081b8000 },
- { _MMIO(0x9888), 0x0c1b4000 },
- { _MMIO(0x9888), 0x0e1b8000 },
- { _MMIO(0x9888), 0x101c8000 },
- { _MMIO(0x9888), 0x1a1c8000 },
- { _MMIO(0x9888), 0x1c1c0024 },
- { _MMIO(0x9888), 0x065b8000 },
- { _MMIO(0x9888), 0x085b4000 },
- { _MMIO(0x9888), 0x0a5bc000 },
- { _MMIO(0x9888), 0x0c5b8000 },
- { _MMIO(0x9888), 0x0e5b4000 },
- { _MMIO(0x9888), 0x005b8000 },
- { _MMIO(0x9888), 0x025b4000 },
- { _MMIO(0x9888), 0x1a5c6000 },
- { _MMIO(0x9888), 0x1c5c001b },
- { _MMIO(0x9888), 0x125c8000 },
- { _MMIO(0x9888), 0x145c8000 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4c2000 },
- { _MMIO(0x9888), 0x0c4c0208 },
- { _MMIO(0x9888), 0x000da000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x020d2000 },
- { _MMIO(0x9888), 0x0c0f5400 },
- { _MMIO(0x9888), 0x0e0f5500 },
- { _MMIO(0x9888), 0x100f0155 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2cc000 },
- { _MMIO(0x9888), 0x162cfb00 },
- { _MMIO(0x9888), 0x182c00be },
- { _MMIO(0x9888), 0x022cc000 },
- { _MMIO(0x9888), 0x042cc000 },
- { _MMIO(0x9888), 0x19900157 },
- { _MMIO(0x9888), 0x1b900158 },
- { _MMIO(0x9888), 0x1d900105 },
- { _MMIO(0x9888), 0x1f900103 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x11900fff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900821 },
- { _MMIO(0x9888), 0x47900802 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900802 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900002 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900422 },
- { _MMIO(0x9888), 0x53904444 },
-};
-
-static int
-get_compute_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_basic;
- lens[n] = ARRAY_SIZE(mux_config_compute_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007ffea },
- { _MMIO(0x2774), 0x00007ffc },
- { _MMIO(0x2778), 0x0007affa },
- { _MMIO(0x277c), 0x0000f5fd },
- { _MMIO(0x2780), 0x00079ffa },
- { _MMIO(0x2784), 0x0000f3fb },
- { _MMIO(0x2788), 0x0007bf7a },
- { _MMIO(0x278c), 0x0000f7e7 },
- { _MMIO(0x2790), 0x0007fefa },
- { _MMIO(0x2794), 0x0000f7cf },
- { _MMIO(0x2798), 0x00077ffa },
- { _MMIO(0x279c), 0x0000efdf },
- { _MMIO(0x27a0), 0x0006fffa },
- { _MMIO(0x27a4), 0x0000cfbf },
- { _MMIO(0x27a8), 0x0003fffa },
- { _MMIO(0x27ac), 0x00005f7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_render_pipe_profile[] = {
- { _MMIO(0x9888), 0x0c0e001f },
- { _MMIO(0x9888), 0x0a0f0000 },
- { _MMIO(0x9888), 0x10116800 },
- { _MMIO(0x9888), 0x178a03e0 },
- { _MMIO(0x9888), 0x11824c00 },
- { _MMIO(0x9888), 0x11830020 },
- { _MMIO(0x9888), 0x13840020 },
- { _MMIO(0x9888), 0x11850019 },
- { _MMIO(0x9888), 0x11860007 },
- { _MMIO(0x9888), 0x01870c40 },
- { _MMIO(0x9888), 0x17880000 },
- { _MMIO(0x9888), 0x022f4000 },
- { _MMIO(0x9888), 0x0a4c0040 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x040d4000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x020e5400 },
- { _MMIO(0x9888), 0x000e0000 },
- { _MMIO(0x9888), 0x080f0040 },
- { _MMIO(0x9888), 0x000f0000 },
- { _MMIO(0x9888), 0x100f0000 },
- { _MMIO(0x9888), 0x0e0f0040 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x06104000 },
- { _MMIO(0x9888), 0x06110012 },
- { _MMIO(0x9888), 0x06131000 },
- { _MMIO(0x9888), 0x01898000 },
- { _MMIO(0x9888), 0x0d890100 },
- { _MMIO(0x9888), 0x03898000 },
- { _MMIO(0x9888), 0x09808000 },
- { _MMIO(0x9888), 0x0b808000 },
- { _MMIO(0x9888), 0x0380c000 },
- { _MMIO(0x9888), 0x0f8a0075 },
- { _MMIO(0x9888), 0x1d8a0000 },
- { _MMIO(0x9888), 0x118a8000 },
- { _MMIO(0x9888), 0x1b8a4000 },
- { _MMIO(0x9888), 0x138a8000 },
- { _MMIO(0x9888), 0x1d81a000 },
- { _MMIO(0x9888), 0x15818000 },
- { _MMIO(0x9888), 0x17818000 },
- { _MMIO(0x9888), 0x0b820030 },
- { _MMIO(0x9888), 0x07828000 },
- { _MMIO(0x9888), 0x0d824000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x05824000 },
- { _MMIO(0x9888), 0x0d830003 },
- { _MMIO(0x9888), 0x0583000c },
- { _MMIO(0x9888), 0x09830000 },
- { _MMIO(0x9888), 0x03838000 },
- { _MMIO(0x9888), 0x07838000 },
- { _MMIO(0x9888), 0x0b840980 },
- { _MMIO(0x9888), 0x03844d80 },
- { _MMIO(0x9888), 0x11840000 },
- { _MMIO(0x9888), 0x09848000 },
- { _MMIO(0x9888), 0x09850080 },
- { _MMIO(0x9888), 0x03850003 },
- { _MMIO(0x9888), 0x01850000 },
- { _MMIO(0x9888), 0x07860000 },
- { _MMIO(0x9888), 0x0f860400 },
- { _MMIO(0x9888), 0x09870032 },
- { _MMIO(0x9888), 0x01888052 },
- { _MMIO(0x9888), 0x11880000 },
- { _MMIO(0x9888), 0x09884000 },
- { _MMIO(0x9888), 0x1b931001 },
- { _MMIO(0x9888), 0x1d930001 },
- { _MMIO(0x9888), 0x19934000 },
- { _MMIO(0x9888), 0x1b958000 },
- { _MMIO(0x9888), 0x1d950094 },
- { _MMIO(0x9888), 0x19958000 },
- { _MMIO(0x9888), 0x09e58000 },
- { _MMIO(0x9888), 0x0be58000 },
- { _MMIO(0x9888), 0x03e5c000 },
- { _MMIO(0x9888), 0x0592c000 },
- { _MMIO(0x9888), 0x0b928000 },
- { _MMIO(0x9888), 0x0d924000 },
- { _MMIO(0x9888), 0x0f924000 },
- { _MMIO(0x9888), 0x11928000 },
- { _MMIO(0x9888), 0x1392c000 },
- { _MMIO(0x9888), 0x09924000 },
- { _MMIO(0x9888), 0x01985000 },
- { _MMIO(0x9888), 0x07988000 },
- { _MMIO(0x9888), 0x09981000 },
- { _MMIO(0x9888), 0x0b982000 },
- { _MMIO(0x9888), 0x0d982000 },
- { _MMIO(0x9888), 0x0f989000 },
- { _MMIO(0x9888), 0x05982000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x23904000 },
- { _MMIO(0x9888), 0x25908000 },
- { _MMIO(0x9888), 0x27904000 },
- { _MMIO(0x9888), 0x29908000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1190c080 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900440 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900400 },
- { _MMIO(0x9888), 0x47900c21 },
- { _MMIO(0x9888), 0x57900400 },
- { _MMIO(0x9888), 0x49900042 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900024 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900841 },
- { _MMIO(0x9888), 0x53900400 },
-};
-
-static int
-get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_pipe_profile;
- lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_reads[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f872 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_reads[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_reads[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f900064 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x1b930055 },
- { _MMIO(0x9888), 0x03e58000 },
- { _MMIO(0x9888), 0x05e5c000 },
- { _MMIO(0x9888), 0x07e54000 },
- { _MMIO(0x9888), 0x13900150 },
- { _MMIO(0x9888), 0x21900151 },
- { _MMIO(0x9888), 0x23900152 },
- { _MMIO(0x9888), 0x25900153 },
- { _MMIO(0x9888), 0x27900154 },
- { _MMIO(0x9888), 0x29900155 },
- { _MMIO(0x9888), 0x2b900156 },
- { _MMIO(0x9888), 0x2d900157 },
- { _MMIO(0x9888), 0x2f90015f },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c60 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900c00 },
- { _MMIO(0x9888), 0x47900c63 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900c63 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_memory_reads_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_reads;
- lens[n] = ARRAY_SIZE(mux_config_memory_reads);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_writes[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f822 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_writes[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_writes[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f901000 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x1b930055 },
- { _MMIO(0x9888), 0x03e58000 },
- { _MMIO(0x9888), 0x05e5c000 },
- { _MMIO(0x9888), 0x07e54000 },
- { _MMIO(0x9888), 0x13900160 },
- { _MMIO(0x9888), 0x21900161 },
- { _MMIO(0x9888), 0x23900162 },
- { _MMIO(0x9888), 0x25900163 },
- { _MMIO(0x9888), 0x27900164 },
- { _MMIO(0x9888), 0x29900165 },
- { _MMIO(0x9888), 0x2b900166 },
- { _MMIO(0x9888), 0x2d900167 },
- { _MMIO(0x9888), 0x2f900150 },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c60 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900c00 },
- { _MMIO(0x9888), 0x47900c63 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900c63 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_memory_writes_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_writes;
- lens[n] = ARRAY_SIZE(mux_config_memory_writes);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extended[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fc2a },
- { _MMIO(0x2774), 0x0000bf00 },
- { _MMIO(0x2778), 0x0007fc6a },
- { _MMIO(0x277c), 0x0000bf00 },
- { _MMIO(0x2780), 0x0007fc92 },
- { _MMIO(0x2784), 0x0000bf00 },
- { _MMIO(0x2788), 0x0007fca2 },
- { _MMIO(0x278c), 0x0000bf00 },
- { _MMIO(0x2790), 0x0007fc32 },
- { _MMIO(0x2794), 0x0000bf00 },
- { _MMIO(0x2798), 0x0007fc9a },
- { _MMIO(0x279c), 0x0000bf00 },
- { _MMIO(0x27a0), 0x0007fe6a },
- { _MMIO(0x27a4), 0x0000bf00 },
- { _MMIO(0x27a8), 0x0007fe7a },
- { _MMIO(0x27ac), 0x0000bf00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extended[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended[] = {
- { _MMIO(0x9888), 0x106c00e0 },
- { _MMIO(0x9888), 0x141c8160 },
- { _MMIO(0x9888), 0x161c8015 },
- { _MMIO(0x9888), 0x181c0120 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x184e8000 },
- { _MMIO(0x9888), 0x1a4eaaa0 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x024e8000 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0e6c0b01 },
- { _MMIO(0x9888), 0x006c0200 },
- { _MMIO(0x9888), 0x026c000c },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x001b8000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x001c0041 },
- { _MMIO(0x9888), 0x061c4200 },
- { _MMIO(0x9888), 0x081c4443 },
- { _MMIO(0x9888), 0x0a1c4645 },
- { _MMIO(0x9888), 0x0c1c7647 },
- { _MMIO(0x9888), 0x041c7357 },
- { _MMIO(0x9888), 0x1c1c0030 },
- { _MMIO(0x9888), 0x101c0000 },
- { _MMIO(0x9888), 0x1a1c0000 },
- { _MMIO(0x9888), 0x121c8000 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4caa2a },
- { _MMIO(0x9888), 0x0c4c02aa },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x000da000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x0c0f5400 },
- { _MMIO(0x9888), 0x0e0f5515 },
- { _MMIO(0x9888), 0x100f0155 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162caa00 },
- { _MMIO(0x9888), 0x182c00aa },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x11907fff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900040 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900802 },
- { _MMIO(0x9888), 0x47900842 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900842 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900800 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_compute_extended_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extended;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_l3_cache[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fffa },
- { _MMIO(0x2774), 0x0000fefe },
- { _MMIO(0x2778), 0x0007fffa },
- { _MMIO(0x277c), 0x0000fefd },
- { _MMIO(0x2790), 0x0007fffa },
- { _MMIO(0x2794), 0x0000fbef },
- { _MMIO(0x2798), 0x0007fffa },
- { _MMIO(0x279c), 0x0000fbdf },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_l3_cache[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00101100 },
- { _MMIO(0xe45c), 0x00201200 },
- { _MMIO(0xe55c), 0x00301300 },
- { _MMIO(0xe65c), 0x00401400 },
-};
-
-static const struct i915_oa_reg mux_config_compute_l3_cache[] = {
- { _MMIO(0x9888), 0x166c0760 },
- { _MMIO(0x9888), 0x1593001e },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x184e8000 },
- { _MMIO(0x9888), 0x1a4e8020 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x006c0051 },
- { _MMIO(0x9888), 0x066c5000 },
- { _MMIO(0x9888), 0x086c5c5d },
- { _MMIO(0x9888), 0x0e6c5e5f },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x186c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x001b4000 },
- { _MMIO(0x9888), 0x061b8000 },
- { _MMIO(0x9888), 0x081bc000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x101c8000 },
- { _MMIO(0x9888), 0x1a1ce000 },
- { _MMIO(0x9888), 0x1c1c0030 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4c2a00 },
- { _MMIO(0x9888), 0x0c4c0280 },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f1500 },
- { _MMIO(0x9888), 0x100f0140 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162c0a00 },
- { _MMIO(0x9888), 0x182c00a0 },
- { _MMIO(0x9888), 0x03933300 },
- { _MMIO(0x9888), 0x05930032 },
- { _MMIO(0x9888), 0x11930000 },
- { _MMIO(0x9888), 0x1b930000 },
- { _MMIO(0x9888), 0x1d900157 },
- { _MMIO(0x9888), 0x1f900158 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1190030f },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900000 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900021 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x53904444 },
- { _MMIO(0x9888), 0x43900000 },
-};
-
-static int
-get_compute_l3_cache_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_l3_cache;
- lens[n] = ARRAY_SIZE(mux_config_compute_l3_cache);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x10800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fdff },
-};
-
-static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_hdc_and_sf[] = {
- { _MMIO(0x9888), 0x104f0232 },
- { _MMIO(0x9888), 0x124f4640 },
- { _MMIO(0x9888), 0x106c0232 },
- { _MMIO(0x9888), 0x11834400 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0c4e8000 },
- { _MMIO(0x9888), 0x004f1880 },
- { _MMIO(0x9888), 0x024f08bb },
- { _MMIO(0x9888), 0x044f001b },
- { _MMIO(0x9888), 0x046c0100 },
- { _MMIO(0x9888), 0x066c000b },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x041b8000 },
- { _MMIO(0x9888), 0x061b4000 },
- { _MMIO(0x9888), 0x1a1c1800 },
- { _MMIO(0x9888), 0x005b8000 },
- { _MMIO(0x9888), 0x025bc000 },
- { _MMIO(0x9888), 0x045b4000 },
- { _MMIO(0x9888), 0x125c8000 },
- { _MMIO(0x9888), 0x145c8000 },
- { _MMIO(0x9888), 0x165c8000 },
- { _MMIO(0x9888), 0x185c8000 },
- { _MMIO(0x9888), 0x0a4c00a0 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x022cc000 },
- { _MMIO(0x9888), 0x042cc000 },
- { _MMIO(0x9888), 0x062cc000 },
- { _MMIO(0x9888), 0x082cc000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x0f8305c0 },
- { _MMIO(0x9888), 0x09830000 },
- { _MMIO(0x9888), 0x07830000 },
- { _MMIO(0x9888), 0x1d950080 },
- { _MMIO(0x9888), 0x13928000 },
- { _MMIO(0x9888), 0x0f988000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900040 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_hdc_and_sf;
- lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_1[] = {
- { _MMIO(0x9888), 0x126c7b40 },
- { _MMIO(0x9888), 0x166c0020 },
- { _MMIO(0x9888), 0x0a603444 },
- { _MMIO(0x9888), 0x0a613400 },
- { _MMIO(0x9888), 0x1a4ea800 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x024e8000 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x064f4000 },
- { _MMIO(0x9888), 0x0c6c5327 },
- { _MMIO(0x9888), 0x0e6c5425 },
- { _MMIO(0x9888), 0x006c2a00 },
- { _MMIO(0x9888), 0x026c285b },
- { _MMIO(0x9888), 0x046c005c },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x1a6c0800 },
- { _MMIO(0x9888), 0x0c1bc000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x001b8000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x1c1c003c },
- { _MMIO(0x9888), 0x121c8000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c0800 },
- { _MMIO(0x9888), 0x065b4000 },
- { _MMIO(0x9888), 0x1a5c1000 },
- { _MMIO(0x9888), 0x10600000 },
- { _MMIO(0x9888), 0x04600000 },
- { _MMIO(0x9888), 0x0c610044 },
- { _MMIO(0x9888), 0x10610000 },
- { _MMIO(0x9888), 0x06610000 },
- { _MMIO(0x9888), 0x0c4c02a8 },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x0a4c002a },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f0154 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x182c00aa },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2cc000 },
- { _MMIO(0x9888), 0x1190ffc0 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900420 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900021 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900400 },
- { _MMIO(0x9888), 0x43900421 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
-};
-
-static int
-get_l3_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_1;
- lens[n] = ARRAY_SIZE(mux_config_l3_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00028002 },
- { _MMIO(0x277c), 0x000087ff },
- { _MMIO(0x2780), 0x00020002 },
- { _MMIO(0x2784), 0x00008fff },
- { _MMIO(0x2788), 0x00008002 },
- { _MMIO(0x278c), 0x0000a7ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_2[] = {
- { _MMIO(0x9888), 0x126c02e0 },
- { _MMIO(0x9888), 0x146c0001 },
- { _MMIO(0x9888), 0x0a623400 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x064f4000 },
- { _MMIO(0x9888), 0x026c3324 },
- { _MMIO(0x9888), 0x046c3422 },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c0800 },
- { _MMIO(0x9888), 0x065b4000 },
- { _MMIO(0x9888), 0x1a5c1000 },
- { _MMIO(0x9888), 0x06614000 },
- { _MMIO(0x9888), 0x0c620044 },
- { _MMIO(0x9888), 0x10620000 },
- { _MMIO(0x9888), 0x06620000 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x0a4c002a },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f4000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2cc000 },
- { _MMIO(0x9888), 0x1190f800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_l3_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_2;
- lens[n] = ARRAY_SIZE(mux_config_l3_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_3[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00028002 },
- { _MMIO(0x277c), 0x000087ff },
- { _MMIO(0x2780), 0x00020002 },
- { _MMIO(0x2784), 0x00008fff },
- { _MMIO(0x2788), 0x00008002 },
- { _MMIO(0x278c), 0x0000a7ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_3[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_3[] = {
- { _MMIO(0x9888), 0x126c4e80 },
- { _MMIO(0x9888), 0x146c0000 },
- { _MMIO(0x9888), 0x0a633400 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0c4e8000 },
- { _MMIO(0x9888), 0x026c3321 },
- { _MMIO(0x9888), 0x046c342f },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1a6c2000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x061b4000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c1800 },
- { _MMIO(0x9888), 0x06604000 },
- { _MMIO(0x9888), 0x0c630044 },
- { _MMIO(0x9888), 0x10630000 },
- { _MMIO(0x9888), 0x06630000 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x0a4c00aa },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f4000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x1190f800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900002 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_l3_3_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_3;
- lens[n] = ARRAY_SIZE(mux_config_l3_3);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000efff },
- { _MMIO(0x2778), 0x00006000 },
- { _MMIO(0x277c), 0x0000f3ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x9888), 0x102f3800 },
- { _MMIO(0x9888), 0x144d0500 },
- { _MMIO(0x9888), 0x120d03c0 },
- { _MMIO(0x9888), 0x140d03cf },
- { _MMIO(0x9888), 0x0c0f0004 },
- { _MMIO(0x9888), 0x0c4e4000 },
- { _MMIO(0x9888), 0x042f0480 },
- { _MMIO(0x9888), 0x082f0000 },
- { _MMIO(0x9888), 0x022f0000 },
- { _MMIO(0x9888), 0x0a4c0090 },
- { _MMIO(0x9888), 0x064d0027 },
- { _MMIO(0x9888), 0x004d0000 },
- { _MMIO(0x9888), 0x000d0d40 },
- { _MMIO(0x9888), 0x020d803f },
- { _MMIO(0x9888), 0x040d8023 },
- { _MMIO(0x9888), 0x100d0000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x020f0010 },
- { _MMIO(0x9888), 0x000f0000 },
- { _MMIO(0x9888), 0x0e0f0050 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41901400 },
- { _MMIO(0x9888), 0x43901485 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900001 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_rasterizer_and_pixel_backend;
- lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_sampler[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x70800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x0000c000 },
- { _MMIO(0x2774), 0x0000e7ff },
- { _MMIO(0x2778), 0x00003000 },
- { _MMIO(0x277c), 0x0000f9ff },
- { _MMIO(0x2780), 0x00000c00 },
- { _MMIO(0x2784), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_sampler[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_sampler[] = {
- { _MMIO(0x9888), 0x14152c00 },
- { _MMIO(0x9888), 0x16150005 },
- { _MMIO(0x9888), 0x121600a0 },
- { _MMIO(0x9888), 0x14352c00 },
- { _MMIO(0x9888), 0x16350005 },
- { _MMIO(0x9888), 0x123600a0 },
- { _MMIO(0x9888), 0x14552c00 },
- { _MMIO(0x9888), 0x16550005 },
- { _MMIO(0x9888), 0x125600a0 },
- { _MMIO(0x9888), 0x062f6000 },
- { _MMIO(0x9888), 0x022f2000 },
- { _MMIO(0x9888), 0x0c4c0050 },
- { _MMIO(0x9888), 0x0a4c0010 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f0350 },
- { _MMIO(0x9888), 0x0c0fb000 },
- { _MMIO(0x9888), 0x0e0f00da },
- { _MMIO(0x9888), 0x182c0028 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x022dc000 },
- { _MMIO(0x9888), 0x042d4000 },
- { _MMIO(0x9888), 0x0c138000 },
- { _MMIO(0x9888), 0x0e132000 },
- { _MMIO(0x9888), 0x0413c000 },
- { _MMIO(0x9888), 0x1c140018 },
- { _MMIO(0x9888), 0x0c157000 },
- { _MMIO(0x9888), 0x0e150078 },
- { _MMIO(0x9888), 0x10150000 },
- { _MMIO(0x9888), 0x04162180 },
- { _MMIO(0x9888), 0x02160000 },
- { _MMIO(0x9888), 0x04174000 },
- { _MMIO(0x9888), 0x0233a000 },
- { _MMIO(0x9888), 0x04333000 },
- { _MMIO(0x9888), 0x14348000 },
- { _MMIO(0x9888), 0x16348000 },
- { _MMIO(0x9888), 0x02357870 },
- { _MMIO(0x9888), 0x10350000 },
- { _MMIO(0x9888), 0x04360043 },
- { _MMIO(0x9888), 0x02360000 },
- { _MMIO(0x9888), 0x04371000 },
- { _MMIO(0x9888), 0x0e538000 },
- { _MMIO(0x9888), 0x00538000 },
- { _MMIO(0x9888), 0x06533000 },
- { _MMIO(0x9888), 0x1c540020 },
- { _MMIO(0x9888), 0x12548000 },
- { _MMIO(0x9888), 0x0e557000 },
- { _MMIO(0x9888), 0x00557800 },
- { _MMIO(0x9888), 0x10550000 },
- { _MMIO(0x9888), 0x06560043 },
- { _MMIO(0x9888), 0x02560000 },
- { _MMIO(0x9888), 0x06571000 },
- { _MMIO(0x9888), 0x1190ff80 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900060 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900060 },
-};
-
-static int
-get_sampler_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_sampler;
- lens[n] = ARRAY_SIZE(mux_config_sampler);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x00007fff },
- { _MMIO(0x2778), 0x00000000 },
- { _MMIO(0x277c), 0x00009fff },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000efff },
- { _MMIO(0x2788), 0x00000000 },
- { _MMIO(0x278c), 0x0000f3ff },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000fdff },
- { _MMIO(0x2798), 0x00000000 },
- { _MMIO(0x279c), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_1[] = {
- { _MMIO(0x9888), 0x12120000 },
- { _MMIO(0x9888), 0x12320000 },
- { _MMIO(0x9888), 0x12520000 },
- { _MMIO(0x9888), 0x002f8000 },
- { _MMIO(0x9888), 0x022f3000 },
- { _MMIO(0x9888), 0x0a4c0015 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f03a0 },
- { _MMIO(0x9888), 0x0c0ff000 },
- { _MMIO(0x9888), 0x0e0f0095 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2d8000 },
- { _MMIO(0x9888), 0x0e2d4000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x02108000 },
- { _MMIO(0x9888), 0x0410c000 },
- { _MMIO(0x9888), 0x02118000 },
- { _MMIO(0x9888), 0x0411c000 },
- { _MMIO(0x9888), 0x02121880 },
- { _MMIO(0x9888), 0x041219b5 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x02134000 },
- { _MMIO(0x9888), 0x04135000 },
- { _MMIO(0x9888), 0x0c308000 },
- { _MMIO(0x9888), 0x0e304000 },
- { _MMIO(0x9888), 0x06304000 },
- { _MMIO(0x9888), 0x0c318000 },
- { _MMIO(0x9888), 0x0e314000 },
- { _MMIO(0x9888), 0x06314000 },
- { _MMIO(0x9888), 0x0c321a80 },
- { _MMIO(0x9888), 0x0e320033 },
- { _MMIO(0x9888), 0x06320031 },
- { _MMIO(0x9888), 0x00320000 },
- { _MMIO(0x9888), 0x0c334000 },
- { _MMIO(0x9888), 0x0e331000 },
- { _MMIO(0x9888), 0x06331000 },
- { _MMIO(0x9888), 0x0e508000 },
- { _MMIO(0x9888), 0x00508000 },
- { _MMIO(0x9888), 0x02504000 },
- { _MMIO(0x9888), 0x0e518000 },
- { _MMIO(0x9888), 0x00518000 },
- { _MMIO(0x9888), 0x02514000 },
- { _MMIO(0x9888), 0x0e521880 },
- { _MMIO(0x9888), 0x00521a80 },
- { _MMIO(0x9888), 0x02520033 },
- { _MMIO(0x9888), 0x0e534000 },
- { _MMIO(0x9888), 0x00534000 },
- { _MMIO(0x9888), 0x02531000 },
- { _MMIO(0x9888), 0x1190ff80 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900062 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
-};
-
-static int
-get_tdl_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_1;
- lens[n] = ARRAY_SIZE(mux_config_tdl_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_2[] = {
- { _MMIO(0x9888), 0x12124d60 },
- { _MMIO(0x9888), 0x12322e60 },
- { _MMIO(0x9888), 0x12524d60 },
- { _MMIO(0x9888), 0x022f3000 },
- { _MMIO(0x9888), 0x0a4c0014 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0fe000 },
- { _MMIO(0x9888), 0x0e0f0097 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x002d8000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x0410c000 },
- { _MMIO(0x9888), 0x0411c000 },
- { _MMIO(0x9888), 0x04121fb7 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x04135000 },
- { _MMIO(0x9888), 0x00308000 },
- { _MMIO(0x9888), 0x06304000 },
- { _MMIO(0x9888), 0x00318000 },
- { _MMIO(0x9888), 0x06314000 },
- { _MMIO(0x9888), 0x00321b80 },
- { _MMIO(0x9888), 0x0632003f },
- { _MMIO(0x9888), 0x00334000 },
- { _MMIO(0x9888), 0x06331000 },
- { _MMIO(0x9888), 0x0250c000 },
- { _MMIO(0x9888), 0x0251c000 },
- { _MMIO(0x9888), 0x02521fb7 },
- { _MMIO(0x9888), 0x00520000 },
- { _MMIO(0x9888), 0x02535000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x43900063 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_tdl_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_2;
- lens[n] = ARRAY_SIZE(mux_config_tdl_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extra[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extra[] = {
- { _MMIO(0xe458), 0x00001000 },
- { _MMIO(0xe558), 0x00003002 },
- { _MMIO(0xe658), 0x00005004 },
- { _MMIO(0xe758), 0x00011010 },
- { _MMIO(0xe45c), 0x00050012 },
- { _MMIO(0xe55c), 0x00052051 },
- { _MMIO(0xe65c), 0x00000008 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extra[] = {
- { _MMIO(0x9888), 0x121203e0 },
- { _MMIO(0x9888), 0x123203e0 },
- { _MMIO(0x9888), 0x125203e0 },
- { _MMIO(0x9888), 0x022f4000 },
- { _MMIO(0x9888), 0x0a4c0040 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0e0f006c },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x042d8000 },
- { _MMIO(0x9888), 0x06104000 },
- { _MMIO(0x9888), 0x06114000 },
- { _MMIO(0x9888), 0x06120033 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x06131000 },
- { _MMIO(0x9888), 0x04308000 },
- { _MMIO(0x9888), 0x04318000 },
- { _MMIO(0x9888), 0x04321980 },
- { _MMIO(0x9888), 0x00320000 },
- { _MMIO(0x9888), 0x04334000 },
- { _MMIO(0x9888), 0x04504000 },
- { _MMIO(0x9888), 0x04514000 },
- { _MMIO(0x9888), 0x04520033 },
- { _MMIO(0x9888), 0x00520000 },
- { _MMIO(0x9888), 0x04531000 },
- { _MMIO(0x9888), 0x1190e000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900c00 },
- { _MMIO(0x9888), 0x45900002 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_compute_extra_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extra;
- lens[n] = ARRAY_SIZE(mux_config_compute_extra);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_vme_pipe[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00100030 },
- { _MMIO(0x2774), 0x0000fff9 },
- { _MMIO(0x2778), 0x00000002 },
- { _MMIO(0x277c), 0x0000fffc },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000fff3 },
- { _MMIO(0x2788), 0x00100180 },
- { _MMIO(0x278c), 0x0000ffcf },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000ffcf },
- { _MMIO(0x2798), 0x00000002 },
- { _MMIO(0x279c), 0x0000ff3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_vme_pipe[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00008003 },
-};
-
-static const struct i915_oa_reg mux_config_vme_pipe[] = {
- { _MMIO(0x9888), 0x141a5800 },
- { _MMIO(0x9888), 0x161a00c0 },
- { _MMIO(0x9888), 0x12180240 },
- { _MMIO(0x9888), 0x14180002 },
- { _MMIO(0x9888), 0x143a5800 },
- { _MMIO(0x9888), 0x163a00c0 },
- { _MMIO(0x9888), 0x12380240 },
- { _MMIO(0x9888), 0x14380002 },
- { _MMIO(0x9888), 0x002f1000 },
- { _MMIO(0x9888), 0x022f8000 },
- { _MMIO(0x9888), 0x042f3000 },
- { _MMIO(0x9888), 0x004c4000 },
- { _MMIO(0x9888), 0x0a4c1500 },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f9500 },
- { _MMIO(0x9888), 0x100f002a },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162c0a00 },
- { _MMIO(0x9888), 0x0a2dc000 },
- { _MMIO(0x9888), 0x0c2dc000 },
- { _MMIO(0x9888), 0x04193000 },
- { _MMIO(0x9888), 0x081a28c1 },
- { _MMIO(0x9888), 0x001a0000 },
- { _MMIO(0x9888), 0x00133000 },
- { _MMIO(0x9888), 0x0613c000 },
- { _MMIO(0x9888), 0x0813f000 },
- { _MMIO(0x9888), 0x00172000 },
- { _MMIO(0x9888), 0x06178000 },
- { _MMIO(0x9888), 0x0817a000 },
- { _MMIO(0x9888), 0x00180037 },
- { _MMIO(0x9888), 0x06180940 },
- { _MMIO(0x9888), 0x08180000 },
- { _MMIO(0x9888), 0x02180000 },
- { _MMIO(0x9888), 0x04183000 },
- { _MMIO(0x9888), 0x06393000 },
- { _MMIO(0x9888), 0x0c3a28c1 },
- { _MMIO(0x9888), 0x003a0000 },
- { _MMIO(0x9888), 0x0a33f000 },
- { _MMIO(0x9888), 0x0c33f000 },
- { _MMIO(0x9888), 0x0a37a000 },
- { _MMIO(0x9888), 0x0c37a000 },
- { _MMIO(0x9888), 0x0a380977 },
- { _MMIO(0x9888), 0x08380000 },
- { _MMIO(0x9888), 0x04380000 },
- { _MMIO(0x9888), 0x06383000 },
- { _MMIO(0x9888), 0x119000ff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900040 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900800 },
- { _MMIO(0x9888), 0x47901000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900844 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_vme_pipe_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_vme_pipe;
- lens[n] = ARRAY_SIZE(mux_config_vme_pipe);
- n++;
-
- return n;
-}
-
static const struct i915_oa_reg b_counter_config_test_oa[] = {
{ _MMIO(0x2740), 0x00000000 },
{ _MMIO(0x2744), 0x00800000 },
@@ -1882,6 +60,7 @@ static const struct i915_oa_reg flex_eu_config_test_oa[] = {
};
static const struct i915_oa_reg mux_config_test_oa[] = {
+ { _MMIO(0x9840), 0x00000080 },
{ _MMIO(0x9888), 0x11810000 },
{ _MMIO(0x9888), 0x07810013 },
{ _MMIO(0x9888), 0x1f810000 },
@@ -1896,1096 +75,35 @@ static const struct i915_oa_reg mux_config_test_oa[] = {
{ _MMIO(0x9888), 0x33900000 },
};
-static int
-get_test_oa_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_test_oa;
- lens[n] = ARRAY_SIZE(mux_config_test_oa);
- n++;
-
- return n;
-}
-
-int i915_oa_select_metric_set_kblgt2(struct drm_i915_private *dev_priv)
-{
- dev_priv->perf.oa.n_mux_configs = 0;
- dev_priv->perf.oa.b_counter_regs = NULL;
- dev_priv->perf.oa.b_counter_regs_len = 0;
- dev_priv->perf.oa.flex_regs = NULL;
- dev_priv->perf.oa.flex_regs_len = 0;
-
- switch (dev_priv->perf.oa.metrics_set) {
- case METRIC_SET_ID_RENDER_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_render_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_basic);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_basic);
-
- return 0;
- case METRIC_SET_ID_RENDER_PIPE_PROFILE:
- dev_priv->perf.oa.n_mux_configs =
- get_render_pipe_profile_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_pipe_profile;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_pipe_profile);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_pipe_profile;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_pipe_profile);
-
- return 0;
- case METRIC_SET_ID_MEMORY_READS:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_reads_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_reads;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_reads);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_reads;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_reads);
-
- return 0;
- case METRIC_SET_ID_MEMORY_WRITES:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_writes_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_writes;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_writes);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_writes;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_writes);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTENDED:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extended_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extended;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extended);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extended;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extended);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_L3_CACHE:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_l3_cache_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_L3_CACHE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_l3_cache;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_l3_cache);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_l3_cache;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_l3_cache);
-
- return 0;
- case METRIC_SET_ID_HDC_AND_SF:
- dev_priv->perf.oa.n_mux_configs =
- get_hdc_and_sf_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_hdc_and_sf;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_hdc_and_sf);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_hdc_and_sf;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_hdc_and_sf);
-
- return 0;
- case METRIC_SET_ID_L3_1:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_1);
-
- return 0;
- case METRIC_SET_ID_L3_2:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_2);
-
- return 0;
- case METRIC_SET_ID_L3_3:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_3_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_3\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_3;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_3);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_3;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_3);
-
- return 0;
- case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND:
- dev_priv->perf.oa.n_mux_configs =
- get_rasterizer_and_pixel_backend_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend);
-
- return 0;
- case METRIC_SET_ID_SAMPLER:
- dev_priv->perf.oa.n_mux_configs =
- get_sampler_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_sampler;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_sampler);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_sampler;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_sampler);
-
- return 0;
- case METRIC_SET_ID_TDL_1:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_1);
-
- return 0;
- case METRIC_SET_ID_TDL_2:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_2);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTRA:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extra_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTRA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extra;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extra);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extra;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extra);
-
- return 0;
- case METRIC_SET_ID_VME_PIPE:
- dev_priv->perf.oa.n_mux_configs =
- get_vme_pipe_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"VME_PIPE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_vme_pipe;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_vme_pipe);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_vme_pipe;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_vme_pipe);
-
- return 0;
- case METRIC_SET_ID_TEST_OA:
- dev_priv->perf.oa.n_mux_configs =
- get_test_oa_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_test_oa;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_test_oa);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_test_oa;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_test_oa);
-
- return 0;
- default:
- return -ENODEV;
- }
-}
-
-static ssize_t
-show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC);
-}
-
-static struct device_attribute dev_attr_render_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_basic[] = {
- &dev_attr_render_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_basic = {
- .name = "f8d677e9-ff6f-4df1-9310-0334c6efacce",
- .attrs = attrs_render_basic,
-};
-
-static ssize_t
-show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC);
-}
-
-static struct device_attribute dev_attr_compute_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_basic[] = {
- &dev_attr_compute_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_basic = {
- .name = "e17fc42a-e614-41b6-90c4-1074841a6c77",
- .attrs = attrs_compute_basic,
-};
-
-static ssize_t
-show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE);
-}
-
-static struct device_attribute dev_attr_render_pipe_profile_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_pipe_profile_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_pipe_profile[] = {
- &dev_attr_render_pipe_profile_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_pipe_profile = {
- .name = "d7a17a3a-ca71-40d2-a919-ace80d50633f",
- .attrs = attrs_render_pipe_profile,
-};
-
-static ssize_t
-show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS);
-}
-
-static struct device_attribute dev_attr_memory_reads_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_reads_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_reads[] = {
- &dev_attr_memory_reads_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_reads = {
- .name = "57b59202-172b-477a-87de-33f85572c589",
- .attrs = attrs_memory_reads,
-};
-
-static ssize_t
-show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES);
-}
-
-static struct device_attribute dev_attr_memory_writes_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_writes_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_writes[] = {
- &dev_attr_memory_writes_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_writes = {
- .name = "3addf8ef-8e9b-40f5-a448-3dbb5d5128b0",
- .attrs = attrs_memory_writes,
-};
-
-static ssize_t
-show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED);
-}
-
-static struct device_attribute dev_attr_compute_extended_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extended_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extended[] = {
- &dev_attr_compute_extended_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extended = {
- .name = "4af0400a-81c3-47db-a6b6-deddbd75680e",
- .attrs = attrs_compute_extended,
-};
-
-static ssize_t
-show_compute_l3_cache_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_L3_CACHE);
-}
-
-static struct device_attribute dev_attr_compute_l3_cache_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_l3_cache_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_l3_cache[] = {
- &dev_attr_compute_l3_cache_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_l3_cache = {
- .name = "0e22f995-79ca-4f67-83ab-e9d9772488d8",
- .attrs = attrs_compute_l3_cache,
-};
-
-static ssize_t
-show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF);
-}
-
-static struct device_attribute dev_attr_hdc_and_sf_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_hdc_and_sf_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_hdc_and_sf[] = {
- &dev_attr_hdc_and_sf_id.attr,
- NULL,
-};
-
-static struct attribute_group group_hdc_and_sf = {
- .name = "bc2a00f7-cb8a-4ff2-8ad0-e241dad16937",
- .attrs = attrs_hdc_and_sf,
-};
-
-static ssize_t
-show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1);
-}
-
-static struct device_attribute dev_attr_l3_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_1[] = {
- &dev_attr_l3_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_1 = {
- .name = "d2bbe790-f058-42d9-81c6-cdedcf655bc2",
- .attrs = attrs_l3_1,
-};
-
-static ssize_t
-show_l3_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_2);
-}
-
-static struct device_attribute dev_attr_l3_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_2[] = {
- &dev_attr_l3_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_2 = {
- .name = "2f8e32e4-5956-46e2-af31-c8ea95887332",
- .attrs = attrs_l3_2,
-};
-
-static ssize_t
-show_l3_3_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_3);
-}
-
-static struct device_attribute dev_attr_l3_3_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_3_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_3[] = {
- &dev_attr_l3_3_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_3 = {
- .name = "ca046aad-b5fb-4101-adce-6473ee6e5b14",
- .attrs = attrs_l3_3,
-};
-
-static ssize_t
-show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND);
-}
-
-static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_rasterizer_and_pixel_backend_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_rasterizer_and_pixel_backend[] = {
- &dev_attr_rasterizer_and_pixel_backend_id.attr,
- NULL,
-};
-
-static struct attribute_group group_rasterizer_and_pixel_backend = {
- .name = "605f388f-24bb-455c-88e3-8d57ae0d7e9f",
- .attrs = attrs_rasterizer_and_pixel_backend,
-};
-
-static ssize_t
-show_sampler_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER);
-}
-
-static struct device_attribute dev_attr_sampler_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_sampler_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_sampler[] = {
- &dev_attr_sampler_id.attr,
- NULL,
-};
-
-static struct attribute_group group_sampler = {
- .name = "31dd157c-bf4e-4bab-bf2b-f5c8174af1af",
- .attrs = attrs_sampler,
-};
-
-static ssize_t
-show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1);
-}
-
-static struct device_attribute dev_attr_tdl_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_1[] = {
- &dev_attr_tdl_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_1 = {
- .name = "105db928-5542-466b-9128-e1f3c91426cb",
- .attrs = attrs_tdl_1,
-};
-
-static ssize_t
-show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2);
-}
-
-static struct device_attribute dev_attr_tdl_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_2[] = {
- &dev_attr_tdl_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_2 = {
- .name = "03db94d2-b37f-4c58-a791-0d2067b013bb",
- .attrs = attrs_tdl_2,
-};
-
-static ssize_t
-show_compute_extra_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTRA);
-}
-
-static struct device_attribute dev_attr_compute_extra_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extra_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extra[] = {
- &dev_attr_compute_extra_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extra = {
- .name = "aa7a3fb9-22fb-43ff-a32d-0ab6c13bbd16",
- .attrs = attrs_compute_extra,
-};
-
-static ssize_t
-show_vme_pipe_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_VME_PIPE);
-}
-
-static struct device_attribute dev_attr_vme_pipe_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_vme_pipe_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_vme_pipe[] = {
- &dev_attr_vme_pipe_id.attr,
- NULL,
-};
-
-static struct attribute_group group_vme_pipe = {
- .name = "398a4268-ef6f-4ffc-b55f-3c7b5363ce61",
- .attrs = attrs_vme_pipe,
-};
-
static ssize_t
show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA);
+ return sprintf(buf, "1\n");
}
-static struct device_attribute dev_attr_test_oa_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_test_oa_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_test_oa[] = {
- &dev_attr_test_oa_id.attr,
- NULL,
-};
-
-static struct attribute_group group_test_oa = {
- .name = "baa3c7e4-52b6-4b85-801e-465a94b746dd",
- .attrs = attrs_test_oa,
-};
-
-int
-i915_perf_register_sysfs_kblgt2(struct drm_i915_private *dev_priv)
+void
+i915_perf_load_test_config_kblgt2(struct drm_i915_private *dev_priv)
{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
- int ret = 0;
+ strncpy(dev_priv->perf.oa.test_config.uuid,
+ "baa3c7e4-52b6-4b85-801e-465a94b746dd",
+ UUID_STRING_LEN);
+ dev_priv->perf.oa.test_config.id = 1;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (ret)
- goto error_render_basic;
- }
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (ret)
- goto error_compute_basic;
- }
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (ret)
- goto error_render_pipe_profile;
- }
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (ret)
- goto error_memory_reads;
- }
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (ret)
- goto error_memory_writes;
- }
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (ret)
- goto error_compute_extended;
- }
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (ret)
- goto error_compute_l3_cache;
- }
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (ret)
- goto error_hdc_and_sf;
- }
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (ret)
- goto error_l3_1;
- }
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (ret)
- goto error_l3_2;
- }
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (ret)
- goto error_l3_3;
- }
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (ret)
- goto error_rasterizer_and_pixel_backend;
- }
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (ret)
- goto error_sampler;
- }
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (ret)
- goto error_tdl_1;
- }
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (ret)
- goto error_tdl_2;
- }
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (ret)
- goto error_compute_extra;
- }
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
- if (ret)
- goto error_vme_pipe;
- }
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa);
- if (ret)
- goto error_test_oa;
- }
+ dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
+ dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
- return 0;
+ dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
+ dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-error_test_oa:
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
-error_vme_pipe:
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
-error_compute_extra:
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
-error_tdl_2:
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
-error_tdl_1:
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
-error_sampler:
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
-error_rasterizer_and_pixel_backend:
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
-error_l3_3:
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
-error_l3_2:
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
-error_l3_1:
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
-error_hdc_and_sf:
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
-error_compute_l3_cache:
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
-error_compute_extended:
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
-error_memory_writes:
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
-error_memory_reads:
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
-error_render_pipe_profile:
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
-error_compute_basic:
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
-error_render_basic:
- return ret;
-}
+ dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
+ dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-void
-i915_perf_unregister_sysfs_kblgt2(struct drm_i915_private *dev_priv)
-{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
+ dev_priv->perf.oa.test_config.sysfs_metric.name = "baa3c7e4-52b6-4b85-801e-465a94b746dd";
+ dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+
+ dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa);
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
+ dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
}
diff --git a/drivers/gpu/drm/i915/i915_oa_kblgt2.h b/drivers/gpu/drm/i915/i915_oa_kblgt2.h
index 7e61bfc..25b80354 100644
--- a/drivers/gpu/drm/i915/i915_oa_kblgt2.h
+++ b/drivers/gpu/drm/i915/i915_oa_kblgt2.h
@@ -29,12 +29,6 @@
#ifndef __I915_OA_KBLGT2_H__
#define __I915_OA_KBLGT2_H__
-extern int i915_oa_n_builtin_metric_sets_kblgt2;
-
-extern int i915_oa_select_metric_set_kblgt2(struct drm_i915_private *dev_priv);
-
-extern int i915_perf_register_sysfs_kblgt2(struct drm_i915_private *dev_priv);
-
-extern void i915_perf_unregister_sysfs_kblgt2(struct drm_i915_private *dev_priv);
+extern void i915_perf_load_test_config_kblgt2(struct drm_i915_private *dev_priv);
#endif
diff --git a/drivers/gpu/drm/i915/i915_oa_kblgt3.c b/drivers/gpu/drm/i915/i915_oa_kblgt3.c
index 6ed0925..5576afd 100644
--- a/drivers/gpu/drm/i915/i915_oa_kblgt3.c
+++ b/drivers/gpu/drm/i915/i915_oa_kblgt3.c
@@ -31,1877 +31,6 @@
#include "i915_drv.h"
#include "i915_oa_kblgt3.h"
-enum metric_set_id {
- METRIC_SET_ID_RENDER_BASIC = 1,
- METRIC_SET_ID_COMPUTE_BASIC,
- METRIC_SET_ID_RENDER_PIPE_PROFILE,
- METRIC_SET_ID_MEMORY_READS,
- METRIC_SET_ID_MEMORY_WRITES,
- METRIC_SET_ID_COMPUTE_EXTENDED,
- METRIC_SET_ID_COMPUTE_L3_CACHE,
- METRIC_SET_ID_HDC_AND_SF,
- METRIC_SET_ID_L3_1,
- METRIC_SET_ID_L3_2,
- METRIC_SET_ID_L3_3,
- METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND,
- METRIC_SET_ID_SAMPLER,
- METRIC_SET_ID_TDL_1,
- METRIC_SET_ID_TDL_2,
- METRIC_SET_ID_COMPUTE_EXTRA,
- METRIC_SET_ID_VME_PIPE,
- METRIC_SET_ID_TEST_OA,
-};
-
-int i915_oa_n_builtin_metric_sets_kblgt3 = 18;
-
-static const struct i915_oa_reg b_counter_config_render_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_render_basic[] = {
- { _MMIO(0x9888), 0x166c01e0 },
- { _MMIO(0x9888), 0x12170280 },
- { _MMIO(0x9888), 0x12370280 },
- { _MMIO(0x9888), 0x16ec01e0 },
- { _MMIO(0x9888), 0x11930317 },
- { _MMIO(0x9888), 0x159303df },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x1a4e0380 },
- { _MMIO(0x9888), 0x0a6c0053 },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x0a1b4000 },
- { _MMIO(0x9888), 0x1c1c0001 },
- { _MMIO(0x9888), 0x002f1000 },
- { _MMIO(0x9888), 0x042f1000 },
- { _MMIO(0x9888), 0x004c4000 },
- { _MMIO(0x9888), 0x0a4c8400 },
- { _MMIO(0x9888), 0x0c4c0002 },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f6600 },
- { _MMIO(0x9888), 0x100f0001 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x162ca200 },
- { _MMIO(0x9888), 0x062d8000 },
- { _MMIO(0x9888), 0x082d8000 },
- { _MMIO(0x9888), 0x00133000 },
- { _MMIO(0x9888), 0x08133000 },
- { _MMIO(0x9888), 0x00170020 },
- { _MMIO(0x9888), 0x08170021 },
- { _MMIO(0x9888), 0x10170000 },
- { _MMIO(0x9888), 0x0633c000 },
- { _MMIO(0x9888), 0x0833c000 },
- { _MMIO(0x9888), 0x06370800 },
- { _MMIO(0x9888), 0x08370840 },
- { _MMIO(0x9888), 0x10370000 },
- { _MMIO(0x9888), 0x1ace0200 },
- { _MMIO(0x9888), 0x0aec5300 },
- { _MMIO(0x9888), 0x10ec0000 },
- { _MMIO(0x9888), 0x1cec0000 },
- { _MMIO(0x9888), 0x0a9b8000 },
- { _MMIO(0x9888), 0x1c9c0002 },
- { _MMIO(0x9888), 0x0ccc0002 },
- { _MMIO(0x9888), 0x0a8d8000 },
- { _MMIO(0x9888), 0x108f0001 },
- { _MMIO(0x9888), 0x16ac8000 },
- { _MMIO(0x9888), 0x0d933031 },
- { _MMIO(0x9888), 0x0f933e3f },
- { _MMIO(0x9888), 0x01933d00 },
- { _MMIO(0x9888), 0x0393073c },
- { _MMIO(0x9888), 0x0593000e },
- { _MMIO(0x9888), 0x1d930000 },
- { _MMIO(0x9888), 0x19930000 },
- { _MMIO(0x9888), 0x1b930000 },
- { _MMIO(0x9888), 0x1d900157 },
- { _MMIO(0x9888), 0x1f900158 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x2b908000 },
- { _MMIO(0x9888), 0x2d908000 },
- { _MMIO(0x9888), 0x2f908000 },
- { _MMIO(0x9888), 0x31908000 },
- { _MMIO(0x9888), 0x15908000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1190003f },
- { _MMIO(0x9888), 0x51902240 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x55900242 },
- { _MMIO(0x9888), 0x45900084 },
- { _MMIO(0x9888), 0x47901400 },
- { _MMIO(0x9888), 0x57902220 },
- { _MMIO(0x9888), 0x49900c60 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900002 },
- { _MMIO(0x9888), 0x43900c63 },
- { _MMIO(0x9888), 0x53902222 },
-};
-
-static int
-get_render_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_basic;
- lens[n] = ARRAY_SIZE(mux_config_render_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_basic[] = {
- { _MMIO(0x9888), 0x104f00e0 },
- { _MMIO(0x9888), 0x124f1c00 },
- { _MMIO(0x9888), 0x106c00e0 },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x1a4e0820 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x064f0900 },
- { _MMIO(0x9888), 0x084f0032 },
- { _MMIO(0x9888), 0x0a4f1891 },
- { _MMIO(0x9888), 0x0c4f0e00 },
- { _MMIO(0x9888), 0x0e4f003c },
- { _MMIO(0x9888), 0x004f0d80 },
- { _MMIO(0x9888), 0x024f003b },
- { _MMIO(0x9888), 0x006c0002 },
- { _MMIO(0x9888), 0x086c0100 },
- { _MMIO(0x9888), 0x0c6c000c },
- { _MMIO(0x9888), 0x0e6c0b00 },
- { _MMIO(0x9888), 0x186c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x001b4000 },
- { _MMIO(0x9888), 0x081b8000 },
- { _MMIO(0x9888), 0x0c1b4000 },
- { _MMIO(0x9888), 0x0e1b8000 },
- { _MMIO(0x9888), 0x101c8000 },
- { _MMIO(0x9888), 0x1a1c8000 },
- { _MMIO(0x9888), 0x1c1c0024 },
- { _MMIO(0x9888), 0x065b8000 },
- { _MMIO(0x9888), 0x085b4000 },
- { _MMIO(0x9888), 0x0a5bc000 },
- { _MMIO(0x9888), 0x0c5b8000 },
- { _MMIO(0x9888), 0x0e5b4000 },
- { _MMIO(0x9888), 0x005b8000 },
- { _MMIO(0x9888), 0x025b4000 },
- { _MMIO(0x9888), 0x1a5c6000 },
- { _MMIO(0x9888), 0x1c5c001b },
- { _MMIO(0x9888), 0x125c8000 },
- { _MMIO(0x9888), 0x145c8000 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4c2000 },
- { _MMIO(0x9888), 0x0c4c0208 },
- { _MMIO(0x9888), 0x000da000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x020d2000 },
- { _MMIO(0x9888), 0x0c0f5400 },
- { _MMIO(0x9888), 0x0e0f5500 },
- { _MMIO(0x9888), 0x100f0155 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2cc000 },
- { _MMIO(0x9888), 0x162cfb00 },
- { _MMIO(0x9888), 0x182c00be },
- { _MMIO(0x9888), 0x022cc000 },
- { _MMIO(0x9888), 0x042cc000 },
- { _MMIO(0x9888), 0x19900157 },
- { _MMIO(0x9888), 0x1b900158 },
- { _MMIO(0x9888), 0x1d900105 },
- { _MMIO(0x9888), 0x1f900103 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x11900fff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900821 },
- { _MMIO(0x9888), 0x47900802 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900802 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900002 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900422 },
- { _MMIO(0x9888), 0x53904444 },
-};
-
-static int
-get_compute_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_basic;
- lens[n] = ARRAY_SIZE(mux_config_compute_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007ffea },
- { _MMIO(0x2774), 0x00007ffc },
- { _MMIO(0x2778), 0x0007affa },
- { _MMIO(0x277c), 0x0000f5fd },
- { _MMIO(0x2780), 0x00079ffa },
- { _MMIO(0x2784), 0x0000f3fb },
- { _MMIO(0x2788), 0x0007bf7a },
- { _MMIO(0x278c), 0x0000f7e7 },
- { _MMIO(0x2790), 0x0007fefa },
- { _MMIO(0x2794), 0x0000f7cf },
- { _MMIO(0x2798), 0x00077ffa },
- { _MMIO(0x279c), 0x0000efdf },
- { _MMIO(0x27a0), 0x0006fffa },
- { _MMIO(0x27a4), 0x0000cfbf },
- { _MMIO(0x27a8), 0x0003fffa },
- { _MMIO(0x27ac), 0x00005f7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_render_pipe_profile[] = {
- { _MMIO(0x9888), 0x0c0e001f },
- { _MMIO(0x9888), 0x0a0f0000 },
- { _MMIO(0x9888), 0x10116800 },
- { _MMIO(0x9888), 0x178a03e0 },
- { _MMIO(0x9888), 0x11824c00 },
- { _MMIO(0x9888), 0x11830020 },
- { _MMIO(0x9888), 0x13840020 },
- { _MMIO(0x9888), 0x11850019 },
- { _MMIO(0x9888), 0x11860007 },
- { _MMIO(0x9888), 0x01870c40 },
- { _MMIO(0x9888), 0x17880000 },
- { _MMIO(0x9888), 0x022f4000 },
- { _MMIO(0x9888), 0x0a4c0040 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x040d4000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x020e5400 },
- { _MMIO(0x9888), 0x000e0000 },
- { _MMIO(0x9888), 0x080f0040 },
- { _MMIO(0x9888), 0x000f0000 },
- { _MMIO(0x9888), 0x100f0000 },
- { _MMIO(0x9888), 0x0e0f0040 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x06104000 },
- { _MMIO(0x9888), 0x06110012 },
- { _MMIO(0x9888), 0x06131000 },
- { _MMIO(0x9888), 0x01898000 },
- { _MMIO(0x9888), 0x0d890100 },
- { _MMIO(0x9888), 0x03898000 },
- { _MMIO(0x9888), 0x09808000 },
- { _MMIO(0x9888), 0x0b808000 },
- { _MMIO(0x9888), 0x0380c000 },
- { _MMIO(0x9888), 0x0f8a0075 },
- { _MMIO(0x9888), 0x1d8a0000 },
- { _MMIO(0x9888), 0x118a8000 },
- { _MMIO(0x9888), 0x1b8a4000 },
- { _MMIO(0x9888), 0x138a8000 },
- { _MMIO(0x9888), 0x1d81a000 },
- { _MMIO(0x9888), 0x15818000 },
- { _MMIO(0x9888), 0x17818000 },
- { _MMIO(0x9888), 0x0b820030 },
- { _MMIO(0x9888), 0x07828000 },
- { _MMIO(0x9888), 0x0d824000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x05824000 },
- { _MMIO(0x9888), 0x0d830003 },
- { _MMIO(0x9888), 0x0583000c },
- { _MMIO(0x9888), 0x09830000 },
- { _MMIO(0x9888), 0x03838000 },
- { _MMIO(0x9888), 0x07838000 },
- { _MMIO(0x9888), 0x0b840980 },
- { _MMIO(0x9888), 0x03844d80 },
- { _MMIO(0x9888), 0x11840000 },
- { _MMIO(0x9888), 0x09848000 },
- { _MMIO(0x9888), 0x09850080 },
- { _MMIO(0x9888), 0x03850003 },
- { _MMIO(0x9888), 0x01850000 },
- { _MMIO(0x9888), 0x07860000 },
- { _MMIO(0x9888), 0x0f860400 },
- { _MMIO(0x9888), 0x09870032 },
- { _MMIO(0x9888), 0x01888052 },
- { _MMIO(0x9888), 0x11880000 },
- { _MMIO(0x9888), 0x09884000 },
- { _MMIO(0x9888), 0x1b931001 },
- { _MMIO(0x9888), 0x1d930001 },
- { _MMIO(0x9888), 0x19934000 },
- { _MMIO(0x9888), 0x1b958000 },
- { _MMIO(0x9888), 0x1d950094 },
- { _MMIO(0x9888), 0x19958000 },
- { _MMIO(0x9888), 0x09e58000 },
- { _MMIO(0x9888), 0x0be58000 },
- { _MMIO(0x9888), 0x03e5c000 },
- { _MMIO(0x9888), 0x0592c000 },
- { _MMIO(0x9888), 0x0b928000 },
- { _MMIO(0x9888), 0x0d924000 },
- { _MMIO(0x9888), 0x0f924000 },
- { _MMIO(0x9888), 0x11928000 },
- { _MMIO(0x9888), 0x1392c000 },
- { _MMIO(0x9888), 0x09924000 },
- { _MMIO(0x9888), 0x01985000 },
- { _MMIO(0x9888), 0x07988000 },
- { _MMIO(0x9888), 0x09981000 },
- { _MMIO(0x9888), 0x0b982000 },
- { _MMIO(0x9888), 0x0d982000 },
- { _MMIO(0x9888), 0x0f989000 },
- { _MMIO(0x9888), 0x05982000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x23904000 },
- { _MMIO(0x9888), 0x25908000 },
- { _MMIO(0x9888), 0x27904000 },
- { _MMIO(0x9888), 0x29908000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1190c080 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900440 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900400 },
- { _MMIO(0x9888), 0x47900c21 },
- { _MMIO(0x9888), 0x57900400 },
- { _MMIO(0x9888), 0x49900042 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900024 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900841 },
- { _MMIO(0x9888), 0x53900400 },
-};
-
-static int
-get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_pipe_profile;
- lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_reads[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f872 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_reads[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_reads[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f900064 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x1b930055 },
- { _MMIO(0x9888), 0x03e58000 },
- { _MMIO(0x9888), 0x05e5c000 },
- { _MMIO(0x9888), 0x07e54000 },
- { _MMIO(0x9888), 0x13900150 },
- { _MMIO(0x9888), 0x21900151 },
- { _MMIO(0x9888), 0x23900152 },
- { _MMIO(0x9888), 0x25900153 },
- { _MMIO(0x9888), 0x27900154 },
- { _MMIO(0x9888), 0x29900155 },
- { _MMIO(0x9888), 0x2b900156 },
- { _MMIO(0x9888), 0x2d900157 },
- { _MMIO(0x9888), 0x2f90015f },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c60 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900c00 },
- { _MMIO(0x9888), 0x47900c63 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900c63 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_memory_reads_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_reads;
- lens[n] = ARRAY_SIZE(mux_config_memory_reads);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_writes[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f822 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_writes[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_writes[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f901000 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x1b930055 },
- { _MMIO(0x9888), 0x03e58000 },
- { _MMIO(0x9888), 0x05e5c000 },
- { _MMIO(0x9888), 0x07e54000 },
- { _MMIO(0x9888), 0x13900160 },
- { _MMIO(0x9888), 0x21900161 },
- { _MMIO(0x9888), 0x23900162 },
- { _MMIO(0x9888), 0x25900163 },
- { _MMIO(0x9888), 0x27900164 },
- { _MMIO(0x9888), 0x29900165 },
- { _MMIO(0x9888), 0x2b900166 },
- { _MMIO(0x9888), 0x2d900167 },
- { _MMIO(0x9888), 0x2f900150 },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c60 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900c00 },
- { _MMIO(0x9888), 0x47900c63 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900c63 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_memory_writes_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_writes;
- lens[n] = ARRAY_SIZE(mux_config_memory_writes);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extended[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fc2a },
- { _MMIO(0x2774), 0x0000bf00 },
- { _MMIO(0x2778), 0x0007fc6a },
- { _MMIO(0x277c), 0x0000bf00 },
- { _MMIO(0x2780), 0x0007fc92 },
- { _MMIO(0x2784), 0x0000bf00 },
- { _MMIO(0x2788), 0x0007fca2 },
- { _MMIO(0x278c), 0x0000bf00 },
- { _MMIO(0x2790), 0x0007fc32 },
- { _MMIO(0x2794), 0x0000bf00 },
- { _MMIO(0x2798), 0x0007fc9a },
- { _MMIO(0x279c), 0x0000bf00 },
- { _MMIO(0x27a0), 0x0007fe6a },
- { _MMIO(0x27a4), 0x0000bf00 },
- { _MMIO(0x27a8), 0x0007fe7a },
- { _MMIO(0x27ac), 0x0000bf00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extended[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended[] = {
- { _MMIO(0x9888), 0x106c00e0 },
- { _MMIO(0x9888), 0x141c8160 },
- { _MMIO(0x9888), 0x161c8015 },
- { _MMIO(0x9888), 0x181c0120 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x184e8000 },
- { _MMIO(0x9888), 0x1a4eaaa0 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x024e8000 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0e6c0b01 },
- { _MMIO(0x9888), 0x006c0200 },
- { _MMIO(0x9888), 0x026c000c },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x001b8000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x001c0041 },
- { _MMIO(0x9888), 0x061c4200 },
- { _MMIO(0x9888), 0x081c4443 },
- { _MMIO(0x9888), 0x0a1c4645 },
- { _MMIO(0x9888), 0x0c1c7647 },
- { _MMIO(0x9888), 0x041c7357 },
- { _MMIO(0x9888), 0x1c1c0030 },
- { _MMIO(0x9888), 0x101c0000 },
- { _MMIO(0x9888), 0x1a1c0000 },
- { _MMIO(0x9888), 0x121c8000 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4caa2a },
- { _MMIO(0x9888), 0x0c4c02aa },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x000da000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x0c0f5400 },
- { _MMIO(0x9888), 0x0e0f5515 },
- { _MMIO(0x9888), 0x100f0155 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162caa00 },
- { _MMIO(0x9888), 0x182c00aa },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x11907fff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900040 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900802 },
- { _MMIO(0x9888), 0x47900842 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900842 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900800 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_compute_extended_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extended;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_l3_cache[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fffa },
- { _MMIO(0x2774), 0x0000fefe },
- { _MMIO(0x2778), 0x0007fffa },
- { _MMIO(0x277c), 0x0000fefd },
- { _MMIO(0x2790), 0x0007fffa },
- { _MMIO(0x2794), 0x0000fbef },
- { _MMIO(0x2798), 0x0007fffa },
- { _MMIO(0x279c), 0x0000fbdf },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_l3_cache[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00101100 },
- { _MMIO(0xe45c), 0x00201200 },
- { _MMIO(0xe55c), 0x00301300 },
- { _MMIO(0xe65c), 0x00401400 },
-};
-
-static const struct i915_oa_reg mux_config_compute_l3_cache[] = {
- { _MMIO(0x9888), 0x166c0760 },
- { _MMIO(0x9888), 0x1593001e },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x184e8000 },
- { _MMIO(0x9888), 0x1a4e8020 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x006c0051 },
- { _MMIO(0x9888), 0x066c5000 },
- { _MMIO(0x9888), 0x086c5c5d },
- { _MMIO(0x9888), 0x0e6c5e5f },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x186c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x001b4000 },
- { _MMIO(0x9888), 0x061b8000 },
- { _MMIO(0x9888), 0x081bc000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x101c8000 },
- { _MMIO(0x9888), 0x1a1ce000 },
- { _MMIO(0x9888), 0x1c1c0030 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4c2a00 },
- { _MMIO(0x9888), 0x0c4c0280 },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f1500 },
- { _MMIO(0x9888), 0x100f0140 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162c0a00 },
- { _MMIO(0x9888), 0x182c00a0 },
- { _MMIO(0x9888), 0x03933300 },
- { _MMIO(0x9888), 0x05930032 },
- { _MMIO(0x9888), 0x11930000 },
- { _MMIO(0x9888), 0x1b930000 },
- { _MMIO(0x9888), 0x1d900157 },
- { _MMIO(0x9888), 0x1f900158 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1190030f },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900000 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900021 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x53904444 },
- { _MMIO(0x9888), 0x43900000 },
-};
-
-static int
-get_compute_l3_cache_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_l3_cache;
- lens[n] = ARRAY_SIZE(mux_config_compute_l3_cache);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x10800000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fdff },
-};
-
-static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_hdc_and_sf[] = {
- { _MMIO(0x9888), 0x104f0232 },
- { _MMIO(0x9888), 0x124f4640 },
- { _MMIO(0x9888), 0x106c0232 },
- { _MMIO(0x9888), 0x11834400 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0c4e8000 },
- { _MMIO(0x9888), 0x004f1880 },
- { _MMIO(0x9888), 0x024f08bb },
- { _MMIO(0x9888), 0x044f001b },
- { _MMIO(0x9888), 0x046c0100 },
- { _MMIO(0x9888), 0x066c000b },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x041b8000 },
- { _MMIO(0x9888), 0x061b4000 },
- { _MMIO(0x9888), 0x1a1c1800 },
- { _MMIO(0x9888), 0x005b8000 },
- { _MMIO(0x9888), 0x025bc000 },
- { _MMIO(0x9888), 0x045b4000 },
- { _MMIO(0x9888), 0x125c8000 },
- { _MMIO(0x9888), 0x145c8000 },
- { _MMIO(0x9888), 0x165c8000 },
- { _MMIO(0x9888), 0x185c8000 },
- { _MMIO(0x9888), 0x0a4c00a0 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x022cc000 },
- { _MMIO(0x9888), 0x042cc000 },
- { _MMIO(0x9888), 0x062cc000 },
- { _MMIO(0x9888), 0x082cc000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x0f8305c0 },
- { _MMIO(0x9888), 0x09830000 },
- { _MMIO(0x9888), 0x07830000 },
- { _MMIO(0x9888), 0x1d950080 },
- { _MMIO(0x9888), 0x13928000 },
- { _MMIO(0x9888), 0x0f988000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900040 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_hdc_and_sf;
- lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_1[] = {
- { _MMIO(0x9888), 0x126c7b40 },
- { _MMIO(0x9888), 0x166c0020 },
- { _MMIO(0x9888), 0x0a603444 },
- { _MMIO(0x9888), 0x0a613400 },
- { _MMIO(0x9888), 0x1a4ea800 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x024e8000 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x064f4000 },
- { _MMIO(0x9888), 0x0c6c5327 },
- { _MMIO(0x9888), 0x0e6c5425 },
- { _MMIO(0x9888), 0x006c2a00 },
- { _MMIO(0x9888), 0x026c285b },
- { _MMIO(0x9888), 0x046c005c },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x1a6c0800 },
- { _MMIO(0x9888), 0x0c1bc000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x001b8000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x1c1c003c },
- { _MMIO(0x9888), 0x121c8000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c0800 },
- { _MMIO(0x9888), 0x065b4000 },
- { _MMIO(0x9888), 0x1a5c1000 },
- { _MMIO(0x9888), 0x10600000 },
- { _MMIO(0x9888), 0x04600000 },
- { _MMIO(0x9888), 0x0c610044 },
- { _MMIO(0x9888), 0x10610000 },
- { _MMIO(0x9888), 0x06610000 },
- { _MMIO(0x9888), 0x0c4c02a8 },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x0a4c002a },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f0154 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x182c00aa },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2cc000 },
- { _MMIO(0x9888), 0x1190ffc0 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900420 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900021 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900400 },
- { _MMIO(0x9888), 0x43900421 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
-};
-
-static int
-get_l3_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_1;
- lens[n] = ARRAY_SIZE(mux_config_l3_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00028002 },
- { _MMIO(0x277c), 0x000087ff },
- { _MMIO(0x2780), 0x00020002 },
- { _MMIO(0x2784), 0x00008fff },
- { _MMIO(0x2788), 0x00008002 },
- { _MMIO(0x278c), 0x0000a7ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_2[] = {
- { _MMIO(0x9888), 0x126c02e0 },
- { _MMIO(0x9888), 0x146c0001 },
- { _MMIO(0x9888), 0x0a623400 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x064f4000 },
- { _MMIO(0x9888), 0x026c3324 },
- { _MMIO(0x9888), 0x046c3422 },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c0800 },
- { _MMIO(0x9888), 0x065b4000 },
- { _MMIO(0x9888), 0x1a5c1000 },
- { _MMIO(0x9888), 0x06614000 },
- { _MMIO(0x9888), 0x0c620044 },
- { _MMIO(0x9888), 0x10620000 },
- { _MMIO(0x9888), 0x06620000 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x0a4c002a },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f4000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2cc000 },
- { _MMIO(0x9888), 0x1190f800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_l3_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_2;
- lens[n] = ARRAY_SIZE(mux_config_l3_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_3[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00028002 },
- { _MMIO(0x277c), 0x000087ff },
- { _MMIO(0x2780), 0x00020002 },
- { _MMIO(0x2784), 0x00008fff },
- { _MMIO(0x2788), 0x00008002 },
- { _MMIO(0x278c), 0x0000a7ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_3[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_3[] = {
- { _MMIO(0x9888), 0x126c4e80 },
- { _MMIO(0x9888), 0x146c0000 },
- { _MMIO(0x9888), 0x0a633400 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0c4e8000 },
- { _MMIO(0x9888), 0x026c3321 },
- { _MMIO(0x9888), 0x046c342f },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1a6c2000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x061b4000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c1800 },
- { _MMIO(0x9888), 0x06604000 },
- { _MMIO(0x9888), 0x0c630044 },
- { _MMIO(0x9888), 0x10630000 },
- { _MMIO(0x9888), 0x06630000 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x0a4c00aa },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f4000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x1190f800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900002 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_l3_3_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_3;
- lens[n] = ARRAY_SIZE(mux_config_l3_3);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000efff },
- { _MMIO(0x2778), 0x00006000 },
- { _MMIO(0x277c), 0x0000f3ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x9888), 0x102f3800 },
- { _MMIO(0x9888), 0x144d0500 },
- { _MMIO(0x9888), 0x120d03c0 },
- { _MMIO(0x9888), 0x140d03cf },
- { _MMIO(0x9888), 0x0c0f0004 },
- { _MMIO(0x9888), 0x0c4e4000 },
- { _MMIO(0x9888), 0x042f0480 },
- { _MMIO(0x9888), 0x082f0000 },
- { _MMIO(0x9888), 0x022f0000 },
- { _MMIO(0x9888), 0x0a4c0090 },
- { _MMIO(0x9888), 0x064d0027 },
- { _MMIO(0x9888), 0x004d0000 },
- { _MMIO(0x9888), 0x000d0d40 },
- { _MMIO(0x9888), 0x020d803f },
- { _MMIO(0x9888), 0x040d8023 },
- { _MMIO(0x9888), 0x100d0000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x020f0010 },
- { _MMIO(0x9888), 0x000f0000 },
- { _MMIO(0x9888), 0x0e0f0050 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41901400 },
- { _MMIO(0x9888), 0x43901485 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900001 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_rasterizer_and_pixel_backend;
- lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_sampler[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x70800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x0000c000 },
- { _MMIO(0x2774), 0x0000e7ff },
- { _MMIO(0x2778), 0x00003000 },
- { _MMIO(0x277c), 0x0000f9ff },
- { _MMIO(0x2780), 0x00000c00 },
- { _MMIO(0x2784), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_sampler[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_sampler[] = {
- { _MMIO(0x9888), 0x14152c00 },
- { _MMIO(0x9888), 0x16150005 },
- { _MMIO(0x9888), 0x121600a0 },
- { _MMIO(0x9888), 0x14352c00 },
- { _MMIO(0x9888), 0x16350005 },
- { _MMIO(0x9888), 0x123600a0 },
- { _MMIO(0x9888), 0x14552c00 },
- { _MMIO(0x9888), 0x16550005 },
- { _MMIO(0x9888), 0x125600a0 },
- { _MMIO(0x9888), 0x062f6000 },
- { _MMIO(0x9888), 0x022f2000 },
- { _MMIO(0x9888), 0x0c4c0050 },
- { _MMIO(0x9888), 0x0a4c0010 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f0350 },
- { _MMIO(0x9888), 0x0c0fb000 },
- { _MMIO(0x9888), 0x0e0f00da },
- { _MMIO(0x9888), 0x182c0028 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x022dc000 },
- { _MMIO(0x9888), 0x042d4000 },
- { _MMIO(0x9888), 0x0c138000 },
- { _MMIO(0x9888), 0x0e132000 },
- { _MMIO(0x9888), 0x0413c000 },
- { _MMIO(0x9888), 0x1c140018 },
- { _MMIO(0x9888), 0x0c157000 },
- { _MMIO(0x9888), 0x0e150078 },
- { _MMIO(0x9888), 0x10150000 },
- { _MMIO(0x9888), 0x04162180 },
- { _MMIO(0x9888), 0x02160000 },
- { _MMIO(0x9888), 0x04174000 },
- { _MMIO(0x9888), 0x0233a000 },
- { _MMIO(0x9888), 0x04333000 },
- { _MMIO(0x9888), 0x14348000 },
- { _MMIO(0x9888), 0x16348000 },
- { _MMIO(0x9888), 0x02357870 },
- { _MMIO(0x9888), 0x10350000 },
- { _MMIO(0x9888), 0x04360043 },
- { _MMIO(0x9888), 0x02360000 },
- { _MMIO(0x9888), 0x04371000 },
- { _MMIO(0x9888), 0x0e538000 },
- { _MMIO(0x9888), 0x00538000 },
- { _MMIO(0x9888), 0x06533000 },
- { _MMIO(0x9888), 0x1c540020 },
- { _MMIO(0x9888), 0x12548000 },
- { _MMIO(0x9888), 0x0e557000 },
- { _MMIO(0x9888), 0x00557800 },
- { _MMIO(0x9888), 0x10550000 },
- { _MMIO(0x9888), 0x06560043 },
- { _MMIO(0x9888), 0x02560000 },
- { _MMIO(0x9888), 0x06571000 },
- { _MMIO(0x9888), 0x1190ff80 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900060 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900060 },
-};
-
-static int
-get_sampler_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_sampler;
- lens[n] = ARRAY_SIZE(mux_config_sampler);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x00007fff },
- { _MMIO(0x2778), 0x00000000 },
- { _MMIO(0x277c), 0x00009fff },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000efff },
- { _MMIO(0x2788), 0x00000000 },
- { _MMIO(0x278c), 0x0000f3ff },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000fdff },
- { _MMIO(0x2798), 0x00000000 },
- { _MMIO(0x279c), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_1[] = {
- { _MMIO(0x9888), 0x12120000 },
- { _MMIO(0x9888), 0x12320000 },
- { _MMIO(0x9888), 0x12520000 },
- { _MMIO(0x9888), 0x002f8000 },
- { _MMIO(0x9888), 0x022f3000 },
- { _MMIO(0x9888), 0x0a4c0015 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f03a0 },
- { _MMIO(0x9888), 0x0c0ff000 },
- { _MMIO(0x9888), 0x0e0f0095 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2d8000 },
- { _MMIO(0x9888), 0x0e2d4000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x02108000 },
- { _MMIO(0x9888), 0x0410c000 },
- { _MMIO(0x9888), 0x02118000 },
- { _MMIO(0x9888), 0x0411c000 },
- { _MMIO(0x9888), 0x02121880 },
- { _MMIO(0x9888), 0x041219b5 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x02134000 },
- { _MMIO(0x9888), 0x04135000 },
- { _MMIO(0x9888), 0x0c308000 },
- { _MMIO(0x9888), 0x0e304000 },
- { _MMIO(0x9888), 0x06304000 },
- { _MMIO(0x9888), 0x0c318000 },
- { _MMIO(0x9888), 0x0e314000 },
- { _MMIO(0x9888), 0x06314000 },
- { _MMIO(0x9888), 0x0c321a80 },
- { _MMIO(0x9888), 0x0e320033 },
- { _MMIO(0x9888), 0x06320031 },
- { _MMIO(0x9888), 0x00320000 },
- { _MMIO(0x9888), 0x0c334000 },
- { _MMIO(0x9888), 0x0e331000 },
- { _MMIO(0x9888), 0x06331000 },
- { _MMIO(0x9888), 0x0e508000 },
- { _MMIO(0x9888), 0x00508000 },
- { _MMIO(0x9888), 0x02504000 },
- { _MMIO(0x9888), 0x0e518000 },
- { _MMIO(0x9888), 0x00518000 },
- { _MMIO(0x9888), 0x02514000 },
- { _MMIO(0x9888), 0x0e521880 },
- { _MMIO(0x9888), 0x00521a80 },
- { _MMIO(0x9888), 0x02520033 },
- { _MMIO(0x9888), 0x0e534000 },
- { _MMIO(0x9888), 0x00534000 },
- { _MMIO(0x9888), 0x02531000 },
- { _MMIO(0x9888), 0x1190ff80 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900062 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
-};
-
-static int
-get_tdl_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_1;
- lens[n] = ARRAY_SIZE(mux_config_tdl_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_2[] = {
- { _MMIO(0x9888), 0x12124d60 },
- { _MMIO(0x9888), 0x12322e60 },
- { _MMIO(0x9888), 0x12524d60 },
- { _MMIO(0x9888), 0x022f3000 },
- { _MMIO(0x9888), 0x0a4c0014 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0fe000 },
- { _MMIO(0x9888), 0x0e0f0097 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x002d8000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x0410c000 },
- { _MMIO(0x9888), 0x0411c000 },
- { _MMIO(0x9888), 0x04121fb7 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x04135000 },
- { _MMIO(0x9888), 0x00308000 },
- { _MMIO(0x9888), 0x06304000 },
- { _MMIO(0x9888), 0x00318000 },
- { _MMIO(0x9888), 0x06314000 },
- { _MMIO(0x9888), 0x00321b80 },
- { _MMIO(0x9888), 0x0632003f },
- { _MMIO(0x9888), 0x00334000 },
- { _MMIO(0x9888), 0x06331000 },
- { _MMIO(0x9888), 0x0250c000 },
- { _MMIO(0x9888), 0x0251c000 },
- { _MMIO(0x9888), 0x02521fb7 },
- { _MMIO(0x9888), 0x00520000 },
- { _MMIO(0x9888), 0x02535000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x43900063 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_tdl_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_2;
- lens[n] = ARRAY_SIZE(mux_config_tdl_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extra[] = {
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extra[] = {
-};
-
-static const struct i915_oa_reg mux_config_compute_extra[] = {
- { _MMIO(0x9888), 0x121203e0 },
- { _MMIO(0x9888), 0x123203e0 },
- { _MMIO(0x9888), 0x125203e0 },
- { _MMIO(0x9888), 0x129203e0 },
- { _MMIO(0x9888), 0x12b203e0 },
- { _MMIO(0x9888), 0x12d203e0 },
- { _MMIO(0x9888), 0x024ec000 },
- { _MMIO(0x9888), 0x044ec000 },
- { _MMIO(0x9888), 0x064ec000 },
- { _MMIO(0x9888), 0x022f4000 },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x0a4c0042 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f006d },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x042d8000 },
- { _MMIO(0x9888), 0x06104000 },
- { _MMIO(0x9888), 0x06114000 },
- { _MMIO(0x9888), 0x06120033 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x06131000 },
- { _MMIO(0x9888), 0x04308000 },
- { _MMIO(0x9888), 0x04318000 },
- { _MMIO(0x9888), 0x04321980 },
- { _MMIO(0x9888), 0x00320000 },
- { _MMIO(0x9888), 0x04334000 },
- { _MMIO(0x9888), 0x04504000 },
- { _MMIO(0x9888), 0x04514000 },
- { _MMIO(0x9888), 0x04520033 },
- { _MMIO(0x9888), 0x00520000 },
- { _MMIO(0x9888), 0x04531000 },
- { _MMIO(0x9888), 0x00af8000 },
- { _MMIO(0x9888), 0x0acc0001 },
- { _MMIO(0x9888), 0x008d8000 },
- { _MMIO(0x9888), 0x028da000 },
- { _MMIO(0x9888), 0x0c8fb000 },
- { _MMIO(0x9888), 0x0e8f0001 },
- { _MMIO(0x9888), 0x06ac8000 },
- { _MMIO(0x9888), 0x02ad4000 },
- { _MMIO(0x9888), 0x02908000 },
- { _MMIO(0x9888), 0x02918000 },
- { _MMIO(0x9888), 0x02921980 },
- { _MMIO(0x9888), 0x00920000 },
- { _MMIO(0x9888), 0x02934000 },
- { _MMIO(0x9888), 0x02b04000 },
- { _MMIO(0x9888), 0x02b14000 },
- { _MMIO(0x9888), 0x02b20033 },
- { _MMIO(0x9888), 0x00b20000 },
- { _MMIO(0x9888), 0x02b31000 },
- { _MMIO(0x9888), 0x00d08000 },
- { _MMIO(0x9888), 0x00d18000 },
- { _MMIO(0x9888), 0x00d21980 },
- { _MMIO(0x9888), 0x00d34000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x43900002 },
- { _MMIO(0x9888), 0x53900420 },
- { _MMIO(0x9888), 0x459000a1 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_compute_extra_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extra;
- lens[n] = ARRAY_SIZE(mux_config_compute_extra);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_vme_pipe[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00100030 },
- { _MMIO(0x2774), 0x0000fff9 },
- { _MMIO(0x2778), 0x00000002 },
- { _MMIO(0x277c), 0x0000fffc },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000fff3 },
- { _MMIO(0x2788), 0x00100180 },
- { _MMIO(0x278c), 0x0000ffcf },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000ffcf },
- { _MMIO(0x2798), 0x00000002 },
- { _MMIO(0x279c), 0x0000ff3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_vme_pipe[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00008003 },
-};
-
-static const struct i915_oa_reg mux_config_vme_pipe[] = {
- { _MMIO(0x9888), 0x141a5800 },
- { _MMIO(0x9888), 0x161a00c0 },
- { _MMIO(0x9888), 0x12180240 },
- { _MMIO(0x9888), 0x14180002 },
- { _MMIO(0x9888), 0x149a5800 },
- { _MMIO(0x9888), 0x169a00c0 },
- { _MMIO(0x9888), 0x12980240 },
- { _MMIO(0x9888), 0x14980002 },
- { _MMIO(0x9888), 0x1a4e3fc0 },
- { _MMIO(0x9888), 0x002f1000 },
- { _MMIO(0x9888), 0x022f8000 },
- { _MMIO(0x9888), 0x042f3000 },
- { _MMIO(0x9888), 0x004c4000 },
- { _MMIO(0x9888), 0x0a4c9500 },
- { _MMIO(0x9888), 0x0c4c002a },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f5500 },
- { _MMIO(0x9888), 0x100f0015 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162caa00 },
- { _MMIO(0x9888), 0x182c000a },
- { _MMIO(0x9888), 0x04193000 },
- { _MMIO(0x9888), 0x081a28c1 },
- { _MMIO(0x9888), 0x001a0000 },
- { _MMIO(0x9888), 0x00133000 },
- { _MMIO(0x9888), 0x0613c000 },
- { _MMIO(0x9888), 0x0813f000 },
- { _MMIO(0x9888), 0x00172000 },
- { _MMIO(0x9888), 0x06178000 },
- { _MMIO(0x9888), 0x0817a000 },
- { _MMIO(0x9888), 0x00180037 },
- { _MMIO(0x9888), 0x06180940 },
- { _MMIO(0x9888), 0x08180000 },
- { _MMIO(0x9888), 0x02180000 },
- { _MMIO(0x9888), 0x04183000 },
- { _MMIO(0x9888), 0x04afc000 },
- { _MMIO(0x9888), 0x06af3000 },
- { _MMIO(0x9888), 0x0acc4000 },
- { _MMIO(0x9888), 0x0ccc0015 },
- { _MMIO(0x9888), 0x0a8da000 },
- { _MMIO(0x9888), 0x0c8da000 },
- { _MMIO(0x9888), 0x0e8f4000 },
- { _MMIO(0x9888), 0x108f0015 },
- { _MMIO(0x9888), 0x16aca000 },
- { _MMIO(0x9888), 0x18ac000a },
- { _MMIO(0x9888), 0x06993000 },
- { _MMIO(0x9888), 0x0c9a28c1 },
- { _MMIO(0x9888), 0x009a0000 },
- { _MMIO(0x9888), 0x0a93f000 },
- { _MMIO(0x9888), 0x0c93f000 },
- { _MMIO(0x9888), 0x0a97a000 },
- { _MMIO(0x9888), 0x0c97a000 },
- { _MMIO(0x9888), 0x0a980977 },
- { _MMIO(0x9888), 0x08980000 },
- { _MMIO(0x9888), 0x04980000 },
- { _MMIO(0x9888), 0x06983000 },
- { _MMIO(0x9888), 0x119000ff },
- { _MMIO(0x9888), 0x51900040 },
- { _MMIO(0x9888), 0x41900020 },
- { _MMIO(0x9888), 0x55900004 },
- { _MMIO(0x9888), 0x45900400 },
- { _MMIO(0x9888), 0x479008a5 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900002 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_vme_pipe_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_vme_pipe;
- lens[n] = ARRAY_SIZE(mux_config_vme_pipe);
- n++;
-
- return n;
-}
-
static const struct i915_oa_reg b_counter_config_test_oa[] = {
{ _MMIO(0x2740), 0x00000000 },
{ _MMIO(0x2744), 0x00800000 },
@@ -1931,6 +60,7 @@ static const struct i915_oa_reg flex_eu_config_test_oa[] = {
};
static const struct i915_oa_reg mux_config_test_oa[] = {
+ { _MMIO(0x9840), 0x00000080 },
{ _MMIO(0x9888), 0x11810000 },
{ _MMIO(0x9888), 0x07810013 },
{ _MMIO(0x9888), 0x1f810000 },
@@ -1945,1096 +75,35 @@ static const struct i915_oa_reg mux_config_test_oa[] = {
{ _MMIO(0x9888), 0x33900000 },
};
-static int
-get_test_oa_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_test_oa;
- lens[n] = ARRAY_SIZE(mux_config_test_oa);
- n++;
-
- return n;
-}
-
-int i915_oa_select_metric_set_kblgt3(struct drm_i915_private *dev_priv)
-{
- dev_priv->perf.oa.n_mux_configs = 0;
- dev_priv->perf.oa.b_counter_regs = NULL;
- dev_priv->perf.oa.b_counter_regs_len = 0;
- dev_priv->perf.oa.flex_regs = NULL;
- dev_priv->perf.oa.flex_regs_len = 0;
-
- switch (dev_priv->perf.oa.metrics_set) {
- case METRIC_SET_ID_RENDER_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_render_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_basic);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_basic);
-
- return 0;
- case METRIC_SET_ID_RENDER_PIPE_PROFILE:
- dev_priv->perf.oa.n_mux_configs =
- get_render_pipe_profile_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_pipe_profile;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_pipe_profile);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_pipe_profile;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_pipe_profile);
-
- return 0;
- case METRIC_SET_ID_MEMORY_READS:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_reads_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_reads;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_reads);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_reads;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_reads);
-
- return 0;
- case METRIC_SET_ID_MEMORY_WRITES:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_writes_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_writes;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_writes);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_writes;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_writes);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTENDED:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extended_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extended;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extended);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extended;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extended);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_L3_CACHE:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_l3_cache_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_L3_CACHE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_l3_cache;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_l3_cache);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_l3_cache;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_l3_cache);
-
- return 0;
- case METRIC_SET_ID_HDC_AND_SF:
- dev_priv->perf.oa.n_mux_configs =
- get_hdc_and_sf_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_hdc_and_sf;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_hdc_and_sf);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_hdc_and_sf;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_hdc_and_sf);
-
- return 0;
- case METRIC_SET_ID_L3_1:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_1);
-
- return 0;
- case METRIC_SET_ID_L3_2:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_2);
-
- return 0;
- case METRIC_SET_ID_L3_3:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_3_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_3\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_3;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_3);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_3;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_3);
-
- return 0;
- case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND:
- dev_priv->perf.oa.n_mux_configs =
- get_rasterizer_and_pixel_backend_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend);
-
- return 0;
- case METRIC_SET_ID_SAMPLER:
- dev_priv->perf.oa.n_mux_configs =
- get_sampler_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_sampler;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_sampler);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_sampler;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_sampler);
-
- return 0;
- case METRIC_SET_ID_TDL_1:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_1);
-
- return 0;
- case METRIC_SET_ID_TDL_2:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_2);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTRA:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extra_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTRA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extra;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extra);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extra;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extra);
-
- return 0;
- case METRIC_SET_ID_VME_PIPE:
- dev_priv->perf.oa.n_mux_configs =
- get_vme_pipe_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"VME_PIPE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_vme_pipe;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_vme_pipe);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_vme_pipe;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_vme_pipe);
-
- return 0;
- case METRIC_SET_ID_TEST_OA:
- dev_priv->perf.oa.n_mux_configs =
- get_test_oa_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_test_oa;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_test_oa);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_test_oa;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_test_oa);
-
- return 0;
- default:
- return -ENODEV;
- }
-}
-
-static ssize_t
-show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC);
-}
-
-static struct device_attribute dev_attr_render_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_basic[] = {
- &dev_attr_render_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_basic = {
- .name = "0286c920-2f6d-493b-b22d-7a5280df43de",
- .attrs = attrs_render_basic,
-};
-
-static ssize_t
-show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC);
-}
-
-static struct device_attribute dev_attr_compute_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_basic[] = {
- &dev_attr_compute_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_basic = {
- .name = "9823aaa1-b06f-40ce-884b-cd798c79f0c2",
- .attrs = attrs_compute_basic,
-};
-
-static ssize_t
-show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE);
-}
-
-static struct device_attribute dev_attr_render_pipe_profile_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_pipe_profile_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_pipe_profile[] = {
- &dev_attr_render_pipe_profile_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_pipe_profile = {
- .name = "c7c735f3-ce58-45cf-aa04-30b183f1faff",
- .attrs = attrs_render_pipe_profile,
-};
-
-static ssize_t
-show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS);
-}
-
-static struct device_attribute dev_attr_memory_reads_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_reads_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_reads[] = {
- &dev_attr_memory_reads_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_reads = {
- .name = "96ec2219-040b-428a-856a-6bc03363a057",
- .attrs = attrs_memory_reads,
-};
-
-static ssize_t
-show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES);
-}
-
-static struct device_attribute dev_attr_memory_writes_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_writes_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_writes[] = {
- &dev_attr_memory_writes_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_writes = {
- .name = "03372b64-4996-4d3b-aa18-790e75eeb9c2",
- .attrs = attrs_memory_writes,
-};
-
-static ssize_t
-show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED);
-}
-
-static struct device_attribute dev_attr_compute_extended_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extended_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extended[] = {
- &dev_attr_compute_extended_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extended = {
- .name = "31b4ce5a-bd61-4c1f-bb5d-f2e731412150",
- .attrs = attrs_compute_extended,
-};
-
-static ssize_t
-show_compute_l3_cache_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_L3_CACHE);
-}
-
-static struct device_attribute dev_attr_compute_l3_cache_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_l3_cache_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_l3_cache[] = {
- &dev_attr_compute_l3_cache_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_l3_cache = {
- .name = "2ce0911a-27fc-4887-96f0-11084fa807c3",
- .attrs = attrs_compute_l3_cache,
-};
-
-static ssize_t
-show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF);
-}
-
-static struct device_attribute dev_attr_hdc_and_sf_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_hdc_and_sf_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_hdc_and_sf[] = {
- &dev_attr_hdc_and_sf_id.attr,
- NULL,
-};
-
-static struct attribute_group group_hdc_and_sf = {
- .name = "546c4c1d-99b8-42fb-a107-5aaabb5314a8",
- .attrs = attrs_hdc_and_sf,
-};
-
-static ssize_t
-show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1);
-}
-
-static struct device_attribute dev_attr_l3_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_1[] = {
- &dev_attr_l3_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_1 = {
- .name = "4e93d156-9b39-4268-8544-a8e0480806d7",
- .attrs = attrs_l3_1,
-};
-
-static ssize_t
-show_l3_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_2);
-}
-
-static struct device_attribute dev_attr_l3_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_2[] = {
- &dev_attr_l3_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_2 = {
- .name = "de1bec86-ca92-4b43-89fa-147653221cc0",
- .attrs = attrs_l3_2,
-};
-
-static ssize_t
-show_l3_3_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_3);
-}
-
-static struct device_attribute dev_attr_l3_3_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_3_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_3[] = {
- &dev_attr_l3_3_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_3 = {
- .name = "e63537bb-10be-4d4a-92c4-c6b0c65e02ef",
- .attrs = attrs_l3_3,
-};
-
-static ssize_t
-show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND);
-}
-
-static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_rasterizer_and_pixel_backend_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_rasterizer_and_pixel_backend[] = {
- &dev_attr_rasterizer_and_pixel_backend_id.attr,
- NULL,
-};
-
-static struct attribute_group group_rasterizer_and_pixel_backend = {
- .name = "7a03a9f8-ec5e-46bb-8b67-1f0ff1476281",
- .attrs = attrs_rasterizer_and_pixel_backend,
-};
-
-static ssize_t
-show_sampler_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER);
-}
-
-static struct device_attribute dev_attr_sampler_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_sampler_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_sampler[] = {
- &dev_attr_sampler_id.attr,
- NULL,
-};
-
-static struct attribute_group group_sampler = {
- .name = "b25d2ebf-a6e0-4b29-96be-a9b010edeeda",
- .attrs = attrs_sampler,
-};
-
-static ssize_t
-show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1);
-}
-
-static struct device_attribute dev_attr_tdl_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_1[] = {
- &dev_attr_tdl_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_1 = {
- .name = "469a05e5-e299-46f7-9598-7b05f3c34991",
- .attrs = attrs_tdl_1,
-};
-
-static ssize_t
-show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2);
-}
-
-static struct device_attribute dev_attr_tdl_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_2[] = {
- &dev_attr_tdl_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_2 = {
- .name = "52f925c6-786a-4ec6-86ce-cba85c83453a",
- .attrs = attrs_tdl_2,
-};
-
-static ssize_t
-show_compute_extra_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTRA);
-}
-
-static struct device_attribute dev_attr_compute_extra_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extra_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extra[] = {
- &dev_attr_compute_extra_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extra = {
- .name = "efc497ac-884e-4ee4-a4a8-15fba22aaf21",
- .attrs = attrs_compute_extra,
-};
-
-static ssize_t
-show_vme_pipe_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_VME_PIPE);
-}
-
-static struct device_attribute dev_attr_vme_pipe_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_vme_pipe_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_vme_pipe[] = {
- &dev_attr_vme_pipe_id.attr,
- NULL,
-};
-
-static struct attribute_group group_vme_pipe = {
- .name = "bfd9764d-2c5b-4c16-bfc1-89de3ca10917",
- .attrs = attrs_vme_pipe,
-};
-
static ssize_t
show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA);
+ return sprintf(buf, "1\n");
}
-static struct device_attribute dev_attr_test_oa_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_test_oa_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_test_oa[] = {
- &dev_attr_test_oa_id.attr,
- NULL,
-};
-
-static struct attribute_group group_test_oa = {
- .name = "f1792f32-6db2-4b50-b4b2-557128f1688d",
- .attrs = attrs_test_oa,
-};
-
-int
-i915_perf_register_sysfs_kblgt3(struct drm_i915_private *dev_priv)
+void
+i915_perf_load_test_config_kblgt3(struct drm_i915_private *dev_priv)
{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
- int ret = 0;
+ strncpy(dev_priv->perf.oa.test_config.uuid,
+ "f1792f32-6db2-4b50-b4b2-557128f1688d",
+ UUID_STRING_LEN);
+ dev_priv->perf.oa.test_config.id = 1;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (ret)
- goto error_render_basic;
- }
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (ret)
- goto error_compute_basic;
- }
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (ret)
- goto error_render_pipe_profile;
- }
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (ret)
- goto error_memory_reads;
- }
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (ret)
- goto error_memory_writes;
- }
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (ret)
- goto error_compute_extended;
- }
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (ret)
- goto error_compute_l3_cache;
- }
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (ret)
- goto error_hdc_and_sf;
- }
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (ret)
- goto error_l3_1;
- }
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (ret)
- goto error_l3_2;
- }
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (ret)
- goto error_l3_3;
- }
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (ret)
- goto error_rasterizer_and_pixel_backend;
- }
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (ret)
- goto error_sampler;
- }
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (ret)
- goto error_tdl_1;
- }
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (ret)
- goto error_tdl_2;
- }
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (ret)
- goto error_compute_extra;
- }
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
- if (ret)
- goto error_vme_pipe;
- }
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa);
- if (ret)
- goto error_test_oa;
- }
+ dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
+ dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
- return 0;
+ dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
+ dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-error_test_oa:
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
-error_vme_pipe:
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
-error_compute_extra:
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
-error_tdl_2:
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
-error_tdl_1:
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
-error_sampler:
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
-error_rasterizer_and_pixel_backend:
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
-error_l3_3:
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
-error_l3_2:
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
-error_l3_1:
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
-error_hdc_and_sf:
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
-error_compute_l3_cache:
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
-error_compute_extended:
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
-error_memory_writes:
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
-error_memory_reads:
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
-error_render_pipe_profile:
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
-error_compute_basic:
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
-error_render_basic:
- return ret;
-}
+ dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
+ dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-void
-i915_perf_unregister_sysfs_kblgt3(struct drm_i915_private *dev_priv)
-{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
+ dev_priv->perf.oa.test_config.sysfs_metric.name = "f1792f32-6db2-4b50-b4b2-557128f1688d";
+ dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+
+ dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa);
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
+ dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
}
diff --git a/drivers/gpu/drm/i915/i915_oa_kblgt3.h b/drivers/gpu/drm/i915/i915_oa_kblgt3.h
index b0ca7f3..d5b5b5c 100644
--- a/drivers/gpu/drm/i915/i915_oa_kblgt3.h
+++ b/drivers/gpu/drm/i915/i915_oa_kblgt3.h
@@ -29,12 +29,6 @@
#ifndef __I915_OA_KBLGT3_H__
#define __I915_OA_KBLGT3_H__
-extern int i915_oa_n_builtin_metric_sets_kblgt3;
-
-extern int i915_oa_select_metric_set_kblgt3(struct drm_i915_private *dev_priv);
-
-extern int i915_perf_register_sysfs_kblgt3(struct drm_i915_private *dev_priv);
-
-extern void i915_perf_unregister_sysfs_kblgt3(struct drm_i915_private *dev_priv);
+extern void i915_perf_load_test_config_kblgt3(struct drm_i915_private *dev_priv);
#endif
diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt2.c b/drivers/gpu/drm/i915/i915_oa_sklgt2.c
index 1268bed..890d558 100644
--- a/drivers/gpu/drm/i915/i915_oa_sklgt2.c
+++ b/drivers/gpu/drm/i915/i915_oa_sklgt2.c
@@ -31,2317 +31,6 @@
#include "i915_drv.h"
#include "i915_oa_sklgt2.h"
-enum metric_set_id {
- METRIC_SET_ID_RENDER_BASIC = 1,
- METRIC_SET_ID_COMPUTE_BASIC,
- METRIC_SET_ID_RENDER_PIPE_PROFILE,
- METRIC_SET_ID_MEMORY_READS,
- METRIC_SET_ID_MEMORY_WRITES,
- METRIC_SET_ID_COMPUTE_EXTENDED,
- METRIC_SET_ID_COMPUTE_L3_CACHE,
- METRIC_SET_ID_HDC_AND_SF,
- METRIC_SET_ID_L3_1,
- METRIC_SET_ID_L3_2,
- METRIC_SET_ID_L3_3,
- METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND,
- METRIC_SET_ID_SAMPLER,
- METRIC_SET_ID_TDL_1,
- METRIC_SET_ID_TDL_2,
- METRIC_SET_ID_COMPUTE_EXTRA,
- METRIC_SET_ID_VME_PIPE,
- METRIC_SET_ID_TEST_OA,
-};
-
-int i915_oa_n_builtin_metric_sets_sklgt2 = 18;
-
-static const struct i915_oa_reg b_counter_config_render_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_render_basic_1_sku_gte_0x02[] = {
- { _MMIO(0x9888), 0x166c01e0 },
- { _MMIO(0x9888), 0x12170280 },
- { _MMIO(0x9888), 0x12370280 },
- { _MMIO(0x9888), 0x11930317 },
- { _MMIO(0x9888), 0x159303df },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x1a4e0080 },
- { _MMIO(0x9888), 0x0a6c0053 },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x0a1b4000 },
- { _MMIO(0x9888), 0x1c1c0001 },
- { _MMIO(0x9888), 0x002f1000 },
- { _MMIO(0x9888), 0x042f1000 },
- { _MMIO(0x9888), 0x004c4000 },
- { _MMIO(0x9888), 0x0a4c8400 },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0d2000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f6600 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x162c2200 },
- { _MMIO(0x9888), 0x062d8000 },
- { _MMIO(0x9888), 0x082d8000 },
- { _MMIO(0x9888), 0x00133000 },
- { _MMIO(0x9888), 0x08133000 },
- { _MMIO(0x9888), 0x00170020 },
- { _MMIO(0x9888), 0x08170021 },
- { _MMIO(0x9888), 0x10170000 },
- { _MMIO(0x9888), 0x0633c000 },
- { _MMIO(0x9888), 0x0833c000 },
- { _MMIO(0x9888), 0x06370800 },
- { _MMIO(0x9888), 0x08370840 },
- { _MMIO(0x9888), 0x10370000 },
- { _MMIO(0x9888), 0x0d933031 },
- { _MMIO(0x9888), 0x0f933e3f },
- { _MMIO(0x9888), 0x01933d00 },
- { _MMIO(0x9888), 0x0393073c },
- { _MMIO(0x9888), 0x0593000e },
- { _MMIO(0x9888), 0x1d930000 },
- { _MMIO(0x9888), 0x19930000 },
- { _MMIO(0x9888), 0x1b930000 },
- { _MMIO(0x9888), 0x1d900157 },
- { _MMIO(0x9888), 0x1f900158 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x2b908000 },
- { _MMIO(0x9888), 0x2d908000 },
- { _MMIO(0x9888), 0x2f908000 },
- { _MMIO(0x9888), 0x31908000 },
- { _MMIO(0x9888), 0x15908000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1190001f },
- { _MMIO(0x9888), 0x51904400 },
- { _MMIO(0x9888), 0x41900020 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900c21 },
- { _MMIO(0x9888), 0x47900061 },
- { _MMIO(0x9888), 0x57904440 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x59900004 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x53904444 },
-};
-
-static int
-get_render_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- if (dev_priv->drm.pdev->revision >= 0x02) {
- regs[n] = mux_config_render_basic_1_sku_gte_0x02;
- lens[n] = ARRAY_SIZE(mux_config_render_basic_1_sku_gte_0x02);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_basic_0_slices_0x01_and_sku_lt_0x02[] = {
- { _MMIO(0x9888), 0x104f00e0 },
- { _MMIO(0x9888), 0x124f1c00 },
- { _MMIO(0x9888), 0x106c00e0 },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f901403 },
- { _MMIO(0x9888), 0x184e8000 },
- { _MMIO(0x9888), 0x1a4e8200 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x004f0db2 },
- { _MMIO(0x9888), 0x064f0900 },
- { _MMIO(0x9888), 0x084f1880 },
- { _MMIO(0x9888), 0x0a4f0011 },
- { _MMIO(0x9888), 0x0c4f0e3c },
- { _MMIO(0x9888), 0x0e4f1d80 },
- { _MMIO(0x9888), 0x086c0002 },
- { _MMIO(0x9888), 0x0a6c0100 },
- { _MMIO(0x9888), 0x0e6c000c },
- { _MMIO(0x9888), 0x026c000b },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x081b4000 },
- { _MMIO(0x9888), 0x0a1b8000 },
- { _MMIO(0x9888), 0x0e1b4000 },
- { _MMIO(0x9888), 0x021b4000 },
- { _MMIO(0x9888), 0x1a1c4000 },
- { _MMIO(0x9888), 0x1c1c0012 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x005bc000 },
- { _MMIO(0x9888), 0x065b8000 },
- { _MMIO(0x9888), 0x085b8000 },
- { _MMIO(0x9888), 0x0a5b4000 },
- { _MMIO(0x9888), 0x0c5bc000 },
- { _MMIO(0x9888), 0x0e5b8000 },
- { _MMIO(0x9888), 0x105c8000 },
- { _MMIO(0x9888), 0x1a5ca000 },
- { _MMIO(0x9888), 0x1c5c002d },
- { _MMIO(0x9888), 0x125c8000 },
- { _MMIO(0x9888), 0x0a4c0800 },
- { _MMIO(0x9888), 0x0c4c0082 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x000da000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x020d2000 },
- { _MMIO(0x9888), 0x0c0f5400 },
- { _MMIO(0x9888), 0x0e0f5500 },
- { _MMIO(0x9888), 0x100f0155 },
- { _MMIO(0x9888), 0x002cc000 },
- { _MMIO(0x9888), 0x0e2cc000 },
- { _MMIO(0x9888), 0x162cbe00 },
- { _MMIO(0x9888), 0x182c00ef },
- { _MMIO(0x9888), 0x022cc000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x19900157 },
- { _MMIO(0x9888), 0x1b900167 },
- { _MMIO(0x9888), 0x1d900105 },
- { _MMIO(0x9888), 0x1f900103 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0xd28), 0x00000000 },
- { _MMIO(0x9888), 0x11900fff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900840 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900842 },
- { _MMIO(0x9888), 0x47900840 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900840 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900040 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900840 },
- { _MMIO(0x9888), 0x53901111 },
-};
-
-static const struct i915_oa_reg mux_config_compute_basic_0_slices_0x01_and_sku_gte_0x02[] = {
- { _MMIO(0x9888), 0x104f00e0 },
- { _MMIO(0x9888), 0x124f1c00 },
- { _MMIO(0x9888), 0x106c00e0 },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f901403 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x1a4e0820 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x064f0900 },
- { _MMIO(0x9888), 0x084f0032 },
- { _MMIO(0x9888), 0x0a4f1810 },
- { _MMIO(0x9888), 0x0c4f0e00 },
- { _MMIO(0x9888), 0x0e4f003c },
- { _MMIO(0x9888), 0x004f0d80 },
- { _MMIO(0x9888), 0x024f003b },
- { _MMIO(0x9888), 0x006c0002 },
- { _MMIO(0x9888), 0x086c0000 },
- { _MMIO(0x9888), 0x0c6c000c },
- { _MMIO(0x9888), 0x0e6c0b00 },
- { _MMIO(0x9888), 0x186c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x001b4000 },
- { _MMIO(0x9888), 0x081b8000 },
- { _MMIO(0x9888), 0x0c1b4000 },
- { _MMIO(0x9888), 0x0e1b8000 },
- { _MMIO(0x9888), 0x101c8000 },
- { _MMIO(0x9888), 0x1a1c8000 },
- { _MMIO(0x9888), 0x1c1c0024 },
- { _MMIO(0x9888), 0x065b8000 },
- { _MMIO(0x9888), 0x085b4000 },
- { _MMIO(0x9888), 0x0a5bc000 },
- { _MMIO(0x9888), 0x0c5b8000 },
- { _MMIO(0x9888), 0x0e5b4000 },
- { _MMIO(0x9888), 0x005b8000 },
- { _MMIO(0x9888), 0x025b4000 },
- { _MMIO(0x9888), 0x1a5c6000 },
- { _MMIO(0x9888), 0x1c5c001b },
- { _MMIO(0x9888), 0x125c8000 },
- { _MMIO(0x9888), 0x145c8000 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4c2000 },
- { _MMIO(0x9888), 0x0c4c0208 },
- { _MMIO(0x9888), 0x000da000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x020d2000 },
- { _MMIO(0x9888), 0x0c0f5400 },
- { _MMIO(0x9888), 0x0e0f5500 },
- { _MMIO(0x9888), 0x100f0155 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2cc000 },
- { _MMIO(0x9888), 0x162cfb00 },
- { _MMIO(0x9888), 0x182c00be },
- { _MMIO(0x9888), 0x022cc000 },
- { _MMIO(0x9888), 0x042cc000 },
- { _MMIO(0x9888), 0x19900157 },
- { _MMIO(0x9888), 0x1b900167 },
- { _MMIO(0x9888), 0x1d900105 },
- { _MMIO(0x9888), 0x1f900103 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x11900fff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900842 },
- { _MMIO(0x9888), 0x47900802 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900802 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900002 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53901111 },
-};
-
-static int
-get_compute_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 2);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 2);
-
- if ((INTEL_INFO(dev_priv)->sseu.slice_mask & 0x01) &&
- (dev_priv->drm.pdev->revision < 0x02)) {
- regs[n] = mux_config_compute_basic_0_slices_0x01_and_sku_lt_0x02;
- lens[n] = ARRAY_SIZE(mux_config_compute_basic_0_slices_0x01_and_sku_lt_0x02);
- n++;
- }
- if ((INTEL_INFO(dev_priv)->sseu.slice_mask & 0x01) &&
- (dev_priv->drm.pdev->revision >= 0x02)) {
- regs[n] = mux_config_compute_basic_0_slices_0x01_and_sku_gte_0x02;
- lens[n] = ARRAY_SIZE(mux_config_compute_basic_0_slices_0x01_and_sku_gte_0x02);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007ffea },
- { _MMIO(0x2774), 0x00007ffc },
- { _MMIO(0x2778), 0x0007affa },
- { _MMIO(0x277c), 0x0000f5fd },
- { _MMIO(0x2780), 0x00079ffa },
- { _MMIO(0x2784), 0x0000f3fb },
- { _MMIO(0x2788), 0x0007bf7a },
- { _MMIO(0x278c), 0x0000f7e7 },
- { _MMIO(0x2790), 0x0007fefa },
- { _MMIO(0x2794), 0x0000f7cf },
- { _MMIO(0x2798), 0x00077ffa },
- { _MMIO(0x279c), 0x0000efdf },
- { _MMIO(0x27a0), 0x0006fffa },
- { _MMIO(0x27a4), 0x0000cfbf },
- { _MMIO(0x27a8), 0x0003fffa },
- { _MMIO(0x27ac), 0x00005f7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_render_pipe_profile_0_sku_lt_0x02[] = {
- { _MMIO(0x9888), 0x0c0e001f },
- { _MMIO(0x9888), 0x0a0f0000 },
- { _MMIO(0x9888), 0x10116800 },
- { _MMIO(0x9888), 0x178a03e0 },
- { _MMIO(0x9888), 0x11824c00 },
- { _MMIO(0x9888), 0x11830020 },
- { _MMIO(0x9888), 0x13840020 },
- { _MMIO(0x9888), 0x11850019 },
- { _MMIO(0x9888), 0x11860007 },
- { _MMIO(0x9888), 0x01870c40 },
- { _MMIO(0x9888), 0x17880000 },
- { _MMIO(0x9888), 0x022f4000 },
- { _MMIO(0x9888), 0x0a4c0040 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x040d4000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x020e5400 },
- { _MMIO(0x9888), 0x000e0000 },
- { _MMIO(0x9888), 0x080f0040 },
- { _MMIO(0x9888), 0x000f0000 },
- { _MMIO(0x9888), 0x100f0000 },
- { _MMIO(0x9888), 0x0e0f0040 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x06104000 },
- { _MMIO(0x9888), 0x06110012 },
- { _MMIO(0x9888), 0x06131000 },
- { _MMIO(0x9888), 0x01898000 },
- { _MMIO(0x9888), 0x0d890100 },
- { _MMIO(0x9888), 0x03898000 },
- { _MMIO(0x9888), 0x09808000 },
- { _MMIO(0x9888), 0x0b808000 },
- { _MMIO(0x9888), 0x0380c000 },
- { _MMIO(0x9888), 0x0f8a0075 },
- { _MMIO(0x9888), 0x1d8a0000 },
- { _MMIO(0x9888), 0x118a8000 },
- { _MMIO(0x9888), 0x1b8a4000 },
- { _MMIO(0x9888), 0x138a8000 },
- { _MMIO(0x9888), 0x1d81a000 },
- { _MMIO(0x9888), 0x15818000 },
- { _MMIO(0x9888), 0x17818000 },
- { _MMIO(0x9888), 0x0b820030 },
- { _MMIO(0x9888), 0x07828000 },
- { _MMIO(0x9888), 0x0d824000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x05824000 },
- { _MMIO(0x9888), 0x0d830003 },
- { _MMIO(0x9888), 0x0583000c },
- { _MMIO(0x9888), 0x09830000 },
- { _MMIO(0x9888), 0x03838000 },
- { _MMIO(0x9888), 0x07838000 },
- { _MMIO(0x9888), 0x0b840980 },
- { _MMIO(0x9888), 0x03844d80 },
- { _MMIO(0x9888), 0x11840000 },
- { _MMIO(0x9888), 0x09848000 },
- { _MMIO(0x9888), 0x09850080 },
- { _MMIO(0x9888), 0x03850003 },
- { _MMIO(0x9888), 0x01850000 },
- { _MMIO(0x9888), 0x07860000 },
- { _MMIO(0x9888), 0x0f860400 },
- { _MMIO(0x9888), 0x09870032 },
- { _MMIO(0x9888), 0x01888052 },
- { _MMIO(0x9888), 0x11880000 },
- { _MMIO(0x9888), 0x09884000 },
- { _MMIO(0x9888), 0x15968000 },
- { _MMIO(0x9888), 0x17968000 },
- { _MMIO(0x9888), 0x0f96c000 },
- { _MMIO(0x9888), 0x1f950011 },
- { _MMIO(0x9888), 0x1d950014 },
- { _MMIO(0x9888), 0x0592c000 },
- { _MMIO(0x9888), 0x0b928000 },
- { _MMIO(0x9888), 0x0d924000 },
- { _MMIO(0x9888), 0x0f924000 },
- { _MMIO(0x9888), 0x11928000 },
- { _MMIO(0x9888), 0x1392c000 },
- { _MMIO(0x9888), 0x09924000 },
- { _MMIO(0x9888), 0x01985000 },
- { _MMIO(0x9888), 0x07988000 },
- { _MMIO(0x9888), 0x09981000 },
- { _MMIO(0x9888), 0x0b982000 },
- { _MMIO(0x9888), 0x0d982000 },
- { _MMIO(0x9888), 0x0f989000 },
- { _MMIO(0x9888), 0x05982000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x23904000 },
- { _MMIO(0x9888), 0x25908000 },
- { _MMIO(0x9888), 0x27904000 },
- { _MMIO(0x9888), 0x29908000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x0b978000 },
- { _MMIO(0x9888), 0x0f974000 },
- { _MMIO(0x9888), 0x11974000 },
- { _MMIO(0x9888), 0x13978000 },
- { _MMIO(0x9888), 0x09974000 },
- { _MMIO(0xd28), 0x00000000 },
- { _MMIO(0x9888), 0x1190c080 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x419010a0 },
- { _MMIO(0x9888), 0x55904000 },
- { _MMIO(0x9888), 0x45901000 },
- { _MMIO(0x9888), 0x47900084 },
- { _MMIO(0x9888), 0x57904400 },
- { _MMIO(0x9888), 0x499000a5 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900081 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x439014a4 },
- { _MMIO(0x9888), 0x53900400 },
-};
-
-static const struct i915_oa_reg mux_config_render_pipe_profile_0_sku_gte_0x02[] = {
- { _MMIO(0x9888), 0x0c0e001f },
- { _MMIO(0x9888), 0x0a0f0000 },
- { _MMIO(0x9888), 0x10116800 },
- { _MMIO(0x9888), 0x178a03e0 },
- { _MMIO(0x9888), 0x11824c00 },
- { _MMIO(0x9888), 0x11830020 },
- { _MMIO(0x9888), 0x13840020 },
- { _MMIO(0x9888), 0x11850019 },
- { _MMIO(0x9888), 0x11860007 },
- { _MMIO(0x9888), 0x01870c40 },
- { _MMIO(0x9888), 0x17880000 },
- { _MMIO(0x9888), 0x022f4000 },
- { _MMIO(0x9888), 0x0a4c0040 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x040d4000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x020e5400 },
- { _MMIO(0x9888), 0x000e0000 },
- { _MMIO(0x9888), 0x080f0040 },
- { _MMIO(0x9888), 0x000f0000 },
- { _MMIO(0x9888), 0x100f0000 },
- { _MMIO(0x9888), 0x0e0f0040 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x06104000 },
- { _MMIO(0x9888), 0x06110012 },
- { _MMIO(0x9888), 0x06131000 },
- { _MMIO(0x9888), 0x01898000 },
- { _MMIO(0x9888), 0x0d890100 },
- { _MMIO(0x9888), 0x03898000 },
- { _MMIO(0x9888), 0x09808000 },
- { _MMIO(0x9888), 0x0b808000 },
- { _MMIO(0x9888), 0x0380c000 },
- { _MMIO(0x9888), 0x0f8a0075 },
- { _MMIO(0x9888), 0x1d8a0000 },
- { _MMIO(0x9888), 0x118a8000 },
- { _MMIO(0x9888), 0x1b8a4000 },
- { _MMIO(0x9888), 0x138a8000 },
- { _MMIO(0x9888), 0x1d81a000 },
- { _MMIO(0x9888), 0x15818000 },
- { _MMIO(0x9888), 0x17818000 },
- { _MMIO(0x9888), 0x0b820030 },
- { _MMIO(0x9888), 0x07828000 },
- { _MMIO(0x9888), 0x0d824000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x05824000 },
- { _MMIO(0x9888), 0x0d830003 },
- { _MMIO(0x9888), 0x0583000c },
- { _MMIO(0x9888), 0x09830000 },
- { _MMIO(0x9888), 0x03838000 },
- { _MMIO(0x9888), 0x07838000 },
- { _MMIO(0x9888), 0x0b840980 },
- { _MMIO(0x9888), 0x03844d80 },
- { _MMIO(0x9888), 0x11840000 },
- { _MMIO(0x9888), 0x09848000 },
- { _MMIO(0x9888), 0x09850080 },
- { _MMIO(0x9888), 0x03850003 },
- { _MMIO(0x9888), 0x01850000 },
- { _MMIO(0x9888), 0x07860000 },
- { _MMIO(0x9888), 0x0f860400 },
- { _MMIO(0x9888), 0x09870032 },
- { _MMIO(0x9888), 0x01888052 },
- { _MMIO(0x9888), 0x11880000 },
- { _MMIO(0x9888), 0x09884000 },
- { _MMIO(0x9888), 0x1b931001 },
- { _MMIO(0x9888), 0x1d930001 },
- { _MMIO(0x9888), 0x19934000 },
- { _MMIO(0x9888), 0x1b958000 },
- { _MMIO(0x9888), 0x1d950094 },
- { _MMIO(0x9888), 0x19958000 },
- { _MMIO(0x9888), 0x05e5a000 },
- { _MMIO(0x9888), 0x01e5c000 },
- { _MMIO(0x9888), 0x0592c000 },
- { _MMIO(0x9888), 0x0b928000 },
- { _MMIO(0x9888), 0x0d924000 },
- { _MMIO(0x9888), 0x0f924000 },
- { _MMIO(0x9888), 0x11928000 },
- { _MMIO(0x9888), 0x1392c000 },
- { _MMIO(0x9888), 0x09924000 },
- { _MMIO(0x9888), 0x01985000 },
- { _MMIO(0x9888), 0x07988000 },
- { _MMIO(0x9888), 0x09981000 },
- { _MMIO(0x9888), 0x0b982000 },
- { _MMIO(0x9888), 0x0d982000 },
- { _MMIO(0x9888), 0x0f989000 },
- { _MMIO(0x9888), 0x05982000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x23904000 },
- { _MMIO(0x9888), 0x25908000 },
- { _MMIO(0x9888), 0x27904000 },
- { _MMIO(0x9888), 0x29908000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1190c080 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x419010a0 },
- { _MMIO(0x9888), 0x55904000 },
- { _MMIO(0x9888), 0x45901000 },
- { _MMIO(0x9888), 0x47900084 },
- { _MMIO(0x9888), 0x57904400 },
- { _MMIO(0x9888), 0x499000a5 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900081 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x439014a4 },
- { _MMIO(0x9888), 0x53900400 },
-};
-
-static int
-get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 2);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 2);
-
- if (dev_priv->drm.pdev->revision < 0x02) {
- regs[n] = mux_config_render_pipe_profile_0_sku_lt_0x02;
- lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile_0_sku_lt_0x02);
- n++;
- }
- if (dev_priv->drm.pdev->revision >= 0x02) {
- regs[n] = mux_config_render_pipe_profile_0_sku_gte_0x02;
- lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile_0_sku_gte_0x02);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_reads[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f872 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_reads[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_reads_0_slices_0x01_and_sku_lt_0x02[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x13946000 },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x0f968000 },
- { _MMIO(0x9888), 0x1196c000 },
- { _MMIO(0x9888), 0x13964000 },
- { _MMIO(0x9888), 0x11938000 },
- { _MMIO(0x9888), 0x1b93fe00 },
- { _MMIO(0x9888), 0x01940010 },
- { _MMIO(0x9888), 0x07941100 },
- { _MMIO(0x9888), 0x09941312 },
- { _MMIO(0x9888), 0x0b941514 },
- { _MMIO(0x9888), 0x0d941716 },
- { _MMIO(0x9888), 0x11940000 },
- { _MMIO(0x9888), 0x19940000 },
- { _MMIO(0x9888), 0x1b940000 },
- { _MMIO(0x9888), 0x1d940000 },
- { _MMIO(0x9888), 0x1b954000 },
- { _MMIO(0x9888), 0x1d95a550 },
- { _MMIO(0x9888), 0x1f9502aa },
- { _MMIO(0x9888), 0x2f900157 },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x13908000 },
- { _MMIO(0x9888), 0x21908000 },
- { _MMIO(0x9888), 0x23908000 },
- { _MMIO(0x9888), 0x25908000 },
- { _MMIO(0x9888), 0x27908000 },
- { _MMIO(0x9888), 0x29908000 },
- { _MMIO(0x9888), 0x2b908000 },
- { _MMIO(0x9888), 0x2d908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0xd28), 0x00000000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static const struct i915_oa_reg mux_config_memory_reads_0_sku_lt_0x05_and_sku_gte_0x02[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x13946000 },
- { _MMIO(0x9888), 0x15940016 },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x19930800 },
- { _MMIO(0x9888), 0x1b93aa55 },
- { _MMIO(0x9888), 0x1d9300aa },
- { _MMIO(0x9888), 0x01940010 },
- { _MMIO(0x9888), 0x07941100 },
- { _MMIO(0x9888), 0x09941312 },
- { _MMIO(0x9888), 0x0b941514 },
- { _MMIO(0x9888), 0x0d941716 },
- { _MMIO(0x9888), 0x0f940018 },
- { _MMIO(0x9888), 0x1b940000 },
- { _MMIO(0x9888), 0x11940000 },
- { _MMIO(0x9888), 0x01e58000 },
- { _MMIO(0x9888), 0x03e57000 },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x13908000 },
- { _MMIO(0x9888), 0x21908000 },
- { _MMIO(0x9888), 0x23908000 },
- { _MMIO(0x9888), 0x25908000 },
- { _MMIO(0x9888), 0x27908000 },
- { _MMIO(0x9888), 0x29908000 },
- { _MMIO(0x9888), 0x2b908000 },
- { _MMIO(0x9888), 0x2d908000 },
- { _MMIO(0x9888), 0x2f908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c20 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900400 },
- { _MMIO(0x9888), 0x47900421 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900421 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900061 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static const struct i915_oa_reg mux_config_memory_reads_0_sku_gte_0x05[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f900064 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x1b930055 },
- { _MMIO(0x9888), 0x03e58000 },
- { _MMIO(0x9888), 0x05e5c000 },
- { _MMIO(0x9888), 0x07e54000 },
- { _MMIO(0x9888), 0x13900150 },
- { _MMIO(0x9888), 0x21900151 },
- { _MMIO(0x9888), 0x23900152 },
- { _MMIO(0x9888), 0x25900153 },
- { _MMIO(0x9888), 0x27900154 },
- { _MMIO(0x9888), 0x29900155 },
- { _MMIO(0x9888), 0x2b900156 },
- { _MMIO(0x9888), 0x2d900157 },
- { _MMIO(0x9888), 0x2f90015f },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c60 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900c00 },
- { _MMIO(0x9888), 0x47900c63 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900c63 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_memory_reads_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 3);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 3);
-
- if ((INTEL_INFO(dev_priv)->sseu.slice_mask & 0x01) &&
- (dev_priv->drm.pdev->revision < 0x02)) {
- regs[n] = mux_config_memory_reads_0_slices_0x01_and_sku_lt_0x02;
- lens[n] = ARRAY_SIZE(mux_config_memory_reads_0_slices_0x01_and_sku_lt_0x02);
- n++;
- }
- if ((dev_priv->drm.pdev->revision < 0x05) &&
- (dev_priv->drm.pdev->revision >= 0x02)) {
- regs[n] = mux_config_memory_reads_0_sku_lt_0x05_and_sku_gte_0x02;
- lens[n] = ARRAY_SIZE(mux_config_memory_reads_0_sku_lt_0x05_and_sku_gte_0x02);
- n++;
- }
- if (dev_priv->drm.pdev->revision >= 0x05) {
- regs[n] = mux_config_memory_reads_0_sku_gte_0x05;
- lens[n] = ARRAY_SIZE(mux_config_memory_reads_0_sku_gte_0x05);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_writes[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f822 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_writes[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_writes_0_slices_0x01_and_sku_lt_0x02[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x13945400 },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f901400 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x0f968000 },
- { _MMIO(0x9888), 0x1196c000 },
- { _MMIO(0x9888), 0x13964000 },
- { _MMIO(0x9888), 0x11938000 },
- { _MMIO(0x9888), 0x1b93fe00 },
- { _MMIO(0x9888), 0x01940010 },
- { _MMIO(0x9888), 0x07941100 },
- { _MMIO(0x9888), 0x09941312 },
- { _MMIO(0x9888), 0x0b941514 },
- { _MMIO(0x9888), 0x0d941716 },
- { _MMIO(0x9888), 0x11940000 },
- { _MMIO(0x9888), 0x19940000 },
- { _MMIO(0x9888), 0x1b940000 },
- { _MMIO(0x9888), 0x1d940000 },
- { _MMIO(0x9888), 0x1b954000 },
- { _MMIO(0x9888), 0x1d95a550 },
- { _MMIO(0x9888), 0x1f9502aa },
- { _MMIO(0x9888), 0x2f900167 },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x13908000 },
- { _MMIO(0x9888), 0x21908000 },
- { _MMIO(0x9888), 0x23908000 },
- { _MMIO(0x9888), 0x25908000 },
- { _MMIO(0x9888), 0x27908000 },
- { _MMIO(0x9888), 0x29908000 },
- { _MMIO(0x9888), 0x2b908000 },
- { _MMIO(0x9888), 0x2d908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0xd28), 0x00000000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static const struct i915_oa_reg mux_config_memory_writes_0_sku_lt_0x05_and_sku_gte_0x02[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x13945400 },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f901400 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x19930800 },
- { _MMIO(0x9888), 0x1b93aa55 },
- { _MMIO(0x9888), 0x1d93002a },
- { _MMIO(0x9888), 0x01940010 },
- { _MMIO(0x9888), 0x07941100 },
- { _MMIO(0x9888), 0x09941312 },
- { _MMIO(0x9888), 0x0b941514 },
- { _MMIO(0x9888), 0x0d941716 },
- { _MMIO(0x9888), 0x1b940000 },
- { _MMIO(0x9888), 0x11940000 },
- { _MMIO(0x9888), 0x01e58000 },
- { _MMIO(0x9888), 0x03e57000 },
- { _MMIO(0x9888), 0x2f900167 },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x13908000 },
- { _MMIO(0x9888), 0x21908000 },
- { _MMIO(0x9888), 0x23908000 },
- { _MMIO(0x9888), 0x25908000 },
- { _MMIO(0x9888), 0x27908000 },
- { _MMIO(0x9888), 0x29908000 },
- { _MMIO(0x9888), 0x2b908000 },
- { _MMIO(0x9888), 0x2d908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c20 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900400 },
- { _MMIO(0x9888), 0x47900421 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900421 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static const struct i915_oa_reg mux_config_memory_writes_0_sku_gte_0x05[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f901000 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x1b930055 },
- { _MMIO(0x9888), 0x03e58000 },
- { _MMIO(0x9888), 0x05e5c000 },
- { _MMIO(0x9888), 0x07e54000 },
- { _MMIO(0x9888), 0x13900160 },
- { _MMIO(0x9888), 0x21900161 },
- { _MMIO(0x9888), 0x23900162 },
- { _MMIO(0x9888), 0x25900163 },
- { _MMIO(0x9888), 0x27900164 },
- { _MMIO(0x9888), 0x29900165 },
- { _MMIO(0x9888), 0x2b900166 },
- { _MMIO(0x9888), 0x2d900167 },
- { _MMIO(0x9888), 0x2f900150 },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c60 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900c00 },
- { _MMIO(0x9888), 0x47900c63 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900c63 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_memory_writes_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 3);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 3);
-
- if ((INTEL_INFO(dev_priv)->sseu.slice_mask & 0x01) &&
- (dev_priv->drm.pdev->revision < 0x02)) {
- regs[n] = mux_config_memory_writes_0_slices_0x01_and_sku_lt_0x02;
- lens[n] = ARRAY_SIZE(mux_config_memory_writes_0_slices_0x01_and_sku_lt_0x02);
- n++;
- }
- if ((dev_priv->drm.pdev->revision < 0x05) &&
- (dev_priv->drm.pdev->revision >= 0x02)) {
- regs[n] = mux_config_memory_writes_0_sku_lt_0x05_and_sku_gte_0x02;
- lens[n] = ARRAY_SIZE(mux_config_memory_writes_0_sku_lt_0x05_and_sku_gte_0x02);
- n++;
- }
- if (dev_priv->drm.pdev->revision >= 0x05) {
- regs[n] = mux_config_memory_writes_0_sku_gte_0x05;
- lens[n] = ARRAY_SIZE(mux_config_memory_writes_0_sku_gte_0x05);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extended[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fc2a },
- { _MMIO(0x2774), 0x0000bf00 },
- { _MMIO(0x2778), 0x0007fc6a },
- { _MMIO(0x277c), 0x0000bf00 },
- { _MMIO(0x2780), 0x0007fc92 },
- { _MMIO(0x2784), 0x0000bf00 },
- { _MMIO(0x2788), 0x0007fca2 },
- { _MMIO(0x278c), 0x0000bf00 },
- { _MMIO(0x2790), 0x0007fc32 },
- { _MMIO(0x2794), 0x0000bf00 },
- { _MMIO(0x2798), 0x0007fc9a },
- { _MMIO(0x279c), 0x0000bf00 },
- { _MMIO(0x27a0), 0x0007fe6a },
- { _MMIO(0x27a4), 0x0000bf00 },
- { _MMIO(0x27a8), 0x0007fe7a },
- { _MMIO(0x27ac), 0x0000bf00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extended[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended_0_subslices_0x01[] = {
- { _MMIO(0x9888), 0x106c00e0 },
- { _MMIO(0x9888), 0x141c8160 },
- { _MMIO(0x9888), 0x161c8015 },
- { _MMIO(0x9888), 0x181c0120 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x184e8000 },
- { _MMIO(0x9888), 0x1a4eaaa0 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x024e8000 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0e6c0b01 },
- { _MMIO(0x9888), 0x006c0200 },
- { _MMIO(0x9888), 0x026c000c },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x001b8000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x001c0041 },
- { _MMIO(0x9888), 0x061c4200 },
- { _MMIO(0x9888), 0x081c4443 },
- { _MMIO(0x9888), 0x0a1c4645 },
- { _MMIO(0x9888), 0x0c1c7647 },
- { _MMIO(0x9888), 0x041c7357 },
- { _MMIO(0x9888), 0x1c1c0030 },
- { _MMIO(0x9888), 0x101c0000 },
- { _MMIO(0x9888), 0x1a1c0000 },
- { _MMIO(0x9888), 0x121c8000 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4caa2a },
- { _MMIO(0x9888), 0x0c4c02aa },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x000da000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x0c0f5400 },
- { _MMIO(0x9888), 0x0e0f5515 },
- { _MMIO(0x9888), 0x100f0155 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162caa00 },
- { _MMIO(0x9888), 0x182c00aa },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0xd28), 0x00000000 },
- { _MMIO(0x9888), 0x11907fff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900040 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900802 },
- { _MMIO(0x9888), 0x47900842 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900842 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900800 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_compute_extended_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x01) {
- regs[n] = mux_config_compute_extended_0_subslices_0x01;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended_0_subslices_0x01);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_l3_cache[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fffa },
- { _MMIO(0x2774), 0x0000fefe },
- { _MMIO(0x2778), 0x0007fffa },
- { _MMIO(0x277c), 0x0000fefd },
- { _MMIO(0x2790), 0x0007fffa },
- { _MMIO(0x2794), 0x0000fbef },
- { _MMIO(0x2798), 0x0007fffa },
- { _MMIO(0x279c), 0x0000fbdf },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_l3_cache[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00101100 },
- { _MMIO(0xe45c), 0x00201200 },
- { _MMIO(0xe55c), 0x00301300 },
- { _MMIO(0xe65c), 0x00401400 },
-};
-
-static const struct i915_oa_reg mux_config_compute_l3_cache[] = {
- { _MMIO(0x9888), 0x166c0760 },
- { _MMIO(0x9888), 0x1593001e },
- { _MMIO(0x9888), 0x3f901403 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x184e8000 },
- { _MMIO(0x9888), 0x1a4e8020 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x006c0051 },
- { _MMIO(0x9888), 0x066c5000 },
- { _MMIO(0x9888), 0x086c5c5d },
- { _MMIO(0x9888), 0x0e6c5e5f },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x186c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x001b4000 },
- { _MMIO(0x9888), 0x061b8000 },
- { _MMIO(0x9888), 0x081bc000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x101c8000 },
- { _MMIO(0x9888), 0x1a1ce000 },
- { _MMIO(0x9888), 0x1c1c0030 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4c2a00 },
- { _MMIO(0x9888), 0x0c4c0280 },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f1500 },
- { _MMIO(0x9888), 0x100f0140 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162c0a00 },
- { _MMIO(0x9888), 0x182c00a0 },
- { _MMIO(0x9888), 0x03933300 },
- { _MMIO(0x9888), 0x05930032 },
- { _MMIO(0x9888), 0x11930000 },
- { _MMIO(0x9888), 0x1b930000 },
- { _MMIO(0x9888), 0x1d900157 },
- { _MMIO(0x9888), 0x1f900167 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1190030f },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900000 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900042 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x53901111 },
- { _MMIO(0x9888), 0x43900420 },
-};
-
-static int
-get_compute_l3_cache_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_l3_cache;
- lens[n] = ARRAY_SIZE(mux_config_compute_l3_cache);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x10800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fdff },
-};
-
-static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_hdc_and_sf[] = {
- { _MMIO(0x9888), 0x104f0232 },
- { _MMIO(0x9888), 0x124f4640 },
- { _MMIO(0x9888), 0x106c0232 },
- { _MMIO(0x9888), 0x11834400 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0c4e8000 },
- { _MMIO(0x9888), 0x004f1880 },
- { _MMIO(0x9888), 0x024f08bb },
- { _MMIO(0x9888), 0x044f001b },
- { _MMIO(0x9888), 0x046c0100 },
- { _MMIO(0x9888), 0x066c000b },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x041b8000 },
- { _MMIO(0x9888), 0x061b4000 },
- { _MMIO(0x9888), 0x1a1c1800 },
- { _MMIO(0x9888), 0x005b8000 },
- { _MMIO(0x9888), 0x025bc000 },
- { _MMIO(0x9888), 0x045b4000 },
- { _MMIO(0x9888), 0x125c8000 },
- { _MMIO(0x9888), 0x145c8000 },
- { _MMIO(0x9888), 0x165c8000 },
- { _MMIO(0x9888), 0x185c8000 },
- { _MMIO(0x9888), 0x0a4c00a0 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x022cc000 },
- { _MMIO(0x9888), 0x042cc000 },
- { _MMIO(0x9888), 0x062cc000 },
- { _MMIO(0x9888), 0x082cc000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x0f8305c0 },
- { _MMIO(0x9888), 0x09830000 },
- { _MMIO(0x9888), 0x07830000 },
- { _MMIO(0x9888), 0x1d950080 },
- { _MMIO(0x9888), 0x13928000 },
- { _MMIO(0x9888), 0x0f988000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b9000a0 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_hdc_and_sf;
- lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_1[] = {
- { _MMIO(0x9888), 0x126c7b40 },
- { _MMIO(0x9888), 0x166c0020 },
- { _MMIO(0x9888), 0x0a603444 },
- { _MMIO(0x9888), 0x0a613400 },
- { _MMIO(0x9888), 0x1a4ea800 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x024e8000 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x064f4000 },
- { _MMIO(0x9888), 0x0c6c5327 },
- { _MMIO(0x9888), 0x0e6c5425 },
- { _MMIO(0x9888), 0x006c2a00 },
- { _MMIO(0x9888), 0x026c285b },
- { _MMIO(0x9888), 0x046c005c },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x1a6c0800 },
- { _MMIO(0x9888), 0x0c1bc000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x001b8000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x1c1c003c },
- { _MMIO(0x9888), 0x121c8000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c0800 },
- { _MMIO(0x9888), 0x065b4000 },
- { _MMIO(0x9888), 0x1a5c1000 },
- { _MMIO(0x9888), 0x10600000 },
- { _MMIO(0x9888), 0x04600000 },
- { _MMIO(0x9888), 0x0c610044 },
- { _MMIO(0x9888), 0x10610000 },
- { _MMIO(0x9888), 0x06610000 },
- { _MMIO(0x9888), 0x0c4c02a8 },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x0a4c002a },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f0154 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x182c00aa },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2cc000 },
- { _MMIO(0x9888), 0x1190ffc0 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900420 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900021 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900400 },
- { _MMIO(0x9888), 0x43900421 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
-};
-
-static int
-get_l3_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_1;
- lens[n] = ARRAY_SIZE(mux_config_l3_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00028002 },
- { _MMIO(0x277c), 0x000087ff },
- { _MMIO(0x2780), 0x00020002 },
- { _MMIO(0x2784), 0x00008fff },
- { _MMIO(0x2788), 0x00008002 },
- { _MMIO(0x278c), 0x0000a7ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_2[] = {
- { _MMIO(0x9888), 0x126c02e0 },
- { _MMIO(0x9888), 0x146c0001 },
- { _MMIO(0x9888), 0x0a623400 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x064f4000 },
- { _MMIO(0x9888), 0x026c3324 },
- { _MMIO(0x9888), 0x046c3422 },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c0800 },
- { _MMIO(0x9888), 0x065b4000 },
- { _MMIO(0x9888), 0x1a5c1000 },
- { _MMIO(0x9888), 0x06614000 },
- { _MMIO(0x9888), 0x0c620044 },
- { _MMIO(0x9888), 0x10620000 },
- { _MMIO(0x9888), 0x06620000 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x0a4c002a },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f4000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2cc000 },
- { _MMIO(0x9888), 0x1190f800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_l3_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_2;
- lens[n] = ARRAY_SIZE(mux_config_l3_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_3[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00028002 },
- { _MMIO(0x277c), 0x000087ff },
- { _MMIO(0x2780), 0x00020002 },
- { _MMIO(0x2784), 0x00008fff },
- { _MMIO(0x2788), 0x00008002 },
- { _MMIO(0x278c), 0x0000a7ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_3[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_3[] = {
- { _MMIO(0x9888), 0x126c4e80 },
- { _MMIO(0x9888), 0x146c0000 },
- { _MMIO(0x9888), 0x0a633400 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0c4e8000 },
- { _MMIO(0x9888), 0x026c3321 },
- { _MMIO(0x9888), 0x046c342f },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1a6c2000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x061b4000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c1800 },
- { _MMIO(0x9888), 0x06604000 },
- { _MMIO(0x9888), 0x0c630044 },
- { _MMIO(0x9888), 0x10630000 },
- { _MMIO(0x9888), 0x06630000 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x0a4c00aa },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f4000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x1190f800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900002 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_l3_3_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_3;
- lens[n] = ARRAY_SIZE(mux_config_l3_3);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000efff },
- { _MMIO(0x2778), 0x00006000 },
- { _MMIO(0x277c), 0x0000f3ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x9888), 0x102f3800 },
- { _MMIO(0x9888), 0x144d0500 },
- { _MMIO(0x9888), 0x120d03c0 },
- { _MMIO(0x9888), 0x140d03cf },
- { _MMIO(0x9888), 0x0c0f0004 },
- { _MMIO(0x9888), 0x0c4e4000 },
- { _MMIO(0x9888), 0x042f0480 },
- { _MMIO(0x9888), 0x082f0000 },
- { _MMIO(0x9888), 0x022f0000 },
- { _MMIO(0x9888), 0x0a4c0090 },
- { _MMIO(0x9888), 0x064d0027 },
- { _MMIO(0x9888), 0x004d0000 },
- { _MMIO(0x9888), 0x000d0d40 },
- { _MMIO(0x9888), 0x020d803f },
- { _MMIO(0x9888), 0x040d8023 },
- { _MMIO(0x9888), 0x100d0000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x020f0010 },
- { _MMIO(0x9888), 0x000f0000 },
- { _MMIO(0x9888), 0x0e0f0050 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41901400 },
- { _MMIO(0x9888), 0x43901485 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900001 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_rasterizer_and_pixel_backend;
- lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_sampler[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x70800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x0000c000 },
- { _MMIO(0x2774), 0x0000e7ff },
- { _MMIO(0x2778), 0x00003000 },
- { _MMIO(0x277c), 0x0000f9ff },
- { _MMIO(0x2780), 0x00000c00 },
- { _MMIO(0x2784), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_sampler[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_sampler[] = {
- { _MMIO(0x9888), 0x14152c00 },
- { _MMIO(0x9888), 0x16150005 },
- { _MMIO(0x9888), 0x121600a0 },
- { _MMIO(0x9888), 0x14352c00 },
- { _MMIO(0x9888), 0x16350005 },
- { _MMIO(0x9888), 0x123600a0 },
- { _MMIO(0x9888), 0x14552c00 },
- { _MMIO(0x9888), 0x16550005 },
- { _MMIO(0x9888), 0x125600a0 },
- { _MMIO(0x9888), 0x062f6000 },
- { _MMIO(0x9888), 0x022f2000 },
- { _MMIO(0x9888), 0x0c4c0050 },
- { _MMIO(0x9888), 0x0a4c0010 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f0350 },
- { _MMIO(0x9888), 0x0c0fb000 },
- { _MMIO(0x9888), 0x0e0f00da },
- { _MMIO(0x9888), 0x182c0028 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x022dc000 },
- { _MMIO(0x9888), 0x042d4000 },
- { _MMIO(0x9888), 0x0c138000 },
- { _MMIO(0x9888), 0x0e132000 },
- { _MMIO(0x9888), 0x0413c000 },
- { _MMIO(0x9888), 0x1c140018 },
- { _MMIO(0x9888), 0x0c157000 },
- { _MMIO(0x9888), 0x0e150078 },
- { _MMIO(0x9888), 0x10150000 },
- { _MMIO(0x9888), 0x04162180 },
- { _MMIO(0x9888), 0x02160000 },
- { _MMIO(0x9888), 0x04174000 },
- { _MMIO(0x9888), 0x0233a000 },
- { _MMIO(0x9888), 0x04333000 },
- { _MMIO(0x9888), 0x14348000 },
- { _MMIO(0x9888), 0x16348000 },
- { _MMIO(0x9888), 0x02357870 },
- { _MMIO(0x9888), 0x10350000 },
- { _MMIO(0x9888), 0x04360043 },
- { _MMIO(0x9888), 0x02360000 },
- { _MMIO(0x9888), 0x04371000 },
- { _MMIO(0x9888), 0x0e538000 },
- { _MMIO(0x9888), 0x00538000 },
- { _MMIO(0x9888), 0x06533000 },
- { _MMIO(0x9888), 0x1c540020 },
- { _MMIO(0x9888), 0x12548000 },
- { _MMIO(0x9888), 0x0e557000 },
- { _MMIO(0x9888), 0x00557800 },
- { _MMIO(0x9888), 0x10550000 },
- { _MMIO(0x9888), 0x06560043 },
- { _MMIO(0x9888), 0x02560000 },
- { _MMIO(0x9888), 0x06571000 },
- { _MMIO(0x9888), 0x1190ff80 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900060 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900060 },
-};
-
-static int
-get_sampler_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_sampler;
- lens[n] = ARRAY_SIZE(mux_config_sampler);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x00007fff },
- { _MMIO(0x2778), 0x00000000 },
- { _MMIO(0x277c), 0x00009fff },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000efff },
- { _MMIO(0x2788), 0x00000000 },
- { _MMIO(0x278c), 0x0000f3ff },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000fdff },
- { _MMIO(0x2798), 0x00000000 },
- { _MMIO(0x279c), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_1[] = {
- { _MMIO(0x9888), 0x12120000 },
- { _MMIO(0x9888), 0x12320000 },
- { _MMIO(0x9888), 0x12520000 },
- { _MMIO(0x9888), 0x002f8000 },
- { _MMIO(0x9888), 0x022f3000 },
- { _MMIO(0x9888), 0x0a4c0015 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f03a0 },
- { _MMIO(0x9888), 0x0c0ff000 },
- { _MMIO(0x9888), 0x0e0f0095 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2d8000 },
- { _MMIO(0x9888), 0x0e2d4000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x02108000 },
- { _MMIO(0x9888), 0x0410c000 },
- { _MMIO(0x9888), 0x02118000 },
- { _MMIO(0x9888), 0x0411c000 },
- { _MMIO(0x9888), 0x02121880 },
- { _MMIO(0x9888), 0x041219b5 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x02134000 },
- { _MMIO(0x9888), 0x04135000 },
- { _MMIO(0x9888), 0x0c308000 },
- { _MMIO(0x9888), 0x0e304000 },
- { _MMIO(0x9888), 0x06304000 },
- { _MMIO(0x9888), 0x0c318000 },
- { _MMIO(0x9888), 0x0e314000 },
- { _MMIO(0x9888), 0x06314000 },
- { _MMIO(0x9888), 0x0c321a80 },
- { _MMIO(0x9888), 0x0e320033 },
- { _MMIO(0x9888), 0x06320031 },
- { _MMIO(0x9888), 0x00320000 },
- { _MMIO(0x9888), 0x0c334000 },
- { _MMIO(0x9888), 0x0e331000 },
- { _MMIO(0x9888), 0x06331000 },
- { _MMIO(0x9888), 0x0e508000 },
- { _MMIO(0x9888), 0x00508000 },
- { _MMIO(0x9888), 0x02504000 },
- { _MMIO(0x9888), 0x0e518000 },
- { _MMIO(0x9888), 0x00518000 },
- { _MMIO(0x9888), 0x02514000 },
- { _MMIO(0x9888), 0x0e521880 },
- { _MMIO(0x9888), 0x00521a80 },
- { _MMIO(0x9888), 0x02520033 },
- { _MMIO(0x9888), 0x0e534000 },
- { _MMIO(0x9888), 0x00534000 },
- { _MMIO(0x9888), 0x02531000 },
- { _MMIO(0x9888), 0x1190ff80 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900062 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
-};
-
-static int
-get_tdl_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_1;
- lens[n] = ARRAY_SIZE(mux_config_tdl_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_2[] = {
- { _MMIO(0x9888), 0x12124d60 },
- { _MMIO(0x9888), 0x12322e60 },
- { _MMIO(0x9888), 0x12524d60 },
- { _MMIO(0x9888), 0x022f3000 },
- { _MMIO(0x9888), 0x0a4c0014 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0fe000 },
- { _MMIO(0x9888), 0x0e0f0097 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x002d8000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x0410c000 },
- { _MMIO(0x9888), 0x0411c000 },
- { _MMIO(0x9888), 0x04121fb7 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x04135000 },
- { _MMIO(0x9888), 0x00308000 },
- { _MMIO(0x9888), 0x06304000 },
- { _MMIO(0x9888), 0x00318000 },
- { _MMIO(0x9888), 0x06314000 },
- { _MMIO(0x9888), 0x00321b80 },
- { _MMIO(0x9888), 0x0632003f },
- { _MMIO(0x9888), 0x00334000 },
- { _MMIO(0x9888), 0x06331000 },
- { _MMIO(0x9888), 0x0250c000 },
- { _MMIO(0x9888), 0x0251c000 },
- { _MMIO(0x9888), 0x02521fb7 },
- { _MMIO(0x9888), 0x00520000 },
- { _MMIO(0x9888), 0x02535000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x43900063 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_tdl_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_2;
- lens[n] = ARRAY_SIZE(mux_config_tdl_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extra[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extra[] = {
- { _MMIO(0xe458), 0x00001000 },
- { _MMIO(0xe558), 0x00003002 },
- { _MMIO(0xe658), 0x00005004 },
- { _MMIO(0xe758), 0x00011010 },
- { _MMIO(0xe45c), 0x00050012 },
- { _MMIO(0xe55c), 0x00052051 },
- { _MMIO(0xe65c), 0x00000008 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extra[] = {
- { _MMIO(0x9888), 0x121203e0 },
- { _MMIO(0x9888), 0x123203e0 },
- { _MMIO(0x9888), 0x125203e0 },
- { _MMIO(0x9888), 0x022f4000 },
- { _MMIO(0x9888), 0x0a4c0040 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0e0f006c },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x042d8000 },
- { _MMIO(0x9888), 0x06104000 },
- { _MMIO(0x9888), 0x06114000 },
- { _MMIO(0x9888), 0x06120033 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x06131000 },
- { _MMIO(0x9888), 0x04308000 },
- { _MMIO(0x9888), 0x04318000 },
- { _MMIO(0x9888), 0x04321980 },
- { _MMIO(0x9888), 0x00320000 },
- { _MMIO(0x9888), 0x04334000 },
- { _MMIO(0x9888), 0x04504000 },
- { _MMIO(0x9888), 0x04514000 },
- { _MMIO(0x9888), 0x04520033 },
- { _MMIO(0x9888), 0x00520000 },
- { _MMIO(0x9888), 0x04531000 },
- { _MMIO(0x9888), 0x1190e000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900c00 },
- { _MMIO(0x9888), 0x45900002 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_compute_extra_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extra;
- lens[n] = ARRAY_SIZE(mux_config_compute_extra);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_vme_pipe[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00100030 },
- { _MMIO(0x2774), 0x0000fff9 },
- { _MMIO(0x2778), 0x00000002 },
- { _MMIO(0x277c), 0x0000fffc },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000fff3 },
- { _MMIO(0x2788), 0x00100180 },
- { _MMIO(0x278c), 0x0000ffcf },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000ffcf },
- { _MMIO(0x2798), 0x00000002 },
- { _MMIO(0x279c), 0x0000ff3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_vme_pipe[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00008003 },
-};
-
-static const struct i915_oa_reg mux_config_vme_pipe[] = {
- { _MMIO(0x9888), 0x141a5800 },
- { _MMIO(0x9888), 0x161a00c0 },
- { _MMIO(0x9888), 0x12180240 },
- { _MMIO(0x9888), 0x14180002 },
- { _MMIO(0x9888), 0x143a5800 },
- { _MMIO(0x9888), 0x163a00c0 },
- { _MMIO(0x9888), 0x12380240 },
- { _MMIO(0x9888), 0x14380002 },
- { _MMIO(0x9888), 0x002f1000 },
- { _MMIO(0x9888), 0x022f8000 },
- { _MMIO(0x9888), 0x042f3000 },
- { _MMIO(0x9888), 0x004c4000 },
- { _MMIO(0x9888), 0x0a4c1500 },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f9500 },
- { _MMIO(0x9888), 0x100f002a },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162c0a00 },
- { _MMIO(0x9888), 0x0a2dc000 },
- { _MMIO(0x9888), 0x0c2dc000 },
- { _MMIO(0x9888), 0x04193000 },
- { _MMIO(0x9888), 0x081a28c1 },
- { _MMIO(0x9888), 0x001a0000 },
- { _MMIO(0x9888), 0x00133000 },
- { _MMIO(0x9888), 0x0613c000 },
- { _MMIO(0x9888), 0x0813f000 },
- { _MMIO(0x9888), 0x00172000 },
- { _MMIO(0x9888), 0x06178000 },
- { _MMIO(0x9888), 0x0817a000 },
- { _MMIO(0x9888), 0x00180037 },
- { _MMIO(0x9888), 0x06180940 },
- { _MMIO(0x9888), 0x08180000 },
- { _MMIO(0x9888), 0x02180000 },
- { _MMIO(0x9888), 0x04183000 },
- { _MMIO(0x9888), 0x06393000 },
- { _MMIO(0x9888), 0x0c3a28c1 },
- { _MMIO(0x9888), 0x003a0000 },
- { _MMIO(0x9888), 0x0a33f000 },
- { _MMIO(0x9888), 0x0c33f000 },
- { _MMIO(0x9888), 0x0a37a000 },
- { _MMIO(0x9888), 0x0c37a000 },
- { _MMIO(0x9888), 0x0a380977 },
- { _MMIO(0x9888), 0x08380000 },
- { _MMIO(0x9888), 0x04380000 },
- { _MMIO(0x9888), 0x06383000 },
- { _MMIO(0x9888), 0x119000ff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900040 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900800 },
- { _MMIO(0x9888), 0x47901000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900844 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_vme_pipe_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_vme_pipe;
- lens[n] = ARRAY_SIZE(mux_config_vme_pipe);
- n++;
-
- return n;
-}
-
static const struct i915_oa_reg b_counter_config_test_oa[] = {
{ _MMIO(0x2740), 0x00000000 },
{ _MMIO(0x2714), 0xf0800000 },
@@ -2370,6 +59,7 @@ static const struct i915_oa_reg flex_eu_config_test_oa[] = {
};
static const struct i915_oa_reg mux_config_test_oa[] = {
+ { _MMIO(0x9840), 0x00000080 },
{ _MMIO(0x9888), 0x11810000 },
{ _MMIO(0x9888), 0x07810016 },
{ _MMIO(0x9888), 0x1f810000 },
@@ -2384,1096 +74,35 @@ static const struct i915_oa_reg mux_config_test_oa[] = {
{ _MMIO(0x9888), 0x33900000 },
};
-static int
-get_test_oa_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_test_oa;
- lens[n] = ARRAY_SIZE(mux_config_test_oa);
- n++;
-
- return n;
-}
-
-int i915_oa_select_metric_set_sklgt2(struct drm_i915_private *dev_priv)
-{
- dev_priv->perf.oa.n_mux_configs = 0;
- dev_priv->perf.oa.b_counter_regs = NULL;
- dev_priv->perf.oa.b_counter_regs_len = 0;
- dev_priv->perf.oa.flex_regs = NULL;
- dev_priv->perf.oa.flex_regs_len = 0;
-
- switch (dev_priv->perf.oa.metrics_set) {
- case METRIC_SET_ID_RENDER_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_render_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_basic);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_basic);
-
- return 0;
- case METRIC_SET_ID_RENDER_PIPE_PROFILE:
- dev_priv->perf.oa.n_mux_configs =
- get_render_pipe_profile_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_pipe_profile;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_pipe_profile);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_pipe_profile;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_pipe_profile);
-
- return 0;
- case METRIC_SET_ID_MEMORY_READS:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_reads_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_reads;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_reads);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_reads;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_reads);
-
- return 0;
- case METRIC_SET_ID_MEMORY_WRITES:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_writes_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_writes;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_writes);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_writes;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_writes);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTENDED:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extended_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extended;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extended);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extended;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extended);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_L3_CACHE:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_l3_cache_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_L3_CACHE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_l3_cache;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_l3_cache);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_l3_cache;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_l3_cache);
-
- return 0;
- case METRIC_SET_ID_HDC_AND_SF:
- dev_priv->perf.oa.n_mux_configs =
- get_hdc_and_sf_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_hdc_and_sf;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_hdc_and_sf);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_hdc_and_sf;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_hdc_and_sf);
-
- return 0;
- case METRIC_SET_ID_L3_1:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_1);
-
- return 0;
- case METRIC_SET_ID_L3_2:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_2);
-
- return 0;
- case METRIC_SET_ID_L3_3:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_3_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_3\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_3;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_3);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_3;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_3);
-
- return 0;
- case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND:
- dev_priv->perf.oa.n_mux_configs =
- get_rasterizer_and_pixel_backend_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend);
-
- return 0;
- case METRIC_SET_ID_SAMPLER:
- dev_priv->perf.oa.n_mux_configs =
- get_sampler_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_sampler;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_sampler);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_sampler;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_sampler);
-
- return 0;
- case METRIC_SET_ID_TDL_1:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_1);
-
- return 0;
- case METRIC_SET_ID_TDL_2:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_2);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTRA:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extra_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTRA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extra;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extra);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extra;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extra);
-
- return 0;
- case METRIC_SET_ID_VME_PIPE:
- dev_priv->perf.oa.n_mux_configs =
- get_vme_pipe_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"VME_PIPE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_vme_pipe;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_vme_pipe);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_vme_pipe;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_vme_pipe);
-
- return 0;
- case METRIC_SET_ID_TEST_OA:
- dev_priv->perf.oa.n_mux_configs =
- get_test_oa_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_test_oa;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_test_oa);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_test_oa;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_test_oa);
-
- return 0;
- default:
- return -ENODEV;
- }
-}
-
-static ssize_t
-show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC);
-}
-
-static struct device_attribute dev_attr_render_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_basic[] = {
- &dev_attr_render_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_basic = {
- .name = "f519e481-24d2-4d42-87c9-3fdd12c00202",
- .attrs = attrs_render_basic,
-};
-
-static ssize_t
-show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC);
-}
-
-static struct device_attribute dev_attr_compute_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_basic[] = {
- &dev_attr_compute_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_basic = {
- .name = "fe47b29d-ae51-423e-bff4-27d965a95b60",
- .attrs = attrs_compute_basic,
-};
-
-static ssize_t
-show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE);
-}
-
-static struct device_attribute dev_attr_render_pipe_profile_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_pipe_profile_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_pipe_profile[] = {
- &dev_attr_render_pipe_profile_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_pipe_profile = {
- .name = "e0ad5ae0-84ba-4f29-a723-1906c12cb774",
- .attrs = attrs_render_pipe_profile,
-};
-
-static ssize_t
-show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS);
-}
-
-static struct device_attribute dev_attr_memory_reads_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_reads_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_reads[] = {
- &dev_attr_memory_reads_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_reads = {
- .name = "9bc436dd-6130-4add-affc-283eb6eaa864",
- .attrs = attrs_memory_reads,
-};
-
-static ssize_t
-show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES);
-}
-
-static struct device_attribute dev_attr_memory_writes_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_writes_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_writes[] = {
- &dev_attr_memory_writes_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_writes = {
- .name = "2ea0da8f-3527-4669-9d9d-13099a7435bf",
- .attrs = attrs_memory_writes,
-};
-
-static ssize_t
-show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED);
-}
-
-static struct device_attribute dev_attr_compute_extended_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extended_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extended[] = {
- &dev_attr_compute_extended_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extended = {
- .name = "d97d16af-028b-4cd1-a672-6210cb5513dd",
- .attrs = attrs_compute_extended,
-};
-
-static ssize_t
-show_compute_l3_cache_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_L3_CACHE);
-}
-
-static struct device_attribute dev_attr_compute_l3_cache_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_l3_cache_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_l3_cache[] = {
- &dev_attr_compute_l3_cache_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_l3_cache = {
- .name = "9fb22842-e708-43f7-9752-e0e41670c39e",
- .attrs = attrs_compute_l3_cache,
-};
-
-static ssize_t
-show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF);
-}
-
-static struct device_attribute dev_attr_hdc_and_sf_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_hdc_and_sf_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_hdc_and_sf[] = {
- &dev_attr_hdc_and_sf_id.attr,
- NULL,
-};
-
-static struct attribute_group group_hdc_and_sf = {
- .name = "5378e2a1-4248-4188-a4ae-da25a794c603",
- .attrs = attrs_hdc_and_sf,
-};
-
-static ssize_t
-show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1);
-}
-
-static struct device_attribute dev_attr_l3_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_1[] = {
- &dev_attr_l3_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_1 = {
- .name = "f42cdd6a-b000-42cb-870f-5eb423a7f514",
- .attrs = attrs_l3_1,
-};
-
-static ssize_t
-show_l3_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_2);
-}
-
-static struct device_attribute dev_attr_l3_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_2[] = {
- &dev_attr_l3_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_2 = {
- .name = "b9bf2423-d88c-4a7b-a051-627611d00dcc",
- .attrs = attrs_l3_2,
-};
-
-static ssize_t
-show_l3_3_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_3);
-}
-
-static struct device_attribute dev_attr_l3_3_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_3_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_3[] = {
- &dev_attr_l3_3_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_3 = {
- .name = "2414a93d-d84f-406e-99c0-472161194b40",
- .attrs = attrs_l3_3,
-};
-
-static ssize_t
-show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND);
-}
-
-static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_rasterizer_and_pixel_backend_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_rasterizer_and_pixel_backend[] = {
- &dev_attr_rasterizer_and_pixel_backend_id.attr,
- NULL,
-};
-
-static struct attribute_group group_rasterizer_and_pixel_backend = {
- .name = "53a45d2d-170b-4cf5-b7bb-585120c8e2f5",
- .attrs = attrs_rasterizer_and_pixel_backend,
-};
-
-static ssize_t
-show_sampler_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER);
-}
-
-static struct device_attribute dev_attr_sampler_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_sampler_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_sampler[] = {
- &dev_attr_sampler_id.attr,
- NULL,
-};
-
-static struct attribute_group group_sampler = {
- .name = "b4cff514-a91e-4798-a0b3-426ca13fc9c1",
- .attrs = attrs_sampler,
-};
-
-static ssize_t
-show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1);
-}
-
-static struct device_attribute dev_attr_tdl_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_1[] = {
- &dev_attr_tdl_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_1 = {
- .name = "7821d13b-9b8b-4405-9618-78cd56b62cce",
- .attrs = attrs_tdl_1,
-};
-
-static ssize_t
-show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2);
-}
-
-static struct device_attribute dev_attr_tdl_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_2[] = {
- &dev_attr_tdl_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_2 = {
- .name = "893f1a4d-919d-4388-8cb7-746d73ea7259",
- .attrs = attrs_tdl_2,
-};
-
-static ssize_t
-show_compute_extra_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTRA);
-}
-
-static struct device_attribute dev_attr_compute_extra_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extra_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extra[] = {
- &dev_attr_compute_extra_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extra = {
- .name = "41a24047-7484-4ead-ae37-de907e5ff2b2",
- .attrs = attrs_compute_extra,
-};
-
-static ssize_t
-show_vme_pipe_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_VME_PIPE);
-}
-
-static struct device_attribute dev_attr_vme_pipe_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_vme_pipe_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_vme_pipe[] = {
- &dev_attr_vme_pipe_id.attr,
- NULL,
-};
-
-static struct attribute_group group_vme_pipe = {
- .name = "95910492-943f-44bd-9461-390240f243fd",
- .attrs = attrs_vme_pipe,
-};
-
static ssize_t
show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA);
+ return sprintf(buf, "1\n");
}
-static struct device_attribute dev_attr_test_oa_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_test_oa_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_test_oa[] = {
- &dev_attr_test_oa_id.attr,
- NULL,
-};
-
-static struct attribute_group group_test_oa = {
- .name = "1651949f-0ac0-4cb1-a06f-dafd74a407d1",
- .attrs = attrs_test_oa,
-};
-
-int
-i915_perf_register_sysfs_sklgt2(struct drm_i915_private *dev_priv)
+void
+i915_perf_load_test_config_sklgt2(struct drm_i915_private *dev_priv)
{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
- int ret = 0;
+ strncpy(dev_priv->perf.oa.test_config.uuid,
+ "1651949f-0ac0-4cb1-a06f-dafd74a407d1",
+ UUID_STRING_LEN);
+ dev_priv->perf.oa.test_config.id = 1;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (ret)
- goto error_render_basic;
- }
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (ret)
- goto error_compute_basic;
- }
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (ret)
- goto error_render_pipe_profile;
- }
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (ret)
- goto error_memory_reads;
- }
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (ret)
- goto error_memory_writes;
- }
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (ret)
- goto error_compute_extended;
- }
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (ret)
- goto error_compute_l3_cache;
- }
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (ret)
- goto error_hdc_and_sf;
- }
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (ret)
- goto error_l3_1;
- }
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (ret)
- goto error_l3_2;
- }
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (ret)
- goto error_l3_3;
- }
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (ret)
- goto error_rasterizer_and_pixel_backend;
- }
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (ret)
- goto error_sampler;
- }
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (ret)
- goto error_tdl_1;
- }
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (ret)
- goto error_tdl_2;
- }
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (ret)
- goto error_compute_extra;
- }
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
- if (ret)
- goto error_vme_pipe;
- }
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa);
- if (ret)
- goto error_test_oa;
- }
+ dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
+ dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
- return 0;
+ dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
+ dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-error_test_oa:
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
-error_vme_pipe:
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
-error_compute_extra:
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
-error_tdl_2:
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
-error_tdl_1:
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
-error_sampler:
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
-error_rasterizer_and_pixel_backend:
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
-error_l3_3:
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
-error_l3_2:
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
-error_l3_1:
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
-error_hdc_and_sf:
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
-error_compute_l3_cache:
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
-error_compute_extended:
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
-error_memory_writes:
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
-error_memory_reads:
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
-error_render_pipe_profile:
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
-error_compute_basic:
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
-error_render_basic:
- return ret;
-}
+ dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
+ dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-void
-i915_perf_unregister_sysfs_sklgt2(struct drm_i915_private *dev_priv)
-{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
+ dev_priv->perf.oa.test_config.sysfs_metric.name = "1651949f-0ac0-4cb1-a06f-dafd74a407d1";
+ dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+
+ dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa);
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
+ dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
}
diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt2.h b/drivers/gpu/drm/i915/i915_oa_sklgt2.h
index f4397ba..fe1aa2c 100644
--- a/drivers/gpu/drm/i915/i915_oa_sklgt2.h
+++ b/drivers/gpu/drm/i915/i915_oa_sklgt2.h
@@ -29,12 +29,6 @@
#ifndef __I915_OA_SKLGT2_H__
#define __I915_OA_SKLGT2_H__
-extern int i915_oa_n_builtin_metric_sets_sklgt2;
-
-extern int i915_oa_select_metric_set_sklgt2(struct drm_i915_private *dev_priv);
-
-extern int i915_perf_register_sysfs_sklgt2(struct drm_i915_private *dev_priv);
-
-extern void i915_perf_unregister_sysfs_sklgt2(struct drm_i915_private *dev_priv);
+extern void i915_perf_load_test_config_sklgt2(struct drm_i915_private *dev_priv);
#endif
diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt3.c b/drivers/gpu/drm/i915/i915_oa_sklgt3.c
index 7765e22..85e51ad 100644
--- a/drivers/gpu/drm/i915/i915_oa_sklgt3.c
+++ b/drivers/gpu/drm/i915/i915_oa_sklgt3.c
@@ -31,1876 +31,6 @@
#include "i915_drv.h"
#include "i915_oa_sklgt3.h"
-enum metric_set_id {
- METRIC_SET_ID_RENDER_BASIC = 1,
- METRIC_SET_ID_COMPUTE_BASIC,
- METRIC_SET_ID_RENDER_PIPE_PROFILE,
- METRIC_SET_ID_MEMORY_READS,
- METRIC_SET_ID_MEMORY_WRITES,
- METRIC_SET_ID_COMPUTE_EXTENDED,
- METRIC_SET_ID_COMPUTE_L3_CACHE,
- METRIC_SET_ID_HDC_AND_SF,
- METRIC_SET_ID_L3_1,
- METRIC_SET_ID_L3_2,
- METRIC_SET_ID_L3_3,
- METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND,
- METRIC_SET_ID_SAMPLER,
- METRIC_SET_ID_TDL_1,
- METRIC_SET_ID_TDL_2,
- METRIC_SET_ID_COMPUTE_EXTRA,
- METRIC_SET_ID_VME_PIPE,
- METRIC_SET_ID_TEST_OA,
-};
-
-int i915_oa_n_builtin_metric_sets_sklgt3 = 18;
-
-static const struct i915_oa_reg b_counter_config_render_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_render_basic[] = {
- { _MMIO(0x9888), 0x166c01e0 },
- { _MMIO(0x9888), 0x12170280 },
- { _MMIO(0x9888), 0x12370280 },
- { _MMIO(0x9888), 0x16ec01e0 },
- { _MMIO(0x9888), 0x11930317 },
- { _MMIO(0x9888), 0x159303df },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x1a4e0380 },
- { _MMIO(0x9888), 0x0a6c0053 },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x0a1b4000 },
- { _MMIO(0x9888), 0x1c1c0001 },
- { _MMIO(0x9888), 0x002f1000 },
- { _MMIO(0x9888), 0x042f1000 },
- { _MMIO(0x9888), 0x004c4000 },
- { _MMIO(0x9888), 0x0a4c8400 },
- { _MMIO(0x9888), 0x0c4c0002 },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f6600 },
- { _MMIO(0x9888), 0x100f0001 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x162ca200 },
- { _MMIO(0x9888), 0x062d8000 },
- { _MMIO(0x9888), 0x082d8000 },
- { _MMIO(0x9888), 0x00133000 },
- { _MMIO(0x9888), 0x08133000 },
- { _MMIO(0x9888), 0x00170020 },
- { _MMIO(0x9888), 0x08170021 },
- { _MMIO(0x9888), 0x10170000 },
- { _MMIO(0x9888), 0x0633c000 },
- { _MMIO(0x9888), 0x0833c000 },
- { _MMIO(0x9888), 0x06370800 },
- { _MMIO(0x9888), 0x08370840 },
- { _MMIO(0x9888), 0x10370000 },
- { _MMIO(0x9888), 0x1ace0200 },
- { _MMIO(0x9888), 0x0aec5300 },
- { _MMIO(0x9888), 0x10ec0000 },
- { _MMIO(0x9888), 0x1cec0000 },
- { _MMIO(0x9888), 0x0a9b8000 },
- { _MMIO(0x9888), 0x1c9c0002 },
- { _MMIO(0x9888), 0x0ccc0002 },
- { _MMIO(0x9888), 0x0a8d8000 },
- { _MMIO(0x9888), 0x108f0001 },
- { _MMIO(0x9888), 0x16ac8000 },
- { _MMIO(0x9888), 0x0d933031 },
- { _MMIO(0x9888), 0x0f933e3f },
- { _MMIO(0x9888), 0x01933d00 },
- { _MMIO(0x9888), 0x0393073c },
- { _MMIO(0x9888), 0x0593000e },
- { _MMIO(0x9888), 0x1d930000 },
- { _MMIO(0x9888), 0x19930000 },
- { _MMIO(0x9888), 0x1b930000 },
- { _MMIO(0x9888), 0x1d900157 },
- { _MMIO(0x9888), 0x1f900158 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x2b908000 },
- { _MMIO(0x9888), 0x2d908000 },
- { _MMIO(0x9888), 0x2f908000 },
- { _MMIO(0x9888), 0x31908000 },
- { _MMIO(0x9888), 0x15908000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1190003f },
- { _MMIO(0x9888), 0x51907710 },
- { _MMIO(0x9888), 0x419020a0 },
- { _MMIO(0x9888), 0x55901515 },
- { _MMIO(0x9888), 0x45900529 },
- { _MMIO(0x9888), 0x47901025 },
- { _MMIO(0x9888), 0x57907770 },
- { _MMIO(0x9888), 0x49902100 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900108 },
- { _MMIO(0x9888), 0x59900007 },
- { _MMIO(0x9888), 0x43902108 },
- { _MMIO(0x9888), 0x53907777 },
-};
-
-static int
-get_render_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_basic;
- lens[n] = ARRAY_SIZE(mux_config_render_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_basic[] = {
- { _MMIO(0x9888), 0x104f00e0 },
- { _MMIO(0x9888), 0x124f1c00 },
- { _MMIO(0x9888), 0x106c00e0 },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x1a4e0820 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x064f0900 },
- { _MMIO(0x9888), 0x084f0032 },
- { _MMIO(0x9888), 0x0a4f1891 },
- { _MMIO(0x9888), 0x0c4f0e00 },
- { _MMIO(0x9888), 0x0e4f003c },
- { _MMIO(0x9888), 0x004f0d80 },
- { _MMIO(0x9888), 0x024f003b },
- { _MMIO(0x9888), 0x006c0002 },
- { _MMIO(0x9888), 0x086c0100 },
- { _MMIO(0x9888), 0x0c6c000c },
- { _MMIO(0x9888), 0x0e6c0b00 },
- { _MMIO(0x9888), 0x186c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x001b4000 },
- { _MMIO(0x9888), 0x081b8000 },
- { _MMIO(0x9888), 0x0c1b4000 },
- { _MMIO(0x9888), 0x0e1b8000 },
- { _MMIO(0x9888), 0x101c8000 },
- { _MMIO(0x9888), 0x1a1c8000 },
- { _MMIO(0x9888), 0x1c1c0024 },
- { _MMIO(0x9888), 0x065b8000 },
- { _MMIO(0x9888), 0x085b4000 },
- { _MMIO(0x9888), 0x0a5bc000 },
- { _MMIO(0x9888), 0x0c5b8000 },
- { _MMIO(0x9888), 0x0e5b4000 },
- { _MMIO(0x9888), 0x005b8000 },
- { _MMIO(0x9888), 0x025b4000 },
- { _MMIO(0x9888), 0x1a5c6000 },
- { _MMIO(0x9888), 0x1c5c001b },
- { _MMIO(0x9888), 0x125c8000 },
- { _MMIO(0x9888), 0x145c8000 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4c2000 },
- { _MMIO(0x9888), 0x0c4c0208 },
- { _MMIO(0x9888), 0x000da000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x020d2000 },
- { _MMIO(0x9888), 0x0c0f5400 },
- { _MMIO(0x9888), 0x0e0f5500 },
- { _MMIO(0x9888), 0x100f0155 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2cc000 },
- { _MMIO(0x9888), 0x162cfb00 },
- { _MMIO(0x9888), 0x182c00be },
- { _MMIO(0x9888), 0x022cc000 },
- { _MMIO(0x9888), 0x042cc000 },
- { _MMIO(0x9888), 0x19900157 },
- { _MMIO(0x9888), 0x1b900158 },
- { _MMIO(0x9888), 0x1d900105 },
- { _MMIO(0x9888), 0x1f900103 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x11900fff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900863 },
- { _MMIO(0x9888), 0x47900802 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900802 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900002 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900c62 },
- { _MMIO(0x9888), 0x53903333 },
-};
-
-static int
-get_compute_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_basic;
- lens[n] = ARRAY_SIZE(mux_config_compute_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007ffea },
- { _MMIO(0x2774), 0x00007ffc },
- { _MMIO(0x2778), 0x0007affa },
- { _MMIO(0x277c), 0x0000f5fd },
- { _MMIO(0x2780), 0x00079ffa },
- { _MMIO(0x2784), 0x0000f3fb },
- { _MMIO(0x2788), 0x0007bf7a },
- { _MMIO(0x278c), 0x0000f7e7 },
- { _MMIO(0x2790), 0x0007fefa },
- { _MMIO(0x2794), 0x0000f7cf },
- { _MMIO(0x2798), 0x00077ffa },
- { _MMIO(0x279c), 0x0000efdf },
- { _MMIO(0x27a0), 0x0006fffa },
- { _MMIO(0x27a4), 0x0000cfbf },
- { _MMIO(0x27a8), 0x0003fffa },
- { _MMIO(0x27ac), 0x00005f7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_render_pipe_profile[] = {
- { _MMIO(0x9888), 0x0c0e001f },
- { _MMIO(0x9888), 0x0a0f0000 },
- { _MMIO(0x9888), 0x10116800 },
- { _MMIO(0x9888), 0x178a03e0 },
- { _MMIO(0x9888), 0x11824c00 },
- { _MMIO(0x9888), 0x11830020 },
- { _MMIO(0x9888), 0x13840020 },
- { _MMIO(0x9888), 0x11850019 },
- { _MMIO(0x9888), 0x11860007 },
- { _MMIO(0x9888), 0x01870c40 },
- { _MMIO(0x9888), 0x17880000 },
- { _MMIO(0x9888), 0x022f4000 },
- { _MMIO(0x9888), 0x0a4c0040 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x040d4000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x020e5400 },
- { _MMIO(0x9888), 0x000e0000 },
- { _MMIO(0x9888), 0x080f0040 },
- { _MMIO(0x9888), 0x000f0000 },
- { _MMIO(0x9888), 0x100f0000 },
- { _MMIO(0x9888), 0x0e0f0040 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x06104000 },
- { _MMIO(0x9888), 0x06110012 },
- { _MMIO(0x9888), 0x06131000 },
- { _MMIO(0x9888), 0x01898000 },
- { _MMIO(0x9888), 0x0d890100 },
- { _MMIO(0x9888), 0x03898000 },
- { _MMIO(0x9888), 0x09808000 },
- { _MMIO(0x9888), 0x0b808000 },
- { _MMIO(0x9888), 0x0380c000 },
- { _MMIO(0x9888), 0x0f8a0075 },
- { _MMIO(0x9888), 0x1d8a0000 },
- { _MMIO(0x9888), 0x118a8000 },
- { _MMIO(0x9888), 0x1b8a4000 },
- { _MMIO(0x9888), 0x138a8000 },
- { _MMIO(0x9888), 0x1d81a000 },
- { _MMIO(0x9888), 0x15818000 },
- { _MMIO(0x9888), 0x17818000 },
- { _MMIO(0x9888), 0x0b820030 },
- { _MMIO(0x9888), 0x07828000 },
- { _MMIO(0x9888), 0x0d824000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x05824000 },
- { _MMIO(0x9888), 0x0d830003 },
- { _MMIO(0x9888), 0x0583000c },
- { _MMIO(0x9888), 0x09830000 },
- { _MMIO(0x9888), 0x03838000 },
- { _MMIO(0x9888), 0x07838000 },
- { _MMIO(0x9888), 0x0b840980 },
- { _MMIO(0x9888), 0x03844d80 },
- { _MMIO(0x9888), 0x11840000 },
- { _MMIO(0x9888), 0x09848000 },
- { _MMIO(0x9888), 0x09850080 },
- { _MMIO(0x9888), 0x03850003 },
- { _MMIO(0x9888), 0x01850000 },
- { _MMIO(0x9888), 0x07860000 },
- { _MMIO(0x9888), 0x0f860400 },
- { _MMIO(0x9888), 0x09870032 },
- { _MMIO(0x9888), 0x01888052 },
- { _MMIO(0x9888), 0x11880000 },
- { _MMIO(0x9888), 0x09884000 },
- { _MMIO(0x9888), 0x1b931001 },
- { _MMIO(0x9888), 0x1d930001 },
- { _MMIO(0x9888), 0x19934000 },
- { _MMIO(0x9888), 0x1b958000 },
- { _MMIO(0x9888), 0x1d950094 },
- { _MMIO(0x9888), 0x19958000 },
- { _MMIO(0x9888), 0x09e58000 },
- { _MMIO(0x9888), 0x0be58000 },
- { _MMIO(0x9888), 0x03e5c000 },
- { _MMIO(0x9888), 0x0592c000 },
- { _MMIO(0x9888), 0x0b928000 },
- { _MMIO(0x9888), 0x0d924000 },
- { _MMIO(0x9888), 0x0f924000 },
- { _MMIO(0x9888), 0x11928000 },
- { _MMIO(0x9888), 0x1392c000 },
- { _MMIO(0x9888), 0x09924000 },
- { _MMIO(0x9888), 0x01985000 },
- { _MMIO(0x9888), 0x07988000 },
- { _MMIO(0x9888), 0x09981000 },
- { _MMIO(0x9888), 0x0b982000 },
- { _MMIO(0x9888), 0x0d982000 },
- { _MMIO(0x9888), 0x0f989000 },
- { _MMIO(0x9888), 0x05982000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x23904000 },
- { _MMIO(0x9888), 0x25908000 },
- { _MMIO(0x9888), 0x27904000 },
- { _MMIO(0x9888), 0x29908000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1190c080 },
- { _MMIO(0x9888), 0x51901150 },
- { _MMIO(0x9888), 0x41901400 },
- { _MMIO(0x9888), 0x55905111 },
- { _MMIO(0x9888), 0x45901400 },
- { _MMIO(0x9888), 0x479004a5 },
- { _MMIO(0x9888), 0x57903455 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b9000a0 },
- { _MMIO(0x9888), 0x59900001 },
- { _MMIO(0x9888), 0x43900005 },
- { _MMIO(0x9888), 0x53900455 },
-};
-
-static int
-get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_pipe_profile;
- lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_reads[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f872 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_reads[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_reads[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f900064 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x1b930055 },
- { _MMIO(0x9888), 0x03e58000 },
- { _MMIO(0x9888), 0x05e5c000 },
- { _MMIO(0x9888), 0x07e54000 },
- { _MMIO(0x9888), 0x13900150 },
- { _MMIO(0x9888), 0x21900151 },
- { _MMIO(0x9888), 0x23900152 },
- { _MMIO(0x9888), 0x25900153 },
- { _MMIO(0x9888), 0x27900154 },
- { _MMIO(0x9888), 0x29900155 },
- { _MMIO(0x9888), 0x2b900156 },
- { _MMIO(0x9888), 0x2d900157 },
- { _MMIO(0x9888), 0x2f90015f },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c60 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900c00 },
- { _MMIO(0x9888), 0x47900c63 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900c63 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_memory_reads_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_reads;
- lens[n] = ARRAY_SIZE(mux_config_memory_reads);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_writes[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f822 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_writes[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_writes[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f901000 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x1b930055 },
- { _MMIO(0x9888), 0x03e58000 },
- { _MMIO(0x9888), 0x05e5c000 },
- { _MMIO(0x9888), 0x07e54000 },
- { _MMIO(0x9888), 0x13900160 },
- { _MMIO(0x9888), 0x21900161 },
- { _MMIO(0x9888), 0x23900162 },
- { _MMIO(0x9888), 0x25900163 },
- { _MMIO(0x9888), 0x27900164 },
- { _MMIO(0x9888), 0x29900165 },
- { _MMIO(0x9888), 0x2b900166 },
- { _MMIO(0x9888), 0x2d900167 },
- { _MMIO(0x9888), 0x2f900150 },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c60 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900c00 },
- { _MMIO(0x9888), 0x47900c63 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900c63 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_memory_writes_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_writes;
- lens[n] = ARRAY_SIZE(mux_config_memory_writes);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extended[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fc2a },
- { _MMIO(0x2774), 0x0000bf00 },
- { _MMIO(0x2778), 0x0007fc6a },
- { _MMIO(0x277c), 0x0000bf00 },
- { _MMIO(0x2780), 0x0007fc92 },
- { _MMIO(0x2784), 0x0000bf00 },
- { _MMIO(0x2788), 0x0007fca2 },
- { _MMIO(0x278c), 0x0000bf00 },
- { _MMIO(0x2790), 0x0007fc32 },
- { _MMIO(0x2794), 0x0000bf00 },
- { _MMIO(0x2798), 0x0007fc9a },
- { _MMIO(0x279c), 0x0000bf00 },
- { _MMIO(0x27a0), 0x0007fe6a },
- { _MMIO(0x27a4), 0x0000bf00 },
- { _MMIO(0x27a8), 0x0007fe7a },
- { _MMIO(0x27ac), 0x0000bf00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extended[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended[] = {
- { _MMIO(0x9888), 0x106c00e0 },
- { _MMIO(0x9888), 0x141c8160 },
- { _MMIO(0x9888), 0x161c8015 },
- { _MMIO(0x9888), 0x181c0120 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x184e8000 },
- { _MMIO(0x9888), 0x1a4eaaa0 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x024e8000 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0e6c0b01 },
- { _MMIO(0x9888), 0x006c0200 },
- { _MMIO(0x9888), 0x026c000c },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x001b8000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x001c0041 },
- { _MMIO(0x9888), 0x061c4200 },
- { _MMIO(0x9888), 0x081c4443 },
- { _MMIO(0x9888), 0x0a1c4645 },
- { _MMIO(0x9888), 0x0c1c7647 },
- { _MMIO(0x9888), 0x041c7357 },
- { _MMIO(0x9888), 0x1c1c0030 },
- { _MMIO(0x9888), 0x101c0000 },
- { _MMIO(0x9888), 0x1a1c0000 },
- { _MMIO(0x9888), 0x121c8000 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4caa2a },
- { _MMIO(0x9888), 0x0c4c02aa },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x000da000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x0c0f5400 },
- { _MMIO(0x9888), 0x0e0f5515 },
- { _MMIO(0x9888), 0x100f0155 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162caa00 },
- { _MMIO(0x9888), 0x182c00aa },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x11907fff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900040 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900802 },
- { _MMIO(0x9888), 0x47900842 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900842 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900800 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_compute_extended_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extended;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_l3_cache[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fffa },
- { _MMIO(0x2774), 0x0000fefe },
- { _MMIO(0x2778), 0x0007fffa },
- { _MMIO(0x277c), 0x0000fefd },
- { _MMIO(0x2790), 0x0007fffa },
- { _MMIO(0x2794), 0x0000fbef },
- { _MMIO(0x2798), 0x0007fffa },
- { _MMIO(0x279c), 0x0000fbdf },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_l3_cache[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00101100 },
- { _MMIO(0xe45c), 0x00201200 },
- { _MMIO(0xe55c), 0x00301300 },
- { _MMIO(0xe65c), 0x00401400 },
-};
-
-static const struct i915_oa_reg mux_config_compute_l3_cache[] = {
- { _MMIO(0x9888), 0x166c0760 },
- { _MMIO(0x9888), 0x1593001e },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x184e8000 },
- { _MMIO(0x9888), 0x1a4e8020 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x006c0051 },
- { _MMIO(0x9888), 0x066c5000 },
- { _MMIO(0x9888), 0x086c5c5d },
- { _MMIO(0x9888), 0x0e6c5e5f },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x186c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x001b4000 },
- { _MMIO(0x9888), 0x061b8000 },
- { _MMIO(0x9888), 0x081bc000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x101c8000 },
- { _MMIO(0x9888), 0x1a1ce000 },
- { _MMIO(0x9888), 0x1c1c0030 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4c2a00 },
- { _MMIO(0x9888), 0x0c4c0280 },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f1500 },
- { _MMIO(0x9888), 0x100f0140 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162c0a00 },
- { _MMIO(0x9888), 0x182c00a0 },
- { _MMIO(0x9888), 0x03933300 },
- { _MMIO(0x9888), 0x05930032 },
- { _MMIO(0x9888), 0x11930000 },
- { _MMIO(0x9888), 0x1b930000 },
- { _MMIO(0x9888), 0x1d900157 },
- { _MMIO(0x9888), 0x1f900158 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1190030f },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900000 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900063 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x53903333 },
- { _MMIO(0x9888), 0x43900840 },
-};
-
-static int
-get_compute_l3_cache_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_l3_cache;
- lens[n] = ARRAY_SIZE(mux_config_compute_l3_cache);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x10800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fdff },
-};
-
-static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_hdc_and_sf[] = {
- { _MMIO(0x9888), 0x104f0232 },
- { _MMIO(0x9888), 0x124f4640 },
- { _MMIO(0x9888), 0x106c0232 },
- { _MMIO(0x9888), 0x11834400 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0c4e8000 },
- { _MMIO(0x9888), 0x004f1880 },
- { _MMIO(0x9888), 0x024f08bb },
- { _MMIO(0x9888), 0x044f001b },
- { _MMIO(0x9888), 0x046c0100 },
- { _MMIO(0x9888), 0x066c000b },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x041b8000 },
- { _MMIO(0x9888), 0x061b4000 },
- { _MMIO(0x9888), 0x1a1c1800 },
- { _MMIO(0x9888), 0x005b8000 },
- { _MMIO(0x9888), 0x025bc000 },
- { _MMIO(0x9888), 0x045b4000 },
- { _MMIO(0x9888), 0x125c8000 },
- { _MMIO(0x9888), 0x145c8000 },
- { _MMIO(0x9888), 0x165c8000 },
- { _MMIO(0x9888), 0x185c8000 },
- { _MMIO(0x9888), 0x0a4c00a0 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x022cc000 },
- { _MMIO(0x9888), 0x042cc000 },
- { _MMIO(0x9888), 0x062cc000 },
- { _MMIO(0x9888), 0x082cc000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x0f8305c0 },
- { _MMIO(0x9888), 0x09830000 },
- { _MMIO(0x9888), 0x07830000 },
- { _MMIO(0x9888), 0x1d950080 },
- { _MMIO(0x9888), 0x13928000 },
- { _MMIO(0x9888), 0x0f988000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x59900005 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_hdc_and_sf;
- lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_1[] = {
- { _MMIO(0x9888), 0x126c7b40 },
- { _MMIO(0x9888), 0x166c0020 },
- { _MMIO(0x9888), 0x0a603444 },
- { _MMIO(0x9888), 0x0a613400 },
- { _MMIO(0x9888), 0x1a4ea800 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x024e8000 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x064f4000 },
- { _MMIO(0x9888), 0x0c6c5327 },
- { _MMIO(0x9888), 0x0e6c5425 },
- { _MMIO(0x9888), 0x006c2a00 },
- { _MMIO(0x9888), 0x026c285b },
- { _MMIO(0x9888), 0x046c005c },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x1a6c0800 },
- { _MMIO(0x9888), 0x0c1bc000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x001b8000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x1c1c003c },
- { _MMIO(0x9888), 0x121c8000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c0800 },
- { _MMIO(0x9888), 0x065b4000 },
- { _MMIO(0x9888), 0x1a5c1000 },
- { _MMIO(0x9888), 0x10600000 },
- { _MMIO(0x9888), 0x04600000 },
- { _MMIO(0x9888), 0x0c610044 },
- { _MMIO(0x9888), 0x10610000 },
- { _MMIO(0x9888), 0x06610000 },
- { _MMIO(0x9888), 0x0c4c02a8 },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x0a4c002a },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f0154 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x182c00aa },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2cc000 },
- { _MMIO(0x9888), 0x1190ffc0 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900420 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900021 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900400 },
- { _MMIO(0x9888), 0x43900421 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
-};
-
-static int
-get_l3_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_1;
- lens[n] = ARRAY_SIZE(mux_config_l3_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00028002 },
- { _MMIO(0x277c), 0x000087ff },
- { _MMIO(0x2780), 0x00020002 },
- { _MMIO(0x2784), 0x00008fff },
- { _MMIO(0x2788), 0x00008002 },
- { _MMIO(0x278c), 0x0000a7ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_2[] = {
- { _MMIO(0x9888), 0x126c02e0 },
- { _MMIO(0x9888), 0x146c0001 },
- { _MMIO(0x9888), 0x0a623400 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x064f4000 },
- { _MMIO(0x9888), 0x026c3324 },
- { _MMIO(0x9888), 0x046c3422 },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c0800 },
- { _MMIO(0x9888), 0x065b4000 },
- { _MMIO(0x9888), 0x1a5c1000 },
- { _MMIO(0x9888), 0x06614000 },
- { _MMIO(0x9888), 0x0c620044 },
- { _MMIO(0x9888), 0x10620000 },
- { _MMIO(0x9888), 0x06620000 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x0a4c002a },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f4000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2cc000 },
- { _MMIO(0x9888), 0x1190f800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_l3_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_2;
- lens[n] = ARRAY_SIZE(mux_config_l3_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_3[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00028002 },
- { _MMIO(0x277c), 0x000087ff },
- { _MMIO(0x2780), 0x00020002 },
- { _MMIO(0x2784), 0x00008fff },
- { _MMIO(0x2788), 0x00008002 },
- { _MMIO(0x278c), 0x0000a7ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_3[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_3[] = {
- { _MMIO(0x9888), 0x126c4e80 },
- { _MMIO(0x9888), 0x146c0000 },
- { _MMIO(0x9888), 0x0a633400 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0c4e8000 },
- { _MMIO(0x9888), 0x026c3321 },
- { _MMIO(0x9888), 0x046c342f },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1a6c2000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x061b4000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c1800 },
- { _MMIO(0x9888), 0x06604000 },
- { _MMIO(0x9888), 0x0c630044 },
- { _MMIO(0x9888), 0x10630000 },
- { _MMIO(0x9888), 0x06630000 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x0a4c00aa },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f4000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x1190f800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900002 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_l3_3_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_3;
- lens[n] = ARRAY_SIZE(mux_config_l3_3);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000efff },
- { _MMIO(0x2778), 0x00006000 },
- { _MMIO(0x277c), 0x0000f3ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x9888), 0x102f3800 },
- { _MMIO(0x9888), 0x144d0500 },
- { _MMIO(0x9888), 0x120d03c0 },
- { _MMIO(0x9888), 0x140d03cf },
- { _MMIO(0x9888), 0x0c0f0004 },
- { _MMIO(0x9888), 0x0c4e4000 },
- { _MMIO(0x9888), 0x042f0480 },
- { _MMIO(0x9888), 0x082f0000 },
- { _MMIO(0x9888), 0x022f0000 },
- { _MMIO(0x9888), 0x0a4c0090 },
- { _MMIO(0x9888), 0x064d0027 },
- { _MMIO(0x9888), 0x004d0000 },
- { _MMIO(0x9888), 0x000d0d40 },
- { _MMIO(0x9888), 0x020d803f },
- { _MMIO(0x9888), 0x040d8023 },
- { _MMIO(0x9888), 0x100d0000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x020f0010 },
- { _MMIO(0x9888), 0x000f0000 },
- { _MMIO(0x9888), 0x0e0f0050 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41901400 },
- { _MMIO(0x9888), 0x43901485 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900001 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_rasterizer_and_pixel_backend;
- lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_sampler[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x70800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x0000c000 },
- { _MMIO(0x2774), 0x0000e7ff },
- { _MMIO(0x2778), 0x00003000 },
- { _MMIO(0x277c), 0x0000f9ff },
- { _MMIO(0x2780), 0x00000c00 },
- { _MMIO(0x2784), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_sampler[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_sampler[] = {
- { _MMIO(0x9888), 0x14152c00 },
- { _MMIO(0x9888), 0x16150005 },
- { _MMIO(0x9888), 0x121600a0 },
- { _MMIO(0x9888), 0x14352c00 },
- { _MMIO(0x9888), 0x16350005 },
- { _MMIO(0x9888), 0x123600a0 },
- { _MMIO(0x9888), 0x14552c00 },
- { _MMIO(0x9888), 0x16550005 },
- { _MMIO(0x9888), 0x125600a0 },
- { _MMIO(0x9888), 0x062f6000 },
- { _MMIO(0x9888), 0x022f2000 },
- { _MMIO(0x9888), 0x0c4c0050 },
- { _MMIO(0x9888), 0x0a4c0010 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f0350 },
- { _MMIO(0x9888), 0x0c0fb000 },
- { _MMIO(0x9888), 0x0e0f00da },
- { _MMIO(0x9888), 0x182c0028 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x022dc000 },
- { _MMIO(0x9888), 0x042d4000 },
- { _MMIO(0x9888), 0x0c138000 },
- { _MMIO(0x9888), 0x0e132000 },
- { _MMIO(0x9888), 0x0413c000 },
- { _MMIO(0x9888), 0x1c140018 },
- { _MMIO(0x9888), 0x0c157000 },
- { _MMIO(0x9888), 0x0e150078 },
- { _MMIO(0x9888), 0x10150000 },
- { _MMIO(0x9888), 0x04162180 },
- { _MMIO(0x9888), 0x02160000 },
- { _MMIO(0x9888), 0x04174000 },
- { _MMIO(0x9888), 0x0233a000 },
- { _MMIO(0x9888), 0x04333000 },
- { _MMIO(0x9888), 0x14348000 },
- { _MMIO(0x9888), 0x16348000 },
- { _MMIO(0x9888), 0x02357870 },
- { _MMIO(0x9888), 0x10350000 },
- { _MMIO(0x9888), 0x04360043 },
- { _MMIO(0x9888), 0x02360000 },
- { _MMIO(0x9888), 0x04371000 },
- { _MMIO(0x9888), 0x0e538000 },
- { _MMIO(0x9888), 0x00538000 },
- { _MMIO(0x9888), 0x06533000 },
- { _MMIO(0x9888), 0x1c540020 },
- { _MMIO(0x9888), 0x12548000 },
- { _MMIO(0x9888), 0x0e557000 },
- { _MMIO(0x9888), 0x00557800 },
- { _MMIO(0x9888), 0x10550000 },
- { _MMIO(0x9888), 0x06560043 },
- { _MMIO(0x9888), 0x02560000 },
- { _MMIO(0x9888), 0x06571000 },
- { _MMIO(0x9888), 0x1190ff80 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900060 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900060 },
-};
-
-static int
-get_sampler_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_sampler;
- lens[n] = ARRAY_SIZE(mux_config_sampler);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x00007fff },
- { _MMIO(0x2778), 0x00000000 },
- { _MMIO(0x277c), 0x00009fff },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000efff },
- { _MMIO(0x2788), 0x00000000 },
- { _MMIO(0x278c), 0x0000f3ff },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000fdff },
- { _MMIO(0x2798), 0x00000000 },
- { _MMIO(0x279c), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_1[] = {
- { _MMIO(0x9888), 0x12120000 },
- { _MMIO(0x9888), 0x12320000 },
- { _MMIO(0x9888), 0x12520000 },
- { _MMIO(0x9888), 0x002f8000 },
- { _MMIO(0x9888), 0x022f3000 },
- { _MMIO(0x9888), 0x0a4c0015 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f03a0 },
- { _MMIO(0x9888), 0x0c0ff000 },
- { _MMIO(0x9888), 0x0e0f0095 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2d8000 },
- { _MMIO(0x9888), 0x0e2d4000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x02108000 },
- { _MMIO(0x9888), 0x0410c000 },
- { _MMIO(0x9888), 0x02118000 },
- { _MMIO(0x9888), 0x0411c000 },
- { _MMIO(0x9888), 0x02121880 },
- { _MMIO(0x9888), 0x041219b5 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x02134000 },
- { _MMIO(0x9888), 0x04135000 },
- { _MMIO(0x9888), 0x0c308000 },
- { _MMIO(0x9888), 0x0e304000 },
- { _MMIO(0x9888), 0x06304000 },
- { _MMIO(0x9888), 0x0c318000 },
- { _MMIO(0x9888), 0x0e314000 },
- { _MMIO(0x9888), 0x06314000 },
- { _MMIO(0x9888), 0x0c321a80 },
- { _MMIO(0x9888), 0x0e320033 },
- { _MMIO(0x9888), 0x06320031 },
- { _MMIO(0x9888), 0x00320000 },
- { _MMIO(0x9888), 0x0c334000 },
- { _MMIO(0x9888), 0x0e331000 },
- { _MMIO(0x9888), 0x06331000 },
- { _MMIO(0x9888), 0x0e508000 },
- { _MMIO(0x9888), 0x00508000 },
- { _MMIO(0x9888), 0x02504000 },
- { _MMIO(0x9888), 0x0e518000 },
- { _MMIO(0x9888), 0x00518000 },
- { _MMIO(0x9888), 0x02514000 },
- { _MMIO(0x9888), 0x0e521880 },
- { _MMIO(0x9888), 0x00521a80 },
- { _MMIO(0x9888), 0x02520033 },
- { _MMIO(0x9888), 0x0e534000 },
- { _MMIO(0x9888), 0x00534000 },
- { _MMIO(0x9888), 0x02531000 },
- { _MMIO(0x9888), 0x1190ff80 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900062 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
-};
-
-static int
-get_tdl_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_1;
- lens[n] = ARRAY_SIZE(mux_config_tdl_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_2[] = {
- { _MMIO(0x9888), 0x12124d60 },
- { _MMIO(0x9888), 0x12322e60 },
- { _MMIO(0x9888), 0x12524d60 },
- { _MMIO(0x9888), 0x022f3000 },
- { _MMIO(0x9888), 0x0a4c0014 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0fe000 },
- { _MMIO(0x9888), 0x0e0f0097 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x002d8000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x0410c000 },
- { _MMIO(0x9888), 0x0411c000 },
- { _MMIO(0x9888), 0x04121fb7 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x04135000 },
- { _MMIO(0x9888), 0x00308000 },
- { _MMIO(0x9888), 0x06304000 },
- { _MMIO(0x9888), 0x00318000 },
- { _MMIO(0x9888), 0x06314000 },
- { _MMIO(0x9888), 0x00321b80 },
- { _MMIO(0x9888), 0x0632003f },
- { _MMIO(0x9888), 0x00334000 },
- { _MMIO(0x9888), 0x06331000 },
- { _MMIO(0x9888), 0x0250c000 },
- { _MMIO(0x9888), 0x0251c000 },
- { _MMIO(0x9888), 0x02521fb7 },
- { _MMIO(0x9888), 0x00520000 },
- { _MMIO(0x9888), 0x02535000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x43900063 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_tdl_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_2;
- lens[n] = ARRAY_SIZE(mux_config_tdl_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extra[] = {
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extra[] = {
-};
-
-static const struct i915_oa_reg mux_config_compute_extra[] = {
- { _MMIO(0x9888), 0x121203e0 },
- { _MMIO(0x9888), 0x123203e0 },
- { _MMIO(0x9888), 0x125203e0 },
- { _MMIO(0x9888), 0x129203e0 },
- { _MMIO(0x9888), 0x12b203e0 },
- { _MMIO(0x9888), 0x12d203e0 },
- { _MMIO(0x9888), 0x024ec000 },
- { _MMIO(0x9888), 0x044ec000 },
- { _MMIO(0x9888), 0x064ec000 },
- { _MMIO(0x9888), 0x022f4000 },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x0a4c0042 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f006d },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x042d8000 },
- { _MMIO(0x9888), 0x06104000 },
- { _MMIO(0x9888), 0x06114000 },
- { _MMIO(0x9888), 0x06120033 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x06131000 },
- { _MMIO(0x9888), 0x04308000 },
- { _MMIO(0x9888), 0x04318000 },
- { _MMIO(0x9888), 0x04321980 },
- { _MMIO(0x9888), 0x00320000 },
- { _MMIO(0x9888), 0x04334000 },
- { _MMIO(0x9888), 0x04504000 },
- { _MMIO(0x9888), 0x04514000 },
- { _MMIO(0x9888), 0x04520033 },
- { _MMIO(0x9888), 0x00520000 },
- { _MMIO(0x9888), 0x04531000 },
- { _MMIO(0x9888), 0x00af8000 },
- { _MMIO(0x9888), 0x0acc0001 },
- { _MMIO(0x9888), 0x008d8000 },
- { _MMIO(0x9888), 0x028da000 },
- { _MMIO(0x9888), 0x0c8fb000 },
- { _MMIO(0x9888), 0x0e8f0001 },
- { _MMIO(0x9888), 0x06ac8000 },
- { _MMIO(0x9888), 0x02ad4000 },
- { _MMIO(0x9888), 0x02908000 },
- { _MMIO(0x9888), 0x02918000 },
- { _MMIO(0x9888), 0x02921980 },
- { _MMIO(0x9888), 0x00920000 },
- { _MMIO(0x9888), 0x02934000 },
- { _MMIO(0x9888), 0x02b04000 },
- { _MMIO(0x9888), 0x02b14000 },
- { _MMIO(0x9888), 0x02b20033 },
- { _MMIO(0x9888), 0x00b20000 },
- { _MMIO(0x9888), 0x02b31000 },
- { _MMIO(0x9888), 0x00d08000 },
- { _MMIO(0x9888), 0x00d18000 },
- { _MMIO(0x9888), 0x00d21980 },
- { _MMIO(0x9888), 0x00d34000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x43900402 },
- { _MMIO(0x9888), 0x53901550 },
- { _MMIO(0x9888), 0x45900080 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_compute_extra_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extra;
- lens[n] = ARRAY_SIZE(mux_config_compute_extra);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_vme_pipe[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00100030 },
- { _MMIO(0x2774), 0x0000fff9 },
- { _MMIO(0x2778), 0x00000002 },
- { _MMIO(0x277c), 0x0000fffc },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000fff3 },
- { _MMIO(0x2788), 0x00100180 },
- { _MMIO(0x278c), 0x0000ffcf },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000ffcf },
- { _MMIO(0x2798), 0x00000002 },
- { _MMIO(0x279c), 0x0000ff3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_vme_pipe[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00008003 },
-};
-
-static const struct i915_oa_reg mux_config_vme_pipe[] = {
- { _MMIO(0x9888), 0x141a5800 },
- { _MMIO(0x9888), 0x161a00c0 },
- { _MMIO(0x9888), 0x12180240 },
- { _MMIO(0x9888), 0x14180002 },
- { _MMIO(0x9888), 0x149a5800 },
- { _MMIO(0x9888), 0x169a00c0 },
- { _MMIO(0x9888), 0x12980240 },
- { _MMIO(0x9888), 0x14980002 },
- { _MMIO(0x9888), 0x1a4e3fc0 },
- { _MMIO(0x9888), 0x002f1000 },
- { _MMIO(0x9888), 0x022f8000 },
- { _MMIO(0x9888), 0x042f3000 },
- { _MMIO(0x9888), 0x004c4000 },
- { _MMIO(0x9888), 0x0a4c9500 },
- { _MMIO(0x9888), 0x0c4c002a },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f5500 },
- { _MMIO(0x9888), 0x100f0015 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162caa00 },
- { _MMIO(0x9888), 0x182c000a },
- { _MMIO(0x9888), 0x04193000 },
- { _MMIO(0x9888), 0x081a28c1 },
- { _MMIO(0x9888), 0x001a0000 },
- { _MMIO(0x9888), 0x00133000 },
- { _MMIO(0x9888), 0x0613c000 },
- { _MMIO(0x9888), 0x0813f000 },
- { _MMIO(0x9888), 0x00172000 },
- { _MMIO(0x9888), 0x06178000 },
- { _MMIO(0x9888), 0x0817a000 },
- { _MMIO(0x9888), 0x00180037 },
- { _MMIO(0x9888), 0x06180940 },
- { _MMIO(0x9888), 0x08180000 },
- { _MMIO(0x9888), 0x02180000 },
- { _MMIO(0x9888), 0x04183000 },
- { _MMIO(0x9888), 0x04afc000 },
- { _MMIO(0x9888), 0x06af3000 },
- { _MMIO(0x9888), 0x0acc4000 },
- { _MMIO(0x9888), 0x0ccc0015 },
- { _MMIO(0x9888), 0x0a8da000 },
- { _MMIO(0x9888), 0x0c8da000 },
- { _MMIO(0x9888), 0x0e8f4000 },
- { _MMIO(0x9888), 0x108f0015 },
- { _MMIO(0x9888), 0x16aca000 },
- { _MMIO(0x9888), 0x18ac000a },
- { _MMIO(0x9888), 0x06993000 },
- { _MMIO(0x9888), 0x0c9a28c1 },
- { _MMIO(0x9888), 0x009a0000 },
- { _MMIO(0x9888), 0x0a93f000 },
- { _MMIO(0x9888), 0x0c93f000 },
- { _MMIO(0x9888), 0x0a97a000 },
- { _MMIO(0x9888), 0x0c97a000 },
- { _MMIO(0x9888), 0x0a980977 },
- { _MMIO(0x9888), 0x08980000 },
- { _MMIO(0x9888), 0x04980000 },
- { _MMIO(0x9888), 0x06983000 },
- { _MMIO(0x9888), 0x119000ff },
- { _MMIO(0x9888), 0x51900050 },
- { _MMIO(0x9888), 0x41900000 },
- { _MMIO(0x9888), 0x55900115 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x47900884 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900002 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_vme_pipe_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_vme_pipe;
- lens[n] = ARRAY_SIZE(mux_config_vme_pipe);
- n++;
-
- return n;
-}
-
static const struct i915_oa_reg b_counter_config_test_oa[] = {
{ _MMIO(0x2740), 0x00000000 },
{ _MMIO(0x2744), 0x00800000 },
@@ -1930,6 +60,7 @@ static const struct i915_oa_reg flex_eu_config_test_oa[] = {
};
static const struct i915_oa_reg mux_config_test_oa[] = {
+ { _MMIO(0x9840), 0x00000080 },
{ _MMIO(0x9888), 0x11810000 },
{ _MMIO(0x9888), 0x07810013 },
{ _MMIO(0x9888), 0x1f810000 },
@@ -1944,1096 +75,35 @@ static const struct i915_oa_reg mux_config_test_oa[] = {
{ _MMIO(0x9888), 0x33900000 },
};
-static int
-get_test_oa_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_test_oa;
- lens[n] = ARRAY_SIZE(mux_config_test_oa);
- n++;
-
- return n;
-}
-
-int i915_oa_select_metric_set_sklgt3(struct drm_i915_private *dev_priv)
-{
- dev_priv->perf.oa.n_mux_configs = 0;
- dev_priv->perf.oa.b_counter_regs = NULL;
- dev_priv->perf.oa.b_counter_regs_len = 0;
- dev_priv->perf.oa.flex_regs = NULL;
- dev_priv->perf.oa.flex_regs_len = 0;
-
- switch (dev_priv->perf.oa.metrics_set) {
- case METRIC_SET_ID_RENDER_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_render_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_basic);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_basic);
-
- return 0;
- case METRIC_SET_ID_RENDER_PIPE_PROFILE:
- dev_priv->perf.oa.n_mux_configs =
- get_render_pipe_profile_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_pipe_profile;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_pipe_profile);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_pipe_profile;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_pipe_profile);
-
- return 0;
- case METRIC_SET_ID_MEMORY_READS:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_reads_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_reads;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_reads);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_reads;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_reads);
-
- return 0;
- case METRIC_SET_ID_MEMORY_WRITES:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_writes_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_writes;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_writes);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_writes;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_writes);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTENDED:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extended_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extended;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extended);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extended;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extended);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_L3_CACHE:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_l3_cache_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_L3_CACHE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_l3_cache;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_l3_cache);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_l3_cache;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_l3_cache);
-
- return 0;
- case METRIC_SET_ID_HDC_AND_SF:
- dev_priv->perf.oa.n_mux_configs =
- get_hdc_and_sf_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_hdc_and_sf;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_hdc_and_sf);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_hdc_and_sf;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_hdc_and_sf);
-
- return 0;
- case METRIC_SET_ID_L3_1:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_1);
-
- return 0;
- case METRIC_SET_ID_L3_2:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_2);
-
- return 0;
- case METRIC_SET_ID_L3_3:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_3_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_3\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_3;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_3);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_3;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_3);
-
- return 0;
- case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND:
- dev_priv->perf.oa.n_mux_configs =
- get_rasterizer_and_pixel_backend_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend);
-
- return 0;
- case METRIC_SET_ID_SAMPLER:
- dev_priv->perf.oa.n_mux_configs =
- get_sampler_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_sampler;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_sampler);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_sampler;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_sampler);
-
- return 0;
- case METRIC_SET_ID_TDL_1:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_1);
-
- return 0;
- case METRIC_SET_ID_TDL_2:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_2);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTRA:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extra_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTRA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extra;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extra);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extra;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extra);
-
- return 0;
- case METRIC_SET_ID_VME_PIPE:
- dev_priv->perf.oa.n_mux_configs =
- get_vme_pipe_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"VME_PIPE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_vme_pipe;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_vme_pipe);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_vme_pipe;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_vme_pipe);
-
- return 0;
- case METRIC_SET_ID_TEST_OA:
- dev_priv->perf.oa.n_mux_configs =
- get_test_oa_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_test_oa;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_test_oa);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_test_oa;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_test_oa);
-
- return 0;
- default:
- return -ENODEV;
- }
-}
-
-static ssize_t
-show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC);
-}
-
-static struct device_attribute dev_attr_render_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_basic[] = {
- &dev_attr_render_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_basic = {
- .name = "4616d450-2393-4836-8146-53c5ed84d359",
- .attrs = attrs_render_basic,
-};
-
-static ssize_t
-show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC);
-}
-
-static struct device_attribute dev_attr_compute_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_basic[] = {
- &dev_attr_compute_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_basic = {
- .name = "4320492b-fd03-42ac-922f-dbe1ef3b7b58",
- .attrs = attrs_compute_basic,
-};
-
-static ssize_t
-show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE);
-}
-
-static struct device_attribute dev_attr_render_pipe_profile_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_pipe_profile_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_pipe_profile[] = {
- &dev_attr_render_pipe_profile_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_pipe_profile = {
- .name = "bd2d9cae-b9ec-4f5b-9d2f-934bed398a2d",
- .attrs = attrs_render_pipe_profile,
-};
-
-static ssize_t
-show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS);
-}
-
-static struct device_attribute dev_attr_memory_reads_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_reads_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_reads[] = {
- &dev_attr_memory_reads_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_reads = {
- .name = "4ca0f3fe-7fd3-4924-98cb-1807d9879767",
- .attrs = attrs_memory_reads,
-};
-
-static ssize_t
-show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES);
-}
-
-static struct device_attribute dev_attr_memory_writes_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_writes_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_writes[] = {
- &dev_attr_memory_writes_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_writes = {
- .name = "a0c0172c-ee13-403d-99ff-2bdf6936cf14",
- .attrs = attrs_memory_writes,
-};
-
-static ssize_t
-show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED);
-}
-
-static struct device_attribute dev_attr_compute_extended_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extended_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extended[] = {
- &dev_attr_compute_extended_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extended = {
- .name = "52435e0b-f188-42ea-8680-21a56ee20dee",
- .attrs = attrs_compute_extended,
-};
-
-static ssize_t
-show_compute_l3_cache_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_L3_CACHE);
-}
-
-static struct device_attribute dev_attr_compute_l3_cache_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_l3_cache_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_l3_cache[] = {
- &dev_attr_compute_l3_cache_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_l3_cache = {
- .name = "27076eeb-49f3-4fed-8423-c66506005c63",
- .attrs = attrs_compute_l3_cache,
-};
-
-static ssize_t
-show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF);
-}
-
-static struct device_attribute dev_attr_hdc_and_sf_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_hdc_and_sf_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_hdc_and_sf[] = {
- &dev_attr_hdc_and_sf_id.attr,
- NULL,
-};
-
-static struct attribute_group group_hdc_and_sf = {
- .name = "8071b409-c39a-4674-94d7-32962ecfb512",
- .attrs = attrs_hdc_and_sf,
-};
-
-static ssize_t
-show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1);
-}
-
-static struct device_attribute dev_attr_l3_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_1[] = {
- &dev_attr_l3_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_1 = {
- .name = "5e0b391e-9ea8-4901-b2ff-b64ff616c7ed",
- .attrs = attrs_l3_1,
-};
-
-static ssize_t
-show_l3_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_2);
-}
-
-static struct device_attribute dev_attr_l3_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_2[] = {
- &dev_attr_l3_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_2 = {
- .name = "25dc828e-1d2d-426e-9546-a1d4233cdf16",
- .attrs = attrs_l3_2,
-};
-
-static ssize_t
-show_l3_3_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_3);
-}
-
-static struct device_attribute dev_attr_l3_3_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_3_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_3[] = {
- &dev_attr_l3_3_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_3 = {
- .name = "3dba9405-2d7e-4d70-8199-e734e82fd6bf",
- .attrs = attrs_l3_3,
-};
-
-static ssize_t
-show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND);
-}
-
-static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_rasterizer_and_pixel_backend_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_rasterizer_and_pixel_backend[] = {
- &dev_attr_rasterizer_and_pixel_backend_id.attr,
- NULL,
-};
-
-static struct attribute_group group_rasterizer_and_pixel_backend = {
- .name = "76935d7b-09c9-46bf-87f1-c18b4a86ebe5",
- .attrs = attrs_rasterizer_and_pixel_backend,
-};
-
-static ssize_t
-show_sampler_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER);
-}
-
-static struct device_attribute dev_attr_sampler_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_sampler_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_sampler[] = {
- &dev_attr_sampler_id.attr,
- NULL,
-};
-
-static struct attribute_group group_sampler = {
- .name = "1b34c0d6-4f4c-4d7b-833f-4aaf236d87a6",
- .attrs = attrs_sampler,
-};
-
-static ssize_t
-show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1);
-}
-
-static struct device_attribute dev_attr_tdl_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_1[] = {
- &dev_attr_tdl_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_1 = {
- .name = "b375c985-9953-455b-bda2-b03f7594e9db",
- .attrs = attrs_tdl_1,
-};
-
-static ssize_t
-show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2);
-}
-
-static struct device_attribute dev_attr_tdl_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_2[] = {
- &dev_attr_tdl_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_2 = {
- .name = "3e2be2bb-884a-49bb-82c5-2358e6bd5f2d",
- .attrs = attrs_tdl_2,
-};
-
-static ssize_t
-show_compute_extra_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTRA);
-}
-
-static struct device_attribute dev_attr_compute_extra_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extra_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extra[] = {
- &dev_attr_compute_extra_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extra = {
- .name = "2d80a648-7b5a-4e92-bbe7-3b5c76f2e221",
- .attrs = attrs_compute_extra,
-};
-
-static ssize_t
-show_vme_pipe_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_VME_PIPE);
-}
-
-static struct device_attribute dev_attr_vme_pipe_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_vme_pipe_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_vme_pipe[] = {
- &dev_attr_vme_pipe_id.attr,
- NULL,
-};
-
-static struct attribute_group group_vme_pipe = {
- .name = "cfae9232-6ffc-42cc-a703-9790016925f0",
- .attrs = attrs_vme_pipe,
-};
-
static ssize_t
show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA);
+ return sprintf(buf, "1\n");
}
-static struct device_attribute dev_attr_test_oa_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_test_oa_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_test_oa[] = {
- &dev_attr_test_oa_id.attr,
- NULL,
-};
-
-static struct attribute_group group_test_oa = {
- .name = "2b985803-d3c9-4629-8a4f-634bfecba0e8",
- .attrs = attrs_test_oa,
-};
-
-int
-i915_perf_register_sysfs_sklgt3(struct drm_i915_private *dev_priv)
+void
+i915_perf_load_test_config_sklgt3(struct drm_i915_private *dev_priv)
{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
- int ret = 0;
+ strncpy(dev_priv->perf.oa.test_config.uuid,
+ "2b985803-d3c9-4629-8a4f-634bfecba0e8",
+ UUID_STRING_LEN);
+ dev_priv->perf.oa.test_config.id = 1;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (ret)
- goto error_render_basic;
- }
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (ret)
- goto error_compute_basic;
- }
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (ret)
- goto error_render_pipe_profile;
- }
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (ret)
- goto error_memory_reads;
- }
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (ret)
- goto error_memory_writes;
- }
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (ret)
- goto error_compute_extended;
- }
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (ret)
- goto error_compute_l3_cache;
- }
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (ret)
- goto error_hdc_and_sf;
- }
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (ret)
- goto error_l3_1;
- }
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (ret)
- goto error_l3_2;
- }
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (ret)
- goto error_l3_3;
- }
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (ret)
- goto error_rasterizer_and_pixel_backend;
- }
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (ret)
- goto error_sampler;
- }
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (ret)
- goto error_tdl_1;
- }
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (ret)
- goto error_tdl_2;
- }
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (ret)
- goto error_compute_extra;
- }
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
- if (ret)
- goto error_vme_pipe;
- }
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa);
- if (ret)
- goto error_test_oa;
- }
+ dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
+ dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
- return 0;
+ dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
+ dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-error_test_oa:
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
-error_vme_pipe:
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
-error_compute_extra:
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
-error_tdl_2:
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
-error_tdl_1:
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
-error_sampler:
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
-error_rasterizer_and_pixel_backend:
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
-error_l3_3:
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
-error_l3_2:
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
-error_l3_1:
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
-error_hdc_and_sf:
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
-error_compute_l3_cache:
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
-error_compute_extended:
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
-error_memory_writes:
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
-error_memory_reads:
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
-error_render_pipe_profile:
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
-error_compute_basic:
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
-error_render_basic:
- return ret;
-}
+ dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
+ dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-void
-i915_perf_unregister_sysfs_sklgt3(struct drm_i915_private *dev_priv)
-{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
+ dev_priv->perf.oa.test_config.sysfs_metric.name = "2b985803-d3c9-4629-8a4f-634bfecba0e8";
+ dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+
+ dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa);
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
+ dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
}
diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt3.h b/drivers/gpu/drm/i915/i915_oa_sklgt3.h
index c0accb1..06746b2 100644
--- a/drivers/gpu/drm/i915/i915_oa_sklgt3.h
+++ b/drivers/gpu/drm/i915/i915_oa_sklgt3.h
@@ -29,12 +29,6 @@
#ifndef __I915_OA_SKLGT3_H__
#define __I915_OA_SKLGT3_H__
-extern int i915_oa_n_builtin_metric_sets_sklgt3;
-
-extern int i915_oa_select_metric_set_sklgt3(struct drm_i915_private *dev_priv);
-
-extern int i915_perf_register_sysfs_sklgt3(struct drm_i915_private *dev_priv);
-
-extern void i915_perf_unregister_sysfs_sklgt3(struct drm_i915_private *dev_priv);
+extern void i915_perf_load_test_config_sklgt3(struct drm_i915_private *dev_priv);
#endif
diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt4.c b/drivers/gpu/drm/i915/i915_oa_sklgt4.c
index 9ddab43..bce031e 100644
--- a/drivers/gpu/drm/i915/i915_oa_sklgt4.c
+++ b/drivers/gpu/drm/i915/i915_oa_sklgt4.c
@@ -31,1930 +31,6 @@
#include "i915_drv.h"
#include "i915_oa_sklgt4.h"
-enum metric_set_id {
- METRIC_SET_ID_RENDER_BASIC = 1,
- METRIC_SET_ID_COMPUTE_BASIC,
- METRIC_SET_ID_RENDER_PIPE_PROFILE,
- METRIC_SET_ID_MEMORY_READS,
- METRIC_SET_ID_MEMORY_WRITES,
- METRIC_SET_ID_COMPUTE_EXTENDED,
- METRIC_SET_ID_COMPUTE_L3_CACHE,
- METRIC_SET_ID_HDC_AND_SF,
- METRIC_SET_ID_L3_1,
- METRIC_SET_ID_L3_2,
- METRIC_SET_ID_L3_3,
- METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND,
- METRIC_SET_ID_SAMPLER,
- METRIC_SET_ID_TDL_1,
- METRIC_SET_ID_TDL_2,
- METRIC_SET_ID_COMPUTE_EXTRA,
- METRIC_SET_ID_VME_PIPE,
- METRIC_SET_ID_TEST_OA,
-};
-
-int i915_oa_n_builtin_metric_sets_sklgt4 = 18;
-
-static const struct i915_oa_reg b_counter_config_render_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_render_basic[] = {
- { _MMIO(0x9888), 0x166c01e0 },
- { _MMIO(0x9888), 0x12170280 },
- { _MMIO(0x9888), 0x12370280 },
- { _MMIO(0x9888), 0x16ec01e0 },
- { _MMIO(0x9888), 0x176c01e0 },
- { _MMIO(0x9888), 0x11930317 },
- { _MMIO(0x9888), 0x159303df },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x1a4e03b0 },
- { _MMIO(0x9888), 0x0a6c0053 },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x0a1b4000 },
- { _MMIO(0x9888), 0x1c1c0001 },
- { _MMIO(0x9888), 0x002f1000 },
- { _MMIO(0x9888), 0x042f1000 },
- { _MMIO(0x9888), 0x004c4000 },
- { _MMIO(0x9888), 0x0a4ca400 },
- { _MMIO(0x9888), 0x0c4c0002 },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f5600 },
- { _MMIO(0x9888), 0x100f0001 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x162caa00 },
- { _MMIO(0x9888), 0x062d8000 },
- { _MMIO(0x9888), 0x00133000 },
- { _MMIO(0x9888), 0x08133000 },
- { _MMIO(0x9888), 0x00170020 },
- { _MMIO(0x9888), 0x08170021 },
- { _MMIO(0x9888), 0x10170000 },
- { _MMIO(0x9888), 0x0633c000 },
- { _MMIO(0x9888), 0x06370800 },
- { _MMIO(0x9888), 0x10370000 },
- { _MMIO(0x9888), 0x1ace0230 },
- { _MMIO(0x9888), 0x0aec5300 },
- { _MMIO(0x9888), 0x10ec0000 },
- { _MMIO(0x9888), 0x1cec0000 },
- { _MMIO(0x9888), 0x0a9b8000 },
- { _MMIO(0x9888), 0x1c9c0002 },
- { _MMIO(0x9888), 0x0acc2000 },
- { _MMIO(0x9888), 0x0ccc0002 },
- { _MMIO(0x9888), 0x088d8000 },
- { _MMIO(0x9888), 0x0a8d8000 },
- { _MMIO(0x9888), 0x0e8f1000 },
- { _MMIO(0x9888), 0x108f0001 },
- { _MMIO(0x9888), 0x16ac8800 },
- { _MMIO(0x9888), 0x1b4e0020 },
- { _MMIO(0x9888), 0x096c5300 },
- { _MMIO(0x9888), 0x116c0000 },
- { _MMIO(0x9888), 0x1d6c0000 },
- { _MMIO(0x9888), 0x091b8000 },
- { _MMIO(0x9888), 0x1b1c8000 },
- { _MMIO(0x9888), 0x0b4c2000 },
- { _MMIO(0x9888), 0x090d8000 },
- { _MMIO(0x9888), 0x0f0f1000 },
- { _MMIO(0x9888), 0x172c0800 },
- { _MMIO(0x9888), 0x0d933031 },
- { _MMIO(0x9888), 0x0f933e3f },
- { _MMIO(0x9888), 0x01933d00 },
- { _MMIO(0x9888), 0x0393073c },
- { _MMIO(0x9888), 0x0593000e },
- { _MMIO(0x9888), 0x1d930000 },
- { _MMIO(0x9888), 0x19930000 },
- { _MMIO(0x9888), 0x1b930000 },
- { _MMIO(0x9888), 0x1d900157 },
- { _MMIO(0x9888), 0x1f900158 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x2b908000 },
- { _MMIO(0x9888), 0x2d908000 },
- { _MMIO(0x9888), 0x2f908000 },
- { _MMIO(0x9888), 0x31908000 },
- { _MMIO(0x9888), 0x15908000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1190003f },
- { _MMIO(0x9888), 0x5190ff30 },
- { _MMIO(0x9888), 0x41900060 },
- { _MMIO(0x9888), 0x55903033 },
- { _MMIO(0x9888), 0x45901421 },
- { _MMIO(0x9888), 0x47900803 },
- { _MMIO(0x9888), 0x5790fff1 },
- { _MMIO(0x9888), 0x49900001 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x5990000f },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x5390ffff },
-};
-
-static int
-get_render_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_basic;
- lens[n] = ARRAY_SIZE(mux_config_render_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_basic[] = {
- { _MMIO(0x9888), 0x104f00e0 },
- { _MMIO(0x9888), 0x124f1c00 },
- { _MMIO(0x9888), 0x106c00e0 },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x1a4e0820 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x064f0900 },
- { _MMIO(0x9888), 0x084f0032 },
- { _MMIO(0x9888), 0x0a4f1891 },
- { _MMIO(0x9888), 0x0c4f0e00 },
- { _MMIO(0x9888), 0x0e4f003c },
- { _MMIO(0x9888), 0x004f0d80 },
- { _MMIO(0x9888), 0x024f003b },
- { _MMIO(0x9888), 0x006c0002 },
- { _MMIO(0x9888), 0x086c0100 },
- { _MMIO(0x9888), 0x0c6c000c },
- { _MMIO(0x9888), 0x0e6c0b00 },
- { _MMIO(0x9888), 0x186c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x001b4000 },
- { _MMIO(0x9888), 0x081b8000 },
- { _MMIO(0x9888), 0x0c1b4000 },
- { _MMIO(0x9888), 0x0e1b8000 },
- { _MMIO(0x9888), 0x101c8000 },
- { _MMIO(0x9888), 0x1a1c8000 },
- { _MMIO(0x9888), 0x1c1c0024 },
- { _MMIO(0x9888), 0x065b8000 },
- { _MMIO(0x9888), 0x085b4000 },
- { _MMIO(0x9888), 0x0a5bc000 },
- { _MMIO(0x9888), 0x0c5b8000 },
- { _MMIO(0x9888), 0x0e5b4000 },
- { _MMIO(0x9888), 0x005b8000 },
- { _MMIO(0x9888), 0x025b4000 },
- { _MMIO(0x9888), 0x1a5c6000 },
- { _MMIO(0x9888), 0x1c5c001b },
- { _MMIO(0x9888), 0x125c8000 },
- { _MMIO(0x9888), 0x145c8000 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4c2000 },
- { _MMIO(0x9888), 0x0c4c0208 },
- { _MMIO(0x9888), 0x000da000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x020d2000 },
- { _MMIO(0x9888), 0x0c0f5400 },
- { _MMIO(0x9888), 0x0e0f5500 },
- { _MMIO(0x9888), 0x100f0155 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2cc000 },
- { _MMIO(0x9888), 0x162cfb00 },
- { _MMIO(0x9888), 0x182c00be },
- { _MMIO(0x9888), 0x022cc000 },
- { _MMIO(0x9888), 0x042cc000 },
- { _MMIO(0x9888), 0x19900157 },
- { _MMIO(0x9888), 0x1b900158 },
- { _MMIO(0x9888), 0x1d900105 },
- { _MMIO(0x9888), 0x1f900103 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x11900fff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900821 },
- { _MMIO(0x9888), 0x47900802 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900802 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900002 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900422 },
- { _MMIO(0x9888), 0x53905555 },
-};
-
-static int
-get_compute_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_basic;
- lens[n] = ARRAY_SIZE(mux_config_compute_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007ffea },
- { _MMIO(0x2774), 0x00007ffc },
- { _MMIO(0x2778), 0x0007affa },
- { _MMIO(0x277c), 0x0000f5fd },
- { _MMIO(0x2780), 0x00079ffa },
- { _MMIO(0x2784), 0x0000f3fb },
- { _MMIO(0x2788), 0x0007bf7a },
- { _MMIO(0x278c), 0x0000f7e7 },
- { _MMIO(0x2790), 0x0007fefa },
- { _MMIO(0x2794), 0x0000f7cf },
- { _MMIO(0x2798), 0x00077ffa },
- { _MMIO(0x279c), 0x0000efdf },
- { _MMIO(0x27a0), 0x0006fffa },
- { _MMIO(0x27a4), 0x0000cfbf },
- { _MMIO(0x27a8), 0x0003fffa },
- { _MMIO(0x27ac), 0x00005f7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_render_pipe_profile[] = {
- { _MMIO(0x9888), 0x0c0e001f },
- { _MMIO(0x9888), 0x0a0f0000 },
- { _MMIO(0x9888), 0x10116800 },
- { _MMIO(0x9888), 0x178a03e0 },
- { _MMIO(0x9888), 0x11824c00 },
- { _MMIO(0x9888), 0x11830020 },
- { _MMIO(0x9888), 0x13840020 },
- { _MMIO(0x9888), 0x11850019 },
- { _MMIO(0x9888), 0x11860007 },
- { _MMIO(0x9888), 0x01870c40 },
- { _MMIO(0x9888), 0x17880000 },
- { _MMIO(0x9888), 0x022f4000 },
- { _MMIO(0x9888), 0x0a4c0040 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x040d4000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x020e5400 },
- { _MMIO(0x9888), 0x000e0000 },
- { _MMIO(0x9888), 0x080f0040 },
- { _MMIO(0x9888), 0x000f0000 },
- { _MMIO(0x9888), 0x100f0000 },
- { _MMIO(0x9888), 0x0e0f0040 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x06104000 },
- { _MMIO(0x9888), 0x06110012 },
- { _MMIO(0x9888), 0x06131000 },
- { _MMIO(0x9888), 0x01898000 },
- { _MMIO(0x9888), 0x0d890100 },
- { _MMIO(0x9888), 0x03898000 },
- { _MMIO(0x9888), 0x09808000 },
- { _MMIO(0x9888), 0x0b808000 },
- { _MMIO(0x9888), 0x0380c000 },
- { _MMIO(0x9888), 0x0f8a0075 },
- { _MMIO(0x9888), 0x1d8a0000 },
- { _MMIO(0x9888), 0x118a8000 },
- { _MMIO(0x9888), 0x1b8a4000 },
- { _MMIO(0x9888), 0x138a8000 },
- { _MMIO(0x9888), 0x1d81a000 },
- { _MMIO(0x9888), 0x15818000 },
- { _MMIO(0x9888), 0x17818000 },
- { _MMIO(0x9888), 0x0b820030 },
- { _MMIO(0x9888), 0x07828000 },
- { _MMIO(0x9888), 0x0d824000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x05824000 },
- { _MMIO(0x9888), 0x0d830003 },
- { _MMIO(0x9888), 0x0583000c },
- { _MMIO(0x9888), 0x09830000 },
- { _MMIO(0x9888), 0x03838000 },
- { _MMIO(0x9888), 0x07838000 },
- { _MMIO(0x9888), 0x0b840980 },
- { _MMIO(0x9888), 0x03844d80 },
- { _MMIO(0x9888), 0x11840000 },
- { _MMIO(0x9888), 0x09848000 },
- { _MMIO(0x9888), 0x09850080 },
- { _MMIO(0x9888), 0x03850003 },
- { _MMIO(0x9888), 0x01850000 },
- { _MMIO(0x9888), 0x07860000 },
- { _MMIO(0x9888), 0x0f860400 },
- { _MMIO(0x9888), 0x09870032 },
- { _MMIO(0x9888), 0x01888052 },
- { _MMIO(0x9888), 0x11880000 },
- { _MMIO(0x9888), 0x09884000 },
- { _MMIO(0x9888), 0x1b931001 },
- { _MMIO(0x9888), 0x1d930001 },
- { _MMIO(0x9888), 0x19934000 },
- { _MMIO(0x9888), 0x1b958000 },
- { _MMIO(0x9888), 0x1d950094 },
- { _MMIO(0x9888), 0x19958000 },
- { _MMIO(0x9888), 0x09e58000 },
- { _MMIO(0x9888), 0x0be58000 },
- { _MMIO(0x9888), 0x03e5c000 },
- { _MMIO(0x9888), 0x0592c000 },
- { _MMIO(0x9888), 0x0b928000 },
- { _MMIO(0x9888), 0x0d924000 },
- { _MMIO(0x9888), 0x0f924000 },
- { _MMIO(0x9888), 0x11928000 },
- { _MMIO(0x9888), 0x1392c000 },
- { _MMIO(0x9888), 0x09924000 },
- { _MMIO(0x9888), 0x01985000 },
- { _MMIO(0x9888), 0x07988000 },
- { _MMIO(0x9888), 0x09981000 },
- { _MMIO(0x9888), 0x0b982000 },
- { _MMIO(0x9888), 0x0d982000 },
- { _MMIO(0x9888), 0x0f989000 },
- { _MMIO(0x9888), 0x05982000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x23904000 },
- { _MMIO(0x9888), 0x25908000 },
- { _MMIO(0x9888), 0x27904000 },
- { _MMIO(0x9888), 0x29908000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1190c080 },
- { _MMIO(0x9888), 0x51901110 },
- { _MMIO(0x9888), 0x41900440 },
- { _MMIO(0x9888), 0x55901111 },
- { _MMIO(0x9888), 0x45900400 },
- { _MMIO(0x9888), 0x47900c21 },
- { _MMIO(0x9888), 0x57901411 },
- { _MMIO(0x9888), 0x49900042 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900024 },
- { _MMIO(0x9888), 0x59900001 },
- { _MMIO(0x9888), 0x43900841 },
- { _MMIO(0x9888), 0x53900411 },
-};
-
-static int
-get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_pipe_profile;
- lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_reads[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f872 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_reads[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_reads[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f900064 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x1b930055 },
- { _MMIO(0x9888), 0x03e58000 },
- { _MMIO(0x9888), 0x05e5c000 },
- { _MMIO(0x9888), 0x07e54000 },
- { _MMIO(0x9888), 0x13900150 },
- { _MMIO(0x9888), 0x21900151 },
- { _MMIO(0x9888), 0x23900152 },
- { _MMIO(0x9888), 0x25900153 },
- { _MMIO(0x9888), 0x27900154 },
- { _MMIO(0x9888), 0x29900155 },
- { _MMIO(0x9888), 0x2b900156 },
- { _MMIO(0x9888), 0x2d900157 },
- { _MMIO(0x9888), 0x2f90015f },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c60 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900c00 },
- { _MMIO(0x9888), 0x47900c63 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900c63 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_memory_reads_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_reads;
- lens[n] = ARRAY_SIZE(mux_config_memory_reads);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_writes[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f822 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_writes[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_writes[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f901000 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x1b930055 },
- { _MMIO(0x9888), 0x03e58000 },
- { _MMIO(0x9888), 0x05e5c000 },
- { _MMIO(0x9888), 0x07e54000 },
- { _MMIO(0x9888), 0x13900160 },
- { _MMIO(0x9888), 0x21900161 },
- { _MMIO(0x9888), 0x23900162 },
- { _MMIO(0x9888), 0x25900163 },
- { _MMIO(0x9888), 0x27900164 },
- { _MMIO(0x9888), 0x29900165 },
- { _MMIO(0x9888), 0x2b900166 },
- { _MMIO(0x9888), 0x2d900167 },
- { _MMIO(0x9888), 0x2f900150 },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c60 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900c00 },
- { _MMIO(0x9888), 0x47900c63 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900c63 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_memory_writes_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_writes;
- lens[n] = ARRAY_SIZE(mux_config_memory_writes);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extended[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fc2a },
- { _MMIO(0x2774), 0x0000bf00 },
- { _MMIO(0x2778), 0x0007fc6a },
- { _MMIO(0x277c), 0x0000bf00 },
- { _MMIO(0x2780), 0x0007fc92 },
- { _MMIO(0x2784), 0x0000bf00 },
- { _MMIO(0x2788), 0x0007fca2 },
- { _MMIO(0x278c), 0x0000bf00 },
- { _MMIO(0x2790), 0x0007fc32 },
- { _MMIO(0x2794), 0x0000bf00 },
- { _MMIO(0x2798), 0x0007fc9a },
- { _MMIO(0x279c), 0x0000bf00 },
- { _MMIO(0x27a0), 0x0007fe6a },
- { _MMIO(0x27a4), 0x0000bf00 },
- { _MMIO(0x27a8), 0x0007fe7a },
- { _MMIO(0x27ac), 0x0000bf00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extended[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended[] = {
- { _MMIO(0x9888), 0x106c00e0 },
- { _MMIO(0x9888), 0x141c8160 },
- { _MMIO(0x9888), 0x161c8015 },
- { _MMIO(0x9888), 0x181c0120 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x184e8000 },
- { _MMIO(0x9888), 0x1a4eaaa0 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x024e8000 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0e6c0b01 },
- { _MMIO(0x9888), 0x006c0200 },
- { _MMIO(0x9888), 0x026c000c },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x001b8000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x001c0041 },
- { _MMIO(0x9888), 0x061c4200 },
- { _MMIO(0x9888), 0x081c4443 },
- { _MMIO(0x9888), 0x0a1c4645 },
- { _MMIO(0x9888), 0x0c1c7647 },
- { _MMIO(0x9888), 0x041c7357 },
- { _MMIO(0x9888), 0x1c1c0030 },
- { _MMIO(0x9888), 0x101c0000 },
- { _MMIO(0x9888), 0x1a1c0000 },
- { _MMIO(0x9888), 0x121c8000 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4caa2a },
- { _MMIO(0x9888), 0x0c4c02aa },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x000da000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x0c0f5400 },
- { _MMIO(0x9888), 0x0e0f5515 },
- { _MMIO(0x9888), 0x100f0155 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162caa00 },
- { _MMIO(0x9888), 0x182c00aa },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x11907fff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900040 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900802 },
- { _MMIO(0x9888), 0x47900842 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900842 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900800 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_compute_extended_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extended;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_l3_cache[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fffa },
- { _MMIO(0x2774), 0x0000fefe },
- { _MMIO(0x2778), 0x0007fffa },
- { _MMIO(0x277c), 0x0000fefd },
- { _MMIO(0x2790), 0x0007fffa },
- { _MMIO(0x2794), 0x0000fbef },
- { _MMIO(0x2798), 0x0007fffa },
- { _MMIO(0x279c), 0x0000fbdf },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_l3_cache[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00101100 },
- { _MMIO(0xe45c), 0x00201200 },
- { _MMIO(0xe55c), 0x00301300 },
- { _MMIO(0xe65c), 0x00401400 },
-};
-
-static const struct i915_oa_reg mux_config_compute_l3_cache[] = {
- { _MMIO(0x9888), 0x166c0760 },
- { _MMIO(0x9888), 0x1593001e },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x184e8000 },
- { _MMIO(0x9888), 0x1a4e8020 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x006c0051 },
- { _MMIO(0x9888), 0x066c5000 },
- { _MMIO(0x9888), 0x086c5c5d },
- { _MMIO(0x9888), 0x0e6c5e5f },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x186c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x001b4000 },
- { _MMIO(0x9888), 0x061b8000 },
- { _MMIO(0x9888), 0x081bc000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x101c8000 },
- { _MMIO(0x9888), 0x1a1ce000 },
- { _MMIO(0x9888), 0x1c1c0030 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4c2a00 },
- { _MMIO(0x9888), 0x0c4c0280 },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f1500 },
- { _MMIO(0x9888), 0x100f0140 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162c0a00 },
- { _MMIO(0x9888), 0x182c00a0 },
- { _MMIO(0x9888), 0x03933300 },
- { _MMIO(0x9888), 0x05930032 },
- { _MMIO(0x9888), 0x11930000 },
- { _MMIO(0x9888), 0x1b930000 },
- { _MMIO(0x9888), 0x1d900157 },
- { _MMIO(0x9888), 0x1f900158 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1190030f },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900000 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900021 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x53905555 },
- { _MMIO(0x9888), 0x43900000 },
-};
-
-static int
-get_compute_l3_cache_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_l3_cache;
- lens[n] = ARRAY_SIZE(mux_config_compute_l3_cache);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x10800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fdff },
-};
-
-static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_hdc_and_sf[] = {
- { _MMIO(0x9888), 0x104f0232 },
- { _MMIO(0x9888), 0x124f4640 },
- { _MMIO(0x9888), 0x106c0232 },
- { _MMIO(0x9888), 0x11834400 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0c4e8000 },
- { _MMIO(0x9888), 0x004f1880 },
- { _MMIO(0x9888), 0x024f08bb },
- { _MMIO(0x9888), 0x044f001b },
- { _MMIO(0x9888), 0x046c0100 },
- { _MMIO(0x9888), 0x066c000b },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x041b8000 },
- { _MMIO(0x9888), 0x061b4000 },
- { _MMIO(0x9888), 0x1a1c1800 },
- { _MMIO(0x9888), 0x005b8000 },
- { _MMIO(0x9888), 0x025bc000 },
- { _MMIO(0x9888), 0x045b4000 },
- { _MMIO(0x9888), 0x125c8000 },
- { _MMIO(0x9888), 0x145c8000 },
- { _MMIO(0x9888), 0x165c8000 },
- { _MMIO(0x9888), 0x185c8000 },
- { _MMIO(0x9888), 0x0a4c00a0 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x022cc000 },
- { _MMIO(0x9888), 0x042cc000 },
- { _MMIO(0x9888), 0x062cc000 },
- { _MMIO(0x9888), 0x082cc000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x0f8305c0 },
- { _MMIO(0x9888), 0x09830000 },
- { _MMIO(0x9888), 0x07830000 },
- { _MMIO(0x9888), 0x1d950080 },
- { _MMIO(0x9888), 0x13928000 },
- { _MMIO(0x9888), 0x0f988000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x59900001 },
- { _MMIO(0x9888), 0x4b900040 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_hdc_and_sf;
- lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_1[] = {
- { _MMIO(0x9888), 0x126c7b40 },
- { _MMIO(0x9888), 0x166c0020 },
- { _MMIO(0x9888), 0x0a603444 },
- { _MMIO(0x9888), 0x0a613400 },
- { _MMIO(0x9888), 0x1a4ea800 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x024e8000 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x064f4000 },
- { _MMIO(0x9888), 0x0c6c5327 },
- { _MMIO(0x9888), 0x0e6c5425 },
- { _MMIO(0x9888), 0x006c2a00 },
- { _MMIO(0x9888), 0x026c285b },
- { _MMIO(0x9888), 0x046c005c },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x1a6c0800 },
- { _MMIO(0x9888), 0x0c1bc000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x001b8000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x1c1c003c },
- { _MMIO(0x9888), 0x121c8000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c0800 },
- { _MMIO(0x9888), 0x065b4000 },
- { _MMIO(0x9888), 0x1a5c1000 },
- { _MMIO(0x9888), 0x10600000 },
- { _MMIO(0x9888), 0x04600000 },
- { _MMIO(0x9888), 0x0c610044 },
- { _MMIO(0x9888), 0x10610000 },
- { _MMIO(0x9888), 0x06610000 },
- { _MMIO(0x9888), 0x0c4c02a8 },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x0a4c002a },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f0154 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x182c00aa },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2cc000 },
- { _MMIO(0x9888), 0x1190ffc0 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900420 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900021 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900400 },
- { _MMIO(0x9888), 0x43900421 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
-};
-
-static int
-get_l3_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_1;
- lens[n] = ARRAY_SIZE(mux_config_l3_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00028002 },
- { _MMIO(0x277c), 0x000087ff },
- { _MMIO(0x2780), 0x00020002 },
- { _MMIO(0x2784), 0x00008fff },
- { _MMIO(0x2788), 0x00008002 },
- { _MMIO(0x278c), 0x0000a7ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_2[] = {
- { _MMIO(0x9888), 0x126c02e0 },
- { _MMIO(0x9888), 0x146c0001 },
- { _MMIO(0x9888), 0x0a623400 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x064f4000 },
- { _MMIO(0x9888), 0x026c3324 },
- { _MMIO(0x9888), 0x046c3422 },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c0800 },
- { _MMIO(0x9888), 0x065b4000 },
- { _MMIO(0x9888), 0x1a5c1000 },
- { _MMIO(0x9888), 0x06614000 },
- { _MMIO(0x9888), 0x0c620044 },
- { _MMIO(0x9888), 0x10620000 },
- { _MMIO(0x9888), 0x06620000 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x0a4c002a },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f4000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2cc000 },
- { _MMIO(0x9888), 0x1190f800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_l3_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_2;
- lens[n] = ARRAY_SIZE(mux_config_l3_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_3[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00028002 },
- { _MMIO(0x277c), 0x000087ff },
- { _MMIO(0x2780), 0x00020002 },
- { _MMIO(0x2784), 0x00008fff },
- { _MMIO(0x2788), 0x00008002 },
- { _MMIO(0x278c), 0x0000a7ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_3[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_3[] = {
- { _MMIO(0x9888), 0x126c4e80 },
- { _MMIO(0x9888), 0x146c0000 },
- { _MMIO(0x9888), 0x0a633400 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0c4e8000 },
- { _MMIO(0x9888), 0x026c3321 },
- { _MMIO(0x9888), 0x046c342f },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1a6c2000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x061b4000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c1800 },
- { _MMIO(0x9888), 0x06604000 },
- { _MMIO(0x9888), 0x0c630044 },
- { _MMIO(0x9888), 0x10630000 },
- { _MMIO(0x9888), 0x06630000 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x0a4c00aa },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f4000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x1190f800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900002 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_l3_3_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_3;
- lens[n] = ARRAY_SIZE(mux_config_l3_3);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000efff },
- { _MMIO(0x2778), 0x00006000 },
- { _MMIO(0x277c), 0x0000f3ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x9888), 0x102f3800 },
- { _MMIO(0x9888), 0x144d0500 },
- { _MMIO(0x9888), 0x120d03c0 },
- { _MMIO(0x9888), 0x140d03cf },
- { _MMIO(0x9888), 0x0c0f0004 },
- { _MMIO(0x9888), 0x0c4e4000 },
- { _MMIO(0x9888), 0x042f0480 },
- { _MMIO(0x9888), 0x082f0000 },
- { _MMIO(0x9888), 0x022f0000 },
- { _MMIO(0x9888), 0x0a4c0090 },
- { _MMIO(0x9888), 0x064d0027 },
- { _MMIO(0x9888), 0x004d0000 },
- { _MMIO(0x9888), 0x000d0d40 },
- { _MMIO(0x9888), 0x020d803f },
- { _MMIO(0x9888), 0x040d8023 },
- { _MMIO(0x9888), 0x100d0000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x020f0010 },
- { _MMIO(0x9888), 0x000f0000 },
- { _MMIO(0x9888), 0x0e0f0050 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41901400 },
- { _MMIO(0x9888), 0x43901485 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900001 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_rasterizer_and_pixel_backend;
- lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_sampler[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x70800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x0000c000 },
- { _MMIO(0x2774), 0x0000e7ff },
- { _MMIO(0x2778), 0x00003000 },
- { _MMIO(0x277c), 0x0000f9ff },
- { _MMIO(0x2780), 0x00000c00 },
- { _MMIO(0x2784), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_sampler[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_sampler[] = {
- { _MMIO(0x9888), 0x14152c00 },
- { _MMIO(0x9888), 0x16150005 },
- { _MMIO(0x9888), 0x121600a0 },
- { _MMIO(0x9888), 0x14352c00 },
- { _MMIO(0x9888), 0x16350005 },
- { _MMIO(0x9888), 0x123600a0 },
- { _MMIO(0x9888), 0x14552c00 },
- { _MMIO(0x9888), 0x16550005 },
- { _MMIO(0x9888), 0x125600a0 },
- { _MMIO(0x9888), 0x062f6000 },
- { _MMIO(0x9888), 0x022f2000 },
- { _MMIO(0x9888), 0x0c4c0050 },
- { _MMIO(0x9888), 0x0a4c0010 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f0350 },
- { _MMIO(0x9888), 0x0c0fb000 },
- { _MMIO(0x9888), 0x0e0f00da },
- { _MMIO(0x9888), 0x182c0028 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x022dc000 },
- { _MMIO(0x9888), 0x042d4000 },
- { _MMIO(0x9888), 0x0c138000 },
- { _MMIO(0x9888), 0x0e132000 },
- { _MMIO(0x9888), 0x0413c000 },
- { _MMIO(0x9888), 0x1c140018 },
- { _MMIO(0x9888), 0x0c157000 },
- { _MMIO(0x9888), 0x0e150078 },
- { _MMIO(0x9888), 0x10150000 },
- { _MMIO(0x9888), 0x04162180 },
- { _MMIO(0x9888), 0x02160000 },
- { _MMIO(0x9888), 0x04174000 },
- { _MMIO(0x9888), 0x0233a000 },
- { _MMIO(0x9888), 0x04333000 },
- { _MMIO(0x9888), 0x14348000 },
- { _MMIO(0x9888), 0x16348000 },
- { _MMIO(0x9888), 0x02357870 },
- { _MMIO(0x9888), 0x10350000 },
- { _MMIO(0x9888), 0x04360043 },
- { _MMIO(0x9888), 0x02360000 },
- { _MMIO(0x9888), 0x04371000 },
- { _MMIO(0x9888), 0x0e538000 },
- { _MMIO(0x9888), 0x00538000 },
- { _MMIO(0x9888), 0x06533000 },
- { _MMIO(0x9888), 0x1c540020 },
- { _MMIO(0x9888), 0x12548000 },
- { _MMIO(0x9888), 0x0e557000 },
- { _MMIO(0x9888), 0x00557800 },
- { _MMIO(0x9888), 0x10550000 },
- { _MMIO(0x9888), 0x06560043 },
- { _MMIO(0x9888), 0x02560000 },
- { _MMIO(0x9888), 0x06571000 },
- { _MMIO(0x9888), 0x1190ff80 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900060 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900060 },
-};
-
-static int
-get_sampler_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_sampler;
- lens[n] = ARRAY_SIZE(mux_config_sampler);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x00007fff },
- { _MMIO(0x2778), 0x00000000 },
- { _MMIO(0x277c), 0x00009fff },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000efff },
- { _MMIO(0x2788), 0x00000000 },
- { _MMIO(0x278c), 0x0000f3ff },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000fdff },
- { _MMIO(0x2798), 0x00000000 },
- { _MMIO(0x279c), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_1[] = {
- { _MMIO(0x9888), 0x12120000 },
- { _MMIO(0x9888), 0x12320000 },
- { _MMIO(0x9888), 0x12520000 },
- { _MMIO(0x9888), 0x002f8000 },
- { _MMIO(0x9888), 0x022f3000 },
- { _MMIO(0x9888), 0x0a4c0015 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f03a0 },
- { _MMIO(0x9888), 0x0c0ff000 },
- { _MMIO(0x9888), 0x0e0f0095 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2d8000 },
- { _MMIO(0x9888), 0x0e2d4000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x02108000 },
- { _MMIO(0x9888), 0x0410c000 },
- { _MMIO(0x9888), 0x02118000 },
- { _MMIO(0x9888), 0x0411c000 },
- { _MMIO(0x9888), 0x02121880 },
- { _MMIO(0x9888), 0x041219b5 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x02134000 },
- { _MMIO(0x9888), 0x04135000 },
- { _MMIO(0x9888), 0x0c308000 },
- { _MMIO(0x9888), 0x0e304000 },
- { _MMIO(0x9888), 0x06304000 },
- { _MMIO(0x9888), 0x0c318000 },
- { _MMIO(0x9888), 0x0e314000 },
- { _MMIO(0x9888), 0x06314000 },
- { _MMIO(0x9888), 0x0c321a80 },
- { _MMIO(0x9888), 0x0e320033 },
- { _MMIO(0x9888), 0x06320031 },
- { _MMIO(0x9888), 0x00320000 },
- { _MMIO(0x9888), 0x0c334000 },
- { _MMIO(0x9888), 0x0e331000 },
- { _MMIO(0x9888), 0x06331000 },
- { _MMIO(0x9888), 0x0e508000 },
- { _MMIO(0x9888), 0x00508000 },
- { _MMIO(0x9888), 0x02504000 },
- { _MMIO(0x9888), 0x0e518000 },
- { _MMIO(0x9888), 0x00518000 },
- { _MMIO(0x9888), 0x02514000 },
- { _MMIO(0x9888), 0x0e521880 },
- { _MMIO(0x9888), 0x00521a80 },
- { _MMIO(0x9888), 0x02520033 },
- { _MMIO(0x9888), 0x0e534000 },
- { _MMIO(0x9888), 0x00534000 },
- { _MMIO(0x9888), 0x02531000 },
- { _MMIO(0x9888), 0x1190ff80 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900062 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
-};
-
-static int
-get_tdl_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_1;
- lens[n] = ARRAY_SIZE(mux_config_tdl_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_2[] = {
- { _MMIO(0x9888), 0x12124d60 },
- { _MMIO(0x9888), 0x12322e60 },
- { _MMIO(0x9888), 0x12524d60 },
- { _MMIO(0x9888), 0x022f3000 },
- { _MMIO(0x9888), 0x0a4c0014 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0fe000 },
- { _MMIO(0x9888), 0x0e0f0097 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x002d8000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x0410c000 },
- { _MMIO(0x9888), 0x0411c000 },
- { _MMIO(0x9888), 0x04121fb7 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x04135000 },
- { _MMIO(0x9888), 0x00308000 },
- { _MMIO(0x9888), 0x06304000 },
- { _MMIO(0x9888), 0x00318000 },
- { _MMIO(0x9888), 0x06314000 },
- { _MMIO(0x9888), 0x00321b80 },
- { _MMIO(0x9888), 0x0632003f },
- { _MMIO(0x9888), 0x00334000 },
- { _MMIO(0x9888), 0x06331000 },
- { _MMIO(0x9888), 0x0250c000 },
- { _MMIO(0x9888), 0x0251c000 },
- { _MMIO(0x9888), 0x02521fb7 },
- { _MMIO(0x9888), 0x00520000 },
- { _MMIO(0x9888), 0x02535000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x43900063 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_tdl_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_2;
- lens[n] = ARRAY_SIZE(mux_config_tdl_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extra[] = {
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extra[] = {
-};
-
-static const struct i915_oa_reg mux_config_compute_extra[] = {
- { _MMIO(0x9888), 0x121203e0 },
- { _MMIO(0x9888), 0x123203e0 },
- { _MMIO(0x9888), 0x125203e0 },
- { _MMIO(0x9888), 0x129203e0 },
- { _MMIO(0x9888), 0x12b203e0 },
- { _MMIO(0x9888), 0x12d203e0 },
- { _MMIO(0x9888), 0x131203e0 },
- { _MMIO(0x9888), 0x133203e0 },
- { _MMIO(0x9888), 0x135203e0 },
- { _MMIO(0x9888), 0x1a4ef000 },
- { _MMIO(0x9888), 0x1c4e0003 },
- { _MMIO(0x9888), 0x024ec000 },
- { _MMIO(0x9888), 0x044ec000 },
- { _MMIO(0x9888), 0x064ec000 },
- { _MMIO(0x9888), 0x022f4000 },
- { _MMIO(0x9888), 0x0c4c02a0 },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x0a4c0042 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f0150 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f006d },
- { _MMIO(0x9888), 0x182c00a8 },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x042d8000 },
- { _MMIO(0x9888), 0x06104000 },
- { _MMIO(0x9888), 0x06114000 },
- { _MMIO(0x9888), 0x06120033 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x06131000 },
- { _MMIO(0x9888), 0x04308000 },
- { _MMIO(0x9888), 0x04318000 },
- { _MMIO(0x9888), 0x04321980 },
- { _MMIO(0x9888), 0x00320000 },
- { _MMIO(0x9888), 0x04334000 },
- { _MMIO(0x9888), 0x04504000 },
- { _MMIO(0x9888), 0x04514000 },
- { _MMIO(0x9888), 0x04520033 },
- { _MMIO(0x9888), 0x00520000 },
- { _MMIO(0x9888), 0x04531000 },
- { _MMIO(0x9888), 0x1acef000 },
- { _MMIO(0x9888), 0x1cce0003 },
- { _MMIO(0x9888), 0x00af8000 },
- { _MMIO(0x9888), 0x0ccc02a0 },
- { _MMIO(0x9888), 0x0acc0001 },
- { _MMIO(0x9888), 0x0c8d8000 },
- { _MMIO(0x9888), 0x0e8da000 },
- { _MMIO(0x9888), 0x008d8000 },
- { _MMIO(0x9888), 0x028da000 },
- { _MMIO(0x9888), 0x108f0150 },
- { _MMIO(0x9888), 0x0c8fb000 },
- { _MMIO(0x9888), 0x0e8f0001 },
- { _MMIO(0x9888), 0x18ac00a8 },
- { _MMIO(0x9888), 0x06ac8000 },
- { _MMIO(0x9888), 0x02ad4000 },
- { _MMIO(0x9888), 0x02908000 },
- { _MMIO(0x9888), 0x02918000 },
- { _MMIO(0x9888), 0x02921980 },
- { _MMIO(0x9888), 0x00920000 },
- { _MMIO(0x9888), 0x02934000 },
- { _MMIO(0x9888), 0x02b04000 },
- { _MMIO(0x9888), 0x02b14000 },
- { _MMIO(0x9888), 0x02b20033 },
- { _MMIO(0x9888), 0x00b20000 },
- { _MMIO(0x9888), 0x02b31000 },
- { _MMIO(0x9888), 0x00d08000 },
- { _MMIO(0x9888), 0x00d18000 },
- { _MMIO(0x9888), 0x00d21980 },
- { _MMIO(0x9888), 0x00d34000 },
- { _MMIO(0x9888), 0x072f8000 },
- { _MMIO(0x9888), 0x0d4c0100 },
- { _MMIO(0x9888), 0x0d0d8000 },
- { _MMIO(0x9888), 0x0f0da000 },
- { _MMIO(0x9888), 0x110f01b0 },
- { _MMIO(0x9888), 0x192c0080 },
- { _MMIO(0x9888), 0x0f2d4000 },
- { _MMIO(0x9888), 0x0f108000 },
- { _MMIO(0x9888), 0x0f118000 },
- { _MMIO(0x9888), 0x0f121980 },
- { _MMIO(0x9888), 0x01120000 },
- { _MMIO(0x9888), 0x0f134000 },
- { _MMIO(0x9888), 0x0f304000 },
- { _MMIO(0x9888), 0x0f314000 },
- { _MMIO(0x9888), 0x0f320033 },
- { _MMIO(0x9888), 0x01320000 },
- { _MMIO(0x9888), 0x0f331000 },
- { _MMIO(0x9888), 0x0d508000 },
- { _MMIO(0x9888), 0x0d518000 },
- { _MMIO(0x9888), 0x0d521980 },
- { _MMIO(0x9888), 0x01520000 },
- { _MMIO(0x9888), 0x0d534000 },
- { _MMIO(0x9888), 0x1190ff80 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900c00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900002 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51901100 },
- { _MMIO(0x9888), 0x41901000 },
- { _MMIO(0x9888), 0x43901423 },
- { _MMIO(0x9888), 0x53903331 },
- { _MMIO(0x9888), 0x45900044 },
-};
-
-static int
-get_compute_extra_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extra;
- lens[n] = ARRAY_SIZE(mux_config_compute_extra);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_vme_pipe[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00100030 },
- { _MMIO(0x2774), 0x0000fff9 },
- { _MMIO(0x2778), 0x00000002 },
- { _MMIO(0x277c), 0x0000fffc },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000fff3 },
- { _MMIO(0x2788), 0x00100180 },
- { _MMIO(0x278c), 0x0000ffcf },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000ffcf },
- { _MMIO(0x2798), 0x00000002 },
- { _MMIO(0x279c), 0x0000ff3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_vme_pipe[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00008003 },
-};
-
-static const struct i915_oa_reg mux_config_vme_pipe[] = {
- { _MMIO(0x9888), 0x141a5800 },
- { _MMIO(0x9888), 0x161a00c0 },
- { _MMIO(0x9888), 0x12180240 },
- { _MMIO(0x9888), 0x14180002 },
- { _MMIO(0x9888), 0x149a5800 },
- { _MMIO(0x9888), 0x169a00c0 },
- { _MMIO(0x9888), 0x12980240 },
- { _MMIO(0x9888), 0x14980002 },
- { _MMIO(0x9888), 0x1a4e3fc0 },
- { _MMIO(0x9888), 0x002f1000 },
- { _MMIO(0x9888), 0x022f8000 },
- { _MMIO(0x9888), 0x042f3000 },
- { _MMIO(0x9888), 0x004c4000 },
- { _MMIO(0x9888), 0x0a4c9500 },
- { _MMIO(0x9888), 0x0c4c002a },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f5500 },
- { _MMIO(0x9888), 0x100f0015 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162caa00 },
- { _MMIO(0x9888), 0x182c000a },
- { _MMIO(0x9888), 0x04193000 },
- { _MMIO(0x9888), 0x081a28c1 },
- { _MMIO(0x9888), 0x001a0000 },
- { _MMIO(0x9888), 0x00133000 },
- { _MMIO(0x9888), 0x0613c000 },
- { _MMIO(0x9888), 0x0813f000 },
- { _MMIO(0x9888), 0x00172000 },
- { _MMIO(0x9888), 0x06178000 },
- { _MMIO(0x9888), 0x0817a000 },
- { _MMIO(0x9888), 0x00180037 },
- { _MMIO(0x9888), 0x06180940 },
- { _MMIO(0x9888), 0x08180000 },
- { _MMIO(0x9888), 0x02180000 },
- { _MMIO(0x9888), 0x04183000 },
- { _MMIO(0x9888), 0x04afc000 },
- { _MMIO(0x9888), 0x06af3000 },
- { _MMIO(0x9888), 0x0acc4000 },
- { _MMIO(0x9888), 0x0ccc0015 },
- { _MMIO(0x9888), 0x0a8da000 },
- { _MMIO(0x9888), 0x0c8da000 },
- { _MMIO(0x9888), 0x0e8f4000 },
- { _MMIO(0x9888), 0x108f0015 },
- { _MMIO(0x9888), 0x16aca000 },
- { _MMIO(0x9888), 0x18ac000a },
- { _MMIO(0x9888), 0x06993000 },
- { _MMIO(0x9888), 0x0c9a28c1 },
- { _MMIO(0x9888), 0x009a0000 },
- { _MMIO(0x9888), 0x0a93f000 },
- { _MMIO(0x9888), 0x0c93f000 },
- { _MMIO(0x9888), 0x0a97a000 },
- { _MMIO(0x9888), 0x0c97a000 },
- { _MMIO(0x9888), 0x0a980977 },
- { _MMIO(0x9888), 0x08980000 },
- { _MMIO(0x9888), 0x04980000 },
- { _MMIO(0x9888), 0x06983000 },
- { _MMIO(0x9888), 0x119000ff },
- { _MMIO(0x9888), 0x51900010 },
- { _MMIO(0x9888), 0x41900060 },
- { _MMIO(0x9888), 0x55900111 },
- { _MMIO(0x9888), 0x45900c00 },
- { _MMIO(0x9888), 0x47900821 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900002 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_vme_pipe_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_vme_pipe;
- lens[n] = ARRAY_SIZE(mux_config_vme_pipe);
- n++;
-
- return n;
-}
-
static const struct i915_oa_reg b_counter_config_test_oa[] = {
{ _MMIO(0x2740), 0x00000000 },
{ _MMIO(0x2744), 0x00800000 },
@@ -1984,6 +60,7 @@ static const struct i915_oa_reg flex_eu_config_test_oa[] = {
};
static const struct i915_oa_reg mux_config_test_oa[] = {
+ { _MMIO(0x9840), 0x00000080 },
{ _MMIO(0x9888), 0x11810000 },
{ _MMIO(0x9888), 0x07810013 },
{ _MMIO(0x9888), 0x1f810000 },
@@ -1998,1096 +75,35 @@ static const struct i915_oa_reg mux_config_test_oa[] = {
{ _MMIO(0x9888), 0x33900000 },
};
-static int
-get_test_oa_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_test_oa;
- lens[n] = ARRAY_SIZE(mux_config_test_oa);
- n++;
-
- return n;
-}
-
-int i915_oa_select_metric_set_sklgt4(struct drm_i915_private *dev_priv)
-{
- dev_priv->perf.oa.n_mux_configs = 0;
- dev_priv->perf.oa.b_counter_regs = NULL;
- dev_priv->perf.oa.b_counter_regs_len = 0;
- dev_priv->perf.oa.flex_regs = NULL;
- dev_priv->perf.oa.flex_regs_len = 0;
-
- switch (dev_priv->perf.oa.metrics_set) {
- case METRIC_SET_ID_RENDER_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_render_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_basic);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_basic);
-
- return 0;
- case METRIC_SET_ID_RENDER_PIPE_PROFILE:
- dev_priv->perf.oa.n_mux_configs =
- get_render_pipe_profile_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_pipe_profile;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_pipe_profile);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_pipe_profile;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_pipe_profile);
-
- return 0;
- case METRIC_SET_ID_MEMORY_READS:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_reads_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_reads;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_reads);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_reads;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_reads);
-
- return 0;
- case METRIC_SET_ID_MEMORY_WRITES:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_writes_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_writes;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_writes);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_writes;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_writes);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTENDED:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extended_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extended;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extended);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extended;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extended);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_L3_CACHE:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_l3_cache_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_L3_CACHE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_l3_cache;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_l3_cache);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_l3_cache;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_l3_cache);
-
- return 0;
- case METRIC_SET_ID_HDC_AND_SF:
- dev_priv->perf.oa.n_mux_configs =
- get_hdc_and_sf_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_hdc_and_sf;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_hdc_and_sf);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_hdc_and_sf;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_hdc_and_sf);
-
- return 0;
- case METRIC_SET_ID_L3_1:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_1);
-
- return 0;
- case METRIC_SET_ID_L3_2:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_2);
-
- return 0;
- case METRIC_SET_ID_L3_3:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_3_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_3\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_3;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_3);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_3;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_3);
-
- return 0;
- case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND:
- dev_priv->perf.oa.n_mux_configs =
- get_rasterizer_and_pixel_backend_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend);
-
- return 0;
- case METRIC_SET_ID_SAMPLER:
- dev_priv->perf.oa.n_mux_configs =
- get_sampler_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_sampler;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_sampler);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_sampler;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_sampler);
-
- return 0;
- case METRIC_SET_ID_TDL_1:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_1);
-
- return 0;
- case METRIC_SET_ID_TDL_2:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_2);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTRA:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extra_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTRA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extra;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extra);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extra;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extra);
-
- return 0;
- case METRIC_SET_ID_VME_PIPE:
- dev_priv->perf.oa.n_mux_configs =
- get_vme_pipe_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"VME_PIPE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_vme_pipe;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_vme_pipe);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_vme_pipe;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_vme_pipe);
-
- return 0;
- case METRIC_SET_ID_TEST_OA:
- dev_priv->perf.oa.n_mux_configs =
- get_test_oa_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_test_oa;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_test_oa);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_test_oa;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_test_oa);
-
- return 0;
- default:
- return -ENODEV;
- }
-}
-
-static ssize_t
-show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC);
-}
-
-static struct device_attribute dev_attr_render_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_basic[] = {
- &dev_attr_render_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_basic = {
- .name = "bad77c24-cc64-480d-99bf-e7b740713800",
- .attrs = attrs_render_basic,
-};
-
-static ssize_t
-show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC);
-}
-
-static struct device_attribute dev_attr_compute_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_basic[] = {
- &dev_attr_compute_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_basic = {
- .name = "7277228f-e7f3-4743-945a-6a2049d11377",
- .attrs = attrs_compute_basic,
-};
-
-static ssize_t
-show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE);
-}
-
-static struct device_attribute dev_attr_render_pipe_profile_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_pipe_profile_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_pipe_profile[] = {
- &dev_attr_render_pipe_profile_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_pipe_profile = {
- .name = "463c668c-3f60-49b6-8f85-d995b635b3b2",
- .attrs = attrs_render_pipe_profile,
-};
-
-static ssize_t
-show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS);
-}
-
-static struct device_attribute dev_attr_memory_reads_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_reads_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_reads[] = {
- &dev_attr_memory_reads_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_reads = {
- .name = "3ae6e74c-72c3-4040-9bd0-7961430b8cc8",
- .attrs = attrs_memory_reads,
-};
-
-static ssize_t
-show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES);
-}
-
-static struct device_attribute dev_attr_memory_writes_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_writes_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_writes[] = {
- &dev_attr_memory_writes_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_writes = {
- .name = "055f256d-4052-467c-8dec-6064a4806433",
- .attrs = attrs_memory_writes,
-};
-
-static ssize_t
-show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED);
-}
-
-static struct device_attribute dev_attr_compute_extended_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extended_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extended[] = {
- &dev_attr_compute_extended_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extended = {
- .name = "753972d4-87cd-4460-824d-754463ac5054",
- .attrs = attrs_compute_extended,
-};
-
-static ssize_t
-show_compute_l3_cache_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_L3_CACHE);
-}
-
-static struct device_attribute dev_attr_compute_l3_cache_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_l3_cache_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_l3_cache[] = {
- &dev_attr_compute_l3_cache_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_l3_cache = {
- .name = "4e4392e9-8f73-457b-ab44-b49f7a0c733b",
- .attrs = attrs_compute_l3_cache,
-};
-
-static ssize_t
-show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF);
-}
-
-static struct device_attribute dev_attr_hdc_and_sf_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_hdc_and_sf_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_hdc_and_sf[] = {
- &dev_attr_hdc_and_sf_id.attr,
- NULL,
-};
-
-static struct attribute_group group_hdc_and_sf = {
- .name = "730d95dd-7da8-4e1c-ab8d-c0eb1e4c1805",
- .attrs = attrs_hdc_and_sf,
-};
-
-static ssize_t
-show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1);
-}
-
-static struct device_attribute dev_attr_l3_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_1[] = {
- &dev_attr_l3_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_1 = {
- .name = "d9e86d70-462b-462a-851e-fd63e8c13d63",
- .attrs = attrs_l3_1,
-};
-
-static ssize_t
-show_l3_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_2);
-}
-
-static struct device_attribute dev_attr_l3_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_2[] = {
- &dev_attr_l3_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_2 = {
- .name = "52200424-6ee9-48b3-b7fa-0afcf1975e4d",
- .attrs = attrs_l3_2,
-};
-
-static ssize_t
-show_l3_3_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_3);
-}
-
-static struct device_attribute dev_attr_l3_3_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_3_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_3[] = {
- &dev_attr_l3_3_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_3 = {
- .name = "1988315f-0a26-44df-acb0-df7ec86b1456",
- .attrs = attrs_l3_3,
-};
-
-static ssize_t
-show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND);
-}
-
-static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_rasterizer_and_pixel_backend_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_rasterizer_and_pixel_backend[] = {
- &dev_attr_rasterizer_and_pixel_backend_id.attr,
- NULL,
-};
-
-static struct attribute_group group_rasterizer_and_pixel_backend = {
- .name = "f1f17ca7-286e-4ae5-9d15-9fccad6c665d",
- .attrs = attrs_rasterizer_and_pixel_backend,
-};
-
-static ssize_t
-show_sampler_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER);
-}
-
-static struct device_attribute dev_attr_sampler_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_sampler_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_sampler[] = {
- &dev_attr_sampler_id.attr,
- NULL,
-};
-
-static struct attribute_group group_sampler = {
- .name = "00a9e0fb-3d2e-4405-852c-dce6334ffb3b",
- .attrs = attrs_sampler,
-};
-
-static ssize_t
-show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1);
-}
-
-static struct device_attribute dev_attr_tdl_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_1[] = {
- &dev_attr_tdl_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_1 = {
- .name = "13dcc50a-7ec0-409b-99d6-a3f932cedcb3",
- .attrs = attrs_tdl_1,
-};
-
-static ssize_t
-show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2);
-}
-
-static struct device_attribute dev_attr_tdl_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_2[] = {
- &dev_attr_tdl_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_2 = {
- .name = "97875e21-6624-4aee-9191-682feb3eae21",
- .attrs = attrs_tdl_2,
-};
-
-static ssize_t
-show_compute_extra_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTRA);
-}
-
-static struct device_attribute dev_attr_compute_extra_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extra_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extra[] = {
- &dev_attr_compute_extra_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extra = {
- .name = "a5aa857d-e8f0-4dfa-8981-ce340fa748fd",
- .attrs = attrs_compute_extra,
-};
-
-static ssize_t
-show_vme_pipe_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_VME_PIPE);
-}
-
-static struct device_attribute dev_attr_vme_pipe_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_vme_pipe_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_vme_pipe[] = {
- &dev_attr_vme_pipe_id.attr,
- NULL,
-};
-
-static struct attribute_group group_vme_pipe = {
- .name = "0e8d8b86-4ee7-4cdd-aaaa-58adc92cb29e",
- .attrs = attrs_vme_pipe,
-};
-
static ssize_t
show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA);
+ return sprintf(buf, "1\n");
}
-static struct device_attribute dev_attr_test_oa_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_test_oa_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_test_oa[] = {
- &dev_attr_test_oa_id.attr,
- NULL,
-};
-
-static struct attribute_group group_test_oa = {
- .name = "882fa433-1f4a-4a67-a962-c741888fe5f5",
- .attrs = attrs_test_oa,
-};
-
-int
-i915_perf_register_sysfs_sklgt4(struct drm_i915_private *dev_priv)
+void
+i915_perf_load_test_config_sklgt4(struct drm_i915_private *dev_priv)
{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
- int ret = 0;
+ strncpy(dev_priv->perf.oa.test_config.uuid,
+ "882fa433-1f4a-4a67-a962-c741888fe5f5",
+ UUID_STRING_LEN);
+ dev_priv->perf.oa.test_config.id = 1;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (ret)
- goto error_render_basic;
- }
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (ret)
- goto error_compute_basic;
- }
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (ret)
- goto error_render_pipe_profile;
- }
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (ret)
- goto error_memory_reads;
- }
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (ret)
- goto error_memory_writes;
- }
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (ret)
- goto error_compute_extended;
- }
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (ret)
- goto error_compute_l3_cache;
- }
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (ret)
- goto error_hdc_and_sf;
- }
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (ret)
- goto error_l3_1;
- }
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (ret)
- goto error_l3_2;
- }
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (ret)
- goto error_l3_3;
- }
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (ret)
- goto error_rasterizer_and_pixel_backend;
- }
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (ret)
- goto error_sampler;
- }
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (ret)
- goto error_tdl_1;
- }
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (ret)
- goto error_tdl_2;
- }
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (ret)
- goto error_compute_extra;
- }
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
- if (ret)
- goto error_vme_pipe;
- }
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa);
- if (ret)
- goto error_test_oa;
- }
+ dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
+ dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
- return 0;
+ dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
+ dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-error_test_oa:
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
-error_vme_pipe:
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
-error_compute_extra:
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
-error_tdl_2:
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
-error_tdl_1:
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
-error_sampler:
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
-error_rasterizer_and_pixel_backend:
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
-error_l3_3:
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
-error_l3_2:
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
-error_l3_1:
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
-error_hdc_and_sf:
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
-error_compute_l3_cache:
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
-error_compute_extended:
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
-error_memory_writes:
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
-error_memory_reads:
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
-error_render_pipe_profile:
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
-error_compute_basic:
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
-error_render_basic:
- return ret;
-}
+ dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
+ dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-void
-i915_perf_unregister_sysfs_sklgt4(struct drm_i915_private *dev_priv)
-{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
+ dev_priv->perf.oa.test_config.sysfs_metric.name = "882fa433-1f4a-4a67-a962-c741888fe5f5";
+ dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+
+ dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa);
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
+ dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
}
diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt4.h b/drivers/gpu/drm/i915/i915_oa_sklgt4.h
index 1b718f1..944fd52 100644
--- a/drivers/gpu/drm/i915/i915_oa_sklgt4.h
+++ b/drivers/gpu/drm/i915/i915_oa_sklgt4.h
@@ -29,12 +29,6 @@
#ifndef __I915_OA_SKLGT4_H__
#define __I915_OA_SKLGT4_H__
-extern int i915_oa_n_builtin_metric_sets_sklgt4;
-
-extern int i915_oa_select_metric_set_sklgt4(struct drm_i915_private *dev_priv);
-
-extern int i915_perf_register_sysfs_sklgt4(struct drm_i915_private *dev_priv);
-
-extern void i915_perf_unregister_sysfs_sklgt4(struct drm_i915_private *dev_priv);
+extern void i915_perf_load_test_config_sklgt4(struct drm_i915_private *dev_priv);
#endif
diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
index b6a7e36..8ab003d 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -46,7 +46,7 @@ struct i915_params i915 __read_mostly = {
.prefault_disable = 0,
.load_detect_test = 0,
.force_reset_modeset_test = 0,
- .reset = true,
+ .reset = 2,
.error_capture = true,
.invert_brightness = 0,
.disable_display = 0,
@@ -115,8 +115,12 @@ MODULE_PARM_DESC(vbt_sdvo_panel_type,
"Override/Ignore selection of SDVO panel mode in the VBT "
"(-2=ignore, -1=auto [default], index in VBT BIOS table)");
-module_param_named_unsafe(reset, i915.reset, bool, 0600);
-MODULE_PARM_DESC(reset, "Attempt GPU resets (default: true)");
+module_param_named_unsafe(reset, i915.reset, int, 0600);
+MODULE_PARM_DESC(reset, "Attempt GPU resets (0=disabled, 1=full gpu reset, 2=engine reset [default])");
+
+module_param_named_unsafe(vbt_firmware, i915.vbt_firmware, charp, 0400);
+MODULE_PARM_DESC(vbt_firmware,
+ "Load VBT from specified file under /lib/firmware");
#if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
module_param_named(error_capture, i915.error_capture, bool, 0600);
diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h
index 34148cc..ac84470 100644
--- a/drivers/gpu/drm/i915/i915_params.h
+++ b/drivers/gpu/drm/i915/i915_params.h
@@ -28,6 +28,7 @@
#include <linux/cache.h> /* for __read_mostly */
#define I915_PARAMS_FOR_EACH(func) \
+ func(char *, vbt_firmware); \
func(int, modeset); \
func(int, panel_ignore_lid); \
func(int, semaphores); \
@@ -51,6 +52,7 @@
func(int, use_mmio_flip); \
func(int, mmio_debug); \
func(int, edp_vswing); \
+ func(int, reset); \
func(unsigned int, inject_load_failure); \
/* leave bools at the end to not create holes */ \
func(bool, alpha_support); \
@@ -60,7 +62,6 @@
func(bool, prefault_disable); \
func(bool, load_detect_test); \
func(bool, force_reset_modeset_test); \
- func(bool, reset); \
func(bool, error_capture); \
func(bool, disable_display); \
func(bool, verbose_state_checks); \
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 506ec32..09d97e0 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -310,7 +310,8 @@ static const struct intel_device_info intel_haswell_info = {
BDW_COLORS, \
.has_logical_ring_contexts = 1, \
.has_full_48bit_ppgtt = 1, \
- .has_64bit_reloc = 1
+ .has_64bit_reloc = 1, \
+ .has_reset_engine = 1
#define BDW_PLATFORM \
BDW_FEATURES, \
@@ -342,6 +343,7 @@ static const struct intel_device_info intel_cherryview_info = {
.has_gmch_display = 1,
.has_aliasing_ppgtt = 1,
.has_full_ppgtt = 1,
+ .has_reset_engine = 1,
.display_mmio_offset = VLV_DISPLAY_BASE,
GEN_CHV_PIPEOFFSETS,
CURSOR_OFFSETS,
@@ -387,6 +389,7 @@ static const struct intel_device_info intel_skylake_gt3_info = {
.has_aliasing_ppgtt = 1, \
.has_full_ppgtt = 1, \
.has_full_48bit_ppgtt = 1, \
+ .has_reset_engine = 1, \
GEN_DEFAULT_PIPEOFFSETS, \
IVB_CURSOR_OFFSETS, \
BDW_COLORS
@@ -395,6 +398,7 @@ static const struct intel_device_info intel_broxton_info = {
GEN9_LP_FEATURES,
.platform = INTEL_BROXTON,
.ddb_size = 512,
+ .has_reset_engine = false,
};
static const struct intel_device_info intel_geminilake_info = {
@@ -446,6 +450,7 @@ static const struct intel_device_info intel_cannonlake_info = {
.gen = 10,
.ddb_size = 1024,
.has_csr = 1,
+ .color = { .degamma_lut_size = 0, .gamma_lut_size = 1024 }
};
/*
diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
index f33d902..94185d6 100644
--- a/drivers/gpu/drm/i915/i915_perf.c
+++ b/drivers/gpu/drm/i915/i915_perf.c
@@ -193,6 +193,7 @@
#include <linux/anon_inodes.h>
#include <linux/sizes.h>
+#include <linux/uuid.h>
#include "i915_drv.h"
#include "i915_oa_hsw.h"
@@ -357,6 +358,54 @@ struct perf_open_properties {
int oa_period_exponent;
};
+static void free_oa_config(struct drm_i915_private *dev_priv,
+ struct i915_oa_config *oa_config)
+{
+ if (!PTR_ERR(oa_config->flex_regs))
+ kfree(oa_config->flex_regs);
+ if (!PTR_ERR(oa_config->b_counter_regs))
+ kfree(oa_config->b_counter_regs);
+ if (!PTR_ERR(oa_config->mux_regs))
+ kfree(oa_config->mux_regs);
+ kfree(oa_config);
+}
+
+static void put_oa_config(struct drm_i915_private *dev_priv,
+ struct i915_oa_config *oa_config)
+{
+ if (!atomic_dec_and_test(&oa_config->ref_count))
+ return;
+
+ free_oa_config(dev_priv, oa_config);
+}
+
+static int get_oa_config(struct drm_i915_private *dev_priv,
+ int metrics_set,
+ struct i915_oa_config **out_config)
+{
+ int ret;
+
+ if (metrics_set == 1) {
+ *out_config = &dev_priv->perf.oa.test_config;
+ atomic_inc(&dev_priv->perf.oa.test_config.ref_count);
+ return 0;
+ }
+
+ ret = mutex_lock_interruptible(&dev_priv->perf.metrics_lock);
+ if (ret)
+ return ret;
+
+ *out_config = idr_find(&dev_priv->perf.metrics_idr, metrics_set);
+ if (!*out_config)
+ ret = -EINVAL;
+ else
+ atomic_inc(&(*out_config)->ref_count);
+
+ mutex_unlock(&dev_priv->perf.metrics_lock);
+
+ return ret;
+}
+
static u32 gen8_oa_hw_tail_read(struct drm_i915_private *dev_priv)
{
return I915_READ(GEN8_OATAILPTR) & GEN8_OATAILPTR_MASK;
@@ -1246,10 +1295,12 @@ static void i915_oa_stream_destroy(struct i915_perf_stream *stream)
BUG_ON(stream != dev_priv->perf.oa.exclusive_stream);
/*
- * Unset exclusive_stream first, it might be checked while
- * disabling the metric set on gen8+.
+ * Unset exclusive_stream first, it will be checked while disabling
+ * the metric set on gen8+.
*/
+ mutex_lock(&dev_priv->drm.struct_mutex);
dev_priv->perf.oa.exclusive_stream = NULL;
+ mutex_unlock(&dev_priv->drm.struct_mutex);
dev_priv->perf.oa.ops.disable_metric_set(dev_priv);
@@ -1261,6 +1312,8 @@ static void i915_oa_stream_destroy(struct i915_perf_stream *stream)
if (stream->ctx)
oa_put_render_ctx_id(stream);
+ put_oa_config(dev_priv, stream->oa_config);
+
if (dev_priv->perf.oa.spurious_report_rs.missed) {
DRM_NOTE("%d spurious OA report notices suppressed due to ratelimiting\n",
dev_priv->perf.oa.spurious_report_rs.missed);
@@ -1440,9 +1493,9 @@ unlock:
static void config_oa_regs(struct drm_i915_private *dev_priv,
const struct i915_oa_reg *regs,
- int n_regs)
+ u32 n_regs)
{
- int i;
+ u32 i;
for (i = 0; i < n_regs; i++) {
const struct i915_oa_reg *reg = regs + i;
@@ -1451,17 +1504,9 @@ static void config_oa_regs(struct drm_i915_private *dev_priv,
}
}
-static int hsw_enable_metric_set(struct drm_i915_private *dev_priv)
+static int hsw_enable_metric_set(struct drm_i915_private *dev_priv,
+ const struct i915_oa_config *oa_config)
{
- int ret = i915_oa_select_metric_set_hsw(dev_priv);
- int i;
-
- if (ret)
- return ret;
-
- I915_WRITE(GDT_CHICKEN_BITS, (I915_READ(GDT_CHICKEN_BITS) |
- GT_NOA_ENABLE));
-
/* PRM:
*
* OA unit is using “crclk†for its functionality. When trunk
@@ -1476,10 +1521,7 @@ static int hsw_enable_metric_set(struct drm_i915_private *dev_priv)
I915_WRITE(GEN6_UCGCTL1, (I915_READ(GEN6_UCGCTL1) |
GEN6_CSUNIT_CLOCK_GATE_DISABLE));
- for (i = 0; i < dev_priv->perf.oa.n_mux_configs; i++) {
- config_oa_regs(dev_priv, dev_priv->perf.oa.mux_regs[i],
- dev_priv->perf.oa.mux_regs_lens[i]);
- }
+ config_oa_regs(dev_priv, oa_config->mux_regs, oa_config->mux_regs_len);
/* It apparently takes a fairly long time for a new MUX
* configuration to be be applied after these register writes.
@@ -1504,8 +1546,8 @@ static int hsw_enable_metric_set(struct drm_i915_private *dev_priv)
*/
usleep_range(15000, 20000);
- config_oa_regs(dev_priv, dev_priv->perf.oa.b_counter_regs,
- dev_priv->perf.oa.b_counter_regs_len);
+ config_oa_regs(dev_priv, oa_config->b_counter_regs,
+ oa_config->b_counter_regs_len);
return 0;
}
@@ -1529,11 +1571,10 @@ static void hsw_disable_metric_set(struct drm_i915_private *dev_priv)
* in the case that the OA unit has been disabled.
*/
static void gen8_update_reg_state_unlocked(struct i915_gem_context *ctx,
- u32 *reg_state)
+ u32 *reg_state,
+ const struct i915_oa_config *oa_config)
{
struct drm_i915_private *dev_priv = ctx->i915;
- const struct i915_oa_reg *flex_regs = dev_priv->perf.oa.flex_regs;
- int n_flex_regs = dev_priv->perf.oa.flex_regs_len;
u32 ctx_oactxctrl = dev_priv->perf.oa.ctx_oactxctrl_offset;
u32 ctx_flexeu0 = dev_priv->perf.oa.ctx_flexeu0_offset;
/* The MMIO offsets for Flex EU registers aren't contiguous */
@@ -1565,12 +1606,15 @@ static void gen8_update_reg_state_unlocked(struct i915_gem_context *ctx,
* will be an explicit 'No Event' we can select, but not yet...
*/
u32 value = 0;
- int j;
- for (j = 0; j < n_flex_regs; j++) {
- if (i915_mmio_reg_offset(flex_regs[j].addr) == mmio) {
- value = flex_regs[j].value;
- break;
+ if (oa_config) {
+ u32 j;
+
+ for (j = 0; j < oa_config->flex_regs_len; j++) {
+ if (i915_mmio_reg_offset(oa_config->flex_regs[j].addr) == mmio) {
+ value = oa_config->flex_regs[j].value;
+ break;
+ }
}
}
@@ -1583,11 +1627,10 @@ static void gen8_update_reg_state_unlocked(struct i915_gem_context *ctx,
* Same as gen8_update_reg_state_unlocked only through the batchbuffer. This
* is only used by the kernel context.
*/
-static int gen8_emit_oa_config(struct drm_i915_gem_request *req)
+static int gen8_emit_oa_config(struct drm_i915_gem_request *req,
+ const struct i915_oa_config *oa_config)
{
struct drm_i915_private *dev_priv = req->i915;
- const struct i915_oa_reg *flex_regs = dev_priv->perf.oa.flex_regs;
- int n_flex_regs = dev_priv->perf.oa.flex_regs_len;
/* The MMIO offsets for Flex EU registers aren't contiguous */
u32 flex_mmio[] = {
i915_mmio_reg_offset(EU_PERF_CNTL0),
@@ -1622,12 +1665,15 @@ static int gen8_emit_oa_config(struct drm_i915_gem_request *req)
* yet...
*/
u32 value = 0;
- int j;
- for (j = 0; j < n_flex_regs; j++) {
- if (i915_mmio_reg_offset(flex_regs[j].addr) == mmio) {
- value = flex_regs[j].value;
- break;
+ if (oa_config) {
+ u32 j;
+
+ for (j = 0; j < oa_config->flex_regs_len; j++) {
+ if (i915_mmio_reg_offset(oa_config->flex_regs[j].addr) == mmio) {
+ value = oa_config->flex_regs[j].value;
+ break;
+ }
}
}
@@ -1641,7 +1687,8 @@ static int gen8_emit_oa_config(struct drm_i915_gem_request *req)
return 0;
}
-static int gen8_switch_to_updated_kernel_context(struct drm_i915_private *dev_priv)
+static int gen8_switch_to_updated_kernel_context(struct drm_i915_private *dev_priv,
+ const struct i915_oa_config *oa_config)
{
struct intel_engine_cs *engine = dev_priv->engine[RCS];
struct i915_gem_timeline *timeline;
@@ -1656,7 +1703,7 @@ static int gen8_switch_to_updated_kernel_context(struct drm_i915_private *dev_pr
if (IS_ERR(req))
return PTR_ERR(req);
- ret = gen8_emit_oa_config(req);
+ ret = gen8_emit_oa_config(req, oa_config);
if (ret) {
i915_add_request(req);
return ret;
@@ -1707,6 +1754,7 @@ static int gen8_switch_to_updated_kernel_context(struct drm_i915_private *dev_pr
* Note: it's only the RCS/Render context that has any OA state.
*/
static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv,
+ const struct i915_oa_config *oa_config,
bool interruptible)
{
struct i915_gem_context *ctx;
@@ -1724,7 +1772,7 @@ static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv,
}
/* Switch away from any user context. */
- ret = gen8_switch_to_updated_kernel_context(dev_priv);
+ ret = gen8_switch_to_updated_kernel_context(dev_priv, oa_config);
if (ret)
goto out;
@@ -1746,7 +1794,7 @@ static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv,
goto out;
/* Update all contexts now that we've stalled the submission. */
- list_for_each_entry(ctx, &dev_priv->context_list, link) {
+ list_for_each_entry(ctx, &dev_priv->contexts.list, link) {
struct intel_context *ce = &ctx->engine[RCS];
u32 *regs;
@@ -1763,7 +1811,7 @@ static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv,
ce->state->obj->mm.dirty = true;
regs += LRC_STATE_PN * PAGE_SIZE / sizeof(*regs);
- gen8_update_reg_state_unlocked(ctx, regs);
+ gen8_update_reg_state_unlocked(ctx, regs, oa_config);
i915_gem_object_unpin_map(ce->state->obj);
}
@@ -1774,13 +1822,10 @@ static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv,
return ret;
}
-static int gen8_enable_metric_set(struct drm_i915_private *dev_priv)
+static int gen8_enable_metric_set(struct drm_i915_private *dev_priv,
+ const struct i915_oa_config *oa_config)
{
- int ret = dev_priv->perf.oa.ops.select_metric_set(dev_priv);
- int i;
-
- if (ret)
- return ret;
+ int ret;
/*
* We disable slice/unslice clock ratio change reports on SKL since
@@ -1817,19 +1862,14 @@ static int gen8_enable_metric_set(struct drm_i915_private *dev_priv)
* to make sure all slices/subslices are ON before writing to NOA
* registers.
*/
- ret = gen8_configure_all_contexts(dev_priv, true);
+ ret = gen8_configure_all_contexts(dev_priv, oa_config, true);
if (ret)
return ret;
- I915_WRITE(GDT_CHICKEN_BITS, 0xA0);
- for (i = 0; i < dev_priv->perf.oa.n_mux_configs; i++) {
- config_oa_regs(dev_priv, dev_priv->perf.oa.mux_regs[i],
- dev_priv->perf.oa.mux_regs_lens[i]);
- }
- I915_WRITE(GDT_CHICKEN_BITS, 0x80);
+ config_oa_regs(dev_priv, oa_config->mux_regs, oa_config->mux_regs_len);
- config_oa_regs(dev_priv, dev_priv->perf.oa.b_counter_regs,
- dev_priv->perf.oa.b_counter_regs_len);
+ config_oa_regs(dev_priv, oa_config->b_counter_regs,
+ oa_config->b_counter_regs_len);
return 0;
}
@@ -1837,7 +1877,11 @@ static int gen8_enable_metric_set(struct drm_i915_private *dev_priv)
static void gen8_disable_metric_set(struct drm_i915_private *dev_priv)
{
/* Reset all contexts' slices/subslices configurations. */
- gen8_configure_all_contexts(dev_priv, false);
+ gen8_configure_all_contexts(dev_priv, NULL, false);
+
+ I915_WRITE(GDT_CHICKEN_BITS, (I915_READ(GDT_CHICKEN_BITS) &
+ ~GT_NOA_ENABLE));
+
}
static void gen7_oa_enable(struct drm_i915_private *dev_priv)
@@ -2011,11 +2055,6 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
return -EBUSY;
}
- if (!props->metrics_set) {
- DRM_DEBUG("OA metric set not specified\n");
- return -EINVAL;
- }
-
if (!props->oa_format) {
DRM_DEBUG("OA report format not specified\n");
return -EINVAL;
@@ -2055,8 +2094,6 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
dev_priv->perf.oa.oa_buffer.format =
dev_priv->perf.oa.oa_formats[props->oa_format].format;
- dev_priv->perf.oa.metrics_set = props->metrics_set;
-
dev_priv->perf.oa.periodic = props->oa_periodic;
if (dev_priv->perf.oa.periodic)
dev_priv->perf.oa.period_exponent = props->oa_period_exponent;
@@ -2067,6 +2104,10 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
return ret;
}
+ ret = get_oa_config(dev_priv, props->metrics_set, &stream->oa_config);
+ if (ret)
+ goto err_config;
+
/* PRM - observability performance counters:
*
* OACONTROL, performance counter enable, note:
@@ -2086,22 +2127,39 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
if (ret)
goto err_oa_buf_alloc;
- ret = dev_priv->perf.oa.ops.enable_metric_set(dev_priv);
+ ret = dev_priv->perf.oa.ops.enable_metric_set(dev_priv,
+ stream->oa_config);
if (ret)
goto err_enable;
stream->ops = &i915_oa_stream_ops;
+ /* Lock device for exclusive_stream access late because
+ * enable_metric_set() might lock as well on gen8+.
+ */
+ ret = i915_mutex_lock_interruptible(&dev_priv->drm);
+ if (ret)
+ goto err_lock;
+
dev_priv->perf.oa.exclusive_stream = stream;
+ mutex_unlock(&dev_priv->drm.struct_mutex);
+
return 0;
+err_lock:
+ dev_priv->perf.oa.ops.disable_metric_set(dev_priv);
+
err_enable:
free_oa_buffer(dev_priv);
err_oa_buf_alloc:
+ put_oa_config(dev_priv, stream->oa_config);
+
intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
intel_runtime_pm_put(dev_priv);
+
+err_config:
if (stream->ctx)
oa_put_render_ctx_id(stream);
@@ -2112,15 +2170,14 @@ void i915_oa_init_reg_state(struct intel_engine_cs *engine,
struct i915_gem_context *ctx,
u32 *reg_state)
{
- struct drm_i915_private *dev_priv = engine->i915;
+ struct i915_perf_stream *stream;
if (engine->id != RCS)
return;
- if (!dev_priv->perf.initialized)
- return;
-
- gen8_update_reg_state_unlocked(ctx, reg_state);
+ stream = engine->i915->perf.oa.exclusive_stream;
+ if (stream)
+ gen8_update_reg_state_unlocked(ctx, reg_state, stream->oa_config);
}
/**
@@ -2444,7 +2501,7 @@ static void i915_perf_destroy_locked(struct i915_perf_stream *stream)
list_del(&stream->link);
if (stream->ctx)
- i915_gem_context_put_unlocked(stream->ctx);
+ i915_gem_context_put(stream->ctx);
kfree(stream);
}
@@ -2483,27 +2540,6 @@ static const struct file_operations fops = {
};
-static struct i915_gem_context *
-lookup_context(struct drm_i915_private *dev_priv,
- struct drm_i915_file_private *file_priv,
- u32 ctx_user_handle)
-{
- struct i915_gem_context *ctx;
- int ret;
-
- ret = i915_mutex_lock_interruptible(&dev_priv->drm);
- if (ret)
- return ERR_PTR(ret);
-
- ctx = i915_gem_context_lookup(file_priv, ctx_user_handle);
- if (!IS_ERR(ctx))
- i915_gem_context_get(ctx);
-
- mutex_unlock(&dev_priv->drm.struct_mutex);
-
- return ctx;
-}
-
/**
* i915_perf_open_ioctl_locked - DRM ioctl() for userspace to open a stream FD
* @dev_priv: i915 device instance
@@ -2545,12 +2581,11 @@ i915_perf_open_ioctl_locked(struct drm_i915_private *dev_priv,
u32 ctx_handle = props->ctx_handle;
struct drm_i915_file_private *file_priv = file->driver_priv;
- specific_ctx = lookup_context(dev_priv, file_priv, ctx_handle);
- if (IS_ERR(specific_ctx)) {
- ret = PTR_ERR(specific_ctx);
- if (ret != -EINTR)
- DRM_DEBUG("Failed to look up context with ID %u for opening perf stream\n",
- ctx_handle);
+ specific_ctx = i915_gem_context_lookup(file_priv, ctx_handle);
+ if (!specific_ctx) {
+ DRM_DEBUG("Failed to look up context with ID %u for opening perf stream\n",
+ ctx_handle);
+ ret = -ENOENT;
goto err;
}
}
@@ -2633,7 +2668,7 @@ err_alloc:
kfree(stream);
err_ctx:
if (specific_ctx)
- i915_gem_context_put_unlocked(specific_ctx);
+ i915_gem_context_put(specific_ctx);
err:
return ret;
}
@@ -2665,7 +2700,7 @@ static int read_properties_unlocked(struct drm_i915_private *dev_priv,
struct perf_open_properties *props)
{
u64 __user *uprop = uprops;
- int i;
+ u32 i;
memset(props, 0, sizeof(struct perf_open_properties));
@@ -2712,8 +2747,7 @@ static int read_properties_unlocked(struct drm_i915_private *dev_priv,
props->sample_flags |= SAMPLE_OA_REPORT;
break;
case DRM_I915_PERF_PROP_OA_METRICS_SET:
- if (value == 0 ||
- value > dev_priv->perf.oa.n_builtin_sets) {
+ if (value == 0) {
DRM_DEBUG("Unknown OA metric set ID\n");
return -EINVAL;
}
@@ -2852,6 +2886,8 @@ int i915_perf_open_ioctl(struct drm_device *dev, void *data,
*/
void i915_perf_register(struct drm_i915_private *dev_priv)
{
+ int ret;
+
if (!dev_priv->perf.initialized)
return;
@@ -2867,44 +2903,42 @@ void i915_perf_register(struct drm_i915_private *dev_priv)
if (!dev_priv->perf.metrics_kobj)
goto exit;
+ sysfs_attr_init(&dev_priv->perf.oa.test_config.sysfs_metric_id.attr);
+
if (IS_HASWELL(dev_priv)) {
- if (i915_perf_register_sysfs_hsw(dev_priv))
- goto sysfs_error;
+ i915_perf_load_test_config_hsw(dev_priv);
} else if (IS_BROADWELL(dev_priv)) {
- if (i915_perf_register_sysfs_bdw(dev_priv))
- goto sysfs_error;
+ i915_perf_load_test_config_bdw(dev_priv);
} else if (IS_CHERRYVIEW(dev_priv)) {
- if (i915_perf_register_sysfs_chv(dev_priv))
- goto sysfs_error;
+ i915_perf_load_test_config_chv(dev_priv);
} else if (IS_SKYLAKE(dev_priv)) {
- if (IS_SKL_GT2(dev_priv)) {
- if (i915_perf_register_sysfs_sklgt2(dev_priv))
- goto sysfs_error;
- } else if (IS_SKL_GT3(dev_priv)) {
- if (i915_perf_register_sysfs_sklgt3(dev_priv))
- goto sysfs_error;
- } else if (IS_SKL_GT4(dev_priv)) {
- if (i915_perf_register_sysfs_sklgt4(dev_priv))
- goto sysfs_error;
- } else
- goto sysfs_error;
+ if (IS_SKL_GT2(dev_priv))
+ i915_perf_load_test_config_sklgt2(dev_priv);
+ else if (IS_SKL_GT3(dev_priv))
+ i915_perf_load_test_config_sklgt3(dev_priv);
+ else if (IS_SKL_GT4(dev_priv))
+ i915_perf_load_test_config_sklgt4(dev_priv);
} else if (IS_BROXTON(dev_priv)) {
- if (i915_perf_register_sysfs_bxt(dev_priv))
- goto sysfs_error;
+ i915_perf_load_test_config_bxt(dev_priv);
} else if (IS_KABYLAKE(dev_priv)) {
- if (IS_KBL_GT2(dev_priv)) {
- if (i915_perf_register_sysfs_kblgt2(dev_priv))
- goto sysfs_error;
- } else if (IS_KBL_GT3(dev_priv)) {
- if (i915_perf_register_sysfs_kblgt3(dev_priv))
- goto sysfs_error;
- } else
- goto sysfs_error;
+ if (IS_KBL_GT2(dev_priv))
+ i915_perf_load_test_config_kblgt2(dev_priv);
+ else if (IS_KBL_GT3(dev_priv))
+ i915_perf_load_test_config_kblgt3(dev_priv);
} else if (IS_GEMINILAKE(dev_priv)) {
- if (i915_perf_register_sysfs_glk(dev_priv))
- goto sysfs_error;
+ i915_perf_load_test_config_glk(dev_priv);
}
+ if (dev_priv->perf.oa.test_config.id == 0)
+ goto sysfs_error;
+
+ ret = sysfs_create_group(dev_priv->perf.metrics_kobj,
+ &dev_priv->perf.oa.test_config.sysfs_metric);
+ if (ret)
+ goto sysfs_error;
+
+ atomic_set(&dev_priv->perf.oa.test_config.ref_count, 1);
+
goto exit;
sysfs_error:
@@ -2929,34 +2963,375 @@ void i915_perf_unregister(struct drm_i915_private *dev_priv)
if (!dev_priv->perf.metrics_kobj)
return;
- if (IS_HASWELL(dev_priv))
- i915_perf_unregister_sysfs_hsw(dev_priv);
- else if (IS_BROADWELL(dev_priv))
- i915_perf_unregister_sysfs_bdw(dev_priv);
- else if (IS_CHERRYVIEW(dev_priv))
- i915_perf_unregister_sysfs_chv(dev_priv);
- else if (IS_SKYLAKE(dev_priv)) {
- if (IS_SKL_GT2(dev_priv))
- i915_perf_unregister_sysfs_sklgt2(dev_priv);
- else if (IS_SKL_GT3(dev_priv))
- i915_perf_unregister_sysfs_sklgt3(dev_priv);
- else if (IS_SKL_GT4(dev_priv))
- i915_perf_unregister_sysfs_sklgt4(dev_priv);
- } else if (IS_BROXTON(dev_priv))
- i915_perf_unregister_sysfs_bxt(dev_priv);
- else if (IS_KABYLAKE(dev_priv)) {
- if (IS_KBL_GT2(dev_priv))
- i915_perf_unregister_sysfs_kblgt2(dev_priv);
- else if (IS_KBL_GT3(dev_priv))
- i915_perf_unregister_sysfs_kblgt3(dev_priv);
- } else if (IS_GEMINILAKE(dev_priv))
- i915_perf_unregister_sysfs_glk(dev_priv);
-
+ sysfs_remove_group(dev_priv->perf.metrics_kobj,
+ &dev_priv->perf.oa.test_config.sysfs_metric);
kobject_put(dev_priv->perf.metrics_kobj);
dev_priv->perf.metrics_kobj = NULL;
}
+static bool gen8_is_valid_flex_addr(struct drm_i915_private *dev_priv, u32 addr)
+{
+ static const i915_reg_t flex_eu_regs[] = {
+ EU_PERF_CNTL0,
+ EU_PERF_CNTL1,
+ EU_PERF_CNTL2,
+ EU_PERF_CNTL3,
+ EU_PERF_CNTL4,
+ EU_PERF_CNTL5,
+ EU_PERF_CNTL6,
+ };
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(flex_eu_regs); i++) {
+ if (flex_eu_regs[i].reg == addr)
+ return true;
+ }
+ return false;
+}
+
+static bool gen7_is_valid_b_counter_addr(struct drm_i915_private *dev_priv, u32 addr)
+{
+ return (addr >= OASTARTTRIG1.reg && addr <= OASTARTTRIG8.reg) ||
+ (addr >= OAREPORTTRIG1.reg && addr <= OAREPORTTRIG8.reg) ||
+ (addr >= OACEC0_0.reg && addr <= OACEC7_1.reg);
+}
+
+static bool gen7_is_valid_mux_addr(struct drm_i915_private *dev_priv, u32 addr)
+{
+ return addr == HALF_SLICE_CHICKEN2.reg ||
+ (addr >= MICRO_BP0_0.reg && addr <= NOA_WRITE.reg) ||
+ (addr >= OA_PERFCNT1_LO.reg && addr <= OA_PERFCNT2_HI.reg) ||
+ (addr >= OA_PERFMATRIX_LO.reg && addr <= OA_PERFMATRIX_HI.reg);
+}
+
+static bool gen8_is_valid_mux_addr(struct drm_i915_private *dev_priv, u32 addr)
+{
+ return gen7_is_valid_mux_addr(dev_priv, addr) ||
+ addr == WAIT_FOR_RC6_EXIT.reg ||
+ (addr >= RPM_CONFIG0.reg && addr <= NOA_CONFIG(8).reg);
+}
+
+static bool hsw_is_valid_mux_addr(struct drm_i915_private *dev_priv, u32 addr)
+{
+ return gen7_is_valid_mux_addr(dev_priv, addr) ||
+ (addr >= 0x25100 && addr <= 0x2FF90) ||
+ addr == 0x9ec0;
+}
+
+static bool chv_is_valid_mux_addr(struct drm_i915_private *dev_priv, u32 addr)
+{
+ return gen7_is_valid_mux_addr(dev_priv, addr) ||
+ (addr >= 0x182300 && addr <= 0x1823A4);
+}
+
+static uint32_t mask_reg_value(u32 reg, u32 val)
+{
+ /* HALF_SLICE_CHICKEN2 is programmed with a the
+ * WaDisableSTUnitPowerOptimization workaround. Make sure the value
+ * programmed by userspace doesn't change this.
+ */
+ if (HALF_SLICE_CHICKEN2.reg == reg)
+ val = val & ~_MASKED_BIT_ENABLE(GEN8_ST_PO_DISABLE);
+
+ /* WAIT_FOR_RC6_EXIT has only one bit fullfilling the function
+ * indicated by its name and a bunch of selection fields used by OA
+ * configs.
+ */
+ if (WAIT_FOR_RC6_EXIT.reg == reg)
+ val = val & ~_MASKED_BIT_ENABLE(HSW_WAIT_FOR_RC6_EXIT_ENABLE);
+
+ return val;
+}
+
+static struct i915_oa_reg *alloc_oa_regs(struct drm_i915_private *dev_priv,
+ bool (*is_valid)(struct drm_i915_private *dev_priv, u32 addr),
+ u32 __user *regs,
+ u32 n_regs)
+{
+ struct i915_oa_reg *oa_regs;
+ int err;
+ u32 i;
+
+ if (!n_regs)
+ return NULL;
+
+ if (!access_ok(VERIFY_READ, regs, n_regs * sizeof(u32) * 2))
+ return ERR_PTR(-EFAULT);
+
+ /* No is_valid function means we're not allowing any register to be programmed. */
+ GEM_BUG_ON(!is_valid);
+ if (!is_valid)
+ return ERR_PTR(-EINVAL);
+
+ oa_regs = kmalloc_array(n_regs, sizeof(*oa_regs), GFP_KERNEL);
+ if (!oa_regs)
+ return ERR_PTR(-ENOMEM);
+
+ for (i = 0; i < n_regs; i++) {
+ u32 addr, value;
+
+ err = get_user(addr, regs);
+ if (err)
+ goto addr_err;
+
+ if (!is_valid(dev_priv, addr)) {
+ DRM_DEBUG("Invalid oa_reg address: %X\n", addr);
+ err = -EINVAL;
+ goto addr_err;
+ }
+
+ err = get_user(value, regs + 1);
+ if (err)
+ goto addr_err;
+
+ oa_regs[i].addr = _MMIO(addr);
+ oa_regs[i].value = mask_reg_value(addr, value);
+
+ regs += 2;
+ }
+
+ return oa_regs;
+
+addr_err:
+ kfree(oa_regs);
+ return ERR_PTR(err);
+}
+
+static ssize_t show_dynamic_id(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct i915_oa_config *oa_config =
+ container_of(attr, typeof(*oa_config), sysfs_metric_id);
+
+ return sprintf(buf, "%d\n", oa_config->id);
+}
+
+static int create_dynamic_oa_sysfs_entry(struct drm_i915_private *dev_priv,
+ struct i915_oa_config *oa_config)
+{
+ sysfs_attr_init(&oa_config->sysfs_metric_id.attr);
+ oa_config->sysfs_metric_id.attr.name = "id";
+ oa_config->sysfs_metric_id.attr.mode = S_IRUGO;
+ oa_config->sysfs_metric_id.show = show_dynamic_id;
+ oa_config->sysfs_metric_id.store = NULL;
+
+ oa_config->attrs[0] = &oa_config->sysfs_metric_id.attr;
+ oa_config->attrs[1] = NULL;
+
+ oa_config->sysfs_metric.name = oa_config->uuid;
+ oa_config->sysfs_metric.attrs = oa_config->attrs;
+
+ return sysfs_create_group(dev_priv->perf.metrics_kobj,
+ &oa_config->sysfs_metric);
+}
+
+/**
+ * i915_perf_add_config_ioctl - DRM ioctl() for userspace to add a new OA config
+ * @dev: drm device
+ * @data: ioctl data (pointer to struct drm_i915_perf_oa_config) copied from
+ * userspace (unvalidated)
+ * @file: drm file
+ *
+ * Validates the submitted OA register to be saved into a new OA config that
+ * can then be used for programming the OA unit and its NOA network.
+ *
+ * Returns: A new allocated config number to be used with the perf open ioctl
+ * or a negative error code on failure.
+ */
+int i915_perf_add_config_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_i915_perf_oa_config *args = data;
+ struct i915_oa_config *oa_config, *tmp;
+ int err, id;
+
+ if (!dev_priv->perf.initialized) {
+ DRM_DEBUG("i915 perf interface not available for this system\n");
+ return -ENOTSUPP;
+ }
+
+ if (!dev_priv->perf.metrics_kobj) {
+ DRM_DEBUG("OA metrics weren't advertised via sysfs\n");
+ return -EINVAL;
+ }
+
+ if (i915_perf_stream_paranoid && !capable(CAP_SYS_ADMIN)) {
+ DRM_DEBUG("Insufficient privileges to add i915 OA config\n");
+ return -EACCES;
+ }
+
+ if ((!args->mux_regs_ptr || !args->n_mux_regs) &&
+ (!args->boolean_regs_ptr || !args->n_boolean_regs) &&
+ (!args->flex_regs_ptr || !args->n_flex_regs)) {
+ DRM_DEBUG("No OA registers given\n");
+ return -EINVAL;
+ }
+
+ oa_config = kzalloc(sizeof(*oa_config), GFP_KERNEL);
+ if (!oa_config) {
+ DRM_DEBUG("Failed to allocate memory for the OA config\n");
+ return -ENOMEM;
+ }
+
+ atomic_set(&oa_config->ref_count, 1);
+
+ if (!uuid_is_valid(args->uuid)) {
+ DRM_DEBUG("Invalid uuid format for OA config\n");
+ err = -EINVAL;
+ goto reg_err;
+ }
+
+ /* Last character in oa_config->uuid will be 0 because oa_config is
+ * kzalloc.
+ */
+ memcpy(oa_config->uuid, args->uuid, sizeof(args->uuid));
+
+ oa_config->mux_regs_len = args->n_mux_regs;
+ oa_config->mux_regs =
+ alloc_oa_regs(dev_priv,
+ dev_priv->perf.oa.ops.is_valid_mux_reg,
+ u64_to_user_ptr(args->mux_regs_ptr),
+ args->n_mux_regs);
+
+ if (IS_ERR(oa_config->mux_regs)) {
+ DRM_DEBUG("Failed to create OA config for mux_regs\n");
+ err = PTR_ERR(oa_config->mux_regs);
+ goto reg_err;
+ }
+
+ oa_config->b_counter_regs_len = args->n_boolean_regs;
+ oa_config->b_counter_regs =
+ alloc_oa_regs(dev_priv,
+ dev_priv->perf.oa.ops.is_valid_b_counter_reg,
+ u64_to_user_ptr(args->boolean_regs_ptr),
+ args->n_boolean_regs);
+
+ if (IS_ERR(oa_config->b_counter_regs)) {
+ DRM_DEBUG("Failed to create OA config for b_counter_regs\n");
+ err = PTR_ERR(oa_config->b_counter_regs);
+ goto reg_err;
+ }
+
+ if (INTEL_GEN(dev_priv) < 8) {
+ if (args->n_flex_regs != 0) {
+ err = -EINVAL;
+ goto reg_err;
+ }
+ } else {
+ oa_config->flex_regs_len = args->n_flex_regs;
+ oa_config->flex_regs =
+ alloc_oa_regs(dev_priv,
+ dev_priv->perf.oa.ops.is_valid_flex_reg,
+ u64_to_user_ptr(args->flex_regs_ptr),
+ args->n_flex_regs);
+
+ if (IS_ERR(oa_config->flex_regs)) {
+ DRM_DEBUG("Failed to create OA config for flex_regs\n");
+ err = PTR_ERR(oa_config->flex_regs);
+ goto reg_err;
+ }
+ }
+
+ err = mutex_lock_interruptible(&dev_priv->perf.metrics_lock);
+ if (err)
+ goto reg_err;
+
+ /* We shouldn't have too many configs, so this iteration shouldn't be
+ * too costly.
+ */
+ idr_for_each_entry(&dev_priv->perf.metrics_idr, tmp, id) {
+ if (!strcmp(tmp->uuid, oa_config->uuid)) {
+ DRM_DEBUG("OA config already exists with this uuid\n");
+ err = -EADDRINUSE;
+ goto sysfs_err;
+ }
+ }
+
+ err = create_dynamic_oa_sysfs_entry(dev_priv, oa_config);
+ if (err) {
+ DRM_DEBUG("Failed to create sysfs entry for OA config\n");
+ goto sysfs_err;
+ }
+
+ /* Config id 0 is invalid, id 1 for kernel stored test config. */
+ oa_config->id = idr_alloc(&dev_priv->perf.metrics_idr,
+ oa_config, 2,
+ 0, GFP_KERNEL);
+ if (oa_config->id < 0) {
+ DRM_DEBUG("Failed to create sysfs entry for OA config\n");
+ err = oa_config->id;
+ goto sysfs_err;
+ }
+
+ mutex_unlock(&dev_priv->perf.metrics_lock);
+
+ return oa_config->id;
+
+sysfs_err:
+ mutex_unlock(&dev_priv->perf.metrics_lock);
+reg_err:
+ put_oa_config(dev_priv, oa_config);
+ DRM_DEBUG("Failed to add new OA config\n");
+ return err;
+}
+
+/**
+ * i915_perf_remove_config_ioctl - DRM ioctl() for userspace to remove an OA config
+ * @dev: drm device
+ * @data: ioctl data (pointer to u64 integer) copied from userspace
+ * @file: drm file
+ *
+ * Configs can be removed while being used, the will stop appearing in sysfs
+ * and their content will be freed when the stream using the config is closed.
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+int i915_perf_remove_config_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u64 *arg = data;
+ struct i915_oa_config *oa_config;
+ int ret;
+
+ if (!dev_priv->perf.initialized) {
+ DRM_DEBUG("i915 perf interface not available for this system\n");
+ return -ENOTSUPP;
+ }
+
+ if (i915_perf_stream_paranoid && !capable(CAP_SYS_ADMIN)) {
+ DRM_DEBUG("Insufficient privileges to remove i915 OA config\n");
+ return -EACCES;
+ }
+
+ ret = mutex_lock_interruptible(&dev_priv->perf.metrics_lock);
+ if (ret)
+ goto lock_err;
+
+ oa_config = idr_find(&dev_priv->perf.metrics_idr, *arg);
+ if (!oa_config) {
+ DRM_DEBUG("Failed to remove unknown OA config\n");
+ ret = -ENOENT;
+ goto config_err;
+ }
+
+ GEM_BUG_ON(*arg != oa_config->id);
+
+ sysfs_remove_group(dev_priv->perf.metrics_kobj,
+ &oa_config->sysfs_metric);
+
+ idr_remove(&dev_priv->perf.metrics_idr, *arg);
+ put_oa_config(dev_priv, oa_config);
+
+config_err:
+ mutex_unlock(&dev_priv->perf.metrics_lock);
+lock_err:
+ return ret;
+}
+
static struct ctl_table oa_table[] = {
{
.procname = "perf_stream_paranoid",
@@ -3010,9 +3385,14 @@ static struct ctl_table dev_root[] = {
*/
void i915_perf_init(struct drm_i915_private *dev_priv)
{
- dev_priv->perf.oa.n_builtin_sets = 0;
+ dev_priv->perf.oa.timestamp_frequency = 0;
if (IS_HASWELL(dev_priv)) {
+ dev_priv->perf.oa.ops.is_valid_b_counter_reg =
+ gen7_is_valid_b_counter_addr;
+ dev_priv->perf.oa.ops.is_valid_mux_reg =
+ hsw_is_valid_mux_addr;
+ dev_priv->perf.oa.ops.is_valid_flex_reg = NULL;
dev_priv->perf.oa.ops.init_oa_buffer = gen7_init_oa_buffer;
dev_priv->perf.oa.ops.enable_metric_set = hsw_enable_metric_set;
dev_priv->perf.oa.ops.disable_metric_set = hsw_disable_metric_set;
@@ -3025,9 +3405,6 @@ void i915_perf_init(struct drm_i915_private *dev_priv)
dev_priv->perf.oa.timestamp_frequency = 12500000;
dev_priv->perf.oa.oa_formats = hsw_oa_formats;
-
- dev_priv->perf.oa.n_builtin_sets =
- i915_oa_n_builtin_metric_sets_hsw;
} else if (i915.enable_execlists) {
/* Note: that although we could theoretically also support the
* legacy ringbuffer mode on BDW (and earlier iterations of
@@ -3035,6 +3412,22 @@ void i915_perf_init(struct drm_i915_private *dev_priv)
* worth the complexity to maintain now that BDW+ enable
* execlist mode by default.
*/
+ dev_priv->perf.oa.ops.is_valid_b_counter_reg =
+ gen7_is_valid_b_counter_addr;
+ dev_priv->perf.oa.ops.is_valid_mux_reg =
+ gen8_is_valid_mux_addr;
+ dev_priv->perf.oa.ops.is_valid_flex_reg =
+ gen8_is_valid_flex_addr;
+
+ dev_priv->perf.oa.ops.init_oa_buffer = gen8_init_oa_buffer;
+ dev_priv->perf.oa.ops.enable_metric_set = gen8_enable_metric_set;
+ dev_priv->perf.oa.ops.disable_metric_set = gen8_disable_metric_set;
+ dev_priv->perf.oa.ops.oa_enable = gen8_oa_enable;
+ dev_priv->perf.oa.ops.oa_disable = gen8_oa_disable;
+ dev_priv->perf.oa.ops.read = gen8_oa_read;
+ dev_priv->perf.oa.ops.oa_hw_tail_read = gen8_oa_hw_tail_read;
+
+ dev_priv->perf.oa.oa_formats = gen8_plus_oa_formats;
if (IS_GEN8(dev_priv)) {
dev_priv->perf.oa.ctx_oactxctrl_offset = 0x120;
@@ -3043,85 +3436,35 @@ void i915_perf_init(struct drm_i915_private *dev_priv)
dev_priv->perf.oa.timestamp_frequency = 12500000;
dev_priv->perf.oa.gen8_valid_ctx_bit = (1<<25);
-
- if (IS_BROADWELL(dev_priv)) {
- dev_priv->perf.oa.n_builtin_sets =
- i915_oa_n_builtin_metric_sets_bdw;
- dev_priv->perf.oa.ops.select_metric_set =
- i915_oa_select_metric_set_bdw;
- } else if (IS_CHERRYVIEW(dev_priv)) {
- dev_priv->perf.oa.n_builtin_sets =
- i915_oa_n_builtin_metric_sets_chv;
- dev_priv->perf.oa.ops.select_metric_set =
- i915_oa_select_metric_set_chv;
+ if (IS_CHERRYVIEW(dev_priv)) {
+ dev_priv->perf.oa.ops.is_valid_mux_reg =
+ chv_is_valid_mux_addr;
}
} else if (IS_GEN9(dev_priv)) {
dev_priv->perf.oa.ctx_oactxctrl_offset = 0x128;
dev_priv->perf.oa.ctx_flexeu0_offset = 0x3de;
- dev_priv->perf.oa.timestamp_frequency = 12000000;
-
dev_priv->perf.oa.gen8_valid_ctx_bit = (1<<16);
- if (IS_SKL_GT2(dev_priv)) {
- dev_priv->perf.oa.n_builtin_sets =
- i915_oa_n_builtin_metric_sets_sklgt2;
- dev_priv->perf.oa.ops.select_metric_set =
- i915_oa_select_metric_set_sklgt2;
- } else if (IS_SKL_GT3(dev_priv)) {
- dev_priv->perf.oa.n_builtin_sets =
- i915_oa_n_builtin_metric_sets_sklgt3;
- dev_priv->perf.oa.ops.select_metric_set =
- i915_oa_select_metric_set_sklgt3;
- } else if (IS_SKL_GT4(dev_priv)) {
- dev_priv->perf.oa.n_builtin_sets =
- i915_oa_n_builtin_metric_sets_sklgt4;
- dev_priv->perf.oa.ops.select_metric_set =
- i915_oa_select_metric_set_sklgt4;
- } else if (IS_BROXTON(dev_priv)) {
+ switch (dev_priv->info.platform) {
+ case INTEL_BROXTON:
+ case INTEL_GEMINILAKE:
dev_priv->perf.oa.timestamp_frequency = 19200000;
-
- dev_priv->perf.oa.n_builtin_sets =
- i915_oa_n_builtin_metric_sets_bxt;
- dev_priv->perf.oa.ops.select_metric_set =
- i915_oa_select_metric_set_bxt;
- } else if (IS_KBL_GT2(dev_priv)) {
- dev_priv->perf.oa.n_builtin_sets =
- i915_oa_n_builtin_metric_sets_kblgt2;
- dev_priv->perf.oa.ops.select_metric_set =
- i915_oa_select_metric_set_kblgt2;
- } else if (IS_KBL_GT3(dev_priv)) {
- dev_priv->perf.oa.n_builtin_sets =
- i915_oa_n_builtin_metric_sets_kblgt3;
- dev_priv->perf.oa.ops.select_metric_set =
- i915_oa_select_metric_set_kblgt3;
- } else if (IS_GEMINILAKE(dev_priv)) {
- dev_priv->perf.oa.timestamp_frequency = 19200000;
-
- dev_priv->perf.oa.n_builtin_sets =
- i915_oa_n_builtin_metric_sets_glk;
- dev_priv->perf.oa.ops.select_metric_set =
- i915_oa_select_metric_set_glk;
+ break;
+ case INTEL_SKYLAKE:
+ case INTEL_KABYLAKE:
+ dev_priv->perf.oa.timestamp_frequency = 12000000;
+ break;
+ default:
+ /* Leave timestamp_frequency to 0 so we can
+ * detect unsupported platforms.
+ */
+ break;
}
}
-
- if (dev_priv->perf.oa.n_builtin_sets) {
- dev_priv->perf.oa.ops.init_oa_buffer = gen8_init_oa_buffer;
- dev_priv->perf.oa.ops.enable_metric_set =
- gen8_enable_metric_set;
- dev_priv->perf.oa.ops.disable_metric_set =
- gen8_disable_metric_set;
- dev_priv->perf.oa.ops.oa_enable = gen8_oa_enable;
- dev_priv->perf.oa.ops.oa_disable = gen8_oa_disable;
- dev_priv->perf.oa.ops.read = gen8_oa_read;
- dev_priv->perf.oa.ops.oa_hw_tail_read =
- gen8_oa_hw_tail_read;
-
- dev_priv->perf.oa.oa_formats = gen8_plus_oa_formats;
- }
}
- if (dev_priv->perf.oa.n_builtin_sets) {
+ if (dev_priv->perf.oa.timestamp_frequency) {
hrtimer_init(&dev_priv->perf.oa.poll_check_timer,
CLOCK_MONOTONIC, HRTIMER_MODE_REL);
dev_priv->perf.oa.poll_check_timer.function = oa_poll_check_timer_cb;
@@ -3135,10 +3478,23 @@ void i915_perf_init(struct drm_i915_private *dev_priv)
dev_priv->perf.oa.timestamp_frequency / 2;
dev_priv->perf.sysctl_header = register_sysctl_table(dev_root);
+ mutex_init(&dev_priv->perf.metrics_lock);
+ idr_init(&dev_priv->perf.metrics_idr);
+
dev_priv->perf.initialized = true;
}
}
+static int destroy_config(int id, void *p, void *data)
+{
+ struct drm_i915_private *dev_priv = data;
+ struct i915_oa_config *oa_config = p;
+
+ put_oa_config(dev_priv, oa_config);
+
+ return 0;
+}
+
/**
* i915_perf_fini - Counter part to i915_perf_init()
* @dev_priv: i915 device instance
@@ -3148,6 +3504,9 @@ void i915_perf_fini(struct drm_i915_private *dev_priv)
if (!dev_priv->perf.initialized)
return;
+ idr_for_each(&dev_priv->perf.metrics_idr, destroy_config, dev_priv);
+ idr_destroy(&dev_priv->perf.metrics_idr);
+
unregister_sysctl_table(dev_priv->perf.sysctl_header);
memset(&dev_priv->perf.oa.ops, 0, sizeof(dev_priv->perf.oa.ops));
diff --git a/drivers/gpu/drm/i915/i915_pvinfo.h b/drivers/gpu/drm/i915/i915_pvinfo.h
index 2cfe96d3..0679a58 100644
--- a/drivers/gpu/drm/i915/i915_pvinfo.h
+++ b/drivers/gpu/drm/i915/i915_pvinfo.h
@@ -49,12 +49,18 @@ enum vgt_g2v_type {
VGT_G2V_MAX,
};
+/*
+ * VGT capabilities type
+ */
+#define VGT_CAPS_FULL_48BIT_PPGTT BIT(2)
+
struct vgt_if {
u64 magic; /* VGT_MAGIC */
u16 version_major;
u16 version_minor;
u32 vgt_id; /* ID of vGT instance */
- u32 rsv1[12]; /* pad to offset 0x40 */
+ u32 vgt_caps; /* VGT capabilities */
+ u32 rsv1[11]; /* pad to offset 0x40 */
/*
* Data structure to describe the balooning info of resources.
* Each VM can only have one portion of continuous area for now.
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 64cc674..ed7cd9e 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -25,6 +25,97 @@
#ifndef _I915_REG_H_
#define _I915_REG_H_
+/**
+ * DOC: The i915 register macro definition style guide
+ *
+ * Follow the style described here for new macros, and while changing existing
+ * macros. Do **not** mass change existing definitions just to update the style.
+ *
+ * Layout
+ * ''''''
+ *
+ * Keep helper macros near the top. For example, _PIPE() and friends.
+ *
+ * Prefix macros that generally should not be used outside of this file with
+ * underscore '_'. For example, _PIPE() and friends, single instances of
+ * registers that are defined solely for the use by function-like macros.
+ *
+ * Avoid using the underscore prefixed macros outside of this file. There are
+ * exceptions, but keep them to a minimum.
+ *
+ * There are two basic types of register definitions: Single registers and
+ * register groups. Register groups are registers which have two or more
+ * instances, for example one per pipe, port, transcoder, etc. Register groups
+ * should be defined using function-like macros.
+ *
+ * For single registers, define the register offset first, followed by register
+ * contents.
+ *
+ * For register groups, define the register instance offsets first, prefixed
+ * with underscore, followed by a function-like macro choosing the right
+ * instance based on the parameter, followed by register contents.
+ *
+ * Define the register contents (i.e. bit and bit field macros) from most
+ * significant to least significant bit. Indent the register content macros
+ * using two extra spaces between ``#define`` and the macro name.
+ *
+ * For bit fields, define a ``_MASK`` and a ``_SHIFT`` macro. Define bit field
+ * contents so that they are already shifted in place, and can be directly
+ * OR'd. For convenience, function-like macros may be used to define bit fields,
+ * but do note that the macros may be needed to read as well as write the
+ * register contents.
+ *
+ * Define bits using ``(1 << N)`` instead of ``BIT(N)``. We may change this in
+ * the future, but this is the prevailing style. Do **not** add ``_BIT`` suffix
+ * to the name.
+ *
+ * Group the register and its contents together without blank lines, separate
+ * from other registers and their contents with one blank line.
+ *
+ * Indent macro values from macro names using TABs. Align values vertically. Use
+ * braces in macro values as needed to avoid unintended precedence after macro
+ * substitution. Use spaces in macro values according to kernel coding
+ * style. Use lower case in hexadecimal values.
+ *
+ * Naming
+ * ''''''
+ *
+ * Try to name registers according to the specs. If the register name changes in
+ * the specs from platform to another, stick to the original name.
+ *
+ * Try to re-use existing register macro definitions. Only add new macros for
+ * new register offsets, or when the register contents have changed enough to
+ * warrant a full redefinition.
+ *
+ * When a register macro changes for a new platform, prefix the new macro using
+ * the platform acronym or generation. For example, ``SKL_`` or ``GEN8_``. The
+ * prefix signifies the start platform/generation using the register.
+ *
+ * When a bit (field) macro changes or gets added for a new platform, while
+ * retaining the existing register macro, add a platform acronym or generation
+ * suffix to the name. For example, ``_SKL`` or ``_GEN8``.
+ *
+ * Examples
+ * ''''''''
+ *
+ * (Note that the values in the example are indented using spaces instead of
+ * TABs to avoid misalignment in generated documentation. Use TABs in the
+ * definitions.)::
+ *
+ * #define _FOO_A 0xf000
+ * #define _FOO_B 0xf001
+ * #define FOO(pipe) _MMIO_PIPE(pipe, _FOO_A, _FOO_B)
+ * #define FOO_ENABLE (1 << 31)
+ * #define FOO_MODE_MASK (0xf << 16)
+ * #define FOO_MODE_SHIFT 16
+ * #define FOO_MODE_BAR (0 << 16)
+ * #define FOO_MODE_BAZ (1 << 16)
+ * #define FOO_MODE_QUX_SNB (2 << 16)
+ *
+ * #define BAR _MMIO(0xb000)
+ * #define GEN8_BAR _MMIO(0xb888)
+ */
+
typedef struct {
uint32_t reg;
} i915_reg_t;
@@ -229,6 +320,28 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
#define GEN8_RPCS_EU_MIN_SHIFT 0
#define GEN8_RPCS_EU_MIN_MASK (0xf << GEN8_RPCS_EU_MIN_SHIFT)
+#define WAIT_FOR_RC6_EXIT _MMIO(0x20CC)
+/* HSW only */
+#define HSW_SELECTIVE_READ_ADDRESSING_SHIFT 2
+#define HSW_SELECTIVE_READ_ADDRESSING_MASK (0x3 << HSW_SLECTIVE_READ_ADDRESSING_SHIFT)
+#define HSW_SELECTIVE_WRITE_ADDRESS_SHIFT 4
+#define HSW_SELECTIVE_WRITE_ADDRESS_MASK (0x7 << HSW_SELECTIVE_WRITE_ADDRESS_SHIFT)
+/* HSW+ */
+#define HSW_WAIT_FOR_RC6_EXIT_ENABLE (1 << 0)
+#define HSW_RCS_CONTEXT_ENABLE (1 << 7)
+#define HSW_RCS_INHIBIT (1 << 8)
+/* Gen8 */
+#define GEN8_SELECTIVE_WRITE_ADDRESS_SHIFT 4
+#define GEN8_SELECTIVE_WRITE_ADDRESS_MASK (0x3 << GEN8_SELECTIVE_WRITE_ADDRESS_SHIFT)
+#define GEN8_SELECTIVE_WRITE_ADDRESS_SHIFT 4
+#define GEN8_SELECTIVE_WRITE_ADDRESS_MASK (0x3 << GEN8_SELECTIVE_WRITE_ADDRESS_SHIFT)
+#define GEN8_SELECTIVE_WRITE_ADDRESSING_ENABLE (1 << 6)
+#define GEN8_SELECTIVE_READ_SUBSLICE_SELECT_SHIFT 9
+#define GEN8_SELECTIVE_READ_SUBSLICE_SELECT_MASK (0x3 << GEN8_SELECTIVE_READ_SUBSLICE_SELECT_SHIFT)
+#define GEN8_SELECTIVE_READ_SLICE_SELECT_SHIFT 11
+#define GEN8_SELECTIVE_READ_SLICE_SELECT_MASK (0x3 << GEN8_SELECTIVE_READ_SLICE_SELECT_SHIFT)
+#define GEN8_SELECTIVE_READ_ADDRESSING_ENABLE (1 << 13)
+
#define GAM_ECOCHK _MMIO(0x4090)
#define BDW_DISABLE_HDC_INVALIDATION (1<<25)
#define ECOCHK_SNB_BIT (1<<10)
@@ -729,119 +842,10 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
#define EU_PERF_CNTL5 _MMIO(0xe55c)
#define EU_PERF_CNTL6 _MMIO(0xe65c)
-#define GDT_CHICKEN_BITS _MMIO(0x9840)
-#define GT_NOA_ENABLE 0x00000080
-
/*
* OA Boolean state
*/
-#define OAREPORTTRIG1 _MMIO(0x2740)
-#define OAREPORTTRIG1_THRESHOLD_MASK 0xffff
-#define OAREPORTTRIG1_EDGE_LEVEL_TRIGER_SELECT_MASK 0xffff0000 /* 0=level */
-
-#define OAREPORTTRIG2 _MMIO(0x2744)
-#define OAREPORTTRIG2_INVERT_A_0 (1<<0)
-#define OAREPORTTRIG2_INVERT_A_1 (1<<1)
-#define OAREPORTTRIG2_INVERT_A_2 (1<<2)
-#define OAREPORTTRIG2_INVERT_A_3 (1<<3)
-#define OAREPORTTRIG2_INVERT_A_4 (1<<4)
-#define OAREPORTTRIG2_INVERT_A_5 (1<<5)
-#define OAREPORTTRIG2_INVERT_A_6 (1<<6)
-#define OAREPORTTRIG2_INVERT_A_7 (1<<7)
-#define OAREPORTTRIG2_INVERT_A_8 (1<<8)
-#define OAREPORTTRIG2_INVERT_A_9 (1<<9)
-#define OAREPORTTRIG2_INVERT_A_10 (1<<10)
-#define OAREPORTTRIG2_INVERT_A_11 (1<<11)
-#define OAREPORTTRIG2_INVERT_A_12 (1<<12)
-#define OAREPORTTRIG2_INVERT_A_13 (1<<13)
-#define OAREPORTTRIG2_INVERT_A_14 (1<<14)
-#define OAREPORTTRIG2_INVERT_A_15 (1<<15)
-#define OAREPORTTRIG2_INVERT_B_0 (1<<16)
-#define OAREPORTTRIG2_INVERT_B_1 (1<<17)
-#define OAREPORTTRIG2_INVERT_B_2 (1<<18)
-#define OAREPORTTRIG2_INVERT_B_3 (1<<19)
-#define OAREPORTTRIG2_INVERT_C_0 (1<<20)
-#define OAREPORTTRIG2_INVERT_C_1 (1<<21)
-#define OAREPORTTRIG2_INVERT_D_0 (1<<22)
-#define OAREPORTTRIG2_THRESHOLD_ENABLE (1<<23)
-#define OAREPORTTRIG2_REPORT_TRIGGER_ENABLE (1<<31)
-
-#define OAREPORTTRIG3 _MMIO(0x2748)
-#define OAREPORTTRIG3_NOA_SELECT_MASK 0xf
-#define OAREPORTTRIG3_NOA_SELECT_8_SHIFT 0
-#define OAREPORTTRIG3_NOA_SELECT_9_SHIFT 4
-#define OAREPORTTRIG3_NOA_SELECT_10_SHIFT 8
-#define OAREPORTTRIG3_NOA_SELECT_11_SHIFT 12
-#define OAREPORTTRIG3_NOA_SELECT_12_SHIFT 16
-#define OAREPORTTRIG3_NOA_SELECT_13_SHIFT 20
-#define OAREPORTTRIG3_NOA_SELECT_14_SHIFT 24
-#define OAREPORTTRIG3_NOA_SELECT_15_SHIFT 28
-
-#define OAREPORTTRIG4 _MMIO(0x274c)
-#define OAREPORTTRIG4_NOA_SELECT_MASK 0xf
-#define OAREPORTTRIG4_NOA_SELECT_0_SHIFT 0
-#define OAREPORTTRIG4_NOA_SELECT_1_SHIFT 4
-#define OAREPORTTRIG4_NOA_SELECT_2_SHIFT 8
-#define OAREPORTTRIG4_NOA_SELECT_3_SHIFT 12
-#define OAREPORTTRIG4_NOA_SELECT_4_SHIFT 16
-#define OAREPORTTRIG4_NOA_SELECT_5_SHIFT 20
-#define OAREPORTTRIG4_NOA_SELECT_6_SHIFT 24
-#define OAREPORTTRIG4_NOA_SELECT_7_SHIFT 28
-
-#define OAREPORTTRIG5 _MMIO(0x2750)
-#define OAREPORTTRIG5_THRESHOLD_MASK 0xffff
-#define OAREPORTTRIG5_EDGE_LEVEL_TRIGER_SELECT_MASK 0xffff0000 /* 0=level */
-
-#define OAREPORTTRIG6 _MMIO(0x2754)
-#define OAREPORTTRIG6_INVERT_A_0 (1<<0)
-#define OAREPORTTRIG6_INVERT_A_1 (1<<1)
-#define OAREPORTTRIG6_INVERT_A_2 (1<<2)
-#define OAREPORTTRIG6_INVERT_A_3 (1<<3)
-#define OAREPORTTRIG6_INVERT_A_4 (1<<4)
-#define OAREPORTTRIG6_INVERT_A_5 (1<<5)
-#define OAREPORTTRIG6_INVERT_A_6 (1<<6)
-#define OAREPORTTRIG6_INVERT_A_7 (1<<7)
-#define OAREPORTTRIG6_INVERT_A_8 (1<<8)
-#define OAREPORTTRIG6_INVERT_A_9 (1<<9)
-#define OAREPORTTRIG6_INVERT_A_10 (1<<10)
-#define OAREPORTTRIG6_INVERT_A_11 (1<<11)
-#define OAREPORTTRIG6_INVERT_A_12 (1<<12)
-#define OAREPORTTRIG6_INVERT_A_13 (1<<13)
-#define OAREPORTTRIG6_INVERT_A_14 (1<<14)
-#define OAREPORTTRIG6_INVERT_A_15 (1<<15)
-#define OAREPORTTRIG6_INVERT_B_0 (1<<16)
-#define OAREPORTTRIG6_INVERT_B_1 (1<<17)
-#define OAREPORTTRIG6_INVERT_B_2 (1<<18)
-#define OAREPORTTRIG6_INVERT_B_3 (1<<19)
-#define OAREPORTTRIG6_INVERT_C_0 (1<<20)
-#define OAREPORTTRIG6_INVERT_C_1 (1<<21)
-#define OAREPORTTRIG6_INVERT_D_0 (1<<22)
-#define OAREPORTTRIG6_THRESHOLD_ENABLE (1<<23)
-#define OAREPORTTRIG6_REPORT_TRIGGER_ENABLE (1<<31)
-
-#define OAREPORTTRIG7 _MMIO(0x2758)
-#define OAREPORTTRIG7_NOA_SELECT_MASK 0xf
-#define OAREPORTTRIG7_NOA_SELECT_8_SHIFT 0
-#define OAREPORTTRIG7_NOA_SELECT_9_SHIFT 4
-#define OAREPORTTRIG7_NOA_SELECT_10_SHIFT 8
-#define OAREPORTTRIG7_NOA_SELECT_11_SHIFT 12
-#define OAREPORTTRIG7_NOA_SELECT_12_SHIFT 16
-#define OAREPORTTRIG7_NOA_SELECT_13_SHIFT 20
-#define OAREPORTTRIG7_NOA_SELECT_14_SHIFT 24
-#define OAREPORTTRIG7_NOA_SELECT_15_SHIFT 28
-
-#define OAREPORTTRIG8 _MMIO(0x275c)
-#define OAREPORTTRIG8_NOA_SELECT_MASK 0xf
-#define OAREPORTTRIG8_NOA_SELECT_0_SHIFT 0
-#define OAREPORTTRIG8_NOA_SELECT_1_SHIFT 4
-#define OAREPORTTRIG8_NOA_SELECT_2_SHIFT 8
-#define OAREPORTTRIG8_NOA_SELECT_3_SHIFT 12
-#define OAREPORTTRIG8_NOA_SELECT_4_SHIFT 16
-#define OAREPORTTRIG8_NOA_SELECT_5_SHIFT 20
-#define OAREPORTTRIG8_NOA_SELECT_6_SHIFT 24
-#define OAREPORTTRIG8_NOA_SELECT_7_SHIFT 28
-
#define OASTARTTRIG1 _MMIO(0x2710)
#define OASTARTTRIG1_THRESHOLD_COUNT_MASK_MBZ 0xffff0000
#define OASTARTTRIG1_THRESHOLD_MASK 0xffff
@@ -956,6 +960,112 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
#define OASTARTTRIG8_NOA_SELECT_6_SHIFT 24
#define OASTARTTRIG8_NOA_SELECT_7_SHIFT 28
+#define OAREPORTTRIG1 _MMIO(0x2740)
+#define OAREPORTTRIG1_THRESHOLD_MASK 0xffff
+#define OAREPORTTRIG1_EDGE_LEVEL_TRIGER_SELECT_MASK 0xffff0000 /* 0=level */
+
+#define OAREPORTTRIG2 _MMIO(0x2744)
+#define OAREPORTTRIG2_INVERT_A_0 (1<<0)
+#define OAREPORTTRIG2_INVERT_A_1 (1<<1)
+#define OAREPORTTRIG2_INVERT_A_2 (1<<2)
+#define OAREPORTTRIG2_INVERT_A_3 (1<<3)
+#define OAREPORTTRIG2_INVERT_A_4 (1<<4)
+#define OAREPORTTRIG2_INVERT_A_5 (1<<5)
+#define OAREPORTTRIG2_INVERT_A_6 (1<<6)
+#define OAREPORTTRIG2_INVERT_A_7 (1<<7)
+#define OAREPORTTRIG2_INVERT_A_8 (1<<8)
+#define OAREPORTTRIG2_INVERT_A_9 (1<<9)
+#define OAREPORTTRIG2_INVERT_A_10 (1<<10)
+#define OAREPORTTRIG2_INVERT_A_11 (1<<11)
+#define OAREPORTTRIG2_INVERT_A_12 (1<<12)
+#define OAREPORTTRIG2_INVERT_A_13 (1<<13)
+#define OAREPORTTRIG2_INVERT_A_14 (1<<14)
+#define OAREPORTTRIG2_INVERT_A_15 (1<<15)
+#define OAREPORTTRIG2_INVERT_B_0 (1<<16)
+#define OAREPORTTRIG2_INVERT_B_1 (1<<17)
+#define OAREPORTTRIG2_INVERT_B_2 (1<<18)
+#define OAREPORTTRIG2_INVERT_B_3 (1<<19)
+#define OAREPORTTRIG2_INVERT_C_0 (1<<20)
+#define OAREPORTTRIG2_INVERT_C_1 (1<<21)
+#define OAREPORTTRIG2_INVERT_D_0 (1<<22)
+#define OAREPORTTRIG2_THRESHOLD_ENABLE (1<<23)
+#define OAREPORTTRIG2_REPORT_TRIGGER_ENABLE (1<<31)
+
+#define OAREPORTTRIG3 _MMIO(0x2748)
+#define OAREPORTTRIG3_NOA_SELECT_MASK 0xf
+#define OAREPORTTRIG3_NOA_SELECT_8_SHIFT 0
+#define OAREPORTTRIG3_NOA_SELECT_9_SHIFT 4
+#define OAREPORTTRIG3_NOA_SELECT_10_SHIFT 8
+#define OAREPORTTRIG3_NOA_SELECT_11_SHIFT 12
+#define OAREPORTTRIG3_NOA_SELECT_12_SHIFT 16
+#define OAREPORTTRIG3_NOA_SELECT_13_SHIFT 20
+#define OAREPORTTRIG3_NOA_SELECT_14_SHIFT 24
+#define OAREPORTTRIG3_NOA_SELECT_15_SHIFT 28
+
+#define OAREPORTTRIG4 _MMIO(0x274c)
+#define OAREPORTTRIG4_NOA_SELECT_MASK 0xf
+#define OAREPORTTRIG4_NOA_SELECT_0_SHIFT 0
+#define OAREPORTTRIG4_NOA_SELECT_1_SHIFT 4
+#define OAREPORTTRIG4_NOA_SELECT_2_SHIFT 8
+#define OAREPORTTRIG4_NOA_SELECT_3_SHIFT 12
+#define OAREPORTTRIG4_NOA_SELECT_4_SHIFT 16
+#define OAREPORTTRIG4_NOA_SELECT_5_SHIFT 20
+#define OAREPORTTRIG4_NOA_SELECT_6_SHIFT 24
+#define OAREPORTTRIG4_NOA_SELECT_7_SHIFT 28
+
+#define OAREPORTTRIG5 _MMIO(0x2750)
+#define OAREPORTTRIG5_THRESHOLD_MASK 0xffff
+#define OAREPORTTRIG5_EDGE_LEVEL_TRIGER_SELECT_MASK 0xffff0000 /* 0=level */
+
+#define OAREPORTTRIG6 _MMIO(0x2754)
+#define OAREPORTTRIG6_INVERT_A_0 (1<<0)
+#define OAREPORTTRIG6_INVERT_A_1 (1<<1)
+#define OAREPORTTRIG6_INVERT_A_2 (1<<2)
+#define OAREPORTTRIG6_INVERT_A_3 (1<<3)
+#define OAREPORTTRIG6_INVERT_A_4 (1<<4)
+#define OAREPORTTRIG6_INVERT_A_5 (1<<5)
+#define OAREPORTTRIG6_INVERT_A_6 (1<<6)
+#define OAREPORTTRIG6_INVERT_A_7 (1<<7)
+#define OAREPORTTRIG6_INVERT_A_8 (1<<8)
+#define OAREPORTTRIG6_INVERT_A_9 (1<<9)
+#define OAREPORTTRIG6_INVERT_A_10 (1<<10)
+#define OAREPORTTRIG6_INVERT_A_11 (1<<11)
+#define OAREPORTTRIG6_INVERT_A_12 (1<<12)
+#define OAREPORTTRIG6_INVERT_A_13 (1<<13)
+#define OAREPORTTRIG6_INVERT_A_14 (1<<14)
+#define OAREPORTTRIG6_INVERT_A_15 (1<<15)
+#define OAREPORTTRIG6_INVERT_B_0 (1<<16)
+#define OAREPORTTRIG6_INVERT_B_1 (1<<17)
+#define OAREPORTTRIG6_INVERT_B_2 (1<<18)
+#define OAREPORTTRIG6_INVERT_B_3 (1<<19)
+#define OAREPORTTRIG6_INVERT_C_0 (1<<20)
+#define OAREPORTTRIG6_INVERT_C_1 (1<<21)
+#define OAREPORTTRIG6_INVERT_D_0 (1<<22)
+#define OAREPORTTRIG6_THRESHOLD_ENABLE (1<<23)
+#define OAREPORTTRIG6_REPORT_TRIGGER_ENABLE (1<<31)
+
+#define OAREPORTTRIG7 _MMIO(0x2758)
+#define OAREPORTTRIG7_NOA_SELECT_MASK 0xf
+#define OAREPORTTRIG7_NOA_SELECT_8_SHIFT 0
+#define OAREPORTTRIG7_NOA_SELECT_9_SHIFT 4
+#define OAREPORTTRIG7_NOA_SELECT_10_SHIFT 8
+#define OAREPORTTRIG7_NOA_SELECT_11_SHIFT 12
+#define OAREPORTTRIG7_NOA_SELECT_12_SHIFT 16
+#define OAREPORTTRIG7_NOA_SELECT_13_SHIFT 20
+#define OAREPORTTRIG7_NOA_SELECT_14_SHIFT 24
+#define OAREPORTTRIG7_NOA_SELECT_15_SHIFT 28
+
+#define OAREPORTTRIG8 _MMIO(0x275c)
+#define OAREPORTTRIG8_NOA_SELECT_MASK 0xf
+#define OAREPORTTRIG8_NOA_SELECT_0_SHIFT 0
+#define OAREPORTTRIG8_NOA_SELECT_1_SHIFT 4
+#define OAREPORTTRIG8_NOA_SELECT_2_SHIFT 8
+#define OAREPORTTRIG8_NOA_SELECT_3_SHIFT 12
+#define OAREPORTTRIG8_NOA_SELECT_4_SHIFT 16
+#define OAREPORTTRIG8_NOA_SELECT_5_SHIFT 20
+#define OAREPORTTRIG8_NOA_SELECT_6_SHIFT 24
+#define OAREPORTTRIG8_NOA_SELECT_7_SHIFT 28
+
/* CECX_0 */
#define OACEC_COMPARE_LESS_OR_EQUAL 6
#define OACEC_COMPARE_NOT_EQUAL 5
@@ -994,6 +1104,51 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
#define OACEC7_0 _MMIO(0x27a8)
#define OACEC7_1 _MMIO(0x27ac)
+/* OA perf counters */
+#define OA_PERFCNT1_LO _MMIO(0x91B8)
+#define OA_PERFCNT1_HI _MMIO(0x91BC)
+#define OA_PERFCNT2_LO _MMIO(0x91C0)
+#define OA_PERFCNT2_HI _MMIO(0x91C4)
+
+#define OA_PERFMATRIX_LO _MMIO(0x91C8)
+#define OA_PERFMATRIX_HI _MMIO(0x91CC)
+
+/* RPM unit config (Gen8+) */
+#define RPM_CONFIG0 _MMIO(0x0D00)
+#define RPM_CONFIG1 _MMIO(0x0D04)
+
+/* RPC unit config (Gen8+) */
+#define RPM_CONFIG _MMIO(0x0D08)
+
+/* NOA (Gen8+) */
+#define NOA_CONFIG(i) _MMIO(0x0D0C + (i) * 4)
+
+#define MICRO_BP0_0 _MMIO(0x9800)
+#define MICRO_BP0_2 _MMIO(0x9804)
+#define MICRO_BP0_1 _MMIO(0x9808)
+
+#define MICRO_BP1_0 _MMIO(0x980C)
+#define MICRO_BP1_2 _MMIO(0x9810)
+#define MICRO_BP1_1 _MMIO(0x9814)
+
+#define MICRO_BP2_0 _MMIO(0x9818)
+#define MICRO_BP2_2 _MMIO(0x981C)
+#define MICRO_BP2_1 _MMIO(0x9820)
+
+#define MICRO_BP3_0 _MMIO(0x9824)
+#define MICRO_BP3_2 _MMIO(0x9828)
+#define MICRO_BP3_1 _MMIO(0x982C)
+
+#define MICRO_BP_TRIGGER _MMIO(0x9830)
+#define MICRO_BP3_COUNT_STATUS01 _MMIO(0x9834)
+#define MICRO_BP3_COUNT_STATUS23 _MMIO(0x9838)
+#define MICRO_BP_FIRED_ARMED _MMIO(0x983C)
+
+#define GDT_CHICKEN_BITS _MMIO(0x9840)
+#define GT_NOA_ENABLE 0x00000080
+
+#define NOA_DATA _MMIO(0x986C)
+#define NOA_WRITE _MMIO(0x9888)
#define _GEN7_PIPEA_DE_LOAD_SL 0x70068
#define _GEN7_PIPEB_DE_LOAD_SL 0x71068
@@ -1063,9 +1218,26 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
#define DP_SSS_RESET(pipe) _DP_SSS(0x2, (pipe))
#define DP_SSS_PWR_GATE(pipe) _DP_SSS(0x3, (pipe))
-/* See the PUNIT HAS v0.8 for the below bits */
-enum punit_power_well {
- /* These numbers are fixed and must match the position of the pw bits */
+/*
+ * i915_power_well_id:
+ *
+ * Platform specific IDs used to look up power wells and - except for custom
+ * power wells - to define request/status register flag bit positions. As such
+ * the set of IDs on a given platform must be unique and except for custom
+ * power wells their value must stay fixed.
+ */
+enum i915_power_well_id {
+ /*
+ * I830
+ * - custom power well
+ */
+ I830_DISP_PW_PIPES = 0,
+
+ /*
+ * VLV/CHV
+ * - PUNIT_REG_PWRGT_CTRL (bit: id*2),
+ * PUNIT_REG_PWRGT_STATUS (bit: id*2) (PUNIT HAS v0.8)
+ */
PUNIT_POWER_WELL_RENDER = 0,
PUNIT_POWER_WELL_MEDIA = 1,
PUNIT_POWER_WELL_DISP2D = 3,
@@ -1077,14 +1249,20 @@ enum punit_power_well {
PUNIT_POWER_WELL_DPIO_RX0 = 10,
PUNIT_POWER_WELL_DPIO_RX1 = 11,
PUNIT_POWER_WELL_DPIO_CMN_D = 12,
-
- /* Not actual bit groups. Used as IDs for lookup_power_well() */
- PUNIT_POWER_WELL_ALWAYS_ON,
-};
-
-enum skl_disp_power_wells {
- /* These numbers are fixed and must match the position of the pw bits */
- SKL_DISP_PW_MISC_IO,
+ /* - custom power well */
+ CHV_DISP_PW_PIPE_A, /* 13 */
+
+ /*
+ * HSW/BDW
+ * - HSW_PWR_WELL_CTL_DRIVER(0) (status bit: id*2, req bit: id*2+1)
+ */
+ HSW_DISP_PW_GLOBAL = 15,
+
+ /*
+ * GEN9+
+ * - HSW_PWR_WELL_CTL_DRIVER(0) (status bit: id*2, req bit: id*2+1)
+ */
+ SKL_DISP_PW_MISC_IO = 0,
SKL_DISP_PW_DDI_A_E,
GLK_DISP_PW_DDI_A = SKL_DISP_PW_DDI_A_E,
CNL_DISP_PW_DDI_A = SKL_DISP_PW_DDI_A_E,
@@ -1103,18 +1281,20 @@ enum skl_disp_power_wells {
SKL_DISP_PW_1 = 14,
SKL_DISP_PW_2,
- /* Not actual bit groups. Used as IDs for lookup_power_well() */
- SKL_DISP_PW_ALWAYS_ON,
+ /* - custom power wells */
SKL_DISP_PW_DC_OFF,
-
BXT_DPIO_CMN_A,
BXT_DPIO_CMN_BC,
- GLK_DPIO_CMN_C,
+ GLK_DPIO_CMN_C, /* 19 */
+
+ /*
+ * Multiple platforms.
+ * Must start following the highest ID of any platform.
+ * - custom power wells
+ */
+ I915_DISP_PW_ALWAYS_ON = 20,
};
-#define SKL_POWER_WELL_STATE(pw) (1 << ((pw) * 2))
-#define SKL_POWER_WELL_REQ(pw) (1 << (((pw) * 2) + 1))
-
#define PUNIT_REG_PWRGT_CTRL 0x60
#define PUNIT_REG_PWRGT_STATUS 0x61
#define PUNIT_PWRGT_MASK(power_well) (3 << ((power_well) * 2))
@@ -2156,6 +2336,7 @@ enum skl_disp_power_wells {
#define DONE_REG _MMIO(0x40b0)
#define GEN8_PRIVATE_PAT_LO _MMIO(0x40e0)
#define GEN8_PRIVATE_PAT_HI _MMIO(0x40e0 + 4)
+#define GEN10_PAT_INDEX(index) _MMIO(0x40e0 + index*4)
#define BSD_HWS_PGA_GEN7 _MMIO(0x04180)
#define BLT_HWS_PGA_GEN7 _MMIO(0x04280)
#define VEBOX_HWS_PGA_GEN7 _MMIO(0x04380)
@@ -3522,7 +3703,7 @@ enum skl_disp_power_wells {
#define INTERVAL_1_28_US(us) roundup(((us) * 100) >> 7, 25)
#define INTERVAL_1_33_US(us) (((us) * 3) >> 2)
#define INTERVAL_0_833_US(us) (((us) * 6) / 5)
-#define GT_INTERVAL_FROM_US(dev_priv, us) (IS_GEN9(dev_priv) ? \
+#define GT_INTERVAL_FROM_US(dev_priv, us) (INTEL_GEN(dev_priv) >= 9 ? \
(IS_GEN9_LP(dev_priv) ? \
INTERVAL_0_833_US(us) : \
INTERVAL_1_33_US(us)) : \
@@ -3531,7 +3712,7 @@ enum skl_disp_power_wells {
#define INTERVAL_1_28_TO_US(interval) (((interval) << 7) / 100)
#define INTERVAL_1_33_TO_US(interval) (((interval) << 2) / 3)
#define INTERVAL_0_833_TO_US(interval) (((interval) * 5) / 6)
-#define GT_PM_INTERVAL_TO_US(dev_priv, interval) (IS_GEN9(dev_priv) ? \
+#define GT_PM_INTERVAL_TO_US(dev_priv, interval) (INTEL_GEN(dev_priv) >= 9 ? \
(IS_GEN9_LP(dev_priv) ? \
INTERVAL_0_833_TO_US(interval) : \
INTERVAL_1_33_TO_US(interval)) : \
@@ -3783,6 +3964,7 @@ enum {
#define EDP_PSR_CTL _MMIO(dev_priv->psr_mmio_base + 0)
#define EDP_PSR_ENABLE (1<<31)
#define BDW_PSR_SINGLE_FRAME (1<<30)
+#define EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK (1<<29) /* SW can't modify */
#define EDP_PSR_LINK_STANDBY (1<<27)
#define EDP_PSR_MIN_LINK_ENTRY_TIME_MASK (3<<25)
#define EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES (0<<25)
@@ -5227,6 +5409,9 @@ enum {
#define _PIPE_MISC_A 0x70030
#define _PIPE_MISC_B 0x71030
+#define PIPEMISC_YUV420_ENABLE (1<<27)
+#define PIPEMISC_YUV420_MODE_FULL_BLEND (1<<26)
+#define PIPEMISC_OUTPUT_COLORSPACE_YUV (1<<11)
#define PIPEMISC_DITHER_BPC_MASK (7<<5)
#define PIPEMISC_DITHER_8_BPC (0<<5)
#define PIPEMISC_DITHER_10_BPC (1<<5)
@@ -6106,6 +6291,10 @@ enum {
#define _PLANE_KEYMSK_2_A 0x70298
#define _PLANE_KEYMAX_1_A 0x701a0
#define _PLANE_KEYMAX_2_A 0x702a0
+#define _PLANE_AUX_DIST_1_A 0x701c0
+#define _PLANE_AUX_DIST_2_A 0x702c0
+#define _PLANE_AUX_OFFSET_1_A 0x701c4
+#define _PLANE_AUX_OFFSET_2_A 0x702c4
#define _PLANE_COLOR_CTL_1_A 0x701CC /* GLK+ */
#define _PLANE_COLOR_CTL_2_A 0x702CC /* GLK+ */
#define _PLANE_COLOR_CTL_3_A 0x703CC /* GLK+ */
@@ -6212,6 +6401,24 @@ enum {
#define PLANE_NV12_BUF_CFG(pipe, plane) \
_MMIO_PLANE(plane, _PLANE_NV12_BUF_CFG_1(pipe), _PLANE_NV12_BUF_CFG_2(pipe))
+#define _PLANE_AUX_DIST_1_B 0x711c0
+#define _PLANE_AUX_DIST_2_B 0x712c0
+#define _PLANE_AUX_DIST_1(pipe) \
+ _PIPE(pipe, _PLANE_AUX_DIST_1_A, _PLANE_AUX_DIST_1_B)
+#define _PLANE_AUX_DIST_2(pipe) \
+ _PIPE(pipe, _PLANE_AUX_DIST_2_A, _PLANE_AUX_DIST_2_B)
+#define PLANE_AUX_DIST(pipe, plane) \
+ _MMIO_PLANE(plane, _PLANE_AUX_DIST_1(pipe), _PLANE_AUX_DIST_2(pipe))
+
+#define _PLANE_AUX_OFFSET_1_B 0x711c4
+#define _PLANE_AUX_OFFSET_2_B 0x712c4
+#define _PLANE_AUX_OFFSET_1(pipe) \
+ _PIPE(pipe, _PLANE_AUX_OFFSET_1_A, _PLANE_AUX_OFFSET_1_B)
+#define _PLANE_AUX_OFFSET_2(pipe) \
+ _PIPE(pipe, _PLANE_AUX_OFFSET_2_A, _PLANE_AUX_OFFSET_2_B)
+#define PLANE_AUX_OFFSET(pipe, plane) \
+ _MMIO_PLANE(plane, _PLANE_AUX_OFFSET_1(pipe), _PLANE_AUX_OFFSET_2(pipe))
+
#define _PLANE_COLOR_CTL_1_B 0x711CC
#define _PLANE_COLOR_CTL_2_B 0x712CC
#define _PLANE_COLOR_CTL_3_B 0x713CC
@@ -6695,6 +6902,7 @@ enum {
# define CHICKEN3_DGMG_DONE_FIX_DISABLE (1 << 2)
#define CHICKEN_PAR1_1 _MMIO(0x42080)
+#define SKL_RC_HASH_OUTSIDE (1 << 15)
#define DPA_MASK_VBLANK_SRD (1 << 15)
#define FORCE_ARB_IDLE_PLANES (1 << 14)
#define SKL_EDP_PSR_FIX_RDWRAP (1 << 3)
@@ -6703,12 +6911,10 @@ enum {
#define KVM_CONFIG_CHANGE_NOTIFICATION_SELECT (1 << 14)
#define CHICKEN_MISC_2 _MMIO(0x42084)
-#define GLK_CL0_PWR_DOWN (1 << 10)
-#define GLK_CL1_PWR_DOWN (1 << 11)
+#define CNL_COMP_PWR_DOWN (1 << 23)
#define GLK_CL2_PWR_DOWN (1 << 12)
-
-#define CHICKEN_MISC_2 _MMIO(0x42084)
-#define COMP_PWR_DOWN (1 << 23)
+#define GLK_CL1_PWR_DOWN (1 << 11)
+#define GLK_CL0_PWR_DOWN (1 << 10)
#define _CHICKEN_PIPESL_1_A 0x420b0
#define _CHICKEN_PIPESL_1_B 0x420b4
@@ -7984,12 +8190,31 @@ enum {
#define SKL_AUD_CODEC_WAKE_SIGNAL (1 << 15)
/* HSW Power Wells */
-#define HSW_PWR_WELL_BIOS _MMIO(0x45400) /* CTL1 */
-#define HSW_PWR_WELL_DRIVER _MMIO(0x45404) /* CTL2 */
-#define HSW_PWR_WELL_KVMR _MMIO(0x45408) /* CTL3 */
-#define HSW_PWR_WELL_DEBUG _MMIO(0x4540C) /* CTL4 */
-#define HSW_PWR_WELL_ENABLE_REQUEST (1<<31)
-#define HSW_PWR_WELL_STATE_ENABLED (1<<30)
+#define _HSW_PWR_WELL_CTL1 0x45400
+#define _HSW_PWR_WELL_CTL2 0x45404
+#define _HSW_PWR_WELL_CTL3 0x45408
+#define _HSW_PWR_WELL_CTL4 0x4540C
+
+/*
+ * Each power well control register contains up to 16 (request, status) HW
+ * flag tuples. The register index and HW flag shift is determined by the
+ * power well ID (see i915_power_well_id). There are 4 possible sources of
+ * power well requests each source having its own set of control registers:
+ * BIOS, DRIVER, KVMR, DEBUG.
+ */
+#define _HSW_PW_REG_IDX(pw) ((pw) >> 4)
+#define _HSW_PW_SHIFT(pw) (((pw) & 0xf) * 2)
+/* TODO: Add all PWR_WELL_CTL registers below for new platforms */
+#define HSW_PWR_WELL_CTL_BIOS(pw) _MMIO(_PICK(_HSW_PW_REG_IDX(pw), \
+ _HSW_PWR_WELL_CTL1))
+#define HSW_PWR_WELL_CTL_DRIVER(pw) _MMIO(_PICK(_HSW_PW_REG_IDX(pw), \
+ _HSW_PWR_WELL_CTL2))
+#define HSW_PWR_WELL_CTL_KVMR _MMIO(_HSW_PWR_WELL_CTL3)
+#define HSW_PWR_WELL_CTL_DEBUG(pw) _MMIO(_PICK(_HSW_PW_REG_IDX(pw), \
+ _HSW_PWR_WELL_CTL4))
+
+#define HSW_PWR_WELL_CTL_REQ(pw) (1 << (_HSW_PW_SHIFT(pw) + 1))
+#define HSW_PWR_WELL_CTL_STATE(pw) (1 << _HSW_PW_SHIFT(pw))
#define HSW_PWR_WELL_CTL5 _MMIO(0x45410)
#define HSW_PWR_WELL_ENABLE_SINGLE_STEP (1<<31)
#define HSW_PWR_WELL_PWR_GATE_OVERRIDE (1<<20)
@@ -7997,11 +8222,17 @@ enum {
#define HSW_PWR_WELL_CTL6 _MMIO(0x45414)
/* SKL Fuse Status */
+enum skl_power_gate {
+ SKL_PG0,
+ SKL_PG1,
+ SKL_PG2,
+};
+
#define SKL_FUSE_STATUS _MMIO(0x42000)
-#define SKL_FUSE_DOWNLOAD_STATUS (1<<31)
-#define SKL_FUSE_PG0_DIST_STATUS (1<<27)
-#define SKL_FUSE_PG1_DIST_STATUS (1<<26)
-#define SKL_FUSE_PG2_DIST_STATUS (1<<25)
+#define SKL_FUSE_DOWNLOAD_STATUS (1<<31)
+/* PG0 (HW control->no power well ID), PG1..PG2 (SKL_DISP_PW1..SKL_DISP_PW2) */
+#define SKL_PW_TO_PG(pw) ((pw) - SKL_DISP_PW_1 + SKL_PG1)
+#define SKL_FUSE_PG_DIST_STATUS(pg) (1 << (27 - (pg)))
/* Per-pipe DDI Function Control */
#define _TRANS_DDI_FUNC_CTL_A 0x60400
@@ -8343,6 +8574,7 @@ enum {
#define DPLL_CFGCR0_LINK_RATE_3240 (6 << 25)
#define DPLL_CFGCR0_LINK_RATE_4050 (7 << 25)
#define DPLL_CFGCR0_DCO_FRACTION_MASK (0x7fff << 10)
+#define DPLL_CFGCR0_DCO_FRAC_SHIFT (10)
#define DPLL_CFGCR0_DCO_FRACTION(x) ((x) << 10)
#define DPLL_CFGCR0_DCO_INTEGER_MASK (0x3ff)
#define CNL_DPLL_CFGCR0(pll) _MMIO_PLL(pll, _CNL_DPLL0_CFGCR0, _CNL_DPLL1_CFGCR0)
@@ -8350,6 +8582,7 @@ enum {
#define _CNL_DPLL0_CFGCR1 0x6C004
#define _CNL_DPLL1_CFGCR1 0x6C084
#define DPLL_CFGCR1_QDIV_RATIO_MASK (0xff << 10)
+#define DPLL_CFGCR1_QDIV_RATIO_SHIFT (10)
#define DPLL_CFGCR1_QDIV_RATIO(x) ((x) << 10)
#define DPLL_CFGCR1_QDIV_MODE(x) ((x) << 9)
#define DPLL_CFGCR1_KDIV_MASK (7 << 6)
diff --git a/drivers/gpu/drm/i915/i915_selftest.h b/drivers/gpu/drm/i915/i915_selftest.h
index 9d7d86f..78e1a1b 100644
--- a/drivers/gpu/drm/i915/i915_selftest.h
+++ b/drivers/gpu/drm/i915/i915_selftest.h
@@ -101,6 +101,4 @@ bool __igt_timeout(unsigned long timeout, const char *fmt, ...);
#define igt_timeout(t, fmt, ...) \
__igt_timeout((t), KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__)
-#define igt_can_mi_store_dword_imm(D) (INTEL_GEN(D) > 2)
-
#endif /* !__I915_SELFTEST_H__ */
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
index 1eef3fa..d61c872 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -96,7 +96,7 @@ static struct attribute *rc6_attrs[] = {
NULL
};
-static struct attribute_group rc6_attr_group = {
+static const struct attribute_group rc6_attr_group = {
.name = power_group_name,
.attrs = rc6_attrs
};
@@ -107,7 +107,7 @@ static struct attribute *rc6p_attrs[] = {
NULL
};
-static struct attribute_group rc6p_attr_group = {
+static const struct attribute_group rc6p_attr_group = {
.name = power_group_name,
.attrs = rc6p_attrs
};
@@ -117,7 +117,7 @@ static struct attribute *media_rc6_attrs[] = {
NULL
};
-static struct attribute_group media_rc6_attr_group = {
+static const struct attribute_group media_rc6_attr_group = {
.name = power_group_name,
.attrs = media_rc6_attrs
};
@@ -209,7 +209,7 @@ i915_l3_write(struct file *filp, struct kobject *kobj,
memcpy(*remap_info + (offset/4), buf, count);
/* NB: We defer the remapping until we switch to the context */
- list_for_each_entry(ctx, &dev_priv->context_list, link)
+ list_for_each_entry(ctx, &dev_priv->contexts.list, link)
ctx->remap_slice |= (1<<slice);
ret = count;
@@ -220,7 +220,7 @@ out:
return ret;
}
-static struct bin_attribute dpf_attrs = {
+static const struct bin_attribute dpf_attrs = {
.attr = {.name = "l3_parity", .mode = (S_IRUSR | S_IWUSR)},
.size = GEN7_L3LOG_SIZE,
.read = i915_l3_read,
@@ -229,7 +229,7 @@ static struct bin_attribute dpf_attrs = {
.private = (void *)0
};
-static struct bin_attribute dpf_attrs_1 = {
+static const struct bin_attribute dpf_attrs_1 = {
.attr = {.name = "l3_parity_slice_1", .mode = (S_IRUSR | S_IWUSR)},
.size = GEN7_L3LOG_SIZE,
.read = i915_l3_read,
@@ -253,7 +253,7 @@ static ssize_t gt_act_freq_mhz_show(struct device *kdev,
ret = intel_gpu_freq(dev_priv, (freq >> 8) & 0xff);
} else {
u32 rpstat = I915_READ(GEN6_RPSTAT1);
- if (IS_GEN9(dev_priv))
+ if (INTEL_GEN(dev_priv) >= 9)
ret = (rpstat & GEN9_CAGF_MASK) >> GEN9_CAGF_SHIFT;
else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
ret = (rpstat & HSW_CAGF_MASK) >> HSW_CAGF_SHIFT;
@@ -532,7 +532,7 @@ static ssize_t error_state_write(struct file *file, struct kobject *kobj,
return count;
}
-static struct bin_attribute error_state_attr = {
+static const struct bin_attribute error_state_attr = {
.attr.name = "error",
.attr.mode = S_IRUSR | S_IWUSR,
.size = 0,
diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c
index cf7a958..5fe9f3f 100644
--- a/drivers/gpu/drm/i915/i915_vgpu.c
+++ b/drivers/gpu/drm/i915/i915_vgpu.c
@@ -75,10 +75,17 @@ void i915_check_vgpu(struct drm_i915_private *dev_priv)
return;
}
+ dev_priv->vgpu.caps = __raw_i915_read32(dev_priv, vgtif_reg(vgt_caps));
+
dev_priv->vgpu.active = true;
DRM_INFO("Virtual GPU for Intel GVT-g detected.\n");
}
+bool intel_vgpu_has_full_48bit_ppgtt(struct drm_i915_private *dev_priv)
+{
+ return dev_priv->vgpu.caps & VGT_CAPS_FULL_48BIT_PPGTT;
+}
+
struct _balloon_info_ {
/*
* There are up to 2 regions per mappable/unmappable graphic
diff --git a/drivers/gpu/drm/i915/i915_vgpu.h b/drivers/gpu/drm/i915/i915_vgpu.h
index 3c3b2d2..b72bd29 100644
--- a/drivers/gpu/drm/i915/i915_vgpu.h
+++ b/drivers/gpu/drm/i915/i915_vgpu.h
@@ -27,6 +27,9 @@
#include "i915_pvinfo.h"
void i915_check_vgpu(struct drm_i915_private *dev_priv);
+
+bool intel_vgpu_has_full_48bit_ppgtt(struct drm_i915_private *dev_priv);
+
int intel_vgt_balloon(struct drm_i915_private *dev_priv);
void intel_vgt_deballoon(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 1cfe137..02d1a5e 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -579,11 +579,17 @@ err_unpin:
static void i915_vma_destroy(struct i915_vma *vma)
{
+ int i;
+
GEM_BUG_ON(vma->node.allocated);
GEM_BUG_ON(i915_vma_is_active(vma));
GEM_BUG_ON(!i915_vma_is_closed(vma));
GEM_BUG_ON(vma->fence);
+ for (i = 0; i < ARRAY_SIZE(vma->last_read); i++)
+ GEM_BUG_ON(i915_gem_active_isset(&vma->last_read[i]));
+ GEM_BUG_ON(i915_gem_active_isset(&vma->last_fence));
+
list_del(&vma->vm_link);
if (!i915_vma_is_ggtt(vma))
i915_ppgtt_put(i915_vm_to_ppgtt(vma->vm));
@@ -591,33 +597,11 @@ static void i915_vma_destroy(struct i915_vma *vma)
kmem_cache_free(to_i915(vma->obj->base.dev)->vmas, vma);
}
-void i915_vma_unlink_ctx(struct i915_vma *vma)
-{
- struct i915_gem_context *ctx = vma->ctx;
-
- if (ctx->vma_lut.ht_size & I915_CTX_RESIZE_IN_PROGRESS) {
- cancel_work_sync(&ctx->vma_lut.resize);
- ctx->vma_lut.ht_size &= ~I915_CTX_RESIZE_IN_PROGRESS;
- }
-
- __hlist_del(&vma->ctx_node);
- ctx->vma_lut.ht_count--;
-
- if (i915_vma_is_ggtt(vma))
- vma->obj->vma_hashed = NULL;
- vma->ctx = NULL;
-
- i915_vma_put(vma);
-}
-
void i915_vma_close(struct i915_vma *vma)
{
GEM_BUG_ON(i915_vma_is_closed(vma));
vma->flags |= I915_VMA_CLOSED;
- if (vma->ctx)
- i915_vma_unlink_ctx(vma);
-
list_del(&vma->obj_link);
rb_erase(&vma->obj_node, &vma->obj->vma_tree);
@@ -680,9 +664,8 @@ int i915_vma_unbind(struct i915_vma *vma)
__i915_vma_unpin(vma);
if (ret)
return ret;
-
- GEM_BUG_ON(i915_vma_is_active(vma));
}
+ GEM_BUG_ON(i915_vma_is_active(vma));
if (i915_vma_is_pinned(vma))
return -EBUSY;
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 20cf272..1fd61e8 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -112,13 +112,9 @@ struct i915_vma {
/**
* Used for performing relocations during execbuffer insertion.
*/
- struct drm_i915_gem_exec_object2 *exec_entry;
+ unsigned int *exec_flags;
struct hlist_node exec_node;
u32 exec_handle;
-
- struct i915_gem_context *ctx;
- struct hlist_node ctx_node;
- u32 ctx_handle;
};
struct i915_vma *
diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
index 4325cb0..ee76fab 100644
--- a/drivers/gpu/drm/i915/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
@@ -114,6 +114,8 @@ int intel_plane_atomic_check_with_state(struct intel_crtc_state *crtc_state,
struct drm_i915_private *dev_priv = to_i915(plane->dev);
struct drm_plane_state *state = &intel_state->base;
struct intel_plane *intel_plane = to_intel_plane(plane);
+ const struct drm_display_mode *adjusted_mode =
+ &crtc_state->base.adjusted_mode;
int ret;
/*
@@ -173,6 +175,19 @@ int intel_plane_atomic_check_with_state(struct intel_crtc_state *crtc_state,
if (ret)
return ret;
+ /*
+ * Y-tiling is not supported in IF-ID Interlace mode in
+ * GEN9 and above.
+ */
+ if (state->fb && INTEL_GEN(dev_priv) >= 9 && crtc_state->base.enable &&
+ adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
+ if (state->fb->modifier == I915_FORMAT_MOD_Y_TILED ||
+ state->fb->modifier == I915_FORMAT_MOD_Yf_TILED) {
+ DRM_DEBUG_KMS("Y/Yf tiling not supported in IF-ID mode\n");
+ return -EINVAL;
+ }
+ }
+
/* FIXME pre-g4x don't work like this */
if (intel_state->base.visible)
crtc_state->active_planes |= BIT(intel_plane->id);
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 7ea7fd1..183e87e 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -1190,6 +1190,15 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
if (is_dvi) {
info->alternate_ddc_pin = ddc_pin;
+ /*
+ * All VBTs that we got so far for B Stepping has this
+ * information wrong for Port D. So, let's just ignore for now.
+ */
+ if (IS_CNL_REVID(dev_priv, CNL_REVID_B0, CNL_REVID_B0) &&
+ port == PORT_D) {
+ info->alternate_ddc_pin = 0;
+ }
+
sanitize_ddc_pin(dev_priv, port);
}
diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c
index 17c4ae7..8e4e8296 100644
--- a/drivers/gpu/drm/i915/intel_color.c
+++ b/drivers/gpu/drm/i915/intel_color.c
@@ -41,6 +41,22 @@
#define LEGACY_LUT_LENGTH (sizeof(struct drm_color_lut) * 256)
+/* Post offset values for RGB->YCBCR conversion */
+#define POSTOFF_RGB_TO_YUV_HI 0x800
+#define POSTOFF_RGB_TO_YUV_ME 0x100
+#define POSTOFF_RGB_TO_YUV_LO 0x800
+
+/*
+ * These values are direct register values specified in the Bspec,
+ * for RGB->YUV conversion matrix (colorspace BT709)
+ */
+#define CSC_RGB_TO_YUV_RU_GU 0x2ba809d8
+#define CSC_RGB_TO_YUV_BU 0x37e80000
+#define CSC_RGB_TO_YUV_RY_GY 0x1e089cc0
+#define CSC_RGB_TO_YUV_BY 0xb5280000
+#define CSC_RGB_TO_YUV_RV_GV 0xbce89ad8
+#define CSC_RGB_TO_YUV_BV 0x1e080000
+
/*
* Extract the CSC coefficient from a CTM coefficient (in U32.32 fixed point
* format). This macro takes the coefficient we want transformed and the
@@ -91,6 +107,30 @@ static void ctm_mult_by_limited(uint64_t *result, int64_t *input)
}
}
+void i9xx_load_ycbcr_conversion_matrix(struct intel_crtc *intel_crtc)
+{
+ int pipe = intel_crtc->pipe;
+ struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
+
+ I915_WRITE(PIPE_CSC_PREOFF_HI(pipe), 0);
+ I915_WRITE(PIPE_CSC_PREOFF_ME(pipe), 0);
+ I915_WRITE(PIPE_CSC_PREOFF_LO(pipe), 0);
+
+ I915_WRITE(PIPE_CSC_COEFF_RU_GU(pipe), CSC_RGB_TO_YUV_RU_GU);
+ I915_WRITE(PIPE_CSC_COEFF_BU(pipe), CSC_RGB_TO_YUV_BU);
+
+ I915_WRITE(PIPE_CSC_COEFF_RY_GY(pipe), CSC_RGB_TO_YUV_RY_GY);
+ I915_WRITE(PIPE_CSC_COEFF_BY(pipe), CSC_RGB_TO_YUV_BY);
+
+ I915_WRITE(PIPE_CSC_COEFF_RV_GV(pipe), CSC_RGB_TO_YUV_RV_GV);
+ I915_WRITE(PIPE_CSC_COEFF_BV(pipe), CSC_RGB_TO_YUV_BV);
+
+ I915_WRITE(PIPE_CSC_POSTOFF_HI(pipe), POSTOFF_RGB_TO_YUV_HI);
+ I915_WRITE(PIPE_CSC_POSTOFF_ME(pipe), POSTOFF_RGB_TO_YUV_ME);
+ I915_WRITE(PIPE_CSC_POSTOFF_LO(pipe), POSTOFF_RGB_TO_YUV_LO);
+ I915_WRITE(PIPE_CSC_MODE(pipe), 0);
+}
+
/* Set up the pipe CSC unit. */
static void i9xx_load_csc_matrix(struct drm_crtc_state *crtc_state)
{
@@ -101,7 +141,10 @@ static void i9xx_load_csc_matrix(struct drm_crtc_state *crtc_state)
uint16_t coeffs[9] = { 0, };
struct intel_crtc_state *intel_crtc_state = to_intel_crtc_state(crtc_state);
- if (crtc_state->ctm) {
+ if (intel_crtc_state->ycbcr420) {
+ i9xx_load_ycbcr_conversion_matrix(intel_crtc);
+ return;
+ } else if (crtc_state->ctm) {
struct drm_color_ctm *ctm =
(struct drm_color_ctm *)crtc_state->ctm->data;
uint64_t input[9] = { 0, };
@@ -616,7 +659,7 @@ void intel_color_init(struct drm_crtc *crtc)
IS_BROXTON(dev_priv)) {
dev_priv->display.load_csc_matrix = i9xx_load_csc_matrix;
dev_priv->display.load_luts = broadwell_load_luts;
- } else if (IS_GEMINILAKE(dev_priv)) {
+ } else if (IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) {
dev_priv->display.load_csc_matrix = i9xx_load_csc_matrix;
dev_priv->display.load_luts = glk_load_luts;
} else {
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 84a1f5e..70e0ff4 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -802,12 +802,10 @@ void intel_crt_reset(struct drm_encoder *encoder)
*/
static const struct drm_connector_funcs intel_crt_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.late_register = intel_connector_register,
.early_unregister = intel_connector_unregister,
.destroy = intel_crt_destroy,
- .set_property = drm_atomic_helper_connector_set_property,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
};
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index d3b3252..4b4fd1f 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1103,6 +1103,62 @@ static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
return dco_freq / (p0 * p1 * p2 * 5);
}
+static int cnl_calc_wrpll_link(struct drm_i915_private *dev_priv,
+ uint32_t pll_id)
+{
+ uint32_t cfgcr0, cfgcr1;
+ uint32_t p0, p1, p2, dco_freq, ref_clock;
+
+ cfgcr0 = I915_READ(CNL_DPLL_CFGCR0(pll_id));
+ cfgcr1 = I915_READ(CNL_DPLL_CFGCR1(pll_id));
+
+ p0 = cfgcr1 & DPLL_CFGCR1_PDIV_MASK;
+ p2 = cfgcr1 & DPLL_CFGCR1_KDIV_MASK;
+
+ if (cfgcr1 & DPLL_CFGCR1_QDIV_MODE(1))
+ p1 = (cfgcr1 & DPLL_CFGCR1_QDIV_RATIO_MASK) >>
+ DPLL_CFGCR1_QDIV_RATIO_SHIFT;
+ else
+ p1 = 1;
+
+
+ switch (p0) {
+ case DPLL_CFGCR1_PDIV_2:
+ p0 = 2;
+ break;
+ case DPLL_CFGCR1_PDIV_3:
+ p0 = 3;
+ break;
+ case DPLL_CFGCR1_PDIV_5:
+ p0 = 5;
+ break;
+ case DPLL_CFGCR1_PDIV_7:
+ p0 = 7;
+ break;
+ }
+
+ switch (p2) {
+ case DPLL_CFGCR1_KDIV_1:
+ p2 = 1;
+ break;
+ case DPLL_CFGCR1_KDIV_2:
+ p2 = 2;
+ break;
+ case DPLL_CFGCR1_KDIV_4:
+ p2 = 4;
+ break;
+ }
+
+ ref_clock = dev_priv->cdclk.hw.ref;
+
+ dco_freq = (cfgcr0 & DPLL_CFGCR0_DCO_INTEGER_MASK) * ref_clock;
+
+ dco_freq += (((cfgcr0 & DPLL_CFGCR0_DCO_FRACTION_MASK) >>
+ DPLL_CFGCR0_DCO_FRAC_SHIFT) * ref_clock) / 0x8000;
+
+ return dco_freq / (p0 * p1 * p2 * 5);
+}
+
static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
{
int dotclock;
@@ -1118,12 +1174,68 @@ static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
else
dotclock = pipe_config->port_clock;
+ if (pipe_config->ycbcr420)
+ dotclock *= 2;
+
if (pipe_config->pixel_multiplier)
dotclock /= pipe_config->pixel_multiplier;
pipe_config->base.adjusted_mode.crtc_clock = dotclock;
}
+static void cnl_ddi_clock_get(struct intel_encoder *encoder,
+ struct intel_crtc_state *pipe_config)
+{
+ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+ int link_clock = 0;
+ uint32_t cfgcr0, pll_id;
+
+ pll_id = intel_get_shared_dpll_id(dev_priv, pipe_config->shared_dpll);
+
+ cfgcr0 = I915_READ(CNL_DPLL_CFGCR0(pll_id));
+
+ if (cfgcr0 & DPLL_CFGCR0_HDMI_MODE) {
+ link_clock = cnl_calc_wrpll_link(dev_priv, pll_id);
+ } else {
+ link_clock = cfgcr0 & DPLL_CFGCR0_LINK_RATE_MASK;
+
+ switch (link_clock) {
+ case DPLL_CFGCR0_LINK_RATE_810:
+ link_clock = 81000;
+ break;
+ case DPLL_CFGCR0_LINK_RATE_1080:
+ link_clock = 108000;
+ break;
+ case DPLL_CFGCR0_LINK_RATE_1350:
+ link_clock = 135000;
+ break;
+ case DPLL_CFGCR0_LINK_RATE_1620:
+ link_clock = 162000;
+ break;
+ case DPLL_CFGCR0_LINK_RATE_2160:
+ link_clock = 216000;
+ break;
+ case DPLL_CFGCR0_LINK_RATE_2700:
+ link_clock = 270000;
+ break;
+ case DPLL_CFGCR0_LINK_RATE_3240:
+ link_clock = 324000;
+ break;
+ case DPLL_CFGCR0_LINK_RATE_4050:
+ link_clock = 405000;
+ break;
+ default:
+ WARN(1, "Unsupported link rate\n");
+ break;
+ }
+ link_clock *= 2;
+ }
+
+ pipe_config->port_clock = link_clock;
+
+ ddi_dotclock_get(pipe_config);
+}
+
static void skl_ddi_clock_get(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config)
{
@@ -1267,6 +1379,8 @@ void intel_ddi_clock_get(struct intel_encoder *encoder,
skl_ddi_clock_get(encoder, pipe_config);
else if (IS_GEN9_LP(dev_priv))
bxt_ddi_clock_get(encoder, pipe_config);
+ else if (IS_CANNONLAKE(dev_priv))
+ cnl_ddi_clock_get(encoder, pipe_config);
}
void intel_ddi_set_pipe_settings(const struct intel_crtc_state *crtc_state)
@@ -1868,9 +1982,12 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder, u32 level)
if ((intel_dp) && (type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP)) {
width = intel_dp->lane_count;
rate = intel_dp->link_rate;
- } else {
+ } else if (type == INTEL_OUTPUT_HDMI) {
width = 4;
/* Rate is always < than 6GHz for HDMI */
+ } else {
+ MISSING_CASE(type);
+ return;
}
/*
diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c
index 77d3214..5f91ddc 100644
--- a/drivers/gpu/drm/i915/intel_device_info.c
+++ b/drivers/gpu/drm/i915/intel_device_info.c
@@ -363,7 +363,7 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv)
*/
if (fuse_strap & ILK_INTERNAL_DISPLAY_DISABLE ||
sfuse_strap & SFUSE_STRAP_DISPLAY_DISABLED ||
- (dev_priv->pch_type == PCH_CPT &&
+ (HAS_PCH_CPT(dev_priv) &&
!(sfuse_strap & SFUSE_STRAP_FUSE_LOCK))) {
DRM_INFO("Display fused off, disabling\n");
info->num_pipes = 0;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index cc484b5..0e93ec2 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -49,11 +49,6 @@
#include <linux/dma_remapping.h>
#include <linux/reservation.h>
-static bool is_mmio_work(struct intel_flip_work *work)
-{
- return work->mmio_work.func;
-}
-
/* Primary plane formats for gen <= 3 */
static const uint32_t i8xx_primary_formats[] = {
DRM_FORMAT_C8,
@@ -72,6 +67,12 @@ static const uint32_t i965_primary_formats[] = {
DRM_FORMAT_XBGR2101010,
};
+static const uint64_t i9xx_format_modifiers[] = {
+ I915_FORMAT_MOD_X_TILED,
+ DRM_FORMAT_MOD_LINEAR,
+ DRM_FORMAT_MOD_INVALID
+};
+
static const uint32_t skl_primary_formats[] = {
DRM_FORMAT_C8,
DRM_FORMAT_RGB565,
@@ -87,11 +88,34 @@ static const uint32_t skl_primary_formats[] = {
DRM_FORMAT_VYUY,
};
+static const uint64_t skl_format_modifiers_noccs[] = {
+ I915_FORMAT_MOD_Yf_TILED,
+ I915_FORMAT_MOD_Y_TILED,
+ I915_FORMAT_MOD_X_TILED,
+ DRM_FORMAT_MOD_LINEAR,
+ DRM_FORMAT_MOD_INVALID
+};
+
+static const uint64_t skl_format_modifiers_ccs[] = {
+ I915_FORMAT_MOD_Yf_TILED_CCS,
+ I915_FORMAT_MOD_Y_TILED_CCS,
+ I915_FORMAT_MOD_Yf_TILED,
+ I915_FORMAT_MOD_Y_TILED,
+ I915_FORMAT_MOD_X_TILED,
+ DRM_FORMAT_MOD_LINEAR,
+ DRM_FORMAT_MOD_INVALID
+};
+
/* Cursor formats */
static const uint32_t intel_cursor_formats[] = {
DRM_FORMAT_ARGB8888,
};
+static const uint64_t cursor_format_modifiers[] = {
+ DRM_FORMAT_MOD_LINEAR,
+ DRM_FORMAT_MOD_INVALID
+};
+
static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config);
static void ironlake_pch_clock_get(struct intel_crtc *crtc,
@@ -1777,7 +1801,7 @@ static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv,
/* FDI must be feeding us bits for PCH ports */
assert_fdi_tx_enabled(dev_priv, (enum pipe) cpu_transcoder);
- assert_fdi_rx_enabled(dev_priv, TRANSCODER_A);
+ assert_fdi_rx_enabled(dev_priv, PIPE_A);
/* Workaround: set timing override bit. */
val = I915_READ(TRANS_CHICKEN2(PIPE_A));
@@ -1853,16 +1877,16 @@ void lpt_disable_pch_transcoder(struct drm_i915_private *dev_priv)
I915_WRITE(TRANS_CHICKEN2(PIPE_A), val);
}
-enum transcoder intel_crtc_pch_transcoder(struct intel_crtc *crtc)
+enum pipe intel_crtc_pch_transcoder(struct intel_crtc *crtc)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
WARN_ON(!crtc->config->has_pch_encoder);
if (HAS_PCH_LPT(dev_priv))
- return TRANSCODER_A;
+ return PIPE_A;
else
- return (enum transcoder) crtc->pipe;
+ return crtc->pipe;
}
/**
@@ -1901,7 +1925,7 @@ static void intel_enable_pipe(struct intel_crtc *crtc)
if (crtc->config->has_pch_encoder) {
/* if driving the PCH, we need FDI enabled */
assert_fdi_rx_pll_enabled(dev_priv,
- (enum pipe) intel_crtc_pch_transcoder(crtc));
+ intel_crtc_pch_transcoder(crtc));
assert_fdi_tx_pll_enabled(dev_priv,
(enum pipe) cpu_transcoder);
}
@@ -1999,11 +2023,19 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int plane)
return 128;
else
return 512;
+ case I915_FORMAT_MOD_Y_TILED_CCS:
+ if (plane == 1)
+ return 128;
+ /* fall through */
case I915_FORMAT_MOD_Y_TILED:
if (IS_GEN2(dev_priv) || HAS_128_BYTE_Y_TILING(dev_priv))
return 128;
else
return 512;
+ case I915_FORMAT_MOD_Yf_TILED_CCS:
+ if (plane == 1)
+ return 128;
+ /* fall through */
case I915_FORMAT_MOD_Yf_TILED:
switch (cpp) {
case 1:
@@ -2110,7 +2142,7 @@ static unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
struct drm_i915_private *dev_priv = to_i915(fb->dev);
/* AUX_DIST needs only 4K alignment */
- if (fb->format->format == DRM_FORMAT_NV12 && plane == 1)
+ if (plane == 1)
return 4096;
switch (fb->modifier) {
@@ -2120,6 +2152,8 @@ static unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
if (INTEL_GEN(dev_priv) >= 9)
return 256 * 1024;
return 0;
+ case I915_FORMAT_MOD_Y_TILED_CCS:
+ case I915_FORMAT_MOD_Yf_TILED_CCS:
case I915_FORMAT_MOD_Y_TILED:
case I915_FORMAT_MOD_Yf_TILED:
return 1 * 1024 * 1024;
@@ -2162,6 +2196,8 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, unsigned int rotation)
*/
intel_runtime_pm_get(dev_priv);
+ atomic_inc(&dev_priv->gpu_error.pending_fb_pin);
+
vma = i915_gem_object_pin_to_display_plane(obj, alignment, &view);
if (IS_ERR(vma))
goto err;
@@ -2189,6 +2225,8 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, unsigned int rotation)
i915_vma_get(vma);
err:
+ atomic_dec(&dev_priv->gpu_error.pending_fb_pin);
+
intel_runtime_pm_put(dev_priv);
return vma;
}
@@ -2427,12 +2465,48 @@ static unsigned int intel_fb_modifier_to_tiling(uint64_t fb_modifier)
case I915_FORMAT_MOD_X_TILED:
return I915_TILING_X;
case I915_FORMAT_MOD_Y_TILED:
+ case I915_FORMAT_MOD_Y_TILED_CCS:
return I915_TILING_Y;
default:
return I915_TILING_NONE;
}
}
+static const struct drm_format_info ccs_formats[] = {
+ { .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
+ { .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
+ { .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
+ { .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
+};
+
+static const struct drm_format_info *
+lookup_format_info(const struct drm_format_info formats[],
+ int num_formats, u32 format)
+{
+ int i;
+
+ for (i = 0; i < num_formats; i++) {
+ if (formats[i].format == format)
+ return &formats[i];
+ }
+
+ return NULL;
+}
+
+static const struct drm_format_info *
+intel_get_format_info(const struct drm_mode_fb_cmd2 *cmd)
+{
+ switch (cmd->modifier[0]) {
+ case I915_FORMAT_MOD_Y_TILED_CCS:
+ case I915_FORMAT_MOD_Yf_TILED_CCS:
+ return lookup_format_info(ccs_formats,
+ ARRAY_SIZE(ccs_formats),
+ cmd->pixel_format);
+ default:
+ return NULL;
+ }
+}
+
static int
intel_fill_fb_info(struct drm_i915_private *dev_priv,
struct drm_framebuffer *fb)
@@ -2456,6 +2530,36 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv,
intel_fb_offset_to_xy(&x, &y, fb, i);
+ if ((fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
+ fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS) && i == 1) {
+ int hsub = fb->format->hsub;
+ int vsub = fb->format->vsub;
+ int tile_width, tile_height;
+ int main_x, main_y;
+ int ccs_x, ccs_y;
+
+ intel_tile_dims(fb, i, &tile_width, &tile_height);
+
+ ccs_x = (x * hsub) % (tile_width * hsub);
+ ccs_y = (y * vsub) % (tile_height * vsub);
+ main_x = intel_fb->normal[0].x % (tile_width * hsub);
+ main_y = intel_fb->normal[0].y % (tile_height * vsub);
+
+ /*
+ * CCS doesn't have its own x/y offset register, so the intra CCS tile
+ * x/y offsets must match between CCS and the main surface.
+ */
+ if (main_x != ccs_x || main_y != ccs_y) {
+ DRM_DEBUG_KMS("Bad CCS x/y (main %d,%d ccs %d,%d) full (main %d,%d ccs %d,%d)\n",
+ main_x, main_y,
+ ccs_x, ccs_y,
+ intel_fb->normal[0].x,
+ intel_fb->normal[0].y,
+ x, y);
+ return -EINVAL;
+ }
+ }
+
/*
* The fence (if used) is aligned to the start of the object
* so having the framebuffer wrap around across the edge of the
@@ -2664,20 +2768,6 @@ out_unref_obj:
return false;
}
-/* Update plane->state->fb to match plane->fb after driver-internal updates */
-static void
-update_state_fb(struct drm_plane *plane)
-{
- if (plane->fb == plane->state->fb)
- return;
-
- if (plane->state->fb)
- drm_framebuffer_unreference(plane->state->fb);
- plane->state->fb = plane->fb;
- if (plane->state->fb)
- drm_framebuffer_reference(plane->state->fb);
-}
-
static void
intel_set_plane_visible(struct intel_crtc_state *crtc_state,
struct intel_plane_state *plane_state,
@@ -2830,6 +2920,9 @@ static int skl_max_plane_width(const struct drm_framebuffer *fb, int plane,
break;
}
break;
+ case I915_FORMAT_MOD_Y_TILED_CCS:
+ case I915_FORMAT_MOD_Yf_TILED_CCS:
+ /* FIXME AUX plane? */
case I915_FORMAT_MOD_Y_TILED:
case I915_FORMAT_MOD_Yf_TILED:
switch (cpp) {
@@ -2852,6 +2945,44 @@ static int skl_max_plane_width(const struct drm_framebuffer *fb, int plane,
return 2048;
}
+static bool skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state,
+ int main_x, int main_y, u32 main_offset)
+{
+ const struct drm_framebuffer *fb = plane_state->base.fb;
+ int hsub = fb->format->hsub;
+ int vsub = fb->format->vsub;
+ int aux_x = plane_state->aux.x;
+ int aux_y = plane_state->aux.y;
+ u32 aux_offset = plane_state->aux.offset;
+ u32 alignment = intel_surf_alignment(fb, 1);
+
+ while (aux_offset >= main_offset && aux_y <= main_y) {
+ int x, y;
+
+ if (aux_x == main_x && aux_y == main_y)
+ break;
+
+ if (aux_offset == 0)
+ break;
+
+ x = aux_x / hsub;
+ y = aux_y / vsub;
+ aux_offset = intel_adjust_tile_offset(&x, &y, plane_state, 1,
+ aux_offset, aux_offset - alignment);
+ aux_x = x * hsub + aux_x % hsub;
+ aux_y = y * vsub + aux_y % vsub;
+ }
+
+ if (aux_x != main_x || aux_y != main_y)
+ return false;
+
+ plane_state->aux.offset = aux_offset;
+ plane_state->aux.x = aux_x;
+ plane_state->aux.y = aux_y;
+
+ return true;
+}
+
static int skl_check_main_surface(struct intel_plane_state *plane_state)
{
const struct drm_framebuffer *fb = plane_state->base.fb;
@@ -2894,7 +3025,7 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
while ((x + w) * cpp > fb->pitches[0]) {
if (offset == 0) {
- DRM_DEBUG_KMS("Unable to find suitable display surface offset\n");
+ DRM_DEBUG_KMS("Unable to find suitable display surface offset due to X-tiling\n");
return -EINVAL;
}
@@ -2903,6 +3034,26 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
}
}
+ /*
+ * CCS AUX surface doesn't have its own x/y offsets, we must make sure
+ * they match with the main surface x/y offsets.
+ */
+ if (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
+ fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS) {
+ while (!skl_check_main_ccs_coordinates(plane_state, x, y, offset)) {
+ if (offset == 0)
+ break;
+
+ offset = intel_adjust_tile_offset(&x, &y, plane_state, 0,
+ offset, offset - alignment);
+ }
+
+ if (x != plane_state->aux.x || y != plane_state->aux.y) {
+ DRM_DEBUG_KMS("Unable to find suitable display surface offset due to CCS\n");
+ return -EINVAL;
+ }
+ }
+
plane_state->main.offset = offset;
plane_state->main.x = x;
plane_state->main.y = y;
@@ -2939,6 +3090,49 @@ static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
return 0;
}
+static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state)
+{
+ struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
+ struct intel_crtc *crtc = to_intel_crtc(plane_state->base.crtc);
+ const struct drm_framebuffer *fb = plane_state->base.fb;
+ int src_x = plane_state->base.src.x1 >> 16;
+ int src_y = plane_state->base.src.y1 >> 16;
+ int hsub = fb->format->hsub;
+ int vsub = fb->format->vsub;
+ int x = src_x / hsub;
+ int y = src_y / vsub;
+ u32 offset;
+
+ switch (plane->id) {
+ case PLANE_PRIMARY:
+ case PLANE_SPRITE0:
+ break;
+ default:
+ DRM_DEBUG_KMS("RC support only on plane 1 and 2\n");
+ return -EINVAL;
+ }
+
+ if (crtc->pipe == PIPE_C) {
+ DRM_DEBUG_KMS("No RC support on pipe C\n");
+ return -EINVAL;
+ }
+
+ if (plane_state->base.rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180)) {
+ DRM_DEBUG_KMS("RC support only with 0/180 degree rotation %x\n",
+ plane_state->base.rotation);
+ return -EINVAL;
+ }
+
+ intel_add_fb_offsets(&x, &y, plane_state, 1);
+ offset = intel_compute_tile_offset(&x, &y, plane_state, 1);
+
+ plane_state->aux.offset = offset;
+ plane_state->aux.x = x * hsub + src_x % hsub;
+ plane_state->aux.y = y * vsub + src_y % vsub;
+
+ return 0;
+}
+
int skl_check_plane_surface(struct intel_plane_state *plane_state)
{
const struct drm_framebuffer *fb = plane_state->base.fb;
@@ -2962,6 +3156,11 @@ int skl_check_plane_surface(struct intel_plane_state *plane_state)
ret = skl_check_nv12_aux_surface(plane_state);
if (ret)
return ret;
+ } else if (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
+ fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS) {
+ ret = skl_check_ccs_aux_surface(plane_state);
+ if (ret)
+ return ret;
} else {
plane_state->aux.offset = ~0xfff;
plane_state->aux.x = 0;
@@ -3268,8 +3467,12 @@ static u32 skl_plane_ctl_tiling(uint64_t fb_modifier)
return PLANE_CTL_TILED_X;
case I915_FORMAT_MOD_Y_TILED:
return PLANE_CTL_TILED_Y;
+ case I915_FORMAT_MOD_Y_TILED_CCS:
+ return PLANE_CTL_TILED_Y | PLANE_CTL_DECOMPRESSION_ENABLE;
case I915_FORMAT_MOD_Yf_TILED:
return PLANE_CTL_TILED_YF;
+ case I915_FORMAT_MOD_Yf_TILED_CCS:
+ return PLANE_CTL_TILED_YF | PLANE_CTL_DECOMPRESSION_ENABLE;
default:
MISSING_CASE(fb_modifier);
}
@@ -3311,7 +3514,7 @@ u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
plane_ctl = PLANE_CTL_ENABLE;
- if (!IS_GEMINILAKE(dev_priv)) {
+ if (!IS_GEMINILAKE(dev_priv) && !IS_CANNONLAKE(dev_priv)) {
plane_ctl |=
PLANE_CTL_PIPE_GAMMA_ENABLE |
PLANE_CTL_PIPE_CSC_ENABLE |
@@ -3342,6 +3545,7 @@ static void skylake_update_primary_plane(struct intel_plane *plane,
u32 plane_ctl = plane_state->ctl;
unsigned int rotation = plane_state->base.rotation;
u32 stride = skl_plane_stride(fb, 0, rotation);
+ u32 aux_stride = skl_plane_stride(fb, 1, rotation);
u32 surf_addr = plane_state->main.offset;
int scaler_id = plane_state->scaler_id;
int src_x = plane_state->main.x;
@@ -3367,7 +3571,7 @@ static void skylake_update_primary_plane(struct intel_plane *plane,
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
- if (IS_GEMINILAKE(dev_priv)) {
+ if (IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) {
I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
PLANE_COLOR_PIPE_GAMMA_ENABLE |
PLANE_COLOR_PIPE_CSC_ENABLE |
@@ -3378,6 +3582,10 @@ static void skylake_update_primary_plane(struct intel_plane *plane,
I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (src_y << 16) | src_x);
I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride);
I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
+ I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id),
+ (plane_state->aux.offset - surf_addr) | aux_stride);
+ I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
+ (plane_state->aux.y << 16) | plane_state->aux.x);
if (scaler_id >= 0) {
uint32_t ps_ctrl = 0;
@@ -3419,14 +3627,6 @@ static void skylake_disable_primary_plane(struct intel_plane *primary,
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
}
-static void intel_complete_page_flips(struct drm_i915_private *dev_priv)
-{
- struct intel_crtc *crtc;
-
- for_each_intel_crtc(&dev_priv->drm, crtc)
- intel_finish_page_flip_cs(dev_priv, crtc->pipe);
-}
-
static int
__intel_display_resume(struct drm_device *dev,
struct drm_atomic_state *state,
@@ -3485,12 +3685,14 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv)
!gpu_reset_clobbers_display(dev_priv))
return;
- /* We have a modeset vs reset deadlock, defensively unbreak it.
- *
- * FIXME: We can do a _lot_ better, this is just a first iteration.
- */
- i915_gem_set_wedged(dev_priv);
- DRM_DEBUG_DRIVER("Wedging GPU to avoid deadlocks with pending modeset updates\n");
+ /* We have a modeset vs reset deadlock, defensively unbreak it. */
+ set_bit(I915_RESET_MODESET, &dev_priv->gpu_error.flags);
+ wake_up_all(&dev_priv->gpu_error.wait_queue);
+
+ if (atomic_read(&dev_priv->gpu_error.pending_fb_pin)) {
+ DRM_DEBUG_KMS("Modeset potentially stuck, unbreaking through wedging\n");
+ i915_gem_set_wedged(dev_priv);
+ }
/*
* Need mode_config.mutex so that we don't
@@ -3542,13 +3744,6 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
if (!state)
goto unlock;
- /*
- * Flips in the rings will be nuked by the reset,
- * so complete all pending flips so that user space
- * will get its events and not get stuck.
- */
- intel_complete_page_flips(dev_priv);
-
dev_priv->modeset_restore_state = NULL;
/* reset doesn't touch the display */
@@ -3585,35 +3780,8 @@ unlock:
drm_modeset_drop_locks(ctx);
drm_modeset_acquire_fini(ctx);
mutex_unlock(&dev->mode_config.mutex);
-}
-
-static bool abort_flip_on_reset(struct intel_crtc *crtc)
-{
- struct i915_gpu_error *error = &to_i915(crtc->base.dev)->gpu_error;
-
- if (i915_reset_backoff(error))
- return true;
-
- if (crtc->reset_count != i915_reset_count(error))
- return true;
- return false;
-}
-
-static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc)
-{
- struct drm_device *dev = crtc->dev;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- bool pending;
-
- if (abort_flip_on_reset(intel_crtc))
- return false;
-
- spin_lock_irq(&dev->event_lock);
- pending = to_intel_crtc(crtc)->flip_work != NULL;
- spin_unlock_irq(&dev->event_lock);
-
- return pending;
+ clear_bit(I915_RESET_MODESET, &dev_priv->gpu_error.flags);
}
static void intel_update_pipe_config(struct intel_crtc *crtc,
@@ -4170,21 +4338,22 @@ static void ironlake_fdi_disable(struct drm_crtc *crtc)
bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv)
{
- struct intel_crtc *crtc;
-
- /* Note that we don't need to be called with mode_config.lock here
- * as our list of CRTC objects is static for the lifetime of the
- * device and so cannot disappear as we iterate. Similarly, we can
- * happily treat the predicates as racy, atomic checks as userspace
- * cannot claim and pin a new fb without at least acquring the
- * struct_mutex and so serialising with us.
- */
- for_each_intel_crtc(&dev_priv->drm, crtc) {
- if (atomic_read(&crtc->unpin_work_count) == 0)
+ struct drm_crtc *crtc;
+ bool cleanup_done;
+
+ drm_for_each_crtc(crtc, &dev_priv->drm) {
+ struct drm_crtc_commit *commit;
+ spin_lock(&crtc->commit_lock);
+ commit = list_first_entry_or_null(&crtc->commit_list,
+ struct drm_crtc_commit, commit_entry);
+ cleanup_done = commit ?
+ try_wait_for_completion(&commit->cleanup_done) : true;
+ spin_unlock(&crtc->commit_lock);
+
+ if (cleanup_done)
continue;
- if (crtc->flip_work)
- intel_wait_for_vblank(dev_priv, crtc->pipe);
+ drm_crtc_wait_one_vblank(crtc);
return true;
}
@@ -4192,57 +4361,6 @@ bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv)
return false;
}
-static void page_flip_completed(struct intel_crtc *intel_crtc)
-{
- struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
- struct intel_flip_work *work = intel_crtc->flip_work;
-
- intel_crtc->flip_work = NULL;
-
- if (work->event)
- drm_crtc_send_vblank_event(&intel_crtc->base, work->event);
-
- drm_crtc_vblank_put(&intel_crtc->base);
-
- wake_up_all(&dev_priv->pending_flip_queue);
- trace_i915_flip_complete(intel_crtc->plane,
- work->pending_flip_obj);
-
- queue_work(dev_priv->wq, &work->unpin_work);
-}
-
-static int intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
-{
- struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = to_i915(dev);
- long ret;
-
- WARN_ON(waitqueue_active(&dev_priv->pending_flip_queue));
-
- ret = wait_event_interruptible_timeout(
- dev_priv->pending_flip_queue,
- !intel_crtc_has_pending_flip(crtc),
- 60*HZ);
-
- if (ret < 0)
- return ret;
-
- if (ret == 0) {
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct intel_flip_work *work;
-
- spin_lock_irq(&dev->event_lock);
- work = intel_crtc->flip_work;
- if (work && !is_mmio_work(work)) {
- WARN_ONCE(1, "Removing stuck page flip\n");
- page_flip_completed(intel_crtc);
- }
- spin_unlock_irq(&dev->event_lock);
- }
-
- return 0;
-}
-
void lpt_disable_iclkip(struct drm_i915_private *dev_priv)
{
u32 temp;
@@ -4562,7 +4680,7 @@ static void lpt_pch_enable(const struct intel_crtc_state *crtc_state)
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
- assert_pch_transcoder_disabled(dev_priv, TRANSCODER_A);
+ assert_pch_transcoder_disabled(dev_priv, PIPE_A);
lpt_program_iclkip(crtc);
@@ -4595,6 +4713,9 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
&crtc_state->scaler_state;
struct intel_crtc *intel_crtc =
to_intel_crtc(crtc_state->base.crtc);
+ struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
+ const struct drm_display_mode *adjusted_mode =
+ &crtc_state->base.adjusted_mode;
int need_scaling;
/*
@@ -4604,6 +4725,21 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
*/
need_scaling = src_w != dst_w || src_h != dst_h;
+ if (crtc_state->ycbcr420 && scaler_user == SKL_CRTC_INDEX)
+ need_scaling = true;
+
+ /*
+ * Scaling/fitting not supported in IF-ID mode in GEN9+
+ * TODO: Interlace fetch mode doesn't support YUV420 planar formats.
+ * Once NV12 is enabled, handle it here while allocating scaler
+ * for NV12.
+ */
+ if (INTEL_GEN(dev_priv) >= 9 && crtc_state->base.enable &&
+ need_scaling && adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
+ DRM_DEBUG_KMS("Pipe/Plane scaling not supported with IF-ID mode\n");
+ return -EINVAL;
+ }
+
/*
* if plane is being disabled or scaler is no more required or force detach
* - free scaler binded to this plane/crtc
@@ -5315,8 +5451,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
return;
if (intel_crtc->config->has_pch_encoder)
- intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
- false);
+ intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
intel_encoders_pre_pll_enable(crtc, pipe_config, old_state);
@@ -5401,8 +5536,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
intel_wait_for_vblank(dev_priv, pipe);
intel_wait_for_vblank(dev_priv, pipe);
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
- intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
- true);
+ intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
}
/* If we change the relative order between pipe/planes enabling, we need
@@ -5499,8 +5633,7 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
if (intel_crtc->config->has_pch_encoder)
- intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
- false);
+ intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
intel_encoders_disable(crtc, old_crtc_state, old_state);
@@ -5528,8 +5661,7 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
intel_encoders_post_disable(crtc, old_crtc_state, old_state);
if (old_crtc_state->has_pch_encoder)
- intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
- true);
+ intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
}
static void i9xx_pfit_enable(struct intel_crtc *crtc)
@@ -5838,8 +5970,6 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc,
return;
if (crtc->primary->state->visible) {
- WARN_ON(intel_crtc->flip_work);
-
intel_pre_disable_primary_noatomic(crtc);
intel_crtc_disable_planes(crtc, 1 << drm_plane_index(crtc->primary));
@@ -6248,6 +6378,16 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
return -EINVAL;
}
+ if (pipe_config->ycbcr420 && pipe_config->base.ctm) {
+ /*
+ * There is only one pipe CSC unit per pipe, and we need that
+ * for output conversion from RGB->YCBCR. So if CTM is already
+ * applied we can't support YCBCR420 output.
+ */
+ DRM_DEBUG_KMS("YCBCR420 and CTM together are not possible\n");
+ return -EINVAL;
+ }
+
/*
* Pipe horizontal size must be even in:
* - DVO ganged mode
@@ -8041,6 +8181,7 @@ static void haswell_set_pipemisc(struct drm_crtc *crtc)
{
struct drm_i915_private *dev_priv = to_i915(crtc->dev);
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_crtc_state *config = intel_crtc->config;
if (IS_BROADWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 9) {
u32 val = 0;
@@ -8066,6 +8207,12 @@ static void haswell_set_pipemisc(struct drm_crtc *crtc)
if (intel_crtc->config->dither)
val |= PIPEMISC_DITHER_ENABLE | PIPEMISC_DITHER_TYPE_SP;
+ if (config->ycbcr420) {
+ val |= PIPEMISC_OUTPUT_COLORSPACE_YUV |
+ PIPEMISC_YUV420_ENABLE |
+ PIPEMISC_YUV420_MODE_FULL_BLEND;
+ }
+
I915_WRITE(PIPEMISC(intel_crtc->pipe), val);
}
}
@@ -8393,10 +8540,16 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
fb->modifier = I915_FORMAT_MOD_X_TILED;
break;
case PLANE_CTL_TILED_Y:
- fb->modifier = I915_FORMAT_MOD_Y_TILED;
+ if (val & PLANE_CTL_DECOMPRESSION_ENABLE)
+ fb->modifier = I915_FORMAT_MOD_Y_TILED_CCS;
+ else
+ fb->modifier = I915_FORMAT_MOD_Y_TILED;
break;
case PLANE_CTL_TILED_YF:
- fb->modifier = I915_FORMAT_MOD_Yf_TILED;
+ if (val & PLANE_CTL_DECOMPRESSION_ENABLE)
+ fb->modifier = I915_FORMAT_MOD_Yf_TILED_CCS;
+ else
+ fb->modifier = I915_FORMAT_MOD_Yf_TILED;
break;
default:
MISSING_CASE(tiling);
@@ -8630,7 +8783,8 @@ static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv)
I915_STATE_WARN(crtc->active, "CRTC for pipe %c enabled\n",
pipe_name(crtc->pipe));
- I915_STATE_WARN(I915_READ(HSW_PWR_WELL_DRIVER), "Power well on\n");
+ I915_STATE_WARN(I915_READ(HSW_PWR_WELL_CTL_DRIVER(HSW_DISP_PW_GLOBAL)),
+ "Display power well on\n");
I915_STATE_WARN(I915_READ(SPLL_CTL) & SPLL_PLL_ENABLE, "SPLL enabled\n");
I915_STATE_WARN(I915_READ(WRPLL_CTL(0)) & WRPLL_PLL_ENABLE, "WRPLL1 enabled\n");
I915_STATE_WARN(I915_READ(WRPLL_CTL(1)) & WRPLL_PLL_ENABLE, "WRPLL2 enabled\n");
@@ -9100,12 +9254,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
u64 power_domain_mask;
bool active;
- if (INTEL_GEN(dev_priv) >= 9) {
- intel_crtc_init_scalers(crtc, pipe_config);
-
- pipe_config->scaler_state.scaler_id = -1;
- pipe_config->scaler_state.scaler_users &= ~(1 << SKL_CRTC_INDEX);
- }
+ intel_crtc_init_scalers(crtc, pipe_config);
power_domain = POWER_DOMAIN_PIPE(crtc->pipe);
if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
@@ -9135,6 +9284,23 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
pipe_config->gamma_mode =
I915_READ(GAMMA_MODE(crtc->pipe)) & GAMMA_MODE_MODE_MASK;
+ if (IS_BROADWELL(dev_priv) || dev_priv->info.gen >= 9) {
+ u32 tmp = I915_READ(PIPEMISC(crtc->pipe));
+ bool clrspace_yuv = tmp & PIPEMISC_OUTPUT_COLORSPACE_YUV;
+
+ if (IS_GEMINILAKE(dev_priv) || dev_priv->info.gen >= 10) {
+ bool blend_mode_420 = tmp &
+ PIPEMISC_YUV420_MODE_FULL_BLEND;
+
+ pipe_config->ycbcr420 = tmp & PIPEMISC_YUV420_ENABLE;
+ if (pipe_config->ycbcr420 != clrspace_yuv ||
+ pipe_config->ycbcr420 != blend_mode_420)
+ DRM_DEBUG_KMS("Bad 4:2:0 mode (%08x)\n", tmp);
+ } else if (clrspace_yuv) {
+ DRM_DEBUG_KMS("YCbCr 4:2:0 Unsupported\n");
+ }
+ }
+
power_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe);
if (intel_display_power_get_if_enabled(dev_priv, power_domain)) {
power_domain_mask |= BIT_ULL(power_domain);
@@ -10112,849 +10278,11 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
static void intel_crtc_destroy(struct drm_crtc *crtc)
{
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct drm_device *dev = crtc->dev;
- struct intel_flip_work *work;
-
- spin_lock_irq(&dev->event_lock);
- work = intel_crtc->flip_work;
- intel_crtc->flip_work = NULL;
- spin_unlock_irq(&dev->event_lock);
-
- if (work) {
- cancel_work_sync(&work->mmio_work);
- cancel_work_sync(&work->unpin_work);
- kfree(work);
- }
drm_crtc_cleanup(crtc);
-
kfree(intel_crtc);
}
-static void intel_unpin_work_fn(struct work_struct *__work)
-{
- struct intel_flip_work *work =
- container_of(__work, struct intel_flip_work, unpin_work);
- struct intel_crtc *crtc = to_intel_crtc(work->crtc);
- struct drm_device *dev = crtc->base.dev;
- struct drm_plane *primary = crtc->base.primary;
-
- if (is_mmio_work(work))
- flush_work(&work->mmio_work);
-
- mutex_lock(&dev->struct_mutex);
- intel_unpin_fb_vma(work->old_vma);
- i915_gem_object_put(work->pending_flip_obj);
- mutex_unlock(&dev->struct_mutex);
-
- i915_gem_request_put(work->flip_queued_req);
-
- intel_frontbuffer_flip_complete(to_i915(dev),
- to_intel_plane(primary)->frontbuffer_bit);
- intel_fbc_post_update(crtc);
- drm_framebuffer_unreference(work->old_fb);
-
- BUG_ON(atomic_read(&crtc->unpin_work_count) == 0);
- atomic_dec(&crtc->unpin_work_count);
-
- kfree(work);
-}
-
-/* Is 'a' after or equal to 'b'? */
-static bool g4x_flip_count_after_eq(u32 a, u32 b)
-{
- return !((a - b) & 0x80000000);
-}
-
-static bool __pageflip_finished_cs(struct intel_crtc *crtc,
- struct intel_flip_work *work)
-{
- struct drm_device *dev = crtc->base.dev;
- struct drm_i915_private *dev_priv = to_i915(dev);
-
- if (abort_flip_on_reset(crtc))
- return true;
-
- /*
- * The relevant registers doen't exist on pre-ctg.
- * As the flip done interrupt doesn't trigger for mmio
- * flips on gmch platforms, a flip count check isn't
- * really needed there. But since ctg has the registers,
- * include it in the check anyway.
- */
- if (INTEL_GEN(dev_priv) < 5 && !IS_G4X(dev_priv))
- return true;
-
- /*
- * BDW signals flip done immediately if the plane
- * is disabled, even if the plane enable is already
- * armed to occur at the next vblank :(
- */
-
- /*
- * A DSPSURFLIVE check isn't enough in case the mmio and CS flips
- * used the same base address. In that case the mmio flip might
- * have completed, but the CS hasn't even executed the flip yet.
- *
- * A flip count check isn't enough as the CS might have updated
- * the base address just after start of vblank, but before we
- * managed to process the interrupt. This means we'd complete the
- * CS flip too soon.
- *
- * Combining both checks should get us a good enough result. It may
- * still happen that the CS flip has been executed, but has not
- * yet actually completed. But in case the base address is the same
- * anyway, we don't really care.
- */
- return (I915_READ(DSPSURFLIVE(crtc->plane)) & ~0xfff) ==
- crtc->flip_work->gtt_offset &&
- g4x_flip_count_after_eq(I915_READ(PIPE_FLIPCOUNT_G4X(crtc->pipe)),
- crtc->flip_work->flip_count);
-}
-
-static bool
-__pageflip_finished_mmio(struct intel_crtc *crtc,
- struct intel_flip_work *work)
-{
- /*
- * MMIO work completes when vblank is different from
- * flip_queued_vblank.
- *
- * Reset counter value doesn't matter, this is handled by
- * i915_wait_request finishing early, so no need to handle
- * reset here.
- */
- return intel_crtc_get_vblank_counter(crtc) != work->flip_queued_vblank;
-}
-
-
-static bool pageflip_finished(struct intel_crtc *crtc,
- struct intel_flip_work *work)
-{
- if (!atomic_read(&work->pending))
- return false;
-
- smp_rmb();
-
- if (is_mmio_work(work))
- return __pageflip_finished_mmio(crtc, work);
- else
- return __pageflip_finished_cs(crtc, work);
-}
-
-void intel_finish_page_flip_cs(struct drm_i915_private *dev_priv, int pipe)
-{
- struct drm_device *dev = &dev_priv->drm;
- struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
- struct intel_flip_work *work;
- unsigned long flags;
-
- /* Ignore early vblank irqs */
- if (!crtc)
- return;
-
- /*
- * This is called both by irq handlers and the reset code (to complete
- * lost pageflips) so needs the full irqsave spinlocks.
- */
- spin_lock_irqsave(&dev->event_lock, flags);
- work = crtc->flip_work;
-
- if (work != NULL &&
- !is_mmio_work(work) &&
- pageflip_finished(crtc, work))
- page_flip_completed(crtc);
-
- spin_unlock_irqrestore(&dev->event_lock, flags);
-}
-
-void intel_finish_page_flip_mmio(struct drm_i915_private *dev_priv, int pipe)
-{
- struct drm_device *dev = &dev_priv->drm;
- struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
- struct intel_flip_work *work;
- unsigned long flags;
-
- /* Ignore early vblank irqs */
- if (!crtc)
- return;
-
- /*
- * This is called both by irq handlers and the reset code (to complete
- * lost pageflips) so needs the full irqsave spinlocks.
- */
- spin_lock_irqsave(&dev->event_lock, flags);
- work = crtc->flip_work;
-
- if (work != NULL &&
- is_mmio_work(work) &&
- pageflip_finished(crtc, work))
- page_flip_completed(crtc);
-
- spin_unlock_irqrestore(&dev->event_lock, flags);
-}
-
-static inline void intel_mark_page_flip_active(struct intel_crtc *crtc,
- struct intel_flip_work *work)
-{
- work->flip_queued_vblank = intel_crtc_get_vblank_counter(crtc);
-
- /* Ensure that the work item is consistent when activating it ... */
- smp_mb__before_atomic();
- atomic_set(&work->pending, 1);
-}
-
-static int intel_gen2_queue_flip(struct drm_device *dev,
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_i915_gem_object *obj,
- struct drm_i915_gem_request *req,
- uint32_t flags)
-{
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- u32 flip_mask, *cs;
-
- cs = intel_ring_begin(req, 6);
- if (IS_ERR(cs))
- return PTR_ERR(cs);
-
- /* Can't queue multiple flips, so wait for the previous
- * one to finish before executing the next.
- */
- if (intel_crtc->plane)
- flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
- else
- flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
- *cs++ = MI_WAIT_FOR_EVENT | flip_mask;
- *cs++ = MI_NOOP;
- *cs++ = MI_DISPLAY_FLIP | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane);
- *cs++ = fb->pitches[0];
- *cs++ = intel_crtc->flip_work->gtt_offset;
- *cs++ = 0; /* aux display base address, unused */
-
- return 0;
-}
-
-static int intel_gen3_queue_flip(struct drm_device *dev,
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_i915_gem_object *obj,
- struct drm_i915_gem_request *req,
- uint32_t flags)
-{
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- u32 flip_mask, *cs;
-
- cs = intel_ring_begin(req, 6);
- if (IS_ERR(cs))
- return PTR_ERR(cs);
-
- if (intel_crtc->plane)
- flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
- else
- flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
- *cs++ = MI_WAIT_FOR_EVENT | flip_mask;
- *cs++ = MI_NOOP;
- *cs++ = MI_DISPLAY_FLIP_I915 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane);
- *cs++ = fb->pitches[0];
- *cs++ = intel_crtc->flip_work->gtt_offset;
- *cs++ = MI_NOOP;
-
- return 0;
-}
-
-static int intel_gen4_queue_flip(struct drm_device *dev,
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_i915_gem_object *obj,
- struct drm_i915_gem_request *req,
- uint32_t flags)
-{
- struct drm_i915_private *dev_priv = to_i915(dev);
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- u32 pf, pipesrc, *cs;
-
- cs = intel_ring_begin(req, 4);
- if (IS_ERR(cs))
- return PTR_ERR(cs);
-
- /* i965+ uses the linear or tiled offsets from the
- * Display Registers (which do not change across a page-flip)
- * so we need only reprogram the base address.
- */
- *cs++ = MI_DISPLAY_FLIP | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane);
- *cs++ = fb->pitches[0];
- *cs++ = intel_crtc->flip_work->gtt_offset |
- intel_fb_modifier_to_tiling(fb->modifier);
-
- /* XXX Enabling the panel-fitter across page-flip is so far
- * untested on non-native modes, so ignore it for now.
- * pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE;
- */
- pf = 0;
- pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
- *cs++ = pf | pipesrc;
-
- return 0;
-}
-
-static int intel_gen6_queue_flip(struct drm_device *dev,
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_i915_gem_object *obj,
- struct drm_i915_gem_request *req,
- uint32_t flags)
-{
- struct drm_i915_private *dev_priv = to_i915(dev);
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- u32 pf, pipesrc, *cs;
-
- cs = intel_ring_begin(req, 4);
- if (IS_ERR(cs))
- return PTR_ERR(cs);
-
- *cs++ = MI_DISPLAY_FLIP | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane);
- *cs++ = fb->pitches[0] | intel_fb_modifier_to_tiling(fb->modifier);
- *cs++ = intel_crtc->flip_work->gtt_offset;
-
- /* Contrary to the suggestions in the documentation,
- * "Enable Panel Fitter" does not seem to be required when page
- * flipping with a non-native mode, and worse causes a normal
- * modeset to fail.
- * pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE;
- */
- pf = 0;
- pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
- *cs++ = pf | pipesrc;
-
- return 0;
-}
-
-static int intel_gen7_queue_flip(struct drm_device *dev,
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_i915_gem_object *obj,
- struct drm_i915_gem_request *req,
- uint32_t flags)
-{
- struct drm_i915_private *dev_priv = to_i915(dev);
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- u32 *cs, plane_bit = 0;
- int len, ret;
-
- switch (intel_crtc->plane) {
- case PLANE_A:
- plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_A;
- break;
- case PLANE_B:
- plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_B;
- break;
- case PLANE_C:
- plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_C;
- break;
- default:
- WARN_ONCE(1, "unknown plane in flip command\n");
- return -ENODEV;
- }
-
- len = 4;
- if (req->engine->id == RCS) {
- len += 6;
- /*
- * On Gen 8, SRM is now taking an extra dword to accommodate
- * 48bits addresses, and we need a NOOP for the batch size to
- * stay even.
- */
- if (IS_GEN8(dev_priv))
- len += 2;
- }
-
- /*
- * BSpec MI_DISPLAY_FLIP for IVB:
- * "The full packet must be contained within the same cache line."
- *
- * Currently the LRI+SRM+MI_DISPLAY_FLIP all fit within the same
- * cacheline, if we ever start emitting more commands before
- * the MI_DISPLAY_FLIP we may need to first emit everything else,
- * then do the cacheline alignment, and finally emit the
- * MI_DISPLAY_FLIP.
- */
- ret = intel_ring_cacheline_align(req);
- if (ret)
- return ret;
-
- cs = intel_ring_begin(req, len);
- if (IS_ERR(cs))
- return PTR_ERR(cs);
-
- /* Unmask the flip-done completion message. Note that the bspec says that
- * we should do this for both the BCS and RCS, and that we must not unmask
- * more than one flip event at any time (or ensure that one flip message
- * can be sent by waiting for flip-done prior to queueing new flips).
- * Experimentation says that BCS works despite DERRMR masking all
- * flip-done completion events and that unmasking all planes at once
- * for the RCS also doesn't appear to drop events. Setting the DERRMR
- * to zero does lead to lockups within MI_DISPLAY_FLIP.
- */
- if (req->engine->id == RCS) {
- *cs++ = MI_LOAD_REGISTER_IMM(1);
- *cs++ = i915_mmio_reg_offset(DERRMR);
- *cs++ = ~(DERRMR_PIPEA_PRI_FLIP_DONE |
- DERRMR_PIPEB_PRI_FLIP_DONE |
- DERRMR_PIPEC_PRI_FLIP_DONE);
- if (IS_GEN8(dev_priv))
- *cs++ = MI_STORE_REGISTER_MEM_GEN8 |
- MI_SRM_LRM_GLOBAL_GTT;
- else
- *cs++ = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT;
- *cs++ = i915_mmio_reg_offset(DERRMR);
- *cs++ = i915_ggtt_offset(req->engine->scratch) + 256;
- if (IS_GEN8(dev_priv)) {
- *cs++ = 0;
- *cs++ = MI_NOOP;
- }
- }
-
- *cs++ = MI_DISPLAY_FLIP_I915 | plane_bit;
- *cs++ = fb->pitches[0] | intel_fb_modifier_to_tiling(fb->modifier);
- *cs++ = intel_crtc->flip_work->gtt_offset;
- *cs++ = MI_NOOP;
-
- return 0;
-}
-
-static bool use_mmio_flip(struct intel_engine_cs *engine,
- struct drm_i915_gem_object *obj)
-{
- /*
- * This is not being used for older platforms, because
- * non-availability of flip done interrupt forces us to use
- * CS flips. Older platforms derive flip done using some clever
- * tricks involving the flip_pending status bits and vblank irqs.
- * So using MMIO flips there would disrupt this mechanism.
- */
-
- if (engine == NULL)
- return true;
-
- if (INTEL_GEN(engine->i915) < 5)
- return false;
-
- if (i915.use_mmio_flip < 0)
- return false;
- else if (i915.use_mmio_flip > 0)
- return true;
- else if (i915.enable_execlists)
- return true;
-
- return engine != i915_gem_object_last_write_engine(obj);
-}
-
-static void skl_do_mmio_flip(struct intel_crtc *intel_crtc,
- unsigned int rotation,
- struct intel_flip_work *work)
-{
- struct drm_device *dev = intel_crtc->base.dev;
- struct drm_i915_private *dev_priv = to_i915(dev);
- struct drm_framebuffer *fb = intel_crtc->base.primary->fb;
- const enum pipe pipe = intel_crtc->pipe;
- u32 ctl, stride = skl_plane_stride(fb, 0, rotation);
-
- ctl = I915_READ(PLANE_CTL(pipe, 0));
- ctl &= ~PLANE_CTL_TILED_MASK;
- switch (fb->modifier) {
- case DRM_FORMAT_MOD_LINEAR:
- break;
- case I915_FORMAT_MOD_X_TILED:
- ctl |= PLANE_CTL_TILED_X;
- break;
- case I915_FORMAT_MOD_Y_TILED:
- ctl |= PLANE_CTL_TILED_Y;
- break;
- case I915_FORMAT_MOD_Yf_TILED:
- ctl |= PLANE_CTL_TILED_YF;
- break;
- default:
- MISSING_CASE(fb->modifier);
- }
-
- /*
- * Both PLANE_CTL and PLANE_STRIDE are not updated on vblank but on
- * PLANE_SURF updates, the update is then guaranteed to be atomic.
- */
- I915_WRITE(PLANE_CTL(pipe, 0), ctl);
- I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
-
- I915_WRITE(PLANE_SURF(pipe, 0), work->gtt_offset);
- POSTING_READ(PLANE_SURF(pipe, 0));
-}
-
-static void ilk_do_mmio_flip(struct intel_crtc *intel_crtc,
- struct intel_flip_work *work)
-{
- struct drm_device *dev = intel_crtc->base.dev;
- struct drm_i915_private *dev_priv = to_i915(dev);
- struct drm_framebuffer *fb = intel_crtc->base.primary->fb;
- i915_reg_t reg = DSPCNTR(intel_crtc->plane);
- u32 dspcntr;
-
- dspcntr = I915_READ(reg);
-
- if (fb->modifier == I915_FORMAT_MOD_X_TILED)
- dspcntr |= DISPPLANE_TILED;
- else
- dspcntr &= ~DISPPLANE_TILED;
-
- I915_WRITE(reg, dspcntr);
-
- I915_WRITE(DSPSURF(intel_crtc->plane), work->gtt_offset);
- POSTING_READ(DSPSURF(intel_crtc->plane));
-}
-
-static void intel_mmio_flip_work_func(struct work_struct *w)
-{
- struct intel_flip_work *work =
- container_of(w, struct intel_flip_work, mmio_work);
- struct intel_crtc *crtc = to_intel_crtc(work->crtc);
- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
- struct intel_framebuffer *intel_fb =
- to_intel_framebuffer(crtc->base.primary->fb);
- struct drm_i915_gem_object *obj = intel_fb->obj;
-
- WARN_ON(i915_gem_object_wait(obj, 0, MAX_SCHEDULE_TIMEOUT, NULL) < 0);
-
- intel_pipe_update_start(crtc);
-
- if (INTEL_GEN(dev_priv) >= 9)
- skl_do_mmio_flip(crtc, work->rotation, work);
- else
- /* use_mmio_flip() retricts MMIO flips to ilk+ */
- ilk_do_mmio_flip(crtc, work);
-
- intel_pipe_update_end(crtc, work);
-}
-
-static int intel_default_queue_flip(struct drm_device *dev,
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_i915_gem_object *obj,
- struct drm_i915_gem_request *req,
- uint32_t flags)
-{
- return -ENODEV;
-}
-
-static bool __pageflip_stall_check_cs(struct drm_i915_private *dev_priv,
- struct intel_crtc *intel_crtc,
- struct intel_flip_work *work)
-{
- u32 addr, vblank;
-
- if (!atomic_read(&work->pending))
- return false;
-
- smp_rmb();
-
- vblank = intel_crtc_get_vblank_counter(intel_crtc);
- if (work->flip_ready_vblank == 0) {
- if (work->flip_queued_req &&
- !i915_gem_request_completed(work->flip_queued_req))
- return false;
-
- work->flip_ready_vblank = vblank;
- }
-
- if (vblank - work->flip_ready_vblank < 3)
- return false;
-
- /* Potential stall - if we see that the flip has happened,
- * assume a missed interrupt. */
- if (INTEL_GEN(dev_priv) >= 4)
- addr = I915_HI_DISPBASE(I915_READ(DSPSURF(intel_crtc->plane)));
- else
- addr = I915_READ(DSPADDR(intel_crtc->plane));
-
- /* There is a potential issue here with a false positive after a flip
- * to the same address. We could address this by checking for a
- * non-incrementing frame counter.
- */
- return addr == work->gtt_offset;
-}
-
-void intel_check_page_flip(struct drm_i915_private *dev_priv, int pipe)
-{
- struct drm_device *dev = &dev_priv->drm;
- struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
- struct intel_flip_work *work;
-
- WARN_ON(!in_interrupt());
-
- if (crtc == NULL)
- return;
-
- spin_lock(&dev->event_lock);
- work = crtc->flip_work;
-
- if (work != NULL && !is_mmio_work(work) &&
- __pageflip_stall_check_cs(dev_priv, crtc, work)) {
- WARN_ONCE(1,
- "Kicking stuck page flip: queued at %d, now %d\n",
- work->flip_queued_vblank, intel_crtc_get_vblank_counter(crtc));
- page_flip_completed(crtc);
- work = NULL;
- }
-
- if (work != NULL && !is_mmio_work(work) &&
- intel_crtc_get_vblank_counter(crtc) - work->flip_queued_vblank > 1)
- intel_queue_rps_boost_for_request(work->flip_queued_req);
- spin_unlock(&dev->event_lock);
-}
-
-__maybe_unused
-static int intel_crtc_page_flip(struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_pending_vblank_event *event,
- uint32_t page_flip_flags)
-{
- struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = to_i915(dev);
- struct drm_framebuffer *old_fb = crtc->primary->fb;
- struct drm_i915_gem_object *obj = intel_fb_obj(fb);
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct drm_plane *primary = crtc->primary;
- enum pipe pipe = intel_crtc->pipe;
- struct intel_flip_work *work;
- struct intel_engine_cs *engine;
- bool mmio_flip;
- struct drm_i915_gem_request *request;
- struct i915_vma *vma;
- int ret;
-
- /*
- * drm_mode_page_flip_ioctl() should already catch this, but double
- * check to be safe. In the future we may enable pageflipping from
- * a disabled primary plane.
- */
- if (WARN_ON(intel_fb_obj(old_fb) == NULL))
- return -EBUSY;
-
- /* Can't change pixel format via MI display flips. */
- if (fb->format != crtc->primary->fb->format)
- return -EINVAL;
-
- /*
- * TILEOFF/LINOFF registers can't be changed via MI display flips.
- * Note that pitch changes could also affect these register.
- */
- if (INTEL_GEN(dev_priv) > 3 &&
- (fb->offsets[0] != crtc->primary->fb->offsets[0] ||
- fb->pitches[0] != crtc->primary->fb->pitches[0]))
- return -EINVAL;
-
- if (i915_terminally_wedged(&dev_priv->gpu_error))
- goto out_hang;
-
- work = kzalloc(sizeof(*work), GFP_KERNEL);
- if (work == NULL)
- return -ENOMEM;
-
- work->event = event;
- work->crtc = crtc;
- work->old_fb = old_fb;
- INIT_WORK(&work->unpin_work, intel_unpin_work_fn);
-
- ret = drm_crtc_vblank_get(crtc);
- if (ret)
- goto free_work;
-
- /* We borrow the event spin lock for protecting flip_work */
- spin_lock_irq(&dev->event_lock);
- if (intel_crtc->flip_work) {
- /* Before declaring the flip queue wedged, check if
- * the hardware completed the operation behind our backs.
- */
- if (pageflip_finished(intel_crtc, intel_crtc->flip_work)) {
- DRM_DEBUG_DRIVER("flip queue: previous flip completed, continuing\n");
- page_flip_completed(intel_crtc);
- } else {
- DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
- spin_unlock_irq(&dev->event_lock);
-
- drm_crtc_vblank_put(crtc);
- kfree(work);
- return -EBUSY;
- }
- }
- intel_crtc->flip_work = work;
- spin_unlock_irq(&dev->event_lock);
-
- if (atomic_read(&intel_crtc->unpin_work_count) >= 2)
- flush_workqueue(dev_priv->wq);
-
- /* Reference the objects for the scheduled work. */
- drm_framebuffer_reference(work->old_fb);
-
- crtc->primary->fb = fb;
- update_state_fb(crtc->primary);
-
- work->pending_flip_obj = i915_gem_object_get(obj);
-
- ret = i915_mutex_lock_interruptible(dev);
- if (ret)
- goto cleanup;
-
- intel_crtc->reset_count = i915_reset_count(&dev_priv->gpu_error);
- if (i915_reset_backoff_or_wedged(&dev_priv->gpu_error)) {
- ret = -EIO;
- goto unlock;
- }
-
- atomic_inc(&intel_crtc->unpin_work_count);
-
- if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv))
- work->flip_count = I915_READ(PIPE_FLIPCOUNT_G4X(pipe)) + 1;
-
- if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
- engine = dev_priv->engine[BCS];
- if (fb->modifier != old_fb->modifier)
- /* vlv: DISPLAY_FLIP fails to change tiling */
- engine = NULL;
- } else if (IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv)) {
- engine = dev_priv->engine[BCS];
- } else if (INTEL_GEN(dev_priv) >= 7) {
- engine = i915_gem_object_last_write_engine(obj);
- if (engine == NULL || engine->id != RCS)
- engine = dev_priv->engine[BCS];
- } else {
- engine = dev_priv->engine[RCS];
- }
-
- mmio_flip = use_mmio_flip(engine, obj);
-
- vma = intel_pin_and_fence_fb_obj(fb, primary->state->rotation);
- if (IS_ERR(vma)) {
- ret = PTR_ERR(vma);
- goto cleanup_pending;
- }
-
- work->old_vma = to_intel_plane_state(primary->state)->vma;
- to_intel_plane_state(primary->state)->vma = vma;
-
- work->gtt_offset = i915_ggtt_offset(vma) + intel_crtc->dspaddr_offset;
- work->rotation = crtc->primary->state->rotation;
-
- /*
- * There's the potential that the next frame will not be compatible with
- * FBC, so we want to call pre_update() before the actual page flip.
- * The problem is that pre_update() caches some information about the fb
- * object, so we want to do this only after the object is pinned. Let's
- * be on the safe side and do this immediately before scheduling the
- * flip.
- */
- intel_fbc_pre_update(intel_crtc, intel_crtc->config,
- to_intel_plane_state(primary->state));
-
- if (mmio_flip) {
- INIT_WORK(&work->mmio_work, intel_mmio_flip_work_func);
- queue_work(system_unbound_wq, &work->mmio_work);
- } else {
- request = i915_gem_request_alloc(engine,
- dev_priv->kernel_context);
- if (IS_ERR(request)) {
- ret = PTR_ERR(request);
- goto cleanup_unpin;
- }
-
- ret = i915_gem_request_await_object(request, obj, false);
- if (ret)
- goto cleanup_request;
-
- ret = dev_priv->display.queue_flip(dev, crtc, fb, obj, request,
- page_flip_flags);
- if (ret)
- goto cleanup_request;
-
- intel_mark_page_flip_active(intel_crtc, work);
-
- work->flip_queued_req = i915_gem_request_get(request);
- i915_add_request(request);
- }
-
- i915_gem_object_wait_priority(obj, 0, I915_PRIORITY_DISPLAY);
- i915_gem_track_fb(intel_fb_obj(old_fb), obj,
- to_intel_plane(primary)->frontbuffer_bit);
- mutex_unlock(&dev->struct_mutex);
-
- intel_frontbuffer_flip_prepare(to_i915(dev),
- to_intel_plane(primary)->frontbuffer_bit);
-
- trace_i915_flip_request(intel_crtc->plane, obj);
-
- return 0;
-
-cleanup_request:
- i915_add_request(request);
-cleanup_unpin:
- to_intel_plane_state(primary->state)->vma = work->old_vma;
- intel_unpin_fb_vma(vma);
-cleanup_pending:
- atomic_dec(&intel_crtc->unpin_work_count);
-unlock:
- mutex_unlock(&dev->struct_mutex);
-cleanup:
- crtc->primary->fb = old_fb;
- update_state_fb(crtc->primary);
-
- i915_gem_object_put(obj);
- drm_framebuffer_unreference(work->old_fb);
-
- spin_lock_irq(&dev->event_lock);
- intel_crtc->flip_work = NULL;
- spin_unlock_irq(&dev->event_lock);
-
- drm_crtc_vblank_put(crtc);
-free_work:
- kfree(work);
-
- if (ret == -EIO) {
- struct drm_atomic_state *state;
- struct drm_plane_state *plane_state;
-
-out_hang:
- state = drm_atomic_state_alloc(dev);
- if (!state)
- return -ENOMEM;
- state->acquire_ctx = dev->mode_config.acquire_ctx;
-
-retry:
- plane_state = drm_atomic_get_plane_state(state, primary);
- ret = PTR_ERR_OR_ZERO(plane_state);
- if (!ret) {
- drm_atomic_set_fb_for_plane(plane_state, fb);
-
- ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
- if (!ret)
- ret = drm_atomic_commit(state);
- }
-
- if (ret == -EDEADLK) {
- drm_modeset_backoff(state->acquire_ctx);
- drm_atomic_state_clear(state);
- goto retry;
- }
-
- drm_atomic_state_put(state);
-
- if (ret == 0 && event) {
- spin_lock_irq(&dev->event_lock);
- drm_crtc_send_vblank_event(crtc, event);
- spin_unlock_irq(&dev->event_lock);
- }
- }
- return ret;
-}
-
-
/**
* intel_wm_need_update - Check whether watermarks need updating
* @plane: drm plane
@@ -11352,6 +10680,9 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
pipe_config->fdi_lanes,
&pipe_config->fdi_m_n);
+ if (pipe_config->ycbcr420)
+ DRM_DEBUG_KMS("YCbCr 4:2:0 output enabled\n");
+
if (intel_crtc_has_dp_encoder(pipe_config)) {
intel_dump_m_n_config(pipe_config, "dp m_n",
pipe_config->lane_count, &pipe_config->dp_m_n);
@@ -11923,6 +11254,7 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
PIPE_CONF_CHECK_I(hdmi_scrambling);
PIPE_CONF_CHECK_I(hdmi_high_tmds_clock_ratio);
PIPE_CONF_CHECK_I(has_infoframe);
+ PIPE_CONF_CHECK_I(ycbcr420);
PIPE_CONF_CHECK_I(has_audio);
@@ -12764,31 +12096,7 @@ static int intel_atomic_check(struct drm_device *dev,
static int intel_atomic_prepare_commit(struct drm_device *dev,
struct drm_atomic_state *state)
{
- struct drm_i915_private *dev_priv = to_i915(dev);
- struct drm_crtc_state *crtc_state;
- struct drm_crtc *crtc;
- int i, ret;
-
- for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
- if (state->legacy_cursor_update)
- continue;
-
- ret = intel_crtc_wait_for_pending_flips(crtc);
- if (ret)
- return ret;
-
- if (atomic_read(&to_intel_crtc(crtc)->unpin_work_count) >= 2)
- flush_workqueue(dev_priv->wq);
- }
-
- ret = mutex_lock_interruptible(&dev->struct_mutex);
- if (ret)
- return ret;
-
- ret = drm_atomic_helper_prepare_planes(dev, state);
- mutex_unlock(&dev->struct_mutex);
-
- return ret;
+ return drm_atomic_helper_prepare_planes(dev, state);
}
u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc)
@@ -12796,7 +12104,7 @@ u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc)
struct drm_device *dev = crtc->base.dev;
if (!dev->max_vblank_count)
- return drm_accurate_vblank_count(&crtc->base);
+ return drm_crtc_accurate_vblank_count(&crtc->base);
return dev->driver->get_vblank_counter(dev, crtc->pipe);
}
@@ -12999,6 +12307,30 @@ static void intel_atomic_helper_free_state_worker(struct work_struct *work)
intel_atomic_helper_free_state(dev_priv);
}
+static void intel_atomic_commit_fence_wait(struct intel_atomic_state *intel_state)
+{
+ struct wait_queue_entry wait_fence, wait_reset;
+ struct drm_i915_private *dev_priv = to_i915(intel_state->base.dev);
+
+ init_wait_entry(&wait_fence, 0);
+ init_wait_entry(&wait_reset, 0);
+ for (;;) {
+ prepare_to_wait(&intel_state->commit_ready.wait,
+ &wait_fence, TASK_UNINTERRUPTIBLE);
+ prepare_to_wait(&dev_priv->gpu_error.wait_queue,
+ &wait_reset, TASK_UNINTERRUPTIBLE);
+
+
+ if (i915_sw_fence_done(&intel_state->commit_ready)
+ || test_bit(I915_RESET_MODESET, &dev_priv->gpu_error.flags))
+ break;
+
+ schedule();
+ }
+ finish_wait(&intel_state->commit_ready.wait, &wait_fence);
+ finish_wait(&dev_priv->gpu_error.wait_queue, &wait_reset);
+}
+
static void intel_atomic_commit_tail(struct drm_atomic_state *state)
{
struct drm_device *dev = state->dev;
@@ -13012,6 +12344,8 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
unsigned crtc_vblank_mask = 0;
int i;
+ intel_atomic_commit_fence_wait(intel_state);
+
drm_atomic_helper_wait_for_dependencies(state);
if (intel_state->modeset)
@@ -13151,9 +12485,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET);
}
- mutex_lock(&dev->struct_mutex);
drm_atomic_helper_cleanup_planes(dev, state);
- mutex_unlock(&dev->struct_mutex);
drm_atomic_helper_commit_cleanup_done(state);
@@ -13179,10 +12511,8 @@ intel_atomic_commit_ready(struct i915_sw_fence *fence,
switch (notify) {
case FENCE_COMPLETE:
- if (state->base.commit_work.func)
- queue_work(system_unbound_wq, &state->base.commit_work);
+ /* we do blocking waits in the worker, nothing to do here */
break;
-
case FENCE_FREE:
{
struct intel_atomic_helper *helper =
@@ -13264,7 +12594,13 @@ static int intel_atomic_commit(struct drm_device *dev,
if (INTEL_GEN(dev_priv) < 9)
state->legacy_cursor_update = false;
- drm_atomic_helper_swap_state(state, true);
+ ret = drm_atomic_helper_swap_state(state, true);
+ if (ret) {
+ i915_sw_fence_commit(&intel_state->commit_ready);
+
+ drm_atomic_helper_cleanup_planes(dev, state);
+ return ret;
+ }
dev_priv->wm.distrust_bios_wm = false;
intel_shared_dpll_swap_state(state);
intel_atomic_track_fbs(state);
@@ -13278,14 +12614,14 @@ static int intel_atomic_commit(struct drm_device *dev,
}
drm_atomic_state_get(state);
- INIT_WORK(&state->commit_work,
- nonblock ? intel_atomic_commit_work : NULL);
+ INIT_WORK(&state->commit_work, intel_atomic_commit_work);
i915_sw_fence_commit(&intel_state->commit_ready);
- if (!nonblock) {
- i915_sw_fence_wait(&intel_state->commit_ready);
+ if (nonblock)
+ queue_work(system_unbound_wq, &state->commit_work);
+ else
intel_atomic_commit_tail(state);
- }
+
return 0;
}
@@ -13293,7 +12629,6 @@ static int intel_atomic_commit(struct drm_device *dev,
static const struct drm_crtc_funcs intel_crtc_funcs = {
.gamma_set = drm_atomic_helper_legacy_gamma_set,
.set_config = drm_atomic_helper_set_config,
- .set_property = drm_atomic_helper_crtc_set_property,
.destroy = intel_crtc_destroy,
.page_flip = drm_atomic_helper_page_flip,
.atomic_duplicate_state = intel_crtc_duplicate_state,
@@ -13327,32 +12662,6 @@ intel_prepare_plane_fb(struct drm_plane *plane,
struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->state->fb);
int ret;
- if (obj) {
- if (plane->type == DRM_PLANE_TYPE_CURSOR &&
- INTEL_INFO(dev_priv)->cursor_needs_physical) {
- const int align = intel_cursor_alignment(dev_priv);
-
- ret = i915_gem_object_attach_phys(obj, align);
- if (ret) {
- DRM_DEBUG_KMS("failed to attach phys object\n");
- return ret;
- }
- } else {
- struct i915_vma *vma;
-
- vma = intel_pin_and_fence_fb_obj(fb, new_state->rotation);
- if (IS_ERR(vma)) {
- DRM_DEBUG_KMS("failed to pin object\n");
- return PTR_ERR(vma);
- }
-
- to_intel_plane_state(new_state)->vma = vma;
- }
- }
-
- if (!obj && !old_obj)
- return 0;
-
if (old_obj) {
struct drm_crtc_state *crtc_state =
drm_atomic_get_existing_crtc_state(new_state->state,
@@ -13391,6 +12700,38 @@ intel_prepare_plane_fb(struct drm_plane *plane,
if (!obj)
return 0;
+ ret = i915_gem_object_pin_pages(obj);
+ if (ret)
+ return ret;
+
+ ret = mutex_lock_interruptible(&dev_priv->drm.struct_mutex);
+ if (ret) {
+ i915_gem_object_unpin_pages(obj);
+ return ret;
+ }
+
+ if (plane->type == DRM_PLANE_TYPE_CURSOR &&
+ INTEL_INFO(dev_priv)->cursor_needs_physical) {
+ const int align = intel_cursor_alignment(dev_priv);
+
+ ret = i915_gem_object_attach_phys(obj, align);
+ } else {
+ struct i915_vma *vma;
+
+ vma = intel_pin_and_fence_fb_obj(fb, new_state->rotation);
+ if (!IS_ERR(vma))
+ to_intel_plane_state(new_state)->vma = vma;
+ else
+ ret = PTR_ERR(vma);
+ }
+
+ i915_gem_object_wait_priority(obj, 0, I915_PRIORITY_DISPLAY);
+
+ mutex_unlock(&dev_priv->drm.struct_mutex);
+ i915_gem_object_unpin_pages(obj);
+ if (ret)
+ return ret;
+
if (!new_state->fence) { /* implicit fencing */
ret = i915_sw_fence_await_reservation(&intel_state->commit_ready,
obj->resv, NULL,
@@ -13398,8 +12739,6 @@ intel_prepare_plane_fb(struct drm_plane *plane,
GFP_KERNEL);
if (ret < 0)
return ret;
-
- i915_gem_object_wait_priority(obj, 0, I915_PRIORITY_DISPLAY);
}
return 0;
@@ -13422,8 +12761,11 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
/* Should only be called after a successful intel_prepare_plane_fb()! */
vma = fetch_and_zero(&to_intel_plane_state(old_state)->vma);
- if (vma)
+ if (vma) {
+ mutex_lock(&plane->dev->struct_mutex);
intel_unpin_fb_vma(vma);
+ mutex_unlock(&plane->dev->struct_mutex);
+ }
}
int
@@ -13550,7 +12892,7 @@ static void intel_finish_crtc_commit(struct drm_crtc *crtc,
{
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- intel_pipe_update_end(intel_crtc, NULL);
+ intel_pipe_update_end(intel_crtc);
}
/**
@@ -13566,15 +12908,110 @@ void intel_plane_destroy(struct drm_plane *plane)
kfree(to_intel_plane(plane));
}
-const struct drm_plane_funcs intel_plane_funcs = {
+static bool i8xx_mod_supported(uint32_t format, uint64_t modifier)
+{
+ switch (format) {
+ case DRM_FORMAT_C8:
+ case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_XRGB1555:
+ case DRM_FORMAT_XRGB8888:
+ return modifier == DRM_FORMAT_MOD_LINEAR ||
+ modifier == I915_FORMAT_MOD_X_TILED;
+ default:
+ return false;
+ }
+}
+
+static bool i965_mod_supported(uint32_t format, uint64_t modifier)
+{
+ switch (format) {
+ case DRM_FORMAT_C8:
+ case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_XRGB2101010:
+ case DRM_FORMAT_XBGR2101010:
+ return modifier == DRM_FORMAT_MOD_LINEAR ||
+ modifier == I915_FORMAT_MOD_X_TILED;
+ default:
+ return false;
+ }
+}
+
+static bool skl_mod_supported(uint32_t format, uint64_t modifier)
+{
+ switch (format) {
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_ARGB8888:
+ case DRM_FORMAT_ABGR8888:
+ if (modifier == I915_FORMAT_MOD_Yf_TILED_CCS ||
+ modifier == I915_FORMAT_MOD_Y_TILED_CCS)
+ return true;
+ /* fall through */
+ case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_XRGB2101010:
+ case DRM_FORMAT_XBGR2101010:
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_YVYU:
+ case DRM_FORMAT_UYVY:
+ case DRM_FORMAT_VYUY:
+ if (modifier == I915_FORMAT_MOD_Yf_TILED)
+ return true;
+ /* fall through */
+ case DRM_FORMAT_C8:
+ if (modifier == DRM_FORMAT_MOD_LINEAR ||
+ modifier == I915_FORMAT_MOD_X_TILED ||
+ modifier == I915_FORMAT_MOD_Y_TILED)
+ return true;
+ /* fall through */
+ default:
+ return false;
+ }
+}
+
+static bool intel_primary_plane_format_mod_supported(struct drm_plane *plane,
+ uint32_t format,
+ uint64_t modifier)
+{
+ struct drm_i915_private *dev_priv = to_i915(plane->dev);
+
+ if (WARN_ON(modifier == DRM_FORMAT_MOD_INVALID))
+ return false;
+
+ if ((modifier >> 56) != DRM_FORMAT_MOD_VENDOR_INTEL &&
+ modifier != DRM_FORMAT_MOD_LINEAR)
+ return false;
+
+ if (INTEL_GEN(dev_priv) >= 9)
+ return skl_mod_supported(format, modifier);
+ else if (INTEL_GEN(dev_priv) >= 4)
+ return i965_mod_supported(format, modifier);
+ else
+ return i8xx_mod_supported(format, modifier);
+
+ unreachable();
+}
+
+static bool intel_cursor_plane_format_mod_supported(struct drm_plane *plane,
+ uint32_t format,
+ uint64_t modifier)
+{
+ if (WARN_ON(modifier == DRM_FORMAT_MOD_INVALID))
+ return false;
+
+ return modifier == DRM_FORMAT_MOD_LINEAR && format == DRM_FORMAT_ARGB8888;
+}
+
+static struct drm_plane_funcs intel_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = intel_plane_destroy,
- .set_property = drm_atomic_helper_plane_set_property,
.atomic_get_property = intel_plane_atomic_get_property,
.atomic_set_property = intel_plane_atomic_set_property,
.atomic_duplicate_state = intel_plane_duplicate_state,
.atomic_destroy_state = intel_plane_destroy_state,
+ .format_mod_supported = intel_primary_plane_format_mod_supported,
};
static int
@@ -13593,7 +13030,7 @@ intel_legacy_cursor_update(struct drm_plane *plane,
struct intel_plane *intel_plane = to_intel_plane(plane);
struct drm_framebuffer *old_fb;
struct drm_crtc_state *crtc_state = crtc->state;
- struct i915_vma *old_vma;
+ struct i915_vma *old_vma, *vma;
/*
* When crtc is inactive or there is a modeset pending,
@@ -13651,8 +13088,6 @@ intel_legacy_cursor_update(struct drm_plane *plane,
goto out_unlock;
}
} else {
- struct i915_vma *vma;
-
vma = intel_pin_and_fence_fb_obj(fb, new_plane_state->rotation);
if (IS_ERR(vma)) {
DRM_DEBUG_KMS("failed to pin object\n");
@@ -13675,7 +13110,7 @@ intel_legacy_cursor_update(struct drm_plane *plane,
*to_intel_plane_state(old_plane_state) = *to_intel_plane_state(new_plane_state);
new_plane_state->fence = NULL;
new_plane_state->fb = old_fb;
- to_intel_plane_state(new_plane_state)->vma = old_vma;
+ to_intel_plane_state(new_plane_state)->vma = NULL;
if (plane->state->visible) {
trace_intel_update_plane(plane, to_intel_crtc(crtc));
@@ -13687,7 +13122,8 @@ intel_legacy_cursor_update(struct drm_plane *plane,
intel_plane->disable_plane(intel_plane, to_intel_crtc(crtc));
}
- intel_cleanup_plane_fb(plane, new_plane_state);
+ if (old_vma)
+ intel_unpin_fb_vma(old_vma);
out_unlock:
mutex_unlock(&dev_priv->drm.struct_mutex);
@@ -13705,11 +13141,11 @@ static const struct drm_plane_funcs intel_cursor_plane_funcs = {
.update_plane = intel_legacy_cursor_update,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = intel_plane_destroy,
- .set_property = drm_atomic_helper_plane_set_property,
.atomic_get_property = intel_plane_atomic_get_property,
.atomic_set_property = intel_plane_atomic_set_property,
.atomic_duplicate_state = intel_plane_duplicate_state,
.atomic_destroy_state = intel_plane_destroy_state,
+ .format_mod_supported = intel_cursor_plane_format_mod_supported,
};
static struct intel_plane *
@@ -13720,6 +13156,7 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
const uint32_t *intel_primary_formats;
unsigned int supported_rotations;
unsigned int num_formats;
+ const uint64_t *modifiers;
int ret;
primary = kzalloc(sizeof(*primary), GFP_KERNEL);
@@ -13755,21 +13192,34 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
primary->frontbuffer_bit = INTEL_FRONTBUFFER_PRIMARY(pipe);
primary->check_plane = intel_check_primary_plane;
- if (INTEL_GEN(dev_priv) >= 9) {
+ if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) {
intel_primary_formats = skl_primary_formats;
num_formats = ARRAY_SIZE(skl_primary_formats);
+ modifiers = skl_format_modifiers_ccs;
+
+ primary->update_plane = skylake_update_primary_plane;
+ primary->disable_plane = skylake_disable_primary_plane;
+ } else if (INTEL_GEN(dev_priv) >= 9) {
+ intel_primary_formats = skl_primary_formats;
+ num_formats = ARRAY_SIZE(skl_primary_formats);
+ if (pipe < PIPE_C)
+ modifiers = skl_format_modifiers_ccs;
+ else
+ modifiers = skl_format_modifiers_noccs;
primary->update_plane = skylake_update_primary_plane;
primary->disable_plane = skylake_disable_primary_plane;
} else if (INTEL_GEN(dev_priv) >= 4) {
intel_primary_formats = i965_primary_formats;
num_formats = ARRAY_SIZE(i965_primary_formats);
+ modifiers = i9xx_format_modifiers;
primary->update_plane = i9xx_update_primary_plane;
primary->disable_plane = i9xx_disable_primary_plane;
} else {
intel_primary_formats = i8xx_primary_formats;
num_formats = ARRAY_SIZE(i8xx_primary_formats);
+ modifiers = i9xx_format_modifiers;
primary->update_plane = i9xx_update_primary_plane;
primary->disable_plane = i9xx_disable_primary_plane;
@@ -13779,18 +13229,21 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
ret = drm_universal_plane_init(&dev_priv->drm, &primary->base,
0, &intel_plane_funcs,
intel_primary_formats, num_formats,
+ modifiers,
DRM_PLANE_TYPE_PRIMARY,
"plane 1%c", pipe_name(pipe));
else if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv))
ret = drm_universal_plane_init(&dev_priv->drm, &primary->base,
0, &intel_plane_funcs,
intel_primary_formats, num_formats,
+ modifiers,
DRM_PLANE_TYPE_PRIMARY,
"primary %c", pipe_name(pipe));
else
ret = drm_universal_plane_init(&dev_priv->drm, &primary->base,
0, &intel_plane_funcs,
intel_primary_formats, num_formats,
+ modifiers,
DRM_PLANE_TYPE_PRIMARY,
"plane %c", plane_name(primary->plane));
if (ret)
@@ -13876,6 +13329,7 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv,
0, &intel_cursor_plane_funcs,
intel_cursor_formats,
ARRAY_SIZE(intel_cursor_formats),
+ cursor_format_modifiers,
DRM_PLANE_TYPE_CURSOR,
"cursor %c", pipe_name(pipe));
if (ret)
@@ -14398,10 +13852,12 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
struct drm_mode_fb_cmd2 *mode_cmd)
{
struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+ struct drm_framebuffer *fb = &intel_fb->base;
struct drm_format_name_buf format_name;
- u32 pitch_limit, stride_alignment;
+ u32 pitch_limit;
unsigned int tiling, stride;
int ret = -EINVAL;
+ int i;
i915_gem_object_lock(obj);
obj->framebuffer_references++;
@@ -14430,6 +13886,19 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
/* Passed in modifier sanity checking. */
switch (mode_cmd->modifier[0]) {
+ case I915_FORMAT_MOD_Y_TILED_CCS:
+ case I915_FORMAT_MOD_Yf_TILED_CCS:
+ switch (mode_cmd->pixel_format) {
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_ABGR8888:
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_ARGB8888:
+ break;
+ default:
+ DRM_DEBUG_KMS("RC supported only with RGB8888 formats\n");
+ goto err;
+ }
+ /* fall through */
case I915_FORMAT_MOD_Y_TILED:
case I915_FORMAT_MOD_Yf_TILED:
if (INTEL_GEN(dev_priv) < 9) {
@@ -14534,25 +14003,46 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
if (mode_cmd->offsets[0] != 0)
goto err;
- drm_helper_mode_fill_fb_struct(&dev_priv->drm,
- &intel_fb->base, mode_cmd);
+ drm_helper_mode_fill_fb_struct(&dev_priv->drm, fb, mode_cmd);
- stride_alignment = intel_fb_stride_alignment(&intel_fb->base, 0);
- if (mode_cmd->pitches[0] & (stride_alignment - 1)) {
- DRM_DEBUG_KMS("pitch (%d) must be at least %u byte aligned\n",
- mode_cmd->pitches[0], stride_alignment);
- goto err;
+ for (i = 0; i < fb->format->num_planes; i++) {
+ u32 stride_alignment;
+
+ if (mode_cmd->handles[i] != mode_cmd->handles[0]) {
+ DRM_DEBUG_KMS("bad plane %d handle\n", i);
+ return -EINVAL;
+ }
+
+ stride_alignment = intel_fb_stride_alignment(fb, i);
+
+ /*
+ * Display WA #0531: skl,bxt,kbl,glk
+ *
+ * Render decompression and plane width > 3840
+ * combined with horizontal panning requires the
+ * plane stride to be a multiple of 4. We'll just
+ * require the entire fb to accommodate that to avoid
+ * potential runtime errors at plane configuration time.
+ */
+ if (IS_GEN9(dev_priv) && i == 0 && fb->width > 3840 &&
+ (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
+ fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS))
+ stride_alignment *= 4;
+
+ if (fb->pitches[i] & (stride_alignment - 1)) {
+ DRM_DEBUG_KMS("plane %d pitch (%d) must be at least %u byte aligned\n",
+ i, fb->pitches[i], stride_alignment);
+ goto err;
+ }
}
intel_fb->obj = obj;
- ret = intel_fill_fb_info(dev_priv, &intel_fb->base);
+ ret = intel_fill_fb_info(dev_priv, fb);
if (ret)
goto err;
- ret = drm_framebuffer_init(obj->base.dev,
- &intel_fb->base,
- &intel_fb_funcs);
+ ret = drm_framebuffer_init(&dev_priv->drm, fb, &intel_fb_funcs);
if (ret) {
DRM_ERROR("framebuffer init failed %d\n", ret);
goto err;
@@ -14600,6 +14090,7 @@ static void intel_atomic_state_free(struct drm_atomic_state *state)
static const struct drm_mode_config_funcs intel_mode_funcs = {
.fb_create = intel_user_framebuffer_create,
+ .get_format_info = intel_get_format_info,
.output_poll_changed = intel_fbdev_output_poll_changed,
.atomic_check = intel_atomic_check,
.atomic_commit = intel_atomic_commit,
@@ -14699,34 +14190,6 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv)
dev_priv->display.update_crtcs = skl_update_crtcs;
else
dev_priv->display.update_crtcs = intel_update_crtcs;
-
- switch (INTEL_INFO(dev_priv)->gen) {
- case 2:
- dev_priv->display.queue_flip = intel_gen2_queue_flip;
- break;
-
- case 3:
- dev_priv->display.queue_flip = intel_gen3_queue_flip;
- break;
-
- case 4:
- case 5:
- dev_priv->display.queue_flip = intel_gen4_queue_flip;
- break;
-
- case 6:
- dev_priv->display.queue_flip = intel_gen6_queue_flip;
- break;
- case 7:
- case 8: /* FIXME(BDW): Check that the gen8 RCS flip works. */
- dev_priv->display.queue_flip = intel_gen7_queue_flip;
- break;
- case 9:
- /* Drop through - unsupported since execlist only. */
- default:
- /* Default just returns -ENODEV to indicate unsupported */
- dev_priv->display.queue_flip = intel_default_queue_flip;
- }
}
/*
@@ -14758,6 +14221,17 @@ static void quirk_backlight_present(struct drm_device *dev)
DRM_INFO("applying backlight present quirk\n");
}
+/* Toshiba Satellite P50-C-18C requires T12 delay to be min 800ms
+ * which is 300 ms greater than eDP spec T12 min.
+ */
+static void quirk_increase_t12_delay(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = to_i915(dev);
+
+ dev_priv->quirks |= QUIRK_INCREASE_T12_DELAY;
+ DRM_INFO("Applying T12 delay quirk\n");
+}
+
struct intel_quirk {
int device;
int subsystem_vendor;
@@ -14841,6 +14315,9 @@ static struct intel_quirk intel_quirks[] = {
/* Dell Chromebook 11 (2015 version) */
{ 0x0a16, 0x1028, 0x0a35, quirk_backlight_present },
+
+ /* Toshiba Satellite P50-C-18C */
+ { 0x191B, 0x1179, 0xF840, quirk_increase_t12_delay },
};
static void intel_init_quirks(struct drm_device *dev)
@@ -15643,7 +15120,7 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
vlv_wm_get_hw_state(dev);
vlv_wm_sanitize(dev_priv);
- } else if (IS_GEN9(dev_priv)) {
+ } else if (INTEL_GEN(dev_priv) >= 9) {
skl_wm_get_hw_state(dev);
} else if (HAS_PCH_SPLIT(dev_priv)) {
ilk_wm_get_hw_state(dev);
@@ -15750,6 +15227,9 @@ void intel_modeset_cleanup(struct drm_device *dev)
*/
drm_kms_helper_poll_fini(dev);
+ /* poll work can call into fbdev, hence clean that up afterwards */
+ intel_fbdev_fini(dev_priv);
+
intel_unregister_dsm_handler();
intel_fbc_global_disable(dev_priv);
@@ -15869,7 +15349,8 @@ intel_display_capture_error_state(struct drm_i915_private *dev_priv)
return NULL;
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
- error->power_well_driver = I915_READ(HSW_PWR_WELL_DRIVER);
+ error->power_well_driver =
+ I915_READ(HSW_PWR_WELL_CTL_DRIVER(HSW_DISP_PW_GLOBAL));
for_each_pipe(dev_priv, i) {
error->pipe[i].power_domain_on =
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 64fa774..4fd4853 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -97,6 +97,9 @@ static const int bxt_rates[] = { 162000, 216000, 243000, 270000,
324000, 432000, 540000 };
static const int skl_rates[] = { 162000, 216000, 270000,
324000, 432000, 540000 };
+static const int cnl_rates[] = { 162000, 216000, 270000,
+ 324000, 432000, 540000,
+ 648000, 810000 };
static const int default_rates[] = { 162000, 270000, 540000 };
/**
@@ -229,8 +232,10 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp)
{
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
+ enum port port = dig_port->port;
const int *source_rates;
int size;
+ u32 voltage;
/* This should only be done once */
WARN_ON(intel_dp->source_rates || intel_dp->num_source_rates);
@@ -238,6 +243,13 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp)
if (IS_GEN9_LP(dev_priv)) {
source_rates = bxt_rates;
size = ARRAY_SIZE(bxt_rates);
+ } else if (IS_CANNONLAKE(dev_priv)) {
+ source_rates = cnl_rates;
+ size = ARRAY_SIZE(cnl_rates);
+ voltage = I915_READ(CNL_PORT_COMP_DW3) & VOLTAGE_INFO_MASK;
+ if (port == PORT_A || port == PORT_D ||
+ voltage == VOLTAGE_INFO_0_85V)
+ size -= 2;
} else if (IS_GEN9_BC(dev_priv)) {
source_rates = skl_rates;
size = ARRAY_SIZE(skl_rates);
@@ -322,19 +334,20 @@ static int intel_dp_common_len_rate_limit(struct intel_dp *intel_dp,
return 0;
}
-static bool intel_dp_link_params_valid(struct intel_dp *intel_dp)
+static bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate,
+ uint8_t lane_count)
{
/*
* FIXME: we need to synchronize the current link parameters with
* hardware readout. Currently fast link training doesn't work on
* boot-up.
*/
- if (intel_dp->link_rate == 0 ||
- intel_dp->link_rate > intel_dp->max_link_rate)
+ if (link_rate == 0 ||
+ link_rate > intel_dp->max_link_rate)
return false;
- if (intel_dp->lane_count == 0 ||
- intel_dp->lane_count > intel_dp_max_lane_count(intel_dp))
+ if (lane_count == 0 ||
+ lane_count > intel_dp_max_lane_count(intel_dp))
return false;
return true;
@@ -1606,6 +1619,23 @@ static int intel_dp_compute_bpp(struct intel_dp *intel_dp,
return bpp;
}
+static bool intel_edp_compare_alt_mode(struct drm_display_mode *m1,
+ struct drm_display_mode *m2)
+{
+ bool bres = false;
+
+ if (m1 && m2)
+ bres = (m1->hdisplay == m2->hdisplay &&
+ m1->hsync_start == m2->hsync_start &&
+ m1->hsync_end == m2->hsync_end &&
+ m1->htotal == m2->htotal &&
+ m1->vdisplay == m2->vdisplay &&
+ m1->vsync_start == m2->vsync_start &&
+ m1->vsync_end == m2->vsync_end &&
+ m1->vtotal == m2->vtotal);
+ return bres;
+}
+
bool
intel_dp_compute_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config,
@@ -1652,8 +1682,16 @@ intel_dp_compute_config(struct intel_encoder *encoder,
pipe_config->has_audio = intel_conn_state->force_audio == HDMI_AUDIO_ON;
if (is_edp(intel_dp) && intel_connector->panel.fixed_mode) {
- intel_fixed_panel_mode(intel_connector->panel.fixed_mode,
- adjusted_mode);
+ struct drm_display_mode *panel_mode =
+ intel_connector->panel.alt_fixed_mode;
+ struct drm_display_mode *req_mode = &pipe_config->base.mode;
+
+ if (!intel_edp_compare_alt_mode(req_mode, panel_mode))
+ panel_mode = intel_connector->panel.fixed_mode;
+
+ drm_mode_debug_printmodeline(panel_mode);
+
+ intel_fixed_panel_mode(panel_mode, adjusted_mode);
if (INTEL_GEN(dev_priv) >= 9) {
int ret;
@@ -1677,12 +1715,18 @@ intel_dp_compute_config(struct intel_encoder *encoder,
if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) {
int index;
- index = intel_dp_rate_index(intel_dp->common_rates,
- intel_dp->num_common_rates,
- intel_dp->compliance.test_link_rate);
- if (index >= 0)
- min_clock = max_clock = index;
- min_lane_count = max_lane_count = intel_dp->compliance.test_lane_count;
+ /* Validate the compliance test data since max values
+ * might have changed due to link train fallback.
+ */
+ if (intel_dp_link_params_valid(intel_dp, intel_dp->compliance.test_link_rate,
+ intel_dp->compliance.test_lane_count)) {
+ index = intel_dp_rate_index(intel_dp->common_rates,
+ intel_dp->num_common_rates,
+ intel_dp->compliance.test_link_rate);
+ if (index >= 0)
+ min_clock = max_clock = index;
+ min_lane_count = max_lane_count = intel_dp->compliance.test_lane_count;
+ }
}
DRM_DEBUG_KMS("DP link computation with max lane count %i "
"max bw %d pixel clock %iKHz\n",
@@ -3963,8 +4007,7 @@ intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector)
static uint8_t intel_dp_autotest_link_training(struct intel_dp *intel_dp)
{
int status = 0;
- int min_lane_count = 1;
- int link_rate_index, test_link_rate;
+ int test_link_rate;
uint8_t test_lane_count, test_link_bw;
/* (DP CTS 1.2)
* 4.3.1.11
@@ -3978,10 +4021,6 @@ static uint8_t intel_dp_autotest_link_training(struct intel_dp *intel_dp)
return DP_TEST_NAK;
}
test_lane_count &= DP_MAX_LANE_COUNT_MASK;
- /* Validate the requested lane count */
- if (test_lane_count < min_lane_count ||
- test_lane_count > intel_dp->max_link_lane_count)
- return DP_TEST_NAK;
status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_LINK_RATE,
&test_link_bw);
@@ -3989,12 +4028,11 @@ static uint8_t intel_dp_autotest_link_training(struct intel_dp *intel_dp)
DRM_DEBUG_KMS("Link Rate read failed\n");
return DP_TEST_NAK;
}
- /* Validate the requested link rate */
test_link_rate = drm_dp_bw_code_to_link_rate(test_link_bw);
- link_rate_index = intel_dp_rate_index(intel_dp->common_rates,
- intel_dp->num_common_rates,
- test_link_rate);
- if (link_rate_index < 0)
+
+ /* Validate the requested link rate and lane count */
+ if (!intel_dp_link_params_valid(intel_dp, test_link_rate,
+ test_lane_count))
return DP_TEST_NAK;
intel_dp->compliance.test_lane_count = test_lane_count;
@@ -4263,7 +4301,8 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
* Validate the cached values of intel_dp->link_rate and
* intel_dp->lane_count before attempting to retrain.
*/
- if (!intel_dp_link_params_valid(intel_dp))
+ if (!intel_dp_link_params_valid(intel_dp, intel_dp->link_rate,
+ intel_dp->lane_count))
return;
/* Retrain if Channel EQ or CR not ok */
@@ -4418,8 +4457,6 @@ static bool ibx_digital_port_connected(struct drm_i915_private *dev_priv,
u32 bit;
switch (port->port) {
- case PORT_A:
- return true;
case PORT_B:
bit = SDE_PORTB_HOTPLUG;
break;
@@ -4443,8 +4480,6 @@ static bool cpt_digital_port_connected(struct drm_i915_private *dev_priv,
u32 bit;
switch (port->port) {
- case PORT_A:
- return true;
case PORT_B:
bit = SDE_PORTB_HOTPLUG_CPT;
break;
@@ -4454,12 +4489,28 @@ static bool cpt_digital_port_connected(struct drm_i915_private *dev_priv,
case PORT_D:
bit = SDE_PORTD_HOTPLUG_CPT;
break;
+ default:
+ MISSING_CASE(port->port);
+ return false;
+ }
+
+ return I915_READ(SDEISR) & bit;
+}
+
+static bool spt_digital_port_connected(struct drm_i915_private *dev_priv,
+ struct intel_digital_port *port)
+{
+ u32 bit;
+
+ switch (port->port) {
+ case PORT_A:
+ bit = SDE_PORTA_HOTPLUG_SPT;
+ break;
case PORT_E:
bit = SDE_PORTE_HOTPLUG_SPT;
break;
default:
- MISSING_CASE(port->port);
- return false;
+ return cpt_digital_port_connected(dev_priv, port);
}
return I915_READ(SDEISR) & bit;
@@ -4511,6 +4562,42 @@ static bool gm45_digital_port_connected(struct drm_i915_private *dev_priv,
return I915_READ(PORT_HOTPLUG_STAT) & bit;
}
+static bool ilk_digital_port_connected(struct drm_i915_private *dev_priv,
+ struct intel_digital_port *port)
+{
+ if (port->port == PORT_A)
+ return I915_READ(DEISR) & DE_DP_A_HOTPLUG;
+ else
+ return ibx_digital_port_connected(dev_priv, port);
+}
+
+static bool snb_digital_port_connected(struct drm_i915_private *dev_priv,
+ struct intel_digital_port *port)
+{
+ if (port->port == PORT_A)
+ return I915_READ(DEISR) & DE_DP_A_HOTPLUG;
+ else
+ return cpt_digital_port_connected(dev_priv, port);
+}
+
+static bool ivb_digital_port_connected(struct drm_i915_private *dev_priv,
+ struct intel_digital_port *port)
+{
+ if (port->port == PORT_A)
+ return I915_READ(DEISR) & DE_DP_A_HOTPLUG_IVB;
+ else
+ return cpt_digital_port_connected(dev_priv, port);
+}
+
+static bool bdw_digital_port_connected(struct drm_i915_private *dev_priv,
+ struct intel_digital_port *port)
+{
+ if (port->port == PORT_A)
+ return I915_READ(GEN8_DE_PORT_ISR) & GEN8_PORT_DP_A_HOTPLUG;
+ else
+ return cpt_digital_port_connected(dev_priv, port);
+}
+
static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
struct intel_digital_port *intel_dig_port)
{
@@ -4518,7 +4605,7 @@ static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
enum port port;
u32 bit;
- intel_hpd_pin_to_port(intel_encoder->hpd_pin, &port);
+ port = intel_hpd_pin_to_port(intel_encoder->hpd_pin);
switch (port) {
case PORT_A:
bit = BXT_DE_PORT_HP_DDIA;
@@ -4547,16 +4634,25 @@ static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
struct intel_digital_port *port)
{
- if (HAS_PCH_IBX(dev_priv))
- return ibx_digital_port_connected(dev_priv, port);
- else if (HAS_PCH_SPLIT(dev_priv))
- return cpt_digital_port_connected(dev_priv, port);
+ if (HAS_GMCH_DISPLAY(dev_priv)) {
+ if (IS_GM45(dev_priv))
+ return gm45_digital_port_connected(dev_priv, port);
+ else
+ return g4x_digital_port_connected(dev_priv, port);
+ }
+
+ if (IS_GEN5(dev_priv))
+ return ilk_digital_port_connected(dev_priv, port);
+ else if (IS_GEN6(dev_priv))
+ return snb_digital_port_connected(dev_priv, port);
+ else if (IS_GEN7(dev_priv))
+ return ivb_digital_port_connected(dev_priv, port);
+ else if (IS_GEN8(dev_priv))
+ return bdw_digital_port_connected(dev_priv, port);
else if (IS_GEN9_LP(dev_priv))
return bxt_digital_port_connected(dev_priv, port);
- else if (IS_GM45(dev_priv))
- return gm45_digital_port_connected(dev_priv, port);
else
- return g4x_digital_port_connected(dev_priv, port);
+ return spt_digital_port_connected(dev_priv, port);
}
static struct edid *
@@ -4950,10 +5046,8 @@ void intel_dp_encoder_reset(struct drm_encoder *encoder)
}
static const struct drm_connector_funcs intel_dp_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.force = intel_dp_force,
.fill_modes = drm_helper_probe_single_connector_modes,
- .set_property = drm_atomic_helper_connector_set_property,
.atomic_get_property = intel_digital_connector_atomic_get_property,
.atomic_set_property = intel_digital_connector_atomic_set_property,
.late_register = intel_dp_connector_register,
@@ -5121,12 +5215,8 @@ intel_pps_readout_hw_state(struct drm_i915_private *dev_priv,
PANEL_POWER_DOWN_DELAY_SHIFT;
if (IS_GEN9_LP(dev_priv) || HAS_PCH_CNP(dev_priv)) {
- u16 tmp = (pp_ctl & BXT_POWER_CYCLE_DELAY_MASK) >>
- BXT_POWER_CYCLE_DELAY_SHIFT;
- if (tmp > 0)
- seq->t11_t12 = (tmp - 1) * 1000;
- else
- seq->t11_t12 = 0;
+ seq->t11_t12 = ((pp_ctl & BXT_POWER_CYCLE_DELAY_MASK) >>
+ BXT_POWER_CYCLE_DELAY_SHIFT) * 1000;
} else {
seq->t11_t12 = ((pp_div & PANEL_POWER_CYCLE_DELAY_MASK) >>
PANEL_POWER_CYCLE_DELAY_SHIFT) * 1000;
@@ -5177,6 +5267,21 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev,
intel_pps_dump_state("cur", &cur);
vbt = dev_priv->vbt.edp.pps;
+ /* On Toshiba Satellite P50-C-18C system the VBT T12 delay
+ * of 500ms appears to be too short. Ocassionally the panel
+ * just fails to power back on. Increasing the delay to 800ms
+ * seems sufficient to avoid this problem.
+ */
+ if (dev_priv->quirks & QUIRK_INCREASE_T12_DELAY) {
+ vbt.t11_t12 = max_t(u16, vbt.t11_t12, 800 * 10);
+ DRM_DEBUG_KMS("Increasing T12 panel delay as per the quirk to %d\n",
+ vbt.t11_t12);
+ }
+ /* T11_T12 delay is special and actually in units of 100ms, but zero
+ * based in the hw (so we need to add 100 ms). But the sw vbt
+ * table multiplies it with 1000 to make it in units of 100usec,
+ * too. */
+ vbt.t11_t12 += 100 * 10;
/* Upper limits from eDP 1.3 spec. Note that we use the clunky units of
* our hw here, which are all in 100usec. */
@@ -5280,7 +5385,7 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
if (IS_GEN9_LP(dev_priv) || HAS_PCH_CNP(dev_priv)) {
pp_div = I915_READ(regs.pp_ctrl);
pp_div &= ~BXT_POWER_CYCLE_DELAY_MASK;
- pp_div |= (DIV_ROUND_UP((seq->t11_t12 + 1), 1000)
+ pp_div |= (DIV_ROUND_UP(seq->t11_t12, 1000)
<< BXT_POWER_CYCLE_DELAY_SHIFT);
} else {
pp_div = ((100 * div)/2 - 1) << PP_REFERENCE_DIVIDER_SHIFT;
@@ -5714,6 +5819,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
struct drm_device *dev = intel_encoder->base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_display_mode *fixed_mode = NULL;
+ struct drm_display_mode *alt_fixed_mode = NULL;
struct drm_display_mode *downclock_mode = NULL;
bool has_dpcd;
struct drm_display_mode *scan;
@@ -5769,13 +5875,14 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
}
intel_connector->edid = edid;
- /* prefer fixed mode from EDID if available */
+ /* prefer fixed mode from EDID if available, save an alt mode also */
list_for_each_entry(scan, &connector->probed_modes, head) {
if ((scan->type & DRM_MODE_TYPE_PREFERRED)) {
fixed_mode = drm_mode_duplicate(dev, scan);
downclock_mode = intel_dp_drrs_init(
intel_connector, fixed_mode);
- break;
+ } else if (!alt_fixed_mode) {
+ alt_fixed_mode = drm_mode_duplicate(dev, scan);
}
}
@@ -5812,7 +5919,8 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
pipe_name(pipe));
}
- intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode);
+ intel_panel_init(&intel_connector->panel, fixed_mode, alt_fixed_mode,
+ downclock_mode);
intel_connector->panel.backlight.power = intel_edp_backlight_power;
intel_panel_setup_backlight(connector, pipe);
@@ -5838,26 +5946,22 @@ intel_dp_init_connector_port_info(struct intel_digital_port *intel_dig_port)
struct intel_encoder *encoder = &intel_dig_port->base;
struct intel_dp *intel_dp = &intel_dig_port->dp;
+ encoder->hpd_pin = intel_hpd_pin(intel_dig_port->port);
+
switch (intel_dig_port->port) {
case PORT_A:
- encoder->hpd_pin = HPD_PORT_A;
intel_dp->aux_power_domain = POWER_DOMAIN_AUX_A;
break;
case PORT_B:
- encoder->hpd_pin = HPD_PORT_B;
intel_dp->aux_power_domain = POWER_DOMAIN_AUX_B;
break;
case PORT_C:
- encoder->hpd_pin = HPD_PORT_C;
intel_dp->aux_power_domain = POWER_DOMAIN_AUX_C;
break;
case PORT_D:
- encoder->hpd_pin = HPD_PORT_D;
intel_dp->aux_power_domain = POWER_DOMAIN_AUX_D;
break;
case PORT_E:
- encoder->hpd_pin = HPD_PORT_E;
-
/* FIXME: Check VBT for actual wiring of PORT E */
intel_dp->aux_power_domain = POWER_DOMAIN_AUX_D;
break;
diff --git a/drivers/gpu/drm/i915/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/intel_dp_aux_backlight.c
index 228ca06..d2830ba 100644
--- a/drivers/gpu/drm/i915/intel_dp_aux_backlight.c
+++ b/drivers/gpu/drm/i915/intel_dp_aux_backlight.c
@@ -98,13 +98,87 @@ intel_dp_aux_set_backlight(const struct drm_connector_state *conn_state, u32 lev
}
}
+/*
+ * Set PWM Frequency divider to match desired frequency in vbt.
+ * The PWM Frequency is calculated as 27Mhz / (F x P).
+ * - Where F = PWM Frequency Pre-Divider value programmed by field 7:0 of the
+ * EDP_BACKLIGHT_FREQ_SET register (DPCD Address 00728h)
+ * - Where P = 2^Pn, where Pn is the value programmed by field 4:0 of the
+ * EDP_PWMGEN_BIT_COUNT register (DPCD Address 00724h)
+ */
+static bool intel_dp_aux_set_pwm_freq(struct intel_connector *connector)
+{
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ struct intel_dp *intel_dp = enc_to_intel_dp(&connector->encoder->base);
+ int freq, fxp, fxp_min, fxp_max, fxp_actual, f = 1;
+ u8 pn, pn_min, pn_max;
+
+ /* Find desired value of (F x P)
+ * Note that, if F x P is out of supported range, the maximum value or
+ * minimum value will applied automatically. So no need to check that.
+ */
+ freq = dev_priv->vbt.backlight.pwm_freq_hz;
+ DRM_DEBUG_KMS("VBT defined backlight frequency %u Hz\n", freq);
+ if (!freq) {
+ DRM_DEBUG_KMS("Use panel default backlight frequency\n");
+ return false;
+ }
+
+ fxp = DIV_ROUND_CLOSEST(KHz(DP_EDP_BACKLIGHT_FREQ_BASE_KHZ), freq);
+
+ /* Use highest possible value of Pn for more granularity of brightness
+ * adjustment while satifying the conditions below.
+ * - Pn is in the range of Pn_min and Pn_max
+ * - F is in the range of 1 and 255
+ * - FxP is within 25% of desired value.
+ * Note: 25% is arbitrary value and may need some tweak.
+ */
+ if (drm_dp_dpcd_readb(&intel_dp->aux,
+ DP_EDP_PWMGEN_BIT_COUNT_CAP_MIN, &pn_min) != 1) {
+ DRM_DEBUG_KMS("Failed to read pwmgen bit count cap min\n");
+ return false;
+ }
+ if (drm_dp_dpcd_readb(&intel_dp->aux,
+ DP_EDP_PWMGEN_BIT_COUNT_CAP_MAX, &pn_max) != 1) {
+ DRM_DEBUG_KMS("Failed to read pwmgen bit count cap max\n");
+ return false;
+ }
+ pn_min &= DP_EDP_PWMGEN_BIT_COUNT_MASK;
+ pn_max &= DP_EDP_PWMGEN_BIT_COUNT_MASK;
+
+ fxp_min = DIV_ROUND_CLOSEST(fxp * 3, 4);
+ fxp_max = DIV_ROUND_CLOSEST(fxp * 5, 4);
+ if (fxp_min < (1 << pn_min) || (255 << pn_max) < fxp_max) {
+ DRM_DEBUG_KMS("VBT defined backlight frequency out of range\n");
+ return false;
+ }
+
+ for (pn = pn_max; pn >= pn_min; pn--) {
+ f = clamp(DIV_ROUND_CLOSEST(fxp, 1 << pn), 1, 255);
+ fxp_actual = f << pn;
+ if (fxp_min <= fxp_actual && fxp_actual <= fxp_max)
+ break;
+ }
+
+ if (drm_dp_dpcd_writeb(&intel_dp->aux,
+ DP_EDP_PWMGEN_BIT_COUNT, pn) < 0) {
+ DRM_DEBUG_KMS("Failed to write aux pwmgen bit count\n");
+ return false;
+ }
+ if (drm_dp_dpcd_writeb(&intel_dp->aux,
+ DP_EDP_BACKLIGHT_FREQ_SET, (u8) f) < 0) {
+ DRM_DEBUG_KMS("Failed to write aux backlight freq\n");
+ return false;
+ }
+ return true;
+}
+
static void intel_dp_aux_enable_backlight(const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
struct intel_connector *connector = to_intel_connector(conn_state->connector);
struct intel_dp *intel_dp = enc_to_intel_dp(&connector->encoder->base);
- uint8_t dpcd_buf = 0;
- uint8_t edp_backlight_mode = 0;
+ uint8_t dpcd_buf, new_dpcd_buf, edp_backlight_mode;
if (drm_dp_dpcd_readb(&intel_dp->aux,
DP_EDP_BACKLIGHT_MODE_SET_REGISTER, &dpcd_buf) != 1) {
@@ -113,18 +187,15 @@ static void intel_dp_aux_enable_backlight(const struct intel_crtc_state *crtc_st
return;
}
+ new_dpcd_buf = dpcd_buf;
edp_backlight_mode = dpcd_buf & DP_EDP_BACKLIGHT_CONTROL_MODE_MASK;
switch (edp_backlight_mode) {
case DP_EDP_BACKLIGHT_CONTROL_MODE_PWM:
case DP_EDP_BACKLIGHT_CONTROL_MODE_PRESET:
case DP_EDP_BACKLIGHT_CONTROL_MODE_PRODUCT:
- dpcd_buf &= ~DP_EDP_BACKLIGHT_CONTROL_MODE_MASK;
- dpcd_buf |= DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD;
- if (drm_dp_dpcd_writeb(&intel_dp->aux,
- DP_EDP_BACKLIGHT_MODE_SET_REGISTER, dpcd_buf) < 0) {
- DRM_DEBUG_KMS("Failed to write aux backlight mode\n");
- }
+ new_dpcd_buf &= ~DP_EDP_BACKLIGHT_CONTROL_MODE_MASK;
+ new_dpcd_buf |= DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD;
break;
/* Do nothing when it is already DPCD mode */
@@ -133,6 +204,17 @@ static void intel_dp_aux_enable_backlight(const struct intel_crtc_state *crtc_st
break;
}
+ if (intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_FREQ_AUX_SET_CAP)
+ if (intel_dp_aux_set_pwm_freq(connector))
+ new_dpcd_buf |= DP_EDP_BACKLIGHT_FREQ_AUX_SET_ENABLE;
+
+ if (new_dpcd_buf != dpcd_buf) {
+ if (drm_dp_dpcd_writeb(&intel_dp->aux,
+ DP_EDP_BACKLIGHT_MODE_SET_REGISTER, new_dpcd_buf) < 0) {
+ DRM_DEBUG_KMS("Failed to write aux backlight mode\n");
+ }
+ }
+
set_aux_backlight_enable(intel_dp, true);
intel_dp_aux_set_backlight(conn_state, connector->panel.backlight.level);
}
diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
index b79c1c0..05907fa 100644
--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
@@ -321,12 +321,16 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
if (!intel_dp_link_training_channel_equalization(intel_dp))
goto failure_handling;
- DRM_DEBUG_KMS("Link Training Passed at Link Rate = %d, Lane count = %d",
+ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Link Training Passed at Link Rate = %d, Lane count = %d",
+ intel_connector->base.base.id,
+ intel_connector->base.name,
intel_dp->link_rate, intel_dp->lane_count);
return;
failure_handling:
- DRM_DEBUG_KMS("Link Training failed at link rate = %d, lane count = %d",
+ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Link Training failed at link rate = %d, lane count = %d",
+ intel_connector->base.base.id,
+ intel_connector->base.name,
intel_dp->link_rate, intel_dp->lane_count);
if (!intel_dp_get_link_train_fallback_values(intel_dp,
intel_dp->link_rate,
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index 2cf046b..93fc8ab 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -346,10 +346,8 @@ intel_dp_mst_connector_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs intel_dp_mst_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = intel_dp_mst_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
- .set_property = drm_atomic_helper_connector_set_property,
.late_register = intel_connector_register,
.early_unregister = intel_connector_unregister,
.destroy = intel_dp_mst_connector_destroy,
@@ -372,6 +370,9 @@ intel_dp_mst_mode_valid(struct drm_connector *connector,
int bpp = 24; /* MST uses fixed bpp */
int max_rate, mode_rate, max_lanes, max_link_clock;
+ if (!intel_dp)
+ return MODE_ERROR;
+
max_link_clock = intel_dp_max_link_rate(intel_dp);
max_lanes = intel_dp_max_lane_count(intel_dp);
@@ -443,28 +444,6 @@ static bool intel_dp_mst_get_hw_state(struct intel_connector *connector)
return false;
}
-static void intel_connector_add_to_fbdev(struct intel_connector *connector)
-{
-#ifdef CONFIG_DRM_FBDEV_EMULATION
- struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-
- if (dev_priv->fbdev)
- drm_fb_helper_add_one_connector(&dev_priv->fbdev->helper,
- &connector->base);
-#endif
-}
-
-static void intel_connector_remove_from_fbdev(struct intel_connector *connector)
-{
-#ifdef CONFIG_DRM_FBDEV_EMULATION
- struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-
- if (dev_priv->fbdev)
- drm_fb_helper_remove_one_connector(&dev_priv->fbdev->helper,
- &connector->base);
-#endif
-}
-
static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, const char *pathprop)
{
struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr);
@@ -500,31 +479,32 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
static void intel_dp_register_mst_connector(struct drm_connector *connector)
{
- struct intel_connector *intel_connector = to_intel_connector(connector);
- struct drm_device *dev = connector->dev;
+ struct drm_i915_private *dev_priv = to_i915(connector->dev);
- drm_modeset_lock_all(dev);
- intel_connector_add_to_fbdev(intel_connector);
- drm_modeset_unlock_all(dev);
+ if (dev_priv->fbdev)
+ drm_fb_helper_add_one_connector(&dev_priv->fbdev->helper,
+ connector);
- drm_connector_register(&intel_connector->base);
+ drm_connector_register(connector);
}
static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
struct drm_connector *connector)
{
struct intel_connector *intel_connector = to_intel_connector(connector);
- struct drm_device *dev = connector->dev;
+ struct drm_i915_private *dev_priv = to_i915(connector->dev);
drm_connector_unregister(connector);
- /* need to nuke the connector */
- drm_modeset_lock_all(dev);
- intel_connector_remove_from_fbdev(intel_connector);
+ if (dev_priv->fbdev)
+ drm_fb_helper_remove_one_connector(&dev_priv->fbdev->helper,
+ connector);
+ /* prevent race with the check in ->detect */
+ drm_modeset_lock(&connector->dev->mode_config.connection_mutex, NULL);
intel_connector->mst_port = NULL;
- drm_modeset_unlock_all(dev);
+ drm_modeset_unlock(&connector->dev->mode_config.connection_mutex);
- drm_connector_unreference(&intel_connector->base);
+ drm_connector_unreference(connector);
DRM_DEBUG_KMS("\n");
}
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index 2f7b0e6..a2a3d93 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -2379,6 +2379,15 @@ cnl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
return pll;
}
+static void cnl_dump_hw_state(struct drm_i915_private *dev_priv,
+ struct intel_dpll_hw_state *hw_state)
+{
+ DRM_DEBUG_KMS("dpll_hw_state: "
+ "cfgcr0: 0x%x, cfgcr1: 0x%x\n",
+ hw_state->cfgcr0,
+ hw_state->cfgcr1);
+}
+
static const struct intel_shared_dpll_funcs cnl_ddi_pll_funcs = {
.enable = cnl_ddi_pll_enable,
.disable = cnl_ddi_pll_disable,
@@ -2395,7 +2404,7 @@ static const struct dpll_info cnl_plls[] = {
static const struct intel_dpll_mgr cnl_pll_mgr = {
.dpll_info = cnl_plls,
.get_dpll = cnl_get_dpll,
- .dump_hw_state = skl_dump_hw_state,
+ .dump_hw_state = cnl_dump_hw_state,
};
/**
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d93efb4..fa47285 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -265,6 +265,7 @@ struct intel_encoder {
struct intel_panel {
struct drm_display_mode *fixed_mode;
+ struct drm_display_mode *alt_fixed_mode;
struct drm_display_mode *downclock_mode;
/* backlight */
@@ -780,13 +781,15 @@ struct intel_crtc_state {
/* HDMI High TMDS char rate ratio */
bool hdmi_high_tmds_clock_ratio;
+
+ /* output format is YCBCR 4:2:0 */
+ bool ycbcr420;
};
struct intel_crtc {
struct drm_crtc base;
enum pipe pipe;
enum plane plane;
- u8 lut_r[256], lut_g[256], lut_b[256];
/*
* Whether the crtc and the connected output pipeline is active. Implies
* that crtc->enabled is set, i.e. the current mode configuration has
@@ -797,9 +800,6 @@ struct intel_crtc {
u8 plane_ids_mask;
unsigned long long enabled_power_domains;
struct intel_overlay *overlay;
- struct intel_flip_work *flip_work;
-
- atomic_t unpin_work_count;
/* Display surface base address adjustement for pageflips. Note that on
* gen4+ this only adjusts up to a tile, offsets within a tile are
@@ -1132,24 +1132,6 @@ intel_get_crtc_for_plane(struct drm_i915_private *dev_priv, enum plane plane)
return dev_priv->plane_to_crtc_mapping[plane];
}
-struct intel_flip_work {
- struct work_struct unpin_work;
- struct work_struct mmio_work;
-
- struct drm_crtc *crtc;
- struct i915_vma *old_vma;
- struct drm_framebuffer *old_fb;
- struct drm_i915_gem_object *pending_flip_obj;
- struct drm_pending_vblank_event *event;
- atomic_t pending;
- u32 flip_count;
- u32 gtt_offset;
- struct drm_i915_gem_request *flip_queued_req;
- u32 flip_queued_vblank;
- u32 flip_ready_vblank;
- unsigned int rotation;
-};
-
struct intel_load_detect_pipe {
struct drm_atomic_state *restore_state;
};
@@ -1211,12 +1193,12 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
enum pipe pipe, bool enable);
bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
- enum transcoder pch_transcoder,
+ enum pipe pch_transcoder,
bool enable);
void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
enum pipe pipe);
void intel_pch_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
- enum transcoder pch_transcoder);
+ enum pipe pch_transcoder);
void intel_check_cpu_fifo_underruns(struct drm_i915_private *dev_priv);
void intel_check_pch_fifo_underruns(struct drm_i915_private *dev_priv);
@@ -1251,9 +1233,9 @@ static inline bool intel_irqs_enabled(struct drm_i915_private *dev_priv)
int intel_get_crtc_scanline(struct intel_crtc *crtc);
void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv,
- unsigned int pipe_mask);
+ u8 pipe_mask);
void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv,
- unsigned int pipe_mask);
+ u8 pipe_mask);
void gen9_reset_guc_interrupts(struct drm_i915_private *dev_priv);
void gen9_enable_guc_interrupts(struct drm_i915_private *dev_priv);
void gen9_disable_guc_interrupts(struct drm_i915_private *dev_priv);
@@ -1326,7 +1308,7 @@ void intel_set_cdclk(struct drm_i915_private *dev_priv,
/* intel_display.c */
void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe);
void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe);
-enum transcoder intel_crtc_pch_transcoder(struct intel_crtc *crtc);
+enum pipe intel_crtc_pch_transcoder(struct intel_crtc *crtc);
void intel_update_rawclk(struct drm_i915_private *dev_priv);
int vlv_get_hpll_vco(struct drm_i915_private *dev_priv);
int vlv_get_cck_clock(struct drm_i915_private *dev_priv,
@@ -1335,7 +1317,6 @@ int vlv_get_cck_clock_hpll(struct drm_i915_private *dev_priv,
const char *name, u32 reg);
void lpt_disable_pch_transcoder(struct drm_i915_private *dev_priv);
void lpt_disable_iclkip(struct drm_i915_private *dev_priv);
-extern const struct drm_plane_funcs intel_plane_funcs;
void intel_init_display_hooks(struct drm_i915_private *dev_priv);
unsigned int intel_fb_xy_to_linear(int x, int y,
const struct intel_plane_state *state,
@@ -1408,9 +1389,6 @@ void intel_unpin_fb_vma(struct i915_vma *vma);
struct drm_framebuffer *
intel_framebuffer_create(struct drm_i915_gem_object *obj,
struct drm_mode_fb_cmd2 *mode_cmd);
-void intel_finish_page_flip_cs(struct drm_i915_private *dev_priv, int pipe);
-void intel_finish_page_flip_mmio(struct drm_i915_private *dev_priv, int pipe);
-void intel_check_page_flip(struct drm_i915_private *dev_priv, int pipe);
int intel_prepare_plane_fb(struct drm_plane *plane,
struct drm_plane_state *new_state);
void intel_cleanup_plane_fb(struct drm_plane *plane,
@@ -1597,7 +1575,8 @@ void intel_hpd_poll_init(struct drm_i915_private *dev_priv);
#ifdef CONFIG_DRM_FBDEV_EMULATION
extern int intel_fbdev_init(struct drm_device *dev);
extern void intel_fbdev_initial_config_async(struct drm_device *dev);
-extern void intel_fbdev_fini(struct drm_device *dev);
+extern void intel_fbdev_unregister(struct drm_i915_private *dev_priv);
+extern void intel_fbdev_fini(struct drm_i915_private *dev_priv);
extern void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous);
extern void intel_fbdev_output_poll_changed(struct drm_device *dev);
extern void intel_fbdev_restore_mode(struct drm_device *dev);
@@ -1611,7 +1590,11 @@ static inline void intel_fbdev_initial_config_async(struct drm_device *dev)
{
}
-static inline void intel_fbdev_fini(struct drm_device *dev)
+static inline void intel_fbdev_unregister(struct drm_i915_private *dev_priv)
+{
+}
+
+static inline void intel_fbdev_fini(struct drm_i915_private *dev_priv)
{
}
@@ -1696,6 +1679,7 @@ void intel_overlay_reset(struct drm_i915_private *dev_priv);
/* intel_panel.c */
int intel_panel_init(struct intel_panel *panel,
struct drm_display_mode *fixed_mode,
+ struct drm_display_mode *alt_fixed_mode,
struct drm_display_mode *downclock_mode);
void intel_panel_fini(struct intel_panel *panel);
void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
@@ -1858,9 +1842,8 @@ void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv);
void gen6_rps_busy(struct drm_i915_private *dev_priv);
void gen6_rps_reset_ei(struct drm_i915_private *dev_priv);
void gen6_rps_idle(struct drm_i915_private *dev_priv);
-void gen6_rps_boost(struct drm_i915_private *dev_priv,
- struct intel_rps_client *rps,
- unsigned long submitted);
+void gen6_rps_boost(struct drm_i915_gem_request *rq,
+ struct intel_rps_client *rps);
void intel_queue_rps_boost_for_request(struct drm_i915_gem_request *req);
void g4x_wm_get_hw_state(struct drm_device *dev);
void vlv_wm_get_hw_state(struct drm_device *dev);
@@ -1902,7 +1885,7 @@ struct intel_plane *intel_sprite_plane_create(struct drm_i915_private *dev_priv,
int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
struct drm_file *file_priv);
void intel_pipe_update_start(struct intel_crtc *crtc);
-void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work);
+void intel_pipe_update_end(struct intel_crtc *crtc);
/* intel_tv.c */
void intel_tv_init(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 50ec836..f0c11ae 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -1653,12 +1653,10 @@ static const struct drm_connector_helper_funcs intel_dsi_connector_helper_funcs
};
static const struct drm_connector_funcs intel_dsi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.late_register = intel_connector_register,
.early_unregister = intel_connector_unregister,
.destroy = intel_dsi_connector_destroy,
.fill_modes = drm_helper_probe_single_connector_modes,
- .set_property = drm_atomic_helper_connector_set_property,
.atomic_get_property = intel_digital_connector_atomic_get_property,
.atomic_set_property = intel_digital_connector_atomic_set_property,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
@@ -1851,7 +1849,7 @@ void intel_dsi_init(struct drm_i915_private *dev_priv)
connector->display_info.width_mm = fixed_mode->width_mm;
connector->display_info.height_mm = fixed_mode->height_mm;
- intel_panel_init(&intel_connector->panel, fixed_mode, NULL);
+ intel_panel_init(&intel_connector->panel, fixed_mode, NULL, NULL);
intel_panel_setup_backlight(connector, INVALID_PIPE);
intel_dsi_add_properties(intel_connector);
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
index c1544a5..c0a0272 100644
--- a/drivers/gpu/drm/i915/intel_dvo.c
+++ b/drivers/gpu/drm/i915/intel_dvo.c
@@ -344,13 +344,11 @@ static void intel_dvo_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs intel_dvo_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = intel_dvo_detect,
.late_register = intel_connector_register,
.early_unregister = intel_connector_unregister,
.destroy = intel_dvo_destroy,
.fill_modes = drm_helper_probe_single_connector_modes,
- .set_property = drm_atomic_helper_connector_set_property,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
};
@@ -554,7 +552,7 @@ void intel_dvo_init(struct drm_i915_private *dev_priv)
*/
intel_panel_init(&intel_connector->panel,
intel_dvo_get_current_mode(connector),
- NULL);
+ NULL, NULL);
intel_dvo->panel_wants_dither = true;
}
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
index 5b4de71..9ab5969 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -149,6 +149,7 @@ __intel_engine_context_size(struct drm_i915_private *dev_priv, u8 class)
switch (INTEL_GEN(dev_priv)) {
default:
MISSING_CASE(INTEL_GEN(dev_priv));
+ case 10:
case 9:
return GEN9_LR_CONTEXT_RENDER_SIZE;
case 8:
@@ -291,11 +292,9 @@ cleanup:
*/
int intel_engines_init(struct drm_i915_private *dev_priv)
{
- struct intel_device_info *device_info = mkwrite_device_info(dev_priv);
struct intel_engine_cs *engine;
enum intel_engine_id id, err_id;
- unsigned int mask = 0;
- int err = 0;
+ int err;
for_each_engine(engine, dev_priv, id) {
const struct engine_class_info *class_info =
@@ -306,40 +305,30 @@ int intel_engines_init(struct drm_i915_private *dev_priv)
init = class_info->init_execlists;
else
init = class_info->init_legacy;
- if (!init) {
- kfree(engine);
- dev_priv->engine[id] = NULL;
- continue;
- }
+
+ err = -EINVAL;
+ err_id = id;
+
+ if (GEM_WARN_ON(!init))
+ goto cleanup;
err = init(engine);
- if (err) {
- err_id = id;
+ if (err)
goto cleanup;
- }
GEM_BUG_ON(!engine->submit_request);
- mask |= ENGINE_MASK(id);
}
- /*
- * Catch failures to update intel_engines table when the new engines
- * are added to the driver by a warning and disabling the forgotten
- * engines.
- */
- if (WARN_ON(mask != INTEL_INFO(dev_priv)->ring_mask))
- device_info->ring_mask = mask;
-
- device_info->num_rings = hweight32(mask);
-
return 0;
cleanup:
for_each_engine(engine, dev_priv, id) {
- if (id >= err_id)
+ if (id >= err_id) {
kfree(engine);
- else
+ dev_priv->engine[id] = NULL;
+ } else {
dev_priv->gt.cleanup_engine(engine);
+ }
}
return err;
}
@@ -348,9 +337,6 @@ void intel_engine_init_global_seqno(struct intel_engine_cs *engine, u32 seqno)
{
struct drm_i915_private *dev_priv = engine->i915;
- GEM_BUG_ON(!intel_engine_is_idle(engine));
- GEM_BUG_ON(i915_gem_active_isset(&engine->timeline->last_request));
-
/* Our semaphore implementation is strictly monotonic (i.e. we proceed
* so long as the semaphore value in the register/page is greater
* than the sync value), so whenever we reset the seqno,
@@ -1294,6 +1280,10 @@ bool intel_engine_is_idle(struct intel_engine_cs *engine)
if (port_request(&engine->execlist_port[0]))
return false;
+ /* ELSP is empty, but there are ready requests? */
+ if (READ_ONCE(engine->execlist_first))
+ return false;
+
/* Ring stopped? */
if (!ring_is_idle(engine))
return false;
@@ -1340,6 +1330,7 @@ void intel_engines_mark_idle(struct drm_i915_private *i915)
for_each_engine(engine, i915, id) {
intel_engine_disarm_breadcrumbs(engine);
i915_gem_batch_pool_fini(&engine->batch_pool);
+ tasklet_kill(&engine->irq_tasklet);
engine->no_priolist = false;
}
}
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index 860b8c2..3fca9fa 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -461,6 +461,8 @@ static void intel_fbc_schedule_activation(struct intel_crtc *crtc)
struct intel_fbc_work *work = &fbc->work;
WARN_ON(!mutex_is_locked(&fbc->lock));
+ if (WARN_ON(!fbc->enabled))
+ return;
if (drm_crtc_vblank_get(&crtc->base)) {
DRM_ERROR("vblank not available for FBC on pipe %c\n",
@@ -1216,7 +1218,7 @@ static void intel_fbc_underrun_work_fn(struct work_struct *work)
mutex_lock(&fbc->lock);
/* Maybe we were scheduled twice. */
- if (fbc->underrun_detected)
+ if (fbc->underrun_detected || !fbc->enabled)
goto out;
DRM_DEBUG_KMS("Disabling FBC due to FIFO underrun.\n");
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c
index 0c4cde6..262e75c 100644
--- a/drivers/gpu/drm/i915/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/intel_fbdev.c
@@ -232,7 +232,6 @@ static int intelfb_create(struct drm_fb_helper *helper,
strcpy(info->fix.id, "inteldrmfb");
- info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
info->fbops = &intelfb_ops;
/* setup aperture base/size for vesafb takeover */
@@ -281,27 +280,6 @@ out_unlock:
return ret;
}
-/** Sets the color ramps on behalf of RandR */
-static void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno)
-{
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-
- intel_crtc->lut_r[regno] = red >> 8;
- intel_crtc->lut_g[regno] = green >> 8;
- intel_crtc->lut_b[regno] = blue >> 8;
-}
-
-static void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
- u16 *blue, int regno)
-{
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-
- *red = intel_crtc->lut_r[regno] << 8;
- *green = intel_crtc->lut_g[regno] << 8;
- *blue = intel_crtc->lut_b[regno] << 8;
-}
-
static struct drm_fb_helper_crtc *
intel_fb_helper_crtc(struct drm_fb_helper *fb_helper, struct drm_crtc *crtc)
{
@@ -352,14 +330,20 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,
unsigned int count = min(fb_helper->connector_count, BITS_PER_LONG);
int i, j;
bool *save_enabled;
- bool fallback = true;
+ bool fallback = true, ret = true;
int num_connectors_enabled = 0;
int num_connectors_detected = 0;
+ struct drm_modeset_acquire_ctx ctx;
save_enabled = kcalloc(count, sizeof(bool), GFP_KERNEL);
if (!save_enabled)
return false;
+ drm_modeset_acquire_init(&ctx, 0);
+
+ while (drm_modeset_lock_all_ctx(fb_helper->dev, &ctx) != 0)
+ drm_modeset_backoff(&ctx);
+
memcpy(save_enabled, enabled, count);
mask = GENMASK(count - 1, 0);
conn_configured = 0;
@@ -370,7 +354,6 @@ retry:
struct drm_connector *connector;
struct drm_encoder *encoder;
struct drm_fb_helper_crtc *new_crtc;
- struct intel_crtc *intel_crtc;
fb_conn = fb_helper->connector_info[i];
connector = fb_conn->connector;
@@ -412,13 +395,6 @@ retry:
num_connectors_enabled++;
- intel_crtc = to_intel_crtc(connector->state->crtc);
- for (j = 0; j < 256; j++) {
- intel_crtc->lut_r[j] = j;
- intel_crtc->lut_g[j] = j;
- intel_crtc->lut_b[j] = j;
- }
-
new_crtc = intel_fb_helper_crtc(fb_helper,
connector->state->crtc);
@@ -509,18 +485,18 @@ retry:
bail:
DRM_DEBUG_KMS("Not using firmware configuration\n");
memcpy(enabled, save_enabled, count);
- kfree(save_enabled);
- return false;
+ ret = false;
}
+ drm_modeset_drop_locks(&ctx);
+ drm_modeset_acquire_fini(&ctx);
+
kfree(save_enabled);
- return true;
+ return ret;
}
static const struct drm_fb_helper_funcs intel_fb_helper_funcs = {
.initial_config = intel_fb_initial_config,
- .gamma_set = intel_crtc_fb_gamma_set,
- .gamma_get = intel_crtc_fb_gamma_get,
.fb_probe = intelfb_create,
};
@@ -531,8 +507,6 @@ static void intel_fbdev_destroy(struct intel_fbdev *ifbdev)
* trying to rectify all the possible error paths leading here.
*/
- drm_fb_helper_unregister_fbi(&ifbdev->helper);
-
drm_fb_helper_fini(&ifbdev->helper);
if (ifbdev->vma) {
@@ -720,8 +694,10 @@ static void intel_fbdev_initial_config(void *data, async_cookie_t cookie)
/* Due to peculiar init order wrt to hpd handling this is separate. */
if (drm_fb_helper_initial_config(&ifbdev->helper,
- ifbdev->preferred_bpp))
- intel_fbdev_fini(ifbdev->helper.dev);
+ ifbdev->preferred_bpp)) {
+ intel_fbdev_unregister(to_i915(ifbdev->helper.dev));
+ intel_fbdev_fini(to_i915(ifbdev->helper.dev));
+ }
}
void intel_fbdev_initial_config_async(struct drm_device *dev)
@@ -744,9 +720,8 @@ static void intel_fbdev_sync(struct intel_fbdev *ifbdev)
ifbdev->cookie = 0;
}
-void intel_fbdev_fini(struct drm_device *dev)
+void intel_fbdev_unregister(struct drm_i915_private *dev_priv)
{
- struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_fbdev *ifbdev = dev_priv->fbdev;
if (!ifbdev)
@@ -756,8 +731,17 @@ void intel_fbdev_fini(struct drm_device *dev)
if (!current_is_async())
intel_fbdev_sync(ifbdev);
+ drm_fb_helper_unregister_fbi(&ifbdev->helper);
+}
+
+void intel_fbdev_fini(struct drm_i915_private *dev_priv)
+{
+ struct intel_fbdev *ifbdev = fetch_and_zero(&dev_priv->fbdev);
+
+ if (!ifbdev)
+ return;
+
intel_fbdev_destroy(ifbdev);
- dev_priv->fbdev = NULL;
}
void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous)
@@ -813,7 +797,7 @@ void intel_fbdev_output_poll_changed(struct drm_device *dev)
{
struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;
- if (ifbdev && ifbdev->vma)
+ if (ifbdev)
drm_fb_helper_hotplug_event(&ifbdev->helper);
}
diff --git a/drivers/gpu/drm/i915/intel_fifo_underrun.c b/drivers/gpu/drm/i915/intel_fifo_underrun.c
index d484862..5a7cca3 100644
--- a/drivers/gpu/drm/i915/intel_fifo_underrun.c
+++ b/drivers/gpu/drm/i915/intel_fifo_underrun.c
@@ -313,11 +313,11 @@ bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
* Returns the previous state of underrun reporting.
*/
bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
- enum transcoder pch_transcoder,
+ enum pipe pch_transcoder,
bool enable)
{
struct intel_crtc *crtc =
- intel_get_crtc_for_pipe(dev_priv, (enum pipe) pch_transcoder);
+ intel_get_crtc_for_pipe(dev_priv, pch_transcoder);
unsigned long flags;
bool old;
@@ -390,7 +390,7 @@ void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
* interrupt to avoid an irq storm.
*/
void intel_pch_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
- enum transcoder pch_transcoder)
+ enum pipe pch_transcoder)
{
if (intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder,
false)) {
diff --git a/drivers/gpu/drm/i915/intel_hangcheck.c b/drivers/gpu/drm/i915/intel_hangcheck.c
index 9b0ece4..d9d87d9 100644
--- a/drivers/gpu/drm/i915/intel_hangcheck.c
+++ b/drivers/gpu/drm/i915/intel_hangcheck.c
@@ -324,7 +324,7 @@ hangcheck_get_action(struct intel_engine_cs *engine,
if (engine->hangcheck.seqno != hc->seqno)
return ENGINE_ACTIVE_SEQNO;
- if (i915_seqno_passed(hc->seqno, intel_engine_last_submit(engine)))
+ if (intel_engine_is_idle(engine))
return ENGINE_IDLE;
return engine_stuck(engine, hc->acthd);
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index ec0779a..e8abea7 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -459,22 +459,31 @@ static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
const struct drm_display_mode *adjusted_mode =
&crtc_state->base.adjusted_mode;
+ struct drm_connector *connector = &intel_hdmi->attached_connector->base;
+ bool is_hdmi2_sink = connector->display_info.hdmi.scdc.supported;
union hdmi_infoframe frame;
int ret;
ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
- adjusted_mode);
+ adjusted_mode,
+ is_hdmi2_sink);
if (ret < 0) {
DRM_ERROR("couldn't fill AVI infoframe\n");
return;
}
+ if (crtc_state->ycbcr420)
+ frame.avi.colorspace = HDMI_COLORSPACE_YUV420;
+ else
+ frame.avi.colorspace = HDMI_COLORSPACE_RGB;
+
drm_hdmi_avi_infoframe_quant_range(&frame.avi, adjusted_mode,
crtc_state->limited_color_range ?
HDMI_QUANTIZATION_RANGE_LIMITED :
HDMI_QUANTIZATION_RANGE_FULL,
intel_hdmi->rgb_quant_range_selectable);
+ /* TODO: handle pixel repetition for YCBCR420 outputs */
intel_write_infoframe(encoder, crtc_state, &frame);
}
@@ -1292,6 +1301,9 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
clock *= 2;
+ if (drm_mode_is_420_only(&connector->display_info, mode))
+ clock /= 2;
+
/* check if we can do 8bpc */
status = hdmi_port_clock_valid(hdmi, clock, true, force_dvi);
@@ -1321,14 +1333,21 @@ static bool hdmi_12bpc_possible(struct intel_crtc_state *crtc_state)
if (crtc_state->output_types != 1 << INTEL_OUTPUT_HDMI)
return false;
- for_each_connector_in_state(state, connector, connector_state, i) {
+ for_each_new_connector_in_state(state, connector, connector_state, i) {
const struct drm_display_info *info = &connector->display_info;
if (connector_state->crtc != crtc_state->base.crtc)
continue;
- if ((info->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_36) == 0)
- return false;
+ if (crtc_state->ycbcr420) {
+ const struct drm_hdmi_info *hdmi = &info->hdmi;
+
+ if (!(hdmi->y420_dc_modes & DRM_EDID_YCBCR420_DC_36))
+ return false;
+ } else {
+ if (!(info->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_36))
+ return false;
+ }
}
/* Display Wa #1139 */
@@ -1339,6 +1358,36 @@ static bool hdmi_12bpc_possible(struct intel_crtc_state *crtc_state)
return true;
}
+static bool
+intel_hdmi_ycbcr420_config(struct drm_connector *connector,
+ struct intel_crtc_state *config,
+ int *clock_12bpc, int *clock_8bpc)
+{
+ struct intel_crtc *intel_crtc = to_intel_crtc(config->base.crtc);
+
+ if (!connector->ycbcr_420_allowed) {
+ DRM_ERROR("Platform doesn't support YCBCR420 output\n");
+ return false;
+ }
+
+ /* YCBCR420 TMDS rate requirement is half the pixel clock */
+ config->port_clock /= 2;
+ *clock_12bpc /= 2;
+ *clock_8bpc /= 2;
+ config->ycbcr420 = true;
+
+ /* YCBCR 420 output conversion needs a scaler */
+ if (skl_update_scaler_crtc(config)) {
+ DRM_DEBUG_KMS("Scaler allocation for output failed\n");
+ return false;
+ }
+
+ intel_pch_panel_fitting(intel_crtc, config,
+ DRM_MODE_SCALE_FULLSCREEN);
+
+ return true;
+}
+
bool intel_hdmi_compute_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config,
struct drm_connector_state *conn_state)
@@ -1346,7 +1395,8 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
- struct drm_scdc *scdc = &conn_state->connector->display_info.hdmi.scdc;
+ struct drm_connector *connector = conn_state->connector;
+ struct drm_scdc *scdc = &connector->display_info.hdmi.scdc;
struct intel_digital_connector_state *intel_conn_state =
to_intel_digital_connector_state(conn_state);
int clock_8bpc = pipe_config->base.adjusted_mode.crtc_clock;
@@ -1376,6 +1426,14 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
clock_12bpc *= 2;
}
+ if (drm_mode_is_420_only(&connector->display_info, adjusted_mode)) {
+ if (!intel_hdmi_ycbcr420_config(connector, pipe_config,
+ &clock_12bpc, &clock_8bpc)) {
+ DRM_ERROR("Can't support YCBCR420 output\n");
+ return false;
+ }
+ }
+
if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv))
pipe_config->has_pch_encoder = true;
@@ -1703,11 +1761,9 @@ static void intel_hdmi_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs intel_hdmi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = intel_hdmi_detect,
.force = intel_hdmi_force,
.fill_modes = drm_helper_probe_single_connector_modes,
- .set_property = drm_atomic_helper_connector_set_property,
.atomic_get_property = intel_digital_connector_atomic_get_property,
.atomic_set_property = intel_digital_connector_atomic_set_property,
.late_register = intel_connector_register,
@@ -1787,45 +1843,114 @@ void intel_hdmi_handle_sink_scrambling(struct intel_encoder *encoder,
DRM_DEBUG_KMS("sink scrambling handled\n");
}
-static u8 intel_hdmi_ddc_pin(struct drm_i915_private *dev_priv,
- enum port port)
+static u8 chv_port_to_ddc_pin(struct drm_i915_private *dev_priv, enum port port)
{
- const struct ddi_vbt_port_info *info =
- &dev_priv->vbt.ddi_port_info[port];
u8 ddc_pin;
- if (info->alternate_ddc_pin) {
- DRM_DEBUG_KMS("Using DDC pin 0x%x for port %c (VBT)\n",
- info->alternate_ddc_pin, port_name(port));
- return info->alternate_ddc_pin;
+ switch (port) {
+ case PORT_B:
+ ddc_pin = GMBUS_PIN_DPB;
+ break;
+ case PORT_C:
+ ddc_pin = GMBUS_PIN_DPC;
+ break;
+ case PORT_D:
+ ddc_pin = GMBUS_PIN_DPD_CHV;
+ break;
+ default:
+ MISSING_CASE(port);
+ ddc_pin = GMBUS_PIN_DPB;
+ break;
}
+ return ddc_pin;
+}
+
+static u8 bxt_port_to_ddc_pin(struct drm_i915_private *dev_priv, enum port port)
+{
+ u8 ddc_pin;
switch (port) {
case PORT_B:
- if (IS_GEN9_LP(dev_priv) || HAS_PCH_CNP(dev_priv))
- ddc_pin = GMBUS_PIN_1_BXT;
- else
- ddc_pin = GMBUS_PIN_DPB;
+ ddc_pin = GMBUS_PIN_1_BXT;
break;
case PORT_C:
- if (IS_GEN9_LP(dev_priv) || HAS_PCH_CNP(dev_priv))
- ddc_pin = GMBUS_PIN_2_BXT;
- else
- ddc_pin = GMBUS_PIN_DPC;
+ ddc_pin = GMBUS_PIN_2_BXT;
+ break;
+ default:
+ MISSING_CASE(port);
+ ddc_pin = GMBUS_PIN_1_BXT;
+ break;
+ }
+ return ddc_pin;
+}
+
+static u8 cnp_port_to_ddc_pin(struct drm_i915_private *dev_priv,
+ enum port port)
+{
+ u8 ddc_pin;
+
+ switch (port) {
+ case PORT_B:
+ ddc_pin = GMBUS_PIN_1_BXT;
+ break;
+ case PORT_C:
+ ddc_pin = GMBUS_PIN_2_BXT;
break;
case PORT_D:
- if (HAS_PCH_CNP(dev_priv))
- ddc_pin = GMBUS_PIN_4_CNP;
- else if (IS_CHERRYVIEW(dev_priv))
- ddc_pin = GMBUS_PIN_DPD_CHV;
- else
- ddc_pin = GMBUS_PIN_DPD;
+ ddc_pin = GMBUS_PIN_4_CNP;
+ break;
+ default:
+ MISSING_CASE(port);
+ ddc_pin = GMBUS_PIN_1_BXT;
+ break;
+ }
+ return ddc_pin;
+}
+
+static u8 g4x_port_to_ddc_pin(struct drm_i915_private *dev_priv,
+ enum port port)
+{
+ u8 ddc_pin;
+
+ switch (port) {
+ case PORT_B:
+ ddc_pin = GMBUS_PIN_DPB;
+ break;
+ case PORT_C:
+ ddc_pin = GMBUS_PIN_DPC;
+ break;
+ case PORT_D:
+ ddc_pin = GMBUS_PIN_DPD;
break;
default:
MISSING_CASE(port);
ddc_pin = GMBUS_PIN_DPB;
break;
}
+ return ddc_pin;
+}
+
+static u8 intel_hdmi_ddc_pin(struct drm_i915_private *dev_priv,
+ enum port port)
+{
+ const struct ddi_vbt_port_info *info =
+ &dev_priv->vbt.ddi_port_info[port];
+ u8 ddc_pin;
+
+ if (info->alternate_ddc_pin) {
+ DRM_DEBUG_KMS("Using DDC pin 0x%x for port %c (VBT)\n",
+ info->alternate_ddc_pin, port_name(port));
+ return info->alternate_ddc_pin;
+ }
+
+ if (IS_CHERRYVIEW(dev_priv))
+ ddc_pin = chv_port_to_ddc_pin(dev_priv, port);
+ else if (IS_GEN9_LP(dev_priv))
+ ddc_pin = bxt_port_to_ddc_pin(dev_priv, port);
+ else if (HAS_PCH_CNP(dev_priv))
+ ddc_pin = cnp_port_to_ddc_pin(dev_priv, port);
+ else
+ ddc_pin = g4x_port_to_ddc_pin(dev_priv, port);
DRM_DEBUG_KMS("Using DDC pin 0x%x for port %c (platform default)\n",
ddc_pin, port_name(port));
@@ -1859,25 +1984,14 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
connector->doublescan_allowed = 0;
connector->stereo_allowed = 1;
+ if (IS_GEMINILAKE(dev_priv))
+ connector->ycbcr_420_allowed = true;
+
intel_hdmi->ddc_bus = intel_hdmi_ddc_pin(dev_priv, port);
- switch (port) {
- case PORT_B:
- intel_encoder->hpd_pin = HPD_PORT_B;
- break;
- case PORT_C:
- intel_encoder->hpd_pin = HPD_PORT_C;
- break;
- case PORT_D:
- intel_encoder->hpd_pin = HPD_PORT_D;
- break;
- case PORT_E:
- intel_encoder->hpd_pin = HPD_PORT_E;
- break;
- default:
- MISSING_CASE(port);
+ if (WARN_ON(port == PORT_A))
return;
- }
+ intel_encoder->hpd_pin = intel_hpd_pin(port);
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
intel_hdmi->write_infoframe = vlv_write_infoframe;
diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
index f120027..875d5d2 100644
--- a/drivers/gpu/drm/i915/intel_hotplug.c
+++ b/drivers/gpu/drm/i915/intel_hotplug.c
@@ -76,26 +76,54 @@
* it will use i915_hotplug_work_func where this logic is handled.
*/
-bool intel_hpd_pin_to_port(enum hpd_pin pin, enum port *port)
+/**
+ * intel_hpd_port - return port hard associated with certain pin.
+ * @pin: the hpd pin to get associated port
+ *
+ * Return port that is associatade with @pin and PORT_NONE if no port is
+ * hard associated with that @pin.
+ */
+enum port intel_hpd_pin_to_port(enum hpd_pin pin)
{
switch (pin) {
case HPD_PORT_A:
- *port = PORT_A;
- return true;
+ return PORT_A;
case HPD_PORT_B:
- *port = PORT_B;
- return true;
+ return PORT_B;
case HPD_PORT_C:
- *port = PORT_C;
- return true;
+ return PORT_C;
case HPD_PORT_D:
- *port = PORT_D;
- return true;
+ return PORT_D;
case HPD_PORT_E:
- *port = PORT_E;
- return true;
+ return PORT_E;
+ default:
+ return PORT_NONE; /* no port for this pin */
+ }
+}
+
+/**
+ * intel_hpd_pin - return pin hard associated with certain port.
+ * @port: the hpd port to get associated pin
+ *
+ * Return pin that is associatade with @port and HDP_NONE if no pin is
+ * hard associated with that @port.
+ */
+enum hpd_pin intel_hpd_pin(enum port port)
+{
+ switch (port) {
+ case PORT_A:
+ return HPD_PORT_A;
+ case PORT_B:
+ return HPD_PORT_B;
+ case PORT_C:
+ return HPD_PORT_C;
+ case PORT_D:
+ return HPD_PORT_D;
+ case PORT_E:
+ return HPD_PORT_E;
default:
- return false; /* no hpd */
+ MISSING_CASE(port);
+ return HPD_NONE;
}
}
@@ -389,8 +417,9 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv,
if (!(BIT(i) & pin_mask))
continue;
- is_dig_port = intel_hpd_pin_to_port(i, &port) &&
- dev_priv->hotplug.irq_port[port];
+ port = intel_hpd_pin_to_port(i);
+ is_dig_port = port != PORT_NONE &&
+ dev_priv->hotplug.irq_port[port];
if (is_dig_port) {
bool long_hpd = long_mask & BIT(i);
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index 3c9e00d..6698826 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -592,7 +592,6 @@ gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
int ret;
intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
- mutex_lock(&dev_priv->gmbus_mutex);
if (bus->force_bit) {
ret = i2c_bit_algo.master_xfer(adapter, msgs, num);
@@ -604,7 +603,6 @@ gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
bus->force_bit |= GMBUS_FORCE_BIT_RETRY;
}
- mutex_unlock(&dev_priv->gmbus_mutex);
intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
return ret;
@@ -624,6 +622,39 @@ static const struct i2c_algorithm gmbus_algorithm = {
.functionality = gmbus_func
};
+static void gmbus_lock_bus(struct i2c_adapter *adapter,
+ unsigned int flags)
+{
+ struct intel_gmbus *bus = to_intel_gmbus(adapter);
+ struct drm_i915_private *dev_priv = bus->dev_priv;
+
+ mutex_lock(&dev_priv->gmbus_mutex);
+}
+
+static int gmbus_trylock_bus(struct i2c_adapter *adapter,
+ unsigned int flags)
+{
+ struct intel_gmbus *bus = to_intel_gmbus(adapter);
+ struct drm_i915_private *dev_priv = bus->dev_priv;
+
+ return mutex_trylock(&dev_priv->gmbus_mutex);
+}
+
+static void gmbus_unlock_bus(struct i2c_adapter *adapter,
+ unsigned int flags)
+{
+ struct intel_gmbus *bus = to_intel_gmbus(adapter);
+ struct drm_i915_private *dev_priv = bus->dev_priv;
+
+ mutex_unlock(&dev_priv->gmbus_mutex);
+}
+
+const struct i2c_lock_operations gmbus_lock_ops = {
+ .lock_bus = gmbus_lock_bus,
+ .trylock_bus = gmbus_trylock_bus,
+ .unlock_bus = gmbus_unlock_bus,
+};
+
/**
* intel_gmbus_setup - instantiate all Intel i2c GMBuses
* @dev_priv: i915 device private
@@ -665,6 +696,7 @@ int intel_setup_gmbus(struct drm_i915_private *dev_priv)
bus->dev_priv = dev_priv;
bus->adapter.algo = &gmbus_algorithm;
+ bus->adapter.lock_ops = &gmbus_lock_ops;
/*
* We wish to retry with bit banging
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 2afa4da..6f972e6 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -1327,6 +1327,31 @@ static void reset_common_ring(struct intel_engine_cs *engine,
{
struct execlist_port *port = engine->execlist_port;
struct intel_context *ce;
+ unsigned int n;
+
+ /*
+ * Catch up with any missed context-switch interrupts.
+ *
+ * Ideally we would just read the remaining CSB entries now that we
+ * know the gpu is idle. However, the CSB registers are sometimes^W
+ * often trashed across a GPU reset! Instead we have to rely on
+ * guessing the missed context-switch events by looking at what
+ * requests were completed.
+ */
+ if (!request) {
+ for (n = 0; n < ARRAY_SIZE(engine->execlist_port); n++)
+ i915_gem_request_put(port_request(&port[n]));
+ memset(engine->execlist_port, 0, sizeof(engine->execlist_port));
+ return;
+ }
+
+ if (request->ctx != port_request(port)->ctx) {
+ i915_gem_request_put(port_request(port));
+ port[0] = port[1];
+ memset(&port[1], 0, sizeof(port[1]));
+ }
+
+ GEM_BUG_ON(request->ctx != port_request(port)->ctx);
/* If the request was innocent, we leave the request in the ELSP
* and will try to replay it on restarting. The context image may
@@ -1338,7 +1363,7 @@ static void reset_common_ring(struct intel_engine_cs *engine,
* and have to at least restore the RING register in the context
* image back to the expected values to skip over the guilty request.
*/
- if (!request || request->fence.error != -EIO)
+ if (request->fence.error != -EIO)
return;
/* We want a simple context + ring to execute the breadcrumb update.
@@ -1360,15 +1385,6 @@ static void reset_common_ring(struct intel_engine_cs *engine,
request->ring->head = request->postfix;
intel_ring_update_space(request->ring);
- /* Catch up with any missed context-switch interrupts */
- if (request->ctx != port_request(port)->ctx) {
- i915_gem_request_put(port_request(port));
- port[0] = port[1];
- memset(&port[1], 0, sizeof(port[1]));
- }
-
- GEM_BUG_ON(request->ctx != port_request(port)->ctx);
-
/* Reset WaIdleLiteRestore:bdw,skl as well */
request->tail =
intel_ring_wrap(request->ring,
@@ -2092,7 +2108,7 @@ void intel_lr_context_resume(struct drm_i915_private *dev_priv)
* So to avoid that we reset the context images upon resume. For
* simplicity, we just zero everything out.
*/
- list_for_each_entry(ctx, &dev_priv->context_list, link) {
+ list_for_each_entry(ctx, &dev_priv->contexts.list, link) {
for_each_engine(engine, dev_priv, id) {
struct intel_context *ce = &ctx->engine[engine->id];
u32 *reg;
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 6fe5d7c..8e21577 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -595,10 +595,8 @@ static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs
};
static const struct drm_connector_funcs intel_lvds_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = intel_lvds_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
- .set_property = drm_atomic_helper_connector_set_property,
.atomic_get_property = intel_digital_connector_atomic_get_property,
.atomic_set_property = intel_digital_connector_atomic_set_property,
.late_register = intel_connector_register,
@@ -1140,7 +1138,8 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
out:
mutex_unlock(&dev->mode_config.mutex);
- intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode);
+ intel_panel_init(&intel_connector->panel, fixed_mode, NULL,
+ downclock_mode);
intel_panel_setup_backlight(connector, INVALID_PIPE);
lvds_encoder->is_dual_link = compute_is_dual_link_lvds(lvds_encoder);
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
index 2bd0300..98154ef 100644
--- a/drivers/gpu/drm/i915/intel_opregion.c
+++ b/drivers/gpu/drm/i915/intel_opregion.c
@@ -27,6 +27,7 @@
#include <linux/acpi.h>
#include <linux/dmi.h>
+#include <linux/firmware.h>
#include <acpi/video.h>
#include <drm/drmP.h>
@@ -829,6 +830,10 @@ void intel_opregion_unregister(struct drm_i915_private *dev_priv)
memunmap(opregion->rvda);
opregion->rvda = NULL;
}
+ if (opregion->vbt_firmware) {
+ kfree(opregion->vbt_firmware);
+ opregion->vbt_firmware = NULL;
+ }
opregion->header = NULL;
opregion->acpi = NULL;
opregion->swsci = NULL;
@@ -912,6 +917,43 @@ static const struct dmi_system_id intel_no_opregion_vbt[] = {
{ }
};
+static int intel_load_vbt_firmware(struct drm_i915_private *dev_priv)
+{
+ struct intel_opregion *opregion = &dev_priv->opregion;
+ const struct firmware *fw = NULL;
+ const char *name = i915.vbt_firmware;
+ int ret;
+
+ if (!name || !*name)
+ return -ENOENT;
+
+ ret = request_firmware(&fw, name, &dev_priv->drm.pdev->dev);
+ if (ret) {
+ DRM_ERROR("Requesting VBT firmware \"%s\" failed (%d)\n",
+ name, ret);
+ return ret;
+ }
+
+ if (intel_bios_is_valid_vbt(fw->data, fw->size)) {
+ opregion->vbt_firmware = kmemdup(fw->data, fw->size, GFP_KERNEL);
+ if (opregion->vbt_firmware) {
+ DRM_DEBUG_KMS("Found valid VBT firmware \"%s\"\n", name);
+ opregion->vbt = opregion->vbt_firmware;
+ opregion->vbt_size = fw->size;
+ ret = 0;
+ } else {
+ ret = -ENOMEM;
+ }
+ } else {
+ DRM_DEBUG_KMS("Invalid VBT firmware \"%s\"\n", name);
+ ret = -EINVAL;
+ }
+
+ release_firmware(fw);
+
+ return ret;
+}
+
int intel_opregion_setup(struct drm_i915_private *dev_priv)
{
struct intel_opregion *opregion = &dev_priv->opregion;
@@ -974,6 +1016,9 @@ int intel_opregion_setup(struct drm_i915_private *dev_priv)
if (mboxes & MBOX_ASLE_EXT)
DRM_DEBUG_DRIVER("ASLE extension supported\n");
+ if (intel_load_vbt_firmware(dev_priv) == 0)
+ goto out;
+
if (dmi_check_system(intel_no_opregion_vbt))
goto out;
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index b96aed9..aace22e 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -799,9 +799,13 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
if (ret != 0)
return ret;
+ atomic_inc(&dev_priv->gpu_error.pending_fb_pin);
+
vma = i915_gem_object_pin_to_display_plane(new_bo, 0, NULL);
- if (IS_ERR(vma))
- return PTR_ERR(vma);
+ if (IS_ERR(vma)) {
+ ret = PTR_ERR(vma);
+ goto out_pin_section;
+ }
ret = i915_vma_put_fence(vma);
if (ret)
@@ -886,6 +890,9 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
out_unpin:
i915_gem_object_unpin_from_display_plane(vma);
+out_pin_section:
+ atomic_dec(&dev_priv->gpu_error.pending_fb_pin);
+
return ret;
}
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 593349b..a17b1de 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -110,7 +110,8 @@ intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
/* Native modes don't need fitting */
if (adjusted_mode->crtc_hdisplay == pipe_config->pipe_src_w &&
- adjusted_mode->crtc_vdisplay == pipe_config->pipe_src_h)
+ adjusted_mode->crtc_vdisplay == pipe_config->pipe_src_h &&
+ !pipe_config->ycbcr420)
goto done;
switch (fitting_mode) {
@@ -1919,11 +1920,13 @@ intel_panel_init_backlight_funcs(struct intel_panel *panel)
int intel_panel_init(struct intel_panel *panel,
struct drm_display_mode *fixed_mode,
+ struct drm_display_mode *alt_fixed_mode,
struct drm_display_mode *downclock_mode)
{
intel_panel_init_backlight_funcs(panel);
panel->fixed_mode = fixed_mode;
+ panel->alt_fixed_mode = alt_fixed_mode;
panel->downclock_mode = downclock_mode;
return 0;
@@ -1937,6 +1940,10 @@ void intel_panel_fini(struct intel_panel *panel)
if (panel->fixed_mode)
drm_mode_destroy(intel_connector->base.dev, panel->fixed_mode);
+ if (panel->alt_fixed_mode)
+ drm_mode_destroy(intel_connector->base.dev,
+ panel->alt_fixed_mode);
+
if (panel->downclock_mode)
drm_mode_destroy(intel_connector->base.dev,
panel->downclock_mode);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 40b224b..ed66293 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -62,6 +62,20 @@ static void gen9_init_clock_gating(struct drm_i915_private *dev_priv)
I915_WRITE(CHICKEN_PAR1_1,
I915_READ(CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP);
+ /*
+ * Display WA#0390: skl,bxt,kbl,glk
+ *
+ * Must match Sampler, Pixel Back End, and Media
+ * (0xE194 bit 8, 0x7014 bit 13, 0x4DDC bits 27 and 31).
+ *
+ * Including bits outside the page in the hash would
+ * require 2 (or 4?) MiB alignment of resources. Just
+ * assume the defaul hashing mode which only uses bits
+ * within the page.
+ */
+ I915_WRITE(CHICKEN_PAR1_1,
+ I915_READ(CHICKEN_PAR1_1) & ~SKL_RC_HASH_OUTSIDE);
+
I915_WRITE(GEN8_CONFIG0,
I915_READ(GEN8_CONFIG0) | GEN9_DEFAULT_FIXES);
@@ -78,6 +92,12 @@ static void gen9_init_clock_gating(struct drm_i915_private *dev_priv)
/* WaFbcHighMemBwCorruptionAvoidance:skl,bxt,kbl,cfl */
I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
ILK_DPFC_DISABLE_DUMMY0);
+
+ if (IS_SKYLAKE(dev_priv)) {
+ /* WaDisableDopClockGating */
+ I915_WRITE(GEN7_MISCCPCTL, I915_READ(GEN7_MISCCPCTL)
+ & ~GEN7_DOP_CLOCK_GATE_ENABLE);
+ }
}
static void bxt_init_clock_gating(struct drm_i915_private *dev_priv)
@@ -2758,7 +2778,7 @@ hsw_compute_linetime_wm(const struct intel_crtc_state *cstate)
static void intel_read_wm_latency(struct drm_i915_private *dev_priv,
uint16_t wm[8])
{
- if (IS_GEN9(dev_priv)) {
+ if (INTEL_GEN(dev_priv) >= 9) {
uint32_t val;
int ret, i;
int level, max_level = ilk_wm_max_level(dev_priv);
@@ -2818,7 +2838,7 @@ static void intel_read_wm_latency(struct drm_i915_private *dev_priv,
}
/*
- * WaWmMemoryReadLatency:skl,glk
+ * WaWmMemoryReadLatency:skl+,glk
*
* punit doesn't take into account the read latency so we need
* to add 2us to the various latency levels we retrieve from the
@@ -2857,6 +2877,8 @@ static void intel_read_wm_latency(struct drm_i915_private *dev_priv,
wm[0] = 7;
wm[1] = (mltr >> MLTR_WM1_SHIFT) & ILK_SRLT_MASK;
wm[2] = (mltr >> MLTR_WM2_SHIFT) & ILK_SRLT_MASK;
+ } else {
+ MISSING_CASE(INTEL_DEVID(dev_priv));
}
}
@@ -2912,7 +2934,7 @@ static void intel_print_wm_latency(struct drm_i915_private *dev_priv,
* - latencies are in us on gen9.
* - before then, WM1+ latency values are in 0.5us units
*/
- if (IS_GEN9(dev_priv))
+ if (INTEL_GEN(dev_priv) >= 9)
latency *= 10;
else if (level > 0)
latency *= 5;
@@ -3530,8 +3552,6 @@ bool ilk_disable_lp_wm(struct drm_device *dev)
return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL);
}
-#define SKL_SAGV_BLOCK_TIME 30 /* µs */
-
/*
* FIXME: We still don't have the proper code detect if we need to apply the WA,
* so assume we'll always need it in order to avoid underruns.
@@ -3549,7 +3569,8 @@ static bool skl_needs_memory_bw_wa(struct intel_atomic_state *state)
static bool
intel_has_sagv(struct drm_i915_private *dev_priv)
{
- if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv))
+ if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv) ||
+ IS_CANNONLAKE(dev_priv))
return true;
if (IS_SKYLAKE(dev_priv) &&
@@ -3655,12 +3676,13 @@ bool intel_can_enable_sagv(struct drm_atomic_state *state)
struct intel_crtc_state *cstate;
enum pipe pipe;
int level, latency;
+ int sagv_block_time_us = IS_GEN9(dev_priv) ? 30 : 20;
if (!intel_has_sagv(dev_priv))
return false;
/*
- * SKL workaround: bspec recommends we disable the SAGV when we have
+ * SKL+ workaround: bspec recommends we disable the SAGV when we have
* more then one pipe enabled
*
* If there are no active CRTCs, no additional checks need be performed
@@ -3699,11 +3721,11 @@ bool intel_can_enable_sagv(struct drm_atomic_state *state)
latency += 15;
/*
- * If any of the planes on this pipe don't enable wm levels
- * that incur memory latencies higher then 30µs we can't enable
- * the SAGV
+ * If any of the planes on this pipe don't enable wm levels that
+ * incur memory latencies higher than sagv_block_time_us we
+ * can't enable the SAGV.
*/
- if (latency < SKL_SAGV_BLOCK_TIME)
+ if (latency < sagv_block_time_us)
return false;
}
@@ -3837,7 +3859,7 @@ skl_plane_downscale_amount(const struct intel_crtc_state *cstate,
uint_fixed_16_16_t downscale_h, downscale_w;
if (WARN_ON(!intel_wm_plane_visible(cstate, pstate)))
- return u32_to_fixed_16_16(0);
+ return u32_to_fixed16(0);
/* n.b., src is 16.16 fixed point, dst is whole integer */
if (plane->id == PLANE_CURSOR) {
@@ -3861,10 +3883,10 @@ skl_plane_downscale_amount(const struct intel_crtc_state *cstate,
dst_h = drm_rect_height(&pstate->base.dst);
}
- fp_w_ratio = fixed_16_16_div(src_w, dst_w);
- fp_h_ratio = fixed_16_16_div(src_h, dst_h);
- downscale_w = max_fixed_16_16(fp_w_ratio, u32_to_fixed_16_16(1));
- downscale_h = max_fixed_16_16(fp_h_ratio, u32_to_fixed_16_16(1));
+ fp_w_ratio = div_fixed16(src_w, dst_w);
+ fp_h_ratio = div_fixed16(src_h, dst_h);
+ downscale_w = max_fixed16(fp_w_ratio, u32_to_fixed16(1));
+ downscale_h = max_fixed16(fp_h_ratio, u32_to_fixed16(1));
return mul_fixed16(downscale_w, downscale_h);
}
@@ -3872,7 +3894,7 @@ skl_plane_downscale_amount(const struct intel_crtc_state *cstate,
static uint_fixed_16_16_t
skl_pipe_downscale_amount(const struct intel_crtc_state *crtc_state)
{
- uint_fixed_16_16_t pipe_downscale = u32_to_fixed_16_16(1);
+ uint_fixed_16_16_t pipe_downscale = u32_to_fixed16(1);
if (!crtc_state->base.enable)
return pipe_downscale;
@@ -3891,10 +3913,10 @@ skl_pipe_downscale_amount(const struct intel_crtc_state *crtc_state)
if (!dst_w || !dst_h)
return pipe_downscale;
- fp_w_ratio = fixed_16_16_div(src_w, dst_w);
- fp_h_ratio = fixed_16_16_div(src_h, dst_h);
- downscale_w = max_fixed_16_16(fp_w_ratio, u32_to_fixed_16_16(1));
- downscale_h = max_fixed_16_16(fp_h_ratio, u32_to_fixed_16_16(1));
+ fp_w_ratio = div_fixed16(src_w, dst_w);
+ fp_h_ratio = div_fixed16(src_h, dst_h);
+ downscale_w = max_fixed16(fp_w_ratio, u32_to_fixed16(1));
+ downscale_h = max_fixed16(fp_h_ratio, u32_to_fixed16(1));
pipe_downscale = mul_fixed16(downscale_w, downscale_h);
}
@@ -3913,14 +3935,14 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
int crtc_clock, dotclk;
uint32_t pipe_max_pixel_rate;
uint_fixed_16_16_t pipe_downscale;
- uint_fixed_16_16_t max_downscale = u32_to_fixed_16_16(1);
+ uint_fixed_16_16_t max_downscale = u32_to_fixed16(1);
if (!cstate->base.enable)
return 0;
drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
uint_fixed_16_16_t plane_downscale;
- uint_fixed_16_16_t fp_9_div_8 = fixed_16_16_div(9, 8);
+ uint_fixed_16_16_t fp_9_div_8 = div_fixed16(9, 8);
int bpp;
if (!intel_wm_plane_visible(cstate,
@@ -3938,7 +3960,7 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
plane_downscale = mul_fixed16(plane_downscale,
fp_9_div_8);
- max_downscale = max_fixed_16_16(plane_downscale, max_downscale);
+ max_downscale = max_fixed16(plane_downscale, max_downscale);
}
pipe_downscale = skl_pipe_downscale_amount(cstate);
@@ -4071,7 +4093,9 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate,
/* For Non Y-tile return 8-blocks */
if (fb->modifier != I915_FORMAT_MOD_Y_TILED &&
- fb->modifier != I915_FORMAT_MOD_Yf_TILED)
+ fb->modifier != I915_FORMAT_MOD_Yf_TILED &&
+ fb->modifier != I915_FORMAT_MOD_Y_TILED_CCS &&
+ fb->modifier != I915_FORMAT_MOD_Yf_TILED_CCS)
return 8;
/*
@@ -4266,8 +4290,9 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
* should allow pixel_rate up to ~2 GHz which seems sufficient since max
* 2xcdclk is 1350 MHz and the pixel rate should never exceed that.
*/
-static uint_fixed_16_16_t skl_wm_method1(uint32_t pixel_rate, uint8_t cpp,
- uint32_t latency)
+static uint_fixed_16_16_t
+skl_wm_method1(const struct drm_i915_private *dev_priv, uint32_t pixel_rate,
+ uint8_t cpp, uint32_t latency)
{
uint32_t wm_intermediate_val;
uint_fixed_16_16_t ret;
@@ -4276,7 +4301,11 @@ static uint_fixed_16_16_t skl_wm_method1(uint32_t pixel_rate, uint8_t cpp,
return FP_16_16_MAX;
wm_intermediate_val = latency * pixel_rate * cpp;
- ret = fixed_16_16_div_u64(wm_intermediate_val, 1000 * 512);
+ ret = div_fixed16(wm_intermediate_val, 1000 * 512);
+
+ if (INTEL_GEN(dev_priv) >= 10)
+ ret = add_fixed16_u32(ret, 1);
+
return ret;
}
@@ -4294,7 +4323,7 @@ static uint_fixed_16_16_t skl_wm_method2(uint32_t pixel_rate,
wm_intermediate_val = latency * pixel_rate;
wm_intermediate_val = DIV_ROUND_UP(wm_intermediate_val,
pipe_htotal * 1000);
- ret = mul_u32_fixed_16_16(wm_intermediate_val, plane_blocks_per_line);
+ ret = mul_u32_fixed16(wm_intermediate_val, plane_blocks_per_line);
return ret;
}
@@ -4306,15 +4335,15 @@ intel_get_linetime_us(struct intel_crtc_state *cstate)
uint_fixed_16_16_t linetime_us;
if (!cstate->base.active)
- return u32_to_fixed_16_16(0);
+ return u32_to_fixed16(0);
pixel_rate = cstate->pixel_rate;
if (WARN_ON(pixel_rate == 0))
- return u32_to_fixed_16_16(0);
+ return u32_to_fixed16(0);
crtc_htotal = cstate->base.adjusted_mode.crtc_htotal;
- linetime_us = fixed_16_16_div_u64(crtc_htotal * 1000, pixel_rate);
+ linetime_us = div_fixed16(crtc_htotal * 1000, pixel_rate);
return linetime_us;
}
@@ -4361,7 +4390,7 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
uint32_t plane_bytes_per_line;
uint32_t res_blocks, res_lines;
uint8_t cpp;
- uint32_t width = 0, height = 0;
+ uint32_t width = 0;
uint32_t plane_pixel_rate;
uint_fixed_16_16_t y_tile_minimum;
uint32_t y_min_scanlines;
@@ -4377,7 +4406,9 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
}
y_tiled = fb->modifier == I915_FORMAT_MOD_Y_TILED ||
- fb->modifier == I915_FORMAT_MOD_Yf_TILED;
+ fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
+ fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
+ fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS;
x_tiled = fb->modifier == I915_FORMAT_MOD_X_TILED;
/* Display WA #1141: kbl,cfl */
@@ -4390,7 +4421,6 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
if (plane->id == PLANE_CURSOR) {
width = intel_pstate->base.crtc_w;
- height = intel_pstate->base.crtc_h;
} else {
/*
* Src coordinates are already rotated by 270 degrees for
@@ -4398,16 +4428,13 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
* GTT mapping), hence no need to account for rotation here.
*/
width = drm_rect_width(&intel_pstate->base.src) >> 16;
- height = drm_rect_height(&intel_pstate->base.src) >> 16;
}
- cpp = fb->format->cpp[0];
+ cpp = (fb->format->format == DRM_FORMAT_NV12) ? fb->format->cpp[1] :
+ fb->format->cpp[0];
plane_pixel_rate = skl_adjusted_plane_pixel_rate(cstate, intel_pstate);
if (drm_rotation_90_or_270(pstate->rotation)) {
- int cpp = (fb->format->format == DRM_FORMAT_NV12) ?
- fb->format->cpp[1] :
- fb->format->cpp[0];
switch (cpp) {
case 1:
@@ -4434,51 +4461,62 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
if (y_tiled) {
interm_pbpl = DIV_ROUND_UP(plane_bytes_per_line *
y_min_scanlines, 512);
- plane_blocks_per_line = fixed_16_16_div(interm_pbpl,
+
+ if (INTEL_GEN(dev_priv) >= 10)
+ interm_pbpl++;
+
+ plane_blocks_per_line = div_fixed16(interm_pbpl,
y_min_scanlines);
- } else if (x_tiled) {
+ } else if (x_tiled && INTEL_GEN(dev_priv) == 9) {
interm_pbpl = DIV_ROUND_UP(plane_bytes_per_line, 512);
- plane_blocks_per_line = u32_to_fixed_16_16(interm_pbpl);
+ plane_blocks_per_line = u32_to_fixed16(interm_pbpl);
} else {
interm_pbpl = DIV_ROUND_UP(plane_bytes_per_line, 512) + 1;
- plane_blocks_per_line = u32_to_fixed_16_16(interm_pbpl);
+ plane_blocks_per_line = u32_to_fixed16(interm_pbpl);
}
- method1 = skl_wm_method1(plane_pixel_rate, cpp, latency);
+ method1 = skl_wm_method1(dev_priv, plane_pixel_rate, cpp, latency);
method2 = skl_wm_method2(plane_pixel_rate,
cstate->base.adjusted_mode.crtc_htotal,
latency,
plane_blocks_per_line);
- y_tile_minimum = mul_u32_fixed_16_16(y_min_scanlines,
- plane_blocks_per_line);
+ y_tile_minimum = mul_u32_fixed16(y_min_scanlines,
+ plane_blocks_per_line);
if (y_tiled) {
- selected_result = max_fixed_16_16(method2, y_tile_minimum);
+ selected_result = max_fixed16(method2, y_tile_minimum);
} else {
uint32_t linetime_us;
- linetime_us = fixed_16_16_to_u32_round_up(
+ linetime_us = fixed16_to_u32_round_up(
intel_get_linetime_us(cstate));
if ((cpp * cstate->base.adjusted_mode.crtc_htotal / 512 < 1) &&
(plane_bytes_per_line / 512 < 1))
selected_result = method2;
else if (ddb_allocation >=
- fixed_16_16_to_u32_round_up(plane_blocks_per_line))
- selected_result = min_fixed_16_16(method1, method2);
+ fixed16_to_u32_round_up(plane_blocks_per_line))
+ selected_result = min_fixed16(method1, method2);
else if (latency >= linetime_us)
- selected_result = min_fixed_16_16(method1, method2);
+ selected_result = min_fixed16(method1, method2);
else
selected_result = method1;
}
- res_blocks = fixed_16_16_to_u32_round_up(selected_result) + 1;
+ res_blocks = fixed16_to_u32_round_up(selected_result) + 1;
res_lines = div_round_up_fixed16(selected_result,
plane_blocks_per_line);
+ /* Display WA #1125: skl,bxt,kbl,glk */
+ if (level == 0 &&
+ (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
+ fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS))
+ res_blocks += fixed16_to_u32_round_up(y_tile_minimum);
+
+ /* Display WA #1126: skl,bxt,kbl,glk */
if (level >= 1 && level <= 7) {
if (y_tiled) {
- res_blocks += fixed_16_16_to_u32_round_up(y_tile_minimum);
+ res_blocks += fixed16_to_u32_round_up(y_tile_minimum);
res_lines += y_min_scanlines;
} else {
res_blocks++;
@@ -4563,8 +4601,7 @@ skl_compute_linetime_wm(struct intel_crtc_state *cstate)
if (is_fixed16_zero(linetime_us))
return 0;
- linetime_wm = fixed_16_16_to_u32_round_up(mul_u32_fixed_16_16(8,
- linetime_us));
+ linetime_wm = fixed16_to_u32_round_up(mul_u32_fixed16(8, linetime_us));
/* Display WA #1135: bxt. */
if (IS_BROXTON(dev_priv) && dev_priv->ipc_enabled)
@@ -5852,7 +5889,7 @@ static u32 intel_rps_limits(struct drm_i915_private *dev_priv, u8 val)
* the hw runs at the minimal clock before selecting the desired
* frequency, if the down threshold expires in that window we will not
* receive a down interrupt. */
- if (IS_GEN9(dev_priv)) {
+ if (INTEL_GEN(dev_priv) >= 9) {
limits = (dev_priv->rps.max_freq_softlimit) << 23;
if (val <= dev_priv->rps.min_freq_softlimit)
limits |= (dev_priv->rps.min_freq_softlimit) << 14;
@@ -5994,7 +6031,7 @@ static int gen6_set_rps(struct drm_i915_private *dev_priv, u8 val)
if (val != dev_priv->rps.cur_freq) {
gen6_set_rps_thresholds(dev_priv, val);
- if (IS_GEN9(dev_priv))
+ if (INTEL_GEN(dev_priv) >= 9)
I915_WRITE(GEN6_RPNSWREQ,
GEN9_FREQUENCY(val));
else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
@@ -6126,47 +6163,35 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv)
gen6_sanitize_rps_pm_mask(dev_priv, ~0));
}
mutex_unlock(&dev_priv->rps.hw_lock);
-
- spin_lock(&dev_priv->rps.client_lock);
- while (!list_empty(&dev_priv->rps.clients))
- list_del_init(dev_priv->rps.clients.next);
- spin_unlock(&dev_priv->rps.client_lock);
}
-void gen6_rps_boost(struct drm_i915_private *dev_priv,
- struct intel_rps_client *rps,
- unsigned long submitted)
+void gen6_rps_boost(struct drm_i915_gem_request *rq,
+ struct intel_rps_client *rps)
{
+ struct drm_i915_private *i915 = rq->i915;
+ bool boost;
+
/* This is intentionally racy! We peek at the state here, then
* validate inside the RPS worker.
*/
- if (!(dev_priv->gt.awake &&
- dev_priv->rps.enabled &&
- dev_priv->rps.cur_freq < dev_priv->rps.boost_freq))
+ if (!i915->rps.enabled)
return;
- /* Force a RPS boost (and don't count it against the client) if
- * the GPU is severely congested.
- */
- if (rps && time_after(jiffies, submitted + DRM_I915_THROTTLE_JIFFIES))
- rps = NULL;
-
- spin_lock(&dev_priv->rps.client_lock);
- if (rps == NULL || list_empty(&rps->link)) {
- spin_lock_irq(&dev_priv->irq_lock);
- if (dev_priv->rps.interrupts_enabled) {
- dev_priv->rps.client_boost = true;
- schedule_work(&dev_priv->rps.work);
- }
- spin_unlock_irq(&dev_priv->irq_lock);
-
- if (rps != NULL) {
- list_add(&rps->link, &dev_priv->rps.clients);
- rps->boosts++;
- } else
- dev_priv->rps.boosts++;
+ boost = false;
+ spin_lock_irq(&rq->lock);
+ if (!rq->waitboost && !i915_gem_request_completed(rq)) {
+ atomic_inc(&i915->rps.num_waiters);
+ rq->waitboost = true;
+ boost = true;
}
- spin_unlock(&dev_priv->rps.client_lock);
+ spin_unlock_irq(&rq->lock);
+ if (!boost)
+ return;
+
+ if (READ_ONCE(i915->rps.cur_freq) < i915->rps.boost_freq)
+ schedule_work(&i915->rps.work);
+
+ atomic_inc(rps ? &rps->boosts : &i915->rps.boosts);
}
int intel_set_rps(struct drm_i915_private *dev_priv, u8 val)
@@ -6365,7 +6390,7 @@ static void gen6_init_rps_frequencies(struct drm_i915_private *dev_priv)
dev_priv->rps.efficient_freq = dev_priv->rps.rp1_freq;
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv) ||
- IS_GEN9_BC(dev_priv)) {
+ IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
u32 ddcc_status = 0;
if (sandybridge_pcode_read(dev_priv,
@@ -6378,7 +6403,7 @@ static void gen6_init_rps_frequencies(struct drm_i915_private *dev_priv)
dev_priv->rps.max_freq);
}
- if (IS_GEN9_BC(dev_priv)) {
+ if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
/* Store the frequency values in 16.66 MHZ units, which is
* the natural hardware unit for SKL
*/
@@ -6684,7 +6709,7 @@ static void gen6_update_ring_freq(struct drm_i915_private *dev_priv)
/* convert DDR frequency from units of 266.6MHz to bandwidth */
min_ring_freq = mult_frac(min_ring_freq, 8, 3);
- if (IS_GEN9_BC(dev_priv)) {
+ if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
/* Convert GT frequency to 50 HZ units */
min_gpu_freq = dev_priv->rps.min_freq / GEN9_FREQ_SCALER;
max_gpu_freq = dev_priv->rps.max_freq / GEN9_FREQ_SCALER;
@@ -6702,7 +6727,7 @@ static void gen6_update_ring_freq(struct drm_i915_private *dev_priv)
int diff = max_gpu_freq - gpu_freq;
unsigned int ia_freq = 0, ring_freq = 0;
- if (IS_GEN9_BC(dev_priv)) {
+ if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
/*
* ring_freq = 2 * GT. ring_freq is in 100MHz units
* No floor required for ring frequency on SKL.
@@ -7833,7 +7858,7 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv)
} else if (INTEL_GEN(dev_priv) >= 9) {
gen9_enable_rc6(dev_priv);
gen9_enable_rps(dev_priv);
- if (IS_GEN9_BC(dev_priv))
+ if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv))
gen6_update_ring_freq(dev_priv);
} else if (IS_BROADWELL(dev_priv)) {
gen8_enable_rps(dev_priv);
@@ -8848,6 +8873,7 @@ static inline int gen6_check_mailbox_status(struct drm_i915_private *dev_priv)
case GEN6_PCODE_SUCCESS:
return 0;
case GEN6_PCODE_UNIMPLEMENTED_CMD:
+ return -ENODEV;
case GEN6_PCODE_ILLEGAL_CMD:
return -ENXIO;
case GEN6_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE:
@@ -8895,7 +8921,8 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val
*/
if (I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) {
- DRM_DEBUG_DRIVER("warning: pcode (read) mailbox access failed\n");
+ DRM_DEBUG_DRIVER("warning: pcode (read from mbox %x) mailbox access failed for %ps\n",
+ mbox, __builtin_return_address(0));
return -EAGAIN;
}
@@ -8906,7 +8933,8 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val
if (__intel_wait_for_register_fw(dev_priv,
GEN6_PCODE_MAILBOX, GEN6_PCODE_READY, 0,
500, 0, NULL)) {
- DRM_ERROR("timeout waiting for pcode read (%d) to finish\n", mbox);
+ DRM_ERROR("timeout waiting for pcode read (from mbox %x) to finish for %ps\n",
+ mbox, __builtin_return_address(0));
return -ETIMEDOUT;
}
@@ -8919,8 +8947,8 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val
status = gen6_check_mailbox_status(dev_priv);
if (status) {
- DRM_DEBUG_DRIVER("warning: pcode (read) mailbox access failed: %d\n",
- status);
+ DRM_DEBUG_DRIVER("warning: pcode (read from mbox %x) mailbox access failed for %ps: %d\n",
+ mbox, __builtin_return_address(0), status);
return status;
}
@@ -8940,7 +8968,8 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv,
*/
if (I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) {
- DRM_DEBUG_DRIVER("warning: pcode (write) mailbox access failed\n");
+ DRM_DEBUG_DRIVER("warning: pcode (write of 0x%08x to mbox %x) mailbox access failed for %ps\n",
+ val, mbox, __builtin_return_address(0));
return -EAGAIN;
}
@@ -8951,7 +8980,8 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv,
if (__intel_wait_for_register_fw(dev_priv,
GEN6_PCODE_MAILBOX, GEN6_PCODE_READY, 0,
500, 0, NULL)) {
- DRM_ERROR("timeout waiting for pcode write (%d) to finish\n", mbox);
+ DRM_ERROR("timeout waiting for pcode write of 0x%08x to mbox %x to finish for %ps\n",
+ val, mbox, __builtin_return_address(0));
return -ETIMEDOUT;
}
@@ -8963,8 +8993,8 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv,
status = gen6_check_mailbox_status(dev_priv);
if (status) {
- DRM_DEBUG_DRIVER("warning: pcode (write) mailbox access failed: %d\n",
- status);
+ DRM_DEBUG_DRIVER("warning: pcode (write of 0x%08x to mbox %x) mailbox access failed for %ps: %d\n",
+ val, mbox, __builtin_return_address(0), status);
return status;
}
@@ -9078,7 +9108,7 @@ static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val)
int intel_gpu_freq(struct drm_i915_private *dev_priv, int val)
{
- if (IS_GEN9(dev_priv))
+ if (INTEL_GEN(dev_priv) >= 9)
return DIV_ROUND_CLOSEST(val * GT_FREQUENCY_MULTIPLIER,
GEN9_FREQ_SCALER);
else if (IS_CHERRYVIEW(dev_priv))
@@ -9091,7 +9121,7 @@ int intel_gpu_freq(struct drm_i915_private *dev_priv, int val)
int intel_freq_opcode(struct drm_i915_private *dev_priv, int val)
{
- if (IS_GEN9(dev_priv))
+ if (INTEL_GEN(dev_priv) >= 9)
return DIV_ROUND_CLOSEST(val * GEN9_FREQ_SCALER,
GT_FREQUENCY_MULTIPLIER);
else if (IS_CHERRYVIEW(dev_priv))
@@ -9113,7 +9143,7 @@ static void __intel_rps_boost_work(struct work_struct *work)
struct drm_i915_gem_request *req = boost->req;
if (!i915_gem_request_completed(req))
- gen6_rps_boost(req->i915, NULL, req->emitted_jiffies);
+ gen6_rps_boost(req, NULL);
i915_gem_request_put(req);
kfree(boost);
@@ -9142,11 +9172,10 @@ void intel_queue_rps_boost_for_request(struct drm_i915_gem_request *req)
void intel_pm_setup(struct drm_i915_private *dev_priv)
{
mutex_init(&dev_priv->rps.hw_lock);
- spin_lock_init(&dev_priv->rps.client_lock);
INIT_DELAYED_WORK(&dev_priv->rps.autoenable_work,
__intel_autoenable_gt_powersave);
- INIT_LIST_HEAD(&dev_priv->rps.clients);
+ atomic_set(&dev_priv->rps.num_waiters, 0);
dev_priv->pm.suspended = false;
atomic_set(&dev_priv->pm.wakeref_count, 0);
diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c
index 559f1ab..1b31ab0 100644
--- a/drivers/gpu/drm/i915/intel_psr.c
+++ b/drivers/gpu/drm/i915/intel_psr.c
@@ -315,6 +315,7 @@ static void intel_enable_source_psr1(struct intel_dp *intel_dp)
else
val |= EDP_PSR_TP1_TP2_SEL;
+ val |= I915_READ(EDP_PSR_CTL) & EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK;
I915_WRITE(EDP_PSR_CTL, val);
}
diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen9.c b/drivers/gpu/drm/i915/intel_renderstate_gen9.c
index 16a7ec2..7d3ac02 100644
--- a/drivers/gpu/drm/i915/intel_renderstate_gen9.c
+++ b/drivers/gpu/drm/i915/intel_renderstate_gen9.c
@@ -20,7 +20,7 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
- * Generated by: intel-gpu-tools-1.8-220-g01153e7
+ * Generated by: intel-gpu-tools-1.19-177-g68e2eab2
*/
#include "intel_renderstate.h"
@@ -873,7 +873,7 @@ static const u32 gen9_null_state_batch[] = {
0x00000000,
0x00000000,
0x78550003,
- 0x00000000,
+ 0x0000000f,
0x00000000,
0x00000000,
0x00000000,
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index acd1da9..cdf084e 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1712,6 +1712,9 @@ u32 *intel_ring_begin(struct drm_i915_gem_request *req,
unsigned int total_bytes;
u32 *cs;
+ /* Packets must be qword aligned. */
+ GEM_BUG_ON(num_dwords & 1);
+
total_bytes = bytes + req->reserved_space;
GEM_BUG_ON(total_bytes > ring->effective_size);
@@ -2140,7 +2143,7 @@ static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv,
engine->emit_breadcrumb = gen6_sema_emit_breadcrumb;
- num_rings = hweight32(INTEL_INFO(dev_priv)->ring_mask) - 1;
+ num_rings = INTEL_INFO(dev_priv)->num_rings - 1;
if (INTEL_GEN(dev_priv) >= 8) {
engine->emit_breadcrumb_sz += num_rings * 6;
} else {
@@ -2184,8 +2187,7 @@ int intel_init_render_ring_buffer(struct intel_engine_cs *engine)
engine->semaphore.signal = gen8_rcs_signal;
- num_rings =
- hweight32(INTEL_INFO(dev_priv)->ring_mask) - 1;
+ num_rings = INTEL_INFO(dev_priv)->num_rings - 1;
engine->emit_breadcrumb_sz += num_rings * 8;
}
} else if (INTEL_GEN(dev_priv) >= 6) {
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 6aa20ac..02d8974 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -121,6 +121,7 @@ struct intel_engine_hangcheck {
unsigned long action_timestamp;
int deadlock;
struct intel_instdone instdone;
+ struct drm_i915_gem_request *active_request;
bool stalled;
};
@@ -734,4 +735,16 @@ bool intel_engines_are_idle(struct drm_i915_private *dev_priv);
void intel_engines_mark_idle(struct drm_i915_private *i915);
void intel_engines_reset_default_submission(struct drm_i915_private *i915);
+static inline bool
+__intel_engine_can_store_dword(unsigned int gen, unsigned int class)
+{
+ if (gen <= 2)
+ return false; /* uses physical not virtual addresses */
+
+ if (gen == 6 && class == VIDEO_DECODE_CLASS)
+ return false; /* b0rked */
+
+ return true;
+}
+
#endif /* _INTEL_RINGBUFFER_H_ */
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index efe80ed..b66d8e1 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -50,10 +50,11 @@
*/
bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv,
- int power_well_id);
+ enum i915_power_well_id power_well_id);
static struct i915_power_well *
-lookup_power_well(struct drm_i915_private *dev_priv, int power_well_id);
+lookup_power_well(struct drm_i915_private *dev_priv,
+ enum i915_power_well_id power_well_id);
const char *
intel_display_power_domain_str(enum intel_display_power_domain domain)
@@ -168,18 +169,6 @@ static void intel_power_well_put(struct drm_i915_private *dev_priv,
intel_power_well_disable(dev_priv, power_well);
}
-/*
- * We should only use the power well if we explicitly asked the hardware to
- * enable it, so check if it's enabled and also check if we've requested it to
- * be enabled.
- */
-static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well)
-{
- return I915_READ(HSW_PWR_WELL_DRIVER) ==
- (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED);
-}
-
/**
* __intel_display_power_is_enabled - unlocked check for a power domain
* @dev_priv: i915 device instance
@@ -278,7 +267,8 @@ void intel_display_set_init_power(struct drm_i915_private *dev_priv,
* to be enabled, and it will only be disabled if none of the registers is
* requesting it to be enabled.
*/
-static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv)
+static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv,
+ u8 irq_pipe_mask, bool has_vga)
{
struct pci_dev *pdev = dev_priv->drm.pdev;
@@ -292,264 +282,158 @@ static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv)
* sure vgacon can keep working normally without triggering interrupts
* and error messages.
*/
- vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO);
- outb(inb(VGA_MSR_READ), VGA_MSR_WRITE);
- vga_put(pdev, VGA_RSRC_LEGACY_IO);
+ if (has_vga) {
+ vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO);
+ outb(inb(VGA_MSR_READ), VGA_MSR_WRITE);
+ vga_put(pdev, VGA_RSRC_LEGACY_IO);
+ }
- if (IS_BROADWELL(dev_priv))
- gen8_irq_power_well_post_enable(dev_priv,
- 1 << PIPE_C | 1 << PIPE_B);
+ if (irq_pipe_mask)
+ gen8_irq_power_well_post_enable(dev_priv, irq_pipe_mask);
}
-static void hsw_power_well_pre_disable(struct drm_i915_private *dev_priv)
+static void hsw_power_well_pre_disable(struct drm_i915_private *dev_priv,
+ u8 irq_pipe_mask)
{
- if (IS_BROADWELL(dev_priv))
- gen8_irq_power_well_pre_disable(dev_priv,
- 1 << PIPE_C | 1 << PIPE_B);
+ if (irq_pipe_mask)
+ gen8_irq_power_well_pre_disable(dev_priv, irq_pipe_mask);
}
-static void skl_power_well_post_enable(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well)
+
+static void hsw_wait_for_power_well_enable(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
{
- struct pci_dev *pdev = dev_priv->drm.pdev;
+ enum i915_power_well_id id = power_well->id;
+
+ /* Timeout for PW1:10 us, AUX:not specified, other PWs:20 us. */
+ WARN_ON(intel_wait_for_register(dev_priv,
+ HSW_PWR_WELL_CTL_DRIVER(id),
+ HSW_PWR_WELL_CTL_STATE(id),
+ HSW_PWR_WELL_CTL_STATE(id),
+ 1));
+}
+
+static u32 hsw_power_well_requesters(struct drm_i915_private *dev_priv,
+ enum i915_power_well_id id)
+{
+ u32 req_mask = HSW_PWR_WELL_CTL_REQ(id);
+ u32 ret;
+
+ ret = I915_READ(HSW_PWR_WELL_CTL_BIOS(id)) & req_mask ? 1 : 0;
+ ret |= I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)) & req_mask ? 2 : 0;
+ ret |= I915_READ(HSW_PWR_WELL_CTL_KVMR) & req_mask ? 4 : 0;
+ ret |= I915_READ(HSW_PWR_WELL_CTL_DEBUG(id)) & req_mask ? 8 : 0;
+
+ return ret;
+}
+
+static void hsw_wait_for_power_well_disable(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+ enum i915_power_well_id id = power_well->id;
+ bool disabled;
+ u32 reqs;
/*
- * After we re-enable the power well, if we touch VGA register 0x3d5
- * we'll get unclaimed register interrupts. This stops after we write
- * anything to the VGA MSR register. The vgacon module uses this
- * register all the time, so if we unbind our driver and, as a
- * consequence, bind vgacon, we'll get stuck in an infinite loop at
- * console_unlock(). So make here we touch the VGA MSR register, making
- * sure vgacon can keep working normally without triggering interrupts
- * and error messages.
+ * Bspec doesn't require waiting for PWs to get disabled, but still do
+ * this for paranoia. The known cases where a PW will be forced on:
+ * - a KVMR request on any power well via the KVMR request register
+ * - a DMC request on PW1 and MISC_IO power wells via the BIOS and
+ * DEBUG request registers
+ * Skip the wait in case any of the request bits are set and print a
+ * diagnostic message.
*/
- if (power_well->id == SKL_DISP_PW_2) {
- vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO);
- outb(inb(VGA_MSR_READ), VGA_MSR_WRITE);
- vga_put(pdev, VGA_RSRC_LEGACY_IO);
+ wait_for((disabled = !(I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)) &
+ HSW_PWR_WELL_CTL_STATE(id))) ||
+ (reqs = hsw_power_well_requesters(dev_priv, id)), 1);
+ if (disabled)
+ return;
- gen8_irq_power_well_post_enable(dev_priv,
- 1 << PIPE_C | 1 << PIPE_B);
- }
+ DRM_DEBUG_KMS("%s forced on (bios:%d driver:%d kvmr:%d debug:%d)\n",
+ power_well->name,
+ !!(reqs & 1), !!(reqs & 2), !!(reqs & 4), !!(reqs & 8));
}
-static void skl_power_well_pre_disable(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well)
+static void gen9_wait_for_power_well_fuses(struct drm_i915_private *dev_priv,
+ enum skl_power_gate pg)
{
- if (power_well->id == SKL_DISP_PW_2)
- gen8_irq_power_well_pre_disable(dev_priv,
- 1 << PIPE_C | 1 << PIPE_B);
+ /* Timeout 5us for PG#0, for other PGs 1us */
+ WARN_ON(intel_wait_for_register(dev_priv, SKL_FUSE_STATUS,
+ SKL_FUSE_PG_DIST_STATUS(pg),
+ SKL_FUSE_PG_DIST_STATUS(pg), 1));
}
-static void hsw_set_power_well(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well, bool enable)
+static void hsw_power_well_enable(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
{
- bool is_enabled, enable_requested;
- uint32_t tmp;
-
- tmp = I915_READ(HSW_PWR_WELL_DRIVER);
- is_enabled = tmp & HSW_PWR_WELL_STATE_ENABLED;
- enable_requested = tmp & HSW_PWR_WELL_ENABLE_REQUEST;
-
- if (enable) {
- if (!enable_requested)
- I915_WRITE(HSW_PWR_WELL_DRIVER,
- HSW_PWR_WELL_ENABLE_REQUEST);
-
- if (!is_enabled) {
- DRM_DEBUG_KMS("Enabling power well\n");
- if (intel_wait_for_register(dev_priv,
- HSW_PWR_WELL_DRIVER,
- HSW_PWR_WELL_STATE_ENABLED,
- HSW_PWR_WELL_STATE_ENABLED,
- 20))
- DRM_ERROR("Timeout enabling power well\n");
- hsw_power_well_post_enable(dev_priv);
- }
+ enum i915_power_well_id id = power_well->id;
+ bool wait_fuses = power_well->hsw.has_fuses;
+ enum skl_power_gate pg;
+ u32 val;
- } else {
- if (enable_requested) {
- hsw_power_well_pre_disable(dev_priv);
- I915_WRITE(HSW_PWR_WELL_DRIVER, 0);
- POSTING_READ(HSW_PWR_WELL_DRIVER);
- DRM_DEBUG_KMS("Requesting to disable the power well\n");
- }
+ if (wait_fuses) {
+ pg = SKL_PW_TO_PG(id);
+ /*
+ * For PW1 we have to wait both for the PW0/PG0 fuse state
+ * before enabling the power well and PW1/PG1's own fuse
+ * state after the enabling. For all other power wells with
+ * fuses we only have to wait for that PW/PG's fuse state
+ * after the enabling.
+ */
+ if (pg == SKL_PG1)
+ gen9_wait_for_power_well_fuses(dev_priv, SKL_PG0);
}
+
+ val = I915_READ(HSW_PWR_WELL_CTL_DRIVER(id));
+ I915_WRITE(HSW_PWR_WELL_CTL_DRIVER(id), val | HSW_PWR_WELL_CTL_REQ(id));
+ hsw_wait_for_power_well_enable(dev_priv, power_well);
+
+ if (wait_fuses)
+ gen9_wait_for_power_well_fuses(dev_priv, pg);
+
+ hsw_power_well_post_enable(dev_priv, power_well->hsw.irq_pipe_mask,
+ power_well->hsw.has_vga);
}
-#define SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_D_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_E_LANES) | \
- BIT_ULL(POWER_DOMAIN_AUX_B) | \
- BIT_ULL(POWER_DOMAIN_AUX_C) | \
- BIT_ULL(POWER_DOMAIN_AUX_D) | \
- BIT_ULL(POWER_DOMAIN_AUDIO) | \
- BIT_ULL(POWER_DOMAIN_VGA) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define SKL_DISPLAY_DDI_IO_A_E_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_A_IO) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_E_IO) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define SKL_DISPLAY_DDI_IO_B_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_B_IO) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define SKL_DISPLAY_DDI_IO_C_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_C_IO) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define SKL_DISPLAY_DDI_IO_D_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_D_IO) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define SKL_DISPLAY_DC_OFF_POWER_DOMAINS ( \
- SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS | \
- BIT_ULL(POWER_DOMAIN_MODESET) | \
- BIT_ULL(POWER_DOMAIN_AUX_A) | \
- BIT_ULL(POWER_DOMAIN_INIT))
+static void hsw_power_well_disable(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+ enum i915_power_well_id id = power_well->id;
+ u32 val;
-#define BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
- BIT_ULL(POWER_DOMAIN_AUX_B) | \
- BIT_ULL(POWER_DOMAIN_AUX_C) | \
- BIT_ULL(POWER_DOMAIN_AUDIO) | \
- BIT_ULL(POWER_DOMAIN_VGA) | \
- BIT_ULL(POWER_DOMAIN_GMBUS) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define BXT_DISPLAY_DC_OFF_POWER_DOMAINS ( \
- BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS | \
- BIT_ULL(POWER_DOMAIN_MODESET) | \
- BIT_ULL(POWER_DOMAIN_AUX_A) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define BXT_DPIO_CMN_A_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_A_LANES) | \
- BIT_ULL(POWER_DOMAIN_AUX_A) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define BXT_DPIO_CMN_BC_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
- BIT_ULL(POWER_DOMAIN_AUX_B) | \
- BIT_ULL(POWER_DOMAIN_AUX_C) | \
- BIT_ULL(POWER_DOMAIN_INIT))
+ hsw_power_well_pre_disable(dev_priv, power_well->hsw.irq_pipe_mask);
-#define GLK_DISPLAY_POWERWELL_2_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
- BIT_ULL(POWER_DOMAIN_AUX_B) | \
- BIT_ULL(POWER_DOMAIN_AUX_C) | \
- BIT_ULL(POWER_DOMAIN_AUDIO) | \
- BIT_ULL(POWER_DOMAIN_VGA) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define GLK_DISPLAY_DDI_IO_A_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_A_IO))
-#define GLK_DISPLAY_DDI_IO_B_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_B_IO))
-#define GLK_DISPLAY_DDI_IO_C_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_C_IO))
-#define GLK_DPIO_CMN_A_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_A_LANES) | \
- BIT_ULL(POWER_DOMAIN_AUX_A) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define GLK_DPIO_CMN_B_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
- BIT_ULL(POWER_DOMAIN_AUX_B) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define GLK_DPIO_CMN_C_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
- BIT_ULL(POWER_DOMAIN_AUX_C) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define GLK_DISPLAY_AUX_A_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_AUX_A) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define GLK_DISPLAY_AUX_B_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_AUX_B) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define GLK_DISPLAY_AUX_C_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_AUX_C) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define GLK_DISPLAY_DC_OFF_POWER_DOMAINS ( \
- GLK_DISPLAY_POWERWELL_2_POWER_DOMAINS | \
- BIT_ULL(POWER_DOMAIN_MODESET) | \
- BIT_ULL(POWER_DOMAIN_AUX_A) | \
- BIT_ULL(POWER_DOMAIN_INIT))
+ val = I915_READ(HSW_PWR_WELL_CTL_DRIVER(id));
+ I915_WRITE(HSW_PWR_WELL_CTL_DRIVER(id),
+ val & ~HSW_PWR_WELL_CTL_REQ(id));
+ hsw_wait_for_power_well_disable(dev_priv, power_well);
+}
-#define CNL_DISPLAY_POWERWELL_2_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_D_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_E_LANES) | \
- BIT_ULL(POWER_DOMAIN_AUX_B) | \
- BIT_ULL(POWER_DOMAIN_AUX_C) | \
- BIT_ULL(POWER_DOMAIN_AUX_D) | \
- BIT_ULL(POWER_DOMAIN_AUDIO) | \
- BIT_ULL(POWER_DOMAIN_VGA) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_DDI_A_IO_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_A_IO) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_E_IO) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_DDI_B_IO_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_B_IO) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_DDI_C_IO_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_C_IO) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_DDI_D_IO_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_D_IO) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_AUX_A_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_AUX_A) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_AUX_B_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_AUX_B) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_AUX_C_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_AUX_C) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_AUX_D_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_AUX_D) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_DC_OFF_POWER_DOMAINS ( \
- CNL_DISPLAY_POWERWELL_2_POWER_DOMAINS | \
- BIT_ULL(POWER_DOMAIN_MODESET) | \
- BIT_ULL(POWER_DOMAIN_AUX_A) | \
- BIT_ULL(POWER_DOMAIN_INIT))
+/*
+ * We should only use the power well if we explicitly asked the hardware to
+ * enable it, so check if it's enabled and also check if we've requested it to
+ * be enabled.
+ */
+static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+ enum i915_power_well_id id = power_well->id;
+ u32 mask = HSW_PWR_WELL_CTL_REQ(id) | HSW_PWR_WELL_CTL_STATE(id);
+
+ return (I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)) & mask) == mask;
+}
static void assert_can_enable_dc9(struct drm_i915_private *dev_priv)
{
+ enum i915_power_well_id id = SKL_DISP_PW_2;
+
WARN_ONCE((I915_READ(DC_STATE_EN) & DC_STATE_EN_DC9),
"DC9 already programmed to be enabled.\n");
WARN_ONCE(I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC5,
"DC5 still not disabled to enable DC9.\n");
- WARN_ONCE(I915_READ(HSW_PWR_WELL_DRIVER), "Power well on.\n");
+ WARN_ONCE(I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)) &
+ HSW_PWR_WELL_CTL_REQ(id),
+ "Power well 2 on.\n");
WARN_ONCE(intel_irqs_enabled(dev_priv),
"Interrupts not disabled yet.\n");
@@ -744,223 +628,39 @@ void skl_disable_dc6(struct drm_i915_private *dev_priv)
gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
}
-static void
-gen9_sanitize_power_well_requests(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well)
-{
- enum skl_disp_power_wells power_well_id = power_well->id;
- u32 val;
- u32 mask;
-
- mask = SKL_POWER_WELL_REQ(power_well_id);
-
- val = I915_READ(HSW_PWR_WELL_KVMR);
- if (WARN_ONCE(val & mask, "Clearing unexpected KVMR request for %s\n",
- power_well->name))
- I915_WRITE(HSW_PWR_WELL_KVMR, val & ~mask);
-
- val = I915_READ(HSW_PWR_WELL_BIOS);
- val |= I915_READ(HSW_PWR_WELL_DEBUG);
-
- if (!(val & mask))
- return;
-
- /*
- * DMC is known to force on the request bits for power well 1 on SKL
- * and BXT and the misc IO power well on SKL but we don't expect any
- * other request bits to be set, so WARN for those.
- */
- if (power_well_id == SKL_DISP_PW_1 ||
- (IS_GEN9_BC(dev_priv) &&
- power_well_id == SKL_DISP_PW_MISC_IO))
- DRM_DEBUG_DRIVER("Clearing auxiliary requests for %s forced on "
- "by DMC\n", power_well->name);
- else
- WARN_ONCE(1, "Clearing unexpected auxiliary requests for %s\n",
- power_well->name);
-
- I915_WRITE(HSW_PWR_WELL_BIOS, val & ~mask);
- I915_WRITE(HSW_PWR_WELL_DEBUG, val & ~mask);
-}
-
-static void skl_set_power_well(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well, bool enable)
-{
- uint32_t tmp, fuse_status;
- uint32_t req_mask, state_mask;
- bool is_enabled, enable_requested, check_fuse_status = false;
-
- tmp = I915_READ(HSW_PWR_WELL_DRIVER);
- fuse_status = I915_READ(SKL_FUSE_STATUS);
-
- switch (power_well->id) {
- case SKL_DISP_PW_1:
- if (intel_wait_for_register(dev_priv,
- SKL_FUSE_STATUS,
- SKL_FUSE_PG0_DIST_STATUS,
- SKL_FUSE_PG0_DIST_STATUS,
- 1)) {
- DRM_ERROR("PG0 not enabled\n");
- return;
- }
- break;
- case SKL_DISP_PW_2:
- if (!(fuse_status & SKL_FUSE_PG1_DIST_STATUS)) {
- DRM_ERROR("PG1 in disabled state\n");
- return;
- }
- break;
- case SKL_DISP_PW_MISC_IO:
- case SKL_DISP_PW_DDI_A_E: /* GLK_DISP_PW_DDI_A, CNL_DISP_PW_DDI_A */
- case SKL_DISP_PW_DDI_B:
- case SKL_DISP_PW_DDI_C:
- case SKL_DISP_PW_DDI_D:
- case GLK_DISP_PW_AUX_A: /* CNL_DISP_PW_AUX_A */
- case GLK_DISP_PW_AUX_B: /* CNL_DISP_PW_AUX_B */
- case GLK_DISP_PW_AUX_C: /* CNL_DISP_PW_AUX_C */
- case CNL_DISP_PW_AUX_D:
- break;
- default:
- WARN(1, "Unknown power well %lu\n", power_well->id);
- return;
- }
-
- req_mask = SKL_POWER_WELL_REQ(power_well->id);
- enable_requested = tmp & req_mask;
- state_mask = SKL_POWER_WELL_STATE(power_well->id);
- is_enabled = tmp & state_mask;
-
- if (!enable && enable_requested)
- skl_power_well_pre_disable(dev_priv, power_well);
-
- if (enable) {
- if (!enable_requested) {
- WARN((tmp & state_mask) &&
- !I915_READ(HSW_PWR_WELL_BIOS),
- "Invalid for power well status to be enabled, unless done by the BIOS, \
- when request is to disable!\n");
- I915_WRITE(HSW_PWR_WELL_DRIVER, tmp | req_mask);
- }
-
- if (!is_enabled) {
- DRM_DEBUG_KMS("Enabling %s\n", power_well->name);
- check_fuse_status = true;
- }
- } else {
- if (enable_requested) {
- I915_WRITE(HSW_PWR_WELL_DRIVER, tmp & ~req_mask);
- POSTING_READ(HSW_PWR_WELL_DRIVER);
- DRM_DEBUG_KMS("Disabling %s\n", power_well->name);
- }
-
- gen9_sanitize_power_well_requests(dev_priv, power_well);
- }
-
- if (wait_for(!!(I915_READ(HSW_PWR_WELL_DRIVER) & state_mask) == enable,
- 1))
- DRM_ERROR("%s %s timeout\n",
- power_well->name, enable ? "enable" : "disable");
-
- if (check_fuse_status) {
- if (power_well->id == SKL_DISP_PW_1) {
- if (intel_wait_for_register(dev_priv,
- SKL_FUSE_STATUS,
- SKL_FUSE_PG1_DIST_STATUS,
- SKL_FUSE_PG1_DIST_STATUS,
- 1))
- DRM_ERROR("PG1 distributing status timeout\n");
- } else if (power_well->id == SKL_DISP_PW_2) {
- if (intel_wait_for_register(dev_priv,
- SKL_FUSE_STATUS,
- SKL_FUSE_PG2_DIST_STATUS,
- SKL_FUSE_PG2_DIST_STATUS,
- 1))
- DRM_ERROR("PG2 distributing status timeout\n");
- }
- }
-
- if (enable && !is_enabled)
- skl_power_well_post_enable(dev_priv, power_well);
-}
-
static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- /* Take over the request bit if set by BIOS. */
- if (I915_READ(HSW_PWR_WELL_BIOS) & HSW_PWR_WELL_ENABLE_REQUEST) {
- if (!(I915_READ(HSW_PWR_WELL_DRIVER) &
- HSW_PWR_WELL_ENABLE_REQUEST))
- I915_WRITE(HSW_PWR_WELL_DRIVER,
- HSW_PWR_WELL_ENABLE_REQUEST);
- I915_WRITE(HSW_PWR_WELL_BIOS, 0);
- }
-}
-
-static void hsw_power_well_enable(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well)
-{
- hsw_set_power_well(dev_priv, power_well, true);
-}
-
-static void hsw_power_well_disable(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well)
-{
- hsw_set_power_well(dev_priv, power_well, false);
-}
-
-static bool skl_power_well_enabled(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well)
-{
- uint32_t mask = SKL_POWER_WELL_REQ(power_well->id) |
- SKL_POWER_WELL_STATE(power_well->id);
-
- return (I915_READ(HSW_PWR_WELL_DRIVER) & mask) == mask;
-}
-
-static void skl_power_well_sync_hw(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well)
-{
- uint32_t mask = SKL_POWER_WELL_REQ(power_well->id);
- uint32_t bios_req = I915_READ(HSW_PWR_WELL_BIOS);
+ enum i915_power_well_id id = power_well->id;
+ u32 mask = HSW_PWR_WELL_CTL_REQ(id);
+ u32 bios_req = I915_READ(HSW_PWR_WELL_CTL_BIOS(id));
/* Take over the request bit if set by BIOS. */
if (bios_req & mask) {
- uint32_t drv_req = I915_READ(HSW_PWR_WELL_DRIVER);
+ u32 drv_req = I915_READ(HSW_PWR_WELL_CTL_DRIVER(id));
if (!(drv_req & mask))
- I915_WRITE(HSW_PWR_WELL_DRIVER, drv_req | mask);
- I915_WRITE(HSW_PWR_WELL_BIOS, bios_req & ~mask);
+ I915_WRITE(HSW_PWR_WELL_CTL_DRIVER(id), drv_req | mask);
+ I915_WRITE(HSW_PWR_WELL_CTL_BIOS(id), bios_req & ~mask);
}
}
-static void skl_power_well_enable(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well)
-{
- skl_set_power_well(dev_priv, power_well, true);
-}
-
-static void skl_power_well_disable(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well)
-{
- skl_set_power_well(dev_priv, power_well, false);
-}
-
static void bxt_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- bxt_ddi_phy_init(dev_priv, power_well->data);
+ bxt_ddi_phy_init(dev_priv, power_well->bxt.phy);
}
static void bxt_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- bxt_ddi_phy_uninit(dev_priv, power_well->data);
+ bxt_ddi_phy_uninit(dev_priv, power_well->bxt.phy);
}
static bool bxt_dpio_cmn_power_well_enabled(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- return bxt_ddi_phy_is_enabled(dev_priv, power_well->data);
+ return bxt_ddi_phy_is_enabled(dev_priv, power_well->bxt.phy);
}
static void bxt_verify_ddi_phy_power_wells(struct drm_i915_private *dev_priv)
@@ -969,16 +669,16 @@ static void bxt_verify_ddi_phy_power_wells(struct drm_i915_private *dev_priv)
power_well = lookup_power_well(dev_priv, BXT_DPIO_CMN_A);
if (power_well->count > 0)
- bxt_ddi_phy_verify_state(dev_priv, power_well->data);
+ bxt_ddi_phy_verify_state(dev_priv, power_well->bxt.phy);
power_well = lookup_power_well(dev_priv, BXT_DPIO_CMN_BC);
if (power_well->count > 0)
- bxt_ddi_phy_verify_state(dev_priv, power_well->data);
+ bxt_ddi_phy_verify_state(dev_priv, power_well->bxt.phy);
if (IS_GEMINILAKE(dev_priv)) {
power_well = lookup_power_well(dev_priv, GLK_DPIO_CMN_C);
if (power_well->count > 0)
- bxt_ddi_phy_verify_state(dev_priv, power_well->data);
+ bxt_ddi_phy_verify_state(dev_priv, power_well->bxt.phy);
}
}
@@ -1076,7 +776,7 @@ static void i830_pipes_power_well_sync_hw(struct drm_i915_private *dev_priv,
static void vlv_set_power_well(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well, bool enable)
{
- enum punit_power_well power_well_id = power_well->id;
+ enum i915_power_well_id power_well_id = power_well->id;
u32 mask;
u32 state;
u32 ctrl;
@@ -1124,7 +824,7 @@ static void vlv_power_well_disable(struct drm_i915_private *dev_priv,
static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- int power_well_id = power_well->id;
+ enum i915_power_well_id power_well_id = power_well->id;
bool enabled = false;
u32 mask;
u32 state;
@@ -1311,8 +1011,9 @@ static void vlv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv,
#define POWER_DOMAIN_MASK (GENMASK_ULL(POWER_DOMAIN_NUM - 1, 0))
-static struct i915_power_well *lookup_power_well(struct drm_i915_private *dev_priv,
- int power_well_id)
+static struct i915_power_well *
+lookup_power_well(struct drm_i915_private *dev_priv,
+ enum i915_power_well_id power_well_id)
{
struct i915_power_domains *power_domains = &dev_priv->power_domains;
int i;
@@ -1659,7 +1360,7 @@ void chv_phy_powergate_lanes(struct intel_encoder *encoder,
static bool chv_pipe_power_well_enabled(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- enum pipe pipe = power_well->id;
+ enum pipe pipe = PIPE_A;
bool enabled;
u32 state, ctrl;
@@ -1689,7 +1390,7 @@ static void chv_set_pipe_power_well(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well,
bool enable)
{
- enum pipe pipe = power_well->id;
+ enum pipe pipe = PIPE_A;
u32 state;
u32 ctrl;
@@ -1722,7 +1423,7 @@ out:
static void chv_pipe_power_well_enable(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- WARN_ON_ONCE(power_well->id != PIPE_A);
+ WARN_ON_ONCE(power_well->id != CHV_DISP_PW_PIPE_A);
chv_set_pipe_power_well(dev_priv, power_well, true);
@@ -1732,7 +1433,7 @@ static void chv_pipe_power_well_enable(struct drm_i915_private *dev_priv,
static void chv_pipe_power_well_disable(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- WARN_ON_ONCE(power_well->id != PIPE_A);
+ WARN_ON_ONCE(power_well->id != CHV_DISP_PW_PIPE_A);
vlv_display_power_well_deinit(dev_priv);
@@ -1848,37 +1549,13 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
intel_runtime_pm_put(dev_priv);
}
-#define HSW_DISPLAY_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PIPE_B) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C) | \
- BIT_ULL(POWER_DOMAIN_PIPE_A_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_D_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_CRT) | /* DDI E */ \
- BIT_ULL(POWER_DOMAIN_VGA) | \
- BIT_ULL(POWER_DOMAIN_AUDIO) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-
-#define BDW_DISPLAY_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PIPE_B) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_D_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_CRT) | /* DDI E */ \
- BIT_ULL(POWER_DOMAIN_VGA) | \
- BIT_ULL(POWER_DOMAIN_AUDIO) | \
+#define I830_PIPES_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PIPE_A) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_A_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
BIT_ULL(POWER_DOMAIN_INIT))
#define VLV_DISPLAY_POWER_DOMAINS ( \
@@ -1961,13 +1638,201 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
BIT_ULL(POWER_DOMAIN_AUX_D) | \
BIT_ULL(POWER_DOMAIN_INIT))
-#define I830_PIPES_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PIPE_A) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B) | \
- BIT_ULL(POWER_DOMAIN_PIPE_A_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
+#define HSW_DISPLAY_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PIPE_B) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_C) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_A_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_D_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_CRT) | /* DDI E */ \
+ BIT_ULL(POWER_DOMAIN_VGA) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+
+#define BDW_DISPLAY_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PIPE_B) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_C) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_D_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_CRT) | /* DDI E */ \
+ BIT_ULL(POWER_DOMAIN_VGA) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+
+#define SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_C) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_D_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_E_LANES) | \
+ BIT_ULL(POWER_DOMAIN_AUX_B) | \
+ BIT_ULL(POWER_DOMAIN_AUX_C) | \
+ BIT_ULL(POWER_DOMAIN_AUX_D) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO) | \
+ BIT_ULL(POWER_DOMAIN_VGA) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define SKL_DISPLAY_DDI_IO_A_E_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_A_IO) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_E_IO) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define SKL_DISPLAY_DDI_IO_B_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_B_IO) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define SKL_DISPLAY_DDI_IO_C_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_C_IO) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define SKL_DISPLAY_DDI_IO_D_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_D_IO) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define SKL_DISPLAY_DC_OFF_POWER_DOMAINS ( \
+ SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS | \
+ BIT_ULL(POWER_DOMAIN_MODESET) | \
+ BIT_ULL(POWER_DOMAIN_AUX_A) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+
+#define BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_C) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
+ BIT_ULL(POWER_DOMAIN_AUX_B) | \
+ BIT_ULL(POWER_DOMAIN_AUX_C) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO) | \
+ BIT_ULL(POWER_DOMAIN_VGA) | \
+ BIT_ULL(POWER_DOMAIN_GMBUS) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define BXT_DISPLAY_DC_OFF_POWER_DOMAINS ( \
+ BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS | \
+ BIT_ULL(POWER_DOMAIN_MODESET) | \
+ BIT_ULL(POWER_DOMAIN_AUX_A) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define BXT_DPIO_CMN_A_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_A_LANES) | \
+ BIT_ULL(POWER_DOMAIN_AUX_A) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define BXT_DPIO_CMN_BC_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
+ BIT_ULL(POWER_DOMAIN_AUX_B) | \
+ BIT_ULL(POWER_DOMAIN_AUX_C) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+
+#define GLK_DISPLAY_POWERWELL_2_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_C) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
+ BIT_ULL(POWER_DOMAIN_AUX_B) | \
+ BIT_ULL(POWER_DOMAIN_AUX_C) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO) | \
+ BIT_ULL(POWER_DOMAIN_VGA) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define GLK_DISPLAY_DDI_IO_A_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_A_IO))
+#define GLK_DISPLAY_DDI_IO_B_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_B_IO))
+#define GLK_DISPLAY_DDI_IO_C_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_C_IO))
+#define GLK_DPIO_CMN_A_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_A_LANES) | \
+ BIT_ULL(POWER_DOMAIN_AUX_A) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define GLK_DPIO_CMN_B_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
+ BIT_ULL(POWER_DOMAIN_AUX_B) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define GLK_DPIO_CMN_C_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
+ BIT_ULL(POWER_DOMAIN_AUX_C) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define GLK_DISPLAY_AUX_A_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_AUX_A) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define GLK_DISPLAY_AUX_B_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_AUX_B) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define GLK_DISPLAY_AUX_C_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_AUX_C) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define GLK_DISPLAY_DC_OFF_POWER_DOMAINS ( \
+ GLK_DISPLAY_POWERWELL_2_POWER_DOMAINS | \
+ BIT_ULL(POWER_DOMAIN_MODESET) | \
+ BIT_ULL(POWER_DOMAIN_AUX_A) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+
+#define CNL_DISPLAY_POWERWELL_2_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_C) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_D_LANES) | \
+ BIT_ULL(POWER_DOMAIN_AUX_B) | \
+ BIT_ULL(POWER_DOMAIN_AUX_C) | \
+ BIT_ULL(POWER_DOMAIN_AUX_D) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO) | \
+ BIT_ULL(POWER_DOMAIN_VGA) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define CNL_DISPLAY_DDI_A_IO_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_A_IO) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define CNL_DISPLAY_DDI_B_IO_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_B_IO) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define CNL_DISPLAY_DDI_C_IO_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_C_IO) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define CNL_DISPLAY_DDI_D_IO_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_D_IO) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define CNL_DISPLAY_AUX_A_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_AUX_A) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define CNL_DISPLAY_AUX_B_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_AUX_B) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define CNL_DISPLAY_AUX_C_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_AUX_C) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define CNL_DISPLAY_AUX_D_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_AUX_D) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define CNL_DISPLAY_DC_OFF_POWER_DOMAINS ( \
+ CNL_DISPLAY_POWERWELL_2_POWER_DOMAINS | \
+ BIT_ULL(POWER_DOMAIN_MODESET) | \
+ BIT_ULL(POWER_DOMAIN_AUX_A) | \
BIT_ULL(POWER_DOMAIN_INIT))
static const struct i915_power_well_ops i9xx_always_on_power_well_ops = {
@@ -1997,6 +1862,7 @@ static struct i915_power_well i9xx_always_on_power_well[] = {
.always_on = 1,
.domains = POWER_DOMAIN_MASK,
.ops = &i9xx_always_on_power_well_ops,
+ .id = I915_DISP_PW_ALWAYS_ON,
},
};
@@ -2013,11 +1879,13 @@ static struct i915_power_well i830_power_wells[] = {
.always_on = 1,
.domains = POWER_DOMAIN_MASK,
.ops = &i9xx_always_on_power_well_ops,
+ .id = I915_DISP_PW_ALWAYS_ON,
},
{
.name = "pipes",
.domains = I830_PIPES_POWER_DOMAINS,
.ops = &i830_pipes_power_well_ops,
+ .id = I830_DISP_PW_PIPES,
},
};
@@ -2028,13 +1896,6 @@ static const struct i915_power_well_ops hsw_power_well_ops = {
.is_enabled = hsw_power_well_enabled,
};
-static const struct i915_power_well_ops skl_power_well_ops = {
- .sync_hw = skl_power_well_sync_hw,
- .enable = skl_power_well_enable,
- .disable = skl_power_well_disable,
- .is_enabled = skl_power_well_enabled,
-};
-
static const struct i915_power_well_ops gen9_dc_off_power_well_ops = {
.sync_hw = i9xx_power_well_sync_hw_noop,
.enable = gen9_dc_off_power_well_enable,
@@ -2055,11 +1916,16 @@ static struct i915_power_well hsw_power_wells[] = {
.always_on = 1,
.domains = POWER_DOMAIN_MASK,
.ops = &i9xx_always_on_power_well_ops,
+ .id = I915_DISP_PW_ALWAYS_ON,
},
{
.name = "display",
.domains = HSW_DISPLAY_POWER_DOMAINS,
.ops = &hsw_power_well_ops,
+ .id = HSW_DISP_PW_GLOBAL,
+ {
+ .hsw.has_vga = true,
+ },
},
};
@@ -2069,11 +1935,17 @@ static struct i915_power_well bdw_power_wells[] = {
.always_on = 1,
.domains = POWER_DOMAIN_MASK,
.ops = &i9xx_always_on_power_well_ops,
+ .id = I915_DISP_PW_ALWAYS_ON,
},
{
.name = "display",
.domains = BDW_DISPLAY_POWER_DOMAINS,
.ops = &hsw_power_well_ops,
+ .id = HSW_DISP_PW_GLOBAL,
+ {
+ .hsw.irq_pipe_mask = BIT(PIPE_B) | BIT(PIPE_C),
+ .hsw.has_vga = true,
+ },
},
};
@@ -2104,7 +1976,7 @@ static struct i915_power_well vlv_power_wells[] = {
.always_on = 1,
.domains = POWER_DOMAIN_MASK,
.ops = &i9xx_always_on_power_well_ops,
- .id = PUNIT_POWER_WELL_ALWAYS_ON,
+ .id = I915_DISP_PW_ALWAYS_ON,
},
{
.name = "display",
@@ -2162,6 +2034,7 @@ static struct i915_power_well chv_power_wells[] = {
.always_on = 1,
.domains = POWER_DOMAIN_MASK,
.ops = &i9xx_always_on_power_well_ops,
+ .id = I915_DISP_PW_ALWAYS_ON,
},
{
.name = "display",
@@ -2171,7 +2044,7 @@ static struct i915_power_well chv_power_wells[] = {
* required for any pipe to work.
*/
.domains = CHV_DISPLAY_POWER_DOMAINS,
- .id = PIPE_A,
+ .id = CHV_DISP_PW_PIPE_A,
.ops = &chv_pipe_power_well_ops,
},
{
@@ -2189,7 +2062,7 @@ static struct i915_power_well chv_power_wells[] = {
};
bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv,
- int power_well_id)
+ enum i915_power_well_id power_well_id)
{
struct i915_power_well *power_well;
bool ret;
@@ -2206,20 +2079,23 @@ static struct i915_power_well skl_power_wells[] = {
.always_on = 1,
.domains = POWER_DOMAIN_MASK,
.ops = &i9xx_always_on_power_well_ops,
- .id = SKL_DISP_PW_ALWAYS_ON,
+ .id = I915_DISP_PW_ALWAYS_ON,
},
{
.name = "power well 1",
/* Handled by the DMC firmware */
.domains = 0,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_1,
+ {
+ .hsw.has_fuses = true,
+ },
},
{
.name = "MISC IO power well",
/* Handled by the DMC firmware */
.domains = 0,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_MISC_IO,
},
{
@@ -2231,31 +2107,36 @@ static struct i915_power_well skl_power_wells[] = {
{
.name = "power well 2",
.domains = SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_2,
+ {
+ .hsw.irq_pipe_mask = BIT(PIPE_B) | BIT(PIPE_C),
+ .hsw.has_vga = true,
+ .hsw.has_fuses = true,
+ },
},
{
.name = "DDI A/E IO power well",
.domains = SKL_DISPLAY_DDI_IO_A_E_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_DDI_A_E,
},
{
.name = "DDI B IO power well",
.domains = SKL_DISPLAY_DDI_IO_B_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_DDI_B,
},
{
.name = "DDI C IO power well",
.domains = SKL_DISPLAY_DDI_IO_C_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_DDI_C,
},
{
.name = "DDI D IO power well",
.domains = SKL_DISPLAY_DDI_IO_D_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_DDI_D,
},
};
@@ -2266,12 +2147,16 @@ static struct i915_power_well bxt_power_wells[] = {
.always_on = 1,
.domains = POWER_DOMAIN_MASK,
.ops = &i9xx_always_on_power_well_ops,
+ .id = I915_DISP_PW_ALWAYS_ON,
},
{
.name = "power well 1",
.domains = 0,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_1,
+ {
+ .hsw.has_fuses = true,
+ },
},
{
.name = "DC off",
@@ -2282,22 +2167,31 @@ static struct i915_power_well bxt_power_wells[] = {
{
.name = "power well 2",
.domains = BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_2,
+ {
+ .hsw.irq_pipe_mask = BIT(PIPE_B) | BIT(PIPE_C),
+ .hsw.has_vga = true,
+ .hsw.has_fuses = true,
+ },
},
{
.name = "dpio-common-a",
.domains = BXT_DPIO_CMN_A_POWER_DOMAINS,
.ops = &bxt_dpio_cmn_power_well_ops,
.id = BXT_DPIO_CMN_A,
- .data = DPIO_PHY1,
+ {
+ .bxt.phy = DPIO_PHY1,
+ },
},
{
.name = "dpio-common-bc",
.domains = BXT_DPIO_CMN_BC_POWER_DOMAINS,
.ops = &bxt_dpio_cmn_power_well_ops,
.id = BXT_DPIO_CMN_BC,
- .data = DPIO_PHY0,
+ {
+ .bxt.phy = DPIO_PHY0,
+ },
},
};
@@ -2307,13 +2201,17 @@ static struct i915_power_well glk_power_wells[] = {
.always_on = 1,
.domains = POWER_DOMAIN_MASK,
.ops = &i9xx_always_on_power_well_ops,
+ .id = I915_DISP_PW_ALWAYS_ON,
},
{
.name = "power well 1",
/* Handled by the DMC firmware */
.domains = 0,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_1,
+ {
+ .hsw.has_fuses = true,
+ },
},
{
.name = "DC off",
@@ -2324,64 +2222,75 @@ static struct i915_power_well glk_power_wells[] = {
{
.name = "power well 2",
.domains = GLK_DISPLAY_POWERWELL_2_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_2,
+ {
+ .hsw.irq_pipe_mask = BIT(PIPE_B) | BIT(PIPE_C),
+ .hsw.has_vga = true,
+ .hsw.has_fuses = true,
+ },
},
{
.name = "dpio-common-a",
.domains = GLK_DPIO_CMN_A_POWER_DOMAINS,
.ops = &bxt_dpio_cmn_power_well_ops,
.id = BXT_DPIO_CMN_A,
- .data = DPIO_PHY1,
+ {
+ .bxt.phy = DPIO_PHY1,
+ },
},
{
.name = "dpio-common-b",
.domains = GLK_DPIO_CMN_B_POWER_DOMAINS,
.ops = &bxt_dpio_cmn_power_well_ops,
.id = BXT_DPIO_CMN_BC,
- .data = DPIO_PHY0,
+ {
+ .bxt.phy = DPIO_PHY0,
+ },
},
{
.name = "dpio-common-c",
.domains = GLK_DPIO_CMN_C_POWER_DOMAINS,
.ops = &bxt_dpio_cmn_power_well_ops,
.id = GLK_DPIO_CMN_C,
- .data = DPIO_PHY2,
+ {
+ .bxt.phy = DPIO_PHY2,
+ },
},
{
.name = "AUX A",
.domains = GLK_DISPLAY_AUX_A_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = GLK_DISP_PW_AUX_A,
},
{
.name = "AUX B",
.domains = GLK_DISPLAY_AUX_B_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = GLK_DISP_PW_AUX_B,
},
{
.name = "AUX C",
.domains = GLK_DISPLAY_AUX_C_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = GLK_DISP_PW_AUX_C,
},
{
.name = "DDI A IO power well",
.domains = GLK_DISPLAY_DDI_IO_A_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = GLK_DISP_PW_DDI_A,
},
{
.name = "DDI B IO power well",
.domains = GLK_DISPLAY_DDI_IO_B_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_DDI_B,
},
{
.name = "DDI C IO power well",
.domains = GLK_DISPLAY_DDI_IO_C_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_DDI_C,
},
};
@@ -2392,36 +2301,40 @@ static struct i915_power_well cnl_power_wells[] = {
.always_on = 1,
.domains = POWER_DOMAIN_MASK,
.ops = &i9xx_always_on_power_well_ops,
+ .id = I915_DISP_PW_ALWAYS_ON,
},
{
.name = "power well 1",
/* Handled by the DMC firmware */
.domains = 0,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_1,
+ {
+ .hsw.has_fuses = true,
+ },
},
{
.name = "AUX A",
.domains = CNL_DISPLAY_AUX_A_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = CNL_DISP_PW_AUX_A,
},
{
.name = "AUX B",
.domains = CNL_DISPLAY_AUX_B_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = CNL_DISP_PW_AUX_B,
},
{
.name = "AUX C",
.domains = CNL_DISPLAY_AUX_C_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = CNL_DISP_PW_AUX_C,
},
{
.name = "AUX D",
.domains = CNL_DISPLAY_AUX_D_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = CNL_DISP_PW_AUX_D,
},
{
@@ -2433,31 +2346,36 @@ static struct i915_power_well cnl_power_wells[] = {
{
.name = "power well 2",
.domains = CNL_DISPLAY_POWERWELL_2_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_2,
+ {
+ .hsw.irq_pipe_mask = BIT(PIPE_B) | BIT(PIPE_C),
+ .hsw.has_vga = true,
+ .hsw.has_fuses = true,
+ },
},
{
.name = "DDI A IO power well",
.domains = CNL_DISPLAY_DDI_A_IO_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = CNL_DISP_PW_DDI_A,
},
{
.name = "DDI B IO power well",
.domains = CNL_DISPLAY_DDI_B_IO_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_DDI_B,
},
{
.name = "DDI C IO power well",
.domains = CNL_DISPLAY_DDI_C_IO_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_DDI_C,
},
{
.name = "DDI D IO power well",
.domains = CNL_DISPLAY_DDI_D_IO_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_DDI_D,
},
};
@@ -2479,7 +2397,7 @@ static uint32_t get_allowed_dc_mask(const struct drm_i915_private *dev_priv,
int requested_dc;
int max_dc;
- if (IS_GEN9_BC(dev_priv)) {
+ if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
max_dc = 2;
mask = 0;
} else if (IS_GEN9_LP(dev_priv)) {
@@ -2521,6 +2439,22 @@ static uint32_t get_allowed_dc_mask(const struct drm_i915_private *dev_priv,
return mask;
}
+static void assert_power_well_ids_unique(struct drm_i915_private *dev_priv)
+{
+ struct i915_power_domains *power_domains = &dev_priv->power_domains;
+ u64 power_well_ids;
+ int i;
+
+ power_well_ids = 0;
+ for (i = 0; i < power_domains->power_well_count; i++) {
+ enum i915_power_well_id id = power_domains->power_wells[i].id;
+
+ WARN_ON(id >= sizeof(power_well_ids) * 8);
+ WARN_ON(power_well_ids & BIT_ULL(id));
+ power_well_ids |= BIT_ULL(id);
+ }
+}
+
#define set_power_wells(power_domains, __power_wells) ({ \
(power_domains)->power_wells = (__power_wells); \
(power_domains)->power_well_count = ARRAY_SIZE(__power_wells); \
@@ -2572,6 +2506,8 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
set_power_wells(power_domains, i9xx_always_on_power_well);
}
+ assert_power_well_ids_unique(dev_priv);
+
return 0;
}
@@ -2694,13 +2630,18 @@ static void skl_display_core_uninit(struct drm_i915_private *dev_priv)
mutex_lock(&power_domains->lock);
- well = lookup_power_well(dev_priv, SKL_DISP_PW_MISC_IO);
- intel_power_well_disable(dev_priv, well);
-
+ /*
+ * BSpec says to keep the MISC IO power well enabled here, only
+ * remove our request for power well 1.
+ * Note that even though the driver's request is removed power well 1
+ * may stay enabled after this due to DMC's own request on it.
+ */
well = lookup_power_well(dev_priv, SKL_DISP_PW_1);
intel_power_well_disable(dev_priv, well);
mutex_unlock(&power_domains->lock);
+
+ usleep_range(10, 30); /* 10 us delay per Bspec */
}
void bxt_display_core_init(struct drm_i915_private *dev_priv,
@@ -2751,13 +2692,19 @@ void bxt_display_core_uninit(struct drm_i915_private *dev_priv)
/* The spec doesn't call for removing the reset handshake flag */
- /* Disable PG1 */
+ /*
+ * Disable PW1 (PG1).
+ * Note that even though the driver's request is removed power well 1
+ * may stay enabled after this due to DMC's own request on it.
+ */
mutex_lock(&power_domains->lock);
well = lookup_power_well(dev_priv, SKL_DISP_PW_1);
intel_power_well_disable(dev_priv, well);
mutex_unlock(&power_domains->lock);
+
+ usleep_range(10, 30); /* 10 us delay per Bspec */
}
#define CNL_PROCMON_IDX(val) \
@@ -2796,7 +2743,7 @@ static void cnl_display_core_init(struct drm_i915_private *dev_priv, bool resume
/* 2. Enable Comp */
val = I915_READ(CHICKEN_MISC_2);
- val &= ~COMP_PWR_DOWN;
+ val &= ~CNL_COMP_PWR_DOWN;
I915_WRITE(CHICKEN_MISC_2, val);
val = I915_READ(CNL_PORT_COMP_DW3);
@@ -2821,7 +2768,10 @@ static void cnl_display_core_init(struct drm_i915_private *dev_priv, bool resume
val |= CL_POWER_DOWN_ENABLE;
I915_WRITE(CNL_PORT_CL1CM_DW5, val);
- /* 4. Enable Power Well 1 (PG1) and Aux IO Power */
+ /*
+ * 4. Enable Power Well 1 (PG1).
+ * The AUX IO power wells will be enabled on demand.
+ */
mutex_lock(&power_domains->lock);
well = lookup_power_well(dev_priv, SKL_DISP_PW_1);
intel_power_well_enable(dev_priv, well);
@@ -2853,15 +2803,21 @@ static void cnl_display_core_uninit(struct drm_i915_private *dev_priv)
/* 3. Disable CD clock */
cnl_uninit_cdclk(dev_priv);
- /* 4. Disable Power Well 1 (PG1) and Aux IO Power */
+ /*
+ * 4. Disable Power Well 1 (PG1).
+ * The AUX IO power wells are toggled on demand, so they are already
+ * disabled at this point.
+ */
mutex_lock(&power_domains->lock);
well = lookup_power_well(dev_priv, SKL_DISP_PW_1);
intel_power_well_disable(dev_priv, well);
mutex_unlock(&power_domains->lock);
+ usleep_range(10, 30); /* 10 us delay per Bspec */
+
/* 5. Disable Comp */
val = I915_READ(CHICKEN_MISC_2);
- val |= COMP_PWR_DOWN;
+ val |= CNL_COMP_PWR_DOWN;
I915_WRITE(CHICKEN_MISC_2, val);
}
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 3f8f30b..3dc38c2 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -451,23 +451,24 @@ static const char * const cmd_status_names[] = {
"Scaling not supported"
};
-static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd,
- const void *args, int args_len)
+static bool __intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd,
+ const void *args, int args_len,
+ bool unlocked)
{
u8 *buf, status;
struct i2c_msg *msgs;
int i, ret = true;
- /* Would be simpler to allocate both in one go ? */
+ /* Would be simpler to allocate both in one go ? */
buf = kzalloc(args_len * 2 + 2, GFP_KERNEL);
if (!buf)
return false;
msgs = kcalloc(args_len + 3, sizeof(*msgs), GFP_KERNEL);
if (!msgs) {
- kfree(buf);
+ kfree(buf);
return false;
- }
+ }
intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len);
@@ -498,7 +499,10 @@ static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd,
msgs[i+2].len = 1;
msgs[i+2].buf = &status;
- ret = i2c_transfer(intel_sdvo->i2c, msgs, i+3);
+ if (unlocked)
+ ret = i2c_transfer(intel_sdvo->i2c, msgs, i+3);
+ else
+ ret = __i2c_transfer(intel_sdvo->i2c, msgs, i+3);
if (ret < 0) {
DRM_DEBUG_KMS("I2c transfer returned %d\n", ret);
ret = false;
@@ -516,6 +520,12 @@ out:
return ret;
}
+static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd,
+ const void *args, int args_len)
+{
+ return __intel_sdvo_write_cmd(intel_sdvo, cmd, args, args_len, true);
+}
+
static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo,
void *response, int response_len)
{
@@ -602,13 +612,13 @@ static int intel_sdvo_get_pixel_multiplier(const struct drm_display_mode *adjust
return 4;
}
-static bool intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo,
- u8 ddc_bus)
+static bool __intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo,
+ u8 ddc_bus)
{
/* This must be the immediately preceding write before the i2c xfer */
- return intel_sdvo_write_cmd(intel_sdvo,
- SDVO_CMD_SET_CONTROL_BUS_SWITCH,
- &ddc_bus, 1);
+ return __intel_sdvo_write_cmd(intel_sdvo,
+ SDVO_CMD_SET_CONTROL_BUS_SWITCH,
+ &ddc_bus, 1, false);
}
static bool intel_sdvo_set_value(struct intel_sdvo *intel_sdvo, u8 cmd, const void *data, int len)
@@ -996,7 +1006,8 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo,
ssize_t len;
ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
- &pipe_config->base.adjusted_mode);
+ &pipe_config->base.adjusted_mode,
+ false);
if (ret < 0) {
DRM_ERROR("couldn't fill AVI infoframe\n");
return false;
@@ -1343,13 +1354,15 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
sdvox |= (9 << 19) | SDVO_BORDER_ENABLE;
}
- if (INTEL_PCH_TYPE(dev_priv) >= PCH_CPT)
+ if (HAS_PCH_CPT(dev_priv))
sdvox |= SDVO_PIPE_SEL_CPT(crtc->pipe);
else
sdvox |= SDVO_PIPE_SEL(crtc->pipe);
- if (crtc_state->has_audio)
+ if (crtc_state->has_audio) {
+ WARN_ON_ONCE(INTEL_GEN(dev_priv) < 4);
sdvox |= SDVO_AUDIO_ENABLE;
+ }
if (INTEL_GEN(dev_priv) >= 4) {
/* done in crtc_mode_set as the dpll_md reg must be written early */
@@ -1479,6 +1492,9 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder,
if (sdvox & HDMI_COLOR_RANGE_16_235)
pipe_config->limited_color_range = true;
+ if (sdvox & SDVO_AUDIO_ENABLE)
+ pipe_config->has_audio = true;
+
if (intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ENCODE,
&val, 1)) {
if (val == SDVO_ENCODE_HDMI)
@@ -2192,10 +2208,8 @@ intel_sdvo_connector_duplicate_state(struct drm_connector *connector)
}
static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = intel_sdvo_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
- .set_property = drm_atomic_helper_connector_set_property,
.atomic_get_property = intel_sdvo_connector_atomic_get_property,
.atomic_set_property = intel_sdvo_connector_atomic_set_property,
.late_register = intel_sdvo_connector_register,
@@ -2454,6 +2468,7 @@ static bool
intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
{
struct drm_encoder *encoder = &intel_sdvo->base.base;
+ struct drm_i915_private *dev_priv = to_i915(encoder->dev);
struct drm_connector *connector;
struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
struct intel_connector *intel_connector;
@@ -2489,7 +2504,9 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
encoder->encoder_type = DRM_MODE_ENCODER_TMDS;
connector->connector_type = DRM_MODE_CONNECTOR_DVID;
- if (intel_sdvo_is_hdmi_connector(intel_sdvo, device)) {
+ /* gen3 doesn't do the hdmi bits in the SDVO register */
+ if (INTEL_GEN(dev_priv) >= 4 &&
+ intel_sdvo_is_hdmi_connector(intel_sdvo, device)) {
connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
intel_sdvo->is_hdmi = true;
}
@@ -2925,7 +2942,7 @@ static int intel_sdvo_ddc_proxy_xfer(struct i2c_adapter *adapter,
{
struct intel_sdvo *sdvo = adapter->algo_data;
- if (!intel_sdvo_set_control_bus_switch(sdvo, sdvo->ddc_bus))
+ if (!__intel_sdvo_set_control_bus_switch(sdvo, sdvo->ddc_bus))
return -EIO;
return sdvo->i2c->algo->master_xfer(sdvo->i2c, msgs, num);
@@ -2942,6 +2959,33 @@ static const struct i2c_algorithm intel_sdvo_ddc_proxy = {
.functionality = intel_sdvo_ddc_proxy_func
};
+static void proxy_lock_bus(struct i2c_adapter *adapter,
+ unsigned int flags)
+{
+ struct intel_sdvo *sdvo = adapter->algo_data;
+ sdvo->i2c->lock_ops->lock_bus(sdvo->i2c, flags);
+}
+
+static int proxy_trylock_bus(struct i2c_adapter *adapter,
+ unsigned int flags)
+{
+ struct intel_sdvo *sdvo = adapter->algo_data;
+ return sdvo->i2c->lock_ops->trylock_bus(sdvo->i2c, flags);
+}
+
+static void proxy_unlock_bus(struct i2c_adapter *adapter,
+ unsigned int flags)
+{
+ struct intel_sdvo *sdvo = adapter->algo_data;
+ sdvo->i2c->lock_ops->unlock_bus(sdvo->i2c, flags);
+}
+
+const struct i2c_lock_operations proxy_lock_ops = {
+ .lock_bus = proxy_lock_bus,
+ .trylock_bus = proxy_trylock_bus,
+ .unlock_bus = proxy_unlock_bus,
+};
+
static bool
intel_sdvo_init_ddc_proxy(struct intel_sdvo *sdvo,
struct drm_i915_private *dev_priv)
@@ -2954,6 +2998,7 @@ intel_sdvo_init_ddc_proxy(struct intel_sdvo *sdvo,
sdvo->ddc.dev.parent = &pdev->dev;
sdvo->ddc.algo_data = sdvo;
sdvo->ddc.algo = &intel_sdvo_ddc_proxy;
+ sdvo->ddc.lock_ops = &proxy_lock_ops;
return i2c_add_adapter(&sdvo->ddc) == 0;
}
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 0c650c2..524933b 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -30,6 +30,7 @@
* support.
*/
#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_rect.h>
@@ -176,7 +177,7 @@ void intel_pipe_update_start(struct intel_crtc *crtc)
* re-enables interrupts and verifies the update was actually completed
* before a vblank using the value of @start_vbl_count.
*/
-void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work)
+void intel_pipe_update_end(struct intel_crtc *crtc)
{
enum pipe pipe = crtc->pipe;
int scanline_end = intel_get_crtc_scanline(crtc);
@@ -184,12 +185,6 @@ void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work
ktime_t end_vbl_time = ktime_get();
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
- if (work) {
- work->flip_queued_vblank = end_vbl_count;
- smp_mb__before_atomic();
- atomic_set(&work->pending, 1);
- }
-
trace_i915_pipe_update_end(crtc, end_vbl_count, scanline_end);
/* We're still in the vblank-evade critical section, this can't race.
@@ -244,6 +239,7 @@ skl_update_plane(struct intel_plane *plane,
u32 surf_addr = plane_state->main.offset;
unsigned int rotation = plane_state->base.rotation;
u32 stride = skl_plane_stride(fb, 0, rotation);
+ u32 aux_stride = skl_plane_stride(fb, 1, rotation);
int crtc_x = plane_state->base.dst.x1;
int crtc_y = plane_state->base.dst.y1;
uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
@@ -262,7 +258,7 @@ skl_update_plane(struct intel_plane *plane,
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
- if (IS_GEMINILAKE(dev_priv)) {
+ if (IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) {
I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
PLANE_COLOR_PIPE_GAMMA_ENABLE |
PLANE_COLOR_PIPE_CSC_ENABLE |
@@ -278,6 +274,10 @@ skl_update_plane(struct intel_plane *plane,
I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride);
I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
+ I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id),
+ (plane_state->aux.offset - surf_addr) | aux_stride);
+ I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
+ (plane_state->aux.y << 16) | plane_state->aux.x);
/* program plane scaler */
if (plane_state->scaler_id >= 0) {
@@ -1038,6 +1038,12 @@ static const uint32_t g4x_plane_formats[] = {
DRM_FORMAT_VYUY,
};
+static const uint64_t i9xx_plane_format_modifiers[] = {
+ I915_FORMAT_MOD_X_TILED,
+ DRM_FORMAT_MOD_LINEAR,
+ DRM_FORMAT_MOD_INVALID
+};
+
static const uint32_t snb_plane_formats[] = {
DRM_FORMAT_XBGR8888,
DRM_FORMAT_XRGB8888,
@@ -1073,6 +1079,122 @@ static uint32_t skl_plane_formats[] = {
DRM_FORMAT_VYUY,
};
+static const uint64_t skl_plane_format_modifiers[] = {
+ I915_FORMAT_MOD_X_TILED,
+ DRM_FORMAT_MOD_LINEAR,
+ DRM_FORMAT_MOD_INVALID
+};
+
+static bool g4x_sprite_plane_format_mod_supported(struct drm_plane *plane,
+ uint32_t format,
+ uint64_t modifier)
+{
+ switch (format) {
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_YVYU:
+ case DRM_FORMAT_UYVY:
+ case DRM_FORMAT_VYUY:
+ if (modifier == DRM_FORMAT_MOD_LINEAR ||
+ modifier == I915_FORMAT_MOD_X_TILED)
+ return true;
+ /* fall through */
+ default:
+ return false;
+ }
+}
+
+static bool vlv_sprite_plane_format_mod_supported(struct drm_plane *plane,
+ uint32_t format,
+ uint64_t modifier)
+{
+ switch (format) {
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_YVYU:
+ case DRM_FORMAT_UYVY:
+ case DRM_FORMAT_VYUY:
+ case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_ARGB8888:
+ case DRM_FORMAT_XBGR2101010:
+ case DRM_FORMAT_ABGR2101010:
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_ABGR8888:
+ if (modifier == DRM_FORMAT_MOD_LINEAR ||
+ modifier == I915_FORMAT_MOD_X_TILED)
+ return true;
+ /* fall through */
+ default:
+ return false;
+ }
+}
+
+static bool skl_sprite_plane_format_mod_supported(struct drm_plane *plane,
+ uint32_t format,
+ uint64_t modifier)
+{
+ /* This is the same as primary plane since SKL has universal planes */
+ switch (format) {
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_ARGB8888:
+ case DRM_FORMAT_ABGR8888:
+ case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_XRGB2101010:
+ case DRM_FORMAT_XBGR2101010:
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_YVYU:
+ case DRM_FORMAT_UYVY:
+ case DRM_FORMAT_VYUY:
+ if (modifier == I915_FORMAT_MOD_Yf_TILED)
+ return true;
+ /* fall through */
+ case DRM_FORMAT_C8:
+ if (modifier == DRM_FORMAT_MOD_LINEAR ||
+ modifier == I915_FORMAT_MOD_X_TILED ||
+ modifier == I915_FORMAT_MOD_Y_TILED)
+ return true;
+ /* fall through */
+ default:
+ return false;
+ }
+}
+
+static bool intel_sprite_plane_format_mod_supported(struct drm_plane *plane,
+ uint32_t format,
+ uint64_t modifier)
+{
+ struct drm_i915_private *dev_priv = to_i915(plane->dev);
+
+ if (WARN_ON(modifier == DRM_FORMAT_MOD_INVALID))
+ return false;
+
+ if ((modifier >> 56) != DRM_FORMAT_MOD_VENDOR_INTEL &&
+ modifier != DRM_FORMAT_MOD_LINEAR)
+ return false;
+
+ if (INTEL_GEN(dev_priv) >= 9)
+ return skl_sprite_plane_format_mod_supported(plane, format, modifier);
+ else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+ return vlv_sprite_plane_format_mod_supported(plane, format, modifier);
+ else
+ return g4x_sprite_plane_format_mod_supported(plane, format, modifier);
+
+ unreachable();
+}
+
+static const struct drm_plane_funcs intel_sprite_plane_funcs = {
+ .update_plane = drm_atomic_helper_update_plane,
+ .disable_plane = drm_atomic_helper_disable_plane,
+ .destroy = intel_plane_destroy,
+ .atomic_get_property = intel_plane_atomic_get_property,
+ .atomic_set_property = intel_plane_atomic_set_property,
+ .atomic_duplicate_state = intel_plane_duplicate_state,
+ .atomic_destroy_state = intel_plane_destroy_state,
+ .format_mod_supported = intel_sprite_plane_format_mod_supported,
+};
+
struct intel_plane *
intel_sprite_plane_create(struct drm_i915_private *dev_priv,
enum pipe pipe, int plane)
@@ -1081,6 +1203,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
struct intel_plane_state *state = NULL;
unsigned long possible_crtcs;
const uint32_t *plane_formats;
+ const uint64_t *modifiers;
unsigned int supported_rotations;
int num_plane_formats;
int ret;
@@ -1098,7 +1221,17 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
}
intel_plane->base.state = &state->base;
- if (INTEL_GEN(dev_priv) >= 9) {
+ if (INTEL_GEN(dev_priv) >= 10) {
+ intel_plane->can_scale = true;
+ state->scaler_id = -1;
+
+ intel_plane->update_plane = skl_update_plane;
+ intel_plane->disable_plane = skl_disable_plane;
+
+ plane_formats = skl_plane_formats;
+ num_plane_formats = ARRAY_SIZE(skl_plane_formats);
+ modifiers = skl_plane_format_modifiers;
+ } else if (INTEL_GEN(dev_priv) >= 9) {
intel_plane->can_scale = true;
state->scaler_id = -1;
@@ -1107,6 +1240,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
plane_formats = skl_plane_formats;
num_plane_formats = ARRAY_SIZE(skl_plane_formats);
+ modifiers = skl_plane_format_modifiers;
} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
intel_plane->can_scale = false;
intel_plane->max_downscale = 1;
@@ -1116,6 +1250,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
plane_formats = vlv_plane_formats;
num_plane_formats = ARRAY_SIZE(vlv_plane_formats);
+ modifiers = i9xx_plane_format_modifiers;
} else if (INTEL_GEN(dev_priv) >= 7) {
if (IS_IVYBRIDGE(dev_priv)) {
intel_plane->can_scale = true;
@@ -1130,6 +1265,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
plane_formats = snb_plane_formats;
num_plane_formats = ARRAY_SIZE(snb_plane_formats);
+ modifiers = i9xx_plane_format_modifiers;
} else {
intel_plane->can_scale = true;
intel_plane->max_downscale = 16;
@@ -1137,6 +1273,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
intel_plane->update_plane = g4x_update_plane;
intel_plane->disable_plane = g4x_disable_plane;
+ modifiers = i9xx_plane_format_modifiers;
if (IS_GEN6(dev_priv)) {
plane_formats = snb_plane_formats;
num_plane_formats = ARRAY_SIZE(snb_plane_formats);
@@ -1169,14 +1306,16 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
if (INTEL_GEN(dev_priv) >= 9)
ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base,
- possible_crtcs, &intel_plane_funcs,
+ possible_crtcs, &intel_sprite_plane_funcs,
plane_formats, num_plane_formats,
+ modifiers,
DRM_PLANE_TYPE_OVERLAY,
"plane %d%c", plane + 2, pipe_name(pipe));
else
ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base,
- possible_crtcs, &intel_plane_funcs,
+ possible_crtcs, &intel_sprite_plane_funcs,
plane_formats, num_plane_formats,
+ modifiers,
DRM_PLANE_TYPE_OVERLAY,
"sprite %c", sprite_name(pipe, plane));
if (ret)
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 784df02..906893c 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1407,11 +1407,9 @@ intel_tv_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs intel_tv_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.late_register = intel_connector_register,
.early_unregister = intel_connector_unregister,
.destroy = intel_tv_destroy,
- .set_property = drm_atomic_helper_connector_set_property,
.fill_modes = drm_helper_probe_single_connector_modes,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c
index 27e072c..0178ba4 100644
--- a/drivers/gpu/drm/i915/intel_uc.c
+++ b/drivers/gpu/drm/i915/intel_uc.c
@@ -94,7 +94,7 @@ void intel_uc_sanitize_options(struct drm_i915_private *dev_priv)
i915.enable_guc_submission = HAS_GUC_SCHED(dev_priv);
}
-static void guc_write_irq_trigger(struct intel_guc *guc)
+static void gen8_guc_raise_irq(struct intel_guc *guc)
{
struct drm_i915_private *dev_priv = guc_to_i915(guc);
@@ -109,7 +109,7 @@ void intel_uc_init_early(struct drm_i915_private *dev_priv)
mutex_init(&guc->send_mutex);
guc->send = intel_guc_send_nop;
- guc->notify = guc_write_irq_trigger;
+ guc->notify = gen8_guc_raise_irq;
}
static void fetch_uc_fw(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 9882724..1d7b879 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -643,7 +643,7 @@ find_fw_domain(struct drm_i915_private *dev_priv, u32 offset)
{ .start = (s), .end = (e), .domains = (d) }
#define HAS_FWTABLE(dev_priv) \
- (IS_GEN9(dev_priv) || \
+ (INTEL_GEN(dev_priv) >= 9 || \
IS_CHERRYVIEW(dev_priv) || \
IS_VALLEYVIEW(dev_priv))
@@ -1072,7 +1072,7 @@ static void intel_uncore_fw_domains_init(struct drm_i915_private *dev_priv)
dev_priv->uncore.fw_clear = _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL);
}
- if (IS_GEN9(dev_priv)) {
+ if (INTEL_GEN(dev_priv) >= 9) {
dev_priv->uncore.funcs.force_wake_get = fw_domains_get;
dev_priv->uncore.funcs.force_wake_put = fw_domains_put;
fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
@@ -1497,7 +1497,6 @@ static int gen6_reset_engines(struct drm_i915_private *dev_priv,
[VECS] = GEN6_GRDOM_VECS,
};
u32 hw_mask;
- int ret;
if (engine_mask == ALL_ENGINES) {
hw_mask = GEN6_GRDOM_FULL;
@@ -1509,11 +1508,7 @@ static int gen6_reset_engines(struct drm_i915_private *dev_priv,
hw_mask |= hw_engine_mask[engine->id];
}
- ret = gen6_hw_domain_reset(dev_priv, hw_mask);
-
- intel_uncore_forcewake_reset(dev_priv, true);
-
- return ret;
+ return gen6_hw_domain_reset(dev_priv, hw_mask);
}
/**
@@ -1719,6 +1714,17 @@ bool intel_has_gpu_reset(struct drm_i915_private *dev_priv)
return intel_get_gpu_reset(dev_priv) != NULL;
}
+/*
+ * When GuC submission is enabled, GuC manages ELSP and can initiate the
+ * engine reset too. For now, fall back to full GPU reset if it is enabled.
+ */
+bool intel_has_reset_engine(struct drm_i915_private *dev_priv)
+{
+ return (dev_priv->info.has_reset_engine &&
+ !dev_priv->guc.execbuf_client &&
+ i915.reset >= 2);
+}
+
int intel_guc_reset(struct drm_i915_private *dev_priv)
{
int ret;
diff --git a/drivers/gpu/drm/i915/selftests/huge_gem_object.c b/drivers/gpu/drm/i915/selftests/huge_gem_object.c
index caf76af..c5c7e8e 100644
--- a/drivers/gpu/drm/i915/selftests/huge_gem_object.c
+++ b/drivers/gpu/drm/i915/selftests/huge_gem_object.c
@@ -111,6 +111,7 @@ huge_gem_object(struct drm_i915_private *i915,
dma_addr_t dma_size)
{
struct drm_i915_gem_object *obj;
+ unsigned int cache_level;
GEM_BUG_ON(!phys_size || phys_size > dma_size);
GEM_BUG_ON(!IS_ALIGNED(phys_size, PAGE_SIZE));
@@ -128,9 +129,8 @@ huge_gem_object(struct drm_i915_private *i915,
obj->base.read_domains = I915_GEM_DOMAIN_CPU;
obj->base.write_domain = I915_GEM_DOMAIN_CPU;
- obj->cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE;
- obj->cache_coherent = i915_gem_object_is_coherent(obj);
- obj->cache_dirty = !obj->cache_coherent;
+ cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE;
+ i915_gem_object_set_cache_coherency(obj, cache_level);
obj->scratch = phys_size;
return obj;
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_coherency.c b/drivers/gpu/drm/i915/selftests/i915_gem_coherency.c
index 95d4aeb..35d778d 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_coherency.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_coherency.c
@@ -241,7 +241,7 @@ static bool always_valid(struct drm_i915_private *i915)
static bool needs_mi_store_dword(struct drm_i915_private *i915)
{
- return igt_can_mi_store_dword_imm(i915);
+ return intel_engine_can_store_dword(i915->engine[RCS]);
}
static const struct igt_coherency_mode {
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/selftests/i915_gem_context.c
index 12b85b3..fb0a58f 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_context.c
@@ -38,8 +38,6 @@ gpu_fill_dw(struct i915_vma *vma, u64 offset, unsigned long count, u32 value)
u32 *cmd;
int err;
- GEM_BUG_ON(!igt_can_mi_store_dword_imm(vma->vm->i915));
-
size = (4 * count + 1) * sizeof(u32);
size = round_up(size, PAGE_SIZE);
obj = i915_gem_object_create_internal(vma->vm->i915, size);
@@ -123,6 +121,7 @@ static int gpu_fill(struct drm_i915_gem_object *obj,
int err;
GEM_BUG_ON(obj->base.size > vm->total);
+ GEM_BUG_ON(!intel_engine_can_store_dword(engine));
vma = i915_vma_instance(obj, vm, NULL);
if (IS_ERR(vma))
@@ -359,6 +358,9 @@ static int igt_ctx_exec(void *arg)
}
for_each_engine(engine, i915, id) {
+ if (!intel_engine_can_store_dword(engine))
+ continue;
+
if (!obj) {
obj = create_test_object(ctx, file, &objects);
if (IS_ERR(obj)) {
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index 50710e3..6b132ca 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -197,6 +197,9 @@ static int lowlevel_hole(struct drm_i915_private *i915,
{
I915_RND_STATE(seed_prng);
unsigned int size;
+ struct i915_vma mock_vma;
+
+ memset(&mock_vma, 0, sizeof(struct i915_vma));
/* Keep creating larger objects until one cannot fit into the hole */
for (size = 12; (hole_end - hole_start) >> size; size++) {
@@ -255,8 +258,11 @@ static int lowlevel_hole(struct drm_i915_private *i915,
vm->allocate_va_range(vm, addr, BIT_ULL(size)))
break;
- vm->insert_entries(vm, obj->mm.pages, addr,
- I915_CACHE_NONE, 0);
+ mock_vma.pages = obj->mm.pages;
+ mock_vma.node.size = BIT_ULL(size);
+ mock_vma.node.start = addr;
+
+ vm->insert_entries(vm, &mock_vma, I915_CACHE_NONE, 0);
}
count = n;
diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c
index fb9072d..2e86ec1 100644
--- a/drivers/gpu/drm/i915/selftests/i915_vma.c
+++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
@@ -186,16 +186,20 @@ static int igt_vma_create(void *arg)
goto end;
}
- list_for_each_entry_safe(ctx, cn, &contexts, link)
+ list_for_each_entry_safe(ctx, cn, &contexts, link) {
+ list_del_init(&ctx->link);
mock_context_close(ctx);
+ }
}
end:
/* Final pass to lookup all created contexts */
err = create_vmas(i915, &objects, &contexts);
out:
- list_for_each_entry_safe(ctx, cn, &contexts, link)
+ list_for_each_entry_safe(ctx, cn, &contexts, link) {
+ list_del_init(&ctx->link);
mock_context_close(ctx);
+ }
list_for_each_entry_safe(obj, on, &objects, st_link)
i915_gem_object_put(obj);
diff --git a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c
index aa31d6c..02e52a1 100644
--- a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c
+++ b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c
@@ -22,8 +22,13 @@
*
*/
+#include <linux/kthread.h>
+
#include "../i915_selftest.h"
+#include "mock_context.h"
+#include "mock_drm.h"
+
struct hang {
struct drm_i915_private *i915;
struct drm_i915_gem_object *hws;
@@ -248,9 +253,6 @@ static int igt_hang_sanitycheck(void *arg)
/* Basic check that we can execute our hanging batch */
- if (!igt_can_mi_store_dword_imm(i915))
- return 0;
-
mutex_lock(&i915->drm.struct_mutex);
err = hang_init(&h, i915);
if (err)
@@ -259,6 +261,9 @@ static int igt_hang_sanitycheck(void *arg)
for_each_engine(engine, i915, id) {
long timeout;
+ if (!intel_engine_can_store_dword(engine))
+ continue;
+
rq = hang_create_request(&h, engine, i915->kernel_context);
if (IS_ERR(rq)) {
err = PTR_ERR(rq);
@@ -292,6 +297,37 @@ unlock:
return err;
}
+static void global_reset_lock(struct drm_i915_private *i915)
+{
+ struct intel_engine_cs *engine;
+ enum intel_engine_id id;
+
+ while (test_and_set_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags))
+ wait_event(i915->gpu_error.reset_queue,
+ !test_bit(I915_RESET_BACKOFF,
+ &i915->gpu_error.flags));
+
+ for_each_engine(engine, i915, id) {
+ while (test_and_set_bit(I915_RESET_ENGINE + id,
+ &i915->gpu_error.flags))
+ wait_on_bit(&i915->gpu_error.flags,
+ I915_RESET_ENGINE + id,
+ TASK_UNINTERRUPTIBLE);
+ }
+}
+
+static void global_reset_unlock(struct drm_i915_private *i915)
+{
+ struct intel_engine_cs *engine;
+ enum intel_engine_id id;
+
+ for_each_engine(engine, i915, id)
+ clear_bit(I915_RESET_ENGINE + id, &i915->gpu_error.flags);
+
+ clear_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags);
+ wake_up_all(&i915->gpu_error.reset_queue);
+}
+
static int igt_global_reset(void *arg)
{
struct drm_i915_private *i915 = arg;
@@ -300,13 +336,13 @@ static int igt_global_reset(void *arg)
/* Check that we can issue a global GPU reset */
- set_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags);
+ global_reset_lock(i915);
set_bit(I915_RESET_HANDOFF, &i915->gpu_error.flags);
mutex_lock(&i915->drm.struct_mutex);
reset_count = i915_reset_count(&i915->gpu_error);
- i915_reset(i915);
+ i915_reset(i915, I915_RESET_QUIET);
if (i915_reset_count(&i915->gpu_error) == reset_count) {
pr_err("No GPU reset recorded!\n");
@@ -315,7 +351,214 @@ static int igt_global_reset(void *arg)
mutex_unlock(&i915->drm.struct_mutex);
GEM_BUG_ON(test_bit(I915_RESET_HANDOFF, &i915->gpu_error.flags));
- clear_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags);
+ global_reset_unlock(i915);
+
+ if (i915_terminally_wedged(&i915->gpu_error))
+ err = -EIO;
+
+ return err;
+}
+
+static int igt_reset_engine(void *arg)
+{
+ struct drm_i915_private *i915 = arg;
+ struct intel_engine_cs *engine;
+ enum intel_engine_id id;
+ unsigned int reset_count, reset_engine_count;
+ int err = 0;
+
+ /* Check that we can issue a global GPU and engine reset */
+
+ if (!intel_has_reset_engine(i915))
+ return 0;
+
+ for_each_engine(engine, i915, id) {
+ set_bit(I915_RESET_ENGINE + engine->id, &i915->gpu_error.flags);
+ reset_count = i915_reset_count(&i915->gpu_error);
+ reset_engine_count = i915_reset_engine_count(&i915->gpu_error,
+ engine);
+
+ err = i915_reset_engine(engine, I915_RESET_QUIET);
+ if (err) {
+ pr_err("i915_reset_engine failed\n");
+ break;
+ }
+
+ if (i915_reset_count(&i915->gpu_error) != reset_count) {
+ pr_err("Full GPU reset recorded! (engine reset expected)\n");
+ err = -EINVAL;
+ break;
+ }
+
+ if (i915_reset_engine_count(&i915->gpu_error, engine) ==
+ reset_engine_count) {
+ pr_err("No %s engine reset recorded!\n", engine->name);
+ err = -EINVAL;
+ break;
+ }
+
+ clear_bit(I915_RESET_ENGINE + engine->id,
+ &i915->gpu_error.flags);
+ }
+
+ if (i915_terminally_wedged(&i915->gpu_error))
+ err = -EIO;
+
+ return err;
+}
+
+static int active_engine(void *data)
+{
+ struct intel_engine_cs *engine = data;
+ struct drm_i915_gem_request *rq[2] = {};
+ struct i915_gem_context *ctx[2];
+ struct drm_file *file;
+ unsigned long count = 0;
+ int err = 0;
+
+ file = mock_file(engine->i915);
+ if (IS_ERR(file))
+ return PTR_ERR(file);
+
+ mutex_lock(&engine->i915->drm.struct_mutex);
+ ctx[0] = live_context(engine->i915, file);
+ mutex_unlock(&engine->i915->drm.struct_mutex);
+ if (IS_ERR(ctx[0])) {
+ err = PTR_ERR(ctx[0]);
+ goto err_file;
+ }
+
+ mutex_lock(&engine->i915->drm.struct_mutex);
+ ctx[1] = live_context(engine->i915, file);
+ mutex_unlock(&engine->i915->drm.struct_mutex);
+ if (IS_ERR(ctx[1])) {
+ err = PTR_ERR(ctx[1]);
+ i915_gem_context_put(ctx[0]);
+ goto err_file;
+ }
+
+ while (!kthread_should_stop()) {
+ unsigned int idx = count++ & 1;
+ struct drm_i915_gem_request *old = rq[idx];
+ struct drm_i915_gem_request *new;
+
+ mutex_lock(&engine->i915->drm.struct_mutex);
+ new = i915_gem_request_alloc(engine, ctx[idx]);
+ if (IS_ERR(new)) {
+ mutex_unlock(&engine->i915->drm.struct_mutex);
+ err = PTR_ERR(new);
+ break;
+ }
+
+ rq[idx] = i915_gem_request_get(new);
+ i915_add_request(new);
+ mutex_unlock(&engine->i915->drm.struct_mutex);
+
+ if (old) {
+ i915_wait_request(old, 0, MAX_SCHEDULE_TIMEOUT);
+ i915_gem_request_put(old);
+ }
+ }
+
+ for (count = 0; count < ARRAY_SIZE(rq); count++)
+ i915_gem_request_put(rq[count]);
+
+err_file:
+ mock_file_free(engine->i915, file);
+ return err;
+}
+
+static int igt_reset_active_engines(void *arg)
+{
+ struct drm_i915_private *i915 = arg;
+ struct intel_engine_cs *engine, *active;
+ enum intel_engine_id id, tmp;
+ int err = 0;
+
+ /* Check that issuing a reset on one engine does not interfere
+ * with any other engine.
+ */
+
+ if (!intel_has_reset_engine(i915))
+ return 0;
+
+ for_each_engine(engine, i915, id) {
+ struct task_struct *threads[I915_NUM_ENGINES];
+ unsigned long resets[I915_NUM_ENGINES];
+ unsigned long global = i915_reset_count(&i915->gpu_error);
+ IGT_TIMEOUT(end_time);
+
+ memset(threads, 0, sizeof(threads));
+ for_each_engine(active, i915, tmp) {
+ struct task_struct *tsk;
+
+ if (active == engine)
+ continue;
+
+ resets[tmp] = i915_reset_engine_count(&i915->gpu_error,
+ active);
+
+ tsk = kthread_run(active_engine, active,
+ "igt/%s", active->name);
+ if (IS_ERR(tsk)) {
+ err = PTR_ERR(tsk);
+ goto unwind;
+ }
+
+ threads[tmp] = tsk;
+ get_task_struct(tsk);
+ }
+
+ set_bit(I915_RESET_ENGINE + engine->id, &i915->gpu_error.flags);
+ do {
+ err = i915_reset_engine(engine, I915_RESET_QUIET);
+ if (err) {
+ pr_err("i915_reset_engine(%s) failed, err=%d\n",
+ engine->name, err);
+ break;
+ }
+ } while (time_before(jiffies, end_time));
+ clear_bit(I915_RESET_ENGINE + engine->id,
+ &i915->gpu_error.flags);
+
+unwind:
+ for_each_engine(active, i915, tmp) {
+ int ret;
+
+ if (!threads[tmp])
+ continue;
+
+ ret = kthread_stop(threads[tmp]);
+ if (ret) {
+ pr_err("kthread for active engine %s failed, err=%d\n",
+ active->name, ret);
+ if (!err)
+ err = ret;
+ }
+ put_task_struct(threads[tmp]);
+
+ if (resets[tmp] != i915_reset_engine_count(&i915->gpu_error,
+ active)) {
+ pr_err("Innocent engine %s was reset (count=%ld)\n",
+ active->name,
+ i915_reset_engine_count(&i915->gpu_error,
+ active) - resets[tmp]);
+ err = -EIO;
+ }
+ }
+
+ if (global != i915_reset_count(&i915->gpu_error)) {
+ pr_err("Global reset (count=%ld)!\n",
+ i915_reset_count(&i915->gpu_error) - global);
+ err = -EIO;
+ }
+
+ if (err)
+ break;
+
+ cond_resched();
+ }
+
if (i915_terminally_wedged(&i915->gpu_error))
err = -EIO;
@@ -356,9 +599,12 @@ static int igt_wait_reset(void *arg)
long timeout;
int err;
+ if (!intel_engine_can_store_dword(i915->engine[RCS]))
+ return 0;
+
/* Check that we detect a stuck waiter and issue a reset */
- set_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags);
+ global_reset_lock(i915);
mutex_lock(&i915->drm.struct_mutex);
err = hang_init(&h, i915);
@@ -403,7 +649,7 @@ fini:
hang_fini(&h);
unlock:
mutex_unlock(&i915->drm.struct_mutex);
- clear_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags);
+ global_reset_unlock(i915);
if (i915_terminally_wedged(&i915->gpu_error))
return -EIO;
@@ -421,10 +667,8 @@ static int igt_reset_queue(void *arg)
/* Check that we replay pending requests following a hang */
- if (!igt_can_mi_store_dword_imm(i915))
- return 0;
+ global_reset_lock(i915);
- set_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags);
mutex_lock(&i915->drm.struct_mutex);
err = hang_init(&h, i915);
if (err)
@@ -435,6 +679,9 @@ static int igt_reset_queue(void *arg)
IGT_TIMEOUT(end_time);
unsigned int count;
+ if (!intel_engine_can_store_dword(engine))
+ continue;
+
prev = hang_create_request(&h, engine, i915->kernel_context);
if (IS_ERR(prev)) {
err = PTR_ERR(prev);
@@ -471,7 +718,7 @@ static int igt_reset_queue(void *arg)
reset_count = fake_hangcheck(prev);
- i915_reset(i915);
+ i915_reset(i915, I915_RESET_QUIET);
GEM_BUG_ON(test_bit(I915_RESET_HANDOFF,
&i915->gpu_error.flags));
@@ -518,7 +765,7 @@ fini:
hang_fini(&h);
unlock:
mutex_unlock(&i915->drm.struct_mutex);
- clear_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags);
+ global_reset_unlock(i915);
if (i915_terminally_wedged(&i915->gpu_error))
return -EIO;
@@ -526,13 +773,83 @@ unlock:
return err;
}
+static int igt_handle_error(void *arg)
+{
+ struct drm_i915_private *i915 = arg;
+ struct intel_engine_cs *engine = i915->engine[RCS];
+ struct hang h;
+ struct drm_i915_gem_request *rq;
+ struct i915_gpu_state *error;
+ int err;
+
+ /* Check that we can issue a global GPU and engine reset */
+
+ if (!intel_has_reset_engine(i915))
+ return 0;
+
+ if (!intel_engine_can_store_dword(i915->engine[RCS]))
+ return 0;
+
+ mutex_lock(&i915->drm.struct_mutex);
+
+ err = hang_init(&h, i915);
+ if (err)
+ goto err_unlock;
+
+ rq = hang_create_request(&h, engine, i915->kernel_context);
+ if (IS_ERR(rq)) {
+ err = PTR_ERR(rq);
+ goto err_fini;
+ }
+
+ i915_gem_request_get(rq);
+ __i915_add_request(rq, true);
+
+ if (!wait_for_hang(&h, rq)) {
+ pr_err("Failed to start request %x\n", rq->fence.seqno);
+ err = -EIO;
+ goto err_request;
+ }
+
+ mutex_unlock(&i915->drm.struct_mutex);
+
+ /* Temporarily disable error capture */
+ error = xchg(&i915->gpu_error.first_error, (void *)-1);
+
+ engine->hangcheck.stalled = true;
+ engine->hangcheck.seqno = intel_engine_get_seqno(engine);
+
+ i915_handle_error(i915, intel_engine_flag(engine), "%s", __func__);
+
+ xchg(&i915->gpu_error.first_error, error);
+
+ mutex_lock(&i915->drm.struct_mutex);
+
+ if (rq->fence.error != -EIO) {
+ pr_err("Guilty request not identified!\n");
+ err = -EINVAL;
+ goto err_request;
+ }
+
+err_request:
+ i915_gem_request_put(rq);
+err_fini:
+ hang_fini(&h);
+err_unlock:
+ mutex_unlock(&i915->drm.struct_mutex);
+ return err;
+}
+
int intel_hangcheck_live_selftests(struct drm_i915_private *i915)
{
static const struct i915_subtest tests[] = {
SUBTEST(igt_hang_sanitycheck),
SUBTEST(igt_global_reset),
+ SUBTEST(igt_reset_engine),
+ SUBTEST(igt_reset_active_engines),
SUBTEST(igt_wait_reset),
SUBTEST(igt_reset_queue),
+ SUBTEST(igt_handle_error),
};
if (!intel_has_gpu_reset(i915))
diff --git a/drivers/gpu/drm/i915/selftests/mock_context.c b/drivers/gpu/drm/i915/selftests/mock_context.c
index f8b9cc2..098ce64 100644
--- a/drivers/gpu/drm/i915/selftests/mock_context.c
+++ b/drivers/gpu/drm/i915/selftests/mock_context.c
@@ -40,18 +40,13 @@ mock_context(struct drm_i915_private *i915,
INIT_LIST_HEAD(&ctx->link);
ctx->i915 = i915;
- ctx->vma_lut.ht_bits = VMA_HT_BITS;
- ctx->vma_lut.ht_size = BIT(VMA_HT_BITS);
- ctx->vma_lut.ht = kcalloc(ctx->vma_lut.ht_size,
- sizeof(*ctx->vma_lut.ht),
- GFP_KERNEL);
- if (!ctx->vma_lut.ht)
- goto err_free;
-
- ret = ida_simple_get(&i915->context_hw_ida,
+ INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL);
+ INIT_LIST_HEAD(&ctx->handles_list);
+
+ ret = ida_simple_get(&i915->contexts.hw_ida,
0, MAX_CONTEXT_HW_ID, GFP_KERNEL);
if (ret < 0)
- goto err_vma_ht;
+ goto err_handles;
ctx->hw_id = ret;
if (name) {
@@ -66,9 +61,7 @@ mock_context(struct drm_i915_private *i915,
return ctx;
-err_vma_ht:
- kvfree(ctx->vma_lut.ht);
-err_free:
+err_handles:
kfree(ctx);
return NULL;
@@ -86,3 +79,20 @@ void mock_context_close(struct i915_gem_context *ctx)
i915_gem_context_put(ctx);
}
+
+void mock_init_contexts(struct drm_i915_private *i915)
+{
+ INIT_LIST_HEAD(&i915->contexts.list);
+ ida_init(&i915->contexts.hw_ida);
+
+ INIT_WORK(&i915->contexts.free_work, contexts_free_worker);
+ init_llist_head(&i915->contexts.free_list);
+}
+
+struct i915_gem_context *
+live_context(struct drm_i915_private *i915, struct drm_file *file)
+{
+ lockdep_assert_held(&i915->drm.struct_mutex);
+
+ return i915_gem_create_context(i915, file->driver_priv);
+}
diff --git a/drivers/gpu/drm/i915/selftests/mock_context.h b/drivers/gpu/drm/i915/selftests/mock_context.h
index 2427e5c..2f432c0 100644
--- a/drivers/gpu/drm/i915/selftests/mock_context.h
+++ b/drivers/gpu/drm/i915/selftests/mock_context.h
@@ -25,10 +25,15 @@
#ifndef __MOCK_CONTEXT_H
#define __MOCK_CONTEXT_H
+void mock_init_contexts(struct drm_i915_private *i915);
+
struct i915_gem_context *
mock_context(struct drm_i915_private *i915,
const char *name);
void mock_context_close(struct i915_gem_context *ctx);
+struct i915_gem_context *
+live_context(struct drm_i915_private *i915, struct drm_file *file);
+
#endif /* !__MOCK_CONTEXT_H */
diff --git a/drivers/gpu/drm/i915/selftests/mock_engine.c b/drivers/gpu/drm/i915/selftests/mock_engine.c
index 5b18a2d..fc0fd74 100644
--- a/drivers/gpu/drm/i915/selftests/mock_engine.c
+++ b/drivers/gpu/drm/i915/selftests/mock_engine.c
@@ -123,10 +123,12 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
}
struct intel_engine_cs *mock_engine(struct drm_i915_private *i915,
- const char *name)
+ const char *name,
+ int id)
{
struct mock_engine *engine;
- static int id;
+
+ GEM_BUG_ON(id >= I915_NUM_ENGINES);
engine = kzalloc(sizeof(*engine) + PAGE_SIZE, GFP_KERNEL);
if (!engine)
@@ -141,7 +143,7 @@ struct intel_engine_cs *mock_engine(struct drm_i915_private *i915,
/* minimal engine setup for requests */
engine->base.i915 = i915;
snprintf(engine->base.name, sizeof(engine->base.name), "%s", name);
- engine->base.id = id++;
+ engine->base.id = id;
engine->base.status_page.page_addr = (void *)(engine + 1);
engine->base.context_pin = mock_context_pin;
diff --git a/drivers/gpu/drm/i915/selftests/mock_engine.h b/drivers/gpu/drm/i915/selftests/mock_engine.h
index e5e2402..133d0c2 100644
--- a/drivers/gpu/drm/i915/selftests/mock_engine.h
+++ b/drivers/gpu/drm/i915/selftests/mock_engine.h
@@ -40,7 +40,8 @@ struct mock_engine {
};
struct intel_engine_cs *mock_engine(struct drm_i915_private *i915,
- const char *name);
+ const char *name,
+ int id);
void mock_engine_flush(struct intel_engine_cs *engine);
void mock_engine_reset(struct intel_engine_cs *engine);
void mock_engine_free(struct intel_engine_cs *engine);
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index 8cdec45..6787234 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -22,6 +22,7 @@
*
*/
+#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
#include "mock_engine.h"
@@ -53,15 +54,17 @@ static void mock_device_release(struct drm_device *dev)
mutex_lock(&i915->drm.struct_mutex);
mock_device_flush(i915);
+ i915_gem_contexts_lost(i915);
mutex_unlock(&i915->drm.struct_mutex);
cancel_delayed_work_sync(&i915->gt.retire_work);
cancel_delayed_work_sync(&i915->gt.idle_work);
+ i915_gem_drain_workqueue(i915);
mutex_lock(&i915->drm.struct_mutex);
for_each_engine(engine, i915, id)
mock_engine_free(engine);
- i915_gem_context_fini(i915);
+ i915_gem_contexts_fini(i915);
mutex_unlock(&i915->drm.struct_mutex);
drain_workqueue(i915->wq);
@@ -108,6 +111,23 @@ static void mock_idle_work_handler(struct work_struct *work)
{
}
+static int pm_domain_resume(struct device *dev)
+{
+ return pm_generic_runtime_resume(dev);
+}
+
+static int pm_domain_suspend(struct device *dev)
+{
+ return pm_generic_runtime_suspend(dev);
+}
+
+static struct dev_pm_domain pm_domain = {
+ .ops = {
+ .runtime_suspend = pm_domain_suspend,
+ .runtime_resume = pm_domain_resume,
+ },
+};
+
struct drm_i915_private *mock_gem_device(void)
{
struct drm_i915_private *i915;
@@ -126,8 +146,10 @@ struct drm_i915_private *mock_gem_device(void)
dev_set_name(&pdev->dev, "mock");
dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ dev_pm_domain_set(&pdev->dev, &pm_domain);
+ pm_runtime_enable(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
- pm_runtime_get_sync(&pdev->dev);
+ WARN_ON(pm_runtime_get_sync(&pdev->dev));
i915 = (struct drm_i915_private *)(pdev + 1);
pci_set_drvdata(pdev, i915);
@@ -160,7 +182,7 @@ struct drm_i915_private *mock_gem_device(void)
INIT_LIST_HEAD(&i915->mm.unbound_list);
INIT_LIST_HEAD(&i915->mm.bound_list);
- ida_init(&i915->context_hw_ida);
+ mock_init_contexts(i915);
INIT_DELAYED_WORK(&i915->gt.retire_work, mock_retire_work_handler);
INIT_DELAYED_WORK(&i915->gt.idle_work, mock_idle_work_handler);
@@ -204,7 +226,7 @@ struct drm_i915_private *mock_gem_device(void)
mutex_unlock(&i915->drm.struct_mutex);
mkwrite_device_info(i915)->ring_mask = BIT(0);
- i915->engine[RCS] = mock_engine(i915, "mock");
+ i915->engine[RCS] = mock_engine(i915, "mock", RCS);
if (!i915->engine[RCS])
goto err_priorities;
diff --git a/drivers/gpu/drm/i915/selftests/mock_gtt.c b/drivers/gpu/drm/i915/selftests/mock_gtt.c
index a61309c..f2118cf 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gtt.c
@@ -33,8 +33,7 @@ static void mock_insert_page(struct i915_address_space *vm,
}
static void mock_insert_entries(struct i915_address_space *vm,
- struct sg_table *st,
- u64 start,
+ struct i915_vma *vma,
enum i915_cache_level level, u32 flags)
{
}
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
index 95e2181..f91cb72 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -115,7 +115,7 @@ static void imx_drm_atomic_commit_tail(struct drm_atomic_state *state)
{
struct drm_device *dev = state->dev;
struct drm_plane *plane;
- struct drm_plane_state *old_plane_state;
+ struct drm_plane_state *old_plane_state, *new_plane_state;
bool plane_disabling = false;
int i;
@@ -127,15 +127,15 @@ static void imx_drm_atomic_commit_tail(struct drm_atomic_state *state)
drm_atomic_helper_commit_modeset_enables(dev, state);
- for_each_plane_in_state(state, plane, old_plane_state, i) {
- if (drm_atomic_plane_disabling(old_plane_state, plane->state))
+ for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
+ if (drm_atomic_plane_disabling(old_plane_state, new_plane_state))
plane_disabling = true;
}
if (plane_disabling) {
drm_atomic_helper_wait_for_vblanks(dev, state);
- for_each_plane_in_state(state, plane, old_plane_state, i)
+ for_each_old_plane_in_state(state, plane, old_plane_state, i)
ipu_plane_disable_deferred(plane);
}
@@ -182,8 +182,6 @@ static struct drm_driver imx_drm_driver = {
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index 8b05ecb..56dd7a9 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -389,7 +389,6 @@ static int imx_ldb_encoder_atomic_check(struct drm_encoder *encoder,
static const struct drm_connector_funcs imx_ldb_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = imx_drm_connector_destroy,
.reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c
index 4826bb7..bc27c26 100644
--- a/drivers/gpu/drm/imx/imx-tve.c
+++ b/drivers/gpu/drm/imx/imx-tve.c
@@ -341,7 +341,6 @@ static int imx_tve_atomic_check(struct drm_encoder *encoder,
}
static const struct drm_connector_funcs imx_tve_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = imx_drm_connector_destroy,
.reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c
index 5456c15..53e0b24 100644
--- a/drivers/gpu/drm/imx/ipuv3-crtc.c
+++ b/drivers/gpu/drm/imx/ipuv3-crtc.c
@@ -50,7 +50,8 @@ static inline struct ipu_crtc *to_ipu_crtc(struct drm_crtc *crtc)
return container_of(crtc, struct ipu_crtc, base);
}
-static void ipu_crtc_enable(struct drm_crtc *crtc)
+static void ipu_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
@@ -293,7 +294,7 @@ static const struct drm_crtc_helper_funcs ipu_helper_funcs = {
.atomic_check = ipu_crtc_atomic_check,
.atomic_begin = ipu_crtc_atomic_begin,
.atomic_disable = ipu_crtc_atomic_disable,
- .enable = ipu_crtc_enable,
+ .atomic_enable = ipu_crtc_atomic_enable,
};
static void ipu_put_resources(struct ipu_crtc *ipu_crtc)
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c
index d384598..cf98596 100644
--- a/drivers/gpu/drm/imx/ipuv3-plane.c
+++ b/drivers/gpu/drm/imx/ipuv3-plane.c
@@ -496,6 +496,27 @@ static int ipu_chan_assign_axi_id(int ipu_chan)
}
}
+static void ipu_calculate_bursts(u32 width, u32 cpp, u32 stride,
+ u8 *burstsize, u8 *num_bursts)
+{
+ const unsigned int width_bytes = width * cpp;
+ unsigned int npb, bursts;
+
+ /* Maximum number of pixels per burst without overshooting stride */
+ for (npb = 64 / cpp; npb > 0; --npb) {
+ if (round_up(width_bytes, npb * cpp) <= stride)
+ break;
+ }
+ *burstsize = npb;
+
+ /* Maximum number of consecutive bursts without overshooting stride */
+ for (bursts = 8; bursts > 1; bursts /= 2) {
+ if (round_up(width_bytes, npb * cpp * bursts) <= stride)
+ break;
+ }
+ *num_bursts = bursts;
+}
+
static void ipu_plane_atomic_update(struct drm_plane *plane,
struct drm_plane_state *old_state)
{
@@ -509,6 +530,9 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
unsigned long alpha_eba = 0;
enum ipu_color_space ics;
unsigned int axi_id = 0;
+ const struct drm_format_info *info;
+ u8 burstsize, num_bursts;
+ u32 width, height;
int active;
if (ipu_plane->dp_flow == IPU_DP_FLOW_SYNC_FG)
@@ -525,8 +549,8 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
ipu_prg_channel_configure(ipu_plane->ipu_ch, axi_id,
drm_rect_width(&state->src) >> 16,
drm_rect_height(&state->src) >> 16,
- state->fb->pitches[0],
- state->fb->format->format, &eba);
+ fb->pitches[0],
+ fb->format->format, &eba);
}
if (old_state->fb && !drm_atomic_crtc_needs_modeset(crtc_state)) {
@@ -555,7 +579,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
ipu_dp_setup_channel(ipu_plane->dp, ics,
IPUV3_COLORSPACE_UNKNOWN);
/* Enable local alpha on partial plane */
- switch (state->fb->format->format) {
+ switch (fb->format->format) {
case DRM_FORMAT_ARGB1555:
case DRM_FORMAT_ABGR1555:
case DRM_FORMAT_RGBA5551:
@@ -581,15 +605,21 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
ipu_dmfc_config_wait4eot(ipu_plane->dmfc, drm_rect_width(dst));
+ width = drm_rect_width(&state->src) >> 16;
+ height = drm_rect_height(&state->src) >> 16;
+ info = drm_format_info(fb->format->format);
+ ipu_calculate_bursts(width, info->cpp[0], fb->pitches[0],
+ &burstsize, &num_bursts);
+
ipu_cpmem_zero(ipu_plane->ipu_ch);
- ipu_cpmem_set_resolution(ipu_plane->ipu_ch,
- drm_rect_width(&state->src) >> 16,
- drm_rect_height(&state->src) >> 16);
- ipu_cpmem_set_fmt(ipu_plane->ipu_ch, state->fb->format->format);
+ ipu_cpmem_set_resolution(ipu_plane->ipu_ch, width, height);
+ ipu_cpmem_set_fmt(ipu_plane->ipu_ch, fb->format->format);
+ ipu_cpmem_set_burstsize(ipu_plane->ipu_ch, burstsize);
ipu_cpmem_set_high_priority(ipu_plane->ipu_ch);
ipu_idmac_set_double_buffer(ipu_plane->ipu_ch, 1);
- ipu_cpmem_set_stride(ipu_plane->ipu_ch, state->fb->pitches[0]);
+ ipu_cpmem_set_stride(ipu_plane->ipu_ch, fb->pitches[0]);
ipu_cpmem_set_axi_id(ipu_plane->ipu_ch, axi_id);
+
switch (fb->format->format) {
case DRM_FORMAT_YUV420:
case DRM_FORMAT_YVU420:
@@ -629,6 +659,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
case DRM_FORMAT_RGBX8888_A8:
case DRM_FORMAT_BGRX8888_A8:
alpha_eba = drm_plane_state_to_eba(state, 1);
+ num_bursts = 0;
dev_dbg(ipu_plane->base.dev->dev, "phys = %lu %lu, x = %d, y = %d",
eba, alpha_eba, state->src.x1 >> 16, state->src.y1 >> 16);
@@ -642,8 +673,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
ipu_cpmem_set_format_passthrough(ipu_plane->alpha_ch, 8);
ipu_cpmem_set_high_priority(ipu_plane->alpha_ch);
ipu_idmac_set_double_buffer(ipu_plane->alpha_ch, 1);
- ipu_cpmem_set_stride(ipu_plane->alpha_ch,
- state->fb->pitches[1]);
+ ipu_cpmem_set_stride(ipu_plane->alpha_ch, fb->pitches[1]);
ipu_cpmem_set_burstsize(ipu_plane->alpha_ch, 16);
ipu_cpmem_set_buffer(ipu_plane->alpha_ch, 0, alpha_eba);
ipu_cpmem_set_buffer(ipu_plane->alpha_ch, 1, alpha_eba);
@@ -655,6 +685,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
}
ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 0, eba);
ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 1, eba);
+ ipu_idmac_lock_enable(ipu_plane->ipu_ch, num_bursts);
ipu_plane_enable(ipu_plane);
}
@@ -673,7 +704,7 @@ int ipu_planes_assign_pre(struct drm_device *dev,
int available_pres = ipu_prg_max_active_channels();
int i;
- for_each_plane_in_state(state, plane, plane_state, i) {
+ for_each_new_plane_in_state(state, plane, plane_state, i) {
struct ipu_plane_state *ipu_state =
to_ipu_plane_state(plane_state);
struct ipu_plane *ipu_plane = to_ipu_plane(plane);
@@ -716,8 +747,8 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
ret = drm_universal_plane_init(dev, &ipu_plane->base, possible_crtcs,
&ipu_plane_funcs, ipu_plane_formats,
- ARRAY_SIZE(ipu_plane_formats), type,
- NULL);
+ ARRAY_SIZE(ipu_plane_formats),
+ NULL, type, NULL);
if (ret) {
DRM_ERROR("failed to initialize plane\n");
kfree(ipu_plane);
diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c
index 8aca202..8def97d 100644
--- a/drivers/gpu/drm/imx/parallel-display.c
+++ b/drivers/gpu/drm/imx/parallel-display.c
@@ -135,7 +135,6 @@ static int imx_pd_encoder_atomic_check(struct drm_encoder *encoder,
}
static const struct drm_connector_funcs imx_pd_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = imx_drm_connector_destroy,
.reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_color.c b/drivers/gpu/drm/mediatek/mtk_disp_color.c
index ef79a6d..f609b62 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_color.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_color.c
@@ -84,8 +84,8 @@ static int mtk_disp_color_bind(struct device *dev, struct device *master,
ret = mtk_ddp_comp_register(drm_dev, &priv->ddp_comp);
if (ret < 0) {
- dev_err(dev, "Failed to register component %s: %d\n",
- dev->of_node->full_name, ret);
+ dev_err(dev, "Failed to register component %pOF: %d\n",
+ dev->of_node, ret);
return ret;
}
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 35bc5ba..978782a 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -235,8 +235,8 @@ static int mtk_disp_ovl_bind(struct device *dev, struct device *master,
ret = mtk_ddp_comp_register(drm_dev, &priv->ddp_comp);
if (ret < 0) {
- dev_err(dev, "Failed to register component %s: %d\n",
- dev->of_node->full_name, ret);
+ dev_err(dev, "Failed to register component %pOF: %d\n",
+ dev->of_node, ret);
return ret;
}
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index b68a513..585943c 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -155,8 +155,8 @@ static int mtk_disp_rdma_bind(struct device *dev, struct device *master,
ret = mtk_ddp_comp_register(drm_dev, &priv->ddp_comp);
if (ret < 0) {
- dev_err(dev, "Failed to register component %s: %d\n",
- dev->of_node->full_name, ret);
+ dev_err(dev, "Failed to register component %pOF: %d\n",
+ dev->of_node, ret);
return ret;
}
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 32ca351..e80a603 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -605,8 +605,8 @@ static int mtk_dpi_bind(struct device *dev, struct device *master, void *data)
ret = mtk_ddp_comp_register(drm_dev, &dpi->ddp_comp);
if (ret < 0) {
- dev_err(dev, "Failed to register component %s: %d\n",
- dev->of_node->full_name, ret);
+ dev_err(dev, "Failed to register component %pOF: %d\n",
+ dev->of_node, ret);
return ret;
}
@@ -710,7 +710,7 @@ static int mtk_dpi_probe(struct platform_device *pdev)
if (!bridge_node)
return -ENODEV;
- dev_info(dev, "Found bridge node: %s\n", bridge_node->full_name);
+ dev_info(dev, "Found bridge node: %pOF\n", bridge_node);
dpi->bridge = of_drm_find_bridge(bridge_node);
of_node_put(bridge_node);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index cb32c93..658b8dd 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -366,7 +366,8 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
}
}
-static void mtk_drm_crtc_enable(struct drm_crtc *crtc)
+static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0];
@@ -390,7 +391,8 @@ static void mtk_drm_crtc_enable(struct drm_crtc *crtc)
mtk_crtc->enabled = true;
}
-static void mtk_drm_crtc_disable(struct drm_crtc *crtc)
+static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0];
@@ -487,10 +489,10 @@ static const struct drm_crtc_funcs mtk_crtc_funcs = {
static const struct drm_crtc_helper_funcs mtk_crtc_helper_funcs = {
.mode_fixup = mtk_drm_crtc_mode_fixup,
.mode_set_nofb = mtk_drm_crtc_mode_set_nofb,
- .enable = mtk_drm_crtc_enable,
- .disable = mtk_drm_crtc_disable,
.atomic_begin = mtk_drm_crtc_atomic_begin,
.atomic_flush = mtk_drm_crtc_atomic_flush,
+ .atomic_enable = mtk_drm_crtc_atomic_enable,
+ .atomic_disable = mtk_drm_crtc_atomic_disable,
};
static int mtk_drm_crtc_init(struct drm_device *drm,
@@ -577,8 +579,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
node = priv->comp_node[comp_id];
comp = priv->ddp_comp[comp_id];
if (!comp) {
- dev_err(dev, "Component %s not initialized\n",
- node->full_name);
+ dev_err(dev, "Component %pOF not initialized\n", node);
ret = -ENODEV;
goto unprepare;
}
@@ -586,8 +587,8 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
ret = clk_prepare(comp->clk);
if (ret) {
dev_err(dev,
- "Failed to prepare clock for component %s: %d\n",
- node->full_name, ret);
+ "Failed to prepare clock for component %pOF: %d\n",
+ node, ret);
goto unprepare;
}
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 07d7ea2..4672317 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -295,15 +295,13 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node,
larb_node = of_parse_phandle(node, "mediatek,larb", 0);
if (!larb_node) {
dev_err(dev,
- "Missing mediadek,larb phandle in %s node\n",
- node->full_name);
+ "Missing mediadek,larb phandle in %pOF node\n", node);
return -EINVAL;
}
larb_pdev = of_find_device_by_node(larb_node);
if (!larb_pdev) {
- dev_warn(dev, "Waiting for larb device %s\n",
- larb_node->full_name);
+ dev_warn(dev, "Waiting for larb device %pOF\n", larb_node);
of_node_put(larb_node);
return -EPROBE_DEFER;
}
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 41d2cff..a2ca90f 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -48,11 +48,11 @@ static void mtk_atomic_schedule(struct mtk_drm_private *private,
static void mtk_atomic_wait_for_fences(struct drm_atomic_state *state)
{
struct drm_plane *plane;
- struct drm_plane_state *plane_state;
+ struct drm_plane_state *new_plane_state;
int i;
- for_each_plane_in_state(state, plane, plane_state, i)
- mtk_fb_wait(plane->state->fb);
+ for_each_new_plane_in_state(state, plane, new_plane_state, i)
+ mtk_fb_wait(new_plane_state->fb);
}
static void mtk_atomic_complete(struct mtk_drm_private *private,
@@ -109,7 +109,12 @@ static int mtk_atomic_commit(struct drm_device *drm,
mutex_lock(&private->commit.lock);
flush_work(&private->commit.work);
- drm_atomic_helper_swap_state(state, true);
+ ret = drm_atomic_helper_swap_state(state, true);
+ if (ret) {
+ mutex_unlock(&private->commit.lock);
+ drm_atomic_helper_cleanup_planes(drm, state);
+ return ret;
+ }
drm_atomic_state_get(state);
if (async)
@@ -187,8 +192,8 @@ static int mtk_drm_kms_init(struct drm_device *drm)
pdev = of_find_device_by_node(private->mutex_node);
if (!pdev) {
- dev_err(drm->dev, "Waiting for disp-mutex device %s\n",
- private->mutex_node->full_name);
+ dev_err(drm->dev, "Waiting for disp-mutex device %pOF\n",
+ private->mutex_node);
of_node_put(private->mutex_node);
return -EPROBE_DEFER;
}
@@ -266,7 +271,6 @@ static void mtk_drm_kms_deinit(struct drm_device *drm)
{
drm_kms_helper_poll_fini(drm);
- drm_vblank_cleanup(drm);
component_unbind_all(drm->dev, drm);
drm_mode_config_cleanup(drm);
}
@@ -289,8 +293,6 @@ static struct drm_driver mtk_drm_driver = {
.gem_free_object_unlocked = mtk_drm_gem_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = mtk_drm_gem_dumb_create,
- .dumb_map_offset = mtk_drm_gem_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
@@ -417,8 +419,8 @@ static int mtk_drm_probe(struct platform_device *pdev)
continue;
if (!of_device_is_available(node)) {
- dev_dbg(dev, "Skipping disabled component %s\n",
- node->full_name);
+ dev_dbg(dev, "Skipping disabled component %pOF\n",
+ node);
continue;
}
@@ -431,8 +433,8 @@ static int mtk_drm_probe(struct platform_device *pdev)
comp_id = mtk_ddp_comp_get_id(node, comp_type);
if (comp_id < 0) {
- dev_warn(dev, "Skipping unknown component %s\n",
- node->full_name);
+ dev_warn(dev, "Skipping unknown component %pOF\n",
+ node);
continue;
}
@@ -448,8 +450,8 @@ static int mtk_drm_probe(struct platform_device *pdev)
comp_type == MTK_DISP_RDMA ||
comp_type == MTK_DSI ||
comp_type == MTK_DPI) {
- dev_info(dev, "Adding component match for %s\n",
- node->full_name);
+ dev_info(dev, "Adding component match for %pOF\n",
+ node);
drm_of_component_match_add(dev, &match, compare_of,
node);
} else {
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_fb.c b/drivers/gpu/drm/mediatek/mtk_drm_fb.c
index d4246c9..0d8d506 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_fb.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_fb.c
@@ -58,7 +58,7 @@ static void mtk_drm_fb_destroy(struct drm_framebuffer *fb)
drm_framebuffer_cleanup(fb);
- drm_gem_object_unreference_unlocked(mtk_fb->gem_obj);
+ drm_gem_object_put_unlocked(mtk_fb->gem_obj);
kfree(mtk_fb);
}
@@ -160,6 +160,6 @@ struct drm_framebuffer *mtk_drm_mode_fb_create(struct drm_device *dev,
return &mtk_fb->base;
unreference:
- drm_gem_object_unreference_unlocked(gem);
+ drm_gem_object_put_unlocked(gem);
return ERR_PTR(ret);
}
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
index 7abc550..f595ac8 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
@@ -122,7 +122,7 @@ int mtk_drm_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
goto err_handle_create;
/* drop reference from allocate - handle holds it now. */
- drm_gem_object_unreference_unlocked(&mtk_gem->base);
+ drm_gem_object_put_unlocked(&mtk_gem->base);
return 0;
@@ -131,31 +131,6 @@ err_handle_create:
return ret;
}
-int mtk_drm_gem_dumb_map_offset(struct drm_file *file_priv,
- struct drm_device *dev, uint32_t handle,
- uint64_t *offset)
-{
- struct drm_gem_object *obj;
- int ret;
-
- obj = drm_gem_object_lookup(file_priv, handle);
- if (!obj) {
- DRM_ERROR("failed to lookup gem object.\n");
- return -EINVAL;
- }
-
- ret = drm_gem_create_mmap_offset(obj);
- if (ret)
- goto out;
-
- *offset = drm_vma_node_offset_addr(&obj->vma_node);
- DRM_DEBUG_KMS("offset = 0x%llx\n", *offset);
-
-out:
- drm_gem_object_unreference_unlocked(obj);
- return ret;
-}
-
static int mtk_drm_gem_object_mmap(struct drm_gem_object *obj,
struct vm_area_struct *vma)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.h b/drivers/gpu/drm/mediatek/mtk_drm_gem.h
index 2752718..534639b 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_gem.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.h
@@ -46,9 +46,6 @@ struct mtk_drm_gem_obj *mtk_drm_gem_create(struct drm_device *dev, size_t size,
bool alloc_kmap);
int mtk_drm_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
struct drm_mode_create_dumb *args);
-int mtk_drm_gem_dumb_map_offset(struct drm_file *file_priv,
- struct drm_device *dev, uint32_t handle,
- uint64_t *offset);
int mtk_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
int mtk_drm_gem_mmap_buf(struct drm_gem_object *obj,
struct vm_area_struct *vma);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
index 1a59b9a..6f12189 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
@@ -175,7 +175,7 @@ int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
err = drm_universal_plane_init(dev, plane, possible_crtcs,
&mtk_plane_funcs, formats,
- ARRAY_SIZE(formats), type, NULL);
+ ARRAY_SIZE(formats), NULL, type, NULL);
if (err) {
DRM_ERROR("failed to initialize plane\n");
return err;
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 97253c8..7e5e24c 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -766,7 +766,6 @@ static const struct drm_encoder_helper_funcs mtk_dsi_encoder_helper_funcs = {
};
static const struct drm_connector_funcs mtk_dsi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
.reset = drm_atomic_helper_connector_reset,
@@ -1048,8 +1047,8 @@ static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
ret = mtk_ddp_comp_register(drm, &dsi->ddp_comp);
if (ret < 0) {
- dev_err(dev, "Failed to register component %s: %d\n",
- dev->of_node->full_name, ret);
+ dev_err(dev, "Failed to register component %pOF: %d\n",
+ dev->of_node, ret);
return ret;
}
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 71eb4fb..690c675 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -975,7 +975,7 @@ static int mtk_hdmi_setup_avi_infoframe(struct mtk_hdmi *hdmi,
u8 buffer[17];
ssize_t err;
- err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+ err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
if (err < 0) {
dev_err(hdmi->dev,
"Failed to get AVI infoframe from mode: %zd\n", err);
@@ -1261,7 +1261,6 @@ static struct drm_encoder *mtk_hdmi_conn_best_enc(struct drm_connector *conn)
}
static const struct drm_connector_funcs mtk_hdmi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = hdmi_conn_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = hdmi_conn_destroy,
@@ -1456,8 +1455,8 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
cec_pdev = of_find_device_by_node(cec_np);
if (!cec_pdev) {
- dev_err(hdmi->dev, "Waiting for CEC device %s\n",
- cec_np->full_name);
+ dev_err(hdmi->dev, "Waiting for CEC device %pOF\n",
+ cec_np);
return -EPROBE_DEFER;
}
hdmi->cec_dev = &cec_pdev->dev;
@@ -1501,8 +1500,8 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
i2c_np = of_parse_phandle(remote, "ddc-i2c-bus", 0);
if (!i2c_np) {
- dev_err(dev, "Failed to find ddc-i2c-bus node in %s\n",
- remote->full_name);
+ dev_err(dev, "Failed to find ddc-i2c-bus node in %pOF\n",
+ remote);
of_node_put(remote);
return -EINVAL;
}
diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c
index c986eb0..5155f01 100644
--- a/drivers/gpu/drm/meson/meson_crtc.c
+++ b/drivers/gpu/drm/meson/meson_crtc.c
@@ -79,7 +79,8 @@ static const struct drm_crtc_funcs meson_crtc_funcs = {
};
-static void meson_crtc_enable(struct drm_crtc *crtc)
+static void meson_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
struct drm_crtc_state *crtc_state = crtc->state;
@@ -102,7 +103,8 @@ static void meson_crtc_enable(struct drm_crtc *crtc)
priv->viu.osd1_enabled = true;
}
-static void meson_crtc_disable(struct drm_crtc *crtc)
+static void meson_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
struct meson_drm *priv = meson_crtc->priv;
@@ -149,10 +151,10 @@ static void meson_crtc_atomic_flush(struct drm_crtc *crtc,
}
static const struct drm_crtc_helper_funcs meson_crtc_helper_funcs = {
- .enable = meson_crtc_enable,
- .disable = meson_crtc_disable,
.atomic_begin = meson_crtc_atomic_begin,
.atomic_flush = meson_crtc_atomic_flush,
+ .atomic_enable = meson_crtc_atomic_enable,
+ .atomic_disable = meson_crtc_atomic_disable,
};
void meson_crtc_irq(struct meson_drm *priv)
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index 4d98fac..7742c7d 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -116,8 +116,6 @@ static struct drm_driver meson_driver = {
/* GEM Ops */
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_destroy = drm_gem_dumb_destroy,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
@@ -303,9 +301,8 @@ static const struct component_master_ops meson_drv_master_ops = {
static int compare_of(struct device *dev, void *data)
{
- DRM_DEBUG_DRIVER("Comparing of node %s with %s\n",
- of_node_full_name(dev->of_node),
- of_node_full_name(data));
+ DRM_DEBUG_DRIVER("Comparing of node %pOF with %pOF\n",
+ dev->of_node, data);
return dev->of_node == data;
}
diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c
index a32d3b6..17e96fa 100644
--- a/drivers/gpu/drm/meson/meson_plane.c
+++ b/drivers/gpu/drm/meson/meson_plane.c
@@ -223,6 +223,7 @@ int meson_plane_create(struct meson_drm *priv)
&meson_plane_funcs,
supported_drm_formats,
ARRAY_SIZE(supported_drm_formats),
+ NULL,
DRM_PLANE_TYPE_PRIMARY, "meson_primary_plane");
drm_plane_helper_add(plane, &meson_plane_helper_funcs);
diff --git a/drivers/gpu/drm/meson/meson_venc_cvbs.c b/drivers/gpu/drm/meson/meson_venc_cvbs.c
index 00775b3..79d95ca 100644
--- a/drivers/gpu/drm/meson/meson_venc_cvbs.c
+++ b/drivers/gpu/drm/meson/meson_venc_cvbs.c
@@ -118,7 +118,6 @@ static int meson_cvbs_connector_mode_valid(struct drm_connector *connector,
}
static const struct drm_connector_funcs meson_cvbs_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = meson_cvbs_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = meson_cvbs_connector_destroy,
diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c
index 63ba0699..1aad278 100644
--- a/drivers/gpu/drm/mga/mga_drv.c
+++ b/drivers/gpu/drm/mga/mga_drv.c
@@ -62,7 +62,6 @@ static struct drm_driver driver = {
.load = mga_driver_load,
.unload = mga_driver_unload,
.lastclose = mga_driver_lastclose,
- .set_busid = drm_pci_set_busid,
.dma_quiescent = mga_driver_dma_quiescent,
.get_vblank_counter = mga_get_vblank_counter,
.enable_vblank = mga_enable_vblank,
@@ -90,12 +89,12 @@ static struct pci_driver mga_pci_driver = {
static int __init mga_init(void)
{
driver.num_ioctls = mga_max_ioctl;
- return drm_pci_init(&driver, &mga_pci_driver);
+ return drm_legacy_pci_init(&driver, &mga_pci_driver);
}
static void __exit mga_exit(void)
{
- drm_pci_exit(&driver, &mga_pci_driver);
+ drm_legacy_pci_exit(&driver, &mga_pci_driver);
}
module_init(mga_init);
diff --git a/drivers/gpu/drm/mgag200/mgag200_cursor.c b/drivers/gpu/drm/mgag200/mgag200_cursor.c
index 2ac3fcb..968e203 100644
--- a/drivers/gpu/drm/mgag200/mgag200_cursor.c
+++ b/drivers/gpu/drm/mgag200/mgag200_cursor.c
@@ -248,7 +248,7 @@ int mga_crtc_cursor_set(struct drm_crtc *crtc,
out_unreserve1:
mgag200_bo_unreserve(pixels_2);
out_unref:
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
index 9ac0078..74cdde2 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -91,7 +91,6 @@ static struct drm_driver driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET,
.load = mgag200_driver_load,
.unload = mgag200_driver_unload,
- .set_busid = drm_pci_set_busid,
.fops = &mgag200_driver_fops,
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
@@ -103,7 +102,6 @@ static struct drm_driver driver = {
.gem_free_object_unlocked = mgag200_gem_free_object,
.dumb_create = mgag200_dumb_create,
.dumb_map_offset = mgag200_dumb_mmap_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
};
static struct pci_driver mgag200_pci_driver = {
@@ -120,12 +118,13 @@ static int __init mgag200_init(void)
if (mgag200_modeset == 0)
return -EINVAL;
- return drm_pci_init(&driver, &mgag200_pci_driver);
+
+ return pci_register_driver(&mgag200_pci_driver);
}
static void __exit mgag200_exit(void)
{
- drm_pci_exit(&driver, &mgag200_pci_driver);
+ pci_unregister_driver(&mgag200_pci_driver);
}
module_init(mgag200_init);
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index c88b6ec..04f1dfb 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -237,11 +237,6 @@ mgag200_bo(struct ttm_buffer_object *bo)
{
return container_of(bo, struct mgag200_bo, bo);
}
- /* mgag200_crtc.c */
-void mga_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno);
-void mga_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
- u16 *blue, int regno);
/* mgag200_mode.c */
int mgag200_modeset_init(struct mga_device *mdev);
diff --git a/drivers/gpu/drm/mgag200/mgag200_fb.c b/drivers/gpu/drm/mgag200/mgag200_fb.c
index 5d3b1fa..30726c9 100644
--- a/drivers/gpu/drm/mgag200/mgag200_fb.c
+++ b/drivers/gpu/drm/mgag200/mgag200_fb.c
@@ -210,7 +210,6 @@ static int mgag200fb_create(struct drm_fb_helper *helper,
strcpy(info->fix.id, "mgadrmfb");
- info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
info->fbops = &mgag200fb_ops;
/* setup aperture base/size for vesafb takeover */
@@ -233,7 +232,7 @@ static int mgag200fb_create(struct drm_fb_helper *helper,
err_alloc_fbi:
vfree(sysram);
err_sysram:
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return ret;
}
@@ -246,7 +245,7 @@ static int mga_fbdev_destroy(struct drm_device *dev,
drm_fb_helper_unregister_fbi(&mfbdev->helper);
if (mfb->obj) {
- drm_gem_object_unreference_unlocked(mfb->obj);
+ drm_gem_object_put_unlocked(mfb->obj);
mfb->obj = NULL;
}
drm_fb_helper_fini(&mfbdev->helper);
@@ -258,8 +257,6 @@ static int mga_fbdev_destroy(struct drm_device *dev,
}
static const struct drm_fb_helper_funcs mga_fb_helper_funcs = {
- .gamma_set = mga_crtc_fb_gamma_set,
- .gamma_get = mga_crtc_fb_gamma_get,
.fb_probe = mgag200fb_create,
};
diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c
index dce8a3e..780f983 100644
--- a/drivers/gpu/drm/mgag200/mgag200_main.c
+++ b/drivers/gpu/drm/mgag200/mgag200_main.c
@@ -18,7 +18,7 @@ static void mga_user_framebuffer_destroy(struct drm_framebuffer *fb)
{
struct mga_framebuffer *mga_fb = to_mga_framebuffer(fb);
- drm_gem_object_unreference_unlocked(mga_fb->obj);
+ drm_gem_object_put_unlocked(mga_fb->obj);
drm_framebuffer_cleanup(fb);
kfree(fb);
}
@@ -59,13 +59,13 @@ mgag200_user_framebuffer_create(struct drm_device *dev,
mga_fb = kzalloc(sizeof(*mga_fb), GFP_KERNEL);
if (!mga_fb) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ERR_PTR(-ENOMEM);
}
ret = mgag200_framebuffer_init(dev, mga_fb, mode_cmd, obj);
if (ret) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
kfree(mga_fb);
return ERR_PTR(ret);
}
@@ -317,7 +317,7 @@ int mgag200_dumb_create(struct drm_file *file,
return ret;
ret = drm_gem_handle_create(file, gobj, &handle);
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
if (ret)
return ret;
@@ -366,6 +366,6 @@ mgag200_dumb_mmap_offset(struct drm_file *file,
bo = gem_to_mga_bo(obj);
*offset = mgag200_bo_mmap_offset(bo);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return 0;
}
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index f4b5358..5e9cd4c 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -27,15 +27,19 @@
static void mga_crtc_load_lut(struct drm_crtc *crtc)
{
- struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct mga_device *mdev = dev->dev_private;
struct drm_framebuffer *fb = crtc->primary->fb;
+ u16 *r_ptr, *g_ptr, *b_ptr;
int i;
if (!crtc->enabled)
return;
+ r_ptr = crtc->gamma_store;
+ g_ptr = r_ptr + crtc->gamma_size;
+ b_ptr = g_ptr + crtc->gamma_size;
+
WREG8(DAC_INDEX + MGA1064_INDEX, 0);
if (fb && fb->format->cpp[0] * 8 == 16) {
@@ -46,25 +50,27 @@ static void mga_crtc_load_lut(struct drm_crtc *crtc)
if (i > (MGAG200_LUT_SIZE >> 1)) {
r = b = 0;
} else {
- r = mga_crtc->lut_r[i << 1];
- b = mga_crtc->lut_b[i << 1];
+ r = *r_ptr++ >> 8;
+ b = *b_ptr++ >> 8;
+ r_ptr++;
+ b_ptr++;
}
} else {
- r = mga_crtc->lut_r[i];
- b = mga_crtc->lut_b[i];
+ r = *r_ptr++ >> 8;
+ b = *b_ptr++ >> 8;
}
/* VGA registers */
WREG8(DAC_INDEX + MGA1064_COL_PAL, r);
- WREG8(DAC_INDEX + MGA1064_COL_PAL, mga_crtc->lut_g[i]);
+ WREG8(DAC_INDEX + MGA1064_COL_PAL, *g_ptr++ >> 8);
WREG8(DAC_INDEX + MGA1064_COL_PAL, b);
}
return;
}
for (i = 0; i < MGAG200_LUT_SIZE; i++) {
/* VGA registers */
- WREG8(DAC_INDEX + MGA1064_COL_PAL, mga_crtc->lut_r[i]);
- WREG8(DAC_INDEX + MGA1064_COL_PAL, mga_crtc->lut_g[i]);
- WREG8(DAC_INDEX + MGA1064_COL_PAL, mga_crtc->lut_b[i]);
+ WREG8(DAC_INDEX + MGA1064_COL_PAL, *r_ptr++ >> 8);
+ WREG8(DAC_INDEX + MGA1064_COL_PAL, *g_ptr++ >> 8);
+ WREG8(DAC_INDEX + MGA1064_COL_PAL, *b_ptr++ >> 8);
}
}
@@ -1399,14 +1405,6 @@ static int mga_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
u16 *blue, uint32_t size,
struct drm_modeset_acquire_ctx *ctx)
{
- struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
- int i;
-
- for (i = 0; i < size; i++) {
- mga_crtc->lut_r[i] = red[i] >> 8;
- mga_crtc->lut_g[i] = green[i] >> 8;
- mga_crtc->lut_b[i] = blue[i] >> 8;
- }
mga_crtc_load_lut(crtc);
return 0;
@@ -1455,14 +1453,12 @@ static const struct drm_crtc_helper_funcs mga_helper_funcs = {
.mode_set_base = mga_crtc_mode_set_base,
.prepare = mga_crtc_prepare,
.commit = mga_crtc_commit,
- .load_lut = mga_crtc_load_lut,
};
/* CRTC setup */
static void mga_crtc_init(struct mga_device *mdev)
{
struct mga_crtc *mga_crtc;
- int i;
mga_crtc = kzalloc(sizeof(struct mga_crtc) +
(MGAG200FB_CONN_LIMIT * sizeof(struct drm_connector *)),
@@ -1476,37 +1472,9 @@ static void mga_crtc_init(struct mga_device *mdev)
drm_mode_crtc_set_gamma_size(&mga_crtc->base, MGAG200_LUT_SIZE);
mdev->mode_info.crtc = mga_crtc;
- for (i = 0; i < MGAG200_LUT_SIZE; i++) {
- mga_crtc->lut_r[i] = i;
- mga_crtc->lut_g[i] = i;
- mga_crtc->lut_b[i] = i;
- }
-
drm_crtc_helper_add(&mga_crtc->base, &mga_helper_funcs);
}
-/** Sets the color ramps on behalf of fbcon */
-void mga_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno)
-{
- struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
-
- mga_crtc->lut_r[regno] = red >> 8;
- mga_crtc->lut_g[regno] = green >> 8;
- mga_crtc->lut_b[regno] = blue >> 8;
-}
-
-/** Gets the color ramps on behalf of fbcon */
-void mga_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
- u16 *blue, int regno)
-{
- struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
-
- *red = (u16)mga_crtc->lut_r[regno] << 8;
- *green = (u16)mga_crtc->lut_g[regno] << 8;
- *blue = (u16)mga_crtc->lut_b[regno] << 8;
-}
-
/*
* The encoder comes after the CRTC in the output pipeline, but before
* the connector. It's responsible for ensuring that the digital
diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
index 0e3828ed..7791313 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
@@ -486,8 +486,6 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev)
adreno_gpu = &a3xx_gpu->base;
gpu = &adreno_gpu->base;
- a3xx_gpu->pdev = pdev;
-
gpu->perfcntrs = perfcntrs;
gpu->num_perfcntrs = ARRAY_SIZE(perfcntrs);
diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.h b/drivers/gpu/drm/msm/adreno/a3xx_gpu.h
index 85ff66c..ab60dc9 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.h
@@ -28,7 +28,6 @@
struct a3xx_gpu {
struct adreno_gpu base;
- struct platform_device *pdev;
/* if OCMEM is used for GMEM: */
uint32_t ocmem_base;
diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
index 19abf22..58341ef 100644
--- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
@@ -568,8 +568,6 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev)
adreno_gpu = &a4xx_gpu->base;
gpu = &adreno_gpu->base;
- a4xx_gpu->pdev = pdev;
-
gpu->perfcntrs = NULL;
gpu->num_perfcntrs = 0;
diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.h b/drivers/gpu/drm/msm/adreno/a4xx_gpu.h
index 0124720..f757184 100644
--- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.h
@@ -23,7 +23,6 @@
struct a4xx_gpu {
struct adreno_gpu base;
- struct platform_device *pdev;
/* if OCMEM is used for GMEM: */
uint32_t ocmem_base;
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index f9eae03..17c59d8 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -284,28 +284,14 @@ static int a5xx_me_init(struct msm_gpu *gpu)
static struct drm_gem_object *a5xx_ucode_load_bo(struct msm_gpu *gpu,
const struct firmware *fw, u64 *iova)
{
- struct drm_device *drm = gpu->dev;
struct drm_gem_object *bo;
void *ptr;
- bo = msm_gem_new_locked(drm, fw->size - 4, MSM_BO_UNCACHED);
- if (IS_ERR(bo))
- return bo;
+ ptr = msm_gem_kernel_new_locked(gpu->dev, fw->size - 4,
+ MSM_BO_UNCACHED | MSM_BO_GPU_READONLY, gpu->aspace, &bo, iova);
- ptr = msm_gem_get_vaddr(bo);
- if (!ptr) {
- drm_gem_object_unreference(bo);
- return ERR_PTR(-ENOMEM);
- }
-
- if (iova) {
- int ret = msm_gem_get_iova(bo, gpu->aspace, iova);
-
- if (ret) {
- drm_gem_object_unreference(bo);
- return ERR_PTR(ret);
- }
- }
+ if (IS_ERR(ptr))
+ return ERR_CAST(ptr);
memcpy(ptr, &fw->data[4], fw->size - 4);
@@ -372,8 +358,7 @@ static int a5xx_zap_shader_init(struct msm_gpu *gpu)
{
static bool loaded;
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
- struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
- struct platform_device *pdev = a5xx_gpu->pdev;
+ struct platform_device *pdev = gpu->pdev;
int ret;
/*
@@ -410,6 +395,7 @@ static int a5xx_zap_shader_init(struct msm_gpu *gpu)
A5XX_RBBM_INT_0_MASK_RBBM_ETS_MS_TIMEOUT | \
A5XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNC_OVERFLOW | \
A5XX_RBBM_INT_0_MASK_CP_HW_ERROR | \
+ A5XX_RBBM_INT_0_MASK_MISC_HANG_DETECT | \
A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS | \
A5XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
A5XX_RBBM_INT_0_MASK_GPMU_VOLTAGE_DROOP)
@@ -812,6 +798,27 @@ static void a5xx_gpmu_err_irq(struct msm_gpu *gpu)
dev_err_ratelimited(gpu->dev->dev, "GPMU | voltage droop\n");
}
+static void a5xx_fault_detect_irq(struct msm_gpu *gpu)
+{
+ struct drm_device *dev = gpu->dev;
+ struct msm_drm_private *priv = dev->dev_private;
+
+ dev_err(dev->dev, "gpu fault fence %x status %8.8X rb %4.4x/%4.4x ib1 %16.16llX/%4.4x ib2 %16.16llX/%4.4x\n",
+ gpu->funcs->last_fence(gpu),
+ gpu_read(gpu, REG_A5XX_RBBM_STATUS),
+ gpu_read(gpu, REG_A5XX_CP_RB_RPTR),
+ gpu_read(gpu, REG_A5XX_CP_RB_WPTR),
+ gpu_read64(gpu, REG_A5XX_CP_IB1_BASE, REG_A5XX_CP_IB1_BASE_HI),
+ gpu_read(gpu, REG_A5XX_CP_IB1_BUFSZ),
+ gpu_read64(gpu, REG_A5XX_CP_IB2_BASE, REG_A5XX_CP_IB2_BASE_HI),
+ gpu_read(gpu, REG_A5XX_CP_IB2_BUFSZ));
+
+ /* Turn off the hangcheck timer to keep it from bothering us */
+ del_timer(&gpu->hangcheck_timer);
+
+ queue_work(priv->wq, &gpu->recover_work);
+}
+
#define RBBM_ERROR_MASK \
(A5XX_RBBM_INT_0_MASK_RBBM_AHB_ERROR | \
A5XX_RBBM_INT_0_MASK_RBBM_TRANSFER_TIMEOUT | \
@@ -838,6 +845,9 @@ static irqreturn_t a5xx_irq(struct msm_gpu *gpu)
if (status & A5XX_RBBM_INT_0_MASK_CP_HW_ERROR)
a5xx_cp_err_irq(gpu);
+ if (status & A5XX_RBBM_INT_0_MASK_MISC_HANG_DETECT)
+ a5xx_fault_detect_irq(gpu);
+
if (status & A5XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS)
a5xx_uche_err_irq(gpu);
@@ -1015,7 +1025,6 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
adreno_gpu = &a5xx_gpu->base;
gpu = &adreno_gpu->base;
- a5xx_gpu->pdev = pdev;
adreno_gpu->registers = a5xx_registers;
adreno_gpu->reg_offsets = a5xx_register_offsets;
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
index 1137092..e944516 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
@@ -23,7 +23,6 @@
struct a5xx_gpu {
struct adreno_gpu base;
- struct platform_device *pdev;
struct drm_gem_object *pm4_bo;
uint64_t pm4_iova;
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_power.c b/drivers/gpu/drm/msm/adreno/a5xx_power.c
index 87af6ee..04aab1d 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_power.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_power.c
@@ -294,16 +294,10 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu)
*/
bosize = (cmds_size + (cmds_size / TYPE4_MAX_PAYLOAD) + 1) << 2;
- a5xx_gpu->gpmu_bo = msm_gem_new_locked(drm, bosize, MSM_BO_UNCACHED);
- if (IS_ERR(a5xx_gpu->gpmu_bo))
- goto err;
-
- if (msm_gem_get_iova(a5xx_gpu->gpmu_bo, gpu->aspace,
- &a5xx_gpu->gpmu_iova))
- goto err;
-
- ptr = msm_gem_get_vaddr(a5xx_gpu->gpmu_bo);
- if (!ptr)
+ ptr = msm_gem_kernel_new_locked(drm, bosize,
+ MSM_BO_UNCACHED | MSM_BO_GPU_READONLY, gpu->aspace,
+ &a5xx_gpu->gpmu_bo, &a5xx_gpu->gpmu_iova);
+ if (IS_ERR(ptr))
goto err;
while (cmds_size > 0) {
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 7414c6b..c8b4ac2 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -337,11 +337,6 @@ void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords)
DRM_ERROR("%s: timeout waiting for ringbuffer space\n", gpu->name);
}
-static const char *iommu_ports[] = {
- "gfx3d_user", "gfx3d_priv",
- "gfx3d1_user", "gfx3d1_priv",
-};
-
int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
struct adreno_gpu *adreno_gpu, const struct adreno_gpu_funcs *funcs)
{
@@ -373,15 +368,15 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
adreno_gpu_config.ringsz = RB_SIZE;
+ pm_runtime_set_autosuspend_delay(&pdev->dev, DRM_MSM_INACTIVE_PERIOD);
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+
ret = msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base,
adreno_gpu->info->name, &adreno_gpu_config);
if (ret)
return ret;
- pm_runtime_set_autosuspend_delay(&pdev->dev, DRM_MSM_INACTIVE_PERIOD);
- pm_runtime_use_autosuspend(&pdev->dev);
- pm_runtime_enable(&pdev->dev);
-
ret = request_firmware(&adreno_gpu->pm4, adreno_gpu->info->pm4fw, drm->dev);
if (ret) {
dev_err(drm->dev, "failed to load %s PM4 firmware: %d\n",
@@ -396,37 +391,17 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
return ret;
}
- if (gpu->aspace && gpu->aspace->mmu) {
- struct msm_mmu *mmu = gpu->aspace->mmu;
- ret = mmu->funcs->attach(mmu, iommu_ports,
- ARRAY_SIZE(iommu_ports));
- if (ret)
- return ret;
- }
+ adreno_gpu->memptrs = msm_gem_kernel_new(drm,
+ sizeof(*adreno_gpu->memptrs), MSM_BO_UNCACHED, gpu->aspace,
+ &adreno_gpu->memptrs_bo, &adreno_gpu->memptrs_iova);
- adreno_gpu->memptrs_bo = msm_gem_new(drm, sizeof(*adreno_gpu->memptrs),
- MSM_BO_UNCACHED);
- if (IS_ERR(adreno_gpu->memptrs_bo)) {
- ret = PTR_ERR(adreno_gpu->memptrs_bo);
- adreno_gpu->memptrs_bo = NULL;
- dev_err(drm->dev, "could not allocate memptrs: %d\n", ret);
- return ret;
- }
-
- adreno_gpu->memptrs = msm_gem_get_vaddr(adreno_gpu->memptrs_bo);
if (IS_ERR(adreno_gpu->memptrs)) {
- dev_err(drm->dev, "could not vmap memptrs\n");
- return -ENOMEM;
- }
-
- ret = msm_gem_get_iova(adreno_gpu->memptrs_bo, gpu->aspace,
- &adreno_gpu->memptrs_iova);
- if (ret) {
- dev_err(drm->dev, "could not map memptrs: %d\n", ret);
- return ret;
+ ret = PTR_ERR(adreno_gpu->memptrs);
+ adreno_gpu->memptrs = NULL;
+ dev_err(drm->dev, "could not allocate memptrs: %d\n", ret);
}
- return 0;
+ return ret;
}
void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)
@@ -446,10 +421,4 @@ void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)
release_firmware(adreno_gpu->pfp);
msm_gpu_cleanup(gpu);
-
- if (gpu->aspace) {
- gpu->aspace->mmu->funcs->detach(gpu->aspace->mmu,
- iommu_ports, ARRAY_SIZE(iommu_ports));
- msm_gem_address_space_put(gpu->aspace);
- }
}
diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c
index 311c1c1..98742d7 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.c
+++ b/drivers/gpu/drm/msm/dsi/dsi.c
@@ -161,12 +161,17 @@ static const struct of_device_id dt_match[] = {
{}
};
+static const struct dev_pm_ops dsi_pm_ops = {
+ SET_RUNTIME_PM_OPS(msm_dsi_runtime_suspend, msm_dsi_runtime_resume, NULL)
+};
+
static struct platform_driver dsi_driver = {
.probe = dsi_dev_probe,
.remove = dsi_dev_remove,
.driver = {
.name = "msm_dsi",
.of_match_table = dt_match,
+ .pm = &dsi_pm_ops,
},
};
diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
index 9e60173..2302046 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -179,6 +179,8 @@ void msm_dsi_host_destroy(struct mipi_dsi_host *host);
int msm_dsi_host_modeset_init(struct mipi_dsi_host *host,
struct drm_device *dev);
int msm_dsi_host_init(struct msm_dsi *msm_dsi);
+int msm_dsi_runtime_suspend(struct device *dev);
+int msm_dsi_runtime_resume(struct device *dev);
/* dsi phy */
struct msm_dsi_phy;
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index c7b612c..dbb31a0 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -135,7 +135,6 @@ struct msm_dsi_host {
struct completion video_comp;
struct mutex dev_mutex;
struct mutex cmd_mutex;
- struct mutex clk_mutex;
spinlock_t intr_lock; /* Protect interrupt ctrl register */
u32 err_work_state;
@@ -221,6 +220,8 @@ static const struct msm_dsi_cfg_handler *dsi_get_config(
goto put_gdsc;
}
+ pm_runtime_get_sync(dev);
+
ret = regulator_enable(gdsc_reg);
if (ret) {
pr_err("%s: unable to enable gdsc\n", __func__);
@@ -247,6 +248,7 @@ disable_clks:
clk_disable_unprepare(ahb_clk);
disable_gdsc:
regulator_disable(gdsc_reg);
+ pm_runtime_put_autosuspend(dev);
put_clk:
clk_put(ahb_clk);
put_gdsc:
@@ -455,6 +457,34 @@ static void dsi_bus_clk_disable(struct msm_dsi_host *msm_host)
clk_disable_unprepare(msm_host->bus_clks[i]);
}
+int msm_dsi_runtime_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct msm_dsi *msm_dsi = platform_get_drvdata(pdev);
+ struct mipi_dsi_host *host = msm_dsi->host;
+ struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+ if (!msm_host->cfg_hnd)
+ return 0;
+
+ dsi_bus_clk_disable(msm_host);
+
+ return 0;
+}
+
+int msm_dsi_runtime_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct msm_dsi *msm_dsi = platform_get_drvdata(pdev);
+ struct mipi_dsi_host *host = msm_dsi->host;
+ struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+ if (!msm_host->cfg_hnd)
+ return 0;
+
+ return dsi_bus_clk_enable(msm_host);
+}
+
static int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host)
{
int ret;
@@ -596,35 +626,6 @@ static void dsi_link_clk_disable(struct msm_dsi_host *msm_host)
}
}
-static int dsi_clk_ctrl(struct msm_dsi_host *msm_host, bool enable)
-{
- int ret = 0;
-
- mutex_lock(&msm_host->clk_mutex);
- if (enable) {
- ret = dsi_bus_clk_enable(msm_host);
- if (ret) {
- pr_err("%s: Can not enable bus clk, %d\n",
- __func__, ret);
- goto unlock_ret;
- }
- ret = dsi_link_clk_enable(msm_host);
- if (ret) {
- pr_err("%s: Can not enable link clk, %d\n",
- __func__, ret);
- dsi_bus_clk_disable(msm_host);
- goto unlock_ret;
- }
- } else {
- dsi_link_clk_disable(msm_host);
- dsi_bus_clk_disable(msm_host);
- }
-
-unlock_ret:
- mutex_unlock(&msm_host->clk_mutex);
- return ret;
-}
-
static int dsi_calc_clk_rate(struct msm_dsi_host *msm_host)
{
struct drm_display_mode *mode = msm_host->mode;
@@ -1699,6 +1700,7 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
}
msm_host->pdev = pdev;
+ msm_dsi->host = &msm_host->base;
ret = dsi_host_parse_dt(msm_host);
if (ret) {
@@ -1713,6 +1715,8 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
goto fail;
}
+ pm_runtime_enable(&pdev->dev);
+
msm_host->cfg_hnd = dsi_get_config(msm_host);
if (!msm_host->cfg_hnd) {
ret = -EINVAL;
@@ -1753,7 +1757,6 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
init_completion(&msm_host->video_comp);
mutex_init(&msm_host->dev_mutex);
mutex_init(&msm_host->cmd_mutex);
- mutex_init(&msm_host->clk_mutex);
spin_lock_init(&msm_host->intr_lock);
/* setup workqueue */
@@ -1761,7 +1764,6 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
INIT_WORK(&msm_host->err_work, dsi_err_worker);
INIT_WORK(&msm_host->hpd_work, dsi_hpd_worker);
- msm_dsi->host = &msm_host->base;
msm_dsi->id = msm_host->id;
DBG("Dsi Host %d initialized", msm_host->id);
@@ -1783,9 +1785,10 @@ void msm_dsi_host_destroy(struct mipi_dsi_host *host)
msm_host->workqueue = NULL;
}
- mutex_destroy(&msm_host->clk_mutex);
mutex_destroy(&msm_host->cmd_mutex);
mutex_destroy(&msm_host->dev_mutex);
+
+ pm_runtime_disable(&msm_host->pdev->dev);
}
int msm_dsi_host_modeset_init(struct mipi_dsi_host *host,
@@ -1881,7 +1884,8 @@ int msm_dsi_host_xfer_prepare(struct mipi_dsi_host *host,
* mdss interrupt is generated in mdp core clock domain
* mdp clock need to be enabled to receive dsi interrupt
*/
- dsi_clk_ctrl(msm_host, 1);
+ pm_runtime_get_sync(&msm_host->pdev->dev);
+ dsi_link_clk_enable(msm_host);
/* TODO: vote for bus bandwidth */
@@ -1911,7 +1915,8 @@ void msm_dsi_host_xfer_restore(struct mipi_dsi_host *host,
/* TODO: unvote for bus bandwidth */
- dsi_clk_ctrl(msm_host, 0);
+ dsi_link_clk_disable(msm_host);
+ pm_runtime_put_autosuspend(&msm_host->pdev->dev);
}
int msm_dsi_host_cmd_tx(struct mipi_dsi_host *host,
@@ -2160,8 +2165,11 @@ int msm_dsi_host_enable(struct mipi_dsi_host *host)
* and only turned on before MDP START.
* This part of code should be enabled once mdp driver support it.
*/
- /* if (msm_panel->mode == MSM_DSI_CMD_MODE)
- dsi_clk_ctrl(msm_host, 0); */
+ /* if (msm_panel->mode == MSM_DSI_CMD_MODE) {
+ * dsi_link_clk_disable(msm_host);
+ * pm_runtime_put_autosuspend(&msm_host->pdev->dev);
+ * }
+ */
return 0;
}
@@ -2217,9 +2225,11 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host,
goto unlock_ret;
}
- ret = dsi_clk_ctrl(msm_host, 1);
+ pm_runtime_get_sync(&msm_host->pdev->dev);
+ ret = dsi_link_clk_enable(msm_host);
if (ret) {
- pr_err("%s: failed to enable clocks. ret=%d\n", __func__, ret);
+ pr_err("%s: failed to enable link clocks. ret=%d\n",
+ __func__, ret);
goto fail_disable_reg;
}
@@ -2243,7 +2253,8 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host,
return 0;
fail_disable_clk:
- dsi_clk_ctrl(msm_host, 0);
+ dsi_link_clk_disable(msm_host);
+ pm_runtime_put_autosuspend(&msm_host->pdev->dev);
fail_disable_reg:
dsi_host_regulator_disable(msm_host);
unlock_ret:
@@ -2268,7 +2279,8 @@ int msm_dsi_host_power_off(struct mipi_dsi_host *host)
pinctrl_pm_select_sleep_state(&msm_host->pdev->dev);
- dsi_clk_ctrl(msm_host, 0);
+ dsi_link_clk_disable(msm_host);
+ pm_runtime_put_autosuspend(&msm_host->pdev->dev);
dsi_host_regulator_disable(msm_host);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index a879ffa..8552481 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -626,7 +626,6 @@ static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge,
}
static const struct drm_connector_funcs dsi_mgr_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = dsi_mgr_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = dsi_mgr_connector_destroy,
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
index 0c2eb9c..7c9bf91 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
@@ -373,7 +373,7 @@ static int dsi_phy_enable_resource(struct msm_dsi_phy *phy)
static void dsi_phy_disable_resource(struct msm_dsi_phy *phy)
{
clk_disable_unprepare(phy->ahb_clk);
- pm_runtime_put_sync(&phy->pdev->dev);
+ pm_runtime_put_autosuspend(&phy->pdev->dev);
}
static const struct of_device_id dsi_phy_dt_match[] = {
diff --git a/drivers/gpu/drm/msm/edp/edp_connector.c b/drivers/gpu/drm/msm/edp/edp_connector.c
index 5960628..6f3fc6b 100644
--- a/drivers/gpu/drm/msm/edp/edp_connector.c
+++ b/drivers/gpu/drm/msm/edp/edp_connector.c
@@ -92,7 +92,6 @@ static int edp_connector_mode_valid(struct drm_connector *connector,
}
static const struct drm_connector_funcs edp_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = edp_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = edp_connector_destroy,
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
index a968cad..17e069a 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -239,6 +239,8 @@ static struct hdmi *msm_hdmi_init(struct platform_device *pdev)
hdmi->pwr_clks[i] = clk;
}
+ pm_runtime_enable(&pdev->dev);
+
hdmi->workq = alloc_ordered_workqueue("msm_hdmi", 0);
hdmi->i2c = msm_hdmi_i2c_init(hdmi);
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
index ae40e71..7e35707 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
@@ -35,6 +35,8 @@ static void msm_hdmi_power_on(struct drm_bridge *bridge)
const struct hdmi_platform_config *config = hdmi->config;
int i, ret;
+ pm_runtime_get_sync(&hdmi->pdev->dev);
+
for (i = 0; i < config->pwr_reg_cnt; i++) {
ret = regulator_enable(hdmi->pwr_regs[i]);
if (ret) {
@@ -84,6 +86,8 @@ static void power_off(struct drm_bridge *bridge)
config->pwr_reg_names[i], ret);
}
}
+
+ pm_runtime_put_autosuspend(&hdmi->pdev->dev);
}
#define AVI_IFRAME_LINE_NUMBER 1
@@ -97,7 +101,7 @@ static void msm_hdmi_config_avi_infoframe(struct hdmi *hdmi)
u32 val;
int len;
- drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode);
+ drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode, false);
len = hdmi_infoframe_pack(&frame, buffer, sizeof(buffer));
if (len < 0) {
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c
index a2515b4..c0848df 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c
@@ -137,6 +137,36 @@ err:
return ret;
}
+static void enable_hpd_clocks(struct hdmi *hdmi, bool enable)
+{
+ const struct hdmi_platform_config *config = hdmi->config;
+ struct device *dev = &hdmi->pdev->dev;
+ int i, ret;
+
+ if (enable) {
+ for (i = 0; i < config->hpd_clk_cnt; i++) {
+ if (config->hpd_freq && config->hpd_freq[i]) {
+ ret = clk_set_rate(hdmi->hpd_clks[i],
+ config->hpd_freq[i]);
+ if (ret)
+ dev_warn(dev,
+ "failed to set clk %s (%d)\n",
+ config->hpd_clk_names[i], ret);
+ }
+
+ ret = clk_prepare_enable(hdmi->hpd_clks[i]);
+ if (ret) {
+ dev_err(dev,
+ "failed to enable hpd clk: %s (%d)\n",
+ config->hpd_clk_names[i], ret);
+ }
+ }
+ } else {
+ for (i = config->hpd_clk_cnt - 1; i >= 0; i--)
+ clk_disable_unprepare(hdmi->hpd_clks[i]);
+ }
+}
+
static int hpd_enable(struct hdmi_connector *hdmi_connector)
{
struct hdmi *hdmi = hdmi_connector->hdmi;
@@ -167,22 +197,8 @@ static int hpd_enable(struct hdmi_connector *hdmi_connector)
goto fail;
}
- for (i = 0; i < config->hpd_clk_cnt; i++) {
- if (config->hpd_freq && config->hpd_freq[i]) {
- ret = clk_set_rate(hdmi->hpd_clks[i],
- config->hpd_freq[i]);
- if (ret)
- dev_warn(dev, "failed to set clk %s (%d)\n",
- config->hpd_clk_names[i], ret);
- }
-
- ret = clk_prepare_enable(hdmi->hpd_clks[i]);
- if (ret) {
- dev_err(dev, "failed to enable hpd clk: %s (%d)\n",
- config->hpd_clk_names[i], ret);
- goto fail;
- }
- }
+ pm_runtime_get_sync(dev);
+ enable_hpd_clocks(hdmi, true);
msm_hdmi_set_mode(hdmi, false);
msm_hdmi_phy_reset(hdmi);
@@ -225,8 +241,8 @@ static void hdp_disable(struct hdmi_connector *hdmi_connector)
msm_hdmi_set_mode(hdmi, false);
- for (i = 0; i < config->hpd_clk_cnt; i++)
- clk_disable_unprepare(hdmi->hpd_clks[i]);
+ enable_hpd_clocks(hdmi, false);
+ pm_runtime_put_autosuspend(dev);
ret = gpio_config(hdmi, false);
if (ret)
@@ -285,7 +301,16 @@ void msm_hdmi_connector_irq(struct drm_connector *connector)
static enum drm_connector_status detect_reg(struct hdmi *hdmi)
{
- uint32_t hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);
+ uint32_t hpd_int_status;
+
+ pm_runtime_get_sync(&hdmi->pdev->dev);
+ enable_hpd_clocks(hdmi, true);
+
+ hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);
+
+ enable_hpd_clocks(hdmi, false);
+ pm_runtime_put_autosuspend(&hdmi->pdev->dev);
+
return (hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED) ?
connector_status_connected : connector_status_disconnected;
}
@@ -407,7 +432,6 @@ static int msm_hdmi_connector_mode_valid(struct drm_connector *connector,
}
static const struct drm_connector_funcs hdmi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = hdmi_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = hdmi_connector_destroy,
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c
index 615e1de..47fa2ab 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c
@@ -279,7 +279,8 @@ static void mdp4_crtc_mode_set_nofb(struct drm_crtc *crtc)
}
}
-static void mdp4_crtc_disable(struct drm_crtc *crtc)
+static void mdp4_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
struct mdp4_kms *mdp4_kms = get_kms(crtc);
@@ -295,7 +296,8 @@ static void mdp4_crtc_disable(struct drm_crtc *crtc)
mdp4_crtc->enabled = false;
}
-static void mdp4_crtc_enable(struct drm_crtc *crtc)
+static void mdp4_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
struct mdp4_kms *mdp4_kms = get_kms(crtc);
@@ -482,7 +484,6 @@ static const struct drm_crtc_funcs mdp4_crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
.destroy = mdp4_crtc_destroy,
.page_flip = drm_atomic_helper_page_flip,
- .set_property = drm_atomic_helper_crtc_set_property,
.cursor_set = mdp4_crtc_cursor_set,
.cursor_move = mdp4_crtc_cursor_move,
.reset = drm_atomic_helper_crtc_reset,
@@ -492,11 +493,11 @@ static const struct drm_crtc_funcs mdp4_crtc_funcs = {
static const struct drm_crtc_helper_funcs mdp4_crtc_helper_funcs = {
.mode_set_nofb = mdp4_crtc_mode_set_nofb,
- .disable = mdp4_crtc_disable,
- .enable = mdp4_crtc_enable,
.atomic_check = mdp4_crtc_atomic_check,
.atomic_begin = mdp4_crtc_atomic_begin,
.atomic_flush = mdp4_crtc_atomic_flush,
+ .atomic_enable = mdp4_crtc_atomic_enable,
+ .atomic_disable = mdp4_crtc_atomic_disable,
};
static void mdp4_crtc_vblank_irq(struct mdp_irq *irq, uint32_t irqstatus)
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
index bcd1f5c..f7f0874 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
@@ -114,7 +114,7 @@ static void mdp4_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *st
mdp4_enable(mdp4_kms);
/* see 119ecb7fd */
- for_each_crtc_in_state(state, crtc, crtc_state, i)
+ for_each_new_crtc_in_state(state, crtc, crtc_state, i)
drm_crtc_vblank_get(crtc);
}
@@ -126,7 +126,7 @@ static void mdp4_complete_commit(struct msm_kms *kms, struct drm_atomic_state *s
struct drm_crtc_state *crtc_state;
/* see 119ecb7fd */
- for_each_crtc_in_state(state, crtc, crtc_state, i)
+ for_each_new_crtc_in_state(state, crtc, crtc_state, i)
drm_crtc_vblank_put(crtc);
mdp4_disable(mdp4_kms);
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c
index 353429b..e3b1c86 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c
@@ -91,7 +91,6 @@ static int mdp4_lvds_connector_mode_valid(struct drm_connector *connector,
}
static const struct drm_connector_funcs mdp4_lvds_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = mdp4_lvds_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = mdp4_lvds_connector_destroy,
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
index a20e3d6..7a1ad3a 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
@@ -401,7 +401,7 @@ struct drm_plane *mdp4_plane_init(struct drm_device *dev,
type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
ret = drm_universal_plane_init(dev, plane, 0xff, &mdp4_plane_funcs,
mdp4_plane->formats, mdp4_plane->nformats,
- type, NULL);
+ NULL, type, NULL);
if (ret)
goto fail;
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c
index aa7402e..60790df9 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c
@@ -192,6 +192,7 @@ int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder,
{
struct mdp5_encoder *mdp5_cmd_enc = to_mdp5_encoder(encoder);
struct mdp5_kms *mdp5_kms;
+ struct device *dev;
int intf_num;
u32 data = 0;
@@ -214,14 +215,16 @@ int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder,
/* Smart Panel, Sync mode */
data |= MDP5_SPLIT_DPL_UPPER_SMART_PANEL;
+ dev = &mdp5_kms->pdev->dev;
+
/* Make sure clocks are on when connectors calling this function. */
- mdp5_enable(mdp5_kms);
+ pm_runtime_get_sync(dev);
mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_UPPER, data);
mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_LOWER,
MDP5_SPLIT_DPL_LOWER_SMART_PANEL);
mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_EN, 1);
- mdp5_disable(mdp5_kms);
+ pm_runtime_put_autosuspend(dev);
return 0;
}
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
index 735a87a..6fcb58a 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
@@ -409,11 +409,13 @@ static void mdp5_crtc_mode_set_nofb(struct drm_crtc *crtc)
spin_unlock_irqrestore(&mdp5_crtc->lm_lock, flags);
}
-static void mdp5_crtc_disable(struct drm_crtc *crtc)
+static void mdp5_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
struct mdp5_kms *mdp5_kms = get_kms(crtc);
+ struct device *dev = &mdp5_kms->pdev->dev;
DBG("%s", crtc->name);
@@ -424,23 +426,28 @@ static void mdp5_crtc_disable(struct drm_crtc *crtc)
mdp_irq_unregister(&mdp5_kms->base, &mdp5_crtc->pp_done);
mdp_irq_unregister(&mdp5_kms->base, &mdp5_crtc->err);
- mdp5_disable(mdp5_kms);
+ pm_runtime_put_autosuspend(dev);
mdp5_crtc->enabled = false;
}
-static void mdp5_crtc_enable(struct drm_crtc *crtc)
+static void mdp5_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
struct mdp5_kms *mdp5_kms = get_kms(crtc);
+ struct device *dev = &mdp5_kms->pdev->dev;
DBG("%s", crtc->name);
if (WARN_ON(mdp5_crtc->enabled))
return;
- mdp5_enable(mdp5_kms);
+ pm_runtime_get_sync(dev);
+
+ mdp5_crtc_mode_set_nofb(crtc);
+
mdp_irq_register(&mdp5_kms->base, &mdp5_crtc->err);
if (mdp5_cstate->cmd_mode)
@@ -531,7 +538,7 @@ static bool is_fullscreen(struct drm_crtc_state *cstate,
((pstate->crtc_y + pstate->crtc_h) >= cstate->mode.vdisplay);
}
-enum mdp_mixer_stage_id get_start_stage(struct drm_crtc *crtc,
+static enum mdp_mixer_stage_id get_start_stage(struct drm_crtc *crtc,
struct drm_crtc_state *new_crtc_state,
struct drm_plane_state *bpstate)
{
@@ -725,6 +732,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
struct mdp5_pipeline *pipeline = &mdp5_cstate->pipeline;
struct drm_device *dev = crtc->dev;
struct mdp5_kms *mdp5_kms = get_kms(crtc);
+ struct platform_device *pdev = mdp5_kms->pdev;
struct msm_kms *kms = &mdp5_kms->base.base;
struct drm_gem_object *cursor_bo, *old_bo = NULL;
uint32_t blendcfg, stride;
@@ -753,7 +761,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
if (!handle) {
DBG("Cursor off");
cursor_enable = false;
- mdp5_enable(mdp5_kms);
+ pm_runtime_get_sync(&pdev->dev);
goto set_cursor;
}
@@ -768,6 +776,8 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
lm = mdp5_cstate->pipeline.mixer->lm;
stride = width * drm_format_plane_cpp(DRM_FORMAT_ARGB8888, 0);
+ pm_runtime_get_sync(&pdev->dev);
+
spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags);
old_bo = mdp5_crtc->cursor.scanout_bo;
@@ -777,8 +787,6 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
get_roi(crtc, &roi_w, &roi_h);
- mdp5_enable(mdp5_kms);
-
mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_STRIDE(lm), stride);
mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_FORMAT(lm),
MDP5_LM_CURSOR_FORMAT_FORMAT(CURSOR_FMT_ARGB8888));
@@ -796,6 +804,8 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
spin_unlock_irqrestore(&mdp5_crtc->cursor.lock, flags);
+ pm_runtime_put_autosuspend(&pdev->dev);
+
set_cursor:
ret = mdp5_ctl_set_cursor(ctl, pipeline, 0, cursor_enable);
if (ret) {
@@ -807,7 +817,7 @@ set_cursor:
crtc_flush(crtc, flush_mask);
end:
- mdp5_disable(mdp5_kms);
+ pm_runtime_put_autosuspend(&pdev->dev);
if (old_bo) {
drm_flip_work_queue(&mdp5_crtc->unref_cursor_work, old_bo);
/* enable vblank to complete cursor work: */
@@ -840,7 +850,7 @@ static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
get_roi(crtc, &roi_w, &roi_h);
- mdp5_enable(mdp5_kms);
+ pm_runtime_get_sync(&mdp5_kms->pdev->dev);
spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags);
mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_SIZE(lm),
@@ -853,7 +863,7 @@ static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
crtc_flush(crtc, flush_mask);
- mdp5_disable(mdp5_kms);
+ pm_runtime_put_autosuspend(&mdp5_kms->pdev->dev);
return 0;
}
@@ -925,7 +935,6 @@ static const struct drm_crtc_funcs mdp5_crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
.destroy = mdp5_crtc_destroy,
.page_flip = drm_atomic_helper_page_flip,
- .set_property = drm_atomic_helper_crtc_set_property,
.reset = mdp5_crtc_reset,
.atomic_duplicate_state = mdp5_crtc_duplicate_state,
.atomic_destroy_state = mdp5_crtc_destroy_state,
@@ -938,7 +947,6 @@ static const struct drm_crtc_funcs mdp5_crtc_no_lm_cursor_funcs = {
.set_config = drm_atomic_helper_set_config,
.destroy = mdp5_crtc_destroy,
.page_flip = drm_atomic_helper_page_flip,
- .set_property = drm_atomic_helper_crtc_set_property,
.reset = mdp5_crtc_reset,
.atomic_duplicate_state = mdp5_crtc_duplicate_state,
.atomic_destroy_state = mdp5_crtc_destroy_state,
@@ -947,11 +955,11 @@ static const struct drm_crtc_funcs mdp5_crtc_no_lm_cursor_funcs = {
static const struct drm_crtc_helper_funcs mdp5_crtc_helper_funcs = {
.mode_set_nofb = mdp5_crtc_mode_set_nofb,
- .disable = mdp5_crtc_disable,
- .enable = mdp5_crtc_enable,
.atomic_check = mdp5_crtc_atomic_check,
.atomic_begin = mdp5_crtc_atomic_begin,
.atomic_flush = mdp5_crtc_atomic_flush,
+ .atomic_enable = mdp5_crtc_atomic_enable,
+ .atomic_disable = mdp5_crtc_atomic_disable,
};
static void mdp5_crtc_vblank_irq(struct mdp_irq *irq, uint32_t irqstatus)
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c
index 70bef51..5b85138 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c
@@ -297,6 +297,10 @@ static void mdp5_encoder_enable(struct drm_encoder *encoder)
{
struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
struct mdp5_interface *intf = mdp5_encoder->intf;
+ /* this isn't right I think */
+ struct drm_crtc_state *cstate = encoder->crtc->state;
+
+ mdp5_encoder_mode_set(encoder, &cstate->mode, &cstate->adjusted_mode);
if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND)
mdp5_cmd_encoder_enable(encoder);
@@ -320,7 +324,6 @@ static int mdp5_encoder_atomic_check(struct drm_encoder *encoder,
}
static const struct drm_encoder_helper_funcs mdp5_encoder_helper_funcs = {
- .mode_set = mdp5_encoder_mode_set,
.disable = mdp5_encoder_disable,
.enable = mdp5_encoder_enable,
.atomic_check = mdp5_encoder_atomic_check,
@@ -350,6 +353,7 @@ int mdp5_vid_encoder_set_split_display(struct drm_encoder *encoder,
struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
struct mdp5_encoder *mdp5_slave_enc = to_mdp5_encoder(slave_encoder);
struct mdp5_kms *mdp5_kms;
+ struct device *dev;
int intf_num;
u32 data = 0;
@@ -369,8 +373,10 @@ int mdp5_vid_encoder_set_split_display(struct drm_encoder *encoder,
else
return -EINVAL;
+ dev = &mdp5_kms->pdev->dev;
/* Make sure clocks are on when connectors calling this function. */
- mdp5_enable(mdp5_kms);
+ pm_runtime_get_sync(dev);
+
/* Dumb Panel, Sync mode */
mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_UPPER, 0);
mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_LOWER, data);
@@ -378,7 +384,7 @@ int mdp5_vid_encoder_set_split_display(struct drm_encoder *encoder,
mdp5_ctl_pair(mdp5_encoder->ctl, mdp5_slave_enc->ctl, true);
- mdp5_disable(mdp5_kms);
+ pm_runtime_put_autosuspend(dev);
return 0;
}
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c
index 3ce8b9d..bb5deb00 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c
@@ -49,16 +49,19 @@ static void mdp5_irq_error_handler(struct mdp_irq *irq, uint32_t irqstatus)
void mdp5_irq_preinstall(struct msm_kms *kms)
{
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
- mdp5_enable(mdp5_kms);
+ struct device *dev = &mdp5_kms->pdev->dev;
+
+ pm_runtime_get_sync(dev);
mdp5_write(mdp5_kms, REG_MDP5_INTR_CLEAR, 0xffffffff);
mdp5_write(mdp5_kms, REG_MDP5_INTR_EN, 0x00000000);
- mdp5_disable(mdp5_kms);
+ pm_runtime_put_autosuspend(dev);
}
int mdp5_irq_postinstall(struct msm_kms *kms)
{
struct mdp_kms *mdp_kms = to_mdp_kms(kms);
struct mdp5_kms *mdp5_kms = to_mdp5_kms(mdp_kms);
+ struct device *dev = &mdp5_kms->pdev->dev;
struct mdp_irq *error_handler = &mdp5_kms->error_handler;
error_handler->irq = mdp5_irq_error_handler;
@@ -67,9 +70,9 @@ int mdp5_irq_postinstall(struct msm_kms *kms)
MDP5_IRQ_INTF2_UNDER_RUN |
MDP5_IRQ_INTF3_UNDER_RUN;
- mdp5_enable(mdp5_kms);
+ pm_runtime_get_sync(dev);
mdp_irq_register(mdp_kms, error_handler);
- mdp5_disable(mdp5_kms);
+ pm_runtime_put_autosuspend(dev);
return 0;
}
@@ -77,9 +80,11 @@ int mdp5_irq_postinstall(struct msm_kms *kms)
void mdp5_irq_uninstall(struct msm_kms *kms)
{
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
- mdp5_enable(mdp5_kms);
+ struct device *dev = &mdp5_kms->pdev->dev;
+
+ pm_runtime_get_sync(dev);
mdp5_write(mdp5_kms, REG_MDP5_INTR_EN, 0x00000000);
- mdp5_disable(mdp5_kms);
+ pm_runtime_put_autosuspend(dev);
}
irqreturn_t mdp5_irq(struct msm_kms *kms)
@@ -109,11 +114,12 @@ irqreturn_t mdp5_irq(struct msm_kms *kms)
int mdp5_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
{
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+ struct device *dev = &mdp5_kms->pdev->dev;
- mdp5_enable(mdp5_kms);
+ pm_runtime_get_sync(dev);
mdp_update_vblank_mask(to_mdp_kms(kms),
mdp5_crtc_vblank(crtc), true);
- mdp5_disable(mdp5_kms);
+ pm_runtime_put_autosuspend(dev);
return 0;
}
@@ -121,9 +127,10 @@ int mdp5_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
void mdp5_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
{
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+ struct device *dev = &mdp5_kms->pdev->dev;
- mdp5_enable(mdp5_kms);
+ pm_runtime_get_sync(dev);
mdp_update_vblank_mask(to_mdp_kms(kms),
mdp5_crtc_vblank(crtc), false);
- mdp5_disable(mdp5_kms);
+ pm_runtime_put_autosuspend(dev);
}
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index 1c603ae..f7c0698 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -30,11 +30,10 @@ static const char *iommu_ports[] = {
static int mdp5_hw_init(struct msm_kms *kms)
{
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
- struct platform_device *pdev = mdp5_kms->pdev;
+ struct device *dev = &mdp5_kms->pdev->dev;
unsigned long flags;
- pm_runtime_get_sync(&pdev->dev);
- mdp5_enable(mdp5_kms);
+ pm_runtime_get_sync(dev);
/* Magic unknown register writes:
*
@@ -66,8 +65,7 @@ static int mdp5_hw_init(struct msm_kms *kms)
mdp5_ctlm_hw_reset(mdp5_kms->ctlm);
- mdp5_disable(mdp5_kms);
- pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_put_sync(dev);
return 0;
}
@@ -111,8 +109,9 @@ static void mdp5_swap_state(struct msm_kms *kms, struct drm_atomic_state *state)
static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)
{
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+ struct device *dev = &mdp5_kms->pdev->dev;
- mdp5_enable(mdp5_kms);
+ pm_runtime_get_sync(dev);
if (mdp5_kms->smp)
mdp5_smp_prepare_commit(mdp5_kms->smp, &mdp5_kms->state->smp);
@@ -121,11 +120,12 @@ static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *st
static void mdp5_complete_commit(struct msm_kms *kms, struct drm_atomic_state *state)
{
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+ struct device *dev = &mdp5_kms->pdev->dev;
if (mdp5_kms->smp)
mdp5_smp_complete_commit(mdp5_kms->smp, &mdp5_kms->state->smp);
- mdp5_disable(mdp5_kms);
+ pm_runtime_put_autosuspend(dev);
}
static void mdp5_wait_for_crtc_commit_done(struct msm_kms *kms,
@@ -249,6 +249,9 @@ int mdp5_disable(struct mdp5_kms *mdp5_kms)
{
DBG("");
+ mdp5_kms->enable_count--;
+ WARN_ON(mdp5_kms->enable_count < 0);
+
clk_disable_unprepare(mdp5_kms->ahb_clk);
clk_disable_unprepare(mdp5_kms->axi_clk);
clk_disable_unprepare(mdp5_kms->core_clk);
@@ -262,6 +265,8 @@ int mdp5_enable(struct mdp5_kms *mdp5_kms)
{
DBG("");
+ mdp5_kms->enable_count++;
+
clk_prepare_enable(mdp5_kms->ahb_clk);
clk_prepare_enable(mdp5_kms->axi_clk);
clk_prepare_enable(mdp5_kms->core_clk);
@@ -486,11 +491,12 @@ fail:
static void read_mdp_hw_revision(struct mdp5_kms *mdp5_kms,
u32 *major, u32 *minor)
{
+ struct device *dev = &mdp5_kms->pdev->dev;
u32 version;
- mdp5_enable(mdp5_kms);
+ pm_runtime_get_sync(dev);
version = mdp5_read(mdp5_kms, REG_MDP5_HW_VERSION);
- mdp5_disable(mdp5_kms);
+ pm_runtime_put_autosuspend(dev);
*major = FIELD(version, MDP5_HW_VERSION_MAJOR);
*minor = FIELD(version, MDP5_HW_VERSION_MINOR);
@@ -643,7 +649,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
* have left things on, in which case we'll start getting faults if
* we don't disable):
*/
- mdp5_enable(mdp5_kms);
+ pm_runtime_get_sync(&pdev->dev);
for (i = 0; i < MDP5_INTF_NUM_MAX; i++) {
if (mdp5_cfg_intf_is_virtual(config->hw->intf.connect[i]) ||
!config->hw->intf.base[i])
@@ -652,7 +658,6 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
mdp5_write(mdp5_kms, REG_MDP5_INTF_FRAME_LINE_COUNT_EN(i), 0x3);
}
- mdp5_disable(mdp5_kms);
mdelay(16);
if (config->platform.iommu) {
@@ -678,6 +683,8 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
aspace = NULL;;
}
+ pm_runtime_put_autosuspend(&pdev->dev);
+
ret = modeset_init(mdp5_kms);
if (ret) {
dev_err(&pdev->dev, "modeset_init failed: %d\n", ret);
@@ -1005,6 +1012,30 @@ static int mdp5_dev_remove(struct platform_device *pdev)
return 0;
}
+static __maybe_unused int mdp5_runtime_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct mdp5_kms *mdp5_kms = platform_get_drvdata(pdev);
+
+ DBG("");
+
+ return mdp5_disable(mdp5_kms);
+}
+
+static __maybe_unused int mdp5_runtime_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct mdp5_kms *mdp5_kms = platform_get_drvdata(pdev);
+
+ DBG("");
+
+ return mdp5_enable(mdp5_kms);
+}
+
+static const struct dev_pm_ops mdp5_pm_ops = {
+ SET_RUNTIME_PM_OPS(mdp5_runtime_suspend, mdp5_runtime_resume, NULL)
+};
+
static const struct of_device_id mdp5_dt_match[] = {
{ .compatible = "qcom,mdp5", },
/* to support downstream DT files */
@@ -1019,6 +1050,7 @@ static struct platform_driver mdp5_driver = {
.driver = {
.name = "msm_mdp",
.of_match_table = mdp5_dt_match,
+ .pm = &mdp5_pm_ops,
},
};
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
index 17caa0e..9b3fe01 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
@@ -76,6 +76,8 @@ struct mdp5_kms {
bool rpm_enabled;
struct mdp_irq error_handler;
+
+ int enable_count;
};
#define to_mdp5_kms(x) container_of(x, struct mdp5_kms, base)
@@ -167,11 +169,13 @@ struct mdp5_encoder {
static inline void mdp5_write(struct mdp5_kms *mdp5_kms, u32 reg, u32 data)
{
+ WARN_ON(mdp5_kms->enable_count <= 0);
msm_writel(data, mdp5_kms->mmio + reg);
}
static inline u32 mdp5_read(struct mdp5_kms *mdp5_kms, u32 reg)
{
+ WARN_ON(mdp5_kms->enable_count <= 0);
return msm_readl(mdp5_kms->mmio + reg);
}
@@ -255,9 +259,6 @@ static inline uint32_t lm2ppdone(struct mdp5_hw_mixer *mixer)
return MDP5_IRQ_PING_PONG_0_DONE << mixer->pp;
}
-int mdp5_disable(struct mdp5_kms *mdp5_kms);
-int mdp5_enable(struct mdp5_kms *mdp5_kms);
-
void mdp5_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask,
uint32_t old_irqmask);
void mdp5_irq_preinstall(struct msm_kms *kms);
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c
index 9c34d78..f2a0db7 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c
@@ -31,6 +31,10 @@ struct msm_mdss {
struct regulator *vdd;
+ struct clk *ahb_clk;
+ struct clk *axi_clk;
+ struct clk *vsync_clk;
+
struct {
volatile unsigned long enabled_mask;
struct irq_domain *domain;
@@ -140,6 +144,51 @@ static int mdss_irq_domain_init(struct msm_mdss *mdss)
return 0;
}
+int msm_mdss_enable(struct msm_mdss *mdss)
+{
+ DBG("");
+
+ clk_prepare_enable(mdss->ahb_clk);
+ if (mdss->axi_clk)
+ clk_prepare_enable(mdss->axi_clk);
+ if (mdss->vsync_clk)
+ clk_prepare_enable(mdss->vsync_clk);
+
+ return 0;
+}
+
+int msm_mdss_disable(struct msm_mdss *mdss)
+{
+ DBG("");
+
+ if (mdss->vsync_clk)
+ clk_disable_unprepare(mdss->vsync_clk);
+ if (mdss->axi_clk)
+ clk_disable_unprepare(mdss->axi_clk);
+ clk_disable_unprepare(mdss->ahb_clk);
+
+ return 0;
+}
+
+static int msm_mdss_get_clocks(struct msm_mdss *mdss)
+{
+ struct platform_device *pdev = to_platform_device(mdss->dev->dev);
+
+ mdss->ahb_clk = msm_clk_get(pdev, "iface");
+ if (IS_ERR(mdss->ahb_clk))
+ mdss->ahb_clk = NULL;
+
+ mdss->axi_clk = msm_clk_get(pdev, "bus");
+ if (IS_ERR(mdss->axi_clk))
+ mdss->axi_clk = NULL;
+
+ mdss->vsync_clk = msm_clk_get(pdev, "vsync");
+ if (IS_ERR(mdss->vsync_clk))
+ mdss->vsync_clk = NULL;
+
+ return 0;
+}
+
void msm_mdss_destroy(struct drm_device *dev)
{
struct msm_drm_private *priv = dev->dev_private;
@@ -153,8 +202,6 @@ void msm_mdss_destroy(struct drm_device *dev)
regulator_disable(mdss->vdd);
- pm_runtime_put_sync(dev->dev);
-
pm_runtime_disable(dev->dev);
}
@@ -190,6 +237,12 @@ int msm_mdss_init(struct drm_device *dev)
goto fail;
}
+ ret = msm_mdss_get_clocks(mdss);
+ if (ret) {
+ dev_err(dev->dev, "failed to get clocks: %d\n", ret);
+ goto fail;
+ }
+
/* Regulator to enable GDSCs in downstream kernels */
mdss->vdd = devm_regulator_get(dev->dev, "vdd");
if (IS_ERR(mdss->vdd)) {
@@ -221,12 +274,6 @@ int msm_mdss_init(struct drm_device *dev)
pm_runtime_enable(dev->dev);
- /*
- * TODO: This is needed as the MDSS GDSC is only tied to MDSS's power
- * domain. Remove this once runtime PM is adapted for all the devices.
- */
- pm_runtime_get_sync(dev->dev);
-
return 0;
fail_irq:
regulator_disable(mdss->vdd);
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
index 61f39c8..4b22ac3 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
@@ -246,7 +246,6 @@ static const struct drm_plane_funcs mdp5_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = mdp5_plane_destroy,
- .set_property = drm_atomic_helper_plane_set_property,
.atomic_set_property = mdp5_plane_atomic_set_property,
.atomic_get_property = mdp5_plane_atomic_get_property,
.reset = mdp5_plane_reset,
@@ -259,7 +258,6 @@ static const struct drm_plane_funcs mdp5_cursor_plane_funcs = {
.update_plane = mdp5_update_cursor_plane_legacy,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = mdp5_plane_destroy,
- .set_property = drm_atomic_helper_plane_set_property,
.atomic_set_property = mdp5_plane_atomic_set_property,
.atomic_get_property = mdp5_plane_atomic_get_property,
.reset = mdp5_plane_reset,
@@ -1139,12 +1137,12 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev,
ret = drm_universal_plane_init(dev, plane, 0xff,
&mdp5_cursor_plane_funcs,
mdp5_plane->formats, mdp5_plane->nformats,
- type, NULL);
+ NULL, type, NULL);
else
ret = drm_universal_plane_init(dev, plane, 0xff,
&mdp5_plane_funcs,
mdp5_plane->formats, mdp5_plane->nformats,
- type, NULL);
+ NULL, type, NULL);
if (ret)
goto fail;
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c
index 58f712d..ae4983d 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c
@@ -28,6 +28,13 @@ struct mdp5_smp {
int blk_cnt;
int blk_size;
+
+ /* register cache */
+ u32 alloc_w[22];
+ u32 alloc_r[22];
+ u32 pipe_reqprio_fifo_wm0[SSPP_MAX];
+ u32 pipe_reqprio_fifo_wm1[SSPP_MAX];
+ u32 pipe_reqprio_fifo_wm2[SSPP_MAX];
};
static inline
@@ -98,16 +105,15 @@ static int smp_request_block(struct mdp5_smp *smp,
static void set_fifo_thresholds(struct mdp5_smp *smp,
enum mdp5_pipe pipe, int nblks)
{
- struct mdp5_kms *mdp5_kms = get_kms(smp);
u32 smp_entries_per_blk = smp->blk_size / (128 / BITS_PER_BYTE);
u32 val;
/* 1/4 of SMP pool that is being fetched */
val = (nblks * smp_entries_per_blk) / 4;
- mdp5_write(mdp5_kms, REG_MDP5_PIPE_REQPRIO_FIFO_WM_0(pipe), val * 1);
- mdp5_write(mdp5_kms, REG_MDP5_PIPE_REQPRIO_FIFO_WM_1(pipe), val * 2);
- mdp5_write(mdp5_kms, REG_MDP5_PIPE_REQPRIO_FIFO_WM_2(pipe), val * 3);
+ smp->pipe_reqprio_fifo_wm0[pipe] = val * 1;
+ smp->pipe_reqprio_fifo_wm1[pipe] = val * 2;
+ smp->pipe_reqprio_fifo_wm2[pipe] = val * 3;
}
/*
@@ -222,7 +228,6 @@ void mdp5_smp_release(struct mdp5_smp *smp, struct mdp5_smp_state *state,
static unsigned update_smp_state(struct mdp5_smp *smp,
u32 cid, mdp5_smp_state_t *assigned)
{
- struct mdp5_kms *mdp5_kms = get_kms(smp);
int cnt = smp->blk_cnt;
unsigned nblks = 0;
u32 blk, val;
@@ -231,7 +236,7 @@ static unsigned update_smp_state(struct mdp5_smp *smp,
int idx = blk / 3;
int fld = blk % 3;
- val = mdp5_read(mdp5_kms, REG_MDP5_SMP_ALLOC_W_REG(idx));
+ val = smp->alloc_w[idx];
switch (fld) {
case 0:
@@ -248,8 +253,8 @@ static unsigned update_smp_state(struct mdp5_smp *smp,
break;
}
- mdp5_write(mdp5_kms, REG_MDP5_SMP_ALLOC_W_REG(idx), val);
- mdp5_write(mdp5_kms, REG_MDP5_SMP_ALLOC_R_REG(idx), val);
+ smp->alloc_w[idx] = val;
+ smp->alloc_r[idx] = val;
nblks++;
}
@@ -257,6 +262,39 @@ static unsigned update_smp_state(struct mdp5_smp *smp,
return nblks;
}
+static void write_smp_alloc_regs(struct mdp5_smp *smp)
+{
+ struct mdp5_kms *mdp5_kms = get_kms(smp);
+ int i, num_regs;
+
+ num_regs = smp->blk_cnt / 3 + 1;
+
+ for (i = 0; i < num_regs; i++) {
+ mdp5_write(mdp5_kms, REG_MDP5_SMP_ALLOC_W_REG(i),
+ smp->alloc_w[i]);
+ mdp5_write(mdp5_kms, REG_MDP5_SMP_ALLOC_R_REG(i),
+ smp->alloc_r[i]);
+ }
+}
+
+static void write_smp_fifo_regs(struct mdp5_smp *smp)
+{
+ struct mdp5_kms *mdp5_kms = get_kms(smp);
+ int i;
+
+ for (i = 0; i < mdp5_kms->num_hwpipes; i++) {
+ struct mdp5_hw_pipe *hwpipe = mdp5_kms->hwpipes[i];
+ enum mdp5_pipe pipe = hwpipe->pipe;
+
+ mdp5_write(mdp5_kms, REG_MDP5_PIPE_REQPRIO_FIFO_WM_0(pipe),
+ smp->pipe_reqprio_fifo_wm0[pipe]);
+ mdp5_write(mdp5_kms, REG_MDP5_PIPE_REQPRIO_FIFO_WM_1(pipe),
+ smp->pipe_reqprio_fifo_wm1[pipe]);
+ mdp5_write(mdp5_kms, REG_MDP5_PIPE_REQPRIO_FIFO_WM_2(pipe),
+ smp->pipe_reqprio_fifo_wm2[pipe]);
+ }
+}
+
void mdp5_smp_prepare_commit(struct mdp5_smp *smp, struct mdp5_smp_state *state)
{
enum mdp5_pipe pipe;
@@ -277,6 +315,9 @@ void mdp5_smp_prepare_commit(struct mdp5_smp *smp, struct mdp5_smp_state *state)
set_fifo_thresholds(smp, pipe, nblks);
}
+ write_smp_alloc_regs(smp);
+ write_smp_fifo_regs(smp);
+
state->assigned = 0;
}
@@ -289,6 +330,8 @@ void mdp5_smp_complete_commit(struct mdp5_smp *smp, struct mdp5_smp_state *state
set_fifo_thresholds(smp, pipe, 0);
}
+ write_smp_fifo_regs(smp);
+
state->released = 0;
}
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
index 9633a68b..025d454 100644
--- a/drivers/gpu/drm/msm/msm_atomic.c
+++ b/drivers/gpu/drm/msm/msm_atomic.c
@@ -84,13 +84,13 @@ static void msm_atomic_wait_for_commit_done(struct drm_device *dev,
struct drm_atomic_state *old_state)
{
struct drm_crtc *crtc;
- struct drm_crtc_state *crtc_state;
+ struct drm_crtc_state *new_crtc_state;
struct msm_drm_private *priv = old_state->dev->dev_private;
struct msm_kms *kms = priv->kms;
int i;
- for_each_crtc_in_state(old_state, crtc, crtc_state, i) {
- if (!crtc->state->enable)
+ for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
+ if (!new_crtc_state->active)
continue;
kms->funcs->wait_for_crtc_commit_done(kms, crtc);
@@ -195,7 +195,7 @@ int msm_atomic_commit(struct drm_device *dev,
struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state;
struct drm_plane *plane;
- struct drm_plane_state *plane_state;
+ struct drm_plane_state *old_plane_state, *new_plane_state;
int i, ret;
ret = drm_atomic_helper_prepare_planes(dev, state);
@@ -211,19 +211,19 @@ int msm_atomic_commit(struct drm_device *dev,
/*
* Figure out what crtcs we have:
*/
- for_each_crtc_in_state(state, crtc, crtc_state, i)
+ for_each_new_crtc_in_state(state, crtc, crtc_state, i)
c->crtc_mask |= drm_crtc_mask(crtc);
/*
* Figure out what fence to wait for:
*/
- for_each_plane_in_state(state, plane, plane_state, i) {
- if ((plane->state->fb != plane_state->fb) && plane_state->fb) {
- struct drm_gem_object *obj = msm_framebuffer_bo(plane_state->fb, 0);
+ for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
+ if ((new_plane_state->fb != old_plane_state->fb) && new_plane_state->fb) {
+ struct drm_gem_object *obj = msm_framebuffer_bo(new_plane_state->fb, 0);
struct msm_gem_object *msm_obj = to_msm_bo(obj);
struct dma_fence *fence = reservation_object_get_excl_rcu(msm_obj->resv);
- drm_atomic_set_fence_for_plane(plane_state, fence);
+ drm_atomic_set_fence_for_plane(new_plane_state, fence);
}
}
@@ -232,20 +232,18 @@ int msm_atomic_commit(struct drm_device *dev,
* mark our set of crtc's as busy:
*/
ret = start_atomic(dev->dev_private, c->crtc_mask);
- if (ret) {
- kfree(c);
- goto error;
- }
+ if (ret)
+ goto err_free;
+
+ BUG_ON(drm_atomic_helper_swap_state(state, false) < 0);
/*
* This is the point of no return - everything below never fails except
* when the hw goes bonghits. Which means we can commit the new state on
* the software side now.
+ *
+ * swap driver private state while still holding state_lock
*/
-
- drm_atomic_helper_swap_state(state, true);
-
- /* swap driver private state while still holding state_lock */
if (to_kms_state(state)->state)
priv->kms->funcs->swap_state(priv->kms, state);
@@ -275,6 +273,8 @@ int msm_atomic_commit(struct drm_device *dev,
return 0;
+err_free:
+ kfree(c);
error:
drm_atomic_helper_cleanup_planes(dev, state);
return ret;
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index f49f6ac..606df7b 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -73,6 +73,10 @@ bool dumpstate = false;
MODULE_PARM_DESC(dumpstate, "Dump KMS state on errors");
module_param(dumpstate, bool, 0600);
+static bool modeset = true;
+MODULE_PARM_DESC(modeset, "Use kernel modesetting [KMS] (1=on (default), 0=disable)");
+module_param(modeset, bool, 0600);
+
/*
* Util/helpers:
*/
@@ -832,7 +836,6 @@ static struct drm_driver msm_driver = {
.gem_vm_ops = &vm_ops,
.dumb_create = msm_gem_dumb_create,
.dumb_map_offset = msm_gem_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_export = drm_gem_prime_export,
@@ -879,8 +882,37 @@ static int msm_pm_resume(struct device *dev)
}
#endif
+#ifdef CONFIG_PM
+static int msm_runtime_suspend(struct device *dev)
+{
+ struct drm_device *ddev = dev_get_drvdata(dev);
+ struct msm_drm_private *priv = ddev->dev_private;
+
+ DBG("");
+
+ if (priv->mdss)
+ return msm_mdss_disable(priv->mdss);
+
+ return 0;
+}
+
+static int msm_runtime_resume(struct device *dev)
+{
+ struct drm_device *ddev = dev_get_drvdata(dev);
+ struct msm_drm_private *priv = ddev->dev_private;
+
+ DBG("");
+
+ if (priv->mdss)
+ return msm_mdss_enable(priv->mdss);
+
+ return 0;
+}
+#endif
+
static const struct dev_pm_ops msm_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(msm_pm_suspend, msm_pm_resume)
+ SET_RUNTIME_PM_OPS(msm_runtime_suspend, msm_runtime_resume, NULL)
};
/*
@@ -1104,6 +1136,9 @@ static struct platform_driver msm_platform_driver = {
static int __init msm_drm_register(void)
{
+ if (!modeset)
+ return -EINVAL;
+
DBG("init");
msm_mdp_register();
msm_dsi_register();
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index fc8d24f..5e8109c 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -55,8 +55,6 @@ struct msm_fence_cb;
struct msm_gem_address_space;
struct msm_gem_vma;
-#define NUM_DOMAINS 2 /* one for KMS, then one per gpu core (?) */
-
struct msm_file_private {
/* currently we don't do anything useful with this.. but when
* per-context address spaces are supported we'd keep track of
@@ -237,6 +235,12 @@ struct drm_gem_object *msm_gem_new(struct drm_device *dev,
uint32_t size, uint32_t flags);
struct drm_gem_object *msm_gem_new_locked(struct drm_device *dev,
uint32_t size, uint32_t flags);
+void *msm_gem_kernel_new(struct drm_device *dev, uint32_t size,
+ uint32_t flags, struct msm_gem_address_space *aspace,
+ struct drm_gem_object **bo, uint64_t *iova);
+void *msm_gem_kernel_new_locked(struct drm_device *dev, uint32_t size,
+ uint32_t flags, struct msm_gem_address_space *aspace,
+ struct drm_gem_object **bo, uint64_t *iova);
struct drm_gem_object *msm_gem_import(struct drm_device *dev,
struct dma_buf *dmabuf, struct sg_table *sgt);
@@ -248,10 +252,10 @@ uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb,
struct msm_gem_address_space *aspace, int plane);
struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane);
const struct msm_format *msm_framebuffer_format(struct drm_framebuffer *fb);
-struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
- const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos);
struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd);
+struct drm_framebuffer * msm_alloc_stolen_fb(struct drm_device *dev,
+ int w, int h, int p, uint32_t format);
struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev);
void msm_fbdev_free(struct drm_device *dev);
diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c
index 6ecb7b1..fc175e7 100644
--- a/drivers/gpu/drm/msm/msm_fb.c
+++ b/drivers/gpu/drm/msm/msm_fb.c
@@ -20,6 +20,7 @@
#include "msm_drv.h"
#include "msm_kms.h"
+#include "msm_gem.h"
struct msm_framebuffer {
struct drm_framebuffer base;
@@ -28,6 +29,8 @@ struct msm_framebuffer {
};
#define to_msm_framebuffer(x) container_of(x, struct msm_framebuffer, base)
+static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
+ const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos);
static int msm_framebuffer_create_handle(struct drm_framebuffer *fb,
struct drm_file *file_priv,
@@ -161,7 +164,7 @@ out_unref:
return ERR_PTR(ret);
}
-struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
+static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos)
{
struct msm_drm_private *priv = dev->dev_private;
@@ -237,3 +240,43 @@ fail:
return ERR_PTR(ret);
}
+
+struct drm_framebuffer *
+msm_alloc_stolen_fb(struct drm_device *dev, int w, int h, int p, uint32_t format)
+{
+ struct drm_mode_fb_cmd2 mode_cmd = {
+ .pixel_format = format,
+ .width = w,
+ .height = h,
+ .pitches = { p },
+ };
+ struct drm_gem_object *bo;
+ struct drm_framebuffer *fb;
+ int size;
+
+ /* allocate backing bo */
+ size = mode_cmd.pitches[0] * mode_cmd.height;
+ DBG("allocating %d bytes for fb %d", size, dev->primary->index);
+ bo = msm_gem_new(dev, size, MSM_BO_SCANOUT | MSM_BO_WC | MSM_BO_STOLEN);
+ if (IS_ERR(bo)) {
+ dev_warn(dev->dev, "could not allocate stolen bo\n");
+ /* try regular bo: */
+ bo = msm_gem_new(dev, size, MSM_BO_SCANOUT | MSM_BO_WC);
+ }
+ if (IS_ERR(bo)) {
+ dev_err(dev->dev, "failed to allocate buffer object\n");
+ return ERR_CAST(bo);
+ }
+
+ fb = msm_framebuffer_init(dev, &mode_cmd, &bo);
+ if (IS_ERR(fb)) {
+ dev_err(dev->dev, "failed to allocate fb\n");
+ /* note: if fb creation failed, we can't rely on fb destroy
+ * to unref the bo:
+ */
+ drm_gem_object_unreference_unlocked(bo);
+ return ERR_CAST(fb);
+ }
+
+ return fb;
+}
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c
index 5ecf4ff..c178563 100644
--- a/drivers/gpu/drm/msm/msm_fbdev.c
+++ b/drivers/gpu/drm/msm/msm_fbdev.c
@@ -19,7 +19,6 @@
#include <drm/drm_fb_helper.h>
#include "msm_drv.h"
-#include "msm_gem.h"
#include "msm_kms.h"
extern int msm_gem_mmap_obj(struct drm_gem_object *obj,
@@ -35,7 +34,6 @@ static int msm_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma);
struct msm_fbdev {
struct drm_fb_helper base;
struct drm_framebuffer *fb;
- struct drm_gem_object *bo;
};
static struct fb_ops msm_fb_ops = {
@@ -57,16 +55,16 @@ static int msm_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
struct drm_fb_helper *helper = (struct drm_fb_helper *)info->par;
struct msm_fbdev *fbdev = to_msm_fbdev(helper);
- struct drm_gem_object *drm_obj = fbdev->bo;
+ struct drm_gem_object *bo = msm_framebuffer_bo(fbdev->fb, 0);
int ret = 0;
- ret = drm_gem_mmap_obj(drm_obj, drm_obj->size, vma);
+ ret = drm_gem_mmap_obj(bo, bo->size, vma);
if (ret) {
pr_err("%s:drm_gem_mmap_obj fail\n", __func__);
return ret;
}
- return msm_gem_mmap_obj(drm_obj, vma);
+ return msm_gem_mmap_obj(bo, vma);
}
static int msm_fbdev_create(struct drm_fb_helper *helper,
@@ -76,47 +74,30 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
struct drm_device *dev = helper->dev;
struct msm_drm_private *priv = dev->dev_private;
struct drm_framebuffer *fb = NULL;
+ struct drm_gem_object *bo;
struct fb_info *fbi = NULL;
- struct drm_mode_fb_cmd2 mode_cmd = {0};
uint64_t paddr;
- int ret, size;
+ uint32_t format;
+ int ret, pitch;
+
+ format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth);
DBG("create fbdev: %dx%d@%d (%dx%d)", sizes->surface_width,
sizes->surface_height, sizes->surface_bpp,
sizes->fb_width, sizes->fb_height);
- mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
- sizes->surface_depth);
-
- mode_cmd.width = sizes->surface_width;
- mode_cmd.height = sizes->surface_height;
-
- mode_cmd.pitches[0] = align_pitch(
- mode_cmd.width, sizes->surface_bpp);
+ pitch = align_pitch(sizes->surface_width, sizes->surface_bpp);
+ fb = msm_alloc_stolen_fb(dev, sizes->surface_width,
+ sizes->surface_height, pitch, format);
- /* allocate backing bo */
- size = mode_cmd.pitches[0] * mode_cmd.height;
- DBG("allocating %d bytes for fb %d", size, dev->primary->index);
- fbdev->bo = msm_gem_new(dev, size, MSM_BO_SCANOUT |
- MSM_BO_WC | MSM_BO_STOLEN);
- if (IS_ERR(fbdev->bo)) {
- ret = PTR_ERR(fbdev->bo);
- fbdev->bo = NULL;
- dev_err(dev->dev, "failed to allocate buffer object: %d\n", ret);
- goto fail;
- }
-
- fb = msm_framebuffer_init(dev, &mode_cmd, &fbdev->bo);
if (IS_ERR(fb)) {
dev_err(dev->dev, "failed to allocate fb\n");
- /* note: if fb creation failed, we can't rely on fb destroy
- * to unref the bo:
- */
- drm_gem_object_unreference_unlocked(fbdev->bo);
ret = PTR_ERR(fb);
goto fail;
}
+ bo = msm_framebuffer_bo(fb, 0);
+
mutex_lock(&dev->struct_mutex);
/*
@@ -124,7 +105,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
* in panic (ie. lock-safe, etc) we could avoid pinning the
* buffer now:
*/
- ret = msm_gem_get_iova(fbdev->bo, priv->kms->aspace, &paddr);
+ ret = msm_gem_get_iova(bo, priv->kms->aspace, &paddr);
if (ret) {
dev_err(dev->dev, "failed to get buffer obj iova: %d\n", ret);
goto fail_unlock;
@@ -143,7 +124,6 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
helper->fb = fb;
fbi->par = helper;
- fbi->flags = FBINFO_DEFAULT;
fbi->fbops = &msm_fb_ops;
strcpy(fbi->fix.id, "msm");
@@ -153,14 +133,14 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
dev->mode_config.fb_base = paddr;
- fbi->screen_base = msm_gem_get_vaddr(fbdev->bo);
+ fbi->screen_base = msm_gem_get_vaddr(bo);
if (IS_ERR(fbi->screen_base)) {
ret = PTR_ERR(fbi->screen_base);
goto fail_unlock;
}
- fbi->screen_size = fbdev->bo->size;
+ fbi->screen_size = bo->size;
fbi->fix.smem_start = paddr;
- fbi->fix.smem_len = fbdev->bo->size;
+ fbi->fix.smem_len = bo->size;
DBG("par=%p, %dx%d", fbi->par, fbi->var.xres, fbi->var.yres);
DBG("allocated %dx%d fb", fbdev->fb->width, fbdev->fb->height);
@@ -242,7 +222,9 @@ void msm_fbdev_free(struct drm_device *dev)
/* this will free the backing object */
if (fbdev->fb) {
- msm_gem_put_vaddr(fbdev->bo);
+ struct drm_gem_object *bo =
+ msm_framebuffer_bo(fbdev->fb, 0);
+ msm_gem_put_vaddr(bo);
drm_framebuffer_remove(fbdev->fb);
}
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index a0c60e7..f15821a0 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -1024,3 +1024,49 @@ fail:
drm_gem_object_unreference_unlocked(obj);
return ERR_PTR(ret);
}
+
+static void *_msm_gem_kernel_new(struct drm_device *dev, uint32_t size,
+ uint32_t flags, struct msm_gem_address_space *aspace,
+ struct drm_gem_object **bo, uint64_t *iova, bool locked)
+{
+ void *vaddr;
+ struct drm_gem_object *obj = _msm_gem_new(dev, size, flags, locked);
+ int ret;
+
+ if (IS_ERR(obj))
+ return ERR_CAST(obj);
+
+ if (iova) {
+ ret = msm_gem_get_iova(obj, aspace, iova);
+ if (ret) {
+ drm_gem_object_unreference(obj);
+ return ERR_PTR(ret);
+ }
+ }
+
+ vaddr = msm_gem_get_vaddr(obj);
+ if (!vaddr) {
+ msm_gem_put_iova(obj, aspace);
+ drm_gem_object_unreference(obj);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ if (bo)
+ *bo = obj;
+
+ return vaddr;
+}
+
+void *msm_gem_kernel_new(struct drm_device *dev, uint32_t size,
+ uint32_t flags, struct msm_gem_address_space *aspace,
+ struct drm_gem_object **bo, uint64_t *iova)
+{
+ return _msm_gem_kernel_new(dev, size, flags, aspace, bo, iova, false);
+}
+
+void *msm_gem_kernel_new_locked(struct drm_device *dev, uint32_t size,
+ uint32_t flags, struct msm_gem_address_space *aspace,
+ struct drm_gem_object **bo, uint64_t *iova)
+{
+ return _msm_gem_kernel_new(dev, size, flags, aspace, bo, iova, true);
+}
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 9f3dbc2..ffbff27 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -562,11 +562,49 @@ static int get_clocks(struct platform_device *pdev, struct msm_gpu *gpu)
return 0;
}
+static struct msm_gem_address_space *
+msm_gpu_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev,
+ uint64_t va_start, uint64_t va_end)
+{
+ struct iommu_domain *iommu;
+ struct msm_gem_address_space *aspace;
+ int ret;
+
+ /*
+ * Setup IOMMU.. eventually we will (I think) do this once per context
+ * and have separate page tables per context. For now, to keep things
+ * simple and to get something working, just use a single address space:
+ */
+ iommu = iommu_domain_alloc(&platform_bus_type);
+ if (!iommu)
+ return NULL;
+
+ iommu->geometry.aperture_start = va_start;
+ iommu->geometry.aperture_end = va_end;
+
+ dev_info(gpu->dev->dev, "%s: using IOMMU\n", gpu->name);
+
+ aspace = msm_gem_address_space_create(&pdev->dev, iommu, "gpu");
+ if (IS_ERR(aspace)) {
+ dev_err(gpu->dev->dev, "failed to init iommu: %ld\n",
+ PTR_ERR(aspace));
+ iommu_domain_free(iommu);
+ return ERR_CAST(aspace);
+ }
+
+ ret = aspace->mmu->funcs->attach(aspace->mmu, NULL, 0);
+ if (ret) {
+ msm_gem_address_space_put(aspace);
+ return ERR_PTR(ret);
+ }
+
+ return aspace;
+}
+
int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
struct msm_gpu *gpu, const struct msm_gpu_funcs *funcs,
const char *name, struct msm_gpu_config *config)
{
- struct iommu_domain *iommu;
int ret;
if (WARN_ON(gpu->num_perfcntrs > ARRAY_SIZE(gpu->last_cntrs)))
@@ -636,28 +674,19 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
if (IS_ERR(gpu->gpu_cx))
gpu->gpu_cx = NULL;
- /* Setup IOMMU.. eventually we will (I think) do this once per context
- * and have separate page tables per context. For now, to keep things
- * simple and to get something working, just use a single address space:
- */
- iommu = iommu_domain_alloc(&platform_bus_type);
- if (iommu) {
- iommu->geometry.aperture_start = config->va_start;
- iommu->geometry.aperture_end = config->va_end;
-
- dev_info(drm->dev, "%s: using IOMMU\n", name);
- gpu->aspace = msm_gem_address_space_create(&pdev->dev,
- iommu, "gpu");
- if (IS_ERR(gpu->aspace)) {
- ret = PTR_ERR(gpu->aspace);
- dev_err(drm->dev, "failed to init iommu: %d\n", ret);
- gpu->aspace = NULL;
- iommu_domain_free(iommu);
- goto fail;
- }
+ gpu->pdev = pdev;
+ platform_set_drvdata(pdev, gpu);
+
+ bs_init(gpu);
- } else {
+ gpu->aspace = msm_gpu_create_address_space(gpu, pdev,
+ config->va_start, config->va_end);
+
+ if (gpu->aspace == NULL)
dev_info(drm->dev, "%s: no IOMMU, fallback to VRAM carveout!\n", name);
+ else if (IS_ERR(gpu->aspace)) {
+ ret = PTR_ERR(gpu->aspace);
+ goto fail;
}
/* Create ringbuffer: */
@@ -669,14 +698,10 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
goto fail;
}
- gpu->pdev = pdev;
- platform_set_drvdata(pdev, gpu);
-
- bs_init(gpu);
-
return 0;
fail:
+ platform_set_drvdata(pdev, NULL);
return ret;
}
@@ -693,7 +718,9 @@ void msm_gpu_cleanup(struct msm_gpu *gpu)
msm_gem_put_iova(gpu->rb->bo, gpu->aspace);
msm_ringbuffer_destroy(gpu->rb);
}
-
- if (gpu->fctx)
- msm_fence_context_free(gpu->fctx);
+ if (gpu->aspace) {
+ gpu->aspace->mmu->funcs->detach(gpu->aspace->mmu,
+ NULL, 0);
+ msm_gem_address_space_put(gpu->aspace);
+ }
}
diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
index a8f2ba5..17d5824 100644
--- a/drivers/gpu/drm/msm/msm_kms.h
+++ b/drivers/gpu/drm/msm/msm_kms.h
@@ -99,5 +99,7 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev);
struct msm_kms *mdp5_kms_init(struct drm_device *dev);
int msm_mdss_init(struct drm_device *dev);
void msm_mdss_destroy(struct drm_device *dev);
+int msm_mdss_enable(struct msm_mdss *mdss);
+int msm_mdss_disable(struct msm_mdss *mdss);
#endif /* __MSM_KMS_H__ */
diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c
index 791bca3..bf065a5 100644
--- a/drivers/gpu/drm/msm/msm_ringbuffer.c
+++ b/drivers/gpu/drm/msm/msm_ringbuffer.c
@@ -33,16 +33,14 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int size)
}
ring->gpu = gpu;
- ring->bo = msm_gem_new(gpu->dev, size, MSM_BO_WC);
- if (IS_ERR(ring->bo)) {
- ret = PTR_ERR(ring->bo);
- ring->bo = NULL;
- goto fail;
- }
- ring->start = msm_gem_get_vaddr(ring->bo);
+ /* Pass NULL for the iova pointer - we will map it later */
+ ring->start = msm_gem_kernel_new(gpu->dev, size, MSM_BO_WC,
+ gpu->aspace, &ring->bo, NULL);
+
if (IS_ERR(ring->start)) {
ret = PTR_ERR(ring->start);
+ ring->start = 0;
goto fail;
}
ring->end = ring->start + (size / 4);
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
index d1b9c34..7fbad9c 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
@@ -190,7 +190,7 @@ static int mxsfb_load(struct drm_device *drm, unsigned long flags)
}
ret = drm_simple_display_pipe_init(drm, &mxsfb->pipe, &mxsfb_funcs,
- mxsfb_formats, ARRAY_SIZE(mxsfb_formats),
+ mxsfb_formats, ARRAY_SIZE(mxsfb_formats), NULL,
&mxsfb->connector);
if (ret < 0) {
dev_err(drm->dev, "Cannot setup simple display pipe\n");
@@ -256,7 +256,6 @@ static void mxsfb_unload(struct drm_device *drm)
drm_kms_helper_poll_fini(drm);
drm_mode_config_cleanup(drm);
- drm_vblank_cleanup(drm);
pm_runtime_get_sync(drm->dev);
drm_irq_uninstall(drm);
@@ -335,11 +334,9 @@ static struct drm_driver mxsfb_driver = {
.irq_uninstall = mxsfb_irq_preinstall,
.enable_vblank = mxsfb_enable_vblank,
.disable_vblank = mxsfb_disable_vblank,
- .gem_free_object = drm_gem_cma_free_object,
+ .gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_export = drm_gem_prime_export,
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_out.c b/drivers/gpu/drm/mxsfb/mxsfb_out.c
index f7d729a..e5edf01 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_out.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_out.c
@@ -74,7 +74,6 @@ static void mxsfb_panel_connector_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs mxsfb_panel_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = mxsfb_panel_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = mxsfb_panel_connector_destroy,
diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
index 4b4b0b4..6aa6ee1 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
@@ -764,13 +764,18 @@ nv_crtc_gamma_load(struct drm_crtc *crtc)
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
struct drm_device *dev = nv_crtc->base.dev;
struct rgb { uint8_t r, g, b; } __attribute__((packed)) *rgbs;
+ u16 *r, *g, *b;
int i;
rgbs = (struct rgb *)nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index].DAC;
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
+
for (i = 0; i < 256; i++) {
- rgbs[i].r = nv_crtc->lut.r[i] >> 8;
- rgbs[i].g = nv_crtc->lut.g[i] >> 8;
- rgbs[i].b = nv_crtc->lut.b[i] >> 8;
+ rgbs[i].r = *r++ >> 8;
+ rgbs[i].g = *g++ >> 8;
+ rgbs[i].b = *b++ >> 8;
}
nouveau_hw_load_state_palette(dev, nv_crtc->index, &nv04_display(dev)->mode_reg);
@@ -792,13 +797,6 @@ nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
struct drm_modeset_acquire_ctx *ctx)
{
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- int i;
-
- for (i = 0; i < size; i++) {
- nv_crtc->lut.r[i] = r[i];
- nv_crtc->lut.g[i] = g[i];
- nv_crtc->lut.b[i] = b[i];
- }
/* We need to know the depth before we upload, but it's possible to
* get called before a framebuffer is bound. If this is the case,
@@ -1095,25 +1093,51 @@ static const struct drm_crtc_helper_funcs nv04_crtc_helper_funcs = {
.mode_set = nv_crtc_mode_set,
.mode_set_base = nv04_crtc_mode_set_base,
.mode_set_base_atomic = nv04_crtc_mode_set_base_atomic,
- .load_lut = nv_crtc_gamma_load,
.disable = nv_crtc_disable,
};
+static const uint32_t modeset_formats[] = {
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_XRGB1555,
+};
+
+static struct drm_plane *
+create_primary_plane(struct drm_device *dev)
+{
+ struct drm_plane *primary;
+ int ret;
+
+ primary = kzalloc(sizeof(*primary), GFP_KERNEL);
+ if (primary == NULL) {
+ DRM_DEBUG_KMS("Failed to allocate primary plane\n");
+ return NULL;
+ }
+
+ /* possible_crtc's will be filled in later by crtc_init */
+ ret = drm_universal_plane_init(dev, primary, 0,
+ &drm_primary_helper_funcs,
+ modeset_formats,
+ ARRAY_SIZE(modeset_formats), NULL,
+ DRM_PLANE_TYPE_PRIMARY, NULL);
+ if (ret) {
+ kfree(primary);
+ primary = NULL;
+ }
+
+ return primary;
+}
+
int
nv04_crtc_create(struct drm_device *dev, int crtc_num)
{
struct nouveau_crtc *nv_crtc;
- int ret, i;
+ int ret;
nv_crtc = kzalloc(sizeof(*nv_crtc), GFP_KERNEL);
if (!nv_crtc)
return -ENOMEM;
- for (i = 0; i < 256; i++) {
- nv_crtc->lut.r[i] = i << 8;
- nv_crtc->lut.g[i] = i << 8;
- nv_crtc->lut.b[i] = i << 8;
- }
nv_crtc->lut.depth = 0;
nv_crtc->index = crtc_num;
@@ -1122,7 +1146,9 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num)
nv_crtc->save = nv_crtc_save;
nv_crtc->restore = nv_crtc_restore;
- drm_crtc_init(dev, &nv_crtc->base, &nv04_crtc_funcs);
+ drm_crtc_init_with_planes(dev, &nv_crtc->base,
+ create_primary_plane(dev), NULL,
+ &nv04_crtc_funcs, NULL);
drm_crtc_helper_add(&nv_crtc->base, &nv04_crtc_helper_funcs);
drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256);
diff --git a/drivers/gpu/drm/nouveau/dispnv04/overlay.c b/drivers/gpu/drm/nouveau/dispnv04/overlay.c
index e54944d..c8c2333 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/overlay.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/overlay.c
@@ -63,6 +63,7 @@ static uint32_t formats[] = {
DRM_FORMAT_YUYV,
DRM_FORMAT_UYVY,
DRM_FORMAT_NV12,
+ DRM_FORMAT_NV21,
};
/* Sine can be approximated with
@@ -90,6 +91,26 @@ cos_mul(int degrees, int factor)
}
static int
+verify_scaling(const struct drm_framebuffer *fb, uint8_t shift,
+ uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h,
+ uint32_t crtc_w, uint32_t crtc_h)
+{
+ if (crtc_w < (src_w >> shift) || crtc_h < (src_h >> shift)) {
+ DRM_DEBUG_KMS("Unsuitable framebuffer scaling: %dx%d -> %dx%d\n",
+ src_w, src_h, crtc_w, crtc_h);
+ return -ERANGE;
+ }
+
+ if (src_x != 0 || src_y != 0) {
+ DRM_DEBUG_KMS("Unsuitable framebuffer offset: %d,%d\n",
+ src_x, src_y);
+ return -ERANGE;
+ }
+
+ return 0;
+}
+
+static int
nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
struct drm_framebuffer *fb, int crtc_x, int crtc_y,
unsigned int crtc_w, unsigned int crtc_h,
@@ -107,7 +128,9 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
bool flip = nv_plane->flip;
int soff = NV_PCRTC0_SIZE * nv_crtc->index;
int soff2 = NV_PCRTC0_SIZE * !nv_crtc->index;
- int format, ret;
+ unsigned shift = drm->client.device.info.chipset >= 0x30 ? 1 : 3;
+ unsigned format = 0;
+ int ret;
/* Source parameters given in 16.16 fixed point, ignore fractional. */
src_x >>= 16;
@@ -115,18 +138,9 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
src_w >>= 16;
src_h >>= 16;
- format = ALIGN(src_w * 4, 0x100);
-
- if (format > 0xffff)
- return -ERANGE;
-
- if (drm->client.device.info.chipset >= 0x30) {
- if (crtc_w < (src_w >> 1) || crtc_h < (src_h >> 1))
- return -ERANGE;
- } else {
- if (crtc_w < (src_w >> 3) || crtc_h < (src_h >> 3))
- return -ERANGE;
- }
+ ret = verify_scaling(fb, shift, 0, 0, src_w, src_h, crtc_w, crtc_h);
+ if (ret)
+ return ret;
ret = nouveau_bo_pin(nv_fb->nvbo, TTM_PL_FLAG_VRAM, false);
if (ret)
@@ -146,21 +160,23 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
nvif_wr32(dev, NV_PVIDEO_POINT_OUT(flip), crtc_y << 16 | crtc_x);
nvif_wr32(dev, NV_PVIDEO_SIZE_OUT(flip), crtc_h << 16 | crtc_w);
- if (fb->format->format != DRM_FORMAT_UYVY)
+ if (fb->format->format == DRM_FORMAT_YUYV ||
+ fb->format->format == DRM_FORMAT_NV12)
format |= NV_PVIDEO_FORMAT_COLOR_LE_CR8YB8CB8YA8;
- if (fb->format->format == DRM_FORMAT_NV12)
+ if (fb->format->format == DRM_FORMAT_NV12 ||
+ fb->format->format == DRM_FORMAT_NV21)
format |= NV_PVIDEO_FORMAT_PLANAR;
if (nv_plane->iturbt_709)
format |= NV_PVIDEO_FORMAT_MATRIX_ITURBT709;
if (nv_plane->colorkey & (1 << 24))
format |= NV_PVIDEO_FORMAT_DISPLAY_COLOR_KEY;
- if (fb->format->format == DRM_FORMAT_NV12) {
+ if (format & NV_PVIDEO_FORMAT_PLANAR) {
nvif_wr32(dev, NV_PVIDEO_UVPLANE_BASE(flip), 0);
nvif_wr32(dev, NV_PVIDEO_UVPLANE_OFFSET_BUFF(flip),
nv_fb->nvbo->bo.offset + fb->offsets[1]);
}
- nvif_wr32(dev, NV_PVIDEO_FORMAT(flip), format);
+ nvif_wr32(dev, NV_PVIDEO_FORMAT(flip), format | fb->pitches[0]);
nvif_wr32(dev, NV_PVIDEO_STOP, 0);
/* TODO: wait for vblank? */
nvif_wr32(dev, NV_PVIDEO_BUFFER, flip ? 0x10 : 0x1);
@@ -357,7 +373,7 @@ nv04_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
struct nouveau_bo *cur = nv_plane->cur;
uint32_t overlay = 1;
int brightness = (nv_plane->brightness - 512) * 62 / 512;
- int pitch, ret, i;
+ int ret, i;
/* Source parameters given in 16.16 fixed point, ignore fractional. */
src_x >>= 16;
@@ -365,17 +381,9 @@ nv04_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
src_w >>= 16;
src_h >>= 16;
- pitch = ALIGN(src_w * 4, 0x100);
-
- if (pitch > 0xffff)
- return -ERANGE;
-
- /* TODO: Compute an offset? Not sure how to do this for YUYV. */
- if (src_x != 0 || src_y != 0)
- return -ERANGE;
-
- if (crtc_w < src_w || crtc_h < src_h)
- return -ERANGE;
+ ret = verify_scaling(fb, 0, src_x, src_y, src_w, src_h, crtc_w, crtc_h);
+ if (ret)
+ return ret;
ret = nouveau_bo_pin(nv_fb->nvbo, TTM_PL_FLAG_VRAM, false);
if (ret)
@@ -389,8 +397,9 @@ nv04_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
for (i = 0; i < 2; i++) {
nvif_wr32(dev, NV_PVIDEO_BUFF0_START_ADDRESS + 4 * i,
- nv_fb->nvbo->bo.offset);
- nvif_wr32(dev, NV_PVIDEO_BUFF0_PITCH_LENGTH + 4 * i, pitch);
+ nv_fb->nvbo->bo.offset);
+ nvif_wr32(dev, NV_PVIDEO_BUFF0_PITCH_LENGTH + 4 * i,
+ fb->pitches[0]);
nvif_wr32(dev, NV_PVIDEO_BUFF0_OFFSET + 4 * i, 0);
}
nvif_wr32(dev, NV_PVIDEO_WINDOW_START, crtc_y << 16 | crtc_x);
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/conn.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/conn.h
index e8e77ee..deb4772 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/conn.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/conn.h
@@ -18,6 +18,7 @@ enum dcb_connector_type {
DCB_CONNECTOR_HDMI_C = 0x63,
DCB_CONNECTOR_DMS59_DP0 = 0x64,
DCB_CONNECTOR_DMS59_DP1 = 0x65,
+ DCB_CONNECTOR_WFD = 0x70,
DCB_CONNECTOR_NONE = 0xff
};
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dcb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dcb.h
index 4892a65..903d117 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dcb.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dcb.h
@@ -6,6 +6,7 @@ enum dcb_output_type {
DCB_OUTPUT_TMDS = 0x2,
DCB_OUTPUT_LVDS = 0x3,
DCB_OUTPUT_DP = 0x6,
+ DCB_OUTPUT_WFD = 0x8,
DCB_OUTPUT_EOL = 0xe,
DCB_OUTPUT_UNUSED = 0xf,
DCB_OUTPUT_ANY = -1,
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h
index b268b96..1bfd93b 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h
@@ -96,4 +96,5 @@ int g84_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
int gt215_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
int gf119_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
int gm107_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
+int gm200_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index b998c33..dd6fba5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -351,11 +351,8 @@ static int parse_fp_mode_table(struct drm_device *dev, struct nvbios *bios)
struct lvdstableheader lth;
if (bios->fp.fptablepointer == 0x0) {
- /* Apple cards don't have the fp table; the laptops use DDC */
- /* The table is also missing on some x86 IGPs */
-#ifndef __powerpc__
- NV_ERROR(drm, "Pointer to flat panel table invalid\n");
-#endif
+ /* Most laptop cards lack an fp table. They use DDC. */
+ NV_DEBUG(drm, "Pointer to flat panel table invalid\n");
bios->digital_min_front_porch = 0x4b;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index dab78c6..70d8e0d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -770,9 +770,6 @@ nouveau_connector_set_property(struct drm_connector *connector,
struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
int ret;
- if (drm_drv_uses_atomic_modeset(connector->dev))
- return drm_atomic_helper_connector_set_property(connector, property, value);
-
ret = connector->funcs->atomic_set_property(&nv_connector->base,
&asyc->state,
property, value);
@@ -1075,17 +1072,9 @@ nouveau_connector_helper_funcs = {
.best_encoder = nouveau_connector_best_encoder,
};
-static int
-nouveau_connector_dpms(struct drm_connector *connector, int mode)
-{
- if (drm_drv_uses_atomic_modeset(connector->dev))
- return drm_atomic_helper_connector_dpms(connector, mode);
- return drm_helper_connector_dpms(connector, mode);
-}
-
static const struct drm_connector_funcs
nouveau_connector_funcs = {
- .dpms = nouveau_connector_dpms,
+ .dpms = drm_helper_connector_dpms,
.reset = nouveau_conn_reset,
.detect = nouveau_connector_detect,
.force = nouveau_connector_force,
@@ -1100,7 +1089,7 @@ nouveau_connector_funcs = {
static const struct drm_connector_funcs
nouveau_connector_funcs_lvds = {
- .dpms = nouveau_connector_dpms,
+ .dpms = drm_helper_connector_dpms,
.reset = nouveau_conn_reset,
.detect = nouveau_connector_detect_lvds,
.force = nouveau_connector_force,
@@ -1195,6 +1184,7 @@ drm_conntype_from_dcb(enum dcb_connector_type dcb)
case DCB_CONNECTOR_HDMI_0 :
case DCB_CONNECTOR_HDMI_1 :
case DCB_CONNECTOR_HDMI_C : return DRM_MODE_CONNECTOR_HDMIA;
+ case DCB_CONNECTOR_WFD : return DRM_MODE_CONNECTOR_VIRTUAL;
default:
break;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_crtc.h b/drivers/gpu/drm/nouveau/nouveau_crtc.h
index 050fcf3..b7a18fb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_crtc.h
+++ b/drivers/gpu/drm/nouveau/nouveau_crtc.h
@@ -61,9 +61,6 @@ struct nouveau_crtc {
struct {
struct nouveau_bo *nvbo;
- uint16_t r[256];
- uint16_t g[256];
- uint16_t b[256];
int depth;
} lut;
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index f362c9f..2e7785f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -159,8 +159,6 @@ nouveau_display_vblank_fini(struct drm_device *dev)
{
struct drm_crtc *crtc;
- drm_vblank_cleanup(dev);
-
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
nvif_notify_fini(&nv_crtc->vblank);
@@ -233,9 +231,30 @@ nouveau_framebuffer_new(struct drm_device *dev,
struct nouveau_bo *nvbo,
struct nouveau_framebuffer **pfb)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_framebuffer *fb;
int ret;
+ /* YUV overlays have special requirements pre-NV50 */
+ if (drm->client.device.info.family < NV_DEVICE_INFO_V0_TESLA &&
+
+ (mode_cmd->pixel_format == DRM_FORMAT_YUYV ||
+ mode_cmd->pixel_format == DRM_FORMAT_UYVY ||
+ mode_cmd->pixel_format == DRM_FORMAT_NV12 ||
+ mode_cmd->pixel_format == DRM_FORMAT_NV21) &&
+ (mode_cmd->pitches[0] & 0x3f || /* align 64 */
+ mode_cmd->pitches[0] >= 0x10000 || /* at most 64k pitch */
+ (mode_cmd->pitches[1] && /* pitches for planes must match */
+ mode_cmd->pitches[0] != mode_cmd->pitches[1]))) {
+ struct drm_format_name_buf format_name;
+ DRM_DEBUG_KMS("Unsuitable framebuffer: format: %s; pitches: 0x%x\n 0x%x\n",
+ drm_get_format_name(mode_cmd->pixel_format,
+ &format_name),
+ mode_cmd->pitches[0],
+ mode_cmd->pitches[1]);
+ return -EINVAL;
+ }
+
if (!(fb = *pfb = kzalloc(sizeof(*fb), GFP_KERNEL)))
return -ENOMEM;
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 90757af..595630d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -585,18 +585,18 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime)
nouveau_led_suspend(dev);
if (dev->mode_config.num_crtc) {
- NV_INFO(drm, "suspending console...\n");
+ NV_DEBUG(drm, "suspending console...\n");
nouveau_fbcon_set_suspend(dev, 1);
- NV_INFO(drm, "suspending display...\n");
+ NV_DEBUG(drm, "suspending display...\n");
ret = nouveau_display_suspend(dev, runtime);
if (ret)
return ret;
}
- NV_INFO(drm, "evicting buffers...\n");
+ NV_DEBUG(drm, "evicting buffers...\n");
ttm_bo_evict_mm(&drm->ttm.bdev, TTM_PL_VRAM);
- NV_INFO(drm, "waiting for kernel channels to go idle...\n");
+ NV_DEBUG(drm, "waiting for kernel channels to go idle...\n");
if (drm->cechan) {
ret = nouveau_channel_idle(drm->cechan);
if (ret)
@@ -609,7 +609,7 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime)
goto fail_display;
}
- NV_INFO(drm, "suspending fence...\n");
+ NV_DEBUG(drm, "suspending fence...\n");
if (drm->fence && nouveau_fence(drm)->suspend) {
if (!nouveau_fence(drm)->suspend(drm)) {
ret = -ENOMEM;
@@ -617,7 +617,7 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime)
}
}
- NV_INFO(drm, "suspending object tree...\n");
+ NV_DEBUG(drm, "suspending object tree...\n");
ret = nvif_client_suspend(&drm->client.base);
if (ret)
goto fail_client;
@@ -630,7 +630,7 @@ fail_client:
fail_display:
if (dev->mode_config.num_crtc) {
- NV_INFO(drm, "resuming display...\n");
+ NV_DEBUG(drm, "resuming display...\n");
nouveau_display_resume(dev, runtime);
}
return ret;
@@ -641,19 +641,19 @@ nouveau_do_resume(struct drm_device *dev, bool runtime)
{
struct nouveau_drm *drm = nouveau_drm(dev);
- NV_INFO(drm, "resuming object tree...\n");
+ NV_DEBUG(drm, "resuming object tree...\n");
nvif_client_resume(&drm->client.base);
- NV_INFO(drm, "resuming fence...\n");
+ NV_DEBUG(drm, "resuming fence...\n");
if (drm->fence && nouveau_fence(drm)->resume)
nouveau_fence(drm)->resume(drm);
nouveau_run_vbios_init(dev);
if (dev->mode_config.num_crtc) {
- NV_INFO(drm, "resuming display...\n");
+ NV_DEBUG(drm, "resuming display...\n");
nouveau_display_resume(dev, runtime);
- NV_INFO(drm, "resuming console...\n");
+ NV_DEBUG(drm, "resuming console...\n");
nouveau_fbcon_set_suspend(dev, 0);
}
@@ -998,7 +998,6 @@ driver_stub = {
.dumb_create = nouveau_display_dumb_create,
.dumb_map_offset = nouveau_display_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
@@ -1098,7 +1097,6 @@ static int __init
nouveau_drm_init(void)
{
driver_pci = driver_stub;
- driver_pci.set_busid = drm_pci_set_busid;
driver_platform = driver_stub;
nouveau_display_options();
@@ -1117,7 +1115,12 @@ nouveau_drm_init(void)
nouveau_register_dsm_handler();
nouveau_backlight_ctor();
- return drm_pci_init(&driver_pci, &nouveau_drm_pci_driver);
+
+#ifdef CONFIG_PCI
+ return pci_register_driver(&nouveau_drm_pci_driver);
+#else
+ return 0;
+#endif
}
static void __exit
@@ -1126,7 +1129,9 @@ nouveau_drm_exit(void)
if (!nouveau_modeset)
return;
- drm_pci_exit(&driver_pci, &nouveau_drm_pci_driver);
+#ifdef CONFIG_PCI
+ pci_unregister_driver(&nouveau_drm_pci_driver);
+#endif
nouveau_backlight_dtor();
nouveau_unregister_dsm_handler();
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index 2665a07..f770784 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -278,26 +278,6 @@ nouveau_fbcon_accel_init(struct drm_device *dev)
info->fbops = &nouveau_fbcon_ops;
}
-static void nouveau_fbcon_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno)
-{
- struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
-
- nv_crtc->lut.r[regno] = red;
- nv_crtc->lut.g[regno] = green;
- nv_crtc->lut.b[regno] = blue;
-}
-
-static void nouveau_fbcon_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
- u16 *blue, int regno)
-{
- struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
-
- *red = nv_crtc->lut.r[regno];
- *green = nv_crtc->lut.g[regno];
- *blue = nv_crtc->lut.b[regno];
-}
-
static void
nouveau_fbcon_zfill(struct drm_device *dev, struct nouveau_fbdev *fbcon)
{
@@ -467,8 +447,6 @@ void nouveau_fbcon_gpu_lockup(struct fb_info *info)
}
static const struct drm_fb_helper_funcs nouveau_fbcon_helper_funcs = {
- .gamma_set = nouveau_fbcon_gamma_set,
- .gamma_get = nouveau_fbcon_gamma_get,
.fb_probe = nouveau_fbcon_create,
};
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c
index 999c35a..b0ad7fc 100644
--- a/drivers/gpu/drm/nouveau/nouveau_ttm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c
@@ -179,7 +179,8 @@ nouveau_gart_manager_new(struct ttm_mem_type_manager *man,
}
static void
-nouveau_gart_manager_debug(struct ttm_mem_type_manager *man, const char *prefix)
+nouveau_gart_manager_debug(struct ttm_mem_type_manager *man,
+ struct drm_printer *printer)
{
}
@@ -252,7 +253,8 @@ nv04_gart_manager_new(struct ttm_mem_type_manager *man,
}
static void
-nv04_gart_manager_debug(struct ttm_mem_type_manager *man, const char *prefix)
+nv04_gart_manager_debug(struct ttm_mem_type_manager *man,
+ struct drm_printer *printer)
{
}
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 2bc0dc9..2dbf62a 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -1055,7 +1055,6 @@ nv50_wndw = {
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = nv50_wndw_destroy,
.reset = nv50_wndw_reset,
- .set_property = drm_atomic_helper_plane_set_property,
.atomic_duplicate_state = nv50_wndw_atomic_duplicate_state,
.atomic_destroy_state = nv50_wndw_atomic_destroy_state,
};
@@ -1083,8 +1082,9 @@ nv50_wndw_ctor(const struct nv50_wndw_func *func, struct drm_device *dev,
wndw->func = func;
wndw->dmac = dmac;
- ret = drm_universal_plane_init(dev, &wndw->plane, 0, &nv50_wndw, format,
- nformat, type, "%s-%d", name, index);
+ ret = drm_universal_plane_init(dev, &wndw->plane, 0, &nv50_wndw,
+ format, nformat, NULL,
+ type, "%s-%d", name, index);
if (ret)
return ret;
@@ -2103,7 +2103,7 @@ nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state)
NV_ATOMIC(drm, "%s atomic_check %d\n", crtc->name, asyh->state.active);
if (asyh->state.active) {
- for_each_connector_in_state(asyh->state.state, conn, conns, i) {
+ for_each_new_connector_in_state(asyh->state.state, conn, conns, i) {
if (conns->crtc == crtc) {
asyc = nouveau_conn_atom(conns);
break;
@@ -2204,28 +2204,29 @@ nv50_head_lut_load(struct drm_crtc *crtc)
struct nv50_disp *disp = nv50_disp(crtc->dev);
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
void __iomem *lut = nvbo_kmap_obj_iovirtual(nv_crtc->lut.nvbo);
+ u16 *r, *g, *b;
int i;
- for (i = 0; i < 256; i++) {
- u16 r = nv_crtc->lut.r[i] >> 2;
- u16 g = nv_crtc->lut.g[i] >> 2;
- u16 b = nv_crtc->lut.b[i] >> 2;
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
+ for (i = 0; i < 256; i++) {
if (disp->disp->oclass < GF110_DISP) {
- writew(r + 0x0000, lut + (i * 0x08) + 0);
- writew(g + 0x0000, lut + (i * 0x08) + 2);
- writew(b + 0x0000, lut + (i * 0x08) + 4);
+ writew((*r++ >> 2) + 0x0000, lut + (i * 0x08) + 0);
+ writew((*g++ >> 2) + 0x0000, lut + (i * 0x08) + 2);
+ writew((*b++ >> 2) + 0x0000, lut + (i * 0x08) + 4);
} else {
- writew(r + 0x6000, lut + (i * 0x20) + 0);
- writew(g + 0x6000, lut + (i * 0x20) + 2);
- writew(b + 0x6000, lut + (i * 0x20) + 4);
+ /* 0x6000 interferes with the 14-bit color??? */
+ writew((*r++ >> 2) + 0x6000, lut + (i * 0x20) + 0);
+ writew((*g++ >> 2) + 0x6000, lut + (i * 0x20) + 2);
+ writew((*b++ >> 2) + 0x6000, lut + (i * 0x20) + 4);
}
}
}
static const struct drm_crtc_helper_funcs
nv50_head_help = {
- .load_lut = nv50_head_lut_load,
.atomic_check = nv50_head_atomic_check,
};
@@ -2234,15 +2235,6 @@ nv50_head_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
uint32_t size,
struct drm_modeset_acquire_ctx *ctx)
{
- struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- u32 i;
-
- for (i = 0; i < size; i++) {
- nv_crtc->lut.r[i] = r[i];
- nv_crtc->lut.g[i] = g[i];
- nv_crtc->lut.b[i] = b[i];
- }
-
nv50_head_lut_load(crtc);
return 0;
}
@@ -2325,7 +2317,6 @@ nv50_head_func = {
.destroy = nv50_head_destroy,
.set_config = drm_atomic_helper_set_config,
.page_flip = drm_atomic_helper_page_flip,
- .set_property = drm_atomic_helper_crtc_set_property,
.atomic_duplicate_state = nv50_head_atomic_duplicate_state,
.atomic_destroy_state = nv50_head_atomic_destroy_state,
};
@@ -2340,19 +2331,13 @@ nv50_head_create(struct drm_device *dev, int index)
struct nv50_base *base;
struct nv50_curs *curs;
struct drm_crtc *crtc;
- int ret, i;
+ int ret;
head = kzalloc(sizeof(*head), GFP_KERNEL);
if (!head)
return -ENOMEM;
head->base.index = index;
- for (i = 0; i < 256; i++) {
- head->base.lut.r[i] = i << 8;
- head->base.lut.g[i] = i << 8;
- head->base.lut.b[i] = i << 8;
- }
-
ret = nv50_base_new(drm, head, &base);
if (ret == 0)
ret = nv50_curs_new(drm, head, &curs);
@@ -2762,7 +2747,8 @@ nv50_hdmi_enable(struct drm_encoder *encoder, struct drm_display_mode *mode)
if (!drm_detect_hdmi_monitor(nv_connector->edid))
return;
- ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame.avi, mode);
+ ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame.avi, mode,
+ false);
if (!ret) {
/* We have an AVI InfoFrame, populate it to the display */
args.pwr.avi_infoframe_length
@@ -3119,11 +3105,9 @@ nv50_mstc_destroy(struct drm_connector *connector)
static const struct drm_connector_funcs
nv50_mstc = {
- .dpms = drm_atomic_helper_connector_dpms,
.reset = nouveau_conn_reset,
.detect = nv50_mstc_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
- .set_property = drm_atomic_helper_connector_set_property,
.destroy = nv50_mstc_destroy,
.atomic_duplicate_state = nouveau_conn_atomic_duplicate_state,
.atomic_destroy_state = nouveau_conn_atomic_destroy_state,
@@ -3157,7 +3141,7 @@ nv50_mstc_new(struct nv50_mstm *mstm, struct drm_dp_mst_port *port,
mstc->connector.funcs->reset(&mstc->connector);
nouveau_conn_attach_properties(&mstc->connector);
- for (i = 0; i < ARRAY_SIZE(mstm->msto) && mstm->msto; i++)
+ for (i = 0; i < ARRAY_SIZE(mstm->msto) && mstm->msto[i]; i++)
drm_mode_connector_attach_encoder(&mstc->connector, &mstm->msto[i]->encoder);
drm_object_attach_property(&mstc->connector.base, dev->mode_config.path_property, 0);
@@ -3913,9 +3897,9 @@ static void
nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
{
struct drm_device *dev = state->dev;
- struct drm_crtc_state *crtc_state;
+ struct drm_crtc_state *new_crtc_state, *old_crtc_state;
struct drm_crtc *crtc;
- struct drm_plane_state *plane_state;
+ struct drm_plane_state *new_plane_state;
struct drm_plane *plane;
struct nouveau_drm *drm = nouveau_drm(dev);
struct nv50_disp *disp = nv50_disp(dev);
@@ -3934,13 +3918,13 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
mutex_lock(&disp->mutex);
/* Disable head(s). */
- for_each_crtc_in_state(state, crtc, crtc_state, i) {
- struct nv50_head_atom *asyh = nv50_head_atom(crtc->state);
+ for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+ struct nv50_head_atom *asyh = nv50_head_atom(new_crtc_state);
struct nv50_head *head = nv50_head(crtc);
NV_ATOMIC(drm, "%s: clr %04x (set %04x)\n", crtc->name,
asyh->clr.mask, asyh->set.mask);
- if (crtc_state->active && !asyh->state.active)
+ if (old_crtc_state->active && !new_crtc_state->active)
drm_crtc_vblank_off(crtc);
if (asyh->clr.mask) {
@@ -3950,8 +3934,8 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
}
/* Disable plane(s). */
- for_each_plane_in_state(state, plane, plane_state, i) {
- struct nv50_wndw_atom *asyw = nv50_wndw_atom(plane->state);
+ for_each_new_plane_in_state(state, plane, new_plane_state, i) {
+ struct nv50_wndw_atom *asyw = nv50_wndw_atom(new_plane_state);
struct nv50_wndw *wndw = nv50_wndw(plane);
NV_ATOMIC(drm, "%s: clr %02x (set %02x)\n", plane->name,
@@ -4016,8 +4000,8 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
}
/* Update head(s). */
- for_each_crtc_in_state(state, crtc, crtc_state, i) {
- struct nv50_head_atom *asyh = nv50_head_atom(crtc->state);
+ for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+ struct nv50_head_atom *asyh = nv50_head_atom(new_crtc_state);
struct nv50_head *head = nv50_head(crtc);
NV_ATOMIC(drm, "%s: set %04x (clr %04x)\n", crtc->name,
@@ -4028,17 +4012,17 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
interlock_core = 1;
}
- if (asyh->state.active) {
- if (!crtc_state->active)
+ if (new_crtc_state->active) {
+ if (!old_crtc_state->active)
drm_crtc_vblank_on(crtc);
- if (asyh->state.event)
+ if (new_crtc_state->event)
drm_crtc_vblank_get(crtc);
}
}
/* Update plane(s). */
- for_each_plane_in_state(state, plane, plane_state, i) {
- struct nv50_wndw_atom *asyw = nv50_wndw_atom(plane->state);
+ for_each_new_plane_in_state(state, plane, new_plane_state, i) {
+ struct nv50_wndw_atom *asyw = nv50_wndw_atom(new_plane_state);
struct nv50_wndw *wndw = nv50_wndw(plane);
NV_ATOMIC(drm, "%s: set %02x (clr %02x)\n", plane->name,
@@ -4068,25 +4052,26 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
mutex_unlock(&disp->mutex);
/* Wait for HW to signal completion. */
- for_each_plane_in_state(state, plane, plane_state, i) {
- struct nv50_wndw_atom *asyw = nv50_wndw_atom(plane->state);
+ for_each_new_plane_in_state(state, plane, new_plane_state, i) {
+ struct nv50_wndw_atom *asyw = nv50_wndw_atom(new_plane_state);
struct nv50_wndw *wndw = nv50_wndw(plane);
int ret = nv50_wndw_wait_armed(wndw, asyw);
if (ret)
NV_ERROR(drm, "%s: timeout\n", plane->name);
}
- for_each_crtc_in_state(state, crtc, crtc_state, i) {
- if (crtc->state->event) {
+ for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
+ if (new_crtc_state->event) {
unsigned long flags;
/* Get correct count/ts if racing with vblank irq */
- if (crtc->state->active)
- drm_accurate_vblank_count(crtc);
+ if (new_crtc_state->active)
+ drm_crtc_accurate_vblank_count(crtc);
spin_lock_irqsave(&crtc->dev->event_lock, flags);
- drm_crtc_send_vblank_event(crtc, crtc->state->event);
+ drm_crtc_send_vblank_event(crtc, new_crtc_state->event);
spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
- crtc->state->event = NULL;
- if (crtc->state->active)
+
+ new_crtc_state->event = NULL;
+ if (new_crtc_state->active)
drm_crtc_vblank_put(crtc);
}
}
@@ -4111,7 +4096,7 @@ nv50_disp_atomic_commit(struct drm_device *dev,
{
struct nouveau_drm *drm = nouveau_drm(dev);
struct nv50_disp *disp = nv50_disp(dev);
- struct drm_plane_state *plane_state;
+ struct drm_plane_state *old_plane_state;
struct drm_plane *plane;
struct drm_crtc *crtc;
bool active = false;
@@ -4134,12 +4119,17 @@ nv50_disp_atomic_commit(struct drm_device *dev,
if (!nonblock) {
ret = drm_atomic_helper_wait_for_fences(dev, state, true);
if (ret)
- goto done;
+ goto err_cleanup;
}
- for_each_plane_in_state(state, plane, plane_state, i) {
- struct nv50_wndw_atom *asyw = nv50_wndw_atom(plane_state);
+ ret = drm_atomic_helper_swap_state(state, true);
+ if (ret)
+ goto err_cleanup;
+
+ for_each_old_plane_in_state(state, plane, old_plane_state, i) {
+ struct nv50_wndw_atom *asyw = nv50_wndw_atom(old_plane_state);
struct nv50_wndw *wndw = nv50_wndw(plane);
+
if (asyw->set.image) {
asyw->ntfy.handle = wndw->dmac->sync.handle;
asyw->ntfy.offset = wndw->ntfy;
@@ -4150,7 +4140,6 @@ nv50_disp_atomic_commit(struct drm_device *dev,
}
}
- drm_atomic_helper_swap_state(state, true);
drm_atomic_state_get(state);
if (nonblock)
@@ -4162,7 +4151,7 @@ nv50_disp_atomic_commit(struct drm_device *dev,
if (crtc->state->enable) {
if (!drm->have_disp_power_ref) {
drm->have_disp_power_ref = true;
- return ret;
+ return 0;
}
active = true;
break;
@@ -4174,6 +4163,9 @@ nv50_disp_atomic_commit(struct drm_device *dev,
drm->have_disp_power_ref = false;
}
+err_cleanup:
+ if (ret)
+ drm_atomic_helper_cleanup_planes(dev, state);
done:
pm_runtime_put_autosuspend(dev->dev);
return ret;
@@ -4200,18 +4192,19 @@ nv50_disp_outp_atomic_add(struct nv50_atom *atom, struct drm_encoder *encoder)
static int
nv50_disp_outp_atomic_check_clr(struct nv50_atom *atom,
- struct drm_connector *connector)
+ struct drm_connector_state *old_connector_state)
{
- struct drm_encoder *encoder = connector->state->best_encoder;
- struct drm_crtc_state *crtc_state;
+ struct drm_encoder *encoder = old_connector_state->best_encoder;
+ struct drm_crtc_state *old_crtc_state, *new_crtc_state;
struct drm_crtc *crtc;
struct nv50_outp_atom *outp;
- if (!(crtc = connector->state->crtc))
+ if (!(crtc = old_connector_state->crtc))
return 0;
- crtc_state = drm_atomic_get_existing_crtc_state(&atom->state, crtc);
- if (crtc->state->active && drm_atomic_crtc_needs_modeset(crtc_state)) {
+ old_crtc_state = drm_atomic_get_old_crtc_state(&atom->state, crtc);
+ new_crtc_state = drm_atomic_get_new_crtc_state(&atom->state, crtc);
+ if (old_crtc_state->active && drm_atomic_crtc_needs_modeset(new_crtc_state)) {
outp = nv50_disp_outp_atomic_add(atom, encoder);
if (IS_ERR(outp))
return PTR_ERR(outp);
@@ -4232,15 +4225,15 @@ nv50_disp_outp_atomic_check_set(struct nv50_atom *atom,
struct drm_connector_state *connector_state)
{
struct drm_encoder *encoder = connector_state->best_encoder;
- struct drm_crtc_state *crtc_state;
+ struct drm_crtc_state *new_crtc_state;
struct drm_crtc *crtc;
struct nv50_outp_atom *outp;
if (!(crtc = connector_state->crtc))
return 0;
- crtc_state = drm_atomic_get_existing_crtc_state(&atom->state, crtc);
- if (crtc_state->active && drm_atomic_crtc_needs_modeset(crtc_state)) {
+ new_crtc_state = drm_atomic_get_new_crtc_state(&atom->state, crtc);
+ if (new_crtc_state->active && drm_atomic_crtc_needs_modeset(new_crtc_state)) {
outp = nv50_disp_outp_atomic_add(atom, encoder);
if (IS_ERR(outp))
return PTR_ERR(outp);
@@ -4256,7 +4249,7 @@ static int
nv50_disp_atomic_check(struct drm_device *dev, struct drm_atomic_state *state)
{
struct nv50_atom *atom = nv50_atom(state);
- struct drm_connector_state *connector_state;
+ struct drm_connector_state *old_connector_state, *new_connector_state;
struct drm_connector *connector;
int ret, i;
@@ -4264,12 +4257,12 @@ nv50_disp_atomic_check(struct drm_device *dev, struct drm_atomic_state *state)
if (ret)
return ret;
- for_each_connector_in_state(state, connector, connector_state, i) {
- ret = nv50_disp_outp_atomic_check_clr(atom, connector);
+ for_each_oldnew_connector_in_state(state, connector, old_connector_state, new_connector_state, i) {
+ ret = nv50_disp_outp_atomic_check_clr(atom, old_connector_state);
if (ret)
return ret;
- ret = nv50_disp_outp_atomic_check_set(atom, connector_state);
+ ret = nv50_disp_outp_atomic_check_set(atom, new_connector_state);
if (ret)
return ret;
}
@@ -4458,11 +4451,13 @@ nv50_display_create(struct drm_device *dev)
/* create crtc objects to represent the hw heads */
if (disp->disp->oclass >= GF110_DISP)
- crtcs = nvif_rd32(&device->object, 0x022448);
+ crtcs = nvif_rd32(&device->object, 0x612004) & 0xf;
else
- crtcs = 2;
+ crtcs = 0x3;
- for (i = 0; i < crtcs; i++) {
+ for (i = 0; i < fls(crtcs); i++) {
+ if (!(crtcs & (1 << i)))
+ continue;
ret = nv50_head_create(dev, i);
if (ret)
goto out;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
index 7bdc7a5..e096a5d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
@@ -2043,6 +2043,7 @@ nv120_chipset = {
.mxm = nv50_mxm_new,
.pci = gk104_pci_new,
.pmu = gm107_pmu_new,
+ .therm = gm200_therm_new,
.secboot = gm200_secboot_new,
.timer = gk20a_timer_new,
.top = gk104_top_new,
@@ -2077,6 +2078,7 @@ nv124_chipset = {
.mxm = nv50_mxm_new,
.pci = gk104_pci_new,
.pmu = gm107_pmu_new,
+ .therm = gm200_therm_new,
.secboot = gm200_secboot_new,
.timer = gk20a_timer_new,
.top = gk104_top_new,
@@ -2111,6 +2113,7 @@ nv126_chipset = {
.mxm = nv50_mxm_new,
.pci = gk104_pci_new,
.pmu = gm107_pmu_new,
+ .therm = gm200_therm_new,
.secboot = gm200_secboot_new,
.timer = gk20a_timer_new,
.top = gk104_top_new,
@@ -2321,6 +2324,35 @@ nv137_chipset = {
};
static const struct nvkm_device_chip
+nv138_chipset = {
+ .name = "GP108",
+ .bar = gf100_bar_new,
+ .bios = nvkm_bios_new,
+ .bus = gf100_bus_new,
+ .devinit = gm200_devinit_new,
+ .fb = gp102_fb_new,
+ .fuse = gm107_fuse_new,
+ .gpio = gk104_gpio_new,
+ .i2c = gm200_i2c_new,
+ .ibus = gm200_ibus_new,
+ .imem = nv50_instmem_new,
+ .ltc = gp100_ltc_new,
+ .mc = gp100_mc_new,
+ .mmu = gf100_mmu_new,
+ .pci = gp100_pci_new,
+ .pmu = gp102_pmu_new,
+ .timer = gk20a_timer_new,
+ .top = gk104_top_new,
+ .ce[0] = gp102_ce_new,
+ .ce[1] = gp102_ce_new,
+ .ce[2] = gp102_ce_new,
+ .ce[3] = gp102_ce_new,
+ .disp = gp102_disp_new,
+ .dma = gf119_dma_new,
+ .fifo = gp100_fifo_new,
+};
+
+static const struct nvkm_device_chip
nv13b_chipset = {
.name = "GP10B",
.bar = gk20a_bar_new,
@@ -2782,6 +2814,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
case 0x134: device->chip = &nv134_chipset; break;
case 0x136: device->chip = &nv136_chipset; break;
case 0x137: device->chip = &nv137_chipset; break;
+ case 0x138: device->chip = &nv138_chipset; break;
case 0x13b: device->chip = &nv13b_chipset; break;
default:
nvdev_error(device, "unknown chipset (%08x)\n", boot0);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
index 88582af..93a75e5 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
@@ -285,6 +285,10 @@ nvkm_disp_oneinit(struct nvkm_engine *engine)
case DCB_OUTPUT_DP:
ret = nvkm_dp_new(disp, i, &dcbE, &outp);
break;
+ case DCB_OUTPUT_WFD:
+ /* No support for WFD yet. */
+ ret = -ENODEV;
+ continue;
default:
nvkm_warn(subdev, "dcb %d type %d unknown\n",
i, dcbE.type);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c
index b335527..9fd7ae3 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c
@@ -92,5 +92,8 @@ gf119_head = {
int
gf119_head_new(struct nvkm_disp *disp, int id)
{
+ struct nvkm_device *device = disp->engine.subdev.device;
+ if (!(nvkm_rd32(device, 0x612004) & (0x00000001 << id)))
+ return 0;
return nvkm_head_new_(&gf119_head, disp, id);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c
index 8a88952..7fea7d4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c
@@ -124,6 +124,8 @@ nv31_mpeg_tile(struct nvkm_engine *engine, int i, struct nvkm_fb_tile *tile)
static bool
nv31_mpeg_mthd_dma(struct nvkm_device *device, u32 mthd, u32 data)
{
+ struct nv31_mpeg *mpeg = nv31_mpeg(device->mpeg);
+ struct nvkm_subdev *subdev = &mpeg->engine.subdev;
u32 inst = data << 4;
u32 dma0 = nvkm_rd32(device, 0x700000 + inst);
u32 dma1 = nvkm_rd32(device, 0x700004 + inst);
@@ -132,8 +134,11 @@ nv31_mpeg_mthd_dma(struct nvkm_device *device, u32 mthd, u32 data)
u32 size = dma1 + 1;
/* only allow linear DMA objects */
- if (!(dma0 & 0x00002000))
+ if (!(dma0 & 0x00002000)) {
+ nvkm_error(subdev, "inst %08x dma0 %08x dma1 %08x dma2 %08x\n",
+ inst, dma0, dma1, dma2);
return false;
+ }
if (mthd == 0x0190) {
/* DMA_CMD */
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv40.c
index 16de5bd..b5ec7c5 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv40.c
@@ -31,6 +31,8 @@ bool
nv40_mpeg_mthd_dma(struct nvkm_device *device, u32 mthd, u32 data)
{
struct nvkm_instmem *imem = device->imem;
+ struct nv31_mpeg *mpeg = nv31_mpeg(device->mpeg);
+ struct nvkm_subdev *subdev = &mpeg->engine.subdev;
u32 inst = data << 4;
u32 dma0 = nvkm_instmem_rd32(imem, inst + 0);
u32 dma1 = nvkm_instmem_rd32(imem, inst + 4);
@@ -39,8 +41,11 @@ nv40_mpeg_mthd_dma(struct nvkm_device *device, u32 mthd, u32 data)
u32 size = dma1 + 1;
/* only allow linear DMA objects */
- if (!(dma0 & 0x00002000))
+ if (!(dma0 & 0x00002000)) {
+ nvkm_error(subdev, "inst %08x dma0 %08x dma1 %08x dma2 %08x\n",
+ inst, dma0, dma1, dma2);
return false;
+ }
if (mthd == 0x0190) {
/* DMA_CMD */
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c
index d45d794..77273b5 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c
@@ -251,7 +251,7 @@ cmd_write(struct nvkm_msgqueue *priv, struct nvkm_msgqueue_hdr *cmd,
struct nvkm_msgqueue_queue *queue)
{
const struct nvkm_subdev *subdev = priv->falcon->owner;
- static unsigned long timeout = ~0;
+ static unsigned timeout = 2000;
unsigned long end_jiffies = jiffies + msecs_to_jiffies(timeout);
int ret = -EAGAIN;
bool commit = true;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c
index 6d8f212..676c167 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c
@@ -24,6 +24,7 @@
#include "gf100.h"
#include <core/gpuobj.h>
+#include <core/option.h>
#include <subdev/fb.h>
#include <subdev/mmu.h>
@@ -59,6 +60,8 @@ gf100_bar_ctor_vm(struct gf100_bar *bar, struct gf100_bar_vm *bar_vm,
return ret;
bar_len = device->func->resource_size(device, bar_nr);
+ if (bar_nr == 3 && bar->bar2_halve)
+ bar_len >>= 1;
ret = nvkm_vm_new(device, 0, bar_len, 0, key, &vm);
if (ret)
@@ -129,6 +132,8 @@ gf100_bar_init(struct nvkm_bar *base)
if (bar->bar[0].mem) {
addr = nvkm_memory_addr(bar->bar[0].mem) >> 12;
+ if (bar->bar2_halve)
+ addr |= 0x40000000;
nvkm_wr32(device, 0x001714, 0x80000000 | addr);
}
@@ -161,6 +166,7 @@ gf100_bar_new_(const struct nvkm_bar_func *func, struct nvkm_device *device,
if (!(bar = kzalloc(sizeof(*bar), GFP_KERNEL)))
return -ENOMEM;
nvkm_bar_ctor(func, device, index, &bar->base);
+ bar->bar2_halve = nvkm_boolopt(device->cfgopt, "NvBar2Halve", false);
*pbar = &bar->base;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h
index f7dea69..20a5255 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h
@@ -11,6 +11,7 @@ struct gf100_bar_vm {
struct gf100_bar {
struct nvkm_bar base;
+ bool bar2_halve;
struct gf100_bar_vm bar[2];
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c
index 3841ad6..a239e73 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c
@@ -60,12 +60,12 @@ gf100_fb_oneinit(struct nvkm_fb *base)
size = min(size, 0x1000);
ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, size, 0x1000,
- false, &fb->base.mmu_rd);
+ true, &fb->base.mmu_rd);
if (ret)
return ret;
ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, size, 0x1000,
- false, &fb->base.mmu_wr);
+ true, &fb->base.mmu_wr);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c
index d2c4d60..f937664 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c
@@ -27,6 +27,7 @@ static const struct nvkm_mc_map
gf100_mc_reset[] = {
{ 0x00020000, NVKM_ENGINE_MSPDEC },
{ 0x00008000, NVKM_ENGINE_MSVLD },
+ { 0x00002000, NVKM_SUBDEV_PMU, true },
{ 0x00001000, NVKM_ENGINE_GR },
{ 0x00000100, NVKM_ENGINE_FIFO },
{ 0x00000080, NVKM_ENGINE_CE1 },
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c
index eb9b278..a4cb824 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c
@@ -192,6 +192,10 @@ nvkm_pci_new_(const struct nvkm_pci_func *func, struct nvkm_device *device,
}
}
+#ifdef __BIG_ENDIAN
+ pci->msi = false;
+#endif
+
pci->msi = nvkm_boolopt(device->cfgopt, "NvMSI", pci->msi);
if (pci->msi && func->msi_rearm) {
pci->msi = pci_enable_msi(pci->pdev) == 0;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c
index 3306f9f..ce70a19 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c
@@ -75,7 +75,7 @@ nvkm_pmu_reset(struct nvkm_pmu *pmu)
{
struct nvkm_device *device = pmu->subdev.device;
- if (!(nvkm_rd32(device, 0x000200) & 0x00002000))
+ if (!pmu->func->enabled(pmu))
return 0;
/* Inhibit interrupts, and wait for idle. */
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf100.c
index 0e36d4c..0b45865 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf100.c
@@ -24,13 +24,30 @@
#include "priv.h"
#include "fuc/gf100.fuc3.h"
+#include <subdev/mc.h>
+
+void
+gf100_pmu_reset(struct nvkm_pmu *pmu)
+{
+ struct nvkm_device *device = pmu->subdev.device;
+ nvkm_mc_disable(device, NVKM_SUBDEV_PMU);
+ nvkm_mc_enable(device, NVKM_SUBDEV_PMU);
+}
+
+bool
+gf100_pmu_enabled(struct nvkm_pmu *pmu)
+{
+ return nvkm_mc_enabled(pmu->subdev.device, NVKM_SUBDEV_PMU);
+}
+
static const struct nvkm_pmu_func
gf100_pmu = {
.code.data = gf100_pmu_code,
.code.size = sizeof(gf100_pmu_code),
.data.data = gf100_pmu_data,
.data.size = sizeof(gf100_pmu_data),
- .reset = gt215_pmu_reset,
+ .enabled = gf100_pmu_enabled,
+ .reset = gf100_pmu_reset,
.init = gt215_pmu_init,
.fini = gt215_pmu_fini,
.intr = gt215_pmu_intr,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf119.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf119.c
index 0e4ba42..3dfa79d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf119.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf119.c
@@ -30,7 +30,8 @@ gf119_pmu = {
.code.size = sizeof(gf119_pmu_code),
.data.data = gf119_pmu_data,
.data.size = sizeof(gf119_pmu_data),
- .reset = gt215_pmu_reset,
+ .enabled = gf100_pmu_enabled,
+ .reset = gf100_pmu_reset,
.init = gt215_pmu_init,
.fini = gt215_pmu_fini,
.intr = gt215_pmu_intr,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c
index 2ad858d..8f7ec10 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c
@@ -109,7 +109,8 @@ gk104_pmu = {
.code.size = sizeof(gk104_pmu_code),
.data.data = gk104_pmu_data,
.data.size = sizeof(gk104_pmu_data),
- .reset = gt215_pmu_reset,
+ .enabled = gf100_pmu_enabled,
+ .reset = gf100_pmu_reset,
.init = gt215_pmu_init,
.fini = gt215_pmu_fini,
.intr = gt215_pmu_intr,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk110.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk110.c
index fc4b8ec..345741d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk110.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk110.c
@@ -88,7 +88,8 @@ gk110_pmu = {
.code.size = sizeof(gk110_pmu_code),
.data.data = gk110_pmu_data,
.data.size = sizeof(gk110_pmu_data),
- .reset = gt215_pmu_reset,
+ .enabled = gf100_pmu_enabled,
+ .reset = gf100_pmu_reset,
.init = gt215_pmu_init,
.fini = gt215_pmu_fini,
.intr = gt215_pmu_intr,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk208.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk208.c
index e9a9127..e4acf78 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk208.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk208.c
@@ -30,7 +30,8 @@ gk208_pmu = {
.code.size = sizeof(gk208_pmu_code),
.data.data = gk208_pmu_data,
.data.size = sizeof(gk208_pmu_data),
- .reset = gt215_pmu_reset,
+ .enabled = gf100_pmu_enabled,
+ .reset = gf100_pmu_reset,
.init = gt215_pmu_init,
.fini = gt215_pmu_fini,
.intr = gt215_pmu_intr,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c
index 978aae3..05e8185 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c
@@ -196,9 +196,10 @@ gk20a_dvfs_data= {
static const struct nvkm_pmu_func
gk20a_pmu = {
+ .enabled = gf100_pmu_enabled,
.init = gk20a_pmu_init,
.fini = gk20a_pmu_fini,
- .reset = gt215_pmu_reset,
+ .reset = gf100_pmu_reset,
};
int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm107.c
index 9a248ed..459df1e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm107.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm107.c
@@ -32,7 +32,8 @@ gm107_pmu = {
.code.size = sizeof(gm107_pmu_code),
.data.data = gm107_pmu_data,
.data.size = sizeof(gm107_pmu_data),
- .reset = gt215_pmu_reset,
+ .enabled = gf100_pmu_enabled,
+ .reset = gf100_pmu_reset,
.init = gt215_pmu_init,
.fini = gt215_pmu_fini,
.intr = gt215_pmu_intr,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c
index 44bef22..31c8431 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c
@@ -38,6 +38,7 @@ gm20b_pmu_recv(struct nvkm_pmu *pmu)
static const struct nvkm_pmu_func
gm20b_pmu = {
+ .enabled = gf100_pmu_enabled,
.intr = gt215_pmu_intr,
.recv = gm20b_pmu_recv,
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp100.c
index 6c41c20c..e210cd6 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp100.c
@@ -25,7 +25,8 @@
static const struct nvkm_pmu_func
gp100_pmu = {
- .reset = gt215_pmu_reset,
+ .enabled = gf100_pmu_enabled,
+ .reset = gf100_pmu_reset,
};
int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp102.c
index f017352..98c7a2a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp102.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp102.c
@@ -31,8 +31,15 @@ gp102_pmu_reset(struct nvkm_pmu *pmu)
nvkm_mask(device, 0x10a3c0, 0x00000001, 0x00000000);
}
+static bool
+gp102_pmu_enabled(struct nvkm_pmu *pmu)
+{
+ return !(nvkm_rd32(pmu->subdev.device, 0x10a3c0) & 0x00000001);
+}
+
static const struct nvkm_pmu_func
gp102_pmu = {
+ .enabled = gp102_pmu_enabled,
.reset = gp102_pmu_reset,
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gt215.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gt215.c
index 90d428b..e04216d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gt215.c
@@ -180,13 +180,19 @@ gt215_pmu_fini(struct nvkm_pmu *pmu)
nvkm_wr32(pmu->subdev.device, 0x10a014, 0x00000060);
}
-void
+static void
gt215_pmu_reset(struct nvkm_pmu *pmu)
{
struct nvkm_device *device = pmu->subdev.device;
- nvkm_mask(device, 0x000200, 0x00002000, 0x00000000);
- nvkm_mask(device, 0x000200, 0x00002000, 0x00002000);
- nvkm_rd32(device, 0x000200);
+ nvkm_mask(device, 0x022210, 0x00000001, 0x00000000);
+ nvkm_mask(device, 0x022210, 0x00000001, 0x00000001);
+ nvkm_rd32(device, 0x022210);
+}
+
+static bool
+gt215_pmu_enabled(struct nvkm_pmu *pmu)
+{
+ return nvkm_rd32(pmu->subdev.device, 0x022210) & 0x00000001;
}
int
@@ -241,6 +247,7 @@ gt215_pmu = {
.code.size = sizeof(gt215_pmu_code),
.data.data = gt215_pmu_data,
.data.size = sizeof(gt215_pmu_data),
+ .enabled = gt215_pmu_enabled,
.reset = gt215_pmu_reset,
.init = gt215_pmu_init,
.fini = gt215_pmu_fini,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h
index 096cba0..a4c48a1 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h
@@ -20,6 +20,7 @@ struct nvkm_pmu_func {
u32 size;
} data;
+ bool (*enabled)(struct nvkm_pmu *);
void (*reset)(struct nvkm_pmu *);
int (*init)(struct nvkm_pmu *);
void (*fini)(struct nvkm_pmu *);
@@ -30,12 +31,14 @@ struct nvkm_pmu_func {
void (*pgob)(struct nvkm_pmu *, bool);
};
-void gt215_pmu_reset(struct nvkm_pmu *);
int gt215_pmu_init(struct nvkm_pmu *);
void gt215_pmu_fini(struct nvkm_pmu *);
void gt215_pmu_intr(struct nvkm_pmu *);
void gt215_pmu_recv(struct nvkm_pmu *);
int gt215_pmu_send(struct nvkm_pmu *, u32[2], u32, u32, u32, u32);
+bool gf100_pmu_enabled(struct nvkm_pmu *);
+void gf100_pmu_reset(struct nvkm_pmu *);
+
void gk110_pmu_pgob(struct nvkm_pmu *, bool);
#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild
index 135758b..2bafcc1 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild
@@ -11,3 +11,4 @@ nvkm-y += nvkm/subdev/therm/g84.o
nvkm-y += nvkm/subdev/therm/gt215.o
nvkm-y += nvkm/subdev/therm/gf119.o
nvkm-y += nvkm/subdev/therm/gm107.o
+nvkm-y += nvkm/subdev/therm/gm200.o
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/g84.c
index 86e8193..96f8da4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/g84.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/g84.c
@@ -203,7 +203,7 @@ g84_therm_fini(struct nvkm_therm *therm)
nvkm_wr32(device, 0x1100, 0x10000); /* PBUS */
}
-static void
+void
g84_therm_init(struct nvkm_therm *therm)
{
g84_sensor_setup(therm);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gm200.c
new file mode 100644
index 0000000..73dc780
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gm200.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2017 Karol Herbst
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Karol Herbst
+ */
+#include "priv.h"
+
+static const struct nvkm_therm_func
+gm200_therm = {
+ .init = g84_therm_init,
+ .fini = g84_therm_fini,
+ .temp_get = g84_temp_get,
+ .program_alarms = nvkm_therm_program_alarms_polling,
+};
+
+int
+gm200_therm_new(struct nvkm_device *device, int index,
+ struct nvkm_therm **ptherm)
+{
+ return nvkm_therm_new_(&gm200_therm, device, index, ptherm);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h
index 235a5d8..1f46e37 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h
@@ -111,6 +111,7 @@ void g84_therm_fini(struct nvkm_therm *);
int gt215_therm_fan_sense(struct nvkm_therm *);
+void g84_therm_init(struct nvkm_therm *);
void gf119_therm_init(struct nvkm_therm *);
int nvkm_fanpwm_create(struct nvkm_therm *, struct dcb_gpio_func *);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c
index e93b241..ddb2b2c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c
@@ -83,7 +83,7 @@ nvkm_therm_sensor_event(struct nvkm_therm *therm, enum nvkm_therm_thrs thrs,
{
struct nvkm_subdev *subdev = &therm->subdev;
bool active;
- const char *thresolds[] = {
+ static const char * const thresholds[] = {
"fanboost", "downclock", "critical", "shutdown"
};
int temperature = therm->func->temp_get(therm);
@@ -94,10 +94,10 @@ nvkm_therm_sensor_event(struct nvkm_therm *therm, enum nvkm_therm_thrs thrs,
if (dir == NVKM_THERM_THRS_FALLING)
nvkm_info(subdev,
"temperature (%i C) went below the '%s' threshold\n",
- temperature, thresolds[thrs]);
+ temperature, thresholds[thrs]);
else
nvkm_info(subdev, "temperature (%i C) hit the '%s' threshold\n",
- temperature, thresolds[thrs]);
+ temperature, thresholds[thrs]);
active = (dir == NVKM_THERM_THRS_RISING);
switch (thrs) {
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
index e1fa143..542a765 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
@@ -198,6 +198,9 @@ static int tvc_probe(struct platform_device *pdev)
struct omap_dss_device *dssdev;
int r;
+ if (!pdev->dev.of_node)
+ return -ENODEV;
+
ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
if (!ddata)
return -ENOMEM;
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
index 79cb69f..d9d25df 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
@@ -15,6 +15,7 @@
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
+#include <linux/mutex.h>
#include <drm/drm_edid.h>
@@ -37,6 +38,10 @@ static const struct videomode hdmic_default_vm = {
struct panel_drv_data {
struct omap_dss_device dssdev;
struct omap_dss_device *in;
+ void (*hpd_cb)(void *cb_data, enum drm_connector_status status);
+ void *hpd_cb_data;
+ bool hpd_enabled;
+ struct mutex hpd_lock;
struct device *dev;
@@ -167,6 +172,70 @@ static bool hdmic_detect(struct omap_dss_device *dssdev)
return in->ops.hdmi->detect(in);
}
+static int hdmic_register_hpd_cb(struct omap_dss_device *dssdev,
+ void (*cb)(void *cb_data,
+ enum drm_connector_status status),
+ void *cb_data)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ if (gpio_is_valid(ddata->hpd_gpio)) {
+ mutex_lock(&ddata->hpd_lock);
+ ddata->hpd_cb = cb;
+ ddata->hpd_cb_data = cb_data;
+ mutex_unlock(&ddata->hpd_lock);
+ return 0;
+ } else if (in->ops.hdmi->register_hpd_cb) {
+ return in->ops.hdmi->register_hpd_cb(in, cb, cb_data);
+ }
+
+ return -ENOTSUPP;
+}
+
+static void hdmic_unregister_hpd_cb(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ if (gpio_is_valid(ddata->hpd_gpio)) {
+ mutex_lock(&ddata->hpd_lock);
+ ddata->hpd_cb = NULL;
+ ddata->hpd_cb_data = NULL;
+ mutex_unlock(&ddata->hpd_lock);
+ } else if (in->ops.hdmi->unregister_hpd_cb) {
+ in->ops.hdmi->unregister_hpd_cb(in);
+ }
+}
+
+static void hdmic_enable_hpd(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ if (gpio_is_valid(ddata->hpd_gpio)) {
+ mutex_lock(&ddata->hpd_lock);
+ ddata->hpd_enabled = true;
+ mutex_unlock(&ddata->hpd_lock);
+ } else if (in->ops.hdmi->enable_hpd) {
+ in->ops.hdmi->enable_hpd(in);
+ }
+}
+
+static void hdmic_disable_hpd(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ if (gpio_is_valid(ddata->hpd_gpio)) {
+ mutex_lock(&ddata->hpd_lock);
+ ddata->hpd_enabled = false;
+ mutex_unlock(&ddata->hpd_lock);
+ } else if (in->ops.hdmi->disable_hpd) {
+ in->ops.hdmi->disable_hpd(in);
+ }
+}
+
static int hdmic_set_hdmi_mode(struct omap_dss_device *dssdev, bool hdmi_mode)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
@@ -197,10 +266,34 @@ static struct omap_dss_driver hdmic_driver = {
.read_edid = hdmic_read_edid,
.detect = hdmic_detect,
+ .register_hpd_cb = hdmic_register_hpd_cb,
+ .unregister_hpd_cb = hdmic_unregister_hpd_cb,
+ .enable_hpd = hdmic_enable_hpd,
+ .disable_hpd = hdmic_disable_hpd,
.set_hdmi_mode = hdmic_set_hdmi_mode,
.set_hdmi_infoframe = hdmic_set_infoframe,
};
+static irqreturn_t hdmic_hpd_isr(int irq, void *data)
+{
+ struct panel_drv_data *ddata = data;
+
+ mutex_lock(&ddata->hpd_lock);
+ if (ddata->hpd_enabled && ddata->hpd_cb) {
+ enum drm_connector_status status;
+
+ if (hdmic_detect(&ddata->dssdev))
+ status = connector_status_connected;
+ else
+ status = connector_status_disconnected;
+
+ ddata->hpd_cb(ddata->hpd_cb_data, status);
+ }
+ mutex_unlock(&ddata->hpd_lock);
+
+ return IRQ_HANDLED;
+}
+
static int hdmic_probe_of(struct platform_device *pdev)
{
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
@@ -246,11 +339,22 @@ static int hdmic_probe(struct platform_device *pdev)
if (r)
return r;
+ mutex_init(&ddata->hpd_lock);
+
if (gpio_is_valid(ddata->hpd_gpio)) {
r = devm_gpio_request_one(&pdev->dev, ddata->hpd_gpio,
GPIOF_DIR_IN, "hdmi_hpd");
if (r)
goto err_reg;
+
+ r = devm_request_threaded_irq(&pdev->dev,
+ gpio_to_irq(ddata->hpd_gpio),
+ NULL, hdmic_hpd_isr,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
+ IRQF_ONESHOT,
+ "hdmic hpd", ddata);
+ if (r)
+ goto err_reg;
}
ddata->vm = hdmic_default_vm;
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
index 58276a4..a9e9d66 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
@@ -15,12 +15,17 @@
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/gpio/consumer.h>
+#include <linux/mutex.h>
#include "../dss/omapdss.h"
struct panel_drv_data {
struct omap_dss_device dssdev;
struct omap_dss_device *in;
+ void (*hpd_cb)(void *cb_data, enum drm_connector_status status);
+ void *hpd_cb_data;
+ bool hpd_enabled;
+ struct mutex hpd_lock;
struct gpio_desc *ct_cp_hpd_gpio;
struct gpio_desc *ls_oe_gpio;
@@ -162,6 +167,49 @@ static bool tpd_detect(struct omap_dss_device *dssdev)
return gpiod_get_value_cansleep(ddata->hpd_gpio);
}
+static int tpd_register_hpd_cb(struct omap_dss_device *dssdev,
+ void (*cb)(void *cb_data,
+ enum drm_connector_status status),
+ void *cb_data)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+
+ mutex_lock(&ddata->hpd_lock);
+ ddata->hpd_cb = cb;
+ ddata->hpd_cb_data = cb_data;
+ mutex_unlock(&ddata->hpd_lock);
+
+ return 0;
+}
+
+static void tpd_unregister_hpd_cb(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+
+ mutex_lock(&ddata->hpd_lock);
+ ddata->hpd_cb = NULL;
+ ddata->hpd_cb_data = NULL;
+ mutex_unlock(&ddata->hpd_lock);
+}
+
+static void tpd_enable_hpd(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+
+ mutex_lock(&ddata->hpd_lock);
+ ddata->hpd_enabled = true;
+ mutex_unlock(&ddata->hpd_lock);
+}
+
+static void tpd_disable_hpd(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+
+ mutex_lock(&ddata->hpd_lock);
+ ddata->hpd_enabled = false;
+ mutex_unlock(&ddata->hpd_lock);
+}
+
static int tpd_set_infoframe(struct omap_dss_device *dssdev,
const struct hdmi_avi_infoframe *avi)
{
@@ -193,10 +241,34 @@ static const struct omapdss_hdmi_ops tpd_hdmi_ops = {
.read_edid = tpd_read_edid,
.detect = tpd_detect,
+ .register_hpd_cb = tpd_register_hpd_cb,
+ .unregister_hpd_cb = tpd_unregister_hpd_cb,
+ .enable_hpd = tpd_enable_hpd,
+ .disable_hpd = tpd_disable_hpd,
.set_infoframe = tpd_set_infoframe,
.set_hdmi_mode = tpd_set_hdmi_mode,
};
+static irqreturn_t tpd_hpd_isr(int irq, void *data)
+{
+ struct panel_drv_data *ddata = data;
+
+ mutex_lock(&ddata->hpd_lock);
+ if (ddata->hpd_enabled && ddata->hpd_cb) {
+ enum drm_connector_status status;
+
+ if (tpd_detect(&ddata->dssdev))
+ status = connector_status_connected;
+ else
+ status = connector_status_disconnected;
+
+ ddata->hpd_cb(ddata->hpd_cb_data, status);
+ }
+ mutex_unlock(&ddata->hpd_lock);
+
+ return IRQ_HANDLED;
+}
+
static int tpd_probe_of(struct platform_device *pdev)
{
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
@@ -261,6 +333,15 @@ static int tpd_probe(struct platform_device *pdev)
ddata->hpd_gpio = gpio;
+ mutex_init(&ddata->hpd_lock);
+
+ r = devm_request_threaded_irq(&pdev->dev, gpiod_to_irq(ddata->hpd_gpio),
+ NULL, tpd_hpd_isr,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ "tpd12s015 hpd", ddata);
+ if (r)
+ goto err_gpio;
+
dssdev = &ddata->dssdev;
dssdev->ops.hdmi = &tpd_hdmi_ops;
dssdev->dev = &pdev->dev;
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
index 6468a76..e065f7e 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
@@ -231,6 +231,9 @@ static int panel_dpi_probe(struct platform_device *pdev)
struct omap_dss_device *dssdev;
int r;
+ if (!pdev->dev.of_node)
+ return -ENODEV;
+
ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
if (ddata == NULL)
return -ENOMEM;
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index 76787a7..92c556a 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -554,7 +554,7 @@ static struct attribute *dsicm_attrs[] = {
NULL,
};
-static struct attribute_group dsicm_attr_group = {
+static const struct attribute_group dsicm_attr_group = {
.attrs = dsicm_attrs,
};
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
index c90474a..74d1396 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
@@ -19,7 +19,7 @@
#include "../dss/omapdss.h"
-static struct videomode lb035q02_vm = {
+static const struct videomode lb035q02_vm = {
.hactive = 320,
.vactive = 240,
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
index 346aefd..8e5bff4 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
@@ -503,7 +503,7 @@ static struct attribute *bldev_attrs[] = {
NULL,
};
-static struct attribute_group bldev_attr_group = {
+static const struct attribute_group bldev_attr_group = {
.attrs = bldev_attrs,
};
@@ -720,6 +720,9 @@ static int acx565akm_probe(struct spi_device *spi)
dev_dbg(&spi->dev, "%s\n", __func__);
+ if (!spi->dev.of_node)
+ return -ENODEV;
+
spi->mode = SPI_MODE_3;
ddata = devm_kzalloc(&spi->dev, sizeof(*ddata), GFP_KERNEL);
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
index cbf4c67..0a38a0e 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
@@ -40,7 +40,7 @@ struct panel_drv_data {
struct spi_device *spi_dev;
};
-static struct videomode td028ttec1_panel_vm = {
+static const struct videomode td028ttec1_panel_vm = {
.hactive = 480,
.vactive = 640,
.pixelclock = 22153000,
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
index 20c6d8f..ac4a6d4 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
@@ -282,7 +282,7 @@ static struct attribute *tpo_td043_attrs[] = {
NULL,
};
-static struct attribute_group tpo_td043_attr_group = {
+static const struct attribute_group tpo_td043_attr_group = {
.attrs = tpo_td043_attrs,
};
diff --git a/drivers/gpu/drm/omapdrm/dss/Makefile b/drivers/gpu/drm/omapdrm/dss/Makefile
index 688195e..142ce5a 100644
--- a/drivers/gpu/drm/omapdrm/dss/Makefile
+++ b/drivers/gpu/drm/omapdrm/dss/Makefile
@@ -5,7 +5,7 @@ omapdss-base-y := base.o display.o dss-of.o output.o
obj-$(CONFIG_OMAP2_DSS) += omapdss.o
# Core DSS files
-omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o \
+omapdss-y := core.o dss.o dispc.o dispc_coefs.o \
pll.o video-pll.o
omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
diff --git a/drivers/gpu/drm/omapdrm/dss/core.c b/drivers/gpu/drm/omapdrm/dss/core.c
index bdce4bf..197ddbc 100644
--- a/drivers/gpu/drm/omapdrm/dss/core.c
+++ b/drivers/gpu/drm/omapdrm/dss/core.c
@@ -24,182 +24,10 @@
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/clk.h>
-#include <linux/err.h>
#include <linux/platform_device.h>
-#include <linux/seq_file.h>
-#include <linux/debugfs.h>
-#include <linux/io.h>
-#include <linux/device.h>
-#include <linux/regulator/consumer.h>
-#include <linux/suspend.h>
-#include <linux/slab.h>
#include "omapdss.h"
#include "dss.h"
-#include "dss_features.h"
-
-static struct {
- struct platform_device *pdev;
-} core;
-
-enum omapdss_version omapdss_get_version(void)
-{
- struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
- return pdata->version;
-}
-EXPORT_SYMBOL(omapdss_get_version);
-
-int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask)
-{
- struct omap_dss_board_info *board_data = core.pdev->dev.platform_data;
-
- if (!board_data->dsi_enable_pads)
- return -ENOENT;
-
- return board_data->dsi_enable_pads(dsi_id, lane_mask);
-}
-
-void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask)
-{
- struct omap_dss_board_info *board_data = core.pdev->dev.platform_data;
-
- if (!board_data->dsi_disable_pads)
- return;
-
- return board_data->dsi_disable_pads(dsi_id, lane_mask);
-}
-
-int dss_set_min_bus_tput(struct device *dev, unsigned long tput)
-{
- struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
-
- if (pdata->set_min_bus_tput)
- return pdata->set_min_bus_tput(dev, tput);
- else
- return 0;
-}
-
-#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
-static int dss_debug_show(struct seq_file *s, void *unused)
-{
- void (*func)(struct seq_file *) = s->private;
- func(s);
- return 0;
-}
-
-static int dss_debug_open(struct inode *inode, struct file *file)
-{
- return single_open(file, dss_debug_show, inode->i_private);
-}
-
-static const struct file_operations dss_debug_fops = {
- .open = dss_debug_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static struct dentry *dss_debugfs_dir;
-
-static int dss_initialize_debugfs(void)
-{
- dss_debugfs_dir = debugfs_create_dir("omapdss", NULL);
- if (IS_ERR(dss_debugfs_dir)) {
- int err = PTR_ERR(dss_debugfs_dir);
- dss_debugfs_dir = NULL;
- return err;
- }
-
- debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir,
- &dss_debug_dump_clocks, &dss_debug_fops);
-
- return 0;
-}
-
-static void dss_uninitialize_debugfs(void)
-{
- if (dss_debugfs_dir)
- debugfs_remove_recursive(dss_debugfs_dir);
-}
-
-int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *))
-{
- struct dentry *d;
-
- d = debugfs_create_file(name, S_IRUGO, dss_debugfs_dir,
- write, &dss_debug_fops);
-
- return PTR_ERR_OR_ZERO(d);
-}
-#else /* CONFIG_OMAP2_DSS_DEBUGFS */
-static inline int dss_initialize_debugfs(void)
-{
- return 0;
-}
-static inline void dss_uninitialize_debugfs(void)
-{
-}
-int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *))
-{
- return 0;
-}
-#endif /* CONFIG_OMAP2_DSS_DEBUGFS */
-
-/* PLATFORM DEVICE */
-
-static void dss_disable_all_devices(void)
-{
- struct omap_dss_device *dssdev = NULL;
-
- for_each_dss_dev(dssdev) {
- if (!dssdev->driver)
- continue;
-
- if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
- dssdev->driver->disable(dssdev);
- }
-}
-
-static int __init omap_dss_probe(struct platform_device *pdev)
-{
- int r;
-
- core.pdev = pdev;
-
- dss_features_init(omapdss_get_version());
-
- r = dss_initialize_debugfs();
- if (r)
- goto err_debugfs;
-
- return 0;
-
-err_debugfs:
-
- return r;
-}
-
-static int omap_dss_remove(struct platform_device *pdev)
-{
- dss_uninitialize_debugfs();
-
- return 0;
-}
-
-static void omap_dss_shutdown(struct platform_device *pdev)
-{
- DSSDBG("shutdown\n");
- dss_disable_all_devices();
-}
-
-static struct platform_driver omap_dss_driver = {
- .remove = omap_dss_remove,
- .shutdown = omap_dss_shutdown,
- .driver = {
- .name = "omapdss",
- },
-};
/* INIT */
static int (*dss_output_drv_reg_funcs[])(void) __initdata = {
@@ -236,21 +64,25 @@ static void (*dss_output_drv_unreg_funcs[])(void) = {
dss_uninit_platform_driver,
};
+static struct platform_device *omap_drm_device;
+
static int __init omap_dss_init(void)
{
int r;
int i;
- r = platform_driver_probe(&omap_dss_driver, omap_dss_probe);
- if (r)
- return r;
-
for (i = 0; i < ARRAY_SIZE(dss_output_drv_reg_funcs); ++i) {
r = dss_output_drv_reg_funcs[i]();
if (r)
goto err_reg;
}
+ omap_drm_device = platform_device_register_simple("omapdrm", 0, NULL, 0);
+ if (IS_ERR(omap_drm_device)) {
+ r = PTR_ERR(omap_drm_device);
+ goto err_reg;
+ }
+
return 0;
err_reg:
@@ -259,8 +91,6 @@ err_reg:
++i)
dss_output_drv_unreg_funcs[i]();
- platform_driver_unregister(&omap_dss_driver);
-
return r;
}
@@ -268,10 +98,10 @@ static void __exit omap_dss_exit(void)
{
int i;
+ platform_device_unregister(omap_drm_device);
+
for (i = 0; i < ARRAY_SIZE(dss_output_drv_unreg_funcs); ++i)
dss_output_drv_unreg_funcs[i]();
-
- platform_driver_unregister(&omap_dss_driver);
}
module_init(omap_dss_init);
diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c
index fd7504b..0f4fdb2 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -39,13 +39,14 @@
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/component.h>
+#include <linux/sys_soc.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_blend.h>
#include "omapdss.h"
#include "dss.h"
-#include "dss_features.h"
#include "dispc.h"
/* DISPC */
@@ -63,6 +64,33 @@ enum omap_burst_size {
#define REG_FLD_MOD(idx, val, start, end) \
dispc_write_reg(idx, FLD_MOD(dispc_read_reg(idx), val, start, end))
+/* DISPC has feature id */
+enum dispc_feature_id {
+ FEAT_LCDENABLEPOL,
+ FEAT_LCDENABLESIGNAL,
+ FEAT_PCKFREEENABLE,
+ FEAT_FUNCGATED,
+ FEAT_MGR_LCD2,
+ FEAT_MGR_LCD3,
+ FEAT_LINEBUFFERSPLIT,
+ FEAT_ROWREPEATENABLE,
+ FEAT_RESIZECONF,
+ /* Independent core clk divider */
+ FEAT_CORE_CLK_DIV,
+ FEAT_HANDLE_UV_SEPARATE,
+ FEAT_ATTR2,
+ FEAT_CPR,
+ FEAT_PRELOAD,
+ FEAT_FIR_COEF_V,
+ FEAT_ALPHA_FIXED_ZORDER,
+ FEAT_ALPHA_FREE_ZORDER,
+ FEAT_FIFO_MERGE,
+ /* An unknown HW bug causing the normal FIFO thresholds not to work */
+ FEAT_OMAP3_DSI_FIFO_BUG,
+ FEAT_BURST_2D,
+ FEAT_MFLAG,
+};
+
struct dispc_features {
u8 sw_start;
u8 fp_start;
@@ -76,6 +104,9 @@ struct dispc_features {
u16 mgr_height_max;
unsigned long max_lcd_pclk;
unsigned long max_tv_pclk;
+ unsigned int max_downscale;
+ unsigned int max_line_width;
+ unsigned int min_pcd;
int (*calc_scaling) (unsigned long pclk, unsigned long lclk,
const struct videomode *vm,
u16 width, u16 height, u16 out_width, u16 out_height,
@@ -86,6 +117,16 @@ struct dispc_features {
u16 width, u16 height, u16 out_width, u16 out_height,
bool mem_to_mem);
u8 num_fifos;
+ const enum dispc_feature_id *features;
+ unsigned int num_features;
+ const struct dss_reg_field *reg_fields;
+ const unsigned int num_reg_fields;
+ const enum omap_overlay_caps *overlay_caps;
+ const u32 **supported_color_modes;
+ unsigned int num_mgrs;
+ unsigned int num_ovls;
+ unsigned int buffer_size_unit;
+ unsigned int burst_size_unit;
/* swap GFX & WB fifos */
bool gfx_fifo_workaround:1;
@@ -180,6 +221,17 @@ enum mgr_reg_fields {
DISPC_MGR_FLD_NUM,
};
+/* DISPC register field id */
+enum dispc_feat_reg_field {
+ FEAT_REG_FIRHINC,
+ FEAT_REG_FIRVINC,
+ FEAT_REG_FIFOHIGHTHRESHOLD,
+ FEAT_REG_FIFOLOWTHRESHOLD,
+ FEAT_REG_FIFOSIZE,
+ FEAT_REG_HORIZONTALACCU,
+ FEAT_REG_VERTICALACCU,
+};
+
struct dispc_reg_field {
u16 reg;
u8 high;
@@ -343,6 +395,38 @@ static void mgr_fld_write(enum omap_channel channel,
spin_unlock_irqrestore(&dispc.control_lock, flags);
}
+static int dispc_get_num_ovls(void)
+{
+ return dispc.feat->num_ovls;
+}
+
+static int dispc_get_num_mgrs(void)
+{
+ return dispc.feat->num_mgrs;
+}
+
+static void dispc_get_reg_field(enum dispc_feat_reg_field id,
+ u8 *start, u8 *end)
+{
+ if (id >= dispc.feat->num_reg_fields)
+ BUG();
+
+ *start = dispc.feat->reg_fields[id].start;
+ *end = dispc.feat->reg_fields[id].end;
+}
+
+static bool dispc_has_feature(enum dispc_feature_id id)
+{
+ unsigned int i;
+
+ for (i = 0; i < dispc.feat->num_features; i++) {
+ if (dispc.feat->features[i] == id)
+ return true;
+ }
+
+ return false;
+}
+
#define SR(reg) \
dispc.ctx[DISPC_##reg / sizeof(u32)] = dispc_read_reg(DISPC_##reg)
#define RR(reg) \
@@ -358,19 +442,19 @@ static void dispc_save_context(void)
SR(CONTROL);
SR(CONFIG);
SR(LINE_NUMBER);
- if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER) ||
- dss_has_feature(FEAT_ALPHA_FREE_ZORDER))
+ if (dispc_has_feature(FEAT_ALPHA_FIXED_ZORDER) ||
+ dispc_has_feature(FEAT_ALPHA_FREE_ZORDER))
SR(GLOBAL_ALPHA);
- if (dss_has_feature(FEAT_MGR_LCD2)) {
+ if (dispc_has_feature(FEAT_MGR_LCD2)) {
SR(CONTROL2);
SR(CONFIG2);
}
- if (dss_has_feature(FEAT_MGR_LCD3)) {
+ if (dispc_has_feature(FEAT_MGR_LCD3)) {
SR(CONTROL3);
SR(CONFIG3);
}
- for (i = 0; i < dss_feat_get_num_mgrs(); i++) {
+ for (i = 0; i < dispc_get_num_mgrs(); i++) {
SR(DEFAULT_COLOR(i));
SR(TRANS_COLOR(i));
SR(SIZE_MGR(i));
@@ -385,14 +469,14 @@ static void dispc_save_context(void)
SR(DATA_CYCLE2(i));
SR(DATA_CYCLE3(i));
- if (dss_has_feature(FEAT_CPR)) {
+ if (dispc_has_feature(FEAT_CPR)) {
SR(CPR_COEF_R(i));
SR(CPR_COEF_G(i));
SR(CPR_COEF_B(i));
}
}
- for (i = 0; i < dss_feat_get_num_ovls(); i++) {
+ for (i = 0; i < dispc_get_num_ovls(); i++) {
SR(OVL_BA0(i));
SR(OVL_BA1(i));
SR(OVL_POSITION(i));
@@ -401,7 +485,7 @@ static void dispc_save_context(void)
SR(OVL_FIFO_THRESHOLD(i));
SR(OVL_ROW_INC(i));
SR(OVL_PIXEL_INC(i));
- if (dss_has_feature(FEAT_PRELOAD))
+ if (dispc_has_feature(FEAT_PRELOAD))
SR(OVL_PRELOAD(i));
if (i == OMAP_DSS_GFX) {
SR(OVL_WINDOW_SKIP(i));
@@ -422,12 +506,12 @@ static void dispc_save_context(void)
for (j = 0; j < 5; j++)
SR(OVL_CONV_COEF(i, j));
- if (dss_has_feature(FEAT_FIR_COEF_V)) {
+ if (dispc_has_feature(FEAT_FIR_COEF_V)) {
for (j = 0; j < 8; j++)
SR(OVL_FIR_COEF_V(i, j));
}
- if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
+ if (dispc_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
SR(OVL_BA0_UV(i));
SR(OVL_BA1_UV(i));
SR(OVL_FIR2(i));
@@ -443,11 +527,11 @@ static void dispc_save_context(void)
for (j = 0; j < 8; j++)
SR(OVL_FIR_COEF_V2(i, j));
}
- if (dss_has_feature(FEAT_ATTR2))
+ if (dispc_has_feature(FEAT_ATTR2))
SR(OVL_ATTRIBUTES2(i));
}
- if (dss_has_feature(FEAT_CORE_CLK_DIV))
+ if (dispc_has_feature(FEAT_CORE_CLK_DIV))
SR(DIVISOR);
dispc.ctx_valid = true;
@@ -468,15 +552,15 @@ static void dispc_restore_context(void)
/*RR(CONTROL);*/
RR(CONFIG);
RR(LINE_NUMBER);
- if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER) ||
- dss_has_feature(FEAT_ALPHA_FREE_ZORDER))
+ if (dispc_has_feature(FEAT_ALPHA_FIXED_ZORDER) ||
+ dispc_has_feature(FEAT_ALPHA_FREE_ZORDER))
RR(GLOBAL_ALPHA);
- if (dss_has_feature(FEAT_MGR_LCD2))
+ if (dispc_has_feature(FEAT_MGR_LCD2))
RR(CONFIG2);
- if (dss_has_feature(FEAT_MGR_LCD3))
+ if (dispc_has_feature(FEAT_MGR_LCD3))
RR(CONFIG3);
- for (i = 0; i < dss_feat_get_num_mgrs(); i++) {
+ for (i = 0; i < dispc_get_num_mgrs(); i++) {
RR(DEFAULT_COLOR(i));
RR(TRANS_COLOR(i));
RR(SIZE_MGR(i));
@@ -491,14 +575,14 @@ static void dispc_restore_context(void)
RR(DATA_CYCLE2(i));
RR(DATA_CYCLE3(i));
- if (dss_has_feature(FEAT_CPR)) {
+ if (dispc_has_feature(FEAT_CPR)) {
RR(CPR_COEF_R(i));
RR(CPR_COEF_G(i));
RR(CPR_COEF_B(i));
}
}
- for (i = 0; i < dss_feat_get_num_ovls(); i++) {
+ for (i = 0; i < dispc_get_num_ovls(); i++) {
RR(OVL_BA0(i));
RR(OVL_BA1(i));
RR(OVL_POSITION(i));
@@ -507,7 +591,7 @@ static void dispc_restore_context(void)
RR(OVL_FIFO_THRESHOLD(i));
RR(OVL_ROW_INC(i));
RR(OVL_PIXEL_INC(i));
- if (dss_has_feature(FEAT_PRELOAD))
+ if (dispc_has_feature(FEAT_PRELOAD))
RR(OVL_PRELOAD(i));
if (i == OMAP_DSS_GFX) {
RR(OVL_WINDOW_SKIP(i));
@@ -528,12 +612,12 @@ static void dispc_restore_context(void)
for (j = 0; j < 5; j++)
RR(OVL_CONV_COEF(i, j));
- if (dss_has_feature(FEAT_FIR_COEF_V)) {
+ if (dispc_has_feature(FEAT_FIR_COEF_V)) {
for (j = 0; j < 8; j++)
RR(OVL_FIR_COEF_V(i, j));
}
- if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
+ if (dispc_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
RR(OVL_BA0_UV(i));
RR(OVL_BA1_UV(i));
RR(OVL_FIR2(i));
@@ -549,18 +633,18 @@ static void dispc_restore_context(void)
for (j = 0; j < 8; j++)
RR(OVL_FIR_COEF_V2(i, j));
}
- if (dss_has_feature(FEAT_ATTR2))
+ if (dispc_has_feature(FEAT_ATTR2))
RR(OVL_ATTRIBUTES2(i));
}
- if (dss_has_feature(FEAT_CORE_CLK_DIV))
+ if (dispc_has_feature(FEAT_CORE_CLK_DIV))
RR(DIVISOR);
/* enable last, because LCD & DIGIT enable are here */
RR(CONTROL);
- if (dss_has_feature(FEAT_MGR_LCD2))
+ if (dispc_has_feature(FEAT_MGR_LCD2))
RR(CONTROL2);
- if (dss_has_feature(FEAT_MGR_LCD3))
+ if (dispc_has_feature(FEAT_MGR_LCD3))
RR(CONTROL3);
/* clear spurious SYNC_LOST_DIGIT interrupts */
dispc_clear_irqstatus(DISPC_IRQ_SYNC_LOST_DIGIT);
@@ -779,7 +863,7 @@ static void dispc_ovl_write_color_conv_coef(enum omap_plane_id plane,
static void dispc_setup_color_conv_coef(void)
{
int i;
- int num_ovl = dss_feat_get_num_ovls();
+ int num_ovl = dispc_get_num_ovls();
const struct color_conv_coef ctbl_bt601_5_ovl = {
/* YUV -> RGB */
298, 409, 0, 298, -208, -100, 298, 0, 517, 0,
@@ -868,10 +952,10 @@ static void dispc_ovl_enable_zorder_planes(void)
{
int i;
- if (!dss_has_feature(FEAT_ALPHA_FREE_ZORDER))
+ if (!dispc_has_feature(FEAT_ALPHA_FREE_ZORDER))
return;
- for (i = 0; i < dss_feat_get_num_ovls(); i++)
+ for (i = 0; i < dispc_get_num_ovls(); i++)
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25);
}
@@ -994,7 +1078,7 @@ static bool format_is_yuv(u32 fourcc)
static void dispc_ovl_configure_burst_type(enum omap_plane_id plane,
enum omap_dss_rotation_type rotation_type)
{
- if (dss_has_feature(FEAT_BURST_2D) == 0)
+ if (dispc_has_feature(FEAT_BURST_2D) == 0)
return;
if (rotation_type == OMAP_DSS_ROT_TILER)
@@ -1025,7 +1109,7 @@ static void dispc_ovl_set_channel_out(enum omap_plane_id plane,
}
val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
- if (dss_has_feature(FEAT_MGR_LCD2)) {
+ if (dispc_has_feature(FEAT_MGR_LCD2)) {
switch (channel) {
case OMAP_DSS_CHANNEL_LCD:
chan = 0;
@@ -1040,7 +1124,7 @@ static void dispc_ovl_set_channel_out(enum omap_plane_id plane,
chan2 = 1;
break;
case OMAP_DSS_CHANNEL_LCD3:
- if (dss_has_feature(FEAT_MGR_LCD3)) {
+ if (dispc_has_feature(FEAT_MGR_LCD3)) {
chan = 0;
chan2 = 2;
} else {
@@ -1089,7 +1173,7 @@ static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane_id plane)
if (FLD_GET(val, shift, shift) == 1)
return OMAP_DSS_CHANNEL_DIGIT;
- if (!dss_has_feature(FEAT_MGR_LCD2))
+ if (!dispc_has_feature(FEAT_MGR_LCD2))
return OMAP_DSS_CHANNEL_LCD;
switch (FLD_GET(val, 31, 30)) {
@@ -1128,7 +1212,7 @@ static void dispc_configure_burst_sizes(void)
const int burst_size = BURST_SIZE_X8;
/* Configure burst size always to maximum size */
- for (i = 0; i < dss_feat_get_num_ovls(); ++i)
+ for (i = 0; i < dispc_get_num_ovls(); ++i)
dispc_ovl_set_burst_size(i, burst_size);
if (dispc.feat->has_writeback)
dispc_ovl_set_burst_size(OMAP_DSS_WB, burst_size);
@@ -1136,19 +1220,28 @@ static void dispc_configure_burst_sizes(void)
static u32 dispc_ovl_get_burst_size(enum omap_plane_id plane)
{
- unsigned unit = dss_feat_get_burst_size_unit();
/* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */
- return unit * 8;
+ return dispc.feat->burst_size_unit * 8;
}
-static const u32 *dispc_ovl_get_color_modes(enum omap_plane_id plane)
+static bool dispc_ovl_color_mode_supported(enum omap_plane_id plane, u32 fourcc)
{
- return dss_feat_get_supported_color_modes(plane);
+ const u32 *modes;
+ unsigned int i;
+
+ modes = dispc.feat->supported_color_modes[plane];
+
+ for (i = 0; modes[i]; ++i) {
+ if (modes[i] == fourcc)
+ return true;
+ }
+
+ return false;
}
-static int dispc_get_num_ovls(void)
+static const u32 *dispc_ovl_get_color_modes(enum omap_plane_id plane)
{
- return dss_feat_get_num_ovls();
+ return dispc.feat->supported_color_modes[plane];
}
static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable)
@@ -1223,9 +1316,9 @@ static void dispc_init_fifos(void)
u32 unit;
int i;
- unit = dss_feat_get_buffer_size_unit();
+ unit = dispc.feat->buffer_size_unit;
- dss_feat_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end);
+ dispc_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end);
for (fifo = 0; fifo < dispc.feat->num_fifos; ++fifo) {
size = REG_GET(DISPC_OVL_FIFO_SIZE_STATUS(fifo), start, end);
@@ -1265,7 +1358,7 @@ static void dispc_init_fifos(void)
/*
* Setup default fifo thresholds.
*/
- for (i = 0; i < dss_feat_get_num_ovls(); ++i) {
+ for (i = 0; i < dispc_get_num_ovls(); ++i) {
u32 low, high;
const bool use_fifomerge = false;
const bool manual_update = false;
@@ -1307,7 +1400,7 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane_id plane, u32 low,
u8 hi_start, hi_end, lo_start, lo_end;
u32 unit;
- unit = dss_feat_get_buffer_size_unit();
+ unit = dispc.feat->buffer_size_unit;
WARN_ON(low % unit != 0);
WARN_ON(high % unit != 0);
@@ -1315,8 +1408,8 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane_id plane, u32 low,
low /= unit;
high /= unit;
- dss_feat_get_reg_field(FEAT_REG_FIFOHIGHTHRESHOLD, &hi_start, &hi_end);
- dss_feat_get_reg_field(FEAT_REG_FIFOLOWTHRESHOLD, &lo_start, &lo_end);
+ dispc_get_reg_field(FEAT_REG_FIFOHIGHTHRESHOLD, &hi_start, &hi_end);
+ dispc_get_reg_field(FEAT_REG_FIFOLOWTHRESHOLD, &lo_start, &lo_end);
DSSDBG("fifo(%d) threshold (bytes), old %u/%u, new %u/%u\n",
plane,
@@ -1335,14 +1428,14 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane_id plane, u32 low,
* large for the preload field, set the threshold to the maximum value
* that can be held by the preload register
*/
- if (dss_has_feature(FEAT_PRELOAD) && dispc.feat->set_max_preload &&
+ if (dispc_has_feature(FEAT_PRELOAD) && dispc.feat->set_max_preload &&
plane != OMAP_DSS_WB)
dispc_write_reg(DISPC_OVL_PRELOAD(plane), min(high, 0xfffu));
}
void dispc_enable_fifomerge(bool enable)
{
- if (!dss_has_feature(FEAT_FIFO_MERGE)) {
+ if (!dispc_has_feature(FEAT_FIFO_MERGE)) {
WARN_ON(enable);
return;
}
@@ -1360,7 +1453,7 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane_id plane,
* buffer_units, and the fifo thresholds must be buffer_unit aligned.
*/
- unsigned buf_unit = dss_feat_get_buffer_size_unit();
+ unsigned buf_unit = dispc.feat->buffer_size_unit;
unsigned ovl_fifo_size, total_fifo_size, burst_size;
int i;
@@ -1369,7 +1462,7 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane_id plane,
if (use_fifomerge) {
total_fifo_size = 0;
- for (i = 0; i < dss_feat_get_num_ovls(); ++i)
+ for (i = 0; i < dispc_get_num_ovls(); ++i)
total_fifo_size += dispc_ovl_get_fifo_size(i);
} else {
total_fifo_size = ovl_fifo_size;
@@ -1381,7 +1474,7 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane_id plane,
* combined fifo size
*/
- if (manual_update && dss_has_feature(FEAT_OMAP3_DSI_FIFO_BUG)) {
+ if (manual_update && dispc_has_feature(FEAT_OMAP3_DSI_FIFO_BUG)) {
*fifo_low = ovl_fifo_size - burst_size * 2;
*fifo_high = total_fifo_size - burst_size;
} else if (plane == OMAP_DSS_WB) {
@@ -1435,9 +1528,9 @@ static void dispc_init_mflag(void)
(1 << 0) | /* MFLAG_CTRL = force always on */
(0 << 2)); /* MFLAG_START = disable */
- for (i = 0; i < dss_feat_get_num_ovls(); ++i) {
+ for (i = 0; i < dispc_get_num_ovls(); ++i) {
u32 size = dispc_ovl_get_fifo_size(i);
- u32 unit = dss_feat_get_buffer_size_unit();
+ u32 unit = dispc.feat->buffer_size_unit;
u32 low, high;
dispc_ovl_set_mflag(i, true);
@@ -1456,7 +1549,7 @@ static void dispc_init_mflag(void)
if (dispc.feat->has_writeback) {
u32 size = dispc_ovl_get_fifo_size(OMAP_DSS_WB);
- u32 unit = dss_feat_get_buffer_size_unit();
+ u32 unit = dispc.feat->buffer_size_unit;
u32 low, high;
dispc_ovl_set_mflag(OMAP_DSS_WB, true);
@@ -1483,10 +1576,8 @@ static void dispc_ovl_set_fir(enum omap_plane_id plane,
if (color_comp == DISPC_COLOR_COMPONENT_RGB_Y) {
u8 hinc_start, hinc_end, vinc_start, vinc_end;
- dss_feat_get_reg_field(FEAT_REG_FIRHINC,
- &hinc_start, &hinc_end);
- dss_feat_get_reg_field(FEAT_REG_FIRVINC,
- &vinc_start, &vinc_end);
+ dispc_get_reg_field(FEAT_REG_FIRHINC, &hinc_start, &hinc_end);
+ dispc_get_reg_field(FEAT_REG_FIRVINC, &vinc_start, &vinc_end);
val = FLD_VAL(vinc, vinc_start, vinc_end) |
FLD_VAL(hinc, hinc_start, hinc_end);
@@ -1503,8 +1594,8 @@ static void dispc_ovl_set_vid_accu0(enum omap_plane_id plane, int haccu,
u32 val;
u8 hor_start, hor_end, vert_start, vert_end;
- dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
- dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
+ dispc_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
+ dispc_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
val = FLD_VAL(vaccu, vert_start, vert_end) |
FLD_VAL(haccu, hor_start, hor_end);
@@ -1518,8 +1609,8 @@ static void dispc_ovl_set_vid_accu1(enum omap_plane_id plane, int haccu,
u32 val;
u8 hor_start, hor_end, vert_start, vert_end;
- dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
- dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
+ dispc_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
+ dispc_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
val = FLD_VAL(vaccu, vert_start, vert_end) |
FLD_VAL(haccu, hor_start, hor_end);
@@ -1671,14 +1762,14 @@ static void dispc_ovl_set_scaling_common(enum omap_plane_id plane,
l |= five_taps ? (1 << 21) : 0;
/* VRESIZECONF and HRESIZECONF */
- if (dss_has_feature(FEAT_RESIZECONF)) {
+ if (dispc_has_feature(FEAT_RESIZECONF)) {
l &= ~(0x3 << 7);
l |= (orig_width <= out_width) ? 0 : (1 << 7);
l |= (orig_height <= out_height) ? 0 : (1 << 8);
}
/* LINEBUFFERSPLIT */
- if (dss_has_feature(FEAT_LINEBUFFERSPLIT)) {
+ if (dispc_has_feature(FEAT_LINEBUFFERSPLIT)) {
l &= ~(0x1 << 22);
l |= five_taps ? (1 << 22) : 0;
}
@@ -1713,7 +1804,7 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane_id plane,
int scale_y = out_height != orig_height;
bool chroma_upscale = plane != OMAP_DSS_WB;
- if (!dss_has_feature(FEAT_HANDLE_UV_SEPARATE))
+ if (!dispc_has_feature(FEAT_HANDLE_UV_SEPARATE))
return;
if (!format_is_yuv(fourcc)) {
@@ -1860,11 +1951,11 @@ static void dispc_ovl_set_rotation_attrs(enum omap_plane_id plane, u8 rotation,
vidrot = 1;
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), vidrot, 13, 12);
- if (dss_has_feature(FEAT_ROWREPEATENABLE))
+ if (dispc_has_feature(FEAT_ROWREPEATENABLE))
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane),
row_repeat ? 1 : 0, 18, 18);
- if (dss_feat_color_mode_supported(plane, DRM_FORMAT_NV12)) {
+ if (dispc_ovl_color_mode_supported(plane, DRM_FORMAT_NV12)) {
bool doublestride =
fourcc == DRM_FORMAT_NV12 &&
rotation_type == OMAP_DSS_ROT_TILER &&
@@ -2118,8 +2209,7 @@ static int dispc_ovl_calc_scaling_24xx(unsigned long pclk, unsigned long lclk,
int error;
u16 in_width, in_height;
int min_factor = min(*decim_x, *decim_y);
- const int maxsinglelinewidth =
- dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+ const int maxsinglelinewidth = dispc.feat->max_line_width;
*five_taps = false;
@@ -2163,8 +2253,7 @@ static int dispc_ovl_calc_scaling_34xx(unsigned long pclk, unsigned long lclk,
{
int error;
u16 in_width, in_height;
- const int maxsinglelinewidth =
- dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+ const int maxsinglelinewidth = dispc.feat->max_line_width;
do {
in_height = height / *decim_y;
@@ -2249,9 +2338,8 @@ static int dispc_ovl_calc_scaling_44xx(unsigned long pclk, unsigned long lclk,
u16 in_width, in_width_max;
int decim_x_min = *decim_x;
u16 in_height = height / *decim_y;
- const int maxsinglelinewidth =
- dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
- const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
+ const int maxsinglelinewidth = dispc.feat->max_line_width;
+ const int maxdownscale = dispc.feat->max_downscale;
if (mem_to_mem) {
in_width_max = out_width * maxdownscale;
@@ -2311,7 +2399,7 @@ static int dispc_ovl_calc_scaling(unsigned long pclk, unsigned long lclk,
int *x_predecim, int *y_predecim, u16 pos_x,
enum omap_dss_rotation_type rotation_type, bool mem_to_mem)
{
- const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
+ const int maxdownscale = dispc.feat->max_downscale;
const int max_decim_limit = 16;
unsigned long core_clk = 0;
int decim_x, decim_y, ret;
@@ -2332,7 +2420,7 @@ static int dispc_ovl_calc_scaling(unsigned long pclk, unsigned long lclk,
} else {
*x_predecim = max_decim_limit;
*y_predecim = (rotation_type == OMAP_DSS_ROT_TILER &&
- dss_has_feature(FEAT_BURST_2D)) ?
+ dispc_has_feature(FEAT_BURST_2D)) ?
2 : max_decim_limit;
}
@@ -2428,7 +2516,7 @@ static int dispc_ovl_setup_common(enum omap_plane_id plane,
out_height);
}
- if (!dss_feat_color_mode_supported(plane, fourcc))
+ if (!dispc_ovl_color_mode_supported(plane, fourcc))
return -EINVAL;
r = dispc_ovl_calc_scaling(pclk, lclk, caps, vm, in_width,
@@ -2549,7 +2637,7 @@ static int dispc_ovl_setup(enum omap_plane_id plane,
enum omap_channel channel)
{
int r;
- enum omap_overlay_caps caps = dss_feat_get_overlay_caps(plane);
+ enum omap_overlay_caps caps = dispc.feat->overlay_caps[plane];
const bool replication = true;
DSSDBG("dispc_ovl_setup %d, pa %pad, pa_uv %pad, sw %d, %d,%d, %dx%d ->"
@@ -2647,12 +2735,12 @@ static int dispc_ovl_enable(enum omap_plane_id plane, bool enable)
static enum omap_dss_output_id dispc_mgr_get_supported_outputs(enum omap_channel channel)
{
- return dss_feat_get_supported_outputs(channel);
+ return dss_get_supported_outputs(channel);
}
static void dispc_lcd_enable_signal_polarity(bool act_high)
{
- if (!dss_has_feature(FEAT_LCDENABLEPOL))
+ if (!dispc_has_feature(FEAT_LCDENABLEPOL))
return;
REG_FLD_MOD(DISPC_CONTROL, act_high ? 1 : 0, 29, 29);
@@ -2660,7 +2748,7 @@ static void dispc_lcd_enable_signal_polarity(bool act_high)
void dispc_lcd_enable_signal(bool enable)
{
- if (!dss_has_feature(FEAT_LCDENABLESIGNAL))
+ if (!dispc_has_feature(FEAT_LCDENABLESIGNAL))
return;
REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 28, 28);
@@ -2668,17 +2756,12 @@ void dispc_lcd_enable_signal(bool enable)
void dispc_pck_free_enable(bool enable)
{
- if (!dss_has_feature(FEAT_PCKFREEENABLE))
+ if (!dispc_has_feature(FEAT_PCKFREEENABLE))
return;
REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27);
}
-static int dispc_get_num_mgrs(void)
-{
- return dss_feat_get_num_mgrs();
-}
-
static void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable)
{
mgr_fld_write(channel, DISPC_MGR_FLD_FIFOHANDCHECK, enable);
@@ -2718,7 +2801,7 @@ static void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable)
static void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch,
bool enable)
{
- if (!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER))
+ if (!dispc_has_feature(FEAT_ALPHA_FIXED_ZORDER))
return;
if (ch == OMAP_DSS_CHANNEL_LCD)
@@ -2735,7 +2818,7 @@ static void dispc_mgr_setup(enum omap_channel channel,
dispc_mgr_enable_trans_key(channel, info->trans_enabled);
dispc_mgr_enable_alpha_fixed_zorder(channel,
info->partial_alpha_enabled);
- if (dss_has_feature(FEAT_CPR)) {
+ if (dispc_has_feature(FEAT_CPR)) {
dispc_mgr_enable_cpr(channel, info->cpr_enable);
dispc_mgr_set_cpr_coef(channel, &info->cpr_coefs);
}
@@ -3013,7 +3096,7 @@ static void dispc_mgr_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
dispc_write_reg(DISPC_DIVISORo(channel),
FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0));
- if (!dss_has_feature(FEAT_CORE_CLK_DIV) &&
+ if (!dispc_has_feature(FEAT_CORE_CLK_DIV) &&
channel == OMAP_DSS_CHANNEL_LCD)
dispc.core_clk_rate = dispc_fclk_rate() / lck_div;
}
@@ -3168,7 +3251,7 @@ void dispc_dump_clocks(struct seq_file *s)
seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate());
- if (dss_has_feature(FEAT_CORE_CLK_DIV)) {
+ if (dispc_has_feature(FEAT_CORE_CLK_DIV)) {
seq_printf(s, "- DISPC-CORE-CLK -\n");
l = dispc_read_reg(DISPC_DIVISOR);
lcd = FLD_GET(l, 23, 16);
@@ -3179,9 +3262,9 @@ void dispc_dump_clocks(struct seq_file *s)
dispc_dump_clocks_channel(s, OMAP_DSS_CHANNEL_LCD);
- if (dss_has_feature(FEAT_MGR_LCD2))
+ if (dispc_has_feature(FEAT_MGR_LCD2))
dispc_dump_clocks_channel(s, OMAP_DSS_CHANNEL_LCD2);
- if (dss_has_feature(FEAT_MGR_LCD3))
+ if (dispc_has_feature(FEAT_MGR_LCD3))
dispc_dump_clocks_channel(s, OMAP_DSS_CHANNEL_LCD3);
dispc_runtime_put();
@@ -3221,18 +3304,18 @@ static void dispc_dump_regs(struct seq_file *s)
DUMPREG(DISPC_CAPABLE);
DUMPREG(DISPC_LINE_STATUS);
DUMPREG(DISPC_LINE_NUMBER);
- if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER) ||
- dss_has_feature(FEAT_ALPHA_FREE_ZORDER))
+ if (dispc_has_feature(FEAT_ALPHA_FIXED_ZORDER) ||
+ dispc_has_feature(FEAT_ALPHA_FREE_ZORDER))
DUMPREG(DISPC_GLOBAL_ALPHA);
- if (dss_has_feature(FEAT_MGR_LCD2)) {
+ if (dispc_has_feature(FEAT_MGR_LCD2)) {
DUMPREG(DISPC_CONTROL2);
DUMPREG(DISPC_CONFIG2);
}
- if (dss_has_feature(FEAT_MGR_LCD3)) {
+ if (dispc_has_feature(FEAT_MGR_LCD3)) {
DUMPREG(DISPC_CONTROL3);
DUMPREG(DISPC_CONFIG3);
}
- if (dss_has_feature(FEAT_MFLAG))
+ if (dispc_has_feature(FEAT_MFLAG))
DUMPREG(DISPC_GLOBAL_MFLAG_ATTRIBUTE);
#undef DUMPREG
@@ -3245,7 +3328,7 @@ static void dispc_dump_regs(struct seq_file *s)
p_names = mgr_names;
/* DISPC channel specific registers */
- for (i = 0; i < dss_feat_get_num_mgrs(); i++) {
+ for (i = 0; i < dispc_get_num_mgrs(); i++) {
DUMPREG(i, DISPC_DEFAULT_COLOR);
DUMPREG(i, DISPC_TRANS_COLOR);
DUMPREG(i, DISPC_SIZE_MGR);
@@ -3262,7 +3345,7 @@ static void dispc_dump_regs(struct seq_file *s)
DUMPREG(i, DISPC_DATA_CYCLE2);
DUMPREG(i, DISPC_DATA_CYCLE3);
- if (dss_has_feature(FEAT_CPR)) {
+ if (dispc_has_feature(FEAT_CPR)) {
DUMPREG(i, DISPC_CPR_COEF_R);
DUMPREG(i, DISPC_CPR_COEF_G);
DUMPREG(i, DISPC_CPR_COEF_B);
@@ -3271,7 +3354,7 @@ static void dispc_dump_regs(struct seq_file *s)
p_names = ovl_names;
- for (i = 0; i < dss_feat_get_num_ovls(); i++) {
+ for (i = 0; i < dispc_get_num_ovls(); i++) {
DUMPREG(i, DISPC_OVL_BA0);
DUMPREG(i, DISPC_OVL_BA1);
DUMPREG(i, DISPC_OVL_POSITION);
@@ -3282,9 +3365,9 @@ static void dispc_dump_regs(struct seq_file *s)
DUMPREG(i, DISPC_OVL_ROW_INC);
DUMPREG(i, DISPC_OVL_PIXEL_INC);
- if (dss_has_feature(FEAT_PRELOAD))
+ if (dispc_has_feature(FEAT_PRELOAD))
DUMPREG(i, DISPC_OVL_PRELOAD);
- if (dss_has_feature(FEAT_MFLAG))
+ if (dispc_has_feature(FEAT_MFLAG))
DUMPREG(i, DISPC_OVL_MFLAG_THRESHOLD);
if (i == OMAP_DSS_GFX) {
@@ -3297,14 +3380,14 @@ static void dispc_dump_regs(struct seq_file *s)
DUMPREG(i, DISPC_OVL_PICTURE_SIZE);
DUMPREG(i, DISPC_OVL_ACCU0);
DUMPREG(i, DISPC_OVL_ACCU1);
- if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
+ if (dispc_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
DUMPREG(i, DISPC_OVL_BA0_UV);
DUMPREG(i, DISPC_OVL_BA1_UV);
DUMPREG(i, DISPC_OVL_FIR2);
DUMPREG(i, DISPC_OVL_ACCU2_0);
DUMPREG(i, DISPC_OVL_ACCU2_1);
}
- if (dss_has_feature(FEAT_ATTR2))
+ if (dispc_has_feature(FEAT_ATTR2))
DUMPREG(i, DISPC_OVL_ATTRIBUTES2);
}
@@ -3319,21 +3402,21 @@ static void dispc_dump_regs(struct seq_file *s)
DUMPREG(i, DISPC_OVL_ROW_INC);
DUMPREG(i, DISPC_OVL_PIXEL_INC);
- if (dss_has_feature(FEAT_MFLAG))
+ if (dispc_has_feature(FEAT_MFLAG))
DUMPREG(i, DISPC_OVL_MFLAG_THRESHOLD);
DUMPREG(i, DISPC_OVL_FIR);
DUMPREG(i, DISPC_OVL_PICTURE_SIZE);
DUMPREG(i, DISPC_OVL_ACCU0);
DUMPREG(i, DISPC_OVL_ACCU1);
- if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
+ if (dispc_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
DUMPREG(i, DISPC_OVL_BA0_UV);
DUMPREG(i, DISPC_OVL_BA1_UV);
DUMPREG(i, DISPC_OVL_FIR2);
DUMPREG(i, DISPC_OVL_ACCU2_0);
DUMPREG(i, DISPC_OVL_ACCU2_1);
}
- if (dss_has_feature(FEAT_ATTR2))
+ if (dispc_has_feature(FEAT_ATTR2))
DUMPREG(i, DISPC_OVL_ATTRIBUTES2);
}
@@ -3349,7 +3432,7 @@ static void dispc_dump_regs(struct seq_file *s)
/* Video pipeline coefficient registers */
/* start from OMAP_DSS_VIDEO1 */
- for (i = 1; i < dss_feat_get_num_ovls(); i++) {
+ for (i = 1; i < dispc_get_num_ovls(); i++) {
for (j = 0; j < 8; j++)
DUMPREG(i, DISPC_OVL_FIR_COEF_H, j);
@@ -3359,12 +3442,12 @@ static void dispc_dump_regs(struct seq_file *s)
for (j = 0; j < 5; j++)
DUMPREG(i, DISPC_OVL_CONV_COEF, j);
- if (dss_has_feature(FEAT_FIR_COEF_V)) {
+ if (dispc_has_feature(FEAT_FIR_COEF_V)) {
for (j = 0; j < 8; j++)
DUMPREG(i, DISPC_OVL_FIR_COEF_V, j);
}
- if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
+ if (dispc_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
for (j = 0; j < 8; j++)
DUMPREG(i, DISPC_OVL_FIR_COEF_H2, j);
@@ -3397,7 +3480,7 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
return 0;
}
-bool dispc_div_calc(unsigned long dispc,
+bool dispc_div_calc(unsigned long dispc_freq,
unsigned long pck_min, unsigned long pck_max,
dispc_div_calc_func func, void *data)
{
@@ -3415,19 +3498,19 @@ bool dispc_div_calc(unsigned long dispc,
min_fck_per_pck = 0;
#endif
- pckd_hw_min = dss_feat_get_param_min(FEAT_PARAM_DSS_PCD);
- pckd_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_PCD);
+ pckd_hw_min = dispc.feat->min_pcd;
+ pckd_hw_max = 255;
- lck_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
+ lck_max = dss_get_max_fck_rate();
pck_min = pck_min ? pck_min : 1;
pck_max = pck_max ? pck_max : ULONG_MAX;
- lckd_start = max(DIV_ROUND_UP(dispc, lck_max), 1ul);
- lckd_stop = min(dispc / pck_min, 255ul);
+ lckd_start = max(DIV_ROUND_UP(dispc_freq, lck_max), 1ul);
+ lckd_stop = min(dispc_freq / pck_min, 255ul);
for (lckd = lckd_start; lckd <= lckd_stop; ++lckd) {
- lck = dispc / lckd;
+ lck = dispc_freq / lckd;
pckd_start = max(DIV_ROUND_UP(lck, pck_max), pckd_hw_min);
pckd_stop = min(lck / pck_min, pckd_hw_max);
@@ -3441,7 +3524,7 @@ bool dispc_div_calc(unsigned long dispc,
* also. Thus we need to use the calculated lck. For
* OMAP4+ the DISPC fclk is a separate clock.
*/
- if (dss_has_feature(FEAT_CORE_CLK_DIV))
+ if (dispc_has_feature(FEAT_CORE_CLK_DIV))
fck = dispc_core_clk_rate();
else
fck = lck;
@@ -3556,10 +3639,10 @@ static void dispc_restore_gamma_tables(void)
dispc_mgr_write_gamma_table(OMAP_DSS_CHANNEL_DIGIT);
- if (dss_has_feature(FEAT_MGR_LCD2))
+ if (dispc_has_feature(FEAT_MGR_LCD2))
dispc_mgr_write_gamma_table(OMAP_DSS_CHANNEL_LCD2);
- if (dss_has_feature(FEAT_MGR_LCD3))
+ if (dispc_has_feature(FEAT_MGR_LCD3))
dispc_mgr_write_gamma_table(OMAP_DSS_CHANNEL_LCD3);
}
@@ -3627,11 +3710,11 @@ static int dispc_init_gamma_tables(void)
u32 *gt;
if (channel == OMAP_DSS_CHANNEL_LCD2 &&
- !dss_has_feature(FEAT_MGR_LCD2))
+ !dispc_has_feature(FEAT_MGR_LCD2))
continue;
if (channel == OMAP_DSS_CHANNEL_LCD3 &&
- !dss_has_feature(FEAT_MGR_LCD3))
+ !dispc_has_feature(FEAT_MGR_LCD3))
continue;
gt = devm_kmalloc_array(&dispc.pdev->dev, gdesc->len,
@@ -3651,7 +3734,7 @@ static void _omap_dispc_initial_config(void)
u32 l;
/* Exclusively enable DISPC_CORE_CLK and set divider to 1 */
- if (dss_has_feature(FEAT_CORE_CLK_DIV)) {
+ if (dispc_has_feature(FEAT_CORE_CLK_DIV)) {
l = dispc_read_reg(DISPC_DIVISOR);
/* Use DISPC_DIVISOR.LCD, instead of DISPC_DIVISOR1.LCD */
l = FLD_MOD(l, 1, 0, 0);
@@ -3669,7 +3752,7 @@ static void _omap_dispc_initial_config(void)
* func-clock auto-gating. For newer versions
* (dispc.feat->has_gamma_table) this enables tv-out gamma tables.
*/
- if (dss_has_feature(FEAT_FUNCGATED) || dispc.feat->has_gamma_table)
+ if (dispc_has_feature(FEAT_FUNCGATED) || dispc.feat->has_gamma_table)
REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9);
dispc_setup_color_conv_coef();
@@ -3685,10 +3768,272 @@ static void _omap_dispc_initial_config(void)
if (dispc.feat->mstandby_workaround)
REG_FLD_MOD(DISPC_MSTANDBY_CTRL, 1, 0, 0);
- if (dss_has_feature(FEAT_MFLAG))
+ if (dispc_has_feature(FEAT_MFLAG))
dispc_init_mflag();
}
+static const enum dispc_feature_id omap2_dispc_features_list[] = {
+ FEAT_LCDENABLEPOL,
+ FEAT_LCDENABLESIGNAL,
+ FEAT_PCKFREEENABLE,
+ FEAT_FUNCGATED,
+ FEAT_ROWREPEATENABLE,
+ FEAT_RESIZECONF,
+};
+
+static const enum dispc_feature_id omap3_dispc_features_list[] = {
+ FEAT_LCDENABLEPOL,
+ FEAT_LCDENABLESIGNAL,
+ FEAT_PCKFREEENABLE,
+ FEAT_FUNCGATED,
+ FEAT_LINEBUFFERSPLIT,
+ FEAT_ROWREPEATENABLE,
+ FEAT_RESIZECONF,
+ FEAT_CPR,
+ FEAT_PRELOAD,
+ FEAT_FIR_COEF_V,
+ FEAT_ALPHA_FIXED_ZORDER,
+ FEAT_FIFO_MERGE,
+ FEAT_OMAP3_DSI_FIFO_BUG,
+};
+
+static const enum dispc_feature_id am43xx_dispc_features_list[] = {
+ FEAT_LCDENABLEPOL,
+ FEAT_LCDENABLESIGNAL,
+ FEAT_PCKFREEENABLE,
+ FEAT_FUNCGATED,
+ FEAT_LINEBUFFERSPLIT,
+ FEAT_ROWREPEATENABLE,
+ FEAT_RESIZECONF,
+ FEAT_CPR,
+ FEAT_PRELOAD,
+ FEAT_FIR_COEF_V,
+ FEAT_ALPHA_FIXED_ZORDER,
+ FEAT_FIFO_MERGE,
+};
+
+static const enum dispc_feature_id omap4_dispc_features_list[] = {
+ FEAT_MGR_LCD2,
+ FEAT_CORE_CLK_DIV,
+ FEAT_HANDLE_UV_SEPARATE,
+ FEAT_ATTR2,
+ FEAT_CPR,
+ FEAT_PRELOAD,
+ FEAT_FIR_COEF_V,
+ FEAT_ALPHA_FREE_ZORDER,
+ FEAT_FIFO_MERGE,
+ FEAT_BURST_2D,
+};
+
+static const enum dispc_feature_id omap5_dispc_features_list[] = {
+ FEAT_MGR_LCD2,
+ FEAT_MGR_LCD3,
+ FEAT_CORE_CLK_DIV,
+ FEAT_HANDLE_UV_SEPARATE,
+ FEAT_ATTR2,
+ FEAT_CPR,
+ FEAT_PRELOAD,
+ FEAT_FIR_COEF_V,
+ FEAT_ALPHA_FREE_ZORDER,
+ FEAT_FIFO_MERGE,
+ FEAT_BURST_2D,
+ FEAT_MFLAG,
+};
+
+static const struct dss_reg_field omap2_dispc_reg_fields[] = {
+ [FEAT_REG_FIRHINC] = { 11, 0 },
+ [FEAT_REG_FIRVINC] = { 27, 16 },
+ [FEAT_REG_FIFOLOWTHRESHOLD] = { 8, 0 },
+ [FEAT_REG_FIFOHIGHTHRESHOLD] = { 24, 16 },
+ [FEAT_REG_FIFOSIZE] = { 8, 0 },
+ [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
+ [FEAT_REG_VERTICALACCU] = { 25, 16 },
+};
+
+static const struct dss_reg_field omap3_dispc_reg_fields[] = {
+ [FEAT_REG_FIRHINC] = { 12, 0 },
+ [FEAT_REG_FIRVINC] = { 28, 16 },
+ [FEAT_REG_FIFOLOWTHRESHOLD] = { 11, 0 },
+ [FEAT_REG_FIFOHIGHTHRESHOLD] = { 27, 16 },
+ [FEAT_REG_FIFOSIZE] = { 10, 0 },
+ [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
+ [FEAT_REG_VERTICALACCU] = { 25, 16 },
+};
+
+static const struct dss_reg_field omap4_dispc_reg_fields[] = {
+ [FEAT_REG_FIRHINC] = { 12, 0 },
+ [FEAT_REG_FIRVINC] = { 28, 16 },
+ [FEAT_REG_FIFOLOWTHRESHOLD] = { 15, 0 },
+ [FEAT_REG_FIFOHIGHTHRESHOLD] = { 31, 16 },
+ [FEAT_REG_FIFOSIZE] = { 15, 0 },
+ [FEAT_REG_HORIZONTALACCU] = { 10, 0 },
+ [FEAT_REG_VERTICALACCU] = { 26, 16 },
+};
+
+static const enum omap_overlay_caps omap2_dispc_overlay_caps[] = {
+ /* OMAP_DSS_GFX */
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
+
+ /* OMAP_DSS_VIDEO1 */
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
+
+ /* OMAP_DSS_VIDEO2 */
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
+};
+
+static const enum omap_overlay_caps omap3430_dispc_overlay_caps[] = {
+ /* OMAP_DSS_GFX */
+ OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
+
+ /* OMAP_DSS_VIDEO1 */
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
+
+ /* OMAP_DSS_VIDEO2 */
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
+};
+
+static const enum omap_overlay_caps omap3630_dispc_overlay_caps[] = {
+ /* OMAP_DSS_GFX */
+ OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA |
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
+
+ /* OMAP_DSS_VIDEO1 */
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
+
+ /* OMAP_DSS_VIDEO2 */
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
+ OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
+};
+
+static const enum omap_overlay_caps omap4_dispc_overlay_caps[] = {
+ /* OMAP_DSS_GFX */
+ OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA |
+ OMAP_DSS_OVL_CAP_ZORDER | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
+
+ /* OMAP_DSS_VIDEO1 */
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
+ OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
+
+ /* OMAP_DSS_VIDEO2 */
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
+ OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
+
+ /* OMAP_DSS_VIDEO3 */
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
+ OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
+};
+
+#define COLOR_ARRAY(arr...) (const u32[]) { arr, 0 }
+
+static const u32 *omap2_dispc_supported_color_modes[] = {
+
+ /* OMAP_DSS_GFX */
+ COLOR_ARRAY(
+ DRM_FORMAT_RGBX4444, DRM_FORMAT_RGB565,
+ DRM_FORMAT_XRGB8888, DRM_FORMAT_RGB888),
+
+ /* OMAP_DSS_VIDEO1 */
+ COLOR_ARRAY(
+ DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_RGB888, DRM_FORMAT_YUYV,
+ DRM_FORMAT_UYVY),
+
+ /* OMAP_DSS_VIDEO2 */
+ COLOR_ARRAY(
+ DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_RGB888, DRM_FORMAT_YUYV,
+ DRM_FORMAT_UYVY),
+};
+
+static const u32 *omap3_dispc_supported_color_modes[] = {
+ /* OMAP_DSS_GFX */
+ COLOR_ARRAY(
+ DRM_FORMAT_RGBX4444, DRM_FORMAT_ARGB4444,
+ DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_RGB888, DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_RGBA8888, DRM_FORMAT_RGBX8888),
+
+ /* OMAP_DSS_VIDEO1 */
+ COLOR_ARRAY(
+ DRM_FORMAT_XRGB8888, DRM_FORMAT_RGB888,
+ DRM_FORMAT_RGBX4444, DRM_FORMAT_RGB565,
+ DRM_FORMAT_YUYV, DRM_FORMAT_UYVY),
+
+ /* OMAP_DSS_VIDEO2 */
+ COLOR_ARRAY(
+ DRM_FORMAT_RGBX4444, DRM_FORMAT_ARGB4444,
+ DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_RGB888, DRM_FORMAT_YUYV,
+ DRM_FORMAT_UYVY, DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_RGBA8888, DRM_FORMAT_RGBX8888),
+};
+
+static const u32 *omap4_dispc_supported_color_modes[] = {
+ /* OMAP_DSS_GFX */
+ COLOR_ARRAY(
+ DRM_FORMAT_RGBX4444, DRM_FORMAT_ARGB4444,
+ DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_RGB888, DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_RGBA8888, DRM_FORMAT_RGBX8888,
+ DRM_FORMAT_ARGB1555, DRM_FORMAT_XRGB4444,
+ DRM_FORMAT_RGBA4444, DRM_FORMAT_XRGB1555),
+
+ /* OMAP_DSS_VIDEO1 */
+ COLOR_ARRAY(
+ DRM_FORMAT_RGB565, DRM_FORMAT_RGBX4444,
+ DRM_FORMAT_YUYV, DRM_FORMAT_ARGB1555,
+ DRM_FORMAT_RGBA8888, DRM_FORMAT_NV12,
+ DRM_FORMAT_RGBA4444, DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_RGB888, DRM_FORMAT_UYVY,
+ DRM_FORMAT_ARGB4444, DRM_FORMAT_XRGB1555,
+ DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB4444,
+ DRM_FORMAT_RGBX8888),
+
+ /* OMAP_DSS_VIDEO2 */
+ COLOR_ARRAY(
+ DRM_FORMAT_RGB565, DRM_FORMAT_RGBX4444,
+ DRM_FORMAT_YUYV, DRM_FORMAT_ARGB1555,
+ DRM_FORMAT_RGBA8888, DRM_FORMAT_NV12,
+ DRM_FORMAT_RGBA4444, DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_RGB888, DRM_FORMAT_UYVY,
+ DRM_FORMAT_ARGB4444, DRM_FORMAT_XRGB1555,
+ DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB4444,
+ DRM_FORMAT_RGBX8888),
+
+ /* OMAP_DSS_VIDEO3 */
+ COLOR_ARRAY(
+ DRM_FORMAT_RGB565, DRM_FORMAT_RGBX4444,
+ DRM_FORMAT_YUYV, DRM_FORMAT_ARGB1555,
+ DRM_FORMAT_RGBA8888, DRM_FORMAT_NV12,
+ DRM_FORMAT_RGBA4444, DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_RGB888, DRM_FORMAT_UYVY,
+ DRM_FORMAT_ARGB4444, DRM_FORMAT_XRGB1555,
+ DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB4444,
+ DRM_FORMAT_RGBX8888),
+
+ /* OMAP_DSS_WB */
+ COLOR_ARRAY(
+ DRM_FORMAT_RGB565, DRM_FORMAT_RGBX4444,
+ DRM_FORMAT_YUYV, DRM_FORMAT_ARGB1555,
+ DRM_FORMAT_RGBA8888, DRM_FORMAT_NV12,
+ DRM_FORMAT_RGBA4444, DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_RGB888, DRM_FORMAT_UYVY,
+ DRM_FORMAT_ARGB4444, DRM_FORMAT_XRGB1555,
+ DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB4444,
+ DRM_FORMAT_RGBX8888),
+};
+
static const struct dispc_features omap24xx_dispc_feats = {
.sw_start = 5,
.fp_start = 15,
@@ -3701,9 +4046,26 @@ static const struct dispc_features omap24xx_dispc_feats = {
.mgr_width_max = 2048,
.mgr_height_max = 2048,
.max_lcd_pclk = 66500000,
+ .max_downscale = 2,
+ /*
+ * Assume the line width buffer to be 768 pixels as OMAP2 DISPC scaler
+ * cannot scale an image width larger than 768.
+ */
+ .max_line_width = 768,
+ .min_pcd = 2,
.calc_scaling = dispc_ovl_calc_scaling_24xx,
.calc_core_clk = calc_core_clk_24xx,
.num_fifos = 3,
+ .features = omap2_dispc_features_list,
+ .num_features = ARRAY_SIZE(omap2_dispc_features_list),
+ .reg_fields = omap2_dispc_reg_fields,
+ .num_reg_fields = ARRAY_SIZE(omap2_dispc_reg_fields),
+ .overlay_caps = omap2_dispc_overlay_caps,
+ .supported_color_modes = omap2_dispc_supported_color_modes,
+ .num_mgrs = 2,
+ .num_ovls = 3,
+ .buffer_size_unit = 1,
+ .burst_size_unit = 8,
.no_framedone_tv = true,
.set_max_preload = false,
.last_pixel_inc_missing = true,
@@ -3722,9 +4084,22 @@ static const struct dispc_features omap34xx_rev1_0_dispc_feats = {
.mgr_height_max = 2048,
.max_lcd_pclk = 173000000,
.max_tv_pclk = 59000000,
+ .max_downscale = 4,
+ .max_line_width = 1024,
+ .min_pcd = 1,
.calc_scaling = dispc_ovl_calc_scaling_34xx,
.calc_core_clk = calc_core_clk_34xx,
.num_fifos = 3,
+ .features = omap3_dispc_features_list,
+ .num_features = ARRAY_SIZE(omap3_dispc_features_list),
+ .reg_fields = omap3_dispc_reg_fields,
+ .num_reg_fields = ARRAY_SIZE(omap3_dispc_reg_fields),
+ .overlay_caps = omap3430_dispc_overlay_caps,
+ .supported_color_modes = omap3_dispc_supported_color_modes,
+ .num_mgrs = 2,
+ .num_ovls = 3,
+ .buffer_size_unit = 1,
+ .burst_size_unit = 8,
.no_framedone_tv = true,
.set_max_preload = false,
.last_pixel_inc_missing = true,
@@ -3743,9 +4118,90 @@ static const struct dispc_features omap34xx_rev3_0_dispc_feats = {
.mgr_height_max = 2048,
.max_lcd_pclk = 173000000,
.max_tv_pclk = 59000000,
+ .max_downscale = 4,
+ .max_line_width = 1024,
+ .min_pcd = 1,
+ .calc_scaling = dispc_ovl_calc_scaling_34xx,
+ .calc_core_clk = calc_core_clk_34xx,
+ .num_fifos = 3,
+ .features = omap3_dispc_features_list,
+ .num_features = ARRAY_SIZE(omap3_dispc_features_list),
+ .reg_fields = omap3_dispc_reg_fields,
+ .num_reg_fields = ARRAY_SIZE(omap3_dispc_reg_fields),
+ .overlay_caps = omap3430_dispc_overlay_caps,
+ .supported_color_modes = omap3_dispc_supported_color_modes,
+ .num_mgrs = 2,
+ .num_ovls = 3,
+ .buffer_size_unit = 1,
+ .burst_size_unit = 8,
+ .no_framedone_tv = true,
+ .set_max_preload = false,
+ .last_pixel_inc_missing = true,
+};
+
+static const struct dispc_features omap36xx_dispc_feats = {
+ .sw_start = 7,
+ .fp_start = 19,
+ .bp_start = 31,
+ .sw_max = 256,
+ .vp_max = 4095,
+ .hp_max = 4096,
+ .mgr_width_start = 10,
+ .mgr_height_start = 26,
+ .mgr_width_max = 2048,
+ .mgr_height_max = 2048,
+ .max_lcd_pclk = 173000000,
+ .max_tv_pclk = 59000000,
+ .max_downscale = 4,
+ .max_line_width = 1024,
+ .min_pcd = 1,
.calc_scaling = dispc_ovl_calc_scaling_34xx,
.calc_core_clk = calc_core_clk_34xx,
.num_fifos = 3,
+ .features = omap3_dispc_features_list,
+ .num_features = ARRAY_SIZE(omap3_dispc_features_list),
+ .reg_fields = omap3_dispc_reg_fields,
+ .num_reg_fields = ARRAY_SIZE(omap3_dispc_reg_fields),
+ .overlay_caps = omap3630_dispc_overlay_caps,
+ .supported_color_modes = omap3_dispc_supported_color_modes,
+ .num_mgrs = 2,
+ .num_ovls = 3,
+ .buffer_size_unit = 1,
+ .burst_size_unit = 8,
+ .no_framedone_tv = true,
+ .set_max_preload = false,
+ .last_pixel_inc_missing = true,
+};
+
+static const struct dispc_features am43xx_dispc_feats = {
+ .sw_start = 7,
+ .fp_start = 19,
+ .bp_start = 31,
+ .sw_max = 256,
+ .vp_max = 4095,
+ .hp_max = 4096,
+ .mgr_width_start = 10,
+ .mgr_height_start = 26,
+ .mgr_width_max = 2048,
+ .mgr_height_max = 2048,
+ .max_lcd_pclk = 173000000,
+ .max_tv_pclk = 59000000,
+ .max_downscale = 4,
+ .max_line_width = 1024,
+ .min_pcd = 1,
+ .calc_scaling = dispc_ovl_calc_scaling_34xx,
+ .calc_core_clk = calc_core_clk_34xx,
+ .num_fifos = 3,
+ .features = am43xx_dispc_features_list,
+ .num_features = ARRAY_SIZE(am43xx_dispc_features_list),
+ .reg_fields = omap3_dispc_reg_fields,
+ .num_reg_fields = ARRAY_SIZE(omap3_dispc_reg_fields),
+ .overlay_caps = omap3430_dispc_overlay_caps,
+ .supported_color_modes = omap3_dispc_supported_color_modes,
+ .num_mgrs = 1,
+ .num_ovls = 3,
+ .buffer_size_unit = 1,
+ .burst_size_unit = 8,
.no_framedone_tv = true,
.set_max_preload = false,
.last_pixel_inc_missing = true,
@@ -3764,9 +4220,22 @@ static const struct dispc_features omap44xx_dispc_feats = {
.mgr_height_max = 2048,
.max_lcd_pclk = 170000000,
.max_tv_pclk = 185625000,
+ .max_downscale = 4,
+ .max_line_width = 2048,
+ .min_pcd = 1,
.calc_scaling = dispc_ovl_calc_scaling_44xx,
.calc_core_clk = calc_core_clk_44xx,
.num_fifos = 5,
+ .features = omap4_dispc_features_list,
+ .num_features = ARRAY_SIZE(omap4_dispc_features_list),
+ .reg_fields = omap4_dispc_reg_fields,
+ .num_reg_fields = ARRAY_SIZE(omap4_dispc_reg_fields),
+ .overlay_caps = omap4_dispc_overlay_caps,
+ .supported_color_modes = omap4_dispc_supported_color_modes,
+ .num_mgrs = 3,
+ .num_ovls = 4,
+ .buffer_size_unit = 16,
+ .burst_size_unit = 16,
.gfx_fifo_workaround = true,
.set_max_preload = true,
.supports_sync_align = true,
@@ -3790,9 +4259,22 @@ static const struct dispc_features omap54xx_dispc_feats = {
.mgr_height_max = 4096,
.max_lcd_pclk = 170000000,
.max_tv_pclk = 186000000,
+ .max_downscale = 4,
+ .max_line_width = 2048,
+ .min_pcd = 1,
.calc_scaling = dispc_ovl_calc_scaling_44xx,
.calc_core_clk = calc_core_clk_44xx,
.num_fifos = 5,
+ .features = omap5_dispc_features_list,
+ .num_features = ARRAY_SIZE(omap5_dispc_features_list),
+ .reg_fields = omap4_dispc_reg_fields,
+ .num_reg_fields = ARRAY_SIZE(omap4_dispc_reg_fields),
+ .overlay_caps = omap4_dispc_overlay_caps,
+ .supported_color_modes = omap4_dispc_supported_color_modes,
+ .num_mgrs = 4,
+ .num_ovls = 4,
+ .buffer_size_unit = 16,
+ .burst_size_unit = 16,
.gfx_fifo_workaround = true,
.mstandby_workaround = true,
.set_max_preload = true,
@@ -3804,54 +4286,6 @@ static const struct dispc_features omap54xx_dispc_feats = {
.has_gamma_i734_bug = true,
};
-static int dispc_init_features(struct platform_device *pdev)
-{
- const struct dispc_features *src;
- struct dispc_features *dst;
-
- dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL);
- if (!dst) {
- dev_err(&pdev->dev, "Failed to allocate DISPC Features\n");
- return -ENOMEM;
- }
-
- switch (omapdss_get_version()) {
- case OMAPDSS_VER_OMAP24xx:
- src = &omap24xx_dispc_feats;
- break;
-
- case OMAPDSS_VER_OMAP34xx_ES1:
- src = &omap34xx_rev1_0_dispc_feats;
- break;
-
- case OMAPDSS_VER_OMAP34xx_ES3:
- case OMAPDSS_VER_OMAP3630:
- case OMAPDSS_VER_AM35xx:
- case OMAPDSS_VER_AM43xx:
- src = &omap34xx_rev3_0_dispc_feats;
- break;
-
- case OMAPDSS_VER_OMAP4430_ES1:
- case OMAPDSS_VER_OMAP4430_ES2:
- case OMAPDSS_VER_OMAP4:
- src = &omap44xx_dispc_feats;
- break;
-
- case OMAPDSS_VER_OMAP5:
- case OMAPDSS_VER_DRA7xx:
- src = &omap54xx_dispc_feats;
- break;
-
- default:
- return -ENODEV;
- }
-
- memcpy(dst, src, sizeof(*dst));
- dispc.feat = dst;
-
- return 0;
-}
-
static irqreturn_t dispc_irq_handler(int irq, void *arg)
{
if (!dispc.is_enabled)
@@ -4083,9 +4517,28 @@ static const struct dispc_ops dispc_ops = {
};
/* DISPC HW IP initialisation */
+static const struct of_device_id dispc_of_match[] = {
+ { .compatible = "ti,omap2-dispc", .data = &omap24xx_dispc_feats },
+ { .compatible = "ti,omap3-dispc", .data = &omap36xx_dispc_feats },
+ { .compatible = "ti,omap4-dispc", .data = &omap44xx_dispc_feats },
+ { .compatible = "ti,omap5-dispc", .data = &omap54xx_dispc_feats },
+ { .compatible = "ti,dra7-dispc", .data = &omap54xx_dispc_feats },
+ {},
+};
+
+static const struct soc_device_attribute dispc_soc_devices[] = {
+ { .machine = "OMAP3[45]*",
+ .revision = "ES[12].?", .data = &omap34xx_rev1_0_dispc_feats },
+ { .machine = "OMAP3[45]*", .data = &omap34xx_rev3_0_dispc_feats },
+ { .machine = "AM35*", .data = &omap34xx_rev3_0_dispc_feats },
+ { .machine = "AM43*", .data = &am43xx_dispc_feats },
+ { /* sentinel */ }
+};
+
static int dispc_bind(struct device *dev, struct device *master, void *data)
{
struct platform_device *pdev = to_platform_device(dev);
+ const struct soc_device_attribute *soc;
u32 rev;
int r = 0;
struct resource *dispc_mem;
@@ -4095,9 +4548,15 @@ static int dispc_bind(struct device *dev, struct device *master, void *data)
spin_lock_init(&dispc.control_lock);
- r = dispc_init_features(dispc.pdev);
- if (r)
- return r;
+ /*
+ * The OMAP3-based models can't be told apart using the compatible
+ * string, use SoC device matching.
+ */
+ soc = soc_device_match(dispc_soc_devices);
+ if (soc)
+ dispc.feat = soc->data;
+ else
+ dispc.feat = of_match_device(dispc_of_match, &pdev->dev)->data;
r = dispc_errata_i734_wa_init();
if (r)
@@ -4226,15 +4685,6 @@ static const struct dev_pm_ops dispc_pm_ops = {
.runtime_resume = dispc_runtime_resume,
};
-static const struct of_device_id dispc_of_match[] = {
- { .compatible = "ti,omap2-dispc", },
- { .compatible = "ti,omap3-dispc", },
- { .compatible = "ti,omap4-dispc", },
- { .compatible = "ti,omap5-dispc", },
- { .compatible = "ti,dra7-dispc", },
- {},
-};
-
static struct platform_driver omap_dispchw_driver = {
.probe = dispc_probe,
.remove = dispc_remove,
diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c b/drivers/gpu/drm/omapdrm/dss/dpi.c
index 86dbb65..daf286f 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -32,13 +32,14 @@
#include <linux/string.h>
#include <linux/of.h>
#include <linux/clk.h>
+#include <linux/sys_soc.h>
#include "omapdss.h"
#include "dss.h"
-#include "dss_features.h"
struct dpi_data {
struct platform_device *pdev;
+ enum dss_model dss_model;
struct regulator *vdds_dsi_reg;
enum dss_clk_source clk_src;
@@ -99,25 +100,21 @@ static enum dss_clk_source dpi_get_clk_src_dra7xx(enum omap_channel channel)
return DSS_CLK_SRC_FCK;
}
-static enum dss_clk_source dpi_get_clk_src(enum omap_channel channel)
+static enum dss_clk_source dpi_get_clk_src(struct dpi_data *dpi)
{
+ enum omap_channel channel = dpi->output.dispc_channel;
+
/*
* XXX we can't currently use DSI PLL for DPI with OMAP3, as the DSI PLL
* would also be used for DISPC fclk. Meaning, when the DPI output is
* disabled, DISPC clock will be disabled, and TV out will stop.
*/
- switch (omapdss_get_version()) {
- case OMAPDSS_VER_OMAP24xx:
- case OMAPDSS_VER_OMAP34xx_ES1:
- case OMAPDSS_VER_OMAP34xx_ES3:
- case OMAPDSS_VER_OMAP3630:
- case OMAPDSS_VER_AM35xx:
- case OMAPDSS_VER_AM43xx:
+ switch (dpi->dss_model) {
+ case DSS_MODEL_OMAP2:
+ case DSS_MODEL_OMAP3:
return DSS_CLK_SRC_FCK;
- case OMAPDSS_VER_OMAP4430_ES1:
- case OMAPDSS_VER_OMAP4430_ES2:
- case OMAPDSS_VER_OMAP4:
+ case DSS_MODEL_OMAP4:
switch (channel) {
case OMAP_DSS_CHANNEL_LCD:
return DSS_CLK_SRC_PLL1_1;
@@ -127,7 +124,7 @@ static enum dss_clk_source dpi_get_clk_src(enum omap_channel channel)
return DSS_CLK_SRC_FCK;
}
- case OMAPDSS_VER_OMAP5:
+ case DSS_MODEL_OMAP5:
switch (channel) {
case OMAP_DSS_CHANNEL_LCD:
return DSS_CLK_SRC_PLL1_1;
@@ -138,7 +135,7 @@ static enum dss_clk_source dpi_get_clk_src(enum omap_channel channel)
return DSS_CLK_SRC_FCK;
}
- case OMAPDSS_VER_DRA7xx:
+ case DSS_MODEL_DRA7:
return dpi_get_clk_src_dra7xx(channel);
default:
@@ -213,7 +210,7 @@ static bool dpi_calc_pll_cb(int n, int m, unsigned long fint,
ctx->pll_cinfo.clkdco = clkdco;
return dss_pll_hsdiv_calc_a(ctx->pll, clkdco,
- ctx->pck_min, dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
+ ctx->pck_min, dss_get_max_fck_rate(),
dpi_calc_hsdiv_cb, ctx);
}
@@ -403,19 +400,13 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
mutex_lock(&dpi->lock);
- if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && !dpi->vdds_dsi_reg) {
- DSSERR("no VDSS_DSI regulator\n");
- r = -ENODEV;
- goto err_no_reg;
- }
-
if (!out->dispc_channel_connected) {
DSSERR("failed to enable display: no output/manager\n");
r = -ENODEV;
goto err_no_out_mgr;
}
- if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) {
+ if (dpi->vdds_dsi_reg) {
r = regulator_enable(dpi->vdds_dsi_reg);
if (r)
goto err_reg_enable;
@@ -459,11 +450,10 @@ err_pll_init:
err_src_sel:
dispc_runtime_put();
err_get_dispc:
- if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
+ if (dpi->vdds_dsi_reg)
regulator_disable(dpi->vdds_dsi_reg);
err_reg_enable:
err_no_out_mgr:
-err_no_reg:
mutex_unlock(&dpi->lock);
return r;
}
@@ -484,7 +474,7 @@ static void dpi_display_disable(struct omap_dss_device *dssdev)
dispc_runtime_put();
- if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
+ if (dpi->vdds_dsi_reg)
regulator_disable(dpi->vdds_dsi_reg);
mutex_unlock(&dpi->lock);
@@ -575,11 +565,21 @@ static int dpi_verify_pll(struct dss_pll *pll)
return 0;
}
+static const struct soc_device_attribute dpi_soc_devices[] = {
+ { .family = "OMAP3[456]*" },
+ { .family = "[AD]M37*" },
+ { /* sentinel */ }
+};
+
static int dpi_init_regulator(struct dpi_data *dpi)
{
struct regulator *vdds_dsi;
- if (!dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
+ /*
+ * The DPI uses the DSI VDDS on OMAP34xx, OMAP35xx, OMAP36xx, AM37xx and
+ * DM37xx only.
+ */
+ if (!soc_device_match(dpi_soc_devices))
return 0;
if (dpi->vdds_dsi_reg)
@@ -604,7 +604,7 @@ static void dpi_init_pll(struct dpi_data *dpi)
if (dpi->pll)
return;
- dpi->clk_src = dpi_get_clk_src(dpi->output.dispc_channel);
+ dpi->clk_src = dpi_get_clk_src(dpi);
pll = dss_pll_find_by_src(dpi->clk_src);
if (!pll)
@@ -624,18 +624,14 @@ static void dpi_init_pll(struct dpi_data *dpi)
* the channel in some more dynamic manner, or get the channel as a user
* parameter.
*/
-static enum omap_channel dpi_get_channel(int port_num)
+static enum omap_channel dpi_get_channel(struct dpi_data *dpi, int port_num)
{
- switch (omapdss_get_version()) {
- case OMAPDSS_VER_OMAP24xx:
- case OMAPDSS_VER_OMAP34xx_ES1:
- case OMAPDSS_VER_OMAP34xx_ES3:
- case OMAPDSS_VER_OMAP3630:
- case OMAPDSS_VER_AM35xx:
- case OMAPDSS_VER_AM43xx:
+ switch (dpi->dss_model) {
+ case DSS_MODEL_OMAP2:
+ case DSS_MODEL_OMAP3:
return OMAP_DSS_CHANNEL_LCD;
- case OMAPDSS_VER_DRA7xx:
+ case DSS_MODEL_DRA7:
switch (port_num) {
case 2:
return OMAP_DSS_CHANNEL_LCD3;
@@ -646,12 +642,10 @@ static enum omap_channel dpi_get_channel(int port_num)
return OMAP_DSS_CHANNEL_LCD;
}
- case OMAPDSS_VER_OMAP4430_ES1:
- case OMAPDSS_VER_OMAP4430_ES2:
- case OMAPDSS_VER_OMAP4:
+ case DSS_MODEL_OMAP4:
return OMAP_DSS_CHANNEL_LCD2;
- case OMAPDSS_VER_OMAP5:
+ case DSS_MODEL_OMAP5:
return OMAP_DSS_CHANNEL_LCD3;
default:
@@ -716,10 +710,8 @@ static const struct omapdss_dpi_ops dpi_ops = {
.get_timings = dpi_get_timings,
};
-static void dpi_init_output_port(struct platform_device *pdev,
- struct device_node *port)
+static void dpi_init_output_port(struct dpi_data *dpi, struct device_node *port)
{
- struct dpi_data *dpi = port->data;
struct omap_dss_device *out = &dpi->output;
int r;
u32 port_num;
@@ -741,10 +733,10 @@ static void dpi_init_output_port(struct platform_device *pdev,
break;
}
- out->dev = &pdev->dev;
+ out->dev = &dpi->pdev->dev;
out->id = OMAP_DSS_OUTPUT_DPI;
out->output_type = OMAP_DISPLAY_TYPE_DPI;
- out->dispc_channel = dpi_get_channel(port_num);
+ out->dispc_channel = dpi_get_channel(dpi, port_num);
out->port_num = port_num;
out->ops.dpi = &dpi_ops;
out->owner = THIS_MODULE;
@@ -760,7 +752,8 @@ static void dpi_uninit_output_port(struct device_node *port)
omapdss_unregister_output(out);
}
-int dpi_init_port(struct platform_device *pdev, struct device_node *port)
+int dpi_init_port(struct platform_device *pdev, struct device_node *port,
+ enum dss_model dss_model)
{
struct dpi_data *dpi;
struct device_node *ep;
@@ -786,11 +779,12 @@ int dpi_init_port(struct platform_device *pdev, struct device_node *port)
of_node_put(ep);
dpi->pdev = pdev;
+ dpi->dss_model = dss_model;
port->data = dpi;
mutex_init(&dpi->lock);
- dpi_init_output_port(pdev, port);
+ dpi_init_output_port(dpi, port);
dpi->port_initialized = true;
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 835f490..b56a057 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -20,6 +20,8 @@
#define DSS_SUBSYS_NAME "DSI"
#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/device.h>
@@ -42,12 +44,12 @@
#include <linux/of_graph.h>
#include <linux/of_platform.h>
#include <linux/component.h>
+#include <linux/sys_soc.h>
#include <video/mipi_display.h>
#include "omapdss.h"
#include "dss.h"
-#include "dss_features.h"
#define DSI_CATCH_MISSING_TE
@@ -228,6 +230,12 @@ static int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel);
#define DSI_MAX_NR_ISRS 2
#define DSI_MAX_NR_LANES 5
+enum dsi_model {
+ DSI_MODEL_OMAP3,
+ DSI_MODEL_OMAP4,
+ DSI_MODEL_OMAP5,
+};
+
enum dsi_lane_function {
DSI_LANE_UNUSED = 0,
DSI_LANE_CLK,
@@ -299,12 +307,36 @@ struct dsi_lp_clock_info {
u16 lp_clk_div;
};
+struct dsi_module_id_data {
+ u32 address;
+ int id;
+};
+
+enum dsi_quirks {
+ DSI_QUIRK_PLL_PWR_BUG = (1 << 0), /* DSI-PLL power command 0x3 is not working */
+ DSI_QUIRK_DCS_CMD_CONFIG_VC = (1 << 1),
+ DSI_QUIRK_VC_OCP_WIDTH = (1 << 2),
+ DSI_QUIRK_REVERSE_TXCLKESC = (1 << 3),
+ DSI_QUIRK_GNQ = (1 << 4),
+ DSI_QUIRK_PHY_DCC = (1 << 5),
+};
+
+struct dsi_of_data {
+ enum dsi_model model;
+ const struct dss_pll_hw *pll_hw;
+ const struct dsi_module_id_data *modules;
+ unsigned int max_fck_freq;
+ unsigned int max_pll_lpdiv;
+ enum dsi_quirks quirks;
+};
+
struct dsi_data {
struct platform_device *pdev;
void __iomem *proto_base;
void __iomem *phy_base;
void __iomem *pll_base;
+ const struct dsi_of_data *data;
int module_id;
int irq;
@@ -312,6 +344,7 @@ struct dsi_data {
bool is_enabled;
struct clk *dss_clk;
+ struct regmap *syscon;
struct dispc_clock_info user_dispc_cinfo;
struct dss_pll_clock_info user_dsi_cinfo;
@@ -397,13 +430,6 @@ struct dsi_packet_sent_handler_data {
struct completion *completion;
};
-struct dsi_module_id_data {
- u32 address;
- int id;
-};
-
-static const struct of_device_id dsi_of_match[];
-
#ifdef DSI_PERF_MEASURE
static bool dsi_perf;
module_param(dsi_perf, bool, 0644);
@@ -1186,6 +1212,7 @@ static int dsi_regulator_init(struct platform_device *dsidev)
static void _dsi_print_reset_status(struct platform_device *dsidev)
{
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
u32 l;
int b0, b1, b2;
@@ -1194,7 +1221,7 @@ static void _dsi_print_reset_status(struct platform_device *dsidev)
* I/O. */
l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5);
- if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC)) {
+ if (dsi->data->quirks & DSI_QUIRK_REVERSE_TXCLKESC) {
b0 = 28;
b1 = 27;
b2 = 26;
@@ -1297,7 +1324,7 @@ static int dsi_set_lp_clk_divisor(struct platform_device *dsidev)
unsigned long dsi_fclk;
unsigned lp_clk_div;
unsigned long lp_clk;
- unsigned lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV);
+ unsigned lpdiv_max = dsi->data->max_pll_lpdiv;
lp_clk_div = dsi->user_lp_cinfo.lp_clk_div;
@@ -1349,11 +1376,12 @@ enum dsi_pll_power_state {
static int dsi_pll_power(struct platform_device *dsidev,
enum dsi_pll_power_state state)
{
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
int t = 0;
/* DSI-PLL power command 0x3 is not working */
- if (dss_has_feature(FEAT_DSI_PLL_PWR_BUG) &&
- state == DSI_PLL_POWER_ON_DIV)
+ if ((dsi->data->quirks & DSI_QUIRK_PLL_PWR_BUG) &&
+ state == DSI_PLL_POWER_ON_DIV)
state = DSI_PLL_POWER_ON_ALL;
/* PLL_PWR_CMD */
@@ -1373,11 +1401,12 @@ static int dsi_pll_power(struct platform_device *dsidev,
}
-static void dsi_pll_calc_dsi_fck(struct dss_pll_clock_info *cinfo)
+static void dsi_pll_calc_dsi_fck(struct dsi_data *dsi,
+ struct dss_pll_clock_info *cinfo)
{
unsigned long max_dsi_fck;
- max_dsi_fck = dss_feat_get_param_max(FEAT_PARAM_DSI_FCK);
+ max_dsi_fck = dsi->data->max_fck_freq;
cinfo->mX[HSDIV_DSI] = DIV_ROUND_UP(cinfo->clkdco, max_dsi_fck);
cinfo->clkout[HSDIV_DSI] = cinfo->clkdco / cinfo->mX[HSDIV_DSI];
@@ -1773,13 +1802,14 @@ static int dsi_cio_power(struct platform_device *dsidev,
static unsigned dsi_get_line_buf_size(struct platform_device *dsidev)
{
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
int val;
/* line buffer on OMAP3 is 1024 x 24bits */
/* XXX: for some reason using full buffer size causes
* considerable TX slowdown with update sizes that fill the
* whole buffer */
- if (!dss_has_feature(FEAT_DSI_GNQ))
+ if (!(dsi->data->quirks & DSI_QUIRK_GNQ))
return 1023 * 3;
val = REG_GET(dsidev, DSI_GNQ, 14, 12); /* VP1_LINE_BUFFER_SIZE */
@@ -1872,6 +1902,7 @@ static inline unsigned ddr2ns(struct platform_device *dsidev, unsigned ddr)
static void dsi_cio_timings(struct platform_device *dsidev)
{
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
u32 r;
u32 ths_prepare, ths_prepare_ths_zero, ths_trail, ths_exit;
u32 tlpx_half, tclk_trail, tclk_zero;
@@ -1934,7 +1965,7 @@ static void dsi_cio_timings(struct platform_device *dsidev)
r = FLD_MOD(r, tclk_trail, 15, 8);
r = FLD_MOD(r, tclk_zero, 7, 0);
- if (dss_has_feature(FEAT_DSI_PHY_DCC)) {
+ if (dsi->data->quirks & DSI_QUIRK_PHY_DCC) {
r = FLD_MOD(r, 0, 21, 21); /* DCCEN = disable */
r = FLD_MOD(r, 1, 22, 22); /* CLKINP_DIVBY2EN = enable */
r = FLD_MOD(r, 1, 23, 23); /* CLKINP_SEL = enable */
@@ -2006,7 +2037,7 @@ static int dsi_cio_wait_tx_clk_esc_reset(struct platform_device *dsidev)
static const u8 offsets_new[] = { 24, 25, 26, 27, 28 };
const u8 *offsets;
- if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC))
+ if (dsi->data->quirks & DSI_QUIRK_REVERSE_TXCLKESC)
offsets = offsets_old;
else
offsets = offsets_new;
@@ -2060,6 +2091,83 @@ static unsigned dsi_get_lane_mask(struct platform_device *dsidev)
return mask;
}
+/* OMAP4 CONTROL_DSIPHY */
+#define OMAP4_DSIPHY_SYSCON_OFFSET 0x78
+
+#define OMAP4_DSI2_LANEENABLE_SHIFT 29
+#define OMAP4_DSI2_LANEENABLE_MASK (0x7 << 29)
+#define OMAP4_DSI1_LANEENABLE_SHIFT 24
+#define OMAP4_DSI1_LANEENABLE_MASK (0x1f << 24)
+#define OMAP4_DSI1_PIPD_SHIFT 19
+#define OMAP4_DSI1_PIPD_MASK (0x1f << 19)
+#define OMAP4_DSI2_PIPD_SHIFT 14
+#define OMAP4_DSI2_PIPD_MASK (0x1f << 14)
+
+static int dsi_omap4_mux_pads(struct dsi_data *dsi, unsigned int lanes)
+{
+ u32 enable_mask, enable_shift;
+ u32 pipd_mask, pipd_shift;
+
+ if (dsi->module_id == 0) {
+ enable_mask = OMAP4_DSI1_LANEENABLE_MASK;
+ enable_shift = OMAP4_DSI1_LANEENABLE_SHIFT;
+ pipd_mask = OMAP4_DSI1_PIPD_MASK;
+ pipd_shift = OMAP4_DSI1_PIPD_SHIFT;
+ } else if (dsi->module_id == 1) {
+ enable_mask = OMAP4_DSI2_LANEENABLE_MASK;
+ enable_shift = OMAP4_DSI2_LANEENABLE_SHIFT;
+ pipd_mask = OMAP4_DSI2_PIPD_MASK;
+ pipd_shift = OMAP4_DSI2_PIPD_SHIFT;
+ } else {
+ return -ENODEV;
+ }
+
+ return regmap_update_bits(dsi->syscon, OMAP4_DSIPHY_SYSCON_OFFSET,
+ enable_mask | pipd_mask,
+ (lanes << enable_shift) | (lanes << pipd_shift));
+}
+
+/* OMAP5 CONTROL_DSIPHY */
+
+#define OMAP5_DSIPHY_SYSCON_OFFSET 0x74
+
+#define OMAP5_DSI1_LANEENABLE_SHIFT 24
+#define OMAP5_DSI2_LANEENABLE_SHIFT 19
+#define OMAP5_DSI_LANEENABLE_MASK 0x1f
+
+static int dsi_omap5_mux_pads(struct dsi_data *dsi, unsigned int lanes)
+{
+ u32 enable_shift;
+
+ if (dsi->module_id == 0)
+ enable_shift = OMAP5_DSI1_LANEENABLE_SHIFT;
+ else if (dsi->module_id == 1)
+ enable_shift = OMAP5_DSI2_LANEENABLE_SHIFT;
+ else
+ return -ENODEV;
+
+ return regmap_update_bits(dsi->syscon, OMAP5_DSIPHY_SYSCON_OFFSET,
+ OMAP5_DSI_LANEENABLE_MASK << enable_shift,
+ lanes << enable_shift);
+}
+
+static int dsi_enable_pads(struct dsi_data *dsi, unsigned int lane_mask)
+{
+ if (dsi->data->model == DSI_MODEL_OMAP4)
+ return dsi_omap4_mux_pads(dsi, lane_mask);
+ if (dsi->data->model == DSI_MODEL_OMAP5)
+ return dsi_omap5_mux_pads(dsi, lane_mask);
+ return 0;
+}
+
+static void dsi_disable_pads(struct dsi_data *dsi)
+{
+ if (dsi->data->model == DSI_MODEL_OMAP4)
+ dsi_omap4_mux_pads(dsi, 0);
+ else if (dsi->data->model == DSI_MODEL_OMAP5)
+ dsi_omap5_mux_pads(dsi, 0);
+}
+
static int dsi_cio_init(struct platform_device *dsidev)
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
@@ -2068,7 +2176,7 @@ static int dsi_cio_init(struct platform_device *dsidev)
DSSDBG("DSI CIO init starts");
- r = dss_dsi_enable_pads(dsi->module_id, dsi_get_lane_mask(dsidev));
+ r = dsi_enable_pads(dsi, dsi_get_lane_mask(dsidev));
if (r)
return r;
@@ -2178,7 +2286,7 @@ err_cio_pwr:
dsi_cio_disable_lane_override(dsidev);
err_scp_clk_dom:
dsi_disable_scp_clk(dsidev);
- dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dsidev));
+ dsi_disable_pads(dsi);
return r;
}
@@ -2191,7 +2299,7 @@ static void dsi_cio_uninit(struct platform_device *dsidev)
dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF);
dsi_disable_scp_clk(dsidev);
- dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dsidev));
+ dsi_disable_pads(dsi);
}
static void dsi_config_tx_fifo(struct platform_device *dsidev,
@@ -2439,7 +2547,7 @@ static void dsi_vc_initial_config(struct platform_device *dsidev, int channel)
r = FLD_MOD(r, 1, 7, 7); /* CS_TX_EN */
r = FLD_MOD(r, 1, 8, 8); /* ECC_TX_EN */
r = FLD_MOD(r, 0, 9, 9); /* MODE_SPEED, high speed on/off */
- if (dss_has_feature(FEAT_DSI_VC_OCP_WIDTH))
+ if (dsi->data->quirks & DSI_QUIRK_VC_OCP_WIDTH)
r = FLD_MOD(r, 3, 11, 10); /* OCP_WIDTH = 32 bit */
r = FLD_MOD(r, 4, 29, 27); /* DMA_RX_REQ_NB = no dma */
@@ -2474,7 +2582,7 @@ static int dsi_vc_config_source(struct platform_device *dsidev, int channel,
REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), source, 1, 1);
/* DCS_CMD_ENABLE */
- if (dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC)) {
+ if (dsi->data->quirks & DSI_QUIRK_DCS_CMD_CONFIG_VC) {
bool enable = source == DSI_VC_SOURCE_VP;
REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), enable, 30, 30);
}
@@ -3607,7 +3715,7 @@ static int dsi_proto_config(struct platform_device *dsidev)
r = FLD_MOD(r, 0, 8, 8); /* VP_CLK_POL */
r = FLD_MOD(r, 1, 14, 14); /* TRIGGER_RESET_MODE */
r = FLD_MOD(r, 1, 19, 19); /* EOT_ENABLE */
- if (!dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC)) {
+ if (!(dsi->data->quirks & DSI_QUIRK_DCS_CMD_CONFIG_VC)) {
r = FLD_MOD(r, 1, 24, 24); /* DCS_CMD_ENABLE */
/* DCS_CMD_CODE, 1=start, 0=continue */
r = FLD_MOD(r, 0, 25, 25);
@@ -4450,6 +4558,7 @@ static bool dsi_cm_calc_pll_cb(int n, int m, unsigned long fint,
unsigned long clkdco, void *data)
{
struct dsi_clk_calc_ctx *ctx = data;
+ struct dsi_data *dsi = dsi_get_dsidrv_data(ctx->dsidev);
ctx->dsi_cinfo.n = n;
ctx->dsi_cinfo.m = m;
@@ -4457,7 +4566,7 @@ static bool dsi_cm_calc_pll_cb(int n, int m, unsigned long fint,
ctx->dsi_cinfo.clkdco = clkdco;
return dss_pll_hsdiv_calc_a(ctx->pll, clkdco, ctx->req_pck_min,
- dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
+ dsi->data->max_fck_freq,
dsi_cm_calc_hsdiv_cb, ctx);
}
@@ -4749,6 +4858,7 @@ static bool dsi_vm_calc_pll_cb(int n, int m, unsigned long fint,
unsigned long clkdco, void *data)
{
struct dsi_clk_calc_ctx *ctx = data;
+ struct dsi_data *dsi = dsi_get_dsidrv_data(ctx->dsidev);
ctx->dsi_cinfo.n = n;
ctx->dsi_cinfo.m = m;
@@ -4756,7 +4866,7 @@ static bool dsi_vm_calc_pll_cb(int n, int m, unsigned long fint,
ctx->dsi_cinfo.clkdco = clkdco;
return dss_pll_hsdiv_calc_a(ctx->pll, clkdco, ctx->req_pck_min,
- dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
+ dsi->data->max_fck_freq,
dsi_vm_calc_hsdiv_cb, ctx);
}
@@ -4827,7 +4937,7 @@ static int dsi_set_config(struct omap_dss_device *dssdev,
goto err;
}
- dsi_pll_calc_dsi_fck(&ctx.dsi_cinfo);
+ dsi_pll_calc_dsi_fck(dsi, &ctx.dsi_cinfo);
r = dsi_lp_clock_calc(ctx.dsi_cinfo.clkout[HSDIV_DSI],
config->lp_clk_min, config->lp_clk_max, &dsi->user_lp_cinfo);
@@ -4857,24 +4967,14 @@ err:
* the channel in some more dynamic manner, or get the channel as a user
* parameter.
*/
-static enum omap_channel dsi_get_channel(int module_id)
+static enum omap_channel dsi_get_channel(struct dsi_data *dsi)
{
- switch (omapdss_get_version()) {
- case OMAPDSS_VER_OMAP24xx:
- case OMAPDSS_VER_AM43xx:
- DSSWARN("DSI not supported\n");
+ switch (dsi->data->model) {
+ case DSI_MODEL_OMAP3:
return OMAP_DSS_CHANNEL_LCD;
- case OMAPDSS_VER_OMAP34xx_ES1:
- case OMAPDSS_VER_OMAP34xx_ES3:
- case OMAPDSS_VER_OMAP3630:
- case OMAPDSS_VER_AM35xx:
- return OMAP_DSS_CHANNEL_LCD;
-
- case OMAPDSS_VER_OMAP4430_ES1:
- case OMAPDSS_VER_OMAP4430_ES2:
- case OMAPDSS_VER_OMAP4:
- switch (module_id) {
+ case DSI_MODEL_OMAP4:
+ switch (dsi->module_id) {
case 0:
return OMAP_DSS_CHANNEL_LCD;
case 1:
@@ -4884,8 +4984,8 @@ static enum omap_channel dsi_get_channel(int module_id)
return OMAP_DSS_CHANNEL_LCD;
}
- case OMAPDSS_VER_OMAP5:
- switch (module_id) {
+ case DSI_MODEL_OMAP5:
+ switch (dsi->module_id) {
case 0:
return OMAP_DSS_CHANNEL_LCD;
case 1:
@@ -5065,7 +5165,7 @@ static void dsi_init_output(struct platform_device *dsidev)
out->output_type = OMAP_DISPLAY_TYPE_DSI;
out->name = dsi->module_id == 0 ? "dsi.0" : "dsi.1";
- out->dispc_channel = dsi_get_channel(dsi->module_id);
+ out->dispc_channel = dsi_get_channel(dsi);
out->ops.dsi = &dsi_ops;
out->owner = THIS_MODULE;
@@ -5240,29 +5340,7 @@ static int dsi_init_pll_data(struct platform_device *dsidev)
pll->id = dsi->module_id == 0 ? DSS_PLL_DSI1 : DSS_PLL_DSI2;
pll->clkin = clk;
pll->base = dsi->pll_base;
-
- switch (omapdss_get_version()) {
- case OMAPDSS_VER_OMAP34xx_ES1:
- case OMAPDSS_VER_OMAP34xx_ES3:
- case OMAPDSS_VER_OMAP3630:
- case OMAPDSS_VER_AM35xx:
- pll->hw = &dss_omap3_dsi_pll_hw;
- break;
-
- case OMAPDSS_VER_OMAP4430_ES1:
- case OMAPDSS_VER_OMAP4430_ES2:
- case OMAPDSS_VER_OMAP4:
- pll->hw = &dss_omap4_dsi_pll_hw;
- break;
-
- case OMAPDSS_VER_OMAP5:
- pll->hw = &dss_omap5_dsi_pll_hw;
- break;
-
- default:
- return -ENODEV;
- }
-
+ pll->hw = dsi->data->pll_hw;
pll->ops = &dsi_pll_ops;
r = dss_pll_register(pll);
@@ -5273,9 +5351,74 @@ static int dsi_init_pll_data(struct platform_device *dsidev)
}
/* DSI1 HW IP initialisation */
+static const struct dsi_of_data dsi_of_data_omap34xx = {
+ .model = DSI_MODEL_OMAP3,
+ .pll_hw = &dss_omap3_dsi_pll_hw,
+ .modules = (const struct dsi_module_id_data[]) {
+ { .address = 0x4804fc00, .id = 0, },
+ { },
+ },
+ .max_fck_freq = 173000000,
+ .max_pll_lpdiv = (1 << 13) - 1,
+ .quirks = DSI_QUIRK_REVERSE_TXCLKESC,
+};
+
+static const struct dsi_of_data dsi_of_data_omap36xx = {
+ .model = DSI_MODEL_OMAP3,
+ .pll_hw = &dss_omap3_dsi_pll_hw,
+ .modules = (const struct dsi_module_id_data[]) {
+ { .address = 0x4804fc00, .id = 0, },
+ { },
+ },
+ .max_fck_freq = 173000000,
+ .max_pll_lpdiv = (1 << 13) - 1,
+ .quirks = DSI_QUIRK_PLL_PWR_BUG,
+};
+
+static const struct dsi_of_data dsi_of_data_omap4 = {
+ .model = DSI_MODEL_OMAP4,
+ .pll_hw = &dss_omap4_dsi_pll_hw,
+ .modules = (const struct dsi_module_id_data[]) {
+ { .address = 0x58004000, .id = 0, },
+ { .address = 0x58005000, .id = 1, },
+ { },
+ },
+ .max_fck_freq = 170000000,
+ .max_pll_lpdiv = (1 << 13) - 1,
+ .quirks = DSI_QUIRK_DCS_CMD_CONFIG_VC | DSI_QUIRK_VC_OCP_WIDTH
+ | DSI_QUIRK_GNQ,
+};
+
+static const struct dsi_of_data dsi_of_data_omap5 = {
+ .model = DSI_MODEL_OMAP5,
+ .pll_hw = &dss_omap5_dsi_pll_hw,
+ .modules = (const struct dsi_module_id_data[]) {
+ { .address = 0x58004000, .id = 0, },
+ { .address = 0x58009000, .id = 1, },
+ { },
+ },
+ .max_fck_freq = 209250000,
+ .max_pll_lpdiv = (1 << 13) - 1,
+ .quirks = DSI_QUIRK_DCS_CMD_CONFIG_VC | DSI_QUIRK_VC_OCP_WIDTH
+ | DSI_QUIRK_GNQ | DSI_QUIRK_PHY_DCC,
+};
+
+static const struct of_device_id dsi_of_match[] = {
+ { .compatible = "ti,omap3-dsi", .data = &dsi_of_data_omap36xx, },
+ { .compatible = "ti,omap4-dsi", .data = &dsi_of_data_omap4, },
+ { .compatible = "ti,omap5-dsi", .data = &dsi_of_data_omap5, },
+ {},
+};
+
+static const struct soc_device_attribute dsi_soc_devices[] = {
+ { .machine = "OMAP3[45]*", .data = &dsi_of_data_omap34xx },
+ { .machine = "AM35*", .data = &dsi_of_data_omap34xx },
+ { /* sentinel */ }
+};
static int dsi_bind(struct device *dev, struct device *master, void *data)
{
struct platform_device *dsidev = to_platform_device(dev);
+ const struct soc_device_attribute *soc;
const struct dsi_module_id_data *d;
u32 rev;
int r, i;
@@ -5339,7 +5482,13 @@ static int dsi_bind(struct device *dev, struct device *master, void *data)
return r;
}
- d = of_match_node(dsi_of_match, dsidev->dev.of_node)->data;
+ soc = soc_device_match(dsi_soc_devices);
+ if (soc)
+ dsi->data = soc->data;
+ else
+ dsi->data = of_match_node(dsi_of_match, dev->of_node)->data;
+
+ d = dsi->data->modules;
while (d->address != 0 && d->address != dsi_mem->start)
d++;
@@ -5350,6 +5499,24 @@ static int dsi_bind(struct device *dev, struct device *master, void *data)
dsi->module_id = d->id;
+ if (dsi->data->model == DSI_MODEL_OMAP4 ||
+ dsi->data->model == DSI_MODEL_OMAP5) {
+ struct device_node *np;
+
+ /*
+ * The OMAP4/5 display DT bindings don't reference the padconf
+ * syscon. Our only option to retrieve it is to find it by name.
+ */
+ np = of_find_node_by_name(NULL,
+ dsi->data->model == DSI_MODEL_OMAP4 ?
+ "omap4_padconf_global" : "omap5_padconf_global");
+ if (!np)
+ return -ENODEV;
+
+ dsi->syscon = syscon_node_to_regmap(np);
+ of_node_put(np);
+ }
+
/* DSI VCs initialization */
for (i = 0; i < ARRAY_SIZE(dsi->vc); i++) {
dsi->vc[i].source = DSI_VC_SOURCE_L4;
@@ -5375,7 +5542,7 @@ static int dsi_bind(struct device *dev, struct device *master, void *data)
/* DSI on OMAP3 doesn't have register DSI_GNQ, set number
* of data to 3 by default */
- if (dss_has_feature(FEAT_DSI_GNQ))
+ if (dsi->data->quirks & DSI_QUIRK_GNQ)
/* NB_DATA_LANES */
dsi->num_lanes_supported = 1 + REG_GET(dsidev, DSI_GNQ, 11, 9);
else
@@ -5495,30 +5662,6 @@ static const struct dev_pm_ops dsi_pm_ops = {
.runtime_resume = dsi_runtime_resume,
};
-static const struct dsi_module_id_data dsi_of_data_omap3[] = {
- { .address = 0x4804fc00, .id = 0, },
- { },
-};
-
-static const struct dsi_module_id_data dsi_of_data_omap4[] = {
- { .address = 0x58004000, .id = 0, },
- { .address = 0x58005000, .id = 1, },
- { },
-};
-
-static const struct dsi_module_id_data dsi_of_data_omap5[] = {
- { .address = 0x58004000, .id = 0, },
- { .address = 0x58009000, .id = 1, },
- { },
-};
-
-static const struct of_device_id dsi_of_match[] = {
- { .compatible = "ti,omap3-dsi", .data = dsi_of_data_omap3, },
- { .compatible = "ti,omap4-dsi", .data = dsi_of_data_omap4, },
- { .compatible = "ti,omap5-dsi", .data = dsi_of_data_omap5, },
- {},
-};
-
static struct platform_driver omap_dsihw_driver = {
.probe = dsi_probe,
.remove = dsi_remove,
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c
index 99e22ca..d1755f1 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -22,6 +22,7 @@
#define DSS_SUBSYS_NAME "DSS"
+#include <linux/debugfs.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/io.h>
@@ -38,14 +39,15 @@
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/of_graph.h>
#include <linux/regulator/consumer.h>
#include <linux/suspend.h>
#include <linux/component.h>
+#include <linux/sys_soc.h>
#include "omapdss.h"
#include "dss.h"
-#include "dss_features.h"
#define DSS_SZ_REGS SZ_512
@@ -69,15 +71,24 @@ struct dss_reg {
#define REG_FLD_MOD(idx, val, start, end) \
dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end))
+struct dss_ops {
+ int (*dpi_select_source)(int port, enum omap_channel channel);
+ int (*select_lcd_source)(enum omap_channel channel,
+ enum dss_clk_source clk_src);
+};
+
struct dss_features {
+ enum dss_model model;
u8 fck_div_max;
+ unsigned int fck_freq_max;
u8 dss_fck_multiplier;
const char *parent_clk_name;
const enum omap_display_type *ports;
int num_ports;
- int (*dpi_select_source)(int port, enum omap_channel channel);
- int (*select_lcd_source)(enum omap_channel channel,
- enum dss_clk_source clk_src);
+ const enum omap_dss_output_id *outputs;
+ const struct dss_ops *ops;
+ struct dss_reg_field dispc_clk_switch;
+ bool has_lcd_clk_src;
};
static struct {
@@ -139,8 +150,7 @@ static void dss_save_context(void)
SR(CONTROL);
- if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
- OMAP_DISPLAY_TYPE_SDI) {
+ if (dss.feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) {
SR(SDI_CONTROL);
SR(PLL_CONTROL);
}
@@ -159,8 +169,7 @@ static void dss_restore_context(void)
RR(CONTROL);
- if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
- OMAP_DISPLAY_TYPE_SDI) {
+ if (dss.feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) {
RR(SDI_CONTROL);
RR(PLL_CONTROL);
}
@@ -390,8 +399,7 @@ static void dss_dump_regs(struct seq_file *s)
DUMPREG(DSS_SYSSTATUS);
DUMPREG(DSS_CONTROL);
- if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
- OMAP_DISPLAY_TYPE_SDI) {
+ if (dss.feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) {
DUMPREG(DSS_SDI_CONTROL);
DUMPREG(DSS_PLL_CONTROL);
DUMPREG(DSS_SDI_STATUS);
@@ -419,14 +427,12 @@ static int dss_get_channel_index(enum omap_channel channel)
static void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
{
int b;
- u8 start, end;
/*
* We always use PRCM clock as the DISPC func clock, except on DSS3,
* where we don't have separate DISPC and LCD clock sources.
*/
- if (WARN_ON(dss_has_feature(FEAT_LCD_CLK_SRC) &&
- clk_src != DSS_CLK_SRC_FCK))
+ if (WARN_ON(dss.feat->has_lcd_clk_src && clk_src != DSS_CLK_SRC_FCK))
return;
switch (clk_src) {
@@ -444,9 +450,9 @@ static void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
return;
}
- dss_feat_get_reg_field(FEAT_REG_DISPC_CLK_SWITCH, &start, &end);
-
- REG_FLD_MOD(DSS_CONTROL, b, start, end); /* DISPC_CLK_SWITCH */
+ REG_FLD_MOD(DSS_CONTROL, b, /* DISPC_CLK_SWITCH */
+ dss.feat->dispc_clk_switch.start,
+ dss.feat->dispc_clk_switch.end);
dss.dispc_clk_source = clk_src;
}
@@ -570,13 +576,13 @@ void dss_select_lcd_clk_source(enum omap_channel channel,
int idx = dss_get_channel_index(channel);
int r;
- if (!dss_has_feature(FEAT_LCD_CLK_SRC)) {
+ if (!dss.feat->has_lcd_clk_src) {
dss_select_dispc_clk_source(clk_src);
dss.lcd_clk_source[idx] = clk_src;
return;
}
- r = dss.feat->select_lcd_source(channel, clk_src);
+ r = dss.feat->ops->select_lcd_source(channel, clk_src);
if (r)
return;
@@ -595,7 +601,7 @@ enum dss_clk_source dss_get_dsi_clk_source(int dsi_module)
enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
{
- if (dss_has_feature(FEAT_LCD_CLK_SRC)) {
+ if (dss.feat->has_lcd_clk_src) {
int idx = dss_get_channel_index(channel);
return dss.lcd_clk_source[idx];
} else {
@@ -615,7 +621,7 @@ bool dss_div_calc(unsigned long pck, unsigned long fck_min,
unsigned long prate;
unsigned m;
- fck_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
+ fck_hw_max = dss.feat->fck_freq_max;
if (dss.parent_clk == NULL) {
unsigned pckd;
@@ -673,6 +679,16 @@ unsigned long dss_get_dispc_clk_rate(void)
return dss.dss_clk_rate;
}
+unsigned long dss_get_max_fck_rate(void)
+{
+ return dss.feat->fck_freq_max;
+}
+
+enum omap_dss_output_id dss_get_supported_outputs(enum omap_channel channel)
+{
+ return dss.feat->outputs[channel];
+}
+
static int dss_setup_default_clock(void)
{
unsigned long max_dss_fck, prate;
@@ -680,7 +696,7 @@ static int dss_setup_default_clock(void)
unsigned fck_div;
int r;
- max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
+ max_dss_fck = dss.feat->fck_freq_max;
if (dss.parent_clk == NULL) {
fck = clk_round_rate(dss.dss_clk, max_dss_fck);
@@ -721,27 +737,29 @@ void dss_set_dac_pwrdn_bgz(bool enable)
void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select src)
{
- enum omap_display_type dp;
- dp = dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_DIGIT);
+ enum omap_dss_output_id outputs;
+
+ outputs = dss.feat->outputs[OMAP_DSS_CHANNEL_DIGIT];
/* Complain about invalid selections */
- WARN_ON((src == DSS_VENC_TV_CLK) && !(dp & OMAP_DISPLAY_TYPE_VENC));
- WARN_ON((src == DSS_HDMI_M_PCLK) && !(dp & OMAP_DISPLAY_TYPE_HDMI));
+ WARN_ON((src == DSS_VENC_TV_CLK) && !(outputs & OMAP_DSS_OUTPUT_VENC));
+ WARN_ON((src == DSS_HDMI_M_PCLK) && !(outputs & OMAP_DSS_OUTPUT_HDMI));
/* Select only if we have options */
- if ((dp & OMAP_DISPLAY_TYPE_VENC) && (dp & OMAP_DISPLAY_TYPE_HDMI))
+ if ((outputs & OMAP_DSS_OUTPUT_VENC) &&
+ (outputs & OMAP_DSS_OUTPUT_HDMI))
REG_FLD_MOD(DSS_CONTROL, src, 15, 15); /* VENC_HDMI_SWITCH */
}
enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
{
- enum omap_display_type displays;
+ enum omap_dss_output_id outputs;
- displays = dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_DIGIT);
- if ((displays & OMAP_DISPLAY_TYPE_HDMI) == 0)
+ outputs = dss.feat->outputs[OMAP_DSS_CHANNEL_DIGIT];
+ if ((outputs & OMAP_DSS_OUTPUT_HDMI) == 0)
return DSS_VENC_TV_CLK;
- if ((displays & OMAP_DISPLAY_TYPE_VENC) == 0)
+ if ((outputs & OMAP_DSS_OUTPUT_VENC) == 0)
return DSS_HDMI_M_PCLK;
return REG_GET(DSS_CONTROL, 15, 15);
@@ -823,7 +841,7 @@ static int dss_dpi_select_source_dra7xx(int port, enum omap_channel channel)
int dss_dpi_select_source(int port, enum omap_channel channel)
{
- return dss.feat->dpi_select_source(port, channel);
+ return dss.feat->ops->dpi_select_source(port, channel);
}
static int dss_get_clocks(void)
@@ -882,7 +900,7 @@ void dss_runtime_put(void)
/* DEBUGFS */
#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
-void dss_debug_dump_clocks(struct seq_file *s)
+static void dss_debug_dump_clocks(struct seq_file *s)
{
dss_dump_clocks(s);
dispc_dump_clocks(s);
@@ -890,8 +908,88 @@ void dss_debug_dump_clocks(struct seq_file *s)
dsi_dump_clocks(s);
#endif
}
-#endif
+static int dss_debug_show(struct seq_file *s, void *unused)
+{
+ void (*func)(struct seq_file *) = s->private;
+
+ func(s);
+ return 0;
+}
+
+static int dss_debug_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, dss_debug_show, inode->i_private);
+}
+
+static const struct file_operations dss_debug_fops = {
+ .open = dss_debug_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static struct dentry *dss_debugfs_dir;
+
+static int dss_initialize_debugfs(void)
+{
+ dss_debugfs_dir = debugfs_create_dir("omapdss", NULL);
+ if (IS_ERR(dss_debugfs_dir)) {
+ int err = PTR_ERR(dss_debugfs_dir);
+
+ dss_debugfs_dir = NULL;
+ return err;
+ }
+
+ debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir,
+ &dss_debug_dump_clocks, &dss_debug_fops);
+
+ return 0;
+}
+
+static void dss_uninitialize_debugfs(void)
+{
+ if (dss_debugfs_dir)
+ debugfs_remove_recursive(dss_debugfs_dir);
+}
+
+int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *))
+{
+ struct dentry *d;
+
+ d = debugfs_create_file(name, S_IRUGO, dss_debugfs_dir,
+ write, &dss_debug_fops);
+
+ return PTR_ERR_OR_ZERO(d);
+}
+#else /* CONFIG_OMAP2_DSS_DEBUGFS */
+static inline int dss_initialize_debugfs(void)
+{
+ return 0;
+}
+static inline void dss_uninitialize_debugfs(void)
+{
+}
+#endif /* CONFIG_OMAP2_DSS_DEBUGFS */
+
+static const struct dss_ops dss_ops_omap2_omap3 = {
+ .dpi_select_source = &dss_dpi_select_source_omap2_omap3,
+};
+
+static const struct dss_ops dss_ops_omap4 = {
+ .dpi_select_source = &dss_dpi_select_source_omap4,
+ .select_lcd_source = &dss_lcd_clk_mux_omap4,
+};
+
+static const struct dss_ops dss_ops_omap5 = {
+ .dpi_select_source = &dss_dpi_select_source_omap5,
+ .select_lcd_source = &dss_lcd_clk_mux_omap5,
+};
+
+static const struct dss_ops dss_ops_dra7 = {
+ .dpi_select_source = &dss_dpi_select_source_dra7xx,
+ .select_lcd_source = &dss_lcd_clk_mux_dra7,
+};
static const enum omap_display_type omap2plus_ports[] = {
OMAP_DISPLAY_TYPE_DPI,
@@ -908,130 +1006,168 @@ static const enum omap_display_type dra7xx_ports[] = {
OMAP_DISPLAY_TYPE_DPI,
};
+static const enum omap_dss_output_id omap2_dss_supported_outputs[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI,
+
+ /* OMAP_DSS_CHANNEL_DIGIT */
+ OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap3430_dss_supported_outputs[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_SDI | OMAP_DSS_OUTPUT_DSI1,
+
+ /* OMAP_DSS_CHANNEL_DIGIT */
+ OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap3630_dss_supported_outputs[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_DSI1,
+
+ /* OMAP_DSS_CHANNEL_DIGIT */
+ OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id am43xx_dss_supported_outputs[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI,
+};
+
+static const enum omap_dss_output_id omap4_dss_supported_outputs[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DSS_OUTPUT_DBI | OMAP_DSS_OUTPUT_DSI1,
+
+ /* OMAP_DSS_CHANNEL_DIGIT */
+ OMAP_DSS_OUTPUT_VENC | OMAP_DSS_OUTPUT_HDMI,
+
+ /* OMAP_DSS_CHANNEL_LCD2 */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_DSI2,
+};
+
+static const enum omap_dss_output_id omap5_dss_supported_outputs[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_DSI1 | OMAP_DSS_OUTPUT_DSI2,
+
+ /* OMAP_DSS_CHANNEL_DIGIT */
+ OMAP_DSS_OUTPUT_HDMI,
+
+ /* OMAP_DSS_CHANNEL_LCD2 */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_DSI1,
+
+ /* OMAP_DSS_CHANNEL_LCD3 */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_DSI2,
+};
+
static const struct dss_features omap24xx_dss_feats = {
+ .model = DSS_MODEL_OMAP2,
/*
* fck div max is really 16, but the divider range has gaps. The range
* from 1 to 6 has no gaps, so let's use that as a max.
*/
.fck_div_max = 6,
+ .fck_freq_max = 133000000,
.dss_fck_multiplier = 2,
.parent_clk_name = "core_ck",
- .dpi_select_source = &dss_dpi_select_source_omap2_omap3,
.ports = omap2plus_ports,
.num_ports = ARRAY_SIZE(omap2plus_ports),
+ .outputs = omap2_dss_supported_outputs,
+ .ops = &dss_ops_omap2_omap3,
+ .dispc_clk_switch = { 0, 0 },
+ .has_lcd_clk_src = false,
};
static const struct dss_features omap34xx_dss_feats = {
+ .model = DSS_MODEL_OMAP3,
.fck_div_max = 16,
+ .fck_freq_max = 173000000,
.dss_fck_multiplier = 2,
.parent_clk_name = "dpll4_ck",
- .dpi_select_source = &dss_dpi_select_source_omap2_omap3,
.ports = omap34xx_ports,
+ .outputs = omap3430_dss_supported_outputs,
.num_ports = ARRAY_SIZE(omap34xx_ports),
+ .ops = &dss_ops_omap2_omap3,
+ .dispc_clk_switch = { 0, 0 },
+ .has_lcd_clk_src = false,
};
static const struct dss_features omap3630_dss_feats = {
+ .model = DSS_MODEL_OMAP3,
.fck_div_max = 32,
+ .fck_freq_max = 173000000,
.dss_fck_multiplier = 1,
.parent_clk_name = "dpll4_ck",
- .dpi_select_source = &dss_dpi_select_source_omap2_omap3,
.ports = omap2plus_ports,
.num_ports = ARRAY_SIZE(omap2plus_ports),
+ .outputs = omap3630_dss_supported_outputs,
+ .ops = &dss_ops_omap2_omap3,
+ .dispc_clk_switch = { 0, 0 },
+ .has_lcd_clk_src = false,
};
static const struct dss_features omap44xx_dss_feats = {
+ .model = DSS_MODEL_OMAP4,
.fck_div_max = 32,
+ .fck_freq_max = 186000000,
.dss_fck_multiplier = 1,
.parent_clk_name = "dpll_per_x2_ck",
- .dpi_select_source = &dss_dpi_select_source_omap4,
.ports = omap2plus_ports,
.num_ports = ARRAY_SIZE(omap2plus_ports),
- .select_lcd_source = &dss_lcd_clk_mux_omap4,
+ .outputs = omap4_dss_supported_outputs,
+ .ops = &dss_ops_omap4,
+ .dispc_clk_switch = { 9, 8 },
+ .has_lcd_clk_src = true,
};
static const struct dss_features omap54xx_dss_feats = {
+ .model = DSS_MODEL_OMAP5,
.fck_div_max = 64,
+ .fck_freq_max = 209250000,
.dss_fck_multiplier = 1,
.parent_clk_name = "dpll_per_x2_ck",
- .dpi_select_source = &dss_dpi_select_source_omap5,
.ports = omap2plus_ports,
.num_ports = ARRAY_SIZE(omap2plus_ports),
- .select_lcd_source = &dss_lcd_clk_mux_omap5,
+ .outputs = omap5_dss_supported_outputs,
+ .ops = &dss_ops_omap5,
+ .dispc_clk_switch = { 9, 7 },
+ .has_lcd_clk_src = true,
};
static const struct dss_features am43xx_dss_feats = {
+ .model = DSS_MODEL_OMAP3,
.fck_div_max = 0,
+ .fck_freq_max = 200000000,
.dss_fck_multiplier = 0,
.parent_clk_name = NULL,
- .dpi_select_source = &dss_dpi_select_source_omap2_omap3,
.ports = omap2plus_ports,
.num_ports = ARRAY_SIZE(omap2plus_ports),
+ .outputs = am43xx_dss_supported_outputs,
+ .ops = &dss_ops_omap2_omap3,
+ .dispc_clk_switch = { 0, 0 },
+ .has_lcd_clk_src = true,
};
static const struct dss_features dra7xx_dss_feats = {
+ .model = DSS_MODEL_DRA7,
.fck_div_max = 64,
+ .fck_freq_max = 209250000,
.dss_fck_multiplier = 1,
.parent_clk_name = "dpll_per_x2_ck",
- .dpi_select_source = &dss_dpi_select_source_dra7xx,
.ports = dra7xx_ports,
.num_ports = ARRAY_SIZE(dra7xx_ports),
- .select_lcd_source = &dss_lcd_clk_mux_dra7,
+ .outputs = omap5_dss_supported_outputs,
+ .ops = &dss_ops_dra7,
+ .dispc_clk_switch = { 9, 7 },
+ .has_lcd_clk_src = true,
};
-static int dss_init_features(struct platform_device *pdev)
-{
- const struct dss_features *src;
- struct dss_features *dst;
-
- dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL);
- if (!dst) {
- dev_err(&pdev->dev, "Failed to allocate local DSS Features\n");
- return -ENOMEM;
- }
-
- switch (omapdss_get_version()) {
- case OMAPDSS_VER_OMAP24xx:
- src = &omap24xx_dss_feats;
- break;
-
- case OMAPDSS_VER_OMAP34xx_ES1:
- case OMAPDSS_VER_OMAP34xx_ES3:
- case OMAPDSS_VER_AM35xx:
- src = &omap34xx_dss_feats;
- break;
-
- case OMAPDSS_VER_OMAP3630:
- src = &omap3630_dss_feats;
- break;
-
- case OMAPDSS_VER_OMAP4430_ES1:
- case OMAPDSS_VER_OMAP4430_ES2:
- case OMAPDSS_VER_OMAP4:
- src = &omap44xx_dss_feats;
- break;
-
- case OMAPDSS_VER_OMAP5:
- src = &omap54xx_dss_feats;
- break;
-
- case OMAPDSS_VER_AM43xx:
- src = &am43xx_dss_feats;
- break;
-
- case OMAPDSS_VER_DRA7xx:
- src = &dra7xx_dss_feats;
- break;
-
- default:
- return -ENODEV;
- }
-
- memcpy(dst, src, sizeof(*dst));
- dss.feat = dst;
-
- return 0;
-}
-
static int dss_init_ports(struct platform_device *pdev)
{
struct device_node *parent = pdev->dev.of_node;
@@ -1045,7 +1181,7 @@ static int dss_init_ports(struct platform_device *pdev)
switch (dss.feat->ports[i]) {
case OMAP_DISPLAY_TYPE_DPI:
- dpi_init_port(pdev, port);
+ dpi_init_port(pdev, port, dss.feat->model);
break;
case OMAP_DISPLAY_TYPE_SDI:
sdi_init_port(pdev, port);
@@ -1144,6 +1280,23 @@ static int dss_video_pll_probe(struct platform_device *pdev)
}
/* DSS HW IP initialisation */
+static const struct of_device_id dss_of_match[] = {
+ { .compatible = "ti,omap2-dss", .data = &omap24xx_dss_feats },
+ { .compatible = "ti,omap3-dss", .data = &omap3630_dss_feats },
+ { .compatible = "ti,omap4-dss", .data = &omap44xx_dss_feats },
+ { .compatible = "ti,omap5-dss", .data = &omap54xx_dss_feats },
+ { .compatible = "ti,dra7-dss", .data = &dra7xx_dss_feats },
+ {},
+};
+MODULE_DEVICE_TABLE(of, dss_of_match);
+
+static const struct soc_device_attribute dss_soc_devices[] = {
+ { .machine = "OMAP3430/3530", .data = &omap34xx_dss_feats },
+ { .machine = "AM35??", .data = &omap34xx_dss_feats },
+ { .family = "AM43xx", .data = &am43xx_dss_feats },
+ { /* sentinel */ }
+};
+
static int dss_bind(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -1151,12 +1304,6 @@ static int dss_bind(struct device *dev)
u32 rev;
int r;
- dss.pdev = pdev;
-
- r = dss_init_features(dss.pdev);
- if (r)
- return r;
-
dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
dss.base = devm_ioremap_resource(&pdev->dev, dss_mem);
if (IS_ERR(dss.base))
@@ -1288,15 +1435,34 @@ static int dss_add_child_component(struct device *dev, void *data)
static int dss_probe(struct platform_device *pdev)
{
+ const struct soc_device_attribute *soc;
struct component_match *match = NULL;
int r;
+ dss.pdev = pdev;
+
+ /*
+ * The various OMAP3-based SoCs can't be told apart using the compatible
+ * string, use SoC device matching.
+ */
+ soc = soc_device_match(dss_soc_devices);
+ if (soc)
+ dss.feat = soc->data;
+ else
+ dss.feat = of_match_device(dss_of_match, &pdev->dev)->data;
+
+ r = dss_initialize_debugfs();
+ if (r)
+ return r;
+
/* add all the child devices as components */
device_for_each_child(&pdev->dev, &match, dss_add_child_component);
r = component_master_add_with_match(&pdev->dev, &dss_component_ops, match);
- if (r)
+ if (r) {
+ dss_uninitialize_debugfs();
return r;
+ }
return 0;
}
@@ -1304,9 +1470,27 @@ static int dss_probe(struct platform_device *pdev)
static int dss_remove(struct platform_device *pdev)
{
component_master_del(&pdev->dev, &dss_component_ops);
+
+ dss_uninitialize_debugfs();
+
return 0;
}
+static void dss_shutdown(struct platform_device *pdev)
+{
+ struct omap_dss_device *dssdev = NULL;
+
+ DSSDBG("shutdown\n");
+
+ for_each_dss_dev(dssdev) {
+ if (!dssdev->driver)
+ continue;
+
+ if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
+ dssdev->driver->disable(dssdev);
+ }
+}
+
static int dss_runtime_suspend(struct device *dev)
{
dss_save_context();
@@ -1343,20 +1527,10 @@ static const struct dev_pm_ops dss_pm_ops = {
.runtime_resume = dss_runtime_resume,
};
-static const struct of_device_id dss_of_match[] = {
- { .compatible = "ti,omap2-dss", },
- { .compatible = "ti,omap3-dss", },
- { .compatible = "ti,omap4-dss", },
- { .compatible = "ti,omap5-dss", },
- { .compatible = "ti,dra7-dss", },
- {},
-};
-
-MODULE_DEVICE_TABLE(of, dss_of_match);
-
static struct platform_driver omap_dsshw_driver = {
.probe = dss_probe,
.remove = dss_remove,
+ .shutdown = dss_shutdown,
.driver = {
.name = "omapdss_dss",
.pm = &dss_pm_ops,
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h b/drivers/gpu/drm/omapdrm/dss/dss.h
index 8dbf35f..ed46557 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.h
+++ b/drivers/gpu/drm/omapdrm/dss/dss.h
@@ -27,6 +27,9 @@
#include "omapdss.h"
+#define MAX_DSS_LCD_MANAGERS 3
+#define MAX_NUM_DSI 2
+
#ifdef pr_fmt
#undef pr_fmt
#endif
@@ -72,6 +75,14 @@
#define FLD_MOD(orig, val, start, end) \
(((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))
+enum dss_model {
+ DSS_MODEL_OMAP2,
+ DSS_MODEL_OMAP3,
+ DSS_MODEL_OMAP4,
+ DSS_MODEL_OMAP5,
+ DSS_MODEL_DRA7,
+};
+
enum dss_io_pad_mode {
DSS_IO_PAD_MODE_RESET,
DSS_IO_PAD_MODE_RFBI,
@@ -174,6 +185,9 @@ struct dss_pll_hw {
bool has_freqsel;
bool has_selfreqdco;
bool has_refsel;
+
+ /* DRA7 errata i886: use high N & M to avoid jitter */
+ bool errata_i886;
};
struct dss_pll {
@@ -192,6 +206,11 @@ struct dss_pll {
struct dss_pll_clock_info cinfo;
};
+/* Defines a generic omap register field */
+struct dss_reg_field {
+ u8 start, end;
+};
+
struct dispc_clock_info {
/* rates that we get with dividers below */
unsigned long lck;
@@ -219,10 +238,11 @@ struct seq_file;
struct platform_device;
/* core */
-int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask);
-void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask);
-int dss_set_min_bus_tput(struct device *dev, unsigned long tput);
-int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *));
+static inline int dss_set_min_bus_tput(struct device *dev, unsigned long tput)
+{
+ /* To be implemented when the OMAP platform will provide this feature */
+ return 0;
+}
static inline bool dss_mgr_is_lcd(enum omap_channel id)
{
@@ -234,6 +254,16 @@ static inline bool dss_mgr_is_lcd(enum omap_channel id)
}
/* DSS */
+#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
+int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *));
+#else
+static inline int dss_debugfs_create_file(const char *name,
+ void (*write)(struct seq_file *))
+{
+ return 0;
+}
+#endif /* CONFIG_OMAP2_DSS_DEBUGFS */
+
int dss_init_platform_driver(void) __init;
void dss_uninit_platform_driver(void);
@@ -241,6 +271,8 @@ int dss_runtime_get(void);
void dss_runtime_put(void);
unsigned long dss_get_dispc_clk_rate(void);
+unsigned long dss_get_max_fck_rate(void);
+enum omap_dss_output_id dss_get_supported_outputs(enum omap_channel channel);
int dss_dpi_select_source(int port, enum omap_channel channel);
void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);
@@ -252,10 +284,6 @@ struct dss_pll *dss_video_pll_init(struct platform_device *pdev, int id,
struct regulator *regulator);
void dss_video_pll_uninit(struct dss_pll *pll);
-#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
-void dss_debug_dump_clocks(struct seq_file *s);
-#endif
-
void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable);
void dss_sdi_init(int datapairs);
@@ -312,11 +340,12 @@ void dsi_irq_handler(void);
/* DPI */
#ifdef CONFIG_OMAP2_DSS_DPI
-int dpi_init_port(struct platform_device *pdev, struct device_node *port);
+int dpi_init_port(struct platform_device *pdev, struct device_node *port,
+ enum dss_model dss_model);
void dpi_uninit_port(struct device_node *port);
#else
static inline int dpi_init_port(struct platform_device *pdev,
- struct device_node *port)
+ struct device_node *port, enum dss_model dss_model)
{
return 0;
}
diff --git a/drivers/gpu/drm/omapdrm/dss/dss_features.c b/drivers/gpu/drm/omapdrm/dss/dss_features.c
deleted file mode 100644
index 0e59971..0000000
--- a/drivers/gpu/drm/omapdrm/dss/dss_features.c
+++ /dev/null
@@ -1,905 +0,0 @@
-/*
- * linux/drivers/video/omap2/dss/dss_features.c
- *
- * Copyright (C) 2010 Texas Instruments
- * Author: Archit Taneja <archit@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License 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.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-#include <drm/drm_fourcc.h>
-
-#include "omapdss.h"
-#include "dss.h"
-#include "dss_features.h"
-
-/* Defines a generic omap register field */
-struct dss_reg_field {
- u8 start, end;
-};
-
-struct dss_param_range {
- int min, max;
-};
-
-struct omap_dss_features {
- const struct dss_reg_field *reg_fields;
- const int num_reg_fields;
-
- const enum dss_feat_id *features;
- const int num_features;
-
- const int num_mgrs;
- const int num_ovls;
- const enum omap_display_type *supported_displays;
- const enum omap_dss_output_id *supported_outputs;
- const u32 **supported_color_modes;
- const enum omap_overlay_caps *overlay_caps;
- const struct dss_param_range *dss_params;
-
- const u32 buffer_size_unit;
- const u32 burst_size_unit;
-};
-
-/* This struct is assigned to one of the below during initialization */
-static const struct omap_dss_features *omap_current_dss_features;
-
-static const struct dss_reg_field omap2_dss_reg_fields[] = {
- [FEAT_REG_FIRHINC] = { 11, 0 },
- [FEAT_REG_FIRVINC] = { 27, 16 },
- [FEAT_REG_FIFOLOWTHRESHOLD] = { 8, 0 },
- [FEAT_REG_FIFOHIGHTHRESHOLD] = { 24, 16 },
- [FEAT_REG_FIFOSIZE] = { 8, 0 },
- [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
- [FEAT_REG_VERTICALACCU] = { 25, 16 },
- [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
-};
-
-static const struct dss_reg_field omap3_dss_reg_fields[] = {
- [FEAT_REG_FIRHINC] = { 12, 0 },
- [FEAT_REG_FIRVINC] = { 28, 16 },
- [FEAT_REG_FIFOLOWTHRESHOLD] = { 11, 0 },
- [FEAT_REG_FIFOHIGHTHRESHOLD] = { 27, 16 },
- [FEAT_REG_FIFOSIZE] = { 10, 0 },
- [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
- [FEAT_REG_VERTICALACCU] = { 25, 16 },
- [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
-};
-
-static const struct dss_reg_field am43xx_dss_reg_fields[] = {
- [FEAT_REG_FIRHINC] = { 12, 0 },
- [FEAT_REG_FIRVINC] = { 28, 16 },
- [FEAT_REG_FIFOLOWTHRESHOLD] = { 11, 0 },
- [FEAT_REG_FIFOHIGHTHRESHOLD] = { 27, 16 },
- [FEAT_REG_FIFOSIZE] = { 10, 0 },
- [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
- [FEAT_REG_VERTICALACCU] = { 25, 16 },
- [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
-};
-
-static const struct dss_reg_field omap4_dss_reg_fields[] = {
- [FEAT_REG_FIRHINC] = { 12, 0 },
- [FEAT_REG_FIRVINC] = { 28, 16 },
- [FEAT_REG_FIFOLOWTHRESHOLD] = { 15, 0 },
- [FEAT_REG_FIFOHIGHTHRESHOLD] = { 31, 16 },
- [FEAT_REG_FIFOSIZE] = { 15, 0 },
- [FEAT_REG_HORIZONTALACCU] = { 10, 0 },
- [FEAT_REG_VERTICALACCU] = { 26, 16 },
- [FEAT_REG_DISPC_CLK_SWITCH] = { 9, 8 },
-};
-
-static const struct dss_reg_field omap5_dss_reg_fields[] = {
- [FEAT_REG_FIRHINC] = { 12, 0 },
- [FEAT_REG_FIRVINC] = { 28, 16 },
- [FEAT_REG_FIFOLOWTHRESHOLD] = { 15, 0 },
- [FEAT_REG_FIFOHIGHTHRESHOLD] = { 31, 16 },
- [FEAT_REG_FIFOSIZE] = { 15, 0 },
- [FEAT_REG_HORIZONTALACCU] = { 10, 0 },
- [FEAT_REG_VERTICALACCU] = { 26, 16 },
- [FEAT_REG_DISPC_CLK_SWITCH] = { 9, 7 },
-};
-
-static const enum omap_display_type omap2_dss_supported_displays[] = {
- /* OMAP_DSS_CHANNEL_LCD */
- OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI,
-
- /* OMAP_DSS_CHANNEL_DIGIT */
- OMAP_DISPLAY_TYPE_VENC,
-};
-
-static const enum omap_display_type omap3430_dss_supported_displays[] = {
- /* OMAP_DSS_CHANNEL_LCD */
- OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
- OMAP_DISPLAY_TYPE_SDI | OMAP_DISPLAY_TYPE_DSI,
-
- /* OMAP_DSS_CHANNEL_DIGIT */
- OMAP_DISPLAY_TYPE_VENC,
-};
-
-static const enum omap_display_type omap3630_dss_supported_displays[] = {
- /* OMAP_DSS_CHANNEL_LCD */
- OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
- OMAP_DISPLAY_TYPE_DSI,
-
- /* OMAP_DSS_CHANNEL_DIGIT */
- OMAP_DISPLAY_TYPE_VENC,
-};
-
-static const enum omap_display_type am43xx_dss_supported_displays[] = {
- /* OMAP_DSS_CHANNEL_LCD */
- OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI,
-};
-
-static const enum omap_display_type omap4_dss_supported_displays[] = {
- /* OMAP_DSS_CHANNEL_LCD */
- OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI,
-
- /* OMAP_DSS_CHANNEL_DIGIT */
- OMAP_DISPLAY_TYPE_VENC | OMAP_DISPLAY_TYPE_HDMI,
-
- /* OMAP_DSS_CHANNEL_LCD2 */
- OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
- OMAP_DISPLAY_TYPE_DSI,
-};
-
-static const enum omap_display_type omap5_dss_supported_displays[] = {
- /* OMAP_DSS_CHANNEL_LCD */
- OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
- OMAP_DISPLAY_TYPE_DSI,
-
- /* OMAP_DSS_CHANNEL_DIGIT */
- OMAP_DISPLAY_TYPE_HDMI | OMAP_DISPLAY_TYPE_DPI,
-
- /* OMAP_DSS_CHANNEL_LCD2 */
- OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
- OMAP_DISPLAY_TYPE_DSI,
-};
-
-static const enum omap_dss_output_id omap2_dss_supported_outputs[] = {
- /* OMAP_DSS_CHANNEL_LCD */
- OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI,
-
- /* OMAP_DSS_CHANNEL_DIGIT */
- OMAP_DSS_OUTPUT_VENC,
-};
-
-static const enum omap_dss_output_id omap3430_dss_supported_outputs[] = {
- /* OMAP_DSS_CHANNEL_LCD */
- OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
- OMAP_DSS_OUTPUT_SDI | OMAP_DSS_OUTPUT_DSI1,
-
- /* OMAP_DSS_CHANNEL_DIGIT */
- OMAP_DSS_OUTPUT_VENC,
-};
-
-static const enum omap_dss_output_id omap3630_dss_supported_outputs[] = {
- /* OMAP_DSS_CHANNEL_LCD */
- OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
- OMAP_DSS_OUTPUT_DSI1,
-
- /* OMAP_DSS_CHANNEL_DIGIT */
- OMAP_DSS_OUTPUT_VENC,
-};
-
-static const enum omap_dss_output_id am43xx_dss_supported_outputs[] = {
- /* OMAP_DSS_CHANNEL_LCD */
- OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI,
-};
-
-static const enum omap_dss_output_id omap4_dss_supported_outputs[] = {
- /* OMAP_DSS_CHANNEL_LCD */
- OMAP_DSS_OUTPUT_DBI | OMAP_DSS_OUTPUT_DSI1,
-
- /* OMAP_DSS_CHANNEL_DIGIT */
- OMAP_DSS_OUTPUT_VENC | OMAP_DSS_OUTPUT_HDMI,
-
- /* OMAP_DSS_CHANNEL_LCD2 */
- OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
- OMAP_DSS_OUTPUT_DSI2,
-};
-
-static const enum omap_dss_output_id omap5_dss_supported_outputs[] = {
- /* OMAP_DSS_CHANNEL_LCD */
- OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
- OMAP_DSS_OUTPUT_DSI1 | OMAP_DSS_OUTPUT_DSI2,
-
- /* OMAP_DSS_CHANNEL_DIGIT */
- OMAP_DSS_OUTPUT_HDMI,
-
- /* OMAP_DSS_CHANNEL_LCD2 */
- OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
- OMAP_DSS_OUTPUT_DSI1,
-
- /* OMAP_DSS_CHANNEL_LCD3 */
- OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
- OMAP_DSS_OUTPUT_DSI2,
-};
-
-#define COLOR_ARRAY(arr...) (const u32[]) { arr, 0 }
-
-static const u32 *omap2_dss_supported_color_modes[] = {
-
- /* OMAP_DSS_GFX */
- COLOR_ARRAY(
- DRM_FORMAT_RGBX4444, DRM_FORMAT_RGB565,
- DRM_FORMAT_XRGB8888, DRM_FORMAT_RGB888),
-
- /* OMAP_DSS_VIDEO1 */
- COLOR_ARRAY(
- DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888,
- DRM_FORMAT_RGB888, DRM_FORMAT_YUYV,
- DRM_FORMAT_UYVY),
-
- /* OMAP_DSS_VIDEO2 */
- COLOR_ARRAY(
- DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888,
- DRM_FORMAT_RGB888, DRM_FORMAT_YUYV,
- DRM_FORMAT_UYVY),
-};
-
-static const u32 *omap3_dss_supported_color_modes[] = {
- /* OMAP_DSS_GFX */
- COLOR_ARRAY(
- DRM_FORMAT_RGBX4444, DRM_FORMAT_ARGB4444,
- DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888,
- DRM_FORMAT_RGB888, DRM_FORMAT_ARGB8888,
- DRM_FORMAT_RGBA8888, DRM_FORMAT_RGBX8888),
-
- /* OMAP_DSS_VIDEO1 */
- COLOR_ARRAY(
- DRM_FORMAT_XRGB8888, DRM_FORMAT_RGB888,
- DRM_FORMAT_RGBX4444, DRM_FORMAT_RGB565,
- DRM_FORMAT_YUYV, DRM_FORMAT_UYVY),
-
- /* OMAP_DSS_VIDEO2 */
- COLOR_ARRAY(
- DRM_FORMAT_RGBX4444, DRM_FORMAT_ARGB4444,
- DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888,
- DRM_FORMAT_RGB888, DRM_FORMAT_YUYV,
- DRM_FORMAT_UYVY, DRM_FORMAT_ARGB8888,
- DRM_FORMAT_RGBA8888, DRM_FORMAT_RGBX8888),
-};
-
-static const u32 *omap4_dss_supported_color_modes[] = {
- /* OMAP_DSS_GFX */
- COLOR_ARRAY(
- DRM_FORMAT_RGBX4444, DRM_FORMAT_ARGB4444,
- DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888,
- DRM_FORMAT_RGB888, DRM_FORMAT_ARGB8888,
- DRM_FORMAT_RGBA8888, DRM_FORMAT_RGBX8888,
- DRM_FORMAT_ARGB1555, DRM_FORMAT_XRGB4444,
- DRM_FORMAT_RGBA4444, DRM_FORMAT_XRGB1555),
-
- /* OMAP_DSS_VIDEO1 */
- COLOR_ARRAY(
- DRM_FORMAT_RGB565, DRM_FORMAT_RGBX4444,
- DRM_FORMAT_YUYV, DRM_FORMAT_ARGB1555,
- DRM_FORMAT_RGBA8888, DRM_FORMAT_NV12,
- DRM_FORMAT_RGBA4444, DRM_FORMAT_XRGB8888,
- DRM_FORMAT_RGB888, DRM_FORMAT_UYVY,
- DRM_FORMAT_ARGB4444, DRM_FORMAT_XRGB1555,
- DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB4444,
- DRM_FORMAT_RGBX8888),
-
- /* OMAP_DSS_VIDEO2 */
- COLOR_ARRAY(
- DRM_FORMAT_RGB565, DRM_FORMAT_RGBX4444,
- DRM_FORMAT_YUYV, DRM_FORMAT_ARGB1555,
- DRM_FORMAT_RGBA8888, DRM_FORMAT_NV12,
- DRM_FORMAT_RGBA4444, DRM_FORMAT_XRGB8888,
- DRM_FORMAT_RGB888, DRM_FORMAT_UYVY,
- DRM_FORMAT_ARGB4444, DRM_FORMAT_XRGB1555,
- DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB4444,
- DRM_FORMAT_RGBX8888),
-
- /* OMAP_DSS_VIDEO3 */
- COLOR_ARRAY(
- DRM_FORMAT_RGB565, DRM_FORMAT_RGBX4444,
- DRM_FORMAT_YUYV, DRM_FORMAT_ARGB1555,
- DRM_FORMAT_RGBA8888, DRM_FORMAT_NV12,
- DRM_FORMAT_RGBA4444, DRM_FORMAT_XRGB8888,
- DRM_FORMAT_RGB888, DRM_FORMAT_UYVY,
- DRM_FORMAT_ARGB4444, DRM_FORMAT_XRGB1555,
- DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB4444,
- DRM_FORMAT_RGBX8888),
-
- /* OMAP_DSS_WB */
- COLOR_ARRAY(
- DRM_FORMAT_RGB565, DRM_FORMAT_RGBX4444,
- DRM_FORMAT_YUYV, DRM_FORMAT_ARGB1555,
- DRM_FORMAT_RGBA8888, DRM_FORMAT_NV12,
- DRM_FORMAT_RGBA4444, DRM_FORMAT_XRGB8888,
- DRM_FORMAT_RGB888, DRM_FORMAT_UYVY,
- DRM_FORMAT_ARGB4444, DRM_FORMAT_XRGB1555,
- DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB4444,
- DRM_FORMAT_RGBX8888),
-};
-
-static const enum omap_overlay_caps omap2_dss_overlay_caps[] = {
- /* OMAP_DSS_GFX */
- OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
-
- /* OMAP_DSS_VIDEO1 */
- OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
- OMAP_DSS_OVL_CAP_REPLICATION,
-
- /* OMAP_DSS_VIDEO2 */
- OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
- OMAP_DSS_OVL_CAP_REPLICATION,
-};
-
-static const enum omap_overlay_caps omap3430_dss_overlay_caps[] = {
- /* OMAP_DSS_GFX */
- OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_POS |
- OMAP_DSS_OVL_CAP_REPLICATION,
-
- /* OMAP_DSS_VIDEO1 */
- OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
- OMAP_DSS_OVL_CAP_REPLICATION,
-
- /* OMAP_DSS_VIDEO2 */
- OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
- OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
-};
-
-static const enum omap_overlay_caps omap3630_dss_overlay_caps[] = {
- /* OMAP_DSS_GFX */
- OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA |
- OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
-
- /* OMAP_DSS_VIDEO1 */
- OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
- OMAP_DSS_OVL_CAP_REPLICATION,
-
- /* OMAP_DSS_VIDEO2 */
- OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
- OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_POS |
- OMAP_DSS_OVL_CAP_REPLICATION,
-};
-
-static const enum omap_overlay_caps omap4_dss_overlay_caps[] = {
- /* OMAP_DSS_GFX */
- OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA |
- OMAP_DSS_OVL_CAP_ZORDER | OMAP_DSS_OVL_CAP_POS |
- OMAP_DSS_OVL_CAP_REPLICATION,
-
- /* OMAP_DSS_VIDEO1 */
- OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
- OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
- OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
-
- /* OMAP_DSS_VIDEO2 */
- OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
- OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
- OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
-
- /* OMAP_DSS_VIDEO3 */
- OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
- OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
- OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
-};
-
-static const struct dss_param_range omap2_dss_param_range[] = {
- [FEAT_PARAM_DSS_FCK] = { 0, 133000000 },
- [FEAT_PARAM_DSS_PCD] = { 2, 255 },
- [FEAT_PARAM_DOWNSCALE] = { 1, 2 },
- /*
- * Assuming the line width buffer to be 768 pixels as OMAP2 DISPC
- * scaler cannot scale a image with width more than 768.
- */
- [FEAT_PARAM_LINEWIDTH] = { 1, 768 },
-};
-
-static const struct dss_param_range omap3_dss_param_range[] = {
- [FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
- [FEAT_PARAM_DSS_PCD] = { 1, 255 },
- [FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1},
- [FEAT_PARAM_DSI_FCK] = { 0, 173000000 },
- [FEAT_PARAM_DOWNSCALE] = { 1, 4 },
- [FEAT_PARAM_LINEWIDTH] = { 1, 1024 },
-};
-
-static const struct dss_param_range am43xx_dss_param_range[] = {
- [FEAT_PARAM_DSS_FCK] = { 0, 200000000 },
- [FEAT_PARAM_DSS_PCD] = { 1, 255 },
- [FEAT_PARAM_DOWNSCALE] = { 1, 4 },
- [FEAT_PARAM_LINEWIDTH] = { 1, 1024 },
-};
-
-static const struct dss_param_range omap4_dss_param_range[] = {
- [FEAT_PARAM_DSS_FCK] = { 0, 186000000 },
- [FEAT_PARAM_DSS_PCD] = { 1, 255 },
- [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
- [FEAT_PARAM_DSI_FCK] = { 0, 170000000 },
- [FEAT_PARAM_DOWNSCALE] = { 1, 4 },
- [FEAT_PARAM_LINEWIDTH] = { 1, 2048 },
-};
-
-static const struct dss_param_range omap5_dss_param_range[] = {
- [FEAT_PARAM_DSS_FCK] = { 0, 209250000 },
- [FEAT_PARAM_DSS_PCD] = { 1, 255 },
- [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
- [FEAT_PARAM_DSI_FCK] = { 0, 209250000 },
- [FEAT_PARAM_DOWNSCALE] = { 1, 4 },
- [FEAT_PARAM_LINEWIDTH] = { 1, 2048 },
-};
-
-static const enum dss_feat_id omap2_dss_feat_list[] = {
- FEAT_LCDENABLEPOL,
- FEAT_LCDENABLESIGNAL,
- FEAT_PCKFREEENABLE,
- FEAT_FUNCGATED,
- FEAT_ROWREPEATENABLE,
- FEAT_RESIZECONF,
-};
-
-static const enum dss_feat_id omap3430_dss_feat_list[] = {
- FEAT_LCDENABLEPOL,
- FEAT_LCDENABLESIGNAL,
- FEAT_PCKFREEENABLE,
- FEAT_FUNCGATED,
- FEAT_LINEBUFFERSPLIT,
- FEAT_ROWREPEATENABLE,
- FEAT_RESIZECONF,
- FEAT_DSI_REVERSE_TXCLKESC,
- FEAT_VENC_REQUIRES_TV_DAC_CLK,
- FEAT_CPR,
- FEAT_PRELOAD,
- FEAT_FIR_COEF_V,
- FEAT_ALPHA_FIXED_ZORDER,
- FEAT_FIFO_MERGE,
- FEAT_OMAP3_DSI_FIFO_BUG,
- FEAT_DPI_USES_VDDS_DSI,
-};
-
-static const enum dss_feat_id am35xx_dss_feat_list[] = {
- FEAT_LCDENABLEPOL,
- FEAT_LCDENABLESIGNAL,
- FEAT_PCKFREEENABLE,
- FEAT_FUNCGATED,
- FEAT_LINEBUFFERSPLIT,
- FEAT_ROWREPEATENABLE,
- FEAT_RESIZECONF,
- FEAT_DSI_REVERSE_TXCLKESC,
- FEAT_VENC_REQUIRES_TV_DAC_CLK,
- FEAT_CPR,
- FEAT_PRELOAD,
- FEAT_FIR_COEF_V,
- FEAT_ALPHA_FIXED_ZORDER,
- FEAT_FIFO_MERGE,
- FEAT_OMAP3_DSI_FIFO_BUG,
-};
-
-static const enum dss_feat_id am43xx_dss_feat_list[] = {
- FEAT_LCDENABLEPOL,
- FEAT_LCDENABLESIGNAL,
- FEAT_PCKFREEENABLE,
- FEAT_FUNCGATED,
- FEAT_LINEBUFFERSPLIT,
- FEAT_ROWREPEATENABLE,
- FEAT_RESIZECONF,
- FEAT_CPR,
- FEAT_PRELOAD,
- FEAT_FIR_COEF_V,
- FEAT_ALPHA_FIXED_ZORDER,
- FEAT_FIFO_MERGE,
-};
-
-static const enum dss_feat_id omap3630_dss_feat_list[] = {
- FEAT_LCDENABLEPOL,
- FEAT_LCDENABLESIGNAL,
- FEAT_PCKFREEENABLE,
- FEAT_FUNCGATED,
- FEAT_LINEBUFFERSPLIT,
- FEAT_ROWREPEATENABLE,
- FEAT_RESIZECONF,
- FEAT_DSI_PLL_PWR_BUG,
- FEAT_CPR,
- FEAT_PRELOAD,
- FEAT_FIR_COEF_V,
- FEAT_ALPHA_FIXED_ZORDER,
- FEAT_FIFO_MERGE,
- FEAT_OMAP3_DSI_FIFO_BUG,
- FEAT_DPI_USES_VDDS_DSI,
-};
-
-static const enum dss_feat_id omap4430_es1_0_dss_feat_list[] = {
- FEAT_MGR_LCD2,
- FEAT_CORE_CLK_DIV,
- FEAT_LCD_CLK_SRC,
- FEAT_DSI_DCS_CMD_CONFIG_VC,
- FEAT_DSI_VC_OCP_WIDTH,
- FEAT_DSI_GNQ,
- FEAT_HANDLE_UV_SEPARATE,
- FEAT_ATTR2,
- FEAT_CPR,
- FEAT_PRELOAD,
- FEAT_FIR_COEF_V,
- FEAT_ALPHA_FREE_ZORDER,
- FEAT_FIFO_MERGE,
- FEAT_BURST_2D,
-};
-
-static const enum dss_feat_id omap4430_es2_0_1_2_dss_feat_list[] = {
- FEAT_MGR_LCD2,
- FEAT_CORE_CLK_DIV,
- FEAT_LCD_CLK_SRC,
- FEAT_DSI_DCS_CMD_CONFIG_VC,
- FEAT_DSI_VC_OCP_WIDTH,
- FEAT_DSI_GNQ,
- FEAT_HDMI_CTS_SWMODE,
- FEAT_HANDLE_UV_SEPARATE,
- FEAT_ATTR2,
- FEAT_CPR,
- FEAT_PRELOAD,
- FEAT_FIR_COEF_V,
- FEAT_ALPHA_FREE_ZORDER,
- FEAT_FIFO_MERGE,
- FEAT_BURST_2D,
-};
-
-static const enum dss_feat_id omap4_dss_feat_list[] = {
- FEAT_MGR_LCD2,
- FEAT_CORE_CLK_DIV,
- FEAT_LCD_CLK_SRC,
- FEAT_DSI_DCS_CMD_CONFIG_VC,
- FEAT_DSI_VC_OCP_WIDTH,
- FEAT_DSI_GNQ,
- FEAT_HDMI_CTS_SWMODE,
- FEAT_HDMI_AUDIO_USE_MCLK,
- FEAT_HANDLE_UV_SEPARATE,
- FEAT_ATTR2,
- FEAT_CPR,
- FEAT_PRELOAD,
- FEAT_FIR_COEF_V,
- FEAT_ALPHA_FREE_ZORDER,
- FEAT_FIFO_MERGE,
- FEAT_BURST_2D,
-};
-
-static const enum dss_feat_id omap5_dss_feat_list[] = {
- FEAT_MGR_LCD2,
- FEAT_MGR_LCD3,
- FEAT_CORE_CLK_DIV,
- FEAT_LCD_CLK_SRC,
- FEAT_DSI_DCS_CMD_CONFIG_VC,
- FEAT_DSI_VC_OCP_WIDTH,
- FEAT_DSI_GNQ,
- FEAT_HDMI_CTS_SWMODE,
- FEAT_HDMI_AUDIO_USE_MCLK,
- FEAT_HANDLE_UV_SEPARATE,
- FEAT_ATTR2,
- FEAT_CPR,
- FEAT_PRELOAD,
- FEAT_FIR_COEF_V,
- FEAT_ALPHA_FREE_ZORDER,
- FEAT_FIFO_MERGE,
- FEAT_BURST_2D,
- FEAT_DSI_PHY_DCC,
- FEAT_MFLAG,
-};
-
-/* OMAP2 DSS Features */
-static const struct omap_dss_features omap2_dss_features = {
- .reg_fields = omap2_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(omap2_dss_reg_fields),
-
- .features = omap2_dss_feat_list,
- .num_features = ARRAY_SIZE(omap2_dss_feat_list),
-
- .num_mgrs = 2,
- .num_ovls = 3,
- .supported_displays = omap2_dss_supported_displays,
- .supported_outputs = omap2_dss_supported_outputs,
- .supported_color_modes = omap2_dss_supported_color_modes,
- .overlay_caps = omap2_dss_overlay_caps,
- .dss_params = omap2_dss_param_range,
- .buffer_size_unit = 1,
- .burst_size_unit = 8,
-};
-
-/* OMAP3 DSS Features */
-static const struct omap_dss_features omap3430_dss_features = {
- .reg_fields = omap3_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
-
- .features = omap3430_dss_feat_list,
- .num_features = ARRAY_SIZE(omap3430_dss_feat_list),
-
- .num_mgrs = 2,
- .num_ovls = 3,
- .supported_displays = omap3430_dss_supported_displays,
- .supported_outputs = omap3430_dss_supported_outputs,
- .supported_color_modes = omap3_dss_supported_color_modes,
- .overlay_caps = omap3430_dss_overlay_caps,
- .dss_params = omap3_dss_param_range,
- .buffer_size_unit = 1,
- .burst_size_unit = 8,
-};
-
-/*
- * AM35xx DSS Features. This is basically OMAP3 DSS Features without the
- * vdds_dsi regulator.
- */
-static const struct omap_dss_features am35xx_dss_features = {
- .reg_fields = omap3_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
-
- .features = am35xx_dss_feat_list,
- .num_features = ARRAY_SIZE(am35xx_dss_feat_list),
-
- .num_mgrs = 2,
- .num_ovls = 3,
- .supported_displays = omap3430_dss_supported_displays,
- .supported_outputs = omap3430_dss_supported_outputs,
- .supported_color_modes = omap3_dss_supported_color_modes,
- .overlay_caps = omap3430_dss_overlay_caps,
- .dss_params = omap3_dss_param_range,
- .buffer_size_unit = 1,
- .burst_size_unit = 8,
-};
-
-static const struct omap_dss_features am43xx_dss_features = {
- .reg_fields = am43xx_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(am43xx_dss_reg_fields),
-
- .features = am43xx_dss_feat_list,
- .num_features = ARRAY_SIZE(am43xx_dss_feat_list),
-
- .num_mgrs = 1,
- .num_ovls = 3,
- .supported_displays = am43xx_dss_supported_displays,
- .supported_outputs = am43xx_dss_supported_outputs,
- .supported_color_modes = omap3_dss_supported_color_modes,
- .overlay_caps = omap3430_dss_overlay_caps,
- .dss_params = am43xx_dss_param_range,
- .buffer_size_unit = 1,
- .burst_size_unit = 8,
-};
-
-static const struct omap_dss_features omap3630_dss_features = {
- .reg_fields = omap3_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
-
- .features = omap3630_dss_feat_list,
- .num_features = ARRAY_SIZE(omap3630_dss_feat_list),
-
- .num_mgrs = 2,
- .num_ovls = 3,
- .supported_displays = omap3630_dss_supported_displays,
- .supported_outputs = omap3630_dss_supported_outputs,
- .supported_color_modes = omap3_dss_supported_color_modes,
- .overlay_caps = omap3630_dss_overlay_caps,
- .dss_params = omap3_dss_param_range,
- .buffer_size_unit = 1,
- .burst_size_unit = 8,
-};
-
-/* OMAP4 DSS Features */
-/* For OMAP4430 ES 1.0 revision */
-static const struct omap_dss_features omap4430_es1_0_dss_features = {
- .reg_fields = omap4_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
-
- .features = omap4430_es1_0_dss_feat_list,
- .num_features = ARRAY_SIZE(omap4430_es1_0_dss_feat_list),
-
- .num_mgrs = 3,
- .num_ovls = 4,
- .supported_displays = omap4_dss_supported_displays,
- .supported_outputs = omap4_dss_supported_outputs,
- .supported_color_modes = omap4_dss_supported_color_modes,
- .overlay_caps = omap4_dss_overlay_caps,
- .dss_params = omap4_dss_param_range,
- .buffer_size_unit = 16,
- .burst_size_unit = 16,
-};
-
-/* For OMAP4430 ES 2.0, 2.1 and 2.2 revisions */
-static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = {
- .reg_fields = omap4_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
-
- .features = omap4430_es2_0_1_2_dss_feat_list,
- .num_features = ARRAY_SIZE(omap4430_es2_0_1_2_dss_feat_list),
-
- .num_mgrs = 3,
- .num_ovls = 4,
- .supported_displays = omap4_dss_supported_displays,
- .supported_outputs = omap4_dss_supported_outputs,
- .supported_color_modes = omap4_dss_supported_color_modes,
- .overlay_caps = omap4_dss_overlay_caps,
- .dss_params = omap4_dss_param_range,
- .buffer_size_unit = 16,
- .burst_size_unit = 16,
-};
-
-/* For all the other OMAP4 versions */
-static const struct omap_dss_features omap4_dss_features = {
- .reg_fields = omap4_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
-
- .features = omap4_dss_feat_list,
- .num_features = ARRAY_SIZE(omap4_dss_feat_list),
-
- .num_mgrs = 3,
- .num_ovls = 4,
- .supported_displays = omap4_dss_supported_displays,
- .supported_outputs = omap4_dss_supported_outputs,
- .supported_color_modes = omap4_dss_supported_color_modes,
- .overlay_caps = omap4_dss_overlay_caps,
- .dss_params = omap4_dss_param_range,
- .buffer_size_unit = 16,
- .burst_size_unit = 16,
-};
-
-/* OMAP5 DSS Features */
-static const struct omap_dss_features omap5_dss_features = {
- .reg_fields = omap5_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(omap5_dss_reg_fields),
-
- .features = omap5_dss_feat_list,
- .num_features = ARRAY_SIZE(omap5_dss_feat_list),
-
- .num_mgrs = 4,
- .num_ovls = 4,
- .supported_displays = omap5_dss_supported_displays,
- .supported_outputs = omap5_dss_supported_outputs,
- .supported_color_modes = omap4_dss_supported_color_modes,
- .overlay_caps = omap4_dss_overlay_caps,
- .dss_params = omap5_dss_param_range,
- .buffer_size_unit = 16,
- .burst_size_unit = 16,
-};
-
-/* Functions returning values related to a DSS feature */
-int dss_feat_get_num_mgrs(void)
-{
- return omap_current_dss_features->num_mgrs;
-}
-
-int dss_feat_get_num_ovls(void)
-{
- return omap_current_dss_features->num_ovls;
-}
-
-unsigned long dss_feat_get_param_min(enum dss_range_param param)
-{
- return omap_current_dss_features->dss_params[param].min;
-}
-
-unsigned long dss_feat_get_param_max(enum dss_range_param param)
-{
- return omap_current_dss_features->dss_params[param].max;
-}
-
-enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel)
-{
- return omap_current_dss_features->supported_displays[channel];
-}
-
-enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel)
-{
- return omap_current_dss_features->supported_outputs[channel];
-}
-
-const u32 *dss_feat_get_supported_color_modes(enum omap_plane_id plane)
-{
- return omap_current_dss_features->supported_color_modes[plane];
-}
-
-enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane_id plane)
-{
- return omap_current_dss_features->overlay_caps[plane];
-}
-
-bool dss_feat_color_mode_supported(enum omap_plane_id plane, u32 fourcc)
-{
- const u32 *modes;
- unsigned int i;
-
- modes = omap_current_dss_features->supported_color_modes[plane];
-
- for (i = 0; modes[i]; ++i) {
- if (modes[i] == fourcc)
- return true;
- }
-
- return false;
-}
-
-u32 dss_feat_get_buffer_size_unit(void)
-{
- return omap_current_dss_features->buffer_size_unit;
-}
-
-u32 dss_feat_get_burst_size_unit(void)
-{
- return omap_current_dss_features->burst_size_unit;
-}
-
-/* DSS has_feature check */
-bool dss_has_feature(enum dss_feat_id id)
-{
- int i;
- const enum dss_feat_id *features = omap_current_dss_features->features;
- const int num_features = omap_current_dss_features->num_features;
-
- for (i = 0; i < num_features; i++) {
- if (features[i] == id)
- return true;
- }
-
- return false;
-}
-
-void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end)
-{
- if (id >= omap_current_dss_features->num_reg_fields)
- BUG();
-
- *start = omap_current_dss_features->reg_fields[id].start;
- *end = omap_current_dss_features->reg_fields[id].end;
-}
-
-void dss_features_init(enum omapdss_version version)
-{
- switch (version) {
- case OMAPDSS_VER_OMAP24xx:
- omap_current_dss_features = &omap2_dss_features;
- break;
-
- case OMAPDSS_VER_OMAP34xx_ES1:
- case OMAPDSS_VER_OMAP34xx_ES3:
- omap_current_dss_features = &omap3430_dss_features;
- break;
-
- case OMAPDSS_VER_OMAP3630:
- omap_current_dss_features = &omap3630_dss_features;
- break;
-
- case OMAPDSS_VER_OMAP4430_ES1:
- omap_current_dss_features = &omap4430_es1_0_dss_features;
- break;
-
- case OMAPDSS_VER_OMAP4430_ES2:
- omap_current_dss_features = &omap4430_es2_0_1_2_dss_features;
- break;
-
- case OMAPDSS_VER_OMAP4:
- omap_current_dss_features = &omap4_dss_features;
- break;
-
- case OMAPDSS_VER_OMAP5:
- case OMAPDSS_VER_DRA7xx:
- omap_current_dss_features = &omap5_dss_features;
- break;
-
- case OMAPDSS_VER_AM35xx:
- omap_current_dss_features = &am35xx_dss_features;
- break;
-
- case OMAPDSS_VER_AM43xx:
- omap_current_dss_features = &am43xx_dss_features;
- break;
-
- default:
- DSSWARN("Unsupported OMAP version");
- break;
- }
-}
diff --git a/drivers/gpu/drm/omapdrm/dss/dss_features.h b/drivers/gpu/drm/omapdrm/dss/dss_features.h
deleted file mode 100644
index c36436d..0000000
--- a/drivers/gpu/drm/omapdrm/dss/dss_features.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * linux/drivers/video/omap2/dss/dss_features.h
- *
- * Copyright (C) 2010 Texas Instruments
- * Author: Archit Taneja <archit@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License 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.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __OMAP2_DSS_FEATURES_H
-#define __OMAP2_DSS_FEATURES_H
-
-#define MAX_DSS_MANAGERS 4
-#define MAX_DSS_OVERLAYS 4
-#define MAX_DSS_LCD_MANAGERS 3
-#define MAX_NUM_DSI 2
-
-/* DSS has feature id */
-enum dss_feat_id {
- FEAT_LCDENABLEPOL,
- FEAT_LCDENABLESIGNAL,
- FEAT_PCKFREEENABLE,
- FEAT_FUNCGATED,
- FEAT_MGR_LCD2,
- FEAT_MGR_LCD3,
- FEAT_LINEBUFFERSPLIT,
- FEAT_ROWREPEATENABLE,
- FEAT_RESIZECONF,
- /* Independent core clk divider */
- FEAT_CORE_CLK_DIV,
- FEAT_LCD_CLK_SRC,
- /* DSI-PLL power command 0x3 is not working */
- FEAT_DSI_PLL_PWR_BUG,
- FEAT_DSI_DCS_CMD_CONFIG_VC,
- FEAT_DSI_VC_OCP_WIDTH,
- FEAT_DSI_REVERSE_TXCLKESC,
- FEAT_DSI_GNQ,
- FEAT_DPI_USES_VDDS_DSI,
- FEAT_HDMI_CTS_SWMODE,
- FEAT_HDMI_AUDIO_USE_MCLK,
- FEAT_HANDLE_UV_SEPARATE,
- FEAT_ATTR2,
- FEAT_VENC_REQUIRES_TV_DAC_CLK,
- FEAT_CPR,
- FEAT_PRELOAD,
- FEAT_FIR_COEF_V,
- FEAT_ALPHA_FIXED_ZORDER,
- FEAT_ALPHA_FREE_ZORDER,
- FEAT_FIFO_MERGE,
- /* An unknown HW bug causing the normal FIFO thresholds not to work */
- FEAT_OMAP3_DSI_FIFO_BUG,
- FEAT_BURST_2D,
- FEAT_DSI_PHY_DCC,
- FEAT_MFLAG,
-};
-
-/* DSS register field id */
-enum dss_feat_reg_field {
- FEAT_REG_FIRHINC,
- FEAT_REG_FIRVINC,
- FEAT_REG_FIFOHIGHTHRESHOLD,
- FEAT_REG_FIFOLOWTHRESHOLD,
- FEAT_REG_FIFOSIZE,
- FEAT_REG_HORIZONTALACCU,
- FEAT_REG_VERTICALACCU,
- FEAT_REG_DISPC_CLK_SWITCH,
-};
-
-enum dss_range_param {
- FEAT_PARAM_DSS_FCK,
- FEAT_PARAM_DSS_PCD,
- FEAT_PARAM_DSIPLL_LPDIV,
- FEAT_PARAM_DSI_FCK,
- FEAT_PARAM_DOWNSCALE,
- FEAT_PARAM_LINEWIDTH,
-};
-
-/* DSS Feature Functions */
-unsigned long dss_feat_get_param_min(enum dss_range_param param);
-unsigned long dss_feat_get_param_max(enum dss_range_param param);
-enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane_id plane);
-bool dss_feat_color_mode_supported(enum omap_plane_id plane,
- u32 fourcc);
-
-u32 dss_feat_get_buffer_size_unit(void); /* in bytes */
-u32 dss_feat_get_burst_size_unit(void); /* in bytes */
-
-bool dss_has_feature(enum dss_feat_id id);
-void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end);
-void dss_features_init(enum omapdss_version version);
-
-enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
-enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel);
-
-int dss_feat_get_num_mgrs(void);
-int dss_feat_get_num_ovls(void);
-const u32 *dss_feat_get_supported_color_modes(enum omap_plane_id plane);
-
-#endif
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi.h b/drivers/gpu/drm/omapdrm/dss/hdmi.h
index fb6cccd..a820b39 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi.h
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi.h
@@ -234,6 +234,7 @@ struct hdmi_core_audio_config {
struct hdmi_wp_data {
void __iomem *base;
phys_addr_t phys_base;
+ unsigned int version;
};
struct hdmi_pll_data {
@@ -245,15 +246,24 @@ struct hdmi_pll_data {
struct hdmi_wp_data *wp;
};
+struct hdmi_phy_features {
+ bool bist_ctrl;
+ bool ldo_voltage;
+ unsigned long max_phy;
+};
+
struct hdmi_phy_data {
void __iomem *base;
+ const struct hdmi_phy_features *features;
u8 lane_function[4];
u8 lane_polarity[4];
};
struct hdmi_core_data {
void __iomem *base;
+ bool cts_swmode;
+ bool audio_use_mclk;
};
static inline void hdmi_write_reg(void __iomem *base_addr, const u32 idx,
@@ -303,7 +313,8 @@ void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp,
struct videomode *vm);
void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt,
struct videomode *vm, struct hdmi_config *param);
-int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp);
+int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp,
+ unsigned int version);
phys_addr_t hdmi_wp_get_audio_dma_addr(struct hdmi_wp_data *wp);
/* HDMI PLL funcs */
@@ -316,7 +327,8 @@ void hdmi_pll_uninit(struct hdmi_pll_data *hpll);
int hdmi_phy_configure(struct hdmi_phy_data *phy, unsigned long hfbitclk,
unsigned long lfbitclk);
void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s);
-int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy);
+int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy,
+ unsigned int version);
int hdmi_phy_parse_lanes(struct hdmi_phy_data *phy, const u32 *lanes);
/* HDMI common funcs */
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index 284b494..f169348 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -40,7 +40,6 @@
#include "omapdss.h"
#include "hdmi4_core.h"
#include "dss.h"
-#include "dss_features.h"
#include "hdmi.h"
static struct omap_hdmi hdmi;
@@ -668,7 +667,7 @@ static int hdmi_audio_register(struct device *dev)
{
struct omap_hdmi_audio_pdata pdata = {
.dev = dev,
- .dss_version = omapdss_get_version(),
+ .version = 4,
.audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp),
.ops = &hdmi_audio_ops,
};
@@ -700,7 +699,7 @@ static int hdmi4_bind(struct device *dev, struct device *master, void *data)
if (r)
return r;
- r = hdmi_wp_init(pdev, &hdmi.wp);
+ r = hdmi_wp_init(pdev, &hdmi.wp, 4);
if (r)
return r;
@@ -708,7 +707,7 @@ static int hdmi4_bind(struct device *dev, struct device *master, void *data)
if (r)
return r;
- r = hdmi_phy_init(pdev, &hdmi.phy);
+ r = hdmi_phy_init(pdev, &hdmi.phy, 4);
if (r)
goto err;
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c b/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c
index ed60016..365cf07 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c
@@ -31,11 +31,11 @@
#include <linux/platform_device.h>
#include <linux/string.h>
#include <linux/seq_file.h>
+#include <linux/sys_soc.h>
#include <sound/asound.h>
#include <sound/asoundef.h>
#include "hdmi4_core.h"
-#include "dss_features.h"
#define HDMI_CORE_AV 0x500
@@ -757,10 +757,10 @@ int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
/* Audio clock regeneration settings */
acore.n = n;
acore.cts = cts;
- if (dss_has_feature(FEAT_HDMI_CTS_SWMODE)) {
+ if (core->cts_swmode) {
acore.aud_par_busclk = 0;
acore.cts_mode = HDMI_AUDIO_CTS_MODE_SW;
- acore.use_mclk = dss_has_feature(FEAT_HDMI_AUDIO_USE_MCLK);
+ acore.use_mclk = core->audio_use_mclk;
} else {
acore.aud_par_busclk = (((128 * 31) - 1) << 8);
acore.cts_mode = HDMI_AUDIO_CTS_MODE_HW;
@@ -884,10 +884,42 @@ void hdmi4_audio_stop(struct hdmi_core_data *core, struct hdmi_wp_data *wp)
hdmi_wp_audio_core_req_enable(wp, false);
}
+struct hdmi4_features {
+ bool cts_swmode;
+ bool audio_use_mclk;
+};
+
+static const struct hdmi4_features hdmi4_es1_features = {
+ .cts_swmode = false,
+ .audio_use_mclk = false,
+};
+
+static const struct hdmi4_features hdmi4_es2_features = {
+ .cts_swmode = true,
+ .audio_use_mclk = false,
+};
+
+static const struct hdmi4_features hdmi4_es3_features = {
+ .cts_swmode = true,
+ .audio_use_mclk = true,
+};
+
+static const struct soc_device_attribute hdmi4_soc_devices[] = {
+ { .family = "OMAP4", .revision = "ES1.?", .data = &hdmi4_es1_features },
+ { .family = "OMAP4", .revision = "ES2.?", .data = &hdmi4_es2_features },
+ { .family = "OMAP4", .data = &hdmi4_es3_features },
+ { /* sentinel */ }
+};
+
int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core)
{
+ const struct hdmi4_features *features;
struct resource *res;
+ features = soc_device_match(hdmi4_soc_devices)->data;
+ core->cts_swmode = features->cts_swmode;
+ core->audio_use_mclk = features->audio_use_mclk;
+
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
core->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(core->base))
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
index 441e199..b3221ca 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
@@ -45,7 +45,6 @@
#include "omapdss.h"
#include "hdmi5_core.h"
#include "dss.h"
-#include "dss_features.h"
static struct omap_hdmi hdmi;
@@ -695,7 +694,7 @@ static int hdmi_audio_register(struct device *dev)
{
struct omap_hdmi_audio_pdata pdata = {
.dev = dev,
- .dss_version = omapdss_get_version(),
+ .version = 5,
.audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp),
.ops = &hdmi_audio_ops,
};
@@ -732,7 +731,7 @@ static int hdmi5_bind(struct device *dev, struct device *master, void *data)
if (r)
return r;
- r = hdmi_wp_init(pdev, &hdmi.wp);
+ r = hdmi_wp_init(pdev, &hdmi.wp, 5);
if (r)
return r;
@@ -740,7 +739,7 @@ static int hdmi5_bind(struct device *dev, struct device *master, void *data)
if (r)
return r;
- r = hdmi_phy_init(pdev, &hdmi.phy);
+ r = hdmi_phy_init(pdev, &hdmi.phy, 5);
if (r)
goto err;
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi_phy.c b/drivers/gpu/drm/omapdrm/dss/hdmi_phy.c
index fb5e4c7..a156292 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi_phy.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi_phy.c
@@ -19,14 +19,6 @@
#include "dss.h"
#include "hdmi.h"
-struct hdmi_phy_features {
- bool bist_ctrl;
- bool ldo_voltage;
- unsigned long max_phy;
-};
-
-static const struct hdmi_phy_features *phy_feat;
-
void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s)
{
#define DUMPPHY(r) seq_printf(s, "%-35s %08x\n", #r,\
@@ -36,7 +28,7 @@ void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s)
DUMPPHY(HDMI_TXPHY_DIGITAL_CTRL);
DUMPPHY(HDMI_TXPHY_POWER_CTRL);
DUMPPHY(HDMI_TXPHY_PAD_CFG_CTRL);
- if (phy_feat->bist_ctrl)
+ if (phy->features->bist_ctrl)
DUMPPHY(HDMI_TXPHY_BIST_CONTROL);
}
@@ -146,7 +138,7 @@ int hdmi_phy_configure(struct hdmi_phy_data *phy, unsigned long hfbitclk,
* In OMAP5+, the HFBITCLK must be divided by 2 before issuing the
* HDMI_PHYPWRCMD_LDOON command.
*/
- if (phy_feat->bist_ctrl)
+ if (phy->features->bist_ctrl)
REG_FLD_MOD(phy->base, HDMI_TXPHY_BIST_CONTROL, 1, 11, 11);
/*
@@ -155,7 +147,7 @@ int hdmi_phy_configure(struct hdmi_phy_data *phy, unsigned long hfbitclk,
*/
if (hfbitclk != lfbitclk)
freqout = 0;
- else if (hfbitclk / 10 < phy_feat->max_phy)
+ else if (hfbitclk / 10 < phy->features->max_phy)
freqout = 1;
else
freqout = 2;
@@ -170,7 +162,7 @@ int hdmi_phy_configure(struct hdmi_phy_data *phy, unsigned long hfbitclk,
hdmi_write_reg(phy->base, HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000);
/* Setup max LDO voltage */
- if (phy_feat->ldo_voltage)
+ if (phy->features->ldo_voltage)
REG_FLD_MOD(phy->base, HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0);
hdmi_phy_configure_lanes(phy);
@@ -190,47 +182,15 @@ static const struct hdmi_phy_features omap54xx_phy_feats = {
.max_phy = 186000000,
};
-static int hdmi_phy_init_features(struct platform_device *pdev)
-{
- struct hdmi_phy_features *dst;
- const struct hdmi_phy_features *src;
-
- dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL);
- if (!dst) {
- dev_err(&pdev->dev, "Failed to allocate HDMI PHY Features\n");
- return -ENOMEM;
- }
-
- switch (omapdss_get_version()) {
- case OMAPDSS_VER_OMAP4430_ES1:
- case OMAPDSS_VER_OMAP4430_ES2:
- case OMAPDSS_VER_OMAP4:
- src = &omap44xx_phy_feats;
- break;
-
- case OMAPDSS_VER_OMAP5:
- case OMAPDSS_VER_DRA7xx:
- src = &omap54xx_phy_feats;
- break;
-
- default:
- return -ENODEV;
- }
-
- memcpy(dst, src, sizeof(*dst));
- phy_feat = dst;
-
- return 0;
-}
-
-int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy)
+int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy,
+ unsigned int version)
{
- int r;
struct resource *res;
- r = hdmi_phy_init_features(pdev);
- if (r)
- return r;
+ if (version == 4)
+ phy->features = &omap44xx_phy_feats;
+ else
+ phy->features = &omap54xx_phy_feats;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
phy->base = devm_ioremap_resource(&pdev->dev, res);
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c b/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c
index 4623935..55bee81 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c
@@ -71,7 +71,7 @@ static void hdmi_pll_disable(struct dss_pll *dsspll)
WARN_ON(r < 0 && r != -ENOSYS);
}
-static const struct dss_pll_ops dsi_pll_ops = {
+static const struct dss_pll_ops hdmi_pll_ops = {
.enable = hdmi_pll_enable,
.disable = hdmi_pll_disable,
.set_config = dss_pll_write_config_type_b,
@@ -128,7 +128,8 @@ static const struct dss_pll_hw dss_omap5_hdmi_pll_hw = {
.has_refsel = true,
};
-static int dsi_init_pll_data(struct platform_device *pdev, struct hdmi_pll_data *hpll)
+static int hdmi_init_pll_data(struct platform_device *pdev,
+ struct hdmi_pll_data *hpll)
{
struct dss_pll *pll = &hpll->pll;
struct clk *clk;
@@ -145,23 +146,12 @@ static int dsi_init_pll_data(struct platform_device *pdev, struct hdmi_pll_data
pll->base = hpll->base;
pll->clkin = clk;
- switch (omapdss_get_version()) {
- case OMAPDSS_VER_OMAP4430_ES1:
- case OMAPDSS_VER_OMAP4430_ES2:
- case OMAPDSS_VER_OMAP4:
+ if (hpll->wp->version == 4)
pll->hw = &dss_omap4_hdmi_pll_hw;
- break;
-
- case OMAPDSS_VER_OMAP5:
- case OMAPDSS_VER_DRA7xx:
+ else
pll->hw = &dss_omap5_hdmi_pll_hw;
- break;
-
- default:
- return -ENODEV;
- }
- pll->ops = &dsi_pll_ops;
+ pll->ops = &hdmi_pll_ops;
r = dss_pll_register(pll);
if (r)
@@ -184,7 +174,7 @@ int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll,
if (IS_ERR(pll->base))
return PTR_ERR(pll->base);
- r = dsi_init_pll_data(pdev, pll);
+ r = hdmi_init_pll_data(pdev, pll);
if (r) {
DSSERR("failed to init HDMI PLL\n");
return r;
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c b/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c
index ab129df..88034fb 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c
@@ -178,9 +178,7 @@ void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp,
* However, we don't support OMAP5 ES1 at all, so we can just check for
* OMAP4 here.
*/
- if (omapdss_get_version() == OMAPDSS_VER_OMAP4430_ES1 ||
- omapdss_get_version() == OMAPDSS_VER_OMAP4430_ES2 ||
- omapdss_get_version() == OMAPDSS_VER_OMAP4)
+ if (wp->version == 4)
hsync_len_offset = 0;
timing_h |= FLD_VAL(vm->hback_porch, 31, 20);
@@ -235,9 +233,7 @@ void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp,
DSSDBG("Enter hdmi_wp_audio_config_format\n");
r = hdmi_read_reg(wp->base, HDMI_WP_AUDIO_CFG);
- if (omapdss_get_version() == OMAPDSS_VER_OMAP4430_ES1 ||
- omapdss_get_version() == OMAPDSS_VER_OMAP4430_ES2 ||
- omapdss_get_version() == OMAPDSS_VER_OMAP4) {
+ if (wp->version == 4) {
r = FLD_MOD(r, aud_fmt->stereo_channels, 26, 24);
r = FLD_MOD(r, aud_fmt->active_chnnls_msk, 23, 16);
}
@@ -282,7 +278,8 @@ int hdmi_wp_audio_core_req_enable(struct hdmi_wp_data *wp, bool enable)
return 0;
}
-int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp)
+int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp,
+ unsigned int version)
{
struct resource *res;
@@ -292,6 +289,7 @@ int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp)
return PTR_ERR(wp->base);
wp->phys_base = res->start;
+ wp->version = version;
return 0;
}
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 85953a0b..47a3316 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -25,6 +25,7 @@
#include <video/videomode.h>
#include <linux/platform_data/omapdss.h>
#include <uapi/drm/drm_mode.h>
+#include <drm/drm_crtc.h>
#define DISPC_IRQ_FRAMEDONE (1 << 0)
#define DISPC_IRQ_VSYNC (1 << 1)
@@ -241,13 +242,6 @@ struct omap_dss_dsi_config {
enum omap_dss_dsi_trans_mode trans_mode;
};
-/* Hardcoded videomodes for tv. Venc only uses these to
- * identify the mode, and does not actually use the configs
- * itself. However, the configs should be something that
- * a normal monitor can also show */
-extern const struct videomode omap_dss_pal_vm;
-extern const struct videomode omap_dss_ntsc_vm;
-
struct omap_dss_cpr_coefs {
s16 rr, rg, rb;
s16 gr, gg, gb;
@@ -403,6 +397,14 @@ struct omapdss_hdmi_ops {
int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len);
bool (*detect)(struct omap_dss_device *dssdev);
+ int (*register_hpd_cb)(struct omap_dss_device *dssdev,
+ void (*cb)(void *cb_data,
+ enum drm_connector_status status),
+ void *cb_data);
+ void (*unregister_hpd_cb)(struct omap_dss_device *dssdev);
+ void (*enable_hpd)(struct omap_dss_device *dssdev);
+ void (*disable_hpd)(struct omap_dss_device *dssdev);
+
int (*set_hdmi_mode)(struct omap_dss_device *dssdev, bool hdmi_mode);
int (*set_infoframe)(struct omap_dss_device *dssdev,
const struct hdmi_avi_infoframe *avi);
@@ -567,12 +569,19 @@ struct omap_dss_driver {
int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len);
bool (*detect)(struct omap_dss_device *dssdev);
+ int (*register_hpd_cb)(struct omap_dss_device *dssdev,
+ void (*cb)(void *cb_data,
+ enum drm_connector_status status),
+ void *cb_data);
+ void (*unregister_hpd_cb)(struct omap_dss_device *dssdev);
+ void (*enable_hpd)(struct omap_dss_device *dssdev);
+ void (*disable_hpd)(struct omap_dss_device *dssdev);
+
int (*set_hdmi_mode)(struct omap_dss_device *dssdev, bool hdmi_mode);
int (*set_hdmi_infoframe)(struct omap_dss_device *dssdev,
const struct hdmi_avi_infoframe *avi);
};
-enum omapdss_version omapdss_get_version(void);
bool omapdss_is_initialized(void);
int omap_dss_register_driver(struct omap_dss_driver *);
diff --git a/drivers/gpu/drm/omapdrm/dss/pll.c b/drivers/gpu/drm/omapdrm/dss/pll.c
index 5e22130..9d9d9d4 100644
--- a/drivers/gpu/drm/omapdrm/dss/pll.c
+++ b/drivers/gpu/drm/omapdrm/dss/pll.c
@@ -215,8 +215,8 @@ bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin,
dss_pll_calc_func func, void *data)
{
const struct dss_pll_hw *hw = pll->hw;
- int n, n_min, n_max;
- int m, m_min, m_max;
+ int n, n_start, n_stop, n_inc;
+ int m, m_start, m_stop, m_inc;
unsigned long fint, clkdco;
unsigned long pll_hw_max;
unsigned long fint_hw_min, fint_hw_max;
@@ -226,22 +226,33 @@ bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin,
fint_hw_min = hw->fint_min;
fint_hw_max = hw->fint_max;
- n_min = max(DIV_ROUND_UP(clkin, fint_hw_max), 1ul);
- n_max = min((unsigned)(clkin / fint_hw_min), hw->n_max);
+ n_start = max(DIV_ROUND_UP(clkin, fint_hw_max), 1ul);
+ n_stop = min((unsigned)(clkin / fint_hw_min), hw->n_max);
+ n_inc = 1;
+
+ if (hw->errata_i886) {
+ swap(n_start, n_stop);
+ n_inc = -1;
+ }
pll_max = pll_max ? pll_max : ULONG_MAX;
- /* Try to find high N & M to avoid jitter (DRA7 errata i886) */
- for (n = n_max; n >= n_min; --n) {
+ for (n = n_start; n != n_stop; n += n_inc) {
fint = clkin / n;
- m_min = max(DIV_ROUND_UP(DIV_ROUND_UP(pll_min, fint), 2),
+ m_start = max(DIV_ROUND_UP(DIV_ROUND_UP(pll_min, fint), 2),
1ul);
- m_max = min3((unsigned)(pll_max / fint / 2),
+ m_stop = min3((unsigned)(pll_max / fint / 2),
(unsigned)(pll_hw_max / fint / 2),
hw->m_max);
+ m_inc = 1;
+
+ if (hw->errata_i886) {
+ swap(m_start, m_stop);
+ m_inc = -1;
+ }
- for (m = m_max; m >= m_min; --m) {
+ for (m = m_start; m != m_stop; m += m_inc) {
clkdco = 2 * m * fint;
if (func(n, m, fint, clkdco, data))
diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c b/drivers/gpu/drm/omapdrm/dss/venc.c
index a6bfb39..d58da6f 100644
--- a/drivers/gpu/drm/omapdrm/dss/venc.c
+++ b/drivers/gpu/drm/omapdrm/dss/venc.c
@@ -37,10 +37,10 @@
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/component.h>
+#include <linux/sys_soc.h>
#include "omapdss.h"
#include "dss.h"
-#include "dss_features.h"
/* Venc registers */
#define VENC_REV_ID 0x00
@@ -263,7 +263,13 @@ static const struct venc_config venc_config_pal_bdghi = {
.fid_ext_start_y__fid_ext_offset_y = 0x01380005,
};
-const struct videomode omap_dss_pal_vm = {
+enum venc_videomode {
+ VENC_MODE_UNKNOWN,
+ VENC_MODE_PAL,
+ VENC_MODE_NTSC,
+};
+
+static const struct videomode omap_dss_pal_vm = {
.hactive = 720,
.vactive = 574,
.pixelclock = 13500000,
@@ -279,9 +285,8 @@ const struct videomode omap_dss_pal_vm = {
DISPLAY_FLAGS_PIXDATA_POSEDGE |
DISPLAY_FLAGS_SYNC_NEGEDGE,
};
-EXPORT_SYMBOL(omap_dss_pal_vm);
-const struct videomode omap_dss_ntsc_vm = {
+static const struct videomode omap_dss_ntsc_vm = {
.hactive = 720,
.vactive = 482,
.pixelclock = 13500000,
@@ -297,7 +302,24 @@ const struct videomode omap_dss_ntsc_vm = {
DISPLAY_FLAGS_PIXDATA_POSEDGE |
DISPLAY_FLAGS_SYNC_NEGEDGE,
};
-EXPORT_SYMBOL(omap_dss_ntsc_vm);
+
+static enum venc_videomode venc_get_videomode(const struct videomode *vm)
+{
+ if (!(vm->flags & DISPLAY_FLAGS_INTERLACED))
+ return VENC_MODE_UNKNOWN;
+
+ if (vm->pixelclock == omap_dss_pal_vm.pixelclock &&
+ vm->hactive == omap_dss_pal_vm.hactive &&
+ vm->vactive == omap_dss_pal_vm.vactive)
+ return VENC_MODE_PAL;
+
+ if (vm->pixelclock == omap_dss_ntsc_vm.pixelclock &&
+ vm->hactive == omap_dss_ntsc_vm.hactive &&
+ vm->vactive == omap_dss_ntsc_vm.vactive)
+ return VENC_MODE_NTSC;
+
+ return VENC_MODE_UNKNOWN;
+}
static struct {
struct platform_device *pdev;
@@ -311,6 +333,7 @@ static struct {
struct videomode vm;
enum omap_dss_venc_type type;
bool invert_polarity;
+ bool requires_tv_dac_clk;
struct omap_dss_device output;
} venc;
@@ -424,14 +447,14 @@ static void venc_runtime_put(void)
static const struct venc_config *venc_timings_to_config(struct videomode *vm)
{
- if (memcmp(&omap_dss_pal_vm, vm, sizeof(*vm)) == 0)
+ switch (venc_get_videomode(vm)) {
+ default:
+ WARN_ON_ONCE(1);
+ case VENC_MODE_PAL:
return &venc_config_pal_trm;
-
- if (memcmp(&omap_dss_ntsc_vm, vm, sizeof(*vm)) == 0)
+ case VENC_MODE_NTSC:
return &venc_config_ntsc_trm;
-
- BUG();
- return NULL;
+ }
}
static int venc_power_on(struct omap_dss_device *dssdev)
@@ -542,15 +565,28 @@ static void venc_display_disable(struct omap_dss_device *dssdev)
static void venc_set_timings(struct omap_dss_device *dssdev,
struct videomode *vm)
{
+ struct videomode actual_vm;
+
DSSDBG("venc_set_timings\n");
mutex_lock(&venc.venc_lock);
+ switch (venc_get_videomode(vm)) {
+ default:
+ WARN_ON_ONCE(1);
+ case VENC_MODE_PAL:
+ actual_vm = omap_dss_pal_vm;
+ break;
+ case VENC_MODE_NTSC:
+ actual_vm = omap_dss_ntsc_vm;
+ break;
+ }
+
/* Reset WSS data when the TV standard changes. */
- if (memcmp(&venc.vm, vm, sizeof(*vm)))
+ if (memcmp(&venc.vm, &actual_vm, sizeof(actual_vm)))
venc.wss_data = 0;
- venc.vm = *vm;
+ venc.vm = actual_vm;
dispc_set_tv_pclk(13500000);
@@ -562,13 +598,13 @@ static int venc_check_timings(struct omap_dss_device *dssdev,
{
DSSDBG("venc_check_timings\n");
- if (memcmp(&omap_dss_pal_vm, vm, sizeof(*vm)) == 0)
- return 0;
-
- if (memcmp(&omap_dss_ntsc_vm, vm, sizeof(*vm)) == 0)
+ switch (venc_get_videomode(vm)) {
+ case VENC_MODE_PAL:
+ case VENC_MODE_NTSC:
return 0;
-
- return -EINVAL;
+ default:
+ return -EINVAL;
+ }
}
static void venc_get_timings(struct omap_dss_device *dssdev,
@@ -693,7 +729,7 @@ static int venc_get_clocks(struct platform_device *pdev)
{
struct clk *clk;
- if (dss_has_feature(FEAT_VENC_REQUIRES_TV_DAC_CLK)) {
+ if (venc.requires_tv_dac_clk) {
clk = devm_clk_get(&pdev->dev, "tv_dac_clk");
if (IS_ERR(clk)) {
DSSERR("can't get tv_dac_clk\n");
@@ -828,6 +864,12 @@ err:
}
/* VENC HW IP initialisation */
+static const struct soc_device_attribute venc_soc_devices[] = {
+ { .machine = "OMAP3[45]*" },
+ { .machine = "AM35*" },
+ { /* sentinel */ }
+};
+
static int venc_bind(struct device *dev, struct device *master, void *data)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -837,6 +879,10 @@ static int venc_bind(struct device *dev, struct device *master, void *data)
venc.pdev = pdev;
+ /* The OMAP34xx, OMAP35xx and AM35xx VENC require the TV DAC clock. */
+ if (soc_device_match(venc_soc_devices))
+ venc.requires_tv_dac_clk = true;
+
mutex_init(&venc.venc_lock);
venc.wss_data = 0;
diff --git a/drivers/gpu/drm/omapdrm/dss/video-pll.c b/drivers/gpu/drm/omapdrm/dss/video-pll.c
index fbd1263..38a239c 100644
--- a/drivers/gpu/drm/omapdrm/dss/video-pll.c
+++ b/drivers/gpu/drm/omapdrm/dss/video-pll.c
@@ -19,7 +19,6 @@
#include "omapdss.h"
#include "dss.h"
-#include "dss_features.h"
struct dss_video_pll {
struct dss_pll pll;
@@ -131,6 +130,8 @@ static const struct dss_pll_hw dss_dra7_video_pll_hw = {
.mX_lsb[3] = 5,
.has_refsel = true,
+
+ .errata_i886 = true,
};
struct dss_pll *dss_video_pll_init(struct platform_device *pdev, int id,
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c
index c24b6b7..aa5ba9a 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -35,6 +35,23 @@ struct omap_connector {
bool hdmi_mode;
};
+static void omap_connector_hpd_cb(void *cb_data,
+ enum drm_connector_status status)
+{
+ struct omap_connector *omap_connector = cb_data;
+ struct drm_connector *connector = &omap_connector->base;
+ struct drm_device *dev = connector->dev;
+ enum drm_connector_status old_status;
+
+ mutex_lock(&dev->mode_config.mutex);
+ old_status = connector->status;
+ connector->status = status;
+ mutex_unlock(&dev->mode_config.mutex);
+
+ if (old_status != status)
+ drm_kms_helper_hotplug_event(dev);
+}
+
bool omap_connector_get_hdmi_mode(struct drm_connector *connector)
{
struct omap_connector *omap_connector = to_omap_connector(connector);
@@ -75,6 +92,10 @@ static void omap_connector_destroy(struct drm_connector *connector)
struct omap_dss_device *dssdev = omap_connector->dssdev;
DBG("%s", omap_connector->dssdev->name);
+ if (connector->polled == DRM_CONNECTOR_POLL_HPD &&
+ dssdev->driver->unregister_hpd_cb) {
+ dssdev->driver->unregister_hpd_cb(dssdev);
+ }
drm_connector_unregister(connector);
drm_connector_cleanup(connector);
kfree(omap_connector);
@@ -195,7 +216,6 @@ static int omap_connector_mode_valid(struct drm_connector *connector,
}
static const struct drm_connector_funcs omap_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.reset = drm_atomic_helper_connector_reset,
.detect = omap_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
@@ -216,6 +236,7 @@ struct drm_connector *omap_connector_init(struct drm_device *dev,
{
struct drm_connector *connector = NULL;
struct omap_connector *omap_connector;
+ bool hpd_supported = false;
DBG("%s", dssdev->name);
@@ -233,7 +254,20 @@ struct drm_connector *omap_connector_init(struct drm_device *dev,
connector_type);
drm_connector_helper_add(connector, &omap_connector_helper_funcs);
- if (dssdev->driver->detect)
+ if (dssdev->driver->register_hpd_cb) {
+ int ret = dssdev->driver->register_hpd_cb(dssdev,
+ omap_connector_hpd_cb,
+ omap_connector);
+ if (!ret)
+ hpd_supported = true;
+ else if (ret != -ENOTSUPP)
+ DBG("%s: Failed to register HPD callback (%d).",
+ dssdev->name, ret);
+ }
+
+ if (hpd_supported)
+ connector->polled = DRM_CONNECTOR_POLL_HPD;
+ else if (dssdev->driver->detect)
connector->polled = DRM_CONNECTOR_POLL_CONNECT |
DRM_CONNECTOR_POLL_DISCONNECT;
else
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index dd0ef40..cc85c16 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -26,6 +26,16 @@
#include "omap_drv.h"
+#define to_omap_crtc_state(x) container_of(x, struct omap_crtc_state, base)
+
+struct omap_crtc_state {
+ /* Must be first. */
+ struct drm_crtc_state base;
+ /* Shadow values for legacy userspace support. */
+ unsigned int rotation;
+ unsigned int zpos;
+};
+
#define to_omap_crtc(x) container_of(x, struct omap_crtc, base)
struct omap_crtc {
@@ -356,7 +366,8 @@ static void omap_crtc_arm_event(struct drm_crtc *crtc)
}
}
-static void omap_crtc_enable(struct drm_crtc *crtc)
+static void omap_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
int ret;
@@ -372,7 +383,8 @@ static void omap_crtc_enable(struct drm_crtc *crtc)
spin_unlock_irq(&crtc->dev->event_lock);
}
-static void omap_crtc_disable(struct drm_crtc *crtc)
+static void omap_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
@@ -443,6 +455,8 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
static int omap_crtc_atomic_check(struct drm_crtc *crtc,
struct drm_crtc_state *state)
{
+ struct drm_plane_state *pri_state;
+
if (state->color_mgmt_changed && state->gamma_lut) {
uint length = state->gamma_lut->length /
sizeof(struct drm_color_lut);
@@ -451,6 +465,16 @@ static int omap_crtc_atomic_check(struct drm_crtc *crtc,
return -EINVAL;
}
+ pri_state = drm_atomic_get_new_plane_state(state->state, crtc->primary);
+ if (pri_state) {
+ struct omap_crtc_state *omap_crtc_state =
+ to_omap_crtc_state(state);
+
+ /* Mirror new values for zpos and rotation in omap_crtc_state */
+ omap_crtc_state->zpos = pri_state->zpos;
+ omap_crtc_state->rotation = pri_state->rotation;
+ }
+
return 0;
}
@@ -496,39 +520,32 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc,
spin_unlock_irq(&crtc->dev->event_lock);
}
-static bool omap_crtc_is_plane_prop(struct drm_crtc *crtc,
- struct drm_property *property)
-{
- struct drm_device *dev = crtc->dev;
- struct omap_drm_private *priv = dev->dev_private;
-
- return property == priv->zorder_prop ||
- property == crtc->primary->rotation_property;
-}
-
static int omap_crtc_atomic_set_property(struct drm_crtc *crtc,
struct drm_crtc_state *state,
struct drm_property *property,
uint64_t val)
{
- if (omap_crtc_is_plane_prop(crtc, property)) {
- struct drm_plane_state *plane_state;
- struct drm_plane *plane = crtc->primary;
-
- /*
- * Delegate property set to the primary plane. Get the plane
- * state and set the property directly.
- */
-
- plane_state = drm_atomic_get_plane_state(state->state, plane);
- if (IS_ERR(plane_state))
- return PTR_ERR(plane_state);
+ struct omap_drm_private *priv = crtc->dev->dev_private;
+ struct drm_plane_state *plane_state;
- return drm_atomic_plane_set_property(plane, plane_state,
- property, val);
- }
+ /*
+ * Delegate property set to the primary plane. Get the plane state and
+ * set the property directly, the shadow copy will be assigned in the
+ * omap_crtc_atomic_check callback. This way updates to plane state will
+ * always be mirrored in the crtc state correctly.
+ */
+ plane_state = drm_atomic_get_plane_state(state->state, crtc->primary);
+ if (IS_ERR(plane_state))
+ return PTR_ERR(plane_state);
+
+ if (property == crtc->primary->rotation_property)
+ plane_state->rotation = val;
+ else if (property == priv->zorder_prop)
+ plane_state->zpos = val;
+ else
+ return -EINVAL;
- return -EINVAL;
+ return 0;
}
static int omap_crtc_atomic_get_property(struct drm_crtc *crtc,
@@ -536,28 +553,60 @@ static int omap_crtc_atomic_get_property(struct drm_crtc *crtc,
struct drm_property *property,
uint64_t *val)
{
- if (omap_crtc_is_plane_prop(crtc, property)) {
- /*
- * Delegate property get to the primary plane. The
- * drm_atomic_plane_get_property() function isn't exported, but
- * can be called through drm_object_property_get_value() as that
- * will call drm_atomic_get_property() for atomic drivers.
- */
- return drm_object_property_get_value(&crtc->primary->base,
- property, val);
- }
+ struct omap_drm_private *priv = crtc->dev->dev_private;
+ struct omap_crtc_state *omap_state = to_omap_crtc_state(state);
+
+ if (property == crtc->primary->rotation_property)
+ *val = omap_state->rotation;
+ else if (property == priv->zorder_prop)
+ *val = omap_state->zpos;
+ else
+ return -EINVAL;
+
+ return 0;
+}
+
+static void omap_crtc_reset(struct drm_crtc *crtc)
+{
+ if (crtc->state)
+ __drm_atomic_helper_crtc_destroy_state(crtc->state);
+
+ kfree(crtc->state);
+ crtc->state = kzalloc(sizeof(struct omap_crtc_state), GFP_KERNEL);
+
+ if (crtc->state)
+ crtc->state->crtc = crtc;
+}
+
+static struct drm_crtc_state *
+omap_crtc_duplicate_state(struct drm_crtc *crtc)
+{
+ struct omap_crtc_state *state, *current_state;
+
+ if (WARN_ON(!crtc->state))
+ return NULL;
+
+ current_state = to_omap_crtc_state(crtc->state);
+
+ state = kmalloc(sizeof(*state), GFP_KERNEL);
+ if (!state)
+ return NULL;
+
+ __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base);
+
+ state->zpos = current_state->zpos;
+ state->rotation = current_state->rotation;
- return -EINVAL;
+ return &state->base;
}
static const struct drm_crtc_funcs omap_crtc_funcs = {
- .reset = drm_atomic_helper_crtc_reset,
+ .reset = omap_crtc_reset,
.set_config = drm_atomic_helper_set_config,
.destroy = omap_crtc_destroy,
.page_flip = drm_atomic_helper_page_flip,
.gamma_set = drm_atomic_helper_legacy_gamma_set,
- .set_property = drm_atomic_helper_crtc_set_property,
- .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
+ .atomic_duplicate_state = omap_crtc_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
.atomic_set_property = omap_crtc_atomic_set_property,
.atomic_get_property = omap_crtc_atomic_get_property,
@@ -567,11 +616,11 @@ static const struct drm_crtc_funcs omap_crtc_funcs = {
static const struct drm_crtc_helper_funcs omap_crtc_helper_funcs = {
.mode_set_nofb = omap_crtc_mode_set_nofb,
- .disable = omap_crtc_disable,
- .enable = omap_crtc_enable,
.atomic_check = omap_crtc_atomic_check,
.atomic_begin = omap_crtc_atomic_begin,
.atomic_flush = omap_crtc_atomic_flush,
+ .atomic_enable = omap_crtc_atomic_enable,
+ .atomic_disable = omap_crtc_atomic_disable,
};
/* -----------------------------------------------------------------------------
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 022029e..cdf5b06 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -57,13 +57,13 @@ static void omap_fb_output_poll_changed(struct drm_device *dev)
static void omap_atomic_wait_for_completion(struct drm_device *dev,
struct drm_atomic_state *old_state)
{
- struct drm_crtc_state *old_crtc_state;
+ struct drm_crtc_state *new_crtc_state;
struct drm_crtc *crtc;
unsigned int i;
int ret;
- for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
- if (!crtc->state->enable)
+ for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
+ if (!new_crtc_state->active)
continue;
ret = omap_crtc_wait_pending(crtc);
@@ -84,23 +84,36 @@ static void omap_atomic_commit_tail(struct drm_atomic_state *old_state)
/* Apply the atomic update. */
drm_atomic_helper_commit_modeset_disables(dev, old_state);
- /* With the current dss dispc implementation we have to enable
- * the new modeset before we can commit planes. The dispc ovl
- * configuration relies on the video mode configuration been
- * written into the HW when the ovl configuration is
- * calculated.
- *
- * This approach is not ideal because after a mode change the
- * plane update is executed only after the first vblank
- * interrupt. The dispc implementation should be fixed so that
- * it is able use uncommitted drm state information.
- */
- drm_atomic_helper_commit_modeset_enables(dev, old_state);
- omap_atomic_wait_for_completion(dev, old_state);
-
- drm_atomic_helper_commit_planes(dev, old_state, 0);
-
- drm_atomic_helper_commit_hw_done(old_state);
+ if (priv->omaprev != 0x3430) {
+ /* With the current dss dispc implementation we have to enable
+ * the new modeset before we can commit planes. The dispc ovl
+ * configuration relies on the video mode configuration been
+ * written into the HW when the ovl configuration is
+ * calculated.
+ *
+ * This approach is not ideal because after a mode change the
+ * plane update is executed only after the first vblank
+ * interrupt. The dispc implementation should be fixed so that
+ * it is able use uncommitted drm state information.
+ */
+ drm_atomic_helper_commit_modeset_enables(dev, old_state);
+ omap_atomic_wait_for_completion(dev, old_state);
+
+ drm_atomic_helper_commit_planes(dev, old_state, 0);
+
+ drm_atomic_helper_commit_hw_done(old_state);
+ } else {
+ /*
+ * OMAP3 DSS seems to have issues with the work-around above,
+ * resulting in endless sync losts if a crtc is enabled without
+ * a plane. For now, skip the WA for OMAP3.
+ */
+ drm_atomic_helper_commit_planes(dev, old_state, 0);
+
+ drm_atomic_helper_commit_modeset_enables(dev, old_state);
+
+ drm_atomic_helper_commit_hw_done(old_state);
+ }
/*
* Wait for completion of the page flips to ensure that old buffers
@@ -324,6 +337,32 @@ static int omap_modeset_init(struct drm_device *dev)
}
/*
+ * Enable the HPD in external components if supported
+ */
+static void omap_modeset_enable_external_hpd(void)
+{
+ struct omap_dss_device *dssdev = NULL;
+
+ for_each_dss_dev(dssdev) {
+ if (dssdev->driver->enable_hpd)
+ dssdev->driver->enable_hpd(dssdev);
+ }
+}
+
+/*
+ * Disable the HPD in external components if supported
+ */
+static void omap_modeset_disable_external_hpd(void)
+{
+ struct omap_dss_device *dssdev = NULL;
+
+ for_each_dss_dev(dssdev) {
+ if (dssdev->driver->disable_hpd)
+ dssdev->driver->disable_hpd(dssdev);
+ }
+}
+
+/*
* drm ioctl funcs
*/
@@ -438,44 +477,11 @@ static int dev_open(struct drm_device *dev, struct drm_file *file)
*/
static void dev_lastclose(struct drm_device *dev)
{
- int i;
-
- /* we don't support vga_switcheroo.. so just make sure the fbdev
- * mode is active
- */
struct omap_drm_private *priv = dev->dev_private;
int ret;
DBG("lastclose: dev=%p", dev);
- /* need to restore default rotation state.. not sure
- * if there is a cleaner way to restore properties to
- * default state? Maybe a flag that properties should
- * automatically be restored to default state on
- * lastclose?
- */
- for (i = 0; i < priv->num_crtcs; i++) {
- struct drm_crtc *crtc = priv->crtcs[i];
-
- if (!crtc->primary->rotation_property)
- continue;
-
- drm_object_property_set_value(&crtc->base,
- crtc->primary->rotation_property,
- DRM_MODE_ROTATE_0);
- }
-
- for (i = 0; i < priv->num_planes; i++) {
- struct drm_plane *plane = priv->planes[i];
-
- if (!plane->rotation_property)
- continue;
-
- drm_object_property_set_value(&plane->base,
- plane->rotation_property,
- DRM_MODE_ROTATE_0);
- }
-
if (priv->fbdev) {
ret = drm_fb_helper_restore_fbdev_mode_unlocked(priv->fbdev);
if (ret)
@@ -517,7 +523,6 @@ static struct drm_driver omap_drm_driver = {
.gem_vm_ops = &omap_gem_vm_ops,
.dumb_create = omap_gem_dumb_create,
.dumb_map_offset = omap_gem_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.ioctls = ioctls,
.num_ioctls = DRM_OMAP_NUM_IOCTLS,
.fops = &omapdriver_fops,
@@ -550,6 +555,12 @@ static int pdev_probe(struct platform_device *pdev)
if (omapdss_is_initialized() == false)
return -EPROBE_DEFER;
+ ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to set the DMA mask\n");
+ return ret;
+ }
+
omap_crtc_pre_init();
ret = omap_connect_dssdevs();
@@ -603,6 +614,7 @@ static int pdev_probe(struct platform_device *pdev)
priv->fbdev = omap_fbdev_init(ddev);
drm_kms_helper_poll_init(ddev);
+ omap_modeset_enable_external_hpd();
/*
* Register the DRM device with the core and the connectors with
@@ -615,6 +627,7 @@ static int pdev_probe(struct platform_device *pdev)
return 0;
err_cleanup_helpers:
+ omap_modeset_disable_external_hpd();
drm_kms_helper_poll_fini(ddev);
if (priv->fbdev)
omap_fbdev_free(ddev);
@@ -643,6 +656,7 @@ static int pdev_remove(struct platform_device *pdev)
drm_dev_unregister(ddev);
+ omap_modeset_disable_external_hpd();
drm_kms_helper_poll_fini(ddev);
if (priv->fbdev)
@@ -734,7 +748,7 @@ static SIMPLE_DEV_PM_OPS(omapdrm_pm_ops, omap_drm_suspend, omap_drm_resume);
static struct platform_driver pdev = {
.driver = {
- .name = DRIVER_NAME,
+ .name = "omapdrm",
.pm = &omapdrm_pm_ops,
},
.probe = pdev_probe,
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 86c977b..624f5b5 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -85,7 +85,8 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder,
if (hdmi_mode && dssdev->driver->set_hdmi_infoframe) {
struct hdmi_avi_infoframe avi;
- r = drm_hdmi_avi_infoframe_from_display_mode(&avi, adjusted_mode);
+ r = drm_hdmi_avi_infoframe_from_display_mode(&avi, adjusted_mode,
+ false);
if (r == 0)
dssdev->driver->set_hdmi_infoframe(dssdev, &avi);
}
diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c
index ddf7a45..b1a762b 100644
--- a/drivers/gpu/drm/omapdrm/omap_fb.c
+++ b/drivers/gpu/drm/omapdrm/omap_fb.c
@@ -379,7 +379,7 @@ struct drm_framebuffer *omap_framebuffer_create(struct drm_device *dev,
return fb;
error:
- while (--i > 0)
+ while (--i >= 0)
drm_gem_object_unreference_unlocked(bos[i]);
return fb;
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c
index daf81a0..9273118 100644
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -184,7 +184,6 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
helper->fb = fb;
fbi->par = helper;
- fbi->flags = FBINFO_DEFAULT;
fbi->fbops = &omap_fb_ops;
strcpy(fbi->fix.id, MODULE_NAME);
diff --git a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
index 863a881..afdbad5 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
@@ -144,7 +144,7 @@ static int omap_gem_dmabuf_mmap(struct dma_buf *buffer,
return omap_gem_mmap_obj(obj, vma);
}
-static struct dma_buf_ops omap_dmabuf_ops = {
+static const struct dma_buf_ops omap_dmabuf_ops = {
.map_dma_buf = omap_gem_map_dma_buf,
.unmap_dma_buf = omap_gem_unmap_dma_buf,
.release = drm_gem_dmabuf_release,
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index 2160f64..15e5d5d 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -235,7 +235,6 @@ static const struct drm_plane_funcs omap_plane_funcs = {
.disable_plane = drm_atomic_helper_disable_plane,
.reset = omap_plane_reset,
.destroy = omap_plane_destroy,
- .set_property = drm_atomic_helper_plane_set_property,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
.atomic_set_property = omap_plane_atomic_set_property,
@@ -291,7 +290,7 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
ret = drm_universal_plane_init(dev, plane, possible_crtcs,
&omap_plane_funcs, formats,
- nformats, type, NULL);
+ nformats, NULL, type, NULL);
if (ret < 0)
goto error;
diff --git a/drivers/gpu/drm/panel/panel-lvds.c b/drivers/gpu/drm/panel/panel-lvds.c
index 3216aa9..e2d57c0 100644
--- a/drivers/gpu/drm/panel/panel-lvds.c
+++ b/drivers/gpu/drm/panel/panel-lvds.c
@@ -143,14 +143,14 @@ static int panel_lvds_parse_dt(struct panel_lvds *lvds)
ret = of_property_read_u32(np, "width-mm", &lvds->width);
if (ret < 0) {
- dev_err(lvds->dev, "%s: invalid or missing %s DT property\n",
- of_node_full_name(np), "width-mm");
+ dev_err(lvds->dev, "%pOF: invalid or missing %s DT property\n",
+ np, "width-mm");
return -ENODEV;
}
ret = of_property_read_u32(np, "height-mm", &lvds->height);
if (ret < 0) {
- dev_err(lvds->dev, "%s: invalid or missing %s DT property\n",
- of_node_full_name(np), "height-mm");
+ dev_err(lvds->dev, "%pOF: invalid or missing %s DT property\n",
+ np, "height-mm");
return -ENODEV;
}
@@ -158,8 +158,8 @@ static int panel_lvds_parse_dt(struct panel_lvds *lvds)
ret = of_property_read_string(np, "data-mapping", &mapping);
if (ret < 0) {
- dev_err(lvds->dev, "%s: invalid or missing %s DT property\n",
- of_node_full_name(np), "data-mapping");
+ dev_err(lvds->dev, "%pOF: invalid or missing %s DT property\n",
+ np, "data-mapping");
return -ENODEV;
}
@@ -170,8 +170,8 @@ static int panel_lvds_parse_dt(struct panel_lvds *lvds)
} else if (!strcmp(mapping, "vesa-24")) {
lvds->bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG;
} else {
- dev_err(lvds->dev, "%s: invalid or missing %s DT property\n",
- of_node_full_name(np), "data-mapping");
+ dev_err(lvds->dev, "%pOF: invalid or missing %s DT property\n",
+ np, "data-mapping");
return -EINVAL;
}
diff --git a/drivers/gpu/drm/pl111/pl111_connector.c b/drivers/gpu/drm/pl111/pl111_connector.c
index 3f213d7..d335f9a 100644
--- a/drivers/gpu/drm/pl111/pl111_connector.c
+++ b/drivers/gpu/drm/pl111/pl111_connector.c
@@ -69,7 +69,6 @@ const struct drm_connector_funcs connector_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = pl111_connector_destroy,
.detect = pl111_connector_detect,
- .dpms = drm_atomic_helper_connector_dpms,
.reset = drm_atomic_helper_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
diff --git a/drivers/gpu/drm/pl111/pl111_display.c b/drivers/gpu/drm/pl111/pl111_display.c
index c6ca4f1b..b58c988 100644
--- a/drivers/gpu/drm/pl111/pl111_display.c
+++ b/drivers/gpu/drm/pl111/pl111_display.c
@@ -23,6 +23,7 @@
#include <drm/drmP.h>
#include <drm/drm_panel.h>
#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_fb_cma_helper.h>
#include "pl111_drm.h"
@@ -274,7 +275,7 @@ void pl111_disable_vblank(struct drm_device *drm, unsigned int crtc)
static int pl111_display_prepare_fb(struct drm_simple_display_pipe *pipe,
struct drm_plane_state *plane_state)
{
- return drm_fb_cma_prepare_fb(&pipe->plane, plane_state);
+ return drm_gem_fb_prepare_fb(&pipe->plane, plane_state);
}
static const struct drm_simple_display_pipe_funcs pl111_display_funcs = {
@@ -457,7 +458,7 @@ int pl111_display_init(struct drm_device *drm)
ret = drm_simple_display_pipe_init(drm, &priv->pipe,
&pl111_display_funcs,
formats, ARRAY_SIZE(formats),
- &priv->connector.connector);
+ NULL, &priv->connector.connector);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c
index ac8771b..581c452 100644
--- a/drivers/gpu/drm/pl111/pl111_drv.c
+++ b/drivers/gpu/drm/pl111/pl111_drv.c
@@ -66,14 +66,15 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_fb_cma_helper.h>
#include "pl111_drm.h"
#define DRIVER_DESC "DRM module for PL111"
-static struct drm_mode_config_funcs mode_config_funcs = {
- .fb_create = drm_fb_cma_create,
+static const struct drm_mode_config_funcs mode_config_funcs = {
+ .fb_create = drm_gem_fb_create,
.atomic_check = drm_atomic_helper_check,
.atomic_commit = drm_atomic_helper_commit,
};
@@ -159,9 +160,7 @@ static struct drm_driver pl111_drm_driver = {
.minor = 0,
.patchlevel = 0,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_destroy = drm_gem_dumb_destroy,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .gem_free_object = drm_gem_cma_free_object,
+ .gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.enable_vblank = pl111_enable_vblank,
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c
index 03fe182..14c5613 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -378,10 +378,6 @@ qxl_framebuffer_init(struct drm_device *dev,
return 0;
}
-static void qxl_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
-}
-
static bool qxl_crtc_mode_fixup(struct drm_crtc *crtc,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
@@ -437,7 +433,7 @@ static void qxl_monitors_config_set(struct qxl_device *qdev,
}
-void qxl_mode_set_nofb(struct drm_crtc *crtc)
+static void qxl_mode_set_nofb(struct drm_crtc *crtc)
{
struct qxl_device *qdev = crtc->dev->dev_private;
struct qxl_crtc *qcrtc = to_qxl_crtc(crtc);
@@ -451,12 +447,14 @@ void qxl_mode_set_nofb(struct drm_crtc *crtc)
}
-static void qxl_crtc_commit(struct drm_crtc *crtc)
+static void qxl_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
DRM_DEBUG("\n");
}
-static void qxl_crtc_disable(struct drm_crtc *crtc)
+static void qxl_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct qxl_crtc *qcrtc = to_qxl_crtc(crtc);
struct qxl_device *qdev = crtc->dev->dev_private;
@@ -467,16 +465,15 @@ static void qxl_crtc_disable(struct drm_crtc *crtc)
}
static const struct drm_crtc_helper_funcs qxl_crtc_helper_funcs = {
- .dpms = qxl_crtc_dpms,
- .disable = qxl_crtc_disable,
.mode_fixup = qxl_crtc_mode_fixup,
.mode_set_nofb = qxl_mode_set_nofb,
- .commit = qxl_crtc_commit,
.atomic_flush = qxl_crtc_atomic_flush,
+ .atomic_enable = qxl_crtc_atomic_enable,
+ .atomic_disable = qxl_crtc_atomic_disable,
};
-int qxl_primary_atomic_check(struct drm_plane *plane,
- struct drm_plane_state *state)
+static int qxl_primary_atomic_check(struct drm_plane *plane,
+ struct drm_plane_state *state)
{
struct qxl_device *qdev = plane->dev->dev_private;
struct qxl_framebuffer *qfb;
@@ -547,8 +544,8 @@ static void qxl_primary_atomic_disable(struct drm_plane *plane,
}
}
-int qxl_plane_atomic_check(struct drm_plane *plane,
- struct drm_plane_state *state)
+static int qxl_plane_atomic_check(struct drm_plane *plane,
+ struct drm_plane_state *state)
{
return 0;
}
@@ -647,8 +644,8 @@ out_free_release:
}
-void qxl_cursor_atomic_disable(struct drm_plane *plane,
- struct drm_plane_state *old_state)
+static void qxl_cursor_atomic_disable(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
{
struct qxl_device *qdev = plane->dev->dev_private;
struct qxl_release *release;
@@ -675,8 +672,8 @@ void qxl_cursor_atomic_disable(struct drm_plane *plane,
qxl_release_fence_buffer_objects(release);
}
-int qxl_plane_prepare_fb(struct drm_plane *plane,
- struct drm_plane_state *new_state)
+static int qxl_plane_prepare_fb(struct drm_plane *plane,
+ struct drm_plane_state *new_state)
{
struct drm_gem_object *obj;
struct qxl_bo *user_bo;
@@ -787,7 +784,7 @@ static struct drm_plane *qxl_create_plane(struct qxl_device *qdev,
err = drm_universal_plane_init(&qdev->ddev, plane, possible_crtcs,
funcs, formats, num_formats,
- type, NULL);
+ NULL, type, NULL);
if (err)
goto free_plane;
diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c
index c2fc201..2445e75 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.c
+++ b/drivers/gpu/drm/qxl/qxl_drv.c
@@ -37,7 +37,6 @@
#include "qxl_drv.h"
#include "qxl_object.h"
-extern int qxl_max_ioctls;
static const struct pci_device_id pciidlist[] = {
{ 0x1b36, 0x100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8,
0xffff00, 0 },
@@ -262,11 +261,8 @@ static struct drm_driver qxl_driver = {
DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
DRIVER_ATOMIC,
- .set_busid = drm_pci_set_busid,
-
.dumb_create = qxl_mode_dumb_create,
.dumb_map_offset = qxl_mode_dumb_mmap,
- .dumb_destroy = drm_gem_dumb_destroy,
#if defined(CONFIG_DEBUG_FS)
.debugfs_init = qxl_debugfs_init,
#endif
@@ -303,12 +299,12 @@ static int __init qxl_init(void)
if (qxl_modeset == 0)
return -EINVAL;
qxl_driver.num_ioctls = qxl_max_ioctls;
- return drm_pci_init(&qxl_driver, &qxl_pci_driver);
+ return pci_register_driver(&qxl_pci_driver);
}
static void __exit qxl_exit(void)
{
- drm_pci_exit(&qxl_driver, &qxl_pci_driver);
+ pci_unregister_driver(&qxl_pci_driver);
}
module_init(qxl_init);
diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
index 3591d23..3397a19 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.h
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
@@ -64,6 +64,7 @@
extern int qxl_log_level;
extern int qxl_num_crtc;
+extern int qxl_max_ioctls;
enum {
QXL_INFO_LEVEL = 1,
diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c
index 573e7e9..844c4a3 100644
--- a/drivers/gpu/drm/qxl/qxl_fb.c
+++ b/drivers/gpu/drm/qxl/qxl_fb.c
@@ -275,7 +275,6 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev,
drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth);
- info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT;
info->fbops = &qxlfb_ops;
/*
diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c
index 0b82a87..31effed 100644
--- a/drivers/gpu/drm/qxl/qxl_ioctl.c
+++ b/drivers/gpu/drm/qxl/qxl_ioctl.c
@@ -163,7 +163,7 @@ static int qxl_process_single_command(struct qxl_device *qdev,
return -EINVAL;
if (!access_ok(VERIFY_READ,
- (void *)(unsigned long)cmd->command,
+ u64_to_user_ptr(cmd->command),
cmd->command_size))
return -EFAULT;
@@ -183,7 +183,9 @@ static int qxl_process_single_command(struct qxl_device *qdev,
/* TODO copy slow path code from i915 */
fb_cmd = qxl_bo_kmap_atomic_page(qdev, cmd_bo, (release->release_offset & PAGE_SIZE));
- unwritten = __copy_from_user_inatomic_nocache(fb_cmd + sizeof(union qxl_release_info) + (release->release_offset & ~PAGE_SIZE), (void *)(unsigned long)cmd->command, cmd->command_size);
+ unwritten = __copy_from_user_inatomic_nocache
+ (fb_cmd + sizeof(union qxl_release_info) + (release->release_offset & ~PAGE_SIZE),
+ u64_to_user_ptr(cmd->command), cmd->command_size);
{
struct qxl_drawable *draw = fb_cmd;
@@ -201,10 +203,9 @@ static int qxl_process_single_command(struct qxl_device *qdev,
num_relocs = 0;
for (i = 0; i < cmd->relocs_num; ++i) {
struct drm_qxl_reloc reloc;
+ struct drm_qxl_reloc __user *u = u64_to_user_ptr(cmd->relocs);
- if (copy_from_user(&reloc,
- &((struct drm_qxl_reloc *)(uintptr_t)cmd->relocs)[i],
- sizeof(reloc))) {
+ if (copy_from_user(&reloc, u + i, sizeof(reloc))) {
ret = -EFAULT;
goto out_free_bos;
}
@@ -282,10 +283,10 @@ static int qxl_execbuffer_ioctl(struct drm_device *dev, void *data,
for (cmd_num = 0; cmd_num < execbuffer->commands_num; ++cmd_num) {
- struct drm_qxl_command *commands =
- (struct drm_qxl_command *)(uintptr_t)execbuffer->commands;
+ struct drm_qxl_command __user *commands =
+ u64_to_user_ptr(execbuffer->commands);
- if (copy_from_user(&user_cmd, &commands[cmd_num],
+ if (copy_from_user(&user_cmd, commands + cmd_num,
sizeof(user_cmd)))
return -EFAULT;
diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c
index 9a7eef7..0a67ddf 100644
--- a/drivers/gpu/drm/qxl/qxl_object.c
+++ b/drivers/gpu/drm/qxl/qxl_object.c
@@ -221,7 +221,7 @@ struct qxl_bo *qxl_bo_ref(struct qxl_bo *bo)
return bo;
}
-int __qxl_bo_pin(struct qxl_bo *bo, u32 domain, u64 *gpu_addr)
+static int __qxl_bo_pin(struct qxl_bo *bo, u32 domain, u64 *gpu_addr)
{
struct drm_device *ddev = bo->gem_base.dev;
int r;
@@ -244,7 +244,7 @@ int __qxl_bo_pin(struct qxl_bo *bo, u32 domain, u64 *gpu_addr)
return r;
}
-int __qxl_bo_unpin(struct qxl_bo *bo)
+static int __qxl_bo_unpin(struct qxl_bo *bo)
{
struct drm_device *ddev = bo->gem_base.dev;
int r, i;
diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c
index 87fc1db..7ecf8a4 100644
--- a/drivers/gpu/drm/qxl/qxl_ttm.c
+++ b/drivers/gpu/drm/qxl/qxl_ttm.c
@@ -187,7 +187,7 @@ static void qxl_evict_flags(struct ttm_buffer_object *bo,
struct ttm_placement *placement)
{
struct qxl_bo *qbo;
- static struct ttm_place placements = {
+ static const struct ttm_place placements = {
.fpfn = 0,
.lpfn = 0,
.flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM
diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c
index a982be5..0d2b7e4 100644
--- a/drivers/gpu/drm/r128/r128_drv.c
+++ b/drivers/gpu/drm/r128/r128_drv.c
@@ -62,7 +62,6 @@ static struct drm_driver driver = {
.load = r128_driver_load,
.preclose = r128_driver_preclose,
.lastclose = r128_driver_lastclose,
- .set_busid = drm_pci_set_busid,
.get_vblank_counter = r128_get_vblank_counter,
.enable_vblank = r128_enable_vblank,
.disable_vblank = r128_disable_vblank,
@@ -96,12 +95,12 @@ static int __init r128_init(void)
{
driver.num_ioctls = r128_max_ioctl;
- return drm_pci_init(&driver, &r128_pci_driver);
+ return drm_legacy_pci_init(&driver, &r128_pci_driver);
}
static void __exit r128_exit(void)
{
- drm_pci_exit(&driver, &r128_pci_driver);
+ drm_legacy_pci_exit(&driver, &r128_pci_driver);
}
module_init(r128_init);
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 3c492a0..02baaaf 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -2217,7 +2217,6 @@ static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
.mode_set_base_atomic = atombios_crtc_set_base_atomic,
.prepare = atombios_crtc_prepare,
.commit = atombios_crtc_commit,
- .load_lut = radeon_crtc_load_lut,
.disable = atombios_crtc_disable,
};
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 5008f3d..ec63bc5 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -464,7 +464,7 @@ struct radeon_bo_list {
struct radeon_bo *robj;
struct ttm_validate_buffer tv;
uint64_t gpu_offset;
- unsigned prefered_domains;
+ unsigned preferred_domains;
unsigned allowed_domains;
uint32_t tiling_flags;
};
@@ -2327,7 +2327,7 @@ struct radeon_device {
uint8_t *bios;
bool is_atom_bios;
uint16_t bios_header_start;
- struct radeon_bo *stollen_vga_memory;
+ struct radeon_bo *stolen_vga_memory;
/* Register mmio */
resource_size_t rmmio_base;
resource_size_t rmmio_size;
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c
index 6efbd65..8d3251a 100644
--- a/drivers/gpu/drm/radeon/radeon_acpi.c
+++ b/drivers/gpu/drm/radeon/radeon_acpi.c
@@ -351,7 +351,7 @@ out:
* handles it.
* Returns NOTIFY code
*/
-int radeon_atif_handler(struct radeon_device *rdev,
+static int radeon_atif_handler(struct radeon_device *rdev,
struct acpi_bus_event *event)
{
struct radeon_atif *atif = &rdev->atif;
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.h b/drivers/gpu/drm/radeon/radeon_acpi.h
index 7af1977..35202a4 100644
--- a/drivers/gpu/drm/radeon/radeon_acpi.h
+++ b/drivers/gpu/drm/radeon/radeon_acpi.h
@@ -27,9 +27,6 @@
struct radeon_device;
struct acpi_bus_event;
-int radeon_atif_handler(struct radeon_device *rdev,
- struct acpi_bus_event *event);
-
/* AMD hw uses four ACPI control methods:
* 1. ATIF
* ARG0: (ACPI_INTEGER) function code
diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c
index aaacac1..770e31f 100644
--- a/drivers/gpu/drm/radeon/radeon_audio.c
+++ b/drivers/gpu/drm/radeon/radeon_audio.c
@@ -516,7 +516,7 @@ static int radeon_audio_set_avi_packet(struct drm_encoder *encoder,
if (!connector)
return -EINVAL;
- err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+ err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
if (err < 0) {
DRM_ERROR("failed to setup AVI infoframe: %d\n", err);
return err;
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 27affbd..2f642cb 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -773,12 +773,15 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct
if (connector->encoder->crtc) {
struct drm_crtc *crtc = connector->encoder->crtc;
- const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
radeon_crtc->output_csc = radeon_encoder->output_csc;
- (*crtc_funcs->load_lut)(crtc);
+ /*
+ * Our .gamma_set assumes the .gamma_store has been
+ * prefilled and don't care about its arguments.
+ */
+ crtc->funcs->gamma_set(crtc, NULL, NULL, NULL, 0, NULL);
}
}
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
index 00b22af..1ae31db 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -130,7 +130,7 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
p->rdev->family == CHIP_RS880)) {
/* TODO: is this still needed for NI+ ? */
- p->relocs[i].prefered_domains =
+ p->relocs[i].preferred_domains =
RADEON_GEM_DOMAIN_VRAM;
p->relocs[i].allowed_domains =
@@ -148,14 +148,14 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
return -EINVAL;
}
- p->relocs[i].prefered_domains = domain;
+ p->relocs[i].preferred_domains = domain;
if (domain == RADEON_GEM_DOMAIN_VRAM)
domain |= RADEON_GEM_DOMAIN_GTT;
p->relocs[i].allowed_domains = domain;
}
if (radeon_ttm_tt_has_userptr(p->relocs[i].robj->tbo.ttm)) {
- uint32_t domain = p->relocs[i].prefered_domains;
+ uint32_t domain = p->relocs[i].preferred_domains;
if (!(domain & RADEON_GEM_DOMAIN_GTT)) {
DRM_ERROR("Only RADEON_GEM_DOMAIN_GTT is "
"allowed for userptr BOs\n");
@@ -163,7 +163,7 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
}
need_mmap_lock = true;
domain = RADEON_GEM_DOMAIN_GTT;
- p->relocs[i].prefered_domains = domain;
+ p->relocs[i].preferred_domains = domain;
p->relocs[i].allowed_domains = domain;
}
@@ -437,7 +437,7 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error, bo
if (bo == NULL)
continue;
- drm_gem_object_unreference_unlocked(&bo->gem_base);
+ drm_gem_object_put_unlocked(&bo->gem_base);
}
}
kfree(parser->track);
diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c
index 4a4f953..9195227 100644
--- a/drivers/gpu/drm/radeon/radeon_cursor.c
+++ b/drivers/gpu/drm/radeon/radeon_cursor.c
@@ -307,7 +307,7 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc,
robj = gem_to_radeon_bo(obj);
ret = radeon_bo_reserve(robj, false);
if (ret != 0) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
/* Only 27 bit offset for legacy cursor */
@@ -317,7 +317,7 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc,
radeon_bo_unreserve(robj);
if (ret) {
DRM_ERROR("Failed to pin new cursor BO (%d)\n", ret);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -352,7 +352,7 @@ unpin:
radeon_bo_unpin(robj);
radeon_bo_unreserve(robj);
}
- drm_gem_object_unreference_unlocked(radeon_crtc->cursor_bo);
+ drm_gem_object_put_unlocked(radeon_crtc->cursor_bo);
}
radeon_crtc->cursor_bo = obj;
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 17d3daf..ddfe91ef 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -42,6 +42,7 @@ static void avivo_crtc_load_lut(struct drm_crtc *crtc)
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
+ u16 *r, *g, *b;
int i;
DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id);
@@ -60,11 +61,14 @@ static void avivo_crtc_load_lut(struct drm_crtc *crtc)
WREG32(AVIVO_DC_LUT_WRITE_EN_MASK, 0x0000003f);
WREG8(AVIVO_DC_LUT_RW_INDEX, 0);
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
for (i = 0; i < 256; i++) {
WREG32(AVIVO_DC_LUT_30_COLOR,
- (radeon_crtc->lut_r[i] << 20) |
- (radeon_crtc->lut_g[i] << 10) |
- (radeon_crtc->lut_b[i] << 0));
+ ((*r++ & 0xffc0) << 14) |
+ ((*g++ & 0xffc0) << 4) |
+ (*b++ >> 6));
}
/* Only change bit 0 of LUT_SEL, other bits are set elsewhere */
@@ -76,6 +80,7 @@ static void dce4_crtc_load_lut(struct drm_crtc *crtc)
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
+ u16 *r, *g, *b;
int i;
DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id);
@@ -93,11 +98,14 @@ static void dce4_crtc_load_lut(struct drm_crtc *crtc)
WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007);
WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0);
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
for (i = 0; i < 256; i++) {
WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset,
- (radeon_crtc->lut_r[i] << 20) |
- (radeon_crtc->lut_g[i] << 10) |
- (radeon_crtc->lut_b[i] << 0));
+ ((*r++ & 0xffc0) << 14) |
+ ((*g++ & 0xffc0) << 4) |
+ (*b++ >> 6));
}
}
@@ -106,6 +114,7 @@ static void dce5_crtc_load_lut(struct drm_crtc *crtc)
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
+ u16 *r, *g, *b;
int i;
DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id);
@@ -135,11 +144,14 @@ static void dce5_crtc_load_lut(struct drm_crtc *crtc)
WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007);
WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0);
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
for (i = 0; i < 256; i++) {
WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset,
- (radeon_crtc->lut_r[i] << 20) |
- (radeon_crtc->lut_g[i] << 10) |
- (radeon_crtc->lut_b[i] << 0));
+ ((*r++ & 0xffc0) << 14) |
+ ((*g++ & 0xffc0) << 4) |
+ (*b++ >> 6));
}
WREG32(NI_DEGAMMA_CONTROL + radeon_crtc->crtc_offset,
@@ -172,6 +184,7 @@ static void legacy_crtc_load_lut(struct drm_crtc *crtc)
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
+ u16 *r, *g, *b;
int i;
uint32_t dac2_cntl;
@@ -183,11 +196,14 @@ static void legacy_crtc_load_lut(struct drm_crtc *crtc)
WREG32(RADEON_DAC_CNTL2, dac2_cntl);
WREG8(RADEON_PALETTE_INDEX, 0);
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
for (i = 0; i < 256; i++) {
WREG32(RADEON_PALETTE_30_DATA,
- (radeon_crtc->lut_r[i] << 20) |
- (radeon_crtc->lut_g[i] << 10) |
- (radeon_crtc->lut_b[i] << 0));
+ ((*r++ & 0xffc0) << 14) |
+ ((*g++ & 0xffc0) << 4) |
+ (*b++ >> 6));
}
}
@@ -209,41 +225,10 @@ void radeon_crtc_load_lut(struct drm_crtc *crtc)
legacy_crtc_load_lut(crtc);
}
-/** Sets the color ramps on behalf of fbcon */
-void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno)
-{
- struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
-
- radeon_crtc->lut_r[regno] = red >> 6;
- radeon_crtc->lut_g[regno] = green >> 6;
- radeon_crtc->lut_b[regno] = blue >> 6;
-}
-
-/** Gets the color ramps on behalf of fbcon */
-void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
- u16 *blue, int regno)
-{
- struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
-
- *red = radeon_crtc->lut_r[regno] << 6;
- *green = radeon_crtc->lut_g[regno] << 6;
- *blue = radeon_crtc->lut_b[regno] << 6;
-}
-
static int radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
u16 *blue, uint32_t size,
struct drm_modeset_acquire_ctx *ctx)
{
- struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
- int i;
-
- /* userspace palettes are always correct as is */
- for (i = 0; i < size; i++) {
- radeon_crtc->lut_r[i] = red[i] >> 6;
- radeon_crtc->lut_g[i] = green[i] >> 6;
- radeon_crtc->lut_b[i] = blue[i] >> 6;
- }
radeon_crtc_load_lut(crtc);
return 0;
@@ -282,7 +267,7 @@ static void radeon_unpin_work_func(struct work_struct *__work)
} else
DRM_ERROR("failed to reserve buffer after flip\n");
- drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
+ drm_gem_object_put_unlocked(&work->old_rbo->gem_base);
kfree(work);
}
@@ -519,7 +504,7 @@ static int radeon_crtc_page_flip_target(struct drm_crtc *crtc,
obj = old_radeon_fb->obj;
/* take a reference to the old object */
- drm_gem_object_reference(obj);
+ drm_gem_object_get(obj);
work->old_rbo = gem_to_radeon_bo(obj);
new_radeon_fb = to_radeon_framebuffer(fb);
@@ -618,7 +603,7 @@ pflip_cleanup:
radeon_bo_unreserve(new_rbo);
cleanup:
- drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
+ drm_gem_object_put_unlocked(&work->old_rbo->gem_base);
dma_fence_put(work->fence);
kfree(work);
return r;
@@ -1303,7 +1288,7 @@ static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb)
{
struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb);
- drm_gem_object_unreference_unlocked(radeon_fb->obj);
+ drm_gem_object_put_unlocked(radeon_fb->obj);
drm_framebuffer_cleanup(fb);
kfree(radeon_fb);
}
@@ -1363,14 +1348,14 @@ radeon_user_framebuffer_create(struct drm_device *dev,
radeon_fb = kzalloc(sizeof(*radeon_fb), GFP_KERNEL);
if (radeon_fb == NULL) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ERR_PTR(-ENOMEM);
}
ret = radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj);
if (ret) {
kfree(radeon_fb);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ERR_PTR(ret);
}
@@ -1388,12 +1373,12 @@ static const struct drm_mode_config_funcs radeon_mode_funcs = {
.output_poll_changed = radeon_output_poll_changed
};
-static struct drm_prop_enum_list radeon_tmds_pll_enum_list[] =
+static const struct drm_prop_enum_list radeon_tmds_pll_enum_list[] =
{ { 0, "driver" },
{ 1, "bios" },
};
-static struct drm_prop_enum_list radeon_tv_std_enum_list[] =
+static const struct drm_prop_enum_list radeon_tv_std_enum_list[] =
{ { TV_STD_NTSC, "ntsc" },
{ TV_STD_PAL, "pal" },
{ TV_STD_PAL_M, "pal-m" },
@@ -1404,25 +1389,25 @@ static struct drm_prop_enum_list radeon_tv_std_enum_list[] =
{ TV_STD_SECAM, "secam" },
};
-static struct drm_prop_enum_list radeon_underscan_enum_list[] =
+static const struct drm_prop_enum_list radeon_underscan_enum_list[] =
{ { UNDERSCAN_OFF, "off" },
{ UNDERSCAN_ON, "on" },
{ UNDERSCAN_AUTO, "auto" },
};
-static struct drm_prop_enum_list radeon_audio_enum_list[] =
+static const struct drm_prop_enum_list radeon_audio_enum_list[] =
{ { RADEON_AUDIO_DISABLE, "off" },
{ RADEON_AUDIO_ENABLE, "on" },
{ RADEON_AUDIO_AUTO, "auto" },
};
/* XXX support different dither options? spatial, temporal, both, etc. */
-static struct drm_prop_enum_list radeon_dither_enum_list[] =
+static const struct drm_prop_enum_list radeon_dither_enum_list[] =
{ { RADEON_FMT_DITHER_DISABLE, "off" },
{ RADEON_FMT_DITHER_ENABLE, "on" },
};
-static struct drm_prop_enum_list radeon_output_csc_enum_list[] =
+static const struct drm_prop_enum_list radeon_output_csc_enum_list[] =
{ { RADEON_OUTPUT_CSC_BYPASS, "bypass" },
{ RADEON_OUTPUT_CSC_TVRGB, "tvrgb" },
{ RADEON_OUTPUT_CSC_YCBCR601, "ycbcr601" },
diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c
index 6598306..ebdf1b8 100644
--- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
+++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
@@ -300,9 +300,7 @@ static void radeon_dp_register_mst_connector(struct drm_connector *connector)
struct drm_device *dev = connector->dev;
struct radeon_device *rdev = dev->dev_private;
- drm_modeset_lock_all(dev);
radeon_fb_add_connector(rdev, connector);
- drm_modeset_unlock_all(dev);
drm_connector_register(connector);
}
@@ -315,13 +313,8 @@ static void radeon_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
struct radeon_device *rdev = dev->dev_private;
drm_connector_unregister(connector);
- /* need to nuke the connector */
- drm_modeset_lock_all(dev);
- /* dpms off */
radeon_fb_remove_connector(rdev, connector);
-
drm_connector_cleanup(connector);
- drm_modeset_unlock_all(dev);
kfree(connector);
DRM_DEBUG_KMS("\n");
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 74abd16..f4becad 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -567,7 +567,6 @@ static struct drm_driver kms_driver = {
.open = radeon_driver_open_kms,
.postclose = radeon_driver_postclose_kms,
.lastclose = radeon_driver_lastclose_kms,
- .set_busid = drm_pci_set_busid,
.unload = radeon_driver_unload_kms,
.get_vblank_counter = radeon_get_vblank_counter_kms,
.enable_vblank = radeon_enable_vblank_kms,
@@ -584,7 +583,6 @@ static struct drm_driver kms_driver = {
.gem_close_object = radeon_gem_object_close,
.dumb_create = radeon_mode_dumb_create,
.dumb_map_offset = radeon_mode_dumb_mmap,
- .dumb_destroy = drm_gem_dumb_destroy,
.fops = &radeon_driver_kms_fops,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
@@ -642,14 +640,13 @@ static int __init radeon_init(void)
return -EINVAL;
}
- /* let modprobe override vga console setting */
- return drm_pci_init(driver, pdriver);
+ return pci_register_driver(pdriver);
}
static void __exit radeon_exit(void)
{
radeon_kfd_fini();
- drm_pci_exit(driver, pdriver);
+ pci_unregister_driver(pdriver);
radeon_unregister_atpx_handler();
}
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index 356ad90..fd25361 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -118,7 +118,7 @@ static void radeonfb_destroy_pinned_object(struct drm_gem_object *gobj)
radeon_bo_unpin(rbo);
radeon_bo_unreserve(rbo);
}
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
}
static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev,
@@ -264,7 +264,6 @@ static int radeonfb_create(struct drm_fb_helper *helper,
drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth);
- info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
info->fbops = &radeonfb_ops;
tmp = radeon_bo_gpu_offset(rbo) - rdev->mc.vram_start;
@@ -300,7 +299,7 @@ out:
}
if (fb && ret) {
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
drm_framebuffer_unregister_private(fb);
drm_framebuffer_cleanup(fb);
kfree(fb);
@@ -332,8 +331,6 @@ static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfb
}
static const struct drm_fb_helper_funcs radeon_fb_helper_funcs = {
- .gamma_set = radeon_crtc_fb_gamma_set,
- .gamma_get = radeon_crtc_fb_gamma_get,
.fb_probe = radeonfb_create,
};
@@ -347,9 +344,12 @@ int radeon_fbdev_init(struct radeon_device *rdev)
if (list_empty(&rdev->ddev->mode_config.connector_list))
return 0;
- /* select 8 bpp console on RN50 or 16MB cards */
- if (ASIC_IS_RN50(rdev) || rdev->mc.real_vram_size <= (32*1024*1024))
+ /* select 8 bpp console on 8MB cards, or 16 bpp on RN50 or 32MB */
+ if (rdev->mc.real_vram_size <= (8*1024*1024))
bpp_sel = 8;
+ else if (ASIC_IS_RN50(rdev) ||
+ rdev->mc.real_vram_size <= (32*1024*1024))
+ bpp_sel = 16;
rfbdev = kzalloc(sizeof(struct radeon_fbdev), GFP_KERNEL);
if (!rfbdev)
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c
index 574bf7e..3386452 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -271,7 +271,7 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data,
}
r = drm_gem_handle_create(filp, gobj, &handle);
/* drop reference from allocate - handle holds it now */
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
if (r) {
up_read(&rdev->exclusive_lock);
r = radeon_gem_handle_lockup(rdev, r);
@@ -352,7 +352,7 @@ int radeon_gem_userptr_ioctl(struct drm_device *dev, void *data,
r = drm_gem_handle_create(filp, gobj, &handle);
/* drop reference from allocate - handle holds it now */
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
if (r)
goto handle_lockup;
@@ -361,7 +361,7 @@ int radeon_gem_userptr_ioctl(struct drm_device *dev, void *data,
return 0;
release_object:
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
handle_lockup:
up_read(&rdev->exclusive_lock);
@@ -395,7 +395,7 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data,
r = radeon_gem_set_domain(gobj, args->read_domains, args->write_domain);
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
up_read(&rdev->exclusive_lock);
r = radeon_gem_handle_lockup(robj->rdev, r);
return r;
@@ -414,11 +414,11 @@ int radeon_mode_dumb_mmap(struct drm_file *filp,
}
robj = gem_to_radeon_bo(gobj);
if (radeon_ttm_tt_has_userptr(robj->tbo.ttm)) {
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return -EPERM;
}
*offset_p = radeon_bo_mmap_offset(robj);
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return 0;
}
@@ -453,7 +453,7 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data,
cur_placement = ACCESS_ONCE(robj->tbo.mem.mem_type);
args->domain = radeon_mem_type_to_domain(cur_placement);
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return r;
}
@@ -485,7 +485,7 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data,
if (rdev->asic->mmio_hdp_flush &&
radeon_mem_type_to_domain(cur_placement) == RADEON_GEM_DOMAIN_VRAM)
robj->rdev->asic->mmio_hdp_flush(rdev);
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
r = radeon_gem_handle_lockup(rdev, r);
return r;
}
@@ -504,7 +504,7 @@ int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data,
return -ENOENT;
robj = gem_to_radeon_bo(gobj);
r = radeon_bo_set_tiling_flags(robj, args->tiling_flags, args->pitch);
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return r;
}
@@ -527,7 +527,7 @@ int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data,
radeon_bo_get_tiling_flags(rbo, &args->tiling_flags, &args->pitch);
radeon_bo_unreserve(rbo);
out:
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return r;
}
@@ -661,14 +661,14 @@ int radeon_gem_va_ioctl(struct drm_device *dev, void *data,
r = radeon_bo_reserve(rbo, false);
if (r) {
args->operation = RADEON_VA_RESULT_ERROR;
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return r;
}
bo_va = radeon_vm_bo_find(&fpriv->vm, rbo);
if (!bo_va) {
args->operation = RADEON_VA_RESULT_ERROR;
radeon_bo_unreserve(rbo);
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return -ENOENT;
}
@@ -695,7 +695,7 @@ int radeon_gem_va_ioctl(struct drm_device *dev, void *data,
args->operation = RADEON_VA_RESULT_ERROR;
}
out:
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return r;
}
@@ -736,7 +736,7 @@ int radeon_gem_op_ioctl(struct drm_device *dev, void *data,
radeon_bo_unreserve(robj);
out:
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return r;
}
@@ -762,7 +762,7 @@ int radeon_mode_dumb_create(struct drm_file *file_priv,
r = drm_gem_handle_create(file_priv, gobj, &handle);
/* drop reference from allocate - handle holds it now */
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
if (r) {
return r;
}
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
index 7aacb44..afaf10d 100644
--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -283,6 +283,10 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
int r = 0;
spin_lock_init(&rdev->irq.lock);
+
+ /* Disable vblank irqs aggressively for power-saving */
+ rdev->ddev->vblank_disable_immediate = true;
+
r = drm_vblank_init(rdev->ddev, rdev->num_crtc);
if (r) {
return r;
@@ -324,7 +328,6 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
*/
void radeon_irq_kms_fini(struct radeon_device *rdev)
{
- drm_vblank_cleanup(rdev->ddev);
if (rdev->irq.installed) {
drm_irq_uninstall(rdev->ddev);
rdev->irq.installed = false;
diff --git a/drivers/gpu/drm/radeon/radeon_kfd.c b/drivers/gpu/drm/radeon/radeon_kfd.c
index a2ab6dc..f6578c9 100644
--- a/drivers/gpu/drm/radeon/radeon_kfd.c
+++ b/drivers/gpu/drm/radeon/radeon_kfd.c
@@ -75,12 +75,14 @@ static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id,
uint32_t hpd_size, uint64_t hpd_gpu_addr);
static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id);
static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
- uint32_t queue_id, uint32_t __user *wptr);
+ uint32_t queue_id, uint32_t __user *wptr,
+ uint32_t wptr_shift, uint32_t wptr_mask,
+ struct mm_struct *mm);
static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd);
static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
uint32_t pipe_id, uint32_t queue_id);
-static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
+static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd, uint32_t reset_type,
unsigned int timeout, uint32_t pipe_id,
uint32_t queue_id);
static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd);
@@ -482,7 +484,9 @@ static inline struct cik_sdma_rlc_registers *get_sdma_mqd(void *mqd)
}
static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
- uint32_t queue_id, uint32_t __user *wptr)
+ uint32_t queue_id, uint32_t __user *wptr,
+ uint32_t wptr_shift, uint32_t wptr_mask,
+ struct mm_struct *mm)
{
uint32_t wptr_shadow, is_wptr_shadow_valid;
struct cik_mqd *m;
@@ -636,7 +640,7 @@ static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd)
return false;
}
-static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
+static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd, uint32_t reset_type,
unsigned int timeout, uint32_t pipe_id,
uint32_t queue_id)
{
@@ -785,7 +789,8 @@ static uint32_t kgd_address_watch_get_offset(struct kgd_dev *kgd,
unsigned int watch_point_id,
unsigned int reg_offset)
{
- return watchRegs[watch_point_id * ADDRESS_WATCH_REG_MAX + reg_offset];
+ return watchRegs[watch_point_id * ADDRESS_WATCH_REG_MAX + reg_offset]
+ / 4;
}
static bool get_atc_vmid_pasid_mapping_valid(struct kgd_dev *kgd, uint8_t vmid)
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
index ce6cb66..1f1856e 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
@@ -1116,7 +1116,6 @@ static const struct drm_crtc_helper_funcs legacy_helper_funcs = {
.mode_set_base_atomic = radeon_crtc_set_base_atomic,
.prepare = radeon_crtc_prepare,
.commit = radeon_crtc_commit,
- .load_lut = radeon_crtc_load_lut,
.disable = radeon_crtc_disable
};
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 00f5ec5..da44ac2 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -935,10 +935,6 @@ extern void
radeon_combios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc);
extern void
radeon_combios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on);
-extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno);
-extern void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
- u16 *blue, int regno);
int radeon_framebuffer_init(struct drm_device *dev,
struct radeon_framebuffer *rfb,
const struct drm_mode_fb_cmd2 *mode_cmd,
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index 8b72229..0935949 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -445,7 +445,7 @@ void radeon_bo_force_delete(struct radeon_device *rdev)
list_del_init(&bo->list);
mutex_unlock(&bo->rdev->gem.mutex);
/* this should unref the ttm bo */
- drm_gem_object_unreference_unlocked(&bo->gem_base);
+ drm_gem_object_put_unlocked(&bo->gem_base);
}
}
@@ -546,7 +546,7 @@ int radeon_bo_list_validate(struct radeon_device *rdev,
list_for_each_entry(lobj, head, tv.head) {
struct radeon_bo *bo = lobj->robj;
if (!bo->pin_count) {
- u32 domain = lobj->prefered_domains;
+ u32 domain = lobj->preferred_domains;
u32 allowed = lobj->allowed_domains;
u32 current_domain =
radeon_mem_type_to_domain(bo->tbo.mem.mem_type);
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index faa0213..bf69bf9 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -178,7 +178,7 @@ static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
static void radeon_evict_flags(struct ttm_buffer_object *bo,
struct ttm_placement *placement)
{
- static struct ttm_place placements = {
+ static const struct ttm_place placements = {
.fpfn = 0,
.lpfn = 0,
.flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM
@@ -907,17 +907,17 @@ int radeon_ttm_init(struct radeon_device *rdev)
r = radeon_bo_create(rdev, 256 * 1024, PAGE_SIZE, true,
RADEON_GEM_DOMAIN_VRAM, 0, NULL,
- NULL, &rdev->stollen_vga_memory);
+ NULL, &rdev->stolen_vga_memory);
if (r) {
return r;
}
- r = radeon_bo_reserve(rdev->stollen_vga_memory, false);
+ r = radeon_bo_reserve(rdev->stolen_vga_memory, false);
if (r)
return r;
- r = radeon_bo_pin(rdev->stollen_vga_memory, RADEON_GEM_DOMAIN_VRAM, NULL);
- radeon_bo_unreserve(rdev->stollen_vga_memory);
+ r = radeon_bo_pin(rdev->stolen_vga_memory, RADEON_GEM_DOMAIN_VRAM, NULL);
+ radeon_bo_unreserve(rdev->stolen_vga_memory);
if (r) {
- radeon_bo_unref(&rdev->stollen_vga_memory);
+ radeon_bo_unref(&rdev->stolen_vga_memory);
return r;
}
DRM_INFO("radeon: %uM of VRAM memory ready\n",
@@ -946,13 +946,13 @@ void radeon_ttm_fini(struct radeon_device *rdev)
if (!rdev->mman.initialized)
return;
radeon_ttm_debugfs_fini(rdev);
- if (rdev->stollen_vga_memory) {
- r = radeon_bo_reserve(rdev->stollen_vga_memory, false);
+ if (rdev->stolen_vga_memory) {
+ r = radeon_bo_reserve(rdev->stolen_vga_memory, false);
if (r == 0) {
- radeon_bo_unpin(rdev->stollen_vga_memory);
- radeon_bo_unreserve(rdev->stollen_vga_memory);
+ radeon_bo_unpin(rdev->stolen_vga_memory);
+ radeon_bo_unreserve(rdev->stolen_vga_memory);
}
- radeon_bo_unref(&rdev->stollen_vga_memory);
+ radeon_bo_unref(&rdev->stolen_vga_memory);
}
ttm_bo_clean_mm(&rdev->mman.bdev, TTM_PL_VRAM);
ttm_bo_clean_mm(&rdev->mman.bdev, TTM_PL_TT);
@@ -1030,19 +1030,17 @@ int radeon_mmap(struct file *filp, struct vm_area_struct *vma)
static int radeon_mm_dump_table(struct seq_file *m, void *data)
{
struct drm_info_node *node = (struct drm_info_node *)m->private;
- unsigned ttm_pl = *(int *)node->info_ent->data;
+ unsigned ttm_pl = *(int*)node->info_ent->data;
struct drm_device *dev = node->minor->dev;
struct radeon_device *rdev = dev->dev_private;
- struct drm_mm *mm = (struct drm_mm *)rdev->mman.bdev.man[ttm_pl].priv;
- struct ttm_bo_global *glob = rdev->mman.bdev.glob;
+ struct ttm_mem_type_manager *man = &rdev->mman.bdev.man[ttm_pl];
struct drm_printer p = drm_seq_file_printer(m);
- spin_lock(&glob->lru_lock);
- drm_mm_print(mm, &p);
- spin_unlock(&glob->lru_lock);
+ man->func->debug(man, &p);
return 0;
}
+
static int ttm_pl_vram = TTM_PL_VRAM;
static int ttm_pl_tt = TTM_PL_TT;
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c
index 5f68245..5e82b40 100644
--- a/drivers/gpu/drm/radeon/radeon_vm.c
+++ b/drivers/gpu/drm/radeon/radeon_vm.c
@@ -139,7 +139,7 @@ struct radeon_bo_list *radeon_vm_get_bos(struct radeon_device *rdev,
/* add the vm page table to the list */
list[0].robj = vm->page_directory;
- list[0].prefered_domains = RADEON_GEM_DOMAIN_VRAM;
+ list[0].preferred_domains = RADEON_GEM_DOMAIN_VRAM;
list[0].allowed_domains = RADEON_GEM_DOMAIN_VRAM;
list[0].tv.bo = &vm->page_directory->tbo;
list[0].tv.shared = true;
@@ -151,7 +151,7 @@ struct radeon_bo_list *radeon_vm_get_bos(struct radeon_device *rdev,
continue;
list[idx].robj = vm->page_tables[i].bo;
- list[idx].prefered_domains = RADEON_GEM_DOMAIN_VRAM;
+ list[idx].preferred_domains = RADEON_GEM_DOMAIN_VRAM;
list[idx].allowed_domains = RADEON_GEM_DOMAIN_VRAM;
list[idx].tv.bo = &list[idx].robj->tbo;
list[idx].tv.shared = true;
diff --git a/drivers/gpu/drm/radeon/vce_v2_0.c b/drivers/gpu/drm/radeon/vce_v2_0.c
index fce2144..b0a43b6 100644
--- a/drivers/gpu/drm/radeon/vce_v2_0.c
+++ b/drivers/gpu/drm/radeon/vce_v2_0.c
@@ -104,6 +104,10 @@ static void vce_v2_0_disable_cg(struct radeon_device *rdev)
WREG32(VCE_CGTT_CLK_OVERRIDE, 7);
}
+/*
+ * Local variable sw_cg is used for debugging purposes, in case we
+ * ran into problems with dynamic clock gating. Don't remove it.
+ */
void vce_v2_0_enable_mgcg(struct radeon_device *rdev, bool enable)
{
bool sw_cg = false;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 345eff7..301ea1a 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -13,6 +13,7 @@
#include <linux/clk.h>
#include <linux/mutex.h>
+#include <linux/sys_soc.h>
#include <drm/drmP.h>
#include <drm/drm_atomic.h>
@@ -129,10 +130,8 @@ static void rcar_du_dpll_divider(struct rcar_du_crtc *rcrtc,
for (fdpll = 1; fdpll < 32; fdpll++) {
unsigned long output;
- /* 1/2 (FRQSEL=1) for duty rate 50% */
output = input * (n + 1) / (m + 1)
- / (fdpll + 1) / 2;
-
+ / (fdpll + 1);
if (output >= 400000000)
continue;
@@ -158,6 +157,11 @@ done:
best_diff);
}
+static const struct soc_device_attribute rcar_du_r8a7795_es1[] = {
+ { .soc_id = "r8a7795", .revision = "ES1.*" },
+ { /* sentinel */ }
+};
+
static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
{
const struct drm_display_mode *mode = &rcrtc->crtc.state->adjusted_mode;
@@ -168,7 +172,8 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
u32 escr;
u32 div;
- /* Compute the clock divisor and select the internal or external dot
+ /*
+ * Compute the clock divisor and select the internal or external dot
* clock based on the requested frequency.
*/
clk = clk_get_rate(rcrtc->clock);
@@ -185,7 +190,20 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
extclk = clk_get_rate(rcrtc->extclock);
if (rcdu->info->dpll_ch & (1 << rcrtc->index)) {
- rcar_du_dpll_divider(rcrtc, &dpll, extclk, mode_clock);
+ unsigned long target = mode_clock;
+
+ /*
+ * The H3 ES1.x exhibits dot clock duty cycle stability
+ * issues. We can work around them by configuring the
+ * DPLL to twice the desired frequency, coupled with a
+ * /2 post-divider. This isn't needed on other SoCs and
+ * breaks HDMI output on M3-W for a currently unknown
+ * reason, so restrict the workaround to H3 ES1.x.
+ */
+ if (soc_device_match(rcar_du_r8a7795_es1))
+ target *= 2;
+
+ rcar_du_dpll_divider(rcrtc, &dpll, extclk, target);
extclk = dpll.output;
}
@@ -197,8 +215,6 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
if (abs((long)extrate - (long)mode_clock) <
abs((long)rate - (long)mode_clock)) {
- dev_dbg(rcrtc->group->dev->dev,
- "crtc%u: using external clock\n", rcrtc->index);
if (rcdu->info->dpll_ch & (1 << rcrtc->index)) {
u32 dpllcr = DPLLCR_CODE | DPLLCR_CLKE
@@ -215,12 +231,14 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
rcar_du_group_write(rcrtc->group, DPLLCR,
dpllcr);
-
- escr = ESCR_DCLKSEL_DCLKIN | 1;
- } else {
- escr = ESCR_DCLKSEL_DCLKIN | extdiv;
}
+
+ escr = ESCR_DCLKSEL_DCLKIN | extdiv;
}
+
+ dev_dbg(rcrtc->group->dev->dev,
+ "mode clock %lu extrate %lu rate %lu ESCR 0x%08x\n",
+ mode_clock, extrate, rate, escr);
}
rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? ESCR2 : ESCR,
@@ -261,12 +279,14 @@ void rcar_du_crtc_route_output(struct drm_crtc *crtc,
struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
struct rcar_du_device *rcdu = rcrtc->group->dev;
- /* Store the route from the CRTC output to the DU output. The DU will be
+ /*
+ * Store the route from the CRTC output to the DU output. The DU will be
* configured when starting the CRTC.
*/
rcrtc->outputs |= BIT(output);
- /* Store RGB routing to DPAD0, the hardware will be configured when
+ /*
+ * Store RGB routing to DPAD0, the hardware will be configured when
* starting the CRTC.
*/
if (output == RCAR_DU_OUTPUT_DPAD0)
@@ -342,7 +362,8 @@ static void rcar_du_crtc_update_planes(struct rcar_du_crtc *rcrtc)
}
}
- /* Update the planes to display timing and dot clock generator
+ /*
+ * Update the planes to display timing and dot clock generator
* associations.
*
* Updating the DPTSR register requires restarting the CRTC group,
@@ -431,14 +452,8 @@ static void rcar_du_crtc_wait_page_flip(struct rcar_du_crtc *rcrtc)
* Start/Stop and Suspend/Resume
*/
-static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
+static void rcar_du_crtc_setup(struct rcar_du_crtc *rcrtc)
{
- struct drm_crtc *crtc = &rcrtc->crtc;
- bool interlaced;
-
- if (rcrtc->started)
- return;
-
/* Set display off and background to black */
rcar_du_crtc_write(rcrtc, DOOR, DOOR_RGB(0, 0, 0));
rcar_du_crtc_write(rcrtc, BPOR, BPOR_RGB(0, 0, 0));
@@ -450,7 +465,20 @@ static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
/* Start with all planes disabled. */
rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, 0);
- /* Select master sync mode. This enables display operation in master
+ /* Enable the VSP compositor. */
+ if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
+ rcar_du_vsp_enable(rcrtc);
+
+ /* Turn vertical blanking interrupt reporting on. */
+ drm_crtc_vblank_on(&rcrtc->crtc);
+}
+
+static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
+{
+ bool interlaced;
+
+ /*
+ * Select master sync mode. This enables display operation in master
* sync mode (with the HSYNC and VSYNC signals configured as outputs and
* actively driven).
*/
@@ -460,38 +488,56 @@ static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
DSYSR_TVM_MASTER);
rcar_du_group_start_stop(rcrtc->group, true);
+}
- /* Enable the VSP compositor. */
- if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
- rcar_du_vsp_enable(rcrtc);
+static void rcar_du_crtc_disable_planes(struct rcar_du_crtc *rcrtc)
+{
+ struct rcar_du_device *rcdu = rcrtc->group->dev;
+ struct drm_crtc *crtc = &rcrtc->crtc;
+ u32 status;
- /* Turn vertical blanking interrupt reporting back on. */
- drm_crtc_vblank_on(crtc);
+ /* Make sure vblank interrupts are enabled. */
+ drm_crtc_vblank_get(crtc);
- rcrtc->started = true;
+ /*
+ * Disable planes and calculate how many vertical blanking interrupts we
+ * have to wait for. If a vertical blanking interrupt has been triggered
+ * but not processed yet, we don't know whether it occurred before or
+ * after the planes got disabled. We thus have to wait for two vblank
+ * interrupts in that case.
+ */
+ spin_lock_irq(&rcrtc->vblank_lock);
+ rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, 0);
+ status = rcar_du_crtc_read(rcrtc, DSSR);
+ rcrtc->vblank_count = status & DSSR_VBK ? 2 : 1;
+ spin_unlock_irq(&rcrtc->vblank_lock);
+
+ if (!wait_event_timeout(rcrtc->vblank_wait, rcrtc->vblank_count == 0,
+ msecs_to_jiffies(100)))
+ dev_warn(rcdu->dev, "vertical blanking timeout\n");
+
+ drm_crtc_vblank_put(crtc);
}
static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc)
{
struct drm_crtc *crtc = &rcrtc->crtc;
- if (!rcrtc->started)
- return;
-
- /* Disable all planes and wait for the change to take effect. This is
- * required as the DSnPR registers are updated on vblank, and no vblank
- * will occur once the CRTC is stopped. Disabling planes when starting
- * the CRTC thus wouldn't be enough as it would start scanning out
- * immediately from old frame buffers until the next vblank.
+ /*
+ * Disable all planes and wait for the change to take effect. This is
+ * required as the plane enable registers are updated on vblank, and no
+ * vblank will occur once the CRTC is stopped. Disabling planes when
+ * starting the CRTC thus wouldn't be enough as it would start scanning
+ * out immediately from old frame buffers until the next vblank.
*
* This increases the CRTC stop delay, especially when multiple CRTCs
* are stopped in one operation as we now wait for one vblank per CRTC.
* Whether this can be improved needs to be researched.
*/
- rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, 0);
- drm_crtc_wait_one_vblank(crtc);
+ rcar_du_crtc_disable_planes(rcrtc);
- /* Disable vertical blanking interrupt reporting. We first need to wait
+ /*
+ * Disable vertical blanking interrupt reporting. We first need to wait
* for page flip completion before stopping the CRTC as userspace
* expects page flips to eventually complete.
*/
@@ -502,14 +548,13 @@ static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc)
if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
rcar_du_vsp_disable(rcrtc);
- /* Select switch sync mode. This stops display operation and configures
+ /*
+ * Select switch sync mode. This stops display operation and configures
* the HSYNC and VSYNC signals as inputs.
*/
rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK, DSYSR_TVM_SWITCH);
rcar_du_group_start_stop(rcrtc->group, false);
-
- rcrtc->started = false;
}
void rcar_du_crtc_suspend(struct rcar_du_crtc *rcrtc)
@@ -529,12 +574,10 @@ void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc)
return;
rcar_du_crtc_get(rcrtc);
- rcar_du_crtc_start(rcrtc);
+ rcar_du_crtc_setup(rcrtc);
/* Commit the planes state. */
- if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE)) {
- rcar_du_vsp_enable(rcrtc);
- } else {
+ if (!rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE)) {
for (i = 0; i < rcrtc->group->num_planes; ++i) {
struct rcar_du_plane *plane = &rcrtc->group->planes[i];
@@ -546,21 +589,33 @@ void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc)
}
rcar_du_crtc_update_planes(rcrtc);
+ rcar_du_crtc_start(rcrtc);
}
/* -----------------------------------------------------------------------------
* CRTC Functions
*/
-static void rcar_du_crtc_enable(struct drm_crtc *crtc)
+static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
- rcar_du_crtc_get(rcrtc);
+ /*
+ * If the CRTC has already been setup by the .atomic_begin() handler we
+ * can skip the setup stage.
+ */
+ if (!rcrtc->initialized) {
+ rcar_du_crtc_get(rcrtc);
+ rcar_du_crtc_setup(rcrtc);
+ rcrtc->initialized = true;
+ }
+
rcar_du_crtc_start(rcrtc);
}
-static void rcar_du_crtc_disable(struct drm_crtc *crtc)
+static void rcar_du_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
@@ -574,6 +629,7 @@ static void rcar_du_crtc_disable(struct drm_crtc *crtc)
}
spin_unlock_irq(&crtc->dev->event_lock);
+ rcrtc->initialized = false;
rcrtc->outputs = 0;
}
@@ -582,6 +638,19 @@ static void rcar_du_crtc_atomic_begin(struct drm_crtc *crtc,
{
struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
+ WARN_ON(!crtc->state->enable);
+
+ /*
+ * If a mode set is in progress we can be called with the CRTC disabled.
+ * We then need to first setup the CRTC in order to configure planes.
+ * The .atomic_enable() handler will notice and skip the CRTC setup.
+ */
+ if (!rcrtc->initialized) {
+ rcar_du_crtc_get(rcrtc);
+ rcar_du_crtc_setup(rcrtc);
+ rcrtc->initialized = true;
+ }
+
if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
rcar_du_vsp_atomic_begin(rcrtc);
}
@@ -609,10 +678,10 @@ static void rcar_du_crtc_atomic_flush(struct drm_crtc *crtc,
}
static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
- .disable = rcar_du_crtc_disable,
- .enable = rcar_du_crtc_enable,
.atomic_begin = rcar_du_crtc_atomic_begin,
.atomic_flush = rcar_du_crtc_atomic_flush,
+ .atomic_enable = rcar_du_crtc_atomic_enable,
+ .atomic_disable = rcar_du_crtc_atomic_disable,
};
static int rcar_du_crtc_enable_vblank(struct drm_crtc *crtc)
@@ -621,6 +690,7 @@ static int rcar_du_crtc_enable_vblank(struct drm_crtc *crtc)
rcar_du_crtc_write(rcrtc, DSRCR, DSRCR_VBCL);
rcar_du_crtc_set(rcrtc, DIER, DIER_VBE);
+ rcrtc->vblank_enable = true;
return 0;
}
@@ -630,6 +700,7 @@ static void rcar_du_crtc_disable_vblank(struct drm_crtc *crtc)
struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
rcar_du_crtc_clr(rcrtc, DIER, DIER_VBE);
+ rcrtc->vblank_enable = false;
}
static const struct drm_crtc_funcs crtc_funcs = {
@@ -654,14 +725,30 @@ static irqreturn_t rcar_du_crtc_irq(int irq, void *arg)
irqreturn_t ret = IRQ_NONE;
u32 status;
+ spin_lock(&rcrtc->vblank_lock);
+
status = rcar_du_crtc_read(rcrtc, DSSR);
rcar_du_crtc_write(rcrtc, DSRCR, status & DSRCR_MASK);
- if (status & DSSR_FRM) {
- drm_crtc_handle_vblank(&rcrtc->crtc);
+ if (status & DSSR_VBK) {
+ /*
+ * Wake up the vblank wait if the counter reaches 0. This must
+ * be protected by the vblank_lock to avoid races in
+ * rcar_du_crtc_disable_planes().
+ */
+ if (rcrtc->vblank_count) {
+ if (--rcrtc->vblank_count == 0)
+ wake_up(&rcrtc->vblank_wait);
+ }
+ }
- if (rcdu->info->gen < 3)
+ spin_unlock(&rcrtc->vblank_lock);
+
+ if (status & DSSR_VBK) {
+ if (rcdu->info->gen < 3) {
+ drm_crtc_handle_vblank(&rcrtc->crtc);
rcar_du_crtc_finish_page_flip(rcrtc);
+ }
ret = IRQ_HANDLED;
}
@@ -715,13 +802,15 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index)
}
init_waitqueue_head(&rcrtc->flip_wait);
+ init_waitqueue_head(&rcrtc->vblank_wait);
+ spin_lock_init(&rcrtc->vblank_lock);
rcrtc->group = rgrp;
rcrtc->mmio_offset = mmio_offsets[index];
rcrtc->index = index;
if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE))
- primary = &rcrtc->vsp->planes[0].plane;
+ primary = &rcrtc->vsp->planes[rcrtc->vsp_pipe].plane;
else
primary = &rgrp->planes[index % 2].plane;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
index b199ed5..fdc2bf9 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
@@ -15,6 +15,7 @@
#define __RCAR_DU_CRTC_H__
#include <linux/mutex.h>
+#include <linux/spinlock.h>
#include <linux/wait.h>
#include <drm/drmP.h>
@@ -30,11 +31,17 @@ struct rcar_du_vsp;
* @extclock: external pixel dot clock (optional)
* @mmio_offset: offset of the CRTC registers in the DU MMIO block
* @index: CRTC software and hardware index
- * @started: whether the CRTC has been started and is running
+ * @initialized: whether the CRTC has been initialized and clocks enabled
+ * @vblank_enable: whether vblank events are enabled on this CRTC
* @event: event to post when the pending page flip completes
* @flip_wait: wait queue used to signal page flip completion
+ * @vblank_lock: protects vblank_wait and vblank_count
+ * @vblank_wait: wait queue used to signal vertical blanking
+ * @vblank_count: number of vertical blanking interrupts to wait for
* @outputs: bitmask of the outputs (enum rcar_du_output) driven by this CRTC
* @group: CRTC group this CRTC belongs to
+ * @vsp: VSP feeding video to this CRTC
+ * @vsp_pipe: index of the VSP pipeline feeding video to this CRTC
*/
struct rcar_du_crtc {
struct drm_crtc crtc;
@@ -43,15 +50,21 @@ struct rcar_du_crtc {
struct clk *extclock;
unsigned int mmio_offset;
unsigned int index;
- bool started;
+ bool initialized;
+ bool vblank_enable;
struct drm_pending_vblank_event *event;
wait_queue_head_t flip_wait;
+ spinlock_t vblank_lock;
+ wait_queue_head_t vblank_wait;
+ unsigned int vblank_count;
+
unsigned int outputs;
struct rcar_du_group *group;
struct rcar_du_vsp *vsp;
+ unsigned int vsp_pipe;
};
#define to_rcar_crtc(c) container_of(c, struct rcar_du_crtc, crtc)
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index d6a0255..d2f29e6 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -39,7 +39,8 @@ static const struct rcar_du_device_info rcar_du_r8a7779_info = {
.features = 0,
.num_crtcs = 2,
.routes = {
- /* R8A7779 has two RGB outputs and one (currently unsupported)
+ /*
+ * R8A7779 has two RGB outputs and one (currently unsupported)
* TCON output.
*/
[RCAR_DU_OUTPUT_DPAD0] = {
@@ -61,7 +62,8 @@ static const struct rcar_du_device_info rcar_du_r8a7790_info = {
.quirks = RCAR_DU_QUIRK_ALIGN_128B | RCAR_DU_QUIRK_LVDS_LANES,
.num_crtcs = 3,
.routes = {
- /* R8A7790 has one RGB output, two LVDS outputs and one
+ /*
+ * R8A7790 has one RGB output, two LVDS outputs and one
* (currently unsupported) TCON output.
*/
[RCAR_DU_OUTPUT_DPAD0] = {
@@ -87,7 +89,8 @@ static const struct rcar_du_device_info rcar_du_r8a7791_info = {
| RCAR_DU_FEATURE_EXT_CTRL_REGS,
.num_crtcs = 2,
.routes = {
- /* R8A779[13] has one RGB output, one LVDS output and one
+ /*
+ * R8A779[13] has one RGB output, one LVDS output and one
* (currently unsupported) TCON output.
*/
[RCAR_DU_OUTPUT_DPAD0] = {
@@ -127,7 +130,8 @@ static const struct rcar_du_device_info rcar_du_r8a7794_info = {
| RCAR_DU_FEATURE_EXT_CTRL_REGS,
.num_crtcs = 2,
.routes = {
- /* R8A7794 has two RGB outputs and one (currently unsupported)
+ /*
+ * R8A7794 has two RGB outputs and one (currently unsupported)
* TCON output.
*/
[RCAR_DU_OUTPUT_DPAD0] = {
@@ -149,7 +153,8 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = {
| RCAR_DU_FEATURE_VSP1_SOURCE,
.num_crtcs = 4,
.routes = {
- /* R8A7795 has one RGB output, two HDMI outputs and one
+ /*
+ * R8A7795 has one RGB output, two HDMI outputs and one
* LVDS output.
*/
[RCAR_DU_OUTPUT_DPAD0] = {
@@ -180,19 +185,25 @@ static const struct rcar_du_device_info rcar_du_r8a7796_info = {
| RCAR_DU_FEATURE_VSP1_SOURCE,
.num_crtcs = 3,
.routes = {
- /* R8A7796 has one RGB output, one LVDS output and one
- * (currently unsupported) HDMI output.
+ /*
+ * R8A7796 has one RGB output, one LVDS output and one HDMI
+ * output.
*/
[RCAR_DU_OUTPUT_DPAD0] = {
.possible_crtcs = BIT(2),
.port = 0,
},
+ [RCAR_DU_OUTPUT_HDMI0] = {
+ .possible_crtcs = BIT(1),
+ .port = 1,
+ },
[RCAR_DU_OUTPUT_LVDS0] = {
.possible_crtcs = BIT(0),
.port = 2,
},
},
.num_lvds = 1,
+ .dpll_ch = BIT(1),
};
static const struct of_device_id rcar_du_of_table[] = {
@@ -238,8 +249,6 @@ static struct drm_driver rcar_du_driver = {
.gem_prime_vunmap = drm_gem_cma_prime_vunmap,
.gem_prime_mmap = drm_gem_cma_prime_mmap,
.dumb_create = rcar_du_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.fops = &rcar_du_fops,
.name = "rcar-du",
.desc = "Renesas R-Car Display Unit",
@@ -341,7 +350,8 @@ static int rcar_du_probe(struct platform_device *pdev)
ddev->irq_enabled = 1;
- /* Register the DRM device with the core and the connectors with
+ /*
+ * Register the DRM device with the core and the connectors with
* sysfs.
*/
ret = drm_dev_register(ddev, 0);
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
index 3e048dd..ba8d280 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
@@ -186,8 +186,8 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
}
if (enc_node) {
- dev_dbg(rcdu->dev, "initializing encoder %s for output %u\n",
- of_node_full_name(enc_node), output);
+ dev_dbg(rcdu->dev, "initializing encoder %pOF for output %u\n",
+ enc_node, output);
/* Locate the DRM bridge from the encoder DT node. */
bridge = of_drm_find_bridge(enc_node);
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
index 64738fc..2f37ea9 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -64,7 +64,8 @@ static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
if (rcdu->info->gen < 3) {
defr8 |= DEFR8_DEFE8;
- /* On Gen2 the DEFR8 register for the first group also controls
+ /*
+ * On Gen2 the DEFR8 register for the first group also controls
* RGB output routing to DPAD0 and VSPD1 routing to DU0/1/2 for
* DU instances that support it.
*/
@@ -75,7 +76,8 @@ static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
defr8 |= DEFR8_VSCS;
}
} else {
- /* On Gen3 VSPD routing can't be configured, but DPAD routing
+ /*
+ * On Gen3 VSPD routing can't be configured, but DPAD routing
* needs to be set despite having a single option available.
*/
u32 crtc = ffs(possible_crtcs) - 1;
@@ -124,7 +126,8 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp)
if (rcdu->info->gen >= 3)
rcar_du_group_write(rgrp, DEFR10, DEFR10_CODE | DEFR10_DEFE10);
- /* Use DS1PR and DS2PR to configure planes priorities and connects the
+ /*
+ * Use DS1PR and DS2PR to configure planes priorities and connects the
* superposition 0 to DU0 pins. DU1 pins will be configured dynamically.
*/
rcar_du_group_write(rgrp, DORCR, DORCR_PG1D_DS1 | DORCR_DPRS);
@@ -177,7 +180,8 @@ static void __rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
void rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
{
- /* Many of the configuration bits are only updated when the display
+ /*
+ * Many of the configuration bits are only updated when the display
* reset (DRES) bit in DSYSR is set to 1, disabling *both* CRTCs. Some
* of those bits could be pre-configured, but others (especially the
* bits related to plane assignment to display timing controllers) need
@@ -208,23 +212,32 @@ void rcar_du_group_restart(struct rcar_du_group *rgrp)
int rcar_du_set_dpad0_vsp1_routing(struct rcar_du_device *rcdu)
{
+ struct rcar_du_group *rgrp;
+ struct rcar_du_crtc *crtc;
+ unsigned int index;
int ret;
if (!rcar_du_has(rcdu, RCAR_DU_FEATURE_EXT_CTRL_REGS))
return 0;
- /* RGB output routing to DPAD0 and VSP1D routing to DU0/1/2 are
- * configured in the DEFR8 register of the first group. As this function
- * can be called with the DU0 and DU1 CRTCs disabled, we need to enable
- * the first group clock before accessing the register.
+ /*
+ * RGB output routing to DPAD0 and VSP1D routing to DU0/1/2 are
+ * configured in the DEFR8 register of the first group on Gen2 and the
+ * last group on Gen3. As this function can be called with the DU
+ * channels of the corresponding CRTCs disabled, we need to enable the
+ * group clock before accessing the register.
*/
- ret = clk_prepare_enable(rcdu->crtcs[0].clock);
+ index = rcdu->info->gen < 3 ? 0 : DIV_ROUND_UP(rcdu->num_crtcs, 2) - 1;
+ rgrp = &rcdu->groups[index];
+ crtc = &rcdu->crtcs[index * 2];
+
+ ret = clk_prepare_enable(crtc->clock);
if (ret < 0)
return ret;
- rcar_du_group_setup_defr8(&rcdu->groups[0]);
+ rcar_du_group_setup_defr8(rgrp);
- clk_disable_unprepare(rcdu->crtcs[0].clock);
+ clk_disable_unprepare(crtc->clock);
return 0;
}
@@ -236,7 +249,8 @@ int rcar_du_group_set_routing(struct rcar_du_group *rgrp)
dorcr &= ~(DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_MASK);
- /* Set the DPAD1 pins sources. Select CRTC 0 if explicitly requested and
+ /*
+ * Set the DPAD1 pins sources. Select CRTC 0 if explicitly requested and
* CRTC 1 in all other cases to avoid cloning CRTC 0 to DPAD0 and DPAD1
* by default.
*/
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index f4125c8..7278b97 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -96,7 +96,8 @@ static const struct rcar_du_format_info rcar_du_format_infos[] = {
.pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
.edf = PnDDCR4_EDF_NONE,
},
- /* The following formats are not supported on Gen2 and thus have no
+ /*
+ * The following formats are not supported on Gen2 and thus have no
* associated .pnmr or .edf settings.
*/
{
@@ -153,7 +154,8 @@ int rcar_du_dumb_create(struct drm_file *file, struct drm_device *dev,
unsigned int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
unsigned int align;
- /* The R8A7779 DU requires a 16 pixels pitch alignment as documented,
+ /*
+ * The R8A7779 DU requires a 16 pixels pitch alignment as documented,
* but the R8A7790 DU seems to require a 128 bytes pitch alignment.
*/
if (rcar_du_needs(rcdu, RCAR_DU_QUIRK_ALIGN_128B))
@@ -255,12 +257,12 @@ static void rcar_du_atomic_commit_tail(struct drm_atomic_state *old_state)
/* Apply the atomic update. */
drm_atomic_helper_commit_modeset_disables(dev, old_state);
- drm_atomic_helper_commit_modeset_enables(dev, old_state);
drm_atomic_helper_commit_planes(dev, old_state,
DRM_PLANE_COMMIT_ACTIVE_ONLY);
+ drm_atomic_helper_commit_modeset_enables(dev, old_state);
drm_atomic_helper_commit_hw_done(old_state);
- drm_atomic_helper_wait_for_vblanks(dev, old_state);
+ drm_atomic_helper_wait_for_flip_done(dev, old_state);
drm_atomic_helper_cleanup_planes(dev, old_state);
}
@@ -297,19 +299,19 @@ static int rcar_du_encoders_init_one(struct rcar_du_device *rcdu,
*/
entity = of_graph_get_remote_port_parent(ep->local_node);
if (!entity) {
- dev_dbg(rcdu->dev, "unconnected endpoint %s, skipping\n",
- ep->local_node->full_name);
+ dev_dbg(rcdu->dev, "unconnected endpoint %pOF, skipping\n",
+ ep->local_node);
return -ENODEV;
}
if (!of_device_is_available(entity)) {
dev_dbg(rcdu->dev,
- "connected entity %s is disabled, skipping\n",
- entity->full_name);
+ "connected entity %pOF is disabled, skipping\n",
+ entity);
return -ENODEV;
}
- entity_ep_node = of_parse_phandle(ep->local_node, "remote-endpoint", 0);
+ entity_ep_node = of_graph_get_remote_endpoint(ep->local_node);
for_each_endpoint_of_node(entity, ep_node) {
if (ep_node == entity_ep_node)
@@ -325,8 +327,8 @@ static int rcar_du_encoders_init_one(struct rcar_du_device *rcdu,
if (!connector) {
dev_warn(rcdu->dev,
- "no connector for encoder %s, skipping\n",
- encoder->full_name);
+ "no connector for encoder %pOF, skipping\n",
+ encoder);
of_node_put(entity_ep_node);
of_node_put(encoder);
return -ENODEV;
@@ -348,8 +350,8 @@ static int rcar_du_encoders_init_one(struct rcar_du_device *rcdu,
ret = rcar_du_encoder_init(rcdu, output, encoder, connector);
if (ret && ret != -EPROBE_DEFER)
dev_warn(rcdu->dev,
- "failed to initialize encoder %s on output %u (%d), skipping\n",
- of_node_full_name(encoder), output, ret);
+ "failed to initialize encoder %pOF on output %u (%d), skipping\n",
+ encoder, output, ret);
of_node_put(encoder);
of_node_put(connector);
@@ -419,7 +421,8 @@ static int rcar_du_properties_init(struct rcar_du_device *rcdu)
if (rcdu->props.alpha == NULL)
return -ENOMEM;
- /* The color key is expressed as an RGB888 triplet stored in a 32-bit
+ /*
+ * The color key is expressed as an RGB888 triplet stored in a 32-bit
* integer in XRGB8888 format. Bit 24 is used as a flag to disable (0)
* or enable source color keying (1).
*/
@@ -432,6 +435,81 @@ static int rcar_du_properties_init(struct rcar_du_device *rcdu)
return 0;
}
+static int rcar_du_vsps_init(struct rcar_du_device *rcdu)
+{
+ const struct device_node *np = rcdu->dev->of_node;
+ struct of_phandle_args args;
+ struct {
+ struct device_node *np;
+ unsigned int crtcs_mask;
+ } vsps[RCAR_DU_MAX_VSPS] = { { 0, }, };
+ unsigned int vsps_count = 0;
+ unsigned int cells;
+ unsigned int i;
+ int ret;
+
+ /*
+ * First parse the DT vsps property to populate the list of VSPs. Each
+ * entry contains a pointer to the VSP DT node and a bitmask of the
+ * connected DU CRTCs.
+ */
+ cells = of_property_count_u32_elems(np, "vsps") / rcdu->num_crtcs - 1;
+ if (cells > 1)
+ return -EINVAL;
+
+ for (i = 0; i < rcdu->num_crtcs; ++i) {
+ unsigned int j;
+
+ ret = of_parse_phandle_with_fixed_args(np, "vsps", cells, i,
+ &args);
+ if (ret < 0)
+ goto error;
+
+ /*
+ * Add the VSP to the list or update the corresponding existing
+ * entry if the VSP has already been added.
+ */
+ for (j = 0; j < vsps_count; ++j) {
+ if (vsps[j].np == args.np)
+ break;
+ }
+
+ if (j < vsps_count)
+ of_node_put(args.np);
+ else
+ vsps[vsps_count++].np = args.np;
+
+ vsps[j].crtcs_mask |= BIT(i);
+
+ /* Store the VSP pointer and pipe index in the CRTC. */
+ rcdu->crtcs[i].vsp = &rcdu->vsps[j];
+ rcdu->crtcs[i].vsp_pipe = cells >= 1 ? args.args[0] : 0;
+ }
+
+ /*
+ * Then initialize all the VSPs from the node pointers and CRTCs bitmask
+ * computed previously.
+ */
+ for (i = 0; i < vsps_count; ++i) {
+ struct rcar_du_vsp *vsp = &rcdu->vsps[i];
+
+ vsp->index = i;
+ vsp->dev = rcdu;
+
+ ret = rcar_du_vsp_init(vsp, vsps[i].np, vsps[i].crtcs_mask);
+ if (ret < 0)
+ goto error;
+ }
+
+ return 0;
+
+error:
+ for (i = 0; i < ARRAY_SIZE(vsps); ++i)
+ of_node_put(vsps[i].np);
+
+ return ret;
+}
+
int rcar_du_modeset_init(struct rcar_du_device *rcdu)
{
static const unsigned int mmio_offsets[] = {
@@ -461,7 +539,8 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
if (ret < 0)
return ret;
- /* Initialize vertical blanking interrupts handling. Start with vblank
+ /*
+ * Initialize vertical blanking interrupts handling. Start with vblank
* disabled for all CRTCs.
*/
ret = drm_vblank_init(dev, (1 << rcdu->info->num_crtcs) - 1);
@@ -481,7 +560,8 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
rgrp->index = i;
rgrp->num_crtcs = min(rcdu->num_crtcs - 2 * i, 2U);
- /* If we have more than one CRTCs in this group pre-associate
+ /*
+ * If we have more than one CRTCs in this group pre-associate
* the low-order planes with CRTC 0 and the high-order planes
* with CRTC 1 to minimize flicker occurring when the
* association is changed.
@@ -499,17 +579,9 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
/* Initialize the compositors. */
if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE)) {
- for (i = 0; i < rcdu->num_crtcs; ++i) {
- struct rcar_du_vsp *vsp = &rcdu->vsps[i];
-
- vsp->index = i;
- vsp->dev = rcdu;
- rcdu->crtcs[i].vsp = vsp;
-
- ret = rcar_du_vsp_init(vsp);
- if (ret < 0)
- return ret;
- }
+ ret = rcar_du_vsps_init(rcdu);
+ if (ret < 0)
+ return ret;
}
/* Create the CRTCs. */
@@ -537,7 +609,8 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
num_encoders = ret;
- /* Set the possible CRTCs and possible clones. There's always at least
+ /*
+ * Set the possible CRTCs and possible clones. There's always at least
* one way for all encoders to clone each other, set all bits in the
* possible clones field.
*/
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c
index ee91481..b373ad4 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c
@@ -46,7 +46,6 @@ static void rcar_du_lvds_connector_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.reset = drm_atomic_helper_connector_reset,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = rcar_du_lvds_connector_destroy,
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c b/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c
index 1661f62..12d22f3 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c
@@ -59,7 +59,8 @@ static void rcar_du_lvdsenc_start_gen2(struct rcar_du_lvdsenc *lvds,
rcar_lvds_write(lvds, LVDPLLCR, pllcr);
- /* Select the input, hardcode mode 0, enable LVDS operation and turn
+ /*
+ * Select the input, hardcode mode 0, enable LVDS operation and turn
* bias circuitry on.
*/
lvdcr0 = (lvds->mode << LVDCR0_LVMD_SHIFT) | LVDCR0_BEN | LVDCR0_LVEN;
@@ -73,7 +74,8 @@ static void rcar_du_lvdsenc_start_gen2(struct rcar_du_lvdsenc *lvds,
LVDCR1_CHSTBY_GEN2(1) | LVDCR1_CHSTBY_GEN2(0) |
LVDCR1_CLKSTBY_GEN2);
- /* Turn the PLL on, wait for the startup delay, and turn the output
+ /*
+ * Turn the PLL on, wait for the startup delay, and turn the output
* on.
*/
lvdcr0 |= LVDCR0_PLLON;
@@ -140,7 +142,8 @@ static int rcar_du_lvdsenc_start(struct rcar_du_lvdsenc *lvds,
if (ret < 0)
return ret;
- /* Hardcode the channels and control signals routing for now.
+ /*
+ * Hardcode the channels and control signals routing for now.
*
* HSYNC -> CTRL0
* VSYNC -> CTRL1
@@ -202,7 +205,8 @@ void rcar_du_lvdsenc_atomic_check(struct rcar_du_lvdsenc *lvds,
{
struct rcar_du_device *rcdu = lvds->dev;
- /* The internal LVDS encoder has a restricted clock frequency operating
+ /*
+ * The internal LVDS encoder has a restricted clock frequency operating
* range (30MHz to 150MHz on Gen2, 25.175MHz to 148.5MHz on Gen3). Clamp
* the clock accordingly.
*/
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
index dcde628..61833cc 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
@@ -50,23 +50,21 @@
* automatically when the core swaps the old and new states.
*/
-static bool rcar_du_plane_needs_realloc(struct rcar_du_plane *plane,
- struct rcar_du_plane_state *new_state)
+static bool rcar_du_plane_needs_realloc(
+ const struct rcar_du_plane_state *old_state,
+ const struct rcar_du_plane_state *new_state)
{
- struct rcar_du_plane_state *cur_state;
-
- cur_state = to_rcar_plane_state(plane->plane.state);
-
- /* Lowering the number of planes doesn't strictly require reallocation
+ /*
+ * Lowering the number of planes doesn't strictly require reallocation
* as the extra hardware plane will be freed when committing, but doing
* so could lead to more fragmentation.
*/
- if (!cur_state->format ||
- cur_state->format->planes != new_state->format->planes)
+ if (!old_state->format ||
+ old_state->format->planes != new_state->format->planes)
return true;
/* Reallocate hardware planes if the source has changed. */
- if (cur_state->source != new_state->source)
+ if (old_state->source != new_state->source)
return true;
return false;
@@ -141,37 +139,43 @@ int rcar_du_atomic_check_planes(struct drm_device *dev,
unsigned int groups = 0;
unsigned int i;
struct drm_plane *drm_plane;
- struct drm_plane_state *drm_plane_state;
+ struct drm_plane_state *old_drm_plane_state;
+ struct drm_plane_state *new_drm_plane_state;
/* Check if hardware planes need to be reallocated. */
- for_each_plane_in_state(state, drm_plane, drm_plane_state, i) {
- struct rcar_du_plane_state *plane_state;
+ for_each_oldnew_plane_in_state(state, drm_plane, old_drm_plane_state,
+ new_drm_plane_state, i) {
+ struct rcar_du_plane_state *old_plane_state;
+ struct rcar_du_plane_state *new_plane_state;
struct rcar_du_plane *plane;
unsigned int index;
plane = to_rcar_plane(drm_plane);
- plane_state = to_rcar_plane_state(drm_plane_state);
+ old_plane_state = to_rcar_plane_state(old_drm_plane_state);
+ new_plane_state = to_rcar_plane_state(new_drm_plane_state);
dev_dbg(rcdu->dev, "%s: checking plane (%u,%tu)\n", __func__,
plane->group->index, plane - plane->group->planes);
- /* If the plane is being disabled we don't need to go through
+ /*
+ * If the plane is being disabled we don't need to go through
* the full reallocation procedure. Just mark the hardware
* plane(s) as freed.
*/
- if (!plane_state->format) {
+ if (!new_plane_state->format) {
dev_dbg(rcdu->dev, "%s: plane is being disabled\n",
__func__);
index = plane - plane->group->planes;
group_freed_planes[plane->group->index] |= 1 << index;
- plane_state->hwindex = -1;
+ new_plane_state->hwindex = -1;
continue;
}
- /* If the plane needs to be reallocated mark it as such, and
+ /*
+ * If the plane needs to be reallocated mark it as such, and
* mark the hardware plane(s) as free.
*/
- if (rcar_du_plane_needs_realloc(plane, plane_state)) {
+ if (rcar_du_plane_needs_realloc(old_plane_state, new_plane_state)) {
dev_dbg(rcdu->dev, "%s: plane needs reallocation\n",
__func__);
groups |= 1 << plane->group->index;
@@ -179,14 +183,15 @@ int rcar_du_atomic_check_planes(struct drm_device *dev,
index = plane - plane->group->planes;
group_freed_planes[plane->group->index] |= 1 << index;
- plane_state->hwindex = -1;
+ new_plane_state->hwindex = -1;
}
}
if (!needs_realloc)
return 0;
- /* Grab all plane states for the groups that need reallocation to ensure
+ /*
+ * Grab all plane states for the groups that need reallocation to ensure
* locking and avoid racy updates. This serializes the update operation,
* but there's not much we can do about it as that's the hardware
* design.
@@ -204,14 +209,15 @@ int rcar_du_atomic_check_planes(struct drm_device *dev,
for (i = 0; i < group->num_planes; ++i) {
struct rcar_du_plane *plane = &group->planes[i];
- struct rcar_du_plane_state *plane_state;
+ struct rcar_du_plane_state *new_plane_state;
struct drm_plane_state *s;
s = drm_atomic_get_plane_state(state, &plane->plane);
if (IS_ERR(s))
return PTR_ERR(s);
- /* If the plane has been freed in the above loop its
+ /*
+ * If the plane has been freed in the above loop its
* hardware planes must not be added to the used planes
* bitmask. However, the current state doesn't reflect
* the free state yet, as we've modified the new state
@@ -226,16 +232,16 @@ int rcar_du_atomic_check_planes(struct drm_device *dev,
continue;
}
- plane_state = to_rcar_plane_state(plane->plane.state);
- used_planes |= rcar_du_plane_hwmask(plane_state);
+ new_plane_state = to_rcar_plane_state(s);
+ used_planes |= rcar_du_plane_hwmask(new_plane_state);
dev_dbg(rcdu->dev,
"%s: plane (%u,%tu) uses %u hwplanes (index %d)\n",
__func__, plane->group->index,
plane - plane->group->planes,
- plane_state->format ?
- plane_state->format->planes : 0,
- plane_state->hwindex);
+ new_plane_state->format ?
+ new_plane_state->format->planes : 0,
+ new_plane_state->hwindex);
}
group_free_planes[index] = 0xff & ~used_planes;
@@ -246,40 +252,45 @@ int rcar_du_atomic_check_planes(struct drm_device *dev,
}
/* Reallocate hardware planes for each plane that needs it. */
- for_each_plane_in_state(state, drm_plane, drm_plane_state, i) {
- struct rcar_du_plane_state *plane_state;
+ for_each_oldnew_plane_in_state(state, drm_plane, old_drm_plane_state,
+ new_drm_plane_state, i) {
+ struct rcar_du_plane_state *old_plane_state;
+ struct rcar_du_plane_state *new_plane_state;
struct rcar_du_plane *plane;
unsigned int crtc_planes;
unsigned int free;
int idx;
plane = to_rcar_plane(drm_plane);
- plane_state = to_rcar_plane_state(drm_plane_state);
+ old_plane_state = to_rcar_plane_state(old_drm_plane_state);
+ new_plane_state = to_rcar_plane_state(new_drm_plane_state);
dev_dbg(rcdu->dev, "%s: allocating plane (%u,%tu)\n", __func__,
plane->group->index, plane - plane->group->planes);
- /* Skip planes that are being disabled or don't need to be
+ /*
+ * Skip planes that are being disabled or don't need to be
* reallocated.
*/
- if (!plane_state->format ||
- !rcar_du_plane_needs_realloc(plane, plane_state))
+ if (!new_plane_state->format ||
+ !rcar_du_plane_needs_realloc(old_plane_state, new_plane_state))
continue;
- /* Try to allocate the plane from the free planes currently
+ /*
+ * Try to allocate the plane from the free planes currently
* associated with the target CRTC to avoid restarting the CRTC
* group and thus minimize flicker. If it fails fall back to
* allocating from all free planes.
*/
- crtc_planes = to_rcar_crtc(plane_state->state.crtc)->index % 2
+ crtc_planes = to_rcar_crtc(new_plane_state->state.crtc)->index % 2
? plane->group->dptsr_planes
: ~plane->group->dptsr_planes;
free = group_free_planes[plane->group->index];
- idx = rcar_du_plane_hwalloc(plane, plane_state,
+ idx = rcar_du_plane_hwalloc(plane, new_plane_state,
free & crtc_planes);
if (idx < 0)
- idx = rcar_du_plane_hwalloc(plane, plane_state,
+ idx = rcar_du_plane_hwalloc(plane, new_plane_state,
free);
if (idx < 0) {
dev_dbg(rcdu->dev, "%s: no available hardware plane\n",
@@ -288,12 +299,12 @@ int rcar_du_atomic_check_planes(struct drm_device *dev,
}
dev_dbg(rcdu->dev, "%s: allocated %u hwplanes (index %u)\n",
- __func__, plane_state->format->planes, idx);
+ __func__, new_plane_state->format->planes, idx);
- plane_state->hwindex = idx;
+ new_plane_state->hwindex = idx;
group_free_planes[plane->group->index] &=
- ~rcar_du_plane_hwmask(plane_state);
+ ~rcar_du_plane_hwmask(new_plane_state);
dev_dbg(rcdu->dev, "%s: group %u free planes mask 0x%02x\n",
__func__, plane->group->index,
@@ -351,14 +362,16 @@ static void rcar_du_plane_setup_scanout(struct rcar_du_group *rgrp,
dma[1] = 0;
}
- /* Memory pitch (expressed in pixels). Must be doubled for interlaced
+ /*
+ * Memory pitch (expressed in pixels). Must be doubled for interlaced
* operation with 32bpp formats.
*/
rcar_du_plane_write(rgrp, index, PnMWR,
(interlaced && state->format->bpp == 32) ?
pitch * 2 : pitch);
- /* The Y position is expressed in raster line units and must be doubled
+ /*
+ * The Y position is expressed in raster line units and must be doubled
* for 32bpp formats, according to the R8A7790 datasheet. No mention of
* doubling the Y position is found in the R8A7779 datasheet, but the
* rule seems to apply there as well.
@@ -396,7 +409,8 @@ static void rcar_du_plane_setup_mode(struct rcar_du_group *rgrp,
u32 colorkey;
u32 pnmr;
- /* The PnALPHAR register controls alpha-blending in 16bpp formats
+ /*
+ * The PnALPHAR register controls alpha-blending in 16bpp formats
* (ARGB1555 and XRGB1555).
*
* For ARGB, set the alpha value to 0, and enable alpha-blending when
@@ -413,7 +427,8 @@ static void rcar_du_plane_setup_mode(struct rcar_du_group *rgrp,
pnmr = PnMR_BM_MD | state->format->pnmr;
- /* Disable color keying when requested. YUV formats have the
+ /*
+ * Disable color keying when requested. YUV formats have the
* PnMR_SPIM_TP_OFF bit set in their pnmr field, disabling color keying
* automatically.
*/
@@ -457,7 +472,8 @@ static void rcar_du_plane_setup_format_gen2(struct rcar_du_group *rgrp,
u32 ddcr2 = PnDDCR2_CODE;
u32 ddcr4;
- /* Data format
+ /*
+ * Data format
*
* The data format is selected by the DDDF field in PnMR and the EDF
* field in DDCR4.
@@ -589,7 +605,8 @@ static void rcar_du_plane_atomic_update(struct drm_plane *plane,
rcar_du_plane_setup(rplane);
- /* Check whether the source has changed from memory to live source or
+ /*
+ * Check whether the source has changed from memory to live source or
* from live source to memory. The source has been configured by the
* VSPS bit in the PnDDCR4 register. Although the datasheet states that
* the bit is updated during vertical blanking, it seems that updates
@@ -698,7 +715,6 @@ static const struct drm_plane_funcs rcar_du_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.reset = rcar_du_plane_reset,
- .set_property = drm_atomic_helper_plane_set_property,
.destroy = drm_plane_cleanup,
.atomic_duplicate_state = rcar_du_plane_atomic_duplicate_state,
.atomic_destroy_state = rcar_du_plane_atomic_destroy_state,
@@ -726,7 +742,8 @@ int rcar_du_planes_init(struct rcar_du_group *rgrp)
unsigned int i;
int ret;
- /* Create one primary plane per CRTC in this group and seven overlay
+ /*
+ * Create one primary plane per CRTC in this group and seven overlay
* planes.
*/
rgrp->num_planes = rgrp->num_crtcs + 7;
@@ -743,8 +760,8 @@ int rcar_du_planes_init(struct rcar_du_group *rgrp)
ret = drm_universal_plane_init(rcdu->ddev, &plane->plane, crtcs,
&rcar_du_plane_funcs, formats,
- ARRAY_SIZE(formats), type,
- NULL);
+ ARRAY_SIZE(formats),
+ NULL, type, NULL);
if (ret < 0)
return ret;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.h b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
index 8b91dd3..f62e09f 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
@@ -20,7 +20,8 @@
struct rcar_du_format_info;
struct rcar_du_group;
-/* The RCAR DU has 8 hardware planes, shared between primary and overlay planes.
+/*
+ * The RCAR DU has 8 hardware planes, shared between primary and overlay planes.
* As using overlay planes requires at least one of the CRTCs being enabled, no
* more than 7 overlay planes can be available. We thus create 1 primary plane
* per CRTC and 7 overlay planes, for a total of up to 9 KMS planes.
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
index f870445..2c96147 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -19,6 +19,7 @@
#include <drm/drm_gem_cma_helper.h>
#include <drm/drm_plane_helper.h>
+#include <linux/bitops.h>
#include <linux/dma-mapping.h>
#include <linux/of_platform.h>
#include <linux/scatterlist.h>
@@ -30,11 +31,15 @@
#include "rcar_du_kms.h"
#include "rcar_du_vsp.h"
-static void rcar_du_vsp_complete(void *private)
+static void rcar_du_vsp_complete(void *private, bool completed)
{
struct rcar_du_crtc *crtc = private;
- rcar_du_crtc_finish_page_flip(crtc);
+ if (crtc->vblank_enable)
+ drm_crtc_handle_vblank(&crtc->crtc);
+
+ if (completed)
+ rcar_du_crtc_finish_page_flip(crtc);
}
void rcar_du_vsp_enable(struct rcar_du_crtc *crtc)
@@ -73,7 +78,8 @@ void rcar_du_vsp_enable(struct rcar_du_crtc *crtc)
__rcar_du_plane_setup(crtc->group, &state);
- /* Ensure that the plane source configuration takes effect by requesting
+ /*
+ * Ensure that the plane source configuration takes effect by requesting
* a restart of the group. See rcar_du_plane_atomic_update() for a more
* detailed explanation.
*
@@ -81,22 +87,22 @@ void rcar_du_vsp_enable(struct rcar_du_crtc *crtc)
*/
crtc->group->need_restart = true;
- vsp1_du_setup_lif(crtc->vsp->vsp, &cfg);
+ vsp1_du_setup_lif(crtc->vsp->vsp, crtc->vsp_pipe, &cfg);
}
void rcar_du_vsp_disable(struct rcar_du_crtc *crtc)
{
- vsp1_du_setup_lif(crtc->vsp->vsp, NULL);
+ vsp1_du_setup_lif(crtc->vsp->vsp, crtc->vsp_pipe, NULL);
}
void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc)
{
- vsp1_du_atomic_begin(crtc->vsp->vsp);
+ vsp1_du_atomic_begin(crtc->vsp->vsp, crtc->vsp_pipe);
}
void rcar_du_vsp_atomic_flush(struct rcar_du_crtc *crtc)
{
- vsp1_du_atomic_flush(crtc->vsp->vsp);
+ vsp1_du_atomic_flush(crtc->vsp->vsp, crtc->vsp_pipe);
}
/* Keep the two tables in sync. */
@@ -162,6 +168,7 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
{
struct rcar_du_vsp_plane_state *state =
to_rcar_vsp_plane_state(plane->plane.state);
+ struct rcar_du_crtc *crtc = to_rcar_crtc(state->state.crtc);
struct drm_framebuffer *fb = plane->plane.state->fb;
struct vsp1_du_atomic_config cfg = {
.pixelformat = 0,
@@ -192,7 +199,8 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
}
}
- vsp1_du_atomic_update(plane->vsp->vsp, plane->index, &cfg);
+ vsp1_du_atomic_update(plane->vsp->vsp, crtc->vsp_pipe,
+ plane->index, &cfg);
}
static int rcar_du_vsp_plane_prepare_fb(struct drm_plane *plane,
@@ -288,11 +296,13 @@ static void rcar_du_vsp_plane_atomic_update(struct drm_plane *plane,
struct drm_plane_state *old_state)
{
struct rcar_du_vsp_plane *rplane = to_rcar_vsp_plane(plane);
+ struct rcar_du_crtc *crtc = to_rcar_crtc(old_state->crtc);
if (plane->state->crtc)
rcar_du_vsp_plane_setup(rplane);
else
- vsp1_du_atomic_update(rplane->vsp->vsp, rplane->index, NULL);
+ vsp1_du_atomic_update(rplane->vsp->vsp, crtc->vsp_pipe,
+ rplane->index, NULL);
}
static const struct drm_plane_helper_funcs rcar_du_vsp_plane_helper_funcs = {
@@ -383,7 +393,6 @@ static const struct drm_plane_funcs rcar_du_vsp_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.reset = rcar_du_vsp_plane_reset,
- .set_property = drm_atomic_helper_plane_set_property,
.destroy = drm_plane_cleanup,
.atomic_duplicate_state = rcar_du_vsp_plane_atomic_duplicate_state,
.atomic_destroy_state = rcar_du_vsp_plane_atomic_destroy_state,
@@ -391,23 +400,17 @@ static const struct drm_plane_funcs rcar_du_vsp_plane_funcs = {
.atomic_get_property = rcar_du_vsp_plane_atomic_get_property,
};
-int rcar_du_vsp_init(struct rcar_du_vsp *vsp)
+int rcar_du_vsp_init(struct rcar_du_vsp *vsp, struct device_node *np,
+ unsigned int crtcs)
{
struct rcar_du_device *rcdu = vsp->dev;
struct platform_device *pdev;
- struct device_node *np;
+ unsigned int num_crtcs = hweight32(crtcs);
unsigned int i;
int ret;
/* Find the VSP device and initialize it. */
- np = of_parse_phandle(rcdu->dev->of_node, "vsps", vsp->index);
- if (!np) {
- dev_err(rcdu->dev, "vsps node not found\n");
- return -ENXIO;
- }
-
pdev = of_find_device_by_node(np);
- of_node_put(np);
if (!pdev)
return -ENXIO;
@@ -417,7 +420,8 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp)
if (ret < 0)
return ret;
- /* The VSP2D (Gen3) has 5 RPFs, but the VSP1D (Gen2) is limited to
+ /*
+ * The VSP2D (Gen3) has 5 RPFs, but the VSP1D (Gen2) is limited to
* 4 RPFs.
*/
vsp->num_planes = rcdu->info->gen >= 3 ? 5 : 4;
@@ -428,19 +432,19 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp)
return -ENOMEM;
for (i = 0; i < vsp->num_planes; ++i) {
- enum drm_plane_type type = i ? DRM_PLANE_TYPE_OVERLAY
- : DRM_PLANE_TYPE_PRIMARY;
+ enum drm_plane_type type = i < num_crtcs
+ ? DRM_PLANE_TYPE_PRIMARY
+ : DRM_PLANE_TYPE_OVERLAY;
struct rcar_du_vsp_plane *plane = &vsp->planes[i];
plane->vsp = vsp;
plane->index = i;
- ret = drm_universal_plane_init(rcdu->ddev, &plane->plane,
- 1 << vsp->index,
+ ret = drm_universal_plane_init(rcdu->ddev, &plane->plane, crtcs,
&rcar_du_vsp_plane_funcs,
formats_kms,
- ARRAY_SIZE(formats_kms), type,
- NULL);
+ ARRAY_SIZE(formats_kms),
+ NULL, type, NULL);
if (ret < 0)
return ret;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.h b/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
index 8861661..f876c51 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
@@ -64,13 +64,19 @@ to_rcar_vsp_plane_state(struct drm_plane_state *state)
}
#ifdef CONFIG_DRM_RCAR_VSP
-int rcar_du_vsp_init(struct rcar_du_vsp *vsp);
+int rcar_du_vsp_init(struct rcar_du_vsp *vsp, struct device_node *np,
+ unsigned int crtcs);
void rcar_du_vsp_enable(struct rcar_du_crtc *crtc);
void rcar_du_vsp_disable(struct rcar_du_crtc *crtc);
void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc);
void rcar_du_vsp_atomic_flush(struct rcar_du_crtc *crtc);
#else
-static inline int rcar_du_vsp_init(struct rcar_du_vsp *vsp) { return -ENXIO; };
+static inline int rcar_du_vsp_init(struct rcar_du_vsp *vsp,
+ struct device_node *np,
+ unsigned int crtcs)
+{
+ return -ENXIO;
+}
static inline void rcar_du_vsp_enable(struct rcar_du_crtc *crtc) { };
static inline void rcar_du_vsp_disable(struct rcar_du_crtc *crtc) { };
static inline void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc) { };
diff --git a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
index 7539626..dc85b53 100644
--- a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
+++ b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
@@ -45,7 +45,7 @@ static int rcar_hdmi_phy_configure(struct dw_hdmi *hdmi,
{
const struct rcar_hdmi_phy_params *params = rcar_hdmi_phy_params;
- for (; params && params->mpixelclock != ~0UL; ++params) {
+ for (; params->mpixelclock != ~0UL; ++params) {
if (mpixelclock <= params->mpixelclock)
break;
}
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 9b0b058..a57da05 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -254,7 +254,6 @@ static void cdn_dp_connector_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs cdn_dp_atomic_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = cdn_dp_connector_detect,
.destroy = cdn_dp_connector_destroy,
.fill_modes = drm_helper_probe_single_connector_modes,
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 21b9737..9a20b9d 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -1080,7 +1080,6 @@ static void dw_mipi_dsi_drm_connector_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs dw_mipi_dsi_atomic_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = dw_mipi_dsi_drm_connector_destroy,
.reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index f820848..ccd5d59 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -7,10 +7,12 @@
* (at your option) any later version.
*/
+#include <linux/clk.h>
+#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
+
#include <drm/drm_of.h>
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
@@ -20,13 +22,32 @@
#include "rockchip_drm_drv.h"
#include "rockchip_drm_vop.h"
-#define GRF_SOC_CON6 0x025c
-#define HDMI_SEL_VOP_LIT (1 << 4)
+#define RK3288_GRF_SOC_CON6 0x025C
+#define RK3288_HDMI_LCDC_SEL BIT(4)
+#define RK3399_GRF_SOC_CON20 0x6250
+#define RK3399_HDMI_LCDC_SEL BIT(6)
+
+#define HIWORD_UPDATE(val, mask) (val | (mask) << 16)
+
+/**
+ * struct rockchip_hdmi_chip_data - splite the grf setting of kind of chips
+ * @lcdsel_grf_reg: grf register offset of lcdc select
+ * @lcdsel_big: reg value of selecting vop big for HDMI
+ * @lcdsel_lit: reg value of selecting vop little for HDMI
+ */
+struct rockchip_hdmi_chip_data {
+ u32 lcdsel_grf_reg;
+ u32 lcdsel_big;
+ u32 lcdsel_lit;
+};
struct rockchip_hdmi {
struct device *dev;
struct regmap *regmap;
struct drm_encoder encoder;
+ const struct rockchip_hdmi_chip_data *chip_data;
+ struct clk *vpll_clk;
+ struct clk *grf_clk;
};
#define to_rockchip_hdmi(x) container_of(x, struct rockchip_hdmi, x)
@@ -143,6 +164,7 @@ static const struct dw_hdmi_phy_config rockchip_phy_config[] = {
static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
{
struct device_node *np = hdmi->dev->of_node;
+ int ret;
hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
if (IS_ERR(hdmi->regmap)) {
@@ -150,6 +172,32 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
return PTR_ERR(hdmi->regmap);
}
+ hdmi->vpll_clk = devm_clk_get(hdmi->dev, "vpll");
+ if (PTR_ERR(hdmi->vpll_clk) == -ENOENT) {
+ hdmi->vpll_clk = NULL;
+ } else if (PTR_ERR(hdmi->vpll_clk) == -EPROBE_DEFER) {
+ return -EPROBE_DEFER;
+ } else if (IS_ERR(hdmi->vpll_clk)) {
+ dev_err(hdmi->dev, "failed to get grf clock\n");
+ return PTR_ERR(hdmi->vpll_clk);
+ }
+
+ hdmi->grf_clk = devm_clk_get(hdmi->dev, "grf");
+ if (PTR_ERR(hdmi->grf_clk) == -ENOENT) {
+ hdmi->grf_clk = NULL;
+ } else if (PTR_ERR(hdmi->grf_clk) == -EPROBE_DEFER) {
+ return -EPROBE_DEFER;
+ } else if (IS_ERR(hdmi->grf_clk)) {
+ dev_err(hdmi->dev, "failed to get grf clock\n");
+ return PTR_ERR(hdmi->grf_clk);
+ }
+
+ ret = clk_prepare_enable(hdmi->vpll_clk);
+ if (ret) {
+ dev_err(hdmi->dev, "Failed to enable HDMI vpll: %d\n", ret);
+ return ret;
+ }
+
return 0;
}
@@ -192,23 +240,36 @@ static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adj_mode)
{
+ struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
+
+ clk_set_rate(hdmi->vpll_clk, adj_mode->clock * 1000);
}
static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)
{
struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
u32 val;
- int mux;
+ int ret;
- mux = drm_of_encoder_active_endpoint_id(hdmi->dev->of_node, encoder);
- if (mux)
- val = HDMI_SEL_VOP_LIT | (HDMI_SEL_VOP_LIT << 16);
+ ret = drm_of_encoder_active_endpoint_id(hdmi->dev->of_node, encoder);
+ if (ret)
+ val = hdmi->chip_data->lcdsel_lit;
else
- val = HDMI_SEL_VOP_LIT << 16;
+ val = hdmi->chip_data->lcdsel_big;
- regmap_write(hdmi->regmap, GRF_SOC_CON6, val);
+ ret = clk_prepare_enable(hdmi->grf_clk);
+ if (ret < 0) {
+ dev_err(hdmi->dev, "failed to enable grfclk %d\n", ret);
+ return;
+ }
+
+ ret = regmap_write(hdmi->regmap, hdmi->chip_data->lcdsel_grf_reg, val);
+ if (ret != 0)
+ dev_err(hdmi->dev, "Could not write to GRF: %d\n", ret);
+
+ clk_disable_unprepare(hdmi->grf_clk);
dev_dbg(hdmi->dev, "vop %s output to hdmi\n",
- (mux) ? "LIT" : "BIG");
+ ret ? "LIT" : "BIG");
}
static int
@@ -232,16 +293,40 @@ static const struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_fun
.atomic_check = dw_hdmi_rockchip_encoder_atomic_check,
};
-static const struct dw_hdmi_plat_data rockchip_hdmi_drv_data = {
+static struct rockchip_hdmi_chip_data rk3288_chip_data = {
+ .lcdsel_grf_reg = RK3288_GRF_SOC_CON6,
+ .lcdsel_big = HIWORD_UPDATE(0, RK3288_HDMI_LCDC_SEL),
+ .lcdsel_lit = HIWORD_UPDATE(RK3288_HDMI_LCDC_SEL, RK3288_HDMI_LCDC_SEL),
+};
+
+static const struct dw_hdmi_plat_data rk3288_hdmi_drv_data = {
.mode_valid = dw_hdmi_rockchip_mode_valid,
.mpll_cfg = rockchip_mpll_cfg,
.cur_ctr = rockchip_cur_ctr,
.phy_config = rockchip_phy_config,
+ .phy_data = &rk3288_chip_data,
+};
+
+static struct rockchip_hdmi_chip_data rk3399_chip_data = {
+ .lcdsel_grf_reg = RK3399_GRF_SOC_CON20,
+ .lcdsel_big = HIWORD_UPDATE(0, RK3399_HDMI_LCDC_SEL),
+ .lcdsel_lit = HIWORD_UPDATE(RK3399_HDMI_LCDC_SEL, RK3399_HDMI_LCDC_SEL),
+};
+
+static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = {
+ .mode_valid = dw_hdmi_rockchip_mode_valid,
+ .mpll_cfg = rockchip_mpll_cfg,
+ .cur_ctr = rockchip_cur_ctr,
+ .phy_config = rockchip_phy_config,
+ .phy_data = &rk3399_chip_data,
};
static const struct of_device_id dw_hdmi_rockchip_dt_ids[] = {
{ .compatible = "rockchip,rk3288-dw-hdmi",
- .data = &rockchip_hdmi_drv_data
+ .data = &rk3288_hdmi_drv_data
+ },
+ { .compatible = "rockchip,rk3399-dw-hdmi",
+ .data = &rk3399_hdmi_drv_data
},
{},
};
@@ -268,6 +353,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
match = of_match_node(dw_hdmi_rockchip_dt_ids, pdev->dev.of_node);
plat_data = match->data;
hdmi->dev = &pdev->dev;
+ hdmi->chip_data = plat_data->phy_data;
encoder = &hdmi->encoder;
encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 7d9b75e..7a251a5 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -294,7 +294,7 @@ static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
union hdmi_infoframe frame;
int rc;
- rc = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode);
+ rc = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode, false);
if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV444)
frame.avi.colorspace = HDMI_COLORSPACE_YUV444;
@@ -592,8 +592,7 @@ static void inno_hdmi_connector_destroy(struct drm_connector *connector)
drm_connector_cleanup(connector);
}
-static struct drm_connector_funcs inno_hdmi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
+static const struct drm_connector_funcs inno_hdmi_connector_funcs = {
.fill_modes = inno_hdmi_probe_single_connector_modes,
.detect = inno_hdmi_connector_detect,
.destroy = inno_hdmi_connector_destroy,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index c16bc0a..ff3d0f5 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -161,23 +161,21 @@ static int rockchip_drm_bind(struct device *dev)
*/
drm_dev->irq_enabled = true;
- /* init kms poll for handling hpd */
- drm_kms_helper_poll_init(drm_dev);
-
ret = rockchip_drm_fbdev_init(drm_dev);
if (ret)
- goto err_kms_helper_poll_fini;
+ goto err_unbind_all;
+
+ /* init kms poll for handling hpd */
+ drm_kms_helper_poll_init(drm_dev);
ret = drm_dev_register(drm_dev, 0);
if (ret)
- goto err_fbdev_fini;
+ goto err_kms_helper_poll_fini;
return 0;
-err_fbdev_fini:
- rockchip_drm_fbdev_fini(drm_dev);
err_kms_helper_poll_fini:
drm_kms_helper_poll_fini(drm_dev);
- drm_vblank_cleanup(drm_dev);
+ rockchip_drm_fbdev_fini(drm_dev);
err_unbind_all:
component_unbind_all(dev, drm_dev);
err_mode_config_cleanup:
@@ -200,7 +198,6 @@ static void rockchip_drm_unbind(struct device *dev)
drm_kms_helper_poll_fini(drm_dev);
drm_atomic_helper_shutdown(drm_dev);
- drm_vblank_cleanup(drm_dev);
component_unbind_all(dev, drm_dev);
drm_mode_config_cleanup(drm_dev);
rockchip_iommu_cleanup(drm_dev);
@@ -235,8 +232,6 @@ static struct drm_driver rockchip_drm_driver = {
.gem_vm_ops = &drm_gem_cma_vm_ops,
.gem_free_object_unlocked = rockchip_gem_free_object,
.dumb_create = rockchip_gem_dumb_create,
- .dumb_map_offset = rockchip_gem_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_import = drm_gem_prime_import,
@@ -378,8 +373,8 @@ static int rockchip_drm_platform_of_probe(struct device *dev)
iommu = of_parse_phandle(port->parent, "iommus", 0);
if (!iommu || !of_device_is_available(iommu->parent)) {
- dev_dbg(dev, "no iommu attached for %s, using non-iommu buffers\n",
- port->parent->full_name);
+ dev_dbg(dev, "no iommu attached for %pOF, using non-iommu buffers\n",
+ port->parent);
/*
* if there is a crtc not support iommu, force set all
* crtc use non-iommu buffer.
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 81f9548..7077304 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -48,7 +48,7 @@ static void rockchip_drm_fb_destroy(struct drm_framebuffer *fb)
int i;
for (i = 0; i < ROCKCHIP_MAX_FB_BUFFER; i++)
- drm_gem_object_unreference_unlocked(rockchip_fb->obj[i]);
+ drm_gem_object_put_unlocked(rockchip_fb->obj[i]);
drm_framebuffer_cleanup(fb);
kfree(rockchip_fb);
@@ -144,7 +144,7 @@ rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
width * drm_format_plane_cpp(mode_cmd->pixel_format, i);
if (obj->size < min_size) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
ret = -EINVAL;
goto err_gem_object_unreference;
}
@@ -161,40 +161,19 @@ rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
err_gem_object_unreference:
for (i--; i >= 0; i--)
- drm_gem_object_unreference_unlocked(objs[i]);
+ drm_gem_object_put_unlocked(objs[i]);
return ERR_PTR(ret);
}
static void rockchip_drm_output_poll_changed(struct drm_device *dev)
{
struct rockchip_drm_private *private = dev->dev_private;
- struct drm_fb_helper *fb_helper = &private->fbdev_helper;
- if (fb_helper)
- drm_fb_helper_hotplug_event(fb_helper);
-}
-
-static void
-rockchip_atomic_commit_tail(struct drm_atomic_state *state)
-{
- struct drm_device *dev = state->dev;
-
- drm_atomic_helper_commit_modeset_disables(dev, state);
-
- drm_atomic_helper_commit_modeset_enables(dev, state);
-
- drm_atomic_helper_commit_planes(dev, state,
- DRM_PLANE_COMMIT_ACTIVE_ONLY);
-
- drm_atomic_helper_commit_hw_done(state);
-
- drm_atomic_helper_wait_for_vblanks(dev, state);
-
- drm_atomic_helper_cleanup_planes(dev, state);
+ drm_fb_helper_hotplug_event(&private->fbdev_helper);
}
static const struct drm_mode_config_helper_funcs rockchip_mode_config_helpers = {
- .atomic_commit_tail = rockchip_atomic_commit_tail,
+ .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
};
static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = {
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
index ce946b9..724579e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
@@ -173,7 +173,7 @@ void rockchip_drm_fbdev_fini(struct drm_device *dev)
drm_fb_helper_unregister_fbi(helper);
if (helper->fb)
- drm_framebuffer_unreference(helper->fb);
+ drm_framebuffer_put(helper->fb);
drm_fb_helper_fini(helper);
}
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index b74ac71..1869c8b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -383,7 +383,7 @@ rockchip_gem_create_with_handle(struct drm_file *file_priv,
goto err_handle_create;
/* drop reference from allocate - handle holds it now. */
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return rk_obj;
@@ -393,32 +393,6 @@ err_handle_create:
return ERR_PTR(ret);
}
-int rockchip_gem_dumb_map_offset(struct drm_file *file_priv,
- struct drm_device *dev, uint32_t handle,
- uint64_t *offset)
-{
- struct drm_gem_object *obj;
- int ret;
-
- obj = drm_gem_object_lookup(file_priv, handle);
- if (!obj) {
- DRM_ERROR("failed to lookup gem object.\n");
- return -EINVAL;
- }
-
- ret = drm_gem_create_mmap_offset(obj);
- if (ret)
- goto out;
-
- *offset = drm_vma_node_offset_addr(&obj->vma_node);
- DRM_DEBUG_KMS("offset = 0x%llx\n", *offset);
-
-out:
- drm_gem_object_unreference_unlocked(obj);
-
- return 0;
-}
-
/*
* rockchip_gem_dumb_create - (struct drm_driver)->dumb_create callback
* function
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.h b/drivers/gpu/drm/rockchip/rockchip_drm_gem.h
index 3f6ea4d..f237375 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.h
@@ -57,7 +57,4 @@ void rockchip_gem_free_object(struct drm_gem_object *obj);
int rockchip_gem_dumb_create(struct drm_file *file_priv,
struct drm_device *dev,
struct drm_mode_create_dumb *args);
-int rockchip_gem_dumb_map_offset(struct drm_file *file_priv,
- struct drm_device *dev, uint32_t handle,
- uint64_t *offset);
#endif /* _ROCKCHIP_DRM_GEM_H */
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 2900f14..bf9ed0e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -42,33 +42,20 @@
#include "rockchip_drm_psr.h"
#include "rockchip_drm_vop.h"
-#define __REG_SET_RELAXED(x, off, mask, shift, v, write_mask) \
- vop_mask_write(x, off, mask, shift, v, write_mask, true)
-
-#define __REG_SET_NORMAL(x, off, mask, shift, v, write_mask) \
- vop_mask_write(x, off, mask, shift, v, write_mask, false)
-
-#define REG_SET(x, base, reg, v, mode) \
- __REG_SET_##mode(x, base + reg.offset, \
- reg.mask, reg.shift, v, reg.write_mask)
-#define REG_SET_MASK(x, base, reg, mask, v, mode) \
- __REG_SET_##mode(x, base + reg.offset, \
- mask, reg.shift, v, reg.write_mask)
-
#define VOP_WIN_SET(x, win, name, v) \
- REG_SET(x, win->base, win->phy->name, v, RELAXED)
+ vop_reg_set(vop, &win->phy->name, win->base, ~0, v, #name)
#define VOP_SCL_SET(x, win, name, v) \
- REG_SET(x, win->base, win->phy->scl->name, v, RELAXED)
+ vop_reg_set(vop, &win->phy->scl->name, win->base, ~0, v, #name)
#define VOP_SCL_SET_EXT(x, win, name, v) \
- REG_SET(x, win->base, win->phy->scl->ext->name, v, RELAXED)
-#define VOP_CTRL_SET(x, name, v) \
- REG_SET(x, 0, (x)->data->ctrl->name, v, NORMAL)
+ vop_reg_set(vop, &win->phy->scl->ext->name, \
+ win->base, ~0, v, #name)
-#define VOP_INTR_GET(vop, name) \
- vop_read_reg(vop, 0, &vop->data->ctrl->name)
+#define VOP_INTR_SET_MASK(vop, name, mask, v) \
+ vop_reg_set(vop, &vop->data->intr->name, 0, mask, v, #name)
+
+#define VOP_REG_SET(vop, group, name, v) \
+ vop_reg_set(vop, &vop->data->group->name, 0, ~0, v, #name)
-#define VOP_INTR_SET(vop, name, mask, v) \
- REG_SET_MASK(vop, 0, vop->data->intr->name, mask, v, NORMAL)
#define VOP_INTR_SET_TYPE(vop, name, type, v) \
do { \
int i, reg = 0, mask = 0; \
@@ -78,13 +65,13 @@
mask |= 1 << i; \
} \
} \
- VOP_INTR_SET(vop, name, mask, reg); \
+ VOP_INTR_SET_MASK(vop, name, mask, reg); \
} while (0)
#define VOP_INTR_GET_TYPE(vop, name, type) \
vop_get_intr_type(vop, &vop->data->intr->name, type)
#define VOP_WIN_GET(x, win, name) \
- vop_read_reg(x, win->base, &win->phy->name)
+ vop_read_reg(x, win->offset, win->phy->name)
#define VOP_WIN_GET_YRGBADDR(vop, win) \
vop_readl(vop, win->base + win->phy->yrgb_mst.offset)
@@ -166,14 +153,22 @@ static inline uint32_t vop_read_reg(struct vop *vop, uint32_t base,
return (vop_readl(vop, base + reg->offset) >> reg->shift) & reg->mask;
}
-static inline void vop_mask_write(struct vop *vop, uint32_t offset,
- uint32_t mask, uint32_t shift, uint32_t v,
- bool write_mask, bool relaxed)
+static void vop_reg_set(struct vop *vop, const struct vop_reg *reg,
+ uint32_t _offset, uint32_t _mask, uint32_t v,
+ const char *reg_name)
{
- if (!mask)
+ int offset, mask, shift;
+
+ if (!reg || !reg->mask) {
+ dev_dbg(vop->dev, "Warning: not support %s\n", reg_name);
return;
+ }
+
+ offset = reg->offset + _offset;
+ mask = reg->mask & _mask;
+ shift = reg->shift;
- if (write_mask) {
+ if (reg->write_mask) {
v = ((v << shift) & 0xffff) | (mask << (shift + 16));
} else {
uint32_t cached_val = vop->regsbak[offset >> 2];
@@ -182,7 +177,7 @@ static inline void vop_mask_write(struct vop *vop, uint32_t offset,
vop->regsbak[offset >> 2] = v;
}
- if (relaxed)
+ if (reg->relaxed)
writel_relaxed(v, vop->regs + offset);
else
writel(v, vop->regs + offset);
@@ -204,7 +199,7 @@ static inline uint32_t vop_get_intr_type(struct vop *vop,
static inline void vop_cfg_done(struct vop *vop)
{
- VOP_CTRL_SET(vop, cfg_done, 1);
+ VOP_REG_SET(vop, common, cfg_done, 1);
}
static bool has_rb_swapped(uint32_t format)
@@ -556,7 +551,7 @@ static int vop_enable(struct drm_crtc *crtc)
spin_lock(&vop->reg_lock);
- VOP_CTRL_SET(vop, standby, 0);
+ VOP_REG_SET(vop, common, standby, 1);
spin_unlock(&vop->reg_lock);
@@ -577,7 +572,8 @@ err_put_pm_runtime:
return ret;
}
-static void vop_crtc_disable(struct drm_crtc *crtc)
+static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct vop *vop = to_vop(crtc);
@@ -599,7 +595,7 @@ static void vop_crtc_disable(struct drm_crtc *crtc)
spin_lock(&vop->reg_lock);
- VOP_CTRL_SET(vop, standby, 1);
+ VOP_REG_SET(vop, common, standby, 1);
spin_unlock(&vop->reg_lock);
@@ -870,7 +866,8 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
return true;
}
-static void vop_crtc_enable(struct drm_crtc *crtc)
+static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct vop *vop = to_vop(crtc);
const struct vop_data *vop_data = vop->data;
@@ -897,70 +894,34 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
return;
}
- /*
- * If dclk rate is zero, mean that scanout is stop,
- * we don't need wait any more.
- */
- if (clk_get_rate(vop->dclk)) {
- /*
- * Rk3288 vop timing register is immediately, when configure
- * display timing on display time, may cause tearing.
- *
- * Vop standby will take effect at end of current frame,
- * if dsp hold valid irq happen, it means standby complete.
- *
- * mode set:
- * standby and wait complete --> |----
- * | display time
- * |----
- * |---> dsp hold irq
- * configure display timing --> |
- * standby exit |
- * | new frame start.
- */
-
- reinit_completion(&vop->dsp_hold_completion);
- vop_dsp_hold_valid_irq_enable(vop);
-
- spin_lock(&vop->reg_lock);
-
- VOP_CTRL_SET(vop, standby, 1);
-
- spin_unlock(&vop->reg_lock);
-
- wait_for_completion(&vop->dsp_hold_completion);
-
- vop_dsp_hold_valid_irq_disable(vop);
- }
-
pin_pol = BIT(DCLK_INVERT);
pin_pol |= (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) ?
BIT(HSYNC_POSITIVE) : 0;
pin_pol |= (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) ?
BIT(VSYNC_POSITIVE) : 0;
- VOP_CTRL_SET(vop, pin_pol, pin_pol);
+ VOP_REG_SET(vop, output, pin_pol, pin_pol);
switch (s->output_type) {
case DRM_MODE_CONNECTOR_LVDS:
- VOP_CTRL_SET(vop, rgb_en, 1);
- VOP_CTRL_SET(vop, rgb_pin_pol, pin_pol);
+ VOP_REG_SET(vop, output, rgb_en, 1);
+ VOP_REG_SET(vop, output, rgb_pin_pol, pin_pol);
break;
case DRM_MODE_CONNECTOR_eDP:
- VOP_CTRL_SET(vop, edp_pin_pol, pin_pol);
- VOP_CTRL_SET(vop, edp_en, 1);
+ VOP_REG_SET(vop, output, edp_pin_pol, pin_pol);
+ VOP_REG_SET(vop, output, edp_en, 1);
break;
case DRM_MODE_CONNECTOR_HDMIA:
- VOP_CTRL_SET(vop, hdmi_pin_pol, pin_pol);
- VOP_CTRL_SET(vop, hdmi_en, 1);
+ VOP_REG_SET(vop, output, hdmi_pin_pol, pin_pol);
+ VOP_REG_SET(vop, output, hdmi_en, 1);
break;
case DRM_MODE_CONNECTOR_DSI:
- VOP_CTRL_SET(vop, mipi_pin_pol, pin_pol);
- VOP_CTRL_SET(vop, mipi_en, 1);
+ VOP_REG_SET(vop, output, mipi_pin_pol, pin_pol);
+ VOP_REG_SET(vop, output, mipi_en, 1);
break;
case DRM_MODE_CONNECTOR_DisplayPort:
pin_pol &= ~BIT(DCLK_INVERT);
- VOP_CTRL_SET(vop, dp_pin_pol, pin_pol);
- VOP_CTRL_SET(vop, dp_en, 1);
+ VOP_REG_SET(vop, output, dp_pin_pol, pin_pol);
+ VOP_REG_SET(vop, output, dp_en, 1);
break;
default:
DRM_DEV_ERROR(vop->dev, "unsupported connector_type [%d]\n",
@@ -973,25 +934,25 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
!(vop_data->feature & VOP_FEATURE_OUTPUT_RGB10))
s->output_mode = ROCKCHIP_OUT_MODE_P888;
- VOP_CTRL_SET(vop, out_mode, s->output_mode);
+ VOP_REG_SET(vop, common, out_mode, s->output_mode);
- VOP_CTRL_SET(vop, htotal_pw, (htotal << 16) | hsync_len);
+ VOP_REG_SET(vop, modeset, htotal_pw, (htotal << 16) | hsync_len);
val = hact_st << 16;
val |= hact_end;
- VOP_CTRL_SET(vop, hact_st_end, val);
- VOP_CTRL_SET(vop, hpost_st_end, val);
+ VOP_REG_SET(vop, modeset, hact_st_end, val);
+ VOP_REG_SET(vop, modeset, hpost_st_end, val);
- VOP_CTRL_SET(vop, vtotal_pw, (vtotal << 16) | vsync_len);
+ VOP_REG_SET(vop, modeset, vtotal_pw, (vtotal << 16) | vsync_len);
val = vact_st << 16;
val |= vact_end;
- VOP_CTRL_SET(vop, vact_st_end, val);
- VOP_CTRL_SET(vop, vpost_st_end, val);
+ VOP_REG_SET(vop, modeset, vact_st_end, val);
+ VOP_REG_SET(vop, modeset, vpost_st_end, val);
- VOP_CTRL_SET(vop, line_flag_num[0], vact_end);
+ VOP_REG_SET(vop, intr, line_flag_num[0], vact_end);
clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
- VOP_CTRL_SET(vop, standby, 0);
+ VOP_REG_SET(vop, common, standby, 0);
rockchip_drm_psr_activate(&vop->crtc);
}
@@ -1026,7 +987,7 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
struct drm_crtc_state *old_crtc_state)
{
struct drm_atomic_state *old_state = old_crtc_state->state;
- struct drm_plane_state *old_plane_state;
+ struct drm_plane_state *old_plane_state, *new_plane_state;
struct vop *vop = to_vop(crtc);
struct drm_plane *plane;
int i;
@@ -1057,14 +1018,15 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
}
spin_unlock_irq(&crtc->dev->event_lock);
- for_each_plane_in_state(old_state, plane, old_plane_state, i) {
+ for_each_oldnew_plane_in_state(old_state, plane, old_plane_state,
+ new_plane_state, i) {
if (!old_plane_state->fb)
continue;
- if (old_plane_state->fb == plane->state->fb)
+ if (old_plane_state->fb == new_plane_state->fb)
continue;
- drm_framebuffer_reference(old_plane_state->fb);
+ drm_framebuffer_get(old_plane_state->fb);
drm_flip_work_queue(&vop->fb_unref_work, old_plane_state->fb);
set_bit(VOP_PENDING_FB_UNREF, &vop->pending);
WARN_ON(drm_crtc_vblank_get(crtc) != 0);
@@ -1078,11 +1040,11 @@ static void vop_crtc_atomic_begin(struct drm_crtc *crtc,
}
static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = {
- .enable = vop_crtc_enable,
- .disable = vop_crtc_disable,
.mode_fixup = vop_crtc_mode_fixup,
.atomic_flush = vop_crtc_atomic_flush,
.atomic_begin = vop_crtc_atomic_begin,
+ .atomic_enable = vop_crtc_atomic_enable,
+ .atomic_disable = vop_crtc_atomic_disable,
};
static void vop_crtc_destroy(struct drm_crtc *crtc)
@@ -1188,7 +1150,7 @@ static void vop_fb_unref_worker(struct drm_flip_work *work, void *val)
struct drm_framebuffer *fb = val;
drm_crtc_vblank_put(&vop->crtc);
- drm_framebuffer_unreference(fb);
+ drm_framebuffer_put(fb);
}
static void vop_handle_vblank(struct vop *vop)
@@ -1289,7 +1251,7 @@ static int vop_create_crtc(struct vop *vop)
0, &vop_plane_funcs,
win_data->phy->data_formats,
win_data->phy->nformats,
- win_data->type, NULL);
+ NULL, win_data->type, NULL);
if (ret) {
DRM_DEV_ERROR(vop->dev, "failed to init plane %d\n",
ret);
@@ -1328,7 +1290,7 @@ static int vop_create_crtc(struct vop *vop)
&vop_plane_funcs,
win_data->phy->data_formats,
win_data->phy->nformats,
- win_data->type, NULL);
+ NULL, win_data->type, NULL);
if (ret) {
DRM_DEV_ERROR(vop->dev, "failed to init overlay %d\n",
ret);
@@ -1339,8 +1301,8 @@ static int vop_create_crtc(struct vop *vop)
port = of_get_child_by_name(dev->of_node, "port");
if (!port) {
- DRM_DEV_ERROR(vop->dev, "no port node found in %s\n",
- dev->of_node->full_name);
+ DRM_DEV_ERROR(vop->dev, "no port node found in %pOF\n",
+ dev->of_node);
ret = -ENOENT;
goto err_cleanup_crtc;
}
@@ -1394,7 +1356,6 @@ static void vop_destroy_crtc(struct vop *vop)
static int vop_initial(struct vop *vop)
{
const struct vop_data *vop_data = vop->data;
- const struct vop_reg_data *init_table = vop_data->init_table;
struct reset_control *ahb_rst;
int i, ret;
@@ -1454,13 +1415,16 @@ static int vop_initial(struct vop *vop)
memcpy(vop->regsbak, vop->regs, vop->len);
- for (i = 0; i < vop_data->table_size; i++)
- vop_writel(vop, init_table[i].offset, init_table[i].value);
+ VOP_REG_SET(vop, misc, global_regdone_en, 1);
+ VOP_REG_SET(vop, common, dsp_blank, 0);
for (i = 0; i < vop_data->win_size; i++) {
const struct vop_win_data *win = &vop_data->win[i];
+ int channel = i * 2 + 1;
+ VOP_WIN_SET(vop, win, channel, (channel + 1) << 4 | channel);
VOP_WIN_SET(vop, win, enable, 0);
+ VOP_WIN_SET(vop, win, gate, 1);
}
vop_cfg_done(vop);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index 27eefbf..56bbd2e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -15,6 +15,14 @@
#ifndef _ROCKCHIP_DRM_VOP_H
#define _ROCKCHIP_DRM_VOP_H
+/*
+ * major: IP major version, used for IP structure
+ * minor: big feature change under same structure
+ */
+#define VOP_VERSION(major, minor) ((major) << 8 | (minor))
+#define VOP_MAJOR(version) ((version) >> 8)
+#define VOP_MINOR(version) ((version) & 0xff)
+
enum vop_data_format {
VOP_FMT_ARGB8888 = 0,
VOP_FMT_RGB888,
@@ -24,53 +32,58 @@ enum vop_data_format {
VOP_FMT_YUV444SP,
};
-struct vop_reg_data {
- uint32_t offset;
- uint32_t value;
-};
-
struct vop_reg {
- uint32_t offset;
- uint32_t shift;
uint32_t mask;
+ uint16_t offset;
+ uint8_t shift;
bool write_mask;
+ bool relaxed;
};
-struct vop_ctrl {
- struct vop_reg standby;
- struct vop_reg data_blank;
- struct vop_reg gate_en;
- struct vop_reg mmu_en;
- struct vop_reg rgb_en;
- struct vop_reg edp_en;
- struct vop_reg hdmi_en;
- struct vop_reg mipi_en;
- struct vop_reg dp_en;
- struct vop_reg out_mode;
- struct vop_reg dither_down;
- struct vop_reg dither_up;
- struct vop_reg pin_pol;
- struct vop_reg rgb_pin_pol;
- struct vop_reg hdmi_pin_pol;
- struct vop_reg edp_pin_pol;
- struct vop_reg mipi_pin_pol;
- struct vop_reg dp_pin_pol;
-
+struct vop_modeset {
struct vop_reg htotal_pw;
struct vop_reg hact_st_end;
+ struct vop_reg hpost_st_end;
struct vop_reg vtotal_pw;
struct vop_reg vact_st_end;
- struct vop_reg hpost_st_end;
struct vop_reg vpost_st_end;
+};
- struct vop_reg line_flag_num[2];
+struct vop_output {
+ struct vop_reg pin_pol;
+ struct vop_reg dp_pin_pol;
+ struct vop_reg edp_pin_pol;
+ struct vop_reg hdmi_pin_pol;
+ struct vop_reg mipi_pin_pol;
+ struct vop_reg rgb_pin_pol;
+ struct vop_reg dp_en;
+ struct vop_reg edp_en;
+ struct vop_reg hdmi_en;
+ struct vop_reg mipi_en;
+ struct vop_reg rgb_en;
+};
+struct vop_common {
struct vop_reg cfg_done;
+ struct vop_reg dsp_blank;
+ struct vop_reg data_blank;
+ struct vop_reg dither_down;
+ struct vop_reg dither_up;
+ struct vop_reg gate_en;
+ struct vop_reg mmu_en;
+ struct vop_reg out_mode;
+ struct vop_reg standby;
+};
+
+struct vop_misc {
+ struct vop_reg global_regdone_en;
};
struct vop_intr {
const int *intrs;
uint32_t nintrs;
+
+ struct vop_reg line_flag_num[2];
struct vop_reg enable;
struct vop_reg clear;
struct vop_reg status;
@@ -115,6 +128,7 @@ struct vop_win_phy {
uint32_t nformats;
struct vop_reg enable;
+ struct vop_reg gate;
struct vop_reg format;
struct vop_reg rb_swap;
struct vop_reg act_info;
@@ -127,6 +141,7 @@ struct vop_win_phy {
struct vop_reg dst_alpha_ctl;
struct vop_reg src_alpha_ctl;
+ struct vop_reg channel;
};
struct vop_win_data {
@@ -136,10 +151,12 @@ struct vop_win_data {
};
struct vop_data {
- const struct vop_reg_data *init_table;
- unsigned int table_size;
- const struct vop_ctrl *ctrl;
+ uint32_t version;
const struct vop_intr *intr;
+ const struct vop_common *common;
+ const struct vop_misc *misc;
+ const struct vop_modeset *modeset;
+ const struct vop_output *output;
const struct vop_win_data *win;
unsigned int win_size;
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index bafd698..94de7b9 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -20,17 +20,23 @@
#include "rockchip_drm_vop.h"
#include "rockchip_vop_reg.h"
-#define VOP_REG(off, _mask, s) \
- {.offset = off, \
+#define _VOP_REG(off, _mask, _shift, _write_mask, _relaxed) \
+ { \
+ .offset = off, \
.mask = _mask, \
- .shift = s, \
- .write_mask = false,}
+ .shift = _shift, \
+ .write_mask = _write_mask, \
+ .relaxed = _relaxed, \
+ }
-#define VOP_REG_MASK(off, _mask, s) \
- {.offset = off, \
- .mask = _mask, \
- .shift = s, \
- .write_mask = true,}
+#define VOP_REG(off, _mask, _shift) \
+ _VOP_REG(off, _mask, _shift, false, true)
+
+#define VOP_REG_SYNC(off, _mask, _shift) \
+ _VOP_REG(off, _mask, _shift, false, false)
+
+#define VOP_REG_MASK_SYNC(off, _mask, _shift) \
+ _VOP_REG(off, _mask, _shift, true, false)
static const uint32_t formats_win_full[] = {
DRM_FORMAT_XRGB8888,
@@ -110,32 +116,35 @@ static const int rk3036_vop_intrs[] = {
static const struct vop_intr rk3036_intr = {
.intrs = rk3036_vop_intrs,
.nintrs = ARRAY_SIZE(rk3036_vop_intrs),
- .status = VOP_REG(RK3036_INT_STATUS, 0xf, 0),
- .enable = VOP_REG(RK3036_INT_STATUS, 0xf, 4),
- .clear = VOP_REG(RK3036_INT_STATUS, 0xf, 8),
+ .line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12),
+ .status = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 0),
+ .enable = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 4),
+ .clear = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 8),
};
-static const struct vop_ctrl rk3036_ctrl_data = {
- .standby = VOP_REG(RK3036_SYS_CTRL, 0x1, 30),
- .out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0),
- .pin_pol = VOP_REG(RK3036_DSP_CTRL0, 0xf, 4),
+static const struct vop_modeset rk3036_modeset = {
.htotal_pw = VOP_REG(RK3036_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
.hact_st_end = VOP_REG(RK3036_DSP_HACT_ST_END, 0x1fff1fff, 0),
.vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
.vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0),
- .line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12),
- .cfg_done = VOP_REG(RK3036_REG_CFG_DONE, 0x1, 0),
};
-static const struct vop_reg_data rk3036_vop_init_reg_table[] = {
- {RK3036_DSP_CTRL1, 0x00000000},
+static const struct vop_output rk3036_output = {
+ .pin_pol = VOP_REG(RK3036_DSP_CTRL0, 0xf, 4),
+};
+
+static const struct vop_common rk3036_common = {
+ .standby = VOP_REG_SYNC(RK3036_SYS_CTRL, 0x1, 30),
+ .out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0),
+ .dsp_blank = VOP_REG(RK3036_DSP_CTRL1, 0x1, 24),
+ .cfg_done = VOP_REG_SYNC(RK3036_REG_CFG_DONE, 0x1, 0),
};
static const struct vop_data rk3036_vop = {
- .init_table = rk3036_vop_init_reg_table,
- .table_size = ARRAY_SIZE(rk3036_vop_init_reg_table),
- .ctrl = &rk3036_ctrl_data,
.intr = &rk3036_intr,
+ .common = &rk3036_common,
+ .modeset = &rk3036_modeset,
+ .output = &rk3036_output,
.win = rk3036_vop_win_data,
.win_size = ARRAY_SIZE(rk3036_vop_win_data),
};
@@ -188,12 +197,14 @@ static const struct vop_win_phy rk3288_win01_data = {
.uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16),
.src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
.dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0),
+ .channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0),
};
static const struct vop_win_phy rk3288_win23_data = {
.data_formats = formats_win_lite,
.nformats = ARRAY_SIZE(formats_win_lite),
- .enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0),
+ .enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 4),
+ .gate = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0),
.format = VOP_REG(RK3288_WIN2_CTRL0, 0x7, 1),
.rb_swap = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 12),
.dsp_info = VOP_REG(RK3288_WIN2_DSP_INFO0, 0x0fff0fff, 0),
@@ -204,40 +215,33 @@ static const struct vop_win_phy rk3288_win23_data = {
.dst_alpha_ctl = VOP_REG(RK3288_WIN2_DST_ALPHA_CTRL, 0xff, 0),
};
-static const struct vop_ctrl rk3288_ctrl_data = {
- .standby = VOP_REG(RK3288_SYS_CTRL, 0x1, 22),
- .gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23),
- .mmu_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 20),
- .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
- .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
- .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
- .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
- .dither_down = VOP_REG(RK3288_DSP_CTRL1, 0xf, 1),
- .dither_up = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6),
- .data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19),
- .out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0),
- .pin_pol = VOP_REG(RK3288_DSP_CTRL0, 0xf, 4),
+static const struct vop_modeset rk3288_modeset = {
.htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
.hact_st_end = VOP_REG(RK3288_DSP_HACT_ST_END, 0x1fff1fff, 0),
.vtotal_pw = VOP_REG(RK3288_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
.vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 0x1fff1fff, 0),
.hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
.vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
- .line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12),
- .cfg_done = VOP_REG(RK3288_REG_CFG_DONE, 0x1, 0),
};
-static const struct vop_reg_data rk3288_init_reg_table[] = {
- {RK3288_SYS_CTRL, 0x00c00000},
- {RK3288_DSP_CTRL0, 0x00000000},
- {RK3288_WIN0_CTRL0, 0x00000080},
- {RK3288_WIN1_CTRL0, 0x00000080},
- /* TODO: Win2/3 support multiple area function, but we haven't found
- * a suitable way to use it yet, so let's just use them as other windows
- * with only area 0 enabled.
- */
- {RK3288_WIN2_CTRL0, 0x00000010},
- {RK3288_WIN3_CTRL0, 0x00000010},
+static const struct vop_output rk3288_output = {
+ .pin_pol = VOP_REG(RK3288_DSP_CTRL0, 0xf, 4),
+ .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
+ .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
+ .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
+ .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
+};
+
+static const struct vop_common rk3288_common = {
+ .standby = VOP_REG_SYNC(RK3288_SYS_CTRL, 0x1, 22),
+ .gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23),
+ .mmu_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 20),
+ .dither_down = VOP_REG(RK3288_DSP_CTRL1, 0xf, 1),
+ .dither_up = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6),
+ .data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19),
+ .dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18),
+ .out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0),
+ .cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0),
};
/*
@@ -267,50 +271,24 @@ static const int rk3288_vop_intrs[] = {
static const struct vop_intr rk3288_vop_intr = {
.intrs = rk3288_vop_intrs,
.nintrs = ARRAY_SIZE(rk3288_vop_intrs),
+ .line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12),
.status = VOP_REG(RK3288_INTR_CTRL0, 0xf, 0),
.enable = VOP_REG(RK3288_INTR_CTRL0, 0xf, 4),
.clear = VOP_REG(RK3288_INTR_CTRL0, 0xf, 8),
};
static const struct vop_data rk3288_vop = {
- .init_table = rk3288_init_reg_table,
- .table_size = ARRAY_SIZE(rk3288_init_reg_table),
+ .version = VOP_VERSION(3, 1),
.feature = VOP_FEATURE_OUTPUT_RGB10,
.intr = &rk3288_vop_intr,
- .ctrl = &rk3288_ctrl_data,
+ .common = &rk3288_common,
+ .modeset = &rk3288_modeset,
+ .output = &rk3288_output,
.win = rk3288_vop_win_data,
.win_size = ARRAY_SIZE(rk3288_vop_win_data),
};
-static const struct vop_ctrl rk3399_ctrl_data = {
- .standby = VOP_REG(RK3399_SYS_CTRL, 0x1, 22),
- .gate_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 23),
- .dp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11),
- .rgb_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 12),
- .hdmi_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 13),
- .edp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 14),
- .mipi_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 15),
- .dither_down = VOP_REG(RK3399_DSP_CTRL1, 0xf, 1),
- .dither_up = VOP_REG(RK3399_DSP_CTRL1, 0x1, 6),
- .data_blank = VOP_REG(RK3399_DSP_CTRL0, 0x1, 19),
- .out_mode = VOP_REG(RK3399_DSP_CTRL0, 0xf, 0),
- .rgb_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 16),
- .dp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 16),
- .hdmi_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 20),
- .edp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 24),
- .mipi_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 28),
- .htotal_pw = VOP_REG(RK3399_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
- .hact_st_end = VOP_REG(RK3399_DSP_HACT_ST_END, 0x1fff1fff, 0),
- .vtotal_pw = VOP_REG(RK3399_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
- .vact_st_end = VOP_REG(RK3399_DSP_VACT_ST_END, 0x1fff1fff, 0),
- .hpost_st_end = VOP_REG(RK3399_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
- .vpost_st_end = VOP_REG(RK3399_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
- .line_flag_num[0] = VOP_REG(RK3399_LINE_FLAG, 0xffff, 0),
- .line_flag_num[1] = VOP_REG(RK3399_LINE_FLAG, 0xffff, 16),
- .cfg_done = VOP_REG_MASK(RK3399_REG_CFG_DONE, 0x1, 0),
-};
-
-static const int rk3399_vop_intrs[] = {
+static const int rk3368_vop_intrs[] = {
FS_INTR,
0, 0,
LINE_FLAG_INTR,
@@ -320,69 +298,232 @@ static const int rk3399_vop_intrs[] = {
DSP_HOLD_VALID_INTR,
};
-static const struct vop_intr rk3399_vop_intr = {
- .intrs = rk3399_vop_intrs,
- .nintrs = ARRAY_SIZE(rk3399_vop_intrs),
- .status = VOP_REG_MASK(RK3399_INTR_STATUS0, 0xffff, 0),
- .enable = VOP_REG_MASK(RK3399_INTR_EN0, 0xffff, 0),
- .clear = VOP_REG_MASK(RK3399_INTR_CLEAR0, 0xffff, 0),
+static const struct vop_intr rk3368_vop_intr = {
+ .intrs = rk3368_vop_intrs,
+ .nintrs = ARRAY_SIZE(rk3368_vop_intrs),
+ .line_flag_num[0] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 0),
+ .line_flag_num[1] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 16),
+ .status = VOP_REG_MASK_SYNC(RK3368_INTR_STATUS, 0x3fff, 0),
+ .enable = VOP_REG_MASK_SYNC(RK3368_INTR_EN, 0x3fff, 0),
+ .clear = VOP_REG_MASK_SYNC(RK3368_INTR_CLEAR, 0x3fff, 0),
};
-static const struct vop_reg_data rk3399_init_reg_table[] = {
- {RK3399_SYS_CTRL, 0x2000f800},
- {RK3399_DSP_CTRL0, 0x00000000},
- {RK3399_WIN0_CTRL0, 0x00000080},
- {RK3399_WIN1_CTRL0, 0x00000080},
- /* TODO: Win2/3 support multiple area function, but we haven't found
- * a suitable way to use it yet, so let's just use them as other windows
- * with only area 0 enabled.
- */
- {RK3399_WIN2_CTRL0, 0x00000010},
- {RK3399_WIN3_CTRL0, 0x00000010},
+static const struct vop_win_phy rk3368_win23_data = {
+ .data_formats = formats_win_lite,
+ .nformats = ARRAY_SIZE(formats_win_lite),
+ .gate = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 0),
+ .enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 4),
+ .format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5),
+ .rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 20),
+ .dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO0, 0x0fff0fff, 0),
+ .dsp_st = VOP_REG(RK3368_WIN2_DSP_ST0, 0x1fff1fff, 0),
+ .yrgb_mst = VOP_REG(RK3368_WIN2_MST0, 0xffffffff, 0),
+ .yrgb_vir = VOP_REG(RK3368_WIN2_VIR0_1, 0x1fff, 0),
+ .src_alpha_ctl = VOP_REG(RK3368_WIN2_SRC_ALPHA_CTRL, 0xff, 0),
+ .dst_alpha_ctl = VOP_REG(RK3368_WIN2_DST_ALPHA_CTRL, 0xff, 0),
+};
+
+static const struct vop_win_data rk3368_vop_win_data[] = {
+ { .base = 0x00, .phy = &rk3288_win01_data,
+ .type = DRM_PLANE_TYPE_PRIMARY },
+ { .base = 0x40, .phy = &rk3288_win01_data,
+ .type = DRM_PLANE_TYPE_OVERLAY },
+ { .base = 0x00, .phy = &rk3368_win23_data,
+ .type = DRM_PLANE_TYPE_OVERLAY },
+ { .base = 0x50, .phy = &rk3368_win23_data,
+ .type = DRM_PLANE_TYPE_CURSOR },
+};
+
+static const struct vop_output rk3368_output = {
+ .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 16),
+ .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 20),
+ .edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 24),
+ .mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 28),
+ .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
+ .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
+ .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
+ .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
+};
+
+static const struct vop_misc rk3368_misc = {
+ .global_regdone_en = VOP_REG(RK3368_SYS_CTRL, 0x1, 11),
+};
+
+static const struct vop_data rk3368_vop = {
+ .version = VOP_VERSION(3, 2),
+ .intr = &rk3368_vop_intr,
+ .common = &rk3288_common,
+ .modeset = &rk3288_modeset,
+ .output = &rk3368_output,
+ .misc = &rk3368_misc,
+ .win = rk3368_vop_win_data,
+ .win_size = ARRAY_SIZE(rk3368_vop_win_data),
+};
+
+static const struct vop_intr rk3366_vop_intr = {
+ .intrs = rk3368_vop_intrs,
+ .nintrs = ARRAY_SIZE(rk3368_vop_intrs),
+ .line_flag_num[0] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 0),
+ .line_flag_num[1] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 16),
+ .status = VOP_REG_MASK_SYNC(RK3366_INTR_STATUS0, 0xffff, 0),
+ .enable = VOP_REG_MASK_SYNC(RK3366_INTR_EN0, 0xffff, 0),
+ .clear = VOP_REG_MASK_SYNC(RK3366_INTR_CLEAR0, 0xffff, 0),
+};
+
+static const struct vop_data rk3366_vop = {
+ .version = VOP_VERSION(3, 4),
+ .intr = &rk3366_vop_intr,
+ .common = &rk3288_common,
+ .modeset = &rk3288_modeset,
+ .output = &rk3368_output,
+ .misc = &rk3368_misc,
+ .win = rk3368_vop_win_data,
+ .win_size = ARRAY_SIZE(rk3368_vop_win_data),
+};
+
+static const struct vop_output rk3399_output = {
+ .dp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 16),
+ .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 16),
+ .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 20),
+ .edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 24),
+ .mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 28),
+ .dp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11),
+ .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
+ .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
+ .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
+ .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
};
static const struct vop_data rk3399_vop_big = {
- .init_table = rk3399_init_reg_table,
- .table_size = ARRAY_SIZE(rk3399_init_reg_table),
+ .version = VOP_VERSION(3, 5),
.feature = VOP_FEATURE_OUTPUT_RGB10,
- .intr = &rk3399_vop_intr,
- .ctrl = &rk3399_ctrl_data,
- /*
- * rk3399 vop big windows register layout is same as rk3288.
- */
- .win = rk3288_vop_win_data,
- .win_size = ARRAY_SIZE(rk3288_vop_win_data),
+ .intr = &rk3366_vop_intr,
+ .common = &rk3288_common,
+ .modeset = &rk3288_modeset,
+ .output = &rk3399_output,
+ .misc = &rk3368_misc,
+ .win = rk3368_vop_win_data,
+ .win_size = ARRAY_SIZE(rk3368_vop_win_data),
};
static const struct vop_win_data rk3399_vop_lit_win_data[] = {
{ .base = 0x00, .phy = &rk3288_win01_data,
.type = DRM_PLANE_TYPE_PRIMARY },
- { .base = 0x00, .phy = &rk3288_win23_data,
+ { .base = 0x00, .phy = &rk3368_win23_data,
.type = DRM_PLANE_TYPE_CURSOR},
};
static const struct vop_data rk3399_vop_lit = {
- .init_table = rk3399_init_reg_table,
- .table_size = ARRAY_SIZE(rk3399_init_reg_table),
- .intr = &rk3399_vop_intr,
- .ctrl = &rk3399_ctrl_data,
- /*
- * rk3399 vop lit windows register layout is same as rk3288,
- * but cut off the win1 and win3 windows.
- */
+ .version = VOP_VERSION(3, 6),
+ .intr = &rk3366_vop_intr,
+ .common = &rk3288_common,
+ .modeset = &rk3288_modeset,
+ .output = &rk3399_output,
+ .misc = &rk3368_misc,
.win = rk3399_vop_lit_win_data,
.win_size = ARRAY_SIZE(rk3399_vop_lit_win_data),
};
+static const struct vop_win_data rk3228_vop_win_data[] = {
+ { .base = 0x00, .phy = &rk3288_win01_data,
+ .type = DRM_PLANE_TYPE_PRIMARY },
+ { .base = 0x40, .phy = &rk3288_win01_data,
+ .type = DRM_PLANE_TYPE_CURSOR },
+};
+
+static const struct vop_data rk3228_vop = {
+ .version = VOP_VERSION(3, 7),
+ .feature = VOP_FEATURE_OUTPUT_RGB10,
+ .intr = &rk3366_vop_intr,
+ .common = &rk3288_common,
+ .modeset = &rk3288_modeset,
+ .output = &rk3399_output,
+ .misc = &rk3368_misc,
+ .win = rk3228_vop_win_data,
+ .win_size = ARRAY_SIZE(rk3228_vop_win_data),
+};
+
+static const struct vop_modeset rk3328_modeset = {
+ .htotal_pw = VOP_REG(RK3328_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
+ .hact_st_end = VOP_REG(RK3328_DSP_HACT_ST_END, 0x1fff1fff, 0),
+ .vtotal_pw = VOP_REG(RK3328_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
+ .vact_st_end = VOP_REG(RK3328_DSP_VACT_ST_END, 0x1fff1fff, 0),
+ .hpost_st_end = VOP_REG(RK3328_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
+ .vpost_st_end = VOP_REG(RK3328_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
+};
+
+static const struct vop_output rk3328_output = {
+ .rgb_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 12),
+ .hdmi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 13),
+ .edp_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 14),
+ .mipi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 15),
+ .rgb_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 16),
+ .hdmi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 20),
+ .edp_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 24),
+ .mipi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 28),
+};
+
+static const struct vop_misc rk3328_misc = {
+ .global_regdone_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 11),
+};
+
+static const struct vop_common rk3328_common = {
+ .standby = VOP_REG_SYNC(RK3328_SYS_CTRL, 0x1, 22),
+ .dither_down = VOP_REG(RK3328_DSP_CTRL1, 0xf, 1),
+ .dither_up = VOP_REG(RK3328_DSP_CTRL1, 0x1, 6),
+ .dsp_blank = VOP_REG(RK3328_DSP_CTRL0, 0x3, 18),
+ .out_mode = VOP_REG(RK3328_DSP_CTRL0, 0xf, 0),
+ .cfg_done = VOP_REG_SYNC(RK3328_REG_CFG_DONE, 0x1, 0),
+};
+
+static const struct vop_intr rk3328_vop_intr = {
+ .intrs = rk3368_vop_intrs,
+ .nintrs = ARRAY_SIZE(rk3368_vop_intrs),
+ .line_flag_num[0] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 0),
+ .line_flag_num[1] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 16),
+ .status = VOP_REG_MASK_SYNC(RK3328_INTR_STATUS0, 0xffff, 0),
+ .enable = VOP_REG_MASK_SYNC(RK3328_INTR_EN0, 0xffff, 0),
+ .clear = VOP_REG_MASK_SYNC(RK3328_INTR_CLEAR0, 0xffff, 0),
+};
+
+static const struct vop_win_data rk3328_vop_win_data[] = {
+ { .base = 0xd0, .phy = &rk3288_win01_data,
+ .type = DRM_PLANE_TYPE_PRIMARY },
+ { .base = 0x1d0, .phy = &rk3288_win01_data,
+ .type = DRM_PLANE_TYPE_OVERLAY },
+ { .base = 0x2d0, .phy = &rk3288_win01_data,
+ .type = DRM_PLANE_TYPE_CURSOR },
+};
+
+static const struct vop_data rk3328_vop = {
+ .version = VOP_VERSION(3, 8),
+ .feature = VOP_FEATURE_OUTPUT_RGB10,
+ .intr = &rk3328_vop_intr,
+ .common = &rk3328_common,
+ .modeset = &rk3328_modeset,
+ .output = &rk3328_output,
+ .misc = &rk3328_misc,
+ .win = rk3328_vop_win_data,
+ .win_size = ARRAY_SIZE(rk3328_vop_win_data),
+};
+
static const struct of_device_id vop_driver_dt_match[] = {
{ .compatible = "rockchip,rk3036-vop",
.data = &rk3036_vop },
{ .compatible = "rockchip,rk3288-vop",
.data = &rk3288_vop },
+ { .compatible = "rockchip,rk3368-vop",
+ .data = &rk3368_vop },
+ { .compatible = "rockchip,rk3366-vop",
+ .data = &rk3366_vop },
{ .compatible = "rockchip,rk3399-vop-big",
.data = &rk3399_vop_big },
{ .compatible = "rockchip,rk3399-vop-lit",
.data = &rk3399_vop_lit },
+ { .compatible = "rockchip,rk3228-vop",
+ .data = &rk3228_vop },
+ { .compatible = "rockchip,rk3328-vop",
+ .data = &rk3328_vop },
{},
};
MODULE_DEVICE_TABLE(of, vop_driver_dt_match);
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h
index cd19726..4a4799f 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h
@@ -41,6 +41,7 @@
#define RK3288_WIN0_SRC_ALPHA_CTRL 0x0060
#define RK3288_WIN0_DST_ALPHA_CTRL 0x0064
#define RK3288_WIN0_FADING_CTRL 0x0068
+#define RK3288_WIN0_CTRL2 0x006c
/* win1 register */
#define RK3288_WIN1_CTRL0 0x0070
@@ -122,6 +123,717 @@
#define RK3288_DSP_VACT_ST_END_F1 0x019c
/* register definition end */
+/* rk3368 register definition */
+#define RK3368_REG_CFG_DONE 0x0000
+#define RK3368_VERSION_INFO 0x0004
+#define RK3368_SYS_CTRL 0x0008
+#define RK3368_SYS_CTRL1 0x000c
+#define RK3368_DSP_CTRL0 0x0010
+#define RK3368_DSP_CTRL1 0x0014
+#define RK3368_DSP_BG 0x0018
+#define RK3368_MCU_CTRL 0x001c
+#define RK3368_LINE_FLAG 0x0020
+#define RK3368_INTR_EN 0x0024
+#define RK3368_INTR_CLEAR 0x0028
+#define RK3368_INTR_STATUS 0x002c
+#define RK3368_WIN0_CTRL0 0x0030
+#define RK3368_WIN0_CTRL1 0x0034
+#define RK3368_WIN0_COLOR_KEY 0x0038
+#define RK3368_WIN0_VIR 0x003c
+#define RK3368_WIN0_YRGB_MST 0x0040
+#define RK3368_WIN0_CBR_MST 0x0044
+#define RK3368_WIN0_ACT_INFO 0x0048
+#define RK3368_WIN0_DSP_INFO 0x004c
+#define RK3368_WIN0_DSP_ST 0x0050
+#define RK3368_WIN0_SCL_FACTOR_YRGB 0x0054
+#define RK3368_WIN0_SCL_FACTOR_CBR 0x0058
+#define RK3368_WIN0_SCL_OFFSET 0x005c
+#define RK3368_WIN0_SRC_ALPHA_CTRL 0x0060
+#define RK3368_WIN0_DST_ALPHA_CTRL 0x0064
+#define RK3368_WIN0_FADING_CTRL 0x0068
+#define RK3368_WIN0_CTRL2 0x006c
+#define RK3368_WIN1_CTRL0 0x0070
+#define RK3368_WIN1_CTRL1 0x0074
+#define RK3368_WIN1_COLOR_KEY 0x0078
+#define RK3368_WIN1_VIR 0x007c
+#define RK3368_WIN1_YRGB_MST 0x0080
+#define RK3368_WIN1_CBR_MST 0x0084
+#define RK3368_WIN1_ACT_INFO 0x0088
+#define RK3368_WIN1_DSP_INFO 0x008c
+#define RK3368_WIN1_DSP_ST 0x0090
+#define RK3368_WIN1_SCL_FACTOR_YRGB 0x0094
+#define RK3368_WIN1_SCL_FACTOR_CBR 0x0098
+#define RK3368_WIN1_SCL_OFFSET 0x009c
+#define RK3368_WIN1_SRC_ALPHA_CTRL 0x00a0
+#define RK3368_WIN1_DST_ALPHA_CTRL 0x00a4
+#define RK3368_WIN1_FADING_CTRL 0x00a8
+#define RK3368_WIN1_CTRL2 0x00ac
+#define RK3368_WIN2_CTRL0 0x00b0
+#define RK3368_WIN2_CTRL1 0x00b4
+#define RK3368_WIN2_VIR0_1 0x00b8
+#define RK3368_WIN2_VIR2_3 0x00bc
+#define RK3368_WIN2_MST0 0x00c0
+#define RK3368_WIN2_DSP_INFO0 0x00c4
+#define RK3368_WIN2_DSP_ST0 0x00c8
+#define RK3368_WIN2_COLOR_KEY 0x00cc
+#define RK3368_WIN2_MST1 0x00d0
+#define RK3368_WIN2_DSP_INFO1 0x00d4
+#define RK3368_WIN2_DSP_ST1 0x00d8
+#define RK3368_WIN2_SRC_ALPHA_CTRL 0x00dc
+#define RK3368_WIN2_MST2 0x00e0
+#define RK3368_WIN2_DSP_INFO2 0x00e4
+#define RK3368_WIN2_DSP_ST2 0x00e8
+#define RK3368_WIN2_DST_ALPHA_CTRL 0x00ec
+#define RK3368_WIN2_MST3 0x00f0
+#define RK3368_WIN2_DSP_INFO3 0x00f4
+#define RK3368_WIN2_DSP_ST3 0x00f8
+#define RK3368_WIN2_FADING_CTRL 0x00fc
+#define RK3368_WIN3_CTRL0 0x0100
+#define RK3368_WIN3_CTRL1 0x0104
+#define RK3368_WIN3_VIR0_1 0x0108
+#define RK3368_WIN3_VIR2_3 0x010c
+#define RK3368_WIN3_MST0 0x0110
+#define RK3368_WIN3_DSP_INFO0 0x0114
+#define RK3368_WIN3_DSP_ST0 0x0118
+#define RK3368_WIN3_COLOR_KEY 0x011c
+#define RK3368_WIN3_MST1 0x0120
+#define RK3368_WIN3_DSP_INFO1 0x0124
+#define RK3368_WIN3_DSP_ST1 0x0128
+#define RK3368_WIN3_SRC_ALPHA_CTRL 0x012c
+#define RK3368_WIN3_MST2 0x0130
+#define RK3368_WIN3_DSP_INFO2 0x0134
+#define RK3368_WIN3_DSP_ST2 0x0138
+#define RK3368_WIN3_DST_ALPHA_CTRL 0x013c
+#define RK3368_WIN3_MST3 0x0140
+#define RK3368_WIN3_DSP_INFO3 0x0144
+#define RK3368_WIN3_DSP_ST3 0x0148
+#define RK3368_WIN3_FADING_CTRL 0x014c
+#define RK3368_HWC_CTRL0 0x0150
+#define RK3368_HWC_CTRL1 0x0154
+#define RK3368_HWC_MST 0x0158
+#define RK3368_HWC_DSP_ST 0x015c
+#define RK3368_HWC_SRC_ALPHA_CTRL 0x0160
+#define RK3368_HWC_DST_ALPHA_CTRL 0x0164
+#define RK3368_HWC_FADING_CTRL 0x0168
+#define RK3368_HWC_RESERVED1 0x016c
+#define RK3368_POST_DSP_HACT_INFO 0x0170
+#define RK3368_POST_DSP_VACT_INFO 0x0174
+#define RK3368_POST_SCL_FACTOR_YRGB 0x0178
+#define RK3368_POST_RESERVED 0x017c
+#define RK3368_POST_SCL_CTRL 0x0180
+#define RK3368_POST_DSP_VACT_INFO_F1 0x0184
+#define RK3368_DSP_HTOTAL_HS_END 0x0188
+#define RK3368_DSP_HACT_ST_END 0x018c
+#define RK3368_DSP_VTOTAL_VS_END 0x0190
+#define RK3368_DSP_VACT_ST_END 0x0194
+#define RK3368_DSP_VS_ST_END_F1 0x0198
+#define RK3368_DSP_VACT_ST_END_F1 0x019c
+#define RK3368_PWM_CTRL 0x01a0
+#define RK3368_PWM_PERIOD_HPR 0x01a4
+#define RK3368_PWM_DUTY_LPR 0x01a8
+#define RK3368_PWM_CNT 0x01ac
+#define RK3368_BCSH_COLOR_BAR 0x01b0
+#define RK3368_BCSH_BCS 0x01b4
+#define RK3368_BCSH_H 0x01b8
+#define RK3368_BCSH_CTRL 0x01bc
+#define RK3368_CABC_CTRL0 0x01c0
+#define RK3368_CABC_CTRL1 0x01c4
+#define RK3368_CABC_CTRL2 0x01c8
+#define RK3368_CABC_CTRL3 0x01cc
+#define RK3368_CABC_GAUSS_LINE0_0 0x01d0
+#define RK3368_CABC_GAUSS_LINE0_1 0x01d4
+#define RK3368_CABC_GAUSS_LINE1_0 0x01d8
+#define RK3368_CABC_GAUSS_LINE1_1 0x01dc
+#define RK3368_CABC_GAUSS_LINE2_0 0x01e0
+#define RK3368_CABC_GAUSS_LINE2_1 0x01e4
+#define RK3368_FRC_LOWER01_0 0x01e8
+#define RK3368_FRC_LOWER01_1 0x01ec
+#define RK3368_FRC_LOWER10_0 0x01f0
+#define RK3368_FRC_LOWER10_1 0x01f4
+#define RK3368_FRC_LOWER11_0 0x01f8
+#define RK3368_FRC_LOWER11_1 0x01fc
+#define RK3368_IFBDC_CTRL 0x0200
+#define RK3368_IFBDC_TILES_NUM 0x0204
+#define RK3368_IFBDC_FRAME_RST_CYCLE 0x0208
+#define RK3368_IFBDC_BASE_ADDR 0x020c
+#define RK3368_IFBDC_MB_SIZE 0x0210
+#define RK3368_IFBDC_CMP_INDEX_INIT 0x0214
+#define RK3368_IFBDC_VIR 0x0220
+#define RK3368_IFBDC_DEBUG0 0x0230
+#define RK3368_IFBDC_DEBUG1 0x0234
+#define RK3368_LATENCY_CTRL0 0x0250
+#define RK3368_RD_MAX_LATENCY_NUM0 0x0254
+#define RK3368_RD_LATENCY_THR_NUM0 0x0258
+#define RK3368_RD_LATENCY_SAMP_NUM0 0x025c
+#define RK3368_WIN0_DSP_BG 0x0260
+#define RK3368_WIN1_DSP_BG 0x0264
+#define RK3368_WIN2_DSP_BG 0x0268
+#define RK3368_WIN3_DSP_BG 0x026c
+#define RK3368_SCAN_LINE_NUM 0x0270
+#define RK3368_CABC_DEBUG0 0x0274
+#define RK3368_CABC_DEBUG1 0x0278
+#define RK3368_CABC_DEBUG2 0x027c
+#define RK3368_DBG_REG_000 0x0280
+#define RK3368_DBG_REG_001 0x0284
+#define RK3368_DBG_REG_002 0x0288
+#define RK3368_DBG_REG_003 0x028c
+#define RK3368_DBG_REG_004 0x0290
+#define RK3368_DBG_REG_005 0x0294
+#define RK3368_DBG_REG_006 0x0298
+#define RK3368_DBG_REG_007 0x029c
+#define RK3368_DBG_REG_008 0x02a0
+#define RK3368_DBG_REG_016 0x02c0
+#define RK3368_DBG_REG_017 0x02c4
+#define RK3368_DBG_REG_018 0x02c8
+#define RK3368_DBG_REG_019 0x02cc
+#define RK3368_DBG_REG_020 0x02d0
+#define RK3368_DBG_REG_021 0x02d4
+#define RK3368_DBG_REG_022 0x02d8
+#define RK3368_DBG_REG_023 0x02dc
+#define RK3368_DBG_REG_028 0x02f0
+#define RK3368_MMU_DTE_ADDR 0x0300
+#define RK3368_MMU_STATUS 0x0304
+#define RK3368_MMU_COMMAND 0x0308
+#define RK3368_MMU_PAGE_FAULT_ADDR 0x030c
+#define RK3368_MMU_ZAP_ONE_LINE 0x0310
+#define RK3368_MMU_INT_RAWSTAT 0x0314
+#define RK3368_MMU_INT_CLEAR 0x0318
+#define RK3368_MMU_INT_MASK 0x031c
+#define RK3368_MMU_INT_STATUS 0x0320
+#define RK3368_MMU_AUTO_GATING 0x0324
+#define RK3368_WIN2_LUT_ADDR 0x0400
+#define RK3368_WIN3_LUT_ADDR 0x0800
+#define RK3368_HWC_LUT_ADDR 0x0c00
+#define RK3368_GAMMA_LUT_ADDR 0x1000
+#define RK3368_CABC_GAMMA_LUT_ADDR 0x1800
+#define RK3368_MCU_BYPASS_WPORT 0x2200
+#define RK3368_MCU_BYPASS_RPORT 0x2300
+/* rk3368 register definition end */
+
+#define RK3366_REG_CFG_DONE 0x0000
+#define RK3366_VERSION_INFO 0x0004
+#define RK3366_SYS_CTRL 0x0008
+#define RK3366_SYS_CTRL1 0x000c
+#define RK3366_DSP_CTRL0 0x0010
+#define RK3366_DSP_CTRL1 0x0014
+#define RK3366_DSP_BG 0x0018
+#define RK3366_MCU_CTRL 0x001c
+#define RK3366_WB_CTRL0 0x0020
+#define RK3366_WB_CTRL1 0x0024
+#define RK3366_WB_YRGB_MST 0x0028
+#define RK3366_WB_CBR_MST 0x002c
+#define RK3366_WIN0_CTRL0 0x0030
+#define RK3366_WIN0_CTRL1 0x0034
+#define RK3366_WIN0_COLOR_KEY 0x0038
+#define RK3366_WIN0_VIR 0x003c
+#define RK3366_WIN0_YRGB_MST 0x0040
+#define RK3366_WIN0_CBR_MST 0x0044
+#define RK3366_WIN0_ACT_INFO 0x0048
+#define RK3366_WIN0_DSP_INFO 0x004c
+#define RK3366_WIN0_DSP_ST 0x0050
+#define RK3366_WIN0_SCL_FACTOR_YRGB 0x0054
+#define RK3366_WIN0_SCL_FACTOR_CBR 0x0058
+#define RK3366_WIN0_SCL_OFFSET 0x005c
+#define RK3366_WIN0_SRC_ALPHA_CTRL 0x0060
+#define RK3366_WIN0_DST_ALPHA_CTRL 0x0064
+#define RK3366_WIN0_FADING_CTRL 0x0068
+#define RK3366_WIN0_CTRL2 0x006c
+#define RK3366_WIN1_CTRL0 0x0070
+#define RK3366_WIN1_CTRL1 0x0074
+#define RK3366_WIN1_COLOR_KEY 0x0078
+#define RK3366_WIN1_VIR 0x007c
+#define RK3366_WIN1_YRGB_MST 0x0080
+#define RK3366_WIN1_CBR_MST 0x0084
+#define RK3366_WIN1_ACT_INFO 0x0088
+#define RK3366_WIN1_DSP_INFO 0x008c
+#define RK3366_WIN1_DSP_ST 0x0090
+#define RK3366_WIN1_SCL_FACTOR_YRGB 0x0094
+#define RK3366_WIN1_SCL_FACTOR_CBR 0x0098
+#define RK3366_WIN1_SCL_OFFSET 0x009c
+#define RK3366_WIN1_SRC_ALPHA_CTRL 0x00a0
+#define RK3366_WIN1_DST_ALPHA_CTRL 0x00a4
+#define RK3366_WIN1_FADING_CTRL 0x00a8
+#define RK3366_WIN1_CTRL2 0x00ac
+#define RK3366_WIN2_CTRL0 0x00b0
+#define RK3366_WIN2_CTRL1 0x00b4
+#define RK3366_WIN2_VIR0_1 0x00b8
+#define RK3366_WIN2_VIR2_3 0x00bc
+#define RK3366_WIN2_MST0 0x00c0
+#define RK3366_WIN2_DSP_INFO0 0x00c4
+#define RK3366_WIN2_DSP_ST0 0x00c8
+#define RK3366_WIN2_COLOR_KEY 0x00cc
+#define RK3366_WIN2_MST1 0x00d0
+#define RK3366_WIN2_DSP_INFO1 0x00d4
+#define RK3366_WIN2_DSP_ST1 0x00d8
+#define RK3366_WIN2_SRC_ALPHA_CTRL 0x00dc
+#define RK3366_WIN2_MST2 0x00e0
+#define RK3366_WIN2_DSP_INFO2 0x00e4
+#define RK3366_WIN2_DSP_ST2 0x00e8
+#define RK3366_WIN2_DST_ALPHA_CTRL 0x00ec
+#define RK3366_WIN2_MST3 0x00f0
+#define RK3366_WIN2_DSP_INFO3 0x00f4
+#define RK3366_WIN2_DSP_ST3 0x00f8
+#define RK3366_WIN2_FADING_CTRL 0x00fc
+#define RK3366_WIN3_CTRL0 0x0100
+#define RK3366_WIN3_CTRL1 0x0104
+#define RK3366_WIN3_VIR0_1 0x0108
+#define RK3366_WIN3_VIR2_3 0x010c
+#define RK3366_WIN3_MST0 0x0110
+#define RK3366_WIN3_DSP_INFO0 0x0114
+#define RK3366_WIN3_DSP_ST0 0x0118
+#define RK3366_WIN3_COLOR_KEY 0x011c
+#define RK3366_WIN3_MST1 0x0120
+#define RK3366_WIN3_DSP_INFO1 0x0124
+#define RK3366_WIN3_DSP_ST1 0x0128
+#define RK3366_WIN3_SRC_ALPHA_CTRL 0x012c
+#define RK3366_WIN3_MST2 0x0130
+#define RK3366_WIN3_DSP_INFO2 0x0134
+#define RK3366_WIN3_DSP_ST2 0x0138
+#define RK3366_WIN3_DST_ALPHA_CTRL 0x013c
+#define RK3366_WIN3_MST3 0x0140
+#define RK3366_WIN3_DSP_INFO3 0x0144
+#define RK3366_WIN3_DSP_ST3 0x0148
+#define RK3366_WIN3_FADING_CTRL 0x014c
+#define RK3366_HWC_CTRL0 0x0150
+#define RK3366_HWC_CTRL1 0x0154
+#define RK3366_HWC_MST 0x0158
+#define RK3366_HWC_DSP_ST 0x015c
+#define RK3366_HWC_SRC_ALPHA_CTRL 0x0160
+#define RK3366_HWC_DST_ALPHA_CTRL 0x0164
+#define RK3366_HWC_FADING_CTRL 0x0168
+#define RK3366_HWC_RESERVED1 0x016c
+#define RK3366_POST_DSP_HACT_INFO 0x0170
+#define RK3366_POST_DSP_VACT_INFO 0x0174
+#define RK3366_POST_SCL_FACTOR_YRGB 0x0178
+#define RK3366_POST_RESERVED 0x017c
+#define RK3366_POST_SCL_CTRL 0x0180
+#define RK3366_POST_DSP_VACT_INFO_F1 0x0184
+#define RK3366_DSP_HTOTAL_HS_END 0x0188
+#define RK3366_DSP_HACT_ST_END 0x018c
+#define RK3366_DSP_VTOTAL_VS_END 0x0190
+#define RK3366_DSP_VACT_ST_END 0x0194
+#define RK3366_DSP_VS_ST_END_F1 0x0198
+#define RK3366_DSP_VACT_ST_END_F1 0x019c
+#define RK3366_PWM_CTRL 0x01a0
+#define RK3366_PWM_PERIOD_HPR 0x01a4
+#define RK3366_PWM_DUTY_LPR 0x01a8
+#define RK3366_PWM_CNT 0x01ac
+#define RK3366_BCSH_COLOR_BAR 0x01b0
+#define RK3366_BCSH_BCS 0x01b4
+#define RK3366_BCSH_H 0x01b8
+#define RK3366_BCSH_CTRL 0x01bc
+#define RK3366_CABC_CTRL0 0x01c0
+#define RK3366_CABC_CTRL1 0x01c4
+#define RK3366_CABC_CTRL2 0x01c8
+#define RK3366_CABC_CTRL3 0x01cc
+#define RK3366_CABC_GAUSS_LINE0_0 0x01d0
+#define RK3366_CABC_GAUSS_LINE0_1 0x01d4
+#define RK3366_CABC_GAUSS_LINE1_0 0x01d8
+#define RK3366_CABC_GAUSS_LINE1_1 0x01dc
+#define RK3366_CABC_GAUSS_LINE2_0 0x01e0
+#define RK3366_CABC_GAUSS_LINE2_1 0x01e4
+#define RK3366_FRC_LOWER01_0 0x01e8
+#define RK3366_FRC_LOWER01_1 0x01ec
+#define RK3366_FRC_LOWER10_0 0x01f0
+#define RK3366_FRC_LOWER10_1 0x01f4
+#define RK3366_FRC_LOWER11_0 0x01f8
+#define RK3366_FRC_LOWER11_1 0x01fc
+#define RK3366_INTR_EN0 0x0280
+#define RK3366_INTR_CLEAR0 0x0284
+#define RK3366_INTR_STATUS0 0x0288
+#define RK3366_INTR_RAW_STATUS0 0x028c
+#define RK3366_INTR_EN1 0x0290
+#define RK3366_INTR_CLEAR1 0x0294
+#define RK3366_INTR_STATUS1 0x0298
+#define RK3366_INTR_RAW_STATUS1 0x029c
+#define RK3366_LINE_FLAG 0x02a0
+#define RK3366_VOP_STATUS 0x02a4
+#define RK3366_BLANKING_VALUE 0x02a8
+#define RK3366_WIN0_DSP_BG 0x02b0
+#define RK3366_WIN1_DSP_BG 0x02b4
+#define RK3366_WIN2_DSP_BG 0x02b8
+#define RK3366_WIN3_DSP_BG 0x02bc
+#define RK3366_WIN2_LUT_ADDR 0x0400
+#define RK3366_WIN3_LUT_ADDR 0x0800
+#define RK3366_HWC_LUT_ADDR 0x0c00
+#define RK3366_GAMMA0_LUT_ADDR 0x1000
+#define RK3366_GAMMA1_LUT_ADDR 0x1400
+#define RK3366_CABC_GAMMA_LUT_ADDR 0x1800
+#define RK3366_MCU_BYPASS_WPORT 0x2200
+#define RK3366_MCU_BYPASS_RPORT 0x2300
+#define RK3366_MMU_DTE_ADDR 0x2400
+#define RK3366_MMU_STATUS 0x2404
+#define RK3366_MMU_COMMAND 0x2408
+#define RK3366_MMU_PAGE_FAULT_ADDR 0x240c
+#define RK3366_MMU_ZAP_ONE_LINE 0x2410
+#define RK3366_MMU_INT_RAWSTAT 0x2414
+#define RK3366_MMU_INT_CLEAR 0x2418
+#define RK3366_MMU_INT_MASK 0x241c
+#define RK3366_MMU_INT_STATUS 0x2420
+#define RK3366_MMU_AUTO_GATING 0x2424
+
+/* rk3399 register definition */
+#define RK3399_REG_CFG_DONE 0x0000
+#define RK3399_VERSION_INFO 0x0004
+#define RK3399_SYS_CTRL 0x0008
+#define RK3399_SYS_CTRL1 0x000c
+#define RK3399_DSP_CTRL0 0x0010
+#define RK3399_DSP_CTRL1 0x0014
+#define RK3399_DSP_BG 0x0018
+#define RK3399_MCU_CTRL 0x001c
+#define RK3399_WB_CTRL0 0x0020
+#define RK3399_WB_CTRL1 0x0024
+#define RK3399_WB_YRGB_MST 0x0028
+#define RK3399_WB_CBR_MST 0x002c
+#define RK3399_WIN0_CTRL0 0x0030
+#define RK3399_WIN0_CTRL1 0x0034
+#define RK3399_WIN0_COLOR_KEY 0x0038
+#define RK3399_WIN0_VIR 0x003c
+#define RK3399_WIN0_YRGB_MST 0x0040
+#define RK3399_WIN0_CBR_MST 0x0044
+#define RK3399_WIN0_ACT_INFO 0x0048
+#define RK3399_WIN0_DSP_INFO 0x004c
+#define RK3399_WIN0_DSP_ST 0x0050
+#define RK3399_WIN0_SCL_FACTOR_YRGB 0x0054
+#define RK3399_WIN0_SCL_FACTOR_CBR 0x0058
+#define RK3399_WIN0_SCL_OFFSET 0x005c
+#define RK3399_WIN0_SRC_ALPHA_CTRL 0x0060
+#define RK3399_WIN0_DST_ALPHA_CTRL 0x0064
+#define RK3399_WIN0_FADING_CTRL 0x0068
+#define RK3399_WIN0_CTRL2 0x006c
+#define RK3399_WIN1_CTRL0 0x0070
+#define RK3399_WIN1_CTRL1 0x0074
+#define RK3399_WIN1_COLOR_KEY 0x0078
+#define RK3399_WIN1_VIR 0x007c
+#define RK3399_WIN1_YRGB_MST 0x0080
+#define RK3399_WIN1_CBR_MST 0x0084
+#define RK3399_WIN1_ACT_INFO 0x0088
+#define RK3399_WIN1_DSP_INFO 0x008c
+#define RK3399_WIN1_DSP_ST 0x0090
+#define RK3399_WIN1_SCL_FACTOR_YRGB 0x0094
+#define RK3399_WIN1_SCL_FACTOR_CBR 0x0098
+#define RK3399_WIN1_SCL_OFFSET 0x009c
+#define RK3399_WIN1_SRC_ALPHA_CTRL 0x00a0
+#define RK3399_WIN1_DST_ALPHA_CTRL 0x00a4
+#define RK3399_WIN1_FADING_CTRL 0x00a8
+#define RK3399_WIN1_CTRL2 0x00ac
+#define RK3399_WIN2_CTRL0 0x00b0
+#define RK3399_WIN2_CTRL1 0x00b4
+#define RK3399_WIN2_VIR0_1 0x00b8
+#define RK3399_WIN2_VIR2_3 0x00bc
+#define RK3399_WIN2_MST0 0x00c0
+#define RK3399_WIN2_DSP_INFO0 0x00c4
+#define RK3399_WIN2_DSP_ST0 0x00c8
+#define RK3399_WIN2_COLOR_KEY 0x00cc
+#define RK3399_WIN2_MST1 0x00d0
+#define RK3399_WIN2_DSP_INFO1 0x00d4
+#define RK3399_WIN2_DSP_ST1 0x00d8
+#define RK3399_WIN2_SRC_ALPHA_CTRL 0x00dc
+#define RK3399_WIN2_MST2 0x00e0
+#define RK3399_WIN2_DSP_INFO2 0x00e4
+#define RK3399_WIN2_DSP_ST2 0x00e8
+#define RK3399_WIN2_DST_ALPHA_CTRL 0x00ec
+#define RK3399_WIN2_MST3 0x00f0
+#define RK3399_WIN2_DSP_INFO3 0x00f4
+#define RK3399_WIN2_DSP_ST3 0x00f8
+#define RK3399_WIN2_FADING_CTRL 0x00fc
+#define RK3399_WIN3_CTRL0 0x0100
+#define RK3399_WIN3_CTRL1 0x0104
+#define RK3399_WIN3_VIR0_1 0x0108
+#define RK3399_WIN3_VIR2_3 0x010c
+#define RK3399_WIN3_MST0 0x0110
+#define RK3399_WIN3_DSP_INFO0 0x0114
+#define RK3399_WIN3_DSP_ST0 0x0118
+#define RK3399_WIN3_COLOR_KEY 0x011c
+#define RK3399_WIN3_MST1 0x0120
+#define RK3399_WIN3_DSP_INFO1 0x0124
+#define RK3399_WIN3_DSP_ST1 0x0128
+#define RK3399_WIN3_SRC_ALPHA_CTRL 0x012c
+#define RK3399_WIN3_MST2 0x0130
+#define RK3399_WIN3_DSP_INFO2 0x0134
+#define RK3399_WIN3_DSP_ST2 0x0138
+#define RK3399_WIN3_DST_ALPHA_CTRL 0x013c
+#define RK3399_WIN3_MST3 0x0140
+#define RK3399_WIN3_DSP_INFO3 0x0144
+#define RK3399_WIN3_DSP_ST3 0x0148
+#define RK3399_WIN3_FADING_CTRL 0x014c
+#define RK3399_HWC_CTRL0 0x0150
+#define RK3399_HWC_CTRL1 0x0154
+#define RK3399_HWC_MST 0x0158
+#define RK3399_HWC_DSP_ST 0x015c
+#define RK3399_HWC_SRC_ALPHA_CTRL 0x0160
+#define RK3399_HWC_DST_ALPHA_CTRL 0x0164
+#define RK3399_HWC_FADING_CTRL 0x0168
+#define RK3399_HWC_RESERVED1 0x016c
+#define RK3399_POST_DSP_HACT_INFO 0x0170
+#define RK3399_POST_DSP_VACT_INFO 0x0174
+#define RK3399_POST_SCL_FACTOR_YRGB 0x0178
+#define RK3399_POST_RESERVED 0x017c
+#define RK3399_POST_SCL_CTRL 0x0180
+#define RK3399_POST_DSP_VACT_INFO_F1 0x0184
+#define RK3399_DSP_HTOTAL_HS_END 0x0188
+#define RK3399_DSP_HACT_ST_END 0x018c
+#define RK3399_DSP_VTOTAL_VS_END 0x0190
+#define RK3399_DSP_VACT_ST_END 0x0194
+#define RK3399_DSP_VS_ST_END_F1 0x0198
+#define RK3399_DSP_VACT_ST_END_F1 0x019c
+#define RK3399_PWM_CTRL 0x01a0
+#define RK3399_PWM_PERIOD_HPR 0x01a4
+#define RK3399_PWM_DUTY_LPR 0x01a8
+#define RK3399_PWM_CNT 0x01ac
+#define RK3399_BCSH_COLOR_BAR 0x01b0
+#define RK3399_BCSH_BCS 0x01b4
+#define RK3399_BCSH_H 0x01b8
+#define RK3399_BCSH_CTRL 0x01bc
+#define RK3399_CABC_CTRL0 0x01c0
+#define RK3399_CABC_CTRL1 0x01c4
+#define RK3399_CABC_CTRL2 0x01c8
+#define RK3399_CABC_CTRL3 0x01cc
+#define RK3399_CABC_GAUSS_LINE0_0 0x01d0
+#define RK3399_CABC_GAUSS_LINE0_1 0x01d4
+#define RK3399_CABC_GAUSS_LINE1_0 0x01d8
+#define RK3399_CABC_GAUSS_LINE1_1 0x01dc
+#define RK3399_CABC_GAUSS_LINE2_0 0x01e0
+#define RK3399_CABC_GAUSS_LINE2_1 0x01e4
+#define RK3399_FRC_LOWER01_0 0x01e8
+#define RK3399_FRC_LOWER01_1 0x01ec
+#define RK3399_FRC_LOWER10_0 0x01f0
+#define RK3399_FRC_LOWER10_1 0x01f4
+#define RK3399_FRC_LOWER11_0 0x01f8
+#define RK3399_FRC_LOWER11_1 0x01fc
+#define RK3399_AFBCD0_CTRL 0x0200
+#define RK3399_AFBCD0_HDR_PTR 0x0204
+#define RK3399_AFBCD0_PIC_SIZE 0x0208
+#define RK3399_AFBCD0_STATUS 0x020c
+#define RK3399_AFBCD1_CTRL 0x0220
+#define RK3399_AFBCD1_HDR_PTR 0x0224
+#define RK3399_AFBCD1_PIC_SIZE 0x0228
+#define RK3399_AFBCD1_STATUS 0x022c
+#define RK3399_AFBCD2_CTRL 0x0240
+#define RK3399_AFBCD2_HDR_PTR 0x0244
+#define RK3399_AFBCD2_PIC_SIZE 0x0248
+#define RK3399_AFBCD2_STATUS 0x024c
+#define RK3399_AFBCD3_CTRL 0x0260
+#define RK3399_AFBCD3_HDR_PTR 0x0264
+#define RK3399_AFBCD3_PIC_SIZE 0x0268
+#define RK3399_AFBCD3_STATUS 0x026c
+#define RK3399_INTR_EN0 0x0280
+#define RK3399_INTR_CLEAR0 0x0284
+#define RK3399_INTR_STATUS0 0x0288
+#define RK3399_INTR_RAW_STATUS0 0x028c
+#define RK3399_INTR_EN1 0x0290
+#define RK3399_INTR_CLEAR1 0x0294
+#define RK3399_INTR_STATUS1 0x0298
+#define RK3399_INTR_RAW_STATUS1 0x029c
+#define RK3399_LINE_FLAG 0x02a0
+#define RK3399_VOP_STATUS 0x02a4
+#define RK3399_BLANKING_VALUE 0x02a8
+#define RK3399_MCU_BYPASS_PORT 0x02ac
+#define RK3399_WIN0_DSP_BG 0x02b0
+#define RK3399_WIN1_DSP_BG 0x02b4
+#define RK3399_WIN2_DSP_BG 0x02b8
+#define RK3399_WIN3_DSP_BG 0x02bc
+#define RK3399_YUV2YUV_WIN 0x02c0
+#define RK3399_YUV2YUV_POST 0x02c4
+#define RK3399_AUTO_GATING_EN 0x02cc
+#define RK3399_WIN0_CSC_COE 0x03a0
+#define RK3399_WIN1_CSC_COE 0x03c0
+#define RK3399_WIN2_CSC_COE 0x03e0
+#define RK3399_WIN3_CSC_COE 0x0400
+#define RK3399_HWC_CSC_COE 0x0420
+#define RK3399_BCSH_R2Y_CSC_COE 0x0440
+#define RK3399_BCSH_Y2R_CSC_COE 0x0460
+#define RK3399_POST_YUV2YUV_Y2R_COE 0x0480
+#define RK3399_POST_YUV2YUV_3X3_COE 0x04a0
+#define RK3399_POST_YUV2YUV_R2Y_COE 0x04c0
+#define RK3399_WIN0_YUV2YUV_Y2R 0x04e0
+#define RK3399_WIN0_YUV2YUV_3X3 0x0500
+#define RK3399_WIN0_YUV2YUV_R2Y 0x0520
+#define RK3399_WIN1_YUV2YUV_Y2R 0x0540
+#define RK3399_WIN1_YUV2YUV_3X3 0x0560
+#define RK3399_WIN1_YUV2YUV_R2Y 0x0580
+#define RK3399_WIN2_YUV2YUV_Y2R 0x05a0
+#define RK3399_WIN2_YUV2YUV_3X3 0x05c0
+#define RK3399_WIN2_YUV2YUV_R2Y 0x05e0
+#define RK3399_WIN3_YUV2YUV_Y2R 0x0600
+#define RK3399_WIN3_YUV2YUV_3X3 0x0620
+#define RK3399_WIN3_YUV2YUV_R2Y 0x0640
+#define RK3399_WIN2_LUT_ADDR 0x1000
+#define RK3399_WIN3_LUT_ADDR 0x1400
+#define RK3399_HWC_LUT_ADDR 0x1800
+#define RK3399_CABC_GAMMA_LUT_ADDR 0x1c00
+#define RK3399_GAMMA_LUT_ADDR 0x2000
+/* rk3399 register definition end */
+
+/* rk3328 register definition end */
+#define RK3328_REG_CFG_DONE 0x00000000
+#define RK3328_VERSION_INFO 0x00000004
+#define RK3328_SYS_CTRL 0x00000008
+#define RK3328_SYS_CTRL1 0x0000000c
+#define RK3328_DSP_CTRL0 0x00000010
+#define RK3328_DSP_CTRL1 0x00000014
+#define RK3328_DSP_BG 0x00000018
+#define RK3328_AUTO_GATING_EN 0x0000003c
+#define RK3328_LINE_FLAG 0x00000040
+#define RK3328_VOP_STATUS 0x00000044
+#define RK3328_BLANKING_VALUE 0x00000048
+#define RK3328_WIN0_DSP_BG 0x00000050
+#define RK3328_WIN1_DSP_BG 0x00000054
+#define RK3328_DBG_PERF_LATENCY_CTRL0 0x000000c0
+#define RK3328_DBG_PERF_RD_MAX_LATENCY_NUM0 0x000000c4
+#define RK3328_DBG_PERF_RD_LATENCY_THR_NUM0 0x000000c8
+#define RK3328_DBG_PERF_RD_LATENCY_SAMP_NUM0 0x000000cc
+#define RK3328_INTR_EN0 0x000000e0
+#define RK3328_INTR_CLEAR0 0x000000e4
+#define RK3328_INTR_STATUS0 0x000000e8
+#define RK3328_INTR_RAW_STATUS0 0x000000ec
+#define RK3328_INTR_EN1 0x000000f0
+#define RK3328_INTR_CLEAR1 0x000000f4
+#define RK3328_INTR_STATUS1 0x000000f8
+#define RK3328_INTR_RAW_STATUS1 0x000000fc
+#define RK3328_WIN0_CTRL0 0x00000100
+#define RK3328_WIN0_CTRL1 0x00000104
+#define RK3328_WIN0_COLOR_KEY 0x00000108
+#define RK3328_WIN0_VIR 0x0000010c
+#define RK3328_WIN0_YRGB_MST 0x00000110
+#define RK3328_WIN0_CBR_MST 0x00000114
+#define RK3328_WIN0_ACT_INFO 0x00000118
+#define RK3328_WIN0_DSP_INFO 0x0000011c
+#define RK3328_WIN0_DSP_ST 0x00000120
+#define RK3328_WIN0_SCL_FACTOR_YRGB 0x00000124
+#define RK3328_WIN0_SCL_FACTOR_CBR 0x00000128
+#define RK3328_WIN0_SCL_OFFSET 0x0000012c
+#define RK3328_WIN0_SRC_ALPHA_CTRL 0x00000130
+#define RK3328_WIN0_DST_ALPHA_CTRL 0x00000134
+#define RK3328_WIN0_FADING_CTRL 0x00000138
+#define RK3328_WIN0_CTRL2 0x0000013c
+#define RK3328_DBG_WIN0_REG0 0x000001f0
+#define RK3328_DBG_WIN0_REG1 0x000001f4
+#define RK3328_DBG_WIN0_REG2 0x000001f8
+#define RK3328_DBG_WIN0_RESERVED 0x000001fc
+#define RK3328_WIN1_CTRL0 0x00000200
+#define RK3328_WIN1_CTRL1 0x00000204
+#define RK3328_WIN1_COLOR_KEY 0x00000208
+#define RK3328_WIN1_VIR 0x0000020c
+#define RK3328_WIN1_YRGB_MST 0x00000210
+#define RK3328_WIN1_CBR_MST 0x00000214
+#define RK3328_WIN1_ACT_INFO 0x00000218
+#define RK3328_WIN1_DSP_INFO 0x0000021c
+#define RK3328_WIN1_DSP_ST 0x00000220
+#define RK3328_WIN1_SCL_FACTOR_YRGB 0x00000224
+#define RK3328_WIN1_SCL_FACTOR_CBR 0x00000228
+#define RK3328_WIN1_SCL_OFFSET 0x0000022c
+#define RK3328_WIN1_SRC_ALPHA_CTRL 0x00000230
+#define RK3328_WIN1_DST_ALPHA_CTRL 0x00000234
+#define RK3328_WIN1_FADING_CTRL 0x00000238
+#define RK3328_WIN1_CTRL2 0x0000023c
+#define RK3328_DBG_WIN1_REG0 0x000002f0
+#define RK3328_DBG_WIN1_REG1 0x000002f4
+#define RK3328_DBG_WIN1_REG2 0x000002f8
+#define RK3328_DBG_WIN1_RESERVED 0x000002fc
+#define RK3328_WIN2_CTRL0 0x00000300
+#define RK3328_WIN2_CTRL1 0x00000304
+#define RK3328_WIN2_COLOR_KEY 0x00000308
+#define RK3328_WIN2_VIR 0x0000030c
+#define RK3328_WIN2_YRGB_MST 0x00000310
+#define RK3328_WIN2_CBR_MST 0x00000314
+#define RK3328_WIN2_ACT_INFO 0x00000318
+#define RK3328_WIN2_DSP_INFO 0x0000031c
+#define RK3328_WIN2_DSP_ST 0x00000320
+#define RK3328_WIN2_SCL_FACTOR_YRGB 0x00000324
+#define RK3328_WIN2_SCL_FACTOR_CBR 0x00000328
+#define RK3328_WIN2_SCL_OFFSET 0x0000032c
+#define RK3328_WIN2_SRC_ALPHA_CTRL 0x00000330
+#define RK3328_WIN2_DST_ALPHA_CTRL 0x00000334
+#define RK3328_WIN2_FADING_CTRL 0x00000338
+#define RK3328_WIN2_CTRL2 0x0000033c
+#define RK3328_DBG_WIN2_REG0 0x000003f0
+#define RK3328_DBG_WIN2_REG1 0x000003f4
+#define RK3328_DBG_WIN2_REG2 0x000003f8
+#define RK3328_DBG_WIN2_RESERVED 0x000003fc
+#define RK3328_WIN3_CTRL0 0x00000400
+#define RK3328_WIN3_CTRL1 0x00000404
+#define RK3328_WIN3_COLOR_KEY 0x00000408
+#define RK3328_WIN3_VIR 0x0000040c
+#define RK3328_WIN3_YRGB_MST 0x00000410
+#define RK3328_WIN3_CBR_MST 0x00000414
+#define RK3328_WIN3_ACT_INFO 0x00000418
+#define RK3328_WIN3_DSP_INFO 0x0000041c
+#define RK3328_WIN3_DSP_ST 0x00000420
+#define RK3328_WIN3_SCL_FACTOR_YRGB 0x00000424
+#define RK3328_WIN3_SCL_FACTOR_CBR 0x00000428
+#define RK3328_WIN3_SCL_OFFSET 0x0000042c
+#define RK3328_WIN3_SRC_ALPHA_CTRL 0x00000430
+#define RK3328_WIN3_DST_ALPHA_CTRL 0x00000434
+#define RK3328_WIN3_FADING_CTRL 0x00000438
+#define RK3328_WIN3_CTRL2 0x0000043c
+#define RK3328_DBG_WIN3_REG0 0x000004f0
+#define RK3328_DBG_WIN3_REG1 0x000004f4
+#define RK3328_DBG_WIN3_REG2 0x000004f8
+#define RK3328_DBG_WIN3_RESERVED 0x000004fc
+
+#define RK3328_HWC_CTRL0 0x00000500
+#define RK3328_HWC_CTRL1 0x00000504
+#define RK3328_HWC_MST 0x00000508
+#define RK3328_HWC_DSP_ST 0x0000050c
+#define RK3328_HWC_SRC_ALPHA_CTRL 0x00000510
+#define RK3328_HWC_DST_ALPHA_CTRL 0x00000514
+#define RK3328_HWC_FADING_CTRL 0x00000518
+#define RK3328_HWC_RESERVED1 0x0000051c
+#define RK3328_POST_DSP_HACT_INFO 0x00000600
+#define RK3328_POST_DSP_VACT_INFO 0x00000604
+#define RK3328_POST_SCL_FACTOR_YRGB 0x00000608
+#define RK3328_POST_RESERVED 0x0000060c
+#define RK3328_POST_SCL_CTRL 0x00000610
+#define RK3328_POST_DSP_VACT_INFO_F1 0x00000614
+#define RK3328_DSP_HTOTAL_HS_END 0x00000618
+#define RK3328_DSP_HACT_ST_END 0x0000061c
+#define RK3328_DSP_VTOTAL_VS_END 0x00000620
+#define RK3328_DSP_VACT_ST_END 0x00000624
+#define RK3328_DSP_VS_ST_END_F1 0x00000628
+#define RK3328_DSP_VACT_ST_END_F1 0x0000062c
+#define RK3328_BCSH_COLOR_BAR 0x00000640
+#define RK3328_BCSH_BCS 0x00000644
+#define RK3328_BCSH_H 0x00000648
+#define RK3328_BCSH_CTRL 0x0000064c
+#define RK3328_FRC_LOWER01_0 0x00000678
+#define RK3328_FRC_LOWER01_1 0x0000067c
+#define RK3328_FRC_LOWER10_0 0x00000680
+#define RK3328_FRC_LOWER10_1 0x00000684
+#define RK3328_FRC_LOWER11_0 0x00000688
+#define RK3328_FRC_LOWER11_1 0x0000068c
+#define RK3328_DBG_POST_REG0 0x000006e8
+#define RK3328_DBG_POST_RESERVED 0x000006ec
+#define RK3328_DBG_DATAO 0x000006f0
+#define RK3328_DBG_DATAO_2 0x000006f4
+
+/* sdr to hdr */
+#define RK3328_SDR2HDR_CTRL 0x00000700
+#define RK3328_EOTF_OETF_Y0 0x00000704
+#define RK3328_RESERVED0001 0x00000708
+#define RK3328_RESERVED0002 0x0000070c
+#define RK3328_EOTF_OETF_Y1 0x00000710
+#define RK3328_EOTF_OETF_Y64 0x0000080c
+#define RK3328_OETF_DX_DXPOW1 0x00000810
+#define RK3328_OETF_DX_DXPOW64 0x0000090c
+#define RK3328_OETF_XN1 0x00000910
+#define RK3328_OETF_XN63 0x00000a08
+
+/* hdr to sdr */
+#define RK3328_HDR2SDR_CTRL 0x00000a10
+#define RK3328_HDR2SDR_SRC_RANGE 0x00000a14
+#define RK3328_HDR2SDR_NORMFACEETF 0x00000a18
+#define RK3328_RESERVED0003 0x00000a1c
+#define RK3328_HDR2SDR_DST_RANGE 0x00000a20
+#define RK3328_HDR2SDR_NORMFACCGAMMA 0x00000a24
+#define RK3328_EETF_OETF_Y0 0x00000a28
+#define RK3328_SAT_Y0 0x00000a2c
+#define RK3328_EETF_OETF_Y1 0x00000a30
+#define RK3328_SAT_Y1 0x00000ab0
+#define RK3328_SAT_Y8 0x00000acc
+
+#define RK3328_HWC_LUT_ADDR 0x00000c00
+
/* rk3036 register definition */
#define RK3036_SYS_CTRL 0x00
#define RK3036_DSP_CTRL0 0x04
@@ -166,197 +878,4 @@
#define RK3036_HWC_LUT_ADDR 0x800
/* rk3036 register definition end */
-/* rk3399 register definition */
-#define RK3399_REG_CFG_DONE 0x00000
-#define RK3399_VERSION_INFO 0x00004
-#define RK3399_SYS_CTRL 0x00008
-#define RK3399_SYS_CTRL1 0x0000c
-#define RK3399_DSP_CTRL0 0x00010
-#define RK3399_DSP_CTRL1 0x00014
-#define RK3399_DSP_BG 0x00018
-#define RK3399_MCU_CTRL 0x0001c
-#define RK3399_WB_CTRL0 0x00020
-#define RK3399_WB_CTRL1 0x00024
-#define RK3399_WB_YRGB_MST 0x00028
-#define RK3399_WB_CBR_MST 0x0002c
-#define RK3399_WIN0_CTRL0 0x00030
-#define RK3399_WIN0_CTRL1 0x00034
-#define RK3399_WIN0_COLOR_KEY 0x00038
-#define RK3399_WIN0_VIR 0x0003c
-#define RK3399_WIN0_YRGB_MST 0x00040
-#define RK3399_WIN0_CBR_MST 0x00044
-#define RK3399_WIN0_ACT_INFO 0x00048
-#define RK3399_WIN0_DSP_INFO 0x0004c
-#define RK3399_WIN0_DSP_ST 0x00050
-#define RK3399_WIN0_SCL_FACTOR_YRGB 0x00054
-#define RK3399_WIN0_SCL_FACTOR_CBR 0x00058
-#define RK3399_WIN0_SCL_OFFSET 0x0005c
-#define RK3399_WIN0_SRC_ALPHA_CTRL 0x00060
-#define RK3399_WIN0_DST_ALPHA_CTRL 0x00064
-#define RK3399_WIN0_FADING_CTRL 0x00068
-#define RK3399_WIN0_CTRL2 0x0006c
-#define RK3399_WIN1_CTRL0 0x00070
-#define RK3399_WIN1_CTRL1 0x00074
-#define RK3399_WIN1_COLOR_KEY 0x00078
-#define RK3399_WIN1_VIR 0x0007c
-#define RK3399_WIN1_YRGB_MST 0x00080
-#define RK3399_WIN1_CBR_MST 0x00084
-#define RK3399_WIN1_ACT_INFO 0x00088
-#define RK3399_WIN1_DSP_INFO 0x0008c
-#define RK3399_WIN1_DSP_ST 0x00090
-#define RK3399_WIN1_SCL_FACTOR_YRGB 0x00094
-#define RK3399_WIN1_SCL_FACTOR_CBR 0x00098
-#define RK3399_WIN1_SCL_OFFSET 0x0009c
-#define RK3399_WIN1_SRC_ALPHA_CTRL 0x000a0
-#define RK3399_WIN1_DST_ALPHA_CTRL 0x000a4
-#define RK3399_WIN1_FADING_CTRL 0x000a8
-#define RK3399_WIN1_CTRL2 0x000ac
-#define RK3399_WIN2_CTRL0 0x000b0
-#define RK3399_WIN2_CTRL1 0x000b4
-#define RK3399_WIN2_VIR0_1 0x000b8
-#define RK3399_WIN2_VIR2_3 0x000bc
-#define RK3399_WIN2_MST0 0x000c0
-#define RK3399_WIN2_DSP_INFO0 0x000c4
-#define RK3399_WIN2_DSP_ST0 0x000c8
-#define RK3399_WIN2_COLOR_KEY 0x000cc
-#define RK3399_WIN2_MST1 0x000d0
-#define RK3399_WIN2_DSP_INFO1 0x000d4
-#define RK3399_WIN2_DSP_ST1 0x000d8
-#define RK3399_WIN2_SRC_ALPHA_CTRL 0x000dc
-#define RK3399_WIN2_MST2 0x000e0
-#define RK3399_WIN2_DSP_INFO2 0x000e4
-#define RK3399_WIN2_DSP_ST2 0x000e8
-#define RK3399_WIN2_DST_ALPHA_CTRL 0x000ec
-#define RK3399_WIN2_MST3 0x000f0
-#define RK3399_WIN2_DSP_INFO3 0x000f4
-#define RK3399_WIN2_DSP_ST3 0x000f8
-#define RK3399_WIN2_FADING_CTRL 0x000fc
-#define RK3399_WIN3_CTRL0 0x00100
-#define RK3399_WIN3_CTRL1 0x00104
-#define RK3399_WIN3_VIR0_1 0x00108
-#define RK3399_WIN3_VIR2_3 0x0010c
-#define RK3399_WIN3_MST0 0x00110
-#define RK3399_WIN3_DSP_INFO0 0x00114
-#define RK3399_WIN3_DSP_ST0 0x00118
-#define RK3399_WIN3_COLOR_KEY 0x0011c
-#define RK3399_WIN3_MST1 0x00120
-#define RK3399_WIN3_DSP_INFO1 0x00124
-#define RK3399_WIN3_DSP_ST1 0x00128
-#define RK3399_WIN3_SRC_ALPHA_CTRL 0x0012c
-#define RK3399_WIN3_MST2 0x00130
-#define RK3399_WIN3_DSP_INFO2 0x00134
-#define RK3399_WIN3_DSP_ST2 0x00138
-#define RK3399_WIN3_DST_ALPHA_CTRL 0x0013c
-#define RK3399_WIN3_MST3 0x00140
-#define RK3399_WIN3_DSP_INFO3 0x00144
-#define RK3399_WIN3_DSP_ST3 0x00148
-#define RK3399_WIN3_FADING_CTRL 0x0014c
-#define RK3399_HWC_CTRL0 0x00150
-#define RK3399_HWC_CTRL1 0x00154
-#define RK3399_HWC_MST 0x00158
-#define RK3399_HWC_DSP_ST 0x0015c
-#define RK3399_HWC_SRC_ALPHA_CTRL 0x00160
-#define RK3399_HWC_DST_ALPHA_CTRL 0x00164
-#define RK3399_HWC_FADING_CTRL 0x00168
-#define RK3399_HWC_RESERVED1 0x0016c
-#define RK3399_POST_DSP_HACT_INFO 0x00170
-#define RK3399_POST_DSP_VACT_INFO 0x00174
-#define RK3399_POST_SCL_FACTOR_YRGB 0x00178
-#define RK3399_POST_RESERVED 0x0017c
-#define RK3399_POST_SCL_CTRL 0x00180
-#define RK3399_POST_DSP_VACT_INFO_F1 0x00184
-#define RK3399_DSP_HTOTAL_HS_END 0x00188
-#define RK3399_DSP_HACT_ST_END 0x0018c
-#define RK3399_DSP_VTOTAL_VS_END 0x00190
-#define RK3399_DSP_VACT_ST_END 0x00194
-#define RK3399_DSP_VS_ST_END_F1 0x00198
-#define RK3399_DSP_VACT_ST_END_F1 0x0019c
-#define RK3399_PWM_CTRL 0x001a0
-#define RK3399_PWM_PERIOD_HPR 0x001a4
-#define RK3399_PWM_DUTY_LPR 0x001a8
-#define RK3399_PWM_CNT 0x001ac
-#define RK3399_BCSH_COLOR_BAR 0x001b0
-#define RK3399_BCSH_BCS 0x001b4
-#define RK3399_BCSH_H 0x001b8
-#define RK3399_BCSH_CTRL 0x001bc
-#define RK3399_CABC_CTRL0 0x001c0
-#define RK3399_CABC_CTRL1 0x001c4
-#define RK3399_CABC_CTRL2 0x001c8
-#define RK3399_CABC_CTRL3 0x001cc
-#define RK3399_CABC_GAUSS_LINE0_0 0x001d0
-#define RK3399_CABC_GAUSS_LINE0_1 0x001d4
-#define RK3399_CABC_GAUSS_LINE1_0 0x001d8
-#define RK3399_CABC_GAUSS_LINE1_1 0x001dc
-#define RK3399_CABC_GAUSS_LINE2_0 0x001e0
-#define RK3399_CABC_GAUSS_LINE2_1 0x001e4
-#define RK3399_FRC_LOWER01_0 0x001e8
-#define RK3399_FRC_LOWER01_1 0x001ec
-#define RK3399_FRC_LOWER10_0 0x001f0
-#define RK3399_FRC_LOWER10_1 0x001f4
-#define RK3399_FRC_LOWER11_0 0x001f8
-#define RK3399_FRC_LOWER11_1 0x001fc
-#define RK3399_AFBCD0_CTRL 0x00200
-#define RK3399_AFBCD0_HDR_PTR 0x00204
-#define RK3399_AFBCD0_PIC_SIZE 0x00208
-#define RK3399_AFBCD0_STATUS 0x0020c
-#define RK3399_AFBCD1_CTRL 0x00220
-#define RK3399_AFBCD1_HDR_PTR 0x00224
-#define RK3399_AFBCD1_PIC_SIZE 0x00228
-#define RK3399_AFBCD1_STATUS 0x0022c
-#define RK3399_AFBCD2_CTRL 0x00240
-#define RK3399_AFBCD2_HDR_PTR 0x00244
-#define RK3399_AFBCD2_PIC_SIZE 0x00248
-#define RK3399_AFBCD2_STATUS 0x0024c
-#define RK3399_AFBCD3_CTRL 0x00260
-#define RK3399_AFBCD3_HDR_PTR 0x00264
-#define RK3399_AFBCD3_PIC_SIZE 0x00268
-#define RK3399_AFBCD3_STATUS 0x0026c
-#define RK3399_INTR_EN0 0x00280
-#define RK3399_INTR_CLEAR0 0x00284
-#define RK3399_INTR_STATUS0 0x00288
-#define RK3399_INTR_RAW_STATUS0 0x0028c
-#define RK3399_INTR_EN1 0x00290
-#define RK3399_INTR_CLEAR1 0x00294
-#define RK3399_INTR_STATUS1 0x00298
-#define RK3399_INTR_RAW_STATUS1 0x0029c
-#define RK3399_LINE_FLAG 0x002a0
-#define RK3399_VOP_STATUS 0x002a4
-#define RK3399_BLANKING_VALUE 0x002a8
-#define RK3399_MCU_BYPASS_PORT 0x002ac
-#define RK3399_WIN0_DSP_BG 0x002b0
-#define RK3399_WIN1_DSP_BG 0x002b4
-#define RK3399_WIN2_DSP_BG 0x002b8
-#define RK3399_WIN3_DSP_BG 0x002bc
-#define RK3399_YUV2YUV_WIN 0x002c0
-#define RK3399_YUV2YUV_POST 0x002c4
-#define RK3399_AUTO_GATING_EN 0x002cc
-#define RK3399_WIN0_CSC_COE 0x003a0
-#define RK3399_WIN1_CSC_COE 0x003c0
-#define RK3399_WIN2_CSC_COE 0x003e0
-#define RK3399_WIN3_CSC_COE 0x00400
-#define RK3399_HWC_CSC_COE 0x00420
-#define RK3399_BCSH_R2Y_CSC_COE 0x00440
-#define RK3399_BCSH_Y2R_CSC_COE 0x00460
-#define RK3399_POST_YUV2YUV_Y2R_COE 0x00480
-#define RK3399_POST_YUV2YUV_3X3_COE 0x004a0
-#define RK3399_POST_YUV2YUV_R2Y_COE 0x004c0
-#define RK3399_WIN0_YUV2YUV_Y2R 0x004e0
-#define RK3399_WIN0_YUV2YUV_3X3 0x00500
-#define RK3399_WIN0_YUV2YUV_R2Y 0x00520
-#define RK3399_WIN1_YUV2YUV_Y2R 0x00540
-#define RK3399_WIN1_YUV2YUV_3X3 0x00560
-#define RK3399_WIN1_YUV2YUV_R2Y 0x00580
-#define RK3399_WIN2_YUV2YUV_Y2R 0x005a0
-#define RK3399_WIN2_YUV2YUV_3X3 0x005c0
-#define RK3399_WIN2_YUV2YUV_R2Y 0x005e0
-#define RK3399_WIN3_YUV2YUV_Y2R 0x00600
-#define RK3399_WIN3_YUV2YUV_3X3 0x00620
-#define RK3399_WIN3_YUV2YUV_R2Y 0x00640
-#define RK3399_WIN2_LUT_ADDR 0x01000
-#define RK3399_WIN3_LUT_ADDR 0x01400
-#define RK3399_HWC_LUT_ADDR 0x01800
-#define RK3399_CABC_GAMMA_LUT_ADDR 0x01c00
-#define RK3399_GAMMA_LUT_ADDR 0x02000
-/* rk3399 register definition end */
-
#endif /* _ROCKCHIP_VOP_REG_H */
diff --git a/drivers/gpu/drm/savage/savage_drv.c b/drivers/gpu/drm/savage/savage_drv.c
index 78c6d8e..2bddeb8 100644
--- a/drivers/gpu/drm/savage/savage_drv.c
+++ b/drivers/gpu/drm/savage/savage_drv.c
@@ -55,7 +55,6 @@ static struct drm_driver driver = {
.preclose = savage_reclaim_buffers,
.lastclose = savage_driver_lastclose,
.unload = savage_driver_unload,
- .set_busid = drm_pci_set_busid,
.ioctls = savage_ioctls,
.dma_ioctl = savage_bci_buffers,
.fops = &savage_driver_fops,
@@ -75,12 +74,12 @@ static struct pci_driver savage_pci_driver = {
static int __init savage_init(void)
{
driver.num_ioctls = savage_max_ioctl;
- return drm_pci_init(&driver, &savage_pci_driver);
+ return drm_legacy_pci_init(&driver, &savage_pci_driver);
}
static void __exit savage_exit(void)
{
- drm_pci_exit(&driver, &savage_pci_driver);
+ drm_legacy_pci_exit(&driver, &savage_pci_driver);
}
module_init(savage_init);
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
index 800d1d2..5925725 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
@@ -145,8 +145,6 @@ static struct drm_driver shmob_drm_driver = {
.gem_prime_vunmap = drm_gem_cma_prime_vunmap,
.gem_prime_mmap = drm_gem_cma_prime_mmap,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.fops = &shmob_drm_fops,
.name = "shmob-drm",
.desc = "Renesas SH Mobile DRM",
@@ -277,7 +275,7 @@ static int shmob_drm_probe(struct platform_device *pdev)
ret = drm_irq_install(ddev, platform_get_irq(pdev, 0));
if (ret < 0) {
dev_err(&pdev->dev, "failed to install IRQ handler\n");
- goto err_vblank_cleanup;
+ goto err_modeset_cleanup;
}
/*
@@ -292,8 +290,6 @@ static int shmob_drm_probe(struct platform_device *pdev)
err_irq_uninstall:
drm_irq_uninstall(ddev);
-err_vblank_cleanup:
- drm_vblank_cleanup(ddev);
err_modeset_cleanup:
drm_kms_helper_poll_fini(ddev);
drm_mode_config_cleanup(ddev);
diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c
index 7f05da1..e04a926 100644
--- a/drivers/gpu/drm/sis/sis_drv.c
+++ b/drivers/gpu/drm/sis/sis_drv.c
@@ -104,7 +104,6 @@ static struct drm_driver driver = {
.open = sis_driver_open,
.preclose = sis_reclaim_buffers_locked,
.postclose = sis_driver_postclose,
- .set_busid = drm_pci_set_busid,
.dma_quiescent = sis_idle,
.lastclose = sis_lastclose,
.ioctls = sis_ioctls,
@@ -125,12 +124,12 @@ static struct pci_driver sis_pci_driver = {
static int __init sis_init(void)
{
driver.num_ioctls = sis_max_ioctl;
- return drm_pci_init(&driver, &sis_pci_driver);
+ return drm_legacy_pci_init(&driver, &sis_pci_driver);
}
static void __exit sis_exit(void)
{
- drm_pci_exit(&driver, &sis_pci_driver);
+ drm_legacy_pci_exit(&driver, &sis_pci_driver);
}
module_init(sis_init);
diff --git a/drivers/gpu/drm/sti/sti_crtc.c b/drivers/gpu/drm/sti/sti_crtc.c
index d45a433..e8a4d48 100644
--- a/drivers/gpu/drm/sti/sti_crtc.c
+++ b/drivers/gpu/drm/sti/sti_crtc.c
@@ -20,7 +20,8 @@
#include "sti_vid.h"
#include "sti_vtg.h"
-static void sti_crtc_enable(struct drm_crtc *crtc)
+static void sti_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct sti_mixer *mixer = to_sti_mixer(crtc);
@@ -31,7 +32,8 @@ static void sti_crtc_enable(struct drm_crtc *crtc)
drm_crtc_vblank_on(crtc);
}
-static void sti_crtc_disabling(struct drm_crtc *crtc)
+static void sti_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct sti_mixer *mixer = to_sti_mixer(crtc);
@@ -222,10 +224,10 @@ static void sti_crtc_atomic_flush(struct drm_crtc *crtc,
}
static const struct drm_crtc_helper_funcs sti_crtc_helper_funcs = {
- .enable = sti_crtc_enable,
- .disable = sti_crtc_disabling,
.mode_set_nofb = sti_crtc_mode_set_nofb,
.atomic_flush = sti_crtc_atomic_flush,
+ .atomic_enable = sti_crtc_atomic_enable,
+ .atomic_disable = sti_crtc_atomic_disable,
};
static void sti_crtc_destroy(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/sti/sti_cursor.c b/drivers/gpu/drm/sti/sti_cursor.c
index 5b3a41f..b709ebb 100644
--- a/drivers/gpu/drm/sti/sti_cursor.c
+++ b/drivers/gpu/drm/sti/sti_cursor.c
@@ -348,7 +348,6 @@ static const struct drm_plane_funcs sti_cursor_plane_helpers_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = sti_cursor_destroy,
- .set_property = drm_atomic_helper_plane_set_property,
.reset = sti_plane_reset,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
@@ -392,7 +391,7 @@ struct drm_plane *sti_cursor_create(struct drm_device *drm_dev,
&sti_cursor_plane_helpers_funcs,
cursor_supported_formats,
ARRAY_SIZE(cursor_supported_formats),
- DRM_PLANE_TYPE_CURSOR, NULL);
+ NULL, DRM_PLANE_TYPE_CURSOR, NULL);
if (res) {
DRM_ERROR("Failed to initialize universal plane\n");
goto err_plane;
diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c
index a4b57428..1700c54 100644
--- a/drivers/gpu/drm/sti/sti_drv.c
+++ b/drivers/gpu/drm/sti/sti_drv.c
@@ -175,8 +175,6 @@ static struct drm_driver sti_driver = {
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.fops = &sti_driver_fops,
.enable_vblank = sti_crtc_enable_vblank,
@@ -237,7 +235,6 @@ static void sti_cleanup(struct drm_device *ddev)
}
drm_kms_helper_poll_fini(ddev);
- drm_vblank_cleanup(ddev);
component_unbind_all(ddev->dev, ddev);
kfree(private);
ddev->dev_private = NULL;
diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c
index 24ebc6b..852bf22 100644
--- a/drivers/gpu/drm/sti/sti_dvo.c
+++ b/drivers/gpu/drm/sti/sti_dvo.c
@@ -412,7 +412,6 @@ static int sti_dvo_late_register(struct drm_connector *connector)
}
static const struct drm_connector_funcs sti_dvo_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = sti_dvo_connector_detect,
.destroy = drm_connector_cleanup,
@@ -582,7 +581,7 @@ static int sti_dvo_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id dvo_of_match[] = {
+static const struct of_device_id dvo_of_match[] = {
{ .compatible = "st,stih407-dvo", },
{ /* end node */ }
};
diff --git a/drivers/gpu/drm/sti/sti_gdp.c b/drivers/gpu/drm/sti/sti_gdp.c
index 5ee0503..b65eea4 100644
--- a/drivers/gpu/drm/sti/sti_gdp.c
+++ b/drivers/gpu/drm/sti/sti_gdp.c
@@ -895,7 +895,6 @@ static const struct drm_plane_funcs sti_gdp_plane_helpers_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = sti_gdp_destroy,
- .set_property = drm_atomic_helper_plane_set_property,
.reset = sti_plane_reset,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
@@ -931,7 +930,7 @@ struct drm_plane *sti_gdp_create(struct drm_device *drm_dev,
&sti_gdp_plane_helpers_funcs,
gdp_supported_formats,
ARRAY_SIZE(gdp_supported_formats),
- type, NULL);
+ NULL, type, NULL);
if (res) {
DRM_ERROR("Failed to initialize universal plane\n");
goto err;
diff --git a/drivers/gpu/drm/sti/sti_hda.c b/drivers/gpu/drm/sti/sti_hda.c
index d6ed909..cf65e32 100644
--- a/drivers/gpu/drm/sti/sti_hda.c
+++ b/drivers/gpu/drm/sti/sti_hda.c
@@ -647,7 +647,6 @@ static int sti_hda_late_register(struct drm_connector *connector)
}
static const struct drm_connector_funcs sti_hda_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
.reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
index a59c95a..30f02d2 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.c
+++ b/drivers/gpu/drm/sti/sti_hdmi.c
@@ -434,7 +434,7 @@ static int hdmi_avi_infoframe_config(struct sti_hdmi *hdmi)
DRM_DEBUG_DRIVER("\n");
- ret = drm_hdmi_avi_infoframe_from_display_mode(&infoframe, mode);
+ ret = drm_hdmi_avi_infoframe_from_display_mode(&infoframe, mode, false);
if (ret < 0) {
DRM_ERROR("failed to setup AVI infoframe: %d\n", ret);
return ret;
@@ -1113,12 +1113,10 @@ static int sti_hdmi_late_register(struct drm_connector *connector)
}
static const struct drm_connector_funcs sti_hdmi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = sti_hdmi_connector_detect,
.destroy = drm_connector_cleanup,
.reset = drm_atomic_helper_connector_reset,
- .set_property = drm_atomic_helper_connector_set_property,
.atomic_set_property = sti_hdmi_connector_set_property,
.atomic_get_property = sti_hdmi_connector_get_property,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
diff --git a/drivers/gpu/drm/sti/sti_hqvdp.c b/drivers/gpu/drm/sti/sti_hqvdp.c
index a1c161f..b19b343 100644
--- a/drivers/gpu/drm/sti/sti_hqvdp.c
+++ b/drivers/gpu/drm/sti/sti_hqvdp.c
@@ -958,6 +958,7 @@ static void sti_hqvdp_start_xp70(struct sti_hqvdp *hqvdp)
}
if (i == POLL_MAX_ATTEMPT) {
DRM_ERROR("Could not reset\n");
+ clk_disable_unprepare(hqvdp->clk);
goto out;
}
@@ -994,6 +995,7 @@ static void sti_hqvdp_start_xp70(struct sti_hqvdp *hqvdp)
}
if (i == POLL_MAX_ATTEMPT) {
DRM_ERROR("Could not boot\n");
+ clk_disable_unprepare(hqvdp->clk);
goto out;
}
@@ -1081,6 +1083,7 @@ static int sti_hqvdp_atomic_check(struct drm_plane *drm_plane,
&hqvdp->vtg_nb,
crtc)) {
DRM_ERROR("Cannot register VTG notifier\n");
+ clk_disable_unprepare(hqvdp->clk_pix_main);
return -EINVAL;
}
hqvdp->vtg_registered = true;
@@ -1273,7 +1276,6 @@ static const struct drm_plane_funcs sti_hqvdp_plane_helpers_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = sti_hqvdp_destroy,
- .set_property = drm_atomic_helper_plane_set_property,
.reset = sti_plane_reset,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
@@ -1295,7 +1297,7 @@ static struct drm_plane *sti_hqvdp_create(struct drm_device *drm_dev,
&sti_hqvdp_plane_helpers_funcs,
hqvdp_supported_formats,
ARRAY_SIZE(hqvdp_supported_formats),
- DRM_PLANE_TYPE_OVERLAY, NULL);
+ NULL, DRM_PLANE_TYPE_OVERLAY, NULL);
if (res) {
DRM_ERROR("Failed to initialize universal plane\n");
return NULL;
@@ -1395,7 +1397,7 @@ static int sti_hqvdp_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id hqvdp_of_match[] = {
+static const struct of_device_id hqvdp_of_match[] = {
{ .compatible = "st,stih407-hqvdp", },
{ /* end node */ }
};
diff --git a/drivers/gpu/drm/stm/Kconfig b/drivers/gpu/drm/stm/Kconfig
index 8fe5b18..35367ad 100644
--- a/drivers/gpu/drm/stm/Kconfig
+++ b/drivers/gpu/drm/stm/Kconfig
@@ -4,7 +4,7 @@ config DRM_STM
select DRM_KMS_HELPER
select DRM_GEM_CMA_HELPER
select DRM_KMS_CMA_HELPER
- select DRM_PANEL
+ select DRM_PANEL_BRIDGE
select VIDEOMODE_HELPERS
select FB_PROVIDE_GET_FB_UNMAPPED_AREA
@@ -13,3 +13,10 @@ config DRM_STM
STMicroelectronics STM32 MCUs.
To compile this driver as a module, choose M here: the module
will be called stm-drm.
+
+config DRM_STM_DSI
+ tristate "STMicroelectronics specific extensions for Synopsys MIPI DSI"
+ depends on DRM_STM
+ select DRM_DW_MIPI_DSI
+ help
+ Choose this option for MIPI DSI support on STMicroelectronics SoC.
diff --git a/drivers/gpu/drm/stm/Makefile b/drivers/gpu/drm/stm/Makefile
index a09ecf4..d883adc 100644
--- a/drivers/gpu/drm/stm/Makefile
+++ b/drivers/gpu/drm/stm/Makefile
@@ -2,4 +2,6 @@ stm-drm-y := \
drv.o \
ltdc.o
+obj-$(CONFIG_DRM_STM_DSI) += dw_mipi_dsi-stm.o
+
obj-$(CONFIG_DRM_STM) += stm-drm.o
diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c
index 83ab48f..b333b37 100644
--- a/drivers/gpu/drm/stm/drv.c
+++ b/drivers/gpu/drm/stm/drv.c
@@ -20,13 +20,6 @@
#include "ltdc.h"
-#define DRIVER_NAME "stm"
-#define DRIVER_DESC "STMicroelectronics SoC DRM"
-#define DRIVER_DATE "20170330"
-#define DRIVER_MAJOR 1
-#define DRIVER_MINOR 0
-#define DRIVER_PATCH_LEVEL 0
-
#define STM_MAX_FB_WIDTH 2048
#define STM_MAX_FB_HEIGHT 2048 /* same as width to handle orientation */
@@ -59,16 +52,14 @@ static struct drm_driver drv_driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
DRIVER_ATOMIC,
.lastclose = drv_lastclose,
- .name = DRIVER_NAME,
- .desc = DRIVER_DESC,
- .date = DRIVER_DATE,
- .major = DRIVER_MAJOR,
- .minor = DRIVER_MINOR,
- .patchlevel = DRIVER_PATCH_LEVEL,
+ .name = "stm",
+ .desc = "STMicroelectronics SoC DRM",
+ .date = "20170330",
+ .major = 1,
+ .minor = 0,
+ .patchlevel = 0,
.fops = &drv_driver_fops,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_free_object_unlocked = drm_gem_cma_free_object,
@@ -206,7 +197,7 @@ static struct platform_driver stm_drm_platform_driver = {
.probe = stm_drm_platform_probe,
.remove = stm_drm_platform_remove,
.driver = {
- .name = DRIVER_NAME,
+ .name = "stm32-display",
.of_match_table = drv_dt_ids,
},
};
diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
new file mode 100644
index 0000000..568c5d0
--- /dev/null
+++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2017
+ *
+ * Authors: Philippe Cornu <philippe.cornu@st.com>
+ * Yannick Fertre <yannick.fertre@st.com>
+ *
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/clk.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <drm/drmP.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/bridge/dw_mipi_dsi.h>
+#include <video/mipi_display.h>
+
+/* DSI wrapper register & bit definitions */
+/* Note: registers are named as in the Reference Manual */
+#define DSI_WCFGR 0x0400 /* Wrapper ConFiGuration Reg */
+#define WCFGR_DSIM BIT(0) /* DSI Mode */
+#define WCFGR_COLMUX GENMASK(3, 1) /* COLor MUltipleXing */
+
+#define DSI_WCR 0x0404 /* Wrapper Control Reg */
+#define WCR_DSIEN BIT(3) /* DSI ENable */
+
+#define DSI_WISR 0x040C /* Wrapper Interrupt and Status Reg */
+#define WISR_PLLLS BIT(8) /* PLL Lock Status */
+#define WISR_RRS BIT(12) /* Regulator Ready Status */
+
+#define DSI_WPCR0 0x0418 /* Wrapper Phy Conf Reg 0 */
+#define WPCR0_UIX4 GENMASK(5, 0) /* Unit Interval X 4 */
+#define WPCR0_TDDL BIT(16) /* Turn Disable Data Lanes */
+
+#define DSI_WRPCR 0x0430 /* Wrapper Regulator & Pll Ctrl Reg */
+#define WRPCR_PLLEN BIT(0) /* PLL ENable */
+#define WRPCR_NDIV GENMASK(8, 2) /* pll loop DIVision Factor */
+#define WRPCR_IDF GENMASK(14, 11) /* pll Input Division Factor */
+#define WRPCR_ODF GENMASK(17, 16) /* pll Output Division Factor */
+#define WRPCR_REGEN BIT(24) /* REGulator ENable */
+#define WRPCR_BGREN BIT(28) /* BandGap Reference ENable */
+#define IDF_MIN 1
+#define IDF_MAX 7
+#define NDIV_MIN 10
+#define NDIV_MAX 125
+#define ODF_MIN 1
+#define ODF_MAX 8
+
+/* dsi color format coding according to the datasheet */
+enum dsi_color {
+ DSI_RGB565_CONF1,
+ DSI_RGB565_CONF2,
+ DSI_RGB565_CONF3,
+ DSI_RGB666_CONF1,
+ DSI_RGB666_CONF2,
+ DSI_RGB888,
+};
+
+#define LANE_MIN_KBPS 31250
+#define LANE_MAX_KBPS 500000
+
+/* Sleep & timeout for regulator on/off, pll lock/unlock & fifo empty */
+#define SLEEP_US 1000
+#define TIMEOUT_US 200000
+
+struct dw_mipi_dsi_stm {
+ void __iomem *base;
+ struct clk *pllref_clk;
+};
+
+static inline void dsi_write(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 val)
+{
+ writel(val, dsi->base + reg);
+}
+
+static inline u32 dsi_read(struct dw_mipi_dsi_stm *dsi, u32 reg)
+{
+ return readl(dsi->base + reg);
+}
+
+static inline void dsi_set(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 mask)
+{
+ dsi_write(dsi, reg, dsi_read(dsi, reg) | mask);
+}
+
+static inline void dsi_clear(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 mask)
+{
+ dsi_write(dsi, reg, dsi_read(dsi, reg) & ~mask);
+}
+
+static inline void dsi_update_bits(struct dw_mipi_dsi_stm *dsi, u32 reg,
+ u32 mask, u32 val)
+{
+ dsi_write(dsi, reg, (dsi_read(dsi, reg) & ~mask) | val);
+}
+
+static enum dsi_color dsi_color_from_mipi(enum mipi_dsi_pixel_format fmt)
+{
+ switch (fmt) {
+ case MIPI_DSI_FMT_RGB888:
+ return DSI_RGB888;
+ case MIPI_DSI_FMT_RGB666:
+ return DSI_RGB666_CONF2;
+ case MIPI_DSI_FMT_RGB666_PACKED:
+ return DSI_RGB666_CONF1;
+ case MIPI_DSI_FMT_RGB565:
+ return DSI_RGB565_CONF1;
+ default:
+ DRM_DEBUG_DRIVER("MIPI color invalid, so we use rgb888\n");
+ }
+ return DSI_RGB888;
+}
+
+static int dsi_pll_get_clkout_khz(int clkin_khz, int idf, int ndiv, int odf)
+{
+ /* prevent from division by 0 */
+ if (idf * odf)
+ return DIV_ROUND_CLOSEST(clkin_khz * ndiv, idf * odf);
+
+ return 0;
+}
+
+static int dsi_pll_get_params(int clkin_khz, int clkout_khz,
+ int *idf, int *ndiv, int *odf)
+{
+ int i, o, n, n_min, n_max;
+ int fvco_min, fvco_max, delta, best_delta; /* all in khz */
+
+ /* Early checks preventing division by 0 & odd results */
+ if ((clkin_khz <= 0) || (clkout_khz <= 0))
+ return -EINVAL;
+
+ fvco_min = LANE_MIN_KBPS * 2 * ODF_MAX;
+ fvco_max = LANE_MAX_KBPS * 2 * ODF_MIN;
+
+ best_delta = 1000000; /* big started value (1000000khz) */
+
+ for (i = IDF_MIN; i <= IDF_MAX; i++) {
+ /* Compute ndiv range according to Fvco */
+ n_min = ((fvco_min * i) / (2 * clkin_khz)) + 1;
+ n_max = (fvco_max * i) / (2 * clkin_khz);
+
+ /* No need to continue idf loop if we reach ndiv max */
+ if (n_min >= NDIV_MAX)
+ break;
+
+ /* Clamp ndiv to valid values */
+ if (n_min < NDIV_MIN)
+ n_min = NDIV_MIN;
+ if (n_max > NDIV_MAX)
+ n_max = NDIV_MAX;
+
+ for (o = ODF_MIN; o <= ODF_MAX; o *= 2) {
+ n = DIV_ROUND_CLOSEST(i * o * clkout_khz, clkin_khz);
+ /* Check ndiv according to vco range */
+ if ((n < n_min) || (n > n_max))
+ continue;
+ /* Check if new delta is better & saves parameters */
+ delta = dsi_pll_get_clkout_khz(clkin_khz, i, n, o) -
+ clkout_khz;
+ if (delta < 0)
+ delta = -delta;
+ if (delta < best_delta) {
+ *idf = i;
+ *ndiv = n;
+ *odf = o;
+ best_delta = delta;
+ }
+ /* fast return in case of "perfect result" */
+ if (!delta)
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+static int dw_mipi_dsi_phy_init(void *priv_data)
+{
+ struct dw_mipi_dsi_stm *dsi = priv_data;
+ u32 val;
+ int ret;
+
+ /* Enable the regulator */
+ dsi_set(dsi, DSI_WRPCR, WRPCR_REGEN | WRPCR_BGREN);
+ ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_RRS,
+ SLEEP_US, TIMEOUT_US);
+ if (ret)
+ DRM_DEBUG_DRIVER("!TIMEOUT! waiting REGU, let's continue\n");
+
+ /* Enable the DSI PLL & wait for its lock */
+ dsi_set(dsi, DSI_WRPCR, WRPCR_PLLEN);
+ ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_PLLLS,
+ SLEEP_US, TIMEOUT_US);
+ if (ret)
+ DRM_DEBUG_DRIVER("!TIMEOUT! waiting PLL, let's continue\n");
+
+ /* Enable the DSI wrapper */
+ dsi_set(dsi, DSI_WCR, WCR_DSIEN);
+
+ return 0;
+}
+
+static int
+dw_mipi_dsi_get_lane_mbps(void *priv_data, struct drm_display_mode *mode,
+ unsigned long mode_flags, u32 lanes, u32 format,
+ unsigned int *lane_mbps)
+{
+ struct dw_mipi_dsi_stm *dsi = priv_data;
+ unsigned int idf, ndiv, odf, pll_in_khz, pll_out_khz;
+ int ret, bpp;
+ u32 val;
+
+ pll_in_khz = (unsigned int)(clk_get_rate(dsi->pllref_clk) / 1000);
+
+ /* Compute requested pll out */
+ bpp = mipi_dsi_pixel_format_to_bpp(format);
+ pll_out_khz = mode->clock * bpp / lanes;
+ /* Add 20% to pll out to be higher than pixel bw (burst mode only) */
+ pll_out_khz = (pll_out_khz * 12) / 10;
+ if (pll_out_khz > LANE_MAX_KBPS) {
+ pll_out_khz = LANE_MAX_KBPS;
+ DRM_WARN("Warning max phy mbps is used\n");
+ }
+ if (pll_out_khz < LANE_MIN_KBPS) {
+ pll_out_khz = LANE_MIN_KBPS;
+ DRM_WARN("Warning min phy mbps is used\n");
+ }
+
+ /* Compute best pll parameters */
+ idf = 0;
+ ndiv = 0;
+ odf = 0;
+ ret = dsi_pll_get_params(pll_in_khz, pll_out_khz, &idf, &ndiv, &odf);
+ if (ret)
+ DRM_WARN("Warning dsi_pll_get_params(): bad params\n");
+
+ /* Get the adjusted pll out value */
+ pll_out_khz = dsi_pll_get_clkout_khz(pll_in_khz, idf, ndiv, odf);
+
+ /* Set the PLL division factors */
+ dsi_update_bits(dsi, DSI_WRPCR, WRPCR_NDIV | WRPCR_IDF | WRPCR_ODF,
+ (ndiv << 2) | (idf << 11) | ((ffs(odf) - 1) << 16));
+
+ /* Compute uix4 & set the bit period in high-speed mode */
+ val = 4000000 / pll_out_khz;
+ dsi_update_bits(dsi, DSI_WPCR0, WPCR0_UIX4, val);
+
+ /* Select video mode by resetting DSIM bit */
+ dsi_clear(dsi, DSI_WCFGR, WCFGR_DSIM);
+
+ /* Select the color coding */
+ dsi_update_bits(dsi, DSI_WCFGR, WCFGR_COLMUX,
+ dsi_color_from_mipi(format) << 1);
+
+ *lane_mbps = pll_out_khz / 1000;
+
+ DRM_DEBUG_DRIVER("pll_in %ukHz pll_out %ukHz lane_mbps %uMHz\n",
+ pll_in_khz, pll_out_khz, *lane_mbps);
+
+ return 0;
+}
+
+static const struct dw_mipi_dsi_phy_ops dw_mipi_dsi_stm_phy_ops = {
+ .init = dw_mipi_dsi_phy_init,
+ .get_lane_mbps = dw_mipi_dsi_get_lane_mbps,
+};
+
+static struct dw_mipi_dsi_plat_data dw_mipi_dsi_stm_plat_data = {
+ .max_data_lanes = 2,
+ .phy_ops = &dw_mipi_dsi_stm_phy_ops,
+};
+
+static const struct of_device_id dw_mipi_dsi_stm_dt_ids[] = {
+ { .compatible = "st,stm32-dsi", .data = &dw_mipi_dsi_stm_plat_data, },
+ { },
+};
+MODULE_DEVICE_TABLE(of, dw_mipi_dsi_stm_dt_ids);
+
+static int dw_mipi_dsi_stm_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct dw_mipi_dsi_stm *dsi;
+ struct resource *res;
+ int ret;
+
+ dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
+ if (!dsi)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ DRM_ERROR("Unable to get resource\n");
+ return -ENODEV;
+ }
+
+ dsi->base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(dsi->base)) {
+ DRM_ERROR("Unable to get dsi registers\n");
+ return PTR_ERR(dsi->base);
+ }
+
+ dsi->pllref_clk = devm_clk_get(dev, "ref");
+ if (IS_ERR(dsi->pllref_clk)) {
+ ret = PTR_ERR(dsi->pllref_clk);
+ dev_err(dev, "Unable to get pll reference clock: %d\n", ret);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(dsi->pllref_clk);
+ if (ret) {
+ dev_err(dev, "%s: Failed to enable pllref_clk\n", __func__);
+ return ret;
+ }
+
+ dw_mipi_dsi_stm_plat_data.base = dsi->base;
+ dw_mipi_dsi_stm_plat_data.priv_data = dsi;
+
+ ret = dw_mipi_dsi_probe(pdev, &dw_mipi_dsi_stm_plat_data);
+ if (ret) {
+ DRM_ERROR("Failed to initialize mipi dsi host\n");
+ clk_disable_unprepare(dsi->pllref_clk);
+ }
+
+ return ret;
+}
+
+static int dw_mipi_dsi_stm_remove(struct platform_device *pdev)
+{
+ struct dw_mipi_dsi_stm *dsi = dw_mipi_dsi_stm_plat_data.priv_data;
+
+ clk_disable_unprepare(dsi->pllref_clk);
+ dw_mipi_dsi_remove(pdev);
+
+ return 0;
+}
+
+static struct platform_driver dw_mipi_dsi_stm_driver = {
+ .probe = dw_mipi_dsi_stm_probe,
+ .remove = dw_mipi_dsi_stm_remove,
+ .driver = {
+ .of_match_table = dw_mipi_dsi_stm_dt_ids,
+ .name = "dw_mipi_dsi-stm",
+ },
+};
+
+module_platform_driver(dw_mipi_dsi_stm_driver);
+
+MODULE_AUTHOR("Philippe Cornu <philippe.cornu@st.com>");
+MODULE_AUTHOR("Yannick Fertre <yannick.fertre@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics DW MIPI DSI host controller driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 1b9483d..d394a03 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -21,7 +21,7 @@
#include <drm/drm_fb_cma_helper.h>
#include <drm/drm_gem_cma_helper.h>
#include <drm/drm_of.h>
-#include <drm/drm_panel.h>
+#include <drm/drm_bridge.h>
#include <drm/drm_plane_helper.h>
#include <video/videomode.h>
@@ -42,52 +42,52 @@
* an extra offset specified with reg_ofs.
*/
#define REG_OFS_NONE 0
-#define REG_OFS_4 4 /* Insertion of "Layer Configuration 2" reg */
+#define REG_OFS_4 4 /* Insertion of "Layer Conf. 2" reg */
#define REG_OFS (ldev->caps.reg_ofs)
-#define LAY_OFS 0x80 /* Register Offset between 2 layers */
+#define LAY_OFS 0x80 /* Register Offset between 2 layers */
/* Global register offsets */
-#define LTDC_IDR 0x0000 /* IDentification */
-#define LTDC_LCR 0x0004 /* Layer Count */
-#define LTDC_SSCR 0x0008 /* Synchronization Size Configuration */
-#define LTDC_BPCR 0x000C /* Back Porch Configuration */
-#define LTDC_AWCR 0x0010 /* Active Width Configuration */
-#define LTDC_TWCR 0x0014 /* Total Width Configuration */
-#define LTDC_GCR 0x0018 /* Global Control */
-#define LTDC_GC1R 0x001C /* Global Configuration 1 */
-#define LTDC_GC2R 0x0020 /* Global Configuration 2 */
-#define LTDC_SRCR 0x0024 /* Shadow Reload Configuration */
-#define LTDC_GACR 0x0028 /* GAmma Correction */
-#define LTDC_BCCR 0x002C /* Background Color Configuration */
-#define LTDC_IER 0x0034 /* Interrupt Enable */
-#define LTDC_ISR 0x0038 /* Interrupt Status */
-#define LTDC_ICR 0x003C /* Interrupt Clear */
-#define LTDC_LIPCR 0x0040 /* Line Interrupt Position Configuration */
-#define LTDC_CPSR 0x0044 /* Current Position Status */
-#define LTDC_CDSR 0x0048 /* Current Display Status */
+#define LTDC_IDR 0x0000 /* IDentification */
+#define LTDC_LCR 0x0004 /* Layer Count */
+#define LTDC_SSCR 0x0008 /* Synchronization Size Configuration */
+#define LTDC_BPCR 0x000C /* Back Porch Configuration */
+#define LTDC_AWCR 0x0010 /* Active Width Configuration */
+#define LTDC_TWCR 0x0014 /* Total Width Configuration */
+#define LTDC_GCR 0x0018 /* Global Control */
+#define LTDC_GC1R 0x001C /* Global Configuration 1 */
+#define LTDC_GC2R 0x0020 /* Global Configuration 2 */
+#define LTDC_SRCR 0x0024 /* Shadow Reload Configuration */
+#define LTDC_GACR 0x0028 /* GAmma Correction */
+#define LTDC_BCCR 0x002C /* Background Color Configuration */
+#define LTDC_IER 0x0034 /* Interrupt Enable */
+#define LTDC_ISR 0x0038 /* Interrupt Status */
+#define LTDC_ICR 0x003C /* Interrupt Clear */
+#define LTDC_LIPCR 0x0040 /* Line Interrupt Position Conf. */
+#define LTDC_CPSR 0x0044 /* Current Position Status */
+#define LTDC_CDSR 0x0048 /* Current Display Status */
/* Layer register offsets */
-#define LTDC_L1LC1R (0x0080) /* L1 Layer Configuration 1 */
-#define LTDC_L1LC2R (0x0084) /* L1 Layer Configuration 2 */
-#define LTDC_L1CR (0x0084 + REG_OFS) /* L1 Control */
-#define LTDC_L1WHPCR (0x0088 + REG_OFS) /* L1 Window Hor Position Config */
-#define LTDC_L1WVPCR (0x008C + REG_OFS) /* L1 Window Vert Position Config */
-#define LTDC_L1CKCR (0x0090 + REG_OFS) /* L1 Color Keying Configuration */
-#define LTDC_L1PFCR (0x0094 + REG_OFS) /* L1 Pixel Format Configuration */
-#define LTDC_L1CACR (0x0098 + REG_OFS) /* L1 Constant Alpha Config */
-#define LTDC_L1DCCR (0x009C + REG_OFS) /* L1 Default Color Configuration */
-#define LTDC_L1BFCR (0x00A0 + REG_OFS) /* L1 Blend Factors Configuration */
-#define LTDC_L1FBBCR (0x00A4 + REG_OFS) /* L1 FrameBuffer Bus Control */
-#define LTDC_L1AFBCR (0x00A8 + REG_OFS) /* L1 AuxFB Control */
-#define LTDC_L1CFBAR (0x00AC + REG_OFS) /* L1 Color FrameBuffer Address */
-#define LTDC_L1CFBLR (0x00B0 + REG_OFS) /* L1 Color FrameBuffer Length */
-#define LTDC_L1CFBLNR (0x00B4 + REG_OFS) /* L1 Color FrameBuffer Line Nb */
-#define LTDC_L1AFBAR (0x00B8 + REG_OFS) /* L1 AuxFB Address */
-#define LTDC_L1AFBLR (0x00BC + REG_OFS) /* L1 AuxFB Length */
-#define LTDC_L1AFBLNR (0x00C0 + REG_OFS) /* L1 AuxFB Line Number */
-#define LTDC_L1CLUTWR (0x00C4 + REG_OFS) /* L1 CLUT Write */
-#define LTDC_L1YS1R (0x00E0 + REG_OFS) /* L1 YCbCr Scale 1 */
-#define LTDC_L1YS2R (0x00E4 + REG_OFS) /* L1 YCbCr Scale 2 */
+#define LTDC_L1LC1R (0x80) /* L1 Layer Configuration 1 */
+#define LTDC_L1LC2R (0x84) /* L1 Layer Configuration 2 */
+#define LTDC_L1CR (0x84 + REG_OFS)/* L1 Control */
+#define LTDC_L1WHPCR (0x88 + REG_OFS)/* L1 Window Hor Position Config */
+#define LTDC_L1WVPCR (0x8C + REG_OFS)/* L1 Window Vert Position Config */
+#define LTDC_L1CKCR (0x90 + REG_OFS)/* L1 Color Keying Configuration */
+#define LTDC_L1PFCR (0x94 + REG_OFS)/* L1 Pixel Format Configuration */
+#define LTDC_L1CACR (0x98 + REG_OFS)/* L1 Constant Alpha Config */
+#define LTDC_L1DCCR (0x9C + REG_OFS)/* L1 Default Color Configuration */
+#define LTDC_L1BFCR (0xA0 + REG_OFS)/* L1 Blend Factors Configuration */
+#define LTDC_L1FBBCR (0xA4 + REG_OFS)/* L1 FrameBuffer Bus Control */
+#define LTDC_L1AFBCR (0xA8 + REG_OFS)/* L1 AuxFB Control */
+#define LTDC_L1CFBAR (0xAC + REG_OFS)/* L1 Color FrameBuffer Address */
+#define LTDC_L1CFBLR (0xB0 + REG_OFS)/* L1 Color FrameBuffer Length */
+#define LTDC_L1CFBLNR (0xB4 + REG_OFS)/* L1 Color FrameBuffer Line Nb */
+#define LTDC_L1AFBAR (0xB8 + REG_OFS)/* L1 AuxFB Address */
+#define LTDC_L1AFBLR (0xBC + REG_OFS)/* L1 AuxFB Length */
+#define LTDC_L1AFBLNR (0xC0 + REG_OFS)/* L1 AuxFB Line Number */
+#define LTDC_L1CLUTWR (0xC4 + REG_OFS)/* L1 CLUT Write */
+#define LTDC_L1YS1R (0xE0 + REG_OFS)/* L1 YCbCr Scale 1 */
+#define LTDC_L1YS2R (0xE4 + REG_OFS)/* L1 YCbCr Scale 2 */
/* Bit definitions */
#define SSCR_VSH GENMASK(10, 0) /* Vertical Synchronization Height */
@@ -104,10 +104,10 @@
#define GCR_LTDCEN BIT(0) /* LTDC ENable */
#define GCR_DEN BIT(16) /* Dither ENable */
-#define GCR_PCPOL BIT(28) /* Pixel Clock POLarity */
-#define GCR_DEPOL BIT(29) /* Data Enable POLarity */
-#define GCR_VSPOL BIT(30) /* Vertical Synchro POLarity */
-#define GCR_HSPOL BIT(31) /* Horizontal Synchro POLarity */
+#define GCR_PCPOL BIT(28) /* Pixel Clock POLarity-Inverted */
+#define GCR_DEPOL BIT(29) /* Data Enable POLarity-High */
+#define GCR_VSPOL BIT(30) /* Vertical Synchro POLarity-High */
+#define GCR_HSPOL BIT(31) /* Horizontal Synchro POLarity-High */
#define GC1R_WBCH GENMASK(3, 0) /* Width of Blue CHannel output */
#define GC1R_WGCH GENMASK(7, 4) /* Width of Green Channel output */
@@ -172,60 +172,52 @@
#define LXCFBLR_CFBLL GENMASK(12, 0) /* Color Frame Buffer Line Length */
#define LXCFBLR_CFBP GENMASK(28, 16) /* Color Frame Buffer Pitch in bytes */
-#define LXCFBLNR_CFBLN GENMASK(10, 0) /* Color Frame Buffer Line Number */
+#define LXCFBLNR_CFBLN GENMASK(10, 0) /* Color Frame Buffer Line Number */
-#define HSPOL_AL 0 /* Horizontal Sync POLarity Active Low */
-#define VSPOL_AL 0 /* Vertical Sync POLarity Active Low */
-#define DEPOL_AL 0 /* Data Enable POLarity Active Low */
-#define PCPOL_IPC 0 /* Input Pixel Clock */
-#define HSPOL_AH GCR_HSPOL /* Horizontal Sync POLarity Active High */
-#define VSPOL_AH GCR_VSPOL /* Vertical Sync POLarity Active High */
-#define DEPOL_AH GCR_DEPOL /* Data Enable POLarity Active High */
-#define PCPOL_IIPC GCR_PCPOL /* Inverted Input Pixel Clock */
-#define CONSTA_MAX 0xFF /* CONSTant Alpha MAX= 1.0 */
-#define BF1_PAXCA 0x600 /* Pixel Alpha x Constant Alpha */
-#define BF1_CA 0x400 /* Constant Alpha */
-#define BF2_1PAXCA 0x007 /* 1 - (Pixel Alpha x Constant Alpha) */
-#define BF2_1CA 0x005 /* 1 - Constant Alpha */
+#define CONSTA_MAX 0xFF /* CONSTant Alpha MAX= 1.0 */
+#define BF1_PAXCA 0x600 /* Pixel Alpha x Constant Alpha */
+#define BF1_CA 0x400 /* Constant Alpha */
+#define BF2_1PAXCA 0x007 /* 1 - (Pixel Alpha x Constant Alpha) */
+#define BF2_1CA 0x005 /* 1 - Constant Alpha */
-#define NB_PF 8 /* Max nb of HW pixel format */
+#define NB_PF 8 /* Max nb of HW pixel format */
enum ltdc_pix_fmt {
PF_NONE,
/* RGB formats */
- PF_ARGB8888, /* ARGB [32 bits] */
- PF_RGBA8888, /* RGBA [32 bits] */
- PF_RGB888, /* RGB [24 bits] */
- PF_RGB565, /* RGB [16 bits] */
- PF_ARGB1555, /* ARGB A:1 bit RGB:15 bits [16 bits] */
- PF_ARGB4444, /* ARGB A:4 bits R/G/B: 4 bits each [16 bits] */
+ PF_ARGB8888, /* ARGB [32 bits] */
+ PF_RGBA8888, /* RGBA [32 bits] */
+ PF_RGB888, /* RGB [24 bits] */
+ PF_RGB565, /* RGB [16 bits] */
+ PF_ARGB1555, /* ARGB A:1 bit RGB:15 bits [16 bits] */
+ PF_ARGB4444, /* ARGB A:4 bits R/G/B: 4 bits each [16 bits] */
/* Indexed formats */
- PF_L8, /* Indexed 8 bits [8 bits] */
- PF_AL44, /* Alpha:4 bits + indexed 4 bits [8 bits] */
- PF_AL88 /* Alpha:8 bits + indexed 8 bits [16 bits] */
+ PF_L8, /* Indexed 8 bits [8 bits] */
+ PF_AL44, /* Alpha:4 bits + indexed 4 bits [8 bits] */
+ PF_AL88 /* Alpha:8 bits + indexed 8 bits [16 bits] */
};
/* The index gives the encoding of the pixel format for an HW version */
static const enum ltdc_pix_fmt ltdc_pix_fmt_a0[NB_PF] = {
- PF_ARGB8888, /* 0x00 */
- PF_RGB888, /* 0x01 */
- PF_RGB565, /* 0x02 */
- PF_ARGB1555, /* 0x03 */
- PF_ARGB4444, /* 0x04 */
- PF_L8, /* 0x05 */
- PF_AL44, /* 0x06 */
- PF_AL88 /* 0x07 */
+ PF_ARGB8888, /* 0x00 */
+ PF_RGB888, /* 0x01 */
+ PF_RGB565, /* 0x02 */
+ PF_ARGB1555, /* 0x03 */
+ PF_ARGB4444, /* 0x04 */
+ PF_L8, /* 0x05 */
+ PF_AL44, /* 0x06 */
+ PF_AL88 /* 0x07 */
};
static const enum ltdc_pix_fmt ltdc_pix_fmt_a1[NB_PF] = {
- PF_ARGB8888, /* 0x00 */
- PF_RGB888, /* 0x01 */
- PF_RGB565, /* 0x02 */
- PF_RGBA8888, /* 0x03 */
- PF_AL44, /* 0x04 */
- PF_L8, /* 0x05 */
- PF_ARGB1555, /* 0x06 */
- PF_ARGB4444 /* 0x07 */
+ PF_ARGB8888, /* 0x00 */
+ PF_RGB888, /* 0x01 */
+ PF_RGB565, /* 0x02 */
+ PF_RGBA8888, /* 0x03 */
+ PF_AL44, /* 0x04 */
+ PF_L8, /* 0x05 */
+ PF_ARGB1555, /* 0x06 */
+ PF_ARGB4444 /* 0x07 */
};
static inline u32 reg_read(void __iomem *base, u32 reg)
@@ -269,11 +261,6 @@ static inline struct ltdc_device *encoder_to_ltdc(struct drm_encoder *enc)
return (struct ltdc_device *)enc->dev->dev_private;
}
-static inline struct ltdc_device *connector_to_ltdc(struct drm_connector *con)
-{
- return (struct ltdc_device *)con->dev->dev_private;
-}
-
static inline enum ltdc_pix_fmt to_ltdc_pixelformat(u32 drm_fmt)
{
enum ltdc_pix_fmt pf;
@@ -307,7 +294,7 @@ static inline enum ltdc_pix_fmt to_ltdc_pixelformat(u32 drm_fmt)
default:
pf = PF_NONE;
break;
- /* Note: There are no DRM_FORMAT for AL44 and AL88 */
+ /* Note: There are no DRM_FORMAT for AL44 and AL88 */
}
return pf;
@@ -330,8 +317,8 @@ static inline u32 to_drm_pixelformat(enum ltdc_pix_fmt pf)
return DRM_FORMAT_ARGB4444;
case PF_L8:
return DRM_FORMAT_C8;
- case PF_AL44: /* No DRM support */
- case PF_AL88: /* No DRM support */
+ case PF_AL44: /* No DRM support */
+ case PF_AL88: /* No DRM support */
case PF_NONE:
default:
return 0;
@@ -375,18 +362,8 @@ static irqreturn_t ltdc_irq(int irq, void *arg)
* DRM_CRTC
*/
-static void ltdc_crtc_load_lut(struct drm_crtc *crtc)
-{
- struct ltdc_device *ldev = crtc_to_ltdc(crtc);
- unsigned int i, lay;
-
- for (lay = 0; lay < ldev->caps.nb_layers; lay++)
- for (i = 0; i < 256; i++)
- reg_write(ldev->regs, LTDC_L1CLUTWR + lay * LAY_OFS,
- ldev->clut[i]);
-}
-
-static void ltdc_crtc_enable(struct drm_crtc *crtc)
+static void ltdc_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct ltdc_device *ldev = crtc_to_ltdc(crtc);
@@ -407,7 +384,8 @@ static void ltdc_crtc_enable(struct drm_crtc *crtc)
drm_crtc_vblank_on(crtc);
}
-static void ltdc_crtc_disable(struct drm_crtc *crtc)
+static void ltdc_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct ltdc_device *ldev = crtc_to_ltdc(crtc);
@@ -462,20 +440,20 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc)
clk_enable(ldev->pixel_clk);
- /* Configures the HS, VS, DE and PC polarities. */
- val = HSPOL_AL | VSPOL_AL | DEPOL_AL | PCPOL_IPC;
+ /* Configures the HS, VS, DE and PC polarities. Default Active Low */
+ val = 0;
if (vm.flags & DISPLAY_FLAGS_HSYNC_HIGH)
- val |= HSPOL_AH;
+ val |= GCR_HSPOL;
if (vm.flags & DISPLAY_FLAGS_VSYNC_HIGH)
- val |= VSPOL_AH;
+ val |= GCR_VSPOL;
if (vm.flags & DISPLAY_FLAGS_DE_HIGH)
- val |= DEPOL_AH;
+ val |= GCR_DEPOL;
if (vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
- val |= PCPOL_IIPC;
+ val |= GCR_PCPOL;
reg_update_bits(ldev->regs, LTDC_GCR,
GCR_HSPOL | GCR_VSPOL | GCR_DEPOL | GCR_PCPOL, val);
@@ -522,12 +500,11 @@ static void ltdc_crtc_atomic_flush(struct drm_crtc *crtc,
}
}
-static struct drm_crtc_helper_funcs ltdc_crtc_helper_funcs = {
- .load_lut = ltdc_crtc_load_lut,
- .enable = ltdc_crtc_enable,
- .disable = ltdc_crtc_disable,
+static const struct drm_crtc_helper_funcs ltdc_crtc_helper_funcs = {
.mode_set_nofb = ltdc_crtc_mode_set_nofb,
.atomic_flush = ltdc_crtc_atomic_flush,
+ .atomic_enable = ltdc_crtc_atomic_enable,
+ .atomic_disable = ltdc_crtc_atomic_disable,
};
int ltdc_crtc_enable_vblank(struct drm_device *ddev, unsigned int pipe)
@@ -548,7 +525,7 @@ void ltdc_crtc_disable_vblank(struct drm_device *ddev, unsigned int pipe)
reg_clear(ldev->regs, LTDC_IER, IER_LIE);
}
-static struct drm_crtc_funcs ltdc_crtc_funcs = {
+static const struct drm_crtc_funcs ltdc_crtc_funcs = {
.destroy = drm_crtc_cleanup,
.set_config = drm_atomic_helper_set_config,
.page_flip = drm_atomic_helper_page_flip,
@@ -613,11 +590,11 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane,
src_w = state->src_w >> 16;
src_h = state->src_h >> 16;
- DRM_DEBUG_DRIVER(
- "plane:%d fb:%d (%dx%d)@(%d,%d) -> (%dx%d)@(%d,%d)\n",
- plane->base.id, fb->base.id,
- src_w, src_h, src_x, src_y,
- state->crtc_w, state->crtc_h, state->crtc_x, state->crtc_y);
+ DRM_DEBUG_DRIVER("plane:%d fb:%d (%dx%d)@(%d,%d) -> (%dx%d)@(%d,%d)\n",
+ plane->base.id, fb->base.id,
+ src_w, src_h, src_x, src_y,
+ state->crtc_w, state->crtc_h,
+ state->crtc_x, state->crtc_y);
bpcr = reg_read(ldev->regs, LTDC_BPCR);
ahbp = (bpcr & BPCR_AHBP) >> 16;
@@ -642,7 +619,7 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane,
if (val == NB_PF) {
DRM_ERROR("Pixel format %.4s not supported\n",
(char *)&fb->format->format);
- val = 0; /* set by default ARGB 32 bits */
+ val = 0; /* set by default ARGB 32 bits */
}
reg_update_bits(ldev->regs, LTDC_L1PFCR + lofs, LXPFCR_PF, val);
@@ -656,8 +633,7 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane,
/* Specifies the constant alpha value */
val = CONSTA_MAX;
- reg_update_bits(ldev->regs, LTDC_L1CACR + lofs,
- LXCACR_CONSTA, val);
+ reg_update_bits(ldev->regs, LTDC_L1CACR + lofs, LXCACR_CONSTA, val);
/* Specifies the blending factors */
val = BF1_PAXCA | BF2_1PAXCA;
@@ -666,8 +642,7 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane,
/* Configures the frame buffer line number */
val = y1 - y0 + 1;
- reg_update_bits(ldev->regs, LTDC_L1CFBLNR + lofs,
- LXCFBLNR_CFBLN, val);
+ reg_update_bits(ldev->regs, LTDC_L1CFBLNR + lofs, LXCFBLNR_CFBLN, val);
/* Sets the FB address */
paddr = (u32)drm_fb_cma_get_gem_addr(fb, state, 0);
@@ -706,11 +681,10 @@ static void ltdc_plane_atomic_disable(struct drm_plane *plane,
oldstate->crtc->base.id, plane->base.id);
}
-static struct drm_plane_funcs ltdc_plane_funcs = {
+static const struct drm_plane_funcs ltdc_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = drm_plane_cleanup,
- .set_property = drm_atomic_helper_plane_set_property,
.reset = drm_atomic_helper_plane_reset,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
@@ -748,7 +722,7 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev,
ret = drm_universal_plane_init(ddev, plane, possible_crtcs,
&ltdc_plane_funcs, formats, nb_fmt,
- type, NULL);
+ NULL, type, NULL);
if (ret < 0)
return 0;
@@ -773,7 +747,7 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
struct ltdc_device *ldev = ddev->dev_private;
struct drm_plane *primary, *overlay;
unsigned int i;
- int res;
+ int ret;
primary = ltdc_plane_create(ddev, DRM_PLANE_TYPE_PRIMARY);
if (!primary) {
@@ -781,9 +755,9 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
return -EINVAL;
}
- res = drm_crtc_init_with_planes(ddev, crtc, primary, NULL,
+ ret = drm_crtc_init_with_planes(ddev, crtc, primary, NULL,
&ltdc_crtc_funcs, NULL);
- if (res) {
+ if (ret) {
DRM_ERROR("Can not initialize CRTC\n");
goto cleanup;
}
@@ -796,7 +770,7 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
for (i = 1; i < ldev->caps.nb_layers; i++) {
overlay = ltdc_plane_create(ddev, DRM_PLANE_TYPE_OVERLAY);
if (!overlay) {
- res = -ENOMEM;
+ ret = -ENOMEM;
DRM_ERROR("Can not create overlay plane %d\n", i);
goto cleanup;
}
@@ -806,137 +780,42 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
cleanup:
ltdc_plane_destroy_all(ddev);
- return res;
+ return ret;
}
/*
* DRM_ENCODER
*/
-static void ltdc_rgb_encoder_enable(struct drm_encoder *encoder)
-{
- struct ltdc_device *ldev = encoder_to_ltdc(encoder);
-
- DRM_DEBUG_DRIVER("\n");
-
- drm_panel_prepare(ldev->panel);
- drm_panel_enable(ldev->panel);
-}
-
-static void ltdc_rgb_encoder_disable(struct drm_encoder *encoder)
-{
- struct ltdc_device *ldev = encoder_to_ltdc(encoder);
-
- DRM_DEBUG_DRIVER("\n");
-
- drm_panel_disable(ldev->panel);
- drm_panel_unprepare(ldev->panel);
-}
-
-static const struct drm_encoder_helper_funcs ltdc_rgb_encoder_helper_funcs = {
- .enable = ltdc_rgb_encoder_enable,
- .disable = ltdc_rgb_encoder_disable,
-};
-
-static const struct drm_encoder_funcs ltdc_rgb_encoder_funcs = {
+static const struct drm_encoder_funcs ltdc_encoder_funcs = {
.destroy = drm_encoder_cleanup,
};
-static struct drm_encoder *ltdc_rgb_encoder_create(struct drm_device *ddev)
+static int ltdc_encoder_init(struct drm_device *ddev)
{
+ struct ltdc_device *ldev = ddev->dev_private;
struct drm_encoder *encoder;
+ int ret;
encoder = devm_kzalloc(ddev->dev, sizeof(*encoder), GFP_KERNEL);
if (!encoder)
- return NULL;
+ return -ENOMEM;
encoder->possible_crtcs = CRTC_MASK;
- encoder->possible_clones = 0; /* No cloning support */
+ encoder->possible_clones = 0; /* No cloning support */
- drm_encoder_init(ddev, encoder, &ltdc_rgb_encoder_funcs,
+ drm_encoder_init(ddev, encoder, &ltdc_encoder_funcs,
DRM_MODE_ENCODER_DPI, NULL);
- drm_encoder_helper_add(encoder, &ltdc_rgb_encoder_helper_funcs);
-
- DRM_DEBUG_DRIVER("RGB encoder:%d created\n", encoder->base.id);
-
- return encoder;
-}
-
-/*
- * DRM_CONNECTOR
- */
-
-static int ltdc_rgb_connector_get_modes(struct drm_connector *connector)
-{
- struct drm_device *ddev = connector->dev;
- struct ltdc_device *ldev = ddev->dev_private;
- int ret = 0;
-
- DRM_DEBUG_DRIVER("\n");
-
- if (ldev->panel)
- ret = drm_panel_get_modes(ldev->panel);
-
- return ret < 0 ? 0 : ret;
-}
-
-static struct drm_connector_helper_funcs ltdc_rgb_connector_helper_funcs = {
- .get_modes = ltdc_rgb_connector_get_modes,
-};
-
-static enum drm_connector_status
-ltdc_rgb_connector_detect(struct drm_connector *connector, bool force)
-{
- struct ltdc_device *ldev = connector_to_ltdc(connector);
-
- return ldev->panel ? connector_status_connected :
- connector_status_disconnected;
-}
-
-static void ltdc_rgb_connector_destroy(struct drm_connector *connector)
-{
- DRM_DEBUG_DRIVER("\n");
-
- drm_connector_unregister(connector);
- drm_connector_cleanup(connector);
-}
-
-static const struct drm_connector_funcs ltdc_rgb_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
- .fill_modes = drm_helper_probe_single_connector_modes,
- .detect = ltdc_rgb_connector_detect,
- .destroy = ltdc_rgb_connector_destroy,
- .reset = drm_atomic_helper_connector_reset,
- .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
- .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
-struct drm_connector *ltdc_rgb_connector_create(struct drm_device *ddev)
-{
- struct drm_connector *connector;
- int err;
-
- connector = devm_kzalloc(ddev->dev, sizeof(*connector), GFP_KERNEL);
- if (!connector) {
- DRM_ERROR("Failed to allocate connector\n");
- return NULL;
- }
-
- connector->polled = DRM_CONNECTOR_POLL_HPD;
-
- err = drm_connector_init(ddev, connector, &ltdc_rgb_connector_funcs,
- DRM_MODE_CONNECTOR_DPI);
- if (err) {
- DRM_ERROR("Failed to initialize connector\n");
- return NULL;
+ ret = drm_bridge_attach(encoder, ldev->bridge, NULL);
+ if (ret) {
+ drm_encoder_cleanup(encoder);
+ return -EINVAL;
}
- drm_connector_helper_add(connector, &ltdc_rgb_connector_helper_funcs);
-
- DRM_DEBUG_DRIVER("RGB connector:%d created\n", connector->base.id);
+ DRM_DEBUG_DRIVER("Bridge encoder:%d created\n", encoder->base.id);
- return connector;
+ return 0;
}
static int ltdc_get_caps(struct drm_device *ddev)
@@ -972,61 +851,26 @@ static int ltdc_get_caps(struct drm_device *ddev)
return 0;
}
-static struct drm_panel *ltdc_get_panel(struct drm_device *ddev)
-{
- struct device *dev = ddev->dev;
- struct device_node *np = dev->of_node;
- struct device_node *entity, *port = NULL;
- struct drm_panel *panel = NULL;
-
- DRM_DEBUG_DRIVER("\n");
-
- /*
- * Parse ltdc node to get remote port and find RGB panel / HDMI slave
- * If a dsi or a bridge (hdmi, lvds...) is connected to ltdc,
- * a remote port & RGB panel will not be found.
- */
- for_each_endpoint_of_node(np, entity) {
- if (!of_device_is_available(entity))
- continue;
-
- port = of_graph_get_remote_port_parent(entity);
- if (port) {
- panel = of_drm_find_panel(port);
- of_node_put(port);
- if (panel) {
- DRM_DEBUG_DRIVER("remote panel %s\n",
- port->full_name);
- } else {
- DRM_DEBUG_DRIVER("panel missing\n");
- of_node_put(entity);
- }
- }
- }
-
- return panel;
-}
-
int ltdc_load(struct drm_device *ddev)
{
struct platform_device *pdev = to_platform_device(ddev->dev);
struct ltdc_device *ldev = ddev->dev_private;
struct device *dev = ddev->dev;
struct device_node *np = dev->of_node;
- struct drm_encoder *encoder;
- struct drm_connector *connector = NULL;
+ struct drm_bridge *bridge;
+ struct drm_panel *panel;
struct drm_crtc *crtc;
struct reset_control *rstc;
- struct resource res;
+ struct resource *res;
int irq, ret, i;
DRM_DEBUG_DRIVER("\n");
- ldev->panel = ltdc_get_panel(ddev);
- if (!ldev->panel)
- return -EPROBE_DEFER;
+ ret = drm_of_find_panel_or_bridge(np, 0, 0, &panel, &bridge);
+ if (ret)
+ return ret;
- rstc = of_reset_control_get(np, NULL);
+ rstc = devm_reset_control_get_exclusive(dev, NULL);
mutex_init(&ldev->err_lock);
@@ -1041,15 +885,18 @@ int ltdc_load(struct drm_device *ddev)
return -ENODEV;
}
- if (of_address_to_resource(np, 0, &res)) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
DRM_ERROR("Unable to get resource\n");
- return -ENODEV;
+ ret = -ENODEV;
+ goto err;
}
- ldev->regs = devm_ioremap_resource(dev, &res);
+ ldev->regs = devm_ioremap_resource(dev, res);
if (IS_ERR(ldev->regs)) {
DRM_ERROR("Unable to get ltdc registers\n");
- return PTR_ERR(ldev->regs);
+ ret = PTR_ERR(ldev->regs);
+ goto err;
}
for (i = 0; i < MAX_IRQ; i++) {
@@ -1062,7 +909,7 @@ int ltdc_load(struct drm_device *ddev)
dev_name(dev), ddev);
if (ret) {
DRM_ERROR("Failed to register LTDC interrupt\n");
- return ret;
+ goto err;
}
}
@@ -1077,33 +924,27 @@ int ltdc_load(struct drm_device *ddev)
if (ret) {
DRM_ERROR("hardware identifier (0x%08x) not supported!\n",
ldev->caps.hw_version);
- return ret;
+ goto err;
}
DRM_INFO("ltdc hw version 0x%08x - ready\n", ldev->caps.hw_version);
- if (ldev->panel) {
- encoder = ltdc_rgb_encoder_create(ddev);
- if (!encoder) {
- DRM_ERROR("Failed to create RGB encoder\n");
- ret = -EINVAL;
+ if (panel) {
+ bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_DPI);
+ if (IS_ERR(bridge)) {
+ DRM_ERROR("Failed to create panel-bridge\n");
+ ret = PTR_ERR(bridge);
goto err;
}
+ ldev->is_panel_bridge = true;
+ }
- connector = ltdc_rgb_connector_create(ddev);
- if (!connector) {
- DRM_ERROR("Failed to create RGB connector\n");
- ret = -EINVAL;
- goto err;
- }
+ ldev->bridge = bridge;
- ret = drm_mode_connector_attach_encoder(connector, encoder);
- if (ret) {
- DRM_ERROR("Failed to attach connector to encoder\n");
- goto err;
- }
-
- drm_panel_attach(ldev->panel, connector);
+ ret = ltdc_encoder_init(ddev);
+ if (ret) {
+ DRM_ERROR("Failed to init encoder\n");
+ goto err;
}
crtc = devm_kzalloc(dev, sizeof(*crtc), GFP_KERNEL);
@@ -1129,9 +970,10 @@ int ltdc_load(struct drm_device *ddev)
ddev->irq_enabled = 1;
return 0;
+
err:
- if (ldev->panel)
- drm_panel_detach(ldev->panel);
+ if (ldev->is_panel_bridge)
+ drm_panel_bridge_remove(bridge);
clk_disable_unprepare(ldev->pixel_clk);
@@ -1144,8 +986,8 @@ void ltdc_unload(struct drm_device *ddev)
DRM_DEBUG_DRIVER("\n");
- if (ldev->panel)
- drm_panel_detach(ldev->panel);
+ if (ldev->is_panel_bridge)
+ drm_panel_bridge_remove(ldev->bridge);
clk_disable_unprepare(ldev->pixel_clk);
}
diff --git a/drivers/gpu/drm/stm/ltdc.h b/drivers/gpu/drm/stm/ltdc.h
index d7a9c73..bc6d6f6 100644
--- a/drivers/gpu/drm/stm/ltdc.h
+++ b/drivers/gpu/drm/stm/ltdc.h
@@ -24,10 +24,10 @@ struct ltdc_device {
struct drm_fbdev_cma *fbdev;
void __iomem *regs;
struct clk *pixel_clk; /* lcd pixel clock */
- struct drm_panel *panel;
+ struct drm_bridge *bridge;
+ bool is_panel_bridge;
struct mutex err_lock; /* protecting error_status */
struct ltdc_caps caps;
- u32 clut[256]; /* color look up table */
u32 error_status;
u32 irq_status;
};
diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig
index 5bcad8f..06f0530 100644
--- a/drivers/gpu/drm/sun4i/Kconfig
+++ b/drivers/gpu/drm/sun4i/Kconfig
@@ -13,17 +13,26 @@ config DRM_SUN4I
Display Engine. If M is selected the module will be called
sun4i-drm.
+if DRM_SUN4I
+
config DRM_SUN4I_HDMI
tristate "Allwinner A10 HDMI Controller Support"
- depends on DRM_SUN4I
default DRM_SUN4I
help
Choose this option if you have an Allwinner SoC with an HDMI
controller.
+config DRM_SUN4I_HDMI_CEC
+ bool "Allwinner A10 HDMI CEC Support"
+ depends on DRM_SUN4I_HDMI
+ select CEC_CORE
+ depends on CEC_PIN
+ help
+ Choose this option if you have an Allwinner SoC with an HDMI
+ controller and want to use CEC.
+
config DRM_SUN4I_BACKEND
tristate "Support for Allwinner A10 Display Engine Backend"
- depends on DRM_SUN4I
default DRM_SUN4I
help
Choose this option if you have an Allwinner SoC with the
@@ -33,10 +42,11 @@ config DRM_SUN4I_BACKEND
config DRM_SUN8I_MIXER
tristate "Support for Allwinner Display Engine 2.0 Mixer"
- depends on DRM_SUN4I
default MACH_SUN8I
help
Choose this option if you have an Allwinner SoC with the
Allwinner Display Engine 2.0, which has a mixer to do some
graphics mixture and feed graphics to TCON, If M is
selected the module will be called sun8i-mixer.
+
+endif
diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile
index e29fd3a..43c753c 100644
--- a/drivers/gpu/drm/sun4i/Makefile
+++ b/drivers/gpu/drm/sun4i/Makefile
@@ -2,6 +2,7 @@ sun4i-drm-y += sun4i_drv.o
sun4i-drm-y += sun4i_framebuffer.o
sun4i-drm-hdmi-y += sun4i_hdmi_enc.o
+sun4i-drm-hdmi-y += sun4i_hdmi_i2c.o
sun4i-drm-hdmi-y += sun4i_hdmi_ddc_clk.o
sun4i-drm-hdmi-y += sun4i_hdmi_tmds_clk.o
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c
index cf48021..ec59436 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.c
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
@@ -312,7 +312,7 @@ static int sun4i_backend_of_get_id(struct device_node *node)
struct device_node *remote;
u32 reg;
- remote = of_parse_phandle(ep, "remote-endpoint", 0);
+ remote = of_graph_get_remote_endpoint(ep);
if (!remote)
continue;
diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c b/drivers/gpu/drm/sun4i/sun4i_crtc.c
index f8c7043..d097c6f 100644
--- a/drivers/gpu/drm/sun4i/sun4i_crtc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c
@@ -69,7 +69,8 @@ static void sun4i_crtc_atomic_flush(struct drm_crtc *crtc,
}
}
-static void sun4i_crtc_disable(struct drm_crtc *crtc)
+static void sun4i_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc);
@@ -86,7 +87,8 @@ static void sun4i_crtc_disable(struct drm_crtc *crtc)
}
}
-static void sun4i_crtc_enable(struct drm_crtc *crtc)
+static void sun4i_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc);
@@ -98,8 +100,8 @@ static void sun4i_crtc_enable(struct drm_crtc *crtc)
static const struct drm_crtc_helper_funcs sun4i_crtc_helper_funcs = {
.atomic_begin = sun4i_crtc_atomic_begin,
.atomic_flush = sun4i_crtc_atomic_flush,
- .disable = sun4i_crtc_disable,
- .enable = sun4i_crtc_enable,
+ .atomic_enable = sun4i_crtc_atomic_enable,
+ .atomic_disable = sun4i_crtc_atomic_disable,
};
static int sun4i_crtc_enable_vblank(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index a45a627..ace5965 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -48,8 +48,6 @@ static struct drm_driver sun4i_drv_driver = {
/* GEM Operations */
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_destroy = drm_gem_dumb_destroy,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
@@ -195,9 +193,9 @@ static bool sun4i_drv_node_is_tcon(struct device_node *node)
static int compare_of(struct device *dev, void *data)
{
- DRM_DEBUG_DRIVER("Comparing of node %s with %s\n",
- of_node_full_name(dev->of_node),
- of_node_full_name(data));
+ DRM_DEBUG_DRIVER("Comparing of node %pOF with %pOF\n",
+ dev->of_node,
+ data);
return dev->of_node == data;
}
@@ -227,8 +225,7 @@ static int sun4i_drv_add_endpoints(struct device *dev,
if (!sun4i_drv_node_is_frontend(node)) {
/* Add current component */
- DRM_DEBUG_DRIVER("Adding component %s\n",
- of_node_full_name(node));
+ DRM_DEBUG_DRIVER("Adding component %pOF\n", node);
drm_of_component_match_add(dev, match, compare_of, node);
count++;
}
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
index 2f2f2ff..1457750 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
@@ -15,6 +15,8 @@
#include <drm/drm_connector.h>
#include <drm/drm_encoder.h>
+#include <media/cec.h>
+
#define SUN4I_HDMI_CTRL_REG 0x004
#define SUN4I_HDMI_CTRL_ENABLE BIT(31)
@@ -86,6 +88,11 @@
#define SUN4I_HDMI_PLL_DBG0_TMDS_PARENT_MASK BIT(21)
#define SUN4I_HDMI_PLL_DBG0_TMDS_PARENT_SHIFT 21
+#define SUN4I_HDMI_CEC 0x214
+#define SUN4I_HDMI_CEC_ENABLE BIT(11)
+#define SUN4I_HDMI_CEC_TX BIT(9)
+#define SUN4I_HDMI_CEC_RX BIT(8)
+
#define SUN4I_HDMI_PKT_CTRL_REG(n) (0x2f0 + (4 * (n)))
#define SUN4I_HDMI_PKT_CTRL_TYPE(n, t) ((t) << (((n) % 4) * 4))
@@ -96,6 +103,7 @@
#define SUN4I_HDMI_DDC_CTRL_ENABLE BIT(31)
#define SUN4I_HDMI_DDC_CTRL_START_CMD BIT(30)
#define SUN4I_HDMI_DDC_CTRL_FIFO_DIR_MASK BIT(8)
+#define SUN4I_HDMI_DDC_CTRL_FIFO_DIR_WRITE (1 << 8)
#define SUN4I_HDMI_DDC_CTRL_FIFO_DIR_READ (0 << 8)
#define SUN4I_HDMI_DDC_CTRL_RESET BIT(0)
@@ -105,14 +113,34 @@
#define SUN4I_HDMI_DDC_ADDR_OFFSET(off) (((off) & 0xff) << 8)
#define SUN4I_HDMI_DDC_ADDR_SLAVE(addr) ((addr) & 0xff)
+#define SUN4I_HDMI_DDC_INT_STATUS_REG 0x50c
+#define SUN4I_HDMI_DDC_INT_STATUS_ILLEGAL_FIFO_OPERATION BIT(7)
+#define SUN4I_HDMI_DDC_INT_STATUS_DDC_RX_FIFO_UNDERFLOW BIT(6)
+#define SUN4I_HDMI_DDC_INT_STATUS_DDC_TX_FIFO_OVERFLOW BIT(5)
+#define SUN4I_HDMI_DDC_INT_STATUS_FIFO_REQUEST BIT(4)
+#define SUN4I_HDMI_DDC_INT_STATUS_ARBITRATION_ERROR BIT(3)
+#define SUN4I_HDMI_DDC_INT_STATUS_ACK_ERROR BIT(2)
+#define SUN4I_HDMI_DDC_INT_STATUS_BUS_ERROR BIT(1)
+#define SUN4I_HDMI_DDC_INT_STATUS_TRANSFER_COMPLETE BIT(0)
+
#define SUN4I_HDMI_DDC_FIFO_CTRL_REG 0x510
#define SUN4I_HDMI_DDC_FIFO_CTRL_CLEAR BIT(31)
+#define SUN4I_HDMI_DDC_FIFO_CTRL_RX_THRES(n) (((n) & 0xf) << 4)
+#define SUN4I_HDMI_DDC_FIFO_CTRL_RX_THRES_MASK GENMASK(7, 4)
+#define SUN4I_HDMI_DDC_FIFO_CTRL_RX_THRES_MAX (BIT(4) - 1)
+#define SUN4I_HDMI_DDC_FIFO_CTRL_TX_THRES(n) ((n) & 0xf)
+#define SUN4I_HDMI_DDC_FIFO_CTRL_TX_THRES_MASK GENMASK(3, 0)
+#define SUN4I_HDMI_DDC_FIFO_CTRL_TX_THRES_MAX (BIT(4) - 1)
#define SUN4I_HDMI_DDC_FIFO_DATA_REG 0x518
+
#define SUN4I_HDMI_DDC_BYTE_COUNT_REG 0x51c
+#define SUN4I_HDMI_DDC_BYTE_COUNT_MAX (BIT(10) - 1)
#define SUN4I_HDMI_DDC_CMD_REG 0x520
#define SUN4I_HDMI_DDC_CMD_EXPLICIT_EDDC_READ 6
+#define SUN4I_HDMI_DDC_CMD_IMPLICIT_READ 5
+#define SUN4I_HDMI_DDC_CMD_IMPLICIT_WRITE 3
#define SUN4I_HDMI_DDC_CLK_REG 0x528
#define SUN4I_HDMI_DDC_CLK_M(m) (((m) & 0x7) << 3)
@@ -146,12 +174,16 @@ struct sun4i_hdmi {
struct clk *ddc_clk;
struct clk *tmds_clk;
+ struct i2c_adapter *i2c;
+
struct sun4i_drv *drv;
bool hdmi_monitor;
+ struct cec_adapter *cec_adap;
};
int sun4i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *clk);
int sun4i_tmds_create(struct sun4i_hdmi *hdmi);
+int sun4i_hdmi_i2c_create(struct device *dev, struct sun4i_hdmi *hdmi);
#endif /* _SUN4I_HDMI_H_ */
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index d3398f62..9ea6cd5 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -29,8 +29,6 @@
#include "sun4i_hdmi.h"
#include "sun4i_tcon.h"
-#define DDC_SEGMENT_ADDR 0x30
-
static inline struct sun4i_hdmi *
drm_encoder_to_sun4i_hdmi(struct drm_encoder *encoder)
{
@@ -52,7 +50,7 @@ static int sun4i_hdmi_setup_avi_infoframes(struct sun4i_hdmi *hdmi,
u8 buffer[17];
int i, ret;
- ret = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+ ret = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
if (ret < 0) {
DRM_ERROR("Failed to get infoframes from mode\n");
return ret;
@@ -184,93 +182,13 @@ static const struct drm_encoder_funcs sun4i_hdmi_funcs = {
.destroy = drm_encoder_cleanup,
};
-static int sun4i_hdmi_read_sub_block(struct sun4i_hdmi *hdmi,
- unsigned int blk, unsigned int offset,
- u8 *buf, unsigned int count)
-{
- unsigned long reg;
- int i;
-
- reg = readl(hdmi->base + SUN4I_HDMI_DDC_CTRL_REG);
- reg &= ~SUN4I_HDMI_DDC_CTRL_FIFO_DIR_MASK;
- writel(reg | SUN4I_HDMI_DDC_CTRL_FIFO_DIR_READ,
- hdmi->base + SUN4I_HDMI_DDC_CTRL_REG);
-
- writel(SUN4I_HDMI_DDC_ADDR_SEGMENT(offset >> 8) |
- SUN4I_HDMI_DDC_ADDR_EDDC(DDC_SEGMENT_ADDR << 1) |
- SUN4I_HDMI_DDC_ADDR_OFFSET(offset) |
- SUN4I_HDMI_DDC_ADDR_SLAVE(DDC_ADDR),
- hdmi->base + SUN4I_HDMI_DDC_ADDR_REG);
-
- reg = readl(hdmi->base + SUN4I_HDMI_DDC_FIFO_CTRL_REG);
- writel(reg | SUN4I_HDMI_DDC_FIFO_CTRL_CLEAR,
- hdmi->base + SUN4I_HDMI_DDC_FIFO_CTRL_REG);
-
- writel(count, hdmi->base + SUN4I_HDMI_DDC_BYTE_COUNT_REG);
- writel(SUN4I_HDMI_DDC_CMD_EXPLICIT_EDDC_READ,
- hdmi->base + SUN4I_HDMI_DDC_CMD_REG);
-
- reg = readl(hdmi->base + SUN4I_HDMI_DDC_CTRL_REG);
- writel(reg | SUN4I_HDMI_DDC_CTRL_START_CMD,
- hdmi->base + SUN4I_HDMI_DDC_CTRL_REG);
-
- if (readl_poll_timeout(hdmi->base + SUN4I_HDMI_DDC_CTRL_REG, reg,
- !(reg & SUN4I_HDMI_DDC_CTRL_START_CMD),
- 100, 100000))
- return -EIO;
-
- for (i = 0; i < count; i++)
- buf[i] = readb(hdmi->base + SUN4I_HDMI_DDC_FIFO_DATA_REG);
-
- return 0;
-}
-
-static int sun4i_hdmi_read_edid_block(void *data, u8 *buf, unsigned int blk,
- size_t length)
-{
- struct sun4i_hdmi *hdmi = data;
- int retry = 2, i;
-
- do {
- for (i = 0; i < length; i += SUN4I_HDMI_DDC_FIFO_SIZE) {
- unsigned char offset = blk * EDID_LENGTH + i;
- unsigned int count = min((unsigned int)SUN4I_HDMI_DDC_FIFO_SIZE,
- length - i);
- int ret;
-
- ret = sun4i_hdmi_read_sub_block(hdmi, blk, offset,
- buf + i, count);
- if (ret)
- return ret;
- }
- } while (!drm_edid_block_valid(buf, blk, true, NULL) && (retry--));
-
- return 0;
-}
-
static int sun4i_hdmi_get_modes(struct drm_connector *connector)
{
struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector);
- unsigned long reg;
struct edid *edid;
int ret;
- /* Reset i2c controller */
- writel(SUN4I_HDMI_DDC_CTRL_ENABLE | SUN4I_HDMI_DDC_CTRL_RESET,
- hdmi->base + SUN4I_HDMI_DDC_CTRL_REG);
- if (readl_poll_timeout(hdmi->base + SUN4I_HDMI_DDC_CTRL_REG, reg,
- !(reg & SUN4I_HDMI_DDC_CTRL_RESET),
- 100, 2000))
- return -EIO;
-
- writel(SUN4I_HDMI_DDC_LINE_CTRL_SDA_ENABLE |
- SUN4I_HDMI_DDC_LINE_CTRL_SCL_ENABLE,
- hdmi->base + SUN4I_HDMI_DDC_LINE_CTRL_REG);
-
- clk_prepare_enable(hdmi->ddc_clk);
- clk_set_rate(hdmi->ddc_clk, 100000);
-
- edid = drm_do_get_edid(connector, sun4i_hdmi_read_edid_block, hdmi);
+ edid = drm_get_edid(connector, hdmi->i2c);
if (!edid)
return 0;
@@ -279,11 +197,10 @@ static int sun4i_hdmi_get_modes(struct drm_connector *connector)
hdmi->hdmi_monitor ? "an HDMI" : "a DVI");
drm_mode_connector_update_edid_property(connector, edid);
+ cec_s_phys_addr_from_edid(hdmi->cec_adap, edid);
ret = drm_add_edid_modes(connector, edid);
kfree(edid);
- clk_disable_unprepare(hdmi->ddc_clk);
-
return ret;
}
@@ -299,14 +216,15 @@ sun4i_hdmi_connector_detect(struct drm_connector *connector, bool force)
if (readl_poll_timeout(hdmi->base + SUN4I_HDMI_HPD_REG, reg,
reg & SUN4I_HDMI_HPD_HIGH,
- 0, 500000))
+ 0, 500000)) {
+ cec_phys_addr_invalidate(hdmi->cec_adap);
return connector_status_disconnected;
+ }
return connector_status_connected;
}
static const struct drm_connector_funcs sun4i_hdmi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = sun4i_hdmi_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
@@ -315,6 +233,40 @@ static const struct drm_connector_funcs sun4i_hdmi_connector_funcs = {
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
+#ifdef CONFIG_DRM_SUN4I_HDMI_CEC
+static bool sun4i_hdmi_cec_pin_read(struct cec_adapter *adap)
+{
+ struct sun4i_hdmi *hdmi = cec_get_drvdata(adap);
+
+ return readl(hdmi->base + SUN4I_HDMI_CEC) & SUN4I_HDMI_CEC_RX;
+}
+
+static void sun4i_hdmi_cec_pin_low(struct cec_adapter *adap)
+{
+ struct sun4i_hdmi *hdmi = cec_get_drvdata(adap);
+
+ /* Start driving the CEC pin low */
+ writel(SUN4I_HDMI_CEC_ENABLE, hdmi->base + SUN4I_HDMI_CEC);
+}
+
+static void sun4i_hdmi_cec_pin_high(struct cec_adapter *adap)
+{
+ struct sun4i_hdmi *hdmi = cec_get_drvdata(adap);
+
+ /*
+ * Stop driving the CEC pin, the pull up will take over
+ * unless another CEC device is driving the pin low.
+ */
+ writel(0, hdmi->base + SUN4I_HDMI_CEC);
+}
+
+static const struct cec_pin_ops sun4i_hdmi_cec_pin_ops = {
+ .read = sun4i_hdmi_cec_pin_read,
+ .low = sun4i_hdmi_cec_pin_low,
+ .high = sun4i_hdmi_cec_pin_high,
+};
+#endif
+
static int sun4i_hdmi_bind(struct device *dev, struct device *master,
void *data)
{
@@ -407,9 +359,9 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
SUN4I_HDMI_PLL_CTRL_PLL_EN;
writel(reg, hdmi->base + SUN4I_HDMI_PLL_CTRL_REG);
- ret = sun4i_ddc_create(hdmi, hdmi->tmds_clk);
+ ret = sun4i_hdmi_i2c_create(dev, hdmi);
if (ret) {
- dev_err(dev, "Couldn't create the DDC clock\n");
+ dev_err(dev, "Couldn't create the HDMI I2C adapter\n");
return ret;
}
@@ -422,13 +374,26 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
NULL);
if (ret) {
dev_err(dev, "Couldn't initialise the HDMI encoder\n");
- return ret;
+ goto err_del_i2c_adapter;
}
hdmi->encoder.possible_crtcs = drm_of_find_possible_crtcs(drm,
dev->of_node);
- if (!hdmi->encoder.possible_crtcs)
- return -EPROBE_DEFER;
+ if (!hdmi->encoder.possible_crtcs) {
+ ret = -EPROBE_DEFER;
+ goto err_del_i2c_adapter;
+ }
+
+#ifdef CONFIG_DRM_SUN4I_HDMI_CEC
+ hdmi->cec_adap = cec_pin_allocate_adapter(&sun4i_hdmi_cec_pin_ops,
+ hdmi, "sun4i", CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS |
+ CEC_CAP_PASSTHROUGH | CEC_CAP_RC);
+ ret = PTR_ERR_OR_ZERO(hdmi->cec_adap);
+ if (ret < 0)
+ goto err_cleanup_connector;
+ writel(readl(hdmi->base + SUN4I_HDMI_CEC) & ~SUN4I_HDMI_CEC_TX,
+ hdmi->base + SUN4I_HDMI_CEC);
+#endif
drm_connector_helper_add(&hdmi->connector,
&sun4i_hdmi_connector_helper_funcs);
@@ -445,12 +410,18 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
hdmi->connector.polled = DRM_CONNECTOR_POLL_CONNECT |
DRM_CONNECTOR_POLL_DISCONNECT;
+ ret = cec_register_adapter(hdmi->cec_adap, dev);
+ if (ret < 0)
+ goto err_cleanup_connector;
drm_mode_connector_attach_encoder(&hdmi->connector, &hdmi->encoder);
return 0;
err_cleanup_connector:
+ cec_delete_adapter(hdmi->cec_adap);
drm_encoder_cleanup(&hdmi->encoder);
+err_del_i2c_adapter:
+ i2c_del_adapter(hdmi->i2c);
return ret;
}
@@ -459,8 +430,10 @@ static void sun4i_hdmi_unbind(struct device *dev, struct device *master,
{
struct sun4i_hdmi *hdmi = dev_get_drvdata(dev);
+ cec_unregister_adapter(hdmi->cec_adap);
drm_connector_cleanup(&hdmi->connector);
drm_encoder_cleanup(&hdmi->encoder);
+ i2c_del_adapter(hdmi->i2c);
}
static const struct component_ops sun4i_hdmi_ops = {
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_i2c.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_i2c.c
new file mode 100644
index 0000000..2e42d09
--- /dev/null
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_i2c.c
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2016 Maxime Ripard <maxime.ripard@free-electrons.com>
+ * Copyright (C) 2017 Jonathan Liu <net147@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <linux/clk.h>
+#include <linux/i2c.h>
+#include <linux/iopoll.h>
+
+#include "sun4i_hdmi.h"
+
+#define SUN4I_HDMI_DDC_INT_STATUS_ERROR_MASK ( \
+ SUN4I_HDMI_DDC_INT_STATUS_ILLEGAL_FIFO_OPERATION | \
+ SUN4I_HDMI_DDC_INT_STATUS_DDC_RX_FIFO_UNDERFLOW | \
+ SUN4I_HDMI_DDC_INT_STATUS_DDC_TX_FIFO_OVERFLOW | \
+ SUN4I_HDMI_DDC_INT_STATUS_ARBITRATION_ERROR | \
+ SUN4I_HDMI_DDC_INT_STATUS_ACK_ERROR | \
+ SUN4I_HDMI_DDC_INT_STATUS_BUS_ERROR \
+)
+
+/* FIFO request bit is set when FIFO level is above RX_THRESHOLD during read */
+#define RX_THRESHOLD SUN4I_HDMI_DDC_FIFO_CTRL_RX_THRES_MAX
+/* FIFO request bit is set when FIFO level is below TX_THRESHOLD during write */
+#define TX_THRESHOLD 1
+
+static int fifo_transfer(struct sun4i_hdmi *hdmi, u8 *buf, int len, bool read)
+{
+ /*
+ * 1 byte takes 9 clock cycles (8 bits + 1 ACK) = 90 us for 100 kHz
+ * clock. As clock rate is fixed, just round it up to 100 us.
+ */
+ const unsigned long byte_time_ns = 100;
+ const u32 mask = SUN4I_HDMI_DDC_INT_STATUS_ERROR_MASK |
+ SUN4I_HDMI_DDC_INT_STATUS_FIFO_REQUEST |
+ SUN4I_HDMI_DDC_INT_STATUS_TRANSFER_COMPLETE;
+ u32 reg;
+
+ /* Limit transfer length by FIFO threshold */
+ len = min_t(int, len, read ? (RX_THRESHOLD + 1) :
+ (SUN4I_HDMI_DDC_FIFO_SIZE - TX_THRESHOLD + 1));
+
+ /* Wait until error, FIFO request bit set or transfer complete */
+ if (readl_poll_timeout(hdmi->base + SUN4I_HDMI_DDC_INT_STATUS_REG, reg,
+ reg & mask, len * byte_time_ns, 100000))
+ return -ETIMEDOUT;
+
+ if (reg & SUN4I_HDMI_DDC_INT_STATUS_ERROR_MASK)
+ return -EIO;
+
+ if (read)
+ readsb(hdmi->base + SUN4I_HDMI_DDC_FIFO_DATA_REG, buf, len);
+ else
+ writesb(hdmi->base + SUN4I_HDMI_DDC_FIFO_DATA_REG, buf, len);
+
+ /* Clear FIFO request bit */
+ writel(SUN4I_HDMI_DDC_INT_STATUS_FIFO_REQUEST,
+ hdmi->base + SUN4I_HDMI_DDC_INT_STATUS_REG);
+
+ return len;
+}
+
+static int xfer_msg(struct sun4i_hdmi *hdmi, struct i2c_msg *msg)
+{
+ int i, len;
+ u32 reg;
+
+ /* Set FIFO direction */
+ reg = readl(hdmi->base + SUN4I_HDMI_DDC_CTRL_REG);
+ reg &= ~SUN4I_HDMI_DDC_CTRL_FIFO_DIR_MASK;
+ reg |= (msg->flags & I2C_M_RD) ?
+ SUN4I_HDMI_DDC_CTRL_FIFO_DIR_READ :
+ SUN4I_HDMI_DDC_CTRL_FIFO_DIR_WRITE;
+ writel(reg, hdmi->base + SUN4I_HDMI_DDC_CTRL_REG);
+
+ /* Set I2C address */
+ writel(SUN4I_HDMI_DDC_ADDR_SLAVE(msg->addr),
+ hdmi->base + SUN4I_HDMI_DDC_ADDR_REG);
+
+ /* Set FIFO RX/TX thresholds and clear FIFO */
+ reg = readl(hdmi->base + SUN4I_HDMI_DDC_FIFO_CTRL_REG);
+ reg |= SUN4I_HDMI_DDC_FIFO_CTRL_CLEAR;
+ reg &= ~SUN4I_HDMI_DDC_FIFO_CTRL_RX_THRES_MASK;
+ reg |= SUN4I_HDMI_DDC_FIFO_CTRL_RX_THRES(RX_THRESHOLD);
+ reg &= ~SUN4I_HDMI_DDC_FIFO_CTRL_TX_THRES_MASK;
+ reg |= SUN4I_HDMI_DDC_FIFO_CTRL_TX_THRES(TX_THRESHOLD);
+ writel(reg, hdmi->base + SUN4I_HDMI_DDC_FIFO_CTRL_REG);
+ if (readl_poll_timeout(hdmi->base + SUN4I_HDMI_DDC_FIFO_CTRL_REG,
+ reg,
+ !(reg & SUN4I_HDMI_DDC_FIFO_CTRL_CLEAR),
+ 100, 2000))
+ return -EIO;
+
+ /* Set transfer length */
+ writel(msg->len, hdmi->base + SUN4I_HDMI_DDC_BYTE_COUNT_REG);
+
+ /* Set command */
+ writel(msg->flags & I2C_M_RD ?
+ SUN4I_HDMI_DDC_CMD_IMPLICIT_READ :
+ SUN4I_HDMI_DDC_CMD_IMPLICIT_WRITE,
+ hdmi->base + SUN4I_HDMI_DDC_CMD_REG);
+
+ /* Clear interrupt status bits */
+ writel(SUN4I_HDMI_DDC_INT_STATUS_ERROR_MASK |
+ SUN4I_HDMI_DDC_INT_STATUS_FIFO_REQUEST |
+ SUN4I_HDMI_DDC_INT_STATUS_TRANSFER_COMPLETE,
+ hdmi->base + SUN4I_HDMI_DDC_INT_STATUS_REG);
+
+ /* Start command */
+ reg = readl(hdmi->base + SUN4I_HDMI_DDC_CTRL_REG);
+ writel(reg | SUN4I_HDMI_DDC_CTRL_START_CMD,
+ hdmi->base + SUN4I_HDMI_DDC_CTRL_REG);
+
+ /* Transfer bytes */
+ for (i = 0; i < msg->len; i += len) {
+ len = fifo_transfer(hdmi, msg->buf + i, msg->len - i,
+ msg->flags & I2C_M_RD);
+ if (len <= 0)
+ return len;
+ }
+
+ /* Wait for command to finish */
+ if (readl_poll_timeout(hdmi->base + SUN4I_HDMI_DDC_CTRL_REG,
+ reg,
+ !(reg & SUN4I_HDMI_DDC_CTRL_START_CMD),
+ 100, 100000))
+ return -EIO;
+
+ /* Check for errors */
+ reg = readl(hdmi->base + SUN4I_HDMI_DDC_INT_STATUS_REG);
+ if ((reg & SUN4I_HDMI_DDC_INT_STATUS_ERROR_MASK) ||
+ !(reg & SUN4I_HDMI_DDC_INT_STATUS_TRANSFER_COMPLETE)) {
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int sun4i_hdmi_i2c_xfer(struct i2c_adapter *adap,
+ struct i2c_msg *msgs, int num)
+{
+ struct sun4i_hdmi *hdmi = i2c_get_adapdata(adap);
+ u32 reg;
+ int err, i, ret = num;
+
+ for (i = 0; i < num; i++) {
+ if (!msgs[i].len)
+ return -EINVAL;
+ if (msgs[i].len > SUN4I_HDMI_DDC_BYTE_COUNT_MAX)
+ return -EINVAL;
+ }
+
+ /* Reset I2C controller */
+ writel(SUN4I_HDMI_DDC_CTRL_ENABLE | SUN4I_HDMI_DDC_CTRL_RESET,
+ hdmi->base + SUN4I_HDMI_DDC_CTRL_REG);
+ if (readl_poll_timeout(hdmi->base + SUN4I_HDMI_DDC_CTRL_REG, reg,
+ !(reg & SUN4I_HDMI_DDC_CTRL_RESET),
+ 100, 2000))
+ return -EIO;
+
+ writel(SUN4I_HDMI_DDC_LINE_CTRL_SDA_ENABLE |
+ SUN4I_HDMI_DDC_LINE_CTRL_SCL_ENABLE,
+ hdmi->base + SUN4I_HDMI_DDC_LINE_CTRL_REG);
+
+ clk_prepare_enable(hdmi->ddc_clk);
+ clk_set_rate(hdmi->ddc_clk, 100000);
+
+ for (i = 0; i < num; i++) {
+ err = xfer_msg(hdmi, &msgs[i]);
+ if (err) {
+ ret = err;
+ break;
+ }
+ }
+
+ clk_disable_unprepare(hdmi->ddc_clk);
+ return ret;
+}
+
+static u32 sun4i_hdmi_i2c_func(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm sun4i_hdmi_i2c_algorithm = {
+ .master_xfer = sun4i_hdmi_i2c_xfer,
+ .functionality = sun4i_hdmi_i2c_func,
+};
+
+int sun4i_hdmi_i2c_create(struct device *dev, struct sun4i_hdmi *hdmi)
+{
+ struct i2c_adapter *adap;
+ int ret = 0;
+
+ ret = sun4i_ddc_create(hdmi, hdmi->tmds_clk);
+ if (ret)
+ return ret;
+
+ adap = devm_kzalloc(dev, sizeof(*adap), GFP_KERNEL);
+ if (!adap)
+ return -ENOMEM;
+
+ adap->owner = THIS_MODULE;
+ adap->class = I2C_CLASS_DDC;
+ adap->algo = &sun4i_hdmi_i2c_algorithm;
+ strlcpy(adap->name, "sun4i_hdmi_i2c adapter", sizeof(adap->name));
+ i2c_set_adapdata(adap, hdmi);
+
+ ret = i2c_add_adapter(adap);
+ if (ret)
+ return ret;
+
+ hdmi->i2c = adap;
+
+ return ret;
+}
diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c
index ead4f9d..7bddf12 100644
--- a/drivers/gpu/drm/sun4i/sun4i_layer.c
+++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
@@ -25,12 +25,6 @@ struct sun4i_plane_desc {
uint32_t nformats;
};
-static int sun4i_backend_layer_atomic_check(struct drm_plane *plane,
- struct drm_plane_state *state)
-{
- return 0;
-}
-
static void sun4i_backend_layer_atomic_disable(struct drm_plane *plane,
struct drm_plane_state *old_state)
{
@@ -52,8 +46,7 @@ static void sun4i_backend_layer_atomic_update(struct drm_plane *plane,
sun4i_backend_layer_enable(backend, layer->id, true);
}
-static struct drm_plane_helper_funcs sun4i_backend_layer_helper_funcs = {
- .atomic_check = sun4i_backend_layer_atomic_check,
+static const struct drm_plane_helper_funcs sun4i_backend_layer_helper_funcs = {
.atomic_disable = sun4i_backend_layer_atomic_disable,
.atomic_update = sun4i_backend_layer_atomic_update,
};
@@ -115,7 +108,7 @@ static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm,
ret = drm_universal_plane_init(drm, &layer->plane, 0,
&sun4i_backend_layer_funcs,
plane->formats, plane->nformats,
- plane->type, NULL);
+ NULL, plane->type, NULL);
if (ret) {
dev_err(drm->dev, "Couldn't initialize layer\n");
return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/sun4i/sun4i_rgb.c b/drivers/gpu/drm/sun4i/sun4i_rgb.c
index 422b191..7cd7090 100644
--- a/drivers/gpu/drm/sun4i/sun4i_rgb.c
+++ b/drivers/gpu/drm/sun4i/sun4i_rgb.c
@@ -119,8 +119,7 @@ sun4i_rgb_connector_destroy(struct drm_connector *connector)
drm_connector_cleanup(connector);
}
-static struct drm_connector_funcs sun4i_rgb_con_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
+static const struct drm_connector_funcs sun4i_rgb_con_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = sun4i_rgb_connector_destroy,
.reset = drm_atomic_helper_connector_reset,
@@ -128,13 +127,6 @@ static struct drm_connector_funcs sun4i_rgb_con_funcs = {
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
-static int sun4i_rgb_atomic_check(struct drm_encoder *encoder,
- struct drm_crtc_state *crtc_state,
- struct drm_connector_state *conn_state)
-{
- return 0;
-}
-
static void sun4i_rgb_encoder_enable(struct drm_encoder *encoder)
{
struct sun4i_rgb *rgb = drm_encoder_to_sun4i_rgb(encoder);
@@ -182,7 +174,6 @@ static void sun4i_rgb_encoder_mode_set(struct drm_encoder *encoder,
}
static struct drm_encoder_helper_funcs sun4i_rgb_enc_helper_funcs = {
- .atomic_check = sun4i_rgb_atomic_check,
.mode_set = sun4i_rgb_encoder_mode_set,
.disable = sun4i_rgb_encoder_disable,
.enable = sun4i_rgb_encoder_enable,
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h
index e3c50ec..552c88e 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
@@ -194,8 +194,6 @@ void sun4i_tcon_channel_enable(struct sun4i_tcon *tcon, int channel);
void sun4i_tcon_enable_vblank(struct sun4i_tcon *tcon, bool enable);
/* Mode Related Controls */
-void sun4i_tcon_switch_interlace(struct sun4i_tcon *tcon,
- bool enable);
void sun4i_tcon_set_mux(struct sun4i_tcon *tcon, int channel,
struct drm_encoder *encoder);
void sun4i_tcon0_mode_set(struct sun4i_tcon *tcon,
diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c
index 338b9e5..050cfd4 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
@@ -341,13 +341,6 @@ static void sun4i_tv_mode_to_drm_mode(const struct tv_mode *tv_mode,
mode->vtotal = mode->vsync_end + tv_mode->vback_porch;
}
-static int sun4i_tv_atomic_check(struct drm_encoder *encoder,
- struct drm_crtc_state *crtc_state,
- struct drm_connector_state *conn_state)
-{
- return 0;
-}
-
static void sun4i_tv_disable(struct drm_encoder *encoder)
{
struct sun4i_tv *tv = drm_encoder_to_sun4i_tv(encoder);
@@ -489,7 +482,6 @@ static void sun4i_tv_mode_set(struct drm_encoder *encoder,
}
static struct drm_encoder_helper_funcs sun4i_tv_helper_funcs = {
- .atomic_check = sun4i_tv_atomic_check,
.disable = sun4i_tv_disable,
.enable = sun4i_tv_enable,
.mode_set = sun4i_tv_mode_set,
@@ -545,8 +537,7 @@ sun4i_tv_comp_connector_destroy(struct drm_connector *connector)
drm_connector_cleanup(connector);
}
-static struct drm_connector_funcs sun4i_tv_comp_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
+static const struct drm_connector_funcs sun4i_tv_comp_connector_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = sun4i_tv_comp_connector_destroy,
.reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/sun4i/sun8i_layer.c b/drivers/gpu/drm/sun4i/sun8i_layer.c
index e627eee..23810ff 100644
--- a/drivers/gpu/drm/sun4i/sun8i_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_layer.c
@@ -90,7 +90,7 @@ static struct sun8i_layer *sun8i_layer_init_one(struct drm_device *drm,
ret = drm_universal_plane_init(drm, &layer->plane, 0,
&sun8i_mixer_layer_funcs,
plane->formats, plane->nformats,
- plane->type, NULL);
+ NULL, plane->type, NULL);
if (ret) {
dev_err(drm->dev, "Couldn't initialize layer\n");
return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/tdfx/tdfx_drv.c b/drivers/gpu/drm/tdfx/tdfx_drv.c
index c54138c..3a14768 100644
--- a/drivers/gpu/drm/tdfx/tdfx_drv.c
+++ b/drivers/gpu/drm/tdfx/tdfx_drv.c
@@ -55,7 +55,6 @@ static const struct file_operations tdfx_driver_fops = {
static struct drm_driver driver = {
.driver_features = DRIVER_LEGACY,
- .set_busid = drm_pci_set_busid,
.fops = &tdfx_driver_fops,
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
@@ -72,12 +71,12 @@ static struct pci_driver tdfx_pci_driver = {
static int __init tdfx_init(void)
{
- return drm_pci_init(&driver, &tdfx_pci_driver);
+ return drm_legacy_pci_init(&driver, &tdfx_pci_driver);
}
static void __exit tdfx_exit(void)
{
- drm_pci_exit(&driver, &tdfx_pci_driver);
+ drm_legacy_pci_exit(&driver, &tdfx_pci_driver);
}
module_init(tdfx_init);
diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig
index 2db29d6..dc58ab1 100644
--- a/drivers/gpu/drm/tegra/Kconfig
+++ b/drivers/gpu/drm/tegra/Kconfig
@@ -3,6 +3,7 @@ config DRM_TEGRA
depends on ARCH_TEGRA || (ARM && COMPILE_TEST)
depends on COMMON_CLK
depends on DRM
+ depends on OF
select DRM_KMS_HELPER
select DRM_MIPI_DSI
select DRM_PANEL
diff --git a/drivers/gpu/drm/tegra/Makefile b/drivers/gpu/drm/tegra/Makefile
index 6af3a9a..8927784 100644
--- a/drivers/gpu/drm/tegra/Makefile
+++ b/drivers/gpu/drm/tegra/Makefile
@@ -17,4 +17,6 @@ tegra-drm-y := \
falcon.o \
vic.o
+tegra-drm-y += trace.o
+
obj-$(CONFIG_DRM_TEGRA) += tegra-drm.o
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index c875f11..4df3911 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -678,8 +678,8 @@ static struct drm_plane *tegra_dc_primary_plane_create(struct drm_device *drm,
err = drm_universal_plane_init(drm, &plane->base, possible_crtcs,
&tegra_primary_plane_funcs, formats,
- num_formats, DRM_PLANE_TYPE_PRIMARY,
- NULL);
+ num_formats, NULL,
+ DRM_PLANE_TYPE_PRIMARY, NULL);
if (err < 0) {
kfree(plane);
return ERR_PTR(err);
@@ -844,8 +844,8 @@ static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm,
err = drm_universal_plane_init(drm, &plane->base, 1 << dc->pipe,
&tegra_cursor_plane_funcs, formats,
- num_formats, DRM_PLANE_TYPE_CURSOR,
- NULL);
+ num_formats, NULL,
+ DRM_PLANE_TYPE_CURSOR, NULL);
if (err < 0) {
kfree(plane);
return ERR_PTR(err);
@@ -906,8 +906,8 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
err = drm_universal_plane_init(drm, &plane->base, 1 << dc->pipe,
&tegra_overlay_plane_funcs, formats,
- num_formats, DRM_PLANE_TYPE_OVERLAY,
- NULL);
+ num_formats, NULL,
+ DRM_PLANE_TYPE_OVERLAY, NULL);
if (err < 0) {
kfree(plane);
return ERR_PTR(err);
@@ -1199,7 +1199,8 @@ static int tegra_dc_wait_idle(struct tegra_dc *dc, unsigned long timeout)
return -ETIMEDOUT;
}
-static void tegra_crtc_disable(struct drm_crtc *crtc)
+static void tegra_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct tegra_dc *dc = to_tegra_dc(crtc);
u32 value;
@@ -1243,7 +1244,8 @@ static void tegra_crtc_disable(struct drm_crtc *crtc)
pm_runtime_put_sync(dc->dev);
}
-static void tegra_crtc_enable(struct drm_crtc *crtc)
+static void tegra_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct drm_display_mode *mode = &crtc->state->adjusted_mode;
struct tegra_dc_state *state = to_dc_state(crtc->state);
@@ -1351,11 +1353,11 @@ static void tegra_crtc_atomic_flush(struct drm_crtc *crtc,
}
static const struct drm_crtc_helper_funcs tegra_crtc_helper_funcs = {
- .disable = tegra_crtc_disable,
- .enable = tegra_crtc_enable,
.atomic_check = tegra_crtc_atomic_check,
.atomic_begin = tegra_crtc_atomic_begin,
.atomic_flush = tegra_crtc_atomic_flush,
+ .atomic_enable = tegra_crtc_atomic_enable,
+ .atomic_disable = tegra_crtc_atomic_disable,
};
static irqreturn_t tegra_dc_irq(int irq, void *data)
diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c
index 2fde44c..e4da041 100644
--- a/drivers/gpu/drm/tegra/dpaux.c
+++ b/drivers/gpu/drm/tegra/dpaux.c
@@ -25,6 +25,7 @@
#include "dpaux.h"
#include "drm.h"
+#include "trace.h"
static DEFINE_MUTEX(dpaux_lock);
static LIST_HEAD(dpaux_list);
@@ -65,14 +66,19 @@ static inline struct tegra_dpaux *work_to_dpaux(struct work_struct *work)
}
static inline u32 tegra_dpaux_readl(struct tegra_dpaux *dpaux,
- unsigned long offset)
+ unsigned int offset)
{
- return readl(dpaux->regs + (offset << 2));
+ u32 value = readl(dpaux->regs + (offset << 2));
+
+ trace_dpaux_readl(dpaux->dev, offset, value);
+
+ return value;
}
static inline void tegra_dpaux_writel(struct tegra_dpaux *dpaux,
- u32 value, unsigned long offset)
+ u32 value, unsigned int offset)
{
+ trace_dpaux_writel(dpaux->dev, offset, value);
writel(value, dpaux->regs + (offset << 2));
}
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 518f4b6..597d563 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -100,7 +100,12 @@ static int tegra_atomic_commit(struct drm_device *drm,
* the software side now.
*/
- drm_atomic_helper_swap_state(state, true);
+ err = drm_atomic_helper_swap_state(state, true);
+ if (err) {
+ mutex_unlock(&tegra->commit.lock);
+ drm_atomic_helper_cleanup_planes(drm, state);
+ return err;
+ }
drm_atomic_state_get(state);
if (nonblock)
@@ -214,12 +219,10 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
err = tegra_drm_fb_init(drm);
if (err < 0)
- goto vblank;
+ goto device;
return 0;
-vblank:
- drm_vblank_cleanup(drm);
device:
host1x_device_exit(device);
fbdev:
@@ -248,7 +251,6 @@ static void tegra_drm_unload(struct drm_device *drm)
drm_kms_helper_poll_fini(drm);
tegra_drm_fb_exit(drm);
drm_mode_config_cleanup(drm);
- drm_vblank_cleanup(drm);
err = host1x_device_exit(device);
if (err < 0)
@@ -304,8 +306,6 @@ host1x_bo_lookup(struct drm_file *file, u32 handle)
if (!gem)
return NULL;
- drm_gem_object_unreference_unlocked(gem);
-
bo = to_tegra_bo(gem);
return &bo->base;
}
@@ -394,8 +394,10 @@ int tegra_drm_submit(struct tegra_drm_context *context,
(void __user *)(uintptr_t)args->waitchks;
struct drm_tegra_syncpt syncpt;
struct host1x *host1x = dev_get_drvdata(drm->dev->parent);
+ struct drm_gem_object **refs;
struct host1x_syncpt *sp;
struct host1x_job *job;
+ unsigned int num_refs;
int err;
/* We don't yet support other than one syncpt_incr struct per submit */
@@ -417,6 +419,21 @@ int tegra_drm_submit(struct tegra_drm_context *context,
job->class = context->client->base.class;
job->serialize = true;
+ /*
+ * Track referenced BOs so that they can be unreferenced after the
+ * submission is complete.
+ */
+ num_refs = num_cmdbufs + num_relocs * 2 + num_waitchks;
+
+ refs = kmalloc_array(num_refs, sizeof(*refs), GFP_KERNEL);
+ if (!refs) {
+ err = -ENOMEM;
+ goto put;
+ }
+
+ /* reuse as an iterator later */
+ num_refs = 0;
+
while (num_cmdbufs) {
struct drm_tegra_cmdbuf cmdbuf;
struct host1x_bo *bo;
@@ -445,6 +462,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
offset = (u64)cmdbuf.offset + (u64)cmdbuf.words * sizeof(u32);
obj = host1x_to_tegra_bo(bo);
+ refs[num_refs++] = &obj->gem;
/*
* Gather buffer base address must be 4-bytes aligned,
@@ -474,6 +492,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
reloc = &job->relocarray[num_relocs];
obj = host1x_to_tegra_bo(reloc->cmdbuf.bo);
+ refs[num_refs++] = &obj->gem;
/*
* The unaligned cmdbuf offset will cause an unaligned write
@@ -487,6 +506,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
}
obj = host1x_to_tegra_bo(reloc->target.bo);
+ refs[num_refs++] = &obj->gem;
if (reloc->target.offset >= obj->gem.size) {
err = -EINVAL;
@@ -506,6 +526,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
goto fail;
obj = host1x_to_tegra_bo(wait->bo);
+ refs[num_refs++] = &obj->gem;
/*
* The unaligned offset will cause an unaligned write during
@@ -545,17 +566,20 @@ int tegra_drm_submit(struct tegra_drm_context *context,
goto fail;
err = host1x_job_submit(job);
- if (err)
- goto fail_submit;
+ if (err) {
+ host1x_job_unpin(job);
+ goto fail;
+ }
args->fence = job->syncpt_end;
- host1x_job_put(job);
- return 0;
-
-fail_submit:
- host1x_job_unpin(job);
fail:
+ while (num_refs--)
+ drm_gem_object_put_unlocked(refs[num_refs]);
+
+ kfree(refs);
+
+put:
host1x_job_put(job);
return err;
}
@@ -591,7 +615,7 @@ static int tegra_gem_mmap(struct drm_device *drm, void *data,
args->offset = drm_vma_node_offset_addr(&bo->gem.vma_node);
- drm_gem_object_unreference_unlocked(gem);
+ drm_gem_object_put_unlocked(gem);
return 0;
}
@@ -858,7 +882,7 @@ static int tegra_gem_set_tiling(struct drm_device *drm, void *data,
bo->tiling.mode = mode;
bo->tiling.value = value;
- drm_gem_object_unreference_unlocked(gem);
+ drm_gem_object_put_unlocked(gem);
return 0;
}
@@ -898,7 +922,7 @@ static int tegra_gem_get_tiling(struct drm_device *drm, void *data,
break;
}
- drm_gem_object_unreference_unlocked(gem);
+ drm_gem_object_put_unlocked(gem);
return err;
}
@@ -923,7 +947,7 @@ static int tegra_gem_set_flags(struct drm_device *drm, void *data,
if (args->flags & DRM_TEGRA_GEM_BOTTOM_UP)
bo->flags |= TEGRA_BO_BOTTOM_UP;
- drm_gem_object_unreference_unlocked(gem);
+ drm_gem_object_put_unlocked(gem);
return 0;
}
@@ -945,7 +969,7 @@ static int tegra_gem_get_flags(struct drm_device *drm, void *data,
if (bo->flags & TEGRA_BO_BOTTOM_UP)
args->flags |= DRM_TEGRA_GEM_BOTTOM_UP;
- drm_gem_object_unreference_unlocked(gem);
+ drm_gem_object_put_unlocked(gem);
return 0;
}
@@ -953,20 +977,34 @@ static int tegra_gem_get_flags(struct drm_device *drm, void *data,
static const struct drm_ioctl_desc tegra_drm_ioctls[] = {
#ifdef CONFIG_DRM_TEGRA_STAGING
- DRM_IOCTL_DEF_DRV(TEGRA_GEM_CREATE, tegra_gem_create, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_GEM_MMAP, tegra_gem_mmap, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_READ, tegra_syncpt_read, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_INCR, tegra_syncpt_incr, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_WAIT, tegra_syncpt_wait, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_OPEN_CHANNEL, tegra_open_channel, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_CLOSE_CHANNEL, tegra_close_channel, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_GET_SYNCPT, tegra_get_syncpt, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_SUBMIT, tegra_submit, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_GET_SYNCPT_BASE, tegra_get_syncpt_base, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_GEM_SET_TILING, tegra_gem_set_tiling, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_GEM_GET_TILING, tegra_gem_get_tiling, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_GEM_SET_FLAGS, tegra_gem_set_flags, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_GEM_GET_FLAGS, tegra_gem_get_flags, 0),
+ DRM_IOCTL_DEF_DRV(TEGRA_GEM_CREATE, tegra_gem_create,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_GEM_MMAP, tegra_gem_mmap,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_READ, tegra_syncpt_read,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_INCR, tegra_syncpt_incr,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_WAIT, tegra_syncpt_wait,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_OPEN_CHANNEL, tegra_open_channel,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_CLOSE_CHANNEL, tegra_close_channel,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_GET_SYNCPT, tegra_get_syncpt,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_SUBMIT, tegra_submit,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_GET_SYNCPT_BASE, tegra_get_syncpt_base,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_GEM_SET_TILING, tegra_gem_set_tiling,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_GEM_GET_TILING, tegra_gem_get_tiling,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_GEM_SET_FLAGS, tegra_gem_set_flags,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_GEM_GET_FLAGS, tegra_gem_get_flags,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
#endif
};
@@ -1033,9 +1071,11 @@ static int tegra_debugfs_iova(struct seq_file *s, void *data)
struct tegra_drm *tegra = drm->dev_private;
struct drm_printer p = drm_seq_file_printer(s);
- mutex_lock(&tegra->mm_lock);
- drm_mm_print(&tegra->mm, &p);
- mutex_unlock(&tegra->mm_lock);
+ if (tegra->domain) {
+ mutex_lock(&tegra->mm_lock);
+ drm_mm_print(&tegra->mm, &p);
+ mutex_unlock(&tegra->mm_lock);
+ }
return 0;
}
@@ -1055,7 +1095,7 @@ static int tegra_debugfs_init(struct drm_minor *minor)
static struct drm_driver tegra_drm_driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
- DRIVER_ATOMIC,
+ DRIVER_ATOMIC | DRIVER_RENDER,
.load = tegra_drm_load,
.unload = tegra_drm_unload,
.open = tegra_drm_open,
@@ -1075,8 +1115,6 @@ static struct drm_driver tegra_drm_driver = {
.gem_prime_import = tegra_gem_prime_import,
.dumb_create = tegra_bo_dumb_create,
- .dumb_map_offset = tegra_bo_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.ioctls = tegra_drm_ioctls,
.num_ioctls = ARRAY_SIZE(tegra_drm_ioctls),
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
index 6d6da01..063f5d3 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/drm/tegra/drm.h
@@ -23,6 +23,7 @@
#include <drm/drm_fixed.h>
#include "gem.h"
+#include "trace.h"
struct reset_control;
@@ -172,14 +173,19 @@ static inline struct tegra_dc *to_tegra_dc(struct drm_crtc *crtc)
}
static inline void tegra_dc_writel(struct tegra_dc *dc, u32 value,
- unsigned long offset)
+ unsigned int offset)
{
+ trace_dc_writel(dc->dev, offset, value);
writel(value, dc->regs + (offset << 2));
}
-static inline u32 tegra_dc_readl(struct tegra_dc *dc, unsigned long offset)
+static inline u32 tegra_dc_readl(struct tegra_dc *dc, unsigned int offset)
{
- return readl(dc->regs + (offset << 2));
+ u32 value = readl(dc->regs + (offset << 2));
+
+ trace_dc_readl(dc->dev, offset, value);
+
+ return value;
}
struct tegra_dc_window {
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
index 3dea121..046649e 100644
--- a/drivers/gpu/drm/tegra/dsi.c
+++ b/drivers/gpu/drm/tegra/dsi.c
@@ -28,6 +28,7 @@
#include "drm.h"
#include "dsi.h"
#include "mipi-phy.h"
+#include "trace.h"
struct tegra_dsi_state {
struct drm_connector_state base;
@@ -105,15 +106,20 @@ static struct tegra_dsi_state *tegra_dsi_get_state(struct tegra_dsi *dsi)
return to_dsi_state(dsi->output.connector.state);
}
-static inline u32 tegra_dsi_readl(struct tegra_dsi *dsi, unsigned long reg)
+static inline u32 tegra_dsi_readl(struct tegra_dsi *dsi, unsigned int offset)
{
- return readl(dsi->regs + (reg << 2));
+ u32 value = readl(dsi->regs + (offset << 2));
+
+ trace_dsi_readl(dsi->dev, offset, value);
+
+ return value;
}
static inline void tegra_dsi_writel(struct tegra_dsi *dsi, u32 value,
- unsigned long reg)
+ unsigned int offset)
{
- writel(value, dsi->regs + (reg << 2));
+ trace_dsi_writel(dsi->dev, offset, value);
+ writel(value, dsi->regs + (offset << 2));
}
static int tegra_dsi_show_regs(struct seq_file *s, void *data)
@@ -815,7 +821,6 @@ tegra_dsi_connector_duplicate_state(struct drm_connector *connector)
}
static const struct drm_connector_funcs tegra_dsi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.reset = tegra_dsi_connector_reset,
.detect = tegra_output_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c
index 25acb73..80540c1 100644
--- a/drivers/gpu/drm/tegra/fb.c
+++ b/drivers/gpu/drm/tegra/fb.c
@@ -88,7 +88,7 @@ static void tegra_fb_destroy(struct drm_framebuffer *framebuffer)
if (bo->pages)
vunmap(bo->vaddr);
- drm_gem_object_unreference_unlocked(&bo->gem);
+ drm_gem_object_put_unlocked(&bo->gem);
}
}
@@ -195,7 +195,7 @@ struct drm_framebuffer *tegra_fb_create(struct drm_device *drm,
unreference:
while (i--)
- drm_gem_object_unreference_unlocked(&planes[i]->gem);
+ drm_gem_object_put_unlocked(&planes[i]->gem);
return ERR_PTR(err);
}
@@ -242,7 +242,7 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper,
info = drm_fb_helper_alloc_fbi(helper);
if (IS_ERR(info)) {
dev_err(drm->dev, "failed to allocate framebuffer info\n");
- drm_gem_object_unreference_unlocked(&bo->gem);
+ drm_gem_object_put_unlocked(&bo->gem);
return PTR_ERR(info);
}
@@ -251,7 +251,7 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper,
err = PTR_ERR(fbdev->fb);
dev_err(drm->dev, "failed to allocate DRM framebuffer: %d\n",
err);
- drm_gem_object_unreference_unlocked(&bo->gem);
+ drm_gem_object_put_unlocked(&bo->gem);
return PTR_ERR(fbdev->fb);
}
diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index 7a39a35..ab1e53d 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -24,7 +24,7 @@ static void tegra_bo_put(struct host1x_bo *bo)
{
struct tegra_bo *obj = host1x_to_tegra_bo(bo);
- drm_gem_object_unreference_unlocked(&obj->gem);
+ drm_gem_object_put_unlocked(&obj->gem);
}
static dma_addr_t tegra_bo_pin(struct host1x_bo *bo, struct sg_table **sgt)
@@ -95,7 +95,7 @@ static struct host1x_bo *tegra_bo_get(struct host1x_bo *bo)
{
struct tegra_bo *obj = host1x_to_tegra_bo(bo);
- drm_gem_object_reference(&obj->gem);
+ drm_gem_object_get(&obj->gem);
return bo;
}
@@ -325,7 +325,7 @@ struct tegra_bo *tegra_bo_create_with_handle(struct drm_file *file,
return ERR_PTR(err);
}
- drm_gem_object_unreference_unlocked(&bo->gem);
+ drm_gem_object_put_unlocked(&bo->gem);
return bo;
}
@@ -423,27 +423,6 @@ int tegra_bo_dumb_create(struct drm_file *file, struct drm_device *drm,
return 0;
}
-int tegra_bo_dumb_map_offset(struct drm_file *file, struct drm_device *drm,
- u32 handle, u64 *offset)
-{
- struct drm_gem_object *gem;
- struct tegra_bo *bo;
-
- gem = drm_gem_object_lookup(file, handle);
- if (!gem) {
- dev_err(drm->dev, "failed to lookup GEM object\n");
- return -EINVAL;
- }
-
- bo = to_tegra_bo(gem);
-
- *offset = drm_vma_node_offset_addr(&bo->gem.vma_node);
-
- drm_gem_object_unreference_unlocked(gem);
-
- return 0;
-}
-
static int tegra_bo_fault(struct vm_fault *vmf)
{
struct vm_area_struct *vma = vmf->vma;
@@ -481,30 +460,28 @@ const struct vm_operations_struct tegra_bo_vm_ops = {
.close = drm_gem_vm_close,
};
-int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma)
+static int tegra_gem_mmap(struct drm_gem_object *gem,
+ struct vm_area_struct *vma)
{
- struct drm_gem_object *gem;
- struct tegra_bo *bo;
- int ret;
-
- ret = drm_gem_mmap(file, vma);
- if (ret)
- return ret;
-
- gem = vma->vm_private_data;
- bo = to_tegra_bo(gem);
+ struct tegra_bo *bo = to_tegra_bo(gem);
if (!bo->pages) {
unsigned long vm_pgoff = vma->vm_pgoff;
+ int err;
+ /*
+ * Clear the VM_PFNMAP flag that was set by drm_gem_mmap(),
+ * and set the vm_pgoff (used as a fake buffer offset by DRM)
+ * to 0 as we want to map the whole buffer.
+ */
vma->vm_flags &= ~VM_PFNMAP;
vma->vm_pgoff = 0;
- ret = dma_mmap_wc(gem->dev->dev, vma, bo->vaddr, bo->paddr,
+ err = dma_mmap_wc(gem->dev->dev, vma, bo->vaddr, bo->paddr,
gem->size);
- if (ret) {
+ if (err < 0) {
drm_gem_vm_close(vma);
- return ret;
+ return err;
}
vma->vm_pgoff = vm_pgoff;
@@ -520,6 +497,20 @@ int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma)
return 0;
}
+int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct drm_gem_object *gem;
+ int err;
+
+ err = drm_gem_mmap(file, vma);
+ if (err < 0)
+ return err;
+
+ gem = vma->vm_private_data;
+
+ return tegra_gem_mmap(gem, vma);
+}
+
static struct sg_table *
tegra_gem_prime_map_dma_buf(struct dma_buf_attachment *attach,
enum dma_data_direction dir)
@@ -603,7 +594,14 @@ static void tegra_gem_prime_kunmap(struct dma_buf *buf, unsigned long page,
static int tegra_gem_prime_mmap(struct dma_buf *buf, struct vm_area_struct *vma)
{
- return -EINVAL;
+ struct drm_gem_object *gem = buf->priv;
+ int err;
+
+ err = drm_gem_mmap_obj(gem, gem->size, vma);
+ if (err < 0)
+ return err;
+
+ return tegra_gem_mmap(gem, vma);
}
static void *tegra_gem_prime_vmap(struct dma_buf *buf)
@@ -654,7 +652,7 @@ struct drm_gem_object *tegra_gem_prime_import(struct drm_device *drm,
struct drm_gem_object *gem = buf->priv;
if (gem->dev == drm) {
- drm_gem_object_reference(gem);
+ drm_gem_object_get(gem);
return gem;
}
}
diff --git a/drivers/gpu/drm/tegra/gem.h b/drivers/gpu/drm/tegra/gem.h
index 8b32a6f..8eb9fd2 100644
--- a/drivers/gpu/drm/tegra/gem.h
+++ b/drivers/gpu/drm/tegra/gem.h
@@ -67,8 +67,6 @@ struct tegra_bo *tegra_bo_create_with_handle(struct drm_file *file,
void tegra_bo_free_object(struct drm_gem_object *gem);
int tegra_bo_dumb_create(struct drm_file *file, struct drm_device *drm,
struct drm_mode_create_dumb *args);
-int tegra_bo_dumb_map_offset(struct drm_file *file, struct drm_device *drm,
- u32 handle, u64 *offset);
int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma);
diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c
index cda0491..5b9d83b 100644
--- a/drivers/gpu/drm/tegra/hdmi.c
+++ b/drivers/gpu/drm/tegra/hdmi.c
@@ -24,6 +24,7 @@
#include "hdmi.h"
#include "drm.h"
#include "dc.h"
+#include "trace.h"
#define HDMI_ELD_BUFFER_SIZE 96
@@ -100,14 +101,19 @@ enum {
};
static inline u32 tegra_hdmi_readl(struct tegra_hdmi *hdmi,
- unsigned long offset)
+ unsigned int offset)
{
- return readl(hdmi->regs + (offset << 2));
+ u32 value = readl(hdmi->regs + (offset << 2));
+
+ trace_hdmi_readl(hdmi->dev, offset, value);
+
+ return value;
}
static inline void tegra_hdmi_writel(struct tegra_hdmi *hdmi, u32 value,
- unsigned long offset)
+ unsigned int offset)
{
+ trace_hdmi_writel(hdmi->dev, offset, value);
writel(value, hdmi->regs + (offset << 2));
}
@@ -734,7 +740,7 @@ static void tegra_hdmi_setup_avi_infoframe(struct tegra_hdmi *hdmi,
u8 buffer[17];
ssize_t err;
- err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+ err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
if (err < 0) {
dev_err(hdmi->dev, "failed to setup AVI infoframe: %zd\n", err);
return;
@@ -902,7 +908,6 @@ tegra_hdmi_connector_detect(struct drm_connector *connector, bool force)
}
static const struct drm_connector_funcs tegra_hdmi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.reset = drm_atomic_helper_connector_reset,
.detect = tegra_hdmi_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c
index a131b44..78ec519 100644
--- a/drivers/gpu/drm/tegra/rgb.c
+++ b/drivers/gpu/drm/tegra/rgb.c
@@ -88,7 +88,6 @@ static void tegra_dc_write_regs(struct tegra_dc *dc,
}
static const struct drm_connector_funcs tegra_rgb_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.reset = drm_atomic_helper_connector_reset,
.detect = tegra_output_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index a8f5289..7ab1d1d 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -26,6 +26,7 @@
#include "dc.h"
#include "drm.h"
#include "sor.h"
+#include "trace.h"
#define SOR_REKEY 0x38
@@ -232,14 +233,19 @@ static inline struct tegra_sor *to_sor(struct tegra_output *output)
return container_of(output, struct tegra_sor, output);
}
-static inline u32 tegra_sor_readl(struct tegra_sor *sor, unsigned long offset)
+static inline u32 tegra_sor_readl(struct tegra_sor *sor, unsigned int offset)
{
- return readl(sor->regs + (offset << 2));
+ u32 value = readl(sor->regs + (offset << 2));
+
+ trace_sor_readl(sor->dev, offset, value);
+
+ return value;
}
static inline void tegra_sor_writel(struct tegra_sor *sor, u32 value,
- unsigned long offset)
+ unsigned int offset)
{
+ trace_sor_writel(sor->dev, offset, value);
writel(value, sor->regs + (offset << 2));
}
@@ -1340,7 +1346,6 @@ tegra_sor_connector_duplicate_state(struct drm_connector *connector)
}
static const struct drm_connector_funcs tegra_sor_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.reset = tegra_sor_connector_reset,
.detect = tegra_sor_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
@@ -1904,7 +1909,7 @@ tegra_sor_hdmi_setup_avi_infoframe(struct tegra_sor *sor,
value &= ~INFOFRAME_CTRL_ENABLE;
tegra_sor_writel(sor, value, SOR_HDMI_AVI_INFOFRAME_CTRL);
- err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+ err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
if (err < 0) {
dev_err(sor->dev, "failed to setup AVI infoframe: %d\n", err);
return err;
diff --git a/drivers/gpu/drm/tegra/trace.c b/drivers/gpu/drm/tegra/trace.c
new file mode 100644
index 0000000..006f65c
--- /dev/null
+++ b/drivers/gpu/drm/tegra/trace.c
@@ -0,0 +1,2 @@
+#define CREATE_TRACE_POINTS
+#include "trace.h"
diff --git a/drivers/gpu/drm/tegra/trace.h b/drivers/gpu/drm/tegra/trace.h
new file mode 100644
index 0000000..e9b7cdad
--- /dev/null
+++ b/drivers/gpu/drm/tegra/trace.h
@@ -0,0 +1,68 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM tegra
+
+#if !defined(DRM_TEGRA_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define DRM_TEGRA_TRACE_H 1
+
+#include <linux/device.h>
+#include <linux/tracepoint.h>
+
+DECLARE_EVENT_CLASS(register_access,
+ TP_PROTO(struct device *dev, unsigned int offset, u32 value),
+ TP_ARGS(dev, offset, value),
+ TP_STRUCT__entry(
+ __field(struct device *, dev)
+ __field(unsigned int, offset)
+ __field(u32, value)
+ ),
+ TP_fast_assign(
+ __entry->dev = dev;
+ __entry->offset = offset;
+ __entry->value = value;
+ ),
+ TP_printk("%s %04x %08x", dev_name(__entry->dev), __entry->offset,
+ __entry->value)
+);
+
+DEFINE_EVENT(register_access, dc_writel,
+ TP_PROTO(struct device *dev, unsigned int offset, u32 value),
+ TP_ARGS(dev, offset, value));
+DEFINE_EVENT(register_access, dc_readl,
+ TP_PROTO(struct device *dev, unsigned int offset, u32 value),
+ TP_ARGS(dev, offset, value));
+
+DEFINE_EVENT(register_access, hdmi_writel,
+ TP_PROTO(struct device *dev, unsigned int offset, u32 value),
+ TP_ARGS(dev, offset, value));
+DEFINE_EVENT(register_access, hdmi_readl,
+ TP_PROTO(struct device *dev, unsigned int offset, u32 value),
+ TP_ARGS(dev, offset, value));
+
+DEFINE_EVENT(register_access, dsi_writel,
+ TP_PROTO(struct device *dev, unsigned int offset, u32 value),
+ TP_ARGS(dev, offset, value));
+DEFINE_EVENT(register_access, dsi_readl,
+ TP_PROTO(struct device *dev, unsigned int offset, u32 value),
+ TP_ARGS(dev, offset, value));
+
+DEFINE_EVENT(register_access, dpaux_writel,
+ TP_PROTO(struct device *dev, unsigned int offset, u32 value),
+ TP_ARGS(dev, offset, value));
+DEFINE_EVENT(register_access, dpaux_readl,
+ TP_PROTO(struct device *dev, unsigned int offset, u32 value),
+ TP_ARGS(dev, offset, value));
+
+DEFINE_EVENT(register_access, sor_writel,
+ TP_PROTO(struct device *dev, unsigned int offset, u32 value),
+ TP_ARGS(dev, offset, value));
+DEFINE_EVENT(register_access, sor_readl,
+ TP_PROTO(struct device *dev, unsigned int offset, u32 value),
+ TP_ARGS(dev, offset, value));
+
+#endif /* DRM_TEGRA_TRACE_H */
+
+/* This part must be outside protection */
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE trace
+#include <trace/define_trace.h>
diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c
index 47cb1aa..2448229 100644
--- a/drivers/gpu/drm/tegra/vic.c
+++ b/drivers/gpu/drm/tegra/vic.c
@@ -258,12 +258,16 @@ static const struct tegra_drm_client_ops vic_ops = {
.submit = tegra_drm_submit,
};
+#define NVIDIA_TEGRA_124_VIC_FIRMWARE "nvidia/tegra124/vic03_ucode.bin"
+
static const struct vic_config vic_t124_config = {
- .firmware = "nvidia/tegra124/vic03_ucode.bin",
+ .firmware = NVIDIA_TEGRA_124_VIC_FIRMWARE,
};
+#define NVIDIA_TEGRA_210_VIC_FIRMWARE "nvidia/tegra210/vic04_ucode.bin"
+
static const struct vic_config vic_t210_config = {
- .firmware = "nvidia/tegra210/vic04_ucode.bin",
+ .firmware = NVIDIA_TEGRA_210_VIC_FIRMWARE,
};
static const struct of_device_id vic_match[] = {
@@ -394,3 +398,10 @@ struct platform_driver tegra_vic_driver = {
.probe = vic_probe,
.remove = vic_remove,
};
+
+#if IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC)
+MODULE_FIRMWARE(NVIDIA_TEGRA_124_VIC_FIRMWARE);
+#endif
+#if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC)
+MODULE_FIRMWARE(NVIDIA_TEGRA_210_VIC_FIRMWARE);
+#endif
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index d524ed0..406fe45 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -504,6 +504,12 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc)
mutex_unlock(&tilcdc_crtc->enable_lock);
}
+static void tilcdc_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
+{
+ tilcdc_crtc_enable(crtc);
+}
+
static void tilcdc_crtc_off(struct drm_crtc *crtc, bool shutdown)
{
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
@@ -562,6 +568,12 @@ static void tilcdc_crtc_disable(struct drm_crtc *crtc)
tilcdc_crtc_off(crtc, false);
}
+static void tilcdc_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
+{
+ tilcdc_crtc_disable(crtc);
+}
+
void tilcdc_crtc_shutdown(struct drm_crtc *crtc)
{
tilcdc_crtc_off(crtc, true);
@@ -729,9 +741,9 @@ static const struct drm_crtc_funcs tilcdc_crtc_funcs = {
static const struct drm_crtc_helper_funcs tilcdc_crtc_helper_funcs = {
.mode_fixup = tilcdc_crtc_mode_fixup,
- .enable = tilcdc_crtc_enable,
- .disable = tilcdc_crtc_disable,
.atomic_check = tilcdc_crtc_atomic_check,
+ .atomic_enable = tilcdc_crtc_atomic_enable,
+ .atomic_disable = tilcdc_crtc_atomic_disable,
};
int tilcdc_crtc_max_width(struct drm_crtc *crtc)
@@ -1038,8 +1050,8 @@ int tilcdc_crtc_create(struct drm_device *dev)
if (priv->is_componentized) {
crtc->port = of_graph_get_port_by_id(dev->dev->of_node, 0);
if (!crtc->port) { /* This should never happen */
- dev_err(dev->dev, "Port node not found in %s\n",
- dev->dev->of_node->full_name);
+ dev_err(dev->dev, "Port node not found in %pOF\n",
+ dev->dev->of_node);
ret = -EINVAL;
goto fail;
}
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index d67e189..b0d70f9 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -108,7 +108,11 @@ static int tilcdc_commit(struct drm_device *dev,
if (ret)
return ret;
- drm_atomic_helper_swap_state(state, true);
+ ret = drm_atomic_helper_swap_state(state, true);
+ if (ret) {
+ drm_atomic_helper_cleanup_planes(dev, state);
+ return ret;
+ }
/*
* Everything below can be run asynchronously without the need to grab
@@ -538,8 +542,6 @@ static struct drm_driver tilcdc_driver = {
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
index 28c3e2f..1813a36 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
@@ -189,7 +189,6 @@ static struct drm_encoder *panel_connector_best_encoder(
static const struct drm_connector_funcs panel_connector_funcs = {
.destroy = panel_connector_destroy,
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.reset = drm_atomic_helper_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_plane.c b/drivers/gpu/drm/tilcdc/tilcdc_plane.c
index ba0d66c..7667b03 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_plane.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_plane.c
@@ -28,7 +28,6 @@ static struct drm_plane_funcs tilcdc_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = drm_plane_cleanup,
- .set_property = drm_atomic_helper_plane_set_property,
.reset = drm_atomic_helper_plane_reset,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
index aabfad8..1e2dfb1 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
@@ -202,7 +202,6 @@ static struct drm_encoder *tfp410_connector_best_encoder(
static const struct drm_connector_funcs tfp410_connector_funcs = {
.destroy = tfp410_connector_destroy,
- .dpms = drm_atomic_helper_connector_dpms,
.detect = tfp410_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/tinydrm/Kconfig b/drivers/gpu/drm/tinydrm/Kconfig
index 3504c538..2e790e7 100644
--- a/drivers/gpu/drm/tinydrm/Kconfig
+++ b/drivers/gpu/drm/tinydrm/Kconfig
@@ -19,3 +19,26 @@ config TINYDRM_MI0283QT
help
DRM driver for the Multi-Inno MI0283QT display panel
If M is selected the module will be called mi0283qt.
+
+config TINYDRM_REPAPER
+ tristate "DRM support for Pervasive Displays RePaper panels (V231)"
+ depends on DRM_TINYDRM && SPI
+ depends on THERMAL || !THERMAL
+ help
+ DRM driver for the following Pervasive Displays panels:
+ 1.44" TFT EPD Panel (E1144CS021)
+ 1.90" TFT EPD Panel (E1190CS021)
+ 2.00" TFT EPD Panel (E2200CS021)
+ 2.71" TFT EPD Panel (E2271CS021)
+
+ If M is selected the module will be called repaper.
+
+config TINYDRM_ST7586
+ tristate "DRM support for Sitronix ST7586 display panels"
+ depends on DRM_TINYDRM && SPI
+ select TINYDRM_MIPI_DBI
+ help
+ DRM driver for the following Sitronix ST7586 panels:
+ * LEGO MINDSTORMS EV3
+
+ If M is selected the module will be called st7586.
diff --git a/drivers/gpu/drm/tinydrm/Makefile b/drivers/gpu/drm/tinydrm/Makefile
index 7a3604c..0c184bd 100644
--- a/drivers/gpu/drm/tinydrm/Makefile
+++ b/drivers/gpu/drm/tinydrm/Makefile
@@ -5,3 +5,5 @@ obj-$(CONFIG_TINYDRM_MIPI_DBI) += mipi-dbi.o
# Displays
obj-$(CONFIG_TINYDRM_MI0283QT) += mi0283qt.o
+obj-$(CONFIG_TINYDRM_REPAPER) += repaper.o
+obj-$(CONFIG_TINYDRM_ST7586) += st7586.o
diff --git a/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c b/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c
index d4cda33..bd6cce0 100644
--- a/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c
+++ b/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c
@@ -7,13 +7,15 @@
* (at your option) any later version.
*/
-#include <drm/tinydrm/tinydrm.h>
-#include <drm/tinydrm/tinydrm-helpers.h>
#include <linux/backlight.h>
+#include <linux/dma-buf.h>
#include <linux/pm.h>
#include <linux/spi/spi.h>
#include <linux/swab.h>
+#include <drm/tinydrm/tinydrm.h>
+#include <drm/tinydrm/tinydrm-helpers.h>
+
static unsigned int spi_max;
module_param(spi_max, uint, 0400);
MODULE_PARM_DESC(spi_max, "Set a lower SPI max transfer size");
@@ -181,6 +183,60 @@ void tinydrm_xrgb8888_to_rgb565(u16 *dst, void *vaddr,
EXPORT_SYMBOL(tinydrm_xrgb8888_to_rgb565);
/**
+ * tinydrm_xrgb8888_to_gray8 - Convert XRGB8888 to grayscale
+ * @dst: 8-bit grayscale destination buffer
+ * @vaddr: XRGB8888 source buffer
+ * @fb: DRM framebuffer
+ * @clip: Clip rectangle area to copy
+ *
+ * Drm doesn't have native monochrome or grayscale support.
+ * Such drivers can announce the commonly supported XR24 format to userspace
+ * and use this function to convert to the native format.
+ *
+ * Monochrome drivers will use the most significant bit,
+ * where 1 means foreground color and 0 background color.
+ *
+ * ITU BT.601 is used for the RGB -> luma (brightness) conversion.
+ */
+void tinydrm_xrgb8888_to_gray8(u8 *dst, void *vaddr, struct drm_framebuffer *fb,
+ struct drm_clip_rect *clip)
+{
+ unsigned int len = (clip->x2 - clip->x1) * sizeof(u32);
+ unsigned int x, y;
+ void *buf;
+ u32 *src;
+
+ if (WARN_ON(fb->format->format != DRM_FORMAT_XRGB8888))
+ return;
+ /*
+ * The cma memory is write-combined so reads are uncached.
+ * Speed up by fetching one line at a time.
+ */
+ buf = kmalloc(len, GFP_KERNEL);
+ if (!buf)
+ return;
+
+ for (y = clip->y1; y < clip->y2; y++) {
+ src = vaddr + (y * fb->pitches[0]);
+ src += clip->x1;
+ memcpy(buf, src, len);
+ src = buf;
+ for (x = clip->x1; x < clip->x2; x++) {
+ u8 r = (*src & 0x00ff0000) >> 16;
+ u8 g = (*src & 0x0000ff00) >> 8;
+ u8 b = *src & 0x000000ff;
+
+ /* ITU BT.601: Y = 0.299 R + 0.587 G + 0.114 B */
+ *dst++ = (3 * r + 6 * g + b) / 10;
+ src++;
+ }
+ }
+
+ kfree(buf);
+}
+EXPORT_SYMBOL(tinydrm_xrgb8888_to_gray8);
+
+/**
* tinydrm_of_find_backlight - Find backlight device in device-tree
* @dev: Device
*
diff --git a/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c b/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c
index ec43fb7..177e9d8 100644
--- a/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c
+++ b/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c
@@ -56,7 +56,7 @@ static const struct drm_connector_helper_funcs tinydrm_connector_hfuncs = {
static enum drm_connector_status
tinydrm_connector_detect(struct drm_connector *connector, bool force)
{
- if (drm_device_is_unplugged(connector->dev))
+ if (drm_dev_is_unplugged(connector->dev))
return connector_status_disconnected;
return connector->status;
@@ -71,7 +71,6 @@ static void tinydrm_connector_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs tinydrm_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.reset = drm_atomic_helper_connector_reset,
.detect = tinydrm_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
@@ -225,7 +224,7 @@ tinydrm_display_pipe_init(struct tinydrm_device *tdev,
return PTR_ERR(connector);
ret = drm_simple_display_pipe_init(drm, &tdev->pipe, funcs, formats,
- format_count, connector);
+ format_count, NULL, connector);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/tinydrm/mi0283qt.c b/drivers/gpu/drm/tinydrm/mi0283qt.c
index 482ff1c3..7e5bb7d 100644
--- a/drivers/gpu/drm/tinydrm/mi0283qt.c
+++ b/drivers/gpu/drm/tinydrm/mi0283qt.c
@@ -195,8 +195,12 @@ static int mi0283qt_probe(struct spi_device *spi)
device_property_read_u32(dev, "rotation", &rotation);
- ret = mipi_dbi_spi_init(spi, mipi, dc, &mi0283qt_pipe_funcs,
- &mi0283qt_driver, &mi0283qt_mode, rotation);
+ ret = mipi_dbi_spi_init(spi, mipi, dc);
+ if (ret)
+ return ret;
+
+ ret = mipi_dbi_init(&spi->dev, mipi, &mi0283qt_pipe_funcs,
+ &mi0283qt_driver, &mi0283qt_mode, rotation);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/tinydrm/mipi-dbi.c b/drivers/gpu/drm/tinydrm/mipi-dbi.c
index c83eeb7..2caeabc 100644
--- a/drivers/gpu/drm/tinydrm/mipi-dbi.c
+++ b/drivers/gpu/drm/tinydrm/mipi-dbi.c
@@ -776,15 +776,12 @@ static int mipi_dbi_typec3_command(struct mipi_dbi *mipi, u8 cmd,
/**
* mipi_dbi_spi_init - Initialize MIPI DBI SPI interfaced controller
* @spi: SPI device
- * @dc: D/C gpio (optional)
* @mipi: &mipi_dbi structure to initialize
- * @pipe_funcs: Display pipe functions
- * @driver: DRM driver
- * @mode: Display mode
- * @rotation: Initial rotation in degrees Counter Clock Wise
+ * @dc: D/C gpio (optional)
*
* This function sets &mipi_dbi->command, enables &mipi->read_commands for the
- * usual read commands and initializes @mipi using mipi_dbi_init().
+ * usual read commands. It should be followed by a call to mipi_dbi_init() or
+ * a driver-specific init.
*
* If @dc is set, a Type C Option 3 interface is assumed, if not
* Type C Option 1.
@@ -799,11 +796,7 @@ static int mipi_dbi_typec3_command(struct mipi_dbi *mipi, u8 cmd,
* Zero on success, negative error code on failure.
*/
int mipi_dbi_spi_init(struct spi_device *spi, struct mipi_dbi *mipi,
- struct gpio_desc *dc,
- const struct drm_simple_display_pipe_funcs *pipe_funcs,
- struct drm_driver *driver,
- const struct drm_display_mode *mode,
- unsigned int rotation)
+ struct gpio_desc *dc)
{
size_t tx_size = tinydrm_spi_max_transfer_size(spi, 0);
struct device *dev = &spi->dev;
@@ -849,7 +842,7 @@ int mipi_dbi_spi_init(struct spi_device *spi, struct mipi_dbi *mipi,
return -ENOMEM;
}
- return mipi_dbi_init(dev, mipi, pipe_funcs, driver, mode, rotation);
+ return 0;
}
EXPORT_SYMBOL(mipi_dbi_spi_init);
diff --git a/drivers/gpu/drm/tinydrm/repaper.c b/drivers/gpu/drm/tinydrm/repaper.c
new file mode 100644
index 0000000..30dc97b
--- /dev/null
+++ b/drivers/gpu/drm/tinydrm/repaper.c
@@ -0,0 +1,1117 @@
+/*
+ * DRM driver for Pervasive Displays RePaper branded e-ink panels
+ *
+ * Copyright 2013-2017 Pervasive Displays, Inc.
+ * Copyright 2017 Noralf Trønnes
+ *
+ * The driver supports:
+ * Material Film: Aurora Mb (V231)
+ * Driver IC: G2 (eTC)
+ *
+ * The controller code was taken from the userspace driver:
+ * https://github.com/repaper/gratis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/delay.h>
+#include <linux/dma-buf.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/sched/clock.h>
+#include <linux/spi/spi.h>
+#include <linux/thermal.h>
+
+#include <drm/tinydrm/tinydrm.h>
+#include <drm/tinydrm/tinydrm-helpers.h>
+
+#define REPAPER_RID_G2_COG_ID 0x12
+
+enum repaper_model {
+ E1144CS021 = 1,
+ E1190CS021,
+ E2200CS021,
+ E2271CS021,
+};
+
+enum repaper_stage { /* Image pixel -> Display pixel */
+ REPAPER_COMPENSATE, /* B -> W, W -> B (Current Image) */
+ REPAPER_WHITE, /* B -> N, W -> W (Current Image) */
+ REPAPER_INVERSE, /* B -> N, W -> B (New Image) */
+ REPAPER_NORMAL /* B -> B, W -> W (New Image) */
+};
+
+enum repaper_epd_border_byte {
+ REPAPER_BORDER_BYTE_NONE,
+ REPAPER_BORDER_BYTE_ZERO,
+ REPAPER_BORDER_BYTE_SET,
+};
+
+struct repaper_epd {
+ struct tinydrm_device tinydrm;
+ struct spi_device *spi;
+
+ struct gpio_desc *panel_on;
+ struct gpio_desc *border;
+ struct gpio_desc *discharge;
+ struct gpio_desc *reset;
+ struct gpio_desc *busy;
+
+ struct thermal_zone_device *thermal;
+
+ unsigned int height;
+ unsigned int width;
+ unsigned int bytes_per_scan;
+ const u8 *channel_select;
+ unsigned int stage_time;
+ unsigned int factored_stage_time;
+ bool middle_scan;
+ bool pre_border_byte;
+ enum repaper_epd_border_byte border_byte;
+
+ u8 *line_buffer;
+ void *current_frame;
+
+ bool enabled;
+ bool cleared;
+ bool partial;
+};
+
+static inline struct repaper_epd *
+epd_from_tinydrm(struct tinydrm_device *tdev)
+{
+ return container_of(tdev, struct repaper_epd, tinydrm);
+}
+
+static int repaper_spi_transfer(struct spi_device *spi, u8 header,
+ const void *tx, void *rx, size_t len)
+{
+ void *txbuf = NULL, *rxbuf = NULL;
+ struct spi_transfer tr[2] = {};
+ u8 *headerbuf;
+ int ret;
+
+ headerbuf = kmalloc(1, GFP_KERNEL);
+ if (!headerbuf)
+ return -ENOMEM;
+
+ headerbuf[0] = header;
+ tr[0].tx_buf = headerbuf;
+ tr[0].len = 1;
+
+ /* Stack allocated tx? */
+ if (tx && len <= 32) {
+ txbuf = kmalloc(len, GFP_KERNEL);
+ if (!txbuf) {
+ ret = -ENOMEM;
+ goto out_free;
+ }
+ memcpy(txbuf, tx, len);
+ }
+
+ if (rx) {
+ rxbuf = kmalloc(len, GFP_KERNEL);
+ if (!rxbuf) {
+ ret = -ENOMEM;
+ goto out_free;
+ }
+ }
+
+ tr[1].tx_buf = txbuf ? txbuf : tx;
+ tr[1].rx_buf = rxbuf;
+ tr[1].len = len;
+
+ ndelay(80);
+ ret = spi_sync_transfer(spi, tr, 2);
+ if (rx && !ret)
+ memcpy(rx, rxbuf, len);
+
+out_free:
+ kfree(headerbuf);
+ kfree(txbuf);
+ kfree(rxbuf);
+
+ return ret;
+}
+
+static int repaper_write_buf(struct spi_device *spi, u8 reg,
+ const u8 *buf, size_t len)
+{
+ int ret;
+
+ ret = repaper_spi_transfer(spi, 0x70, &reg, NULL, 1);
+ if (ret)
+ return ret;
+
+ return repaper_spi_transfer(spi, 0x72, buf, NULL, len);
+}
+
+static int repaper_write_val(struct spi_device *spi, u8 reg, u8 val)
+{
+ return repaper_write_buf(spi, reg, &val, 1);
+}
+
+static int repaper_read_val(struct spi_device *spi, u8 reg)
+{
+ int ret;
+ u8 val;
+
+ ret = repaper_spi_transfer(spi, 0x70, &reg, NULL, 1);
+ if (ret)
+ return ret;
+
+ ret = repaper_spi_transfer(spi, 0x73, NULL, &val, 1);
+
+ return ret ? ret : val;
+}
+
+static int repaper_read_id(struct spi_device *spi)
+{
+ int ret;
+ u8 id;
+
+ ret = repaper_spi_transfer(spi, 0x71, NULL, &id, 1);
+
+ return ret ? ret : id;
+}
+
+static void repaper_spi_mosi_low(struct spi_device *spi)
+{
+ const u8 buf[1] = { 0 };
+
+ spi_write(spi, buf, 1);
+}
+
+/* pixels on display are numbered from 1 so even is actually bits 1,3,5,... */
+static void repaper_even_pixels(struct repaper_epd *epd, u8 **pp,
+ const u8 *data, u8 fixed_value, const u8 *mask,
+ enum repaper_stage stage)
+{
+ unsigned int b;
+
+ for (b = 0; b < (epd->width / 8); b++) {
+ if (data) {
+ u8 pixels = data[b] & 0xaa;
+ u8 pixel_mask = 0xff;
+ u8 p1, p2, p3, p4;
+
+ if (mask) {
+ pixel_mask = (mask[b] ^ pixels) & 0xaa;
+ pixel_mask |= pixel_mask >> 1;
+ }
+
+ switch (stage) {
+ case REPAPER_COMPENSATE: /* B -> W, W -> B (Current) */
+ pixels = 0xaa | ((pixels ^ 0xaa) >> 1);
+ break;
+ case REPAPER_WHITE: /* B -> N, W -> W (Current) */
+ pixels = 0x55 + ((pixels ^ 0xaa) >> 1);
+ break;
+ case REPAPER_INVERSE: /* B -> N, W -> B (New) */
+ pixels = 0x55 | (pixels ^ 0xaa);
+ break;
+ case REPAPER_NORMAL: /* B -> B, W -> W (New) */
+ pixels = 0xaa | (pixels >> 1);
+ break;
+ }
+
+ pixels = (pixels & pixel_mask) | (~pixel_mask & 0x55);
+ p1 = (pixels >> 6) & 0x03;
+ p2 = (pixels >> 4) & 0x03;
+ p3 = (pixels >> 2) & 0x03;
+ p4 = (pixels >> 0) & 0x03;
+ pixels = (p1 << 0) | (p2 << 2) | (p3 << 4) | (p4 << 6);
+ *(*pp)++ = pixels;
+ } else {
+ *(*pp)++ = fixed_value;
+ }
+ }
+}
+
+/* pixels on display are numbered from 1 so odd is actually bits 0,2,4,... */
+static void repaper_odd_pixels(struct repaper_epd *epd, u8 **pp,
+ const u8 *data, u8 fixed_value, const u8 *mask,
+ enum repaper_stage stage)
+{
+ unsigned int b;
+
+ for (b = epd->width / 8; b > 0; b--) {
+ if (data) {
+ u8 pixels = data[b - 1] & 0x55;
+ u8 pixel_mask = 0xff;
+
+ if (mask) {
+ pixel_mask = (mask[b - 1] ^ pixels) & 0x55;
+ pixel_mask |= pixel_mask << 1;
+ }
+
+ switch (stage) {
+ case REPAPER_COMPENSATE: /* B -> W, W -> B (Current) */
+ pixels = 0xaa | (pixels ^ 0x55);
+ break;
+ case REPAPER_WHITE: /* B -> N, W -> W (Current) */
+ pixels = 0x55 + (pixels ^ 0x55);
+ break;
+ case REPAPER_INVERSE: /* B -> N, W -> B (New) */
+ pixels = 0x55 | ((pixels ^ 0x55) << 1);
+ break;
+ case REPAPER_NORMAL: /* B -> B, W -> W (New) */
+ pixels = 0xaa | pixels;
+ break;
+ }
+
+ pixels = (pixels & pixel_mask) | (~pixel_mask & 0x55);
+ *(*pp)++ = pixels;
+ } else {
+ *(*pp)++ = fixed_value;
+ }
+ }
+}
+
+/* interleave bits: (byte)76543210 -> (16 bit).7.6.5.4.3.2.1 */
+static inline u16 repaper_interleave_bits(u16 value)
+{
+ value = (value | (value << 4)) & 0x0f0f;
+ value = (value | (value << 2)) & 0x3333;
+ value = (value | (value << 1)) & 0x5555;
+
+ return value;
+}
+
+/* pixels on display are numbered from 1 */
+static void repaper_all_pixels(struct repaper_epd *epd, u8 **pp,
+ const u8 *data, u8 fixed_value, const u8 *mask,
+ enum repaper_stage stage)
+{
+ unsigned int b;
+
+ for (b = epd->width / 8; b > 0; b--) {
+ if (data) {
+ u16 pixels = repaper_interleave_bits(data[b - 1]);
+ u16 pixel_mask = 0xffff;
+
+ if (mask) {
+ pixel_mask = repaper_interleave_bits(mask[b - 1]);
+
+ pixel_mask = (pixel_mask ^ pixels) & 0x5555;
+ pixel_mask |= pixel_mask << 1;
+ }
+
+ switch (stage) {
+ case REPAPER_COMPENSATE: /* B -> W, W -> B (Current) */
+ pixels = 0xaaaa | (pixels ^ 0x5555);
+ break;
+ case REPAPER_WHITE: /* B -> N, W -> W (Current) */
+ pixels = 0x5555 + (pixels ^ 0x5555);
+ break;
+ case REPAPER_INVERSE: /* B -> N, W -> B (New) */
+ pixels = 0x5555 | ((pixels ^ 0x5555) << 1);
+ break;
+ case REPAPER_NORMAL: /* B -> B, W -> W (New) */
+ pixels = 0xaaaa | pixels;
+ break;
+ }
+
+ pixels = (pixels & pixel_mask) | (~pixel_mask & 0x5555);
+ *(*pp)++ = pixels >> 8;
+ *(*pp)++ = pixels;
+ } else {
+ *(*pp)++ = fixed_value;
+ *(*pp)++ = fixed_value;
+ }
+ }
+}
+
+/* output one line of scan and data bytes to the display */
+static void repaper_one_line(struct repaper_epd *epd, unsigned int line,
+ const u8 *data, u8 fixed_value, const u8 *mask,
+ enum repaper_stage stage)
+{
+ u8 *p = epd->line_buffer;
+ unsigned int b;
+
+ repaper_spi_mosi_low(epd->spi);
+
+ if (epd->pre_border_byte)
+ *p++ = 0x00;
+
+ if (epd->middle_scan) {
+ /* data bytes */
+ repaper_odd_pixels(epd, &p, data, fixed_value, mask, stage);
+
+ /* scan line */
+ for (b = epd->bytes_per_scan; b > 0; b--) {
+ if (line / 4 == b - 1)
+ *p++ = 0x03 << (2 * (line & 0x03));
+ else
+ *p++ = 0x00;
+ }
+
+ /* data bytes */
+ repaper_even_pixels(epd, &p, data, fixed_value, mask, stage);
+ } else {
+ /*
+ * even scan line, but as lines on display are numbered from 1,
+ * line: 1,3,5,...
+ */
+ for (b = 0; b < epd->bytes_per_scan; b++) {
+ if (0 != (line & 0x01) && line / 8 == b)
+ *p++ = 0xc0 >> (line & 0x06);
+ else
+ *p++ = 0x00;
+ }
+
+ /* data bytes */
+ repaper_all_pixels(epd, &p, data, fixed_value, mask, stage);
+
+ /*
+ * odd scan line, but as lines on display are numbered from 1,
+ * line: 0,2,4,6,...
+ */
+ for (b = epd->bytes_per_scan; b > 0; b--) {
+ if (0 == (line & 0x01) && line / 8 == b - 1)
+ *p++ = 0x03 << (line & 0x06);
+ else
+ *p++ = 0x00;
+ }
+ }
+
+ switch (epd->border_byte) {
+ case REPAPER_BORDER_BYTE_NONE:
+ break;
+
+ case REPAPER_BORDER_BYTE_ZERO:
+ *p++ = 0x00;
+ break;
+
+ case REPAPER_BORDER_BYTE_SET:
+ switch (stage) {
+ case REPAPER_COMPENSATE:
+ case REPAPER_WHITE:
+ case REPAPER_INVERSE:
+ *p++ = 0x00;
+ break;
+ case REPAPER_NORMAL:
+ *p++ = 0xaa;
+ break;
+ }
+ break;
+ }
+
+ repaper_write_buf(epd->spi, 0x0a, epd->line_buffer,
+ p - epd->line_buffer);
+
+ /* Output data to panel */
+ repaper_write_val(epd->spi, 0x02, 0x07);
+
+ repaper_spi_mosi_low(epd->spi);
+}
+
+static void repaper_frame_fixed(struct repaper_epd *epd, u8 fixed_value,
+ enum repaper_stage stage)
+{
+ unsigned int line;
+
+ for (line = 0; line < epd->height; line++)
+ repaper_one_line(epd, line, NULL, fixed_value, NULL, stage);
+}
+
+static void repaper_frame_data(struct repaper_epd *epd, const u8 *image,
+ const u8 *mask, enum repaper_stage stage)
+{
+ unsigned int line;
+
+ if (!mask) {
+ for (line = 0; line < epd->height; line++) {
+ repaper_one_line(epd, line,
+ &image[line * (epd->width / 8)],
+ 0, NULL, stage);
+ }
+ } else {
+ for (line = 0; line < epd->height; line++) {
+ size_t n = line * epd->width / 8;
+
+ repaper_one_line(epd, line, &image[n], 0, &mask[n],
+ stage);
+ }
+ }
+}
+
+static void repaper_frame_fixed_repeat(struct repaper_epd *epd, u8 fixed_value,
+ enum repaper_stage stage)
+{
+ u64 start = local_clock();
+ u64 end = start + (epd->factored_stage_time * 1000 * 1000);
+
+ do {
+ repaper_frame_fixed(epd, fixed_value, stage);
+ } while (local_clock() < end);
+}
+
+static void repaper_frame_data_repeat(struct repaper_epd *epd, const u8 *image,
+ const u8 *mask, enum repaper_stage stage)
+{
+ u64 start = local_clock();
+ u64 end = start + (epd->factored_stage_time * 1000 * 1000);
+
+ do {
+ repaper_frame_data(epd, image, mask, stage);
+ } while (local_clock() < end);
+}
+
+static void repaper_get_temperature(struct repaper_epd *epd)
+{
+ int ret, temperature = 0;
+ unsigned int factor10x;
+
+ if (!epd->thermal)
+ return;
+
+ ret = thermal_zone_get_temp(epd->thermal, &temperature);
+ if (ret) {
+ dev_err(&epd->spi->dev, "Failed to get temperature (%d)\n",
+ ret);
+ return;
+ }
+
+ temperature /= 1000;
+
+ if (temperature <= -10)
+ factor10x = 170;
+ else if (temperature <= -5)
+ factor10x = 120;
+ else if (temperature <= 5)
+ factor10x = 80;
+ else if (temperature <= 10)
+ factor10x = 40;
+ else if (temperature <= 15)
+ factor10x = 30;
+ else if (temperature <= 20)
+ factor10x = 20;
+ else if (temperature <= 40)
+ factor10x = 10;
+ else
+ factor10x = 7;
+
+ epd->factored_stage_time = epd->stage_time * factor10x / 10;
+}
+
+static void repaper_gray8_to_mono_reversed(u8 *buf, u32 width, u32 height)
+{
+ u8 *gray8 = buf, *mono = buf;
+ int y, xb, i;
+
+ for (y = 0; y < height; y++)
+ for (xb = 0; xb < width / 8; xb++) {
+ u8 byte = 0x00;
+
+ for (i = 0; i < 8; i++) {
+ int x = xb * 8 + i;
+
+ byte >>= 1;
+ if (gray8[y * width + x] >> 7)
+ byte |= BIT(7);
+ }
+ *mono++ = byte;
+ }
+}
+
+static int repaper_fb_dirty(struct drm_framebuffer *fb,
+ struct drm_file *file_priv,
+ unsigned int flags, unsigned int color,
+ struct drm_clip_rect *clips,
+ unsigned int num_clips)
+{
+ struct drm_gem_cma_object *cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
+ struct dma_buf_attachment *import_attach = cma_obj->base.import_attach;
+ struct tinydrm_device *tdev = fb->dev->dev_private;
+ struct repaper_epd *epd = epd_from_tinydrm(tdev);
+ struct drm_clip_rect clip;
+ u8 *buf = NULL;
+ int ret = 0;
+
+ /* repaper can't do partial updates */
+ clip.x1 = 0;
+ clip.x2 = fb->width;
+ clip.y1 = 0;
+ clip.y2 = fb->height;
+
+ mutex_lock(&tdev->dirty_lock);
+
+ if (!epd->enabled)
+ goto out_unlock;
+
+ /* fbdev can flush even when we're not interested */
+ if (tdev->pipe.plane.fb != fb)
+ goto out_unlock;
+
+ repaper_get_temperature(epd);
+
+ DRM_DEBUG("Flushing [FB:%d] st=%ums\n", fb->base.id,
+ epd->factored_stage_time);
+
+ buf = kmalloc(fb->width * fb->height, GFP_KERNEL);
+ if (!buf) {
+ ret = -ENOMEM;
+ goto out_unlock;
+ }
+
+ if (import_attach) {
+ ret = dma_buf_begin_cpu_access(import_attach->dmabuf,
+ DMA_FROM_DEVICE);
+ if (ret)
+ goto out_unlock;
+ }
+
+ tinydrm_xrgb8888_to_gray8(buf, cma_obj->vaddr, fb, &clip);
+
+ if (import_attach) {
+ ret = dma_buf_end_cpu_access(import_attach->dmabuf,
+ DMA_FROM_DEVICE);
+ if (ret)
+ goto out_unlock;
+ }
+
+ repaper_gray8_to_mono_reversed(buf, fb->width, fb->height);
+
+ if (epd->partial) {
+ repaper_frame_data_repeat(epd, buf, epd->current_frame,
+ REPAPER_NORMAL);
+ } else if (epd->cleared) {
+ repaper_frame_data_repeat(epd, epd->current_frame, NULL,
+ REPAPER_COMPENSATE);
+ repaper_frame_data_repeat(epd, epd->current_frame, NULL,
+ REPAPER_WHITE);
+ repaper_frame_data_repeat(epd, buf, NULL, REPAPER_INVERSE);
+ repaper_frame_data_repeat(epd, buf, NULL, REPAPER_NORMAL);
+
+ epd->partial = true;
+ } else {
+ /* Clear display (anything -> white) */
+ repaper_frame_fixed_repeat(epd, 0xff, REPAPER_COMPENSATE);
+ repaper_frame_fixed_repeat(epd, 0xff, REPAPER_WHITE);
+ repaper_frame_fixed_repeat(epd, 0xaa, REPAPER_INVERSE);
+ repaper_frame_fixed_repeat(epd, 0xaa, REPAPER_NORMAL);
+
+ /* Assuming a clear (white) screen output an image */
+ repaper_frame_fixed_repeat(epd, 0xaa, REPAPER_COMPENSATE);
+ repaper_frame_fixed_repeat(epd, 0xaa, REPAPER_WHITE);
+ repaper_frame_data_repeat(epd, buf, NULL, REPAPER_INVERSE);
+ repaper_frame_data_repeat(epd, buf, NULL, REPAPER_NORMAL);
+
+ epd->cleared = true;
+ epd->partial = true;
+ }
+
+ memcpy(epd->current_frame, buf, fb->width * fb->height / 8);
+
+ /*
+ * An extra frame write is needed if pixels are set in the bottom line,
+ * or else grey lines rises up from the pixels
+ */
+ if (epd->pre_border_byte) {
+ unsigned int x;
+
+ for (x = 0; x < (fb->width / 8); x++)
+ if (buf[x + (fb->width * (fb->height - 1) / 8)]) {
+ repaper_frame_data_repeat(epd, buf,
+ epd->current_frame,
+ REPAPER_NORMAL);
+ break;
+ }
+ }
+
+out_unlock:
+ mutex_unlock(&tdev->dirty_lock);
+
+ if (ret)
+ dev_err(fb->dev->dev, "Failed to update display (%d)\n", ret);
+ kfree(buf);
+
+ return ret;
+}
+
+static const struct drm_framebuffer_funcs repaper_fb_funcs = {
+ .destroy = drm_fb_cma_destroy,
+ .create_handle = drm_fb_cma_create_handle,
+ .dirty = repaper_fb_dirty,
+};
+
+static void power_off(struct repaper_epd *epd)
+{
+ /* Turn off power and all signals */
+ gpiod_set_value_cansleep(epd->reset, 0);
+ gpiod_set_value_cansleep(epd->panel_on, 0);
+ if (epd->border)
+ gpiod_set_value_cansleep(epd->border, 0);
+
+ /* Ensure SPI MOSI and CLOCK are Low before CS Low */
+ repaper_spi_mosi_low(epd->spi);
+
+ /* Discharge pulse */
+ gpiod_set_value_cansleep(epd->discharge, 1);
+ msleep(150);
+ gpiod_set_value_cansleep(epd->discharge, 0);
+}
+
+static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe,
+ struct drm_crtc_state *crtc_state)
+{
+ struct tinydrm_device *tdev = pipe_to_tinydrm(pipe);
+ struct repaper_epd *epd = epd_from_tinydrm(tdev);
+ struct spi_device *spi = epd->spi;
+ struct device *dev = &spi->dev;
+ bool dc_ok = false;
+ int i, ret;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ /* Power up sequence */
+ gpiod_set_value_cansleep(epd->reset, 0);
+ gpiod_set_value_cansleep(epd->panel_on, 0);
+ gpiod_set_value_cansleep(epd->discharge, 0);
+ if (epd->border)
+ gpiod_set_value_cansleep(epd->border, 0);
+ repaper_spi_mosi_low(spi);
+ usleep_range(5000, 10000);
+
+ gpiod_set_value_cansleep(epd->panel_on, 1);
+ /*
+ * This delay comes from the repaper.org userspace driver, it's not
+ * mentioned in the datasheet.
+ */
+ usleep_range(10000, 15000);
+ gpiod_set_value_cansleep(epd->reset, 1);
+ if (epd->border)
+ gpiod_set_value_cansleep(epd->border, 1);
+ usleep_range(5000, 10000);
+ gpiod_set_value_cansleep(epd->reset, 0);
+ usleep_range(5000, 10000);
+ gpiod_set_value_cansleep(epd->reset, 1);
+ usleep_range(5000, 10000);
+
+ /* Wait for COG to become ready */
+ for (i = 100; i > 0; i--) {
+ if (!gpiod_get_value_cansleep(epd->busy))
+ break;
+
+ usleep_range(10, 100);
+ }
+
+ if (!i) {
+ dev_err(dev, "timeout waiting for panel to become ready.\n");
+ power_off(epd);
+ return;
+ }
+
+ repaper_read_id(spi);
+ ret = repaper_read_id(spi);
+ if (ret != REPAPER_RID_G2_COG_ID) {
+ if (ret < 0)
+ dev_err(dev, "failed to read chip (%d)\n", ret);
+ else
+ dev_err(dev, "wrong COG ID 0x%02x\n", ret);
+ power_off(epd);
+ return;
+ }
+
+ /* Disable OE */
+ repaper_write_val(spi, 0x02, 0x40);
+
+ ret = repaper_read_val(spi, 0x0f);
+ if (ret < 0 || !(ret & 0x80)) {
+ if (ret < 0)
+ dev_err(dev, "failed to read chip (%d)\n", ret);
+ else
+ dev_err(dev, "panel is reported broken\n");
+ power_off(epd);
+ return;
+ }
+
+ /* Power saving mode */
+ repaper_write_val(spi, 0x0b, 0x02);
+ /* Channel select */
+ repaper_write_buf(spi, 0x01, epd->channel_select, 8);
+ /* High power mode osc */
+ repaper_write_val(spi, 0x07, 0xd1);
+ /* Power setting */
+ repaper_write_val(spi, 0x08, 0x02);
+ /* Vcom level */
+ repaper_write_val(spi, 0x09, 0xc2);
+ /* Power setting */
+ repaper_write_val(spi, 0x04, 0x03);
+ /* Driver latch on */
+ repaper_write_val(spi, 0x03, 0x01);
+ /* Driver latch off */
+ repaper_write_val(spi, 0x03, 0x00);
+ usleep_range(5000, 10000);
+
+ /* Start chargepump */
+ for (i = 0; i < 4; ++i) {
+ /* Charge pump positive voltage on - VGH/VDL on */
+ repaper_write_val(spi, 0x05, 0x01);
+ msleep(240);
+
+ /* Charge pump negative voltage on - VGL/VDL on */
+ repaper_write_val(spi, 0x05, 0x03);
+ msleep(40);
+
+ /* Charge pump Vcom on - Vcom driver on */
+ repaper_write_val(spi, 0x05, 0x0f);
+ msleep(40);
+
+ /* check DC/DC */
+ ret = repaper_read_val(spi, 0x0f);
+ if (ret < 0) {
+ dev_err(dev, "failed to read chip (%d)\n", ret);
+ power_off(epd);
+ return;
+ }
+
+ if (ret & 0x40) {
+ dc_ok = true;
+ break;
+ }
+ }
+
+ if (!dc_ok) {
+ dev_err(dev, "dc/dc failed\n");
+ power_off(epd);
+ return;
+ }
+
+ /*
+ * Output enable to disable
+ * The userspace driver sets this to 0x04, but the datasheet says 0x06
+ */
+ repaper_write_val(spi, 0x02, 0x04);
+
+ epd->enabled = true;
+ epd->partial = false;
+}
+
+static void repaper_pipe_disable(struct drm_simple_display_pipe *pipe)
+{
+ struct tinydrm_device *tdev = pipe_to_tinydrm(pipe);
+ struct repaper_epd *epd = epd_from_tinydrm(tdev);
+ struct spi_device *spi = epd->spi;
+ unsigned int line;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ mutex_lock(&tdev->dirty_lock);
+ epd->enabled = false;
+ mutex_unlock(&tdev->dirty_lock);
+
+ /* Nothing frame */
+ for (line = 0; line < epd->height; line++)
+ repaper_one_line(epd, 0x7fffu, NULL, 0x00, NULL,
+ REPAPER_COMPENSATE);
+
+ /* 2.7" */
+ if (epd->border) {
+ /* Dummy line */
+ repaper_one_line(epd, 0x7fffu, NULL, 0x00, NULL,
+ REPAPER_COMPENSATE);
+ msleep(25);
+ gpiod_set_value_cansleep(epd->border, 0);
+ msleep(200);
+ gpiod_set_value_cansleep(epd->border, 1);
+ } else {
+ /* Border dummy line */
+ repaper_one_line(epd, 0x7fffu, NULL, 0x00, NULL,
+ REPAPER_NORMAL);
+ msleep(200);
+ }
+
+ /* not described in datasheet */
+ repaper_write_val(spi, 0x0b, 0x00);
+ /* Latch reset turn on */
+ repaper_write_val(spi, 0x03, 0x01);
+ /* Power off charge pump Vcom */
+ repaper_write_val(spi, 0x05, 0x03);
+ /* Power off charge pump neg voltage */
+ repaper_write_val(spi, 0x05, 0x01);
+ msleep(120);
+ /* Discharge internal */
+ repaper_write_val(spi, 0x04, 0x80);
+ /* turn off all charge pumps */
+ repaper_write_val(spi, 0x05, 0x00);
+ /* Turn off osc */
+ repaper_write_val(spi, 0x07, 0x01);
+ msleep(50);
+
+ power_off(epd);
+}
+
+static const struct drm_simple_display_pipe_funcs repaper_pipe_funcs = {
+ .enable = repaper_pipe_enable,
+ .disable = repaper_pipe_disable,
+ .update = tinydrm_display_pipe_update,
+ .prepare_fb = tinydrm_display_pipe_prepare_fb,
+};
+
+static const uint32_t repaper_formats[] = {
+ DRM_FORMAT_XRGB8888,
+};
+
+static const struct drm_display_mode repaper_e1144cs021_mode = {
+ TINYDRM_MODE(128, 96, 29, 22),
+};
+
+static const u8 repaper_e1144cs021_cs[] = { 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0f, 0xff, 0x00 };
+
+static const struct drm_display_mode repaper_e1190cs021_mode = {
+ TINYDRM_MODE(144, 128, 36, 32),
+};
+
+static const u8 repaper_e1190cs021_cs[] = { 0x00, 0x00, 0x00, 0x03,
+ 0xfc, 0x00, 0x00, 0xff };
+
+static const struct drm_display_mode repaper_e2200cs021_mode = {
+ TINYDRM_MODE(200, 96, 46, 22),
+};
+
+static const u8 repaper_e2200cs021_cs[] = { 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0xff, 0xe0, 0x00 };
+
+static const struct drm_display_mode repaper_e2271cs021_mode = {
+ TINYDRM_MODE(264, 176, 57, 38),
+};
+
+static const u8 repaper_e2271cs021_cs[] = { 0x00, 0x00, 0x00, 0x7f,
+ 0xff, 0xfe, 0x00, 0x00 };
+
+DEFINE_DRM_GEM_CMA_FOPS(repaper_fops);
+
+static struct drm_driver repaper_driver = {
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
+ DRIVER_ATOMIC,
+ .fops = &repaper_fops,
+ TINYDRM_GEM_DRIVER_OPS,
+ .name = "repaper",
+ .desc = "Pervasive Displays RePaper e-ink panels",
+ .date = "20170405",
+ .major = 1,
+ .minor = 0,
+};
+
+static const struct of_device_id repaper_of_match[] = {
+ { .compatible = "pervasive,e1144cs021", .data = (void *)E1144CS021 },
+ { .compatible = "pervasive,e1190cs021", .data = (void *)E1190CS021 },
+ { .compatible = "pervasive,e2200cs021", .data = (void *)E2200CS021 },
+ { .compatible = "pervasive,e2271cs021", .data = (void *)E2271CS021 },
+ {},
+};
+MODULE_DEVICE_TABLE(of, repaper_of_match);
+
+static const struct spi_device_id repaper_id[] = {
+ { "e1144cs021", E1144CS021 },
+ { "e1190cs021", E1190CS021 },
+ { "e2200cs021", E2200CS021 },
+ { "e2271cs021", E2271CS021 },
+ { },
+};
+MODULE_DEVICE_TABLE(spi, repaper_id);
+
+static int repaper_probe(struct spi_device *spi)
+{
+ const struct drm_display_mode *mode;
+ const struct spi_device_id *spi_id;
+ const struct of_device_id *match;
+ struct device *dev = &spi->dev;
+ struct tinydrm_device *tdev;
+ enum repaper_model model;
+ const char *thermal_zone;
+ struct repaper_epd *epd;
+ size_t line_buffer_size;
+ int ret;
+
+ match = of_match_device(repaper_of_match, dev);
+ if (match) {
+ model = (enum repaper_model)match->data;
+ } else {
+ spi_id = spi_get_device_id(spi);
+ model = spi_id->driver_data;
+ }
+
+ /* The SPI device is used to allocate dma memory */
+ if (!dev->coherent_dma_mask) {
+ ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
+ if (ret) {
+ dev_warn(dev, "Failed to set dma mask %d\n", ret);
+ return ret;
+ }
+ }
+
+ epd = devm_kzalloc(dev, sizeof(*epd), GFP_KERNEL);
+ if (!epd)
+ return -ENOMEM;
+
+ epd->spi = spi;
+
+ epd->panel_on = devm_gpiod_get(dev, "panel-on", GPIOD_OUT_LOW);
+ if (IS_ERR(epd->panel_on)) {
+ ret = PTR_ERR(epd->panel_on);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Failed to get gpio 'panel-on'\n");
+ return ret;
+ }
+
+ epd->discharge = devm_gpiod_get(dev, "discharge", GPIOD_OUT_LOW);
+ if (IS_ERR(epd->discharge)) {
+ ret = PTR_ERR(epd->discharge);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Failed to get gpio 'discharge'\n");
+ return ret;
+ }
+
+ epd->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(epd->reset)) {
+ ret = PTR_ERR(epd->reset);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Failed to get gpio 'reset'\n");
+ return ret;
+ }
+
+ epd->busy = devm_gpiod_get(dev, "busy", GPIOD_IN);
+ if (IS_ERR(epd->busy)) {
+ ret = PTR_ERR(epd->busy);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Failed to get gpio 'busy'\n");
+ return ret;
+ }
+
+ if (!device_property_read_string(dev, "pervasive,thermal-zone",
+ &thermal_zone)) {
+ epd->thermal = thermal_zone_get_zone_by_name(thermal_zone);
+ if (IS_ERR(epd->thermal)) {
+ dev_err(dev, "Failed to get thermal zone: %s\n",
+ thermal_zone);
+ return PTR_ERR(epd->thermal);
+ }
+ }
+
+ switch (model) {
+ case E1144CS021:
+ mode = &repaper_e1144cs021_mode;
+ epd->channel_select = repaper_e1144cs021_cs;
+ epd->stage_time = 480;
+ epd->bytes_per_scan = 96 / 4;
+ epd->middle_scan = true; /* data-scan-data */
+ epd->pre_border_byte = false;
+ epd->border_byte = REPAPER_BORDER_BYTE_ZERO;
+ break;
+
+ case E1190CS021:
+ mode = &repaper_e1190cs021_mode;
+ epd->channel_select = repaper_e1190cs021_cs;
+ epd->stage_time = 480;
+ epd->bytes_per_scan = 128 / 4 / 2;
+ epd->middle_scan = false; /* scan-data-scan */
+ epd->pre_border_byte = false;
+ epd->border_byte = REPAPER_BORDER_BYTE_SET;
+ break;
+
+ case E2200CS021:
+ mode = &repaper_e2200cs021_mode;
+ epd->channel_select = repaper_e2200cs021_cs;
+ epd->stage_time = 480;
+ epd->bytes_per_scan = 96 / 4;
+ epd->middle_scan = true; /* data-scan-data */
+ epd->pre_border_byte = true;
+ epd->border_byte = REPAPER_BORDER_BYTE_NONE;
+ break;
+
+ case E2271CS021:
+ epd->border = devm_gpiod_get(dev, "border", GPIOD_OUT_LOW);
+ if (IS_ERR(epd->border)) {
+ ret = PTR_ERR(epd->border);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Failed to get gpio 'border'\n");
+ return ret;
+ }
+
+ mode = &repaper_e2271cs021_mode;
+ epd->channel_select = repaper_e2271cs021_cs;
+ epd->stage_time = 630;
+ epd->bytes_per_scan = 176 / 4;
+ epd->middle_scan = true; /* data-scan-data */
+ epd->pre_border_byte = true;
+ epd->border_byte = REPAPER_BORDER_BYTE_NONE;
+ break;
+
+ default:
+ return -ENODEV;
+ }
+
+ epd->width = mode->hdisplay;
+ epd->height = mode->vdisplay;
+ epd->factored_stage_time = epd->stage_time;
+
+ line_buffer_size = 2 * epd->width / 8 + epd->bytes_per_scan + 2;
+ epd->line_buffer = devm_kzalloc(dev, line_buffer_size, GFP_KERNEL);
+ if (!epd->line_buffer)
+ return -ENOMEM;
+
+ epd->current_frame = devm_kzalloc(dev, epd->width * epd->height / 8,
+ GFP_KERNEL);
+ if (!epd->current_frame)
+ return -ENOMEM;
+
+ tdev = &epd->tinydrm;
+
+ ret = devm_tinydrm_init(dev, tdev, &repaper_fb_funcs, &repaper_driver);
+ if (ret)
+ return ret;
+
+ ret = tinydrm_display_pipe_init(tdev, &repaper_pipe_funcs,
+ DRM_MODE_CONNECTOR_VIRTUAL,
+ repaper_formats,
+ ARRAY_SIZE(repaper_formats), mode, 0);
+ if (ret)
+ return ret;
+
+ drm_mode_config_reset(tdev->drm);
+
+ ret = devm_tinydrm_register(tdev);
+ if (ret)
+ return ret;
+
+ spi_set_drvdata(spi, tdev);
+
+ DRM_DEBUG_DRIVER("Initialized %s:%s @%uMHz on minor %d\n",
+ tdev->drm->driver->name, dev_name(dev),
+ spi->max_speed_hz / 1000000,
+ tdev->drm->primary->index);
+
+ return 0;
+}
+
+static void repaper_shutdown(struct spi_device *spi)
+{
+ struct tinydrm_device *tdev = spi_get_drvdata(spi);
+
+ tinydrm_shutdown(tdev);
+}
+
+static struct spi_driver repaper_spi_driver = {
+ .driver = {
+ .name = "repaper",
+ .owner = THIS_MODULE,
+ .of_match_table = repaper_of_match,
+ },
+ .id_table = repaper_id,
+ .probe = repaper_probe,
+ .shutdown = repaper_shutdown,
+};
+module_spi_driver(repaper_spi_driver);
+
+MODULE_DESCRIPTION("Pervasive Displays RePaper DRM driver");
+MODULE_AUTHOR("Noralf Trønnes");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tinydrm/st7586.c b/drivers/gpu/drm/tinydrm/st7586.c
new file mode 100644
index 0000000..b439956
--- /dev/null
+++ b/drivers/gpu/drm/tinydrm/st7586.c
@@ -0,0 +1,428 @@
+/*
+ * DRM driver for Sitronix ST7586 panels
+ *
+ * Copyright 2017 David Lechner <david@lechnology.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/delay.h>
+#include <linux/dma-buf.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/property.h>
+#include <linux/spi/spi.h>
+#include <video/mipi_display.h>
+
+#include <drm/tinydrm/mipi-dbi.h>
+#include <drm/tinydrm/tinydrm-helpers.h>
+
+/* controller-specific commands */
+#define ST7586_DISP_MODE_GRAY 0x38
+#define ST7586_DISP_MODE_MONO 0x39
+#define ST7586_ENABLE_DDRAM 0x3a
+#define ST7586_SET_DISP_DUTY 0xb0
+#define ST7586_SET_PART_DISP 0xb4
+#define ST7586_SET_NLINE_INV 0xb5
+#define ST7586_SET_VOP 0xc0
+#define ST7586_SET_BIAS_SYSTEM 0xc3
+#define ST7586_SET_BOOST_LEVEL 0xc4
+#define ST7586_SET_VOP_OFFSET 0xc7
+#define ST7586_ENABLE_ANALOG 0xd0
+#define ST7586_AUTO_READ_CTRL 0xd7
+#define ST7586_OTP_RW_CTRL 0xe0
+#define ST7586_OTP_CTRL_OUT 0xe1
+#define ST7586_OTP_READ 0xe3
+
+#define ST7586_DISP_CTRL_MX BIT(6)
+#define ST7586_DISP_CTRL_MY BIT(7)
+
+/*
+ * The ST7586 controller has an unusual pixel format where 2bpp grayscale is
+ * packed 3 pixels per byte with the first two pixels using 3 bits and the 3rd
+ * pixel using only 2 bits.
+ *
+ * | D7 | D6 | D5 || | || 2bpp |
+ * | (D4) | (D3) | (D2) || D1 | D0 || GRAY |
+ * +------+------+------++------+------++------+
+ * | 1 | 1 | 1 || 1 | 1 || 0 0 | black
+ * | 1 | 0 | 0 || 1 | 0 || 0 1 | dark gray
+ * | 0 | 1 | 0 || 0 | 1 || 1 0 | light gray
+ * | 0 | 0 | 0 || 0 | 0 || 1 1 | white
+ */
+
+static const u8 st7586_lookup[] = { 0x7, 0x4, 0x2, 0x0 };
+
+static void st7586_xrgb8888_to_gray332(u8 *dst, void *vaddr,
+ struct drm_framebuffer *fb,
+ struct drm_clip_rect *clip)
+{
+ size_t len = (clip->x2 - clip->x1) * (clip->y2 - clip->y1);
+ unsigned int x, y;
+ u8 *src, *buf, val;
+
+ buf = kmalloc(len, GFP_KERNEL);
+ if (!buf)
+ return;
+
+ tinydrm_xrgb8888_to_gray8(buf, vaddr, fb, clip);
+ src = buf;
+
+ for (y = clip->y1; y < clip->y2; y++) {
+ for (x = clip->x1; x < clip->x2; x += 3) {
+ val = st7586_lookup[*src++ >> 6] << 5;
+ val |= st7586_lookup[*src++ >> 6] << 2;
+ val |= st7586_lookup[*src++ >> 6] >> 1;
+ *dst++ = val;
+ }
+ }
+
+ kfree(buf);
+}
+
+static int st7586_buf_copy(void *dst, struct drm_framebuffer *fb,
+ struct drm_clip_rect *clip)
+{
+ struct drm_gem_cma_object *cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
+ struct dma_buf_attachment *import_attach = cma_obj->base.import_attach;
+ void *src = cma_obj->vaddr;
+ int ret = 0;
+
+ if (import_attach) {
+ ret = dma_buf_begin_cpu_access(import_attach->dmabuf,
+ DMA_FROM_DEVICE);
+ if (ret)
+ return ret;
+ }
+
+ st7586_xrgb8888_to_gray332(dst, src, fb, clip);
+
+ if (import_attach)
+ ret = dma_buf_end_cpu_access(import_attach->dmabuf,
+ DMA_FROM_DEVICE);
+
+ return ret;
+}
+
+static int st7586_fb_dirty(struct drm_framebuffer *fb,
+ struct drm_file *file_priv, unsigned int flags,
+ unsigned int color, struct drm_clip_rect *clips,
+ unsigned int num_clips)
+{
+ struct tinydrm_device *tdev = fb->dev->dev_private;
+ struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
+ struct drm_clip_rect clip;
+ int start, end;
+ int ret = 0;
+
+ mutex_lock(&tdev->dirty_lock);
+
+ if (!mipi->enabled)
+ goto out_unlock;
+
+ /* fbdev can flush even when we're not interested */
+ if (tdev->pipe.plane.fb != fb)
+ goto out_unlock;
+
+ tinydrm_merge_clips(&clip, clips, num_clips, flags, fb->width,
+ fb->height);
+
+ /* 3 pixels per byte, so grow clip to nearest multiple of 3 */
+ clip.x1 = rounddown(clip.x1, 3);
+ clip.x2 = roundup(clip.x2, 3);
+
+ DRM_DEBUG("Flushing [FB:%d] x1=%u, x2=%u, y1=%u, y2=%u\n", fb->base.id,
+ clip.x1, clip.x2, clip.y1, clip.y2);
+
+ ret = st7586_buf_copy(mipi->tx_buf, fb, &clip);
+ if (ret)
+ goto out_unlock;
+
+ /* Pixels are packed 3 per byte */
+ start = clip.x1 / 3;
+ end = clip.x2 / 3;
+
+ mipi_dbi_command(mipi, MIPI_DCS_SET_COLUMN_ADDRESS,
+ (start >> 8) & 0xFF, start & 0xFF,
+ (end >> 8) & 0xFF, (end - 1) & 0xFF);
+ mipi_dbi_command(mipi, MIPI_DCS_SET_PAGE_ADDRESS,
+ (clip.y1 >> 8) & 0xFF, clip.y1 & 0xFF,
+ (clip.y2 >> 8) & 0xFF, (clip.y2 - 1) & 0xFF);
+
+ ret = mipi_dbi_command_buf(mipi, MIPI_DCS_WRITE_MEMORY_START,
+ (u8 *)mipi->tx_buf,
+ (end - start) * (clip.y2 - clip.y1));
+
+out_unlock:
+ mutex_unlock(&tdev->dirty_lock);
+
+ if (ret)
+ dev_err_once(fb->dev->dev, "Failed to update display %d\n",
+ ret);
+
+ return ret;
+}
+
+static const struct drm_framebuffer_funcs st7586_fb_funcs = {
+ .destroy = drm_fb_cma_destroy,
+ .create_handle = drm_fb_cma_create_handle,
+ .dirty = st7586_fb_dirty,
+};
+
+static void st7586_pipe_enable(struct drm_simple_display_pipe *pipe,
+ struct drm_crtc_state *crtc_state)
+{
+ struct tinydrm_device *tdev = pipe_to_tinydrm(pipe);
+ struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
+ struct drm_framebuffer *fb = pipe->plane.fb;
+ struct device *dev = tdev->drm->dev;
+ int ret;
+ u8 addr_mode;
+
+ DRM_DEBUG_KMS("\n");
+
+ mipi_dbi_hw_reset(mipi);
+ ret = mipi_dbi_command(mipi, ST7586_AUTO_READ_CTRL, 0x9f);
+ if (ret) {
+ dev_err(dev, "Error sending command %d\n", ret);
+ return;
+ }
+
+ mipi_dbi_command(mipi, ST7586_OTP_RW_CTRL, 0x00);
+
+ msleep(10);
+
+ mipi_dbi_command(mipi, ST7586_OTP_READ);
+
+ msleep(20);
+
+ mipi_dbi_command(mipi, ST7586_OTP_CTRL_OUT);
+ mipi_dbi_command(mipi, MIPI_DCS_EXIT_SLEEP_MODE);
+ mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_OFF);
+
+ msleep(50);
+
+ mipi_dbi_command(mipi, ST7586_SET_VOP_OFFSET, 0x00);
+ mipi_dbi_command(mipi, ST7586_SET_VOP, 0xe3, 0x00);
+ mipi_dbi_command(mipi, ST7586_SET_BIAS_SYSTEM, 0x02);
+ mipi_dbi_command(mipi, ST7586_SET_BOOST_LEVEL, 0x04);
+ mipi_dbi_command(mipi, ST7586_ENABLE_ANALOG, 0x1d);
+ mipi_dbi_command(mipi, ST7586_SET_NLINE_INV, 0x00);
+ mipi_dbi_command(mipi, ST7586_DISP_MODE_GRAY);
+ mipi_dbi_command(mipi, ST7586_ENABLE_DDRAM, 0x02);
+
+ switch (mipi->rotation) {
+ default:
+ addr_mode = 0x00;
+ break;
+ case 90:
+ addr_mode = ST7586_DISP_CTRL_MY;
+ break;
+ case 180:
+ addr_mode = ST7586_DISP_CTRL_MX | ST7586_DISP_CTRL_MY;
+ break;
+ case 270:
+ addr_mode = ST7586_DISP_CTRL_MX;
+ break;
+ }
+ mipi_dbi_command(mipi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
+
+ mipi_dbi_command(mipi, ST7586_SET_DISP_DUTY, 0x7f);
+ mipi_dbi_command(mipi, ST7586_SET_PART_DISP, 0xa0);
+ mipi_dbi_command(mipi, MIPI_DCS_SET_PARTIAL_AREA, 0x00, 0x00, 0x00, 0x77);
+ mipi_dbi_command(mipi, MIPI_DCS_EXIT_INVERT_MODE);
+
+ msleep(100);
+
+ mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_ON);
+
+ mipi->enabled = true;
+
+ if (fb)
+ fb->funcs->dirty(fb, NULL, 0, 0, NULL, 0);
+}
+
+static void st7586_pipe_disable(struct drm_simple_display_pipe *pipe)
+{
+ struct tinydrm_device *tdev = pipe_to_tinydrm(pipe);
+ struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
+
+ DRM_DEBUG_KMS("\n");
+
+ if (!mipi->enabled)
+ return;
+
+ mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_OFF);
+ mipi->enabled = false;
+}
+
+static const u32 st7586_formats[] = {
+ DRM_FORMAT_XRGB8888,
+};
+
+static int st7586_init(struct device *dev, struct mipi_dbi *mipi,
+ const struct drm_simple_display_pipe_funcs *pipe_funcs,
+ struct drm_driver *driver, const struct drm_display_mode *mode,
+ unsigned int rotation)
+{
+ size_t bufsize = (mode->vdisplay + 2) / 3 * mode->hdisplay;
+ struct tinydrm_device *tdev = &mipi->tinydrm;
+ int ret;
+
+ mutex_init(&mipi->cmdlock);
+
+ mipi->tx_buf = devm_kmalloc(dev, bufsize, GFP_KERNEL);
+ if (!mipi->tx_buf)
+ return -ENOMEM;
+
+ ret = devm_tinydrm_init(dev, tdev, &st7586_fb_funcs, driver);
+ if (ret)
+ return ret;
+
+ ret = tinydrm_display_pipe_init(tdev, pipe_funcs,
+ DRM_MODE_CONNECTOR_VIRTUAL,
+ st7586_formats,
+ ARRAY_SIZE(st7586_formats),
+ mode, rotation);
+ if (ret)
+ return ret;
+
+ tdev->drm->mode_config.preferred_depth = 32;
+ mipi->rotation = rotation;
+
+ drm_mode_config_reset(tdev->drm);
+
+ DRM_DEBUG_KMS("preferred_depth=%u, rotation = %u\n",
+ tdev->drm->mode_config.preferred_depth, rotation);
+
+ return 0;
+}
+
+static const struct drm_simple_display_pipe_funcs st7586_pipe_funcs = {
+ .enable = st7586_pipe_enable,
+ .disable = st7586_pipe_disable,
+ .update = tinydrm_display_pipe_update,
+ .prepare_fb = tinydrm_display_pipe_prepare_fb,
+};
+
+static const struct drm_display_mode st7586_mode = {
+ TINYDRM_MODE(178, 128, 37, 27),
+};
+
+DEFINE_DRM_GEM_CMA_FOPS(st7586_fops);
+
+static struct drm_driver st7586_driver = {
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
+ DRIVER_ATOMIC,
+ .fops = &st7586_fops,
+ TINYDRM_GEM_DRIVER_OPS,
+ .lastclose = tinydrm_lastclose,
+ .debugfs_init = mipi_dbi_debugfs_init,
+ .name = "st7586",
+ .desc = "Sitronix ST7586",
+ .date = "20170801",
+ .major = 1,
+ .minor = 0,
+};
+
+static const struct of_device_id st7586_of_match[] = {
+ { .compatible = "lego,ev3-lcd" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, st7586_of_match);
+
+static const struct spi_device_id st7586_id[] = {
+ { "ev3-lcd", 0 },
+ { },
+};
+MODULE_DEVICE_TABLE(spi, st7586_id);
+
+static int st7586_probe(struct spi_device *spi)
+{
+ struct device *dev = &spi->dev;
+ struct tinydrm_device *tdev;
+ struct mipi_dbi *mipi;
+ struct gpio_desc *a0;
+ u32 rotation = 0;
+ int ret;
+
+ mipi = devm_kzalloc(dev, sizeof(*mipi), GFP_KERNEL);
+ if (!mipi)
+ return -ENOMEM;
+
+ mipi->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+ if (IS_ERR(mipi->reset)) {
+ dev_err(dev, "Failed to get gpio 'reset'\n");
+ return PTR_ERR(mipi->reset);
+ }
+
+ a0 = devm_gpiod_get(dev, "a0", GPIOD_OUT_LOW);
+ if (IS_ERR(a0)) {
+ dev_err(dev, "Failed to get gpio 'a0'\n");
+ return PTR_ERR(a0);
+ }
+
+ device_property_read_u32(dev, "rotation", &rotation);
+
+ ret = mipi_dbi_spi_init(spi, mipi, a0);
+ if (ret)
+ return ret;
+
+ /* Cannot read from this controller via SPI */
+ mipi->read_commands = NULL;
+
+ /*
+ * we are using 8-bit data, so we are not actually swapping anything,
+ * but setting mipi->swap_bytes makes mipi_dbi_typec3_command() do the
+ * right thing and not use 16-bit transfers (which results in swapped
+ * bytes on little-endian systems and causes out of order data to be
+ * sent to the display).
+ */
+ mipi->swap_bytes = true;
+
+ ret = st7586_init(&spi->dev, mipi, &st7586_pipe_funcs, &st7586_driver,
+ &st7586_mode, rotation);
+ if (ret)
+ return ret;
+
+ tdev = &mipi->tinydrm;
+
+ ret = devm_tinydrm_register(tdev);
+ if (ret)
+ return ret;
+
+ spi_set_drvdata(spi, mipi);
+
+ DRM_DEBUG_DRIVER("Initialized %s:%s @%uMHz on minor %d\n",
+ tdev->drm->driver->name, dev_name(dev),
+ spi->max_speed_hz / 1000000,
+ tdev->drm->primary->index);
+
+ return 0;
+}
+
+static void st7586_shutdown(struct spi_device *spi)
+{
+ struct mipi_dbi *mipi = spi_get_drvdata(spi);
+
+ tinydrm_shutdown(&mipi->tinydrm);
+}
+
+static struct spi_driver st7586_spi_driver = {
+ .driver = {
+ .name = "st7586",
+ .owner = THIS_MODULE,
+ .of_match_table = st7586_of_match,
+ },
+ .id_table = st7586_id,
+ .probe = st7586_probe,
+ .shutdown = st7586_shutdown,
+};
+module_spi_driver(st7586_spi_driver);
+
+MODULE_DESCRIPTION("Sitronix ST7586 DRM driver");
+MODULE_AUTHOR("David Lechner <david@lechnology.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 22b5702..cba11f1 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -70,6 +70,7 @@ static inline int ttm_mem_type_from_place(const struct ttm_place *place,
static void ttm_mem_type_debug(struct ttm_bo_device *bdev, int mem_type)
{
struct ttm_mem_type_manager *man = &bdev->man[mem_type];
+ struct drm_printer p = drm_debug_printer(TTM_PFX);
pr_err(" has_type: %d\n", man->has_type);
pr_err(" use_type: %d\n", man->use_type);
@@ -79,7 +80,7 @@ static void ttm_mem_type_debug(struct ttm_bo_device *bdev, int mem_type)
pr_err(" available_caching: 0x%08X\n", man->available_caching);
pr_err(" default_caching: 0x%08X\n", man->default_caching);
if (mem_type != TTM_PL_SYSTEM)
- (*man->func->debug)(man, TTM_PFX);
+ (*man->func->debug)(man, &p);
}
static void ttm_bo_mem_space_debug(struct ttm_buffer_object *bo,
@@ -394,14 +395,33 @@ static void ttm_bo_cleanup_memtype_use(struct ttm_buffer_object *bo)
ww_mutex_unlock (&bo->resv->lock);
}
+static int ttm_bo_individualize_resv(struct ttm_buffer_object *bo)
+{
+ int r;
+
+ if (bo->resv == &bo->ttm_resv)
+ return 0;
+
+ reservation_object_init(&bo->ttm_resv);
+ BUG_ON(!reservation_object_trylock(&bo->ttm_resv));
+
+ r = reservation_object_copy_fences(&bo->ttm_resv, bo->resv);
+ if (r) {
+ reservation_object_unlock(&bo->ttm_resv);
+ reservation_object_fini(&bo->ttm_resv);
+ }
+
+ return r;
+}
+
static void ttm_bo_flush_all_fences(struct ttm_buffer_object *bo)
{
struct reservation_object_list *fobj;
struct dma_fence *fence;
int i;
- fobj = reservation_object_get_list(bo->resv);
- fence = reservation_object_get_excl(bo->resv);
+ fobj = reservation_object_get_list(&bo->ttm_resv);
+ fence = reservation_object_get_excl(&bo->ttm_resv);
if (fence && !fence->ops->signaled)
dma_fence_enable_sw_signaling(fence);
@@ -430,8 +450,19 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo)
ttm_bo_cleanup_memtype_use(bo);
return;
- } else
- ttm_bo_flush_all_fences(bo);
+ }
+
+ ret = ttm_bo_individualize_resv(bo);
+ if (ret) {
+ /* Last resort, if we fail to allocate memory for the
+ * fences block for the BO to become idle and free it.
+ */
+ spin_unlock(&glob->lru_lock);
+ ttm_bo_wait(bo, true, true);
+ ttm_bo_cleanup_memtype_use(bo);
+ return;
+ }
+ ttm_bo_flush_all_fences(bo);
/*
* Make NO_EVICT bos immediately available to
@@ -443,6 +474,8 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo)
ttm_bo_add_to_lru(bo);
}
+ if (bo->resv != &bo->ttm_resv)
+ reservation_object_unlock(&bo->ttm_resv);
__ttm_bo_unreserve(bo);
}
@@ -471,17 +504,25 @@ static int ttm_bo_cleanup_refs_and_unlock(struct ttm_buffer_object *bo,
bool no_wait_gpu)
{
struct ttm_bo_global *glob = bo->glob;
+ struct reservation_object *resv;
int ret;
- ret = ttm_bo_wait(bo, false, true);
+ if (unlikely(list_empty(&bo->ddestroy)))
+ resv = bo->resv;
+ else
+ resv = &bo->ttm_resv;
+
+ if (reservation_object_test_signaled_rcu(resv, true))
+ ret = 0;
+ else
+ ret = -EBUSY;
if (ret && !no_wait_gpu) {
long lret;
ww_mutex_unlock(&bo->resv->lock);
spin_unlock(&glob->lru_lock);
- lret = reservation_object_wait_timeout_rcu(bo->resv,
- true,
+ lret = reservation_object_wait_timeout_rcu(resv, true,
interruptible,
30 * HZ);
@@ -505,13 +546,6 @@ static int ttm_bo_cleanup_refs_and_unlock(struct ttm_buffer_object *bo,
spin_unlock(&glob->lru_lock);
return 0;
}
-
- /*
- * remove sync_obj with ttm_bo_wait, the wait should be
- * finished, and no new wait object should have been added.
- */
- ret = ttm_bo_wait(bo, false, true);
- WARN_ON(ret);
}
if (ret || unlikely(list_empty(&bo->ddestroy))) {
diff --git a/drivers/gpu/drm/ttm/ttm_bo_manager.c b/drivers/gpu/drm/ttm/ttm_bo_manager.c
index 90a6c0b..a7c232d 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_manager.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_manager.c
@@ -136,13 +136,12 @@ static int ttm_bo_man_takedown(struct ttm_mem_type_manager *man)
}
static void ttm_bo_man_debug(struct ttm_mem_type_manager *man,
- const char *prefix)
+ struct drm_printer *printer)
{
struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv;
- struct drm_printer p = drm_debug_printer(prefix);
spin_lock(&rman->lock);
- drm_mm_print(&rman->mm, &p);
+ drm_mm_print(&rman->mm, printer);
spin_unlock(&rman->lock);
}
diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c
index b442d12..c8ebb75 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_vm.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c
@@ -39,6 +39,7 @@
#include <linux/rbtree.h>
#include <linux/module.h>
#include <linux/uaccess.h>
+#include <linux/mem_encrypt.h>
#define TTM_BO_VM_NUM_PREFAULT 16
@@ -230,9 +231,11 @@ static int ttm_bo_vm_fault(struct vm_fault *vmf)
* first page.
*/
for (i = 0; i < TTM_BO_VM_NUM_PREFAULT; ++i) {
- if (bo->mem.bus.is_iomem)
+ if (bo->mem.bus.is_iomem) {
+ /* Iomem should not be marked encrypted */
+ cvma.vm_page_prot = pgprot_decrypted(cvma.vm_page_prot);
pfn = bdev->driver->io_mem_pfn(bo, page_offset);
- else {
+ } else {
page = ttm->pages[page_offset];
if (unlikely(!page && i == 0)) {
retval = VM_FAULT_OOM;
@@ -294,10 +297,87 @@ static void ttm_bo_vm_close(struct vm_area_struct *vma)
vma->vm_private_data = NULL;
}
+static int ttm_bo_vm_access_kmap(struct ttm_buffer_object *bo,
+ unsigned long offset,
+ void *buf, int len, int write)
+{
+ unsigned long page = offset >> PAGE_SHIFT;
+ unsigned long bytes_left = len;
+ int ret;
+
+ /* Copy a page at a time, that way no extra virtual address
+ * mapping is needed
+ */
+ offset -= page << PAGE_SHIFT;
+ do {
+ unsigned long bytes = min(bytes_left, PAGE_SIZE - offset);
+ struct ttm_bo_kmap_obj map;
+ void *ptr;
+ bool is_iomem;
+
+ ret = ttm_bo_kmap(bo, page, 1, &map);
+ if (ret)
+ return ret;
+
+ ptr = (uint8_t *)ttm_kmap_obj_virtual(&map, &is_iomem) + offset;
+ WARN_ON_ONCE(is_iomem);
+ if (write)
+ memcpy(ptr, buf, bytes);
+ else
+ memcpy(buf, ptr, bytes);
+ ttm_bo_kunmap(&map);
+
+ page++;
+ bytes_left -= bytes;
+ offset = 0;
+ } while (bytes_left);
+
+ return len;
+}
+
+static int ttm_bo_vm_access(struct vm_area_struct *vma, unsigned long addr,
+ void *buf, int len, int write)
+{
+ unsigned long offset = (addr) - vma->vm_start;
+ struct ttm_buffer_object *bo = vma->vm_private_data;
+ int ret;
+
+ if (len < 1 || (offset + len) >> PAGE_SHIFT > bo->num_pages)
+ return -EIO;
+
+ ret = ttm_bo_reserve(bo, true, false, NULL);
+ if (ret)
+ return ret;
+
+ switch (bo->mem.mem_type) {
+ case TTM_PL_SYSTEM:
+ if (unlikely(bo->ttm->page_flags & TTM_PAGE_FLAG_SWAPPED)) {
+ ret = ttm_tt_swapin(bo->ttm);
+ if (unlikely(ret != 0))
+ return ret;
+ }
+ /* fall through */
+ case TTM_PL_TT:
+ ret = ttm_bo_vm_access_kmap(bo, offset, buf, len, write);
+ break;
+ default:
+ if (bo->bdev->driver->access_memory)
+ ret = bo->bdev->driver->access_memory(
+ bo, offset, buf, len, write);
+ else
+ ret = -EIO;
+ }
+
+ ttm_bo_unreserve(bo);
+
+ return ret;
+}
+
static const struct vm_operations_struct ttm_bo_vm_ops = {
.fault = ttm_bo_vm_fault,
.open = ttm_bo_vm_open,
- .close = ttm_bo_vm_close
+ .close = ttm_bo_vm_close,
+ .access = ttm_bo_vm_access
};
static struct ttm_buffer_object *ttm_bo_vm_lookup(struct ttm_bo_device *bdev,
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c
index eeddc1e..8715998 100644
--- a/drivers/gpu/drm/ttm/ttm_page_alloc.c
+++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c
@@ -615,7 +615,7 @@ static void ttm_page_pool_fill_locked(struct ttm_page_pool *pool,
} else {
pr_err("Failed to fill pool (%p)\n", pool);
/* If we have any pages left put them to the pool. */
- list_for_each_entry(p, &pool->list, lru) {
+ list_for_each_entry(p, &new_pages, lru) {
++cpages;
}
list_splice(&new_pages, &pool->list);
diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c
index d2f57c5..9f9a497 100644
--- a/drivers/gpu/drm/udl/udl_connector.c
+++ b/drivers/gpu/drm/udl/udl_connector.c
@@ -96,7 +96,7 @@ static int udl_mode_valid(struct drm_connector *connector,
static enum drm_connector_status
udl_detect(struct drm_connector *connector, bool force)
{
- if (drm_device_is_unplugged(connector->dev))
+ if (drm_dev_is_unplugged(connector->dev))
return connector_status_disconnected;
return connector_status_connected;
}
diff --git a/drivers/gpu/drm/udl/udl_dmabuf.c b/drivers/gpu/drm/udl/udl_dmabuf.c
index 2e031a8..2867ed1 100644
--- a/drivers/gpu/drm/udl/udl_dmabuf.c
+++ b/drivers/gpu/drm/udl/udl_dmabuf.c
@@ -186,7 +186,7 @@ static int udl_dmabuf_mmap(struct dma_buf *dma_buf,
return -EINVAL;
}
-static struct dma_buf_ops udl_dmabuf_ops = {
+static const struct dma_buf_ops udl_dmabuf_ops = {
.attach = udl_attach_dma_buf,
.detach = udl_detach_dma_buf,
.map_dma_buf = udl_map_dma_buf,
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index cd8b017..31421b6 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -11,11 +11,6 @@
#include <drm/drm_crtc_helper.h>
#include "udl_drv.h"
-static int udl_driver_set_busid(struct drm_device *d, struct drm_master *m)
-{
- return 0;
-}
-
static int udl_usb_suspend(struct usb_interface *interface,
pm_message_t message)
{
@@ -52,7 +47,6 @@ static struct drm_driver driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
.load = udl_driver_load,
.unload = udl_driver_unload,
- .set_busid = udl_driver_set_busid,
/* gem hooks */
.gem_free_object = udl_gem_free_object,
@@ -60,7 +54,6 @@ static struct drm_driver driver = {
.dumb_create = udl_dumb_create,
.dumb_map_offset = udl_gem_mmap,
- .dumb_destroy = drm_gem_dumb_destroy,
.fops = &udl_driver_fops,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
@@ -108,7 +101,7 @@ static void udl_usb_disconnect(struct usb_interface *interface)
drm_kms_helper_poll_disable(dev);
udl_fbdev_unplug(dev);
udl_drop_usb(dev);
- drm_unplug_dev(dev);
+ drm_dev_unplug(dev);
}
/*
@@ -118,7 +111,7 @@ static void udl_usb_disconnect(struct usb_interface *interface)
* which is compatible with all known USB 2.0 era graphics chips and firmware,
* but allows DisplayLink to increment those for any future incompatible chips
*/
-static struct usb_device_id id_table[] = {
+static const struct usb_device_id id_table[] = {
{.idVendor = 0x17e9, .bInterfaceClass = 0xff,
.bInterfaceSubClass = 0x00,
.bInterfaceProtocol = 0x00,
diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c
index 4a65003..b5b335c 100644
--- a/drivers/gpu/drm/udl/udl_fb.c
+++ b/drivers/gpu/drm/udl/udl_fb.c
@@ -14,6 +14,7 @@
#include <linux/slab.h>
#include <linux/fb.h>
#include <linux/dma-buf.h>
+#include <linux/mem_encrypt.h>
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
@@ -169,6 +170,9 @@ static int udl_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
pr_notice("mmap() framebuffer addr:%lu size:%lu\n",
pos, size);
+ /* We don't want the framebuffer to be mapped encrypted */
+ vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
+
while (size > 0) {
page = vmalloc_to_pfn((void *)pos);
if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
@@ -198,7 +202,7 @@ static int udl_fb_open(struct fb_info *info, int user)
struct udl_device *udl = dev->dev_private;
/* If the USB device is gone, we don't accept new opens */
- if (drm_device_is_unplugged(udl->ddev))
+ if (drm_dev_is_unplugged(udl->ddev))
return -ENODEV;
ufbdev->fb_count++;
@@ -309,7 +313,7 @@ static void udl_user_framebuffer_destroy(struct drm_framebuffer *fb)
struct udl_framebuffer *ufb = to_udl_fb(fb);
if (ufb->obj)
- drm_gem_object_unreference_unlocked(&ufb->obj->base);
+ drm_gem_object_put_unlocked(&ufb->obj->base);
drm_framebuffer_cleanup(fb);
kfree(ufb);
@@ -393,7 +397,6 @@ static int udlfb_create(struct drm_fb_helper *helper,
info->fix.smem_len = size;
info->fix.smem_start = (unsigned long)ufbdev->ufb.obj->vmapping;
- info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
info->fbops = &udlfb_ops;
drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth);
drm_fb_helper_fill_var(info, &ufbdev->helper, sizes->fb_width, sizes->fb_height);
@@ -404,7 +407,7 @@ static int udlfb_create(struct drm_fb_helper *helper,
return ret;
out_gfree:
- drm_gem_object_unreference_unlocked(&ufbdev->ufb.obj->base);
+ drm_gem_object_put_unlocked(&ufbdev->ufb.obj->base);
out:
return ret;
}
@@ -420,7 +423,7 @@ static void udl_fbdev_destroy(struct drm_device *dev,
drm_fb_helper_fini(&ufbdev->helper);
drm_framebuffer_unregister_private(&ufbdev->ufb.base);
drm_framebuffer_cleanup(&ufbdev->ufb.base);
- drm_gem_object_unreference_unlocked(&ufbdev->ufb.obj->base);
+ drm_gem_object_put_unlocked(&ufbdev->ufb.obj->base);
}
int udl_fbdev_init(struct drm_device *dev)
diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c
index db9cece..dee6bd9 100644
--- a/drivers/gpu/drm/udl/udl_gem.c
+++ b/drivers/gpu/drm/udl/udl_gem.c
@@ -52,7 +52,7 @@ udl_gem_create(struct drm_file *file,
return ret;
}
- drm_gem_object_unreference_unlocked(&obj->base);
+ drm_gem_object_put_unlocked(&obj->base);
*handle_p = handle;
return 0;
}
@@ -234,7 +234,7 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev,
*offset = drm_vma_node_offset_addr(&gobj->base.vma_node);
out:
- drm_gem_object_unreference(&gobj->base);
+ drm_gem_object_put(&gobj->base);
unlock:
mutex_unlock(&dev->struct_mutex);
return ret;
diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
index a9d93b8..0328b2c 100644
--- a/drivers/gpu/drm/udl/udl_main.c
+++ b/drivers/gpu/drm/udl/udl_main.c
@@ -371,8 +371,6 @@ void udl_driver_unload(struct drm_device *dev)
{
struct udl_device *udl = dev->dev_private;
- drm_vblank_cleanup(dev);
-
if (udl->urbs.count)
udl_free_urb_list(dev);
diff --git a/drivers/gpu/drm/vc4/Kconfig b/drivers/gpu/drm/vc4/Kconfig
index 4361bdc..fdae18a 100644
--- a/drivers/gpu/drm/vc4/Kconfig
+++ b/drivers/gpu/drm/vc4/Kconfig
@@ -19,3 +19,11 @@ config DRM_VC4
This driver requires that "avoid_warnings=2" be present in
the config.txt for the firmware, to keep it from smashing
our display setup.
+
+config DRM_VC4_HDMI_CEC
+ bool "Broadcom VC4 HDMI CEC Support"
+ depends on DRM_VC4
+ select CEC_CORE
+ help
+ Choose this option if you have a Broadcom VC4 GPU
+ and want to use CEC.
diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index 487f964..3afdbf4 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -24,21 +24,35 @@
#include "vc4_drv.h"
#include "uapi/drm/vc4_drm.h"
+static const char * const bo_type_names[] = {
+ "kernel",
+ "V3D",
+ "V3D shader",
+ "dumb",
+ "binner",
+ "RCL",
+ "BCL",
+ "kernel BO cache",
+};
+
+static bool is_user_label(int label)
+{
+ return label >= VC4_BO_TYPE_COUNT;
+}
+
static void vc4_bo_stats_dump(struct vc4_dev *vc4)
{
- DRM_INFO("num bos allocated: %d\n",
- vc4->bo_stats.num_allocated);
- DRM_INFO("size bos allocated: %dkb\n",
- vc4->bo_stats.size_allocated / 1024);
- DRM_INFO("num bos used: %d\n",
- vc4->bo_stats.num_allocated - vc4->bo_stats.num_cached);
- DRM_INFO("size bos used: %dkb\n",
- (vc4->bo_stats.size_allocated -
- vc4->bo_stats.size_cached) / 1024);
- DRM_INFO("num bos cached: %d\n",
- vc4->bo_stats.num_cached);
- DRM_INFO("size bos cached: %dkb\n",
- vc4->bo_stats.size_cached / 1024);
+ int i;
+
+ for (i = 0; i < vc4->num_labels; i++) {
+ if (!vc4->bo_labels[i].num_allocated)
+ continue;
+
+ DRM_INFO("%30s: %6dkb BOs (%d)\n",
+ vc4->bo_labels[i].name,
+ vc4->bo_labels[i].size_allocated / 1024,
+ vc4->bo_labels[i].num_allocated);
+ }
}
#ifdef CONFIG_DEBUG_FS
@@ -47,64 +61,133 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *unused)
struct drm_info_node *node = (struct drm_info_node *)m->private;
struct drm_device *dev = node->minor->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);
- struct vc4_bo_stats stats;
+ int i;
- /* Take a snapshot of the current stats with the lock held. */
mutex_lock(&vc4->bo_lock);
- stats = vc4->bo_stats;
+ for (i = 0; i < vc4->num_labels; i++) {
+ if (!vc4->bo_labels[i].num_allocated)
+ continue;
+
+ seq_printf(m, "%30s: %6dkb BOs (%d)\n",
+ vc4->bo_labels[i].name,
+ vc4->bo_labels[i].size_allocated / 1024,
+ vc4->bo_labels[i].num_allocated);
+ }
mutex_unlock(&vc4->bo_lock);
- seq_printf(m, "num bos allocated: %d\n",
- stats.num_allocated);
- seq_printf(m, "size bos allocated: %dkb\n",
- stats.size_allocated / 1024);
- seq_printf(m, "num bos used: %d\n",
- stats.num_allocated - stats.num_cached);
- seq_printf(m, "size bos used: %dkb\n",
- (stats.size_allocated - stats.size_cached) / 1024);
- seq_printf(m, "num bos cached: %d\n",
- stats.num_cached);
- seq_printf(m, "size bos cached: %dkb\n",
- stats.size_cached / 1024);
-
return 0;
}
#endif
+/* Takes ownership of *name and returns the appropriate slot for it in
+ * the bo_labels[] array, extending it as necessary.
+ *
+ * This is inefficient and could use a hash table instead of walking
+ * an array and strcmp()ing. However, the assumption is that user
+ * labeling will be infrequent (scanout buffers and other long-lived
+ * objects, or debug driver builds), so we can live with it for now.
+ */
+static int vc4_get_user_label(struct vc4_dev *vc4, const char *name)
+{
+ int i;
+ int free_slot = -1;
+
+ for (i = 0; i < vc4->num_labels; i++) {
+ if (!vc4->bo_labels[i].name) {
+ free_slot = i;
+ } else if (strcmp(vc4->bo_labels[i].name, name) == 0) {
+ kfree(name);
+ return i;
+ }
+ }
+
+ if (free_slot != -1) {
+ WARN_ON(vc4->bo_labels[free_slot].num_allocated != 0);
+ vc4->bo_labels[free_slot].name = name;
+ return free_slot;
+ } else {
+ u32 new_label_count = vc4->num_labels + 1;
+ struct vc4_label *new_labels =
+ krealloc(vc4->bo_labels,
+ new_label_count * sizeof(*new_labels),
+ GFP_KERNEL);
+
+ if (!new_labels) {
+ kfree(name);
+ return -1;
+ }
+
+ free_slot = vc4->num_labels;
+ vc4->bo_labels = new_labels;
+ vc4->num_labels = new_label_count;
+
+ vc4->bo_labels[free_slot].name = name;
+ vc4->bo_labels[free_slot].num_allocated = 0;
+ vc4->bo_labels[free_slot].size_allocated = 0;
+
+ return free_slot;
+ }
+}
+
+static void vc4_bo_set_label(struct drm_gem_object *gem_obj, int label)
+{
+ struct vc4_bo *bo = to_vc4_bo(gem_obj);
+ struct vc4_dev *vc4 = to_vc4_dev(gem_obj->dev);
+
+ lockdep_assert_held(&vc4->bo_lock);
+
+ if (label != -1) {
+ vc4->bo_labels[label].num_allocated++;
+ vc4->bo_labels[label].size_allocated += gem_obj->size;
+ }
+
+ vc4->bo_labels[bo->label].num_allocated--;
+ vc4->bo_labels[bo->label].size_allocated -= gem_obj->size;
+
+ if (vc4->bo_labels[bo->label].num_allocated == 0 &&
+ is_user_label(bo->label)) {
+ /* Free user BO label slots on last unreference.
+ * Slots are just where we track the stats for a given
+ * name, and once a name is unused we can reuse that
+ * slot.
+ */
+ kfree(vc4->bo_labels[bo->label].name);
+ vc4->bo_labels[bo->label].name = NULL;
+ }
+
+ bo->label = label;
+}
+
static uint32_t bo_page_index(size_t size)
{
return (size / PAGE_SIZE) - 1;
}
-/* Must be called with bo_lock held. */
static void vc4_bo_destroy(struct vc4_bo *bo)
{
struct drm_gem_object *obj = &bo->base.base;
struct vc4_dev *vc4 = to_vc4_dev(obj->dev);
+ lockdep_assert_held(&vc4->bo_lock);
+
+ vc4_bo_set_label(obj, -1);
+
if (bo->validated_shader) {
kfree(bo->validated_shader->texture_samples);
kfree(bo->validated_shader);
bo->validated_shader = NULL;
}
- vc4->bo_stats.num_allocated--;
- vc4->bo_stats.size_allocated -= obj->size;
-
reservation_object_fini(&bo->_resv);
drm_gem_cma_free_object(obj);
}
-/* Must be called with bo_lock held. */
static void vc4_bo_remove_from_cache(struct vc4_bo *bo)
{
- struct drm_gem_object *obj = &bo->base.base;
- struct vc4_dev *vc4 = to_vc4_dev(obj->dev);
-
- vc4->bo_stats.num_cached--;
- vc4->bo_stats.size_cached -= obj->size;
+ struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);
+ lockdep_assert_held(&vc4->bo_lock);
list_del(&bo->unref_head);
list_del(&bo->size_head);
}
@@ -165,7 +248,8 @@ static void vc4_bo_cache_purge(struct drm_device *dev)
}
static struct vc4_bo *vc4_bo_get_from_cache(struct drm_device *dev,
- uint32_t size)
+ uint32_t size,
+ enum vc4_kernel_bo_type type)
{
struct vc4_dev *vc4 = to_vc4_dev(dev);
uint32_t page_index = bo_page_index(size);
@@ -186,6 +270,8 @@ static struct vc4_bo *vc4_bo_get_from_cache(struct drm_device *dev,
kref_init(&bo->base.base.refcount);
out:
+ if (bo)
+ vc4_bo_set_label(&bo->base.base, type);
mutex_unlock(&vc4->bo_lock);
return bo;
}
@@ -208,8 +294,9 @@ struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size)
return ERR_PTR(-ENOMEM);
mutex_lock(&vc4->bo_lock);
- vc4->bo_stats.num_allocated++;
- vc4->bo_stats.size_allocated += size;
+ bo->label = VC4_BO_TYPE_KERNEL;
+ vc4->bo_labels[VC4_BO_TYPE_KERNEL].num_allocated++;
+ vc4->bo_labels[VC4_BO_TYPE_KERNEL].size_allocated += size;
mutex_unlock(&vc4->bo_lock);
bo->resv = &bo->_resv;
reservation_object_init(bo->resv);
@@ -218,7 +305,7 @@ struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size)
}
struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size,
- bool allow_unzeroed)
+ bool allow_unzeroed, enum vc4_kernel_bo_type type)
{
size_t size = roundup(unaligned_size, PAGE_SIZE);
struct vc4_dev *vc4 = to_vc4_dev(dev);
@@ -229,7 +316,7 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size,
return ERR_PTR(-EINVAL);
/* First, try to get a vc4_bo from the kernel BO cache. */
- bo = vc4_bo_get_from_cache(dev, size);
+ bo = vc4_bo_get_from_cache(dev, size, type);
if (bo) {
if (!allow_unzeroed)
memset(bo->base.vaddr, 0, bo->base.base.size);
@@ -251,7 +338,13 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size,
return ERR_PTR(-ENOMEM);
}
}
- return to_vc4_bo(&cma_obj->base);
+ bo = to_vc4_bo(&cma_obj->base);
+
+ mutex_lock(&vc4->bo_lock);
+ vc4_bo_set_label(&cma_obj->base, type);
+ mutex_unlock(&vc4->bo_lock);
+
+ return bo;
}
int vc4_dumb_create(struct drm_file *file_priv,
@@ -268,22 +361,23 @@ int vc4_dumb_create(struct drm_file *file_priv,
if (args->size < args->pitch * args->height)
args->size = args->pitch * args->height;
- bo = vc4_bo_create(dev, args->size, false);
+ bo = vc4_bo_create(dev, args->size, false, VC4_BO_TYPE_DUMB);
if (IS_ERR(bo))
return PTR_ERR(bo);
ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle);
- drm_gem_object_unreference_unlocked(&bo->base.base);
+ drm_gem_object_put_unlocked(&bo->base.base);
return ret;
}
-/* Must be called with bo_lock held. */
static void vc4_bo_cache_free_old(struct drm_device *dev)
{
struct vc4_dev *vc4 = to_vc4_dev(dev);
unsigned long expire_time = jiffies - msecs_to_jiffies(1000);
+ lockdep_assert_held(&vc4->bo_lock);
+
while (!list_empty(&vc4->bo_cache.time_list)) {
struct vc4_bo *bo = list_last_entry(&vc4->bo_cache.time_list,
struct vc4_bo, unref_head);
@@ -348,8 +442,7 @@ void vc4_free_object(struct drm_gem_object *gem_bo)
list_add(&bo->size_head, cache_list);
list_add(&bo->unref_head, &vc4->bo_cache.time_list);
- vc4->bo_stats.num_cached++;
- vc4->bo_stats.size_cached += gem_bo->size;
+ vc4_bo_set_label(&bo->base.base, VC4_BO_TYPE_KERNEL_CACHE);
vc4_bo_cache_free_old(dev);
@@ -389,7 +482,7 @@ vc4_prime_export(struct drm_device *dev, struct drm_gem_object *obj, int flags)
struct vc4_bo *bo = to_vc4_bo(obj);
if (bo->validated_shader) {
- DRM_ERROR("Attempting to export shader BO\n");
+ DRM_DEBUG("Attempting to export shader BO\n");
return ERR_PTR(-EINVAL);
}
@@ -410,7 +503,7 @@ int vc4_mmap(struct file *filp, struct vm_area_struct *vma)
bo = to_vc4_bo(gem_obj);
if (bo->validated_shader && (vma->vm_flags & VM_WRITE)) {
- DRM_ERROR("mmaping of shader BOs for writing not allowed.\n");
+ DRM_DEBUG("mmaping of shader BOs for writing not allowed.\n");
return -EINVAL;
}
@@ -435,7 +528,7 @@ int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
struct vc4_bo *bo = to_vc4_bo(obj);
if (bo->validated_shader && (vma->vm_flags & VM_WRITE)) {
- DRM_ERROR("mmaping of shader BOs for writing not allowed.\n");
+ DRM_DEBUG("mmaping of shader BOs for writing not allowed.\n");
return -EINVAL;
}
@@ -447,7 +540,7 @@ void *vc4_prime_vmap(struct drm_gem_object *obj)
struct vc4_bo *bo = to_vc4_bo(obj);
if (bo->validated_shader) {
- DRM_ERROR("mmaping of shader BOs not allowed.\n");
+ DRM_DEBUG("mmaping of shader BOs not allowed.\n");
return ERR_PTR(-EINVAL);
}
@@ -483,12 +576,12 @@ int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
* We can't allocate from the BO cache, because the BOs don't
* get zeroed, and that might leak data between users.
*/
- bo = vc4_bo_create(dev, args->size, false);
+ bo = vc4_bo_create(dev, args->size, false, VC4_BO_TYPE_V3D);
if (IS_ERR(bo))
return PTR_ERR(bo);
ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle);
- drm_gem_object_unreference_unlocked(&bo->base.base);
+ drm_gem_object_put_unlocked(&bo->base.base);
return ret;
}
@@ -501,14 +594,14 @@ int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data,
gem_obj = drm_gem_object_lookup(file_priv, args->handle);
if (!gem_obj) {
- DRM_ERROR("Failed to look up GEM BO %d\n", args->handle);
+ DRM_DEBUG("Failed to look up GEM BO %d\n", args->handle);
return -EINVAL;
}
/* The mmap offset was set up at BO allocation time. */
args->offset = drm_vma_node_offset_addr(&gem_obj->vma_node);
- drm_gem_object_unreference_unlocked(gem_obj);
+ drm_gem_object_put_unlocked(gem_obj);
return 0;
}
@@ -536,7 +629,7 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data,
return -EINVAL;
}
- bo = vc4_bo_create(dev, args->size, true);
+ bo = vc4_bo_create(dev, args->size, true, VC4_BO_TYPE_V3D_SHADER);
if (IS_ERR(bo))
return PTR_ERR(bo);
@@ -564,7 +657,7 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data,
ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle);
fail:
- drm_gem_object_unreference_unlocked(&bo->base.base);
+ drm_gem_object_put_unlocked(&bo->base.base);
return ret;
}
@@ -605,13 +698,13 @@ int vc4_set_tiling_ioctl(struct drm_device *dev, void *data,
gem_obj = drm_gem_object_lookup(file_priv, args->handle);
if (!gem_obj) {
- DRM_ERROR("Failed to look up GEM BO %d\n", args->handle);
+ DRM_DEBUG("Failed to look up GEM BO %d\n", args->handle);
return -ENOENT;
}
bo = to_vc4_bo(gem_obj);
bo->t_format = t_format;
- drm_gem_object_unreference_unlocked(gem_obj);
+ drm_gem_object_put_unlocked(gem_obj);
return 0;
}
@@ -636,7 +729,7 @@ int vc4_get_tiling_ioctl(struct drm_device *dev, void *data,
gem_obj = drm_gem_object_lookup(file_priv, args->handle);
if (!gem_obj) {
- DRM_ERROR("Failed to look up GEM BO %d\n", args->handle);
+ DRM_DEBUG("Failed to look up GEM BO %d\n", args->handle);
return -ENOENT;
}
bo = to_vc4_bo(gem_obj);
@@ -646,14 +739,29 @@ int vc4_get_tiling_ioctl(struct drm_device *dev, void *data,
else
args->modifier = DRM_FORMAT_MOD_NONE;
- drm_gem_object_unreference_unlocked(gem_obj);
+ drm_gem_object_put_unlocked(gem_obj);
return 0;
}
-void vc4_bo_cache_init(struct drm_device *dev)
+int vc4_bo_cache_init(struct drm_device *dev)
{
struct vc4_dev *vc4 = to_vc4_dev(dev);
+ int i;
+
+ /* Create the initial set of BO labels that the kernel will
+ * use. This lets us avoid a bunch of string reallocation in
+ * the kernel's draw and BO allocation paths.
+ */
+ vc4->bo_labels = kcalloc(VC4_BO_TYPE_COUNT, sizeof(*vc4->bo_labels),
+ GFP_KERNEL);
+ if (!vc4->bo_labels)
+ return -ENOMEM;
+ vc4->num_labels = VC4_BO_TYPE_COUNT;
+
+ BUILD_BUG_ON(ARRAY_SIZE(bo_type_names) != VC4_BO_TYPE_COUNT);
+ for (i = 0; i < VC4_BO_TYPE_COUNT; i++)
+ vc4->bo_labels[i].name = bo_type_names[i];
mutex_init(&vc4->bo_lock);
@@ -663,19 +771,66 @@ void vc4_bo_cache_init(struct drm_device *dev)
setup_timer(&vc4->bo_cache.time_timer,
vc4_bo_cache_time_timer,
(unsigned long)dev);
+
+ return 0;
}
void vc4_bo_cache_destroy(struct drm_device *dev)
{
struct vc4_dev *vc4 = to_vc4_dev(dev);
+ int i;
del_timer(&vc4->bo_cache.time_timer);
cancel_work_sync(&vc4->bo_cache.time_work);
vc4_bo_cache_purge(dev);
- if (vc4->bo_stats.num_allocated) {
- DRM_ERROR("Destroying BO cache while BOs still allocated:\n");
- vc4_bo_stats_dump(vc4);
+ for (i = 0; i < vc4->num_labels; i++) {
+ if (vc4->bo_labels[i].num_allocated) {
+ DRM_ERROR("Destroying BO cache with %d %s "
+ "BOs still allocated\n",
+ vc4->bo_labels[i].num_allocated,
+ vc4->bo_labels[i].name);
+ }
+
+ if (is_user_label(i))
+ kfree(vc4->bo_labels[i].name);
}
+ kfree(vc4->bo_labels);
+}
+
+int vc4_label_bo_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct vc4_dev *vc4 = to_vc4_dev(dev);
+ struct drm_vc4_label_bo *args = data;
+ char *name;
+ struct drm_gem_object *gem_obj;
+ int ret = 0, label;
+
+ if (!args->len)
+ return -EINVAL;
+
+ name = strndup_user(u64_to_user_ptr(args->name), args->len + 1);
+ if (IS_ERR(name))
+ return PTR_ERR(name);
+
+ gem_obj = drm_gem_object_lookup(file_priv, args->handle);
+ if (!gem_obj) {
+ DRM_ERROR("Failed to look up GEM BO %d\n", args->handle);
+ kfree(name);
+ return -ENOENT;
+ }
+
+ mutex_lock(&vc4->bo_lock);
+ label = vc4_get_user_label(vc4, name);
+ if (label != -1)
+ vc4_bo_set_label(gem_obj, label);
+ else
+ ret = -ENOMEM;
+ mutex_unlock(&vc4->bo_lock);
+
+ drm_gem_object_put_unlocked(gem_obj);
+
+ return ret;
}
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index a12cc7e..ce1e3b9 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -479,7 +479,8 @@ static void require_hvs_enabled(struct drm_device *dev)
SCALER_DISPCTRL_ENABLE);
}
-static void vc4_crtc_disable(struct drm_crtc *crtc)
+static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct drm_device *dev = crtc->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);
@@ -518,6 +519,19 @@ static void vc4_crtc_disable(struct drm_crtc *crtc)
WARN_ON_ONCE((HVS_READ(SCALER_DISPSTATX(chan)) &
(SCALER_DISPSTATX_FULL | SCALER_DISPSTATX_EMPTY)) !=
SCALER_DISPSTATX_EMPTY);
+
+ /*
+ * Make sure we issue a vblank event after disabling the CRTC if
+ * someone was waiting it.
+ */
+ if (crtc->state->event) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ drm_crtc_send_vblank_event(crtc, crtc->state->event);
+ crtc->state->event = NULL;
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ }
}
static void vc4_crtc_update_dlist(struct drm_crtc *crtc)
@@ -548,7 +562,8 @@ static void vc4_crtc_update_dlist(struct drm_crtc *crtc)
}
}
-static void vc4_crtc_enable(struct drm_crtc *crtc)
+static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct drm_device *dev = crtc->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);
@@ -577,18 +592,17 @@ static void vc4_crtc_enable(struct drm_crtc *crtc)
CRTC_READ(PV_V_CONTROL) | PV_VCONTROL_VIDEN);
}
-static bool vc4_crtc_mode_fixup(struct drm_crtc *crtc,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
+static enum drm_mode_status vc4_crtc_mode_valid(struct drm_crtc *crtc,
+ const struct drm_display_mode *mode)
{
/* Do not allow doublescan modes from user space */
- if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) {
+ if (mode->flags & DRM_MODE_FLAG_DBLSCAN) {
DRM_DEBUG_KMS("[CRTC:%d] Doublescan mode rejected.\n",
crtc->base.id);
- return false;
+ return MODE_NO_DBLESCAN;
}
- return true;
+ return MODE_OK;
}
static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
@@ -682,14 +696,6 @@ static void vc4_disable_vblank(struct drm_crtc *crtc)
CRTC_WRITE(PV_INTEN, 0);
}
-/* Must be called with the event lock held */
-bool vc4_event_pending(struct drm_crtc *crtc)
-{
- struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
-
- return !!vc4_crtc->event;
-}
-
static void vc4_crtc_handle_page_flip(struct vc4_crtc *vc4_crtc)
{
struct drm_crtc *crtc = &vc4_crtc->base;
@@ -757,7 +763,7 @@ vc4_async_page_flip_complete(struct vc4_seqno_cb *cb)
}
drm_crtc_vblank_put(crtc);
- drm_framebuffer_unreference(flip_state->fb);
+ drm_framebuffer_put(flip_state->fb);
kfree(flip_state);
up(&vc4->async_modeset);
@@ -786,7 +792,7 @@ static int vc4_async_page_flip(struct drm_crtc *crtc,
if (!flip_state)
return -ENOMEM;
- drm_framebuffer_reference(fb);
+ drm_framebuffer_get(fb);
flip_state->fb = fb;
flip_state->crtc = crtc;
flip_state->event = event;
@@ -794,7 +800,7 @@ static int vc4_async_page_flip(struct drm_crtc *crtc,
/* Make sure all other async modesetes have landed. */
ret = down_interruptible(&vc4->async_modeset);
if (ret) {
- drm_framebuffer_unreference(fb);
+ drm_framebuffer_put(fb);
kfree(flip_state);
return ret;
}
@@ -885,11 +891,11 @@ static const struct drm_crtc_funcs vc4_crtc_funcs = {
static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = {
.mode_set_nofb = vc4_crtc_mode_set_nofb,
- .disable = vc4_crtc_disable,
- .enable = vc4_crtc_enable,
- .mode_fixup = vc4_crtc_mode_fixup,
+ .mode_valid = vc4_crtc_mode_valid,
.atomic_check = vc4_crtc_atomic_check,
.atomic_flush = vc4_crtc_atomic_flush,
+ .atomic_enable = vc4_crtc_atomic_enable,
+ .atomic_disable = vc4_crtc_atomic_disable,
};
static const struct vc4_crtc_data pv0_data = {
diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c
index 2e0fe46..519cefe 100644
--- a/drivers/gpu/drm/vc4/vc4_dpi.c
+++ b/drivers/gpu/drm/vc4/vc4_dpi.c
@@ -224,20 +224,19 @@ static void vc4_dpi_encoder_enable(struct drm_encoder *encoder)
DRM_ERROR("Failed to set clock rate: %d\n", ret);
}
-static bool vc4_dpi_encoder_mode_fixup(struct drm_encoder *encoder,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
+static enum drm_mode_status vc4_dpi_encoder_mode_valid(struct drm_encoder *encoder,
+ const struct drm_display_mode *mode)
{
- if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
- return false;
+ if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+ return MODE_NO_INTERLACE;
- return true;
+ return MODE_OK;
}
static const struct drm_encoder_helper_funcs vc4_dpi_encoder_helper_funcs = {
.disable = vc4_dpi_encoder_disable,
.enable = vc4_dpi_encoder_enable,
- .mode_fixup = vc4_dpi_encoder_mode_fixup,
+ .mode_valid = vc4_dpi_encoder_mode_valid,
};
static const struct of_device_id vc4_dpi_dt_match[] = {
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index c6b487c..1c96edc 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -99,6 +99,7 @@ static int vc4_get_param_ioctl(struct drm_device *dev, void *data,
case DRM_VC4_PARAM_SUPPORTS_BRANCHES:
case DRM_VC4_PARAM_SUPPORTS_ETC1:
case DRM_VC4_PARAM_SUPPORTS_THREADED_FS:
+ case DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER:
args->value = true;
break;
default:
@@ -140,6 +141,7 @@ static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
DRM_IOCTL_DEF_DRV(VC4_GET_PARAM, vc4_get_param_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(VC4_SET_TILING, vc4_set_tiling_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(VC4_GET_TILING, vc4_get_tiling_ioctl, DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(VC4_LABEL_BO, vc4_label_bo_ioctl, DRM_RENDER_ALLOW),
};
static struct drm_driver vc4_drm_driver = {
@@ -178,8 +180,6 @@ static struct drm_driver vc4_drm_driver = {
.gem_prime_mmap = vc4_prime_mmap,
.dumb_create = vc4_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.ioctls = vc4_drm_ioctls,
.num_ioctls = ARRAY_SIZE(vc4_drm_ioctls),
@@ -257,7 +257,9 @@ static int vc4_drm_bind(struct device *dev)
vc4->dev = drm;
drm->dev_private = vc4;
- vc4_bo_cache_init(drm);
+ ret = vc4_bo_cache_init(drm);
+ if (ret)
+ goto dev_unref;
drm_mode_config_init(drm);
@@ -281,8 +283,9 @@ unbind_all:
component_unbind_all(dev, drm);
gem_destroy:
vc4_gem_destroy(drm);
- drm_dev_unref(drm);
vc4_bo_cache_destroy(drm);
+dev_unref:
+ drm_dev_unref(drm);
return ret;
}
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index df22698..87f2d8e 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -11,6 +11,24 @@
#include <drm/drm_encoder.h>
#include <drm/drm_gem_cma_helper.h>
+/* Don't forget to update vc4_bo.c: bo_type_names[] when adding to
+ * this.
+ */
+enum vc4_kernel_bo_type {
+ /* Any kernel allocation (gem_create_object hook) before it
+ * gets another type set.
+ */
+ VC4_BO_TYPE_KERNEL,
+ VC4_BO_TYPE_V3D,
+ VC4_BO_TYPE_V3D_SHADER,
+ VC4_BO_TYPE_DUMB,
+ VC4_BO_TYPE_BIN,
+ VC4_BO_TYPE_RCL,
+ VC4_BO_TYPE_BCL,
+ VC4_BO_TYPE_KERNEL_CACHE,
+ VC4_BO_TYPE_COUNT
+};
+
struct vc4_dev {
struct drm_device *dev;
@@ -46,14 +64,14 @@ struct vc4_dev {
struct timer_list time_timer;
} bo_cache;
- struct vc4_bo_stats {
+ u32 num_labels;
+ struct vc4_label {
+ const char *name;
u32 num_allocated;
u32 size_allocated;
- u32 num_cached;
- u32 size_cached;
- } bo_stats;
+ } *bo_labels;
- /* Protects bo_cache and the BO stats. */
+ /* Protects bo_cache and bo_labels. */
struct mutex bo_lock;
uint64_t dma_fence_context;
@@ -169,6 +187,11 @@ struct vc4_bo {
/* normally (resv == &_resv) except for imported bo's */
struct reservation_object *resv;
struct reservation_object _resv;
+
+ /* One of enum vc4_kernel_bo_type, or VC4_BO_TYPE_COUNT + i
+ * for user-allocated labels.
+ */
+ int label;
};
static inline struct vc4_bo *
@@ -460,7 +483,7 @@ struct vc4_validated_shader_info {
struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size);
void vc4_free_object(struct drm_gem_object *gem_obj);
struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size,
- bool from_cache);
+ bool from_cache, enum vc4_kernel_bo_type type);
int vc4_dumb_create(struct drm_file *file_priv,
struct drm_device *dev,
struct drm_mode_create_dumb *args);
@@ -478,6 +501,8 @@ int vc4_get_tiling_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
int vc4_get_hang_state_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+int vc4_label_bo_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
int vc4_mmap(struct file *filp, struct vm_area_struct *vma);
struct reservation_object *vc4_prime_res_obj(struct drm_gem_object *obj);
int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
@@ -485,13 +510,12 @@ struct drm_gem_object *vc4_prime_import_sg_table(struct drm_device *dev,
struct dma_buf_attachment *attach,
struct sg_table *sgt);
void *vc4_prime_vmap(struct drm_gem_object *obj);
-void vc4_bo_cache_init(struct drm_device *dev);
+int vc4_bo_cache_init(struct drm_device *dev);
void vc4_bo_cache_destroy(struct drm_device *dev);
int vc4_bo_stats_debugfs(struct seq_file *m, void *arg);
/* vc4_crtc.c */
extern struct platform_driver vc4_crtc_driver;
-bool vc4_event_pending(struct drm_crtc *crtc);
int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg);
bool vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id,
bool in_vblank_irq, int *vpos, int *hpos,
diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
index 5e8b81e..d1e0dc9 100644
--- a/drivers/gpu/drm/vc4/vc4_dsi.c
+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
@@ -736,18 +736,18 @@ static void vc4_dsi_latch_ulps(struct vc4_dsi *dsi, bool latch)
/* Enters or exits Ultra Low Power State. */
static void vc4_dsi_ulps(struct vc4_dsi *dsi, bool ulps)
{
- bool continuous = dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS;
- u32 phyc_ulps = ((continuous ? DSI_PORT_BIT(PHYC_CLANE_ULPS) : 0) |
+ bool non_continuous = dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS;
+ u32 phyc_ulps = ((non_continuous ? DSI_PORT_BIT(PHYC_CLANE_ULPS) : 0) |
DSI_PHYC_DLANE0_ULPS |
(dsi->lanes > 1 ? DSI_PHYC_DLANE1_ULPS : 0) |
(dsi->lanes > 2 ? DSI_PHYC_DLANE2_ULPS : 0) |
(dsi->lanes > 3 ? DSI_PHYC_DLANE3_ULPS : 0));
- u32 stat_ulps = ((continuous ? DSI1_STAT_PHY_CLOCK_ULPS : 0) |
+ u32 stat_ulps = ((non_continuous ? DSI1_STAT_PHY_CLOCK_ULPS : 0) |
DSI1_STAT_PHY_D0_ULPS |
(dsi->lanes > 1 ? DSI1_STAT_PHY_D1_ULPS : 0) |
(dsi->lanes > 2 ? DSI1_STAT_PHY_D2_ULPS : 0) |
(dsi->lanes > 3 ? DSI1_STAT_PHY_D3_ULPS : 0));
- u32 stat_stop = ((continuous ? DSI1_STAT_PHY_CLOCK_STOP : 0) |
+ u32 stat_stop = ((non_continuous ? DSI1_STAT_PHY_CLOCK_STOP : 0) |
DSI1_STAT_PHY_D0_STOP |
(dsi->lanes > 1 ? DSI1_STAT_PHY_D1_STOP : 0) |
(dsi->lanes > 2 ? DSI1_STAT_PHY_D2_STOP : 0) |
@@ -1035,7 +1035,17 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)
DSI_HS_DLT4_TRAIL) |
VC4_SET_FIELD(0, DSI_HS_DLT4_ANLAT));
- DSI_PORT_WRITE(HS_DLT5, VC4_SET_FIELD(dsi_hs_timing(ui_ns, 1000, 5000),
+ /* T_INIT is how long STOP is driven after power-up to
+ * indicate to the slave (also coming out of power-up) that
+ * master init is complete, and should be greater than the
+ * maximum of two value: T_INIT,MASTER and T_INIT,SLAVE. The
+ * D-PHY spec gives a minimum 100us for T_INIT,MASTER and
+ * T_INIT,SLAVE, while allowing protocols on top of it to give
+ * greater minimums. The vc4 firmware uses an extremely
+ * conservative 5ms, and we maintain that here.
+ */
+ DSI_PORT_WRITE(HS_DLT5, VC4_SET_FIELD(dsi_hs_timing(ui_ns,
+ 5 * 1000 * 1000, 0),
DSI_HS_DLT5_INIT));
DSI_PORT_WRITE(HS_DLT6,
@@ -1626,14 +1636,10 @@ static void vc4_dsi_unbind(struct device *dev, struct device *master,
pm_runtime_disable(dev);
- drm_bridge_remove(dsi->bridge);
vc4_dsi_encoder_destroy(dsi->encoder);
mipi_dsi_host_unregister(&dsi->dsi_host);
- clk_disable_unprepare(dsi->pll_phy_clock);
- clk_disable_unprepare(dsi->escape_clock);
-
if (dsi->port == 1)
vc4->dsi1 = NULL;
}
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index d5b821a..d0c6bfb 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -55,7 +55,7 @@ vc4_free_hang_state(struct drm_device *dev, struct vc4_hang_state *state)
unsigned int i;
for (i = 0; i < state->user_state.bo_count; i++)
- drm_gem_object_unreference_unlocked(state->bo[i]);
+ drm_gem_object_put_unlocked(state->bo[i]);
kfree(state);
}
@@ -119,7 +119,7 @@ vc4_get_hang_state_ioctl(struct drm_device *dev, void *data,
bo_state[i].size = vc4_bo->base.base.size;
}
- if (copy_to_user((void __user *)(uintptr_t)get_state->bo,
+ if (copy_to_user(u64_to_user_ptr(get_state->bo),
bo_state,
state->bo_count * sizeof(*bo_state)))
ret = -EFAULT;
@@ -188,12 +188,12 @@ vc4_save_hang_state(struct drm_device *dev)
continue;
for (j = 0; j < exec[i]->bo_count; j++) {
- drm_gem_object_reference(&exec[i]->bo[j]->base);
+ drm_gem_object_get(&exec[i]->bo[j]->base);
kernel_state->bo[j + prev_idx] = &exec[i]->bo[j]->base;
}
list_for_each_entry(bo, &exec[i]->unref_list, unref_head) {
- drm_gem_object_reference(&bo->base.base);
+ drm_gem_object_get(&bo->base.base);
kernel_state->bo[j + prev_idx] = &bo->base.base;
j++;
}
@@ -659,7 +659,7 @@ vc4_cl_lookup_bos(struct drm_device *dev,
/* See comment on bo_index for why we have to check
* this.
*/
- DRM_ERROR("Rendering requires BOs to validate\n");
+ DRM_DEBUG("Rendering requires BOs to validate\n");
return -EINVAL;
}
@@ -678,8 +678,7 @@ vc4_cl_lookup_bos(struct drm_device *dev,
goto fail;
}
- if (copy_from_user(handles,
- (void __user *)(uintptr_t)args->bo_handles,
+ if (copy_from_user(handles, u64_to_user_ptr(args->bo_handles),
exec->bo_count * sizeof(uint32_t))) {
ret = -EFAULT;
DRM_ERROR("Failed to copy in GEM handles\n");
@@ -691,13 +690,13 @@ vc4_cl_lookup_bos(struct drm_device *dev,
struct drm_gem_object *bo = idr_find(&file_priv->object_idr,
handles[i]);
if (!bo) {
- DRM_ERROR("Failed to look up GEM BO %d: %d\n",
+ DRM_DEBUG("Failed to look up GEM BO %d: %d\n",
i, handles[i]);
ret = -EINVAL;
spin_unlock(&file_priv->table_lock);
goto fail;
}
- drm_gem_object_reference(bo);
+ drm_gem_object_get(bo);
exec->bo[i] = (struct drm_gem_cma_object *)bo;
}
spin_unlock(&file_priv->table_lock);
@@ -729,7 +728,7 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec)
args->shader_rec_count >= (UINT_MAX /
sizeof(struct vc4_shader_state)) ||
temp_size < exec_size) {
- DRM_ERROR("overflow in exec arguments\n");
+ DRM_DEBUG("overflow in exec arguments\n");
ret = -EINVAL;
goto fail;
}
@@ -755,27 +754,27 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec)
exec->shader_state_size = args->shader_rec_count;
if (copy_from_user(bin,
- (void __user *)(uintptr_t)args->bin_cl,
+ u64_to_user_ptr(args->bin_cl),
args->bin_cl_size)) {
ret = -EFAULT;
goto fail;
}
if (copy_from_user(exec->shader_rec_u,
- (void __user *)(uintptr_t)args->shader_rec,
+ u64_to_user_ptr(args->shader_rec),
args->shader_rec_size)) {
ret = -EFAULT;
goto fail;
}
if (copy_from_user(exec->uniforms_u,
- (void __user *)(uintptr_t)args->uniforms,
+ u64_to_user_ptr(args->uniforms),
args->uniforms_size)) {
ret = -EFAULT;
goto fail;
}
- bo = vc4_bo_create(dev, exec_size, true);
+ bo = vc4_bo_create(dev, exec_size, true, VC4_BO_TYPE_BCL);
if (IS_ERR(bo)) {
DRM_ERROR("Couldn't allocate BO for binning\n");
ret = PTR_ERR(bo);
@@ -835,7 +834,7 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec)
if (exec->bo) {
for (i = 0; i < exec->bo_count; i++)
- drm_gem_object_unreference_unlocked(&exec->bo[i]->base);
+ drm_gem_object_put_unlocked(&exec->bo[i]->base);
kvfree(exec->bo);
}
@@ -843,7 +842,7 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec)
struct vc4_bo *bo = list_first_entry(&exec->unref_list,
struct vc4_bo, unref_head);
list_del(&bo->unref_head);
- drm_gem_object_unreference_unlocked(&bo->base.base);
+ drm_gem_object_put_unlocked(&bo->base.base);
}
/* Free up the allocation of any bin slots we used. */
@@ -974,7 +973,7 @@ vc4_wait_bo_ioctl(struct drm_device *dev, void *data,
gem_obj = drm_gem_object_lookup(file_priv, args->handle);
if (!gem_obj) {
- DRM_ERROR("Failed to look up GEM BO %d\n", args->handle);
+ DRM_DEBUG("Failed to look up GEM BO %d\n", args->handle);
return -EINVAL;
}
bo = to_vc4_bo(gem_obj);
@@ -982,7 +981,7 @@ vc4_wait_bo_ioctl(struct drm_device *dev, void *data,
ret = vc4_wait_for_seqno_ioctl_helper(dev, bo->seqno,
&args->timeout_ns);
- drm_gem_object_unreference_unlocked(gem_obj);
+ drm_gem_object_put_unlocked(gem_obj);
return ret;
}
@@ -1008,8 +1007,11 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data,
struct ww_acquire_ctx acquire_ctx;
int ret = 0;
- if ((args->flags & ~VC4_SUBMIT_CL_USE_CLEAR_COLOR) != 0) {
- DRM_ERROR("Unknown flags: 0x%02x\n", args->flags);
+ if ((args->flags & ~(VC4_SUBMIT_CL_USE_CLEAR_COLOR |
+ VC4_SUBMIT_CL_FIXED_RCL_ORDER |
+ VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X |
+ VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y)) != 0) {
+ DRM_DEBUG("Unknown flags: 0x%02x\n", args->flags);
return -EINVAL;
}
@@ -1118,6 +1120,4 @@ vc4_gem_destroy(struct drm_device *dev)
if (vc4->hang_state)
vc4_free_hang_state(dev, vc4->hang_state);
-
- vc4_bo_cache_destroy(dev);
}
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index ed63d4e..937da8d 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -57,9 +57,14 @@
#include <sound/pcm_drm_eld.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
+#include "media/cec.h"
#include "vc4_drv.h"
#include "vc4_regs.h"
+#define HSM_CLOCK_FREQ 163682864
+#define CEC_CLOCK_FREQ 40000
+#define CEC_CLOCK_DIV (HSM_CLOCK_FREQ / CEC_CLOCK_FREQ)
+
/* HDMI audio information */
struct vc4_hdmi_audio {
struct snd_soc_card card;
@@ -85,6 +90,11 @@ struct vc4_hdmi {
int hpd_gpio;
bool hpd_active_low;
+ struct cec_adapter *cec_adap;
+ struct cec_msg cec_rx_msg;
+ bool cec_tx_ok;
+ bool cec_irq_was_rx;
+
struct clk *pixel_clock;
struct clk *hsm_clock;
};
@@ -149,6 +159,23 @@ static const struct {
HDMI_REG(VC4_HDMI_VERTB1),
HDMI_REG(VC4_HDMI_TX_PHY_RESET_CTL),
HDMI_REG(VC4_HDMI_TX_PHY_CTL0),
+
+ HDMI_REG(VC4_HDMI_CEC_CNTRL_1),
+ HDMI_REG(VC4_HDMI_CEC_CNTRL_2),
+ HDMI_REG(VC4_HDMI_CEC_CNTRL_3),
+ HDMI_REG(VC4_HDMI_CEC_CNTRL_4),
+ HDMI_REG(VC4_HDMI_CEC_CNTRL_5),
+ HDMI_REG(VC4_HDMI_CPU_STATUS),
+ HDMI_REG(VC4_HDMI_CPU_MASK_STATUS),
+
+ HDMI_REG(VC4_HDMI_CEC_RX_DATA_1),
+ HDMI_REG(VC4_HDMI_CEC_RX_DATA_2),
+ HDMI_REG(VC4_HDMI_CEC_RX_DATA_3),
+ HDMI_REG(VC4_HDMI_CEC_RX_DATA_4),
+ HDMI_REG(VC4_HDMI_CEC_TX_DATA_1),
+ HDMI_REG(VC4_HDMI_CEC_TX_DATA_2),
+ HDMI_REG(VC4_HDMI_CEC_TX_DATA_3),
+ HDMI_REG(VC4_HDMI_CEC_TX_DATA_4),
};
static const struct {
@@ -216,8 +243,8 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
if (gpio_get_value_cansleep(vc4->hdmi->hpd_gpio) ^
vc4->hdmi->hpd_active_low)
return connector_status_connected;
- else
- return connector_status_disconnected;
+ cec_phys_addr_invalidate(vc4->hdmi->cec_adap);
+ return connector_status_disconnected;
}
if (drm_probe_ddc(vc4->hdmi->ddc))
@@ -225,8 +252,8 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
if (HDMI_READ(VC4_HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED)
return connector_status_connected;
- else
- return connector_status_disconnected;
+ cec_phys_addr_invalidate(vc4->hdmi->cec_adap);
+ return connector_status_disconnected;
}
static void vc4_hdmi_connector_destroy(struct drm_connector *connector)
@@ -247,6 +274,7 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
struct edid *edid;
edid = drm_get_edid(connector, vc4->hdmi->ddc);
+ cec_s_phys_addr_from_edid(vc4->hdmi->cec_adap, edid);
if (!edid)
return -ENODEV;
@@ -260,12 +288,12 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
drm_mode_connector_update_edid_property(connector, edid);
ret = drm_add_edid_modes(connector, edid);
drm_edid_to_eld(connector, edid);
+ kfree(edid);
return ret;
}
static const struct drm_connector_funcs vc4_hdmi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = vc4_hdmi_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = vc4_hdmi_connector_destroy,
@@ -395,7 +423,7 @@ static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder)
union hdmi_infoframe frame;
int ret;
- ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode);
+ ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode, false);
if (ret < 0) {
DRM_ERROR("couldn't fill AVI infoframe\n");
return;
@@ -463,11 +491,6 @@ static void vc4_hdmi_encoder_disable(struct drm_encoder *encoder)
HD_WRITE(VC4_HD_VID_CTL,
HD_READ(VC4_HD_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
- HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_SW_RST);
- udelay(1);
- HD_WRITE(VC4_HD_M_CTL, 0);
-
- clk_disable_unprepare(hdmi->hsm_clock);
clk_disable_unprepare(hdmi->pixel_clock);
ret = pm_runtime_put(&hdmi->pdev->dev);
@@ -509,16 +532,6 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
return;
}
- /* This is the rate that is set by the firmware. The number
- * needs to be a bit higher than the pixel clock rate
- * (generally 148.5Mhz).
- */
- ret = clk_set_rate(hdmi->hsm_clock, 163682864);
- if (ret) {
- DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
- return;
- }
-
ret = clk_set_rate(hdmi->pixel_clock,
mode->clock * 1000 *
((mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1));
@@ -533,20 +546,6 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
return;
}
- ret = clk_prepare_enable(hdmi->hsm_clock);
- if (ret) {
- DRM_ERROR("Failed to turn on HDMI state machine clock: %d\n",
- ret);
- clk_disable_unprepare(hdmi->pixel_clock);
- return;
- }
-
- HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_SW_RST);
- udelay(1);
- HD_WRITE(VC4_HD_M_CTL, 0);
-
- HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_ENABLE);
-
HDMI_WRITE(VC4_HDMI_SW_RESET_CONTROL,
VC4_HDMI_SW_RESET_HDMI |
VC4_HDMI_SW_RESET_FORMAT_DETECT);
@@ -1150,6 +1149,159 @@ static void vc4_hdmi_audio_cleanup(struct vc4_hdmi *hdmi)
snd_soc_unregister_codec(dev);
}
+#ifdef CONFIG_DRM_VC4_HDMI_CEC
+static irqreturn_t vc4_cec_irq_handler_thread(int irq, void *priv)
+{
+ struct vc4_dev *vc4 = priv;
+ struct vc4_hdmi *hdmi = vc4->hdmi;
+
+ if (hdmi->cec_irq_was_rx) {
+ if (hdmi->cec_rx_msg.len)
+ cec_received_msg(hdmi->cec_adap, &hdmi->cec_rx_msg);
+ } else if (hdmi->cec_tx_ok) {
+ cec_transmit_done(hdmi->cec_adap, CEC_TX_STATUS_OK,
+ 0, 0, 0, 0);
+ } else {
+ /*
+ * This CEC implementation makes 1 retry, so if we
+ * get a NACK, then that means it made 2 attempts.
+ */
+ cec_transmit_done(hdmi->cec_adap, CEC_TX_STATUS_NACK,
+ 0, 2, 0, 0);
+ }
+ return IRQ_HANDLED;
+}
+
+static void vc4_cec_read_msg(struct vc4_dev *vc4, u32 cntrl1)
+{
+ struct cec_msg *msg = &vc4->hdmi->cec_rx_msg;
+ unsigned int i;
+
+ msg->len = 1 + ((cntrl1 & VC4_HDMI_CEC_REC_WRD_CNT_MASK) >>
+ VC4_HDMI_CEC_REC_WRD_CNT_SHIFT);
+ for (i = 0; i < msg->len; i += 4) {
+ u32 val = HDMI_READ(VC4_HDMI_CEC_RX_DATA_1 + i);
+
+ msg->msg[i] = val & 0xff;
+ msg->msg[i + 1] = (val >> 8) & 0xff;
+ msg->msg[i + 2] = (val >> 16) & 0xff;
+ msg->msg[i + 3] = (val >> 24) & 0xff;
+ }
+}
+
+static irqreturn_t vc4_cec_irq_handler(int irq, void *priv)
+{
+ struct vc4_dev *vc4 = priv;
+ struct vc4_hdmi *hdmi = vc4->hdmi;
+ u32 stat = HDMI_READ(VC4_HDMI_CPU_STATUS);
+ u32 cntrl1, cntrl5;
+
+ if (!(stat & VC4_HDMI_CPU_CEC))
+ return IRQ_NONE;
+ hdmi->cec_rx_msg.len = 0;
+ cntrl1 = HDMI_READ(VC4_HDMI_CEC_CNTRL_1);
+ cntrl5 = HDMI_READ(VC4_HDMI_CEC_CNTRL_5);
+ hdmi->cec_irq_was_rx = cntrl5 & VC4_HDMI_CEC_RX_CEC_INT;
+ if (hdmi->cec_irq_was_rx) {
+ vc4_cec_read_msg(vc4, cntrl1);
+ cntrl1 |= VC4_HDMI_CEC_CLEAR_RECEIVE_OFF;
+ HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, cntrl1);
+ cntrl1 &= ~VC4_HDMI_CEC_CLEAR_RECEIVE_OFF;
+ } else {
+ hdmi->cec_tx_ok = cntrl1 & VC4_HDMI_CEC_TX_STATUS_GOOD;
+ cntrl1 &= ~VC4_HDMI_CEC_START_XMIT_BEGIN;
+ }
+ HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, cntrl1);
+ HDMI_WRITE(VC4_HDMI_CPU_CLEAR, VC4_HDMI_CPU_CEC);
+
+ return IRQ_WAKE_THREAD;
+}
+
+static int vc4_hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable)
+{
+ struct vc4_dev *vc4 = cec_get_drvdata(adap);
+ /* clock period in microseconds */
+ const u32 usecs = 1000000 / CEC_CLOCK_FREQ;
+ u32 val = HDMI_READ(VC4_HDMI_CEC_CNTRL_5);
+
+ val &= ~(VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET |
+ VC4_HDMI_CEC_CNT_TO_4700_US_MASK |
+ VC4_HDMI_CEC_CNT_TO_4500_US_MASK);
+ val |= ((4700 / usecs) << VC4_HDMI_CEC_CNT_TO_4700_US_SHIFT) |
+ ((4500 / usecs) << VC4_HDMI_CEC_CNT_TO_4500_US_SHIFT);
+
+ if (enable) {
+ HDMI_WRITE(VC4_HDMI_CEC_CNTRL_5, val |
+ VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET);
+ HDMI_WRITE(VC4_HDMI_CEC_CNTRL_5, val);
+ HDMI_WRITE(VC4_HDMI_CEC_CNTRL_2,
+ ((1500 / usecs) << VC4_HDMI_CEC_CNT_TO_1500_US_SHIFT) |
+ ((1300 / usecs) << VC4_HDMI_CEC_CNT_TO_1300_US_SHIFT) |
+ ((800 / usecs) << VC4_HDMI_CEC_CNT_TO_800_US_SHIFT) |
+ ((600 / usecs) << VC4_HDMI_CEC_CNT_TO_600_US_SHIFT) |
+ ((400 / usecs) << VC4_HDMI_CEC_CNT_TO_400_US_SHIFT));
+ HDMI_WRITE(VC4_HDMI_CEC_CNTRL_3,
+ ((2750 / usecs) << VC4_HDMI_CEC_CNT_TO_2750_US_SHIFT) |
+ ((2400 / usecs) << VC4_HDMI_CEC_CNT_TO_2400_US_SHIFT) |
+ ((2050 / usecs) << VC4_HDMI_CEC_CNT_TO_2050_US_SHIFT) |
+ ((1700 / usecs) << VC4_HDMI_CEC_CNT_TO_1700_US_SHIFT));
+ HDMI_WRITE(VC4_HDMI_CEC_CNTRL_4,
+ ((4300 / usecs) << VC4_HDMI_CEC_CNT_TO_4300_US_SHIFT) |
+ ((3900 / usecs) << VC4_HDMI_CEC_CNT_TO_3900_US_SHIFT) |
+ ((3600 / usecs) << VC4_HDMI_CEC_CNT_TO_3600_US_SHIFT) |
+ ((3500 / usecs) << VC4_HDMI_CEC_CNT_TO_3500_US_SHIFT));
+
+ HDMI_WRITE(VC4_HDMI_CPU_MASK_CLEAR, VC4_HDMI_CPU_CEC);
+ } else {
+ HDMI_WRITE(VC4_HDMI_CPU_MASK_SET, VC4_HDMI_CPU_CEC);
+ HDMI_WRITE(VC4_HDMI_CEC_CNTRL_5, val |
+ VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET);
+ }
+ return 0;
+}
+
+static int vc4_hdmi_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
+{
+ struct vc4_dev *vc4 = cec_get_drvdata(adap);
+
+ HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1,
+ (HDMI_READ(VC4_HDMI_CEC_CNTRL_1) & ~VC4_HDMI_CEC_ADDR_MASK) |
+ (log_addr & 0xf) << VC4_HDMI_CEC_ADDR_SHIFT);
+ return 0;
+}
+
+static int vc4_hdmi_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
+ u32 signal_free_time, struct cec_msg *msg)
+{
+ struct vc4_dev *vc4 = cec_get_drvdata(adap);
+ u32 val;
+ unsigned int i;
+
+ for (i = 0; i < msg->len; i += 4)
+ HDMI_WRITE(VC4_HDMI_CEC_TX_DATA_1 + i,
+ (msg->msg[i]) |
+ (msg->msg[i + 1] << 8) |
+ (msg->msg[i + 2] << 16) |
+ (msg->msg[i + 3] << 24));
+
+ val = HDMI_READ(VC4_HDMI_CEC_CNTRL_1);
+ val &= ~VC4_HDMI_CEC_START_XMIT_BEGIN;
+ HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, val);
+ val &= ~VC4_HDMI_CEC_MESSAGE_LENGTH_MASK;
+ val |= (msg->len - 1) << VC4_HDMI_CEC_MESSAGE_LENGTH_SHIFT;
+ val |= VC4_HDMI_CEC_START_XMIT_BEGIN;
+
+ HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, val);
+ return 0;
+}
+
+static const struct cec_adap_ops vc4_hdmi_cec_adap_ops = {
+ .adap_enable = vc4_hdmi_cec_adap_enable,
+ .adap_log_addr = vc4_hdmi_cec_adap_log_addr,
+ .adap_transmit = vc4_hdmi_cec_adap_transmit,
+};
+#endif
+
static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -1205,6 +1357,23 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
return -EPROBE_DEFER;
}
+ /* This is the rate that is set by the firmware. The number
+ * needs to be a bit higher than the pixel clock rate
+ * (generally 148.5Mhz).
+ */
+ ret = clk_set_rate(hdmi->hsm_clock, HSM_CLOCK_FREQ);
+ if (ret) {
+ DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
+ goto err_put_i2c;
+ }
+
+ ret = clk_prepare_enable(hdmi->hsm_clock);
+ if (ret) {
+ DRM_ERROR("Failed to turn on HDMI state machine clock: %d\n",
+ ret);
+ goto err_put_i2c;
+ }
+
/* Only use the GPIO HPD pin if present in the DT, otherwise
* we'll use the HDMI core's register.
*/
@@ -1216,7 +1385,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
&hpd_gpio_flags);
if (hdmi->hpd_gpio < 0) {
ret = hdmi->hpd_gpio;
- goto err_put_i2c;
+ goto err_unprepare_hsm;
}
hdmi->hpd_active_low = hpd_gpio_flags & OF_GPIO_ACTIVE_LOW;
@@ -1224,6 +1393,14 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
vc4->hdmi = hdmi;
+ /* HDMI core must be enabled. */
+ if (!(HD_READ(VC4_HD_M_CTL) & VC4_HD_M_ENABLE)) {
+ HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_SW_RST);
+ udelay(1);
+ HD_WRITE(VC4_HD_M_CTL, 0);
+
+ HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_ENABLE);
+ }
pm_runtime_enable(dev);
drm_encoder_init(drm, hdmi->encoder, &vc4_hdmi_encoder_funcs,
@@ -1235,6 +1412,37 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
ret = PTR_ERR(hdmi->connector);
goto err_destroy_encoder;
}
+#ifdef CONFIG_DRM_VC4_HDMI_CEC
+ hdmi->cec_adap = cec_allocate_adapter(&vc4_hdmi_cec_adap_ops,
+ vc4, "vc4",
+ CEC_CAP_TRANSMIT |
+ CEC_CAP_LOG_ADDRS |
+ CEC_CAP_PASSTHROUGH |
+ CEC_CAP_RC, 1);
+ ret = PTR_ERR_OR_ZERO(hdmi->cec_adap);
+ if (ret < 0)
+ goto err_destroy_conn;
+ HDMI_WRITE(VC4_HDMI_CPU_MASK_SET, 0xffffffff);
+ value = HDMI_READ(VC4_HDMI_CEC_CNTRL_1);
+ value &= ~VC4_HDMI_CEC_DIV_CLK_CNT_MASK;
+ /*
+ * Set the logical address to Unregistered and set the clock
+ * divider: the hsm_clock rate and this divider setting will
+ * give a 40 kHz CEC clock.
+ */
+ value |= VC4_HDMI_CEC_ADDR_MASK |
+ (4091 << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT);
+ HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, value);
+ ret = devm_request_threaded_irq(dev, platform_get_irq(pdev, 0),
+ vc4_cec_irq_handler,
+ vc4_cec_irq_handler_thread, 0,
+ "vc4 hdmi cec", vc4);
+ if (ret)
+ goto err_delete_cec_adap;
+ ret = cec_register_adapter(hdmi->cec_adap, dev);
+ if (ret < 0)
+ goto err_delete_cec_adap;
+#endif
ret = vc4_hdmi_audio_init(hdmi);
if (ret)
@@ -1242,8 +1450,16 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
return 0;
+#ifdef CONFIG_DRM_VC4_HDMI_CEC
+err_delete_cec_adap:
+ cec_delete_adapter(hdmi->cec_adap);
+err_destroy_conn:
+ vc4_hdmi_connector_destroy(hdmi->connector);
+#endif
err_destroy_encoder:
vc4_hdmi_encoder_destroy(hdmi->encoder);
+err_unprepare_hsm:
+ clk_disable_unprepare(hdmi->hsm_clock);
pm_runtime_disable(dev);
err_put_i2c:
put_device(&hdmi->ddc->dev);
@@ -1259,10 +1475,11 @@ static void vc4_hdmi_unbind(struct device *dev, struct device *master,
struct vc4_hdmi *hdmi = vc4->hdmi;
vc4_hdmi_audio_cleanup(hdmi);
-
+ cec_unregister_adapter(hdmi->cec_adap);
vc4_hdmi_connector_destroy(hdmi->connector);
vc4_hdmi_encoder_destroy(hdmi->encoder);
+ clk_disable_unprepare(hdmi->hsm_clock);
pm_runtime_disable(dev);
put_device(&hdmi->ddc->dev);
diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index bc6ecdc..50c4959 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -20,6 +20,7 @@
#include <drm/drm_crtc_helper.h>
#include <drm/drm_plane_helper.h>
#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_framebuffer_helper.h>
#include "vc4_drv.h"
static void vc4_output_poll_changed(struct drm_device *dev)
@@ -29,16 +30,9 @@ static void vc4_output_poll_changed(struct drm_device *dev)
drm_fbdev_cma_hotplug_event(vc4->fbdev);
}
-struct vc4_commit {
- struct drm_device *dev;
- struct drm_atomic_state *state;
- struct vc4_seqno_cb cb;
-};
-
static void
-vc4_atomic_complete_commit(struct vc4_commit *c)
+vc4_atomic_complete_commit(struct drm_atomic_state *state)
{
- struct drm_atomic_state *state = c->state;
struct drm_device *dev = state->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);
@@ -72,28 +66,14 @@ vc4_atomic_complete_commit(struct vc4_commit *c)
drm_atomic_state_put(state);
up(&vc4->async_modeset);
-
- kfree(c);
}
-static void
-vc4_atomic_complete_commit_seqno_cb(struct vc4_seqno_cb *cb)
+static void commit_work(struct work_struct *work)
{
- struct vc4_commit *c = container_of(cb, struct vc4_commit, cb);
-
- vc4_atomic_complete_commit(c);
-}
-
-static struct vc4_commit *commit_init(struct drm_atomic_state *state)
-{
- struct vc4_commit *c = kzalloc(sizeof(*c), GFP_KERNEL);
-
- if (!c)
- return NULL;
- c->dev = state->dev;
- c->state = state;
-
- return c;
+ struct drm_atomic_state *state = container_of(work,
+ struct drm_atomic_state,
+ commit_work);
+ vc4_atomic_complete_commit(state);
}
/**
@@ -115,40 +95,29 @@ static int vc4_atomic_commit(struct drm_device *dev,
{
struct vc4_dev *vc4 = to_vc4_dev(dev);
int ret;
- int i;
- uint64_t wait_seqno = 0;
- struct vc4_commit *c;
- struct drm_plane *plane;
- struct drm_plane_state *new_state;
-
- c = commit_init(state);
- if (!c)
- return -ENOMEM;
ret = drm_atomic_helper_setup_commit(state, nonblock);
if (ret)
return ret;
+ INIT_WORK(&state->commit_work, commit_work);
+
ret = down_interruptible(&vc4->async_modeset);
- if (ret) {
- kfree(c);
+ if (ret)
return ret;
- }
ret = drm_atomic_helper_prepare_planes(dev, state);
if (ret) {
- kfree(c);
up(&vc4->async_modeset);
return ret;
}
- for_each_plane_in_state(state, plane, new_state, i) {
- if ((plane->state->fb != new_state->fb) && new_state->fb) {
- struct drm_gem_cma_object *cma_bo =
- drm_fb_cma_get_gem_obj(new_state->fb, 0);
- struct vc4_bo *bo = to_vc4_bo(&cma_bo->base);
-
- wait_seqno = max(bo->seqno, wait_seqno);
+ if (!nonblock) {
+ ret = drm_atomic_helper_wait_for_fences(dev, state, true);
+ if (ret) {
+ drm_atomic_helper_cleanup_planes(dev, state);
+ up(&vc4->async_modeset);
+ return ret;
}
}
@@ -158,7 +127,7 @@ static int vc4_atomic_commit(struct drm_device *dev,
* the software side now.
*/
- drm_atomic_helper_swap_state(state, true);
+ BUG_ON(drm_atomic_helper_swap_state(state, false) < 0);
/*
* Everything below can be run asynchronously without the need to grab
@@ -177,13 +146,10 @@ static int vc4_atomic_commit(struct drm_device *dev,
*/
drm_atomic_state_get(state);
- if (nonblock) {
- vc4_queue_seqno_cb(dev, &c->cb, wait_seqno,
- vc4_atomic_complete_commit_seqno_cb);
- } else {
- vc4_wait_for_seqno(dev, wait_seqno, ~0ull, false);
- vc4_atomic_complete_commit(c);
- }
+ if (nonblock)
+ queue_work(system_unbound_wq, &state->commit_work);
+ else
+ vc4_atomic_complete_commit(state);
return 0;
}
@@ -204,7 +170,7 @@ static struct drm_framebuffer *vc4_fb_create(struct drm_device *dev,
gem_obj = drm_gem_object_lookup(file_priv,
mode_cmd->handles[0]);
if (!gem_obj) {
- DRM_ERROR("Failed to look up GEM BO %d\n",
+ DRM_DEBUG("Failed to look up GEM BO %d\n",
mode_cmd->handles[0]);
return ERR_PTR(-ENOENT);
}
@@ -219,12 +185,12 @@ static struct drm_framebuffer *vc4_fb_create(struct drm_device *dev,
mode_cmd_local.modifier[0] = DRM_FORMAT_MOD_NONE;
}
- drm_gem_object_unreference_unlocked(gem_obj);
+ drm_gem_object_put_unlocked(gem_obj);
mode_cmd = &mode_cmd_local;
}
- return drm_fb_cma_create(dev, file_priv, mode_cmd);
+ return drm_gem_fb_create(dev, file_priv, mode_cmd);
}
static const struct drm_mode_config_funcs vc4_mode_funcs = {
@@ -241,6 +207,9 @@ int vc4_kms_load(struct drm_device *dev)
sema_init(&vc4->async_modeset, 1);
+ /* Set support for vblank irq fast disable, before drm_vblank_init() */
+ dev->vblank_disable_immediate = true;
+
ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
if (ret < 0) {
dev_err(dev->dev, "failed to initialize vblank\n");
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index fa6809d..2968b3e 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -759,9 +759,26 @@ void vc4_plane_async_set_fb(struct drm_plane *plane, struct drm_framebuffer *fb)
vc4_state->dlist[vc4_state->ptr0_offset] = addr;
}
+static int vc4_prepare_fb(struct drm_plane *plane,
+ struct drm_plane_state *state)
+{
+ struct vc4_bo *bo;
+ struct dma_fence *fence;
+
+ if ((plane->state->fb == state->fb) || !state->fb)
+ return 0;
+
+ bo = to_vc4_bo(&drm_fb_cma_get_gem_obj(state->fb, 0)->base);
+ fence = reservation_object_get_excl_rcu(bo->resv);
+ drm_atomic_set_fence_for_plane(state, fence);
+
+ return 0;
+}
+
static const struct drm_plane_helper_funcs vc4_plane_helper_funcs = {
.atomic_check = vc4_plane_atomic_check,
.atomic_update = vc4_plane_atomic_update,
+ .prepare_fb = vc4_prepare_fb,
};
static void vc4_plane_destroy(struct drm_plane *plane)
@@ -885,7 +902,7 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev,
ret = drm_universal_plane_init(dev, plane, 0,
&vc4_plane_funcs,
formats, num_formats,
- type, NULL);
+ NULL, type, NULL);
drm_plane_helper_add(plane, &vc4_plane_helper_funcs);
diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
index d382c34..55677bd 100644
--- a/drivers/gpu/drm/vc4/vc4_regs.h
+++ b/drivers/gpu/drm/vc4/vc4_regs.h
@@ -561,16 +561,129 @@
# define VC4_HDMI_VERTB_VBP_MASK VC4_MASK(8, 0)
# define VC4_HDMI_VERTB_VBP_SHIFT 0
+#define VC4_HDMI_CEC_CNTRL_1 0x0e8
+/* Set when the transmission has ended. */
+# define VC4_HDMI_CEC_TX_EOM BIT(31)
+/* If set, transmission was acked on the 1st or 2nd attempt (only one
+ * retry is attempted). If in continuous mode, this means TX needs to
+ * be filled if !TX_EOM.
+ */
+# define VC4_HDMI_CEC_TX_STATUS_GOOD BIT(30)
+# define VC4_HDMI_CEC_RX_EOM BIT(29)
+# define VC4_HDMI_CEC_RX_STATUS_GOOD BIT(28)
+/* Number of bytes received for the message. */
+# define VC4_HDMI_CEC_REC_WRD_CNT_MASK VC4_MASK(27, 24)
+# define VC4_HDMI_CEC_REC_WRD_CNT_SHIFT 24
+/* Sets continuous receive mode. Generates interrupt after each 8
+ * bytes to signal that RX_DATA should be consumed, and at RX_EOM.
+ *
+ * If disabled, maximum 16 bytes will be received (including header),
+ * and interrupt at RX_EOM. Later bytes will be acked but not put
+ * into the RX_DATA.
+ */
+# define VC4_HDMI_CEC_RX_CONTINUE BIT(23)
+# define VC4_HDMI_CEC_TX_CONTINUE BIT(22)
+/* Set this after a CEC interrupt. */
+# define VC4_HDMI_CEC_CLEAR_RECEIVE_OFF BIT(21)
+/* Starts a TX. Will wait for appropriate idel time before CEC
+ * activity. Must be cleared in between transmits.
+ */
+# define VC4_HDMI_CEC_START_XMIT_BEGIN BIT(20)
+# define VC4_HDMI_CEC_MESSAGE_LENGTH_MASK VC4_MASK(19, 16)
+# define VC4_HDMI_CEC_MESSAGE_LENGTH_SHIFT 16
+/* Device's CEC address */
+# define VC4_HDMI_CEC_ADDR_MASK VC4_MASK(15, 12)
+# define VC4_HDMI_CEC_ADDR_SHIFT 12
+/* Divides off of HSM clock to generate CEC bit clock. */
+/* With the current defaults the CEC bit clock is 40 kHz = 25 usec */
+# define VC4_HDMI_CEC_DIV_CLK_CNT_MASK VC4_MASK(11, 0)
+# define VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT 0
+
+/* Set these fields to how many bit clock cycles get to that many
+ * microseconds.
+ */
+#define VC4_HDMI_CEC_CNTRL_2 0x0ec
+# define VC4_HDMI_CEC_CNT_TO_1500_US_MASK VC4_MASK(30, 24)
+# define VC4_HDMI_CEC_CNT_TO_1500_US_SHIFT 24
+# define VC4_HDMI_CEC_CNT_TO_1300_US_MASK VC4_MASK(23, 17)
+# define VC4_HDMI_CEC_CNT_TO_1300_US_SHIFT 17
+# define VC4_HDMI_CEC_CNT_TO_800_US_MASK VC4_MASK(16, 11)
+# define VC4_HDMI_CEC_CNT_TO_800_US_SHIFT 11
+# define VC4_HDMI_CEC_CNT_TO_600_US_MASK VC4_MASK(10, 5)
+# define VC4_HDMI_CEC_CNT_TO_600_US_SHIFT 5
+# define VC4_HDMI_CEC_CNT_TO_400_US_MASK VC4_MASK(4, 0)
+# define VC4_HDMI_CEC_CNT_TO_400_US_SHIFT 0
+
+#define VC4_HDMI_CEC_CNTRL_3 0x0f0
+# define VC4_HDMI_CEC_CNT_TO_2750_US_MASK VC4_MASK(31, 24)
+# define VC4_HDMI_CEC_CNT_TO_2750_US_SHIFT 24
+# define VC4_HDMI_CEC_CNT_TO_2400_US_MASK VC4_MASK(23, 16)
+# define VC4_HDMI_CEC_CNT_TO_2400_US_SHIFT 16
+# define VC4_HDMI_CEC_CNT_TO_2050_US_MASK VC4_MASK(15, 8)
+# define VC4_HDMI_CEC_CNT_TO_2050_US_SHIFT 8
+# define VC4_HDMI_CEC_CNT_TO_1700_US_MASK VC4_MASK(7, 0)
+# define VC4_HDMI_CEC_CNT_TO_1700_US_SHIFT 0
+
+#define VC4_HDMI_CEC_CNTRL_4 0x0f4
+# define VC4_HDMI_CEC_CNT_TO_4300_US_MASK VC4_MASK(31, 24)
+# define VC4_HDMI_CEC_CNT_TO_4300_US_SHIFT 24
+# define VC4_HDMI_CEC_CNT_TO_3900_US_MASK VC4_MASK(23, 16)
+# define VC4_HDMI_CEC_CNT_TO_3900_US_SHIFT 16
+# define VC4_HDMI_CEC_CNT_TO_3600_US_MASK VC4_MASK(15, 8)
+# define VC4_HDMI_CEC_CNT_TO_3600_US_SHIFT 8
+# define VC4_HDMI_CEC_CNT_TO_3500_US_MASK VC4_MASK(7, 0)
+# define VC4_HDMI_CEC_CNT_TO_3500_US_SHIFT 0
+
+#define VC4_HDMI_CEC_CNTRL_5 0x0f8
+# define VC4_HDMI_CEC_TX_SW_RESET BIT(27)
+# define VC4_HDMI_CEC_RX_SW_RESET BIT(26)
+# define VC4_HDMI_CEC_PAD_SW_RESET BIT(25)
+# define VC4_HDMI_CEC_MUX_TP_OUT_CEC BIT(24)
+# define VC4_HDMI_CEC_RX_CEC_INT BIT(23)
+# define VC4_HDMI_CEC_CLK_PRELOAD_MASK VC4_MASK(22, 16)
+# define VC4_HDMI_CEC_CLK_PRELOAD_SHIFT 16
+# define VC4_HDMI_CEC_CNT_TO_4700_US_MASK VC4_MASK(15, 8)
+# define VC4_HDMI_CEC_CNT_TO_4700_US_SHIFT 8
+# define VC4_HDMI_CEC_CNT_TO_4500_US_MASK VC4_MASK(7, 0)
+# define VC4_HDMI_CEC_CNT_TO_4500_US_SHIFT 0
+
+/* Transmit data, first byte is low byte of the 32-bit reg. MSB of
+ * each byte transmitted first.
+ */
+#define VC4_HDMI_CEC_TX_DATA_1 0x0fc
+#define VC4_HDMI_CEC_TX_DATA_2 0x100
+#define VC4_HDMI_CEC_TX_DATA_3 0x104
+#define VC4_HDMI_CEC_TX_DATA_4 0x108
+#define VC4_HDMI_CEC_RX_DATA_1 0x10c
+#define VC4_HDMI_CEC_RX_DATA_2 0x110
+#define VC4_HDMI_CEC_RX_DATA_3 0x114
+#define VC4_HDMI_CEC_RX_DATA_4 0x118
+
#define VC4_HDMI_TX_PHY_RESET_CTL 0x2c0
#define VC4_HDMI_TX_PHY_CTL0 0x2c4
# define VC4_HDMI_TX_PHY_RNG_PWRDN BIT(25)
+/* Interrupt status bits */
+#define VC4_HDMI_CPU_STATUS 0x340
+#define VC4_HDMI_CPU_SET 0x344
+#define VC4_HDMI_CPU_CLEAR 0x348
+# define VC4_HDMI_CPU_CEC BIT(6)
+# define VC4_HDMI_CPU_HOTPLUG BIT(0)
+
+#define VC4_HDMI_CPU_MASK_STATUS 0x34c
+#define VC4_HDMI_CPU_MASK_SET 0x350
+#define VC4_HDMI_CPU_MASK_CLEAR 0x354
+
#define VC4_HDMI_GCP(x) (0x400 + ((x) * 0x4))
#define VC4_HDMI_RAM_PACKET(x) (0x400 + ((x) * 0x24))
#define VC4_HDMI_PACKET_STRIDE 0x24
#define VC4_HD_M_CTL 0x00c
+/* Debug: Current receive value on the CEC pad. */
+# define VC4_HD_CECRXD BIT(9)
+/* Debug: Override CEC output to 0. */
+# define VC4_HD_CECOVR BIT(8)
# define VC4_HD_M_REGISTER_FILE_STANDBY (3 << 6)
# define VC4_HD_M_RAM_STANDBY (3 << 4)
# define VC4_HD_M_SW_RST BIT(2)
diff --git a/drivers/gpu/drm/vc4/vc4_render_cl.c b/drivers/gpu/drm/vc4/vc4_render_cl.c
index 5dc1942..273984f 100644
--- a/drivers/gpu/drm/vc4/vc4_render_cl.c
+++ b/drivers/gpu/drm/vc4/vc4_render_cl.c
@@ -261,8 +261,17 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec,
uint8_t max_y_tile = args->max_y_tile;
uint8_t xtiles = max_x_tile - min_x_tile + 1;
uint8_t ytiles = max_y_tile - min_y_tile + 1;
- uint8_t x, y;
+ uint8_t xi, yi;
uint32_t size, loop_body_size;
+ bool positive_x = true;
+ bool positive_y = true;
+
+ if (args->flags & VC4_SUBMIT_CL_FIXED_RCL_ORDER) {
+ if (!(args->flags & VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X))
+ positive_x = false;
+ if (!(args->flags & VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y))
+ positive_y = false;
+ }
size = VC4_PACKET_TILE_RENDERING_MODE_CONFIG_SIZE;
loop_body_size = VC4_PACKET_TILE_COORDINATES_SIZE;
@@ -320,7 +329,7 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec,
size += xtiles * ytiles * loop_body_size;
- setup->rcl = &vc4_bo_create(dev, size, true)->base;
+ setup->rcl = &vc4_bo_create(dev, size, true, VC4_BO_TYPE_RCL)->base;
if (IS_ERR(setup->rcl))
return PTR_ERR(setup->rcl);
list_add_tail(&to_vc4_bo(&setup->rcl->base)->unref_head,
@@ -354,10 +363,12 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec,
rcl_u16(setup, args->height);
rcl_u16(setup, args->color_write.bits);
- for (y = min_y_tile; y <= max_y_tile; y++) {
- for (x = min_x_tile; x <= max_x_tile; x++) {
- bool first = (x == min_x_tile && y == min_y_tile);
- bool last = (x == max_x_tile && y == max_y_tile);
+ for (yi = 0; yi < ytiles; yi++) {
+ int y = positive_y ? min_y_tile + yi : max_y_tile - yi;
+ for (xi = 0; xi < xtiles; xi++) {
+ int x = positive_x ? min_x_tile + xi : max_x_tile - xi;
+ bool first = (xi == 0 && yi == 0);
+ bool last = (xi == xtiles - 1 && yi == ytiles - 1);
emit_tile(exec, setup, x, y, first, last);
}
@@ -378,14 +389,14 @@ static int vc4_full_res_bounds_check(struct vc4_exec_info *exec,
u32 render_tiles_stride = DIV_ROUND_UP(exec->args->width, 32);
if (surf->offset > obj->base.size) {
- DRM_ERROR("surface offset %d > BO size %zd\n",
+ DRM_DEBUG("surface offset %d > BO size %zd\n",
surf->offset, obj->base.size);
return -EINVAL;
}
if ((obj->base.size - surf->offset) / VC4_TILE_BUFFER_SIZE <
render_tiles_stride * args->max_y_tile + args->max_x_tile) {
- DRM_ERROR("MSAA tile %d, %d out of bounds "
+ DRM_DEBUG("MSAA tile %d, %d out of bounds "
"(bo size %zd, offset %d).\n",
args->max_x_tile, args->max_y_tile,
obj->base.size,
@@ -401,7 +412,7 @@ static int vc4_rcl_msaa_surface_setup(struct vc4_exec_info *exec,
struct drm_vc4_submit_rcl_surface *surf)
{
if (surf->flags != 0 || surf->bits != 0) {
- DRM_ERROR("MSAA surface had nonzero flags/bits\n");
+ DRM_DEBUG("MSAA surface had nonzero flags/bits\n");
return -EINVAL;
}
@@ -415,7 +426,7 @@ static int vc4_rcl_msaa_surface_setup(struct vc4_exec_info *exec,
exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj;
if (surf->offset & 0xf) {
- DRM_ERROR("MSAA write must be 16b aligned.\n");
+ DRM_DEBUG("MSAA write must be 16b aligned.\n");
return -EINVAL;
}
@@ -437,7 +448,7 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec,
int ret;
if (surf->flags & ~VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) {
- DRM_ERROR("Extra flags set\n");
+ DRM_DEBUG("Extra flags set\n");
return -EINVAL;
}
@@ -453,12 +464,12 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec,
if (surf->flags & VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) {
if (surf == &exec->args->zs_write) {
- DRM_ERROR("general zs write may not be a full-res.\n");
+ DRM_DEBUG("general zs write may not be a full-res.\n");
return -EINVAL;
}
if (surf->bits != 0) {
- DRM_ERROR("load/store general bits set with "
+ DRM_DEBUG("load/store general bits set with "
"full res load/store.\n");
return -EINVAL;
}
@@ -473,19 +484,19 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec,
if (surf->bits & ~(VC4_LOADSTORE_TILE_BUFFER_TILING_MASK |
VC4_LOADSTORE_TILE_BUFFER_BUFFER_MASK |
VC4_LOADSTORE_TILE_BUFFER_FORMAT_MASK)) {
- DRM_ERROR("Unknown bits in load/store: 0x%04x\n",
+ DRM_DEBUG("Unknown bits in load/store: 0x%04x\n",
surf->bits);
return -EINVAL;
}
if (tiling > VC4_TILING_FORMAT_LT) {
- DRM_ERROR("Bad tiling format\n");
+ DRM_DEBUG("Bad tiling format\n");
return -EINVAL;
}
if (buffer == VC4_LOADSTORE_TILE_BUFFER_ZS) {
if (format != 0) {
- DRM_ERROR("No color format should be set for ZS\n");
+ DRM_DEBUG("No color format should be set for ZS\n");
return -EINVAL;
}
cpp = 4;
@@ -499,16 +510,16 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec,
cpp = 4;
break;
default:
- DRM_ERROR("Bad tile buffer format\n");
+ DRM_DEBUG("Bad tile buffer format\n");
return -EINVAL;
}
} else {
- DRM_ERROR("Bad load/store buffer %d.\n", buffer);
+ DRM_DEBUG("Bad load/store buffer %d.\n", buffer);
return -EINVAL;
}
if (surf->offset & 0xf) {
- DRM_ERROR("load/store buffer must be 16b aligned.\n");
+ DRM_DEBUG("load/store buffer must be 16b aligned.\n");
return -EINVAL;
}
@@ -533,7 +544,7 @@ vc4_rcl_render_config_surface_setup(struct vc4_exec_info *exec,
int cpp;
if (surf->flags != 0) {
- DRM_ERROR("No flags supported on render config.\n");
+ DRM_DEBUG("No flags supported on render config.\n");
return -EINVAL;
}
@@ -541,7 +552,7 @@ vc4_rcl_render_config_surface_setup(struct vc4_exec_info *exec,
VC4_RENDER_CONFIG_FORMAT_MASK |
VC4_RENDER_CONFIG_MS_MODE_4X |
VC4_RENDER_CONFIG_DECIMATE_MODE_4X)) {
- DRM_ERROR("Unknown bits in render config: 0x%04x\n",
+ DRM_DEBUG("Unknown bits in render config: 0x%04x\n",
surf->bits);
return -EINVAL;
}
@@ -556,7 +567,7 @@ vc4_rcl_render_config_surface_setup(struct vc4_exec_info *exec,
exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj;
if (tiling > VC4_TILING_FORMAT_LT) {
- DRM_ERROR("Bad tiling format\n");
+ DRM_DEBUG("Bad tiling format\n");
return -EINVAL;
}
@@ -569,7 +580,7 @@ vc4_rcl_render_config_surface_setup(struct vc4_exec_info *exec,
cpp = 4;
break;
default:
- DRM_ERROR("Bad tile buffer format\n");
+ DRM_DEBUG("Bad tile buffer format\n");
return -EINVAL;
}
@@ -590,7 +601,7 @@ int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec)
if (args->min_x_tile > args->max_x_tile ||
args->min_y_tile > args->max_y_tile) {
- DRM_ERROR("Bad render tile set (%d,%d)-(%d,%d)\n",
+ DRM_DEBUG("Bad render tile set (%d,%d)-(%d,%d)\n",
args->min_x_tile, args->min_y_tile,
args->max_x_tile, args->max_y_tile);
return -EINVAL;
@@ -599,7 +610,7 @@ int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec)
if (has_bin &&
(args->max_x_tile > exec->bin_tiles_x ||
args->max_y_tile > exec->bin_tiles_y)) {
- DRM_ERROR("Render tiles (%d,%d) outside of bin config "
+ DRM_DEBUG("Render tiles (%d,%d) outside of bin config "
"(%d,%d)\n",
args->max_x_tile, args->max_y_tile,
exec->bin_tiles_x, exec->bin_tiles_y);
@@ -642,7 +653,7 @@ int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec)
*/
if (!setup.color_write && !setup.zs_write &&
!setup.msaa_color_write && !setup.msaa_zs_write) {
- DRM_ERROR("RCL requires color or Z/S write\n");
+ DRM_DEBUG("RCL requires color or Z/S write\n");
return -EINVAL;
}
diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c
index 8c723da..622cd43 100644
--- a/drivers/gpu/drm/vc4/vc4_v3d.c
+++ b/drivers/gpu/drm/vc4/vc4_v3d.c
@@ -236,7 +236,8 @@ vc4_allocate_bin_bo(struct drm_device *drm)
INIT_LIST_HEAD(&list);
while (true) {
- struct vc4_bo *bo = vc4_bo_create(drm, size, true);
+ struct vc4_bo *bo = vc4_bo_create(drm, size, true,
+ VC4_BO_TYPE_BIN);
if (IS_ERR(bo)) {
ret = PTR_ERR(bo);
diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c
index 814b512..2db485a 100644
--- a/drivers/gpu/drm/vc4/vc4_validate.c
+++ b/drivers/gpu/drm/vc4/vc4_validate.c
@@ -109,7 +109,7 @@ vc4_use_bo(struct vc4_exec_info *exec, uint32_t hindex)
struct vc4_bo *bo;
if (hindex >= exec->bo_count) {
- DRM_ERROR("BO index %d greater than BO count %d\n",
+ DRM_DEBUG("BO index %d greater than BO count %d\n",
hindex, exec->bo_count);
return NULL;
}
@@ -117,7 +117,7 @@ vc4_use_bo(struct vc4_exec_info *exec, uint32_t hindex)
bo = to_vc4_bo(&obj->base);
if (bo->validated_shader) {
- DRM_ERROR("Trying to use shader BO as something other than "
+ DRM_DEBUG("Trying to use shader BO as something other than "
"a shader\n");
return NULL;
}
@@ -172,7 +172,7 @@ vc4_check_tex_size(struct vc4_exec_info *exec, struct drm_gem_cma_object *fbo,
* our math.
*/
if (width > 4096 || height > 4096) {
- DRM_ERROR("Surface dimensions (%d,%d) too large",
+ DRM_DEBUG("Surface dimensions (%d,%d) too large",
width, height);
return false;
}
@@ -191,7 +191,7 @@ vc4_check_tex_size(struct vc4_exec_info *exec, struct drm_gem_cma_object *fbo,
aligned_height = round_up(height, utile_h);
break;
default:
- DRM_ERROR("buffer tiling %d unsupported\n", tiling_format);
+ DRM_DEBUG("buffer tiling %d unsupported\n", tiling_format);
return false;
}
@@ -200,7 +200,7 @@ vc4_check_tex_size(struct vc4_exec_info *exec, struct drm_gem_cma_object *fbo,
if (size + offset < size ||
size + offset > fbo->base.size) {
- DRM_ERROR("Overflow in %dx%d (%dx%d) fbo size (%d + %d > %zd)\n",
+ DRM_DEBUG("Overflow in %dx%d (%dx%d) fbo size (%d + %d > %zd)\n",
width, height,
aligned_width, aligned_height,
size, offset, fbo->base.size);
@@ -214,7 +214,7 @@ static int
validate_flush(VALIDATE_ARGS)
{
if (!validate_bin_pos(exec, untrusted, exec->args->bin_cl_size - 1)) {
- DRM_ERROR("Bin CL must end with VC4_PACKET_FLUSH\n");
+ DRM_DEBUG("Bin CL must end with VC4_PACKET_FLUSH\n");
return -EINVAL;
}
exec->found_flush = true;
@@ -226,13 +226,13 @@ static int
validate_start_tile_binning(VALIDATE_ARGS)
{
if (exec->found_start_tile_binning_packet) {
- DRM_ERROR("Duplicate VC4_PACKET_START_TILE_BINNING\n");
+ DRM_DEBUG("Duplicate VC4_PACKET_START_TILE_BINNING\n");
return -EINVAL;
}
exec->found_start_tile_binning_packet = true;
if (!exec->found_tile_binning_mode_config_packet) {
- DRM_ERROR("missing VC4_PACKET_TILE_BINNING_MODE_CONFIG\n");
+ DRM_DEBUG("missing VC4_PACKET_TILE_BINNING_MODE_CONFIG\n");
return -EINVAL;
}
@@ -243,7 +243,7 @@ static int
validate_increment_semaphore(VALIDATE_ARGS)
{
if (!validate_bin_pos(exec, untrusted, exec->args->bin_cl_size - 2)) {
- DRM_ERROR("Bin CL must end with "
+ DRM_DEBUG("Bin CL must end with "
"VC4_PACKET_INCREMENT_SEMAPHORE\n");
return -EINVAL;
}
@@ -264,7 +264,7 @@ validate_indexed_prim_list(VALIDATE_ARGS)
/* Check overflow condition */
if (exec->shader_state_count == 0) {
- DRM_ERROR("shader state must precede primitives\n");
+ DRM_DEBUG("shader state must precede primitives\n");
return -EINVAL;
}
shader_state = &exec->shader_state[exec->shader_state_count - 1];
@@ -281,7 +281,7 @@ validate_indexed_prim_list(VALIDATE_ARGS)
if (offset > ib->base.size ||
(ib->base.size - offset) / index_size < length) {
- DRM_ERROR("IB access overflow (%d + %d*%d > %zd)\n",
+ DRM_DEBUG("IB access overflow (%d + %d*%d > %zd)\n",
offset, length, index_size, ib->base.size);
return -EINVAL;
}
@@ -301,13 +301,13 @@ validate_gl_array_primitive(VALIDATE_ARGS)
/* Check overflow condition */
if (exec->shader_state_count == 0) {
- DRM_ERROR("shader state must precede primitives\n");
+ DRM_DEBUG("shader state must precede primitives\n");
return -EINVAL;
}
shader_state = &exec->shader_state[exec->shader_state_count - 1];
if (length + base_index < length) {
- DRM_ERROR("primitive vertex count overflow\n");
+ DRM_DEBUG("primitive vertex count overflow\n");
return -EINVAL;
}
max_index = length + base_index - 1;
@@ -324,7 +324,7 @@ validate_gl_shader_state(VALIDATE_ARGS)
uint32_t i = exec->shader_state_count++;
if (i >= exec->shader_state_size) {
- DRM_ERROR("More requests for shader states than declared\n");
+ DRM_DEBUG("More requests for shader states than declared\n");
return -EINVAL;
}
@@ -332,7 +332,7 @@ validate_gl_shader_state(VALIDATE_ARGS)
exec->shader_state[i].max_index = 0;
if (exec->shader_state[i].addr & ~0xf) {
- DRM_ERROR("high bits set in GL shader rec reference\n");
+ DRM_DEBUG("high bits set in GL shader rec reference\n");
return -EINVAL;
}
@@ -356,7 +356,7 @@ validate_tile_binning_config(VALIDATE_ARGS)
int bin_slot;
if (exec->found_tile_binning_mode_config_packet) {
- DRM_ERROR("Duplicate VC4_PACKET_TILE_BINNING_MODE_CONFIG\n");
+ DRM_DEBUG("Duplicate VC4_PACKET_TILE_BINNING_MODE_CONFIG\n");
return -EINVAL;
}
exec->found_tile_binning_mode_config_packet = true;
@@ -368,14 +368,14 @@ validate_tile_binning_config(VALIDATE_ARGS)
if (exec->bin_tiles_x == 0 ||
exec->bin_tiles_y == 0) {
- DRM_ERROR("Tile binning config of %dx%d too small\n",
+ DRM_DEBUG("Tile binning config of %dx%d too small\n",
exec->bin_tiles_x, exec->bin_tiles_y);
return -EINVAL;
}
if (flags & (VC4_BIN_CONFIG_DB_NON_MS |
VC4_BIN_CONFIG_TILE_BUFFER_64BIT)) {
- DRM_ERROR("unsupported binning config flags 0x%02x\n", flags);
+ DRM_DEBUG("unsupported binning config flags 0x%02x\n", flags);
return -EINVAL;
}
@@ -493,20 +493,20 @@ vc4_validate_bin_cl(struct drm_device *dev,
const struct cmd_info *info;
if (cmd >= ARRAY_SIZE(cmd_info)) {
- DRM_ERROR("0x%08x: packet %d out of bounds\n",
+ DRM_DEBUG("0x%08x: packet %d out of bounds\n",
src_offset, cmd);
return -EINVAL;
}
info = &cmd_info[cmd];
if (!info->name) {
- DRM_ERROR("0x%08x: packet %d invalid\n",
+ DRM_DEBUG("0x%08x: packet %d invalid\n",
src_offset, cmd);
return -EINVAL;
}
if (src_offset + info->len > len) {
- DRM_ERROR("0x%08x: packet %d (%s) length 0x%08x "
+ DRM_DEBUG("0x%08x: packet %d (%s) length 0x%08x "
"exceeds bounds (0x%08x)\n",
src_offset, cmd, info->name, info->len,
src_offset + len);
@@ -519,7 +519,7 @@ vc4_validate_bin_cl(struct drm_device *dev,
if (info->func && info->func(exec,
dst_pkt + 1,
src_pkt + 1)) {
- DRM_ERROR("0x%08x: packet %d (%s) failed to validate\n",
+ DRM_DEBUG("0x%08x: packet %d (%s) failed to validate\n",
src_offset, cmd, info->name);
return -EINVAL;
}
@@ -537,7 +537,7 @@ vc4_validate_bin_cl(struct drm_device *dev,
exec->ct0ea = exec->ct0ca + dst_offset;
if (!exec->found_start_tile_binning_packet) {
- DRM_ERROR("Bin CL missing VC4_PACKET_START_TILE_BINNING\n");
+ DRM_DEBUG("Bin CL missing VC4_PACKET_START_TILE_BINNING\n");
return -EINVAL;
}
@@ -549,7 +549,7 @@ vc4_validate_bin_cl(struct drm_device *dev,
* semaphore increment.
*/
if (!exec->found_increment_semaphore_packet || !exec->found_flush) {
- DRM_ERROR("Bin CL missing VC4_PACKET_INCREMENT_SEMAPHORE + "
+ DRM_DEBUG("Bin CL missing VC4_PACKET_INCREMENT_SEMAPHORE + "
"VC4_PACKET_FLUSH\n");
return -EINVAL;
}
@@ -588,11 +588,11 @@ reloc_tex(struct vc4_exec_info *exec,
uint32_t remaining_size = tex->base.size - p0;
if (p0 > tex->base.size - 4) {
- DRM_ERROR("UBO offset greater than UBO size\n");
+ DRM_DEBUG("UBO offset greater than UBO size\n");
goto fail;
}
if (p1 > remaining_size - 4) {
- DRM_ERROR("UBO clamp would allow reads "
+ DRM_DEBUG("UBO clamp would allow reads "
"outside of UBO\n");
goto fail;
}
@@ -612,14 +612,14 @@ reloc_tex(struct vc4_exec_info *exec,
if (VC4_GET_FIELD(p3, VC4_TEX_P2_PTYPE) ==
VC4_TEX_P2_PTYPE_CUBE_MAP_STRIDE) {
if (cube_map_stride) {
- DRM_ERROR("Cube map stride set twice\n");
+ DRM_DEBUG("Cube map stride set twice\n");
goto fail;
}
cube_map_stride = p3 & VC4_TEX_P2_CMST_MASK;
}
if (!cube_map_stride) {
- DRM_ERROR("Cube map stride not set\n");
+ DRM_DEBUG("Cube map stride not set\n");
goto fail;
}
}
@@ -660,7 +660,7 @@ reloc_tex(struct vc4_exec_info *exec,
case VC4_TEXTURE_TYPE_RGBA64:
case VC4_TEXTURE_TYPE_YUV422R:
default:
- DRM_ERROR("Texture format %d unsupported\n", type);
+ DRM_DEBUG("Texture format %d unsupported\n", type);
goto fail;
}
utile_w = utile_width(cpp);
@@ -713,7 +713,7 @@ reloc_tex(struct vc4_exec_info *exec,
level_size = aligned_width * cpp * aligned_height;
if (offset < level_size) {
- DRM_ERROR("Level %d (%dx%d -> %dx%d) size %db "
+ DRM_DEBUG("Level %d (%dx%d -> %dx%d) size %db "
"overflowed buffer bounds (offset %d)\n",
i, level_width, level_height,
aligned_width, aligned_height,
@@ -764,7 +764,7 @@ validate_gl_shader_rec(struct drm_device *dev,
nr_relocs = ARRAY_SIZE(shader_reloc_offsets) + nr_attributes;
if (nr_relocs * 4 > exec->shader_rec_size) {
- DRM_ERROR("overflowed shader recs reading %d handles "
+ DRM_DEBUG("overflowed shader recs reading %d handles "
"from %d bytes left\n",
nr_relocs, exec->shader_rec_size);
return -EINVAL;
@@ -774,7 +774,7 @@ validate_gl_shader_rec(struct drm_device *dev,
exec->shader_rec_size -= nr_relocs * 4;
if (packet_size > exec->shader_rec_size) {
- DRM_ERROR("overflowed shader recs copying %db packet "
+ DRM_DEBUG("overflowed shader recs copying %db packet "
"from %d bytes left\n",
packet_size, exec->shader_rec_size);
return -EINVAL;
@@ -794,7 +794,7 @@ validate_gl_shader_rec(struct drm_device *dev,
for (i = 0; i < shader_reloc_count; i++) {
if (src_handles[i] > exec->bo_count) {
- DRM_ERROR("Shader handle %d too big\n", src_handles[i]);
+ DRM_DEBUG("Shader handle %d too big\n", src_handles[i]);
return -EINVAL;
}
@@ -810,13 +810,13 @@ validate_gl_shader_rec(struct drm_device *dev,
if (((*(uint16_t *)pkt_u & VC4_SHADER_FLAG_FS_SINGLE_THREAD) == 0) !=
to_vc4_bo(&bo[0]->base)->validated_shader->is_threaded) {
- DRM_ERROR("Thread mode of CL and FS do not match\n");
+ DRM_DEBUG("Thread mode of CL and FS do not match\n");
return -EINVAL;
}
if (to_vc4_bo(&bo[1]->base)->validated_shader->is_threaded ||
to_vc4_bo(&bo[2]->base)->validated_shader->is_threaded) {
- DRM_ERROR("cs and vs cannot be threaded\n");
+ DRM_DEBUG("cs and vs cannot be threaded\n");
return -EINVAL;
}
@@ -831,7 +831,7 @@ validate_gl_shader_rec(struct drm_device *dev,
*(uint32_t *)(pkt_v + o) = bo[i]->paddr + src_offset;
if (src_offset != 0) {
- DRM_ERROR("Shaders must be at offset 0 of "
+ DRM_DEBUG("Shaders must be at offset 0 of "
"the BO.\n");
return -EINVAL;
}
@@ -842,7 +842,7 @@ validate_gl_shader_rec(struct drm_device *dev,
if (validated_shader->uniforms_src_size >
exec->uniforms_size) {
- DRM_ERROR("Uniforms src buffer overflow\n");
+ DRM_DEBUG("Uniforms src buffer overflow\n");
return -EINVAL;
}
@@ -900,7 +900,7 @@ validate_gl_shader_rec(struct drm_device *dev,
if (vbo->base.size < offset ||
vbo->base.size - offset < attr_size) {
- DRM_ERROR("BO offset overflow (%d + %d > %zu)\n",
+ DRM_DEBUG("BO offset overflow (%d + %d > %zu)\n",
offset, attr_size, vbo->base.size);
return -EINVAL;
}
@@ -909,7 +909,7 @@ validate_gl_shader_rec(struct drm_device *dev,
max_index = ((vbo->base.size - offset - attr_size) /
stride);
if (state->max_index > max_index) {
- DRM_ERROR("primitives use index %d out of "
+ DRM_DEBUG("primitives use index %d out of "
"supplied %d\n",
state->max_index, max_index);
return -EINVAL;
diff --git a/drivers/gpu/drm/vc4/vc4_validate_shaders.c b/drivers/gpu/drm/vc4/vc4_validate_shaders.c
index 0b2df5c..d3f15bf 100644
--- a/drivers/gpu/drm/vc4/vc4_validate_shaders.c
+++ b/drivers/gpu/drm/vc4/vc4_validate_shaders.c
@@ -200,7 +200,7 @@ check_tmu_write(struct vc4_validated_shader_info *validated_shader,
uint32_t clamp_reg, clamp_offset;
if (sig == QPU_SIG_SMALL_IMM) {
- DRM_ERROR("direct TMU read used small immediate\n");
+ DRM_DEBUG("direct TMU read used small immediate\n");
return false;
}
@@ -209,7 +209,7 @@ check_tmu_write(struct vc4_validated_shader_info *validated_shader,
*/
if (is_mul ||
QPU_GET_FIELD(inst, QPU_OP_ADD) != QPU_A_ADD) {
- DRM_ERROR("direct TMU load wasn't an add\n");
+ DRM_DEBUG("direct TMU load wasn't an add\n");
return false;
}
@@ -220,13 +220,13 @@ check_tmu_write(struct vc4_validated_shader_info *validated_shader,
*/
clamp_reg = raddr_add_a_to_live_reg_index(inst);
if (clamp_reg == ~0) {
- DRM_ERROR("direct TMU load wasn't clamped\n");
+ DRM_DEBUG("direct TMU load wasn't clamped\n");
return false;
}
clamp_offset = validation_state->live_min_clamp_offsets[clamp_reg];
if (clamp_offset == ~0) {
- DRM_ERROR("direct TMU load wasn't clamped\n");
+ DRM_DEBUG("direct TMU load wasn't clamped\n");
return false;
}
@@ -238,7 +238,7 @@ check_tmu_write(struct vc4_validated_shader_info *validated_shader,
if (!(add_b == QPU_MUX_A && raddr_a == QPU_R_UNIF) &&
!(add_b == QPU_MUX_B && raddr_b == QPU_R_UNIF)) {
- DRM_ERROR("direct TMU load didn't add to a uniform\n");
+ DRM_DEBUG("direct TMU load didn't add to a uniform\n");
return false;
}
@@ -246,14 +246,14 @@ check_tmu_write(struct vc4_validated_shader_info *validated_shader,
} else {
if (raddr_a == QPU_R_UNIF || (sig != QPU_SIG_SMALL_IMM &&
raddr_b == QPU_R_UNIF)) {
- DRM_ERROR("uniform read in the same instruction as "
+ DRM_DEBUG("uniform read in the same instruction as "
"texture setup.\n");
return false;
}
}
if (validation_state->tmu_write_count[tmu] >= 4) {
- DRM_ERROR("TMU%d got too many parameters before dispatch\n",
+ DRM_DEBUG("TMU%d got too many parameters before dispatch\n",
tmu);
return false;
}
@@ -265,7 +265,7 @@ check_tmu_write(struct vc4_validated_shader_info *validated_shader,
*/
if (!is_direct) {
if (validation_state->needs_uniform_address_update) {
- DRM_ERROR("Texturing with undefined uniform address\n");
+ DRM_DEBUG("Texturing with undefined uniform address\n");
return false;
}
@@ -336,35 +336,35 @@ validate_uniform_address_write(struct vc4_validated_shader_info *validated_shade
case QPU_SIG_LOAD_TMU1:
break;
default:
- DRM_ERROR("uniforms address change must be "
+ DRM_DEBUG("uniforms address change must be "
"normal math\n");
return false;
}
if (is_mul || QPU_GET_FIELD(inst, QPU_OP_ADD) != QPU_A_ADD) {
- DRM_ERROR("Uniform address reset must be an ADD.\n");
+ DRM_DEBUG("Uniform address reset must be an ADD.\n");
return false;
}
if (QPU_GET_FIELD(inst, QPU_COND_ADD) != QPU_COND_ALWAYS) {
- DRM_ERROR("Uniform address reset must be unconditional.\n");
+ DRM_DEBUG("Uniform address reset must be unconditional.\n");
return false;
}
if (QPU_GET_FIELD(inst, QPU_PACK) != QPU_PACK_A_NOP &&
!(inst & QPU_PM)) {
- DRM_ERROR("No packing allowed on uniforms reset\n");
+ DRM_DEBUG("No packing allowed on uniforms reset\n");
return false;
}
if (add_lri == -1) {
- DRM_ERROR("First argument of uniform address write must be "
+ DRM_DEBUG("First argument of uniform address write must be "
"an immediate value.\n");
return false;
}
if (validation_state->live_immediates[add_lri] != expected_offset) {
- DRM_ERROR("Resetting uniforms with offset %db instead of %db\n",
+ DRM_DEBUG("Resetting uniforms with offset %db instead of %db\n",
validation_state->live_immediates[add_lri],
expected_offset);
return false;
@@ -372,7 +372,7 @@ validate_uniform_address_write(struct vc4_validated_shader_info *validated_shade
if (!(add_b == QPU_MUX_A && raddr_a == QPU_R_UNIF) &&
!(add_b == QPU_MUX_B && raddr_b == QPU_R_UNIF)) {
- DRM_ERROR("Second argument of uniform address write must be "
+ DRM_DEBUG("Second argument of uniform address write must be "
"a uniform.\n");
return false;
}
@@ -417,7 +417,7 @@ check_reg_write(struct vc4_validated_shader_info *validated_shader,
switch (waddr) {
case QPU_W_UNIFORMS_ADDRESS:
if (is_b) {
- DRM_ERROR("relative uniforms address change "
+ DRM_DEBUG("relative uniforms address change "
"unsupported\n");
return false;
}
@@ -452,11 +452,11 @@ check_reg_write(struct vc4_validated_shader_info *validated_shader,
/* XXX: I haven't thought about these, so don't support them
* for now.
*/
- DRM_ERROR("Unsupported waddr %d\n", waddr);
+ DRM_DEBUG("Unsupported waddr %d\n", waddr);
return false;
case QPU_W_VPM_ADDR:
- DRM_ERROR("General VPM DMA unsupported\n");
+ DRM_DEBUG("General VPM DMA unsupported\n");
return false;
case QPU_W_VPM:
@@ -559,7 +559,7 @@ check_instruction_writes(struct vc4_validated_shader_info *validated_shader,
bool ok;
if (is_tmu_write(waddr_add) && is_tmu_write(waddr_mul)) {
- DRM_ERROR("ADD and MUL both set up textures\n");
+ DRM_DEBUG("ADD and MUL both set up textures\n");
return false;
}
@@ -588,7 +588,7 @@ check_branch(uint64_t inst,
* there's no need for it.
*/
if (waddr_add != QPU_W_NOP || waddr_mul != QPU_W_NOP) {
- DRM_ERROR("branch instruction at %d wrote a register.\n",
+ DRM_DEBUG("branch instruction at %d wrote a register.\n",
validation_state->ip);
return false;
}
@@ -614,7 +614,7 @@ check_instruction_reads(struct vc4_validated_shader_info *validated_shader,
validated_shader->uniforms_size += 4;
if (validation_state->needs_uniform_address_update) {
- DRM_ERROR("Uniform read with undefined uniform "
+ DRM_DEBUG("Uniform read with undefined uniform "
"address\n");
return false;
}
@@ -660,19 +660,19 @@ vc4_validate_branches(struct vc4_shader_validation_state *validation_state)
continue;
if (ip - last_branch < 4) {
- DRM_ERROR("Branch at %d during delay slots\n", ip);
+ DRM_DEBUG("Branch at %d during delay slots\n", ip);
return false;
}
last_branch = ip;
if (inst & QPU_BRANCH_REG) {
- DRM_ERROR("branching from register relative "
+ DRM_DEBUG("branching from register relative "
"not supported\n");
return false;
}
if (!(inst & QPU_BRANCH_REL)) {
- DRM_ERROR("relative branching required\n");
+ DRM_DEBUG("relative branching required\n");
return false;
}
@@ -682,13 +682,13 @@ vc4_validate_branches(struct vc4_shader_validation_state *validation_state)
* end of the shader object.
*/
if (branch_imm % sizeof(inst) != 0) {
- DRM_ERROR("branch target not aligned\n");
+ DRM_DEBUG("branch target not aligned\n");
return false;
}
branch_target_ip = after_delay_ip + (branch_imm >> 3);
if (branch_target_ip >= validation_state->max_ip) {
- DRM_ERROR("Branch at %d outside of shader (ip %d/%d)\n",
+ DRM_DEBUG("Branch at %d outside of shader (ip %d/%d)\n",
ip, branch_target_ip,
validation_state->max_ip);
return false;
@@ -699,7 +699,7 @@ vc4_validate_branches(struct vc4_shader_validation_state *validation_state)
* the shader.
*/
if (after_delay_ip >= validation_state->max_ip) {
- DRM_ERROR("Branch at %d continues past shader end "
+ DRM_DEBUG("Branch at %d continues past shader end "
"(%d/%d)\n",
ip, after_delay_ip, validation_state->max_ip);
return false;
@@ -709,7 +709,7 @@ vc4_validate_branches(struct vc4_shader_validation_state *validation_state)
}
if (max_branch_target > validation_state->max_ip - 3) {
- DRM_ERROR("Branch landed after QPU_SIG_PROG_END");
+ DRM_DEBUG("Branch landed after QPU_SIG_PROG_END");
return false;
}
@@ -750,7 +750,7 @@ vc4_handle_branch_target(struct vc4_shader_validation_state *validation_state)
return true;
if (texturing_in_progress(validation_state)) {
- DRM_ERROR("Branch target landed during TMU setup\n");
+ DRM_DEBUG("Branch target landed during TMU setup\n");
return false;
}
@@ -837,7 +837,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
case QPU_SIG_LAST_THREAD_SWITCH:
if (!check_instruction_writes(validated_shader,
&validation_state)) {
- DRM_ERROR("Bad write at ip %d\n", ip);
+ DRM_DEBUG("Bad write at ip %d\n", ip);
goto fail;
}
@@ -855,7 +855,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
validated_shader->is_threaded = true;
if (ip < last_thread_switch_ip + 3) {
- DRM_ERROR("Thread switch too soon after "
+ DRM_DEBUG("Thread switch too soon after "
"last switch at ip %d\n", ip);
goto fail;
}
@@ -867,7 +867,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
case QPU_SIG_LOAD_IMM:
if (!check_instruction_writes(validated_shader,
&validation_state)) {
- DRM_ERROR("Bad LOAD_IMM write at ip %d\n", ip);
+ DRM_DEBUG("Bad LOAD_IMM write at ip %d\n", ip);
goto fail;
}
break;
@@ -878,14 +878,14 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
goto fail;
if (ip < last_thread_switch_ip + 3) {
- DRM_ERROR("Branch in thread switch at ip %d",
+ DRM_DEBUG("Branch in thread switch at ip %d",
ip);
goto fail;
}
break;
default:
- DRM_ERROR("Unsupported QPU signal %d at "
+ DRM_DEBUG("Unsupported QPU signal %d at "
"instruction %d\n", sig, ip);
goto fail;
}
@@ -898,7 +898,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
}
if (ip == validation_state.max_ip) {
- DRM_ERROR("shader failed to terminate before "
+ DRM_DEBUG("shader failed to terminate before "
"shader BO end at %zd\n",
shader_obj->base.size);
goto fail;
@@ -907,7 +907,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
/* Might corrupt other thread */
if (validated_shader->is_threaded &&
validation_state.all_registers_used) {
- DRM_ERROR("Shader uses threading, but uses the upper "
+ DRM_DEBUG("Shader uses threading, but uses the upper "
"half of the registers, too\n");
goto fail;
}
diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
index 09c1e05..3a9a302 100644
--- a/drivers/gpu/drm/vc4/vc4_vec.c
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
@@ -366,10 +366,8 @@ static int vc4_vec_connector_get_modes(struct drm_connector *connector)
}
static const struct drm_connector_funcs vc4_vec_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = vc4_vec_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
- .set_property = drm_atomic_helper_connector_set_property,
.destroy = vc4_vec_connector_destroy,
.reset = drm_atomic_helper_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c
index 18f401b..2524ff1 100644
--- a/drivers/gpu/drm/vgem/vgem_drv.c
+++ b/drivers/gpu/drm/vgem/vgem_drv.c
@@ -52,6 +52,7 @@ static void vgem_gem_free_object(struct drm_gem_object *obj)
struct drm_vgem_gem_object *vgem_obj = to_vgem_bo(obj);
kvfree(vgem_obj->pages);
+ mutex_destroy(&vgem_obj->pages_lock);
if (obj->import_attach)
drm_prime_gem_destroy(obj, vgem_obj->table);
@@ -76,11 +77,15 @@ static int vgem_gem_fault(struct vm_fault *vmf)
if (page_offset > num_pages)
return VM_FAULT_SIGBUS;
+ ret = -ENOENT;
+ mutex_lock(&obj->pages_lock);
if (obj->pages) {
get_page(obj->pages[page_offset]);
vmf->page = obj->pages[page_offset];
ret = 0;
- } else {
+ }
+ mutex_unlock(&obj->pages_lock);
+ if (ret) {
struct page *page;
page = shmem_read_mapping_page(
@@ -161,6 +166,8 @@ static struct drm_vgem_gem_object *__vgem_gem_create(struct drm_device *dev,
return ERR_PTR(ret);
}
+ mutex_init(&obj->pages_lock);
+
return obj;
}
@@ -183,7 +190,7 @@ static struct drm_gem_object *vgem_gem_create(struct drm_device *dev,
return ERR_CAST(obj);
ret = drm_gem_handle_create(file, &obj->base, handle);
- drm_gem_object_unreference_unlocked(&obj->base);
+ drm_gem_object_put_unlocked(&obj->base);
if (ret)
goto err;
@@ -238,7 +245,7 @@ static int vgem_gem_dumb_map(struct drm_file *file, struct drm_device *dev,
*offset = drm_vma_node_offset_addr(&obj->vma_node);
unref:
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -271,40 +278,70 @@ static const struct file_operations vgem_driver_fops = {
.poll = drm_poll,
.read = drm_read,
.unlocked_ioctl = drm_ioctl,
+ .compat_ioctl = drm_compat_ioctl,
.release = drm_release,
};
+static struct page **vgem_pin_pages(struct drm_vgem_gem_object *bo)
+{
+ mutex_lock(&bo->pages_lock);
+ if (bo->pages_pin_count++ == 0) {
+ struct page **pages;
+
+ pages = drm_gem_get_pages(&bo->base);
+ if (IS_ERR(pages)) {
+ bo->pages_pin_count--;
+ mutex_unlock(&bo->pages_lock);
+ return pages;
+ }
+
+ bo->pages = pages;
+ }
+ mutex_unlock(&bo->pages_lock);
+
+ return bo->pages;
+}
+
+static void vgem_unpin_pages(struct drm_vgem_gem_object *bo)
+{
+ mutex_lock(&bo->pages_lock);
+ if (--bo->pages_pin_count == 0) {
+ drm_gem_put_pages(&bo->base, bo->pages, true, true);
+ bo->pages = NULL;
+ }
+ mutex_unlock(&bo->pages_lock);
+}
+
static int vgem_prime_pin(struct drm_gem_object *obj)
{
+ struct drm_vgem_gem_object *bo = to_vgem_bo(obj);
long n_pages = obj->size >> PAGE_SHIFT;
struct page **pages;
- /* Flush the object from the CPU cache so that importers can rely
- * on coherent indirect access via the exported dma-address.
- */
- pages = drm_gem_get_pages(obj);
+ pages = vgem_pin_pages(bo);
if (IS_ERR(pages))
return PTR_ERR(pages);
+ /* Flush the object from the CPU cache so that importers can rely
+ * on coherent indirect access via the exported dma-address.
+ */
drm_clflush_pages(pages, n_pages);
- drm_gem_put_pages(obj, pages, true, false);
return 0;
}
-static struct sg_table *vgem_prime_get_sg_table(struct drm_gem_object *obj)
+static void vgem_prime_unpin(struct drm_gem_object *obj)
{
- struct sg_table *st;
- struct page **pages;
+ struct drm_vgem_gem_object *bo = to_vgem_bo(obj);
- pages = drm_gem_get_pages(obj);
- if (IS_ERR(pages))
- return ERR_CAST(pages);
+ vgem_unpin_pages(bo);
+}
- st = drm_prime_pages_to_sg(pages, obj->size >> PAGE_SHIFT);
- drm_gem_put_pages(obj, pages, false, false);
+static struct sg_table *vgem_prime_get_sg_table(struct drm_gem_object *obj)
+{
+ struct drm_vgem_gem_object *bo = to_vgem_bo(obj);
- return st;
+ return drm_prime_pages_to_sg(bo->pages, bo->base.size >> PAGE_SHIFT);
}
static struct drm_gem_object* vgem_prime_import(struct drm_device *dev,
@@ -333,6 +370,8 @@ static struct drm_gem_object *vgem_prime_import_sg_table(struct drm_device *dev,
__vgem_gem_destroy(obj);
return ERR_PTR(-ENOMEM);
}
+
+ obj->pages_pin_count++; /* perma-pinned */
drm_prime_sg_to_page_addr_arrays(obj->table, obj->pages, NULL,
npages);
return &obj->base;
@@ -340,23 +379,23 @@ static struct drm_gem_object *vgem_prime_import_sg_table(struct drm_device *dev,
static void *vgem_prime_vmap(struct drm_gem_object *obj)
{
+ struct drm_vgem_gem_object *bo = to_vgem_bo(obj);
long n_pages = obj->size >> PAGE_SHIFT;
struct page **pages;
- void *addr;
- pages = drm_gem_get_pages(obj);
+ pages = vgem_pin_pages(bo);
if (IS_ERR(pages))
return NULL;
- addr = vmap(pages, n_pages, 0, pgprot_writecombine(PAGE_KERNEL));
- drm_gem_put_pages(obj, pages, false, false);
-
- return addr;
+ return vmap(pages, n_pages, 0, pgprot_writecombine(PAGE_KERNEL));
}
static void vgem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
{
+ struct drm_vgem_gem_object *bo = to_vgem_bo(obj);
+
vunmap(vaddr);
+ vgem_unpin_pages(bo);
}
static int vgem_prime_mmap(struct drm_gem_object *obj,
@@ -409,6 +448,7 @@ static struct drm_driver vgem_driver = {
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_pin = vgem_prime_pin,
+ .gem_prime_unpin = vgem_prime_unpin,
.gem_prime_import = vgem_prime_import,
.gem_prime_export = drm_gem_prime_export,
.gem_prime_import_sg_table = vgem_prime_import_sg_table,
diff --git a/drivers/gpu/drm/vgem/vgem_drv.h b/drivers/gpu/drm/vgem/vgem_drv.h
index 1aae014..5c8f6d6 100644
--- a/drivers/gpu/drm/vgem/vgem_drv.h
+++ b/drivers/gpu/drm/vgem/vgem_drv.h
@@ -43,7 +43,11 @@ struct vgem_file {
#define to_vgem_bo(x) container_of(x, struct drm_vgem_gem_object, base)
struct drm_vgem_gem_object {
struct drm_gem_object base;
+
struct page **pages;
+ unsigned int pages_pin_count;
+ struct mutex pages_lock;
+
struct sg_table *table;
};
diff --git a/drivers/gpu/drm/vgem/vgem_fence.c b/drivers/gpu/drm/vgem/vgem_fence.c
index 3109c83..8fd52f2 100644
--- a/drivers/gpu/drm/vgem/vgem_fence.c
+++ b/drivers/gpu/drm/vgem/vgem_fence.c
@@ -213,7 +213,7 @@ err_fence:
dma_fence_put(fence);
}
err:
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c
index 9e0e539..aaf766f 100644
--- a/drivers/gpu/drm/via/via_drv.c
+++ b/drivers/gpu/drm/via/via_drv.c
@@ -77,7 +77,6 @@ static struct drm_driver driver = {
.open = via_driver_open,
.preclose = via_reclaim_buffers_locked,
.postclose = via_driver_postclose,
- .set_busid = drm_pci_set_busid,
.context_dtor = via_final_context,
.get_vblank_counter = via_get_vblank_counter,
.enable_vblank = via_enable_vblank,
@@ -107,12 +106,12 @@ static int __init via_init(void)
{
driver.num_ioctls = via_max_ioctl;
via_init_command_verifier();
- return drm_pci_init(&driver, &via_pci_driver);
+ return drm_legacy_pci_init(&driver, &via_pci_driver);
}
static void __exit via_exit(void)
{
- drm_pci_exit(&driver, &via_pci_driver);
+ drm_legacy_pci_exit(&driver, &via_pci_driver);
}
module_init(via_init);
diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c
index d51bd45..b6d5205 100644
--- a/drivers/gpu/drm/virtio/virtgpu_display.c
+++ b/drivers/gpu/drm/virtio/virtgpu_display.c
@@ -113,11 +113,13 @@ static void virtio_gpu_crtc_mode_set_nofb(struct drm_crtc *crtc)
crtc->mode.vdisplay, 0, 0);
}
-static void virtio_gpu_crtc_enable(struct drm_crtc *crtc)
+static void virtio_gpu_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
}
-static void virtio_gpu_crtc_disable(struct drm_crtc *crtc)
+static void virtio_gpu_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct drm_device *dev = crtc->dev;
struct virtio_gpu_device *vgdev = dev->dev_private;
@@ -145,11 +147,11 @@ static void virtio_gpu_crtc_atomic_flush(struct drm_crtc *crtc,
}
static const struct drm_crtc_helper_funcs virtio_gpu_crtc_helper_funcs = {
- .enable = virtio_gpu_crtc_enable,
- .disable = virtio_gpu_crtc_disable,
.mode_set_nofb = virtio_gpu_crtc_mode_set_nofb,
.atomic_check = virtio_gpu_crtc_atomic_check,
.atomic_flush = virtio_gpu_crtc_atomic_flush,
+ .atomic_enable = virtio_gpu_crtc_atomic_enable,
+ .atomic_disable = virtio_gpu_crtc_atomic_disable,
};
static void virtio_gpu_enc_mode_set(struct drm_encoder *encoder,
@@ -250,7 +252,6 @@ static void virtio_gpu_conn_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs virtio_gpu_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = virtio_gpu_conn_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = virtio_gpu_conn_destroy,
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c
index 63d35c7..49a3d8d 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.c
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
@@ -122,7 +122,6 @@ static struct drm_driver driver = {
.dumb_create = virtio_gpu_mode_dumb_create,
.dumb_map_offset = virtio_gpu_mode_dumb_mmap,
- .dumb_destroy = virtio_gpu_mode_dumb_destroy,
#if defined(CONFIG_DEBUG_FS)
.debugfs_init = virtio_gpu_debugfs_init,
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 3a66abb..da2fb58 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -236,9 +236,6 @@ struct virtio_gpu_object *virtio_gpu_alloc_object(struct drm_device *dev,
int virtio_gpu_mode_dumb_create(struct drm_file *file_priv,
struct drm_device *dev,
struct drm_mode_create_dumb *args);
-int virtio_gpu_mode_dumb_destroy(struct drm_file *file_priv,
- struct drm_device *dev,
- uint32_t handle);
int virtio_gpu_mode_dumb_mmap(struct drm_file *file_priv,
struct drm_device *dev,
uint32_t handle, uint64_t *offset_p);
diff --git a/drivers/gpu/drm/virtio/virtgpu_fb.c b/drivers/gpu/drm/virtio/virtgpu_fb.c
index 33df067..15d18fd 100644
--- a/drivers/gpu/drm/virtio/virtgpu_fb.c
+++ b/drivers/gpu/drm/virtio/virtgpu_fb.c
@@ -273,7 +273,6 @@ static int virtio_gpufb_create(struct drm_fb_helper *helper,
vfbdev->helper.fb = fb;
strcpy(info->fix.id, "virtiodrmfb");
- info->flags = FBINFO_DEFAULT;
info->fbops = &virtio_gpufb_ops;
info->pixmap.flags = FB_PIXMAP_SYSTEM;
@@ -309,7 +308,7 @@ static int virtio_gpu_fbdev_destroy(struct drm_device *dev,
return 0;
}
-static struct drm_fb_helper_funcs virtio_gpu_fb_helper_funcs = {
+static const struct drm_fb_helper_funcs virtio_gpu_fb_helper_funcs = {
.fb_probe = virtio_gpufb_create,
};
diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c
index cc025d8..72ad7b1 100644
--- a/drivers/gpu/drm/virtio/virtgpu_gem.c
+++ b/drivers/gpu/drm/virtio/virtgpu_gem.c
@@ -118,13 +118,6 @@ fail:
return ret;
}
-int virtio_gpu_mode_dumb_destroy(struct drm_file *file_priv,
- struct drm_device *dev,
- uint32_t handle)
-{
- return drm_gem_handle_delete(file_priv, handle);
-}
-
int virtio_gpu_mode_dumb_mmap(struct drm_file *file_priv,
struct drm_device *dev,
uint32_t handle, uint64_t *offset_p)
diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c
index adcdbd0..71ba455 100644
--- a/drivers/gpu/drm/virtio/virtgpu_plane.c
+++ b/drivers/gpu/drm/virtio/virtgpu_plane.c
@@ -298,7 +298,7 @@ struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev,
ret = drm_universal_plane_init(dev, plane, 1 << index,
&virtio_gpu_plane_funcs,
formats, nformats,
- type, NULL);
+ NULL, type, NULL);
if (ret)
goto err_plane_init;
diff --git a/drivers/gpu/drm/virtio/virtgpu_ttm.c b/drivers/gpu/drm/virtio/virtgpu_ttm.c
index c1f2af4..cd389c5 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ttm.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ttm.c
@@ -192,7 +192,7 @@ static int ttm_bo_man_takedown(struct ttm_mem_type_manager *man)
}
static void ttm_bo_man_debug(struct ttm_mem_type_manager *man,
- const char *prefix)
+ struct drm_printer *printer)
{
}
@@ -234,7 +234,7 @@ static int virtio_gpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
static void virtio_gpu_evict_flags(struct ttm_buffer_object *bo,
struct ttm_placement *placement)
{
- static struct ttm_place placements = {
+ static const struct ttm_place placements = {
.fpfn = 0,
.lpfn = 0,
.flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
index 8617879..c706ad3 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
@@ -51,6 +51,7 @@ struct vmw_cmdbuf_context {
struct list_head hw_submitted;
struct list_head preempted;
unsigned num_hw_submitted;
+ bool block_submission;
};
/**
@@ -60,6 +61,9 @@ struct vmw_cmdbuf_context {
* kernel command submissions, @cur.
* @space_mutex: Mutex to protect against starvation when we allocate
* main pool buffer space.
+ * @error_mutex: Mutex to serialize the work queue error handling.
+ * Note this is not needed if the same workqueue handler
+ * can't race with itself...
* @work: A struct work_struct implementeing command buffer error handling.
* Immutable.
* @dev_priv: Pointer to the device private struct. Immutable.
@@ -85,7 +89,6 @@ struct vmw_cmdbuf_context {
* Internal protection.
* @dheaders: Pool of DMA memory for device command buffer headers with trailing
* space for inline data. Internal protection.
- * @tasklet: Tasklet struct for irq processing. Immutable.
* @alloc_queue: Wait queue for processes waiting to allocate command buffer
* space.
* @idle_queue: Wait queue for processes waiting for command buffer idle.
@@ -102,6 +105,7 @@ struct vmw_cmdbuf_context {
struct vmw_cmdbuf_man {
struct mutex cur_mutex;
struct mutex space_mutex;
+ struct mutex error_mutex;
struct work_struct work;
struct vmw_private *dev_priv;
struct vmw_cmdbuf_context ctx[SVGA_CB_CONTEXT_MAX];
@@ -117,7 +121,6 @@ struct vmw_cmdbuf_man {
spinlock_t lock;
struct dma_pool *headers;
struct dma_pool *dheaders;
- struct tasklet_struct tasklet;
wait_queue_head_t alloc_queue;
wait_queue_head_t idle_queue;
bool irq_on;
@@ -181,12 +184,13 @@ struct vmw_cmdbuf_alloc_info {
};
/* Loop over each context in the command buffer manager. */
-#define for_each_cmdbuf_ctx(_man, _i, _ctx) \
+#define for_each_cmdbuf_ctx(_man, _i, _ctx) \
for (_i = 0, _ctx = &(_man)->ctx[0]; (_i) < SVGA_CB_CONTEXT_MAX; \
++(_i), ++(_ctx))
-static int vmw_cmdbuf_startstop(struct vmw_cmdbuf_man *man, bool enable);
-
+static int vmw_cmdbuf_startstop(struct vmw_cmdbuf_man *man, u32 context,
+ bool enable);
+static int vmw_cmdbuf_preempt(struct vmw_cmdbuf_man *man, u32 context);
/**
* vmw_cmdbuf_cur_lock - Helper to lock the cur_mutex.
@@ -278,9 +282,9 @@ void vmw_cmdbuf_header_free(struct vmw_cmdbuf_header *header)
vmw_cmdbuf_header_inline_free(header);
return;
}
- spin_lock_bh(&man->lock);
+ spin_lock(&man->lock);
__vmw_cmdbuf_header_free(header);
- spin_unlock_bh(&man->lock);
+ spin_unlock(&man->lock);
}
@@ -331,7 +335,8 @@ static void vmw_cmdbuf_ctx_submit(struct vmw_cmdbuf_man *man,
struct vmw_cmdbuf_context *ctx)
{
while (ctx->num_hw_submitted < man->max_hw_submitted &&
- !list_empty(&ctx->submitted)) {
+ !list_empty(&ctx->submitted) &&
+ !ctx->block_submission) {
struct vmw_cmdbuf_header *entry;
SVGACBStatus status;
@@ -386,12 +391,17 @@ static void vmw_cmdbuf_ctx_process(struct vmw_cmdbuf_man *man,
__vmw_cmdbuf_header_free(entry);
break;
case SVGA_CB_STATUS_COMMAND_ERROR:
- case SVGA_CB_STATUS_CB_HEADER_ERROR:
+ entry->cb_header->status = SVGA_CB_STATUS_NONE;
list_add_tail(&entry->list, &man->error);
schedule_work(&man->work);
break;
case SVGA_CB_STATUS_PREEMPTED:
- list_add(&entry->list, &ctx->preempted);
+ entry->cb_header->status = SVGA_CB_STATUS_NONE;
+ list_add_tail(&entry->list, &ctx->preempted);
+ break;
+ case SVGA_CB_STATUS_CB_HEADER_ERROR:
+ WARN_ONCE(true, "Command buffer header error.\n");
+ __vmw_cmdbuf_header_free(entry);
break;
default:
WARN_ONCE(true, "Undefined command buffer status.\n");
@@ -468,20 +478,17 @@ static void vmw_cmdbuf_ctx_add(struct vmw_cmdbuf_man *man,
}
/**
- * vmw_cmdbuf_man_tasklet - The main part of the command buffer interrupt
- * handler implemented as a tasklet.
+ * vmw_cmdbuf_irqthread - The main part of the command buffer interrupt
+ * handler implemented as a threaded irq task.
*
- * @data: Tasklet closure. A pointer to the command buffer manager cast to
- * an unsigned long.
+ * @man: Pointer to the command buffer manager.
*
- * The bottom half (tasklet) of the interrupt handler simply calls into the
+ * The bottom half of the interrupt handler simply calls into the
* command buffer processor to free finished buffers and submit any
* queued buffers to hardware.
*/
-static void vmw_cmdbuf_man_tasklet(unsigned long data)
+void vmw_cmdbuf_irqthread(struct vmw_cmdbuf_man *man)
{
- struct vmw_cmdbuf_man *man = (struct vmw_cmdbuf_man *) data;
-
spin_lock(&man->lock);
vmw_cmdbuf_man_process(man);
spin_unlock(&man->lock);
@@ -502,24 +509,112 @@ static void vmw_cmdbuf_work_func(struct work_struct *work)
container_of(work, struct vmw_cmdbuf_man, work);
struct vmw_cmdbuf_header *entry, *next;
uint32_t dummy;
- bool restart = false;
+ bool restart[SVGA_CB_CONTEXT_MAX];
+ bool send_fence = false;
+ struct list_head restart_head[SVGA_CB_CONTEXT_MAX];
+ int i;
+ struct vmw_cmdbuf_context *ctx;
- spin_lock_bh(&man->lock);
+ for_each_cmdbuf_ctx(man, i, ctx) {
+ INIT_LIST_HEAD(&restart_head[i]);
+ restart[i] = false;
+ }
+
+ mutex_lock(&man->error_mutex);
+ spin_lock(&man->lock);
list_for_each_entry_safe(entry, next, &man->error, list) {
- restart = true;
- DRM_ERROR("Command buffer error.\n");
+ SVGACBHeader *cb_hdr = entry->cb_header;
+ SVGA3dCmdHeader *header = (SVGA3dCmdHeader *)
+ (entry->cmd + cb_hdr->errorOffset);
+ u32 error_cmd_size, new_start_offset;
+ const char *cmd_name;
+
+ list_del_init(&entry->list);
+ restart[entry->cb_context] = true;
+
+ if (!vmw_cmd_describe(header, &error_cmd_size, &cmd_name)) {
+ DRM_ERROR("Unknown command causing device error.\n");
+ DRM_ERROR("Command buffer offset is %lu\n",
+ (unsigned long) cb_hdr->errorOffset);
+ __vmw_cmdbuf_header_free(entry);
+ send_fence = true;
+ continue;
+ }
- list_del(&entry->list);
- __vmw_cmdbuf_header_free(entry);
- wake_up_all(&man->idle_queue);
+ DRM_ERROR("Command \"%s\" causing device error.\n", cmd_name);
+ DRM_ERROR("Command buffer offset is %lu\n",
+ (unsigned long) cb_hdr->errorOffset);
+ DRM_ERROR("Command size is %lu\n",
+ (unsigned long) error_cmd_size);
+
+ new_start_offset = cb_hdr->errorOffset + error_cmd_size;
+
+ if (new_start_offset >= cb_hdr->length) {
+ __vmw_cmdbuf_header_free(entry);
+ send_fence = true;
+ continue;
+ }
+
+ if (man->using_mob)
+ cb_hdr->ptr.mob.mobOffset += new_start_offset;
+ else
+ cb_hdr->ptr.pa += (u64) new_start_offset;
+
+ entry->cmd += new_start_offset;
+ cb_hdr->length -= new_start_offset;
+ cb_hdr->errorOffset = 0;
+ cb_hdr->offset = 0;
+ list_add_tail(&entry->list, &restart_head[entry->cb_context]);
+ man->ctx[entry->cb_context].block_submission = true;
+ }
+ spin_unlock(&man->lock);
+
+ /* Preempt all contexts with errors */
+ for_each_cmdbuf_ctx(man, i, ctx) {
+ if (ctx->block_submission && vmw_cmdbuf_preempt(man, i))
+ DRM_ERROR("Failed preempting command buffer "
+ "context %u.\n", i);
+ }
+
+ spin_lock(&man->lock);
+ for_each_cmdbuf_ctx(man, i, ctx) {
+ if (!ctx->block_submission)
+ continue;
+
+ /* Move preempted command buffers to the preempted queue. */
+ vmw_cmdbuf_ctx_process(man, ctx, &dummy);
+
+ /*
+ * Add the preempted queue after the command buffer
+ * that caused an error.
+ */
+ list_splice_init(&ctx->preempted, restart_head[i].prev);
+
+ /*
+ * Finally add all command buffers first in the submitted
+ * queue, to rerun them.
+ */
+ list_splice_init(&restart_head[i], &ctx->submitted);
+
+ ctx->block_submission = false;
}
- spin_unlock_bh(&man->lock);
- if (restart && vmw_cmdbuf_startstop(man, true))
- DRM_ERROR("Failed restarting command buffer context 0.\n");
+ vmw_cmdbuf_man_process(man);
+ spin_unlock(&man->lock);
+
+ for_each_cmdbuf_ctx(man, i, ctx) {
+ if (restart[i] && vmw_cmdbuf_startstop(man, i, true))
+ DRM_ERROR("Failed restarting command buffer "
+ "context %u.\n", i);
+ }
/* Send a new fence in case one was removed */
- vmw_fifo_send_fence(man->dev_priv, &dummy);
+ if (send_fence) {
+ vmw_fifo_send_fence(man->dev_priv, &dummy);
+ wake_up_all(&man->idle_queue);
+ }
+
+ mutex_unlock(&man->error_mutex);
}
/**
@@ -536,7 +631,7 @@ static bool vmw_cmdbuf_man_idle(struct vmw_cmdbuf_man *man,
bool idle = false;
int i;
- spin_lock_bh(&man->lock);
+ spin_lock(&man->lock);
vmw_cmdbuf_man_process(man);
for_each_cmdbuf_ctx(man, i, ctx) {
if (!list_empty(&ctx->submitted) ||
@@ -548,7 +643,7 @@ static bool vmw_cmdbuf_man_idle(struct vmw_cmdbuf_man *man,
idle = list_empty(&man->error);
out_unlock:
- spin_unlock_bh(&man->lock);
+ spin_unlock(&man->lock);
return idle;
}
@@ -571,7 +666,7 @@ static void __vmw_cmdbuf_cur_flush(struct vmw_cmdbuf_man *man)
if (!cur)
return;
- spin_lock_bh(&man->lock);
+ spin_lock(&man->lock);
if (man->cur_pos == 0) {
__vmw_cmdbuf_header_free(cur);
goto out_unlock;
@@ -580,7 +675,7 @@ static void __vmw_cmdbuf_cur_flush(struct vmw_cmdbuf_man *man)
man->cur->cb_header->length = man->cur_pos;
vmw_cmdbuf_ctx_add(man, man->cur, SVGA_CB_CONTEXT_0);
out_unlock:
- spin_unlock_bh(&man->lock);
+ spin_unlock(&man->lock);
man->cur = NULL;
man->cur_pos = 0;
}
@@ -673,14 +768,14 @@ static bool vmw_cmdbuf_try_alloc(struct vmw_cmdbuf_man *man,
return true;
memset(info->node, 0, sizeof(*info->node));
- spin_lock_bh(&man->lock);
+ spin_lock(&man->lock);
ret = drm_mm_insert_node(&man->mm, info->node, info->page_size);
if (ret) {
vmw_cmdbuf_man_process(man);
ret = drm_mm_insert_node(&man->mm, info->node, info->page_size);
}
- spin_unlock_bh(&man->lock);
+ spin_unlock(&man->lock);
info->done = !ret;
return info->done;
@@ -801,9 +896,9 @@ static int vmw_cmdbuf_space_pool(struct vmw_cmdbuf_man *man,
return 0;
out_no_cb_header:
- spin_lock_bh(&man->lock);
+ spin_lock(&man->lock);
drm_mm_remove_node(&header->node);
- spin_unlock_bh(&man->lock);
+ spin_unlock(&man->lock);
return ret;
}
@@ -1023,18 +1118,6 @@ void vmw_cmdbuf_commit(struct vmw_cmdbuf_man *man, size_t size,
vmw_cmdbuf_cur_unlock(man);
}
-/**
- * vmw_cmdbuf_tasklet_schedule - Schedule the interrupt handler bottom half.
- *
- * @man: The command buffer manager.
- */
-void vmw_cmdbuf_tasklet_schedule(struct vmw_cmdbuf_man *man)
-{
- if (!man)
- return;
-
- tasklet_schedule(&man->tasklet);
-}
/**
* vmw_cmdbuf_send_device_command - Send a command through the device context.
@@ -1059,9 +1142,9 @@ static int vmw_cmdbuf_send_device_command(struct vmw_cmdbuf_man *man,
memcpy(cmd, command, size);
header->cb_header->length = size;
header->cb_context = SVGA_CB_CONTEXT_DEVICE;
- spin_lock_bh(&man->lock);
+ spin_lock(&man->lock);
status = vmw_cmdbuf_header_submit(header);
- spin_unlock_bh(&man->lock);
+ spin_unlock(&man->lock);
vmw_cmdbuf_header_free(header);
if (status != SVGA_CB_STATUS_COMPLETED) {
@@ -1074,6 +1157,29 @@ static int vmw_cmdbuf_send_device_command(struct vmw_cmdbuf_man *man,
}
/**
+ * vmw_cmdbuf_preempt - Send a preempt command through the device
+ * context.
+ *
+ * @man: The command buffer manager.
+ *
+ * Synchronously sends a preempt command.
+ */
+static int vmw_cmdbuf_preempt(struct vmw_cmdbuf_man *man, u32 context)
+{
+ struct {
+ uint32 id;
+ SVGADCCmdPreempt body;
+ } __packed cmd;
+
+ cmd.id = SVGA_DC_CMD_PREEMPT;
+ cmd.body.context = SVGA_CB_CONTEXT_0 + context;
+ cmd.body.ignoreIDZero = 0;
+
+ return vmw_cmdbuf_send_device_command(man, &cmd, sizeof(cmd));
+}
+
+
+/**
* vmw_cmdbuf_startstop - Send a start / stop command through the device
* context.
*
@@ -1082,7 +1188,7 @@ static int vmw_cmdbuf_send_device_command(struct vmw_cmdbuf_man *man,
*
* Synchronously sends a device start / stop context command.
*/
-static int vmw_cmdbuf_startstop(struct vmw_cmdbuf_man *man,
+static int vmw_cmdbuf_startstop(struct vmw_cmdbuf_man *man, u32 context,
bool enable)
{
struct {
@@ -1092,7 +1198,7 @@ static int vmw_cmdbuf_startstop(struct vmw_cmdbuf_man *man,
cmd.id = SVGA_DC_CMD_START_STOP_CONTEXT;
cmd.body.enable = (enable) ? 1 : 0;
- cmd.body.context = SVGA_CB_CONTEXT_0;
+ cmd.body.context = SVGA_CB_CONTEXT_0 + context;
return vmw_cmdbuf_send_device_command(man, &cmd, sizeof(cmd));
}
@@ -1191,7 +1297,7 @@ struct vmw_cmdbuf_man *vmw_cmdbuf_man_create(struct vmw_private *dev_priv)
{
struct vmw_cmdbuf_man *man;
struct vmw_cmdbuf_context *ctx;
- int i;
+ unsigned int i;
int ret;
if (!(dev_priv->capabilities & SVGA_CAP_COMMAND_BUFFERS))
@@ -1226,8 +1332,7 @@ struct vmw_cmdbuf_man *vmw_cmdbuf_man_create(struct vmw_private *dev_priv)
spin_lock_init(&man->lock);
mutex_init(&man->cur_mutex);
mutex_init(&man->space_mutex);
- tasklet_init(&man->tasklet, vmw_cmdbuf_man_tasklet,
- (unsigned long) man);
+ mutex_init(&man->error_mutex);
man->default_size = VMW_CMDBUF_INLINE_SIZE;
init_waitqueue_head(&man->alloc_queue);
init_waitqueue_head(&man->idle_queue);
@@ -1236,11 +1341,14 @@ struct vmw_cmdbuf_man *vmw_cmdbuf_man_create(struct vmw_private *dev_priv)
INIT_WORK(&man->work, &vmw_cmdbuf_work_func);
vmw_generic_waiter_add(dev_priv, SVGA_IRQFLAG_ERROR,
&dev_priv->error_waiters);
- ret = vmw_cmdbuf_startstop(man, true);
- if (ret) {
- DRM_ERROR("Failed starting command buffer context 0.\n");
- vmw_cmdbuf_man_destroy(man);
- return ERR_PTR(ret);
+ for_each_cmdbuf_ctx(man, i, ctx) {
+ ret = vmw_cmdbuf_startstop(man, i, true);
+ if (ret) {
+ DRM_ERROR("Failed starting command buffer "
+ "context %u.\n", i);
+ vmw_cmdbuf_man_destroy(man);
+ return ERR_PTR(ret);
+ }
}
return man;
@@ -1290,18 +1398,24 @@ void vmw_cmdbuf_remove_pool(struct vmw_cmdbuf_man *man)
*/
void vmw_cmdbuf_man_destroy(struct vmw_cmdbuf_man *man)
{
+ struct vmw_cmdbuf_context *ctx;
+ unsigned int i;
+
WARN_ON_ONCE(man->has_pool);
(void) vmw_cmdbuf_idle(man, false, 10*HZ);
- if (vmw_cmdbuf_startstop(man, false))
- DRM_ERROR("Failed stopping command buffer context 0.\n");
+
+ for_each_cmdbuf_ctx(man, i, ctx)
+ if (vmw_cmdbuf_startstop(man, i, false))
+ DRM_ERROR("Failed stopping command buffer "
+ "context %u.\n", i);
vmw_generic_waiter_remove(man->dev_priv, SVGA_IRQFLAG_ERROR,
&man->dev_priv->error_waiters);
- tasklet_kill(&man->tasklet);
(void) cancel_work_sync(&man->work);
dma_pool_destroy(man->dheaders);
dma_pool_destroy(man->headers);
mutex_destroy(&man->cur_mutex);
mutex_destroy(&man->space_mutex);
+ mutex_destroy(&man->error_mutex);
kfree(man);
}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 4436d53..e84fee3 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -36,7 +36,6 @@
#include <drm/ttm/ttm_module.h>
#include <linux/dma_remapping.h>
-#define VMWGFX_DRIVER_NAME "vmwgfx"
#define VMWGFX_DRIVER_DESC "Linux drm driver for VMware graphics devices"
#define VMWGFX_CHIP_SVGAII 0
#define VMW_FB_RESERVATION 0
@@ -825,7 +824,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
}
if (dev_priv->capabilities & SVGA_CAP_IRQMASK) {
- ret = drm_irq_install(dev, dev->pdev->irq);
+ ret = vmw_irq_install(dev, dev->pdev->irq);
if (ret != 0) {
DRM_ERROR("Failed installing irq: %d\n", ret);
goto out_no_irq;
@@ -937,7 +936,7 @@ out_no_bdev:
vmw_fence_manager_takedown(dev_priv->fman);
out_no_fman:
if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
- drm_irq_uninstall(dev_priv->dev);
+ vmw_irq_uninstall(dev_priv->dev);
out_no_irq:
if (dev_priv->stealth)
pci_release_region(dev->pdev, 2);
@@ -990,7 +989,7 @@ static void vmw_driver_unload(struct drm_device *dev)
vmw_release_device_late(dev_priv);
vmw_fence_manager_takedown(dev_priv->fman);
if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
- drm_irq_uninstall(dev_priv->dev);
+ vmw_irq_uninstall(dev_priv->dev);
if (dev_priv->stealth)
pci_release_region(dev->pdev, 2);
else
@@ -1516,10 +1515,6 @@ static struct drm_driver driver = {
.load = vmw_driver_load,
.unload = vmw_driver_unload,
.lastclose = vmw_lastclose,
- .irq_preinstall = vmw_irq_preinstall,
- .irq_postinstall = vmw_irq_postinstall,
- .irq_uninstall = vmw_irq_uninstall,
- .irq_handler = vmw_irq_handler,
.get_vblank_counter = vmw_get_vblank_counter,
.enable_vblank = vmw_enable_vblank,
.disable_vblank = vmw_disable_vblank,
@@ -1531,7 +1526,6 @@ static struct drm_driver driver = {
.master_drop = vmw_master_drop,
.open = vmw_driver_open,
.postclose = vmw_postclose,
- .set_busid = drm_pci_set_busid,
.dumb_create = vmw_dumb_create,
.dumb_map_offset = vmw_dumb_map_offset,
@@ -1571,7 +1565,7 @@ static int __init vmwgfx_init(void)
if (vgacon_text_force())
return -EINVAL;
- ret = drm_pci_init(&driver, &vmw_pci_driver);
+ ret = pci_register_driver(&vmw_pci_driver);
if (ret)
DRM_ERROR("Failed initializing DRM.\n");
return ret;
@@ -1579,7 +1573,7 @@ static int __init vmwgfx_init(void)
static void __exit vmwgfx_exit(void)
{
- drm_pci_exit(&driver, &vmw_pci_driver);
+ pci_unregister_driver(&vmw_pci_driver);
}
module_init(vmwgfx_init);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index 4b948fb..7e5f30e 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -40,10 +40,12 @@
#include <drm/ttm/ttm_execbuf_util.h>
#include <drm/ttm/ttm_module.h>
#include "vmwgfx_fence.h"
+#include <linux/sync_file.h>
-#define VMWGFX_DRIVER_DATE "20170607"
+#define VMWGFX_DRIVER_NAME "vmwgfx"
+#define VMWGFX_DRIVER_DATE "20170612"
#define VMWGFX_DRIVER_MAJOR 2
-#define VMWGFX_DRIVER_MINOR 13
+#define VMWGFX_DRIVER_MINOR 14
#define VMWGFX_DRIVER_PATCHLEVEL 0
#define VMWGFX_FILE_PAGE_OFFSET 0x00100000
#define VMWGFX_FIFO_STATIC_SIZE (1024*1024)
@@ -351,6 +353,12 @@ struct vmw_otable_batch {
struct ttm_buffer_object *otable_bo;
};
+enum {
+ VMW_IRQTHREAD_FENCE,
+ VMW_IRQTHREAD_CMDBUF,
+ VMW_IRQTHREAD_MAX
+};
+
struct vmw_private {
struct ttm_bo_device bdev;
struct ttm_bo_global_ref bo_global_ref;
@@ -529,6 +537,7 @@ struct vmw_private {
struct vmw_otable_batch otable_batch;
struct vmw_cmdbuf_man *cman;
+ DECLARE_BITMAP(irqthread_pending, VMW_IRQTHREAD_MAX);
};
static inline struct vmw_surface *vmw_res_to_srf(struct vmw_resource *res)
@@ -561,24 +570,21 @@ static inline struct vmw_master *vmw_master(struct drm_master *master)
static inline void vmw_write(struct vmw_private *dev_priv,
unsigned int offset, uint32_t value)
{
- unsigned long irq_flags;
-
- spin_lock_irqsave(&dev_priv->hw_lock, irq_flags);
+ spin_lock(&dev_priv->hw_lock);
outl(offset, dev_priv->io_start + VMWGFX_INDEX_PORT);
outl(value, dev_priv->io_start + VMWGFX_VALUE_PORT);
- spin_unlock_irqrestore(&dev_priv->hw_lock, irq_flags);
+ spin_unlock(&dev_priv->hw_lock);
}
static inline uint32_t vmw_read(struct vmw_private *dev_priv,
unsigned int offset)
{
- unsigned long irq_flags;
u32 val;
- spin_lock_irqsave(&dev_priv->hw_lock, irq_flags);
+ spin_lock(&dev_priv->hw_lock);
outl(offset, dev_priv->io_start + VMWGFX_INDEX_PORT);
val = inl(dev_priv->io_start + VMWGFX_VALUE_PORT);
- spin_unlock_irqrestore(&dev_priv->hw_lock, irq_flags);
+ spin_unlock(&dev_priv->hw_lock);
return val;
}
@@ -821,7 +827,8 @@ extern int vmw_execbuf_process(struct drm_file *file_priv,
uint32_t dx_context_handle,
struct drm_vmw_fence_rep __user
*user_fence_rep,
- struct vmw_fence_obj **out_fence);
+ struct vmw_fence_obj **out_fence,
+ uint32_t flags);
extern void __vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv,
struct vmw_fence_obj *fence);
extern void vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv);
@@ -836,23 +843,23 @@ extern void vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv,
struct drm_vmw_fence_rep __user
*user_fence_rep,
struct vmw_fence_obj *fence,
- uint32_t fence_handle);
+ uint32_t fence_handle,
+ int32_t out_fence_fd,
+ struct sync_file *sync_file);
extern int vmw_validate_single_buffer(struct vmw_private *dev_priv,
struct ttm_buffer_object *bo,
bool interruptible,
bool validate_as_mob);
-
+bool vmw_cmd_describe(const void *buf, u32 *size, char const **cmd);
/**
* IRQs and wating - vmwgfx_irq.c
*/
-extern irqreturn_t vmw_irq_handler(int irq, void *arg);
extern int vmw_wait_seqno(struct vmw_private *dev_priv, bool lazy,
uint32_t seqno, bool interruptible,
unsigned long timeout);
-extern void vmw_irq_preinstall(struct drm_device *dev);
-extern int vmw_irq_postinstall(struct drm_device *dev);
+extern int vmw_irq_install(struct drm_device *dev, int irq);
extern void vmw_irq_uninstall(struct drm_device *dev);
extern bool vmw_seqno_passed(struct vmw_private *dev_priv,
uint32_t seqno);
@@ -1150,13 +1157,13 @@ extern void *vmw_cmdbuf_reserve(struct vmw_cmdbuf_man *man, size_t size,
extern void vmw_cmdbuf_commit(struct vmw_cmdbuf_man *man, size_t size,
struct vmw_cmdbuf_header *header,
bool flush);
-extern void vmw_cmdbuf_tasklet_schedule(struct vmw_cmdbuf_man *man);
extern void *vmw_cmdbuf_alloc(struct vmw_cmdbuf_man *man,
size_t size, bool interruptible,
struct vmw_cmdbuf_header **p_header);
extern void vmw_cmdbuf_header_free(struct vmw_cmdbuf_header *header);
extern int vmw_cmdbuf_cur_flush(struct vmw_cmdbuf_man *man,
bool interruptible);
+extern void vmw_cmdbuf_irqthread(struct vmw_cmdbuf_man *man);
/**
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
index 2cfb3c9..21c62a3 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
@@ -24,6 +24,7 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
+#include <linux/sync_file.h>
#include "vmwgfx_drv.h"
#include "vmwgfx_reg.h"
@@ -112,11 +113,12 @@ struct vmw_cmd_entry {
bool user_allow;
bool gb_disable;
bool gb_enable;
+ const char *cmd_name;
};
#define VMW_CMD_DEF(_cmd, _func, _user_allow, _gb_disable, _gb_enable) \
[(_cmd) - SVGA_3D_CMD_BASE] = {(_func), (_user_allow),\
- (_gb_disable), (_gb_enable)}
+ (_gb_disable), (_gb_enable), #_cmd}
static int vmw_resource_context_res_add(struct vmw_private *dev_priv,
struct vmw_sw_context *sw_context,
@@ -3302,6 +3304,8 @@ static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = {
true, false, true),
VMW_CMD_DEF(SVGA_3D_CMD_NOP, &vmw_cmd_ok,
true, false, true),
+ VMW_CMD_DEF(SVGA_3D_CMD_NOP_ERROR, &vmw_cmd_ok,
+ true, false, true),
VMW_CMD_DEF(SVGA_3D_CMD_ENABLE_GART, &vmw_cmd_invalid,
false, false, true),
VMW_CMD_DEF(SVGA_3D_CMD_DISABLE_GART, &vmw_cmd_invalid,
@@ -3469,6 +3473,51 @@ static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = {
true, false, true),
};
+bool vmw_cmd_describe(const void *buf, u32 *size, char const **cmd)
+{
+ u32 cmd_id = ((u32 *) buf)[0];
+
+ if (cmd_id >= SVGA_CMD_MAX) {
+ SVGA3dCmdHeader *header = (SVGA3dCmdHeader *) buf;
+ const struct vmw_cmd_entry *entry;
+
+ *size = header->size + sizeof(SVGA3dCmdHeader);
+ cmd_id = header->id;
+ if (cmd_id >= SVGA_3D_CMD_MAX)
+ return false;
+
+ cmd_id -= SVGA_3D_CMD_BASE;
+ entry = &vmw_cmd_entries[cmd_id];
+ *cmd = entry->cmd_name;
+ return true;
+ }
+
+ switch (cmd_id) {
+ case SVGA_CMD_UPDATE:
+ *cmd = "SVGA_CMD_UPDATE";
+ *size = sizeof(u32) + sizeof(SVGAFifoCmdUpdate);
+ break;
+ case SVGA_CMD_DEFINE_GMRFB:
+ *cmd = "SVGA_CMD_DEFINE_GMRFB";
+ *size = sizeof(u32) + sizeof(SVGAFifoCmdDefineGMRFB);
+ break;
+ case SVGA_CMD_BLIT_GMRFB_TO_SCREEN:
+ *cmd = "SVGA_CMD_BLIT_GMRFB_TO_SCREEN";
+ *size = sizeof(u32) + sizeof(SVGAFifoCmdBlitGMRFBToScreen);
+ break;
+ case SVGA_CMD_BLIT_SCREEN_TO_GMRFB:
+ *cmd = "SVGA_CMD_BLIT_SCREEN_TO_GMRFB";
+ *size = sizeof(u32) + sizeof(SVGAFifoCmdBlitGMRFBToScreen);
+ break;
+ default:
+ *cmd = "UNKNOWN";
+ *size = 0;
+ return false;
+ }
+
+ return true;
+}
+
static int vmw_cmd_check(struct vmw_private *dev_priv,
struct vmw_sw_context *sw_context,
void *buf, uint32_t *size)
@@ -3781,6 +3830,8 @@ int vmw_execbuf_fence_commands(struct drm_file *file_priv,
* which the information should be copied.
* @fence: Pointer to the fenc object.
* @fence_handle: User-space fence handle.
+ * @out_fence_fd: exported file descriptor for the fence. -1 if not used
+ * @sync_file: Only used to clean up in case of an error in this function.
*
* This function copies fence information to user-space. If copying fails,
* The user-space struct drm_vmw_fence_rep::error member is hopefully
@@ -3796,7 +3847,9 @@ vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv,
int ret,
struct drm_vmw_fence_rep __user *user_fence_rep,
struct vmw_fence_obj *fence,
- uint32_t fence_handle)
+ uint32_t fence_handle,
+ int32_t out_fence_fd,
+ struct sync_file *sync_file)
{
struct drm_vmw_fence_rep fence_rep;
@@ -3806,6 +3859,7 @@ vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv,
memset(&fence_rep, 0, sizeof(fence_rep));
fence_rep.error = ret;
+ fence_rep.fd = out_fence_fd;
if (ret == 0) {
BUG_ON(fence == NULL);
@@ -3828,6 +3882,14 @@ vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv,
* and unreference the handle.
*/
if (unlikely(ret != 0) && (fence_rep.error == 0)) {
+ if (sync_file)
+ fput(sync_file->file);
+
+ if (fence_rep.fd != -1) {
+ put_unused_fd(fence_rep.fd);
+ fence_rep.fd = -1;
+ }
+
ttm_ref_object_base_unref(vmw_fp->tfile,
fence_handle, TTM_REF_USAGE);
DRM_ERROR("Fence copy error. Syncing.\n");
@@ -4003,7 +4065,8 @@ int vmw_execbuf_process(struct drm_file *file_priv,
uint64_t throttle_us,
uint32_t dx_context_handle,
struct drm_vmw_fence_rep __user *user_fence_rep,
- struct vmw_fence_obj **out_fence)
+ struct vmw_fence_obj **out_fence,
+ uint32_t flags)
{
struct vmw_sw_context *sw_context = &dev_priv->ctx;
struct vmw_fence_obj *fence = NULL;
@@ -4013,20 +4076,33 @@ int vmw_execbuf_process(struct drm_file *file_priv,
struct ww_acquire_ctx ticket;
uint32_t handle;
int ret;
+ int32_t out_fence_fd = -1;
+ struct sync_file *sync_file = NULL;
+
+
+ if (flags & DRM_VMW_EXECBUF_FLAG_EXPORT_FENCE_FD) {
+ out_fence_fd = get_unused_fd_flags(O_CLOEXEC);
+ if (out_fence_fd < 0) {
+ DRM_ERROR("Failed to get a fence file descriptor.\n");
+ return out_fence_fd;
+ }
+ }
if (throttle_us) {
ret = vmw_wait_lag(dev_priv, &dev_priv->fifo.marker_queue,
throttle_us);
if (ret)
- return ret;
+ goto out_free_fence_fd;
}
kernel_commands = vmw_execbuf_cmdbuf(dev_priv, user_commands,
kernel_commands, command_size,
&header);
- if (IS_ERR(kernel_commands))
- return PTR_ERR(kernel_commands);
+ if (IS_ERR(kernel_commands)) {
+ ret = PTR_ERR(kernel_commands);
+ goto out_free_fence_fd;
+ }
ret = mutex_lock_interruptible(&dev_priv->cmdbuf_mutex);
if (ret) {
@@ -4162,8 +4238,32 @@ int vmw_execbuf_process(struct drm_file *file_priv,
__vmw_execbuf_release_pinned_bo(dev_priv, fence);
vmw_clear_validations(sw_context);
+
+ /*
+ * If anything fails here, give up trying to export the fence
+ * and do a sync since the user mode will not be able to sync
+ * the fence itself. This ensures we are still functionally
+ * correct.
+ */
+ if (flags & DRM_VMW_EXECBUF_FLAG_EXPORT_FENCE_FD) {
+
+ sync_file = sync_file_create(&fence->base);
+ if (!sync_file) {
+ DRM_ERROR("Unable to create sync file for fence\n");
+ put_unused_fd(out_fence_fd);
+ out_fence_fd = -1;
+
+ (void) vmw_fence_obj_wait(fence, false, false,
+ VMW_FENCE_WAIT_TIMEOUT);
+ } else {
+ /* Link the fence with the FD created earlier */
+ fd_install(out_fence_fd, sync_file->file);
+ }
+ }
+
vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret,
- user_fence_rep, fence, handle);
+ user_fence_rep, fence, handle,
+ out_fence_fd, sync_file);
/* Don't unreference when handing fence out */
if (unlikely(out_fence != NULL)) {
@@ -4214,6 +4314,9 @@ out_unlock:
out_free_header:
if (header)
vmw_cmdbuf_header_free(header);
+out_free_fence_fd:
+ if (out_fence_fd >= 0)
+ put_unused_fd(out_fence_fd);
return ret;
}
@@ -4366,6 +4469,7 @@ int vmw_execbuf_ioctl(struct drm_device *dev, unsigned long data,
static const size_t copy_offset[] = {
offsetof(struct drm_vmw_execbuf_arg, context_handle),
sizeof(struct drm_vmw_execbuf_arg)};
+ struct dma_fence *in_fence = NULL;
if (unlikely(size < copy_offset[0])) {
DRM_ERROR("Invalid command size, ioctl %d\n",
@@ -4401,15 +4505,25 @@ int vmw_execbuf_ioctl(struct drm_device *dev, unsigned long data,
arg.context_handle = (uint32_t) -1;
break;
case 2:
- if (arg.pad64 != 0) {
- DRM_ERROR("Unused IOCTL data not set to zero.\n");
- return -EINVAL;
- }
- break;
default:
break;
}
+
+ /* If imported a fence FD from elsewhere, then wait on it */
+ if (arg.flags & DRM_VMW_EXECBUF_FLAG_IMPORT_FENCE_FD) {
+ in_fence = sync_file_get_fence(arg.imported_fence_fd);
+
+ if (!in_fence) {
+ DRM_ERROR("Cannot get imported fence\n");
+ return -EINVAL;
+ }
+
+ ret = vmw_wait_dma_fence(dev_priv->fman, in_fence);
+ if (ret)
+ goto out;
+ }
+
ret = ttm_read_lock(&dev_priv->reservation_sem, true);
if (unlikely(ret != 0))
return ret;
@@ -4419,12 +4533,16 @@ int vmw_execbuf_ioctl(struct drm_device *dev, unsigned long data,
NULL, arg.command_size, arg.throttle_us,
arg.context_handle,
(void __user *)(unsigned long)arg.fence_rep,
- NULL);
+ NULL,
+ arg.flags);
ttm_read_unlock(&dev_priv->reservation_sem);
if (unlikely(ret != 0))
- return ret;
+ goto out;
vmw_kms_cursor_post_execbuf(dev_priv);
- return 0;
+out:
+ if (in_fence)
+ dma_fence_put(in_fence);
+ return ret;
}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
index 6f4cb46..d23a18a 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
@@ -779,7 +779,6 @@ int vmw_fb_init(struct vmw_private *vmw_priv)
info->screen_base = (char __iomem *)par->vmalloc;
info->screen_size = fb_size;
- info->flags = FBINFO_DEFAULT;
info->fbops = &vmw_fb_ops;
/* 24 depth per default */
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
index b8bc5bc..3bbad22 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
@@ -114,12 +114,11 @@ static void vmw_fence_obj_destroy(struct dma_fence *f)
container_of(f, struct vmw_fence_obj, base);
struct vmw_fence_manager *fman = fman_from_fence(fence);
- unsigned long irq_flags;
- spin_lock_irqsave(&fman->lock, irq_flags);
+ spin_lock(&fman->lock);
list_del_init(&fence->head);
--fman->num_fence_objects;
- spin_unlock_irqrestore(&fman->lock, irq_flags);
+ spin_unlock(&fman->lock);
fence->destroy(fence);
}
@@ -252,10 +251,10 @@ static void vmw_fence_work_func(struct work_struct *work)
INIT_LIST_HEAD(&list);
mutex_lock(&fman->goal_irq_mutex);
- spin_lock_irq(&fman->lock);
+ spin_lock(&fman->lock);
list_splice_init(&fman->cleanup_list, &list);
seqno_valid = fman->seqno_valid;
- spin_unlock_irq(&fman->lock);
+ spin_unlock(&fman->lock);
if (!seqno_valid && fman->goal_irq_on) {
fman->goal_irq_on = false;
@@ -305,15 +304,14 @@ struct vmw_fence_manager *vmw_fence_manager_init(struct vmw_private *dev_priv)
void vmw_fence_manager_takedown(struct vmw_fence_manager *fman)
{
- unsigned long irq_flags;
bool lists_empty;
(void) cancel_work_sync(&fman->work);
- spin_lock_irqsave(&fman->lock, irq_flags);
+ spin_lock(&fman->lock);
lists_empty = list_empty(&fman->fence_list) &&
list_empty(&fman->cleanup_list);
- spin_unlock_irqrestore(&fman->lock, irq_flags);
+ spin_unlock(&fman->lock);
BUG_ON(!lists_empty);
kfree(fman);
@@ -323,7 +321,6 @@ static int vmw_fence_obj_init(struct vmw_fence_manager *fman,
struct vmw_fence_obj *fence, u32 seqno,
void (*destroy) (struct vmw_fence_obj *fence))
{
- unsigned long irq_flags;
int ret = 0;
dma_fence_init(&fence->base, &vmw_fence_ops, &fman->lock,
@@ -331,7 +328,7 @@ static int vmw_fence_obj_init(struct vmw_fence_manager *fman,
INIT_LIST_HEAD(&fence->seq_passed_actions);
fence->destroy = destroy;
- spin_lock_irqsave(&fman->lock, irq_flags);
+ spin_lock(&fman->lock);
if (unlikely(fman->fifo_down)) {
ret = -EBUSY;
goto out_unlock;
@@ -340,7 +337,7 @@ static int vmw_fence_obj_init(struct vmw_fence_manager *fman,
++fman->num_fence_objects;
out_unlock:
- spin_unlock_irqrestore(&fman->lock, irq_flags);
+ spin_unlock(&fman->lock);
return ret;
}
@@ -489,11 +486,9 @@ rerun:
void vmw_fences_update(struct vmw_fence_manager *fman)
{
- unsigned long irq_flags;
-
- spin_lock_irqsave(&fman->lock, irq_flags);
+ spin_lock(&fman->lock);
__vmw_fences_update(fman);
- spin_unlock_irqrestore(&fman->lock, irq_flags);
+ spin_unlock(&fman->lock);
}
bool vmw_fence_obj_signaled(struct vmw_fence_obj *fence)
@@ -650,6 +645,51 @@ out_no_object:
/**
+ * vmw_wait_dma_fence - Wait for a dma fence
+ *
+ * @fman: pointer to a fence manager
+ * @fence: DMA fence to wait on
+ *
+ * This function handles the case when the fence is actually a fence
+ * array. If that's the case, it'll wait on each of the child fence
+ */
+int vmw_wait_dma_fence(struct vmw_fence_manager *fman,
+ struct dma_fence *fence)
+{
+ struct dma_fence_array *fence_array;
+ int ret = 0;
+ int i;
+
+
+ if (dma_fence_is_signaled(fence))
+ return 0;
+
+ if (!dma_fence_is_array(fence))
+ return dma_fence_wait(fence, true);
+
+ /* From i915: Note that if the fence-array was created in
+ * signal-on-any mode, we should *not* decompose it into its individual
+ * fences. However, we don't currently store which mode the fence-array
+ * is operating in. Fortunately, the only user of signal-on-any is
+ * private to amdgpu and we should not see any incoming fence-array
+ * from sync-file being in signal-on-any mode.
+ */
+
+ fence_array = to_dma_fence_array(fence);
+ for (i = 0; i < fence_array->num_fences; i++) {
+ struct dma_fence *child = fence_array->fences[i];
+
+ ret = dma_fence_wait(child, true);
+
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+
+/**
* vmw_fence_fifo_down - signal all unsignaled fence objects.
*/
@@ -663,14 +703,14 @@ void vmw_fence_fifo_down(struct vmw_fence_manager *fman)
* restart when we've released the fman->lock.
*/
- spin_lock_irq(&fman->lock);
+ spin_lock(&fman->lock);
fman->fifo_down = true;
while (!list_empty(&fman->fence_list)) {
struct vmw_fence_obj *fence =
list_entry(fman->fence_list.prev, struct vmw_fence_obj,
head);
dma_fence_get(&fence->base);
- spin_unlock_irq(&fman->lock);
+ spin_unlock(&fman->lock);
ret = vmw_fence_obj_wait(fence, false, false,
VMW_FENCE_WAIT_TIMEOUT);
@@ -686,18 +726,16 @@ void vmw_fence_fifo_down(struct vmw_fence_manager *fman)
BUG_ON(!list_empty(&fence->head));
dma_fence_put(&fence->base);
- spin_lock_irq(&fman->lock);
+ spin_lock(&fman->lock);
}
- spin_unlock_irq(&fman->lock);
+ spin_unlock(&fman->lock);
}
void vmw_fence_fifo_up(struct vmw_fence_manager *fman)
{
- unsigned long irq_flags;
-
- spin_lock_irqsave(&fman->lock, irq_flags);
+ spin_lock(&fman->lock);
fman->fifo_down = false;
- spin_unlock_irqrestore(&fman->lock, irq_flags);
+ spin_unlock(&fman->lock);
}
@@ -812,9 +850,9 @@ int vmw_fence_obj_signaled_ioctl(struct drm_device *dev, void *data,
arg->signaled = vmw_fence_obj_signaled(fence);
arg->signaled_flags = arg->flags;
- spin_lock_irq(&fman->lock);
+ spin_lock(&fman->lock);
arg->passed_seqno = dev_priv->last_read_seqno;
- spin_unlock_irq(&fman->lock);
+ spin_unlock(&fman->lock);
ttm_base_object_unref(&base);
@@ -841,8 +879,7 @@ int vmw_fence_obj_unref_ioctl(struct drm_device *dev, void *data,
*
* This function is called when the seqno of the fence where @action is
* attached has passed. It queues the event on the submitter's event list.
- * This function is always called from atomic context, and may be called
- * from irq context.
+ * This function is always called from atomic context.
*/
static void vmw_event_fence_action_seq_passed(struct vmw_fence_action *action)
{
@@ -851,13 +888,13 @@ static void vmw_event_fence_action_seq_passed(struct vmw_fence_action *action)
struct drm_device *dev = eaction->dev;
struct drm_pending_event *event = eaction->event;
struct drm_file *file_priv;
- unsigned long irq_flags;
+
if (unlikely(event == NULL))
return;
file_priv = event->file_priv;
- spin_lock_irqsave(&dev->event_lock, irq_flags);
+ spin_lock_irq(&dev->event_lock);
if (likely(eaction->tv_sec != NULL)) {
struct timeval tv;
@@ -869,7 +906,7 @@ static void vmw_event_fence_action_seq_passed(struct vmw_fence_action *action)
drm_send_event_locked(dev, eaction->event);
eaction->event = NULL;
- spin_unlock_irqrestore(&dev->event_lock, irq_flags);
+ spin_unlock_irq(&dev->event_lock);
}
/**
@@ -904,11 +941,10 @@ static void vmw_fence_obj_add_action(struct vmw_fence_obj *fence,
struct vmw_fence_action *action)
{
struct vmw_fence_manager *fman = fman_from_fence(fence);
- unsigned long irq_flags;
bool run_update = false;
mutex_lock(&fman->goal_irq_mutex);
- spin_lock_irqsave(&fman->lock, irq_flags);
+ spin_lock(&fman->lock);
fman->pending_actions[action->type]++;
if (dma_fence_is_signaled_locked(&fence->base)) {
@@ -927,7 +963,7 @@ static void vmw_fence_obj_add_action(struct vmw_fence_obj *fence,
run_update = vmw_fence_goal_check_locked(fence);
}
- spin_unlock_irqrestore(&fman->lock, irq_flags);
+ spin_unlock(&fman->lock);
if (run_update) {
if (!fman->goal_irq_on) {
@@ -1114,7 +1150,7 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data,
}
vmw_execbuf_copy_fence_user(dev_priv, vmw_fp, 0, user_fence_rep, fence,
- handle);
+ handle, -1, NULL);
vmw_fence_obj_unreference(&fence);
return 0;
out_no_create:
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.h b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.h
index d9d85aa..20224db 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.h
@@ -28,6 +28,7 @@
#ifndef _VMWGFX_FENCE_H_
#include <linux/dma-fence.h>
+#include <linux/dma-fence-array.h>
#define VMW_FENCE_WAIT_TIMEOUT (5*HZ)
@@ -102,6 +103,9 @@ extern int vmw_user_fence_create(struct drm_file *file_priv,
struct vmw_fence_obj **p_fence,
uint32_t *p_handle);
+extern int vmw_wait_dma_fence(struct vmw_fence_manager *fman,
+ struct dma_fence *fence);
+
extern void vmw_fence_fifo_up(struct vmw_fence_manager *fman);
extern void vmw_fence_fifo_down(struct vmw_fence_manager *fman);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
index d2b03d4..f2f9d88 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
@@ -157,9 +157,9 @@ static int vmw_gmrid_man_takedown(struct ttm_mem_type_manager *man)
}
static void vmw_gmrid_man_debug(struct ttm_mem_type_manager *man,
- const char *prefix)
+ struct drm_printer *printer)
{
- pr_info("%s: No debug info available for the GMR id manager\n", prefix);
+ drm_printf(printer, "No debug info available for the GMR id manager\n");
}
const struct ttm_mem_type_manager_func vmw_gmrid_manager_func = {
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c
index 0c7e172..b9239ba 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c
@@ -30,11 +30,56 @@
#define VMW_FENCE_WRAP (1 << 24)
-irqreturn_t vmw_irq_handler(int irq, void *arg)
+/**
+ * vmw_thread_fn - Deferred (process context) irq handler
+ *
+ * @irq: irq number
+ * @arg: Closure argument. Pointer to a struct drm_device cast to void *
+ *
+ * This function implements the deferred part of irq processing.
+ * The function is guaranteed to run at least once after the
+ * vmw_irq_handler has returned with IRQ_WAKE_THREAD.
+ *
+ */
+static irqreturn_t vmw_thread_fn(int irq, void *arg)
+{
+ struct drm_device *dev = (struct drm_device *)arg;
+ struct vmw_private *dev_priv = vmw_priv(dev);
+ irqreturn_t ret = IRQ_NONE;
+
+ if (test_and_clear_bit(VMW_IRQTHREAD_FENCE,
+ dev_priv->irqthread_pending)) {
+ vmw_fences_update(dev_priv->fman);
+ wake_up_all(&dev_priv->fence_queue);
+ ret = IRQ_HANDLED;
+ }
+
+ if (test_and_clear_bit(VMW_IRQTHREAD_CMDBUF,
+ dev_priv->irqthread_pending)) {
+ vmw_cmdbuf_irqthread(dev_priv->cman);
+ ret = IRQ_HANDLED;
+ }
+
+ return ret;
+}
+
+/**
+ * vmw_irq_handler irq handler
+ *
+ * @irq: irq number
+ * @arg: Closure argument. Pointer to a struct drm_device cast to void *
+ *
+ * This function implements the quick part of irq processing.
+ * The function performs fast actions like clearing the device interrupt
+ * flags and also reasonably quick actions like waking processes waiting for
+ * FIFO space. Other IRQ actions are deferred to the IRQ thread.
+ */
+static irqreturn_t vmw_irq_handler(int irq, void *arg)
{
struct drm_device *dev = (struct drm_device *)arg;
struct vmw_private *dev_priv = vmw_priv(dev);
uint32_t status, masked_status;
+ irqreturn_t ret = IRQ_HANDLED;
status = inl(dev_priv->io_start + VMWGFX_IRQSTATUS_PORT);
masked_status = status & READ_ONCE(dev_priv->irq_mask);
@@ -45,20 +90,21 @@ irqreturn_t vmw_irq_handler(int irq, void *arg)
if (!status)
return IRQ_NONE;
- if (masked_status & (SVGA_IRQFLAG_ANY_FENCE |
- SVGA_IRQFLAG_FENCE_GOAL)) {
- vmw_fences_update(dev_priv->fman);
- wake_up_all(&dev_priv->fence_queue);
- }
-
if (masked_status & SVGA_IRQFLAG_FIFO_PROGRESS)
wake_up_all(&dev_priv->fifo_queue);
- if (masked_status & (SVGA_IRQFLAG_COMMAND_BUFFER |
- SVGA_IRQFLAG_ERROR))
- vmw_cmdbuf_tasklet_schedule(dev_priv->cman);
+ if ((masked_status & (SVGA_IRQFLAG_ANY_FENCE |
+ SVGA_IRQFLAG_FENCE_GOAL)) &&
+ !test_and_set_bit(VMW_IRQTHREAD_FENCE, dev_priv->irqthread_pending))
+ ret = IRQ_WAKE_THREAD;
- return IRQ_HANDLED;
+ if ((masked_status & (SVGA_IRQFLAG_COMMAND_BUFFER |
+ SVGA_IRQFLAG_ERROR)) &&
+ !test_and_set_bit(VMW_IRQTHREAD_CMDBUF,
+ dev_priv->irqthread_pending))
+ ret = IRQ_WAKE_THREAD;
+
+ return ret;
}
static bool vmw_fifo_idle(struct vmw_private *dev_priv, uint32_t seqno)
@@ -281,23 +327,15 @@ int vmw_wait_seqno(struct vmw_private *dev_priv,
return ret;
}
-void vmw_irq_preinstall(struct drm_device *dev)
+static void vmw_irq_preinstall(struct drm_device *dev)
{
struct vmw_private *dev_priv = vmw_priv(dev);
uint32_t status;
- if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK))
- return;
-
status = inl(dev_priv->io_start + VMWGFX_IRQSTATUS_PORT);
outl(status, dev_priv->io_start + VMWGFX_IRQSTATUS_PORT);
}
-int vmw_irq_postinstall(struct drm_device *dev)
-{
- return 0;
-}
-
void vmw_irq_uninstall(struct drm_device *dev)
{
struct vmw_private *dev_priv = vmw_priv(dev);
@@ -306,8 +344,41 @@ void vmw_irq_uninstall(struct drm_device *dev)
if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK))
return;
+ if (!dev->irq_enabled)
+ return;
+
vmw_write(dev_priv, SVGA_REG_IRQMASK, 0);
status = inl(dev_priv->io_start + VMWGFX_IRQSTATUS_PORT);
outl(status, dev_priv->io_start + VMWGFX_IRQSTATUS_PORT);
+
+ dev->irq_enabled = false;
+ free_irq(dev->irq, dev);
+}
+
+/**
+ * vmw_irq_install - Install the irq handlers
+ *
+ * @dev: Pointer to the drm device.
+ * @irq: The irq number.
+ * Return: Zero if successful. Negative number otherwise.
+ */
+int vmw_irq_install(struct drm_device *dev, int irq)
+{
+ int ret;
+
+ if (dev->irq_enabled)
+ return -EBUSY;
+
+ vmw_irq_preinstall(dev);
+
+ ret = request_threaded_irq(irq, vmw_irq_handler, vmw_thread_fn,
+ IRQF_SHARED, VMWGFX_DRIVER_NAME, dev);
+ if (ret < 0)
+ return ret;
+
+ dev->irq_enabled = true;
+ dev->irq = irq;
+
+ return ret;
}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 61e06f0..b850562f 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -1536,7 +1536,7 @@ err_out:
* RETURNS
* Zero for success or -errno
*/
-int
+static int
vmw_kms_atomic_check_modeset(struct drm_device *dev,
struct drm_atomic_state *state)
{
@@ -1545,8 +1545,7 @@ vmw_kms_atomic_check_modeset(struct drm_device *dev,
struct vmw_private *dev_priv = vmw_priv(dev);
int i;
-
- for_each_crtc_in_state(state, crtc, crtc_state, i) {
+ for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
unsigned long requested_bb_mem = 0;
if (dev_priv->active_display_unit == vmw_du_screen_target) {
@@ -1567,10 +1566,34 @@ vmw_kms_atomic_check_modeset(struct drm_device *dev,
}
+/**
+ * vmw_kms_atomic_commit - Perform an atomic state commit
+ *
+ * @dev: DRM device
+ * @state: the driver state object
+ * @nonblock: Whether nonblocking behaviour is requested
+ *
+ * This is a simple wrapper around drm_atomic_helper_commit() for
+ * us to clear the nonblocking value.
+ *
+ * Nonblocking commits currently cause synchronization issues
+ * for vmwgfx.
+ *
+ * RETURNS
+ * Zero for success or negative error code on failure.
+ */
+int vmw_kms_atomic_commit(struct drm_device *dev,
+ struct drm_atomic_state *state,
+ bool nonblock)
+{
+ return drm_atomic_helper_commit(dev, state, false);
+}
+
+
static const struct drm_mode_config_funcs vmw_kms_funcs = {
.fb_create = vmw_kms_fb_create,
.atomic_check = vmw_kms_atomic_check_modeset,
- .atomic_commit = drm_atomic_helper_commit,
+ .atomic_commit = vmw_kms_atomic_commit,
};
static int vmw_kms_generic_present(struct vmw_private *dev_priv,
@@ -1667,7 +1690,7 @@ int vmw_kms_init(struct vmw_private *dev_priv)
int vmw_kms_close(struct vmw_private *dev_priv)
{
- int ret;
+ int ret = 0;
/*
* Docs says we should take the lock before calling this function
@@ -1675,11 +1698,7 @@ int vmw_kms_close(struct vmw_private *dev_priv)
* drm_encoder_cleanup which takes the lock we deadlock.
*/
drm_mode_config_cleanup(dev_priv->dev);
- if (dev_priv->active_display_unit == vmw_du_screen_object)
- ret = vmw_kms_sou_close_display(dev_priv);
- else if (dev_priv->active_display_unit == vmw_du_screen_target)
- ret = vmw_kms_stdu_close_display(dev_priv);
- else
+ if (dev_priv->active_display_unit == vmw_du_legacy)
ret = vmw_kms_ldu_close_display(dev_priv);
return ret;
@@ -2499,7 +2518,7 @@ void vmw_kms_helper_buffer_finish(struct vmw_private *dev_priv,
if (file_priv)
vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv),
ret, user_fence_rep, fence,
- handle);
+ handle, -1, NULL);
if (out_fence)
*out_fence = fence;
else
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
index 5f8d678..ff9c838 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
@@ -390,7 +390,6 @@ int vmw_kms_update_proxy(struct vmw_resource *res,
* Screen Objects display functions - vmwgfx_scrn.c
*/
int vmw_kms_sou_init_display(struct vmw_private *dev_priv);
-int vmw_kms_sou_close_display(struct vmw_private *dev_priv);
int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv,
struct vmw_framebuffer *framebuffer,
struct drm_clip_rect *clips,
@@ -418,7 +417,6 @@ int vmw_kms_sou_readback(struct vmw_private *dev_priv,
* Screen Target Display Unit functions - vmwgfx_stdu.c
*/
int vmw_kms_stdu_init_display(struct vmw_private *dev_priv);
-int vmw_kms_stdu_close_display(struct vmw_private *dev_priv);
int vmw_kms_stdu_surface_dirty(struct vmw_private *dev_priv,
struct vmw_framebuffer *framebuffer,
struct drm_clip_rect *clips,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
index d3987bc..b8a0980 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
@@ -203,19 +203,7 @@ static void vmw_ldu_crtc_mode_set_nofb(struct drm_crtc *crtc)
}
/**
- * vmw_ldu_crtc_helper_prepare - Noop
- *
- * @crtc: CRTC associated with the new screen
- *
- * Prepares the CRTC for a mode set, but we don't need to do anything here.
- *
- */
-static void vmw_ldu_crtc_helper_prepare(struct drm_crtc *crtc)
-{
-}
-
-/**
- * vmw_ldu_crtc_helper_commit - Noop
+ * vmw_ldu_crtc_atomic_enable - Noop
*
* @crtc: CRTC associated with the new screen
*
@@ -224,16 +212,18 @@ static void vmw_ldu_crtc_helper_prepare(struct drm_crtc *crtc)
* but since for LDU the display plane is closely tied to the
* CRTC, it makes more sense to do those at plane update time.
*/
-static void vmw_ldu_crtc_helper_commit(struct drm_crtc *crtc)
+static void vmw_ldu_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
}
/**
- * vmw_ldu_crtc_helper_disable - Turns off CRTC
+ * vmw_ldu_crtc_atomic_disable - Turns off CRTC
*
* @crtc: CRTC to be turned off
*/
-static void vmw_ldu_crtc_helper_disable(struct drm_crtc *crtc)
+static void vmw_ldu_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
}
@@ -388,13 +378,12 @@ drm_plane_helper_funcs vmw_ldu_primary_plane_helper_funcs = {
};
static const struct drm_crtc_helper_funcs vmw_ldu_crtc_helper_funcs = {
- .prepare = vmw_ldu_crtc_helper_prepare,
- .commit = vmw_ldu_crtc_helper_commit,
- .disable = vmw_ldu_crtc_helper_disable,
.mode_set_nofb = vmw_ldu_crtc_mode_set_nofb,
.atomic_check = vmw_du_crtc_atomic_check,
.atomic_begin = vmw_du_crtc_atomic_begin,
.atomic_flush = vmw_du_crtc_atomic_flush,
+ .atomic_enable = vmw_ldu_crtc_atomic_enable,
+ .atomic_disable = vmw_ldu_crtc_atomic_disable,
};
@@ -439,7 +428,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
0, &vmw_ldu_plane_funcs,
vmw_primary_plane_formats,
ARRAY_SIZE(vmw_primary_plane_formats),
- DRM_PLANE_TYPE_PRIMARY, NULL);
+ NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret) {
DRM_ERROR("Failed to initialize primary plane");
goto err_free;
@@ -454,7 +443,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
0, &vmw_ldu_cursor_funcs,
vmw_cursor_plane_formats,
ARRAY_SIZE(vmw_cursor_plane_formats),
- DRM_PLANE_TYPE_CURSOR, NULL);
+ NULL, DRM_PLANE_TYPE_CURSOR, NULL);
if (ret) {
DRM_ERROR("Failed to initialize cursor plane");
drm_plane_cleanup(&ldu->base.primary);
@@ -582,13 +571,9 @@ err_free:
int vmw_kms_ldu_close_display(struct vmw_private *dev_priv)
{
- struct drm_device *dev = dev_priv->dev;
-
if (!dev_priv->ldu_priv)
return -ENOSYS;
- drm_vblank_cleanup(dev);
-
BUG_ON(!list_empty(&dev_priv->ldu_priv->active));
kfree(dev_priv->ldu_priv);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
index 8d7dc9d..d1552d3 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
@@ -270,22 +270,24 @@ static void vmw_sou_crtc_helper_prepare(struct drm_crtc *crtc)
}
/**
- * vmw_sou_crtc_helper_commit - Noop
+ * vmw_sou_crtc_atomic_enable - Noop
*
* @crtc: CRTC associated with the new screen
*
* This is called after a mode set has been completed.
*/
-static void vmw_sou_crtc_helper_commit(struct drm_crtc *crtc)
+static void vmw_sou_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
}
/**
- * vmw_sou_crtc_helper_disable - Turns off CRTC
+ * vmw_sou_crtc_atomic_disable - Turns off CRTC
*
* @crtc: CRTC to be turned off
*/
-static void vmw_sou_crtc_helper_disable(struct drm_crtc *crtc)
+static void vmw_sou_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct vmw_private *dev_priv;
struct vmw_screen_object_unit *sou;
@@ -573,12 +575,12 @@ drm_plane_helper_funcs vmw_sou_primary_plane_helper_funcs = {
static const struct drm_crtc_helper_funcs vmw_sou_crtc_helper_funcs = {
.prepare = vmw_sou_crtc_helper_prepare,
- .commit = vmw_sou_crtc_helper_commit,
- .disable = vmw_sou_crtc_helper_disable,
.mode_set_nofb = vmw_sou_crtc_mode_set_nofb,
.atomic_check = vmw_du_crtc_atomic_check,
.atomic_begin = vmw_du_crtc_atomic_begin,
.atomic_flush = vmw_du_crtc_atomic_flush,
+ .atomic_enable = vmw_sou_crtc_atomic_enable,
+ .atomic_disable = vmw_sou_crtc_atomic_disable,
};
@@ -622,7 +624,7 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
0, &vmw_sou_plane_funcs,
vmw_primary_plane_formats,
ARRAY_SIZE(vmw_primary_plane_formats),
- DRM_PLANE_TYPE_PRIMARY, NULL);
+ NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret) {
DRM_ERROR("Failed to initialize primary plane");
goto err_free;
@@ -637,7 +639,7 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
0, &vmw_sou_cursor_funcs,
vmw_cursor_plane_formats,
ARRAY_SIZE(vmw_cursor_plane_formats),
- DRM_PLANE_TYPE_CURSOR, NULL);
+ NULL, DRM_PLANE_TYPE_CURSOR, NULL);
if (ret) {
DRM_ERROR("Failed to initialize cursor plane");
drm_plane_cleanup(&sou->base.primary);
@@ -746,15 +748,6 @@ int vmw_kms_sou_init_display(struct vmw_private *dev_priv)
return 0;
}
-int vmw_kms_sou_close_display(struct vmw_private *dev_priv)
-{
- struct drm_device *dev = dev_priv->dev;
-
- drm_vblank_cleanup(dev);
-
- return 0;
-}
-
static int do_dmabuf_define_gmrfb(struct vmw_private *dev_priv,
struct vmw_framebuffer *framebuffer)
{
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
index 5284e8d..ca3afae 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
@@ -412,7 +412,8 @@ static void vmw_stdu_crtc_helper_prepare(struct drm_crtc *crtc)
}
-static void vmw_stdu_crtc_helper_commit(struct drm_crtc *crtc)
+static void vmw_stdu_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct vmw_private *dev_priv;
struct vmw_screen_target_display_unit *stdu;
@@ -432,7 +433,8 @@ static void vmw_stdu_crtc_helper_commit(struct drm_crtc *crtc)
vmw_kms_del_active(dev_priv, &stdu->base);
}
-static void vmw_stdu_crtc_helper_disable(struct drm_crtc *crtc)
+static void vmw_stdu_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct vmw_private *dev_priv;
struct vmw_screen_target_display_unit *stdu;
@@ -1415,12 +1417,12 @@ drm_plane_helper_funcs vmw_stdu_primary_plane_helper_funcs = {
static const struct drm_crtc_helper_funcs vmw_stdu_crtc_helper_funcs = {
.prepare = vmw_stdu_crtc_helper_prepare,
- .commit = vmw_stdu_crtc_helper_commit,
- .disable = vmw_stdu_crtc_helper_disable,
.mode_set_nofb = vmw_stdu_crtc_mode_set_nofb,
.atomic_check = vmw_du_crtc_atomic_check,
.atomic_begin = vmw_du_crtc_atomic_begin,
.atomic_flush = vmw_du_crtc_atomic_flush,
+ .atomic_enable = vmw_stdu_crtc_atomic_enable,
+ .atomic_disable = vmw_stdu_crtc_atomic_disable,
};
@@ -1473,7 +1475,7 @@ static int vmw_stdu_init(struct vmw_private *dev_priv, unsigned unit)
0, &vmw_stdu_plane_funcs,
vmw_primary_plane_formats,
ARRAY_SIZE(vmw_primary_plane_formats),
- DRM_PLANE_TYPE_PRIMARY, NULL);
+ NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret) {
DRM_ERROR("Failed to initialize primary plane");
goto err_free;
@@ -1488,7 +1490,7 @@ static int vmw_stdu_init(struct vmw_private *dev_priv, unsigned unit)
0, &vmw_stdu_cursor_funcs,
vmw_cursor_plane_formats,
ARRAY_SIZE(vmw_cursor_plane_formats),
- DRM_PLANE_TYPE_CURSOR, NULL);
+ NULL, DRM_PLANE_TYPE_CURSOR, NULL);
if (ret) {
DRM_ERROR("Failed to initialize cursor plane");
drm_plane_cleanup(&stdu->base.primary);
@@ -1651,36 +1653,11 @@ int vmw_kms_stdu_init_display(struct vmw_private *dev_priv)
if (unlikely(ret != 0)) {
DRM_ERROR("Failed to initialize STDU %d", i);
- goto err_vblank_cleanup;
+ return ret;
}
}
DRM_INFO("Screen Target Display device initialized\n");
return 0;
-
-err_vblank_cleanup:
- drm_vblank_cleanup(dev);
- return ret;
-}
-
-
-
-/**
- * vmw_kms_stdu_close_display - Cleans up after vmw_kms_stdu_init_display
- *
- * @dev_priv: VMW DRM device
- *
- * Frees up any resources allocated by vmw_kms_stdu_init_display
- *
- * RETURNS:
- * 0 on success
- */
-int vmw_kms_stdu_close_display(struct vmw_private *dev_priv)
-{
- struct drm_device *dev = dev_priv->dev;
-
- drm_vblank_cleanup(dev);
-
- return 0;
}
diff --git a/drivers/gpu/drm/zte/zx_drm_drv.c b/drivers/gpu/drm/zte/zx_drm_drv.c
index f46c855..4524482 100644
--- a/drivers/gpu/drm/zte/zx_drm_drv.c
+++ b/drivers/gpu/drm/zte/zx_drm_drv.c
@@ -59,11 +59,9 @@ static struct drm_driver zx_drm_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
DRIVER_ATOMIC,
.lastclose = zx_drm_lastclose,
- .gem_free_object = drm_gem_cma_free_object,
+ .gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_export = drm_gem_prime_export,
@@ -149,7 +147,6 @@ out_fbdev_fini:
out_poll_fini:
drm_kms_helper_poll_fini(drm);
drm_mode_config_cleanup(drm);
- drm_vblank_cleanup(drm);
out_unbind:
component_unbind_all(dev, drm);
out_unregister:
@@ -171,7 +168,6 @@ static void zx_drm_unbind(struct device *dev)
}
drm_kms_helper_poll_fini(drm);
drm_mode_config_cleanup(drm);
- drm_vblank_cleanup(drm);
component_unbind_all(dev, drm);
dev_set_drvdata(dev, NULL);
drm->dev_private = NULL;
diff --git a/drivers/gpu/drm/zte/zx_hdmi.c b/drivers/gpu/drm/zte/zx_hdmi.c
index 0df7366..b8abb1b 100644
--- a/drivers/gpu/drm/zte/zx_hdmi.c
+++ b/drivers/gpu/drm/zte/zx_hdmi.c
@@ -124,7 +124,7 @@ static int zx_hdmi_config_video_avi(struct zx_hdmi *hdmi,
union hdmi_infoframe frame;
int ret;
- ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode);
+ ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode, false);
if (ret) {
DRM_DEV_ERROR(hdmi->dev, "failed to get avi infoframe: %d\n",
ret);
@@ -300,7 +300,6 @@ zx_hdmi_connector_detect(struct drm_connector *connector, bool force)
}
static const struct drm_connector_funcs zx_hdmi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = zx_hdmi_connector_detect,
.destroy = drm_connector_cleanup,
diff --git a/drivers/gpu/drm/zte/zx_plane.c b/drivers/gpu/drm/zte/zx_plane.c
index 4a62527..18e7634 100644
--- a/drivers/gpu/drm/zte/zx_plane.c
+++ b/drivers/gpu/drm/zte/zx_plane.c
@@ -540,7 +540,7 @@ int zx_plane_init(struct drm_device *drm, struct zx_plane *zplane,
ret = drm_universal_plane_init(drm, plane, VOU_CRTC_MASK,
&zx_plane_funcs, formats, format_count,
- type, NULL);
+ NULL, type, NULL);
if (ret) {
DRM_DEV_ERROR(dev, "failed to init universal plane: %d\n", ret);
return ret;
diff --git a/drivers/gpu/drm/zte/zx_tvenc.c b/drivers/gpu/drm/zte/zx_tvenc.c
index b56dc69..0de1a71 100644
--- a/drivers/gpu/drm/zte/zx_tvenc.c
+++ b/drivers/gpu/drm/zte/zx_tvenc.c
@@ -269,7 +269,6 @@ static struct drm_connector_helper_funcs zx_tvenc_connector_helper_funcs = {
};
static const struct drm_connector_funcs zx_tvenc_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
.reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/zte/zx_vga.c b/drivers/gpu/drm/zte/zx_vga.c
index 1e0811f..3e7e33c 100644
--- a/drivers/gpu/drm/zte/zx_vga.c
+++ b/drivers/gpu/drm/zte/zx_vga.c
@@ -138,7 +138,6 @@ zx_vga_connector_detect(struct drm_connector *connector, bool force)
}
static const struct drm_connector_funcs zx_vga_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = zx_vga_connector_detect,
.destroy = drm_connector_cleanup,
diff --git a/drivers/gpu/drm/zte/zx_vou.c b/drivers/gpu/drm/zte/zx_vou.c
index 5fbd10b..7491813 100644
--- a/drivers/gpu/drm/zte/zx_vou.c
+++ b/drivers/gpu/drm/zte/zx_vou.c
@@ -350,7 +350,8 @@ static inline void vou_chn_set_update(struct zx_crtc *zcrtc)
zx_writel(zcrtc->chnreg + CHN_UPDATE, 1);
}
-static void zx_crtc_enable(struct drm_crtc *crtc)
+static void zx_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct drm_display_mode *mode = &crtc->state->adjusted_mode;
bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
@@ -454,7 +455,8 @@ static void zx_crtc_enable(struct drm_crtc *crtc)
DRM_DEV_ERROR(vou->dev, "failed to enable pixclk: %d\n", ret);
}
-static void zx_crtc_disable(struct drm_crtc *crtc)
+static void zx_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct zx_crtc *zcrtc = to_zx_crtc(crtc);
const struct zx_crtc_bits *bits = zcrtc->bits;
@@ -490,9 +492,9 @@ static void zx_crtc_atomic_flush(struct drm_crtc *crtc,
}
static const struct drm_crtc_helper_funcs zx_crtc_helper_funcs = {
- .enable = zx_crtc_enable,
- .disable = zx_crtc_disable,
.atomic_flush = zx_crtc_atomic_flush,
+ .atomic_enable = zx_crtc_atomic_enable,
+ .atomic_disable = zx_crtc_atomic_disable,
};
static int zx_vou_enable_vblank(struct drm_crtc *crtc)
diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c
index a048e3a..f9cde03 100644
--- a/drivers/gpu/host1x/bus.c
+++ b/drivers/gpu/host1x/bus.c
@@ -41,13 +41,15 @@ struct host1x_subdev {
/**
* host1x_subdev_add() - add a new subdevice with an associated device node
* @device: host1x device to add the subdevice to
- * @driver: host1x driver
* @np: device node
*/
static int host1x_subdev_add(struct host1x_device *device,
+ struct host1x_driver *driver,
struct device_node *np)
{
struct host1x_subdev *subdev;
+ struct device_node *child;
+ int err;
subdev = kzalloc(sizeof(*subdev), GFP_KERNEL);
if (!subdev)
@@ -60,6 +62,19 @@ static int host1x_subdev_add(struct host1x_device *device,
list_add_tail(&subdev->list, &device->subdevs);
mutex_unlock(&device->subdevs_lock);
+ /* recursively add children */
+ for_each_child_of_node(np, child) {
+ if (of_match_node(driver->subdevs, child) &&
+ of_device_is_available(child)) {
+ err = host1x_subdev_add(device, driver, child);
+ if (err < 0) {
+ /* XXX cleanup? */
+ of_node_put(child);
+ return err;
+ }
+ }
+ }
+
return 0;
}
@@ -88,7 +103,7 @@ static int host1x_device_parse_dt(struct host1x_device *device,
for_each_child_of_node(device->dev.parent->of_node, np) {
if (of_match_node(driver->subdevs, np) &&
of_device_is_available(np)) {
- err = host1x_subdev_add(device, np);
+ err = host1x_subdev_add(device, driver, np);
if (err < 0) {
of_node_put(np);
return err;
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 7782725..7f22c5c 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -134,8 +134,8 @@ static int host1x_probe(struct platform_device *pdev)
syncpt_irq = platform_get_irq(pdev, 0);
if (syncpt_irq < 0) {
- dev_err(&pdev->dev, "failed to get IRQ\n");
- return -ENXIO;
+ dev_err(&pdev->dev, "failed to get IRQ: %d\n", syncpt_irq);
+ return syncpt_irq;
}
host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
diff --git a/drivers/gpu/host1x/hw/intr_hw.c b/drivers/gpu/host1x/hw/intr_hw.c
index dacb800..37ebb51 100644
--- a/drivers/gpu/host1x/hw/intr_hw.c
+++ b/drivers/gpu/host1x/hw/intr_hw.c
@@ -33,10 +33,10 @@ static void host1x_intr_syncpt_handle(struct host1x_syncpt *syncpt)
unsigned int id = syncpt->id;
struct host1x *host = syncpt->host;
- host1x_sync_writel(host, BIT_MASK(id),
- HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(BIT_WORD(id)));
- host1x_sync_writel(host, BIT_MASK(id),
- HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(BIT_WORD(id)));
+ host1x_sync_writel(host, BIT(id % 32),
+ HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(id / 32));
+ host1x_sync_writel(host, BIT(id % 32),
+ HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(id / 32));
schedule_work(&syncpt->intr.work);
}
@@ -50,9 +50,9 @@ static irqreturn_t syncpt_thresh_isr(int irq, void *dev_id)
for (i = 0; i < DIV_ROUND_UP(host->info->nb_pts, 32); i++) {
reg = host1x_sync_readl(host,
HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(i));
- for_each_set_bit(id, &reg, BITS_PER_LONG) {
+ for_each_set_bit(id, &reg, 32) {
struct host1x_syncpt *syncpt =
- host->syncpt + (i * BITS_PER_LONG + id);
+ host->syncpt + (i * 32 + id);
host1x_intr_syncpt_handle(syncpt);
}
}
@@ -117,17 +117,17 @@ static void _host1x_intr_set_syncpt_threshold(struct host1x *host,
static void _host1x_intr_enable_syncpt_intr(struct host1x *host,
unsigned int id)
{
- host1x_sync_writel(host, BIT_MASK(id),
- HOST1X_SYNC_SYNCPT_THRESH_INT_ENABLE_CPU0(BIT_WORD(id)));
+ host1x_sync_writel(host, BIT(id % 32),
+ HOST1X_SYNC_SYNCPT_THRESH_INT_ENABLE_CPU0(id / 32));
}
static void _host1x_intr_disable_syncpt_intr(struct host1x *host,
unsigned int id)
{
- host1x_sync_writel(host, BIT_MASK(id),
- HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(BIT_WORD(id)));
- host1x_sync_writel(host, BIT_MASK(id),
- HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(BIT_WORD(id)));
+ host1x_sync_writel(host, BIT(id % 32),
+ HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(id / 32));
+ host1x_sync_writel(host, BIT(id % 32),
+ HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(id / 32));
}
static int _host1x_free_syncpt_irq(struct host1x *host)
diff --git a/drivers/gpu/host1x/hw/syncpt_hw.c b/drivers/gpu/host1x/hw/syncpt_hw.c
index c93f74f..7b0270d 100644
--- a/drivers/gpu/host1x/hw/syncpt_hw.c
+++ b/drivers/gpu/host1x/hw/syncpt_hw.c
@@ -89,7 +89,7 @@ static int syncpt_cpu_incr(struct host1x_syncpt *sp)
host1x_syncpt_idle(sp))
return -EINVAL;
- host1x_sync_writel(host, BIT_MASK(sp->id),
+ host1x_sync_writel(host, BIT(sp->id % 32),
HOST1X_SYNC_SYNCPT_CPU_INCR(reg_offset));
wmb();
diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c
index bee5044..db509ab 100644
--- a/drivers/gpu/host1x/job.c
+++ b/drivers/gpu/host1x/job.c
@@ -197,10 +197,6 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
}
phys_addr = host1x_bo_pin(reloc->target.bo, &sgt);
- if (!phys_addr) {
- err = -EINVAL;
- goto unpin;
- }
job->addr_phys[job->num_unpins] = phys_addr;
job->unpins[job->num_unpins].bo = reloc->target.bo;
@@ -225,10 +221,6 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
}
phys_addr = host1x_bo_pin(g->bo, &sgt);
- if (!phys_addr) {
- err = -EINVAL;
- goto unpin;
- }
if (!IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL) && host->domain) {
for_each_sg(sgt->sgl, sg, sgt->nents, j)
diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c
index 960d816..6a573d2 100644
--- a/drivers/gpu/ipu-v3/ipu-common.c
+++ b/drivers/gpu/ipu-v3/ipu-common.c
@@ -1217,8 +1217,8 @@ static int ipu_add_client_devices(struct ipu_soc *ipu, unsigned long ipu_base)
of_node = of_graph_get_port_by_id(dev->of_node, i);
if (!of_node) {
dev_info(dev,
- "no port@%d node in %s, not using %s%d\n",
- i, dev->of_node->full_name,
+ "no port@%d node in %pOF, not using %s%d\n",
+ i, dev->of_node,
(i / 2) ? "DI" : "CSI", i % 2);
continue;
}
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 5ef2814..d654314 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -343,6 +343,7 @@ config SENSORS_ASB100
config SENSORS_ASPEED
tristate "ASPEED AST2400/AST2500 PWM and Fan tach driver"
+ depends on THERMAL || THERMAL=n
select REGMAP
help
This driver provides support for ASPEED AST2400/AST2500 PWM
@@ -790,6 +791,13 @@ config SENSORS_LTC4261
This driver can also be built as a module. If so, the module will
be called ltc4261.
+config SENSORS_LTQ_CPUTEMP
+ bool "Lantiq cpu temperature sensor driver"
+ depends on LANTIQ
+ help
+ If you say yes here you get support for the temperature
+ sensor inside your CPU.
+
config SENSORS_MAX1111
tristate "Maxim MAX1111 Serial 8-bit ADC chip and compatibles"
depends on SPI_MASTER
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index d4641a9..c84d978 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -110,6 +110,7 @@ obj-$(CONFIG_SENSORS_LTC4222) += ltc4222.o
obj-$(CONFIG_SENSORS_LTC4245) += ltc4245.o
obj-$(CONFIG_SENSORS_LTC4260) += ltc4260.o
obj-$(CONFIG_SENSORS_LTC4261) += ltc4261.o
+obj-$(CONFIG_SENSORS_LTQ_CPUTEMP) += ltq-cputemp.o
obj-$(CONFIG_SENSORS_MAX1111) += max1111.o
obj-$(CONFIG_SENSORS_MAX16065) += max16065.o
obj-$(CONFIG_SENSORS_MAX1619) += max1619.o
diff --git a/drivers/hwmon/adc128d818.c b/drivers/hwmon/adc128d818.c
index a557b46..bd2ca31 100644
--- a/drivers/hwmon/adc128d818.c
+++ b/drivers/hwmon/adc128d818.c
@@ -384,7 +384,7 @@ static struct attribute *adc128_attrs[] = {
NULL
};
-static struct attribute_group adc128_group = {
+static const struct attribute_group adc128_group = {
.attrs = adc128_attrs,
.is_visible = adc128_is_visible,
};
diff --git a/drivers/hwmon/ads1015.c b/drivers/hwmon/ads1015.c
index 357b426..98c704d 100644
--- a/drivers/hwmon/ads1015.c
+++ b/drivers/hwmon/ads1015.c
@@ -191,24 +191,23 @@ static int ads1015_get_channels_config_of(struct i2c_client *client)
unsigned int data_rate = ADS1015_DEFAULT_DATA_RATE;
if (of_property_read_u32(node, "reg", &pval)) {
- dev_err(&client->dev, "invalid reg on %s\n",
- node->full_name);
+ dev_err(&client->dev, "invalid reg on %pOF\n", node);
continue;
}
channel = pval;
if (channel >= ADS1015_CHANNELS) {
dev_err(&client->dev,
- "invalid channel index %d on %s\n",
- channel, node->full_name);
+ "invalid channel index %d on %pOF\n",
+ channel, node);
continue;
}
if (!of_property_read_u32(node, "ti,gain", &pval)) {
pga = pval;
if (pga > 6) {
- dev_err(&client->dev, "invalid gain on %s\n",
- node->full_name);
+ dev_err(&client->dev, "invalid gain on %pOF\n",
+ node);
return -EINVAL;
}
}
@@ -217,8 +216,7 @@ static int ads1015_get_channels_config_of(struct i2c_client *client)
data_rate = pval;
if (data_rate > 7) {
dev_err(&client->dev,
- "invalid data_rate on %s\n",
- node->full_name);
+ "invalid data_rate on %pOF\n", node);
return -EINVAL;
}
}
diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c
index 1baa213..9ef8499 100644
--- a/drivers/hwmon/adt7475.c
+++ b/drivers/hwmon/adt7475.c
@@ -1319,14 +1319,14 @@ static struct attribute *vid_attrs[] = {
NULL
};
-static struct attribute_group adt7475_attr_group = { .attrs = adt7475_attrs };
-static struct attribute_group fan4_attr_group = { .attrs = fan4_attrs };
-static struct attribute_group pwm2_attr_group = { .attrs = pwm2_attrs };
-static struct attribute_group in0_attr_group = { .attrs = in0_attrs };
-static struct attribute_group in3_attr_group = { .attrs = in3_attrs };
-static struct attribute_group in4_attr_group = { .attrs = in4_attrs };
-static struct attribute_group in5_attr_group = { .attrs = in5_attrs };
-static struct attribute_group vid_attr_group = { .attrs = vid_attrs };
+static const struct attribute_group adt7475_attr_group = { .attrs = adt7475_attrs };
+static const struct attribute_group fan4_attr_group = { .attrs = fan4_attrs };
+static const struct attribute_group pwm2_attr_group = { .attrs = pwm2_attrs };
+static const struct attribute_group in0_attr_group = { .attrs = in0_attrs };
+static const struct attribute_group in3_attr_group = { .attrs = in3_attrs };
+static const struct attribute_group in4_attr_group = { .attrs = in4_attrs };
+static const struct attribute_group in5_attr_group = { .attrs = in5_attrs };
+static const struct attribute_group vid_attr_group = { .attrs = vid_attrs };
static int adt7475_detect(struct i2c_client *client,
struct i2c_board_info *info)
diff --git a/drivers/hwmon/asc7621.c b/drivers/hwmon/asc7621.c
index c77644d..4875e99 100644
--- a/drivers/hwmon/asc7621.c
+++ b/drivers/hwmon/asc7621.c
@@ -512,7 +512,7 @@ static ssize_t show_pwm_ac(struct device *dev,
{
SETUP_SHOW_DATA_PARAM(dev, attr);
u8 config, altbit, regval;
- const u8 map[] = {
+ static const u8 map[] = {
0x01, 0x02, 0x04, 0x1f, 0x00, 0x06, 0x07, 0x10,
0x08, 0x0f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f
};
@@ -533,7 +533,7 @@ static ssize_t store_pwm_ac(struct device *dev,
SETUP_STORE_DATA_PARAM(dev, attr);
unsigned long reqval;
u8 currval, config, altbit, newval;
- const u16 map[] = {
+ static const u16 map[] = {
0x04, 0x00, 0x01, 0xff, 0x02, 0xff, 0x05, 0x06,
0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
diff --git a/drivers/hwmon/aspeed-pwm-tacho.c b/drivers/hwmon/aspeed-pwm-tacho.c
index ddfe66b..69b97d4 100644
--- a/drivers/hwmon/aspeed-pwm-tacho.c
+++ b/drivers/hwmon/aspeed-pwm-tacho.c
@@ -20,6 +20,7 @@
#include <linux/platform_device.h>
#include <linux/sysfs.h>
#include <linux/regmap.h>
+#include <linux/thermal.h>
/* ASPEED PWM & FAN Tach Register Definition */
#define ASPEED_PTCR_CTRL 0x00
@@ -166,6 +167,18 @@
/* How long we sleep in us while waiting for an RPM result. */
#define ASPEED_RPM_STATUS_SLEEP_USEC 500
+#define MAX_CDEV_NAME_LEN 16
+
+struct aspeed_cooling_device {
+ char name[16];
+ struct aspeed_pwm_tacho_data *priv;
+ struct thermal_cooling_device *tcdev;
+ int pwm_port;
+ u8 *cooling_levels;
+ u8 max_state;
+ u8 cur_state;
+};
+
struct aspeed_pwm_tacho_data {
struct regmap *regmap;
unsigned long clk_freq;
@@ -180,6 +193,7 @@ struct aspeed_pwm_tacho_data {
u8 pwm_port_type[8];
u8 pwm_port_fan_ctrl[8];
u8 fan_tach_ch_source[16];
+ struct aspeed_cooling_device *cdev[8];
const struct attribute_group *groups[3];
};
@@ -765,6 +779,94 @@ static void aspeed_create_fan_tach_channel(struct aspeed_pwm_tacho_data *priv,
}
}
+static int
+aspeed_pwm_cz_get_max_state(struct thermal_cooling_device *tcdev,
+ unsigned long *state)
+{
+ struct aspeed_cooling_device *cdev = tcdev->devdata;
+
+ *state = cdev->max_state;
+
+ return 0;
+}
+
+static int
+aspeed_pwm_cz_get_cur_state(struct thermal_cooling_device *tcdev,
+ unsigned long *state)
+{
+ struct aspeed_cooling_device *cdev = tcdev->devdata;
+
+ *state = cdev->cur_state;
+
+ return 0;
+}
+
+static int
+aspeed_pwm_cz_set_cur_state(struct thermal_cooling_device *tcdev,
+ unsigned long state)
+{
+ struct aspeed_cooling_device *cdev = tcdev->devdata;
+
+ if (state > cdev->max_state)
+ return -EINVAL;
+
+ cdev->cur_state = state;
+ cdev->priv->pwm_port_fan_ctrl[cdev->pwm_port] =
+ cdev->cooling_levels[cdev->cur_state];
+ aspeed_set_pwm_port_fan_ctrl(cdev->priv, cdev->pwm_port,
+ cdev->cooling_levels[cdev->cur_state]);
+
+ return 0;
+}
+
+static const struct thermal_cooling_device_ops aspeed_pwm_cool_ops = {
+ .get_max_state = aspeed_pwm_cz_get_max_state,
+ .get_cur_state = aspeed_pwm_cz_get_cur_state,
+ .set_cur_state = aspeed_pwm_cz_set_cur_state,
+};
+
+static int aspeed_create_pwm_cooling(struct device *dev,
+ struct device_node *child,
+ struct aspeed_pwm_tacho_data *priv,
+ u32 pwm_port, u8 num_levels)
+{
+ int ret;
+ struct aspeed_cooling_device *cdev;
+
+ cdev = devm_kzalloc(dev, sizeof(*cdev), GFP_KERNEL);
+
+ if (!cdev)
+ return -ENOMEM;
+
+ cdev->cooling_levels = devm_kzalloc(dev, num_levels, GFP_KERNEL);
+ if (!cdev->cooling_levels)
+ return -ENOMEM;
+
+ cdev->max_state = num_levels - 1;
+ ret = of_property_read_u8_array(child, "cooling-levels",
+ cdev->cooling_levels,
+ num_levels);
+ if (ret) {
+ dev_err(dev, "Property 'cooling-levels' cannot be read.\n");
+ return ret;
+ }
+ snprintf(cdev->name, MAX_CDEV_NAME_LEN, "%s%d", child->name, pwm_port);
+
+ cdev->tcdev = thermal_of_cooling_device_register(child,
+ cdev->name,
+ cdev,
+ &aspeed_pwm_cool_ops);
+ if (IS_ERR(cdev->tcdev))
+ return PTR_ERR(cdev->tcdev);
+
+ cdev->priv = priv;
+ cdev->pwm_port = pwm_port;
+
+ priv->cdev[pwm_port] = cdev;
+
+ return 0;
+}
+
static int aspeed_create_fan(struct device *dev,
struct device_node *child,
struct aspeed_pwm_tacho_data *priv)
@@ -778,6 +880,15 @@ static int aspeed_create_fan(struct device *dev,
return ret;
aspeed_create_pwm_port(priv, (u8)pwm_port);
+ ret = of_property_count_u8_elems(child, "cooling-levels");
+
+ if (ret > 0) {
+ ret = aspeed_create_pwm_cooling(dev, child, priv, pwm_port,
+ ret);
+ if (ret)
+ return ret;
+ }
+
count = of_property_count_u8_elems(child, "aspeed,fan-tach-ch");
if (count < 1)
return -EINVAL;
@@ -834,9 +945,10 @@ static int aspeed_pwm_tacho_probe(struct platform_device *pdev)
for_each_child_of_node(np, child) {
ret = aspeed_create_fan(dev, child, priv);
- of_node_put(child);
- if (ret)
+ if (ret) {
+ of_node_put(child);
return ret;
+ }
}
priv->groups[0] = &pwm_dev_group;
diff --git a/drivers/hwmon/da9052-hwmon.c b/drivers/hwmon/da9052-hwmon.c
index c9832bf..97a62f5 100644
--- a/drivers/hwmon/da9052-hwmon.c
+++ b/drivers/hwmon/da9052-hwmon.c
@@ -20,13 +20,19 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/mfd/da9052/da9052.h>
#include <linux/mfd/da9052/reg.h>
+#include <linux/regulator/consumer.h>
struct da9052_hwmon {
- struct da9052 *da9052;
- struct mutex hwmon_lock;
+ struct da9052 *da9052;
+ struct mutex hwmon_lock;
+ bool tsi_as_adc;
+ int tsiref_mv;
+ struct regulator *tsiref;
+ struct completion tsidone;
};
static const char * const input_names[] = {
@@ -37,6 +43,10 @@ static const char * const input_names[] = {
[DA9052_ADC_IN4] = "ADC IN4",
[DA9052_ADC_IN5] = "ADC IN5",
[DA9052_ADC_IN6] = "ADC IN6",
+ [DA9052_ADC_TSI_XP] = "ADC TS X+",
+ [DA9052_ADC_TSI_YP] = "ADC TS Y+",
+ [DA9052_ADC_TSI_XN] = "ADC TS X-",
+ [DA9052_ADC_TSI_YN] = "ADC TS Y-",
[DA9052_ADC_TJUNC] = "BATTERY JUNCTION TEMP",
[DA9052_ADC_VBBAT] = "BACK-UP BATTERY VOLTAGE",
};
@@ -59,6 +69,11 @@ static inline int vbbat_reg_to_mv(int value)
return DIV_ROUND_CLOSEST(value * 5000, 1023);
}
+static inline int input_tsireg_to_mv(struct da9052_hwmon *hwmon, int value)
+{
+ return DIV_ROUND_CLOSEST(value * hwmon->tsiref_mv, 1023);
+}
+
static inline int da9052_enable_vddout_channel(struct da9052 *da9052)
{
return da9052_reg_update(da9052, DA9052_ADC_CONT_REG,
@@ -154,6 +169,97 @@ static ssize_t da9052_read_misc_channel(struct device *dev,
return sprintf(buf, "%d\n", input_reg_to_mv(ret));
}
+static int da9052_request_tsi_read(struct da9052_hwmon *hwmon, int channel)
+{
+ u8 val = DA9052_TSICONTB_TSIMAN;
+
+ switch (channel) {
+ case DA9052_ADC_TSI_XP:
+ val |= DA9052_TSICONTB_TSIMUX_XP;
+ break;
+ case DA9052_ADC_TSI_YP:
+ val |= DA9052_TSICONTB_TSIMUX_YP;
+ break;
+ case DA9052_ADC_TSI_XN:
+ val |= DA9052_TSICONTB_TSIMUX_XN;
+ break;
+ case DA9052_ADC_TSI_YN:
+ val |= DA9052_TSICONTB_TSIMUX_YN;
+ break;
+ }
+
+ return da9052_reg_write(hwmon->da9052, DA9052_TSI_CONT_B_REG, val);
+}
+
+static int da9052_get_tsi_result(struct da9052_hwmon *hwmon, int channel)
+{
+ u8 regs[3];
+ int msb, lsb, err;
+
+ /* block read to avoid separation of MSB and LSB */
+ err = da9052_group_read(hwmon->da9052, DA9052_TSI_X_MSB_REG,
+ ARRAY_SIZE(regs), regs);
+ if (err)
+ return err;
+
+ switch (channel) {
+ case DA9052_ADC_TSI_XP:
+ case DA9052_ADC_TSI_XN:
+ msb = regs[0] << DA9052_TSILSB_TSIXL_BITS;
+ lsb = regs[2] & DA9052_TSILSB_TSIXL;
+ lsb >>= DA9052_TSILSB_TSIXL_SHIFT;
+ break;
+ case DA9052_ADC_TSI_YP:
+ case DA9052_ADC_TSI_YN:
+ msb = regs[1] << DA9052_TSILSB_TSIYL_BITS;
+ lsb = regs[2] & DA9052_TSILSB_TSIYL;
+ lsb >>= DA9052_TSILSB_TSIYL_SHIFT;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return msb | lsb;
+}
+
+
+static ssize_t __da9052_read_tsi(struct device *dev, int channel)
+{
+ struct da9052_hwmon *hwmon = dev_get_drvdata(dev);
+ int ret;
+
+ reinit_completion(&hwmon->tsidone);
+
+ ret = da9052_request_tsi_read(hwmon, channel);
+ if (ret < 0)
+ return ret;
+
+ /* Wait for an conversion done interrupt */
+ if (!wait_for_completion_timeout(&hwmon->tsidone,
+ msecs_to_jiffies(500)))
+ return -ETIMEDOUT;
+
+ return da9052_get_tsi_result(hwmon, channel);
+}
+
+static ssize_t da9052_read_tsi(struct device *dev,
+ struct device_attribute *devattr,
+ char *buf)
+{
+ struct da9052_hwmon *hwmon = dev_get_drvdata(dev);
+ int channel = to_sensor_dev_attr(devattr)->index;
+ int ret;
+
+ mutex_lock(&hwmon->hwmon_lock);
+ ret = __da9052_read_tsi(dev, channel);
+ mutex_unlock(&hwmon->hwmon_lock);
+
+ if (ret < 0)
+ return ret;
+ else
+ return sprintf(buf, "%d\n", input_tsireg_to_mv(hwmon, ret));
+}
+
static ssize_t da9052_read_tjunc(struct device *dev,
struct device_attribute *devattr, char *buf)
{
@@ -196,43 +302,82 @@ static ssize_t show_label(struct device *dev,
input_names[to_sensor_dev_attr(devattr)->index]);
}
-static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, da9052_read_vddout, NULL,
+static umode_t da9052_channel_is_visible(struct kobject *kobj,
+ struct attribute *attr, int index)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct da9052_hwmon *hwmon = dev_get_drvdata(dev);
+ struct device_attribute *dattr = container_of(attr,
+ struct device_attribute, attr);
+ struct sensor_device_attribute *sattr = to_sensor_dev_attr(dattr);
+
+ if (!hwmon->tsi_as_adc) {
+ switch (sattr->index) {
+ case DA9052_ADC_TSI_XP:
+ case DA9052_ADC_TSI_YP:
+ case DA9052_ADC_TSI_XN:
+ case DA9052_ADC_TSI_YN:
+ return 0;
+ }
+ }
+
+ return attr->mode;
+}
+
+static SENSOR_DEVICE_ATTR(in0_input, 0444, da9052_read_vddout, NULL,
DA9052_ADC_VDDOUT);
-static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO, show_label, NULL,
+static SENSOR_DEVICE_ATTR(in0_label, 0444, show_label, NULL,
DA9052_ADC_VDDOUT);
-static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, da9052_read_vbat, NULL,
+static SENSOR_DEVICE_ATTR(in3_input, 0444, da9052_read_vbat, NULL,
DA9052_ADC_VBAT);
-static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL,
+static SENSOR_DEVICE_ATTR(in3_label, 0444, show_label, NULL,
DA9052_ADC_VBAT);
-static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, da9052_read_misc_channel, NULL,
+static SENSOR_DEVICE_ATTR(in4_input, 0444, da9052_read_misc_channel, NULL,
DA9052_ADC_IN4);
-static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO, show_label, NULL,
+static SENSOR_DEVICE_ATTR(in4_label, 0444, show_label, NULL,
DA9052_ADC_IN4);
-static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, da9052_read_misc_channel, NULL,
+static SENSOR_DEVICE_ATTR(in5_input, 0444, da9052_read_misc_channel, NULL,
DA9052_ADC_IN5);
-static SENSOR_DEVICE_ATTR(in5_label, S_IRUGO, show_label, NULL,
+static SENSOR_DEVICE_ATTR(in5_label, 0444, show_label, NULL,
DA9052_ADC_IN5);
-static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, da9052_read_misc_channel, NULL,
+static SENSOR_DEVICE_ATTR(in6_input, 0444, da9052_read_misc_channel, NULL,
DA9052_ADC_IN6);
-static SENSOR_DEVICE_ATTR(in6_label, S_IRUGO, show_label, NULL,
+static SENSOR_DEVICE_ATTR(in6_label, 0444, show_label, NULL,
DA9052_ADC_IN6);
-static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, da9052_read_vbbat, NULL,
+static SENSOR_DEVICE_ATTR(in9_input, 0444, da9052_read_vbbat, NULL,
DA9052_ADC_VBBAT);
-static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_label, NULL,
+static SENSOR_DEVICE_ATTR(in9_label, 0444, show_label, NULL,
DA9052_ADC_VBBAT);
-static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, da9052_read_ich, NULL,
+static SENSOR_DEVICE_ATTR(in70_input, 0444, da9052_read_tsi, NULL,
+ DA9052_ADC_TSI_XP);
+static SENSOR_DEVICE_ATTR(in70_label, 0444, show_label, NULL,
+ DA9052_ADC_TSI_XP);
+static SENSOR_DEVICE_ATTR(in71_input, 0444, da9052_read_tsi, NULL,
+ DA9052_ADC_TSI_XN);
+static SENSOR_DEVICE_ATTR(in71_label, 0444, show_label, NULL,
+ DA9052_ADC_TSI_XN);
+static SENSOR_DEVICE_ATTR(in72_input, 0444, da9052_read_tsi, NULL,
+ DA9052_ADC_TSI_YP);
+static SENSOR_DEVICE_ATTR(in72_label, 0444, show_label, NULL,
+ DA9052_ADC_TSI_YP);
+static SENSOR_DEVICE_ATTR(in73_input, 0444, da9052_read_tsi, NULL,
+ DA9052_ADC_TSI_YN);
+static SENSOR_DEVICE_ATTR(in73_label, 0444, show_label, NULL,
+ DA9052_ADC_TSI_YN);
+
+static SENSOR_DEVICE_ATTR(curr1_input, 0444, da9052_read_ich, NULL,
DA9052_ADC_ICH);
-static SENSOR_DEVICE_ATTR(curr1_label, S_IRUGO, show_label, NULL,
+static SENSOR_DEVICE_ATTR(curr1_label, 0444, show_label, NULL,
DA9052_ADC_ICH);
-static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, da9052_read_tbat, NULL,
+static SENSOR_DEVICE_ATTR(temp2_input, 0444, da9052_read_tbat, NULL,
DA9052_ADC_TBAT);
-static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, show_label, NULL,
+static SENSOR_DEVICE_ATTR(temp2_label, 0444, show_label, NULL,
DA9052_ADC_TBAT);
-static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, da9052_read_tjunc, NULL,
+static SENSOR_DEVICE_ATTR(temp8_input, 0444, da9052_read_tjunc, NULL,
DA9052_ADC_TJUNC);
-static SENSOR_DEVICE_ATTR(temp8_label, S_IRUGO, show_label, NULL,
+static SENSOR_DEVICE_ATTR(temp8_label, 0444, show_label, NULL,
DA9052_ADC_TJUNC);
static struct attribute *da9052_attrs[] = {
@@ -246,6 +391,14 @@ static struct attribute *da9052_attrs[] = {
&sensor_dev_attr_in5_label.dev_attr.attr,
&sensor_dev_attr_in6_input.dev_attr.attr,
&sensor_dev_attr_in6_label.dev_attr.attr,
+ &sensor_dev_attr_in70_input.dev_attr.attr,
+ &sensor_dev_attr_in70_label.dev_attr.attr,
+ &sensor_dev_attr_in71_input.dev_attr.attr,
+ &sensor_dev_attr_in71_label.dev_attr.attr,
+ &sensor_dev_attr_in72_input.dev_attr.attr,
+ &sensor_dev_attr_in72_label.dev_attr.attr,
+ &sensor_dev_attr_in73_input.dev_attr.attr,
+ &sensor_dev_attr_in73_label.dev_attr.attr,
&sensor_dev_attr_in9_input.dev_attr.attr,
&sensor_dev_attr_in9_label.dev_attr.attr,
&sensor_dev_attr_curr1_input.dev_attr.attr,
@@ -257,29 +410,117 @@ static struct attribute *da9052_attrs[] = {
NULL
};
-ATTRIBUTE_GROUPS(da9052);
+static const struct attribute_group da9052_group = {
+ .attrs = da9052_attrs,
+ .is_visible = da9052_channel_is_visible,
+};
+__ATTRIBUTE_GROUPS(da9052);
+
+static irqreturn_t da9052_tsi_datardy_irq(int irq, void *data)
+{
+ struct da9052_hwmon *hwmon = data;
+
+ complete(&hwmon->tsidone);
+ return IRQ_HANDLED;
+}
static int da9052_hwmon_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct da9052_hwmon *hwmon;
struct device *hwmon_dev;
+ int err;
hwmon = devm_kzalloc(dev, sizeof(struct da9052_hwmon), GFP_KERNEL);
if (!hwmon)
return -ENOMEM;
+ platform_set_drvdata(pdev, hwmon);
+
mutex_init(&hwmon->hwmon_lock);
hwmon->da9052 = dev_get_drvdata(pdev->dev.parent);
+ init_completion(&hwmon->tsidone);
+
+ hwmon->tsi_as_adc =
+ device_property_read_bool(pdev->dev.parent, "dlg,tsi-as-adc");
+
+ if (hwmon->tsi_as_adc) {
+ hwmon->tsiref = devm_regulator_get(pdev->dev.parent, "tsiref");
+ if (IS_ERR(hwmon->tsiref)) {
+ err = PTR_ERR(hwmon->tsiref);
+ dev_err(&pdev->dev, "failed to get tsiref: %d", err);
+ return err;
+ }
+
+ err = regulator_enable(hwmon->tsiref);
+ if (err)
+ return err;
+
+ hwmon->tsiref_mv = regulator_get_voltage(hwmon->tsiref);
+ if (hwmon->tsiref_mv < 0) {
+ err = hwmon->tsiref_mv;
+ goto exit_regulator;
+ }
+
+ /* convert from microvolt (DT) to millivolt (hwmon) */
+ hwmon->tsiref_mv /= 1000;
+
+ /* TSIREF limits from datasheet */
+ if (hwmon->tsiref_mv < 1800 || hwmon->tsiref_mv > 2600) {
+ dev_err(hwmon->da9052->dev, "invalid TSIREF voltage: %d",
+ hwmon->tsiref_mv);
+ err = -ENXIO;
+ goto exit_regulator;
+ }
+
+ /* disable touchscreen features */
+ da9052_reg_write(hwmon->da9052, DA9052_TSI_CONT_A_REG, 0x00);
+
+ err = da9052_request_irq(hwmon->da9052, DA9052_IRQ_TSIREADY,
+ "tsiready-irq", da9052_tsi_datardy_irq,
+ hwmon);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to register TSIRDY IRQ: %d",
+ err);
+ goto exit_regulator;
+ }
+ }
+
hwmon_dev = devm_hwmon_device_register_with_groups(dev, "da9052",
hwmon,
da9052_groups);
- return PTR_ERR_OR_ZERO(hwmon_dev);
+ err = PTR_ERR_OR_ZERO(hwmon_dev);
+ if (err)
+ goto exit_irq;
+
+ return 0;
+
+exit_irq:
+ if (hwmon->tsi_as_adc)
+ da9052_free_irq(hwmon->da9052, DA9052_IRQ_TSIREADY, hwmon);
+exit_regulator:
+ if (hwmon->tsiref)
+ regulator_disable(hwmon->tsiref);
+
+ return err;
+}
+
+static int da9052_hwmon_remove(struct platform_device *pdev)
+{
+ struct da9052_hwmon *hwmon = platform_get_drvdata(pdev);
+
+ if (hwmon->tsi_as_adc) {
+ da9052_free_irq(hwmon->da9052, DA9052_IRQ_TSIREADY, hwmon);
+ regulator_disable(hwmon->tsiref);
+ }
+
+ return 0;
}
static struct platform_driver da9052_hwmon_driver = {
.probe = da9052_hwmon_probe,
+ .remove = da9052_hwmon_remove,
.driver = {
.name = "da9052-hwmon",
},
diff --git a/drivers/hwmon/ftsteutates.c b/drivers/hwmon/ftsteutates.c
index 0f0277e..0801f48 100644
--- a/drivers/hwmon/ftsteutates.c
+++ b/drivers/hwmon/ftsteutates.c
@@ -60,7 +60,7 @@
static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
-static struct i2c_device_id fts_id[] = {
+static const struct i2c_device_id fts_id[] = {
{ "ftsteutates", 0 },
{ }
};
@@ -435,6 +435,7 @@ clear_temp_alarm(struct device *dev, struct device_attribute *devattr,
goto error;
data->valid = false;
+ ret = count;
error:
mutex_unlock(&data->update_lock);
return ret;
@@ -508,6 +509,7 @@ clear_fan_alarm(struct device *dev, struct device_attribute *devattr,
goto error;
data->valid = false;
+ ret = count;
error:
mutex_unlock(&data->update_lock);
return ret;
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c
index dd6e17c..c9790e2 100644
--- a/drivers/hwmon/hwmon.c
+++ b/drivers/hwmon/hwmon.c
@@ -85,7 +85,7 @@ static umode_t hwmon_dev_name_is_visible(struct kobject *kobj,
return attr->mode;
}
-static struct attribute_group hwmon_dev_attr_group = {
+static const struct attribute_group hwmon_dev_attr_group = {
.attrs = hwmon_dev_attrs,
.is_visible = hwmon_dev_name_is_visible,
};
@@ -135,7 +135,7 @@ static int hwmon_thermal_get_temp(void *data, int *temp)
return 0;
}
-static struct thermal_zone_of_device_ops hwmon_thermal_ops = {
+static const struct thermal_zone_of_device_ops hwmon_thermal_ops = {
.get_temp = hwmon_thermal_get_temp,
};
diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c
index a5a9f45..9397d2f 100644
--- a/drivers/hwmon/i5k_amb.c
+++ b/drivers/hwmon/i5k_amb.c
@@ -495,7 +495,7 @@ static struct {
};
#ifdef MODULE
-static struct pci_device_id i5k_amb_ids[] = {
+static const struct pci_device_id i5k_amb_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5000_ERR) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5400_ERR) },
{ 0, }
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 4dfc723..f8499cb 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -497,12 +497,14 @@ static const struct it87_devices it87_devices[] = {
#define has_vin3_5v(data) ((data)->features & FEAT_VIN3_5V)
struct it87_sio_data {
+ int sioaddr;
enum chips type;
/* Values read from Super-I/O config space */
u8 revision;
u8 vid_value;
u8 beep_pin;
u8 internal; /* Internal sensors can be labeled */
+ bool need_in7_reroute;
/* Features skipped based on config or DMI */
u16 skip_in;
u8 skip_vid;
@@ -517,6 +519,7 @@ struct it87_sio_data {
*/
struct it87_data {
const struct attribute_group *groups[7];
+ int sioaddr;
enum chips type;
u32 features;
u8 peci_mask;
@@ -532,6 +535,7 @@ struct it87_data {
u16 in_internal; /* Bitfield, internal sensors (for labels) */
u16 has_in; /* Bitfield, voltage sensors enabled */
u8 in[NUM_VIN][3]; /* [nr][0]=in, [1]=min, [2]=max */
+ bool need_in7_reroute;
u8 has_fan; /* Bitfield, fans enabled */
u16 fan[NUM_FAN][2]; /* Register values, [nr][0]=fan, [1]=min */
u8 has_temp; /* Bitfield, temp sensors enabled */
@@ -2487,6 +2491,7 @@ static int __init it87_find(int sioaddr, unsigned short *address,
}
err = 0;
+ sio_data->sioaddr = sioaddr;
sio_data->revision = superio_inb(sioaddr, DEVREV) & 0x0f;
pr_info("Found IT%04x%s chip at 0x%x, revision %d\n", chip_type,
it87_devices[sio_data->type].suffix,
@@ -2575,6 +2580,7 @@ static int __init it87_find(int sioaddr, unsigned short *address,
reg2c |= BIT(1);
superio_outb(sioaddr, IT87_SIO_PINX2_REG,
reg2c);
+ sio_data->need_in7_reroute = true;
pr_notice("Routing internal VCCH5V to in7.\n");
}
pr_notice("in7 routed to internal voltage divider, with external pin disabled.\n");
@@ -2761,13 +2767,13 @@ static int __init it87_find(int sioaddr, unsigned short *address,
uart6 = sio_data->type == it8782 && (reg & BIT(2));
/*
- * The IT8720F has no VIN7 pin, so VCCH should always be
+ * The IT8720F has no VIN7 pin, so VCCH5V should always be
* routed internally to VIN7 with an internal divider.
* Curiously, there still is a configuration bit to control
* this, which means it can be set incorrectly. And even
* more curiously, many boards out there are improperly
* configured, even though the IT8720F datasheet claims
- * that the internal routing of VCCH to VIN7 is the default
+ * that the internal routing of VCCH5V to VIN7 is the default
* setting. So we force the internal routing in this case.
*
* On IT8782F, VIN7 is multiplexed with one of the UART6 pins.
@@ -2777,7 +2783,8 @@ static int __init it87_find(int sioaddr, unsigned short *address,
if ((sio_data->type == it8720 || uart6) && !(reg & BIT(1))) {
reg |= BIT(1);
superio_outb(sioaddr, IT87_SIO_PINX2_REG, reg);
- pr_notice("Routing internal VCCH to in7\n");
+ sio_data->need_in7_reroute = true;
+ pr_notice("Routing internal VCCH5V to in7\n");
}
if (reg & BIT(0))
sio_data->internal |= BIT(0);
@@ -2828,13 +2835,89 @@ exit:
return err;
}
+/*
+ * Some chips seem to have default value 0xff for all limit
+ * registers. For low voltage limits it makes no sense and triggers
+ * alarms, so change to 0 instead. For high temperature limits, it
+ * means -1 degree C, which surprisingly doesn't trigger an alarm,
+ * but is still confusing, so change to 127 degrees C.
+ */
+static void it87_check_limit_regs(struct it87_data *data)
+{
+ int i, reg;
+
+ for (i = 0; i < NUM_VIN_LIMIT; i++) {
+ reg = it87_read_value(data, IT87_REG_VIN_MIN(i));
+ if (reg == 0xff)
+ it87_write_value(data, IT87_REG_VIN_MIN(i), 0);
+ }
+ for (i = 0; i < NUM_TEMP_LIMIT; i++) {
+ reg = it87_read_value(data, IT87_REG_TEMP_HIGH(i));
+ if (reg == 0xff)
+ it87_write_value(data, IT87_REG_TEMP_HIGH(i), 127);
+ }
+}
+
+/* Check if voltage monitors are reset manually or by some reason */
+static void it87_check_voltage_monitors_reset(struct it87_data *data)
+{
+ int reg;
+
+ reg = it87_read_value(data, IT87_REG_VIN_ENABLE);
+ if ((reg & 0xff) == 0) {
+ /* Enable all voltage monitors */
+ it87_write_value(data, IT87_REG_VIN_ENABLE, 0xff);
+ }
+}
+
+/* Check if tachometers are reset manually or by some reason */
+static void it87_check_tachometers_reset(struct platform_device *pdev)
+{
+ struct it87_sio_data *sio_data = dev_get_platdata(&pdev->dev);
+ struct it87_data *data = platform_get_drvdata(pdev);
+ u8 mask, fan_main_ctrl;
+
+ mask = 0x70 & ~(sio_data->skip_fan << 4);
+ fan_main_ctrl = it87_read_value(data, IT87_REG_FAN_MAIN_CTRL);
+ if ((fan_main_ctrl & mask) == 0) {
+ /* Enable all fan tachometers */
+ fan_main_ctrl |= mask;
+ it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
+ fan_main_ctrl);
+ }
+}
+
+/* Set tachometers to 16-bit mode if needed */
+static void it87_check_tachometers_16bit_mode(struct platform_device *pdev)
+{
+ struct it87_data *data = platform_get_drvdata(pdev);
+ int reg;
+
+ if (!has_fan16_config(data))
+ return;
+
+ reg = it87_read_value(data, IT87_REG_FAN_16BIT);
+ if (~reg & 0x07 & data->has_fan) {
+ dev_dbg(&pdev->dev,
+ "Setting fan1-3 to 16-bit mode\n");
+ it87_write_value(data, IT87_REG_FAN_16BIT,
+ reg | 0x07);
+ }
+}
+
+static void it87_start_monitoring(struct it87_data *data)
+{
+ it87_write_value(data, IT87_REG_CONFIG,
+ (it87_read_value(data, IT87_REG_CONFIG) & 0x3e)
+ | (update_vbat ? 0x41 : 0x01));
+}
+
/* Called when we have found a new IT87. */
static void it87_init_device(struct platform_device *pdev)
{
struct it87_sio_data *sio_data = dev_get_platdata(&pdev->dev);
struct it87_data *data = platform_get_drvdata(pdev);
int tmp, i;
- u8 mask;
/*
* For each PWM channel:
@@ -2855,23 +2938,7 @@ static void it87_init_device(struct platform_device *pdev)
data->auto_pwm[i][3] = 0x7f; /* Full speed, hard-coded */
}
- /*
- * Some chips seem to have default value 0xff for all limit
- * registers. For low voltage limits it makes no sense and triggers
- * alarms, so change to 0 instead. For high temperature limits, it
- * means -1 degree C, which surprisingly doesn't trigger an alarm,
- * but is still confusing, so change to 127 degrees C.
- */
- for (i = 0; i < NUM_VIN_LIMIT; i++) {
- tmp = it87_read_value(data, IT87_REG_VIN_MIN(i));
- if (tmp == 0xff)
- it87_write_value(data, IT87_REG_VIN_MIN(i), 0);
- }
- for (i = 0; i < NUM_TEMP_LIMIT; i++) {
- tmp = it87_read_value(data, IT87_REG_TEMP_HIGH(i));
- if (tmp == 0xff)
- it87_write_value(data, IT87_REG_TEMP_HIGH(i), 127);
- }
+ it87_check_limit_regs(data);
/*
* Temperature channels are not forcibly enabled, as they can be
@@ -2880,38 +2947,19 @@ static void it87_init_device(struct platform_device *pdev)
* run-time through the temp{1-3}_type sysfs accessors if needed.
*/
- /* Check if voltage monitors are reset manually or by some reason */
- tmp = it87_read_value(data, IT87_REG_VIN_ENABLE);
- if ((tmp & 0xff) == 0) {
- /* Enable all voltage monitors */
- it87_write_value(data, IT87_REG_VIN_ENABLE, 0xff);
- }
+ it87_check_voltage_monitors_reset(data);
+
+ it87_check_tachometers_reset(pdev);
- /* Check if tachometers are reset manually or by some reason */
- mask = 0x70 & ~(sio_data->skip_fan << 4);
data->fan_main_ctrl = it87_read_value(data, IT87_REG_FAN_MAIN_CTRL);
- if ((data->fan_main_ctrl & mask) == 0) {
- /* Enable all fan tachometers */
- data->fan_main_ctrl |= mask;
- it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
- data->fan_main_ctrl);
- }
data->has_fan = (data->fan_main_ctrl >> 4) & 0x07;
- tmp = it87_read_value(data, IT87_REG_FAN_16BIT);
-
- /* Set tachometers to 16-bit mode if needed */
- if (has_fan16_config(data)) {
- if (~tmp & 0x07 & data->has_fan) {
- dev_dbg(&pdev->dev,
- "Setting fan1-3 to 16-bit mode\n");
- it87_write_value(data, IT87_REG_FAN_16BIT,
- tmp | 0x07);
- }
- }
+ it87_check_tachometers_16bit_mode(pdev);
/* Check for additional fans */
if (has_five_fans(data)) {
+ tmp = it87_read_value(data, IT87_REG_FAN_16BIT);
+
if (tmp & BIT(4))
data->has_fan |= BIT(3); /* fan4 enabled */
if (tmp & BIT(5))
@@ -2933,10 +2981,7 @@ static void it87_init_device(struct platform_device *pdev)
sio_data->skip_pwm |= BIT(5);
}
- /* Start monitoring */
- it87_write_value(data, IT87_REG_CONFIG,
- (it87_read_value(data, IT87_REG_CONFIG) & 0x3e)
- | (update_vbat ? 0x41 : 0x01));
+ it87_start_monitoring(data);
}
/* Return 1 if and only if the PWM interface is safe to use */
@@ -2986,8 +3031,6 @@ static int it87_check_pwm(struct device *dev)
"PWM configuration is too broken to be fixed\n");
}
- dev_info(dev,
- "Detected broken BIOS defaults, disabling PWM interface\n");
return 0;
} else if (fix_pwm_polarity) {
dev_info(dev,
@@ -3020,6 +3063,7 @@ static int it87_probe(struct platform_device *pdev)
return -ENOMEM;
data->addr = res->start;
+ data->sioaddr = sio_data->sioaddr;
data->type = sio_data->type;
data->features = it87_devices[sio_data->type].features;
data->peci_mask = it87_devices[sio_data->type].peci_mask;
@@ -3058,6 +3102,9 @@ static int it87_probe(struct platform_device *pdev)
/* Check PWM configuration */
enable_pwm_interface = it87_check_pwm(dev);
+ if (!enable_pwm_interface)
+ dev_info(dev,
+ "Detected broken BIOS defaults, disabling PWM interface\n");
/* Starting with IT8721F, we handle scaling of internal voltages */
if (has_12mv_adc(data)) {
@@ -3085,6 +3132,7 @@ static int it87_probe(struct platform_device *pdev)
}
data->in_internal = sio_data->internal;
+ data->need_in7_reroute = sio_data->need_in7_reroute;
data->has_in = 0x3ff & ~sio_data->skip_in;
if (has_six_temp(data)) {
@@ -3140,9 +3188,71 @@ static int it87_probe(struct platform_device *pdev)
return PTR_ERR_OR_ZERO(hwmon_dev);
}
+static void __maybe_unused it87_resume_sio(struct platform_device *pdev)
+{
+ struct it87_data *data = dev_get_drvdata(&pdev->dev);
+ int err;
+ int reg2c;
+
+ if (!data->need_in7_reroute)
+ return;
+
+ err = superio_enter(data->sioaddr);
+ if (err) {
+ dev_warn(&pdev->dev,
+ "Unable to enter Super I/O to reroute in7 (%d)",
+ err);
+ return;
+ }
+
+ superio_select(data->sioaddr, GPIO);
+
+ reg2c = superio_inb(data->sioaddr, IT87_SIO_PINX2_REG);
+ if (!(reg2c & BIT(1))) {
+ dev_dbg(&pdev->dev,
+ "Routing internal VCCH5V to in7 again");
+
+ reg2c |= BIT(1);
+ superio_outb(data->sioaddr, IT87_SIO_PINX2_REG,
+ reg2c);
+ }
+
+ superio_exit(data->sioaddr);
+}
+
+static int __maybe_unused it87_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct it87_data *data = dev_get_drvdata(dev);
+
+ it87_resume_sio(pdev);
+
+ mutex_lock(&data->update_lock);
+
+ it87_check_pwm(dev);
+ it87_check_limit_regs(data);
+ it87_check_voltage_monitors_reset(data);
+ it87_check_tachometers_reset(pdev);
+ it87_check_tachometers_16bit_mode(pdev);
+
+ it87_start_monitoring(data);
+
+ /* force update */
+ data->valid = 0;
+
+ mutex_unlock(&data->update_lock);
+
+ it87_update_device(dev);
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(it87_dev_pm_ops, NULL, it87_resume);
+
static struct platform_driver it87_driver = {
.driver = {
.name = DRVNAME,
+ .pm = &it87_dev_pm_ops,
},
.probe = it87_probe,
};
diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c
index 1bf22ef..5f11dc0 100644
--- a/drivers/hwmon/jc42.c
+++ b/drivers/hwmon/jc42.c
@@ -72,6 +72,8 @@ static const unsigned short normal_i2c[] = {
#define NXP_MANID 0x1131 /* NXP Semiconductors */
#define ONS_MANID 0x1b09 /* ON Semiconductor */
#define STM_MANID 0x104a /* ST Microelectronics */
+#define GT_MANID 0x1c68 /* Giantec */
+#define GT_MANID2 0x132d /* Giantec, 2nd mfg ID */
/* Supported chips */
@@ -86,6 +88,13 @@ static const unsigned short normal_i2c[] = {
#define AT30TSE004_DEVID 0x2200
#define AT30TSE004_DEVID_MASK 0xffff
+/* Giantec */
+#define GT30TS00_DEVID 0x2200
+#define GT30TS00_DEVID_MASK 0xff00
+
+#define GT34TS02_DEVID 0x3300
+#define GT34TS02_DEVID_MASK 0xff00
+
/* IDT */
#define TSE2004_DEVID 0x2200
#define TSE2004_DEVID_MASK 0xff00
@@ -130,6 +139,12 @@ static const unsigned short normal_i2c[] = {
#define CAT6095_DEVID 0x0800 /* Also matches CAT34TS02 */
#define CAT6095_DEVID_MASK 0xffe0
+#define CAT34TS02C_DEVID 0x0a00
+#define CAT34TS02C_DEVID_MASK 0xfff0
+
+#define CAT34TS04_DEVID 0x2200
+#define CAT34TS04_DEVID_MASK 0xfff0
+
/* ST Microelectronics */
#define STTS424_DEVID 0x0101
#define STTS424_DEVID_MASK 0xffff
@@ -158,6 +173,8 @@ static struct jc42_chips jc42_chips[] = {
{ ADT_MANID, ADT7408_DEVID, ADT7408_DEVID_MASK },
{ ATMEL_MANID, AT30TS00_DEVID, AT30TS00_DEVID_MASK },
{ ATMEL_MANID2, AT30TSE004_DEVID, AT30TSE004_DEVID_MASK },
+ { GT_MANID, GT30TS00_DEVID, GT30TS00_DEVID_MASK },
+ { GT_MANID2, GT34TS02_DEVID, GT34TS02_DEVID_MASK },
{ IDT_MANID, TSE2004_DEVID, TSE2004_DEVID_MASK },
{ IDT_MANID, TS3000_DEVID, TS3000_DEVID_MASK },
{ IDT_MANID, TS3001_DEVID, TS3001_DEVID_MASK },
@@ -170,6 +187,8 @@ static struct jc42_chips jc42_chips[] = {
{ MCP_MANID, MCP9843_DEVID, MCP9843_DEVID_MASK },
{ NXP_MANID, SE97_DEVID, SE97_DEVID_MASK },
{ ONS_MANID, CAT6095_DEVID, CAT6095_DEVID_MASK },
+ { ONS_MANID, CAT34TS02C_DEVID, CAT34TS02C_DEVID_MASK },
+ { ONS_MANID, CAT34TS04_DEVID, CAT34TS04_DEVID_MASK },
{ NXP_MANID, SE98_DEVID, SE98_DEVID_MASK },
{ STM_MANID, STTS424_DEVID, STTS424_DEVID_MASK },
{ STM_MANID, STTS424E_DEVID, STTS424E_DEVID_MASK },
diff --git a/drivers/hwmon/ltq-cputemp.c b/drivers/hwmon/ltq-cputemp.c
new file mode 100644
index 0000000..1d33f94
--- /dev/null
+++ b/drivers/hwmon/ltq-cputemp.c
@@ -0,0 +1,163 @@
+/* Lantiq cpu temperature sensor driver
+ *
+ * Copyright (C) 2017 Florian Eckert <fe@dev.tdt.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * 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
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>
+ */
+
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+
+#include <lantiq_soc.h>
+
+/* gphy1 configuration register contains cpu temperature */
+#define CGU_GPHY1_CR 0x0040
+#define CGU_TEMP_PD BIT(19)
+
+static void ltq_cputemp_enable(void)
+{
+ ltq_cgu_w32(ltq_cgu_r32(CGU_GPHY1_CR) | CGU_TEMP_PD, CGU_GPHY1_CR);
+}
+
+static void ltq_cputemp_disable(void *data)
+{
+ ltq_cgu_w32(ltq_cgu_r32(CGU_GPHY1_CR) & ~CGU_TEMP_PD, CGU_GPHY1_CR);
+}
+
+static int ltq_read(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel, long *temp)
+{
+ int value;
+
+ switch (attr) {
+ case hwmon_temp_input:
+ /* get the temperature including one decimal place */
+ value = (ltq_cgu_r32(CGU_GPHY1_CR) >> 9) & 0x01FF;
+ value = value * 5;
+ /* range -38 to +154 °C, register value zero is -38.0 °C */
+ value -= 380;
+ /* scale temp to millidegree */
+ value = value * 100;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ *temp = value;
+ return 0;
+}
+
+static umode_t ltq_is_visible(const void *_data, enum hwmon_sensor_types type,
+ u32 attr, int channel)
+{
+ if (type != hwmon_temp)
+ return 0;
+
+ switch (attr) {
+ case hwmon_temp_input:
+ return 0444;
+ default:
+ return 0;
+ }
+}
+
+static const u32 ltq_chip_config[] = {
+ HWMON_C_REGISTER_TZ,
+ 0
+};
+
+static const struct hwmon_channel_info ltq_chip = {
+ .type = hwmon_chip,
+ .config = ltq_chip_config,
+};
+
+static const u32 ltq_temp_config[] = {
+ HWMON_T_INPUT,
+ 0
+};
+
+static const struct hwmon_channel_info ltq_temp = {
+ .type = hwmon_temp,
+ .config = ltq_temp_config,
+};
+
+static const struct hwmon_channel_info *ltq_info[] = {
+ &ltq_chip,
+ &ltq_temp,
+ NULL
+};
+
+static const struct hwmon_ops ltq_hwmon_ops = {
+ .is_visible = ltq_is_visible,
+ .read = ltq_read,
+};
+
+static const struct hwmon_chip_info ltq_chip_info = {
+ .ops = &ltq_hwmon_ops,
+ .info = ltq_info,
+};
+
+static int ltq_cputemp_probe(struct platform_device *pdev)
+{
+ struct device *hwmon_dev;
+ int err = 0;
+
+ /* available on vr9 v1.2 SoCs only */
+ if (ltq_soc_type() != SOC_TYPE_VR9_2)
+ return -ENODEV;
+
+ err = devm_add_action(&pdev->dev, ltq_cputemp_disable, NULL);
+ if (err)
+ return err;
+
+ ltq_cputemp_enable();
+
+ hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev,
+ "ltq_cputemp",
+ NULL,
+ &ltq_chip_info,
+ NULL);
+
+ if (IS_ERR(hwmon_dev)) {
+ dev_err(&pdev->dev, "Failed to register as hwmon device");
+ return PTR_ERR(hwmon_dev);
+ }
+
+ return 0;
+}
+
+const struct of_device_id ltq_cputemp_match[] = {
+ { .compatible = "lantiq,cputemp" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ltq_cputemp_match);
+
+static struct platform_driver ltq_cputemp_driver = {
+ .probe = ltq_cputemp_probe,
+ .driver = {
+ .name = "ltq-cputemp",
+ .of_match_table = ltq_cputemp_match,
+ },
+};
+
+module_platform_driver(ltq_cputemp_driver);
+
+MODULE_AUTHOR("Florian Eckert <fe@dev.tdt.de>");
+MODULE_DESCRIPTION("Lantiq cpu temperature sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/nct7802.c b/drivers/hwmon/nct7802.c
index 12b94b0..2876c18 100644
--- a/drivers/hwmon/nct7802.c
+++ b/drivers/hwmon/nct7802.c
@@ -704,7 +704,7 @@ static umode_t nct7802_temp_is_visible(struct kobject *kobj,
return attr->mode;
}
-static struct attribute_group nct7802_temp_group = {
+static const struct attribute_group nct7802_temp_group = {
.attrs = nct7802_temp_attrs,
.is_visible = nct7802_temp_is_visible,
};
@@ -802,7 +802,7 @@ static umode_t nct7802_in_is_visible(struct kobject *kobj,
return attr->mode;
}
-static struct attribute_group nct7802_in_group = {
+static const struct attribute_group nct7802_in_group = {
.attrs = nct7802_in_attrs,
.is_visible = nct7802_in_is_visible,
};
@@ -880,7 +880,7 @@ static umode_t nct7802_fan_is_visible(struct kobject *kobj,
return attr->mode;
}
-static struct attribute_group nct7802_fan_group = {
+static const struct attribute_group nct7802_fan_group = {
.attrs = nct7802_fan_attrs,
.is_visible = nct7802_fan_is_visible,
};
@@ -898,7 +898,7 @@ static struct attribute *nct7802_pwm_attrs[] = {
NULL
};
-static struct attribute_group nct7802_pwm_group = {
+static const struct attribute_group nct7802_pwm_group = {
.attrs = nct7802_pwm_attrs,
};
@@ -1011,7 +1011,7 @@ static struct attribute *nct7802_auto_point_attrs[] = {
NULL
};
-static struct attribute_group nct7802_auto_point_group = {
+static const struct attribute_group nct7802_auto_point_group = {
.attrs = nct7802_auto_point_attrs,
};
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
index 68d717a..4001932 100644
--- a/drivers/hwmon/pmbus/Kconfig
+++ b/drivers/hwmon/pmbus/Kconfig
@@ -37,6 +37,15 @@ config SENSORS_ADM1275
This driver can also be built as a module. If so, the module will
be called adm1275.
+config SENSORS_IBM_CFFPS
+ tristate "IBM Common Form Factor Power Supply"
+ help
+ If you say yes here you get hardware monitoring support for the IBM
+ Common Form Factor power supply.
+
+ This driver can also be built as a module. If so, the module will
+ be called ibm-cffps.
+
config SENSORS_IR35221
tristate "Infineon IR35221"
default n
@@ -135,6 +144,15 @@ config SENSORS_TPS40422
This driver can also be built as a module. If so, the module will
be called tps40422.
+config SENSORS_TPS53679
+ tristate "TI TPS53679"
+ help
+ If you say yes here you get hardware monitoring support for TI
+ TPS53679.
+
+ This driver can also be built as a module. If so, the module will
+ be called tps53679.
+
config SENSORS_UCD9000
tristate "TI UCD90120, UCD90124, UCD90160, UCD9090, UCD90910"
default n
diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
index 75bb7ca..459a6be 100644
--- a/drivers/hwmon/pmbus/Makefile
+++ b/drivers/hwmon/pmbus/Makefile
@@ -5,6 +5,7 @@
obj-$(CONFIG_PMBUS) += pmbus_core.o
obj-$(CONFIG_SENSORS_PMBUS) += pmbus.o
obj-$(CONFIG_SENSORS_ADM1275) += adm1275.o
+obj-$(CONFIG_SENSORS_IBM_CFFPS) += ibm-cffps.o
obj-$(CONFIG_SENSORS_IR35221) += ir35221.o
obj-$(CONFIG_SENSORS_LM25066) += lm25066.o
obj-$(CONFIG_SENSORS_LTC2978) += ltc2978.o
@@ -14,6 +15,7 @@ obj-$(CONFIG_SENSORS_MAX20751) += max20751.o
obj-$(CONFIG_SENSORS_MAX34440) += max34440.o
obj-$(CONFIG_SENSORS_MAX8688) += max8688.o
obj-$(CONFIG_SENSORS_TPS40422) += tps40422.o
+obj-$(CONFIG_SENSORS_TPS53679) += tps53679.o
obj-$(CONFIG_SENSORS_UCD9000) += ucd9000.o
obj-$(CONFIG_SENSORS_UCD9200) += ucd9200.o
obj-$(CONFIG_SENSORS_ZL6100) += zl6100.o
diff --git a/drivers/hwmon/pmbus/ibm-cffps.c b/drivers/hwmon/pmbus/ibm-cffps.c
new file mode 100644
index 0000000..cb56da6
--- /dev/null
+++ b/drivers/hwmon/pmbus/ibm-cffps.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2017 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+
+#include "pmbus.h"
+
+/* STATUS_MFR_SPECIFIC bits */
+#define CFFPS_MFR_FAN_FAULT BIT(0)
+#define CFFPS_MFR_THERMAL_FAULT BIT(1)
+#define CFFPS_MFR_OV_FAULT BIT(2)
+#define CFFPS_MFR_UV_FAULT BIT(3)
+#define CFFPS_MFR_PS_KILL BIT(4)
+#define CFFPS_MFR_OC_FAULT BIT(5)
+#define CFFPS_MFR_VAUX_FAULT BIT(6)
+#define CFFPS_MFR_CURRENT_SHARE_WARNING BIT(7)
+
+static int ibm_cffps_read_byte_data(struct i2c_client *client, int page,
+ int reg)
+{
+ int rc, mfr;
+
+ switch (reg) {
+ case PMBUS_STATUS_VOUT:
+ case PMBUS_STATUS_IOUT:
+ case PMBUS_STATUS_TEMPERATURE:
+ case PMBUS_STATUS_FAN_12:
+ rc = pmbus_read_byte_data(client, page, reg);
+ if (rc < 0)
+ return rc;
+
+ mfr = pmbus_read_byte_data(client, page,
+ PMBUS_STATUS_MFR_SPECIFIC);
+ if (mfr < 0)
+ /*
+ * Return the status register instead of an error,
+ * since we successfully read status.
+ */
+ return rc;
+
+ /* Add MFR_SPECIFIC bits to the standard pmbus status regs. */
+ if (reg == PMBUS_STATUS_FAN_12) {
+ if (mfr & CFFPS_MFR_FAN_FAULT)
+ rc |= PB_FAN_FAN1_FAULT;
+ } else if (reg == PMBUS_STATUS_TEMPERATURE) {
+ if (mfr & CFFPS_MFR_THERMAL_FAULT)
+ rc |= PB_TEMP_OT_FAULT;
+ } else if (reg == PMBUS_STATUS_VOUT) {
+ if (mfr & (CFFPS_MFR_OV_FAULT | CFFPS_MFR_VAUX_FAULT))
+ rc |= PB_VOLTAGE_OV_FAULT;
+ if (mfr & CFFPS_MFR_UV_FAULT)
+ rc |= PB_VOLTAGE_UV_FAULT;
+ } else if (reg == PMBUS_STATUS_IOUT) {
+ if (mfr & CFFPS_MFR_OC_FAULT)
+ rc |= PB_IOUT_OC_FAULT;
+ if (mfr & CFFPS_MFR_CURRENT_SHARE_WARNING)
+ rc |= PB_CURRENT_SHARE_FAULT;
+ }
+ break;
+ default:
+ rc = -ENODATA;
+ break;
+ }
+
+ return rc;
+}
+
+static int ibm_cffps_read_word_data(struct i2c_client *client, int page,
+ int reg)
+{
+ int rc, mfr;
+
+ switch (reg) {
+ case PMBUS_STATUS_WORD:
+ rc = pmbus_read_word_data(client, page, reg);
+ if (rc < 0)
+ return rc;
+
+ mfr = pmbus_read_byte_data(client, page,
+ PMBUS_STATUS_MFR_SPECIFIC);
+ if (mfr < 0)
+ /*
+ * Return the status register instead of an error,
+ * since we successfully read status.
+ */
+ return rc;
+
+ if (mfr & CFFPS_MFR_PS_KILL)
+ rc |= PB_STATUS_OFF;
+ break;
+ default:
+ rc = -ENODATA;
+ break;
+ }
+
+ return rc;
+}
+
+static struct pmbus_driver_info ibm_cffps_info = {
+ .pages = 1,
+ .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT |
+ PMBUS_HAVE_PIN | PMBUS_HAVE_FAN12 | PMBUS_HAVE_TEMP |
+ PMBUS_HAVE_TEMP2 | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_VOUT |
+ PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_STATUS_INPUT |
+ PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_STATUS_FAN12,
+ .read_byte_data = ibm_cffps_read_byte_data,
+ .read_word_data = ibm_cffps_read_word_data,
+};
+
+static int ibm_cffps_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ return pmbus_do_probe(client, id, &ibm_cffps_info);
+}
+
+static const struct i2c_device_id ibm_cffps_id[] = {
+ { "ibm_cffps1", 1 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, ibm_cffps_id);
+
+static const struct of_device_id ibm_cffps_of_match[] = {
+ { .compatible = "ibm,cffps1" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, ibm_cffps_of_match);
+
+static struct i2c_driver ibm_cffps_driver = {
+ .driver = {
+ .name = "ibm-cffps",
+ .of_match_table = ibm_cffps_of_match,
+ },
+ .probe = ibm_cffps_probe,
+ .remove = pmbus_do_remove,
+ .id_table = ibm_cffps_id,
+};
+
+module_i2c_driver(ibm_cffps_driver);
+
+MODULE_AUTHOR("Eddie James");
+MODULE_DESCRIPTION("PMBus driver for IBM Common Form Factor power supplies");
+MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/pmbus/lm25066.c b/drivers/hwmon/pmbus/lm25066.c
index a3d912cd..10d17fb 100644
--- a/drivers/hwmon/pmbus/lm25066.c
+++ b/drivers/hwmon/pmbus/lm25066.c
@@ -28,7 +28,7 @@
#include <linux/i2c.h>
#include "pmbus.h"
-enum chips { lm25056, lm25063, lm25066, lm5064, lm5066 };
+enum chips { lm25056, lm25063, lm25066, lm5064, lm5066, lm5066i };
#define LM25066_READ_VAUX 0xd0
#define LM25066_MFR_READ_IIN 0xd1
@@ -65,7 +65,7 @@ struct __coeff {
#define PSC_CURRENT_IN_L (PSC_NUM_CLASSES)
#define PSC_POWER_L (PSC_NUM_CLASSES + 1)
-static struct __coeff lm25066_coeff[5][PSC_NUM_CLASSES + 2] = {
+static struct __coeff lm25066_coeff[6][PSC_NUM_CLASSES + 2] = {
[lm25056] = {
[PSC_VOLTAGE_IN] = {
.m = 16296,
@@ -210,6 +210,41 @@ static struct __coeff lm25066_coeff[5][PSC_NUM_CLASSES + 2] = {
.m = 16,
},
},
+ [lm5066i] = {
+ [PSC_VOLTAGE_IN] = {
+ .m = 4617,
+ .b = -140,
+ .R = -2,
+ },
+ [PSC_VOLTAGE_OUT] = {
+ .m = 4602,
+ .b = 500,
+ .R = -2,
+ },
+ [PSC_CURRENT_IN] = {
+ .m = 15076,
+ .b = -504,
+ .R = -2,
+ },
+ [PSC_CURRENT_IN_L] = {
+ .m = 7645,
+ .b = 100,
+ .R = -2,
+ },
+ [PSC_POWER] = {
+ .m = 1701,
+ .b = -4000,
+ .R = -3,
+ },
+ [PSC_POWER_L] = {
+ .m = 861,
+ .b = -965,
+ .R = -3,
+ },
+ [PSC_TEMPERATURE] = {
+ .m = 16,
+ },
+ },
};
struct lm25066_data {
@@ -250,6 +285,7 @@ static int lm25066_read_word_data(struct i2c_client *client, int page, int reg)
ret = DIV_ROUND_CLOSEST(ret * 70, 453);
break;
case lm5066:
+ case lm5066i:
/* VIN: 2.18 mV VAUX: 725 uV LSB */
ret = DIV_ROUND_CLOSEST(ret * 725, 2180);
break;
@@ -488,16 +524,18 @@ static int lm25066_probe(struct i2c_client *client,
info->m[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].m;
info->b[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].b;
info->R[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].R;
- info->b[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].b;
info->R[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].R;
- info->b[PSC_POWER] = coeff[PSC_POWER].b;
info->R[PSC_POWER] = coeff[PSC_POWER].R;
if (config & LM25066_DEV_SETUP_CL) {
info->m[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN_L].m;
+ info->b[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN_L].b;
info->m[PSC_POWER] = coeff[PSC_POWER_L].m;
+ info->b[PSC_POWER] = coeff[PSC_POWER_L].b;
} else {
info->m[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].m;
+ info->b[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].b;
info->m[PSC_POWER] = coeff[PSC_POWER].m;
+ info->b[PSC_POWER] = coeff[PSC_POWER].b;
}
return pmbus_do_probe(client, id, info);
@@ -509,6 +547,7 @@ static const struct i2c_device_id lm25066_id[] = {
{"lm25066", lm25066},
{"lm5064", lm5064},
{"lm5066", lm5066},
+ {"lm5066i", lm5066i},
{ }
};
diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h
index bfcb13b..4efa2bd 100644
--- a/drivers/hwmon/pmbus/pmbus.h
+++ b/drivers/hwmon/pmbus/pmbus.h
@@ -341,7 +341,7 @@ enum pmbus_sensor_classes {
#define PMBUS_HAVE_STATUS_VMON BIT(19)
enum pmbus_data_format { linear = 0, direct, vid };
-enum vrm_version { vr11 = 0, vr12 };
+enum vrm_version { vr11 = 0, vr12, vr13 };
struct pmbus_driver_info {
int pages; /* Total number of pages */
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index f1eff6b..302f0ae 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/debugfs.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -101,6 +102,7 @@ struct pmbus_data {
int num_attributes;
struct attribute_group group;
const struct attribute_group *groups[2];
+ struct dentry *debugfs; /* debugfs device directory */
struct pmbus_sensor *sensors;
@@ -112,12 +114,20 @@ struct pmbus_data {
* A single status register covers multiple attributes,
* so we keep them all together.
*/
- u8 status[PB_NUM_STATUS_REG];
- u8 status_register;
+ u16 status[PB_NUM_STATUS_REG];
+
+ bool has_status_word; /* device uses STATUS_WORD register */
+ int (*read_status)(struct i2c_client *client, int page);
u8 currpage;
};
+struct pmbus_debugfs_entry {
+ struct i2c_client *client;
+ u8 page;
+ u8 reg;
+};
+
void pmbus_clear_cache(struct i2c_client *client)
{
struct pmbus_data *data = i2c_get_clientdata(client);
@@ -324,7 +334,7 @@ static int pmbus_check_status_cml(struct i2c_client *client)
struct pmbus_data *data = i2c_get_clientdata(client);
int status, status2;
- status = _pmbus_read_byte_data(client, -1, data->status_register);
+ status = data->read_status(client, -1);
if (status < 0 || (status & PB_STATUS_CML)) {
status2 = _pmbus_read_byte_data(client, -1, PMBUS_STATUS_CML);
if (status2 < 0 || (status2 & PB_CML_FAULT_INVALID_COMMAND))
@@ -348,6 +358,23 @@ static bool pmbus_check_register(struct i2c_client *client,
return rv >= 0;
}
+static bool pmbus_check_status_register(struct i2c_client *client, int page)
+{
+ int status;
+ struct pmbus_data *data = i2c_get_clientdata(client);
+
+ status = data->read_status(client, page);
+ if (status >= 0 && !(data->flags & PMBUS_SKIP_STATUS_CHECK) &&
+ (status & PB_STATUS_CML)) {
+ status = _pmbus_read_byte_data(client, -1, PMBUS_STATUS_CML);
+ if (status < 0 || (status & PB_CML_FAULT_INVALID_COMMAND))
+ status = -EIO;
+ }
+
+ pmbus_clear_fault_page(client, -1);
+ return status >= 0;
+}
+
bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg)
{
return pmbus_check_register(client, _pmbus_read_byte_data, page, reg);
@@ -394,8 +421,7 @@ static struct pmbus_data *pmbus_update_device(struct device *dev)
for (i = 0; i < info->pages; i++) {
data->status[PB_STATUS_BASE + i]
- = _pmbus_read_byte_data(client, i,
- data->status_register);
+ = data->read_status(client, i);
for (j = 0; j < ARRAY_SIZE(pmbus_status); j++) {
struct _pmbus_status *s = &pmbus_status[j];
@@ -531,6 +557,10 @@ static long pmbus_reg2data_vid(struct pmbus_data *data,
if (val >= 0x01)
rv = 250 + (val - 1) * 5;
break;
+ case vr13:
+ if (val >= 0x01)
+ rv = 500 + (val - 1) * 10;
+ break;
}
return rv;
}
@@ -716,10 +746,10 @@ static int pmbus_get_boolean(struct pmbus_data *data, struct pmbus_boolean *b,
{
struct pmbus_sensor *s1 = b->s1;
struct pmbus_sensor *s2 = b->s2;
- u16 reg = (index >> 8) & 0xffff;
- u8 mask = index & 0xff;
+ u16 reg = (index >> 16) & 0xffff;
+ u16 mask = index & 0xffff;
int ret, status;
- u8 regval;
+ u16 regval;
status = data->status[reg];
if (status < 0)
@@ -860,7 +890,7 @@ static int pmbus_add_boolean(struct pmbus_data *data,
const char *name, const char *type, int seq,
struct pmbus_sensor *s1,
struct pmbus_sensor *s2,
- u16 reg, u8 mask)
+ u16 reg, u16 mask)
{
struct pmbus_boolean *boolean;
struct sensor_device_attribute *a;
@@ -876,7 +906,7 @@ static int pmbus_add_boolean(struct pmbus_data *data,
boolean->s1 = s1;
boolean->s2 = s2;
pmbus_attr_init(a, boolean->name, S_IRUGO, pmbus_show_boolean, NULL,
- (reg << 8) | mask);
+ (reg << 16) | mask);
return pmbus_add_attribute(data, &a->dev_attr.attr);
}
@@ -962,7 +992,7 @@ struct pmbus_limit_attr {
*/
struct pmbus_sensor_attr {
u16 reg; /* sensor register */
- u8 gbit; /* generic status bit */
+ u16 gbit; /* generic status bit */
u8 nlimit; /* # of limit registers */
enum pmbus_sensor_classes class;/* sensor class */
const char *label; /* sensor label */
@@ -1028,6 +1058,7 @@ static int pmbus_add_sensor_attrs_one(struct i2c_client *client,
const struct pmbus_sensor_attr *attr)
{
struct pmbus_sensor *base;
+ bool upper = !!(attr->gbit & 0xff00); /* need to check STATUS_WORD */
int ret;
if (attr->label) {
@@ -1048,11 +1079,12 @@ static int pmbus_add_sensor_attrs_one(struct i2c_client *client,
/*
* Add generic alarm attribute only if there are no individual
* alarm attributes, if there is a global alarm bit, and if
- * the generic status register for this page is accessible.
+ * the generic status register (word or byte, depending on
+ * which global bit is set) for this page is accessible.
*/
if (!ret && attr->gbit &&
- pmbus_check_byte_register(client, page,
- data->status_register)) {
+ (!upper || (upper && data->has_status_word)) &&
+ pmbus_check_status_register(client, page)) {
ret = pmbus_add_boolean(data, name, "alarm", index,
NULL, NULL,
PB_STATUS_BASE + page,
@@ -1308,6 +1340,7 @@ static const struct pmbus_sensor_attr current_attributes[] = {
.func = PMBUS_HAVE_IIN,
.sfunc = PMBUS_HAVE_STATUS_INPUT,
.sbase = PB_STATUS_INPUT_BASE,
+ .gbit = PB_STATUS_INPUT,
.limit = iin_limit_attrs,
.nlimit = ARRAY_SIZE(iin_limit_attrs),
}, {
@@ -1392,6 +1425,7 @@ static const struct pmbus_sensor_attr power_attributes[] = {
.func = PMBUS_HAVE_PIN,
.sfunc = PMBUS_HAVE_STATUS_INPUT,
.sbase = PB_STATUS_INPUT_BASE,
+ .gbit = PB_STATUS_INPUT,
.limit = pin_limit_attrs,
.nlimit = ARRAY_SIZE(pin_limit_attrs),
}, {
@@ -1729,6 +1763,16 @@ static int pmbus_identify_common(struct i2c_client *client,
return 0;
}
+static int pmbus_read_status_byte(struct i2c_client *client, int page)
+{
+ return _pmbus_read_byte_data(client, page, PMBUS_STATUS_BYTE);
+}
+
+static int pmbus_read_status_word(struct i2c_client *client, int page)
+{
+ return _pmbus_read_word_data(client, page, PMBUS_STATUS_WORD);
+}
+
static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data,
struct pmbus_driver_info *info)
{
@@ -1736,19 +1780,21 @@ static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data,
int page, ret;
/*
- * Some PMBus chips don't support PMBUS_STATUS_BYTE, so try
- * to use PMBUS_STATUS_WORD instead if that is the case.
+ * Some PMBus chips don't support PMBUS_STATUS_WORD, so try
+ * to use PMBUS_STATUS_BYTE instead if that is the case.
* Bail out if both registers are not supported.
*/
- data->status_register = PMBUS_STATUS_BYTE;
- ret = i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE);
- if (ret < 0 || ret == 0xff) {
- data->status_register = PMBUS_STATUS_WORD;
- ret = i2c_smbus_read_word_data(client, PMBUS_STATUS_WORD);
- if (ret < 0 || ret == 0xffff) {
+ data->read_status = pmbus_read_status_word;
+ ret = i2c_smbus_read_word_data(client, PMBUS_STATUS_WORD);
+ if (ret < 0 || ret == 0xffff) {
+ data->read_status = pmbus_read_status_byte;
+ ret = i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE);
+ if (ret < 0 || ret == 0xff) {
dev_err(dev, "PMBus status register not found\n");
return -ENODEV;
}
+ } else {
+ data->has_status_word = true;
}
/* Enable PEC if the controller supports it */
@@ -1859,6 +1905,184 @@ static int pmbus_regulator_register(struct pmbus_data *data)
}
#endif
+static struct dentry *pmbus_debugfs_dir; /* pmbus debugfs directory */
+
+#if IS_ENABLED(CONFIG_DEBUG_FS)
+static int pmbus_debugfs_get(void *data, u64 *val)
+{
+ int rc;
+ struct pmbus_debugfs_entry *entry = data;
+
+ rc = _pmbus_read_byte_data(entry->client, entry->page, entry->reg);
+ if (rc < 0)
+ return rc;
+
+ *val = rc;
+
+ return 0;
+}
+DEFINE_DEBUGFS_ATTRIBUTE(pmbus_debugfs_ops, pmbus_debugfs_get, NULL,
+ "0x%02llx\n");
+
+static int pmbus_debugfs_get_status(void *data, u64 *val)
+{
+ int rc;
+ struct pmbus_debugfs_entry *entry = data;
+ struct pmbus_data *pdata = i2c_get_clientdata(entry->client);
+
+ rc = pdata->read_status(entry->client, entry->page);
+ if (rc < 0)
+ return rc;
+
+ *val = rc;
+
+ return 0;
+}
+DEFINE_DEBUGFS_ATTRIBUTE(pmbus_debugfs_ops_status, pmbus_debugfs_get_status,
+ NULL, "0x%04llx\n");
+
+static int pmbus_init_debugfs(struct i2c_client *client,
+ struct pmbus_data *data)
+{
+ int i, idx = 0;
+ char name[PMBUS_NAME_SIZE];
+ struct pmbus_debugfs_entry *entries;
+
+ if (!pmbus_debugfs_dir)
+ return -ENODEV;
+
+ /*
+ * Create the debugfs directory for this device. Use the hwmon device
+ * name to avoid conflicts (hwmon numbers are globally unique).
+ */
+ data->debugfs = debugfs_create_dir(dev_name(data->hwmon_dev),
+ pmbus_debugfs_dir);
+ if (IS_ERR_OR_NULL(data->debugfs)) {
+ data->debugfs = NULL;
+ return -ENODEV;
+ }
+
+ /* Allocate the max possible entries we need. */
+ entries = devm_kzalloc(data->dev,
+ sizeof(*entries) * (data->info->pages * 10),
+ GFP_KERNEL);
+ if (!entries)
+ return -ENOMEM;
+
+ for (i = 0; i < data->info->pages; ++i) {
+ /* Check accessibility of status register if it's not page 0 */
+ if (!i || pmbus_check_status_register(client, i)) {
+ /* No need to set reg as we have special read op. */
+ entries[idx].client = client;
+ entries[idx].page = i;
+ scnprintf(name, PMBUS_NAME_SIZE, "status%d", i);
+ debugfs_create_file(name, 0444, data->debugfs,
+ &entries[idx++],
+ &pmbus_debugfs_ops_status);
+ }
+
+ if (data->info->func[i] & PMBUS_HAVE_STATUS_VOUT) {
+ entries[idx].client = client;
+ entries[idx].page = i;
+ entries[idx].reg = PMBUS_STATUS_VOUT;
+ scnprintf(name, PMBUS_NAME_SIZE, "status%d_vout", i);
+ debugfs_create_file(name, 0444, data->debugfs,
+ &entries[idx++],
+ &pmbus_debugfs_ops);
+ }
+
+ if (data->info->func[i] & PMBUS_HAVE_STATUS_IOUT) {
+ entries[idx].client = client;
+ entries[idx].page = i;
+ entries[idx].reg = PMBUS_STATUS_IOUT;
+ scnprintf(name, PMBUS_NAME_SIZE, "status%d_iout", i);
+ debugfs_create_file(name, 0444, data->debugfs,
+ &entries[idx++],
+ &pmbus_debugfs_ops);
+ }
+
+ if (data->info->func[i] & PMBUS_HAVE_STATUS_INPUT) {
+ entries[idx].client = client;
+ entries[idx].page = i;
+ entries[idx].reg = PMBUS_STATUS_INPUT;
+ scnprintf(name, PMBUS_NAME_SIZE, "status%d_input", i);
+ debugfs_create_file(name, 0444, data->debugfs,
+ &entries[idx++],
+ &pmbus_debugfs_ops);
+ }
+
+ if (data->info->func[i] & PMBUS_HAVE_STATUS_TEMP) {
+ entries[idx].client = client;
+ entries[idx].page = i;
+ entries[idx].reg = PMBUS_STATUS_TEMPERATURE;
+ scnprintf(name, PMBUS_NAME_SIZE, "status%d_temp", i);
+ debugfs_create_file(name, 0444, data->debugfs,
+ &entries[idx++],
+ &pmbus_debugfs_ops);
+ }
+
+ if (pmbus_check_byte_register(client, i, PMBUS_STATUS_CML)) {
+ entries[idx].client = client;
+ entries[idx].page = i;
+ entries[idx].reg = PMBUS_STATUS_CML;
+ scnprintf(name, PMBUS_NAME_SIZE, "status%d_cml", i);
+ debugfs_create_file(name, 0444, data->debugfs,
+ &entries[idx++],
+ &pmbus_debugfs_ops);
+ }
+
+ if (pmbus_check_byte_register(client, i, PMBUS_STATUS_OTHER)) {
+ entries[idx].client = client;
+ entries[idx].page = i;
+ entries[idx].reg = PMBUS_STATUS_OTHER;
+ scnprintf(name, PMBUS_NAME_SIZE, "status%d_other", i);
+ debugfs_create_file(name, 0444, data->debugfs,
+ &entries[idx++],
+ &pmbus_debugfs_ops);
+ }
+
+ if (pmbus_check_byte_register(client, i,
+ PMBUS_STATUS_MFR_SPECIFIC)) {
+ entries[idx].client = client;
+ entries[idx].page = i;
+ entries[idx].reg = PMBUS_STATUS_MFR_SPECIFIC;
+ scnprintf(name, PMBUS_NAME_SIZE, "status%d_mfr", i);
+ debugfs_create_file(name, 0444, data->debugfs,
+ &entries[idx++],
+ &pmbus_debugfs_ops);
+ }
+
+ if (data->info->func[i] & PMBUS_HAVE_STATUS_FAN12) {
+ entries[idx].client = client;
+ entries[idx].page = i;
+ entries[idx].reg = PMBUS_STATUS_FAN_12;
+ scnprintf(name, PMBUS_NAME_SIZE, "status%d_fan12", i);
+ debugfs_create_file(name, 0444, data->debugfs,
+ &entries[idx++],
+ &pmbus_debugfs_ops);
+ }
+
+ if (data->info->func[i] & PMBUS_HAVE_STATUS_FAN34) {
+ entries[idx].client = client;
+ entries[idx].page = i;
+ entries[idx].reg = PMBUS_STATUS_FAN_34;
+ scnprintf(name, PMBUS_NAME_SIZE, "status%d_fan34", i);
+ debugfs_create_file(name, 0444, data->debugfs,
+ &entries[idx++],
+ &pmbus_debugfs_ops);
+ }
+ }
+
+ return 0;
+}
+#else
+static int pmbus_init_debugfs(struct i2c_client *client,
+ struct pmbus_data *data)
+{
+ return 0;
+}
+#endif /* IS_ENABLED(CONFIG_DEBUG_FS) */
+
int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id,
struct pmbus_driver_info *info)
{
@@ -1918,6 +2142,10 @@ int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id,
if (ret)
goto out_unregister;
+ ret = pmbus_init_debugfs(client, data);
+ if (ret)
+ dev_warn(dev, "Failed to register debugfs\n");
+
return 0;
out_unregister:
@@ -1931,12 +2159,32 @@ EXPORT_SYMBOL_GPL(pmbus_do_probe);
int pmbus_do_remove(struct i2c_client *client)
{
struct pmbus_data *data = i2c_get_clientdata(client);
+
+ debugfs_remove_recursive(data->debugfs);
+
hwmon_device_unregister(data->hwmon_dev);
kfree(data->group.attrs);
return 0;
}
EXPORT_SYMBOL_GPL(pmbus_do_remove);
+static int __init pmbus_core_init(void)
+{
+ pmbus_debugfs_dir = debugfs_create_dir("pmbus", NULL);
+ if (IS_ERR(pmbus_debugfs_dir))
+ pmbus_debugfs_dir = NULL;
+
+ return 0;
+}
+
+static void __exit pmbus_core_exit(void)
+{
+ debugfs_remove_recursive(pmbus_debugfs_dir);
+}
+
+module_init(pmbus_core_init);
+module_exit(pmbus_core_exit);
+
MODULE_AUTHOR("Guenter Roeck");
MODULE_DESCRIPTION("PMBus core driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/pmbus/tps53679.c b/drivers/hwmon/pmbus/tps53679.c
new file mode 100644
index 0000000..85b515c
--- /dev/null
+++ b/drivers/hwmon/pmbus/tps53679.c
@@ -0,0 +1,113 @@
+/*
+ * Hardware monitoring driver for Texas Instruments TPS53679
+ *
+ * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2017 Vadim Pasternak <vadimp@mellanox.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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/err.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include "pmbus.h"
+
+#define TPS53679_PROT_VR12_5MV 0x01 /* VR12.0 mode, 5-mV DAC */
+#define TPS53679_PROT_VR12_5_10MV 0x02 /* VR12.5 mode, 10-mV DAC */
+#define TPS53679_PROT_VR13_10MV 0x04 /* VR13.0 mode, 10-mV DAC */
+#define TPS53679_PROT_IMVP8_5MV 0x05 /* IMVP8 mode, 5-mV DAC */
+#define TPS53679_PROT_VR13_5MV 0x07 /* VR13.0 mode, 5-mV DAC */
+#define TPS53679_PAGE_NUM 2
+
+static int tps53679_identify(struct i2c_client *client,
+ struct pmbus_driver_info *info)
+{
+ u8 vout_params;
+ int ret;
+
+ /* Read the register with VOUT scaling value.*/
+ ret = pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE);
+ if (ret < 0)
+ return ret;
+
+ vout_params = ret & GENMASK(4, 0);
+
+ switch (vout_params) {
+ case TPS53679_PROT_VR13_10MV:
+ case TPS53679_PROT_VR12_5_10MV:
+ info->vrm_version = vr13;
+ break;
+ case TPS53679_PROT_VR13_5MV:
+ case TPS53679_PROT_VR12_5MV:
+ case TPS53679_PROT_IMVP8_5MV:
+ info->vrm_version = vr12;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct pmbus_driver_info tps53679_info = {
+ .pages = TPS53679_PAGE_NUM,
+ .format[PSC_VOLTAGE_IN] = linear,
+ .format[PSC_VOLTAGE_OUT] = vid,
+ .format[PSC_TEMPERATURE] = linear,
+ .format[PSC_CURRENT_OUT] = linear,
+ .format[PSC_POWER] = linear,
+ .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
+ PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
+ PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP |
+ PMBUS_HAVE_POUT,
+ .func[1] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
+ PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
+ PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP |
+ PMBUS_HAVE_POUT,
+ .identify = tps53679_identify,
+};
+
+static int tps53679_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ return pmbus_do_probe(client, id, &tps53679_info);
+}
+
+static const struct i2c_device_id tps53679_id[] = {
+ {"tps53679", 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, tps53679_id);
+
+static const struct of_device_id tps53679_of_match[] = {
+ {.compatible = "ti,tps53679"},
+ {}
+};
+MODULE_DEVICE_TABLE(of, tps53679_of_match);
+
+static struct i2c_driver tps53679_driver = {
+ .driver = {
+ .name = "tps53679",
+ .of_match_table = of_match_ptr(tps53679_of_match),
+ },
+ .probe = tps53679_probe,
+ .remove = pmbus_do_remove,
+ .id_table = tps53679_id,
+};
+
+module_i2c_driver(tps53679_driver);
+
+MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
+MODULE_DESCRIPTION("PMBus driver for Texas Instruments TPS53679");
+MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/scpi-hwmon.c b/drivers/hwmon/scpi-hwmon.c
index a586480..7e49da5 100644
--- a/drivers/hwmon/scpi-hwmon.c
+++ b/drivers/hwmon/scpi-hwmon.c
@@ -120,7 +120,7 @@ scpi_show_label(struct device *dev, struct device_attribute *attr, char *buf)
return sprintf(buf, "%s\n", sensor->info.name);
}
-static struct thermal_zone_of_device_ops scpi_sensor_ops = {
+static const struct thermal_zone_of_device_ops scpi_sensor_ops = {
.get_temp = scpi_read_temp,
};
diff --git a/drivers/hwmon/stts751.c b/drivers/hwmon/stts751.c
index d56251d..3f940fb 100644
--- a/drivers/hwmon/stts751.c
+++ b/drivers/hwmon/stts751.c
@@ -718,6 +718,10 @@ static int stts751_read_chip_config(struct stts751_priv *priv)
ret = i2c_smbus_read_byte_data(priv->client, STTS751_REG_RATE);
if (ret < 0)
return ret;
+ if (ret >= ARRAY_SIZE(stts751_intervals)) {
+ dev_err(priv->dev, "Unrecognized conversion rate 0x%x\n", ret);
+ return -ENODEV;
+ }
priv->interval = ret;
ret = stts751_read_reg16(priv, &priv->event_max,
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index 57248bc..2b98a17 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -256,7 +256,8 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
struct dw_i2c_dev *dev;
u32 acpi_speed, ht = 0;
struct resource *mem;
- int irq, ret;
+ int i, irq, ret;
+ const int supported_speeds[] = { 0, 100000, 400000, 1000000, 3400000 };
irq = platform_get_irq(pdev, 0);
if (irq < 0)
@@ -297,9 +298,16 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
}
acpi_speed = i2c_acpi_find_bus_speed(&pdev->dev);
- /* Some broken DSTDs use 1MiHz instead of 1MHz */
- if (acpi_speed == 1048576)
- acpi_speed = 1000000;
+ /*
+ * Some DSTDs use a non standard speed, round down to the lowest
+ * standard speed.
+ */
+ for (i = 1; i < ARRAY_SIZE(supported_speeds); i++) {
+ if (acpi_speed < supported_speeds[i])
+ break;
+ }
+ acpi_speed = supported_speeds[i - 1];
+
/*
* Find bus speed from the "clock-frequency" device property, ACPI
* or by using fast mode if neither is set.
diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c
index e98e44e..22ffcb7 100644
--- a/drivers/i2c/busses/i2c-ismt.c
+++ b/drivers/i2c/busses/i2c-ismt.c
@@ -341,8 +341,10 @@ static int ismt_process_desc(const struct ismt_desc *desc,
break;
case I2C_SMBUS_BLOCK_DATA:
case I2C_SMBUS_I2C_BLOCK_DATA:
- memcpy(&data->block[1], dma_buffer, desc->rxbytes);
- data->block[0] = desc->rxbytes;
+ if (desc->rxbytes != dma_buffer[0] + 1)
+ return -EMSGSIZE;
+
+ memcpy(data->block, dma_buffer, desc->rxbytes);
break;
}
return 0;
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index c2ae819..e87ffb3 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -913,16 +913,15 @@ static __cpuidle int intel_idle(struct cpuidle_device *dev,
struct cpuidle_state *state = &drv->states[index];
unsigned long eax = flg2MWAIT(state->flags);
unsigned int cstate;
- int cpu = smp_processor_id();
cstate = (((eax) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK) + 1;
/*
- * leave_mm() to avoid costly and often unnecessary wakeups
- * for flushing the user TLB's associated with the active mm.
+ * NB: if CPUIDLE_FLAG_TLB_FLUSHED is set, this idle transition
+ * will probably flush the TLB. It's not guaranteed to flush
+ * the TLB, though, so it's not clear that we can do anything
+ * useful with this knowledge.
*/
- if (state->flags & CPUIDLE_FLAG_TLB_FLUSHED)
- leave_mm(cpu);
if (!(lapic_timer_reliable_states & (1 << (cstate))))
tick_broadcast_enter();
diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
index efc6773..3dec972 100644
--- a/drivers/iio/accel/bma180.c
+++ b/drivers/iio/accel/bma180.c
@@ -842,7 +842,7 @@ static SIMPLE_DEV_PM_OPS(bma180_pm_ops, bma180_suspend, bma180_resume);
#define BMA180_PM_OPS NULL
#endif
-static struct i2c_device_id bma180_ids[] = {
+static const struct i2c_device_id bma180_ids[] = {
{ "bma180", BMA180 },
{ "bma250", BMA250 },
{ }
diff --git a/drivers/iio/accel/bmc150-accel-i2c.c b/drivers/iio/accel/bmc150-accel-i2c.c
index 8ca8041..f85014f 100644
--- a/drivers/iio/accel/bmc150-accel-i2c.c
+++ b/drivers/iio/accel/bmc150-accel-i2c.c
@@ -64,6 +64,7 @@ static const struct acpi_device_id bmc150_accel_acpi_match[] = {
{"BMA250E", bma250e},
{"BMA222E", bma222e},
{"BMA0280", bma280},
+ {"BOSC0200"},
{ },
};
MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
diff --git a/drivers/iio/accel/da311.c b/drivers/iio/accel/da311.c
index 537cfa8..c0c1620 100644
--- a/drivers/iio/accel/da311.c
+++ b/drivers/iio/accel/da311.c
@@ -139,7 +139,7 @@ static int da311_register_mask_write(struct i2c_client *client, u16 addr,
/* Init sequence taken from the android driver */
static int da311_reset(struct i2c_client *client)
{
- const struct {
+ static const struct {
u16 addr;
u8 mask;
u8 data;
diff --git a/drivers/iio/accel/sca3000.c b/drivers/iio/accel/sca3000.c
index cb1d83f..39ab210 100644
--- a/drivers/iio/accel/sca3000.c
+++ b/drivers/iio/accel/sca3000.c
@@ -36,7 +36,7 @@
#define SCA3000_LOCKED BIT(5)
#define SCA3000_EEPROM_CS_ERROR BIT(1)
#define SCA3000_SPI_FRAME_ERROR BIT(0)
-
+
/* All reads done using register decrement so no need to directly access LSBs */
#define SCA3000_REG_X_MSB_ADDR 0x05
#define SCA3000_REG_Y_MSB_ADDR 0x07
@@ -74,7 +74,7 @@
#define SCA3000_REG_INT_STATUS_ADDR 0x16
#define SCA3000_REG_INT_STATUS_THREE_QUARTERS BIT(7)
#define SCA3000_REG_INT_STATUS_HALF BIT(6)
-
+
#define SCA3000_INT_STATUS_FREE_FALL BIT(3)
#define SCA3000_INT_STATUS_Y_TRIGGER BIT(2)
#define SCA3000_INT_STATUS_X_TRIGGER BIT(1)
@@ -124,7 +124,7 @@
#define SCA3000_REG_INT_MASK_ADDR 0x21
#define SCA3000_REG_INT_MASK_PROT_MASK 0x1C
-
+
#define SCA3000_REG_INT_MASK_RING_THREE_QUARTER BIT(7)
#define SCA3000_REG_INT_MASK_RING_HALF BIT(6)
diff --git a/drivers/iio/accel/st_accel.h b/drivers/iio/accel/st_accel.h
index 3ad44ce..0fe5216 100644
--- a/drivers/iio/accel/st_accel.h
+++ b/drivers/iio/accel/st_accel.h
@@ -29,10 +29,13 @@ enum st_accel_type {
LIS2DH12,
LIS3L02DQ,
LNG2DM,
+ H3LIS331DL,
+ LIS331DL,
+ LIS3LV02DL,
ST_ACCEL_MAX,
};
-#define H3LIS331DL_DRIVER_NAME "h3lis331dl_accel"
+#define H3LIS331DL_ACCEL_DEV_NAME "h3lis331dl_accel"
#define LIS3LV02DL_ACCEL_DEV_NAME "lis3lv02dl_accel"
#define LSM303DLHC_ACCEL_DEV_NAME "lsm303dlhc_accel"
#define LIS3DH_ACCEL_DEV_NAME "lis3dh"
diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
index e44f62b..752856b3 100644
--- a/drivers/iio/accel/st_accel_core.c
+++ b/drivers/iio/accel/st_accel_core.c
@@ -161,7 +161,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.drdy_irq = {
.addr = 0x22,
.mask_int1 = 0x10,
- .mask_int2 = 0x08,
+ .mask_int2 = 0x00,
.addr_ihl = 0x25,
.mask_ihl = 0x02,
.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
@@ -464,7 +464,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.wai = 0x32,
.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
.sensors_supported = {
- [0] = H3LIS331DL_DRIVER_NAME,
+ [0] = H3LIS331DL_ACCEL_DEV_NAME,
},
.ch = (struct iio_chan_spec *)st_accel_12bit_channels,
.odr = {
@@ -637,7 +637,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.drdy_irq = {
.addr = 0x22,
.mask_int1 = 0x10,
- .mask_int2 = 0x08,
+ .mask_int2 = 0x00,
.addr_ihl = 0x25,
.mask_ihl = 0x02,
.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
diff --git a/drivers/iio/accel/st_accel_i2c.c b/drivers/iio/accel/st_accel_i2c.c
index 543f0ad..18cafb9 100644
--- a/drivers/iio/accel/st_accel_i2c.c
+++ b/drivers/iio/accel/st_accel_i2c.c
@@ -84,7 +84,7 @@ static const struct of_device_id st_accel_of_match[] = {
},
{
.compatible = "st,h3lis331dl-accel",
- .data = H3LIS331DL_DRIVER_NAME,
+ .data = H3LIS331DL_ACCEL_DEV_NAME,
},
{
.compatible = "st,lis3l02dq",
@@ -126,6 +126,9 @@ static const struct i2c_device_id st_accel_id_table[] = {
{ LIS2DH12_ACCEL_DEV_NAME, LIS2DH12 },
{ LIS3L02DQ_ACCEL_DEV_NAME, LIS3L02DQ },
{ LNG2DM_ACCEL_DEV_NAME, LNG2DM },
+ { H3LIS331DL_ACCEL_DEV_NAME, H3LIS331DL },
+ { LIS331DL_ACCEL_DEV_NAME, LIS331DL },
+ { LIS3LV02DL_ACCEL_DEV_NAME, LIS3LV02DL },
{},
};
MODULE_DEVICE_TABLE(i2c, st_accel_id_table);
@@ -144,7 +147,8 @@ static int st_accel_i2c_probe(struct i2c_client *client,
adata = iio_priv(indio_dev);
if (client->dev.of_node) {
- st_sensors_of_i2c_probe(client, st_accel_of_match);
+ st_sensors_of_name_probe(&client->dev, st_accel_of_match,
+ client->name, sizeof(client->name));
} else if (ACPI_HANDLE(&client->dev)) {
ret = st_sensors_match_acpi_device(&client->dev);
if ((ret < 0) || (ret >= ST_ACCEL_MAX))
diff --git a/drivers/iio/accel/st_accel_spi.c b/drivers/iio/accel/st_accel_spi.c
index 1a867f5..915fa49 100644
--- a/drivers/iio/accel/st_accel_spi.c
+++ b/drivers/iio/accel/st_accel_spi.c
@@ -18,6 +18,77 @@
#include <linux/iio/common/st_sensors_spi.h>
#include "st_accel.h"
+#ifdef CONFIG_OF
+/*
+ * For new single-chip sensors use <device_name> as compatible string.
+ * For old single-chip devices keep <device_name>-accel to maintain
+ * compatibility
+ */
+static const struct of_device_id st_accel_of_match[] = {
+ {
+ /* An older compatible */
+ .compatible = "st,lis302dl-spi",
+ .data = LIS3LV02DL_ACCEL_DEV_NAME,
+ },
+ {
+ .compatible = "st,lis3lv02dl-accel",
+ .data = LIS3LV02DL_ACCEL_DEV_NAME,
+ },
+ {
+ .compatible = "st,lis3dh-accel",
+ .data = LIS3DH_ACCEL_DEV_NAME,
+ },
+ {
+ .compatible = "st,lsm330d-accel",
+ .data = LSM330D_ACCEL_DEV_NAME,
+ },
+ {
+ .compatible = "st,lsm330dl-accel",
+ .data = LSM330DL_ACCEL_DEV_NAME,
+ },
+ {
+ .compatible = "st,lsm330dlc-accel",
+ .data = LSM330DLC_ACCEL_DEV_NAME,
+ },
+ {
+ .compatible = "st,lis331dlh-accel",
+ .data = LIS331DLH_ACCEL_DEV_NAME,
+ },
+ {
+ .compatible = "st,lsm330-accel",
+ .data = LSM330_ACCEL_DEV_NAME,
+ },
+ {
+ .compatible = "st,lsm303agr-accel",
+ .data = LSM303AGR_ACCEL_DEV_NAME,
+ },
+ {
+ .compatible = "st,lis2dh12-accel",
+ .data = LIS2DH12_ACCEL_DEV_NAME,
+ },
+ {
+ .compatible = "st,lis3l02dq",
+ .data = LIS3L02DQ_ACCEL_DEV_NAME,
+ },
+ {
+ .compatible = "st,lng2dm-accel",
+ .data = LNG2DM_ACCEL_DEV_NAME,
+ },
+ {
+ .compatible = "st,h3lis331dl-accel",
+ .data = H3LIS331DL_ACCEL_DEV_NAME,
+ },
+ {
+ .compatible = "st,lis331dl-accel",
+ .data = LIS331DL_ACCEL_DEV_NAME,
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(of, st_accel_of_match);
+#else
+#define st_accel_of_match NULL
+#endif
+
static int st_accel_spi_probe(struct spi_device *spi)
{
struct iio_dev *indio_dev;
@@ -30,6 +101,8 @@ static int st_accel_spi_probe(struct spi_device *spi)
adata = iio_priv(indio_dev);
+ st_sensors_of_name_probe(&spi->dev, st_accel_of_match,
+ spi->modalias, sizeof(spi->modalias));
st_sensors_spi_configure(indio_dev, spi, adata);
err = st_accel_common_probe(indio_dev);
@@ -57,22 +130,17 @@ static const struct spi_device_id st_accel_id_table[] = {
{ LIS2DH12_ACCEL_DEV_NAME },
{ LIS3L02DQ_ACCEL_DEV_NAME },
{ LNG2DM_ACCEL_DEV_NAME },
+ { H3LIS331DL_ACCEL_DEV_NAME },
+ { LIS331DL_ACCEL_DEV_NAME },
+ { LIS3LV02DL_ACCEL_DEV_NAME },
{},
};
MODULE_DEVICE_TABLE(spi, st_accel_id_table);
-#ifdef CONFIG_OF
-static const struct of_device_id lis302dl_spi_dt_ids[] = {
- { .compatible = "st,lis302dl-spi" },
- {}
-};
-MODULE_DEVICE_TABLE(of, lis302dl_spi_dt_ids);
-#endif
-
static struct spi_driver st_accel_driver = {
.driver = {
.name = "st-accel-spi",
- .of_match_table = of_match_ptr(lis302dl_spi_dt_ids),
+ .of_match_table = of_match_ptr(st_accel_of_match),
},
.probe = st_accel_spi_probe,
.remove = st_accel_spi_remove,
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 614fa41..5762565 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -158,6 +158,7 @@ config AT91_SAMA5D2_ADC
tristate "Atmel AT91 SAMA5D2 ADC"
depends on ARCH_AT91 || COMPILE_TEST
depends on HAS_IOMEM
+ select IIO_TRIGGERED_BUFFER
help
Say yes here to build support for Atmel SAMA5D2 ADC which is
available on SAMA5D2 SoC family.
@@ -239,6 +240,15 @@ config DA9150_GPADC
To compile this driver as a module, choose M here: the module will be
called berlin2-adc.
+config DLN2_ADC
+ tristate "Diolan DLN-2 ADC driver support"
+ depends on MFD_DLN2
+ help
+ Say yes here to build support for Diolan DLN-2 ADC.
+
+ This driver can also be built as a module. If so, the module will be
+ called adc_dln2.
+
config ENVELOPE_DETECTOR
tristate "Envelope detector using a DAC and a comparator"
depends on OF
@@ -249,6 +259,17 @@ config ENVELOPE_DETECTOR
To compile this driver as a module, choose M here: the module will be
called envelope-detector.
+config EP93XX_ADC
+ tristate "Cirrus Logic EP93XX ADC driver"
+ depends on ARCH_EP93XX
+ help
+ Driver for the ADC module on the EP93XX series of SoC from Cirrus Logic.
+ It's recommended to switch on CONFIG_HIGH_RES_TIMERS option, in this
+ case driver will reduce its CPU usage by 90% in some use cases.
+
+ To compile this driver as a module, choose M here: the module will be
+ called ep93xx_adc.
+
config EXYNOS_ADC
tristate "Exynos ADC driver support"
depends on ARCH_EXYNOS || ARCH_S3C24XX || ARCH_S3C64XX || (OF && COMPILE_TEST)
@@ -322,7 +343,7 @@ config INA2XX_ADC
This driver is mutually exclusive with the HWMON version.
config IMX7D_ADC
- tristate "IMX7D ADC driver"
+ tristate "Freescale IMX7D ADC driver"
depends on ARCH_MXC || COMPILE_TEST
depends on HAS_IOMEM
help
@@ -362,6 +383,16 @@ config LPC32XX_ADC
activate only one via device tree selection. Provides direct access
via sysfs.
+config LTC2471
+ tristate "Linear Technology LTC2471 and LTC2473 ADC driver"
+ depends on I2C
+ help
+ Say yes here to build support for Linear Technology LTC2471 and
+ LTC2473 16-bit I2C ADC.
+
+ This driver can also be built as a module. If so, the module will
+ be called ltc2471.
+
config LTC2485
tristate "Linear Technology LTC2485 ADC driver"
depends on I2C
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index b546736a..9874e05 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -24,7 +24,9 @@ obj-$(CONFIG_BERLIN2_ADC) += berlin2-adc.o
obj-$(CONFIG_CC10001_ADC) += cc10001_adc.o
obj-$(CONFIG_CPCAP_ADC) += cpcap-adc.o
obj-$(CONFIG_DA9150_GPADC) += da9150-gpadc.o
+obj-$(CONFIG_DLN2_ADC) += dln2-adc.o
obj-$(CONFIG_ENVELOPE_DETECTOR) += envelope-detector.o
+obj-$(CONFIG_EP93XX_ADC) += ep93xx_adc.o
obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
obj-$(CONFIG_FSL_MX25_ADC) += fsl-imx25-gcq.o
obj-$(CONFIG_HI8435) += hi8435.o
@@ -34,6 +36,7 @@ obj-$(CONFIG_INA2XX_ADC) += ina2xx-adc.o
obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
obj-$(CONFIG_LPC18XX_ADC) += lpc18xx_adc.o
obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o
+obj-$(CONFIG_LTC2471) += ltc2471.o
obj-$(CONFIG_LTC2485) += ltc2485.o
obj-$(CONFIG_LTC2497) += ltc2497.o
obj-$(CONFIG_MAX1027) += max1027.o
diff --git a/drivers/iio/adc/ad7766.c b/drivers/iio/adc/ad7766.c
index 75cca42..ce45037 100644
--- a/drivers/iio/adc/ad7766.c
+++ b/drivers/iio/adc/ad7766.c
@@ -103,8 +103,7 @@ static int ad7766_preenable(struct iio_dev *indio_dev)
return ret;
}
- if (ad7766->pd_gpio)
- gpiod_set_value(ad7766->pd_gpio, 0);
+ gpiod_set_value(ad7766->pd_gpio, 0);
return 0;
}
@@ -113,8 +112,7 @@ static int ad7766_postdisable(struct iio_dev *indio_dev)
{
struct ad7766 *ad7766 = iio_priv(indio_dev);
- if (ad7766->pd_gpio)
- gpiod_set_value(ad7766->pd_gpio, 1);
+ gpiod_set_value(ad7766->pd_gpio, 1);
/*
* The PD pin is synchronous to the clock, so give it some time to
diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index e10dca3..bc5b38e 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -25,6 +25,11 @@
#include <linux/wait.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/pinctrl/consumer.h>
#include <linux/regulator/consumer.h>
/* Control Register */
@@ -132,6 +137,17 @@
#define AT91_SAMA5D2_PRESSR 0xbc
/* Trigger Register */
#define AT91_SAMA5D2_TRGR 0xc0
+/* Mask for TRGMOD field of TRGR register */
+#define AT91_SAMA5D2_TRGR_TRGMOD_MASK GENMASK(2, 0)
+/* No trigger, only software trigger can start conversions */
+#define AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER 0
+/* Trigger Mode external trigger rising edge */
+#define AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_RISE 1
+/* Trigger Mode external trigger falling edge */
+#define AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_FALL 2
+/* Trigger Mode external trigger any edge */
+#define AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_ANY 3
+
/* Correction Select Register */
#define AT91_SAMA5D2_COSR 0xd0
/* Correction Value Register */
@@ -145,14 +161,29 @@
/* Version Register */
#define AT91_SAMA5D2_VERSION 0xfc
+#define AT91_SAMA5D2_HW_TRIG_CNT 3
+#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
+#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
+
+/*
+ * Maximum number of bytes to hold conversion from all channels
+ * plus the timestamp
+ */
+#define AT91_BUFFER_MAX_BYTES ((AT91_SAMA5D2_SINGLE_CHAN_CNT + \
+ AT91_SAMA5D2_DIFF_CHAN_CNT) * 2 + 8)
+
+#define AT91_BUFFER_MAX_HWORDS (AT91_BUFFER_MAX_BYTES / 2)
+
#define AT91_SAMA5D2_CHAN_SINGLE(num, addr) \
{ \
.type = IIO_VOLTAGE, \
.channel = num, \
.address = addr, \
+ .scan_index = num, \
.scan_type = { \
.sign = 'u', \
.realbits = 12, \
+ .storagebits = 16, \
}, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
@@ -168,9 +199,11 @@
.channel = num, \
.channel2 = num2, \
.address = addr, \
+ .scan_index = num + AT91_SAMA5D2_SINGLE_CHAN_CNT, \
.scan_type = { \
.sign = 's', \
.realbits = 12, \
+ .storagebits = 16, \
}, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
@@ -188,6 +221,12 @@ struct at91_adc_soc_info {
unsigned max_sample_rate;
};
+struct at91_adc_trigger {
+ char *name;
+ unsigned int trgmod_value;
+ unsigned int edge_type;
+};
+
struct at91_adc_state {
void __iomem *base;
int irq;
@@ -195,11 +234,14 @@ struct at91_adc_state {
struct regulator *reg;
struct regulator *vref;
int vref_uv;
+ struct iio_trigger *trig;
+ const struct at91_adc_trigger *selected_trig;
const struct iio_chan_spec *chan;
bool conversion_done;
u32 conversion_value;
struct at91_adc_soc_info soc_info;
wait_queue_head_t wq_data_available;
+ u16 buffer[AT91_BUFFER_MAX_HWORDS];
/*
* lock to prevent concurrent 'single conversion' requests through
* sysfs.
@@ -207,6 +249,24 @@ struct at91_adc_state {
struct mutex lock;
};
+static const struct at91_adc_trigger at91_adc_trigger_list[] = {
+ {
+ .name = "external_rising",
+ .trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_RISE,
+ .edge_type = IRQ_TYPE_EDGE_RISING,
+ },
+ {
+ .name = "external_falling",
+ .trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_FALL,
+ .edge_type = IRQ_TYPE_EDGE_FALLING,
+ },
+ {
+ .name = "external_any",
+ .trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_ANY,
+ .edge_type = IRQ_TYPE_EDGE_BOTH,
+ },
+};
+
static const struct iio_chan_spec at91_adc_channels[] = {
AT91_SAMA5D2_CHAN_SINGLE(0, 0x50),
AT91_SAMA5D2_CHAN_SINGLE(1, 0x54),
@@ -226,12 +286,132 @@ static const struct iio_chan_spec at91_adc_channels[] = {
AT91_SAMA5D2_CHAN_DIFF(6, 7, 0x68),
AT91_SAMA5D2_CHAN_DIFF(8, 9, 0x70),
AT91_SAMA5D2_CHAN_DIFF(10, 11, 0x78),
+ IIO_CHAN_SOFT_TIMESTAMP(AT91_SAMA5D2_SINGLE_CHAN_CNT
+ + AT91_SAMA5D2_DIFF_CHAN_CNT + 1),
+};
+
+static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
+{
+ struct iio_dev *indio = iio_trigger_get_drvdata(trig);
+ struct at91_adc_state *st = iio_priv(indio);
+ u32 status = at91_adc_readl(st, AT91_SAMA5D2_TRGR);
+ u8 bit;
+
+ /* clear TRGMOD */
+ status &= ~AT91_SAMA5D2_TRGR_TRGMOD_MASK;
+
+ if (state)
+ status |= st->selected_trig->trgmod_value;
+
+ /* set/unset hw trigger */
+ at91_adc_writel(st, AT91_SAMA5D2_TRGR, status);
+
+ for_each_set_bit(bit, indio->active_scan_mask, indio->num_channels) {
+ struct iio_chan_spec const *chan = indio->channels + bit;
+
+ if (state) {
+ at91_adc_writel(st, AT91_SAMA5D2_CHER,
+ BIT(chan->channel));
+ at91_adc_writel(st, AT91_SAMA5D2_IER,
+ BIT(chan->channel));
+ } else {
+ at91_adc_writel(st, AT91_SAMA5D2_IDR,
+ BIT(chan->channel));
+ at91_adc_writel(st, AT91_SAMA5D2_CHDR,
+ BIT(chan->channel));
+ }
+ }
+
+ return 0;
+}
+
+static int at91_adc_reenable_trigger(struct iio_trigger *trig)
+{
+ struct iio_dev *indio = iio_trigger_get_drvdata(trig);
+ struct at91_adc_state *st = iio_priv(indio);
+
+ enable_irq(st->irq);
+
+ /* Needed to ACK the DRDY interruption */
+ at91_adc_readl(st, AT91_SAMA5D2_LCDR);
+ return 0;
+}
+
+static const struct iio_trigger_ops at91_adc_trigger_ops = {
+ .owner = THIS_MODULE,
+ .set_trigger_state = &at91_adc_configure_trigger,
+ .try_reenable = &at91_adc_reenable_trigger,
};
+static struct iio_trigger *at91_adc_allocate_trigger(struct iio_dev *indio,
+ char *trigger_name)
+{
+ struct iio_trigger *trig;
+ int ret;
+
+ trig = devm_iio_trigger_alloc(&indio->dev, "%s-dev%d-%s", indio->name,
+ indio->id, trigger_name);
+ if (!trig)
+ return NULL;
+
+ trig->dev.parent = indio->dev.parent;
+ iio_trigger_set_drvdata(trig, indio);
+ trig->ops = &at91_adc_trigger_ops;
+
+ ret = devm_iio_trigger_register(&indio->dev, trig);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return trig;
+}
+
+static int at91_adc_trigger_init(struct iio_dev *indio)
+{
+ struct at91_adc_state *st = iio_priv(indio);
+
+ st->trig = at91_adc_allocate_trigger(indio, st->selected_trig->name);
+ if (IS_ERR(st->trig)) {
+ dev_err(&indio->dev,
+ "could not allocate trigger\n");
+ return PTR_ERR(st->trig);
+ }
+
+ return 0;
+}
+
+static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio = pf->indio_dev;
+ struct at91_adc_state *st = iio_priv(indio);
+ int i = 0;
+ u8 bit;
+
+ for_each_set_bit(bit, indio->active_scan_mask, indio->num_channels) {
+ struct iio_chan_spec const *chan = indio->channels + bit;
+
+ st->buffer[i] = at91_adc_readl(st, chan->address);
+ i++;
+ }
+
+ iio_push_to_buffers_with_timestamp(indio, st->buffer, pf->timestamp);
+
+ iio_trigger_notify_done(indio->trig);
+
+ return IRQ_HANDLED;
+}
+
+static int at91_adc_buffer_init(struct iio_dev *indio)
+{
+ return devm_iio_triggered_buffer_setup(&indio->dev, indio,
+ &iio_pollfunc_store_time,
+ &at91_adc_trigger_handler, NULL);
+}
+
static unsigned at91_adc_startup_time(unsigned startup_time_min,
unsigned adc_clk_khz)
{
- const unsigned startup_lookup[] = {
+ static const unsigned int startup_lookup[] = {
0, 8, 16, 24,
64, 80, 96, 112,
512, 576, 640, 704,
@@ -293,14 +473,18 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
u32 status = at91_adc_readl(st, AT91_SAMA5D2_ISR);
u32 imr = at91_adc_readl(st, AT91_SAMA5D2_IMR);
- if (status & imr) {
+ if (!(status & imr))
+ return IRQ_NONE;
+
+ if (iio_buffer_enabled(indio)) {
+ disable_irq_nosync(irq);
+ iio_trigger_poll(indio->trig);
+ } else {
st->conversion_value = at91_adc_readl(st, st->chan->address);
st->conversion_done = true;
wake_up_interruptible(&st->wq_data_available);
- return IRQ_HANDLED;
}
-
- return IRQ_NONE;
+ return IRQ_HANDLED;
}
static int at91_adc_read_raw(struct iio_dev *indio_dev,
@@ -313,6 +497,11 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
+ /* we cannot use software trigger if hw trigger enabled */
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret)
+ return ret;
+
mutex_lock(&st->lock);
st->chan = chan;
@@ -344,6 +533,8 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev,
at91_adc_writel(st, AT91_SAMA5D2_CHDR, BIT(chan->channel));
mutex_unlock(&st->lock);
+
+ iio_device_release_direct_mode(indio_dev);
return ret;
case IIO_CHAN_INFO_SCALE:
@@ -386,12 +577,27 @@ static const struct iio_info at91_adc_info = {
.driver_module = THIS_MODULE,
};
+static void at91_adc_hw_init(struct at91_adc_state *st)
+{
+ at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST);
+ at91_adc_writel(st, AT91_SAMA5D2_IDR, 0xffffffff);
+ /*
+ * Transfer field must be set to 2 according to the datasheet and
+ * allows different analog settings for each channel.
+ */
+ at91_adc_writel(st, AT91_SAMA5D2_MR,
+ AT91_SAMA5D2_MR_TRANSFER(2) | AT91_SAMA5D2_MR_ANACH);
+
+ at91_adc_setup_samp_freq(st, st->soc_info.min_sample_rate);
+}
+
static int at91_adc_probe(struct platform_device *pdev)
{
struct iio_dev *indio_dev;
struct at91_adc_state *st;
struct resource *res;
- int ret;
+ int ret, i;
+ u32 edge_type;
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*st));
if (!indio_dev)
@@ -432,6 +638,27 @@ static int at91_adc_probe(struct platform_device *pdev)
return ret;
}
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "atmel,trigger-edge-type", &edge_type);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "invalid or missing value for atmel,trigger-edge-type\n");
+ return ret;
+ }
+
+ st->selected_trig = NULL;
+
+ for (i = 0; i < AT91_SAMA5D2_HW_TRIG_CNT; i++)
+ if (at91_adc_trigger_list[i].edge_type == edge_type) {
+ st->selected_trig = &at91_adc_trigger_list[i];
+ break;
+ }
+
+ if (!st->selected_trig) {
+ dev_err(&pdev->dev, "invalid external trigger edge value\n");
+ return -EINVAL;
+ }
+
init_waitqueue_head(&st->wq_data_available);
mutex_init(&st->lock);
@@ -482,16 +709,7 @@ static int at91_adc_probe(struct platform_device *pdev)
goto vref_disable;
}
- at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST);
- at91_adc_writel(st, AT91_SAMA5D2_IDR, 0xffffffff);
- /*
- * Transfer field must be set to 2 according to the datasheet and
- * allows different analog settings for each channel.
- */
- at91_adc_writel(st, AT91_SAMA5D2_MR,
- AT91_SAMA5D2_MR_TRANSFER(2) | AT91_SAMA5D2_MR_ANACH);
-
- at91_adc_setup_samp_freq(st, st->soc_info.min_sample_rate);
+ at91_adc_hw_init(st);
ret = clk_prepare_enable(st->per_clk);
if (ret)
@@ -499,10 +717,25 @@ static int at91_adc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, indio_dev);
+ ret = at91_adc_buffer_init(indio_dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "couldn't initialize the buffer.\n");
+ goto per_clk_disable_unprepare;
+ }
+
+ ret = at91_adc_trigger_init(indio_dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "couldn't setup the triggers.\n");
+ goto per_clk_disable_unprepare;
+ }
+
ret = iio_device_register(indio_dev);
if (ret < 0)
goto per_clk_disable_unprepare;
+ dev_info(&pdev->dev, "setting up trigger as %s\n",
+ st->selected_trig->name);
+
dev_info(&pdev->dev, "version: %x\n",
readl_relaxed(st->base + AT91_SAMA5D2_VERSION));
@@ -532,6 +765,69 @@ static int at91_adc_remove(struct platform_device *pdev)
return 0;
}
+static __maybe_unused int at91_adc_suspend(struct device *dev)
+{
+ struct iio_dev *indio_dev =
+ platform_get_drvdata(to_platform_device(dev));
+ struct at91_adc_state *st = iio_priv(indio_dev);
+
+ /*
+ * Do a sofware reset of the ADC before we go to suspend.
+ * this will ensure that all pins are free from being muxed by the ADC
+ * and can be used by for other devices.
+ * Otherwise, ADC will hog them and we can't go to suspend mode.
+ */
+ at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST);
+
+ clk_disable_unprepare(st->per_clk);
+ regulator_disable(st->vref);
+ regulator_disable(st->reg);
+
+ return pinctrl_pm_select_sleep_state(dev);
+}
+
+static __maybe_unused int at91_adc_resume(struct device *dev)
+{
+ struct iio_dev *indio_dev =
+ platform_get_drvdata(to_platform_device(dev));
+ struct at91_adc_state *st = iio_priv(indio_dev);
+ int ret;
+
+ ret = pinctrl_pm_select_default_state(dev);
+ if (ret)
+ goto resume_failed;
+
+ ret = regulator_enable(st->reg);
+ if (ret)
+ goto resume_failed;
+
+ ret = regulator_enable(st->vref);
+ if (ret)
+ goto reg_disable_resume;
+
+ ret = clk_prepare_enable(st->per_clk);
+ if (ret)
+ goto vref_disable_resume;
+
+ at91_adc_hw_init(st);
+
+ /* reconfiguring trigger hardware state */
+ if (iio_buffer_enabled(indio_dev))
+ at91_adc_configure_trigger(st->trig, true);
+
+ return 0;
+
+vref_disable_resume:
+ regulator_disable(st->vref);
+reg_disable_resume:
+ regulator_disable(st->reg);
+resume_failed:
+ dev_err(&indio_dev->dev, "failed to resume\n");
+ return ret;
+}
+
+static SIMPLE_DEV_PM_OPS(at91_adc_pm_ops, at91_adc_suspend, at91_adc_resume);
+
static const struct of_device_id at91_adc_dt_match[] = {
{
.compatible = "atmel,sama5d2-adc",
@@ -547,6 +843,7 @@ static struct platform_driver at91_adc_driver = {
.driver = {
.name = "at91-sama5d2_adc",
.of_match_table = at91_adc_dt_match,
+ .pm = &at91_adc_pm_ops,
},
};
module_platform_driver(at91_adc_driver)
diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c
index 34b928c..1510972 100644
--- a/drivers/iio/adc/at91_adc.c
+++ b/drivers/iio/adc/at91_adc.c
@@ -799,7 +799,7 @@ static u32 calc_startup_ticks_9x5(u32 startup_time, u32 adc_clk_khz)
* For sama5d3x and at91sam9x5, the formula changes to:
* Startup Time = <lookup_table_value> / ADC Clock
*/
- const int startup_lookup[] = {
+ static const int startup_lookup[] = {
0, 8, 16, 24,
64, 80, 96, 112,
512, 576, 640, 704,
diff --git a/drivers/iio/adc/dln2-adc.c b/drivers/iio/adc/dln2-adc.c
new file mode 100644
index 0000000..ab8d6ae
--- /dev/null
+++ b/drivers/iio/adc/dln2-adc.c
@@ -0,0 +1,722 @@
+/*
+ * Driver for the Diolan DLN-2 USB-ADC adapter
+ *
+ * Copyright (c) 2017 Jack Andersen
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/dln2.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/kfifo_buf.h>
+
+#define DLN2_ADC_MOD_NAME "dln2-adc"
+
+#define DLN2_ADC_ID 0x06
+
+#define DLN2_ADC_GET_CHANNEL_COUNT DLN2_CMD(0x01, DLN2_ADC_ID)
+#define DLN2_ADC_ENABLE DLN2_CMD(0x02, DLN2_ADC_ID)
+#define DLN2_ADC_DISABLE DLN2_CMD(0x03, DLN2_ADC_ID)
+#define DLN2_ADC_CHANNEL_ENABLE DLN2_CMD(0x05, DLN2_ADC_ID)
+#define DLN2_ADC_CHANNEL_DISABLE DLN2_CMD(0x06, DLN2_ADC_ID)
+#define DLN2_ADC_SET_RESOLUTION DLN2_CMD(0x08, DLN2_ADC_ID)
+#define DLN2_ADC_CHANNEL_GET_VAL DLN2_CMD(0x0A, DLN2_ADC_ID)
+#define DLN2_ADC_CHANNEL_GET_ALL_VAL DLN2_CMD(0x0B, DLN2_ADC_ID)
+#define DLN2_ADC_CHANNEL_SET_CFG DLN2_CMD(0x0C, DLN2_ADC_ID)
+#define DLN2_ADC_CHANNEL_GET_CFG DLN2_CMD(0x0D, DLN2_ADC_ID)
+#define DLN2_ADC_CONDITION_MET_EV DLN2_CMD(0x10, DLN2_ADC_ID)
+
+#define DLN2_ADC_EVENT_NONE 0
+#define DLN2_ADC_EVENT_BELOW 1
+#define DLN2_ADC_EVENT_LEVEL_ABOVE 2
+#define DLN2_ADC_EVENT_OUTSIDE 3
+#define DLN2_ADC_EVENT_INSIDE 4
+#define DLN2_ADC_EVENT_ALWAYS 5
+
+#define DLN2_ADC_MAX_CHANNELS 8
+#define DLN2_ADC_DATA_BITS 10
+
+/*
+ * Plays similar role to iio_demux_table in subsystem core; except allocated
+ * in a fixed 8-element array.
+ */
+struct dln2_adc_demux_table {
+ unsigned int from;
+ unsigned int to;
+ unsigned int length;
+};
+
+struct dln2_adc {
+ struct platform_device *pdev;
+ struct iio_chan_spec iio_channels[DLN2_ADC_MAX_CHANNELS + 1];
+ int port, trigger_chan;
+ struct iio_trigger *trig;
+ struct mutex mutex;
+ /* Cached sample period in milliseconds */
+ unsigned int sample_period;
+ /* Demux table */
+ unsigned int demux_count;
+ struct dln2_adc_demux_table demux[DLN2_ADC_MAX_CHANNELS];
+ /* Precomputed timestamp padding offset and length */
+ unsigned int ts_pad_offset, ts_pad_length;
+};
+
+struct dln2_adc_port_chan {
+ u8 port;
+ u8 chan;
+};
+
+struct dln2_adc_get_all_vals {
+ __le16 channel_mask;
+ __le16 values[DLN2_ADC_MAX_CHANNELS];
+};
+
+static void dln2_adc_add_demux(struct dln2_adc *dln2,
+ unsigned int in_loc, unsigned int out_loc,
+ unsigned int length)
+{
+ struct dln2_adc_demux_table *p = dln2->demux_count ?
+ &dln2->demux[dln2->demux_count - 1] : NULL;
+
+ if (p && p->from + p->length == in_loc &&
+ p->to + p->length == out_loc) {
+ p->length += length;
+ } else if (dln2->demux_count < DLN2_ADC_MAX_CHANNELS) {
+ p = &dln2->demux[dln2->demux_count++];
+ p->from = in_loc;
+ p->to = out_loc;
+ p->length = length;
+ }
+}
+
+static void dln2_adc_update_demux(struct dln2_adc *dln2)
+{
+ int in_ind = -1, out_ind;
+ unsigned int in_loc = 0, out_loc = 0;
+ struct iio_dev *indio_dev = platform_get_drvdata(dln2->pdev);
+
+ /* Clear out any old demux */
+ dln2->demux_count = 0;
+
+ /* Optimize all 8-channels case */
+ if (indio_dev->masklength &&
+ (*indio_dev->active_scan_mask & 0xff) == 0xff) {
+ dln2_adc_add_demux(dln2, 0, 0, 16);
+ dln2->ts_pad_offset = 0;
+ dln2->ts_pad_length = 0;
+ return;
+ }
+
+ /* Build demux table from fixed 8-channels to active_scan_mask */
+ for_each_set_bit(out_ind,
+ indio_dev->active_scan_mask,
+ indio_dev->masklength) {
+ /* Handle timestamp separately */
+ if (out_ind == DLN2_ADC_MAX_CHANNELS)
+ break;
+ for (++in_ind; in_ind != out_ind; ++in_ind)
+ in_loc += 2;
+ dln2_adc_add_demux(dln2, in_loc, out_loc, 2);
+ out_loc += 2;
+ in_loc += 2;
+ }
+
+ if (indio_dev->scan_timestamp) {
+ size_t ts_offset = indio_dev->scan_bytes / sizeof(int64_t) - 1;
+
+ dln2->ts_pad_offset = out_loc;
+ dln2->ts_pad_length = ts_offset * sizeof(int64_t) - out_loc;
+ } else {
+ dln2->ts_pad_offset = 0;
+ dln2->ts_pad_length = 0;
+ }
+}
+
+static int dln2_adc_get_chan_count(struct dln2_adc *dln2)
+{
+ int ret;
+ u8 port = dln2->port;
+ u8 count;
+ int olen = sizeof(count);
+
+ ret = dln2_transfer(dln2->pdev, DLN2_ADC_GET_CHANNEL_COUNT,
+ &port, sizeof(port), &count, &olen);
+ if (ret < 0) {
+ dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__);
+ return ret;
+ }
+ if (olen < sizeof(count))
+ return -EPROTO;
+
+ return count;
+}
+
+static int dln2_adc_set_port_resolution(struct dln2_adc *dln2)
+{
+ int ret;
+ struct dln2_adc_port_chan port_chan = {
+ .port = dln2->port,
+ .chan = DLN2_ADC_DATA_BITS,
+ };
+
+ ret = dln2_transfer_tx(dln2->pdev, DLN2_ADC_SET_RESOLUTION,
+ &port_chan, sizeof(port_chan));
+ if (ret < 0)
+ dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__);
+
+ return ret;
+}
+
+static int dln2_adc_set_chan_enabled(struct dln2_adc *dln2,
+ int channel, bool enable)
+{
+ int ret;
+ struct dln2_adc_port_chan port_chan = {
+ .port = dln2->port,
+ .chan = channel,
+ };
+ u16 cmd = enable ? DLN2_ADC_CHANNEL_ENABLE : DLN2_ADC_CHANNEL_DISABLE;
+
+ ret = dln2_transfer_tx(dln2->pdev, cmd, &port_chan, sizeof(port_chan));
+ if (ret < 0)
+ dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__);
+
+ return ret;
+}
+
+static int dln2_adc_set_port_enabled(struct dln2_adc *dln2, bool enable,
+ u16 *conflict_out)
+{
+ int ret;
+ u8 port = dln2->port;
+ __le16 conflict;
+ int olen = sizeof(conflict);
+ u16 cmd = enable ? DLN2_ADC_ENABLE : DLN2_ADC_DISABLE;
+
+ if (conflict_out)
+ *conflict_out = 0;
+
+ ret = dln2_transfer(dln2->pdev, cmd, &port, sizeof(port),
+ &conflict, &olen);
+ if (ret < 0) {
+ dev_dbg(&dln2->pdev->dev, "Problem in %s(%d)\n",
+ __func__, (int)enable);
+ if (conflict_out && enable && olen >= sizeof(conflict))
+ *conflict_out = le16_to_cpu(conflict);
+ return ret;
+ }
+ if (enable && olen < sizeof(conflict))
+ return -EPROTO;
+
+ return ret;
+}
+
+static int dln2_adc_set_chan_period(struct dln2_adc *dln2,
+ unsigned int channel, unsigned int period)
+{
+ int ret;
+ struct {
+ struct dln2_adc_port_chan port_chan;
+ __u8 type;
+ __le16 period;
+ __le16 low;
+ __le16 high;
+ } __packed set_cfg = {
+ .port_chan.port = dln2->port,
+ .port_chan.chan = channel,
+ .type = period ? DLN2_ADC_EVENT_ALWAYS : DLN2_ADC_EVENT_NONE,
+ .period = cpu_to_le16(period)
+ };
+
+ ret = dln2_transfer_tx(dln2->pdev, DLN2_ADC_CHANNEL_SET_CFG,
+ &set_cfg, sizeof(set_cfg));
+ if (ret < 0)
+ dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__);
+
+ return ret;
+}
+
+static int dln2_adc_read(struct dln2_adc *dln2, unsigned int channel)
+{
+ int ret, i;
+ struct iio_dev *indio_dev = platform_get_drvdata(dln2->pdev);
+ u16 conflict;
+ __le16 value;
+ int olen = sizeof(value);
+ struct dln2_adc_port_chan port_chan = {
+ .port = dln2->port,
+ .chan = channel,
+ };
+
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret < 0)
+ return ret;
+
+ ret = dln2_adc_set_chan_enabled(dln2, channel, true);
+ if (ret < 0)
+ goto release_direct;
+
+ ret = dln2_adc_set_port_enabled(dln2, true, &conflict);
+ if (ret < 0) {
+ if (conflict) {
+ dev_err(&dln2->pdev->dev,
+ "ADC pins conflict with mask %04X\n",
+ (int)conflict);
+ ret = -EBUSY;
+ }
+ goto disable_chan;
+ }
+
+ /*
+ * Call GET_VAL twice due to initial zero-return immediately after
+ * enabling channel.
+ */
+ for (i = 0; i < 2; ++i) {
+ ret = dln2_transfer(dln2->pdev, DLN2_ADC_CHANNEL_GET_VAL,
+ &port_chan, sizeof(port_chan),
+ &value, &olen);
+ if (ret < 0) {
+ dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__);
+ goto disable_port;
+ }
+ if (olen < sizeof(value)) {
+ ret = -EPROTO;
+ goto disable_port;
+ }
+ }
+
+ ret = le16_to_cpu(value);
+
+disable_port:
+ dln2_adc_set_port_enabled(dln2, false, NULL);
+disable_chan:
+ dln2_adc_set_chan_enabled(dln2, channel, false);
+release_direct:
+ iio_device_release_direct_mode(indio_dev);
+
+ return ret;
+}
+
+static int dln2_adc_read_all(struct dln2_adc *dln2,
+ struct dln2_adc_get_all_vals *get_all_vals)
+{
+ int ret;
+ __u8 port = dln2->port;
+ int olen = sizeof(*get_all_vals);
+
+ ret = dln2_transfer(dln2->pdev, DLN2_ADC_CHANNEL_GET_ALL_VAL,
+ &port, sizeof(port), get_all_vals, &olen);
+ if (ret < 0) {
+ dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__);
+ return ret;
+ }
+ if (olen < sizeof(*get_all_vals))
+ return -EPROTO;
+
+ return ret;
+}
+
+static int dln2_adc_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val,
+ int *val2,
+ long mask)
+{
+ int ret;
+ unsigned int microhertz;
+ struct dln2_adc *dln2 = iio_priv(indio_dev);
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ mutex_lock(&dln2->mutex);
+ ret = dln2_adc_read(dln2, chan->channel);
+ mutex_unlock(&dln2->mutex);
+
+ if (ret < 0)
+ return ret;
+
+ *val = ret;
+ return IIO_VAL_INT;
+
+ case IIO_CHAN_INFO_SCALE:
+ /*
+ * Voltage reference is fixed at 3.3v
+ * 3.3 / (1 << 10) * 1000000000
+ */
+ *val = 0;
+ *val2 = 3222656;
+ return IIO_VAL_INT_PLUS_NANO;
+
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ if (dln2->sample_period) {
+ microhertz = 1000000000 / dln2->sample_period;
+ *val = microhertz / 1000000;
+ *val2 = microhertz % 1000000;
+ } else {
+ *val = 0;
+ *val2 = 0;
+ }
+
+ return IIO_VAL_INT_PLUS_MICRO;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static int dln2_adc_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val,
+ int val2,
+ long mask)
+{
+ int ret;
+ unsigned int microhertz;
+ struct dln2_adc *dln2 = iio_priv(indio_dev);
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ microhertz = 1000000 * val + val2;
+
+ mutex_lock(&dln2->mutex);
+
+ dln2->sample_period =
+ microhertz ? 1000000000 / microhertz : UINT_MAX;
+ if (dln2->sample_period > 65535) {
+ dln2->sample_period = 65535;
+ dev_warn(&dln2->pdev->dev,
+ "clamping period to 65535ms\n");
+ }
+
+ /*
+ * The first requested channel is arbitrated as a shared
+ * trigger source, so only one event is registered with the
+ * DLN. The event handler will then read all enabled channel
+ * values using DLN2_ADC_CHANNEL_GET_ALL_VAL to maintain
+ * synchronization between ADC readings.
+ */
+ if (dln2->trigger_chan != -1)
+ ret = dln2_adc_set_chan_period(dln2,
+ dln2->trigger_chan, dln2->sample_period);
+ else
+ ret = 0;
+
+ mutex_unlock(&dln2->mutex);
+
+ return ret;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static int dln2_update_scan_mode(struct iio_dev *indio_dev,
+ const unsigned long *scan_mask)
+{
+ struct dln2_adc *dln2 = iio_priv(indio_dev);
+ int chan_count = indio_dev->num_channels - 1;
+ int ret, i, j;
+
+ mutex_lock(&dln2->mutex);
+
+ for (i = 0; i < chan_count; ++i) {
+ ret = dln2_adc_set_chan_enabled(dln2, i,
+ test_bit(i, scan_mask));
+ if (ret < 0) {
+ for (j = 0; j < i; ++j)
+ dln2_adc_set_chan_enabled(dln2, j, false);
+ mutex_unlock(&dln2->mutex);
+ dev_err(&dln2->pdev->dev,
+ "Unable to enable ADC channel %d\n", i);
+ return -EBUSY;
+ }
+ }
+
+ dln2_adc_update_demux(dln2);
+
+ mutex_unlock(&dln2->mutex);
+
+ return 0;
+}
+
+#define DLN2_ADC_CHAN(lval, idx) { \
+ lval.type = IIO_VOLTAGE; \
+ lval.channel = idx; \
+ lval.indexed = 1; \
+ lval.info_mask_separate = BIT(IIO_CHAN_INFO_RAW); \
+ lval.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_SAMP_FREQ); \
+ lval.scan_index = idx; \
+ lval.scan_type.sign = 'u'; \
+ lval.scan_type.realbits = DLN2_ADC_DATA_BITS; \
+ lval.scan_type.storagebits = 16; \
+ lval.scan_type.endianness = IIO_LE; \
+}
+
+/* Assignment version of IIO_CHAN_SOFT_TIMESTAMP */
+#define IIO_CHAN_SOFT_TIMESTAMP_ASSIGN(lval, _si) { \
+ lval.type = IIO_TIMESTAMP; \
+ lval.channel = -1; \
+ lval.scan_index = _si; \
+ lval.scan_type.sign = 's'; \
+ lval.scan_type.realbits = 64; \
+ lval.scan_type.storagebits = 64; \
+}
+
+static const struct iio_info dln2_adc_info = {
+ .read_raw = dln2_adc_read_raw,
+ .write_raw = dln2_adc_write_raw,
+ .update_scan_mode = dln2_update_scan_mode,
+ .driver_module = THIS_MODULE,
+};
+
+static irqreturn_t dln2_adc_trigger_h(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct {
+ __le16 values[DLN2_ADC_MAX_CHANNELS];
+ int64_t timestamp_space;
+ } data;
+ struct dln2_adc_get_all_vals dev_data;
+ struct dln2_adc *dln2 = iio_priv(indio_dev);
+ const struct dln2_adc_demux_table *t;
+ int ret, i;
+
+ mutex_lock(&dln2->mutex);
+ ret = dln2_adc_read_all(dln2, &dev_data);
+ mutex_unlock(&dln2->mutex);
+ if (ret < 0)
+ goto done;
+
+ /* Demux operation */
+ for (i = 0; i < dln2->demux_count; ++i) {
+ t = &dln2->demux[i];
+ memcpy((void *)data.values + t->to,
+ (void *)dev_data.values + t->from, t->length);
+ }
+
+ /* Zero padding space between values and timestamp */
+ if (dln2->ts_pad_length)
+ memset((void *)data.values + dln2->ts_pad_offset,
+ 0, dln2->ts_pad_length);
+
+ iio_push_to_buffers_with_timestamp(indio_dev, &data,
+ iio_get_time_ns(indio_dev));
+
+done:
+ iio_trigger_notify_done(indio_dev->trig);
+ return IRQ_HANDLED;
+}
+
+static int dln2_adc_triggered_buffer_postenable(struct iio_dev *indio_dev)
+{
+ int ret;
+ struct dln2_adc *dln2 = iio_priv(indio_dev);
+ u16 conflict;
+ unsigned int trigger_chan;
+
+ mutex_lock(&dln2->mutex);
+
+ /* Enable ADC */
+ ret = dln2_adc_set_port_enabled(dln2, true, &conflict);
+ if (ret < 0) {
+ mutex_unlock(&dln2->mutex);
+ dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__);
+ if (conflict) {
+ dev_err(&dln2->pdev->dev,
+ "ADC pins conflict with mask %04X\n",
+ (int)conflict);
+ ret = -EBUSY;
+ }
+ return ret;
+ }
+
+ /* Assign trigger channel based on first enabled channel */
+ trigger_chan = find_first_bit(indio_dev->active_scan_mask,
+ indio_dev->masklength);
+ if (trigger_chan < DLN2_ADC_MAX_CHANNELS) {
+ dln2->trigger_chan = trigger_chan;
+ ret = dln2_adc_set_chan_period(dln2, dln2->trigger_chan,
+ dln2->sample_period);
+ mutex_unlock(&dln2->mutex);
+ if (ret < 0) {
+ dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__);
+ return ret;
+ }
+ } else {
+ dln2->trigger_chan = -1;
+ mutex_unlock(&dln2->mutex);
+ }
+
+ return iio_triggered_buffer_postenable(indio_dev);
+}
+
+static int dln2_adc_triggered_buffer_predisable(struct iio_dev *indio_dev)
+{
+ int ret;
+ struct dln2_adc *dln2 = iio_priv(indio_dev);
+
+ mutex_lock(&dln2->mutex);
+
+ /* Disable trigger channel */
+ if (dln2->trigger_chan != -1) {
+ dln2_adc_set_chan_period(dln2, dln2->trigger_chan, 0);
+ dln2->trigger_chan = -1;
+ }
+
+ /* Disable ADC */
+ ret = dln2_adc_set_port_enabled(dln2, false, NULL);
+
+ mutex_unlock(&dln2->mutex);
+ if (ret < 0) {
+ dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__);
+ return ret;
+ }
+
+ return iio_triggered_buffer_predisable(indio_dev);
+}
+
+static const struct iio_buffer_setup_ops dln2_adc_buffer_setup_ops = {
+ .postenable = dln2_adc_triggered_buffer_postenable,
+ .predisable = dln2_adc_triggered_buffer_predisable,
+};
+
+static void dln2_adc_event(struct platform_device *pdev, u16 echo,
+ const void *data, int len)
+{
+ struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+ struct dln2_adc *dln2 = iio_priv(indio_dev);
+
+ /* Called via URB completion handler */
+ iio_trigger_poll(dln2->trig);
+}
+
+static const struct iio_trigger_ops dln2_adc_trigger_ops = {
+ .owner = THIS_MODULE,
+};
+
+static int dln2_adc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct dln2_adc *dln2;
+ struct dln2_platform_data *pdata = dev_get_platdata(&pdev->dev);
+ struct iio_dev *indio_dev;
+ int i, ret, chans;
+
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*dln2));
+ if (!indio_dev) {
+ dev_err(dev, "failed allocating iio device\n");
+ return -ENOMEM;
+ }
+
+ dln2 = iio_priv(indio_dev);
+ dln2->pdev = pdev;
+ dln2->port = pdata->port;
+ dln2->trigger_chan = -1;
+ mutex_init(&dln2->mutex);
+
+ platform_set_drvdata(pdev, indio_dev);
+
+ ret = dln2_adc_set_port_resolution(dln2);
+ if (ret < 0) {
+ dev_err(dev, "failed to set ADC resolution to 10 bits\n");
+ return ret;
+ }
+
+ chans = dln2_adc_get_chan_count(dln2);
+ if (chans < 0) {
+ dev_err(dev, "failed to get channel count: %d\n", chans);
+ return chans;
+ }
+ if (chans > DLN2_ADC_MAX_CHANNELS) {
+ chans = DLN2_ADC_MAX_CHANNELS;
+ dev_warn(dev, "clamping channels to %d\n",
+ DLN2_ADC_MAX_CHANNELS);
+ }
+
+ for (i = 0; i < chans; ++i)
+ DLN2_ADC_CHAN(dln2->iio_channels[i], i)
+ IIO_CHAN_SOFT_TIMESTAMP_ASSIGN(dln2->iio_channels[i], i);
+
+ indio_dev->name = DLN2_ADC_MOD_NAME;
+ indio_dev->dev.parent = dev;
+ indio_dev->info = &dln2_adc_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = dln2->iio_channels;
+ indio_dev->num_channels = chans + 1;
+ indio_dev->setup_ops = &dln2_adc_buffer_setup_ops;
+
+ dln2->trig = devm_iio_trigger_alloc(dev, "%s-dev%d",
+ indio_dev->name, indio_dev->id);
+ if (!dln2->trig) {
+ dev_err(dev, "failed to allocate trigger\n");
+ return -ENOMEM;
+ }
+ dln2->trig->ops = &dln2_adc_trigger_ops;
+ iio_trigger_set_drvdata(dln2->trig, dln2);
+ devm_iio_trigger_register(dev, dln2->trig);
+ iio_trigger_set_immutable(indio_dev, dln2->trig);
+
+ ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
+ dln2_adc_trigger_h,
+ &dln2_adc_buffer_setup_ops);
+ if (ret) {
+ dev_err(dev, "failed to allocate triggered buffer: %d\n", ret);
+ return ret;
+ }
+
+ ret = dln2_register_event_cb(pdev, DLN2_ADC_CONDITION_MET_EV,
+ dln2_adc_event);
+ if (ret) {
+ dev_err(dev, "failed to setup DLN2 periodic event: %d\n", ret);
+ return ret;
+ }
+
+ ret = iio_device_register(indio_dev);
+ if (ret) {
+ dev_err(dev, "failed to register iio device: %d\n", ret);
+ goto unregister_event;
+ }
+
+ return ret;
+
+unregister_event:
+ dln2_unregister_event_cb(pdev, DLN2_ADC_CONDITION_MET_EV);
+
+ return ret;
+}
+
+static int dln2_adc_remove(struct platform_device *pdev)
+{
+ struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+
+ iio_device_unregister(indio_dev);
+ dln2_unregister_event_cb(pdev, DLN2_ADC_CONDITION_MET_EV);
+ return 0;
+}
+
+static struct platform_driver dln2_adc_driver = {
+ .driver.name = DLN2_ADC_MOD_NAME,
+ .probe = dln2_adc_probe,
+ .remove = dln2_adc_remove,
+};
+
+module_platform_driver(dln2_adc_driver);
+
+MODULE_AUTHOR("Jack Andersen <jackoalan@gmail.com");
+MODULE_DESCRIPTION("Driver for the Diolan DLN2 ADC interface");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:dln2-adc");
diff --git a/drivers/iio/adc/ep93xx_adc.c b/drivers/iio/adc/ep93xx_adc.c
new file mode 100644
index 0000000..a179ac4
--- /dev/null
+++ b/drivers/iio/adc/ep93xx_adc.c
@@ -0,0 +1,255 @@
+/*
+ * Driver for ADC module on the Cirrus Logic EP93xx series of SoCs
+ *
+ * Copyright (C) 2015 Alexander Sverdlin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * The driver uses polling to get the conversion status. According to EP93xx
+ * datasheets, reading ADCResult register starts the conversion, but user is also
+ * responsible for ensuring that delay between adjacent conversion triggers is
+ * long enough so that maximum allowed conversion rate is not exceeded. This
+ * basically renders IRQ mode unusable.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/iio/iio.h>
+#include <linux/io.h>
+#include <linux/irqflags.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+
+/*
+ * This code could benefit from real HR Timers, but jiffy granularity would
+ * lower ADC conversion rate down to CONFIG_HZ, so we fallback to busy wait
+ * in such case.
+ *
+ * HR Timers-based version loads CPU only up to 10% during back to back ADC
+ * conversion, while busy wait-based version consumes whole CPU power.
+ */
+#ifdef CONFIG_HIGH_RES_TIMERS
+#define ep93xx_adc_delay(usmin, usmax) usleep_range(usmin, usmax)
+#else
+#define ep93xx_adc_delay(usmin, usmax) udelay(usmin)
+#endif
+
+#define EP93XX_ADC_RESULT 0x08
+#define EP93XX_ADC_SDR BIT(31)
+#define EP93XX_ADC_SWITCH 0x18
+#define EP93XX_ADC_SW_LOCK 0x20
+
+struct ep93xx_adc_priv {
+ struct clk *clk;
+ void __iomem *base;
+ int lastch;
+ struct mutex lock;
+};
+
+#define EP93XX_ADC_CH(index, dname, swcfg) { \
+ .type = IIO_VOLTAGE, \
+ .indexed = 1, \
+ .channel = index, \
+ .address = swcfg, \
+ .datasheet_name = dname, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_OFFSET), \
+}
+
+/*
+ * Numbering scheme for channels 0..4 is defined in EP9301 and EP9302 datasheets.
+ * EP9307, EP9312 and EP9312 have 3 channels more (total 8), but the numbering is
+ * not defined. So the last three are numbered randomly, let's say.
+ */
+static const struct iio_chan_spec ep93xx_adc_channels[8] = {
+ EP93XX_ADC_CH(0, "YM", 0x608),
+ EP93XX_ADC_CH(1, "SXP", 0x680),
+ EP93XX_ADC_CH(2, "SXM", 0x640),
+ EP93XX_ADC_CH(3, "SYP", 0x620),
+ EP93XX_ADC_CH(4, "SYM", 0x610),
+ EP93XX_ADC_CH(5, "XP", 0x601),
+ EP93XX_ADC_CH(6, "XM", 0x602),
+ EP93XX_ADC_CH(7, "YP", 0x604),
+};
+
+static int ep93xx_read_raw(struct iio_dev *iiodev,
+ struct iio_chan_spec const *channel, int *value,
+ int *shift, long mask)
+{
+ struct ep93xx_adc_priv *priv = iio_priv(iiodev);
+ unsigned long timeout;
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ mutex_lock(&priv->lock);
+ if (priv->lastch != channel->channel) {
+ priv->lastch = channel->channel;
+ /*
+ * Switch register is software-locked, unlocking must be
+ * immediately followed by write
+ */
+ local_irq_disable();
+ writel_relaxed(0xAA, priv->base + EP93XX_ADC_SW_LOCK);
+ writel_relaxed(channel->address,
+ priv->base + EP93XX_ADC_SWITCH);
+ local_irq_enable();
+ /*
+ * Settling delay depends on module clock and could be
+ * 2ms or 500us
+ */
+ ep93xx_adc_delay(2000, 2000);
+ }
+ /* Start the conversion, eventually discarding old result */
+ readl_relaxed(priv->base + EP93XX_ADC_RESULT);
+ /* Ensure maximum conversion rate is not exceeded */
+ ep93xx_adc_delay(DIV_ROUND_UP(1000000, 925),
+ DIV_ROUND_UP(1000000, 925));
+ /* At this point conversion must be completed, but anyway... */
+ ret = IIO_VAL_INT;
+ timeout = jiffies + msecs_to_jiffies(1) + 1;
+ while (1) {
+ u32 t;
+
+ t = readl_relaxed(priv->base + EP93XX_ADC_RESULT);
+ if (t & EP93XX_ADC_SDR) {
+ *value = sign_extend32(t, 15);
+ break;
+ }
+
+ if (time_after(jiffies, timeout)) {
+ dev_err(&iiodev->dev, "Conversion timeout\n");
+ ret = -ETIMEDOUT;
+ break;
+ }
+
+ cpu_relax();
+ }
+ mutex_unlock(&priv->lock);
+ return ret;
+
+ case IIO_CHAN_INFO_OFFSET:
+ /* According to datasheet, range is -25000..25000 */
+ *value = 25000;
+ return IIO_VAL_INT;
+
+ case IIO_CHAN_INFO_SCALE:
+ /* Typical supply voltage is 3.3v */
+ *value = (1ULL << 32) * 3300 / 50000;
+ *shift = 32;
+ return IIO_VAL_FRACTIONAL_LOG2;
+ }
+
+ return -EINVAL;
+}
+
+static const struct iio_info ep93xx_adc_info = {
+ .driver_module = THIS_MODULE,
+ .read_raw = ep93xx_read_raw,
+};
+
+static int ep93xx_adc_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct iio_dev *iiodev;
+ struct ep93xx_adc_priv *priv;
+ struct clk *pclk;
+ struct resource *res;
+
+ iiodev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv));
+ if (!iiodev)
+ return -ENOMEM;
+ priv = iio_priv(iiodev);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "Cannot obtain memory resource\n");
+ return -ENXIO;
+ }
+ priv->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(priv->base)) {
+ dev_err(&pdev->dev, "Cannot map memory resource\n");
+ return PTR_ERR(priv->base);
+ }
+
+ iiodev->dev.parent = &pdev->dev;
+ iiodev->name = dev_name(&pdev->dev);
+ iiodev->modes = INDIO_DIRECT_MODE;
+ iiodev->info = &ep93xx_adc_info;
+ iiodev->num_channels = ARRAY_SIZE(ep93xx_adc_channels);
+ iiodev->channels = ep93xx_adc_channels;
+
+ priv->lastch = -1;
+ mutex_init(&priv->lock);
+
+ platform_set_drvdata(pdev, iiodev);
+
+ priv->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(priv->clk)) {
+ dev_err(&pdev->dev, "Cannot obtain clock\n");
+ return PTR_ERR(priv->clk);
+ }
+
+ pclk = clk_get_parent(priv->clk);
+ if (!pclk) {
+ dev_warn(&pdev->dev, "Cannot obtain parent clock\n");
+ } else {
+ /*
+ * This is actually a place for improvement:
+ * EP93xx ADC supports two clock divisors -- 4 and 16,
+ * resulting in conversion rates 3750 and 925 samples per second
+ * with 500us or 2ms settling time respectively.
+ * One might find this interesting enough to be configurable.
+ */
+ ret = clk_set_rate(priv->clk, clk_get_rate(pclk) / 16);
+ if (ret)
+ dev_warn(&pdev->dev, "Cannot set clock rate\n");
+ /*
+ * We can tolerate rate setting failure because the module should
+ * work in any case.
+ */
+ }
+
+ ret = clk_enable(priv->clk);
+ if (ret) {
+ dev_err(&pdev->dev, "Cannot enable clock\n");
+ return ret;
+ }
+
+ ret = iio_device_register(iiodev);
+ if (ret)
+ clk_disable(priv->clk);
+
+ return ret;
+}
+
+static int ep93xx_adc_remove(struct platform_device *pdev)
+{
+ struct iio_dev *iiodev = platform_get_drvdata(pdev);
+ struct ep93xx_adc_priv *priv = iio_priv(iiodev);
+
+ iio_device_unregister(iiodev);
+ clk_disable(priv->clk);
+
+ return 0;
+}
+
+static struct platform_driver ep93xx_adc_driver = {
+ .driver = {
+ .name = "ep93xx-adc",
+ },
+ .probe = ep93xx_adc_probe,
+ .remove = ep93xx_adc_remove,
+};
+module_platform_driver(ep93xx_adc_driver);
+
+MODULE_AUTHOR("Alexander Sverdlin <alexander.sverdlin@gmail.com>");
+MODULE_DESCRIPTION("Cirrus Logic EP93XX ADC driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ep93xx-adc");
diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c
index c3f8613..f387b97 100644
--- a/drivers/iio/adc/ina2xx-adc.c
+++ b/drivers/iio/adc/ina2xx-adc.c
@@ -44,6 +44,7 @@
#define INA226_MASK_ENABLE 0x06
#define INA226_CVRF BIT(3)
+#define INA219_CNVR BIT(1)
#define INA2XX_MAX_REGISTERS 8
@@ -592,6 +593,7 @@ static int ina2xx_work_buffer(struct iio_dev *indio_dev)
int bit, ret, i = 0;
s64 time_a, time_b;
unsigned int alert;
+ int cnvr_need_clear = 0;
time_a = iio_get_time_ns(indio_dev);
@@ -603,22 +605,30 @@ static int ina2xx_work_buffer(struct iio_dev *indio_dev)
* we check the ConVersionReadyFlag.
* On hardware that supports using the ALERT pin to toggle a
* GPIO a triggered buffer could be used instead.
- * For now, we pay for that extra read of the ALERT register
+ * For now, we do an extra read of the MASK_ENABLE register (INA226)
+ * resp. the BUS_VOLTAGE register (INA219).
*/
if (!chip->allow_async_readout)
do {
- ret = regmap_read(chip->regmap, INA226_MASK_ENABLE,
- &alert);
+ if (chip->config->chip_id == ina226) {
+ ret = regmap_read(chip->regmap,
+ INA226_MASK_ENABLE, &alert);
+ alert &= INA226_CVRF;
+ } else {
+ ret = regmap_read(chip->regmap,
+ INA2XX_BUS_VOLTAGE, &alert);
+ alert &= INA219_CNVR;
+ cnvr_need_clear = alert;
+ }
+
if (ret < 0)
return ret;
- alert &= INA226_CVRF;
} while (!alert);
/*
- * Single register reads: bulk_read will not work with ina226
- * as there is no auto-increment of the address register for
- * data length longer than 16bits.
+ * Single register reads: bulk_read will not work with ina226/219
+ * as there is no auto-increment of the register pointer.
*/
for_each_set_bit(bit, indio_dev->active_scan_mask,
indio_dev->masklength) {
@@ -630,6 +640,18 @@ static int ina2xx_work_buffer(struct iio_dev *indio_dev)
return ret;
data[i++] = val;
+
+ if (INA2XX_SHUNT_VOLTAGE + bit == INA2XX_POWER)
+ cnvr_need_clear = 0;
+ }
+
+ /* Dummy read on INA219 power register to clear CNVR flag */
+ if (cnvr_need_clear && chip->config->chip_id == ina219) {
+ unsigned int val;
+
+ ret = regmap_read(chip->regmap, INA2XX_POWER, &val);
+ if (ret < 0)
+ return ret;
}
time_b = iio_get_time_ns(indio_dev);
diff --git a/drivers/iio/adc/ltc2471.c b/drivers/iio/adc/ltc2471.c
new file mode 100644
index 0000000..29b7ed6
--- /dev/null
+++ b/drivers/iio/adc/ltc2471.c
@@ -0,0 +1,160 @@
+/*
+ * Driver for Linear Technology LTC2471 and LTC2473 voltage monitors
+ * The LTC2473 is identical to the 2471, but reports a differential signal.
+ *
+ * Copyright (C) 2017 Topic Embedded Products
+ * Author: Mike Looijmans <mike.looijmans@topic.nl>
+ *
+ * License: GPLv2
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+enum ltc2471_chips {
+ ltc2471,
+ ltc2473,
+};
+
+struct ltc2471_data {
+ struct i2c_client *client;
+};
+
+/* Reference voltage is 1.25V */
+#define LTC2471_VREF 1250
+
+/* Read two bytes from the I2C bus to obtain the ADC result */
+static int ltc2471_get_value(struct i2c_client *client)
+{
+ int ret;
+ __be16 buf;
+
+ ret = i2c_master_recv(client, (char *)&buf, sizeof(buf));
+ if (ret < 0)
+ return ret;
+ if (ret != sizeof(buf))
+ return -EIO;
+
+ /* MSB first */
+ return be16_to_cpu(buf);
+}
+
+static int ltc2471_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long info)
+{
+ struct ltc2471_data *data = iio_priv(indio_dev);
+ int ret;
+
+ switch (info) {
+ case IIO_CHAN_INFO_RAW:
+ ret = ltc2471_get_value(data->client);
+ if (ret < 0)
+ return ret;
+ *val = ret;
+ return IIO_VAL_INT;
+
+ case IIO_CHAN_INFO_SCALE:
+ if (chan->differential)
+ /* Output ranges from -VREF to +VREF */
+ *val = 2 * LTC2471_VREF;
+ else
+ /* Output ranges from 0 to VREF */
+ *val = LTC2471_VREF;
+ *val2 = 16; /* 16 data bits */
+ return IIO_VAL_FRACTIONAL_LOG2;
+
+ case IIO_CHAN_INFO_OFFSET:
+ /* Only differential chip has this property */
+ *val = -LTC2471_VREF;
+ return IIO_VAL_INT;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct iio_chan_spec ltc2471_channel[] = {
+ {
+ .type = IIO_VOLTAGE,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
+ },
+};
+
+static const struct iio_chan_spec ltc2473_channel[] = {
+ {
+ .type = IIO_VOLTAGE,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_OFFSET),
+ .differential = 1,
+ },
+};
+
+static const struct iio_info ltc2471_info = {
+ .read_raw = ltc2471_read_raw,
+ .driver_module = THIS_MODULE,
+};
+
+static int ltc2471_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct iio_dev *indio_dev;
+ struct ltc2471_data *data;
+ int ret;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+ return -EOPNOTSUPP;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ data = iio_priv(indio_dev);
+ data->client = client;
+
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->name = id->name;
+ indio_dev->info = &ltc2471_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ if (id->driver_data == ltc2473)
+ indio_dev->channels = ltc2473_channel;
+ else
+ indio_dev->channels = ltc2471_channel;
+ indio_dev->num_channels = 1;
+
+ /* Trigger once to start conversion and check if chip is there */
+ ret = ltc2471_get_value(client);
+ if (ret < 0) {
+ dev_err(&client->dev, "Cannot read from device.\n");
+ return ret;
+ }
+
+ return devm_iio_device_register(&client->dev, indio_dev);
+}
+
+static const struct i2c_device_id ltc2471_i2c_id[] = {
+ { "ltc2471", ltc2471 },
+ { "ltc2473", ltc2473 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, ltc2471_i2c_id);
+
+static struct i2c_driver ltc2471_i2c_driver = {
+ .driver = {
+ .name = "ltc2471",
+ },
+ .probe = ltc2471_i2c_probe,
+ .id_table = ltc2471_i2c_id,
+};
+
+module_i2c_driver(ltc2471_i2c_driver);
+
+MODULE_DESCRIPTION("LTC2471/LTC2473 ADC driver");
+MODULE_AUTHOR("Topic Embedded Products");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/adc/ltc2497.c b/drivers/iio/adc/ltc2497.c
index 2691b10..5bf8011 100644
--- a/drivers/iio/adc/ltc2497.c
+++ b/drivers/iio/adc/ltc2497.c
@@ -11,6 +11,7 @@
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/iio/iio.h>
+#include <linux/iio/driver.h>
#include <linux/iio/sysfs.h>
#include <linux/module.h>
#include <linux/of.h>
@@ -127,13 +128,14 @@ static int ltc2497_read_raw(struct iio_dev *indio_dev,
}
}
-#define LTC2497_CHAN(_chan, _addr) { \
+#define LTC2497_CHAN(_chan, _addr, _ds_name) { \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.channel = (_chan), \
.address = (_addr | (_chan / 2) | ((_chan & 1) ? LTC2497_SIGN : 0)), \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+ .datasheet_name = (_ds_name), \
}
#define LTC2497_CHAN_DIFF(_chan, _addr) { \
@@ -148,22 +150,22 @@ static int ltc2497_read_raw(struct iio_dev *indio_dev,
}
static const struct iio_chan_spec ltc2497_channel[] = {
- LTC2497_CHAN(0, LTC2497_SGL),
- LTC2497_CHAN(1, LTC2497_SGL),
- LTC2497_CHAN(2, LTC2497_SGL),
- LTC2497_CHAN(3, LTC2497_SGL),
- LTC2497_CHAN(4, LTC2497_SGL),
- LTC2497_CHAN(5, LTC2497_SGL),
- LTC2497_CHAN(6, LTC2497_SGL),
- LTC2497_CHAN(7, LTC2497_SGL),
- LTC2497_CHAN(8, LTC2497_SGL),
- LTC2497_CHAN(9, LTC2497_SGL),
- LTC2497_CHAN(10, LTC2497_SGL),
- LTC2497_CHAN(11, LTC2497_SGL),
- LTC2497_CHAN(12, LTC2497_SGL),
- LTC2497_CHAN(13, LTC2497_SGL),
- LTC2497_CHAN(14, LTC2497_SGL),
- LTC2497_CHAN(15, LTC2497_SGL),
+ LTC2497_CHAN(0, LTC2497_SGL, "CH0"),
+ LTC2497_CHAN(1, LTC2497_SGL, "CH1"),
+ LTC2497_CHAN(2, LTC2497_SGL, "CH2"),
+ LTC2497_CHAN(3, LTC2497_SGL, "CH3"),
+ LTC2497_CHAN(4, LTC2497_SGL, "CH4"),
+ LTC2497_CHAN(5, LTC2497_SGL, "CH5"),
+ LTC2497_CHAN(6, LTC2497_SGL, "CH6"),
+ LTC2497_CHAN(7, LTC2497_SGL, "CH7"),
+ LTC2497_CHAN(8, LTC2497_SGL, "CH8"),
+ LTC2497_CHAN(9, LTC2497_SGL, "CH9"),
+ LTC2497_CHAN(10, LTC2497_SGL, "CH10"),
+ LTC2497_CHAN(11, LTC2497_SGL, "CH11"),
+ LTC2497_CHAN(12, LTC2497_SGL, "CH12"),
+ LTC2497_CHAN(13, LTC2497_SGL, "CH13"),
+ LTC2497_CHAN(14, LTC2497_SGL, "CH14"),
+ LTC2497_CHAN(15, LTC2497_SGL, "CH15"),
LTC2497_CHAN_DIFF(0, LTC2497_DIFF),
LTC2497_CHAN_DIFF(1, LTC2497_DIFF),
LTC2497_CHAN_DIFF(2, LTC2497_DIFF),
@@ -192,6 +194,7 @@ static int ltc2497_probe(struct i2c_client *client,
{
struct iio_dev *indio_dev;
struct ltc2497_st *st;
+ struct iio_map *plat_data;
int ret;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
@@ -221,19 +224,31 @@ static int ltc2497_probe(struct i2c_client *client,
if (ret < 0)
return ret;
+ if (client->dev.platform_data) {
+ plat_data = ((struct iio_map *)client->dev.platform_data);
+ ret = iio_map_array_register(indio_dev, plat_data);
+ if (ret) {
+ dev_err(&indio_dev->dev, "iio map err: %d\n", ret);
+ goto err_regulator_disable;
+ }
+ }
+
ret = i2c_smbus_write_byte(st->client, LTC2497_CONFIG_DEFAULT);
if (ret < 0)
- goto err_regulator_disable;
+ goto err_array_unregister;
st->addr_prev = LTC2497_CONFIG_DEFAULT;
st->time_prev = ktime_get();
ret = iio_device_register(indio_dev);
if (ret < 0)
- goto err_regulator_disable;
+ goto err_array_unregister;
return 0;
+err_array_unregister:
+ iio_map_array_unregister(indio_dev);
+
err_regulator_disable:
regulator_disable(st->ref);
@@ -245,6 +260,7 @@ static int ltc2497_remove(struct i2c_client *client)
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct ltc2497_st *st = iio_priv(indio_dev);
+ iio_map_array_unregister(indio_dev);
iio_device_unregister(indio_dev);
regulator_disable(st->ref);
diff --git a/drivers/iio/adc/max9611.c b/drivers/iio/adc/max9611.c
index b0526e4..b1dd17c 100644
--- a/drivers/iio/adc/max9611.c
+++ b/drivers/iio/adc/max9611.c
@@ -549,8 +549,8 @@ static int max9611_probe(struct i2c_client *client,
ret = of_property_read_u32(of_node, shunt_res_prop, &of_shunt);
if (ret) {
dev_err(&client->dev,
- "Missing %s property for %s node\n",
- shunt_res_prop, of_node->full_name);
+ "Missing %s property for %pOF node\n",
+ shunt_res_prop, of_node);
return ret;
}
max9611->shunt_resistor_uohm = of_shunt;
diff --git a/drivers/iio/adc/mcp3422.c b/drivers/iio/adc/mcp3422.c
index 254135e..63de705 100644
--- a/drivers/iio/adc/mcp3422.c
+++ b/drivers/iio/adc/mcp3422.c
@@ -379,10 +379,12 @@ static int mcp3422_probe(struct i2c_client *client,
/* meaningful default configuration */
config = (MCP3422_CONT_SAMPLING
- | MCP3422_CHANNEL_VALUE(1)
+ | MCP3422_CHANNEL_VALUE(0)
| MCP3422_PGA_VALUE(MCP3422_PGA_1)
| MCP3422_SAMPLE_RATE_VALUE(MCP3422_SRATE_240));
- mcp3422_update_config(adc, config);
+ err = mcp3422_update_config(adc, config);
+ if (err < 0)
+ return err;
err = devm_iio_device_register(&client->dev, indio_dev);
if (err < 0)
diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c
index 83da50e..2e8dbb8 100644
--- a/drivers/iio/adc/meson_saradc.c
+++ b/drivers/iio/adc/meson_saradc.c
@@ -572,8 +572,8 @@ static int meson_sar_adc_clk_init(struct iio_dev *indio_dev,
struct clk_init_data init;
const char *clk_parents[1];
- init.name = devm_kasprintf(&indio_dev->dev, GFP_KERNEL, "%s#adc_div",
- of_node_full_name(indio_dev->dev.of_node));
+ init.name = devm_kasprintf(&indio_dev->dev, GFP_KERNEL, "%pOF#adc_div",
+ indio_dev->dev.of_node);
init.flags = 0;
init.ops = &clk_divider_ops;
clk_parents[0] = __clk_get_name(priv->clkin);
@@ -591,8 +591,8 @@ static int meson_sar_adc_clk_init(struct iio_dev *indio_dev,
if (WARN_ON(IS_ERR(priv->adc_div_clk)))
return PTR_ERR(priv->adc_div_clk);
- init.name = devm_kasprintf(&indio_dev->dev, GFP_KERNEL, "%s#adc_en",
- of_node_full_name(indio_dev->dev.of_node));
+ init.name = devm_kasprintf(&indio_dev->dev, GFP_KERNEL, "%pOF#adc_en",
+ indio_dev->dev.of_node);
init.flags = CLK_SET_RATE_PARENT;
init.ops = &clk_gate_ops;
clk_parents[0] = __clk_get_name(priv->adc_div_clk);
@@ -915,6 +915,11 @@ static int meson_sar_adc_probe(struct platform_device *pdev)
init_completion(&priv->done);
match = of_match_device(meson_sar_adc_of_match, &pdev->dev);
+ if (!match) {
+ dev_err(&pdev->dev, "failed to match device\n");
+ return -ENODEV;
+ }
+
priv->data = match->data;
indio_dev->name = priv->data->name;
diff --git a/drivers/iio/adc/mt6577_auxadc.c b/drivers/iio/adc/mt6577_auxadc.c
index 2d104c8..414cf44 100644
--- a/drivers/iio/adc/mt6577_auxadc.c
+++ b/drivers/iio/adc/mt6577_auxadc.c
@@ -184,6 +184,37 @@ static const struct iio_info mt6577_auxadc_info = {
.read_raw = &mt6577_auxadc_read_raw,
};
+static int __maybe_unused mt6577_auxadc_resume(struct device *dev)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct mt6577_auxadc_device *adc_dev = iio_priv(indio_dev);
+ int ret;
+
+ ret = clk_prepare_enable(adc_dev->adc_clk);
+ if (ret) {
+ pr_err("failed to enable auxadc clock\n");
+ return ret;
+ }
+
+ mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC,
+ MT6577_AUXADC_PDN_EN, 0);
+ mdelay(MT6577_AUXADC_POWER_READY_MS);
+
+ return 0;
+}
+
+static int __maybe_unused mt6577_auxadc_suspend(struct device *dev)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct mt6577_auxadc_device *adc_dev = iio_priv(indio_dev);
+
+ mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC,
+ 0, MT6577_AUXADC_PDN_EN);
+ clk_disable_unprepare(adc_dev->adc_clk);
+
+ return 0;
+}
+
static int mt6577_auxadc_probe(struct platform_device *pdev)
{
struct mt6577_auxadc_device *adc_dev;
@@ -269,8 +300,13 @@ static int mt6577_auxadc_remove(struct platform_device *pdev)
return 0;
}
+static SIMPLE_DEV_PM_OPS(mt6577_auxadc_pm_ops,
+ mt6577_auxadc_suspend,
+ mt6577_auxadc_resume);
+
static const struct of_device_id mt6577_auxadc_of_match[] = {
{ .compatible = "mediatek,mt2701-auxadc", },
+ { .compatible = "mediatek,mt7622-auxadc", },
{ .compatible = "mediatek,mt8173-auxadc", },
{ }
};
@@ -280,6 +316,7 @@ static struct platform_driver mt6577_auxadc_driver = {
.driver = {
.name = "mt6577-auxadc",
.of_match_table = mt6577_auxadc_of_match,
+ .pm = &mt6577_auxadc_pm_ops,
},
.probe = mt6577_auxadc_probe,
.remove = mt6577_auxadc_remove,
diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c
index ae6d332..5f612d6 100644
--- a/drivers/iio/adc/rockchip_saradc.c
+++ b/drivers/iio/adc/rockchip_saradc.c
@@ -224,6 +224,11 @@ static int rockchip_saradc_probe(struct platform_device *pdev)
info = iio_priv(indio_dev);
match = of_match_device(rockchip_saradc_match, &pdev->dev);
+ if (!match) {
+ dev_err(&pdev->dev, "failed to match device\n");
+ return -ENODEV;
+ }
+
info->data = match->data;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -235,7 +240,8 @@ static int rockchip_saradc_probe(struct platform_device *pdev)
* The reset should be an optional property, as it should work
* with old devicetrees as well
*/
- info->reset = devm_reset_control_get(&pdev->dev, "saradc-apb");
+ info->reset = devm_reset_control_get_exclusive(&pdev->dev,
+ "saradc-apb");
if (IS_ERR(info->reset)) {
ret = PTR_ERR(info->reset);
if (ret != -ENOENT)
diff --git a/drivers/iio/adc/stm32-adc-core.c b/drivers/iio/adc/stm32-adc-core.c
index 6096763..804198e 100644
--- a/drivers/iio/adc/stm32-adc-core.c
+++ b/drivers/iio/adc/stm32-adc-core.c
@@ -172,7 +172,7 @@ struct stm32h7_adc_ck_spec {
int div;
};
-const struct stm32h7_adc_ck_spec stm32h7_adc_ckmodes_spec[] = {
+static const struct stm32h7_adc_ck_spec stm32h7_adc_ckmodes_spec[] = {
/* 00: CK_ADC[1..3]: Asynchronous clock modes */
{ 0, 0, 1 },
{ 0, 1, 2 },
diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c
index 5bfcc1f..6bc6028 100644
--- a/drivers/iio/adc/stm32-adc.c
+++ b/drivers/iio/adc/stm32-adc.c
@@ -83,6 +83,8 @@
#define STM32H7_ADC_IER 0x04
#define STM32H7_ADC_CR 0x08
#define STM32H7_ADC_CFGR 0x0C
+#define STM32H7_ADC_SMPR1 0x14
+#define STM32H7_ADC_SMPR2 0x18
#define STM32H7_ADC_PCSEL 0x1C
#define STM32H7_ADC_SQR1 0x30
#define STM32H7_ADC_SQR2 0x34
@@ -151,6 +153,7 @@ enum stm32h7_adc_dmngt {
#define STM32H7_BOOST_CLKRATE 20000000UL
#define STM32_ADC_MAX_SQ 16 /* SQ1..SQ16 */
+#define STM32_ADC_MAX_SMP 7 /* SMPx range is [0..7] */
#define STM32_ADC_TIMEOUT_US 100000
#define STM32_ADC_TIMEOUT (msecs_to_jiffies(STM32_ADC_TIMEOUT_US / 1000))
@@ -227,6 +230,8 @@ struct stm32_adc_regs {
* @exten: trigger control register & bitfield
* @extsel: trigger selection register & bitfield
* @res: resolution selection register & bitfield
+ * @smpr: smpr1 & smpr2 registers offset array
+ * @smp_bits: smpr1 & smpr2 index and bitfields
*/
struct stm32_adc_regspec {
const u32 dr;
@@ -236,6 +241,8 @@ struct stm32_adc_regspec {
const struct stm32_adc_regs exten;
const struct stm32_adc_regs extsel;
const struct stm32_adc_regs res;
+ const u32 smpr[2];
+ const struct stm32_adc_regs *smp_bits;
};
struct stm32_adc;
@@ -251,6 +258,7 @@ struct stm32_adc;
* @start_conv: routine to start conversions
* @stop_conv: routine to stop conversions
* @unprepare: optional unprepare routine (disable, power-down)
+ * @smp_cycles: programmable sampling time (ADC clock cycles)
*/
struct stm32_adc_cfg {
const struct stm32_adc_regspec *regs;
@@ -262,6 +270,7 @@ struct stm32_adc_cfg {
void (*start_conv)(struct stm32_adc *, bool dma);
void (*stop_conv)(struct stm32_adc *);
void (*unprepare)(struct stm32_adc *);
+ const unsigned int *smp_cycles;
};
/**
@@ -283,6 +292,7 @@ struct stm32_adc_cfg {
* @rx_dma_buf: dma rx buffer bus address
* @rx_buf_sz: dma rx buffer size
* @pcsel bitmask to preselect channels on some devices
+ * @smpr_val: sampling time settings (e.g. smpr1 / smpr2)
* @cal: optional calibration data on some devices
*/
struct stm32_adc {
@@ -303,6 +313,7 @@ struct stm32_adc {
dma_addr_t rx_dma_buf;
unsigned int rx_buf_sz;
u32 pcsel;
+ u32 smpr_val[2];
struct stm32_adc_calib cal;
};
@@ -431,6 +442,39 @@ static struct stm32_adc_trig_info stm32f4_adc_trigs[] = {
{}, /* sentinel */
};
+/**
+ * stm32f4_smp_bits[] - describe sampling time register index & bit fields
+ * Sorted so it can be indexed by channel number.
+ */
+static const struct stm32_adc_regs stm32f4_smp_bits[] = {
+ /* STM32F4_ADC_SMPR2: smpr[] index, mask, shift for SMP0 to SMP9 */
+ { 1, GENMASK(2, 0), 0 },
+ { 1, GENMASK(5, 3), 3 },
+ { 1, GENMASK(8, 6), 6 },
+ { 1, GENMASK(11, 9), 9 },
+ { 1, GENMASK(14, 12), 12 },
+ { 1, GENMASK(17, 15), 15 },
+ { 1, GENMASK(20, 18), 18 },
+ { 1, GENMASK(23, 21), 21 },
+ { 1, GENMASK(26, 24), 24 },
+ { 1, GENMASK(29, 27), 27 },
+ /* STM32F4_ADC_SMPR1, smpr[] index, mask, shift for SMP10 to SMP18 */
+ { 0, GENMASK(2, 0), 0 },
+ { 0, GENMASK(5, 3), 3 },
+ { 0, GENMASK(8, 6), 6 },
+ { 0, GENMASK(11, 9), 9 },
+ { 0, GENMASK(14, 12), 12 },
+ { 0, GENMASK(17, 15), 15 },
+ { 0, GENMASK(20, 18), 18 },
+ { 0, GENMASK(23, 21), 21 },
+ { 0, GENMASK(26, 24), 24 },
+};
+
+/* STM32F4 programmable sampling time (ADC clock cycles) */
+static const unsigned int stm32f4_adc_smp_cycles[STM32_ADC_MAX_SMP + 1] = {
+ 3, 15, 28, 56, 84, 112, 144, 480,
+};
+
static const struct stm32_adc_regspec stm32f4_adc_regspec = {
.dr = STM32F4_ADC_DR,
.ier_eoc = { STM32F4_ADC_CR1, STM32F4_EOCIE },
@@ -440,6 +484,8 @@ static const struct stm32_adc_regspec stm32f4_adc_regspec = {
.extsel = { STM32F4_ADC_CR2, STM32F4_EXTSEL_MASK,
STM32F4_EXTSEL_SHIFT },
.res = { STM32F4_ADC_CR1, STM32F4_RES_MASK, STM32F4_RES_SHIFT },
+ .smpr = { STM32F4_ADC_SMPR1, STM32F4_ADC_SMPR2 },
+ .smp_bits = stm32f4_smp_bits,
};
static const struct stm32_adc_regs stm32h7_sq[STM32_ADC_MAX_SQ + 1] = {
@@ -483,6 +529,40 @@ static struct stm32_adc_trig_info stm32h7_adc_trigs[] = {
{},
};
+/**
+ * stm32h7_smp_bits - describe sampling time register index & bit fields
+ * Sorted so it can be indexed by channel number.
+ */
+static const struct stm32_adc_regs stm32h7_smp_bits[] = {
+ /* STM32H7_ADC_SMPR1, smpr[] index, mask, shift for SMP0 to SMP9 */
+ { 0, GENMASK(2, 0), 0 },
+ { 0, GENMASK(5, 3), 3 },
+ { 0, GENMASK(8, 6), 6 },
+ { 0, GENMASK(11, 9), 9 },
+ { 0, GENMASK(14, 12), 12 },
+ { 0, GENMASK(17, 15), 15 },
+ { 0, GENMASK(20, 18), 18 },
+ { 0, GENMASK(23, 21), 21 },
+ { 0, GENMASK(26, 24), 24 },
+ { 0, GENMASK(29, 27), 27 },
+ /* STM32H7_ADC_SMPR2, smpr[] index, mask, shift for SMP10 to SMP19 */
+ { 1, GENMASK(2, 0), 0 },
+ { 1, GENMASK(5, 3), 3 },
+ { 1, GENMASK(8, 6), 6 },
+ { 1, GENMASK(11, 9), 9 },
+ { 1, GENMASK(14, 12), 12 },
+ { 1, GENMASK(17, 15), 15 },
+ { 1, GENMASK(20, 18), 18 },
+ { 1, GENMASK(23, 21), 21 },
+ { 1, GENMASK(26, 24), 24 },
+ { 1, GENMASK(29, 27), 27 },
+};
+
+/* STM32H7 programmable sampling time (ADC clock cycles, rounded down) */
+static const unsigned int stm32h7_adc_smp_cycles[STM32_ADC_MAX_SMP + 1] = {
+ 1, 2, 8, 16, 32, 64, 387, 810,
+};
+
static const struct stm32_adc_regspec stm32h7_adc_regspec = {
.dr = STM32H7_ADC_DR,
.ier_eoc = { STM32H7_ADC_IER, STM32H7_EOCIE },
@@ -492,6 +572,8 @@ static const struct stm32_adc_regspec stm32h7_adc_regspec = {
.extsel = { STM32H7_ADC_CFGR, STM32H7_EXTSEL_MASK,
STM32H7_EXTSEL_SHIFT },
.res = { STM32H7_ADC_CFGR, STM32H7_RES_MASK, STM32H7_RES_SHIFT },
+ .smpr = { STM32H7_ADC_SMPR1, STM32H7_ADC_SMPR2 },
+ .smp_bits = stm32h7_smp_bits,
};
/**
@@ -933,6 +1015,7 @@ static void stm32h7_adc_unprepare(struct stm32_adc *adc)
* @scan_mask: channels to be converted
*
* Conversion sequence :
+ * Apply sampling time settings for all channels.
* Configure ADC scan sequence based on selected channels in scan_mask.
* Add channels to SQR registers, from scan_mask LSB to MSB, then
* program sequence len.
@@ -946,6 +1029,10 @@ static int stm32_adc_conf_scan_seq(struct iio_dev *indio_dev,
u32 val, bit;
int i = 0;
+ /* Apply sampling time settings */
+ stm32_adc_writel(adc, adc->cfg->regs->smpr[0], adc->smpr_val[0]);
+ stm32_adc_writel(adc, adc->cfg->regs->smpr[1], adc->smpr_val[1]);
+
for_each_set_bit(bit, scan_mask, indio_dev->masklength) {
chan = indio_dev->channels + bit;
/*
@@ -1079,6 +1166,7 @@ static const struct iio_enum stm32_adc_trig_pol = {
* @res: conversion result
*
* The function performs a single conversion on a given channel:
+ * - Apply sampling time settings
* - Program sequencer with one channel (e.g. in SQ1 with len = 1)
* - Use SW trigger
* - Start conversion, then wait for interrupt completion.
@@ -1103,6 +1191,10 @@ static int stm32_adc_single_conv(struct iio_dev *indio_dev,
return ret;
}
+ /* Apply sampling time settings */
+ stm32_adc_writel(adc, regs->smpr[0], adc->smpr_val[0]);
+ stm32_adc_writel(adc, regs->smpr[1], adc->smpr_val[1]);
+
/* Program chan number in regular sequence (SQ1) */
val = stm32_adc_readl(adc, regs->sqr[1].reg);
val &= ~regs->sqr[1].mask;
@@ -1507,10 +1599,28 @@ static int stm32_adc_of_get_resolution(struct iio_dev *indio_dev)
return 0;
}
+static void stm32_adc_smpr_init(struct stm32_adc *adc, int channel, u32 smp_ns)
+{
+ const struct stm32_adc_regs *smpr = &adc->cfg->regs->smp_bits[channel];
+ u32 period_ns, shift = smpr->shift, mask = smpr->mask;
+ unsigned int smp, r = smpr->reg;
+
+ /* Determine sampling time (ADC clock cycles) */
+ period_ns = NSEC_PER_SEC / adc->common->rate;
+ for (smp = 0; smp <= STM32_ADC_MAX_SMP; smp++)
+ if ((period_ns * adc->cfg->smp_cycles[smp]) >= smp_ns)
+ break;
+ if (smp > STM32_ADC_MAX_SMP)
+ smp = STM32_ADC_MAX_SMP;
+
+ /* pre-build sampling time registers (e.g. smpr1, smpr2) */
+ adc->smpr_val[r] = (adc->smpr_val[r] & ~mask) | (smp << shift);
+}
+
static void stm32_adc_chan_init_one(struct iio_dev *indio_dev,
struct iio_chan_spec *chan,
const struct stm32_adc_chan_spec *channel,
- int scan_index)
+ int scan_index, u32 smp)
{
struct stm32_adc *adc = iio_priv(indio_dev);
@@ -1526,6 +1636,9 @@ static void stm32_adc_chan_init_one(struct iio_dev *indio_dev,
chan->scan_type.storagebits = 16;
chan->ext_info = stm32_adc_ext_info;
+ /* Prepare sampling time settings */
+ stm32_adc_smpr_init(adc, chan->channel, smp);
+
/* pre-build selected channels mask */
adc->pcsel |= BIT(chan->channel);
}
@@ -1538,8 +1651,8 @@ static int stm32_adc_chan_of_init(struct iio_dev *indio_dev)
struct property *prop;
const __be32 *cur;
struct iio_chan_spec *channels;
- int scan_index = 0, num_channels;
- u32 val;
+ int scan_index = 0, num_channels, ret;
+ u32 val, smp = 0;
num_channels = of_property_count_u32_elems(node, "st,adc-channels");
if (num_channels < 0 ||
@@ -1548,6 +1661,13 @@ static int stm32_adc_chan_of_init(struct iio_dev *indio_dev)
return num_channels < 0 ? num_channels : -EINVAL;
}
+ /* Optional sample time is provided either for each, or all channels */
+ ret = of_property_count_u32_elems(node, "st,min-sample-time-nsecs");
+ if (ret > 1 && ret != num_channels) {
+ dev_err(&indio_dev->dev, "Invalid st,min-sample-time-nsecs\n");
+ return -EINVAL;
+ }
+
channels = devm_kcalloc(&indio_dev->dev, num_channels,
sizeof(struct iio_chan_spec), GFP_KERNEL);
if (!channels)
@@ -1558,9 +1678,19 @@ static int stm32_adc_chan_of_init(struct iio_dev *indio_dev)
dev_err(&indio_dev->dev, "Invalid channel %d\n", val);
return -EINVAL;
}
+
+ /*
+ * Using of_property_read_u32_index(), smp value will only be
+ * modified if valid u32 value can be decoded. This allows to
+ * get either no value, 1 shared value for all indexes, or one
+ * value per channel.
+ */
+ of_property_read_u32_index(node, "st,min-sample-time-nsecs",
+ scan_index, &smp);
+
stm32_adc_chan_init_one(indio_dev, &channels[scan_index],
&adc_info->channels[val],
- scan_index);
+ scan_index, smp);
scan_index++;
}
@@ -1755,6 +1885,7 @@ static const struct stm32_adc_cfg stm32f4_adc_cfg = {
.clk_required = true,
.start_conv = stm32f4_adc_start_conv,
.stop_conv = stm32f4_adc_stop_conv,
+ .smp_cycles = stm32f4_adc_smp_cycles,
};
static const struct stm32_adc_cfg stm32h7_adc_cfg = {
@@ -1766,6 +1897,7 @@ static const struct stm32_adc_cfg stm32h7_adc_cfg = {
.stop_conv = stm32h7_adc_stop_conv,
.prepare = stm32h7_adc_prepare,
.unprepare = stm32h7_adc_unprepare,
+ .smp_cycles = stm32h7_adc_smp_cycles,
};
static const struct of_device_id stm32_adc_of_match[] = {
diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c
index 884b8e46..d121002 100644
--- a/drivers/iio/adc/ti-ads1015.c
+++ b/drivers/iio/adc/ti-ads1015.c
@@ -17,6 +17,7 @@
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/init.h>
+#include <linux/irq.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/pm_runtime.h>
@@ -28,6 +29,7 @@
#include <linux/iio/iio.h>
#include <linux/iio/types.h>
#include <linux/iio/sysfs.h>
+#include <linux/iio/events.h>
#include <linux/iio/buffer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/trigger_consumer.h>
@@ -36,17 +38,38 @@
#define ADS1015_CONV_REG 0x00
#define ADS1015_CFG_REG 0x01
+#define ADS1015_LO_THRESH_REG 0x02
+#define ADS1015_HI_THRESH_REG 0x03
+#define ADS1015_CFG_COMP_QUE_SHIFT 0
+#define ADS1015_CFG_COMP_LAT_SHIFT 2
+#define ADS1015_CFG_COMP_POL_SHIFT 3
+#define ADS1015_CFG_COMP_MODE_SHIFT 4
#define ADS1015_CFG_DR_SHIFT 5
#define ADS1015_CFG_MOD_SHIFT 8
#define ADS1015_CFG_PGA_SHIFT 9
#define ADS1015_CFG_MUX_SHIFT 12
+#define ADS1015_CFG_COMP_QUE_MASK GENMASK(1, 0)
+#define ADS1015_CFG_COMP_LAT_MASK BIT(2)
+#define ADS1015_CFG_COMP_POL_MASK BIT(2)
+#define ADS1015_CFG_COMP_MODE_MASK BIT(4)
#define ADS1015_CFG_DR_MASK GENMASK(7, 5)
#define ADS1015_CFG_MOD_MASK BIT(8)
#define ADS1015_CFG_PGA_MASK GENMASK(11, 9)
#define ADS1015_CFG_MUX_MASK GENMASK(14, 12)
+/* Comparator queue and disable field */
+#define ADS1015_CFG_COMP_DISABLE 3
+
+/* Comparator polarity field */
+#define ADS1015_CFG_COMP_POL_LOW 0
+#define ADS1015_CFG_COMP_POL_HIGH 1
+
+/* Comparator mode field */
+#define ADS1015_CFG_COMP_MODE_TRAD 0
+#define ADS1015_CFG_COMP_MODE_WINDOW 1
+
/* device operating modes */
#define ADS1015_CONTINUOUS 0
#define ADS1015_SINGLESHOT 1
@@ -81,18 +104,36 @@ static const unsigned int ads1115_data_rate[] = {
8, 16, 32, 64, 128, 250, 475, 860
};
-static const struct {
- int scale;
- int uscale;
-} ads1015_scale[] = {
- {3, 0},
- {2, 0},
- {1, 0},
- {0, 500000},
- {0, 250000},
- {0, 125000},
- {0, 125000},
- {0, 125000},
+/*
+ * Translation from PGA bits to full-scale positive and negative input voltage
+ * range in mV
+ */
+static int ads1015_fullscale_range[] = {
+ 6144, 4096, 2048, 1024, 512, 256, 256, 256
+};
+
+/*
+ * Translation from COMP_QUE field value to the number of successive readings
+ * exceed the threshold values before an interrupt is generated
+ */
+static const int ads1015_comp_queue[] = { 1, 2, 4 };
+
+static const struct iio_event_spec ads1015_events[] = {
+ {
+ .type = IIO_EV_TYPE_THRESH,
+ .dir = IIO_EV_DIR_RISING,
+ .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+ BIT(IIO_EV_INFO_ENABLE),
+ }, {
+ .type = IIO_EV_TYPE_THRESH,
+ .dir = IIO_EV_DIR_FALLING,
+ .mask_separate = BIT(IIO_EV_INFO_VALUE),
+ }, {
+ .type = IIO_EV_TYPE_THRESH,
+ .dir = IIO_EV_DIR_EITHER,
+ .mask_separate = BIT(IIO_EV_INFO_ENABLE) |
+ BIT(IIO_EV_INFO_PERIOD),
+ },
};
#define ADS1015_V_CHAN(_chan, _addr) { \
@@ -111,6 +152,8 @@ static const struct {
.shift = 4, \
.endianness = IIO_CPU, \
}, \
+ .event_spec = ads1015_events, \
+ .num_event_specs = ARRAY_SIZE(ads1015_events), \
.datasheet_name = "AIN"#_chan, \
}
@@ -132,6 +175,8 @@ static const struct {
.shift = 4, \
.endianness = IIO_CPU, \
}, \
+ .event_spec = ads1015_events, \
+ .num_event_specs = ARRAY_SIZE(ads1015_events), \
.datasheet_name = "AIN"#_chan"-AIN"#_chan2, \
}
@@ -150,6 +195,8 @@ static const struct {
.storagebits = 16, \
.endianness = IIO_CPU, \
}, \
+ .event_spec = ads1015_events, \
+ .num_event_specs = ARRAY_SIZE(ads1015_events), \
.datasheet_name = "AIN"#_chan, \
}
@@ -170,9 +217,17 @@ static const struct {
.storagebits = 16, \
.endianness = IIO_CPU, \
}, \
+ .event_spec = ads1015_events, \
+ .num_event_specs = ARRAY_SIZE(ads1015_events), \
.datasheet_name = "AIN"#_chan"-AIN"#_chan2, \
}
+struct ads1015_thresh_data {
+ unsigned int comp_queue;
+ int high_thresh;
+ int low_thresh;
+};
+
struct ads1015_data {
struct regmap *regmap;
/*
@@ -182,18 +237,54 @@ struct ads1015_data {
struct mutex lock;
struct ads1015_channel_data channel_data[ADS1015_CHANNELS];
+ unsigned int event_channel;
+ unsigned int comp_mode;
+ struct ads1015_thresh_data thresh_data[ADS1015_CHANNELS];
+
unsigned int *data_rate;
+ /*
+ * Set to true when the ADC is switched to the continuous-conversion
+ * mode and exits from a power-down state. This flag is used to avoid
+ * getting the stale result from the conversion register.
+ */
+ bool conv_invalid;
};
+static bool ads1015_event_channel_enabled(struct ads1015_data *data)
+{
+ return (data->event_channel != ADS1015_CHANNELS);
+}
+
+static void ads1015_event_channel_enable(struct ads1015_data *data, int chan,
+ int comp_mode)
+{
+ WARN_ON(ads1015_event_channel_enabled(data));
+
+ data->event_channel = chan;
+ data->comp_mode = comp_mode;
+}
+
+static void ads1015_event_channel_disable(struct ads1015_data *data, int chan)
+{
+ data->event_channel = ADS1015_CHANNELS;
+}
+
static bool ads1015_is_writeable_reg(struct device *dev, unsigned int reg)
{
- return (reg == ADS1015_CFG_REG);
+ switch (reg) {
+ case ADS1015_CFG_REG:
+ case ADS1015_LO_THRESH_REG:
+ case ADS1015_HI_THRESH_REG:
+ return true;
+ default:
+ return false;
+ }
}
static const struct regmap_config ads1015_regmap_config = {
.reg_bits = 8,
.val_bits = 16,
- .max_register = ADS1015_CFG_REG,
+ .max_register = ADS1015_HI_THRESH_REG,
.writeable_reg = ads1015_is_writeable_reg,
};
@@ -235,33 +326,51 @@ static int ads1015_set_power_state(struct ads1015_data *data, bool on)
ret = pm_runtime_put_autosuspend(dev);
}
- return ret;
+ return ret < 0 ? ret : 0;
}
static
int ads1015_get_adc_result(struct ads1015_data *data, int chan, int *val)
{
int ret, pga, dr, conv_time;
- bool change;
+ unsigned int old, mask, cfg;
if (chan < 0 || chan >= ADS1015_CHANNELS)
return -EINVAL;
+ ret = regmap_read(data->regmap, ADS1015_CFG_REG, &old);
+ if (ret)
+ return ret;
+
pga = data->channel_data[chan].pga;
dr = data->channel_data[chan].data_rate;
+ mask = ADS1015_CFG_MUX_MASK | ADS1015_CFG_PGA_MASK |
+ ADS1015_CFG_DR_MASK;
+ cfg = chan << ADS1015_CFG_MUX_SHIFT | pga << ADS1015_CFG_PGA_SHIFT |
+ dr << ADS1015_CFG_DR_SHIFT;
+
+ if (ads1015_event_channel_enabled(data)) {
+ mask |= ADS1015_CFG_COMP_QUE_MASK | ADS1015_CFG_COMP_MODE_MASK;
+ cfg |= data->thresh_data[chan].comp_queue <<
+ ADS1015_CFG_COMP_QUE_SHIFT |
+ data->comp_mode <<
+ ADS1015_CFG_COMP_MODE_SHIFT;
+ }
- ret = regmap_update_bits_check(data->regmap, ADS1015_CFG_REG,
- ADS1015_CFG_MUX_MASK |
- ADS1015_CFG_PGA_MASK,
- chan << ADS1015_CFG_MUX_SHIFT |
- pga << ADS1015_CFG_PGA_SHIFT,
- &change);
- if (ret < 0)
+ cfg = (old & ~mask) | (cfg & mask);
+
+ ret = regmap_write(data->regmap, ADS1015_CFG_REG, cfg);
+ if (ret)
return ret;
- if (change) {
- conv_time = DIV_ROUND_UP(USEC_PER_SEC, data->data_rate[dr]);
+ if (old != cfg || data->conv_invalid) {
+ int dr_old = (old & ADS1015_CFG_DR_MASK) >>
+ ADS1015_CFG_DR_SHIFT;
+
+ conv_time = DIV_ROUND_UP(USEC_PER_SEC, data->data_rate[dr_old]);
+ conv_time += DIV_ROUND_UP(USEC_PER_SEC, data->data_rate[dr]);
usleep_range(conv_time, conv_time + 1);
+ data->conv_invalid = false;
}
return regmap_read(data->regmap, ADS1015_CONV_REG, val);
@@ -298,52 +407,36 @@ err:
return IRQ_HANDLED;
}
-static int ads1015_set_scale(struct ads1015_data *data, int chan,
+static int ads1015_set_scale(struct ads1015_data *data,
+ struct iio_chan_spec const *chan,
int scale, int uscale)
{
- int i, ret, rindex = -1;
-
- for (i = 0; i < ARRAY_SIZE(ads1015_scale); i++)
- if (ads1015_scale[i].scale == scale &&
- ads1015_scale[i].uscale == uscale) {
- rindex = i;
- break;
+ int i;
+ int fullscale = div_s64((scale * 1000000LL + uscale) <<
+ (chan->scan_type.realbits - 1), 1000000);
+
+ for (i = 0; i < ARRAY_SIZE(ads1015_fullscale_range); i++) {
+ if (ads1015_fullscale_range[i] == fullscale) {
+ data->channel_data[chan->address].pga = i;
+ return 0;
}
- if (rindex < 0)
- return -EINVAL;
-
- ret = regmap_update_bits(data->regmap, ADS1015_CFG_REG,
- ADS1015_CFG_PGA_MASK,
- rindex << ADS1015_CFG_PGA_SHIFT);
- if (ret < 0)
- return ret;
-
- data->channel_data[chan].pga = rindex;
+ }
- return 0;
+ return -EINVAL;
}
static int ads1015_set_data_rate(struct ads1015_data *data, int chan, int rate)
{
- int i, ret, rindex = -1;
+ int i;
- for (i = 0; i < ARRAY_SIZE(ads1015_data_rate); i++)
+ for (i = 0; i < ARRAY_SIZE(ads1015_data_rate); i++) {
if (data->data_rate[i] == rate) {
- rindex = i;
- break;
+ data->channel_data[chan].data_rate = i;
+ return 0;
}
- if (rindex < 0)
- return -EINVAL;
-
- ret = regmap_update_bits(data->regmap, ADS1015_CFG_REG,
- ADS1015_CFG_DR_MASK,
- rindex << ADS1015_CFG_DR_SHIFT);
- if (ret < 0)
- return ret;
-
- data->channel_data[chan].data_rate = rindex;
+ }
- return 0;
+ return -EINVAL;
}
static int ads1015_read_raw(struct iio_dev *indio_dev,
@@ -353,41 +446,47 @@ static int ads1015_read_raw(struct iio_dev *indio_dev,
int ret, idx;
struct ads1015_data *data = iio_priv(indio_dev);
- mutex_lock(&indio_dev->mlock);
mutex_lock(&data->lock);
switch (mask) {
case IIO_CHAN_INFO_RAW: {
int shift = chan->scan_type.shift;
- if (iio_buffer_enabled(indio_dev)) {
- ret = -EBUSY;
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret)
break;
+
+ if (ads1015_event_channel_enabled(data) &&
+ data->event_channel != chan->address) {
+ ret = -EBUSY;
+ goto release_direct;
}
ret = ads1015_set_power_state(data, true);
if (ret < 0)
- break;
+ goto release_direct;
ret = ads1015_get_adc_result(data, chan->address, val);
if (ret < 0) {
ads1015_set_power_state(data, false);
- break;
+ goto release_direct;
}
*val = sign_extend32(*val >> shift, 15 - shift);
ret = ads1015_set_power_state(data, false);
if (ret < 0)
- break;
+ goto release_direct;
ret = IIO_VAL_INT;
+release_direct:
+ iio_device_release_direct_mode(indio_dev);
break;
}
case IIO_CHAN_INFO_SCALE:
idx = data->channel_data[chan->address].pga;
- *val = ads1015_scale[idx].scale;
- *val2 = ads1015_scale[idx].uscale;
- ret = IIO_VAL_INT_PLUS_MICRO;
+ *val = ads1015_fullscale_range[idx];
+ *val2 = chan->scan_type.realbits - 1;
+ ret = IIO_VAL_FRACTIONAL_LOG2;
break;
case IIO_CHAN_INFO_SAMP_FREQ:
idx = data->channel_data[chan->address].data_rate;
@@ -399,7 +498,6 @@ static int ads1015_read_raw(struct iio_dev *indio_dev,
break;
}
mutex_unlock(&data->lock);
- mutex_unlock(&indio_dev->mlock);
return ret;
}
@@ -414,7 +512,7 @@ static int ads1015_write_raw(struct iio_dev *indio_dev,
mutex_lock(&data->lock);
switch (mask) {
case IIO_CHAN_INFO_SCALE:
- ret = ads1015_set_scale(data, chan->address, val, val2);
+ ret = ads1015_set_scale(data, chan, val, val2);
break;
case IIO_CHAN_INFO_SAMP_FREQ:
ret = ads1015_set_data_rate(data, chan->address, val);
@@ -428,8 +526,254 @@ static int ads1015_write_raw(struct iio_dev *indio_dev,
return ret;
}
+static int ads1015_read_event(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan, enum iio_event_type type,
+ enum iio_event_direction dir, enum iio_event_info info, int *val,
+ int *val2)
+{
+ struct ads1015_data *data = iio_priv(indio_dev);
+ int ret;
+ unsigned int comp_queue;
+ int period;
+ int dr;
+
+ mutex_lock(&data->lock);
+
+ switch (info) {
+ case IIO_EV_INFO_VALUE:
+ *val = (dir == IIO_EV_DIR_RISING) ?
+ data->thresh_data[chan->address].high_thresh :
+ data->thresh_data[chan->address].low_thresh;
+ ret = IIO_VAL_INT;
+ break;
+ case IIO_EV_INFO_PERIOD:
+ dr = data->channel_data[chan->address].data_rate;
+ comp_queue = data->thresh_data[chan->address].comp_queue;
+ period = ads1015_comp_queue[comp_queue] *
+ USEC_PER_SEC / data->data_rate[dr];
+
+ *val = period / USEC_PER_SEC;
+ *val2 = period % USEC_PER_SEC;
+ ret = IIO_VAL_INT_PLUS_MICRO;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ mutex_unlock(&data->lock);
+
+ return ret;
+}
+
+static int ads1015_write_event(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan, enum iio_event_type type,
+ enum iio_event_direction dir, enum iio_event_info info, int val,
+ int val2)
+{
+ struct ads1015_data *data = iio_priv(indio_dev);
+ int realbits = chan->scan_type.realbits;
+ int ret = 0;
+ long long period;
+ int i;
+ int dr;
+
+ mutex_lock(&data->lock);
+
+ switch (info) {
+ case IIO_EV_INFO_VALUE:
+ if (val >= 1 << (realbits - 1) || val < -1 << (realbits - 1)) {
+ ret = -EINVAL;
+ break;
+ }
+ if (dir == IIO_EV_DIR_RISING)
+ data->thresh_data[chan->address].high_thresh = val;
+ else
+ data->thresh_data[chan->address].low_thresh = val;
+ break;
+ case IIO_EV_INFO_PERIOD:
+ dr = data->channel_data[chan->address].data_rate;
+ period = val * USEC_PER_SEC + val2;
+
+ for (i = 0; i < ARRAY_SIZE(ads1015_comp_queue) - 1; i++) {
+ if (period <= ads1015_comp_queue[i] *
+ USEC_PER_SEC / data->data_rate[dr])
+ break;
+ }
+ data->thresh_data[chan->address].comp_queue = i;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ mutex_unlock(&data->lock);
+
+ return ret;
+}
+
+static int ads1015_read_event_config(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan, enum iio_event_type type,
+ enum iio_event_direction dir)
+{
+ struct ads1015_data *data = iio_priv(indio_dev);
+ int ret = 0;
+
+ mutex_lock(&data->lock);
+ if (data->event_channel == chan->address) {
+ switch (dir) {
+ case IIO_EV_DIR_RISING:
+ ret = 1;
+ break;
+ case IIO_EV_DIR_EITHER:
+ ret = (data->comp_mode == ADS1015_CFG_COMP_MODE_WINDOW);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ }
+ mutex_unlock(&data->lock);
+
+ return ret;
+}
+
+static int ads1015_enable_event_config(struct ads1015_data *data,
+ const struct iio_chan_spec *chan, int comp_mode)
+{
+ int low_thresh = data->thresh_data[chan->address].low_thresh;
+ int high_thresh = data->thresh_data[chan->address].high_thresh;
+ int ret;
+ unsigned int val;
+
+ if (ads1015_event_channel_enabled(data)) {
+ if (data->event_channel != chan->address ||
+ (data->comp_mode == ADS1015_CFG_COMP_MODE_TRAD &&
+ comp_mode == ADS1015_CFG_COMP_MODE_WINDOW))
+ return -EBUSY;
+
+ return 0;
+ }
+
+ if (comp_mode == ADS1015_CFG_COMP_MODE_TRAD) {
+ low_thresh = max(-1 << (chan->scan_type.realbits - 1),
+ high_thresh - 1);
+ }
+ ret = regmap_write(data->regmap, ADS1015_LO_THRESH_REG,
+ low_thresh << chan->scan_type.shift);
+ if (ret)
+ return ret;
+
+ ret = regmap_write(data->regmap, ADS1015_HI_THRESH_REG,
+ high_thresh << chan->scan_type.shift);
+ if (ret)
+ return ret;
+
+ ret = ads1015_set_power_state(data, true);
+ if (ret < 0)
+ return ret;
+
+ ads1015_event_channel_enable(data, chan->address, comp_mode);
+
+ ret = ads1015_get_adc_result(data, chan->address, &val);
+ if (ret) {
+ ads1015_event_channel_disable(data, chan->address);
+ ads1015_set_power_state(data, false);
+ }
+
+ return ret;
+}
+
+static int ads1015_disable_event_config(struct ads1015_data *data,
+ const struct iio_chan_spec *chan, int comp_mode)
+{
+ int ret;
+
+ if (!ads1015_event_channel_enabled(data))
+ return 0;
+
+ if (data->event_channel != chan->address)
+ return 0;
+
+ if (data->comp_mode == ADS1015_CFG_COMP_MODE_TRAD &&
+ comp_mode == ADS1015_CFG_COMP_MODE_WINDOW)
+ return 0;
+
+ ret = regmap_update_bits(data->regmap, ADS1015_CFG_REG,
+ ADS1015_CFG_COMP_QUE_MASK,
+ ADS1015_CFG_COMP_DISABLE <<
+ ADS1015_CFG_COMP_QUE_SHIFT);
+ if (ret)
+ return ret;
+
+ ads1015_event_channel_disable(data, chan->address);
+
+ return ads1015_set_power_state(data, false);
+}
+
+static int ads1015_write_event_config(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan, enum iio_event_type type,
+ enum iio_event_direction dir, int state)
+{
+ struct ads1015_data *data = iio_priv(indio_dev);
+ int ret;
+ int comp_mode = (dir == IIO_EV_DIR_EITHER) ?
+ ADS1015_CFG_COMP_MODE_WINDOW : ADS1015_CFG_COMP_MODE_TRAD;
+
+ mutex_lock(&data->lock);
+
+ /* Prevent from enabling both buffer and event at a time */
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret) {
+ mutex_unlock(&data->lock);
+ return ret;
+ }
+
+ if (state)
+ ret = ads1015_enable_event_config(data, chan, comp_mode);
+ else
+ ret = ads1015_disable_event_config(data, chan, comp_mode);
+
+ iio_device_release_direct_mode(indio_dev);
+ mutex_unlock(&data->lock);
+
+ return ret;
+}
+
+static irqreturn_t ads1015_event_handler(int irq, void *priv)
+{
+ struct iio_dev *indio_dev = priv;
+ struct ads1015_data *data = iio_priv(indio_dev);
+ int val;
+ int ret;
+
+ /* Clear the latched ALERT/RDY pin */
+ ret = regmap_read(data->regmap, ADS1015_CONV_REG, &val);
+ if (ret)
+ return IRQ_HANDLED;
+
+ if (ads1015_event_channel_enabled(data)) {
+ enum iio_event_direction dir;
+ u64 code;
+
+ dir = data->comp_mode == ADS1015_CFG_COMP_MODE_TRAD ?
+ IIO_EV_DIR_RISING : IIO_EV_DIR_EITHER;
+ code = IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, data->event_channel,
+ IIO_EV_TYPE_THRESH, dir);
+ iio_push_event(indio_dev, code, iio_get_time_ns(indio_dev));
+ }
+
+ return IRQ_HANDLED;
+}
+
static int ads1015_buffer_preenable(struct iio_dev *indio_dev)
{
+ struct ads1015_data *data = iio_priv(indio_dev);
+
+ /* Prevent from enabling both buffer and event at a time */
+ if (ads1015_event_channel_enabled(data))
+ return -EBUSY;
+
return ads1015_set_power_state(iio_priv(indio_dev), true);
}
@@ -446,7 +790,10 @@ static const struct iio_buffer_setup_ops ads1015_buffer_setup_ops = {
.validate_scan_mask = &iio_validate_scan_mask_onehot,
};
-static IIO_CONST_ATTR(scale_available, "3 2 1 0.5 0.25 0.125");
+static IIO_CONST_ATTR_NAMED(ads1015_scale_available, scale_available,
+ "3 2 1 0.5 0.25 0.125");
+static IIO_CONST_ATTR_NAMED(ads1115_scale_available, scale_available,
+ "0.1875 0.125 0.0625 0.03125 0.015625 0.007813");
static IIO_CONST_ATTR_NAMED(ads1015_sampling_frequency_available,
sampling_frequency_available, "128 250 490 920 1600 2400 3300");
@@ -454,7 +801,7 @@ static IIO_CONST_ATTR_NAMED(ads1115_sampling_frequency_available,
sampling_frequency_available, "8 16 32 64 128 250 475 860");
static struct attribute *ads1015_attributes[] = {
- &iio_const_attr_scale_available.dev_attr.attr,
+ &iio_const_attr_ads1015_scale_available.dev_attr.attr,
&iio_const_attr_ads1015_sampling_frequency_available.dev_attr.attr,
NULL,
};
@@ -464,7 +811,7 @@ static const struct attribute_group ads1015_attribute_group = {
};
static struct attribute *ads1115_attributes[] = {
- &iio_const_attr_scale_available.dev_attr.attr,
+ &iio_const_attr_ads1115_scale_available.dev_attr.attr,
&iio_const_attr_ads1115_sampling_frequency_available.dev_attr.attr,
NULL,
};
@@ -477,6 +824,10 @@ static const struct iio_info ads1015_info = {
.driver_module = THIS_MODULE,
.read_raw = ads1015_read_raw,
.write_raw = ads1015_write_raw,
+ .read_event_value = ads1015_read_event,
+ .write_event_value = ads1015_write_event,
+ .read_event_config = ads1015_read_event_config,
+ .write_event_config = ads1015_write_event_config,
.attrs = &ads1015_attribute_group,
};
@@ -484,6 +835,10 @@ static const struct iio_info ads1115_info = {
.driver_module = THIS_MODULE,
.read_raw = ads1015_read_raw,
.write_raw = ads1015_write_raw,
+ .read_event_value = ads1015_read_event,
+ .write_event_value = ads1015_write_event,
+ .read_event_config = ads1015_read_event_config,
+ .write_event_config = ads1015_write_event_config,
.attrs = &ads1115_attribute_group,
};
@@ -505,24 +860,24 @@ static int ads1015_get_channels_config_of(struct i2c_client *client)
unsigned int data_rate = ADS1015_DEFAULT_DATA_RATE;
if (of_property_read_u32(node, "reg", &pval)) {
- dev_err(&client->dev, "invalid reg on %s\n",
- node->full_name);
+ dev_err(&client->dev, "invalid reg on %pOF\n",
+ node);
continue;
}
channel = pval;
if (channel >= ADS1015_CHANNELS) {
dev_err(&client->dev,
- "invalid channel index %d on %s\n",
- channel, node->full_name);
+ "invalid channel index %d on %pOF\n",
+ channel, node);
continue;
}
if (!of_property_read_u32(node, "ti,gain", &pval)) {
pga = pval;
if (pga > 6) {
- dev_err(&client->dev, "invalid gain on %s\n",
- node->full_name);
+ dev_err(&client->dev, "invalid gain on %pOF\n",
+ node);
of_node_put(node);
return -EINVAL;
}
@@ -532,8 +887,8 @@ static int ads1015_get_channels_config_of(struct i2c_client *client)
data_rate = pval;
if (data_rate > 7) {
dev_err(&client->dev,
- "invalid data_rate on %s\n",
- node->full_name);
+ "invalid data_rate on %pOF\n",
+ node);
of_node_put(node);
return -EINVAL;
}
@@ -573,6 +928,13 @@ static void ads1015_get_channels_config(struct i2c_client *client)
}
}
+static int ads1015_set_conv_mode(struct ads1015_data *data, int mode)
+{
+ return regmap_update_bits(data->regmap, ADS1015_CFG_REG,
+ ADS1015_CFG_MOD_MASK,
+ mode << ADS1015_CFG_MOD_SHIFT);
+}
+
static int ads1015_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -580,6 +942,7 @@ static int ads1015_probe(struct i2c_client *client,
struct ads1015_data *data;
int ret;
enum chip_ids chip;
+ int i;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (!indio_dev)
@@ -614,6 +977,18 @@ static int ads1015_probe(struct i2c_client *client,
break;
}
+ data->event_channel = ADS1015_CHANNELS;
+ /*
+ * Set default lower and upper threshold to min and max value
+ * respectively.
+ */
+ for (i = 0; i < ADS1015_CHANNELS; i++) {
+ int realbits = indio_dev->channels[i].scan_type.realbits;
+
+ data->thresh_data[i].low_thresh = -1 << (realbits - 1);
+ data->thresh_data[i].high_thresh = (1 << (realbits - 1)) - 1;
+ }
+
/* we need to keep this ABI the same as used by hwmon ADS1015 driver */
ads1015_get_channels_config(client);
@@ -623,16 +998,56 @@ static int ads1015_probe(struct i2c_client *client,
return PTR_ERR(data->regmap);
}
- ret = iio_triggered_buffer_setup(indio_dev, NULL,
- ads1015_trigger_handler,
- &ads1015_buffer_setup_ops);
+ ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev, NULL,
+ ads1015_trigger_handler,
+ &ads1015_buffer_setup_ops);
if (ret < 0) {
dev_err(&client->dev, "iio triggered buffer setup failed\n");
return ret;
}
+
+ if (client->irq) {
+ unsigned long irq_trig =
+ irqd_get_trigger_type(irq_get_irq_data(client->irq));
+ unsigned int cfg_comp_mask = ADS1015_CFG_COMP_QUE_MASK |
+ ADS1015_CFG_COMP_LAT_MASK | ADS1015_CFG_COMP_POL_MASK;
+ unsigned int cfg_comp =
+ ADS1015_CFG_COMP_DISABLE << ADS1015_CFG_COMP_QUE_SHIFT |
+ 1 << ADS1015_CFG_COMP_LAT_SHIFT;
+
+ switch (irq_trig) {
+ case IRQF_TRIGGER_LOW:
+ cfg_comp |= ADS1015_CFG_COMP_POL_LOW;
+ break;
+ case IRQF_TRIGGER_HIGH:
+ cfg_comp |= ADS1015_CFG_COMP_POL_HIGH;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = regmap_update_bits(data->regmap, ADS1015_CFG_REG,
+ cfg_comp_mask, cfg_comp);
+ if (ret)
+ return ret;
+
+ ret = devm_request_threaded_irq(&client->dev, client->irq,
+ NULL, ads1015_event_handler,
+ irq_trig | IRQF_ONESHOT,
+ client->name, indio_dev);
+ if (ret)
+ return ret;
+ }
+
+ ret = ads1015_set_conv_mode(data, ADS1015_CONTINUOUS);
+ if (ret)
+ return ret;
+
+ data->conv_invalid = true;
+
ret = pm_runtime_set_active(&client->dev);
if (ret)
- goto err_buffer_cleanup;
+ return ret;
pm_runtime_set_autosuspend_delay(&client->dev, ADS1015_SLEEP_DELAY_MS);
pm_runtime_use_autosuspend(&client->dev);
pm_runtime_enable(&client->dev);
@@ -640,15 +1055,10 @@ static int ads1015_probe(struct i2c_client *client,
ret = iio_device_register(indio_dev);
if (ret < 0) {
dev_err(&client->dev, "Failed to register IIO device\n");
- goto err_buffer_cleanup;
+ return ret;
}
return 0;
-
-err_buffer_cleanup:
- iio_triggered_buffer_cleanup(indio_dev);
-
- return ret;
}
static int ads1015_remove(struct i2c_client *client)
@@ -662,12 +1072,8 @@ static int ads1015_remove(struct i2c_client *client)
pm_runtime_set_suspended(&client->dev);
pm_runtime_put_noidle(&client->dev);
- iio_triggered_buffer_cleanup(indio_dev);
-
/* power down single shot mode */
- return regmap_update_bits(data->regmap, ADS1015_CFG_REG,
- ADS1015_CFG_MOD_MASK,
- ADS1015_SINGLESHOT << ADS1015_CFG_MOD_SHIFT);
+ return ads1015_set_conv_mode(data, ADS1015_SINGLESHOT);
}
#ifdef CONFIG_PM
@@ -676,19 +1082,20 @@ static int ads1015_runtime_suspend(struct device *dev)
struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
struct ads1015_data *data = iio_priv(indio_dev);
- return regmap_update_bits(data->regmap, ADS1015_CFG_REG,
- ADS1015_CFG_MOD_MASK,
- ADS1015_SINGLESHOT << ADS1015_CFG_MOD_SHIFT);
+ return ads1015_set_conv_mode(data, ADS1015_SINGLESHOT);
}
static int ads1015_runtime_resume(struct device *dev)
{
struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
struct ads1015_data *data = iio_priv(indio_dev);
+ int ret;
- return regmap_update_bits(data->regmap, ADS1015_CFG_REG,
- ADS1015_CFG_MOD_MASK,
- ADS1015_CONTINUOUS << ADS1015_CFG_MOD_SHIFT);
+ ret = ads1015_set_conv_mode(data, ADS1015_CONTINUOUS);
+ if (!ret)
+ data->conv_invalid = true;
+
+ return ret;
}
#endif
diff --git a/drivers/iio/adc/ti-ads7950.c b/drivers/iio/adc/ti-ads7950.c
index 16a0663..a376190 100644
--- a/drivers/iio/adc/ti-ads7950.c
+++ b/drivers/iio/adc/ti-ads7950.c
@@ -21,6 +21,7 @@
* GNU General Public License for more details.
*/
+#include <linux/acpi.h>
#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/err.h>
@@ -37,6 +38,12 @@
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
+/*
+ * In case of ACPI, we use the 5000 mV as default for the reference pin.
+ * Device tree users encode that via the vref-supply regulator.
+ */
+#define TI_ADS7950_VA_MV_ACPI_DEFAULT 5000
+
#define TI_ADS7950_CR_MANUAL BIT(12)
#define TI_ADS7950_CR_WRITE BIT(11)
#define TI_ADS7950_CR_CHAN(ch) ((ch) << 7)
@@ -58,6 +65,7 @@ struct ti_ads7950_state {
struct spi_message scan_single_msg;
struct regulator *reg;
+ unsigned int vref_mv;
unsigned int settings;
@@ -305,11 +313,15 @@ static int ti_ads7950_get_range(struct ti_ads7950_state *st)
{
int vref;
- vref = regulator_get_voltage(st->reg);
- if (vref < 0)
- return vref;
+ if (st->vref_mv) {
+ vref = st->vref_mv;
+ } else {
+ vref = regulator_get_voltage(st->reg);
+ if (vref < 0)
+ return vref;
- vref /= 1000;
+ vref /= 1000;
+ }
if (st->settings & TI_ADS7950_CR_RANGE_5V)
vref *= 2;
@@ -411,6 +423,10 @@ static int ti_ads7950_probe(struct spi_device *spi)
spi_message_init_with_transfers(&st->scan_single_msg,
st->scan_single_xfer, 3);
+ /* Use hard coded value for reference voltage in ACPI case */
+ if (ACPI_COMPANION(&spi->dev))
+ st->vref_mv = TI_ADS7950_VA_MV_ACPI_DEFAULT;
+
st->reg = devm_regulator_get(&spi->dev, "vref");
if (IS_ERR(st->reg)) {
dev_err(&spi->dev, "Failed get get regulator \"vref\"\n");
@@ -475,9 +491,27 @@ static const struct spi_device_id ti_ads7950_id[] = {
};
MODULE_DEVICE_TABLE(spi, ti_ads7950_id);
+static const struct of_device_id ads7950_of_table[] = {
+ { .compatible = "ti,ads7950", .data = &ti_ads7950_chip_info[TI_ADS7950] },
+ { .compatible = "ti,ads7951", .data = &ti_ads7950_chip_info[TI_ADS7951] },
+ { .compatible = "ti,ads7952", .data = &ti_ads7950_chip_info[TI_ADS7952] },
+ { .compatible = "ti,ads7953", .data = &ti_ads7950_chip_info[TI_ADS7953] },
+ { .compatible = "ti,ads7954", .data = &ti_ads7950_chip_info[TI_ADS7954] },
+ { .compatible = "ti,ads7955", .data = &ti_ads7950_chip_info[TI_ADS7955] },
+ { .compatible = "ti,ads7956", .data = &ti_ads7950_chip_info[TI_ADS7956] },
+ { .compatible = "ti,ads7957", .data = &ti_ads7950_chip_info[TI_ADS7957] },
+ { .compatible = "ti,ads7958", .data = &ti_ads7950_chip_info[TI_ADS7958] },
+ { .compatible = "ti,ads7959", .data = &ti_ads7950_chip_info[TI_ADS7959] },
+ { .compatible = "ti,ads7960", .data = &ti_ads7950_chip_info[TI_ADS7960] },
+ { .compatible = "ti,ads7961", .data = &ti_ads7950_chip_info[TI_ADS7961] },
+ { },
+};
+MODULE_DEVICE_TABLE(of, ads7950_of_table);
+
static struct spi_driver ti_ads7950_driver = {
.driver = {
.name = "ads7950",
+ .of_match_table = ads7950_of_table,
},
.probe = ti_ads7950_probe,
.remove = ti_ads7950_remove,
diff --git a/drivers/iio/adc/xilinx-xadc-events.c b/drivers/iio/adc/xilinx-xadc-events.c
index 6d5c2a6..dc06703 100644
--- a/drivers/iio/adc/xilinx-xadc-events.c
+++ b/drivers/iio/adc/xilinx-xadc-events.c
@@ -68,7 +68,7 @@ void xadc_handle_events(struct iio_dev *indio_dev, unsigned long events)
xadc_handle_event(indio_dev, i);
}
-static unsigned xadc_get_threshold_offset(const struct iio_chan_spec *chan,
+static unsigned int xadc_get_threshold_offset(const struct iio_chan_spec *chan,
enum iio_event_direction dir)
{
unsigned int offset;
@@ -90,26 +90,24 @@ static unsigned xadc_get_threshold_offset(const struct iio_chan_spec *chan,
static unsigned int xadc_get_alarm_mask(const struct iio_chan_spec *chan)
{
- if (chan->type == IIO_TEMP) {
+ if (chan->type == IIO_TEMP)
return XADC_ALARM_OT_MASK;
- } else {
- switch (chan->channel) {
- case 0:
- return XADC_ALARM_VCCINT_MASK;
- case 1:
- return XADC_ALARM_VCCAUX_MASK;
- case 2:
- return XADC_ALARM_VCCBRAM_MASK;
- case 3:
- return XADC_ALARM_VCCPINT_MASK;
- case 4:
- return XADC_ALARM_VCCPAUX_MASK;
- case 5:
- return XADC_ALARM_VCCODDR_MASK;
- default:
- /* We will never get here */
- return 0;
- }
+ switch (chan->channel) {
+ case 0:
+ return XADC_ALARM_VCCINT_MASK;
+ case 1:
+ return XADC_ALARM_VCCAUX_MASK;
+ case 2:
+ return XADC_ALARM_VCCBRAM_MASK;
+ case 3:
+ return XADC_ALARM_VCCPINT_MASK;
+ case 4:
+ return XADC_ALARM_VCCPAUX_MASK;
+ case 5:
+ return XADC_ALARM_VCCODDR_MASK;
+ default:
+ /* We will never get here */
+ return 0;
}
}
diff --git a/drivers/iio/adc/xilinx-xadc.h b/drivers/iio/adc/xilinx-xadc.h
index f6f0819..62edbda 100644
--- a/drivers/iio/adc/xilinx-xadc.h
+++ b/drivers/iio/adc/xilinx-xadc.h
@@ -71,13 +71,13 @@ struct xadc {
};
struct xadc_ops {
- int (*read)(struct xadc *, unsigned int, uint16_t *);
- int (*write)(struct xadc *, unsigned int, uint16_t);
+ int (*read)(struct xadc *xadc, unsigned int reg, uint16_t *val);
+ int (*write)(struct xadc *xadc, unsigned int reg, uint16_t val);
int (*setup)(struct platform_device *pdev, struct iio_dev *indio_dev,
int irq);
- void (*update_alarm)(struct xadc *, unsigned int);
- unsigned long (*get_dclk_rate)(struct xadc *);
- irqreturn_t (*interrupt_handler)(int, void *);
+ void (*update_alarm)(struct xadc *xadc, unsigned int alarm);
+ unsigned long (*get_dclk_rate)(struct xadc *xadc);
+ irqreturn_t (*interrupt_handler)(int irq, void *devid);
unsigned int flags;
};
diff --git a/drivers/iio/chemical/Kconfig b/drivers/iio/chemical/Kconfig
index cea7f98..5cb5be7 100644
--- a/drivers/iio/chemical/Kconfig
+++ b/drivers/iio/chemical/Kconfig
@@ -21,6 +21,15 @@ config ATLAS_PH_SENSOR
To compile this driver as module, choose M here: the
module will be called atlas-ph-sensor.
+config CCS811
+ tristate "AMS CCS811 VOC sensor"
+ depends on I2C
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ Say Y here to build I2C interface support for the AMS
+ CCS811 VOC (Volatile Organic Compounds) sensor
+
config IAQCORE
tristate "AMS iAQ-Core VOC sensors"
depends on I2C
diff --git a/drivers/iio/chemical/Makefile b/drivers/iio/chemical/Makefile
index b02202b..a629b29 100644
--- a/drivers/iio/chemical/Makefile
+++ b/drivers/iio/chemical/Makefile
@@ -4,5 +4,6 @@
# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_ATLAS_PH_SENSOR) += atlas-ph-sensor.o
+obj-$(CONFIG_CCS811) += ccs811.o
obj-$(CONFIG_IAQCORE) += ams-iaq-core.o
obj-$(CONFIG_VZ89X) += vz89x.o
diff --git a/drivers/iio/chemical/ccs811.c b/drivers/iio/chemical/ccs811.c
new file mode 100644
index 0000000..840a6cb
--- /dev/null
+++ b/drivers/iio/chemical/ccs811.c
@@ -0,0 +1,405 @@
+/*
+ * ccs811.c - Support for AMS CCS811 VOC Sensor
+ *
+ * Copyright (C) 2017 Narcisa Vasile <narcisaanamaria12@gmail.com>
+ *
+ * Datasheet: ams.com/content/download/951091/2269479/CCS811_DS000459_3-00.pdf
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * IIO driver for AMS CCS811 (I2C address 0x5A/0x5B set by ADDR Low/High)
+ *
+ * TODO:
+ * 1. Make the drive mode selectable form userspace
+ * 2. Add support for interrupts
+ * 3. Adjust time to wait for data to be ready based on selected operation mode
+ * 4. Read error register and put the information in logs
+ */
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/module.h>
+
+#define CCS811_STATUS 0x00
+#define CCS811_MEAS_MODE 0x01
+#define CCS811_ALG_RESULT_DATA 0x02
+#define CCS811_RAW_DATA 0x03
+#define CCS811_HW_ID 0x20
+#define CCS881_HW_ID_VALUE 0x81
+#define CCS811_HW_VERSION 0x21
+#define CCS811_HW_VERSION_VALUE 0x10
+#define CCS811_HW_VERSION_MASK 0xF0
+#define CCS811_ERR 0xE0
+/* Used to transition from boot to application mode */
+#define CCS811_APP_START 0xF4
+
+/* Status register flags */
+#define CCS811_STATUS_ERROR BIT(0)
+#define CCS811_STATUS_DATA_READY BIT(3)
+#define CCS811_STATUS_APP_VALID_MASK BIT(4)
+#define CCS811_STATUS_APP_VALID_LOADED BIT(4)
+/*
+ * Value of FW_MODE bit of STATUS register describes the sensor's state:
+ * 0: Firmware is in boot mode, this allows new firmware to be loaded
+ * 1: Firmware is in application mode. CCS811 is ready to take ADC measurements
+ */
+#define CCS811_STATUS_FW_MODE_MASK BIT(7)
+#define CCS811_STATUS_FW_MODE_APPLICATION BIT(7)
+
+/* Measurement modes */
+#define CCS811_MODE_IDLE 0x00
+#define CCS811_MODE_IAQ_1SEC 0x10
+#define CCS811_MODE_IAQ_10SEC 0x20
+#define CCS811_MODE_IAQ_60SEC 0x30
+#define CCS811_MODE_RAW_DATA 0x40
+
+#define CCS811_VOLTAGE_MASK 0x3FF
+
+struct ccs811_reading {
+ __be16 co2;
+ __be16 voc;
+ u8 status;
+ u8 error;
+ __be16 resistance;
+} __attribute__((__packed__));
+
+struct ccs811_data {
+ struct i2c_client *client;
+ struct mutex lock; /* Protect readings */
+ struct ccs811_reading buffer;
+};
+
+static const struct iio_chan_spec ccs811_channels[] = {
+ {
+ .type = IIO_CURRENT,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
+ .scan_index = -1,
+ }, {
+ .type = IIO_VOLTAGE,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
+ .scan_index = -1,
+ }, {
+ .type = IIO_CONCENTRATION,
+ .channel2 = IIO_MOD_CO2,
+ .modified = 1,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_OFFSET) |
+ BIT(IIO_CHAN_INFO_SCALE),
+ .scan_index = 0,
+ .scan_type = {
+ .sign = 'u',
+ .realbits = 16,
+ .storagebits = 16,
+ .endianness = IIO_BE,
+ },
+ }, {
+ .type = IIO_CONCENTRATION,
+ .channel2 = IIO_MOD_VOC,
+ .modified = 1,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
+ .scan_index = 1,
+ .scan_type = {
+ .sign = 'u',
+ .realbits = 16,
+ .storagebits = 16,
+ .endianness = IIO_BE,
+ },
+ },
+ IIO_CHAN_SOFT_TIMESTAMP(2),
+};
+
+/*
+ * The CCS811 powers-up in boot mode. A setup write to CCS811_APP_START will
+ * transition the sensor to application mode.
+ */
+static int ccs811_start_sensor_application(struct i2c_client *client)
+{
+ int ret;
+
+ ret = i2c_smbus_read_byte_data(client, CCS811_STATUS);
+ if (ret < 0)
+ return ret;
+
+ if ((ret & CCS811_STATUS_APP_VALID_MASK) !=
+ CCS811_STATUS_APP_VALID_LOADED)
+ return -EIO;
+
+ ret = i2c_smbus_write_byte(client, CCS811_APP_START);
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_smbus_read_byte_data(client, CCS811_STATUS);
+ if (ret < 0)
+ return ret;
+
+ if ((ret & CCS811_STATUS_FW_MODE_MASK) !=
+ CCS811_STATUS_FW_MODE_APPLICATION) {
+ dev_err(&client->dev, "Application failed to start. Sensor is still in boot mode.\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int ccs811_setup(struct i2c_client *client)
+{
+ int ret;
+
+ ret = ccs811_start_sensor_application(client);
+ if (ret < 0)
+ return ret;
+
+ return i2c_smbus_write_byte_data(client, CCS811_MEAS_MODE,
+ CCS811_MODE_IAQ_1SEC);
+}
+
+static int ccs811_get_measurement(struct ccs811_data *data)
+{
+ int ret, tries = 11;
+
+ /* Maximum waiting time: 1s, as measurements are made every second */
+ while (tries-- > 0) {
+ ret = i2c_smbus_read_byte_data(data->client, CCS811_STATUS);
+ if (ret < 0)
+ return ret;
+
+ if ((ret & CCS811_STATUS_DATA_READY) || tries == 0)
+ break;
+ msleep(100);
+ }
+ if (!(ret & CCS811_STATUS_DATA_READY))
+ return -EIO;
+
+ return i2c_smbus_read_i2c_block_data(data->client,
+ CCS811_ALG_RESULT_DATA, 8,
+ (char *)&data->buffer);
+}
+
+static int ccs811_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct ccs811_data *data = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ mutex_lock(&data->lock);
+ ret = ccs811_get_measurement(data);
+ if (ret < 0) {
+ mutex_unlock(&data->lock);
+ return ret;
+ }
+
+ switch (chan->type) {
+ case IIO_VOLTAGE:
+ *val = be16_to_cpu(data->buffer.resistance) &
+ CCS811_VOLTAGE_MASK;
+ ret = IIO_VAL_INT;
+ break;
+ case IIO_CURRENT:
+ *val = be16_to_cpu(data->buffer.resistance) >> 10;
+ ret = IIO_VAL_INT;
+ break;
+ case IIO_CONCENTRATION:
+ switch (chan->channel2) {
+ case IIO_MOD_CO2:
+ *val = be16_to_cpu(data->buffer.co2);
+ ret = IIO_VAL_INT;
+ break;
+ case IIO_MOD_VOC:
+ *val = be16_to_cpu(data->buffer.voc);
+ ret = IIO_VAL_INT;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ mutex_unlock(&data->lock);
+
+ return ret;
+
+ case IIO_CHAN_INFO_SCALE:
+ switch (chan->type) {
+ case IIO_VOLTAGE:
+ *val = 1;
+ *val2 = 612903;
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CURRENT:
+ *val = 0;
+ *val2 = 1000;
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CONCENTRATION:
+ switch (chan->channel2) {
+ case IIO_MOD_CO2:
+ *val = 0;
+ *val2 = 12834;
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_MOD_VOC:
+ *val = 0;
+ *val2 = 84246;
+ return IIO_VAL_INT_PLUS_MICRO;
+ default:
+ return -EINVAL;
+ }
+ default:
+ return -EINVAL;
+ }
+ case IIO_CHAN_INFO_OFFSET:
+ if (!(chan->type == IIO_CONCENTRATION &&
+ chan->channel2 == IIO_MOD_CO2))
+ return -EINVAL;
+ *val = -400;
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct iio_info ccs811_info = {
+ .read_raw = ccs811_read_raw,
+ .driver_module = THIS_MODULE,
+};
+
+static irqreturn_t ccs811_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct ccs811_data *data = iio_priv(indio_dev);
+ struct i2c_client *client = data->client;
+ s16 buf[8]; /* s16 eCO2 + s16 TVOC + padding + 8 byte timestamp */
+ int ret;
+
+ ret = i2c_smbus_read_i2c_block_data(client, CCS811_ALG_RESULT_DATA, 4,
+ (u8 *)&buf);
+ if (ret != 4) {
+ dev_err(&client->dev, "cannot read sensor data\n");
+ goto err;
+ }
+
+ iio_push_to_buffers_with_timestamp(indio_dev, buf,
+ iio_get_time_ns(indio_dev));
+
+err:
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
+static int ccs811_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct iio_dev *indio_dev;
+ struct ccs811_data *data;
+ int ret;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE
+ | I2C_FUNC_SMBUS_BYTE_DATA
+ | I2C_FUNC_SMBUS_READ_I2C_BLOCK))
+ return -EOPNOTSUPP;
+
+ /* Check hardware id (should be 0x81 for this family of devices) */
+ ret = i2c_smbus_read_byte_data(client, CCS811_HW_ID);
+ if (ret < 0)
+ return ret;
+
+ if (ret != CCS881_HW_ID_VALUE) {
+ dev_err(&client->dev, "hardware id doesn't match CCS81x\n");
+ return -ENODEV;
+ }
+
+ ret = i2c_smbus_read_byte_data(client, CCS811_HW_VERSION);
+ if (ret < 0)
+ return ret;
+
+ if ((ret & CCS811_HW_VERSION_MASK) != CCS811_HW_VERSION_VALUE) {
+ dev_err(&client->dev, "no CCS811 sensor\n");
+ return -ENODEV;
+ }
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ ret = ccs811_setup(client);
+ if (ret < 0)
+ return ret;
+
+ data = iio_priv(indio_dev);
+ i2c_set_clientdata(client, indio_dev);
+ data->client = client;
+
+ mutex_init(&data->lock);
+
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->name = id->name;
+ indio_dev->info = &ccs811_info;
+
+ indio_dev->channels = ccs811_channels;
+ indio_dev->num_channels = ARRAY_SIZE(ccs811_channels);
+
+ ret = iio_triggered_buffer_setup(indio_dev, NULL,
+ ccs811_trigger_handler, NULL);
+
+ if (ret < 0) {
+ dev_err(&client->dev, "triggered buffer setup failed\n");
+ goto err_poweroff;
+ }
+
+ ret = iio_device_register(indio_dev);
+ if (ret < 0) {
+ dev_err(&client->dev, "unable to register iio device\n");
+ goto err_buffer_cleanup;
+ }
+ return 0;
+
+err_buffer_cleanup:
+ iio_triggered_buffer_cleanup(indio_dev);
+err_poweroff:
+ i2c_smbus_write_byte_data(client, CCS811_MEAS_MODE, CCS811_MODE_IDLE);
+
+ return ret;
+}
+
+static int ccs811_remove(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+
+ iio_device_unregister(indio_dev);
+ iio_triggered_buffer_cleanup(indio_dev);
+
+ return i2c_smbus_write_byte_data(client, CCS811_MEAS_MODE,
+ CCS811_MODE_IDLE);
+}
+
+static const struct i2c_device_id ccs811_id[] = {
+ {"ccs811", 0},
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ccs811_id);
+
+static struct i2c_driver ccs811_driver = {
+ .driver = {
+ .name = "ccs811",
+ },
+ .probe = ccs811_probe,
+ .remove = ccs811_remove,
+ .id_table = ccs811_id,
+};
+module_i2c_driver(ccs811_driver);
+
+MODULE_AUTHOR("Narcisa Vasile <narcisaanamaria12@gmail.com>");
+MODULE_DESCRIPTION("CCS811 volatile organic compounds sensor");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c
index 6e6a1ec..d99bb14 100644
--- a/drivers/iio/common/st_sensors/st_sensors_core.c
+++ b/drivers/iio/common/st_sensors/st_sensors_core.c
@@ -15,6 +15,7 @@
#include <linux/iio/iio.h>
#include <linux/regulator/consumer.h>
#include <linux/of.h>
+#include <linux/of_device.h>
#include <asm/unaligned.h>
#include <linux/iio/common/st_sensors.h>
@@ -345,6 +346,36 @@ static struct st_sensors_platform_data *st_sensors_of_probe(struct device *dev,
return pdata;
}
+
+/**
+ * st_sensors_of_name_probe() - device tree probe for ST sensor name
+ * @dev: driver model representation of the device.
+ * @match: the OF match table for the device, containing compatible strings
+ * but also a .data field with the corresponding internal kernel name
+ * used by this sensor.
+ * @name: device name buffer reference.
+ * @len: device name buffer length.
+ *
+ * In effect this function matches a compatible string to an internal kernel
+ * name for a certain sensor device, so that the rest of the autodetection can
+ * rely on that name from this point on. I2C/SPI devices will be renamed
+ * to match the internal kernel convention.
+ */
+void st_sensors_of_name_probe(struct device *dev,
+ const struct of_device_id *match,
+ char *name, int len)
+{
+ const struct of_device_id *of_id;
+
+ of_id = of_match_device(match, dev);
+ if (!of_id || !of_id->data)
+ return;
+
+ /* The name from the OF match takes precedence if present */
+ strncpy(name, of_id->data, len);
+ name[len - 1] = '\0';
+}
+EXPORT_SYMBOL(st_sensors_of_name_probe);
#else
static struct st_sensors_platform_data *st_sensors_of_probe(struct device *dev,
struct st_sensors_platform_data *defdata)
diff --git a/drivers/iio/common/st_sensors/st_sensors_i2c.c b/drivers/iio/common/st_sensors/st_sensors_i2c.c
index c83df4d..b81e48e 100644
--- a/drivers/iio/common/st_sensors/st_sensors_i2c.c
+++ b/drivers/iio/common/st_sensors/st_sensors_i2c.c
@@ -79,35 +79,6 @@ void st_sensors_i2c_configure(struct iio_dev *indio_dev,
}
EXPORT_SYMBOL(st_sensors_i2c_configure);
-#ifdef CONFIG_OF
-/**
- * st_sensors_of_i2c_probe() - device tree probe for ST I2C sensors
- * @client: the I2C client device for the sensor
- * @match: the OF match table for the device, containing compatible strings
- * but also a .data field with the corresponding internal kernel name
- * used by this sensor.
- *
- * In effect this function matches a compatible string to an internal kernel
- * name for a certain sensor device, so that the rest of the autodetection can
- * rely on that name from this point on. I2C client devices will be renamed
- * to match the internal kernel convention.
- */
-void st_sensors_of_i2c_probe(struct i2c_client *client,
- const struct of_device_id *match)
-{
- const struct of_device_id *of_id;
-
- of_id = of_match_device(match, &client->dev);
- if (!of_id)
- return;
-
- /* The name from the OF match takes precedence if present */
- strncpy(client->name, of_id->data, sizeof(client->name));
- client->name[sizeof(client->name) - 1] = '\0';
-}
-EXPORT_SYMBOL(st_sensors_of_i2c_probe);
-#endif
-
#ifdef CONFIG_ACPI
int st_sensors_match_acpi_device(struct device *dev)
{
diff --git a/drivers/iio/dac/stm32-dac-core.c b/drivers/iio/dac/stm32-dac-core.c
index 75e4878..55026fe 100644
--- a/drivers/iio/dac/stm32-dac-core.c
+++ b/drivers/iio/dac/stm32-dac-core.c
@@ -42,6 +42,14 @@ struct stm32_dac_priv {
struct stm32_dac_common common;
};
+/**
+ * struct stm32_dac_cfg - DAC configuration
+ * @has_hfsel: DAC has high frequency control
+ */
+struct stm32_dac_cfg {
+ bool has_hfsel;
+};
+
static struct stm32_dac_priv *to_stm32_dac_priv(struct stm32_dac_common *com)
{
return container_of(com, struct stm32_dac_priv, common);
@@ -57,6 +65,7 @@ static const struct regmap_config stm32_dac_regmap_cfg = {
static int stm32_dac_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
+ const struct stm32_dac_cfg *cfg;
struct stm32_dac_priv *priv;
struct regmap *regmap;
struct resource *res;
@@ -69,6 +78,8 @@ static int stm32_dac_probe(struct platform_device *pdev)
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
+ cfg = (const struct stm32_dac_cfg *)
+ of_match_device(dev->driver->of_match_table, dev)->data;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mmio = devm_ioremap_resource(dev, res);
@@ -114,19 +125,23 @@ static int stm32_dac_probe(struct platform_device *pdev)
goto err_vref;
}
- priv->rst = devm_reset_control_get(dev, NULL);
+ priv->rst = devm_reset_control_get_exclusive(dev, NULL);
if (!IS_ERR(priv->rst)) {
reset_control_assert(priv->rst);
udelay(2);
reset_control_deassert(priv->rst);
}
- /* When clock speed is higher than 80MHz, set HFSEL */
- priv->common.hfsel = (clk_get_rate(priv->pclk) > 80000000UL);
- ret = regmap_update_bits(regmap, STM32_DAC_CR, STM32H7_DAC_CR_HFSEL,
- priv->common.hfsel ? STM32H7_DAC_CR_HFSEL : 0);
- if (ret)
- goto err_pclk;
+ if (cfg && cfg->has_hfsel) {
+ /* When clock speed is higher than 80MHz, set HFSEL */
+ priv->common.hfsel = (clk_get_rate(priv->pclk) > 80000000UL);
+ ret = regmap_update_bits(regmap, STM32_DAC_CR,
+ STM32H7_DAC_CR_HFSEL,
+ priv->common.hfsel ?
+ STM32H7_DAC_CR_HFSEL : 0);
+ if (ret)
+ goto err_pclk;
+ }
platform_set_drvdata(pdev, &priv->common);
@@ -158,8 +173,17 @@ static int stm32_dac_remove(struct platform_device *pdev)
return 0;
}
+static const struct stm32_dac_cfg stm32h7_dac_cfg = {
+ .has_hfsel = true,
+};
+
static const struct of_device_id stm32_dac_of_match[] = {
- { .compatible = "st,stm32h7-dac-core", },
+ {
+ .compatible = "st,stm32f4-dac-core",
+ }, {
+ .compatible = "st,stm32h7-dac-core",
+ .data = (void *)&stm32h7_dac_cfg,
+ },
{},
};
MODULE_DEVICE_TABLE(of, stm32_dac_of_match);
diff --git a/drivers/iio/dac/stm32-dac.c b/drivers/iio/dac/stm32-dac.c
index 50f8ec0..c1864e8 100644
--- a/drivers/iio/dac/stm32-dac.c
+++ b/drivers/iio/dac/stm32-dac.c
@@ -268,7 +268,7 @@ static int stm32_dac_chan_of_init(struct iio_dev *indio_dev)
break;
}
if (i >= ARRAY_SIZE(stm32_dac_channels)) {
- dev_err(&indio_dev->dev, "Invalid st,dac-channel\n");
+ dev_err(&indio_dev->dev, "Invalid reg property\n");
return -EINVAL;
}
diff --git a/drivers/iio/gyro/mpu3050-core.c b/drivers/iio/gyro/mpu3050-core.c
index 2be2a5d..e0d241a 100644
--- a/drivers/iio/gyro/mpu3050-core.c
+++ b/drivers/iio/gyro/mpu3050-core.c
@@ -1063,11 +1063,6 @@ static int mpu3050_trigger_probe(struct iio_dev *indio_dev, int irq)
case IRQF_TRIGGER_RISING:
dev_info(&indio_dev->dev,
"pulse interrupts on the rising edge\n");
- if (mpu3050->irq_opendrain) {
- dev_info(&indio_dev->dev,
- "rising edge incompatible with open drain\n");
- mpu3050->irq_opendrain = false;
- }
break;
case IRQF_TRIGGER_FALLING:
mpu3050->irq_actl = true;
@@ -1078,11 +1073,6 @@ static int mpu3050_trigger_probe(struct iio_dev *indio_dev, int irq)
mpu3050->irq_latch = true;
dev_info(&indio_dev->dev,
"interrupts active high level\n");
- if (mpu3050->irq_opendrain) {
- dev_info(&indio_dev->dev,
- "active high incompatible with open drain\n");
- mpu3050->irq_opendrain = false;
- }
/*
* With level IRQs, we mask the IRQ until it is processed,
* but with edge IRQs (pulses) we can queue several interrupts
diff --git a/drivers/iio/gyro/st_gyro.h b/drivers/iio/gyro/st_gyro.h
index a5c5c4e..48923ae 100644
--- a/drivers/iio/gyro/st_gyro.h
+++ b/drivers/iio/gyro/st_gyro.h
@@ -19,6 +19,7 @@
#define LSM330DL_GYRO_DEV_NAME "lsm330dl_gyro"
#define LSM330DLC_GYRO_DEV_NAME "lsm330dlc_gyro"
#define L3GD20_GYRO_DEV_NAME "l3gd20"
+#define L3GD20H_GYRO_DEV_NAME "l3gd20h"
#define L3G4IS_GYRO_DEV_NAME "l3g4is_ui"
#define LSM330_GYRO_DEV_NAME "lsm330_gyro"
#define LSM9DS0_GYRO_DEV_NAME "lsm9ds0_gyro"
diff --git a/drivers/iio/gyro/st_gyro_core.c b/drivers/iio/gyro/st_gyro_core.c
index 2a42b3d..e366422 100644
--- a/drivers/iio/gyro/st_gyro_core.c
+++ b/drivers/iio/gyro/st_gyro_core.c
@@ -35,6 +35,7 @@
#define ST_GYRO_DEFAULT_OUT_Z_L_ADDR 0x2c
/* FULLSCALE */
+#define ST_GYRO_FS_AVL_245DPS 245
#define ST_GYRO_FS_AVL_250DPS 250
#define ST_GYRO_FS_AVL_500DPS 500
#define ST_GYRO_FS_AVL_2000DPS 2000
@@ -196,17 +197,17 @@ static const struct st_sensor_settings st_gyro_sensors_settings[] = {
.wai = 0xd7,
.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
.sensors_supported = {
- [0] = L3GD20_GYRO_DEV_NAME,
+ [0] = L3GD20H_GYRO_DEV_NAME,
},
.ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
.odr = {
.addr = 0x20,
.mask = 0xc0,
.odr_avl = {
- { .hz = 95, .value = 0x00, },
- { .hz = 190, .value = 0x01, },
- { .hz = 380, .value = 0x02, },
- { .hz = 760, .value = 0x03, },
+ { .hz = 100, .value = 0x00, },
+ { .hz = 200, .value = 0x01, },
+ { .hz = 400, .value = 0x02, },
+ { .hz = 800, .value = 0x03, },
},
},
.pw = {
@@ -224,7 +225,7 @@ static const struct st_sensor_settings st_gyro_sensors_settings[] = {
.mask = 0x30,
.fs_avl = {
[0] = {
- .num = ST_GYRO_FS_AVL_250DPS,
+ .num = ST_GYRO_FS_AVL_245DPS,
.value = 0x00,
.gain = IIO_DEGREE_TO_RAD(8750),
},
diff --git a/drivers/iio/gyro/st_gyro_i2c.c b/drivers/iio/gyro/st_gyro_i2c.c
index 40056b8..b405b82 100644
--- a/drivers/iio/gyro/st_gyro_i2c.c
+++ b/drivers/iio/gyro/st_gyro_i2c.c
@@ -41,6 +41,10 @@ static const struct of_device_id st_gyro_of_match[] = {
.data = L3GD20_GYRO_DEV_NAME,
},
{
+ .compatible = "st,l3gd20h-gyro",
+ .data = L3GD20H_GYRO_DEV_NAME,
+ },
+ {
.compatible = "st,l3g4is-gyro",
.data = L3G4IS_GYRO_DEV_NAME,
},
@@ -71,7 +75,8 @@ static int st_gyro_i2c_probe(struct i2c_client *client,
return -ENOMEM;
gdata = iio_priv(indio_dev);
- st_sensors_of_i2c_probe(client, st_gyro_of_match);
+ st_sensors_of_name_probe(&client->dev, st_gyro_of_match,
+ client->name, sizeof(client->name));
st_sensors_i2c_configure(indio_dev, client, gdata);
@@ -95,6 +100,7 @@ static const struct i2c_device_id st_gyro_id_table[] = {
{ LSM330DL_GYRO_DEV_NAME },
{ LSM330DLC_GYRO_DEV_NAME },
{ L3GD20_GYRO_DEV_NAME },
+ { L3GD20H_GYRO_DEV_NAME },
{ L3G4IS_GYRO_DEV_NAME },
{ LSM330_GYRO_DEV_NAME },
{ LSM9DS0_GYRO_DEV_NAME },
diff --git a/drivers/iio/gyro/st_gyro_spi.c b/drivers/iio/gyro/st_gyro_spi.c
index fbf2fae..0b52ed5 100644
--- a/drivers/iio/gyro/st_gyro_spi.c
+++ b/drivers/iio/gyro/st_gyro_spi.c
@@ -18,6 +18,56 @@
#include <linux/iio/common/st_sensors_spi.h>
#include "st_gyro.h"
+#ifdef CONFIG_OF
+/*
+ * For new single-chip sensors use <device_name> as compatible string.
+ * For old single-chip devices keep <device_name>-gyro to maintain
+ * compatibility
+ */
+static const struct of_device_id st_gyro_of_match[] = {
+ {
+ .compatible = "st,l3g4200d-gyro",
+ .data = L3G4200D_GYRO_DEV_NAME,
+ },
+ {
+ .compatible = "st,lsm330d-gyro",
+ .data = LSM330D_GYRO_DEV_NAME,
+ },
+ {
+ .compatible = "st,lsm330dl-gyro",
+ .data = LSM330DL_GYRO_DEV_NAME,
+ },
+ {
+ .compatible = "st,lsm330dlc-gyro",
+ .data = LSM330DLC_GYRO_DEV_NAME,
+ },
+ {
+ .compatible = "st,l3gd20-gyro",
+ .data = L3GD20_GYRO_DEV_NAME,
+ },
+ {
+ .compatible = "st,l3gd20h-gyro",
+ .data = L3GD20H_GYRO_DEV_NAME,
+ },
+ {
+ .compatible = "st,l3g4is-gyro",
+ .data = L3G4IS_GYRO_DEV_NAME,
+ },
+ {
+ .compatible = "st,lsm330-gyro",
+ .data = LSM330_GYRO_DEV_NAME,
+ },
+ {
+ .compatible = "st,lsm9ds0-gyro",
+ .data = LSM9DS0_GYRO_DEV_NAME,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, st_gyro_of_match);
+#else
+#define st_gyro_of_match NULL
+#endif
+
static int st_gyro_spi_probe(struct spi_device *spi)
{
struct iio_dev *indio_dev;
@@ -30,6 +80,8 @@ static int st_gyro_spi_probe(struct spi_device *spi)
gdata = iio_priv(indio_dev);
+ st_sensors_of_name_probe(&spi->dev, st_gyro_of_match,
+ spi->modalias, sizeof(spi->modalias));
st_sensors_spi_configure(indio_dev, spi, gdata);
err = st_gyro_common_probe(indio_dev);
@@ -52,6 +104,7 @@ static const struct spi_device_id st_gyro_id_table[] = {
{ LSM330DL_GYRO_DEV_NAME },
{ LSM330DLC_GYRO_DEV_NAME },
{ L3GD20_GYRO_DEV_NAME },
+ { L3GD20H_GYRO_DEV_NAME },
{ L3G4IS_GYRO_DEV_NAME },
{ LSM330_GYRO_DEV_NAME },
{ LSM9DS0_GYRO_DEV_NAME },
@@ -62,6 +115,7 @@ MODULE_DEVICE_TABLE(spi, st_gyro_id_table);
static struct spi_driver st_gyro_driver = {
.driver = {
.name = "st-gyro-spi",
+ .of_match_table = of_match_ptr(st_gyro_of_match),
},
.probe = st_gyro_spi_probe,
.remove = st_gyro_spi_remove,
diff --git a/drivers/iio/humidity/Kconfig b/drivers/iio/humidity/Kconfig
index 14b9ce4..2c0fc9a 100644
--- a/drivers/iio/humidity/Kconfig
+++ b/drivers/iio/humidity/Kconfig
@@ -31,7 +31,8 @@ config HDC100X
select IIO_TRIGGERED_BUFFER
help
Say yes here to build support for the Texas Instruments
- HDC1000 and HDC1008 relative humidity and temperature sensors.
+ HDC1000, HDC1008, HDC1010, HDC1050, and HDC1080 relative
+ humidity and temperature sensors.
To compile this driver as a module, choose M here: the module
will be called hdc100x.
diff --git a/drivers/iio/humidity/hdc100x.c b/drivers/iio/humidity/hdc100x.c
index aa17115..7851bd9 100644
--- a/drivers/iio/humidity/hdc100x.c
+++ b/drivers/iio/humidity/hdc100x.c
@@ -13,6 +13,12 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
+ * Datasheets:
+ * http://www.ti.com/product/HDC1000/datasheet
+ * http://www.ti.com/product/HDC1008/datasheet
+ * http://www.ti.com/product/HDC1010/datasheet
+ * http://www.ti.com/product/HDC1050/datasheet
+ * http://www.ti.com/product/HDC1080/datasheet
*/
#include <linux/delay.h>
@@ -414,13 +420,29 @@ static int hdc100x_remove(struct i2c_client *client)
static const struct i2c_device_id hdc100x_id[] = {
{ "hdc100x", 0 },
+ { "hdc1000", 0 },
+ { "hdc1008", 0 },
+ { "hdc1010", 0 },
+ { "hdc1050", 0 },
+ { "hdc1080", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, hdc100x_id);
+static const struct of_device_id hdc100x_dt_ids[] = {
+ { .compatible = "ti,hdc1000" },
+ { .compatible = "ti,hdc1008" },
+ { .compatible = "ti,hdc1010" },
+ { .compatible = "ti,hdc1050" },
+ { .compatible = "ti,hdc1080" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, hdc100x_dt_ids);
+
static struct i2c_driver hdc100x_driver = {
.driver = {
.name = "hdc100x",
+ .of_match_table = of_match_ptr(hdc100x_dt_ids),
},
.probe = hdc100x_probe,
.remove = hdc100x_remove,
diff --git a/drivers/iio/humidity/hts221.h b/drivers/iio/humidity/hts221.h
index 9451026..51d0219 100644
--- a/drivers/iio/humidity/hts221.h
+++ b/drivers/iio/humidity/hts221.h
@@ -30,12 +30,6 @@ struct hts221_transfer_function {
int (*write)(struct device *dev, u8 addr, int len, u8 *data);
};
-#define HTS221_AVG_DEPTH 8
-struct hts221_avg_avl {
- u16 avg;
- u8 val;
-};
-
enum hts221_sensor_type {
HTS221_SENSOR_H,
HTS221_SENSOR_T,
@@ -66,10 +60,9 @@ struct hts221_hw {
extern const struct dev_pm_ops hts221_pm_ops;
-int hts221_config_drdy(struct hts221_hw *hw, bool enable);
+int hts221_write_with_mask(struct hts221_hw *hw, u8 addr, u8 mask, u8 val);
int hts221_probe(struct iio_dev *iio_dev);
-int hts221_power_on(struct hts221_hw *hw);
-int hts221_power_off(struct hts221_hw *hw);
+int hts221_set_enable(struct hts221_hw *hw, bool enable);
int hts221_allocate_buffers(struct hts221_hw *hw);
int hts221_allocate_trigger(struct hts221_hw *hw);
diff --git a/drivers/iio/humidity/hts221_buffer.c b/drivers/iio/humidity/hts221_buffer.c
index 7d19a3d..9690dfe 100644
--- a/drivers/iio/humidity/hts221_buffer.c
+++ b/drivers/iio/humidity/hts221_buffer.c
@@ -20,8 +20,16 @@
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/buffer.h>
+#include <linux/platform_data/st_sensors_pdata.h>
+
#include "hts221.h"
+#define HTS221_REG_DRDY_HL_ADDR 0x22
+#define HTS221_REG_DRDY_HL_MASK BIT(7)
+#define HTS221_REG_DRDY_PP_OD_ADDR 0x22
+#define HTS221_REG_DRDY_PP_OD_MASK BIT(6)
+#define HTS221_REG_DRDY_EN_ADDR 0x22
+#define HTS221_REG_DRDY_EN_MASK BIT(2)
#define HTS221_REG_STATUS_ADDR 0x27
#define HTS221_RH_DRDY_MASK BIT(1)
#define HTS221_TEMP_DRDY_MASK BIT(0)
@@ -30,8 +38,12 @@ static int hts221_trig_set_state(struct iio_trigger *trig, bool state)
{
struct iio_dev *iio_dev = iio_trigger_get_drvdata(trig);
struct hts221_hw *hw = iio_priv(iio_dev);
+ int err;
+
+ err = hts221_write_with_mask(hw, HTS221_REG_DRDY_EN_ADDR,
+ HTS221_REG_DRDY_EN_MASK, state);
- return hts221_config_drdy(hw, state);
+ return err < 0 ? err : 0;
}
static const struct iio_trigger_ops hts221_trigger_ops = {
@@ -67,6 +79,9 @@ static irqreturn_t hts221_trigger_handler_thread(int irq, void *private)
int hts221_allocate_trigger(struct hts221_hw *hw)
{
struct iio_dev *iio_dev = iio_priv_to_dev(hw);
+ bool irq_active_low = false, open_drain = false;
+ struct device_node *np = hw->dev->of_node;
+ struct st_sensors_platform_data *pdata;
unsigned long irq_type;
int err;
@@ -76,6 +91,10 @@ int hts221_allocate_trigger(struct hts221_hw *hw)
case IRQF_TRIGGER_HIGH:
case IRQF_TRIGGER_RISING:
break;
+ case IRQF_TRIGGER_LOW:
+ case IRQF_TRIGGER_FALLING:
+ irq_active_low = true;
+ break;
default:
dev_info(hw->dev,
"mode %lx unsupported, using IRQF_TRIGGER_RISING\n",
@@ -84,6 +103,24 @@ int hts221_allocate_trigger(struct hts221_hw *hw)
break;
}
+ err = hts221_write_with_mask(hw, HTS221_REG_DRDY_HL_ADDR,
+ HTS221_REG_DRDY_HL_MASK, irq_active_low);
+ if (err < 0)
+ return err;
+
+ pdata = (struct st_sensors_platform_data *)hw->dev->platform_data;
+ if ((np && of_property_read_bool(np, "drive-open-drain")) ||
+ (pdata && pdata->open_drain)) {
+ irq_type |= IRQF_SHARED;
+ open_drain = true;
+ }
+
+ err = hts221_write_with_mask(hw, HTS221_REG_DRDY_PP_OD_ADDR,
+ HTS221_REG_DRDY_PP_OD_MASK,
+ open_drain);
+ if (err < 0)
+ return err;
+
err = devm_request_threaded_irq(hw->dev, hw->irq, NULL,
hts221_trigger_handler_thread,
irq_type | IRQF_ONESHOT,
@@ -109,12 +146,12 @@ int hts221_allocate_trigger(struct hts221_hw *hw)
static int hts221_buffer_preenable(struct iio_dev *iio_dev)
{
- return hts221_power_on(iio_priv(iio_dev));
+ return hts221_set_enable(iio_priv(iio_dev), true);
}
static int hts221_buffer_postdisable(struct iio_dev *iio_dev)
{
- return hts221_power_off(iio_priv(iio_dev));
+ return hts221_set_enable(iio_priv(iio_dev), false);
}
static const struct iio_buffer_setup_ops hts221_buffer_ops = {
diff --git a/drivers/iio/humidity/hts221_core.c b/drivers/iio/humidity/hts221_core.c
index a56da39..32524a8 100644
--- a/drivers/iio/humidity/hts221_core.c
+++ b/drivers/iio/humidity/hts221_core.c
@@ -23,7 +23,6 @@
#define HTS221_REG_CNTRL1_ADDR 0x20
#define HTS221_REG_CNTRL2_ADDR 0x21
-#define HTS221_REG_CNTRL3_ADDR 0x22
#define HTS221_REG_AVG_ADDR 0x10
#define HTS221_REG_H_OUT_L 0x28
@@ -32,30 +31,9 @@
#define HTS221_HUMIDITY_AVG_MASK 0x07
#define HTS221_TEMP_AVG_MASK 0x38
-#define HTS221_ODR_MASK 0x87
+#define HTS221_ODR_MASK 0x03
#define HTS221_BDU_MASK BIT(2)
-
-#define HTS221_DRDY_MASK BIT(2)
-
-#define HTS221_ENABLE_SENSOR BIT(7)
-
-#define HTS221_HUMIDITY_AVG_4 0x00 /* 0.4 %RH */
-#define HTS221_HUMIDITY_AVG_8 0x01 /* 0.3 %RH */
-#define HTS221_HUMIDITY_AVG_16 0x02 /* 0.2 %RH */
-#define HTS221_HUMIDITY_AVG_32 0x03 /* 0.15 %RH */
-#define HTS221_HUMIDITY_AVG_64 0x04 /* 0.1 %RH */
-#define HTS221_HUMIDITY_AVG_128 0x05 /* 0.07 %RH */
-#define HTS221_HUMIDITY_AVG_256 0x06 /* 0.05 %RH */
-#define HTS221_HUMIDITY_AVG_512 0x07 /* 0.03 %RH */
-
-#define HTS221_TEMP_AVG_2 0x00 /* 0.08 degC */
-#define HTS221_TEMP_AVG_4 0x08 /* 0.05 degC */
-#define HTS221_TEMP_AVG_8 0x10 /* 0.04 degC */
-#define HTS221_TEMP_AVG_16 0x18 /* 0.03 degC */
-#define HTS221_TEMP_AVG_32 0x20 /* 0.02 degC */
-#define HTS221_TEMP_AVG_64 0x28 /* 0.015 degC */
-#define HTS221_TEMP_AVG_128 0x30 /* 0.01 degC */
-#define HTS221_TEMP_AVG_256 0x38 /* 0.007 degC */
+#define HTS221_ENABLE_MASK BIT(7)
/* calibration registers */
#define HTS221_REG_0RH_CAL_X_H 0x36
@@ -73,10 +51,11 @@ struct hts221_odr {
u8 val;
};
+#define HTS221_AVG_DEPTH 8
struct hts221_avg {
u8 addr;
u8 mask;
- struct hts221_avg_avl avg_avl[HTS221_AVG_DEPTH];
+ u16 avg_avl[HTS221_AVG_DEPTH];
};
static const struct hts221_odr hts221_odr_table[] = {
@@ -90,28 +69,28 @@ static const struct hts221_avg hts221_avg_list[] = {
.addr = HTS221_REG_AVG_ADDR,
.mask = HTS221_HUMIDITY_AVG_MASK,
.avg_avl = {
- { 4, HTS221_HUMIDITY_AVG_4 },
- { 8, HTS221_HUMIDITY_AVG_8 },
- { 16, HTS221_HUMIDITY_AVG_16 },
- { 32, HTS221_HUMIDITY_AVG_32 },
- { 64, HTS221_HUMIDITY_AVG_64 },
- { 128, HTS221_HUMIDITY_AVG_128 },
- { 256, HTS221_HUMIDITY_AVG_256 },
- { 512, HTS221_HUMIDITY_AVG_512 },
+ 4, /* 0.4 %RH */
+ 8, /* 0.3 %RH */
+ 16, /* 0.2 %RH */
+ 32, /* 0.15 %RH */
+ 64, /* 0.1 %RH */
+ 128, /* 0.07 %RH */
+ 256, /* 0.05 %RH */
+ 512, /* 0.03 %RH */
},
},
{
.addr = HTS221_REG_AVG_ADDR,
.mask = HTS221_TEMP_AVG_MASK,
.avg_avl = {
- { 2, HTS221_TEMP_AVG_2 },
- { 4, HTS221_TEMP_AVG_4 },
- { 8, HTS221_TEMP_AVG_8 },
- { 16, HTS221_TEMP_AVG_16 },
- { 32, HTS221_TEMP_AVG_32 },
- { 64, HTS221_TEMP_AVG_64 },
- { 128, HTS221_TEMP_AVG_128 },
- { 256, HTS221_TEMP_AVG_256 },
+ 2, /* 0.08 degC */
+ 4, /* 0.05 degC */
+ 8, /* 0.04 degC */
+ 16, /* 0.03 degC */
+ 32, /* 0.02 degC */
+ 64, /* 0.015 degC */
+ 128, /* 0.01 degC */
+ 256, /* 0.007 degC */
},
},
};
@@ -152,8 +131,7 @@ static const struct iio_chan_spec hts221_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(2),
};
-static int hts221_write_with_mask(struct hts221_hw *hw, u8 addr, u8 mask,
- u8 val)
+int hts221_write_with_mask(struct hts221_hw *hw, u8 addr, u8 mask, u8 val)
{
u8 data;
int err;
@@ -166,7 +144,7 @@ static int hts221_write_with_mask(struct hts221_hw *hw, u8 addr, u8 mask,
goto unlock;
}
- data = (data & ~mask) | (val & mask);
+ data = (data & ~mask) | ((val << __ffs(mask)) & mask);
err = hw->tf->write(hw->dev, addr, sizeof(data), &data);
if (err < 0)
@@ -199,21 +177,9 @@ static int hts221_check_whoami(struct hts221_hw *hw)
return 0;
}
-int hts221_config_drdy(struct hts221_hw *hw, bool enable)
-{
- u8 val = enable ? BIT(2) : 0;
- int err;
-
- err = hts221_write_with_mask(hw, HTS221_REG_CNTRL3_ADDR,
- HTS221_DRDY_MASK, val);
-
- return err < 0 ? err : 0;
-}
-
static int hts221_update_odr(struct hts221_hw *hw, u8 odr)
{
int i, err;
- u8 val;
for (i = 0; i < ARRAY_SIZE(hts221_odr_table); i++)
if (hts221_odr_table[i].hz == odr)
@@ -222,9 +188,8 @@ static int hts221_update_odr(struct hts221_hw *hw, u8 odr)
if (i == ARRAY_SIZE(hts221_odr_table))
return -EINVAL;
- val = HTS221_ENABLE_SENSOR | HTS221_BDU_MASK | hts221_odr_table[i].val;
err = hts221_write_with_mask(hw, HTS221_REG_CNTRL1_ADDR,
- HTS221_ODR_MASK, val);
+ HTS221_ODR_MASK, hts221_odr_table[i].val);
if (err < 0)
return err;
@@ -241,14 +206,13 @@ static int hts221_update_avg(struct hts221_hw *hw,
const struct hts221_avg *avg = &hts221_avg_list[type];
for (i = 0; i < HTS221_AVG_DEPTH; i++)
- if (avg->avg_avl[i].avg == val)
+ if (avg->avg_avl[i] == val)
break;
if (i == HTS221_AVG_DEPTH)
return -EINVAL;
- err = hts221_write_with_mask(hw, avg->addr, avg->mask,
- avg->avg_avl[i].val);
+ err = hts221_write_with_mask(hw, avg->addr, avg->mask, i);
if (err < 0)
return err;
@@ -283,7 +247,7 @@ hts221_sysfs_rh_oversampling_avail(struct device *dev,
for (i = 0; i < ARRAY_SIZE(avg->avg_avl); i++)
len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
- avg->avg_avl[i].avg);
+ avg->avg_avl[i]);
buf[len - 1] = '\n';
return len;
@@ -300,36 +264,22 @@ hts221_sysfs_temp_oversampling_avail(struct device *dev,
for (i = 0; i < ARRAY_SIZE(avg->avg_avl); i++)
len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
- avg->avg_avl[i].avg);
+ avg->avg_avl[i]);
buf[len - 1] = '\n';
return len;
}
-int hts221_power_on(struct hts221_hw *hw)
-{
- int err;
-
- err = hts221_update_odr(hw, hw->odr);
- if (err < 0)
- return err;
-
- hw->enabled = true;
-
- return 0;
-}
-
-int hts221_power_off(struct hts221_hw *hw)
+int hts221_set_enable(struct hts221_hw *hw, bool enable)
{
- __le16 data = 0;
int err;
- err = hw->tf->write(hw->dev, HTS221_REG_CNTRL1_ADDR, sizeof(data),
- (u8 *)&data);
+ err = hts221_write_with_mask(hw, HTS221_REG_CNTRL1_ADDR,
+ HTS221_ENABLE_MASK, enable);
if (err < 0)
return err;
- hw->enabled = false;
+ hw->enabled = enable;
return 0;
}
@@ -484,7 +434,7 @@ static int hts221_read_oneshot(struct hts221_hw *hw, u8 addr, int *val)
u8 data[HTS221_DATA_SIZE];
int err;
- err = hts221_power_on(hw);
+ err = hts221_set_enable(hw, true);
if (err < 0)
return err;
@@ -494,7 +444,7 @@ static int hts221_read_oneshot(struct hts221_hw *hw, u8 addr, int *val)
if (err < 0)
return err;
- hts221_power_off(hw);
+ hts221_set_enable(hw, false);
*val = (s16)get_unaligned_le16(data);
@@ -534,13 +484,13 @@ static int hts221_read_raw(struct iio_dev *iio_dev,
case IIO_HUMIDITYRELATIVE:
avg = &hts221_avg_list[HTS221_SENSOR_H];
idx = hw->sensors[HTS221_SENSOR_H].cur_avg_idx;
- *val = avg->avg_avl[idx].avg;
+ *val = avg->avg_avl[idx];
ret = IIO_VAL_INT;
break;
case IIO_TEMP:
avg = &hts221_avg_list[HTS221_SENSOR_T];
idx = hw->sensors[HTS221_SENSOR_T].cur_avg_idx;
- *val = avg->avg_avl[idx].avg;
+ *val = avg->avg_avl[idx];
ret = IIO_VAL_INT;
break;
default:
@@ -644,8 +594,6 @@ int hts221_probe(struct iio_dev *iio_dev)
if (err < 0)
return err;
- hw->odr = hts221_odr_table[0].hz;
-
iio_dev->modes = INDIO_DIRECT_MODE;
iio_dev->dev.parent = hw->dev;
iio_dev->available_scan_masks = hts221_scan_masks;
@@ -654,6 +602,16 @@ int hts221_probe(struct iio_dev *iio_dev)
iio_dev->name = HTS221_DEV_NAME;
iio_dev->info = &hts221_info;
+ /* enable Block Data Update */
+ err = hts221_write_with_mask(hw, HTS221_REG_CNTRL1_ADDR,
+ HTS221_BDU_MASK, 1);
+ if (err < 0)
+ return err;
+
+ err = hts221_update_odr(hw, hts221_odr_table[0].hz);
+ if (err < 0)
+ return err;
+
/* configure humidity sensor */
err = hts221_parse_rh_caldata(hw);
if (err < 0) {
@@ -661,7 +619,7 @@ int hts221_probe(struct iio_dev *iio_dev)
return err;
}
- data = hts221_avg_list[HTS221_SENSOR_H].avg_avl[3].avg;
+ data = hts221_avg_list[HTS221_SENSOR_H].avg_avl[3];
err = hts221_update_avg(hw, HTS221_SENSOR_H, data);
if (err < 0) {
dev_err(hw->dev, "failed to set rh oversampling ratio\n");
@@ -676,7 +634,7 @@ int hts221_probe(struct iio_dev *iio_dev)
return err;
}
- data = hts221_avg_list[HTS221_SENSOR_T].avg_avl[3].avg;
+ data = hts221_avg_list[HTS221_SENSOR_T].avg_avl[3];
err = hts221_update_avg(hw, HTS221_SENSOR_T, data);
if (err < 0) {
dev_err(hw->dev,
@@ -702,11 +660,10 @@ static int __maybe_unused hts221_suspend(struct device *dev)
{
struct iio_dev *iio_dev = dev_get_drvdata(dev);
struct hts221_hw *hw = iio_priv(iio_dev);
- __le16 data = 0;
int err;
- err = hw->tf->write(hw->dev, HTS221_REG_CNTRL1_ADDR, sizeof(data),
- (u8 *)&data);
+ err = hts221_write_with_mask(hw, HTS221_REG_CNTRL1_ADDR,
+ HTS221_ENABLE_MASK, false);
return err < 0 ? err : 0;
}
@@ -718,7 +675,8 @@ static int __maybe_unused hts221_resume(struct device *dev)
int err = 0;
if (hw->enabled)
- err = hts221_update_odr(hw, hw->odr);
+ err = hts221_write_with_mask(hw, HTS221_REG_CNTRL1_ADDR,
+ HTS221_ENABLE_MASK, true);
return err;
}
diff --git a/drivers/iio/humidity/htu21.c b/drivers/iio/humidity/htu21.c
index 0fbbd8c..2c4b9be 100644
--- a/drivers/iio/humidity/htu21.c
+++ b/drivers/iio/humidity/htu21.c
@@ -238,11 +238,19 @@ static const struct i2c_device_id htu21_id[] = {
};
MODULE_DEVICE_TABLE(i2c, htu21_id);
+static const struct of_device_id htu21_of_match[] = {
+ { .compatible = "meas,htu21", },
+ { .compatible = "meas,ms8607-humidity", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, htu21_of_match);
+
static struct i2c_driver htu21_driver = {
.probe = htu21_probe,
.id_table = htu21_id,
.driver = {
.name = "htu21",
+ .of_match_table = of_match_ptr(htu21_of_match),
},
};
diff --git a/drivers/iio/imu/adis16400_core.c b/drivers/iio/imu/adis16400_core.c
index fb7c0db..9b697d3 100644
--- a/drivers/iio/imu/adis16400_core.c
+++ b/drivers/iio/imu/adis16400_core.c
@@ -217,7 +217,7 @@ static int adis16400_set_freq(struct adis16400_state *st, unsigned int freq)
return adis_write_reg_8(&st->adis, ADIS16400_SMPL_PRD, val);
}
-static const unsigned adis16400_3db_divisors[] = {
+static const unsigned int adis16400_3db_divisors[] = {
[0] = 2, /* Special case */
[1] = 6,
[2] = 12,
@@ -890,7 +890,7 @@ static const struct adis_data adis16400_data = {
static void adis16400_setup_chan_mask(struct adis16400_state *st)
{
const struct adis16400_chip_info *chip_info = st->variant;
- unsigned i;
+ unsigned int i;
for (i = 0; i < chip_info->num_channels; i++) {
const struct iio_chan_spec *ch = &chip_info->channels[i];
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
index 2a72acc..e2737dc 100644
--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
@@ -31,6 +31,8 @@
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
+#include <linux/platform_data/st_sensors_pdata.h>
+
#include "st_lsm6dsx.h"
#define ST_LSM6DSX_REG_FIFO_THL_ADDR 0x06
@@ -39,6 +41,8 @@
#define ST_LSM6DSX_REG_FIFO_DEC_GXL_ADDR 0x08
#define ST_LSM6DSX_REG_HLACTIVE_ADDR 0x12
#define ST_LSM6DSX_REG_HLACTIVE_MASK BIT(5)
+#define ST_LSM6DSX_REG_PP_OD_ADDR 0x12
+#define ST_LSM6DSX_REG_PP_OD_MASK BIT(4)
#define ST_LSM6DSX_REG_FIFO_MODE_ADDR 0x0a
#define ST_LSM6DSX_FIFO_MODE_MASK GENMASK(2, 0)
#define ST_LSM6DSX_FIFO_ODR_MASK GENMASK(6, 3)
@@ -417,6 +421,8 @@ static const struct iio_buffer_setup_ops st_lsm6dsx_buffer_ops = {
int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw)
{
+ struct device_node *np = hw->dev->of_node;
+ struct st_sensors_platform_data *pdata;
struct iio_buffer *buffer;
unsigned long irq_type;
bool irq_active_low;
@@ -444,6 +450,17 @@ int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw)
if (err < 0)
return err;
+ pdata = (struct st_sensors_platform_data *)hw->dev->platform_data;
+ if ((np && of_property_read_bool(np, "drive-open-drain")) ||
+ (pdata && pdata->open_drain)) {
+ err = st_lsm6dsx_write_with_mask(hw, ST_LSM6DSX_REG_PP_OD_ADDR,
+ ST_LSM6DSX_REG_PP_OD_MASK, 1);
+ if (err < 0)
+ return err;
+
+ irq_type |= IRQF_SHARED;
+ }
+
err = devm_request_threaded_irq(hw->dev, hw->irq,
st_lsm6dsx_handler_irq,
st_lsm6dsx_handler_thread,
diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
index da3d06b..069defc 100644
--- a/drivers/iio/inkern.c
+++ b/drivers/iio/inkern.c
@@ -44,7 +44,7 @@ int iio_map_array_register(struct iio_dev *indio_dev, struct iio_map *maps)
}
mapi->map = &maps[i];
mapi->indio_dev = indio_dev;
- list_add(&mapi->l, &iio_map_list);
+ list_add_tail(&mapi->l, &iio_map_list);
i++;
}
error_ret:
@@ -205,8 +205,8 @@ static struct iio_channel *of_iio_channel_get_by_name(struct device_node *np,
if (!IS_ERR(chan) || PTR_ERR(chan) == -EPROBE_DEFER)
break;
else if (name && index >= 0) {
- pr_err("ERROR: could not get IIO channel %s:%s(%i)\n",
- np->full_name, name ? name : "", index);
+ pr_err("ERROR: could not get IIO channel %pOF:%s(%i)\n",
+ np, name ? name : "", index);
return NULL;
}
diff --git a/drivers/iio/light/apds9300.c b/drivers/iio/light/apds9300.c
index 649b26f..05eacd1 100644
--- a/drivers/iio/light/apds9300.c
+++ b/drivers/iio/light/apds9300.c
@@ -505,7 +505,7 @@ static SIMPLE_DEV_PM_OPS(apds9300_pm_ops, apds9300_suspend, apds9300_resume);
#define APDS9300_PM_OPS NULL
#endif
-static struct i2c_device_id apds9300_id[] = {
+static const struct i2c_device_id apds9300_id[] = {
{ APDS9300_DRV_NAME, 0 },
{ }
};
diff --git a/drivers/iio/light/rpr0521.c b/drivers/iio/light/rpr0521.c
index 9d0c2e8..a6efa126 100644
--- a/drivers/iio/light/rpr0521.c
+++ b/drivers/iio/light/rpr0521.c
@@ -9,7 +9,7 @@
*
* IIO driver for RPR-0521RS (7-bit I2C slave address 0x38).
*
- * TODO: illuminance channel, buffer
+ * TODO: illuminance channel
*/
#include <linux/module.h>
@@ -20,6 +20,10 @@
#include <linux/acpi.h>
#include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
#include <linux/iio/sysfs.h>
#include <linux/pm_runtime.h>
@@ -30,6 +34,7 @@
#define RPR0521_REG_PXS_DATA 0x44 /* 16-bit, little endian */
#define RPR0521_REG_ALS_DATA0 0x46 /* 16-bit, little endian */
#define RPR0521_REG_ALS_DATA1 0x48 /* 16-bit, little endian */
+#define RPR0521_REG_INTERRUPT 0x4A
#define RPR0521_REG_PS_OFFSET_LSB 0x53
#define RPR0521_REG_ID 0x92
@@ -42,16 +47,31 @@
#define RPR0521_ALS_DATA1_GAIN_SHIFT 2
#define RPR0521_PXS_GAIN_MASK GENMASK(5, 4)
#define RPR0521_PXS_GAIN_SHIFT 4
+#define RPR0521_PXS_PERSISTENCE_MASK GENMASK(3, 0)
+#define RPR0521_INTERRUPT_INT_TRIG_PS_MASK BIT(0)
+#define RPR0521_INTERRUPT_INT_TRIG_ALS_MASK BIT(1)
+#define RPR0521_INTERRUPT_INT_REASSERT_MASK BIT(3)
+#define RPR0521_INTERRUPT_ALS_INT_STATUS_MASK BIT(6)
+#define RPR0521_INTERRUPT_PS_INT_STATUS_MASK BIT(7)
#define RPR0521_MODE_ALS_ENABLE BIT(7)
#define RPR0521_MODE_ALS_DISABLE 0x00
#define RPR0521_MODE_PXS_ENABLE BIT(6)
#define RPR0521_MODE_PXS_DISABLE 0x00
+#define RPR0521_PXS_PERSISTENCE_DRDY 0x00
+
+#define RPR0521_INTERRUPT_INT_TRIG_PS_ENABLE BIT(0)
+#define RPR0521_INTERRUPT_INT_TRIG_PS_DISABLE 0x00
+#define RPR0521_INTERRUPT_INT_TRIG_ALS_ENABLE BIT(1)
+#define RPR0521_INTERRUPT_INT_TRIG_ALS_DISABLE 0x00
+#define RPR0521_INTERRUPT_INT_REASSERT_ENABLE BIT(3)
+#define RPR0521_INTERRUPT_INT_REASSERT_DISABLE 0x00
#define RPR0521_MANUFACT_ID 0xE0
#define RPR0521_DEFAULT_MEAS_TIME 0x06 /* ALS - 100ms, PXS - 100ms */
#define RPR0521_DRV_NAME "RPR0521"
+#define RPR0521_IRQ_NAME "rpr0521_event"
#define RPR0521_REGMAP_NAME "rpr0521_regmap"
#define RPR0521_SLEEP_DELAY_MS 2000
@@ -167,6 +187,9 @@ struct rpr0521_data {
bool als_dev_en;
bool pxs_dev_en;
+ struct iio_trigger *drdy_trigger0;
+ s64 irq_timestamp;
+
/* optimize runtime pm ops - enable/disable device only if needed */
bool als_ps_need_en;
bool pxs_ps_need_en;
@@ -196,6 +219,19 @@ static const struct attribute_group rpr0521_attribute_group = {
.attrs = rpr0521_attributes,
};
+/* Order of the channel data in buffer */
+enum rpr0521_scan_index_order {
+ RPR0521_CHAN_INDEX_PXS,
+ RPR0521_CHAN_INDEX_BOTH,
+ RPR0521_CHAN_INDEX_IR,
+};
+
+static const unsigned long rpr0521_available_scan_masks[] = {
+ BIT(RPR0521_CHAN_INDEX_PXS) | BIT(RPR0521_CHAN_INDEX_BOTH) |
+ BIT(RPR0521_CHAN_INDEX_IR),
+ 0
+};
+
static const struct iio_chan_spec rpr0521_channels[] = {
{
.type = IIO_PROXIMITY,
@@ -204,6 +240,13 @@ static const struct iio_chan_spec rpr0521_channels[] = {
BIT(IIO_CHAN_INFO_OFFSET) |
BIT(IIO_CHAN_INFO_SCALE),
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+ .scan_index = RPR0521_CHAN_INDEX_PXS,
+ .scan_type = {
+ .sign = 'u',
+ .realbits = 16,
+ .storagebits = 16,
+ .endianness = IIO_LE,
+ },
},
{
.type = IIO_INTENSITY,
@@ -213,6 +256,13 @@ static const struct iio_chan_spec rpr0521_channels[] = {
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE),
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+ .scan_index = RPR0521_CHAN_INDEX_BOTH,
+ .scan_type = {
+ .sign = 'u',
+ .realbits = 16,
+ .storagebits = 16,
+ .endianness = IIO_LE,
+ },
},
{
.type = IIO_INTENSITY,
@@ -222,6 +272,13 @@ static const struct iio_chan_spec rpr0521_channels[] = {
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE),
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+ .scan_index = RPR0521_CHAN_INDEX_IR,
+ .scan_type = {
+ .sign = 'u',
+ .realbits = 16,
+ .storagebits = 16,
+ .endianness = IIO_LE,
+ },
},
};
@@ -330,6 +387,198 @@ static int rpr0521_set_power_state(struct rpr0521_data *data, bool on,
return 0;
}
+/* Interrupt register tells if this sensor caused the interrupt or not. */
+static inline bool rpr0521_is_triggered(struct rpr0521_data *data)
+{
+ int ret;
+ int reg;
+
+ ret = regmap_read(data->regmap, RPR0521_REG_INTERRUPT, &reg);
+ if (ret < 0)
+ return false; /* Reg read failed. */
+ if (reg &
+ (RPR0521_INTERRUPT_ALS_INT_STATUS_MASK |
+ RPR0521_INTERRUPT_PS_INT_STATUS_MASK))
+ return true;
+ else
+ return false; /* Int not from this sensor. */
+}
+
+/* IRQ to trigger handler */
+static irqreturn_t rpr0521_drdy_irq_handler(int irq, void *private)
+{
+ struct iio_dev *indio_dev = private;
+ struct rpr0521_data *data = iio_priv(indio_dev);
+
+ data->irq_timestamp = iio_get_time_ns(indio_dev);
+ /*
+ * We need to wake the thread to read the interrupt reg. It
+ * is not possible to do that here because regmap_read takes a
+ * mutex.
+ */
+
+ return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t rpr0521_drdy_irq_thread(int irq, void *private)
+{
+ struct iio_dev *indio_dev = private;
+ struct rpr0521_data *data = iio_priv(indio_dev);
+
+ if (rpr0521_is_triggered(data)) {
+ iio_trigger_poll_chained(data->drdy_trigger0);
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
+static irqreturn_t rpr0521_trigger_consumer_store_time(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+
+ /* Other trigger polls store time here. */
+ if (!iio_trigger_using_own(indio_dev))
+ pf->timestamp = iio_get_time_ns(indio_dev);
+
+ return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t rpr0521_trigger_consumer_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct rpr0521_data *data = iio_priv(indio_dev);
+ int err;
+
+ u8 buffer[16]; /* 3 16-bit channels + padding + ts */
+
+ /* Use irq timestamp when reasonable. */
+ if (iio_trigger_using_own(indio_dev) && data->irq_timestamp) {
+ pf->timestamp = data->irq_timestamp;
+ data->irq_timestamp = 0;
+ }
+ /* Other chained trigger polls get timestamp only here. */
+ if (!pf->timestamp)
+ pf->timestamp = iio_get_time_ns(indio_dev);
+
+ err = regmap_bulk_read(data->regmap, RPR0521_REG_PXS_DATA,
+ &buffer,
+ (3 * 2) + 1); /* 3 * 16-bit + (discarded) int clear reg. */
+ if (!err)
+ iio_push_to_buffers_with_timestamp(indio_dev,
+ buffer, pf->timestamp);
+ else
+ dev_err(&data->client->dev,
+ "Trigger consumer can't read from sensor.\n");
+ pf->timestamp = 0;
+
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
+static int rpr0521_write_int_enable(struct rpr0521_data *data)
+{
+ int err;
+
+ /* Interrupt after each measurement */
+ err = regmap_update_bits(data->regmap, RPR0521_REG_PXS_CTRL,
+ RPR0521_PXS_PERSISTENCE_MASK,
+ RPR0521_PXS_PERSISTENCE_DRDY);
+ if (err) {
+ dev_err(&data->client->dev, "PS control reg write fail.\n");
+ return -EBUSY;
+ }
+
+ /* Ignore latch and mode because of drdy */
+ err = regmap_write(data->regmap, RPR0521_REG_INTERRUPT,
+ RPR0521_INTERRUPT_INT_REASSERT_DISABLE |
+ RPR0521_INTERRUPT_INT_TRIG_ALS_DISABLE |
+ RPR0521_INTERRUPT_INT_TRIG_PS_ENABLE
+ );
+ if (err) {
+ dev_err(&data->client->dev, "Interrupt setup write fail.\n");
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+static int rpr0521_write_int_disable(struct rpr0521_data *data)
+{
+ /* Don't care of clearing mode, assert and latch. */
+ return regmap_write(data->regmap, RPR0521_REG_INTERRUPT,
+ RPR0521_INTERRUPT_INT_TRIG_ALS_DISABLE |
+ RPR0521_INTERRUPT_INT_TRIG_PS_DISABLE
+ );
+}
+
+/*
+ * Trigger producer enable / disable. Note that there will be trigs only when
+ * measurement data is ready to be read.
+ */
+static int rpr0521_pxs_drdy_set_state(struct iio_trigger *trigger,
+ bool enable_drdy)
+{
+ struct iio_dev *indio_dev = iio_trigger_get_drvdata(trigger);
+ struct rpr0521_data *data = iio_priv(indio_dev);
+ int err;
+
+ if (enable_drdy)
+ err = rpr0521_write_int_enable(data);
+ else
+ err = rpr0521_write_int_disable(data);
+ if (err)
+ dev_err(&data->client->dev, "rpr0521_pxs_drdy_set_state failed\n");
+
+ return err;
+}
+
+static const struct iio_trigger_ops rpr0521_trigger_ops = {
+ .set_trigger_state = rpr0521_pxs_drdy_set_state,
+ .owner = THIS_MODULE,
+ };
+
+
+static int rpr0521_buffer_preenable(struct iio_dev *indio_dev)
+{
+ int err;
+ struct rpr0521_data *data = iio_priv(indio_dev);
+
+ mutex_lock(&data->lock);
+ err = rpr0521_set_power_state(data, true,
+ (RPR0521_MODE_PXS_MASK | RPR0521_MODE_ALS_MASK));
+ mutex_unlock(&data->lock);
+ if (err)
+ dev_err(&data->client->dev, "_buffer_preenable fail\n");
+
+ return err;
+}
+
+static int rpr0521_buffer_postdisable(struct iio_dev *indio_dev)
+{
+ int err;
+ struct rpr0521_data *data = iio_priv(indio_dev);
+
+ mutex_lock(&data->lock);
+ err = rpr0521_set_power_state(data, false,
+ (RPR0521_MODE_PXS_MASK | RPR0521_MODE_ALS_MASK));
+ mutex_unlock(&data->lock);
+ if (err)
+ dev_err(&data->client->dev, "_buffer_postdisable fail\n");
+
+ return err;
+}
+
+static const struct iio_buffer_setup_ops rpr0521_buffer_setup_ops = {
+ .preenable = rpr0521_buffer_preenable,
+ .postenable = iio_triggered_buffer_postenable,
+ .predisable = iio_triggered_buffer_predisable,
+ .postdisable = rpr0521_buffer_postdisable,
+};
+
static int rpr0521_get_gain(struct rpr0521_data *data, int chan,
int *val, int *val2)
{
@@ -473,6 +722,7 @@ static int rpr0521_read_raw(struct iio_dev *indio_dev,
{
struct rpr0521_data *data = iio_priv(indio_dev);
int ret;
+ int busy;
u8 device_mask;
__le16 raw_data;
@@ -481,26 +731,30 @@ static int rpr0521_read_raw(struct iio_dev *indio_dev,
if (chan->type != IIO_INTENSITY && chan->type != IIO_PROXIMITY)
return -EINVAL;
+ busy = iio_device_claim_direct_mode(indio_dev);
+ if (busy)
+ return -EBUSY;
+
device_mask = rpr0521_data_reg[chan->address].device_mask;
mutex_lock(&data->lock);
ret = rpr0521_set_power_state(data, true, device_mask);
- if (ret < 0) {
- mutex_unlock(&data->lock);
- return ret;
- }
+ if (ret < 0)
+ goto rpr0521_read_raw_out;
ret = regmap_bulk_read(data->regmap,
rpr0521_data_reg[chan->address].address,
&raw_data, sizeof(raw_data));
if (ret < 0) {
rpr0521_set_power_state(data, false, device_mask);
- mutex_unlock(&data->lock);
- return ret;
+ goto rpr0521_read_raw_out;
}
ret = rpr0521_set_power_state(data, false, device_mask);
+
+rpr0521_read_raw_out:
mutex_unlock(&data->lock);
+ iio_device_release_direct_mode(indio_dev);
if (ret < 0)
return ret;
@@ -617,12 +871,15 @@ static int rpr0521_init(struct rpr0521_data *data)
return ret;
#endif
+ data->irq_timestamp = 0;
+
return 0;
}
static int rpr0521_poweroff(struct rpr0521_data *data)
{
int ret;
+ int tmp;
ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL,
RPR0521_MODE_ALS_MASK |
@@ -635,6 +892,16 @@ static int rpr0521_poweroff(struct rpr0521_data *data)
data->als_dev_en = false;
data->pxs_dev_en = false;
+ /*
+ * Int pin keeps state after power off. Set pin to high impedance
+ * mode to prevent power drain.
+ */
+ ret = regmap_read(data->regmap, RPR0521_REG_INTERRUPT, &tmp);
+ if (ret) {
+ dev_err(&data->client->dev, "Failed to reset int pin.\n");
+ return ret;
+ }
+
return 0;
}
@@ -707,6 +974,61 @@ static int rpr0521_probe(struct i2c_client *client,
pm_runtime_set_autosuspend_delay(&client->dev, RPR0521_SLEEP_DELAY_MS);
pm_runtime_use_autosuspend(&client->dev);
+ /*
+ * If sensor write/read is needed in _probe after _use_autosuspend,
+ * sensor needs to be _resumed first using rpr0521_set_power_state().
+ */
+
+ /* IRQ to trigger setup */
+ if (client->irq) {
+ /* Trigger0 producer setup */
+ data->drdy_trigger0 = devm_iio_trigger_alloc(
+ indio_dev->dev.parent,
+ "%s-dev%d", indio_dev->name, indio_dev->id);
+ if (!data->drdy_trigger0) {
+ ret = -ENOMEM;
+ goto err_pm_disable;
+ }
+ data->drdy_trigger0->dev.parent = indio_dev->dev.parent;
+ data->drdy_trigger0->ops = &rpr0521_trigger_ops;
+ indio_dev->available_scan_masks = rpr0521_available_scan_masks;
+ iio_trigger_set_drvdata(data->drdy_trigger0, indio_dev);
+
+ /* Ties irq to trigger producer handler. */
+ ret = devm_request_threaded_irq(&client->dev, client->irq,
+ rpr0521_drdy_irq_handler, rpr0521_drdy_irq_thread,
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ RPR0521_IRQ_NAME, indio_dev);
+ if (ret < 0) {
+ dev_err(&client->dev, "request irq %d for trigger0 failed\n",
+ client->irq);
+ goto err_pm_disable;
+ }
+
+ ret = devm_iio_trigger_register(indio_dev->dev.parent,
+ data->drdy_trigger0);
+ if (ret) {
+ dev_err(&client->dev, "iio trigger register failed\n");
+ goto err_pm_disable;
+ }
+
+ /*
+ * Now whole pipe from physical interrupt (irq defined by
+ * devicetree to device) to trigger0 output is set up.
+ */
+
+ /* Trigger consumer setup */
+ ret = devm_iio_triggered_buffer_setup(indio_dev->dev.parent,
+ indio_dev,
+ rpr0521_trigger_consumer_store_time,
+ rpr0521_trigger_consumer_handler,
+ &rpr0521_buffer_setup_ops);
+ if (ret < 0) {
+ dev_err(&client->dev, "iio triggered buffer setup failed\n");
+ goto err_pm_disable;
+ }
+ }
+
ret = iio_device_register(indio_dev);
if (ret)
goto err_pm_disable;
diff --git a/drivers/iio/light/tcs3472.c b/drivers/iio/light/tcs3472.c
index 3aa71e3..09e6ca5 100644
--- a/drivers/iio/light/tcs3472.c
+++ b/drivers/iio/light/tcs3472.c
@@ -11,6 +11,8 @@
* 7-bit I2C slave address 0x39 (TCS34721, TCS34723) or 0x29 (TCS34725,
* TCS34727)
*
+ * Datasheet: http://ams.com/eng/content/download/319364/1117183/file/TCS3472_Datasheet_EN_v2.pdf
+ *
* TODO: interrupt support, thresholds, wait time
*/
@@ -169,7 +171,7 @@ static int tcs3472_write_raw(struct iio_dev *indio_dev,
for (i = 0; i < 256; i++) {
if (val2 == (256 - i) * 2400) {
data->atime = i;
- return i2c_smbus_write_word_data(
+ return i2c_smbus_write_byte_data(
data->client, TCS3472_ATIME,
data->atime);
}
diff --git a/drivers/iio/light/tsl2583.c b/drivers/iio/light/tsl2583.c
index 1679181..fb711ed 100644
--- a/drivers/iio/light/tsl2583.c
+++ b/drivers/iio/light/tsl2583.c
@@ -924,7 +924,7 @@ static const struct dev_pm_ops tsl2583_pm_ops = {
SET_RUNTIME_PM_OPS(tsl2583_suspend, tsl2583_resume, NULL)
};
-static struct i2c_device_id tsl2583_idtable[] = {
+static const struct i2c_device_id tsl2583_idtable[] = {
{ "tsl2580", 0 },
{ "tsl2581", 1 },
{ "tsl2583", 2 },
diff --git a/drivers/iio/magnetometer/Kconfig b/drivers/iio/magnetometer/Kconfig
index 421ad90..ed9d776 100644
--- a/drivers/iio/magnetometer/Kconfig
+++ b/drivers/iio/magnetometer/Kconfig
@@ -13,8 +13,8 @@ config AK8974
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
- Say yes here to build support for Asahi Kasei AK8974 or
- AMI305 I2C-based 3-axis magnetometer chips.
+ Say yes here to build support for Asahi Kasei AK8974, AMI305 or
+ AMI306 I2C-based 3-axis magnetometer chips.
To compile this driver as a module, choose M here: the module
will be called ak8974.
diff --git a/drivers/iio/magnetometer/ak8974.c b/drivers/iio/magnetometer/ak8974.c
index e13370d..0bff76e 100644
--- a/drivers/iio/magnetometer/ak8974.c
+++ b/drivers/iio/magnetometer/ak8974.c
@@ -20,6 +20,7 @@
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/bitops.h>
+#include <linux/random.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/pm_runtime.h>
@@ -36,7 +37,7 @@
* and MSB is at the next higher address.
*/
-/* These registers are common for AK8974 and AMI305 */
+/* These registers are common for AK8974 and AMI30x */
#define AK8974_SELFTEST 0x0C
#define AK8974_SELFTEST_IDLE 0x55
#define AK8974_SELFTEST_OK 0xAA
@@ -44,6 +45,7 @@
#define AK8974_INFO 0x0D
#define AK8974_WHOAMI 0x0F
+#define AK8974_WHOAMI_VALUE_AMI306 0x46
#define AK8974_WHOAMI_VALUE_AMI305 0x47
#define AK8974_WHOAMI_VALUE_AK8974 0x48
@@ -73,6 +75,35 @@
#define AK8974_TEMP 0x31
#define AMI305_TEMP 0x60
+/* AMI306-specific control register */
+#define AMI306_CTRL4 0x5C
+
+/* AMI306 factory calibration data */
+
+/* fine axis sensitivity */
+#define AMI306_FINEOUTPUT_X 0x90
+#define AMI306_FINEOUTPUT_Y 0x92
+#define AMI306_FINEOUTPUT_Z 0x94
+
+/* axis sensitivity */
+#define AMI306_SENS_X 0x96
+#define AMI306_SENS_Y 0x98
+#define AMI306_SENS_Z 0x9A
+
+/* axis cross-interference */
+#define AMI306_GAIN_PARA_XZ 0x9C
+#define AMI306_GAIN_PARA_XY 0x9D
+#define AMI306_GAIN_PARA_YZ 0x9E
+#define AMI306_GAIN_PARA_YX 0x9F
+#define AMI306_GAIN_PARA_ZY 0xA0
+#define AMI306_GAIN_PARA_ZX 0xA1
+
+/* offset at ZERO magnetic field */
+#define AMI306_OFFZERO_X 0xF8
+#define AMI306_OFFZERO_Y 0xFA
+#define AMI306_OFFZERO_Z 0xFC
+
+
#define AK8974_INT_X_HIGH BIT(7) /* Axis over +threshold */
#define AK8974_INT_Y_HIGH BIT(6)
#define AK8974_INT_Z_HIGH BIT(5)
@@ -158,6 +189,26 @@ struct ak8974 {
static const char ak8974_reg_avdd[] = "avdd";
static const char ak8974_reg_dvdd[] = "dvdd";
+static int ak8974_get_u16_val(struct ak8974 *ak8974, u8 reg, u16 *val)
+{
+ int ret;
+ __le16 bulk;
+
+ ret = regmap_bulk_read(ak8974->map, reg, &bulk, 2);
+ if (ret)
+ return ret;
+ *val = le16_to_cpu(bulk);
+
+ return 0;
+}
+
+static int ak8974_set_u16_val(struct ak8974 *ak8974, u8 reg, u16 val)
+{
+ __le16 bulk = cpu_to_le16(val);
+
+ return regmap_bulk_write(ak8974->map, reg, &bulk, 2);
+}
+
static int ak8974_set_power(struct ak8974 *ak8974, bool mode)
{
int ret;
@@ -209,6 +260,12 @@ static int ak8974_configure(struct ak8974 *ak8974)
ret = regmap_write(ak8974->map, AK8974_CTRL3, 0);
if (ret)
return ret;
+ if (ak8974->variant == AK8974_WHOAMI_VALUE_AMI306) {
+ /* magic from datasheet: set high-speed measurement mode */
+ ret = ak8974_set_u16_val(ak8974, AMI306_CTRL4, 0xA07E);
+ if (ret)
+ return ret;
+ }
ret = regmap_write(ak8974->map, AK8974_INT_CTRL, AK8974_INT_CTRL_POL);
if (ret)
return ret;
@@ -388,17 +445,18 @@ static int ak8974_selftest(struct ak8974 *ak8974)
return 0;
}
-static int ak8974_get_u16_val(struct ak8974 *ak8974, u8 reg, u16 *val)
+static void ak8974_read_calib_data(struct ak8974 *ak8974, unsigned int reg,
+ __le16 *tab, size_t tab_size)
{
- int ret;
- __le16 bulk;
-
- ret = regmap_bulk_read(ak8974->map, reg, &bulk, 2);
- if (ret)
- return ret;
- *val = le16_to_cpu(bulk);
-
- return 0;
+ int ret = regmap_bulk_read(ak8974->map, reg, tab, tab_size);
+ if (ret) {
+ memset(tab, 0xFF, tab_size);
+ dev_warn(&ak8974->i2c->dev,
+ "can't read calibration data (regs %u..%zu): %d\n",
+ reg, reg + tab_size - 1, ret);
+ } else {
+ add_device_randomness(tab, tab_size);
+ }
}
static int ak8974_detect(struct ak8974 *ak8974)
@@ -413,9 +471,13 @@ static int ak8974_detect(struct ak8974 *ak8974)
if (ret)
return ret;
+ name = "ami305";
+
switch (whoami) {
+ case AK8974_WHOAMI_VALUE_AMI306:
+ name = "ami306";
+ /* fall-through */
case AK8974_WHOAMI_VALUE_AMI305:
- name = "ami305";
ret = regmap_read(ak8974->map, AMI305_VER, &fw);
if (ret)
return ret;
@@ -423,6 +485,7 @@ static int ak8974_detect(struct ak8974 *ak8974)
ret = ak8974_get_u16_val(ak8974, AMI305_SN, &sn);
if (ret)
return ret;
+ add_device_randomness(&sn, sizeof(sn));
dev_info(&ak8974->i2c->dev,
"detected %s, FW ver %02x, S/N: %04x\n",
name, fw, sn);
@@ -440,6 +503,33 @@ static int ak8974_detect(struct ak8974 *ak8974)
ak8974->name = name;
ak8974->variant = whoami;
+ if (whoami == AK8974_WHOAMI_VALUE_AMI306) {
+ __le16 fab_data1[9], fab_data2[3];
+ int i;
+
+ ak8974_read_calib_data(ak8974, AMI306_FINEOUTPUT_X,
+ fab_data1, sizeof(fab_data1));
+ ak8974_read_calib_data(ak8974, AMI306_OFFZERO_X,
+ fab_data2, sizeof(fab_data2));
+
+ for (i = 0; i < 3; ++i) {
+ static const char axis[3] = "XYZ";
+ static const char pgaxis[6] = "ZYZXYX";
+ unsigned offz = le16_to_cpu(fab_data2[i]) & 0x7F;
+ unsigned fine = le16_to_cpu(fab_data1[i]);
+ unsigned sens = le16_to_cpu(fab_data1[i + 3]);
+ unsigned pgain1 = le16_to_cpu(fab_data1[i + 6]);
+ unsigned pgain2 = pgain1 >> 8;
+
+ pgain1 &= 0xFF;
+
+ dev_info(&ak8974->i2c->dev,
+ "factory calibration for axis %c: offz=%u sens=%u fine=%u pga%c=%u pga%c=%u\n",
+ axis[i], offz, sens, fine, pgaxis[i * 2],
+ pgain1, pgaxis[i * 2 + 1], pgain2);
+ }
+ }
+
return 0;
}
@@ -602,19 +692,27 @@ static bool ak8974_writeable_reg(struct device *dev, unsigned int reg)
case AMI305_OFFSET_Y + 1:
case AMI305_OFFSET_Z:
case AMI305_OFFSET_Z + 1:
- if (ak8974->variant == AK8974_WHOAMI_VALUE_AMI305)
- return true;
- return false;
+ return ak8974->variant == AK8974_WHOAMI_VALUE_AMI305 ||
+ ak8974->variant == AK8974_WHOAMI_VALUE_AMI306;
+ case AMI306_CTRL4:
+ case AMI306_CTRL4 + 1:
+ return ak8974->variant == AK8974_WHOAMI_VALUE_AMI306;
default:
return false;
}
}
+static bool ak8974_precious_reg(struct device *dev, unsigned int reg)
+{
+ return reg == AK8974_INT_CLEAR;
+}
+
static const struct regmap_config ak8974_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.writeable_reg = ak8974_writeable_reg,
+ .precious_reg = ak8974_precious_reg,
};
static int ak8974_probe(struct i2c_client *i2c,
@@ -678,7 +776,7 @@ static int ak8974_probe(struct i2c_client *i2c,
ret = ak8974_detect(ak8974);
if (ret) {
- dev_err(&i2c->dev, "neither AK8974 nor AMI305 found\n");
+ dev_err(&i2c->dev, "neither AK8974 nor AMI30x found\n");
goto power_off;
}
@@ -827,6 +925,7 @@ static const struct dev_pm_ops ak8974_dev_pm_ops = {
static const struct i2c_device_id ak8974_id[] = {
{"ami305", 0 },
+ {"ami306", 0 },
{"ak8974", 0 },
{}
};
@@ -850,7 +949,7 @@ static struct i2c_driver ak8974_driver = {
};
module_i2c_driver(ak8974_driver);
-MODULE_DESCRIPTION("AK8974 and AMI305 3-axis magnetometer driver");
+MODULE_DESCRIPTION("AK8974 and AMI30x 3-axis magnetometer driver");
MODULE_AUTHOR("Samu Onkalo");
MODULE_AUTHOR("Linus Walleij");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c
index 825369f..4ff8839 100644
--- a/drivers/iio/magnetometer/ak8975.c
+++ b/drivers/iio/magnetometer/ak8975.c
@@ -784,6 +784,7 @@ static const struct iio_info ak8975_info = {
.driver_module = THIS_MODULE,
};
+#ifdef CONFIG_ACPI
static const struct acpi_device_id ak_acpi_match[] = {
{"AK8975", AK8975},
{"AK8963", AK8963},
@@ -793,6 +794,7 @@ static const struct acpi_device_id ak_acpi_match[] = {
{ },
};
MODULE_DEVICE_TABLE(acpi, ak_acpi_match);
+#endif
static const char *ak8975_match_acpi_device(struct device *dev,
enum asahi_compass_chipset *chipset)
diff --git a/drivers/iio/magnetometer/st_magn.h b/drivers/iio/magnetometer/st_magn.h
index 9daca46..8fe51ce 100644
--- a/drivers/iio/magnetometer/st_magn.h
+++ b/drivers/iio/magnetometer/st_magn.h
@@ -19,6 +19,7 @@
#define LSM303DLM_MAGN_DEV_NAME "lsm303dlm_magn"
#define LIS3MDL_MAGN_DEV_NAME "lis3mdl"
#define LSM303AGR_MAGN_DEV_NAME "lsm303agr_magn"
+#define LIS2MDL_MAGN_DEV_NAME "lis2mdl"
int st_magn_common_probe(struct iio_dev *indio_dev);
void st_magn_common_remove(struct iio_dev *indio_dev);
diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c
index c385636..e68368b 100644
--- a/drivers/iio/magnetometer/st_magn_core.c
+++ b/drivers/iio/magnetometer/st_magn_core.c
@@ -315,7 +315,7 @@ static const struct st_sensor_settings st_magn_sensors_settings[] = {
},
},
},
- .multi_read_bit = false,
+ .multi_read_bit = true,
.bootime = 2,
},
{
@@ -323,6 +323,7 @@ static const struct st_sensor_settings st_magn_sensors_settings[] = {
.wai_addr = 0x4f,
.sensors_supported = {
[0] = LSM303AGR_MAGN_DEV_NAME,
+ [1] = LIS2MDL_MAGN_DEV_NAME,
},
.ch = (struct iio_chan_spec *)st_magn_3_16bit_channels,
.odr = {
diff --git a/drivers/iio/magnetometer/st_magn_i2c.c b/drivers/iio/magnetometer/st_magn_i2c.c
index 8aa37af..feaa28c 100644
--- a/drivers/iio/magnetometer/st_magn_i2c.c
+++ b/drivers/iio/magnetometer/st_magn_i2c.c
@@ -40,6 +40,10 @@ static const struct of_device_id st_magn_of_match[] = {
.compatible = "st,lsm303agr-magn",
.data = LSM303AGR_MAGN_DEV_NAME,
},
+ {
+ .compatible = "st,lis2mdl",
+ .data = LIS2MDL_MAGN_DEV_NAME,
+ },
{},
};
MODULE_DEVICE_TABLE(of, st_magn_of_match);
@@ -59,7 +63,8 @@ static int st_magn_i2c_probe(struct i2c_client *client,
return -ENOMEM;
mdata = iio_priv(indio_dev);
- st_sensors_of_i2c_probe(client, st_magn_of_match);
+ st_sensors_of_name_probe(&client->dev, st_magn_of_match,
+ client->name, sizeof(client->name));
st_sensors_i2c_configure(indio_dev, client, mdata);
@@ -84,6 +89,7 @@ static const struct i2c_device_id st_magn_id_table[] = {
{ LSM303DLM_MAGN_DEV_NAME },
{ LIS3MDL_MAGN_DEV_NAME },
{ LSM303AGR_MAGN_DEV_NAME },
+ { LIS2MDL_MAGN_DEV_NAME },
{},
};
MODULE_DEVICE_TABLE(i2c, st_magn_id_table);
diff --git a/drivers/iio/magnetometer/st_magn_spi.c b/drivers/iio/magnetometer/st_magn_spi.c
index f3cb4dc..7b7cd08 100644
--- a/drivers/iio/magnetometer/st_magn_spi.c
+++ b/drivers/iio/magnetometer/st_magn_spi.c
@@ -18,6 +18,32 @@
#include <linux/iio/common/st_sensors_spi.h>
#include "st_magn.h"
+#ifdef CONFIG_OF
+/*
+ * For new single-chip sensors use <device_name> as compatible string.
+ * For old single-chip devices keep <device_name>-magn to maintain
+ * compatibility
+ */
+static const struct of_device_id st_magn_of_match[] = {
+ {
+ .compatible = "st,lis3mdl-magn",
+ .data = LIS3MDL_MAGN_DEV_NAME,
+ },
+ {
+ .compatible = "st,lsm303agr-magn",
+ .data = LSM303AGR_MAGN_DEV_NAME,
+ },
+ {
+ .compatible = "st,lis2mdl",
+ .data = LIS2MDL_MAGN_DEV_NAME,
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(of, st_magn_of_match);
+#else
+#define st_magn_of_match NULL
+#endif
+
static int st_magn_spi_probe(struct spi_device *spi)
{
struct iio_dev *indio_dev;
@@ -30,6 +56,8 @@ static int st_magn_spi_probe(struct spi_device *spi)
mdata = iio_priv(indio_dev);
+ st_sensors_of_name_probe(&spi->dev, st_magn_of_match,
+ spi->modalias, sizeof(spi->modalias));
st_sensors_spi_configure(indio_dev, spi, mdata);
err = st_magn_common_probe(indio_dev);
@@ -50,6 +78,7 @@ static int st_magn_spi_remove(struct spi_device *spi)
static const struct spi_device_id st_magn_id_table[] = {
{ LIS3MDL_MAGN_DEV_NAME },
{ LSM303AGR_MAGN_DEV_NAME },
+ { LIS2MDL_MAGN_DEV_NAME },
{},
};
MODULE_DEVICE_TABLE(spi, st_magn_id_table);
@@ -57,6 +86,7 @@ MODULE_DEVICE_TABLE(spi, st_magn_id_table);
static struct spi_driver st_magn_driver = {
.driver = {
.name = "st-magn-spi",
+ .of_match_table = of_match_ptr(st_magn_of_match),
},
.probe = st_magn_spi_probe,
.remove = st_magn_spi_remove,
diff --git a/drivers/iio/orientation/hid-sensor-rotation.c b/drivers/iio/orientation/hid-sensor-rotation.c
index e9fa86c..98fe0c5 100644
--- a/drivers/iio/orientation/hid-sensor-rotation.c
+++ b/drivers/iio/orientation/hid-sensor-rotation.c
@@ -238,7 +238,7 @@ static int dev_rot_parse_report(struct platform_device *pdev,
static int hid_dev_rot_probe(struct platform_device *pdev)
{
int ret;
- static char *name;
+ char *name;
struct iio_dev *indio_dev;
struct dev_rot_state *rot_state;
struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
diff --git a/drivers/iio/pressure/ms5637.c b/drivers/iio/pressure/ms5637.c
index 953ffbc..c413f8a 100644
--- a/drivers/iio/pressure/ms5637.c
+++ b/drivers/iio/pressure/ms5637.c
@@ -181,11 +181,21 @@ static const struct i2c_device_id ms5637_id[] = {
};
MODULE_DEVICE_TABLE(i2c, ms5637_id);
+static const struct of_device_id ms5637_of_match[] = {
+ { .compatible = "meas,ms5637", },
+ { .compatible = "meas,ms5805", },
+ { .compatible = "meas,ms5837", },
+ { .compatible = "meas,ms8607-temppressure", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, ms5637_of_match);
+
static struct i2c_driver ms5637_driver = {
.probe = ms5637_probe,
.id_table = ms5637_id,
.driver = {
- .name = "ms5637"
+ .name = "ms5637",
+ .of_match_table = of_match_ptr(ms5637_of_match),
},
};
diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c
index f1bce05..34611a8 100644
--- a/drivers/iio/pressure/st_pressure_core.c
+++ b/drivers/iio/pressure/st_pressure_core.c
@@ -390,7 +390,7 @@ static const struct st_sensor_settings st_press_sensors_settings[] = {
.drdy_irq = {
.addr = 0x23,
.mask_int1 = 0x01,
- .mask_int2 = 0x10,
+ .mask_int2 = 0x00,
.addr_ihl = 0x22,
.mask_ihl = 0x80,
.addr_od = 0x22,
@@ -449,7 +449,7 @@ static const struct st_sensor_settings st_press_sensors_settings[] = {
.drdy_irq = {
.addr = 0x12,
.mask_int1 = 0x04,
- .mask_int2 = 0x08,
+ .mask_int2 = 0x00,
.addr_ihl = 0x12,
.mask_ihl = 0x80,
.addr_od = 0x12,
diff --git a/drivers/iio/pressure/st_pressure_i2c.c b/drivers/iio/pressure/st_pressure_i2c.c
index 17417a4..7f15e92 100644
--- a/drivers/iio/pressure/st_pressure_i2c.c
+++ b/drivers/iio/pressure/st_pressure_i2c.c
@@ -77,7 +77,8 @@ static int st_press_i2c_probe(struct i2c_client *client,
press_data = iio_priv(indio_dev);
if (client->dev.of_node) {
- st_sensors_of_i2c_probe(client, st_press_of_match);
+ st_sensors_of_name_probe(&client->dev, st_press_of_match,
+ client->name, sizeof(client->name));
} else if (ACPI_HANDLE(&client->dev)) {
ret = st_sensors_match_acpi_device(&client->dev);
if ((ret < 0) || (ret >= ST_PRESS_MAX))
diff --git a/drivers/iio/pressure/st_pressure_spi.c b/drivers/iio/pressure/st_pressure_spi.c
index 5505080..f5ebd36 100644
--- a/drivers/iio/pressure/st_pressure_spi.c
+++ b/drivers/iio/pressure/st_pressure_spi.c
@@ -18,6 +18,36 @@
#include <linux/iio/common/st_sensors_spi.h>
#include "st_pressure.h"
+#ifdef CONFIG_OF
+/*
+ * For new single-chip sensors use <device_name> as compatible string.
+ * For old single-chip devices keep <device_name>-press to maintain
+ * compatibility
+ */
+static const struct of_device_id st_press_of_match[] = {
+ {
+ .compatible = "st,lps001wp-press",
+ .data = LPS001WP_PRESS_DEV_NAME,
+ },
+ {
+ .compatible = "st,lps25h-press",
+ .data = LPS25H_PRESS_DEV_NAME,
+ },
+ {
+ .compatible = "st,lps331ap-press",
+ .data = LPS331AP_PRESS_DEV_NAME,
+ },
+ {
+ .compatible = "st,lps22hb-press",
+ .data = LPS22HB_PRESS_DEV_NAME,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, st_press_of_match);
+#else
+#define st_press_of_match NULL
+#endif
+
static int st_press_spi_probe(struct spi_device *spi)
{
struct iio_dev *indio_dev;
@@ -30,6 +60,8 @@ static int st_press_spi_probe(struct spi_device *spi)
press_data = iio_priv(indio_dev);
+ st_sensors_of_name_probe(&spi->dev, st_press_of_match,
+ spi->modalias, sizeof(spi->modalias));
st_sensors_spi_configure(indio_dev, spi, press_data);
err = st_press_common_probe(indio_dev);
@@ -58,6 +90,7 @@ MODULE_DEVICE_TABLE(spi, st_press_id_table);
static struct spi_driver st_press_driver = {
.driver = {
.name = "st-press-spi",
+ .of_match_table = of_match_ptr(st_press_of_match),
},
.probe = st_press_spi_probe,
.remove = st_press_spi_remove,
diff --git a/drivers/iio/pressure/zpa2326.c b/drivers/iio/pressure/zpa2326.c
index c92a95f..ebfb1de 100644
--- a/drivers/iio/pressure/zpa2326.c
+++ b/drivers/iio/pressure/zpa2326.c
@@ -141,14 +141,14 @@ struct zpa2326_private {
struct regulator *vdd;
};
-#define zpa2326_err(_idev, _format, _arg...) \
- dev_err(_idev->dev.parent, _format, ##_arg)
+#define zpa2326_err(idev, fmt, ...) \
+ dev_err(idev->dev.parent, fmt "\n", ##__VA_ARGS__)
-#define zpa2326_warn(_idev, _format, _arg...) \
- dev_warn(_idev->dev.parent, _format, ##_arg)
+#define zpa2326_warn(idev, fmt, ...) \
+ dev_warn(idev->dev.parent, fmt "\n", ##__VA_ARGS__)
-#define zpa2326_dbg(_idev, _format, _arg...) \
- dev_dbg(_idev->dev.parent, _format, ##_arg)
+#define zpa2326_dbg(idev, fmt, ...) \
+ dev_dbg(idev->dev.parent, fmt "\n", ##__VA_ARGS__)
bool zpa2326_isreg_writeable(struct device *dev, unsigned int reg)
{
diff --git a/drivers/iio/proximity/Kconfig b/drivers/iio/proximity/Kconfig
index 5b81a8c..ae07095 100644
--- a/drivers/iio/proximity/Kconfig
+++ b/drivers/iio/proximity/Kconfig
@@ -57,12 +57,12 @@ config SX9500
module will be called sx9500.
config SRF08
- tristate "Devantech SRF08 ultrasonic ranger sensor"
+ tristate "Devantech SRF02/SRF08/SRF10 ultrasonic ranger sensor"
depends on I2C
help
- Say Y here to build a driver for Devantech SRF08 ultrasonic
- ranger sensor. This driver can be used to measure the distance
- of objects.
+ Say Y here to build a driver for Devantech SRF02/SRF08/SRF10
+ ultrasonic ranger sensors with i2c interface.
+ This driver can be used to measure the distance of objects.
To compile this driver as a module, choose M here: the
module will be called srf08.
diff --git a/drivers/iio/proximity/srf08.c b/drivers/iio/proximity/srf08.c
index 49316cbf7..9380d54 100644
--- a/drivers/iio/proximity/srf08.c
+++ b/drivers/iio/proximity/srf08.c
@@ -1,14 +1,18 @@
/*
- * srf08.c - Support for Devantech SRF08 ultrasonic ranger
+ * srf08.c - Support for Devantech SRFxx ultrasonic ranger
+ * with i2c interface
+ * actually supported are srf02, srf08, srf10
*
- * Copyright (c) 2016 Andreas Klinger <ak@it-klinger.de>
+ * Copyright (c) 2016, 2017 Andreas Klinger <ak@it-klinger.de>
*
* This file is subject to the terms and conditions of version 2 of
- * the GNU General Public License. See the file COPYING in the main
+ * the GNU General Public License. See the file COPYING in the main
* directory of this archive for more details.
*
* For details about the device see:
* http://www.robot-electronics.co.uk/htm/srf08tech.html
+ * http://www.robot-electronics.co.uk/htm/srf10tech.htm
+ * http://www.robot-electronics.co.uk/htm/srf02tech.htm
*/
#include <linux/err.h>
@@ -18,6 +22,9 @@
#include <linux/bitops.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
/* registers of SRF08 device */
#define SRF08_WRITE_COMMAND 0x00 /* Command Register */
@@ -30,14 +37,46 @@
#define SRF08_CMD_RANGING_CM 0x51 /* Ranging Mode - Result in cm */
-#define SRF08_DEFAULT_GAIN 1025 /* default analogue value of Gain */
-#define SRF08_DEFAULT_RANGE 6020 /* default value of Range in mm */
+enum srf08_sensor_type {
+ SRF02,
+ SRF08,
+ SRF10,
+ SRF_MAX_TYPE
+};
+
+struct srf08_chip_info {
+ const int *sensitivity_avail;
+ int num_sensitivity_avail;
+ int sensitivity_default;
+
+ /* default value of Range in mm */
+ int range_default;
+};
struct srf08_data {
struct i2c_client *client;
- int sensitivity; /* Gain */
- int range_mm; /* max. Range in mm */
+
+ /*
+ * Gain in the datasheet is called sensitivity here to distinct it
+ * from the gain used with amplifiers of adc's
+ */
+ int sensitivity;
+
+ /* max. Range in mm */
+ int range_mm;
struct mutex lock;
+
+ /*
+ * triggered buffer
+ * 1x16-bit channel + 3x16 padding + 4x16 timestamp
+ */
+ s16 buffer[8];
+
+ /* Sensor-Type */
+ enum srf08_sensor_type sensor_type;
+
+ /* Chip-specific information */
+ const struct srf08_chip_info *chip_info;
};
/*
@@ -47,11 +86,42 @@ struct srf08_data {
* But with ADC's this term is already used differently and that's why it
* is called "Sensitivity" here.
*/
-static const int srf08_sensitivity[] = {
+static const struct srf08_chip_info srf02_chip_info = {
+ .sensitivity_avail = NULL,
+ .num_sensitivity_avail = 0,
+ .sensitivity_default = 0,
+
+ .range_default = 0,
+};
+
+static const int srf08_sensitivity_avail[] = {
94, 97, 100, 103, 107, 110, 114, 118,
123, 128, 133, 139, 145, 152, 159, 168,
177, 187, 199, 212, 227, 245, 265, 288,
- 317, 352, 395, 450, 524, 626, 777, 1025 };
+ 317, 352, 395, 450, 524, 626, 777, 1025
+ };
+
+static const struct srf08_chip_info srf08_chip_info = {
+ .sensitivity_avail = srf08_sensitivity_avail,
+ .num_sensitivity_avail = ARRAY_SIZE(srf08_sensitivity_avail),
+ .sensitivity_default = 1025,
+
+ .range_default = 6020,
+};
+
+static const int srf10_sensitivity_avail[] = {
+ 40, 40, 50, 60, 70, 80, 100, 120,
+ 140, 200, 250, 300, 350, 400, 500, 600,
+ 700,
+ };
+
+static const struct srf08_chip_info srf10_chip_info = {
+ .sensitivity_avail = srf10_sensitivity_avail,
+ .num_sensitivity_avail = ARRAY_SIZE(srf10_sensitivity_avail),
+ .sensitivity_default = 700,
+
+ .range_default = 6020,
+};
static int srf08_read_ranging(struct srf08_data *data)
{
@@ -110,6 +180,29 @@ static int srf08_read_ranging(struct srf08_data *data)
return ret;
}
+static irqreturn_t srf08_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct srf08_data *data = iio_priv(indio_dev);
+ s16 sensor_data;
+
+ sensor_data = srf08_read_ranging(data);
+ if (sensor_data < 0)
+ goto err;
+
+ mutex_lock(&data->lock);
+
+ data->buffer[0] = sensor_data;
+ iio_push_to_buffers_with_timestamp(indio_dev,
+ data->buffer, pf->timestamp);
+
+ mutex_unlock(&data->lock);
+err:
+ iio_trigger_notify_done(indio_dev->trig);
+ return IRQ_HANDLED;
+}
+
static int srf08_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *channel, int *val,
int *val2, long mask)
@@ -225,9 +318,13 @@ static ssize_t srf08_show_sensitivity_available(struct device *dev,
struct device_attribute *attr, char *buf)
{
int i, len = 0;
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct srf08_data *data = iio_priv(indio_dev);
- for (i = 0; i < ARRAY_SIZE(srf08_sensitivity); i++)
- len += sprintf(buf + len, "%d ", srf08_sensitivity[i]);
+ for (i = 0; i < data->chip_info->num_sensitivity_avail; i++)
+ if (data->chip_info->sensitivity_avail[i])
+ len += sprintf(buf + len, "%d ",
+ data->chip_info->sensitivity_avail[i]);
len += sprintf(buf + len, "\n");
@@ -256,19 +353,21 @@ static ssize_t srf08_write_sensitivity(struct srf08_data *data,
int ret, i;
u8 regval;
- for (i = 0; i < ARRAY_SIZE(srf08_sensitivity); i++)
- if (val == srf08_sensitivity[i]) {
+ if (!val)
+ return -EINVAL;
+
+ for (i = 0; i < data->chip_info->num_sensitivity_avail; i++)
+ if (val && (val == data->chip_info->sensitivity_avail[i])) {
regval = i;
break;
}
- if (i >= ARRAY_SIZE(srf08_sensitivity))
+ if (i >= data->chip_info->num_sensitivity_avail)
return -EINVAL;
mutex_lock(&data->lock);
- ret = i2c_smbus_write_byte_data(client,
- SRF08_WRITE_MAX_GAIN, regval);
+ ret = i2c_smbus_write_byte_data(client, SRF08_WRITE_MAX_GAIN, regval);
if (ret < 0) {
dev_err(&client->dev, "write_sensitivity - err: %d\n", ret);
mutex_unlock(&data->lock);
@@ -323,7 +422,15 @@ static const struct iio_chan_spec srf08_channels[] = {
.info_mask_separate =
BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE),
+ .scan_index = 0,
+ .scan_type = {
+ .sign = 's',
+ .realbits = 16,
+ .storagebits = 16,
+ .endianness = IIO_CPU,
+ },
},
+ IIO_CHAN_SOFT_TIMESTAMP(1),
};
static const struct iio_info srf08_info = {
@@ -332,6 +439,15 @@ static const struct iio_info srf08_info = {
.driver_module = THIS_MODULE,
};
+/*
+ * srf02 don't have an adjustable range or sensitivity,
+ * so we don't need attributes at all
+ */
+static const struct iio_info srf02_info = {
+ .read_raw = srf08_read_raw,
+ .driver_module = THIS_MODULE,
+};
+
static int srf08_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -352,34 +468,84 @@ static int srf08_probe(struct i2c_client *client,
data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
data->client = client;
+ data->sensor_type = (enum srf08_sensor_type)id->driver_data;
+
+ switch (data->sensor_type) {
+ case SRF02:
+ data->chip_info = &srf02_chip_info;
+ indio_dev->info = &srf02_info;
+ break;
+ case SRF08:
+ data->chip_info = &srf08_chip_info;
+ indio_dev->info = &srf08_info;
+ break;
+ case SRF10:
+ data->chip_info = &srf10_chip_info;
+ indio_dev->info = &srf08_info;
+ break;
+ default:
+ return -EINVAL;
+ }
- indio_dev->name = "srf08";
+ indio_dev->name = id->name;
indio_dev->dev.parent = &client->dev;
indio_dev->modes = INDIO_DIRECT_MODE;
- indio_dev->info = &srf08_info;
indio_dev->channels = srf08_channels;
indio_dev->num_channels = ARRAY_SIZE(srf08_channels);
mutex_init(&data->lock);
- /*
- * set default values of device here
- * these register values cannot be read from the hardware
- * therefore set driver specific default values
- */
- ret = srf08_write_range_mm(data, SRF08_DEFAULT_RANGE);
- if (ret < 0)
+ ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev,
+ iio_pollfunc_store_time, srf08_trigger_handler, NULL);
+ if (ret < 0) {
+ dev_err(&client->dev, "setup of iio triggered buffer failed\n");
return ret;
+ }
- ret = srf08_write_sensitivity(data, SRF08_DEFAULT_GAIN);
- if (ret < 0)
- return ret;
+ if (data->chip_info->range_default) {
+ /*
+ * set default range of device in mm here
+ * these register values cannot be read from the hardware
+ * therefore set driver specific default values
+ *
+ * srf02 don't have a default value so it'll be omitted
+ */
+ ret = srf08_write_range_mm(data,
+ data->chip_info->range_default);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (data->chip_info->sensitivity_default) {
+ /*
+ * set default sensitivity of device here
+ * these register values cannot be read from the hardware
+ * therefore set driver specific default values
+ *
+ * srf02 don't have a default value so it'll be omitted
+ */
+ ret = srf08_write_sensitivity(data,
+ data->chip_info->sensitivity_default);
+ if (ret < 0)
+ return ret;
+ }
return devm_iio_device_register(&client->dev, indio_dev);
}
+static const struct of_device_id of_srf08_match[] = {
+ { .compatible = "devantech,srf02", (void *)SRF02},
+ { .compatible = "devantech,srf08", (void *)SRF08},
+ { .compatible = "devantech,srf10", (void *)SRF10},
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, of_srf08_match);
+
static const struct i2c_device_id srf08_id[] = {
- { "srf08", 0 },
+ { "srf02", SRF02 },
+ { "srf08", SRF08 },
+ { "srf10", SRF10 },
{ }
};
MODULE_DEVICE_TABLE(i2c, srf08_id);
@@ -387,6 +553,7 @@ MODULE_DEVICE_TABLE(i2c, srf08_id);
static struct i2c_driver srf08_driver = {
.driver = {
.name = "srf08",
+ .of_match_table = of_srf08_match,
},
.probe = srf08_probe,
.id_table = srf08_id,
@@ -394,5 +561,5 @@ static struct i2c_driver srf08_driver = {
module_i2c_driver(srf08_driver);
MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>");
-MODULE_DESCRIPTION("Devantech SRF08 ultrasonic ranger driver");
+MODULE_DESCRIPTION("Devantech SRF02/SRF08/SRF10 i2c ultrasonic ranger driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/iio/temperature/tsys01.c b/drivers/iio/temperature/tsys01.c
index 3e60c61..d8aa211 100644
--- a/drivers/iio/temperature/tsys01.c
+++ b/drivers/iio/temperature/tsys01.c
@@ -214,11 +214,18 @@ static const struct i2c_device_id tsys01_id[] = {
};
MODULE_DEVICE_TABLE(i2c, tsys01_id);
+static const struct of_device_id tsys01_of_match[] = {
+ { .compatible = "meas,tsys01", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, tsys01_of_match);
+
static struct i2c_driver tsys01_driver = {
.probe = tsys01_i2c_probe,
.id_table = tsys01_id,
.driver = {
.name = "tsys01",
+ .of_match_table = of_match_ptr(tsys01_of_match),
},
};
diff --git a/drivers/iio/trigger/stm32-timer-trigger.c b/drivers/iio/trigger/stm32-timer-trigger.c
index 25ad6ab..9b90534 100644
--- a/drivers/iio/trigger/stm32-timer-trigger.c
+++ b/drivers/iio/trigger/stm32-timer-trigger.c
@@ -13,6 +13,7 @@
#include <linux/mfd/stm32-timers.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/of_device.h>
#define MAX_TRIGGERS 7
#define MAX_VALIDS 5
@@ -28,9 +29,14 @@ static const void *triggers_table[][MAX_TRIGGERS] = {
{ TIM7_TRGO,},
{ TIM8_TRGO, TIM8_TRGO2, TIM8_CH1, TIM8_CH2, TIM8_CH3, TIM8_CH4,},
{ TIM9_TRGO, TIM9_CH1, TIM9_CH2,},
- { }, /* timer 10 */
- { }, /* timer 11 */
+ { TIM10_OC1,},
+ { TIM11_OC1,},
{ TIM12_TRGO, TIM12_CH1, TIM12_CH2,},
+ { TIM13_OC1,},
+ { TIM14_OC1,},
+ { TIM15_TRGO,},
+ { TIM16_OC1,},
+ { TIM17_OC1,},
};
/* List the triggers accepted by each timer */
@@ -43,10 +49,30 @@ static const void *valids_table[][MAX_VALIDS] = {
{ }, /* timer 6 */
{ }, /* timer 7 */
{ TIM1_TRGO, TIM2_TRGO, TIM4_TRGO, TIM5_TRGO,},
- { TIM2_TRGO, TIM3_TRGO,},
+ { TIM2_TRGO, TIM3_TRGO, TIM10_OC1, TIM11_OC1,},
+ { }, /* timer 10 */
+ { }, /* timer 11 */
+ { TIM4_TRGO, TIM5_TRGO, TIM13_OC1, TIM14_OC1,},
+};
+
+static const void *stm32h7_valids_table[][MAX_VALIDS] = {
+ { TIM15_TRGO, TIM2_TRGO, TIM3_TRGO, TIM4_TRGO,},
+ { TIM1_TRGO, TIM8_TRGO, TIM3_TRGO, TIM4_TRGO,},
+ { TIM1_TRGO, TIM2_TRGO, TIM15_TRGO, TIM4_TRGO,},
+ { TIM1_TRGO, TIM2_TRGO, TIM3_TRGO, TIM8_TRGO,},
+ { TIM1_TRGO, TIM8_TRGO, TIM3_TRGO, TIM4_TRGO,},
+ { }, /* timer 6 */
+ { }, /* timer 7 */
+ { TIM1_TRGO, TIM2_TRGO, TIM4_TRGO, TIM5_TRGO,},
+ { }, /* timer 9 */
{ }, /* timer 10 */
{ }, /* timer 11 */
- { TIM4_TRGO, TIM5_TRGO,},
+ { TIM4_TRGO, TIM5_TRGO, TIM13_OC1, TIM14_OC1,},
+ { }, /* timer 13 */
+ { }, /* timer 14 */
+ { TIM1_TRGO, TIM3_TRGO, TIM16_OC1, TIM17_OC1,},
+ { }, /* timer 16 */
+ { }, /* timer 17 */
};
struct stm32_timer_trigger {
@@ -59,11 +85,21 @@ struct stm32_timer_trigger {
bool has_trgo2;
};
+struct stm32_timer_trigger_cfg {
+ const void *(*valids_table)[MAX_VALIDS];
+ const unsigned int num_valids_table;
+};
+
static bool stm32_timer_is_trgo2_name(const char *name)
{
return !!strstr(name, "trgo2");
}
+static bool stm32_timer_is_trgo_name(const char *name)
+{
+ return (!!strstr(name, "trgo") && !strstr(name, "trgo2"));
+}
+
static int stm32_timer_start(struct stm32_timer_trigger *priv,
struct iio_trigger *trig,
unsigned int frequency)
@@ -328,6 +364,7 @@ static int stm32_setup_iio_triggers(struct stm32_timer_trigger *priv)
while (cur && *cur) {
struct iio_trigger *trig;
+ bool cur_is_trgo = stm32_timer_is_trgo_name(*cur);
bool cur_is_trgo2 = stm32_timer_is_trgo2_name(*cur);
if (cur_is_trgo2 && !priv->has_trgo2) {
@@ -344,10 +381,9 @@ static int stm32_setup_iio_triggers(struct stm32_timer_trigger *priv)
/*
* sampling frequency and master mode attributes
- * should only be available on trgo trigger which
- * is always the first in the list.
+ * should only be available on trgo/trgo2 triggers
*/
- if (cur == priv->triggers || cur_is_trgo2)
+ if (cur_is_trgo || cur_is_trgo2)
trig->dev.groups = stm32_trigger_attr_groups;
iio_trigger_set_drvdata(trig, priv);
@@ -770,18 +806,22 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct stm32_timer_trigger *priv;
struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent);
+ const struct stm32_timer_trigger_cfg *cfg;
unsigned int index;
int ret;
if (of_property_read_u32(dev->of_node, "reg", &index))
return -EINVAL;
+ cfg = (const struct stm32_timer_trigger_cfg *)
+ of_match_device(dev->driver->of_match_table, dev)->data;
+
if (index >= ARRAY_SIZE(triggers_table) ||
- index >= ARRAY_SIZE(valids_table))
+ index >= cfg->num_valids_table)
return -EINVAL;
/* Create an IIO device only if we have triggers to be validated */
- if (*valids_table[index])
+ if (*cfg->valids_table[index])
priv = stm32_setup_counter_device(dev);
else
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -794,7 +834,7 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev)
priv->clk = ddata->clk;
priv->max_arr = ddata->max_arr;
priv->triggers = triggers_table[index];
- priv->valids = valids_table[index];
+ priv->valids = cfg->valids_table[index];
stm32_timer_detect_trgo2(priv);
ret = stm32_setup_iio_triggers(priv);
@@ -806,8 +846,24 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev)
return 0;
}
+static const struct stm32_timer_trigger_cfg stm32_timer_trg_cfg = {
+ .valids_table = valids_table,
+ .num_valids_table = ARRAY_SIZE(valids_table),
+};
+
+static const struct stm32_timer_trigger_cfg stm32h7_timer_trg_cfg = {
+ .valids_table = stm32h7_valids_table,
+ .num_valids_table = ARRAY_SIZE(stm32h7_valids_table),
+};
+
static const struct of_device_id stm32_trig_of_match[] = {
- { .compatible = "st,stm32-timer-trigger", },
+ {
+ .compatible = "st,stm32-timer-trigger",
+ .data = (void *)&stm32_timer_trg_cfg,
+ }, {
+ .compatible = "st,stm32h7-timer-trigger",
+ .data = (void *)&stm32h7_timer_trg_cfg,
+ },
{ /* end node */ },
};
MODULE_DEVICE_TABLE(of, stm32_trig_of_match);
diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig
index 234fe01..3726205 100644
--- a/drivers/infiniband/Kconfig
+++ b/drivers/infiniband/Kconfig
@@ -34,6 +34,15 @@ config INFINIBAND_USER_ACCESS
libibverbs, libibcm and a hardware driver library from
<http://www.openfabrics.org/git/>.
+config INFINIBAND_EXP_USER_ACCESS
+ bool "Allow experimental support for Infiniband ABI"
+ depends on INFINIBAND_USER_ACCESS
+ ---help---
+ IOCTL based ABI support for Infiniband. This allows userspace
+ to invoke the experimental IOCTL based ABI.
+ These commands are parsed via per-device parsing tree and
+ enables per-device features.
+
config INFINIBAND_USER_MEM
bool
depends on INFINIBAND_USER_ACCESS != n
diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile
index e3cdaff..b4df164 100644
--- a/drivers/infiniband/core/Makefile
+++ b/drivers/infiniband/core/Makefile
@@ -11,7 +11,8 @@ ib_core-y := packer.o ud_header.o verbs.o cq.o rw.o sysfs.o \
device.o fmr_pool.o cache.o netlink.o \
roce_gid_mgmt.o mr_pool.o addr.o sa_query.o \
multicast.o mad.o smi.o agent.o mad_rmpp.o \
- security.o
+ security.o nldev.o
+
ib_core-$(CONFIG_INFINIBAND_USER_MEM) += umem.o
ib_core-$(CONFIG_INFINIBAND_ON_DEMAND_PAGING) += umem_odp.o umem_rbtree.o
ib_core-$(CONFIG_CGROUP_RDMA) += cgroup.o
@@ -31,4 +32,5 @@ ib_umad-y := user_mad.o
ib_ucm-y := ucm.o
ib_uverbs-y := uverbs_main.o uverbs_cmd.o uverbs_marshall.o \
- rdma_core.o uverbs_std_types.o
+ rdma_core.o uverbs_std_types.o uverbs_ioctl.o \
+ uverbs_ioctl_merge.o
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index 437522c..12523f6 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -130,13 +130,11 @@ static void ib_nl_process_good_ip_rsep(const struct nlmsghdr *nlh)
}
int ib_nl_handle_ip_res_resp(struct sk_buff *skb,
- struct netlink_callback *cb)
+ struct nlmsghdr *nlh,
+ struct netlink_ext_ack *extack)
{
- const struct nlmsghdr *nlh = (struct nlmsghdr *)cb->nlh;
-
if ((nlh->nlmsg_flags & NLM_F_REQUEST) ||
- !(NETLINK_CB(skb).sk) ||
- !netlink_capable(skb, CAP_NET_ADMIN))
+ !(NETLINK_CB(skb).sk))
return -EPERM;
if (ib_nl_is_good_ip_resp(nlh))
@@ -186,7 +184,7 @@ static int ib_nl_ip_send_msg(struct rdma_dev_addr *dev_addr,
/* Repair the nlmsg header length */
nlmsg_end(skb, nlh);
- ibnl_multicast(skb, nlh, RDMA_NL_GROUP_LS, GFP_KERNEL);
+ rdma_nl_multicast(skb, RDMA_NL_GROUP_LS, GFP_KERNEL);
/* Make the request retry, so when we get the response from userspace
* we will have something.
@@ -326,7 +324,7 @@ static void queue_req(struct addr_req *req)
static int ib_nl_fetch_ha(struct dst_entry *dst, struct rdma_dev_addr *dev_addr,
const void *daddr, u32 seq, u16 family)
{
- if (ibnl_chk_listeners(RDMA_NL_GROUP_LS))
+ if (rdma_nl_chk_listeners(RDMA_NL_GROUP_LS))
return -EADDRNOTAVAIL;
/* We fill in what we can, the response will fill the rest */
diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
index efc9430..7751563 100644
--- a/drivers/infiniband/core/cache.c
+++ b/drivers/infiniband/core/cache.c
@@ -1199,30 +1199,23 @@ int ib_cache_setup_one(struct ib_device *device)
device->cache.ports =
kzalloc(sizeof(*device->cache.ports) *
(rdma_end_port(device) - rdma_start_port(device) + 1), GFP_KERNEL);
- if (!device->cache.ports) {
- err = -ENOMEM;
- goto out;
- }
+ if (!device->cache.ports)
+ return -ENOMEM;
err = gid_table_setup_one(device);
- if (err)
- goto out;
+ if (err) {
+ kfree(device->cache.ports);
+ device->cache.ports = NULL;
+ return err;
+ }
for (p = 0; p <= rdma_end_port(device) - rdma_start_port(device); ++p)
ib_cache_update(device, p + rdma_start_port(device), true);
INIT_IB_EVENT_HANDLER(&device->cache.event_handler,
device, ib_cache_event);
- err = ib_register_event_handler(&device->cache.event_handler);
- if (err)
- goto err;
-
+ ib_register_event_handler(&device->cache.event_handler);
return 0;
-
-err:
- gid_table_cleanup_one(device);
-out:
- return err;
}
void ib_cache_release_one(struct ib_device *device)
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 2b4d613..4c4b465 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -373,11 +373,19 @@ out:
return ret;
}
-static int cm_alloc_response_msg(struct cm_port *port,
- struct ib_mad_recv_wc *mad_recv_wc,
- struct ib_mad_send_buf **msg)
+static struct ib_mad_send_buf *cm_alloc_response_msg_no_ah(struct cm_port *port,
+ struct ib_mad_recv_wc *mad_recv_wc)
+{
+ return ib_create_send_mad(port->mad_agent, 1, mad_recv_wc->wc->pkey_index,
+ 0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA,
+ GFP_ATOMIC,
+ IB_MGMT_BASE_VERSION);
+}
+
+static int cm_create_response_msg_ah(struct cm_port *port,
+ struct ib_mad_recv_wc *mad_recv_wc,
+ struct ib_mad_send_buf *msg)
{
- struct ib_mad_send_buf *m;
struct ib_ah *ah;
ah = ib_create_ah_from_wc(port->mad_agent->qp->pd, mad_recv_wc->wc,
@@ -385,27 +393,40 @@ static int cm_alloc_response_msg(struct cm_port *port,
if (IS_ERR(ah))
return PTR_ERR(ah);
- m = ib_create_send_mad(port->mad_agent, 1, mad_recv_wc->wc->pkey_index,
- 0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA,
- GFP_ATOMIC,
- IB_MGMT_BASE_VERSION);
- if (IS_ERR(m)) {
- rdma_destroy_ah(ah);
- return PTR_ERR(m);
- }
- m->ah = ah;
- *msg = m;
+ msg->ah = ah;
return 0;
}
static void cm_free_msg(struct ib_mad_send_buf *msg)
{
- rdma_destroy_ah(msg->ah);
+ if (msg->ah)
+ rdma_destroy_ah(msg->ah);
if (msg->context[0])
cm_deref_id(msg->context[0]);
ib_free_send_mad(msg);
}
+static int cm_alloc_response_msg(struct cm_port *port,
+ struct ib_mad_recv_wc *mad_recv_wc,
+ struct ib_mad_send_buf **msg)
+{
+ struct ib_mad_send_buf *m;
+ int ret;
+
+ m = cm_alloc_response_msg_no_ah(port, mad_recv_wc);
+ if (IS_ERR(m))
+ return PTR_ERR(m);
+
+ ret = cm_create_response_msg_ah(port, mad_recv_wc, m);
+ if (ret) {
+ cm_free_msg(m);
+ return ret;
+ }
+
+ *msg = m;
+ return 0;
+}
+
static void * cm_copy_private_data(const void *private_data,
u8 private_data_len)
{
@@ -1175,6 +1196,11 @@ static void cm_format_req(struct cm_req_msg *req_msg,
{
struct sa_path_rec *pri_path = param->primary_path;
struct sa_path_rec *alt_path = param->alternate_path;
+ bool pri_ext = false;
+
+ if (pri_path->rec_type == SA_PATH_REC_TYPE_OPA)
+ pri_ext = opa_is_extended_lid(pri_path->opa.dlid,
+ pri_path->opa.slid);
cm_format_mad_hdr(&req_msg->hdr, CM_REQ_ATTR_ID,
cm_form_tid(cm_id_priv, CM_MSG_SEQUENCE_REQ));
@@ -1202,18 +1228,24 @@ static void cm_format_req(struct cm_req_msg *req_msg,
cm_req_set_srq(req_msg, param->srq);
}
+ req_msg->primary_local_gid = pri_path->sgid;
+ req_msg->primary_remote_gid = pri_path->dgid;
+ if (pri_ext) {
+ req_msg->primary_local_gid.global.interface_id
+ = OPA_MAKE_ID(be32_to_cpu(pri_path->opa.slid));
+ req_msg->primary_remote_gid.global.interface_id
+ = OPA_MAKE_ID(be32_to_cpu(pri_path->opa.dlid));
+ }
if (pri_path->hop_limit <= 1) {
- req_msg->primary_local_lid =
+ req_msg->primary_local_lid = pri_ext ? 0 :
htons(ntohl(sa_path_get_slid(pri_path)));
- req_msg->primary_remote_lid =
+ req_msg->primary_remote_lid = pri_ext ? 0 :
htons(ntohl(sa_path_get_dlid(pri_path)));
} else {
/* Work-around until there's a way to obtain remote LID info */
req_msg->primary_local_lid = IB_LID_PERMISSIVE;
req_msg->primary_remote_lid = IB_LID_PERMISSIVE;
}
- req_msg->primary_local_gid = pri_path->sgid;
- req_msg->primary_remote_gid = pri_path->dgid;
cm_req_set_primary_flow_label(req_msg, pri_path->flow_label);
cm_req_set_primary_packet_rate(req_msg, pri_path->rate);
req_msg->primary_traffic_class = pri_path->traffic_class;
@@ -1225,17 +1257,29 @@ static void cm_format_req(struct cm_req_msg *req_msg,
pri_path->packet_life_time));
if (alt_path) {
+ bool alt_ext = false;
+
+ if (alt_path->rec_type == SA_PATH_REC_TYPE_OPA)
+ alt_ext = opa_is_extended_lid(alt_path->opa.dlid,
+ alt_path->opa.slid);
+
+ req_msg->alt_local_gid = alt_path->sgid;
+ req_msg->alt_remote_gid = alt_path->dgid;
+ if (alt_ext) {
+ req_msg->alt_local_gid.global.interface_id
+ = OPA_MAKE_ID(be32_to_cpu(alt_path->opa.slid));
+ req_msg->alt_remote_gid.global.interface_id
+ = OPA_MAKE_ID(be32_to_cpu(alt_path->opa.dlid));
+ }
if (alt_path->hop_limit <= 1) {
- req_msg->alt_local_lid =
+ req_msg->alt_local_lid = alt_ext ? 0 :
htons(ntohl(sa_path_get_slid(alt_path)));
- req_msg->alt_remote_lid =
+ req_msg->alt_remote_lid = alt_ext ? 0 :
htons(ntohl(sa_path_get_dlid(alt_path)));
} else {
req_msg->alt_local_lid = IB_LID_PERMISSIVE;
req_msg->alt_remote_lid = IB_LID_PERMISSIVE;
}
- req_msg->alt_local_gid = alt_path->sgid;
- req_msg->alt_remote_gid = alt_path->dgid;
cm_req_set_alt_flow_label(req_msg,
alt_path->flow_label);
cm_req_set_alt_packet_rate(req_msg, alt_path->rate);
@@ -1405,16 +1449,63 @@ static inline int cm_is_active_peer(__be64 local_ca_guid, __be64 remote_ca_guid,
(be32_to_cpu(local_qpn) > be32_to_cpu(remote_qpn))));
}
+static bool cm_req_has_alt_path(struct cm_req_msg *req_msg)
+{
+ return ((req_msg->alt_local_lid) ||
+ (ib_is_opa_gid(&req_msg->alt_local_gid)));
+}
+
+static void cm_path_set_rec_type(struct ib_device *ib_device, u8 port_num,
+ struct sa_path_rec *path, union ib_gid *gid)
+{
+ if (ib_is_opa_gid(gid) && rdma_cap_opa_ah(ib_device, port_num))
+ path->rec_type = SA_PATH_REC_TYPE_OPA;
+ else
+ path->rec_type = SA_PATH_REC_TYPE_IB;
+}
+
+static void cm_format_path_lid_from_req(struct cm_req_msg *req_msg,
+ struct sa_path_rec *primary_path,
+ struct sa_path_rec *alt_path)
+{
+ u32 lid;
+
+ if (primary_path->rec_type != SA_PATH_REC_TYPE_OPA) {
+ sa_path_set_dlid(primary_path,
+ htonl(ntohs(req_msg->primary_local_lid)));
+ sa_path_set_slid(primary_path,
+ htonl(ntohs(req_msg->primary_remote_lid)));
+ } else {
+ lid = opa_get_lid_from_gid(&req_msg->primary_local_gid);
+ sa_path_set_dlid(primary_path, cpu_to_be32(lid));
+
+ lid = opa_get_lid_from_gid(&req_msg->primary_remote_gid);
+ sa_path_set_slid(primary_path, cpu_to_be32(lid));
+ }
+
+ if (!cm_req_has_alt_path(req_msg))
+ return;
+
+ if (alt_path->rec_type != SA_PATH_REC_TYPE_OPA) {
+ sa_path_set_dlid(alt_path,
+ htonl(ntohs(req_msg->alt_local_lid)));
+ sa_path_set_slid(alt_path,
+ htonl(ntohs(req_msg->alt_remote_lid)));
+ } else {
+ lid = opa_get_lid_from_gid(&req_msg->alt_local_gid);
+ sa_path_set_dlid(alt_path, cpu_to_be32(lid));
+
+ lid = opa_get_lid_from_gid(&req_msg->alt_remote_gid);
+ sa_path_set_slid(alt_path, cpu_to_be32(lid));
+ }
+}
+
static void cm_format_paths_from_req(struct cm_req_msg *req_msg,
struct sa_path_rec *primary_path,
struct sa_path_rec *alt_path)
{
primary_path->dgid = req_msg->primary_local_gid;
primary_path->sgid = req_msg->primary_remote_gid;
- sa_path_set_dlid(primary_path,
- htonl(ntohs(req_msg->primary_local_lid)));
- sa_path_set_slid(primary_path,
- htonl(ntohs(req_msg->primary_remote_lid)));
primary_path->flow_label = cm_req_get_primary_flow_label(req_msg);
primary_path->hop_limit = req_msg->primary_hop_limit;
primary_path->traffic_class = req_msg->primary_traffic_class;
@@ -1431,13 +1522,9 @@ static void cm_format_paths_from_req(struct cm_req_msg *req_msg,
primary_path->packet_life_time -= (primary_path->packet_life_time > 0);
primary_path->service_id = req_msg->service_id;
- if (req_msg->alt_local_lid) {
+ if (cm_req_has_alt_path(req_msg)) {
alt_path->dgid = req_msg->alt_local_gid;
alt_path->sgid = req_msg->alt_remote_gid;
- sa_path_set_dlid(alt_path,
- htonl(ntohs(req_msg->alt_local_lid)));
- sa_path_set_slid(alt_path,
- htonl(ntohs(req_msg->alt_remote_lid)));
alt_path->flow_label = cm_req_get_alt_flow_label(req_msg);
alt_path->hop_limit = req_msg->alt_hop_limit;
alt_path->traffic_class = req_msg->alt_traffic_class;
@@ -1454,6 +1541,7 @@ static void cm_format_paths_from_req(struct cm_req_msg *req_msg,
alt_path->packet_life_time -= (alt_path->packet_life_time > 0);
alt_path->service_id = req_msg->service_id;
}
+ cm_format_path_lid_from_req(req_msg, primary_path, alt_path);
}
static u16 cm_get_bth_pkey(struct cm_work *work)
@@ -1703,7 +1791,7 @@ static void cm_process_routed_req(struct cm_req_msg *req_msg, struct ib_wc *wc)
{
if (!cm_req_get_primary_subnet_local(req_msg)) {
if (req_msg->primary_local_lid == IB_LID_PERMISSIVE) {
- req_msg->primary_local_lid = cpu_to_be16(wc->slid);
+ req_msg->primary_local_lid = ib_lid_be16(wc->slid);
cm_req_set_primary_sl(req_msg, wc->sl);
}
@@ -1713,7 +1801,7 @@ static void cm_process_routed_req(struct cm_req_msg *req_msg, struct ib_wc *wc)
if (!cm_req_get_alt_subnet_local(req_msg)) {
if (req_msg->alt_local_lid == IB_LID_PERMISSIVE) {
- req_msg->alt_local_lid = cpu_to_be16(wc->slid);
+ req_msg->alt_local_lid = ib_lid_be16(wc->slid);
cm_req_set_alt_sl(req_msg, wc->sl);
}
@@ -1784,9 +1872,12 @@ static int cm_req_handler(struct cm_work *work)
dev_net(gid_attr.ndev));
dev_put(gid_attr.ndev);
} else {
- work->path[0].rec_type = SA_PATH_REC_TYPE_IB;
+ cm_path_set_rec_type(work->port->cm_dev->ib_device,
+ work->port->port_num,
+ &work->path[0],
+ &req_msg->primary_local_gid);
}
- if (req_msg->alt_local_lid)
+ if (cm_req_has_alt_path(req_msg))
work->path[1].rec_type = work->path[0].rec_type;
cm_format_paths_from_req(req_msg, &work->path[0],
&work->path[1]);
@@ -1811,16 +1902,19 @@ static int cm_req_handler(struct cm_work *work)
dev_net(gid_attr.ndev));
dev_put(gid_attr.ndev);
} else {
- work->path[0].rec_type = SA_PATH_REC_TYPE_IB;
+ cm_path_set_rec_type(work->port->cm_dev->ib_device,
+ work->port->port_num,
+ &work->path[0],
+ &req_msg->primary_local_gid);
}
- if (req_msg->alt_local_lid)
+ if (cm_req_has_alt_path(req_msg))
work->path[1].rec_type = work->path[0].rec_type;
ib_send_cm_rej(cm_id, IB_CM_REJ_INVALID_GID,
&work->path[0].sgid, sizeof work->path[0].sgid,
NULL, 0);
goto rejected;
}
- if (req_msg->alt_local_lid) {
+ if (cm_req_has_alt_path(req_msg)) {
ret = cm_init_av_by_path(&work->path[1], &cm_id_priv->alt_av,
cm_id_priv);
if (ret) {
@@ -2424,7 +2518,8 @@ static int cm_dreq_handler(struct cm_work *work)
case IB_CM_TIMEWAIT:
atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES].
counter[CM_DREQ_COUNTER]);
- if (cm_alloc_response_msg(work->port, work->mad_recv_wc, &msg))
+ msg = cm_alloc_response_msg_no_ah(work->port, work->mad_recv_wc);
+ if (IS_ERR(msg))
goto unlock;
cm_format_drep((struct cm_drep_msg *) msg->mad, cm_id_priv,
@@ -2432,7 +2527,8 @@ static int cm_dreq_handler(struct cm_work *work)
cm_id_priv->private_data_len);
spin_unlock_irq(&cm_id_priv->lock);
- if (ib_post_send_mad(msg, NULL))
+ if (cm_create_response_msg_ah(work->port, work->mad_recv_wc, msg) ||
+ ib_post_send_mad(msg, NULL))
cm_free_msg(msg);
goto deref;
case IB_CM_DREQ_RCVD:
@@ -2843,6 +2939,11 @@ static void cm_format_lap(struct cm_lap_msg *lap_msg,
const void *private_data,
u8 private_data_len)
{
+ bool alt_ext = false;
+
+ if (alternate_path->rec_type == SA_PATH_REC_TYPE_OPA)
+ alt_ext = opa_is_extended_lid(alternate_path->opa.dlid,
+ alternate_path->opa.slid);
cm_format_mad_hdr(&lap_msg->hdr, CM_LAP_ATTR_ID,
cm_form_tid(cm_id_priv, CM_MSG_SEQUENCE_LAP));
lap_msg->local_comm_id = cm_id_priv->id.local_id;
@@ -2856,6 +2957,12 @@ static void cm_format_lap(struct cm_lap_msg *lap_msg,
htons(ntohl(sa_path_get_dlid(alternate_path)));
lap_msg->alt_local_gid = alternate_path->sgid;
lap_msg->alt_remote_gid = alternate_path->dgid;
+ if (alt_ext) {
+ lap_msg->alt_local_gid.global.interface_id
+ = OPA_MAKE_ID(be32_to_cpu(alternate_path->opa.slid));
+ lap_msg->alt_remote_gid.global.interface_id
+ = OPA_MAKE_ID(be32_to_cpu(alternate_path->opa.dlid));
+ }
cm_lap_set_flow_label(lap_msg, alternate_path->flow_label);
cm_lap_set_traffic_class(lap_msg, alternate_path->traffic_class);
lap_msg->alt_hop_limit = alternate_path->hop_limit;
@@ -2924,16 +3031,29 @@ out: spin_unlock_irqrestore(&cm_id_priv->lock, flags);
}
EXPORT_SYMBOL(ib_send_cm_lap);
+static void cm_format_path_lid_from_lap(struct cm_lap_msg *lap_msg,
+ struct sa_path_rec *path)
+{
+ u32 lid;
+
+ if (path->rec_type != SA_PATH_REC_TYPE_OPA) {
+ sa_path_set_dlid(path, htonl(ntohs(lap_msg->alt_local_lid)));
+ sa_path_set_slid(path, htonl(ntohs(lap_msg->alt_remote_lid)));
+ } else {
+ lid = opa_get_lid_from_gid(&lap_msg->alt_local_gid);
+ sa_path_set_dlid(path, cpu_to_be32(lid));
+
+ lid = opa_get_lid_from_gid(&lap_msg->alt_remote_gid);
+ sa_path_set_slid(path, cpu_to_be32(lid));
+ }
+}
+
static void cm_format_path_from_lap(struct cm_id_private *cm_id_priv,
struct sa_path_rec *path,
struct cm_lap_msg *lap_msg)
{
- memset(path, 0, sizeof *path);
- path->rec_type = SA_PATH_REC_TYPE_IB;
path->dgid = lap_msg->alt_local_gid;
path->sgid = lap_msg->alt_remote_gid;
- sa_path_set_dlid(path, htonl(ntohs(lap_msg->alt_local_lid)));
- sa_path_set_slid(path, htonl(ntohs(lap_msg->alt_remote_lid)));
path->flow_label = cm_lap_get_flow_label(lap_msg);
path->hop_limit = lap_msg->alt_hop_limit;
path->traffic_class = cm_lap_get_traffic_class(lap_msg);
@@ -2947,6 +3067,7 @@ static void cm_format_path_from_lap(struct cm_id_private *cm_id_priv,
path->packet_life_time_selector = IB_SA_EQ;
path->packet_life_time = cm_lap_get_local_ack_timeout(lap_msg);
path->packet_life_time -= (path->packet_life_time > 0);
+ cm_format_path_lid_from_lap(lap_msg, path);
}
static int cm_lap_handler(struct cm_work *work)
@@ -2965,6 +3086,11 @@ static int cm_lap_handler(struct cm_work *work)
return -EINVAL;
param = &work->cm_event.param.lap_rcvd;
+ memset(&work->path[0], 0, sizeof(work->path[1]));
+ cm_path_set_rec_type(work->port->cm_dev->ib_device,
+ work->port->port_num,
+ &work->path[0],
+ &lap_msg->alt_local_gid);
param->alternate_path = &work->path[0];
cm_format_path_from_lap(cm_id_priv, param->alternate_path, lap_msg);
work->cm_event.private_data = &lap_msg->private_data;
@@ -2980,7 +3106,8 @@ static int cm_lap_handler(struct cm_work *work)
case IB_CM_MRA_LAP_SENT:
atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES].
counter[CM_LAP_COUNTER]);
- if (cm_alloc_response_msg(work->port, work->mad_recv_wc, &msg))
+ msg = cm_alloc_response_msg_no_ah(work->port, work->mad_recv_wc);
+ if (IS_ERR(msg))
goto unlock;
cm_format_mra((struct cm_mra_msg *) msg->mad, cm_id_priv,
@@ -2990,7 +3117,8 @@ static int cm_lap_handler(struct cm_work *work)
cm_id_priv->private_data_len);
spin_unlock_irq(&cm_id_priv->lock);
- if (ib_post_send_mad(msg, NULL))
+ if (cm_create_response_msg_ah(work->port, work->mad_recv_wc, msg) ||
+ ib_post_send_mad(msg, NULL))
cm_free_msg(msg);
goto deref;
case IB_CM_LAP_RCVD:
@@ -4201,7 +4329,7 @@ static int __init ib_cm_init(void)
goto error1;
}
- cm.wq = create_workqueue("ib_cm");
+ cm.wq = alloc_workqueue("ib_cm", 0, 1);
if (!cm.wq) {
ret = -ENOMEM;
goto error2;
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 0eb3932..852c8fe 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -72,6 +72,7 @@ MODULE_LICENSE("Dual BSD/GPL");
#define CMA_MAX_CM_RETRIES 15
#define CMA_CM_MRA_SETTING (IB_CM_MRA_FLAG_DELAY | 24)
#define CMA_IBOE_PACKET_LIFETIME 18
+#define CMA_PREFERRED_ROCE_GID_TYPE IB_GID_TYPE_ROCE_UDP_ENCAP
static const char * const cma_events[] = {
[RDMA_CM_EVENT_ADDR_RESOLVED] = "address resolved",
@@ -3998,7 +3999,8 @@ static void iboe_mcast_work_handler(struct work_struct *work)
kfree(mw);
}
-static void cma_iboe_set_mgid(struct sockaddr *addr, union ib_gid *mgid)
+static void cma_iboe_set_mgid(struct sockaddr *addr, union ib_gid *mgid,
+ enum ib_gid_type gid_type)
{
struct sockaddr_in *sin = (struct sockaddr_in *)addr;
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
@@ -4008,8 +4010,8 @@ static void cma_iboe_set_mgid(struct sockaddr *addr, union ib_gid *mgid)
} else if (addr->sa_family == AF_INET6) {
memcpy(mgid, &sin6->sin6_addr, sizeof *mgid);
} else {
- mgid->raw[0] = 0xff;
- mgid->raw[1] = 0x0e;
+ mgid->raw[0] = (gid_type == IB_GID_TYPE_IB) ? 0xff : 0;
+ mgid->raw[1] = (gid_type == IB_GID_TYPE_IB) ? 0x0e : 0;
mgid->raw[2] = 0;
mgid->raw[3] = 0;
mgid->raw[4] = 0;
@@ -4050,7 +4052,9 @@ static int cma_iboe_join_multicast(struct rdma_id_private *id_priv,
goto out1;
}
- cma_iboe_set_mgid(addr, &mc->multicast.ib->rec.mgid);
+ gid_type = id_priv->cma_dev->default_gid_type[id_priv->id.port_num -
+ rdma_start_port(id_priv->cma_dev->device)];
+ cma_iboe_set_mgid(addr, &mc->multicast.ib->rec.mgid, gid_type);
mc->multicast.ib->rec.pkey = cpu_to_be16(0xffff);
if (id_priv->id.ps == RDMA_PS_UDP)
@@ -4066,8 +4070,6 @@ static int cma_iboe_join_multicast(struct rdma_id_private *id_priv,
mc->multicast.ib->rec.hop_limit = 1;
mc->multicast.ib->rec.mtu = iboe_get_mtu(ndev->mtu);
- gid_type = id_priv->cma_dev->default_gid_type[id_priv->id.port_num -
- rdma_start_port(id_priv->cma_dev->device)];
if (addr->sa_family == AF_INET) {
if (gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP) {
mc->multicast.ib->rec.hop_limit = IPV6_DEFAULT_HOPLIMIT;
@@ -4280,8 +4282,12 @@ static void cma_add_one(struct ib_device *device)
for (i = rdma_start_port(device); i <= rdma_end_port(device); i++) {
supported_gids = roce_gid_type_mask_support(device, i);
WARN_ON(!supported_gids);
- cma_dev->default_gid_type[i - rdma_start_port(device)] =
- find_first_bit(&supported_gids, BITS_PER_LONG);
+ if (supported_gids & (1 << CMA_PREFERRED_ROCE_GID_TYPE))
+ cma_dev->default_gid_type[i - rdma_start_port(device)] =
+ CMA_PREFERRED_ROCE_GID_TYPE;
+ else
+ cma_dev->default_gid_type[i - rdma_start_port(device)] =
+ find_first_bit(&supported_gids, BITS_PER_LONG);
cma_dev->default_roce_tos[i - rdma_start_port(device)] = 0;
}
@@ -4452,9 +4458,8 @@ out:
return skb->len;
}
-static const struct ibnl_client_cbs cma_cb_table[] = {
- [RDMA_NL_RDMA_CM_ID_STATS] = { .dump = cma_get_id_stats,
- .module = THIS_MODULE },
+static const struct rdma_nl_cbs cma_cb_table[] = {
+ [RDMA_NL_RDMA_CM_ID_STATS] = { .dump = cma_get_id_stats},
};
static int cma_init_net(struct net *net)
@@ -4506,9 +4511,7 @@ static int __init cma_init(void)
if (ret)
goto err;
- if (ibnl_add_client(RDMA_NL_RDMA_CM, ARRAY_SIZE(cma_cb_table),
- cma_cb_table))
- pr_warn("RDMA CMA: failed to add netlink callback\n");
+ rdma_nl_register(RDMA_NL_RDMA_CM, cma_cb_table);
cma_configfs_init();
return 0;
@@ -4525,7 +4528,7 @@ err_wq:
static void __exit cma_cleanup(void)
{
cma_configfs_exit();
- ibnl_remove_client(RDMA_NL_RDMA_CM);
+ rdma_nl_unregister(RDMA_NL_RDMA_CM);
ib_unregister_client(&cma_client);
unregister_netdevice_notifier(&cma_nb);
rdma_addr_unregister_client(&addr_client);
@@ -4534,5 +4537,7 @@ static void __exit cma_cleanup(void)
destroy_workqueue(cma_wq);
}
+MODULE_ALIAS_RDMA_NETLINK(RDMA_NL_RDMA_CM, 1);
+
module_init(cma_init);
module_exit(cma_cleanup);
diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h
index 11ae675..a1d687a 100644
--- a/drivers/infiniband/core/core_priv.h
+++ b/drivers/infiniband/core/core_priv.h
@@ -38,6 +38,7 @@
#include <linux/cgroup_rdma.h>
#include <rdma/ib_verbs.h>
+#include <rdma/opa_addr.h>
#include <rdma/ib_mad.h>
#include "mad_priv.h"
@@ -102,6 +103,14 @@ void ib_enum_all_roce_netdevs(roce_netdev_filter filter,
roce_netdev_callback cb,
void *cookie);
+typedef int (*nldev_callback)(struct ib_device *device,
+ struct sk_buff *skb,
+ struct netlink_callback *cb,
+ unsigned int idx);
+
+int ib_enum_all_devs(nldev_callback nldev_cb, struct sk_buff *skb,
+ struct netlink_callback *cb);
+
enum ib_cache_gid_default_mode {
IB_CACHE_GID_DEFAULT_MODE_SET,
IB_CACHE_GID_DEFAULT_MODE_DELETE
@@ -179,8 +188,8 @@ void ib_mad_cleanup(void);
int ib_sa_init(void);
void ib_sa_cleanup(void);
-int ibnl_init(void);
-void ibnl_cleanup(void);
+int rdma_nl_init(void);
+void rdma_nl_exit(void);
/**
* Check if there are any listeners to the netlink group
@@ -190,11 +199,14 @@ void ibnl_cleanup(void);
int ibnl_chk_listeners(unsigned int group);
int ib_nl_handle_resolve_resp(struct sk_buff *skb,
- struct netlink_callback *cb);
+ struct nlmsghdr *nlh,
+ struct netlink_ext_ack *extack);
int ib_nl_handle_set_timeout(struct sk_buff *skb,
- struct netlink_callback *cb);
+ struct nlmsghdr *nlh,
+ struct netlink_ext_ack *extack);
int ib_nl_handle_ip_res_resp(struct sk_buff *skb,
- struct netlink_callback *cb);
+ struct nlmsghdr *nlh,
+ struct netlink_ext_ack *extack);
int ib_get_cached_subnet_prefix(struct ib_device *device,
u8 port_num,
@@ -301,4 +313,9 @@ static inline int ib_mad_enforce_security(struct ib_mad_agent_private *map,
return 0;
}
#endif
+
+struct ib_device *__ib_device_get_by_index(u32 ifindex);
+/* RDMA device netlink */
+void nldev_init(void);
+void nldev_exit(void);
#endif /* _CORE_PRIV_H */
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index 221468f..84fc32a 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -134,6 +134,17 @@ static int ib_device_check_mandatory(struct ib_device *device)
return 0;
}
+struct ib_device *__ib_device_get_by_index(u32 index)
+{
+ struct ib_device *device;
+
+ list_for_each_entry(device, &device_list, core_list)
+ if (device->index == index)
+ return device;
+
+ return NULL;
+}
+
static struct ib_device *__ib_device_get_by_name(const char *name)
{
struct ib_device *device;
@@ -145,7 +156,6 @@ static struct ib_device *__ib_device_get_by_name(const char *name)
return NULL;
}
-
static int alloc_name(char *name)
{
unsigned long *inuse;
@@ -326,10 +336,10 @@ static int read_port_immutable(struct ib_device *device)
return 0;
}
-void ib_get_device_fw_str(struct ib_device *dev, char *str, size_t str_len)
+void ib_get_device_fw_str(struct ib_device *dev, char *str)
{
if (dev->get_dev_fw_str)
- dev->get_dev_fw_str(dev, str, str_len);
+ dev->get_dev_fw_str(dev, str);
else
str[0] = '\0';
}
@@ -395,6 +405,30 @@ static int ib_security_change(struct notifier_block *nb, unsigned long event,
}
/**
+ * __dev_new_index - allocate an device index
+ *
+ * Returns a suitable unique value for a new device interface
+ * number. It assumes that there are less than 2^32-1 ib devices
+ * will be present in the system.
+ */
+static u32 __dev_new_index(void)
+{
+ /*
+ * The device index to allow stable naming.
+ * Similar to struct net -> ifindex.
+ */
+ static u32 index;
+
+ for (;;) {
+ if (!(++index))
+ index = 1;
+
+ if (!__ib_device_get_by_index(index))
+ return index;
+ }
+}
+
+/**
* ib_register_device - Register an IB device with IB core
* @device:Device to register
*
@@ -489,9 +523,10 @@ int ib_register_device(struct ib_device *device,
device->reg_state = IB_DEV_REGISTERED;
list_for_each_entry(client, &client_list, list)
- if (client->add && !add_client_context(device, client))
+ if (!add_client_context(device, client) && client->add)
client->add(device);
+ device->index = __dev_new_index();
down_write(&lists_rwsem);
list_add_tail(&device->core_list, &device_list);
up_write(&lists_rwsem);
@@ -578,7 +613,7 @@ int ib_register_client(struct ib_client *client)
mutex_lock(&device_mutex);
list_for_each_entry(device, &device_list, core_list)
- if (client->add && !add_client_context(device, client))
+ if (!add_client_context(device, client) && client->add)
client->add(device);
down_write(&lists_rwsem);
@@ -712,7 +747,7 @@ EXPORT_SYMBOL(ib_set_client_data);
* chapter 11 of the InfiniBand Architecture Specification). This
* callback may occur in interrupt context.
*/
-int ib_register_event_handler (struct ib_event_handler *event_handler)
+void ib_register_event_handler(struct ib_event_handler *event_handler)
{
unsigned long flags;
@@ -720,8 +755,6 @@ int ib_register_event_handler (struct ib_event_handler *event_handler)
list_add_tail(&event_handler->list,
&event_handler->device->event_handler_list);
spin_unlock_irqrestore(&event_handler->device->event_handler_lock, flags);
-
- return 0;
}
EXPORT_SYMBOL(ib_register_event_handler);
@@ -732,15 +765,13 @@ EXPORT_SYMBOL(ib_register_event_handler);
* Unregister an event handler registered with
* ib_register_event_handler().
*/
-int ib_unregister_event_handler(struct ib_event_handler *event_handler)
+void ib_unregister_event_handler(struct ib_event_handler *event_handler)
{
unsigned long flags;
spin_lock_irqsave(&event_handler->device->event_handler_lock, flags);
list_del(&event_handler->list);
spin_unlock_irqrestore(&event_handler->device->event_handler_lock, flags);
-
- return 0;
}
EXPORT_SYMBOL(ib_unregister_event_handler);
@@ -894,6 +925,31 @@ void ib_enum_all_roce_netdevs(roce_netdev_filter filter,
}
/**
+ * ib_enum_all_devs - enumerate all ib_devices
+ * @cb: Callback to call for each found ib_device
+ *
+ * Enumerates all ib_devices and calls callback() on each device.
+ */
+int ib_enum_all_devs(nldev_callback nldev_cb, struct sk_buff *skb,
+ struct netlink_callback *cb)
+{
+ struct ib_device *dev;
+ unsigned int idx = 0;
+ int ret = 0;
+
+ down_read(&lists_rwsem);
+ list_for_each_entry(dev, &device_list, core_list) {
+ ret = nldev_cb(dev, skb, cb, idx);
+ if (ret)
+ break;
+ idx++;
+ }
+
+ up_read(&lists_rwsem);
+ return ret;
+}
+
+/**
* ib_query_pkey - Get P_Key table entry
* @device:Device to query
* @port_num:Port number to query
@@ -945,14 +1001,17 @@ int ib_modify_port(struct ib_device *device,
u8 port_num, int port_modify_mask,
struct ib_port_modify *port_modify)
{
- if (!device->modify_port)
- return -ENOSYS;
+ int rc;
if (!rdma_is_port_valid(device, port_num))
return -EINVAL;
- return device->modify_port(device, port_num, port_modify_mask,
- port_modify);
+ if (device->modify_port)
+ rc = device->modify_port(device, port_num, port_modify_mask,
+ port_modify);
+ else
+ rc = rdma_protocol_roce(device, port_num) ? 0 : -ENOSYS;
+ return rc;
}
EXPORT_SYMBOL(ib_modify_port);
@@ -1087,29 +1146,21 @@ struct net_device *ib_get_net_dev_by_params(struct ib_device *dev,
}
EXPORT_SYMBOL(ib_get_net_dev_by_params);
-static struct ibnl_client_cbs ibnl_ls_cb_table[] = {
+static const struct rdma_nl_cbs ibnl_ls_cb_table[] = {
[RDMA_NL_LS_OP_RESOLVE] = {
- .dump = ib_nl_handle_resolve_resp,
- .module = THIS_MODULE },
+ .doit = ib_nl_handle_resolve_resp,
+ .flags = RDMA_NL_ADMIN_PERM,
+ },
[RDMA_NL_LS_OP_SET_TIMEOUT] = {
- .dump = ib_nl_handle_set_timeout,
- .module = THIS_MODULE },
+ .doit = ib_nl_handle_set_timeout,
+ .flags = RDMA_NL_ADMIN_PERM,
+ },
[RDMA_NL_LS_OP_IP_RESOLVE] = {
- .dump = ib_nl_handle_ip_res_resp,
- .module = THIS_MODULE },
+ .doit = ib_nl_handle_ip_res_resp,
+ .flags = RDMA_NL_ADMIN_PERM,
+ },
};
-static int ib_add_ibnl_clients(void)
-{
- return ibnl_add_client(RDMA_NL_LS, ARRAY_SIZE(ibnl_ls_cb_table),
- ibnl_ls_cb_table);
-}
-
-static void ib_remove_ibnl_clients(void)
-{
- ibnl_remove_client(RDMA_NL_LS);
-}
-
static int __init ib_core_init(void)
{
int ret;
@@ -1131,9 +1182,9 @@ static int __init ib_core_init(void)
goto err_comp;
}
- ret = ibnl_init();
+ ret = rdma_nl_init();
if (ret) {
- pr_warn("Couldn't init IB netlink interface\n");
+ pr_warn("Couldn't init IB netlink interface: err %d\n", ret);
goto err_sysfs;
}
@@ -1155,24 +1206,18 @@ static int __init ib_core_init(void)
goto err_mad;
}
- ret = ib_add_ibnl_clients();
- if (ret) {
- pr_warn("Couldn't register ibnl clients\n");
- goto err_sa;
- }
-
ret = register_lsm_notifier(&ibdev_lsm_nb);
if (ret) {
pr_warn("Couldn't register LSM notifier. ret %d\n", ret);
- goto err_ibnl_clients;
+ goto err_sa;
}
+ nldev_init();
+ rdma_nl_register(RDMA_NL_LS, ibnl_ls_cb_table);
ib_cache_setup();
return 0;
-err_ibnl_clients:
- ib_remove_ibnl_clients();
err_sa:
ib_sa_cleanup();
err_mad:
@@ -1180,7 +1225,7 @@ err_mad:
err_addr:
addr_cleanup();
err_ibnl:
- ibnl_cleanup();
+ rdma_nl_exit();
err_sysfs:
class_unregister(&ib_class);
err_comp:
@@ -1192,18 +1237,21 @@ err:
static void __exit ib_core_cleanup(void)
{
- unregister_lsm_notifier(&ibdev_lsm_nb);
ib_cache_cleanup();
- ib_remove_ibnl_clients();
+ nldev_exit();
+ rdma_nl_unregister(RDMA_NL_LS);
+ unregister_lsm_notifier(&ibdev_lsm_nb);
ib_sa_cleanup();
ib_mad_cleanup();
addr_cleanup();
- ibnl_cleanup();
+ rdma_nl_exit();
class_unregister(&ib_class);
destroy_workqueue(ib_comp_wq);
/* Make sure that any pending umem accounting work is done. */
destroy_workqueue(ib_wq);
}
+MODULE_ALIAS_RDMA_NETLINK(RDMA_NL_LS, 4);
+
module_init(ib_core_init);
module_exit(ib_core_cleanup);
diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c
index 31661b5..fcf42f6 100644
--- a/drivers/infiniband/core/iwcm.c
+++ b/drivers/infiniband/core/iwcm.c
@@ -80,7 +80,7 @@ const char *__attribute_const__ iwcm_reject_msg(int reason)
}
EXPORT_SYMBOL(iwcm_reject_msg);
-static struct ibnl_client_cbs iwcm_nl_cb_table[] = {
+static struct rdma_nl_cbs iwcm_nl_cb_table[] = {
[RDMA_NL_IWPM_REG_PID] = {.dump = iwpm_register_pid_cb},
[RDMA_NL_IWPM_ADD_MAPPING] = {.dump = iwpm_add_mapping_cb},
[RDMA_NL_IWPM_QUERY_MAPPING] = {.dump = iwpm_add_and_query_mapping_cb},
@@ -1175,13 +1175,9 @@ static int __init iw_cm_init(void)
ret = iwpm_init(RDMA_NL_IWCM);
if (ret)
pr_err("iw_cm: couldn't init iwpm\n");
-
- ret = ibnl_add_client(RDMA_NL_IWCM, ARRAY_SIZE(iwcm_nl_cb_table),
- iwcm_nl_cb_table);
- if (ret)
- pr_err("iw_cm: couldn't register netlink callbacks\n");
-
- iwcm_wq = alloc_ordered_workqueue("iw_cm_wq", WQ_MEM_RECLAIM);
+ else
+ rdma_nl_register(RDMA_NL_IWCM, iwcm_nl_cb_table);
+ iwcm_wq = alloc_ordered_workqueue("iw_cm_wq", 0);
if (!iwcm_wq)
return -ENOMEM;
@@ -1200,9 +1196,11 @@ static void __exit iw_cm_cleanup(void)
{
unregister_net_sysctl_table(iwcm_ctl_table_hdr);
destroy_workqueue(iwcm_wq);
- ibnl_remove_client(RDMA_NL_IWCM);
+ rdma_nl_unregister(RDMA_NL_IWCM);
iwpm_exit(RDMA_NL_IWCM);
}
+MODULE_ALIAS_RDMA_NETLINK(RDMA_NL_IWCM, 2);
+
module_init(iw_cm_init);
module_exit(iw_cm_cleanup);
diff --git a/drivers/infiniband/core/iwpm_msg.c b/drivers/infiniband/core/iwpm_msg.c
index a0e7c16..30825bb 100644
--- a/drivers/infiniband/core/iwpm_msg.c
+++ b/drivers/infiniband/core/iwpm_msg.c
@@ -42,7 +42,6 @@ int iwpm_valid_pid(void)
{
return iwpm_user_pid > 0;
}
-EXPORT_SYMBOL(iwpm_valid_pid);
/*
* iwpm_register_pid - Send a netlink query to user space
@@ -104,7 +103,7 @@ int iwpm_register_pid(struct iwpm_dev_data *pm_msg, u8 nl_client)
pr_debug("%s: Multicasting a nlmsg (dev = %s ifname = %s iwpm = %s)\n",
__func__, pm_msg->dev_name, pm_msg->if_name, iwpm_ulib_name);
- ret = ibnl_multicast(skb, nlh, RDMA_NL_GROUP_IWPM, GFP_KERNEL);
+ ret = rdma_nl_multicast(skb, RDMA_NL_GROUP_IWPM, GFP_KERNEL);
if (ret) {
skb = NULL; /* skb is freed in the netlink send-op handling */
iwpm_user_pid = IWPM_PID_UNAVAILABLE;
@@ -122,7 +121,6 @@ pid_query_error:
iwpm_free_nlmsg_request(&nlmsg_request->kref);
return ret;
}
-EXPORT_SYMBOL(iwpm_register_pid);
/*
* iwpm_add_mapping - Send a netlink add mapping message
@@ -174,7 +172,7 @@ int iwpm_add_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client)
goto add_mapping_error;
nlmsg_request->req_buffer = pm_msg;
- ret = ibnl_unicast(skb, nlh, iwpm_user_pid);
+ ret = rdma_nl_unicast_wait(skb, iwpm_user_pid);
if (ret) {
skb = NULL; /* skb is freed in the netlink send-op handling */
iwpm_user_pid = IWPM_PID_UNDEFINED;
@@ -191,7 +189,6 @@ add_mapping_error:
iwpm_free_nlmsg_request(&nlmsg_request->kref);
return ret;
}
-EXPORT_SYMBOL(iwpm_add_mapping);
/*
* iwpm_add_and_query_mapping - Send a netlink add and query
@@ -251,7 +248,7 @@ int iwpm_add_and_query_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client)
goto query_mapping_error;
nlmsg_request->req_buffer = pm_msg;
- ret = ibnl_unicast(skb, nlh, iwpm_user_pid);
+ ret = rdma_nl_unicast_wait(skb, iwpm_user_pid);
if (ret) {
skb = NULL; /* skb is freed in the netlink send-op handling */
err_str = "Unable to send a nlmsg";
@@ -267,7 +264,6 @@ query_mapping_error:
iwpm_free_nlmsg_request(&nlmsg_request->kref);
return ret;
}
-EXPORT_SYMBOL(iwpm_add_and_query_mapping);
/*
* iwpm_remove_mapping - Send a netlink remove mapping message
@@ -312,7 +308,7 @@ int iwpm_remove_mapping(struct sockaddr_storage *local_addr, u8 nl_client)
if (ret)
goto remove_mapping_error;
- ret = ibnl_unicast(skb, nlh, iwpm_user_pid);
+ ret = rdma_nl_unicast_wait(skb, iwpm_user_pid);
if (ret) {
skb = NULL; /* skb is freed in the netlink send-op handling */
iwpm_user_pid = IWPM_PID_UNDEFINED;
@@ -328,7 +324,6 @@ remove_mapping_error:
dev_kfree_skb_any(skb);
return ret;
}
-EXPORT_SYMBOL(iwpm_remove_mapping);
/* netlink attribute policy for the received response to register pid request */
static const struct nla_policy resp_reg_policy[IWPM_NLA_RREG_PID_MAX] = {
@@ -397,7 +392,6 @@ register_pid_response_exit:
up(&nlmsg_request->sem);
return 0;
}
-EXPORT_SYMBOL(iwpm_register_pid_cb);
/* netlink attribute policy for the received response to add mapping request */
static const struct nla_policy resp_add_policy[IWPM_NLA_RMANAGE_MAPPING_MAX] = {
@@ -466,7 +460,6 @@ add_mapping_response_exit:
up(&nlmsg_request->sem);
return 0;
}
-EXPORT_SYMBOL(iwpm_add_mapping_cb);
/* netlink attribute policy for the response to add and query mapping request
* and response with remote address info */
@@ -558,7 +551,6 @@ query_mapping_response_exit:
up(&nlmsg_request->sem);
return 0;
}
-EXPORT_SYMBOL(iwpm_add_and_query_mapping_cb);
/*
* iwpm_remote_info_cb - Process a port mapper message, containing
@@ -627,7 +619,6 @@ int iwpm_remote_info_cb(struct sk_buff *skb, struct netlink_callback *cb)
"remote_info: Mapped remote sockaddr:");
return ret;
}
-EXPORT_SYMBOL(iwpm_remote_info_cb);
/* netlink attribute policy for the received request for mapping info */
static const struct nla_policy resp_mapinfo_policy[IWPM_NLA_MAPINFO_REQ_MAX] = {
@@ -677,7 +668,6 @@ int iwpm_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb)
ret = iwpm_send_mapinfo(nl_client, iwpm_user_pid);
return ret;
}
-EXPORT_SYMBOL(iwpm_mapping_info_cb);
/* netlink attribute policy for the received mapping info ack */
static const struct nla_policy ack_mapinfo_policy[IWPM_NLA_MAPINFO_NUM_MAX] = {
@@ -707,7 +697,6 @@ int iwpm_ack_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb)
atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
return 0;
}
-EXPORT_SYMBOL(iwpm_ack_mapping_info_cb);
/* netlink attribute policy for the received port mapper error message */
static const struct nla_policy map_error_policy[IWPM_NLA_ERR_MAX] = {
@@ -751,4 +740,3 @@ int iwpm_mapping_error_cb(struct sk_buff *skb, struct netlink_callback *cb)
up(&nlmsg_request->sem);
return 0;
}
-EXPORT_SYMBOL(iwpm_mapping_error_cb);
diff --git a/drivers/infiniband/core/iwpm_util.c b/drivers/infiniband/core/iwpm_util.c
index f13870e..c81c559 100644
--- a/drivers/infiniband/core/iwpm_util.c
+++ b/drivers/infiniband/core/iwpm_util.c
@@ -54,8 +54,6 @@ static struct iwpm_admin_data iwpm_admin;
int iwpm_init(u8 nl_client)
{
int ret = 0;
- if (iwpm_valid_client(nl_client))
- return -EINVAL;
mutex_lock(&iwpm_admin_lock);
if (atomic_read(&iwpm_admin.refcount) == 0) {
iwpm_hash_bucket = kzalloc(IWPM_MAPINFO_HASH_SIZE *
@@ -83,7 +81,6 @@ init_exit:
}
return ret;
}
-EXPORT_SYMBOL(iwpm_init);
static void free_hash_bucket(void);
static void free_reminfo_bucket(void);
@@ -109,7 +106,6 @@ int iwpm_exit(u8 nl_client)
iwpm_set_registration(nl_client, IWPM_REG_UNDEF);
return 0;
}
-EXPORT_SYMBOL(iwpm_exit);
static struct hlist_head *get_mapinfo_hash_bucket(struct sockaddr_storage *,
struct sockaddr_storage *);
@@ -148,7 +144,6 @@ int iwpm_create_mapinfo(struct sockaddr_storage *local_sockaddr,
spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags);
return ret;
}
-EXPORT_SYMBOL(iwpm_create_mapinfo);
int iwpm_remove_mapinfo(struct sockaddr_storage *local_sockaddr,
struct sockaddr_storage *mapped_local_addr)
@@ -184,7 +179,6 @@ remove_mapinfo_exit:
spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags);
return ret;
}
-EXPORT_SYMBOL(iwpm_remove_mapinfo);
static void free_hash_bucket(void)
{
@@ -297,7 +291,6 @@ get_remote_info_exit:
spin_unlock_irqrestore(&iwpm_reminfo_lock, flags);
return ret;
}
-EXPORT_SYMBOL(iwpm_get_remote_info);
struct iwpm_nlmsg_request *iwpm_get_nlmsg_request(__u32 nlmsg_seq,
u8 nl_client, gfp_t gfp)
@@ -383,15 +376,11 @@ int iwpm_get_nlmsg_seq(void)
int iwpm_valid_client(u8 nl_client)
{
- if (nl_client >= RDMA_NL_NUM_CLIENTS)
- return 0;
return iwpm_admin.client_list[nl_client];
}
void iwpm_set_valid(u8 nl_client, int valid)
{
- if (nl_client >= RDMA_NL_NUM_CLIENTS)
- return;
iwpm_admin.client_list[nl_client] = valid;
}
@@ -608,7 +597,7 @@ static int send_mapinfo_num(u32 mapping_num, u8 nl_client, int iwpm_pid)
&mapping_num, IWPM_NLA_MAPINFO_SEND_NUM);
if (ret)
goto mapinfo_num_error;
- ret = ibnl_unicast(skb, nlh, iwpm_pid);
+ ret = rdma_nl_unicast(skb, iwpm_pid);
if (ret) {
skb = NULL;
err_str = "Unable to send a nlmsg";
@@ -637,7 +626,7 @@ static int send_nlmsg_done(struct sk_buff *skb, u8 nl_client, int iwpm_pid)
return -ENOMEM;
}
nlh->nlmsg_type = NLMSG_DONE;
- ret = ibnl_unicast(skb, (struct nlmsghdr *)skb->data, iwpm_pid);
+ ret = rdma_nl_unicast(skb, iwpm_pid);
if (ret)
pr_warn("%s Unable to send a nlmsg\n", __func__);
return ret;
diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c
index 0d3cca0..e5cf09c 100644
--- a/drivers/infiniband/core/mad_rmpp.c
+++ b/drivers/infiniband/core/mad_rmpp.c
@@ -64,7 +64,7 @@ struct mad_rmpp_recv {
__be64 tid;
u32 src_qp;
- u16 slid;
+ u32 slid;
u8 mgmt_class;
u8 class_version;
u8 method;
diff --git a/drivers/infiniband/core/netlink.c b/drivers/infiniband/core/netlink.c
index 94931c4..e685148 100644
--- a/drivers/infiniband/core/netlink.c
+++ b/drivers/infiniband/core/netlink.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (c) 2017 Mellanox Technologies Inc. All rights reserved.
* Copyright (c) 2010 Voltaire Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
@@ -37,239 +38,267 @@
#include <net/net_namespace.h>
#include <net/sock.h>
#include <rdma/rdma_netlink.h>
+#include <linux/module.h>
#include "core_priv.h"
-struct ibnl_client {
- struct list_head list;
- int index;
- int nops;
- const struct ibnl_client_cbs *cb_table;
-};
+#include "core_priv.h"
-static DEFINE_MUTEX(ibnl_mutex);
+static DEFINE_MUTEX(rdma_nl_mutex);
static struct sock *nls;
-static LIST_HEAD(client_list);
+static struct {
+ const struct rdma_nl_cbs *cb_table;
+} rdma_nl_types[RDMA_NL_NUM_CLIENTS];
-int ibnl_chk_listeners(unsigned int group)
+int rdma_nl_chk_listeners(unsigned int group)
{
- if (netlink_has_listeners(nls, group) == 0)
- return -1;
- return 0;
+ return (netlink_has_listeners(nls, group)) ? 0 : -1;
}
+EXPORT_SYMBOL(rdma_nl_chk_listeners);
-int ibnl_add_client(int index, int nops,
- const struct ibnl_client_cbs cb_table[])
+static bool is_nl_msg_valid(unsigned int type, unsigned int op)
{
- struct ibnl_client *cur;
- struct ibnl_client *nl_client;
+ static const unsigned int max_num_ops[RDMA_NL_NUM_CLIENTS - 1] = {
+ RDMA_NL_RDMA_CM_NUM_OPS,
+ RDMA_NL_IWPM_NUM_OPS,
+ 0,
+ RDMA_NL_LS_NUM_OPS,
+ RDMA_NLDEV_NUM_OPS };
- nl_client = kmalloc(sizeof *nl_client, GFP_KERNEL);
- if (!nl_client)
- return -ENOMEM;
+ /*
+ * This BUILD_BUG_ON is intended to catch addition of new
+ * RDMA netlink protocol without updating the array above.
+ */
+ BUILD_BUG_ON(RDMA_NL_NUM_CLIENTS != 6);
- nl_client->index = index;
- nl_client->nops = nops;
- nl_client->cb_table = cb_table;
+ if (type > RDMA_NL_NUM_CLIENTS - 1)
+ return false;
- mutex_lock(&ibnl_mutex);
+ return (op < max_num_ops[type - 1]) ? true : false;
+}
- list_for_each_entry(cur, &client_list, list) {
- if (cur->index == index) {
- pr_warn("Client for %d already exists\n", index);
- mutex_unlock(&ibnl_mutex);
- kfree(nl_client);
- return -EINVAL;
- }
+static bool is_nl_valid(unsigned int type, unsigned int op)
+{
+ const struct rdma_nl_cbs *cb_table;
+
+ if (!is_nl_msg_valid(type, op))
+ return false;
+
+ cb_table = rdma_nl_types[type].cb_table;
+#ifdef CONFIG_MODULES
+ if (!cb_table) {
+ mutex_unlock(&rdma_nl_mutex);
+ request_module("rdma-netlink-subsys-%d", type);
+ mutex_lock(&rdma_nl_mutex);
+ cb_table = rdma_nl_types[type].cb_table;
}
+#endif
- list_add_tail(&nl_client->list, &client_list);
-
- mutex_unlock(&ibnl_mutex);
-
- return 0;
+ if (!cb_table || (!cb_table[op].dump && !cb_table[op].doit))
+ return false;
+ return true;
}
-EXPORT_SYMBOL(ibnl_add_client);
-int ibnl_remove_client(int index)
+void rdma_nl_register(unsigned int index,
+ const struct rdma_nl_cbs cb_table[])
{
- struct ibnl_client *cur, *next;
-
- mutex_lock(&ibnl_mutex);
- list_for_each_entry_safe(cur, next, &client_list, list) {
- if (cur->index == index) {
- list_del(&(cur->list));
- mutex_unlock(&ibnl_mutex);
- kfree(cur);
- return 0;
- }
+ mutex_lock(&rdma_nl_mutex);
+ if (!is_nl_msg_valid(index, 0)) {
+ /*
+ * All clients are not interesting in success/failure of
+ * this call. They want to see the print to error log and
+ * continue their initialization. Print warning for them,
+ * because it is programmer's error to be here.
+ */
+ mutex_unlock(&rdma_nl_mutex);
+ WARN(true,
+ "The not-valid %u index was supplied to RDMA netlink\n",
+ index);
+ return;
}
- pr_warn("Can't remove callback for client idx %d. Not found\n", index);
- mutex_unlock(&ibnl_mutex);
- return -EINVAL;
+ if (rdma_nl_types[index].cb_table) {
+ mutex_unlock(&rdma_nl_mutex);
+ WARN(true,
+ "The %u index is already registered in RDMA netlink\n",
+ index);
+ return;
+ }
+
+ rdma_nl_types[index].cb_table = cb_table;
+ mutex_unlock(&rdma_nl_mutex);
+}
+EXPORT_SYMBOL(rdma_nl_register);
+
+void rdma_nl_unregister(unsigned int index)
+{
+ mutex_lock(&rdma_nl_mutex);
+ rdma_nl_types[index].cb_table = NULL;
+ mutex_unlock(&rdma_nl_mutex);
}
-EXPORT_SYMBOL(ibnl_remove_client);
+EXPORT_SYMBOL(rdma_nl_unregister);
void *ibnl_put_msg(struct sk_buff *skb, struct nlmsghdr **nlh, int seq,
int len, int client, int op, int flags)
{
- unsigned char *prev_tail;
-
- prev_tail = skb_tail_pointer(skb);
- *nlh = nlmsg_put(skb, 0, seq, RDMA_NL_GET_TYPE(client, op),
- len, flags);
+ *nlh = nlmsg_put(skb, 0, seq, RDMA_NL_GET_TYPE(client, op), len, flags);
if (!*nlh)
- goto out_nlmsg_trim;
- (*nlh)->nlmsg_len = skb_tail_pointer(skb) - prev_tail;
+ return NULL;
return nlmsg_data(*nlh);
-
-out_nlmsg_trim:
- nlmsg_trim(skb, prev_tail);
- return NULL;
}
EXPORT_SYMBOL(ibnl_put_msg);
int ibnl_put_attr(struct sk_buff *skb, struct nlmsghdr *nlh,
int len, void *data, int type)
{
- unsigned char *prev_tail;
-
- prev_tail = skb_tail_pointer(skb);
- if (nla_put(skb, type, len, data))
- goto nla_put_failure;
- nlh->nlmsg_len += skb_tail_pointer(skb) - prev_tail;
+ if (nla_put(skb, type, len, data)) {
+ nlmsg_cancel(skb, nlh);
+ return -EMSGSIZE;
+ }
return 0;
-
-nla_put_failure:
- nlmsg_trim(skb, prev_tail - nlh->nlmsg_len);
- return -EMSGSIZE;
}
EXPORT_SYMBOL(ibnl_put_attr);
-static int ibnl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
- struct netlink_ext_ack *extack)
+static int rdma_nl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
+ struct netlink_ext_ack *extack)
{
- struct ibnl_client *client;
int type = nlh->nlmsg_type;
- int index = RDMA_NL_GET_CLIENT(type);
+ unsigned int index = RDMA_NL_GET_CLIENT(type);
unsigned int op = RDMA_NL_GET_OP(type);
+ const struct rdma_nl_cbs *cb_table;
+
+ if (!is_nl_valid(index, op))
+ return -EINVAL;
+
+ cb_table = rdma_nl_types[index].cb_table;
- list_for_each_entry(client, &client_list, list) {
- if (client->index == index) {
- if (op >= client->nops || !client->cb_table[op].dump)
- return -EINVAL;
-
- /*
- * For response or local service set_timeout request,
- * there is no need to use netlink_dump_start.
- */
- if (!(nlh->nlmsg_flags & NLM_F_REQUEST) ||
- (index == RDMA_NL_LS &&
- op == RDMA_NL_LS_OP_SET_TIMEOUT)) {
- struct netlink_callback cb = {
- .skb = skb,
- .nlh = nlh,
- .dump = client->cb_table[op].dump,
- .module = client->cb_table[op].module,
- };
-
- return cb.dump(skb, &cb);
- }
-
- {
- struct netlink_dump_control c = {
- .dump = client->cb_table[op].dump,
- .module = client->cb_table[op].module,
- };
- return netlink_dump_start(nls, skb, nlh, &c);
- }
- }
+ if ((cb_table[op].flags & RDMA_NL_ADMIN_PERM) &&
+ !netlink_capable(skb, CAP_NET_ADMIN))
+ return -EPERM;
+
+ /* FIXME: Convert IWCM to properly handle doit callbacks */
+ if ((nlh->nlmsg_flags & NLM_F_DUMP) || index == RDMA_NL_RDMA_CM ||
+ index == RDMA_NL_IWCM) {
+ struct netlink_dump_control c = {
+ .dump = cb_table[op].dump,
+ };
+ return netlink_dump_start(nls, skb, nlh, &c);
}
- pr_info("Index %d wasn't found in client list\n", index);
- return -EINVAL;
+ if (cb_table[op].doit)
+ return cb_table[op].doit(skb, nlh, extack);
+
+ return 0;
}
-static void ibnl_rcv_reply_skb(struct sk_buff *skb)
+/*
+ * This function is similar to netlink_rcv_skb with one exception:
+ * It calls to the callback for the netlink messages without NLM_F_REQUEST
+ * flag. These messages are intended for RDMA_NL_LS consumer, so it is allowed
+ * for that consumer only.
+ */
+static int rdma_nl_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *,
+ struct nlmsghdr *,
+ struct netlink_ext_ack *))
{
+ struct netlink_ext_ack extack = {};
struct nlmsghdr *nlh;
- int msglen;
+ int err;
- /*
- * Process responses until there is no more message or the first
- * request. Generally speaking, it is not recommended to mix responses
- * with requests.
- */
while (skb->len >= nlmsg_total_size(0)) {
+ int msglen;
+
nlh = nlmsg_hdr(skb);
+ err = 0;
if (nlh->nlmsg_len < NLMSG_HDRLEN || skb->len < nlh->nlmsg_len)
- return;
-
- /* Handle response only */
- if (nlh->nlmsg_flags & NLM_F_REQUEST)
- return;
-
- ibnl_rcv_msg(skb, nlh, NULL);
+ return 0;
+ /*
+ * Generally speaking, the only requests are handled
+ * by the kernel, but RDMA_NL_LS is different, because it
+ * runs backward netlink scheme. Kernel initiates messages
+ * and waits for reply with data to keep pathrecord cache
+ * in sync.
+ */
+ if (!(nlh->nlmsg_flags & NLM_F_REQUEST) &&
+ (RDMA_NL_GET_CLIENT(nlh->nlmsg_type) != RDMA_NL_LS))
+ goto ack;
+
+ /* Skip control messages */
+ if (nlh->nlmsg_type < NLMSG_MIN_TYPE)
+ goto ack;
+
+ err = cb(skb, nlh, &extack);
+ if (err == -EINTR)
+ goto skip;
+
+ack:
+ if (nlh->nlmsg_flags & NLM_F_ACK || err)
+ netlink_ack(skb, nlh, err, &extack);
+
+skip:
msglen = NLMSG_ALIGN(nlh->nlmsg_len);
if (msglen > skb->len)
msglen = skb->len;
skb_pull(skb, msglen);
}
+
+ return 0;
}
-static void ibnl_rcv(struct sk_buff *skb)
+static void rdma_nl_rcv(struct sk_buff *skb)
{
- mutex_lock(&ibnl_mutex);
- ibnl_rcv_reply_skb(skb);
- netlink_rcv_skb(skb, &ibnl_rcv_msg);
- mutex_unlock(&ibnl_mutex);
+ mutex_lock(&rdma_nl_mutex);
+ rdma_nl_rcv_skb(skb, &rdma_nl_rcv_msg);
+ mutex_unlock(&rdma_nl_mutex);
}
-int ibnl_unicast(struct sk_buff *skb, struct nlmsghdr *nlh,
- __u32 pid)
+int rdma_nl_unicast(struct sk_buff *skb, u32 pid)
+{
+ int err;
+
+ err = netlink_unicast(nls, skb, pid, MSG_DONTWAIT);
+ return (err < 0) ? err : 0;
+}
+EXPORT_SYMBOL(rdma_nl_unicast);
+
+int rdma_nl_unicast_wait(struct sk_buff *skb, __u32 pid)
{
int err;
err = netlink_unicast(nls, skb, pid, 0);
return (err < 0) ? err : 0;
}
-EXPORT_SYMBOL(ibnl_unicast);
+EXPORT_SYMBOL(rdma_nl_unicast_wait);
-int ibnl_multicast(struct sk_buff *skb, struct nlmsghdr *nlh,
- unsigned int group, gfp_t flags)
+int rdma_nl_multicast(struct sk_buff *skb, unsigned int group, gfp_t flags)
{
return nlmsg_multicast(nls, skb, 0, group, flags);
}
-EXPORT_SYMBOL(ibnl_multicast);
+EXPORT_SYMBOL(rdma_nl_multicast);
-int __init ibnl_init(void)
+int __init rdma_nl_init(void)
{
struct netlink_kernel_cfg cfg = {
- .input = ibnl_rcv,
+ .input = rdma_nl_rcv,
};
nls = netlink_kernel_create(&init_net, NETLINK_RDMA, &cfg);
- if (!nls) {
- pr_warn("Failed to create netlink socket\n");
+ if (!nls)
return -ENOMEM;
- }
nls->sk_sndtimeo = 10 * HZ;
return 0;
}
-void ibnl_cleanup(void)
+void rdma_nl_exit(void)
{
- struct ibnl_client *cur, *next;
+ int idx;
- mutex_lock(&ibnl_mutex);
- list_for_each_entry_safe(cur, next, &client_list, list) {
- list_del(&(cur->list));
- kfree(cur);
- }
- mutex_unlock(&ibnl_mutex);
+ for (idx = 0; idx < RDMA_NL_NUM_CLIENTS; idx++)
+ rdma_nl_unregister(idx);
netlink_kernel_release(nls);
}
+
+MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_RDMA);
diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c
new file mode 100644
index 0000000..3ba24c4
--- /dev/null
+++ b/drivers/infiniband/core/nldev.c
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the names of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * 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 <linux/module.h>
+#include <net/netlink.h>
+#include <rdma/rdma_netlink.h>
+
+#include "core_priv.h"
+
+static const struct nla_policy nldev_policy[RDMA_NLDEV_ATTR_MAX] = {
+ [RDMA_NLDEV_ATTR_DEV_INDEX] = { .type = NLA_U32 },
+ [RDMA_NLDEV_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING,
+ .len = IB_DEVICE_NAME_MAX - 1},
+ [RDMA_NLDEV_ATTR_PORT_INDEX] = { .type = NLA_U32 },
+ [RDMA_NLDEV_ATTR_FW_VERSION] = { .type = NLA_NUL_STRING,
+ .len = IB_FW_VERSION_NAME_MAX - 1},
+ [RDMA_NLDEV_ATTR_NODE_GUID] = { .type = NLA_U64 },
+ [RDMA_NLDEV_ATTR_SYS_IMAGE_GUID] = { .type = NLA_U64 },
+ [RDMA_NLDEV_ATTR_SUBNET_PREFIX] = { .type = NLA_U64 },
+ [RDMA_NLDEV_ATTR_LID] = { .type = NLA_U32 },
+ [RDMA_NLDEV_ATTR_SM_LID] = { .type = NLA_U32 },
+ [RDMA_NLDEV_ATTR_LMC] = { .type = NLA_U8 },
+ [RDMA_NLDEV_ATTR_PORT_STATE] = { .type = NLA_U8 },
+ [RDMA_NLDEV_ATTR_PORT_PHYS_STATE] = { .type = NLA_U8 },
+ [RDMA_NLDEV_ATTR_DEV_NODE_TYPE] = { .type = NLA_U8 },
+};
+
+static int fill_dev_info(struct sk_buff *msg, struct ib_device *device)
+{
+ char fw[IB_FW_VERSION_NAME_MAX];
+
+ if (nla_put_u32(msg, RDMA_NLDEV_ATTR_DEV_INDEX, device->index))
+ return -EMSGSIZE;
+ if (nla_put_string(msg, RDMA_NLDEV_ATTR_DEV_NAME, device->name))
+ return -EMSGSIZE;
+ if (nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, rdma_end_port(device)))
+ return -EMSGSIZE;
+
+ BUILD_BUG_ON(sizeof(device->attrs.device_cap_flags) != sizeof(u64));
+ if (nla_put_u64_64bit(msg, RDMA_NLDEV_ATTR_CAP_FLAGS,
+ device->attrs.device_cap_flags, 0))
+ return -EMSGSIZE;
+
+ ib_get_device_fw_str(device, fw);
+ /* Device without FW has strlen(fw) */
+ if (strlen(fw) && nla_put_string(msg, RDMA_NLDEV_ATTR_FW_VERSION, fw))
+ return -EMSGSIZE;
+
+ if (nla_put_u64_64bit(msg, RDMA_NLDEV_ATTR_NODE_GUID,
+ be64_to_cpu(device->node_guid), 0))
+ return -EMSGSIZE;
+ if (nla_put_u64_64bit(msg, RDMA_NLDEV_ATTR_SYS_IMAGE_GUID,
+ be64_to_cpu(device->attrs.sys_image_guid), 0))
+ return -EMSGSIZE;
+ if (nla_put_u8(msg, RDMA_NLDEV_ATTR_DEV_NODE_TYPE, device->node_type))
+ return -EMSGSIZE;
+ return 0;
+}
+
+static int fill_port_info(struct sk_buff *msg,
+ struct ib_device *device, u32 port)
+{
+ struct ib_port_attr attr;
+ int ret;
+
+ if (nla_put_u32(msg, RDMA_NLDEV_ATTR_DEV_INDEX, device->index))
+ return -EMSGSIZE;
+ if (nla_put_string(msg, RDMA_NLDEV_ATTR_DEV_NAME, device->name))
+ return -EMSGSIZE;
+ if (nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, port))
+ return -EMSGSIZE;
+
+ ret = ib_query_port(device, port, &attr);
+ if (ret)
+ return ret;
+
+ BUILD_BUG_ON(sizeof(attr.port_cap_flags) > sizeof(u64));
+ if (nla_put_u64_64bit(msg, RDMA_NLDEV_ATTR_CAP_FLAGS,
+ (u64)attr.port_cap_flags, 0))
+ return -EMSGSIZE;
+ if (rdma_protocol_ib(device, port) &&
+ nla_put_u64_64bit(msg, RDMA_NLDEV_ATTR_SUBNET_PREFIX,
+ attr.subnet_prefix, 0))
+ return -EMSGSIZE;
+ if (rdma_protocol_ib(device, port)) {
+ if (nla_put_u32(msg, RDMA_NLDEV_ATTR_LID, attr.lid))
+ return -EMSGSIZE;
+ if (nla_put_u32(msg, RDMA_NLDEV_ATTR_SM_LID, attr.sm_lid))
+ return -EMSGSIZE;
+ if (nla_put_u8(msg, RDMA_NLDEV_ATTR_LMC, attr.lmc))
+ return -EMSGSIZE;
+ }
+ if (nla_put_u8(msg, RDMA_NLDEV_ATTR_PORT_STATE, attr.state))
+ return -EMSGSIZE;
+ if (nla_put_u8(msg, RDMA_NLDEV_ATTR_PORT_PHYS_STATE, attr.phys_state))
+ return -EMSGSIZE;
+ return 0;
+}
+
+static int nldev_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
+ struct netlink_ext_ack *extack)
+{
+ struct nlattr *tb[RDMA_NLDEV_ATTR_MAX];
+ struct ib_device *device;
+ struct sk_buff *msg;
+ u32 index;
+ int err;
+
+ err = nlmsg_parse(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
+ nldev_policy, extack);
+ if (err || !tb[RDMA_NLDEV_ATTR_DEV_INDEX])
+ return -EINVAL;
+
+ index = nla_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
+
+ device = __ib_device_get_by_index(index);
+ if (!device)
+ return -EINVAL;
+
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
+
+ nlh = nlmsg_put(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq,
+ RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_GET),
+ 0, 0);
+
+ err = fill_dev_info(msg, device);
+ if (err) {
+ nlmsg_free(msg);
+ return err;
+ }
+
+ nlmsg_end(msg, nlh);
+
+ return rdma_nl_unicast(msg, NETLINK_CB(skb).portid);
+}
+
+static int _nldev_get_dumpit(struct ib_device *device,
+ struct sk_buff *skb,
+ struct netlink_callback *cb,
+ unsigned int idx)
+{
+ int start = cb->args[0];
+ struct nlmsghdr *nlh;
+
+ if (idx < start)
+ return 0;
+
+ nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
+ RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_GET),
+ 0, NLM_F_MULTI);
+
+ if (fill_dev_info(skb, device)) {
+ nlmsg_cancel(skb, nlh);
+ goto out;
+ }
+
+ nlmsg_end(skb, nlh);
+
+ idx++;
+
+out: cb->args[0] = idx;
+ return skb->len;
+}
+
+static int nldev_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
+{
+ /*
+ * There is no need to take lock, because
+ * we are relying on ib_core's lists_rwsem
+ */
+ return ib_enum_all_devs(_nldev_get_dumpit, skb, cb);
+}
+
+static int nldev_port_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
+ struct netlink_ext_ack *extack)
+{
+ struct nlattr *tb[RDMA_NLDEV_ATTR_MAX];
+ struct ib_device *device;
+ struct sk_buff *msg;
+ u32 index;
+ u32 port;
+ int err;
+
+ err = nlmsg_parse(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
+ nldev_policy, extack);
+ if (err || !tb[RDMA_NLDEV_ATTR_PORT_INDEX])
+ return -EINVAL;
+
+ index = nla_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
+ device = __ib_device_get_by_index(index);
+ if (!device)
+ return -EINVAL;
+
+ port = nla_get_u32(tb[RDMA_NLDEV_ATTR_PORT_INDEX]);
+ if (!rdma_is_port_valid(device, port))
+ return -EINVAL;
+
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
+
+ nlh = nlmsg_put(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq,
+ RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_GET),
+ 0, 0);
+
+ err = fill_port_info(msg, device, port);
+ if (err) {
+ nlmsg_free(msg);
+ return err;
+ }
+
+ nlmsg_end(msg, nlh);
+
+ return rdma_nl_unicast(msg, NETLINK_CB(skb).portid);
+}
+
+static int nldev_port_get_dumpit(struct sk_buff *skb,
+ struct netlink_callback *cb)
+{
+ struct nlattr *tb[RDMA_NLDEV_ATTR_MAX];
+ struct ib_device *device;
+ int start = cb->args[0];
+ struct nlmsghdr *nlh;
+ u32 idx = 0;
+ u32 ifindex;
+ int err;
+ u32 p;
+
+ err = nlmsg_parse(cb->nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
+ nldev_policy, NULL);
+ if (err || !tb[RDMA_NLDEV_ATTR_DEV_INDEX])
+ return -EINVAL;
+
+ ifindex = nla_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
+ device = __ib_device_get_by_index(ifindex);
+ if (!device)
+ return -EINVAL;
+
+ for (p = rdma_start_port(device); p <= rdma_end_port(device); ++p) {
+ /*
+ * The dumpit function returns all information from specific
+ * index. This specific index is taken from the netlink
+ * messages request sent by user and it is available
+ * in cb->args[0].
+ *
+ * Usually, the user doesn't fill this field and it causes
+ * to return everything.
+ *
+ */
+ if (idx < start) {
+ idx++;
+ continue;
+ }
+
+ nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid,
+ cb->nlh->nlmsg_seq,
+ RDMA_NL_GET_TYPE(RDMA_NL_NLDEV,
+ RDMA_NLDEV_CMD_PORT_GET),
+ 0, NLM_F_MULTI);
+
+ if (fill_port_info(skb, device, p)) {
+ nlmsg_cancel(skb, nlh);
+ goto out;
+ }
+ idx++;
+ nlmsg_end(skb, nlh);
+ }
+
+out: cb->args[0] = idx;
+ return skb->len;
+}
+
+static const struct rdma_nl_cbs nldev_cb_table[] = {
+ [RDMA_NLDEV_CMD_GET] = {
+ .doit = nldev_get_doit,
+ .dump = nldev_get_dumpit,
+ },
+ [RDMA_NLDEV_CMD_PORT_GET] = {
+ .doit = nldev_port_get_doit,
+ .dump = nldev_port_get_dumpit,
+ },
+};
+
+void __init nldev_init(void)
+{
+ rdma_nl_register(RDMA_NL_NLDEV, nldev_cb_table);
+}
+
+void __exit nldev_exit(void)
+{
+ rdma_nl_unregister(RDMA_NL_NLDEV);
+}
+
+MODULE_ALIAS_RDMA_NETLINK(RDMA_NL_NLDEV, 5);
diff --git a/drivers/infiniband/core/rdma_core.c b/drivers/infiniband/core/rdma_core.c
index 41c31a2..85b5ee4 100644
--- a/drivers/infiniband/core/rdma_core.c
+++ b/drivers/infiniband/core/rdma_core.c
@@ -35,10 +35,57 @@
#include <rdma/ib_verbs.h>
#include <rdma/uverbs_types.h>
#include <linux/rcupdate.h>
+#include <rdma/uverbs_ioctl.h>
+#include <rdma/rdma_user_ioctl.h>
#include "uverbs.h"
#include "core_priv.h"
#include "rdma_core.h"
+int uverbs_ns_idx(u16 *id, unsigned int ns_count)
+{
+ int ret = (*id & UVERBS_ID_NS_MASK) >> UVERBS_ID_NS_SHIFT;
+
+ if (ret >= ns_count)
+ return -EINVAL;
+
+ *id &= ~UVERBS_ID_NS_MASK;
+ return ret;
+}
+
+const struct uverbs_object_spec *uverbs_get_object(const struct ib_device *ibdev,
+ uint16_t object)
+{
+ const struct uverbs_root_spec *object_hash = ibdev->specs_root;
+ const struct uverbs_object_spec_hash *objects;
+ int ret = uverbs_ns_idx(&object, object_hash->num_buckets);
+
+ if (ret < 0)
+ return NULL;
+
+ objects = object_hash->object_buckets[ret];
+
+ if (object >= objects->num_objects)
+ return NULL;
+
+ return objects->objects[object];
+}
+
+const struct uverbs_method_spec *uverbs_get_method(const struct uverbs_object_spec *object,
+ uint16_t method)
+{
+ const struct uverbs_method_spec_hash *methods;
+ int ret = uverbs_ns_idx(&method, object->num_buckets);
+
+ if (ret < 0)
+ return NULL;
+
+ methods = object->method_buckets[ret];
+ if (method >= methods->num_methods)
+ return NULL;
+
+ return methods->methods[method];
+}
+
void uverbs_uobject_get(struct ib_uobject *uobject)
{
kref_get(&uobject->ref);
@@ -404,6 +451,41 @@ int __must_check rdma_remove_commit_uobject(struct ib_uobject *uobj)
return ret;
}
+static int null_obj_type_class_remove_commit(struct ib_uobject *uobj,
+ enum rdma_remove_reason why)
+{
+ return 0;
+}
+
+static const struct uverbs_obj_type null_obj_type = {
+ .type_class = &((const struct uverbs_obj_type_class){
+ .remove_commit = null_obj_type_class_remove_commit,
+ /* be cautious */
+ .needs_kfree_rcu = true}),
+};
+
+int rdma_explicit_destroy(struct ib_uobject *uobject)
+{
+ int ret;
+ struct ib_ucontext *ucontext = uobject->context;
+
+ /* Cleanup is running. Calling this should have been impossible */
+ if (!down_read_trylock(&ucontext->cleanup_rwsem)) {
+ WARN(true, "ib_uverbs: Cleanup is running while removing an uobject\n");
+ return 0;
+ }
+ lockdep_check(uobject, true);
+ ret = uobject->type->type_class->remove_commit(uobject,
+ RDMA_REMOVE_DESTROY);
+ if (ret)
+ return ret;
+
+ uobject->type = &null_obj_type;
+
+ up_read(&ucontext->cleanup_rwsem);
+ return 0;
+}
+
static void alloc_commit_idr_uobject(struct ib_uobject *uobj)
{
uverbs_uobject_add(uobj);
@@ -625,3 +707,100 @@ const struct uverbs_obj_type_class uverbs_fd_class = {
.needs_kfree_rcu = false,
};
+struct ib_uobject *uverbs_get_uobject_from_context(const struct uverbs_obj_type *type_attrs,
+ struct ib_ucontext *ucontext,
+ enum uverbs_obj_access access,
+ int id)
+{
+ switch (access) {
+ case UVERBS_ACCESS_READ:
+ return rdma_lookup_get_uobject(type_attrs, ucontext, id, false);
+ case UVERBS_ACCESS_DESTROY:
+ case UVERBS_ACCESS_WRITE:
+ return rdma_lookup_get_uobject(type_attrs, ucontext, id, true);
+ case UVERBS_ACCESS_NEW:
+ return rdma_alloc_begin_uobject(type_attrs, ucontext);
+ default:
+ WARN_ON(true);
+ return ERR_PTR(-EOPNOTSUPP);
+ }
+}
+
+int uverbs_finalize_object(struct ib_uobject *uobj,
+ enum uverbs_obj_access access,
+ bool commit)
+{
+ int ret = 0;
+
+ /*
+ * refcounts should be handled at the object level and not at the
+ * uobject level. Refcounts of the objects themselves are done in
+ * handlers.
+ */
+
+ switch (access) {
+ case UVERBS_ACCESS_READ:
+ rdma_lookup_put_uobject(uobj, false);
+ break;
+ case UVERBS_ACCESS_WRITE:
+ rdma_lookup_put_uobject(uobj, true);
+ break;
+ case UVERBS_ACCESS_DESTROY:
+ if (commit)
+ ret = rdma_remove_commit_uobject(uobj);
+ else
+ rdma_lookup_put_uobject(uobj, true);
+ break;
+ case UVERBS_ACCESS_NEW:
+ if (commit)
+ ret = rdma_alloc_commit_uobject(uobj);
+ else
+ rdma_alloc_abort_uobject(uobj);
+ break;
+ default:
+ WARN_ON(true);
+ ret = -EOPNOTSUPP;
+ }
+
+ return ret;
+}
+
+int uverbs_finalize_objects(struct uverbs_attr_bundle *attrs_bundle,
+ struct uverbs_attr_spec_hash * const *spec_hash,
+ size_t num,
+ bool commit)
+{
+ unsigned int i;
+ int ret = 0;
+
+ for (i = 0; i < num; i++) {
+ struct uverbs_attr_bundle_hash *curr_bundle =
+ &attrs_bundle->hash[i];
+ const struct uverbs_attr_spec_hash *curr_spec_bucket =
+ spec_hash[i];
+ unsigned int j;
+
+ for (j = 0; j < curr_bundle->num_attrs; j++) {
+ struct uverbs_attr *attr;
+ const struct uverbs_attr_spec *spec;
+
+ if (!uverbs_attr_is_valid_in_hash(curr_bundle, j))
+ continue;
+
+ attr = &curr_bundle->attrs[j];
+ spec = &curr_spec_bucket->attrs[j];
+
+ if (spec->type == UVERBS_ATTR_TYPE_IDR ||
+ spec->type == UVERBS_ATTR_TYPE_FD) {
+ int current_ret;
+
+ current_ret = uverbs_finalize_object(attr->obj_attr.uobject,
+ spec->obj.access,
+ commit);
+ if (!ret)
+ ret = current_ret;
+ }
+ }
+ }
+ return ret;
+}
diff --git a/drivers/infiniband/core/rdma_core.h b/drivers/infiniband/core/rdma_core.h
index 1b82e7f..1efcf93 100644
--- a/drivers/infiniband/core/rdma_core.h
+++ b/drivers/infiniband/core/rdma_core.h
@@ -39,9 +39,15 @@
#include <linux/idr.h>
#include <rdma/uverbs_types.h>
+#include <rdma/uverbs_ioctl.h>
#include <rdma/ib_verbs.h>
#include <linux/mutex.h>
+int uverbs_ns_idx(u16 *id, unsigned int ns_count);
+const struct uverbs_object_spec *uverbs_get_object(const struct ib_device *ibdev,
+ uint16_t object);
+const struct uverbs_method_spec *uverbs_get_method(const struct uverbs_object_spec *object,
+ uint16_t method);
/*
* These functions initialize the context and cleanups its uobjects.
* The context has a list of objects which is protected by a mutex
@@ -75,4 +81,40 @@ void uverbs_uobject_put(struct ib_uobject *uobject);
*/
void uverbs_close_fd(struct file *f);
+/*
+ * Get an ib_uobject that corresponds to the given id from ucontext, assuming
+ * the object is from the given type. Lock it to the required access when
+ * applicable.
+ * This function could create (access == NEW), destroy (access == DESTROY)
+ * or unlock (access == READ || access == WRITE) objects if required.
+ * The action will be finalized only when uverbs_finalize_object or
+ * uverbs_finalize_objects are called.
+ */
+struct ib_uobject *uverbs_get_uobject_from_context(const struct uverbs_obj_type *type_attrs,
+ struct ib_ucontext *ucontext,
+ enum uverbs_obj_access access,
+ int id);
+int uverbs_finalize_object(struct ib_uobject *uobj,
+ enum uverbs_obj_access access,
+ bool commit);
+/*
+ * Note that certain finalize stages could return a status:
+ * (a) alloc_commit could return a failure if the object is committed at the
+ * same time when the context is destroyed.
+ * (b) remove_commit could fail if the object wasn't destroyed successfully.
+ * Since multiple objects could be finalized in one transaction, it is very NOT
+ * recommended to have several finalize actions which have side effects.
+ * For example, it's NOT recommended to have a certain action which has both
+ * a commit action and a destroy action or two destroy objects in the same
+ * action. The rule of thumb is to have one destroy or commit action with
+ * multiple lookups.
+ * The first non zero return value of finalize_object is returned from this
+ * function. For example, this could happen when we couldn't destroy an
+ * object.
+ */
+int uverbs_finalize_objects(struct uverbs_attr_bundle *attrs_bundle,
+ struct uverbs_attr_spec_hash * const *spec_hash,
+ size_t num,
+ bool commit);
+
#endif /* RDMA_CORE_H */
diff --git a/drivers/infiniband/core/roce_gid_mgmt.c b/drivers/infiniband/core/roce_gid_mgmt.c
index 94a9eef..90e3889 100644
--- a/drivers/infiniband/core/roce_gid_mgmt.c
+++ b/drivers/infiniband/core/roce_gid_mgmt.c
@@ -44,6 +44,8 @@
static struct workqueue_struct *gid_cache_wq;
+static struct workqueue_struct *gid_cache_wq;
+
enum gid_op_type {
GID_DEL = 0,
GID_ADD
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index 70fa4ca..ab5e102 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -50,6 +50,7 @@
#include <uapi/rdma/ib_user_sa.h>
#include <rdma/ib_marshall.h>
#include <rdma/ib_addr.h>
+#include <rdma/opa_addr.h>
#include "sa.h"
#include "core_priv.h"
@@ -861,7 +862,7 @@ static int ib_nl_send_msg(struct ib_sa_query *query, gfp_t gfp_mask)
/* Repair the nlmsg header length */
nlmsg_end(skb, nlh);
- ret = ibnl_multicast(skb, nlh, RDMA_NL_GROUP_LS, gfp_mask);
+ ret = rdma_nl_multicast(skb, RDMA_NL_GROUP_LS, gfp_mask);
if (!ret)
ret = len;
else
@@ -1021,9 +1022,9 @@ static void ib_nl_request_timeout(struct work_struct *work)
}
int ib_nl_handle_set_timeout(struct sk_buff *skb,
- struct netlink_callback *cb)
+ struct nlmsghdr *nlh,
+ struct netlink_ext_ack *extack)
{
- const struct nlmsghdr *nlh = (struct nlmsghdr *)cb->nlh;
int timeout, delta, abs_delta;
const struct nlattr *attr;
unsigned long flags;
@@ -1033,8 +1034,7 @@ int ib_nl_handle_set_timeout(struct sk_buff *skb,
int ret;
if (!(nlh->nlmsg_flags & NLM_F_REQUEST) ||
- !(NETLINK_CB(skb).sk) ||
- !netlink_capable(skb, CAP_NET_ADMIN))
+ !(NETLINK_CB(skb).sk))
return -EPERM;
ret = nla_parse(tb, LS_NLA_TYPE_MAX - 1, nlmsg_data(nlh),
@@ -1098,9 +1098,9 @@ static inline int ib_nl_is_good_resolve_resp(const struct nlmsghdr *nlh)
}
int ib_nl_handle_resolve_resp(struct sk_buff *skb,
- struct netlink_callback *cb)
+ struct nlmsghdr *nlh,
+ struct netlink_ext_ack *extack)
{
- const struct nlmsghdr *nlh = (struct nlmsghdr *)cb->nlh;
unsigned long flags;
struct ib_sa_query *query;
struct ib_mad_send_buf *send_buf;
@@ -1109,8 +1109,7 @@ int ib_nl_handle_resolve_resp(struct sk_buff *skb,
int ret;
if ((nlh->nlmsg_flags & NLM_F_REQUEST) ||
- !(NETLINK_CB(skb).sk) ||
- !netlink_capable(skb, CAP_NET_ADMIN))
+ !(NETLINK_CB(skb).sk))
return -EPERM;
spin_lock_irqsave(&ib_nl_request_lock, flags);
@@ -1241,6 +1240,11 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
ah_attr->type = rdma_ah_find_type(device, port_num);
rdma_ah_set_dlid(ah_attr, be32_to_cpu(sa_path_get_dlid(rec)));
+
+ if ((ah_attr->type == RDMA_AH_ATTR_TYPE_OPA) &&
+ (rdma_ah_get_dlid(ah_attr) == be16_to_cpu(IB_LID_PERMISSIVE)))
+ rdma_ah_set_make_grd(ah_attr, true);
+
rdma_ah_set_sl(ah_attr, rec->sl);
rdma_ah_set_path_bits(ah_attr, be32_to_cpu(sa_path_get_slid(rec)) &
get_src_path_mask(device, port_num));
@@ -1420,7 +1424,7 @@ static int send_mad(struct ib_sa_query *query, int timeout_ms, gfp_t gfp_mask)
if ((query->flags & IB_SA_ENABLE_LOCAL_SERVICE) &&
(!(query->flags & IB_SA_QUERY_OPA))) {
- if (!ibnl_chk_listeners(RDMA_NL_GROUP_LS)) {
+ if (!rdma_nl_chk_listeners(RDMA_NL_GROUP_LS)) {
if (!ib_nl_make_request(query, gfp_mask))
return id;
}
@@ -2290,12 +2294,15 @@ static void update_sm_ah(struct work_struct *work)
rdma_ah_set_sl(&ah_attr, port_attr.sm_sl);
rdma_ah_set_port_num(&ah_attr, port->port_num);
if (port_attr.grh_required) {
- rdma_ah_set_ah_flags(&ah_attr, IB_AH_GRH);
-
- rdma_ah_set_subnet_prefix(&ah_attr,
- cpu_to_be64(port_attr.subnet_prefix));
- rdma_ah_set_interface_id(&ah_attr,
- cpu_to_be64(IB_SA_WELL_KNOWN_GUID));
+ if (ah_attr.type == RDMA_AH_ATTR_TYPE_OPA) {
+ rdma_ah_set_make_grd(&ah_attr, true);
+ } else {
+ rdma_ah_set_ah_flags(&ah_attr, IB_AH_GRH);
+ rdma_ah_set_subnet_prefix(&ah_attr,
+ cpu_to_be64(port_attr.subnet_prefix));
+ rdma_ah_set_interface_id(&ah_attr,
+ cpu_to_be64(IB_SA_WELL_KNOWN_GUID));
+ }
}
new_ah->ah = rdma_create_ah(port->agent->qp->pd, &ah_attr);
@@ -2410,8 +2417,7 @@ static void ib_sa_add_one(struct ib_device *device)
*/
INIT_IB_EVENT_HANDLER(&sa_dev->event_handler, device, ib_sa_event);
- if (ib_register_event_handler(&sa_dev->event_handler))
- goto err;
+ ib_register_event_handler(&sa_dev->event_handler);
for (i = 0; i <= e - s; ++i) {
if (rdma_cap_ib_sa(device, i + 1))
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index 7ebe1ef..abc5ab5 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -1210,8 +1210,8 @@ static ssize_t show_fw_ver(struct device *device, struct device_attribute *attr,
{
struct ib_device *dev = container_of(device, struct ib_device, dev);
- ib_get_device_fw_str(dev, buf, PAGE_SIZE);
- strlcat(buf, "\n", PAGE_SIZE);
+ ib_get_device_fw_str(dev, buf);
+ strlcat(buf, "\n", IB_FW_VERSION_NAME_MAX);
return strlen(buf);
}
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c
index 112099c..f2a7f62 100644
--- a/drivers/infiniband/core/ucm.c
+++ b/drivers/infiniband/core/ucm.c
@@ -618,7 +618,7 @@ static ssize_t ib_ucm_init_qp_attr(struct ib_ucm_file *file,
if (result)
goto out;
- ib_copy_qp_attr_to_user(&resp, &qp_attr);
+ ib_copy_qp_attr_to_user(ctx->cm_id->device, &resp, &qp_attr);
if (copy_to_user((void __user *)(unsigned long)cmd.response,
&resp, sizeof(resp)))
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index 276f0ef..eb85b54 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -248,14 +248,15 @@ static void ucma_copy_conn_event(struct rdma_ucm_conn_param *dst,
dst->qp_num = src->qp_num;
}
-static void ucma_copy_ud_event(struct rdma_ucm_ud_param *dst,
+static void ucma_copy_ud_event(struct ib_device *device,
+ struct rdma_ucm_ud_param *dst,
struct rdma_ud_param *src)
{
if (src->private_data_len)
memcpy(dst->private_data, src->private_data,
src->private_data_len);
dst->private_data_len = src->private_data_len;
- ib_copy_ah_attr_to_user(&dst->ah_attr, &src->ah_attr);
+ ib_copy_ah_attr_to_user(device, &dst->ah_attr, &src->ah_attr);
dst->qp_num = src->qp_num;
dst->qkey = src->qkey;
}
@@ -335,7 +336,8 @@ static int ucma_event_handler(struct rdma_cm_id *cm_id,
uevent->resp.event = event->event;
uevent->resp.status = event->status;
if (cm_id->qp_type == IB_QPT_UD)
- ucma_copy_ud_event(&uevent->resp.param.ud, &event->param.ud);
+ ucma_copy_ud_event(cm_id->device, &uevent->resp.param.ud,
+ &event->param.ud);
else
ucma_copy_conn_event(&uevent->resp.param.conn,
&event->param.conn);
@@ -1157,7 +1159,7 @@ static ssize_t ucma_init_qp_attr(struct ucma_file *file,
if (ret)
goto out;
- ib_copy_qp_attr_to_user(&resp, &qp_attr);
+ ib_copy_qp_attr_to_user(ctx->cm_id->device, &resp, &qp_attr);
if (copy_to_user((void __user *)(unsigned long)cmd.response,
&resp, sizeof(resp)))
ret = -EFAULT;
diff --git a/drivers/infiniband/core/umem_odp.c b/drivers/infiniband/core/umem_odp.c
index 8c4ec56..55e8f5e 100644
--- a/drivers/infiniband/core/umem_odp.c
+++ b/drivers/infiniband/core/umem_odp.c
@@ -166,24 +166,6 @@ static int invalidate_page_trampoline(struct ib_umem *item, u64 start,
return 0;
}
-static void ib_umem_notifier_invalidate_page(struct mmu_notifier *mn,
- struct mm_struct *mm,
- unsigned long address)
-{
- struct ib_ucontext *context = container_of(mn, struct ib_ucontext, mn);
-
- if (!context->invalidate_range)
- return;
-
- ib_ucontext_notifier_start_account(context);
- down_read(&context->umem_rwsem);
- rbt_ib_umem_for_each_in_range(&context->umem_tree, address,
- address + PAGE_SIZE,
- invalidate_page_trampoline, NULL);
- up_read(&context->umem_rwsem);
- ib_ucontext_notifier_end_account(context);
-}
-
static int invalidate_range_start_trampoline(struct ib_umem *item, u64 start,
u64 end, void *cookie)
{
@@ -237,7 +219,6 @@ static void ib_umem_notifier_invalidate_range_end(struct mmu_notifier *mn,
static const struct mmu_notifier_ops ib_umem_notifiers = {
.release = ib_umem_notifier_release,
- .invalidate_page = ib_umem_notifier_invalidate_page,
.invalidate_range_start = ib_umem_notifier_invalidate_range_start,
.invalidate_range_end = ib_umem_notifier_invalidate_range_end,
};
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
index 36a6f5c..c1696e6 100644
--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -229,7 +229,7 @@ static void recv_handler(struct ib_mad_agent *agent,
packet->mad.hdr.status = 0;
packet->mad.hdr.length = hdr_size(file) + mad_recv_wc->mad_len;
packet->mad.hdr.qpn = cpu_to_be32(mad_recv_wc->wc->src_qp);
- packet->mad.hdr.lid = cpu_to_be16(mad_recv_wc->wc->slid);
+ packet->mad.hdr.lid = ib_lid_be16(mad_recv_wc->wc->slid);
packet->mad.hdr.sl = mad_recv_wc->wc->sl;
packet->mad.hdr.path_bits = mad_recv_wc->wc->dlid_path_bits;
packet->mad.hdr.pkey_index = mad_recv_wc->wc->pkey_index;
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h
index 64d494a..37c8903 100644
--- a/drivers/infiniband/core/uverbs.h
+++ b/drivers/infiniband/core/uverbs.h
@@ -100,6 +100,7 @@ struct ib_uverbs_device {
struct mutex lists_mutex; /* protect lists */
struct list_head uverbs_file_list;
struct list_head uverbs_events_file_list;
+ struct uverbs_root_spec *specs_root;
};
struct ib_uverbs_event_queue {
@@ -218,6 +219,8 @@ int uverbs_dealloc_mw(struct ib_mw *mw);
void ib_uverbs_detach_umcast(struct ib_qp *qp,
struct ib_uqp_object *uobj);
+long ib_uverbs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
+
struct ib_uverbs_flow_spec {
union {
union {
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 739bd69..e0cb9986 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -91,9 +91,10 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
goto err;
}
- INIT_UDATA(&udata, buf + sizeof cmd,
- (unsigned long) cmd.response + sizeof resp,
- in_len - sizeof cmd, out_len - sizeof resp);
+ INIT_UDATA(&udata, buf + sizeof(cmd),
+ (unsigned long) cmd.response + sizeof(resp),
+ in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
+ out_len - sizeof(resp));
ret = ib_rdmacg_try_charge(&cg_obj, ib_dev, RDMACG_RESOURCE_HCA_HANDLE);
if (ret)
@@ -275,8 +276,14 @@ ssize_t ib_uverbs_query_port(struct ib_uverbs_file *file,
resp.bad_pkey_cntr = attr.bad_pkey_cntr;
resp.qkey_viol_cntr = attr.qkey_viol_cntr;
resp.pkey_tbl_len = attr.pkey_tbl_len;
- resp.lid = attr.lid;
- resp.sm_lid = attr.sm_lid;
+
+ if (rdma_cap_opa_ah(ib_dev, cmd.port_num)) {
+ resp.lid = OPA_TO_IB_UCAST_LID(attr.lid);
+ resp.sm_lid = OPA_TO_IB_UCAST_LID(attr.sm_lid);
+ } else {
+ resp.lid = ib_lid_cpu16(attr.lid);
+ resp.sm_lid = ib_lid_cpu16(attr.sm_lid);
+ }
resp.lmc = attr.lmc;
resp.max_vl_num = attr.max_vl_num;
resp.sm_sl = attr.sm_sl;
@@ -313,9 +320,10 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file,
if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT;
- INIT_UDATA(&udata, buf + sizeof cmd,
- (unsigned long) cmd.response + sizeof resp,
- in_len - sizeof cmd, out_len - sizeof resp);
+ INIT_UDATA(&udata, buf + sizeof(cmd),
+ (unsigned long) cmd.response + sizeof(resp),
+ in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
+ out_len - sizeof(resp));
uobj = uobj_alloc(uobj_get_type(pd), file->ucontext);
if (IS_ERR(uobj))
@@ -482,9 +490,10 @@ ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file,
if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT;
- INIT_UDATA(&udata, buf + sizeof cmd,
- (unsigned long) cmd.response + sizeof resp,
- in_len - sizeof cmd, out_len - sizeof resp);
+ INIT_UDATA(&udata, buf + sizeof(cmd),
+ (unsigned long) cmd.response + sizeof(resp),
+ in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
+ out_len - sizeof(resp));
mutex_lock(&file->device->xrcd_tree_mutex);
@@ -646,9 +655,10 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT;
- INIT_UDATA(&udata, buf + sizeof cmd,
- (unsigned long) cmd.response + sizeof resp,
- in_len - sizeof cmd, out_len - sizeof resp);
+ INIT_UDATA(&udata, buf + sizeof(cmd),
+ (unsigned long) cmd.response + sizeof(resp),
+ in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
+ out_len - sizeof(resp));
if ((cmd.start & ~PAGE_MASK) != (cmd.hca_va & ~PAGE_MASK))
return -EINVAL;
@@ -740,7 +750,8 @@ ssize_t ib_uverbs_rereg_mr(struct ib_uverbs_file *file,
INIT_UDATA(&udata, buf + sizeof(cmd),
(unsigned long) cmd.response + sizeof(resp),
- in_len - sizeof(cmd), out_len - sizeof(resp));
+ in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
+ out_len - sizeof(resp));
if (cmd.flags & ~IB_MR_REREG_SUPPORTED || !cmd.flags)
return -EINVAL;
@@ -1080,7 +1091,8 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
INIT_UDATA(&uhw, buf + sizeof(cmd),
(unsigned long)cmd.response + sizeof(resp),
- in_len - sizeof(cmd), out_len - sizeof(resp));
+ in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
+ out_len - sizeof(resp));
memset(&cmd_ex, 0, sizeof(cmd_ex));
cmd_ex.user_handle = cmd.user_handle;
@@ -1161,9 +1173,10 @@ ssize_t ib_uverbs_resize_cq(struct ib_uverbs_file *file,
if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT;
- INIT_UDATA(&udata, buf + sizeof cmd,
- (unsigned long) cmd.response + sizeof resp,
- in_len - sizeof cmd, out_len - sizeof resp);
+ INIT_UDATA(&udata, buf + sizeof(cmd),
+ (unsigned long) cmd.response + sizeof(resp),
+ in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
+ out_len - sizeof(resp));
cq = uobj_get_obj_read(cq, cmd.cq_handle, file->ucontext);
if (!cq)
@@ -1185,7 +1198,8 @@ out:
return ret ? ret : in_len;
}
-static int copy_wc_to_user(void __user *dest, struct ib_wc *wc)
+static int copy_wc_to_user(struct ib_device *ib_dev, void __user *dest,
+ struct ib_wc *wc)
{
struct ib_uverbs_wc tmp;
@@ -1199,7 +1213,10 @@ static int copy_wc_to_user(void __user *dest, struct ib_wc *wc)
tmp.src_qp = wc->src_qp;
tmp.wc_flags = wc->wc_flags;
tmp.pkey_index = wc->pkey_index;
- tmp.slid = wc->slid;
+ if (rdma_cap_opa_ah(ib_dev, wc->port_num))
+ tmp.slid = OPA_TO_IB_UCAST_LID(wc->slid);
+ else
+ tmp.slid = ib_lid_cpu16(wc->slid);
tmp.sl = wc->sl;
tmp.dlid_path_bits = wc->dlid_path_bits;
tmp.port_num = wc->port_num;
@@ -1243,7 +1260,7 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
if (!ret)
break;
- ret = copy_wc_to_user(data_ptr, &wc);
+ ret = copy_wc_to_user(ib_dev, data_ptr, &wc);
if (ret)
goto out_put;
@@ -1383,8 +1400,9 @@ static int create_qp(struct ib_uverbs_file *file,
attr.rwq_ind_tbl = ind_tbl;
}
- if ((cmd_sz >= offsetof(typeof(*cmd), reserved1) +
- sizeof(cmd->reserved1)) && cmd->reserved1) {
+ if (cmd_sz > sizeof(*cmd) &&
+ !ib_is_udata_cleared(ucore, sizeof(*cmd),
+ cmd_sz - sizeof(*cmd))) {
ret = -EOPNOTSUPP;
goto err_put;
}
@@ -1420,7 +1438,7 @@ static int create_qp(struct ib_uverbs_file *file,
if (cmd->is_srq) {
srq = uobj_get_obj_read(srq, cmd->srq_handle,
file->ucontext);
- if (!srq || srq->srq_type != IB_SRQT_BASIC) {
+ if (!srq || srq->srq_type == IB_SRQT_XRC) {
ret = -EINVAL;
goto err_put;
}
@@ -1482,11 +1500,21 @@ static int create_qp(struct ib_uverbs_file *file,
IB_QP_CREATE_MANAGED_SEND |
IB_QP_CREATE_MANAGED_RECV |
IB_QP_CREATE_SCATTER_FCS |
- IB_QP_CREATE_CVLAN_STRIPPING)) {
+ IB_QP_CREATE_CVLAN_STRIPPING |
+ IB_QP_CREATE_SOURCE_QPN)) {
ret = -EINVAL;
goto err_put;
}
+ if (attr.create_flags & IB_QP_CREATE_SOURCE_QPN) {
+ if (!capable(CAP_NET_RAW)) {
+ ret = -EPERM;
+ goto err_put;
+ }
+
+ attr.source_qpn = cmd->source_qpn;
+ }
+
buf = (void *)cmd + sizeof(*cmd);
if (cmd_sz > sizeof(*cmd))
if (!(buf[0] == 0 && !memcmp(buf, buf + 1,
@@ -1722,9 +1750,10 @@ ssize_t ib_uverbs_open_qp(struct ib_uverbs_file *file,
if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT;
- INIT_UDATA(&udata, buf + sizeof cmd,
- (unsigned long) cmd.response + sizeof resp,
- in_len - sizeof cmd, out_len - sizeof resp);
+ INIT_UDATA(&udata, buf + sizeof(cmd),
+ (unsigned long) cmd.response + sizeof(resp),
+ in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
+ out_len - sizeof(resp));
obj = (struct ib_uqp_object *)uobj_alloc(uobj_get_type(qp),
file->ucontext);
@@ -1791,6 +1820,28 @@ err_put:
return ret;
}
+static void copy_ah_attr_to_uverbs(struct ib_uverbs_qp_dest *uverb_attr,
+ struct rdma_ah_attr *rdma_attr)
+{
+ const struct ib_global_route *grh;
+
+ uverb_attr->dlid = rdma_ah_get_dlid(rdma_attr);
+ uverb_attr->sl = rdma_ah_get_sl(rdma_attr);
+ uverb_attr->src_path_bits = rdma_ah_get_path_bits(rdma_attr);
+ uverb_attr->static_rate = rdma_ah_get_static_rate(rdma_attr);
+ uverb_attr->is_global = !!(rdma_ah_get_ah_flags(rdma_attr) &
+ IB_AH_GRH);
+ if (uverb_attr->is_global) {
+ grh = rdma_ah_read_grh(rdma_attr);
+ memcpy(uverb_attr->dgid, grh->dgid.raw, 16);
+ uverb_attr->flow_label = grh->flow_label;
+ uverb_attr->sgid_index = grh->sgid_index;
+ uverb_attr->hop_limit = grh->hop_limit;
+ uverb_attr->traffic_class = grh->traffic_class;
+ }
+ uverb_attr->port_num = rdma_ah_get_port_num(rdma_attr);
+}
+
ssize_t ib_uverbs_query_qp(struct ib_uverbs_file *file,
struct ib_device *ib_dev,
const char __user *buf, int in_len,
@@ -1801,7 +1852,6 @@ ssize_t ib_uverbs_query_qp(struct ib_uverbs_file *file,
struct ib_qp *qp;
struct ib_qp_attr *attr;
struct ib_qp_init_attr *init_attr;
- const struct ib_global_route *grh;
int ret;
if (copy_from_user(&cmd, buf, sizeof cmd))
@@ -1851,39 +1901,8 @@ ssize_t ib_uverbs_query_qp(struct ib_uverbs_file *file,
resp.alt_port_num = attr->alt_port_num;
resp.alt_timeout = attr->alt_timeout;
- resp.dest.dlid = rdma_ah_get_dlid(&attr->ah_attr);
- resp.dest.sl = rdma_ah_get_sl(&attr->ah_attr);
- resp.dest.src_path_bits = rdma_ah_get_path_bits(&attr->ah_attr);
- resp.dest.static_rate = rdma_ah_get_static_rate(&attr->ah_attr);
- resp.dest.is_global = !!(rdma_ah_get_ah_flags(&attr->ah_attr) &
- IB_AH_GRH);
- if (resp.dest.is_global) {
- grh = rdma_ah_read_grh(&attr->ah_attr);
- memcpy(resp.dest.dgid, grh->dgid.raw, 16);
- resp.dest.flow_label = grh->flow_label;
- resp.dest.sgid_index = grh->sgid_index;
- resp.dest.hop_limit = grh->hop_limit;
- resp.dest.traffic_class = grh->traffic_class;
- }
- resp.dest.port_num = rdma_ah_get_port_num(&attr->ah_attr);
-
- resp.alt_dest.dlid = rdma_ah_get_dlid(&attr->alt_ah_attr);
- resp.alt_dest.sl = rdma_ah_get_sl(&attr->alt_ah_attr);
- resp.alt_dest.src_path_bits = rdma_ah_get_path_bits(&attr->alt_ah_attr);
- resp.alt_dest.static_rate
- = rdma_ah_get_static_rate(&attr->alt_ah_attr);
- resp.alt_dest.is_global
- = !!(rdma_ah_get_ah_flags(&attr->alt_ah_attr) &
- IB_AH_GRH);
- if (resp.alt_dest.is_global) {
- grh = rdma_ah_read_grh(&attr->alt_ah_attr);
- memcpy(resp.alt_dest.dgid, grh->dgid.raw, 16);
- resp.alt_dest.flow_label = grh->flow_label;
- resp.alt_dest.sgid_index = grh->sgid_index;
- resp.alt_dest.hop_limit = grh->hop_limit;
- resp.alt_dest.traffic_class = grh->traffic_class;
- }
- resp.alt_dest.port_num = rdma_ah_get_port_num(&attr->alt_ah_attr);
+ copy_ah_attr_to_uverbs(&resp.dest, &attr->ah_attr);
+ copy_ah_attr_to_uverbs(&resp.alt_dest, &attr->alt_ah_attr);
resp.max_send_wr = init_attr->cap.max_send_wr;
resp.max_recv_wr = init_attr->cap.max_recv_wr;
@@ -1917,6 +1936,29 @@ static int modify_qp_mask(enum ib_qp_type qp_type, int mask)
}
}
+static void copy_ah_attr_from_uverbs(struct ib_device *dev,
+ struct rdma_ah_attr *rdma_attr,
+ struct ib_uverbs_qp_dest *uverb_attr)
+{
+ rdma_attr->type = rdma_ah_find_type(dev, uverb_attr->port_num);
+ if (uverb_attr->is_global) {
+ rdma_ah_set_grh(rdma_attr, NULL,
+ uverb_attr->flow_label,
+ uverb_attr->sgid_index,
+ uverb_attr->hop_limit,
+ uverb_attr->traffic_class);
+ rdma_ah_set_dgid_raw(rdma_attr, uverb_attr->dgid);
+ } else {
+ rdma_ah_set_ah_flags(rdma_attr, 0);
+ }
+ rdma_ah_set_dlid(rdma_attr, uverb_attr->dlid);
+ rdma_ah_set_sl(rdma_attr, uverb_attr->sl);
+ rdma_ah_set_path_bits(rdma_attr, uverb_attr->src_path_bits);
+ rdma_ah_set_static_rate(rdma_attr, uverb_attr->static_rate);
+ rdma_ah_set_port_num(rdma_attr, uverb_attr->port_num);
+ rdma_ah_set_make_grd(rdma_attr, false);
+}
+
static int modify_qp(struct ib_uverbs_file *file,
struct ib_uverbs_ex_modify_qp *cmd, struct ib_udata *udata)
{
@@ -1964,48 +2006,12 @@ static int modify_qp(struct ib_uverbs_file *file,
attr->rate_limit = cmd->rate_limit;
if (cmd->base.attr_mask & IB_QP_AV)
- attr->ah_attr.type = rdma_ah_find_type(qp->device,
- cmd->base.dest.port_num);
- if (cmd->base.dest.is_global) {
- rdma_ah_set_grh(&attr->ah_attr, NULL,
- cmd->base.dest.flow_label,
- cmd->base.dest.sgid_index,
- cmd->base.dest.hop_limit,
- cmd->base.dest.traffic_class);
- rdma_ah_set_dgid_raw(&attr->ah_attr, cmd->base.dest.dgid);
- } else {
- rdma_ah_set_ah_flags(&attr->ah_attr, 0);
- }
- rdma_ah_set_dlid(&attr->ah_attr, cmd->base.dest.dlid);
- rdma_ah_set_sl(&attr->ah_attr, cmd->base.dest.sl);
- rdma_ah_set_path_bits(&attr->ah_attr, cmd->base.dest.src_path_bits);
- rdma_ah_set_static_rate(&attr->ah_attr, cmd->base.dest.static_rate);
- rdma_ah_set_port_num(&attr->ah_attr,
- cmd->base.dest.port_num);
+ copy_ah_attr_from_uverbs(qp->device, &attr->ah_attr,
+ &cmd->base.dest);
if (cmd->base.attr_mask & IB_QP_ALT_PATH)
- attr->alt_ah_attr.type =
- rdma_ah_find_type(qp->device, cmd->base.dest.port_num);
- if (cmd->base.alt_dest.is_global) {
- rdma_ah_set_grh(&attr->alt_ah_attr, NULL,
- cmd->base.alt_dest.flow_label,
- cmd->base.alt_dest.sgid_index,
- cmd->base.alt_dest.hop_limit,
- cmd->base.alt_dest.traffic_class);
- rdma_ah_set_dgid_raw(&attr->alt_ah_attr,
- cmd->base.alt_dest.dgid);
- } else {
- rdma_ah_set_ah_flags(&attr->alt_ah_attr, 0);
- }
-
- rdma_ah_set_dlid(&attr->alt_ah_attr, cmd->base.alt_dest.dlid);
- rdma_ah_set_sl(&attr->alt_ah_attr, cmd->base.alt_dest.sl);
- rdma_ah_set_path_bits(&attr->alt_ah_attr,
- cmd->base.alt_dest.src_path_bits);
- rdma_ah_set_static_rate(&attr->alt_ah_attr,
- cmd->base.alt_dest.static_rate);
- rdma_ah_set_port_num(&attr->alt_ah_attr,
- cmd->base.alt_dest.port_num);
+ copy_ah_attr_from_uverbs(qp->device, &attr->alt_ah_attr,
+ &cmd->base.alt_dest);
ret = ib_modify_qp_with_udata(qp, attr,
modify_qp_mask(qp->qp_type,
@@ -2037,7 +2043,8 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
return -EOPNOTSUPP;
INIT_UDATA(&udata, buf + sizeof(cmd.base), NULL,
- in_len - sizeof(cmd.base), out_len);
+ in_len - sizeof(cmd.base) - sizeof(struct ib_uverbs_cmd_hdr),
+ out_len);
ret = modify_qp(file, &cmd, &udata);
if (ret)
@@ -2543,7 +2550,8 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
INIT_UDATA(&udata, buf + sizeof(cmd),
(unsigned long)cmd.response + sizeof(resp),
- in_len - sizeof(cmd), out_len - sizeof(resp));
+ in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
+ out_len - sizeof(resp));
uobj = uobj_alloc(uobj_get_type(ah), file->ucontext);
if (IS_ERR(uobj))
@@ -2556,6 +2564,7 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
}
attr.type = rdma_ah_find_type(ib_dev, cmd.attr.port_num);
+ rdma_ah_set_make_grd(&attr, false);
rdma_ah_set_dlid(&attr, cmd.attr.dlid);
rdma_ah_set_sl(&attr, cmd.attr.sl);
rdma_ah_set_path_bits(&attr, cmd.attr.src_path_bits);
@@ -3472,6 +3481,9 @@ static int __uverbs_create_xsrq(struct ib_uverbs_file *file,
if (IS_ERR(obj))
return PTR_ERR(obj);
+ if (cmd->srq_type == IB_SRQT_TM)
+ attr.ext.tag_matching.max_num_tags = cmd->max_num_tags;
+
if (cmd->srq_type == IB_SRQT_XRC) {
xrcd_uobj = uobj_get_read(uobj_get_type(xrcd), cmd->xrcd_handle,
file->ucontext);
@@ -3488,10 +3500,12 @@ static int __uverbs_create_xsrq(struct ib_uverbs_file *file,
obj->uxrcd = container_of(xrcd_uobj, struct ib_uxrcd_object, uobject);
atomic_inc(&obj->uxrcd->refcnt);
+ }
- attr.ext.xrc.cq = uobj_get_obj_read(cq, cmd->cq_handle,
- file->ucontext);
- if (!attr.ext.xrc.cq) {
+ if (ib_srq_has_cq(cmd->srq_type)) {
+ attr.ext.cq = uobj_get_obj_read(cq, cmd->cq_handle,
+ file->ucontext);
+ if (!attr.ext.cq) {
ret = -EINVAL;
goto err_put_xrcd;
}
@@ -3526,10 +3540,13 @@ static int __uverbs_create_xsrq(struct ib_uverbs_file *file,
srq->event_handler = attr.event_handler;
srq->srq_context = attr.srq_context;
+ if (ib_srq_has_cq(cmd->srq_type)) {
+ srq->ext.cq = attr.ext.cq;
+ atomic_inc(&attr.ext.cq->usecnt);
+ }
+
if (cmd->srq_type == IB_SRQT_XRC) {
- srq->ext.xrc.cq = attr.ext.xrc.cq;
srq->ext.xrc.xrcd = attr.ext.xrc.xrcd;
- atomic_inc(&attr.ext.xrc.cq->usecnt);
atomic_inc(&attr.ext.xrc.xrcd->usecnt);
}
@@ -3552,10 +3569,12 @@ static int __uverbs_create_xsrq(struct ib_uverbs_file *file,
goto err_copy;
}
- if (cmd->srq_type == IB_SRQT_XRC) {
+ if (cmd->srq_type == IB_SRQT_XRC)
uobj_put_read(xrcd_uobj);
- uobj_put_obj_read(attr.ext.xrc.cq);
- }
+
+ if (ib_srq_has_cq(cmd->srq_type))
+ uobj_put_obj_read(attr.ext.cq);
+
uobj_put_obj_read(pd);
uobj_alloc_commit(&obj->uevent.uobject);
@@ -3568,8 +3587,8 @@ err_put:
uobj_put_obj_read(pd);
err_put_cq:
- if (cmd->srq_type == IB_SRQT_XRC)
- uobj_put_obj_read(attr.ext.xrc.cq);
+ if (ib_srq_has_cq(cmd->srq_type))
+ uobj_put_obj_read(attr.ext.cq);
err_put_xrcd:
if (cmd->srq_type == IB_SRQT_XRC) {
@@ -3599,6 +3618,7 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT;
+ memset(&xcmd, 0, sizeof(xcmd));
xcmd.response = cmd.response;
xcmd.user_handle = cmd.user_handle;
xcmd.srq_type = IB_SRQT_BASIC;
@@ -3607,10 +3627,10 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
xcmd.max_sge = cmd.max_sge;
xcmd.srq_limit = cmd.srq_limit;
- INIT_UDATA(&udata, buf + sizeof cmd,
- (unsigned long) cmd.response + sizeof resp,
- in_len - sizeof cmd - sizeof(struct ib_uverbs_cmd_hdr),
- out_len - sizeof resp);
+ INIT_UDATA(&udata, buf + sizeof(cmd),
+ (unsigned long) cmd.response + sizeof(resp),
+ in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
+ out_len - sizeof(resp));
ret = __uverbs_create_xsrq(file, ib_dev, &xcmd, &udata);
if (ret)
@@ -3634,10 +3654,10 @@ ssize_t ib_uverbs_create_xsrq(struct ib_uverbs_file *file,
if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT;
- INIT_UDATA(&udata, buf + sizeof cmd,
- (unsigned long) cmd.response + sizeof resp,
- in_len - sizeof cmd - sizeof(struct ib_uverbs_cmd_hdr),
- out_len - sizeof resp);
+ INIT_UDATA(&udata, buf + sizeof(cmd),
+ (unsigned long) cmd.response + sizeof(resp),
+ in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
+ out_len - sizeof(resp));
ret = __uverbs_create_xsrq(file, ib_dev, &cmd, &udata);
if (ret)
@@ -3848,6 +3868,16 @@ int ib_uverbs_ex_query_device(struct ib_uverbs_file *file,
resp.raw_packet_caps = attr.raw_packet_caps;
resp.response_length += sizeof(resp.raw_packet_caps);
+
+ if (ucore->outlen < resp.response_length + sizeof(resp.xrq_caps))
+ goto end;
+
+ resp.xrq_caps.max_rndv_hdr_size = attr.xrq_caps.max_rndv_hdr_size;
+ resp.xrq_caps.max_num_tags = attr.xrq_caps.max_num_tags;
+ resp.xrq_caps.max_ops = attr.xrq_caps.max_ops;
+ resp.xrq_caps.max_sge = attr.xrq_caps.max_sge;
+ resp.xrq_caps.flags = attr.xrq_caps.flags;
+ resp.response_length += sizeof(resp.xrq_caps);
end:
err = ib_copy_to_udata(ucore, &resp, resp.response_length);
return err;
diff --git a/drivers/infiniband/core/uverbs_ioctl.c b/drivers/infiniband/core/uverbs_ioctl.c
new file mode 100644
index 0000000..5286ad5
--- /dev/null
+++ b/drivers/infiniband/core/uverbs_ioctl.c
@@ -0,0 +1,364 @@
+/*
+ * Copyright (c) 2017, Mellanox Technologies inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <rdma/rdma_user_ioctl.h>
+#include <rdma/uverbs_ioctl.h>
+#include "rdma_core.h"
+#include "uverbs.h"
+
+static int uverbs_process_attr(struct ib_device *ibdev,
+ struct ib_ucontext *ucontext,
+ const struct ib_uverbs_attr *uattr,
+ u16 attr_id,
+ const struct uverbs_attr_spec_hash *attr_spec_bucket,
+ struct uverbs_attr_bundle_hash *attr_bundle_h,
+ struct ib_uverbs_attr __user *uattr_ptr)
+{
+ const struct uverbs_attr_spec *spec;
+ struct uverbs_attr *e;
+ const struct uverbs_object_spec *object;
+ struct uverbs_obj_attr *o_attr;
+ struct uverbs_attr *elements = attr_bundle_h->attrs;
+
+ if (uattr->reserved)
+ return -EINVAL;
+
+ if (attr_id >= attr_spec_bucket->num_attrs) {
+ if (uattr->flags & UVERBS_ATTR_F_MANDATORY)
+ return -EINVAL;
+ else
+ return 0;
+ }
+
+ spec = &attr_spec_bucket->attrs[attr_id];
+ e = &elements[attr_id];
+ e->uattr = uattr_ptr;
+
+ switch (spec->type) {
+ case UVERBS_ATTR_TYPE_PTR_IN:
+ case UVERBS_ATTR_TYPE_PTR_OUT:
+ if (uattr->len < spec->len ||
+ (!(spec->flags & UVERBS_ATTR_SPEC_F_MIN_SZ) &&
+ uattr->len > spec->len))
+ return -EINVAL;
+
+ e->ptr_attr.data = uattr->data;
+ e->ptr_attr.len = uattr->len;
+ e->ptr_attr.flags = uattr->flags;
+ break;
+
+ case UVERBS_ATTR_TYPE_IDR:
+ if (uattr->data >> 32)
+ return -EINVAL;
+ /* fall through */
+ case UVERBS_ATTR_TYPE_FD:
+ if (uattr->len != 0 || !ucontext || uattr->data > INT_MAX)
+ return -EINVAL;
+
+ o_attr = &e->obj_attr;
+ object = uverbs_get_object(ibdev, spec->obj.obj_type);
+ if (!object)
+ return -EINVAL;
+ o_attr->type = object->type_attrs;
+
+ o_attr->id = (int)uattr->data;
+ o_attr->uobject = uverbs_get_uobject_from_context(
+ o_attr->type,
+ ucontext,
+ spec->obj.access,
+ o_attr->id);
+
+ if (IS_ERR(o_attr->uobject))
+ return PTR_ERR(o_attr->uobject);
+
+ if (spec->obj.access == UVERBS_ACCESS_NEW) {
+ u64 id = o_attr->uobject->id;
+
+ /* Copy the allocated id to the user-space */
+ if (put_user(id, &e->uattr->data)) {
+ uverbs_finalize_object(o_attr->uobject,
+ UVERBS_ACCESS_NEW,
+ false);
+ return -EFAULT;
+ }
+ }
+
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ set_bit(attr_id, attr_bundle_h->valid_bitmap);
+ return 0;
+}
+
+static int uverbs_uattrs_process(struct ib_device *ibdev,
+ struct ib_ucontext *ucontext,
+ const struct ib_uverbs_attr *uattrs,
+ size_t num_uattrs,
+ const struct uverbs_method_spec *method,
+ struct uverbs_attr_bundle *attr_bundle,
+ struct ib_uverbs_attr __user *uattr_ptr)
+{
+ size_t i;
+ int ret = 0;
+ int num_given_buckets = 0;
+
+ for (i = 0; i < num_uattrs; i++) {
+ const struct ib_uverbs_attr *uattr = &uattrs[i];
+ u16 attr_id = uattr->attr_id;
+ struct uverbs_attr_spec_hash *attr_spec_bucket;
+
+ ret = uverbs_ns_idx(&attr_id, method->num_buckets);
+ if (ret < 0) {
+ if (uattr->flags & UVERBS_ATTR_F_MANDATORY) {
+ uverbs_finalize_objects(attr_bundle,
+ method->attr_buckets,
+ num_given_buckets,
+ false);
+ return ret;
+ }
+ continue;
+ }
+
+ /*
+ * ret is the found ns, so increase num_given_buckets if
+ * necessary.
+ */
+ if (ret >= num_given_buckets)
+ num_given_buckets = ret + 1;
+
+ attr_spec_bucket = method->attr_buckets[ret];
+ ret = uverbs_process_attr(ibdev, ucontext, uattr, attr_id,
+ attr_spec_bucket, &attr_bundle->hash[ret],
+ uattr_ptr++);
+ if (ret) {
+ uverbs_finalize_objects(attr_bundle,
+ method->attr_buckets,
+ num_given_buckets,
+ false);
+ return ret;
+ }
+ }
+
+ return num_given_buckets;
+}
+
+static int uverbs_validate_kernel_mandatory(const struct uverbs_method_spec *method_spec,
+ struct uverbs_attr_bundle *attr_bundle)
+{
+ unsigned int i;
+
+ for (i = 0; i < attr_bundle->num_buckets; i++) {
+ struct uverbs_attr_spec_hash *attr_spec_bucket =
+ method_spec->attr_buckets[i];
+
+ if (!bitmap_subset(attr_spec_bucket->mandatory_attrs_bitmask,
+ attr_bundle->hash[i].valid_bitmap,
+ attr_spec_bucket->num_attrs))
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int uverbs_handle_method(struct ib_uverbs_attr __user *uattr_ptr,
+ const struct ib_uverbs_attr *uattrs,
+ size_t num_uattrs,
+ struct ib_device *ibdev,
+ struct ib_uverbs_file *ufile,
+ const struct uverbs_method_spec *method_spec,
+ struct uverbs_attr_bundle *attr_bundle)
+{
+ int ret;
+ int finalize_ret;
+ int num_given_buckets;
+
+ num_given_buckets = uverbs_uattrs_process(ibdev, ufile->ucontext, uattrs,
+ num_uattrs, method_spec,
+ attr_bundle, uattr_ptr);
+ if (num_given_buckets <= 0)
+ return -EINVAL;
+
+ attr_bundle->num_buckets = num_given_buckets;
+ ret = uverbs_validate_kernel_mandatory(method_spec, attr_bundle);
+ if (ret)
+ goto cleanup;
+
+ ret = method_spec->handler(ibdev, ufile, attr_bundle);
+cleanup:
+ finalize_ret = uverbs_finalize_objects(attr_bundle,
+ method_spec->attr_buckets,
+ attr_bundle->num_buckets,
+ !ret);
+
+ return ret ? ret : finalize_ret;
+}
+
+#define UVERBS_OPTIMIZE_USING_STACK_SZ 256
+static long ib_uverbs_cmd_verbs(struct ib_device *ib_dev,
+ struct ib_uverbs_file *file,
+ struct ib_uverbs_ioctl_hdr *hdr,
+ void __user *buf)
+{
+ const struct uverbs_object_spec *object_spec;
+ const struct uverbs_method_spec *method_spec;
+ long err = 0;
+ unsigned int i;
+ struct {
+ struct ib_uverbs_attr *uattrs;
+ struct uverbs_attr_bundle *uverbs_attr_bundle;
+ } *ctx = NULL;
+ struct uverbs_attr *curr_attr;
+ unsigned long *curr_bitmap;
+ size_t ctx_size;
+#ifdef UVERBS_OPTIMIZE_USING_STACK_SZ
+ uintptr_t data[UVERBS_OPTIMIZE_USING_STACK_SZ / sizeof(uintptr_t)];
+#endif
+
+ if (hdr->reserved)
+ return -EINVAL;
+
+ object_spec = uverbs_get_object(ib_dev, hdr->object_id);
+ if (!object_spec)
+ return -EOPNOTSUPP;
+
+ method_spec = uverbs_get_method(object_spec, hdr->method_id);
+ if (!method_spec)
+ return -EOPNOTSUPP;
+
+ if ((method_spec->flags & UVERBS_ACTION_FLAG_CREATE_ROOT) ^ !file->ucontext)
+ return -EINVAL;
+
+ ctx_size = sizeof(*ctx) +
+ sizeof(struct uverbs_attr_bundle) +
+ sizeof(struct uverbs_attr_bundle_hash) * method_spec->num_buckets +
+ sizeof(*ctx->uattrs) * hdr->num_attrs +
+ sizeof(*ctx->uverbs_attr_bundle->hash[0].attrs) *
+ method_spec->num_child_attrs +
+ sizeof(*ctx->uverbs_attr_bundle->hash[0].valid_bitmap) *
+ (method_spec->num_child_attrs / BITS_PER_LONG +
+ method_spec->num_buckets);
+
+#ifdef UVERBS_OPTIMIZE_USING_STACK_SZ
+ if (ctx_size <= UVERBS_OPTIMIZE_USING_STACK_SZ)
+ ctx = (void *)data;
+
+ if (!ctx)
+#endif
+ ctx = kmalloc(ctx_size, GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ ctx->uverbs_attr_bundle = (void *)ctx + sizeof(*ctx);
+ ctx->uattrs = (void *)(ctx->uverbs_attr_bundle + 1) +
+ (sizeof(ctx->uverbs_attr_bundle->hash[0]) *
+ method_spec->num_buckets);
+ curr_attr = (void *)(ctx->uattrs + hdr->num_attrs);
+ curr_bitmap = (void *)(curr_attr + method_spec->num_child_attrs);
+
+ /*
+ * We just fill the pointers and num_attrs here. The data itself will be
+ * filled at a later stage (uverbs_process_attr)
+ */
+ for (i = 0; i < method_spec->num_buckets; i++) {
+ unsigned int curr_num_attrs = method_spec->attr_buckets[i]->num_attrs;
+
+ ctx->uverbs_attr_bundle->hash[i].attrs = curr_attr;
+ curr_attr += curr_num_attrs;
+ ctx->uverbs_attr_bundle->hash[i].num_attrs = curr_num_attrs;
+ ctx->uverbs_attr_bundle->hash[i].valid_bitmap = curr_bitmap;
+ bitmap_zero(curr_bitmap, curr_num_attrs);
+ curr_bitmap += BITS_TO_LONGS(curr_num_attrs);
+ }
+
+ err = copy_from_user(ctx->uattrs, buf,
+ sizeof(*ctx->uattrs) * hdr->num_attrs);
+ if (err) {
+ err = -EFAULT;
+ goto out;
+ }
+
+ err = uverbs_handle_method(buf, ctx->uattrs, hdr->num_attrs, ib_dev,
+ file, method_spec, ctx->uverbs_attr_bundle);
+out:
+#ifdef UVERBS_OPTIMIZE_USING_STACK_SZ
+ if (ctx_size > UVERBS_OPTIMIZE_USING_STACK_SZ)
+#endif
+ kfree(ctx);
+ return err;
+}
+
+#define IB_UVERBS_MAX_CMD_SZ 4096
+
+long ib_uverbs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ struct ib_uverbs_file *file = filp->private_data;
+ struct ib_uverbs_ioctl_hdr __user *user_hdr =
+ (struct ib_uverbs_ioctl_hdr __user *)arg;
+ struct ib_uverbs_ioctl_hdr hdr;
+ struct ib_device *ib_dev;
+ int srcu_key;
+ long err;
+
+ srcu_key = srcu_read_lock(&file->device->disassociate_srcu);
+ ib_dev = srcu_dereference(file->device->ib_dev,
+ &file->device->disassociate_srcu);
+ if (!ib_dev) {
+ err = -EIO;
+ goto out;
+ }
+
+ if (cmd == RDMA_VERBS_IOCTL) {
+ err = copy_from_user(&hdr, user_hdr, sizeof(hdr));
+
+ if (err || hdr.length > IB_UVERBS_MAX_CMD_SZ ||
+ hdr.length != sizeof(hdr) + hdr.num_attrs * sizeof(struct ib_uverbs_attr)) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (hdr.reserved) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ err = ib_uverbs_cmd_verbs(ib_dev, file, &hdr,
+ (__user void *)arg + sizeof(hdr));
+ } else {
+ err = -ENOIOCTLCMD;
+ }
+out:
+ srcu_read_unlock(&file->device->disassociate_srcu, srcu_key);
+
+ return err;
+}
diff --git a/drivers/infiniband/core/uverbs_ioctl_merge.c b/drivers/infiniband/core/uverbs_ioctl_merge.c
new file mode 100644
index 0000000..76ddb65
--- /dev/null
+++ b/drivers/infiniband/core/uverbs_ioctl_merge.c
@@ -0,0 +1,665 @@
+/*
+ * Copyright (c) 2017, Mellanox Technologies inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <rdma/uverbs_ioctl.h>
+#include <rdma/rdma_user_ioctl.h>
+#include <linux/bitops.h>
+#include "uverbs.h"
+
+#define UVERBS_NUM_NS (UVERBS_ID_NS_MASK >> UVERBS_ID_NS_SHIFT)
+#define GET_NS_ID(idx) (((idx) & UVERBS_ID_NS_MASK) >> UVERBS_ID_NS_SHIFT)
+#define GET_ID(idx) ((idx) & ~UVERBS_ID_NS_MASK)
+
+#define _for_each_element(elem, tmpi, tmpj, hashes, num_buckets_offset, \
+ buckets_offset) \
+ for (tmpj = 0, \
+ elem = (*(const void ***)((hashes)[tmpi] + \
+ (buckets_offset)))[0]; \
+ tmpj < *(size_t *)((hashes)[tmpi] + (num_buckets_offset)); \
+ tmpj++) \
+ if ((elem = ((*(const void ***)(hashes[tmpi] + \
+ (buckets_offset)))[tmpj])))
+
+/*
+ * Iterate all elements of a few @hashes. The number of given hashes is
+ * indicated by @num_hashes. The offset of the number of buckets in the hash is
+ * represented by @num_buckets_offset, while the offset of the buckets array in
+ * the hash structure is represented by @buckets_offset. tmpi and tmpj are two
+ * short (or int) based indices that are given by the user. tmpi iterates over
+ * the different hashes. @elem points the current element in the hashes[tmpi]
+ * bucket we are looping on. To be honest, @hashes representation isn't exactly
+ * a hash, but more a collection of elements. These elements' ids are treated
+ * in a hash like manner, where the first upper bits are the bucket number.
+ * These elements are later mapped into a perfect-hash.
+ */
+#define for_each_element(elem, tmpi, tmpj, hashes, num_hashes, \
+ num_buckets_offset, buckets_offset) \
+ for (tmpi = 0; tmpi < (num_hashes); tmpi++) \
+ _for_each_element(elem, tmpi, tmpj, hashes, num_buckets_offset,\
+ buckets_offset)
+
+#define get_elements_iterators_entry_above(iters, num_elements, elements, \
+ num_objects_fld, objects_fld, bucket,\
+ min_id) \
+ get_elements_above_id((const void **)iters, num_elements, \
+ (const void **)(elements), \
+ offsetof(typeof(**elements), \
+ num_objects_fld), \
+ offsetof(typeof(**elements), objects_fld),\
+ offsetof(typeof(***(*elements)->objects_fld), id),\
+ bucket, min_id)
+
+#define get_objects_above_id(iters, num_trees, trees, bucket, min_id) \
+ get_elements_iterators_entry_above(iters, num_trees, trees, \
+ num_objects, objects, bucket, min_id)
+
+#define get_methods_above_id(method_iters, num_iters, iters, bucket, min_id)\
+ get_elements_iterators_entry_above(method_iters, num_iters, iters, \
+ num_methods, methods, bucket, min_id)
+
+#define get_attrs_above_id(attrs_iters, num_iters, iters, bucket, min_id)\
+ get_elements_iterators_entry_above(attrs_iters, num_iters, iters, \
+ num_attrs, attrs, bucket, min_id)
+
+/*
+ * get_elements_above_id get a few hashes represented by @elements and
+ * @num_elements. The hashes fields are described by @num_offset, @data_offset
+ * and @id_offset in the same way as required by for_each_element. The function
+ * returns an array of @iters, represents an array of elements in the hashes
+ * buckets, which their ids are the smallest ids in all hashes but are all
+ * larger than the id given by min_id. Elements are only added to the iters
+ * array if their id belongs to the bucket @bucket. The number of elements in
+ * the returned array is returned by the function. @min_id is also updated to
+ * reflect the new min_id of all elements in iters.
+ */
+static size_t get_elements_above_id(const void **iters,
+ unsigned int num_elements,
+ const void **elements,
+ size_t num_offset,
+ size_t data_offset,
+ size_t id_offset,
+ u16 bucket,
+ short *min_id)
+{
+ size_t num_iters = 0;
+ short min = SHRT_MAX;
+ const void *elem;
+ int i, j, last_stored = -1;
+
+ for_each_element(elem, i, j, elements, num_elements, num_offset,
+ data_offset) {
+ u16 id = *(u16 *)(elem + id_offset);
+
+ if (GET_NS_ID(id) != bucket)
+ continue;
+
+ if (GET_ID(id) < *min_id ||
+ (min != SHRT_MAX && GET_ID(id) > min))
+ continue;
+
+ /*
+ * We first iterate all hashes represented by @elements. When
+ * we do, we try to find an element @elem in the bucket @bucket
+ * which its id is min. Since we can't ensure the user sorted
+ * the elements in increasing order, we override this hash's
+ * minimal id element we found, if a new element with a smaller
+ * id was just found.
+ */
+ iters[last_stored == i ? num_iters - 1 : num_iters++] = elem;
+ last_stored = i;
+ min = GET_ID(id);
+ }
+
+ /*
+ * We only insert to our iters array an element, if its id is smaller
+ * than all previous ids. Therefore, the final iters array is sorted so
+ * that smaller ids are in the end of the array.
+ * Therefore, we need to clean the beginning of the array to make sure
+ * all ids of final elements are equal to min.
+ */
+ for (i = num_iters - 1; i >= 0 &&
+ GET_ID(*(u16 *)(iters[i] + id_offset)) == min; i--)
+ ;
+
+ num_iters -= i + 1;
+ memmove(iters, iters + i + 1, sizeof(*iters) * num_iters);
+
+ *min_id = min;
+ return num_iters;
+}
+
+#define find_max_element_entry_id(num_elements, elements, num_objects_fld, \
+ objects_fld, bucket) \
+ find_max_element_id(num_elements, (const void **)(elements), \
+ offsetof(typeof(**elements), num_objects_fld), \
+ offsetof(typeof(**elements), objects_fld), \
+ offsetof(typeof(***(*elements)->objects_fld), id),\
+ bucket)
+
+static short find_max_element_ns_id(unsigned int num_elements,
+ const void **elements,
+ size_t num_offset,
+ size_t data_offset,
+ size_t id_offset)
+{
+ short max_ns = SHRT_MIN;
+ const void *elem;
+ int i, j;
+
+ for_each_element(elem, i, j, elements, num_elements, num_offset,
+ data_offset) {
+ u16 id = *(u16 *)(elem + id_offset);
+
+ if (GET_NS_ID(id) > max_ns)
+ max_ns = GET_NS_ID(id);
+ }
+
+ return max_ns;
+}
+
+static short find_max_element_id(unsigned int num_elements,
+ const void **elements,
+ size_t num_offset,
+ size_t data_offset,
+ size_t id_offset,
+ u16 bucket)
+{
+ short max_id = SHRT_MIN;
+ const void *elem;
+ int i, j;
+
+ for_each_element(elem, i, j, elements, num_elements, num_offset,
+ data_offset) {
+ u16 id = *(u16 *)(elem + id_offset);
+
+ if (GET_NS_ID(id) == bucket &&
+ GET_ID(id) > max_id)
+ max_id = GET_ID(id);
+ }
+ return max_id;
+}
+
+#define find_max_element_entry_id(num_elements, elements, num_objects_fld, \
+ objects_fld, bucket) \
+ find_max_element_id(num_elements, (const void **)(elements), \
+ offsetof(typeof(**elements), num_objects_fld), \
+ offsetof(typeof(**elements), objects_fld), \
+ offsetof(typeof(***(*elements)->objects_fld), id),\
+ bucket)
+
+#define find_max_element_ns_entry_id(num_elements, elements, \
+ num_objects_fld, objects_fld) \
+ find_max_element_ns_id(num_elements, (const void **)(elements), \
+ offsetof(typeof(**elements), num_objects_fld),\
+ offsetof(typeof(**elements), objects_fld), \
+ offsetof(typeof(***(*elements)->objects_fld), id))
+
+/*
+ * find_max_xxxx_ns_id gets a few elements. Each element is described by an id
+ * which its upper bits represents a namespace. It finds the max namespace. This
+ * could be used in order to know how many buckets do we need to allocate. If no
+ * elements exist, SHRT_MIN is returned. Namespace represents here different
+ * buckets. The common example is "common bucket" and "driver bucket".
+ *
+ * find_max_xxxx_id gets a few elements and a bucket. Each element is described
+ * by an id which its upper bits represent a namespace. It returns the max id
+ * which is contained in the same namespace defined in @bucket. This could be
+ * used in order to know how many elements do we need to allocate in the bucket.
+ * If no elements exist, SHRT_MIN is returned.
+ */
+
+#define find_max_object_id(num_trees, trees, bucket) \
+ find_max_element_entry_id(num_trees, trees, num_objects,\
+ objects, bucket)
+#define find_max_object_ns_id(num_trees, trees) \
+ find_max_element_ns_entry_id(num_trees, trees, \
+ num_objects, objects)
+
+#define find_max_method_id(num_iters, iters, bucket) \
+ find_max_element_entry_id(num_iters, iters, num_methods,\
+ methods, bucket)
+#define find_max_method_ns_id(num_iters, iters) \
+ find_max_element_ns_entry_id(num_iters, iters, \
+ num_methods, methods)
+
+#define find_max_attr_id(num_iters, iters, bucket) \
+ find_max_element_entry_id(num_iters, iters, num_attrs, \
+ attrs, bucket)
+#define find_max_attr_ns_id(num_iters, iters) \
+ find_max_element_ns_entry_id(num_iters, iters, \
+ num_attrs, attrs)
+
+static void free_method(struct uverbs_method_spec *method)
+{
+ unsigned int i;
+
+ if (!method)
+ return;
+
+ for (i = 0; i < method->num_buckets; i++)
+ kfree(method->attr_buckets[i]);
+
+ kfree(method);
+}
+
+#define IS_ATTR_OBJECT(attr) ((attr)->type == UVERBS_ATTR_TYPE_IDR || \
+ (attr)->type == UVERBS_ATTR_TYPE_FD)
+
+/*
+ * This function gets array of size @num_method_defs which contains pointers to
+ * method definitions @method_defs. The function allocates an
+ * uverbs_method_spec structure and initializes its number of buckets and the
+ * elements in buckets to the correct attributes. While doing that, it
+ * validates that there aren't conflicts between attributes of different
+ * method_defs.
+ */
+static struct uverbs_method_spec *build_method_with_attrs(const struct uverbs_method_def **method_defs,
+ size_t num_method_defs)
+{
+ int bucket_idx;
+ int max_attr_buckets = 0;
+ size_t num_attr_buckets = 0;
+ int res = 0;
+ struct uverbs_method_spec *method = NULL;
+ const struct uverbs_attr_def **attr_defs;
+ unsigned int num_of_singularities = 0;
+
+ max_attr_buckets = find_max_attr_ns_id(num_method_defs, method_defs);
+ if (max_attr_buckets >= 0)
+ num_attr_buckets = max_attr_buckets + 1;
+
+ method = kzalloc(sizeof(*method) +
+ num_attr_buckets * sizeof(*method->attr_buckets),
+ GFP_KERNEL);
+ if (!method)
+ return ERR_PTR(-ENOMEM);
+
+ method->num_buckets = num_attr_buckets;
+ attr_defs = kcalloc(num_method_defs, sizeof(*attr_defs), GFP_KERNEL);
+ if (!attr_defs) {
+ res = -ENOMEM;
+ goto free_method;
+ }
+ for (bucket_idx = 0; bucket_idx < method->num_buckets; bucket_idx++) {
+ short min_id = SHRT_MIN;
+ int attr_max_bucket = 0;
+ struct uverbs_attr_spec_hash *hash = NULL;
+
+ attr_max_bucket = find_max_attr_id(num_method_defs, method_defs,
+ bucket_idx);
+ if (attr_max_bucket < 0)
+ continue;
+
+ hash = kzalloc(sizeof(*hash) +
+ ALIGN(sizeof(*hash->attrs) * (attr_max_bucket + 1),
+ sizeof(long)) +
+ BITS_TO_LONGS(attr_max_bucket) * sizeof(long),
+ GFP_KERNEL);
+ if (!hash) {
+ res = -ENOMEM;
+ goto free;
+ }
+ hash->num_attrs = attr_max_bucket + 1;
+ method->num_child_attrs += hash->num_attrs;
+ hash->mandatory_attrs_bitmask = (void *)(hash + 1) +
+ ALIGN(sizeof(*hash->attrs) *
+ (attr_max_bucket + 1),
+ sizeof(long));
+
+ method->attr_buckets[bucket_idx] = hash;
+
+ do {
+ size_t num_attr_defs;
+ struct uverbs_attr_spec *attr;
+ bool attr_obj_with_special_access;
+
+ num_attr_defs =
+ get_attrs_above_id(attr_defs,
+ num_method_defs,
+ method_defs,
+ bucket_idx,
+ &min_id);
+ /* Last attr in bucket */
+ if (!num_attr_defs)
+ break;
+
+ if (num_attr_defs > 1) {
+ /*
+ * We don't allow two attribute definitions for
+ * the same attribute. This is usually a
+ * programmer error. If required, it's better to
+ * just add a new attribute to capture the new
+ * semantics.
+ */
+ res = -EEXIST;
+ goto free;
+ }
+
+ attr = &hash->attrs[min_id];
+ memcpy(attr, &attr_defs[0]->attr, sizeof(*attr));
+
+ attr_obj_with_special_access = IS_ATTR_OBJECT(attr) &&
+ (attr->obj.access == UVERBS_ACCESS_NEW ||
+ attr->obj.access == UVERBS_ACCESS_DESTROY);
+ num_of_singularities += !!attr_obj_with_special_access;
+ if (WARN(num_of_singularities > 1,
+ "ib_uverbs: Method contains more than one object attr (%d) with new/destroy access\n",
+ min_id) ||
+ WARN(attr_obj_with_special_access &&
+ !(attr->flags & UVERBS_ATTR_SPEC_F_MANDATORY),
+ "ib_uverbs: Tried to merge attr (%d) but it's an object with new/destroy aceess but isn't mandatory\n",
+ min_id) ||
+ WARN(IS_ATTR_OBJECT(attr) &&
+ attr->flags & UVERBS_ATTR_SPEC_F_MIN_SZ,
+ "ib_uverbs: Tried to merge attr (%d) but it's an object with min_sz flag\n",
+ min_id)) {
+ res = -EINVAL;
+ goto free;
+ }
+
+ if (attr->flags & UVERBS_ATTR_SPEC_F_MANDATORY)
+ set_bit(min_id, hash->mandatory_attrs_bitmask);
+ min_id++;
+
+ } while (1);
+ }
+ kfree(attr_defs);
+ return method;
+
+free:
+ kfree(attr_defs);
+free_method:
+ free_method(method);
+ return ERR_PTR(res);
+}
+
+static void free_object(struct uverbs_object_spec *object)
+{
+ unsigned int i, j;
+
+ if (!object)
+ return;
+
+ for (i = 0; i < object->num_buckets; i++) {
+ struct uverbs_method_spec_hash *method_buckets =
+ object->method_buckets[i];
+
+ if (!method_buckets)
+ continue;
+
+ for (j = 0; j < method_buckets->num_methods; j++)
+ free_method(method_buckets->methods[j]);
+
+ kfree(method_buckets);
+ }
+
+ kfree(object);
+}
+
+/*
+ * This function gets array of size @num_object_defs which contains pointers to
+ * object definitions @object_defs. The function allocated an
+ * uverbs_object_spec structure and initialize its number of buckets and the
+ * elements in buckets to the correct methods. While doing that, it
+ * sorts out the correct relationship between conflicts in the same method.
+ */
+static struct uverbs_object_spec *build_object_with_methods(const struct uverbs_object_def **object_defs,
+ size_t num_object_defs)
+{
+ u16 bucket_idx;
+ int max_method_buckets = 0;
+ u16 num_method_buckets = 0;
+ int res = 0;
+ struct uverbs_object_spec *object = NULL;
+ const struct uverbs_method_def **method_defs;
+
+ max_method_buckets = find_max_method_ns_id(num_object_defs, object_defs);
+ if (max_method_buckets >= 0)
+ num_method_buckets = max_method_buckets + 1;
+
+ object = kzalloc(sizeof(*object) +
+ num_method_buckets *
+ sizeof(*object->method_buckets), GFP_KERNEL);
+ if (!object)
+ return ERR_PTR(-ENOMEM);
+
+ object->num_buckets = num_method_buckets;
+ method_defs = kcalloc(num_object_defs, sizeof(*method_defs), GFP_KERNEL);
+ if (!method_defs) {
+ res = -ENOMEM;
+ goto free_object;
+ }
+
+ for (bucket_idx = 0; bucket_idx < object->num_buckets; bucket_idx++) {
+ short min_id = SHRT_MIN;
+ int methods_max_bucket = 0;
+ struct uverbs_method_spec_hash *hash = NULL;
+
+ methods_max_bucket = find_max_method_id(num_object_defs, object_defs,
+ bucket_idx);
+ if (methods_max_bucket < 0)
+ continue;
+
+ hash = kzalloc(sizeof(*hash) +
+ sizeof(*hash->methods) * (methods_max_bucket + 1),
+ GFP_KERNEL);
+ if (!hash) {
+ res = -ENOMEM;
+ goto free;
+ }
+
+ hash->num_methods = methods_max_bucket + 1;
+ object->method_buckets[bucket_idx] = hash;
+
+ do {
+ size_t num_method_defs;
+ struct uverbs_method_spec *method;
+ int i;
+
+ num_method_defs =
+ get_methods_above_id(method_defs,
+ num_object_defs,
+ object_defs,
+ bucket_idx,
+ &min_id);
+ /* Last method in bucket */
+ if (!num_method_defs)
+ break;
+
+ method = build_method_with_attrs(method_defs,
+ num_method_defs);
+ if (IS_ERR(method)) {
+ res = PTR_ERR(method);
+ goto free;
+ }
+
+ /*
+ * The last tree which is given as an argument to the
+ * merge overrides previous method handler.
+ * Therefore, we iterate backwards and search for the
+ * first handler which != NULL. This also defines the
+ * set of flags used for this handler.
+ */
+ for (i = num_object_defs - 1;
+ i >= 0 && !method_defs[i]->handler; i--)
+ ;
+ hash->methods[min_id++] = method;
+ /* NULL handler isn't allowed */
+ if (WARN(i < 0,
+ "ib_uverbs: tried to merge function id %d, but all handlers are NULL\n",
+ min_id)) {
+ res = -EINVAL;
+ goto free;
+ }
+ method->handler = method_defs[i]->handler;
+ method->flags = method_defs[i]->flags;
+
+ } while (1);
+ }
+ kfree(method_defs);
+ return object;
+
+free:
+ kfree(method_defs);
+free_object:
+ free_object(object);
+ return ERR_PTR(res);
+}
+
+void uverbs_free_spec_tree(struct uverbs_root_spec *root)
+{
+ unsigned int i, j;
+
+ if (!root)
+ return;
+
+ for (i = 0; i < root->num_buckets; i++) {
+ struct uverbs_object_spec_hash *object_hash =
+ root->object_buckets[i];
+
+ if (!object_hash)
+ continue;
+
+ for (j = 0; j < object_hash->num_objects; j++)
+ free_object(object_hash->objects[j]);
+
+ kfree(object_hash);
+ }
+
+ kfree(root);
+}
+EXPORT_SYMBOL(uverbs_free_spec_tree);
+
+struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees,
+ const struct uverbs_object_tree_def **trees)
+{
+ u16 bucket_idx;
+ short max_object_buckets = 0;
+ size_t num_objects_buckets = 0;
+ struct uverbs_root_spec *root_spec = NULL;
+ const struct uverbs_object_def **object_defs;
+ int i;
+ int res = 0;
+
+ max_object_buckets = find_max_object_ns_id(num_trees, trees);
+ /*
+ * Devices which don't want to support ib_uverbs, should just allocate
+ * an empty parsing tree. Every user-space command won't hit any valid
+ * entry in the parsing tree and thus will fail.
+ */
+ if (max_object_buckets >= 0)
+ num_objects_buckets = max_object_buckets + 1;
+
+ root_spec = kzalloc(sizeof(*root_spec) +
+ num_objects_buckets * sizeof(*root_spec->object_buckets),
+ GFP_KERNEL);
+ if (!root_spec)
+ return ERR_PTR(-ENOMEM);
+ root_spec->num_buckets = num_objects_buckets;
+
+ object_defs = kcalloc(num_trees, sizeof(*object_defs),
+ GFP_KERNEL);
+ if (!object_defs) {
+ res = -ENOMEM;
+ goto free_root;
+ }
+
+ for (bucket_idx = 0; bucket_idx < root_spec->num_buckets; bucket_idx++) {
+ short min_id = SHRT_MIN;
+ short objects_max_bucket;
+ struct uverbs_object_spec_hash *hash = NULL;
+
+ objects_max_bucket = find_max_object_id(num_trees, trees,
+ bucket_idx);
+ if (objects_max_bucket < 0)
+ continue;
+
+ hash = kzalloc(sizeof(*hash) +
+ sizeof(*hash->objects) * (objects_max_bucket + 1),
+ GFP_KERNEL);
+ if (!hash) {
+ res = -ENOMEM;
+ goto free;
+ }
+ hash->num_objects = objects_max_bucket + 1;
+ root_spec->object_buckets[bucket_idx] = hash;
+
+ do {
+ size_t num_object_defs;
+ struct uverbs_object_spec *object;
+
+ num_object_defs = get_objects_above_id(object_defs,
+ num_trees,
+ trees,
+ bucket_idx,
+ &min_id);
+ /* Last object in bucket */
+ if (!num_object_defs)
+ break;
+
+ object = build_object_with_methods(object_defs,
+ num_object_defs);
+ if (IS_ERR(object)) {
+ res = PTR_ERR(object);
+ goto free;
+ }
+
+ /*
+ * The last tree which is given as an argument to the
+ * merge overrides previous object's type_attrs.
+ * Therefore, we iterate backwards and search for the
+ * first type_attrs which != NULL.
+ */
+ for (i = num_object_defs - 1;
+ i >= 0 && !object_defs[i]->type_attrs; i--)
+ ;
+ /*
+ * NULL is a valid type_attrs. It means an object we
+ * can't instantiate (like DEVICE).
+ */
+ object->type_attrs = i < 0 ? NULL :
+ object_defs[i]->type_attrs;
+
+ hash->objects[min_id++] = object;
+ } while (1);
+ }
+
+ kfree(object_defs);
+ return root_spec;
+
+free:
+ kfree(object_defs);
+free_root:
+ uverbs_free_spec_tree(root_spec);
+ return ERR_PTR(res);
+}
+EXPORT_SYMBOL(uverbs_alloc_spec_tree);
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index 5e530d2..dc2aed6 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -49,6 +49,7 @@
#include <linux/uaccess.h>
#include <rdma/ib.h>
+#include <rdma/uverbs_std_types.h>
#include "uverbs.h"
#include "core_priv.h"
@@ -595,7 +596,6 @@ struct file *ib_uverbs_alloc_async_event_file(struct ib_uverbs_file *uverbs_file
{
struct ib_uverbs_async_event_file *ev_file;
struct file *filp;
- int ret;
ev_file = kzalloc(sizeof(*ev_file), GFP_KERNEL);
if (!ev_file)
@@ -621,21 +621,11 @@ struct file *ib_uverbs_alloc_async_event_file(struct ib_uverbs_file *uverbs_file
INIT_IB_EVENT_HANDLER(&uverbs_file->event_handler,
ib_dev,
ib_uverbs_event_handler);
- ret = ib_register_event_handler(&uverbs_file->event_handler);
- if (ret)
- goto err_put_file;
-
+ ib_register_event_handler(&uverbs_file->event_handler);
/* At that point async file stuff was fully set */
return filp;
-err_put_file:
- fput(filp);
- kref_put(&uverbs_file->async_file->ref,
- ib_uverbs_release_async_event_file);
- uverbs_file->async_file = NULL;
- return ERR_PTR(ret);
-
err_put_refs:
kref_put(&ev_file->uverbs_file->ref, ib_uverbs_release_file);
kref_put(&ev_file->ref, ib_uverbs_release_async_event_file);
@@ -949,6 +939,9 @@ static const struct file_operations uverbs_fops = {
.open = ib_uverbs_open,
.release = ib_uverbs_close,
.llseek = no_llseek,
+#if IS_ENABLED(CONFIG_INFINIBAND_EXP_USER_ACCESS)
+ .unlocked_ioctl = ib_uverbs_ioctl,
+#endif
};
static const struct file_operations uverbs_mmap_fops = {
@@ -958,6 +951,9 @@ static const struct file_operations uverbs_mmap_fops = {
.open = ib_uverbs_open,
.release = ib_uverbs_close,
.llseek = no_llseek,
+#if IS_ENABLED(CONFIG_INFINIBAND_EXP_USER_ACCESS)
+ .unlocked_ioctl = ib_uverbs_ioctl,
+#endif
};
static struct ib_client uverbs_client = {
@@ -1108,6 +1104,18 @@ static void ib_uverbs_add_one(struct ib_device *device)
if (device_create_file(uverbs_dev->dev, &dev_attr_abi_version))
goto err_class;
+ if (!device->specs_root) {
+ const struct uverbs_object_tree_def *default_root[] = {
+ uverbs_default_get_objects()};
+
+ uverbs_dev->specs_root = uverbs_alloc_spec_tree(1,
+ default_root);
+ if (IS_ERR(uverbs_dev->specs_root))
+ goto err_class;
+
+ device->specs_root = uverbs_dev->specs_root;
+ }
+
ib_set_client_data(device, &uverbs_client, uverbs_dev);
return;
@@ -1239,6 +1247,11 @@ static void ib_uverbs_remove_one(struct ib_device *device, void *client_data)
ib_uverbs_comp_dev(uverbs_dev);
if (wait_clients)
wait_for_completion(&uverbs_dev->comp);
+ if (uverbs_dev->specs_root) {
+ uverbs_free_spec_tree(uverbs_dev->specs_root);
+ device->specs_root = NULL;
+ }
+
kobject_put(&uverbs_dev->kobj);
}
diff --git a/drivers/infiniband/core/uverbs_marshall.c b/drivers/infiniband/core/uverbs_marshall.c
index 94fd989..bd0acf3 100644
--- a/drivers/infiniband/core/uverbs_marshall.c
+++ b/drivers/infiniband/core/uverbs_marshall.c
@@ -33,10 +33,47 @@
#include <linux/export.h>
#include <rdma/ib_marshall.h>
-void ib_copy_ah_attr_to_user(struct ib_uverbs_ah_attr *dst,
- struct rdma_ah_attr *src)
+#define OPA_DEFAULT_GID_PREFIX cpu_to_be64(0xfe80000000000000ULL)
+static int rdma_ah_conv_opa_to_ib(struct ib_device *dev,
+ struct rdma_ah_attr *ib,
+ struct rdma_ah_attr *opa)
{
+ struct ib_port_attr port_attr;
+ int ret = 0;
+
+ /* Do structure copy and the over-write fields */
+ *ib = *opa;
+
+ ib->type = RDMA_AH_ATTR_TYPE_IB;
+ rdma_ah_set_grh(ib, NULL, 0, 0, 1, 0);
+
+ if (ib_query_port(dev, opa->port_num, &port_attr)) {
+ /* Set to default subnet to indicate error */
+ rdma_ah_set_subnet_prefix(ib, OPA_DEFAULT_GID_PREFIX);
+ ret = -EINVAL;
+ } else {
+ rdma_ah_set_subnet_prefix(ib,
+ cpu_to_be64(port_attr.subnet_prefix));
+ }
+ rdma_ah_set_interface_id(ib, OPA_MAKE_ID(rdma_ah_get_dlid(opa)));
+ return ret;
+}
+
+void ib_copy_ah_attr_to_user(struct ib_device *device,
+ struct ib_uverbs_ah_attr *dst,
+ struct rdma_ah_attr *ah_attr)
+{
+ struct rdma_ah_attr *src = ah_attr;
+ struct rdma_ah_attr conv_ah;
+
memset(&dst->grh.reserved, 0, sizeof(dst->grh.reserved));
+
+ if ((ah_attr->type == RDMA_AH_ATTR_TYPE_OPA) &&
+ (rdma_ah_get_dlid(ah_attr) >=
+ be16_to_cpu(IB_MULTICAST_LID_BASE)) &&
+ (!rdma_ah_conv_opa_to_ib(device, &conv_ah, ah_attr)))
+ src = &conv_ah;
+
dst->dlid = rdma_ah_get_dlid(src);
dst->sl = rdma_ah_get_sl(src);
dst->src_path_bits = rdma_ah_get_path_bits(src);
@@ -57,7 +94,8 @@ void ib_copy_ah_attr_to_user(struct ib_uverbs_ah_attr *dst,
}
EXPORT_SYMBOL(ib_copy_ah_attr_to_user);
-void ib_copy_qp_attr_to_user(struct ib_uverbs_qp_attr *dst,
+void ib_copy_qp_attr_to_user(struct ib_device *device,
+ struct ib_uverbs_qp_attr *dst,
struct ib_qp_attr *src)
{
dst->qp_state = src->qp_state;
@@ -76,8 +114,8 @@ void ib_copy_qp_attr_to_user(struct ib_uverbs_qp_attr *dst,
dst->max_recv_sge = src->cap.max_recv_sge;
dst->max_inline_data = src->cap.max_inline_data;
- ib_copy_ah_attr_to_user(&dst->ah_attr, &src->ah_attr);
- ib_copy_ah_attr_to_user(&dst->alt_ah_attr, &src->alt_ah_attr);
+ ib_copy_ah_attr_to_user(device, &dst->ah_attr, &src->ah_attr);
+ ib_copy_ah_attr_to_user(device, &dst->alt_ah_attr, &src->alt_ah_attr);
dst->pkey_index = src->pkey_index;
dst->alt_pkey_index = src->alt_pkey_index;
diff --git a/drivers/infiniband/core/uverbs_std_types.c b/drivers/infiniband/core/uverbs_std_types.c
index ef29337..0a98579 100644
--- a/drivers/infiniband/core/uverbs_std_types.c
+++ b/drivers/infiniband/core/uverbs_std_types.c
@@ -209,67 +209,244 @@ static int uverbs_hot_unplug_completion_event_file(struct ib_uobject_file *uobj_
return 0;
};
-const struct uverbs_obj_fd_type uverbs_type_attrs_comp_channel = {
- .type = UVERBS_TYPE_ALLOC_FD(sizeof(struct ib_uverbs_completion_event_file), 0),
- .context_closed = uverbs_hot_unplug_completion_event_file,
- .fops = &uverbs_event_fops,
- .name = "[infinibandevent]",
- .flags = O_RDONLY,
-};
+/*
+ * This spec is used in order to pass information to the hardware driver in a
+ * legacy way. Every verb that could get driver specific data should get this
+ * spec.
+ */
+static const struct uverbs_attr_def uverbs_uhw_compat_in =
+ UVERBS_ATTR_PTR_IN_SZ(UVERBS_UHW_IN, 0, UA_FLAGS(UVERBS_ATTR_SPEC_F_MIN_SZ));
+static const struct uverbs_attr_def uverbs_uhw_compat_out =
+ UVERBS_ATTR_PTR_OUT_SZ(UVERBS_UHW_OUT, 0, UA_FLAGS(UVERBS_ATTR_SPEC_F_MIN_SZ));
-const struct uverbs_obj_idr_type uverbs_type_attrs_cq = {
- .type = UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_ucq_object), 0),
- .destroy_object = uverbs_free_cq,
-};
+static void create_udata(struct uverbs_attr_bundle *ctx,
+ struct ib_udata *udata)
+{
+ /*
+ * This is for ease of conversion. The purpose is to convert all drivers
+ * to use uverbs_attr_bundle instead of ib_udata.
+ * Assume attr == 0 is input and attr == 1 is output.
+ */
+ void __user *inbuf;
+ size_t inbuf_len = 0;
+ void __user *outbuf;
+ size_t outbuf_len = 0;
+ const struct uverbs_attr *uhw_in =
+ uverbs_attr_get(ctx, UVERBS_UHW_IN);
+ const struct uverbs_attr *uhw_out =
+ uverbs_attr_get(ctx, UVERBS_UHW_OUT);
+
+ if (!IS_ERR(uhw_in)) {
+ inbuf = uhw_in->ptr_attr.ptr;
+ inbuf_len = uhw_in->ptr_attr.len;
+ }
-const struct uverbs_obj_idr_type uverbs_type_attrs_qp = {
- .type = UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_uqp_object), 0),
- .destroy_object = uverbs_free_qp,
-};
+ if (!IS_ERR(uhw_out)) {
+ outbuf = uhw_out->ptr_attr.ptr;
+ outbuf_len = uhw_out->ptr_attr.len;
+ }
-const struct uverbs_obj_idr_type uverbs_type_attrs_mw = {
- .type = UVERBS_TYPE_ALLOC_IDR(0),
- .destroy_object = uverbs_free_mw,
-};
+ INIT_UDATA_BUF_OR_NULL(udata, inbuf, outbuf, inbuf_len, outbuf_len);
+}
-const struct uverbs_obj_idr_type uverbs_type_attrs_mr = {
- /* 1 is used in order to free the MR after all the MWs */
- .type = UVERBS_TYPE_ALLOC_IDR(1),
- .destroy_object = uverbs_free_mr,
-};
+static int uverbs_create_cq_handler(struct ib_device *ib_dev,
+ struct ib_uverbs_file *file,
+ struct uverbs_attr_bundle *attrs)
+{
+ struct ib_ucontext *ucontext = file->ucontext;
+ struct ib_ucq_object *obj;
+ struct ib_udata uhw;
+ int ret;
+ u64 user_handle;
+ struct ib_cq_init_attr attr = {};
+ struct ib_cq *cq;
+ struct ib_uverbs_completion_event_file *ev_file = NULL;
+ const struct uverbs_attr *ev_file_attr;
+ struct ib_uobject *ev_file_uobj;
+
+ if (!(ib_dev->uverbs_cmd_mask & 1ULL << IB_USER_VERBS_CMD_CREATE_CQ))
+ return -EOPNOTSUPP;
+
+ ret = uverbs_copy_from(&attr.comp_vector, attrs, CREATE_CQ_COMP_VECTOR);
+ if (!ret)
+ ret = uverbs_copy_from(&attr.cqe, attrs, CREATE_CQ_CQE);
+ if (!ret)
+ ret = uverbs_copy_from(&user_handle, attrs, CREATE_CQ_USER_HANDLE);
+ if (ret)
+ return ret;
-const struct uverbs_obj_idr_type uverbs_type_attrs_srq = {
- .type = UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_usrq_object), 0),
- .destroy_object = uverbs_free_srq,
-};
+ /* Optional param, if it doesn't exist, we get -ENOENT and skip it */
+ if (uverbs_copy_from(&attr.flags, attrs, CREATE_CQ_FLAGS) == -EFAULT)
+ return -EFAULT;
-const struct uverbs_obj_idr_type uverbs_type_attrs_ah = {
- .type = UVERBS_TYPE_ALLOC_IDR(0),
- .destroy_object = uverbs_free_ah,
-};
+ ev_file_attr = uverbs_attr_get(attrs, CREATE_CQ_COMP_CHANNEL);
+ if (!IS_ERR(ev_file_attr)) {
+ ev_file_uobj = ev_file_attr->obj_attr.uobject;
-const struct uverbs_obj_idr_type uverbs_type_attrs_flow = {
- .type = UVERBS_TYPE_ALLOC_IDR(0),
- .destroy_object = uverbs_free_flow,
-};
+ ev_file = container_of(ev_file_uobj,
+ struct ib_uverbs_completion_event_file,
+ uobj_file.uobj);
+ uverbs_uobject_get(ev_file_uobj);
+ }
-const struct uverbs_obj_idr_type uverbs_type_attrs_wq = {
- .type = UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_uwq_object), 0),
- .destroy_object = uverbs_free_wq,
-};
+ if (attr.comp_vector >= ucontext->ufile->device->num_comp_vectors) {
+ ret = -EINVAL;
+ goto err_event_file;
+ }
-const struct uverbs_obj_idr_type uverbs_type_attrs_rwq_ind_table = {
- .type = UVERBS_TYPE_ALLOC_IDR(0),
- .destroy_object = uverbs_free_rwq_ind_tbl,
-};
+ obj = container_of(uverbs_attr_get(attrs, CREATE_CQ_HANDLE)->obj_attr.uobject,
+ typeof(*obj), uobject);
+ obj->uverbs_file = ucontext->ufile;
+ obj->comp_events_reported = 0;
+ obj->async_events_reported = 0;
+ INIT_LIST_HEAD(&obj->comp_list);
+ INIT_LIST_HEAD(&obj->async_list);
+
+ /* Temporary, only until drivers get the new uverbs_attr_bundle */
+ create_udata(attrs, &uhw);
+
+ cq = ib_dev->create_cq(ib_dev, &attr, ucontext, &uhw);
+ if (IS_ERR(cq)) {
+ ret = PTR_ERR(cq);
+ goto err_event_file;
+ }
-const struct uverbs_obj_idr_type uverbs_type_attrs_xrcd = {
- .type = UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_uxrcd_object), 0),
- .destroy_object = uverbs_free_xrcd,
-};
+ cq->device = ib_dev;
+ cq->uobject = &obj->uobject;
+ cq->comp_handler = ib_uverbs_comp_handler;
+ cq->event_handler = ib_uverbs_cq_event_handler;
+ cq->cq_context = &ev_file->ev_queue;
+ obj->uobject.object = cq;
+ obj->uobject.user_handle = user_handle;
+ atomic_set(&cq->usecnt, 0);
+
+ ret = uverbs_copy_to(attrs, CREATE_CQ_RESP_CQE, &cq->cqe);
+ if (ret)
+ goto err_cq;
-const struct uverbs_obj_idr_type uverbs_type_attrs_pd = {
- /* 2 is used in order to free the PD after MRs */
- .type = UVERBS_TYPE_ALLOC_IDR(2),
- .destroy_object = uverbs_free_pd,
+ return 0;
+err_cq:
+ ib_destroy_cq(cq);
+
+err_event_file:
+ if (ev_file)
+ uverbs_uobject_put(ev_file_uobj);
+ return ret;
};
+
+static DECLARE_UVERBS_METHOD(
+ uverbs_method_cq_create, UVERBS_CQ_CREATE, uverbs_create_cq_handler,
+ &UVERBS_ATTR_IDR(CREATE_CQ_HANDLE, UVERBS_OBJECT_CQ, UVERBS_ACCESS_NEW,
+ UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
+ &UVERBS_ATTR_PTR_IN(CREATE_CQ_CQE, u32,
+ UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
+ &UVERBS_ATTR_PTR_IN(CREATE_CQ_USER_HANDLE, u64,
+ UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
+ &UVERBS_ATTR_FD(CREATE_CQ_COMP_CHANNEL, UVERBS_OBJECT_COMP_CHANNEL,
+ UVERBS_ACCESS_READ),
+ &UVERBS_ATTR_PTR_IN(CREATE_CQ_COMP_VECTOR, u32,
+ UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
+ &UVERBS_ATTR_PTR_IN(CREATE_CQ_FLAGS, u32),
+ &UVERBS_ATTR_PTR_OUT(CREATE_CQ_RESP_CQE, u32,
+ UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
+ &uverbs_uhw_compat_in, &uverbs_uhw_compat_out);
+
+static int uverbs_destroy_cq_handler(struct ib_device *ib_dev,
+ struct ib_uverbs_file *file,
+ struct uverbs_attr_bundle *attrs)
+{
+ struct ib_uverbs_destroy_cq_resp resp;
+ struct ib_uobject *uobj =
+ uverbs_attr_get(attrs, DESTROY_CQ_HANDLE)->obj_attr.uobject;
+ struct ib_ucq_object *obj = container_of(uobj, struct ib_ucq_object,
+ uobject);
+ int ret;
+
+ if (!(ib_dev->uverbs_cmd_mask & 1ULL << IB_USER_VERBS_CMD_DESTROY_CQ))
+ return -EOPNOTSUPP;
+
+ ret = rdma_explicit_destroy(uobj);
+ if (ret)
+ return ret;
+
+ resp.comp_events_reported = obj->comp_events_reported;
+ resp.async_events_reported = obj->async_events_reported;
+
+ return uverbs_copy_to(attrs, DESTROY_CQ_RESP, &resp);
+}
+
+static DECLARE_UVERBS_METHOD(
+ uverbs_method_cq_destroy, UVERBS_CQ_DESTROY, uverbs_destroy_cq_handler,
+ &UVERBS_ATTR_IDR(DESTROY_CQ_HANDLE, UVERBS_OBJECT_CQ,
+ UVERBS_ACCESS_DESTROY,
+ UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
+ &UVERBS_ATTR_PTR_OUT(DESTROY_CQ_RESP, struct ib_uverbs_destroy_cq_resp,
+ UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)));
+
+DECLARE_UVERBS_OBJECT(uverbs_object_comp_channel,
+ UVERBS_OBJECT_COMP_CHANNEL,
+ &UVERBS_TYPE_ALLOC_FD(0,
+ sizeof(struct ib_uverbs_completion_event_file),
+ uverbs_hot_unplug_completion_event_file,
+ &uverbs_event_fops,
+ "[infinibandevent]", O_RDONLY));
+
+DECLARE_UVERBS_OBJECT(uverbs_object_cq, UVERBS_OBJECT_CQ,
+ &UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_ucq_object), 0,
+ uverbs_free_cq),
+ &uverbs_method_cq_create,
+ &uverbs_method_cq_destroy);
+
+DECLARE_UVERBS_OBJECT(uverbs_object_qp, UVERBS_OBJECT_QP,
+ &UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_uqp_object), 0,
+ uverbs_free_qp));
+
+DECLARE_UVERBS_OBJECT(uverbs_object_mw, UVERBS_OBJECT_MW,
+ &UVERBS_TYPE_ALLOC_IDR(0, uverbs_free_mw));
+
+DECLARE_UVERBS_OBJECT(uverbs_object_mr, UVERBS_OBJECT_MR,
+ /* 1 is used in order to free the MR after all the MWs */
+ &UVERBS_TYPE_ALLOC_IDR(1, uverbs_free_mr));
+
+DECLARE_UVERBS_OBJECT(uverbs_object_srq, UVERBS_OBJECT_SRQ,
+ &UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_usrq_object), 0,
+ uverbs_free_srq));
+
+DECLARE_UVERBS_OBJECT(uverbs_object_ah, UVERBS_OBJECT_AH,
+ &UVERBS_TYPE_ALLOC_IDR(0, uverbs_free_ah));
+
+DECLARE_UVERBS_OBJECT(uverbs_object_flow, UVERBS_OBJECT_FLOW,
+ &UVERBS_TYPE_ALLOC_IDR(0, uverbs_free_flow));
+
+DECLARE_UVERBS_OBJECT(uverbs_object_wq, UVERBS_OBJECT_WQ,
+ &UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_uwq_object), 0,
+ uverbs_free_wq));
+
+DECLARE_UVERBS_OBJECT(uverbs_object_rwq_ind_table,
+ UVERBS_OBJECT_RWQ_IND_TBL,
+ &UVERBS_TYPE_ALLOC_IDR(0, uverbs_free_rwq_ind_tbl));
+
+DECLARE_UVERBS_OBJECT(uverbs_object_xrcd, UVERBS_OBJECT_XRCD,
+ &UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_uxrcd_object), 0,
+ uverbs_free_xrcd));
+
+DECLARE_UVERBS_OBJECT(uverbs_object_pd, UVERBS_OBJECT_PD,
+ /* 2 is used in order to free the PD after MRs */
+ &UVERBS_TYPE_ALLOC_IDR(2, uverbs_free_pd));
+
+DECLARE_UVERBS_OBJECT(uverbs_object_device, UVERBS_OBJECT_DEVICE, NULL);
+
+DECLARE_UVERBS_OBJECT_TREE(uverbs_default_objects,
+ &uverbs_object_device,
+ &uverbs_object_pd,
+ &uverbs_object_mr,
+ &uverbs_object_comp_channel,
+ &uverbs_object_cq,
+ &uverbs_object_qp,
+ &uverbs_object_ah,
+ &uverbs_object_mw,
+ &uverbs_object_srq,
+ &uverbs_object_flow,
+ &uverbs_object_wq,
+ &uverbs_object_rwq_ind_table,
+ &uverbs_object_xrcd);
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index b456e3c..ee9e27d 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -180,39 +180,29 @@ EXPORT_SYMBOL(ib_rate_to_mbps);
__attribute_const__ enum rdma_transport_type
rdma_node_get_transport(enum rdma_node_type node_type)
{
- switch (node_type) {
- case RDMA_NODE_IB_CA:
- case RDMA_NODE_IB_SWITCH:
- case RDMA_NODE_IB_ROUTER:
- return RDMA_TRANSPORT_IB;
- case RDMA_NODE_RNIC:
- return RDMA_TRANSPORT_IWARP;
- case RDMA_NODE_USNIC:
+
+ if (node_type == RDMA_NODE_USNIC)
return RDMA_TRANSPORT_USNIC;
- case RDMA_NODE_USNIC_UDP:
+ if (node_type == RDMA_NODE_USNIC_UDP)
return RDMA_TRANSPORT_USNIC_UDP;
- default:
- BUG();
- return 0;
- }
+ if (node_type == RDMA_NODE_RNIC)
+ return RDMA_TRANSPORT_IWARP;
+
+ return RDMA_TRANSPORT_IB;
}
EXPORT_SYMBOL(rdma_node_get_transport);
enum rdma_link_layer rdma_port_get_link_layer(struct ib_device *device, u8 port_num)
{
+ enum rdma_transport_type lt;
if (device->get_link_layer)
return device->get_link_layer(device, port_num);
- switch (rdma_node_get_transport(device->node_type)) {
- case RDMA_TRANSPORT_IB:
+ lt = rdma_node_get_transport(device->node_type);
+ if (lt == RDMA_TRANSPORT_IB)
return IB_LINK_LAYER_INFINIBAND;
- case RDMA_TRANSPORT_IWARP:
- case RDMA_TRANSPORT_USNIC:
- case RDMA_TRANSPORT_USNIC_UDP:
- return IB_LINK_LAYER_ETHERNET;
- default:
- return IB_LINK_LAYER_UNSPECIFIED;
- }
+
+ return IB_LINK_LAYER_ETHERNET;
}
EXPORT_SYMBOL(rdma_port_get_link_layer);
@@ -478,6 +468,8 @@ int ib_init_ah_from_wc(struct ib_device *device, u8 port_num,
union ib_gid dgid;
union ib_gid sgid;
+ might_sleep();
+
memset(ah_attr, 0, sizeof *ah_attr);
ah_attr->type = rdma_ah_find_type(device, port_num);
if (rdma_cap_eth_ah(device, port_num)) {
@@ -632,11 +624,13 @@ struct ib_srq *ib_create_srq(struct ib_pd *pd,
srq->event_handler = srq_init_attr->event_handler;
srq->srq_context = srq_init_attr->srq_context;
srq->srq_type = srq_init_attr->srq_type;
+ if (ib_srq_has_cq(srq->srq_type)) {
+ srq->ext.cq = srq_init_attr->ext.cq;
+ atomic_inc(&srq->ext.cq->usecnt);
+ }
if (srq->srq_type == IB_SRQT_XRC) {
srq->ext.xrc.xrcd = srq_init_attr->ext.xrc.xrcd;
- srq->ext.xrc.cq = srq_init_attr->ext.xrc.cq;
atomic_inc(&srq->ext.xrc.xrcd->usecnt);
- atomic_inc(&srq->ext.xrc.cq->usecnt);
}
atomic_inc(&pd->usecnt);
atomic_set(&srq->usecnt, 0);
@@ -677,18 +671,18 @@ int ib_destroy_srq(struct ib_srq *srq)
pd = srq->pd;
srq_type = srq->srq_type;
- if (srq_type == IB_SRQT_XRC) {
+ if (ib_srq_has_cq(srq_type))
+ cq = srq->ext.cq;
+ if (srq_type == IB_SRQT_XRC)
xrcd = srq->ext.xrc.xrcd;
- cq = srq->ext.xrc.cq;
- }
ret = srq->device->destroy_srq(srq);
if (!ret) {
atomic_dec(&pd->usecnt);
- if (srq_type == IB_SRQT_XRC) {
+ if (srq_type == IB_SRQT_XRC)
atomic_dec(&xrcd->usecnt);
+ if (ib_srq_has_cq(srq_type))
atomic_dec(&cq->usecnt);
- }
}
return ret;
@@ -1244,6 +1238,18 @@ int ib_resolve_eth_dmac(struct ib_device *device,
if (rdma_link_local_addr((struct in6_addr *)grh->dgid.raw)) {
rdma_get_ll_mac((struct in6_addr *)grh->dgid.raw,
ah_attr->roce.dmac);
+ return 0;
+ }
+ if (rdma_is_multicast_addr((struct in6_addr *)ah_attr->grh.dgid.raw)) {
+ if (ipv6_addr_v4mapped((struct in6_addr *)ah_attr->grh.dgid.raw)) {
+ __be32 addr = 0;
+
+ memcpy(&addr, ah_attr->grh.dgid.raw + 12, 4);
+ ip_eth_mc_map(addr, (char *)ah_attr->roce.dmac);
+ } else {
+ ipv6_eth_mc_map((struct in6_addr *)ah_attr->grh.dgid.raw,
+ (char *)ah_attr->roce.dmac);
+ }
} else {
union ib_gid sgid;
struct ib_gid_attr sgid_attr;
@@ -1306,6 +1312,61 @@ int ib_modify_qp_with_udata(struct ib_qp *qp, struct ib_qp_attr *attr,
}
EXPORT_SYMBOL(ib_modify_qp_with_udata);
+int ib_get_eth_speed(struct ib_device *dev, u8 port_num, u8 *speed, u8 *width)
+{
+ int rc;
+ u32 netdev_speed;
+ struct net_device *netdev;
+ struct ethtool_link_ksettings lksettings;
+
+ if (rdma_port_get_link_layer(dev, port_num) != IB_LINK_LAYER_ETHERNET)
+ return -EINVAL;
+
+ if (!dev->get_netdev)
+ return -EOPNOTSUPP;
+
+ netdev = dev->get_netdev(dev, port_num);
+ if (!netdev)
+ return -ENODEV;
+
+ rtnl_lock();
+ rc = __ethtool_get_link_ksettings(netdev, &lksettings);
+ rtnl_unlock();
+
+ dev_put(netdev);
+
+ if (!rc) {
+ netdev_speed = lksettings.base.speed;
+ } else {
+ netdev_speed = SPEED_1000;
+ pr_warn("%s speed is unknown, defaulting to %d\n", netdev->name,
+ netdev_speed);
+ }
+
+ if (netdev_speed <= SPEED_1000) {
+ *width = IB_WIDTH_1X;
+ *speed = IB_SPEED_SDR;
+ } else if (netdev_speed <= SPEED_10000) {
+ *width = IB_WIDTH_1X;
+ *speed = IB_SPEED_FDR10;
+ } else if (netdev_speed <= SPEED_20000) {
+ *width = IB_WIDTH_4X;
+ *speed = IB_SPEED_DDR;
+ } else if (netdev_speed <= SPEED_25000) {
+ *width = IB_WIDTH_1X;
+ *speed = IB_SPEED_EDR;
+ } else if (netdev_speed <= SPEED_40000) {
+ *width = IB_WIDTH_4X;
+ *speed = IB_SPEED_FDR10;
+ } else {
+ *width = IB_WIDTH_4X;
+ *speed = IB_SPEED_EDR;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(ib_get_eth_speed);
+
int ib_modify_qp(struct ib_qp *qp,
struct ib_qp_attr *qp_attr,
int qp_attr_mask)
@@ -1573,15 +1634,53 @@ EXPORT_SYMBOL(ib_dealloc_fmr);
/* Multicast groups */
+static bool is_valid_mcast_lid(struct ib_qp *qp, u16 lid)
+{
+ struct ib_qp_init_attr init_attr = {};
+ struct ib_qp_attr attr = {};
+ int num_eth_ports = 0;
+ int port;
+
+ /* If QP state >= init, it is assigned to a port and we can check this
+ * port only.
+ */
+ if (!ib_query_qp(qp, &attr, IB_QP_STATE | IB_QP_PORT, &init_attr)) {
+ if (attr.qp_state >= IB_QPS_INIT) {
+ if (qp->device->get_link_layer(qp->device, attr.port_num) !=
+ IB_LINK_LAYER_INFINIBAND)
+ return true;
+ goto lid_check;
+ }
+ }
+
+ /* Can't get a quick answer, iterate over all ports */
+ for (port = 0; port < qp->device->phys_port_cnt; port++)
+ if (qp->device->get_link_layer(qp->device, port) !=
+ IB_LINK_LAYER_INFINIBAND)
+ num_eth_ports++;
+
+ /* If we have at lease one Ethernet port, RoCE annex declares that
+ * multicast LID should be ignored. We can't tell at this step if the
+ * QP belongs to an IB or Ethernet port.
+ */
+ if (num_eth_ports)
+ return true;
+
+ /* If all the ports are IB, we can check according to IB spec. */
+lid_check:
+ return !(lid < be16_to_cpu(IB_MULTICAST_LID_BASE) ||
+ lid == be16_to_cpu(IB_LID_PERMISSIVE));
+}
+
int ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
{
int ret;
if (!qp->device->attach_mcast)
return -ENOSYS;
- if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD ||
- lid < be16_to_cpu(IB_MULTICAST_LID_BASE) ||
- lid == be16_to_cpu(IB_LID_PERMISSIVE))
+
+ if (!rdma_is_multicast_addr((struct in6_addr *)gid->raw) ||
+ qp->qp_type != IB_QPT_UD || !is_valid_mcast_lid(qp, lid))
return -EINVAL;
ret = qp->device->attach_mcast(qp, gid, lid);
@@ -1597,9 +1696,9 @@ int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
if (!qp->device->detach_mcast)
return -ENOSYS;
- if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD ||
- lid < be16_to_cpu(IB_MULTICAST_LID_BASE) ||
- lid == be16_to_cpu(IB_LID_PERMISSIVE))
+
+ if (!rdma_is_multicast_addr((struct in6_addr *)gid->raw) ||
+ qp->qp_type != IB_QPT_UD || !is_valid_mcast_lid(qp, lid))
return -EINVAL;
ret = qp->device->detach_mcast(qp, gid, lid);
diff --git a/drivers/infiniband/hw/bnxt_re/Makefile b/drivers/infiniband/hw/bnxt_re/Makefile
index 036f84e..afbaa0e 100644
--- a/drivers/infiniband/hw/bnxt_re/Makefile
+++ b/drivers/infiniband/hw/bnxt_re/Makefile
@@ -3,4 +3,4 @@ ccflags-y := -Idrivers/net/ethernet/broadcom/bnxt
obj-$(CONFIG_INFINIBAND_BNXT_RE) += bnxt_re.o
bnxt_re-y := main.o ib_verbs.o \
qplib_res.o qplib_rcfw.o \
- qplib_sp.o qplib_fp.o
+ qplib_sp.o qplib_fp.o hw_counters.o
diff --git a/drivers/infiniband/hw/bnxt_re/bnxt_re.h b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
index 8552753..b3ad37f 100644
--- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h
+++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
@@ -85,7 +85,7 @@ struct bnxt_re_sqp_entries {
};
#define BNXT_RE_MIN_MSIX 2
-#define BNXT_RE_MAX_MSIX 16
+#define BNXT_RE_MAX_MSIX 9
#define BNXT_RE_AEQ_IDX 0
#define BNXT_RE_NQ_IDX 1
@@ -116,7 +116,7 @@ struct bnxt_re_dev {
struct bnxt_qplib_rcfw rcfw;
/* NQ */
- struct bnxt_qplib_nq nq;
+ struct bnxt_qplib_nq nq[BNXT_RE_MAX_MSIX];
/* Device Resources */
struct bnxt_qplib_dev_attr dev_attr;
@@ -140,6 +140,7 @@ struct bnxt_re_dev {
struct bnxt_re_qp *qp1_sqp;
struct bnxt_re_ah *sqp_ah;
struct bnxt_re_sqp_entries sqp_tbl[1024];
+ atomic_t nq_alloc_cnt;
};
#define to_bnxt_re_dev(ptr, member) \
diff --git a/drivers/infiniband/hw/bnxt_re/hw_counters.c b/drivers/infiniband/hw/bnxt_re/hw_counters.c
new file mode 100644
index 0000000..7b28219
--- /dev/null
+++ b/drivers/infiniband/hw/bnxt_re/hw_counters.c
@@ -0,0 +1,114 @@
+/*
+ * Broadcom NetXtreme-E RoCE driver.
+ *
+ * Copyright (c) 2016 - 2017, Broadcom. All rights reserved. The term
+ * Broadcom refers to Broadcom Limited and/or its subsidiaries.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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.
+ *
+ * Description: Statistics
+ *
+ */
+
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/prefetch.h>
+#include <linux/delay.h>
+
+#include <rdma/ib_addr.h>
+
+#include "bnxt_ulp.h"
+#include "roce_hsi.h"
+#include "qplib_res.h"
+#include "qplib_sp.h"
+#include "qplib_fp.h"
+#include "qplib_rcfw.h"
+#include "bnxt_re.h"
+#include "hw_counters.h"
+
+static const char * const bnxt_re_stat_name[] = {
+ [BNXT_RE_ACTIVE_QP] = "active_qps",
+ [BNXT_RE_ACTIVE_SRQ] = "active_srqs",
+ [BNXT_RE_ACTIVE_CQ] = "active_cqs",
+ [BNXT_RE_ACTIVE_MR] = "active_mrs",
+ [BNXT_RE_ACTIVE_MW] = "active_mws",
+ [BNXT_RE_RX_PKTS] = "rx_pkts",
+ [BNXT_RE_RX_BYTES] = "rx_bytes",
+ [BNXT_RE_TX_PKTS] = "tx_pkts",
+ [BNXT_RE_TX_BYTES] = "tx_bytes",
+ [BNXT_RE_RECOVERABLE_ERRORS] = "recoverable_errors"
+};
+
+int bnxt_re_ib_get_hw_stats(struct ib_device *ibdev,
+ struct rdma_hw_stats *stats,
+ u8 port, int index)
+{
+ struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev);
+ struct ctx_hw_stats *bnxt_re_stats = rdev->qplib_ctx.stats.dma;
+
+ if (!port || !stats)
+ return -EINVAL;
+
+ stats->value[BNXT_RE_ACTIVE_QP] = atomic_read(&rdev->qp_count);
+ stats->value[BNXT_RE_ACTIVE_SRQ] = atomic_read(&rdev->srq_count);
+ stats->value[BNXT_RE_ACTIVE_CQ] = atomic_read(&rdev->cq_count);
+ stats->value[BNXT_RE_ACTIVE_MR] = atomic_read(&rdev->mr_count);
+ stats->value[BNXT_RE_ACTIVE_MW] = atomic_read(&rdev->mw_count);
+ if (bnxt_re_stats) {
+ stats->value[BNXT_RE_RECOVERABLE_ERRORS] =
+ le64_to_cpu(bnxt_re_stats->tx_bcast_pkts);
+ stats->value[BNXT_RE_RX_PKTS] =
+ le64_to_cpu(bnxt_re_stats->rx_ucast_pkts);
+ stats->value[BNXT_RE_RX_BYTES] =
+ le64_to_cpu(bnxt_re_stats->rx_ucast_bytes);
+ stats->value[BNXT_RE_TX_PKTS] =
+ le64_to_cpu(bnxt_re_stats->tx_ucast_pkts);
+ stats->value[BNXT_RE_TX_BYTES] =
+ le64_to_cpu(bnxt_re_stats->tx_ucast_bytes);
+ }
+ return ARRAY_SIZE(bnxt_re_stat_name);
+}
+
+struct rdma_hw_stats *bnxt_re_ib_alloc_hw_stats(struct ib_device *ibdev,
+ u8 port_num)
+{
+ BUILD_BUG_ON(ARRAY_SIZE(bnxt_re_stat_name) != BNXT_RE_NUM_COUNTERS);
+ /* We support only per port stats */
+ if (!port_num)
+ return NULL;
+
+ return rdma_alloc_hw_stats_struct(bnxt_re_stat_name,
+ ARRAY_SIZE(bnxt_re_stat_name),
+ RDMA_HW_STATS_DEFAULT_LIFESPAN);
+}
diff --git a/drivers/infiniband/hw/bnxt_re/hw_counters.h b/drivers/infiniband/hw/bnxt_re/hw_counters.h
new file mode 100644
index 0000000..be0dc00
--- /dev/null
+++ b/drivers/infiniband/hw/bnxt_re/hw_counters.h
@@ -0,0 +1,62 @@
+/*
+ * Broadcom NetXtreme-E RoCE driver.
+ *
+ * Copyright (c) 2016 - 2017, Broadcom. All rights reserved. The term
+ * Broadcom refers to Broadcom Limited and/or its subsidiaries.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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.
+ *
+ * Description: Statistics (header)
+ *
+ */
+
+#ifndef __BNXT_RE_HW_STATS_H__
+#define __BNXT_RE_HW_STATS_H__
+
+enum bnxt_re_hw_stats {
+ BNXT_RE_ACTIVE_QP,
+ BNXT_RE_ACTIVE_SRQ,
+ BNXT_RE_ACTIVE_CQ,
+ BNXT_RE_ACTIVE_MR,
+ BNXT_RE_ACTIVE_MW,
+ BNXT_RE_RX_PKTS,
+ BNXT_RE_RX_BYTES,
+ BNXT_RE_TX_PKTS,
+ BNXT_RE_TX_BYTES,
+ BNXT_RE_RECOVERABLE_ERRORS,
+ BNXT_RE_NUM_COUNTERS
+};
+
+struct rdma_hw_stats *bnxt_re_ib_alloc_hw_stats(struct ib_device *ibdev,
+ u8 port_num);
+int bnxt_re_ib_get_hw_stats(struct ib_device *ibdev,
+ struct rdma_hw_stats *stats,
+ u8 port, int index);
+#endif /* __BNXT_RE_HW_STATS_H__ */
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index f0e01b3..01eee15 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -223,50 +223,6 @@ int bnxt_re_modify_device(struct ib_device *ibdev,
return 0;
}
-static void __to_ib_speed_width(struct net_device *netdev, u8 *speed, u8 *width)
-{
- struct ethtool_link_ksettings lksettings;
- u32 espeed;
-
- if (netdev->ethtool_ops && netdev->ethtool_ops->get_link_ksettings) {
- memset(&lksettings, 0, sizeof(lksettings));
- rtnl_lock();
- netdev->ethtool_ops->get_link_ksettings(netdev, &lksettings);
- rtnl_unlock();
- espeed = lksettings.base.speed;
- } else {
- espeed = SPEED_UNKNOWN;
- }
- switch (espeed) {
- case SPEED_1000:
- *speed = IB_SPEED_SDR;
- *width = IB_WIDTH_1X;
- break;
- case SPEED_10000:
- *speed = IB_SPEED_QDR;
- *width = IB_WIDTH_1X;
- break;
- case SPEED_20000:
- *speed = IB_SPEED_DDR;
- *width = IB_WIDTH_4X;
- break;
- case SPEED_25000:
- *speed = IB_SPEED_EDR;
- *width = IB_WIDTH_1X;
- break;
- case SPEED_40000:
- *speed = IB_SPEED_QDR;
- *width = IB_WIDTH_4X;
- break;
- case SPEED_50000:
- break;
- default:
- *speed = IB_SPEED_SDR;
- *width = IB_WIDTH_1X;
- break;
- }
-}
-
/* Port */
int bnxt_re_query_port(struct ib_device *ibdev, u8 port_num,
struct ib_port_attr *port_attr)
@@ -308,25 +264,9 @@ int bnxt_re_query_port(struct ib_device *ibdev, u8 port_num,
* IB stack to avoid race in the NETDEV_UNREG path
*/
if (test_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags))
- __to_ib_speed_width(rdev->netdev, &port_attr->active_speed,
- &port_attr->active_width);
- return 0;
-}
-
-int bnxt_re_modify_port(struct ib_device *ibdev, u8 port_num,
- int port_modify_mask,
- struct ib_port_modify *port_modify)
-{
- switch (port_modify_mask) {
- case IB_PORT_SHUTDOWN:
- break;
- case IB_PORT_INIT_TYPE:
- break;
- case IB_PORT_RESET_QKEY_CNTR:
- break;
- default:
- break;
- }
+ if (ib_get_eth_speed(ibdev, port_num, &port_attr->active_speed,
+ &port_attr->active_width))
+ return -EINVAL;
return 0;
}
@@ -846,6 +786,7 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp)
struct bnxt_re_dev *rdev = qp->rdev;
int rc;
+ bnxt_qplib_del_flush_qp(&qp->qplib_qp);
rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &qp->qplib_qp);
if (rc) {
dev_err(rdev_to_dev(rdev), "Failed to destroy HW QP");
@@ -860,6 +801,7 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp)
return rc;
}
+ bnxt_qplib_del_flush_qp(&qp->qplib_qp);
rc = bnxt_qplib_destroy_qp(&rdev->qplib_res,
&rdev->qp1_sqp->qplib_qp);
if (rc) {
@@ -969,7 +911,6 @@ static struct bnxt_re_ah *bnxt_re_create_shadow_qp_ah
if (!ah)
return NULL;
- memset(ah, 0, sizeof(*ah));
ah->rdev = rdev;
ah->qplib_ah.pd = &pd->qplib_pd;
@@ -1016,7 +957,6 @@ static struct bnxt_re_qp *bnxt_re_create_shadow_qp
if (!qp)
return NULL;
- memset(qp, 0, sizeof(*qp));
qp->rdev = rdev;
/* Initialize the shadow QP structure from the QP1 values */
@@ -1404,6 +1344,21 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr,
}
qp->qplib_qp.modify_flags |= CMDQ_MODIFY_QP_MODIFY_MASK_STATE;
qp->qplib_qp.state = __from_ib_qp_state(qp_attr->qp_state);
+
+ if (!qp->sumem &&
+ qp->qplib_qp.state == CMDQ_MODIFY_QP_NEW_STATE_ERR) {
+ dev_dbg(rdev_to_dev(rdev),
+ "Move QP = %p to flush list\n",
+ qp);
+ bnxt_qplib_add_flush_qp(&qp->qplib_qp);
+ }
+ if (!qp->sumem &&
+ qp->qplib_qp.state == CMDQ_MODIFY_QP_NEW_STATE_RESET) {
+ dev_dbg(rdev_to_dev(rdev),
+ "Move QP = %p out of flush list\n",
+ qp);
+ bnxt_qplib_del_flush_qp(&qp->qplib_qp);
+ }
}
if (qp_attr_mask & IB_QP_EN_SQD_ASYNC_NOTIFY) {
qp->qplib_qp.modify_flags |=
@@ -2333,6 +2288,7 @@ int bnxt_re_destroy_cq(struct ib_cq *ib_cq)
struct bnxt_re_cq *cq = container_of(ib_cq, struct bnxt_re_cq, ib_cq);
struct bnxt_re_dev *rdev = cq->rdev;
int rc;
+ struct bnxt_qplib_nq *nq = cq->qplib_cq.nq;
rc = bnxt_qplib_destroy_cq(&rdev->qplib_res, &cq->qplib_cq);
if (rc) {
@@ -2347,7 +2303,7 @@ int bnxt_re_destroy_cq(struct ib_cq *ib_cq)
kfree(cq);
}
atomic_dec(&rdev->cq_count);
- rdev->nq.budget--;
+ nq->budget--;
return 0;
}
@@ -2361,6 +2317,8 @@ struct ib_cq *bnxt_re_create_cq(struct ib_device *ibdev,
struct bnxt_re_cq *cq = NULL;
int rc, entries;
int cqe = attr->cqe;
+ struct bnxt_qplib_nq *nq = NULL;
+ unsigned int nq_alloc_cnt;
/* Validate CQ fields */
if (cqe < 1 || cqe > dev_attr->max_cq_wqes) {
@@ -2412,8 +2370,15 @@ struct ib_cq *bnxt_re_create_cq(struct ib_device *ibdev,
cq->qplib_cq.sghead = NULL;
cq->qplib_cq.nmap = 0;
}
+ /*
+ * Allocating the NQ in a round robin fashion. nq_alloc_cnt is a
+ * used for getting the NQ index.
+ */
+ nq_alloc_cnt = atomic_inc_return(&rdev->nq_alloc_cnt);
+ nq = &rdev->nq[nq_alloc_cnt % (rdev->num_msix - 1)];
cq->qplib_cq.max_wqe = entries;
- cq->qplib_cq.cnq_hw_ring_id = rdev->nq.ring_id;
+ cq->qplib_cq.cnq_hw_ring_id = nq->ring_id;
+ cq->qplib_cq.nq = nq;
rc = bnxt_qplib_create_cq(&rdev->qplib_res, &cq->qplib_cq);
if (rc) {
@@ -2423,7 +2388,7 @@ struct ib_cq *bnxt_re_create_cq(struct ib_device *ibdev,
cq->ib_cq.cqe = entries;
cq->cq_period = cq->qplib_cq.period;
- rdev->nq.budget++;
+ nq->budget++;
atomic_inc(&rdev->cq_count);
@@ -2921,6 +2886,10 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, int num_entries, struct ib_wc *wc)
sq->send_phantom = false;
}
}
+ if (ncqe < budget)
+ ncqe += bnxt_qplib_process_flush_list(&cq->qplib_cq,
+ cqe + ncqe,
+ budget - ncqe);
if (!ncqe)
break;
@@ -3410,7 +3379,7 @@ int bnxt_re_dealloc_ucontext(struct ib_ucontext *ib_uctx)
&rdev->qplib_res.dpi_tbl,
&uctx->dpi);
if (rc)
- dev_err(rdev_to_dev(rdev), "Deallocte HW DPI failed!");
+ dev_err(rdev_to_dev(rdev), "Deallocate HW DPI failed!");
/* Don't fail, continue*/
uctx->dpi.dbr = NULL;
}
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.h b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
index a0bb7e3..1df11ed2 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.h
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
@@ -141,9 +141,6 @@ int bnxt_re_modify_device(struct ib_device *ibdev,
struct ib_device_modify *device_modify);
int bnxt_re_query_port(struct ib_device *ibdev, u8 port_num,
struct ib_port_attr *port_attr);
-int bnxt_re_modify_port(struct ib_device *ibdev, u8 port_num,
- int port_modify_mask,
- struct ib_port_modify *port_modify);
int bnxt_re_get_port_immutable(struct ib_device *ibdev, u8 port_num,
struct ib_port_immutable *immutable);
int bnxt_re_query_pkey(struct ib_device *ibdev, u8 port_num,
diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
index ceae2d9..82d1cbc 100644
--- a/drivers/infiniband/hw/bnxt_re/main.c
+++ b/drivers/infiniband/hw/bnxt_re/main.c
@@ -64,13 +64,14 @@
#include "ib_verbs.h"
#include <rdma/bnxt_re-abi.h>
#include "bnxt.h"
+#include "hw_counters.h"
+
static char version[] =
BNXT_RE_DESC " v" ROCE_DRV_MODULE_VERSION "\n";
MODULE_AUTHOR("Eddie Wai <eddie.wai@broadcom.com>");
MODULE_DESCRIPTION(BNXT_RE_DESC " Driver");
MODULE_LICENSE("Dual BSD/GPL");
-MODULE_VERSION(ROCE_DRV_MODULE_VERSION);
/* globals */
static struct list_head bnxt_re_dev_list = LIST_HEAD_INIT(bnxt_re_dev_list);
@@ -162,7 +163,7 @@ static int bnxt_re_free_msix(struct bnxt_re_dev *rdev, bool lock_wait)
static int bnxt_re_request_msix(struct bnxt_re_dev *rdev)
{
- int rc = 0, num_msix_want = BNXT_RE_MIN_MSIX, num_msix_got;
+ int rc = 0, num_msix_want = BNXT_RE_MAX_MSIX, num_msix_got;
struct bnxt_en_dev *en_dev;
if (!rdev)
@@ -170,6 +171,8 @@ static int bnxt_re_request_msix(struct bnxt_re_dev *rdev)
en_dev = rdev->en_dev;
+ num_msix_want = min_t(u32, BNXT_RE_MAX_MSIX, num_online_cpus());
+
rtnl_lock();
num_msix_got = en_dev->en_ops->bnxt_request_msix(en_dev, BNXT_ROCE_ULP,
rdev->msix_entries,
@@ -474,7 +477,6 @@ static int bnxt_re_register_ib(struct bnxt_re_dev *rdev)
ibdev->modify_device = bnxt_re_modify_device;
ibdev->query_port = bnxt_re_query_port;
- ibdev->modify_port = bnxt_re_modify_port;
ibdev->get_port_immutable = bnxt_re_get_port_immutable;
ibdev->query_pkey = bnxt_re_query_pkey;
ibdev->query_gid = bnxt_re_query_gid;
@@ -513,6 +515,8 @@ static int bnxt_re_register_ib(struct bnxt_re_dev *rdev)
ibdev->alloc_ucontext = bnxt_re_alloc_ucontext;
ibdev->dealloc_ucontext = bnxt_re_dealloc_ucontext;
ibdev->mmap = bnxt_re_mmap;
+ ibdev->get_hw_stats = bnxt_re_ib_get_hw_stats;
+ ibdev->alloc_hw_stats = bnxt_re_ib_alloc_hw_stats;
return ib_register_device(ibdev, NULL);
}
@@ -653,8 +657,12 @@ static int bnxt_re_cqn_handler(struct bnxt_qplib_nq *nq,
static void bnxt_re_cleanup_res(struct bnxt_re_dev *rdev)
{
- if (rdev->nq.hwq.max_elements)
- bnxt_qplib_disable_nq(&rdev->nq);
+ int i;
+
+ if (rdev->nq[0].hwq.max_elements) {
+ for (i = 1; i < rdev->num_msix; i++)
+ bnxt_qplib_disable_nq(&rdev->nq[i - 1]);
+ }
if (rdev->qplib_res.rcfw)
bnxt_qplib_cleanup_res(&rdev->qplib_res);
@@ -662,31 +670,41 @@ static void bnxt_re_cleanup_res(struct bnxt_re_dev *rdev)
static int bnxt_re_init_res(struct bnxt_re_dev *rdev)
{
- int rc = 0;
+ int rc = 0, i;
bnxt_qplib_init_res(&rdev->qplib_res);
- if (rdev->msix_entries[BNXT_RE_NQ_IDX].vector <= 0)
- return -EINVAL;
+ for (i = 1; i < rdev->num_msix ; i++) {
+ rc = bnxt_qplib_enable_nq(rdev->en_dev->pdev, &rdev->nq[i - 1],
+ i - 1, rdev->msix_entries[i].vector,
+ rdev->msix_entries[i].db_offset,
+ &bnxt_re_cqn_handler, NULL);
- rc = bnxt_qplib_enable_nq(rdev->en_dev->pdev, &rdev->nq,
- rdev->msix_entries[BNXT_RE_NQ_IDX].vector,
- rdev->msix_entries[BNXT_RE_NQ_IDX].db_offset,
- &bnxt_re_cqn_handler,
- NULL);
+ if (rc) {
+ dev_err(rdev_to_dev(rdev),
+ "Failed to enable NQ with rc = 0x%x", rc);
+ goto fail;
+ }
+ }
+ return 0;
+fail:
+ return rc;
+}
- if (rc)
- dev_err(rdev_to_dev(rdev), "Failed to enable NQ: %#x", rc);
+static void bnxt_re_free_nq_res(struct bnxt_re_dev *rdev, bool lock_wait)
+{
+ int i;
- return rc;
+ for (i = 0; i < rdev->num_msix - 1; i++) {
+ bnxt_re_net_ring_free(rdev, rdev->nq[i].ring_id, lock_wait);
+ bnxt_qplib_free_nq(&rdev->nq[i]);
+ }
}
static void bnxt_re_free_res(struct bnxt_re_dev *rdev, bool lock_wait)
{
- if (rdev->nq.hwq.max_elements) {
- bnxt_re_net_ring_free(rdev, rdev->nq.ring_id, lock_wait);
- bnxt_qplib_free_nq(&rdev->nq);
- }
+ bnxt_re_free_nq_res(rdev, lock_wait);
+
if (rdev->qplib_res.dpi_tbl.max) {
bnxt_qplib_dealloc_dpi(&rdev->qplib_res,
&rdev->qplib_res.dpi_tbl,
@@ -700,7 +718,7 @@ static void bnxt_re_free_res(struct bnxt_re_dev *rdev, bool lock_wait)
static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
{
- int rc = 0;
+ int rc = 0, i;
/* Configure and allocate resources for qplib */
rdev->qplib_res.rcfw = &rdev->rcfw;
@@ -717,30 +735,42 @@ static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
&rdev->dpi_privileged,
rdev);
if (rc)
- goto fail;
+ goto dealloc_res;
- rdev->nq.hwq.max_elements = BNXT_RE_MAX_CQ_COUNT +
- BNXT_RE_MAX_SRQC_COUNT + 2;
- rc = bnxt_qplib_alloc_nq(rdev->en_dev->pdev, &rdev->nq);
- if (rc) {
- dev_err(rdev_to_dev(rdev),
- "Failed to allocate NQ memory: %#x", rc);
- goto fail;
- }
- rc = bnxt_re_net_ring_alloc
- (rdev, rdev->nq.hwq.pbl[PBL_LVL_0].pg_map_arr,
- rdev->nq.hwq.pbl[rdev->nq.hwq.level].pg_count,
- HWRM_RING_ALLOC_CMPL, BNXT_QPLIB_NQE_MAX_CNT - 1,
- rdev->msix_entries[BNXT_RE_NQ_IDX].ring_idx,
- &rdev->nq.ring_id);
- if (rc) {
- dev_err(rdev_to_dev(rdev),
- "Failed to allocate NQ ring: %#x", rc);
- goto free_nq;
+ for (i = 0; i < rdev->num_msix - 1; i++) {
+ rdev->nq[i].hwq.max_elements = BNXT_RE_MAX_CQ_COUNT +
+ BNXT_RE_MAX_SRQC_COUNT + 2;
+ rc = bnxt_qplib_alloc_nq(rdev->en_dev->pdev, &rdev->nq[i]);
+ if (rc) {
+ dev_err(rdev_to_dev(rdev), "Alloc Failed NQ%d rc:%#x",
+ i, rc);
+ goto dealloc_dpi;
+ }
+ rc = bnxt_re_net_ring_alloc
+ (rdev, rdev->nq[i].hwq.pbl[PBL_LVL_0].pg_map_arr,
+ rdev->nq[i].hwq.pbl[rdev->nq[i].hwq.level].pg_count,
+ HWRM_RING_ALLOC_CMPL,
+ BNXT_QPLIB_NQE_MAX_CNT - 1,
+ rdev->msix_entries[i + 1].ring_idx,
+ &rdev->nq[i].ring_id);
+ if (rc) {
+ dev_err(rdev_to_dev(rdev),
+ "Failed to allocate NQ fw id with rc = 0x%x",
+ rc);
+ goto free_nq;
+ }
}
return 0;
free_nq:
- bnxt_qplib_free_nq(&rdev->nq);
+ for (i = 0; i < rdev->num_msix - 1; i++)
+ bnxt_qplib_free_nq(&rdev->nq[i]);
+dealloc_dpi:
+ bnxt_qplib_dealloc_dpi(&rdev->qplib_res,
+ &rdev->qplib_res.dpi_tbl,
+ &rdev->dpi_privileged);
+dealloc_res:
+ bnxt_qplib_free_res(&rdev->qplib_res);
+
fail:
rdev->qplib_res.rcfw = NULL;
return rc;
@@ -835,6 +865,42 @@ static void bnxt_re_dev_stop(struct bnxt_re_dev *rdev)
mutex_unlock(&rdev->qp_lock);
}
+static int bnxt_re_update_gid(struct bnxt_re_dev *rdev)
+{
+ struct bnxt_qplib_sgid_tbl *sgid_tbl = &rdev->qplib_res.sgid_tbl;
+ struct bnxt_qplib_gid gid;
+ u16 gid_idx, index;
+ int rc = 0;
+
+ if (!test_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags))
+ return 0;
+
+ if (!sgid_tbl) {
+ dev_err(rdev_to_dev(rdev), "QPLIB: SGID table not allocated");
+ return -EINVAL;
+ }
+
+ for (index = 0; index < sgid_tbl->active; index++) {
+ gid_idx = sgid_tbl->hw_id[index];
+
+ if (!memcmp(&sgid_tbl->tbl[index], &bnxt_qplib_gid_zero,
+ sizeof(bnxt_qplib_gid_zero)))
+ continue;
+ /* need to modify the VLAN enable setting of non VLAN GID only
+ * as setting is done for VLAN GID while adding GID
+ */
+ if (sgid_tbl->vlan[index])
+ continue;
+
+ memcpy(&gid, &sgid_tbl->tbl[index], sizeof(gid));
+
+ rc = bnxt_qplib_update_sgid(sgid_tbl, &gid, gid_idx,
+ rdev->qplib_res.netdev->dev_addr);
+ }
+
+ return rc;
+}
+
static u32 bnxt_re_get_priority_mask(struct bnxt_re_dev *rdev)
{
u32 prio_map = 0, tmp_map = 0;
@@ -854,8 +920,6 @@ static u32 bnxt_re_get_priority_mask(struct bnxt_re_dev *rdev)
tmp_map = dcb_ieee_getapp_mask(netdev, &app);
prio_map |= tmp_map;
- if (!prio_map)
- prio_map = -EFAULT;
return prio_map;
}
@@ -881,10 +945,7 @@ static int bnxt_re_setup_qos(struct bnxt_re_dev *rdev)
int rc;
/* Get priority for roce */
- rc = bnxt_re_get_priority_mask(rdev);
- if (rc < 0)
- return rc;
- prio_map = (u8)rc;
+ prio_map = bnxt_re_get_priority_mask(rdev);
if (prio_map == rdev->cur_prio_map)
return 0;
@@ -906,6 +967,16 @@ static int bnxt_re_setup_qos(struct bnxt_re_dev *rdev)
return rc;
}
+ /* Actual priorities are not programmed as they are already
+ * done by L2 driver; just enable or disable priority vlan tagging
+ */
+ if ((prio_map == 0 && rdev->qplib_res.prio) ||
+ (prio_map != 0 && !rdev->qplib_res.prio)) {
+ rdev->qplib_res.prio = prio_map ? true : false;
+
+ bnxt_re_update_gid(rdev);
+ }
+
return 0;
}
@@ -998,7 +1069,8 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
/* Establish RCFW Communication Channel to initialize the context
* memory for the function and all child VFs
*/
- rc = bnxt_qplib_alloc_rcfw_channel(rdev->en_dev->pdev, &rdev->rcfw);
+ rc = bnxt_qplib_alloc_rcfw_channel(rdev->en_dev->pdev, &rdev->rcfw,
+ BNXT_RE_MAX_QPC_COUNT);
if (rc)
goto fail;
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
index 9af1514..e8afc47 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
@@ -51,6 +51,168 @@
#include "qplib_fp.h"
static void bnxt_qplib_arm_cq_enable(struct bnxt_qplib_cq *cq);
+static void __clean_cq(struct bnxt_qplib_cq *cq, u64 qp);
+
+static void bnxt_qplib_cancel_phantom_processing(struct bnxt_qplib_qp *qp)
+{
+ qp->sq.condition = false;
+ qp->sq.send_phantom = false;
+ qp->sq.single = false;
+}
+
+/* Flush list */
+static void __bnxt_qplib_add_flush_qp(struct bnxt_qplib_qp *qp)
+{
+ struct bnxt_qplib_cq *scq, *rcq;
+
+ scq = qp->scq;
+ rcq = qp->rcq;
+
+ if (!qp->sq.flushed) {
+ dev_dbg(&scq->hwq.pdev->dev,
+ "QPLIB: FP: Adding to SQ Flush list = %p",
+ qp);
+ bnxt_qplib_cancel_phantom_processing(qp);
+ list_add_tail(&qp->sq_flush, &scq->sqf_head);
+ qp->sq.flushed = true;
+ }
+ if (!qp->srq) {
+ if (!qp->rq.flushed) {
+ dev_dbg(&rcq->hwq.pdev->dev,
+ "QPLIB: FP: Adding to RQ Flush list = %p",
+ qp);
+ list_add_tail(&qp->rq_flush, &rcq->rqf_head);
+ qp->rq.flushed = true;
+ }
+ }
+}
+
+void bnxt_qplib_acquire_cq_locks(struct bnxt_qplib_qp *qp,
+ unsigned long *flags)
+ __acquires(&qp->scq->hwq.lock) __acquires(&qp->rcq->hwq.lock)
+{
+ spin_lock_irqsave(&qp->scq->hwq.lock, *flags);
+ if (qp->scq == qp->rcq)
+ __acquire(&qp->rcq->hwq.lock);
+ else
+ spin_lock(&qp->rcq->hwq.lock);
+}
+
+void bnxt_qplib_release_cq_locks(struct bnxt_qplib_qp *qp,
+ unsigned long *flags)
+ __releases(&qp->scq->hwq.lock) __releases(&qp->rcq->hwq.lock)
+{
+ if (qp->scq == qp->rcq)
+ __release(&qp->rcq->hwq.lock);
+ else
+ spin_unlock(&qp->rcq->hwq.lock);
+ spin_unlock_irqrestore(&qp->scq->hwq.lock, *flags);
+}
+
+static struct bnxt_qplib_cq *bnxt_qplib_find_buddy_cq(struct bnxt_qplib_qp *qp,
+ struct bnxt_qplib_cq *cq)
+{
+ struct bnxt_qplib_cq *buddy_cq = NULL;
+
+ if (qp->scq == qp->rcq)
+ buddy_cq = NULL;
+ else if (qp->scq == cq)
+ buddy_cq = qp->rcq;
+ else
+ buddy_cq = qp->scq;
+ return buddy_cq;
+}
+
+static void bnxt_qplib_lock_buddy_cq(struct bnxt_qplib_qp *qp,
+ struct bnxt_qplib_cq *cq)
+ __acquires(&buddy_cq->hwq.lock)
+{
+ struct bnxt_qplib_cq *buddy_cq = NULL;
+
+ buddy_cq = bnxt_qplib_find_buddy_cq(qp, cq);
+ if (!buddy_cq)
+ __acquire(&cq->hwq.lock);
+ else
+ spin_lock(&buddy_cq->hwq.lock);
+}
+
+static void bnxt_qplib_unlock_buddy_cq(struct bnxt_qplib_qp *qp,
+ struct bnxt_qplib_cq *cq)
+ __releases(&buddy_cq->hwq.lock)
+{
+ struct bnxt_qplib_cq *buddy_cq = NULL;
+
+ buddy_cq = bnxt_qplib_find_buddy_cq(qp, cq);
+ if (!buddy_cq)
+ __release(&cq->hwq.lock);
+ else
+ spin_unlock(&buddy_cq->hwq.lock);
+}
+
+void bnxt_qplib_add_flush_qp(struct bnxt_qplib_qp *qp)
+{
+ unsigned long flags;
+
+ bnxt_qplib_acquire_cq_locks(qp, &flags);
+ __bnxt_qplib_add_flush_qp(qp);
+ bnxt_qplib_release_cq_locks(qp, &flags);
+}
+
+static void __bnxt_qplib_del_flush_qp(struct bnxt_qplib_qp *qp)
+{
+ struct bnxt_qplib_cq *scq, *rcq;
+
+ scq = qp->scq;
+ rcq = qp->rcq;
+
+ if (qp->sq.flushed) {
+ qp->sq.flushed = false;
+ list_del(&qp->sq_flush);
+ }
+ if (!qp->srq) {
+ if (qp->rq.flushed) {
+ qp->rq.flushed = false;
+ list_del(&qp->rq_flush);
+ }
+ }
+}
+
+void bnxt_qplib_del_flush_qp(struct bnxt_qplib_qp *qp)
+{
+ unsigned long flags;
+
+ bnxt_qplib_acquire_cq_locks(qp, &flags);
+ __clean_cq(qp->scq, (u64)(unsigned long)qp);
+ qp->sq.hwq.prod = 0;
+ qp->sq.hwq.cons = 0;
+ __clean_cq(qp->rcq, (u64)(unsigned long)qp);
+ qp->rq.hwq.prod = 0;
+ qp->rq.hwq.cons = 0;
+
+ __bnxt_qplib_del_flush_qp(qp);
+ bnxt_qplib_release_cq_locks(qp, &flags);
+}
+
+static void bnxt_qpn_cqn_sched_task(struct work_struct *work)
+{
+ struct bnxt_qplib_nq_work *nq_work =
+ container_of(work, struct bnxt_qplib_nq_work, work);
+
+ struct bnxt_qplib_cq *cq = nq_work->cq;
+ struct bnxt_qplib_nq *nq = nq_work->nq;
+
+ if (cq && nq) {
+ spin_lock_bh(&cq->compl_lock);
+ if (atomic_read(&cq->arm_state) && nq->cqn_handler) {
+ dev_dbg(&nq->pdev->dev,
+ "%s:Trigger cq = %p event nq = %p\n",
+ __func__, cq, nq);
+ nq->cqn_handler(nq, cq);
+ }
+ spin_unlock_bh(&cq->compl_lock);
+ }
+ kfree(nq_work);
+}
static void bnxt_qplib_free_qp_hdr_buf(struct bnxt_qplib_res *res,
struct bnxt_qplib_qp *qp)
@@ -119,6 +281,7 @@ static void bnxt_qplib_service_nq(unsigned long data)
struct bnxt_qplib_nq *nq = (struct bnxt_qplib_nq *)data;
struct bnxt_qplib_hwq *hwq = &nq->hwq;
struct nq_base *nqe, **nq_ptr;
+ struct bnxt_qplib_cq *cq;
int num_cqne_processed = 0;
u32 sw_cons, raw_cons;
u16 type;
@@ -143,15 +306,17 @@ static void bnxt_qplib_service_nq(unsigned long data)
q_handle = le32_to_cpu(nqcne->cq_handle_low);
q_handle |= (u64)le32_to_cpu(nqcne->cq_handle_high)
<< 32;
- bnxt_qplib_arm_cq_enable((struct bnxt_qplib_cq *)
- ((unsigned long)q_handle));
- if (!nq->cqn_handler(nq, (struct bnxt_qplib_cq *)
- ((unsigned long)q_handle)))
+ cq = (struct bnxt_qplib_cq *)(unsigned long)q_handle;
+ bnxt_qplib_arm_cq_enable(cq);
+ spin_lock_bh(&cq->compl_lock);
+ atomic_set(&cq->arm_state, 0);
+ if (!nq->cqn_handler(nq, (cq)))
num_cqne_processed++;
else
dev_warn(&nq->pdev->dev,
"QPLIB: cqn - type 0x%x not handled",
type);
+ spin_unlock_bh(&cq->compl_lock);
break;
}
case NQ_BASE_TYPE_DBQ_EVENT:
@@ -190,12 +355,17 @@ static irqreturn_t bnxt_qplib_nq_irq(int irq, void *dev_instance)
void bnxt_qplib_disable_nq(struct bnxt_qplib_nq *nq)
{
+ if (nq->cqn_wq) {
+ destroy_workqueue(nq->cqn_wq);
+ nq->cqn_wq = NULL;
+ }
/* Make sure the HW is stopped! */
synchronize_irq(nq->vector);
tasklet_disable(&nq->worker);
tasklet_kill(&nq->worker);
if (nq->requested) {
+ irq_set_affinity_hint(nq->vector, NULL);
free_irq(nq->vector, nq);
nq->requested = false;
}
@@ -209,14 +379,14 @@ void bnxt_qplib_disable_nq(struct bnxt_qplib_nq *nq)
}
int bnxt_qplib_enable_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq,
- int msix_vector, int bar_reg_offset,
+ int nq_idx, int msix_vector, int bar_reg_offset,
int (*cqn_handler)(struct bnxt_qplib_nq *nq,
struct bnxt_qplib_cq *),
int (*srqn_handler)(struct bnxt_qplib_nq *nq,
void *, u8 event))
{
resource_size_t nq_base;
- int rc;
+ int rc = -1;
nq->pdev = pdev;
nq->vector = msix_vector;
@@ -227,14 +397,31 @@ int bnxt_qplib_enable_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq,
tasklet_init(&nq->worker, bnxt_qplib_service_nq, (unsigned long)nq);
+ /* Have a task to schedule CQ notifiers in post send case */
+ nq->cqn_wq = create_singlethread_workqueue("bnxt_qplib_nq");
+ if (!nq->cqn_wq)
+ goto fail;
+
nq->requested = false;
- rc = request_irq(nq->vector, bnxt_qplib_nq_irq, 0, "bnxt_qplib_nq", nq);
+ memset(nq->name, 0, 32);
+ sprintf(nq->name, "bnxt_qplib_nq-%d", nq_idx);
+ rc = request_irq(nq->vector, bnxt_qplib_nq_irq, 0, nq->name, nq);
if (rc) {
dev_err(&nq->pdev->dev,
"Failed to request IRQ for NQ: %#x", rc);
bnxt_qplib_disable_nq(nq);
goto fail;
}
+
+ cpumask_clear(&nq->mask);
+ cpumask_set_cpu(nq_idx, &nq->mask);
+ rc = irq_set_affinity_hint(nq->vector, &nq->mask);
+ if (rc) {
+ dev_warn(&nq->pdev->dev,
+ "QPLIB: set affinity failed; vector: %d nq_idx: %d\n",
+ nq->vector, nq_idx);
+ }
+
nq->requested = true;
nq->bar_reg = NQ_CONS_PCI_BAR_REGION;
nq->bar_reg_off = bar_reg_offset;
@@ -258,8 +445,10 @@ fail:
void bnxt_qplib_free_nq(struct bnxt_qplib_nq *nq)
{
- if (nq->hwq.max_elements)
+ if (nq->hwq.max_elements) {
bnxt_qplib_free_hwq(nq->pdev, &nq->hwq);
+ nq->hwq.max_elements = 0;
+ }
}
int bnxt_qplib_alloc_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq)
@@ -401,8 +590,8 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
qp->id = le32_to_cpu(resp.xid);
qp->cur_qp_state = CMDQ_MODIFY_QP_NEW_STATE_RESET;
- sq->flush_in_progress = false;
- rq->flush_in_progress = false;
+ rcfw->qp_tbl[qp->id].qp_id = qp->id;
+ rcfw->qp_tbl[qp->id].qp_handle = (void *)qp;
return 0;
@@ -615,8 +804,10 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
qp->id = le32_to_cpu(resp.xid);
qp->cur_qp_state = CMDQ_MODIFY_QP_NEW_STATE_RESET;
- sq->flush_in_progress = false;
- rq->flush_in_progress = false;
+ INIT_LIST_HEAD(&qp->sq_flush);
+ INIT_LIST_HEAD(&qp->rq_flush);
+ rcfw->qp_tbl[qp->id].qp_id = qp->id;
+ rcfw->qp_tbl[qp->id].qp_handle = (void *)qp;
return 0;
@@ -963,13 +1154,19 @@ int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res,
u16 cmd_flags = 0;
int rc;
+ rcfw->qp_tbl[qp->id].qp_id = BNXT_QPLIB_QP_ID_INVALID;
+ rcfw->qp_tbl[qp->id].qp_handle = NULL;
+
RCFW_CMD_PREP(req, DESTROY_QP, cmd_flags);
req.qp_cid = cpu_to_le32(qp->id);
rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
(void *)&resp, NULL, 0);
- if (rc)
+ if (rc) {
+ rcfw->qp_tbl[qp->id].qp_id = qp->id;
+ rcfw->qp_tbl[qp->id].qp_handle = qp;
return rc;
+ }
/* Must walk the associated CQs to nullified the QP ptr */
spin_lock_irqsave(&qp->scq->hwq.lock, flags);
@@ -1074,14 +1271,21 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp,
struct bnxt_qplib_swq *swq;
struct sq_send *hw_sq_send_hdr, **hw_sq_send_ptr;
struct sq_sge *hw_sge;
+ struct bnxt_qplib_nq_work *nq_work = NULL;
+ bool sch_handler = false;
u32 sw_prod;
u8 wqe_size16;
int i, rc = 0, data_len = 0, pkt_num = 0;
__le32 temp32;
if (qp->state != CMDQ_MODIFY_QP_NEW_STATE_RTS) {
- rc = -EINVAL;
- goto done;
+ if (qp->state == CMDQ_MODIFY_QP_NEW_STATE_ERR) {
+ sch_handler = true;
+ dev_dbg(&sq->hwq.pdev->dev,
+ "%s Error QP. Scheduling for poll_cq\n",
+ __func__);
+ goto queue_err;
+ }
}
if (bnxt_qplib_queue_full(sq)) {
@@ -1301,12 +1505,35 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp,
((swq->next_psn << SQ_PSN_SEARCH_NEXT_PSN_SFT) &
SQ_PSN_SEARCH_NEXT_PSN_MASK));
}
-
+queue_err:
+ if (sch_handler) {
+ /* Store the ULP info in the software structures */
+ sw_prod = HWQ_CMP(sq->hwq.prod, &sq->hwq);
+ swq = &sq->swq[sw_prod];
+ swq->wr_id = wqe->wr_id;
+ swq->type = wqe->type;
+ swq->flags = wqe->flags;
+ if (qp->sig_type)
+ swq->flags |= SQ_SEND_FLAGS_SIGNAL_COMP;
+ swq->start_psn = sq->psn & BTH_PSN_MASK;
+ }
sq->hwq.prod++;
-
qp->wqe_cnt++;
done:
+ if (sch_handler) {
+ nq_work = kzalloc(sizeof(*nq_work), GFP_ATOMIC);
+ if (nq_work) {
+ nq_work->cq = qp->scq;
+ nq_work->nq = qp->scq->nq;
+ INIT_WORK(&nq_work->work, bnxt_qpn_cqn_sched_task);
+ queue_work(qp->scq->nq->cqn_wq, &nq_work->work);
+ } else {
+ dev_err(&sq->hwq.pdev->dev,
+ "QPLIB: FP: Failed to allocate SQ nq_work!");
+ rc = -ENOMEM;
+ }
+ }
return rc;
}
@@ -1334,15 +1561,17 @@ int bnxt_qplib_post_recv(struct bnxt_qplib_qp *qp,
struct bnxt_qplib_q *rq = &qp->rq;
struct rq_wqe *rqe, **rqe_ptr;
struct sq_sge *hw_sge;
+ struct bnxt_qplib_nq_work *nq_work = NULL;
+ bool sch_handler = false;
u32 sw_prod;
int i, rc = 0;
if (qp->state == CMDQ_MODIFY_QP_NEW_STATE_ERR) {
- dev_err(&rq->hwq.pdev->dev,
- "QPLIB: FP: QP (0x%x) is in the 0x%x state",
- qp->id, qp->state);
- rc = -EINVAL;
- goto done;
+ sch_handler = true;
+ dev_dbg(&rq->hwq.pdev->dev,
+ "%s Error QP. Scheduling for poll_cq\n",
+ __func__);
+ goto queue_err;
}
if (bnxt_qplib_queue_full(rq)) {
dev_err(&rq->hwq.pdev->dev,
@@ -1378,7 +1607,27 @@ int bnxt_qplib_post_recv(struct bnxt_qplib_qp *qp,
/* Supply the rqe->wr_id index to the wr_id_tbl for now */
rqe->wr_id[0] = cpu_to_le32(sw_prod);
+queue_err:
+ if (sch_handler) {
+ /* Store the ULP info in the software structures */
+ sw_prod = HWQ_CMP(rq->hwq.prod, &rq->hwq);
+ rq->swq[sw_prod].wr_id = wqe->wr_id;
+ }
+
rq->hwq.prod++;
+ if (sch_handler) {
+ nq_work = kzalloc(sizeof(*nq_work), GFP_ATOMIC);
+ if (nq_work) {
+ nq_work->cq = qp->rcq;
+ nq_work->nq = qp->rcq->nq;
+ INIT_WORK(&nq_work->work, bnxt_qpn_cqn_sched_task);
+ queue_work(qp->rcq->nq->cqn_wq, &nq_work->work);
+ } else {
+ dev_err(&rq->hwq.pdev->dev,
+ "QPLIB: FP: Failed to allocate RQ nq_work!");
+ rc = -ENOMEM;
+ }
+ }
done:
return rc;
}
@@ -1471,6 +1720,9 @@ int bnxt_qplib_create_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq)
cq->dbr_base = res->dpi_tbl.dbr_bar_reg_iomem;
cq->period = BNXT_QPLIB_QUEUE_START_PERIOD;
init_waitqueue_head(&cq->waitq);
+ INIT_LIST_HEAD(&cq->sqf_head);
+ INIT_LIST_HEAD(&cq->rqf_head);
+ spin_lock_init(&cq->compl_lock);
bnxt_qplib_arm_cq_enable(cq);
return 0;
@@ -1513,9 +1765,13 @@ static int __flush_sq(struct bnxt_qplib_q *sq, struct bnxt_qplib_qp *qp,
while (*budget) {
sw_cons = HWQ_CMP(sq->hwq.cons, &sq->hwq);
if (sw_cons == sw_prod) {
- sq->flush_in_progress = false;
break;
}
+ /* Skip the FENCE WQE completions */
+ if (sq->swq[sw_cons].wr_id == BNXT_QPLIB_FENCE_WRID) {
+ bnxt_qplib_cancel_phantom_processing(qp);
+ goto skip_compl;
+ }
memset(cqe, 0, sizeof(*cqe));
cqe->status = CQ_REQ_STATUS_WORK_REQUEST_FLUSHED_ERR;
cqe->opcode = CQ_BASE_CQE_TYPE_REQ;
@@ -1525,6 +1781,7 @@ static int __flush_sq(struct bnxt_qplib_q *sq, struct bnxt_qplib_qp *qp,
cqe->type = sq->swq[sw_cons].type;
cqe++;
(*budget)--;
+skip_compl:
sq->hwq.cons++;
}
*pcqe = cqe;
@@ -1536,11 +1793,24 @@ static int __flush_sq(struct bnxt_qplib_q *sq, struct bnxt_qplib_qp *qp,
}
static int __flush_rq(struct bnxt_qplib_q *rq, struct bnxt_qplib_qp *qp,
- int opcode, struct bnxt_qplib_cqe **pcqe, int *budget)
+ struct bnxt_qplib_cqe **pcqe, int *budget)
{
struct bnxt_qplib_cqe *cqe;
u32 sw_prod, sw_cons;
int rc = 0;
+ int opcode = 0;
+
+ switch (qp->type) {
+ case CMDQ_CREATE_QP1_TYPE_GSI:
+ opcode = CQ_BASE_CQE_TYPE_RES_RAWETH_QP1;
+ break;
+ case CMDQ_CREATE_QP_TYPE_RC:
+ opcode = CQ_BASE_CQE_TYPE_RES_RC;
+ break;
+ case CMDQ_CREATE_QP_TYPE_UD:
+ opcode = CQ_BASE_CQE_TYPE_RES_UD;
+ break;
+ }
/* Flush the rest of the RQ */
sw_prod = HWQ_CMP(rq->hwq.prod, &rq->hwq);
@@ -1567,6 +1837,21 @@ static int __flush_rq(struct bnxt_qplib_q *rq, struct bnxt_qplib_qp *qp,
return rc;
}
+void bnxt_qplib_mark_qp_error(void *qp_handle)
+{
+ struct bnxt_qplib_qp *qp = qp_handle;
+
+ if (!qp)
+ return;
+
+ /* Must block new posting of SQ and RQ */
+ qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR;
+ bnxt_qplib_cancel_phantom_processing(qp);
+
+ /* Add qp to flush list of the CQ */
+ __bnxt_qplib_add_flush_qp(qp);
+}
+
/* Note: SQE is valid from sw_sq_cons up to cqe_sq_cons (exclusive)
* CQE is track from sw_cq_cons to max_element but valid only if VALID=1
*/
@@ -1694,10 +1979,12 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
cqe_sq_cons, sq->hwq.max_elements);
return -EINVAL;
}
- /* If we were in the middle of flushing the SQ, continue */
- if (sq->flush_in_progress)
- goto flush;
+ if (qp->sq.flushed) {
+ dev_dbg(&cq->hwq.pdev->dev,
+ "%s: QPLIB: QP in Flush QP = %p\n", __func__, qp);
+ goto done;
+ }
/* Require to walk the sq's swq to fabricate CQEs for all previously
* signaled SWQEs due to CQE aggregation from the current sq cons
* to the cqe_sq_cons
@@ -1733,11 +2020,9 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
sw_sq_cons, cqe->wr_id, cqe->status);
cqe++;
(*budget)--;
- sq->flush_in_progress = true;
- /* Must block new posting of SQ and RQ */
- qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR;
- sq->condition = false;
- sq->single = false;
+ bnxt_qplib_lock_buddy_cq(qp, cq);
+ bnxt_qplib_mark_qp_error(qp);
+ bnxt_qplib_unlock_buddy_cq(qp, cq);
} else {
if (swq->flags & SQ_SEND_FLAGS_SIGNAL_COMP) {
/* Before we complete, do WA 9060 */
@@ -1768,15 +2053,6 @@ out:
* the WC for this CQE
*/
sq->single = false;
- if (!sq->flush_in_progress)
- goto done;
-flush:
- /* Require to walk the sq's swq to fabricate CQEs for all
- * previously posted SWQEs due to the error CQE received
- */
- rc = __flush_sq(sq, qp, pcqe, budget);
- if (!rc)
- sq->flush_in_progress = false;
done:
return rc;
}
@@ -1798,6 +2074,12 @@ static int bnxt_qplib_cq_process_res_rc(struct bnxt_qplib_cq *cq,
dev_err(&cq->hwq.pdev->dev, "QPLIB: process_cq RC qp is NULL");
return -EINVAL;
}
+ if (qp->rq.flushed) {
+ dev_dbg(&cq->hwq.pdev->dev,
+ "%s: QPLIB: QP in Flush QP = %p\n", __func__, qp);
+ goto done;
+ }
+
cqe = *pcqe;
cqe->opcode = hwcqe->cqe_type_toggle & CQ_BASE_CQE_TYPE_MASK;
cqe->length = le32_to_cpu(hwcqe->length);
@@ -1817,8 +2099,6 @@ static int bnxt_qplib_cq_process_res_rc(struct bnxt_qplib_cq *cq,
wr_id_idx, rq->hwq.max_elements);
return -EINVAL;
}
- if (rq->flush_in_progress)
- goto flush_rq;
cqe->wr_id = rq->swq[wr_id_idx].wr_id;
cqe++;
@@ -1827,12 +2107,13 @@ static int bnxt_qplib_cq_process_res_rc(struct bnxt_qplib_cq *cq,
*pcqe = cqe;
if (hwcqe->status != CQ_RES_RC_STATUS_OK) {
- rq->flush_in_progress = true;
-flush_rq:
- rc = __flush_rq(rq, qp, CQ_BASE_CQE_TYPE_RES_RC, pcqe, budget);
- if (!rc)
- rq->flush_in_progress = false;
+ /* Add qp to flush list of the CQ */
+ bnxt_qplib_lock_buddy_cq(qp, cq);
+ __bnxt_qplib_add_flush_qp(qp);
+ bnxt_qplib_unlock_buddy_cq(qp, cq);
}
+
+done:
return rc;
}
@@ -1853,6 +2134,11 @@ static int bnxt_qplib_cq_process_res_ud(struct bnxt_qplib_cq *cq,
dev_err(&cq->hwq.pdev->dev, "QPLIB: process_cq UD qp is NULL");
return -EINVAL;
}
+ if (qp->rq.flushed) {
+ dev_dbg(&cq->hwq.pdev->dev,
+ "%s: QPLIB: QP in Flush QP = %p\n", __func__, qp);
+ goto done;
+ }
cqe = *pcqe;
cqe->opcode = hwcqe->cqe_type_toggle & CQ_BASE_CQE_TYPE_MASK;
cqe->length = le32_to_cpu(hwcqe->length);
@@ -1876,8 +2162,6 @@ static int bnxt_qplib_cq_process_res_ud(struct bnxt_qplib_cq *cq,
wr_id_idx, rq->hwq.max_elements);
return -EINVAL;
}
- if (rq->flush_in_progress)
- goto flush_rq;
cqe->wr_id = rq->swq[wr_id_idx].wr_id;
cqe++;
@@ -1886,12 +2170,12 @@ static int bnxt_qplib_cq_process_res_ud(struct bnxt_qplib_cq *cq,
*pcqe = cqe;
if (hwcqe->status != CQ_RES_RC_STATUS_OK) {
- rq->flush_in_progress = true;
-flush_rq:
- rc = __flush_rq(rq, qp, CQ_BASE_CQE_TYPE_RES_UD, pcqe, budget);
- if (!rc)
- rq->flush_in_progress = false;
+ /* Add qp to flush list of the CQ */
+ bnxt_qplib_lock_buddy_cq(qp, cq);
+ __bnxt_qplib_add_flush_qp(qp);
+ bnxt_qplib_unlock_buddy_cq(qp, cq);
}
+done:
return rc;
}
@@ -1932,6 +2216,11 @@ static int bnxt_qplib_cq_process_res_raweth_qp1(struct bnxt_qplib_cq *cq,
"QPLIB: process_cq Raw/QP1 qp is NULL");
return -EINVAL;
}
+ if (qp->rq.flushed) {
+ dev_dbg(&cq->hwq.pdev->dev,
+ "%s: QPLIB: QP in Flush QP = %p\n", __func__, qp);
+ goto done;
+ }
cqe = *pcqe;
cqe->opcode = hwcqe->cqe_type_toggle & CQ_BASE_CQE_TYPE_MASK;
cqe->flags = le16_to_cpu(hwcqe->flags);
@@ -1960,8 +2249,6 @@ static int bnxt_qplib_cq_process_res_raweth_qp1(struct bnxt_qplib_cq *cq,
wr_id_idx, rq->hwq.max_elements);
return -EINVAL;
}
- if (rq->flush_in_progress)
- goto flush_rq;
cqe->wr_id = rq->swq[wr_id_idx].wr_id;
cqe++;
@@ -1970,13 +2257,13 @@ static int bnxt_qplib_cq_process_res_raweth_qp1(struct bnxt_qplib_cq *cq,
*pcqe = cqe;
if (hwcqe->status != CQ_RES_RC_STATUS_OK) {
- rq->flush_in_progress = true;
-flush_rq:
- rc = __flush_rq(rq, qp, CQ_BASE_CQE_TYPE_RES_RAWETH_QP1, pcqe,
- budget);
- if (!rc)
- rq->flush_in_progress = false;
+ /* Add qp to flush list of the CQ */
+ bnxt_qplib_lock_buddy_cq(qp, cq);
+ __bnxt_qplib_add_flush_qp(qp);
+ bnxt_qplib_unlock_buddy_cq(qp, cq);
}
+
+done:
return rc;
}
@@ -1990,7 +2277,6 @@ static int bnxt_qplib_cq_process_terminal(struct bnxt_qplib_cq *cq,
struct bnxt_qplib_cqe *cqe;
u32 sw_cons = 0, cqe_cons;
int rc = 0;
- u8 opcode = 0;
/* Check the Status */
if (hwcqe->status != CQ_TERMINAL_STATUS_OK)
@@ -2005,6 +2291,7 @@ static int bnxt_qplib_cq_process_terminal(struct bnxt_qplib_cq *cq,
"QPLIB: FP: CQ Process terminal qp is NULL");
return -EINVAL;
}
+
/* Must block new posting of SQ and RQ */
qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR;
@@ -2023,9 +2310,12 @@ static int bnxt_qplib_cq_process_terminal(struct bnxt_qplib_cq *cq,
cqe_cons, sq->hwq.max_elements);
goto do_rq;
}
- /* If we were in the middle of flushing, continue */
- if (sq->flush_in_progress)
- goto flush_sq;
+
+ if (qp->sq.flushed) {
+ dev_dbg(&cq->hwq.pdev->dev,
+ "%s: QPLIB: QP in Flush QP = %p\n", __func__, qp);
+ goto sq_done;
+ }
/* Terminal CQE can also include aggregated successful CQEs prior.
* So we must complete all CQEs from the current sq's cons to the
@@ -2055,11 +2345,6 @@ static int bnxt_qplib_cq_process_terminal(struct bnxt_qplib_cq *cq,
rc = -EAGAIN;
goto sq_done;
}
- sq->flush_in_progress = true;
-flush_sq:
- rc = __flush_sq(sq, qp, pcqe, budget);
- if (!rc)
- sq->flush_in_progress = false;
sq_done:
if (rc)
return rc;
@@ -2075,26 +2360,23 @@ do_rq:
cqe_cons, rq->hwq.max_elements);
goto done;
}
+
+ if (qp->rq.flushed) {
+ dev_dbg(&cq->hwq.pdev->dev,
+ "%s: QPLIB: QP in Flush QP = %p\n", __func__, qp);
+ rc = 0;
+ goto done;
+ }
+
/* Terminal CQE requires all posted RQEs to complete with FLUSHED_ERR
* from the current rq->cons to the rq->prod regardless what the
* rq->cons the terminal CQE indicates
*/
- rq->flush_in_progress = true;
- switch (qp->type) {
- case CMDQ_CREATE_QP1_TYPE_GSI:
- opcode = CQ_BASE_CQE_TYPE_RES_RAWETH_QP1;
- break;
- case CMDQ_CREATE_QP_TYPE_RC:
- opcode = CQ_BASE_CQE_TYPE_RES_RC;
- break;
- case CMDQ_CREATE_QP_TYPE_UD:
- opcode = CQ_BASE_CQE_TYPE_RES_UD;
- break;
- }
- rc = __flush_rq(rq, qp, opcode, pcqe, budget);
- if (!rc)
- rq->flush_in_progress = false;
+ /* Add qp to flush list of the CQ */
+ bnxt_qplib_lock_buddy_cq(qp, cq);
+ __bnxt_qplib_add_flush_qp(qp);
+ bnxt_qplib_unlock_buddy_cq(qp, cq);
done:
return rc;
}
@@ -2115,6 +2397,33 @@ static int bnxt_qplib_cq_process_cutoff(struct bnxt_qplib_cq *cq,
return 0;
}
+int bnxt_qplib_process_flush_list(struct bnxt_qplib_cq *cq,
+ struct bnxt_qplib_cqe *cqe,
+ int num_cqes)
+{
+ struct bnxt_qplib_qp *qp = NULL;
+ u32 budget = num_cqes;
+ unsigned long flags;
+
+ spin_lock_irqsave(&cq->hwq.lock, flags);
+ list_for_each_entry(qp, &cq->sqf_head, sq_flush) {
+ dev_dbg(&cq->hwq.pdev->dev,
+ "QPLIB: FP: Flushing SQ QP= %p",
+ qp);
+ __flush_sq(&qp->sq, qp, &cqe, &budget);
+ }
+
+ list_for_each_entry(qp, &cq->rqf_head, rq_flush) {
+ dev_dbg(&cq->hwq.pdev->dev,
+ "QPLIB: FP: Flushing RQ QP= %p",
+ qp);
+ __flush_rq(&qp->rq, qp, &cqe, &budget);
+ }
+ spin_unlock_irqrestore(&cq->hwq.lock, flags);
+
+ return num_cqes - budget;
+}
+
int bnxt_qplib_poll_cq(struct bnxt_qplib_cq *cq, struct bnxt_qplib_cqe *cqe,
int num_cqes, struct bnxt_qplib_qp **lib_qp)
{
@@ -2205,6 +2514,7 @@ void bnxt_qplib_req_notify_cq(struct bnxt_qplib_cq *cq, u32 arm_type)
spin_lock_irqsave(&cq->hwq.lock, flags);
if (arm_type)
bnxt_qplib_arm_cq(cq, arm_type);
-
+ /* Using cq->arm_state variable to track whether to issue cq handler */
+ atomic_set(&cq->arm_state, 1);
spin_unlock_irqrestore(&cq->hwq.lock, flags);
}
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
index 19176e0..8ead70c 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
@@ -220,19 +220,20 @@ struct bnxt_qplib_q {
u16 q_full_delta;
u16 max_sge;
u32 psn;
- bool flush_in_progress;
bool condition;
bool single;
bool send_phantom;
u32 phantom_wqe_cnt;
u32 phantom_cqe_cnt;
u32 next_cq_cons;
+ bool flushed;
};
struct bnxt_qplib_qp {
struct bnxt_qplib_pd *pd;
struct bnxt_qplib_dpi *dpi;
u64 qp_handle;
+#define BNXT_QPLIB_QP_ID_INVALID 0xFFFFFFFF
u32 id;
u8 type;
u8 sig_type;
@@ -296,6 +297,8 @@ struct bnxt_qplib_qp {
dma_addr_t sq_hdr_buf_map;
void *rq_hdr_buf;
dma_addr_t rq_hdr_buf_map;
+ struct list_head sq_flush;
+ struct list_head rq_flush;
};
#define BNXT_QPLIB_MAX_CQE_ENTRY_SIZE sizeof(struct cq_base)
@@ -351,6 +354,7 @@ struct bnxt_qplib_cq {
u16 period;
struct bnxt_qplib_hwq hwq;
u32 cnq_hw_ring_id;
+ struct bnxt_qplib_nq *nq;
bool resize_in_progress;
struct scatterlist *sghead;
u32 nmap;
@@ -360,6 +364,9 @@ struct bnxt_qplib_cq {
unsigned long flags;
#define CQ_FLAGS_RESIZE_IN_PROG 1
wait_queue_head_t waitq;
+ struct list_head sqf_head, rqf_head;
+ atomic_t arm_state;
+ spinlock_t compl_lock; /* synch CQ handlers */
};
#define BNXT_QPLIB_MAX_IRRQE_ENTRY_SIZE sizeof(struct xrrq_irrq)
@@ -400,6 +407,7 @@ struct bnxt_qplib_nq {
struct pci_dev *pdev;
int vector;
+ cpumask_t mask;
int budget;
bool requested;
struct tasklet_struct worker;
@@ -417,11 +425,19 @@ struct bnxt_qplib_nq {
(struct bnxt_qplib_nq *nq,
void *srq,
u8 event);
+ struct workqueue_struct *cqn_wq;
+ char name[32];
+};
+
+struct bnxt_qplib_nq_work {
+ struct work_struct work;
+ struct bnxt_qplib_nq *nq;
+ struct bnxt_qplib_cq *cq;
};
void bnxt_qplib_disable_nq(struct bnxt_qplib_nq *nq);
int bnxt_qplib_enable_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq,
- int msix_vector, int bar_reg_offset,
+ int nq_idx, int msix_vector, int bar_reg_offset,
int (*cqn_handler)(struct bnxt_qplib_nq *nq,
struct bnxt_qplib_cq *cq),
int (*srqn_handler)(struct bnxt_qplib_nq *nq,
@@ -453,4 +469,13 @@ bool bnxt_qplib_is_cq_empty(struct bnxt_qplib_cq *cq);
void bnxt_qplib_req_notify_cq(struct bnxt_qplib_cq *cq, u32 arm_type);
void bnxt_qplib_free_nq(struct bnxt_qplib_nq *nq);
int bnxt_qplib_alloc_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq);
+void bnxt_qplib_add_flush_qp(struct bnxt_qplib_qp *qp);
+void bnxt_qplib_del_flush_qp(struct bnxt_qplib_qp *qp);
+void bnxt_qplib_acquire_cq_locks(struct bnxt_qplib_qp *qp,
+ unsigned long *flags);
+void bnxt_qplib_release_cq_locks(struct bnxt_qplib_qp *qp,
+ unsigned long *flags);
+int bnxt_qplib_process_flush_list(struct bnxt_qplib_cq *cq,
+ struct bnxt_qplib_cqe *cqe,
+ int num_cqes);
#endif /* __BNXT_QPLIB_FP_H__ */
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
index 16e4275..391bb70 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
@@ -44,6 +44,9 @@
#include "roce_hsi.h"
#include "qplib_res.h"
#include "qplib_rcfw.h"
+#include "qplib_sp.h"
+#include "qplib_fp.h"
+
static void bnxt_qplib_service_creq(unsigned long data);
/* Hardware communication channel */
@@ -279,16 +282,29 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
struct creq_qp_event *qp_event)
{
struct bnxt_qplib_hwq *cmdq = &rcfw->cmdq;
+ struct creq_qp_error_notification *err_event;
struct bnxt_qplib_crsq *crsqe;
unsigned long flags;
+ struct bnxt_qplib_qp *qp;
u16 cbit, blocked = 0;
u16 cookie;
__le16 mcookie;
+ u32 qp_id;
switch (qp_event->event) {
case CREQ_QP_EVENT_EVENT_QP_ERROR_NOTIFICATION:
+ err_event = (struct creq_qp_error_notification *)qp_event;
+ qp_id = le32_to_cpu(err_event->xid);
+ qp = rcfw->qp_tbl[qp_id].qp_handle;
dev_dbg(&rcfw->pdev->dev,
"QPLIB: Received QP error notification");
+ dev_dbg(&rcfw->pdev->dev,
+ "QPLIB: qpid 0x%x, req_err=0x%x, resp_err=0x%x\n",
+ qp_id, err_event->req_err_state_reason,
+ err_event->res_err_state_reason);
+ bnxt_qplib_acquire_cq_locks(qp, &flags);
+ bnxt_qplib_mark_qp_error(qp);
+ bnxt_qplib_release_cq_locks(qp, &flags);
break;
default:
/* Command Response */
@@ -507,6 +523,7 @@ skip_ctx_setup:
void bnxt_qplib_free_rcfw_channel(struct bnxt_qplib_rcfw *rcfw)
{
+ kfree(rcfw->qp_tbl);
kfree(rcfw->crsqe_tbl);
bnxt_qplib_free_hwq(rcfw->pdev, &rcfw->cmdq);
bnxt_qplib_free_hwq(rcfw->pdev, &rcfw->creq);
@@ -514,7 +531,8 @@ void bnxt_qplib_free_rcfw_channel(struct bnxt_qplib_rcfw *rcfw)
}
int bnxt_qplib_alloc_rcfw_channel(struct pci_dev *pdev,
- struct bnxt_qplib_rcfw *rcfw)
+ struct bnxt_qplib_rcfw *rcfw,
+ int qp_tbl_sz)
{
rcfw->pdev = pdev;
rcfw->creq.max_elements = BNXT_QPLIB_CREQE_MAX_CNT;
@@ -541,6 +559,12 @@ int bnxt_qplib_alloc_rcfw_channel(struct pci_dev *pdev,
if (!rcfw->crsqe_tbl)
goto fail;
+ rcfw->qp_tbl_size = qp_tbl_sz;
+ rcfw->qp_tbl = kcalloc(qp_tbl_sz, sizeof(struct bnxt_qplib_qp_node),
+ GFP_KERNEL);
+ if (!rcfw->qp_tbl)
+ goto fail;
+
return 0;
fail:
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
index 09ce121..0ed312f 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
+++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
@@ -148,6 +148,11 @@ struct bnxt_qplib_rcfw_sbuf {
u32 size;
};
+struct bnxt_qplib_qp_node {
+ u32 qp_id; /* QP id */
+ void *qp_handle; /* ptr to qplib_qp */
+};
+
/* RCFW Communication Channels */
struct bnxt_qplib_rcfw {
struct pci_dev *pdev;
@@ -181,11 +186,13 @@ struct bnxt_qplib_rcfw {
/* Actual Cmd and Resp Queues */
struct bnxt_qplib_hwq cmdq;
struct bnxt_qplib_crsq *crsqe_tbl;
+ int qp_tbl_size;
+ struct bnxt_qplib_qp_node *qp_tbl;
};
void bnxt_qplib_free_rcfw_channel(struct bnxt_qplib_rcfw *rcfw);
int bnxt_qplib_alloc_rcfw_channel(struct pci_dev *pdev,
- struct bnxt_qplib_rcfw *rcfw);
+ struct bnxt_qplib_rcfw *rcfw, int qp_tbl_sz);
void bnxt_qplib_disable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw);
int bnxt_qplib_enable_rcfw_channel(struct pci_dev *pdev,
struct bnxt_qplib_rcfw *rcfw,
@@ -207,4 +214,5 @@ int bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw,
int bnxt_qplib_deinit_rcfw(struct bnxt_qplib_rcfw *rcfw);
int bnxt_qplib_init_rcfw(struct bnxt_qplib_rcfw *rcfw,
struct bnxt_qplib_ctx *ctx, int is_virtfn);
+void bnxt_qplib_mark_qp_error(void *qp_handle);
#endif /* __BNXT_QPLIB_RCFW_H__ */
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_res.c b/drivers/infiniband/hw/bnxt_re/qplib_res.c
index 62447b3..4e10170 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_res.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_res.c
@@ -468,9 +468,11 @@ static void bnxt_qplib_free_sgid_tbl(struct bnxt_qplib_res *res,
kfree(sgid_tbl->tbl);
kfree(sgid_tbl->hw_id);
kfree(sgid_tbl->ctx);
+ kfree(sgid_tbl->vlan);
sgid_tbl->tbl = NULL;
sgid_tbl->hw_id = NULL;
sgid_tbl->ctx = NULL;
+ sgid_tbl->vlan = NULL;
sgid_tbl->max = 0;
sgid_tbl->active = 0;
}
@@ -491,8 +493,15 @@ static int bnxt_qplib_alloc_sgid_tbl(struct bnxt_qplib_res *res,
if (!sgid_tbl->ctx)
goto out_free2;
+ sgid_tbl->vlan = kcalloc(max, sizeof(u8), GFP_KERNEL);
+ if (!sgid_tbl->vlan)
+ goto out_free3;
+
sgid_tbl->max = max;
return 0;
+out_free3:
+ kfree(sgid_tbl->ctx);
+ sgid_tbl->ctx = NULL;
out_free2:
kfree(sgid_tbl->hw_id);
sgid_tbl->hw_id = NULL;
@@ -514,6 +523,7 @@ static void bnxt_qplib_cleanup_sgid_tbl(struct bnxt_qplib_res *res,
}
memset(sgid_tbl->tbl, 0, sizeof(struct bnxt_qplib_gid) * sgid_tbl->max);
memset(sgid_tbl->hw_id, -1, sizeof(u16) * sgid_tbl->max);
+ memset(sgid_tbl->vlan, 0, sizeof(u8) * sgid_tbl->max);
sgid_tbl->active = 0;
}
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_res.h b/drivers/infiniband/hw/bnxt_re/qplib_res.h
index 2e48555..e872075 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_res.h
+++ b/drivers/infiniband/hw/bnxt_re/qplib_res.h
@@ -116,6 +116,7 @@ struct bnxt_qplib_sgid_tbl {
u16 max;
u16 active;
void *ctx;
+ u8 *vlan;
};
struct bnxt_qplib_pkey_tbl {
@@ -188,6 +189,7 @@ struct bnxt_qplib_res {
struct bnxt_qplib_sgid_tbl sgid_tbl;
struct bnxt_qplib_pkey_tbl pkey_tbl;
struct bnxt_qplib_dpi_tbl dpi_tbl;
+ bool prio;
};
#define to_bnxt_qplib(ptr, type, member) \
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/drivers/infiniband/hw/bnxt_re/qplib_sp.c
index ef91ab7..e277e54 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c
@@ -213,6 +213,7 @@ int bnxt_qplib_del_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
}
memcpy(&sgid_tbl->tbl[index], &bnxt_qplib_gid_zero,
sizeof(bnxt_qplib_gid_zero));
+ sgid_tbl->vlan[index] = 0;
sgid_tbl->active--;
dev_dbg(&res->pdev->dev,
"QPLIB: SGID deleted hw_id[0x%x] = 0x%x active = 0x%x",
@@ -265,28 +266,32 @@ int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
struct cmdq_add_gid req;
struct creq_add_gid_resp resp;
u16 cmd_flags = 0;
- u32 temp32[4];
- u16 temp16[3];
int rc;
RCFW_CMD_PREP(req, ADD_GID, cmd_flags);
- memcpy(temp32, gid->data, sizeof(struct bnxt_qplib_gid));
- req.gid[0] = cpu_to_be32(temp32[3]);
- req.gid[1] = cpu_to_be32(temp32[2]);
- req.gid[2] = cpu_to_be32(temp32[1]);
- req.gid[3] = cpu_to_be32(temp32[0]);
- if (vlan_id != 0xFFFF)
- req.vlan = cpu_to_le16((vlan_id &
- CMDQ_ADD_GID_VLAN_VLAN_ID_MASK) |
- CMDQ_ADD_GID_VLAN_TPID_TPID_8100 |
- CMDQ_ADD_GID_VLAN_VLAN_EN);
+ req.gid[0] = cpu_to_be32(((u32 *)gid->data)[3]);
+ req.gid[1] = cpu_to_be32(((u32 *)gid->data)[2]);
+ req.gid[2] = cpu_to_be32(((u32 *)gid->data)[1]);
+ req.gid[3] = cpu_to_be32(((u32 *)gid->data)[0]);
+ /*
+ * driver should ensure that all RoCE traffic is always VLAN
+ * tagged if RoCE traffic is running on non-zero VLAN ID or
+ * RoCE traffic is running on non-zero Priority.
+ */
+ if ((vlan_id != 0xFFFF) || res->prio) {
+ if (vlan_id != 0xFFFF)
+ req.vlan = cpu_to_le16
+ (vlan_id & CMDQ_ADD_GID_VLAN_VLAN_ID_MASK);
+ req.vlan |= cpu_to_le16
+ (CMDQ_ADD_GID_VLAN_TPID_TPID_8100 |
+ CMDQ_ADD_GID_VLAN_VLAN_EN);
+ }
/* MAC in network format */
- memcpy(temp16, smac, 6);
- req.src_mac[0] = cpu_to_be16(temp16[0]);
- req.src_mac[1] = cpu_to_be16(temp16[1]);
- req.src_mac[2] = cpu_to_be16(temp16[2]);
+ req.src_mac[0] = cpu_to_be16(((u16 *)smac)[0]);
+ req.src_mac[1] = cpu_to_be16(((u16 *)smac)[1]);
+ req.src_mac[2] = cpu_to_be16(((u16 *)smac)[2]);
rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
(void *)&resp, NULL, 0);
@@ -297,6 +302,9 @@ int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
/* Add GID to the sgid_tbl */
memcpy(&sgid_tbl->tbl[free_idx], gid, sizeof(*gid));
sgid_tbl->active++;
+ if (vlan_id != 0xFFFF)
+ sgid_tbl->vlan[free_idx] = 1;
+
dev_dbg(&res->pdev->dev,
"QPLIB: SGID added hw_id[0x%x] = 0x%x active = 0x%x",
free_idx, sgid_tbl->hw_id[free_idx], sgid_tbl->active);
@@ -306,6 +314,43 @@ int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
return 0;
}
+int bnxt_qplib_update_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
+ struct bnxt_qplib_gid *gid, u16 gid_idx,
+ u8 *smac)
+{
+ struct bnxt_qplib_res *res = to_bnxt_qplib(sgid_tbl,
+ struct bnxt_qplib_res,
+ sgid_tbl);
+ struct bnxt_qplib_rcfw *rcfw = res->rcfw;
+ struct creq_modify_gid_resp resp;
+ struct cmdq_modify_gid req;
+ int rc;
+ u16 cmd_flags = 0;
+
+ RCFW_CMD_PREP(req, MODIFY_GID, cmd_flags);
+
+ req.gid[0] = cpu_to_be32(((u32 *)gid->data)[3]);
+ req.gid[1] = cpu_to_be32(((u32 *)gid->data)[2]);
+ req.gid[2] = cpu_to_be32(((u32 *)gid->data)[1]);
+ req.gid[3] = cpu_to_be32(((u32 *)gid->data)[0]);
+ if (res->prio) {
+ req.vlan |= cpu_to_le16
+ (CMDQ_ADD_GID_VLAN_TPID_TPID_8100 |
+ CMDQ_ADD_GID_VLAN_VLAN_EN);
+ }
+
+ /* MAC in network format */
+ req.src_mac[0] = cpu_to_be16(((u16 *)smac)[0]);
+ req.src_mac[1] = cpu_to_be16(((u16 *)smac)[1]);
+ req.src_mac[2] = cpu_to_be16(((u16 *)smac)[2]);
+
+ req.gid_index = cpu_to_le16(gid_idx);
+
+ rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
+ (void *)&resp, NULL, 0);
+ return rc;
+}
+
/* pkeys */
int bnxt_qplib_get_pkey(struct bnxt_qplib_res *res,
struct bnxt_qplib_pkey_tbl *pkey_tbl, u16 index,
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.h b/drivers/infiniband/hw/bnxt_re/qplib_sp.h
index 2ce7e2a..1132258 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.h
+++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.h
@@ -135,6 +135,8 @@ int bnxt_qplib_del_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
struct bnxt_qplib_gid *gid, u8 *mac, u16 vlan_id,
bool update, u32 *index);
+int bnxt_qplib_update_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
+ struct bnxt_qplib_gid *gid, u16 gid_idx, u8 *smac);
int bnxt_qplib_get_pkey(struct bnxt_qplib_res *res,
struct bnxt_qplib_pkey_tbl *pkey_tbl, u16 index,
u16 *pkey);
diff --git a/drivers/infiniband/hw/bnxt_re/roce_hsi.h b/drivers/infiniband/hw/bnxt_re/roce_hsi.h
index fc23477..eeb55b2 100644
--- a/drivers/infiniband/hw/bnxt_re/roce_hsi.h
+++ b/drivers/infiniband/hw/bnxt_re/roce_hsi.h
@@ -1473,8 +1473,8 @@ struct cmdq_modify_gid {
u8 resp_size;
u8 reserved8;
__le64 resp_addr;
- __le32 gid[4];
- __le16 src_mac[3];
+ __be32 gid[4];
+ __be16 src_mac[3];
__le16 vlan;
#define CMDQ_MODIFY_GID_VLAN_VLAN_ID_MASK 0xfffUL
#define CMDQ_MODIFY_GID_VLAN_VLAN_ID_SFT 0
diff --git a/drivers/infiniband/hw/cxgb3/iwch.c b/drivers/infiniband/hw/cxgb3/iwch.c
index 47b2ce2..591de31 100644
--- a/drivers/infiniband/hw/cxgb3/iwch.c
+++ b/drivers/infiniband/hw/cxgb3/iwch.c
@@ -45,7 +45,6 @@
MODULE_AUTHOR("Boyd Faulkner, Steve Wise");
MODULE_DESCRIPTION("Chelsio T3 RDMA Driver");
MODULE_LICENSE("Dual BSD/GPL");
-MODULE_VERSION(DRV_VERSION);
static void open_rnic_dev(struct t3cdev *);
static void close_rnic_dev(struct t3cdev *);
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c
index 0cd0c1f..099e76f 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c
@@ -1336,8 +1336,7 @@ static int iwch_port_immutable(struct ib_device *ibdev, u8 port_num,
return 0;
}
-static void get_dev_fw_ver_str(struct ib_device *ibdev, char *str,
- size_t str_len)
+static void get_dev_fw_ver_str(struct ib_device *ibdev, char *str)
{
struct iwch_dev *iwch_dev = to_iwch_dev(ibdev);
struct ethtool_drvinfo info;
@@ -1345,7 +1344,7 @@ static void get_dev_fw_ver_str(struct ib_device *ibdev, char *str,
pr_debug("%s dev 0x%p\n", __func__, iwch_dev);
lldev->ethtool_ops->get_drvinfo(lldev, &info);
- snprintf(str, str_len, "%s", info.fw_version);
+ snprintf(str, IB_FW_VERSION_NAME_MAX, "%s", info.fw_version);
}
int iwch_register_device(struct iwch_dev *dev)
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
index e49b34c..ceaa2fa 100644
--- a/drivers/infiniband/hw/cxgb4/cm.c
+++ b/drivers/infiniband/hw/cxgb4/cm.c
@@ -2871,7 +2871,6 @@ static int close_con_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
return 0;
pr_debug("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
- BUG_ON(!ep);
/* The cm_id may be null if we failed to connect */
mutex_lock(&ep->com.mutex);
diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c
index ae0b79a..fc886f8 100644
--- a/drivers/infiniband/hw/cxgb4/device.c
+++ b/drivers/infiniband/hw/cxgb4/device.c
@@ -44,7 +44,6 @@
MODULE_AUTHOR("Steve Wise");
MODULE_DESCRIPTION("Chelsio T4/T5 RDMA Driver");
MODULE_LICENSE("Dual BSD/GPL");
-MODULE_VERSION(DRV_VERSION);
static int allow_db_fc_on_t5;
module_param(allow_db_fc_on_t5, int, 0644);
diff --git a/drivers/infiniband/hw/cxgb4/provider.c b/drivers/infiniband/hw/cxgb4/provider.c
index 0771e9a..346e833 100644
--- a/drivers/infiniband/hw/cxgb4/provider.c
+++ b/drivers/infiniband/hw/cxgb4/provider.c
@@ -517,14 +517,13 @@ static int c4iw_port_immutable(struct ib_device *ibdev, u8 port_num,
return 0;
}
-static void get_dev_fw_str(struct ib_device *dev, char *str,
- size_t str_len)
+static void get_dev_fw_str(struct ib_device *dev, char *str)
{
struct c4iw_dev *c4iw_dev = container_of(dev, struct c4iw_dev,
ibdev);
pr_debug("%s dev 0x%p\n", __func__, dev);
- snprintf(str, str_len, "%u.%u.%u.%u",
+ snprintf(str, IB_FW_VERSION_NAME_MAX, "%u.%u.%u.%u",
FW_HDR_FW_VER_MAJOR_G(c4iw_dev->rdev.lldi.fw_vers),
FW_HDR_FW_VER_MINOR_G(c4iw_dev->rdev.lldi.fw_vers),
FW_HDR_FW_VER_MICRO_G(c4iw_dev->rdev.lldi.fw_vers),
diff --git a/drivers/infiniband/hw/hfi1/Kconfig b/drivers/infiniband/hw/hfi1/Kconfig
index f6ea088..7b146b6 100644
--- a/drivers/infiniband/hw/hfi1/Kconfig
+++ b/drivers/infiniband/hw/hfi1/Kconfig
@@ -13,13 +13,6 @@ config HFI1_DEBUG_SDMA_ORDER
---help---
This is a debug flag to test for out of order
sdma completions for unit testing
-config HFI1_VERBS_31BIT_PSN
- bool "HFI1 enable 31 bit PSN"
- depends on INFINIBAND_HFI1
- default y
- ---help---
- Setting this enables 31 BIT PSN
- For verbs RC/UC
config SDMA_VERBOSITY
bool "Config SDMA Verbosity"
depends on INFINIBAND_HFI1
diff --git a/drivers/infiniband/hw/hfi1/Makefile b/drivers/infiniband/hw/hfi1/Makefile
index 88085f6..66d538c 100644
--- a/drivers/infiniband/hw/hfi1/Makefile
+++ b/drivers/infiniband/hw/hfi1/Makefile
@@ -8,7 +8,7 @@
obj-$(CONFIG_INFINIBAND_HFI1) += hfi1.o
hfi1-y := affinity.o chip.o device.o driver.o efivar.o \
- eprom.o file_ops.o firmware.o \
+ eprom.o exp_rcv.o file_ops.o firmware.o \
init.o intr.o mad.o mmu_rb.o pcie.o pio.o pio_copy.o platform.o \
qp.o qsfp.o rc.o ruc.o sdma.o sysfs.o trace.o \
uc.o ud.o user_exp_rcv.o user_pages.o user_sdma.o verbs.o \
diff --git a/drivers/infiniband/hw/hfi1/affinity.c b/drivers/infiniband/hw/hfi1/affinity.c
index e2cd2cd..a97055d 100644
--- a/drivers/infiniband/hw/hfi1/affinity.c
+++ b/drivers/infiniband/hw/hfi1/affinity.c
@@ -1,5 +1,5 @@
/*
- * Copyright(c) 2015, 2016 Intel Corporation.
+ * Copyright(c) 2015 - 2017 Intel Corporation.
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
@@ -335,10 +335,10 @@ static void hfi1_update_sdma_affinity(struct hfi1_msix_entry *msix, int cpu)
sde->cpu = cpu;
cpumask_clear(&msix->mask);
cpumask_set_cpu(cpu, &msix->mask);
- dd_dev_dbg(dd, "IRQ vector: %u, type %s engine %u -> cpu: %d\n",
- msix->msix.vector, irq_type_names[msix->type],
+ dd_dev_dbg(dd, "IRQ: %u, type %s engine %u -> cpu: %d\n",
+ msix->irq, irq_type_names[msix->type],
sde->this_idx, cpu);
- irq_set_affinity_hint(msix->msix.vector, &msix->mask);
+ irq_set_affinity_hint(msix->irq, &msix->mask);
/*
* Set the new cpu in the hfi1_affinity_node and clean
@@ -387,7 +387,7 @@ static void hfi1_setup_sdma_notifier(struct hfi1_msix_entry *msix)
{
struct irq_affinity_notify *notify = &msix->notify;
- notify->irq = msix->msix.vector;
+ notify->irq = msix->irq;
notify->notify = hfi1_irq_notifier_notify;
notify->release = hfi1_irq_notifier_release;
@@ -472,10 +472,10 @@ static int get_irq_affinity(struct hfi1_devdata *dd,
}
cpumask_set_cpu(cpu, &msix->mask);
- dd_dev_info(dd, "IRQ vector: %u, type %s %s -> cpu: %d\n",
- msix->msix.vector, irq_type_names[msix->type],
+ dd_dev_info(dd, "IRQ: %u, type %s %s -> cpu: %d\n",
+ msix->irq, irq_type_names[msix->type],
extra, cpu);
- irq_set_affinity_hint(msix->msix.vector, &msix->mask);
+ irq_set_affinity_hint(msix->irq, &msix->mask);
if (msix->type == IRQ_SDMA) {
sde->cpu = cpu;
@@ -533,7 +533,7 @@ void hfi1_put_irq_affinity(struct hfi1_devdata *dd,
}
}
- irq_set_affinity_hint(msix->msix.vector, NULL);
+ irq_set_affinity_hint(msix->irq, NULL);
cpumask_clear(&msix->mask);
mutex_unlock(&node_affinity.lock);
}
diff --git a/drivers/infiniband/hw/hfi1/affinity.h b/drivers/infiniband/hw/hfi1/affinity.h
index e78c7aa..2a1e374 100644
--- a/drivers/infiniband/hw/hfi1/affinity.h
+++ b/drivers/infiniband/hw/hfi1/affinity.h
@@ -1,5 +1,5 @@
/*
- * Copyright(c) 2015, 2016 Intel Corporation.
+ * Copyright(c) 2015 - 2017 Intel Corporation.
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
@@ -75,24 +75,26 @@ struct hfi1_msix_entry;
/* Initialize non-HT cpu cores mask */
void init_real_cpu_mask(void);
/* Initialize driver affinity data */
-int hfi1_dev_affinity_init(struct hfi1_devdata *);
+int hfi1_dev_affinity_init(struct hfi1_devdata *dd);
/*
* Set IRQ affinity to a CPU. The function will determine the
* CPU and set the affinity to it.
*/
-int hfi1_get_irq_affinity(struct hfi1_devdata *, struct hfi1_msix_entry *);
+int hfi1_get_irq_affinity(struct hfi1_devdata *dd,
+ struct hfi1_msix_entry *msix);
/*
* Remove the IRQ's CPU affinity. This function also updates
* any internal CPU tracking data
*/
-void hfi1_put_irq_affinity(struct hfi1_devdata *, struct hfi1_msix_entry *);
+void hfi1_put_irq_affinity(struct hfi1_devdata *dd,
+ struct hfi1_msix_entry *msix);
/*
* Determine a CPU affinity for a user process, if the process does not
* have an affinity set yet.
*/
-int hfi1_get_proc_affinity(int);
+int hfi1_get_proc_affinity(int node);
/* Release a CPU used by a user process. */
-void hfi1_put_proc_affinity(int);
+void hfi1_put_proc_affinity(int cpu);
struct hfi1_affinity_node {
int node;
diff --git a/drivers/infiniband/hw/hfi1/aspm.h b/drivers/infiniband/hw/hfi1/aspm.h
index 794e681..522b40e 100644
--- a/drivers/infiniband/hw/hfi1/aspm.h
+++ b/drivers/infiniband/hw/hfi1/aspm.h
@@ -237,14 +237,17 @@ static inline void aspm_disable_all(struct hfi1_devdata *dd)
{
struct hfi1_ctxtdata *rcd;
unsigned long flags;
- unsigned i;
+ u16 i;
for (i = 0; i < dd->first_dyn_alloc_ctxt; i++) {
- rcd = dd->rcd[i];
- del_timer_sync(&rcd->aspm_timer);
- spin_lock_irqsave(&rcd->aspm_lock, flags);
- rcd->aspm_intr_enable = false;
- spin_unlock_irqrestore(&rcd->aspm_lock, flags);
+ rcd = hfi1_rcd_get_by_index(dd, i);
+ if (rcd) {
+ del_timer_sync(&rcd->aspm_timer);
+ spin_lock_irqsave(&rcd->aspm_lock, flags);
+ rcd->aspm_intr_enable = false;
+ spin_unlock_irqrestore(&rcd->aspm_lock, flags);
+ hfi1_rcd_put(rcd);
+ }
}
aspm_disable(dd);
@@ -256,7 +259,7 @@ static inline void aspm_enable_all(struct hfi1_devdata *dd)
{
struct hfi1_ctxtdata *rcd;
unsigned long flags;
- unsigned i;
+ u16 i;
aspm_enable(dd);
@@ -264,11 +267,14 @@ static inline void aspm_enable_all(struct hfi1_devdata *dd)
return;
for (i = 0; i < dd->first_dyn_alloc_ctxt; i++) {
- rcd = dd->rcd[i];
- spin_lock_irqsave(&rcd->aspm_lock, flags);
- rcd->aspm_intr_enable = true;
- rcd->aspm_enabled = true;
- spin_unlock_irqrestore(&rcd->aspm_lock, flags);
+ rcd = hfi1_rcd_get_by_index(dd, i);
+ if (rcd) {
+ spin_lock_irqsave(&rcd->aspm_lock, flags);
+ rcd->aspm_intr_enable = true;
+ rcd->aspm_enabled = true;
+ spin_unlock_irqrestore(&rcd->aspm_lock, flags);
+ hfi1_rcd_put(rcd);
+ }
}
}
@@ -284,13 +290,18 @@ static inline void aspm_ctx_init(struct hfi1_ctxtdata *rcd)
static inline void aspm_init(struct hfi1_devdata *dd)
{
- unsigned i;
+ struct hfi1_ctxtdata *rcd;
+ u16 i;
spin_lock_init(&dd->aspm_lock);
dd->aspm_supported = aspm_hw_l1_supported(dd);
- for (i = 0; i < dd->first_dyn_alloc_ctxt; i++)
- aspm_ctx_init(dd->rcd[i]);
+ for (i = 0; i < dd->first_dyn_alloc_ctxt; i++) {
+ rcd = hfi1_rcd_get_by_index(dd, i);
+ if (rcd)
+ aspm_ctx_init(rcd);
+ hfi1_rcd_put(rcd);
+ }
/* Start with ASPM disabled */
aspm_hw_set_l1_ent_latency(dd);
diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c
index 94b54850..b2ed4b9 100644
--- a/drivers/infiniband/hw/hfi1/chip.c
+++ b/drivers/infiniband/hw/hfi1/chip.c
@@ -1012,14 +1012,15 @@ static struct flag_table dc8051_info_err_flags[] = {
*/
static struct flag_table dc8051_info_host_msg_flags[] = {
FLAG_ENTRY0("Host request done", 0x0001),
- FLAG_ENTRY0("BC SMA message", 0x0002),
- FLAG_ENTRY0("BC PWR_MGM message", 0x0004),
+ FLAG_ENTRY0("BC PWR_MGM message", 0x0002),
+ FLAG_ENTRY0("BC SMA message", 0x0004),
FLAG_ENTRY0("BC Unknown message (BCC)", 0x0008),
FLAG_ENTRY0("BC Unknown message (LCB)", 0x0010),
FLAG_ENTRY0("External device config request", 0x0020),
FLAG_ENTRY0("VerifyCap all frames received", 0x0040),
FLAG_ENTRY0("LinkUp achieved", 0x0080),
FLAG_ENTRY0("Link going down", 0x0100),
+ FLAG_ENTRY0("Link width downgraded", 0x0200),
};
static u32 encoded_size(u32 size);
@@ -1064,8 +1065,13 @@ static int do_8051_command(struct hfi1_devdata *dd, u32 type, u64 in_data,
static int read_idle_sma(struct hfi1_devdata *dd, u64 *data);
static int thermal_init(struct hfi1_devdata *dd);
+static void update_statusp(struct hfi1_pportdata *ppd, u32 state);
static int wait_logical_linkstate(struct hfi1_pportdata *ppd, u32 state,
int msecs);
+static void log_state_transition(struct hfi1_pportdata *ppd, u32 state);
+static void log_physical_state(struct hfi1_pportdata *ppd, u32 state);
+static int wait_physical_linkstate(struct hfi1_pportdata *ppd, u32 state,
+ int msecs);
static void read_planned_down_reason_code(struct hfi1_devdata *dd, u8 *pdrrc);
static void read_link_down_reason(struct hfi1_devdata *dd, u8 *ldr);
static void handle_temp_err(struct hfi1_devdata *dd);
@@ -1294,25 +1300,71 @@ CNTR_ELEM(#name, \
CNTR_SYNTH, \
access_ibp_##cntr)
+/**
+ * hfi_addr_from_offset - return addr for readq/writeq
+ * @dd - the dd device
+ * @offset - the offset of the CSR within bar0
+ *
+ * This routine selects the appropriate base address
+ * based on the indicated offset.
+ */
+static inline void __iomem *hfi1_addr_from_offset(
+ const struct hfi1_devdata *dd,
+ u32 offset)
+{
+ if (offset >= dd->base2_start)
+ return dd->kregbase2 + (offset - dd->base2_start);
+ return dd->kregbase1 + offset;
+}
+
+/**
+ * read_csr - read CSR at the indicated offset
+ * @dd - the dd device
+ * @offset - the offset of the CSR within bar0
+ *
+ * Return: the value read or all FF's if there
+ * is no mapping
+ */
u64 read_csr(const struct hfi1_devdata *dd, u32 offset)
{
- if (dd->flags & HFI1_PRESENT) {
- return readq((void __iomem *)dd->kregbase + offset);
- }
+ if (dd->flags & HFI1_PRESENT)
+ return readq(hfi1_addr_from_offset(dd, offset));
return -1;
}
+/**
+ * write_csr - write CSR at the indicated offset
+ * @dd - the dd device
+ * @offset - the offset of the CSR within bar0
+ * @value - value to write
+ */
void write_csr(const struct hfi1_devdata *dd, u32 offset, u64 value)
{
- if (dd->flags & HFI1_PRESENT)
- writeq(value, (void __iomem *)dd->kregbase + offset);
+ if (dd->flags & HFI1_PRESENT) {
+ void __iomem *base = hfi1_addr_from_offset(dd, offset);
+
+ /* avoid write to RcvArray */
+ if (WARN_ON(offset >= RCV_ARRAY && offset < dd->base2_start))
+ return;
+ writeq(value, base);
+ }
}
+/**
+ * get_csr_addr - return te iomem address for offset
+ * @dd - the dd device
+ * @offset - the offset of the CSR within bar0
+ *
+ * Return: The iomem address to use in subsequent
+ * writeq/readq operations.
+ */
void __iomem *get_csr_addr(
- struct hfi1_devdata *dd,
+ const struct hfi1_devdata *dd,
u32 offset)
{
- return (void __iomem *)dd->kregbase + offset;
+ if (dd->flags & HFI1_PRESENT)
+ return hfi1_addr_from_offset(dd, offset);
+ return NULL;
}
static inline u64 read_write_csr(const struct hfi1_devdata *dd, u32 csr,
@@ -5496,7 +5548,7 @@ static void update_rcverr_timer(unsigned long opaque)
set_link_down_reason(
ppd, OPA_LINKDOWN_REASON_EXCESSIVE_BUFFER_OVERRUN, 0,
OPA_LINKDOWN_REASON_EXCESSIVE_BUFFER_OVERRUN);
- queue_work(ppd->hfi1_wq, &ppd->link_bounce_work);
+ queue_work(ppd->link_wq, &ppd->link_bounce_work);
}
dd->rcv_ovfl_cnt = (u32)cur_ovfl_cnt;
@@ -6051,7 +6103,7 @@ static void handle_qsfp_int(struct hfi1_devdata *dd, u32 src_ctx, u64 reg)
* will not happen. We have to do it here
* before turning the DC off.
*/
- queue_work(ppd->hfi1_wq, &ppd->link_down_work);
+ queue_work(ppd->link_wq, &ppd->link_down_work);
}
} else {
dd_dev_info(dd, "%s: QSFP module inserted\n",
@@ -6086,7 +6138,7 @@ static void handle_qsfp_int(struct hfi1_devdata *dd, u32 src_ctx, u64 reg)
/* Schedule the QSFP work only if there is a cable attached. */
if (qsfp_mod_present(ppd))
- queue_work(ppd->hfi1_wq, &ppd->qsfp_info.qsfp_work);
+ queue_work(ppd->link_wq, &ppd->qsfp_info.qsfp_work);
}
static int request_host_lcb_access(struct hfi1_devdata *dd)
@@ -6735,13 +6787,17 @@ static void wait_for_freeze_status(struct hfi1_devdata *dd, int freeze)
static void rxe_freeze(struct hfi1_devdata *dd)
{
int i;
+ struct hfi1_ctxtdata *rcd;
/* disable port */
clear_rcvctrl(dd, RCV_CTRL_RCV_PORT_ENABLE_SMASK);
/* disable all receive contexts */
- for (i = 0; i < dd->num_rcv_contexts; i++)
- hfi1_rcvctrl(dd, HFI1_RCVCTRL_CTXT_DIS, i);
+ for (i = 0; i < dd->num_rcv_contexts; i++) {
+ rcd = hfi1_rcd_get_by_index(dd, i);
+ hfi1_rcvctrl(dd, HFI1_RCVCTRL_CTXT_DIS, rcd);
+ hfi1_rcd_put(rcd);
+ }
}
/*
@@ -6753,21 +6809,24 @@ static void rxe_freeze(struct hfi1_devdata *dd)
static void rxe_kernel_unfreeze(struct hfi1_devdata *dd)
{
u32 rcvmask;
- int i;
+ u16 i;
+ struct hfi1_ctxtdata *rcd;
/* enable all kernel contexts */
for (i = 0; i < dd->num_rcv_contexts; i++) {
- struct hfi1_ctxtdata *rcd = dd->rcd[i];
+ rcd = hfi1_rcd_get_by_index(dd, i);
/* Ensure all non-user contexts(including vnic) are enabled */
- if (!rcd || !rcd->sc || (rcd->sc->type == SC_USER))
+ if (!rcd || !rcd->sc || (rcd->sc->type == SC_USER)) {
+ hfi1_rcd_put(rcd);
continue;
-
+ }
rcvmask = HFI1_RCVCTRL_CTXT_ENB;
/* HFI1_RCVCTRL_TAILUPD_[ENB|DIS] needs to be set explicitly */
- rcvmask |= HFI1_CAP_KGET_MASK(dd->rcd[i]->flags, DMA_RTAIL) ?
+ rcvmask |= HFI1_CAP_KGET_MASK(rcd->flags, DMA_RTAIL) ?
HFI1_RCVCTRL_TAILUPD_ENB : HFI1_RCVCTRL_TAILUPD_DIS;
- hfi1_rcvctrl(dd, rcvmask, i);
+ hfi1_rcvctrl(dd, rcvmask, rcd);
+ hfi1_rcd_put(rcd);
}
/* enable port */
@@ -6906,7 +6965,7 @@ static void reset_neighbor_info(struct hfi1_pportdata *ppd)
static const char * const link_down_reason_strs[] = {
[OPA_LINKDOWN_REASON_NONE] = "None",
- [OPA_LINKDOWN_REASON_RCV_ERROR_0] = "Recive error 0",
+ [OPA_LINKDOWN_REASON_RCV_ERROR_0] = "Receive error 0",
[OPA_LINKDOWN_REASON_BAD_PKT_LEN] = "Bad packet length",
[OPA_LINKDOWN_REASON_PKT_TOO_LONG] = "Packet too long",
[OPA_LINKDOWN_REASON_PKT_TOO_SHORT] = "Packet too short",
@@ -6996,6 +7055,7 @@ void handle_link_down(struct work_struct *work)
/* Go offline first, then deal with reading/writing through 8051 */
was_up = !!(ppd->host_link_state & HLS_UP);
set_link_state(ppd, HLS_DN_OFFLINE);
+ xchg(&ppd->is_link_down_queued, 0);
if (was_up) {
lcl_reason = 0;
@@ -7330,7 +7390,7 @@ void handle_verify_cap(struct work_struct *work)
struct hfi1_devdata *dd = ppd->dd;
u64 reg;
u8 power_management;
- u8 continious;
+ u8 continuous;
u8 vcu;
u8 vau;
u8 z;
@@ -7349,7 +7409,7 @@ void handle_verify_cap(struct work_struct *work)
lcb_shutdown(dd, 0);
adjust_lcb_for_fpga_serdes(dd);
- read_vc_remote_phy(dd, &power_management, &continious);
+ read_vc_remote_phy(dd, &power_management, &continuous);
read_vc_remote_fabric(dd, &vau, &z, &vcu, &vl15buf,
&partner_supported_crc);
read_vc_remote_link_width(dd, &remote_tx_rate, &link_widths);
@@ -7363,7 +7423,7 @@ void handle_verify_cap(struct work_struct *work)
get_link_widths(dd, &active_tx, &active_rx);
dd_dev_info(dd,
"Peer PHY: power management 0x%x, continuous updates 0x%x\n",
- (int)power_management, (int)continious);
+ (int)power_management, (int)continuous);
dd_dev_info(dd,
"Peer Fabric: vAU %d, Z %d, vCU %d, vl15 credits 0x%x, CRC sizes 0x%x\n",
(int)vau, (int)z, (int)vcu, (int)vl15buf,
@@ -7689,12 +7749,12 @@ static void handle_8051_interrupt(struct hfi1_devdata *dd, u32 unused, u64 reg)
host_msg &= ~(u64)HOST_REQ_DONE;
}
if (host_msg & BC_SMA_MSG) {
- queue_work(ppd->hfi1_wq, &ppd->sma_message_work);
+ queue_work(ppd->link_wq, &ppd->sma_message_work);
host_msg &= ~(u64)BC_SMA_MSG;
}
if (host_msg & LINKUP_ACHIEVED) {
dd_dev_info(dd, "8051: Link up\n");
- queue_work(ppd->hfi1_wq, &ppd->link_up_work);
+ queue_work(ppd->link_wq, &ppd->link_up_work);
host_msg &= ~(u64)LINKUP_ACHIEVED;
}
if (host_msg & EXT_DEVICE_CFG_REQ) {
@@ -7702,7 +7762,7 @@ static void handle_8051_interrupt(struct hfi1_devdata *dd, u32 unused, u64 reg)
host_msg &= ~(u64)EXT_DEVICE_CFG_REQ;
}
if (host_msg & VERIFY_CAP_FRAME) {
- queue_work(ppd->hfi1_wq, &ppd->link_vc_work);
+ queue_work(ppd->link_wq, &ppd->link_vc_work);
host_msg &= ~(u64)VERIFY_CAP_FRAME;
}
if (host_msg & LINK_GOING_DOWN) {
@@ -7717,7 +7777,7 @@ static void handle_8051_interrupt(struct hfi1_devdata *dd, u32 unused, u64 reg)
host_msg &= ~(u64)LINK_GOING_DOWN;
}
if (host_msg & LINK_WIDTH_DOWNGRADED) {
- queue_work(ppd->hfi1_wq, &ppd->link_downgrade_work);
+ queue_work(ppd->link_wq, &ppd->link_downgrade_work);
host_msg &= ~(u64)LINK_WIDTH_DOWNGRADED;
}
if (host_msg) {
@@ -7752,15 +7812,22 @@ static void handle_8051_interrupt(struct hfi1_devdata *dd, u32 unused, u64 reg)
if (queue_link_down) {
/*
* if the link is already going down or disabled, do not
- * queue another
+ * queue another. If there's a link down entry already
+ * queued, don't queue another one.
*/
if ((ppd->host_link_state &
(HLS_GOING_OFFLINE | HLS_LINK_COOLDOWN)) ||
ppd->link_enabled == 0) {
- dd_dev_info(dd, "%s: not queuing link down\n",
- __func__);
+ dd_dev_info(dd, "%s: not queuing link down. host_link_state %x, link_enabled %x\n",
+ __func__, ppd->host_link_state,
+ ppd->link_enabled);
} else {
- queue_work(ppd->hfi1_wq, &ppd->link_down_work);
+ if (xchg(&ppd->is_link_down_queued, 1) == 1)
+ dd_dev_info(dd,
+ "%s: link down request already queued\n",
+ __func__);
+ else
+ queue_work(ppd->link_wq, &ppd->link_down_work);
}
}
}
@@ -7968,7 +8035,7 @@ static void handle_dcc_err(struct hfi1_devdata *dd, u32 unused, u64 reg)
dd_dev_info_ratelimited(dd, "%s: PortErrorAction bounce\n",
__func__);
set_link_down_reason(ppd, lcl_reason, 0, lcl_reason);
- queue_work(ppd->hfi1_wq, &ppd->link_bounce_work);
+ queue_work(ppd->link_wq, &ppd->link_bounce_work);
}
}
@@ -8052,7 +8119,7 @@ static void is_rcv_avail_int(struct hfi1_devdata *dd, unsigned int source)
char *err_detail;
if (likely(source < dd->num_rcv_contexts)) {
- rcd = dd->rcd[source];
+ rcd = hfi1_rcd_get_by_index(dd, source);
if (rcd) {
/* Check for non-user contexts, including vnic */
if ((source < dd->first_dyn_alloc_ctxt) ||
@@ -8060,6 +8127,8 @@ static void is_rcv_avail_int(struct hfi1_devdata *dd, unsigned int source)
rcd->do_interrupt(rcd, 0);
else
handle_user_interrupt(rcd);
+
+ hfi1_rcd_put(rcd);
return; /* OK */
}
/* received an interrupt, but no rcd */
@@ -8081,12 +8150,14 @@ static void is_rcv_urgent_int(struct hfi1_devdata *dd, unsigned int source)
char *err_detail;
if (likely(source < dd->num_rcv_contexts)) {
- rcd = dd->rcd[source];
+ rcd = hfi1_rcd_get_by_index(dd, source);
if (rcd) {
/* only pay attention to user urgent interrupts */
if ((source >= dd->first_dyn_alloc_ctxt) &&
(!rcd->sc || (rcd->sc->type == SC_USER)))
handle_user_interrupt(rcd);
+
+ hfi1_rcd_put(rcd);
return; /* OK */
}
/* received an interrupt, but no rcd */
@@ -8219,8 +8290,8 @@ static irqreturn_t sdma_interrupt(int irq, void *data)
/* handle the interrupt(s) */
sdma_engine_interrupt(sde, status);
} else {
- dd_dev_err(dd, "SDMA engine %u interrupt, but no status bits set\n",
- sde->this_idx);
+ dd_dev_err_ratelimited(dd, "SDMA engine %u interrupt, but no status bits set\n",
+ sde->this_idx);
}
return IRQ_HANDLED;
}
@@ -8291,7 +8362,7 @@ static irqreturn_t receive_context_interrupt(int irq, void *data)
int disposition;
int present;
- trace_hfi1_receive_interrupt(dd, rcd->ctxt);
+ trace_hfi1_receive_interrupt(dd, rcd);
this_cpu_inc(*dd->int_counter);
aspm_ctx_disable(rcd);
@@ -8781,6 +8852,20 @@ static void read_remote_device_id(struct hfi1_devdata *dd, u16 *device_id,
& REMOTE_DEVICE_REV_MASK;
}
+int write_host_interface_version(struct hfi1_devdata *dd, u8 version)
+{
+ u32 frame;
+ u32 mask;
+
+ mask = (HOST_INTERFACE_VERSION_MASK << HOST_INTERFACE_VERSION_SHIFT);
+ read_8051_config(dd, RESERVED_REGISTERS, GENERAL_CONFIG, &frame);
+ /* Clear, then set field */
+ frame &= ~mask;
+ frame |= ((u32)version << HOST_INTERFACE_VERSION_SHIFT);
+ return load_8051_config(dd, RESERVED_REGISTERS, GENERAL_CONFIG,
+ frame);
+}
+
void read_misc_status(struct hfi1_devdata *dd, u8 *ver_major, u8 *ver_minor,
u8 *ver_patch)
{
@@ -9257,12 +9342,6 @@ int start_link(struct hfi1_pportdata *ppd)
*/
tune_serdes(ppd);
- if (!ppd->link_enabled) {
- dd_dev_info(ppd->dd,
- "%s: stopping link start because link is disabled\n",
- __func__);
- return 0;
- }
if (!ppd->driver_link_ready) {
dd_dev_info(ppd->dd,
"%s: stopping link start because driver is not ready\n",
@@ -9373,13 +9452,13 @@ static int handle_qsfp_error_conditions(struct hfi1_pportdata *ppd,
if ((qsfp_interrupt_status[0] & QSFP_HIGH_TEMP_ALARM) ||
(qsfp_interrupt_status[0] & QSFP_HIGH_TEMP_WARNING))
- dd_dev_info(dd, "%s: QSFP cable temperature too high\n",
- __func__);
+ dd_dev_err(dd, "%s: QSFP cable temperature too high\n",
+ __func__);
if ((qsfp_interrupt_status[0] & QSFP_LOW_TEMP_ALARM) ||
(qsfp_interrupt_status[0] & QSFP_LOW_TEMP_WARNING))
- dd_dev_info(dd, "%s: QSFP cable temperature too low\n",
- __func__);
+ dd_dev_err(dd, "%s: QSFP cable temperature too low\n",
+ __func__);
/*
* The remaining alarms/warnings don't matter if the link is down.
@@ -9389,75 +9468,75 @@ static int handle_qsfp_error_conditions(struct hfi1_pportdata *ppd,
if ((qsfp_interrupt_status[1] & QSFP_HIGH_VCC_ALARM) ||
(qsfp_interrupt_status[1] & QSFP_HIGH_VCC_WARNING))
- dd_dev_info(dd, "%s: QSFP supply voltage too high\n",
- __func__);
+ dd_dev_err(dd, "%s: QSFP supply voltage too high\n",
+ __func__);
if ((qsfp_interrupt_status[1] & QSFP_LOW_VCC_ALARM) ||
(qsfp_interrupt_status[1] & QSFP_LOW_VCC_WARNING))
- dd_dev_info(dd, "%s: QSFP supply voltage too low\n",
- __func__);
+ dd_dev_err(dd, "%s: QSFP supply voltage too low\n",
+ __func__);
/* Byte 2 is vendor specific */
if ((qsfp_interrupt_status[3] & QSFP_HIGH_POWER_ALARM) ||
(qsfp_interrupt_status[3] & QSFP_HIGH_POWER_WARNING))
- dd_dev_info(dd, "%s: Cable RX channel 1/2 power too high\n",
- __func__);
+ dd_dev_err(dd, "%s: Cable RX channel 1/2 power too high\n",
+ __func__);
if ((qsfp_interrupt_status[3] & QSFP_LOW_POWER_ALARM) ||
(qsfp_interrupt_status[3] & QSFP_LOW_POWER_WARNING))
- dd_dev_info(dd, "%s: Cable RX channel 1/2 power too low\n",
- __func__);
+ dd_dev_err(dd, "%s: Cable RX channel 1/2 power too low\n",
+ __func__);
if ((qsfp_interrupt_status[4] & QSFP_HIGH_POWER_ALARM) ||
(qsfp_interrupt_status[4] & QSFP_HIGH_POWER_WARNING))
- dd_dev_info(dd, "%s: Cable RX channel 3/4 power too high\n",
- __func__);
+ dd_dev_err(dd, "%s: Cable RX channel 3/4 power too high\n",
+ __func__);
if ((qsfp_interrupt_status[4] & QSFP_LOW_POWER_ALARM) ||
(qsfp_interrupt_status[4] & QSFP_LOW_POWER_WARNING))
- dd_dev_info(dd, "%s: Cable RX channel 3/4 power too low\n",
- __func__);
+ dd_dev_err(dd, "%s: Cable RX channel 3/4 power too low\n",
+ __func__);
if ((qsfp_interrupt_status[5] & QSFP_HIGH_BIAS_ALARM) ||
(qsfp_interrupt_status[5] & QSFP_HIGH_BIAS_WARNING))
- dd_dev_info(dd, "%s: Cable TX channel 1/2 bias too high\n",
- __func__);
+ dd_dev_err(dd, "%s: Cable TX channel 1/2 bias too high\n",
+ __func__);
if ((qsfp_interrupt_status[5] & QSFP_LOW_BIAS_ALARM) ||
(qsfp_interrupt_status[5] & QSFP_LOW_BIAS_WARNING))
- dd_dev_info(dd, "%s: Cable TX channel 1/2 bias too low\n",
- __func__);
+ dd_dev_err(dd, "%s: Cable TX channel 1/2 bias too low\n",
+ __func__);
if ((qsfp_interrupt_status[6] & QSFP_HIGH_BIAS_ALARM) ||
(qsfp_interrupt_status[6] & QSFP_HIGH_BIAS_WARNING))
- dd_dev_info(dd, "%s: Cable TX channel 3/4 bias too high\n",
- __func__);
+ dd_dev_err(dd, "%s: Cable TX channel 3/4 bias too high\n",
+ __func__);
if ((qsfp_interrupt_status[6] & QSFP_LOW_BIAS_ALARM) ||
(qsfp_interrupt_status[6] & QSFP_LOW_BIAS_WARNING))
- dd_dev_info(dd, "%s: Cable TX channel 3/4 bias too low\n",
- __func__);
+ dd_dev_err(dd, "%s: Cable TX channel 3/4 bias too low\n",
+ __func__);
if ((qsfp_interrupt_status[7] & QSFP_HIGH_POWER_ALARM) ||
(qsfp_interrupt_status[7] & QSFP_HIGH_POWER_WARNING))
- dd_dev_info(dd, "%s: Cable TX channel 1/2 power too high\n",
- __func__);
+ dd_dev_err(dd, "%s: Cable TX channel 1/2 power too high\n",
+ __func__);
if ((qsfp_interrupt_status[7] & QSFP_LOW_POWER_ALARM) ||
(qsfp_interrupt_status[7] & QSFP_LOW_POWER_WARNING))
- dd_dev_info(dd, "%s: Cable TX channel 1/2 power too low\n",
- __func__);
+ dd_dev_err(dd, "%s: Cable TX channel 1/2 power too low\n",
+ __func__);
if ((qsfp_interrupt_status[8] & QSFP_HIGH_POWER_ALARM) ||
(qsfp_interrupt_status[8] & QSFP_HIGH_POWER_WARNING))
- dd_dev_info(dd, "%s: Cable TX channel 3/4 power too high\n",
- __func__);
+ dd_dev_err(dd, "%s: Cable TX channel 3/4 power too high\n",
+ __func__);
if ((qsfp_interrupt_status[8] & QSFP_LOW_POWER_ALARM) ||
(qsfp_interrupt_status[8] & QSFP_LOW_POWER_WARNING))
- dd_dev_info(dd, "%s: Cable TX channel 3/4 power too low\n",
- __func__);
+ dd_dev_err(dd, "%s: Cable TX channel 3/4 power too low\n",
+ __func__);
/* Bytes 9-10 and 11-12 are reserved */
/* Bytes 13-15 are vendor specific */
@@ -9480,6 +9559,13 @@ void qsfp_event(struct work_struct *work)
if (!qsfp_mod_present(ppd))
return;
+ if (ppd->host_link_state == HLS_DN_DISABLE) {
+ dd_dev_info(ppd->dd,
+ "%s: stopping link start because link is disabled\n",
+ __func__);
+ return;
+ }
+
/*
* Turn DC back on after cable has been re-inserted. Up until
* now, the DC has been in reset to save power.
@@ -9635,7 +9721,7 @@ static void try_start_link(struct hfi1_pportdata *ppd)
"QSFP not responding, waiting and retrying %d\n",
(int)ppd->qsfp_retry_count);
ppd->qsfp_retry_count++;
- queue_delayed_work(ppd->hfi1_wq, &ppd->start_link_work,
+ queue_delayed_work(ppd->link_wq, &ppd->start_link_work,
msecs_to_jiffies(QSFP_RETRY_WAIT));
return;
}
@@ -9742,17 +9828,6 @@ static inline int init_cpu_counters(struct hfi1_devdata *dd)
return 0;
}
-static const char * const pt_names[] = {
- "expected",
- "eager",
- "invalid"
-};
-
-static const char *pt_name(u32 type)
-{
- return type >= ARRAY_SIZE(pt_names) ? "unknown" : pt_names[type];
-}
-
/*
* index is the index into the receive array
*/
@@ -9760,35 +9835,34 @@ void hfi1_put_tid(struct hfi1_devdata *dd, u32 index,
u32 type, unsigned long pa, u16 order)
{
u64 reg;
- void __iomem *base = (dd->rcvarray_wc ? dd->rcvarray_wc :
- (dd->kregbase + RCV_ARRAY));
if (!(dd->flags & HFI1_PRESENT))
goto done;
- if (type == PT_INVALID) {
+ if (type == PT_INVALID || type == PT_INVALID_FLUSH) {
pa = 0;
+ order = 0;
} else if (type > PT_INVALID) {
dd_dev_err(dd,
"unexpected receive array type %u for index %u, not handled\n",
type, index);
goto done;
}
-
- hfi1_cdbg(TID, "type %s, index 0x%x, pa 0x%lx, bsize 0x%lx",
- pt_name(type), index, pa, (unsigned long)order);
+ trace_hfi1_put_tid(dd, index, type, pa, order);
#define RT_ADDR_SHIFT 12 /* 4KB kernel address boundary */
reg = RCV_ARRAY_RT_WRITE_ENABLE_SMASK
| (u64)order << RCV_ARRAY_RT_BUF_SIZE_SHIFT
| ((pa >> RT_ADDR_SHIFT) & RCV_ARRAY_RT_ADDR_MASK)
<< RCV_ARRAY_RT_ADDR_SHIFT;
- writeq(reg, base + (index * 8));
+ trace_hfi1_write_rcvarray(dd->rcvarray_wc + (index * 8), reg);
+ writeq(reg, dd->rcvarray_wc + (index * 8));
- if (type == PT_EAGER)
+ if (type == PT_EAGER || type == PT_INVALID_FLUSH || (index & 3) == 3)
/*
- * Eager entries are written one-by-one so we have to push them
- * after we write the entry.
+ * Eager entries are written and flushed
+ *
+ * Expected entries are flushed every 4 writes
*/
flush_wc();
done:
@@ -9810,15 +9884,6 @@ void hfi1_clear_tids(struct hfi1_ctxtdata *rcd)
hfi1_put_tid(dd, i, PT_INVALID, 0, 0);
}
-struct ib_header *hfi1_get_msgheader(
- struct hfi1_devdata *dd, __le32 *rhf_addr)
-{
- u32 offset = rhf_hdrq_offset(rhf_to_cpu(rhf_addr));
-
- return (struct ib_header *)
- (rhf_addr - dd->rhf_offset + offset);
-}
-
static const char * const ib_cfg_name_strings[] = {
"HFI1_IB_CFG_LIDLMC",
"HFI1_IB_CFG_LWID_DG_ENB",
@@ -10010,10 +10075,16 @@ static void set_lidlmc(struct hfi1_pportdata *ppd)
struct hfi1_devdata *dd = ppd->dd;
u32 mask = ~((1U << ppd->lmc) - 1);
u64 c1 = read_csr(ppd->dd, DCC_CFG_PORT_CONFIG1);
+ u32 lid;
+ /*
+ * Program 0 in CSR if port lid is extended. This prevents
+ * 9B packets being sent out for large lids.
+ */
+ lid = (ppd->lid >= be16_to_cpu(IB_MULTICAST_LID_BASE)) ? 0 : ppd->lid;
c1 &= ~(DCC_CFG_PORT_CONFIG1_TARGET_DLID_SMASK
| DCC_CFG_PORT_CONFIG1_DLID_MASK_SMASK);
- c1 |= ((ppd->lid & DCC_CFG_PORT_CONFIG1_TARGET_DLID_MASK)
+ c1 |= ((lid & DCC_CFG_PORT_CONFIG1_TARGET_DLID_MASK)
<< DCC_CFG_PORT_CONFIG1_TARGET_DLID_SHIFT) |
((mask & DCC_CFG_PORT_CONFIG1_DLID_MASK_MASK)
<< DCC_CFG_PORT_CONFIG1_DLID_MASK_SHIFT);
@@ -10024,7 +10095,7 @@ static void set_lidlmc(struct hfi1_pportdata *ppd)
*/
sreg = ((mask & SEND_CTXT_CHECK_SLID_MASK_MASK) <<
SEND_CTXT_CHECK_SLID_MASK_SHIFT) |
- (((ppd->lid & mask) & SEND_CTXT_CHECK_SLID_VALUE_MASK) <<
+ (((lid & mask) & SEND_CTXT_CHECK_SLID_VALUE_MASK) <<
SEND_CTXT_CHECK_SLID_VALUE_SHIFT);
for (i = 0; i < dd->chip_send_contexts; i++) {
@@ -10034,29 +10105,7 @@ static void set_lidlmc(struct hfi1_pportdata *ppd)
}
/* Now we have to do the same thing for the sdma engines */
- sdma_update_lmc(dd, mask, ppd->lid);
-}
-
-static int wait_phy_linkstate(struct hfi1_devdata *dd, u32 state, u32 msecs)
-{
- unsigned long timeout;
- u32 curr_state;
-
- timeout = jiffies + msecs_to_jiffies(msecs);
- while (1) {
- curr_state = read_physical_state(dd);
- if (curr_state == state)
- break;
- if (time_after(jiffies, timeout)) {
- dd_dev_err(dd,
- "timeout waiting for phy link state 0x%x, current state is 0x%x\n",
- state, curr_state);
- return -ETIMEDOUT;
- }
- usleep_range(1950, 2050); /* sleep 2ms-ish */
- }
-
- return 0;
+ sdma_update_lmc(dd, mask, lid);
}
static const char *state_completed_string(u32 completed)
@@ -10238,8 +10287,10 @@ static void force_logical_link_state_down(struct hfi1_pportdata *ppd)
write_csr(dd, DC_LCB_CFG_ALLOW_LINK_UP, 0);
write_csr(dd, DC_LCB_CFG_IGNORE_LOST_RCLK, 0);
- /* call again to adjust ppd->statusp, if needed */
- get_logical_state(ppd);
+ /* adjust ppd->statusp, if needed */
+ update_statusp(ppd, IB_PORT_DOWN);
+
+ dd_dev_info(ppd->dd, "logical state forced to LINK_DOWN\n");
}
/*
@@ -10253,49 +10304,35 @@ static void force_logical_link_state_down(struct hfi1_pportdata *ppd)
static int goto_offline(struct hfi1_pportdata *ppd, u8 rem_reason)
{
struct hfi1_devdata *dd = ppd->dd;
- u32 pstate, previous_state;
+ u32 previous_state;
int ret;
- int do_transition;
- int do_wait;
update_lcb_cache(dd);
previous_state = ppd->host_link_state;
ppd->host_link_state = HLS_GOING_OFFLINE;
- pstate = read_physical_state(dd);
- if (pstate == PLS_OFFLINE) {
- do_transition = 0; /* in right state */
- do_wait = 0; /* ...no need to wait */
- } else if ((pstate & 0xf0) == PLS_OFFLINE) {
- do_transition = 0; /* in an offline transient state */
- do_wait = 1; /* ...wait for it to settle */
- } else {
- do_transition = 1; /* need to move to offline */
- do_wait = 1; /* ...will need to wait */
- }
- if (do_transition) {
- ret = set_physical_link_state(dd,
- (rem_reason << 8) | PLS_OFFLINE);
+ /* start offline transition */
+ ret = set_physical_link_state(dd, (rem_reason << 8) | PLS_OFFLINE);
- if (ret != HCMD_SUCCESS) {
- dd_dev_err(dd,
- "Failed to transition to Offline link state, return %d\n",
- ret);
- return -EINVAL;
- }
- if (ppd->offline_disabled_reason ==
- HFI1_ODR_MASK(OPA_LINKDOWN_REASON_NONE))
- ppd->offline_disabled_reason =
- HFI1_ODR_MASK(OPA_LINKDOWN_REASON_TRANSIENT);
+ if (ret != HCMD_SUCCESS) {
+ dd_dev_err(dd,
+ "Failed to transition to Offline link state, return %d\n",
+ ret);
+ return -EINVAL;
}
+ if (ppd->offline_disabled_reason ==
+ HFI1_ODR_MASK(OPA_LINKDOWN_REASON_NONE))
+ ppd->offline_disabled_reason =
+ HFI1_ODR_MASK(OPA_LINKDOWN_REASON_TRANSIENT);
- if (do_wait) {
- /* it can take a while for the link to go down */
- ret = wait_phy_linkstate(dd, PLS_OFFLINE, 10000);
- if (ret < 0)
- return ret;
- }
+ /*
+ * Wait for offline transition. It can take a while for
+ * the link to go down.
+ */
+ ret = wait_physical_linkstate(ppd, PLS_OFFLINE, 10000);
+ if (ret < 0)
+ return ret;
/*
* Now in charge of LCB - must be after the physical state is
@@ -10415,11 +10452,11 @@ static const char *link_state_reason_name(struct hfi1_pportdata *ppd, u32 state)
}
/*
- * driver_physical_state - convert the driver's notion of a port's
+ * driver_pstate - convert the driver's notion of a port's
* state (an HLS_*) into a physical state (a {IB,OPA}_PORTPHYSSTATE_*).
* Return -1 (converted to a u32) to indicate error.
*/
-u32 driver_physical_state(struct hfi1_pportdata *ppd)
+u32 driver_pstate(struct hfi1_pportdata *ppd)
{
switch (ppd->host_link_state) {
case HLS_UP_INIT:
@@ -10449,11 +10486,11 @@ u32 driver_physical_state(struct hfi1_pportdata *ppd)
}
/*
- * driver_logical_state - convert the driver's notion of a port's
+ * driver_lstate - convert the driver's notion of a port's
* state (an HLS_*) into a logical state (a IB_PORT_*). Return -1
* (converted to a u32) to indicate error.
*/
-u32 driver_logical_state(struct hfi1_pportdata *ppd)
+u32 driver_lstate(struct hfi1_pportdata *ppd)
{
if (ppd->host_link_state && (ppd->host_link_state & HLS_DOWN))
return IB_PORT_DOWN;
@@ -10484,6 +10521,14 @@ void set_link_down_reason(struct hfi1_pportdata *ppd, u8 lcl_reason,
}
/*
+ * Verify if BCT for data VLs is non-zero.
+ */
+static inline bool data_vls_operational(struct hfi1_pportdata *ppd)
+{
+ return !!ppd->actual_vls_operational;
+}
+
+/*
* Change the physical and/or logical link state.
*
* Do not call this routine while inside an interrupt. It contains
@@ -10545,38 +10590,58 @@ int set_link_state(struct hfi1_pportdata *ppd, u32 state)
goto unexpected;
}
+ /*
+ * Wait for Link_Up physical state.
+ * Physical and Logical states should already be
+ * be transitioned to LinkUp and LinkInit respectively.
+ */
+ ret = wait_physical_linkstate(ppd, PLS_LINKUP, 1000);
+ if (ret) {
+ dd_dev_err(dd,
+ "%s: physical state did not change to LINK-UP\n",
+ __func__);
+ break;
+ }
+
ret = wait_logical_linkstate(ppd, IB_PORT_INIT, 1000);
if (ret) {
dd_dev_err(dd,
"%s: logical state did not change to INIT\n",
__func__);
- } else {
- /* clear old transient LINKINIT_REASON code */
- if (ppd->linkinit_reason >= OPA_LINKINIT_REASON_CLEAR)
- ppd->linkinit_reason =
- OPA_LINKINIT_REASON_LINKUP;
+ break;
+ }
- /* enable the port */
- add_rcvctrl(dd, RCV_CTRL_RCV_PORT_ENABLE_SMASK);
+ /* clear old transient LINKINIT_REASON code */
+ if (ppd->linkinit_reason >= OPA_LINKINIT_REASON_CLEAR)
+ ppd->linkinit_reason =
+ OPA_LINKINIT_REASON_LINKUP;
- handle_linkup_change(dd, 1);
- ppd->host_link_state = HLS_UP_INIT;
- }
+ /* enable the port */
+ add_rcvctrl(dd, RCV_CTRL_RCV_PORT_ENABLE_SMASK);
+
+ handle_linkup_change(dd, 1);
+ ppd->host_link_state = HLS_UP_INIT;
break;
case HLS_UP_ARMED:
if (ppd->host_link_state != HLS_UP_INIT)
goto unexpected;
- ppd->host_link_state = HLS_UP_ARMED;
+ if (!data_vls_operational(ppd)) {
+ dd_dev_err(dd,
+ "%s: data VLs not operational\n", __func__);
+ ret = -EINVAL;
+ break;
+ }
+
set_logical_state(dd, LSTATE_ARMED);
ret = wait_logical_linkstate(ppd, IB_PORT_ARMED, 1000);
if (ret) {
- /* logical state didn't change, stay at init */
- ppd->host_link_state = HLS_UP_INIT;
dd_dev_err(dd,
"%s: logical state did not change to ARMED\n",
__func__);
+ break;
}
+ ppd->host_link_state = HLS_UP_ARMED;
/*
* The simulator does not currently implement SMA messages,
* so neighbor_normal is not set. Set it here when we first
@@ -10589,18 +10654,16 @@ int set_link_state(struct hfi1_pportdata *ppd, u32 state)
if (ppd->host_link_state != HLS_UP_ARMED)
goto unexpected;
- ppd->host_link_state = HLS_UP_ACTIVE;
set_logical_state(dd, LSTATE_ACTIVE);
ret = wait_logical_linkstate(ppd, IB_PORT_ACTIVE, 1000);
if (ret) {
- /* logical state didn't change, stay at armed */
- ppd->host_link_state = HLS_UP_ARMED;
dd_dev_err(dd,
"%s: logical state did not change to ACTIVE\n",
__func__);
} else {
/* tell all engines to go running */
sdma_all_running(dd);
+ ppd->host_link_state = HLS_UP_ACTIVE;
/* Signal the IB layer that the port has went active */
event.device = &dd->verbs_dev.rdi.ibdev;
@@ -10658,6 +10721,8 @@ int set_link_state(struct hfi1_pportdata *ppd, u32 state)
*/
if (ret)
goto_offline(ppd, 0);
+ else
+ log_physical_state(ppd, PLS_POLLING);
break;
case HLS_DN_DISABLE:
/* link is disabled */
@@ -10682,6 +10747,13 @@ int set_link_state(struct hfi1_pportdata *ppd, u32 state)
ret = -EINVAL;
break;
}
+ ret = wait_physical_linkstate(ppd, PLS_DISABLED, 10000);
+ if (ret) {
+ dd_dev_err(dd,
+ "%s: physical state did not change to DISABLED\n",
+ __func__);
+ break;
+ }
dc_shutdown(dd);
}
ppd->host_link_state = HLS_DN_DISABLE;
@@ -10699,6 +10771,7 @@ int set_link_state(struct hfi1_pportdata *ppd, u32 state)
if (ppd->host_link_state != HLS_DN_POLL)
goto unexpected;
ppd->host_link_state = HLS_VERIFY_CAP;
+ log_physical_state(ppd, PLS_CONFIGPHY_VERIFYCAP);
break;
case HLS_GOING_UP:
if (ppd->host_link_state != HLS_VERIFY_CAP)
@@ -11693,16 +11766,18 @@ static u32 encoded_size(u32 size)
return 0x1; /* if invalid, go with the minimum size */
}
-void hfi1_rcvctrl(struct hfi1_devdata *dd, unsigned int op, int ctxt)
+void hfi1_rcvctrl(struct hfi1_devdata *dd, unsigned int op,
+ struct hfi1_ctxtdata *rcd)
{
- struct hfi1_ctxtdata *rcd;
u64 rcvctrl, reg;
int did_enable = 0;
+ u16 ctxt;
- rcd = dd->rcd[ctxt];
if (!rcd)
return;
+ ctxt = rcd->ctxt;
+
hfi1_cdbg(RCVCTRL, "ctxt %d op 0x%x", ctxt, op);
rcvctrl = read_kctxt_csr(dd, ctxt, RCV_CTXT_CTRL);
@@ -12604,20 +12679,8 @@ const char *opa_pstate_name(u32 pstate)
return "unknown";
}
-/*
- * Read the hardware link state and set the driver's cached value of it.
- * Return the (new) current value.
- */
-u32 get_logical_state(struct hfi1_pportdata *ppd)
+static void update_statusp(struct hfi1_pportdata *ppd, u32 state)
{
- u32 new_state;
-
- new_state = chip_to_opa_lstate(ppd->dd, read_logical_state(ppd->dd));
- if (new_state != ppd->lstate) {
- dd_dev_info(ppd->dd, "logical state changed to %s (0x%x)\n",
- opa_lstate_name(new_state), new_state);
- ppd->lstate = new_state;
- }
/*
* Set port status flags in the page mapped into userspace
* memory. Do it here to ensure a reliable state - this is
@@ -12627,7 +12690,7 @@ u32 get_logical_state(struct hfi1_pportdata *ppd)
* function.
*/
if (ppd->statusp) {
- switch (ppd->lstate) {
+ switch (state) {
case IB_PORT_DOWN:
case IB_PORT_INIT:
*ppd->statusp &= ~(HFI1_STATUS_IB_CONF |
@@ -12641,10 +12704,9 @@ u32 get_logical_state(struct hfi1_pportdata *ppd)
break;
}
}
- return ppd->lstate;
}
-/**
+/*
* wait_logical_linkstate - wait for an IB link state change to occur
* @ppd: port device
* @state: the state to wait for
@@ -12658,35 +12720,88 @@ static int wait_logical_linkstate(struct hfi1_pportdata *ppd, u32 state,
int msecs)
{
unsigned long timeout;
+ u32 new_state;
timeout = jiffies + msecs_to_jiffies(msecs);
while (1) {
- if (get_logical_state(ppd) == state)
- return 0;
- if (time_after(jiffies, timeout))
+ new_state = chip_to_opa_lstate(ppd->dd,
+ read_logical_state(ppd->dd));
+ if (new_state == state)
break;
+ if (time_after(jiffies, timeout)) {
+ dd_dev_err(ppd->dd,
+ "timeout waiting for link state 0x%x\n",
+ state);
+ return -ETIMEDOUT;
+ }
msleep(20);
}
- dd_dev_err(ppd->dd, "timeout waiting for link state 0x%x\n", state);
- return -ETIMEDOUT;
+ update_statusp(ppd, state);
+ dd_dev_info(ppd->dd,
+ "logical state changed to %s (0x%x)\n",
+ opa_lstate_name(state),
+ state);
+ return 0;
}
-u8 hfi1_ibphys_portstate(struct hfi1_pportdata *ppd)
+static void log_state_transition(struct hfi1_pportdata *ppd, u32 state)
{
- u32 pstate;
- u32 ib_pstate;
+ u32 ib_pstate = chip_to_opa_pstate(ppd->dd, state);
- pstate = read_physical_state(ppd->dd);
- ib_pstate = chip_to_opa_pstate(ppd->dd, pstate);
- if (ppd->last_pstate != ib_pstate) {
- dd_dev_info(ppd->dd,
- "%s: physical state changed to %s (0x%x), phy 0x%x\n",
- __func__, opa_pstate_name(ib_pstate), ib_pstate,
- pstate);
- ppd->last_pstate = ib_pstate;
+ dd_dev_info(ppd->dd,
+ "physical state changed to %s (0x%x), phy 0x%x\n",
+ opa_pstate_name(ib_pstate), ib_pstate, state);
+}
+
+/*
+ * Read the physical hardware link state and check if it matches host
+ * drivers anticipated state.
+ */
+static void log_physical_state(struct hfi1_pportdata *ppd, u32 state)
+{
+ u32 read_state = read_physical_state(ppd->dd);
+
+ if (read_state == state) {
+ log_state_transition(ppd, state);
+ } else {
+ dd_dev_err(ppd->dd,
+ "anticipated phy link state 0x%x, read 0x%x\n",
+ state, read_state);
}
- return ib_pstate;
+}
+
+/*
+ * wait_physical_linkstate - wait for an physical link state change to occur
+ * @ppd: port device
+ * @state: the state to wait for
+ * @msecs: the number of milliseconds to wait
+ *
+ * Wait up to msecs milliseconds for physical link state change to occur.
+ * Returns 0 if state reached, otherwise -ETIMEDOUT.
+ */
+static int wait_physical_linkstate(struct hfi1_pportdata *ppd, u32 state,
+ int msecs)
+{
+ u32 read_state;
+ unsigned long timeout;
+
+ timeout = jiffies + msecs_to_jiffies(msecs);
+ while (1) {
+ read_state = read_physical_state(ppd->dd);
+ if (read_state == state)
+ break;
+ if (time_after(jiffies, timeout)) {
+ dd_dev_err(ppd->dd,
+ "timeout waiting for phy link state 0x%x\n",
+ state);
+ return -ETIMEDOUT;
+ }
+ usleep_range(1950, 2050); /* sleep 2ms-ish */
+ }
+
+ log_state_transition(ppd, state);
+ return 0;
}
#define CLEAR_STATIC_RATE_CONTROL_SMASK(r) \
@@ -12809,30 +12924,24 @@ static void clean_up_interrupts(struct hfi1_devdata *dd)
for (i = 0; i < dd->num_msix_entries; i++, me++) {
if (!me->arg) /* => no irq, no affinity */
continue;
- hfi1_put_irq_affinity(dd, &dd->msix_entries[i]);
- free_irq(me->msix.vector, me->arg);
+ hfi1_put_irq_affinity(dd, me);
+ free_irq(me->irq, me->arg);
}
+
+ /* clean structures */
+ kfree(dd->msix_entries);
+ dd->msix_entries = NULL;
+ dd->num_msix_entries = 0;
} else {
/* INTx */
if (dd->requested_intx_irq) {
free_irq(dd->pcidev->irq, dd);
dd->requested_intx_irq = 0;
}
- }
-
- /* turn off interrupts */
- if (dd->num_msix_entries) {
- /* MSI-X */
- pci_disable_msix(dd->pcidev);
- } else {
- /* INTx */
disable_intx(dd->pcidev);
}
- /* clean structures */
- kfree(dd->msix_entries);
- dd->msix_entries = NULL;
- dd->num_msix_entries = 0;
+ pci_free_irq_vectors(dd->pcidev);
}
/*
@@ -12953,7 +13062,7 @@ static int request_msix_irqs(struct hfi1_devdata *dd)
me->type = IRQ_SDMA;
} else if (first_rx <= i && i < last_rx) {
idx = i - first_rx;
- rcd = dd->rcd[idx];
+ rcd = hfi1_rcd_get_by_index(dd, idx);
if (rcd) {
/*
* Set the interrupt register and mask for this
@@ -12972,6 +13081,7 @@ static int request_msix_irqs(struct hfi1_devdata *dd)
remap_intr(dd, IS_RCVAVAIL_START + idx, i);
me->type = IRQ_RCVCTXT;
rcd->msix_intr = i;
+ hfi1_rcd_put(rcd);
}
} else {
/* not in our expected range - complain, then
@@ -12986,13 +13096,21 @@ static int request_msix_irqs(struct hfi1_devdata *dd)
continue;
/* make sure the name is terminated */
me->name[sizeof(me->name) - 1] = 0;
+ me->irq = pci_irq_vector(dd->pcidev, i);
+ /*
+ * On err return me->irq. Don't need to clear this
+ * because 'arg' has not been set, and cleanup will
+ * do the right thing.
+ */
+ if (me->irq < 0)
+ return me->irq;
- ret = request_threaded_irq(me->msix.vector, handler, thread, 0,
+ ret = request_threaded_irq(me->irq, handler, thread, 0,
me->name, arg);
if (ret) {
dd_dev_err(dd,
- "unable to allocate %s interrupt, vector %d, index %d, err %d\n",
- err_info, me->msix.vector, idx, ret);
+ "unable to allocate %s interrupt, irq %d, index %d, err %d\n",
+ err_info, me->irq, idx, ret);
return ret;
}
/*
@@ -13003,8 +13121,7 @@ static int request_msix_irqs(struct hfi1_devdata *dd)
ret = hfi1_get_irq_affinity(dd, me);
if (ret)
- dd_dev_err(dd,
- "unable to pin IRQ %d\n", ret);
+ dd_dev_err(dd, "unable to pin IRQ %d\n", ret);
}
return ret;
@@ -13023,7 +13140,7 @@ void hfi1_vnic_synchronize_irq(struct hfi1_devdata *dd)
struct hfi1_ctxtdata *rcd = dd->vnic.ctxt[i];
struct hfi1_msix_entry *me = &dd->msix_entries[rcd->msix_intr];
- synchronize_irq(me->msix.vector);
+ synchronize_irq(me->irq);
}
}
@@ -13036,7 +13153,7 @@ void hfi1_reset_vnic_msix_info(struct hfi1_ctxtdata *rcd)
return;
hfi1_put_irq_affinity(dd, me);
- free_irq(me->msix.vector, me->arg);
+ free_irq(me->irq, me->arg);
me->arg = NULL;
}
@@ -13064,14 +13181,19 @@ void hfi1_set_vnic_msix_info(struct hfi1_ctxtdata *rcd)
DRIVER_NAME "_%d kctxt%d", dd->unit, idx);
me->name[sizeof(me->name) - 1] = 0;
me->type = IRQ_RCVCTXT;
-
+ me->irq = pci_irq_vector(dd->pcidev, rcd->msix_intr);
+ if (me->irq < 0) {
+ dd_dev_err(dd, "vnic irq vector request (idx %d) fail %d\n",
+ idx, me->irq);
+ return;
+ }
remap_intr(dd, IS_RCVAVAIL_START + idx, rcd->msix_intr);
- ret = request_threaded_irq(me->msix.vector, receive_context_interrupt,
+ ret = request_threaded_irq(me->irq, receive_context_interrupt,
receive_context_thread, 0, me->name, arg);
if (ret) {
- dd_dev_err(dd, "vnic irq request (vector %d, idx %d) fail %d\n",
- me->msix.vector, idx, ret);
+ dd_dev_err(dd, "vnic irq request (irq %d, idx %d) fail %d\n",
+ me->irq, idx, ret);
return;
}
/*
@@ -13084,7 +13206,7 @@ void hfi1_set_vnic_msix_info(struct hfi1_ctxtdata *rcd)
if (ret) {
dd_dev_err(dd,
"unable to pin IRQ %d\n", ret);
- free_irq(me->msix.vector, me->arg);
+ free_irq(me->irq, me->arg);
}
}
@@ -13107,9 +13229,8 @@ static void reset_interrupts(struct hfi1_devdata *dd)
static int set_up_interrupts(struct hfi1_devdata *dd)
{
- struct hfi1_msix_entry *entries;
- u32 total, request;
- int i, ret;
+ u32 total;
+ int ret, request;
int single_interrupt = 0; /* we expect to have all the interrupts */
/*
@@ -13121,39 +13242,31 @@ static int set_up_interrupts(struct hfi1_devdata *dd)
*/
total = 1 + dd->num_sdma + dd->n_krcv_queues + HFI1_NUM_VNIC_CTXT;
- entries = kcalloc(total, sizeof(*entries), GFP_KERNEL);
- if (!entries) {
- ret = -ENOMEM;
- goto fail;
- }
- /* 1-1 MSI-X entry assignment */
- for (i = 0; i < total; i++)
- entries[i].msix.entry = i;
-
/* ask for MSI-X interrupts */
- request = total;
- request_msix(dd, &request, entries);
-
- if (request == 0) {
+ request = request_msix(dd, total);
+ if (request < 0) {
+ ret = request;
+ goto fail;
+ } else if (request == 0) {
/* using INTx */
/* dd->num_msix_entries already zero */
- kfree(entries);
single_interrupt = 1;
dd_dev_err(dd, "MSI-X failed, using INTx interrupts\n");
+ } else if (request < total) {
+ /* using MSI-X, with reduced interrupts */
+ dd_dev_err(dd, "reduced interrupt found, wanted %u, got %u\n",
+ total, request);
+ ret = -EINVAL;
+ goto fail;
} else {
- /* using MSI-X */
- dd->num_msix_entries = request;
- dd->msix_entries = entries;
-
- if (request != total) {
- /* using MSI-X, with reduced interrupts */
- dd_dev_err(
- dd,
- "cannot handle reduced interrupt case, want %u, got %u\n",
- total, request);
- ret = -EINVAL;
+ dd->msix_entries = kcalloc(total, sizeof(*dd->msix_entries),
+ GFP_KERNEL);
+ if (!dd->msix_entries) {
+ ret = -ENOMEM;
goto fail;
}
+ /* using MSI-X */
+ dd->num_msix_entries = total;
dd_dev_info(dd, "%u MSI-X interrupts allocated\n", total);
}
@@ -13396,8 +13509,7 @@ static void write_uninitialized_csrs_and_memories(struct hfi1_devdata *dd)
/* RcvArray */
for (i = 0; i < dd->chip_rcv_array_count; i++)
- write_csr(dd, RCV_ARRAY + (8 * i),
- RCV_ARRAY_RT_WRITE_ENABLE_SMASK);
+ hfi1_put_tid(dd, i, PT_INVALID_FLUSH, 0, 0);
/* RcvQPMapTable */
for (i = 0; i < 32; i++)
@@ -13831,9 +13943,10 @@ static void init_sc2vl_tables(struct hfi1_devdata *dd)
* a reset following the (possible) FLR in this routine.
*
*/
-static void init_chip(struct hfi1_devdata *dd)
+static int init_chip(struct hfi1_devdata *dd)
{
int i;
+ int ret = 0;
/*
* Put the HFI CSRs in a known state.
@@ -13881,12 +13994,22 @@ static void init_chip(struct hfi1_devdata *dd)
pcie_flr(dd->pcidev);
/* restore command and BARs */
- restore_pci_variables(dd);
+ ret = restore_pci_variables(dd);
+ if (ret) {
+ dd_dev_err(dd, "%s: Could not restore PCI variables\n",
+ __func__);
+ return ret;
+ }
if (is_ax(dd)) {
dd_dev_info(dd, "Resetting CSRs with FLR\n");
pcie_flr(dd->pcidev);
- restore_pci_variables(dd);
+ ret = restore_pci_variables(dd);
+ if (ret) {
+ dd_dev_err(dd, "%s: Could not restore PCI variables\n",
+ __func__);
+ return ret;
+ }
}
} else {
dd_dev_info(dd, "Resetting CSRs with writes\n");
@@ -13914,6 +14037,7 @@ static void init_chip(struct hfi1_devdata *dd)
write_csr(dd, ASIC_QSFP1_OUT, 0x1f);
write_csr(dd, ASIC_QSFP2_OUT, 0x1f);
init_chip_resources(dd);
+ return ret;
}
static void init_early_variables(struct hfi1_devdata *dd)
@@ -14365,6 +14489,7 @@ void hfi1_deinit_vnic_rsm(struct hfi1_devdata *dd)
static void init_rxe(struct hfi1_devdata *dd)
{
struct rsm_map_table *rmt;
+ u64 val;
/* enable all receive errors */
write_csr(dd, RCV_ERR_MASK, ~0ull);
@@ -14389,6 +14514,11 @@ static void init_rxe(struct hfi1_devdata *dd)
* (64 bytes). Max_Payload_Size is possibly modified upward in
* tune_pcie_caps() which is called after this routine.
*/
+
+ /* Have 16 bytes (4DW) of bypass header available in header queue */
+ val = read_csr(dd, RCV_BYPASS);
+ val |= (4ull << 16);
+ write_csr(dd, RCV_BYPASS, val);
}
static void init_other(struct hfi1_devdata *dd)
@@ -14470,99 +14600,86 @@ static void init_txe(struct hfi1_devdata *dd)
write_csr(dd, SEND_CM_TIMER_CTRL, HFI1_CREDIT_RETURN_RATE);
}
-int hfi1_set_ctxt_jkey(struct hfi1_devdata *dd, unsigned ctxt, u16 jkey)
+int hfi1_set_ctxt_jkey(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd,
+ u16 jkey)
{
- struct hfi1_ctxtdata *rcd = dd->rcd[ctxt];
- unsigned sctxt;
- int ret = 0;
+ u8 hw_ctxt;
u64 reg;
- if (!rcd || !rcd->sc) {
- ret = -EINVAL;
- goto done;
- }
- sctxt = rcd->sc->hw_context;
+ if (!rcd || !rcd->sc)
+ return -EINVAL;
+
+ hw_ctxt = rcd->sc->hw_context;
reg = SEND_CTXT_CHECK_JOB_KEY_MASK_SMASK | /* mask is always 1's */
((jkey & SEND_CTXT_CHECK_JOB_KEY_VALUE_MASK) <<
SEND_CTXT_CHECK_JOB_KEY_VALUE_SHIFT);
/* JOB_KEY_ALLOW_PERMISSIVE is not allowed by default */
if (HFI1_CAP_KGET_MASK(rcd->flags, ALLOW_PERM_JKEY))
reg |= SEND_CTXT_CHECK_JOB_KEY_ALLOW_PERMISSIVE_SMASK;
- write_kctxt_csr(dd, sctxt, SEND_CTXT_CHECK_JOB_KEY, reg);
+ write_kctxt_csr(dd, hw_ctxt, SEND_CTXT_CHECK_JOB_KEY, reg);
/*
* Enable send-side J_KEY integrity check, unless this is A0 h/w
*/
if (!is_ax(dd)) {
- reg = read_kctxt_csr(dd, sctxt, SEND_CTXT_CHECK_ENABLE);
+ reg = read_kctxt_csr(dd, hw_ctxt, SEND_CTXT_CHECK_ENABLE);
reg |= SEND_CTXT_CHECK_ENABLE_CHECK_JOB_KEY_SMASK;
- write_kctxt_csr(dd, sctxt, SEND_CTXT_CHECK_ENABLE, reg);
+ write_kctxt_csr(dd, hw_ctxt, SEND_CTXT_CHECK_ENABLE, reg);
}
/* Enable J_KEY check on receive context. */
reg = RCV_KEY_CTRL_JOB_KEY_ENABLE_SMASK |
((jkey & RCV_KEY_CTRL_JOB_KEY_VALUE_MASK) <<
RCV_KEY_CTRL_JOB_KEY_VALUE_SHIFT);
- write_kctxt_csr(dd, ctxt, RCV_KEY_CTRL, reg);
-done:
- return ret;
+ write_kctxt_csr(dd, rcd->ctxt, RCV_KEY_CTRL, reg);
+
+ return 0;
}
-int hfi1_clear_ctxt_jkey(struct hfi1_devdata *dd, unsigned ctxt)
+int hfi1_clear_ctxt_jkey(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd)
{
- struct hfi1_ctxtdata *rcd = dd->rcd[ctxt];
- unsigned sctxt;
- int ret = 0;
+ u8 hw_ctxt;
u64 reg;
- if (!rcd || !rcd->sc) {
- ret = -EINVAL;
- goto done;
- }
- sctxt = rcd->sc->hw_context;
- write_kctxt_csr(dd, sctxt, SEND_CTXT_CHECK_JOB_KEY, 0);
+ if (!rcd || !rcd->sc)
+ return -EINVAL;
+
+ hw_ctxt = rcd->sc->hw_context;
+ write_kctxt_csr(dd, hw_ctxt, SEND_CTXT_CHECK_JOB_KEY, 0);
/*
* Disable send-side J_KEY integrity check, unless this is A0 h/w.
* This check would not have been enabled for A0 h/w, see
* set_ctxt_jkey().
*/
if (!is_ax(dd)) {
- reg = read_kctxt_csr(dd, sctxt, SEND_CTXT_CHECK_ENABLE);
+ reg = read_kctxt_csr(dd, hw_ctxt, SEND_CTXT_CHECK_ENABLE);
reg &= ~SEND_CTXT_CHECK_ENABLE_CHECK_JOB_KEY_SMASK;
- write_kctxt_csr(dd, sctxt, SEND_CTXT_CHECK_ENABLE, reg);
+ write_kctxt_csr(dd, hw_ctxt, SEND_CTXT_CHECK_ENABLE, reg);
}
/* Turn off the J_KEY on the receive side */
- write_kctxt_csr(dd, ctxt, RCV_KEY_CTRL, 0);
-done:
- return ret;
+ write_kctxt_csr(dd, rcd->ctxt, RCV_KEY_CTRL, 0);
+
+ return 0;
}
-int hfi1_set_ctxt_pkey(struct hfi1_devdata *dd, unsigned ctxt, u16 pkey)
+int hfi1_set_ctxt_pkey(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd,
+ u16 pkey)
{
- struct hfi1_ctxtdata *rcd;
- unsigned sctxt;
- int ret = 0;
+ u8 hw_ctxt;
u64 reg;
- if (ctxt < dd->num_rcv_contexts) {
- rcd = dd->rcd[ctxt];
- } else {
- ret = -EINVAL;
- goto done;
- }
- if (!rcd || !rcd->sc) {
- ret = -EINVAL;
- goto done;
- }
- sctxt = rcd->sc->hw_context;
+ if (!rcd || !rcd->sc)
+ return -EINVAL;
+
+ hw_ctxt = rcd->sc->hw_context;
reg = ((u64)pkey & SEND_CTXT_CHECK_PARTITION_KEY_VALUE_MASK) <<
SEND_CTXT_CHECK_PARTITION_KEY_VALUE_SHIFT;
- write_kctxt_csr(dd, sctxt, SEND_CTXT_CHECK_PARTITION_KEY, reg);
- reg = read_kctxt_csr(dd, sctxt, SEND_CTXT_CHECK_ENABLE);
+ write_kctxt_csr(dd, hw_ctxt, SEND_CTXT_CHECK_PARTITION_KEY, reg);
+ reg = read_kctxt_csr(dd, hw_ctxt, SEND_CTXT_CHECK_ENABLE);
reg |= SEND_CTXT_CHECK_ENABLE_CHECK_PARTITION_KEY_SMASK;
reg &= ~SEND_CTXT_CHECK_ENABLE_DISALLOW_KDETH_PACKETS_SMASK;
- write_kctxt_csr(dd, sctxt, SEND_CTXT_CHECK_ENABLE, reg);
-done:
- return ret;
+ write_kctxt_csr(dd, hw_ctxt, SEND_CTXT_CHECK_ENABLE, reg);
+
+ return 0;
}
int hfi1_clear_ctxt_pkey(struct hfi1_devdata *dd, struct hfi1_ctxtdata *ctxt)
@@ -14573,9 +14690,6 @@ int hfi1_clear_ctxt_pkey(struct hfi1_devdata *dd, struct hfi1_ctxtdata *ctxt)
if (!ctxt || !ctxt->sc)
return -EINVAL;
- if (ctxt->ctxt >= dd->num_rcv_contexts)
- return -EINVAL;
-
hw_ctxt = ctxt->sc->hw_context;
reg = read_kctxt_csr(dd, hw_ctxt, SEND_CTXT_CHECK_ENABLE);
reg &= ~SEND_CTXT_CHECK_ENABLE_CHECK_PARTITION_KEY_SMASK;
@@ -14773,7 +14887,6 @@ struct hfi1_devdata *hfi1_init_dd(struct pci_dev *pdev,
}
ppd->vls_supported = num_vls;
ppd->vls_operational = ppd->vls_supported;
- ppd->actual_vls_operational = ppd->vls_supported;
/* Set the default MTU. */
for (vl = 0; vl < num_vls; vl++)
dd->vld[vl].mtu = hfi1_max_mtu;
@@ -14782,7 +14895,6 @@ struct hfi1_devdata *hfi1_init_dd(struct pci_dev *pdev,
* Set the initial values to reasonable default, will be set
* for real when link is up.
*/
- ppd->lstate = IB_PORT_DOWN;
ppd->overrun_threshold = 0x4;
ppd->phy_error_threshold = 0xf;
ppd->port_crc_mode_enabled = link_crc_mask;
@@ -14793,7 +14905,6 @@ struct hfi1_devdata *hfi1_init_dd(struct pci_dev *pdev,
/* start in offline */
ppd->host_link_state = HLS_DN_OFFLINE;
init_vl_arb_caches(ppd);
- ppd->last_pstate = 0xff; /* invalid value */
}
dd->link_default = HLS_DN_POLL;
@@ -14807,6 +14918,11 @@ struct hfi1_devdata *hfi1_init_dd(struct pci_dev *pdev,
if (ret < 0)
goto bail_free;
+ /* Save PCI space registers to rewrite after device reset */
+ ret = save_pci_variables(dd);
+ if (ret < 0)
+ goto bail_cleanup;
+
/* verify that reads actually work, save revision for reset check */
dd->revision = read_csr(dd, CCE_REVISION);
if (dd->revision == ~(u64)0) {
@@ -14899,7 +15015,9 @@ struct hfi1_devdata *hfi1_init_dd(struct pci_dev *pdev,
goto bail_cleanup;
/* obtain chip sizes, reset chip CSRs */
- init_chip(dd);
+ ret = init_chip(dd);
+ if (ret)
+ goto bail_cleanup;
/* read in the PCIe link speed information */
ret = pcie_speeds(dd);
@@ -14974,10 +15092,16 @@ struct hfi1_devdata *hfi1_init_dd(struct pci_dev *pdev,
if (ret)
goto bail_cleanup;
- ret = hfi1_create_ctxts(dd);
+ ret = hfi1_create_kctxts(dd);
if (ret)
goto bail_cleanup;
+ /*
+ * Initialize aspm, to be done after gen3 transition and setting up
+ * contexts and before enabling interrupts
+ */
+ aspm_init(dd);
+
dd->rcvhdrsize = DEFAULT_RCVHDRSIZE;
/*
* rcd[0] is guaranteed to be valid by this point. Also, all
@@ -14996,7 +15120,7 @@ struct hfi1_devdata *hfi1_init_dd(struct pci_dev *pdev,
goto bail_cleanup;
}
- /* use contexts created by hfi1_create_ctxts */
+ /* use contexts created by hfi1_create_kctxts */
ret = set_up_interrupts(dd);
if (ret)
goto bail_cleanup;
diff --git a/drivers/infiniband/hw/hfi1/chip.h b/drivers/infiniband/hw/hfi1/chip.h
index cbe455d..b8345a6 100644
--- a/drivers/infiniband/hw/hfi1/chip.h
+++ b/drivers/infiniband/hw/hfi1/chip.h
@@ -384,6 +384,7 @@
#define VERIFY_CAP_LOCAL_FABRIC 0x08
#define VERIFY_CAP_LOCAL_LINK_WIDTH 0x09
#define LOCAL_DEVICE_ID 0x0a
+#define RESERVED_REGISTERS 0x0b
#define LOCAL_LNI_INFO 0x0c
#define REMOTE_LNI_INFO 0x0d
#define MISC_STATUS 0x0e
@@ -506,6 +507,9 @@
#define DOWN_REMOTE_REASON_SHIFT 16
#define DOWN_REMOTE_REASON_MASK 0xff
+#define HOST_INTERFACE_VERSION_SHIFT 16
+#define HOST_INTERFACE_VERSION_MASK 0xff
+
/* verify capability PHY power management bits */
#define PWRM_BER_CONTROL 0x1
#define PWRM_BANDWIDTH_CONTROL 0x2
@@ -605,11 +609,11 @@ int read_lcb_csr(struct hfi1_devdata *dd, u32 offset, u64 *data);
int write_lcb_csr(struct hfi1_devdata *dd, u32 offset, u64 data);
void __iomem *get_csr_addr(
- struct hfi1_devdata *dd,
+ const struct hfi1_devdata *dd,
u32 offset);
static inline void __iomem *get_kctxt_csr_addr(
- struct hfi1_devdata *dd,
+ const struct hfi1_devdata *dd,
int ctxt,
u32 offset0)
{
@@ -644,7 +648,6 @@ u64 create_pbc(struct hfi1_pportdata *ppd, u64 flags, int srate_mbs, u32 vl,
#define NUM_PCIE_SERDES 16 /* number of PCIe serdes on the SBus */
extern const u8 pcie_serdes_broadcast[];
extern const u8 pcie_pcs_addrs[2][NUM_PCIE_SERDES];
-extern uint platform_config_load;
/* SBus commands */
#define RESET_SBUS_RECEIVER 0x20
@@ -704,6 +707,7 @@ int read_8051_data(struct hfi1_devdata *dd, u32 addr, u32 len, u64 *result);
/* chip.c */
void read_misc_status(struct hfi1_devdata *dd, u8 *ver_major, u8 *ver_minor,
u8 *ver_patch);
+int write_host_interface_version(struct hfi1_devdata *dd, u8 version);
void read_guid(struct hfi1_devdata *dd);
int wait_fm_ready(struct hfi1_devdata *dd, u32 mstimeout);
void set_link_down_reason(struct hfi1_pportdata *ppd, u8 lcl_reason,
@@ -743,11 +747,10 @@ int is_ax(struct hfi1_devdata *dd);
int is_bx(struct hfi1_devdata *dd);
u32 read_physical_state(struct hfi1_devdata *dd);
u32 chip_to_opa_pstate(struct hfi1_devdata *dd, u32 chip_pstate);
-u32 get_logical_state(struct hfi1_pportdata *ppd);
const char *opa_lstate_name(u32 lstate);
const char *opa_pstate_name(u32 pstate);
-u32 driver_physical_state(struct hfi1_pportdata *ppd);
-u32 driver_logical_state(struct hfi1_pportdata *ppd);
+u32 driver_pstate(struct hfi1_pportdata *ppd);
+u32 driver_lstate(struct hfi1_pportdata *ppd);
int acquire_lcb_access(struct hfi1_devdata *dd, int sleep_ok);
int release_lcb_access(struct hfi1_devdata *dd, int sleep_ok);
@@ -1347,21 +1350,21 @@ enum {
u64 get_all_cpu_total(u64 __percpu *cntr);
void hfi1_start_cleanup(struct hfi1_devdata *dd);
void hfi1_clear_tids(struct hfi1_ctxtdata *rcd);
-struct ib_header *hfi1_get_msgheader(
- struct hfi1_devdata *dd, __le32 *rhf_addr);
void hfi1_init_ctxt(struct send_context *sc);
void hfi1_put_tid(struct hfi1_devdata *dd, u32 index,
u32 type, unsigned long pa, u16 order);
void hfi1_quiet_serdes(struct hfi1_pportdata *ppd);
-void hfi1_rcvctrl(struct hfi1_devdata *dd, unsigned int op, int ctxt);
+void hfi1_rcvctrl(struct hfi1_devdata *dd, unsigned int op,
+ struct hfi1_ctxtdata *rcd);
u32 hfi1_read_cntrs(struct hfi1_devdata *dd, char **namep, u64 **cntrp);
u32 hfi1_read_portcntrs(struct hfi1_pportdata *ppd, char **namep, u64 **cntrp);
-u8 hfi1_ibphys_portstate(struct hfi1_pportdata *ppd);
int hfi1_get_ib_cfg(struct hfi1_pportdata *ppd, int which);
int hfi1_set_ib_cfg(struct hfi1_pportdata *ppd, int which, u32 val);
-int hfi1_set_ctxt_jkey(struct hfi1_devdata *dd, unsigned ctxt, u16 jkey);
-int hfi1_clear_ctxt_jkey(struct hfi1_devdata *dd, unsigned ctxt);
-int hfi1_set_ctxt_pkey(struct hfi1_devdata *dd, unsigned ctxt, u16 pkey);
+int hfi1_set_ctxt_jkey(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd,
+ u16 jkey);
+int hfi1_clear_ctxt_jkey(struct hfi1_devdata *dd, struct hfi1_ctxtdata *ctxt);
+int hfi1_set_ctxt_pkey(struct hfi1_devdata *dd, struct hfi1_ctxtdata *ctxt,
+ u16 pkey);
int hfi1_clear_ctxt_pkey(struct hfi1_devdata *dd, struct hfi1_ctxtdata *ctxt);
void hfi1_read_link_quality(struct hfi1_devdata *dd, u8 *link_quality);
void hfi1_init_vnic_rsm(struct hfi1_devdata *dd);
diff --git a/drivers/infiniband/hw/hfi1/common.h b/drivers/infiniband/hw/hfi1/common.h
index 995d62c..3e27794e 100644
--- a/drivers/infiniband/hw/hfi1/common.h
+++ b/drivers/infiniband/hw/hfi1/common.h
@@ -325,22 +325,15 @@ struct diag_pkt {
#define HFI1_LRH_BTH 0x0002 /* 1. word of IB LRH - next header: BTH */
/* misc. */
+#define SC15_PACKET 0xF
#define SIZE_OF_CRC 1
+#define SIZE_OF_LT 1
#define LIM_MGMT_P_KEY 0x7FFF
#define FULL_MGMT_P_KEY 0xFFFF
#define DEFAULT_P_KEY LIM_MGMT_P_KEY
-/**
- * 0xF8 - 4 bits of multicast range and 1 bit for collective range
- * Example: For 24 bit LID space,
- * Multicast range: 0xF00000 to 0xF7FFFF
- * Collective range: 0xF80000 to 0xFFFFFE
- */
-#define HFI1_MCAST_NR 0x4 /* Number of top bits set */
-#define HFI1_COLLECTIVE_NR 0x1 /* Number of bits after MCAST_NR */
-
#define HFI1_PSM_IOC_BASE_SEQ 0x0
static inline __u64 rhf_to_cpu(const __le32 *rbuf)
diff --git a/drivers/infiniband/hw/hfi1/debugfs.c b/drivers/infiniband/hw/hfi1/debugfs.c
index e9fa3c2..36ae1fd 100644
--- a/drivers/infiniband/hw/hfi1/debugfs.c
+++ b/drivers/infiniband/hw/hfi1/debugfs.c
@@ -1,4 +1,3 @@
-#ifdef CONFIG_DEBUG_FS
/*
* Copyright(c) 2015-2017 Intel Corporation.
*
@@ -173,12 +172,15 @@ static int _opcode_stats_seq_show(struct seq_file *s, void *v)
u64 n_packets = 0, n_bytes = 0;
struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
struct hfi1_devdata *dd = dd_from_dev(ibd);
+ struct hfi1_ctxtdata *rcd;
for (j = 0; j < dd->first_dyn_alloc_ctxt; j++) {
- if (!dd->rcd[j])
- continue;
- n_packets += dd->rcd[j]->opstats->stats[i].n_packets;
- n_bytes += dd->rcd[j]->opstats->stats[i].n_bytes;
+ rcd = hfi1_rcd_get_by_index(dd, j);
+ if (rcd) {
+ n_packets += rcd->opstats->stats[i].n_packets;
+ n_bytes += rcd->opstats->stats[i].n_bytes;
+ }
+ hfi1_rcd_put(rcd);
}
if (!n_packets && !n_bytes)
return SEQ_SKIP;
@@ -231,6 +233,7 @@ static int _ctx_stats_seq_show(struct seq_file *s, void *v)
u64 n_packets = 0;
struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
struct hfi1_devdata *dd = dd_from_dev(ibd);
+ struct hfi1_ctxtdata *rcd;
if (v == SEQ_START_TOKEN) {
seq_puts(s, "Ctx:npkts\n");
@@ -240,11 +243,14 @@ static int _ctx_stats_seq_show(struct seq_file *s, void *v)
spos = v;
i = *spos;
- if (!dd->rcd[i])
+ rcd = hfi1_rcd_get_by_index(dd, i);
+ if (!rcd)
return SEQ_SKIP;
- for (j = 0; j < ARRAY_SIZE(dd->rcd[i]->opstats->stats); j++)
- n_packets += dd->rcd[i]->opstats->stats[j].n_packets;
+ for (j = 0; j < ARRAY_SIZE(rcd->opstats->stats); j++)
+ n_packets += rcd->opstats->stats[j].n_packets;
+
+ hfi1_rcd_put(rcd);
if (!n_packets)
return SEQ_SKIP;
@@ -260,10 +266,10 @@ DEBUGFS_FILE_OPS(ctx_stats);
static void *_qp_stats_seq_start(struct seq_file *s, loff_t *pos)
__acquires(RCU)
{
- struct qp_iter *iter;
+ struct rvt_qp_iter *iter;
loff_t n = *pos;
- iter = qp_iter_init(s->private);
+ iter = rvt_qp_iter_init(s->private, 0, NULL);
/* stop calls rcu_read_unlock */
rcu_read_lock();
@@ -272,7 +278,7 @@ static void *_qp_stats_seq_start(struct seq_file *s, loff_t *pos)
return NULL;
do {
- if (qp_iter_next(iter)) {
+ if (rvt_qp_iter_next(iter)) {
kfree(iter);
return NULL;
}
@@ -285,11 +291,11 @@ static void *_qp_stats_seq_next(struct seq_file *s, void *iter_ptr,
loff_t *pos)
__must_hold(RCU)
{
- struct qp_iter *iter = iter_ptr;
+ struct rvt_qp_iter *iter = iter_ptr;
(*pos)++;
- if (qp_iter_next(iter)) {
+ if (rvt_qp_iter_next(iter)) {
kfree(iter);
return NULL;
}
@@ -305,7 +311,7 @@ static void _qp_stats_seq_stop(struct seq_file *s, void *iter_ptr)
static int _qp_stats_seq_show(struct seq_file *s, void *iter_ptr)
{
- struct qp_iter *iter = iter_ptr;
+ struct rvt_qp_iter *iter = iter_ptr;
if (!iter)
return 0;
@@ -361,6 +367,52 @@ DEBUGFS_SEQ_FILE_OPS(sdes);
DEBUGFS_SEQ_FILE_OPEN(sdes)
DEBUGFS_FILE_OPS(sdes);
+static void *_rcds_seq_start(struct seq_file *s, loff_t *pos)
+{
+ struct hfi1_ibdev *ibd;
+ struct hfi1_devdata *dd;
+
+ ibd = (struct hfi1_ibdev *)s->private;
+ dd = dd_from_dev(ibd);
+ if (!dd->rcd || *pos >= dd->n_krcv_queues)
+ return NULL;
+ return pos;
+}
+
+static void *_rcds_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+ struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
+ struct hfi1_devdata *dd = dd_from_dev(ibd);
+
+ ++*pos;
+ if (!dd->rcd || *pos >= dd->n_krcv_queues)
+ return NULL;
+ return pos;
+}
+
+static void _rcds_seq_stop(struct seq_file *s, void *v)
+{
+}
+
+static int _rcds_seq_show(struct seq_file *s, void *v)
+{
+ struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
+ struct hfi1_devdata *dd = dd_from_dev(ibd);
+ struct hfi1_ctxtdata *rcd;
+ loff_t *spos = v;
+ loff_t i = *spos;
+
+ rcd = hfi1_rcd_get_by_index(dd, i);
+ if (rcd)
+ seqfile_dump_rcd(s, rcd);
+ hfi1_rcd_put(rcd);
+ return 0;
+}
+
+DEBUGFS_SEQ_FILE_OPS(rcds);
+DEBUGFS_SEQ_FILE_OPEN(rcds)
+DEBUGFS_FILE_OPS(rcds);
+
/* read the per-device counters */
static ssize_t dev_counters_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
@@ -1098,12 +1150,15 @@ static int _fault_stats_seq_show(struct seq_file *s, void *v)
u64 n_packets = 0, n_bytes = 0;
struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
struct hfi1_devdata *dd = dd_from_dev(ibd);
+ struct hfi1_ctxtdata *rcd;
for (j = 0; j < dd->first_dyn_alloc_ctxt; j++) {
- if (!dd->rcd[j])
- continue;
- n_packets += dd->rcd[j]->opstats->stats[i].n_packets;
- n_bytes += dd->rcd[j]->opstats->stats[i].n_bytes;
+ rcd = hfi1_rcd_get_by_index(dd, j);
+ if (rcd) {
+ n_packets += rcd->opstats->stats[i].n_packets;
+ n_bytes += rcd->opstats->stats[i].n_bytes;
+ }
+ hfi1_rcd_put(rcd);
}
if (!n_packets && !n_bytes)
return SEQ_SKIP;
@@ -1311,6 +1366,7 @@ void hfi1_dbg_ibdev_init(struct hfi1_ibdev *ibd)
DEBUGFS_SEQ_FILE_CREATE(ctx_stats, ibd->hfi1_ibdev_dbg, ibd);
DEBUGFS_SEQ_FILE_CREATE(qp_stats, ibd->hfi1_ibdev_dbg, ibd);
DEBUGFS_SEQ_FILE_CREATE(sdes, ibd->hfi1_ibdev_dbg, ibd);
+ DEBUGFS_SEQ_FILE_CREATE(rcds, ibd->hfi1_ibdev_dbg, ibd);
DEBUGFS_SEQ_FILE_CREATE(sdma_cpu_list, ibd->hfi1_ibdev_dbg, ibd);
/* dev counter files */
for (i = 0; i < ARRAY_SIZE(cntr_ops); i++)
@@ -1478,5 +1534,3 @@ void hfi1_dbg_exit(void)
debugfs_remove_recursive(hfi1_dbg_root);
hfi1_dbg_root = NULL;
}
-
-#endif
diff --git a/drivers/infiniband/hw/hfi1/driver.c b/drivers/infiniband/hw/hfi1/driver.c
index a50870e..7372cc0 100644
--- a/drivers/infiniband/hw/hfi1/driver.c
+++ b/drivers/infiniband/hw/hfi1/driver.c
@@ -96,7 +96,6 @@ MODULE_PARM_DESC(cap_mask, "Bit mask of enabled/disabled HW features");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("Intel Omni-Path Architecture driver");
-MODULE_VERSION(HFI1_DRIVER_VERSION);
/*
* MAX_PKT_RCV is the max # if packets processed per receive interrupt.
@@ -196,7 +195,7 @@ int hfi1_count_active_units(void)
spin_lock_irqsave(&hfi1_devs_lock, flags);
list_for_each_entry(dd, &hfi1_dev_list, list) {
- if (!(dd->flags & HFI1_PRESENT) || !dd->kregbase)
+ if (!(dd->flags & HFI1_PRESENT) || !dd->kregbase1)
continue;
for (pidx = 0; pidx < dd->num_pports; ++pidx) {
ppd = dd->pport + pidx;
@@ -224,6 +223,27 @@ static inline void *get_egrbuf(const struct hfi1_ctxtdata *rcd, u64 rhf,
(offset * RCV_BUF_BLOCK_SIZE));
}
+static inline void *hfi1_get_header(struct hfi1_devdata *dd,
+ __le32 *rhf_addr)
+{
+ u32 offset = rhf_hdrq_offset(rhf_to_cpu(rhf_addr));
+
+ return (void *)(rhf_addr - dd->rhf_offset + offset);
+}
+
+static inline struct ib_header *hfi1_get_msgheader(struct hfi1_devdata *dd,
+ __le32 *rhf_addr)
+{
+ return (struct ib_header *)hfi1_get_header(dd, rhf_addr);
+}
+
+static inline struct hfi1_16b_header
+ *hfi1_get_16B_header(struct hfi1_devdata *dd,
+ __le32 *rhf_addr)
+{
+ return (struct hfi1_16b_header *)hfi1_get_header(dd, rhf_addr);
+}
+
/*
* Validate and encode the a given RcvArray Buffer size.
* The function will check whether the given size falls within
@@ -249,7 +269,7 @@ static void rcv_hdrerr(struct hfi1_ctxtdata *rcd, struct hfi1_pportdata *ppd,
{
struct ib_header *rhdr = packet->hdr;
u32 rte = rhf_rcv_type_err(packet->rhf);
- int lnh = ib_get_lnh(rhdr);
+ u32 mlid_base;
struct hfi1_ibport *ibp = rcd_to_iport(rcd);
struct hfi1_devdata *dd = ppd->dd;
struct rvt_dev_info *rdi = &dd->verbs_dev.rdi;
@@ -257,37 +277,47 @@ static void rcv_hdrerr(struct hfi1_ctxtdata *rcd, struct hfi1_pportdata *ppd,
if (packet->rhf & (RHF_VCRC_ERR | RHF_ICRC_ERR))
return;
+ if (packet->etype == RHF_RCV_TYPE_BYPASS) {
+ goto drop;
+ } else {
+ u8 lnh = ib_get_lnh(rhdr);
+
+ mlid_base = be16_to_cpu(IB_MULTICAST_LID_BASE);
+ if (lnh == HFI1_LRH_BTH) {
+ packet->ohdr = &rhdr->u.oth;
+ } else if (lnh == HFI1_LRH_GRH) {
+ packet->ohdr = &rhdr->u.l.oth;
+ packet->grh = &rhdr->u.l.grh;
+ } else {
+ goto drop;
+ }
+ }
+
if (packet->rhf & RHF_TID_ERR) {
/* For TIDERR and RC QPs preemptively schedule a NAK */
- struct ib_other_headers *ohdr = NULL;
u32 tlen = rhf_pkt_len(packet->rhf); /* in bytes */
- u16 lid = ib_get_dlid(rhdr);
+ u32 dlid = ib_get_dlid(rhdr);
u32 qp_num;
- u32 rcv_flags = 0;
/* Sanity check packet */
if (tlen < 24)
goto drop;
/* Check for GRH */
- if (lnh == HFI1_LRH_BTH) {
- ohdr = &rhdr->u.oth;
- } else if (lnh == HFI1_LRH_GRH) {
+ if (packet->grh) {
u32 vtf;
+ struct ib_grh *grh = packet->grh;
- ohdr = &rhdr->u.l.oth;
- if (rhdr->u.l.grh.next_hdr != IB_GRH_NEXT_HDR)
+ if (grh->next_hdr != IB_GRH_NEXT_HDR)
goto drop;
- vtf = be32_to_cpu(rhdr->u.l.grh.version_tclass_flow);
+ vtf = be32_to_cpu(grh->version_tclass_flow);
if ((vtf >> IB_GRH_VERSION_SHIFT) != IB_GRH_VERSION)
goto drop;
- rcv_flags |= HFI1_HAS_GRH;
- } else {
- goto drop;
}
+
/* Get the destination QP number. */
- qp_num = be32_to_cpu(ohdr->bth[1]) & RVT_QPN_MASK;
- if (lid < be16_to_cpu(IB_MULTICAST_LID_BASE)) {
+ qp_num = ib_bth_get_qpn(packet->ohdr);
+ if (dlid < mlid_base) {
struct rvt_qp *qp;
unsigned long flags;
@@ -312,11 +342,7 @@ static void rcv_hdrerr(struct hfi1_ctxtdata *rcd, struct hfi1_pportdata *ppd,
switch (qp->ibqp.qp_type) {
case IB_QPT_RC:
- hfi1_rc_hdrerr(
- rcd,
- rhdr,
- rcv_flags,
- qp);
+ hfi1_rc_hdrerr(rcd, packet, qp);
break;
default:
/* For now don't handle any other QP types */
@@ -332,9 +358,8 @@ static void rcv_hdrerr(struct hfi1_ctxtdata *rcd, struct hfi1_pportdata *ppd,
switch (rte) {
case RHF_RTE_ERROR_OP_CODE_ERR:
{
- u32 opcode;
void *ebuf = NULL;
- __be32 *bth = NULL;
+ u8 opcode;
if (rhf_use_egr_bfr(packet->rhf))
ebuf = packet->ebuf;
@@ -342,16 +367,7 @@ static void rcv_hdrerr(struct hfi1_ctxtdata *rcd, struct hfi1_pportdata *ppd,
if (!ebuf)
goto drop; /* this should never happen */
- if (lnh == HFI1_LRH_BTH)
- bth = (__be32 *)ebuf;
- else if (lnh == HFI1_LRH_GRH)
- bth = (__be32 *)((char *)ebuf + sizeof(struct ib_grh));
- else
- goto drop;
-
- opcode = be32_to_cpu(bth[0]) >> 24;
- opcode &= 0xff;
-
+ opcode = ib_bth_get_opcode(packet->ohdr);
if (opcode == IB_OPCODE_CNP) {
/*
* Only in pre-B0 h/w is the CNP_OPCODE handled
@@ -365,7 +381,7 @@ static void rcv_hdrerr(struct hfi1_ctxtdata *rcd, struct hfi1_pportdata *ppd,
sc5 = hfi1_9B_get_sc5(rhdr, packet->rhf);
sl = ibp->sc_to_sl[sc5];
- lqpn = be32_to_cpu(bth[1]) & RVT_QPN_MASK;
+ lqpn = ib_bth_get_qpn(packet->ohdr);
rcu_read_lock();
qp = rvt_lookup_qpn(rdi, &ibp->rvp, lqpn);
if (!qp) {
@@ -415,33 +431,39 @@ static inline void init_packet(struct hfi1_ctxtdata *rcd,
packet->rhf = rhf_to_cpu(packet->rhf_addr);
packet->rhqoff = rcd->head;
packet->numpkt = 0;
- packet->rcv_flags = 0;
}
void hfi1_process_ecn_slowpath(struct rvt_qp *qp, struct hfi1_packet *pkt,
bool do_cnp)
{
struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num);
- struct ib_header *hdr = pkt->hdr;
struct ib_other_headers *ohdr = pkt->ohdr;
- struct ib_grh *grh = NULL;
+ struct ib_grh *grh = pkt->grh;
u32 rqpn = 0, bth1;
- u16 rlid, dlid = ib_get_dlid(hdr);
- u8 sc, svc_type;
+ u16 pkey, rlid, dlid = ib_get_dlid(pkt->hdr);
+ u8 hdr_type, sc, svc_type;
bool is_mcast = false;
- if (pkt->rcv_flags & HFI1_HAS_GRH)
- grh = &hdr->u.l.grh;
+ if (pkt->etype == RHF_RCV_TYPE_BYPASS) {
+ is_mcast = hfi1_is_16B_mcast(dlid);
+ pkey = hfi1_16B_get_pkey(pkt->hdr);
+ sc = hfi1_16B_get_sc(pkt->hdr);
+ hdr_type = HFI1_PKT_TYPE_16B;
+ } else {
+ is_mcast = (dlid > be16_to_cpu(IB_MULTICAST_LID_BASE)) &&
+ (dlid != be16_to_cpu(IB_LID_PERMISSIVE));
+ pkey = ib_bth_get_pkey(ohdr);
+ sc = hfi1_9B_get_sc5(pkt->hdr, pkt->rhf);
+ hdr_type = HFI1_PKT_TYPE_9B;
+ }
switch (qp->ibqp.qp_type) {
case IB_QPT_SMI:
case IB_QPT_GSI:
case IB_QPT_UD:
- rlid = ib_get_slid(hdr);
- rqpn = be32_to_cpu(ohdr->u.ud.deth[1]) & RVT_QPN_MASK;
+ rlid = ib_get_slid(pkt->hdr);
+ rqpn = ib_get_sqpn(pkt->ohdr);
svc_type = IB_CC_SVCTYPE_UD;
- is_mcast = (dlid > be16_to_cpu(IB_MULTICAST_LID_BASE)) &&
- (dlid != be16_to_cpu(IB_LID_PERMISSIVE));
break;
case IB_QPT_UC:
rlid = rdma_ah_get_dlid(&qp->remote_ah_attr);
@@ -457,14 +479,11 @@ void hfi1_process_ecn_slowpath(struct rvt_qp *qp, struct hfi1_packet *pkt,
return;
}
- sc = hfi1_9B_get_sc5(hdr, pkt->rhf);
-
bth1 = be32_to_cpu(ohdr->bth[1]);
- if (do_cnp && (bth1 & IB_FECN_SMASK)) {
- u16 pkey = (u16)be32_to_cpu(ohdr->bth[0]);
-
- return_cnp(ibp, qp, rqpn, pkey, dlid, rlid, sc, grh);
- }
+ /* Call appropriate CNP handler */
+ if (do_cnp && (bth1 & IB_FECN_SMASK))
+ hfi1_handle_cnp_tbl[hdr_type](ibp, qp, rqpn, pkey,
+ dlid, rlid, sc, grh);
if (!is_mcast && (bth1 & IB_BECN_SMASK)) {
struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
@@ -591,9 +610,10 @@ static void __prescan_rxq(struct hfi1_packet *packet)
if (lnh == HFI1_LRH_BTH) {
packet->ohdr = &hdr->u.oth;
+ packet->grh = NULL;
} else if (lnh == HFI1_LRH_GRH) {
packet->ohdr = &hdr->u.l.oth;
- packet->rcv_flags |= HFI1_HAS_GRH;
+ packet->grh = &hdr->u.l.grh;
} else {
goto next; /* just in case */
}
@@ -698,10 +718,8 @@ static inline int process_rcv_packet(struct hfi1_packet *packet, int thread)
{
int ret;
- packet->hdr = hfi1_get_msgheader(packet->rcd->dd,
- packet->rhf_addr);
- packet->hlen = (u8 *)packet->rhf_addr - (u8 *)packet->hdr;
packet->etype = rhf_rcv_type(packet->rhf);
+
/* total length */
packet->tlen = rhf_pkt_len(packet->rhf); /* in bytes */
/* retrieve eager buffer details */
@@ -759,7 +777,7 @@ static inline void process_rcv_update(int last, struct hfi1_packet *packet)
packet->etail, 0, 0);
packet->updegr = 0;
}
- packet->rcv_flags = 0;
+ packet->grh = NULL;
}
static inline void finish_packet(struct hfi1_packet *packet)
@@ -837,9 +855,10 @@ bail:
return last;
}
-static inline void set_nodma_rtail(struct hfi1_devdata *dd, u8 ctxt)
+static inline void set_nodma_rtail(struct hfi1_devdata *dd, u16 ctxt)
{
- int i;
+ struct hfi1_ctxtdata *rcd;
+ u16 i;
/*
* For dynamically allocated kernel contexts (like vnic) switch
@@ -847,19 +866,28 @@ static inline void set_nodma_rtail(struct hfi1_devdata *dd, u8 ctxt)
* interrupt handler for all statically allocated kernel contexts.
*/
if (ctxt >= dd->first_dyn_alloc_ctxt) {
- dd->rcd[ctxt]->do_interrupt =
- &handle_receive_interrupt_nodma_rtail;
+ rcd = hfi1_rcd_get_by_index(dd, ctxt);
+ if (rcd) {
+ rcd->do_interrupt =
+ &handle_receive_interrupt_nodma_rtail;
+ hfi1_rcd_put(rcd);
+ }
return;
}
- for (i = HFI1_CTRL_CTXT + 1; i < dd->first_dyn_alloc_ctxt; i++)
- dd->rcd[i]->do_interrupt =
- &handle_receive_interrupt_nodma_rtail;
+ for (i = HFI1_CTRL_CTXT + 1; i < dd->first_dyn_alloc_ctxt; i++) {
+ rcd = hfi1_rcd_get_by_index(dd, i);
+ if (rcd)
+ rcd->do_interrupt =
+ &handle_receive_interrupt_nodma_rtail;
+ hfi1_rcd_put(rcd);
+ }
}
-static inline void set_dma_rtail(struct hfi1_devdata *dd, u8 ctxt)
+static inline void set_dma_rtail(struct hfi1_devdata *dd, u16 ctxt)
{
- int i;
+ struct hfi1_ctxtdata *rcd;
+ u16 i;
/*
* For dynamically allocated kernel contexts (like vnic) switch
@@ -867,27 +895,39 @@ static inline void set_dma_rtail(struct hfi1_devdata *dd, u8 ctxt)
* interrupt handler for all statically allocated kernel contexts.
*/
if (ctxt >= dd->first_dyn_alloc_ctxt) {
- dd->rcd[ctxt]->do_interrupt =
- &handle_receive_interrupt_dma_rtail;
+ rcd = hfi1_rcd_get_by_index(dd, ctxt);
+ if (rcd) {
+ rcd->do_interrupt =
+ &handle_receive_interrupt_dma_rtail;
+ hfi1_rcd_put(rcd);
+ }
return;
}
- for (i = HFI1_CTRL_CTXT + 1; i < dd->first_dyn_alloc_ctxt; i++)
- dd->rcd[i]->do_interrupt =
- &handle_receive_interrupt_dma_rtail;
+ for (i = HFI1_CTRL_CTXT + 1; i < dd->first_dyn_alloc_ctxt; i++) {
+ rcd = hfi1_rcd_get_by_index(dd, i);
+ if (rcd)
+ rcd->do_interrupt =
+ &handle_receive_interrupt_dma_rtail;
+ hfi1_rcd_put(rcd);
+ }
}
void set_all_slowpath(struct hfi1_devdata *dd)
{
- int i;
+ struct hfi1_ctxtdata *rcd;
+ u16 i;
/* HFI1_CTRL_CTXT must always use the slow path interrupt handler */
for (i = HFI1_CTRL_CTXT + 1; i < dd->num_rcv_contexts; i++) {
- struct hfi1_ctxtdata *rcd = dd->rcd[i];
-
+ rcd = hfi1_rcd_get_by_index(dd, i);
+ if (!rcd)
+ continue;
if ((i < dd->first_dyn_alloc_ctxt) ||
- (rcd && rcd->sc && (rcd->sc->type == SC_KERNEL)))
+ (rcd->sc && (rcd->sc->type == SC_KERNEL))) {
rcd->do_interrupt = &handle_receive_interrupt;
+ }
+ hfi1_rcd_put(rcd);
}
}
@@ -896,20 +936,30 @@ static inline int set_armed_to_active(struct hfi1_ctxtdata *rcd,
struct hfi1_devdata *dd)
{
struct work_struct *lsaw = &rcd->ppd->linkstate_active_work;
- struct ib_header *hdr = hfi1_get_msgheader(packet->rcd->dd,
- packet->rhf_addr);
u8 etype = rhf_rcv_type(packet->rhf);
+ u8 sc = SC15_PACKET;
+
+ if (etype == RHF_RCV_TYPE_IB) {
+ struct ib_header *hdr = hfi1_get_msgheader(packet->rcd->dd,
+ packet->rhf_addr);
+ sc = hfi1_9B_get_sc5(hdr, packet->rhf);
+ } else if (etype == RHF_RCV_TYPE_BYPASS) {
+ struct hfi1_16b_header *hdr = hfi1_get_16B_header(
+ packet->rcd->dd,
+ packet->rhf_addr);
+ sc = hfi1_16B_get_sc(hdr);
+ }
+ if (sc != SC15_PACKET) {
+ int hwstate = driver_lstate(rcd->ppd);
- if (etype == RHF_RCV_TYPE_IB &&
- hfi1_9B_get_sc5(hdr, packet->rhf) != 0xf) {
- int hwstate = read_logical_state(dd);
-
- if (hwstate != LSTATE_ACTIVE) {
- dd_dev_info(dd, "Unexpected link state %d\n", hwstate);
+ if (hwstate != IB_PORT_ACTIVE) {
+ dd_dev_info(dd,
+ "Unexpected link state %s\n",
+ opa_lstate_name(hwstate));
return 0;
}
- queue_work(rcd->ppd->hfi1_wq, lsaw);
+ queue_work(rcd->ppd->link_wq, lsaw);
return 1;
}
return 0;
@@ -1063,7 +1113,8 @@ void receive_interrupt_work(struct work_struct *work)
struct hfi1_pportdata *ppd = container_of(work, struct hfi1_pportdata,
linkstate_active_work);
struct hfi1_devdata *dd = ppd->dd;
- int i;
+ struct hfi1_ctxtdata *rcd;
+ u16 i;
/* Received non-SC15 packet implies neighbor_normal */
ppd->neighbor_normal = 1;
@@ -1073,8 +1124,12 @@ void receive_interrupt_work(struct work_struct *work)
* Interrupt all statically allocated kernel contexts that could
* have had an interrupt during auto activation.
*/
- for (i = HFI1_CTRL_CTXT; i < dd->first_dyn_alloc_ctxt; i++)
- force_recv_intr(dd->rcd[i]);
+ for (i = HFI1_CTRL_CTXT; i < dd->first_dyn_alloc_ctxt; i++) {
+ rcd = hfi1_rcd_get_by_index(dd, i);
+ if (rcd)
+ force_recv_intr(rcd);
+ hfi1_rcd_put(rcd);
+ }
}
/*
@@ -1264,10 +1319,9 @@ void hfi1_start_led_override(struct hfi1_pportdata *ppd, unsigned int timeon,
*/
int hfi1_reset_device(int unit)
{
- int ret, i;
+ int ret;
struct hfi1_devdata *dd = hfi1_lookup(unit);
struct hfi1_pportdata *ppd;
- unsigned long flags;
int pidx;
if (!dd) {
@@ -1277,7 +1331,7 @@ int hfi1_reset_device(int unit)
dd_dev_info(dd, "Reset on unit %u requested\n", unit);
- if (!dd->kregbase || !(dd->flags & HFI1_PRESENT)) {
+ if (!dd->kregbase1 || !(dd->flags & HFI1_PRESENT)) {
dd_dev_info(dd,
"Invalid unit number %u or not initialized or not present\n",
unit);
@@ -1285,17 +1339,15 @@ int hfi1_reset_device(int unit)
goto bail;
}
- spin_lock_irqsave(&dd->uctxt_lock, flags);
+ /* If there are any user/vnic contexts, we cannot reset */
+ mutex_lock(&hfi1_mutex);
if (dd->rcd)
- for (i = dd->first_dyn_alloc_ctxt;
- i < dd->num_rcv_contexts; i++) {
- if (!dd->rcd[i])
- continue;
- spin_unlock_irqrestore(&dd->uctxt_lock, flags);
+ if (hfi1_stats.sps_ctxts) {
+ mutex_unlock(&hfi1_mutex);
ret = -EBUSY;
goto bail;
}
- spin_unlock_irqrestore(&dd->uctxt_lock, flags);
+ mutex_unlock(&hfi1_mutex);
for (pidx = 0; pidx < dd->num_pports; ++pidx) {
ppd = dd->pport + pidx;
@@ -1321,6 +1373,162 @@ bail:
return ret;
}
+static inline void hfi1_setup_ib_header(struct hfi1_packet *packet)
+{
+ packet->hdr = (struct hfi1_ib_message_header *)
+ hfi1_get_msgheader(packet->rcd->dd,
+ packet->rhf_addr);
+ packet->hlen = (u8 *)packet->rhf_addr - (u8 *)packet->hdr;
+}
+
+static int hfi1_bypass_ingress_pkt_check(struct hfi1_packet *packet)
+{
+ struct hfi1_pportdata *ppd = packet->rcd->ppd;
+
+ /* slid and dlid cannot be 0 */
+ if ((!packet->slid) || (!packet->dlid))
+ return -EINVAL;
+
+ /* Compare port lid with incoming packet dlid */
+ if ((!(hfi1_is_16B_mcast(packet->dlid))) &&
+ (packet->dlid !=
+ opa_get_lid(be32_to_cpu(OPA_LID_PERMISSIVE), 16B))) {
+ if (packet->dlid != ppd->lid)
+ return -EINVAL;
+ }
+
+ /* No multicast packets with SC15 */
+ if ((hfi1_is_16B_mcast(packet->dlid)) && (packet->sc == 0xF))
+ return -EINVAL;
+
+ /* Packets with permissive DLID always on SC15 */
+ if ((packet->dlid == opa_get_lid(be32_to_cpu(OPA_LID_PERMISSIVE),
+ 16B)) &&
+ (packet->sc != 0xF))
+ return -EINVAL;
+
+ return 0;
+}
+
+static int hfi1_setup_9B_packet(struct hfi1_packet *packet)
+{
+ struct hfi1_ibport *ibp = rcd_to_iport(packet->rcd);
+ struct ib_header *hdr;
+ u8 lnh;
+
+ hfi1_setup_ib_header(packet);
+ hdr = packet->hdr;
+
+ lnh = ib_get_lnh(hdr);
+ if (lnh == HFI1_LRH_BTH) {
+ packet->ohdr = &hdr->u.oth;
+ packet->grh = NULL;
+ } else if (lnh == HFI1_LRH_GRH) {
+ u32 vtf;
+
+ packet->ohdr = &hdr->u.l.oth;
+ packet->grh = &hdr->u.l.grh;
+ if (packet->grh->next_hdr != IB_GRH_NEXT_HDR)
+ goto drop;
+ vtf = be32_to_cpu(packet->grh->version_tclass_flow);
+ if ((vtf >> IB_GRH_VERSION_SHIFT) != IB_GRH_VERSION)
+ goto drop;
+ } else {
+ goto drop;
+ }
+
+ /* Query commonly used fields from packet header */
+ packet->payload = packet->ebuf;
+ packet->opcode = ib_bth_get_opcode(packet->ohdr);
+ packet->slid = ib_get_slid(hdr);
+ packet->dlid = ib_get_dlid(hdr);
+ if (unlikely((packet->dlid >= be16_to_cpu(IB_MULTICAST_LID_BASE)) &&
+ (packet->dlid != be16_to_cpu(IB_LID_PERMISSIVE))))
+ packet->dlid += opa_get_mcast_base(OPA_MCAST_NR) -
+ be16_to_cpu(IB_MULTICAST_LID_BASE);
+ packet->sl = ib_get_sl(hdr);
+ packet->sc = hfi1_9B_get_sc5(hdr, packet->rhf);
+ packet->pad = ib_bth_get_pad(packet->ohdr);
+ packet->extra_byte = 0;
+ packet->fecn = ib_bth_get_fecn(packet->ohdr);
+ packet->becn = ib_bth_get_becn(packet->ohdr);
+
+ return 0;
+drop:
+ ibp->rvp.n_pkt_drops++;
+ return -EINVAL;
+}
+
+static int hfi1_setup_bypass_packet(struct hfi1_packet *packet)
+{
+ /*
+ * Bypass packets have a different header/payload split
+ * compared to an IB packet.
+ * Current split is set such that 16 bytes of the actual
+ * header is in the header buffer and the remining is in
+ * the eager buffer. We chose 16 since hfi1 driver only
+ * supports 16B bypass packets and we will be able to
+ * receive the entire LRH with such a split.
+ */
+
+ struct hfi1_ctxtdata *rcd = packet->rcd;
+ struct hfi1_pportdata *ppd = rcd->ppd;
+ struct hfi1_ibport *ibp = &ppd->ibport_data;
+ u8 l4;
+ u8 grh_len;
+
+ packet->hdr = (struct hfi1_16b_header *)
+ hfi1_get_16B_header(packet->rcd->dd,
+ packet->rhf_addr);
+ packet->hlen = (u8 *)packet->rhf_addr - (u8 *)packet->hdr;
+
+ l4 = hfi1_16B_get_l4(packet->hdr);
+ if (l4 == OPA_16B_L4_IB_LOCAL) {
+ grh_len = 0;
+ packet->ohdr = packet->ebuf;
+ packet->grh = NULL;
+ } else if (l4 == OPA_16B_L4_IB_GLOBAL) {
+ u32 vtf;
+
+ grh_len = sizeof(struct ib_grh);
+ packet->ohdr = packet->ebuf + grh_len;
+ packet->grh = packet->ebuf;
+ if (packet->grh->next_hdr != IB_GRH_NEXT_HDR)
+ goto drop;
+ vtf = be32_to_cpu(packet->grh->version_tclass_flow);
+ if ((vtf >> IB_GRH_VERSION_SHIFT) != IB_GRH_VERSION)
+ goto drop;
+ } else {
+ goto drop;
+ }
+
+ /* Query commonly used fields from packet header */
+ packet->opcode = ib_bth_get_opcode(packet->ohdr);
+ packet->hlen = hdr_len_by_opcode[packet->opcode] + 8 + grh_len;
+ packet->payload = packet->ebuf + packet->hlen - (4 * sizeof(u32));
+ packet->slid = hfi1_16B_get_slid(packet->hdr);
+ packet->dlid = hfi1_16B_get_dlid(packet->hdr);
+ if (unlikely(hfi1_is_16B_mcast(packet->dlid)))
+ packet->dlid += opa_get_mcast_base(OPA_MCAST_NR) -
+ opa_get_lid(opa_get_mcast_base(OPA_MCAST_NR),
+ 16B);
+ packet->sc = hfi1_16B_get_sc(packet->hdr);
+ packet->sl = ibp->sc_to_sl[packet->sc];
+ packet->pad = hfi1_16B_bth_get_pad(packet->ohdr);
+ packet->extra_byte = SIZE_OF_LT;
+ packet->fecn = hfi1_16B_get_fecn(packet->hdr);
+ packet->becn = hfi1_16B_get_becn(packet->hdr);
+
+ if (hfi1_bypass_ingress_pkt_check(packet))
+ goto drop;
+
+ return 0;
+drop:
+ hfi1_cdbg(PKT, "%s: packet dropped\n", __func__);
+ ibp->rvp.n_pkt_drops++;
+ return -EINVAL;
+}
+
void handle_eflags(struct hfi1_packet *packet)
{
struct hfi1_ctxtdata *rcd = packet->rcd;
@@ -1351,6 +1559,9 @@ int process_receive_ib(struct hfi1_packet *packet)
if (unlikely(hfi1_dbg_fault_packet(packet)))
return RHF_RCV_CONTINUE;
+ if (hfi1_setup_9B_packet(packet))
+ return RHF_RCV_CONTINUE;
+
trace_hfi1_rcvhdr(packet->rcd->ppd->dd,
packet->rcd->ctxt,
rhf_err_flags(packet->rhf),
@@ -1380,8 +1591,8 @@ static inline bool hfi1_is_vnic_packet(struct hfi1_packet *packet)
if (packet->rcd->is_vnic)
return true;
- if ((HFI1_GET_L2_TYPE(packet->ebuf) == OPA_VNIC_L2_TYPE) &&
- (HFI1_GET_L4_TYPE(packet->ebuf) == OPA_VNIC_L4_ETHR))
+ if ((hfi1_16B_get_l2(packet->ebuf) == OPA_16B_L2_TYPE) &&
+ (hfi1_16B_get_l4(packet->ebuf) == OPA_16B_L4_ETHR))
return true;
return false;
@@ -1391,25 +1602,38 @@ int process_receive_bypass(struct hfi1_packet *packet)
{
struct hfi1_devdata *dd = packet->rcd->dd;
- if (unlikely(rhf_err_flags(packet->rhf))) {
- handle_eflags(packet);
- } else if (hfi1_is_vnic_packet(packet)) {
+ if (hfi1_is_vnic_packet(packet)) {
hfi1_vnic_bypass_rcv(packet);
return RHF_RCV_CONTINUE;
}
- dd_dev_err(dd, "Unsupported bypass packet. Dropping\n");
- incr_cntr64(&dd->sw_rcv_bypass_packet_errors);
- if (!(dd->err_info_rcvport.status_and_code & OPA_EI_STATUS_SMASK)) {
- u64 *flits = packet->ebuf;
+ if (hfi1_setup_bypass_packet(packet))
+ return RHF_RCV_CONTINUE;
+
+ if (unlikely(rhf_err_flags(packet->rhf))) {
+ handle_eflags(packet);
+ return RHF_RCV_CONTINUE;
+ }
- if (flits && !(packet->rhf & RHF_LEN_ERR)) {
- dd->err_info_rcvport.packet_flit1 = flits[0];
- dd->err_info_rcvport.packet_flit2 =
- packet->tlen > sizeof(flits[0]) ? flits[1] : 0;
+ if (hfi1_16B_get_l2(packet->hdr) == 0x2) {
+ hfi1_16B_rcv(packet);
+ } else {
+ dd_dev_err(dd,
+ "Bypass packets other than 16B are not supported in normal operation. Dropping\n");
+ incr_cntr64(&dd->sw_rcv_bypass_packet_errors);
+ if (!(dd->err_info_rcvport.status_and_code &
+ OPA_EI_STATUS_SMASK)) {
+ u64 *flits = packet->ebuf;
+
+ if (flits && !(packet->rhf & RHF_LEN_ERR)) {
+ dd->err_info_rcvport.packet_flit1 = flits[0];
+ dd->err_info_rcvport.packet_flit2 =
+ packet->tlen > sizeof(flits[0]) ?
+ flits[1] : 0;
+ }
+ dd->err_info_rcvport.status_and_code |=
+ (OPA_EI_STATUS_SMASK | BAD_L2_ERR);
}
- dd->err_info_rcvport.status_and_code |=
- (OPA_EI_STATUS_SMASK | BAD_L2_ERR);
}
return RHF_RCV_CONTINUE;
}
@@ -1422,6 +1646,7 @@ int process_receive_error(struct hfi1_packet *packet)
rhf_rcv_type_err(packet->rhf) == 3))
return RHF_RCV_CONTINUE;
+ hfi1_setup_ib_header(packet);
handle_eflags(packet);
if (unlikely(rhf_err_flags(packet->rhf)))
@@ -1435,6 +1660,8 @@ int kdeth_process_expected(struct hfi1_packet *packet)
{
if (unlikely(hfi1_dbg_fault_packet(packet)))
return RHF_RCV_CONTINUE;
+
+ hfi1_setup_ib_header(packet);
if (unlikely(rhf_err_flags(packet->rhf)))
handle_eflags(packet);
@@ -1445,6 +1672,7 @@ int kdeth_process_expected(struct hfi1_packet *packet)
int kdeth_process_eager(struct hfi1_packet *packet)
{
+ hfi1_setup_ib_header(packet);
if (unlikely(rhf_err_flags(packet->rhf)))
handle_eflags(packet);
if (unlikely(hfi1_dbg_fault_packet(packet)))
@@ -1461,3 +1689,62 @@ int process_receive_invalid(struct hfi1_packet *packet)
rhf_rcv_type(packet->rhf));
return RHF_RCV_CONTINUE;
}
+
+void seqfile_dump_rcd(struct seq_file *s, struct hfi1_ctxtdata *rcd)
+{
+ struct hfi1_packet packet;
+ struct ps_mdata mdata;
+
+ seq_printf(s, "Rcd %u: RcvHdr cnt %u entsize %u %s head %llu tail %llu\n",
+ rcd->ctxt, rcd->rcvhdrq_cnt, rcd->rcvhdrqentsize,
+ HFI1_CAP_KGET_MASK(rcd->flags, DMA_RTAIL) ?
+ "dma_rtail" : "nodma_rtail",
+ read_uctxt_csr(rcd->dd, rcd->ctxt, RCV_HDR_HEAD) &
+ RCV_HDR_HEAD_HEAD_MASK,
+ read_uctxt_csr(rcd->dd, rcd->ctxt, RCV_HDR_TAIL));
+
+ init_packet(rcd, &packet);
+ init_ps_mdata(&mdata, &packet);
+
+ while (1) {
+ struct hfi1_devdata *dd = rcd->dd;
+ __le32 *rhf_addr = (__le32 *)rcd->rcvhdrq + mdata.ps_head +
+ dd->rhf_offset;
+ struct ib_header *hdr;
+ u64 rhf = rhf_to_cpu(rhf_addr);
+ u32 etype = rhf_rcv_type(rhf), qpn;
+ u8 opcode;
+ u32 psn;
+ u8 lnh;
+
+ if (ps_done(&mdata, rhf, rcd))
+ break;
+
+ if (ps_skip(&mdata, rhf, rcd))
+ goto next;
+
+ if (etype > RHF_RCV_TYPE_IB)
+ goto next;
+
+ packet.hdr = hfi1_get_msgheader(dd, rhf_addr);
+ hdr = packet.hdr;
+
+ lnh = be16_to_cpu(hdr->lrh[0]) & 3;
+
+ if (lnh == HFI1_LRH_BTH)
+ packet.ohdr = &hdr->u.oth;
+ else if (lnh == HFI1_LRH_GRH)
+ packet.ohdr = &hdr->u.l.oth;
+ else
+ goto next; /* just in case */
+
+ opcode = (be32_to_cpu(packet.ohdr->bth[0]) >> 24);
+ qpn = be32_to_cpu(packet.ohdr->bth[1]) & RVT_QPN_MASK;
+ psn = mask_psn(be32_to_cpu(packet.ohdr->bth[2]));
+
+ seq_printf(s, "\tEnt %u: opcode 0x%x, qpn 0x%x, psn 0x%x\n",
+ mdata.ps_head, opcode, qpn, psn);
+next:
+ update_ps_mdata(&mdata, rcd);
+ }
+}
diff --git a/drivers/infiniband/hw/hfi1/eprom.c b/drivers/infiniband/hw/hfi1/eprom.c
index 26da124..d46b171 100644
--- a/drivers/infiniband/hw/hfi1/eprom.c
+++ b/drivers/infiniband/hw/hfi1/eprom.c
@@ -250,7 +250,6 @@ static int read_partition_platform_config(struct hfi1_devdata *dd, void **data,
{
void *buffer;
void *p;
- u32 length;
int ret;
buffer = kmalloc(P1_SIZE, GFP_KERNEL);
@@ -265,13 +264,13 @@ static int read_partition_platform_config(struct hfi1_devdata *dd, void **data,
/* scan for image magic that may trail the actual data */
p = strnstr(buffer, IMAGE_TRAIL_MAGIC, P1_SIZE);
- if (p)
- length = p - buffer;
- else
- length = P1_SIZE;
+ if (!p) {
+ kfree(buffer);
+ return -ENOENT;
+ }
*data = buffer;
- *size = length;
+ *size = p - buffer;
return 0;
}
diff --git a/drivers/infiniband/hw/hfi1/exp_rcv.c b/drivers/infiniband/hw/hfi1/exp_rcv.c
new file mode 100644
index 0000000..0af9167
--- /dev/null
+++ b/drivers/infiniband/hw/hfi1/exp_rcv.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright(c) 2017 Intel Corporation.
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * BSD LICENSE
+ *
+ * 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 Intel Corporation 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE 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 "exp_rcv.h"
+#include "trace.h"
+
+/**
+ * exp_tid_group_init - initialize exp_tid_set
+ * @set - the set
+ */
+void hfi1_exp_tid_group_init(struct exp_tid_set *set)
+{
+ INIT_LIST_HEAD(&set->list);
+ set->count = 0;
+}
+
+/**
+ * alloc_ctxt_rcv_groups - initialize expected receive groups
+ * @rcd - the context to add the groupings to
+ */
+int hfi1_alloc_ctxt_rcv_groups(struct hfi1_ctxtdata *rcd)
+{
+ struct hfi1_devdata *dd = rcd->dd;
+ u32 tidbase;
+ struct tid_group *grp;
+ int i;
+
+ tidbase = rcd->expected_base;
+ for (i = 0; i < rcd->expected_count /
+ dd->rcv_entries.group_size; i++) {
+ grp = kzalloc(sizeof(*grp), GFP_KERNEL);
+ if (!grp)
+ goto bail;
+ grp->size = dd->rcv_entries.group_size;
+ grp->base = tidbase;
+ tid_group_add_tail(grp, &rcd->tid_group_list);
+ tidbase += dd->rcv_entries.group_size;
+ }
+
+ return 0;
+bail:
+ hfi1_free_ctxt_rcv_groups(rcd);
+ return -ENOMEM;
+}
+
+/**
+ * free_ctxt_rcv_groups - free expected receive groups
+ * @rcd - the context to free
+ *
+ * The routine dismantles the expect receive linked
+ * list and clears any tids associated with the receive
+ * context.
+ *
+ * This should only be called for kernel contexts and the
+ * a base user context.
+ */
+void hfi1_free_ctxt_rcv_groups(struct hfi1_ctxtdata *rcd)
+{
+ struct tid_group *grp, *gptr;
+
+ WARN_ON(!EXP_TID_SET_EMPTY(rcd->tid_full_list));
+ WARN_ON(!EXP_TID_SET_EMPTY(rcd->tid_used_list));
+
+ list_for_each_entry_safe(grp, gptr, &rcd->tid_group_list.list, list) {
+ tid_group_remove(grp, &rcd->tid_group_list);
+ kfree(grp);
+ }
+
+ hfi1_clear_tids(rcd);
+}
diff --git a/drivers/infiniband/hw/hfi1/exp_rcv.h b/drivers/infiniband/hw/hfi1/exp_rcv.h
new file mode 100644
index 0000000..0871904
--- /dev/null
+++ b/drivers/infiniband/hw/hfi1/exp_rcv.h
@@ -0,0 +1,190 @@
+#ifndef _HFI1_EXP_RCV_H
+#define _HFI1_EXP_RCV_H
+/*
+ * Copyright(c) 2017 Intel Corporation.
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * BSD LICENSE
+ *
+ * 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 Intel Corporation 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE 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 "hfi.h"
+
+#define EXP_TID_SET_EMPTY(set) (set.count == 0 && list_empty(&set.list))
+
+#define EXP_TID_TIDLEN_MASK 0x7FFULL
+#define EXP_TID_TIDLEN_SHIFT 0
+#define EXP_TID_TIDCTRL_MASK 0x3ULL
+#define EXP_TID_TIDCTRL_SHIFT 20
+#define EXP_TID_TIDIDX_MASK 0x3FFULL
+#define EXP_TID_TIDIDX_SHIFT 22
+#define EXP_TID_GET(tid, field) \
+ (((tid) >> EXP_TID_TID##field##_SHIFT) & EXP_TID_TID##field##_MASK)
+
+#define EXP_TID_SET(field, value) \
+ (((value) & EXP_TID_TID##field##_MASK) << \
+ EXP_TID_TID##field##_SHIFT)
+#define EXP_TID_CLEAR(tid, field) ({ \
+ (tid) &= ~(EXP_TID_TID##field##_MASK << \
+ EXP_TID_TID##field##_SHIFT); \
+ })
+#define EXP_TID_RESET(tid, field, value) do { \
+ EXP_TID_CLEAR(tid, field); \
+ (tid) |= EXP_TID_SET(field, (value)); \
+ } while (0)
+
+/*
+ * Define fields in the KDETH header so we can update the header
+ * template.
+ */
+#define KDETH_OFFSET_SHIFT 0
+#define KDETH_OFFSET_MASK 0x7fff
+#define KDETH_OM_SHIFT 15
+#define KDETH_OM_MASK 0x1
+#define KDETH_TID_SHIFT 16
+#define KDETH_TID_MASK 0x3ff
+#define KDETH_TIDCTRL_SHIFT 26
+#define KDETH_TIDCTRL_MASK 0x3
+#define KDETH_INTR_SHIFT 28
+#define KDETH_INTR_MASK 0x1
+#define KDETH_SH_SHIFT 29
+#define KDETH_SH_MASK 0x1
+#define KDETH_KVER_SHIFT 30
+#define KDETH_KVER_MASK 0x3
+#define KDETH_JKEY_SHIFT 0x0
+#define KDETH_JKEY_MASK 0xff
+#define KDETH_HCRC_UPPER_SHIFT 16
+#define KDETH_HCRC_UPPER_MASK 0xff
+#define KDETH_HCRC_LOWER_SHIFT 24
+#define KDETH_HCRC_LOWER_MASK 0xff
+
+#define KDETH_GET(val, field) \
+ (((le32_to_cpu((val))) >> KDETH_##field##_SHIFT) & KDETH_##field##_MASK)
+#define KDETH_SET(dw, field, val) do { \
+ u32 dwval = le32_to_cpu(dw); \
+ dwval &= ~(KDETH_##field##_MASK << KDETH_##field##_SHIFT); \
+ dwval |= (((val) & KDETH_##field##_MASK) << \
+ KDETH_##field##_SHIFT); \
+ dw = cpu_to_le32(dwval); \
+ } while (0)
+
+#define KDETH_RESET(dw, field, val) ({ dw = 0; KDETH_SET(dw, field, val); })
+
+/* KDETH OM multipliers and switch over point */
+#define KDETH_OM_SMALL 4
+#define KDETH_OM_SMALL_SHIFT 2
+#define KDETH_OM_LARGE 64
+#define KDETH_OM_LARGE_SHIFT 6
+#define KDETH_OM_MAX_SIZE (1 << ((KDETH_OM_LARGE / KDETH_OM_SMALL) + 1))
+
+struct tid_group {
+ struct list_head list;
+ u32 base;
+ u8 size;
+ u8 used;
+ u8 map;
+};
+
+/*
+ * Write an "empty" RcvArray entry.
+ * This function exists so the TID registaration code can use it
+ * to write to unused/unneeded entries and still take advantage
+ * of the WC performance improvements. The HFI will ignore this
+ * write to the RcvArray entry.
+ */
+static inline void rcv_array_wc_fill(struct hfi1_devdata *dd, u32 index)
+{
+ /*
+ * Doing the WC fill writes only makes sense if the device is
+ * present and the RcvArray has been mapped as WC memory.
+ */
+ if ((dd->flags & HFI1_PRESENT) && dd->rcvarray_wc) {
+ writeq(0, dd->rcvarray_wc + (index * 8));
+ if ((index & 3) == 3)
+ flush_wc();
+ }
+}
+
+static inline void tid_group_add_tail(struct tid_group *grp,
+ struct exp_tid_set *set)
+{
+ list_add_tail(&grp->list, &set->list);
+ set->count++;
+}
+
+static inline void tid_group_remove(struct tid_group *grp,
+ struct exp_tid_set *set)
+{
+ list_del_init(&grp->list);
+ set->count--;
+}
+
+static inline void tid_group_move(struct tid_group *group,
+ struct exp_tid_set *s1,
+ struct exp_tid_set *s2)
+{
+ tid_group_remove(group, s1);
+ tid_group_add_tail(group, s2);
+}
+
+static inline struct tid_group *tid_group_pop(struct exp_tid_set *set)
+{
+ struct tid_group *grp =
+ list_first_entry(&set->list, struct tid_group, list);
+ list_del_init(&grp->list);
+ set->count--;
+ return grp;
+}
+
+static inline u32 rcventry2tidinfo(u32 rcventry)
+{
+ u32 pair = rcventry & ~0x1;
+
+ return EXP_TID_SET(IDX, pair >> 1) |
+ EXP_TID_SET(CTRL, 1 << (rcventry - pair));
+}
+
+int hfi1_alloc_ctxt_rcv_groups(struct hfi1_ctxtdata *rcd);
+void hfi1_free_ctxt_rcv_groups(struct hfi1_ctxtdata *rcd);
+void hfi1_exp_tid_group_init(struct exp_tid_set *set);
+
+#endif /* _HFI1_EXP_RCV_H */
diff --git a/drivers/infiniband/hw/hfi1/file_ops.c b/drivers/infiniband/hw/hfi1/file_ops.c
index 3158128..2bc8926 100644
--- a/drivers/infiniband/hw/hfi1/file_ops.c
+++ b/drivers/infiniband/hw/hfi1/file_ops.c
@@ -58,10 +58,10 @@
#include "device.h"
#include "common.h"
#include "trace.h"
+#include "mmu_rb.h"
#include "user_sdma.h"
#include "user_exp_rcv.h"
#include "aspm.h"
-#include "mmu_rb.h"
#undef pr_fmt
#define pr_fmt(fmt) DRIVER_NAME ": " fmt
@@ -79,21 +79,25 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma);
static u64 kvirt_to_phys(void *addr);
static int assign_ctxt(struct hfi1_filedata *fd, struct hfi1_user_info *uinfo);
-static int init_subctxts(struct hfi1_ctxtdata *uctxt,
- const struct hfi1_user_info *uinfo);
-static int init_user_ctxt(struct hfi1_filedata *fd);
+static void init_subctxts(struct hfi1_ctxtdata *uctxt,
+ const struct hfi1_user_info *uinfo);
+static int init_user_ctxt(struct hfi1_filedata *fd,
+ struct hfi1_ctxtdata *uctxt);
static void user_init(struct hfi1_ctxtdata *uctxt);
static int get_ctxt_info(struct hfi1_filedata *fd, void __user *ubase,
__u32 len);
static int get_base_info(struct hfi1_filedata *fd, void __user *ubase,
__u32 len);
-static int setup_base_ctxt(struct hfi1_filedata *fd);
+static int setup_base_ctxt(struct hfi1_filedata *fd,
+ struct hfi1_ctxtdata *uctxt);
static int setup_subctxt(struct hfi1_ctxtdata *uctxt);
static int find_sub_ctxt(struct hfi1_filedata *fd,
const struct hfi1_user_info *uinfo);
static int allocate_ctxt(struct hfi1_filedata *fd, struct hfi1_devdata *dd,
- struct hfi1_user_info *uinfo);
+ struct hfi1_user_info *uinfo,
+ struct hfi1_ctxtdata **cd);
+static void deallocate_ctxt(struct hfi1_ctxtdata *uctxt);
static unsigned int poll_urgent(struct file *fp, struct poll_table_struct *pt);
static unsigned int poll_next(struct file *fp, struct poll_table_struct *pt);
static int user_event_ack(struct hfi1_ctxtdata *uctxt, u16 subctxt,
@@ -116,7 +120,7 @@ static const struct file_operations hfi1_file_ops = {
.llseek = noop_llseek,
};
-static struct vm_operations_struct vm_ops = {
+static const struct vm_operations_struct vm_ops = {
.fault = vma_fault,
};
@@ -181,7 +185,7 @@ static int hfi1_file_open(struct inode *inode, struct file *fp)
struct hfi1_devdata,
user_cdev);
- if (!((dd->flags & HFI1_PRESENT) && dd->kregbase))
+ if (!((dd->flags & HFI1_PRESENT) && dd->kregbase1))
return -EINVAL;
if (!atomic_inc_not_zero(&dd->user_refcount))
@@ -267,12 +271,14 @@ static long hfi1_file_ioctl(struct file *fp, unsigned int cmd,
/*
* Copy the number of tidlist entries we used
* and the length of the buffer we registered.
- * These fields are adjacent in the structure so
- * we can copy them at the same time.
*/
addr = arg + offsetof(struct hfi1_tid_info, tidcnt);
if (copy_to_user((void __user *)addr, &tinfo.tidcnt,
- sizeof(tinfo.tidcnt) +
+ sizeof(tinfo.tidcnt)))
+ return -EFAULT;
+
+ addr = arg + offsetof(struct hfi1_tid_info, length);
+ if (copy_to_user((void __user *)addr, &tinfo.length,
sizeof(tinfo.length)))
ret = -EFAULT;
}
@@ -388,8 +394,7 @@ static long hfi1_file_ioctl(struct file *fp, unsigned int cmd,
sc_disable(sc);
ret = sc_enable(sc);
- hfi1_rcvctrl(dd, HFI1_RCVCTRL_CTXT_ENB,
- uctxt->ctxt);
+ hfi1_rcvctrl(dd, HFI1_RCVCTRL_CTXT_ENB, uctxt);
} else {
ret = sc_restart(sc);
}
@@ -425,8 +430,7 @@ static ssize_t hfi1_write_iter(struct kiocb *kiocb, struct iov_iter *from)
if (!iter_is_iovec(from) || !dim)
return -EINVAL;
- hfi1_cdbg(SDMA, "SDMA request from %u:%u (%lu)",
- fd->uctxt->ctxt, fd->subctxt, dim);
+ trace_hfi1_sdma_request(fd->dd, fd->uctxt->ctxt, fd->subctxt, dim);
if (atomic_read(&pq->n_reqs) == pq->n_max_reqs)
return -ENOSPC;
@@ -752,12 +756,11 @@ static int hfi1_file_close(struct inode *inode, struct file *fp)
if (!uctxt)
goto done;
- hfi1_cdbg(PROC, "freeing ctxt %u:%u", uctxt->ctxt, fdata->subctxt);
- mutex_lock(&hfi1_mutex);
+ hfi1_cdbg(PROC, "closing ctxt %u:%u", uctxt->ctxt, fdata->subctxt);
flush_wc();
/* drain user sdma queue */
- hfi1_user_sdma_free_queues(fdata);
+ hfi1_user_sdma_free_queues(fdata, uctxt);
/* release the cpu */
hfi1_put_proc_affinity(fdata->rec_cpu_num);
@@ -766,6 +769,13 @@ static int hfi1_file_close(struct inode *inode, struct file *fp)
hfi1_user_exp_rcv_free(fdata);
/*
+ * fdata->uctxt is used in the above cleanup. It is not ready to be
+ * removed until here.
+ */
+ fdata->uctxt = NULL;
+ hfi1_rcd_put(uctxt);
+
+ /*
* Clear any left over, unhandled events so the next process that
* gets this context doesn't get confused.
*/
@@ -773,13 +783,14 @@ static int hfi1_file_close(struct inode *inode, struct file *fp)
HFI1_MAX_SHARED_CTXTS) + fdata->subctxt;
*ev = 0;
+ spin_lock_irqsave(&dd->uctxt_lock, flags);
__clear_bit(fdata->subctxt, uctxt->in_use_ctxts);
if (!bitmap_empty(uctxt->in_use_ctxts, HFI1_MAX_SHARED_CTXTS)) {
- mutex_unlock(&hfi1_mutex);
+ spin_unlock_irqrestore(&dd->uctxt_lock, flags);
goto done;
}
+ spin_unlock_irqrestore(&dd->uctxt_lock, flags);
- spin_lock_irqsave(&dd->uctxt_lock, flags);
/*
* Disable receive context and interrupt available, reset all
* RcvCtxtCtrl bits to default values.
@@ -790,34 +801,24 @@ static int hfi1_file_close(struct inode *inode, struct file *fp)
HFI1_RCVCTRL_TAILUPD_DIS |
HFI1_RCVCTRL_ONE_PKT_EGR_DIS |
HFI1_RCVCTRL_NO_RHQ_DROP_DIS |
- HFI1_RCVCTRL_NO_EGR_DROP_DIS, uctxt->ctxt);
+ HFI1_RCVCTRL_NO_EGR_DROP_DIS, uctxt);
/* Clear the context's J_KEY */
- hfi1_clear_ctxt_jkey(dd, uctxt->ctxt);
+ hfi1_clear_ctxt_jkey(dd, uctxt);
/*
- * Reset context integrity checks to default.
- * (writes to CSRs probably belong in chip.c)
+ * If a send context is allocated, reset context integrity
+ * checks to default and disable the send context.
*/
- write_kctxt_csr(dd, uctxt->sc->hw_context, SEND_CTXT_CHECK_ENABLE,
- hfi1_pkt_default_send_ctxt_mask(dd, uctxt->sc->type));
- sc_disable(uctxt->sc);
- spin_unlock_irqrestore(&dd->uctxt_lock, flags);
-
- dd->rcd[uctxt->ctxt] = NULL;
+ if (uctxt->sc) {
+ set_pio_integrity(uctxt->sc);
+ sc_disable(uctxt->sc);
+ }
- hfi1_user_exp_rcv_grp_free(uctxt);
+ hfi1_free_ctxt_rcv_groups(uctxt);
hfi1_clear_ctxt_pkey(dd, uctxt);
- uctxt->rcvwait_to = 0;
- uctxt->piowait_to = 0;
- uctxt->rcvnowait = 0;
- uctxt->pionowait = 0;
uctxt->event_flags = 0;
- hfi1_stats.sps_ctxts--;
- if (++dd->freectxts == dd->num_user_contexts)
- aspm_enable_all(dd);
- mutex_unlock(&hfi1_mutex);
- hfi1_free_ctxtdata(dd, uctxt);
+ deallocate_ctxt(uctxt);
done:
mmdrop(fdata->mm);
kobject_put(&dd->kobj);
@@ -845,135 +846,211 @@ static u64 kvirt_to_phys(void *addr)
return paddr;
}
+/**
+ * complete_subctxt
+ * @fd: valid filedata pointer
+ *
+ * Sub-context info can only be set up after the base context
+ * has been completed. This is indicated by the clearing of the
+ * HFI1_CTXT_BASE_UINIT bit.
+ *
+ * Wait for the bit to be cleared, and then complete the subcontext
+ * initialization.
+ *
+ */
+static int complete_subctxt(struct hfi1_filedata *fd)
+{
+ int ret;
+ unsigned long flags;
+
+ /*
+ * sub-context info can only be set up after the base context
+ * has been completed.
+ */
+ ret = wait_event_interruptible(
+ fd->uctxt->wait,
+ !test_bit(HFI1_CTXT_BASE_UNINIT, &fd->uctxt->event_flags));
+
+ if (test_bit(HFI1_CTXT_BASE_FAILED, &fd->uctxt->event_flags))
+ ret = -ENOMEM;
+
+ /* Finish the sub-context init */
+ if (!ret) {
+ fd->rec_cpu_num = hfi1_get_proc_affinity(fd->uctxt->numa_id);
+ ret = init_user_ctxt(fd, fd->uctxt);
+ }
+
+ if (ret) {
+ hfi1_rcd_put(fd->uctxt);
+ fd->uctxt = NULL;
+ spin_lock_irqsave(&fd->dd->uctxt_lock, flags);
+ __clear_bit(fd->subctxt, fd->uctxt->in_use_ctxts);
+ spin_unlock_irqrestore(&fd->dd->uctxt_lock, flags);
+ }
+
+ return ret;
+}
+
static int assign_ctxt(struct hfi1_filedata *fd, struct hfi1_user_info *uinfo)
{
int ret;
unsigned int swmajor, swminor;
+ struct hfi1_ctxtdata *uctxt = NULL;
swmajor = uinfo->userversion >> 16;
if (swmajor != HFI1_USER_SWMAJOR)
return -ENODEV;
+ if (uinfo->subctxt_cnt > HFI1_MAX_SHARED_CTXTS)
+ return -EINVAL;
+
swminor = uinfo->userversion & 0xffff;
+ /*
+ * Acquire the mutex to protect against multiple creations of what
+ * could be a shared base context.
+ */
mutex_lock(&hfi1_mutex);
/*
- * Get a sub context if necessary.
+ * Get a sub context if available (fd->uctxt will be set).
* ret < 0 error, 0 no context, 1 sub-context found
*/
- ret = 0;
- if (uinfo->subctxt_cnt) {
- ret = find_sub_ctxt(fd, uinfo);
- if (ret > 0)
- fd->rec_cpu_num =
- hfi1_get_proc_affinity(fd->uctxt->numa_id);
- }
+ ret = find_sub_ctxt(fd, uinfo);
/*
- * Allocate a base context if context sharing is not required or we
- * couldn't find a sub context.
+ * Allocate a base context if context sharing is not required or a
+ * sub context wasn't found.
*/
if (!ret)
- ret = allocate_ctxt(fd, fd->dd, uinfo);
+ ret = allocate_ctxt(fd, fd->dd, uinfo, &uctxt);
mutex_unlock(&hfi1_mutex);
- /* Depending on the context type, do the appropriate init */
- if (ret > 0) {
- /*
- * sub-context info can only be set up after the base
- * context has been completed.
- */
- ret = wait_event_interruptible(fd->uctxt->wait, !test_bit(
- HFI1_CTXT_BASE_UNINIT,
- &fd->uctxt->event_flags));
- if (test_bit(HFI1_CTXT_BASE_FAILED, &fd->uctxt->event_flags)) {
- clear_bit(fd->subctxt, fd->uctxt->in_use_ctxts);
- return -ENOMEM;
- }
- /* The only thing a sub context needs is the user_xxx stuff */
- if (!ret)
- ret = init_user_ctxt(fd);
-
- if (ret)
- clear_bit(fd->subctxt, fd->uctxt->in_use_ctxts);
- } else if (!ret) {
- ret = setup_base_ctxt(fd);
- if (fd->uctxt->subctxt_cnt) {
- /* If there is an error, set the failed bit. */
- if (ret)
- set_bit(HFI1_CTXT_BASE_FAILED,
- &fd->uctxt->event_flags);
+ /* Depending on the context type, finish the appropriate init */
+ switch (ret) {
+ case 0:
+ ret = setup_base_ctxt(fd, uctxt);
+ if (uctxt->subctxt_cnt) {
/*
- * Base context is done, notify anybody using a
- * sub-context that is waiting for this completion
+ * Base context is done (successfully or not), notify
+ * anybody using a sub-context that is waiting for
+ * this completion.
*/
- clear_bit(HFI1_CTXT_BASE_UNINIT,
- &fd->uctxt->event_flags);
- wake_up(&fd->uctxt->wait);
+ clear_bit(HFI1_CTXT_BASE_UNINIT, &uctxt->event_flags);
+ wake_up(&uctxt->wait);
}
+ break;
+ case 1:
+ ret = complete_subctxt(fd);
+ break;
+ default:
+ break;
}
return ret;
}
-/*
- * The hfi1_mutex must be held when this function is called. It is
- * necessary to ensure serialized access to the bitmask in_use_ctxts.
+/**
+ * match_ctxt
+ * @fd: valid filedata pointer
+ * @uinfo: user info to compare base context with
+ * @uctxt: context to compare uinfo to.
+ *
+ * Compare the given context with the given information to see if it
+ * can be used for a sub context.
*/
-static int find_sub_ctxt(struct hfi1_filedata *fd,
- const struct hfi1_user_info *uinfo)
+static int match_ctxt(struct hfi1_filedata *fd,
+ const struct hfi1_user_info *uinfo,
+ struct hfi1_ctxtdata *uctxt)
{
- int i;
struct hfi1_devdata *dd = fd->dd;
+ unsigned long flags;
u16 subctxt;
- for (i = dd->first_dyn_alloc_ctxt; i < dd->num_rcv_contexts; i++) {
- struct hfi1_ctxtdata *uctxt = dd->rcd[i];
+ /* Skip dynamically allocated kernel contexts */
+ if (uctxt->sc && (uctxt->sc->type == SC_KERNEL))
+ return 0;
- /* Skip ctxts which are not yet open */
- if (!uctxt ||
- bitmap_empty(uctxt->in_use_ctxts,
- HFI1_MAX_SHARED_CTXTS))
- continue;
+ /* Skip ctxt if it doesn't match the requested one */
+ if (memcmp(uctxt->uuid, uinfo->uuid, sizeof(uctxt->uuid)) ||
+ uctxt->jkey != generate_jkey(current_uid()) ||
+ uctxt->subctxt_id != uinfo->subctxt_id ||
+ uctxt->subctxt_cnt != uinfo->subctxt_cnt)
+ return 0;
- /* Skip dynamically allocted kernel contexts */
- if (uctxt->sc && (uctxt->sc->type == SC_KERNEL))
- continue;
+ /* Verify the sharing process matches the base */
+ if (uctxt->userversion != uinfo->userversion)
+ return -EINVAL;
- /* Skip ctxt if it doesn't match the requested one */
- if (memcmp(uctxt->uuid, uinfo->uuid,
- sizeof(uctxt->uuid)) ||
- uctxt->jkey != generate_jkey(current_uid()) ||
- uctxt->subctxt_id != uinfo->subctxt_id ||
- uctxt->subctxt_cnt != uinfo->subctxt_cnt)
- continue;
+ /* Find an unused sub context */
+ spin_lock_irqsave(&dd->uctxt_lock, flags);
+ if (bitmap_empty(uctxt->in_use_ctxts, HFI1_MAX_SHARED_CTXTS)) {
+ /* context is being closed, do not use */
+ spin_unlock_irqrestore(&dd->uctxt_lock, flags);
+ return 0;
+ }
- /* Verify the sharing process matches the master */
- if (uctxt->userversion != uinfo->userversion)
- return -EINVAL;
+ subctxt = find_first_zero_bit(uctxt->in_use_ctxts,
+ HFI1_MAX_SHARED_CTXTS);
+ if (subctxt >= uctxt->subctxt_cnt) {
+ spin_unlock_irqrestore(&dd->uctxt_lock, flags);
+ return -EBUSY;
+ }
- /* Find an unused context */
- subctxt = find_first_zero_bit(uctxt->in_use_ctxts,
- HFI1_MAX_SHARED_CTXTS);
- if (subctxt >= uctxt->subctxt_cnt)
- return -EBUSY;
+ fd->subctxt = subctxt;
+ __set_bit(fd->subctxt, uctxt->in_use_ctxts);
+ spin_unlock_irqrestore(&dd->uctxt_lock, flags);
- fd->uctxt = uctxt;
- fd->subctxt = subctxt;
- __set_bit(fd->subctxt, uctxt->in_use_ctxts);
+ fd->uctxt = uctxt;
+ hfi1_rcd_get(uctxt);
+
+ return 1;
+}
- return 1;
+/**
+ * find_sub_ctxt
+ * @fd: valid filedata pointer
+ * @uinfo: matching info to use to find a possible context to share.
+ *
+ * The hfi1_mutex must be held when this function is called. It is
+ * necessary to ensure serialized creation of shared contexts.
+ *
+ * Return:
+ * 0 No sub-context found
+ * 1 Subcontext found and allocated
+ * errno EINVAL (incorrect parameters)
+ * EBUSY (all sub contexts in use)
+ */
+static int find_sub_ctxt(struct hfi1_filedata *fd,
+ const struct hfi1_user_info *uinfo)
+{
+ struct hfi1_ctxtdata *uctxt;
+ struct hfi1_devdata *dd = fd->dd;
+ u16 i;
+ int ret;
+
+ if (!uinfo->subctxt_cnt)
+ return 0;
+
+ for (i = dd->first_dyn_alloc_ctxt; i < dd->num_rcv_contexts; i++) {
+ uctxt = hfi1_rcd_get_by_index(dd, i);
+ if (uctxt) {
+ ret = match_ctxt(fd, uinfo, uctxt);
+ hfi1_rcd_put(uctxt);
+ /* value of != 0 will return */
+ if (ret)
+ return ret;
+ }
}
return 0;
}
static int allocate_ctxt(struct hfi1_filedata *fd, struct hfi1_devdata *dd,
- struct hfi1_user_info *uinfo)
+ struct hfi1_user_info *uinfo,
+ struct hfi1_ctxtdata **rcd)
{
struct hfi1_ctxtdata *uctxt;
- unsigned int ctxt;
int ret, numa;
if (dd->flags & HFI1_FROZEN) {
@@ -987,22 +1064,9 @@ static int allocate_ctxt(struct hfi1_filedata *fd, struct hfi1_devdata *dd,
return -EIO;
}
- /*
- * This check is sort of redundant to the next EBUSY error. It would
- * also indicate an inconsistancy in the driver if this value was
- * zero, but there were still contexts available.
- */
if (!dd->freectxts)
return -EBUSY;
- for (ctxt = dd->first_dyn_alloc_ctxt;
- ctxt < dd->num_rcv_contexts; ctxt++)
- if (!dd->rcd[ctxt])
- break;
-
- if (ctxt == dd->num_rcv_contexts)
- return -EBUSY;
-
/*
* If we don't have a NUMA node requested, preference is towards
* device NUMA node.
@@ -1012,11 +1076,10 @@ static int allocate_ctxt(struct hfi1_filedata *fd, struct hfi1_devdata *dd,
numa = cpu_to_node(fd->rec_cpu_num);
else
numa = numa_node_id();
- uctxt = hfi1_create_ctxtdata(dd->pport, ctxt, numa);
- if (!uctxt) {
- dd_dev_err(dd,
- "Unable to allocate ctxtdata memory, failing open\n");
- return -ENOMEM;
+ ret = hfi1_create_ctxtdata(dd->pport, numa, &uctxt);
+ if (ret < 0) {
+ dd_dev_err(dd, "user ctxtdata allocation failed\n");
+ return ret;
}
hfi1_cdbg(PROC, "[%u:%u] pid %u assigned to CPU %d (NUMA %u)",
uctxt->ctxt, fd->subctxt, current->pid, fd->rec_cpu_num,
@@ -1025,8 +1088,7 @@ static int allocate_ctxt(struct hfi1_filedata *fd, struct hfi1_devdata *dd,
/*
* Allocate and enable a PIO send context.
*/
- uctxt->sc = sc_alloc(dd, SC_USER, uctxt->rcvhdrqentsize,
- uctxt->dd->node);
+ uctxt->sc = sc_alloc(dd, SC_USER, uctxt->rcvhdrqentsize, dd->node);
if (!uctxt->sc) {
ret = -ENOMEM;
goto ctxdata_free;
@@ -1038,28 +1100,19 @@ static int allocate_ctxt(struct hfi1_filedata *fd, struct hfi1_devdata *dd,
goto ctxdata_free;
/*
- * Setup sub context resources if the user-level has requested
+ * Setup sub context information if the user-level has requested
* sub contexts.
* This has to be done here so the rest of the sub-contexts find the
- * proper master.
+ * proper base context.
*/
- if (uinfo->subctxt_cnt) {
- ret = init_subctxts(uctxt, uinfo);
- /*
- * On error, we don't need to disable and de-allocate the
- * send context because it will be done during file close
- */
- if (ret)
- goto ctxdata_free;
- }
+ if (uinfo->subctxt_cnt)
+ init_subctxts(uctxt, uinfo);
uctxt->userversion = uinfo->userversion;
uctxt->flags = hfi1_cap_mask; /* save current flag state */
init_waitqueue_head(&uctxt->wait);
strlcpy(uctxt->comm, current->comm, sizeof(uctxt->comm));
memcpy(uctxt->uuid, uinfo->uuid, sizeof(uctxt->uuid));
uctxt->jkey = generate_jkey(current_uid());
- INIT_LIST_HEAD(&uctxt->sdma_queues);
- spin_lock_init(&uctxt->sdma_qlock);
hfi1_stats.sps_ctxts++;
/*
* Disable ASPM when there are open user/PSM contexts to avoid
@@ -1067,31 +1120,33 @@ static int allocate_ctxt(struct hfi1_filedata *fd, struct hfi1_devdata *dd,
*/
if (dd->freectxts-- == dd->num_user_contexts)
aspm_disable_all(dd);
- fd->uctxt = uctxt;
+
+ *rcd = uctxt;
return 0;
ctxdata_free:
- dd->rcd[ctxt] = NULL;
- hfi1_free_ctxtdata(dd, uctxt);
+ hfi1_free_ctxt(uctxt);
return ret;
}
-static int init_subctxts(struct hfi1_ctxtdata *uctxt,
- const struct hfi1_user_info *uinfo)
+static void deallocate_ctxt(struct hfi1_ctxtdata *uctxt)
{
- u16 num_subctxts;
+ mutex_lock(&hfi1_mutex);
+ hfi1_stats.sps_ctxts--;
+ if (++uctxt->dd->freectxts == uctxt->dd->num_user_contexts)
+ aspm_enable_all(uctxt->dd);
+ mutex_unlock(&hfi1_mutex);
- num_subctxts = uinfo->subctxt_cnt;
- if (num_subctxts > HFI1_MAX_SHARED_CTXTS)
- return -EINVAL;
+ hfi1_free_ctxt(uctxt);
+}
+static void init_subctxts(struct hfi1_ctxtdata *uctxt,
+ const struct hfi1_user_info *uinfo)
+{
uctxt->subctxt_cnt = uinfo->subctxt_cnt;
uctxt->subctxt_id = uinfo->subctxt_id;
- uctxt->redirect_seq_cnt = 1;
set_bit(HFI1_CTXT_BASE_UNINIT, &uctxt->event_flags);
-
- return 0;
}
static int setup_subctxt(struct hfi1_ctxtdata *uctxt)
@@ -1153,7 +1208,7 @@ static void user_init(struct hfi1_ctxtdata *uctxt)
clear_rcvhdrtail(uctxt);
/* Setup J_KEY before enabling the context */
- hfi1_set_ctxt_jkey(uctxt->dd, uctxt->ctxt, uctxt->jkey);
+ hfi1_set_ctxt_jkey(uctxt->dd, uctxt, uctxt->jkey);
rcvctrl_ops = HFI1_RCVCTRL_CTXT_ENB;
if (HFI1_CAP_UGET_MASK(uctxt->flags, HDRSUPP))
@@ -1179,7 +1234,7 @@ static void user_init(struct hfi1_ctxtdata *uctxt)
rcvctrl_ops |= HFI1_RCVCTRL_TAILUPD_ENB;
else
rcvctrl_ops |= HFI1_RCVCTRL_TAILUPD_DIS;
- hfi1_rcvctrl(uctxt->dd, rcvctrl_ops, uctxt->ctxt);
+ hfi1_rcvctrl(uctxt->dd, rcvctrl_ops, uctxt);
}
static int get_ctxt_info(struct hfi1_filedata *fd, void __user *ubase,
@@ -1223,23 +1278,25 @@ static int get_ctxt_info(struct hfi1_filedata *fd, void __user *ubase,
return ret;
}
-static int init_user_ctxt(struct hfi1_filedata *fd)
+static int init_user_ctxt(struct hfi1_filedata *fd,
+ struct hfi1_ctxtdata *uctxt)
{
- struct hfi1_ctxtdata *uctxt = fd->uctxt;
int ret;
ret = hfi1_user_sdma_alloc_queues(uctxt, fd);
if (ret)
return ret;
- ret = hfi1_user_exp_rcv_init(fd);
+ ret = hfi1_user_exp_rcv_init(fd, uctxt);
+ if (ret)
+ hfi1_user_sdma_free_queues(fd, uctxt);
return ret;
}
-static int setup_base_ctxt(struct hfi1_filedata *fd)
+static int setup_base_ctxt(struct hfi1_filedata *fd,
+ struct hfi1_ctxtdata *uctxt)
{
- struct hfi1_ctxtdata *uctxt = fd->uctxt;
struct hfi1_devdata *dd = uctxt->dd;
int ret = 0;
@@ -1260,20 +1317,27 @@ static int setup_base_ctxt(struct hfi1_filedata *fd)
if (ret)
goto setup_failed;
- ret = hfi1_user_exp_rcv_grp_init(fd);
+ ret = hfi1_alloc_ctxt_rcv_groups(uctxt);
if (ret)
goto setup_failed;
- ret = init_user_ctxt(fd);
+ ret = init_user_ctxt(fd, uctxt);
if (ret)
goto setup_failed;
user_init(uctxt);
+ /* Now that the context is set up, the fd can get a reference. */
+ fd->uctxt = uctxt;
+ hfi1_rcd_get(uctxt);
+
return 0;
setup_failed:
- hfi1_free_ctxtdata(dd, uctxt);
+ /* Set the failed bit so sub-context init can do the right thing */
+ set_bit(HFI1_CTXT_BASE_FAILED, &uctxt->event_flags);
+ deallocate_ctxt(uctxt);
+
return ret;
}
@@ -1390,7 +1454,7 @@ static unsigned int poll_next(struct file *fp,
spin_lock_irq(&dd->uctxt_lock);
if (hdrqempty(uctxt)) {
set_bit(HFI1_CTXT_WAITING_RCV, &uctxt->event_flags);
- hfi1_rcvctrl(dd, HFI1_RCVCTRL_INTRAVAIL_ENB, uctxt->ctxt);
+ hfi1_rcvctrl(dd, HFI1_RCVCTRL_INTRAVAIL_ENB, uctxt);
pollflag = 0;
} else {
pollflag = POLLIN | POLLRDNORM;
@@ -1409,19 +1473,14 @@ int hfi1_set_uevent_bits(struct hfi1_pportdata *ppd, const int evtbit)
{
struct hfi1_ctxtdata *uctxt;
struct hfi1_devdata *dd = ppd->dd;
- unsigned ctxt;
- int ret = 0;
- unsigned long flags;
+ u16 ctxt;
- if (!dd->events) {
- ret = -EINVAL;
- goto done;
- }
+ if (!dd->events)
+ return -EINVAL;
- spin_lock_irqsave(&dd->uctxt_lock, flags);
for (ctxt = dd->first_dyn_alloc_ctxt; ctxt < dd->num_rcv_contexts;
ctxt++) {
- uctxt = dd->rcd[ctxt];
+ uctxt = hfi1_rcd_get_by_index(dd, ctxt);
if (uctxt) {
unsigned long *evs = dd->events +
(uctxt->ctxt - dd->first_dyn_alloc_ctxt) *
@@ -1434,11 +1493,11 @@ int hfi1_set_uevent_bits(struct hfi1_pportdata *ppd, const int evtbit)
set_bit(evtbit, evs);
for (i = 1; i < uctxt->subctxt_cnt; i++)
set_bit(evtbit, evs + i);
+ hfi1_rcd_put(uctxt);
}
}
- spin_unlock_irqrestore(&dd->uctxt_lock, flags);
-done:
- return ret;
+
+ return 0;
}
/**
@@ -1475,7 +1534,7 @@ static int manage_rcvq(struct hfi1_ctxtdata *uctxt, u16 subctxt,
} else {
rcvctrl_op = HFI1_RCVCTRL_CTXT_DIS;
}
- hfi1_rcvctrl(dd, rcvctrl_op, uctxt->ctxt);
+ hfi1_rcvctrl(dd, rcvctrl_op, uctxt);
/* always; new head should be equal to new tail; see above */
bail:
return 0;
@@ -1525,7 +1584,7 @@ static int set_ctxt_pkey(struct hfi1_ctxtdata *uctxt, u16 subctxt, u16 pkey)
}
if (intable)
- ret = hfi1_set_ctxt_pkey(dd, uctxt->ctxt, pkey);
+ ret = hfi1_set_ctxt_pkey(dd, uctxt, pkey);
done:
return ret;
}
diff --git a/drivers/infiniband/hw/hfi1/firmware.c b/drivers/infiniband/hw/hfi1/firmware.c
index 4042c11..5aea8f4 100644
--- a/drivers/infiniband/hw/hfi1/firmware.c
+++ b/drivers/infiniband/hw/hfi1/firmware.c
@@ -64,30 +64,22 @@
#define DEFAULT_FW_FABRIC_NAME "hfi1_fabric.fw"
#define DEFAULT_FW_SBUS_NAME "hfi1_sbus.fw"
#define DEFAULT_FW_PCIE_NAME "hfi1_pcie.fw"
-#define DEFAULT_PLATFORM_CONFIG_NAME "hfi1_platform.dat"
#define ALT_FW_8051_NAME_ASIC "hfi1_dc8051_d.fw"
#define ALT_FW_FABRIC_NAME "hfi1_fabric_d.fw"
#define ALT_FW_SBUS_NAME "hfi1_sbus_d.fw"
#define ALT_FW_PCIE_NAME "hfi1_pcie_d.fw"
+#define HOST_INTERFACE_VERSION 1
static uint fw_8051_load = 1;
static uint fw_fabric_serdes_load = 1;
static uint fw_pcie_serdes_load = 1;
static uint fw_sbus_load = 1;
-/*
- * Access required in platform.c
- * Maintains state of whether the platform config was fetched via the
- * fallback option
- */
-uint platform_config_load;
-
/* Firmware file names get set in hfi1_firmware_init() based on the above */
static char *fw_8051_name;
static char *fw_fabric_serdes_name;
static char *fw_sbus_name;
static char *fw_pcie_serdes_name;
-static char *platform_config_name;
#define SBUS_MAX_POLL_COUNT 100
#define SBUS_COUNTER(reg, name) \
@@ -177,7 +169,6 @@ static struct firmware_details fw_8051;
static struct firmware_details fw_fabric;
static struct firmware_details fw_pcie;
static struct firmware_details fw_sbus;
-static const struct firmware *platform_config;
/* flags for turn_off_spicos() */
#define SPICO_SBUS 0x1
@@ -615,6 +606,14 @@ retry:
fw_fabric_serdes_name = ALT_FW_FABRIC_NAME;
fw_sbus_name = ALT_FW_SBUS_NAME;
fw_pcie_serdes_name = ALT_FW_PCIE_NAME;
+
+ /*
+ * Add a delay before obtaining and loading debug firmware.
+ * Authorization will fail if the delay between firmware
+ * authorization events is shorter than 50us. Add 100us to
+ * make a delay time safe.
+ */
+ usleep_range(100, 120);
}
if (fw_sbus_load) {
@@ -675,7 +674,6 @@ done:
static int obtain_firmware(struct hfi1_devdata *dd)
{
unsigned long timeout;
- int err = 0;
mutex_lock(&fw_mutex);
@@ -699,38 +697,11 @@ static int obtain_firmware(struct hfi1_devdata *dd)
}
/* not in FW_TRY state */
- if (fw_state == FW_FINAL) {
- if (platform_config) {
- dd->platform_config.data = platform_config->data;
- dd->platform_config.size = platform_config->size;
- }
- goto done; /* already acquired */
- } else if (fw_state == FW_ERR) {
- goto done; /* already tried and failed */
- }
- /* fw_state is FW_EMPTY */
-
/* set fw_state to FW_TRY, FW_FINAL, or FW_ERR, and fw_err */
- __obtain_firmware(dd);
-
- if (platform_config_load) {
- platform_config = NULL;
- err = request_firmware(&platform_config, platform_config_name,
- &dd->pcidev->dev);
- if (err) {
- platform_config = NULL;
- dd_dev_err(dd,
- "%s: No default platform config file found\n",
- __func__);
- goto done;
- }
- dd->platform_config.data = platform_config->data;
- dd->platform_config.size = platform_config->size;
- }
+ if (fw_state == FW_EMPTY)
+ __obtain_firmware(dd);
-done:
mutex_unlock(&fw_mutex);
-
return fw_err;
}
@@ -752,9 +723,6 @@ void dispose_firmware(void)
dispose_one_firmware(&fw_pcie);
dispose_one_firmware(&fw_sbus);
- release_firmware(platform_config);
- platform_config = NULL;
-
/* retain the error state, otherwise revert to empty */
if (fw_state != FW_ERR)
fw_state = FW_EMPTY;
@@ -1079,6 +1047,13 @@ static int load_8051_firmware(struct hfi1_devdata *dd,
dd_dev_info(dd, "8051 firmware version %d.%d.%d\n",
(int)ver_major, (int)ver_minor, (int)ver_patch);
dd->dc8051_ver = dc8051_ver(ver_major, ver_minor, ver_patch);
+ ret = write_host_interface_version(dd, HOST_INTERFACE_VERSION);
+ if (ret != HCMD_SUCCESS) {
+ dd_dev_err(dd,
+ "Failed to set host interface version, return 0x%x\n",
+ ret);
+ return -EIO;
+ }
return 0;
}
@@ -1709,10 +1684,8 @@ int hfi1_firmware_init(struct hfi1_devdata *dd)
}
/* no 8051 or QSFP on simulator */
- if (dd->icode == ICODE_FUNCTIONAL_SIMULATOR) {
+ if (dd->icode == ICODE_FUNCTIONAL_SIMULATOR)
fw_8051_load = 0;
- platform_config_load = 0;
- }
if (!fw_8051_name) {
if (dd->icode == ICODE_RTL_SILICON)
@@ -1726,8 +1699,6 @@ int hfi1_firmware_init(struct hfi1_devdata *dd)
fw_sbus_name = DEFAULT_FW_SBUS_NAME;
if (!fw_pcie_serdes_name)
fw_pcie_serdes_name = DEFAULT_FW_PCIE_NAME;
- if (!platform_config_name)
- platform_config_name = DEFAULT_PLATFORM_CONFIG_NAME;
return obtain_firmware(dd);
}
@@ -1773,6 +1744,7 @@ static int check_meta_version(struct hfi1_devdata *dd, u32 *system_table)
int parse_platform_config(struct hfi1_devdata *dd)
{
struct platform_config_cache *pcfgcache = &dd->pcfg_cache;
+ struct hfi1_pportdata *ppd = dd->pport;
u32 *ptr = NULL;
u32 header1 = 0, header2 = 0, magic_num = 0, crc = 0, file_length = 0;
u32 record_idx = 0, table_type = 0, table_length_dwords = 0;
@@ -1784,7 +1756,7 @@ int parse_platform_config(struct hfi1_devdata *dd)
* scratch register bitmap, thus there is no platform config to parse.
* Skip parsing in these situations.
*/
- if (is_integrated(dd) && !platform_config_load)
+ if (ppd->config_from_scratch)
return 0;
if (!dd->platform_config.data) {
@@ -2073,13 +2045,14 @@ int get_platform_config_field(struct hfi1_devdata *dd,
int ret = 0, wlen = 0, seek = 0;
u32 field_len_bits = 0, field_start_bits = 0, *src_ptr = NULL;
struct platform_config_cache *pcfgcache = &dd->pcfg_cache;
+ struct hfi1_pportdata *ppd = dd->pport;
if (data)
memset(data, 0, len);
else
return -EINVAL;
- if (is_integrated(dd) && !platform_config_load) {
+ if (ppd->config_from_scratch) {
/*
* Use saved configuration from ppd for integrated platforms
*/
diff --git a/drivers/infiniband/hw/hfi1/hfi.h b/drivers/infiniband/hw/hfi1/hfi.h
index 414a04a..3ac9c30 100644
--- a/drivers/infiniband/hw/hfi1/hfi.h
+++ b/drivers/infiniband/hw/hfi1/hfi.h
@@ -66,9 +66,11 @@
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <rdma/ib_hdrs.h>
+#include <rdma/opa_addr.h>
#include <linux/rhashtable.h>
#include <linux/netdevice.h>
#include <rdma/rdma_vt.h>
+#include <rdma/opa_addr.h>
#include "chip_registers.h"
#include "common.h"
@@ -213,13 +215,11 @@ struct hfi1_ctxtdata {
/* dynamic receive available interrupt timeout */
u32 rcvavail_timeout;
- /*
- * number of opens (including slave sub-contexts) on this instance
- * (ignoring forks, dup, etc. for now)
- */
- int cnt;
+ /* Reference count the base context usage */
+ struct kref kref;
+
/* Device context index */
- unsigned ctxt;
+ u16 ctxt;
/*
* non-zero if ctxt can be shared, and defines the maximum number of
* sub-contexts for this device context.
@@ -245,24 +245,10 @@ struct hfi1_ctxtdata {
/* lock protecting all Expected TID data */
struct mutex exp_lock;
- /* number of pio bufs for this ctxt (all procs, if shared) */
- u32 piocnt;
- /* first pio buffer for this ctxt */
- u32 pio_base;
- /* chip offset of PIO buffers for this ctxt */
- u32 piobufs;
/* per-context configuration flags */
unsigned long flags;
/* per-context event flags for fileops/intr communication */
unsigned long event_flags;
- /* WAIT_RCV that timed out, no interrupt */
- u32 rcvwait_to;
- /* WAIT_PIO that timed out, no interrupt */
- u32 piowait_to;
- /* WAIT_RCV already happened, no wait */
- u32 rcvnowait;
- /* WAIT_PIO already happened, no wait */
- u32 pionowait;
/* total number of polled urgent packets */
u32 urgent;
/* saved total number of polled urgent packets for poll edge trigger */
@@ -289,10 +275,8 @@ struct hfi1_ctxtdata {
u16 poll_type;
/* receive packet sequence counter */
u8 seq_cnt;
- u8 redirect_seq_cnt;
/* ctxt rcvhdrq head offset */
u32 head;
- u32 pkt_count;
/* QPs waiting for context processing */
struct list_head qp_wait_list;
/* interrupt handling */
@@ -301,15 +285,6 @@ struct hfi1_ctxtdata {
unsigned numa_id; /* numa node of this context */
/* verbs stats per CTX */
struct hfi1_opcode_stats_perctx *opstats;
- /*
- * This is the kernel thread that will keep making
- * progress on the user sdma requests behind the scenes.
- * There is one per context (shared contexts use the master's).
- */
- struct task_struct *progress;
- struct list_head sdma_queues;
- /* protect sdma queues */
- spinlock_t sdma_qlock;
/* Is ASPM interrupt supported for this context */
bool aspm_intr_supported;
@@ -352,23 +327,150 @@ struct hfi1_ctxtdata {
struct hfi1_packet {
void *ebuf;
void *hdr;
+ void *payload;
struct hfi1_ctxtdata *rcd;
__le32 *rhf_addr;
struct rvt_qp *qp;
struct ib_other_headers *ohdr;
+ struct ib_grh *grh;
u64 rhf;
u32 maxcnt;
u32 rhqoff;
+ u32 dlid;
+ u32 slid;
u16 tlen;
s16 etail;
u8 hlen;
u8 numpkt;
u8 rsize;
u8 updegr;
- u8 rcv_flags;
u8 etype;
+ u8 extra_byte;
+ u8 pad;
+ u8 sc;
+ u8 sl;
+ u8 opcode;
+ bool becn;
+ bool fecn;
};
+/* Packet types */
+#define HFI1_PKT_TYPE_9B 0
+#define HFI1_PKT_TYPE_16B 1
+
+/*
+ * OPA 16B Header
+ */
+#define OPA_16B_L4_MASK 0xFFull
+#define OPA_16B_SC_MASK 0x1F00000ull
+#define OPA_16B_SC_SHIFT 20
+#define OPA_16B_LID_MASK 0xFFFFFull
+#define OPA_16B_DLID_MASK 0xF000ull
+#define OPA_16B_DLID_SHIFT 20
+#define OPA_16B_DLID_HIGH_SHIFT 12
+#define OPA_16B_SLID_MASK 0xF00ull
+#define OPA_16B_SLID_SHIFT 20
+#define OPA_16B_SLID_HIGH_SHIFT 8
+#define OPA_16B_BECN_MASK 0x80000000ull
+#define OPA_16B_BECN_SHIFT 31
+#define OPA_16B_FECN_MASK 0x10000000ull
+#define OPA_16B_FECN_SHIFT 28
+#define OPA_16B_L2_MASK 0x60000000ull
+#define OPA_16B_L2_SHIFT 29
+#define OPA_16B_PKEY_MASK 0xFFFF0000ull
+#define OPA_16B_PKEY_SHIFT 16
+#define OPA_16B_LEN_MASK 0x7FF00000ull
+#define OPA_16B_LEN_SHIFT 20
+#define OPA_16B_RC_MASK 0xE000000ull
+#define OPA_16B_RC_SHIFT 25
+#define OPA_16B_AGE_MASK 0xFF0000ull
+#define OPA_16B_AGE_SHIFT 16
+#define OPA_16B_ENTROPY_MASK 0xFFFFull
+
+/*
+ * OPA 16B L2/L4 Encodings
+ */
+#define OPA_16B_L2_TYPE 0x02
+#define OPA_16B_L4_IB_LOCAL 0x09
+#define OPA_16B_L4_IB_GLOBAL 0x0A
+#define OPA_16B_L4_ETHR OPA_VNIC_L4_ETHR
+
+static inline u8 hfi1_16B_get_l4(struct hfi1_16b_header *hdr)
+{
+ return (u8)(hdr->lrh[2] & OPA_16B_L4_MASK);
+}
+
+static inline u8 hfi1_16B_get_sc(struct hfi1_16b_header *hdr)
+{
+ return (u8)((hdr->lrh[1] & OPA_16B_SC_MASK) >> OPA_16B_SC_SHIFT);
+}
+
+static inline u32 hfi1_16B_get_dlid(struct hfi1_16b_header *hdr)
+{
+ return (u32)((hdr->lrh[1] & OPA_16B_LID_MASK) |
+ (((hdr->lrh[2] & OPA_16B_DLID_MASK) >>
+ OPA_16B_DLID_HIGH_SHIFT) << OPA_16B_DLID_SHIFT));
+}
+
+static inline u32 hfi1_16B_get_slid(struct hfi1_16b_header *hdr)
+{
+ return (u32)((hdr->lrh[0] & OPA_16B_LID_MASK) |
+ (((hdr->lrh[2] & OPA_16B_SLID_MASK) >>
+ OPA_16B_SLID_HIGH_SHIFT) << OPA_16B_SLID_SHIFT));
+}
+
+static inline u8 hfi1_16B_get_becn(struct hfi1_16b_header *hdr)
+{
+ return (u8)((hdr->lrh[0] & OPA_16B_BECN_MASK) >> OPA_16B_BECN_SHIFT);
+}
+
+static inline u8 hfi1_16B_get_fecn(struct hfi1_16b_header *hdr)
+{
+ return (u8)((hdr->lrh[1] & OPA_16B_FECN_MASK) >> OPA_16B_FECN_SHIFT);
+}
+
+static inline u8 hfi1_16B_get_l2(struct hfi1_16b_header *hdr)
+{
+ return (u8)((hdr->lrh[1] & OPA_16B_L2_MASK) >> OPA_16B_L2_SHIFT);
+}
+
+static inline u16 hfi1_16B_get_pkey(struct hfi1_16b_header *hdr)
+{
+ return (u16)((hdr->lrh[2] & OPA_16B_PKEY_MASK) >> OPA_16B_PKEY_SHIFT);
+}
+
+static inline u8 hfi1_16B_get_rc(struct hfi1_16b_header *hdr)
+{
+ return (u8)((hdr->lrh[1] & OPA_16B_RC_MASK) >> OPA_16B_RC_SHIFT);
+}
+
+static inline u8 hfi1_16B_get_age(struct hfi1_16b_header *hdr)
+{
+ return (u8)((hdr->lrh[3] & OPA_16B_AGE_MASK) >> OPA_16B_AGE_SHIFT);
+}
+
+static inline u16 hfi1_16B_get_len(struct hfi1_16b_header *hdr)
+{
+ return (u16)((hdr->lrh[0] & OPA_16B_LEN_MASK) >> OPA_16B_LEN_SHIFT);
+}
+
+static inline u16 hfi1_16B_get_entropy(struct hfi1_16b_header *hdr)
+{
+ return (u16)(hdr->lrh[3] & OPA_16B_ENTROPY_MASK);
+}
+
+#define OPA_16B_MAKE_QW(low_dw, high_dw) (((u64)(high_dw) << 32) | (low_dw))
+
+/*
+ * BTH
+ */
+#define OPA_16B_BTH_PAD_MASK 7
+static inline u8 hfi1_16B_bth_get_pad(struct ib_other_headers *ohdr)
+{
+ return (u8)((be32_to_cpu(ohdr->bth[0]) >> IB_BTH_PAD_SHIFT) &
+ OPA_16B_BTH_PAD_MASK);
+}
+
struct rvt_sge_state;
/*
@@ -512,7 +614,7 @@ static inline void incr_cntr32(u32 *cntr)
#define MAX_NAME_SIZE 64
struct hfi1_msix_entry {
enum irq_type type;
- struct msix_entry msix;
+ int irq;
void *arg;
char name[MAX_NAME_SIZE];
cpumask_t mask;
@@ -575,6 +677,9 @@ struct hfi1_pportdata {
u8 default_atten;
u8 max_power_class;
+ /* did we read platform config from scratch registers? */
+ bool config_from_scratch;
+
/* GUIDs for this interface, in host order, guids[0] is a port guid */
u64 guids[HFI1_GUIDS_PER_PORT];
@@ -593,6 +698,7 @@ struct hfi1_pportdata {
/* SendDMA related entries */
struct workqueue_struct *hfi1_wq;
+ struct workqueue_struct *link_wq;
/* move out of interrupt context */
struct work_struct link_vc_work;
@@ -607,8 +713,6 @@ struct hfi1_pportdata {
struct mutex hls_lock;
u32 host_link_state;
- u32 lstate; /* logical link state */
-
/* these are the "32 bit" regs */
u32 ibmtu; /* The MTU programmed for this unit */
@@ -619,7 +723,7 @@ struct hfi1_pportdata {
u32 ibmaxlen;
u32 current_egress_rate; /* units [10^6 bits/sec] */
/* LID programmed for this instance */
- u16 lid;
+ u32 lid;
/* list of pkeys programmed; 0 if not set */
u16 pkeys[MAX_PKEY_VALUES];
u16 link_width_supported;
@@ -654,12 +758,12 @@ struct hfi1_pportdata {
u8 link_enabled; /* link enabled? */
u8 linkinit_reason;
u8 local_tx_rate; /* rate given to 8051 firmware */
- u8 last_pstate; /* info only */
u8 qsfp_retry_count;
/* placeholders for IB MAD packet settings */
u8 overrun_threshold;
u8 phy_error_threshold;
+ unsigned int is_link_down_queued;
/* Used to override LED behavior for things like maintenance beaconing*/
/*
@@ -756,6 +860,10 @@ struct hfi1_pportdata {
typedef int (*rhf_rcv_function_ptr)(struct hfi1_packet *packet);
typedef void (*opcode_handler)(struct hfi1_packet *packet);
+typedef void (*hfi1_make_req)(struct rvt_qp *qp,
+ struct hfi1_pkt_state *ps,
+ struct rvt_swqe *wqe);
+
/* return values for the RHF receive functions */
#define RHF_RCV_CONTINUE 0 /* keep going */
@@ -860,12 +968,15 @@ struct hfi1_devdata {
struct device *diag_device;
struct device *ui_device;
- /* mem-mapped pointer to base of chip regs */
- u8 __iomem *kregbase;
- /* end of mem-mapped chip space excluding sendbuf and user regs */
- u8 __iomem *kregend;
- /* physical address of chip for io_remap, etc. */
+ /* first mapping up to RcvArray */
+ u8 __iomem *kregbase1;
resource_size_t physaddr;
+
+ /* second uncached mapping from RcvArray to pio send buffers */
+ u8 __iomem *kregbase2;
+ /* for detecting offset above kregbase2 address */
+ u32 base2_start;
+
/* Per VL data. Enough for all VLs but not all elements are set/used. */
struct per_vl_data vld[PER_VL_SEND_CONTEXTS];
/* send context data */
@@ -953,8 +1064,7 @@ struct hfi1_devdata {
u64 __iomem *egrtidbase;
spinlock_t sendctrl_lock; /* protect changes to SendCtrl */
spinlock_t rcvctrl_lock; /* protect changes to RcvCtrl */
- /* around rcd and (user ctxts) ctxt_cnt use (intr vs free) */
- spinlock_t uctxt_lock; /* rcd and user context changes */
+ spinlock_t uctxt_lock; /* protect rcd changes */
struct mutex dc8051_lock; /* exclusive access to 8051 */
struct workqueue_struct *update_cntr_wq;
struct work_struct update_cntr_work;
@@ -1229,9 +1339,10 @@ static inline bool hfi1_vnic_is_rsm_full(struct hfi1_devdata *dd, int spare)
#define dc8051_ver_patch(a) ((a) & 0x0000ff)
/* f_put_tid types */
-#define PT_EXPECTED 0
-#define PT_EAGER 1
-#define PT_INVALID 2
+#define PT_EXPECTED 0
+#define PT_EAGER 1
+#define PT_INVALID_FLUSH 2
+#define PT_INVALID 3
struct tid_rb_node;
struct mmu_rb_node;
@@ -1276,13 +1387,16 @@ void handle_user_interrupt(struct hfi1_ctxtdata *rcd);
int hfi1_create_rcvhdrq(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd);
int hfi1_setup_eagerbufs(struct hfi1_ctxtdata *rcd);
-int hfi1_create_ctxts(struct hfi1_devdata *dd);
-struct hfi1_ctxtdata *hfi1_create_ctxtdata(struct hfi1_pportdata *ppd, u32 ctxt,
- int numa);
+int hfi1_create_kctxts(struct hfi1_devdata *dd);
+int hfi1_create_ctxtdata(struct hfi1_pportdata *ppd, int numa,
+ struct hfi1_ctxtdata **rcd);
+void hfi1_free_ctxt(struct hfi1_ctxtdata *rcd);
void hfi1_init_pportdata(struct pci_dev *pdev, struct hfi1_pportdata *ppd,
struct hfi1_devdata *dd, u8 hw_pidx, u8 port);
void hfi1_free_ctxtdata(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd);
-
+int hfi1_rcd_put(struct hfi1_ctxtdata *rcd);
+void hfi1_rcd_get(struct hfi1_ctxtdata *rcd);
+struct hfi1_ctxtdata *hfi1_rcd_get_by_index(struct hfi1_devdata *dd, u16 ctxt);
int handle_receive_interrupt(struct hfi1_ctxtdata *rcd, int thread);
int handle_receive_interrupt_nodma_rtail(struct hfi1_ctxtdata *rcd, int thread);
int handle_receive_interrupt_dma_rtail(struct hfi1_ctxtdata *rcd, int thread);
@@ -1292,6 +1406,13 @@ void hfi1_set_vnic_msix_info(struct hfi1_ctxtdata *rcd);
void hfi1_reset_vnic_msix_info(struct hfi1_ctxtdata *rcd);
extern const struct pci_device_id hfi1_pci_tbl[];
+void hfi1_make_ud_req_9B(struct rvt_qp *qp,
+ struct hfi1_pkt_state *ps,
+ struct rvt_swqe *wqe);
+
+void hfi1_make_ud_req_16B(struct rvt_qp *qp,
+ struct hfi1_pkt_state *ps,
+ struct rvt_swqe *wqe);
/* receive packet handler dispositions */
#define RCV_PKT_OK 0x0 /* keep going */
@@ -1306,21 +1427,6 @@ static inline __le32 *get_rhf_addr(struct hfi1_ctxtdata *rcd)
int hfi1_reset_device(int);
-/* return the driver's idea of the logical OPA port state */
-static inline u32 driver_lstate(struct hfi1_pportdata *ppd)
-{
- /*
- * The driver does some processing from the time the logical
- * link state is at INIT to the time the SM can be notified
- * as such. Return IB_PORT_DOWN until the software state
- * is ready.
- */
- if (ppd->lstate == IB_PORT_INIT && !(ppd->host_link_state & HLS_UP))
- return IB_PORT_DOWN;
- else
- return ppd->lstate;
-}
-
void receive_interrupt_work(struct work_struct *work);
/* extract service channel from header and rhf */
@@ -1413,13 +1519,25 @@ static inline u32 egress_cycles(u32 len, u32 rate)
}
void set_link_ipg(struct hfi1_pportdata *ppd);
-void process_becn(struct hfi1_pportdata *ppd, u8 sl, u16 rlid, u32 lqpn,
+void process_becn(struct hfi1_pportdata *ppd, u8 sl, u32 rlid, u32 lqpn,
u32 rqpn, u8 svc_type);
void return_cnp(struct hfi1_ibport *ibp, struct rvt_qp *qp, u32 remote_qpn,
u32 pkey, u32 slid, u32 dlid, u8 sc5,
const struct ib_grh *old_grh);
+void return_cnp_16B(struct hfi1_ibport *ibp, struct rvt_qp *qp,
+ u32 remote_qpn, u32 pkey, u32 slid, u32 dlid,
+ u8 sc5, const struct ib_grh *old_grh);
+typedef void (*hfi1_handle_cnp)(struct hfi1_ibport *ibp, struct rvt_qp *qp,
+ u32 remote_qpn, u32 pkey, u32 slid, u32 dlid,
+ u8 sc5, const struct ib_grh *old_grh);
+
+/* We support only two types - 9B and 16B for now */
+static const hfi1_handle_cnp hfi1_handle_cnp_tbl[2] = {
+ [HFI1_PKT_TYPE_9B] = &return_cnp,
+ [HFI1_PKT_TYPE_16B] = &return_cnp_16B
+};
#define PKEY_CHECK_INVALID -1
-int egress_pkey_check(struct hfi1_pportdata *ppd, __be16 *lrh, __be32 *bth,
+int egress_pkey_check(struct hfi1_pportdata *ppd, u32 slid, u16 pkey,
u8 sc5, int8_t s_pkey_index);
#define PACKET_EGRESS_TIMEOUT 350
@@ -1522,9 +1640,9 @@ static void ingress_pkey_table_fail(struct hfi1_pportdata *ppd, u16 pkey,
* by HW and rcv_pkey_check function should be called instead.
*/
static inline int ingress_pkey_check(struct hfi1_pportdata *ppd, u16 pkey,
- u8 sc5, u8 idx, u16 slid)
+ u8 sc5, u8 idx, u32 slid, bool force)
{
- if (!(ppd->part_enforce & HFI1_PART_ENFORCE_IN))
+ if (!(force) && !(ppd->part_enforce & HFI1_PART_ENFORCE_IN))
return 0;
/* If SC15, pkey[0:14] must be 0x7fff */
@@ -1658,12 +1776,22 @@ static inline bool process_ecn(struct rvt_qp *qp, struct hfi1_packet *pkt,
bool do_cnp)
{
struct ib_other_headers *ohdr = pkt->ohdr;
- u32 bth1;
- bth1 = be32_to_cpu(ohdr->bth[1]);
- if (unlikely(bth1 & (IB_BECN_SMASK | IB_FECN_SMASK))) {
+ u32 bth1;
+ bool becn = false;
+ bool fecn = false;
+
+ if (pkt->etype == RHF_RCV_TYPE_BYPASS) {
+ fecn = hfi1_16B_get_fecn(pkt->hdr);
+ becn = hfi1_16B_get_becn(pkt->hdr);
+ } else {
+ bth1 = be32_to_cpu(ohdr->bth[1]);
+ fecn = bth1 & IB_FECN_SMASK;
+ becn = bth1 & IB_BECN_SMASK;
+ }
+ if (unlikely(fecn || becn)) {
hfi1_process_ecn_slowpath(qp, pkt, do_cnp);
- return !!(bth1 & IB_FECN_SMASK);
+ return fecn;
}
return false;
}
@@ -1829,10 +1957,9 @@ void hfi1_pcie_cleanup(struct pci_dev *pdev);
int hfi1_pcie_ddinit(struct hfi1_devdata *dd, struct pci_dev *pdev);
void hfi1_pcie_ddcleanup(struct hfi1_devdata *);
int pcie_speeds(struct hfi1_devdata *dd);
-void request_msix(struct hfi1_devdata *dd, u32 *nent,
- struct hfi1_msix_entry *entry);
-void hfi1_enable_intx(struct pci_dev *pdev);
-void restore_pci_variables(struct hfi1_devdata *dd);
+int request_msix(struct hfi1_devdata *dd, u32 msireq);
+int restore_pci_variables(struct hfi1_devdata *dd);
+int save_pci_variables(struct hfi1_devdata *dd);
int do_pcie_gen3_transition(struct hfi1_devdata *dd);
int parse_platform_config(struct hfi1_devdata *dd);
int get_platform_config_field(struct hfi1_devdata *dd,
@@ -1860,6 +1987,7 @@ int process_receive_error(struct hfi1_packet *packet);
int kdeth_process_expected(struct hfi1_packet *packet);
int kdeth_process_eager(struct hfi1_packet *packet);
int process_receive_invalid(struct hfi1_packet *packet);
+void seqfile_dump_rcd(struct seq_file *s, struct hfi1_ctxtdata *rcd);
/* global module parameter variables */
extern unsigned int hfi1_max_mtu;
@@ -1991,9 +2119,15 @@ static inline u64 hfi1_pkt_base_sdma_integrity(struct hfi1_devdata *dd)
#define dd_dev_emerg(dd, fmt, ...) \
dev_emerg(&(dd)->pcidev->dev, "%s: " fmt, \
get_unit_name((dd)->unit), ##__VA_ARGS__)
+
#define dd_dev_err(dd, fmt, ...) \
dev_err(&(dd)->pcidev->dev, "%s: " fmt, \
get_unit_name((dd)->unit), ##__VA_ARGS__)
+
+#define dd_dev_err_ratelimited(dd, fmt, ...) \
+ dev_err_ratelimited(&(dd)->pcidev->dev, "%s: " fmt, \
+ get_unit_name((dd)->unit), ##__VA_ARGS__)
+
#define dd_dev_warn(dd, fmt, ...) \
dev_warn(&(dd)->pcidev->dev, "%s: " fmt, \
get_unit_name((dd)->unit), ##__VA_ARGS__)
@@ -2087,52 +2221,220 @@ int hfi1_tempsense_rd(struct hfi1_devdata *dd, struct hfi1_temp *temp);
#define DD_DEV_ENTRY(dd) __string(dev, dev_name(&(dd)->pcidev->dev))
#define DD_DEV_ASSIGN(dd) __assign_str(dev, dev_name(&(dd)->pcidev->dev))
-#define packettype_name(etype) { RHF_RCV_TYPE_##etype, #etype }
-#define show_packettype(etype) \
-__print_symbolic(etype, \
- packettype_name(EXPECTED), \
- packettype_name(EAGER), \
- packettype_name(IB), \
- packettype_name(ERROR), \
- packettype_name(BYPASS))
-
-#define ib_opcode_name(opcode) { IB_OPCODE_##opcode, #opcode }
-#define show_ib_opcode(opcode) \
-__print_symbolic(opcode, \
- ib_opcode_name(RC_SEND_FIRST), \
- ib_opcode_name(RC_SEND_MIDDLE), \
- ib_opcode_name(RC_SEND_LAST), \
- ib_opcode_name(RC_SEND_LAST_WITH_IMMEDIATE), \
- ib_opcode_name(RC_SEND_ONLY), \
- ib_opcode_name(RC_SEND_ONLY_WITH_IMMEDIATE), \
- ib_opcode_name(RC_RDMA_WRITE_FIRST), \
- ib_opcode_name(RC_RDMA_WRITE_MIDDLE), \
- ib_opcode_name(RC_RDMA_WRITE_LAST), \
- ib_opcode_name(RC_RDMA_WRITE_LAST_WITH_IMMEDIATE), \
- ib_opcode_name(RC_RDMA_WRITE_ONLY), \
- ib_opcode_name(RC_RDMA_WRITE_ONLY_WITH_IMMEDIATE), \
- ib_opcode_name(RC_RDMA_READ_REQUEST), \
- ib_opcode_name(RC_RDMA_READ_RESPONSE_FIRST), \
- ib_opcode_name(RC_RDMA_READ_RESPONSE_MIDDLE), \
- ib_opcode_name(RC_RDMA_READ_RESPONSE_LAST), \
- ib_opcode_name(RC_RDMA_READ_RESPONSE_ONLY), \
- ib_opcode_name(RC_ACKNOWLEDGE), \
- ib_opcode_name(RC_ATOMIC_ACKNOWLEDGE), \
- ib_opcode_name(RC_COMPARE_SWAP), \
- ib_opcode_name(RC_FETCH_ADD), \
- ib_opcode_name(UC_SEND_FIRST), \
- ib_opcode_name(UC_SEND_MIDDLE), \
- ib_opcode_name(UC_SEND_LAST), \
- ib_opcode_name(UC_SEND_LAST_WITH_IMMEDIATE), \
- ib_opcode_name(UC_SEND_ONLY), \
- ib_opcode_name(UC_SEND_ONLY_WITH_IMMEDIATE), \
- ib_opcode_name(UC_RDMA_WRITE_FIRST), \
- ib_opcode_name(UC_RDMA_WRITE_MIDDLE), \
- ib_opcode_name(UC_RDMA_WRITE_LAST), \
- ib_opcode_name(UC_RDMA_WRITE_LAST_WITH_IMMEDIATE), \
- ib_opcode_name(UC_RDMA_WRITE_ONLY), \
- ib_opcode_name(UC_RDMA_WRITE_ONLY_WITH_IMMEDIATE), \
- ib_opcode_name(UD_SEND_ONLY), \
- ib_opcode_name(UD_SEND_ONLY_WITH_IMMEDIATE), \
- ib_opcode_name(CNP))
+static inline void hfi1_update_ah_attr(struct ib_device *ibdev,
+ struct rdma_ah_attr *attr)
+{
+ struct hfi1_pportdata *ppd;
+ struct hfi1_ibport *ibp;
+ u32 dlid = rdma_ah_get_dlid(attr);
+
+ /*
+ * Kernel clients may not have setup GRH information
+ * Set that here.
+ */
+ ibp = to_iport(ibdev, rdma_ah_get_port_num(attr));
+ ppd = ppd_from_ibp(ibp);
+ if ((((dlid >= be16_to_cpu(IB_MULTICAST_LID_BASE)) ||
+ (ppd->lid >= be16_to_cpu(IB_MULTICAST_LID_BASE))) &&
+ (dlid != be32_to_cpu(OPA_LID_PERMISSIVE)) &&
+ (dlid != be16_to_cpu(IB_LID_PERMISSIVE)) &&
+ (!(rdma_ah_get_ah_flags(attr) & IB_AH_GRH))) ||
+ (rdma_ah_get_make_grd(attr))) {
+ rdma_ah_set_ah_flags(attr, IB_AH_GRH);
+ rdma_ah_set_interface_id(attr, OPA_MAKE_ID(dlid));
+ rdma_ah_set_subnet_prefix(attr, ibp->rvp.gid_prefix);
+ }
+}
+
+/*
+ * hfi1_check_mcast- Check if the given lid is
+ * in the OPA multicast range.
+ *
+ * The LID might either reside in ah.dlid or might be
+ * in the GRH of the address handle as DGID if extended
+ * addresses are in use.
+ */
+static inline bool hfi1_check_mcast(u32 lid)
+{
+ return ((lid >= opa_get_mcast_base(OPA_MCAST_NR)) &&
+ (lid != be32_to_cpu(OPA_LID_PERMISSIVE)));
+}
+
+#define opa_get_lid(lid, format) \
+ __opa_get_lid(lid, OPA_PORT_PACKET_FORMAT_##format)
+
+/* Convert a lid to a specific lid space */
+static inline u32 __opa_get_lid(u32 lid, u8 format)
+{
+ bool is_mcast = hfi1_check_mcast(lid);
+
+ switch (format) {
+ case OPA_PORT_PACKET_FORMAT_8B:
+ case OPA_PORT_PACKET_FORMAT_10B:
+ if (is_mcast)
+ return (lid - opa_get_mcast_base(OPA_MCAST_NR) +
+ 0xF0000);
+ return lid & 0xFFFFF;
+ case OPA_PORT_PACKET_FORMAT_16B:
+ if (is_mcast)
+ return (lid - opa_get_mcast_base(OPA_MCAST_NR) +
+ 0xF00000);
+ return lid & 0xFFFFFF;
+ case OPA_PORT_PACKET_FORMAT_9B:
+ if (is_mcast)
+ return (lid -
+ opa_get_mcast_base(OPA_MCAST_NR) +
+ be16_to_cpu(IB_MULTICAST_LID_BASE));
+ else
+ return lid & 0xFFFF;
+ default:
+ return lid;
+ }
+}
+
+/* Return true if the given lid is the OPA 16B multicast range */
+static inline bool hfi1_is_16B_mcast(u32 lid)
+{
+ return ((lid >=
+ opa_get_lid(opa_get_mcast_base(OPA_MCAST_NR), 16B)) &&
+ (lid != opa_get_lid(be32_to_cpu(OPA_LID_PERMISSIVE), 16B)));
+}
+
+static inline void hfi1_make_opa_lid(struct rdma_ah_attr *attr)
+{
+ const struct ib_global_route *grh = rdma_ah_read_grh(attr);
+ u32 dlid = rdma_ah_get_dlid(attr);
+
+ /* Modify ah_attr.dlid to be in the 32 bit LID space.
+ * This is how the address will be laid out:
+ * Assuming MCAST_NR to be 4,
+ * 32 bit permissive LID = 0xFFFFFFFF
+ * Multicast LID range = 0xFFFFFFFE to 0xF0000000
+ * Unicast LID range = 0xEFFFFFFF to 1
+ * Invalid LID = 0
+ */
+ if (ib_is_opa_gid(&grh->dgid))
+ dlid = opa_get_lid_from_gid(&grh->dgid);
+ else if ((dlid >= be16_to_cpu(IB_MULTICAST_LID_BASE)) &&
+ (dlid != be16_to_cpu(IB_LID_PERMISSIVE)) &&
+ (dlid != be32_to_cpu(OPA_LID_PERMISSIVE)))
+ dlid = dlid - be16_to_cpu(IB_MULTICAST_LID_BASE) +
+ opa_get_mcast_base(OPA_MCAST_NR);
+ else if (dlid == be16_to_cpu(IB_LID_PERMISSIVE))
+ dlid = be32_to_cpu(OPA_LID_PERMISSIVE);
+
+ rdma_ah_set_dlid(attr, dlid);
+}
+
+static inline u8 hfi1_get_packet_type(u32 lid)
+{
+ /* 9B if lid > 0xF0000000 */
+ if (lid >= opa_get_mcast_base(OPA_MCAST_NR))
+ return HFI1_PKT_TYPE_9B;
+
+ /* 16B if lid > 0xC000 */
+ if (lid >= opa_get_lid(opa_get_mcast_base(OPA_MCAST_NR), 9B))
+ return HFI1_PKT_TYPE_16B;
+
+ return HFI1_PKT_TYPE_9B;
+}
+
+static inline bool hfi1_get_hdr_type(u32 lid, struct rdma_ah_attr *attr)
+{
+ /*
+ * If there was an incoming 16B packet with permissive
+ * LIDs, OPA GIDs would have been programmed when those
+ * packets were received. A 16B packet will have to
+ * be sent in response to that packet. Return a 16B
+ * header type if that's the case.
+ */
+ if (rdma_ah_get_dlid(attr) == be32_to_cpu(OPA_LID_PERMISSIVE))
+ return (ib_is_opa_gid(&rdma_ah_read_grh(attr)->dgid)) ?
+ HFI1_PKT_TYPE_16B : HFI1_PKT_TYPE_9B;
+
+ /*
+ * Return a 16B header type if either the the destination
+ * or source lid is extended.
+ */
+ if (hfi1_get_packet_type(rdma_ah_get_dlid(attr)) == HFI1_PKT_TYPE_16B)
+ return HFI1_PKT_TYPE_16B;
+
+ return hfi1_get_packet_type(lid);
+}
+
+static inline void hfi1_make_ext_grh(struct hfi1_packet *packet,
+ struct ib_grh *grh, u32 slid,
+ u32 dlid)
+{
+ struct hfi1_ibport *ibp = &packet->rcd->ppd->ibport_data;
+ struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
+
+ if (!ibp)
+ return;
+
+ grh->hop_limit = 1;
+ grh->sgid.global.subnet_prefix = ibp->rvp.gid_prefix;
+ if (slid == opa_get_lid(be32_to_cpu(OPA_LID_PERMISSIVE), 16B))
+ grh->sgid.global.interface_id =
+ OPA_MAKE_ID(be32_to_cpu(OPA_LID_PERMISSIVE));
+ else
+ grh->sgid.global.interface_id = OPA_MAKE_ID(slid);
+
+ /*
+ * Upper layers (like mad) may compare the dgid in the
+ * wc that is obtained here with the sgid_index in
+ * the wr. Since sgid_index in wr is always 0 for
+ * extended lids, set the dgid here to the default
+ * IB gid.
+ */
+ grh->dgid.global.subnet_prefix = ibp->rvp.gid_prefix;
+ grh->dgid.global.interface_id =
+ cpu_to_be64(ppd->guids[HFI1_PORT_GUID_INDEX]);
+}
+
+static inline int hfi1_get_16b_padding(u32 hdr_size, u32 payload)
+{
+ return -(hdr_size + payload + (SIZE_OF_CRC << 2) +
+ SIZE_OF_LT) & 0x7;
+}
+
+static inline void hfi1_make_ib_hdr(struct ib_header *hdr,
+ u16 lrh0, u16 len,
+ u16 dlid, u16 slid)
+{
+ hdr->lrh[0] = cpu_to_be16(lrh0);
+ hdr->lrh[1] = cpu_to_be16(dlid);
+ hdr->lrh[2] = cpu_to_be16(len);
+ hdr->lrh[3] = cpu_to_be16(slid);
+}
+
+static inline void hfi1_make_16b_hdr(struct hfi1_16b_header *hdr,
+ u32 slid, u32 dlid,
+ u16 len, u16 pkey,
+ u8 becn, u8 fecn, u8 l4,
+ u8 sc)
+{
+ u32 lrh0 = 0;
+ u32 lrh1 = 0x40000000;
+ u32 lrh2 = 0;
+ u32 lrh3 = 0;
+
+ lrh0 = (lrh0 & ~OPA_16B_BECN_MASK) | (becn << OPA_16B_BECN_SHIFT);
+ lrh0 = (lrh0 & ~OPA_16B_LEN_MASK) | (len << OPA_16B_LEN_SHIFT);
+ lrh0 = (lrh0 & ~OPA_16B_LID_MASK) | (slid & OPA_16B_LID_MASK);
+ lrh1 = (lrh1 & ~OPA_16B_FECN_MASK) | (fecn << OPA_16B_FECN_SHIFT);
+ lrh1 = (lrh1 & ~OPA_16B_SC_MASK) | (sc << OPA_16B_SC_SHIFT);
+ lrh1 = (lrh1 & ~OPA_16B_LID_MASK) | (dlid & OPA_16B_LID_MASK);
+ lrh2 = (lrh2 & ~OPA_16B_SLID_MASK) |
+ ((slid >> OPA_16B_SLID_SHIFT) << OPA_16B_SLID_HIGH_SHIFT);
+ lrh2 = (lrh2 & ~OPA_16B_DLID_MASK) |
+ ((dlid >> OPA_16B_DLID_SHIFT) << OPA_16B_DLID_HIGH_SHIFT);
+ lrh2 = (lrh2 & ~OPA_16B_PKEY_MASK) | (pkey << OPA_16B_PKEY_SHIFT);
+ lrh2 = (lrh2 & ~OPA_16B_L4_MASK) | l4;
+
+ hdr->lrh[0] = lrh0;
+ hdr->lrh[1] = lrh1;
+ hdr->lrh[2] = lrh2;
+ hdr->lrh[3] = lrh3;
+}
#endif /* _HFI1_KERNEL_H */
diff --git a/drivers/infiniband/hw/hfi1/init.c b/drivers/infiniband/hw/hfi1/init.c
index 4a11d4d..fba7700 100644
--- a/drivers/infiniband/hw/hfi1/init.c
+++ b/drivers/infiniband/hw/hfi1/init.c
@@ -67,6 +67,7 @@
#include "aspm.h"
#include "affinity.h"
#include "vnic.h"
+#include "exp_rcv.h"
#undef pr_fmt
#define pr_fmt(fmt) DRIVER_NAME ": " fmt
@@ -125,85 +126,198 @@ static struct idr hfi1_unit_table;
u32 hfi1_cpulist_count;
unsigned long *hfi1_cpulist;
-/*
- * Common code for creating the receive context array.
- */
-int hfi1_create_ctxts(struct hfi1_devdata *dd)
+static int hfi1_create_kctxt(struct hfi1_devdata *dd,
+ struct hfi1_pportdata *ppd)
{
- unsigned i;
+ struct hfi1_ctxtdata *rcd;
int ret;
/* Control context has to be always 0 */
BUILD_BUG_ON(HFI1_CTRL_CTXT != 0);
+ ret = hfi1_create_ctxtdata(ppd, dd->node, &rcd);
+ if (ret < 0) {
+ dd_dev_err(dd, "Kernel receive context allocation failed\n");
+ return ret;
+ }
+
+ /*
+ * Set up the kernel context flags here and now because they use
+ * default values for all receive side memories. User contexts will
+ * be handled as they are created.
+ */
+ rcd->flags = HFI1_CAP_KGET(MULTI_PKT_EGR) |
+ HFI1_CAP_KGET(NODROP_RHQ_FULL) |
+ HFI1_CAP_KGET(NODROP_EGR_FULL) |
+ HFI1_CAP_KGET(DMA_RTAIL);
+
+ /* Control context must use DMA_RTAIL */
+ if (rcd->ctxt == HFI1_CTRL_CTXT)
+ rcd->flags |= HFI1_CAP_DMA_RTAIL;
+ rcd->seq_cnt = 1;
+
+ rcd->sc = sc_alloc(dd, SC_ACK, rcd->rcvhdrqentsize, dd->node);
+ if (!rcd->sc) {
+ dd_dev_err(dd, "Kernel send context allocation failed\n");
+ return -ENOMEM;
+ }
+ hfi1_init_ctxt(rcd->sc);
+
+ return 0;
+}
+
+/*
+ * Create the receive context array and one or more kernel contexts
+ */
+int hfi1_create_kctxts(struct hfi1_devdata *dd)
+{
+ u16 i;
+ int ret;
+
dd->rcd = kzalloc_node(dd->num_rcv_contexts * sizeof(*dd->rcd),
GFP_KERNEL, dd->node);
if (!dd->rcd)
- goto nomem;
+ return -ENOMEM;
- /* create one or more kernel contexts */
for (i = 0; i < dd->first_dyn_alloc_ctxt; ++i) {
- struct hfi1_pportdata *ppd;
- struct hfi1_ctxtdata *rcd;
+ ret = hfi1_create_kctxt(dd, dd->pport);
+ if (ret)
+ goto bail;
+ }
- ppd = dd->pport + (i % dd->num_pports);
+ return 0;
+bail:
+ for (i = 0; dd->rcd && i < dd->first_dyn_alloc_ctxt; ++i)
+ hfi1_free_ctxt(dd->rcd[i]);
- /* dd->rcd[i] gets assigned inside the callee */
- rcd = hfi1_create_ctxtdata(ppd, i, dd->node);
- if (!rcd) {
- dd_dev_err(dd,
- "Unable to allocate kernel receive context, failing\n");
- goto nomem;
- }
- /*
- * Set up the kernel context flags here and now because they
- * use default values for all receive side memories. User
- * contexts will be handled as they are created.
- */
- rcd->flags = HFI1_CAP_KGET(MULTI_PKT_EGR) |
- HFI1_CAP_KGET(NODROP_RHQ_FULL) |
- HFI1_CAP_KGET(NODROP_EGR_FULL) |
- HFI1_CAP_KGET(DMA_RTAIL);
-
- /* Control context must use DMA_RTAIL */
- if (rcd->ctxt == HFI1_CTRL_CTXT)
- rcd->flags |= HFI1_CAP_DMA_RTAIL;
- rcd->seq_cnt = 1;
-
- rcd->sc = sc_alloc(dd, SC_ACK, rcd->rcvhdrqentsize, dd->node);
- if (!rcd->sc) {
- dd_dev_err(dd,
- "Unable to allocate kernel send context, failing\n");
- goto nomem;
- }
+ /* All the contexts should be freed, free the array */
+ kfree(dd->rcd);
+ dd->rcd = NULL;
+ return ret;
+}
+
+/*
+ * Helper routines for the receive context reference count (rcd and uctxt).
+ */
+static void hfi1_rcd_init(struct hfi1_ctxtdata *rcd)
+{
+ kref_init(&rcd->kref);
+}
- hfi1_init_ctxt(rcd->sc);
+/**
+ * hfi1_rcd_free - When reference is zero clean up.
+ * @kref: pointer to an initialized rcd data structure
+ *
+ */
+static void hfi1_rcd_free(struct kref *kref)
+{
+ unsigned long flags;
+ struct hfi1_ctxtdata *rcd =
+ container_of(kref, struct hfi1_ctxtdata, kref);
+
+ hfi1_free_ctxtdata(rcd->dd, rcd);
+
+ spin_lock_irqsave(&rcd->dd->uctxt_lock, flags);
+ rcd->dd->rcd[rcd->ctxt] = NULL;
+ spin_unlock_irqrestore(&rcd->dd->uctxt_lock, flags);
+
+ kfree(rcd);
+}
+
+/**
+ * hfi1_rcd_put - decrement reference for rcd
+ * @rcd: pointer to an initialized rcd data structure
+ *
+ * Use this to put a reference after the init.
+ */
+int hfi1_rcd_put(struct hfi1_ctxtdata *rcd)
+{
+ if (rcd)
+ return kref_put(&rcd->kref, hfi1_rcd_free);
+
+ return 0;
+}
+
+/**
+ * hfi1_rcd_get - increment reference for rcd
+ * @rcd: pointer to an initialized rcd data structure
+ *
+ * Use this to get a reference after the init.
+ */
+void hfi1_rcd_get(struct hfi1_ctxtdata *rcd)
+{
+ kref_get(&rcd->kref);
+}
+
+/**
+ * allocate_rcd_index - allocate an rcd index from the rcd array
+ * @dd: pointer to a valid devdata structure
+ * @rcd: rcd data structure to assign
+ * @index: pointer to index that is allocated
+ *
+ * Find an empty index in the rcd array, and assign the given rcd to it.
+ * If the array is full, we are EBUSY.
+ *
+ */
+static int allocate_rcd_index(struct hfi1_devdata *dd,
+ struct hfi1_ctxtdata *rcd, u16 *index)
+{
+ unsigned long flags;
+ u16 ctxt;
+
+ spin_lock_irqsave(&dd->uctxt_lock, flags);
+ for (ctxt = 0; ctxt < dd->num_rcv_contexts; ctxt++)
+ if (!dd->rcd[ctxt])
+ break;
+
+ if (ctxt < dd->num_rcv_contexts) {
+ rcd->ctxt = ctxt;
+ dd->rcd[ctxt] = rcd;
+ hfi1_rcd_init(rcd);
}
+ spin_unlock_irqrestore(&dd->uctxt_lock, flags);
- /*
- * Initialize aspm, to be done after gen3 transition and setting up
- * contexts and before enabling interrupts
- */
- aspm_init(dd);
+ if (ctxt >= dd->num_rcv_contexts)
+ return -EBUSY;
+
+ *index = ctxt;
return 0;
-nomem:
- ret = -ENOMEM;
+}
- if (dd->rcd) {
- for (i = 0; i < dd->num_rcv_contexts; ++i)
- hfi1_free_ctxtdata(dd, dd->rcd[i]);
+/**
+ * hfi1_rcd_get_by_index
+ * @dd: pointer to a valid devdata structure
+ * @ctxt: the index of an possilbe rcd
+ *
+ * We need to protect access to the rcd array. If access is needed to
+ * one or more index, get the protecting spinlock and then increment the
+ * kref.
+ *
+ * The caller is responsible for making the _put().
+ *
+ */
+struct hfi1_ctxtdata *hfi1_rcd_get_by_index(struct hfi1_devdata *dd, u16 ctxt)
+{
+ unsigned long flags;
+ struct hfi1_ctxtdata *rcd = NULL;
+
+ spin_lock_irqsave(&dd->uctxt_lock, flags);
+ if (dd->rcd[ctxt]) {
+ rcd = dd->rcd[ctxt];
+ hfi1_rcd_get(rcd);
}
- kfree(dd->rcd);
- dd->rcd = NULL;
- return ret;
+ spin_unlock_irqrestore(&dd->uctxt_lock, flags);
+
+ return rcd;
}
/*
- * Common code for user and kernel context setup.
+ * Common code for user and kernel context create and setup.
+ * NOTE: the initial kref is done here (hf1_rcd_init()).
*/
-struct hfi1_ctxtdata *hfi1_create_ctxtdata(struct hfi1_pportdata *ppd, u32 ctxt,
- int numa)
+int hfi1_create_ctxtdata(struct hfi1_pportdata *ppd, int numa,
+ struct hfi1_ctxtdata **context)
{
struct hfi1_devdata *dd = ppd->dd;
struct hfi1_ctxtdata *rcd;
@@ -217,20 +331,30 @@ struct hfi1_ctxtdata *hfi1_create_ctxtdata(struct hfi1_pportdata *ppd, u32 ctxt,
rcd = kzalloc_node(sizeof(*rcd), GFP_KERNEL, numa);
if (rcd) {
u32 rcvtids, max_entries;
-
- hfi1_cdbg(PROC, "setting up context %u\n", ctxt);
+ u16 ctxt;
+ int ret;
+
+ ret = allocate_rcd_index(dd, rcd, &ctxt);
+ if (ret) {
+ *context = NULL;
+ kfree(rcd);
+ return ret;
+ }
INIT_LIST_HEAD(&rcd->qp_wait_list);
+ hfi1_exp_tid_group_init(&rcd->tid_group_list);
+ hfi1_exp_tid_group_init(&rcd->tid_used_list);
+ hfi1_exp_tid_group_init(&rcd->tid_full_list);
rcd->ppd = ppd;
rcd->dd = dd;
__set_bit(0, rcd->in_use_ctxts);
- rcd->ctxt = ctxt;
- dd->rcd[ctxt] = rcd;
rcd->numa_id = numa;
rcd->rcv_array_groups = dd->rcv_entries.ngroups;
mutex_init(&rcd->exp_lock);
+ hfi1_cdbg(PROC, "setting up context %u\n", rcd->ctxt);
+
/*
* Calculate the context's RcvArray entry starting point.
* We do this here because we have to take into account all
@@ -328,14 +452,30 @@ struct hfi1_ctxtdata *hfi1_create_ctxtdata(struct hfi1_pportdata *ppd, u32 ctxt,
if (!rcd->opstats)
goto bail;
}
+
+ *context = rcd;
+ return 0;
}
- return rcd;
+
bail:
- dd->rcd[ctxt] = NULL;
- kfree(rcd->egrbufs.rcvtids);
- kfree(rcd->egrbufs.buffers);
- kfree(rcd);
- return NULL;
+ *context = NULL;
+ hfi1_free_ctxt(rcd);
+ return -ENOMEM;
+}
+
+/**
+ * hfi1_free_ctxt
+ * @rcd: pointer to an initialized rcd data structure
+ *
+ * This wrapper is the free function that matches hfi1_create_ctxtdata().
+ * When a context is done being used (kernel or user), this function is called
+ * for the "final" put to match the kref init from hf1i_create_ctxtdata().
+ * Other users of the context do a get/put sequence to make sure that the
+ * structure isn't removed while in use.
+ */
+void hfi1_free_ctxt(struct hfi1_ctxtdata *rcd)
+{
+ hfi1_rcd_put(rcd);
}
/*
@@ -483,7 +623,6 @@ void hfi1_init_pportdata(struct pci_dev *pdev, struct hfi1_pportdata *ppd,
ppd->pkeys[default_pkey_idx] = DEFAULT_P_KEY;
ppd->part_enforce |= HFI1_PART_ENFORCE_IN;
- ppd->part_enforce |= HFI1_PART_ENFORCE_OUT;
if (loopback) {
hfi1_early_err(&pdev->dev,
@@ -559,16 +698,19 @@ static int loadtime_init(struct hfi1_devdata *dd)
static int init_after_reset(struct hfi1_devdata *dd)
{
int i;
-
+ struct hfi1_ctxtdata *rcd;
/*
* Ensure chip does no sends or receives, tail updates, or
* pioavail updates while we re-initialize. This is mostly
* for the driver data structures, not chip registers.
*/
- for (i = 0; i < dd->num_rcv_contexts; i++)
+ for (i = 0; i < dd->num_rcv_contexts; i++) {
+ rcd = hfi1_rcd_get_by_index(dd, i);
hfi1_rcvctrl(dd, HFI1_RCVCTRL_CTXT_DIS |
- HFI1_RCVCTRL_INTRAVAIL_DIS |
- HFI1_RCVCTRL_TAILUPD_DIS, i);
+ HFI1_RCVCTRL_INTRAVAIL_DIS |
+ HFI1_RCVCTRL_TAILUPD_DIS, rcd);
+ hfi1_rcd_put(rcd);
+ }
pio_send_control(dd, PSC_GLOBAL_DISABLE);
for (i = 0; i < dd->num_send_contexts; i++)
sc_disable(dd->send_contexts[i].sc);
@@ -578,8 +720,9 @@ static int init_after_reset(struct hfi1_devdata *dd)
static void enable_chip(struct hfi1_devdata *dd)
{
+ struct hfi1_ctxtdata *rcd;
u32 rcvmask;
- u32 i;
+ u16 i;
/* enable PIO send */
pio_send_control(dd, PSC_GLOBAL_ENABLE);
@@ -589,17 +732,21 @@ static void enable_chip(struct hfi1_devdata *dd)
* Other ctxts done as user opens and initializes them.
*/
for (i = 0; i < dd->first_dyn_alloc_ctxt; ++i) {
+ rcd = hfi1_rcd_get_by_index(dd, i);
+ if (!rcd)
+ continue;
rcvmask = HFI1_RCVCTRL_CTXT_ENB | HFI1_RCVCTRL_INTRAVAIL_ENB;
- rcvmask |= HFI1_CAP_KGET_MASK(dd->rcd[i]->flags, DMA_RTAIL) ?
+ rcvmask |= HFI1_CAP_KGET_MASK(rcd->flags, DMA_RTAIL) ?
HFI1_RCVCTRL_TAILUPD_ENB : HFI1_RCVCTRL_TAILUPD_DIS;
- if (!HFI1_CAP_KGET_MASK(dd->rcd[i]->flags, MULTI_PKT_EGR))
+ if (!HFI1_CAP_KGET_MASK(rcd->flags, MULTI_PKT_EGR))
rcvmask |= HFI1_RCVCTRL_ONE_PKT_EGR_ENB;
- if (HFI1_CAP_KGET_MASK(dd->rcd[i]->flags, NODROP_RHQ_FULL))
+ if (HFI1_CAP_KGET_MASK(rcd->flags, NODROP_RHQ_FULL))
rcvmask |= HFI1_RCVCTRL_NO_RHQ_DROP_ENB;
- if (HFI1_CAP_KGET_MASK(dd->rcd[i]->flags, NODROP_EGR_FULL))
+ if (HFI1_CAP_KGET_MASK(rcd->flags, NODROP_EGR_FULL))
rcvmask |= HFI1_RCVCTRL_NO_EGR_DROP_ENB;
- hfi1_rcvctrl(dd, rcvmask, i);
- sc_enable(dd->rcd[i]->sc);
+ hfi1_rcvctrl(dd, rcvmask, rcd);
+ sc_enable(rcd->sc);
+ hfi1_rcd_put(rcd);
}
}
@@ -624,6 +771,20 @@ static int create_workqueues(struct hfi1_devdata *dd)
if (!ppd->hfi1_wq)
goto wq_error;
}
+ if (!ppd->link_wq) {
+ /*
+ * Make the link workqueue single-threaded to enforce
+ * serialization.
+ */
+ ppd->link_wq =
+ alloc_workqueue(
+ "hfi_link_%d_%d",
+ WQ_SYSFS | WQ_MEM_RECLAIM | WQ_UNBOUND,
+ 1, /* max_active */
+ dd->unit, pidx);
+ if (!ppd->link_wq)
+ goto wq_error;
+ }
}
return 0;
wq_error:
@@ -634,6 +795,10 @@ wq_error:
destroy_workqueue(ppd->hfi1_wq);
ppd->hfi1_wq = NULL;
}
+ if (ppd->link_wq) {
+ destroy_workqueue(ppd->link_wq);
+ ppd->link_wq = NULL;
+ }
}
return -ENOMEM;
}
@@ -656,7 +821,8 @@ wq_error:
int hfi1_init(struct hfi1_devdata *dd, int reinit)
{
int ret = 0, pidx, lastfail = 0;
- unsigned i, len;
+ unsigned long len;
+ u16 i;
struct hfi1_ctxtdata *rcd;
struct hfi1_pportdata *ppd;
@@ -725,7 +891,7 @@ int hfi1_init(struct hfi1_devdata *dd, int reinit)
* existing, and re-allocate.
* Need to re-create rest of ctxt 0 ctxtdata as well.
*/
- rcd = dd->rcd[i];
+ rcd = hfi1_rcd_get_by_index(dd, i);
if (!rcd)
continue;
@@ -739,6 +905,7 @@ int hfi1_init(struct hfi1_devdata *dd, int reinit)
"failed to allocate kernel ctxt's rcvhdrq and/or egr bufs\n");
ret = lastfail;
}
+ hfi1_rcd_put(rcd);
}
/* Allocate enough memory for user event notification. */
@@ -858,6 +1025,7 @@ static void stop_timers(struct hfi1_devdata *dd)
static void shutdown_device(struct hfi1_devdata *dd)
{
struct hfi1_pportdata *ppd;
+ struct hfi1_ctxtdata *rcd;
unsigned pidx;
int i;
@@ -876,12 +1044,15 @@ static void shutdown_device(struct hfi1_devdata *dd)
for (pidx = 0; pidx < dd->num_pports; ++pidx) {
ppd = dd->pport + pidx;
- for (i = 0; i < dd->num_rcv_contexts; i++)
+ for (i = 0; i < dd->num_rcv_contexts; i++) {
+ rcd = hfi1_rcd_get_by_index(dd, i);
hfi1_rcvctrl(dd, HFI1_RCVCTRL_TAILUPD_DIS |
- HFI1_RCVCTRL_CTXT_DIS |
- HFI1_RCVCTRL_INTRAVAIL_DIS |
- HFI1_RCVCTRL_PKEY_DIS |
- HFI1_RCVCTRL_ONE_PKT_EGR_DIS, i);
+ HFI1_RCVCTRL_CTXT_DIS |
+ HFI1_RCVCTRL_INTRAVAIL_DIS |
+ HFI1_RCVCTRL_PKEY_DIS |
+ HFI1_RCVCTRL_ONE_PKT_EGR_DIS, rcd);
+ hfi1_rcd_put(rcd);
+ }
/*
* Gracefully stop all sends allowing any in progress to
* trickle out first.
@@ -917,6 +1088,10 @@ static void shutdown_device(struct hfi1_devdata *dd)
destroy_workqueue(ppd->hfi1_wq);
ppd->hfi1_wq = NULL;
}
+ if (ppd->link_wq) {
+ destroy_workqueue(ppd->link_wq);
+ ppd->link_wq = NULL;
+ }
}
sdma_exit(dd);
}
@@ -927,14 +1102,11 @@ static void shutdown_device(struct hfi1_devdata *dd)
* @rcd: the ctxtdata structure
*
* free up any allocated data for a context
- * This should not touch anything that would affect a simultaneous
- * re-allocation of context data, because it is called after hfi1_mutex
- * is released (and can be called from reinit as well).
* It should never change any chip state, or global driver state.
*/
void hfi1_free_ctxtdata(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd)
{
- unsigned e;
+ u32 e;
if (!rcd)
return;
@@ -953,6 +1125,7 @@ void hfi1_free_ctxtdata(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd)
/* all the RcvArray entries should have been cleared by now */
kfree(rcd->egrbufs.rcvtids);
+ rcd->egrbufs.rcvtids = NULL;
for (e = 0; e < rcd->egrbufs.alloced; e++) {
if (rcd->egrbufs.buffers[e].dma)
@@ -962,13 +1135,21 @@ void hfi1_free_ctxtdata(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd)
rcd->egrbufs.buffers[e].dma);
}
kfree(rcd->egrbufs.buffers);
+ rcd->egrbufs.alloced = 0;
+ rcd->egrbufs.buffers = NULL;
sc_free(rcd->sc);
+ rcd->sc = NULL;
+
vfree(rcd->subctxt_uregbase);
vfree(rcd->subctxt_rcvegrbuf);
vfree(rcd->subctxt_rcvhdr_base);
kfree(rcd->opstats);
- kfree(rcd);
+
+ rcd->subctxt_uregbase = NULL;
+ rcd->subctxt_rcvegrbuf = NULL;
+ rcd->subctxt_rcvhdr_base = NULL;
+ rcd->opstats = NULL;
}
/*
@@ -1311,8 +1492,6 @@ static void cleanup_device_data(struct hfi1_devdata *dd)
{
int ctxt;
int pidx;
- struct hfi1_ctxtdata **tmp;
- unsigned long flags;
/* users can't do anything more with chip */
for (pidx = 0; pidx < dd->num_pports; ++pidx) {
@@ -1337,18 +1516,6 @@ static void cleanup_device_data(struct hfi1_devdata *dd)
free_credit_return(dd);
- /*
- * Free any resources still in use (usually just kernel contexts)
- * at unload; we do for ctxtcnt, because that's what we allocate.
- * We acquire lock to be really paranoid that rcd isn't being
- * accessed from some interrupt-related code (that should not happen,
- * but best to be sure).
- */
- spin_lock_irqsave(&dd->uctxt_lock, flags);
- tmp = dd->rcd;
- dd->rcd = NULL;
- spin_unlock_irqrestore(&dd->uctxt_lock, flags);
-
if (dd->rcvhdrtail_dummy_kvaddr) {
dma_free_coherent(&dd->pcidev->dev, sizeof(u64),
(void *)dd->rcvhdrtail_dummy_kvaddr,
@@ -1356,16 +1523,22 @@ static void cleanup_device_data(struct hfi1_devdata *dd)
dd->rcvhdrtail_dummy_kvaddr = NULL;
}
- for (ctxt = 0; tmp && ctxt < dd->num_rcv_contexts; ctxt++) {
- struct hfi1_ctxtdata *rcd = tmp[ctxt];
+ /*
+ * Free any resources still in use (usually just kernel contexts)
+ * at unload; we do for ctxtcnt, because that's what we allocate.
+ */
+ for (ctxt = 0; dd->rcd && ctxt < dd->num_rcv_contexts; ctxt++) {
+ struct hfi1_ctxtdata *rcd = dd->rcd[ctxt];
- tmp[ctxt] = NULL; /* debugging paranoia */
if (rcd) {
hfi1_clear_tids(rcd);
- hfi1_free_ctxtdata(dd, rcd);
+ hfi1_free_ctxt(rcd);
}
}
- kfree(tmp);
+
+ kfree(dd->rcd);
+ dd->rcd = NULL;
+
free_pio_map(dd);
/* must follow rcv context free - need to remove rcv's hooks */
for (ctxt = 0; ctxt < dd->num_send_contexts; ctxt++)
@@ -1532,6 +1705,10 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
destroy_workqueue(ppd->hfi1_wq);
ppd->hfi1_wq = NULL;
}
+ if (ppd->link_wq) {
+ destroy_workqueue(ppd->link_wq);
+ ppd->link_wq = NULL;
+ }
}
if (!j)
hfi1_device_remove(dd);
diff --git a/drivers/infiniband/hw/hfi1/intr.c b/drivers/infiniband/hw/hfi1/intr.c
index 04a5082d..96845df 100644
--- a/drivers/infiniband/hw/hfi1/intr.c
+++ b/drivers/infiniband/hw/hfi1/intr.c
@@ -164,6 +164,7 @@ void handle_linkup_change(struct hfi1_devdata *dd, u32 linkup)
ppd->linkup = 0;
/* clear HW details of the previous connection */
+ ppd->actual_vls_operational = 0;
reset_link_credits(dd);
/* freeze after a link down to guarantee a clean egress */
@@ -196,7 +197,7 @@ void handle_user_interrupt(struct hfi1_ctxtdata *rcd)
if (test_and_clear_bit(HFI1_CTXT_WAITING_RCV, &rcd->event_flags)) {
wake_up_interruptible(&rcd->wait);
- hfi1_rcvctrl(dd, HFI1_RCVCTRL_INTRAVAIL_DIS, rcd->ctxt);
+ hfi1_rcvctrl(dd, HFI1_RCVCTRL_INTRAVAIL_DIS, rcd);
} else if (test_and_clear_bit(HFI1_CTXT_WAITING_URG,
&rcd->event_flags)) {
rcd->urgent++;
diff --git a/drivers/infiniband/hw/hfi1/iowait.h b/drivers/infiniband/hw/hfi1/iowait.h
index d9740dd..591697d 100644
--- a/drivers/infiniband/hw/hfi1/iowait.h
+++ b/drivers/infiniband/hw/hfi1/iowait.h
@@ -106,7 +106,9 @@ struct iowait {
struct sdma_engine *sde,
struct iowait *wait,
struct sdma_txreq *tx,
- unsigned seq);
+ uint seq,
+ bool pkts_sent
+ );
void (*wakeup)(struct iowait *wait, int reason);
void (*sdma_drained)(struct iowait *wait);
seqlock_t *lock;
@@ -118,6 +120,7 @@ struct iowait {
u32 count;
u32 tx_limit;
u32 tx_count;
+ u8 starved_cnt;
};
#define SDMA_AVAIL_REASON 0
@@ -143,7 +146,8 @@ static inline void iowait_init(
struct sdma_engine *sde,
struct iowait *wait,
struct sdma_txreq *tx,
- unsigned seq),
+ uint seq,
+ bool pkts_sent),
void (*wakeup)(struct iowait *wait, int reason),
void (*sdma_drained)(struct iowait *wait))
{
@@ -305,4 +309,66 @@ static inline struct sdma_txreq *iowait_get_txhead(struct iowait *wait)
return tx;
}
+/**
+ * iowait_queue - Put the iowait on a wait queue
+ * @pkts_sent: have some packets been sent before queuing?
+ * @w: the iowait struct
+ * @wait_head: the wait queue
+ *
+ * This function is called to insert an iowait struct into a
+ * wait queue after a resource (eg, sdma decriptor or pio
+ * buffer) is run out.
+ */
+static inline void iowait_queue(bool pkts_sent, struct iowait *w,
+ struct list_head *wait_head)
+{
+ /*
+ * To play fair, insert the iowait at the tail of the wait queue if it
+ * has already sent some packets; Otherwise, put it at the head.
+ */
+ if (pkts_sent) {
+ list_add_tail(&w->list, wait_head);
+ w->starved_cnt = 0;
+ } else {
+ list_add(&w->list, wait_head);
+ w->starved_cnt++;
+ }
+}
+
+/**
+ * iowait_starve_clear - clear the wait queue's starve count
+ * @pkts_sent: have some packets been sent?
+ * @w: the iowait struct
+ *
+ * This function is called to clear the starve count. If no
+ * packets have been sent, the starve count will not be cleared.
+ */
+static inline void iowait_starve_clear(bool pkts_sent, struct iowait *w)
+{
+ if (pkts_sent)
+ w->starved_cnt = 0;
+}
+
+/**
+ * iowait_starve_find_max - Find the maximum of the starve count
+ * @w: the iowait struct
+ * @max: a variable containing the max starve count
+ * @idx: the index of the current iowait in an array
+ * @max_idx: a variable containing the array index for the
+ * iowait entry that has the max starve count
+ *
+ * This function is called to compare the starve count of a
+ * given iowait with the given max starve count. The max starve
+ * count and the index will be updated if the iowait's start
+ * count is larger.
+ */
+static inline void iowait_starve_find_max(struct iowait *w, u8 *max,
+ uint idx, uint *max_idx)
+{
+ if (w->starved_cnt > *max) {
+ *max = w->starved_cnt;
+ *max_idx = idx;
+ }
+}
+
#endif
diff --git a/drivers/infiniband/hw/hfi1/mad.c b/drivers/infiniband/hw/hfi1/mad.c
index 5977673..f4c0ffc 100644
--- a/drivers/infiniband/hw/hfi1/mad.c
+++ b/drivers/infiniband/hw/hfi1/mad.c
@@ -46,6 +46,7 @@
*/
#include <linux/net.h>
+#include <rdma/opa_addr.h>
#define OPA_NUM_PKEY_BLOCKS_PER_SMP (OPA_SMP_DR_DATA_SIZE \
/ (OPA_PARTITION_TABLE_BLK_SIZE * sizeof(u16)))
@@ -59,6 +60,24 @@
#define OPA_LINK_WIDTH_RESET_OLD 0x0fff
#define OPA_LINK_WIDTH_RESET 0xffff
+struct trap_node {
+ struct list_head list;
+ struct opa_mad_notice_attr data;
+ __be64 tid;
+ int len;
+ u32 retry;
+ u8 in_use;
+ u8 repress;
+};
+
+static int smp_length_check(u32 data_size, u32 request_len)
+{
+ if (unlikely(request_len < data_size))
+ return -EINVAL;
+
+ return 0;
+}
+
static int reply(struct ib_mad_hdr *smp)
{
/*
@@ -89,28 +108,222 @@ void hfi1_event_pkey_change(struct hfi1_devdata *dd, u8 port)
ib_dispatch_event(&event);
}
-static void send_trap(struct hfi1_ibport *ibp, void *data, unsigned len)
+/*
+ * If the port is down, clean up all pending traps. We need to be careful
+ * with the given trap, because it may be queued.
+ */
+static void cleanup_traps(struct hfi1_ibport *ibp, struct trap_node *trap)
+{
+ struct trap_node *node, *q;
+ unsigned long flags;
+ struct list_head trap_list;
+ int i;
+
+ for (i = 0; i < RVT_MAX_TRAP_LISTS; i++) {
+ spin_lock_irqsave(&ibp->rvp.lock, flags);
+ list_replace_init(&ibp->rvp.trap_lists[i].list, &trap_list);
+ ibp->rvp.trap_lists[i].list_len = 0;
+ spin_unlock_irqrestore(&ibp->rvp.lock, flags);
+
+ /*
+ * Remove all items from the list, freeing all the non-given
+ * traps.
+ */
+ list_for_each_entry_safe(node, q, &trap_list, list) {
+ list_del(&node->list);
+ if (node != trap)
+ kfree(node);
+ }
+ }
+
+ /*
+ * If this wasn't on one of the lists it would not be freed. If it
+ * was on the list, it is now safe to free.
+ */
+ kfree(trap);
+}
+
+static struct trap_node *check_and_add_trap(struct hfi1_ibport *ibp,
+ struct trap_node *trap)
+{
+ struct trap_node *node;
+ struct trap_list *trap_list;
+ unsigned long flags;
+ unsigned long timeout;
+ int found = 0;
+ unsigned int queue_id;
+ static int trap_count;
+
+ queue_id = trap->data.generic_type & 0x0F;
+ if (queue_id >= RVT_MAX_TRAP_LISTS) {
+ trap_count++;
+ pr_err_ratelimited("hfi1: Invalid trap 0x%0x dropped. Total dropped: %d\n",
+ trap->data.generic_type, trap_count);
+ kfree(trap);
+ return NULL;
+ }
+
+ /*
+ * Since the retry (handle timeout) does not remove a trap request
+ * from the list, all we have to do is compare the node.
+ */
+ spin_lock_irqsave(&ibp->rvp.lock, flags);
+ trap_list = &ibp->rvp.trap_lists[queue_id];
+
+ list_for_each_entry(node, &trap_list->list, list) {
+ if (node == trap) {
+ node->retry++;
+ found = 1;
+ break;
+ }
+ }
+
+ /* If it is not on the list, add it, limited to RVT-MAX_TRAP_LEN. */
+ if (!found) {
+ if (trap_list->list_len < RVT_MAX_TRAP_LEN) {
+ trap_list->list_len++;
+ list_add_tail(&trap->list, &trap_list->list);
+ } else {
+ pr_warn_ratelimited("hfi1: Maximum trap limit reached for 0x%0x traps\n",
+ trap->data.generic_type);
+ kfree(trap);
+ }
+ }
+
+ /*
+ * Next check to see if there is a timer pending. If not, set it up
+ * and get the first trap from the list.
+ */
+ node = NULL;
+ if (!timer_pending(&ibp->rvp.trap_timer)) {
+ /*
+ * o14-2
+ * If the time out is set we have to wait until it expires
+ * before the trap can be sent.
+ * This should be > RVT_TRAP_TIMEOUT
+ */
+ timeout = (RVT_TRAP_TIMEOUT *
+ (1UL << ibp->rvp.subnet_timeout)) / 1000;
+ mod_timer(&ibp->rvp.trap_timer,
+ jiffies + usecs_to_jiffies(timeout));
+ node = list_first_entry(&trap_list->list, struct trap_node,
+ list);
+ node->in_use = 1;
+ }
+ spin_unlock_irqrestore(&ibp->rvp.lock, flags);
+
+ return node;
+}
+
+static void subn_handle_opa_trap_repress(struct hfi1_ibport *ibp,
+ struct opa_smp *smp)
+{
+ struct trap_list *trap_list;
+ struct trap_node *trap;
+ unsigned long flags;
+ int i;
+
+ if (smp->attr_id != IB_SMP_ATTR_NOTICE)
+ return;
+
+ spin_lock_irqsave(&ibp->rvp.lock, flags);
+ for (i = 0; i < RVT_MAX_TRAP_LISTS; i++) {
+ trap_list = &ibp->rvp.trap_lists[i];
+ trap = list_first_entry_or_null(&trap_list->list,
+ struct trap_node, list);
+ if (trap && trap->tid == smp->tid) {
+ if (trap->in_use) {
+ trap->repress = 1;
+ } else {
+ trap_list->list_len--;
+ list_del(&trap->list);
+ kfree(trap);
+ }
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&ibp->rvp.lock, flags);
+}
+
+static void hfi1_update_sm_ah_attr(struct hfi1_ibport *ibp,
+ struct rdma_ah_attr *attr, u32 dlid)
+{
+ rdma_ah_set_dlid(attr, dlid);
+ rdma_ah_set_port_num(attr, ppd_from_ibp(ibp)->port);
+ if (dlid >= be16_to_cpu(IB_MULTICAST_LID_BASE)) {
+ struct ib_global_route *grh = rdma_ah_retrieve_grh(attr);
+
+ rdma_ah_set_ah_flags(attr, IB_AH_GRH);
+ grh->sgid_index = 0;
+ grh->hop_limit = 1;
+ grh->dgid.global.subnet_prefix =
+ ibp->rvp.gid_prefix;
+ grh->dgid.global.interface_id = OPA_MAKE_ID(dlid);
+ }
+}
+
+static int hfi1_modify_qp0_ah(struct hfi1_ibport *ibp,
+ struct rvt_ah *ah, u32 dlid)
+{
+ struct rdma_ah_attr attr;
+ struct rvt_qp *qp0;
+ int ret = -EINVAL;
+
+ memset(&attr, 0, sizeof(attr));
+ attr.type = ah->ibah.type;
+ hfi1_update_sm_ah_attr(ibp, &attr, dlid);
+ rcu_read_lock();
+ qp0 = rcu_dereference(ibp->rvp.qp[0]);
+ if (qp0)
+ ret = rdma_modify_ah(&ah->ibah, &attr);
+ rcu_read_unlock();
+ return ret;
+}
+
+static struct ib_ah *hfi1_create_qp0_ah(struct hfi1_ibport *ibp, u32 dlid)
+{
+ struct rdma_ah_attr attr;
+ struct ib_ah *ah = ERR_PTR(-EINVAL);
+ struct rvt_qp *qp0;
+ struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
+ struct hfi1_devdata *dd = dd_from_ppd(ppd);
+ u8 port_num = ppd->port;
+
+ memset(&attr, 0, sizeof(attr));
+ attr.type = rdma_ah_find_type(&dd->verbs_dev.rdi.ibdev, port_num);
+ hfi1_update_sm_ah_attr(ibp, &attr, dlid);
+ rcu_read_lock();
+ qp0 = rcu_dereference(ibp->rvp.qp[0]);
+ if (qp0)
+ ah = rdma_create_ah(qp0->ibqp.pd, &attr);
+ rcu_read_unlock();
+ return ah;
+}
+
+static void send_trap(struct hfi1_ibport *ibp, struct trap_node *trap)
{
struct ib_mad_send_buf *send_buf;
struct ib_mad_agent *agent;
struct opa_smp *smp;
- int ret;
unsigned long flags;
- unsigned long timeout;
int pkey_idx;
u32 qpn = ppd_from_ibp(ibp)->sm_trap_qp;
agent = ibp->rvp.send_agent;
- if (!agent)
+ if (!agent) {
+ cleanup_traps(ibp, trap);
return;
+ }
/* o14-3.2.1 */
- if (ppd_from_ibp(ibp)->lstate != IB_PORT_ACTIVE)
+ if (driver_lstate(ppd_from_ibp(ibp)) != IB_PORT_ACTIVE) {
+ cleanup_traps(ibp, trap);
return;
+ }
- /* o14-2 */
- if (ibp->rvp.trap_timeout && time_before(jiffies,
- ibp->rvp.trap_timeout))
+ /* Add the trap to the list if necessary and see if we can send it */
+ trap = check_and_add_trap(ibp, trap);
+ if (!trap)
return;
pkey_idx = hfi1_lookup_pkey_idx(ibp, LIM_MGMT_P_KEY);
@@ -131,11 +344,21 @@ static void send_trap(struct hfi1_ibport *ibp, void *data, unsigned len)
smp->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
smp->class_version = OPA_SM_CLASS_VERSION;
smp->method = IB_MGMT_METHOD_TRAP;
- ibp->rvp.tid++;
- smp->tid = cpu_to_be64(ibp->rvp.tid);
+
+ /* Only update the transaction ID for new traps (o13-5). */
+ if (trap->tid == 0) {
+ ibp->rvp.tid++;
+ /* make sure that tid != 0 */
+ if (ibp->rvp.tid == 0)
+ ibp->rvp.tid++;
+ trap->tid = cpu_to_be64(ibp->rvp.tid);
+ }
+ smp->tid = trap->tid;
+
smp->attr_id = IB_SMP_ATTR_NOTICE;
/* o14-1: smp->mkey = 0; */
- memcpy(smp->route.lid.data, data, len);
+
+ memcpy(smp->route.lid.data, &trap->data, trap->len);
spin_lock_irqsave(&ibp->rvp.lock, flags);
if (!ibp->rvp.sm_ah) {
@@ -144,65 +367,101 @@ static void send_trap(struct hfi1_ibport *ibp, void *data, unsigned len)
ah = hfi1_create_qp0_ah(ibp, ibp->rvp.sm_lid);
if (IS_ERR(ah)) {
- ret = PTR_ERR(ah);
- } else {
- send_buf->ah = ah;
- ibp->rvp.sm_ah = ibah_to_rvtah(ah);
- ret = 0;
+ spin_unlock_irqrestore(&ibp->rvp.lock, flags);
+ return;
}
+ send_buf->ah = ah;
+ ibp->rvp.sm_ah = ibah_to_rvtah(ah);
} else {
- ret = -EINVAL;
+ spin_unlock_irqrestore(&ibp->rvp.lock, flags);
+ return;
}
} else {
send_buf->ah = &ibp->rvp.sm_ah->ibah;
- ret = 0;
}
+
+ /*
+ * If the trap was repressed while things were getting set up, don't
+ * bother sending it. This could happen for a retry.
+ */
+ if (trap->repress) {
+ list_del(&trap->list);
+ spin_unlock_irqrestore(&ibp->rvp.lock, flags);
+ kfree(trap);
+ ib_free_send_mad(send_buf);
+ return;
+ }
+
+ trap->in_use = 0;
spin_unlock_irqrestore(&ibp->rvp.lock, flags);
- if (!ret)
- ret = ib_post_send_mad(send_buf, NULL);
- if (!ret) {
- /* 4.096 usec. */
- timeout = (4096 * (1UL << ibp->rvp.subnet_timeout)) / 1000;
- ibp->rvp.trap_timeout = jiffies + usecs_to_jiffies(timeout);
- } else {
+ if (ib_post_send_mad(send_buf, NULL))
ib_free_send_mad(send_buf);
- ibp->rvp.trap_timeout = 0;
+}
+
+void hfi1_handle_trap_timer(unsigned long data)
+{
+ struct hfi1_ibport *ibp = (struct hfi1_ibport *)data;
+ struct trap_node *trap = NULL;
+ unsigned long flags;
+ int i;
+
+ /* Find the trap with the highest priority */
+ spin_lock_irqsave(&ibp->rvp.lock, flags);
+ for (i = 0; !trap && i < RVT_MAX_TRAP_LISTS; i++) {
+ trap = list_first_entry_or_null(&ibp->rvp.trap_lists[i].list,
+ struct trap_node, list);
}
+ spin_unlock_irqrestore(&ibp->rvp.lock, flags);
+
+ if (trap)
+ send_trap(ibp, trap);
+}
+
+static struct trap_node *create_trap_node(u8 type, __be16 trap_num, u32 lid)
+{
+ struct trap_node *trap;
+
+ trap = kzalloc(sizeof(*trap), GFP_ATOMIC);
+ if (!trap)
+ return NULL;
+
+ INIT_LIST_HEAD(&trap->list);
+ trap->data.generic_type = type;
+ trap->data.prod_type_lsb = IB_NOTICE_PROD_CA;
+ trap->data.trap_num = trap_num;
+ trap->data.issuer_lid = cpu_to_be32(lid);
+
+ return trap;
}
/*
- * Send a bad [PQ]_Key trap (ch. 14.3.8).
+ * Send a bad P_Key trap (ch. 14.3.8).
*/
-void hfi1_bad_pqkey(struct hfi1_ibport *ibp, __be16 trap_num, u32 key, u32 sl,
- u32 qp1, u32 qp2, u16 lid1, u16 lid2)
+void hfi1_bad_pkey(struct hfi1_ibport *ibp, u32 key, u32 sl,
+ u32 qp1, u32 qp2, u32 lid1, u32 lid2)
{
- struct opa_mad_notice_attr data;
+ struct trap_node *trap;
u32 lid = ppd_from_ibp(ibp)->lid;
- u32 _lid1 = lid1;
- u32 _lid2 = lid2;
-
- memset(&data, 0, sizeof(data));
- if (trap_num == OPA_TRAP_BAD_P_KEY)
- ibp->rvp.pkey_violations++;
- else
- ibp->rvp.qkey_violations++;
ibp->rvp.n_pkt_drops++;
+ ibp->rvp.pkey_violations++;
+
+ trap = create_trap_node(IB_NOTICE_TYPE_SECURITY, OPA_TRAP_BAD_P_KEY,
+ lid);
+ if (!trap)
+ return;
/* Send violation trap */
- data.generic_type = IB_NOTICE_TYPE_SECURITY;
- data.prod_type_lsb = IB_NOTICE_PROD_CA;
- data.trap_num = trap_num;
- data.issuer_lid = cpu_to_be32(lid);
- data.ntc_257_258.lid1 = cpu_to_be32(_lid1);
- data.ntc_257_258.lid2 = cpu_to_be32(_lid2);
- data.ntc_257_258.key = cpu_to_be32(key);
- data.ntc_257_258.sl = sl << 3;
- data.ntc_257_258.qp1 = cpu_to_be32(qp1);
- data.ntc_257_258.qp2 = cpu_to_be32(qp2);
-
- send_trap(ibp, &data, sizeof(data));
+ trap->data.ntc_257_258.lid1 = cpu_to_be32(lid1);
+ trap->data.ntc_257_258.lid2 = cpu_to_be32(lid2);
+ trap->data.ntc_257_258.key = cpu_to_be32(key);
+ trap->data.ntc_257_258.sl = sl << 3;
+ trap->data.ntc_257_258.qp1 = cpu_to_be32(qp1);
+ trap->data.ntc_257_258.qp2 = cpu_to_be32(qp2);
+
+ trap->len = sizeof(trap->data);
+ send_trap(ibp, trap);
}
/*
@@ -211,34 +470,36 @@ void hfi1_bad_pqkey(struct hfi1_ibport *ibp, __be16 trap_num, u32 key, u32 sl,
static void bad_mkey(struct hfi1_ibport *ibp, struct ib_mad_hdr *mad,
__be64 mkey, __be32 dr_slid, u8 return_path[], u8 hop_cnt)
{
- struct opa_mad_notice_attr data;
+ struct trap_node *trap;
u32 lid = ppd_from_ibp(ibp)->lid;
- memset(&data, 0, sizeof(data));
+ trap = create_trap_node(IB_NOTICE_TYPE_SECURITY, OPA_TRAP_BAD_M_KEY,
+ lid);
+ if (!trap)
+ return;
+
/* Send violation trap */
- data.generic_type = IB_NOTICE_TYPE_SECURITY;
- data.prod_type_lsb = IB_NOTICE_PROD_CA;
- data.trap_num = OPA_TRAP_BAD_M_KEY;
- data.issuer_lid = cpu_to_be32(lid);
- data.ntc_256.lid = data.issuer_lid;
- data.ntc_256.method = mad->method;
- data.ntc_256.attr_id = mad->attr_id;
- data.ntc_256.attr_mod = mad->attr_mod;
- data.ntc_256.mkey = mkey;
+ trap->data.ntc_256.lid = trap->data.issuer_lid;
+ trap->data.ntc_256.method = mad->method;
+ trap->data.ntc_256.attr_id = mad->attr_id;
+ trap->data.ntc_256.attr_mod = mad->attr_mod;
+ trap->data.ntc_256.mkey = mkey;
if (mad->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) {
- data.ntc_256.dr_slid = dr_slid;
- data.ntc_256.dr_trunc_hop = IB_NOTICE_TRAP_DR_NOTICE;
- if (hop_cnt > ARRAY_SIZE(data.ntc_256.dr_rtn_path)) {
- data.ntc_256.dr_trunc_hop |=
+ trap->data.ntc_256.dr_slid = dr_slid;
+ trap->data.ntc_256.dr_trunc_hop = IB_NOTICE_TRAP_DR_NOTICE;
+ if (hop_cnt > ARRAY_SIZE(trap->data.ntc_256.dr_rtn_path)) {
+ trap->data.ntc_256.dr_trunc_hop |=
IB_NOTICE_TRAP_DR_TRUNC;
- hop_cnt = ARRAY_SIZE(data.ntc_256.dr_rtn_path);
+ hop_cnt = ARRAY_SIZE(trap->data.ntc_256.dr_rtn_path);
}
- data.ntc_256.dr_trunc_hop |= hop_cnt;
- memcpy(data.ntc_256.dr_rtn_path, return_path,
+ trap->data.ntc_256.dr_trunc_hop |= hop_cnt;
+ memcpy(trap->data.ntc_256.dr_rtn_path, return_path,
hop_cnt);
}
- send_trap(ibp, &data, sizeof(data));
+ trap->len = sizeof(trap->data);
+
+ send_trap(ibp, trap);
}
/*
@@ -246,22 +507,24 @@ static void bad_mkey(struct hfi1_ibport *ibp, struct ib_mad_hdr *mad,
*/
void hfi1_cap_mask_chg(struct rvt_dev_info *rdi, u8 port_num)
{
- struct opa_mad_notice_attr data;
+ struct trap_node *trap;
struct hfi1_ibdev *verbs_dev = dev_from_rdi(rdi);
struct hfi1_devdata *dd = dd_from_dev(verbs_dev);
struct hfi1_ibport *ibp = &dd->pport[port_num - 1].ibport_data;
u32 lid = ppd_from_ibp(ibp)->lid;
- memset(&data, 0, sizeof(data));
+ trap = create_trap_node(IB_NOTICE_TYPE_INFO,
+ OPA_TRAP_CHANGE_CAPABILITY,
+ lid);
+ if (!trap)
+ return;
- data.generic_type = IB_NOTICE_TYPE_INFO;
- data.prod_type_lsb = IB_NOTICE_PROD_CA;
- data.trap_num = OPA_TRAP_CHANGE_CAPABILITY;
- data.issuer_lid = cpu_to_be32(lid);
- data.ntc_144.lid = data.issuer_lid;
- data.ntc_144.new_cap_mask = cpu_to_be32(ibp->rvp.port_cap_flags);
+ trap->data.ntc_144.lid = trap->data.issuer_lid;
+ trap->data.ntc_144.new_cap_mask = cpu_to_be32(ibp->rvp.port_cap_flags);
+ trap->data.ntc_144.cap_mask3 = cpu_to_be16(ibp->rvp.port_cap3_flags);
- send_trap(ibp, &data, sizeof(data));
+ trap->len = sizeof(trap->data);
+ send_trap(ibp, trap);
}
/*
@@ -269,19 +532,19 @@ void hfi1_cap_mask_chg(struct rvt_dev_info *rdi, u8 port_num)
*/
void hfi1_sys_guid_chg(struct hfi1_ibport *ibp)
{
- struct opa_mad_notice_attr data;
+ struct trap_node *trap;
u32 lid = ppd_from_ibp(ibp)->lid;
- memset(&data, 0, sizeof(data));
+ trap = create_trap_node(IB_NOTICE_TYPE_INFO, OPA_TRAP_CHANGE_SYSGUID,
+ lid);
+ if (!trap)
+ return;
- data.generic_type = IB_NOTICE_TYPE_INFO;
- data.prod_type_lsb = IB_NOTICE_PROD_CA;
- data.trap_num = OPA_TRAP_CHANGE_SYSGUID;
- data.issuer_lid = cpu_to_be32(lid);
- data.ntc_145.new_sys_guid = ib_hfi1_sys_image_guid;
- data.ntc_145.lid = data.issuer_lid;
+ trap->data.ntc_145.new_sys_guid = ib_hfi1_sys_image_guid;
+ trap->data.ntc_145.lid = trap->data.issuer_lid;
- send_trap(ibp, &data, sizeof(data));
+ trap->len = sizeof(trap->data);
+ send_trap(ibp, trap);
}
/*
@@ -289,29 +552,30 @@ void hfi1_sys_guid_chg(struct hfi1_ibport *ibp)
*/
void hfi1_node_desc_chg(struct hfi1_ibport *ibp)
{
- struct opa_mad_notice_attr data;
+ struct trap_node *trap;
u32 lid = ppd_from_ibp(ibp)->lid;
- memset(&data, 0, sizeof(data));
+ trap = create_trap_node(IB_NOTICE_TYPE_INFO,
+ OPA_TRAP_CHANGE_CAPABILITY,
+ lid);
+ if (!trap)
+ return;
- data.generic_type = IB_NOTICE_TYPE_INFO;
- data.prod_type_lsb = IB_NOTICE_PROD_CA;
- data.trap_num = OPA_TRAP_CHANGE_CAPABILITY;
- data.issuer_lid = cpu_to_be32(lid);
- data.ntc_144.lid = data.issuer_lid;
- data.ntc_144.change_flags =
+ trap->data.ntc_144.lid = trap->data.issuer_lid;
+ trap->data.ntc_144.change_flags =
cpu_to_be16(OPA_NOTICE_TRAP_NODE_DESC_CHG);
- send_trap(ibp, &data, sizeof(data));
+ trap->len = sizeof(trap->data);
+ send_trap(ibp, trap);
}
static int __subn_get_opa_nodedesc(struct opa_smp *smp, u32 am,
u8 *data, struct ib_device *ibdev,
- u8 port, u32 *resp_len)
+ u8 port, u32 *resp_len, u32 max_len)
{
struct opa_node_description *nd;
- if (am) {
+ if (am || smp_length_check(sizeof(*nd), max_len)) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
}
@@ -328,7 +592,7 @@ static int __subn_get_opa_nodedesc(struct opa_smp *smp, u32 am,
static int __subn_get_opa_nodeinfo(struct opa_smp *smp, u32 am, u8 *data,
struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
struct opa_node_info *ni;
struct hfi1_devdata *dd = dd_from_ibdev(ibdev);
@@ -338,6 +602,7 @@ static int __subn_get_opa_nodeinfo(struct opa_smp *smp, u32 am, u8 *data,
/* GUID 0 is illegal */
if (am || pidx >= dd->num_pports || ibdev->node_guid == 0 ||
+ smp_length_check(sizeof(*ni), max_len) ||
get_sguid(to_iport(ibdev, port), HFI1_PORT_GUID_INDEX) == 0) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
@@ -519,7 +784,7 @@ void read_ltp_rtt(struct hfi1_devdata *dd)
static int __subn_get_opa_portinfo(struct opa_smp *smp, u32 am, u8 *data,
struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
int i;
struct hfi1_devdata *dd;
@@ -535,7 +800,7 @@ static int __subn_get_opa_portinfo(struct opa_smp *smp, u32 am, u8 *data,
u32 buffer_units;
u64 tmp = 0;
- if (num_ports != 1) {
+ if (num_ports != 1 || smp_length_check(sizeof(*pi), max_len)) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
}
@@ -605,7 +870,7 @@ static int __subn_get_opa_portinfo(struct opa_smp *smp, u32 am, u8 *data,
ppd->offline_disabled_reason;
pi->port_states.portphysstate_portstate =
- (hfi1_ibphys_portstate(ppd) << 4) | state;
+ (driver_pstate(ppd) << 4) | state;
pi->mkeyprotect_lmc = (ibp->rvp.mkeyprot << 6) | ppd->lmc;
@@ -704,13 +969,9 @@ static int __subn_get_opa_portinfo(struct opa_smp *smp, u32 am, u8 *data,
buffer_units |= (dd->vl15_init << 11) & OPA_PI_MASK_BUF_UNIT_VL15_INIT;
pi->buffer_units = cpu_to_be32(buffer_units);
- pi->opa_cap_mask = cpu_to_be16(OPA_CAP_MASK3_IsSharedSpaceSupported |
- OPA_CAP_MASK3_IsEthOnFabricSupported);
- /* Driver does not support mcast/collective configuration */
- pi->opa_cap_mask &=
- cpu_to_be16(~OPA_CAP_MASK3_IsAddrRangeConfigSupported);
- pi->collectivemask_multicastmask = ((HFI1_COLLECTIVE_NR & 0x7)
- << 3 | (HFI1_MCAST_NR & 0x7));
+ pi->opa_cap_mask = cpu_to_be16(ibp->rvp.port_cap3_flags);
+ pi->collectivemask_multicastmask = ((OPA_COLLECTIVE_NR & 0x7)
+ << 3 | (OPA_MCAST_NR & 0x7));
/* HFI supports a replay buffer 128 LTPs in size */
pi->replay_depth.buffer = 0x80;
@@ -748,7 +1009,7 @@ static int get_pkeys(struct hfi1_devdata *dd, u8 port, u16 *pkeys)
static int __subn_get_opa_pkeytable(struct opa_smp *smp, u32 am, u8 *data,
struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
struct hfi1_devdata *dd = dd_from_ibdev(ibdev);
u32 n_blocks_req = OPA_AM_NBLK(am);
@@ -771,6 +1032,11 @@ static int __subn_get_opa_pkeytable(struct opa_smp *smp, u32 am, u8 *data,
size = (n_blocks_req * OPA_PARTITION_TABLE_BLK_SIZE) * sizeof(u16);
+ if (smp_length_check(size, max_len)) {
+ smp->status |= IB_SMP_INVALID_FIELD;
+ return reply((struct ib_mad_hdr *)smp);
+ }
+
if (start_block + n_blocks_req > n_blocks_avail ||
n_blocks_req > OPA_NUM_PKEY_BLOCKS_PER_SMP) {
pr_warn("OPA Get PKey AM Invalid : s 0x%x; req 0x%x; "
@@ -915,8 +1181,8 @@ static int physical_transition_allowed(int old, int new)
static int port_states_transition_allowed(struct hfi1_pportdata *ppd,
u32 logical_new, u32 physical_new)
{
- u32 physical_old = driver_physical_state(ppd);
- u32 logical_old = driver_logical_state(ppd);
+ u32 physical_old = driver_pstate(ppd);
+ u32 logical_old = driver_lstate(ppd);
int ret, logical_allowed, physical_allowed;
ret = logical_transition_allowed(logical_old, logical_new);
@@ -1074,7 +1340,7 @@ static int set_port_states(struct hfi1_pportdata *ppd, struct opa_smp *smp,
*/
static int __subn_set_opa_portinfo(struct opa_smp *smp, u32 am, u8 *data,
struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
struct opa_port_info *pi = (struct opa_port_info *)data;
struct ib_event event;
@@ -1083,8 +1349,8 @@ static int __subn_set_opa_portinfo(struct opa_smp *smp, u32 am, u8 *data,
struct hfi1_ibport *ibp;
u8 clientrereg;
unsigned long flags;
- u32 smlid, opa_lid; /* tmp vars to hold LID values */
- u16 lid;
+ u32 smlid;
+ u32 lid;
u8 ls_old, ls_new, ps_new;
u8 vls;
u8 msl;
@@ -1095,27 +1361,26 @@ static int __subn_set_opa_portinfo(struct opa_smp *smp, u32 am, u8 *data,
int ret, i, invalid = 0, call_set_mtu = 0;
int call_link_downgrade_policy = 0;
- if (num_ports != 1) {
+ if (num_ports != 1 ||
+ smp_length_check(sizeof(*pi), max_len)) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
}
- opa_lid = be32_to_cpu(pi->lid);
- if (opa_lid & 0xFFFF0000) {
- pr_warn("OPA_PortInfo lid out of range: %X\n", opa_lid);
+ lid = be32_to_cpu(pi->lid);
+ if (lid & 0xFF000000) {
+ pr_warn("OPA_PortInfo lid out of range: %X\n", lid);
smp->status |= IB_SMP_INVALID_FIELD;
goto get_only;
}
- lid = (u16)(opa_lid & 0x0000FFFF);
smlid = be32_to_cpu(pi->sm_lid);
- if (smlid & 0xFFFF0000) {
+ if (smlid & 0xFF000000) {
pr_warn("OPA_PortInfo SM lid out of range: %X\n", smlid);
smp->status |= IB_SMP_INVALID_FIELD;
goto get_only;
}
- smlid &= 0x0000FFFF;
clientrereg = (pi->clientrereg_subnettimeout &
OPA_PI_MASK_CLIENT_REREGISTER);
@@ -1130,12 +1395,16 @@ static int __subn_set_opa_portinfo(struct opa_smp *smp, u32 am, u8 *data,
ls_old = driver_lstate(ppd);
ibp->rvp.mkey = pi->mkey;
- ibp->rvp.gid_prefix = pi->subnet_prefix;
+ if (ibp->rvp.gid_prefix != pi->subnet_prefix) {
+ ibp->rvp.gid_prefix = pi->subnet_prefix;
+ event.event = IB_EVENT_GID_CHANGE;
+ ib_dispatch_event(&event);
+ }
ibp->rvp.mkey_lease_period = be16_to_cpu(pi->mkey_lease_period);
/* Must be a valid unicast LID address. */
if ((lid == 0 && ls_old > IB_PORT_INIT) ||
- lid >= be16_to_cpu(IB_MULTICAST_LID_BASE)) {
+ (hfi1_is_16B_mcast(lid))) {
smp->status |= IB_SMP_INVALID_FIELD;
pr_warn("SubnSet(OPA_PortInfo) lid invalid 0x%x\n",
lid);
@@ -1148,6 +1417,16 @@ static int __subn_set_opa_portinfo(struct opa_smp *smp, u32 am, u8 *data,
hfi1_set_lid(ppd, lid, pi->mkeyprotect_lmc & OPA_PI_MASK_LMC);
event.event = IB_EVENT_LID_CHANGE;
ib_dispatch_event(&event);
+
+ if (HFI1_PORT_GUID_INDEX + 1 < HFI1_GUIDS_PER_PORT) {
+ /* Manufacture GID from LID to support extended
+ * addresses
+ */
+ ppd->guids[HFI1_PORT_GUID_INDEX + 1] =
+ be64_to_cpu(OPA_MAKE_ID(lid));
+ event.event = IB_EVENT_GID_CHANGE;
+ ib_dispatch_event(&event);
+ }
}
msl = pi->smsl & OPA_PI_MASK_SMSL;
@@ -1158,7 +1437,7 @@ static int __subn_set_opa_portinfo(struct opa_smp *smp, u32 am, u8 *data,
/* Must be a valid unicast LID address. */
if ((smlid == 0 && ls_old > IB_PORT_INIT) ||
- smlid >= be16_to_cpu(IB_MULTICAST_LID_BASE)) {
+ (hfi1_is_16B_mcast(smlid))) {
smp->status |= IB_SMP_INVALID_FIELD;
pr_warn("SubnSet(OPA_PortInfo) smlid invalid 0x%x\n", smlid);
} else if (smlid != ibp->rvp.sm_lid || msl != ibp->rvp.sm_sl) {
@@ -1166,7 +1445,7 @@ static int __subn_set_opa_portinfo(struct opa_smp *smp, u32 am, u8 *data,
spin_lock_irqsave(&ibp->rvp.lock, flags);
if (ibp->rvp.sm_ah) {
if (smlid != ibp->rvp.sm_lid)
- rdma_ah_set_dlid(&ibp->rvp.sm_ah->attr, smlid);
+ hfi1_modify_qp0_ah(ibp, ibp->rvp.sm_ah, smlid);
if (msl != ibp->rvp.sm_sl)
rdma_ah_set_sl(&ibp->rvp.sm_ah->attr, msl);
}
@@ -1346,7 +1625,8 @@ static int __subn_set_opa_portinfo(struct opa_smp *smp, u32 am, u8 *data,
if (ret)
return ret;
- ret = __subn_get_opa_portinfo(smp, am, data, ibdev, port, resp_len);
+ ret = __subn_get_opa_portinfo(smp, am, data, ibdev, port, resp_len,
+ max_len);
/* restore re-reg bit per o14-12.2.1 */
pi->clientrereg_subnettimeout |= clientrereg;
@@ -1363,7 +1643,8 @@ static int __subn_set_opa_portinfo(struct opa_smp *smp, u32 am, u8 *data,
return ret;
get_only:
- return __subn_get_opa_portinfo(smp, am, data, ibdev, port, resp_len);
+ return __subn_get_opa_portinfo(smp, am, data, ibdev, port, resp_len,
+ max_len);
}
/**
@@ -1424,7 +1705,7 @@ static int set_pkeys(struct hfi1_devdata *dd, u8 port, u16 *pkeys)
static int __subn_set_opa_pkeytable(struct opa_smp *smp, u32 am, u8 *data,
struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
struct hfi1_devdata *dd = dd_from_ibdev(ibdev);
u32 n_blocks_sent = OPA_AM_NBLK(am);
@@ -1434,6 +1715,7 @@ static int __subn_set_opa_pkeytable(struct opa_smp *smp, u32 am, u8 *data,
int i;
u16 n_blocks_avail;
unsigned npkeys = hfi1_get_npkeys(dd);
+ u32 size = 0;
if (n_blocks_sent == 0) {
pr_warn("OPA Get PKey AM Invalid : P = %d; B = 0x%x; N = 0x%x\n",
@@ -1444,6 +1726,13 @@ static int __subn_set_opa_pkeytable(struct opa_smp *smp, u32 am, u8 *data,
n_blocks_avail = (u16)(npkeys / OPA_PARTITION_TABLE_BLK_SIZE) + 1;
+ size = sizeof(u16) * (n_blocks_sent * OPA_PARTITION_TABLE_BLK_SIZE);
+
+ if (smp_length_check(size, max_len)) {
+ smp->status |= IB_SMP_INVALID_FIELD;
+ return reply((struct ib_mad_hdr *)smp);
+ }
+
if (start_block + n_blocks_sent > n_blocks_avail ||
n_blocks_sent > OPA_NUM_PKEY_BLOCKS_PER_SMP) {
pr_warn("OPA Set PKey AM Invalid : s 0x%x; req 0x%x; avail 0x%x; blk/smp 0x%lx\n",
@@ -1461,7 +1750,8 @@ static int __subn_set_opa_pkeytable(struct opa_smp *smp, u32 am, u8 *data,
return reply((struct ib_mad_hdr *)smp);
}
- return __subn_get_opa_pkeytable(smp, am, data, ibdev, port, resp_len);
+ return __subn_get_opa_pkeytable(smp, am, data, ibdev, port, resp_len,
+ max_len);
}
#define ILLEGAL_VL 12
@@ -1522,14 +1812,14 @@ static int get_sc2vlt_tables(struct hfi1_devdata *dd, void *data)
static int __subn_get_opa_sl_to_sc(struct opa_smp *smp, u32 am, u8 *data,
struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
struct hfi1_ibport *ibp = to_iport(ibdev, port);
u8 *p = data;
size_t size = ARRAY_SIZE(ibp->sl_to_sc); /* == 32 */
unsigned i;
- if (am) {
+ if (am || smp_length_check(size, max_len)) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
}
@@ -1545,14 +1835,15 @@ static int __subn_get_opa_sl_to_sc(struct opa_smp *smp, u32 am, u8 *data,
static int __subn_set_opa_sl_to_sc(struct opa_smp *smp, u32 am, u8 *data,
struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
struct hfi1_ibport *ibp = to_iport(ibdev, port);
u8 *p = data;
+ size_t size = ARRAY_SIZE(ibp->sl_to_sc);
int i;
u8 sc;
- if (am) {
+ if (am || smp_length_check(size, max_len)) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
}
@@ -1567,19 +1858,20 @@ static int __subn_set_opa_sl_to_sc(struct opa_smp *smp, u32 am, u8 *data,
}
}
- return __subn_get_opa_sl_to_sc(smp, am, data, ibdev, port, resp_len);
+ return __subn_get_opa_sl_to_sc(smp, am, data, ibdev, port, resp_len,
+ max_len);
}
static int __subn_get_opa_sc_to_sl(struct opa_smp *smp, u32 am, u8 *data,
struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
struct hfi1_ibport *ibp = to_iport(ibdev, port);
u8 *p = data;
size_t size = ARRAY_SIZE(ibp->sc_to_sl); /* == 32 */
unsigned i;
- if (am) {
+ if (am || smp_length_check(size, max_len)) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
}
@@ -1595,13 +1887,14 @@ static int __subn_get_opa_sc_to_sl(struct opa_smp *smp, u32 am, u8 *data,
static int __subn_set_opa_sc_to_sl(struct opa_smp *smp, u32 am, u8 *data,
struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
struct hfi1_ibport *ibp = to_iport(ibdev, port);
+ size_t size = ARRAY_SIZE(ibp->sc_to_sl);
u8 *p = data;
int i;
- if (am) {
+ if (am || smp_length_check(size, max_len)) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
}
@@ -1609,19 +1902,20 @@ static int __subn_set_opa_sc_to_sl(struct opa_smp *smp, u32 am, u8 *data,
for (i = 0; i < ARRAY_SIZE(ibp->sc_to_sl); i++)
ibp->sc_to_sl[i] = *p++;
- return __subn_get_opa_sc_to_sl(smp, am, data, ibdev, port, resp_len);
+ return __subn_get_opa_sc_to_sl(smp, am, data, ibdev, port, resp_len,
+ max_len);
}
static int __subn_get_opa_sc_to_vlt(struct opa_smp *smp, u32 am, u8 *data,
struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
u32 n_blocks = OPA_AM_NBLK(am);
struct hfi1_devdata *dd = dd_from_ibdev(ibdev);
void *vp = (void *)data;
size_t size = 4 * sizeof(u64);
- if (n_blocks != 1) {
+ if (n_blocks != 1 || smp_length_check(size, max_len)) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
}
@@ -1636,7 +1930,7 @@ static int __subn_get_opa_sc_to_vlt(struct opa_smp *smp, u32 am, u8 *data,
static int __subn_set_opa_sc_to_vlt(struct opa_smp *smp, u32 am, u8 *data,
struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
u32 n_blocks = OPA_AM_NBLK(am);
int async_update = OPA_AM_ASYNC(am);
@@ -1644,8 +1938,15 @@ static int __subn_set_opa_sc_to_vlt(struct opa_smp *smp, u32 am, u8 *data,
void *vp = (void *)data;
struct hfi1_pportdata *ppd;
int lstate;
+ /*
+ * set_sc2vlt_tables writes the information contained in *data
+ * to four 64-bit registers SendSC2VLt[0-3]. We need to make
+ * sure *max_len is not greater than the total size of the four
+ * SendSC2VLt[0-3] registers.
+ */
+ size_t size = 4 * sizeof(u64);
- if (n_blocks != 1 || async_update) {
+ if (n_blocks != 1 || async_update || smp_length_check(size, max_len)) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
}
@@ -1665,27 +1966,28 @@ static int __subn_set_opa_sc_to_vlt(struct opa_smp *smp, u32 am, u8 *data,
set_sc2vlt_tables(dd, vp);
- return __subn_get_opa_sc_to_vlt(smp, am, data, ibdev, port, resp_len);
+ return __subn_get_opa_sc_to_vlt(smp, am, data, ibdev, port, resp_len,
+ max_len);
}
static int __subn_get_opa_sc_to_vlnt(struct opa_smp *smp, u32 am, u8 *data,
struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
u32 n_blocks = OPA_AM_NPORT(am);
struct hfi1_devdata *dd = dd_from_ibdev(ibdev);
struct hfi1_pportdata *ppd;
void *vp = (void *)data;
- int size;
+ int size = sizeof(struct sc2vlnt);
- if (n_blocks != 1) {
+ if (n_blocks != 1 || smp_length_check(size, max_len)) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
}
ppd = dd->pport + (port - 1);
- size = fm_get_table(ppd, FM_TBL_SC2VLNT, vp);
+ fm_get_table(ppd, FM_TBL_SC2VLNT, vp);
if (resp_len)
*resp_len += size;
@@ -1695,15 +1997,16 @@ static int __subn_get_opa_sc_to_vlnt(struct opa_smp *smp, u32 am, u8 *data,
static int __subn_set_opa_sc_to_vlnt(struct opa_smp *smp, u32 am, u8 *data,
struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
u32 n_blocks = OPA_AM_NPORT(am);
struct hfi1_devdata *dd = dd_from_ibdev(ibdev);
struct hfi1_pportdata *ppd;
void *vp = (void *)data;
int lstate;
+ int size = sizeof(struct sc2vlnt);
- if (n_blocks != 1) {
+ if (n_blocks != 1 || smp_length_check(size, max_len)) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
}
@@ -1721,12 +2024,12 @@ static int __subn_set_opa_sc_to_vlnt(struct opa_smp *smp, u32 am, u8 *data,
fm_set_table(ppd, FM_TBL_SC2VLNT, vp);
return __subn_get_opa_sc_to_vlnt(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
}
static int __subn_get_opa_psi(struct opa_smp *smp, u32 am, u8 *data,
struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
u32 nports = OPA_AM_NPORT(am);
u32 start_of_sm_config = OPA_AM_START_SM_CFG(am);
@@ -1735,7 +2038,7 @@ static int __subn_get_opa_psi(struct opa_smp *smp, u32 am, u8 *data,
struct hfi1_pportdata *ppd;
struct opa_port_state_info *psi = (struct opa_port_state_info *)data;
- if (nports != 1) {
+ if (nports != 1 || smp_length_check(sizeof(*psi), max_len)) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
}
@@ -1755,7 +2058,7 @@ static int __subn_get_opa_psi(struct opa_smp *smp, u32 am, u8 *data,
ppd->offline_disabled_reason;
psi->port_states.portphysstate_portstate =
- (hfi1_ibphys_portstate(ppd) << 4) | (lstate & 0xf);
+ (driver_pstate(ppd) << 4) | (lstate & 0xf);
psi->link_width_downgrade_tx_active =
cpu_to_be16(ppd->link_width_downgrade_tx_active);
psi->link_width_downgrade_rx_active =
@@ -1768,7 +2071,7 @@ static int __subn_get_opa_psi(struct opa_smp *smp, u32 am, u8 *data,
static int __subn_set_opa_psi(struct opa_smp *smp, u32 am, u8 *data,
struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
u32 nports = OPA_AM_NPORT(am);
u32 start_of_sm_config = OPA_AM_START_SM_CFG(am);
@@ -1779,7 +2082,7 @@ static int __subn_set_opa_psi(struct opa_smp *smp, u32 am, u8 *data,
struct opa_port_state_info *psi = (struct opa_port_state_info *)data;
int ret, invalid = 0;
- if (nports != 1) {
+ if (nports != 1 || smp_length_check(sizeof(*psi), max_len)) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
}
@@ -1809,19 +2112,21 @@ static int __subn_set_opa_psi(struct opa_smp *smp, u32 am, u8 *data,
if (invalid)
smp->status |= IB_SMP_INVALID_FIELD;
- return __subn_get_opa_psi(smp, am, data, ibdev, port, resp_len);
+ return __subn_get_opa_psi(smp, am, data, ibdev, port, resp_len,
+ max_len);
}
static int __subn_get_opa_cable_info(struct opa_smp *smp, u32 am, u8 *data,
struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
struct hfi1_devdata *dd = dd_from_ibdev(ibdev);
u32 addr = OPA_AM_CI_ADDR(am);
u32 len = OPA_AM_CI_LEN(am) + 1;
int ret;
- if (dd->pport->port_type != PORT_TYPE_QSFP) {
+ if (dd->pport->port_type != PORT_TYPE_QSFP ||
+ smp_length_check(len, max_len)) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
}
@@ -1864,21 +2169,22 @@ static int __subn_get_opa_cable_info(struct opa_smp *smp, u32 am, u8 *data,
}
static int __subn_get_opa_bct(struct opa_smp *smp, u32 am, u8 *data,
- struct ib_device *ibdev, u8 port, u32 *resp_len)
+ struct ib_device *ibdev, u8 port, u32 *resp_len,
+ u32 max_len)
{
u32 num_ports = OPA_AM_NPORT(am);
struct hfi1_devdata *dd = dd_from_ibdev(ibdev);
struct hfi1_pportdata *ppd;
struct buffer_control *p = (struct buffer_control *)data;
- int size;
+ int size = sizeof(struct buffer_control);
- if (num_ports != 1) {
+ if (num_ports != 1 || smp_length_check(size, max_len)) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
}
ppd = dd->pport + (port - 1);
- size = fm_get_table(ppd, FM_TBL_BUFFER_CONTROL, p);
+ fm_get_table(ppd, FM_TBL_BUFFER_CONTROL, p);
trace_bct_get(dd, p);
if (resp_len)
*resp_len += size;
@@ -1887,14 +2193,15 @@ static int __subn_get_opa_bct(struct opa_smp *smp, u32 am, u8 *data,
}
static int __subn_set_opa_bct(struct opa_smp *smp, u32 am, u8 *data,
- struct ib_device *ibdev, u8 port, u32 *resp_len)
+ struct ib_device *ibdev, u8 port, u32 *resp_len,
+ u32 max_len)
{
u32 num_ports = OPA_AM_NPORT(am);
struct hfi1_devdata *dd = dd_from_ibdev(ibdev);
struct hfi1_pportdata *ppd;
struct buffer_control *p = (struct buffer_control *)data;
- if (num_ports != 1) {
+ if (num_ports != 1 || smp_length_check(sizeof(*p), max_len)) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
}
@@ -1905,41 +2212,43 @@ static int __subn_set_opa_bct(struct opa_smp *smp, u32 am, u8 *data,
return reply((struct ib_mad_hdr *)smp);
}
- return __subn_get_opa_bct(smp, am, data, ibdev, port, resp_len);
+ return __subn_get_opa_bct(smp, am, data, ibdev, port, resp_len,
+ max_len);
}
static int __subn_get_opa_vl_arb(struct opa_smp *smp, u32 am, u8 *data,
struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
struct hfi1_pportdata *ppd = ppd_from_ibp(to_iport(ibdev, port));
u32 num_ports = OPA_AM_NPORT(am);
u8 section = (am & 0x00ff0000) >> 16;
u8 *p = data;
- int size = 0;
+ int size = 256;
- if (num_ports != 1) {
+ if (num_ports != 1 || smp_length_check(size, max_len)) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
}
switch (section) {
case OPA_VLARB_LOW_ELEMENTS:
- size = fm_get_table(ppd, FM_TBL_VL_LOW_ARB, p);
+ fm_get_table(ppd, FM_TBL_VL_LOW_ARB, p);
break;
case OPA_VLARB_HIGH_ELEMENTS:
- size = fm_get_table(ppd, FM_TBL_VL_HIGH_ARB, p);
+ fm_get_table(ppd, FM_TBL_VL_HIGH_ARB, p);
break;
case OPA_VLARB_PREEMPT_ELEMENTS:
- size = fm_get_table(ppd, FM_TBL_VL_PREEMPT_ELEMS, p);
+ fm_get_table(ppd, FM_TBL_VL_PREEMPT_ELEMS, p);
break;
case OPA_VLARB_PREEMPT_MATRIX:
- size = fm_get_table(ppd, FM_TBL_VL_PREEMPT_MATRIX, p);
+ fm_get_table(ppd, FM_TBL_VL_PREEMPT_MATRIX, p);
break;
default:
pr_warn("OPA SubnGet(VL Arb) AM Invalid : 0x%x\n",
be32_to_cpu(smp->attr_mod));
smp->status |= IB_SMP_INVALID_FIELD;
+ size = 0;
break;
}
@@ -1951,14 +2260,15 @@ static int __subn_get_opa_vl_arb(struct opa_smp *smp, u32 am, u8 *data,
static int __subn_set_opa_vl_arb(struct opa_smp *smp, u32 am, u8 *data,
struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
struct hfi1_pportdata *ppd = ppd_from_ibp(to_iport(ibdev, port));
u32 num_ports = OPA_AM_NPORT(am);
u8 section = (am & 0x00ff0000) >> 16;
u8 *p = data;
+ int size = 256;
- if (num_ports != 1) {
+ if (num_ports != 1 || smp_length_check(size, max_len)) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
}
@@ -1986,7 +2296,8 @@ static int __subn_set_opa_vl_arb(struct opa_smp *smp, u32 am, u8 *data,
break;
}
- return __subn_get_opa_vl_arb(smp, am, data, ibdev, port, resp_len);
+ return __subn_get_opa_vl_arb(smp, am, data, ibdev, port, resp_len,
+ max_len);
}
struct opa_pma_mad {
@@ -3282,13 +3593,18 @@ struct opa_congestion_info_attr {
static int __subn_get_opa_cong_info(struct opa_smp *smp, u32 am, u8 *data,
struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
struct opa_congestion_info_attr *p =
(struct opa_congestion_info_attr *)data;
struct hfi1_ibport *ibp = to_iport(ibdev, port);
struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
+ if (smp_length_check(sizeof(*p), max_len)) {
+ smp->status |= IB_SMP_INVALID_FIELD;
+ return reply((struct ib_mad_hdr *)smp);
+ }
+
p->congestion_info = 0;
p->control_table_cap = ppd->cc_max_table_entries;
p->congestion_log_length = OPA_CONG_LOG_ELEMS;
@@ -3301,7 +3617,7 @@ static int __subn_get_opa_cong_info(struct opa_smp *smp, u32 am, u8 *data,
static int __subn_get_opa_cong_setting(struct opa_smp *smp, u32 am,
u8 *data, struct ib_device *ibdev,
- u8 port, u32 *resp_len)
+ u8 port, u32 *resp_len, u32 max_len)
{
int i;
struct opa_congestion_setting_attr *p =
@@ -3311,6 +3627,11 @@ static int __subn_get_opa_cong_setting(struct opa_smp *smp, u32 am,
struct opa_congestion_setting_entry_shadow *entries;
struct cc_state *cc_state;
+ if (smp_length_check(sizeof(*p), max_len)) {
+ smp->status |= IB_SMP_INVALID_FIELD;
+ return reply((struct ib_mad_hdr *)smp);
+ }
+
rcu_read_lock();
cc_state = get_cc_state(ppd);
@@ -3385,7 +3706,7 @@ static void apply_cc_state(struct hfi1_pportdata *ppd)
static int __subn_set_opa_cong_setting(struct opa_smp *smp, u32 am, u8 *data,
struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
struct opa_congestion_setting_attr *p =
(struct opa_congestion_setting_attr *)data;
@@ -3394,6 +3715,11 @@ static int __subn_set_opa_cong_setting(struct opa_smp *smp, u32 am, u8 *data,
struct opa_congestion_setting_entry_shadow *entries;
int i;
+ if (smp_length_check(sizeof(*p), max_len)) {
+ smp->status |= IB_SMP_INVALID_FIELD;
+ return reply((struct ib_mad_hdr *)smp);
+ }
+
/*
* Save details from packet into the ppd. Hold the cc_state_lock so
* our information is consistent with anyone trying to apply the state.
@@ -3415,12 +3741,12 @@ static int __subn_set_opa_cong_setting(struct opa_smp *smp, u32 am, u8 *data,
apply_cc_state(ppd);
return __subn_get_opa_cong_setting(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
}
static int __subn_get_opa_hfi1_cong_log(struct opa_smp *smp, u32 am,
u8 *data, struct ib_device *ibdev,
- u8 port, u32 *resp_len)
+ u8 port, u32 *resp_len, u32 max_len)
{
struct hfi1_ibport *ibp = to_iport(ibdev, port);
struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
@@ -3428,7 +3754,7 @@ static int __subn_get_opa_hfi1_cong_log(struct opa_smp *smp, u32 am,
s64 ts;
int i;
- if (am != 0) {
+ if (am || smp_length_check(sizeof(*cong_log), max_len)) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
}
@@ -3486,7 +3812,7 @@ static int __subn_get_opa_hfi1_cong_log(struct opa_smp *smp, u32 am,
static int __subn_get_opa_cc_table(struct opa_smp *smp, u32 am, u8 *data,
struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
struct ib_cc_table_attr *cc_table_attr =
(struct ib_cc_table_attr *)data;
@@ -3498,9 +3824,10 @@ static int __subn_get_opa_cc_table(struct opa_smp *smp, u32 am, u8 *data,
int i, j;
u32 sentry, eentry;
struct cc_state *cc_state;
+ u32 size = sizeof(u16) * (IB_CCT_ENTRIES * n_blocks + 1);
/* sanity check n_blocks, start_block */
- if (n_blocks == 0 ||
+ if (n_blocks == 0 || smp_length_check(size, max_len) ||
start_block + n_blocks > ppd->cc_max_table_entries) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
@@ -3530,14 +3857,14 @@ static int __subn_get_opa_cc_table(struct opa_smp *smp, u32 am, u8 *data,
rcu_read_unlock();
if (resp_len)
- *resp_len += sizeof(u16) * (IB_CCT_ENTRIES * n_blocks + 1);
+ *resp_len += size;
return reply((struct ib_mad_hdr *)smp);
}
static int __subn_set_opa_cc_table(struct opa_smp *smp, u32 am, u8 *data,
struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
struct ib_cc_table_attr *p = (struct ib_cc_table_attr *)data;
struct hfi1_ibport *ibp = to_iport(ibdev, port);
@@ -3548,9 +3875,10 @@ static int __subn_set_opa_cc_table(struct opa_smp *smp, u32 am, u8 *data,
int i, j;
u32 sentry, eentry;
u16 ccti_limit;
+ u32 size = sizeof(u16) * (IB_CCT_ENTRIES * n_blocks + 1);
/* sanity check n_blocks, start_block */
- if (n_blocks == 0 ||
+ if (n_blocks == 0 || smp_length_check(size, max_len) ||
start_block + n_blocks > ppd->cc_max_table_entries) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
@@ -3581,7 +3909,8 @@ static int __subn_set_opa_cc_table(struct opa_smp *smp, u32 am, u8 *data,
/* now apply the information */
apply_cc_state(ppd);
- return __subn_get_opa_cc_table(smp, am, data, ibdev, port, resp_len);
+ return __subn_get_opa_cc_table(smp, am, data, ibdev, port, resp_len,
+ max_len);
}
struct opa_led_info {
@@ -3594,7 +3923,7 @@ struct opa_led_info {
static int __subn_get_opa_led_info(struct opa_smp *smp, u32 am, u8 *data,
struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
struct hfi1_devdata *dd = dd_from_ibdev(ibdev);
struct hfi1_pportdata *ppd = dd->pport;
@@ -3602,7 +3931,7 @@ static int __subn_get_opa_led_info(struct opa_smp *smp, u32 am, u8 *data,
u32 nport = OPA_AM_NPORT(am);
u32 is_beaconing_active;
- if (nport != 1) {
+ if (nport != 1 || smp_length_check(sizeof(*p), max_len)) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
}
@@ -3624,14 +3953,14 @@ static int __subn_get_opa_led_info(struct opa_smp *smp, u32 am, u8 *data,
static int __subn_set_opa_led_info(struct opa_smp *smp, u32 am, u8 *data,
struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
struct hfi1_devdata *dd = dd_from_ibdev(ibdev);
struct opa_led_info *p = (struct opa_led_info *)data;
u32 nport = OPA_AM_NPORT(am);
int on = !!(be32_to_cpu(p->rsvd_led_mask) & OPA_LED_MASK);
- if (nport != 1) {
+ if (nport != 1 || smp_length_check(sizeof(*p), max_len)) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
}
@@ -3641,12 +3970,13 @@ static int __subn_set_opa_led_info(struct opa_smp *smp, u32 am, u8 *data,
else
shutdown_led_override(dd->pport);
- return __subn_get_opa_led_info(smp, am, data, ibdev, port, resp_len);
+ return __subn_get_opa_led_info(smp, am, data, ibdev, port, resp_len,
+ max_len);
}
static int subn_get_opa_sma(__be16 attr_id, struct opa_smp *smp, u32 am,
u8 *data, struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
int ret;
struct hfi1_ibport *ibp = to_iport(ibdev, port);
@@ -3654,71 +3984,71 @@ static int subn_get_opa_sma(__be16 attr_id, struct opa_smp *smp, u32 am,
switch (attr_id) {
case IB_SMP_ATTR_NODE_DESC:
ret = __subn_get_opa_nodedesc(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case IB_SMP_ATTR_NODE_INFO:
ret = __subn_get_opa_nodeinfo(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case IB_SMP_ATTR_PORT_INFO:
ret = __subn_get_opa_portinfo(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case IB_SMP_ATTR_PKEY_TABLE:
ret = __subn_get_opa_pkeytable(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case OPA_ATTRIB_ID_SL_TO_SC_MAP:
ret = __subn_get_opa_sl_to_sc(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case OPA_ATTRIB_ID_SC_TO_SL_MAP:
ret = __subn_get_opa_sc_to_sl(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case OPA_ATTRIB_ID_SC_TO_VLT_MAP:
ret = __subn_get_opa_sc_to_vlt(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case OPA_ATTRIB_ID_SC_TO_VLNT_MAP:
ret = __subn_get_opa_sc_to_vlnt(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case OPA_ATTRIB_ID_PORT_STATE_INFO:
ret = __subn_get_opa_psi(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case OPA_ATTRIB_ID_BUFFER_CONTROL_TABLE:
ret = __subn_get_opa_bct(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case OPA_ATTRIB_ID_CABLE_INFO:
ret = __subn_get_opa_cable_info(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case IB_SMP_ATTR_VL_ARB_TABLE:
ret = __subn_get_opa_vl_arb(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case OPA_ATTRIB_ID_CONGESTION_INFO:
ret = __subn_get_opa_cong_info(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case OPA_ATTRIB_ID_HFI_CONGESTION_SETTING:
ret = __subn_get_opa_cong_setting(smp, am, data, ibdev,
- port, resp_len);
+ port, resp_len, max_len);
break;
case OPA_ATTRIB_ID_HFI_CONGESTION_LOG:
ret = __subn_get_opa_hfi1_cong_log(smp, am, data, ibdev,
- port, resp_len);
+ port, resp_len, max_len);
break;
case OPA_ATTRIB_ID_CONGESTION_CONTROL_TABLE:
ret = __subn_get_opa_cc_table(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case IB_SMP_ATTR_LED_INFO:
ret = __subn_get_opa_led_info(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case IB_SMP_ATTR_SM_INFO:
if (ibp->rvp.port_cap_flags & IB_PORT_SM_DISABLED)
@@ -3736,7 +4066,7 @@ static int subn_get_opa_sma(__be16 attr_id, struct opa_smp *smp, u32 am,
static int subn_set_opa_sma(__be16 attr_id, struct opa_smp *smp, u32 am,
u8 *data, struct ib_device *ibdev, u8 port,
- u32 *resp_len)
+ u32 *resp_len, u32 max_len)
{
int ret;
struct hfi1_ibport *ibp = to_iport(ibdev, port);
@@ -3744,51 +4074,51 @@ static int subn_set_opa_sma(__be16 attr_id, struct opa_smp *smp, u32 am,
switch (attr_id) {
case IB_SMP_ATTR_PORT_INFO:
ret = __subn_set_opa_portinfo(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case IB_SMP_ATTR_PKEY_TABLE:
ret = __subn_set_opa_pkeytable(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case OPA_ATTRIB_ID_SL_TO_SC_MAP:
ret = __subn_set_opa_sl_to_sc(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case OPA_ATTRIB_ID_SC_TO_SL_MAP:
ret = __subn_set_opa_sc_to_sl(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case OPA_ATTRIB_ID_SC_TO_VLT_MAP:
ret = __subn_set_opa_sc_to_vlt(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case OPA_ATTRIB_ID_SC_TO_VLNT_MAP:
ret = __subn_set_opa_sc_to_vlnt(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case OPA_ATTRIB_ID_PORT_STATE_INFO:
ret = __subn_set_opa_psi(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case OPA_ATTRIB_ID_BUFFER_CONTROL_TABLE:
ret = __subn_set_opa_bct(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case IB_SMP_ATTR_VL_ARB_TABLE:
ret = __subn_set_opa_vl_arb(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case OPA_ATTRIB_ID_HFI_CONGESTION_SETTING:
ret = __subn_set_opa_cong_setting(smp, am, data, ibdev,
- port, resp_len);
+ port, resp_len, max_len);
break;
case OPA_ATTRIB_ID_CONGESTION_CONTROL_TABLE:
ret = __subn_set_opa_cc_table(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case IB_SMP_ATTR_LED_INFO:
ret = __subn_set_opa_led_info(smp, am, data, ibdev, port,
- resp_len);
+ resp_len, max_len);
break;
case IB_SMP_ATTR_SM_INFO:
if (ibp->rvp.port_cap_flags & IB_PORT_SM_DISABLED)
@@ -3844,7 +4174,10 @@ static int subn_get_opa_aggregate(struct opa_smp *smp,
memset(next_smp + sizeof(*agg), 0, agg_data_len);
(void)subn_get_opa_sma(agg->attr_id, smp, am, agg->data,
- ibdev, port, NULL);
+ ibdev, port, NULL, (u32)agg_data_len);
+
+ if (smp->status & IB_SMP_INVALID_FIELD)
+ break;
if (smp->status & ~IB_SMP_DIRECTION) {
set_aggr_error(agg);
return reply((struct ib_mad_hdr *)smp);
@@ -3887,7 +4220,9 @@ static int subn_set_opa_aggregate(struct opa_smp *smp,
}
(void)subn_set_opa_sma(agg->attr_id, smp, am, agg->data,
- ibdev, port, NULL);
+ ibdev, port, NULL, (u32)agg_data_len);
+ if (smp->status & IB_SMP_INVALID_FIELD)
+ break;
if (smp->status & ~IB_SMP_DIRECTION) {
set_aggr_error(agg);
return reply((struct ib_mad_hdr *)smp);
@@ -3958,7 +4293,7 @@ static int opa_local_smp_check(struct hfi1_ibport *ibp,
const struct ib_wc *in_wc)
{
struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
- u16 slid = in_wc->slid;
+ u16 slid = ib_lid_cpu16(in_wc->slid);
u16 pkey;
if (in_wc->pkey_index >= ARRAY_SIZE(ppd->pkeys))
@@ -3997,12 +4332,13 @@ static int process_subn_opa(struct ib_device *ibdev, int mad_flags,
struct opa_smp *smp = (struct opa_smp *)out_mad;
struct hfi1_ibport *ibp = to_iport(ibdev, port);
u8 *data;
- u32 am;
+ u32 am, data_size;
__be16 attr_id;
int ret;
*out_mad = *in_mad;
data = opa_get_smp_data(smp);
+ data_size = (u32)opa_get_smp_data_size(smp);
am = be32_to_cpu(smp->attr_mod);
attr_id = smp->attr_id;
@@ -4046,7 +4382,8 @@ static int process_subn_opa(struct ib_device *ibdev, int mad_flags,
default:
clear_opa_smp_data(smp);
ret = subn_get_opa_sma(attr_id, smp, am, data,
- ibdev, port, resp_len);
+ ibdev, port, resp_len,
+ data_size);
break;
case OPA_ATTRIB_ID_AGGREGATE:
ret = subn_get_opa_aggregate(smp, ibdev, port,
@@ -4058,7 +4395,8 @@ static int process_subn_opa(struct ib_device *ibdev, int mad_flags,
switch (attr_id) {
default:
ret = subn_set_opa_sma(attr_id, smp, am, data,
- ibdev, port, resp_len);
+ ibdev, port, resp_len,
+ data_size);
break;
case OPA_ATTRIB_ID_AGGREGATE:
ret = subn_set_opa_aggregate(smp, ibdev, port,
@@ -4077,6 +4415,11 @@ static int process_subn_opa(struct ib_device *ibdev, int mad_flags,
*/
ret = IB_MAD_RESULT_SUCCESS;
break;
+ case IB_MGMT_METHOD_TRAP_REPRESS:
+ subn_handle_opa_trap_repress(ibp, smp);
+ /* Always successful */
+ ret = IB_MAD_RESULT_SUCCESS;
+ break;
default:
smp->status |= IB_SMP_UNSUP_METHOD;
ret = reply((struct ib_mad_hdr *)smp);
diff --git a/drivers/infiniband/hw/hfi1/mad.h b/drivers/infiniband/hw/hfi1/mad.h
index 5aa3fd1..4c12450 100644
--- a/drivers/infiniband/hw/hfi1/mad.h
+++ b/drivers/infiniband/hw/hfi1/mad.h
@@ -1,5 +1,5 @@
/*
- * Copyright(c) 2015, 2016 Intel Corporation.
+ * Copyright(c) 2015 - 2017 Intel Corporation.
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
@@ -115,7 +115,7 @@ struct opa_mad_notice_attr {
__be32 lid; /* LID where change occurred */
__be32 new_cap_mask; /* new capability mask */
__be16 reserved2;
- __be16 cap_mask;
+ __be16 cap_mask3;
__be16 change_flags; /* low 4 bits only */
} __packed ntc_144;
@@ -428,5 +428,6 @@ struct sc2vlnt {
COUNTER_MASK(1, 4))
void hfi1_event_pkey_change(struct hfi1_devdata *dd, u8 port);
+void hfi1_handle_trap_timer(unsigned long data);
#endif /* _HFI1_MAD_H */
diff --git a/drivers/infiniband/hw/hfi1/mmu_rb.c b/drivers/infiniband/hw/hfi1/mmu_rb.c
index ccbf52c..2f0d285 100644
--- a/drivers/infiniband/hw/hfi1/mmu_rb.c
+++ b/drivers/infiniband/hw/hfi1/mmu_rb.c
@@ -1,5 +1,5 @@
/*
- * Copyright(c) 2016 Intel Corporation.
+ * Copyright(c) 2016 - 2017 Intel Corporation.
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
@@ -67,8 +67,6 @@ struct mmu_rb_handler {
static unsigned long mmu_node_start(struct mmu_rb_node *);
static unsigned long mmu_node_last(struct mmu_rb_node *);
-static inline void mmu_notifier_page(struct mmu_notifier *, struct mm_struct *,
- unsigned long);
static inline void mmu_notifier_range_start(struct mmu_notifier *,
struct mm_struct *,
unsigned long, unsigned long);
@@ -82,7 +80,6 @@ static void do_remove(struct mmu_rb_handler *handler,
static void handle_remove(struct work_struct *work);
static const struct mmu_notifier_ops mn_opts = {
- .invalidate_page = mmu_notifier_page,
.invalidate_range_start = mmu_notifier_range_start,
};
@@ -172,9 +169,8 @@ int hfi1_mmu_rb_insert(struct mmu_rb_handler *handler,
unsigned long flags;
int ret = 0;
+ trace_hfi1_mmu_rb_insert(mnode->addr, mnode->len);
spin_lock_irqsave(&handler->lock, flags);
- hfi1_cdbg(MMU, "Inserting node addr 0x%llx, len %u", mnode->addr,
- mnode->len);
node = __mmu_rb_search(handler, mnode->addr, mnode->len);
if (node) {
ret = -EINVAL;
@@ -200,7 +196,7 @@ static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *handler,
{
struct mmu_rb_node *node = NULL;
- hfi1_cdbg(MMU, "Searching for addr 0x%llx, len %u", addr, len);
+ trace_hfi1_mmu_rb_search(addr, len);
if (!handler->ops->filter) {
node = __mmu_int_rb_iter_first(&handler->root, addr,
(addr + len) - 1);
@@ -217,21 +213,27 @@ static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *handler,
return node;
}
-struct mmu_rb_node *hfi1_mmu_rb_extract(struct mmu_rb_handler *handler,
- unsigned long addr, unsigned long len)
+bool hfi1_mmu_rb_remove_unless_exact(struct mmu_rb_handler *handler,
+ unsigned long addr, unsigned long len,
+ struct mmu_rb_node **rb_node)
{
struct mmu_rb_node *node;
unsigned long flags;
+ bool ret = false;
spin_lock_irqsave(&handler->lock, flags);
node = __mmu_rb_search(handler, addr, len);
if (node) {
+ if (node->addr == addr && node->len == len)
+ goto unlock;
__mmu_int_rb_remove(node, &handler->root);
list_del(&node->list); /* remove from LRU list */
+ ret = true;
}
+unlock:
spin_unlock_irqrestore(&handler->lock, flags);
-
- return node;
+ *rb_node = node;
+ return ret;
}
void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg)
@@ -275,8 +277,7 @@ void hfi1_mmu_rb_remove(struct mmu_rb_handler *handler,
unsigned long flags;
/* Validity of handler and node pointers has been checked by caller. */
- hfi1_cdbg(MMU, "Removing node addr 0x%llx, len %u", node->addr,
- node->len);
+ trace_hfi1_mmu_rb_remove(node->addr, node->len);
spin_lock_irqsave(&handler->lock, flags);
__mmu_int_rb_remove(node, &handler->root);
list_del(&node->list); /* remove from LRU list */
@@ -285,12 +286,6 @@ void hfi1_mmu_rb_remove(struct mmu_rb_handler *handler,
handler->ops->remove(handler->ops_arg, node);
}
-static inline void mmu_notifier_page(struct mmu_notifier *mn,
- struct mm_struct *mm, unsigned long addr)
-{
- mmu_notifier_mem_invalidate(mn, mm, addr, addr + PAGE_SIZE);
-}
-
static inline void mmu_notifier_range_start(struct mmu_notifier *mn,
struct mm_struct *mm,
unsigned long start,
@@ -315,8 +310,7 @@ static void mmu_notifier_mem_invalidate(struct mmu_notifier *mn,
node; node = ptr) {
/* Guard against node removal. */
ptr = __mmu_int_rb_iter_next(node, start, end - 1);
- hfi1_cdbg(MMU, "Invalidating node addr 0x%llx, len %u",
- node->addr, node->len);
+ trace_hfi1_mmu_mem_invalidate(node->addr, node->len);
if (handler->ops->invalidate(handler->ops_arg, node)) {
__mmu_int_rb_remove(node, root);
/* move from LRU list to delete list */
diff --git a/drivers/infiniband/hw/hfi1/mmu_rb.h b/drivers/infiniband/hw/hfi1/mmu_rb.h
index 754f6eb..f04cec1 100644
--- a/drivers/infiniband/hw/hfi1/mmu_rb.h
+++ b/drivers/infiniband/hw/hfi1/mmu_rb.h
@@ -81,7 +81,8 @@ int hfi1_mmu_rb_insert(struct mmu_rb_handler *handler,
void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg);
void hfi1_mmu_rb_remove(struct mmu_rb_handler *handler,
struct mmu_rb_node *mnode);
-struct mmu_rb_node *hfi1_mmu_rb_extract(struct mmu_rb_handler *handler,
- unsigned long addr, unsigned long len);
+bool hfi1_mmu_rb_remove_unless_exact(struct mmu_rb_handler *handler,
+ unsigned long addr, unsigned long len,
+ struct mmu_rb_node **rb_node);
#endif /* _HFI1_MMU_RB_H */
diff --git a/drivers/infiniband/hw/hfi1/opa_compat.h b/drivers/infiniband/hw/hfi1/opa_compat.h
index 6ef3c1c..774215b 100644
--- a/drivers/infiniband/hw/hfi1/opa_compat.h
+++ b/drivers/infiniband/hw/hfi1/opa_compat.h
@@ -84,7 +84,8 @@ static inline u8 port_states_to_phys_state(struct opa_port_states *ps)
/*
* OPA port physical states
* IB Volume 1, Table 146 PortInfo/IB Volume 2 Section 5.4.2(1) PortPhysState
- * values.
+ * values are the same in OmniPath Architecture. OPA leverages some of the same
+ * concepts as InfiniBand, but has a few other states as well.
*
* When writing, only values 0-3 are valid, other values are ignored.
* When reading, 0 is reserved.
@@ -92,6 +93,8 @@ static inline u8 port_states_to_phys_state(struct opa_port_states *ps)
* Returned by the ibphys_portstate() routine.
*/
enum opa_port_phys_state {
+ /* Values 0-7 have the same meaning in OPA as in InfiniBand. */
+
IB_PORTPHYSSTATE_NOP = 0,
/* 1 is reserved */
IB_PORTPHYSSTATE_POLLING = 2,
@@ -101,9 +104,23 @@ enum opa_port_phys_state {
IB_PORTPHYSSTATE_LINK_ERROR_RECOVERY = 6,
IB_PORTPHYSSTATE_PHY_TEST = 7,
/* 8 is reserved */
+
+ /*
+ * Offline: Port is quiet (transmitters disabled) due to lack of
+ * physical media, unsupported media, or transition between link up
+ * and next link up attempt
+ */
OPA_PORTPHYSSTATE_OFFLINE = 9,
- OPA_PORTPHYSSTATE_GANGED = 10,
+
+ /* 10 is reserved */
+
+ /*
+ * Phy_Test: Specific test patterns are transmitted, and receiver BER
+ * can be monitored. This facilitates signal integrity testing for the
+ * physical layer of the port.
+ */
OPA_PORTPHYSSTATE_TEST = 11,
+
OPA_PORTPHYSSTATE_MAX = 11,
/* values 12-15 are reserved/ignored */
};
diff --git a/drivers/infiniband/hw/hfi1/pcie.c b/drivers/infiniband/hw/hfi1/pcie.c
index 6a9f6f9..82447b7 100644
--- a/drivers/infiniband/hw/hfi1/pcie.c
+++ b/drivers/infiniband/hw/hfi1/pcie.c
@@ -1,5 +1,5 @@
/*
- * Copyright(c) 2015, 2016 Intel Corporation.
+ * Copyright(c) 2015 - 2017 Intel Corporation.
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
@@ -68,7 +68,7 @@
/*
* Code to adjust PCIe capabilities.
*/
-static void tune_pcie_caps(struct hfi1_devdata *);
+static int tune_pcie_caps(struct hfi1_devdata *);
/*
* Do all the common PCIe setup and initialization.
@@ -161,6 +161,7 @@ int hfi1_pcie_ddinit(struct hfi1_devdata *dd, struct pci_dev *pdev)
{
unsigned long len;
resource_size_t addr;
+ int ret = 0;
dd->pcidev = pdev;
pci_set_drvdata(pdev, dd);
@@ -179,47 +180,54 @@ int hfi1_pcie_ddinit(struct hfi1_devdata *dd, struct pci_dev *pdev)
return -EINVAL;
}
- dd->kregbase = ioremap_nocache(addr, TXE_PIO_SEND);
- if (!dd->kregbase)
+ dd->kregbase1 = ioremap_nocache(addr, RCV_ARRAY);
+ if (!dd->kregbase1) {
+ dd_dev_err(dd, "UC mapping of kregbase1 failed\n");
return -ENOMEM;
+ }
+ dd_dev_info(dd, "UC base1: %p for %x\n", dd->kregbase1, RCV_ARRAY);
+ dd->chip_rcv_array_count = readq(dd->kregbase1 + RCV_ARRAY_CNT);
+ dd_dev_info(dd, "RcvArray count: %u\n", dd->chip_rcv_array_count);
+ dd->base2_start = RCV_ARRAY + dd->chip_rcv_array_count * 8;
+
+ dd->kregbase2 = ioremap_nocache(
+ addr + dd->base2_start,
+ TXE_PIO_SEND - dd->base2_start);
+ if (!dd->kregbase2) {
+ dd_dev_err(dd, "UC mapping of kregbase2 failed\n");
+ goto nomem;
+ }
+ dd_dev_info(dd, "UC base2: %p for %x\n", dd->kregbase2,
+ TXE_PIO_SEND - dd->base2_start);
dd->piobase = ioremap_wc(addr + TXE_PIO_SEND, TXE_PIO_SIZE);
if (!dd->piobase) {
- iounmap(dd->kregbase);
- return -ENOMEM;
+ dd_dev_err(dd, "WC mapping of send buffers failed\n");
+ goto nomem;
}
+ dd_dev_info(dd, "WC piobase: %p\n for %x", dd->piobase, TXE_PIO_SIZE);
- dd->flags |= HFI1_PRESENT; /* now register routines work */
-
- dd->kregend = dd->kregbase + TXE_PIO_SEND;
dd->physaddr = addr; /* used for io_remap, etc. */
/*
- * Re-map the chip's RcvArray as write-combining to allow us
+ * Map the chip's RcvArray as write-combining to allow us
* to write an entire cacheline worth of entries in one shot.
- * If this re-map fails, just continue - the RcvArray programming
- * function will handle both cases.
*/
- dd->chip_rcv_array_count = read_csr(dd, RCV_ARRAY_CNT);
dd->rcvarray_wc = ioremap_wc(addr + RCV_ARRAY,
dd->chip_rcv_array_count * 8);
- dd_dev_info(dd, "WC Remapped RcvArray: %p\n", dd->rcvarray_wc);
- /*
- * Save BARs and command to rewrite after device reset.
- */
- pci_read_config_dword(dd->pcidev, PCI_BASE_ADDRESS_0, &dd->pcibar0);
- pci_read_config_dword(dd->pcidev, PCI_BASE_ADDRESS_1, &dd->pcibar1);
- pci_read_config_dword(dd->pcidev, PCI_ROM_ADDRESS, &dd->pci_rom);
- pci_read_config_word(dd->pcidev, PCI_COMMAND, &dd->pci_command);
- pcie_capability_read_word(dd->pcidev, PCI_EXP_DEVCTL, &dd->pcie_devctl);
- pcie_capability_read_word(dd->pcidev, PCI_EXP_LNKCTL, &dd->pcie_lnkctl);
- pcie_capability_read_word(dd->pcidev, PCI_EXP_DEVCTL2,
- &dd->pcie_devctl2);
- pci_read_config_dword(dd->pcidev, PCI_CFG_MSIX0, &dd->pci_msix0);
- pci_read_config_dword(dd->pcidev, PCIE_CFG_SPCIE1, &dd->pci_lnkctl3);
- pci_read_config_dword(dd->pcidev, PCIE_CFG_TPH2, &dd->pci_tph2);
+ if (!dd->rcvarray_wc) {
+ dd_dev_err(dd, "WC mapping of receive array failed\n");
+ goto nomem;
+ }
+ dd_dev_info(dd, "WC RcvArray: %p for %x\n",
+ dd->rcvarray_wc, dd->chip_rcv_array_count * 8);
+ dd->flags |= HFI1_PRESENT; /* chip.c CSR routines now work */
return 0;
+nomem:
+ ret = -ENOMEM;
+ hfi1_pcie_ddcleanup(dd);
+ return ret;
}
/*
@@ -229,59 +237,19 @@ int hfi1_pcie_ddinit(struct hfi1_devdata *dd, struct pci_dev *pdev)
*/
void hfi1_pcie_ddcleanup(struct hfi1_devdata *dd)
{
- u64 __iomem *base = (void __iomem *)dd->kregbase;
-
dd->flags &= ~HFI1_PRESENT;
- dd->kregbase = NULL;
- iounmap(base);
+ if (dd->kregbase1)
+ iounmap(dd->kregbase1);
+ dd->kregbase1 = NULL;
+ if (dd->kregbase2)
+ iounmap(dd->kregbase2);
+ dd->kregbase2 = NULL;
if (dd->rcvarray_wc)
iounmap(dd->rcvarray_wc);
+ dd->rcvarray_wc = NULL;
if (dd->piobase)
iounmap(dd->piobase);
-}
-
-static void msix_setup(struct hfi1_devdata *dd, int pos, u32 *msixcnt,
- struct hfi1_msix_entry *hfi1_msix_entry)
-{
- int ret;
- int nvec = *msixcnt;
- struct msix_entry *msix_entry;
- int i;
-
- /*
- * We can't pass hfi1_msix_entry array to msix_setup
- * so use a dummy msix_entry array and copy the allocated
- * irq back to the hfi1_msix_entry array.
- */
- msix_entry = kmalloc_array(nvec, sizeof(*msix_entry), GFP_KERNEL);
- if (!msix_entry) {
- ret = -ENOMEM;
- goto do_intx;
- }
-
- for (i = 0; i < nvec; i++)
- msix_entry[i] = hfi1_msix_entry[i].msix;
-
- ret = pci_enable_msix_range(dd->pcidev, msix_entry, 1, nvec);
- if (ret < 0)
- goto free_msix_entry;
- nvec = ret;
-
- for (i = 0; i < nvec; i++)
- hfi1_msix_entry[i].msix = msix_entry[i];
-
- kfree(msix_entry);
- *msixcnt = nvec;
- return;
-
-free_msix_entry:
- kfree(msix_entry);
-
-do_intx:
- dd_dev_err(dd, "pci_enable_msix_range %d vectors failed: %d, falling back to INTx\n",
- nvec, ret);
- *msixcnt = 0;
- hfi1_enable_intx(dd->pcidev);
+ dd->piobase = NULL;
}
/* return the PCIe link speed from the given link status */
@@ -314,8 +282,14 @@ static u32 extract_width(u16 linkstat)
static void update_lbus_info(struct hfi1_devdata *dd)
{
u16 linkstat;
+ int ret;
+
+ ret = pcie_capability_read_word(dd->pcidev, PCI_EXP_LNKSTA, &linkstat);
+ if (ret) {
+ dd_dev_err(dd, "Unable to read from PCI config\n");
+ return;
+ }
- pcie_capability_read_word(dd->pcidev, PCI_EXP_LNKSTA, &linkstat);
dd->lbus_width = extract_width(linkstat);
dd->lbus_speed = extract_speed(linkstat);
snprintf(dd->lbus_info, sizeof(dd->lbus_info),
@@ -330,6 +304,7 @@ int pcie_speeds(struct hfi1_devdata *dd)
{
u32 linkcap;
struct pci_dev *parent = dd->pcidev->bus->self;
+ int ret;
if (!pci_is_pcie(dd->pcidev)) {
dd_dev_err(dd, "Can't find PCI Express capability!\n");
@@ -339,7 +314,12 @@ int pcie_speeds(struct hfi1_devdata *dd)
/* find if our max speed is Gen3 and parent supports Gen3 speeds */
dd->link_gen3_capable = 1;
- pcie_capability_read_dword(dd->pcidev, PCI_EXP_LNKCAP, &linkcap);
+ ret = pcie_capability_read_dword(dd->pcidev, PCI_EXP_LNKCAP, &linkcap);
+ if (ret) {
+ dd_dev_err(dd, "Unable to read from PCI config\n");
+ return ret;
+ }
+
if ((linkcap & PCI_EXP_LNKCAP_SLS) != GEN3_SPEED_VECTOR) {
dd_dev_info(dd,
"This HFI is not Gen3 capable, max speed 0x%x, need 0x3\n",
@@ -364,49 +344,150 @@ int pcie_speeds(struct hfi1_devdata *dd)
}
/*
- * Returns in *nent:
- * - actual number of interrupts allocated
+ * Returns:
+ * - actual number of interrupts allocated or
* - 0 if fell back to INTx.
+ * - error
*/
-void request_msix(struct hfi1_devdata *dd, u32 *nent,
- struct hfi1_msix_entry *entry)
+int request_msix(struct hfi1_devdata *dd, u32 msireq)
{
- int pos;
+ int nvec, ret;
- pos = dd->pcidev->msix_cap;
- if (*nent && pos) {
- msix_setup(dd, pos, nent, entry);
- /* did it, either MSI-X or INTx */
- } else {
- *nent = 0;
- hfi1_enable_intx(dd->pcidev);
+ nvec = pci_alloc_irq_vectors(dd->pcidev, 1, msireq,
+ PCI_IRQ_MSIX | PCI_IRQ_LEGACY);
+ if (nvec < 0) {
+ dd_dev_err(dd, "pci_alloc_irq_vectors() failed: %d\n", nvec);
+ return nvec;
}
- tune_pcie_caps(dd);
+ ret = tune_pcie_caps(dd);
+ if (ret) {
+ dd_dev_err(dd, "tune_pcie_caps() failed: %d\n", ret);
+ pci_free_irq_vectors(dd->pcidev);
+ return ret;
+ }
+
+ /* check for legacy IRQ */
+ if (nvec == 1 && !dd->pcidev->msix_enabled)
+ return 0;
+
+ return nvec;
}
-void hfi1_enable_intx(struct pci_dev *pdev)
+/* restore command and BARs after a reset has wiped them out */
+int restore_pci_variables(struct hfi1_devdata *dd)
{
- /* first, turn on INTx */
- pci_intx(pdev, 1);
- /* then turn off MSI-X */
- pci_disable_msix(pdev);
+ int ret = 0;
+
+ ret = pci_write_config_word(dd->pcidev, PCI_COMMAND, dd->pci_command);
+ if (ret)
+ goto error;
+
+ ret = pci_write_config_dword(dd->pcidev, PCI_BASE_ADDRESS_0,
+ dd->pcibar0);
+ if (ret)
+ goto error;
+
+ ret = pci_write_config_dword(dd->pcidev, PCI_BASE_ADDRESS_1,
+ dd->pcibar1);
+ if (ret)
+ goto error;
+
+ ret = pci_write_config_dword(dd->pcidev, PCI_ROM_ADDRESS, dd->pci_rom);
+ if (ret)
+ goto error;
+
+ ret = pcie_capability_write_word(dd->pcidev, PCI_EXP_DEVCTL,
+ dd->pcie_devctl);
+ if (ret)
+ goto error;
+
+ ret = pcie_capability_write_word(dd->pcidev, PCI_EXP_LNKCTL,
+ dd->pcie_lnkctl);
+ if (ret)
+ goto error;
+
+ ret = pcie_capability_write_word(dd->pcidev, PCI_EXP_DEVCTL2,
+ dd->pcie_devctl2);
+ if (ret)
+ goto error;
+
+ ret = pci_write_config_dword(dd->pcidev, PCI_CFG_MSIX0, dd->pci_msix0);
+ if (ret)
+ goto error;
+
+ ret = pci_write_config_dword(dd->pcidev, PCIE_CFG_SPCIE1,
+ dd->pci_lnkctl3);
+ if (ret)
+ goto error;
+
+ ret = pci_write_config_dword(dd->pcidev, PCIE_CFG_TPH2, dd->pci_tph2);
+ if (ret)
+ goto error;
+
+ return 0;
+
+error:
+ dd_dev_err(dd, "Unable to write to PCI config\n");
+ return ret;
}
-/* restore command and BARs after a reset has wiped them out */
-void restore_pci_variables(struct hfi1_devdata *dd)
+/* Save BARs and command to rewrite after device reset */
+int save_pci_variables(struct hfi1_devdata *dd)
{
- pci_write_config_word(dd->pcidev, PCI_COMMAND, dd->pci_command);
- pci_write_config_dword(dd->pcidev, PCI_BASE_ADDRESS_0, dd->pcibar0);
- pci_write_config_dword(dd->pcidev, PCI_BASE_ADDRESS_1, dd->pcibar1);
- pci_write_config_dword(dd->pcidev, PCI_ROM_ADDRESS, dd->pci_rom);
- pcie_capability_write_word(dd->pcidev, PCI_EXP_DEVCTL, dd->pcie_devctl);
- pcie_capability_write_word(dd->pcidev, PCI_EXP_LNKCTL, dd->pcie_lnkctl);
- pcie_capability_write_word(dd->pcidev, PCI_EXP_DEVCTL2,
- dd->pcie_devctl2);
- pci_write_config_dword(dd->pcidev, PCI_CFG_MSIX0, dd->pci_msix0);
- pci_write_config_dword(dd->pcidev, PCIE_CFG_SPCIE1, dd->pci_lnkctl3);
- pci_write_config_dword(dd->pcidev, PCIE_CFG_TPH2, dd->pci_tph2);
+ int ret = 0;
+
+ ret = pci_read_config_dword(dd->pcidev, PCI_BASE_ADDRESS_0,
+ &dd->pcibar0);
+ if (ret)
+ goto error;
+
+ ret = pci_read_config_dword(dd->pcidev, PCI_BASE_ADDRESS_1,
+ &dd->pcibar1);
+ if (ret)
+ goto error;
+
+ ret = pci_read_config_dword(dd->pcidev, PCI_ROM_ADDRESS, &dd->pci_rom);
+ if (ret)
+ goto error;
+
+ ret = pci_read_config_word(dd->pcidev, PCI_COMMAND, &dd->pci_command);
+ if (ret)
+ goto error;
+
+ ret = pcie_capability_read_word(dd->pcidev, PCI_EXP_DEVCTL,
+ &dd->pcie_devctl);
+ if (ret)
+ goto error;
+
+ ret = pcie_capability_read_word(dd->pcidev, PCI_EXP_LNKCTL,
+ &dd->pcie_lnkctl);
+ if (ret)
+ goto error;
+
+ ret = pcie_capability_read_word(dd->pcidev, PCI_EXP_DEVCTL2,
+ &dd->pcie_devctl2);
+ if (ret)
+ goto error;
+
+ ret = pci_read_config_dword(dd->pcidev, PCI_CFG_MSIX0, &dd->pci_msix0);
+ if (ret)
+ goto error;
+
+ ret = pci_read_config_dword(dd->pcidev, PCIE_CFG_SPCIE1,
+ &dd->pci_lnkctl3);
+ if (ret)
+ goto error;
+
+ ret = pci_read_config_dword(dd->pcidev, PCIE_CFG_TPH2, &dd->pci_tph2);
+ if (ret)
+ goto error;
+
+ return 0;
+
+error:
+ dd_dev_err(dd, "Unable to read from PCI config\n");
+ return ret;
}
/*
@@ -421,21 +502,33 @@ uint aspm_mode = ASPM_MODE_DISABLED;
module_param_named(aspm, aspm_mode, uint, S_IRUGO);
MODULE_PARM_DESC(aspm, "PCIe ASPM: 0: disable, 1: enable, 2: dynamic");
-static void tune_pcie_caps(struct hfi1_devdata *dd)
+static int tune_pcie_caps(struct hfi1_devdata *dd)
{
struct pci_dev *parent;
u16 rc_mpss, rc_mps, ep_mpss, ep_mps;
u16 rc_mrrs, ep_mrrs, max_mrrs, ectl;
+ int ret;
/*
* Turn on extended tags in DevCtl in case the BIOS has turned it off
* to improve WFR SDMA bandwidth
*/
- pcie_capability_read_word(dd->pcidev, PCI_EXP_DEVCTL, &ectl);
+ ret = pcie_capability_read_word(dd->pcidev,
+ PCI_EXP_DEVCTL, &ectl);
+ if (ret) {
+ dd_dev_err(dd, "Unable to read from PCI config\n");
+ return ret;
+ }
+
if (!(ectl & PCI_EXP_DEVCTL_EXT_TAG)) {
dd_dev_info(dd, "Enabling PCIe extended tags\n");
ectl |= PCI_EXP_DEVCTL_EXT_TAG;
- pcie_capability_write_word(dd->pcidev, PCI_EXP_DEVCTL, ectl);
+ ret = pcie_capability_write_word(dd->pcidev,
+ PCI_EXP_DEVCTL, ectl);
+ if (ret) {
+ dd_dev_err(dd, "Unable to write to PCI config\n");
+ return ret;
+ }
}
/* Find out supported and configured values for parent (root) */
parent = dd->pcidev->bus->self;
@@ -444,14 +537,14 @@ static void tune_pcie_caps(struct hfi1_devdata *dd)
* access to the upstream component.
*/
if (!parent)
- return;
+ return -EINVAL;
if (!pci_is_root_bus(parent->bus)) {
dd_dev_info(dd, "Parent not root\n");
- return;
+ return -EINVAL;
}
if (!pci_is_pcie(parent) || !pci_is_pcie(dd->pcidev))
- return;
+ return -EINVAL;
rc_mpss = parent->pcie_mpss;
rc_mps = ffs(pcie_get_mps(parent)) - 8;
/* Find out supported and configured values for endpoint (us) */
@@ -497,6 +590,8 @@ static void tune_pcie_caps(struct hfi1_devdata *dd)
ep_mrrs = max_mrrs;
pcie_set_readrq(dd->pcidev, ep_mrrs);
}
+
+ return 0;
}
/* End of PCIe capability tuning */
@@ -728,6 +823,7 @@ static int load_eq_table(struct hfi1_devdata *dd, const u8 eq[11][3], u8 fs,
u32 violation;
u32 i;
u8 c_minus1, c0, c_plus1;
+ int ret;
for (i = 0; i < 11; i++) {
/* set index */
@@ -739,8 +835,14 @@ static int load_eq_table(struct hfi1_devdata *dd, const u8 eq[11][3], u8 fs,
pci_write_config_dword(pdev, PCIE_CFG_REG_PL102,
eq_value(c_minus1, c0, c_plus1));
/* check if these coefficients violate EQ rules */
- pci_read_config_dword(dd->pcidev, PCIE_CFG_REG_PL105,
- &violation);
+ ret = pci_read_config_dword(dd->pcidev,
+ PCIE_CFG_REG_PL105, &violation);
+ if (ret) {
+ dd_dev_err(dd, "Unable to read from PCI config\n");
+ hit_error = 1;
+ break;
+ }
+
if (violation
& PCIE_CFG_REG_PL105_GEN3_EQ_VIOLATE_COEF_RULES_SMASK){
if (hit_error == 0) {
@@ -1194,7 +1296,13 @@ retry:
* that it is Gen3 capable earlier.
*/
dd_dev_info(dd, "%s: setting parent target link speed\n", __func__);
- pcie_capability_read_word(parent, PCI_EXP_LNKCTL2, &lnkctl2);
+ ret = pcie_capability_read_word(parent, PCI_EXP_LNKCTL2, &lnkctl2);
+ if (ret) {
+ dd_dev_err(dd, "Unable to read from PCI config\n");
+ return_error = 1;
+ goto done;
+ }
+
dd_dev_info(dd, "%s: ..old link control2: 0x%x\n", __func__,
(u32)lnkctl2);
/* only write to parent if target is not as high as ours */
@@ -1203,20 +1311,37 @@ retry:
lnkctl2 |= target_vector;
dd_dev_info(dd, "%s: ..new link control2: 0x%x\n", __func__,
(u32)lnkctl2);
- pcie_capability_write_word(parent, PCI_EXP_LNKCTL2, lnkctl2);
+ ret = pcie_capability_write_word(parent,
+ PCI_EXP_LNKCTL2, lnkctl2);
+ if (ret) {
+ dd_dev_err(dd, "Unable to write to PCI config\n");
+ return_error = 1;
+ goto done;
+ }
} else {
dd_dev_info(dd, "%s: ..target speed is OK\n", __func__);
}
dd_dev_info(dd, "%s: setting target link speed\n", __func__);
- pcie_capability_read_word(dd->pcidev, PCI_EXP_LNKCTL2, &lnkctl2);
+ ret = pcie_capability_read_word(dd->pcidev, PCI_EXP_LNKCTL2, &lnkctl2);
+ if (ret) {
+ dd_dev_err(dd, "Unable to read from PCI config\n");
+ return_error = 1;
+ goto done;
+ }
+
dd_dev_info(dd, "%s: ..old link control2: 0x%x\n", __func__,
(u32)lnkctl2);
lnkctl2 &= ~LNKCTL2_TARGET_LINK_SPEED_MASK;
lnkctl2 |= target_vector;
dd_dev_info(dd, "%s: ..new link control2: 0x%x\n", __func__,
(u32)lnkctl2);
- pcie_capability_write_word(dd->pcidev, PCI_EXP_LNKCTL2, lnkctl2);
+ ret = pcie_capability_write_word(dd->pcidev, PCI_EXP_LNKCTL2, lnkctl2);
+ if (ret) {
+ dd_dev_err(dd, "Unable to write to PCI config\n");
+ return_error = 1;
+ goto done;
+ }
/* step 5h: arm gasket logic */
/* hold DC in reset across the SBR */
@@ -1266,7 +1391,14 @@ retry:
/* restore PCI space registers we know were reset */
dd_dev_info(dd, "%s: calling restore_pci_variables\n", __func__);
- restore_pci_variables(dd);
+ ret = restore_pci_variables(dd);
+ if (ret) {
+ dd_dev_err(dd, "%s: Could not restore PCI variables\n",
+ __func__);
+ return_error = 1;
+ goto done;
+ }
+
/* restore firmware control */
write_csr(dd, MISC_CFG_FW_CTRL, fw_ctrl);
@@ -1296,7 +1428,13 @@ retry:
setextled(dd, 0);
/* check for any per-lane errors */
- pci_read_config_dword(dd->pcidev, PCIE_CFG_SPCIE2, &reg32);
+ ret = pci_read_config_dword(dd->pcidev, PCIE_CFG_SPCIE2, &reg32);
+ if (ret) {
+ dd_dev_err(dd, "Unable to read from PCI config\n");
+ return_error = 1;
+ goto done;
+ }
+
dd_dev_info(dd, "%s: per-lane errors: 0x%x\n", __func__, reg32);
/* extract status, look for our HFI */
diff --git a/drivers/infiniband/hw/hfi1/pio.c b/drivers/infiniband/hw/hfi1/pio.c
index ed72b5a..7108a4b 100644
--- a/drivers/infiniband/hw/hfi1/pio.c
+++ b/drivers/infiniband/hw/hfi1/pio.c
@@ -1012,7 +1012,7 @@ static void sc_wait_for_packet_egress(struct send_context *sc, int pause)
"%s: context %u(%u) timeout waiting for packets to egress, remaining count %u, bouncing link\n",
__func__, sc->sw_index,
sc->hw_context, (u32)reg);
- queue_work(dd->pport->hfi1_wq,
+ queue_work(dd->pport->link_wq,
&dd->pport->link_bounce_work);
break;
}
@@ -1568,7 +1568,8 @@ static void sc_piobufavail(struct send_context *sc)
struct rvt_qp *qp;
struct hfi1_qp_priv *priv;
unsigned long flags;
- unsigned i, n = 0;
+ uint i, n = 0, max_idx = 0;
+ u8 max_starved_cnt = 0;
if (dd->send_contexts[sc->sw_index].type != SC_KERNEL &&
dd->send_contexts[sc->sw_index].type != SC_VL15)
@@ -1591,6 +1592,7 @@ static void sc_piobufavail(struct send_context *sc)
priv = qp->priv;
list_del_init(&priv->s_iowait.list);
priv->s_iowait.lock = NULL;
+ iowait_starve_find_max(wait, &max_starved_cnt, n, &max_idx);
/* refcount held until actual wake up */
qps[n++] = qp;
}
@@ -1605,9 +1607,14 @@ static void sc_piobufavail(struct send_context *sc)
}
write_sequnlock_irqrestore(&dev->iowait_lock, flags);
- for (i = 0; i < n; i++)
- hfi1_qp_wakeup(qps[i],
+ /* Wake up the most starved one first */
+ if (n)
+ hfi1_qp_wakeup(qps[max_idx],
RVT_S_WAIT_PIO | RVT_S_WAIT_PIO_DRAIN);
+ for (i = 0; i < n; i++)
+ if (i != max_idx)
+ hfi1_qp_wakeup(qps[i],
+ RVT_S_WAIT_PIO | RVT_S_WAIT_PIO_DRAIN);
}
/* translate a send credit update to a bit code of reasons */
diff --git a/drivers/infiniband/hw/hfi1/platform.c b/drivers/infiniband/hw/hfi1/platform.c
index 838fe84..a8af96d 100644
--- a/drivers/infiniband/hw/hfi1/platform.c
+++ b/drivers/infiniband/hw/hfi1/platform.c
@@ -45,10 +45,14 @@
*
*/
+#include <linux/firmware.h>
+
#include "hfi.h"
#include "efivar.h"
#include "eprom.h"
+#define DEFAULT_PLATFORM_CONFIG_NAME "hfi1_platform.dat"
+
static int validate_scratch_checksum(struct hfi1_devdata *dd)
{
u64 checksum = 0, temp_scratch = 0;
@@ -58,8 +62,13 @@ static int validate_scratch_checksum(struct hfi1_devdata *dd)
version = (temp_scratch & BITMAP_VERSION_SMASK) >> BITMAP_VERSION_SHIFT;
/* Prevent power on default of all zeroes from passing checksum */
- if (!version)
+ if (!version) {
+ dd_dev_err(dd, "%s: Config bitmap uninitialized\n", __func__);
+ dd_dev_err(dd,
+ "%s: Please update your BIOS to support active channels\n",
+ __func__);
return 0;
+ }
/*
* ASIC scratch 0 only contains the checksum and bitmap version as
@@ -84,6 +93,8 @@ static int validate_scratch_checksum(struct hfi1_devdata *dd)
if (checksum + temp_scratch == 0xFFFF)
return 1;
+
+ dd_dev_err(dd, "%s: Configuration bitmap corrupted\n", __func__);
return 0;
}
@@ -131,25 +142,22 @@ static void save_platform_config_fields(struct hfi1_devdata *dd)
ppd->max_power_class = (temp_scratch & QSFP_MAX_POWER_SMASK) >>
QSFP_MAX_POWER_SHIFT;
+
+ ppd->config_from_scratch = true;
}
void get_platform_config(struct hfi1_devdata *dd)
{
int ret = 0;
- unsigned long size = 0;
u8 *temp_platform_config = NULL;
u32 esize;
+ const struct firmware *platform_config_file = NULL;
if (is_integrated(dd)) {
if (validate_scratch_checksum(dd)) {
save_platform_config_fields(dd);
return;
}
- dd_dev_err(dd, "%s: Config bitmap corrupted/uninitialized\n",
- __func__);
- dd_dev_err(dd,
- "%s: Please update your BIOS to support active channels\n",
- __func__);
} else {
ret = eprom_read_platform_config(dd,
(void **)&temp_platform_config,
@@ -160,36 +168,37 @@ void get_platform_config(struct hfi1_devdata *dd)
dd->platform_config.size = esize;
return;
}
- /* fail, try EFI variable */
-
- ret = read_hfi1_efi_var(dd, "configuration", &size,
- (void **)&temp_platform_config);
- if (!ret) {
- dd->platform_config.data = temp_platform_config;
- dd->platform_config.size = size;
- return;
- }
}
dd_dev_err(dd,
"%s: Failed to get platform config, falling back to sub-optimal default file\n",
__func__);
- /* fall back to request firmware */
- platform_config_load = 1;
-}
-void free_platform_config(struct hfi1_devdata *dd)
-{
- if (!platform_config_load) {
- /*
- * was loaded from EFI or the EPROM, release memory
- * allocated by read_efi_var/eprom_read_platform_config
- */
- kfree(dd->platform_config.data);
+ ret = request_firmware(&platform_config_file,
+ DEFAULT_PLATFORM_CONFIG_NAME,
+ &dd->pcidev->dev);
+ if (ret) {
+ dd_dev_err(dd,
+ "%s: No default platform config file found\n",
+ __func__);
+ return;
}
+
/*
- * else do nothing, dispose_firmware will release
- * struct firmware platform_config on driver exit
+ * Allocate separate memory block to store data and free firmware
+ * structure. This allows free_platform_config to treat EPROM and
+ * fallback configs in the same manner.
*/
+ dd->platform_config.data = kmemdup(platform_config_file->data,
+ platform_config_file->size,
+ GFP_KERNEL);
+ dd->platform_config.size = platform_config_file->size;
+ release_firmware(platform_config_file);
+}
+
+void free_platform_config(struct hfi1_devdata *dd)
+{
+ /* Release memory allocated for eprom or fallback file read. */
+ kfree(dd->platform_config.data);
}
void get_port_type(struct hfi1_pportdata *ppd)
@@ -242,7 +251,7 @@ static int qual_power(struct hfi1_pportdata *ppd)
if (ppd->offline_disabled_reason ==
HFI1_ODR_MASK(OPA_LINKDOWN_REASON_POWER_POLICY)) {
- dd_dev_info(
+ dd_dev_err(
ppd->dd,
"%s: Port disabled due to system power restrictions\n",
__func__);
@@ -268,7 +277,7 @@ static int qual_bitrate(struct hfi1_pportdata *ppd)
if (ppd->offline_disabled_reason ==
HFI1_ODR_MASK(OPA_LINKDOWN_REASON_LINKSPEED_POLICY)) {
- dd_dev_info(
+ dd_dev_err(
ppd->dd,
"%s: Cable failed bitrate check, disabling port\n",
__func__);
@@ -709,15 +718,15 @@ static void apply_tunings(
ret = load_8051_config(ppd->dd, DC_HOST_COMM_SETTINGS,
GENERAL_CONFIG, config_data);
if (ret != HCMD_SUCCESS)
- dd_dev_info(ppd->dd,
- "%s: Failed set ext device config params\n",
- __func__);
+ dd_dev_err(ppd->dd,
+ "%s: Failed set ext device config params\n",
+ __func__);
}
if (tx_preset_index == OPA_INVALID_INDEX) {
if (ppd->port_type == PORT_TYPE_QSFP && limiting_active)
- dd_dev_info(ppd->dd, "%s: Invalid Tx preset index\n",
- __func__);
+ dd_dev_err(ppd->dd, "%s: Invalid Tx preset index\n",
+ __func__);
return;
}
@@ -900,7 +909,7 @@ static int tune_qsfp(struct hfi1_pportdata *ppd,
case 0xD: /* fallthrough */
case 0xF:
default:
- dd_dev_info(ppd->dd, "%s: Unknown/unsupported cable\n",
+ dd_dev_warn(ppd->dd, "%s: Unknown/unsupported cable\n",
__func__);
break;
}
@@ -935,6 +944,21 @@ void tune_serdes(struct hfi1_pportdata *ppd)
if (loopback != LOOPBACK_NONE ||
ppd->dd->icode == ICODE_FUNCTIONAL_SIMULATOR) {
ppd->driver_link_ready = 1;
+
+ if (qsfp_mod_present(ppd)) {
+ ret = acquire_chip_resource(ppd->dd,
+ qsfp_resource(ppd->dd),
+ QSFP_WAIT);
+ if (ret) {
+ dd_dev_err(ppd->dd, "%s: hfi%d: cannot lock i2c chain\n",
+ __func__, (int)ppd->dd->hfi1_id);
+ goto bail;
+ }
+
+ refresh_qsfp_cache(ppd, &ppd->qsfp_info);
+ release_chip_resource(ppd->dd, qsfp_resource(ppd->dd));
+ }
+
return;
}
@@ -942,7 +966,7 @@ void tune_serdes(struct hfi1_pportdata *ppd)
case PORT_TYPE_DISCONNECTED:
ppd->offline_disabled_reason =
HFI1_ODR_MASK(OPA_LINKDOWN_REASON_DISCONNECTED);
- dd_dev_info(dd, "%s: Port disconnected, disabling port\n",
+ dd_dev_warn(dd, "%s: Port disconnected, disabling port\n",
__func__);
goto bail;
case PORT_TYPE_FIXED:
@@ -1027,7 +1051,7 @@ void tune_serdes(struct hfi1_pportdata *ppd)
}
break;
default:
- dd_dev_info(ppd->dd, "%s: Unknown port type\n", __func__);
+ dd_dev_warn(ppd->dd, "%s: Unknown port type\n", __func__);
ppd->port_type = PORT_TYPE_UNKNOWN;
tuning_method = OPA_UNKNOWN_TUNING;
total_atten = 0;
diff --git a/drivers/infiniband/hw/hfi1/qp.c b/drivers/infiniband/hw/hfi1/qp.c
index 1a7af9f..4b01ccd 100644
--- a/drivers/infiniband/hw/hfi1/qp.c
+++ b/drivers/infiniband/hw/hfi1/qp.c
@@ -1,5 +1,5 @@
/*
- * Copyright(c) 2015, 2016 Intel Corporation.
+ * Copyright(c) 2015 - 2017 Intel Corporation.
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
@@ -68,17 +68,12 @@ static int iowait_sleep(
struct sdma_engine *sde,
struct iowait *wait,
struct sdma_txreq *stx,
- unsigned seq);
+ unsigned int seq,
+ bool pkts_sent);
static void iowait_wakeup(struct iowait *wait, int reason);
static void iowait_sdma_drained(struct iowait *wait);
static void qp_pio_drain(struct rvt_qp *qp);
-static inline unsigned mk_qpn(struct rvt_qpn_table *qpt,
- struct rvt_qpn_map *map, unsigned off)
-{
- return (map - qpt->map) * RVT_BITS_PER_PAGE + off;
-}
-
const struct rvt_operation_params hfi1_post_parms[RVT_OPERATION_MAX] = {
[IB_WR_RDMA_WRITE] = {
.length = sizeof(struct ib_rdma_wr),
@@ -237,6 +232,31 @@ int hfi1_check_modify_qp(struct rvt_qp *qp, struct ib_qp_attr *attr,
return 0;
}
+/*
+ * qp_set_16b - Set the hdr_type based on whether the slid or the
+ * dlid in the connection is extended. Only applicable for RC and UC
+ * QPs. UD QPs determine this on the fly from the ah in the wqe
+ */
+static inline void qp_set_16b(struct rvt_qp *qp)
+{
+ struct hfi1_pportdata *ppd;
+ struct hfi1_ibport *ibp;
+ struct hfi1_qp_priv *priv = qp->priv;
+
+ /* Update ah_attr to account for extended LIDs */
+ hfi1_update_ah_attr(qp->ibqp.device, &qp->remote_ah_attr);
+
+ /* Create 32 bit LIDs */
+ hfi1_make_opa_lid(&qp->remote_ah_attr);
+
+ if (!(rdma_ah_get_ah_flags(&qp->remote_ah_attr) & IB_AH_GRH))
+ return;
+
+ ibp = to_iport(qp->ibqp.device, qp->port_num);
+ ppd = ppd_from_ibp(ibp);
+ priv->hdr_type = hfi1_get_hdr_type(ppd->lid, &qp->remote_ah_attr);
+}
+
void hfi1_modify_qp(struct rvt_qp *qp, struct ib_qp_attr *attr,
int attr_mask, struct ib_udata *udata)
{
@@ -247,6 +267,7 @@ void hfi1_modify_qp(struct rvt_qp *qp, struct ib_qp_attr *attr,
priv->s_sc = ah_to_sc(ibqp->device, &qp->remote_ah_attr);
priv->s_sde = qp_to_sdma_engine(qp, priv->s_sc);
priv->s_sendcontext = qp_to_send_context(qp, priv->s_sc);
+ qp_set_16b(qp);
}
if (attr_mask & IB_QP_PATH_MIG_STATE &&
@@ -256,6 +277,7 @@ void hfi1_modify_qp(struct rvt_qp *qp, struct ib_qp_attr *attr,
priv->s_sc = ah_to_sc(ibqp->device, &qp->remote_ah_attr);
priv->s_sde = qp_to_sdma_engine(qp, priv->s_sc);
priv->s_sendcontext = qp_to_send_context(qp, priv->s_sc);
+ qp_set_16b(qp);
}
}
@@ -377,7 +399,8 @@ static int iowait_sleep(
struct sdma_engine *sde,
struct iowait *wait,
struct sdma_txreq *stx,
- unsigned seq)
+ uint seq,
+ bool pkts_sent)
{
struct verbs_txreq *tx = container_of(stx, struct verbs_txreq, txreq);
struct rvt_qp *qp;
@@ -408,7 +431,8 @@ static int iowait_sleep(
ibp->rvp.n_dmawait++;
qp->s_flags |= RVT_S_WAIT_DMA_DESC;
- list_add_tail(&priv->s_iowait.list, &sde->dmawait);
+ iowait_queue(pkts_sent, &priv->s_iowait,
+ &sde->dmawait);
priv->s_iowait.lock = &dev->iowait_lock;
trace_hfi1_qpsleep(qp, RVT_S_WAIT_DMA_DESC);
rvt_get_qp(qp);
@@ -506,82 +530,6 @@ struct send_context *qp_to_send_context(struct rvt_qp *qp, u8 sc5)
sc5);
}
-struct qp_iter {
- struct hfi1_ibdev *dev;
- struct rvt_qp *qp;
- int specials;
- int n;
-};
-
-struct qp_iter *qp_iter_init(struct hfi1_ibdev *dev)
-{
- struct qp_iter *iter;
-
- iter = kzalloc(sizeof(*iter), GFP_KERNEL);
- if (!iter)
- return NULL;
-
- iter->dev = dev;
- iter->specials = dev->rdi.ibdev.phys_port_cnt * 2;
-
- return iter;
-}
-
-int qp_iter_next(struct qp_iter *iter)
-{
- struct hfi1_ibdev *dev = iter->dev;
- int n = iter->n;
- int ret = 1;
- struct rvt_qp *pqp = iter->qp;
- struct rvt_qp *qp;
-
- /*
- * The approach is to consider the special qps
- * as an additional table entries before the
- * real hash table. Since the qp code sets
- * the qp->next hash link to NULL, this works just fine.
- *
- * iter->specials is 2 * # ports
- *
- * n = 0..iter->specials is the special qp indices
- *
- * n = iter->specials..dev->rdi.qp_dev->qp_table_size+iter->specials are
- * the potential hash bucket entries
- *
- */
- for (; n < dev->rdi.qp_dev->qp_table_size + iter->specials; n++) {
- if (pqp) {
- qp = rcu_dereference(pqp->next);
- } else {
- if (n < iter->specials) {
- struct hfi1_pportdata *ppd;
- struct hfi1_ibport *ibp;
- int pidx;
-
- pidx = n % dev->rdi.ibdev.phys_port_cnt;
- ppd = &dd_from_dev(dev)->pport[pidx];
- ibp = &ppd->ibport_data;
-
- if (!(n & 1))
- qp = rcu_dereference(ibp->rvp.qp[0]);
- else
- qp = rcu_dereference(ibp->rvp.qp[1]);
- } else {
- qp = rcu_dereference(
- dev->rdi.qp_dev->qp_table[
- (n - iter->specials)]);
- }
- }
- pqp = qp;
- if (qp) {
- iter->qp = qp;
- iter->n = n;
- return 0;
- }
- }
- return ret;
-}
-
static const char * const qp_type_str[] = {
"SMI", "GSI", "RC", "UC", "UD",
};
@@ -595,19 +543,27 @@ static int qp_idle(struct rvt_qp *qp)
qp->s_tail == qp->s_head;
}
-void qp_iter_print(struct seq_file *s, struct qp_iter *iter)
+/**
+ * qp_iter_print - print the qp information to seq_file
+ * @s: the seq_file to emit the qp information on
+ * @iter: the iterator for the qp hash list
+ */
+void qp_iter_print(struct seq_file *s, struct rvt_qp_iter *iter)
{
struct rvt_swqe *wqe;
struct rvt_qp *qp = iter->qp;
struct hfi1_qp_priv *priv = qp->priv;
struct sdma_engine *sde;
struct send_context *send_context;
+ struct rvt_ack_entry *e = NULL;
sde = qp_to_sdma_engine(qp, priv->s_sc);
wqe = rvt_get_swqe_ptr(qp, qp->s_last);
send_context = qp_to_send_context(qp, priv->s_sc);
+ if (qp->s_ack_queue)
+ e = &qp->s_ack_queue[qp->s_tail_ack_queue];
seq_printf(s,
- "N %d %s QP %x R %u %s %u %u %u f=%x %u %u %u %u %u %u SPSN %x %x %x %x %x RPSN %x (%u %u %u %u %u %u %u) RQP %x LID %x SL %u MTU %u %u %u %u %u SDE %p,%u SC %p,%u SCQ %u %u PID %d\n",
+ "N %d %s QP %x R %u %s %u %u %u f=%x %u %u %u %u %u %u SPSN %x %x %x %x %x RPSN %x S(%u %u %u %u %u %u %u) R(%u %u %u) RQP %x LID %x SL %u MTU %u %u %u %u %u SDE %p,%u SC %p,%u SCQ %u %u PID %d OS %x %x E %x %x %x\n",
iter->n,
qp_idle(qp) ? "I" : "B",
qp->ibqp.qp_num,
@@ -630,6 +586,10 @@ void qp_iter_print(struct seq_file *s, struct qp_iter *iter)
qp->s_last, qp->s_acked, qp->s_cur,
qp->s_tail, qp->s_head, qp->s_size,
qp->s_avail,
+ /* ack_queue ring pointers, size */
+ qp->s_tail_ack_queue, qp->r_head_ack_queue,
+ rvt_max_atomic(&to_idev(qp->ibqp.device)->rdi),
+ /* remote QP info */
qp->remote_qpn,
rdma_ah_get_dlid(&qp->remote_ah_attr),
rdma_ah_get_sl(&qp->remote_ah_attr),
@@ -644,7 +604,13 @@ void qp_iter_print(struct seq_file *s, struct qp_iter *iter)
send_context ? send_context->sw_index : 0,
ibcq_to_rvtcq(qp->ibqp.send_cq)->queue->head,
ibcq_to_rvtcq(qp->ibqp.send_cq)->queue->tail,
- qp->pid);
+ qp->pid,
+ qp->s_state,
+ qp->s_ack_state,
+ /* ack queue information */
+ e ? e->opcode : 0,
+ e ? e->psn : 0,
+ e ? e->lpsn : 0);
}
void *qp_priv_alloc(struct rvt_dev_info *rdi, struct rvt_qp *qp)
@@ -750,6 +716,7 @@ void hfi1_migrate_qp(struct rvt_qp *qp)
qp->s_flags |= RVT_S_AHG_CLEAR;
priv->s_sc = ah_to_sc(qp->ibqp.device, &qp->remote_ah_attr);
priv->s_sde = qp_to_sdma_engine(qp, priv->s_sc);
+ qp_set_16b(qp);
ev.device = qp->ibqp.device;
ev.element.qp = &qp->ibqp;
@@ -832,6 +799,45 @@ void notify_error_qp(struct rvt_qp *qp)
}
/**
+ * hfi1_qp_iter_cb - callback for iterator
+ * @qp - the qp
+ * @v - the sl in low bits of v
+ *
+ * This is called from the iterator callback to work
+ * on an individual qp.
+ */
+static void hfi1_qp_iter_cb(struct rvt_qp *qp, u64 v)
+{
+ int lastwqe;
+ struct ib_event ev;
+ struct hfi1_ibport *ibp =
+ to_iport(qp->ibqp.device, qp->port_num);
+ struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
+ u8 sl = (u8)v;
+
+ if (qp->port_num != ppd->port ||
+ (qp->ibqp.qp_type != IB_QPT_UC &&
+ qp->ibqp.qp_type != IB_QPT_RC) ||
+ rdma_ah_get_sl(&qp->remote_ah_attr) != sl ||
+ !(ib_rvt_state_ops[qp->state] & RVT_POST_SEND_OK))
+ return;
+
+ spin_lock_irq(&qp->r_lock);
+ spin_lock(&qp->s_hlock);
+ spin_lock(&qp->s_lock);
+ lastwqe = rvt_error_qp(qp, IB_WC_WR_FLUSH_ERR);
+ spin_unlock(&qp->s_lock);
+ spin_unlock(&qp->s_hlock);
+ spin_unlock_irq(&qp->r_lock);
+ if (lastwqe) {
+ ev.device = qp->ibqp.device;
+ ev.element.qp = &qp->ibqp;
+ ev.event = IB_EVENT_QP_LAST_WQE_REACHED;
+ qp->ibqp.event_handler(&ev, qp->ibqp.qp_context);
+ }
+}
+
+/**
* hfi1_error_port_qps - put a port's RC/UC qps into error state
* @ibp: the ibport.
* @sl: the service level.
@@ -842,44 +848,8 @@ void notify_error_qp(struct rvt_qp *qp)
*/
void hfi1_error_port_qps(struct hfi1_ibport *ibp, u8 sl)
{
- struct rvt_qp *qp = NULL;
struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
struct hfi1_ibdev *dev = &ppd->dd->verbs_dev;
- int n;
- int lastwqe;
- struct ib_event ev;
-
- rcu_read_lock();
-
- /* Deal only with RC/UC qps that use the given SL. */
- for (n = 0; n < dev->rdi.qp_dev->qp_table_size; n++) {
- for (qp = rcu_dereference(dev->rdi.qp_dev->qp_table[n]); qp;
- qp = rcu_dereference(qp->next)) {
- if (qp->port_num == ppd->port &&
- (qp->ibqp.qp_type == IB_QPT_UC ||
- qp->ibqp.qp_type == IB_QPT_RC) &&
- rdma_ah_get_sl(&qp->remote_ah_attr) == sl &&
- (ib_rvt_state_ops[qp->state] &
- RVT_POST_SEND_OK)) {
- spin_lock_irq(&qp->r_lock);
- spin_lock(&qp->s_hlock);
- spin_lock(&qp->s_lock);
- lastwqe = rvt_error_qp(qp,
- IB_WC_WR_FLUSH_ERR);
- spin_unlock(&qp->s_lock);
- spin_unlock(&qp->s_hlock);
- spin_unlock_irq(&qp->r_lock);
- if (lastwqe) {
- ev.device = qp->ibqp.device;
- ev.element.qp = &qp->ibqp;
- ev.event =
- IB_EVENT_QP_LAST_WQE_REACHED;
- qp->ibqp.event_handler(&ev,
- qp->ibqp.qp_context);
- }
- }
- }
- }
- rcu_read_unlock();
+ rvt_qp_iter(&dev->rdi, sl, hfi1_qp_iter_cb);
}
diff --git a/drivers/infiniband/hw/hfi1/qp.h b/drivers/infiniband/hw/hfi1/qp.h
index 6fe542b..c06d2f8 100644
--- a/drivers/infiniband/hw/hfi1/qp.h
+++ b/drivers/infiniband/hw/hfi1/qp.h
@@ -1,7 +1,7 @@
#ifndef _QP_H
#define _QP_H
/*
- * Copyright(c) 2015, 2016 Intel Corporation.
+ * Copyright(c) 2015 - 2017 Intel Corporation.
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
@@ -94,26 +94,7 @@ void hfi1_qp_wakeup(struct rvt_qp *qp, u32 flag);
struct sdma_engine *qp_to_sdma_engine(struct rvt_qp *qp, u8 sc5);
struct send_context *qp_to_send_context(struct rvt_qp *qp, u8 sc5);
-struct qp_iter;
-
-/**
- * qp_iter_init - initialize the iterator for the qp hash list
- * @dev: the hfi1_ibdev
- */
-struct qp_iter *qp_iter_init(struct hfi1_ibdev *dev);
-
-/**
- * qp_iter_next - Find the next qp in the hash list
- * @iter: the iterator for the qp hash list
- */
-int qp_iter_next(struct qp_iter *iter);
-
-/**
- * qp_iter_print - print the qp information to seq_file
- * @s: the seq_file to emit the qp information on
- * @iter: the iterator for the qp hash list
- */
-void qp_iter_print(struct seq_file *s, struct qp_iter *iter);
+void qp_iter_print(struct seq_file *s, struct rvt_qp_iter *iter);
void _hfi1_schedule_send(struct rvt_qp *qp);
void hfi1_schedule_send(struct rvt_qp *qp);
diff --git a/drivers/infiniband/hw/hfi1/rc.c b/drivers/infiniband/hw/hfi1/rc.c
index 1080778..e1cf0c0 100644
--- a/drivers/infiniband/hw/hfi1/rc.c
+++ b/drivers/infiniband/hw/hfi1/rc.c
@@ -100,8 +100,12 @@ static int make_rc_ack(struct hfi1_ibdev *dev, struct rvt_qp *qp,
if (!(ib_rvt_state_ops[qp->state] & RVT_PROCESS_RECV_OK))
goto bail;
- /* header size in 32-bit words LRH+BTH = (8+12)/4. */
- hwords = 5;
+ if (priv->hdr_type == HFI1_PKT_TYPE_9B)
+ /* header size in 32-bit words LRH+BTH = (8+12)/4. */
+ hwords = 5;
+ else
+ /* header size in 32-bit words 16B LRH+BTH = (16+12)/4. */
+ hwords = 7;
switch (qp->s_ack_state) {
case OP(RDMA_READ_RESPONSE_LAST):
@@ -258,8 +262,7 @@ int hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
struct ib_other_headers *ohdr;
struct rvt_sge_state *ss;
struct rvt_swqe *wqe;
- /* header size in 32-bit words LRH+BTH = (8+12)/4. */
- u32 hwords = 5;
+ u32 hwords;
u32 len;
u32 bth0 = 0;
u32 bth2;
@@ -273,9 +276,23 @@ int hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
if (IS_ERR(ps->s_txreq))
goto bail_no_tx;
- ohdr = &ps->s_txreq->phdr.hdr.u.oth;
- if (rdma_ah_get_ah_flags(&qp->remote_ah_attr) & IB_AH_GRH)
- ohdr = &ps->s_txreq->phdr.hdr.u.l.oth;
+ ps->s_txreq->phdr.hdr.hdr_type = priv->hdr_type;
+ if (priv->hdr_type == HFI1_PKT_TYPE_9B) {
+ /* header size in 32-bit words LRH+BTH = (8+12)/4. */
+ hwords = 5;
+ if (rdma_ah_get_ah_flags(&qp->remote_ah_attr) & IB_AH_GRH)
+ ohdr = &ps->s_txreq->phdr.hdr.ibh.u.l.oth;
+ else
+ ohdr = &ps->s_txreq->phdr.hdr.ibh.u.oth;
+ } else {
+ /* header size in 32-bit words 16B LRH+BTH = (16+12)/4. */
+ hwords = 7;
+ if ((rdma_ah_get_ah_flags(&qp->remote_ah_attr) & IB_AH_GRH) &&
+ (hfi1_check_mcast(rdma_ah_get_dlid(&qp->remote_ah_attr))))
+ ohdr = &ps->s_txreq->phdr.hdr.opah.u.l.oth;
+ else
+ ohdr = &ps->s_txreq->phdr.hdr.opah.u.oth;
+ }
/* Sending responses has higher priority over sending requests. */
if ((qp->s_flags & RVT_S_RESP_PENDING) &&
@@ -425,7 +442,7 @@ int hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
case IB_WR_RDMA_WRITE:
if (newreq && !(qp->s_flags & RVT_S_UNLIMITED_CREDIT))
qp->s_lsn++;
- /* FALLTHROUGH */
+ goto no_flow_control;
case IB_WR_RDMA_WRITE_WITH_IMM:
/* If no credit, return. */
if (!(qp->s_flags & RVT_S_UNLIMITED_CREDIT) &&
@@ -433,6 +450,7 @@ int hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
qp->s_flags |= RVT_S_WAIT_SSN_CREDIT;
goto bail;
}
+no_flow_control:
put_ib_reth_vaddr(
wqe->rdma_wr.remote_addr,
&ohdr->u.rc.reth);
@@ -703,6 +721,154 @@ bail_no_tx:
return 0;
}
+static inline void hfi1_make_bth_aeth(struct rvt_qp *qp,
+ struct ib_other_headers *ohdr,
+ u32 bth0, u32 bth1)
+{
+ if (qp->r_nak_state)
+ ohdr->u.aeth = cpu_to_be32((qp->r_msn & IB_MSN_MASK) |
+ (qp->r_nak_state <<
+ IB_AETH_CREDIT_SHIFT));
+ else
+ ohdr->u.aeth = rvt_compute_aeth(qp);
+
+ ohdr->bth[0] = cpu_to_be32(bth0);
+ ohdr->bth[1] = cpu_to_be32(bth1 | qp->remote_qpn);
+ ohdr->bth[2] = cpu_to_be32(mask_psn(qp->r_ack_psn));
+}
+
+static inline void hfi1_queue_rc_ack(struct rvt_qp *qp, bool is_fecn)
+{
+ struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num);
+ unsigned long flags;
+
+ spin_lock_irqsave(&qp->s_lock, flags);
+ if (!(ib_rvt_state_ops[qp->state] & RVT_PROCESS_RECV_OK))
+ goto unlock;
+ this_cpu_inc(*ibp->rvp.rc_qacks);
+ qp->s_flags |= RVT_S_ACK_PENDING | RVT_S_RESP_PENDING;
+ qp->s_nak_state = qp->r_nak_state;
+ qp->s_ack_psn = qp->r_ack_psn;
+ if (is_fecn)
+ qp->s_flags |= RVT_S_ECN;
+
+ /* Schedule the send tasklet. */
+ hfi1_schedule_send(qp);
+unlock:
+ spin_unlock_irqrestore(&qp->s_lock, flags);
+}
+
+static inline void hfi1_make_rc_ack_9B(struct rvt_qp *qp,
+ struct hfi1_opa_header *opa_hdr,
+ u8 sc5, bool is_fecn,
+ u64 *pbc_flags, u32 *hwords,
+ u32 *nwords)
+{
+ struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num);
+ struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
+ struct ib_header *hdr = &opa_hdr->ibh;
+ struct ib_other_headers *ohdr;
+ u16 lrh0 = HFI1_LRH_BTH;
+ u16 pkey;
+ u32 bth0, bth1;
+
+ opa_hdr->hdr_type = HFI1_PKT_TYPE_9B;
+ ohdr = &hdr->u.oth;
+ /* header size in 32-bit words LRH+BTH+AETH = (8+12+4)/4 */
+ *hwords = 6;
+
+ if (unlikely(rdma_ah_get_ah_flags(&qp->remote_ah_attr) & IB_AH_GRH)) {
+ *hwords += hfi1_make_grh(ibp, &hdr->u.l.grh,
+ rdma_ah_read_grh(&qp->remote_ah_attr),
+ *hwords - 2, SIZE_OF_CRC);
+ ohdr = &hdr->u.l.oth;
+ lrh0 = HFI1_LRH_GRH;
+ }
+ /* set PBC_DC_INFO bit (aka SC[4]) in pbc_flags */
+ *pbc_flags |= ((!!(sc5 & 0x10)) << PBC_DC_INFO_SHIFT);
+
+ /* read pkey_index w/o lock (its atomic) */
+ pkey = hfi1_get_pkey(ibp, qp->s_pkey_index);
+
+ lrh0 |= (sc5 & IB_SC_MASK) << IB_SC_SHIFT |
+ (rdma_ah_get_sl(&qp->remote_ah_attr) & IB_SL_MASK) <<
+ IB_SL_SHIFT;
+
+ hfi1_make_ib_hdr(hdr, lrh0, *hwords + SIZE_OF_CRC,
+ opa_get_lid(rdma_ah_get_dlid(&qp->remote_ah_attr), 9B),
+ ppd->lid | rdma_ah_get_path_bits(&qp->remote_ah_attr));
+
+ bth0 = pkey | (OP(ACKNOWLEDGE) << 24);
+ if (qp->s_mig_state == IB_MIG_MIGRATED)
+ bth0 |= IB_BTH_MIG_REQ;
+ bth1 = (!!is_fecn) << IB_BECN_SHIFT;
+ hfi1_make_bth_aeth(qp, ohdr, bth0, bth1);
+}
+
+static inline void hfi1_make_rc_ack_16B(struct rvt_qp *qp,
+ struct hfi1_opa_header *opa_hdr,
+ u8 sc5, bool is_fecn,
+ u64 *pbc_flags, u32 *hwords,
+ u32 *nwords)
+{
+ struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num);
+ struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
+ struct hfi1_16b_header *hdr = &opa_hdr->opah;
+ struct ib_other_headers *ohdr;
+ u32 bth0, bth1;
+ u16 len, pkey;
+ u8 becn = !!is_fecn;
+ u8 l4 = OPA_16B_L4_IB_LOCAL;
+ u8 extra_bytes;
+
+ opa_hdr->hdr_type = HFI1_PKT_TYPE_16B;
+ ohdr = &hdr->u.oth;
+ /* header size in 32-bit words 16B LRH+BTH+AETH = (16+12+4)/4 */
+ *hwords = 8;
+ extra_bytes = hfi1_get_16b_padding(*hwords << 2, 0);
+ *nwords = SIZE_OF_CRC + ((extra_bytes + SIZE_OF_LT) >> 2);
+
+ if (unlikely(rdma_ah_get_ah_flags(&qp->remote_ah_attr) & IB_AH_GRH) &&
+ hfi1_check_mcast(rdma_ah_get_dlid(&qp->remote_ah_attr))) {
+ *hwords += hfi1_make_grh(ibp, &hdr->u.l.grh,
+ rdma_ah_read_grh(&qp->remote_ah_attr),
+ *hwords - 4, *nwords);
+ ohdr = &hdr->u.l.oth;
+ l4 = OPA_16B_L4_IB_GLOBAL;
+ }
+ *pbc_flags |= PBC_PACKET_BYPASS | PBC_INSERT_BYPASS_ICRC;
+
+ /* read pkey_index w/o lock (its atomic) */
+ pkey = hfi1_get_pkey(ibp, qp->s_pkey_index);
+
+ /* Convert dwords to flits */
+ len = (*hwords + *nwords) >> 1;
+
+ hfi1_make_16b_hdr(hdr,
+ ppd->lid | rdma_ah_get_path_bits(&qp->remote_ah_attr),
+ opa_get_lid(rdma_ah_get_dlid(&qp->remote_ah_attr),
+ 16B),
+ len, pkey, becn, 0, l4, sc5);
+
+ bth0 = pkey | (OP(ACKNOWLEDGE) << 24);
+ bth0 |= extra_bytes << 20;
+ if (qp->s_mig_state == IB_MIG_MIGRATED)
+ bth1 = OPA_BTH_MIG_REQ;
+ hfi1_make_bth_aeth(qp, ohdr, bth0, bth1);
+}
+
+typedef void (*hfi1_make_rc_ack)(struct rvt_qp *qp,
+ struct hfi1_opa_header *opa_hdr,
+ u8 sc5, bool is_fecn,
+ u64 *pbc_flags, u32 *hwords,
+ u32 *nwords);
+
+/* We support only two types - 9B and 16B for now */
+static const hfi1_make_rc_ack hfi1_make_rc_ack_tbl[2] = {
+ [HFI1_PKT_TYPE_9B] = &hfi1_make_rc_ack_9B,
+ [HFI1_PKT_TYPE_16B] = &hfi1_make_rc_ack_16B
+};
+
/**
* hfi1_send_rc_ack - Construct an ACK packet and send it
* @qp: a pointer to the QP
@@ -711,83 +877,48 @@ bail_no_tx:
* Note that RDMA reads and atomics are handled in the
* send side QP state and send engine.
*/
-void hfi1_send_rc_ack(struct hfi1_ctxtdata *rcd, struct rvt_qp *qp,
- int is_fecn)
+void hfi1_send_rc_ack(struct hfi1_ctxtdata *rcd,
+ struct rvt_qp *qp, bool is_fecn)
{
struct hfi1_ibport *ibp = rcd_to_iport(rcd);
+ struct hfi1_qp_priv *priv = qp->priv;
struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
+ u8 sc5 = ibp->sl_to_sc[rdma_ah_get_sl(&qp->remote_ah_attr)];
u64 pbc, pbc_flags = 0;
- u16 lrh0;
- u16 sc5;
- u32 bth0;
- u32 hwords;
- u32 vl, plen;
- struct send_context *sc;
+ u32 hwords = 0;
+ u32 nwords = 0;
+ u32 plen;
struct pio_buf *pbuf;
- struct ib_header hdr;
- struct ib_other_headers *ohdr;
- unsigned long flags;
+ struct hfi1_opa_header opa_hdr;
/* clear the defer count */
qp->r_adefered = 0;
/* Don't send ACK or NAK if a RDMA read or atomic is pending. */
- if (qp->s_flags & RVT_S_RESP_PENDING)
- goto queue_ack;
+ if (qp->s_flags & RVT_S_RESP_PENDING) {
+ hfi1_queue_rc_ack(qp, is_fecn);
+ return;
+ }
/* Ensure s_rdma_ack_cnt changes are committed */
smp_read_barrier_depends();
- if (qp->s_rdma_ack_cnt)
- goto queue_ack;
-
- /* Construct the header */
- /* header size in 32-bit words LRH+BTH+AETH = (8+12+4)/4 */
- hwords = 6;
- if (unlikely(rdma_ah_get_ah_flags(&qp->remote_ah_attr) & IB_AH_GRH)) {
- hwords += hfi1_make_grh(ibp, &hdr.u.l.grh,
- rdma_ah_read_grh(&qp->remote_ah_attr),
- hwords, 0);
- ohdr = &hdr.u.l.oth;
- lrh0 = HFI1_LRH_GRH;
- } else {
- ohdr = &hdr.u.oth;
- lrh0 = HFI1_LRH_BTH;
+ if (qp->s_rdma_ack_cnt) {
+ hfi1_queue_rc_ack(qp, is_fecn);
+ return;
}
- /* read pkey_index w/o lock (its atomic) */
- bth0 = hfi1_get_pkey(ibp, qp->s_pkey_index) | (OP(ACKNOWLEDGE) << 24);
- if (qp->s_mig_state == IB_MIG_MIGRATED)
- bth0 |= IB_BTH_MIG_REQ;
- if (qp->r_nak_state)
- ohdr->u.aeth = cpu_to_be32((qp->r_msn & IB_MSN_MASK) |
- (qp->r_nak_state <<
- IB_AETH_CREDIT_SHIFT));
- else
- ohdr->u.aeth = rvt_compute_aeth(qp);
- sc5 = ibp->sl_to_sc[rdma_ah_get_sl(&qp->remote_ah_attr)];
- /* set PBC_DC_INFO bit (aka SC[4]) in pbc_flags */
- pbc_flags |= ((!!(sc5 & 0x10)) << PBC_DC_INFO_SHIFT);
- lrh0 |= (sc5 & 0xf) << 12 | (rdma_ah_get_sl(&qp->remote_ah_attr)
- & 0xf) << 4;
- hdr.lrh[0] = cpu_to_be16(lrh0);
- hdr.lrh[1] = cpu_to_be16(rdma_ah_get_dlid(&qp->remote_ah_attr));
- hdr.lrh[2] = cpu_to_be16(hwords + SIZE_OF_CRC);
- hdr.lrh[3] = cpu_to_be16(ppd->lid |
- rdma_ah_get_path_bits(&qp->remote_ah_attr));
- ohdr->bth[0] = cpu_to_be32(bth0);
- ohdr->bth[1] = cpu_to_be32(qp->remote_qpn);
- ohdr->bth[1] |= cpu_to_be32((!!is_fecn) << IB_BECN_SHIFT);
- ohdr->bth[2] = cpu_to_be32(mask_psn(qp->r_ack_psn));
/* Don't try to send ACKs if the link isn't ACTIVE */
if (driver_lstate(ppd) != IB_PORT_ACTIVE)
return;
- sc = rcd->sc;
- plen = 2 /* PBC */ + hwords;
- vl = sc_to_vlt(ppd->dd, sc5);
- pbc = create_pbc(ppd, pbc_flags, qp->srate_mbps, vl, plen);
+ /* Make the appropriate header */
+ hfi1_make_rc_ack_tbl[priv->hdr_type](qp, &opa_hdr, sc5, is_fecn,
+ &pbc_flags, &hwords, &nwords);
- pbuf = sc_buffer_alloc(sc, plen, NULL, NULL);
+ plen = 2 /* PBC */ + hwords + nwords;
+ pbc = create_pbc(ppd, pbc_flags, qp->srate_mbps,
+ sc_to_vlt(ppd->dd, sc5), plen);
+ pbuf = sc_buffer_alloc(rcd->sc, plen, NULL, NULL);
if (!pbuf) {
/*
* We have no room to send at the moment. Pass
@@ -795,31 +926,18 @@ void hfi1_send_rc_ack(struct hfi1_ctxtdata *rcd, struct rvt_qp *qp,
* so that when enough buffer space becomes available,
* the ACK is sent ahead of other outgoing packets.
*/
- goto queue_ack;
+ hfi1_queue_rc_ack(qp, is_fecn);
+ return;
}
-
- trace_ack_output_ibhdr(dd_from_ibdev(qp->ibqp.device), &hdr);
+ trace_ack_output_ibhdr(dd_from_ibdev(qp->ibqp.device),
+ &opa_hdr, ib_is_sc5(sc5));
/* write the pbc and data */
- ppd->dd->pio_inline_send(ppd->dd, pbuf, pbc, &hdr, hwords);
-
+ ppd->dd->pio_inline_send(ppd->dd, pbuf, pbc,
+ (priv->hdr_type == HFI1_PKT_TYPE_9B ?
+ (void *)&opa_hdr.ibh :
+ (void *)&opa_hdr.opah), hwords);
return;
-
-queue_ack:
- spin_lock_irqsave(&qp->s_lock, flags);
- if (!(ib_rvt_state_ops[qp->state] & RVT_PROCESS_RECV_OK))
- goto unlock;
- this_cpu_inc(*ibp->rvp.rc_qacks);
- qp->s_flags |= RVT_S_ACK_PENDING | RVT_S_RESP_PENDING;
- qp->s_nak_state = qp->r_nak_state;
- qp->s_ack_psn = qp->r_ack_psn;
- if (is_fecn)
- qp->s_flags |= RVT_S_ECN;
-
- /* Schedule the send engine. */
- hfi1_schedule_send(qp);
-unlock:
- spin_unlock_irqrestore(&qp->s_lock, flags);
}
/**
@@ -984,10 +1102,13 @@ static void reset_sending_psn(struct rvt_qp *qp, u32 psn)
/*
* This should be called with the QP s_lock held and interrupts disabled.
*/
-void hfi1_rc_send_complete(struct rvt_qp *qp, struct ib_header *hdr)
+void hfi1_rc_send_complete(struct rvt_qp *qp, struct hfi1_opa_header *opah)
{
struct ib_other_headers *ohdr;
+ struct hfi1_qp_priv *priv = qp->priv;
struct rvt_swqe *wqe;
+ struct ib_header *hdr = NULL;
+ struct hfi1_16b_header *hdr_16b = NULL;
u32 opcode;
u32 psn;
@@ -996,10 +1117,22 @@ void hfi1_rc_send_complete(struct rvt_qp *qp, struct ib_header *hdr)
return;
/* Find out where the BTH is */
- if (ib_get_lnh(hdr) == HFI1_LRH_BTH)
- ohdr = &hdr->u.oth;
- else
- ohdr = &hdr->u.l.oth;
+ if (priv->hdr_type == HFI1_PKT_TYPE_9B) {
+ hdr = &opah->ibh;
+ if (ib_get_lnh(hdr) == HFI1_LRH_BTH)
+ ohdr = &hdr->u.oth;
+ else
+ ohdr = &hdr->u.l.oth;
+ } else {
+ u8 l4;
+
+ hdr_16b = &opah->opah;
+ l4 = hfi1_16B_get_l4(hdr_16b);
+ if (l4 == OPA_16B_L4_IB_LOCAL)
+ ohdr = &hdr_16b->u.oth;
+ else
+ ohdr = &hdr_16b->u.l.oth;
+ }
opcode = ib_bth_get_opcode(ohdr);
if (opcode >= OP(RDMA_READ_RESPONSE_FIRST) &&
@@ -1009,7 +1142,7 @@ void hfi1_rc_send_complete(struct rvt_qp *qp, struct ib_header *hdr)
return;
}
- psn = be32_to_cpu(ohdr->bth[2]);
+ psn = ib_bth_get_psn(ohdr);
reset_sending_psn(qp, psn);
/*
@@ -1399,36 +1532,34 @@ static void rdma_seq_err(struct rvt_qp *qp, struct hfi1_ibport *ibp, u32 psn,
/**
* rc_rcv_resp - process an incoming RC response packet
- * @ibp: the port this packet came in on
- * @ohdr: the other headers for this packet
- * @data: the packet data
- * @tlen: the packet length
- * @qp: the QP for this packet
- * @opcode: the opcode for this packet
- * @psn: the packet sequence number for this packet
- * @hdrsize: the header length
- * @pmtu: the path MTU
+ * @packet: data packet information
*
* This is called from hfi1_rc_rcv() to process an incoming RC response
* packet for the given QP.
* Called at interrupt level.
*/
-static void rc_rcv_resp(struct hfi1_ibport *ibp,
- struct ib_other_headers *ohdr,
- void *data, u32 tlen, struct rvt_qp *qp,
- u32 opcode, u32 psn, u32 hdrsize, u32 pmtu,
- struct hfi1_ctxtdata *rcd)
+static void rc_rcv_resp(struct hfi1_packet *packet)
{
+ struct hfi1_ctxtdata *rcd = packet->rcd;
+ void *data = packet->payload;
+ u32 tlen = packet->tlen;
+ struct rvt_qp *qp = packet->qp;
+ struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num);
+ struct ib_other_headers *ohdr = packet->ohdr;
struct rvt_swqe *wqe;
enum ib_wc_status status;
unsigned long flags;
int diff;
- u32 pad;
- u32 aeth;
u64 val;
+ u32 aeth;
+ u32 psn = ib_bth_get_psn(packet->ohdr);
+ u32 pmtu = qp->pmtu;
+ u16 hdrsize = packet->hlen;
+ u8 opcode = packet->opcode;
+ u8 pad = packet->pad;
+ u8 extra_bytes = pad + packet->extra_byte + (SIZE_OF_CRC << 2);
spin_lock_irqsave(&qp->s_lock, flags);
-
trace_hfi1_ack(qp, psn);
/* Ignore invalid responses. */
@@ -1494,7 +1625,7 @@ static void rc_rcv_resp(struct hfi1_ibport *ibp,
if (unlikely(wqe->wr.opcode != IB_WR_RDMA_READ))
goto ack_op_err;
read_middle:
- if (unlikely(tlen != (hdrsize + pmtu + 4)))
+ if (unlikely(tlen != (hdrsize + pmtu + extra_bytes)))
goto ack_len_err;
if (unlikely(pmtu >= qp->s_rdma_read_len))
goto ack_len_err;
@@ -1526,13 +1657,11 @@ read_middle:
aeth = be32_to_cpu(ohdr->u.aeth);
if (!do_rc_ack(qp, aeth, psn, opcode, 0, rcd))
goto ack_done;
- /* Get the number of bytes the message was padded by. */
- pad = ib_bth_get_pad(ohdr);
/*
* Check that the data size is >= 0 && <= pmtu.
* Remember to account for ICRC (4).
*/
- if (unlikely(tlen < (hdrsize + pad + 4)))
+ if (unlikely(tlen < (hdrsize + extra_bytes)))
goto ack_len_err;
/*
* If this is a response to a resent RDMA read, we
@@ -1550,16 +1679,14 @@ read_middle:
goto ack_seq_err;
if (unlikely(wqe->wr.opcode != IB_WR_RDMA_READ))
goto ack_op_err;
- /* Get the number of bytes the message was padded by. */
- pad = ib_bth_get_pad(ohdr);
/*
* Check that the data size is >= 1 && <= pmtu.
* Remember to account for ICRC (4).
*/
- if (unlikely(tlen <= (hdrsize + pad + 4)))
+ if (unlikely(tlen <= (hdrsize + extra_bytes)))
goto ack_len_err;
read_last:
- tlen -= hdrsize + pad + 4;
+ tlen -= hdrsize + extra_bytes;
if (unlikely(tlen != qp->s_rdma_read_len))
goto ack_len_err;
aeth = be32_to_cpu(ohdr->u.aeth);
@@ -1844,7 +1971,7 @@ static void log_cca_event(struct hfi1_pportdata *ppd, u8 sl, u32 rlid,
spin_unlock_irqrestore(&ppd->cc_log_lock, flags);
}
-void process_becn(struct hfi1_pportdata *ppd, u8 sl, u16 rlid, u32 lqpn,
+void process_becn(struct hfi1_pportdata *ppd, u8 sl, u32 rlid, u32 lqpn,
u32 rqpn, u8 svc_type)
{
struct cca_timer *cca_timer;
@@ -1901,12 +2028,7 @@ void process_becn(struct hfi1_pportdata *ppd, u8 sl, u16 rlid, u32 lqpn,
/**
* hfi1_rc_rcv - process an incoming RC packet
- * @rcd: the context pointer
- * @hdr: the header of this packet
- * @rcv_flags: flags relevant to rcv processing
- * @data: the packet data
- * @tlen: the packet length
- * @qp: the QP for this packet
+ * @packet: data packet information
*
* This is called from qp_rcv() to process an incoming RC packet
* for the given QP.
@@ -1915,17 +2037,16 @@ void process_becn(struct hfi1_pportdata *ppd, u8 sl, u16 rlid, u32 lqpn,
void hfi1_rc_rcv(struct hfi1_packet *packet)
{
struct hfi1_ctxtdata *rcd = packet->rcd;
- struct ib_header *hdr = packet->hdr;
- u32 rcv_flags = packet->rcv_flags;
- void *data = packet->ebuf;
+ void *data = packet->payload;
u32 tlen = packet->tlen;
struct rvt_qp *qp = packet->qp;
struct hfi1_ibport *ibp = rcd_to_iport(rcd);
struct ib_other_headers *ohdr = packet->ohdr;
- u32 bth0, opcode;
+ u32 bth0 = be32_to_cpu(ohdr->bth[0]);
+ u32 opcode = packet->opcode;
u32 hdrsize = packet->hlen;
- u32 psn;
- u32 pad;
+ u32 psn = ib_bth_get_psn(packet->ohdr);
+ u32 pad = packet->pad;
struct ib_wc wc;
u32 pmtu = qp->pmtu;
int diff;
@@ -1935,17 +2056,15 @@ void hfi1_rc_rcv(struct hfi1_packet *packet)
bool is_fecn = false;
bool copy_last = false;
u32 rkey;
+ u8 extra_bytes = pad + packet->extra_byte + (SIZE_OF_CRC << 2);
lockdep_assert_held(&qp->r_lock);
- bth0 = be32_to_cpu(ohdr->bth[0]);
- if (hfi1_ruc_check_hdr(ibp, hdr, rcv_flags & HFI1_HAS_GRH, qp, bth0))
+
+ if (hfi1_ruc_check_hdr(ibp, packet))
return;
is_fecn = process_ecn(qp, packet, false);
- psn = be32_to_cpu(ohdr->bth[2]);
- opcode = ib_bth_get_opcode(ohdr);
-
/*
* Process responses (ACKs) before anything else. Note that the
* packet sequence number will be for something in the send work
@@ -1954,8 +2073,7 @@ void hfi1_rc_rcv(struct hfi1_packet *packet)
*/
if (opcode >= OP(RDMA_READ_RESPONSE_FIRST) &&
opcode <= OP(ATOMIC_ACKNOWLEDGE)) {
- rc_rcv_resp(ibp, ohdr, data, tlen, qp, opcode, psn,
- hdrsize, pmtu, rcd);
+ rc_rcv_resp(packet);
if (is_fecn)
goto send_ack;
return;
@@ -2022,7 +2140,12 @@ void hfi1_rc_rcv(struct hfi1_packet *packet)
case OP(RDMA_WRITE_MIDDLE):
send_middle:
/* Check for invalid length PMTU or posted rwqe len. */
- if (unlikely(tlen != (hdrsize + pmtu + 4)))
+ /*
+ * There will be no padding for 9B packet but 16B packets
+ * will come in with some padding since we always add
+ * CRC and LT bytes which will need to be flit aligned
+ */
+ if (unlikely(tlen != (hdrsize + pmtu + extra_bytes)))
goto nack_inv;
qp->r_rcv_len += pmtu;
if (unlikely(qp->r_rcv_len > qp->r_len))
@@ -2074,14 +2197,12 @@ no_immediate_data:
wc.wc_flags = 0;
wc.ex.imm_data = 0;
send_last:
- /* Get the number of bytes the message was padded by. */
- pad = ib_bth_get_pad(ohdr);
/* Check for invalid length. */
/* LAST len should be >= 1 */
- if (unlikely(tlen < (hdrsize + pad + 4)))
+ if (unlikely(tlen < (hdrsize + extra_bytes)))
goto nack_inv;
- /* Don't count the CRC. */
- tlen -= (hdrsize + pad + 4);
+ /* Don't count the CRC(and padding and LT byte for 16B). */
+ tlen -= (hdrsize + extra_bytes);
wc.byte_len = tlen + qp->r_rcv_len;
if (unlikely(wc.byte_len > qp->r_len))
goto nack_inv;
@@ -2368,28 +2489,19 @@ send_ack:
void hfi1_rc_hdrerr(
struct hfi1_ctxtdata *rcd,
- struct ib_header *hdr,
- u32 rcv_flags,
+ struct hfi1_packet *packet,
struct rvt_qp *qp)
{
- int has_grh = rcv_flags & HFI1_HAS_GRH;
- struct ib_other_headers *ohdr;
struct hfi1_ibport *ibp = rcd_to_iport(rcd);
int diff;
u32 opcode;
- u32 psn, bth0;
-
- /* Check for GRH */
- ohdr = &hdr->u.oth;
- if (has_grh)
- ohdr = &hdr->u.l.oth;
+ u32 psn;
- bth0 = be32_to_cpu(ohdr->bth[0]);
- if (hfi1_ruc_check_hdr(ibp, hdr, has_grh, qp, bth0))
+ if (hfi1_ruc_check_hdr(ibp, packet))
return;
- psn = be32_to_cpu(ohdr->bth[2]);
- opcode = ib_bth_get_opcode(ohdr);
+ psn = ib_bth_get_psn(packet->ohdr);
+ opcode = ib_bth_get_opcode(packet->ohdr);
/* Only deal with RDMA Writes for now */
if (opcode < IB_OPCODE_RC_RDMA_READ_RESPONSE_FIRST) {
diff --git a/drivers/infiniband/hw/hfi1/ruc.c b/drivers/infiniband/hw/hfi1/ruc.c
index 3a17dab..b3291f0 100644
--- a/drivers/infiniband/hw/hfi1/ruc.c
+++ b/drivers/infiniband/hw/hfi1/ruc.c
@@ -74,8 +74,10 @@ static int init_sge(struct rvt_qp *qp, struct rvt_rwqe *wqe)
if (wqe->sg_list[i].length == 0)
continue;
/* Check LKEY */
- if (!rvt_lkey_ok(rkt, pd, j ? &ss->sg_list[j - 1] : &ss->sge,
- &wqe->sg_list[i], IB_ACCESS_LOCAL_WRITE))
+ ret = rvt_lkey_ok(rkt, pd, j ? &ss->sg_list[j - 1] : &ss->sge,
+ NULL, &wqe->sg_list[i],
+ IB_ACCESS_LOCAL_WRITE);
+ if (unlikely(ret <= 0))
goto bad_lkey;
qp->r_len += wqe->sg_list[i].length;
j++;
@@ -214,100 +216,104 @@ static int gid_ok(union ib_gid *gid, __be64 gid_prefix, __be64 id)
*
* The s_lock will be acquired around the hfi1_migrate_qp() call.
*/
-int hfi1_ruc_check_hdr(struct hfi1_ibport *ibp, struct ib_header *hdr,
- int has_grh, struct rvt_qp *qp, u32 bth0)
+int hfi1_ruc_check_hdr(struct hfi1_ibport *ibp, struct hfi1_packet *packet)
{
__be64 guid;
unsigned long flags;
+ struct rvt_qp *qp = packet->qp;
u8 sc5 = ibp->sl_to_sc[rdma_ah_get_sl(&qp->remote_ah_attr)];
+ u32 dlid = packet->dlid;
+ u32 slid = packet->slid;
+ u32 sl = packet->sl;
+ int migrated;
+ u32 bth0, bth1;
+ u16 pkey;
+
+ bth0 = be32_to_cpu(packet->ohdr->bth[0]);
+ bth1 = be32_to_cpu(packet->ohdr->bth[1]);
+ if (packet->etype == RHF_RCV_TYPE_BYPASS) {
+ pkey = hfi1_16B_get_pkey(packet->hdr);
+ migrated = bth1 & OPA_BTH_MIG_REQ;
+ } else {
+ pkey = ib_bth_get_pkey(packet->ohdr);
+ migrated = bth0 & IB_BTH_MIG_REQ;
+ }
- if (qp->s_mig_state == IB_MIG_ARMED && (bth0 & IB_BTH_MIG_REQ)) {
- if (!has_grh) {
- if (rdma_ah_get_ah_flags(&qp->alt_ah_attr) &
- IB_AH_GRH)
- goto err;
+ if (qp->s_mig_state == IB_MIG_ARMED && migrated) {
+ if (!packet->grh) {
+ if ((rdma_ah_get_ah_flags(&qp->alt_ah_attr) &
+ IB_AH_GRH) &&
+ (packet->etype != RHF_RCV_TYPE_BYPASS))
+ return 1;
} else {
const struct ib_global_route *grh;
if (!(rdma_ah_get_ah_flags(&qp->alt_ah_attr) &
IB_AH_GRH))
- goto err;
+ return 1;
grh = rdma_ah_read_grh(&qp->alt_ah_attr);
guid = get_sguid(ibp, grh->sgid_index);
- if (!gid_ok(&hdr->u.l.grh.dgid, ibp->rvp.gid_prefix,
+ if (!gid_ok(&packet->grh->dgid, ibp->rvp.gid_prefix,
guid))
- goto err;
+ return 1;
if (!gid_ok(
- &hdr->u.l.grh.sgid,
+ &packet->grh->sgid,
grh->dgid.global.subnet_prefix,
grh->dgid.global.interface_id))
- goto err;
+ return 1;
}
- if (unlikely(rcv_pkey_check(ppd_from_ibp(ibp), (u16)bth0, sc5,
- ib_get_slid(hdr)))) {
- hfi1_bad_pqkey(ibp, OPA_TRAP_BAD_P_KEY,
- (u16)bth0,
- ib_get_sl(hdr),
- 0, qp->ibqp.qp_num,
- ib_get_slid(hdr),
- ib_get_dlid(hdr));
- goto err;
+ if (unlikely(rcv_pkey_check(ppd_from_ibp(ibp), pkey,
+ sc5, slid))) {
+ hfi1_bad_pkey(ibp, pkey, sl, 0, qp->ibqp.qp_num,
+ slid, dlid);
+ return 1;
}
/* Validate the SLID. See Ch. 9.6.1.5 and 17.2.8 */
- if (ib_get_slid(hdr) !=
- rdma_ah_get_dlid(&qp->alt_ah_attr) ||
+ if (slid != rdma_ah_get_dlid(&qp->alt_ah_attr) ||
ppd_from_ibp(ibp)->port !=
rdma_ah_get_port_num(&qp->alt_ah_attr))
- goto err;
+ return 1;
spin_lock_irqsave(&qp->s_lock, flags);
hfi1_migrate_qp(qp);
spin_unlock_irqrestore(&qp->s_lock, flags);
} else {
- if (!has_grh) {
- if (rdma_ah_get_ah_flags(&qp->remote_ah_attr) &
- IB_AH_GRH)
- goto err;
+ if (!packet->grh) {
+ if ((rdma_ah_get_ah_flags(&qp->remote_ah_attr) &
+ IB_AH_GRH) &&
+ (packet->etype != RHF_RCV_TYPE_BYPASS))
+ return 1;
} else {
const struct ib_global_route *grh;
if (!(rdma_ah_get_ah_flags(&qp->remote_ah_attr) &
IB_AH_GRH))
- goto err;
+ return 1;
grh = rdma_ah_read_grh(&qp->remote_ah_attr);
guid = get_sguid(ibp, grh->sgid_index);
- if (!gid_ok(&hdr->u.l.grh.dgid, ibp->rvp.gid_prefix,
+ if (!gid_ok(&packet->grh->dgid, ibp->rvp.gid_prefix,
guid))
- goto err;
+ return 1;
if (!gid_ok(
- &hdr->u.l.grh.sgid,
+ &packet->grh->sgid,
grh->dgid.global.subnet_prefix,
grh->dgid.global.interface_id))
- goto err;
+ return 1;
}
- if (unlikely(rcv_pkey_check(ppd_from_ibp(ibp), (u16)bth0, sc5,
- ib_get_slid(hdr)))) {
- hfi1_bad_pqkey(ibp, OPA_TRAP_BAD_P_KEY,
- (u16)bth0,
- ib_get_sl(hdr),
- 0, qp->ibqp.qp_num,
- ib_get_slid(hdr),
- ib_get_dlid(hdr));
- goto err;
+ if (unlikely(rcv_pkey_check(ppd_from_ibp(ibp), pkey,
+ sc5, slid))) {
+ hfi1_bad_pkey(ibp, pkey, sl, 0, qp->ibqp.qp_num,
+ slid, dlid);
+ return 1;
}
/* Validate the SLID. See Ch. 9.6.1.5 */
- if (ib_get_slid(hdr) !=
- rdma_ah_get_dlid(&qp->remote_ah_attr) ||
+ if ((slid != rdma_ah_get_dlid(&qp->remote_ah_attr)) ||
ppd_from_ibp(ibp)->port != qp->port_num)
- goto err;
- if (qp->s_mig_state == IB_MIG_REARM &&
- !(bth0 & IB_BTH_MIG_REQ))
+ return 1;
+ if (qp->s_mig_state == IB_MIG_REARM && !migrated)
qp->s_mig_state = IB_MIG_ARMED;
}
return 0;
-
-err:
- return 1;
}
/**
@@ -643,7 +649,7 @@ done:
* @ibp: a pointer to the IB port
* @hdr: a pointer to the GRH header being constructed
* @grh: the global route address to send to
- * @hwords: the number of 32 bit words of header being sent
+ * @hwords: size of header after grh being sent in dwords
* @nwords: the number of 32 bit words of data being sent
*
* Return the size of the header in 32 bit words.
@@ -655,7 +661,7 @@ u32 hfi1_make_grh(struct hfi1_ibport *ibp, struct ib_grh *hdr,
cpu_to_be32((IB_GRH_VERSION << IB_GRH_VERSION_SHIFT) |
(grh->traffic_class << IB_GRH_TCLASS_SHIFT) |
(grh->flow_label << IB_GRH_FLOW_SHIFT));
- hdr->paylen = cpu_to_be16((hwords - 2 + nwords + SIZE_OF_CRC) << 2);
+ hdr->paylen = cpu_to_be16((hwords + nwords) << 2);
/* next_hdr is defined by C8-7 in ch. 8.4.1 */
hdr->next_hdr = IB_GRH_NEXT_HDR;
hdr->hop_limit = grh->hop_limit;
@@ -671,7 +677,8 @@ u32 hfi1_make_grh(struct hfi1_ibport *ibp, struct ib_grh *hdr,
return sizeof(struct ib_grh) / sizeof(u32);
}
-#define BTH2_OFFSET (offsetof(struct hfi1_sdma_header, hdr.u.oth.bth[2]) / 4)
+#define BTH2_OFFSET (offsetof(struct hfi1_sdma_header, \
+ hdr.ibh.u.oth.bth[2]) / 4)
/**
* build_ahg - create ahg in s_ahg
@@ -728,73 +735,186 @@ static inline void build_ahg(struct rvt_qp *qp, u32 npsn)
}
}
-void hfi1_make_ruc_header(struct rvt_qp *qp, struct ib_other_headers *ohdr,
- u32 bth0, u32 bth2, int middle,
- struct hfi1_pkt_state *ps)
+static inline void hfi1_make_ruc_bth(struct rvt_qp *qp,
+ struct ib_other_headers *ohdr,
+ u32 bth0, u32 bth1, u32 bth2)
+{
+ bth1 |= qp->remote_qpn;
+ ohdr->bth[0] = cpu_to_be32(bth0);
+ ohdr->bth[1] = cpu_to_be32(bth1);
+ ohdr->bth[2] = cpu_to_be32(bth2);
+}
+
+static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp,
+ struct ib_other_headers *ohdr,
+ u32 bth0, u32 bth2, int middle,
+ struct hfi1_pkt_state *ps)
{
struct hfi1_qp_priv *priv = qp->priv;
struct hfi1_ibport *ibp = ps->ibp;
- u16 lrh0;
- u32 nwords;
- u32 extra_bytes;
- u32 bth1;
-
- /* Construct the header. */
- extra_bytes = -ps->s_txreq->s_cur_size & 3;
- nwords = (ps->s_txreq->s_cur_size + extra_bytes) >> 2;
- lrh0 = HFI1_LRH_BTH;
+ struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
+ u32 bth1 = 0;
+ u32 slid;
+ u16 pkey = hfi1_get_pkey(ibp, qp->s_pkey_index);
+ u8 l4 = OPA_16B_L4_IB_LOCAL;
+ u8 extra_bytes = hfi1_get_16b_padding((qp->s_hdrwords << 2),
+ ps->s_txreq->s_cur_size);
+ u32 nwords = SIZE_OF_CRC + ((ps->s_txreq->s_cur_size +
+ extra_bytes + SIZE_OF_LT) >> 2);
+ u8 becn = 0;
+
+ if (unlikely(rdma_ah_get_ah_flags(&qp->remote_ah_attr) & IB_AH_GRH) &&
+ hfi1_check_mcast(rdma_ah_get_dlid(&qp->remote_ah_attr))) {
+ struct ib_grh *grh;
+ struct ib_global_route *grd =
+ rdma_ah_retrieve_grh(&qp->remote_ah_attr);
+ int hdrwords;
+
+ /*
+ * Ensure OPA GIDs are transformed to IB gids
+ * before creating the GRH.
+ */
+ if (grd->sgid_index == OPA_GID_INDEX)
+ grd->sgid_index = 0;
+ grh = &ps->s_txreq->phdr.hdr.opah.u.l.grh;
+ l4 = OPA_16B_L4_IB_GLOBAL;
+ hdrwords = qp->s_hdrwords - 4;
+ qp->s_hdrwords += hfi1_make_grh(ibp, grh, grd,
+ hdrwords, nwords);
+ middle = 0;
+ }
+
+ if (qp->s_mig_state == IB_MIG_MIGRATED)
+ bth1 |= OPA_BTH_MIG_REQ;
+ else
+ middle = 0;
+
+ if (middle)
+ build_ahg(qp, bth2);
+ else
+ qp->s_flags &= ~RVT_S_AHG_VALID;
+
+ bth0 |= pkey;
+ bth0 |= extra_bytes << 20;
+ if (qp->s_flags & RVT_S_ECN) {
+ qp->s_flags &= ~RVT_S_ECN;
+ /* we recently received a FECN, so return a BECN */
+ becn = 1;
+ }
+ hfi1_make_ruc_bth(qp, ohdr, bth0, bth1, bth2);
+
+ if (!ppd->lid)
+ slid = be32_to_cpu(OPA_LID_PERMISSIVE);
+ else
+ slid = ppd->lid |
+ (rdma_ah_get_path_bits(&qp->remote_ah_attr) &
+ ((1 << ppd->lmc) - 1));
+
+ hfi1_make_16b_hdr(&ps->s_txreq->phdr.hdr.opah,
+ slid,
+ opa_get_lid(rdma_ah_get_dlid(&qp->remote_ah_attr),
+ 16B),
+ (qp->s_hdrwords + nwords) >> 1,
+ pkey, becn, 0, l4, priv->s_sc);
+}
+
+static inline void hfi1_make_ruc_header_9B(struct rvt_qp *qp,
+ struct ib_other_headers *ohdr,
+ u32 bth0, u32 bth2, int middle,
+ struct hfi1_pkt_state *ps)
+{
+ struct hfi1_qp_priv *priv = qp->priv;
+ struct hfi1_ibport *ibp = ps->ibp;
+ struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
+ u32 bth1 = 0;
+ u16 pkey = hfi1_get_pkey(ibp, qp->s_pkey_index);
+ u16 lrh0 = HFI1_LRH_BTH;
+ u16 slid;
+ u8 extra_bytes = -ps->s_txreq->s_cur_size & 3;
+ u32 nwords = SIZE_OF_CRC + ((ps->s_txreq->s_cur_size +
+ extra_bytes) >> 2);
+
if (unlikely(rdma_ah_get_ah_flags(&qp->remote_ah_attr) & IB_AH_GRH)) {
+ struct ib_grh *grh = &ps->s_txreq->phdr.hdr.ibh.u.l.grh;
+ int hdrwords = qp->s_hdrwords - 2;
+
+ lrh0 = HFI1_LRH_GRH;
qp->s_hdrwords +=
- hfi1_make_grh(ibp,
- &ps->s_txreq->phdr.hdr.u.l.grh,
+ hfi1_make_grh(ibp, grh,
rdma_ah_read_grh(&qp->remote_ah_attr),
- qp->s_hdrwords, nwords);
- lrh0 = HFI1_LRH_GRH;
+ hdrwords, nwords);
middle = 0;
}
lrh0 |= (priv->s_sc & 0xf) << 12 |
(rdma_ah_get_sl(&qp->remote_ah_attr) & 0xf) << 4;
- /*
- * reset s_ahg/AHG fields
- *
- * This insures that the ahgentry/ahgcount
- * are at a non-AHG default to protect
- * build_verbs_tx_desc() from using
- * an include ahgidx.
- *
- * build_ahg() will modify as appropriate
- * to use the AHG feature.
- */
- priv->s_ahg->tx_flags = 0;
- priv->s_ahg->ahgcount = 0;
- priv->s_ahg->ahgidx = 0;
+
if (qp->s_mig_state == IB_MIG_MIGRATED)
bth0 |= IB_BTH_MIG_REQ;
else
middle = 0;
+
if (middle)
build_ahg(qp, bth2);
else
qp->s_flags &= ~RVT_S_AHG_VALID;
- ps->s_txreq->phdr.hdr.lrh[0] = cpu_to_be16(lrh0);
- ps->s_txreq->phdr.hdr.lrh[1] =
- cpu_to_be16(rdma_ah_get_dlid(&qp->remote_ah_attr));
- ps->s_txreq->phdr.hdr.lrh[2] =
- cpu_to_be16(qp->s_hdrwords + nwords + SIZE_OF_CRC);
- ps->s_txreq->phdr.hdr.lrh[3] =
- cpu_to_be16(ppd_from_ibp(ibp)->lid |
- rdma_ah_get_path_bits(&qp->remote_ah_attr));
- bth0 |= hfi1_get_pkey(ibp, qp->s_pkey_index);
+
+ bth0 |= pkey;
bth0 |= extra_bytes << 20;
- ohdr->bth[0] = cpu_to_be32(bth0);
- bth1 = qp->remote_qpn;
if (qp->s_flags & RVT_S_ECN) {
qp->s_flags &= ~RVT_S_ECN;
/* we recently received a FECN, so return a BECN */
bth1 |= (IB_BECN_MASK << IB_BECN_SHIFT);
}
- ohdr->bth[1] = cpu_to_be32(bth1);
- ohdr->bth[2] = cpu_to_be32(bth2);
+ hfi1_make_ruc_bth(qp, ohdr, bth0, bth1, bth2);
+
+ if (!ppd->lid)
+ slid = be16_to_cpu(IB_LID_PERMISSIVE);
+ else
+ slid = ppd->lid |
+ (rdma_ah_get_path_bits(&qp->remote_ah_attr) &
+ ((1 << ppd->lmc) - 1));
+ hfi1_make_ib_hdr(&ps->s_txreq->phdr.hdr.ibh,
+ lrh0,
+ qp->s_hdrwords + nwords,
+ opa_get_lid(rdma_ah_get_dlid(&qp->remote_ah_attr), 9B),
+ ppd_from_ibp(ibp)->lid |
+ rdma_ah_get_path_bits(&qp->remote_ah_attr));
+}
+
+typedef void (*hfi1_make_ruc_hdr)(struct rvt_qp *qp,
+ struct ib_other_headers *ohdr,
+ u32 bth0, u32 bth2, int middle,
+ struct hfi1_pkt_state *ps);
+
+/* We support only two types - 9B and 16B for now */
+static const hfi1_make_ruc_hdr hfi1_ruc_header_tbl[2] = {
+ [HFI1_PKT_TYPE_9B] = &hfi1_make_ruc_header_9B,
+ [HFI1_PKT_TYPE_16B] = &hfi1_make_ruc_header_16B
+};
+
+void hfi1_make_ruc_header(struct rvt_qp *qp, struct ib_other_headers *ohdr,
+ u32 bth0, u32 bth2, int middle,
+ struct hfi1_pkt_state *ps)
+{
+ struct hfi1_qp_priv *priv = qp->priv;
+
+ /*
+ * reset s_ahg/AHG fields
+ *
+ * This insures that the ahgentry/ahgcount
+ * are at a non-AHG default to protect
+ * build_verbs_tx_desc() from using
+ * an include ahgidx.
+ *
+ * build_ahg() will modify as appropriate
+ * to use the AHG feature.
+ */
+ priv->s_ahg->tx_flags = 0;
+ priv->s_ahg->ahgcount = 0;
+ priv->s_ahg->ahgidx = 0;
+
+ /* Make the appropriate header */
+ hfi1_ruc_header_tbl[priv->hdr_type](qp, ohdr, bth0, bth2, middle, ps);
}
/* when sending, force a reschedule every one of these periods */
@@ -816,6 +936,8 @@ void hfi1_make_ruc_header(struct rvt_qp *qp, struct ib_other_headers *ohdr,
static bool schedule_send_yield(struct rvt_qp *qp,
struct hfi1_pkt_state *ps)
{
+ ps->pkts_sent = true;
+
if (unlikely(time_after(jiffies, ps->timeout))) {
if (!ps->in_thread ||
workqueue_congested(ps->cpu, ps->ppd->hfi1_wq)) {
@@ -912,6 +1034,7 @@ void hfi1_do_send(struct rvt_qp *qp, bool in_thread)
ps.timeout = jiffies + ps.timeout_int;
ps.cpu = priv->s_sde ? priv->s_sde->cpu :
cpumask_first(cpumask_of_node(ps.ppd->dd->node));
+ ps.pkts_sent = false;
/* insure a pre-built packet is handled */
ps.s_txreq = get_waiting_verbs_txreq(qp);
@@ -934,7 +1057,7 @@ void hfi1_do_send(struct rvt_qp *qp, bool in_thread)
spin_lock_irqsave(&qp->s_lock, ps.flags);
}
} while (make_req(qp, &ps));
-
+ iowait_starve_clear(ps.pkts_sent, &priv->s_iowait);
spin_unlock_irqrestore(&qp->s_lock, ps.flags);
}
diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c
index bfd0d51..6781bcd 100644
--- a/drivers/infiniband/hw/hfi1/sdma.c
+++ b/drivers/infiniband/hw/hfi1/sdma.c
@@ -246,7 +246,7 @@ static void __sdma_process_event(
enum sdma_events event);
static void dump_sdma_state(struct sdma_engine *sde);
static void sdma_make_progress(struct sdma_engine *sde, u64 status);
-static void sdma_desc_avail(struct sdma_engine *sde, unsigned avail);
+static void sdma_desc_avail(struct sdma_engine *sde, uint avail);
static void sdma_flush_descq(struct sdma_engine *sde);
/**
@@ -325,7 +325,7 @@ static void sdma_wait_for_packet_egress(struct sdma_engine *sde,
/* timed out - bounce the link */
dd_dev_err(dd, "%s: engine %u timeout waiting for packets to egress, remaining count %u, bouncing link\n",
__func__, sde->this_idx, (u32)reg);
- queue_work(dd->pport->hfi1_wq,
+ queue_work(dd->pport->link_wq,
&dd->pport->link_bounce_work);
break;
}
@@ -1340,10 +1340,8 @@ static void sdma_clean(struct hfi1_devdata *dd, size_t num_engines)
* @dd: hfi1_devdata
* @port: port number (currently only zero)
*
- * sdma_init initializes the specified number of engines.
- *
- * The code initializes each sde, its csrs. Interrupts
- * are not required to be enabled.
+ * Initializes each sde and its csrs.
+ * Interrupts are not required to be enabled.
*
* Returns:
* 0 - success, -errno on failure
@@ -1764,13 +1762,14 @@ retry:
*
* This is called with head_lock held.
*/
-static void sdma_desc_avail(struct sdma_engine *sde, unsigned avail)
+static void sdma_desc_avail(struct sdma_engine *sde, uint avail)
{
struct iowait *wait, *nw;
struct iowait *waits[SDMA_WAIT_BATCH_SIZE];
- unsigned i, n = 0, seq;
+ uint i, n = 0, seq, max_idx = 0;
struct sdma_txreq *stx;
struct hfi1_ibdev *dev = &sde->dd->verbs_dev;
+ u8 max_starved_cnt = 0;
#ifdef CONFIG_SDMA_VERBOSITY
dd_dev_err(sde->dd, "CONFIG SDMA(%u) %s:%d %s()\n", sde->this_idx,
@@ -1805,6 +1804,9 @@ static void sdma_desc_avail(struct sdma_engine *sde, unsigned avail)
if (num_desc > avail)
break;
avail -= num_desc;
+ /* Find the most starved wait memeber */
+ iowait_starve_find_max(wait, &max_starved_cnt,
+ n, &max_idx);
list_del_init(&wait->list);
waits[n++] = wait;
}
@@ -1813,8 +1815,13 @@ static void sdma_desc_avail(struct sdma_engine *sde, unsigned avail)
}
} while (read_seqretry(&dev->iowait_lock, seq));
+ /* Schedule the most starved one first */
+ if (n)
+ waits[max_idx]->wakeup(waits[max_idx], SDMA_AVAIL_REASON);
+
for (i = 0; i < n; i++)
- waits[i]->wakeup(waits[i], SDMA_AVAIL_REASON);
+ if (i != max_idx)
+ waits[i]->wakeup(waits[i], SDMA_AVAIL_REASON);
}
/* head_lock must be held */
@@ -2351,7 +2358,8 @@ static inline u16 submit_tx(struct sdma_engine *sde, struct sdma_txreq *tx)
static int sdma_check_progress(
struct sdma_engine *sde,
struct iowait *wait,
- struct sdma_txreq *tx)
+ struct sdma_txreq *tx,
+ bool pkts_sent)
{
int ret;
@@ -2364,7 +2372,7 @@ static int sdma_check_progress(
seq = raw_seqcount_begin(
(const seqcount_t *)&sde->head_lock.seqcount);
- ret = wait->sleep(sde, wait, tx, seq);
+ ret = wait->sleep(sde, wait, tx, seq, pkts_sent);
if (ret == -EAGAIN)
sde->desc_avail = sdma_descq_freecnt(sde);
} else {
@@ -2378,6 +2386,7 @@ static int sdma_check_progress(
* @sde: sdma engine to use
* @wait: wait structure to use when full (may be NULL)
* @tx: sdma_txreq to submit
+ * @pkts_sent: has any packet been sent yet?
*
* The call submits the tx into the ring. If a iowait structure is non-NULL
* the packet will be queued to the list in wait.
@@ -2389,7 +2398,8 @@ static int sdma_check_progress(
*/
int sdma_send_txreq(struct sdma_engine *sde,
struct iowait *wait,
- struct sdma_txreq *tx)
+ struct sdma_txreq *tx,
+ bool pkts_sent)
{
int ret = 0;
u16 tail;
@@ -2431,7 +2441,7 @@ unlock_noconn:
ret = -ECOMM;
goto unlock;
nodesc:
- ret = sdma_check_progress(sde, wait, tx);
+ ret = sdma_check_progress(sde, wait, tx, pkts_sent);
if (ret == -EAGAIN) {
ret = 0;
goto retry;
@@ -2500,8 +2510,10 @@ retry:
}
update_tail:
total_count = submit_count + flush_count;
- if (wait)
+ if (wait) {
iowait_sdma_add(wait, total_count);
+ iowait_starve_clear(submit_count > 0, wait);
+ }
if (tail != INVALID_TAIL)
sdma_update_tail(sde, tail);
spin_unlock_irqrestore(&sde->tail_lock, flags);
@@ -2529,7 +2541,7 @@ unlock_noconn:
ret = -ECOMM;
goto update_tail;
nodesc:
- ret = sdma_check_progress(sde, wait, tx);
+ ret = sdma_check_progress(sde, wait, tx, submit_count > 0);
if (ret == -EAGAIN) {
ret = 0;
goto retry;
diff --git a/drivers/infiniband/hw/hfi1/sdma.h b/drivers/infiniband/hw/hfi1/sdma.h
index 64f10b8..107011d 100644
--- a/drivers/infiniband/hw/hfi1/sdma.h
+++ b/drivers/infiniband/hw/hfi1/sdma.h
@@ -852,7 +852,8 @@ struct iowait;
int sdma_send_txreq(struct sdma_engine *sde,
struct iowait *wait,
- struct sdma_txreq *tx);
+ struct sdma_txreq *tx,
+ bool pkts_sent);
int sdma_send_txlist(struct sdma_engine *sde,
struct iowait *wait,
struct list_head *tx_list,
diff --git a/drivers/infiniband/hw/hfi1/sysfs.c b/drivers/infiniband/hw/hfi1/sysfs.c
index 2f3bbca..6d2702ef 100644
--- a/drivers/infiniband/hw/hfi1/sysfs.c
+++ b/drivers/infiniband/hw/hfi1/sysfs.c
@@ -95,7 +95,7 @@ static void port_release(struct kobject *kobj)
/* nothing to do since memory is freed by hfi1_free_devdata() */
}
-static struct bin_attribute cc_table_bin_attr = {
+static const struct bin_attribute cc_table_bin_attr = {
.attr = {.name = "cc_table_bin", .mode = 0444},
.read = read_cc_table_bin,
.size = PAGE_SIZE,
@@ -137,7 +137,7 @@ static ssize_t read_cc_setting_bin(struct file *filp, struct kobject *kobj,
return count;
}
-static struct bin_attribute cc_setting_bin_attr = {
+static const struct bin_attribute cc_setting_bin_attr = {
.attr = {.name = "cc_settings_bin", .mode = 0444},
.read = read_cc_setting_bin,
.size = PAGE_SIZE,
diff --git a/drivers/infiniband/hw/hfi1/trace.c b/drivers/infiniband/hw/hfi1/trace.c
index eafae48..9938bb9 100644
--- a/drivers/infiniband/hw/hfi1/trace.c
+++ b/drivers/infiniband/hw/hfi1/trace.c
@@ -47,7 +47,7 @@
#define CREATE_TRACE_POINTS
#include "trace.h"
-u8 ibhdr_exhdr_len(struct ib_header *hdr)
+static u8 __get_ib_hdr_len(struct ib_header *hdr)
{
struct ib_other_headers *ohdr;
u8 opcode;
@@ -61,13 +61,69 @@ u8 ibhdr_exhdr_len(struct ib_header *hdr)
0 : hdr_len_by_opcode[opcode] - (12 + 8);
}
-#define IMM_PRN "imm %d"
-#define RETH_PRN "reth vaddr 0x%.16llx rkey 0x%.8x dlen 0x%.8x"
-#define AETH_PRN "aeth syn 0x%.2x %s msn 0x%.8x"
-#define DETH_PRN "deth qkey 0x%.8x sqpn 0x%.6x"
-#define IETH_PRN "ieth rkey 0x%.8x"
-#define ATOMICACKETH_PRN "origdata %llx"
-#define ATOMICETH_PRN "vaddr 0x%llx rkey 0x%.8x sdata %llx cdata %llx"
+static u8 __get_16b_hdr_len(struct hfi1_16b_header *hdr)
+{
+ struct ib_other_headers *ohdr;
+ u8 opcode;
+
+ if (hfi1_16B_get_l4(hdr) == OPA_16B_L4_IB_LOCAL)
+ ohdr = &hdr->u.oth;
+ else
+ ohdr = &hdr->u.l.oth;
+ opcode = ib_bth_get_opcode(ohdr);
+ return hdr_len_by_opcode[opcode] == 0 ?
+ 0 : hdr_len_by_opcode[opcode] - (12 + 8 + 8);
+}
+
+u8 hfi1_trace_packet_hdr_len(struct hfi1_packet *packet)
+{
+ if (packet->etype != RHF_RCV_TYPE_BYPASS)
+ return __get_ib_hdr_len(packet->hdr);
+ else
+ return __get_16b_hdr_len(packet->hdr);
+}
+
+u8 hfi1_trace_opa_hdr_len(struct hfi1_opa_header *opa_hdr)
+{
+ if (!opa_hdr->hdr_type)
+ return __get_ib_hdr_len(&opa_hdr->ibh);
+ else
+ return __get_16b_hdr_len(&opa_hdr->opah);
+}
+
+const char *hfi1_trace_get_packet_str(struct hfi1_packet *packet)
+{
+ if (packet->etype != RHF_RCV_TYPE_BYPASS)
+ return "IB";
+
+ switch (hfi1_16B_get_l2(packet->hdr)) {
+ case 0:
+ return "0";
+ case 1:
+ return "1";
+ case 2:
+ return "16B";
+ case 3:
+ return "9B";
+ }
+ return "";
+}
+
+const char *hfi1_trace_get_packet_type_str(u8 l4)
+{
+ if (l4)
+ return "16B";
+ else
+ return "9B";
+}
+
+#define IMM_PRN "imm:%d"
+#define RETH_PRN "reth vaddr:0x%.16llx rkey:0x%.8x dlen:0x%.8x"
+#define AETH_PRN "aeth syn:0x%.2x %s msn:0x%.8x"
+#define DETH_PRN "deth qkey:0x%.8x sqpn:0x%.6x"
+#define IETH_PRN "ieth rkey:0x%.8x"
+#define ATOMICACKETH_PRN "origdata:%llx"
+#define ATOMICETH_PRN "vaddr:0x%llx rkey:0x%.8x sdata:%llx cdata:%llx"
#define OP(transport, op) IB_OPCODE_## transport ## _ ## op
@@ -84,6 +140,125 @@ static const char *parse_syndrome(u8 syndrome)
return "";
}
+void hfi1_trace_parse_9b_bth(struct ib_other_headers *ohdr,
+ u8 *ack, u8 *becn, u8 *fecn, u8 *mig,
+ u8 *se, u8 *pad, u8 *opcode, u8 *tver,
+ u16 *pkey, u32 *psn, u32 *qpn)
+{
+ *ack = ib_bth_get_ackreq(ohdr);
+ *becn = ib_bth_get_becn(ohdr);
+ *fecn = ib_bth_get_fecn(ohdr);
+ *mig = ib_bth_get_migreq(ohdr);
+ *se = ib_bth_get_se(ohdr);
+ *pad = ib_bth_get_pad(ohdr);
+ *opcode = ib_bth_get_opcode(ohdr);
+ *tver = ib_bth_get_tver(ohdr);
+ *pkey = ib_bth_get_pkey(ohdr);
+ *psn = ib_bth_get_psn(ohdr);
+ *qpn = ib_bth_get_qpn(ohdr);
+}
+
+void hfi1_trace_parse_16b_bth(struct ib_other_headers *ohdr,
+ u8 *ack, u8 *mig, u8 *opcode,
+ u8 *pad, u8 *se, u8 *tver,
+ u32 *psn, u32 *qpn)
+{
+ *ack = ib_bth_get_ackreq(ohdr);
+ *mig = ib_bth_get_migreq(ohdr);
+ *opcode = ib_bth_get_opcode(ohdr);
+ *pad = ib_bth_get_pad(ohdr);
+ *se = ib_bth_get_se(ohdr);
+ *tver = ib_bth_get_tver(ohdr);
+ *psn = ib_bth_get_psn(ohdr);
+ *qpn = ib_bth_get_qpn(ohdr);
+}
+
+void hfi1_trace_parse_9b_hdr(struct ib_header *hdr, bool sc5,
+ u8 *lnh, u8 *lver, u8 *sl, u8 *sc,
+ u16 *len, u32 *dlid, u32 *slid)
+{
+ *lnh = ib_get_lnh(hdr);
+ *lver = ib_get_lver(hdr);
+ *sl = ib_get_sl(hdr);
+ *sc = ib_get_sc(hdr) | (sc5 << 4);
+ *len = ib_get_len(hdr);
+ *dlid = ib_get_dlid(hdr);
+ *slid = ib_get_slid(hdr);
+}
+
+void hfi1_trace_parse_16b_hdr(struct hfi1_16b_header *hdr,
+ u8 *age, u8 *becn, u8 *fecn,
+ u8 *l4, u8 *rc, u8 *sc,
+ u16 *entropy, u16 *len, u16 *pkey,
+ u32 *dlid, u32 *slid)
+{
+ *age = hfi1_16B_get_age(hdr);
+ *becn = hfi1_16B_get_becn(hdr);
+ *fecn = hfi1_16B_get_fecn(hdr);
+ *l4 = hfi1_16B_get_l4(hdr);
+ *rc = hfi1_16B_get_rc(hdr);
+ *sc = hfi1_16B_get_sc(hdr);
+ *entropy = hfi1_16B_get_entropy(hdr);
+ *len = hfi1_16B_get_len(hdr);
+ *pkey = hfi1_16B_get_pkey(hdr);
+ *dlid = hfi1_16B_get_dlid(hdr);
+ *slid = hfi1_16B_get_slid(hdr);
+}
+
+#define LRH_PRN "len:%d sc:%d dlid:0x%.4x slid:0x%.4x "
+#define LRH_9B_PRN "lnh:%d,%s lver:%d sl:%d"
+#define LRH_16B_PRN "age:%d becn:%d fecn:%d l4:%d " \
+ "rc:%d sc:%d pkey:0x%.4x entropy:0x%.4x"
+const char *hfi1_trace_fmt_lrh(struct trace_seq *p, bool bypass,
+ u8 age, u8 becn, u8 fecn, u8 l4,
+ u8 lnh, const char *lnh_name, u8 lver,
+ u8 rc, u8 sc, u8 sl, u16 entropy,
+ u16 len, u16 pkey, u32 dlid, u32 slid)
+{
+ const char *ret = trace_seq_buffer_ptr(p);
+
+ trace_seq_printf(p, LRH_PRN, len, sc, dlid, slid);
+
+ if (bypass)
+ trace_seq_printf(p, LRH_16B_PRN,
+ age, becn, fecn, l4, rc, sc, pkey, entropy);
+
+ else
+ trace_seq_printf(p, LRH_9B_PRN,
+ lnh, lnh_name, lver, sl);
+ trace_seq_putc(p, 0);
+
+ return ret;
+}
+
+#define BTH_9B_PRN \
+ "op:0x%.2x,%s se:%d m:%d pad:%d tver:%d pkey:0x%.4x " \
+ "f:%d b:%d qpn:0x%.6x a:%d psn:0x%.8x"
+#define BTH_16B_PRN \
+ "op:0x%.2x,%s se:%d m:%d pad:%d tver:%d " \
+ "qpn:0x%.6x a:%d psn:0x%.8x"
+const char *hfi1_trace_fmt_bth(struct trace_seq *p, bool bypass,
+ u8 ack, u8 becn, u8 fecn, u8 mig,
+ u8 se, u8 pad, u8 opcode, const char *opname,
+ u8 tver, u16 pkey, u32 psn, u32 qpn)
+{
+ const char *ret = trace_seq_buffer_ptr(p);
+
+ if (bypass)
+ trace_seq_printf(p, BTH_16B_PRN,
+ opcode, opname,
+ se, mig, pad, tver, qpn, ack, psn);
+
+ else
+ trace_seq_printf(p, BTH_9B_PRN,
+ opcode, opname,
+ se, mig, pad, tver, pkey, fecn, becn,
+ qpn, ack, psn);
+ trace_seq_putc(p, 0);
+
+ return ret;
+}
+
const char *parse_everbs_hdrs(
struct trace_seq *p,
u8 opcode,
diff --git a/drivers/infiniband/hw/hfi1/trace.h b/drivers/infiniband/hw/hfi1/trace.h
index 92dc88f..af50c07 100644
--- a/drivers/infiniband/hw/hfi1/trace.h
+++ b/drivers/infiniband/hw/hfi1/trace.h
@@ -1,5 +1,5 @@
/*
- * Copyright(c) 2015, 2016 Intel Corporation.
+ * Copyright(c) 2015 - 2017 Intel Corporation.
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
@@ -51,3 +51,4 @@
#include "trace_rc.h"
#include "trace_rx.h"
#include "trace_tx.h"
+#include "trace_mmu.h"
diff --git a/drivers/infiniband/hw/hfi1/trace_ibhdrs.h b/drivers/infiniband/hw/hfi1/trace_ibhdrs.h
index 090f6b5..6721f84 100644
--- a/drivers/infiniband/hw/hfi1/trace_ibhdrs.h
+++ b/drivers/infiniband/hw/hfi1/trace_ibhdrs.h
@@ -55,8 +55,79 @@
#undef TRACE_SYSTEM
#define TRACE_SYSTEM hfi1_ibhdrs
+#define ib_opcode_name(opcode) { IB_OPCODE_##opcode, #opcode }
+#define show_ib_opcode(opcode) \
+__print_symbolic(opcode, \
+ ib_opcode_name(RC_SEND_FIRST), \
+ ib_opcode_name(RC_SEND_MIDDLE), \
+ ib_opcode_name(RC_SEND_LAST), \
+ ib_opcode_name(RC_SEND_LAST_WITH_IMMEDIATE), \
+ ib_opcode_name(RC_SEND_ONLY), \
+ ib_opcode_name(RC_SEND_ONLY_WITH_IMMEDIATE), \
+ ib_opcode_name(RC_RDMA_WRITE_FIRST), \
+ ib_opcode_name(RC_RDMA_WRITE_MIDDLE), \
+ ib_opcode_name(RC_RDMA_WRITE_LAST), \
+ ib_opcode_name(RC_RDMA_WRITE_LAST_WITH_IMMEDIATE), \
+ ib_opcode_name(RC_RDMA_WRITE_ONLY), \
+ ib_opcode_name(RC_RDMA_WRITE_ONLY_WITH_IMMEDIATE), \
+ ib_opcode_name(RC_RDMA_READ_REQUEST), \
+ ib_opcode_name(RC_RDMA_READ_RESPONSE_FIRST), \
+ ib_opcode_name(RC_RDMA_READ_RESPONSE_MIDDLE), \
+ ib_opcode_name(RC_RDMA_READ_RESPONSE_LAST), \
+ ib_opcode_name(RC_RDMA_READ_RESPONSE_ONLY), \
+ ib_opcode_name(RC_ACKNOWLEDGE), \
+ ib_opcode_name(RC_ATOMIC_ACKNOWLEDGE), \
+ ib_opcode_name(RC_COMPARE_SWAP), \
+ ib_opcode_name(RC_FETCH_ADD), \
+ ib_opcode_name(UC_SEND_FIRST), \
+ ib_opcode_name(UC_SEND_MIDDLE), \
+ ib_opcode_name(UC_SEND_LAST), \
+ ib_opcode_name(UC_SEND_LAST_WITH_IMMEDIATE), \
+ ib_opcode_name(UC_SEND_ONLY), \
+ ib_opcode_name(UC_SEND_ONLY_WITH_IMMEDIATE), \
+ ib_opcode_name(UC_RDMA_WRITE_FIRST), \
+ ib_opcode_name(UC_RDMA_WRITE_MIDDLE), \
+ ib_opcode_name(UC_RDMA_WRITE_LAST), \
+ ib_opcode_name(UC_RDMA_WRITE_LAST_WITH_IMMEDIATE), \
+ ib_opcode_name(UC_RDMA_WRITE_ONLY), \
+ ib_opcode_name(UC_RDMA_WRITE_ONLY_WITH_IMMEDIATE), \
+ ib_opcode_name(UD_SEND_ONLY), \
+ ib_opcode_name(UD_SEND_ONLY_WITH_IMMEDIATE), \
+ ib_opcode_name(CNP))
+
u8 ibhdr_exhdr_len(struct ib_header *hdr);
const char *parse_everbs_hdrs(struct trace_seq *p, u8 opcode, void *ehdrs);
+u8 hfi1_trace_opa_hdr_len(struct hfi1_opa_header *opah);
+u8 hfi1_trace_packet_hdr_len(struct hfi1_packet *packet);
+const char *hfi1_trace_get_packet_type_str(u8 l4);
+const char *hfi1_trace_get_packet_str(struct hfi1_packet *packet);
+void hfi1_trace_parse_9b_bth(struct ib_other_headers *ohdr,
+ u8 *ack, u8 *becn, u8 *fecn, u8 *mig,
+ u8 *se, u8 *pad, u8 *opcode, u8 *tver,
+ u16 *pkey, u32 *psn, u32 *qpn);
+void hfi1_trace_parse_9b_hdr(struct ib_header *hdr, bool sc5,
+ u8 *lnh, u8 *lver, u8 *sl, u8 *sc,
+ u16 *len, u32 *dlid, u32 *slid);
+void hfi1_trace_parse_16b_bth(struct ib_other_headers *ohdr,
+ u8 *ack, u8 *mig, u8 *opcode,
+ u8 *pad, u8 *se, u8 *tver,
+ u32 *psn, u32 *qpn);
+void hfi1_trace_parse_16b_hdr(struct hfi1_16b_header *hdr,
+ u8 *age, u8 *becn, u8 *fecn,
+ u8 *l4, u8 *rc, u8 *sc,
+ u16 *entropy, u16 *len, u16 *pkey,
+ u32 *dlid, u32 *slid);
+
+const char *hfi1_trace_fmt_lrh(struct trace_seq *p, bool bypass,
+ u8 age, u8 becn, u8 fecn, u8 l4,
+ u8 lnh, const char *lnh_name, u8 lver,
+ u8 rc, u8 sc, u8 sl, u16 entropy,
+ u16 len, u16 pkey, u32 dlid, u32 slid);
+
+const char *hfi1_trace_fmt_bth(struct trace_seq *p, bool bypass,
+ u8 ack, u8 becn, u8 fecn, u8 mig,
+ u8 se, u8 pad, u8 opcode, const char *opname,
+ u8 tver, u16 pkey, u32 psn, u32 qpn);
#define __parse_ib_ehdrs(op, ehdrs) parse_everbs_hdrs(p, op, ehdrs)
@@ -65,140 +136,303 @@ const char *parse_everbs_hdrs(struct trace_seq *p, u8 opcode, void *ehdrs);
__print_symbolic(lrh, \
lrh_name(LRH_BTH), \
lrh_name(LRH_GRH))
+#define PKT_ENTRY(pkt) __string(ptype, hfi1_trace_get_packet_str(packet))
+#define PKT_ASSIGN(pkt) __assign_str(ptype, hfi1_trace_get_packet_str(packet))
-#define LRH_PRN "vl %d lver %d sl %d lnh %d,%s dlid %.4x len %d slid %.4x"
-#define BTH_PRN \
- "op 0x%.2x,%s se %d m %d pad %d tver %d pkey 0x%.4x " \
- "f %d b %d qpn 0x%.6x a %d psn 0x%.8x"
-#define EHDR_PRN "%s"
-
-DECLARE_EVENT_CLASS(hfi1_ibhdr_template,
+DECLARE_EVENT_CLASS(hfi1_input_ibhdr_template,
TP_PROTO(struct hfi1_devdata *dd,
- struct ib_header *hdr),
- TP_ARGS(dd, hdr),
+ struct hfi1_packet *packet,
+ bool sc5),
+ TP_ARGS(dd, packet, sc5),
TP_STRUCT__entry(
DD_DEV_ENTRY(dd)
- /* LRH */
- __field(u8, vl)
+ PKT_ENTRY(packet)
+ __field(bool, bypass)
+ __field(u8, ack)
+ __field(u8, age)
+ __field(u8, becn)
+ __field(u8, fecn)
+ __field(u8, l4)
+ __field(u8, lnh)
__field(u8, lver)
+ __field(u8, mig)
+ __field(u8, opcode)
+ __field(u8, pad)
+ __field(u8, rc)
+ __field(u8, sc)
+ __field(u8, se)
__field(u8, sl)
- __field(u8, lnh)
- __field(u16, dlid)
+ __field(u8, tver)
+ __field(u16, entropy)
__field(u16, len)
- __field(u16, slid)
- /* BTH */
+ __field(u16, pkey)
+ __field(u32, dlid)
+ __field(u32, psn)
+ __field(u32, qpn)
+ __field(u32, slid)
+ /* extended headers */
+ __dynamic_array(u8, ehdrs,
+ hfi1_trace_packet_hdr_len(packet))
+ ),
+ TP_fast_assign(
+ DD_DEV_ASSIGN(dd);
+ PKT_ASSIGN(packet);
+
+ if (packet->etype == RHF_RCV_TYPE_BYPASS) {
+ __entry->bypass = true;
+ hfi1_trace_parse_16b_hdr(packet->hdr,
+ &__entry->age,
+ &__entry->becn,
+ &__entry->fecn,
+ &__entry->l4,
+ &__entry->rc,
+ &__entry->sc,
+ &__entry->entropy,
+ &__entry->len,
+ &__entry->pkey,
+ &__entry->dlid,
+ &__entry->slid);
+
+ hfi1_trace_parse_16b_bth(packet->ohdr,
+ &__entry->ack,
+ &__entry->mig,
+ &__entry->opcode,
+ &__entry->pad,
+ &__entry->se,
+ &__entry->tver,
+ &__entry->psn,
+ &__entry->qpn);
+ } else {
+ __entry->bypass = false;
+ hfi1_trace_parse_9b_hdr(packet->hdr, sc5,
+ &__entry->lnh,
+ &__entry->lver,
+ &__entry->sl,
+ &__entry->sc,
+ &__entry->len,
+ &__entry->dlid,
+ &__entry->slid);
+
+ hfi1_trace_parse_9b_bth(packet->ohdr,
+ &__entry->ack,
+ &__entry->becn,
+ &__entry->fecn,
+ &__entry->mig,
+ &__entry->se,
+ &__entry->pad,
+ &__entry->opcode,
+ &__entry->tver,
+ &__entry->pkey,
+ &__entry->psn,
+ &__entry->qpn);
+ }
+ /* extended headers */
+ memcpy(__get_dynamic_array(ehdrs),
+ &packet->ohdr->u,
+ __get_dynamic_array_len(ehdrs));
+ ),
+ TP_printk("[%s] (%s) %s %s hlen:%d %s",
+ __get_str(dev),
+ __get_str(ptype),
+ hfi1_trace_fmt_lrh(p,
+ __entry->bypass,
+ __entry->age,
+ __entry->becn,
+ __entry->fecn,
+ __entry->l4,
+ __entry->lnh,
+ show_lnh(__entry->lnh),
+ __entry->lver,
+ __entry->rc,
+ __entry->sc,
+ __entry->sl,
+ __entry->entropy,
+ __entry->len,
+ __entry->pkey,
+ __entry->dlid,
+ __entry->slid),
+ hfi1_trace_fmt_bth(p,
+ __entry->bypass,
+ __entry->ack,
+ __entry->becn,
+ __entry->fecn,
+ __entry->mig,
+ __entry->se,
+ __entry->pad,
+ __entry->opcode,
+ show_ib_opcode(__entry->opcode),
+ __entry->tver,
+ __entry->pkey,
+ __entry->psn,
+ __entry->qpn),
+ /* extended headers */
+ __get_dynamic_array_len(ehdrs),
+ __parse_ib_ehdrs(
+ __entry->opcode,
+ (void *)__get_dynamic_array(ehdrs))
+ )
+);
+
+DEFINE_EVENT(hfi1_input_ibhdr_template, input_ibhdr,
+ TP_PROTO(struct hfi1_devdata *dd,
+ struct hfi1_packet *packet, bool sc5),
+ TP_ARGS(dd, packet, sc5));
+
+DECLARE_EVENT_CLASS(hfi1_output_ibhdr_template,
+ TP_PROTO(struct hfi1_devdata *dd,
+ struct hfi1_opa_header *opah, bool sc5),
+ TP_ARGS(dd, opah, sc5),
+ TP_STRUCT__entry(
+ DD_DEV_ENTRY(dd)
+ __field(bool, bypass)
+ __field(u8, ack)
+ __field(u8, age)
+ __field(u8, becn)
+ __field(u8, fecn)
+ __field(u8, l4)
+ __field(u8, lnh)
+ __field(u8, lver)
+ __field(u8, mig)
__field(u8, opcode)
- __field(u8, se)
- __field(u8, m)
__field(u8, pad)
+ __field(u8, rc)
+ __field(u8, sc)
+ __field(u8, se)
+ __field(u8, sl)
__field(u8, tver)
+ __field(u16, entropy)
+ __field(u16, len)
__field(u16, pkey)
- __field(u8, f)
- __field(u8, b)
- __field(u32, qpn)
- __field(u8, a)
+ __field(u32, dlid)
__field(u32, psn)
+ __field(u32, qpn)
+ __field(u32, slid)
/* extended headers */
- __dynamic_array(u8, ehdrs, ibhdr_exhdr_len(hdr))
+ __dynamic_array(u8, ehdrs,
+ hfi1_trace_opa_hdr_len(opah))
),
- TP_fast_assign(
+ TP_fast_assign(
struct ib_other_headers *ohdr;
DD_DEV_ASSIGN(dd);
- /* LRH */
- __entry->vl =
- (u8)(be16_to_cpu(hdr->lrh[0]) >> 12);
- __entry->lver =
- (u8)(be16_to_cpu(hdr->lrh[0]) >> 8) & 0xf;
- __entry->sl =
- (u8)(be16_to_cpu(hdr->lrh[0]) >> 4) & 0xf;
- __entry->lnh =
- (u8)(be16_to_cpu(hdr->lrh[0]) & 3);
- __entry->dlid =
- be16_to_cpu(hdr->lrh[1]);
- /* allow for larger len */
- __entry->len =
- be16_to_cpu(hdr->lrh[2]);
- __entry->slid =
- be16_to_cpu(hdr->lrh[3]);
- /* BTH */
- if (__entry->lnh == HFI1_LRH_BTH)
- ohdr = &hdr->u.oth;
- else
- ohdr = &hdr->u.l.oth;
- __entry->opcode =
- (be32_to_cpu(ohdr->bth[0]) >> 24) & 0xff;
- __entry->se =
- (be32_to_cpu(ohdr->bth[0]) >> 23) & 1;
- __entry->m =
- (be32_to_cpu(ohdr->bth[0]) >> 22) & 1;
- __entry->pad =
- (be32_to_cpu(ohdr->bth[0]) >> 20) & 3;
- __entry->tver =
- (be32_to_cpu(ohdr->bth[0]) >> 16) & 0xf;
- __entry->pkey =
- be32_to_cpu(ohdr->bth[0]) & 0xffff;
- __entry->f =
- (be32_to_cpu(ohdr->bth[1]) >> IB_FECN_SHIFT) &
- IB_FECN_MASK;
- __entry->b =
- (be32_to_cpu(ohdr->bth[1]) >> IB_BECN_SHIFT) &
- IB_BECN_MASK;
- __entry->qpn =
- be32_to_cpu(ohdr->bth[1]) & RVT_QPN_MASK;
- __entry->a =
- (be32_to_cpu(ohdr->bth[2]) >> 31) & 1;
- /* allow for larger PSN */
- __entry->psn =
- be32_to_cpu(ohdr->bth[2]) & 0x7fffffff;
+
+ if (opah->hdr_type) {
+ __entry->bypass = true;
+ hfi1_trace_parse_16b_hdr(&opah->opah,
+ &__entry->age,
+ &__entry->becn,
+ &__entry->fecn,
+ &__entry->l4,
+ &__entry->rc,
+ &__entry->sc,
+ &__entry->entropy,
+ &__entry->len,
+ &__entry->pkey,
+ &__entry->dlid,
+ &__entry->slid);
+
+ if (entry->l4 == OPA_16B_L4_IB_LOCAL)
+ ohdr = &opah->opah.u.oth;
+ else
+ ohdr = &opah->opah.u.l.oth;
+ hfi1_trace_parse_16b_bth(ohdr,
+ &__entry->ack,
+ &__entry->mig,
+ &__entry->opcode,
+ &__entry->pad,
+ &__entry->se,
+ &__entry->tver,
+ &__entry->psn,
+ &__entry->qpn);
+ } else {
+ __entry->bypass = false;
+ hfi1_trace_parse_9b_hdr(&opah->ibh, sc5,
+ &__entry->lnh,
+ &__entry->lver,
+ &__entry->sl,
+ &__entry->sc,
+ &__entry->len,
+ &__entry->dlid,
+ &__entry->slid);
+ if (entry->lnh == HFI1_LRH_BTH)
+ ohdr = &opah->ibh.u.oth;
+ else
+ ohdr = &opah->ibh.u.l.oth;
+ hfi1_trace_parse_9b_bth(ohdr,
+ &__entry->ack,
+ &__entry->becn,
+ &__entry->fecn,
+ &__entry->mig,
+ &__entry->se,
+ &__entry->pad,
+ &__entry->opcode,
+ &__entry->tver,
+ &__entry->pkey,
+ &__entry->psn,
+ &__entry->qpn);
+ }
+
/* extended headers */
- memcpy(__get_dynamic_array(ehdrs), &ohdr->u,
- ibhdr_exhdr_len(hdr));
- ),
- TP_printk("[%s] " LRH_PRN " " BTH_PRN " " EHDR_PRN,
- __get_str(dev),
- /* LRH */
- __entry->vl,
- __entry->lver,
- __entry->sl,
- __entry->lnh, show_lnh(__entry->lnh),
- __entry->dlid,
- __entry->len,
- __entry->slid,
- /* BTH */
- __entry->opcode, show_ib_opcode(__entry->opcode),
- __entry->se,
- __entry->m,
- __entry->pad,
- __entry->tver,
- __entry->pkey,
- __entry->f,
- __entry->b,
- __entry->qpn,
- __entry->a,
- __entry->psn,
- /* extended headers */
- __parse_ib_ehdrs(
- __entry->opcode,
- (void *)__get_dynamic_array(ehdrs))
- )
+ memcpy(__get_dynamic_array(ehdrs),
+ &ohdr->u, __get_dynamic_array_len(ehdrs));
+ ),
+ TP_printk("[%s] (%s) %s %s hlen:%d %s",
+ __get_str(dev),
+ hfi1_trace_get_packet_type_str(__entry->l4),
+ hfi1_trace_fmt_lrh(p,
+ __entry->bypass,
+ __entry->age,
+ __entry->becn,
+ __entry->fecn,
+ __entry->l4,
+ __entry->lnh,
+ show_lnh(__entry->lnh),
+ __entry->lver,
+ __entry->rc,
+ __entry->sc,
+ __entry->sl,
+ __entry->entropy,
+ __entry->len,
+ __entry->pkey,
+ __entry->dlid,
+ __entry->slid),
+ hfi1_trace_fmt_bth(p,
+ __entry->bypass,
+ __entry->ack,
+ __entry->becn,
+ __entry->fecn,
+ __entry->mig,
+ __entry->se,
+ __entry->pad,
+ __entry->opcode,
+ show_ib_opcode(__entry->opcode),
+ __entry->tver,
+ __entry->pkey,
+ __entry->psn,
+ __entry->qpn),
+ /* extended headers */
+ __get_dynamic_array_len(ehdrs),
+ __parse_ib_ehdrs(
+ __entry->opcode,
+ (void *)__get_dynamic_array(ehdrs))
+ )
);
-DEFINE_EVENT(hfi1_ibhdr_template, input_ibhdr,
- TP_PROTO(struct hfi1_devdata *dd, struct ib_header *hdr),
- TP_ARGS(dd, hdr));
+DEFINE_EVENT(hfi1_output_ibhdr_template, pio_output_ibhdr,
+ TP_PROTO(struct hfi1_devdata *dd,
+ struct hfi1_opa_header *opah, bool sc5),
+ TP_ARGS(dd, opah, sc5));
-DEFINE_EVENT(hfi1_ibhdr_template, pio_output_ibhdr,
- TP_PROTO(struct hfi1_devdata *dd, struct ib_header *hdr),
- TP_ARGS(dd, hdr));
+DEFINE_EVENT(hfi1_output_ibhdr_template, ack_output_ibhdr,
+ TP_PROTO(struct hfi1_devdata *dd,
+ struct hfi1_opa_header *opah, bool sc5),
+ TP_ARGS(dd, opah, sc5));
-DEFINE_EVENT(hfi1_ibhdr_template, ack_output_ibhdr,
- TP_PROTO(struct hfi1_devdata *dd, struct ib_header *hdr),
- TP_ARGS(dd, hdr));
+DEFINE_EVENT(hfi1_output_ibhdr_template, sdma_output_ibhdr,
+ TP_PROTO(struct hfi1_devdata *dd,
+ struct hfi1_opa_header *opah, bool sc5),
+ TP_ARGS(dd, opah, sc5));
-DEFINE_EVENT(hfi1_ibhdr_template, sdma_output_ibhdr,
- TP_PROTO(struct hfi1_devdata *dd, struct ib_header *hdr),
- TP_ARGS(dd, hdr));
#endif /* __HFI1_TRACE_IBHDRS_H */
diff --git a/drivers/infiniband/hw/hfi1/trace_misc.h b/drivers/infiniband/hw/hfi1/trace_misc.h
index deac77d..8db2253 100644
--- a/drivers/infiniband/hw/hfi1/trace_misc.h
+++ b/drivers/infiniband/hw/hfi1/trace_misc.h
@@ -72,6 +72,26 @@ TRACE_EVENT(hfi1_interrupt,
__entry->src)
);
+DECLARE_EVENT_CLASS(
+ hfi1_csr_template,
+ TP_PROTO(void __iomem *addr, u64 value),
+ TP_ARGS(addr, value),
+ TP_STRUCT__entry(
+ __field(void __iomem *, addr)
+ __field(u64, value)
+ ),
+ TP_fast_assign(
+ __entry->addr = addr;
+ __entry->value = value;
+ ),
+ TP_printk("addr %p value %llx", __entry->addr, __entry->value)
+);
+
+DEFINE_EVENT(
+ hfi1_csr_template, hfi1_write_rcvarray,
+ TP_PROTO(void __iomem *addr, u64 value),
+ TP_ARGS(addr, value));
+
#ifdef CONFIG_FAULT_INJECTION
TRACE_EVENT(hfi1_fault_opcode,
TP_PROTO(struct rvt_qp *qp, u8 opcode),
diff --git a/drivers/infiniband/hw/hfi1/trace_mmu.h b/drivers/infiniband/hw/hfi1/trace_mmu.h
new file mode 100644
index 0000000..3b7abbc
--- /dev/null
+++ b/drivers/infiniband/hw/hfi1/trace_mmu.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright(c) 2017 Intel Corporation.
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * BSD LICENSE
+ *
+ * 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 Intel Corporation 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE 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.
+ *
+ */
+#if !defined(__HFI1_TRACE_MMU_H) || defined(TRACE_HEADER_MULTI_READ)
+#define __HFI1_TRACE_MMU_H
+
+#include <linux/tracepoint.h>
+#include <linux/trace_seq.h>
+
+#include "hfi.h"
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM hfi1_mmu
+
+DECLARE_EVENT_CLASS(hfi1_mmu_rb_template,
+ TP_PROTO(unsigned long addr, unsigned long len),
+ TP_ARGS(addr, len),
+ TP_STRUCT__entry(__field(unsigned long, addr)
+ __field(unsigned long, len)
+ ),
+ TP_fast_assign(__entry->addr = addr;
+ __entry->len = len;
+ ),
+ TP_printk("MMU node addr 0x%lx, len %lu",
+ __entry->addr,
+ __entry->len
+ )
+);
+
+DEFINE_EVENT(hfi1_mmu_rb_template, hfi1_mmu_rb_insert,
+ TP_PROTO(unsigned long addr, unsigned long len),
+ TP_ARGS(addr, len));
+
+DEFINE_EVENT(hfi1_mmu_rb_template, hfi1_mmu_rb_search,
+ TP_PROTO(unsigned long addr, unsigned long len),
+ TP_ARGS(addr, len));
+
+DEFINE_EVENT(hfi1_mmu_rb_template, hfi1_mmu_rb_remove,
+ TP_PROTO(unsigned long addr, unsigned long len),
+ TP_ARGS(addr, len));
+
+DEFINE_EVENT(hfi1_mmu_rb_template, hfi1_mmu_mem_invalidate,
+ TP_PROTO(unsigned long addr, unsigned long len),
+ TP_ARGS(addr, len));
+
+#endif /* __HFI1_TRACE_RC_H */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE trace_mmu
+#include <trace/define_trace.h>
diff --git a/drivers/infiniband/hw/hfi1/trace_rx.h b/drivers/infiniband/hw/hfi1/trace_rx.h
index f77e59f..f9909d2 100644
--- a/drivers/infiniband/hw/hfi1/trace_rx.h
+++ b/drivers/infiniband/hw/hfi1/trace_rx.h
@@ -52,9 +52,25 @@
#include "hfi.h"
+#define tidtype_name(type) { PT_##type, #type }
+#define show_tidtype(type) \
+__print_symbolic(type, \
+ tidtype_name(EXPECTED), \
+ tidtype_name(EAGER), \
+ tidtype_name(INVALID)) \
+
#undef TRACE_SYSTEM
#define TRACE_SYSTEM hfi1_rx
+#define packettype_name(etype) { RHF_RCV_TYPE_##etype, #etype }
+#define show_packettype(etype) \
+__print_symbolic(etype, \
+ packettype_name(EXPECTED), \
+ packettype_name(EAGER), \
+ packettype_name(IB), \
+ packettype_name(ERROR), \
+ packettype_name(BYPASS))
+
TRACE_EVENT(hfi1_rcvhdr,
TP_PROTO(struct hfi1_devdata *dd,
u32 ctxt,
@@ -98,24 +114,24 @@ TRACE_EVENT(hfi1_rcvhdr,
);
TRACE_EVENT(hfi1_receive_interrupt,
- TP_PROTO(struct hfi1_devdata *dd, u32 ctxt),
- TP_ARGS(dd, ctxt),
+ TP_PROTO(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd),
+ TP_ARGS(dd, rcd),
TP_STRUCT__entry(DD_DEV_ENTRY(dd)
__field(u32, ctxt)
__field(u8, slow_path)
__field(u8, dma_rtail)
),
TP_fast_assign(DD_DEV_ASSIGN(dd);
- __entry->ctxt = ctxt;
- if (dd->rcd[ctxt]->do_interrupt ==
+ __entry->ctxt = rcd->ctxt;
+ if (rcd->do_interrupt ==
&handle_receive_interrupt) {
__entry->slow_path = 1;
__entry->dma_rtail = 0xFF;
- } else if (dd->rcd[ctxt]->do_interrupt ==
+ } else if (rcd->do_interrupt ==
&handle_receive_interrupt_dma_rtail){
__entry->dma_rtail = 1;
__entry->slow_path = 0;
- } else if (dd->rcd[ctxt]->do_interrupt ==
+ } else if (rcd->do_interrupt ==
&handle_receive_interrupt_nodma_rtail) {
__entry->dma_rtail = 0;
__entry->slow_path = 0;
@@ -129,7 +145,8 @@ TRACE_EVENT(hfi1_receive_interrupt,
)
);
-TRACE_EVENT(hfi1_exp_tid_reg,
+DECLARE_EVENT_CLASS(
+ hfi1_exp_tid_reg_unreg,
TP_PROTO(unsigned int ctxt, u16 subctxt, u32 rarr,
u32 npages, unsigned long va, unsigned long pa,
dma_addr_t dma),
@@ -163,38 +180,45 @@ TRACE_EVENT(hfi1_exp_tid_reg,
)
);
-TRACE_EVENT(hfi1_exp_tid_unreg,
- TP_PROTO(unsigned int ctxt, u16 subctxt, u32 rarr, u32 npages,
- unsigned long va, unsigned long pa, dma_addr_t dma),
- TP_ARGS(ctxt, subctxt, rarr, npages, va, pa, dma),
- TP_STRUCT__entry(
- __field(unsigned int, ctxt)
- __field(u16, subctxt)
- __field(u32, rarr)
- __field(u32, npages)
- __field(unsigned long, va)
- __field(unsigned long, pa)
- __field(dma_addr_t, dma)
- ),
- TP_fast_assign(
- __entry->ctxt = ctxt;
- __entry->subctxt = subctxt;
- __entry->rarr = rarr;
- __entry->npages = npages;
- __entry->va = va;
- __entry->pa = pa;
- __entry->dma = dma;
- ),
- TP_printk("[%u:%u] entry:%u, %u pages @ 0x%lx, va:0x%lx dma:0x%llx",
- __entry->ctxt,
- __entry->subctxt,
- __entry->rarr,
- __entry->npages,
- __entry->pa,
- __entry->va,
- __entry->dma
- )
- );
+DEFINE_EVENT(
+ hfi1_exp_tid_reg_unreg, hfi1_exp_tid_unreg,
+ TP_PROTO(unsigned int ctxt, u16 subctxt, u32 rarr, u32 npages,
+ unsigned long va, unsigned long pa, dma_addr_t dma),
+ TP_ARGS(ctxt, subctxt, rarr, npages, va, pa, dma));
+
+DEFINE_EVENT(
+ hfi1_exp_tid_reg_unreg, hfi1_exp_tid_reg,
+ TP_PROTO(unsigned int ctxt, u16 subctxt, u32 rarr, u32 npages,
+ unsigned long va, unsigned long pa, dma_addr_t dma),
+ TP_ARGS(ctxt, subctxt, rarr, npages, va, pa, dma));
+
+TRACE_EVENT(
+ hfi1_put_tid,
+ TP_PROTO(struct hfi1_devdata *dd,
+ u32 index, u32 type, unsigned long pa, u16 order),
+ TP_ARGS(dd, index, type, pa, order),
+ TP_STRUCT__entry(
+ DD_DEV_ENTRY(dd)
+ __field(unsigned long, pa);
+ __field(u32, index);
+ __field(u32, type);
+ __field(u16, order);
+ ),
+ TP_fast_assign(
+ DD_DEV_ASSIGN(dd);
+ __entry->pa = pa;
+ __entry->index = index;
+ __entry->type = type;
+ __entry->order = order;
+ ),
+ TP_printk("[%s] type %s pa %lx index %u order %u",
+ __get_str(dev),
+ show_tidtype(__entry->type),
+ __entry->pa,
+ __entry->index,
+ __entry->order
+ )
+);
TRACE_EVENT(hfi1_exp_tid_inval,
TP_PROTO(unsigned int ctxt, u16 subctxt, unsigned long va, u32 rarr,
diff --git a/drivers/infiniband/hw/hfi1/trace_tx.h b/drivers/infiniband/hw/hfi1/trace_tx.h
index c59809a..c57af3b 100644
--- a/drivers/infiniband/hw/hfi1/trace_tx.h
+++ b/drivers/infiniband/hw/hfi1/trace_tx.h
@@ -1,5 +1,5 @@
/*
- * Copyright(c) 2015, 2016 Intel Corporation.
+ * Copyright(c) 2015 - 2017 Intel Corporation.
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
@@ -198,6 +198,140 @@ TRACE_EVENT(hfi1_sdma_engine_select,
)
);
+TRACE_EVENT(hfi1_sdma_user_free_queues,
+ TP_PROTO(struct hfi1_devdata *dd, u16 ctxt, u16 subctxt),
+ TP_ARGS(dd, ctxt, subctxt),
+ TP_STRUCT__entry(DD_DEV_ENTRY(dd)
+ __field(u16, ctxt)
+ __field(u16, subctxt)
+ ),
+ TP_fast_assign(DD_DEV_ASSIGN(dd);
+ __entry->ctxt = ctxt;
+ __entry->subctxt = subctxt;
+ ),
+ TP_printk("[%s] SDMA [%u:%u] Freeing user SDMA queues",
+ __get_str(dev),
+ __entry->ctxt,
+ __entry->subctxt
+ )
+);
+
+TRACE_EVENT(hfi1_sdma_user_process_request,
+ TP_PROTO(struct hfi1_devdata *dd, u16 ctxt, u16 subctxt,
+ u16 comp_idx),
+ TP_ARGS(dd, ctxt, subctxt, comp_idx),
+ TP_STRUCT__entry(DD_DEV_ENTRY(dd)
+ __field(u16, ctxt)
+ __field(u16, subctxt)
+ __field(u16, comp_idx)
+ ),
+ TP_fast_assign(DD_DEV_ASSIGN(dd);
+ __entry->ctxt = ctxt;
+ __entry->subctxt = subctxt;
+ __entry->comp_idx = comp_idx;
+ ),
+ TP_printk("[%s] SDMA [%u:%u] Using req/comp entry: %u",
+ __get_str(dev),
+ __entry->ctxt,
+ __entry->subctxt,
+ __entry->comp_idx
+ )
+);
+
+DECLARE_EVENT_CLASS(
+ hfi1_sdma_value_template,
+ TP_PROTO(struct hfi1_devdata *dd, u16 ctxt, u16 subctxt, u16 comp_idx,
+ u32 value),
+ TP_ARGS(dd, ctxt, subctxt, comp_idx, value),
+ TP_STRUCT__entry(DD_DEV_ENTRY(dd)
+ __field(u16, ctxt)
+ __field(u16, subctxt)
+ __field(u16, comp_idx)
+ __field(u32, value)
+ ),
+ TP_fast_assign(DD_DEV_ASSIGN(dd);
+ __entry->ctxt = ctxt;
+ __entry->subctxt = subctxt;
+ __entry->comp_idx = comp_idx;
+ __entry->value = value;
+ ),
+ TP_printk("[%s] SDMA [%u:%u:%u] value: %u",
+ __get_str(dev),
+ __entry->ctxt,
+ __entry->subctxt,
+ __entry->comp_idx,
+ __entry->value
+ )
+);
+
+DEFINE_EVENT(hfi1_sdma_value_template, hfi1_sdma_user_initial_tidoffset,
+ TP_PROTO(struct hfi1_devdata *dd, u16 ctxt, u16 subctxt,
+ u16 comp_idx, u32 tidoffset),
+ TP_ARGS(dd, ctxt, subctxt, comp_idx, tidoffset));
+
+DEFINE_EVENT(hfi1_sdma_value_template, hfi1_sdma_user_data_length,
+ TP_PROTO(struct hfi1_devdata *dd, u16 ctxt, u16 subctxt,
+ u16 comp_idx, u32 data_len),
+ TP_ARGS(dd, ctxt, subctxt, comp_idx, data_len));
+
+DEFINE_EVENT(hfi1_sdma_value_template, hfi1_sdma_user_compute_length,
+ TP_PROTO(struct hfi1_devdata *dd, u16 ctxt, u16 subctxt,
+ u16 comp_idx, u32 data_len),
+ TP_ARGS(dd, ctxt, subctxt, comp_idx, data_len));
+
+TRACE_EVENT(hfi1_sdma_user_tid_info,
+ TP_PROTO(struct hfi1_devdata *dd, u16 ctxt, u16 subctxt,
+ u16 comp_idx, u32 tidoffset, u32 units, u8 shift),
+ TP_ARGS(dd, ctxt, subctxt, comp_idx, tidoffset, units, shift),
+ TP_STRUCT__entry(DD_DEV_ENTRY(dd)
+ __field(u16, ctxt)
+ __field(u16, subctxt)
+ __field(u16, comp_idx)
+ __field(u32, tidoffset)
+ __field(u32, units)
+ __field(u8, shift)
+ ),
+ TP_fast_assign(DD_DEV_ASSIGN(dd);
+ __entry->ctxt = ctxt;
+ __entry->subctxt = subctxt;
+ __entry->comp_idx = comp_idx;
+ __entry->tidoffset = tidoffset;
+ __entry->units = units;
+ __entry->shift = shift;
+ ),
+ TP_printk("[%s] SDMA [%u:%u:%u] TID offset %ubytes %uunits om %u",
+ __get_str(dev),
+ __entry->ctxt,
+ __entry->subctxt,
+ __entry->comp_idx,
+ __entry->tidoffset,
+ __entry->units,
+ __entry->shift
+ )
+);
+
+TRACE_EVENT(hfi1_sdma_request,
+ TP_PROTO(struct hfi1_devdata *dd, u16 ctxt, u16 subctxt,
+ unsigned long dim),
+ TP_ARGS(dd, ctxt, subctxt, dim),
+ TP_STRUCT__entry(DD_DEV_ENTRY(dd)
+ __field(u16, ctxt)
+ __field(u16, subctxt)
+ __field(unsigned long, dim)
+ ),
+ TP_fast_assign(DD_DEV_ASSIGN(dd);
+ __entry->ctxt = ctxt;
+ __entry->subctxt = subctxt;
+ __entry->dim = dim;
+ ),
+ TP_printk("[%s] SDMA from %u:%u (%lu)",
+ __get_str(dev),
+ __entry->ctxt,
+ __entry->subctxt,
+ __entry->dim
+ )
+);
+
DECLARE_EVENT_CLASS(hfi1_sdma_engine_class,
TP_PROTO(struct sdma_engine *sde, u64 status),
TP_ARGS(sde, status),
diff --git a/drivers/infiniband/hw/hfi1/uc.c b/drivers/infiniband/hw/hfi1/uc.c
index 5da1e45..0b64617 100644
--- a/drivers/infiniband/hw/hfi1/uc.c
+++ b/drivers/infiniband/hw/hfi1/uc.c
@@ -65,7 +65,7 @@ int hfi1_make_uc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
struct hfi1_qp_priv *priv = qp->priv;
struct ib_other_headers *ohdr;
struct rvt_swqe *wqe;
- u32 hwords = 5;
+ u32 hwords;
u32 bth0 = 0;
u32 len;
u32 pmtu = qp->pmtu;
@@ -93,9 +93,23 @@ int hfi1_make_uc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
goto done_free_tx;
}
- ohdr = &ps->s_txreq->phdr.hdr.u.oth;
- if (rdma_ah_get_ah_flags(&qp->remote_ah_attr) & IB_AH_GRH)
- ohdr = &ps->s_txreq->phdr.hdr.u.l.oth;
+ ps->s_txreq->phdr.hdr.hdr_type = priv->hdr_type;
+ if (priv->hdr_type == HFI1_PKT_TYPE_9B) {
+ /* header size in 32-bit words LRH+BTH = (8+12)/4. */
+ hwords = 5;
+ if (rdma_ah_get_ah_flags(&qp->remote_ah_attr) & IB_AH_GRH)
+ ohdr = &ps->s_txreq->phdr.hdr.ibh.u.l.oth;
+ else
+ ohdr = &ps->s_txreq->phdr.hdr.ibh.u.oth;
+ } else {
+ /* header size in 32-bit words 16B LRH+BTH = (16+12)/4. */
+ hwords = 7;
+ if ((rdma_ah_get_ah_flags(&qp->remote_ah_attr) & IB_AH_GRH) &&
+ (hfi1_check_mcast(rdma_ah_get_dlid(&qp->remote_ah_attr))))
+ ohdr = &ps->s_txreq->phdr.hdr.opah.u.l.oth;
+ else
+ ohdr = &ps->s_txreq->phdr.hdr.opah.u.oth;
+ }
/* Get the next send request. */
wqe = rvt_get_swqe_ptr(qp, qp->s_cur);
@@ -297,31 +311,26 @@ bail_no_tx:
void hfi1_uc_rcv(struct hfi1_packet *packet)
{
struct hfi1_ibport *ibp = rcd_to_iport(packet->rcd);
- struct ib_header *hdr = packet->hdr;
- u32 rcv_flags = packet->rcv_flags;
- void *data = packet->ebuf;
+ void *data = packet->payload;
u32 tlen = packet->tlen;
struct rvt_qp *qp = packet->qp;
struct ib_other_headers *ohdr = packet->ohdr;
- u32 bth0, opcode;
+ u32 opcode = packet->opcode;
u32 hdrsize = packet->hlen;
u32 psn;
- u32 pad;
+ u32 pad = packet->pad;
struct ib_wc wc;
u32 pmtu = qp->pmtu;
struct ib_reth *reth;
- int has_grh = rcv_flags & HFI1_HAS_GRH;
int ret;
+ u8 extra_bytes = pad + packet->extra_byte + (SIZE_OF_CRC << 2);
- bth0 = be32_to_cpu(ohdr->bth[0]);
- if (hfi1_ruc_check_hdr(ibp, hdr, has_grh, qp, bth0))
+ if (hfi1_ruc_check_hdr(ibp, packet))
return;
process_ecn(qp, packet, true);
- psn = be32_to_cpu(ohdr->bth[2]);
- opcode = ib_bth_get_opcode(ohdr);
-
+ psn = ib_bth_get_psn(ohdr);
/* Compare the PSN verses the expected PSN. */
if (unlikely(cmp_psn(psn, qp->r_psn) != 0)) {
/*
@@ -414,7 +423,12 @@ send_first:
/* FALLTHROUGH */
case OP(SEND_MIDDLE):
/* Check for invalid length PMTU or posted rwqe len. */
- if (unlikely(tlen != (hdrsize + pmtu + 4)))
+ /*
+ * There will be no padding for 9B packet but 16B packets
+ * will come in with some padding since we always add
+ * CRC and LT bytes which will need to be flit aligned
+ */
+ if (unlikely(tlen != (hdrsize + pmtu + extra_bytes)))
goto rewind;
qp->r_rcv_len += pmtu;
if (unlikely(qp->r_rcv_len > qp->r_len))
@@ -432,14 +446,12 @@ no_immediate_data:
wc.ex.imm_data = 0;
wc.wc_flags = 0;
send_last:
- /* Get the number of bytes the message was padded by. */
- pad = ib_bth_get_pad(ohdr);
/* Check for invalid length. */
/* LAST len should be >= 1 */
- if (unlikely(tlen < (hdrsize + pad + 4)))
+ if (unlikely(tlen < (hdrsize + extra_bytes)))
goto rewind;
/* Don't count the CRC. */
- tlen -= (hdrsize + pad + 4);
+ tlen -= (hdrsize + extra_bytes);
wc.byte_len = tlen + qp->r_rcv_len;
if (unlikely(wc.byte_len > qp->r_len))
goto rewind;
@@ -527,14 +539,12 @@ rdma_first:
rdma_last_imm:
wc.wc_flags = IB_WC_WITH_IMM;
- /* Get the number of bytes the message was padded by. */
- pad = ib_bth_get_pad(ohdr);
/* Check for invalid length. */
/* LAST len should be >= 1 */
if (unlikely(tlen < (hdrsize + pad + 4)))
goto drop;
/* Don't count the CRC. */
- tlen -= (hdrsize + pad + 4);
+ tlen -= (hdrsize + extra_bytes);
if (unlikely(tlen + qp->r_rcv_len != qp->r_len))
goto drop;
if (test_and_clear_bit(RVT_R_REWIND_SGE, &qp->r_aflags)) {
@@ -554,14 +564,12 @@ rdma_last_imm:
case OP(RDMA_WRITE_LAST):
rdma_last:
- /* Get the number of bytes the message was padded by. */
- pad = ib_bth_get_pad(ohdr);
/* Check for invalid length. */
/* LAST len should be >= 1 */
if (unlikely(tlen < (hdrsize + pad + 4)))
goto drop;
/* Don't count the CRC. */
- tlen -= (hdrsize + pad + 4);
+ tlen -= (hdrsize + extra_bytes);
if (unlikely(tlen + qp->r_rcv_len != qp->r_len))
goto drop;
hfi1_copy_sge(&qp->r_sge, data, tlen, true, false);
diff --git a/drivers/infiniband/hw/hfi1/ud.c b/drivers/infiniband/hw/hfi1/ud.c
index 6a4e95c..2ba74fd 100644
--- a/drivers/infiniband/hw/hfi1/ud.c
+++ b/drivers/infiniband/hw/hfi1/ud.c
@@ -53,6 +53,12 @@
#include "verbs_txreq.h"
#include "qp.h"
+/* We support only two types - 9B and 16B for now */
+static const hfi1_make_req hfi1_make_ud_req_tbl[2] = {
+ [HFI1_PKT_TYPE_9B] = &hfi1_make_ud_req_9B,
+ [HFI1_PKT_TYPE_16B] = &hfi1_make_ud_req_16B
+};
+
/**
* ud_loopback - handle send on loopback QPs
* @sqp: the sending QP
@@ -67,6 +73,7 @@ static void ud_loopback(struct rvt_qp *sqp, struct rvt_swqe *swqe)
{
struct hfi1_ibport *ibp = to_iport(sqp->ibqp.device, sqp->port_num);
struct hfi1_pportdata *ppd;
+ struct hfi1_qp_priv *priv = sqp->priv;
struct rvt_qp *qp;
struct rdma_ah_attr *ah_attr;
unsigned long flags;
@@ -102,18 +109,19 @@ static void ud_loopback(struct rvt_qp *sqp, struct rvt_swqe *swqe)
if (qp->ibqp.qp_num > 1) {
u16 pkey;
- u16 slid;
+ u32 slid;
u8 sc5 = ibp->sl_to_sc[rdma_ah_get_sl(ah_attr)];
pkey = hfi1_get_pkey(ibp, sqp->s_pkey_index);
slid = ppd->lid | (rdma_ah_get_path_bits(ah_attr) &
((1 << ppd->lmc) - 1));
if (unlikely(ingress_pkey_check(ppd, pkey, sc5,
- qp->s_pkey_index, slid))) {
- hfi1_bad_pqkey(ibp, OPA_TRAP_BAD_P_KEY, pkey,
- rdma_ah_get_sl(ah_attr),
- sqp->ibqp.qp_num, qp->ibqp.qp_num,
- slid, rdma_ah_get_dlid(ah_attr));
+ qp->s_pkey_index,
+ slid, false))) {
+ hfi1_bad_pkey(ibp, pkey,
+ rdma_ah_get_sl(ah_attr),
+ sqp->ibqp.qp_num, qp->ibqp.qp_num,
+ slid, rdma_ah_get_dlid(ah_attr));
goto drop;
}
}
@@ -128,18 +136,8 @@ static void ud_loopback(struct rvt_qp *sqp, struct rvt_swqe *swqe)
qkey = (int)swqe->ud_wr.remote_qkey < 0 ?
sqp->qkey : swqe->ud_wr.remote_qkey;
- if (unlikely(qkey != qp->qkey)) {
- u16 lid;
-
- lid = ppd->lid | (rdma_ah_get_path_bits(ah_attr) &
- ((1 << ppd->lmc) - 1));
- hfi1_bad_pqkey(ibp, OPA_TRAP_BAD_Q_KEY, qkey,
- rdma_ah_get_sl(ah_attr),
- sqp->ibqp.qp_num, qp->ibqp.qp_num,
- lid,
- rdma_ah_get_dlid(ah_attr));
- goto drop;
- }
+ if (unlikely(qkey != qp->qkey))
+ goto drop; /* silently drop per IBTA spec */
}
/*
@@ -185,9 +183,33 @@ static void ud_loopback(struct rvt_qp *sqp, struct rvt_swqe *swqe)
if (rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH) {
struct ib_grh grh;
- const struct ib_global_route *grd = rdma_ah_read_grh(ah_attr);
+ struct ib_global_route grd = *(rdma_ah_read_grh(ah_attr));
+
+ /*
+ * For loopback packets with extended LIDs, the
+ * sgid_index in the GRH is 0 and the dgid is
+ * OPA GID of the sender. While creating a response
+ * to the loopback packet, IB core creates the new
+ * sgid_index from the DGID and that will be the
+ * OPA_GID_INDEX. The new dgid is from the sgid
+ * index and that will be in the IB GID format.
+ *
+ * We now have a case where the sent packet had a
+ * different sgid_index and dgid compared to the
+ * one that was received in response.
+ *
+ * Fix this inconsistency.
+ */
+ if (priv->hdr_type == HFI1_PKT_TYPE_16B) {
+ if (grd.sgid_index == 0)
+ grd.sgid_index = OPA_GID_INDEX;
+
+ if (ib_is_opa_gid(&grd.dgid))
+ grd.dgid.global.interface_id =
+ cpu_to_be64(ppd->guids[HFI1_PORT_GUID_INDEX]);
+ }
- hfi1_make_grh(ibp, &grh, grd, 0, 0);
+ hfi1_make_grh(ibp, &grh, &grd, 0, 0);
hfi1_copy_sge(&qp->r_sge, &grh,
sizeof(grh), true, false);
wc.wc_flags |= IB_WC_GRH;
@@ -244,7 +266,7 @@ static void ud_loopback(struct rvt_qp *sqp, struct rvt_swqe *swqe)
wc.pkey_index = 0;
}
wc.slid = ppd->lid | (rdma_ah_get_path_bits(ah_attr) &
- ((1 << ppd->lmc) - 1));
+ ((1 << ppd->lmc) - 1));
/* Check for loopback when the port lid is not set */
if (wc.slid == 0 && sqp->ibqp.qp_type == IB_QPT_GSI)
wc.slid = be16_to_cpu(IB_LID_PERMISSIVE);
@@ -261,6 +283,183 @@ drop:
rcu_read_unlock();
}
+static void hfi1_make_bth_deth(struct rvt_qp *qp, struct rvt_swqe *wqe,
+ struct ib_other_headers *ohdr,
+ u16 *pkey, u32 extra_bytes, bool bypass)
+{
+ u32 bth0;
+ struct hfi1_ibport *ibp;
+
+ ibp = to_iport(qp->ibqp.device, qp->port_num);
+ if (wqe->wr.opcode == IB_WR_SEND_WITH_IMM) {
+ ohdr->u.ud.imm_data = wqe->wr.ex.imm_data;
+ bth0 = IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE << 24;
+ } else {
+ bth0 = IB_OPCODE_UD_SEND_ONLY << 24;
+ }
+
+ if (wqe->wr.send_flags & IB_SEND_SOLICITED)
+ bth0 |= IB_BTH_SOLICITED;
+ bth0 |= extra_bytes << 20;
+ if (qp->ibqp.qp_type == IB_QPT_GSI || qp->ibqp.qp_type == IB_QPT_SMI)
+ *pkey = hfi1_get_pkey(ibp, wqe->ud_wr.pkey_index);
+ else
+ *pkey = hfi1_get_pkey(ibp, qp->s_pkey_index);
+ if (!bypass)
+ bth0 |= *pkey;
+ ohdr->bth[0] = cpu_to_be32(bth0);
+ ohdr->bth[1] = cpu_to_be32(wqe->ud_wr.remote_qpn);
+ ohdr->bth[2] = cpu_to_be32(mask_psn(wqe->psn));
+ /*
+ * Qkeys with the high order bit set mean use the
+ * qkey from the QP context instead of the WR (see 10.2.5).
+ */
+ ohdr->u.ud.deth[0] = cpu_to_be32((int)wqe->ud_wr.remote_qkey < 0 ?
+ qp->qkey : wqe->ud_wr.remote_qkey);
+ ohdr->u.ud.deth[1] = cpu_to_be32(qp->ibqp.qp_num);
+}
+
+void hfi1_make_ud_req_9B(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
+ struct rvt_swqe *wqe)
+{
+ u32 nwords, extra_bytes;
+ u16 len, slid, dlid, pkey;
+ u16 lrh0 = 0;
+ u8 sc5;
+ struct hfi1_qp_priv *priv = qp->priv;
+ struct ib_other_headers *ohdr;
+ struct rdma_ah_attr *ah_attr;
+ struct hfi1_pportdata *ppd;
+ struct hfi1_ibport *ibp;
+ struct ib_grh *grh;
+
+ ibp = to_iport(qp->ibqp.device, qp->port_num);
+ ppd = ppd_from_ibp(ibp);
+ ah_attr = &ibah_to_rvtah(wqe->ud_wr.ah)->attr;
+
+ extra_bytes = -wqe->length & 3;
+ nwords = ((wqe->length + extra_bytes) >> 2) + SIZE_OF_CRC;
+ /* header size in dwords LRH+BTH+DETH = (8+12+8)/4. */
+ qp->s_hdrwords = 7;
+ if (wqe->wr.opcode == IB_WR_SEND_WITH_IMM)
+ qp->s_hdrwords++;
+
+ if (rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH) {
+ grh = &ps->s_txreq->phdr.hdr.ibh.u.l.grh;
+ qp->s_hdrwords += hfi1_make_grh(ibp, grh,
+ rdma_ah_read_grh(ah_attr),
+ qp->s_hdrwords - 2, nwords);
+ lrh0 = HFI1_LRH_GRH;
+ ohdr = &ps->s_txreq->phdr.hdr.ibh.u.l.oth;
+ } else {
+ lrh0 = HFI1_LRH_BTH;
+ ohdr = &ps->s_txreq->phdr.hdr.ibh.u.oth;
+ }
+
+ sc5 = ibp->sl_to_sc[rdma_ah_get_sl(ah_attr)];
+ lrh0 |= (rdma_ah_get_sl(ah_attr) & 0xf) << 4;
+ if (qp->ibqp.qp_type == IB_QPT_SMI) {
+ lrh0 |= 0xF000; /* Set VL (see ch. 13.5.3.1) */
+ priv->s_sc = 0xf;
+ } else {
+ lrh0 |= (sc5 & 0xf) << 12;
+ priv->s_sc = sc5;
+ }
+
+ dlid = opa_get_lid(rdma_ah_get_dlid(ah_attr), 9B);
+ if (dlid == be16_to_cpu(IB_LID_PERMISSIVE)) {
+ slid = be16_to_cpu(IB_LID_PERMISSIVE);
+ } else {
+ u16 lid = (u16)ppd->lid;
+
+ if (lid) {
+ lid |= rdma_ah_get_path_bits(ah_attr) &
+ ((1 << ppd->lmc) - 1);
+ slid = lid;
+ } else {
+ slid = be16_to_cpu(IB_LID_PERMISSIVE);
+ }
+ }
+ hfi1_make_bth_deth(qp, wqe, ohdr, &pkey, extra_bytes, false);
+ len = qp->s_hdrwords + nwords;
+
+ /* Setup the packet */
+ ps->s_txreq->phdr.hdr.hdr_type = HFI1_PKT_TYPE_9B;
+ hfi1_make_ib_hdr(&ps->s_txreq->phdr.hdr.ibh,
+ lrh0, len, dlid, slid);
+}
+
+void hfi1_make_ud_req_16B(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
+ struct rvt_swqe *wqe)
+{
+ struct hfi1_qp_priv *priv = qp->priv;
+ struct ib_other_headers *ohdr;
+ struct rdma_ah_attr *ah_attr;
+ struct hfi1_pportdata *ppd;
+ struct hfi1_ibport *ibp;
+ u32 dlid, slid, nwords, extra_bytes;
+ u16 len, pkey;
+ u8 l4, sc5;
+
+ ibp = to_iport(qp->ibqp.device, qp->port_num);
+ ppd = ppd_from_ibp(ibp);
+ ah_attr = &ibah_to_rvtah(wqe->ud_wr.ah)->attr;
+ /* header size in dwords 16B LRH+BTH+DETH = (16+12+8)/4. */
+ qp->s_hdrwords = 9;
+ if (wqe->wr.opcode == IB_WR_SEND_WITH_IMM)
+ qp->s_hdrwords++;
+
+ /* SW provides space for CRC and LT for bypass packets. */
+ extra_bytes = hfi1_get_16b_padding((qp->s_hdrwords << 2),
+ wqe->length);
+ nwords = ((wqe->length + extra_bytes + SIZE_OF_LT) >> 2) + SIZE_OF_CRC;
+
+ if ((rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH) &&
+ hfi1_check_mcast(rdma_ah_get_dlid(ah_attr))) {
+ struct ib_grh *grh;
+ struct ib_global_route *grd = rdma_ah_retrieve_grh(ah_attr);
+ /*
+ * Ensure OPA GIDs are transformed to IB gids
+ * before creating the GRH.
+ */
+ if (grd->sgid_index == OPA_GID_INDEX) {
+ dd_dev_warn(ppd->dd, "Bad sgid_index. sgid_index: %d\n",
+ grd->sgid_index);
+ grd->sgid_index = 0;
+ }
+ grh = &ps->s_txreq->phdr.hdr.opah.u.l.grh;
+ qp->s_hdrwords += hfi1_make_grh(ibp, grh, grd,
+ qp->s_hdrwords - 4, nwords);
+ ohdr = &ps->s_txreq->phdr.hdr.opah.u.l.oth;
+ l4 = OPA_16B_L4_IB_GLOBAL;
+ } else {
+ ohdr = &ps->s_txreq->phdr.hdr.opah.u.oth;
+ l4 = OPA_16B_L4_IB_LOCAL;
+ }
+
+ sc5 = ibp->sl_to_sc[rdma_ah_get_sl(ah_attr)];
+ if (qp->ibqp.qp_type == IB_QPT_SMI)
+ priv->s_sc = 0xf;
+ else
+ priv->s_sc = sc5;
+
+ dlid = opa_get_lid(rdma_ah_get_dlid(ah_attr), 16B);
+ if (!ppd->lid)
+ slid = be32_to_cpu(OPA_LID_PERMISSIVE);
+ else
+ slid = ppd->lid | (rdma_ah_get_path_bits(ah_attr) &
+ ((1 << ppd->lmc) - 1));
+
+ hfi1_make_bth_deth(qp, wqe, ohdr, &pkey, extra_bytes, true);
+ /* Convert dwords to flits */
+ len = (qp->s_hdrwords + nwords) >> 1;
+
+ /* Setup the packet */
+ ps->s_txreq->phdr.hdr.hdr_type = HFI1_PKT_TYPE_16B;
+ hfi1_make_16b_hdr(&ps->s_txreq->phdr.hdr.opah,
+ slid, dlid, len, pkey, 0, 0, l4, priv->s_sc);
+}
+
/**
* hfi1_make_ud_req - construct a UD request packet
* @qp: the QP
@@ -272,18 +471,12 @@ drop:
int hfi1_make_ud_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
{
struct hfi1_qp_priv *priv = qp->priv;
- struct ib_other_headers *ohdr;
struct rdma_ah_attr *ah_attr;
struct hfi1_pportdata *ppd;
struct hfi1_ibport *ibp;
struct rvt_swqe *wqe;
- u32 nwords;
- u32 extra_bytes;
- u32 bth0;
- u16 lrh0;
- u16 lid;
int next_cur;
- u8 sc5;
+ u32 lid;
ps->s_txreq = get_txreq(ps->dev, qp);
if (IS_ERR(ps->s_txreq))
@@ -320,13 +513,14 @@ int hfi1_make_ud_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
ibp = to_iport(qp->ibqp.device, qp->port_num);
ppd = ppd_from_ibp(ibp);
ah_attr = &ibah_to_rvtah(wqe->ud_wr.ah)->attr;
- if (rdma_ah_get_dlid(ah_attr) < be16_to_cpu(IB_MULTICAST_LID_BASE) ||
- rdma_ah_get_dlid(ah_attr) == be16_to_cpu(IB_LID_PERMISSIVE)) {
+ priv->hdr_type = hfi1_get_hdr_type(ppd->lid, ah_attr);
+ if ((!hfi1_check_mcast(rdma_ah_get_dlid(ah_attr))) ||
+ (rdma_ah_get_dlid(ah_attr) == be32_to_cpu(OPA_LID_PERMISSIVE))) {
lid = rdma_ah_get_dlid(ah_attr) & ~((1 << ppd->lmc) - 1);
if (unlikely(!loopback &&
- (lid == ppd->lid ||
- (lid == be16_to_cpu(IB_LID_PERMISSIVE) &&
- qp->ibqp.qp_type == IB_QPT_GSI)))) {
+ ((lid == ppd->lid) ||
+ ((lid == be32_to_cpu(OPA_LID_PERMISSIVE)) &&
+ (qp->ibqp.qp_type == IB_QPT_GSI))))) {
unsigned long tflags = ps->flags;
/*
* If DMAs are in progress, we can't generate
@@ -350,11 +544,6 @@ int hfi1_make_ud_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
}
qp->s_cur = next_cur;
- extra_bytes = -wqe->length & 3;
- nwords = (wqe->length + extra_bytes) >> 2;
-
- /* header size in 32-bit words LRH+BTH+DETH = (8+12+8)/4. */
- qp->s_hdrwords = 7;
ps->s_txreq->s_cur_size = wqe->length;
ps->s_txreq->ss = &qp->s_sge;
qp->s_srate = rdma_ah_get_static_rate(ah_attr);
@@ -365,77 +554,12 @@ int hfi1_make_ud_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
qp->s_sge.num_sge = wqe->wr.num_sge;
qp->s_sge.total_len = wqe->length;
- if (rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH) {
- /* Header size in 32-bit words. */
- qp->s_hdrwords += hfi1_make_grh(ibp,
- &ps->s_txreq->phdr.hdr.u.l.grh,
- rdma_ah_read_grh(ah_attr),
- qp->s_hdrwords, nwords);
- lrh0 = HFI1_LRH_GRH;
- ohdr = &ps->s_txreq->phdr.hdr.u.l.oth;
- /*
- * Don't worry about sending to locally attached multicast
- * QPs. It is unspecified by the spec. what happens.
- */
- } else {
- /* Header size in 32-bit words. */
- lrh0 = HFI1_LRH_BTH;
- ohdr = &ps->s_txreq->phdr.hdr.u.oth;
- }
- if (wqe->wr.opcode == IB_WR_SEND_WITH_IMM) {
- qp->s_hdrwords++;
- ohdr->u.ud.imm_data = wqe->wr.ex.imm_data;
- bth0 = IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE << 24;
- } else {
- bth0 = IB_OPCODE_UD_SEND_ONLY << 24;
- }
- sc5 = ibp->sl_to_sc[rdma_ah_get_sl(ah_attr)];
- lrh0 |= (rdma_ah_get_sl(ah_attr) & 0xf) << 4;
- if (qp->ibqp.qp_type == IB_QPT_SMI) {
- lrh0 |= 0xF000; /* Set VL (see ch. 13.5.3.1) */
- priv->s_sc = 0xf;
- } else {
- lrh0 |= (sc5 & 0xf) << 12;
- priv->s_sc = sc5;
- }
+ /* Make the appropriate header */
+ hfi1_make_ud_req_tbl[priv->hdr_type](qp, ps, qp->s_wqe);
priv->s_sde = qp_to_sdma_engine(qp, priv->s_sc);
ps->s_txreq->sde = priv->s_sde;
priv->s_sendcontext = qp_to_send_context(qp, priv->s_sc);
ps->s_txreq->psc = priv->s_sendcontext;
- ps->s_txreq->phdr.hdr.lrh[0] = cpu_to_be16(lrh0);
- ps->s_txreq->phdr.hdr.lrh[1] =
- cpu_to_be16(rdma_ah_get_dlid(ah_attr));
- ps->s_txreq->phdr.hdr.lrh[2] =
- cpu_to_be16(qp->s_hdrwords + nwords + SIZE_OF_CRC);
- if (rdma_ah_get_dlid(ah_attr) == be16_to_cpu(IB_LID_PERMISSIVE)) {
- ps->s_txreq->phdr.hdr.lrh[3] = IB_LID_PERMISSIVE;
- } else {
- lid = ppd->lid;
- if (lid) {
- lid |= rdma_ah_get_path_bits(ah_attr) &
- ((1 << ppd->lmc) - 1);
- ps->s_txreq->phdr.hdr.lrh[3] = cpu_to_be16(lid);
- } else {
- ps->s_txreq->phdr.hdr.lrh[3] = IB_LID_PERMISSIVE;
- }
- }
- if (wqe->wr.send_flags & IB_SEND_SOLICITED)
- bth0 |= IB_BTH_SOLICITED;
- bth0 |= extra_bytes << 20;
- if (qp->ibqp.qp_type == IB_QPT_GSI || qp->ibqp.qp_type == IB_QPT_SMI)
- bth0 |= hfi1_get_pkey(ibp, wqe->ud_wr.pkey_index);
- else
- bth0 |= hfi1_get_pkey(ibp, qp->s_pkey_index);
- ohdr->bth[0] = cpu_to_be32(bth0);
- ohdr->bth[1] = cpu_to_be32(wqe->ud_wr.remote_qpn);
- ohdr->bth[2] = cpu_to_be32(mask_psn(wqe->psn));
- /*
- * Qkeys with the high order bit set mean use the
- * qkey from the QP context instead of the WR (see 10.2.5).
- */
- ohdr->u.ud.deth[0] = cpu_to_be32((int)wqe->ud_wr.remote_qkey < 0 ?
- qp->qkey : wqe->ud_wr.remote_qkey);
- ohdr->u.ud.deth[1] = cpu_to_be32(qp->ibqp.qp_num);
/* disarm any ahg */
priv->s_ahg->ahgcount = 0;
priv->s_ahg->ahgidx = 0;
@@ -505,6 +629,64 @@ int hfi1_lookup_pkey_idx(struct hfi1_ibport *ibp, u16 pkey)
return -1;
}
+void return_cnp_16B(struct hfi1_ibport *ibp, struct rvt_qp *qp,
+ u32 remote_qpn, u32 pkey, u32 slid, u32 dlid,
+ u8 sc5, const struct ib_grh *old_grh)
+{
+ u64 pbc, pbc_flags = 0;
+ u32 bth0, plen, vl, hwords = 7;
+ u16 len;
+ u8 l4;
+ struct hfi1_16b_header hdr;
+ struct ib_other_headers *ohdr;
+ struct pio_buf *pbuf;
+ struct send_context *ctxt = qp_to_send_context(qp, sc5);
+ struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
+ u32 nwords;
+
+ /* Populate length */
+ nwords = ((hfi1_get_16b_padding(hwords << 2, 0) +
+ SIZE_OF_LT) >> 2) + SIZE_OF_CRC;
+ if (old_grh) {
+ struct ib_grh *grh = &hdr.u.l.grh;
+
+ grh->version_tclass_flow = old_grh->version_tclass_flow;
+ grh->paylen = cpu_to_be16((hwords - 4 + nwords) << 2);
+ grh->hop_limit = 0xff;
+ grh->sgid = old_grh->dgid;
+ grh->dgid = old_grh->sgid;
+ ohdr = &hdr.u.l.oth;
+ l4 = OPA_16B_L4_IB_GLOBAL;
+ hwords += sizeof(struct ib_grh) / sizeof(u32);
+ } else {
+ ohdr = &hdr.u.oth;
+ l4 = OPA_16B_L4_IB_LOCAL;
+ }
+
+ /* BIT 16 to 19 is TVER. Bit 20 to 22 is pad cnt */
+ bth0 = (IB_OPCODE_CNP << 24) | (1 << 16) |
+ (hfi1_get_16b_padding(hwords << 2, 0) << 20);
+ ohdr->bth[0] = cpu_to_be32(bth0);
+
+ ohdr->bth[1] = cpu_to_be32(remote_qpn);
+ ohdr->bth[2] = 0; /* PSN 0 */
+
+ /* Convert dwords to flits */
+ len = (hwords + nwords) >> 1;
+ hfi1_make_16b_hdr(&hdr, slid, dlid, len, pkey, 1, 0, l4, sc5);
+
+ plen = 2 /* PBC */ + hwords + nwords;
+ pbc_flags |= PBC_PACKET_BYPASS | PBC_INSERT_BYPASS_ICRC;
+ vl = sc_to_vlt(ppd->dd, sc5);
+ pbc = create_pbc(ppd, pbc_flags, qp->srate_mbps, vl, plen);
+ if (ctxt) {
+ pbuf = sc_buffer_alloc(ctxt, plen, NULL, NULL);
+ if (pbuf)
+ ppd->dd->pio_inline_send(ppd->dd, pbuf, pbc,
+ &hdr, hwords);
+ }
+}
+
void return_cnp(struct hfi1_ibport *ibp, struct rvt_qp *qp, u32 remote_qpn,
u32 pkey, u32 slid, u32 dlid, u8 sc5,
const struct ib_grh *old_grh)
@@ -543,13 +725,9 @@ void return_cnp(struct hfi1_ibport *ibp, struct rvt_qp *qp, u32 remote_qpn,
ohdr->bth[1] = cpu_to_be32(remote_qpn | (1 << IB_BECN_SHIFT));
ohdr->bth[2] = 0; /* PSN 0 */
- hdr.lrh[0] = cpu_to_be16(lrh0);
- hdr.lrh[1] = cpu_to_be16(dlid);
- hdr.lrh[2] = cpu_to_be16(hwords + SIZE_OF_CRC);
- hdr.lrh[3] = cpu_to_be16(slid);
-
+ hfi1_make_ib_hdr(&hdr, lrh0, hwords + SIZE_OF_CRC, dlid, slid);
plen = 2 /* PBC */ + hwords;
- pbc_flags |= (!!(sc5 & 0x10)) << PBC_DC_INFO_SHIFT;
+ pbc_flags |= (ib_is_sc5(sc5) << PBC_DC_INFO_SHIFT);
vl = sc_to_vlt(ppd->dd, sc5);
pbc = create_pbc(ppd, pbc_flags, qp->srate_mbps, vl, plen);
if (ctxt) {
@@ -668,37 +846,45 @@ static int opa_smp_check(struct hfi1_ibport *ibp, u16 pkey, u8 sc5,
void hfi1_ud_rcv(struct hfi1_packet *packet)
{
struct ib_other_headers *ohdr = packet->ohdr;
- int opcode;
u32 hdrsize = packet->hlen;
struct ib_wc wc;
u32 qkey;
u32 src_qp;
- u16 dlid, pkey;
+ u16 pkey;
int mgmt_pkey_idx = -1;
struct hfi1_ibport *ibp = rcd_to_iport(packet->rcd);
struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
struct ib_header *hdr = packet->hdr;
- u32 rcv_flags = packet->rcv_flags;
- void *data = packet->ebuf;
+ void *data = packet->payload;
u32 tlen = packet->tlen;
struct rvt_qp *qp = packet->qp;
- bool has_grh = rcv_flags & HFI1_HAS_GRH;
- u8 sc5 = hfi1_9B_get_sc5(hdr, packet->rhf);
- u32 bth1;
- u8 sl_from_sc, sl;
- u16 slid;
+ u8 sc5 = packet->sc;
+ u8 sl_from_sc;
+ u8 opcode = packet->opcode;
+ u8 sl = packet->sl;
+ u32 dlid = packet->dlid;
+ u32 slid = packet->slid;
u8 extra_bytes;
+ bool dlid_is_permissive;
+ bool slid_is_permissive;
- qkey = be32_to_cpu(ohdr->u.ud.deth[0]);
- src_qp = be32_to_cpu(ohdr->u.ud.deth[1]) & RVT_QPN_MASK;
- dlid = ib_get_dlid(hdr);
- bth1 = be32_to_cpu(ohdr->bth[1]);
- slid = ib_get_slid(hdr);
- pkey = ib_bth_get_pkey(ohdr);
- opcode = ib_bth_get_opcode(ohdr);
- sl = ib_get_sl(hdr);
- extra_bytes = ib_bth_get_pad(ohdr);
- extra_bytes += (SIZE_OF_CRC << 2);
+ extra_bytes = packet->pad + packet->extra_byte + (SIZE_OF_CRC << 2);
+ qkey = ib_get_qkey(ohdr);
+ src_qp = ib_get_sqpn(ohdr);
+
+ if (packet->etype == RHF_RCV_TYPE_BYPASS) {
+ u32 permissive_lid =
+ opa_get_lid(be32_to_cpu(OPA_LID_PERMISSIVE), 16B);
+
+ pkey = hfi1_16B_get_pkey(packet->hdr);
+ dlid_is_permissive = (dlid == permissive_lid);
+ slid_is_permissive = (slid == permissive_lid);
+ } else {
+ hdr = packet->hdr;
+ pkey = ib_bth_get_pkey(ohdr);
+ dlid_is_permissive = (dlid == be16_to_cpu(IB_LID_PERMISSIVE));
+ slid_is_permissive = (slid == be16_to_cpu(IB_LID_PERMISSIVE));
+ }
sl_from_sc = ibp->sc_to_sl[sc5];
process_ecn(qp, packet, (opcode != IB_OPCODE_CNP));
@@ -716,8 +902,7 @@ void hfi1_ud_rcv(struct hfi1_packet *packet)
* and the QKEY matches (see 9.6.1.4.1 and 9.6.1.5.1).
*/
if (qp->ibqp.qp_num) {
- if (unlikely(hdr->lrh[1] == IB_LID_PERMISSIVE ||
- hdr->lrh[3] == IB_LID_PERMISSIVE))
+ if (unlikely(dlid_is_permissive || slid_is_permissive))
goto drop;
if (qp->ibqp.qp_num > 1) {
if (unlikely(rcv_pkey_check(ppd, pkey, sc5, slid))) {
@@ -727,10 +912,10 @@ void hfi1_ud_rcv(struct hfi1_packet *packet)
* for invalid pkeys is optional according to
* IB spec (release 1.3, section 10.9.4)
*/
- hfi1_bad_pqkey(ibp, OPA_TRAP_BAD_P_KEY,
- pkey, sl,
- src_qp, qp->ibqp.qp_num,
- slid, dlid);
+ hfi1_bad_pkey(ibp,
+ pkey, sl,
+ src_qp, qp->ibqp.qp_num,
+ slid, dlid);
return;
}
} else {
@@ -739,12 +924,9 @@ void hfi1_ud_rcv(struct hfi1_packet *packet)
if (mgmt_pkey_idx < 0)
goto drop;
}
- if (unlikely(qkey != qp->qkey)) {
- hfi1_bad_pqkey(ibp, OPA_TRAP_BAD_Q_KEY, qkey, sl,
- src_qp, qp->ibqp.qp_num,
- slid, dlid);
+ if (unlikely(qkey != qp->qkey)) /* Silent drop */
return;
- }
+
/* Drop invalid MAD packets (see 13.5.3.1). */
if (unlikely(qp->ibqp.qp_num == 1 &&
(tlen > 2048 || (sc5 == 0xF))))
@@ -758,8 +940,7 @@ void hfi1_ud_rcv(struct hfi1_packet *packet)
if (tlen > 2048)
goto drop;
- if ((hdr->lrh[1] == IB_LID_PERMISSIVE ||
- hdr->lrh[3] == IB_LID_PERMISSIVE) &&
+ if ((dlid_is_permissive || slid_is_permissive) &&
smp->mgmt_class != IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)
goto drop;
@@ -811,8 +992,19 @@ void hfi1_ud_rcv(struct hfi1_packet *packet)
qp->r_flags |= RVT_R_REUSE_SGE;
goto drop;
}
- if (has_grh) {
- hfi1_copy_sge(&qp->r_sge, &hdr->u.l.grh,
+ if (packet->grh) {
+ hfi1_copy_sge(&qp->r_sge, packet->grh,
+ sizeof(struct ib_grh), true, false);
+ wc.wc_flags |= IB_WC_GRH;
+ } else if (packet->etype == RHF_RCV_TYPE_BYPASS) {
+ struct ib_grh grh;
+ /*
+ * Assuming we only created 16B on the send side
+ * if we want to use large LIDs, since GRH was stripped
+ * out when creating 16B, add back the GRH here.
+ */
+ hfi1_make_ext_grh(packet, &grh, slid, dlid);
+ hfi1_copy_sge(&qp->r_sge, &grh,
sizeof(struct ib_grh), true, false);
wc.wc_flags |= IB_WC_GRH;
} else {
@@ -845,14 +1037,15 @@ void hfi1_ud_rcv(struct hfi1_packet *packet)
} else {
wc.pkey_index = 0;
}
-
+ if (slid_is_permissive)
+ slid = be32_to_cpu(OPA_LID_PERMISSIVE);
wc.slid = slid;
wc.sl = sl_from_sc;
/*
* Save the LMC lower bits if the destination LID is a unicast LID.
*/
- wc.dlid_path_bits = dlid >= be16_to_cpu(IB_MULTICAST_LID_BASE) ? 0 :
+ wc.dlid_path_bits = hfi1_check_mcast(dlid) ? 0 :
dlid & ((1 << ppd_from_ibp(ibp)->lmc) - 1);
wc.port_num = qp->port_num;
/* Signal completion event if the solicited bit is set. */
diff --git a/drivers/infiniband/hw/hfi1/user_exp_rcv.c b/drivers/infiniband/hw/hfi1/user_exp_rcv.c
index a8f0aa4..6f6c14d 100644
--- a/drivers/infiniband/hw/hfi1/user_exp_rcv.c
+++ b/drivers/infiniband/hw/hfi1/user_exp_rcv.c
@@ -47,58 +47,28 @@
#include <asm/page.h>
#include <linux/string.h>
+#include "mmu_rb.h"
#include "user_exp_rcv.h"
#include "trace.h"
-#include "mmu_rb.h"
-
-struct tid_group {
- struct list_head list;
- u32 base;
- u8 size;
- u8 used;
- u8 map;
-};
-
-struct tid_rb_node {
- struct mmu_rb_node mmu;
- unsigned long phys;
- struct tid_group *grp;
- u32 rcventry;
- dma_addr_t dma_addr;
- bool freed;
- unsigned npages;
- struct page *pages[0];
-};
-
-struct tid_pageset {
- u16 idx;
- u16 count;
-};
-
-#define EXP_TID_SET_EMPTY(set) (set.count == 0 && list_empty(&set.list))
-
-#define num_user_pages(vaddr, len) \
- (1 + (((((unsigned long)(vaddr) + \
- (unsigned long)(len) - 1) & PAGE_MASK) - \
- ((unsigned long)vaddr & PAGE_MASK)) >> PAGE_SHIFT))
static void unlock_exp_tids(struct hfi1_ctxtdata *uctxt,
struct exp_tid_set *set,
struct hfi1_filedata *fd);
-static u32 find_phys_blocks(struct page **pages, unsigned npages,
- struct tid_pageset *list);
-static int set_rcvarray_entry(struct hfi1_filedata *fd, unsigned long vaddr,
+static u32 find_phys_blocks(struct tid_user_buf *tidbuf, unsigned int npages);
+static int set_rcvarray_entry(struct hfi1_filedata *fd,
+ struct tid_user_buf *tbuf,
u32 rcventry, struct tid_group *grp,
- struct page **pages, unsigned npages);
+ u16 pageidx, unsigned int npages);
static int tid_rb_insert(void *arg, struct mmu_rb_node *node);
static void cacheless_tid_rb_remove(struct hfi1_filedata *fdata,
struct tid_rb_node *tnode);
static void tid_rb_remove(void *arg, struct mmu_rb_node *node);
static int tid_rb_invalidate(void *arg, struct mmu_rb_node *mnode);
-static int program_rcvarray(struct hfi1_filedata *fd, unsigned long vaddr,
- struct tid_group *grp, struct tid_pageset *sets,
- unsigned start, u16 count, struct page **pages,
- u32 *tidlist, unsigned *tididx, unsigned *pmapped);
+static int program_rcvarray(struct hfi1_filedata *fd, struct tid_user_buf *,
+ struct tid_group *grp,
+ unsigned int start, u16 count,
+ u32 *tidlist, unsigned int *tididx,
+ unsigned int *pmapped);
static int unprogram_rcvarray(struct hfi1_filedata *fd, u32 tidinfo,
struct tid_group **grp);
static void clear_tid_node(struct hfi1_filedata *fd, struct tid_rb_node *node);
@@ -109,96 +79,14 @@ static struct mmu_rb_ops tid_rb_ops = {
.invalidate = tid_rb_invalidate
};
-static inline u32 rcventry2tidinfo(u32 rcventry)
-{
- u32 pair = rcventry & ~0x1;
-
- return EXP_TID_SET(IDX, pair >> 1) |
- EXP_TID_SET(CTRL, 1 << (rcventry - pair));
-}
-
-static inline void exp_tid_group_init(struct exp_tid_set *set)
-{
- INIT_LIST_HEAD(&set->list);
- set->count = 0;
-}
-
-static inline void tid_group_remove(struct tid_group *grp,
- struct exp_tid_set *set)
-{
- list_del_init(&grp->list);
- set->count--;
-}
-
-static inline void tid_group_add_tail(struct tid_group *grp,
- struct exp_tid_set *set)
-{
- list_add_tail(&grp->list, &set->list);
- set->count++;
-}
-
-static inline struct tid_group *tid_group_pop(struct exp_tid_set *set)
-{
- struct tid_group *grp =
- list_first_entry(&set->list, struct tid_group, list);
- list_del_init(&grp->list);
- set->count--;
- return grp;
-}
-
-static inline void tid_group_move(struct tid_group *group,
- struct exp_tid_set *s1,
- struct exp_tid_set *s2)
-{
- tid_group_remove(group, s1);
- tid_group_add_tail(group, s2);
-}
-
-int hfi1_user_exp_rcv_grp_init(struct hfi1_filedata *fd)
-{
- struct hfi1_ctxtdata *uctxt = fd->uctxt;
- struct hfi1_devdata *dd = fd->dd;
- u32 tidbase;
- u32 i;
- struct tid_group *grp, *gptr;
-
- exp_tid_group_init(&uctxt->tid_group_list);
- exp_tid_group_init(&uctxt->tid_used_list);
- exp_tid_group_init(&uctxt->tid_full_list);
-
- tidbase = uctxt->expected_base;
- for (i = 0; i < uctxt->expected_count /
- dd->rcv_entries.group_size; i++) {
- grp = kzalloc(sizeof(*grp), GFP_KERNEL);
- if (!grp)
- goto grp_failed;
-
- grp->size = dd->rcv_entries.group_size;
- grp->base = tidbase;
- tid_group_add_tail(grp, &uctxt->tid_group_list);
- tidbase += dd->rcv_entries.group_size;
- }
-
- return 0;
-
-grp_failed:
- list_for_each_entry_safe(grp, gptr, &uctxt->tid_group_list.list,
- list) {
- list_del_init(&grp->list);
- kfree(grp);
- }
-
- return -ENOMEM;
-}
-
/*
* Initialize context and file private data needed for Expected
* receive caching. This needs to be done after the context has
* been configured with the eager/expected RcvEntry counts.
*/
-int hfi1_user_exp_rcv_init(struct hfi1_filedata *fd)
+int hfi1_user_exp_rcv_init(struct hfi1_filedata *fd,
+ struct hfi1_ctxtdata *uctxt)
{
- struct hfi1_ctxtdata *uctxt = fd->uctxt;
struct hfi1_devdata *dd = uctxt->dd;
int ret = 0;
@@ -266,18 +154,6 @@ int hfi1_user_exp_rcv_init(struct hfi1_filedata *fd)
return ret;
}
-void hfi1_user_exp_rcv_grp_free(struct hfi1_ctxtdata *uctxt)
-{
- struct tid_group *grp, *gptr;
-
- list_for_each_entry_safe(grp, gptr, &uctxt->tid_group_list.list,
- list) {
- list_del_init(&grp->list);
- kfree(grp);
- }
- hfi1_clear_tids(uctxt);
-}
-
void hfi1_user_exp_rcv_free(struct hfi1_filedata *fd)
{
struct hfi1_ctxtdata *uctxt = fd->uctxt;
@@ -302,21 +178,90 @@ void hfi1_user_exp_rcv_free(struct hfi1_filedata *fd)
fd->entry_to_rb = NULL;
}
-/*
- * Write an "empty" RcvArray entry.
- * This function exists so the TID registaration code can use it
- * to write to unused/unneeded entries and still take advantage
- * of the WC performance improvements. The HFI will ignore this
- * write to the RcvArray entry.
+/**
+ * Release pinned receive buffer pages.
+ *
+ * @mapped - true if the pages have been DMA mapped. false otherwise.
+ * @idx - Index of the first page to unpin.
+ * @npages - No of pages to unpin.
+ *
+ * If the pages have been DMA mapped (indicated by mapped parameter), their
+ * info will be passed via a struct tid_rb_node. If they haven't been mapped,
+ * their info will be passed via a struct tid_user_buf.
+ */
+static void unpin_rcv_pages(struct hfi1_filedata *fd,
+ struct tid_user_buf *tidbuf,
+ struct tid_rb_node *node,
+ unsigned int idx,
+ unsigned int npages,
+ bool mapped)
+{
+ struct page **pages;
+ struct hfi1_devdata *dd = fd->uctxt->dd;
+
+ if (mapped) {
+ pci_unmap_single(dd->pcidev, node->dma_addr,
+ node->mmu.len, PCI_DMA_FROMDEVICE);
+ pages = &node->pages[idx];
+ } else {
+ pages = &tidbuf->pages[idx];
+ }
+ hfi1_release_user_pages(fd->mm, pages, npages, mapped);
+ fd->tid_n_pinned -= npages;
+}
+
+/**
+ * Pin receive buffer pages.
*/
-static inline void rcv_array_wc_fill(struct hfi1_devdata *dd, u32 index)
+static int pin_rcv_pages(struct hfi1_filedata *fd, struct tid_user_buf *tidbuf)
{
+ int pinned;
+ unsigned int npages;
+ unsigned long vaddr = tidbuf->vaddr;
+ struct page **pages = NULL;
+ struct hfi1_devdata *dd = fd->uctxt->dd;
+
+ /* Get the number of pages the user buffer spans */
+ npages = num_user_pages(vaddr, tidbuf->length);
+ if (!npages)
+ return -EINVAL;
+
+ if (npages > fd->uctxt->expected_count) {
+ dd_dev_err(dd, "Expected buffer too big\n");
+ return -EINVAL;
+ }
+
+ /* Verify that access is OK for the user buffer */
+ if (!access_ok(VERIFY_WRITE, (void __user *)vaddr,
+ npages * PAGE_SIZE)) {
+ dd_dev_err(dd, "Fail vaddr %p, %u pages, !access_ok\n",
+ (void *)vaddr, npages);
+ return -EFAULT;
+ }
+ /* Allocate the array of struct page pointers needed for pinning */
+ pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL);
+ if (!pages)
+ return -ENOMEM;
+
/*
- * Doing the WC fill writes only makes sense if the device is
- * present and the RcvArray has been mapped as WC memory.
+ * Pin all the pages of the user buffer. If we can't pin all the
+ * pages, accept the amount pinned so far and program only that.
+ * User space knows how to deal with partially programmed buffers.
*/
- if ((dd->flags & HFI1_PRESENT) && dd->rcvarray_wc)
- writeq(0, dd->rcvarray_wc + (index * 8));
+ if (!hfi1_can_pin_pages(dd, fd->mm, fd->tid_n_pinned, npages)) {
+ kfree(pages);
+ return -ENOMEM;
+ }
+
+ pinned = hfi1_acquire_user_pages(fd->mm, vaddr, npages, true, pages);
+ if (pinned <= 0) {
+ kfree(pages);
+ return pinned;
+ }
+ tidbuf->pages = pages;
+ tidbuf->npages = npages;
+ fd->tid_n_pinned += pinned;
+ return pinned;
}
/*
@@ -374,62 +319,33 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd,
int ret = 0, need_group = 0, pinned;
struct hfi1_ctxtdata *uctxt = fd->uctxt;
struct hfi1_devdata *dd = uctxt->dd;
- unsigned npages, ngroups, pageidx = 0, pageset_count, npagesets,
+ unsigned int ngroups, pageidx = 0, pageset_count,
tididx = 0, mapped, mapped_pages = 0;
- unsigned long vaddr = tinfo->vaddr;
- struct page **pages = NULL;
u32 *tidlist = NULL;
- struct tid_pageset *pagesets = NULL;
+ struct tid_user_buf *tidbuf;
- /* Get the number of pages the user buffer spans */
- npages = num_user_pages(vaddr, tinfo->length);
- if (!npages)
- return -EINVAL;
-
- if (npages > uctxt->expected_count) {
- dd_dev_err(dd, "Expected buffer too big\n");
- return -EINVAL;
- }
-
- /* Verify that access is OK for the user buffer */
- if (!access_ok(VERIFY_WRITE, (void __user *)vaddr,
- npages * PAGE_SIZE)) {
- dd_dev_err(dd, "Fail vaddr %p, %u pages, !access_ok\n",
- (void *)vaddr, npages);
- return -EFAULT;
- }
-
- pagesets = kcalloc(uctxt->expected_count, sizeof(*pagesets),
- GFP_KERNEL);
- if (!pagesets)
+ tidbuf = kzalloc(sizeof(*tidbuf), GFP_KERNEL);
+ if (!tidbuf)
return -ENOMEM;
- /* Allocate the array of struct page pointers needed for pinning */
- pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL);
- if (!pages) {
- ret = -ENOMEM;
- goto bail;
- }
-
- /*
- * Pin all the pages of the user buffer. If we can't pin all the
- * pages, accept the amount pinned so far and program only that.
- * User space knows how to deal with partially programmed buffers.
- */
- if (!hfi1_can_pin_pages(dd, fd->mm, fd->tid_n_pinned, npages)) {
- ret = -ENOMEM;
- goto bail;
+ tidbuf->vaddr = tinfo->vaddr;
+ tidbuf->length = tinfo->length;
+ tidbuf->psets = kcalloc(uctxt->expected_count, sizeof(*tidbuf->psets),
+ GFP_KERNEL);
+ if (!tidbuf->psets) {
+ kfree(tidbuf);
+ return -ENOMEM;
}
- pinned = hfi1_acquire_user_pages(fd->mm, vaddr, npages, true, pages);
+ pinned = pin_rcv_pages(fd, tidbuf);
if (pinned <= 0) {
- ret = pinned;
- goto bail;
+ kfree(tidbuf->psets);
+ kfree(tidbuf);
+ return pinned;
}
- fd->tid_n_pinned += npages;
/* Find sets of physically contiguous pages */
- npagesets = find_phys_blocks(pages, pinned, pagesets);
+ tidbuf->n_psets = find_phys_blocks(tidbuf, pinned);
/*
* We don't need to access this under a lock since tid_used is per
@@ -437,10 +353,10 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd,
* and hfi1_user_exp_rcv_setup() at the same time.
*/
spin_lock(&fd->tid_lock);
- if (fd->tid_used + npagesets > fd->tid_limit)
+ if (fd->tid_used + tidbuf->n_psets > fd->tid_limit)
pageset_count = fd->tid_limit - fd->tid_used;
else
- pageset_count = npagesets;
+ pageset_count = tidbuf->n_psets;
spin_unlock(&fd->tid_lock);
if (!pageset_count)
@@ -468,9 +384,9 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd,
struct tid_group *grp =
tid_group_pop(&uctxt->tid_group_list);
- ret = program_rcvarray(fd, vaddr, grp, pagesets,
+ ret = program_rcvarray(fd, tidbuf, grp,
pageidx, dd->rcv_entries.group_size,
- pages, tidlist, &tididx, &mapped);
+ tidlist, &tididx, &mapped);
/*
* If there was a failure to program the RcvArray
* entries for the entire group, reset the grp fields
@@ -514,8 +430,8 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd,
unsigned use = min_t(unsigned, pageset_count - pageidx,
grp->size - grp->used);
- ret = program_rcvarray(fd, vaddr, grp, pagesets,
- pageidx, use, pages, tidlist,
+ ret = program_rcvarray(fd, tidbuf, grp,
+ pageidx, use, tidlist,
&tididx, &mapped);
if (ret < 0) {
hfi1_cdbg(TID,
@@ -575,16 +491,14 @@ nomem:
* If not everything was mapped (due to insufficient RcvArray entries,
* for example), unpin all unmapped pages so we can pin them nex time.
*/
- if (mapped_pages != pinned) {
- hfi1_release_user_pages(fd->mm, &pages[mapped_pages],
- pinned - mapped_pages,
- false);
- fd->tid_n_pinned -= pinned - mapped_pages;
- }
+ if (mapped_pages != pinned)
+ unpin_rcv_pages(fd, tidbuf, NULL, mapped_pages,
+ (pinned - mapped_pages), false);
bail:
- kfree(pagesets);
- kfree(pages);
+ kfree(tidbuf->psets);
kfree(tidlist);
+ kfree(tidbuf->pages);
+ kfree(tidbuf);
return ret > 0 ? 0 : ret;
}
@@ -674,11 +588,12 @@ int hfi1_user_exp_rcv_invalid(struct hfi1_filedata *fd,
return ret;
}
-static u32 find_phys_blocks(struct page **pages, unsigned npages,
- struct tid_pageset *list)
+static u32 find_phys_blocks(struct tid_user_buf *tidbuf, unsigned int npages)
{
unsigned pagecount, pageidx, setcount = 0, i;
unsigned long pfn, this_pfn;
+ struct page **pages = tidbuf->pages;
+ struct tid_pageset *list = tidbuf->psets;
if (!npages)
return 0;
@@ -741,13 +656,13 @@ static u32 find_phys_blocks(struct page **pages, unsigned npages,
/**
* program_rcvarray() - program an RcvArray group with receive buffers
* @fd: filedata pointer
- * @vaddr: starting user virtual address
+ * @tbuf: pointer to struct tid_user_buf that has the user buffer starting
+ * virtual address, buffer length, page pointers, pagesets (array of
+ * struct tid_pageset holding information on physically contiguous
+ * chunks from the user buffer), and other fields.
* @grp: RcvArray group
- * @sets: array of struct tid_pageset holding information on physically
- * contiguous chunks from the user buffer
* @start: starting index into sets array
* @count: number of struct tid_pageset's to program
- * @pages: an array of struct page * for the user buffer
* @tidlist: the array of u32 elements when the information about the
* programmed RcvArray entries is to be encoded.
* @tididx: starting offset into tidlist
@@ -765,11 +680,11 @@ static u32 find_phys_blocks(struct page **pages, unsigned npages,
* -ENOMEM or -EFAULT on error from set_rcvarray_entry(), or
* number of RcvArray entries programmed.
*/
-static int program_rcvarray(struct hfi1_filedata *fd, unsigned long vaddr,
+static int program_rcvarray(struct hfi1_filedata *fd, struct tid_user_buf *tbuf,
struct tid_group *grp,
- struct tid_pageset *sets,
- unsigned start, u16 count, struct page **pages,
- u32 *tidlist, unsigned *tididx, unsigned *pmapped)
+ unsigned int start, u16 count,
+ u32 *tidlist, unsigned int *tididx,
+ unsigned int *pmapped)
{
struct hfi1_ctxtdata *uctxt = fd->uctxt;
struct hfi1_devdata *dd = uctxt->dd;
@@ -808,11 +723,11 @@ static int program_rcvarray(struct hfi1_filedata *fd, unsigned long vaddr,
}
rcventry = grp->base + useidx;
- npages = sets[setidx].count;
- pageidx = sets[setidx].idx;
+ npages = tbuf->psets[setidx].count;
+ pageidx = tbuf->psets[setidx].idx;
- ret = set_rcvarray_entry(fd, vaddr + (pageidx * PAGE_SIZE),
- rcventry, grp, pages + pageidx,
+ ret = set_rcvarray_entry(fd, tbuf,
+ rcventry, grp, pageidx,
npages);
if (ret)
return ret;
@@ -833,15 +748,17 @@ static int program_rcvarray(struct hfi1_filedata *fd, unsigned long vaddr,
return idx;
}
-static int set_rcvarray_entry(struct hfi1_filedata *fd, unsigned long vaddr,
+static int set_rcvarray_entry(struct hfi1_filedata *fd,
+ struct tid_user_buf *tbuf,
u32 rcventry, struct tid_group *grp,
- struct page **pages, unsigned npages)
+ u16 pageidx, unsigned int npages)
{
int ret;
struct hfi1_ctxtdata *uctxt = fd->uctxt;
struct tid_rb_node *node;
struct hfi1_devdata *dd = uctxt->dd;
dma_addr_t phys;
+ struct page **pages = tbuf->pages + pageidx;
/*
* Allocate the node first so we can handle a potential
@@ -862,7 +779,7 @@ static int set_rcvarray_entry(struct hfi1_filedata *fd, unsigned long vaddr,
return -EFAULT;
}
- node->mmu.addr = vaddr;
+ node->mmu.addr = tbuf->vaddr + (pageidx * PAGE_SIZE);
node->mmu.len = npages * PAGE_SIZE;
node->phys = page_to_phys(pages[0]);
node->npages = npages;
@@ -935,17 +852,13 @@ static void clear_tid_node(struct hfi1_filedata *fd, struct tid_rb_node *node)
node->npages, node->mmu.addr, node->phys,
node->dma_addr);
- hfi1_put_tid(dd, node->rcventry, PT_INVALID, 0, 0);
/*
* Make sure device has seen the write before we unpin the
* pages.
*/
- flush_wc();
+ hfi1_put_tid(dd, node->rcventry, PT_INVALID_FLUSH, 0, 0);
- pci_unmap_single(dd->pcidev, node->dma_addr, node->mmu.len,
- PCI_DMA_FROMDEVICE);
- hfi1_release_user_pages(fd->mm, node->pages, node->npages, true);
- fd->tid_n_pinned -= node->npages;
+ unpin_rcv_pages(fd, NULL, node, 0, node->npages, true);
node->grp->used--;
node->grp->map &= ~(1 << (node->rcventry - node->grp->base));
diff --git a/drivers/infiniband/hw/hfi1/user_exp_rcv.h b/drivers/infiniband/hw/hfi1/user_exp_rcv.h
index 5250c89..e383cc0 100644
--- a/drivers/infiniband/hw/hfi1/user_exp_rcv.h
+++ b/drivers/infiniband/hw/hfi1/user_exp_rcv.h
@@ -49,30 +49,44 @@
#include "hfi.h"
-#define EXP_TID_TIDLEN_MASK 0x7FFULL
-#define EXP_TID_TIDLEN_SHIFT 0
-#define EXP_TID_TIDCTRL_MASK 0x3ULL
-#define EXP_TID_TIDCTRL_SHIFT 20
-#define EXP_TID_TIDIDX_MASK 0x3FFULL
-#define EXP_TID_TIDIDX_SHIFT 22
-#define EXP_TID_GET(tid, field) \
- (((tid) >> EXP_TID_TID##field##_SHIFT) & EXP_TID_TID##field##_MASK)
+#include "exp_rcv.h"
-#define EXP_TID_SET(field, value) \
- (((value) & EXP_TID_TID##field##_MASK) << \
- EXP_TID_TID##field##_SHIFT)
-#define EXP_TID_CLEAR(tid, field) ({ \
- (tid) &= ~(EXP_TID_TID##field##_MASK << \
- EXP_TID_TID##field##_SHIFT); \
- })
-#define EXP_TID_RESET(tid, field, value) do { \
- EXP_TID_CLEAR(tid, field); \
- (tid) |= EXP_TID_SET(field, (value)); \
- } while (0)
+struct tid_pageset {
+ u16 idx;
+ u16 count;
+};
-void hfi1_user_exp_rcv_grp_free(struct hfi1_ctxtdata *uctxt);
-int hfi1_user_exp_rcv_grp_init(struct hfi1_filedata *fd);
-int hfi1_user_exp_rcv_init(struct hfi1_filedata *fd);
+struct tid_user_buf {
+ unsigned long vaddr;
+ unsigned long length;
+ unsigned int npages;
+ struct page **pages;
+ struct tid_pageset *psets;
+ unsigned int n_psets;
+};
+
+struct tid_rb_node {
+ struct mmu_rb_node mmu;
+ unsigned long phys;
+ struct tid_group *grp;
+ u32 rcventry;
+ dma_addr_t dma_addr;
+ bool freed;
+ unsigned int npages;
+ struct page *pages[0];
+};
+
+static inline int num_user_pages(unsigned long addr,
+ unsigned long len)
+{
+ const unsigned long spage = addr & PAGE_MASK;
+ const unsigned long epage = (addr + len - 1) & PAGE_MASK;
+
+ return 1 + ((epage - spage) >> PAGE_SHIFT);
+}
+
+int hfi1_user_exp_rcv_init(struct hfi1_filedata *fd,
+ struct hfi1_ctxtdata *uctxt);
void hfi1_user_exp_rcv_free(struct hfi1_filedata *fd);
int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd,
struct hfi1_tid_info *tinfo);
diff --git a/drivers/infiniband/hw/hfi1/user_sdma.c b/drivers/infiniband/hw/hfi1/user_sdma.c
index d55339f..c0c0e04 100644
--- a/drivers/infiniband/hw/hfi1/user_sdma.c
+++ b/drivers/infiniband/hw/hfi1/user_sdma.c
@@ -64,224 +64,20 @@
#include "hfi.h"
#include "sdma.h"
+#include "mmu_rb.h"
#include "user_sdma.h"
#include "verbs.h" /* for the headers */
#include "common.h" /* for struct hfi1_tid_info */
#include "trace.h"
-#include "mmu_rb.h"
static uint hfi1_sdma_comp_ring_size = 128;
module_param_named(sdma_comp_size, hfi1_sdma_comp_ring_size, uint, S_IRUGO);
MODULE_PARM_DESC(sdma_comp_size, "Size of User SDMA completion ring. Default: 128");
-/* The maximum number of Data io vectors per message/request */
-#define MAX_VECTORS_PER_REQ 8
-/*
- * Maximum number of packet to send from each message/request
- * before moving to the next one.
- */
-#define MAX_PKTS_PER_QUEUE 16
-
-#define num_pages(x) (1 + ((((x) - 1) & PAGE_MASK) >> PAGE_SHIFT))
-
-#define req_opcode(x) \
- (((x) >> HFI1_SDMA_REQ_OPCODE_SHIFT) & HFI1_SDMA_REQ_OPCODE_MASK)
-#define req_version(x) \
- (((x) >> HFI1_SDMA_REQ_VERSION_SHIFT) & HFI1_SDMA_REQ_OPCODE_MASK)
-#define req_iovcnt(x) \
- (((x) >> HFI1_SDMA_REQ_IOVCNT_SHIFT) & HFI1_SDMA_REQ_IOVCNT_MASK)
-
-/* Number of BTH.PSN bits used for sequence number in expected rcvs */
-#define BTH_SEQ_MASK 0x7ffull
-
-/*
- * Define fields in the KDETH header so we can update the header
- * template.
- */
-#define KDETH_OFFSET_SHIFT 0
-#define KDETH_OFFSET_MASK 0x7fff
-#define KDETH_OM_SHIFT 15
-#define KDETH_OM_MASK 0x1
-#define KDETH_TID_SHIFT 16
-#define KDETH_TID_MASK 0x3ff
-#define KDETH_TIDCTRL_SHIFT 26
-#define KDETH_TIDCTRL_MASK 0x3
-#define KDETH_INTR_SHIFT 28
-#define KDETH_INTR_MASK 0x1
-#define KDETH_SH_SHIFT 29
-#define KDETH_SH_MASK 0x1
-#define KDETH_HCRC_UPPER_SHIFT 16
-#define KDETH_HCRC_UPPER_MASK 0xff
-#define KDETH_HCRC_LOWER_SHIFT 24
-#define KDETH_HCRC_LOWER_MASK 0xff
-
-#define AHG_KDETH_INTR_SHIFT 12
-#define AHG_KDETH_SH_SHIFT 13
-
-#define PBC2LRH(x) ((((x) & 0xfff) << 2) - 4)
-#define LRH2PBC(x) ((((x) >> 2) + 1) & 0xfff)
-
-#define KDETH_GET(val, field) \
- (((le32_to_cpu((val))) >> KDETH_##field##_SHIFT) & KDETH_##field##_MASK)
-#define KDETH_SET(dw, field, val) do { \
- u32 dwval = le32_to_cpu(dw); \
- dwval &= ~(KDETH_##field##_MASK << KDETH_##field##_SHIFT); \
- dwval |= (((val) & KDETH_##field##_MASK) << \
- KDETH_##field##_SHIFT); \
- dw = cpu_to_le32(dwval); \
- } while (0)
-
-#define AHG_HEADER_SET(arr, idx, dw, bit, width, value) \
- do { \
- if ((idx) < ARRAY_SIZE((arr))) \
- (arr)[(idx++)] = sdma_build_ahg_descriptor( \
- (__force u16)(value), (dw), (bit), \
- (width)); \
- else \
- return -ERANGE; \
- } while (0)
-
-/* KDETH OM multipliers and switch over point */
-#define KDETH_OM_SMALL 4
-#define KDETH_OM_SMALL_SHIFT 2
-#define KDETH_OM_LARGE 64
-#define KDETH_OM_LARGE_SHIFT 6
-#define KDETH_OM_MAX_SIZE (1 << ((KDETH_OM_LARGE / KDETH_OM_SMALL) + 1))
-
-/* Tx request flag bits */
-#define TXREQ_FLAGS_REQ_ACK BIT(0) /* Set the ACK bit in the header */
-#define TXREQ_FLAGS_REQ_DISABLE_SH BIT(1) /* Disable header suppression */
-
-/* SDMA request flag bits */
-#define SDMA_REQ_FOR_THREAD 1
-#define SDMA_REQ_SEND_DONE 2
-#define SDMA_REQ_HAS_ERROR 3
-#define SDMA_REQ_DONE_ERROR 4
-
-#define SDMA_PKT_Q_INACTIVE BIT(0)
-#define SDMA_PKT_Q_ACTIVE BIT(1)
-#define SDMA_PKT_Q_DEFERRED BIT(2)
-
-/*
- * Maximum retry attempts to submit a TX request
- * before putting the process to sleep.
- */
-#define MAX_DEFER_RETRY_COUNT 1
-
static unsigned initial_pkt_count = 8;
-#define SDMA_IOWAIT_TIMEOUT 1000 /* in milliseconds */
-
-struct sdma_mmu_node;
-
-struct user_sdma_iovec {
- struct list_head list;
- struct iovec iov;
- /* number of pages in this vector */
- unsigned npages;
- /* array of pinned pages for this vector */
- struct page **pages;
- /*
- * offset into the virtual address space of the vector at
- * which we last left off.
- */
- u64 offset;
- struct sdma_mmu_node *node;
-};
-
-struct sdma_mmu_node {
- struct mmu_rb_node rb;
- struct hfi1_user_sdma_pkt_q *pq;
- atomic_t refcount;
- struct page **pages;
- unsigned npages;
-};
-
-/* evict operation argument */
-struct evict_data {
- u32 cleared; /* count evicted so far */
- u32 target; /* target count to evict */
-};
-
-struct user_sdma_request {
- struct sdma_req_info info;
- struct hfi1_user_sdma_pkt_q *pq;
- struct hfi1_user_sdma_comp_q *cq;
- /* This is the original header from user space */
- struct hfi1_pkt_header hdr;
- /*
- * Pointer to the SDMA engine for this request.
- * Since different request could be on different VLs,
- * each request will need it's own engine pointer.
- */
- struct sdma_engine *sde;
- s8 ahg_idx;
- u32 ahg[9];
- /*
- * KDETH.Offset (Eager) field
- * We need to remember the initial value so the headers
- * can be updated properly.
- */
- u32 koffset;
- /*
- * KDETH.OFFSET (TID) field
- * The offset can cover multiple packets, depending on the
- * size of the TID entry.
- */
- u32 tidoffset;
- /*
- * We copy the iovs for this request (based on
- * info.iovcnt). These are only the data vectors
- */
- unsigned data_iovs;
- /* total length of the data in the request */
- u32 data_len;
- /* progress index moving along the iovs array */
- unsigned iov_idx;
- struct user_sdma_iovec iovs[MAX_VECTORS_PER_REQ];
- /* number of elements copied to the tids array */
- u16 n_tids;
- /* TID array values copied from the tid_iov vector */
- u32 *tids;
- u16 tididx;
- u32 sent;
- u64 seqnum;
- u64 seqcomp;
- u64 seqsubmitted;
- struct list_head txps;
- unsigned long flags;
- /* status of the last txreq completed */
- int status;
-};
-
-/*
- * A single txreq could span up to 3 physical pages when the MTU
- * is sufficiently large (> 4K). Each of the IOV pointers also
- * needs it's own set of flags so the vector has been handled
- * independently of each other.
- */
-struct user_sdma_txreq {
- /* Packet header for the txreq */
- struct hfi1_pkt_header hdr;
- struct sdma_txreq txreq;
- struct list_head list;
- struct user_sdma_request *req;
- u16 flags;
- unsigned busycount;
- u64 seqnum;
-};
-
-#define SDMA_DBG(req, fmt, ...) \
- hfi1_cdbg(SDMA, "[%u:%u:%u:%u] " fmt, (req)->pq->dd->unit, \
- (req)->pq->ctxt, (req)->pq->subctxt, (req)->info.comp_idx, \
- ##__VA_ARGS__)
-#define SDMA_Q_DBG(pq, fmt, ...) \
- hfi1_cdbg(SDMA, "[%u:%u:%u] " fmt, (pq)->dd->unit, (pq)->ctxt, \
- (pq)->subctxt, ##__VA_ARGS__)
-
static int user_sdma_send_pkts(struct user_sdma_request *req,
unsigned maxpkts);
-static int num_user_pages(const struct iovec *iov);
static void user_sdma_txreq_cb(struct sdma_txreq *txreq, int status);
static inline void pq_update(struct hfi1_user_sdma_pkt_q *pq);
static void user_sdma_free_request(struct user_sdma_request *req, bool unpin);
@@ -307,7 +103,8 @@ static int defer_packet_queue(
struct sdma_engine *sde,
struct iowait *wait,
struct sdma_txreq *txreq,
- unsigned int seq);
+ uint seq,
+ bool pkts_sent);
static void activate_packet_queue(struct iowait *wait, int reason);
static bool sdma_rb_filter(struct mmu_rb_node *node, unsigned long addr,
unsigned long len);
@@ -329,7 +126,8 @@ static int defer_packet_queue(
struct sdma_engine *sde,
struct iowait *wait,
struct sdma_txreq *txreq,
- unsigned seq)
+ uint seq,
+ bool pkts_sent)
{
struct hfi1_user_sdma_pkt_q *pq =
container_of(wait, struct hfi1_user_sdma_pkt_q, busy);
@@ -349,7 +147,7 @@ static int defer_packet_queue(
xchg(&pq->state, SDMA_PKT_Q_DEFERRED);
write_seqlock(&dev->iowait_lock);
if (list_empty(&pq->busy.list))
- list_add_tail(&pq->busy.list, &sde->dmawait);
+ iowait_queue(pkts_sent, &pq->busy, &sde->dmawait);
write_sequnlock(&dev->iowait_lock);
return -EBUSY;
eagain:
@@ -364,13 +162,6 @@ static void activate_packet_queue(struct iowait *wait, int reason)
wake_up(&wait->wait_dma);
};
-static void sdma_kmem_cache_ctor(void *obj)
-{
- struct user_sdma_txreq *tx = obj;
-
- memset(tx, 0, sizeof(*tx));
-}
-
int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt,
struct hfi1_filedata *fd)
{
@@ -379,7 +170,6 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt,
struct hfi1_devdata *dd;
struct hfi1_user_sdma_comp_q *cq;
struct hfi1_user_sdma_pkt_q *pq;
- unsigned long flags;
if (!uctxt || !fd)
return -EBADF;
@@ -393,7 +183,6 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt,
if (!pq)
return -ENOMEM;
- INIT_LIST_HEAD(&pq->list);
pq->dd = dd;
pq->ctxt = uctxt->ctxt;
pq->subctxt = fd->subctxt;
@@ -426,7 +215,7 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt,
sizeof(struct user_sdma_txreq),
L1_CACHE_BYTES,
SLAB_HWCACHE_ALIGN,
- sdma_kmem_cache_ctor);
+ NULL);
if (!pq->txreq_cache) {
dd_dev_err(dd, "[%u] Failed to allocate TxReq cache\n",
uctxt->ctxt);
@@ -454,10 +243,6 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt,
fd->pq = pq;
fd->cq = cq;
- spin_lock_irqsave(&uctxt->sdma_qlock, flags);
- list_add(&pq->list, &uctxt->sdma_queues);
- spin_unlock_irqrestore(&uctxt->sdma_qlock, flags);
-
return 0;
pq_mmu_fail:
@@ -476,22 +261,17 @@ pq_reqs_nomem:
return ret;
}
-int hfi1_user_sdma_free_queues(struct hfi1_filedata *fd)
+int hfi1_user_sdma_free_queues(struct hfi1_filedata *fd,
+ struct hfi1_ctxtdata *uctxt)
{
- struct hfi1_ctxtdata *uctxt = fd->uctxt;
struct hfi1_user_sdma_pkt_q *pq;
- unsigned long flags;
- hfi1_cdbg(SDMA, "[%u:%u:%u] Freeing user SDMA queues", uctxt->dd->unit,
- uctxt->ctxt, fd->subctxt);
+ trace_hfi1_sdma_user_free_queues(uctxt->dd, uctxt->ctxt, fd->subctxt);
+
pq = fd->pq;
if (pq) {
if (pq->handler)
hfi1_mmu_rb_unregister(pq->handler);
- spin_lock_irqsave(&uctxt->sdma_qlock, flags);
- if (!list_empty(&pq->list))
- list_del_init(&pq->list);
- spin_unlock_irqrestore(&uctxt->sdma_qlock, flags);
iowait_sdma_drain(&pq->busy);
/* Wait until all requests have been freed. */
wait_event_interruptible(
@@ -546,6 +326,8 @@ int hfi1_user_sdma_process_request(struct hfi1_filedata *fd,
struct sdma_req_info info;
struct user_sdma_request *req;
u8 opcode, sc, vl;
+ u16 pkey;
+ u32 slid;
int req_queued = 0;
u16 dlid;
u32 selector;
@@ -567,7 +349,6 @@ int hfi1_user_sdma_process_request(struct hfi1_filedata *fd,
trace_hfi1_sdma_user_reqinfo(dd, uctxt->ctxt, fd->subctxt,
(u16 *)&info);
-
if (info.comp_idx >= hfi1_sdma_comp_ring_size) {
hfi1_cdbg(SDMA,
"[%u:%u:%u:%u] Invalid comp index",
@@ -604,15 +385,23 @@ int hfi1_user_sdma_process_request(struct hfi1_filedata *fd,
/*
* All safety checks have been done and this request has been claimed.
*/
- hfi1_cdbg(SDMA, "[%u:%u:%u] Using req/comp entry %u\n", dd->unit,
- uctxt->ctxt, fd->subctxt, info.comp_idx);
+ trace_hfi1_sdma_user_process_request(dd, uctxt->ctxt, fd->subctxt,
+ info.comp_idx);
req = pq->reqs + info.comp_idx;
- memset(req, 0, sizeof(*req));
req->data_iovs = req_iovcnt(info.ctrl) - 1; /* subtract header vector */
+ req->data_len = 0;
req->pq = pq;
req->cq = cq;
req->status = -1;
req->ahg_idx = -1;
+ req->iov_idx = 0;
+ req->sent = 0;
+ req->seqnum = 0;
+ req->seqcomp = 0;
+ req->seqsubmitted = 0;
+ req->tids = NULL;
+ req->done = 0;
+ req->has_error = 0;
INIT_LIST_HEAD(&req->txps);
memcpy(&req->info, &info, sizeof(info));
@@ -671,8 +460,9 @@ int hfi1_user_sdma_process_request(struct hfi1_filedata *fd,
}
/* Checking P_KEY for requests from user-space */
- if (egress_pkey_check(dd->pport, req->hdr.lrh, req->hdr.bth, sc,
- PKEY_CHECK_INVALID)) {
+ pkey = (u16)be32_to_cpu(req->hdr.bth[0]);
+ slid = be16_to_cpu(req->hdr.lrh[3]);
+ if (egress_pkey_check(dd->pport, slid, pkey, sc, PKEY_CHECK_INVALID)) {
ret = -EINVAL;
goto free_req;
}
@@ -696,24 +486,27 @@ int hfi1_user_sdma_process_request(struct hfi1_filedata *fd,
req->tidoffset = KDETH_GET(req->hdr.kdeth.ver_tid_offset, OFFSET) *
(KDETH_GET(req->hdr.kdeth.ver_tid_offset, OM) ?
KDETH_OM_LARGE : KDETH_OM_SMALL);
- SDMA_DBG(req, "Initial TID offset %u", req->tidoffset);
+ trace_hfi1_sdma_user_initial_tidoffset(dd, uctxt->ctxt, fd->subctxt,
+ info.comp_idx, req->tidoffset);
idx++;
/* Save all the IO vector structures */
for (i = 0; i < req->data_iovs; i++) {
+ req->iovs[i].offset = 0;
INIT_LIST_HEAD(&req->iovs[i].list);
memcpy(&req->iovs[i].iov,
iovec + idx++,
sizeof(req->iovs[i].iov));
ret = pin_vector_pages(req, &req->iovs[i]);
if (ret) {
+ req->data_iovs = i;
req->status = ret;
goto free_req;
}
req->data_len += req->iovs[i].iov.iov_len;
}
- SDMA_DBG(req, "total data length %u", req->data_len);
-
+ trace_hfi1_sdma_user_data_length(dd, uctxt->ctxt, fd->subctxt,
+ info.comp_idx, req->data_len);
if (pcount > req->info.npkts)
pcount = req->info.npkts;
/*
@@ -749,6 +542,7 @@ int hfi1_user_sdma_process_request(struct hfi1_filedata *fd,
}
req->tids = tmp;
req->n_tids = ntids;
+ req->tididx = 0;
idx++;
}
@@ -791,12 +585,12 @@ int hfi1_user_sdma_process_request(struct hfi1_filedata *fd,
* request have been submitted to the SDMA engine. However, it
* will not wait for send completions.
*/
- while (!test_bit(SDMA_REQ_SEND_DONE, &req->flags)) {
+ while (req->seqsubmitted != req->info.npkts) {
ret = user_sdma_send_pkts(req, pcount);
if (ret < 0) {
if (ret != -EBUSY) {
req->status = ret;
- set_bit(SDMA_REQ_DONE_ERROR, &req->flags);
+ WRITE_ONCE(req->has_error, 1);
if (ACCESS_ONCE(req->seqcomp) ==
req->seqsubmitted - 1)
goto free_req;
@@ -867,7 +661,11 @@ static inline u32 compute_data_length(struct user_sdma_request *req,
} else {
len = min(req->data_len - req->sent, (u32)req->info.fragsize);
}
- SDMA_DBG(req, "Data Length = %u", len);
+ trace_hfi1_sdma_user_compute_length(req->pq->dd,
+ req->pq->ctxt,
+ req->pq->subctxt,
+ req->info.comp_idx,
+ len);
return len;
}
@@ -884,6 +682,84 @@ static inline u32 get_lrh_len(struct hfi1_pkt_header hdr, u32 len)
return ((sizeof(hdr) - sizeof(hdr.pbc)) + 4 + len);
}
+static int user_sdma_txadd_ahg(struct user_sdma_request *req,
+ struct user_sdma_txreq *tx,
+ u32 datalen)
+{
+ int ret;
+ u16 pbclen = le16_to_cpu(req->hdr.pbc[0]);
+ u32 lrhlen = get_lrh_len(req->hdr, pad_len(datalen));
+ struct hfi1_user_sdma_pkt_q *pq = req->pq;
+
+ /*
+ * Copy the request header into the tx header
+ * because the HW needs a cacheline-aligned
+ * address.
+ * This copy can be optimized out if the hdr
+ * member of user_sdma_request were also
+ * cacheline aligned.
+ */
+ memcpy(&tx->hdr, &req->hdr, sizeof(tx->hdr));
+ if (PBC2LRH(pbclen) != lrhlen) {
+ pbclen = (pbclen & 0xf000) | LRH2PBC(lrhlen);
+ tx->hdr.pbc[0] = cpu_to_le16(pbclen);
+ }
+ ret = check_header_template(req, &tx->hdr, lrhlen, datalen);
+ if (ret)
+ return ret;
+ ret = sdma_txinit_ahg(&tx->txreq, SDMA_TXREQ_F_AHG_COPY,
+ sizeof(tx->hdr) + datalen, req->ahg_idx,
+ 0, NULL, 0, user_sdma_txreq_cb);
+ if (ret)
+ return ret;
+ ret = sdma_txadd_kvaddr(pq->dd, &tx->txreq, &tx->hdr, sizeof(tx->hdr));
+ if (ret)
+ sdma_txclean(pq->dd, &tx->txreq);
+ return ret;
+}
+
+static int user_sdma_txadd(struct user_sdma_request *req,
+ struct user_sdma_txreq *tx,
+ struct user_sdma_iovec *iovec, u32 datalen,
+ u32 *queued_ptr, u32 *data_sent_ptr,
+ u64 *iov_offset_ptr)
+{
+ int ret;
+ unsigned int pageidx, len;
+ unsigned long base, offset;
+ u64 iov_offset = *iov_offset_ptr;
+ u32 queued = *queued_ptr, data_sent = *data_sent_ptr;
+ struct hfi1_user_sdma_pkt_q *pq = req->pq;
+
+ base = (unsigned long)iovec->iov.iov_base;
+ offset = offset_in_page(base + iovec->offset + iov_offset);
+ pageidx = (((iovec->offset + iov_offset + base) - (base & PAGE_MASK)) >>
+ PAGE_SHIFT);
+ len = offset + req->info.fragsize > PAGE_SIZE ?
+ PAGE_SIZE - offset : req->info.fragsize;
+ len = min((datalen - queued), len);
+ ret = sdma_txadd_page(pq->dd, &tx->txreq, iovec->pages[pageidx],
+ offset, len);
+ if (ret) {
+ SDMA_DBG(req, "SDMA txreq add page failed %d\n", ret);
+ return ret;
+ }
+ iov_offset += len;
+ queued += len;
+ data_sent += len;
+ if (unlikely(queued < datalen && pageidx == iovec->npages &&
+ req->iov_idx < req->data_iovs - 1)) {
+ iovec->offset += iov_offset;
+ iovec = &req->iovs[++req->iov_idx];
+ iov_offset = 0;
+ }
+
+ *queued_ptr = queued;
+ *data_sent_ptr = data_sent;
+ *iov_offset_ptr = iov_offset;
+ return ret;
+}
+
static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts)
{
int ret = 0, count;
@@ -898,10 +774,8 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts)
pq = req->pq;
/* If tx completion has reported an error, we are done. */
- if (test_bit(SDMA_REQ_HAS_ERROR, &req->flags)) {
- set_bit(SDMA_REQ_DONE_ERROR, &req->flags);
+ if (READ_ONCE(req->has_error))
return -EFAULT;
- }
/*
* Check if we might have sent the entire request already
@@ -924,10 +798,8 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts)
* with errors. If so, we are not going to process any
* more packets from this request.
*/
- if (test_bit(SDMA_REQ_HAS_ERROR, &req->flags)) {
- set_bit(SDMA_REQ_DONE_ERROR, &req->flags);
+ if (READ_ONCE(req->has_error))
return -EFAULT;
- }
tx = kmem_cache_alloc(pq->txreq_cache, GFP_KERNEL);
if (!tx)
@@ -984,39 +856,9 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts)
if (req->ahg_idx >= 0) {
if (!req->seqnum) {
- u16 pbclen = le16_to_cpu(req->hdr.pbc[0]);
- u32 lrhlen = get_lrh_len(req->hdr,
- pad_len(datalen));
- /*
- * Copy the request header into the tx header
- * because the HW needs a cacheline-aligned
- * address.
- * This copy can be optimized out if the hdr
- * member of user_sdma_request were also
- * cacheline aligned.
- */
- memcpy(&tx->hdr, &req->hdr, sizeof(tx->hdr));
- if (PBC2LRH(pbclen) != lrhlen) {
- pbclen = (pbclen & 0xf000) |
- LRH2PBC(lrhlen);
- tx->hdr.pbc[0] = cpu_to_le16(pbclen);
- }
- ret = check_header_template(req, &tx->hdr,
- lrhlen, datalen);
+ ret = user_sdma_txadd_ahg(req, tx, datalen);
if (ret)
goto free_tx;
- ret = sdma_txinit_ahg(&tx->txreq,
- SDMA_TXREQ_F_AHG_COPY,
- sizeof(tx->hdr) + datalen,
- req->ahg_idx, 0, NULL, 0,
- user_sdma_txreq_cb);
- if (ret)
- goto free_tx;
- ret = sdma_txadd_kvaddr(pq->dd, &tx->txreq,
- &tx->hdr,
- sizeof(tx->hdr));
- if (ret)
- goto free_txreq;
} else {
int changes;
@@ -1024,11 +866,6 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts)
datalen);
if (changes < 0)
goto free_tx;
- sdma_txinit_ahg(&tx->txreq,
- SDMA_TXREQ_F_USE_AHG,
- datalen, req->ahg_idx, changes,
- req->ahg, sizeof(req->hdr),
- user_sdma_txreq_cb);
}
} else {
ret = sdma_txinit(&tx->txreq, 0, sizeof(req->hdr) +
@@ -1052,35 +889,10 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts)
*/
while (queued < datalen &&
(req->sent + data_sent) < req->data_len) {
- unsigned long base, offset;
- unsigned pageidx, len;
-
- base = (unsigned long)iovec->iov.iov_base;
- offset = offset_in_page(base + iovec->offset +
- iov_offset);
- pageidx = (((iovec->offset + iov_offset +
- base) - (base & PAGE_MASK)) >> PAGE_SHIFT);
- len = offset + req->info.fragsize > PAGE_SIZE ?
- PAGE_SIZE - offset : req->info.fragsize;
- len = min((datalen - queued), len);
- ret = sdma_txadd_page(pq->dd, &tx->txreq,
- iovec->pages[pageidx],
- offset, len);
- if (ret) {
- SDMA_DBG(req, "SDMA txreq add page failed %d\n",
- ret);
+ ret = user_sdma_txadd(req, tx, iovec, datalen,
+ &queued, &data_sent, &iov_offset);
+ if (ret)
goto free_txreq;
- }
- iov_offset += len;
- queued += len;
- data_sent += len;
- if (unlikely(queued < datalen &&
- pageidx == iovec->npages &&
- req->iov_idx < req->data_iovs - 1)) {
- iovec->offset += iov_offset;
- iovec = &req->iovs[++req->iov_idx];
- iov_offset = 0;
- }
}
/*
* The txreq was submitted successfully so we can update
@@ -1105,7 +917,7 @@ dosend:
ret = sdma_send_txlist(req->sde, &pq->busy, &req->txps, &count);
req->seqsubmitted += count;
if (req->seqsubmitted == req->info.npkts) {
- set_bit(SDMA_REQ_SEND_DONE, &req->flags);
+ WRITE_ONCE(req->done, 1);
/*
* The txreq has already been submitted to the HW queue
* so we can free the AHG entry now. Corruption will not
@@ -1124,19 +936,6 @@ free_tx:
return ret;
}
-/*
- * How many pages in this iovec element?
- */
-static inline int num_user_pages(const struct iovec *iov)
-{
- const unsigned long addr = (unsigned long)iov->iov_base;
- const unsigned long len = iov->iov_len;
- const unsigned long spage = addr & PAGE_MASK;
- const unsigned long epage = (addr + len - 1) & PAGE_MASK;
-
- return 1 + ((epage - spage) >> PAGE_SHIFT);
-}
-
static u32 sdma_cache_evict(struct hfi1_user_sdma_pkt_q *pq, u32 npages)
{
struct evict_data evict_data;
@@ -1147,22 +946,82 @@ static u32 sdma_cache_evict(struct hfi1_user_sdma_pkt_q *pq, u32 npages)
return evict_data.cleared;
}
+static int pin_sdma_pages(struct user_sdma_request *req,
+ struct user_sdma_iovec *iovec,
+ struct sdma_mmu_node *node,
+ int npages)
+{
+ int pinned, cleared;
+ struct page **pages;
+ struct hfi1_user_sdma_pkt_q *pq = req->pq;
+
+ pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL);
+ if (!pages) {
+ SDMA_DBG(req, "Failed page array alloc");
+ return -ENOMEM;
+ }
+ memcpy(pages, node->pages, node->npages * sizeof(*pages));
+
+ npages -= node->npages;
+retry:
+ if (!hfi1_can_pin_pages(pq->dd, pq->mm,
+ atomic_read(&pq->n_locked), npages)) {
+ cleared = sdma_cache_evict(pq, npages);
+ if (cleared >= npages)
+ goto retry;
+ }
+ pinned = hfi1_acquire_user_pages(pq->mm,
+ ((unsigned long)iovec->iov.iov_base +
+ (node->npages * PAGE_SIZE)), npages, 0,
+ pages + node->npages);
+ if (pinned < 0) {
+ kfree(pages);
+ return pinned;
+ }
+ if (pinned != npages) {
+ unpin_vector_pages(pq->mm, pages, node->npages, pinned);
+ return -EFAULT;
+ }
+ kfree(node->pages);
+ node->rb.len = iovec->iov.iov_len;
+ node->pages = pages;
+ atomic_add(pinned, &pq->n_locked);
+ return pinned;
+}
+
+static void unpin_sdma_pages(struct sdma_mmu_node *node)
+{
+ if (node->npages) {
+ unpin_vector_pages(node->pq->mm, node->pages, 0, node->npages);
+ atomic_sub(node->npages, &node->pq->n_locked);
+ }
+}
+
static int pin_vector_pages(struct user_sdma_request *req,
struct user_sdma_iovec *iovec)
{
- int ret = 0, pinned, npages, cleared;
- struct page **pages;
+ int ret = 0, pinned, npages;
struct hfi1_user_sdma_pkt_q *pq = req->pq;
struct sdma_mmu_node *node = NULL;
struct mmu_rb_node *rb_node;
-
- rb_node = hfi1_mmu_rb_extract(pq->handler,
- (unsigned long)iovec->iov.iov_base,
- iovec->iov.iov_len);
- if (rb_node)
+ struct iovec *iov;
+ bool extracted;
+
+ extracted =
+ hfi1_mmu_rb_remove_unless_exact(pq->handler,
+ (unsigned long)
+ iovec->iov.iov_base,
+ iovec->iov.iov_len, &rb_node);
+ if (rb_node) {
node = container_of(rb_node, struct sdma_mmu_node, rb);
- else
- rb_node = NULL;
+ if (!extracted) {
+ atomic_inc(&node->refcount);
+ iovec->pages = node->pages;
+ iovec->npages = node->npages;
+ iovec->node = node;
+ return 0;
+ }
+ }
if (!node) {
node = kzalloc(sizeof(*node), GFP_KERNEL);
@@ -1174,46 +1033,16 @@ static int pin_vector_pages(struct user_sdma_request *req,
atomic_set(&node->refcount, 0);
}
- npages = num_user_pages(&iovec->iov);
+ iov = &iovec->iov;
+ npages = num_user_pages((unsigned long)iov->iov_base, iov->iov_len);
if (node->npages < npages) {
- pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL);
- if (!pages) {
- SDMA_DBG(req, "Failed page array alloc");
- ret = -ENOMEM;
- goto bail;
- }
- memcpy(pages, node->pages, node->npages * sizeof(*pages));
-
- npages -= node->npages;
-
-retry:
- if (!hfi1_can_pin_pages(pq->dd, pq->mm,
- atomic_read(&pq->n_locked), npages)) {
- cleared = sdma_cache_evict(pq, npages);
- if (cleared >= npages)
- goto retry;
- }
- pinned = hfi1_acquire_user_pages(pq->mm,
- ((unsigned long)iovec->iov.iov_base +
- (node->npages * PAGE_SIZE)), npages, 0,
- pages + node->npages);
+ pinned = pin_sdma_pages(req, iovec, node, npages);
if (pinned < 0) {
- kfree(pages);
ret = pinned;
goto bail;
}
- if (pinned != npages) {
- unpin_vector_pages(pq->mm, pages, node->npages,
- pinned);
- ret = -EFAULT;
- goto bail;
- }
- kfree(node->pages);
- node->rb.len = iovec->iov.iov_len;
- node->pages = pages;
node->npages += pinned;
npages = node->npages;
- atomic_add(pinned, &pq->n_locked);
}
iovec->pages = node->pages;
iovec->npages = npages;
@@ -1221,14 +1050,12 @@ retry:
ret = hfi1_mmu_rb_insert(req->pq->handler, &node->rb);
if (ret) {
- atomic_sub(node->npages, &pq->n_locked);
iovec->node = NULL;
goto bail;
}
return 0;
bail:
- if (rb_node)
- unpin_vector_pages(pq->mm, node->pages, 0, node->npages);
+ unpin_sdma_pages(node);
kfree(node);
return ret;
}
@@ -1408,9 +1235,10 @@ static int set_txreq_header(struct user_sdma_request *req,
* Set the KDETH.OFFSET and KDETH.OM based on size of
* transfer.
*/
- SDMA_DBG(req, "TID offset %ubytes %uunits om%u",
- req->tidoffset, req->tidoffset >> omfactor,
- omfactor != KDETH_OM_SMALL_SHIFT);
+ trace_hfi1_sdma_user_tid_info(
+ pq->dd, pq->ctxt, pq->subctxt, req->info.comp_idx,
+ req->tidoffset, req->tidoffset >> omfactor,
+ omfactor != KDETH_OM_SMALL_SHIFT);
KDETH_SET(hdr->kdeth.ver_tid_offset, OFFSET,
req->tidoffset >> omfactor);
KDETH_SET(hdr->kdeth.ver_tid_offset, OM,
@@ -1423,21 +1251,22 @@ done:
}
static int set_txreq_header_ahg(struct user_sdma_request *req,
- struct user_sdma_txreq *tx, u32 len)
+ struct user_sdma_txreq *tx, u32 datalen)
{
+ u32 ahg[AHG_KDETH_ARRAY_SIZE];
int diff = 0;
u8 omfactor; /* KDETH.OM */
struct hfi1_user_sdma_pkt_q *pq = req->pq;
struct hfi1_pkt_header *hdr = &req->hdr;
u16 pbclen = le16_to_cpu(hdr->pbc[0]);
- u32 val32, tidval = 0, lrhlen = get_lrh_len(*hdr, pad_len(len));
+ u32 val32, tidval = 0, lrhlen = get_lrh_len(*hdr, pad_len(datalen));
if (PBC2LRH(pbclen) != lrhlen) {
/* PBC.PbcLengthDWs */
- AHG_HEADER_SET(req->ahg, diff, 0, 0, 12,
+ AHG_HEADER_SET(ahg, diff, 0, 0, 12,
cpu_to_le16(LRH2PBC(lrhlen)));
/* LRH.PktLen (we need the full 16 bits due to byte swap) */
- AHG_HEADER_SET(req->ahg, diff, 3, 0, 16,
+ AHG_HEADER_SET(ahg, diff, 3, 0, 16,
cpu_to_be16(lrhlen >> 2));
}
@@ -1449,13 +1278,12 @@ static int set_txreq_header_ahg(struct user_sdma_request *req,
(HFI1_CAP_IS_KSET(EXTENDED_PSN) ? 0x7fffffff : 0xffffff);
if (unlikely(tx->flags & TXREQ_FLAGS_REQ_ACK))
val32 |= 1UL << 31;
- AHG_HEADER_SET(req->ahg, diff, 6, 0, 16, cpu_to_be16(val32 >> 16));
- AHG_HEADER_SET(req->ahg, diff, 6, 16, 16, cpu_to_be16(val32 & 0xffff));
+ AHG_HEADER_SET(ahg, diff, 6, 0, 16, cpu_to_be16(val32 >> 16));
+ AHG_HEADER_SET(ahg, diff, 6, 16, 16, cpu_to_be16(val32 & 0xffff));
/* KDETH.Offset */
- AHG_HEADER_SET(req->ahg, diff, 15, 0, 16,
+ AHG_HEADER_SET(ahg, diff, 15, 0, 16,
cpu_to_le16(req->koffset & 0xffff));
- AHG_HEADER_SET(req->ahg, diff, 15, 16, 16,
- cpu_to_le16(req->koffset >> 16));
+ AHG_HEADER_SET(ahg, diff, 15, 16, 16, cpu_to_le16(req->koffset >> 16));
if (req_opcode(req->info.ctrl) == EXPECTED) {
__le16 val;
@@ -1473,9 +1301,8 @@ static int set_txreq_header_ahg(struct user_sdma_request *req,
* we have to check again.
*/
if (++req->tididx > req->n_tids - 1 ||
- !req->tids[req->tididx]) {
+ !req->tids[req->tididx])
return -EINVAL;
- }
tidval = req->tids[req->tididx];
}
omfactor = ((EXP_TID_GET(tidval, LEN) *
@@ -1483,7 +1310,7 @@ static int set_txreq_header_ahg(struct user_sdma_request *req,
KDETH_OM_MAX_SIZE) ? KDETH_OM_LARGE_SHIFT :
KDETH_OM_SMALL_SHIFT;
/* KDETH.OM and KDETH.OFFSET (TID) */
- AHG_HEADER_SET(req->ahg, diff, 7, 0, 16,
+ AHG_HEADER_SET(ahg, diff, 7, 0, 16,
((!!(omfactor - KDETH_OM_SMALL_SHIFT)) << 15 |
((req->tidoffset >> omfactor)
& 0x7fff)));
@@ -1503,12 +1330,20 @@ static int set_txreq_header_ahg(struct user_sdma_request *req,
AHG_KDETH_INTR_SHIFT));
}
- AHG_HEADER_SET(req->ahg, diff, 7, 16, 14, val);
+ AHG_HEADER_SET(ahg, diff, 7, 16, 14, val);
}
+ if (diff < 0)
+ return diff;
trace_hfi1_sdma_user_header_ahg(pq->dd, pq->ctxt, pq->subctxt,
req->info.comp_idx, req->sde->this_idx,
- req->ahg_idx, req->ahg, diff, tidval);
+ req->ahg_idx, ahg, diff, tidval);
+ sdma_txinit_ahg(&tx->txreq,
+ SDMA_TXREQ_F_USE_AHG,
+ datalen, req->ahg_idx, diff,
+ ahg, sizeof(req->hdr),
+ user_sdma_txreq_cb);
+
return diff;
}
@@ -1537,7 +1372,7 @@ static void user_sdma_txreq_cb(struct sdma_txreq *txreq, int status)
if (status != SDMA_TXREQ_S_OK) {
SDMA_DBG(req, "SDMA completion with error %d",
status);
- set_bit(SDMA_REQ_HAS_ERROR, &req->flags);
+ WRITE_ONCE(req->has_error, 1);
}
req->seqcomp = tx->seqnum;
@@ -1556,8 +1391,8 @@ static void user_sdma_txreq_cb(struct sdma_txreq *txreq, int status)
if (status != SDMA_TXREQ_S_OK)
req->status = status;
if (req->seqcomp == (ACCESS_ONCE(req->seqsubmitted) - 1) &&
- (test_bit(SDMA_REQ_SEND_DONE, &req->flags) ||
- test_bit(SDMA_REQ_DONE_ERROR, &req->flags))) {
+ (READ_ONCE(req->done) ||
+ READ_ONCE(req->has_error))) {
user_sdma_free_request(req, false);
pq_update(pq);
set_comp_state(pq, cq, idx, ERROR, req->status);
@@ -1611,8 +1446,6 @@ static inline void set_comp_state(struct hfi1_user_sdma_pkt_q *pq,
u16 idx, enum hfi1_sdma_comp_state state,
int ret)
{
- hfi1_cdbg(SDMA, "[%u:%u:%u:%u] Setting completion status %u %d",
- pq->dd->unit, pq->ctxt, pq->subctxt, idx, state, ret);
if (state == ERROR)
cq->comps[idx].errcode = -ret;
smp_wmb(); /* make sure errcode is visible first */
@@ -1667,10 +1500,7 @@ static void sdma_rb_remove(void *arg, struct mmu_rb_node *mnode)
struct sdma_mmu_node *node =
container_of(mnode, struct sdma_mmu_node, rb);
- atomic_sub(node->npages, &node->pq->n_locked);
-
- unpin_vector_pages(node->pq->mm, node->pages, 0, node->npages);
-
+ unpin_sdma_pages(node);
kfree(node);
}
diff --git a/drivers/infiniband/hw/hfi1/user_sdma.h b/drivers/infiniband/hw/hfi1/user_sdma.h
index e5b10ae..9b8bb56 100644
--- a/drivers/infiniband/hw/hfi1/user_sdma.h
+++ b/drivers/infiniband/hw/hfi1/user_sdma.h
@@ -53,11 +53,68 @@
#include "iowait.h"
#include "user_exp_rcv.h"
+/* The maximum number of Data io vectors per message/request */
+#define MAX_VECTORS_PER_REQ 8
+/*
+ * Maximum number of packet to send from each message/request
+ * before moving to the next one.
+ */
+#define MAX_PKTS_PER_QUEUE 16
+
+#define num_pages(x) (1 + ((((x) - 1) & PAGE_MASK) >> PAGE_SHIFT))
+
+#define req_opcode(x) \
+ (((x) >> HFI1_SDMA_REQ_OPCODE_SHIFT) & HFI1_SDMA_REQ_OPCODE_MASK)
+#define req_version(x) \
+ (((x) >> HFI1_SDMA_REQ_VERSION_SHIFT) & HFI1_SDMA_REQ_OPCODE_MASK)
+#define req_iovcnt(x) \
+ (((x) >> HFI1_SDMA_REQ_IOVCNT_SHIFT) & HFI1_SDMA_REQ_IOVCNT_MASK)
+
+/* Number of BTH.PSN bits used for sequence number in expected rcvs */
+#define BTH_SEQ_MASK 0x7ffull
+
+#define AHG_KDETH_INTR_SHIFT 12
+#define AHG_KDETH_SH_SHIFT 13
+#define AHG_KDETH_ARRAY_SIZE 9
+
+#define PBC2LRH(x) ((((x) & 0xfff) << 2) - 4)
+#define LRH2PBC(x) ((((x) >> 2) + 1) & 0xfff)
+
+#define AHG_HEADER_SET(arr, idx, dw, bit, width, value) \
+ do { \
+ if ((idx) < ARRAY_SIZE((arr))) \
+ (arr)[(idx++)] = sdma_build_ahg_descriptor( \
+ (__force u16)(value), (dw), (bit), \
+ (width)); \
+ else \
+ return -ERANGE; \
+ } while (0)
+
+/* Tx request flag bits */
+#define TXREQ_FLAGS_REQ_ACK BIT(0) /* Set the ACK bit in the header */
+#define TXREQ_FLAGS_REQ_DISABLE_SH BIT(1) /* Disable header suppression */
+
+#define SDMA_PKT_Q_INACTIVE BIT(0)
+#define SDMA_PKT_Q_ACTIVE BIT(1)
+#define SDMA_PKT_Q_DEFERRED BIT(2)
+
+/*
+ * Maximum retry attempts to submit a TX request
+ * before putting the process to sleep.
+ */
+#define MAX_DEFER_RETRY_COUNT 1
+
+#define SDMA_IOWAIT_TIMEOUT 1000 /* in milliseconds */
+
+#define SDMA_DBG(req, fmt, ...) \
+ hfi1_cdbg(SDMA, "[%u:%u:%u:%u] " fmt, (req)->pq->dd->unit, \
+ (req)->pq->ctxt, (req)->pq->subctxt, (req)->info.comp_idx, \
+ ##__VA_ARGS__)
+
extern uint extended_psn;
struct hfi1_user_sdma_pkt_q {
- struct list_head list;
- unsigned ctxt;
+ u16 ctxt;
u16 subctxt;
u16 n_max_reqs;
atomic_t n_reqs;
@@ -80,9 +137,115 @@ struct hfi1_user_sdma_comp_q {
struct hfi1_sdma_comp_entry *comps;
};
+struct sdma_mmu_node {
+ struct mmu_rb_node rb;
+ struct hfi1_user_sdma_pkt_q *pq;
+ atomic_t refcount;
+ struct page **pages;
+ unsigned int npages;
+};
+
+struct user_sdma_iovec {
+ struct list_head list;
+ struct iovec iov;
+ /* number of pages in this vector */
+ unsigned int npages;
+ /* array of pinned pages for this vector */
+ struct page **pages;
+ /*
+ * offset into the virtual address space of the vector at
+ * which we last left off.
+ */
+ u64 offset;
+ struct sdma_mmu_node *node;
+};
+
+/* evict operation argument */
+struct evict_data {
+ u32 cleared; /* count evicted so far */
+ u32 target; /* target count to evict */
+};
+
+struct user_sdma_request {
+ /* This is the original header from user space */
+ struct hfi1_pkt_header hdr;
+
+ /* Read mostly fields */
+ struct hfi1_user_sdma_pkt_q *pq ____cacheline_aligned_in_smp;
+ struct hfi1_user_sdma_comp_q *cq;
+ /*
+ * Pointer to the SDMA engine for this request.
+ * Since different request could be on different VLs,
+ * each request will need it's own engine pointer.
+ */
+ struct sdma_engine *sde;
+ struct sdma_req_info info;
+ /* TID array values copied from the tid_iov vector */
+ u32 *tids;
+ /* total length of the data in the request */
+ u32 data_len;
+ /* number of elements copied to the tids array */
+ u16 n_tids;
+ /*
+ * We copy the iovs for this request (based on
+ * info.iovcnt). These are only the data vectors
+ */
+ u8 data_iovs;
+ s8 ahg_idx;
+
+ /* Writeable fields shared with interrupt */
+ u64 seqcomp ____cacheline_aligned_in_smp;
+ u64 seqsubmitted;
+ /* status of the last txreq completed */
+ int status;
+
+ /* Send side fields */
+ struct list_head txps ____cacheline_aligned_in_smp;
+ u64 seqnum;
+ /*
+ * KDETH.OFFSET (TID) field
+ * The offset can cover multiple packets, depending on the
+ * size of the TID entry.
+ */
+ u32 tidoffset;
+ /*
+ * KDETH.Offset (Eager) field
+ * We need to remember the initial value so the headers
+ * can be updated properly.
+ */
+ u32 koffset;
+ u32 sent;
+ /* TID index copied from the tid_iov vector */
+ u16 tididx;
+ /* progress index moving along the iovs array */
+ u8 iov_idx;
+ u8 done;
+ u8 has_error;
+
+ struct user_sdma_iovec iovs[MAX_VECTORS_PER_REQ];
+} ____cacheline_aligned_in_smp;
+
+/*
+ * A single txreq could span up to 3 physical pages when the MTU
+ * is sufficiently large (> 4K). Each of the IOV pointers also
+ * needs it's own set of flags so the vector has been handled
+ * independently of each other.
+ */
+struct user_sdma_txreq {
+ /* Packet header for the txreq */
+ struct hfi1_pkt_header hdr;
+ struct sdma_txreq txreq;
+ struct list_head list;
+ struct user_sdma_request *req;
+ u16 flags;
+ unsigned int busycount;
+ u64 seqnum;
+};
+
int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt,
struct hfi1_filedata *fd);
-int hfi1_user_sdma_free_queues(struct hfi1_filedata *fd);
+int hfi1_user_sdma_free_queues(struct hfi1_filedata *fd,
+ struct hfi1_ctxtdata *uctxt);
int hfi1_user_sdma_process_request(struct hfi1_filedata *fd,
struct iovec *iovec, unsigned long dim,
unsigned long *count);
diff --git a/drivers/infiniband/hw/hfi1/verbs.c b/drivers/infiniband/hw/hfi1/verbs.c
index 2d19f9b..e232f3c 100644
--- a/drivers/infiniband/hw/hfi1/verbs.c
+++ b/drivers/infiniband/hw/hfi1/verbs.c
@@ -53,6 +53,7 @@
#include <linux/rculist.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
+#include <rdma/opa_addr.h>
#include "hfi.h"
#include "common.h"
@@ -508,13 +509,14 @@ again:
/*
* Make sure the QP is ready and able to accept the given opcode.
*/
-static inline opcode_handler qp_ok(int opcode, struct hfi1_packet *packet)
+static inline opcode_handler qp_ok(struct hfi1_packet *packet)
{
if (!(ib_rvt_state_ops[packet->qp->state] & RVT_PROCESS_RECV_OK))
return NULL;
- if (((opcode & RVT_OPCODE_QP_MASK) == packet->qp->allowed_ops) ||
- (opcode == IB_OPCODE_CNP))
- return opcode_handler_tbl[opcode];
+ if (((packet->opcode & RVT_OPCODE_QP_MASK) ==
+ packet->qp->allowed_ops) ||
+ (packet->opcode == IB_OPCODE_CNP))
+ return opcode_handler_tbl[packet->opcode];
return NULL;
}
@@ -548,69 +550,54 @@ static u64 hfi1_fault_tx(struct rvt_qp *qp, u8 opcode, u64 pbc)
return pbc;
}
-/**
- * hfi1_ib_rcv - process an incoming packet
- * @packet: data packet information
- *
- * This is called to process an incoming packet at interrupt level.
- *
- * Tlen is the length of the header + data + CRC in bytes.
- */
-void hfi1_ib_rcv(struct hfi1_packet *packet)
+static int hfi1_do_pkey_check(struct hfi1_packet *packet)
{
struct hfi1_ctxtdata *rcd = packet->rcd;
- struct ib_header *hdr = packet->hdr;
- u32 tlen = packet->tlen;
+ struct hfi1_pportdata *ppd = rcd->ppd;
+ struct hfi1_16b_header *hdr = packet->hdr;
+ u16 pkey;
+
+ /* Pkey check needed only for bypass packets */
+ if (packet->etype != RHF_RCV_TYPE_BYPASS)
+ return 0;
+
+ /* Perform pkey check */
+ pkey = hfi1_16B_get_pkey(hdr);
+ return ingress_pkey_check(ppd, pkey, packet->sc,
+ packet->qp->s_pkey_index,
+ packet->slid, true);
+}
+
+static inline void hfi1_handle_packet(struct hfi1_packet *packet,
+ bool is_mcast)
+{
+ u32 qp_num;
+ struct hfi1_ctxtdata *rcd = packet->rcd;
struct hfi1_pportdata *ppd = rcd->ppd;
struct hfi1_ibport *ibp = rcd_to_iport(rcd);
struct rvt_dev_info *rdi = &ppd->dd->verbs_dev.rdi;
opcode_handler packet_handler;
unsigned long flags;
- u32 qp_num;
- int lnh;
- u8 opcode;
- u16 lid;
-
- /* Check for GRH */
- lnh = ib_get_lnh(hdr);
- if (lnh == HFI1_LRH_BTH) {
- packet->ohdr = &hdr->u.oth;
- } else if (lnh == HFI1_LRH_GRH) {
- u32 vtf;
-
- packet->ohdr = &hdr->u.l.oth;
- if (hdr->u.l.grh.next_hdr != IB_GRH_NEXT_HDR)
- goto drop;
- vtf = be32_to_cpu(hdr->u.l.grh.version_tclass_flow);
- if ((vtf >> IB_GRH_VERSION_SHIFT) != IB_GRH_VERSION)
- goto drop;
- packet->rcv_flags |= HFI1_HAS_GRH;
- } else {
- goto drop;
- }
-
- trace_input_ibhdr(rcd->dd, hdr);
- opcode = ib_bth_get_opcode(packet->ohdr);
- inc_opstats(tlen, &rcd->opstats->stats[opcode]);
+ inc_opstats(packet->tlen, &rcd->opstats->stats[packet->opcode]);
- /* Get the destination QP number. */
- qp_num = be32_to_cpu(packet->ohdr->bth[1]) & RVT_QPN_MASK;
- lid = ib_get_dlid(hdr);
- if (unlikely((lid >= be16_to_cpu(IB_MULTICAST_LID_BASE)) &&
- (lid != be16_to_cpu(IB_LID_PERMISSIVE)))) {
+ if (unlikely(is_mcast)) {
struct rvt_mcast *mcast;
struct rvt_mcast_qp *p;
- if (lnh != HFI1_LRH_GRH)
+ if (!packet->grh)
goto drop;
- mcast = rvt_mcast_find(&ibp->rvp, &hdr->u.l.grh.dgid, lid);
+ mcast = rvt_mcast_find(&ibp->rvp,
+ &packet->grh->dgid,
+ opa_get_lid(packet->dlid, 9B));
if (!mcast)
goto drop;
list_for_each_entry_rcu(p, &mcast->qp_list, list) {
packet->qp = p->qp;
+ if (hfi1_do_pkey_check(packet))
+ goto drop;
spin_lock_irqsave(&packet->qp->r_lock, flags);
- packet_handler = qp_ok(opcode, packet);
+ packet_handler = qp_ok(packet);
if (likely(packet_handler))
packet_handler(packet);
else
@@ -624,19 +611,22 @@ void hfi1_ib_rcv(struct hfi1_packet *packet)
if (atomic_dec_return(&mcast->refcount) <= 1)
wake_up(&mcast->wait);
} else {
+ /* Get the destination QP number. */
+ qp_num = ib_bth_get_qpn(packet->ohdr);
rcu_read_lock();
packet->qp = rvt_lookup_qpn(rdi, &ibp->rvp, qp_num);
- if (!packet->qp) {
- rcu_read_unlock();
- goto drop;
- }
- if (unlikely(hfi1_dbg_fault_opcode(packet->qp, opcode,
- true))) {
- rcu_read_unlock();
- goto drop;
- }
+ if (!packet->qp)
+ goto unlock_drop;
+
+ if (hfi1_do_pkey_check(packet))
+ goto unlock_drop;
+
+ if (unlikely(hfi1_dbg_fault_opcode(packet->qp, packet->opcode,
+ true)))
+ goto unlock_drop;
+
spin_lock_irqsave(&packet->qp->r_lock, flags);
- packet_handler = qp_ok(opcode, packet);
+ packet_handler = qp_ok(packet);
if (likely(packet_handler))
packet_handler(packet);
else
@@ -645,11 +635,34 @@ void hfi1_ib_rcv(struct hfi1_packet *packet)
rcu_read_unlock();
}
return;
-
+unlock_drop:
+ rcu_read_unlock();
drop:
ibp->rvp.n_pkt_drops++;
}
+/**
+ * hfi1_ib_rcv - process an incoming packet
+ * @packet: data packet information
+ *
+ * This is called to process an incoming packet at interrupt level.
+ */
+void hfi1_ib_rcv(struct hfi1_packet *packet)
+{
+ struct hfi1_ctxtdata *rcd = packet->rcd;
+
+ trace_input_ibhdr(rcd->dd, packet, !!(rhf_dc_info(packet->rhf)));
+ hfi1_handle_packet(packet, hfi1_check_mcast(packet->dlid));
+}
+
+void hfi1_16B_rcv(struct hfi1_packet *packet)
+{
+ struct hfi1_ctxtdata *rcd = packet->rcd;
+
+ trace_input_ibhdr(rcd->dd, packet, false);
+ hfi1_handle_packet(packet, hfi1_check_mcast(packet->dlid));
+}
+
/*
* This is called from a timer to check for QPs
* which need kernel memory in order to send a packet.
@@ -696,7 +709,7 @@ static void verbs_sdma_complete(
if (tx->wqe) {
hfi1_send_complete(qp, tx->wqe, IB_WC_SUCCESS);
} else if (qp->ibqp.qp_type == IB_QPT_RC) {
- struct ib_header *hdr;
+ struct hfi1_opa_header *hdr;
hdr = &tx->phdr.hdr;
hfi1_rc_send_complete(qp, hdr);
@@ -799,12 +812,27 @@ static int build_verbs_tx_desc(
int ret = 0;
struct hfi1_sdma_header *phdr = &tx->phdr;
u16 hdrbytes = tx->hdr_dwords << 2;
+ u32 *hdr;
+ u8 extra_bytes = 0;
+ static char trail_buf[12]; /* CRC = 4, LT = 1, Pad = 0 to 7 bytes */
+ if (tx->phdr.hdr.hdr_type) {
+ /*
+ * hdrbytes accounts for PBC. Need to subtract 8 bytes
+ * before calculating padding.
+ */
+ extra_bytes = hfi1_get_16b_padding(hdrbytes - 8, length) +
+ (SIZE_OF_CRC << 2) + SIZE_OF_LT;
+ hdr = (u32 *)&phdr->hdr.opah;
+ } else {
+ hdr = (u32 *)&phdr->hdr.ibh;
+ }
if (!ahg_info->ahgcount) {
ret = sdma_txinit_ahg(
&tx->txreq,
ahg_info->tx_flags,
- hdrbytes + length,
+ hdrbytes + length +
+ extra_bytes,
ahg_info->ahgidx,
0,
NULL,
@@ -834,8 +862,17 @@ static int build_verbs_tx_desc(
goto bail_txadd;
}
/* add the ulp payload - if any. tx->ss can be NULL for acks */
- if (tx->ss)
+ if (tx->ss) {
ret = build_verbs_ulp_payload(sde, length, tx);
+ if (ret)
+ goto bail_txadd;
+ }
+
+ /* add icrc, lt byte, and padding to flit */
+ if (extra_bytes != 0)
+ ret = sdma_txadd_kvaddr(sde->dd, &tx->txreq,
+ trail_buf, extra_bytes);
+
bail_txadd:
return ret;
}
@@ -847,26 +884,42 @@ int hfi1_verbs_send_dma(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
struct hfi1_ahg_info *ahg_info = priv->s_ahg;
u32 hdrwords = qp->s_hdrwords;
u32 len = ps->s_txreq->s_cur_size;
- u32 plen = hdrwords + ((len + 3) >> 2) + 2; /* includes pbc */
+ u32 plen;
struct hfi1_ibdev *dev = ps->dev;
struct hfi1_pportdata *ppd = ps->ppd;
struct verbs_txreq *tx;
u8 sc5 = priv->s_sc;
-
int ret;
+ u32 dwords;
+ bool bypass = false;
+
+ if (ps->s_txreq->phdr.hdr.hdr_type) {
+ u8 extra_bytes = hfi1_get_16b_padding((hdrwords << 2), len);
+
+ dwords = (len + extra_bytes + (SIZE_OF_CRC << 2) +
+ SIZE_OF_LT) >> 2;
+ bypass = true;
+ } else {
+ dwords = (len + 3) >> 2;
+ }
+ plen = hdrwords + dwords + 2;
tx = ps->s_txreq;
if (!sdma_txreq_built(&tx->txreq)) {
if (likely(pbc == 0)) {
u32 vl = sc_to_vlt(dd_from_ibdev(qp->ibqp.device), sc5);
- u8 opcode = get_opcode(&tx->phdr.hdr);
/* No vl15 here */
- /* set PBC_DC_INFO bit (aka SC[4]) in pbc_flags */
- pbc |= (!!(sc5 & 0x10)) << PBC_DC_INFO_SHIFT;
+ /* set PBC_DC_INFO bit (aka SC[4]) in pbc */
+ if (ps->s_txreq->phdr.hdr.hdr_type)
+ pbc |= PBC_PACKET_BYPASS |
+ PBC_INSERT_BYPASS_ICRC;
+ else
+ pbc |= (ib_is_sc5(sc5) << PBC_DC_INFO_SHIFT);
- if (unlikely(hfi1_dbg_fault_opcode(qp, opcode, false)))
- pbc = hfi1_fault_tx(qp, opcode, pbc);
+ if (unlikely(hfi1_dbg_fault_opcode(qp, ps->opcode,
+ false)))
+ pbc = hfi1_fault_tx(qp, ps->opcode, pbc);
pbc = create_pbc(ppd,
pbc,
qp->srate_mbps,
@@ -878,14 +931,15 @@ int hfi1_verbs_send_dma(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
if (unlikely(ret))
goto bail_build;
}
- ret = sdma_send_txreq(tx->sde, &priv->s_iowait, &tx->txreq);
+ ret = sdma_send_txreq(tx->sde, &priv->s_iowait, &tx->txreq,
+ ps->pkts_sent);
if (unlikely(ret < 0)) {
if (ret == -ECOMM)
goto bail_ecomm;
return ret;
}
trace_sdma_output_ibhdr(dd_from_ibdev(qp->ibqp.device),
- &ps->s_txreq->phdr.hdr);
+ &ps->s_txreq->phdr.hdr, ib_is_sc5(sc5));
return ret;
bail_ecomm:
@@ -935,7 +989,8 @@ static int pio_wait(struct rvt_qp *qp,
dev->n_piodrain += !!(flag & RVT_S_WAIT_PIO_DRAIN);
qp->s_flags |= flag;
was_empty = list_empty(&sc->piowait);
- list_add_tail(&priv->s_iowait.list, &sc->piowait);
+ iowait_queue(ps->pkts_sent, &priv->s_iowait,
+ &sc->piowait);
priv->s_iowait.lock = &dev->iowait_lock;
trace_hfi1_qpsleep(qp, RVT_S_WAIT_PIO);
rvt_get_qp(qp);
@@ -967,10 +1022,10 @@ int hfi1_verbs_send_pio(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
u32 hdrwords = qp->s_hdrwords;
struct rvt_sge_state *ss = ps->s_txreq->ss;
u32 len = ps->s_txreq->s_cur_size;
- u32 dwords = (len + 3) >> 2;
- u32 plen = hdrwords + dwords + 2; /* includes pbc */
+ u32 dwords;
+ u32 plen;
struct hfi1_pportdata *ppd = ps->ppd;
- u32 *hdr = (u32 *)&ps->s_txreq->phdr.hdr;
+ u32 *hdr;
u8 sc5;
unsigned long flags = 0;
struct send_context *sc;
@@ -978,6 +1033,23 @@ int hfi1_verbs_send_pio(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
int wc_status = IB_WC_SUCCESS;
int ret = 0;
pio_release_cb cb = NULL;
+ u32 lrh0_16b;
+ bool bypass = false;
+ u8 extra_bytes = 0;
+
+ if (ps->s_txreq->phdr.hdr.hdr_type) {
+ u8 pad_size = hfi1_get_16b_padding((hdrwords << 2), len);
+
+ extra_bytes = pad_size + (SIZE_OF_CRC << 2) + SIZE_OF_LT;
+ dwords = (len + extra_bytes) >> 2;
+ hdr = (u32 *)&ps->s_txreq->phdr.hdr.opah;
+ lrh0_16b = ps->s_txreq->phdr.hdr.opah.lrh[0];
+ bypass = true;
+ } else {
+ dwords = (len + 3) >> 2;
+ hdr = (u32 *)&ps->s_txreq->phdr.hdr.ibh;
+ }
+ plen = hdrwords + dwords + 2;
/* only RC/UC use complete */
switch (qp->ibqp.qp_type) {
@@ -995,13 +1067,14 @@ int hfi1_verbs_send_pio(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
if (likely(pbc == 0)) {
u8 vl = sc_to_vlt(dd_from_ibdev(qp->ibqp.device), sc5);
- struct verbs_txreq *tx = ps->s_txreq;
- u8 opcode = get_opcode(&tx->phdr.hdr);
- /* set PBC_DC_INFO bit (aka SC[4]) in pbc_flags */
- pbc |= (!!(sc5 & 0x10)) << PBC_DC_INFO_SHIFT;
- if (unlikely(hfi1_dbg_fault_opcode(qp, opcode, false)))
- pbc = hfi1_fault_tx(qp, opcode, pbc);
+ /* set PBC_DC_INFO bit (aka SC[4]) in pbc */
+ if (ps->s_txreq->phdr.hdr.hdr_type)
+ pbc |= PBC_PACKET_BYPASS | PBC_INSERT_BYPASS_ICRC;
+ else
+ pbc |= (ib_is_sc5(sc5) << PBC_DC_INFO_SHIFT);
+ if (unlikely(hfi1_dbg_fault_opcode(qp, ps->opcode, false)))
+ pbc = hfi1_fault_tx(qp, ps->opcode, pbc);
pbc = create_pbc(ppd, pbc, qp->srate_mbps, vl, plen);
}
if (cb)
@@ -1038,11 +1111,12 @@ int hfi1_verbs_send_pio(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
}
}
- if (len == 0) {
+ if (dwords == 0) {
pio_copy(ppd->dd, pbuf, pbc, hdr, hdrwords);
} else {
+ seg_pio_copy_start(pbuf, pbc,
+ hdr, hdrwords * 4);
if (ss) {
- seg_pio_copy_start(pbuf, pbc, hdr, hdrwords * 4);
while (len) {
void *addr = ss->sge.vaddr;
u32 slen = ss->sge.length;
@@ -1053,12 +1127,24 @@ int hfi1_verbs_send_pio(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
seg_pio_copy_mid(pbuf, addr, slen);
len -= slen;
}
- seg_pio_copy_end(pbuf);
}
+ /*
+ * Bypass packet will need to copy additional
+ * bytes to accommodate for CRC and LT bytes
+ */
+ if (extra_bytes) {
+ u8 *empty_buf;
+
+ empty_buf = kcalloc(extra_bytes, sizeof(u8),
+ GFP_KERNEL);
+ seg_pio_copy_mid(pbuf, empty_buf, extra_bytes);
+ kfree(empty_buf);
+ }
+ seg_pio_copy_end(pbuf);
}
trace_pio_output_ibhdr(dd_from_ibdev(qp->ibqp.device),
- &ps->s_txreq->phdr.hdr);
+ &ps->s_txreq->phdr.hdr, ib_is_sc5(sc5));
pio_bail:
if (qp->s_wqe) {
@@ -1104,10 +1190,10 @@ static inline int egress_pkey_matches_entry(u16 pkey, u16 ent)
/**
* egress_pkey_check - check P_KEY of a packet
- * @ppd: Physical IB port data
- * @lrh: Local route header
- * @bth: Base transport header
- * @sc5: SC for packet
+ * @ppd: Physical IB port data
+ * @slid: SLID for packet
+ * @bkey: PKEY for header
+ * @sc5: SC for packet
* @s_pkey_index: It will be used for look up optimization for kernel contexts
* only. If it is negative value, then it means user contexts is calling this
* function.
@@ -1116,19 +1202,16 @@ static inline int egress_pkey_matches_entry(u16 pkey, u16 ent)
*
* Return: 0 on success, otherwise, 1
*/
-int egress_pkey_check(struct hfi1_pportdata *ppd, __be16 *lrh, __be32 *bth,
+int egress_pkey_check(struct hfi1_pportdata *ppd, u32 slid, u16 pkey,
u8 sc5, int8_t s_pkey_index)
{
struct hfi1_devdata *dd;
int i;
- u16 pkey;
int is_user_ctxt_mechanism = (s_pkey_index < 0);
if (!(ppd->part_enforce & HFI1_PART_ENFORCE_OUT))
return 0;
- pkey = (u16)be32_to_cpu(bth[0]);
-
/* If SC15, pkey[0:14] must be 0x7fff */
if ((sc5 == 0xf) && ((pkey & PKEY_LOW_15_MASK) != PKEY_LOW_15_MASK))
goto bad;
@@ -1161,8 +1244,6 @@ bad:
dd = ppd->dd;
if (!(dd->err_info_xmit_constraint.status &
OPA_EI_STATUS_SMASK)) {
- u16 slid = be16_to_cpu(lrh[3]);
-
dd->err_info_xmit_constraint.status |=
OPA_EI_STATUS_SMASK;
dd->err_info_xmit_constraint.slid = slid;
@@ -1179,11 +1260,11 @@ bad:
* and size
*/
static inline send_routine get_send_routine(struct rvt_qp *qp,
- struct verbs_txreq *tx)
+ struct hfi1_pkt_state *ps)
{
struct hfi1_devdata *dd = dd_from_ibdev(qp->ibqp.device);
struct hfi1_qp_priv *priv = qp->priv;
- struct ib_header *h = &tx->phdr.hdr;
+ struct verbs_txreq *tx = ps->s_txreq;
if (unlikely(!(dd->flags & HFI1_HAS_SEND_DMA)))
return dd->process_pio_send;
@@ -1195,11 +1276,9 @@ static inline send_routine get_send_routine(struct rvt_qp *qp,
break;
case IB_QPT_UC:
case IB_QPT_RC: {
- u8 op = get_opcode(h);
-
if (piothreshold &&
tx->s_cur_size <= min(piothreshold, qp->pmtu) &&
- (BIT(op & OPMASK) & pio_opmask[op >> 5]) &&
+ (BIT(ps->opcode & OPMASK) & pio_opmask[ps->opcode >> 5]) &&
iowait_sdma_pending(&priv->s_iowait) == 0 &&
!sdma_txreq_built(&tx->txreq))
return dd->process_pio_send;
@@ -1224,25 +1303,38 @@ int hfi1_verbs_send(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
struct hfi1_devdata *dd = dd_from_ibdev(qp->ibqp.device);
struct hfi1_qp_priv *priv = qp->priv;
struct ib_other_headers *ohdr;
- struct ib_header *hdr;
send_routine sr;
int ret;
- u8 lnh;
+ u16 pkey;
+ u32 slid;
- hdr = &ps->s_txreq->phdr.hdr;
/* locate the pkey within the headers */
- lnh = ib_get_lnh(hdr);
- if (lnh == HFI1_LRH_GRH)
- ohdr = &hdr->u.l.oth;
- else
- ohdr = &hdr->u.oth;
-
- sr = get_send_routine(qp, ps->s_txreq);
- ret = egress_pkey_check(dd->pport,
- hdr->lrh,
- ohdr->bth,
- priv->s_sc,
- qp->s_pkey_index);
+ if (ps->s_txreq->phdr.hdr.hdr_type) {
+ struct hfi1_16b_header *hdr = &ps->s_txreq->phdr.hdr.opah;
+ u8 l4 = hfi1_16B_get_l4(hdr);
+
+ if (l4 == OPA_16B_L4_IB_GLOBAL)
+ ohdr = &hdr->u.l.oth;
+ else
+ ohdr = &hdr->u.oth;
+ slid = hfi1_16B_get_slid(hdr);
+ pkey = hfi1_16B_get_pkey(hdr);
+ } else {
+ struct ib_header *hdr = &ps->s_txreq->phdr.hdr.ibh;
+ u8 lnh = ib_get_lnh(hdr);
+
+ if (lnh == HFI1_LRH_GRH)
+ ohdr = &hdr->u.l.oth;
+ else
+ ohdr = &hdr->u.oth;
+ slid = ib_get_slid(hdr);
+ pkey = ib_bth_get_pkey(ohdr);
+ }
+
+ ps->opcode = ib_bth_get_opcode(ohdr);
+ sr = get_send_routine(qp, ps);
+ ret = egress_pkey_check(dd->pport, slid, pkey,
+ priv->s_sc, qp->s_pkey_index);
if (unlikely(ret)) {
/*
* The value we are returning here does not get propagated to
@@ -1361,14 +1453,14 @@ static int query_port(struct rvt_dev_info *rdi, u8 port_num,
struct hfi1_ibdev *verbs_dev = dev_from_rdi(rdi);
struct hfi1_devdata *dd = dd_from_dev(verbs_dev);
struct hfi1_pportdata *ppd = &dd->pport[port_num - 1];
- u16 lid = ppd->lid;
+ u32 lid = ppd->lid;
/* props being zeroed by the caller, avoid zeroing it here */
props->lid = lid ? lid : 0;
props->lmc = ppd->lmc;
/* OPA logical states match IB logical states */
props->state = driver_lstate(ppd);
- props->phys_state = hfi1_ibphys_portstate(ppd);
+ props->phys_state = driver_pstate(ppd);
props->gid_tbl_len = HFI1_GUIDS_PER_PORT;
props->active_width = (u8)opa_width_to_ib(ppd->link_width_active);
/* see rate_show() in ib core/sysfs.c */
@@ -1388,6 +1480,15 @@ static int query_port(struct rvt_dev_info *rdi, u8 port_num,
props->active_mtu = !valid_ib_mtu(ppd->ibmtu) ? props->max_mtu :
mtu_to_enum(ppd->ibmtu, IB_MTU_2048);
+ /*
+ * sm_lid of 0xFFFF needs special handling so that it can
+ * be differentiated from a permissve LID of 0xFFFF.
+ * We set the grh_required flag here so the SA can program
+ * the DGID in the address handle appropriately
+ */
+ if (props->sm_lid == be16_to_cpu(IB_LID_PERMISSIVE))
+ props->grh_required = true;
+
return 0;
}
@@ -1473,6 +1574,10 @@ static int hfi1_check_ah(struct ib_device *ibdev, struct rdma_ah_attr *ah_attr)
struct hfi1_devdata *dd;
u8 sc5;
+ if (hfi1_check_mcast(rdma_ah_get_dlid(ah_attr)) &&
+ !(rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH))
+ return -EINVAL;
+
/* test the mapping for validity */
ibp = to_iport(ibdev, rdma_ah_get_port_num(ah_attr));
ppd = ppd_from_ibp(ibp);
@@ -1491,6 +1596,7 @@ static void hfi1_notify_new_ah(struct ib_device *ibdev,
struct hfi1_pportdata *ppd;
struct hfi1_devdata *dd;
u8 sc5;
+ struct rdma_ah_attr *attr = &ah->attr;
/*
* Do not trust reading anything from rvt_ah at this point as it is not
@@ -1500,33 +1606,14 @@ static void hfi1_notify_new_ah(struct ib_device *ibdev,
ibp = to_iport(ibdev, rdma_ah_get_port_num(ah_attr));
ppd = ppd_from_ibp(ibp);
sc5 = ibp->sl_to_sc[rdma_ah_get_sl(&ah->attr)];
+ hfi1_update_ah_attr(ibdev, attr);
+ hfi1_make_opa_lid(attr);
dd = dd_from_ppd(ppd);
ah->vl = sc_to_vlt(dd, sc5);
if (ah->vl < num_vls || ah->vl == 15)
ah->log_pmtu = ilog2(dd->vld[ah->vl].mtu);
}
-struct ib_ah *hfi1_create_qp0_ah(struct hfi1_ibport *ibp, u16 dlid)
-{
- struct rdma_ah_attr attr;
- struct ib_ah *ah = ERR_PTR(-EINVAL);
- struct rvt_qp *qp0;
- struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
- struct hfi1_devdata *dd = dd_from_ppd(ppd);
- u8 port_num = ppd->port;
-
- memset(&attr, 0, sizeof(attr));
- attr.type = rdma_ah_find_type(&dd->verbs_dev.rdi.ibdev, port_num);
- rdma_ah_set_dlid(&attr, dlid);
- rdma_ah_set_port_num(&attr, ppd_from_ibp(ibp)->port);
- rcu_read_lock();
- qp0 = rcu_dereference(ibp->rvp.qp[0]);
- if (qp0)
- ah = rdma_create_ah(qp0->ibqp.pd, &attr);
- rcu_read_unlock();
- return ah;
-}
-
/**
* hfi1_get_npkeys - return the size of the PKEY table for context 0
* @dd: the hfi1_ib device
@@ -1547,13 +1634,22 @@ static void init_ibport(struct hfi1_pportdata *ppd)
ibp->sc_to_sl[i] = i;
}
+ for (i = 0; i < RVT_MAX_TRAP_LISTS ; i++)
+ INIT_LIST_HEAD(&ibp->rvp.trap_lists[i].list);
+ setup_timer(&ibp->rvp.trap_timer, hfi1_handle_trap_timer,
+ (unsigned long)ibp);
+
spin_lock_init(&ibp->rvp.lock);
/* Set the prefix to the default value (see ch. 4.1.1) */
ibp->rvp.gid_prefix = IB_DEFAULT_GID_PREFIX;
ibp->rvp.sm_lid = 0;
- /* Below should only set bits defined in OPA PortInfo.CapabilityMask */
+ /*
+ * Below should only set bits defined in OPA PortInfo.CapabilityMask
+ * and PortInfo.CapabilityMask3
+ */
ibp->rvp.port_cap_flags = IB_PORT_AUTO_MIGR_SUP |
IB_PORT_CAP_MASK_NOTICE_SUP;
+ ibp->rvp.port_cap3_flags = OPA_CAP_MASK3_IsSharedSpaceSupported;
ibp->rvp.pma_counter_select[0] = IB_PMA_PORT_XMIT_DATA;
ibp->rvp.pma_counter_select[1] = IB_PMA_PORT_RCV_DATA;
ibp->rvp.pma_counter_select[2] = IB_PMA_PORT_XMIT_PKTS;
@@ -1564,14 +1660,13 @@ static void init_ibport(struct hfi1_pportdata *ppd)
RCU_INIT_POINTER(ibp->rvp.qp[1], NULL);
}
-static void hfi1_get_dev_fw_str(struct ib_device *ibdev, char *str,
- size_t str_len)
+static void hfi1_get_dev_fw_str(struct ib_device *ibdev, char *str)
{
struct rvt_dev_info *rdi = ib_to_rvt(ibdev);
struct hfi1_ibdev *dev = dev_from_rdi(rdi);
u32 ver = dd_from_dev(dev)->dc8051_ver;
- snprintf(str, str_len, "%u.%u.%u", dc8051_ver_maj(ver),
+ snprintf(str, IB_FW_VERSION_NAME_MAX, "%u.%u.%u", dc8051_ver_maj(ver),
dc8051_ver_min(ver), dc8051_ver_patch(ver));
}
@@ -1816,7 +1911,8 @@ int hfi1_register_ib_device(struct hfi1_devdata *dd)
dd->verbs_dev.rdi.dparms.psn_mask = PSN_MASK;
dd->verbs_dev.rdi.dparms.psn_shift = PSN_SHIFT;
dd->verbs_dev.rdi.dparms.psn_modify_mask = PSN_MODIFY_MASK;
- dd->verbs_dev.rdi.dparms.core_cap_flags = RDMA_CORE_PORT_INTEL_OPA;
+ dd->verbs_dev.rdi.dparms.core_cap_flags = RDMA_CORE_PORT_INTEL_OPA |
+ RDMA_CORE_CAP_OPA_AH;
dd->verbs_dev.rdi.dparms.max_mad_size = OPA_MGMT_MAD_SIZE;
dd->verbs_dev.rdi.driver_f.qp_priv_alloc = qp_priv_alloc;
diff --git a/drivers/infiniband/hw/hfi1/verbs.h b/drivers/infiniband/hw/hfi1/verbs.h
index cd635d0..87d1285 100644
--- a/drivers/infiniband/hw/hfi1/verbs.h
+++ b/drivers/infiniband/hw/hfi1/verbs.h
@@ -95,6 +95,7 @@ struct hfi1_packet;
#define HFI1_VENDOR_IPG cpu_to_be16(0xFFA0)
#define IB_DEFAULT_GID_PREFIX cpu_to_be64(0xfe80000000000000ULL)
+#define OPA_BTH_MIG_REQ BIT(31)
#define RC_OP(x) IB_OPCODE_RC_##x
#define UC_OP(x) IB_OPCODE_UC_##x
@@ -104,6 +105,25 @@ enum {
HFI1_HAS_GRH = (1 << 0),
};
+struct hfi1_16b_header {
+ u32 lrh[4];
+ union {
+ struct {
+ struct ib_grh grh;
+ struct ib_other_headers oth;
+ } l;
+ struct ib_other_headers oth;
+ } u;
+} __packed;
+
+struct hfi1_opa_header {
+ union {
+ struct ib_header ibh; /* 9B header */
+ struct hfi1_16b_header opah; /* 16B header */
+ };
+ u8 hdr_type; /* 9B or 16B */
+} __packed;
+
struct hfi1_ahg_info {
u32 ahgdesc[2];
u16 tx_flags;
@@ -113,7 +133,7 @@ struct hfi1_ahg_info {
struct hfi1_sdma_header {
__le64 pbc;
- struct ib_header hdr;
+ struct hfi1_opa_header hdr;
} __packed;
/*
@@ -127,6 +147,7 @@ struct hfi1_qp_priv {
u8 s_sc; /* SC[0..4] for next packet */
struct iowait s_iowait;
struct rvt_qp *owner;
+ u8 hdr_type; /* 9B or 16B */
};
/*
@@ -142,7 +163,9 @@ struct hfi1_pkt_state {
unsigned long timeout;
unsigned long timeout_int;
int cpu;
+ u8 opcode;
bool in_thread;
+ bool pkts_sent;
};
#define HFI1_PSN_CREDIT 16
@@ -236,8 +259,8 @@ static inline int hfi1_send_ok(struct rvt_qp *qp)
/*
* This must be called with s_lock held.
*/
-void hfi1_bad_pqkey(struct hfi1_ibport *ibp, __be16 trap_num, u32 key, u32 sl,
- u32 qp1, u32 qp2, u16 lid1, u16 lid2);
+void hfi1_bad_pkey(struct hfi1_ibport *ibp, u32 key, u32 sl,
+ u32 qp1, u32 qp2, u32 lid1, u32 lid2);
void hfi1_cap_mask_chg(struct rvt_dev_info *rdi, u8 port_num);
void hfi1_sys_guid_chg(struct hfi1_ibport *ibp);
void hfi1_node_desc_chg(struct hfi1_ibport *ibp);
@@ -257,13 +280,8 @@ int hfi1_process_mad(struct ib_device *ibdev, int mad_flags, u8 port,
* necessarily be at least one bit less than
* the container holding the PSN.
*/
-#ifndef CONFIG_HFI1_VERBS_31BIT_PSN
-#define PSN_MASK 0xFFFFFF
-#define PSN_SHIFT 8
-#else
#define PSN_MASK 0x7FFFFFFF
#define PSN_SHIFT 1
-#endif
#define PSN_MODIFY_MASK 0xFFFFFF
/*
@@ -307,15 +325,12 @@ void hfi1_rc_rcv(struct hfi1_packet *packet);
void hfi1_rc_hdrerr(
struct hfi1_ctxtdata *rcd,
- struct ib_header *hdr,
- u32 rcv_flags,
+ struct hfi1_packet *packet,
struct rvt_qp *qp);
u8 ah_to_sc(struct ib_device *ibdev, struct rdma_ah_attr *ah_attr);
-struct ib_ah *hfi1_create_qp0_ah(struct hfi1_ibport *ibp, u16 dlid);
-
-void hfi1_rc_send_complete(struct rvt_qp *qp, struct ib_header *hdr);
+void hfi1_rc_send_complete(struct rvt_qp *qp, struct hfi1_opa_header *opah);
void hfi1_ud_rcv(struct hfi1_packet *packet);
@@ -336,18 +351,7 @@ int hfi1_check_send_wqe(struct rvt_qp *qp, struct rvt_swqe *wqe);
extern const u32 rc_only_opcode;
extern const u32 uc_only_opcode;
-static inline u8 get_opcode(struct ib_header *h)
-{
- u16 lnh = be16_to_cpu(h->lrh[0]) & 3;
-
- if (lnh == IB_LNH_IBA_LOCAL)
- return be32_to_cpu(h->u.oth.bth[0]) >> 24;
- else
- return be32_to_cpu(h->u.l.oth.bth[0]) >> 24;
-}
-
-int hfi1_ruc_check_hdr(struct hfi1_ibport *ibp, struct ib_header *hdr,
- int has_grh, struct rvt_qp *qp, u32 bth0);
+int hfi1_ruc_check_hdr(struct hfi1_ibport *ibp, struct hfi1_packet *packet);
u32 hfi1_make_grh(struct hfi1_ibport *ibp, struct ib_grh *hdr,
const struct ib_global_route *grh, u32 hwords, u32 nwords);
@@ -365,7 +369,8 @@ void hfi1_do_send(struct rvt_qp *qp, bool in_thread);
void hfi1_send_complete(struct rvt_qp *qp, struct rvt_swqe *wqe,
enum ib_wc_status status);
-void hfi1_send_rc_ack(struct hfi1_ctxtdata *, struct rvt_qp *qp, int is_fecn);
+void hfi1_send_rc_ack(struct hfi1_ctxtdata *rcd, struct rvt_qp *qp,
+ bool is_fecn);
int hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps);
@@ -379,6 +384,8 @@ void hfi1_unregister_ib_device(struct hfi1_devdata *);
void hfi1_ib_rcv(struct hfi1_packet *packet);
+void hfi1_16B_rcv(struct hfi1_packet *packet);
+
unsigned hfi1_get_npkeys(struct hfi1_devdata *);
int hfi1_verbs_send_dma(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
diff --git a/drivers/infiniband/hw/hfi1/verbs_txreq.c b/drivers/infiniband/hw/hfi1/verbs_txreq.c
index 5d23172..873e48e 100644
--- a/drivers/infiniband/hw/hfi1/verbs_txreq.c
+++ b/drivers/infiniband/hw/hfi1/verbs_txreq.c
@@ -1,5 +1,5 @@
/*
- * Copyright(c) 2016 Intel Corporation.
+ * Copyright(c) 2016 - 2017 Intel Corporation.
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
@@ -119,13 +119,6 @@ out:
return tx;
}
-static void verbs_txreq_kmem_cache_ctor(void *obj)
-{
- struct verbs_txreq *tx = (struct verbs_txreq *)obj;
-
- memset(tx, 0, sizeof(*tx));
-}
-
int verbs_txreq_init(struct hfi1_ibdev *dev)
{
char buf[TXREQ_LEN];
@@ -135,7 +128,7 @@ int verbs_txreq_init(struct hfi1_ibdev *dev)
dev->verbs_txreq_cache = kmem_cache_create(buf,
sizeof(struct verbs_txreq),
0, SLAB_HWCACHE_ALIGN,
- verbs_txreq_kmem_cache_ctor);
+ NULL);
if (!dev->verbs_txreq_cache)
return -ENOMEM;
return 0;
diff --git a/drivers/infiniband/hw/hfi1/vnic.h b/drivers/infiniband/hw/hfi1/vnic.h
index 4a621cd..5ae7815 100644
--- a/drivers/infiniband/hw/hfi1/vnic.h
+++ b/drivers/infiniband/hw/hfi1/vnic.h
@@ -54,21 +54,6 @@
#define HFI1_VNIC_MAX_TXQ 16
#define HFI1_VNIC_MAX_PAD 12
-/* L2 header definitions */
-#define HFI1_L2_TYPE_OFFSET 0x7
-#define HFI1_L2_TYPE_SHFT 0x5
-#define HFI1_L2_TYPE_MASK 0x3
-
-#define HFI1_GET_L2_TYPE(hdr) \
- ((*((u8 *)(hdr) + HFI1_L2_TYPE_OFFSET) >> HFI1_L2_TYPE_SHFT) & \
- HFI1_L2_TYPE_MASK)
-
-/* L4 type definitions */
-#define HFI1_L4_TYPE_OFFSET 8
-
-#define HFI1_GET_L4_TYPE(data) \
- (*((u8 *)(data) + HFI1_L4_TYPE_OFFSET))
-
/* L4 header definitions */
#define HFI1_VNIC_L4_HDR_OFFSET OPA_VNIC_L2_HDR_LEN
@@ -103,6 +88,7 @@ struct hfi1_vnic_sdma {
struct sdma_txreq stx;
unsigned int state;
u8 q_idx;
+ bool pkts_sent;
};
/**
diff --git a/drivers/infiniband/hw/hfi1/vnic_main.c b/drivers/infiniband/hw/hfi1/vnic_main.c
index 339f0cd..f419cbb 100644
--- a/drivers/infiniband/hw/hfi1/vnic_main.c
+++ b/drivers/infiniband/hw/hfi1/vnic_main.c
@@ -95,7 +95,7 @@ static int setup_vnic_ctxt(struct hfi1_devdata *dd, struct hfi1_ctxtdata *uctxt)
if (HFI1_CAP_KGET_MASK(uctxt->flags, DMA_RTAIL))
rcvctrl_ops |= HFI1_RCVCTRL_TAILUPD_ENB;
- hfi1_rcvctrl(uctxt->dd, rcvctrl_ops, uctxt->ctxt);
+ hfi1_rcvctrl(uctxt->dd, rcvctrl_ops, uctxt);
uctxt->is_vnic = true;
done:
@@ -106,22 +106,13 @@ static int allocate_vnic_ctxt(struct hfi1_devdata *dd,
struct hfi1_ctxtdata **vnic_ctxt)
{
struct hfi1_ctxtdata *uctxt;
- unsigned int ctxt;
int ret;
if (dd->flags & HFI1_FROZEN)
return -EIO;
- for (ctxt = dd->first_dyn_alloc_ctxt;
- ctxt < dd->num_rcv_contexts; ctxt++)
- if (!dd->rcd[ctxt])
- break;
-
- if (ctxt == dd->num_rcv_contexts)
- return -EBUSY;
-
- uctxt = hfi1_create_ctxtdata(dd->pport, ctxt, dd->node);
- if (!uctxt) {
+ ret = hfi1_create_ctxtdata(dd->pport, dd->node, &uctxt);
+ if (ret < 0) {
dd_dev_err(dd, "Unable to create ctxtdata, failing open\n");
return -ENOMEM;
}
@@ -155,12 +146,7 @@ static int allocate_vnic_ctxt(struct hfi1_devdata *dd,
return ret;
bail:
- /*
- * hfi1_free_ctxtdata() also releases send_context
- * structure if uctxt->sc is not null
- */
- dd->rcd[uctxt->ctxt] = NULL;
- hfi1_free_ctxtdata(dd, uctxt);
+ hfi1_free_ctxt(uctxt);
dd_dev_dbg(dd, "vnic allocation failed. rc %d\n", ret);
return ret;
}
@@ -168,15 +154,12 @@ bail:
static void deallocate_vnic_ctxt(struct hfi1_devdata *dd,
struct hfi1_ctxtdata *uctxt)
{
- unsigned long flags;
-
dd_dev_dbg(dd, "closing vnic context %d\n", uctxt->ctxt);
flush_wc();
if (dd->num_msix_entries)
hfi1_reset_vnic_msix_info(uctxt);
- spin_lock_irqsave(&dd->uctxt_lock, flags);
/*
* Disable receive context and interrupt available, reset all
* RcvCtxtCtrl bits to default values.
@@ -186,7 +169,7 @@ static void deallocate_vnic_ctxt(struct hfi1_devdata *dd,
HFI1_RCVCTRL_INTRAVAIL_DIS |
HFI1_RCVCTRL_ONE_PKT_EGR_DIS |
HFI1_RCVCTRL_NO_RHQ_DROP_DIS |
- HFI1_RCVCTRL_NO_EGR_DROP_DIS, uctxt->ctxt);
+ HFI1_RCVCTRL_NO_EGR_DROP_DIS, uctxt);
/*
* VNIC contexts are allocated from user context pool.
* Release them back to user context pool.
@@ -199,16 +182,15 @@ static void deallocate_vnic_ctxt(struct hfi1_devdata *dd,
sc_disable(uctxt->sc);
dd->send_contexts[uctxt->sc->sw_index].type = SC_USER;
- spin_unlock_irqrestore(&dd->uctxt_lock, flags);
- dd->rcd[uctxt->ctxt] = NULL;
uctxt->event_flags = 0;
hfi1_clear_tids(uctxt);
hfi1_clear_ctxt_pkey(dd, uctxt);
hfi1_stats.sps_ctxts--;
- hfi1_free_ctxtdata(dd, uctxt);
+
+ hfi1_free_ctxt(uctxt);
}
void hfi1_vnic_setup(struct hfi1_devdata *dd)
@@ -582,8 +564,8 @@ void hfi1_vnic_bypass_rcv(struct hfi1_packet *packet)
int l4_type, vesw_id = -1;
u8 q_idx;
- l4_type = HFI1_GET_L4_TYPE(packet->ebuf);
- if (likely(l4_type == OPA_VNIC_L4_ETHR)) {
+ l4_type = hfi1_16B_get_l4(packet->ebuf);
+ if (likely(l4_type == OPA_16B_L4_ETHR)) {
vesw_id = HFI1_VNIC_GET_VESWID(packet->ebuf);
vinfo = idr_find(&dd->vnic.vesw_idr, vesw_id);
@@ -751,6 +733,7 @@ static int hfi1_vnic_init(struct hfi1_vnic_vport_info *vinfo)
rc = hfi1_vnic_allot_ctxt(dd, &dd->vnic.ctxt[i]);
if (rc)
break;
+ hfi1_rcd_get(dd->vnic.ctxt[i]);
dd->vnic.ctxt[i]->vnic_q_idx = i;
}
@@ -762,6 +745,7 @@ static int hfi1_vnic_init(struct hfi1_vnic_vport_info *vinfo)
*/
while (i-- > dd->vnic.num_ctxt) {
deallocate_vnic_ctxt(dd, dd->vnic.ctxt[i]);
+ hfi1_rcd_put(dd->vnic.ctxt[i]);
dd->vnic.ctxt[i] = NULL;
}
goto alloc_fail;
@@ -791,6 +775,7 @@ static void hfi1_vnic_deinit(struct hfi1_vnic_vport_info *vinfo)
if (--dd->vnic.num_vports == 0) {
for (i = 0; i < dd->vnic.num_ctxt; i++) {
deallocate_vnic_ctxt(dd, dd->vnic.ctxt[i]);
+ hfi1_rcd_put(dd->vnic.ctxt[i]);
dd->vnic.ctxt[i] = NULL;
}
hfi1_deinit_vnic_rsm(dd);
diff --git a/drivers/infiniband/hw/hfi1/vnic_sdma.c b/drivers/infiniband/hw/hfi1/vnic_sdma.c
index 51a817d..c3c96c5 100644
--- a/drivers/infiniband/hw/hfi1/vnic_sdma.c
+++ b/drivers/infiniband/hw/hfi1/vnic_sdma.c
@@ -198,11 +198,16 @@ int hfi1_vnic_send_dma(struct hfi1_devdata *dd, u8 q_idx,
goto free_desc;
tx->retry_count = 0;
- ret = sdma_send_txreq(sde, &vnic_sdma->wait, &tx->txreq);
+ ret = sdma_send_txreq(sde, &vnic_sdma->wait, &tx->txreq,
+ vnic_sdma->pkts_sent);
/* When -ECOMM, sdma callback will be called with ABORT status */
if (unlikely(ret && unlikely(ret != -ECOMM)))
goto free_desc;
+ if (!ret) {
+ vnic_sdma->pkts_sent = true;
+ iowait_starve_clear(vnic_sdma->pkts_sent, &vnic_sdma->wait);
+ }
return ret;
free_desc:
@@ -211,6 +216,8 @@ free_desc:
tx_err:
if (ret != -EBUSY)
dev_kfree_skb_any(skb);
+ else
+ vnic_sdma->pkts_sent = false;
return ret;
}
@@ -225,7 +232,8 @@ tx_err:
static int hfi1_vnic_sdma_sleep(struct sdma_engine *sde,
struct iowait *wait,
struct sdma_txreq *txreq,
- unsigned int seq)
+ uint seq,
+ bool pkts_sent)
{
struct hfi1_vnic_sdma *vnic_sdma =
container_of(wait, struct hfi1_vnic_sdma, wait);
@@ -239,7 +247,7 @@ static int hfi1_vnic_sdma_sleep(struct sdma_engine *sde,
vnic_sdma->state = HFI1_VNIC_SDMA_Q_DEFERRED;
write_seqlock(&dev->iowait_lock);
if (list_empty(&vnic_sdma->wait.list))
- list_add_tail(&vnic_sdma->wait.list, &sde->dmawait);
+ iowait_queue(pkts_sent, wait, &sde->dmawait);
write_sequnlock(&dev->iowait_lock);
return -EBUSY;
}
@@ -295,22 +303,15 @@ void hfi1_vnic_sdma_init(struct hfi1_vnic_vport_info *vinfo)
}
}
-static void hfi1_vnic_txreq_kmem_cache_ctor(void *obj)
-{
- struct vnic_txreq *tx = (struct vnic_txreq *)obj;
-
- memset(tx, 0, sizeof(*tx));
-}
-
int hfi1_vnic_txreq_init(struct hfi1_devdata *dd)
{
char buf[HFI1_VNIC_TXREQ_NAME_LEN];
snprintf(buf, sizeof(buf), "hfi1_%u_vnic_txreq_cache", dd->unit);
dd->vnic.txreq_cache = kmem_cache_create(buf,
- sizeof(struct vnic_txreq),
- 0, SLAB_HWCACHE_ALIGN,
- hfi1_vnic_txreq_kmem_cache_ctor);
+ sizeof(struct vnic_txreq),
+ 0, SLAB_HWCACHE_ALIGN,
+ NULL);
if (!dd->vnic.txreq_cache)
return -ENOMEM;
return 0;
diff --git a/drivers/infiniband/hw/hns/Kconfig b/drivers/infiniband/hw/hns/Kconfig
index e1a6e05..61c93bb 100644
--- a/drivers/infiniband/hw/hns/Kconfig
+++ b/drivers/infiniband/hw/hns/Kconfig
@@ -1,7 +1,7 @@
config INFINIBAND_HNS
tristate "HNS RoCE Driver"
depends on NET_VENDOR_HISILICON
- depends on ARM64 && HNS && HNS_DSAF && HNS_ENET
+ depends on (ARM64 || (COMPILE_TEST && 64BIT)) && HNS && HNS_DSAF && HNS_ENET
---help---
This is a RoCE/RDMA driver for the Hisilicon RoCE engine. The engine
is used in Hisilicon Hi1610 and more further ICT SoC.
diff --git a/drivers/infiniband/hw/hns/hns_roce_alloc.c b/drivers/infiniband/hw/hns/hns_roce_alloc.c
index 605962f..e1b433c 100644
--- a/drivers/infiniband/hw/hns/hns_roce_alloc.c
+++ b/drivers/infiniband/hw/hns/hns_roce_alloc.c
@@ -32,6 +32,7 @@
*/
#include <linux/platform_device.h>
+#include <linux/vmalloc.h>
#include "hns_roce_device.h"
int hns_roce_bitmap_alloc(struct hns_roce_bitmap *bitmap, unsigned long *obj)
diff --git a/drivers/infiniband/hw/hns/hns_roce_eq.c b/drivers/infiniband/hw/hns/hns_roce_eq.c
index 50f8649..b0f4373 100644
--- a/drivers/infiniband/hw/hns/hns_roce_eq.c
+++ b/drivers/infiniband/hw/hns/hns_roce_eq.c
@@ -31,6 +31,7 @@
*/
#include <linux/platform_device.h>
+#include <linux/interrupt.h>
#include "hns_roce_common.h"
#include "hns_roce_device.h"
#include "hns_roce_eq.h"
@@ -292,7 +293,7 @@ static int hns_roce_aeq_int(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq)
dev_warn(dev, "Unhandled event %d on EQ %d at index %u\n",
event_type, eq->eqn, eq->cons_index);
break;
- };
+ }
eq->cons_index++;
aeqes_found = 1;
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
index 2540b65..747efd1 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
@@ -2023,7 +2023,6 @@ int hns_roce_v1_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags)
struct hns_roce_cq *hr_cq = to_hr_cq(ibcq);
u32 notification_flag;
u32 doorbell[2];
- int ret = 0;
notification_flag = (flags & IB_CQ_SOLICITED_MASK) ==
IB_CQ_SOLICITED ? CQ_DB_REQ_NOT : CQ_DB_REQ_NOT_SOL;
@@ -2043,7 +2042,7 @@ int hns_roce_v1_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags)
hns_roce_write64_k(doorbell, hr_cq->cq_db_l);
- return ret;
+ return 0;
}
static int hns_roce_v1_poll_one(struct hns_roce_cq *hr_cq,
diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c
index 80fc01f..e387360 100644
--- a/drivers/infiniband/hw/hns/hns_roce_mr.c
+++ b/drivers/infiniband/hw/hns/hns_roce_mr.c
@@ -32,6 +32,7 @@
*/
#include <linux/platform_device.h>
+#include <linux/vmalloc.h>
#include <rdma/ib_umem.h>
#include "hns_roce_device.h"
#include "hns_roce_cmd.h"
diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c
index 054c526..f5dd21c 100644
--- a/drivers/infiniband/hw/hns/hns_roce_qp.c
+++ b/drivers/infiniband/hw/hns/hns_roce_qp.c
@@ -799,7 +799,7 @@ bool hns_roce_wq_overflow(struct hns_roce_wq *hr_wq, int nreq,
cur = hr_wq->head - hr_wq->tail;
if (likely(cur + nreq < hr_wq->max_post))
- return 0;
+ return false;
hr_cq = to_hr_cq(ib_cq);
spin_lock(&hr_cq->lock);
diff --git a/drivers/infiniband/hw/i40iw/i40iw_cm.c b/drivers/infiniband/hw/i40iw/i40iw_cm.c
index 5a2fa74..14f36ba 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_cm.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_cm.c
@@ -1582,15 +1582,14 @@ static enum i40iw_status_code i40iw_del_multiple_qhash(
}
/**
- * i40iw_netdev_vlan_ipv6 - Gets the netdev and mac
+ * i40iw_netdev_vlan_ipv6 - Gets the netdev and vlan
* @addr: local IPv6 address
* @vlan_id: vlan id for the given IPv6 address
- * @mac: mac address for the given IPv6 address
*
* Returns the net_device of the IPv6 address and also sets the
- * vlan id and mac for that address.
+ * vlan id for that address.
*/
-static struct net_device *i40iw_netdev_vlan_ipv6(u32 *addr, u16 *vlan_id, u8 *mac)
+static struct net_device *i40iw_netdev_vlan_ipv6(u32 *addr, u16 *vlan_id)
{
struct net_device *ip_dev = NULL;
struct in6_addr laddr6;
@@ -1600,15 +1599,11 @@ static struct net_device *i40iw_netdev_vlan_ipv6(u32 *addr, u16 *vlan_id, u8 *ma
i40iw_copy_ip_htonl(laddr6.in6_u.u6_addr32, addr);
if (vlan_id)
*vlan_id = I40IW_NO_VLAN;
- if (mac)
- eth_zero_addr(mac);
rcu_read_lock();
for_each_netdev_rcu(&init_net, ip_dev) {
if (ipv6_chk_addr(&init_net, &laddr6, ip_dev, 1)) {
if (vlan_id)
*vlan_id = rdma_vlan_dev_vlan_id(ip_dev);
- if (ip_dev->dev_addr && mac)
- ether_addr_copy(mac, ip_dev->dev_addr);
break;
}
}
@@ -3588,7 +3583,7 @@ int i40iw_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
cm_node->vlan_id = i40iw_get_vlan_ipv4(cm_node->loc_addr);
} else {
cm_node->ipv4 = false;
- i40iw_netdev_vlan_ipv6(cm_node->loc_addr, &cm_node->vlan_id, NULL);
+ i40iw_netdev_vlan_ipv6(cm_node->loc_addr, &cm_node->vlan_id);
}
i40iw_debug(cm_node->dev,
I40IW_DEBUG_CM,
@@ -3687,8 +3682,6 @@ int i40iw_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
cm_node->accelerated = 1;
if (cm_node->accept_pend) {
- if (!cm_node->listener)
- i40iw_pr_err("cm_node->listener NULL for passive node\n");
atomic_dec(&cm_node->listener->pend_accepts_cnt);
cm_node->accept_pend = 0;
}
@@ -3789,7 +3782,7 @@ int i40iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
raddr6->sin6_addr.in6_u.u6_addr32);
cm_info.loc_port = ntohs(laddr6->sin6_port);
cm_info.rem_port = ntohs(raddr6->sin6_port);
- i40iw_netdev_vlan_ipv6(cm_info.loc_addr, &cm_info.vlan_id, NULL);
+ i40iw_netdev_vlan_ipv6(cm_info.loc_addr, &cm_info.vlan_id);
}
cm_info.cm_id = cm_id;
cm_info.tos = cm_id->tos;
@@ -3931,8 +3924,7 @@ int i40iw_create_listen(struct iw_cm_id *cm_id, int backlog)
cm_info.loc_port = ntohs(laddr6->sin6_port);
if (ipv6_addr_type(&laddr6->sin6_addr) != IPV6_ADDR_ANY)
i40iw_netdev_vlan_ipv6(cm_info.loc_addr,
- &cm_info.vlan_id,
- NULL);
+ &cm_info.vlan_id);
else
wildcard = true;
}
@@ -4056,12 +4048,7 @@ static void i40iw_cm_event_connected(struct i40iw_cm_event *event)
i40iw_modify_qp(&iwqp->ibqp, &attr, IB_QP_STATE, NULL);
cm_node->accelerated = 1;
- if (cm_node->accept_pend) {
- if (!cm_node->listener)
- i40iw_pr_err("listener is null for passive node\n");
- atomic_dec(&cm_node->listener->pend_accepts_cnt);
- cm_node->accept_pend = 0;
- }
+
return;
error:
diff --git a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c
index a49ff2e..d1f5345 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c
@@ -54,6 +54,17 @@ static inline void i40iw_insert_wqe_hdr(u64 *wqe, u64 header)
set_64bit_val(wqe, 24, header);
}
+void i40iw_check_cqp_progress(struct i40iw_cqp_timeout *cqp_timeout, struct i40iw_sc_dev *dev)
+{
+ if (cqp_timeout->compl_cqp_cmds != dev->cqp_cmd_stats[OP_COMPLETED_COMMANDS]) {
+ cqp_timeout->compl_cqp_cmds = dev->cqp_cmd_stats[OP_COMPLETED_COMMANDS];
+ cqp_timeout->count = 0;
+ } else {
+ if (dev->cqp_cmd_stats[OP_REQUESTED_COMMANDS] != cqp_timeout->compl_cqp_cmds)
+ cqp_timeout->count++;
+ }
+}
+
/**
* i40iw_get_cqp_reg_info - get head and tail for cqp using registers
* @cqp: struct for cqp hw
diff --git a/drivers/infiniband/hw/i40iw/i40iw_main.c b/drivers/infiniband/hw/i40iw/i40iw_main.c
index ae8463f..cc742c3 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_main.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_main.c
@@ -77,7 +77,6 @@ MODULE_PARM_DESC(mpa_version, "MPA version to be used in MPA Req/Resp 1 or 2");
MODULE_AUTHOR("Intel Corporation, <e1000-rdma@lists.sourceforge.net>");
MODULE_DESCRIPTION("Intel(R) Ethernet Connection X722 iWARP RDMA Driver");
MODULE_LICENSE("Dual BSD/GPL");
-MODULE_VERSION(DRV_VERSION);
static struct i40e_client i40iw_client;
static char i40iw_client_name[I40E_CLIENT_STR_LENGTH] = "i40iw";
diff --git a/drivers/infiniband/hw/i40iw/i40iw_p.h b/drivers/infiniband/hw/i40iw/i40iw_p.h
index 28a92fe..e217a12 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_p.h
+++ b/drivers/infiniband/hw/i40iw/i40iw_p.h
@@ -35,11 +35,13 @@
#ifndef I40IW_P_H
#define I40IW_P_H
-#define PAUSE_TIMER_VALUE 0xFFFF
-#define REFRESH_THRESHOLD 0x7FFF
-#define HIGH_THRESHOLD 0x800
-#define LOW_THRESHOLD 0x200
-#define ALL_TC2PFC 0xFF
+#define PAUSE_TIMER_VALUE 0xFFFF
+#define REFRESH_THRESHOLD 0x7FFF
+#define HIGH_THRESHOLD 0x800
+#define LOW_THRESHOLD 0x200
+#define ALL_TC2PFC 0xFF
+#define CQP_COMPL_WAIT_TIME 0x3E8
+#define CQP_TIMEOUT_THRESHOLD 5
void i40iw_debug_buf(struct i40iw_sc_dev *dev, enum i40iw_debug_flag mask,
char *desc, u64 *buf, u32 size);
@@ -51,6 +53,8 @@ void i40iw_sc_cqp_post_sq(struct i40iw_sc_cqp *cqp);
u64 *i40iw_sc_cqp_get_next_send_wqe(struct i40iw_sc_cqp *cqp, u64 scratch);
+void i40iw_check_cqp_progress(struct i40iw_cqp_timeout *cqp_timeout, struct i40iw_sc_dev *dev);
+
enum i40iw_status_code i40iw_sc_mr_fast_register(struct i40iw_sc_qp *qp,
struct i40iw_fast_reg_stag_info *info,
bool post_sq);
diff --git a/drivers/infiniband/hw/i40iw/i40iw_pble.c b/drivers/infiniband/hw/i40iw/i40iw_pble.c
index c87ba16..540aab5 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_pble.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_pble.c
@@ -269,10 +269,8 @@ static enum i40iw_status_code add_bp_pages(struct i40iw_sc_dev *dev,
status = i40iw_add_sd_table_entry(dev->hw, hmc_info,
info->idx.sd_idx, I40IW_SD_TYPE_PAGED,
I40IW_HMC_DIRECT_BP_SIZE);
- if (status) {
- i40iw_free_vmalloc_mem(dev->hw, chunk);
- return status;
- }
+ if (status)
+ goto error;
if (!dev->is_pf) {
status = i40iw_vchnl_vf_add_hmc_objs(dev, I40IW_HMC_IW_PBLE,
fpm_to_idx(pble_rsrc,
@@ -280,8 +278,7 @@ static enum i40iw_status_code add_bp_pages(struct i40iw_sc_dev *dev,
(info->pages << PBLE_512_SHIFT));
if (status) {
i40iw_pr_err("allocate PBLEs in the PF. Error %i\n", status);
- i40iw_free_vmalloc_mem(dev->hw, chunk);
- return status;
+ goto error;
}
}
addr = chunk->vaddr;
diff --git a/drivers/infiniband/hw/i40iw/i40iw_puda.c b/drivers/infiniband/hw/i40iw/i40iw_puda.c
index 7f5583d..c2cab20 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_puda.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_puda.c
@@ -949,14 +949,16 @@ enum i40iw_status_code i40iw_puda_create_rsrc(struct i40iw_sc_vsi *vsi,
ret = i40iw_puda_qp_create(rsrc);
}
if (ret) {
- i40iw_debug(dev, I40IW_DEBUG_PUDA, "[%s] error qp_create\n", __func__);
+ i40iw_debug(dev, I40IW_DEBUG_PUDA, "[%s] error qp_create\n",
+ __func__);
goto error;
}
rsrc->completion = PUDA_QP_CREATED;
ret = i40iw_puda_allocbufs(rsrc, info->tx_buf_cnt + info->rq_size);
if (ret) {
- i40iw_debug(dev, I40IW_DEBUG_PUDA, "[%s] error allloc_buf\n", __func__);
+ i40iw_debug(dev, I40IW_DEBUG_PUDA, "[%s] error alloc_buf\n",
+ __func__);
goto error;
}
diff --git a/drivers/infiniband/hw/i40iw/i40iw_type.h b/drivers/infiniband/hw/i40iw/i40iw_type.h
index 959ec81..63118f6 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_type.h
+++ b/drivers/infiniband/hw/i40iw/i40iw_type.h
@@ -1345,4 +1345,9 @@ struct i40iw_virtchnl_work_info {
void *worker_vf_dev;
};
+struct i40iw_cqp_timeout {
+ u64 compl_cqp_cmds;
+ u8 count;
+};
+
#endif
diff --git a/drivers/infiniband/hw/i40iw/i40iw_uk.c b/drivers/infiniband/hw/i40iw/i40iw_uk.c
index 1060725..0aadb7a 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_uk.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_uk.c
@@ -912,7 +912,7 @@ enum i40iw_status_code i40iw_get_wqe_shift(u32 wqdepth, u32 sge, u32 inline_data
return 0;
}
-static struct i40iw_qp_uk_ops iw_qp_uk_ops = {
+static const struct i40iw_qp_uk_ops iw_qp_uk_ops = {
.iw_qp_post_wr = i40iw_qp_post_wr,
.iw_qp_ring_push_db = i40iw_qp_ring_push_db,
.iw_rdma_write = i40iw_rdma_write,
@@ -926,14 +926,14 @@ static struct i40iw_qp_uk_ops iw_qp_uk_ops = {
.iw_post_nop = i40iw_nop
};
-static struct i40iw_cq_ops iw_cq_ops = {
+static const struct i40iw_cq_ops iw_cq_ops = {
.iw_cq_request_notification = i40iw_cq_request_notification,
.iw_cq_poll_completion = i40iw_cq_poll_completion,
.iw_cq_post_entries = i40iw_cq_post_entries,
.iw_cq_clean = i40iw_clean_cq
};
-static struct i40iw_device_uk_ops iw_device_uk_ops = {
+static const struct i40iw_device_uk_ops iw_device_uk_ops = {
.iwarp_cq_uk_init = i40iw_cq_uk_init,
.iwarp_qp_uk_init = i40iw_qp_uk_init,
};
diff --git a/drivers/infiniband/hw/i40iw/i40iw_utils.c b/drivers/infiniband/hw/i40iw/i40iw_utils.c
index e311ec5..62f1f45 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_utils.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_utils.c
@@ -445,23 +445,29 @@ static int i40iw_wait_event(struct i40iw_device *iwdev,
{
struct cqp_commands_info *info = &cqp_request->info;
struct i40iw_cqp *iwcqp = &iwdev->cqp;
+ struct i40iw_cqp_timeout cqp_timeout;
bool cqp_error = false;
int err_code = 0;
- int timeout_ret = 0;
+ memset(&cqp_timeout, 0, sizeof(cqp_timeout));
+ cqp_timeout.compl_cqp_cmds = iwdev->sc_dev.cqp_cmd_stats[OP_COMPLETED_COMMANDS];
+ do {
+ if (wait_event_timeout(cqp_request->waitq,
+ cqp_request->request_done, CQP_COMPL_WAIT_TIME))
+ break;
- timeout_ret = wait_event_timeout(cqp_request->waitq,
- cqp_request->request_done,
- I40IW_EVENT_TIMEOUT);
- if (!timeout_ret) {
- i40iw_pr_err("error cqp command 0x%x timed out ret = %d\n",
- info->cqp_cmd, timeout_ret);
+ i40iw_check_cqp_progress(&cqp_timeout, &iwdev->sc_dev);
+
+ if (cqp_timeout.count < CQP_TIMEOUT_THRESHOLD)
+ continue;
+
+ i40iw_pr_err("error cqp command 0x%x timed out", info->cqp_cmd);
err_code = -ETIME;
if (!iwdev->reset) {
iwdev->reset = true;
i40iw_request_reset(iwdev);
}
goto done;
- }
+ } while (1);
cqp_error = cqp_request->compl_info.error;
if (cqp_error) {
i40iw_pr_err("error cqp command 0x%x completion maj = 0x%x min=0x%x\n",
diff --git a/drivers/infiniband/hw/i40iw/i40iw_verbs.c b/drivers/infiniband/hw/i40iw/i40iw_verbs.c
index 02d871d..1aa4110 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_verbs.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_verbs.c
@@ -2584,13 +2584,12 @@ static const char * const i40iw_hw_stat_names[] = {
"iwRdmaInv"
};
-static void i40iw_get_dev_fw_str(struct ib_device *dev, char *str,
- size_t str_len)
+static void i40iw_get_dev_fw_str(struct ib_device *dev, char *str)
{
u32 firmware_version = I40IW_FW_VERSION;
- snprintf(str, str_len, "%u.%u", firmware_version,
- (firmware_version & 0x000000ff));
+ snprintf(str, IB_FW_VERSION_NAME_MAX, "%u.%u", firmware_version,
+ (firmware_version & 0x000000ff));
}
/**
diff --git a/drivers/infiniband/hw/mlx4/alias_GUID.c b/drivers/infiniband/hw/mlx4/alias_GUID.c
index ea24230..155b4df 100644
--- a/drivers/infiniband/hw/mlx4/alias_GUID.c
+++ b/drivers/infiniband/hw/mlx4/alias_GUID.c
@@ -528,7 +528,7 @@ static int set_guid_rec(struct ib_device *ibdev,
memset(&guid_info_rec, 0, sizeof (struct ib_sa_guidinfo_rec));
- guid_info_rec.lid = cpu_to_be16(attr.lid);
+ guid_info_rec.lid = ib_lid_be16(attr.lid);
guid_info_rec.block_num = index;
memcpy(guid_info_rec.guid_info_list, rec_det->all_recs,
@@ -781,7 +781,7 @@ void mlx4_ib_init_alias_guid_work(struct mlx4_ib_dev *dev, int port)
spin_lock_irqsave(&dev->sriov.going_down_lock, flags);
spin_lock_irqsave(&dev->sriov.alias_guid.ag_work_lock, flags1);
if (!dev->sriov.is_going_down) {
- /* If there is pending one should cancell then run, otherwise
+ /* If there is pending one should cancel then run, otherwise
* won't run till previous one is ended as same work
* struct is used.
*/
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c
index ff931c5..cab7963 100644
--- a/drivers/infiniband/hw/mlx4/cq.c
+++ b/drivers/infiniband/hw/mlx4/cq.c
@@ -218,6 +218,7 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev,
goto err_mtt;
uar = &to_mucontext(context)->uar;
+ cq->mcq.usage = MLX4_RES_USAGE_USER_VERBS;
} else {
err = mlx4_db_alloc(dev->dev, &cq->db, 1);
if (err)
@@ -233,6 +234,7 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev,
goto err_db;
uar = &dev->priv_uar;
+ cq->mcq.usage = MLX4_RES_USAGE_DRIVER;
}
if (dev->eq_table)
@@ -635,7 +637,7 @@ static void mlx4_ib_poll_sw_comp(struct mlx4_ib_cq *cq, int num_entries,
struct mlx4_ib_qp *qp;
*npolled = 0;
- /* Find uncompleted WQEs belonging to that cq and retrun
+ /* Find uncompleted WQEs belonging to that cq and return
* simulated FLUSH_ERR completions
*/
list_for_each_entry(qp, &cq->send_qp_list, cq_send_list) {
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c
index 21d31cb..0793a21 100644
--- a/drivers/infiniband/hw/mlx4/mad.c
+++ b/drivers/infiniband/hw/mlx4/mad.c
@@ -169,7 +169,7 @@ int mlx4_MAD_IFC(struct mlx4_ib_dev *dev, int mad_ifc_flags,
op_modifier |= 0x4;
- in_modifier |= in_wc->slid << 16;
+ in_modifier |= ib_lid_cpu16(in_wc->slid) << 16;
}
err = mlx4_cmd_box(dev->dev, inmailbox->dma, outmailbox->dma, in_modifier,
@@ -625,7 +625,7 @@ int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port,
memcpy((char *)&tun_mad->hdr.slid_mac_47_32, &(wc->smac[4]), 2);
} else {
tun_mad->hdr.sl_vid = cpu_to_be16(((u16)(wc->sl)) << 12);
- tun_mad->hdr.slid_mac_47_32 = cpu_to_be16(wc->slid);
+ tun_mad->hdr.slid_mac_47_32 = ib_lid_be16(wc->slid);
}
ib_dma_sync_single_for_device(&dev->ib_dev,
@@ -826,7 +826,7 @@ static int ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
}
}
- slid = in_wc ? in_wc->slid : be16_to_cpu(IB_LID_PERMISSIVE);
+ slid = in_wc ? ib_lid_cpu16(in_wc->slid) : be16_to_cpu(IB_LID_PERMISSIVE);
if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP && slid == 0) {
forward_trap(to_mdev(ibdev), port_num, in_mad);
@@ -860,7 +860,7 @@ static int ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
in_mad->mad_hdr.method == IB_MGMT_METHOD_SET &&
in_mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO &&
!ib_query_port(ibdev, port_num, &pattr))
- prev_lid = pattr.lid;
+ prev_lid = ib_lid_cpu16(pattr.lid);
err = mlx4_MAD_IFC(to_mdev(ibdev),
(mad_flags & IB_MAD_IGNORE_MKEY ? MLX4_MAD_IFC_IGNORE_MKEY : 0) |
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index d1b43cb..c636842 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -70,7 +70,6 @@
MODULE_AUTHOR("Roland Dreier");
MODULE_DESCRIPTION("Mellanox ConnectX HCA InfiniBand driver");
MODULE_LICENSE("Dual BSD/GPL");
-MODULE_VERSION(DRV_VERSION);
int mlx4_ib_sm_guid_assign = 0;
module_param_named(sm_guid_assign, mlx4_ib_sm_guid_assign, int, 0444);
@@ -81,6 +80,8 @@ static const char mlx4_ib_version[] =
DRV_VERSION "\n";
static void do_slave_init(struct mlx4_ib_dev *ibdev, int slave, int do_init);
+static enum rdma_link_layer mlx4_ib_port_link_layer(struct ib_device *device,
+ u8 port_num);
static struct workqueue_struct *wq;
@@ -552,6 +553,16 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
props->timestamp_mask = 0xFFFFFFFFFFFFULL;
props->max_ah = INT_MAX;
+ if ((dev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RSS) &&
+ (mlx4_ib_port_link_layer(ibdev, 1) == IB_LINK_LAYER_ETHERNET ||
+ mlx4_ib_port_link_layer(ibdev, 2) == IB_LINK_LAYER_ETHERNET)) {
+ props->rss_caps.max_rwq_indirection_tables = props->max_qp;
+ props->rss_caps.max_rwq_indirection_table_size =
+ dev->dev->caps.max_rss_tbl_sz;
+ props->rss_caps.supported_qpts = 1 << IB_QPT_RAW_PACKET;
+ props->max_wq_type_rq = props->max_qp;
+ }
+
if (!mlx4_is_slave(dev->dev))
err = mlx4_get_internal_clock_params(dev->dev, &clock_params);
@@ -563,6 +574,13 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
}
}
+ if (uhw->outlen >= resp.response_length +
+ sizeof(resp.max_inl_recv_sz)) {
+ resp.response_length += sizeof(resp.max_inl_recv_sz);
+ resp.max_inl_recv_sz = dev->dev->caps.max_rq_sg *
+ sizeof(struct mlx4_wqe_data_seg);
+ }
+
if (uhw->outlen) {
err = ib_copy_to_udata(uhw, &resp, resp.response_length);
if (err)
@@ -1069,6 +1087,9 @@ static struct ib_ucontext *mlx4_ib_alloc_ucontext(struct ib_device *ibdev,
INIT_LIST_HEAD(&context->db_page_list);
mutex_init(&context->db_page_mutex);
+ INIT_LIST_HEAD(&context->wqn_ranges_list);
+ mutex_init(&context->wqn_ranges_mutex);
+
if (ibdev->uverbs_abi_ver == MLX4_IB_UVERBS_NO_DEV_CAPS_ABI_VERSION)
err = ib_copy_to_udata(udata, &resp_v3, sizeof(resp_v3));
else
@@ -2566,12 +2587,11 @@ static int mlx4_port_immutable(struct ib_device *ibdev, u8 port_num,
return 0;
}
-static void get_fw_ver_str(struct ib_device *device, char *str,
- size_t str_len)
+static void get_fw_ver_str(struct ib_device *device, char *str)
{
struct mlx4_ib_dev *dev =
container_of(device, struct mlx4_ib_dev, ib_dev);
- snprintf(str, str_len, "%d.%d.%d",
+ snprintf(str, IB_FW_VERSION_NAME_MAX, "%d.%d.%d",
(int) (dev->dev->caps.fw_ver >> 32),
(int) (dev->dev->caps.fw_ver >> 16) & 0xffff,
(int) dev->dev->caps.fw_ver & 0xffff);
@@ -2713,6 +2733,26 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
ibdev->ib_dev.get_dev_fw_str = get_fw_ver_str;
ibdev->ib_dev.disassociate_ucontext = mlx4_ib_disassociate_ucontext;
+ if ((dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RSS) &&
+ ((mlx4_ib_port_link_layer(&ibdev->ib_dev, 1) ==
+ IB_LINK_LAYER_ETHERNET) ||
+ (mlx4_ib_port_link_layer(&ibdev->ib_dev, 2) ==
+ IB_LINK_LAYER_ETHERNET))) {
+ ibdev->ib_dev.create_wq = mlx4_ib_create_wq;
+ ibdev->ib_dev.modify_wq = mlx4_ib_modify_wq;
+ ibdev->ib_dev.destroy_wq = mlx4_ib_destroy_wq;
+ ibdev->ib_dev.create_rwq_ind_table =
+ mlx4_ib_create_rwq_ind_table;
+ ibdev->ib_dev.destroy_rwq_ind_table =
+ mlx4_ib_destroy_rwq_ind_table;
+ ibdev->ib_dev.uverbs_ex_cmd_mask |=
+ (1ull << IB_USER_VERBS_EX_CMD_CREATE_WQ) |
+ (1ull << IB_USER_VERBS_EX_CMD_MODIFY_WQ) |
+ (1ull << IB_USER_VERBS_EX_CMD_DESTROY_WQ) |
+ (1ull << IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL) |
+ (1ull << IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL);
+ }
+
if (!mlx4_is_slave(ibdev->dev)) {
ibdev->ib_dev.alloc_fmr = mlx4_ib_fmr_alloc;
ibdev->ib_dev.map_phys_fmr = mlx4_ib_map_phys_fmr;
@@ -2772,7 +2812,8 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
allocated = 0;
if (mlx4_ib_port_link_layer(&ibdev->ib_dev, i + 1) ==
IB_LINK_LAYER_ETHERNET) {
- err = mlx4_counter_alloc(ibdev->dev, &counter_index);
+ err = mlx4_counter_alloc(ibdev->dev, &counter_index,
+ MLX4_RES_USAGE_DRIVER);
/* if failed to allocate a new counter, use default */
if (err)
counter_index =
@@ -2827,7 +2868,8 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
ibdev->steer_qpn_count = MLX4_IB_UC_MAX_NUM_QPS;
err = mlx4_qp_reserve_range(dev, ibdev->steer_qpn_count,
MLX4_IB_UC_STEER_QPN_ALIGN,
- &ibdev->steer_qpn_base, 0);
+ &ibdev->steer_qpn_base, 0,
+ MLX4_RES_USAGE_DRIVER);
if (err)
goto err_counter;
diff --git a/drivers/infiniband/hw/mlx4/mcg.c b/drivers/infiniband/hw/mlx4/mcg.c
index b73f897..70eb9f9 100644
--- a/drivers/infiniband/hw/mlx4/mcg.c
+++ b/drivers/infiniband/hw/mlx4/mcg.c
@@ -808,8 +808,7 @@ static ssize_t sysfs_show_group(struct device *dev,
struct device_attribute *attr, char *buf);
static struct mcast_group *acquire_group(struct mlx4_ib_demux_ctx *ctx,
- union ib_gid *mgid, int create,
- gfp_t gfp_mask)
+ union ib_gid *mgid, int create)
{
struct mcast_group *group, *cur_group;
int is_mgid0;
@@ -825,7 +824,7 @@ static struct mcast_group *acquire_group(struct mlx4_ib_demux_ctx *ctx,
if (!create)
return ERR_PTR(-ENOENT);
- group = kzalloc(sizeof *group, gfp_mask);
+ group = kzalloc(sizeof(*group), GFP_KERNEL);
if (!group)
return ERR_PTR(-ENOMEM);
@@ -892,7 +891,7 @@ int mlx4_ib_mcg_demux_handler(struct ib_device *ibdev, int port, int slave,
case IB_MGMT_METHOD_GET_RESP:
case IB_SA_METHOD_DELETE_RESP:
mutex_lock(&ctx->mcg_table_lock);
- group = acquire_group(ctx, &rec->mgid, 0, GFP_KERNEL);
+ group = acquire_group(ctx, &rec->mgid, 0);
mutex_unlock(&ctx->mcg_table_lock);
if (IS_ERR(group)) {
if (mad->mad_hdr.method == IB_MGMT_METHOD_GET_RESP) {
@@ -954,7 +953,7 @@ int mlx4_ib_mcg_multiplex_handler(struct ib_device *ibdev, int port,
req->sa_mad = *sa_mad;
mutex_lock(&ctx->mcg_table_lock);
- group = acquire_group(ctx, &rec->mgid, may_create, GFP_KERNEL);
+ group = acquire_group(ctx, &rec->mgid, may_create);
mutex_unlock(&ctx->mcg_table_lock);
if (IS_ERR(group)) {
kfree(req);
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h
index 9db82e6..1fa1982 100644
--- a/drivers/infiniband/hw/mlx4/mlx4_ib.h
+++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h
@@ -46,6 +46,7 @@
#include <linux/mlx4/device.h>
#include <linux/mlx4/doorbell.h>
+#include <linux/mlx4/qp.h>
#define MLX4_IB_DRV_NAME "mlx4_ib"
@@ -88,6 +89,8 @@ struct mlx4_ib_ucontext {
struct list_head db_page_list;
struct mutex db_page_mutex;
struct mlx4_ib_vma_private_data hw_bar_info[HW_BAR_COUNT];
+ struct list_head wqn_ranges_list;
+ struct mutex wqn_ranges_mutex; /* protect wqn_ranges_list */
};
struct mlx4_ib_pd {
@@ -289,8 +292,25 @@ struct mlx4_roce_smac_vlan_info {
int update_vid;
};
+struct mlx4_wqn_range {
+ int base_wqn;
+ int size;
+ int refcount;
+ bool dirty;
+ struct list_head list;
+};
+
+struct mlx4_ib_rss {
+ unsigned int base_qpn_tbl_sz;
+ u8 flags;
+ u8 rss_key[MLX4_EN_RSS_KEY_SIZE];
+};
+
struct mlx4_ib_qp {
- struct ib_qp ibqp;
+ union {
+ struct ib_qp ibqp;
+ struct ib_wq ibwq;
+ };
struct mlx4_qp mqp;
struct mlx4_buf buf;
@@ -318,6 +338,7 @@ struct mlx4_ib_qp {
u8 sq_no_prefetch;
u8 state;
int mlx_type;
+ u32 inl_recv_sz;
struct list_head gid_list;
struct list_head steering_rules;
struct mlx4_ib_buf *sqp_proxy_rcv;
@@ -328,6 +349,10 @@ struct mlx4_ib_qp {
struct list_head cq_recv_list;
struct list_head cq_send_list;
struct counter_index *counter_index;
+ struct mlx4_wqn_range *wqn_range;
+ /* Number of RSS QP parents that uses this WQ */
+ u32 rss_usecnt;
+ struct mlx4_ib_rss *rss_ctx;
};
struct mlx4_ib_srq {
@@ -623,6 +648,8 @@ struct mlx4_uverbs_ex_query_device_resp {
__u32 comp_mask;
__u32 response_length;
__u64 hca_core_clock_offset;
+ __u32 max_inl_recv_sz;
+ __u32 reserved;
};
static inline struct mlx4_ib_dev *to_mdev(struct ib_device *ibdev)
@@ -890,4 +917,17 @@ void mlx4_sched_ib_sl2vl_update_work(struct mlx4_ib_dev *ibdev,
void mlx4_ib_sl2vl_update(struct mlx4_ib_dev *mdev, int port);
+struct ib_wq *mlx4_ib_create_wq(struct ib_pd *pd,
+ struct ib_wq_init_attr *init_attr,
+ struct ib_udata *udata);
+int mlx4_ib_destroy_wq(struct ib_wq *wq);
+int mlx4_ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr,
+ u32 wq_attr_mask, struct ib_udata *udata);
+
+struct ib_rwq_ind_table
+*mlx4_ib_create_rwq_ind_table(struct ib_device *device,
+ struct ib_rwq_ind_table_init_attr *init_attr,
+ struct ib_udata *udata);
+int mlx4_ib_destroy_rwq_ind_table(struct ib_rwq_ind_table *wq_ind_table);
+
#endif /* MLX4_IB_H */
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 75c0e6c..2747abd 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -36,7 +36,6 @@
#include <net/ip.h>
#include <linux/slab.h>
#include <linux/netdevice.h>
-#include <linux/vmalloc.h>
#include <rdma/ib_cache.h>
#include <rdma/ib_pack.h>
@@ -53,6 +52,7 @@ static void mlx4_ib_lock_cqs(struct mlx4_ib_cq *send_cq,
struct mlx4_ib_cq *recv_cq);
static void mlx4_ib_unlock_cqs(struct mlx4_ib_cq *send_cq,
struct mlx4_ib_cq *recv_cq);
+static int _mlx4_ib_modify_wq(struct ib_wq *ibwq, enum ib_wq_state new_state);
enum {
MLX4_IB_ACK_REQ_FREQ = 8,
@@ -116,6 +116,11 @@ static const __be32 mlx4_ib_opcode[] = {
[IB_WR_MASKED_ATOMIC_FETCH_AND_ADD] = cpu_to_be32(MLX4_OPCODE_MASKED_ATOMIC_FA),
};
+enum mlx4_ib_source_type {
+ MLX4_IB_QP_SRC = 0,
+ MLX4_IB_RWQ_SRC = 1,
+};
+
static struct mlx4_ib_sqp *to_msqp(struct mlx4_ib_qp *mqp)
{
return container_of(mqp, struct mlx4_ib_sqp, qp);
@@ -330,6 +335,12 @@ static void mlx4_ib_qp_event(struct mlx4_qp *qp, enum mlx4_event type)
}
}
+static void mlx4_ib_wq_event(struct mlx4_qp *qp, enum mlx4_event type)
+{
+ pr_warn_ratelimited("Unexpected event type %d on WQ 0x%06x. Events are not supported for WQs\n",
+ type, qp->qpn);
+}
+
static int send_wqe_overhead(enum mlx4_ib_qp_type type, u32 flags)
{
/*
@@ -377,7 +388,8 @@ static int send_wqe_overhead(enum mlx4_ib_qp_type type, u32 flags)
}
static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
- int is_user, int has_rq, struct mlx4_ib_qp *qp)
+ int is_user, int has_rq, struct mlx4_ib_qp *qp,
+ u32 inl_recv_sz)
{
/* Sanity check RQ size before proceeding */
if (cap->max_recv_wr > dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE ||
@@ -385,18 +397,24 @@ static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
return -EINVAL;
if (!has_rq) {
- if (cap->max_recv_wr)
+ if (cap->max_recv_wr || inl_recv_sz)
return -EINVAL;
qp->rq.wqe_cnt = qp->rq.max_gs = 0;
} else {
+ u32 max_inl_recv_sz = dev->dev->caps.max_rq_sg *
+ sizeof(struct mlx4_wqe_data_seg);
+ u32 wqe_size;
+
/* HW requires >= 1 RQ entry with >= 1 gather entry */
- if (is_user && (!cap->max_recv_wr || !cap->max_recv_sge))
+ if (is_user && (!cap->max_recv_wr || !cap->max_recv_sge ||
+ inl_recv_sz > max_inl_recv_sz))
return -EINVAL;
qp->rq.wqe_cnt = roundup_pow_of_two(max(1U, cap->max_recv_wr));
qp->rq.max_gs = roundup_pow_of_two(max(1U, cap->max_recv_sge));
- qp->rq.wqe_shift = ilog2(qp->rq.max_gs * sizeof (struct mlx4_wqe_data_seg));
+ wqe_size = qp->rq.max_gs * sizeof(struct mlx4_wqe_data_seg);
+ qp->rq.wqe_shift = ilog2(max_t(u32, wqe_size, inl_recv_sz));
}
/* leave userspace return values as they were, so as not to break ABI */
@@ -632,7 +650,300 @@ static void mlx4_ib_free_qp_counter(struct mlx4_ib_dev *dev,
qp->counter_index = NULL;
}
+static int set_qp_rss(struct mlx4_ib_dev *dev, struct mlx4_ib_rss *rss_ctx,
+ struct ib_qp_init_attr *init_attr,
+ struct mlx4_ib_create_qp_rss *ucmd)
+{
+ rss_ctx->base_qpn_tbl_sz = init_attr->rwq_ind_tbl->ind_tbl[0]->wq_num |
+ (init_attr->rwq_ind_tbl->log_ind_tbl_size << 24);
+
+ if ((ucmd->rx_hash_function == MLX4_IB_RX_HASH_FUNC_TOEPLITZ) &&
+ (dev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RSS_TOP)) {
+ memcpy(rss_ctx->rss_key, ucmd->rx_hash_key,
+ MLX4_EN_RSS_KEY_SIZE);
+ } else {
+ pr_debug("RX Hash function is not supported\n");
+ return (-EOPNOTSUPP);
+ }
+
+ if ((ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_SRC_IPV4) &&
+ (ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_DST_IPV4)) {
+ rss_ctx->flags = MLX4_RSS_IPV4;
+ } else if ((ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_SRC_IPV4) ||
+ (ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_DST_IPV4)) {
+ pr_debug("RX Hash fields_mask is not supported - both IPv4 SRC and DST must be set\n");
+ return (-EOPNOTSUPP);
+ }
+
+ if ((ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_SRC_IPV6) &&
+ (ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_DST_IPV6)) {
+ rss_ctx->flags |= MLX4_RSS_IPV6;
+ } else if ((ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_SRC_IPV6) ||
+ (ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_DST_IPV6)) {
+ pr_debug("RX Hash fields_mask is not supported - both IPv6 SRC and DST must be set\n");
+ return (-EOPNOTSUPP);
+ }
+
+ if ((ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_SRC_PORT_UDP) &&
+ (ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_DST_PORT_UDP)) {
+ if (!(dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_UDP_RSS)) {
+ pr_debug("RX Hash fields_mask for UDP is not supported\n");
+ return (-EOPNOTSUPP);
+ }
+
+ if (rss_ctx->flags & MLX4_RSS_IPV4) {
+ rss_ctx->flags |= MLX4_RSS_UDP_IPV4;
+ } else if (rss_ctx->flags & MLX4_RSS_IPV6) {
+ rss_ctx->flags |= MLX4_RSS_UDP_IPV6;
+ } else {
+ pr_debug("RX Hash fields_mask is not supported - UDP must be set with IPv4 or IPv6\n");
+ return (-EOPNOTSUPP);
+ }
+ } else if ((ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_SRC_PORT_UDP) ||
+ (ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_DST_PORT_UDP)) {
+ pr_debug("RX Hash fields_mask is not supported - both UDP SRC and DST must be set\n");
+ return (-EOPNOTSUPP);
+ }
+
+ if ((ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_SRC_PORT_TCP) &&
+ (ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_DST_PORT_TCP)) {
+ if (rss_ctx->flags & MLX4_RSS_IPV4) {
+ rss_ctx->flags |= MLX4_RSS_TCP_IPV4;
+ } else if (rss_ctx->flags & MLX4_RSS_IPV6) {
+ rss_ctx->flags |= MLX4_RSS_TCP_IPV6;
+ } else {
+ pr_debug("RX Hash fields_mask is not supported - TCP must be set with IPv4 or IPv6\n");
+ return (-EOPNOTSUPP);
+ }
+
+ } else if ((ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_SRC_PORT_TCP) ||
+ (ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_DST_PORT_TCP)) {
+ pr_debug("RX Hash fields_mask is not supported - both TCP SRC and DST must be set\n");
+ return (-EOPNOTSUPP);
+ }
+
+ return 0;
+}
+
+static int create_qp_rss(struct mlx4_ib_dev *dev, struct ib_pd *ibpd,
+ struct ib_qp_init_attr *init_attr,
+ struct mlx4_ib_create_qp_rss *ucmd,
+ struct mlx4_ib_qp *qp)
+{
+ int qpn;
+ int err;
+
+ qp->mqp.usage = MLX4_RES_USAGE_USER_VERBS;
+
+ err = mlx4_qp_reserve_range(dev->dev, 1, 1, &qpn, 0, qp->mqp.usage);
+ if (err)
+ return err;
+
+ err = mlx4_qp_alloc(dev->dev, qpn, &qp->mqp);
+ if (err)
+ goto err_qpn;
+
+ mutex_init(&qp->mutex);
+
+ INIT_LIST_HEAD(&qp->gid_list);
+ INIT_LIST_HEAD(&qp->steering_rules);
+
+ qp->mlx4_ib_qp_type = MLX4_IB_QPT_RAW_PACKET;
+ qp->state = IB_QPS_RESET;
+
+ /* Set dummy send resources to be compatible with HV and PRM */
+ qp->sq_no_prefetch = 1;
+ qp->sq.wqe_cnt = 1;
+ qp->sq.wqe_shift = MLX4_IB_MIN_SQ_STRIDE;
+ qp->buf_size = qp->sq.wqe_cnt << MLX4_IB_MIN_SQ_STRIDE;
+ qp->mtt = (to_mqp(
+ (struct ib_qp *)init_attr->rwq_ind_tbl->ind_tbl[0]))->mtt;
+
+ qp->rss_ctx = kzalloc(sizeof(*qp->rss_ctx), GFP_KERNEL);
+ if (!qp->rss_ctx) {
+ err = -ENOMEM;
+ goto err_qp_alloc;
+ }
+
+ err = set_qp_rss(dev, qp->rss_ctx, init_attr, ucmd);
+ if (err)
+ goto err;
+
+ return 0;
+
+err:
+ kfree(qp->rss_ctx);
+
+err_qp_alloc:
+ mlx4_qp_remove(dev->dev, &qp->mqp);
+ mlx4_qp_free(dev->dev, &qp->mqp);
+
+err_qpn:
+ mlx4_qp_release_range(dev->dev, qpn, 1);
+ return err;
+}
+
+static struct ib_qp *_mlx4_ib_create_qp_rss(struct ib_pd *pd,
+ struct ib_qp_init_attr *init_attr,
+ struct ib_udata *udata)
+{
+ struct mlx4_ib_qp *qp;
+ struct mlx4_ib_create_qp_rss ucmd = {};
+ size_t required_cmd_sz;
+ int err;
+
+ if (!udata) {
+ pr_debug("RSS QP with NULL udata\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (udata->outlen)
+ return ERR_PTR(-EOPNOTSUPP);
+
+ required_cmd_sz = offsetof(typeof(ucmd), reserved1) +
+ sizeof(ucmd.reserved1);
+ if (udata->inlen < required_cmd_sz) {
+ pr_debug("invalid inlen\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen))) {
+ pr_debug("copy failed\n");
+ return ERR_PTR(-EFAULT);
+ }
+
+ if (memchr_inv(ucmd.reserved, 0, sizeof(ucmd.reserved)))
+ return ERR_PTR(-EOPNOTSUPP);
+
+ if (ucmd.comp_mask || ucmd.reserved1)
+ return ERR_PTR(-EOPNOTSUPP);
+
+ if (udata->inlen > sizeof(ucmd) &&
+ !ib_is_udata_cleared(udata, sizeof(ucmd),
+ udata->inlen - sizeof(ucmd))) {
+ pr_debug("inlen is not supported\n");
+ return ERR_PTR(-EOPNOTSUPP);
+ }
+
+ if (init_attr->qp_type != IB_QPT_RAW_PACKET) {
+ pr_debug("RSS QP with unsupported QP type %d\n",
+ init_attr->qp_type);
+ return ERR_PTR(-EOPNOTSUPP);
+ }
+
+ if (init_attr->create_flags) {
+ pr_debug("RSS QP doesn't support create flags\n");
+ return ERR_PTR(-EOPNOTSUPP);
+ }
+
+ if (init_attr->send_cq || init_attr->cap.max_send_wr) {
+ pr_debug("RSS QP with unsupported send attributes\n");
+ return ERR_PTR(-EOPNOTSUPP);
+ }
+
+ qp = kzalloc(sizeof(*qp), GFP_KERNEL);
+ if (!qp)
+ return ERR_PTR(-ENOMEM);
+
+ qp->pri.vid = 0xFFFF;
+ qp->alt.vid = 0xFFFF;
+
+ err = create_qp_rss(to_mdev(pd->device), pd, init_attr, &ucmd, qp);
+ if (err) {
+ kfree(qp);
+ return ERR_PTR(err);
+ }
+
+ qp->ibqp.qp_num = qp->mqp.qpn;
+
+ return &qp->ibqp;
+}
+
+/*
+ * This function allocates a WQN from a range which is consecutive and aligned
+ * to its size. In case the range is full, then it creates a new range and
+ * allocates WQN from it. The new range will be used for following allocations.
+ */
+static int mlx4_ib_alloc_wqn(struct mlx4_ib_ucontext *context,
+ struct mlx4_ib_qp *qp, int range_size, int *wqn)
+{
+ struct mlx4_ib_dev *dev = to_mdev(context->ibucontext.device);
+ struct mlx4_wqn_range *range;
+ int err = 0;
+
+ mutex_lock(&context->wqn_ranges_mutex);
+
+ range = list_first_entry_or_null(&context->wqn_ranges_list,
+ struct mlx4_wqn_range, list);
+
+ if (!range || (range->refcount == range->size) || range->dirty) {
+ range = kzalloc(sizeof(*range), GFP_KERNEL);
+ if (!range) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ err = mlx4_qp_reserve_range(dev->dev, range_size,
+ range_size, &range->base_wqn, 0,
+ qp->mqp.usage);
+ if (err) {
+ kfree(range);
+ goto out;
+ }
+
+ range->size = range_size;
+ list_add(&range->list, &context->wqn_ranges_list);
+ } else if (range_size != 1) {
+ /*
+ * Requesting a new range (>1) when last range is still open, is
+ * not valid.
+ */
+ err = -EINVAL;
+ goto out;
+ }
+
+ qp->wqn_range = range;
+
+ *wqn = range->base_wqn + range->refcount;
+
+ range->refcount++;
+
+out:
+ mutex_unlock(&context->wqn_ranges_mutex);
+
+ return err;
+}
+
+static void mlx4_ib_release_wqn(struct mlx4_ib_ucontext *context,
+ struct mlx4_ib_qp *qp, bool dirty_release)
+{
+ struct mlx4_ib_dev *dev = to_mdev(context->ibucontext.device);
+ struct mlx4_wqn_range *range;
+
+ mutex_lock(&context->wqn_ranges_mutex);
+
+ range = qp->wqn_range;
+
+ range->refcount--;
+ if (!range->refcount) {
+ mlx4_qp_release_range(dev->dev, range->base_wqn,
+ range->size);
+ list_del(&range->list);
+ kfree(range);
+ } else if (dirty_release) {
+ /*
+ * A range which one of its WQNs is destroyed, won't be able to be
+ * reused for further WQN allocations.
+ * The next created WQ will allocate a new range.
+ */
+ range->dirty = 1;
+ }
+
+ mutex_unlock(&context->wqn_ranges_mutex);
+}
+
static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
+ enum mlx4_ib_source_type src,
struct ib_qp_init_attr *init_attr,
struct ib_udata *udata, int sqpn,
struct mlx4_ib_qp **caller_qp)
@@ -645,6 +956,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
enum mlx4_ib_qp_type qp_type = (enum mlx4_ib_qp_type) init_attr->qp_type;
struct mlx4_ib_cq *mcq;
unsigned long flags;
+ int range_size = 0;
/* When tunneling special qps, we use a plain UD qp */
if (sqpn) {
@@ -719,26 +1031,70 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR)
qp->sq_signal_bits = cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE);
- err = set_rq_size(dev, &init_attr->cap, !!pd->uobject, qp_has_rq(init_attr), qp);
- if (err)
- goto err;
if (pd->uobject) {
- struct mlx4_ib_create_qp ucmd;
+ union {
+ struct mlx4_ib_create_qp qp;
+ struct mlx4_ib_create_wq wq;
+ } ucmd;
+ size_t copy_len;
- if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) {
+ copy_len = (src == MLX4_IB_QP_SRC) ?
+ sizeof(struct mlx4_ib_create_qp) :
+ min(sizeof(struct mlx4_ib_create_wq), udata->inlen);
+
+ if (ib_copy_from_udata(&ucmd, udata, copy_len)) {
err = -EFAULT;
goto err;
}
- qp->sq_no_prefetch = ucmd.sq_no_prefetch;
+ if (src == MLX4_IB_RWQ_SRC) {
+ if (ucmd.wq.comp_mask || ucmd.wq.reserved[0] ||
+ ucmd.wq.reserved[1] || ucmd.wq.reserved[2]) {
+ pr_debug("user command isn't supported\n");
+ err = -EOPNOTSUPP;
+ goto err;
+ }
+
+ if (ucmd.wq.log_range_size >
+ ilog2(dev->dev->caps.max_rss_tbl_sz)) {
+ pr_debug("WQN range size must be equal or smaller than %d\n",
+ dev->dev->caps.max_rss_tbl_sz);
+ err = -EOPNOTSUPP;
+ goto err;
+ }
+ range_size = 1 << ucmd.wq.log_range_size;
+ } else {
+ qp->inl_recv_sz = ucmd.qp.inl_recv_sz;
+ }
- err = set_user_sq_size(dev, qp, &ucmd);
+ err = set_rq_size(dev, &init_attr->cap, !!pd->uobject,
+ qp_has_rq(init_attr), qp, qp->inl_recv_sz);
if (err)
goto err;
- qp->umem = ib_umem_get(pd->uobject->context, ucmd.buf_addr,
- qp->buf_size, 0, 0);
+ if (src == MLX4_IB_QP_SRC) {
+ qp->sq_no_prefetch = ucmd.qp.sq_no_prefetch;
+
+ err = set_user_sq_size(dev, qp,
+ (struct mlx4_ib_create_qp *)
+ &ucmd);
+ if (err)
+ goto err;
+ } else {
+ qp->sq_no_prefetch = 1;
+ qp->sq.wqe_cnt = 1;
+ qp->sq.wqe_shift = MLX4_IB_MIN_SQ_STRIDE;
+ /* Allocated buffer expects to have at least that SQ
+ * size.
+ */
+ qp->buf_size = (qp->rq.wqe_cnt << qp->rq.wqe_shift) +
+ (qp->sq.wqe_cnt << qp->sq.wqe_shift);
+ }
+
+ qp->umem = ib_umem_get(pd->uobject->context,
+ (src == MLX4_IB_QP_SRC) ? ucmd.qp.buf_addr :
+ ucmd.wq.buf_addr, qp->buf_size, 0, 0);
if (IS_ERR(qp->umem)) {
err = PTR_ERR(qp->umem);
goto err;
@@ -755,11 +1111,18 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
if (qp_has_rq(init_attr)) {
err = mlx4_ib_db_map_user(to_mucontext(pd->uobject->context),
- ucmd.db_addr, &qp->db);
+ (src == MLX4_IB_QP_SRC) ? ucmd.qp.db_addr :
+ ucmd.wq.db_addr, &qp->db);
if (err)
goto err_mtt;
}
+ qp->mqp.usage = MLX4_RES_USAGE_USER_VERBS;
} else {
+ err = set_rq_size(dev, &init_attr->cap, !!pd->uobject,
+ qp_has_rq(init_attr), qp, 0);
+ if (err)
+ goto err;
+
qp->sq_no_prefetch = 0;
if (init_attr->create_flags & IB_QP_CREATE_IPOIB_UD_LSO)
@@ -812,20 +1175,15 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
if (err)
goto err_mtt;
- qp->sq.wrid = kmalloc_array(qp->sq.wqe_cnt, sizeof(u64),
- GFP_KERNEL | __GFP_NOWARN);
- if (!qp->sq.wrid)
- qp->sq.wrid = __vmalloc(qp->sq.wqe_cnt * sizeof(u64),
- GFP_KERNEL, PAGE_KERNEL);
- qp->rq.wrid = kmalloc_array(qp->rq.wqe_cnt, sizeof(u64),
- GFP_KERNEL | __GFP_NOWARN);
- if (!qp->rq.wrid)
- qp->rq.wrid = __vmalloc(qp->rq.wqe_cnt * sizeof(u64),
- GFP_KERNEL, PAGE_KERNEL);
+ qp->sq.wrid = kvmalloc_array(qp->sq.wqe_cnt,
+ sizeof(u64), GFP_KERNEL);
+ qp->rq.wrid = kvmalloc_array(qp->rq.wqe_cnt,
+ sizeof(u64), GFP_KERNEL);
if (!qp->sq.wrid || !qp->rq.wrid) {
err = -ENOMEM;
goto err_wrid;
}
+ qp->mqp.usage = MLX4_RES_USAGE_DRIVER;
}
if (sqpn) {
@@ -836,6 +1194,11 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
goto err_wrid;
}
}
+ } else if (src == MLX4_IB_RWQ_SRC) {
+ err = mlx4_ib_alloc_wqn(to_mucontext(pd->uobject->context), qp,
+ range_size, &qpn);
+ if (err)
+ goto err_wrid;
} else {
/* Raw packet QPNs may not have bits 6,7 set in their qp_num;
* otherwise, the WQE BlueFlame setup flow wrongly causes
@@ -845,13 +1208,14 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
(init_attr->cap.max_send_wr ?
MLX4_RESERVE_ETH_BF_QP : 0) |
(init_attr->cap.max_recv_wr ?
- MLX4_RESERVE_A0_QP : 0));
+ MLX4_RESERVE_A0_QP : 0),
+ qp->mqp.usage);
else
if (qp->flags & MLX4_IB_QP_NETIF)
err = mlx4_ib_steer_qp_alloc(dev, 1, &qpn);
else
err = mlx4_qp_reserve_range(dev->dev, 1, 1,
- &qpn, 0);
+ &qpn, 0, qp->mqp.usage);
if (err)
goto err_proxy;
}
@@ -873,7 +1237,9 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
*/
qp->doorbell_qpn = swab32(qp->mqp.qpn << 8);
- qp->mqp.event = mlx4_ib_qp_event;
+ qp->mqp.event = (src == MLX4_IB_QP_SRC) ? mlx4_ib_qp_event :
+ mlx4_ib_wq_event;
+
if (!*caller_qp)
*caller_qp = qp;
@@ -900,6 +1266,9 @@ err_qpn:
if (!sqpn) {
if (qp->flags & MLX4_IB_QP_NETIF)
mlx4_ib_steer_qp_free(dev, qpn, 1);
+ else if (src == MLX4_IB_RWQ_SRC)
+ mlx4_ib_release_wqn(to_mucontext(pd->uobject->context),
+ qp, 0);
else
mlx4_qp_release_range(dev->dev, qpn, 1);
}
@@ -998,7 +1367,7 @@ static struct mlx4_ib_pd *get_pd(struct mlx4_ib_qp *qp)
return to_mpd(qp->ibqp.pd);
}
-static void get_cqs(struct mlx4_ib_qp *qp,
+static void get_cqs(struct mlx4_ib_qp *qp, enum mlx4_ib_source_type src,
struct mlx4_ib_cq **send_cq, struct mlx4_ib_cq **recv_cq)
{
switch (qp->ibqp.qp_type) {
@@ -1011,14 +1380,46 @@ static void get_cqs(struct mlx4_ib_qp *qp,
*recv_cq = *send_cq;
break;
default:
- *send_cq = to_mcq(qp->ibqp.send_cq);
- *recv_cq = to_mcq(qp->ibqp.recv_cq);
+ *recv_cq = (src == MLX4_IB_QP_SRC) ? to_mcq(qp->ibqp.recv_cq) :
+ to_mcq(qp->ibwq.cq);
+ *send_cq = (src == MLX4_IB_QP_SRC) ? to_mcq(qp->ibqp.send_cq) :
+ *recv_cq;
break;
}
}
+static void destroy_qp_rss(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp)
+{
+ if (qp->state != IB_QPS_RESET) {
+ int i;
+
+ for (i = 0; i < (1 << qp->ibqp.rwq_ind_tbl->log_ind_tbl_size);
+ i++) {
+ struct ib_wq *ibwq = qp->ibqp.rwq_ind_tbl->ind_tbl[i];
+ struct mlx4_ib_qp *wq = to_mqp((struct ib_qp *)ibwq);
+
+ mutex_lock(&wq->mutex);
+
+ wq->rss_usecnt--;
+
+ mutex_unlock(&wq->mutex);
+ }
+
+ if (mlx4_qp_modify(dev->dev, NULL, to_mlx4_state(qp->state),
+ MLX4_QP_STATE_RST, NULL, 0, 0, &qp->mqp))
+ pr_warn("modify QP %06x to RESET failed.\n",
+ qp->mqp.qpn);
+ }
+
+ mlx4_qp_remove(dev->dev, &qp->mqp);
+ mlx4_qp_free(dev->dev, &qp->mqp);
+ mlx4_qp_release_range(dev->dev, qp->mqp.qpn, 1);
+ del_gid_entries(qp);
+ kfree(qp->rss_ctx);
+}
+
static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp,
- int is_user)
+ enum mlx4_ib_source_type src, int is_user)
{
struct mlx4_ib_cq *send_cq, *recv_cq;
unsigned long flags;
@@ -1051,7 +1452,7 @@ static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp,
}
}
- get_cqs(qp, &send_cq, &recv_cq);
+ get_cqs(qp, src, &send_cq, &recv_cq);
spin_lock_irqsave(&dev->reset_flow_resource_lock, flags);
mlx4_ib_lock_cqs(send_cq, recv_cq);
@@ -1077,6 +1478,9 @@ static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp,
if (!is_sqp(dev, qp) && !is_tunnel_qp(dev, qp)) {
if (qp->flags & MLX4_IB_QP_NETIF)
mlx4_ib_steer_qp_free(dev, qp->mqp.qpn, 1);
+ else if (src == MLX4_IB_RWQ_SRC)
+ mlx4_ib_release_wqn(to_mucontext(
+ qp->ibwq.uobject->context), qp, 1);
else
mlx4_qp_release_range(dev->dev, qp->mqp.qpn, 1);
}
@@ -1084,9 +1488,12 @@ static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp,
mlx4_mtt_cleanup(dev->dev, &qp->mtt);
if (is_user) {
- if (qp->rq.wqe_cnt)
- mlx4_ib_db_unmap_user(to_mucontext(qp->ibqp.uobject->context),
- &qp->db);
+ if (qp->rq.wqe_cnt) {
+ struct mlx4_ib_ucontext *mcontext = !src ?
+ to_mucontext(qp->ibqp.uobject->context) :
+ to_mucontext(qp->ibwq.uobject->context);
+ mlx4_ib_db_unmap_user(mcontext, &qp->db);
+ }
ib_umem_release(qp->umem);
} else {
kvfree(qp->sq.wrid);
@@ -1128,6 +1535,9 @@ static struct ib_qp *_mlx4_ib_create_qp(struct ib_pd *pd,
int sup_u_create_flags = MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK;
u16 xrcdn = 0;
+ if (init_attr->rwq_ind_tbl)
+ return _mlx4_ib_create_qp_rss(pd, init_attr, udata);
+
/*
* We only support LSO, vendor flag1, and multicast loopback blocking,
* and only for kernel UD QPs.
@@ -1182,8 +1592,8 @@ static struct ib_qp *_mlx4_ib_create_qp(struct ib_pd *pd,
/* fall through */
case IB_QPT_UD:
{
- err = create_qp_common(to_mdev(pd->device), pd, init_attr,
- udata, 0, &qp);
+ err = create_qp_common(to_mdev(pd->device), pd, MLX4_IB_QP_SRC,
+ init_attr, udata, 0, &qp);
if (err) {
kfree(qp);
return ERR_PTR(err);
@@ -1203,7 +1613,9 @@ static struct ib_qp *_mlx4_ib_create_qp(struct ib_pd *pd,
if (udata)
return ERR_PTR(-EINVAL);
if (init_attr->create_flags & MLX4_IB_QP_CREATE_ROCE_V2_GSI) {
- int res = mlx4_qp_reserve_range(to_mdev(pd->device)->dev, 1, 1, &sqpn, 0);
+ int res = mlx4_qp_reserve_range(to_mdev(pd->device)->dev,
+ 1, 1, &sqpn, 0,
+ MLX4_RES_USAGE_DRIVER);
if (res)
return ERR_PTR(res);
@@ -1211,8 +1623,8 @@ static struct ib_qp *_mlx4_ib_create_qp(struct ib_pd *pd,
sqpn = get_sqp_num(to_mdev(pd->device), init_attr);
}
- err = create_qp_common(to_mdev(pd->device), pd, init_attr, udata,
- sqpn, &qp);
+ err = create_qp_common(to_mdev(pd->device), pd, MLX4_IB_QP_SRC,
+ init_attr, udata, sqpn, &qp);
if (err)
return ERR_PTR(err);
@@ -1267,7 +1679,6 @@ static int _mlx4_ib_destroy_qp(struct ib_qp *qp)
{
struct mlx4_ib_dev *dev = to_mdev(qp->device);
struct mlx4_ib_qp *mqp = to_mqp(qp);
- struct mlx4_ib_pd *pd;
if (is_qp0(dev, mqp))
mlx4_CLOSE_PORT(dev->dev, mqp->port);
@@ -1282,8 +1693,14 @@ static int _mlx4_ib_destroy_qp(struct ib_qp *qp)
if (mqp->counter_index)
mlx4_ib_free_qp_counter(dev, mqp);
- pd = get_pd(mqp);
- destroy_qp_common(dev, mqp, !!pd->ibpd.uobject);
+ if (qp->rwq_ind_tbl) {
+ destroy_qp_rss(dev, mqp);
+ } else {
+ struct mlx4_ib_pd *pd;
+
+ pd = get_pd(mqp);
+ destroy_qp_common(dev, mqp, MLX4_IB_QP_SRC, !!pd->ibpd.uobject);
+ }
if (is_sqp(dev, mqp))
kfree(to_msqp(mqp));
@@ -1566,7 +1983,7 @@ static int create_qp_lb_counter(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp)
!(dev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_LB_SRC_CHK))
return 0;
- err = mlx4_counter_alloc(dev->dev, &tmp_idx);
+ err = mlx4_counter_alloc(dev->dev, &tmp_idx, MLX4_RES_USAGE_DRIVER);
if (err)
return err;
@@ -1606,12 +2023,119 @@ static u8 gid_type_to_qpc(enum ib_gid_type gid_type)
}
}
-static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
+/*
+ * Go over all RSS QP's childes (WQs) and apply their HW state according to
+ * their logic state if the RSS QP is the first RSS QP associated for the WQ.
+ */
+static int bringup_rss_rwqs(struct ib_rwq_ind_table *ind_tbl, u8 port_num)
+{
+ int err = 0;
+ int i;
+
+ for (i = 0; i < (1 << ind_tbl->log_ind_tbl_size); i++) {
+ struct ib_wq *ibwq = ind_tbl->ind_tbl[i];
+ struct mlx4_ib_qp *wq = to_mqp((struct ib_qp *)ibwq);
+
+ mutex_lock(&wq->mutex);
+
+ /* Mlx4_ib restrictions:
+ * WQ's is associated to a port according to the RSS QP it is
+ * associates to.
+ * In case the WQ is associated to a different port by another
+ * RSS QP, return a failure.
+ */
+ if ((wq->rss_usecnt > 0) && (wq->port != port_num)) {
+ err = -EINVAL;
+ mutex_unlock(&wq->mutex);
+ break;
+ }
+ wq->port = port_num;
+ if ((wq->rss_usecnt == 0) && (ibwq->state == IB_WQS_RDY)) {
+ err = _mlx4_ib_modify_wq(ibwq, IB_WQS_RDY);
+ if (err) {
+ mutex_unlock(&wq->mutex);
+ break;
+ }
+ }
+ wq->rss_usecnt++;
+
+ mutex_unlock(&wq->mutex);
+ }
+
+ if (i && err) {
+ int j;
+
+ for (j = (i - 1); j >= 0; j--) {
+ struct ib_wq *ibwq = ind_tbl->ind_tbl[j];
+ struct mlx4_ib_qp *wq = to_mqp((struct ib_qp *)ibwq);
+
+ mutex_lock(&wq->mutex);
+
+ if ((wq->rss_usecnt == 1) &&
+ (ibwq->state == IB_WQS_RDY))
+ if (_mlx4_ib_modify_wq(ibwq, IB_WQS_RESET))
+ pr_warn("failed to reverse WQN=0x%06x\n",
+ ibwq->wq_num);
+ wq->rss_usecnt--;
+
+ mutex_unlock(&wq->mutex);
+ }
+ }
+
+ return err;
+}
+
+static void bring_down_rss_rwqs(struct ib_rwq_ind_table *ind_tbl)
+{
+ int i;
+
+ for (i = 0; i < (1 << ind_tbl->log_ind_tbl_size); i++) {
+ struct ib_wq *ibwq = ind_tbl->ind_tbl[i];
+ struct mlx4_ib_qp *wq = to_mqp((struct ib_qp *)ibwq);
+
+ mutex_lock(&wq->mutex);
+
+ if ((wq->rss_usecnt == 1) && (ibwq->state == IB_WQS_RDY))
+ if (_mlx4_ib_modify_wq(ibwq, IB_WQS_RESET))
+ pr_warn("failed to reverse WQN=%x\n",
+ ibwq->wq_num);
+ wq->rss_usecnt--;
+
+ mutex_unlock(&wq->mutex);
+ }
+}
+
+static void fill_qp_rss_context(struct mlx4_qp_context *context,
+ struct mlx4_ib_qp *qp)
+{
+ struct mlx4_rss_context *rss_context;
+
+ rss_context = (void *)context + offsetof(struct mlx4_qp_context,
+ pri_path) + MLX4_RSS_OFFSET_IN_QPC_PRI_PATH;
+
+ rss_context->base_qpn = cpu_to_be32(qp->rss_ctx->base_qpn_tbl_sz);
+ rss_context->default_qpn =
+ cpu_to_be32(qp->rss_ctx->base_qpn_tbl_sz & 0xffffff);
+ if (qp->rss_ctx->flags & (MLX4_RSS_UDP_IPV4 | MLX4_RSS_UDP_IPV6))
+ rss_context->base_qpn_udp = rss_context->default_qpn;
+ rss_context->flags = qp->rss_ctx->flags;
+ /* Currently support just toeplitz */
+ rss_context->hash_fn = MLX4_RSS_HASH_TOP;
+
+ memcpy(rss_context->rss_key, qp->rss_ctx->rss_key,
+ MLX4_EN_RSS_KEY_SIZE);
+}
+
+static int __mlx4_ib_modify_qp(void *src, enum mlx4_ib_source_type src_type,
const struct ib_qp_attr *attr, int attr_mask,
enum ib_qp_state cur_state, enum ib_qp_state new_state)
{
- struct mlx4_ib_dev *dev = to_mdev(ibqp->device);
- struct mlx4_ib_qp *qp = to_mqp(ibqp);
+ struct ib_uobject *ibuobject;
+ struct ib_srq *ibsrq;
+ struct ib_rwq_ind_table *rwq_ind_tbl;
+ enum ib_qp_type qp_type;
+ struct mlx4_ib_dev *dev;
+ struct mlx4_ib_qp *qp;
struct mlx4_ib_pd *pd;
struct mlx4_ib_cq *send_cq, *recv_cq;
struct mlx4_qp_context *context;
@@ -1621,6 +2145,30 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
int err = -EINVAL;
int counter_index;
+ if (src_type == MLX4_IB_RWQ_SRC) {
+ struct ib_wq *ibwq;
+
+ ibwq = (struct ib_wq *)src;
+ ibuobject = ibwq->uobject;
+ ibsrq = NULL;
+ rwq_ind_tbl = NULL;
+ qp_type = IB_QPT_RAW_PACKET;
+ qp = to_mqp((struct ib_qp *)ibwq);
+ dev = to_mdev(ibwq->device);
+ pd = to_mpd(ibwq->pd);
+ } else {
+ struct ib_qp *ibqp;
+
+ ibqp = (struct ib_qp *)src;
+ ibuobject = ibqp->uobject;
+ ibsrq = ibqp->srq;
+ rwq_ind_tbl = ibqp->rwq_ind_tbl;
+ qp_type = ibqp->qp_type;
+ qp = to_mqp(ibqp);
+ dev = to_mdev(ibqp->device);
+ pd = get_pd(qp);
+ }
+
/* APM is not supported under RoCE */
if (attr_mask & IB_QP_ALT_PATH &&
rdma_port_get_link_layer(&dev->ib_dev, qp->port) ==
@@ -1634,6 +2182,11 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
context->flags = cpu_to_be32((to_mlx4_state(new_state) << 28) |
(to_mlx4_st(dev, qp->mlx4_ib_qp_type) << 16));
+ if (rwq_ind_tbl) {
+ fill_qp_rss_context(context, qp);
+ context->flags |= cpu_to_be32(1 << MLX4_RSS_QPC_FLAG_OFFSET);
+ }
+
if (!(attr_mask & IB_QP_PATH_MIG_STATE))
context->flags |= cpu_to_be32(MLX4_QP_PM_MIGRATED << 11);
else {
@@ -1651,11 +2204,14 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
}
}
- if (ibqp->qp_type == IB_QPT_GSI || ibqp->qp_type == IB_QPT_SMI)
+ if (qp->inl_recv_sz)
+ context->param3 |= cpu_to_be32(1 << 25);
+
+ if (qp_type == IB_QPT_GSI || qp_type == IB_QPT_SMI)
context->mtu_msgmax = (IB_MTU_4096 << 5) | 11;
- else if (ibqp->qp_type == IB_QPT_RAW_PACKET)
+ else if (qp_type == IB_QPT_RAW_PACKET)
context->mtu_msgmax = (MLX4_RAW_QP_MTU << 5) | MLX4_RAW_QP_MSGMAX;
- else if (ibqp->qp_type == IB_QPT_UD) {
+ else if (qp_type == IB_QPT_UD) {
if (qp->flags & MLX4_IB_QP_LSO)
context->mtu_msgmax = (IB_MTU_4096 << 5) |
ilog2(dev->dev->caps.max_gso_sz);
@@ -1671,9 +2227,11 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
ilog2(dev->dev->caps.max_msg_sz);
}
- if (qp->rq.wqe_cnt)
- context->rq_size_stride = ilog2(qp->rq.wqe_cnt) << 3;
- context->rq_size_stride |= qp->rq.wqe_shift - 4;
+ if (!rwq_ind_tbl) { /* PRM RSS receive side should be left zeros */
+ if (qp->rq.wqe_cnt)
+ context->rq_size_stride = ilog2(qp->rq.wqe_cnt) << 3;
+ context->rq_size_stride |= qp->rq.wqe_shift - 4;
+ }
if (qp->sq.wqe_cnt)
context->sq_size_stride = ilog2(qp->sq.wqe_cnt) << 3;
@@ -1685,14 +2243,15 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
context->sq_size_stride |= !!qp->sq_no_prefetch << 7;
context->xrcd = cpu_to_be32((u32) qp->xrcdn);
- if (ibqp->qp_type == IB_QPT_RAW_PACKET)
+ if (qp_type == IB_QPT_RAW_PACKET)
context->param3 |= cpu_to_be32(1 << 30);
}
- if (qp->ibqp.uobject)
+ if (ibuobject)
context->usr_page = cpu_to_be32(
mlx4_to_hw_uar_index(dev->dev,
- to_mucontext(ibqp->uobject->context)->uar.index));
+ to_mucontext(ibuobject->context)
+ ->uar.index));
else
context->usr_page = cpu_to_be32(
mlx4_to_hw_uar_index(dev->dev, dev->priv_uar.index));
@@ -1736,7 +2295,7 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
steer_qp = 1;
}
- if (ibqp->qp_type == IB_QPT_GSI) {
+ if (qp_type == IB_QPT_GSI) {
enum ib_gid_type gid_type = qp->flags & MLX4_IB_ROCE_V2_GSI_QP ?
IB_GID_TYPE_ROCE_UDP_ENCAP : IB_GID_TYPE_ROCE;
u8 qpc_roce_mode = gid_type_to_qpc(gid_type);
@@ -1753,7 +2312,7 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
}
if (attr_mask & IB_QP_AV) {
- u8 port_num = mlx4_is_bonded(to_mdev(ibqp->device)->dev) ? 1 :
+ u8 port_num = mlx4_is_bonded(dev->dev) ? 1 :
attr_mask & IB_QP_PORT ? attr->port_num : qp->port;
union ib_gid gid;
struct ib_gid_attr gid_attr = {.gid_type = IB_GID_TYPE_IB};
@@ -1768,7 +2327,7 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
int index =
rdma_ah_read_grh(&attr->ah_attr)->sgid_index;
- status = ib_get_cached_gid(ibqp->device, port_num,
+ status = ib_get_cached_gid(&dev->ib_dev, port_num,
index, &gid, &gid_attr);
if (!status && !memcmp(&gid, &zgid, sizeof(gid)))
status = -ENOENT;
@@ -1825,15 +2384,20 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
optpar |= MLX4_QP_OPTPAR_ALT_ADDR_PATH;
}
- pd = get_pd(qp);
- get_cqs(qp, &send_cq, &recv_cq);
- context->pd = cpu_to_be32(pd->pdn);
+ context->pd = cpu_to_be32(pd->pdn);
+
+ if (!rwq_ind_tbl) {
+ get_cqs(qp, src_type, &send_cq, &recv_cq);
+ } else { /* Set dummy CQs to be compatible with HV and PRM */
+ send_cq = to_mcq(rwq_ind_tbl->ind_tbl[0]->cq);
+ recv_cq = send_cq;
+ }
context->cqn_send = cpu_to_be32(send_cq->mcq.cqn);
context->cqn_recv = cpu_to_be32(recv_cq->mcq.cqn);
context->params1 = cpu_to_be32(MLX4_IB_ACK_REQ_FREQ << 28);
/* Set "fast registration enabled" for all kernel QPs */
- if (!qp->ibqp.uobject)
+ if (!ibuobject)
context->params1 |= cpu_to_be32(1 << 11);
if (attr_mask & IB_QP_RNR_RETRY) {
@@ -1868,7 +2432,7 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
optpar |= MLX4_QP_OPTPAR_RWE | MLX4_QP_OPTPAR_RRE | MLX4_QP_OPTPAR_RAE;
}
- if (ibqp->srq)
+ if (ibsrq)
context->params2 |= cpu_to_be32(MLX4_QP_BIT_RIC);
if (attr_mask & IB_QP_MIN_RNR_TIMER) {
@@ -1899,17 +2463,19 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
optpar |= MLX4_QP_OPTPAR_Q_KEY;
}
- if (ibqp->srq)
- context->srqn = cpu_to_be32(1 << 24 | to_msrq(ibqp->srq)->msrq.srqn);
+ if (ibsrq)
+ context->srqn = cpu_to_be32(1 << 24 |
+ to_msrq(ibsrq)->msrq.srqn);
- if (qp->rq.wqe_cnt && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT)
+ if (qp->rq.wqe_cnt &&
+ cur_state == IB_QPS_RESET &&
+ new_state == IB_QPS_INIT)
context->db_rec_addr = cpu_to_be64(qp->db.dma);
if (cur_state == IB_QPS_INIT &&
new_state == IB_QPS_RTR &&
- (ibqp->qp_type == IB_QPT_GSI || ibqp->qp_type == IB_QPT_SMI ||
- ibqp->qp_type == IB_QPT_UD ||
- ibqp->qp_type == IB_QPT_RAW_PACKET)) {
+ (qp_type == IB_QPT_GSI || qp_type == IB_QPT_SMI ||
+ qp_type == IB_QPT_UD || qp_type == IB_QPT_RAW_PACKET)) {
context->pri_path.sched_queue = (qp->port - 1) << 6;
if (qp->mlx4_ib_qp_type == MLX4_IB_QPT_SMI ||
qp->mlx4_ib_qp_type &
@@ -1942,7 +2508,7 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
}
}
- if (qp->ibqp.qp_type == IB_QPT_RAW_PACKET) {
+ if (qp_type == IB_QPT_RAW_PACKET) {
context->pri_path.ackto = (context->pri_path.ackto & 0xf8) |
MLX4_IB_LINK_TYPE_ETH;
if (dev->dev->caps.tunnel_offload_mode == MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) {
@@ -1952,7 +2518,7 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
}
}
- if (ibqp->qp_type == IB_QPT_UD && (new_state == IB_QPS_RTR)) {
+ if (qp_type == IB_QPT_UD && (new_state == IB_QPS_RTR)) {
int is_eth = rdma_port_get_link_layer(
&dev->ib_dev, qp->port) ==
IB_LINK_LAYER_ETHERNET;
@@ -1962,14 +2528,15 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
}
}
-
if (cur_state == IB_QPS_RTS && new_state == IB_QPS_SQD &&
attr_mask & IB_QP_EN_SQD_ASYNC_NOTIFY && attr->en_sqd_async_notify)
sqd_event = 1;
else
sqd_event = 0;
- if (!ibqp->uobject && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT)
+ if (!ibuobject &&
+ cur_state == IB_QPS_RESET &&
+ new_state == IB_QPS_INIT)
context->rlkey_roce_mode |= (1 << 4);
/*
@@ -1978,7 +2545,9 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
* headroom is stamped so that the hardware doesn't start
* processing stale work requests.
*/
- if (!ibqp->uobject && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
+ if (!ibuobject &&
+ cur_state == IB_QPS_RESET &&
+ new_state == IB_QPS_INIT) {
struct mlx4_wqe_ctrl_seg *ctrl;
int i;
@@ -2035,9 +2604,9 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
* entries and reinitialize the QP.
*/
if (new_state == IB_QPS_RESET) {
- if (!ibqp->uobject) {
+ if (!ibuobject) {
mlx4_ib_cq_clean(recv_cq, qp->mqp.qpn,
- ibqp->srq ? to_msrq(ibqp->srq) : NULL);
+ ibsrq ? to_msrq(ibsrq) : NULL);
if (send_cq != recv_cq)
mlx4_ib_cq_clean(send_cq, qp->mqp.qpn, NULL);
@@ -2148,22 +2717,25 @@ out:
return err;
}
+enum {
+ MLX4_IB_MODIFY_QP_RSS_SUP_ATTR_MSK = (IB_QP_STATE |
+ IB_QP_PORT),
+};
+
static int _mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
int attr_mask, struct ib_udata *udata)
{
+ enum rdma_link_layer ll = IB_LINK_LAYER_UNSPECIFIED;
struct mlx4_ib_dev *dev = to_mdev(ibqp->device);
struct mlx4_ib_qp *qp = to_mqp(ibqp);
enum ib_qp_state cur_state, new_state;
int err = -EINVAL;
- int ll;
mutex_lock(&qp->mutex);
cur_state = attr_mask & IB_QP_CUR_STATE ? attr->cur_qp_state : qp->state;
new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state;
- if (cur_state == new_state && cur_state == IB_QPS_RESET) {
- ll = IB_LINK_LAYER_UNSPECIFIED;
- } else {
+ if (cur_state != new_state || cur_state != IB_QPS_RESET) {
int port = attr_mask & IB_QP_PORT ? attr->port_num : qp->port;
ll = rdma_port_get_link_layer(&dev->ib_dev, port);
}
@@ -2178,6 +2750,27 @@ static int _mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
goto out;
}
+ if (ibqp->rwq_ind_tbl) {
+ if (!(((cur_state == IB_QPS_RESET) &&
+ (new_state == IB_QPS_INIT)) ||
+ ((cur_state == IB_QPS_INIT) &&
+ (new_state == IB_QPS_RTR)))) {
+ pr_debug("qpn 0x%x: RSS QP unsupported transition %d to %d\n",
+ ibqp->qp_num, cur_state, new_state);
+
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if (attr_mask & ~MLX4_IB_MODIFY_QP_RSS_SUP_ATTR_MSK) {
+ pr_debug("qpn 0x%x: RSS QP unsupported attribute mask 0x%x for transition %d to %d\n",
+ ibqp->qp_num, attr_mask, cur_state, new_state);
+
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+ }
+
if (mlx4_is_bonded(dev->dev) && (attr_mask & IB_QP_PORT)) {
if ((cur_state == IB_QPS_RESET) && (new_state == IB_QPS_INIT)) {
if ((ibqp->qp_type == IB_QPT_RC) ||
@@ -2242,7 +2835,17 @@ static int _mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
goto out;
}
- err = __mlx4_ib_modify_qp(ibqp, attr, attr_mask, cur_state, new_state);
+ if (ibqp->rwq_ind_tbl && (new_state == IB_QPS_INIT)) {
+ err = bringup_rss_rwqs(ibqp->rwq_ind_tbl, attr->port_num);
+ if (err)
+ goto out;
+ }
+
+ err = __mlx4_ib_modify_qp(ibqp, MLX4_IB_QP_SRC, attr, attr_mask,
+ cur_state, new_state);
+
+ if (ibqp->rwq_ind_tbl && err)
+ bring_down_rss_rwqs(ibqp->rwq_ind_tbl);
if (mlx4_is_bonded(dev->dev) && (attr_mask & IB_QP_PORT))
attr->port_num = 1;
@@ -3432,6 +4035,9 @@ int mlx4_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr
int mlx4_state;
int err = 0;
+ if (ibqp->rwq_ind_tbl)
+ return -EOPNOTSUPP;
+
mutex_lock(&qp->mutex);
if (qp->state == IB_QPS_RESET) {
@@ -3527,3 +4133,285 @@ out:
return err;
}
+struct ib_wq *mlx4_ib_create_wq(struct ib_pd *pd,
+ struct ib_wq_init_attr *init_attr,
+ struct ib_udata *udata)
+{
+ struct mlx4_ib_dev *dev;
+ struct ib_qp_init_attr ib_qp_init_attr;
+ struct mlx4_ib_qp *qp;
+ struct mlx4_ib_create_wq ucmd;
+ int err, required_cmd_sz;
+
+ if (!(udata && pd->uobject))
+ return ERR_PTR(-EINVAL);
+
+ required_cmd_sz = offsetof(typeof(ucmd), comp_mask) +
+ sizeof(ucmd.comp_mask);
+ if (udata->inlen < required_cmd_sz) {
+ pr_debug("invalid inlen\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (udata->inlen > sizeof(ucmd) &&
+ !ib_is_udata_cleared(udata, sizeof(ucmd),
+ udata->inlen - sizeof(ucmd))) {
+ pr_debug("inlen is not supported\n");
+ return ERR_PTR(-EOPNOTSUPP);
+ }
+
+ if (udata->outlen)
+ return ERR_PTR(-EOPNOTSUPP);
+
+ dev = to_mdev(pd->device);
+
+ if (init_attr->wq_type != IB_WQT_RQ) {
+ pr_debug("unsupported wq type %d\n", init_attr->wq_type);
+ return ERR_PTR(-EOPNOTSUPP);
+ }
+
+ if (init_attr->create_flags) {
+ pr_debug("unsupported create_flags %u\n",
+ init_attr->create_flags);
+ return ERR_PTR(-EOPNOTSUPP);
+ }
+
+ qp = kzalloc(sizeof(*qp), GFP_KERNEL);
+ if (!qp)
+ return ERR_PTR(-ENOMEM);
+
+ qp->pri.vid = 0xFFFF;
+ qp->alt.vid = 0xFFFF;
+
+ memset(&ib_qp_init_attr, 0, sizeof(ib_qp_init_attr));
+ ib_qp_init_attr.qp_context = init_attr->wq_context;
+ ib_qp_init_attr.qp_type = IB_QPT_RAW_PACKET;
+ ib_qp_init_attr.cap.max_recv_wr = init_attr->max_wr;
+ ib_qp_init_attr.cap.max_recv_sge = init_attr->max_sge;
+ ib_qp_init_attr.recv_cq = init_attr->cq;
+ ib_qp_init_attr.send_cq = ib_qp_init_attr.recv_cq; /* Dummy CQ */
+
+ err = create_qp_common(dev, pd, MLX4_IB_RWQ_SRC, &ib_qp_init_attr,
+ udata, 0, &qp);
+ if (err) {
+ kfree(qp);
+ return ERR_PTR(err);
+ }
+
+ qp->ibwq.event_handler = init_attr->event_handler;
+ qp->ibwq.wq_num = qp->mqp.qpn;
+ qp->ibwq.state = IB_WQS_RESET;
+
+ return &qp->ibwq;
+}
+
+static int ib_wq2qp_state(enum ib_wq_state state)
+{
+ switch (state) {
+ case IB_WQS_RESET:
+ return IB_QPS_RESET;
+ case IB_WQS_RDY:
+ return IB_QPS_RTR;
+ default:
+ return IB_QPS_ERR;
+ }
+}
+
+static int _mlx4_ib_modify_wq(struct ib_wq *ibwq, enum ib_wq_state new_state)
+{
+ struct mlx4_ib_qp *qp = to_mqp((struct ib_qp *)ibwq);
+ enum ib_qp_state qp_cur_state;
+ enum ib_qp_state qp_new_state;
+ int attr_mask;
+ int err;
+
+ /* ib_qp.state represents the WQ HW state while ib_wq.state represents
+ * the WQ logic state.
+ */
+ qp_cur_state = qp->state;
+ qp_new_state = ib_wq2qp_state(new_state);
+
+ if (ib_wq2qp_state(new_state) == qp_cur_state)
+ return 0;
+
+ if (new_state == IB_WQS_RDY) {
+ struct ib_qp_attr attr = {};
+
+ attr.port_num = qp->port;
+ attr_mask = IB_QP_PORT;
+
+ err = __mlx4_ib_modify_qp(ibwq, MLX4_IB_RWQ_SRC, &attr,
+ attr_mask, IB_QPS_RESET, IB_QPS_INIT);
+ if (err) {
+ pr_debug("WQN=0x%06x failed to apply RST->INIT on the HW QP\n",
+ ibwq->wq_num);
+ return err;
+ }
+
+ qp_cur_state = IB_QPS_INIT;
+ }
+
+ attr_mask = 0;
+ err = __mlx4_ib_modify_qp(ibwq, MLX4_IB_RWQ_SRC, NULL, attr_mask,
+ qp_cur_state, qp_new_state);
+
+ if (err && (qp_cur_state == IB_QPS_INIT)) {
+ qp_new_state = IB_QPS_RESET;
+ if (__mlx4_ib_modify_qp(ibwq, MLX4_IB_RWQ_SRC, NULL,
+ attr_mask, IB_QPS_INIT, IB_QPS_RESET)) {
+ pr_warn("WQN=0x%06x failed with reverting HW's resources failure\n",
+ ibwq->wq_num);
+ qp_new_state = IB_QPS_INIT;
+ }
+ }
+
+ qp->state = qp_new_state;
+
+ return err;
+}
+
+int mlx4_ib_modify_wq(struct ib_wq *ibwq, struct ib_wq_attr *wq_attr,
+ u32 wq_attr_mask, struct ib_udata *udata)
+{
+ struct mlx4_ib_qp *qp = to_mqp((struct ib_qp *)ibwq);
+ struct mlx4_ib_modify_wq ucmd = {};
+ size_t required_cmd_sz;
+ enum ib_wq_state cur_state, new_state;
+ int err = 0;
+
+ required_cmd_sz = offsetof(typeof(ucmd), reserved) +
+ sizeof(ucmd.reserved);
+ if (udata->inlen < required_cmd_sz)
+ return -EINVAL;
+
+ if (udata->inlen > sizeof(ucmd) &&
+ !ib_is_udata_cleared(udata, sizeof(ucmd),
+ udata->inlen - sizeof(ucmd)))
+ return -EOPNOTSUPP;
+
+ if (ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen)))
+ return -EFAULT;
+
+ if (ucmd.comp_mask || ucmd.reserved)
+ return -EOPNOTSUPP;
+
+ if (wq_attr_mask & IB_WQ_FLAGS)
+ return -EOPNOTSUPP;
+
+ cur_state = wq_attr_mask & IB_WQ_CUR_STATE ? wq_attr->curr_wq_state :
+ ibwq->state;
+ new_state = wq_attr_mask & IB_WQ_STATE ? wq_attr->wq_state : cur_state;
+
+ if (cur_state < IB_WQS_RESET || cur_state > IB_WQS_ERR ||
+ new_state < IB_WQS_RESET || new_state > IB_WQS_ERR)
+ return -EINVAL;
+
+ if ((new_state == IB_WQS_RDY) && (cur_state == IB_WQS_ERR))
+ return -EINVAL;
+
+ if ((new_state == IB_WQS_ERR) && (cur_state == IB_WQS_RESET))
+ return -EINVAL;
+
+ /* Need to protect against the parent RSS which also may modify WQ
+ * state.
+ */
+ mutex_lock(&qp->mutex);
+
+ /* Can update HW state only if a RSS QP has already associated to this
+ * WQ, so we can apply its port on the WQ.
+ */
+ if (qp->rss_usecnt)
+ err = _mlx4_ib_modify_wq(ibwq, new_state);
+
+ if (!err)
+ ibwq->state = new_state;
+
+ mutex_unlock(&qp->mutex);
+
+ return err;
+}
+
+int mlx4_ib_destroy_wq(struct ib_wq *ibwq)
+{
+ struct mlx4_ib_dev *dev = to_mdev(ibwq->device);
+ struct mlx4_ib_qp *qp = to_mqp((struct ib_qp *)ibwq);
+
+ if (qp->counter_index)
+ mlx4_ib_free_qp_counter(dev, qp);
+
+ destroy_qp_common(dev, qp, MLX4_IB_RWQ_SRC, 1);
+
+ kfree(qp);
+
+ return 0;
+}
+
+struct ib_rwq_ind_table
+*mlx4_ib_create_rwq_ind_table(struct ib_device *device,
+ struct ib_rwq_ind_table_init_attr *init_attr,
+ struct ib_udata *udata)
+{
+ struct ib_rwq_ind_table *rwq_ind_table;
+ struct mlx4_ib_create_rwq_ind_tbl_resp resp = {};
+ unsigned int ind_tbl_size = 1 << init_attr->log_ind_tbl_size;
+ unsigned int base_wqn;
+ size_t min_resp_len;
+ int i;
+ int err;
+
+ if (udata->inlen > 0 &&
+ !ib_is_udata_cleared(udata, 0,
+ udata->inlen))
+ return ERR_PTR(-EOPNOTSUPP);
+
+ min_resp_len = offsetof(typeof(resp), reserved) + sizeof(resp.reserved);
+ if (udata->outlen && udata->outlen < min_resp_len)
+ return ERR_PTR(-EINVAL);
+
+ if (ind_tbl_size >
+ device->attrs.rss_caps.max_rwq_indirection_table_size) {
+ pr_debug("log_ind_tbl_size = %d is bigger than supported = %d\n",
+ ind_tbl_size,
+ device->attrs.rss_caps.max_rwq_indirection_table_size);
+ return ERR_PTR(-EINVAL);
+ }
+
+ base_wqn = init_attr->ind_tbl[0]->wq_num;
+
+ if (base_wqn % ind_tbl_size) {
+ pr_debug("WQN=0x%x isn't aligned with indirection table size\n",
+ base_wqn);
+ return ERR_PTR(-EINVAL);
+ }
+
+ for (i = 1; i < ind_tbl_size; i++) {
+ if (++base_wqn != init_attr->ind_tbl[i]->wq_num) {
+ pr_debug("indirection table's WQNs aren't consecutive\n");
+ return ERR_PTR(-EINVAL);
+ }
+ }
+
+ rwq_ind_table = kzalloc(sizeof(*rwq_ind_table), GFP_KERNEL);
+ if (!rwq_ind_table)
+ return ERR_PTR(-ENOMEM);
+
+ if (udata->outlen) {
+ resp.response_length = offsetof(typeof(resp), response_length) +
+ sizeof(resp.response_length);
+ err = ib_copy_to_udata(udata, &resp, resp.response_length);
+ if (err)
+ goto err;
+ }
+
+ return rwq_ind_table;
+
+err:
+ kfree(rwq_ind_table);
+ return ERR_PTR(err);
+}
+
+int mlx4_ib_destroy_rwq_ind_table(struct ib_rwq_ind_table *ib_rwq_ind_tbl)
+{
+ kfree(ib_rwq_ind_tbl);
+ return 0;
+}
diff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c
index 0facaf5..ebee56c 100644
--- a/drivers/infiniband/hw/mlx4/srq.c
+++ b/drivers/infiniband/hw/mlx4/srq.c
@@ -34,7 +34,6 @@
#include <linux/mlx4/qp.h>
#include <linux/mlx4/srq.h>
#include <linux/slab.h>
-#include <linux/vmalloc.h>
#include "mlx4_ib.h"
#include <rdma/mlx4-abi.h>
@@ -171,20 +170,16 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd,
if (err)
goto err_mtt;
- srq->wrid = kmalloc_array(srq->msrq.max, sizeof(u64),
- GFP_KERNEL | __GFP_NOWARN);
+ srq->wrid = kvmalloc_array(srq->msrq.max,
+ sizeof(u64), GFP_KERNEL);
if (!srq->wrid) {
- srq->wrid = __vmalloc(srq->msrq.max * sizeof(u64),
- GFP_KERNEL, PAGE_KERNEL);
- if (!srq->wrid) {
- err = -ENOMEM;
- goto err_mtt;
- }
+ err = -ENOMEM;
+ goto err_mtt;
}
}
- cqn = (init_attr->srq_type == IB_SRQT_XRC) ?
- to_mcq(init_attr->ext.xrc.cq)->mcq.cqn : 0;
+ cqn = ib_srq_has_cq(init_attr->srq_type) ?
+ to_mcq(init_attr->ext.cq)->mcq.cqn : 0;
xrcdn = (init_attr->srq_type == IB_SRQT_XRC) ?
to_mxrcd(init_attr->ext.xrc.xrcd)->xrcdn :
(u16) dev->dev->caps.reserved_xrcds;
diff --git a/drivers/infiniband/hw/mlx5/Makefile b/drivers/infiniband/hw/mlx5/Makefile
index 90ad2ad..bc62996 100644
--- a/drivers/infiniband/hw/mlx5/Makefile
+++ b/drivers/infiniband/hw/mlx5/Makefile
@@ -1,4 +1,4 @@
obj-$(CONFIG_MLX5_INFINIBAND) += mlx5_ib.o
-mlx5_ib-y := main.o cq.o doorbell.o qp.o mem.o srq.o mr.o ah.o mad.o gsi.o ib_virt.o cmd.o
+mlx5_ib-y := main.o cq.o doorbell.o qp.o mem.o srq.o mr.o ah.o mad.o gsi.o ib_virt.o cmd.o cong.o
mlx5_ib-$(CONFIG_INFINIBAND_ON_DEMAND_PAGING) += odp.o
diff --git a/drivers/infiniband/hw/mlx5/cmd.c b/drivers/infiniband/hw/mlx5/cmd.c
index 18d5e1d..470995f 100644
--- a/drivers/infiniband/hw/mlx5/cmd.c
+++ b/drivers/infiniband/hw/mlx5/cmd.c
@@ -57,3 +57,23 @@ int mlx5_cmd_query_cong_counter(struct mlx5_core_dev *dev,
MLX5_SET(query_cong_statistics_in, in, clear, reset);
return mlx5_cmd_exec(dev, in, sizeof(in), out, out_size);
}
+
+int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point,
+ void *out, int out_size)
+{
+ u32 in[MLX5_ST_SZ_DW(query_cong_params_in)] = { };
+
+ MLX5_SET(query_cong_params_in, in, opcode,
+ MLX5_CMD_OP_QUERY_CONG_PARAMS);
+ MLX5_SET(query_cong_params_in, in, cong_protocol, cong_point);
+
+ return mlx5_cmd_exec(dev, in, sizeof(in), out, out_size);
+}
+
+int mlx5_cmd_modify_cong_params(struct mlx5_core_dev *dev,
+ void *in, int in_size)
+{
+ u32 out[MLX5_ST_SZ_DW(modify_cong_params_out)] = { };
+
+ return mlx5_cmd_exec(dev, in, in_size, out, sizeof(out));
+}
diff --git a/drivers/infiniband/hw/mlx5/cmd.h b/drivers/infiniband/hw/mlx5/cmd.h
index fa09228..af4c245 100644
--- a/drivers/infiniband/hw/mlx5/cmd.h
+++ b/drivers/infiniband/hw/mlx5/cmd.h
@@ -39,4 +39,8 @@
int mlx5_cmd_null_mkey(struct mlx5_core_dev *dev, u32 *null_mkey);
int mlx5_cmd_query_cong_counter(struct mlx5_core_dev *dev,
bool reset, void *out, int out_size);
+int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point,
+ void *out, int out_size);
+int mlx5_cmd_modify_cong_params(struct mlx5_core_dev *mdev,
+ void *in, int in_size);
#endif /* MLX5_IB_CMD_H */
diff --git a/drivers/infiniband/hw/mlx5/cong.c b/drivers/infiniband/hw/mlx5/cong.c
new file mode 100644
index 0000000..2d32b51
--- /dev/null
+++ b/drivers/infiniband/hw/mlx5/cong.c
@@ -0,0 +1,421 @@
+/*
+ * Copyright (c) 2013-2017, Mellanox Technologies. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/debugfs.h>
+
+#include "mlx5_ib.h"
+#include "cmd.h"
+
+enum mlx5_ib_cong_node_type {
+ MLX5_IB_RROCE_ECN_RP = 1,
+ MLX5_IB_RROCE_ECN_NP = 2,
+};
+
+static const char * const mlx5_ib_dbg_cc_name[] = {
+ "rp_clamp_tgt_rate",
+ "rp_clamp_tgt_rate_ati",
+ "rp_time_reset",
+ "rp_byte_reset",
+ "rp_threshold",
+ "rp_ai_rate",
+ "rp_hai_rate",
+ "rp_min_dec_fac",
+ "rp_min_rate",
+ "rp_rate_to_set_on_first_cnp",
+ "rp_dce_tcp_g",
+ "rp_dce_tcp_rtt",
+ "rp_rate_reduce_monitor_period",
+ "rp_initial_alpha_value",
+ "rp_gd",
+ "np_cnp_dscp",
+ "np_cnp_prio_mode",
+ "np_cnp_prio",
+};
+
+#define MLX5_IB_RP_CLAMP_TGT_RATE_ATTR BIT(1)
+#define MLX5_IB_RP_CLAMP_TGT_RATE_ATI_ATTR BIT(2)
+#define MLX5_IB_RP_TIME_RESET_ATTR BIT(3)
+#define MLX5_IB_RP_BYTE_RESET_ATTR BIT(4)
+#define MLX5_IB_RP_THRESHOLD_ATTR BIT(5)
+#define MLX5_IB_RP_AI_RATE_ATTR BIT(7)
+#define MLX5_IB_RP_HAI_RATE_ATTR BIT(8)
+#define MLX5_IB_RP_MIN_DEC_FAC_ATTR BIT(9)
+#define MLX5_IB_RP_MIN_RATE_ATTR BIT(10)
+#define MLX5_IB_RP_RATE_TO_SET_ON_FIRST_CNP_ATTR BIT(11)
+#define MLX5_IB_RP_DCE_TCP_G_ATTR BIT(12)
+#define MLX5_IB_RP_DCE_TCP_RTT_ATTR BIT(13)
+#define MLX5_IB_RP_RATE_REDUCE_MONITOR_PERIOD_ATTR BIT(14)
+#define MLX5_IB_RP_INITIAL_ALPHA_VALUE_ATTR BIT(15)
+#define MLX5_IB_RP_GD_ATTR BIT(16)
+
+#define MLX5_IB_NP_CNP_DSCP_ATTR BIT(3)
+#define MLX5_IB_NP_CNP_PRIO_MODE_ATTR BIT(4)
+
+static enum mlx5_ib_cong_node_type
+mlx5_ib_param_to_node(enum mlx5_ib_dbg_cc_types param_offset)
+{
+ if (param_offset >= MLX5_IB_DBG_CC_RP_CLAMP_TGT_RATE &&
+ param_offset <= MLX5_IB_DBG_CC_RP_GD)
+ return MLX5_IB_RROCE_ECN_RP;
+ else
+ return MLX5_IB_RROCE_ECN_NP;
+}
+
+static u32 mlx5_get_cc_param_val(void *field, int offset)
+{
+ switch (offset) {
+ case MLX5_IB_DBG_CC_RP_CLAMP_TGT_RATE:
+ return MLX5_GET(cong_control_r_roce_ecn_rp, field,
+ clamp_tgt_rate);
+ case MLX5_IB_DBG_CC_RP_CLAMP_TGT_RATE_ATI:
+ return MLX5_GET(cong_control_r_roce_ecn_rp, field,
+ clamp_tgt_rate_after_time_inc);
+ case MLX5_IB_DBG_CC_RP_TIME_RESET:
+ return MLX5_GET(cong_control_r_roce_ecn_rp, field,
+ rpg_time_reset);
+ case MLX5_IB_DBG_CC_RP_BYTE_RESET:
+ return MLX5_GET(cong_control_r_roce_ecn_rp, field,
+ rpg_byte_reset);
+ case MLX5_IB_DBG_CC_RP_THRESHOLD:
+ return MLX5_GET(cong_control_r_roce_ecn_rp, field,
+ rpg_threshold);
+ case MLX5_IB_DBG_CC_RP_AI_RATE:
+ return MLX5_GET(cong_control_r_roce_ecn_rp, field,
+ rpg_ai_rate);
+ case MLX5_IB_DBG_CC_RP_HAI_RATE:
+ return MLX5_GET(cong_control_r_roce_ecn_rp, field,
+ rpg_hai_rate);
+ case MLX5_IB_DBG_CC_RP_MIN_DEC_FAC:
+ return MLX5_GET(cong_control_r_roce_ecn_rp, field,
+ rpg_min_dec_fac);
+ case MLX5_IB_DBG_CC_RP_MIN_RATE:
+ return MLX5_GET(cong_control_r_roce_ecn_rp, field,
+ rpg_min_rate);
+ case MLX5_IB_DBG_CC_RP_RATE_TO_SET_ON_FIRST_CNP:
+ return MLX5_GET(cong_control_r_roce_ecn_rp, field,
+ rate_to_set_on_first_cnp);
+ case MLX5_IB_DBG_CC_RP_DCE_TCP_G:
+ return MLX5_GET(cong_control_r_roce_ecn_rp, field,
+ dce_tcp_g);
+ case MLX5_IB_DBG_CC_RP_DCE_TCP_RTT:
+ return MLX5_GET(cong_control_r_roce_ecn_rp, field,
+ dce_tcp_rtt);
+ case MLX5_IB_DBG_CC_RP_RATE_REDUCE_MONITOR_PERIOD:
+ return MLX5_GET(cong_control_r_roce_ecn_rp, field,
+ rate_reduce_monitor_period);
+ case MLX5_IB_DBG_CC_RP_INITIAL_ALPHA_VALUE:
+ return MLX5_GET(cong_control_r_roce_ecn_rp, field,
+ initial_alpha_value);
+ case MLX5_IB_DBG_CC_RP_GD:
+ return MLX5_GET(cong_control_r_roce_ecn_rp, field,
+ rpg_gd);
+ case MLX5_IB_DBG_CC_NP_CNP_DSCP:
+ return MLX5_GET(cong_control_r_roce_ecn_np, field,
+ cnp_dscp);
+ case MLX5_IB_DBG_CC_NP_CNP_PRIO_MODE:
+ return MLX5_GET(cong_control_r_roce_ecn_np, field,
+ cnp_prio_mode);
+ case MLX5_IB_DBG_CC_NP_CNP_PRIO:
+ return MLX5_GET(cong_control_r_roce_ecn_np, field,
+ cnp_802p_prio);
+ default:
+ return 0;
+ }
+}
+
+static void mlx5_ib_set_cc_param_mask_val(void *field, int offset,
+ u32 var, u32 *attr_mask)
+{
+ switch (offset) {
+ case MLX5_IB_DBG_CC_RP_CLAMP_TGT_RATE:
+ *attr_mask |= MLX5_IB_RP_CLAMP_TGT_RATE_ATTR;
+ MLX5_SET(cong_control_r_roce_ecn_rp, field,
+ clamp_tgt_rate, var);
+ break;
+ case MLX5_IB_DBG_CC_RP_CLAMP_TGT_RATE_ATI:
+ *attr_mask |= MLX5_IB_RP_CLAMP_TGT_RATE_ATI_ATTR;
+ MLX5_SET(cong_control_r_roce_ecn_rp, field,
+ clamp_tgt_rate_after_time_inc, var);
+ break;
+ case MLX5_IB_DBG_CC_RP_TIME_RESET:
+ *attr_mask |= MLX5_IB_RP_TIME_RESET_ATTR;
+ MLX5_SET(cong_control_r_roce_ecn_rp, field,
+ rpg_time_reset, var);
+ break;
+ case MLX5_IB_DBG_CC_RP_BYTE_RESET:
+ *attr_mask |= MLX5_IB_RP_BYTE_RESET_ATTR;
+ MLX5_SET(cong_control_r_roce_ecn_rp, field,
+ rpg_byte_reset, var);
+ break;
+ case MLX5_IB_DBG_CC_RP_THRESHOLD:
+ *attr_mask |= MLX5_IB_RP_THRESHOLD_ATTR;
+ MLX5_SET(cong_control_r_roce_ecn_rp, field,
+ rpg_threshold, var);
+ break;
+ case MLX5_IB_DBG_CC_RP_AI_RATE:
+ *attr_mask |= MLX5_IB_RP_AI_RATE_ATTR;
+ MLX5_SET(cong_control_r_roce_ecn_rp, field,
+ rpg_ai_rate, var);
+ break;
+ case MLX5_IB_DBG_CC_RP_HAI_RATE:
+ *attr_mask |= MLX5_IB_RP_HAI_RATE_ATTR;
+ MLX5_SET(cong_control_r_roce_ecn_rp, field,
+ rpg_hai_rate, var);
+ break;
+ case MLX5_IB_DBG_CC_RP_MIN_DEC_FAC:
+ *attr_mask |= MLX5_IB_RP_MIN_DEC_FAC_ATTR;
+ MLX5_SET(cong_control_r_roce_ecn_rp, field,
+ rpg_min_dec_fac, var);
+ break;
+ case MLX5_IB_DBG_CC_RP_MIN_RATE:
+ *attr_mask |= MLX5_IB_RP_MIN_RATE_ATTR;
+ MLX5_SET(cong_control_r_roce_ecn_rp, field,
+ rpg_min_rate, var);
+ break;
+ case MLX5_IB_DBG_CC_RP_RATE_TO_SET_ON_FIRST_CNP:
+ *attr_mask |= MLX5_IB_RP_RATE_TO_SET_ON_FIRST_CNP_ATTR;
+ MLX5_SET(cong_control_r_roce_ecn_rp, field,
+ rate_to_set_on_first_cnp, var);
+ break;
+ case MLX5_IB_DBG_CC_RP_DCE_TCP_G:
+ *attr_mask |= MLX5_IB_RP_DCE_TCP_G_ATTR;
+ MLX5_SET(cong_control_r_roce_ecn_rp, field,
+ dce_tcp_g, var);
+ break;
+ case MLX5_IB_DBG_CC_RP_DCE_TCP_RTT:
+ *attr_mask |= MLX5_IB_RP_DCE_TCP_RTT_ATTR;
+ MLX5_SET(cong_control_r_roce_ecn_rp, field,
+ dce_tcp_rtt, var);
+ break;
+ case MLX5_IB_DBG_CC_RP_RATE_REDUCE_MONITOR_PERIOD:
+ *attr_mask |= MLX5_IB_RP_RATE_REDUCE_MONITOR_PERIOD_ATTR;
+ MLX5_SET(cong_control_r_roce_ecn_rp, field,
+ rate_reduce_monitor_period, var);
+ break;
+ case MLX5_IB_DBG_CC_RP_INITIAL_ALPHA_VALUE:
+ *attr_mask |= MLX5_IB_RP_INITIAL_ALPHA_VALUE_ATTR;
+ MLX5_SET(cong_control_r_roce_ecn_rp, field,
+ initial_alpha_value, var);
+ break;
+ case MLX5_IB_DBG_CC_RP_GD:
+ *attr_mask |= MLX5_IB_RP_GD_ATTR;
+ MLX5_SET(cong_control_r_roce_ecn_rp, field,
+ rpg_gd, var);
+ break;
+ case MLX5_IB_DBG_CC_NP_CNP_DSCP:
+ *attr_mask |= MLX5_IB_NP_CNP_DSCP_ATTR;
+ MLX5_SET(cong_control_r_roce_ecn_np, field, cnp_dscp, var);
+ break;
+ case MLX5_IB_DBG_CC_NP_CNP_PRIO_MODE:
+ *attr_mask |= MLX5_IB_NP_CNP_PRIO_MODE_ATTR;
+ MLX5_SET(cong_control_r_roce_ecn_np, field, cnp_prio_mode, var);
+ break;
+ case MLX5_IB_DBG_CC_NP_CNP_PRIO:
+ *attr_mask |= MLX5_IB_NP_CNP_PRIO_MODE_ATTR;
+ MLX5_SET(cong_control_r_roce_ecn_np, field, cnp_prio_mode, 0);
+ MLX5_SET(cong_control_r_roce_ecn_np, field, cnp_802p_prio, var);
+ break;
+ }
+}
+
+static int mlx5_ib_get_cc_params(struct mlx5_ib_dev *dev, int offset, u32 *var)
+{
+ int outlen = MLX5_ST_SZ_BYTES(query_cong_params_out);
+ void *out;
+ void *field;
+ int err;
+ enum mlx5_ib_cong_node_type node;
+
+ out = kvzalloc(outlen, GFP_KERNEL);
+ if (!out)
+ return -ENOMEM;
+
+ node = mlx5_ib_param_to_node(offset);
+
+ err = mlx5_cmd_query_cong_params(dev->mdev, node, out, outlen);
+ if (err)
+ goto free;
+
+ field = MLX5_ADDR_OF(query_cong_params_out, out, congestion_parameters);
+ *var = mlx5_get_cc_param_val(field, offset);
+
+free:
+ kvfree(out);
+ return err;
+}
+
+static int mlx5_ib_set_cc_params(struct mlx5_ib_dev *dev, int offset, u32 var)
+{
+ int inlen = MLX5_ST_SZ_BYTES(modify_cong_params_in);
+ void *in;
+ void *field;
+ enum mlx5_ib_cong_node_type node;
+ u32 attr_mask = 0;
+ int err;
+
+ in = kvzalloc(inlen, GFP_KERNEL);
+ if (!in)
+ return -ENOMEM;
+
+ MLX5_SET(modify_cong_params_in, in, opcode,
+ MLX5_CMD_OP_MODIFY_CONG_PARAMS);
+
+ node = mlx5_ib_param_to_node(offset);
+ MLX5_SET(modify_cong_params_in, in, cong_protocol, node);
+
+ field = MLX5_ADDR_OF(modify_cong_params_in, in, congestion_parameters);
+ mlx5_ib_set_cc_param_mask_val(field, offset, var, &attr_mask);
+
+ field = MLX5_ADDR_OF(modify_cong_params_in, in, field_select);
+ MLX5_SET(field_select_r_roce_rp, field, field_select_r_roce_rp,
+ attr_mask);
+
+ err = mlx5_cmd_modify_cong_params(dev->mdev, in, inlen);
+ kvfree(in);
+ return err;
+}
+
+static ssize_t set_param(struct file *filp, const char __user *buf,
+ size_t count, loff_t *pos)
+{
+ struct mlx5_ib_dbg_param *param = filp->private_data;
+ int offset = param->offset;
+ char lbuf[11] = { };
+ u32 var;
+ int ret;
+
+ if (count > sizeof(lbuf))
+ return -EINVAL;
+
+ if (copy_from_user(lbuf, buf, count))
+ return -EFAULT;
+
+ lbuf[sizeof(lbuf) - 1] = '\0';
+
+ if (kstrtou32(lbuf, 0, &var))
+ return -EINVAL;
+
+ ret = mlx5_ib_set_cc_params(param->dev, offset, var);
+ return ret ? ret : count;
+}
+
+static ssize_t get_param(struct file *filp, char __user *buf, size_t count,
+ loff_t *pos)
+{
+ struct mlx5_ib_dbg_param *param = filp->private_data;
+ int offset = param->offset;
+ u32 var = 0;
+ int ret;
+ char lbuf[11];
+
+ if (*pos)
+ return 0;
+
+ ret = mlx5_ib_get_cc_params(param->dev, offset, &var);
+ if (ret)
+ return ret;
+
+ ret = snprintf(lbuf, sizeof(lbuf), "%d\n", var);
+ if (ret < 0)
+ return ret;
+
+ if (copy_to_user(buf, lbuf, ret))
+ return -EFAULT;
+
+ *pos += ret;
+ return ret;
+}
+
+static const struct file_operations dbg_cc_fops = {
+ .owner = THIS_MODULE,
+ .open = simple_open,
+ .write = set_param,
+ .read = get_param,
+};
+
+void mlx5_ib_cleanup_cong_debugfs(struct mlx5_ib_dev *dev)
+{
+ if (!mlx5_debugfs_root ||
+ !dev->dbg_cc_params ||
+ !dev->dbg_cc_params->root)
+ return;
+
+ debugfs_remove_recursive(dev->dbg_cc_params->root);
+ kfree(dev->dbg_cc_params);
+ dev->dbg_cc_params = NULL;
+}
+
+int mlx5_ib_init_cong_debugfs(struct mlx5_ib_dev *dev)
+{
+ struct mlx5_ib_dbg_cc_params *dbg_cc_params;
+ int i;
+
+ if (!mlx5_debugfs_root)
+ goto out;
+
+ if (!MLX5_CAP_GEN(dev->mdev, cc_query_allowed) ||
+ !MLX5_CAP_GEN(dev->mdev, cc_modify_allowed))
+ goto out;
+
+ dbg_cc_params = kzalloc(sizeof(*dbg_cc_params), GFP_KERNEL);
+ if (!dbg_cc_params)
+ goto out;
+
+ dev->dbg_cc_params = dbg_cc_params;
+
+ dbg_cc_params->root = debugfs_create_dir("cc_params",
+ dev->mdev->priv.dbg_root);
+ if (!dbg_cc_params->root)
+ goto err;
+
+ for (i = 0; i < MLX5_IB_DBG_CC_MAX; i++) {
+ dbg_cc_params->params[i].offset = i;
+ dbg_cc_params->params[i].dev = dev;
+ dbg_cc_params->params[i].dentry =
+ debugfs_create_file(mlx5_ib_dbg_cc_name[i],
+ 0600, dbg_cc_params->root,
+ &dbg_cc_params->params[i],
+ &dbg_cc_fops);
+ if (!dbg_cc_params->params[i].dentry)
+ goto err;
+ }
+out: return 0;
+
+err:
+ mlx5_ib_warn(dev, "cong debugfs failure\n");
+ mlx5_ib_cleanup_cong_debugfs(dev);
+ /*
+ * We don't want to fail driver if debugfs failed to initialize,
+ * so we are not forwarding error to the user.
+ */
+ return 0;
+}
diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c
index a384d72..2aa53f4 100644
--- a/drivers/infiniband/hw/mlx5/cq.c
+++ b/drivers/infiniband/hw/mlx5/cq.c
@@ -499,7 +499,7 @@ static void mlx5_ib_poll_sw_comp(struct mlx5_ib_cq *cq, int num_entries,
struct mlx5_ib_qp *qp;
*npolled = 0;
- /* Find uncompleted WQEs belonging to that cq and retrun mmics ones */
+ /* Find uncompleted WQEs belonging to that cq and return mmics ones */
list_for_each_entry(qp, &cq->list_send_qp, cq_send_list) {
sw_send_comp(qp, num_entries, wc + *npolled, npolled);
if (*npolled >= num_entries)
@@ -751,10 +751,8 @@ static int create_cq_user(struct mlx5_ib_dev *dev, struct ib_udata *udata,
void *cqc;
int err;
- ucmdlen =
- (udata->inlen - sizeof(struct ib_uverbs_cmd_hdr) <
- sizeof(ucmd)) ? (sizeof(ucmd) -
- sizeof(ucmd.reserved)) : sizeof(ucmd);
+ ucmdlen = udata->inlen < sizeof(ucmd) ?
+ (sizeof(ucmd) - sizeof(ucmd.reserved)) : sizeof(ucmd);
if (ib_copy_from_udata(&ucmd, udata, ucmdlen))
return -EFAULT;
diff --git a/drivers/infiniband/hw/mlx5/ib_virt.c b/drivers/infiniband/hw/mlx5/ib_virt.c
index c1b9de8..649a336 100644
--- a/drivers/infiniband/hw/mlx5/ib_virt.c
+++ b/drivers/infiniband/hw/mlx5/ib_virt.c
@@ -96,6 +96,7 @@ int mlx5_ib_set_vf_link_state(struct ib_device *device, int vf,
struct mlx5_ib_dev *dev = to_mdev(device);
struct mlx5_core_dev *mdev = dev->mdev;
struct mlx5_hca_vport_context *in;
+ struct mlx5_vf_context *vfs_ctx = mdev->priv.sriov.vfs_ctx;
int err;
in = kzalloc(sizeof(*in), GFP_KERNEL);
@@ -109,6 +110,8 @@ int mlx5_ib_set_vf_link_state(struct ib_device *device, int vf,
}
in->field_select = MLX5_HCA_VPORT_SEL_STATE_POLICY;
err = mlx5_core_modify_hca_vport_context(mdev, 1, 1, vf + 1, in);
+ if (!err)
+ vfs_ctx[vf].policy = in->policy;
out:
kfree(in);
@@ -151,6 +154,7 @@ static int set_vf_node_guid(struct ib_device *device, int vf, u8 port, u64 guid)
struct mlx5_ib_dev *dev = to_mdev(device);
struct mlx5_core_dev *mdev = dev->mdev;
struct mlx5_hca_vport_context *in;
+ struct mlx5_vf_context *vfs_ctx = mdev->priv.sriov.vfs_ctx;
int err;
in = kzalloc(sizeof(*in), GFP_KERNEL);
@@ -160,6 +164,8 @@ static int set_vf_node_guid(struct ib_device *device, int vf, u8 port, u64 guid)
in->field_select = MLX5_HCA_VPORT_SEL_NODE_GUID;
in->node_guid = guid;
err = mlx5_core_modify_hca_vport_context(mdev, 1, 1, vf + 1, in);
+ if (!err)
+ vfs_ctx[vf].node_guid = guid;
kfree(in);
return err;
}
@@ -169,6 +175,7 @@ static int set_vf_port_guid(struct ib_device *device, int vf, u8 port, u64 guid)
struct mlx5_ib_dev *dev = to_mdev(device);
struct mlx5_core_dev *mdev = dev->mdev;
struct mlx5_hca_vport_context *in;
+ struct mlx5_vf_context *vfs_ctx = mdev->priv.sriov.vfs_ctx;
int err;
in = kzalloc(sizeof(*in), GFP_KERNEL);
@@ -178,6 +185,8 @@ static int set_vf_port_guid(struct ib_device *device, int vf, u8 port, u64 guid)
in->field_select = MLX5_HCA_VPORT_SEL_PORT_GUID;
in->port_guid = guid;
err = mlx5_core_modify_hca_vport_context(mdev, 1, 1, vf + 1, in);
+ if (!err)
+ vfs_ctx[vf].port_guid = guid;
kfree(in);
return err;
}
diff --git a/drivers/infiniband/hw/mlx5/mad.c b/drivers/infiniband/hw/mlx5/mad.c
index 95db929..1003b01 100644
--- a/drivers/infiniband/hw/mlx5/mad.c
+++ b/drivers/infiniband/hw/mlx5/mad.c
@@ -78,7 +78,7 @@ static int process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
u16 slid;
int err;
- slid = in_wc ? in_wc->slid : be16_to_cpu(IB_LID_PERMISSIVE);
+ slid = in_wc ? ib_lid_cpu16(in_wc->slid) : be16_to_cpu(IB_LID_PERMISSIVE);
if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP && slid == 0)
return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED;
@@ -204,7 +204,7 @@ static int process_pma_cmd(struct ib_device *ibdev, u8 port_num,
int err;
void *out_cnt;
- /* Decalring support of extended counters */
+ /* Declaring support of extended counters */
if (in_mad->mad_hdr.attr_id == IB_PMA_CLASS_PORT_INFO) {
struct ib_class_port_info cpi = {};
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index f7fcde1..ab3c562 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -30,6 +30,7 @@
* SOFTWARE.
*/
+#include <linux/debugfs.h>
#include <linux/highmem.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -58,6 +59,7 @@
#include <linux/mlx5/vport.h>
#include "mlx5_ib.h"
#include "cmd.h"
+#include <linux/mlx5/vport.h>
#define DRIVER_NAME "mlx5_ib"
#define DRIVER_VERSION "5.0-0"
@@ -65,7 +67,6 @@
MODULE_AUTHOR("Eli Cohen <eli@mellanox.com>");
MODULE_DESCRIPTION("Mellanox Connect-IB HCA IB driver");
MODULE_LICENSE("Dual BSD/GPL");
-MODULE_VERSION(DRIVER_VERSION);
static char mlx5_version[] =
DRIVER_NAME ": Mellanox Connect-IB Infiniband driver v"
@@ -97,6 +98,20 @@ mlx5_ib_port_link_layer(struct ib_device *device, u8 port_num)
return mlx5_port_type_cap_to_rdma_ll(port_type_cap);
}
+static int get_port_state(struct ib_device *ibdev,
+ u8 port_num,
+ enum ib_port_state *state)
+{
+ struct ib_port_attr attr;
+ int ret;
+
+ memset(&attr, 0, sizeof(attr));
+ ret = mlx5_ib_query_port(ibdev, port_num, &attr);
+ if (!ret)
+ *state = attr.state;
+ return ret;
+}
+
static int mlx5_netdev_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
@@ -114,6 +129,7 @@ static int mlx5_netdev_event(struct notifier_block *this,
write_unlock(&ibdev->roce.netdev_lock);
break;
+ case NETDEV_CHANGE:
case NETDEV_UP:
case NETDEV_DOWN: {
struct net_device *lag_ndev = mlx5_lag_get_roce_netdev(ibdev->mdev);
@@ -127,10 +143,23 @@ static int mlx5_netdev_event(struct notifier_block *this,
if ((upper == ndev || (!upper && ndev == ibdev->roce.netdev))
&& ibdev->ib_active) {
struct ib_event ibev = { };
+ enum ib_port_state port_state;
+ if (get_port_state(&ibdev->ib_dev, 1, &port_state))
+ return NOTIFY_DONE;
+
+ if (ibdev->roce.last_port_state == port_state)
+ return NOTIFY_DONE;
+
+ ibdev->roce.last_port_state = port_state;
ibev.device = &ibdev->ib_dev;
- ibev.event = (event == NETDEV_UP) ?
- IB_EVENT_PORT_ACTIVE : IB_EVENT_PORT_ERR;
+ if (port_state == IB_PORT_DOWN)
+ ibev.event = IB_EVENT_PORT_ERR;
+ else if (port_state == IB_PORT_ACTIVE)
+ ibev.event = IB_EVENT_PORT_ACTIVE;
+ else
+ return NOTIFY_DONE;
+
ibev.element.port_num = 1;
ib_dispatch_event(&ibev);
}
@@ -668,6 +697,14 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
props->device_cap_flags |= IB_DEVICE_UD_TSO;
}
+ if (MLX5_CAP_GEN(dev->mdev, rq_delay_drop) &&
+ MLX5_CAP_GEN(dev->mdev, general_notification_event))
+ props->raw_packet_caps |= IB_RAW_PACKET_CAP_DELAY_DROP;
+
+ if (MLX5_CAP_GEN(mdev, ipoib_enhanced_offloads) &&
+ MLX5_CAP_IPOIB_ENHANCED(mdev, csum_cap))
+ props->device_cap_flags |= IB_DEVICE_UD_IP_CSUM;
+
if (MLX5_CAP_GEN(dev->mdev, eth_net_offloads) &&
MLX5_CAP_ETH(dev->mdev, scatter_fcs)) {
/* Legacy bit to support old userspace libraries */
@@ -740,6 +777,16 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
1 << MLX5_CAP_GEN(dev->mdev, log_max_rq);
}
+ if (MLX5_CAP_GEN(mdev, tag_matching)) {
+ props->xrq_caps.max_rndv_hdr_size = MLX5_TM_MAX_RNDV_MSG_SIZE;
+ props->xrq_caps.max_num_tags =
+ (1 << MLX5_CAP_GEN(mdev, log_tag_matching_list_sz)) - 1;
+ props->xrq_caps.flags = IB_TM_CAP_RC;
+ props->xrq_caps.max_ops =
+ 1 << MLX5_CAP_GEN(mdev, log_max_qp_sz);
+ props->xrq_caps.max_sge = MLX5_TM_MAX_SGE;
+ }
+
if (field_avail(typeof(resp), cqe_comp_caps, uhw->outlen)) {
resp.cqe_comp_caps.max_num =
MLX5_CAP_GEN(dev->mdev, cqe_compression) ?
@@ -765,8 +812,14 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
if (field_avail(typeof(resp), mlx5_ib_support_multi_pkt_send_wqes,
uhw->outlen)) {
- resp.mlx5_ib_support_multi_pkt_send_wqes =
- MLX5_CAP_ETH(mdev, multi_pkt_send_wqe);
+ if (MLX5_CAP_ETH(mdev, multi_pkt_send_wqe))
+ resp.mlx5_ib_support_multi_pkt_send_wqes =
+ MLX5_IB_ALLOW_MPW;
+
+ if (MLX5_CAP_ETH(mdev, enhanced_multi_pkt_send_wqe))
+ resp.mlx5_ib_support_multi_pkt_send_wqes |=
+ MLX5_IB_SUPPORT_EMPW;
+
resp.response_length +=
sizeof(resp.mlx5_ib_support_multi_pkt_send_wqes);
}
@@ -774,6 +827,27 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
if (field_avail(typeof(resp), reserved, uhw->outlen))
resp.response_length += sizeof(resp.reserved);
+ if (field_avail(typeof(resp), sw_parsing_caps,
+ uhw->outlen)) {
+ resp.response_length += sizeof(resp.sw_parsing_caps);
+ if (MLX5_CAP_ETH(mdev, swp)) {
+ resp.sw_parsing_caps.sw_parsing_offloads |=
+ MLX5_IB_SW_PARSING;
+
+ if (MLX5_CAP_ETH(mdev, swp_csum))
+ resp.sw_parsing_caps.sw_parsing_offloads |=
+ MLX5_IB_SW_PARSING_CSUM;
+
+ if (MLX5_CAP_ETH(mdev, swp_lso))
+ resp.sw_parsing_caps.sw_parsing_offloads |=
+ MLX5_IB_SW_PARSING_LSO;
+
+ if (resp.sw_parsing_caps.sw_parsing_offloads)
+ resp.sw_parsing_caps.supported_qpts =
+ BIT(IB_QPT_RAW_PACKET);
+ }
+ }
+
if (uhw->outlen) {
err = ib_copy_to_udata(uhw, &resp, resp.response_length);
@@ -1144,7 +1218,7 @@ static int calc_total_bfregs(struct mlx5_ib_dev *dev, bool lib_uar_4k,
if (req->num_low_latency_bfregs > req->total_num_bfregs - 1)
return -EINVAL;
- mlx5_ib_dbg(dev, "uar_4k: fw support %s, lib support %s, user requested %d bfregs, alloated %d, using %d sys pages\n",
+ mlx5_ib_dbg(dev, "uar_4k: fw support %s, lib support %s, user requested %d bfregs, allocated %d, using %d sys pages\n",
MLX5_CAP_GEN(dev->mdev, uar_4k) ? "yes" : "no",
lib_uar_4k ? "yes" : "no", ref_bfregs,
req->total_num_bfregs, *num_sys_pages);
@@ -1193,6 +1267,45 @@ static int deallocate_uars(struct mlx5_ib_dev *dev, struct mlx5_ib_ucontext *con
return 0;
}
+static int mlx5_ib_alloc_transport_domain(struct mlx5_ib_dev *dev, u32 *tdn)
+{
+ int err;
+
+ err = mlx5_core_alloc_transport_domain(dev->mdev, tdn);
+ if (err)
+ return err;
+
+ if ((MLX5_CAP_GEN(dev->mdev, port_type) != MLX5_CAP_PORT_TYPE_ETH) ||
+ !MLX5_CAP_GEN(dev->mdev, disable_local_lb))
+ return err;
+
+ mutex_lock(&dev->lb_mutex);
+ dev->user_td++;
+
+ if (dev->user_td == 2)
+ err = mlx5_nic_vport_update_local_lb(dev->mdev, true);
+
+ mutex_unlock(&dev->lb_mutex);
+ return err;
+}
+
+static void mlx5_ib_dealloc_transport_domain(struct mlx5_ib_dev *dev, u32 tdn)
+{
+ mlx5_core_dealloc_transport_domain(dev->mdev, tdn);
+
+ if ((MLX5_CAP_GEN(dev->mdev, port_type) != MLX5_CAP_PORT_TYPE_ETH) ||
+ !MLX5_CAP_GEN(dev->mdev, disable_local_lb))
+ return;
+
+ mutex_lock(&dev->lb_mutex);
+ dev->user_td--;
+
+ if (dev->user_td < 2)
+ mlx5_nic_vport_update_local_lb(dev->mdev, false);
+
+ mutex_unlock(&dev->lb_mutex);
+}
+
static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
struct ib_udata *udata)
{
@@ -1203,7 +1316,6 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
struct mlx5_bfreg_info *bfregi;
int ver;
int err;
- size_t reqlen;
size_t min_req_v2 = offsetof(struct mlx5_ib_alloc_ucontext_req_v2,
max_cqe_version);
bool lib_uar_4k;
@@ -1211,18 +1323,14 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
if (!dev->ib_active)
return ERR_PTR(-EAGAIN);
- if (udata->inlen < sizeof(struct ib_uverbs_cmd_hdr))
- return ERR_PTR(-EINVAL);
-
- reqlen = udata->inlen - sizeof(struct ib_uverbs_cmd_hdr);
- if (reqlen == sizeof(struct mlx5_ib_alloc_ucontext_req))
+ if (udata->inlen == sizeof(struct mlx5_ib_alloc_ucontext_req))
ver = 0;
- else if (reqlen >= min_req_v2)
+ else if (udata->inlen >= min_req_v2)
ver = 2;
else
return ERR_PTR(-EINVAL);
- err = ib_copy_from_udata(&req, udata, min(reqlen, sizeof(req)));
+ err = ib_copy_from_udata(&req, udata, min(udata->inlen, sizeof(req)));
if (err)
return ERR_PTR(err);
@@ -1301,8 +1409,7 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
mutex_init(&context->upd_xlt_page_mutex);
if (MLX5_CAP_GEN(dev->mdev, log_max_transport_domain)) {
- err = mlx5_core_alloc_transport_domain(dev->mdev,
- &context->tdn);
+ err = mlx5_ib_alloc_transport_domain(dev, &context->tdn);
if (err)
goto out_page;
}
@@ -1368,7 +1475,7 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
out_td:
if (MLX5_CAP_GEN(dev->mdev, log_max_transport_domain))
- mlx5_core_dealloc_transport_domain(dev->mdev, context->tdn);
+ mlx5_ib_dealloc_transport_domain(dev, context->tdn);
out_page:
free_page(context->upd_xlt_page);
@@ -1396,7 +1503,7 @@ static int mlx5_ib_dealloc_ucontext(struct ib_ucontext *ibcontext)
bfregi = &context->bfregi;
if (MLX5_CAP_GEN(dev->mdev, log_max_transport_domain))
- mlx5_core_dealloc_transport_domain(dev->mdev, context->tdn);
+ mlx5_ib_dealloc_transport_domain(dev, context->tdn);
free_page(context->upd_xlt_page);
deallocate_uars(dev, context);
@@ -2034,23 +2141,34 @@ static int parse_flow_attr(struct mlx5_core_dev *mdev, u32 *match_c,
* it won't fall into the multicast flow steering table and this rule
* could steal other multicast packets.
*/
-static bool flow_is_multicast_only(struct ib_flow_attr *ib_attr)
+static bool flow_is_multicast_only(const struct ib_flow_attr *ib_attr)
{
- struct ib_flow_spec_eth *eth_spec;
+ union ib_flow_spec *flow_spec;
if (ib_attr->type != IB_FLOW_ATTR_NORMAL ||
- ib_attr->size < sizeof(struct ib_flow_attr) +
- sizeof(struct ib_flow_spec_eth) ||
ib_attr->num_of_specs < 1)
return false;
- eth_spec = (struct ib_flow_spec_eth *)(ib_attr + 1);
- if (eth_spec->type != IB_FLOW_SPEC_ETH ||
- eth_spec->size != sizeof(*eth_spec))
+ flow_spec = (union ib_flow_spec *)(ib_attr + 1);
+ if (flow_spec->type == IB_FLOW_SPEC_IPV4) {
+ struct ib_flow_spec_ipv4 *ipv4_spec;
+
+ ipv4_spec = (struct ib_flow_spec_ipv4 *)flow_spec;
+ if (ipv4_is_multicast(ipv4_spec->val.dst_ip))
+ return true;
+
return false;
+ }
+
+ if (flow_spec->type == IB_FLOW_SPEC_ETH) {
+ struct ib_flow_spec_eth *eth_spec;
- return is_multicast_ether_addr(eth_spec->mask.dst_mac) &&
- is_multicast_ether_addr(eth_spec->val.dst_mac);
+ eth_spec = (struct ib_flow_spec_eth *)flow_spec;
+ return is_multicast_ether_addr(eth_spec->mask.dst_mac) &&
+ is_multicast_ether_addr(eth_spec->val.dst_mac);
+ }
+
+ return false;
}
static bool is_valid_ethertype(struct mlx5_core_dev *mdev,
@@ -2235,10 +2353,31 @@ static struct mlx5_ib_flow_prio *get_flow_table(struct mlx5_ib_dev *dev,
return err ? ERR_PTR(err) : prio;
}
-static struct mlx5_ib_flow_handler *create_flow_rule(struct mlx5_ib_dev *dev,
- struct mlx5_ib_flow_prio *ft_prio,
- const struct ib_flow_attr *flow_attr,
- struct mlx5_flow_destination *dst)
+static void set_underlay_qp(struct mlx5_ib_dev *dev,
+ struct mlx5_flow_spec *spec,
+ u32 underlay_qpn)
+{
+ void *misc_params_c = MLX5_ADDR_OF(fte_match_param,
+ spec->match_criteria,
+ misc_parameters);
+ void *misc_params_v = MLX5_ADDR_OF(fte_match_param, spec->match_value,
+ misc_parameters);
+
+ if (underlay_qpn &&
+ MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev,
+ ft_field_support.bth_dst_qp)) {
+ MLX5_SET(fte_match_set_misc,
+ misc_params_v, bth_dst_qp, underlay_qpn);
+ MLX5_SET(fte_match_set_misc,
+ misc_params_c, bth_dst_qp, 0xffffff);
+ }
+}
+
+static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev,
+ struct mlx5_ib_flow_prio *ft_prio,
+ const struct ib_flow_attr *flow_attr,
+ struct mlx5_flow_destination *dst,
+ u32 underlay_qpn)
{
struct mlx5_flow_table *ft = ft_prio->flow_table;
struct mlx5_ib_flow_handler *handler;
@@ -2274,6 +2413,9 @@ static struct mlx5_ib_flow_handler *create_flow_rule(struct mlx5_ib_dev *dev,
ib_flow += ((union ib_flow_spec *)ib_flow)->size;
}
+ if (!flow_is_multicast_only(flow_attr))
+ set_underlay_qp(dev, spec, underlay_qpn);
+
spec->match_criteria_enable = get_match_criteria_enable(spec->match_criteria);
if (is_drop) {
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP;
@@ -2313,6 +2455,14 @@ free:
return err ? ERR_PTR(err) : handler;
}
+static struct mlx5_ib_flow_handler *create_flow_rule(struct mlx5_ib_dev *dev,
+ struct mlx5_ib_flow_prio *ft_prio,
+ const struct ib_flow_attr *flow_attr,
+ struct mlx5_flow_destination *dst)
+{
+ return _create_flow_rule(dev, ft_prio, flow_attr, dst, 0);
+}
+
static struct mlx5_ib_flow_handler *create_dont_trap_rule(struct mlx5_ib_dev *dev,
struct mlx5_ib_flow_prio *ft_prio,
struct ib_flow_attr *flow_attr,
@@ -2449,6 +2599,7 @@ static struct ib_flow *mlx5_ib_create_flow(struct ib_qp *qp,
struct mlx5_ib_flow_prio *ft_prio_tx = NULL;
struct mlx5_ib_flow_prio *ft_prio;
int err;
+ int underlay_qpn;
if (flow_attr->priority > MLX5_IB_FLOW_LAST_PRIO)
return ERR_PTR(-ENOMEM);
@@ -2489,8 +2640,10 @@ static struct ib_flow *mlx5_ib_create_flow(struct ib_qp *qp,
handler = create_dont_trap_rule(dev, ft_prio,
flow_attr, dst);
} else {
- handler = create_flow_rule(dev, ft_prio, flow_attr,
- dst);
+ underlay_qpn = (mqp->flags & MLX5_IB_QP_UNDERLAY) ?
+ mqp->underlay_qpn : 0;
+ handler = _create_flow_rule(dev, ft_prio, flow_attr,
+ dst, underlay_qpn);
}
} else if (flow_attr->type == IB_FLOW_ATTR_ALL_DEFAULT ||
flow_attr->type == IB_FLOW_ATTR_MC_DEFAULT) {
@@ -2528,8 +2681,14 @@ unlock:
static int mlx5_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
{
struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
+ struct mlx5_ib_qp *mqp = to_mqp(ibqp);
int err;
+ if (mqp->flags & MLX5_IB_QP_UNDERLAY) {
+ mlx5_ib_dbg(dev, "Attaching a multi cast group to underlay QP is not supported\n");
+ return -EOPNOTSUPP;
+ }
+
err = mlx5_core_attach_mcg(dev->mdev, gid, ibqp->qp_num);
if (err)
mlx5_ib_warn(dev, "failed attaching QPN 0x%x, MGID %pI6\n",
@@ -2691,6 +2850,26 @@ static void mlx5_ib_handle_internal_error(struct mlx5_ib_dev *ibdev)
spin_unlock_irqrestore(&ibdev->reset_flow_resource_lock, flags);
}
+static void delay_drop_handler(struct work_struct *work)
+{
+ int err;
+ struct mlx5_ib_delay_drop *delay_drop =
+ container_of(work, struct mlx5_ib_delay_drop,
+ delay_drop_work);
+
+ atomic_inc(&delay_drop->events_cnt);
+
+ mutex_lock(&delay_drop->lock);
+ err = mlx5_core_set_delay_drop(delay_drop->dev->mdev,
+ delay_drop->timeout);
+ if (err) {
+ mlx5_ib_warn(delay_drop->dev, "Failed to set delay drop, timeout=%u\n",
+ delay_drop->timeout);
+ delay_drop->activate = false;
+ }
+ mutex_unlock(&delay_drop->lock);
+}
+
static void mlx5_ib_event(struct mlx5_core_dev *dev, void *context,
enum mlx5_dev_event event, unsigned long param)
{
@@ -2743,8 +2922,11 @@ static void mlx5_ib_event(struct mlx5_core_dev *dev, void *context,
ibev.event = IB_EVENT_CLIENT_REREGISTER;
port = (u8)param;
break;
+ case MLX5_DEV_EVENT_DELAY_DROP_TIMEOUT:
+ schedule_work(&ibdev->delay_drop.delay_drop_work);
+ goto out;
default:
- return;
+ goto out;
}
ibev.device = &ibdev->ib_dev;
@@ -2752,7 +2934,7 @@ static void mlx5_ib_event(struct mlx5_core_dev *dev, void *context,
if (port < 1 || port > ibdev->num_ports) {
mlx5_ib_warn(ibdev, "warning: event on port %d\n", port);
- return;
+ goto out;
}
if (ibdev->ib_active)
@@ -2760,6 +2942,9 @@ static void mlx5_ib_event(struct mlx5_core_dev *dev, void *context,
if (fatal)
ibdev->ib_active = false;
+
+out:
+ return;
}
static int set_has_smi_cap(struct mlx5_ib_dev *dev)
@@ -3042,7 +3227,7 @@ static int create_dev_resources(struct mlx5_ib_resources *devr)
attr.attr.max_sge = 1;
attr.attr.max_wr = 1;
attr.srq_type = IB_SRQT_XRC;
- attr.ext.xrc.cq = devr->c0;
+ attr.ext.cq = devr->c0;
attr.ext.xrc.xrcd = devr->x0;
devr->s0 = mlx5_ib_create_srq(devr->p0, &attr, NULL);
@@ -3057,9 +3242,9 @@ static int create_dev_resources(struct mlx5_ib_resources *devr)
devr->s0->srq_context = NULL;
devr->s0->srq_type = IB_SRQT_XRC;
devr->s0->ext.xrc.xrcd = devr->x0;
- devr->s0->ext.xrc.cq = devr->c0;
+ devr->s0->ext.cq = devr->c0;
atomic_inc(&devr->s0->ext.xrc.xrcd->usecnt);
- atomic_inc(&devr->s0->ext.xrc.cq->usecnt);
+ atomic_inc(&devr->s0->ext.cq->usecnt);
atomic_inc(&devr->p0->usecnt);
atomic_set(&devr->s0->usecnt, 0);
@@ -3078,9 +3263,9 @@ static int create_dev_resources(struct mlx5_ib_resources *devr)
devr->s1->event_handler = NULL;
devr->s1->srq_context = NULL;
devr->s1->srq_type = IB_SRQT_BASIC;
- devr->s1->ext.xrc.cq = devr->c0;
+ devr->s1->ext.cq = devr->c0;
atomic_inc(&devr->p0->usecnt);
- atomic_set(&devr->s0->usecnt, 0);
+ atomic_set(&devr->s1->usecnt, 0);
for (port = 0; port < ARRAY_SIZE(devr->ports); ++port) {
INIT_WORK(&devr->ports[port].pkey_change_work,
@@ -3173,13 +3358,13 @@ static int mlx5_port_immutable(struct ib_device *ibdev, u8 port_num,
return 0;
}
-static void get_dev_fw_str(struct ib_device *ibdev, char *str,
- size_t str_len)
+static void get_dev_fw_str(struct ib_device *ibdev, char *str)
{
struct mlx5_ib_dev *dev =
container_of(ibdev, struct mlx5_ib_dev, ib_dev);
- snprintf(str, str_len, "%d.%d.%04d", fw_rev_maj(dev->mdev),
- fw_rev_min(dev->mdev), fw_rev_sub(dev->mdev));
+ snprintf(str, IB_FW_VERSION_NAME_MAX, "%d.%d.%04d",
+ fw_rev_maj(dev->mdev), fw_rev_min(dev->mdev),
+ fw_rev_sub(dev->mdev));
}
static int mlx5_eth_lag_init(struct mlx5_ib_dev *dev)
@@ -3319,6 +3504,17 @@ static const struct mlx5_ib_counter cong_cnts[] = {
INIT_CONG_COUNTER(np_cnp_sent),
};
+static const struct mlx5_ib_counter extended_err_cnts[] = {
+ INIT_Q_COUNTER(resp_local_length_error),
+ INIT_Q_COUNTER(resp_cqe_error),
+ INIT_Q_COUNTER(req_cqe_error),
+ INIT_Q_COUNTER(req_remote_invalid_request),
+ INIT_Q_COUNTER(req_remote_access_errors),
+ INIT_Q_COUNTER(resp_remote_access_errors),
+ INIT_Q_COUNTER(resp_cqe_flush_error),
+ INIT_Q_COUNTER(req_cqe_flush_error),
+};
+
static void mlx5_ib_dealloc_counters(struct mlx5_ib_dev *dev)
{
unsigned int i;
@@ -3343,6 +3539,10 @@ static int __mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev,
if (MLX5_CAP_GEN(dev->mdev, retransmission_q_counters))
num_counters += ARRAY_SIZE(retrans_q_cnts);
+
+ if (MLX5_CAP_GEN(dev->mdev, enhanced_error_q_counters))
+ num_counters += ARRAY_SIZE(extended_err_cnts);
+
cnts->num_q_counters = num_counters;
if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) {
@@ -3392,6 +3592,13 @@ static void mlx5_ib_fill_counters(struct mlx5_ib_dev *dev,
}
}
+ if (MLX5_CAP_GEN(dev->mdev, enhanced_error_q_counters)) {
+ for (i = 0; i < ARRAY_SIZE(extended_err_cnts); i++, j++) {
+ names[j] = extended_err_cnts[i].name;
+ offsets[j] = extended_err_cnts[i].offset;
+ }
+ }
+
if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) {
for (i = 0; i < ARRAY_SIZE(cong_cnts); i++, j++) {
names[j] = cong_cnts[i].name;
@@ -3562,6 +3769,136 @@ mlx5_ib_alloc_rdma_netdev(struct ib_device *hca,
return netdev;
}
+static void delay_drop_debugfs_cleanup(struct mlx5_ib_dev *dev)
+{
+ if (!dev->delay_drop.dbg)
+ return;
+ debugfs_remove_recursive(dev->delay_drop.dbg->dir_debugfs);
+ kfree(dev->delay_drop.dbg);
+ dev->delay_drop.dbg = NULL;
+}
+
+static void cancel_delay_drop(struct mlx5_ib_dev *dev)
+{
+ if (!(dev->ib_dev.attrs.raw_packet_caps & IB_RAW_PACKET_CAP_DELAY_DROP))
+ return;
+
+ cancel_work_sync(&dev->delay_drop.delay_drop_work);
+ delay_drop_debugfs_cleanup(dev);
+}
+
+static ssize_t delay_drop_timeout_read(struct file *filp, char __user *buf,
+ size_t count, loff_t *pos)
+{
+ struct mlx5_ib_delay_drop *delay_drop = filp->private_data;
+ char lbuf[20];
+ int len;
+
+ len = snprintf(lbuf, sizeof(lbuf), "%u\n", delay_drop->timeout);
+ return simple_read_from_buffer(buf, count, pos, lbuf, len);
+}
+
+static ssize_t delay_drop_timeout_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *pos)
+{
+ struct mlx5_ib_delay_drop *delay_drop = filp->private_data;
+ u32 timeout;
+ u32 var;
+
+ if (kstrtouint_from_user(buf, count, 0, &var))
+ return -EFAULT;
+
+ timeout = min_t(u32, roundup(var, 100), MLX5_MAX_DELAY_DROP_TIMEOUT_MS *
+ 1000);
+ if (timeout != var)
+ mlx5_ib_dbg(delay_drop->dev, "Round delay drop timeout to %u usec\n",
+ timeout);
+
+ delay_drop->timeout = timeout;
+
+ return count;
+}
+
+static const struct file_operations fops_delay_drop_timeout = {
+ .owner = THIS_MODULE,
+ .open = simple_open,
+ .write = delay_drop_timeout_write,
+ .read = delay_drop_timeout_read,
+};
+
+static int delay_drop_debugfs_init(struct mlx5_ib_dev *dev)
+{
+ struct mlx5_ib_dbg_delay_drop *dbg;
+
+ if (!mlx5_debugfs_root)
+ return 0;
+
+ dbg = kzalloc(sizeof(*dbg), GFP_KERNEL);
+ if (!dbg)
+ return -ENOMEM;
+
+ dbg->dir_debugfs =
+ debugfs_create_dir("delay_drop",
+ dev->mdev->priv.dbg_root);
+ if (!dbg->dir_debugfs)
+ return -ENOMEM;
+
+ dbg->events_cnt_debugfs =
+ debugfs_create_atomic_t("num_timeout_events", 0400,
+ dbg->dir_debugfs,
+ &dev->delay_drop.events_cnt);
+ if (!dbg->events_cnt_debugfs)
+ goto out_debugfs;
+
+ dbg->rqs_cnt_debugfs =
+ debugfs_create_atomic_t("num_rqs", 0400,
+ dbg->dir_debugfs,
+ &dev->delay_drop.rqs_cnt);
+ if (!dbg->rqs_cnt_debugfs)
+ goto out_debugfs;
+
+ dbg->timeout_debugfs =
+ debugfs_create_file("timeout", 0600,
+ dbg->dir_debugfs,
+ &dev->delay_drop,
+ &fops_delay_drop_timeout);
+ if (!dbg->timeout_debugfs)
+ goto out_debugfs;
+
+ dev->delay_drop.dbg = dbg;
+
+ return 0;
+
+out_debugfs:
+ delay_drop_debugfs_cleanup(dev);
+ return -ENOMEM;
+}
+
+static void init_delay_drop(struct mlx5_ib_dev *dev)
+{
+ if (!(dev->ib_dev.attrs.raw_packet_caps & IB_RAW_PACKET_CAP_DELAY_DROP))
+ return;
+
+ mutex_init(&dev->delay_drop.lock);
+ dev->delay_drop.dev = dev;
+ dev->delay_drop.activate = false;
+ dev->delay_drop.timeout = MLX5_MAX_DELAY_DROP_TIMEOUT_MS * 1000;
+ INIT_WORK(&dev->delay_drop.delay_drop_work, delay_drop_handler);
+ atomic_set(&dev->delay_drop.rqs_cnt, 0);
+ atomic_set(&dev->delay_drop.events_cnt, 0);
+
+ if (delay_drop_debugfs_init(dev))
+ mlx5_ib_warn(dev, "Failed to init delay drop debugfs\n");
+}
+
+static const struct cpumask *
+mlx5_ib_get_vector_affinity(struct ib_device *ibdev, int comp_vector)
+{
+ struct mlx5_ib_dev *dev = to_mdev(ibdev);
+
+ return mlx5_get_vector_affinity(dev->mdev, comp_vector);
+}
+
static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
{
struct mlx5_ib_dev *dev;
@@ -3692,6 +4029,7 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
dev->ib_dev.check_mr_status = mlx5_ib_check_mr_status;
dev->ib_dev.get_port_immutable = mlx5_port_immutable;
dev->ib_dev.get_dev_fw_str = get_dev_fw_str;
+ dev->ib_dev.get_vector_affinity = mlx5_ib_get_vector_affinity;
if (MLX5_CAP_GEN(mdev, ipoib_enhanced_offloads))
dev->ib_dev.alloc_rdma_netdev = mlx5_ib_alloc_rdma_netdev;
@@ -3729,18 +4067,20 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
(1ull << IB_USER_VERBS_CMD_CLOSE_XRCD);
}
+ dev->ib_dev.create_flow = mlx5_ib_create_flow;
+ dev->ib_dev.destroy_flow = mlx5_ib_destroy_flow;
+ dev->ib_dev.uverbs_ex_cmd_mask |=
+ (1ull << IB_USER_VERBS_EX_CMD_CREATE_FLOW) |
+ (1ull << IB_USER_VERBS_EX_CMD_DESTROY_FLOW);
+
if (mlx5_ib_port_link_layer(&dev->ib_dev, 1) ==
IB_LINK_LAYER_ETHERNET) {
- dev->ib_dev.create_flow = mlx5_ib_create_flow;
- dev->ib_dev.destroy_flow = mlx5_ib_destroy_flow;
dev->ib_dev.create_wq = mlx5_ib_create_wq;
dev->ib_dev.modify_wq = mlx5_ib_modify_wq;
dev->ib_dev.destroy_wq = mlx5_ib_destroy_wq;
dev->ib_dev.create_rwq_ind_table = mlx5_ib_create_rwq_ind_table;
dev->ib_dev.destroy_rwq_ind_table = mlx5_ib_destroy_rwq_ind_table;
dev->ib_dev.uverbs_ex_cmd_mask |=
- (1ull << IB_USER_VERBS_EX_CMD_CREATE_FLOW) |
- (1ull << IB_USER_VERBS_EX_CMD_DESTROY_FLOW) |
(1ull << IB_USER_VERBS_EX_CMD_CREATE_WQ) |
(1ull << IB_USER_VERBS_EX_CMD_MODIFY_WQ) |
(1ull << IB_USER_VERBS_EX_CMD_DESTROY_WQ) |
@@ -3760,6 +4100,7 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
err = mlx5_enable_eth(dev);
if (err)
goto err_free_port;
+ dev->roce.last_port_state = IB_PORT_DOWN;
}
err = create_dev_resources(&dev->devr);
@@ -3776,9 +4117,13 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
goto err_odp;
}
+ err = mlx5_ib_init_cong_debugfs(dev);
+ if (err)
+ goto err_cnt;
+
dev->mdev->priv.uar = mlx5_get_uars_page(dev->mdev);
if (!dev->mdev->priv.uar)
- goto err_cnt;
+ goto err_cong;
err = mlx5_alloc_bfreg(dev->mdev, &dev->bfreg, false, false);
if (err)
@@ -3796,18 +4141,25 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
if (err)
goto err_dev;
+ init_delay_drop(dev);
+
for (i = 0; i < ARRAY_SIZE(mlx5_class_attributes); i++) {
err = device_create_file(&dev->ib_dev.dev,
mlx5_class_attributes[i]);
if (err)
- goto err_umrc;
+ goto err_delay_drop;
}
+ if ((MLX5_CAP_GEN(mdev, port_type) == MLX5_CAP_PORT_TYPE_ETH) &&
+ MLX5_CAP_GEN(mdev, disable_local_lb))
+ mutex_init(&dev->lb_mutex);
+
dev->ib_active = true;
return dev;
-err_umrc:
+err_delay_drop:
+ cancel_delay_drop(dev);
destroy_umrc_res(dev);
err_dev:
@@ -3823,6 +4175,8 @@ err_uar_page:
mlx5_put_uars_page(dev->mdev, dev->mdev->priv.uar);
err_cnt:
+ mlx5_ib_cleanup_cong_debugfs(dev);
+err_cong:
if (MLX5_CAP_GEN(dev->mdev, max_qp_cnt))
mlx5_ib_dealloc_counters(dev);
@@ -3852,11 +4206,13 @@ static void mlx5_ib_remove(struct mlx5_core_dev *mdev, void *context)
struct mlx5_ib_dev *dev = context;
enum rdma_link_layer ll = mlx5_ib_port_link_layer(&dev->ib_dev, 1);
+ cancel_delay_drop(dev);
mlx5_remove_netdev_notifier(dev);
ib_unregister_device(&dev->ib_dev);
mlx5_free_bfreg(dev->mdev, &dev->fp_bfreg);
mlx5_free_bfreg(dev->mdev, &dev->bfreg);
mlx5_put_uars_page(dev->mdev, mdev->priv.uar);
+ mlx5_ib_cleanup_cong_debugfs(dev);
if (MLX5_CAP_GEN(dev->mdev, max_qp_cnt))
mlx5_ib_dealloc_counters(dev);
destroy_umrc_res(dev);
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index bdcf254..189e80c 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -107,6 +107,11 @@ enum {
MLX5_CQE_VERSION_V1,
};
+enum {
+ MLX5_TM_MAX_RNDV_MSG_SIZE = 64,
+ MLX5_TM_MAX_SGE = 1,
+};
+
struct mlx5_ib_vma_private_data {
struct list_head list;
struct vm_area_struct *vma;
@@ -247,6 +252,10 @@ struct mlx5_ib_wq {
void *qend;
};
+enum mlx5_ib_wq_flags {
+ MLX5_IB_WQ_FLAGS_DELAY_DROP = 0x1,
+};
+
struct mlx5_ib_rwq {
struct ib_wq ibwq;
struct mlx5_core_qp core_qp;
@@ -264,6 +273,7 @@ struct mlx5_ib_rwq {
u32 wqe_count;
u32 wqe_shift;
int wq_sig;
+ u32 create_flags; /* Use enum mlx5_ib_wq_flags */
};
enum {
@@ -378,6 +388,7 @@ struct mlx5_ib_qp {
struct list_head cq_recv_list;
struct list_head cq_send_list;
u32 rate_limit;
+ u32 underlay_qpn;
};
struct mlx5_ib_cq_buf {
@@ -399,6 +410,7 @@ enum mlx5_ib_qp_flags {
MLX5_IB_QP_CAP_SCATTER_FCS = 1 << 7,
MLX5_IB_QP_RSS = 1 << 8,
MLX5_IB_QP_CVLAN_STRIPPING = 1 << 9,
+ MLX5_IB_QP_UNDERLAY = 1 << 10,
};
struct mlx5_umr_wr {
@@ -496,7 +508,7 @@ struct mlx5_ib_mr {
struct mlx5_shared_mr_info *smr_info;
struct list_head list;
int order;
- int umred;
+ bool allocated_from_cache;
int npages;
struct mlx5_ib_dev *dev;
u32 out[MLX5_ST_SZ_DW(create_mkey_out)];
@@ -616,6 +628,63 @@ struct mlx5_roce {
struct net_device *netdev;
struct notifier_block nb;
atomic_t next_port;
+ enum ib_port_state last_port_state;
+};
+
+struct mlx5_ib_dbg_param {
+ int offset;
+ struct mlx5_ib_dev *dev;
+ struct dentry *dentry;
+};
+
+enum mlx5_ib_dbg_cc_types {
+ MLX5_IB_DBG_CC_RP_CLAMP_TGT_RATE,
+ MLX5_IB_DBG_CC_RP_CLAMP_TGT_RATE_ATI,
+ MLX5_IB_DBG_CC_RP_TIME_RESET,
+ MLX5_IB_DBG_CC_RP_BYTE_RESET,
+ MLX5_IB_DBG_CC_RP_THRESHOLD,
+ MLX5_IB_DBG_CC_RP_AI_RATE,
+ MLX5_IB_DBG_CC_RP_HAI_RATE,
+ MLX5_IB_DBG_CC_RP_MIN_DEC_FAC,
+ MLX5_IB_DBG_CC_RP_MIN_RATE,
+ MLX5_IB_DBG_CC_RP_RATE_TO_SET_ON_FIRST_CNP,
+ MLX5_IB_DBG_CC_RP_DCE_TCP_G,
+ MLX5_IB_DBG_CC_RP_DCE_TCP_RTT,
+ MLX5_IB_DBG_CC_RP_RATE_REDUCE_MONITOR_PERIOD,
+ MLX5_IB_DBG_CC_RP_INITIAL_ALPHA_VALUE,
+ MLX5_IB_DBG_CC_RP_GD,
+ MLX5_IB_DBG_CC_NP_CNP_DSCP,
+ MLX5_IB_DBG_CC_NP_CNP_PRIO_MODE,
+ MLX5_IB_DBG_CC_NP_CNP_PRIO,
+ MLX5_IB_DBG_CC_MAX,
+};
+
+struct mlx5_ib_dbg_cc_params {
+ struct dentry *root;
+ struct mlx5_ib_dbg_param params[MLX5_IB_DBG_CC_MAX];
+};
+
+enum {
+ MLX5_MAX_DELAY_DROP_TIMEOUT_MS = 100,
+};
+
+struct mlx5_ib_dbg_delay_drop {
+ struct dentry *dir_debugfs;
+ struct dentry *rqs_cnt_debugfs;
+ struct dentry *events_cnt_debugfs;
+ struct dentry *timeout_debugfs;
+};
+
+struct mlx5_ib_delay_drop {
+ struct mlx5_ib_dev *dev;
+ struct work_struct delay_drop_work;
+ /* serialize setting of delay drop */
+ struct mutex lock;
+ u32 timeout;
+ bool activate;
+ atomic_t events_cnt;
+ atomic_t rqs_cnt;
+ struct mlx5_ib_dbg_delay_drop *dbg;
};
struct mlx5_ib_dev {
@@ -652,9 +721,15 @@ struct mlx5_ib_dev {
struct list_head qp_list;
/* Array with num_ports elements */
struct mlx5_ib_port *port;
- struct mlx5_sq_bfreg bfreg;
- struct mlx5_sq_bfreg fp_bfreg;
- u8 umr_fence;
+ struct mlx5_sq_bfreg bfreg;
+ struct mlx5_sq_bfreg fp_bfreg;
+ struct mlx5_ib_delay_drop delay_drop;
+ struct mlx5_ib_dbg_cc_params *dbg_cc_params;
+
+ /* protect the user_td */
+ struct mutex lb_mutex;
+ u32 user_td;
+ u8 umr_fence;
};
static inline struct mlx5_ib_cq *to_mibcq(struct mlx5_core_cq *mcq)
@@ -904,6 +979,9 @@ __be16 mlx5_get_roce_udp_sport(struct mlx5_ib_dev *dev, u8 port_num,
int mlx5_get_roce_gid_type(struct mlx5_ib_dev *dev, u8 port_num,
int index, enum ib_gid_type *gid_type);
+void mlx5_ib_cleanup_cong_debugfs(struct mlx5_ib_dev *dev);
+int mlx5_ib_init_cong_debugfs(struct mlx5_ib_dev *dev);
+
/* GSI QP helper functions */
struct ib_qp *mlx5_ib_gsi_create_qp(struct ib_pd *pd,
struct ib_qp_init_attr *init_attr);
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
index 2c40a2e..0e2789d 100644
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -48,7 +48,7 @@ enum {
#define MLX5_UMR_ALIGN 2048
static int clean_mr(struct mlx5_ib_mr *mr);
-static int use_umr(struct mlx5_ib_dev *dev, int order);
+static int mr_cache_max_order(struct mlx5_ib_dev *dev);
static int unreg_umr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr);
static int destroy_mkey(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr)
@@ -183,7 +183,7 @@ static int add_keys(struct mlx5_ib_dev *dev, int c, int num)
break;
}
mr->order = ent->order;
- mr->umred = 1;
+ mr->allocated_from_cache = 1;
mr->dev = dev;
MLX5_SET(mkc, mkc, free, 1);
@@ -491,16 +491,18 @@ static struct mlx5_ib_mr *alloc_cached_mr(struct mlx5_ib_dev *dev, int order)
struct mlx5_mr_cache *cache = &dev->cache;
struct mlx5_ib_mr *mr = NULL;
struct mlx5_cache_ent *ent;
+ int last_umr_cache_entry;
int c;
int i;
c = order2idx(dev, order);
- if (c < 0 || c > MAX_UMR_CACHE_ENTRY) {
+ last_umr_cache_entry = order2idx(dev, mr_cache_max_order(dev));
+ if (c < 0 || c > last_umr_cache_entry) {
mlx5_ib_warn(dev, "order %d, cache index %d\n", order, c);
return NULL;
}
- for (i = c; i < MAX_UMR_CACHE_ENTRY; i++) {
+ for (i = c; i <= last_umr_cache_entry; i++) {
ent = &cache->ent[i];
mlx5_ib_dbg(dev, "order %d, cache index %d\n", ent->order, i);
@@ -674,12 +676,12 @@ int mlx5_mr_cache_init(struct mlx5_ib_dev *dev)
INIT_DELAYED_WORK(&ent->dwork, delayed_cache_work_func);
queue_work(cache->wq, &ent->work);
- if (i > MAX_UMR_CACHE_ENTRY) {
+ if (i > MR_CACHE_LAST_STD_ENTRY) {
mlx5_odp_init_mr_cache_entry(ent);
continue;
}
- if (!use_umr(dev, ent->order))
+ if (ent->order > mr_cache_max_order(dev))
continue;
ent->page = PAGE_SHIFT;
@@ -806,21 +808,22 @@ err_free:
return ERR_PTR(err);
}
-static int get_octo_len(u64 addr, u64 len, int page_size)
+static int get_octo_len(u64 addr, u64 len, int page_shift)
{
+ u64 page_size = 1ULL << page_shift;
u64 offset;
int npages;
offset = addr & (page_size - 1);
- npages = ALIGN(len + offset, page_size) >> ilog2(page_size);
+ npages = ALIGN(len + offset, page_size) >> page_shift;
return (npages + 1) / 2;
}
-static int use_umr(struct mlx5_ib_dev *dev, int order)
+static int mr_cache_max_order(struct mlx5_ib_dev *dev)
{
if (MLX5_CAP_GEN(dev->mdev, umr_extended_translation_offset))
- return order <= MAX_UMR_CACHE_ENTRY + 2;
- return order <= MLX5_MAX_UMR_SHIFT;
+ return MR_CACHE_LAST_STD_ENTRY + 2;
+ return MLX5_MAX_UMR_SHIFT;
}
static int mr_umem_get(struct ib_pd *pd, u64 start, u64 length,
@@ -896,7 +899,8 @@ static int mlx5_ib_post_send_wait(struct mlx5_ib_dev *dev,
return err;
}
-static struct mlx5_ib_mr *reg_umr(struct ib_pd *pd, struct ib_umem *umem,
+static struct mlx5_ib_mr *alloc_mr_from_cache(
+ struct ib_pd *pd, struct ib_umem *umem,
u64 virt_addr, u64 len, int npages,
int page_shift, int order, int access_flags)
{
@@ -928,16 +932,6 @@ static struct mlx5_ib_mr *reg_umr(struct ib_pd *pd, struct ib_umem *umem,
mr->mmkey.size = len;
mr->mmkey.pd = to_mpd(pd)->pdn;
- err = mlx5_ib_update_xlt(mr, 0, npages, page_shift,
- MLX5_IB_UPD_XLT_ENABLE);
-
- if (err) {
- mlx5_mr_cache_free(dev, mr);
- return ERR_PTR(err);
- }
-
- mr->live = 1;
-
return mr;
}
@@ -1103,7 +1097,8 @@ free_xlt:
static struct mlx5_ib_mr *reg_create(struct ib_mr *ibmr, struct ib_pd *pd,
u64 virt_addr, u64 length,
struct ib_umem *umem, int npages,
- int page_shift, int access_flags)
+ int page_shift, int access_flags,
+ bool populate)
{
struct mlx5_ib_dev *dev = to_mdev(pd->device);
struct mlx5_ib_mr *mr;
@@ -1118,15 +1113,19 @@ static struct mlx5_ib_mr *reg_create(struct ib_mr *ibmr, struct ib_pd *pd,
if (!mr)
return ERR_PTR(-ENOMEM);
- inlen = MLX5_ST_SZ_BYTES(create_mkey_in) +
- sizeof(*pas) * ((npages + 1) / 2) * 2;
+ mr->ibmr.pd = pd;
+ mr->access_flags = access_flags;
+
+ inlen = MLX5_ST_SZ_BYTES(create_mkey_in);
+ if (populate)
+ inlen += sizeof(*pas) * roundup(npages, 2);
in = kvzalloc(inlen, GFP_KERNEL);
if (!in) {
err = -ENOMEM;
goto err_1;
}
pas = (__be64 *)MLX5_ADDR_OF(create_mkey_in, in, klm_pas_mtt);
- if (!(access_flags & IB_ACCESS_ON_DEMAND))
+ if (populate && !(access_flags & IB_ACCESS_ON_DEMAND))
mlx5_ib_populate_pas(dev, umem, page_shift, pas,
pg_cap ? MLX5_IB_MTT_PRESENT : 0);
@@ -1135,23 +1134,27 @@ static struct mlx5_ib_mr *reg_create(struct ib_mr *ibmr, struct ib_pd *pd,
MLX5_SET(create_mkey_in, in, pg_access, !!(pg_cap));
mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry);
+ MLX5_SET(mkc, mkc, free, !populate);
MLX5_SET(mkc, mkc, access_mode, MLX5_MKC_ACCESS_MODE_MTT);
MLX5_SET(mkc, mkc, a, !!(access_flags & IB_ACCESS_REMOTE_ATOMIC));
MLX5_SET(mkc, mkc, rw, !!(access_flags & IB_ACCESS_REMOTE_WRITE));
MLX5_SET(mkc, mkc, rr, !!(access_flags & IB_ACCESS_REMOTE_READ));
MLX5_SET(mkc, mkc, lw, !!(access_flags & IB_ACCESS_LOCAL_WRITE));
MLX5_SET(mkc, mkc, lr, 1);
+ MLX5_SET(mkc, mkc, umr_en, 1);
MLX5_SET64(mkc, mkc, start_addr, virt_addr);
MLX5_SET64(mkc, mkc, len, length);
MLX5_SET(mkc, mkc, pd, to_mpd(pd)->pdn);
MLX5_SET(mkc, mkc, bsf_octword_size, 0);
MLX5_SET(mkc, mkc, translations_octword_size,
- get_octo_len(virt_addr, length, 1 << page_shift));
+ get_octo_len(virt_addr, length, page_shift));
MLX5_SET(mkc, mkc, log_page_size, page_shift);
MLX5_SET(mkc, mkc, qpn, 0xffffff);
- MLX5_SET(create_mkey_in, in, translations_octword_actual_size,
- get_octo_len(virt_addr, length, 1 << page_shift));
+ if (populate) {
+ MLX5_SET(create_mkey_in, in, translations_octword_actual_size,
+ get_octo_len(virt_addr, length, page_shift));
+ }
err = mlx5_core_create_mkey(dev->mdev, &mr->mmkey, in, inlen);
if (err) {
@@ -1160,9 +1163,7 @@ static struct mlx5_ib_mr *reg_create(struct ib_mr *ibmr, struct ib_pd *pd,
}
mr->mmkey.type = MLX5_MKEY_MR;
mr->desc_size = sizeof(struct mlx5_mtt);
- mr->umem = umem;
mr->dev = dev;
- mr->live = 1;
kvfree(in);
mlx5_ib_dbg(dev, "mkey = 0x%x\n", mr->mmkey.key);
@@ -1202,6 +1203,7 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
int ncont;
int order;
int err;
+ bool use_umr = true;
mlx5_ib_dbg(dev, "start 0x%llx, virt_addr 0x%llx, length 0x%llx, access_flags 0x%x\n",
start, virt_addr, length, access_flags);
@@ -1220,27 +1222,29 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
err = mr_umem_get(pd, start, length, access_flags, &umem, &npages,
&page_shift, &ncont, &order);
- if (err < 0)
+ if (err < 0)
return ERR_PTR(err);
- if (use_umr(dev, order)) {
- mr = reg_umr(pd, umem, virt_addr, length, ncont, page_shift,
- order, access_flags);
+ if (order <= mr_cache_max_order(dev)) {
+ mr = alloc_mr_from_cache(pd, umem, virt_addr, length, ncont,
+ page_shift, order, access_flags);
if (PTR_ERR(mr) == -EAGAIN) {
mlx5_ib_dbg(dev, "cache empty for order %d", order);
mr = NULL;
}
- } else if (access_flags & IB_ACCESS_ON_DEMAND &&
- !MLX5_CAP_GEN(dev->mdev, umr_extended_translation_offset)) {
- err = -EINVAL;
- pr_err("Got MR registration for ODP MR > 512MB, not supported for Connect-IB");
- goto error;
+ } else if (!MLX5_CAP_GEN(dev->mdev, umr_extended_translation_offset)) {
+ if (access_flags & IB_ACCESS_ON_DEMAND) {
+ err = -EINVAL;
+ pr_err("Got MR registration for ODP MR > 512MB, not supported for Connect-IB");
+ goto error;
+ }
+ use_umr = false;
}
if (!mr) {
mutex_lock(&dev->slow_path_mutex);
mr = reg_create(NULL, pd, virt_addr, length, umem, ncont,
- page_shift, access_flags);
+ page_shift, access_flags, !use_umr);
mutex_unlock(&dev->slow_path_mutex);
}
@@ -1258,8 +1262,22 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
update_odp_mr(mr);
#endif
- return &mr->ibmr;
+ if (use_umr) {
+ int update_xlt_flags = MLX5_IB_UPD_XLT_ENABLE;
+ if (access_flags & IB_ACCESS_ON_DEMAND)
+ update_xlt_flags |= MLX5_IB_UPD_XLT_ZAP;
+
+ err = mlx5_ib_update_xlt(mr, 0, ncont, page_shift,
+ update_xlt_flags);
+ if (err) {
+ mlx5_ib_dereg_mr(&mr->ibmr);
+ return ERR_PTR(err);
+ }
+ }
+
+ mr->live = 1;
+ return &mr->ibmr;
error:
ib_umem_release(umem);
return ERR_PTR(err);
@@ -1347,7 +1365,7 @@ int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start,
/*
* UMR can't be used - MKey needs to be replaced.
*/
- if (mr->umred) {
+ if (mr->allocated_from_cache) {
err = unreg_umr(dev, mr);
if (err)
mlx5_ib_warn(dev, "Failed to unregister MR\n");
@@ -1360,12 +1378,13 @@ int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start,
return err;
mr = reg_create(ib_mr, pd, addr, len, mr->umem, ncont,
- page_shift, access_flags);
+ page_shift, access_flags, true);
if (IS_ERR(mr))
return PTR_ERR(mr);
- mr->umred = 0;
+ mr->allocated_from_cache = 0;
+ mr->live = 1;
} else {
/*
* Send a UMR WQE
@@ -1453,7 +1472,7 @@ mlx5_free_priv_descs(struct mlx5_ib_mr *mr)
static int clean_mr(struct mlx5_ib_mr *mr)
{
struct mlx5_ib_dev *dev = to_mdev(mr->ibmr.device);
- int umred = mr->umred;
+ int allocated_from_cache = mr->allocated_from_cache;
int err;
if (mr->sig) {
@@ -1471,20 +1490,20 @@ static int clean_mr(struct mlx5_ib_mr *mr)
mlx5_free_priv_descs(mr);
- if (!umred) {
+ if (!allocated_from_cache) {
+ u32 key = mr->mmkey.key;
+
err = destroy_mkey(dev, mr);
+ kfree(mr);
if (err) {
mlx5_ib_warn(dev, "failed to destroy mkey 0x%x (%d)\n",
- mr->mmkey.key, err);
+ key, err);
return err;
}
} else {
mlx5_mr_cache_free(dev, mr);
}
- if (!umred)
- kfree(mr);
-
return 0;
}
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index f58f8f5..acb79d3 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -34,6 +34,7 @@
#include <rdma/ib_umem.h>
#include <rdma/ib_cache.h>
#include <rdma/ib_user_verbs.h>
+#include <linux/mlx5/fs.h>
#include "mlx5_ib.h"
/* not supported currently */
@@ -453,7 +454,8 @@ static int set_user_buf_size(struct mlx5_ib_dev *dev,
return -EINVAL;
}
- if (attr->qp_type == IB_QPT_RAW_PACKET) {
+ if (attr->qp_type == IB_QPT_RAW_PACKET ||
+ qp->flags & MLX5_IB_QP_UNDERLAY) {
base->ubuffer.buf_size = qp->rq.wqe_cnt << qp->rq.wqe_shift;
qp->raw_packet_qp.sq.ubuffer.buf_size = qp->sq.wqe_cnt << 6;
} else {
@@ -675,10 +677,14 @@ err_umem:
return err;
}
-static void destroy_user_rq(struct ib_pd *pd, struct mlx5_ib_rwq *rwq)
+static void destroy_user_rq(struct mlx5_ib_dev *dev, struct ib_pd *pd,
+ struct mlx5_ib_rwq *rwq)
{
struct mlx5_ib_ucontext *context;
+ if (rwq->create_flags & MLX5_IB_WQ_FLAGS_DELAY_DROP)
+ atomic_dec(&dev->delay_drop.rqs_cnt);
+
context = to_mucontext(pd->uobject->context);
mlx5_ib_db_unmap_user(context, &rwq->db);
if (rwq->umem)
@@ -959,11 +965,16 @@ static int create_kernel_qp(struct mlx5_ib_dev *dev,
goto err_free;
}
- qp->sq.wrid = kmalloc(qp->sq.wqe_cnt * sizeof(*qp->sq.wrid), GFP_KERNEL);
- qp->sq.wr_data = kmalloc(qp->sq.wqe_cnt * sizeof(*qp->sq.wr_data), GFP_KERNEL);
- qp->rq.wrid = kmalloc(qp->rq.wqe_cnt * sizeof(*qp->rq.wrid), GFP_KERNEL);
- qp->sq.w_list = kmalloc(qp->sq.wqe_cnt * sizeof(*qp->sq.w_list), GFP_KERNEL);
- qp->sq.wqe_head = kmalloc(qp->sq.wqe_cnt * sizeof(*qp->sq.wqe_head), GFP_KERNEL);
+ qp->sq.wrid = kvmalloc_array(qp->sq.wqe_cnt,
+ sizeof(*qp->sq.wrid), GFP_KERNEL);
+ qp->sq.wr_data = kvmalloc_array(qp->sq.wqe_cnt,
+ sizeof(*qp->sq.wr_data), GFP_KERNEL);
+ qp->rq.wrid = kvmalloc_array(qp->rq.wqe_cnt,
+ sizeof(*qp->rq.wrid), GFP_KERNEL);
+ qp->sq.w_list = kvmalloc_array(qp->sq.wqe_cnt,
+ sizeof(*qp->sq.w_list), GFP_KERNEL);
+ qp->sq.wqe_head = kvmalloc_array(qp->sq.wqe_cnt,
+ sizeof(*qp->sq.wqe_head), GFP_KERNEL);
if (!qp->sq.wrid || !qp->sq.wr_data || !qp->rq.wrid ||
!qp->sq.w_list || !qp->sq.wqe_head) {
@@ -975,11 +986,11 @@ static int create_kernel_qp(struct mlx5_ib_dev *dev,
return 0;
err_wrid:
- kfree(qp->sq.wqe_head);
- kfree(qp->sq.w_list);
- kfree(qp->sq.wrid);
- kfree(qp->sq.wr_data);
- kfree(qp->rq.wrid);
+ kvfree(qp->sq.wqe_head);
+ kvfree(qp->sq.w_list);
+ kvfree(qp->sq.wrid);
+ kvfree(qp->sq.wr_data);
+ kvfree(qp->rq.wrid);
mlx5_db_free(dev->mdev, &qp->db);
err_free:
@@ -992,11 +1003,11 @@ err_buf:
static void destroy_qp_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp)
{
- kfree(qp->sq.wqe_head);
- kfree(qp->sq.w_list);
- kfree(qp->sq.wrid);
- kfree(qp->sq.wr_data);
- kfree(qp->rq.wrid);
+ kvfree(qp->sq.wqe_head);
+ kvfree(qp->sq.w_list);
+ kvfree(qp->sq.wrid);
+ kvfree(qp->sq.wr_data);
+ kvfree(qp->rq.wrid);
mlx5_db_free(dev->mdev, &qp->db);
mlx5_buf_free(dev->mdev, &qp->buf);
}
@@ -1021,12 +1032,16 @@ static int is_connected(enum ib_qp_type qp_type)
}
static int create_raw_packet_qp_tis(struct mlx5_ib_dev *dev,
+ struct mlx5_ib_qp *qp,
struct mlx5_ib_sq *sq, u32 tdn)
{
u32 in[MLX5_ST_SZ_DW(create_tis_in)] = {0};
void *tisc = MLX5_ADDR_OF(create_tis_in, in, ctx);
MLX5_SET(tisc, tisc, transport_domain, tdn);
+ if (qp->flags & MLX5_IB_QP_UNDERLAY)
+ MLX5_SET(tisc, tisc, underlay_qpn, qp->underlay_qpn);
+
return mlx5_core_create_tis(dev->mdev, in, sizeof(in), &sq->tisn);
}
@@ -1068,11 +1083,16 @@ static int create_raw_packet_qp_sq(struct mlx5_ib_dev *dev,
sqc = MLX5_ADDR_OF(create_sq_in, in, ctx);
MLX5_SET(sqc, sqc, flush_in_error_en, 1);
+ if (MLX5_CAP_ETH(dev->mdev, multi_pkt_send_wqe))
+ MLX5_SET(sqc, sqc, allow_multi_pkt_send_wqe, 1);
MLX5_SET(sqc, sqc, state, MLX5_SQC_STATE_RST);
MLX5_SET(sqc, sqc, user_index, MLX5_GET(qpc, qpc, user_index));
MLX5_SET(sqc, sqc, cqn, MLX5_GET(qpc, qpc, cqn_snd));
MLX5_SET(sqc, sqc, tis_lst_sz, 1);
MLX5_SET(sqc, sqc, tis_num_0, sq->tisn);
+ if (MLX5_CAP_GEN(dev->mdev, eth_net_offloads) &&
+ MLX5_CAP_ETH(dev->mdev, swp))
+ MLX5_SET(sqc, sqc, allow_swp, 1);
wq = MLX5_ADDR_OF(sqc, sqc, wq);
MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_CYCLIC);
@@ -1229,7 +1249,7 @@ static int create_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
u32 tdn = mucontext->tdn;
if (qp->sq.wqe_cnt) {
- err = create_raw_packet_qp_tis(dev, sq, tdn);
+ err = create_raw_packet_qp_tis(dev, qp, sq, tdn);
if (err)
return err;
@@ -1503,10 +1523,6 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
u32 *in;
int err;
- base = init_attr->qp_type == IB_QPT_RAW_PACKET ?
- &qp->raw_packet_qp.rq.base :
- &qp->trans_qp.base;
-
mutex_init(&qp->mutex);
spin_lock_init(&qp->sq.lock);
spin_lock_init(&qp->rq.lock);
@@ -1588,10 +1604,28 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
qp->wq_sig = !!(ucmd.flags & MLX5_QP_FLAG_SIGNATURE);
qp->scat_cqe = !!(ucmd.flags & MLX5_QP_FLAG_SCATTER_CQE);
+
+ if (init_attr->create_flags & IB_QP_CREATE_SOURCE_QPN) {
+ if (init_attr->qp_type != IB_QPT_UD ||
+ (MLX5_CAP_GEN(dev->mdev, port_type) !=
+ MLX5_CAP_PORT_TYPE_IB) ||
+ !mlx5_get_flow_namespace(dev->mdev, MLX5_FLOW_NAMESPACE_BYPASS)) {
+ mlx5_ib_dbg(dev, "Source QP option isn't supported\n");
+ return -EOPNOTSUPP;
+ }
+
+ qp->flags |= MLX5_IB_QP_UNDERLAY;
+ qp->underlay_qpn = init_attr->source_qpn;
+ }
} else {
qp->wq_sig = !!wq_signature;
}
+ base = (init_attr->qp_type == IB_QPT_RAW_PACKET ||
+ qp->flags & MLX5_IB_QP_UNDERLAY) ?
+ &qp->raw_packet_qp.rq.base :
+ &qp->trans_qp.base;
+
qp->has_rq = qp_has_rq(init_attr);
err = set_rq_size(dev, &init_attr->cap, qp->has_rq,
qp, (pd && pd->uobject) ? &ucmd : NULL);
@@ -1695,10 +1729,15 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
MLX5_SET(qpc, qpc, rq_type, get_rx_type(qp, init_attr));
- if (qp->sq.wqe_cnt)
+ if (qp->sq.wqe_cnt) {
MLX5_SET(qpc, qpc, log_sq_size, ilog2(qp->sq.wqe_cnt));
- else
+ } else {
MLX5_SET(qpc, qpc, no_sq, 1);
+ if (init_attr->srq &&
+ init_attr->srq->srq_type == IB_SRQT_TM)
+ MLX5_SET(qpc, qpc, offload_type,
+ MLX5_QPC_OFFLOAD_TYPE_RNDV);
+ }
/* Set default resources */
switch (init_attr->qp_type) {
@@ -1742,7 +1781,8 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
qp->flags |= MLX5_IB_QP_LSO;
}
- if (init_attr->qp_type == IB_QPT_RAW_PACKET) {
+ if (init_attr->qp_type == IB_QPT_RAW_PACKET ||
+ qp->flags & MLX5_IB_QP_UNDERLAY) {
qp->raw_packet_qp.sq.ubuffer.buf_addr = ucmd.sq_buf_addr;
raw_packet_qp_copy_info(qp, &qp->raw_packet_qp);
err = create_raw_packet_qp(dev, qp, in, pd);
@@ -1894,7 +1934,7 @@ static int modify_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp)
{
struct mlx5_ib_cq *send_cq, *recv_cq;
- struct mlx5_ib_qp_base *base = &qp->trans_qp.base;
+ struct mlx5_ib_qp_base *base;
unsigned long flags;
int err;
@@ -1903,12 +1943,14 @@ static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp)
return;
}
- base = qp->ibqp.qp_type == IB_QPT_RAW_PACKET ?
+ base = (qp->ibqp.qp_type == IB_QPT_RAW_PACKET ||
+ qp->flags & MLX5_IB_QP_UNDERLAY) ?
&qp->raw_packet_qp.rq.base :
&qp->trans_qp.base;
if (qp->state != IB_QPS_RESET) {
- if (qp->ibqp.qp_type != IB_QPT_RAW_PACKET) {
+ if (qp->ibqp.qp_type != IB_QPT_RAW_PACKET &&
+ !(qp->flags & MLX5_IB_QP_UNDERLAY)) {
err = mlx5_core_qp_modify(dev->mdev,
MLX5_CMD_OP_2RST_QP, 0,
NULL, &base->mqp);
@@ -1947,7 +1989,8 @@ static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp)
mlx5_ib_unlock_cqs(send_cq, recv_cq);
spin_unlock_irqrestore(&dev->reset_flow_resource_lock, flags);
- if (qp->ibqp.qp_type == IB_QPT_RAW_PACKET) {
+ if (qp->ibqp.qp_type == IB_QPT_RAW_PACKET ||
+ qp->flags & MLX5_IB_QP_UNDERLAY) {
destroy_raw_packet_qp(dev, qp);
} else {
err = mlx5_core_destroy_qp(dev->mdev, &base->mqp);
@@ -2703,7 +2746,8 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
if (is_sqp(ibqp->qp_type)) {
context->mtu_msgmax = (IB_MTU_256 << 5) | 8;
- } else if (ibqp->qp_type == IB_QPT_UD ||
+ } else if ((ibqp->qp_type == IB_QPT_UD &&
+ !(qp->flags & MLX5_IB_QP_UNDERLAY)) ||
ibqp->qp_type == MLX5_IB_QPT_REG_UMR) {
context->mtu_msgmax = (IB_MTU_4096 << 5) | 12;
} else if (attr_mask & IB_QP_PATH_MTU) {
@@ -2800,6 +2844,11 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
u8 port_num = (attr_mask & IB_QP_PORT ? attr->port_num :
qp->port) - 1;
+
+ /* Underlay port should be used - index 0 function per port */
+ if (qp->flags & MLX5_IB_QP_UNDERLAY)
+ port_num = 0;
+
mibport = &dev->port[port_num];
context->qp_counter_set_usr_page |=
cpu_to_be32((u32)(mibport->cnts.set_id) << 24);
@@ -2825,7 +2874,8 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
optpar = ib_mask_to_mlx5_opt(attr_mask);
optpar &= opt_mask[mlx5_cur][mlx5_new][mlx5_st];
- if (qp->ibqp.qp_type == IB_QPT_RAW_PACKET) {
+ if (qp->ibqp.qp_type == IB_QPT_RAW_PACKET ||
+ qp->flags & MLX5_IB_QP_UNDERLAY) {
struct mlx5_modify_raw_qp_param raw_qp_param = {};
raw_qp_param.operation = op;
@@ -2914,7 +2964,13 @@ int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
ll = dev->ib_dev.get_link_layer(&dev->ib_dev, port);
}
- if (qp_type != MLX5_IB_QPT_REG_UMR &&
+ if (qp->flags & MLX5_IB_QP_UNDERLAY) {
+ if (attr_mask & ~(IB_QP_STATE | IB_QP_CUR_STATE)) {
+ mlx5_ib_dbg(dev, "invalid attr_mask 0x%x when underlay QP is used\n",
+ attr_mask);
+ goto out;
+ }
+ } else if (qp_type != MLX5_IB_QPT_REG_UMR &&
!ib_modify_qp_is_ok(cur_state, new_state, qp_type, attr_mask, ll)) {
mlx5_ib_dbg(dev, "invalid QP state transition from %d to %d, qp_type %d, attr_mask 0x%x\n",
cur_state, new_state, ibqp->qp_type, attr_mask);
@@ -4478,9 +4534,14 @@ int mlx5_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
return mlx5_ib_gsi_query_qp(ibqp, qp_attr, qp_attr_mask,
qp_init_attr);
+ /* Not all of output fields are applicable, make sure to zero them */
+ memset(qp_init_attr, 0, sizeof(*qp_init_attr));
+ memset(qp_attr, 0, sizeof(*qp_attr));
+
mutex_lock(&qp->mutex);
- if (qp->ibqp.qp_type == IB_QPT_RAW_PACKET) {
+ if (qp->ibqp.qp_type == IB_QPT_RAW_PACKET ||
+ qp->flags & MLX5_IB_QP_UNDERLAY) {
err = query_raw_packet_qp_state(dev, qp, &raw_packet_qp_state);
if (err)
goto out;
@@ -4598,6 +4659,27 @@ static void mlx5_ib_wq_event(struct mlx5_core_qp *core_qp, int type)
}
}
+static int set_delay_drop(struct mlx5_ib_dev *dev)
+{
+ int err = 0;
+
+ mutex_lock(&dev->delay_drop.lock);
+ if (dev->delay_drop.activate)
+ goto out;
+
+ err = mlx5_core_set_delay_drop(dev->mdev, dev->delay_drop.timeout);
+ if (err)
+ goto out;
+
+ dev->delay_drop.activate = true;
+out:
+ mutex_unlock(&dev->delay_drop.lock);
+
+ if (!err)
+ atomic_inc(&dev->delay_drop.rqs_cnt);
+ return err;
+}
+
static int create_rq(struct mlx5_ib_rwq *rwq, struct ib_pd *pd,
struct ib_wq_init_attr *init_attr)
{
@@ -4652,9 +4734,28 @@ static int create_rq(struct mlx5_ib_rwq *rwq, struct ib_pd *pd,
}
MLX5_SET(rqc, rqc, scatter_fcs, 1);
}
+ if (init_attr->create_flags & IB_WQ_FLAGS_DELAY_DROP) {
+ if (!(dev->ib_dev.attrs.raw_packet_caps &
+ IB_RAW_PACKET_CAP_DELAY_DROP)) {
+ mlx5_ib_dbg(dev, "Delay drop is not supported\n");
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+ MLX5_SET(rqc, rqc, delay_drop_en, 1);
+ }
rq_pas0 = (__be64 *)MLX5_ADDR_OF(wq, wq, pas);
mlx5_ib_populate_pas(dev, rwq->umem, rwq->page_shift, rq_pas0, 0);
err = mlx5_core_create_rq_tracked(dev->mdev, in, inlen, &rwq->core_qp);
+ if (!err && init_attr->create_flags & IB_WQ_FLAGS_DELAY_DROP) {
+ err = set_delay_drop(dev);
+ if (err) {
+ mlx5_ib_warn(dev, "Failed to enable delay drop err=%d\n",
+ err);
+ mlx5_core_destroy_rq_tracked(dev->mdev, &rwq->core_qp);
+ } else {
+ rwq->create_flags |= MLX5_IB_WQ_FLAGS_DELAY_DROP;
+ }
+ }
out:
kvfree(in);
return err;
@@ -4788,7 +4889,7 @@ struct ib_wq *mlx5_ib_create_wq(struct ib_pd *pd,
err_copy:
mlx5_core_destroy_rq_tracked(dev->mdev, &rwq->core_qp);
err_user_rq:
- destroy_user_rq(pd, rwq);
+ destroy_user_rq(dev, pd, rwq);
err:
kfree(rwq);
return ERR_PTR(err);
@@ -4800,7 +4901,7 @@ int mlx5_ib_destroy_wq(struct ib_wq *wq)
struct mlx5_ib_rwq *rwq = to_mrwq(wq);
mlx5_core_destroy_rq_tracked(dev->mdev, &rwq->core_qp);
- destroy_user_rq(wq->pd, rwq);
+ destroy_user_rq(dev, wq->pd, rwq);
kfree(rwq);
return 0;
diff --git a/drivers/infiniband/hw/mlx5/srq.c b/drivers/infiniband/hw/mlx5/srq.c
index 43707b1..6d5fada 100644
--- a/drivers/infiniband/hw/mlx5/srq.c
+++ b/drivers/infiniband/hw/mlx5/srq.c
@@ -101,7 +101,7 @@ static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq,
udata->inlen - sizeof(ucmd)))
return -EINVAL;
- if (in->type == IB_SRQT_XRC) {
+ if (in->type != IB_SRQT_BASIC) {
err = get_srq_user_index(to_mucontext(pd->uobject->context),
&ucmd, udata->inlen, &uidx);
if (err)
@@ -145,7 +145,7 @@ static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq,
in->log_page_size = page_shift - MLX5_ADAPTER_PAGE_SHIFT;
in->page_offset = offset;
if (MLX5_CAP_GEN(dev->mdev, cqe_version) == MLX5_CQE_VERSION_V1 &&
- in->type == IB_SRQT_XRC)
+ in->type != IB_SRQT_BASIC)
in->user_index = uidx;
return 0;
@@ -196,7 +196,7 @@ static int create_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq,
}
mlx5_fill_page_array(&srq->buf, in->pas);
- srq->wrid = kmalloc(srq->msrq.max * sizeof(u64), GFP_KERNEL);
+ srq->wrid = kvmalloc_array(srq->msrq.max, sizeof(u64), GFP_KERNEL);
if (!srq->wrid) {
err = -ENOMEM;
goto err_in;
@@ -205,7 +205,7 @@ static int create_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq,
in->log_page_size = srq->buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT;
if (MLX5_CAP_GEN(dev->mdev, cqe_version) == MLX5_CQE_VERSION_V1 &&
- in->type == IB_SRQT_XRC)
+ in->type != IB_SRQT_BASIC)
in->user_index = MLX5_IB_DEFAULT_UIDX;
return 0;
@@ -230,7 +230,7 @@ static void destroy_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq)
static void destroy_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq)
{
- kfree(srq->wrid);
+ kvfree(srq->wrid);
mlx5_buf_free(dev->mdev, &srq->buf);
mlx5_db_free(dev->mdev, &srq->db);
}
@@ -292,14 +292,29 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
in.wqe_shift = srq->msrq.wqe_shift - 4;
if (srq->wq_sig)
in.flags |= MLX5_SRQ_FLAG_WQ_SIG;
- if (init_attr->srq_type == IB_SRQT_XRC) {
+
+ if (init_attr->srq_type == IB_SRQT_XRC)
in.xrcd = to_mxrcd(init_attr->ext.xrc.xrcd)->xrcdn;
- in.cqn = to_mcq(init_attr->ext.xrc.cq)->mcq.cqn;
- } else if (init_attr->srq_type == IB_SRQT_BASIC) {
+ else
in.xrcd = to_mxrcd(dev->devr.x0)->xrcdn;
- in.cqn = to_mcq(dev->devr.c0)->mcq.cqn;
+
+ if (init_attr->srq_type == IB_SRQT_TM) {
+ in.tm_log_list_size =
+ ilog2(init_attr->ext.tag_matching.max_num_tags) + 1;
+ if (in.tm_log_list_size >
+ MLX5_CAP_GEN(dev->mdev, log_tag_matching_list_sz)) {
+ mlx5_ib_dbg(dev, "TM SRQ max_num_tags exceeding limit\n");
+ err = -EINVAL;
+ goto err_usr_kern_srq;
+ }
+ in.flags |= MLX5_SRQ_FLAG_RNDV;
}
+ if (ib_srq_has_cq(init_attr->srq_type))
+ in.cqn = to_mcq(init_attr->ext.cq)->mcq.cqn;
+ else
+ in.cqn = to_mcq(dev->devr.c0)->mcq.cqn;
+
in.pd = to_mpd(pd)->pdn;
in.db_record = srq->db.dma;
err = mlx5_core_create_srq(dev->mdev, &srq->msrq, &in);
diff --git a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c
index 2aec990..e7f6223 100644
--- a/drivers/infiniband/hw/mthca/mthca_av.c
+++ b/drivers/infiniband/hw/mthca/mthca_av.c
@@ -186,7 +186,7 @@ int mthca_create_ah(struct mthca_dev *dev,
on_hca_fail:
if (ah->type == MTHCA_AH_PCI_POOL) {
- ah->av = pci_pool_zalloc(dev->av_table.pool,
+ ah->av = dma_pool_zalloc(dev->av_table.pool,
GFP_ATOMIC, &ah->avdma);
if (!ah->av)
return -ENOMEM;
@@ -250,7 +250,7 @@ int mthca_destroy_ah(struct mthca_dev *dev, struct mthca_ah *ah)
break;
case MTHCA_AH_PCI_POOL:
- pci_pool_free(dev->av_table.pool, ah->av, ah->avdma);
+ dma_pool_free(dev->av_table.pool, ah->av, ah->avdma);
break;
case MTHCA_AH_KMALLOC:
@@ -340,7 +340,7 @@ int mthca_init_av_table(struct mthca_dev *dev)
if (err)
return err;
- dev->av_table.pool = pci_pool_create("mthca_av", dev->pdev,
+ dev->av_table.pool = dma_pool_create("mthca_av", &dev->pdev->dev,
MTHCA_AV_SIZE,
MTHCA_AV_SIZE, 0);
if (!dev->av_table.pool)
@@ -360,7 +360,7 @@ int mthca_init_av_table(struct mthca_dev *dev)
return 0;
out_free_pool:
- pci_pool_destroy(dev->av_table.pool);
+ dma_pool_destroy(dev->av_table.pool);
out_free_alloc:
mthca_alloc_cleanup(&dev->av_table.alloc);
@@ -374,6 +374,6 @@ void mthca_cleanup_av_table(struct mthca_dev *dev)
if (dev->av_table.av_map)
iounmap(dev->av_table.av_map);
- pci_pool_destroy(dev->av_table.pool);
+ dma_pool_destroy(dev->av_table.pool);
mthca_alloc_cleanup(&dev->av_table.alloc);
}
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index 9d83a53..419a2a2 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -538,7 +538,7 @@ int mthca_cmd_init(struct mthca_dev *dev)
return -ENOMEM;
}
- dev->cmd.pool = pci_pool_create("mthca_cmd", dev->pdev,
+ dev->cmd.pool = dma_pool_create("mthca_cmd", &dev->pdev->dev,
MTHCA_MAILBOX_SIZE,
MTHCA_MAILBOX_SIZE, 0);
if (!dev->cmd.pool) {
@@ -551,7 +551,7 @@ int mthca_cmd_init(struct mthca_dev *dev)
void mthca_cmd_cleanup(struct mthca_dev *dev)
{
- pci_pool_destroy(dev->cmd.pool);
+ dma_pool_destroy(dev->cmd.pool);
iounmap(dev->hcr);
if (dev->cmd.flags & MTHCA_CMD_POST_DOORBELLS)
iounmap(dev->cmd.dbell_map);
@@ -621,7 +621,7 @@ struct mthca_mailbox *mthca_alloc_mailbox(struct mthca_dev *dev,
if (!mailbox)
return ERR_PTR(-ENOMEM);
- mailbox->buf = pci_pool_alloc(dev->cmd.pool, gfp_mask, &mailbox->dma);
+ mailbox->buf = dma_pool_alloc(dev->cmd.pool, gfp_mask, &mailbox->dma);
if (!mailbox->buf) {
kfree(mailbox);
return ERR_PTR(-ENOMEM);
@@ -635,7 +635,7 @@ void mthca_free_mailbox(struct mthca_dev *dev, struct mthca_mailbox *mailbox)
if (!mailbox)
return;
- pci_pool_free(dev->cmd.pool, mailbox->buf, mailbox->dma);
+ dma_pool_free(dev->cmd.pool, mailbox->buf, mailbox->dma);
kfree(mailbox);
}
@@ -698,7 +698,7 @@ static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm,
for (i = 0; i < mthca_icm_size(&iter) >> lg; ++i) {
if (virt != -1) {
pages[nent * 2] = cpu_to_be64(virt);
- virt += 1 << lg;
+ virt += 1ULL << lg;
}
pages[nent * 2 + 1] =
@@ -1921,7 +1921,7 @@ int mthca_MAD_IFC(struct mthca_dev *dev, int ignore_mkey, int ignore_bkey,
(in_wc->wc_flags & IB_WC_GRH ? 0x80 : 0);
MTHCA_PUT(inbox, val, MAD_IFC_G_PATH_OFFSET);
- MTHCA_PUT(inbox, in_wc->slid, MAD_IFC_RLID_OFFSET);
+ MTHCA_PUT(inbox, ib_lid_cpu16(in_wc->slid), MAD_IFC_RLID_OFFSET);
MTHCA_PUT(inbox, in_wc->pkey_index, MAD_IFC_PKEY_OFFSET);
if (in_grh)
@@ -1929,7 +1929,7 @@ int mthca_MAD_IFC(struct mthca_dev *dev, int ignore_mkey, int ignore_bkey,
op_modifier |= 0x4;
- in_modifier |= in_wc->slid << 16;
+ in_modifier |= ib_lid_cpu16(in_wc->slid) << 16;
}
err = mthca_cmd_box(dev, inmailbox->dma, outmailbox->dma,
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
index ec7da9a..5508afb 100644
--- a/drivers/infiniband/hw/mthca/mthca_dev.h
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h
@@ -118,7 +118,7 @@ enum {
};
struct mthca_cmd {
- struct pci_pool *pool;
+ struct dma_pool *pool;
struct mutex hcr_mutex;
struct semaphore poll_sem;
struct semaphore event_sem;
@@ -263,7 +263,7 @@ struct mthca_qp_table {
};
struct mthca_av_table {
- struct pci_pool *pool;
+ struct dma_pool *pool;
int num_ddr_avs;
u64 ddr_av_base;
void __iomem *av_map;
diff --git a/drivers/infiniband/hw/mthca/mthca_mad.c b/drivers/infiniband/hw/mthca/mthca_mad.c
index 7df3db7..093f775 100644
--- a/drivers/infiniband/hw/mthca/mthca_mad.c
+++ b/drivers/infiniband/hw/mthca/mthca_mad.c
@@ -205,7 +205,7 @@ int mthca_process_mad(struct ib_device *ibdev,
u16 *out_mad_pkey_index)
{
int err;
- u16 slid = in_wc ? in_wc->slid : be16_to_cpu(IB_LID_PERMISSIVE);
+ u16 slid = in_wc ? ib_lid_cpu16(in_wc->slid) : be16_to_cpu(IB_LID_PERMISSIVE);
u16 prev_lid = 0;
struct ib_port_attr pattr;
const struct ib_mad *in_mad = (const struct ib_mad *)in;
@@ -256,7 +256,7 @@ int mthca_process_mad(struct ib_device *ibdev,
in_mad->mad_hdr.method == IB_MGMT_METHOD_SET &&
in_mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO &&
!ib_query_port(ibdev, port_num, &pattr))
- prev_lid = pattr.lid;
+ prev_lid = ib_lid_cpu16(pattr.lid);
err = mthca_MAD_IFC(to_mdev(ibdev),
mad_flags & IB_MAD_IGNORE_MKEY,
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index c309e5c..e36a9bc 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -49,7 +49,6 @@
MODULE_AUTHOR("Roland Dreier");
MODULE_DESCRIPTION("Mellanox InfiniBand HCA low-level driver");
MODULE_LICENSE("Dual BSD/GPL");
-MODULE_VERSION(DRV_VERSION);
#ifdef CONFIG_INFINIBAND_MTHCA_DEBUG
@@ -1162,7 +1161,7 @@ static void mthca_remove_one(struct pci_dev *pdev)
mutex_unlock(&mthca_device_mutex);
}
-static struct pci_device_id mthca_pci_table[] = {
+static const struct pci_device_id mthca_pci_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_MELLANOX, PCI_DEVICE_ID_MELLANOX_TAVOR),
.driver_data = TAVOR },
{ PCI_DEVICE(PCI_VENDOR_ID_TOPSPIN, PCI_DEVICE_ID_MELLANOX_TAVOR),
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index c197cd9..6fee779 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -914,7 +914,7 @@ static struct ib_mr *mthca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
int err = 0;
int write_mtt_size;
- if (udata->inlen - sizeof (struct ib_uverbs_cmd_hdr) < sizeof ucmd) {
+ if (udata->inlen < sizeof ucmd) {
if (!to_mucontext(pd->uobject->context)->reg_mr_warned) {
mthca_warn(dev, "Process '%s' did not pass in MR attrs.\n",
current->comm);
@@ -1178,12 +1178,11 @@ static int mthca_port_immutable(struct ib_device *ibdev, u8 port_num,
return 0;
}
-static void get_dev_fw_str(struct ib_device *device, char *str,
- size_t str_len)
+static void get_dev_fw_str(struct ib_device *device, char *str)
{
struct mthca_dev *dev =
container_of(device, struct mthca_dev, ib_dev);
- snprintf(str, str_len, "%d.%d.%d",
+ snprintf(str, IB_FW_VERSION_NAME_MAX, "%d.%d.%d",
(int) (dev->fw_ver >> 32),
(int) (dev->fw_ver >> 16) & 0xffff,
(int) dev->fw_ver & 0xffff);
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
index a30aa65..942ca84 100644
--- a/drivers/infiniband/hw/nes/nes.c
+++ b/drivers/infiniband/hw/nes/nes.c
@@ -63,7 +63,6 @@
MODULE_AUTHOR("NetEffect");
MODULE_DESCRIPTION("NetEffect RNIC Low-level iWARP Driver");
MODULE_LICENSE("Dual BSD/GPL");
-MODULE_VERSION(DRV_VERSION);
int interrupt_mod_interval = 0;
@@ -102,7 +101,7 @@ static unsigned int ee_flsh_adapter;
static unsigned int sysfs_nonidx_addr;
static unsigned int sysfs_idx_addr;
-static struct pci_device_id nes_pci_table[] = {
+static const struct pci_device_id nes_pci_table[] = {
{ PCI_VDEVICE(NETEFFECT, PCI_DEVICE_ID_NETEFFECT_NE020), },
{ PCI_VDEVICE(NETEFFECT, PCI_DEVICE_ID_NETEFFECT_NE020_KR), },
{0}
@@ -808,13 +807,6 @@ static void nes_remove(struct pci_dev *pcidev)
}
-static struct pci_driver nes_pci_driver = {
- .name = DRV_NAME,
- .id_table = nes_pci_table,
- .probe = nes_probe,
- .remove = nes_remove,
-};
-
static ssize_t adapter_show(struct device_driver *ddp, char *buf)
{
unsigned int devfn = 0xffffffff;
@@ -1156,35 +1148,29 @@ static DRIVER_ATTR_RW(idx_addr);
static DRIVER_ATTR_RW(idx_data);
static DRIVER_ATTR_RW(wqm_quanta);
-static int nes_create_driver_sysfs(struct pci_driver *drv)
-{
- int error;
- error = driver_create_file(&drv->driver, &driver_attr_adapter);
- error |= driver_create_file(&drv->driver, &driver_attr_eeprom_cmd);
- error |= driver_create_file(&drv->driver, &driver_attr_eeprom_data);
- error |= driver_create_file(&drv->driver, &driver_attr_flash_cmd);
- error |= driver_create_file(&drv->driver, &driver_attr_flash_data);
- error |= driver_create_file(&drv->driver, &driver_attr_nonidx_addr);
- error |= driver_create_file(&drv->driver, &driver_attr_nonidx_data);
- error |= driver_create_file(&drv->driver, &driver_attr_idx_addr);
- error |= driver_create_file(&drv->driver, &driver_attr_idx_data);
- error |= driver_create_file(&drv->driver, &driver_attr_wqm_quanta);
- return error;
-}
+static struct attribute *nes_attrs[] = {
+ &driver_attr_adapter.attr,
+ &driver_attr_eeprom_cmd.attr,
+ &driver_attr_eeprom_data.attr,
+ &driver_attr_flash_cmd.attr,
+ &driver_attr_flash_data.attr,
+ &driver_attr_nonidx_addr.attr,
+ &driver_attr_nonidx_data.attr,
+ &driver_attr_idx_addr.attr,
+ &driver_attr_idx_data.attr,
+ &driver_attr_wqm_quanta.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(nes);
+
+static struct pci_driver nes_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = nes_pci_table,
+ .probe = nes_probe,
+ .remove = nes_remove,
+ .groups = nes_groups,
+};
-static void nes_remove_driver_sysfs(struct pci_driver *drv)
-{
- driver_remove_file(&drv->driver, &driver_attr_adapter);
- driver_remove_file(&drv->driver, &driver_attr_eeprom_cmd);
- driver_remove_file(&drv->driver, &driver_attr_eeprom_data);
- driver_remove_file(&drv->driver, &driver_attr_flash_cmd);
- driver_remove_file(&drv->driver, &driver_attr_flash_data);
- driver_remove_file(&drv->driver, &driver_attr_nonidx_addr);
- driver_remove_file(&drv->driver, &driver_attr_nonidx_data);
- driver_remove_file(&drv->driver, &driver_attr_idx_addr);
- driver_remove_file(&drv->driver, &driver_attr_idx_data);
- driver_remove_file(&drv->driver, &driver_attr_wqm_quanta);
-}
/**
* nes_init_module - module initialization entry point
@@ -1192,20 +1178,13 @@ static void nes_remove_driver_sysfs(struct pci_driver *drv)
static int __init nes_init_module(void)
{
int retval;
- int retval1;
retval = nes_cm_start();
if (retval) {
printk(KERN_ERR PFX "Unable to start NetEffect iWARP CM.\n");
return retval;
}
- retval = pci_register_driver(&nes_pci_driver);
- if (retval >= 0) {
- retval1 = nes_create_driver_sysfs(&nes_pci_driver);
- if (retval1 < 0)
- printk(KERN_ERR PFX "Unable to create NetEffect sys files.\n");
- }
- return retval;
+ return pci_register_driver(&nes_pci_driver);
}
@@ -1215,7 +1194,6 @@ static int __init nes_init_module(void)
static void __exit nes_exit_module(void)
{
nes_cm_stop();
- nes_remove_driver_sysfs(&nes_pci_driver);
pci_unregister_driver(&nes_pci_driver);
}
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index 25dcd75..f0dc5f4 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -481,21 +481,16 @@ static int nes_query_port(struct ib_device *ibdev, u8 port, struct ib_port_attr
props->active_mtu = ib_mtu_int_to_enum(netdev->mtu);
props->lid = 1;
- props->lmc = 0;
- props->sm_lid = 0;
- props->sm_sl = 0;
if (netif_queue_stopped(netdev))
props->state = IB_PORT_DOWN;
else if (nesvnic->linkup)
props->state = IB_PORT_ACTIVE;
else
props->state = IB_PORT_DOWN;
- props->phys_state = 0;
props->port_cap_flags = IB_PORT_CM_SUP | IB_PORT_REINIT_SUP |
IB_PORT_VENDOR_CLASS_SUP | IB_PORT_BOOT_MGMT_SUP;
props->gid_tbl_len = 1;
props->pkey_tbl_len = 1;
- props->qkey_viol_cntr = 0;
props->active_width = IB_WIDTH_4X;
props->active_speed = IB_SPEED_SDR;
props->max_msg_sz = 0x80000000;
@@ -3672,15 +3667,14 @@ static int nes_port_immutable(struct ib_device *ibdev, u8 port_num,
return 0;
}
-static void get_dev_fw_str(struct ib_device *dev, char *str,
- size_t str_len)
+static void get_dev_fw_str(struct ib_device *dev, char *str)
{
struct nes_ib_device *nesibdev =
container_of(dev, struct nes_ib_device, ibdev);
struct nes_vnic *nesvnic = nesibdev->nesvnic;
nes_debug(NES_DBG_INIT, "\n");
- snprintf(str, str_len, "%u.%u",
+ snprintf(str, IB_FW_VERSION_NAME_MAX, "%u.%u",
(nesvnic->nesdev->nesadapter->firmware_version >> 16),
(nesvnic->nesdev->nesadapter->firmware_version & 0x000000ff));
}
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
index 57c9a2a..fbfbd9e 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
@@ -58,7 +58,6 @@
#include "ocrdma_stats.h"
#include <rdma/ocrdma-abi.h>
-MODULE_VERSION(OCRDMA_ROCE_DRV_VERSION);
MODULE_DESCRIPTION(OCRDMA_ROCE_DRV_DESC " " OCRDMA_ROCE_DRV_VERSION);
MODULE_AUTHOR("Emulex Corporation");
MODULE_LICENSE("Dual BSD/GPL");
@@ -108,12 +107,11 @@ static int ocrdma_port_immutable(struct ib_device *ibdev, u8 port_num,
return 0;
}
-static void get_dev_fw_str(struct ib_device *device, char *str,
- size_t str_len)
+static void get_dev_fw_str(struct ib_device *device, char *str)
{
struct ocrdma_dev *dev = get_ocrdma_dev(device);
- snprintf(str, str_len, "%s", &dev->attr.fw_ver[0]);
+ snprintf(str, IB_FW_VERSION_NAME_MAX, "%s", &dev->attr.fw_ver[0]);
}
static int ocrdma_register_device(struct ocrdma_dev *dev)
diff --git a/drivers/infiniband/hw/qedr/main.c b/drivers/infiniband/hw/qedr/main.c
index b5851fd..97d033f 100644
--- a/drivers/infiniband/hw/qedr/main.c
+++ b/drivers/infiniband/hw/qedr/main.c
@@ -47,7 +47,6 @@
MODULE_DESCRIPTION("QLogic 40G/100G ROCE Driver");
MODULE_AUTHOR("QLogic Corporation");
MODULE_LICENSE("Dual BSD/GPL");
-MODULE_VERSION(QEDR_MODULE_VERSION);
#define QEDR_WQ_MULTIPLIER_DFT (3)
@@ -69,13 +68,12 @@ static enum rdma_link_layer qedr_link_layer(struct ib_device *device,
return IB_LINK_LAYER_ETHERNET;
}
-static void qedr_get_dev_fw_str(struct ib_device *ibdev, char *str,
- size_t str_len)
+static void qedr_get_dev_fw_str(struct ib_device *ibdev, char *str)
{
struct qedr_dev *qedr = get_qedr_dev(ibdev);
u32 fw_ver = (u32)qedr->attr.fw_ver;
- snprintf(str, str_len, "%d. %d. %d. %d",
+ snprintf(str, IB_FW_VERSION_NAME_MAX, "%d. %d. %d. %d",
(fw_ver >> 24) & 0xFF, (fw_ver >> 16) & 0xFF,
(fw_ver >> 8) & 0xFF, fw_ver & 0xFF);
}
@@ -778,6 +776,7 @@ static struct qedr_dev *qedr_add(struct qed_dev *cdev, struct pci_dev *pdev,
if (rc)
goto init_err;
+ dev->user_dpm_enabled = dev_info.user_dpm_enabled;
dev->num_hwfns = dev_info.common.num_hwfns;
dev->rdma_ctx = dev->ops->rdma_get_rdma_ctx(cdev);
diff --git a/drivers/infiniband/hw/qedr/qedr.h b/drivers/infiniband/hw/qedr/qedr.h
index ab7784b..b2bb42e 100644
--- a/drivers/infiniband/hw/qedr/qedr.h
+++ b/drivers/infiniband/hw/qedr/qedr.h
@@ -41,7 +41,6 @@
#include <linux/qed/roce_common.h>
#include "qedr_hsi_rdma.h"
-#define QEDR_MODULE_VERSION "8.10.10.0"
#define QEDR_NODE_DESC "QLogic 579xx RoCE HCA"
#define DP_NAME(dev) ((dev)->ibdev.name)
@@ -163,6 +162,8 @@ struct qedr_dev {
struct qedr_qp *gsi_qp;
unsigned long enet_state;
+
+ u8 user_dpm_enabled;
};
#define QEDR_MAX_SQ_PBL (0x8000)
diff --git a/drivers/infiniband/hw/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c
index 2ae71b8..769ac07 100644
--- a/drivers/infiniband/hw/qedr/verbs.c
+++ b/drivers/infiniband/hw/qedr/verbs.c
@@ -376,6 +376,9 @@ struct ib_ucontext *qedr_alloc_ucontext(struct ib_device *ibdev,
memset(&uresp, 0, sizeof(uresp));
+ uresp.dpm_enabled = dev->user_dpm_enabled;
+ uresp.wids_enabled = 1;
+ uresp.wid_count = oparams.wid_count;
uresp.db_pa = ctx->dpi_phys_addr;
uresp.db_size = ctx->dpi_size;
uresp.max_send_wr = dev->attr.max_sqe;
@@ -488,7 +491,7 @@ struct ib_pd *qedr_alloc_pd(struct ib_device *ibdev,
(udata && context) ? "User Lib" : "Kernel");
if (!dev->rdma_ctx) {
- DP_ERR(dev, "invlaid RDMA context\n");
+ DP_ERR(dev, "invalid RDMA context\n");
return ERR_PTR(-EINVAL);
}
diff --git a/drivers/infiniband/hw/qib/qib.h b/drivers/infiniband/hw/qib/qib.h
index a3e21a2..f9e1c69 100644
--- a/drivers/infiniband/hw/qib/qib.h
+++ b/drivers/infiniband/hw/qib/qib.h
@@ -1,7 +1,7 @@
#ifndef _QIB_KERNEL_H
#define _QIB_KERNEL_H
/*
- * Copyright (c) 2012, 2013 Intel Corporation. All rights reserved.
+ * Copyright (c) 2012 - 2017 Intel Corporation. All rights reserved.
* Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved.
* Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
*
@@ -443,7 +443,7 @@ struct qib_irq_notify;
#endif
struct qib_msix_entry {
- struct msix_entry msix;
+ int irq;
void *arg;
#ifdef CONFIG_INFINIBAND_QIB_DCA
int dca;
@@ -1433,9 +1433,9 @@ int qib_pcie_init(struct pci_dev *, const struct pci_device_id *);
int qib_pcie_ddinit(struct qib_devdata *, struct pci_dev *,
const struct pci_device_id *);
void qib_pcie_ddcleanup(struct qib_devdata *);
-int qib_pcie_params(struct qib_devdata *, u32, u32 *, struct qib_msix_entry *);
+int qib_pcie_params(struct qib_devdata *dd, u32 minw, u32 *nent);
int qib_reinit_intr(struct qib_devdata *);
-void qib_enable_intx(struct pci_dev *);
+void qib_enable_intx(struct qib_devdata *dd);
void qib_nomsi(struct qib_devdata *);
void qib_nomsix(struct qib_devdata *);
void qib_pcie_getcmd(struct qib_devdata *, u16 *, u8 *, u8 *);
diff --git a/drivers/infiniband/hw/qib/qib_debugfs.c b/drivers/infiniband/hw/qib/qib_debugfs.c
index 5bad8e3..5ed1ed9 100644
--- a/drivers/infiniband/hw/qib/qib_debugfs.c
+++ b/drivers/infiniband/hw/qib/qib_debugfs.c
@@ -1,6 +1,5 @@
-#ifdef CONFIG_DEBUG_FS
/*
- * Copyright (c) 2013 Intel Corporation. All rights reserved.
+ * Copyright (c) 2013 - 2017 Intel Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -191,10 +190,10 @@ DEBUGFS_FILE(ctx_stats)
static void *_qp_stats_seq_start(struct seq_file *s, loff_t *pos)
__acquires(RCU)
{
- struct qib_qp_iter *iter;
+ struct rvt_qp_iter *iter;
loff_t n = *pos;
- iter = qib_qp_iter_init(s->private);
+ iter = rvt_qp_iter_init(s->private, 0, NULL);
/* stop calls rcu_read_unlock */
rcu_read_lock();
@@ -203,7 +202,7 @@ static void *_qp_stats_seq_start(struct seq_file *s, loff_t *pos)
return NULL;
do {
- if (qib_qp_iter_next(iter)) {
+ if (rvt_qp_iter_next(iter)) {
kfree(iter);
return NULL;
}
@@ -216,11 +215,11 @@ static void *_qp_stats_seq_next(struct seq_file *s, void *iter_ptr,
loff_t *pos)
__must_hold(RCU)
{
- struct qib_qp_iter *iter = iter_ptr;
+ struct rvt_qp_iter *iter = iter_ptr;
(*pos)++;
- if (qib_qp_iter_next(iter)) {
+ if (rvt_qp_iter_next(iter)) {
kfree(iter);
return NULL;
}
@@ -236,7 +235,7 @@ static void _qp_stats_seq_stop(struct seq_file *s, void *iter_ptr)
static int _qp_stats_seq_show(struct seq_file *s, void *iter_ptr)
{
- struct qib_qp_iter *iter = iter_ptr;
+ struct rvt_qp_iter *iter = iter_ptr;
if (!iter)
return 0;
@@ -284,6 +283,3 @@ void qib_dbg_exit(void)
debugfs_remove_recursive(qib_dbg_root);
qib_dbg_root = NULL;
}
-
-#endif
-
diff --git a/drivers/infiniband/hw/qib/qib_driver.c b/drivers/infiniband/hw/qib/qib_driver.c
index 2b5982f..719906a 100644
--- a/drivers/infiniband/hw/qib/qib_driver.c
+++ b/drivers/infiniband/hw/qib/qib_driver.c
@@ -66,7 +66,6 @@ MODULE_PARM_DESC(compat_ddr_negotiate,
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Intel <ibsupport@intel.com>");
MODULE_DESCRIPTION("Intel IB driver");
-MODULE_VERSION(QIB_DRIVER_VERSION);
/*
* QIB_PIO_MAXIBHDR is the max IB header size allowed for in our
diff --git a/drivers/infiniband/hw/qib/qib_iba6120.c b/drivers/infiniband/hw/qib/qib_iba6120.c
index e423b71..3259a60 100644
--- a/drivers/infiniband/hw/qib/qib_iba6120.c
+++ b/drivers/infiniband/hw/qib/qib_iba6120.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 Intel Corporation. All rights reserved.
+ * Copyright (c) 2013 - 2017 Intel Corporation. All rights reserved.
* Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation.
* All rights reserved.
* Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
@@ -1742,38 +1742,32 @@ static void qib_setup_6120_interrupt(struct qib_devdata *dd)
*/
static void pe_boardname(struct qib_devdata *dd)
{
- char *n;
- u32 boardid, namelen;
+ u32 boardid;
boardid = SYM_FIELD(dd->revision, Revision,
BoardID);
switch (boardid) {
case 2:
- n = "InfiniPath_QLE7140";
+ dd->boardname = "InfiniPath_QLE7140";
break;
default:
qib_dev_err(dd, "Unknown 6120 board with ID %u\n", boardid);
- n = "Unknown_InfiniPath_6120";
+ dd->boardname = "Unknown_InfiniPath_6120";
break;
}
- namelen = strlen(n) + 1;
- dd->boardname = kmalloc(namelen, GFP_KERNEL);
- if (dd->boardname)
- snprintf(dd->boardname, namelen, "%s", n);
if (dd->majrev != 4 || !dd->minrev || dd->minrev > 2)
qib_dev_err(dd,
- "Unsupported InfiniPath hardware revision %u.%u!\n",
- dd->majrev, dd->minrev);
+ "Unsupported InfiniPath hardware revision %u.%u!\n",
+ dd->majrev, dd->minrev);
snprintf(dd->boardversion, sizeof(dd->boardversion),
"ChipABI %u.%u, %s, InfiniPath%u %u.%u, SW Compat %u\n",
QIB_CHIP_VERS_MAJ, QIB_CHIP_VERS_MIN, dd->boardname,
- (unsigned)SYM_FIELD(dd->revision, Revision_R, Arch),
+ (unsigned int)SYM_FIELD(dd->revision, Revision_R, Arch),
dd->majrev, dd->minrev,
- (unsigned)SYM_FIELD(dd->revision, Revision_R, SW));
-
+ (unsigned int)SYM_FIELD(dd->revision, Revision_R, SW));
}
/*
@@ -1838,7 +1832,7 @@ static int qib_6120_setup_reset(struct qib_devdata *dd)
bail:
if (ret) {
- if (qib_pcie_params(dd, dd->lbus_width, NULL, NULL))
+ if (qib_pcie_params(dd, dd->lbus_width, NULL))
qib_dev_err(dd,
"Reset failed to setup PCIe or interrupts; continuing anyway\n");
/* clear the reset error, init error/hwerror mask */
@@ -3562,7 +3556,7 @@ struct qib_devdata *qib_init_iba6120_funcs(struct pci_dev *pdev,
if (qib_mini_init)
goto bail;
- if (qib_pcie_params(dd, 8, NULL, NULL))
+ if (qib_pcie_params(dd, 8, NULL))
qib_dev_err(dd,
"Failed to setup PCIe or interrupts; continuing anyway\n");
dd->cspec->irq = pdev->irq; /* save IRQ */
diff --git a/drivers/infiniband/hw/qib/qib_iba7220.c b/drivers/infiniband/hw/qib/qib_iba7220.c
index c3679c4..04bdd3d 100644
--- a/drivers/infiniband/hw/qib/qib_iba7220.c
+++ b/drivers/infiniband/hw/qib/qib_iba7220.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (c) 2011 - 2017 Intel Corporation. All rights reserved.
* Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation.
* All rights reserved.
* Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
@@ -2049,41 +2050,35 @@ static void qib_setup_7220_interrupt(struct qib_devdata *dd)
*/
static void qib_7220_boardname(struct qib_devdata *dd)
{
- char *n;
- u32 boardid, namelen;
+ u32 boardid;
boardid = SYM_FIELD(dd->revision, Revision,
BoardID);
switch (boardid) {
case 1:
- n = "InfiniPath_QLE7240";
+ dd->boardname = "InfiniPath_QLE7240";
break;
case 2:
- n = "InfiniPath_QLE7280";
+ dd->boardname = "InfiniPath_QLE7280";
break;
default:
qib_dev_err(dd, "Unknown 7220 board with ID %u\n", boardid);
- n = "Unknown_InfiniPath_7220";
+ dd->boardname = "Unknown_InfiniPath_7220";
break;
}
- namelen = strlen(n) + 1;
- dd->boardname = kmalloc(namelen, GFP_KERNEL);
- if (dd->boardname)
- snprintf(dd->boardname, namelen, "%s", n);
-
if (dd->majrev != 5 || !dd->minrev || dd->minrev > 2)
qib_dev_err(dd,
- "Unsupported InfiniPath hardware revision %u.%u!\n",
- dd->majrev, dd->minrev);
+ "Unsupported InfiniPath hardware revision %u.%u!\n",
+ dd->majrev, dd->minrev);
snprintf(dd->boardversion, sizeof(dd->boardversion),
"ChipABI %u.%u, %s, InfiniPath%u %u.%u, SW Compat %u\n",
QIB_CHIP_VERS_MAJ, QIB_CHIP_VERS_MIN, dd->boardname,
- (unsigned)SYM_FIELD(dd->revision, Revision_R, Arch),
+ (unsigned int)SYM_FIELD(dd->revision, Revision_R, Arch),
dd->majrev, dd->minrev,
- (unsigned)SYM_FIELD(dd->revision, Revision_R, SW));
+ (unsigned int)SYM_FIELD(dd->revision, Revision_R, SW));
}
/*
@@ -2148,7 +2143,7 @@ static int qib_setup_7220_reset(struct qib_devdata *dd)
bail:
if (ret) {
- if (qib_pcie_params(dd, dd->lbus_width, NULL, NULL))
+ if (qib_pcie_params(dd, dd->lbus_width, NULL))
qib_dev_err(dd,
"Reset failed to setup PCIe or interrupts; continuing anyway\n");
@@ -3309,7 +3304,7 @@ static int qib_7220_intr_fallback(struct qib_devdata *dd)
qib_devinfo(dd->pcidev,
"MSI interrupt not detected, trying INTx interrupts\n");
qib_7220_free_irq(dd);
- qib_enable_intx(dd->pcidev);
+ qib_enable_intx(dd);
/*
* Some newer kernels require free_irq before disable_msi,
* and irq can be changed during disable and INTx enable
@@ -4619,7 +4614,7 @@ struct qib_devdata *qib_init_iba7220_funcs(struct pci_dev *pdev,
minwidth = 8; /* x8 capable boards */
break;
}
- if (qib_pcie_params(dd, minwidth, NULL, NULL))
+ if (qib_pcie_params(dd, minwidth, NULL))
qib_dev_err(dd,
"Failed to setup PCIe or interrupts; continuing anyway\n");
diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c
index bb2439f..14cadf6 100644
--- a/drivers/infiniband/hw/qib/qib_iba7322.c
+++ b/drivers/infiniband/hw/qib/qib_iba7322.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Intel Corporation. All rights reserved.
+ * Copyright (c) 2012 - 2017 Intel Corporation. All rights reserved.
* Copyright (c) 2008 - 2012 QLogic Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
@@ -2841,10 +2841,10 @@ static void qib_7322_nomsix(struct qib_devdata *dd)
reset_dca_notifier(dd, &dd->cspec->msix_entries[i]);
#endif
irq_set_affinity_hint(
- dd->cspec->msix_entries[i].msix.vector, NULL);
+ dd->cspec->msix_entries[i].irq, NULL);
free_cpumask_var(dd->cspec->msix_entries[i].mask);
- free_irq(dd->cspec->msix_entries[i].msix.vector,
- dd->cspec->msix_entries[i].arg);
+ free_irq(dd->cspec->msix_entries[i].irq,
+ dd->cspec->msix_entries[i].arg);
}
qib_nomsix(dd);
}
@@ -3336,9 +3336,9 @@ static void reset_dca_notifier(struct qib_devdata *dd, struct qib_msix_entry *m)
qib_devinfo(dd->pcidev,
"Disabling notifier on HCA %d irq %d\n",
dd->unit,
- m->msix.vector);
+ m->irq);
irq_set_affinity_notifier(
- m->msix.vector,
+ m->irq,
NULL);
m->notifier = NULL;
}
@@ -3354,7 +3354,7 @@ static void setup_dca_notifier(struct qib_devdata *dd, struct qib_msix_entry *m)
int ret;
m->notifier = n;
- n->notify.irq = m->msix.vector;
+ n->notify.irq = m->irq;
n->notify.notify = qib_irq_notifier_notify;
n->notify.release = qib_irq_notifier_release;
n->arg = m->arg;
@@ -3500,10 +3500,21 @@ try_intx:
- 1,
QIB_DRV_NAME "%d (kctx)", dd->unit);
}
- ret = request_irq(
- dd->cspec->msix_entries[msixnum].msix.vector,
- handler, 0, dd->cspec->msix_entries[msixnum].name,
- arg);
+
+ dd->cspec->msix_entries[msixnum].irq = pci_irq_vector(
+ dd->pcidev, msixnum);
+ if (dd->cspec->msix_entries[msixnum].irq < 0) {
+ qib_dev_err(dd,
+ "Couldn't get MSIx irq (vec=%d): %d\n",
+ msixnum,
+ dd->cspec->msix_entries[msixnum].irq);
+ qib_7322_nomsix(dd);
+ goto try_intx;
+ }
+ ret = request_irq(dd->cspec->msix_entries[msixnum].irq,
+ handler, 0,
+ dd->cspec->msix_entries[msixnum].name,
+ arg);
if (ret) {
/*
* Shouldn't happen since the enable said we could
@@ -3512,7 +3523,7 @@ try_intx:
qib_dev_err(dd,
"Couldn't setup MSIx interrupt (vec=%d, irq=%d): %d\n",
msixnum,
- dd->cspec->msix_entries[msixnum].msix.vector,
+ dd->cspec->msix_entries[msixnum].irq,
ret);
qib_7322_nomsix(dd);
goto try_intx;
@@ -3548,7 +3559,7 @@ try_intx:
dd->cspec->msix_entries[msixnum].mask);
}
irq_set_affinity_hint(
- dd->cspec->msix_entries[msixnum].msix.vector,
+ dd->cspec->msix_entries[msixnum].irq,
dd->cspec->msix_entries[msixnum].mask);
}
msixnum++;
@@ -3571,75 +3582,69 @@ bail:;
static unsigned qib_7322_boardname(struct qib_devdata *dd)
{
/* Will need enumeration of board-types here */
- char *n;
- u32 boardid, namelen;
- unsigned features = DUAL_PORT_CAP;
+ u32 boardid;
+ unsigned int features = DUAL_PORT_CAP;
boardid = SYM_FIELD(dd->revision, Revision, BoardID);
switch (boardid) {
case 0:
- n = "InfiniPath_QLE7342_Emulation";
+ dd->boardname = "InfiniPath_QLE7342_Emulation";
break;
case 1:
- n = "InfiniPath_QLE7340";
+ dd->boardname = "InfiniPath_QLE7340";
dd->flags |= QIB_HAS_QSFP;
features = PORT_SPD_CAP;
break;
case 2:
- n = "InfiniPath_QLE7342";
+ dd->boardname = "InfiniPath_QLE7342";
dd->flags |= QIB_HAS_QSFP;
break;
case 3:
- n = "InfiniPath_QMI7342";
+ dd->boardname = "InfiniPath_QMI7342";
break;
case 4:
- n = "InfiniPath_Unsupported7342";
+ dd->boardname = "InfiniPath_Unsupported7342";
qib_dev_err(dd, "Unsupported version of QMH7342\n");
features = 0;
break;
case BOARD_QMH7342:
- n = "InfiniPath_QMH7342";
+ dd->boardname = "InfiniPath_QMH7342";
features = 0x24;
break;
case BOARD_QME7342:
- n = "InfiniPath_QME7342";
+ dd->boardname = "InfiniPath_QME7342";
break;
case 8:
- n = "InfiniPath_QME7362";
+ dd->boardname = "InfiniPath_QME7362";
dd->flags |= QIB_HAS_QSFP;
break;
case BOARD_QMH7360:
- n = "Intel IB QDR 1P FLR-QSFP Adptr";
+ dd->boardname = "Intel IB QDR 1P FLR-QSFP Adptr";
dd->flags |= QIB_HAS_QSFP;
break;
case 15:
- n = "InfiniPath_QLE7342_TEST";
+ dd->boardname = "InfiniPath_QLE7342_TEST";
dd->flags |= QIB_HAS_QSFP;
break;
default:
- n = "InfiniPath_QLE73xy_UNKNOWN";
+ dd->boardname = "InfiniPath_QLE73xy_UNKNOWN";
qib_dev_err(dd, "Unknown 7322 board type %u\n", boardid);
break;
}
dd->board_atten = 1; /* index into txdds_Xdr */
- namelen = strlen(n) + 1;
- dd->boardname = kmalloc(namelen, GFP_KERNEL);
- if (dd->boardname)
- snprintf(dd->boardname, namelen, "%s", n);
-
snprintf(dd->boardversion, sizeof(dd->boardversion),
"ChipABI %u.%u, %s, InfiniPath%u %u.%u, SW Compat %u\n",
QIB_CHIP_VERS_MAJ, QIB_CHIP_VERS_MIN, dd->boardname,
- (unsigned)SYM_FIELD(dd->revision, Revision_R, Arch),
+ (unsigned int)SYM_FIELD(dd->revision, Revision_R, Arch),
dd->majrev, dd->minrev,
- (unsigned)SYM_FIELD(dd->revision, Revision_R, SW));
+ (unsigned int)SYM_FIELD(dd->revision, Revision_R, SW));
if (qib_singleport && (features >> PORT_SPD_CAP_SHIFT) & PORT_SPD_CAP) {
qib_devinfo(dd->pcidev,
- "IB%u: Forced to single port mode by module parameter\n",
- dd->unit);
+ "IB%u: Forced to single port mode by module parameter\n",
+ dd->unit);
features &= PORT_SPD_CAP;
}
@@ -3744,7 +3749,6 @@ static int qib_do_7322_reset(struct qib_devdata *dd)
if (msix_entries) {
/* restore the MSIx vector address and data if saved above */
for (i = 0; i < msix_entries; i++) {
- dd->cspec->msix_entries[i].msix.entry = i;
if (!msix_vecsave || !msix_vecsave[2 * i])
continue;
qib_write_kreg(dd, 2 * i +
@@ -3762,8 +3766,7 @@ static int qib_do_7322_reset(struct qib_devdata *dd)
write_7322_initregs(dd);
if (qib_pcie_params(dd, dd->lbus_width,
- &dd->cspec->num_msix_entries,
- dd->cspec->msix_entries))
+ &dd->cspec->num_msix_entries))
qib_dev_err(dd,
"Reset failed to setup PCIe or interrupts; continuing anyway\n");
@@ -5195,7 +5198,7 @@ static int qib_7322_intr_fallback(struct qib_devdata *dd)
qib_devinfo(dd->pcidev,
"MSIx interrupt not detected, trying INTx interrupts\n");
qib_7322_nomsix(dd);
- qib_enable_intx(dd->pcidev);
+ qib_enable_intx(dd);
qib_setup_7322_interrupt(dd, 0);
return 1;
}
@@ -6172,7 +6175,7 @@ static int setup_txselect(const char *str, struct kernel_param *kp)
unsigned long val;
char *n;
- if (strlen(str) >= MAX_ATTEN_LEN) {
+ if (strlen(str) >= ARRAY_SIZE(txselect_list)) {
pr_info("txselect_values string too long\n");
return -ENOSPC;
}
@@ -6183,7 +6186,7 @@ static int setup_txselect(const char *str, struct kernel_param *kp)
TXDDS_TABLE_SZ + TXDDS_EXTRA_SZ + TXDDS_MFG_SZ);
return -EINVAL;
}
- strcpy(txselect_list, str);
+ strncpy(txselect_list, str, ARRAY_SIZE(txselect_list) - 1);
list_for_each_entry(dd, &qib_dev_list, list)
if (dd->deviceid == PCI_DEVICE_ID_QLOGIC_IB_7322)
@@ -7327,10 +7330,7 @@ struct qib_devdata *qib_init_iba7322_funcs(struct pci_dev *pdev,
if (!dd->cspec->msix_entries)
tabsize = 0;
- for (i = 0; i < tabsize; i++)
- dd->cspec->msix_entries[i].msix.entry = i;
-
- if (qib_pcie_params(dd, 8, &tabsize, dd->cspec->msix_entries))
+ if (qib_pcie_params(dd, 8, &tabsize))
qib_dev_err(dd,
"Failed to setup PCIe or interrupts; continuing anyway\n");
/* may be less than we wanted, if not enough available */
diff --git a/drivers/infiniband/hw/qib/qib_init.c b/drivers/infiniband/hw/qib/qib_init.c
index 6c16ba1..c5a4c65 100644
--- a/drivers/infiniband/hw/qib/qib_init.c
+++ b/drivers/infiniband/hw/qib/qib_init.c
@@ -399,7 +399,7 @@ static int loadtime_init(struct qib_devdata *dd)
if (((dd->revision >> QLOGIC_IB_R_SOFTWARE_SHIFT) &
QLOGIC_IB_R_SOFTWARE_MASK) != QIB_CHIP_SWVERSION) {
qib_dev_err(dd,
- "Driver only handles version %d, chip swversion is %d (%llx), failng\n",
+ "Driver only handles version %d, chip swversion is %d (%llx), failing\n",
QIB_CHIP_SWVERSION,
(int)(dd->revision >>
QLOGIC_IB_R_SOFTWARE_SHIFT) &
@@ -1398,7 +1398,6 @@ static void cleanup_device_data(struct qib_devdata *dd)
qib_free_ctxtdata(dd, rcd);
}
kfree(tmp);
- kfree(dd->boardname);
}
/*
diff --git a/drivers/infiniband/hw/qib/qib_mad.c b/drivers/infiniband/hw/qib/qib_mad.c
index da295e0..82d9da9 100644
--- a/drivers/infiniband/hw/qib/qib_mad.c
+++ b/drivers/infiniband/hw/qib/qib_mad.c
@@ -105,7 +105,7 @@ static void qib_send_trap(struct qib_ibport *ibp, void *data, unsigned len)
if (ibp->rvp.sm_lid != be16_to_cpu(IB_LID_PERMISSIVE)) {
struct ib_ah *ah;
- ah = qib_create_qp0_ah(ibp, ibp->rvp.sm_lid);
+ ah = qib_create_qp0_ah(ibp, (u16)ibp->rvp.sm_lid);
if (IS_ERR(ah))
ret = PTR_ERR(ah);
else {
@@ -134,24 +134,21 @@ static void qib_send_trap(struct qib_ibport *ibp, void *data, unsigned len)
}
/*
- * Send a bad [PQ]_Key trap (ch. 14.3.8).
+ * Send a bad P_Key trap (ch. 14.3.8).
*/
-void qib_bad_pqkey(struct qib_ibport *ibp, __be16 trap_num, u32 key, u32 sl,
- u32 qp1, u32 qp2, __be16 lid1, __be16 lid2)
+void qib_bad_pkey(struct qib_ibport *ibp, u32 key, u32 sl,
+ u32 qp1, u32 qp2, __be16 lid1, __be16 lid2)
{
struct ib_mad_notice_attr data;
- if (trap_num == IB_NOTICE_TRAP_BAD_PKEY)
- ibp->rvp.pkey_violations++;
- else
- ibp->rvp.qkey_violations++;
ibp->rvp.n_pkt_drops++;
+ ibp->rvp.pkey_violations++;
/* Send violation trap */
data.generic_type = IB_NOTICE_TYPE_SECURITY;
data.prod_type_msb = 0;
data.prod_type_lsb = IB_NOTICE_PROD_CA;
- data.trap_num = trap_num;
+ data.trap_num = IB_NOTICE_TRAP_BAD_PKEY;
data.issuer_lid = cpu_to_be16(ppd_from_ibp(ibp)->lid);
data.toggle_count = 0;
memset(&data.details, 0, sizeof(data.details));
@@ -499,7 +496,7 @@ static int subn_get_portinfo(struct ib_smp *smp, struct ib_device *ibdev,
pip->mkey = ibp->rvp.mkey;
pip->gid_prefix = ibp->rvp.gid_prefix;
pip->lid = cpu_to_be16(ppd->lid);
- pip->sm_lid = cpu_to_be16(ibp->rvp.sm_lid);
+ pip->sm_lid = cpu_to_be16((u16)ibp->rvp.sm_lid);
pip->cap_mask = cpu_to_be32(ibp->rvp.port_cap_flags);
/* pip->diag_code; */
pip->mkey_lease_period = cpu_to_be16(ibp->rvp.mkey_lease_period);
@@ -874,8 +871,6 @@ static int subn_set_portinfo(struct ib_smp *smp, struct ib_device *ibdev,
ib_dispatch_event(&event);
}
- ret = subn_get_portinfo(smp, ibdev, port);
-
/* restore re-reg bit per o14-12.2.1 */
pip->clientrereg_resv_subnetto |= clientrereg;
@@ -1578,8 +1573,8 @@ static int pma_get_portcounters_cong(struct ib_pma_mad *pmp,
cntrs.port_xmit_packets -= ibp->z_port_xmit_packets;
cntrs.port_rcv_packets -= ibp->z_port_rcv_packets;
- memset(pmp->reserved, 0, sizeof(pmp->reserved) +
- sizeof(pmp->data));
+ memset(pmp->reserved, 0, sizeof(pmp->reserved));
+ memset(pmp->data, 0, sizeof(pmp->data));
/*
* Set top 3 bits to indicate interval in picoseconds in
diff --git a/drivers/infiniband/hw/qib/qib_pcie.c b/drivers/infiniband/hw/qib/qib_pcie.c
index c379b83..d90403e 100644
--- a/drivers/infiniband/hw/qib/qib_pcie.c
+++ b/drivers/infiniband/hw/qib/qib_pcie.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (c) 2010 - 2017 Intel Corporation. All rights reserved.
* Copyright (c) 2008, 2009 QLogic Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
@@ -187,112 +188,84 @@ void qib_pcie_ddcleanup(struct qib_devdata *dd)
pci_set_drvdata(dd->pcidev, NULL);
}
-static void qib_msix_setup(struct qib_devdata *dd, int pos, u32 *msixcnt,
- struct qib_msix_entry *qib_msix_entry)
-{
- int ret;
- int nvec = *msixcnt;
- struct msix_entry *msix_entry;
- int i;
-
- ret = pci_msix_vec_count(dd->pcidev);
- if (ret < 0)
- goto do_intx;
-
- nvec = min(nvec, ret);
-
- /* We can't pass qib_msix_entry array to qib_msix_setup
- * so use a dummy msix_entry array and copy the allocated
- * irq back to the qib_msix_entry array. */
- msix_entry = kcalloc(nvec, sizeof(*msix_entry), GFP_KERNEL);
- if (!msix_entry)
- goto do_intx;
-
- for (i = 0; i < nvec; i++)
- msix_entry[i] = qib_msix_entry[i].msix;
-
- ret = pci_enable_msix_range(dd->pcidev, msix_entry, 1, nvec);
- if (ret < 0)
- goto free_msix_entry;
- else
- nvec = ret;
-
- for (i = 0; i < nvec; i++)
- qib_msix_entry[i].msix = msix_entry[i];
-
- kfree(msix_entry);
- *msixcnt = nvec;
- return;
-
-free_msix_entry:
- kfree(msix_entry);
-
-do_intx:
- qib_dev_err(
- dd,
- "pci_enable_msix_range %d vectors failed: %d, falling back to INTx\n",
- nvec, ret);
- *msixcnt = 0;
- qib_enable_intx(dd->pcidev);
-}
-
/**
* We save the msi lo and hi values, so we can restore them after
* chip reset (the kernel PCI infrastructure doesn't yet handle that
* correctly.
*/
-static int qib_msi_setup(struct qib_devdata *dd, int pos)
+static void qib_msi_setup(struct qib_devdata *dd, int pos)
{
struct pci_dev *pdev = dd->pcidev;
u16 control;
- int ret;
- ret = pci_enable_msi(pdev);
- if (ret)
- qib_dev_err(dd,
- "pci_enable_msi failed: %d, interrupts may not work\n",
- ret);
- /* continue even if it fails, we may still be OK... */
-
- pci_read_config_dword(pdev, pos + PCI_MSI_ADDRESS_LO,
- &dd->msi_lo);
- pci_read_config_dword(pdev, pos + PCI_MSI_ADDRESS_HI,
- &dd->msi_hi);
+ pci_read_config_dword(pdev, pos + PCI_MSI_ADDRESS_LO, &dd->msi_lo);
+ pci_read_config_dword(pdev, pos + PCI_MSI_ADDRESS_HI, &dd->msi_hi);
pci_read_config_word(pdev, pos + PCI_MSI_FLAGS, &control);
+
/* now save the data (vector) info */
- pci_read_config_word(pdev, pos + ((control & PCI_MSI_FLAGS_64BIT)
- ? 12 : 8),
+ pci_read_config_word(pdev,
+ pos + ((control & PCI_MSI_FLAGS_64BIT) ? 12 : 8),
&dd->msi_data);
- return ret;
}
-int qib_pcie_params(struct qib_devdata *dd, u32 minw, u32 *nent,
- struct qib_msix_entry *entry)
+static int qib_allocate_irqs(struct qib_devdata *dd, u32 maxvec)
+{
+ unsigned int flags = PCI_IRQ_LEGACY;
+
+ /* Check our capabilities */
+ if (dd->pcidev->msix_cap) {
+ flags |= PCI_IRQ_MSIX;
+ } else {
+ if (dd->pcidev->msi_cap) {
+ flags |= PCI_IRQ_MSI;
+ /* Get msi_lo and msi_hi */
+ qib_msi_setup(dd, dd->pcidev->msi_cap);
+ }
+ }
+
+ if (!(flags & (PCI_IRQ_MSIX | PCI_IRQ_MSI)))
+ qib_dev_err(dd, "No PCI MSI or MSIx capability!\n");
+
+ return pci_alloc_irq_vectors(dd->pcidev, 1, maxvec, flags);
+}
+
+int qib_pcie_params(struct qib_devdata *dd, u32 minw, u32 *nent)
{
u16 linkstat, speed;
- int pos = 0, ret = 1;
+ int nvec;
+ int maxvec;
+ int ret = 0;
if (!pci_is_pcie(dd->pcidev)) {
qib_dev_err(dd, "Can't find PCI Express capability!\n");
/* set up something... */
dd->lbus_width = 1;
dd->lbus_speed = 2500; /* Gen1, 2.5GHz */
+ ret = -1;
goto bail;
}
- pos = dd->pcidev->msix_cap;
- if (nent && *nent && pos) {
- qib_msix_setup(dd, pos, nent, entry);
- ret = 0; /* did it, either MSIx or INTx */
- } else {
- pos = dd->pcidev->msi_cap;
- if (pos)
- ret = qib_msi_setup(dd, pos);
- else
- qib_dev_err(dd, "No PCI MSI or MSIx capability!\n");
+ maxvec = (nent && *nent) ? *nent : 1;
+ nvec = qib_allocate_irqs(dd, maxvec);
+ if (nvec < 0) {
+ ret = nvec;
+ goto bail;
+ }
+
+ /*
+ * If nent exists, make sure to record how many vectors were allocated
+ */
+ if (nent) {
+ *nent = nvec;
+
+ /*
+ * If we requested (nent) MSIX, but msix_enabled is not set,
+ * pci_alloc_irq_vectors() enabled INTx.
+ */
+ if (!dd->pcidev->msix_enabled)
+ qib_dev_err(dd,
+ "no msix vectors allocated, using INTx\n");
}
- if (!pos)
- qib_enable_intx(dd->pcidev);
pcie_capability_read_word(dd->pcidev, PCI_EXP_LNKSTA, &linkstat);
/*
@@ -379,7 +352,7 @@ int qib_reinit_intr(struct qib_devdata *dd)
ret = 1;
bail:
if (!ret && (dd->flags & QIB_HAS_INTX)) {
- qib_enable_intx(dd->pcidev);
+ qib_enable_intx(dd);
ret = 1;
}
@@ -397,7 +370,7 @@ bail:
void qib_nomsi(struct qib_devdata *dd)
{
dd->msi_lo = 0;
- pci_disable_msi(dd->pcidev);
+ pci_free_irq_vectors(dd->pcidev);
}
/*
@@ -405,23 +378,21 @@ void qib_nomsi(struct qib_devdata *dd)
*/
void qib_nomsix(struct qib_devdata *dd)
{
- pci_disable_msix(dd->pcidev);
+ pci_free_irq_vectors(dd->pcidev);
}
/*
* Similar to pci_intx(pdev, 1), except that we make sure
* msi(x) is off.
*/
-void qib_enable_intx(struct pci_dev *pdev)
+void qib_enable_intx(struct qib_devdata *dd)
{
u16 cw, new;
int pos;
+ struct pci_dev *pdev = dd->pcidev;
- /* first, turn on INTx */
- pci_read_config_word(pdev, PCI_COMMAND, &cw);
- new = cw & ~PCI_COMMAND_INTX_DISABLE;
- if (new != cw)
- pci_write_config_word(pdev, PCI_COMMAND, new);
+ if (pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_LEGACY) < 0)
+ qib_dev_err(dd, "Failed to enable INTx\n");
pos = pdev->msi_cap;
if (pos) {
diff --git a/drivers/infiniband/hw/qib/qib_qp.c b/drivers/infiniband/hw/qib/qib_qp.c
index a343e3b..344e401 100644
--- a/drivers/infiniband/hw/qib/qib_qp.c
+++ b/drivers/infiniband/hw/qib/qib_qp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013 Intel Corporation. All rights reserved.
+ * Copyright (c) 2012 - 2017 Intel Corporation. All rights reserved.
* Copyright (c) 2006 - 2012 QLogic Corporation. * All rights reserved.
* Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
*
@@ -415,53 +415,16 @@ int qib_check_send_wqe(struct rvt_qp *qp,
#ifdef CONFIG_DEBUG_FS
-struct qib_qp_iter {
- struct qib_ibdev *dev;
- struct rvt_qp *qp;
- int n;
-};
-
-struct qib_qp_iter *qib_qp_iter_init(struct qib_ibdev *dev)
-{
- struct qib_qp_iter *iter;
-
- iter = kzalloc(sizeof(*iter), GFP_KERNEL);
- if (!iter)
- return NULL;
-
- iter->dev = dev;
-
- return iter;
-}
-
-int qib_qp_iter_next(struct qib_qp_iter *iter)
-{
- struct qib_ibdev *dev = iter->dev;
- int n = iter->n;
- int ret = 1;
- struct rvt_qp *pqp = iter->qp;
- struct rvt_qp *qp;
-
- for (; n < dev->rdi.qp_dev->qp_table_size; n++) {
- if (pqp)
- qp = rcu_dereference(pqp->next);
- else
- qp = rcu_dereference(dev->rdi.qp_dev->qp_table[n]);
- pqp = qp;
- if (qp) {
- iter->qp = qp;
- iter->n = n;
- return 0;
- }
- }
- return ret;
-}
-
static const char * const qp_type_str[] = {
"SMI", "GSI", "RC", "UC", "UD",
};
-void qib_qp_iter_print(struct seq_file *s, struct qib_qp_iter *iter)
+/**
+ * qib_qp_iter_print - print information to seq_file
+ * @s - the seq_file
+ * @iter - the iterator
+ */
+void qib_qp_iter_print(struct seq_file *s, struct rvt_qp_iter *iter)
{
struct rvt_swqe *wqe;
struct rvt_qp *qp = iter->qp;
diff --git a/drivers/infiniband/hw/qib/qib_rc.c b/drivers/infiniband/hw/qib/qib_rc.c
index 4ddbcac..e9a9173 100644
--- a/drivers/infiniband/hw/qib/qib_rc.c
+++ b/drivers/infiniband/hw/qib/qib_rc.c
@@ -348,7 +348,7 @@ int qib_make_rc_req(struct rvt_qp *qp, unsigned long *flags)
case IB_WR_RDMA_WRITE:
if (newreq && !(qp->s_flags & RVT_S_UNLIMITED_CREDIT))
qp->s_lsn++;
- /* FALLTHROUGH */
+ goto no_flow_control;
case IB_WR_RDMA_WRITE_WITH_IMM:
/* If no credit, return. */
if (!(qp->s_flags & RVT_S_UNLIMITED_CREDIT) &&
@@ -356,7 +356,7 @@ int qib_make_rc_req(struct rvt_qp *qp, unsigned long *flags)
qp->s_flags |= RVT_S_WAIT_SSN_CREDIT;
goto bail;
}
-
+no_flow_control:
ohdr->u.rc.reth.vaddr =
cpu_to_be64(wqe->rdma_wr.remote_addr);
ohdr->u.rc.reth.rkey =
diff --git a/drivers/infiniband/hw/qib/qib_ruc.c b/drivers/infiniband/hw/qib/qib_ruc.c
index bd09de7..53efbb0 100644
--- a/drivers/infiniband/hw/qib/qib_ruc.c
+++ b/drivers/infiniband/hw/qib/qib_ruc.c
@@ -58,8 +58,10 @@ static int qib_init_sge(struct rvt_qp *qp, struct rvt_rwqe *wqe)
if (wqe->sg_list[i].length == 0)
continue;
/* Check LKEY */
- if (!rvt_lkey_ok(rkt, pd, j ? &ss->sg_list[j - 1] : &ss->sge,
- &wqe->sg_list[i], IB_ACCESS_LOCAL_WRITE))
+ ret = rvt_lkey_ok(rkt, pd, j ? &ss->sg_list[j - 1] : &ss->sge,
+ NULL, &wqe->sg_list[i],
+ IB_ACCESS_LOCAL_WRITE);
+ if (unlikely(ret <= 0))
goto bad_lkey;
qp->r_len += wqe->sg_list[i].length;
j++;
@@ -256,11 +258,11 @@ int qib_ruc_check_hdr(struct qib_ibport *ibp, struct ib_header *hdr,
}
if (!qib_pkey_ok((u16)bth0,
qib_get_pkey(ibp, qp->s_alt_pkey_index))) {
- qib_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_PKEY,
- (u16)bth0,
- (be16_to_cpu(hdr->lrh[0]) >> 4) & 0xF,
- 0, qp->ibqp.qp_num,
- hdr->lrh[3], hdr->lrh[1]);
+ qib_bad_pkey(ibp,
+ (u16)bth0,
+ (be16_to_cpu(hdr->lrh[0]) >> 4) & 0xF,
+ 0, qp->ibqp.qp_num,
+ hdr->lrh[3], hdr->lrh[1]);
goto err;
}
/* Validate the SLID. See Ch. 9.6.1.5 and 17.2.8 */
@@ -295,11 +297,11 @@ int qib_ruc_check_hdr(struct qib_ibport *ibp, struct ib_header *hdr,
}
if (!qib_pkey_ok((u16)bth0,
qib_get_pkey(ibp, qp->s_pkey_index))) {
- qib_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_PKEY,
- (u16)bth0,
- (be16_to_cpu(hdr->lrh[0]) >> 4) & 0xF,
- 0, qp->ibqp.qp_num,
- hdr->lrh[3], hdr->lrh[1]);
+ qib_bad_pkey(ibp,
+ (u16)bth0,
+ (be16_to_cpu(hdr->lrh[0]) >> 4) & 0xF,
+ 0, qp->ibqp.qp_num,
+ hdr->lrh[3], hdr->lrh[1]);
goto err;
}
/* Validate the SLID. See Ch. 9.6.1.5 */
@@ -643,8 +645,10 @@ u32 qib_make_grh(struct qib_ibport *ibp, struct ib_grh *hdr,
hdr->hop_limit = grh->hop_limit;
/* The SGID is 32-bit aligned. */
hdr->sgid.global.subnet_prefix = ibp->rvp.gid_prefix;
- hdr->sgid.global.interface_id = grh->sgid_index ?
- ibp->guids[grh->sgid_index - 1] : ppd_from_ibp(ibp)->guid;
+ if (!grh->sgid_index)
+ hdr->sgid.global.interface_id = ppd_from_ibp(ibp)->guid;
+ else if (grh->sgid_index < QIB_GUIDS_PER_PORT)
+ hdr->sgid.global.interface_id = ibp->guids[grh->sgid_index - 1];
hdr->dgid = grh->dgid;
/* GRH header size in 32-bit words. */
diff --git a/drivers/infiniband/hw/qib/qib_sysfs.c b/drivers/infiniband/hw/qib/qib_sysfs.c
index fe4cf5e..ca2638d 100644
--- a/drivers/infiniband/hw/qib/qib_sysfs.c
+++ b/drivers/infiniband/hw/qib/qib_sysfs.c
@@ -247,7 +247,7 @@ static struct kobj_type qib_port_cc_ktype = {
.release = qib_port_release,
};
-static struct bin_attribute cc_table_bin_attr = {
+static const struct bin_attribute cc_table_bin_attr = {
.attr = {.name = "cc_table_bin", .mode = 0444},
.read = read_cc_table_bin,
.size = PAGE_SIZE,
@@ -286,7 +286,7 @@ static ssize_t read_cc_setting_bin(struct file *filp, struct kobject *kobj,
return count;
}
-static struct bin_attribute cc_setting_bin_attr = {
+static const struct bin_attribute cc_setting_bin_attr = {
.attr = {.name = "cc_settings_bin", .mode = 0444},
.read = read_cc_setting_bin,
.size = PAGE_SIZE,
diff --git a/drivers/infiniband/hw/qib/qib_ud.c b/drivers/infiniband/hw/qib/qib_ud.c
index 341a123..be49074 100644
--- a/drivers/infiniband/hw/qib/qib_ud.c
+++ b/drivers/infiniband/hw/qib/qib_ud.c
@@ -66,8 +66,7 @@ static void qib_ud_loopback(struct rvt_qp *sqp, struct rvt_swqe *swqe)
qp = rvt_lookup_qpn(rdi, &ibp->rvp, swqe->ud_wr.remote_qpn);
if (!qp) {
ibp->rvp.n_pkt_drops++;
- rcu_read_unlock();
- return;
+ goto drop;
}
sqptype = sqp->ibqp.qp_type == IB_QPT_GSI ?
@@ -94,11 +93,11 @@ static void qib_ud_loopback(struct rvt_qp *sqp, struct rvt_swqe *swqe)
if (unlikely(!qib_pkey_ok(pkey1, pkey2))) {
lid = ppd->lid | (rdma_ah_get_path_bits(ah_attr) &
((1 << ppd->lmc) - 1));
- qib_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_PKEY, pkey1,
- rdma_ah_get_sl(ah_attr),
- sqp->ibqp.qp_num, qp->ibqp.qp_num,
- cpu_to_be16(lid),
- cpu_to_be16(rdma_ah_get_dlid(ah_attr)));
+ qib_bad_pkey(ibp, pkey1,
+ rdma_ah_get_sl(ah_attr),
+ sqp->ibqp.qp_num, qp->ibqp.qp_num,
+ cpu_to_be16(lid),
+ cpu_to_be16(rdma_ah_get_dlid(ah_attr)));
goto drop;
}
}
@@ -113,18 +112,8 @@ static void qib_ud_loopback(struct rvt_qp *sqp, struct rvt_swqe *swqe)
qkey = (int)swqe->ud_wr.remote_qkey < 0 ?
sqp->qkey : swqe->ud_wr.remote_qkey;
- if (unlikely(qkey != qp->qkey)) {
- u16 lid;
-
- lid = ppd->lid | (rdma_ah_get_path_bits(ah_attr) &
- ((1 << ppd->lmc) - 1));
- qib_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_QKEY, qkey,
- rdma_ah_get_sl(ah_attr),
- sqp->ibqp.qp_num, qp->ibqp.qp_num,
- cpu_to_be16(lid),
- cpu_to_be16(rdma_ah_get_dlid(ah_attr)));
+ if (unlikely(qkey != qp->qkey))
goto drop;
- }
}
/*
@@ -487,22 +476,18 @@ void qib_ud_rcv(struct qib_ibport *ibp, struct ib_header *hdr,
pkey1 = be32_to_cpu(ohdr->bth[0]);
pkey2 = qib_get_pkey(ibp, qp->s_pkey_index);
if (unlikely(!qib_pkey_ok(pkey1, pkey2))) {
- qib_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_PKEY,
- pkey1,
- (be16_to_cpu(hdr->lrh[0]) >> 4) &
+ qib_bad_pkey(ibp,
+ pkey1,
+ (be16_to_cpu(hdr->lrh[0]) >> 4) &
0xF,
- src_qp, qp->ibqp.qp_num,
- hdr->lrh[3], hdr->lrh[1]);
+ src_qp, qp->ibqp.qp_num,
+ hdr->lrh[3], hdr->lrh[1]);
return;
}
}
- if (unlikely(qkey != qp->qkey)) {
- qib_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_QKEY, qkey,
- (be16_to_cpu(hdr->lrh[0]) >> 4) & 0xF,
- src_qp, qp->ibqp.qp_num,
- hdr->lrh[3], hdr->lrh[1]);
+ if (unlikely(qkey != qp->qkey))
return;
- }
+
/* Drop invalid MAD packets (see 13.5.3.1). */
if (unlikely(qp->ibqp.qp_num == 1 &&
(tlen != 256 ||
diff --git a/drivers/infiniband/hw/qib/qib_verbs.c b/drivers/infiniband/hw/qib/qib_verbs.c
index ac42dce..9d92aeb 100644
--- a/drivers/infiniband/hw/qib/qib_verbs.c
+++ b/drivers/infiniband/hw/qib/qib_verbs.c
@@ -1341,6 +1341,15 @@ int qib_check_ah(struct ib_device *ibdev, struct rdma_ah_attr *ah_attr)
if (rdma_ah_get_sl(ah_attr) > 15)
return -EINVAL;
+ if (rdma_ah_get_dlid(ah_attr) == 0)
+ return -EINVAL;
+ if (rdma_ah_get_dlid(ah_attr) >=
+ be16_to_cpu(IB_MULTICAST_LID_BASE) &&
+ rdma_ah_get_dlid(ah_attr) !=
+ be16_to_cpu(IB_LID_PERMISSIVE) &&
+ !(rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH))
+ return -EINVAL;
+
return 0;
}
diff --git a/drivers/infiniband/hw/qib/qib_verbs.h b/drivers/infiniband/hw/qib/qib_verbs.h
index a52fc67..f887737 100644
--- a/drivers/infiniband/hw/qib/qib_verbs.h
+++ b/drivers/infiniband/hw/qib/qib_verbs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013 Intel Corporation. All rights reserved.
+ * Copyright (c) 2012 - 2017 Intel Corporation. All rights reserved.
* Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved.
* Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
*
@@ -241,8 +241,8 @@ static inline int qib_pkey_ok(u16 pkey1, u16 pkey2)
return p1 && p1 == p2 && ((__s16)pkey1 < 0 || (__s16)pkey2 < 0);
}
-void qib_bad_pqkey(struct qib_ibport *ibp, __be16 trap_num, u32 key, u32 sl,
- u32 qp1, u32 qp2, __be16 lid1, __be16 lid2);
+void qib_bad_pkey(struct qib_ibport *ibp, u32 key, u32 sl,
+ u32 qp1, u32 qp2, __be16 lid1, __be16 lid2);
void qib_cap_mask_chg(struct rvt_dev_info *rdi, u8 port_num);
void qib_sys_guid_chg(struct qib_ibport *ibp);
void qib_node_desc_chg(struct qib_ibport *ibp);
@@ -282,13 +282,7 @@ int qib_alloc_qpn(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt,
void qib_restart_rc(struct rvt_qp *qp, u32 psn, int wait);
#ifdef CONFIG_DEBUG_FS
-struct qib_qp_iter;
-
-struct qib_qp_iter *qib_qp_iter_init(struct qib_ibdev *dev);
-
-int qib_qp_iter_next(struct qib_qp_iter *iter);
-
-void qib_qp_iter_print(struct seq_file *s, struct qib_qp_iter *iter);
+void qib_qp_iter_print(struct seq_file *s, struct rvt_qp_iter *iter);
#endif
diff --git a/drivers/infiniband/hw/usnic/usnic_fwd.c b/drivers/infiniband/hw/usnic/usnic_fwd.c
index 3c37dd5..995a26b 100644
--- a/drivers/infiniband/hw/usnic/usnic_fwd.c
+++ b/drivers/infiniband/hw/usnic/usnic_fwd.c
@@ -110,20 +110,12 @@ void usnic_fwd_set_mac(struct usnic_fwd_dev *ufdev, char mac[ETH_ALEN])
spin_unlock(&ufdev->lock);
}
-int usnic_fwd_add_ipaddr(struct usnic_fwd_dev *ufdev, __be32 inaddr)
+void usnic_fwd_add_ipaddr(struct usnic_fwd_dev *ufdev, __be32 inaddr)
{
- int status;
-
spin_lock(&ufdev->lock);
- if (ufdev->inaddr == 0) {
+ if (!ufdev->inaddr)
ufdev->inaddr = inaddr;
- status = 0;
- } else {
- status = -EFAULT;
- }
spin_unlock(&ufdev->lock);
-
- return status;
}
void usnic_fwd_del_ipaddr(struct usnic_fwd_dev *ufdev)
diff --git a/drivers/infiniband/hw/usnic/usnic_fwd.h b/drivers/infiniband/hw/usnic/usnic_fwd.h
index b2ac22b..0b2cc4e 100644
--- a/drivers/infiniband/hw/usnic/usnic_fwd.h
+++ b/drivers/infiniband/hw/usnic/usnic_fwd.h
@@ -75,7 +75,7 @@ struct usnic_fwd_dev *usnic_fwd_dev_alloc(struct pci_dev *pdev);
void usnic_fwd_dev_free(struct usnic_fwd_dev *ufdev);
void usnic_fwd_set_mac(struct usnic_fwd_dev *ufdev, char mac[ETH_ALEN]);
-int usnic_fwd_add_ipaddr(struct usnic_fwd_dev *ufdev, __be32 inaddr);
+void usnic_fwd_add_ipaddr(struct usnic_fwd_dev *ufdev, __be32 inaddr);
void usnic_fwd_del_ipaddr(struct usnic_fwd_dev *ufdev);
void usnic_fwd_carrier_up(struct usnic_fwd_dev *ufdev);
void usnic_fwd_carrier_down(struct usnic_fwd_dev *ufdev);
diff --git a/drivers/infiniband/hw/usnic/usnic_ib_main.c b/drivers/infiniband/hw/usnic/usnic_ib_main.c
index c0c1e8b..f45e99a 100644
--- a/drivers/infiniband/hw/usnic/usnic_ib_main.c
+++ b/drivers/infiniband/hw/usnic/usnic_ib_main.c
@@ -333,9 +333,7 @@ static int usnic_port_immutable(struct ib_device *ibdev, u8 port_num,
return 0;
}
-static void usnic_get_dev_fw_str(struct ib_device *device,
- char *str,
- size_t str_len)
+static void usnic_get_dev_fw_str(struct ib_device *device, char *str)
{
struct usnic_ib_dev *us_ibdev =
container_of(device, struct usnic_ib_dev, ib_dev);
@@ -345,7 +343,7 @@ static void usnic_get_dev_fw_str(struct ib_device *device,
us_ibdev->netdev->ethtool_ops->get_drvinfo(us_ibdev->netdev, &info);
mutex_unlock(&us_ibdev->usdev_lock);
- snprintf(str, str_len, "%s", info.fw_version);
+ snprintf(str, IB_FW_VERSION_NAME_MAX, "%s", info.fw_version);
}
/* Start of PF discovery section */
@@ -353,7 +351,7 @@ static void *usnic_ib_device_add(struct pci_dev *dev)
{
struct usnic_ib_dev *us_ibdev;
union ib_gid gid;
- struct in_ifaddr *in;
+ struct in_device *ind;
struct net_device *netdev;
usnic_dbg("\n");
@@ -409,6 +407,7 @@ static void *usnic_ib_device_add(struct pci_dev *dev)
us_ibdev->ib_dev.query_port = usnic_ib_query_port;
us_ibdev->ib_dev.query_pkey = usnic_ib_query_pkey;
us_ibdev->ib_dev.query_gid = usnic_ib_query_gid;
+ us_ibdev->ib_dev.get_netdev = usnic_get_netdev;
us_ibdev->ib_dev.get_link_layer = usnic_ib_port_link_layer;
us_ibdev->ib_dev.alloc_pd = usnic_ib_alloc_pd;
us_ibdev->ib_dev.dealloc_pd = usnic_ib_dealloc_pd;
@@ -442,9 +441,11 @@ static void *usnic_ib_device_add(struct pci_dev *dev)
if (netif_carrier_ok(us_ibdev->netdev))
usnic_fwd_carrier_up(us_ibdev->ufdev);
- in = ((struct in_device *)(netdev->ip_ptr))->ifa_list;
- if (in != NULL)
- usnic_fwd_add_ipaddr(us_ibdev->ufdev, in->ifa_address);
+ ind = in_dev_get(netdev);
+ if (ind->ifa_list)
+ usnic_fwd_add_ipaddr(us_ibdev->ufdev,
+ ind->ifa_list->ifa_address);
+ in_dev_put(ind);
usnic_mac_ip_to_gid(us_ibdev->netdev->perm_addr,
us_ibdev->ufdev->inaddr, &gid.raw[0]);
@@ -720,7 +721,6 @@ static void __exit usnic_ib_destroy(void)
MODULE_DESCRIPTION("Cisco VIC (usNIC) Verbs Driver");
MODULE_AUTHOR("Upinder Malhi <umalhi@cisco.com>");
MODULE_LICENSE("Dual BSD/GPL");
-MODULE_VERSION(DRV_VERSION);
module_param(usnic_log_lvl, uint, S_IRUGO | S_IWUSR);
module_param(usnic_ib_share_vf, uint, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(usnic_log_lvl, " Off=0, Err=1, Info=2, Debug=3");
diff --git a/drivers/infiniband/hw/usnic/usnic_ib_verbs.c b/drivers/infiniband/hw/usnic/usnic_ib_verbs.c
index 4996984..e4113ef 100644
--- a/drivers/infiniband/hw/usnic/usnic_ib_verbs.c
+++ b/drivers/infiniband/hw/usnic/usnic_ib_verbs.c
@@ -164,6 +164,8 @@ find_free_vf_and_create_qp_grp(struct usnic_ib_dev *us_ibdev,
if (usnic_ib_share_vf) {
/* Try to find resouces on a used vf which is in pd */
dev_list = usnic_uiom_get_dev_list(pd->umem_pd);
+ if (IS_ERR(dev_list))
+ return ERR_CAST(dev_list);
for (i = 0; dev_list[i]; i++) {
dev = dev_list[i];
vf = pci_get_drvdata(to_pci_dev(dev));
@@ -226,27 +228,6 @@ static void qp_grp_destroy(struct usnic_ib_qp_grp *qp_grp)
spin_unlock(&vf->lock);
}
-static void eth_speed_to_ib_speed(int speed, u8 *active_speed,
- u8 *active_width)
-{
- if (speed <= 10000) {
- *active_width = IB_WIDTH_1X;
- *active_speed = IB_SPEED_FDR10;
- } else if (speed <= 20000) {
- *active_width = IB_WIDTH_4X;
- *active_speed = IB_SPEED_DDR;
- } else if (speed <= 30000) {
- *active_width = IB_WIDTH_4X;
- *active_speed = IB_SPEED_QDR;
- } else if (speed <= 40000) {
- *active_width = IB_WIDTH_4X;
- *active_speed = IB_SPEED_FDR10;
- } else {
- *active_width = IB_WIDTH_4X;
- *active_speed = IB_SPEED_EDR;
- }
-}
-
static int create_qp_validate_user_data(struct usnic_ib_create_qp_cmd cmd)
{
if (cmd.spec.trans_type <= USNIC_TRANSPORT_UNKNOWN ||
@@ -326,12 +307,16 @@ int usnic_ib_query_port(struct ib_device *ibdev, u8 port,
struct ib_port_attr *props)
{
struct usnic_ib_dev *us_ibdev = to_usdev(ibdev);
- struct ethtool_link_ksettings cmd;
usnic_dbg("\n");
mutex_lock(&us_ibdev->usdev_lock);
- __ethtool_get_link_ksettings(us_ibdev->netdev, &cmd);
+ if (ib_get_eth_speed(ibdev, port, &props->active_speed,
+ &props->active_width)) {
+ mutex_unlock(&us_ibdev->usdev_lock);
+ return -EINVAL;
+ }
+
/* props being zeroed by the caller, avoid zeroing it here */
props->lid = 0;
@@ -355,8 +340,6 @@ int usnic_ib_query_port(struct ib_device *ibdev, u8 port,
props->pkey_tbl_len = 1;
props->bad_pkey_cntr = 0;
props->qkey_viol_cntr = 0;
- eth_speed_to_ib_speed(cmd.base.speed, &props->active_speed,
- &props->active_width);
props->max_mtu = IB_MTU_4096;
props->active_mtu = iboe_get_mtu(us_ibdev->ufdev->mtu);
/* Userspace will adjust for hdrs */
@@ -424,6 +407,16 @@ int usnic_ib_query_gid(struct ib_device *ibdev, u8 port, int index,
return 0;
}
+struct net_device *usnic_get_netdev(struct ib_device *device, u8 port_num)
+{
+ struct usnic_ib_dev *us_ibdev = to_usdev(device);
+
+ if (us_ibdev->netdev)
+ dev_hold(us_ibdev->netdev);
+
+ return us_ibdev->netdev;
+}
+
int usnic_ib_query_pkey(struct ib_device *ibdev, u8 port, u16 index,
u16 *pkey)
{
diff --git a/drivers/infiniband/hw/usnic/usnic_ib_verbs.h b/drivers/infiniband/hw/usnic/usnic_ib_verbs.h
index 172e43b..1fda944 100644
--- a/drivers/infiniband/hw/usnic/usnic_ib_verbs.h
+++ b/drivers/infiniband/hw/usnic/usnic_ib_verbs.h
@@ -48,6 +48,7 @@ int usnic_ib_query_qp(struct ib_qp *qp, struct ib_qp_attr *qp_attr,
struct ib_qp_init_attr *qp_init_attr);
int usnic_ib_query_gid(struct ib_device *ibdev, u8 port, int index,
union ib_gid *gid);
+struct net_device *usnic_get_netdev(struct ib_device *device, u8 port_num);
int usnic_ib_query_pkey(struct ib_device *ibdev, u8 port, u16 index,
u16 *pkey);
struct ib_pd *usnic_ib_alloc_pd(struct ib_device *ibdev,
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h b/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h
index 8e2f0a1..663a0c3 100644
--- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h
@@ -194,6 +194,7 @@ struct pvrdma_dev {
void *resp_slot;
unsigned long flags;
struct list_head device_link;
+ unsigned int dsr_version;
/* Locking and interrupt information. */
spinlock_t cmd_lock; /* Command lock. */
@@ -444,6 +445,7 @@ void pvrdma_ah_attr_to_rdma(struct rdma_ah_attr *dst,
const struct pvrdma_ah_attr *src);
void rdma_ah_attr_to_pvrdma(struct pvrdma_ah_attr *dst,
const struct rdma_ah_attr *src);
+u8 ib_gid_type_to_pvrdma(enum ib_gid_type gid_type);
int pvrdma_uar_table_init(struct pvrdma_dev *dev);
void pvrdma_uar_table_cleanup(struct pvrdma_dev *dev);
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c
index 90aa326..3562c0c 100644
--- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c
@@ -299,7 +299,7 @@ static inline struct pvrdma_cqe *get_cqe(struct pvrdma_cq *cq, int i)
void _pvrdma_flush_cqe(struct pvrdma_qp *qp, struct pvrdma_cq *cq)
{
- int head;
+ unsigned int head;
int has_data;
if (!cq->is_kernel)
@@ -389,6 +389,7 @@ retry:
wc->dlid_path_bits = cqe->dlid_path_bits;
wc->port_num = cqe->port_num;
wc->vendor_err = cqe->vendor_err;
+ wc->network_hdr_type = cqe->network_hdr_type;
/* Update shared ring state */
pvrdma_idx_ring_inc(&cq->ring_state->rx.cons_head, cq->ibcq.cqe);
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_dev_api.h b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_dev_api.h
index 09078cc..df0a6b5 100644
--- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_dev_api.h
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_dev_api.h
@@ -50,7 +50,15 @@
#include "pvrdma_verbs.h"
-#define PVRDMA_VERSION 17
+/*
+ * PVRDMA version macros. Some new features require updates to PVRDMA_VERSION.
+ * These macros allow us to check for different features if necessary.
+ */
+
+#define PVRDMA_ROCEV1_VERSION 17
+#define PVRDMA_ROCEV2_VERSION 18
+#define PVRDMA_VERSION PVRDMA_ROCEV2_VERSION
+
#define PVRDMA_BOARD_ID 1
#define PVRDMA_REV_ID 1
@@ -123,6 +131,31 @@
#define PVRDMA_GID_TYPE_FLAG_ROCE_V1 BIT(0)
#define PVRDMA_GID_TYPE_FLAG_ROCE_V2 BIT(1)
+/*
+ * Version checks. This checks whether each version supports specific
+ * capabilities from the device.
+ */
+
+#define PVRDMA_IS_VERSION17(_dev) \
+ (_dev->dsr_version == PVRDMA_ROCEV1_VERSION && \
+ _dev->dsr->caps.gid_types == PVRDMA_GID_TYPE_FLAG_ROCE_V1)
+
+#define PVRDMA_IS_VERSION18(_dev) \
+ (_dev->dsr_version >= PVRDMA_ROCEV2_VERSION && \
+ (_dev->dsr->caps.gid_types == PVRDMA_GID_TYPE_FLAG_ROCE_V1 || \
+ _dev->dsr->caps.gid_types == PVRDMA_GID_TYPE_FLAG_ROCE_V2)) \
+
+#define PVRDMA_SUPPORTED(_dev) \
+ ((_dev->dsr->caps.mode == PVRDMA_DEVICE_MODE_ROCE) && \
+ (PVRDMA_IS_VERSION17(_dev) || PVRDMA_IS_VERSION18(_dev)))
+
+/*
+ * Get capability values based on device version.
+ */
+
+#define PVRDMA_GET_CAP(_dev, _old_val, _val) \
+ ((PVRDMA_IS_VERSION18(_dev)) ? _val : _old_val)
+
enum pvrdma_pci_resource {
PVRDMA_PCI_RESOURCE_MSIX, /* BAR0: MSI-X, MMIO. */
PVRDMA_PCI_RESOURCE_REG, /* BAR1: Registers, MMIO. */
@@ -225,7 +258,7 @@ struct pvrdma_device_caps {
u8 atomic_ops; /* PVRDMA_ATOMIC_OP_* bits */
u8 bmme_flags; /* FRWR Mem Mgmt Extensions */
u8 gid_types; /* PVRDMA_GID_TYPE_FLAG_ */
- u8 reserved[4];
+ u32 max_fast_reg_page_list_len;
};
struct pvrdma_ring_page_info {
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c
index 34ebc76..6ce709a 100644
--- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c
@@ -102,12 +102,11 @@ static struct device_attribute *pvrdma_class_attributes[] = {
&dev_attr_board_id
};
-static void pvrdma_get_fw_ver_str(struct ib_device *device, char *str,
- size_t str_len)
+static void pvrdma_get_fw_ver_str(struct ib_device *device, char *str)
{
struct pvrdma_dev *dev =
container_of(device, struct pvrdma_dev, ib_dev);
- snprintf(str, str_len, "%d.%d.%d\n",
+ snprintf(str, IB_FW_VERSION_NAME_MAX, "%d.%d.%d\n",
(int) (dev->dsr->caps.fw_ver >> 32),
(int) (dev->dsr->caps.fw_ver >> 16) & 0xffff,
(int) dev->dsr->caps.fw_ver & 0xffff);
@@ -129,10 +128,14 @@ static int pvrdma_init_device(struct pvrdma_dev *dev)
static int pvrdma_port_immutable(struct ib_device *ibdev, u8 port_num,
struct ib_port_immutable *immutable)
{
+ struct pvrdma_dev *dev = to_vdev(ibdev);
struct ib_port_attr attr;
int err;
- immutable->core_cap_flags = RDMA_CORE_PORT_IBA_ROCE;
+ if (dev->dsr->caps.gid_types == PVRDMA_GID_TYPE_FLAG_ROCE_V1)
+ immutable->core_cap_flags |= RDMA_CORE_PORT_IBA_ROCE;
+ else if (dev->dsr->caps.gid_types == PVRDMA_GID_TYPE_FLAG_ROCE_V2)
+ immutable->core_cap_flags |= RDMA_CORE_PORT_IBA_ROCE_UDP_ENCAP;
err = ib_query_port(ibdev, port_num, &attr);
if (err)
@@ -570,6 +573,7 @@ static void pvrdma_free_slots(struct pvrdma_dev *dev)
static int pvrdma_add_gid_at_index(struct pvrdma_dev *dev,
const union ib_gid *gid,
+ u8 gid_type,
int index)
{
int ret;
@@ -587,7 +591,7 @@ static int pvrdma_add_gid_at_index(struct pvrdma_dev *dev,
cmd_bind->mtu = ib_mtu_enum_to_int(IB_MTU_1024);
cmd_bind->vlan = 0xfff;
cmd_bind->index = index;
- cmd_bind->gid_type = PVRDMA_GID_TYPE_FLAG_ROCE_V1;
+ cmd_bind->gid_type = gid_type;
ret = pvrdma_cmd_post(dev, &req, NULL, 0);
if (ret < 0) {
@@ -608,7 +612,9 @@ static int pvrdma_add_gid(struct ib_device *ibdev,
{
struct pvrdma_dev *dev = to_vdev(ibdev);
- return pvrdma_add_gid_at_index(dev, gid, index);
+ return pvrdma_add_gid_at_index(dev, gid,
+ ib_gid_type_to_pvrdma(attr->gid_type),
+ index);
}
static int pvrdma_del_gid_at_index(struct pvrdma_dev *dev, int index)
@@ -723,7 +729,6 @@ static int pvrdma_pci_probe(struct pci_dev *pdev,
int ret;
unsigned long start;
unsigned long len;
- unsigned int version;
dma_addr_t slot_dma = 0;
dev_dbg(&pdev->dev, "initializing driver %s\n", pci_name(pdev));
@@ -820,13 +825,9 @@ static int pvrdma_pci_probe(struct pci_dev *pdev,
goto err_unmap_regs;
}
- version = pvrdma_read_reg(dev, PVRDMA_REG_VERSION);
+ dev->dsr_version = pvrdma_read_reg(dev, PVRDMA_REG_VERSION);
dev_info(&pdev->dev, "device version %d, driver version %d\n",
- version, PVRDMA_VERSION);
- if (version < PVRDMA_VERSION) {
- dev_err(&pdev->dev, "incompatible device version\n");
- goto err_uar_unmap;
- }
+ dev->dsr_version, PVRDMA_VERSION);
dev->dsr = dma_alloc_coherent(&pdev->dev, sizeof(*dev->dsr),
&dev->dsrbase, GFP_KERNEL);
@@ -897,17 +898,9 @@ static int pvrdma_pci_probe(struct pci_dev *pdev,
/* Make sure the write is complete before reading status. */
mb();
- /* Currently, the driver only supports RoCE mode. */
- if (dev->dsr->caps.mode != PVRDMA_DEVICE_MODE_ROCE) {
- dev_err(&pdev->dev, "unsupported transport %d\n",
- dev->dsr->caps.mode);
- ret = -EFAULT;
- goto err_free_cq_ring;
- }
-
- /* Currently, the driver only supports RoCE V1. */
- if (!(dev->dsr->caps.gid_types & PVRDMA_GID_TYPE_FLAG_ROCE_V1)) {
- dev_err(&pdev->dev, "driver needs RoCE v1 support\n");
+ /* The driver supports RoCE V1 and V2. */
+ if (!PVRDMA_SUPPORTED(dev)) {
+ dev_err(&pdev->dev, "driver needs RoCE v1 or v2 support\n");
ret = -EFAULT;
goto err_free_cq_ring;
}
@@ -1078,7 +1071,7 @@ static void pvrdma_pci_remove(struct pci_dev *pdev)
pci_set_drvdata(pdev, NULL);
}
-static struct pci_device_id pvrdma_pci_table[] = {
+static const struct pci_device_id pvrdma_pci_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_VMWARE, PCI_DEVICE_ID_VMWARE_PVRDMA), },
{ 0 },
};
@@ -1119,5 +1112,4 @@ module_exit(pvrdma_cleanup);
MODULE_AUTHOR("VMware, Inc");
MODULE_DESCRIPTION("VMware Paravirtual RDMA driver");
-MODULE_VERSION(DRV_VERSION);
MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_misc.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_misc.c
index ec6a4ca..fb0c5c0 100644
--- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_misc.c
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_misc.c
@@ -303,3 +303,10 @@ void rdma_ah_attr_to_pvrdma(struct pvrdma_ah_attr *dst,
dst->port_num = rdma_ah_get_port_num(src);
memcpy(&dst->dmac, src->roce.dmac, sizeof(dst->dmac));
}
+
+u8 ib_gid_type_to_pvrdma(enum ib_gid_type gid_type)
+{
+ return (gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP) ?
+ PVRDMA_GID_TYPE_FLAG_ROCE_V2 :
+ PVRDMA_GID_TYPE_FLAG_ROCE_V1;
+}
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_ring.h b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_ring.h
index ed9022a..8b558ae 100644
--- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_ring.h
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_ring.h
@@ -111,21 +111,4 @@ static inline __s32 pvrdma_idx_ring_has_data(const struct pvrdma_ring *r,
return PVRDMA_INVALID_IDX;
}
-static inline bool pvrdma_idx_ring_is_valid_idx(const struct pvrdma_ring *r,
- __u32 max_elems, __u32 *idx)
-{
- const __u32 tail = atomic_read(&r->prod_tail);
- const __u32 head = atomic_read(&r->cons_head);
-
- if (pvrdma_idx_valid(tail, max_elems) &&
- pvrdma_idx_valid(head, max_elems) &&
- pvrdma_idx_valid(*idx, max_elems)) {
- if (tail > head && (*idx < tail && *idx >= head))
- return true;
- else if (head > tail && (*idx >= head || *idx < tail))
- return true;
- }
- return false;
-}
-
#endif /* __PVRDMA_RING_H__ */
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
index 2851704..48776f5 100644
--- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
@@ -83,6 +83,8 @@ int pvrdma_query_device(struct ib_device *ibdev,
props->max_qp_wr = dev->dsr->caps.max_qp_wr;
props->device_cap_flags = dev->dsr->caps.device_cap_flags;
props->max_sge = dev->dsr->caps.max_sge;
+ props->max_sge_rd = PVRDMA_GET_CAP(dev, dev->dsr->caps.max_sge,
+ dev->dsr->caps.max_sge_rd);
props->max_cq = dev->dsr->caps.max_cq;
props->max_cqe = dev->dsr->caps.max_cqe;
props->max_mr = dev->dsr->caps.max_mr;
@@ -101,8 +103,14 @@ int pvrdma_query_device(struct ib_device *ibdev,
(dev->dsr->caps.bmme_flags & PVRDMA_BMME_FLAG_REMOTE_INV) &&
(dev->dsr->caps.bmme_flags & PVRDMA_BMME_FLAG_FAST_REG_WR)) {
props->device_cap_flags |= IB_DEVICE_MEM_MGT_EXTENSIONS;
+ props->max_fast_reg_page_list_len = PVRDMA_GET_CAP(dev,
+ PVRDMA_MAX_FAST_REG_PAGES,
+ dev->dsr->caps.max_fast_reg_page_list_len);
}
+ props->device_cap_flags |= IB_DEVICE_PORT_ACTIVE_EVENT |
+ IB_DEVICE_RC_RNR_NAK_GEN;
+
return 0;
}
@@ -143,6 +151,7 @@ int pvrdma_query_port(struct ib_device *ibdev, u8 port,
props->gid_tbl_len = resp->attrs.gid_tbl_len;
props->port_cap_flags =
pvrdma_port_cap_flags_to_ib(resp->attrs.port_cap_flags);
+ props->port_cap_flags |= IB_PORT_CM_SUP | IB_PORT_IP_BASED_GIDS;
props->max_msg_sz = resp->attrs.max_msg_sz;
props->bad_pkey_cntr = resp->attrs.bad_pkey_cntr;
props->qkey_viol_cntr = resp->attrs.qkey_viol_cntr;
diff --git a/drivers/infiniband/sw/rdmavt/ah.c b/drivers/infiniband/sw/rdmavt/ah.c
index a96d4aa..ba3639a 100644
--- a/drivers/infiniband/sw/rdmavt/ah.c
+++ b/drivers/infiniband/sw/rdmavt/ah.c
@@ -66,8 +66,6 @@ int rvt_check_ah(struct ib_device *ibdev,
int port_num = rdma_ah_get_port_num(ah_attr);
struct ib_port_attr port_attr;
struct rvt_dev_info *rdi = ib_to_rvt(ibdev);
- enum rdma_link_layer link = rdma_port_get_link_layer(ibdev, port_num);
- u32 dlid = rdma_ah_get_dlid(ah_attr);
u8 ah_flags = rdma_ah_get_ah_flags(ah_attr);
u8 static_rate = rdma_ah_get_static_rate(ah_attr);
@@ -83,14 +81,6 @@ int rvt_check_ah(struct ib_device *ibdev,
if ((ah_flags & IB_AH_GRH) &&
rdma_ah_read_grh(ah_attr)->sgid_index >= port_attr.gid_tbl_len)
return -EINVAL;
- if (link != IB_LINK_LAYER_ETHERNET) {
- if (dlid == 0)
- return -EINVAL;
- if (dlid >= be16_to_cpu(IB_MULTICAST_LID_BASE) &&
- dlid != be16_to_cpu(IB_LID_PERMISSIVE) &&
- !(ah_flags & IB_AH_GRH))
- return -EINVAL;
- }
if (rdi->driver_f.check_ah)
return rdi->driver_f.check_ah(ibdev, ah_attr);
return 0;
diff --git a/drivers/infiniband/sw/rdmavt/cq.c b/drivers/infiniband/sw/rdmavt/cq.c
index 0ae2ff8..97d71e4 100644
--- a/drivers/infiniband/sw/rdmavt/cq.c
+++ b/drivers/infiniband/sw/rdmavt/cq.c
@@ -107,7 +107,7 @@ void rvt_cq_enter(struct rvt_cq *cq, struct ib_wc *entry, bool solicited)
wc->uqueue[head].src_qp = entry->src_qp;
wc->uqueue[head].wc_flags = entry->wc_flags;
wc->uqueue[head].pkey_index = entry->pkey_index;
- wc->uqueue[head].slid = entry->slid;
+ wc->uqueue[head].slid = ib_lid_cpu16(entry->slid);
wc->uqueue[head].sl = entry->sl;
wc->uqueue[head].dlid_path_bits = entry->dlid_path_bits;
wc->uqueue[head].port_num = entry->port_num;
diff --git a/drivers/infiniband/sw/rdmavt/mr.c b/drivers/infiniband/sw/rdmavt/mr.c
index aa5f9ea3..4271351 100644
--- a/drivers/infiniband/sw/rdmavt/mr.c
+++ b/drivers/infiniband/sw/rdmavt/mr.c
@@ -441,6 +441,105 @@ bail_umem:
}
/**
+ * rvt_dereg_clean_qp_cb - callback from iterator
+ * @qp - the qp
+ * @v - the mregion (as u64)
+ *
+ * This routine fields the callback for all QPs and
+ * for QPs in the same PD as the MR will call the
+ * rvt_qp_mr_clean() to potentially cleanup references.
+ */
+static void rvt_dereg_clean_qp_cb(struct rvt_qp *qp, u64 v)
+{
+ struct rvt_mregion *mr = (struct rvt_mregion *)v;
+
+ /* skip PDs that are not ours */
+ if (mr->pd != qp->ibqp.pd)
+ return;
+ rvt_qp_mr_clean(qp, mr->lkey);
+}
+
+/**
+ * rvt_dereg_clean_qps - find QPs for reference cleanup
+ * @mr - the MR that is being deregistered
+ *
+ * This routine iterates RC QPs looking for references
+ * to the lkey noted in mr.
+ */
+static void rvt_dereg_clean_qps(struct rvt_mregion *mr)
+{
+ struct rvt_dev_info *rdi = ib_to_rvt(mr->pd->device);
+
+ rvt_qp_iter(rdi, (u64)mr, rvt_dereg_clean_qp_cb);
+}
+
+/**
+ * rvt_check_refs - check references
+ * @mr - the megion
+ * @t - the caller identification
+ *
+ * This routine checks MRs holding a reference during
+ * when being de-registered.
+ *
+ * If the count is non-zero, the code calls a clean routine then
+ * waits for the timeout for the count to zero.
+ */
+static int rvt_check_refs(struct rvt_mregion *mr, const char *t)
+{
+ unsigned long timeout;
+ struct rvt_dev_info *rdi = ib_to_rvt(mr->pd->device);
+
+ if (percpu_ref_is_zero(&mr->refcount))
+ return 0;
+ /* avoid dma mr */
+ if (mr->lkey)
+ rvt_dereg_clean_qps(mr);
+ timeout = wait_for_completion_timeout(&mr->comp, 5 * HZ);
+ if (!timeout) {
+ rvt_pr_err(rdi,
+ "%s timeout mr %p pd %p lkey %x refcount %ld\n",
+ t, mr, mr->pd, mr->lkey,
+ atomic_long_read(&mr->refcount.count));
+ rvt_get_mr(mr);
+ return -EBUSY;
+ }
+ return 0;
+}
+
+/**
+ * rvt_mr_has_lkey - is MR
+ * @mr - the mregion
+ * @lkey - the lkey
+ */
+bool rvt_mr_has_lkey(struct rvt_mregion *mr, u32 lkey)
+{
+ return mr && lkey == mr->lkey;
+}
+
+/**
+ * rvt_ss_has_lkey - is mr in sge tests
+ * @ss - the sge state
+ * @lkey
+ *
+ * This code tests for an MR in the indicated
+ * sge state.
+ */
+bool rvt_ss_has_lkey(struct rvt_sge_state *ss, u32 lkey)
+{
+ int i;
+ bool rval = false;
+
+ if (!ss->num_sge)
+ return rval;
+ /* first one */
+ rval = rvt_mr_has_lkey(ss->sge.mr, lkey);
+ /* any others */
+ for (i = 0; !rval && i < ss->num_sge - 1; i++)
+ rval = rvt_mr_has_lkey(ss->sg_list[i].mr, lkey);
+ return rval;
+}
+
+/**
* rvt_dereg_mr - unregister and free a memory region
* @ibmr: the memory region to free
*
@@ -453,22 +552,14 @@ bail_umem:
int rvt_dereg_mr(struct ib_mr *ibmr)
{
struct rvt_mr *mr = to_imr(ibmr);
- struct rvt_dev_info *rdi = ib_to_rvt(ibmr->pd->device);
- int ret = 0;
- unsigned long timeout;
+ int ret;
rvt_free_lkey(&mr->mr);
rvt_put_mr(&mr->mr); /* will set completion if last */
- timeout = wait_for_completion_timeout(&mr->mr.comp, 5 * HZ);
- if (!timeout) {
- rvt_pr_err(rdi,
- "rvt_dereg_mr timeout mr %p pd %p\n",
- mr, mr->mr.pd);
- rvt_get_mr(&mr->mr);
- ret = -EBUSY;
+ ret = rvt_check_refs(&mr->mr, __func__);
+ if (ret)
goto out;
- }
rvt_deinit_mregion(&mr->mr);
if (mr->umem)
ib_umem_release(mr->umem);
@@ -761,16 +852,12 @@ int rvt_dealloc_fmr(struct ib_fmr *ibfmr)
{
struct rvt_fmr *fmr = to_ifmr(ibfmr);
int ret = 0;
- unsigned long timeout;
rvt_free_lkey(&fmr->mr);
rvt_put_mr(&fmr->mr); /* will set completion if last */
- timeout = wait_for_completion_timeout(&fmr->mr.comp, 5 * HZ);
- if (!timeout) {
- rvt_get_mr(&fmr->mr);
- ret = -EBUSY;
+ ret = rvt_check_refs(&fmr->mr, __func__);
+ if (ret)
goto out;
- }
rvt_deinit_mregion(&fmr->mr);
kfree(fmr);
out:
@@ -778,23 +865,52 @@ out:
}
/**
+ * rvt_sge_adjacent - is isge compressible
+ * @last_sge: last outgoing SGE written
+ * @sge: SGE to check
+ *
+ * If adjacent will update last_sge to add length.
+ *
+ * Return: true if isge is adjacent to last sge
+ */
+static inline bool rvt_sge_adjacent(struct rvt_sge *last_sge,
+ struct ib_sge *sge)
+{
+ if (last_sge && sge->lkey == last_sge->mr->lkey &&
+ ((uint64_t)(last_sge->vaddr + last_sge->length) == sge->addr)) {
+ if (sge->lkey) {
+ if (unlikely((sge->addr - last_sge->mr->user_base +
+ sge->length > last_sge->mr->length)))
+ return false; /* overrun, caller will catch */
+ } else {
+ last_sge->length += sge->length;
+ }
+ last_sge->sge_length += sge->length;
+ trace_rvt_sge_adjacent(last_sge, sge);
+ return true;
+ }
+ return false;
+}
+
+/**
* rvt_lkey_ok - check IB SGE for validity and initialize
* @rkt: table containing lkey to check SGE against
* @pd: protection domain
* @isge: outgoing internal SGE
+ * @last_sge: last outgoing SGE written
* @sge: SGE to check
* @acc: access flags
*
* Check the IB SGE for validity and initialize our internal version
* of it.
*
- * Return: 1 if valid and successful, otherwise returns 0.
- *
- * increments the reference count upon success
+ * Increments the reference count when a new sge is stored.
*
+ * Return: 0 if compressed, 1 if added , otherwise returns -errno.
*/
int rvt_lkey_ok(struct rvt_lkey_table *rkt, struct rvt_pd *pd,
- struct rvt_sge *isge, struct ib_sge *sge, int acc)
+ struct rvt_sge *isge, struct rvt_sge *last_sge,
+ struct ib_sge *sge, int acc)
{
struct rvt_mregion *mr;
unsigned n, m;
@@ -804,12 +920,14 @@ int rvt_lkey_ok(struct rvt_lkey_table *rkt, struct rvt_pd *pd,
* We use LKEY == zero for kernel virtual addresses
* (see rvt_get_dma_mr() and dma_virt_ops).
*/
- rcu_read_lock();
if (sge->lkey == 0) {
struct rvt_dev_info *dev = ib_to_rvt(pd->ibpd.device);
if (pd->user)
- goto bail;
+ return -EINVAL;
+ if (rvt_sge_adjacent(last_sge, sge))
+ return 0;
+ rcu_read_lock();
mr = rcu_dereference(dev->dma_mr);
if (!mr)
goto bail;
@@ -824,6 +942,9 @@ int rvt_lkey_ok(struct rvt_lkey_table *rkt, struct rvt_pd *pd,
isge->n = 0;
goto ok;
}
+ if (rvt_sge_adjacent(last_sge, sge))
+ return 0;
+ rcu_read_lock();
mr = rcu_dereference(rkt->table[sge->lkey >> rkt->shift]);
if (!mr)
goto bail;
@@ -874,12 +995,13 @@ int rvt_lkey_ok(struct rvt_lkey_table *rkt, struct rvt_pd *pd,
isge->m = m;
isge->n = n;
ok:
+ trace_rvt_sge_new(isge, sge);
return 1;
bail_unref:
rvt_put_mr(mr);
bail:
rcu_read_unlock();
- return 0;
+ return -EINVAL;
}
EXPORT_SYMBOL(rvt_lkey_ok);
diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c
index 8876ee7..22df09a 100644
--- a/drivers/infiniband/sw/rdmavt/qp.c
+++ b/drivers/infiniband/sw/rdmavt/qp.c
@@ -52,6 +52,7 @@
#include <linux/slab.h>
#include <rdma/ib_verbs.h>
#include <rdma/ib_hdrs.h>
+#include <rdma/opa_addr.h>
#include "qp.h"
#include "vt.h"
#include "trace.h"
@@ -421,15 +422,6 @@ bail:
return ret;
}
-static void free_qpn(struct rvt_qpn_table *qpt, u32 qpn)
-{
- struct rvt_qpn_map *map;
-
- map = qpt->map + qpn / RVT_BITS_PER_PAGE;
- if (map->page)
- clear_bit(qpn & RVT_BITS_PER_PAGE_MASK, map->page);
-}
-
/**
* rvt_clear_mr_refs - Drop help mr refs
* @qp: rvt qp data structure
@@ -448,13 +440,9 @@ static void rvt_clear_mr_refs(struct rvt_qp *qp, int clr_sends)
if (clr_sends) {
while (qp->s_last != qp->s_head) {
struct rvt_swqe *wqe = rvt_get_swqe_ptr(qp, qp->s_last);
- unsigned i;
- for (i = 0; i < wqe->wr.num_sge; i++) {
- struct rvt_sge *sge = &wqe->sg_list[i];
+ rvt_put_swqe(wqe);
- rvt_put_mr(sge->mr);
- }
if (qp->ibqp.qp_type == IB_QPT_UD ||
qp->ibqp.qp_type == IB_QPT_SMI ||
qp->ibqp.qp_type == IB_QPT_GSI)
@@ -470,10 +458,7 @@ static void rvt_clear_mr_refs(struct rvt_qp *qp, int clr_sends)
}
}
- if (qp->ibqp.qp_type != IB_QPT_RC)
- return;
-
- for (n = 0; n < rvt_max_atomic(rdi); n++) {
+ for (n = 0; qp->s_ack_queue && n < rvt_max_atomic(rdi); n++) {
struct rvt_ack_entry *e = &qp->s_ack_queue[n];
if (e->rdma_sge.mr) {
@@ -484,6 +469,113 @@ static void rvt_clear_mr_refs(struct rvt_qp *qp, int clr_sends)
}
/**
+ * rvt_swqe_has_lkey - return true if lkey is used by swqe
+ * @wqe - the send wqe
+ * @lkey - the lkey
+ *
+ * Test the swqe for using lkey
+ */
+static bool rvt_swqe_has_lkey(struct rvt_swqe *wqe, u32 lkey)
+{
+ int i;
+
+ for (i = 0; i < wqe->wr.num_sge; i++) {
+ struct rvt_sge *sge = &wqe->sg_list[i];
+
+ if (rvt_mr_has_lkey(sge->mr, lkey))
+ return true;
+ }
+ return false;
+}
+
+/**
+ * rvt_qp_sends_has_lkey - return true is qp sends use lkey
+ * @qp - the rvt_qp
+ * @lkey - the lkey
+ */
+static bool rvt_qp_sends_has_lkey(struct rvt_qp *qp, u32 lkey)
+{
+ u32 s_last = qp->s_last;
+
+ while (s_last != qp->s_head) {
+ struct rvt_swqe *wqe = rvt_get_swqe_ptr(qp, s_last);
+
+ if (rvt_swqe_has_lkey(wqe, lkey))
+ return true;
+
+ if (++s_last >= qp->s_size)
+ s_last = 0;
+ }
+ if (qp->s_rdma_mr)
+ if (rvt_mr_has_lkey(qp->s_rdma_mr, lkey))
+ return true;
+ return false;
+}
+
+/**
+ * rvt_qp_acks_has_lkey - return true if acks have lkey
+ * @qp - the qp
+ * @lkey - the lkey
+ */
+static bool rvt_qp_acks_has_lkey(struct rvt_qp *qp, u32 lkey)
+{
+ int i;
+ struct rvt_dev_info *rdi = ib_to_rvt(qp->ibqp.device);
+
+ for (i = 0; qp->s_ack_queue && i < rvt_max_atomic(rdi); i++) {
+ struct rvt_ack_entry *e = &qp->s_ack_queue[i];
+
+ if (rvt_mr_has_lkey(e->rdma_sge.mr, lkey))
+ return true;
+ }
+ return false;
+}
+
+/*
+ * rvt_qp_mr_clean - clean up remote ops for lkey
+ * @qp - the qp
+ * @lkey - the lkey that is being de-registered
+ *
+ * This routine checks if the lkey is being used by
+ * the qp.
+ *
+ * If so, the qp is put into an error state to elminate
+ * any references from the qp.
+ */
+void rvt_qp_mr_clean(struct rvt_qp *qp, u32 lkey)
+{
+ bool lastwqe = false;
+
+ if (qp->ibqp.qp_type == IB_QPT_SMI ||
+ qp->ibqp.qp_type == IB_QPT_GSI)
+ /* avoid special QPs */
+ return;
+ spin_lock_irq(&qp->r_lock);
+ spin_lock(&qp->s_hlock);
+ spin_lock(&qp->s_lock);
+
+ if (qp->state == IB_QPS_ERR || qp->state == IB_QPS_RESET)
+ goto check_lwqe;
+
+ if (rvt_ss_has_lkey(&qp->r_sge, lkey) ||
+ rvt_qp_sends_has_lkey(qp, lkey) ||
+ rvt_qp_acks_has_lkey(qp, lkey))
+ lastwqe = rvt_error_qp(qp, IB_WC_LOC_PROT_ERR);
+check_lwqe:
+ spin_unlock(&qp->s_lock);
+ spin_unlock(&qp->s_hlock);
+ spin_unlock_irq(&qp->r_lock);
+ if (lastwqe) {
+ struct ib_event ev;
+
+ ev.device = qp->ibqp.device;
+ ev.element.qp = &qp->ibqp;
+ ev.event = IB_EVENT_QP_LAST_WQE_REACHED;
+ qp->ibqp.event_handler(&ev, qp->ibqp.qp_context);
+ }
+}
+
+/**
* rvt_remove_qp - remove qp form table
* @rdi: rvt dev struct
* @qp: qp to remove
@@ -645,6 +737,19 @@ static void rvt_reset_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp,
lockdep_assert_held(&qp->s_lock);
}
+/** rvt_free_qpn - Free a qpn from the bit map
+ * @qpt: QP table
+ * @qpn: queue pair number to free
+ */
+static void rvt_free_qpn(struct rvt_qpn_table *qpt, u32 qpn)
+{
+ struct rvt_qpn_map *map;
+
+ map = qpt->map + (qpn & RVT_QPN_MASK) / RVT_BITS_PER_PAGE;
+ if (map->page)
+ clear_bit(qpn & RVT_BITS_PER_PAGE_MASK, map->page);
+}
+
/**
* rvt_create_qp - create a queue pair for a device
* @ibpd: the protection domain who's device we create the queue pair for
@@ -914,7 +1019,7 @@ bail_ip:
kref_put(&qp->ip->ref, rvt_release_mmap_info);
bail_qpn:
- free_qpn(&rdi->qp_dev->qpn_table, qp->ibqp.qp_num);
+ rvt_free_qpn(&rdi->qp_dev->qpn_table, qp->ibqp.qp_num);
bail_rq_wq:
if (!qp->ip)
@@ -1062,6 +1167,7 @@ int rvt_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
int mig = 0;
int pmtu = 0; /* for gcc warning only */
enum rdma_link_layer link;
+ int opa_ah;
link = rdma_port_get_link_layer(ibqp->device, qp->port_num);
@@ -1072,6 +1178,7 @@ int rvt_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
cur_state = attr_mask & IB_QP_CUR_STATE ?
attr->cur_qp_state : qp->state;
new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state;
+ opa_ah = rdma_cap_opa_ah(ibqp->device, qp->port_num);
if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type,
attr_mask, link))
@@ -1082,17 +1189,31 @@ int rvt_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
goto inval;
if (attr_mask & IB_QP_AV) {
- if (rdma_ah_get_dlid(&attr->ah_attr) >=
- be16_to_cpu(IB_MULTICAST_LID_BASE))
- goto inval;
+ if (opa_ah) {
+ if (rdma_ah_get_dlid(&attr->ah_attr) >=
+ opa_get_mcast_base(OPA_MCAST_NR))
+ goto inval;
+ } else {
+ if (rdma_ah_get_dlid(&attr->ah_attr) >=
+ be16_to_cpu(IB_MULTICAST_LID_BASE))
+ goto inval;
+ }
+
if (rvt_check_ah(qp->ibqp.device, &attr->ah_attr))
goto inval;
}
if (attr_mask & IB_QP_ALT_PATH) {
- if (rdma_ah_get_dlid(&attr->alt_ah_attr) >=
- be16_to_cpu(IB_MULTICAST_LID_BASE))
- goto inval;
+ if (opa_ah) {
+ if (rdma_ah_get_dlid(&attr->alt_ah_attr) >=
+ opa_get_mcast_base(OPA_MCAST_NR))
+ goto inval;
+ } else {
+ if (rdma_ah_get_dlid(&attr->alt_ah_attr) >=
+ be16_to_cpu(IB_MULTICAST_LID_BASE))
+ goto inval;
+ }
+
if (rvt_check_ah(qp->ibqp.device, &attr->alt_ah_attr))
goto inval;
if (attr->alt_pkey_index >= rvt_get_npkeys(rdi))
@@ -1239,7 +1360,6 @@ int rvt_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
if (attr_mask & IB_QP_PATH_MTU) {
qp->pmtu = rdi->driver_f.mtu_from_qp(rdi, qp, pmtu);
- qp->path_mtu = rdi->driver_f.mtu_to_path_mtu(qp->pmtu);
qp->log_pmtu = ilog2(qp->pmtu);
}
@@ -1301,19 +1421,6 @@ inval:
return -EINVAL;
}
-/** rvt_free_qpn - Free a qpn from the bit map
- * @qpt: QP table
- * @qpn: queue pair number to free
- */
-static void rvt_free_qpn(struct rvt_qpn_table *qpt, u32 qpn)
-{
- struct rvt_qpn_map *map;
-
- map = qpt->map + qpn / RVT_BITS_PER_PAGE;
- if (map->page)
- clear_bit(qpn & RVT_BITS_PER_PAGE_MASK, map->page);
-}
-
/**
* rvt_destroy_qp - destroy a queue pair
* @ibqp: the queue pair to destroy
@@ -1375,7 +1482,7 @@ int rvt_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
attr->qp_state = qp->state;
attr->cur_qp_state = attr->qp_state;
- attr->path_mtu = qp->path_mtu;
+ attr->path_mtu = rdi->driver_f.mtu_to_path_mtu(qp->pmtu);
attr->path_mig_state = qp->s_mig_state;
attr->qkey = qp->qkey;
attr->rq_psn = qp->r_psn & rdi->dparms.psn_mask;
@@ -1695,22 +1802,23 @@ static int rvt_post_one_wr(struct rvt_qp *qp,
wqe->length = 0;
j = 0;
if (wr->num_sge) {
+ struct rvt_sge *last_sge = NULL;
+
acc = wr->opcode >= IB_WR_RDMA_READ ?
IB_ACCESS_LOCAL_WRITE : 0;
for (i = 0; i < wr->num_sge; i++) {
u32 length = wr->sg_list[i].length;
- int ok;
if (length == 0)
continue;
- ok = rvt_lkey_ok(rkt, pd, &wqe->sg_list[j],
- &wr->sg_list[i], acc);
- if (!ok) {
- ret = -EINVAL;
+ ret = rvt_lkey_ok(rkt, pd, &wqe->sg_list[j], last_sge,
+ &wr->sg_list[i], acc);
+ if (unlikely(ret < 0))
goto bail_inval_free;
- }
wqe->length += length;
- j++;
+ if (ret)
+ last_sge = &wqe->sg_list[j];
+ j += ret;
}
wqe->wr.num_sge = j;
}
@@ -1757,7 +1865,7 @@ static int rvt_post_one_wr(struct rvt_qp *qp,
wqe->wr.send_flags &= ~RVT_SEND_RESERVE_USED;
qp->s_avail--;
}
- trace_rvt_post_one_wr(qp, wqe);
+ trace_rvt_post_one_wr(qp, wqe, wr->num_sge);
smp_wmb(); /* see request builders */
qp->s_head = next;
@@ -2065,3 +2173,147 @@ enum hrtimer_restart rvt_rc_rnr_retry(struct hrtimer *t)
return HRTIMER_NORESTART;
}
EXPORT_SYMBOL(rvt_rc_rnr_retry);
+
+/**
+ * rvt_qp_iter_init - initial for QP iteration
+ * @rdi - rvt devinfo
+ * @v - u64 value
+ *
+ * This returns an iterator suitable for iterating QPs
+ * in the system.
+ *
+ * The @cb is a user defined callback and @v is a 64
+ * bit value passed to and relevant for processing in the
+ * @cb. An example use case would be to alter QP processing
+ * based on criteria not part of the rvt_qp.
+ *
+ * Use cases that require memory allocation to succeed
+ * must preallocate appropriately.
+ *
+ * Return: a pointer to an rvt_qp_iter or NULL
+ */
+struct rvt_qp_iter *rvt_qp_iter_init(struct rvt_dev_info *rdi,
+ u64 v,
+ void (*cb)(struct rvt_qp *qp, u64 v))
+{
+ struct rvt_qp_iter *i;
+
+ i = kzalloc(sizeof(*i), GFP_KERNEL);
+ if (!i)
+ return NULL;
+
+ i->rdi = rdi;
+ /* number of special QPs (SMI/GSI) for device */
+ i->specials = rdi->ibdev.phys_port_cnt * 2;
+ i->v = v;
+ i->cb = cb;
+
+ return i;
+}
+EXPORT_SYMBOL(rvt_qp_iter_init);
+
+/**
+ * rvt_qp_iter_next - return the next QP in iter
+ * @iter - the iterator
+ *
+ * Fine grained QP iterator suitable for use
+ * with debugfs seq_file mechanisms.
+ *
+ * Updates iter->qp with the current QP when the return
+ * value is 0.
+ *
+ * Return: 0 - iter->qp is valid 1 - no more QPs
+ */
+int rvt_qp_iter_next(struct rvt_qp_iter *iter)
+ __must_hold(RCU)
+{
+ int n = iter->n;
+ int ret = 1;
+ struct rvt_qp *pqp = iter->qp;
+ struct rvt_qp *qp;
+ struct rvt_dev_info *rdi = iter->rdi;
+
+ /*
+ * The approach is to consider the special qps
+ * as additional table entries before the
+ * real hash table. Since the qp code sets
+ * the qp->next hash link to NULL, this works just fine.
+ *
+ * iter->specials is 2 * # ports
+ *
+ * n = 0..iter->specials is the special qp indices
+ *
+ * n = iter->specials..rdi->qp_dev->qp_table_size+iter->specials are
+ * the potential hash bucket entries
+ *
+ */
+ for (; n < rdi->qp_dev->qp_table_size + iter->specials; n++) {
+ if (pqp) {
+ qp = rcu_dereference(pqp->next);
+ } else {
+ if (n < iter->specials) {
+ struct rvt_ibport *rvp;
+ int pidx;
+
+ pidx = n % rdi->ibdev.phys_port_cnt;
+ rvp = rdi->ports[pidx];
+ qp = rcu_dereference(rvp->qp[n & 1]);
+ } else {
+ qp = rcu_dereference(
+ rdi->qp_dev->qp_table[
+ (n - iter->specials)]);
+ }
+ }
+ pqp = qp;
+ if (qp) {
+ iter->qp = qp;
+ iter->n = n;
+ return 0;
+ }
+ }
+ return ret;
+}
+EXPORT_SYMBOL(rvt_qp_iter_next);
+
+/**
+ * rvt_qp_iter - iterate all QPs
+ * @rdi - rvt devinfo
+ * @v - a 64 bit value
+ * @cb - a callback
+ *
+ * This provides a way for iterating all QPs.
+ *
+ * The @cb is a user defined callback and @v is a 64
+ * bit value passed to and relevant for processing in the
+ * cb. An example use case would be to alter QP processing
+ * based on criteria not part of the rvt_qp.
+ *
+ * The code has an internal iterator to simplify
+ * non seq_file use cases.
+ */
+void rvt_qp_iter(struct rvt_dev_info *rdi,
+ u64 v,
+ void (*cb)(struct rvt_qp *qp, u64 v))
+{
+ int ret;
+ struct rvt_qp_iter i = {
+ .rdi = rdi,
+ .specials = rdi->ibdev.phys_port_cnt * 2,
+ .v = v,
+ .cb = cb
+ };
+
+ rcu_read_lock();
+ do {
+ ret = rvt_qp_iter_next(&i);
+ if (!ret) {
+ rvt_get_qp(i.qp);
+ rcu_read_unlock();
+ i.cb(i.qp, i.v);
+ rcu_read_lock();
+ rvt_put_qp(i.qp);
+ }
+ } while (!ret);
+ rcu_read_unlock();
+}
+EXPORT_SYMBOL(rvt_qp_iter);
diff --git a/drivers/infiniband/sw/rdmavt/trace_mr.h b/drivers/infiniband/sw/rdmavt/trace_mr.h
index 3318a6c..976e482 100644
--- a/drivers/infiniband/sw/rdmavt/trace_mr.h
+++ b/drivers/infiniband/sw/rdmavt/trace_mr.h
@@ -103,6 +103,68 @@ DEFINE_EVENT(
TP_PROTO(struct rvt_mregion *mr, u16 m, u16 n, void *v, size_t len),
TP_ARGS(mr, m, n, v, len));
+DECLARE_EVENT_CLASS(
+ rvt_sge_template,
+ TP_PROTO(struct rvt_sge *sge, struct ib_sge *isge),
+ TP_ARGS(sge, isge),
+ TP_STRUCT__entry(
+ RDI_DEV_ENTRY(ib_to_rvt(sge->mr->pd->device))
+ __field(struct rvt_mregion *, mr)
+ __field(struct rvt_sge *, sge)
+ __field(struct ib_sge *, isge)
+ __field(void *, vaddr)
+ __field(u64, ivaddr)
+ __field(u32, lkey)
+ __field(u32, sge_length)
+ __field(u32, length)
+ __field(u32, ilength)
+ __field(int, user)
+ __field(u16, m)
+ __field(u16, n)
+ ),
+ TP_fast_assign(
+ RDI_DEV_ASSIGN(ib_to_rvt(sge->mr->pd->device));
+ __entry->mr = sge->mr;
+ __entry->sge = sge;
+ __entry->isge = isge;
+ __entry->vaddr = sge->vaddr;
+ __entry->ivaddr = isge->addr;
+ __entry->lkey = sge->mr->lkey;
+ __entry->sge_length = sge->sge_length;
+ __entry->length = sge->length;
+ __entry->ilength = isge->length;
+ __entry->m = sge->m;
+ __entry->n = sge->m;
+ __entry->user = ibpd_to_rvtpd(sge->mr->pd)->user;
+ ),
+ TP_printk(
+ "[%s] mr %p sge %p isge %p vaddr %p ivaddr %llx lkey %x sge_length %u length %u ilength %u m %u n %u user %u",
+ __get_str(dev),
+ __entry->mr,
+ __entry->sge,
+ __entry->isge,
+ __entry->vaddr,
+ __entry->ivaddr,
+ __entry->lkey,
+ __entry->sge_length,
+ __entry->length,
+ __entry->ilength,
+ __entry->m,
+ __entry->n,
+ __entry->user
+ )
+);
+
+DEFINE_EVENT(
+ rvt_sge_template, rvt_sge_adjacent,
+ TP_PROTO(struct rvt_sge *sge, struct ib_sge *isge),
+ TP_ARGS(sge, isge));
+
+DEFINE_EVENT(
+ rvt_sge_template, rvt_sge_new,
+ TP_PROTO(struct rvt_sge *sge, struct ib_sge *isge),
+ TP_ARGS(sge, isge));
+
#endif /* __RVT_TRACE_MR_H */
#undef TRACE_INCLUDE_PATH
diff --git a/drivers/infiniband/sw/rdmavt/trace_tx.h b/drivers/infiniband/sw/rdmavt/trace_tx.h
index a613a22..0ef25fc 100644
--- a/drivers/infiniband/sw/rdmavt/trace_tx.h
+++ b/drivers/infiniband/sw/rdmavt/trace_tx.h
@@ -84,12 +84,12 @@ __print_symbolic(opcode, \
wr_opcode_name(RESERVED10))
#define POS_PRN \
-"[%s] wqe %p wr_id %llx send_flags %x qpn %x qpt %u psn %x lpsn %x ssn %x length %u opcode 0x%.2x,%s size %u avail %u head %u last %u pid %u num_sge %u"
+"[%s] wqe %p wr_id %llx send_flags %x qpn %x qpt %u psn %x lpsn %x ssn %x length %u opcode 0x%.2x,%s size %u avail %u head %u last %u pid %u num_sge %u wr_num_sge %u"
TRACE_EVENT(
rvt_post_one_wr,
- TP_PROTO(struct rvt_qp *qp, struct rvt_swqe *wqe),
- TP_ARGS(qp, wqe),
+ TP_PROTO(struct rvt_qp *qp, struct rvt_swqe *wqe, int wr_num_sge),
+ TP_ARGS(qp, wqe, wr_num_sge),
TP_STRUCT__entry(
RDI_DEV_ENTRY(ib_to_rvt(qp->ibqp.device))
__field(u64, wr_id)
@@ -108,6 +108,7 @@ TRACE_EVENT(
__field(int, send_flags)
__field(pid_t, pid)
__field(int, num_sge)
+ __field(int, wr_num_sge)
),
TP_fast_assign(
RDI_DEV_ASSIGN(ib_to_rvt(qp->ibqp.device))
@@ -127,6 +128,7 @@ TRACE_EVENT(
__entry->ssn = wqe->ssn;
__entry->send_flags = wqe->wr.send_flags;
__entry->num_sge = wqe->wr.num_sge;
+ __entry->wr_num_sge = wr_num_sge;
),
TP_printk(
POS_PRN,
@@ -146,7 +148,8 @@ TRACE_EVENT(
__entry->head,
__entry->last,
__entry->pid,
- __entry->num_sge
+ __entry->num_sge,
+ __entry->wr_num_sge
)
);
diff --git a/drivers/infiniband/sw/rdmavt/vt.c b/drivers/infiniband/sw/rdmavt/vt.c
index 0d7c6bb..64bdd44 100644
--- a/drivers/infiniband/sw/rdmavt/vt.c
+++ b/drivers/infiniband/sw/rdmavt/vt.c
@@ -202,8 +202,13 @@ static int rvt_modify_port(struct ib_device *ibdev, u8 port_num,
return -EINVAL;
rvp = rdi->ports[port_index];
- rvp->port_cap_flags |= props->set_port_cap_mask;
- rvp->port_cap_flags &= ~props->clr_port_cap_mask;
+ if (port_modify_mask & IB_PORT_OPA_MASK_CHG) {
+ rvp->port_cap3_flags |= props->set_port_cap_mask;
+ rvp->port_cap3_flags &= ~props->clr_port_cap_mask;
+ } else {
+ rvp->port_cap_flags |= props->set_port_cap_mask;
+ rvp->port_cap_flags &= ~props->clr_port_cap_mask;
+ }
if (props->set_port_cap_mask || props->clr_port_cap_mask)
rdi->driver_f.cap_mask_chg(rdi, port_num);
diff --git a/drivers/infiniband/sw/rxe/rxe.c b/drivers/infiniband/sw/rxe/rxe.c
index c21c913..8c3d30b 100644
--- a/drivers/infiniband/sw/rxe/rxe.c
+++ b/drivers/infiniband/sw/rxe/rxe.c
@@ -38,7 +38,6 @@
MODULE_AUTHOR("Bob Pearson, Frank Zago, John Groves, Kamal Heib");
MODULE_DESCRIPTION("Soft RDMA transport");
MODULE_LICENSE("Dual BSD/GPL");
-MODULE_VERSION("0.2");
/* free resources for all ports on a device */
static void rxe_cleanup_ports(struct rxe_dev *rxe)
diff --git a/drivers/infiniband/sw/rxe/rxe.h b/drivers/infiniband/sw/rxe/rxe.h
index 1ac5b85..6447d73 100644
--- a/drivers/infiniband/sw/rxe/rxe.h
+++ b/drivers/infiniband/sw/rxe/rxe.h
@@ -97,7 +97,7 @@ int rxe_rcv(struct sk_buff *skb);
void rxe_dev_put(struct rxe_dev *rxe);
struct rxe_dev *net_to_rxe(struct net_device *ndev);
-struct rxe_dev *get_rxe_by_name(const char* name);
+struct rxe_dev *get_rxe_by_name(const char *name);
void rxe_port_up(struct rxe_dev *rxe);
void rxe_port_down(struct rxe_dev *rxe);
diff --git a/drivers/infiniband/sw/rxe/rxe_av.c b/drivers/infiniband/sw/rxe/rxe_av.c
index 5bddf46..1cc9e2e 100644
--- a/drivers/infiniband/sw/rxe/rxe_av.c
+++ b/drivers/infiniband/sw/rxe/rxe_av.c
@@ -38,18 +38,13 @@ int rxe_av_chk_attr(struct rxe_dev *rxe, struct rdma_ah_attr *attr)
{
struct rxe_port *port;
- if (rdma_ah_get_port_num(attr) != 1) {
- pr_info("invalid port_num = %d\n", rdma_ah_get_port_num(attr));
- return -EINVAL;
- }
-
port = &rxe->port;
if (rdma_ah_get_ah_flags(attr) & IB_AH_GRH) {
u8 sgid_index = rdma_ah_read_grh(attr)->sgid_index;
if (sgid_index > port->attr.gid_tbl_len) {
- pr_info("invalid sgid index = %d\n", sgid_index);
+ pr_warn("invalid sgid index = %d\n", sgid_index);
return -EINVAL;
}
}
diff --git a/drivers/infiniband/sw/rxe/rxe_cq.c b/drivers/infiniband/sw/rxe/rxe_cq.c
index 49fe42c..c4aabf7 100644
--- a/drivers/infiniband/sw/rxe/rxe_cq.c
+++ b/drivers/infiniband/sw/rxe/rxe_cq.c
@@ -69,6 +69,14 @@ err1:
static void rxe_send_complete(unsigned long data)
{
struct rxe_cq *cq = (struct rxe_cq *)data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&cq->cq_lock, flags);
+ if (cq->is_dying) {
+ spin_unlock_irqrestore(&cq->cq_lock, flags);
+ return;
+ }
+ spin_unlock_irqrestore(&cq->cq_lock, flags);
cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context);
}
@@ -97,6 +105,8 @@ int rxe_cq_from_init(struct rxe_dev *rxe, struct rxe_cq *cq, int cqe,
if (udata)
cq->is_user = 1;
+ cq->is_dying = false;
+
tasklet_init(&cq->comp_task, rxe_send_complete, (unsigned long)cq);
spin_lock_init(&cq->cq_lock);
@@ -156,6 +166,15 @@ int rxe_cq_post(struct rxe_cq *cq, struct rxe_cqe *cqe, int solicited)
return 0;
}
+void rxe_cq_disable(struct rxe_cq *cq)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&cq->cq_lock, flags);
+ cq->is_dying = true;
+ spin_unlock_irqrestore(&cq->cq_lock, flags);
+}
+
void rxe_cq_cleanup(struct rxe_pool_entry *arg)
{
struct rxe_cq *cq = container_of(arg, typeof(*cq), pelem);
diff --git a/drivers/infiniband/sw/rxe/rxe_hw_counters.c b/drivers/infiniband/sw/rxe/rxe_hw_counters.c
index 7ef90aa..6aeb7a1 100644
--- a/drivers/infiniband/sw/rxe/rxe_hw_counters.c
+++ b/drivers/infiniband/sw/rxe/rxe_hw_counters.c
@@ -33,7 +33,7 @@
#include "rxe.h"
#include "rxe_hw_counters.h"
-const char * const rxe_counter_name[] = {
+static const char * const rxe_counter_name[] = {
[RXE_CNT_SENT_PKTS] = "sent_pkts",
[RXE_CNT_RCVD_PKTS] = "rcvd_pkts",
[RXE_CNT_DUP_REQ] = "duplicate_request",
diff --git a/drivers/infiniband/sw/rxe/rxe_loc.h b/drivers/infiniband/sw/rxe/rxe_loc.h
index d6299ed..77b3ed0 100644
--- a/drivers/infiniband/sw/rxe/rxe_loc.h
+++ b/drivers/infiniband/sw/rxe/rxe_loc.h
@@ -64,6 +64,8 @@ int rxe_cq_resize_queue(struct rxe_cq *cq, int new_cqe, struct ib_udata *udata);
int rxe_cq_post(struct rxe_cq *cq, struct rxe_cqe *cqe, int solicited);
+void rxe_cq_disable(struct rxe_cq *cq);
+
void rxe_cq_cleanup(struct rxe_pool_entry *arg);
/* rxe_mcast.c */
@@ -219,8 +221,6 @@ static inline void rxe_advance_resp_resource(struct rxe_qp *qp)
void retransmit_timer(unsigned long data);
void rnr_nak_timer(unsigned long data);
-void dump_qp(struct rxe_qp *qp);
-
/* rxe_srq.c */
#define IB_SRQ_INIT_MASK (~IB_SRQ_LIMIT)
@@ -250,7 +250,7 @@ void rxe_resp_queue_pkt(struct rxe_dev *rxe,
void rxe_comp_queue_pkt(struct rxe_dev *rxe,
struct rxe_qp *qp, struct sk_buff *skb);
-static inline unsigned wr_opcode_mask(int opcode, struct rxe_qp *qp)
+static inline unsigned int wr_opcode_mask(int opcode, struct rxe_qp *qp)
{
return rxe_wr_opcode_info[opcode].mask[qp->ibqp.qp_type];
}
diff --git a/drivers/infiniband/sw/rxe/rxe_mmap.c b/drivers/infiniband/sw/rxe/rxe_mmap.c
index bd812e0..d22431e 100644
--- a/drivers/infiniband/sw/rxe/rxe_mmap.c
+++ b/drivers/infiniband/sw/rxe/rxe_mmap.c
@@ -76,7 +76,7 @@ static void rxe_vma_close(struct vm_area_struct *vma)
kref_put(&ip->ref, rxe_mmap_release);
}
-static struct vm_operations_struct rxe_vm_ops = {
+static const struct vm_operations_struct rxe_vm_ops = {
.open = rxe_vma_open,
.close = rxe_vma_close,
};
diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c
index e37cc89..5c2684b 100644
--- a/drivers/infiniband/sw/rxe/rxe_mr.c
+++ b/drivers/infiniband/sw/rxe/rxe_mr.c
@@ -367,11 +367,11 @@ int rxe_mem_copy(struct rxe_mem *mem, u64 iova, void *addr, int length,
dest = (dir == to_mem_obj) ?
((void *)(uintptr_t)iova) : addr;
+ memcpy(dest, src, length);
+
if (crcp)
*crcp = rxe_crc32(to_rdev(mem->pd->ibpd.device),
- *crcp, src, length);
-
- memcpy(dest, src, length);
+ *crcp, dest, length);
return 0;
}
@@ -401,11 +401,11 @@ int rxe_mem_copy(struct rxe_mem *mem, u64 iova, void *addr, int length,
if (bytes > length)
bytes = length;
+ memcpy(dest, src, bytes);
+
if (crcp)
crc = rxe_crc32(to_rdev(mem->pd->ibpd.device),
- crc, src, bytes);
-
- memcpy(dest, src, bytes);
+ crc, dest, bytes);
length -= bytes;
addr += bytes;
diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c
index 08f3f90..59dee10 100644
--- a/drivers/infiniband/sw/rxe/rxe_net.c
+++ b/drivers/infiniband/sw/rxe/rxe_net.c
@@ -191,7 +191,7 @@ static struct dst_entry *rxe_find_route(struct rxe_dev *rxe,
if (qp_type(qp) == IB_QPT_RC)
dst = sk_dst_get(qp->sk->sk);
- if (!dst || !(dst->obsolete && dst->ops->check(dst, 0))) {
+ if (!dst || !dst_check(dst, qp->dst_cookie)) {
if (dst)
dst_release(dst);
@@ -209,6 +209,11 @@ static struct dst_entry *rxe_find_route(struct rxe_dev *rxe,
saddr6 = &av->sgid_addr._sockaddr_in6.sin6_addr;
daddr6 = &av->dgid_addr._sockaddr_in6.sin6_addr;
dst = rxe_find_route6(rxe->ndev, saddr6, daddr6);
+#if IS_ENABLED(CONFIG_IPV6)
+ if (dst)
+ qp->dst_cookie =
+ rt6_get_cookie((struct rt6_info *)dst);
+#endif
}
}
@@ -337,7 +342,7 @@ static void prepare_ipv6_hdr(struct dst_entry *dst, struct sk_buff *skb,
memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED
| IPSKB_REROUTED);
- skb_dst_set(skb, dst);
+ skb_dst_set(skb, dst_clone(dst));
__skb_push(skb, sizeof(*ip6h));
skb_reset_network_header(skb);
@@ -388,7 +393,7 @@ static int prepare6(struct rxe_dev *rxe, struct rxe_pkt_info *pkt,
struct sk_buff *skb, struct rxe_av *av)
{
struct rxe_qp *qp = pkt->qp;
- struct dst_entry *dst = NULL;
+ struct dst_entry *dst;
struct in6_addr *saddr = &av->sgid_addr._sockaddr_in6.sin6_addr;
struct in6_addr *daddr = &av->dgid_addr._sockaddr_in6.sin6_addr;
@@ -460,12 +465,17 @@ int rxe_send(struct rxe_dev *rxe, struct rxe_pkt_info *pkt, struct sk_buff *skb)
nskb->destructor = rxe_skb_tx_dtor;
nskb->sk = pkt->qp->sk->sk;
+ rxe_add_ref(pkt->qp);
+ atomic_inc(&pkt->qp->skb_out);
+
if (av->network_type == RDMA_NETWORK_IPV4) {
err = ip_local_out(dev_net(skb_dst(skb)->dev), nskb->sk, nskb);
} else if (av->network_type == RDMA_NETWORK_IPV6) {
err = ip6_local_out(dev_net(skb_dst(skb)->dev), nskb->sk, nskb);
} else {
pr_err("Unknown layer 3 protocol: %d\n", av->network_type);
+ atomic_dec(&pkt->qp->skb_out);
+ rxe_drop_ref(pkt->qp);
kfree_skb(nskb);
return -EINVAL;
}
@@ -475,10 +485,7 @@ int rxe_send(struct rxe_dev *rxe, struct rxe_pkt_info *pkt, struct sk_buff *skb)
return -EAGAIN;
}
- rxe_add_ref(pkt->qp);
- atomic_inc(&pkt->qp->skb_out);
kfree_skb(skb);
-
return 0;
}
@@ -644,8 +651,13 @@ static int rxe_notify(struct notifier_block *not_blk,
pr_info("%s changed mtu to %d\n", ndev->name, ndev->mtu);
rxe_set_mtu(rxe, ndev->mtu);
break;
- case NETDEV_REBOOT:
case NETDEV_CHANGE:
+ if (netif_running(ndev) && netif_carrier_ok(ndev))
+ rxe_port_up(rxe);
+ else
+ rxe_port_down(rxe);
+ break;
+ case NETDEV_REBOOT:
case NETDEV_GOING_DOWN:
case NETDEV_CHANGEADDR:
case NETDEV_CHANGENAME:
diff --git a/drivers/infiniband/sw/rxe/rxe_pool.c b/drivers/infiniband/sw/rxe/rxe_pool.c
index 75d11ee..c1b5f38 100644
--- a/drivers/infiniband/sw/rxe/rxe_pool.c
+++ b/drivers/infiniband/sw/rxe/rxe_pool.c
@@ -188,7 +188,7 @@ int rxe_pool_init(
struct rxe_dev *rxe,
struct rxe_pool *pool,
enum rxe_elem_type type,
- unsigned max_elem)
+ unsigned int max_elem)
{
int err = 0;
size_t size = rxe_type_info[type].size;
diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c
index 80ccc7c..00bda93 100644
--- a/drivers/infiniband/sw/rxe/rxe_qp.c
+++ b/drivers/infiniband/sw/rxe/rxe_qp.c
@@ -851,13 +851,8 @@ void rxe_qp_cleanup(struct rxe_pool_entry *arg)
qp->resp.mr = NULL;
}
- if (qp_type(qp) == IB_QPT_RC) {
- struct dst_entry *dst = NULL;
-
- dst = sk_dst_get(qp->sk->sk);
- if (dst)
- dst_release(dst);
- }
+ if (qp_type(qp) == IB_QPT_RC)
+ sk_dst_reset(qp->sk->sk);
free_rd_atomic_resources(qp);
diff --git a/drivers/infiniband/sw/rxe/rxe_req.c b/drivers/infiniband/sw/rxe/rxe_req.c
index 7ee465d..d84222f 100644
--- a/drivers/infiniband/sw/rxe/rxe_req.c
+++ b/drivers/infiniband/sw/rxe/rxe_req.c
@@ -43,7 +43,7 @@ static int next_opcode(struct rxe_qp *qp, struct rxe_send_wqe *wqe,
static inline void retry_first_write_send(struct rxe_qp *qp,
struct rxe_send_wqe *wqe,
- unsigned mask, int npsn)
+ unsigned int mask, int npsn)
{
int i;
@@ -594,8 +594,10 @@ int rxe_requester(void *arg)
rxe_add_ref(qp);
next_wqe:
- if (unlikely(!qp->valid))
+ if (unlikely(!qp->valid)) {
+ rxe_drain_req_pkts(qp, true);
goto exit;
+ }
if (unlikely(qp->req.state == QP_STATE_ERROR)) {
rxe_drain_req_pkts(qp, true);
diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c
index a958ee9..4240866 100644
--- a/drivers/infiniband/sw/rxe/rxe_resp.c
+++ b/drivers/infiniband/sw/rxe/rxe_resp.c
@@ -1055,7 +1055,7 @@ static struct resp_res *find_resource(struct rxe_qp *qp, u32 psn)
{
int i;
- for (i = 0; i < qp->attr.max_rd_atomic; i++) {
+ for (i = 0; i < qp->attr.max_dest_rd_atomic; i++) {
struct resp_res *res = &qp->resp.resources[i];
if (res->type == 0)
diff --git a/drivers/infiniband/sw/rxe/rxe_task.c b/drivers/infiniband/sw/rxe/rxe_task.c
index d2a14a1..ea3810b 100644
--- a/drivers/infiniband/sw/rxe/rxe_task.c
+++ b/drivers/infiniband/sw/rxe/rxe_task.c
@@ -78,7 +78,7 @@ void rxe_do_task(unsigned long data)
default:
spin_unlock_irqrestore(&task->state_lock, flags);
- pr_warn("bad state = %d in rxe_do_task\n", task->state);
+ pr_warn("%s failed with bad state %d\n", __func__, task->state);
return;
}
@@ -105,7 +105,7 @@ void rxe_do_task(unsigned long data)
break;
default:
- pr_warn("bad state = %d in rxe_do_task\n",
+ pr_warn("%s failed with bad state %d\n", __func__,
task->state);
}
spin_unlock_irqrestore(&task->state_lock, flags);
diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c
index af90a7d..0b362f4 100644
--- a/drivers/infiniband/sw/rxe/rxe_verbs.c
+++ b/drivers/infiniband/sw/rxe/rxe_verbs.c
@@ -51,40 +51,16 @@ static int rxe_query_device(struct ib_device *dev,
return 0;
}
-static void rxe_eth_speed_to_ib_speed(int speed, u8 *active_speed,
- u8 *active_width)
-{
- if (speed <= 1000) {
- *active_width = IB_WIDTH_1X;
- *active_speed = IB_SPEED_SDR;
- } else if (speed <= 10000) {
- *active_width = IB_WIDTH_1X;
- *active_speed = IB_SPEED_FDR10;
- } else if (speed <= 20000) {
- *active_width = IB_WIDTH_4X;
- *active_speed = IB_SPEED_DDR;
- } else if (speed <= 30000) {
- *active_width = IB_WIDTH_4X;
- *active_speed = IB_SPEED_QDR;
- } else if (speed <= 40000) {
- *active_width = IB_WIDTH_4X;
- *active_speed = IB_SPEED_FDR10;
- } else {
- *active_width = IB_WIDTH_4X;
- *active_speed = IB_SPEED_EDR;
- }
-}
-
static int rxe_query_port(struct ib_device *dev,
u8 port_num, struct ib_port_attr *attr)
{
struct rxe_dev *rxe = to_rdev(dev);
struct rxe_port *port;
- u32 speed;
+ int rc = -EINVAL;
if (unlikely(port_num != 1)) {
pr_warn("invalid port_number %d\n", port_num);
- goto err1;
+ goto out;
}
port = &rxe->port;
@@ -93,29 +69,12 @@ static int rxe_query_port(struct ib_device *dev,
*attr = port->attr;
mutex_lock(&rxe->usdev_lock);
- if (rxe->ndev->ethtool_ops->get_link_ksettings) {
- struct ethtool_link_ksettings ks;
-
- rxe->ndev->ethtool_ops->get_link_ksettings(rxe->ndev, &ks);
- speed = ks.base.speed;
- } else if (rxe->ndev->ethtool_ops->get_settings) {
- struct ethtool_cmd cmd;
-
- rxe->ndev->ethtool_ops->get_settings(rxe->ndev, &cmd);
- speed = cmd.speed;
- } else {
- pr_warn("%s speed is unknown, defaulting to 1000\n",
- rxe->ndev->name);
- speed = 1000;
- }
- rxe_eth_speed_to_ib_speed(speed, &attr->active_speed,
- &attr->active_width);
+ rc = ib_get_eth_speed(dev, port_num, &attr->active_speed,
+ &attr->active_width);
mutex_unlock(&rxe->usdev_lock);
- return 0;
-
-err1:
- return -EINVAL;
+out:
+ return rc;
}
static int rxe_query_gid(struct ib_device *device,
@@ -960,6 +919,8 @@ static int rxe_destroy_cq(struct ib_cq *ibcq)
{
struct rxe_cq *cq = to_rcq(ibcq);
+ rxe_cq_disable(cq);
+
rxe_drop_ref(cq);
return 0;
}
@@ -1210,8 +1171,8 @@ static int rxe_detach_mcast(struct ib_qp *ibqp, union ib_gid *mgid, u16 mlid)
return rxe_mcast_drop_grp_elem(rxe, qp, mgid);
}
-static ssize_t rxe_show_parent(struct device *device,
- struct device_attribute *attr, char *buf)
+static ssize_t parent_show(struct device *device,
+ struct device_attribute *attr, char *buf)
{
struct rxe_dev *rxe = container_of(device, struct rxe_dev,
ib_dev.dev);
@@ -1219,7 +1180,7 @@ static ssize_t rxe_show_parent(struct device *device,
return snprintf(buf, 16, "%s\n", rxe_parent_name(rxe, 1));
}
-static DEVICE_ATTR(parent, S_IRUGO, rxe_show_parent, NULL);
+static DEVICE_ATTR_RO(parent);
static struct device_attribute *rxe_dev_attributes[] = {
&dev_attr_parent,
@@ -1336,15 +1297,15 @@ int rxe_register_device(struct rxe_dev *rxe)
err = ib_register_device(dev, NULL);
if (err) {
- pr_warn("rxe_register_device failed, err = %d\n", err);
+ pr_warn("%s failed with error %d\n", __func__, err);
goto err1;
}
for (i = 0; i < ARRAY_SIZE(rxe_dev_attributes); ++i) {
err = device_create_file(&dev->dev, rxe_dev_attributes[i]);
if (err) {
- pr_warn("device_create_file failed, i = %d, err = %d\n",
- i, err);
+ pr_warn("%s failed with error %d for attr number %d\n",
+ __func__, err, i);
goto err2;
}
}
diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h
index 5a180fb..0c2dbe4 100644
--- a/drivers/infiniband/sw/rxe/rxe_verbs.h
+++ b/drivers/infiniband/sw/rxe/rxe_verbs.h
@@ -89,6 +89,7 @@ struct rxe_cq {
struct rxe_queue *queue;
spinlock_t cq_lock;
u8 notify;
+ bool is_dying;
int is_user;
struct tasklet_struct comp_task;
};
@@ -247,6 +248,7 @@ struct rxe_qp {
struct rxe_rq rq;
struct socket *sk;
+ u32 dst_cookie;
struct rxe_av pri_av;
struct rxe_av alt_av;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index 7ac2505..4a5c7a0 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -337,6 +337,7 @@ struct ipoib_dev_priv {
struct rw_semaphore vlan_rwsem;
struct mutex mcast_mutex;
+ struct mutex sysfs_mutex;
struct rb_root path_tree;
struct list_head path_list;
@@ -367,7 +368,7 @@ struct ipoib_dev_priv {
u32 qkey;
union ib_gid local_gid;
- u16 local_lid;
+ u32 local_lid;
unsigned int admin_mtu;
unsigned int mcast_mtu;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index d69410c..14b62f7 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -1506,9 +1506,14 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr,
if (test_bit(IPOIB_FLAG_GOING_DOWN, &priv->flags))
return -EPERM;
- if (!rtnl_trylock())
+ if (!mutex_trylock(&priv->sysfs_mutex))
return restart_syscall();
+ if (!rtnl_trylock()) {
+ mutex_unlock(&priv->sysfs_mutex);
+ return restart_syscall();
+ }
+
ret = ipoib_set_mode(dev, buf);
/* The assumption is that the function ipoib_set_mode returned
@@ -1517,6 +1522,7 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr,
*/
if (ret != -EBUSY)
rtnl_unlock();
+ mutex_unlock(&priv->sysfs_mutex);
return (!ret || ret == -EBUSY) ? count : ret;
}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
index 184a22f..8dc1e62 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
@@ -63,8 +63,7 @@ static void ipoib_get_drvinfo(struct net_device *netdev,
{
struct ipoib_dev_priv *priv = ipoib_priv(netdev);
- ib_get_device_fw_str(priv->ca, drvinfo->fw_version,
- sizeof(drvinfo->fw_version));
+ ib_get_device_fw_str(priv->ca, drvinfo->fw_version);
strlcpy(drvinfo->bus_info, dev_name(priv->ca->dev.parent),
sizeof(drvinfo->bus_info));
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 6c77df3..bac95b5 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -60,7 +60,6 @@ const char ipoib_driver_version[] = DRV_VERSION;
MODULE_AUTHOR("Roland Dreier");
MODULE_DESCRIPTION("IP-over-InfiniBand net driver");
MODULE_LICENSE("Dual BSD/GPL");
-MODULE_VERSION(DRV_VERSION);
int ipoib_sendq_size __read_mostly = IPOIB_TX_RING_SIZE;
int ipoib_recvq_size __read_mostly = IPOIB_RX_RING_SIZE;
@@ -100,6 +99,8 @@ static struct net_device *ipoib_get_net_dev_by_params(
const union ib_gid *gid, const struct sockaddr *addr,
void *client_data);
static int ipoib_set_mac(struct net_device *dev, void *addr);
+static int ipoib_ioctl(struct net_device *dev, struct ifreq *ifr,
+ int cmd);
static struct ib_client ipoib_client = {
.name = "ipoib",
@@ -1681,6 +1682,17 @@ out:
return -ENOMEM;
}
+static int ipoib_ioctl(struct net_device *dev, struct ifreq *ifr,
+ int cmd)
+{
+ struct ipoib_dev_priv *priv = ipoib_priv(dev);
+
+ if (!priv->rn_ops->ndo_do_ioctl)
+ return -EOPNOTSUPP;
+
+ return priv->rn_ops->ndo_do_ioctl(dev, ifr, cmd);
+}
+
int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port)
{
struct ipoib_dev_priv *priv = ipoib_priv(dev);
@@ -1835,6 +1847,7 @@ static const struct net_device_ops ipoib_netdev_ops_pf = {
.ndo_set_vf_guid = ipoib_set_vf_guid,
.ndo_set_mac_address = ipoib_set_mac,
.ndo_get_stats64 = ipoib_get_stats,
+ .ndo_do_ioctl = ipoib_ioctl,
};
static const struct net_device_ops ipoib_netdev_ops_vf = {
@@ -1848,6 +1861,7 @@ static const struct net_device_ops ipoib_netdev_ops_vf = {
.ndo_set_rx_mode = ipoib_set_mcast_list,
.ndo_get_iflink = ipoib_get_iflink,
.ndo_get_stats64 = ipoib_get_stats,
+ .ndo_do_ioctl = ipoib_ioctl,
};
void ipoib_setup_common(struct net_device *dev)
@@ -1879,6 +1893,7 @@ static void ipoib_build_priv(struct net_device *dev)
spin_lock_init(&priv->lock);
init_rwsem(&priv->vlan_rwsem);
mutex_init(&priv->mcast_mutex);
+ mutex_init(&priv->sysfs_mutex);
INIT_LIST_HEAD(&priv->path_list);
INIT_LIST_HEAD(&priv->child_intfs);
@@ -2228,13 +2243,7 @@ static struct net_device *ipoib_add_port(const char *format,
INIT_IB_EVENT_HANDLER(&priv->event_handler,
priv->ca, ipoib_event);
- result = ib_register_event_handler(&priv->event_handler);
- if (result < 0) {
- printk(KERN_WARNING "%s: ib_register_event_handler failed for "
- "port %d (ret = %d)\n",
- hca->name, port, result);
- goto event_failed;
- }
+ ib_register_event_handler(&priv->event_handler);
result = register_netdev(priv->dev);
if (result) {
@@ -2267,8 +2276,6 @@ register_failed:
set_bit(IPOIB_STOP_NEIGH_GC, &priv->flags);
cancel_delayed_work(&priv->neigh_reap_task);
flush_workqueue(priv->wq);
-
-event_failed:
ipoib_dev_cleanup(priv->dev);
device_init_failed:
@@ -2338,7 +2345,11 @@ static void ipoib_remove_one(struct ib_device *device, void *client_data)
cancel_delayed_work(&priv->neigh_reap_task);
flush_workqueue(priv->wq);
+ /* Wrap rtnl_lock/unlock with mutex to protect sysfs calls */
+ mutex_lock(&priv->sysfs_mutex);
unregister_netdev(priv->dev);
+ mutex_unlock(&priv->sysfs_mutex);
+
rn->free_rdma_netdev(priv->dev);
list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
index 081b33d..9927cd6 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -133,12 +133,20 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
snprintf(intf_name, sizeof intf_name, "%s.%04x",
ppriv->dev->name, pkey);
- if (!rtnl_trylock())
+ if (!mutex_trylock(&ppriv->sysfs_mutex))
return restart_syscall();
+ if (!rtnl_trylock()) {
+ mutex_unlock(&ppriv->sysfs_mutex);
+ return restart_syscall();
+ }
+
priv = ipoib_intf_alloc(ppriv->ca, ppriv->port, intf_name);
- if (!priv)
+ if (!priv) {
+ rtnl_unlock();
+ mutex_unlock(&ppriv->sysfs_mutex);
return -ENOMEM;
+ }
down_write(&ppriv->vlan_rwsem);
@@ -164,8 +172,8 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
out:
up_write(&ppriv->vlan_rwsem);
-
rtnl_unlock();
+ mutex_unlock(&ppriv->sysfs_mutex);
if (result) {
free_netdev(priv->dev);
@@ -188,8 +196,13 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey)
if (test_bit(IPOIB_FLAG_GOING_DOWN, &ppriv->flags))
return -EPERM;
- if (!rtnl_trylock())
+ if (!mutex_trylock(&ppriv->sysfs_mutex))
+ return restart_syscall();
+
+ if (!rtnl_trylock()) {
+ mutex_unlock(&ppriv->sysfs_mutex);
return restart_syscall();
+ }
down_write(&ppriv->vlan_rwsem);
list_for_each_entry_safe(priv, tpriv, &ppriv->child_intfs, list) {
@@ -208,6 +221,7 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey)
}
rtnl_unlock();
+ mutex_unlock(&ppriv->sysfs_mutex);
if (dev) {
free_netdev(dev);
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 37b33d7..19624e0 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -77,7 +77,6 @@
MODULE_DESCRIPTION("iSER (iSCSI Extensions for RDMA) Datamover");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Alex Nezhinsky, Dan Bar Dov, Or Gerlitz");
-MODULE_VERSION(DRV_VER);
static struct scsi_host_template iscsi_iser_sht;
static struct iscsi_transport iscsi_iser_transport;
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 26a004e..55a73b0 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -106,9 +106,7 @@ static int iser_create_device_ib_res(struct iser_device *device)
INIT_IB_EVENT_HANDLER(&device->event_handler, ib_dev,
iser_event_handler);
- if (ib_register_event_handler(&device->event_handler))
- goto cq_err;
-
+ ib_register_event_handler(&device->event_handler);
return 0;
cq_err:
@@ -141,7 +139,7 @@ static void iser_free_device_ib_res(struct iser_device *device)
comp->cq = NULL;
}
- (void)ib_unregister_event_handler(&device->event_handler);
+ ib_unregister_event_handler(&device->event_handler);
ib_dealloc_pd(device->pd);
kfree(device->comps);
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index 0e66265..ceabdb8 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -2710,7 +2710,6 @@ static void __exit isert_exit(void)
}
MODULE_DESCRIPTION("iSER-Target for mainline target infrastructure");
-MODULE_VERSION("1.0");
MODULE_AUTHOR("nab@Linux-iSCSI.org");
MODULE_LICENSE("GPL");
diff --git a/drivers/infiniband/ulp/opa_vnic/opa_vnic_vema.c b/drivers/infiniband/ulp/opa_vnic/opa_vnic_vema.c
index cf768dd..21f0b48 100644
--- a/drivers/infiniband/ulp/opa_vnic/opa_vnic_vema.c
+++ b/drivers/infiniband/ulp/opa_vnic/opa_vnic_vema.c
@@ -52,7 +52,9 @@
#include <linux/module.h>
#include <rdma/ib_addr.h>
-#include <rdma/ib_smi.h>
+#include <rdma/ib_verbs.h>
+#include <rdma/opa_smi.h>
+#include <rdma/opa_port_info.h>
#include "opa_vnic_internal.h"
@@ -952,12 +954,7 @@ static int vema_register(struct opa_vnic_ctrl_port *cport)
INIT_IB_EVENT_HANDLER(&port->event_handler,
cport->ibdev, opa_vnic_event);
- ret = ib_register_event_handler(&port->event_handler);
- if (ret) {
- c_err("port %d: event handler register failed\n", i);
- vema_unregister(cport);
- return ret;
- }
+ ib_register_event_handler(&port->event_handler);
idr_init(&port->vport_idr);
mutex_init(&port->lock);
@@ -980,6 +977,27 @@ static int vema_register(struct opa_vnic_ctrl_port *cport)
}
/**
+ * opa_vnic_ctrl_config_dev -- This function sends a trap to the EM
+ * by way of ib_modify_port to indicate support for ethernet on the
+ * fabric.
+ * @cport: pointer to control port
+ * @en: enable or disable ethernet on fabric support
+ */
+static void opa_vnic_ctrl_config_dev(struct opa_vnic_ctrl_port *cport, bool en)
+{
+ struct ib_port_modify pm = { 0 };
+ int i;
+
+ if (en)
+ pm.set_port_cap_mask = OPA_CAP_MASK3_IsEthOnFabricSupported;
+ else
+ pm.clr_port_cap_mask = OPA_CAP_MASK3_IsEthOnFabricSupported;
+
+ for (i = 1; i <= cport->num_ports; i++)
+ ib_modify_port(cport->ibdev, i, IB_PORT_OPA_MASK_CHG, &pm);
+}
+
+/**
* opa_vnic_vema_add_one -- Handle new ib device
* @device: ib device pointer
*
@@ -1007,6 +1025,7 @@ static void opa_vnic_vema_add_one(struct ib_device *device)
c_info("VNIC client initialized\n");
ib_set_client_data(device, &opa_vnic_client, cport);
+ opa_vnic_ctrl_config_dev(cport, true);
}
/**
@@ -1025,6 +1044,7 @@ static void opa_vnic_vema_rem_one(struct ib_device *device,
return;
c_info("removing VNIC client\n");
+ opa_vnic_ctrl_config_dev(cport, false);
vema_unregister(cport);
kfree(cport);
}
@@ -1053,4 +1073,3 @@ module_exit(opa_vnic_deinit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Intel Corporation");
MODULE_DESCRIPTION("Intel OPA Virtual Network driver");
-MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 2354c74..fa5ccdb 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -62,7 +62,6 @@
MODULE_AUTHOR("Roland Dreier");
MODULE_DESCRIPTION("InfiniBand SCSI RDMA Protocol initiator");
MODULE_LICENSE("Dual BSD/GPL");
-MODULE_VERSION(DRV_VERSION);
MODULE_INFO(release_date, DRV_RELDATE);
#if !defined(CONFIG_DYNAMIC_DEBUG)
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
index 402275b..9e8e922 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -2238,7 +2238,7 @@ static int srpt_write_pending(struct se_cmd *se_cmd)
cqe, first_wr);
cqe = NULL;
}
-
+
ret = ib_post_send(ch->qp, first_wr, &bad_wr);
if (ret) {
pr_err("%s: ib_post_send() returned %d for %d (avail: %d)\n",
@@ -2530,8 +2530,7 @@ static void srpt_add_one(struct ib_device *device)
INIT_IB_EVENT_HANDLER(&sdev->event_handler, sdev->device,
srpt_event_handler);
- if (ib_register_event_handler(&sdev->event_handler))
- goto err_cm;
+ ib_register_event_handler(&sdev->event_handler);
sdev->ioctx_ring = (struct srpt_recv_ioctx **)
srpt_alloc_ioctx_ring(sdev, sdev->srq_size,
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.h b/drivers/infiniband/ulp/srpt/ib_srpt.h
index cc118385..1b817e5 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.h
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.h
@@ -328,8 +328,8 @@ struct srpt_port {
u8 port_guid[24];
u8 port_gid[64];
u8 port;
- u16 sm_lid;
- u16 lid;
+ u32 sm_lid;
+ u32 lid;
union ib_gid gid;
struct work_struct work;
struct se_portal_group port_guid_tpg;
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 298a6ba..ca0e19a 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -476,10 +476,21 @@ static const u8 xboxone_hori_init[] = {
};
/*
- * A rumble packet is required for some PowerA pads to start
+ * A specific rumble packet is required for some PowerA pads to start
* sending input reports. One of those pads is (0x24c6:0x543a).
*/
-static const u8 xboxone_zerorumble_init[] = {
+static const u8 xboxone_rumblebegin_init[] = {
+ 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00,
+ 0x1D, 0x1D, 0xFF, 0x00, 0x00
+};
+
+/*
+ * A rumble packet with zero FF intensity will immediately
+ * terminate the rumbling required to init PowerA pads.
+ * This should happen fast enough that the motors don't
+ * spin up to enough speed to actually vibrate the gamepad.
+ */
+static const u8 xboxone_rumbleend_init[] = {
0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00
};
@@ -494,9 +505,12 @@ static const struct xboxone_init_packet xboxone_init_packets[] = {
XBOXONE_INIT_PKT(0x0e6f, 0x0165, xboxone_hori_init),
XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_init),
XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init),
- XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_zerorumble_init),
- XBOXONE_INIT_PKT(0x24c6, 0x542a, xboxone_zerorumble_init),
- XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_zerorumble_init),
+ XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumblebegin_init),
+ XBOXONE_INIT_PKT(0x24c6, 0x542a, xboxone_rumblebegin_init),
+ XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_rumblebegin_init),
+ XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumbleend_init),
+ XBOXONE_INIT_PKT(0x24c6, 0x542a, xboxone_rumbleend_init),
+ XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_rumbleend_init),
};
struct xpad_output_packet {
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index a047b9a..0b10d4b 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -827,7 +827,7 @@ static int gpio_keys_probe(struct platform_device *pdev)
fwnode_handle_put(child);
- error = sysfs_create_group(&dev->kobj, &gpio_keys_attr_group);
+ error = devm_device_add_group(dev, &gpio_keys_attr_group);
if (error) {
dev_err(dev, "Unable to export keys/switches, error: %d\n",
error);
@@ -838,23 +838,12 @@ static int gpio_keys_probe(struct platform_device *pdev)
if (error) {
dev_err(dev, "Unable to register input device, error: %d\n",
error);
- goto err_remove_group;
+ return error;
}
device_init_wakeup(dev, wakeup);
return 0;
-
-err_remove_group:
- sysfs_remove_group(&dev->kobj, &gpio_keys_attr_group);
- return error;
-}
-
-static int gpio_keys_remove(struct platform_device *pdev)
-{
- sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group);
-
- return 0;
}
static int __maybe_unused gpio_keys_suspend(struct device *dev)
@@ -912,7 +901,6 @@ static SIMPLE_DEV_PM_OPS(gpio_keys_pm_ops, gpio_keys_suspend, gpio_keys_resume);
static struct platform_driver gpio_keys_device_driver = {
.probe = gpio_keys_probe,
- .remove = gpio_keys_remove,
.driver = {
.name = "gpio-keys",
.pm = &gpio_keys_pm_ops,
diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c
index 198dc07..a4e404a 100644
--- a/drivers/input/keyboard/hilkbd.c
+++ b/drivers/input/keyboard/hilkbd.c
@@ -299,7 +299,7 @@ static void hil_keyb_exit(void)
}
#if defined(CONFIG_PARISC)
-static int hil_probe_chip(struct parisc_device *dev)
+static int __init hil_probe_chip(struct parisc_device *dev)
{
/* Only allow one HIL keyboard */
if (hil_dev.dev)
@@ -320,14 +320,14 @@ static int hil_probe_chip(struct parisc_device *dev)
return hil_keyb_init();
}
-static int hil_remove_chip(struct parisc_device *dev)
+static int __exit hil_remove_chip(struct parisc_device *dev)
{
hil_keyb_exit();
return 0;
}
-static struct parisc_device_id hil_tbl[] = {
+static const struct parisc_device_id hil_tbl[] __initconst = {
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00073 },
{ 0, }
};
@@ -337,11 +337,11 @@ static struct parisc_device_id hil_tbl[] = {
MODULE_DEVICE_TABLE(parisc, hil_tbl);
#endif
-static struct parisc_driver hil_driver = {
+static struct parisc_driver hil_driver __refdata = {
.name = "hil",
.id_table = hil_tbl,
.probe = hil_probe_chip,
- .remove = hil_remove_chip,
+ .remove = __exit_p(hil_remove_chip),
};
static int __init hil_init(void)
diff --git a/drivers/input/misc/axp20x-pek.c b/drivers/input/misc/axp20x-pek.c
index 38c79eb..cfeb0e9 100644
--- a/drivers/input/misc/axp20x-pek.c
+++ b/drivers/input/misc/axp20x-pek.c
@@ -182,13 +182,6 @@ static irqreturn_t axp20x_pek_irq(int irq, void *pwr)
return IRQ_HANDLED;
}
-static void axp20x_remove_sysfs_group(void *_data)
-{
- struct device *dev = _data;
-
- sysfs_remove_group(&dev->kobj, &axp20x_attribute_group);
-}
-
static int axp20x_pek_probe_input_device(struct axp20x_pek *axp20x_pek,
struct platform_device *pdev)
{
@@ -313,22 +306,13 @@ static int axp20x_pek_probe(struct platform_device *pdev)
return error;
}
- error = sysfs_create_group(&pdev->dev.kobj, &axp20x_attribute_group);
+ error = devm_device_add_group(&pdev->dev, &axp20x_attribute_group);
if (error) {
dev_err(&pdev->dev, "Failed to create sysfs attributes: %d\n",
error);
return error;
}
- error = devm_add_action(&pdev->dev,
- axp20x_remove_sysfs_group, &pdev->dev);
- if (error) {
- axp20x_remove_sysfs_group(&pdev->dev);
- dev_err(&pdev->dev, "Failed to add sysfs cleanup action: %d\n",
- error);
- return error;
- }
-
platform_set_drvdata(pdev, axp20x_pek);
return 0;
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index 16c3046..5af0b7d 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -535,16 +535,17 @@ static void synaptics_apply_quirks(struct psmouse *psmouse,
}
}
+static bool synaptics_has_agm(struct synaptics_data *priv)
+{
+ return (SYN_CAP_ADV_GESTURE(priv->info.ext_cap_0c) ||
+ SYN_CAP_IMAGE_SENSOR(priv->info.ext_cap_0c));
+}
+
static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse)
{
static u8 param = 0xc8;
- struct synaptics_data *priv = psmouse->private;
int error;
- if (!(SYN_CAP_ADV_GESTURE(priv->info.ext_cap_0c) ||
- SYN_CAP_IMAGE_SENSOR(priv->info.ext_cap_0c)))
- return 0;
-
error = psmouse_sliced_command(psmouse, SYN_QUE_MODEL);
if (error)
return error;
@@ -553,9 +554,6 @@ static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse)
if (error)
return error;
- /* Advanced gesture mode also sends multi finger data */
- priv->info.capabilities |= BIT(1);
-
return 0;
}
@@ -578,7 +576,7 @@ static int synaptics_set_mode(struct psmouse *psmouse)
if (error)
return error;
- if (priv->absolute_mode) {
+ if (priv->absolute_mode && synaptics_has_agm(priv)) {
error = synaptics_set_advanced_gesture_mode(psmouse);
if (error) {
psmouse_err(psmouse,
@@ -766,9 +764,7 @@ static int synaptics_parse_hw_state(const u8 buf[],
((buf[0] & 0x04) >> 1) |
((buf[3] & 0x04) >> 2));
- if ((SYN_CAP_ADV_GESTURE(priv->info.ext_cap_0c) ||
- SYN_CAP_IMAGE_SENSOR(priv->info.ext_cap_0c)) &&
- hw->w == 2) {
+ if (synaptics_has_agm(priv) && hw->w == 2) {
synaptics_parse_agm(buf, priv, hw);
return 1;
}
@@ -1033,6 +1029,15 @@ static void synaptics_image_sensor_process(struct psmouse *psmouse,
synaptics_report_mt_data(psmouse, sgm, num_fingers);
}
+static bool synaptics_has_multifinger(struct synaptics_data *priv)
+{
+ if (SYN_CAP_MULTIFINGER(priv->info.capabilities))
+ return true;
+
+ /* Advanced gesture mode also sends multi finger data */
+ return synaptics_has_agm(priv);
+}
+
/*
* called for each full received packet from the touchpad
*/
@@ -1079,7 +1084,7 @@ static void synaptics_process_packet(struct psmouse *psmouse)
if (SYN_CAP_EXTENDED(info->capabilities)) {
switch (hw.w) {
case 0 ... 1:
- if (SYN_CAP_MULTIFINGER(info->capabilities))
+ if (synaptics_has_multifinger(priv))
num_fingers = hw.w + 2;
break;
case 2:
@@ -1123,7 +1128,7 @@ static void synaptics_process_packet(struct psmouse *psmouse)
input_report_abs(dev, ABS_TOOL_WIDTH, finger_width);
input_report_key(dev, BTN_TOOL_FINGER, num_fingers == 1);
- if (SYN_CAP_MULTIFINGER(info->capabilities)) {
+ if (synaptics_has_multifinger(priv)) {
input_report_key(dev, BTN_TOOL_DOUBLETAP, num_fingers == 2);
input_report_key(dev, BTN_TOOL_TRIPLETAP, num_fingers == 3);
}
@@ -1283,7 +1288,7 @@ static void set_input_params(struct psmouse *psmouse,
__set_bit(BTN_TOUCH, dev->keybit);
__set_bit(BTN_TOOL_FINGER, dev->keybit);
- if (SYN_CAP_MULTIFINGER(info->capabilities)) {
+ if (synaptics_has_multifinger(priv)) {
__set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
__set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
}
diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index 7f7e917..6dca3c0 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -570,18 +570,14 @@ static int rmi_f01_probe(struct rmi_function *fn)
dev_set_drvdata(&fn->dev, f01);
- error = sysfs_create_group(&fn->rmi_dev->dev.kobj, &rmi_f01_attr_group);
+ error = devm_device_add_group(&fn->rmi_dev->dev, &rmi_f01_attr_group);
if (error)
- dev_warn(&fn->dev, "Failed to create sysfs group: %d\n", error);
+ dev_warn(&fn->dev,
+ "Failed to create attribute group: %d\n", error);
return 0;
}
-static void rmi_f01_remove(struct rmi_function *fn)
-{
- sysfs_remove_group(&fn->rmi_dev->dev.kobj, &rmi_f01_attr_group);
-}
-
static int rmi_f01_config(struct rmi_function *fn)
{
struct f01_data *f01 = dev_get_drvdata(&fn->dev);
@@ -721,7 +717,6 @@ struct rmi_function_handler rmi_f01_handler = {
},
.func = 0x01,
.probe = rmi_f01_probe,
- .remove = rmi_f01_remove,
.config = rmi_f01_config,
.attention = rmi_f01_attention,
.suspend = rmi_f01_suspend,
diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
index ecba666..aa9f29b 100644
--- a/drivers/input/serio/gscps2.c
+++ b/drivers/input/serio/gscps2.c
@@ -325,7 +325,7 @@ static void gscps2_close(struct serio *port)
* @return: success/error report
*/
-static int gscps2_probe(struct parisc_device *dev)
+static int __init gscps2_probe(struct parisc_device *dev)
{
struct gscps2port *ps2port;
struct serio *serio;
@@ -412,7 +412,7 @@ fail_nomem:
* @return: success/error report
*/
-static int gscps2_remove(struct parisc_device *dev)
+static int __exit gscps2_remove(struct parisc_device *dev)
{
struct gscps2port *ps2port = dev_get_drvdata(&dev->dev);
@@ -430,7 +430,7 @@ static int gscps2_remove(struct parisc_device *dev)
}
-static struct parisc_device_id gscps2_device_tbl[] = {
+static const struct parisc_device_id gscps2_device_tbl[] __initconst = {
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00084 }, /* LASI PS/2 */
#ifdef DINO_TESTED
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00096 }, /* DINO PS/2 */
@@ -439,11 +439,11 @@ static struct parisc_device_id gscps2_device_tbl[] = {
};
MODULE_DEVICE_TABLE(parisc, gscps2_device_tbl);
-static struct parisc_driver parisc_ps2_driver = {
+static struct parisc_driver parisc_ps2_driver __refdata = {
.name = "gsc_ps2",
.id_table = gscps2_device_tbl,
.probe = gscps2_probe,
- .remove = gscps2_remove,
+ .remove = __exit_p(gscps2_remove),
};
static int __init gscps2_init(void)
diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c
index 1bfdae4..8eef684 100644
--- a/drivers/input/serio/hp_sdc.c
+++ b/drivers/input/serio/hp_sdc.c
@@ -805,7 +805,7 @@ static void hp_sdc_kicker(unsigned long data)
#if defined(__hppa__)
-static const struct parisc_device_id hp_sdc_tbl[] = {
+static const struct parisc_device_id hp_sdc_tbl[] __initconst = {
{
.hw_type = HPHW_FIO,
.hversion_rev = HVERSION_REV_ANY_ID,
@@ -820,7 +820,7 @@ MODULE_DEVICE_TABLE(parisc, hp_sdc_tbl);
static int __init hp_sdc_init_hppa(struct parisc_device *d);
static struct delayed_work moduleloader_work;
-static struct parisc_driver hp_sdc_driver = {
+static struct parisc_driver hp_sdc_driver __refdata = {
.name = "hp_sdc",
.id_table = hp_sdc_tbl,
.probe = hp_sdc_init_hppa,
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 354cbd6..4ad7e5e 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -575,7 +575,7 @@ static void dump_dte_entry(u16 devid)
static void dump_command(unsigned long phys_addr)
{
- struct iommu_cmd *cmd = phys_to_virt(phys_addr);
+ struct iommu_cmd *cmd = iommu_phys_to_virt(phys_addr);
int i;
for (i = 0; i < 4; ++i)
@@ -919,11 +919,13 @@ static void copy_cmd_to_buffer(struct amd_iommu *iommu,
static void build_completion_wait(struct iommu_cmd *cmd, u64 address)
{
+ u64 paddr = iommu_virt_to_phys((void *)address);
+
WARN_ON(address & 0x7ULL);
memset(cmd, 0, sizeof(*cmd));
- cmd->data[0] = lower_32_bits(__pa(address)) | CMD_COMPL_WAIT_STORE_MASK;
- cmd->data[1] = upper_32_bits(__pa(address));
+ cmd->data[0] = lower_32_bits(paddr) | CMD_COMPL_WAIT_STORE_MASK;
+ cmd->data[1] = upper_32_bits(paddr);
cmd->data[2] = 1;
CMD_SET_TYPE(cmd, CMD_COMPL_WAIT);
}
@@ -1383,7 +1385,7 @@ static bool increase_address_space(struct protection_domain *domain,
return false;
*pte = PM_LEVEL_PDE(domain->mode,
- virt_to_phys(domain->pt_root));
+ iommu_virt_to_phys(domain->pt_root));
domain->pt_root = pte;
domain->mode += 1;
domain->updated = true;
@@ -1420,7 +1422,7 @@ static u64 *alloc_pte(struct protection_domain *domain,
if (!page)
return NULL;
- __npte = PM_LEVEL_PDE(level, virt_to_phys(page));
+ __npte = PM_LEVEL_PDE(level, iommu_virt_to_phys(page));
/* pte could have been changed somewhere. */
if (cmpxchg64(pte, __pte, __npte) != __pte) {
@@ -1536,10 +1538,10 @@ static int iommu_map_page(struct protection_domain *dom,
return -EBUSY;
if (count > 1) {
- __pte = PAGE_SIZE_PTE(phys_addr, page_size);
+ __pte = PAGE_SIZE_PTE(__sme_set(phys_addr), page_size);
__pte |= PM_LEVEL_ENC(7) | IOMMU_PTE_P | IOMMU_PTE_FC;
} else
- __pte = phys_addr | IOMMU_PTE_P | IOMMU_PTE_FC;
+ __pte = __sme_set(phys_addr) | IOMMU_PTE_P | IOMMU_PTE_FC;
if (prot & IOMMU_PROT_IR)
__pte |= IOMMU_PTE_IR;
@@ -1755,7 +1757,7 @@ static void free_gcr3_tbl_level1(u64 *tbl)
if (!(tbl[i] & GCR3_VALID))
continue;
- ptr = __va(tbl[i] & PAGE_MASK);
+ ptr = iommu_phys_to_virt(tbl[i] & PAGE_MASK);
free_page((unsigned long)ptr);
}
@@ -1770,7 +1772,7 @@ static void free_gcr3_tbl_level2(u64 *tbl)
if (!(tbl[i] & GCR3_VALID))
continue;
- ptr = __va(tbl[i] & PAGE_MASK);
+ ptr = iommu_phys_to_virt(tbl[i] & PAGE_MASK);
free_gcr3_tbl_level1(ptr);
}
@@ -2049,7 +2051,7 @@ static void set_dte_entry(u16 devid, struct protection_domain *domain, bool ats)
u64 flags = 0;
if (domain->mode != PAGE_MODE_NONE)
- pte_root = virt_to_phys(domain->pt_root);
+ pte_root = iommu_virt_to_phys(domain->pt_root);
pte_root |= (domain->mode & DEV_ENTRY_MODE_MASK)
<< DEV_ENTRY_MODE_SHIFT;
@@ -2061,7 +2063,7 @@ static void set_dte_entry(u16 devid, struct protection_domain *domain, bool ats)
flags |= DTE_FLAG_IOTLB;
if (domain->flags & PD_IOMMUV2_MASK) {
- u64 gcr3 = __pa(domain->gcr3_tbl);
+ u64 gcr3 = iommu_virt_to_phys(domain->gcr3_tbl);
u64 glx = domain->glx;
u64 tmp;
@@ -3606,10 +3608,10 @@ static u64 *__get_gcr3_pte(u64 *root, int level, int pasid, bool alloc)
if (root == NULL)
return NULL;
- *pte = __pa(root) | GCR3_VALID;
+ *pte = iommu_virt_to_phys(root) | GCR3_VALID;
}
- root = __va(*pte & PAGE_MASK);
+ root = iommu_phys_to_virt(*pte & PAGE_MASK);
level -= 1;
}
@@ -3788,7 +3790,7 @@ static void set_dte_irq_entry(u16 devid, struct irq_remap_table *table)
dte = amd_iommu_dev_table[devid].data[2];
dte &= ~DTE_IRQ_PHYS_ADDR_MASK;
- dte |= virt_to_phys(table->table);
+ dte |= iommu_virt_to_phys(table->table);
dte |= DTE_IRQ_REMAP_INTCTL;
dte |= DTE_IRQ_TABLE_LEN;
dte |= DTE_IRQ_REMAP_ENABLE;
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 3723037..2292a6c 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -30,6 +30,7 @@
#include <linux/iommu.h>
#include <linux/kmemleak.h>
#include <linux/crash_dump.h>
+#include <linux/mem_encrypt.h>
#include <asm/pci-direct.h>
#include <asm/iommu.h>
#include <asm/gart.h>
@@ -348,7 +349,7 @@ static void iommu_set_device_table(struct amd_iommu *iommu)
BUG_ON(iommu->mmio_base == NULL);
- entry = virt_to_phys(amd_iommu_dev_table);
+ entry = iommu_virt_to_phys(amd_iommu_dev_table);
entry |= (dev_table_size >> 12) - 1;
memcpy_toio(iommu->mmio_base + MMIO_DEV_TABLE_OFFSET,
&entry, sizeof(entry));
@@ -606,7 +607,7 @@ static void iommu_enable_command_buffer(struct amd_iommu *iommu)
BUG_ON(iommu->cmd_buf == NULL);
- entry = (u64)virt_to_phys(iommu->cmd_buf);
+ entry = iommu_virt_to_phys(iommu->cmd_buf);
entry |= MMIO_CMD_SIZE_512;
memcpy_toio(iommu->mmio_base + MMIO_CMD_BUF_OFFSET,
@@ -635,7 +636,7 @@ static void iommu_enable_event_buffer(struct amd_iommu *iommu)
BUG_ON(iommu->evt_buf == NULL);
- entry = (u64)virt_to_phys(iommu->evt_buf) | EVT_LEN_MASK;
+ entry = iommu_virt_to_phys(iommu->evt_buf) | EVT_LEN_MASK;
memcpy_toio(iommu->mmio_base + MMIO_EVT_BUF_OFFSET,
&entry, sizeof(entry));
@@ -668,7 +669,7 @@ static void iommu_enable_ppr_log(struct amd_iommu *iommu)
if (iommu->ppr_log == NULL)
return;
- entry = (u64)virt_to_phys(iommu->ppr_log) | PPR_LOG_SIZE_512;
+ entry = iommu_virt_to_phys(iommu->ppr_log) | PPR_LOG_SIZE_512;
memcpy_toio(iommu->mmio_base + MMIO_PPR_LOG_OFFSET,
&entry, sizeof(entry));
@@ -748,10 +749,10 @@ static int iommu_init_ga_log(struct amd_iommu *iommu)
if (!iommu->ga_log_tail)
goto err_out;
- entry = (u64)virt_to_phys(iommu->ga_log) | GA_LOG_SIZE_512;
+ entry = iommu_virt_to_phys(iommu->ga_log) | GA_LOG_SIZE_512;
memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_BASE_OFFSET,
&entry, sizeof(entry));
- entry = ((u64)virt_to_phys(iommu->ga_log) & 0xFFFFFFFFFFFFFULL) & ~7ULL;
+ entry = (iommu_virt_to_phys(iommu->ga_log) & 0xFFFFFFFFFFFFFULL) & ~7ULL;
memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_TAIL_OFFSET,
&entry, sizeof(entry));
writel(0x00, iommu->mmio_base + MMIO_GA_HEAD_OFFSET);
@@ -2564,6 +2565,24 @@ static int __init amd_iommu_init(void)
return ret;
}
+static bool amd_iommu_sme_check(void)
+{
+ if (!sme_active() || (boot_cpu_data.x86 != 0x17))
+ return true;
+
+ /* For Fam17h, a specific level of support is required */
+ if (boot_cpu_data.microcode >= 0x08001205)
+ return true;
+
+ if ((boot_cpu_data.microcode >= 0x08001126) &&
+ (boot_cpu_data.microcode <= 0x080011ff))
+ return true;
+
+ pr_notice("AMD-Vi: IOMMU not currently supported when SME is active\n");
+
+ return false;
+}
+
/****************************************************************************
*
* Early detect code. This code runs at IOMMU detection time in the DMA
@@ -2578,6 +2597,9 @@ int __init amd_iommu_detect(void)
if (no_iommu || (iommu_detected && !gart_iommu_aperture))
return -ENODEV;
+ if (!amd_iommu_sme_check())
+ return -ENODEV;
+
ret = iommu_go_to_state(IOMMU_IVRS_DETECTED);
if (ret)
return ret;
diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h
index 466260f..3f12fb2 100644
--- a/drivers/iommu/amd_iommu_proto.h
+++ b/drivers/iommu/amd_iommu_proto.h
@@ -87,4 +87,14 @@ static inline bool iommu_feature(struct amd_iommu *iommu, u64 f)
return !!(iommu->features & f);
}
+static inline u64 iommu_virt_to_phys(void *vaddr)
+{
+ return (u64)__sme_set(virt_to_phys(vaddr));
+}
+
+static inline void *iommu_phys_to_virt(unsigned long paddr)
+{
+ return phys_to_virt(__sme_clr(paddr));
+}
+
#endif /* _ASM_X86_AMD_IOMMU_PROTO_H */
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index d6b873b..8e3a857 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -344,7 +344,7 @@
#define IOMMU_PAGE_MASK (((1ULL << 52) - 1) & ~0xfffULL)
#define IOMMU_PTE_PRESENT(pte) ((pte) & IOMMU_PTE_P)
-#define IOMMU_PTE_PAGE(pte) (phys_to_virt((pte) & IOMMU_PAGE_MASK))
+#define IOMMU_PTE_PAGE(pte) (iommu_phys_to_virt((pte) & IOMMU_PAGE_MASK))
#define IOMMU_PTE_MODE(pte) (((pte) >> 9) & 0x07)
#define IOMMU_PROT_MASK 0x03
diff --git a/drivers/iommu/amd_iommu_v2.c b/drivers/iommu/amd_iommu_v2.c
index 6629c47..dccf5b7 100644
--- a/drivers/iommu/amd_iommu_v2.c
+++ b/drivers/iommu/amd_iommu_v2.c
@@ -391,13 +391,6 @@ static int mn_clear_flush_young(struct mmu_notifier *mn,
return 0;
}
-static void mn_invalidate_page(struct mmu_notifier *mn,
- struct mm_struct *mm,
- unsigned long address)
-{
- __mn_flush_page(mn, address);
-}
-
static void mn_invalidate_range(struct mmu_notifier *mn,
struct mm_struct *mm,
unsigned long start, unsigned long end)
@@ -436,7 +429,6 @@ static void mn_release(struct mmu_notifier *mn, struct mm_struct *mm)
static const struct mmu_notifier_ops iommu_mn = {
.release = mn_release,
.clear_flush_young = mn_clear_flush_young,
- .invalidate_page = mn_invalidate_page,
.invalidate_range = mn_invalidate_range,
};
diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c
index f167c0d..f620dcc 100644
--- a/drivers/iommu/intel-svm.c
+++ b/drivers/iommu/intel-svm.c
@@ -223,14 +223,6 @@ static void intel_change_pte(struct mmu_notifier *mn, struct mm_struct *mm,
intel_flush_svm_range(svm, address, 1, 1, 0);
}
-static void intel_invalidate_page(struct mmu_notifier *mn, struct mm_struct *mm,
- unsigned long address)
-{
- struct intel_svm *svm = container_of(mn, struct intel_svm, notifier);
-
- intel_flush_svm_range(svm, address, 1, 1, 0);
-}
-
/* Pages have been freed at this point */
static void intel_invalidate_range(struct mmu_notifier *mn,
struct mm_struct *mm,
@@ -285,7 +277,6 @@ static void intel_mm_release(struct mmu_notifier *mn, struct mm_struct *mm)
static const struct mmu_notifier_ops intel_mmuops = {
.release = intel_mm_release,
.change_pte = intel_change_pte,
- .invalidate_page = intel_invalidate_page,
.invalidate_range = intel_invalidate_range,
};
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index f1fd5f4..9d8a1dd 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -7,6 +7,7 @@ config ARM_GIC
select IRQ_DOMAIN
select IRQ_DOMAIN_HIERARCHY
select MULTI_IRQ_HANDLER
+ select GENERIC_IRQ_EFFECTIVE_AFF_MASK
config ARM_GIC_PM
bool
@@ -34,6 +35,7 @@ config ARM_GIC_V3
select MULTI_IRQ_HANDLER
select IRQ_DOMAIN_HIERARCHY
select PARTITION_PERCPU
+ select GENERIC_IRQ_EFFECTIVE_AFF_MASK
config ARM_GIC_V3_ITS
bool
@@ -64,6 +66,7 @@ config ARMADA_370_XP_IRQ
bool
select GENERIC_IRQ_CHIP
select PCI_MSI if PCI
+ select GENERIC_IRQ_EFFECTIVE_AFF_MASK
config ALPINE_MSI
bool
@@ -93,11 +96,13 @@ config BCM6345_L1_IRQ
bool
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
+ select GENERIC_IRQ_EFFECTIVE_AFF_MASK
config BCM7038_L1_IRQ
bool
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
+ select GENERIC_IRQ_EFFECTIVE_AFF_MASK
config BCM7120_L2_IRQ
bool
@@ -136,6 +141,7 @@ config IRQ_MIPS_CPU
select GENERIC_IRQ_IPI if SYS_SUPPORTS_MULTITHREADING
select IRQ_DOMAIN
select IRQ_DOMAIN_HIERARCHY if GENERIC_IRQ_IPI
+ select GENERIC_IRQ_EFFECTIVE_AFF_MASK
config CLPS711X_IRQCHIP
bool
@@ -217,6 +223,7 @@ config VERSATILE_FPGA_IRQ_NR
config XTENSA_MX
bool
select IRQ_DOMAIN
+ select GENERIC_IRQ_EFFECTIVE_AFF_MASK
config XILINX_INTC
bool
@@ -306,3 +313,11 @@ config QCOM_IRQ_COMBINER
help
Say yes here to add support for the IRQ combiner devices embedded
in Qualcomm Technologies chips.
+
+config IRQ_UNIPHIER_AIDET
+ bool "UniPhier AIDET support" if COMPILE_TEST
+ depends on ARCH_UNIPHIER || COMPILE_TEST
+ default ARCH_UNIPHIER
+ select IRQ_DOMAIN_HIERARCHY
+ help
+ Support for the UniPhier AIDET (ARM Interrupt Detector).
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index e88d856..845abc1 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -28,7 +28,7 @@ obj-$(CONFIG_ARM_GIC_PM) += irq-gic-pm.o
obj-$(CONFIG_ARCH_REALVIEW) += irq-gic-realview.o
obj-$(CONFIG_ARM_GIC_V2M) += irq-gic-v2m.o
obj-$(CONFIG_ARM_GIC_V3) += irq-gic-v3.o irq-gic-common.o
-obj-$(CONFIG_ARM_GIC_V3_ITS) += irq-gic-v3-its.o irq-gic-v3-its-pci-msi.o irq-gic-v3-its-platform-msi.o
+obj-$(CONFIG_ARM_GIC_V3_ITS) += irq-gic-v3-its.o irq-gic-v3-its-pci-msi.o irq-gic-v3-its-platform-msi.o irq-gic-v4.o
obj-$(CONFIG_PARTITION_PERCPU) += irq-partition-percpu.o
obj-$(CONFIG_HISILICON_IRQ_MBIGEN) += irq-mbigen.o
obj-$(CONFIG_ARM_NVIC) += irq-nvic.o
@@ -78,3 +78,4 @@ obj-$(CONFIG_EZNPS_GIC) += irq-eznps.o
obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-vic.o irq-aspeed-i2c-ic.o
obj-$(CONFIG_STM32_EXTI) += irq-stm32-exti.o
obj-$(CONFIG_QCOM_IRQ_COMBINER) += qcom-irq-combiner.o
+obj-$(CONFIG_IRQ_UNIPHIER_AIDET) += irq-uniphier-aidet.o
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c
index b207b2c..c9bdc52 100644
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -203,7 +203,7 @@ static struct irq_chip armada_370_xp_msi_irq_chip = {
static struct msi_domain_info armada_370_xp_msi_domain_info = {
.flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
- MSI_FLAG_MULTI_PCI_MSI),
+ MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX),
.chip = &armada_370_xp_msi_irq_chip,
};
@@ -330,6 +330,8 @@ static int armada_xp_set_affinity(struct irq_data *d,
writel(reg, main_int_base + ARMADA_370_XP_INT_SOURCE_CTL(hwirq));
raw_spin_unlock(&irq_controller_lock);
+ irq_data_update_effective_affinity(d, cpumask_of(cpu));
+
return IRQ_SET_MASK_OK;
}
#endif
@@ -363,6 +365,7 @@ static int armada_370_xp_mpic_irq_map(struct irq_domain *h,
} else {
irq_set_chip_and_handler(virq, &armada_370_xp_irq_chip,
handle_level_irq);
+ irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(virq)));
}
irq_set_probe(virq);
diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c
index 44d7c38..d2da8a1 100644
--- a/drivers/irqchip/irq-bcm2835.c
+++ b/drivers/irqchip/irq-bcm2835.c
@@ -147,13 +147,12 @@ static int __init armctrl_of_init(struct device_node *node,
base = of_iomap(node, 0);
if (!base)
- panic("%s: unable to map IC registers\n",
- node->full_name);
+ panic("%pOF: unable to map IC registers\n", node);
intc.domain = irq_domain_add_linear(node, MAKE_HWIRQ(NR_BANKS, 0),
&armctrl_ops, NULL);
if (!intc.domain)
- panic("%s: unable to create IRQ domain\n", node->full_name);
+ panic("%pOF: unable to create IRQ domain\n", node);
for (b = 0; b < NR_BANKS; b++) {
intc.pending[b] = base + reg_pending[b];
@@ -173,8 +172,8 @@ static int __init armctrl_of_init(struct device_node *node,
int parent_irq = irq_of_parse_and_map(node, 0);
if (!parent_irq) {
- panic("%s: unable to get parent interrupt.\n",
- node->full_name);
+ panic("%pOF: unable to get parent interrupt.\n",
+ node);
}
irq_set_chained_handler(parent_irq, bcm2836_chained_handle_irq);
} else {
diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c
index e7463e3..dc8c1e3 100644
--- a/drivers/irqchip/irq-bcm2836.c
+++ b/drivers/irqchip/irq-bcm2836.c
@@ -282,8 +282,7 @@ static int __init bcm2836_arm_irqchip_l1_intc_of_init(struct device_node *node,
{
intc.base = of_iomap(node, 0);
if (!intc.base) {
- panic("%s: unable to map local interrupt registers\n",
- node->full_name);
+ panic("%pOF: unable to map local interrupt registers\n", node);
}
bcm2835_init_local_timer_frequency();
@@ -292,7 +291,7 @@ static int __init bcm2836_arm_irqchip_l1_intc_of_init(struct device_node *node,
&bcm2836_arm_irqchip_intc_ops,
NULL);
if (!intc.domain)
- panic("%s: unable to create IRQ domain\n", node->full_name);
+ panic("%pOF: unable to create IRQ domain\n", node);
bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_CNTPSIRQ,
&bcm2836_arm_irqchip_timer);
diff --git a/drivers/irqchip/irq-bcm6345-l1.c b/drivers/irqchip/irq-bcm6345-l1.c
index daa4ae8..43f8abe 100644
--- a/drivers/irqchip/irq-bcm6345-l1.c
+++ b/drivers/irqchip/irq-bcm6345-l1.c
@@ -231,6 +231,8 @@ static int bcm6345_l1_set_affinity(struct irq_data *d,
}
raw_spin_unlock_irqrestore(&intc->lock, flags);
+ irq_data_update_effective_affinity(d, cpumask_of(new_cpu));
+
return IRQ_SET_MASK_OK_NOCOPY;
}
@@ -291,6 +293,7 @@ static int bcm6345_l1_map(struct irq_domain *d, unsigned int virq,
irq_set_chip_and_handler(virq,
&bcm6345_l1_irq_chip, handle_percpu_irq);
irq_set_chip_data(virq, d->host_data);
+ irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(virq)));
return 0;
}
diff --git a/drivers/irqchip/irq-bcm7038-l1.c b/drivers/irqchip/irq-bcm7038-l1.c
index c2662a1..55cfb98 100644
--- a/drivers/irqchip/irq-bcm7038-l1.c
+++ b/drivers/irqchip/irq-bcm7038-l1.c
@@ -212,6 +212,8 @@ static int bcm7038_l1_set_affinity(struct irq_data *d,
__bcm7038_l1_unmask(d, first_cpu);
raw_spin_unlock_irqrestore(&intc->lock, flags);
+ irq_data_update_effective_affinity(d, cpumask_of(first_cpu));
+
return 0;
}
@@ -299,6 +301,7 @@ static int bcm7038_l1_map(struct irq_domain *d, unsigned int virq,
{
irq_set_chip_and_handler(virq, &bcm7038_l1_irq_chip, handle_level_irq);
irq_set_chip_data(virq, d->host_data);
+ irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(virq)));
return 0;
}
diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120-l2.c
index 64c2692..983640e 100644
--- a/drivers/irqchip/irq-bcm7120-l2.c
+++ b/drivers/irqchip/irq-bcm7120-l2.c
@@ -250,12 +250,6 @@ static int __init bcm7120_l2_intc_probe(struct device_node *dn,
if (ret < 0)
goto out_free_l1_data;
- for (idx = 0; idx < data->n_words; idx++) {
- __raw_writel(data->irq_fwd_mask[idx],
- data->pair_base[idx] +
- data->en_offset[idx]);
- }
-
for (irq = 0; irq < data->num_parent_irqs; irq++) {
ret = bcm7120_l2_intc_init_one(dn, data, irq, valid_mask);
if (ret)
@@ -297,6 +291,10 @@ static int __init bcm7120_l2_intc_probe(struct device_node *dn,
gc->reg_base = data->pair_base[idx];
ct->regs.mask = data->en_offset[idx];
+ /* gc->reg_base is defined and so is gc->writel */
+ irq_reg_writel(gc, data->irq_fwd_mask[idx],
+ data->en_offset[idx]);
+
ct->chip.irq_mask = irq_gc_mask_clr_bit;
ct->chip.irq_unmask = irq_gc_mask_set_bit;
ct->chip.irq_ack = irq_gc_noop;
diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c
index f966012..99d97d7 100644
--- a/drivers/irqchip/irq-crossbar.c
+++ b/drivers/irqchip/irq-crossbar.c
@@ -341,13 +341,13 @@ static int __init irqcrossbar_init(struct device_node *node,
int err;
if (!parent) {
- pr_err("%s: no parent, giving up\n", node->full_name);
+ pr_err("%pOF: no parent, giving up\n", node);
return -ENODEV;
}
parent_domain = irq_find_host(parent);
if (!parent_domain) {
- pr_err("%s: unable to obtain parent domain\n", node->full_name);
+ pr_err("%pOF: unable to obtain parent domain\n", node);
return -ENXIO;
}
@@ -360,7 +360,7 @@ static int __init irqcrossbar_init(struct device_node *node,
node, &crossbar_domain_ops,
NULL);
if (!domain) {
- pr_err("%s: failed to allocated domain\n", node->full_name);
+ pr_err("%pOF: failed to allocated domain\n", node);
return -ENOMEM;
}
diff --git a/drivers/irqchip/irq-digicolor.c b/drivers/irqchip/irq-digicolor.c
index 3aae015..fc38d2d 100644
--- a/drivers/irqchip/irq-digicolor.c
+++ b/drivers/irqchip/irq-digicolor.c
@@ -78,7 +78,7 @@ static int __init digicolor_of_init(struct device_node *node,
reg_base = of_iomap(node, 0);
if (!reg_base) {
- pr_err("%s: unable to map IC registers\n", node->full_name);
+ pr_err("%pOF: unable to map IC registers\n", node);
return -ENXIO;
}
@@ -88,7 +88,7 @@ static int __init digicolor_of_init(struct device_node *node,
ucregs = syscon_regmap_lookup_by_phandle(node, "syscon");
if (IS_ERR(ucregs)) {
- pr_err("%s: unable to map UC registers\n", node->full_name);
+ pr_err("%pOF: unable to map UC registers\n", node);
return PTR_ERR(ucregs);
}
/* channel 1, regular IRQs */
@@ -97,7 +97,7 @@ static int __init digicolor_of_init(struct device_node *node,
digicolor_irq_domain =
irq_domain_add_linear(node, 64, &irq_generic_chip_ops, NULL);
if (!digicolor_irq_domain) {
- pr_err("%s: unable to create IRQ domain\n", node->full_name);
+ pr_err("%pOF: unable to create IRQ domain\n", node);
return -ENOMEM;
}
@@ -105,7 +105,7 @@ static int __init digicolor_of_init(struct device_node *node,
"digicolor_irq", handle_level_irq,
clr, 0, 0);
if (ret) {
- pr_err("%s: unable to allocate IRQ gc\n", node->full_name);
+ pr_err("%pOF: unable to allocate IRQ gc\n", node);
return ret;
}
diff --git a/drivers/irqchip/irq-dw-apb-ictl.c b/drivers/irqchip/irq-dw-apb-ictl.c
index 052f266..0a19618 100644
--- a/drivers/irqchip/irq-dw-apb-ictl.c
+++ b/drivers/irqchip/irq-dw-apb-ictl.c
@@ -79,24 +79,24 @@ static int __init dw_apb_ictl_init(struct device_node *np,
/* Map the parent interrupt for the chained handler */
irq = irq_of_parse_and_map(np, 0);
if (irq <= 0) {
- pr_err("%s: unable to parse irq\n", np->full_name);
+ pr_err("%pOF: unable to parse irq\n", np);
return -EINVAL;
}
ret = of_address_to_resource(np, 0, &r);
if (ret) {
- pr_err("%s: unable to get resource\n", np->full_name);
+ pr_err("%pOF: unable to get resource\n", np);
return ret;
}
if (!request_mem_region(r.start, resource_size(&r), np->full_name)) {
- pr_err("%s: unable to request mem region\n", np->full_name);
+ pr_err("%pOF: unable to request mem region\n", np);
return -ENOMEM;
}
iobase = ioremap(r.start, resource_size(&r));
if (!iobase) {
- pr_err("%s: unable to map resource\n", np->full_name);
+ pr_err("%pOF: unable to map resource\n", np);
ret = -ENOMEM;
goto err_release;
}
@@ -123,7 +123,7 @@ static int __init dw_apb_ictl_init(struct device_node *np,
domain = irq_domain_add_linear(np, nrirqs,
&irq_generic_chip_ops, NULL);
if (!domain) {
- pr_err("%s: unable to add irq domain\n", np->full_name);
+ pr_err("%pOF: unable to add irq domain\n", np);
ret = -ENOMEM;
goto err_unmap;
}
@@ -132,7 +132,7 @@ static int __init dw_apb_ictl_init(struct device_node *np,
handle_level_irq, clr, 0,
IRQ_GC_INIT_MASK_CACHE);
if (ret) {
- pr_err("%s: unable to alloc irq domain gc\n", np->full_name);
+ pr_err("%pOF: unable to alloc irq domain gc\n", np);
goto err_unmap;
}
diff --git a/drivers/irqchip/irq-gic-v3-its-pci-msi.c b/drivers/irqchip/irq-gic-v3-its-pci-msi.c
index 7793121..14a8c0a 100644
--- a/drivers/irqchip/irq-gic-v3-its-pci-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-pci-msi.c
@@ -138,7 +138,7 @@ static int __init its_pci_of_msi_init(void)
if (its_pci_msi_init_one(of_node_to_fwnode(np), np->full_name))
continue;
- pr_info("PCI/MSI: %s domain created\n", np->full_name);
+ pr_info("PCI/MSI: %pOF domain created\n", np);
}
return 0;
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 284738a..e8d8934 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013, 2014 ARM Limited, All Rights Reserved.
+ * Copyright (C) 2013-2017 ARM Limited, All Rights Reserved.
* Author: Marc Zyngier <marc.zyngier@arm.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -36,6 +36,7 @@
#include <linux/irqchip.h>
#include <linux/irqchip/arm-gic-v3.h>
+#include <linux/irqchip/arm-gic-v4.h>
#include <asm/cputype.h>
#include <asm/exception.h>
@@ -48,6 +49,19 @@
#define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0)
+static u32 lpi_id_bits;
+
+/*
+ * We allocate memory for PROPBASE to cover 2 ^ lpi_id_bits LPIs to
+ * deal with (one configuration byte per interrupt). PENDBASE has to
+ * be 64kB aligned (one bit per LPI, plus 8192 bits for SPI/PPI/SGI).
+ */
+#define LPI_NRBITS lpi_id_bits
+#define LPI_PROPBASE_SZ ALIGN(BIT(LPI_NRBITS), SZ_64K)
+#define LPI_PENDBASE_SZ ALIGN(BIT(LPI_NRBITS) / 8, SZ_64K)
+
+#define LPI_PROP_DEFAULT_PRIO 0xa0
+
/*
* Collection structure - just an ID, and a redistributor address to
* ping. We use one per CPU as a bag of interrupts assigned to this
@@ -88,6 +102,7 @@ struct its_node {
u32 ite_size;
u32 device_ids;
int numa_node;
+ bool is_v4;
};
#define ITS_ITT_ALIGN SZ_256
@@ -100,11 +115,17 @@ struct event_lpi_map {
u16 *col_map;
irq_hw_number_t lpi_base;
int nr_lpis;
+ struct mutex vlpi_lock;
+ struct its_vm *vm;
+ struct its_vlpi_map *vlpi_maps;
+ int nr_vlpis;
};
/*
- * The ITS view of a device - belongs to an ITS, a collection, owns an
- * interrupt translation table, and a list of interrupts.
+ * The ITS view of a device - belongs to an ITS, owns an interrupt
+ * translation table, and a list of interrupts. If it some of its
+ * LPIs are injected into a guest (GICv4), the event_map.vm field
+ * indicates which one.
*/
struct its_device {
struct list_head entry;
@@ -115,13 +136,33 @@ struct its_device {
u32 device_id;
};
+static struct {
+ raw_spinlock_t lock;
+ struct its_device *dev;
+ struct its_vpe **vpes;
+ int next_victim;
+} vpe_proxy;
+
static LIST_HEAD(its_nodes);
static DEFINE_SPINLOCK(its_lock);
static struct rdists *gic_rdists;
static struct irq_domain *its_parent;
+/*
+ * We have a maximum number of 16 ITSs in the whole system if we're
+ * using the ITSList mechanism
+ */
+#define ITS_LIST_MAX 16
+
+static unsigned long its_list_map;
+static u16 vmovp_seq_num;
+static DEFINE_RAW_SPINLOCK(vmovp_lock);
+
+static DEFINE_IDA(its_vpeid_ida);
+
#define gic_data_rdist() (raw_cpu_ptr(gic_rdists->rdist))
#define gic_data_rdist_rd_base() (gic_data_rdist()->rd_base)
+#define gic_data_rdist_vlpi_base() (gic_data_rdist_rd_base() + SZ_128K)
static struct its_collection *dev_event_to_col(struct its_device *its_dev,
u32 event)
@@ -145,6 +186,11 @@ struct its_cmd_desc {
struct {
struct its_device *dev;
u32 event_id;
+ } its_clear_cmd;
+
+ struct {
+ struct its_device *dev;
+ u32 event_id;
} its_int_cmd;
struct {
@@ -177,6 +223,38 @@ struct its_cmd_desc {
struct {
struct its_collection *col;
} its_invall_cmd;
+
+ struct {
+ struct its_vpe *vpe;
+ } its_vinvall_cmd;
+
+ struct {
+ struct its_vpe *vpe;
+ struct its_collection *col;
+ bool valid;
+ } its_vmapp_cmd;
+
+ struct {
+ struct its_vpe *vpe;
+ struct its_device *dev;
+ u32 virt_id;
+ u32 event_id;
+ bool db_enabled;
+ } its_vmapti_cmd;
+
+ struct {
+ struct its_vpe *vpe;
+ struct its_device *dev;
+ u32 event_id;
+ bool db_enabled;
+ } its_vmovi_cmd;
+
+ struct {
+ struct its_vpe *vpe;
+ struct its_collection *col;
+ u16 seq_num;
+ u16 its_list;
+ } its_vmovp_cmd;
};
};
@@ -193,6 +271,9 @@ struct its_cmd_block {
typedef struct its_collection *(*its_cmd_builder_t)(struct its_cmd_block *,
struct its_cmd_desc *);
+typedef struct its_vpe *(*its_cmd_vbuilder_t)(struct its_cmd_block *,
+ struct its_cmd_desc *);
+
static void its_mask_encode(u64 *raw_cmd, u64 val, int h, int l)
{
u64 mask = GENMASK_ULL(h, l);
@@ -245,6 +326,46 @@ static void its_encode_collection(struct its_cmd_block *cmd, u16 col)
its_mask_encode(&cmd->raw_cmd[2], col, 15, 0);
}
+static void its_encode_vpeid(struct its_cmd_block *cmd, u16 vpeid)
+{
+ its_mask_encode(&cmd->raw_cmd[1], vpeid, 47, 32);
+}
+
+static void its_encode_virt_id(struct its_cmd_block *cmd, u32 virt_id)
+{
+ its_mask_encode(&cmd->raw_cmd[2], virt_id, 31, 0);
+}
+
+static void its_encode_db_phys_id(struct its_cmd_block *cmd, u32 db_phys_id)
+{
+ its_mask_encode(&cmd->raw_cmd[2], db_phys_id, 63, 32);
+}
+
+static void its_encode_db_valid(struct its_cmd_block *cmd, bool db_valid)
+{
+ its_mask_encode(&cmd->raw_cmd[2], db_valid, 0, 0);
+}
+
+static void its_encode_seq_num(struct its_cmd_block *cmd, u16 seq_num)
+{
+ its_mask_encode(&cmd->raw_cmd[0], seq_num, 47, 32);
+}
+
+static void its_encode_its_list(struct its_cmd_block *cmd, u16 its_list)
+{
+ its_mask_encode(&cmd->raw_cmd[1], its_list, 15, 0);
+}
+
+static void its_encode_vpt_addr(struct its_cmd_block *cmd, u64 vpt_pa)
+{
+ its_mask_encode(&cmd->raw_cmd[3], vpt_pa >> 16, 50, 16);
+}
+
+static void its_encode_vpt_size(struct its_cmd_block *cmd, u8 vpt_size)
+{
+ its_mask_encode(&cmd->raw_cmd[3], vpt_size, 4, 0);
+}
+
static inline void its_fixup_cmd(struct its_cmd_block *cmd)
{
/* Let's fixup BE commands */
@@ -358,6 +479,40 @@ static struct its_collection *its_build_inv_cmd(struct its_cmd_block *cmd,
return col;
}
+static struct its_collection *its_build_int_cmd(struct its_cmd_block *cmd,
+ struct its_cmd_desc *desc)
+{
+ struct its_collection *col;
+
+ col = dev_event_to_col(desc->its_int_cmd.dev,
+ desc->its_int_cmd.event_id);
+
+ its_encode_cmd(cmd, GITS_CMD_INT);
+ its_encode_devid(cmd, desc->its_int_cmd.dev->device_id);
+ its_encode_event_id(cmd, desc->its_int_cmd.event_id);
+
+ its_fixup_cmd(cmd);
+
+ return col;
+}
+
+static struct its_collection *its_build_clear_cmd(struct its_cmd_block *cmd,
+ struct its_cmd_desc *desc)
+{
+ struct its_collection *col;
+
+ col = dev_event_to_col(desc->its_clear_cmd.dev,
+ desc->its_clear_cmd.event_id);
+
+ its_encode_cmd(cmd, GITS_CMD_CLEAR);
+ its_encode_devid(cmd, desc->its_clear_cmd.dev->device_id);
+ its_encode_event_id(cmd, desc->its_clear_cmd.event_id);
+
+ its_fixup_cmd(cmd);
+
+ return col;
+}
+
static struct its_collection *its_build_invall_cmd(struct its_cmd_block *cmd,
struct its_cmd_desc *desc)
{
@@ -369,6 +524,94 @@ static struct its_collection *its_build_invall_cmd(struct its_cmd_block *cmd,
return NULL;
}
+static struct its_vpe *its_build_vinvall_cmd(struct its_cmd_block *cmd,
+ struct its_cmd_desc *desc)
+{
+ its_encode_cmd(cmd, GITS_CMD_VINVALL);
+ its_encode_vpeid(cmd, desc->its_vinvall_cmd.vpe->vpe_id);
+
+ its_fixup_cmd(cmd);
+
+ return desc->its_vinvall_cmd.vpe;
+}
+
+static struct its_vpe *its_build_vmapp_cmd(struct its_cmd_block *cmd,
+ struct its_cmd_desc *desc)
+{
+ unsigned long vpt_addr;
+
+ vpt_addr = virt_to_phys(page_address(desc->its_vmapp_cmd.vpe->vpt_page));
+
+ its_encode_cmd(cmd, GITS_CMD_VMAPP);
+ its_encode_vpeid(cmd, desc->its_vmapp_cmd.vpe->vpe_id);
+ its_encode_valid(cmd, desc->its_vmapp_cmd.valid);
+ its_encode_target(cmd, desc->its_vmapp_cmd.col->target_address);
+ its_encode_vpt_addr(cmd, vpt_addr);
+ its_encode_vpt_size(cmd, LPI_NRBITS - 1);
+
+ its_fixup_cmd(cmd);
+
+ return desc->its_vmapp_cmd.vpe;
+}
+
+static struct its_vpe *its_build_vmapti_cmd(struct its_cmd_block *cmd,
+ struct its_cmd_desc *desc)
+{
+ u32 db;
+
+ if (desc->its_vmapti_cmd.db_enabled)
+ db = desc->its_vmapti_cmd.vpe->vpe_db_lpi;
+ else
+ db = 1023;
+
+ its_encode_cmd(cmd, GITS_CMD_VMAPTI);
+ its_encode_devid(cmd, desc->its_vmapti_cmd.dev->device_id);
+ its_encode_vpeid(cmd, desc->its_vmapti_cmd.vpe->vpe_id);
+ its_encode_event_id(cmd, desc->its_vmapti_cmd.event_id);
+ its_encode_db_phys_id(cmd, db);
+ its_encode_virt_id(cmd, desc->its_vmapti_cmd.virt_id);
+
+ its_fixup_cmd(cmd);
+
+ return desc->its_vmapti_cmd.vpe;
+}
+
+static struct its_vpe *its_build_vmovi_cmd(struct its_cmd_block *cmd,
+ struct its_cmd_desc *desc)
+{
+ u32 db;
+
+ if (desc->its_vmovi_cmd.db_enabled)
+ db = desc->its_vmovi_cmd.vpe->vpe_db_lpi;
+ else
+ db = 1023;
+
+ its_encode_cmd(cmd, GITS_CMD_VMOVI);
+ its_encode_devid(cmd, desc->its_vmovi_cmd.dev->device_id);
+ its_encode_vpeid(cmd, desc->its_vmovi_cmd.vpe->vpe_id);
+ its_encode_event_id(cmd, desc->its_vmovi_cmd.event_id);
+ its_encode_db_phys_id(cmd, db);
+ its_encode_db_valid(cmd, true);
+
+ its_fixup_cmd(cmd);
+
+ return desc->its_vmovi_cmd.vpe;
+}
+
+static struct its_vpe *its_build_vmovp_cmd(struct its_cmd_block *cmd,
+ struct its_cmd_desc *desc)
+{
+ its_encode_cmd(cmd, GITS_CMD_VMOVP);
+ its_encode_seq_num(cmd, desc->its_vmovp_cmd.seq_num);
+ its_encode_its_list(cmd, desc->its_vmovp_cmd.its_list);
+ its_encode_vpeid(cmd, desc->its_vmovp_cmd.vpe->vpe_id);
+ its_encode_target(cmd, desc->its_vmovp_cmd.col->target_address);
+
+ its_fixup_cmd(cmd);
+
+ return desc->its_vmovp_cmd.vpe;
+}
+
static u64 its_cmd_ptr_to_offset(struct its_node *its,
struct its_cmd_block *ptr)
{
@@ -453,7 +696,13 @@ static void its_wait_for_range_completion(struct its_node *its,
while (1) {
rd_idx = readl_relaxed(its->base + GITS_CREADR);
- if (rd_idx >= to_idx || rd_idx < from_idx)
+
+ /* Direct case */
+ if (from_idx < to_idx && rd_idx >= to_idx)
+ break;
+
+ /* Wrapped case */
+ if (from_idx >= to_idx && rd_idx >= to_idx && rd_idx < from_idx)
break;
count--;
@@ -466,42 +715,84 @@ static void its_wait_for_range_completion(struct its_node *its,
}
}
-static void its_send_single_command(struct its_node *its,
- its_cmd_builder_t builder,
- struct its_cmd_desc *desc)
+/* Warning, macro hell follows */
+#define BUILD_SINGLE_CMD_FUNC(name, buildtype, synctype, buildfn) \
+void name(struct its_node *its, \
+ buildtype builder, \
+ struct its_cmd_desc *desc) \
+{ \
+ struct its_cmd_block *cmd, *sync_cmd, *next_cmd; \
+ synctype *sync_obj; \
+ unsigned long flags; \
+ \
+ raw_spin_lock_irqsave(&its->lock, flags); \
+ \
+ cmd = its_allocate_entry(its); \
+ if (!cmd) { /* We're soooooo screewed... */ \
+ raw_spin_unlock_irqrestore(&its->lock, flags); \
+ return; \
+ } \
+ sync_obj = builder(cmd, desc); \
+ its_flush_cmd(its, cmd); \
+ \
+ if (sync_obj) { \
+ sync_cmd = its_allocate_entry(its); \
+ if (!sync_cmd) \
+ goto post; \
+ \
+ buildfn(sync_cmd, sync_obj); \
+ its_flush_cmd(its, sync_cmd); \
+ } \
+ \
+post: \
+ next_cmd = its_post_commands(its); \
+ raw_spin_unlock_irqrestore(&its->lock, flags); \
+ \
+ its_wait_for_range_completion(its, cmd, next_cmd); \
+}
+
+static void its_build_sync_cmd(struct its_cmd_block *sync_cmd,
+ struct its_collection *sync_col)
+{
+ its_encode_cmd(sync_cmd, GITS_CMD_SYNC);
+ its_encode_target(sync_cmd, sync_col->target_address);
+
+ its_fixup_cmd(sync_cmd);
+}
+
+static BUILD_SINGLE_CMD_FUNC(its_send_single_command, its_cmd_builder_t,
+ struct its_collection, its_build_sync_cmd)
+
+static void its_build_vsync_cmd(struct its_cmd_block *sync_cmd,
+ struct its_vpe *sync_vpe)
+{
+ its_encode_cmd(sync_cmd, GITS_CMD_VSYNC);
+ its_encode_vpeid(sync_cmd, sync_vpe->vpe_id);
+
+ its_fixup_cmd(sync_cmd);
+}
+
+static BUILD_SINGLE_CMD_FUNC(its_send_single_vcommand, its_cmd_vbuilder_t,
+ struct its_vpe, its_build_vsync_cmd)
+
+static void its_send_int(struct its_device *dev, u32 event_id)
{
- struct its_cmd_block *cmd, *sync_cmd, *next_cmd;
- struct its_collection *sync_col;
- unsigned long flags;
+ struct its_cmd_desc desc;
- raw_spin_lock_irqsave(&its->lock, flags);
+ desc.its_int_cmd.dev = dev;
+ desc.its_int_cmd.event_id = event_id;
- cmd = its_allocate_entry(its);
- if (!cmd) { /* We're soooooo screewed... */
- pr_err_ratelimited("ITS can't allocate, dropping command\n");
- raw_spin_unlock_irqrestore(&its->lock, flags);
- return;
- }
- sync_col = builder(cmd, desc);
- its_flush_cmd(its, cmd);
+ its_send_single_command(dev->its, its_build_int_cmd, &desc);
+}
- if (sync_col) {
- sync_cmd = its_allocate_entry(its);
- if (!sync_cmd) {
- pr_err_ratelimited("ITS can't SYNC, skipping\n");
- goto post;
- }
- its_encode_cmd(sync_cmd, GITS_CMD_SYNC);
- its_encode_target(sync_cmd, sync_col->target_address);
- its_fixup_cmd(sync_cmd);
- its_flush_cmd(its, sync_cmd);
- }
+static void its_send_clear(struct its_device *dev, u32 event_id)
+{
+ struct its_cmd_desc desc;
-post:
- next_cmd = its_post_commands(its);
- raw_spin_unlock_irqrestore(&its->lock, flags);
+ desc.its_clear_cmd.dev = dev;
+ desc.its_clear_cmd.event_id = event_id;
- its_wait_for_range_completion(its, cmd, next_cmd);
+ its_send_single_command(dev->its, its_build_clear_cmd, &desc);
}
static void its_send_inv(struct its_device *dev, u32 event_id)
@@ -577,6 +868,106 @@ static void its_send_invall(struct its_node *its, struct its_collection *col)
its_send_single_command(its, its_build_invall_cmd, &desc);
}
+static void its_send_vmapti(struct its_device *dev, u32 id)
+{
+ struct its_vlpi_map *map = &dev->event_map.vlpi_maps[id];
+ struct its_cmd_desc desc;
+
+ desc.its_vmapti_cmd.vpe = map->vpe;
+ desc.its_vmapti_cmd.dev = dev;
+ desc.its_vmapti_cmd.virt_id = map->vintid;
+ desc.its_vmapti_cmd.event_id = id;
+ desc.its_vmapti_cmd.db_enabled = map->db_enabled;
+
+ its_send_single_vcommand(dev->its, its_build_vmapti_cmd, &desc);
+}
+
+static void its_send_vmovi(struct its_device *dev, u32 id)
+{
+ struct its_vlpi_map *map = &dev->event_map.vlpi_maps[id];
+ struct its_cmd_desc desc;
+
+ desc.its_vmovi_cmd.vpe = map->vpe;
+ desc.its_vmovi_cmd.dev = dev;
+ desc.its_vmovi_cmd.event_id = id;
+ desc.its_vmovi_cmd.db_enabled = map->db_enabled;
+
+ its_send_single_vcommand(dev->its, its_build_vmovi_cmd, &desc);
+}
+
+static void its_send_vmapp(struct its_vpe *vpe, bool valid)
+{
+ struct its_cmd_desc desc;
+ struct its_node *its;
+
+ desc.its_vmapp_cmd.vpe = vpe;
+ desc.its_vmapp_cmd.valid = valid;
+
+ list_for_each_entry(its, &its_nodes, entry) {
+ if (!its->is_v4)
+ continue;
+
+ desc.its_vmapp_cmd.col = &its->collections[vpe->col_idx];
+ its_send_single_vcommand(its, its_build_vmapp_cmd, &desc);
+ }
+}
+
+static void its_send_vmovp(struct its_vpe *vpe)
+{
+ struct its_cmd_desc desc;
+ struct its_node *its;
+ unsigned long flags;
+ int col_id = vpe->col_idx;
+
+ desc.its_vmovp_cmd.vpe = vpe;
+ desc.its_vmovp_cmd.its_list = (u16)its_list_map;
+
+ if (!its_list_map) {
+ its = list_first_entry(&its_nodes, struct its_node, entry);
+ desc.its_vmovp_cmd.seq_num = 0;
+ desc.its_vmovp_cmd.col = &its->collections[col_id];
+ its_send_single_vcommand(its, its_build_vmovp_cmd, &desc);
+ return;
+ }
+
+ /*
+ * Yet another marvel of the architecture. If using the
+ * its_list "feature", we need to make sure that all ITSs
+ * receive all VMOVP commands in the same order. The only way
+ * to guarantee this is to make vmovp a serialization point.
+ *
+ * Wall <-- Head.
+ */
+ raw_spin_lock_irqsave(&vmovp_lock, flags);
+
+ desc.its_vmovp_cmd.seq_num = vmovp_seq_num++;
+
+ /* Emit VMOVPs */
+ list_for_each_entry(its, &its_nodes, entry) {
+ if (!its->is_v4)
+ continue;
+
+ desc.its_vmovp_cmd.col = &its->collections[col_id];
+ its_send_single_vcommand(its, its_build_vmovp_cmd, &desc);
+ }
+
+ raw_spin_unlock_irqrestore(&vmovp_lock, flags);
+}
+
+static void its_send_vinvall(struct its_vpe *vpe)
+{
+ struct its_cmd_desc desc;
+ struct its_node *its;
+
+ desc.its_vinvall_cmd.vpe = vpe;
+
+ list_for_each_entry(its, &its_nodes, entry) {
+ if (!its->is_v4)
+ continue;
+ its_send_single_vcommand(its, its_build_vinvall_cmd, &desc);
+ }
+}
+
/*
* irqchip functions - assumes MSI, mostly.
*/
@@ -587,17 +978,26 @@ static inline u32 its_get_event_id(struct irq_data *d)
return d->hwirq - its_dev->event_map.lpi_base;
}
-static void lpi_set_config(struct irq_data *d, bool enable)
+static void lpi_write_config(struct irq_data *d, u8 clr, u8 set)
{
- struct its_device *its_dev = irq_data_get_irq_chip_data(d);
- irq_hw_number_t hwirq = d->hwirq;
- u32 id = its_get_event_id(d);
- u8 *cfg = page_address(gic_rdists->prop_page) + hwirq - 8192;
+ irq_hw_number_t hwirq;
+ struct page *prop_page;
+ u8 *cfg;
- if (enable)
- *cfg |= LPI_PROP_ENABLED;
- else
- *cfg &= ~LPI_PROP_ENABLED;
+ if (irqd_is_forwarded_to_vcpu(d)) {
+ struct its_device *its_dev = irq_data_get_irq_chip_data(d);
+ u32 event = its_get_event_id(d);
+
+ prop_page = its_dev->event_map.vm->vprop_page;
+ hwirq = its_dev->event_map.vlpi_maps[event].vintid;
+ } else {
+ prop_page = gic_rdists->prop_page;
+ hwirq = d->hwirq;
+ }
+
+ cfg = page_address(prop_page) + hwirq - 8192;
+ *cfg &= ~clr;
+ *cfg |= set | LPI_PROP_GROUP1;
/*
* Make the above write visible to the redistributors.
@@ -608,17 +1008,53 @@ static void lpi_set_config(struct irq_data *d, bool enable)
gic_flush_dcache_to_poc(cfg, sizeof(*cfg));
else
dsb(ishst);
- its_send_inv(its_dev, id);
+}
+
+static void lpi_update_config(struct irq_data *d, u8 clr, u8 set)
+{
+ struct its_device *its_dev = irq_data_get_irq_chip_data(d);
+
+ lpi_write_config(d, clr, set);
+ its_send_inv(its_dev, its_get_event_id(d));
+}
+
+static void its_vlpi_set_doorbell(struct irq_data *d, bool enable)
+{
+ struct its_device *its_dev = irq_data_get_irq_chip_data(d);
+ u32 event = its_get_event_id(d);
+
+ if (its_dev->event_map.vlpi_maps[event].db_enabled == enable)
+ return;
+
+ its_dev->event_map.vlpi_maps[event].db_enabled = enable;
+
+ /*
+ * More fun with the architecture:
+ *
+ * Ideally, we'd issue a VMAPTI to set the doorbell to its LPI
+ * value or to 1023, depending on the enable bit. But that
+ * would be issueing a mapping for an /existing/ DevID+EventID
+ * pair, which is UNPREDICTABLE. Instead, let's issue a VMOVI
+ * to the /same/ vPE, using this opportunity to adjust the
+ * doorbell. Mouahahahaha. We loves it, Precious.
+ */
+ its_send_vmovi(its_dev, event);
}
static void its_mask_irq(struct irq_data *d)
{
- lpi_set_config(d, false);
+ if (irqd_is_forwarded_to_vcpu(d))
+ its_vlpi_set_doorbell(d, false);
+
+ lpi_update_config(d, LPI_PROP_ENABLED, 0);
}
static void its_unmask_irq(struct irq_data *d)
{
- lpi_set_config(d, true);
+ if (irqd_is_forwarded_to_vcpu(d))
+ its_vlpi_set_doorbell(d, true);
+
+ lpi_update_config(d, 0, LPI_PROP_ENABLED);
}
static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
@@ -630,6 +1066,10 @@ static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
struct its_collection *target_col;
u32 id = its_get_event_id(d);
+ /* A forwarded interrupt should use irq_set_vcpu_affinity */
+ if (irqd_is_forwarded_to_vcpu(d))
+ return -EINVAL;
+
/* lpi cannot be routed to a redistributor that is on a foreign node */
if (its_dev->its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_23144) {
if (its_dev->its->numa_node >= 0) {
@@ -649,6 +1089,7 @@ static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
target_col = &its_dev->its->collections[cpu];
its_send_movi(its_dev, target_col, id);
its_dev->event_map.col_map[id] = cpu;
+ irq_data_update_effective_affinity(d, cpumask_of(cpu));
}
return IRQ_SET_MASK_OK_DONE;
@@ -670,6 +1111,179 @@ static void its_irq_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)
iommu_dma_map_msi_msg(d->irq, msg);
}
+static int its_irq_set_irqchip_state(struct irq_data *d,
+ enum irqchip_irq_state which,
+ bool state)
+{
+ struct its_device *its_dev = irq_data_get_irq_chip_data(d);
+ u32 event = its_get_event_id(d);
+
+ if (which != IRQCHIP_STATE_PENDING)
+ return -EINVAL;
+
+ if (state)
+ its_send_int(its_dev, event);
+ else
+ its_send_clear(its_dev, event);
+
+ return 0;
+}
+
+static int its_vlpi_map(struct irq_data *d, struct its_cmd_info *info)
+{
+ struct its_device *its_dev = irq_data_get_irq_chip_data(d);
+ u32 event = its_get_event_id(d);
+ int ret = 0;
+
+ if (!info->map)
+ return -EINVAL;
+
+ mutex_lock(&its_dev->event_map.vlpi_lock);
+
+ if (!its_dev->event_map.vm) {
+ struct its_vlpi_map *maps;
+
+ maps = kzalloc(sizeof(*maps) * its_dev->event_map.nr_lpis,
+ GFP_KERNEL);
+ if (!maps) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ its_dev->event_map.vm = info->map->vm;
+ its_dev->event_map.vlpi_maps = maps;
+ } else if (its_dev->event_map.vm != info->map->vm) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* Get our private copy of the mapping information */
+ its_dev->event_map.vlpi_maps[event] = *info->map;
+
+ if (irqd_is_forwarded_to_vcpu(d)) {
+ /* Already mapped, move it around */
+ its_send_vmovi(its_dev, event);
+ } else {
+ /* Drop the physical mapping */
+ its_send_discard(its_dev, event);
+
+ /* and install the virtual one */
+ its_send_vmapti(its_dev, event);
+ irqd_set_forwarded_to_vcpu(d);
+
+ /* Increment the number of VLPIs */
+ its_dev->event_map.nr_vlpis++;
+ }
+
+out:
+ mutex_unlock(&its_dev->event_map.vlpi_lock);
+ return ret;
+}
+
+static int its_vlpi_get(struct irq_data *d, struct its_cmd_info *info)
+{
+ struct its_device *its_dev = irq_data_get_irq_chip_data(d);
+ u32 event = its_get_event_id(d);
+ int ret = 0;
+
+ mutex_lock(&its_dev->event_map.vlpi_lock);
+
+ if (!its_dev->event_map.vm ||
+ !its_dev->event_map.vlpi_maps[event].vm) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* Copy our mapping information to the incoming request */
+ *info->map = its_dev->event_map.vlpi_maps[event];
+
+out:
+ mutex_unlock(&its_dev->event_map.vlpi_lock);
+ return ret;
+}
+
+static int its_vlpi_unmap(struct irq_data *d)
+{
+ struct its_device *its_dev = irq_data_get_irq_chip_data(d);
+ u32 event = its_get_event_id(d);
+ int ret = 0;
+
+ mutex_lock(&its_dev->event_map.vlpi_lock);
+
+ if (!its_dev->event_map.vm || !irqd_is_forwarded_to_vcpu(d)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* Drop the virtual mapping */
+ its_send_discard(its_dev, event);
+
+ /* and restore the physical one */
+ irqd_clr_forwarded_to_vcpu(d);
+ its_send_mapti(its_dev, d->hwirq, event);
+ lpi_update_config(d, 0xff, (LPI_PROP_DEFAULT_PRIO |
+ LPI_PROP_ENABLED |
+ LPI_PROP_GROUP1));
+
+ /*
+ * Drop the refcount and make the device available again if
+ * this was the last VLPI.
+ */
+ if (!--its_dev->event_map.nr_vlpis) {
+ its_dev->event_map.vm = NULL;
+ kfree(its_dev->event_map.vlpi_maps);
+ }
+
+out:
+ mutex_unlock(&its_dev->event_map.vlpi_lock);
+ return ret;
+}
+
+static int its_vlpi_prop_update(struct irq_data *d, struct its_cmd_info *info)
+{
+ struct its_device *its_dev = irq_data_get_irq_chip_data(d);
+
+ if (!its_dev->event_map.vm || !irqd_is_forwarded_to_vcpu(d))
+ return -EINVAL;
+
+ if (info->cmd_type == PROP_UPDATE_AND_INV_VLPI)
+ lpi_update_config(d, 0xff, info->config);
+ else
+ lpi_write_config(d, 0xff, info->config);
+ its_vlpi_set_doorbell(d, !!(info->config & LPI_PROP_ENABLED));
+
+ return 0;
+}
+
+static int its_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
+{
+ struct its_device *its_dev = irq_data_get_irq_chip_data(d);
+ struct its_cmd_info *info = vcpu_info;
+
+ /* Need a v4 ITS */
+ if (!its_dev->its->is_v4)
+ return -EINVAL;
+
+ /* Unmap request? */
+ if (!info)
+ return its_vlpi_unmap(d);
+
+ switch (info->cmd_type) {
+ case MAP_VLPI:
+ return its_vlpi_map(d, info);
+
+ case GET_VLPI:
+ return its_vlpi_get(d, info);
+
+ case PROP_UPDATE_VLPI:
+ case PROP_UPDATE_AND_INV_VLPI:
+ return its_vlpi_prop_update(d, info);
+
+ default:
+ return -EINVAL;
+ }
+}
+
static struct irq_chip its_irq_chip = {
.name = "ITS",
.irq_mask = its_mask_irq,
@@ -677,6 +1291,8 @@ static struct irq_chip its_irq_chip = {
.irq_eoi = irq_chip_eoi_parent,
.irq_set_affinity = its_set_affinity,
.irq_compose_msi_msg = its_irq_compose_msi_msg,
+ .irq_set_irqchip_state = its_irq_set_irqchip_state,
+ .irq_set_vcpu_affinity = its_irq_set_vcpu_affinity,
};
/*
@@ -695,7 +1311,6 @@ static struct irq_chip its_irq_chip = {
static unsigned long *lpi_bitmap;
static u32 lpi_chunks;
-static u32 lpi_id_bits;
static DEFINE_SPINLOCK(lpi_lock);
static int its_lpi_to_chunk(int lpi)
@@ -766,16 +1381,15 @@ out:
return bitmap;
}
-static void its_lpi_free(struct event_lpi_map *map)
+static void its_lpi_free_chunks(unsigned long *bitmap, int base, int nr_ids)
{
- int base = map->lpi_base;
- int nr_ids = map->nr_lpis;
int lpi;
spin_lock(&lpi_lock);
for (lpi = base; lpi < (base + nr_ids); lpi += IRQS_PER_CHUNK) {
int chunk = its_lpi_to_chunk(lpi);
+
BUG_ON(chunk > lpi_chunks);
if (test_bit(chunk, lpi_bitmap)) {
clear_bit(chunk, lpi_bitmap);
@@ -786,28 +1400,40 @@ static void its_lpi_free(struct event_lpi_map *map)
spin_unlock(&lpi_lock);
- kfree(map->lpi_map);
- kfree(map->col_map);
+ kfree(bitmap);
}
-/*
- * We allocate memory for PROPBASE to cover 2 ^ lpi_id_bits LPIs to
- * deal with (one configuration byte per interrupt). PENDBASE has to
- * be 64kB aligned (one bit per LPI, plus 8192 bits for SPI/PPI/SGI).
- */
-#define LPI_NRBITS lpi_id_bits
-#define LPI_PROPBASE_SZ ALIGN(BIT(LPI_NRBITS), SZ_64K)
-#define LPI_PENDBASE_SZ ALIGN(BIT(LPI_NRBITS) / 8, SZ_64K)
+static struct page *its_allocate_prop_table(gfp_t gfp_flags)
+{
+ struct page *prop_page;
-#define LPI_PROP_DEFAULT_PRIO 0xa0
+ prop_page = alloc_pages(gfp_flags, get_order(LPI_PROPBASE_SZ));
+ if (!prop_page)
+ return NULL;
+
+ /* Priority 0xa0, Group-1, disabled */
+ memset(page_address(prop_page),
+ LPI_PROP_DEFAULT_PRIO | LPI_PROP_GROUP1,
+ LPI_PROPBASE_SZ);
+
+ /* Make sure the GIC will observe the written configuration */
+ gic_flush_dcache_to_poc(page_address(prop_page), LPI_PROPBASE_SZ);
+
+ return prop_page;
+}
+
+static void its_free_prop_table(struct page *prop_page)
+{
+ free_pages((unsigned long)page_address(prop_page),
+ get_order(LPI_PROPBASE_SZ));
+}
static int __init its_alloc_lpi_tables(void)
{
phys_addr_t paddr;
lpi_id_bits = min_t(u32, gic_rdists->id_bits, ITS_MAX_LPI_NRBITS);
- gic_rdists->prop_page = alloc_pages(GFP_NOWAIT,
- get_order(LPI_PROPBASE_SZ));
+ gic_rdists->prop_page = its_allocate_prop_table(GFP_NOWAIT);
if (!gic_rdists->prop_page) {
pr_err("Failed to allocate PROPBASE\n");
return -ENOMEM;
@@ -816,14 +1442,6 @@ static int __init its_alloc_lpi_tables(void)
paddr = page_to_phys(gic_rdists->prop_page);
pr_info("GIC: using LPI property table @%pa\n", &paddr);
- /* Priority 0xa0, Group-1, disabled */
- memset(page_address(gic_rdists->prop_page),
- LPI_PROP_DEFAULT_PRIO | LPI_PROP_GROUP1,
- LPI_PROPBASE_SZ);
-
- /* Make sure the GIC will observe the written configuration */
- gic_flush_dcache_to_poc(page_address(gic_rdists->prop_page), LPI_PROPBASE_SZ);
-
return its_lpi_init(lpi_id_bits);
}
@@ -962,10 +1580,13 @@ retry_baser:
return 0;
}
-static bool its_parse_baser_device(struct its_node *its, struct its_baser *baser,
- u32 psz, u32 *order)
+static bool its_parse_indirect_baser(struct its_node *its,
+ struct its_baser *baser,
+ u32 psz, u32 *order)
{
- u64 esz = GITS_BASER_ENTRY_SIZE(its_read_baser(its, baser));
+ u64 tmp = its_read_baser(its, baser);
+ u64 type = GITS_BASER_TYPE(tmp);
+ u64 esz = GITS_BASER_ENTRY_SIZE(tmp);
u64 val = GITS_BASER_InnerShareable | GITS_BASER_RaWaWb;
u32 ids = its->device_ids;
u32 new_order = *order;
@@ -1004,8 +1625,9 @@ static bool its_parse_baser_device(struct its_node *its, struct its_baser *baser
if (new_order >= MAX_ORDER) {
new_order = MAX_ORDER - 1;
ids = ilog2(PAGE_ORDER_TO_SIZE(new_order) / (int)esz);
- pr_warn("ITS@%pa: Device Table too large, reduce ids %u->%u\n",
- &its->phys_base, its->device_ids, ids);
+ pr_warn("ITS@%pa: %s Table too large, reduce ids %u->%u\n",
+ &its->phys_base, its_base_type_string[type],
+ its->device_ids, ids);
}
*order = new_order;
@@ -1053,11 +1675,16 @@ static int its_alloc_tables(struct its_node *its)
u32 order = get_order(psz);
bool indirect = false;
- if (type == GITS_BASER_TYPE_NONE)
+ switch (type) {
+ case GITS_BASER_TYPE_NONE:
continue;
- if (type == GITS_BASER_TYPE_DEVICE)
- indirect = its_parse_baser_device(its, baser, psz, &order);
+ case GITS_BASER_TYPE_DEVICE:
+ case GITS_BASER_TYPE_VCPU:
+ indirect = its_parse_indirect_baser(its, baser,
+ psz, &order);
+ break;
+ }
err = its_setup_baser(its, baser, cache, shr, psz, order, indirect);
if (err < 0) {
@@ -1084,6 +1711,30 @@ static int its_alloc_collections(struct its_node *its)
return 0;
}
+static struct page *its_allocate_pending_table(gfp_t gfp_flags)
+{
+ struct page *pend_page;
+ /*
+ * The pending pages have to be at least 64kB aligned,
+ * hence the 'max(LPI_PENDBASE_SZ, SZ_64K)' below.
+ */
+ pend_page = alloc_pages(gfp_flags | __GFP_ZERO,
+ get_order(max_t(u32, LPI_PENDBASE_SZ, SZ_64K)));
+ if (!pend_page)
+ return NULL;
+
+ /* Make sure the GIC will observe the zero-ed page */
+ gic_flush_dcache_to_poc(page_address(pend_page), LPI_PENDBASE_SZ);
+
+ return pend_page;
+}
+
+static void its_free_pending_table(struct page *pt)
+{
+ free_pages((unsigned long)page_address(pt),
+ get_order(max_t(u32, LPI_PENDBASE_SZ, SZ_64K)));
+}
+
static void its_cpu_init_lpis(void)
{
void __iomem *rbase = gic_data_rdist_rd_base();
@@ -1094,21 +1745,14 @@ static void its_cpu_init_lpis(void)
pend_page = gic_data_rdist()->pend_page;
if (!pend_page) {
phys_addr_t paddr;
- /*
- * The pending pages have to be at least 64kB aligned,
- * hence the 'max(LPI_PENDBASE_SZ, SZ_64K)' below.
- */
- pend_page = alloc_pages(GFP_NOWAIT | __GFP_ZERO,
- get_order(max_t(u32, LPI_PENDBASE_SZ, SZ_64K)));
+
+ pend_page = its_allocate_pending_table(GFP_NOWAIT);
if (!pend_page) {
pr_err("Failed to allocate PENDBASE for CPU%d\n",
smp_processor_id());
return;
}
- /* Make sure the GIC will observe the zero-ed page */
- gic_flush_dcache_to_poc(page_address(pend_page), LPI_PENDBASE_SZ);
-
paddr = page_to_phys(pend_page);
pr_info("CPU%d: using LPI pending table @%pa\n",
smp_processor_id(), &paddr);
@@ -1259,26 +1903,19 @@ static struct its_baser *its_get_baser(struct its_node *its, u32 type)
return NULL;
}
-static bool its_alloc_device_table(struct its_node *its, u32 dev_id)
+static bool its_alloc_table_entry(struct its_baser *baser, u32 id)
{
- struct its_baser *baser;
struct page *page;
u32 esz, idx;
__le64 *table;
- baser = its_get_baser(its, GITS_BASER_TYPE_DEVICE);
-
- /* Don't allow device id that exceeds ITS hardware limit */
- if (!baser)
- return (ilog2(dev_id) < its->device_ids);
-
/* Don't allow device id that exceeds single, flat table limit */
esz = GITS_BASER_ENTRY_SIZE(baser->val);
if (!(baser->val & GITS_BASER_INDIRECT))
- return (dev_id < (PAGE_ORDER_TO_SIZE(baser->order) / esz));
+ return (id < (PAGE_ORDER_TO_SIZE(baser->order) / esz));
/* Compute 1st level table index & check if that exceeds table limit */
- idx = dev_id >> ilog2(baser->psz / esz);
+ idx = id >> ilog2(baser->psz / esz);
if (idx >= (PAGE_ORDER_TO_SIZE(baser->order) / GITS_LVL1_ENTRY_SIZE))
return false;
@@ -1307,11 +1944,52 @@ static bool its_alloc_device_table(struct its_node *its, u32 dev_id)
return true;
}
+static bool its_alloc_device_table(struct its_node *its, u32 dev_id)
+{
+ struct its_baser *baser;
+
+ baser = its_get_baser(its, GITS_BASER_TYPE_DEVICE);
+
+ /* Don't allow device id that exceeds ITS hardware limit */
+ if (!baser)
+ return (ilog2(dev_id) < its->device_ids);
+
+ return its_alloc_table_entry(baser, dev_id);
+}
+
+static bool its_alloc_vpe_table(u32 vpe_id)
+{
+ struct its_node *its;
+
+ /*
+ * Make sure the L2 tables are allocated on *all* v4 ITSs. We
+ * could try and only do it on ITSs corresponding to devices
+ * that have interrupts targeted at this VPE, but the
+ * complexity becomes crazy (and you have tons of memory
+ * anyway, right?).
+ */
+ list_for_each_entry(its, &its_nodes, entry) {
+ struct its_baser *baser;
+
+ if (!its->is_v4)
+ continue;
+
+ baser = its_get_baser(its, GITS_BASER_TYPE_VCPU);
+ if (!baser)
+ return false;
+
+ if (!its_alloc_table_entry(baser, vpe_id))
+ return false;
+ }
+
+ return true;
+}
+
static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
- int nvecs)
+ int nvecs, bool alloc_lpis)
{
struct its_device *dev;
- unsigned long *lpi_map;
+ unsigned long *lpi_map = NULL;
unsigned long flags;
u16 *col_map = NULL;
void *itt;
@@ -1333,11 +2011,18 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
sz = nr_ites * its->ite_size;
sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1;
itt = kzalloc(sz, GFP_KERNEL);
- lpi_map = its_lpi_alloc_chunks(nvecs, &lpi_base, &nr_lpis);
- if (lpi_map)
- col_map = kzalloc(sizeof(*col_map) * nr_lpis, GFP_KERNEL);
+ if (alloc_lpis) {
+ lpi_map = its_lpi_alloc_chunks(nvecs, &lpi_base, &nr_lpis);
+ if (lpi_map)
+ col_map = kzalloc(sizeof(*col_map) * nr_lpis,
+ GFP_KERNEL);
+ } else {
+ col_map = kzalloc(sizeof(*col_map) * nr_ites, GFP_KERNEL);
+ nr_lpis = 0;
+ lpi_base = 0;
+ }
- if (!dev || !itt || !lpi_map || !col_map) {
+ if (!dev || !itt || !col_map || (!lpi_map && alloc_lpis)) {
kfree(dev);
kfree(itt);
kfree(lpi_map);
@@ -1354,6 +2039,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
dev->event_map.col_map = col_map;
dev->event_map.lpi_base = lpi_base;
dev->event_map.nr_lpis = nr_lpis;
+ mutex_init(&dev->event_map.vlpi_lock);
dev->device_id = dev_id;
INIT_LIST_HEAD(&dev->entry);
@@ -1412,6 +2098,16 @@ static int its_msi_prepare(struct irq_domain *domain, struct device *dev,
msi_info = msi_get_domain_info(domain);
its = msi_info->data;
+ if (!gic_rdists->has_direct_lpi &&
+ vpe_proxy.dev &&
+ vpe_proxy.dev->its == its &&
+ dev_id == vpe_proxy.dev->device_id) {
+ /* Bad luck. Get yourself a better implementation */
+ WARN_ONCE(1, "DevId %x clashes with GICv4 VPE proxy device\n",
+ dev_id);
+ return -EINVAL;
+ }
+
its_dev = its_find_device(its, dev_id);
if (its_dev) {
/*
@@ -1423,7 +2119,7 @@ static int its_msi_prepare(struct irq_domain *domain, struct device *dev,
goto out;
}
- its_dev = its_create_device(its, dev_id, nvec);
+ its_dev = its_create_device(its, dev_id, nvec, true);
if (!its_dev)
return -ENOMEM;
@@ -1481,6 +2177,7 @@ static int its_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
irq_domain_set_hwirq_and_chip(domain, virq + i,
hwirq, &its_irq_chip, its_dev);
+ irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(virq + i)));
pr_debug("ID:%d pID:%d vID:%d\n",
(int)(hwirq - its_dev->event_map.lpi_base),
(int) hwirq, virq + i);
@@ -1495,13 +2192,16 @@ static void its_irq_domain_activate(struct irq_domain *domain,
struct its_device *its_dev = irq_data_get_irq_chip_data(d);
u32 event = its_get_event_id(d);
const struct cpumask *cpu_mask = cpu_online_mask;
+ int cpu;
/* get the cpu_mask of local node */
if (its_dev->its->numa_node >= 0)
cpu_mask = cpumask_of_node(its_dev->its->numa_node);
/* Bind the LPI to the first possible CPU */
- its_dev->event_map.col_map[event] = cpumask_first(cpu_mask);
+ cpu = cpumask_first(cpu_mask);
+ its_dev->event_map.col_map[event] = cpu;
+ irq_data_update_effective_affinity(d, cpumask_of(cpu));
/* Map the GIC IRQ and event to the device */
its_send_mapti(its_dev, d->hwirq, event);
@@ -1539,7 +2239,10 @@ static void its_irq_domain_free(struct irq_domain *domain, unsigned int virq,
/* If all interrupts have been freed, start mopping the floor */
if (bitmap_empty(its_dev->event_map.lpi_map,
its_dev->event_map.nr_lpis)) {
- its_lpi_free(&its_dev->event_map);
+ its_lpi_free_chunks(its_dev->event_map.lpi_map,
+ its_dev->event_map.lpi_base,
+ its_dev->event_map.nr_lpis);
+ kfree(its_dev->event_map.col_map);
/* Unmap device/itt */
its_send_mapd(its_dev, 0);
@@ -1556,6 +2259,451 @@ static const struct irq_domain_ops its_domain_ops = {
.deactivate = its_irq_domain_deactivate,
};
+/*
+ * This is insane.
+ *
+ * If a GICv4 doesn't implement Direct LPIs (which is extremely
+ * likely), the only way to perform an invalidate is to use a fake
+ * device to issue an INV command, implying that the LPI has first
+ * been mapped to some event on that device. Since this is not exactly
+ * cheap, we try to keep that mapping around as long as possible, and
+ * only issue an UNMAP if we're short on available slots.
+ *
+ * Broken by design(tm).
+ */
+static void its_vpe_db_proxy_unmap_locked(struct its_vpe *vpe)
+{
+ /* Already unmapped? */
+ if (vpe->vpe_proxy_event == -1)
+ return;
+
+ its_send_discard(vpe_proxy.dev, vpe->vpe_proxy_event);
+ vpe_proxy.vpes[vpe->vpe_proxy_event] = NULL;
+
+ /*
+ * We don't track empty slots at all, so let's move the
+ * next_victim pointer if we can quickly reuse that slot
+ * instead of nuking an existing entry. Not clear that this is
+ * always a win though, and this might just generate a ripple
+ * effect... Let's just hope VPEs don't migrate too often.
+ */
+ if (vpe_proxy.vpes[vpe_proxy.next_victim])
+ vpe_proxy.next_victim = vpe->vpe_proxy_event;
+
+ vpe->vpe_proxy_event = -1;
+}
+
+static void its_vpe_db_proxy_unmap(struct its_vpe *vpe)
+{
+ if (!gic_rdists->has_direct_lpi) {
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&vpe_proxy.lock, flags);
+ its_vpe_db_proxy_unmap_locked(vpe);
+ raw_spin_unlock_irqrestore(&vpe_proxy.lock, flags);
+ }
+}
+
+static void its_vpe_db_proxy_map_locked(struct its_vpe *vpe)
+{
+ /* Already mapped? */
+ if (vpe->vpe_proxy_event != -1)
+ return;
+
+ /* This slot was already allocated. Kick the other VPE out. */
+ if (vpe_proxy.vpes[vpe_proxy.next_victim])
+ its_vpe_db_proxy_unmap_locked(vpe_proxy.vpes[vpe_proxy.next_victim]);
+
+ /* Map the new VPE instead */
+ vpe_proxy.vpes[vpe_proxy.next_victim] = vpe;
+ vpe->vpe_proxy_event = vpe_proxy.next_victim;
+ vpe_proxy.next_victim = (vpe_proxy.next_victim + 1) % vpe_proxy.dev->nr_ites;
+
+ vpe_proxy.dev->event_map.col_map[vpe->vpe_proxy_event] = vpe->col_idx;
+ its_send_mapti(vpe_proxy.dev, vpe->vpe_db_lpi, vpe->vpe_proxy_event);
+}
+
+static void its_vpe_db_proxy_move(struct its_vpe *vpe, int from, int to)
+{
+ unsigned long flags;
+ struct its_collection *target_col;
+
+ if (gic_rdists->has_direct_lpi) {
+ void __iomem *rdbase;
+
+ rdbase = per_cpu_ptr(gic_rdists->rdist, from)->rd_base;
+ gic_write_lpir(vpe->vpe_db_lpi, rdbase + GICR_CLRLPIR);
+ while (gic_read_lpir(rdbase + GICR_SYNCR) & 1)
+ cpu_relax();
+
+ return;
+ }
+
+ raw_spin_lock_irqsave(&vpe_proxy.lock, flags);
+
+ its_vpe_db_proxy_map_locked(vpe);
+
+ target_col = &vpe_proxy.dev->its->collections[to];
+ its_send_movi(vpe_proxy.dev, target_col, vpe->vpe_proxy_event);
+ vpe_proxy.dev->event_map.col_map[vpe->vpe_proxy_event] = to;
+
+ raw_spin_unlock_irqrestore(&vpe_proxy.lock, flags);
+}
+
+static int its_vpe_set_affinity(struct irq_data *d,
+ const struct cpumask *mask_val,
+ bool force)
+{
+ struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
+ int cpu = cpumask_first(mask_val);
+
+ /*
+ * Changing affinity is mega expensive, so let's be as lazy as
+ * we can and only do it if we really have to. Also, if mapped
+ * into the proxy device, we need to move the doorbell
+ * interrupt to its new location.
+ */
+ if (vpe->col_idx != cpu) {
+ int from = vpe->col_idx;
+
+ vpe->col_idx = cpu;
+ its_send_vmovp(vpe);
+ its_vpe_db_proxy_move(vpe, from, cpu);
+ }
+
+ return IRQ_SET_MASK_OK_DONE;
+}
+
+static void its_vpe_schedule(struct its_vpe *vpe)
+{
+ void * __iomem vlpi_base = gic_data_rdist_vlpi_base();
+ u64 val;
+
+ /* Schedule the VPE */
+ val = virt_to_phys(page_address(vpe->its_vm->vprop_page)) &
+ GENMASK_ULL(51, 12);
+ val |= (LPI_NRBITS - 1) & GICR_VPROPBASER_IDBITS_MASK;
+ val |= GICR_VPROPBASER_RaWb;
+ val |= GICR_VPROPBASER_InnerShareable;
+ gits_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
+
+ val = virt_to_phys(page_address(vpe->vpt_page)) &
+ GENMASK_ULL(51, 16);
+ val |= GICR_VPENDBASER_RaWaWb;
+ val |= GICR_VPENDBASER_NonShareable;
+ /*
+ * There is no good way of finding out if the pending table is
+ * empty as we can race against the doorbell interrupt very
+ * easily. So in the end, vpe->pending_last is only an
+ * indication that the vcpu has something pending, not one
+ * that the pending table is empty. A good implementation
+ * would be able to read its coarse map pretty quickly anyway,
+ * making this a tolerable issue.
+ */
+ val |= GICR_VPENDBASER_PendingLast;
+ val |= vpe->idai ? GICR_VPENDBASER_IDAI : 0;
+ val |= GICR_VPENDBASER_Valid;
+ gits_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
+}
+
+static void its_vpe_deschedule(struct its_vpe *vpe)
+{
+ void * __iomem vlpi_base = gic_data_rdist_vlpi_base();
+ u32 count = 1000000; /* 1s! */
+ bool clean;
+ u64 val;
+
+ /* We're being scheduled out */
+ val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER);
+ val &= ~GICR_VPENDBASER_Valid;
+ gits_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
+
+ do {
+ val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER);
+ clean = !(val & GICR_VPENDBASER_Dirty);
+ if (!clean) {
+ count--;
+ cpu_relax();
+ udelay(1);
+ }
+ } while (!clean && count);
+
+ if (unlikely(!clean && !count)) {
+ pr_err_ratelimited("ITS virtual pending table not cleaning\n");
+ vpe->idai = false;
+ vpe->pending_last = true;
+ } else {
+ vpe->idai = !!(val & GICR_VPENDBASER_IDAI);
+ vpe->pending_last = !!(val & GICR_VPENDBASER_PendingLast);
+ }
+}
+
+static int its_vpe_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
+{
+ struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
+ struct its_cmd_info *info = vcpu_info;
+
+ switch (info->cmd_type) {
+ case SCHEDULE_VPE:
+ its_vpe_schedule(vpe);
+ return 0;
+
+ case DESCHEDULE_VPE:
+ its_vpe_deschedule(vpe);
+ return 0;
+
+ case INVALL_VPE:
+ its_send_vinvall(vpe);
+ return 0;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static void its_vpe_send_cmd(struct its_vpe *vpe,
+ void (*cmd)(struct its_device *, u32))
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&vpe_proxy.lock, flags);
+
+ its_vpe_db_proxy_map_locked(vpe);
+ cmd(vpe_proxy.dev, vpe->vpe_proxy_event);
+
+ raw_spin_unlock_irqrestore(&vpe_proxy.lock, flags);
+}
+
+static void its_vpe_send_inv(struct irq_data *d)
+{
+ struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
+
+ if (gic_rdists->has_direct_lpi) {
+ void __iomem *rdbase;
+
+ rdbase = per_cpu_ptr(gic_rdists->rdist, vpe->col_idx)->rd_base;
+ gic_write_lpir(vpe->vpe_db_lpi, rdbase + GICR_INVLPIR);
+ while (gic_read_lpir(rdbase + GICR_SYNCR) & 1)
+ cpu_relax();
+ } else {
+ its_vpe_send_cmd(vpe, its_send_inv);
+ }
+}
+
+static void its_vpe_mask_irq(struct irq_data *d)
+{
+ /*
+ * We need to unmask the LPI, which is described by the parent
+ * irq_data. Instead of calling into the parent (which won't
+ * exactly do the right thing, let's simply use the
+ * parent_data pointer. Yes, I'm naughty.
+ */
+ lpi_write_config(d->parent_data, LPI_PROP_ENABLED, 0);
+ its_vpe_send_inv(d);
+}
+
+static void its_vpe_unmask_irq(struct irq_data *d)
+{
+ /* Same hack as above... */
+ lpi_write_config(d->parent_data, 0, LPI_PROP_ENABLED);
+ its_vpe_send_inv(d);
+}
+
+static int its_vpe_set_irqchip_state(struct irq_data *d,
+ enum irqchip_irq_state which,
+ bool state)
+{
+ struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
+
+ if (which != IRQCHIP_STATE_PENDING)
+ return -EINVAL;
+
+ if (gic_rdists->has_direct_lpi) {
+ void __iomem *rdbase;
+
+ rdbase = per_cpu_ptr(gic_rdists->rdist, vpe->col_idx)->rd_base;
+ if (state) {
+ gic_write_lpir(vpe->vpe_db_lpi, rdbase + GICR_SETLPIR);
+ } else {
+ gic_write_lpir(vpe->vpe_db_lpi, rdbase + GICR_CLRLPIR);
+ while (gic_read_lpir(rdbase + GICR_SYNCR) & 1)
+ cpu_relax();
+ }
+ } else {
+ if (state)
+ its_vpe_send_cmd(vpe, its_send_int);
+ else
+ its_vpe_send_cmd(vpe, its_send_clear);
+ }
+
+ return 0;
+}
+
+static struct irq_chip its_vpe_irq_chip = {
+ .name = "GICv4-vpe",
+ .irq_mask = its_vpe_mask_irq,
+ .irq_unmask = its_vpe_unmask_irq,
+ .irq_eoi = irq_chip_eoi_parent,
+ .irq_set_affinity = its_vpe_set_affinity,
+ .irq_set_irqchip_state = its_vpe_set_irqchip_state,
+ .irq_set_vcpu_affinity = its_vpe_set_vcpu_affinity,
+};
+
+static int its_vpe_id_alloc(void)
+{
+ return ida_simple_get(&its_vpeid_ida, 0, 1 << 16, GFP_KERNEL);
+}
+
+static void its_vpe_id_free(u16 id)
+{
+ ida_simple_remove(&its_vpeid_ida, id);
+}
+
+static int its_vpe_init(struct its_vpe *vpe)
+{
+ struct page *vpt_page;
+ int vpe_id;
+
+ /* Allocate vpe_id */
+ vpe_id = its_vpe_id_alloc();
+ if (vpe_id < 0)
+ return vpe_id;
+
+ /* Allocate VPT */
+ vpt_page = its_allocate_pending_table(GFP_KERNEL);
+ if (!vpt_page) {
+ its_vpe_id_free(vpe_id);
+ return -ENOMEM;
+ }
+
+ if (!its_alloc_vpe_table(vpe_id)) {
+ its_vpe_id_free(vpe_id);
+ its_free_pending_table(vpe->vpt_page);
+ return -ENOMEM;
+ }
+
+ vpe->vpe_id = vpe_id;
+ vpe->vpt_page = vpt_page;
+ vpe->vpe_proxy_event = -1;
+
+ return 0;
+}
+
+static void its_vpe_teardown(struct its_vpe *vpe)
+{
+ its_vpe_db_proxy_unmap(vpe);
+ its_vpe_id_free(vpe->vpe_id);
+ its_free_pending_table(vpe->vpt_page);
+}
+
+static void its_vpe_irq_domain_free(struct irq_domain *domain,
+ unsigned int virq,
+ unsigned int nr_irqs)
+{
+ struct its_vm *vm = domain->host_data;
+ int i;
+
+ irq_domain_free_irqs_parent(domain, virq, nr_irqs);
+
+ for (i = 0; i < nr_irqs; i++) {
+ struct irq_data *data = irq_domain_get_irq_data(domain,
+ virq + i);
+ struct its_vpe *vpe = irq_data_get_irq_chip_data(data);
+
+ BUG_ON(vm != vpe->its_vm);
+
+ clear_bit(data->hwirq, vm->db_bitmap);
+ its_vpe_teardown(vpe);
+ irq_domain_reset_irq_data(data);
+ }
+
+ if (bitmap_empty(vm->db_bitmap, vm->nr_db_lpis)) {
+ its_lpi_free_chunks(vm->db_bitmap, vm->db_lpi_base, vm->nr_db_lpis);
+ its_free_prop_table(vm->vprop_page);
+ }
+}
+
+static int its_vpe_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
+ unsigned int nr_irqs, void *args)
+{
+ struct its_vm *vm = args;
+ unsigned long *bitmap;
+ struct page *vprop_page;
+ int base, nr_ids, i, err = 0;
+
+ BUG_ON(!vm);
+
+ bitmap = its_lpi_alloc_chunks(nr_irqs, &base, &nr_ids);
+ if (!bitmap)
+ return -ENOMEM;
+
+ if (nr_ids < nr_irqs) {
+ its_lpi_free_chunks(bitmap, base, nr_ids);
+ return -ENOMEM;
+ }
+
+ vprop_page = its_allocate_prop_table(GFP_KERNEL);
+ if (!vprop_page) {
+ its_lpi_free_chunks(bitmap, base, nr_ids);
+ return -ENOMEM;
+ }
+
+ vm->db_bitmap = bitmap;
+ vm->db_lpi_base = base;
+ vm->nr_db_lpis = nr_ids;
+ vm->vprop_page = vprop_page;
+
+ for (i = 0; i < nr_irqs; i++) {
+ vm->vpes[i]->vpe_db_lpi = base + i;
+ err = its_vpe_init(vm->vpes[i]);
+ if (err)
+ break;
+ err = its_irq_gic_domain_alloc(domain, virq + i,
+ vm->vpes[i]->vpe_db_lpi);
+ if (err)
+ break;
+ irq_domain_set_hwirq_and_chip(domain, virq + i, i,
+ &its_vpe_irq_chip, vm->vpes[i]);
+ set_bit(i, bitmap);
+ }
+
+ if (err) {
+ if (i > 0)
+ its_vpe_irq_domain_free(domain, virq, i - 1);
+
+ its_lpi_free_chunks(bitmap, base, nr_ids);
+ its_free_prop_table(vprop_page);
+ }
+
+ return err;
+}
+
+static void its_vpe_irq_domain_activate(struct irq_domain *domain,
+ struct irq_data *d)
+{
+ struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
+
+ /* Map the VPE to the first possible CPU */
+ vpe->col_idx = cpumask_first(cpu_online_mask);
+ its_send_vmapp(vpe, true);
+ its_send_vinvall(vpe);
+}
+
+static void its_vpe_irq_domain_deactivate(struct irq_domain *domain,
+ struct irq_data *d)
+{
+ struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
+
+ its_send_vmapp(vpe, false);
+}
+
+static const struct irq_domain_ops its_vpe_domain_ops = {
+ .alloc = its_vpe_irq_domain_alloc,
+ .free = its_vpe_irq_domain_free,
+ .activate = its_vpe_irq_domain_activate,
+ .deactivate = its_vpe_irq_domain_deactivate,
+};
+
static int its_force_quiescent(void __iomem *base)
{
u32 count = 1000000; /* 1s */
@@ -1571,7 +2719,7 @@ static int its_force_quiescent(void __iomem *base)
return 0;
/* Disable the generation of all interrupts to this ITS */
- val &= ~GITS_CTLR_ENABLE;
+ val &= ~(GITS_CTLR_ENABLE | GITS_CTLR_ImDe);
writel_relaxed(val, base + GITS_CTLR);
/* Poll GITS_CTLR and wait until ITS becomes quiescent */
@@ -1672,13 +2820,92 @@ static int its_init_domain(struct fwnode_handle *handle, struct its_node *its)
return 0;
}
+static int its_init_vpe_domain(void)
+{
+ struct its_node *its;
+ u32 devid;
+ int entries;
+
+ if (gic_rdists->has_direct_lpi) {
+ pr_info("ITS: Using DirectLPI for VPE invalidation\n");
+ return 0;
+ }
+
+ /* Any ITS will do, even if not v4 */
+ its = list_first_entry(&its_nodes, struct its_node, entry);
+
+ entries = roundup_pow_of_two(nr_cpu_ids);
+ vpe_proxy.vpes = kzalloc(sizeof(*vpe_proxy.vpes) * entries,
+ GFP_KERNEL);
+ if (!vpe_proxy.vpes) {
+ pr_err("ITS: Can't allocate GICv4 proxy device array\n");
+ return -ENOMEM;
+ }
+
+ /* Use the last possible DevID */
+ devid = GENMASK(its->device_ids - 1, 0);
+ vpe_proxy.dev = its_create_device(its, devid, entries, false);
+ if (!vpe_proxy.dev) {
+ kfree(vpe_proxy.vpes);
+ pr_err("ITS: Can't allocate GICv4 proxy device\n");
+ return -ENOMEM;
+ }
+
+ BUG_ON(entries != vpe_proxy.dev->nr_ites);
+
+ raw_spin_lock_init(&vpe_proxy.lock);
+ vpe_proxy.next_victim = 0;
+ pr_info("ITS: Allocated DevID %x as GICv4 proxy device (%d slots)\n",
+ devid, vpe_proxy.dev->nr_ites);
+
+ return 0;
+}
+
+static int __init its_compute_its_list_map(struct resource *res,
+ void __iomem *its_base)
+{
+ int its_number;
+ u32 ctlr;
+
+ /*
+ * This is assumed to be done early enough that we're
+ * guaranteed to be single-threaded, hence no
+ * locking. Should this change, we should address
+ * this.
+ */
+ its_number = find_first_zero_bit(&its_list_map, ITS_LIST_MAX);
+ if (its_number >= ITS_LIST_MAX) {
+ pr_err("ITS@%pa: No ITSList entry available!\n",
+ &res->start);
+ return -EINVAL;
+ }
+
+ ctlr = readl_relaxed(its_base + GITS_CTLR);
+ ctlr &= ~GITS_CTLR_ITS_NUMBER;
+ ctlr |= its_number << GITS_CTLR_ITS_NUMBER_SHIFT;
+ writel_relaxed(ctlr, its_base + GITS_CTLR);
+ ctlr = readl_relaxed(its_base + GITS_CTLR);
+ if ((ctlr & GITS_CTLR_ITS_NUMBER) != (its_number << GITS_CTLR_ITS_NUMBER_SHIFT)) {
+ its_number = ctlr & GITS_CTLR_ITS_NUMBER;
+ its_number >>= GITS_CTLR_ITS_NUMBER_SHIFT;
+ }
+
+ if (test_and_set_bit(its_number, &its_list_map)) {
+ pr_err("ITS@%pa: Duplicate ITSList entry %d\n",
+ &res->start, its_number);
+ return -EINVAL;
+ }
+
+ return its_number;
+}
+
static int __init its_probe_one(struct resource *res,
struct fwnode_handle *handle, int numa_node)
{
struct its_node *its;
void __iomem *its_base;
- u32 val;
- u64 baser, tmp;
+ u32 val, ctlr;
+ u64 baser, tmp, typer;
int err;
its_base = ioremap(res->start, resource_size(res));
@@ -1711,9 +2938,24 @@ static int __init its_probe_one(struct resource *res,
raw_spin_lock_init(&its->lock);
INIT_LIST_HEAD(&its->entry);
INIT_LIST_HEAD(&its->its_device_list);
+ typer = gic_read_typer(its_base + GITS_TYPER);
its->base = its_base;
its->phys_base = res->start;
- its->ite_size = ((gic_read_typer(its_base + GITS_TYPER) >> 4) & 0xf) + 1;
+ its->ite_size = GITS_TYPER_ITT_ENTRY_SIZE(typer);
+ its->is_v4 = !!(typer & GITS_TYPER_VLPIS);
+ if (its->is_v4) {
+ if (!(typer & GITS_TYPER_VMOVP)) {
+ err = its_compute_its_list_map(res, its_base);
+ if (err < 0)
+ goto out_free_its;
+
+ pr_info("ITS@%pa: Using ITS number %d\n",
+ &res->start, err);
+ } else {
+ pr_info("ITS@%pa: Single VMOVP capable\n", &res->start);
+ }
+ }
+
its->numa_node = numa_node;
its->cmd_base = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
@@ -1760,7 +3002,11 @@ static int __init its_probe_one(struct resource *res,
}
gits_write_cwriter(0, its->base + GITS_CWRITER);
- writel_relaxed(GITS_CTLR_ENABLE, its->base + GITS_CTLR);
+ ctlr = readl_relaxed(its->base + GITS_CTLR);
+ ctlr |= GITS_CTLR_ENABLE;
+ if (its->is_v4)
+ ctlr |= GITS_CTLR_ImDe;
+ writel_relaxed(ctlr, its->base + GITS_CTLR);
err = its_init_domain(handle, its);
if (err)
@@ -1816,13 +3062,13 @@ static int __init its_of_probe(struct device_node *node)
for (np = of_find_matching_node(node, its_device_id); np;
np = of_find_matching_node(np, its_device_id)) {
if (!of_property_read_bool(np, "msi-controller")) {
- pr_warn("%s: no msi-controller property, ITS ignored\n",
- np->full_name);
+ pr_warn("%pOF: no msi-controller property, ITS ignored\n",
+ np);
continue;
}
if (of_address_to_resource(np, 0, &res)) {
- pr_warn("%s: no regs?\n", np->full_name);
+ pr_warn("%pOF: no regs?\n", np);
continue;
}
@@ -1984,6 +3230,9 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
struct irq_domain *parent_domain)
{
struct device_node *of_node;
+ struct its_node *its;
+ bool has_v4 = false;
+ int err;
its_parent = parent_domain;
of_node = to_of_node(handle);
@@ -1998,5 +3247,20 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
}
gic_rdists = rdists;
- return its_alloc_lpi_tables();
+ err = its_alloc_lpi_tables();
+ if (err)
+ return err;
+
+ list_for_each_entry(its, &its_nodes, entry)
+ has_v4 |= its->is_v4;
+
+ if (has_v4 & rdists->has_vlpis) {
+ if (its_init_vpe_domain() ||
+ its_init_v4(parent_domain, &its_vpe_domain_ops)) {
+ rdists->has_vlpis = false;
+ pr_err("ITS: Disabling GICv4 support\n");
+ }
+ }
+
+ return 0;
}
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 984c3ec..519149e 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013, 2014 ARM Limited, All Rights Reserved.
+ * Copyright (C) 2013-2017 ARM Limited, All Rights Reserved.
* Author: Marc Zyngier <marc.zyngier@arm.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -423,24 +423,14 @@ static void __init gic_dist_init(void)
gic_write_irouter(affinity, base + GICD_IROUTER + i * 8);
}
-static int gic_populate_rdist(void)
+static int gic_iterate_rdists(int (*fn)(struct redist_region *, void __iomem *))
{
- unsigned long mpidr = cpu_logical_map(smp_processor_id());
- u64 typer;
- u32 aff;
+ int ret = -ENODEV;
int i;
- /*
- * Convert affinity to a 32bit value that can be matched to
- * GICR_TYPER bits [63:32].
- */
- aff = (MPIDR_AFFINITY_LEVEL(mpidr, 3) << 24 |
- MPIDR_AFFINITY_LEVEL(mpidr, 2) << 16 |
- MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 |
- MPIDR_AFFINITY_LEVEL(mpidr, 0));
-
for (i = 0; i < gic_data.nr_redist_regions; i++) {
void __iomem *ptr = gic_data.redist_regions[i].redist_base;
+ u64 typer;
u32 reg;
reg = readl_relaxed(ptr + GICR_PIDR2) & GIC_PIDR2_ARCH_MASK;
@@ -452,15 +442,9 @@ static int gic_populate_rdist(void)
do {
typer = gic_read_typer(ptr + GICR_TYPER);
- if ((typer >> 32) == aff) {
- u64 offset = ptr - gic_data.redist_regions[i].redist_base;
- gic_data_rdist_rd_base() = ptr;
- gic_data_rdist()->phys_base = gic_data.redist_regions[i].phys_base + offset;
- pr_info("CPU%d: found redistributor %lx region %d:%pa\n",
- smp_processor_id(), mpidr, i,
- &gic_data_rdist()->phys_base);
+ ret = fn(gic_data.redist_regions + i, ptr);
+ if (!ret)
return 0;
- }
if (gic_data.redist_regions[i].single_redist)
break;
@@ -475,12 +459,71 @@ static int gic_populate_rdist(void)
} while (!(typer & GICR_TYPER_LAST));
}
+ return ret ? -ENODEV : 0;
+}
+
+static int __gic_populate_rdist(struct redist_region *region, void __iomem *ptr)
+{
+ unsigned long mpidr = cpu_logical_map(smp_processor_id());
+ u64 typer;
+ u32 aff;
+
+ /*
+ * Convert affinity to a 32bit value that can be matched to
+ * GICR_TYPER bits [63:32].
+ */
+ aff = (MPIDR_AFFINITY_LEVEL(mpidr, 3) << 24 |
+ MPIDR_AFFINITY_LEVEL(mpidr, 2) << 16 |
+ MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 |
+ MPIDR_AFFINITY_LEVEL(mpidr, 0));
+
+ typer = gic_read_typer(ptr + GICR_TYPER);
+ if ((typer >> 32) == aff) {
+ u64 offset = ptr - region->redist_base;
+ gic_data_rdist_rd_base() = ptr;
+ gic_data_rdist()->phys_base = region->phys_base + offset;
+
+ pr_info("CPU%d: found redistributor %lx region %d:%pa\n",
+ smp_processor_id(), mpidr,
+ (int)(region - gic_data.redist_regions),
+ &gic_data_rdist()->phys_base);
+ return 0;
+ }
+
+ /* Try next one */
+ return 1;
+}
+
+static int gic_populate_rdist(void)
+{
+ if (gic_iterate_rdists(__gic_populate_rdist) == 0)
+ return 0;
+
/* We couldn't even deal with ourselves... */
WARN(true, "CPU%d: mpidr %lx has no re-distributor!\n",
- smp_processor_id(), mpidr);
+ smp_processor_id(),
+ (unsigned long)cpu_logical_map(smp_processor_id()));
return -ENODEV;
}
+static int __gic_update_vlpi_properties(struct redist_region *region,
+ void __iomem *ptr)
+{
+ u64 typer = gic_read_typer(ptr + GICR_TYPER);
+ gic_data.rdists.has_vlpis &= !!(typer & GICR_TYPER_VLPIS);
+ gic_data.rdists.has_direct_lpi &= !!(typer & GICR_TYPER_DirectLPIS);
+
+ return 1;
+}
+
+static void gic_update_vlpi_properties(void)
+{
+ gic_iterate_rdists(__gic_update_vlpi_properties);
+ pr_info("%sVLPI support, %sdirect LPI support\n",
+ !gic_data.rdists.has_vlpis ? "no " : "",
+ !gic_data.rdists.has_direct_lpi ? "no " : "");
+}
+
static void gic_cpu_sys_reg_init(void)
{
/*
@@ -677,6 +720,8 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
else
gic_dist_wait_for_rwp();
+ irq_data_update_effective_affinity(d, cpumask_of(cpu));
+
return IRQ_SET_MASK_OK_DONE;
}
#else
@@ -775,6 +820,7 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
irq_domain_set_info(d, irq, hw, chip, d->host_data,
handle_fasteoi_irq, NULL, NULL);
irq_set_probe(irq);
+ irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(irq)));
}
/* LPIs */
if (hw >= 8192 && hw < GIC_ID_NR) {
@@ -953,6 +999,8 @@ static int __init gic_init_bases(void __iomem *dist_base,
gic_data.domain = irq_domain_create_tree(handle, &gic_irq_domain_ops,
&gic_data);
gic_data.rdists.rdist = alloc_percpu(typeof(*gic_data.rdists.rdist));
+ gic_data.rdists.has_vlpis = true;
+ gic_data.rdists.has_direct_lpi = true;
if (WARN_ON(!gic_data.domain) || WARN_ON(!gic_data.rdists.rdist)) {
err = -ENOMEM;
@@ -961,6 +1009,8 @@ static int __init gic_init_bases(void __iomem *dist_base,
set_handle_irq(gic_handle_irq);
+ gic_update_vlpi_properties();
+
if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis())
its_init(handle, &gic_data.rdists, gic_data.domain);
@@ -1067,7 +1117,7 @@ static void __init gic_populate_ppi_partitions(struct device_node *gic_node)
if (WARN_ON(cpu == -1))
continue;
- pr_cont("%s[%d] ", cpu_node->full_name, cpu);
+ pr_cont("%pOF[%d] ", cpu_node, cpu);
cpumask_set_cpu(cpu, &part->mask);
}
@@ -1122,6 +1172,7 @@ static void __init gic_of_setup_kvm_info(struct device_node *node)
if (!ret)
gic_v3_kvm_info.vcpu = r;
+ gic_v3_kvm_info.has_v4 = gic_data.rdists.has_vlpis;
gic_set_kvm_info(&gic_v3_kvm_info);
}
@@ -1135,15 +1186,13 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
dist_base = of_iomap(node, 0);
if (!dist_base) {
- pr_err("%s: unable to map gic dist registers\n",
- node->full_name);
+ pr_err("%pOF: unable to map gic dist registers\n", node);
return -ENXIO;
}
err = gic_validate_dist_version(dist_base);
if (err) {
- pr_err("%s: no distributor detected, giving up\n",
- node->full_name);
+ pr_err("%pOF: no distributor detected, giving up\n", node);
goto out_unmap_dist;
}
@@ -1163,8 +1212,7 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
ret = of_address_to_resource(node, 1 + i, &res);
rdist_regs[i].redist_base = of_iomap(node, 1 + i);
if (ret || !rdist_regs[i].redist_base) {
- pr_err("%s: couldn't map region %d\n",
- node->full_name, i);
+ pr_err("%pOF: couldn't map region %d\n", node, i);
err = -ENODEV;
goto out_unmap_rdist;
}
@@ -1418,6 +1466,7 @@ static void __init gic_acpi_setup_kvm_info(void)
vcpu->end = vcpu->start + ACPI_GICV2_VCPU_MEM_SIZE - 1;
}
+ gic_v3_kvm_info.has_v4 = gic_data.rdists.has_vlpis;
gic_set_kvm_info(&gic_v3_kvm_info);
}
diff --git a/drivers/irqchip/irq-gic-v4.c b/drivers/irqchip/irq-gic-v4.c
new file mode 100644
index 0000000..2370e6d
--- /dev/null
+++ b/drivers/irqchip/irq-gic-v4.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2016,2017 ARM Limited, All Rights Reserved.
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/msi.h>
+#include <linux/sched.h>
+
+#include <linux/irqchip/arm-gic-v4.h>
+
+/*
+ * WARNING: The blurb below assumes that you understand the
+ * intricacies of GICv3, GICv4, and how a guest's view of a GICv3 gets
+ * translated into GICv4 commands. So it effectively targets at most
+ * two individuals. You know who you are.
+ *
+ * The core GICv4 code is designed to *avoid* exposing too much of the
+ * core GIC code (that would in turn leak into the hypervisor code),
+ * and instead provide a hypervisor agnostic interface to the HW (of
+ * course, the astute reader will quickly realize that hypervisor
+ * agnostic actually means KVM-specific - what were you thinking?).
+ *
+ * In order to achieve a modicum of isolation, we try to hide most of
+ * the GICv4 "stuff" behind normal irqchip operations:
+ *
+ * - Any guest-visible VLPI is backed by a Linux interrupt (and a
+ * physical LPI which gets unmapped when the guest maps the
+ * VLPI). This allows the same DevID/EventID pair to be either
+ * mapped to the LPI (host) or the VLPI (guest). Note that this is
+ * exclusive, and you cannot have both.
+ *
+ * - Enabling/disabling a VLPI is done by issuing mask/unmask calls.
+ *
+ * - Guest INT/CLEAR commands are implemented through
+ * irq_set_irqchip_state().
+ *
+ * - The *bizarre* stuff (mapping/unmapping an interrupt to a VLPI, or
+ * issuing an INV after changing a priority) gets shoved into the
+ * irq_set_vcpu_affinity() method. While this is quite horrible
+ * (let's face it, this is the irqchip version of an ioctl), it
+ * confines the crap to a single location. And map/unmap really is
+ * about setting the affinity of a VLPI to a vcpu, so only INV is
+ * majorly out of place. So there.
+ *
+ * A number of commands are simply not provided by this interface, as
+ * they do not make direct sense. For example, MAPD is purely local to
+ * the virtual ITS (because it references a virtual device, and the
+ * physical ITS is still very much in charge of the physical
+ * device). Same goes for things like MAPC (the physical ITS deals
+ * with the actual vPE affinity, and not the braindead concept of
+ * collection). SYNC is not provided either, as each and every command
+ * is followed by a VSYNC. This could be relaxed in the future, should
+ * this be seen as a bottleneck (yes, this means *never*).
+ *
+ * But handling VLPIs is only one side of the job of the GICv4
+ * code. The other (darker) side is to take care of the doorbell
+ * interrupts which are delivered when a VLPI targeting a non-running
+ * vcpu is being made pending.
+ *
+ * The choice made here is that each vcpu (VPE in old northern GICv4
+ * dialect) gets a single doorbell LPI, no matter how many interrupts
+ * are targeting it. This has a nice property, which is that the
+ * interrupt becomes a handle for the VPE, and that the hypervisor
+ * code can manipulate it through the normal interrupt API:
+ *
+ * - VMs (or rather the VM abstraction that matters to the GIC)
+ * contain an irq domain where each interrupt maps to a VPE. In
+ * turn, this domain sits on top of the normal LPI allocator, and a
+ * specially crafted irq_chip implementation.
+ *
+ * - mask/unmask do what is expected on the doorbell interrupt.
+ *
+ * - irq_set_affinity is used to move a VPE from one redistributor to
+ * another.
+ *
+ * - irq_set_vcpu_affinity once again gets hijacked for the purpose of
+ * creating a new sub-API, namely scheduling/descheduling a VPE
+ * (which involves programming GICR_V{PROP,PEND}BASER) and
+ * performing INVALL operations.
+ */
+
+static struct irq_domain *gic_domain;
+static const struct irq_domain_ops *vpe_domain_ops;
+
+int its_alloc_vcpu_irqs(struct its_vm *vm)
+{
+ int vpe_base_irq, i;
+
+ vm->fwnode = irq_domain_alloc_named_id_fwnode("GICv4-vpe",
+ task_pid_nr(current));
+ if (!vm->fwnode)
+ goto err;
+
+ vm->domain = irq_domain_create_hierarchy(gic_domain, 0, vm->nr_vpes,
+ vm->fwnode, vpe_domain_ops,
+ vm);
+ if (!vm->domain)
+ goto err;
+
+ for (i = 0; i < vm->nr_vpes; i++) {
+ vm->vpes[i]->its_vm = vm;
+ vm->vpes[i]->idai = true;
+ }
+
+ vpe_base_irq = __irq_domain_alloc_irqs(vm->domain, -1, vm->nr_vpes,
+ NUMA_NO_NODE, vm,
+ false, NULL);
+ if (vpe_base_irq <= 0)
+ goto err;
+
+ for (i = 0; i < vm->nr_vpes; i++)
+ vm->vpes[i]->irq = vpe_base_irq + i;
+
+ return 0;
+
+err:
+ if (vm->domain)
+ irq_domain_remove(vm->domain);
+ if (vm->fwnode)
+ irq_domain_free_fwnode(vm->fwnode);
+
+ return -ENOMEM;
+}
+
+void its_free_vcpu_irqs(struct its_vm *vm)
+{
+ irq_domain_free_irqs(vm->vpes[0]->irq, vm->nr_vpes);
+ irq_domain_remove(vm->domain);
+ irq_domain_free_fwnode(vm->fwnode);
+}
+
+static int its_send_vpe_cmd(struct its_vpe *vpe, struct its_cmd_info *info)
+{
+ return irq_set_vcpu_affinity(vpe->irq, info);
+}
+
+int its_schedule_vpe(struct its_vpe *vpe, bool on)
+{
+ struct its_cmd_info info;
+
+ WARN_ON(preemptible());
+
+ info.cmd_type = on ? SCHEDULE_VPE : DESCHEDULE_VPE;
+
+ return its_send_vpe_cmd(vpe, &info);
+}
+
+int its_invall_vpe(struct its_vpe *vpe)
+{
+ struct its_cmd_info info = {
+ .cmd_type = INVALL_VPE,
+ };
+
+ return its_send_vpe_cmd(vpe, &info);
+}
+
+int its_map_vlpi(int irq, struct its_vlpi_map *map)
+{
+ struct its_cmd_info info = {
+ .cmd_type = MAP_VLPI,
+ .map = map,
+ };
+
+ /*
+ * The host will never see that interrupt firing again, so it
+ * is vital that we don't do any lazy masking.
+ */
+ irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY);
+
+ return irq_set_vcpu_affinity(irq, &info);
+}
+
+int its_get_vlpi(int irq, struct its_vlpi_map *map)
+{
+ struct its_cmd_info info = {
+ .cmd_type = GET_VLPI,
+ .map = map,
+ };
+
+ return irq_set_vcpu_affinity(irq, &info);
+}
+
+int its_unmap_vlpi(int irq)
+{
+ irq_clear_status_flags(irq, IRQ_DISABLE_UNLAZY);
+ return irq_set_vcpu_affinity(irq, NULL);
+}
+
+int its_prop_update_vlpi(int irq, u8 config, bool inv)
+{
+ struct its_cmd_info info = {
+ .cmd_type = inv ? PROP_UPDATE_AND_INV_VLPI : PROP_UPDATE_VLPI,
+ .config = config,
+ };
+
+ return irq_set_vcpu_affinity(irq, &info);
+}
+
+int its_init_v4(struct irq_domain *domain, const struct irq_domain_ops *ops)
+{
+ if (domain) {
+ pr_info("ITS: Enabling GICv4 support\n");
+ gic_domain = domain;
+ vpe_domain_ops = ops;
+ return 0;
+ }
+
+ pr_err("ITS: No GICv4 VPE domain allocated\n");
+ return -ENODEV;
+}
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index d3e7c43..651d726 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -344,6 +344,8 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
writel_relaxed(val | bit, reg);
gic_unlock_irqrestore(flags);
+ irq_data_update_effective_affinity(d, cpumask_of(cpu));
+
return IRQ_SET_MASK_OK_DONE;
}
#endif
@@ -413,7 +415,7 @@ static void gic_handle_cascade_irq(struct irq_desc *desc)
chained_irq_exit(chip, desc);
}
-static struct irq_chip gic_chip = {
+static const struct irq_chip gic_chip = {
.irq_mask = gic_mask_irq,
.irq_unmask = gic_unmask_irq,
.irq_eoi = gic_eoi_irq,
@@ -969,6 +971,7 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
irq_domain_set_info(d, irq, hw, &gic->chip, d->host_data,
handle_fasteoi_irq, NULL, NULL);
irq_set_probe(irq);
+ irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(irq)));
}
return 0;
}
diff --git a/drivers/irqchip/irq-hip04.c b/drivers/irqchip/irq-hip04.c
index c1b4ee9..5b4fd2f 100644
--- a/drivers/irqchip/irq-hip04.c
+++ b/drivers/irqchip/irq-hip04.c
@@ -165,6 +165,8 @@ static int hip04_irq_set_affinity(struct irq_data *d,
writel_relaxed(val | bit, reg);
raw_spin_unlock(&irq_controller_lock);
+ irq_data_update_effective_affinity(d, cpumask_of(cpu));
+
return IRQ_SET_MASK_OK;
}
#endif
@@ -312,6 +314,7 @@ static int hip04_irq_domain_map(struct irq_domain *d, unsigned int irq,
irq_set_chip_and_handler(irq, &hip04_irq_chip,
handle_fasteoi_irq);
irq_set_probe(irq);
+ irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(irq)));
}
irq_set_chip_data(irq, d->host_data);
return 0;
diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c
index bb36f57..675eda5 100644
--- a/drivers/irqchip/irq-imx-gpcv2.c
+++ b/drivers/irqchip/irq-imx-gpcv2.c
@@ -214,13 +214,13 @@ static int __init imx_gpcv2_irqchip_init(struct device_node *node,
int i;
if (!parent) {
- pr_err("%s: no parent, giving up\n", node->full_name);
+ pr_err("%pOF: no parent, giving up\n", node);
return -ENODEV;
}
parent_domain = irq_find_host(parent);
if (!parent_domain) {
- pr_err("%s: unable to get parent domain\n", node->full_name);
+ pr_err("%pOF: unable to get parent domain\n", node);
return -ENXIO;
}
diff --git a/drivers/irqchip/irq-lpc32xx.c b/drivers/irqchip/irq-lpc32xx.c
index 1034aeb..a48357d 100644
--- a/drivers/irqchip/irq-lpc32xx.c
+++ b/drivers/irqchip/irq-lpc32xx.c
@@ -191,7 +191,7 @@ static int __init lpc32xx_of_ic_init(struct device_node *node,
irqc->base = of_iomap(node, 0);
if (!irqc->base) {
- pr_err("%s: unable to map registers\n", node->full_name);
+ pr_err("%pOF: unable to map registers\n", node);
kfree(irqc);
return -EINVAL;
}
diff --git a/drivers/irqchip/irq-ls-scfg-msi.c b/drivers/irqchip/irq-ls-scfg-msi.c
index 02cca74c..119f4ef 100644
--- a/drivers/irqchip/irq-ls-scfg-msi.c
+++ b/drivers/irqchip/irq-ls-scfg-msi.c
@@ -17,13 +17,32 @@
#include <linux/irq.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/irqdomain.h>
+#include <linux/of_irq.h>
#include <linux/of_pci.h>
#include <linux/of_platform.h>
#include <linux/spinlock.h>
-#define MSI_MAX_IRQS 32
-#define MSI_IBS_SHIFT 3
-#define MSIR 4
+#define MSI_IRQS_PER_MSIR 32
+#define MSI_MSIR_OFFSET 4
+
+#define MSI_LS1043V1_1_IRQS_PER_MSIR 8
+#define MSI_LS1043V1_1_MSIR_OFFSET 0x10
+
+struct ls_scfg_msi_cfg {
+ u32 ibs_shift; /* Shift of interrupt bit select */
+ u32 msir_irqs; /* The irq number per MSIR */
+ u32 msir_base; /* The base address of MSIR */
+};
+
+struct ls_scfg_msir {
+ struct ls_scfg_msi *msi_data;
+ unsigned int index;
+ unsigned int gic_irq;
+ unsigned int bit_start;
+ unsigned int bit_end;
+ unsigned int srs; /* Shared interrupt register select */
+ void __iomem *reg;
+};
struct ls_scfg_msi {
spinlock_t lock;
@@ -32,8 +51,11 @@ struct ls_scfg_msi {
struct irq_domain *msi_domain;
void __iomem *regs;
phys_addr_t msiir_addr;
- int irq;
- DECLARE_BITMAP(used, MSI_MAX_IRQS);
+ struct ls_scfg_msi_cfg *cfg;
+ u32 msir_num;
+ struct ls_scfg_msir *msir;
+ u32 irqs_num;
+ unsigned long *used;
};
static struct irq_chip ls_scfg_msi_irq_chip = {
@@ -49,19 +71,56 @@ static struct msi_domain_info ls_scfg_msi_domain_info = {
.chip = &ls_scfg_msi_irq_chip,
};
+static int msi_affinity_flag = 1;
+
+static int __init early_parse_ls_scfg_msi(char *p)
+{
+ if (p && strncmp(p, "no-affinity", 11) == 0)
+ msi_affinity_flag = 0;
+ else
+ msi_affinity_flag = 1;
+
+ return 0;
+}
+early_param("lsmsi", early_parse_ls_scfg_msi);
+
static void ls_scfg_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
{
struct ls_scfg_msi *msi_data = irq_data_get_irq_chip_data(data);
msg->address_hi = upper_32_bits(msi_data->msiir_addr);
msg->address_lo = lower_32_bits(msi_data->msiir_addr);
- msg->data = data->hwirq << MSI_IBS_SHIFT;
+ msg->data = data->hwirq;
+
+ if (msi_affinity_flag)
+ msg->data |= cpumask_first(data->common->affinity);
}
static int ls_scfg_msi_set_affinity(struct irq_data *irq_data,
const struct cpumask *mask, bool force)
{
- return -EINVAL;
+ struct ls_scfg_msi *msi_data = irq_data_get_irq_chip_data(irq_data);
+ u32 cpu;
+
+ if (!msi_affinity_flag)
+ return -EINVAL;
+
+ if (!force)
+ cpu = cpumask_any_and(mask, cpu_online_mask);
+ else
+ cpu = cpumask_first(mask);
+
+ if (cpu >= msi_data->msir_num)
+ return -EINVAL;
+
+ if (msi_data->msir[cpu].gic_irq <= 0) {
+ pr_warn("cannot bind the irq to cpu%d\n", cpu);
+ return -EINVAL;
+ }
+
+ cpumask_copy(irq_data->common->affinity, mask);
+
+ return IRQ_SET_MASK_OK;
}
static struct irq_chip ls_scfg_msi_parent_chip = {
@@ -81,8 +140,8 @@ static int ls_scfg_msi_domain_irq_alloc(struct irq_domain *domain,
WARN_ON(nr_irqs != 1);
spin_lock(&msi_data->lock);
- pos = find_first_zero_bit(msi_data->used, MSI_MAX_IRQS);
- if (pos < MSI_MAX_IRQS)
+ pos = find_first_zero_bit(msi_data->used, msi_data->irqs_num);
+ if (pos < msi_data->irqs_num)
__set_bit(pos, msi_data->used);
else
err = -ENOSPC;
@@ -106,7 +165,7 @@ static void ls_scfg_msi_domain_irq_free(struct irq_domain *domain,
int pos;
pos = d->hwirq;
- if (pos < 0 || pos >= MSI_MAX_IRQS) {
+ if (pos < 0 || pos >= msi_data->irqs_num) {
pr_err("failed to teardown msi. Invalid hwirq %d\n", pos);
return;
}
@@ -123,15 +182,22 @@ static const struct irq_domain_ops ls_scfg_msi_domain_ops = {
static void ls_scfg_msi_irq_handler(struct irq_desc *desc)
{
- struct ls_scfg_msi *msi_data = irq_desc_get_handler_data(desc);
+ struct ls_scfg_msir *msir = irq_desc_get_handler_data(desc);
+ struct ls_scfg_msi *msi_data = msir->msi_data;
unsigned long val;
- int pos, virq;
+ int pos, size, virq, hwirq;
chained_irq_enter(irq_desc_get_chip(desc), desc);
- val = ioread32be(msi_data->regs + MSIR);
- for_each_set_bit(pos, &val, MSI_MAX_IRQS) {
- virq = irq_find_mapping(msi_data->parent, (31 - pos));
+ val = ioread32be(msir->reg);
+
+ pos = msir->bit_start;
+ size = msir->bit_end + 1;
+
+ for_each_set_bit_from(pos, &val, size) {
+ hwirq = ((msir->bit_end - pos) << msi_data->cfg->ibs_shift) |
+ msir->srs;
+ virq = irq_find_mapping(msi_data->parent, hwirq);
if (virq)
generic_handle_irq(virq);
}
@@ -143,7 +209,7 @@ static int ls_scfg_msi_domains_init(struct ls_scfg_msi *msi_data)
{
/* Initialize MSI domain parent */
msi_data->parent = irq_domain_add_linear(NULL,
- MSI_MAX_IRQS,
+ msi_data->irqs_num,
&ls_scfg_msi_domain_ops,
msi_data);
if (!msi_data->parent) {
@@ -164,16 +230,117 @@ static int ls_scfg_msi_domains_init(struct ls_scfg_msi *msi_data)
return 0;
}
+static int ls_scfg_msi_setup_hwirq(struct ls_scfg_msi *msi_data, int index)
+{
+ struct ls_scfg_msir *msir;
+ int virq, i, hwirq;
+
+ virq = platform_get_irq(msi_data->pdev, index);
+ if (virq <= 0)
+ return -ENODEV;
+
+ msir = &msi_data->msir[index];
+ msir->index = index;
+ msir->msi_data = msi_data;
+ msir->gic_irq = virq;
+ msir->reg = msi_data->regs + msi_data->cfg->msir_base + 4 * index;
+
+ if (msi_data->cfg->msir_irqs == MSI_LS1043V1_1_IRQS_PER_MSIR) {
+ msir->bit_start = 32 - ((msir->index + 1) *
+ MSI_LS1043V1_1_IRQS_PER_MSIR);
+ msir->bit_end = msir->bit_start +
+ MSI_LS1043V1_1_IRQS_PER_MSIR - 1;
+ } else {
+ msir->bit_start = 0;
+ msir->bit_end = msi_data->cfg->msir_irqs - 1;
+ }
+
+ irq_set_chained_handler_and_data(msir->gic_irq,
+ ls_scfg_msi_irq_handler,
+ msir);
+
+ if (msi_affinity_flag) {
+ /* Associate MSIR interrupt to the cpu */
+ irq_set_affinity(msir->gic_irq, get_cpu_mask(index));
+ msir->srs = 0; /* This value is determined by the CPU */
+ } else
+ msir->srs = index;
+
+ /* Release the hwirqs corresponding to this MSIR */
+ if (!msi_affinity_flag || msir->index == 0) {
+ for (i = 0; i < msi_data->cfg->msir_irqs; i++) {
+ hwirq = i << msi_data->cfg->ibs_shift | msir->index;
+ bitmap_clear(msi_data->used, hwirq, 1);
+ }
+ }
+
+ return 0;
+}
+
+static int ls_scfg_msi_teardown_hwirq(struct ls_scfg_msir *msir)
+{
+ struct ls_scfg_msi *msi_data = msir->msi_data;
+ int i, hwirq;
+
+ if (msir->gic_irq > 0)
+ irq_set_chained_handler_and_data(msir->gic_irq, NULL, NULL);
+
+ for (i = 0; i < msi_data->cfg->msir_irqs; i++) {
+ hwirq = i << msi_data->cfg->ibs_shift | msir->index;
+ bitmap_set(msi_data->used, hwirq, 1);
+ }
+
+ return 0;
+}
+
+static struct ls_scfg_msi_cfg ls1021_msi_cfg = {
+ .ibs_shift = 3,
+ .msir_irqs = MSI_IRQS_PER_MSIR,
+ .msir_base = MSI_MSIR_OFFSET,
+};
+
+static struct ls_scfg_msi_cfg ls1046_msi_cfg = {
+ .ibs_shift = 2,
+ .msir_irqs = MSI_IRQS_PER_MSIR,
+ .msir_base = MSI_MSIR_OFFSET,
+};
+
+static struct ls_scfg_msi_cfg ls1043_v1_1_msi_cfg = {
+ .ibs_shift = 2,
+ .msir_irqs = MSI_LS1043V1_1_IRQS_PER_MSIR,
+ .msir_base = MSI_LS1043V1_1_MSIR_OFFSET,
+};
+
+static const struct of_device_id ls_scfg_msi_id[] = {
+ /* The following two misspelled compatibles are obsolete */
+ { .compatible = "fsl,1s1021a-msi", .data = &ls1021_msi_cfg},
+ { .compatible = "fsl,1s1043a-msi", .data = &ls1021_msi_cfg},
+
+ { .compatible = "fsl,ls1021a-msi", .data = &ls1021_msi_cfg },
+ { .compatible = "fsl,ls1043a-msi", .data = &ls1021_msi_cfg },
+ { .compatible = "fsl,ls1043a-v1.1-msi", .data = &ls1043_v1_1_msi_cfg },
+ { .compatible = "fsl,ls1046a-msi", .data = &ls1046_msi_cfg },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ls_scfg_msi_id);
+
static int ls_scfg_msi_probe(struct platform_device *pdev)
{
+ const struct of_device_id *match;
struct ls_scfg_msi *msi_data;
struct resource *res;
- int ret;
+ int i, ret;
+
+ match = of_match_device(ls_scfg_msi_id, &pdev->dev);
+ if (!match)
+ return -ENODEV;
msi_data = devm_kzalloc(&pdev->dev, sizeof(*msi_data), GFP_KERNEL);
if (!msi_data)
return -ENOMEM;
+ msi_data->cfg = (struct ls_scfg_msi_cfg *) match->data;
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
msi_data->regs = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(msi_data->regs)) {
@@ -182,23 +349,48 @@ static int ls_scfg_msi_probe(struct platform_device *pdev)
}
msi_data->msiir_addr = res->start;
- msi_data->irq = platform_get_irq(pdev, 0);
- if (msi_data->irq <= 0) {
- dev_err(&pdev->dev, "failed to get MSI irq\n");
- return -ENODEV;
- }
-
msi_data->pdev = pdev;
spin_lock_init(&msi_data->lock);
+ msi_data->irqs_num = MSI_IRQS_PER_MSIR *
+ (1 << msi_data->cfg->ibs_shift);
+ msi_data->used = devm_kcalloc(&pdev->dev,
+ BITS_TO_LONGS(msi_data->irqs_num),
+ sizeof(*msi_data->used),
+ GFP_KERNEL);
+ if (!msi_data->used)
+ return -ENOMEM;
+ /*
+ * Reserve all the hwirqs
+ * The available hwirqs will be released in ls1_msi_setup_hwirq()
+ */
+ bitmap_set(msi_data->used, 0, msi_data->irqs_num);
+
+ msi_data->msir_num = of_irq_count(pdev->dev.of_node);
+
+ if (msi_affinity_flag) {
+ u32 cpu_num;
+
+ cpu_num = num_possible_cpus();
+ if (msi_data->msir_num >= cpu_num)
+ msi_data->msir_num = cpu_num;
+ else
+ msi_affinity_flag = 0;
+ }
+
+ msi_data->msir = devm_kcalloc(&pdev->dev, msi_data->msir_num,
+ sizeof(*msi_data->msir),
+ GFP_KERNEL);
+ if (!msi_data->msir)
+ return -ENOMEM;
+
+ for (i = 0; i < msi_data->msir_num; i++)
+ ls_scfg_msi_setup_hwirq(msi_data, i);
+
ret = ls_scfg_msi_domains_init(msi_data);
if (ret)
return ret;
- irq_set_chained_handler_and_data(msi_data->irq,
- ls_scfg_msi_irq_handler,
- msi_data);
-
platform_set_drvdata(pdev, msi_data);
return 0;
@@ -207,8 +399,10 @@ static int ls_scfg_msi_probe(struct platform_device *pdev)
static int ls_scfg_msi_remove(struct platform_device *pdev)
{
struct ls_scfg_msi *msi_data = platform_get_drvdata(pdev);
+ int i;
- irq_set_chained_handler_and_data(msi_data->irq, NULL, NULL);
+ for (i = 0; i < msi_data->msir_num; i++)
+ ls_scfg_msi_teardown_hwirq(&msi_data->msir[i]);
irq_domain_remove(msi_data->msi_domain);
irq_domain_remove(msi_data->parent);
@@ -218,12 +412,6 @@ static int ls_scfg_msi_remove(struct platform_device *pdev)
return 0;
}
-static const struct of_device_id ls_scfg_msi_id[] = {
- { .compatible = "fsl,1s1021a-msi", },
- { .compatible = "fsl,1s1043a-msi", },
- {},
-};
-
static struct platform_driver ls_scfg_msi_driver = {
.driver = {
.name = "ls-scfg-msi",
diff --git a/drivers/irqchip/irq-metag-ext.c b/drivers/irqchip/irq-metag-ext.c
index 0cdd923..be7216b 100644
--- a/drivers/irqchip/irq-metag-ext.c
+++ b/drivers/irqchip/irq-metag-ext.c
@@ -518,6 +518,8 @@ static int meta_intc_set_affinity(struct irq_data *data,
metag_out32(TBI_TRIG_VEC(TBID_SIGNUM_TR2(thread)), vec_addr);
+ irq_data_update_effective_affinity(data, cpumask_of(cpu));
+
return 0;
}
#else
@@ -578,6 +580,8 @@ static int meta_intc_map(struct irq_domain *d, unsigned int irq,
else
irq_set_chip_and_handler(irq, &meta_intc_edge_chip,
handle_edge_irq);
+
+ irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(irq)));
return 0;
}
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 6ab1d3a..b3a60da 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -445,24 +445,27 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq);
cpumask_t tmp = CPU_MASK_NONE;
unsigned long flags;
- int i;
+ int i, cpu;
cpumask_and(&tmp, cpumask, cpu_online_mask);
if (cpumask_empty(&tmp))
return -EINVAL;
+ cpu = cpumask_first(&tmp);
+
/* Assumption : cpumask refers to a single CPU */
spin_lock_irqsave(&gic_lock, flags);
/* Re-route this IRQ */
- gic_map_to_vpe(irq, mips_cm_vp_id(cpumask_first(&tmp)));
+ gic_map_to_vpe(irq, mips_cm_vp_id(cpu));
/* Update the pcpu_masks */
for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
clear_bit(irq, pcpu_masks[i].pcpu_mask);
- set_bit(irq, pcpu_masks[cpumask_first(&tmp)].pcpu_mask);
+ set_bit(irq, pcpu_masks[cpu].pcpu_mask);
cpumask_copy(irq_data_get_affinity_mask(d), cpumask);
+ irq_data_update_effective_affinity(d, cpumask_of(cpu));
spin_unlock_irqrestore(&gic_lock, flags);
return IRQ_SET_MASK_OK_NOCOPY;
@@ -716,6 +719,7 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq,
if (err)
return err;
+ irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(virq)));
return gic_shared_irq_domain_map(d, virq, hwirq, 0);
}
@@ -1020,8 +1024,11 @@ static int __init gic_of_init(struct device_node *node,
gic_len = resource_size(&res);
}
- if (mips_cm_present())
+ if (mips_cm_present()) {
write_gcr_gic_base(gic_base | CM_GCR_GIC_BASE_GICEN_MSK);
+ /* Ensure GIC region is enabled before trying to access it */
+ __sync();
+ }
gic_present = true;
__gic_init(gic_base, gic_len, cpu_vec, 0, node);
diff --git a/drivers/irqchip/irq-mmp.c b/drivers/irqchip/irq-mmp.c
index 013fc96..25f32e1 100644
--- a/drivers/irqchip/irq-mmp.c
+++ b/drivers/irqchip/irq-mmp.c
@@ -181,13 +181,13 @@ const struct irq_domain_ops mmp_irq_domain_ops = {
.xlate = mmp_irq_domain_xlate,
};
-static struct mmp_intc_conf mmp_conf = {
+static const struct mmp_intc_conf mmp_conf = {
.conf_enable = 0x51,
.conf_disable = 0x0,
.conf_mask = 0x7f,
};
-static struct mmp_intc_conf mmp2_conf = {
+static const struct mmp_intc_conf mmp2_conf = {
.conf_enable = 0x20,
.conf_disable = 0x0,
.conf_mask = 0x7f,
diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c
index eeac512..90aaf19 100644
--- a/drivers/irqchip/irq-mtk-sysirq.c
+++ b/drivers/irqchip/irq-mtk-sysirq.c
@@ -178,8 +178,7 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
chip_data->intpol_words[i] = size / 4;
chip_data->intpol_bases[i] = of_iomap(node, i);
if (ret || !chip_data->intpol_bases[i]) {
- pr_err("%s: couldn't map region %d\n",
- node->full_name, i);
+ pr_err("%pOF: couldn't map region %d\n", node, i);
ret = -ENODEV;
goto out_free_intpol;
}
diff --git a/drivers/irqchip/irq-mxs.c b/drivers/irqchip/irq-mxs.c
index 05fa9f7..e8b31f5 100644
--- a/drivers/irqchip/irq-mxs.c
+++ b/drivers/irqchip/irq-mxs.c
@@ -179,7 +179,7 @@ static void __init icoll_add_domain(struct device_node *np,
&icoll_irq_domain_ops, NULL);
if (!icoll_domain)
- panic("%s: unable to create irq domain", np->full_name);
+ panic("%pOF: unable to create irq domain", np);
}
static void __iomem * __init icoll_init_iobase(struct device_node *np)
@@ -188,7 +188,7 @@ static void __iomem * __init icoll_init_iobase(struct device_node *np)
icoll_base = of_io_request_and_map(np, 0, np->name);
if (IS_ERR(icoll_base))
- panic("%s: unable to map resource", np->full_name);
+ panic("%pOF: unable to map resource", np);
return icoll_base;
}
diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
index 491568c..45363ff 100644
--- a/drivers/irqchip/irq-stm32-exti.c
+++ b/drivers/irqchip/irq-stm32-exti.c
@@ -140,7 +140,7 @@ static int __init stm32_exti_init(struct device_node *node,
base = of_iomap(node, 0);
if (!base) {
- pr_err("%s: Unable to map registers\n", node->full_name);
+ pr_err("%pOF: Unable to map registers\n", node);
return -ENOMEM;
}
@@ -149,7 +149,7 @@ static int __init stm32_exti_init(struct device_node *node,
nr_exti = fls(readl_relaxed(base + EXTI_RTSR));
writel_relaxed(0, base + EXTI_RTSR);
- pr_info("%s: %d External IRQs detected\n", node->full_name, nr_exti);
+ pr_info("%pOF: %d External IRQs detected\n", node, nr_exti);
domain = irq_domain_add_linear(node, nr_exti,
&irq_exti_domain_ops, NULL);
@@ -163,8 +163,8 @@ static int __init stm32_exti_init(struct device_node *node,
ret = irq_alloc_domain_generic_chips(domain, nr_exti, 1, "exti",
handle_edge_irq, clr, 0, 0);
if (ret) {
- pr_err("%s: Could not allocate generic interrupt chip.\n",
- node->full_name);
+ pr_err("%pOF: Could not allocate generic interrupt chip.\n",
+ node);
goto out_free_domain;
}
diff --git a/drivers/irqchip/irq-sun4i.c b/drivers/irqchip/irq-sun4i.c
index 376b280..e3e5b91 100644
--- a/drivers/irqchip/irq-sun4i.c
+++ b/drivers/irqchip/irq-sun4i.c
@@ -97,8 +97,8 @@ static int __init sun4i_of_init(struct device_node *node,
{
sun4i_irq_base = of_iomap(node, 0);
if (!sun4i_irq_base)
- panic("%s: unable to map IC registers\n",
- node->full_name);
+ panic("%pOF: unable to map IC registers\n",
+ node);
/* Disable all interrupts */
writel(0, sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(0));
@@ -124,7 +124,7 @@ static int __init sun4i_of_init(struct device_node *node,
sun4i_irq_domain = irq_domain_add_linear(node, 3 * 32,
&sun4i_irq_ops, NULL);
if (!sun4i_irq_domain)
- panic("%s: unable to create IRQ domain\n", node->full_name);
+ panic("%pOF: unable to create IRQ domain\n", node);
set_handle_irq(sun4i_handle_irq);
diff --git a/drivers/irqchip/irq-tegra.c b/drivers/irqchip/irq-tegra.c
index 3973a14..0abc0cd 100644
--- a/drivers/irqchip/irq-tegra.c
+++ b/drivers/irqchip/irq-tegra.c
@@ -291,13 +291,13 @@ static int __init tegra_ictlr_init(struct device_node *node,
int err;
if (!parent) {
- pr_err("%s: no parent, giving up\n", node->full_name);
+ pr_err("%pOF: no parent, giving up\n", node);
return -ENODEV;
}
parent_domain = irq_find_host(parent);
if (!parent_domain) {
- pr_err("%s: unable to obtain parent domain\n", node->full_name);
+ pr_err("%pOF: unable to obtain parent domain\n", node);
return -ENXIO;
}
@@ -329,29 +329,29 @@ static int __init tegra_ictlr_init(struct device_node *node,
}
if (!num_ictlrs) {
- pr_err("%s: no valid regions, giving up\n", node->full_name);
+ pr_err("%pOF: no valid regions, giving up\n", node);
err = -ENOMEM;
goto out_free;
}
WARN(num_ictlrs != soc->num_ictlrs,
- "%s: Found %u interrupt controllers in DT; expected %u.\n",
- node->full_name, num_ictlrs, soc->num_ictlrs);
+ "%pOF: Found %u interrupt controllers in DT; expected %u.\n",
+ node, num_ictlrs, soc->num_ictlrs);
domain = irq_domain_add_hierarchy(parent_domain, 0, num_ictlrs * 32,
node, &tegra_ictlr_domain_ops,
lic);
if (!domain) {
- pr_err("%s: failed to allocated domain\n", node->full_name);
+ pr_err("%pOF: failed to allocated domain\n", node);
err = -ENOMEM;
goto out_unmap;
}
tegra_ictlr_syscore_init();
- pr_info("%s: %d interrupts forwarded to %s\n",
- node->full_name, num_ictlrs * 32, parent->full_name);
+ pr_info("%pOF: %d interrupts forwarded to %pOF\n",
+ node, num_ictlrs * 32, parent);
return 0;
diff --git a/drivers/irqchip/irq-uniphier-aidet.c b/drivers/irqchip/irq-uniphier-aidet.c
new file mode 100644
index 0000000..7ba7f25
--- /dev/null
+++ b/drivers/irqchip/irq-uniphier-aidet.c
@@ -0,0 +1,261 @@
+/*
+ * Driver for UniPhier AIDET (ARM Interrupt Detector)
+ *
+ * Copyright (C) 2017 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 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/bitops.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+
+#define UNIPHIER_AIDET_NR_IRQS 256
+
+#define UNIPHIER_AIDET_DETCONF 0x04 /* inverter register base */
+
+struct uniphier_aidet_priv {
+ struct irq_domain *domain;
+ void __iomem *reg_base;
+ spinlock_t lock;
+ u32 saved_vals[UNIPHIER_AIDET_NR_IRQS / 32];
+};
+
+static void uniphier_aidet_reg_update(struct uniphier_aidet_priv *priv,
+ unsigned int reg, u32 mask, u32 val)
+{
+ unsigned long flags;
+ u32 tmp;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ tmp = readl_relaxed(priv->reg_base + reg);
+ tmp &= ~mask;
+ tmp |= mask & val;
+ writel_relaxed(tmp, priv->reg_base + reg);
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static void uniphier_aidet_detconf_update(struct uniphier_aidet_priv *priv,
+ unsigned long index, unsigned int val)
+{
+ unsigned int reg;
+ u32 mask;
+
+ reg = UNIPHIER_AIDET_DETCONF + index / 32 * 4;
+ mask = BIT(index % 32);
+
+ uniphier_aidet_reg_update(priv, reg, mask, val ? mask : 0);
+}
+
+static int uniphier_aidet_irq_set_type(struct irq_data *data, unsigned int type)
+{
+ struct uniphier_aidet_priv *priv = data->chip_data;
+ unsigned int val;
+
+ /* enable inverter for active low triggers */
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ case IRQ_TYPE_LEVEL_HIGH:
+ val = 0;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ val = 1;
+ type = IRQ_TYPE_EDGE_RISING;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ val = 1;
+ type = IRQ_TYPE_LEVEL_HIGH;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ uniphier_aidet_detconf_update(priv, data->hwirq, val);
+
+ return irq_chip_set_type_parent(data, type);
+}
+
+static struct irq_chip uniphier_aidet_irq_chip = {
+ .name = "AIDET",
+ .irq_mask = irq_chip_mask_parent,
+ .irq_unmask = irq_chip_unmask_parent,
+ .irq_eoi = irq_chip_eoi_parent,
+ .irq_set_affinity = irq_chip_set_affinity_parent,
+ .irq_set_type = uniphier_aidet_irq_set_type,
+};
+
+static int uniphier_aidet_domain_translate(struct irq_domain *domain,
+ struct irq_fwspec *fwspec,
+ unsigned long *out_hwirq,
+ unsigned int *out_type)
+{
+ if (WARN_ON(fwspec->param_count < 2))
+ return -EINVAL;
+
+ *out_hwirq = fwspec->param[0];
+ *out_type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK;
+
+ return 0;
+}
+
+static int uniphier_aidet_domain_alloc(struct irq_domain *domain,
+ unsigned int virq, unsigned int nr_irqs,
+ void *arg)
+{
+ struct irq_fwspec parent_fwspec;
+ irq_hw_number_t hwirq;
+ unsigned int type;
+ int ret;
+
+ if (nr_irqs != 1)
+ return -EINVAL;
+
+ ret = uniphier_aidet_domain_translate(domain, arg, &hwirq, &type);
+ if (ret)
+ return ret;
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ case IRQ_TYPE_LEVEL_HIGH:
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ type = IRQ_TYPE_EDGE_RISING;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ type = IRQ_TYPE_LEVEL_HIGH;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (hwirq >= UNIPHIER_AIDET_NR_IRQS)
+ return -ENXIO;
+
+ ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
+ &uniphier_aidet_irq_chip,
+ domain->host_data);
+ if (ret)
+ return ret;
+
+ /* parent is GIC */
+ parent_fwspec.fwnode = domain->parent->fwnode;
+ parent_fwspec.param_count = 3;
+ parent_fwspec.param[0] = 0; /* SPI */
+ parent_fwspec.param[1] = hwirq;
+ parent_fwspec.param[2] = type;
+
+ return irq_domain_alloc_irqs_parent(domain, virq, 1, &parent_fwspec);
+}
+
+static const struct irq_domain_ops uniphier_aidet_domain_ops = {
+ .alloc = uniphier_aidet_domain_alloc,
+ .free = irq_domain_free_irqs_common,
+ .translate = uniphier_aidet_domain_translate,
+};
+
+static int uniphier_aidet_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *parent_np;
+ struct irq_domain *parent_domain;
+ struct uniphier_aidet_priv *priv;
+ struct resource *res;
+
+ parent_np = of_irq_find_parent(dev->of_node);
+ if (!parent_np)
+ return -ENXIO;
+
+ parent_domain = irq_find_host(parent_np);
+ of_node_put(parent_np);
+ if (!parent_domain)
+ return -EPROBE_DEFER;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ priv->reg_base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(priv->reg_base))
+ return PTR_ERR(priv->reg_base);
+
+ spin_lock_init(&priv->lock);
+
+ priv->domain = irq_domain_create_hierarchy(
+ parent_domain, 0,
+ UNIPHIER_AIDET_NR_IRQS,
+ of_node_to_fwnode(dev->of_node),
+ &uniphier_aidet_domain_ops, priv);
+ if (!priv->domain)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, priv);
+
+ return 0;
+}
+
+static int __maybe_unused uniphier_aidet_suspend(struct device *dev)
+{
+ struct uniphier_aidet_priv *priv = dev_get_drvdata(dev);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(priv->saved_vals); i++)
+ priv->saved_vals[i] = readl_relaxed(
+ priv->reg_base + UNIPHIER_AIDET_DETCONF + i * 4);
+
+ return 0;
+}
+
+static int __maybe_unused uniphier_aidet_resume(struct device *dev)
+{
+ struct uniphier_aidet_priv *priv = dev_get_drvdata(dev);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(priv->saved_vals); i++)
+ writel_relaxed(priv->saved_vals[i],
+ priv->reg_base + UNIPHIER_AIDET_DETCONF + i * 4);
+
+ return 0;
+}
+
+static const struct dev_pm_ops uniphier_aidet_pm_ops = {
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(uniphier_aidet_suspend,
+ uniphier_aidet_resume)
+};
+
+static const struct of_device_id uniphier_aidet_match[] = {
+ { .compatible = "socionext,uniphier-ld4-aidet" },
+ { .compatible = "socionext,uniphier-pro4-aidet" },
+ { .compatible = "socionext,uniphier-sld8-aidet" },
+ { .compatible = "socionext,uniphier-pro5-aidet" },
+ { .compatible = "socionext,uniphier-pxs2-aidet" },
+ { .compatible = "socionext,uniphier-ld11-aidet" },
+ { .compatible = "socionext,uniphier-ld20-aidet" },
+ { .compatible = "socionext,uniphier-pxs3-aidet" },
+ { /* sentinel */ }
+};
+
+static struct platform_driver uniphier_aidet_driver = {
+ .probe = uniphier_aidet_probe,
+ .driver = {
+ .name = "uniphier-aidet",
+ .of_match_table = uniphier_aidet_match,
+ .pm = &uniphier_aidet_pm_ops,
+ },
+};
+builtin_platform_driver(uniphier_aidet_driver);
diff --git a/drivers/irqchip/irq-xilinx-intc.c b/drivers/irqchip/irq-xilinx-intc.c
index 3db7ab1..e3043de 100644
--- a/drivers/irqchip/irq-xilinx-intc.c
+++ b/drivers/irqchip/irq-xilinx-intc.c
@@ -186,8 +186,8 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
if (irqc->intr_mask >> nr_irq)
pr_warn("irq-xilinx: mismatch in kind-of-intr param\n");
- pr_info("irq-xilinx: %s: num_irq=%d, edge=0x%x\n",
- intc->full_name, nr_irq, irqc->intr_mask);
+ pr_info("irq-xilinx: %pOF: num_irq=%d, edge=0x%x\n",
+ intc, nr_irq, irqc->intr_mask);
/*
diff --git a/drivers/irqchip/irq-xtensa-mx.c b/drivers/irqchip/irq-xtensa-mx.c
index 72a391e..a15a951 100644
--- a/drivers/irqchip/irq-xtensa-mx.c
+++ b/drivers/irqchip/irq-xtensa-mx.c
@@ -32,6 +32,7 @@ static int xtensa_mx_irq_map(struct irq_domain *d, unsigned int irq,
irq_set_status_flags(irq, IRQ_LEVEL);
return 0;
}
+ irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(irq)));
return xtensa_irq_map(d, irq, hw);
}
@@ -121,9 +122,12 @@ static int xtensa_mx_irq_retrigger(struct irq_data *d)
static int xtensa_mx_irq_set_affinity(struct irq_data *d,
const struct cpumask *dest, bool force)
{
- unsigned mask = 1u << cpumask_any_and(dest, cpu_online_mask);
+ int cpu = cpumask_any_and(dest, cpu_online_mask);
+ unsigned mask = 1u << cpu;
set_er(mask, MIROUT(d->hwirq - HW_IRQ_MX_BASE));
+ irq_data_update_effective_affinity(d, cpumask_of(cpu));
+
return 0;
}
diff --git a/drivers/lguest/Kconfig b/drivers/lguest/Kconfig
deleted file mode 100644
index 169172d..0000000
--- a/drivers/lguest/Kconfig
+++ /dev/null
@@ -1,13 +0,0 @@
-config LGUEST
- tristate "Linux hypervisor example code"
- depends on X86_32 && EVENTFD && TTY && PCI_DIRECT
- select HVC_DRIVER
- ---help---
- This is a very simple module which allows you to run
- multiple instances of the same Linux kernel, using the
- "lguest" command found in the tools/lguest directory.
-
- Note that "lguest" is pronounced to rhyme with "fell quest",
- not "rustyvisor". See tools/lguest/lguest.txt.
-
- If unsure, say N. If curious, say M. If masochistic, say Y.
diff --git a/drivers/lguest/Makefile b/drivers/lguest/Makefile
deleted file mode 100644
index 16f52ee..0000000
--- a/drivers/lguest/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-# Host requires the other files, which can be a module.
-obj-$(CONFIG_LGUEST) += lg.o
-lg-y = core.o hypercalls.o page_tables.o interrupts_and_traps.o \
- segments.o lguest_user.o
-
-lg-$(CONFIG_X86_32) += x86/switcher_32.o x86/core.o
-
-Preparation Preparation!: PREFIX=P
-Guest: PREFIX=G
-Drivers: PREFIX=D
-Launcher: PREFIX=L
-Host: PREFIX=H
-Switcher: PREFIX=S
-Mastery: PREFIX=M
-Beer:
- @for f in Preparation Guest Drivers Launcher Host Switcher Mastery; do echo "{==- $$f -==}"; make -s $$f; done; echo "{==-==}"
-Preparation Preparation! Guest Drivers Launcher Host Switcher Mastery:
- @sh ../../tools/lguest/extract $(PREFIX) `find ../../* -name '*.[chS]' -wholename '*lguest*'`
-Puppy:
- @clear
- @printf " __ \n (___()'\`;\n /, /\`\n \\\\\\\"--\\\\\\ \n"
- @sleep 2; clear; printf "\n\n Sit!\n\n"; sleep 1; clear
- @printf " __ \n ()'\`; \n /\\|\` \n / | \n(/_)_|_ \n"
- @sleep 2; clear; printf "\n\n Stand!\n\n"; sleep 1; clear
- @printf " __ \n ()'\`; \n /\\|\` \n /._.= \n /| / \n(_\_)_ \n"
- @sleep 2; clear; printf "\n\n Good puppy!\n\n"; sleep 1; clear
diff --git a/drivers/lguest/README b/drivers/lguest/README
deleted file mode 100644
index b7db39a..0000000
--- a/drivers/lguest/README
+++ /dev/null
@@ -1,47 +0,0 @@
-Welcome, friend reader, to lguest.
-
-Lguest is an adventure, with you, the reader, as Hero. I can't think of many
-5000-line projects which offer both such capability and glimpses of future
-potential; it is an exciting time to be delving into the source!
-
-But be warned; this is an arduous journey of several hours or more! And as we
-know, all true Heroes are driven by a Noble Goal. Thus I offer a Beer (or
-equivalent) to anyone I meet who has completed this documentation.
-
-So get comfortable and keep your wits about you (both quick and humorous).
-Along your way to the Noble Goal, you will also gain masterly insight into
-lguest, and hypervisors and x86 virtualization in general.
-
-Our Quest is in seven parts: (best read with C highlighting turned on)
-
-I) Preparation
- - In which our potential hero is flown quickly over the landscape for a
- taste of its scope. Suitable for the armchair coders and other such
- persons of faint constitution.
-
-II) Guest
- - Where we encounter the first tantalising wisps of code, and come to
- understand the details of the life of a Guest kernel.
-
-III) Drivers
- - Whereby the Guest finds its voice and become useful, and our
- understanding of the Guest is completed.
-
-IV) Launcher
- - Where we trace back to the creation of the Guest, and thus begin our
- understanding of the Host.
-
-V) Host
- - Where we master the Host code, through a long and tortuous journey.
- Indeed, it is here that our hero is tested in the Bit of Despair.
-
-VI) Switcher
- - Where our understanding of the intertwined nature of Guests and Hosts
- is completed.
-
-VII) Mastery
- - Where our fully fledged hero grapples with the Great Question:
- "What next?"
-
-make Preparation!
-Rusty Russell.
diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
deleted file mode 100644
index 395ed19..0000000
--- a/drivers/lguest/core.c
+++ /dev/null
@@ -1,398 +0,0 @@
-/*P:400
- * This contains run_guest() which actually calls into the Host<->Guest
- * Switcher and analyzes the return, such as determining if the Guest wants the
- * Host to do something. This file also contains useful helper routines.
-:*/
-#include <linux/module.h>
-#include <linux/stringify.h>
-#include <linux/stddef.h>
-#include <linux/io.h>
-#include <linux/mm.h>
-#include <linux/sched/signal.h>
-#include <linux/vmalloc.h>
-#include <linux/cpu.h>
-#include <linux/freezer.h>
-#include <linux/highmem.h>
-#include <linux/slab.h>
-#include <asm/paravirt.h>
-#include <asm/pgtable.h>
-#include <linux/uaccess.h>
-#include <asm/poll.h>
-#include <asm/asm-offsets.h>
-#include "lg.h"
-
-unsigned long switcher_addr;
-struct page **lg_switcher_pages;
-static struct vm_struct *switcher_text_vma;
-static struct vm_struct *switcher_stacks_vma;
-
-/* This One Big lock protects all inter-guest data structures. */
-DEFINE_MUTEX(lguest_lock);
-
-/*H:010
- * We need to set up the Switcher at a high virtual address. Remember the
- * Switcher is a few hundred bytes of assembler code which actually changes the
- * CPU to run the Guest, and then changes back to the Host when a trap or
- * interrupt happens.
- *
- * The Switcher code must be at the same virtual address in the Guest as the
- * Host since it will be running as the switchover occurs.
- *
- * Trying to map memory at a particular address is an unusual thing to do, so
- * it's not a simple one-liner.
- */
-static __init int map_switcher(void)
-{
- int i, err;
-
- /*
- * Map the Switcher in to high memory.
- *
- * It turns out that if we choose the address 0xFFC00000 (4MB under the
- * top virtual address), it makes setting up the page tables really
- * easy.
- */
-
- /* We assume Switcher text fits into a single page. */
- if (end_switcher_text - start_switcher_text > PAGE_SIZE) {
- printk(KERN_ERR "lguest: switcher text too large (%zu)\n",
- end_switcher_text - start_switcher_text);
- return -EINVAL;
- }
-
- /*
- * We allocate an array of struct page pointers. map_vm_area() wants
- * this, rather than just an array of pages.
- */
- lg_switcher_pages = kmalloc(sizeof(lg_switcher_pages[0])
- * TOTAL_SWITCHER_PAGES,
- GFP_KERNEL);
- if (!lg_switcher_pages) {
- err = -ENOMEM;
- goto out;
- }
-
- /*
- * Now we actually allocate the pages. The Guest will see these pages,
- * so we make sure they're zeroed.
- */
- for (i = 0; i < TOTAL_SWITCHER_PAGES; i++) {
- lg_switcher_pages[i] = alloc_page(GFP_KERNEL|__GFP_ZERO);
- if (!lg_switcher_pages[i]) {
- err = -ENOMEM;
- goto free_some_pages;
- }
- }
-
- /*
- * Copy in the compiled-in Switcher code (from x86/switcher_32.S).
- * It goes in the first page, which we map in momentarily.
- */
- memcpy(kmap(lg_switcher_pages[0]), start_switcher_text,
- end_switcher_text - start_switcher_text);
- kunmap(lg_switcher_pages[0]);
-
- /*
- * We place the Switcher underneath the fixmap area, which is the
- * highest virtual address we can get. This is important, since we
- * tell the Guest it can't access this memory, so we want its ceiling
- * as high as possible.
- */
- switcher_addr = FIXADDR_START - TOTAL_SWITCHER_PAGES*PAGE_SIZE;
-
- /*
- * Now we reserve the "virtual memory area"s we want. We might
- * not get them in theory, but in practice it's worked so far.
- *
- * We want the switcher text to be read-only and executable, and
- * the stacks to be read-write and non-executable.
- */
- switcher_text_vma = __get_vm_area(PAGE_SIZE, VM_ALLOC|VM_NO_GUARD,
- switcher_addr,
- switcher_addr + PAGE_SIZE);
-
- if (!switcher_text_vma) {
- err = -ENOMEM;
- printk("lguest: could not map switcher pages high\n");
- goto free_pages;
- }
-
- switcher_stacks_vma = __get_vm_area(SWITCHER_STACK_PAGES * PAGE_SIZE,
- VM_ALLOC|VM_NO_GUARD,
- switcher_addr + PAGE_SIZE,
- switcher_addr + TOTAL_SWITCHER_PAGES * PAGE_SIZE);
- if (!switcher_stacks_vma) {
- err = -ENOMEM;
- printk("lguest: could not map switcher pages high\n");
- goto free_text_vma;
- }
-
- /*
- * This code actually sets up the pages we've allocated to appear at
- * switcher_addr. map_vm_area() takes the vma we allocated above, the
- * kind of pages we're mapping (kernel text pages and kernel writable
- * pages respectively), and a pointer to our array of struct pages.
- */
- err = map_vm_area(switcher_text_vma, PAGE_KERNEL_RX, lg_switcher_pages);
- if (err) {
- printk("lguest: text map_vm_area failed: %i\n", err);
- goto free_vmas;
- }
-
- err = map_vm_area(switcher_stacks_vma, PAGE_KERNEL,
- lg_switcher_pages + SWITCHER_TEXT_PAGES);
- if (err) {
- printk("lguest: stacks map_vm_area failed: %i\n", err);
- goto free_vmas;
- }
-
- /*
- * Now the Switcher is mapped at the right address, we can't fail!
- */
- printk(KERN_INFO "lguest: mapped switcher at %p\n",
- switcher_text_vma->addr);
- /* And we succeeded... */
- return 0;
-
-free_vmas:
- /* Undoes map_vm_area and __get_vm_area */
- vunmap(switcher_stacks_vma->addr);
-free_text_vma:
- vunmap(switcher_text_vma->addr);
-free_pages:
- i = TOTAL_SWITCHER_PAGES;
-free_some_pages:
- for (--i; i >= 0; i--)
- __free_pages(lg_switcher_pages[i], 0);
- kfree(lg_switcher_pages);
-out:
- return err;
-}
-/*:*/
-
-/* Cleaning up the mapping when the module is unloaded is almost... too easy. */
-static void unmap_switcher(void)
-{
- unsigned int i;
-
- /* vunmap() undoes *both* map_vm_area() and __get_vm_area(). */
- vunmap(switcher_text_vma->addr);
- vunmap(switcher_stacks_vma->addr);
- /* Now we just need to free the pages we copied the switcher into */
- for (i = 0; i < TOTAL_SWITCHER_PAGES; i++)
- __free_pages(lg_switcher_pages[i], 0);
- kfree(lg_switcher_pages);
-}
-
-/*H:032
- * Dealing With Guest Memory.
- *
- * Before we go too much further into the Host, we need to grok the routines
- * we use to deal with Guest memory.
- *
- * When the Guest gives us (what it thinks is) a physical address, we can use
- * the normal copy_from_user() & copy_to_user() on the corresponding place in
- * the memory region allocated by the Launcher.
- *
- * But we can't trust the Guest: it might be trying to access the Launcher
- * code. We have to check that the range is below the pfn_limit the Launcher
- * gave us. We have to make sure that addr + len doesn't give us a false
- * positive by overflowing, too.
- */
-bool lguest_address_ok(const struct lguest *lg,
- unsigned long addr, unsigned long len)
-{
- return addr+len <= lg->pfn_limit * PAGE_SIZE && (addr+len >= addr);
-}
-
-/*
- * This routine copies memory from the Guest. Here we can see how useful the
- * kill_lguest() routine we met in the Launcher can be: we return a random
- * value (all zeroes) instead of needing to return an error.
- */
-void __lgread(struct lg_cpu *cpu, void *b, unsigned long addr, unsigned bytes)
-{
- if (!lguest_address_ok(cpu->lg, addr, bytes)
- || copy_from_user(b, cpu->lg->mem_base + addr, bytes) != 0) {
- /* copy_from_user should do this, but as we rely on it... */
- memset(b, 0, bytes);
- kill_guest(cpu, "bad read address %#lx len %u", addr, bytes);
- }
-}
-
-/* This is the write (copy into Guest) version. */
-void __lgwrite(struct lg_cpu *cpu, unsigned long addr, const void *b,
- unsigned bytes)
-{
- if (!lguest_address_ok(cpu->lg, addr, bytes)
- || copy_to_user(cpu->lg->mem_base + addr, b, bytes) != 0)
- kill_guest(cpu, "bad write address %#lx len %u", addr, bytes);
-}
-/*:*/
-
-/*H:030
- * Let's jump straight to the the main loop which runs the Guest.
- * Remember, this is called by the Launcher reading /dev/lguest, and we keep
- * going around and around until something interesting happens.
- */
-int run_guest(struct lg_cpu *cpu, unsigned long __user *user)
-{
- /* If the launcher asked for a register with LHREQ_GETREG */
- if (cpu->reg_read) {
- if (put_user(*cpu->reg_read, user))
- return -EFAULT;
- cpu->reg_read = NULL;
- return sizeof(*cpu->reg_read);
- }
-
- /* We stop running once the Guest is dead. */
- while (!cpu->lg->dead) {
- unsigned int irq;
- bool more;
-
- /* First we run any hypercalls the Guest wants done. */
- if (cpu->hcall)
- do_hypercalls(cpu);
-
- /* Do we have to tell the Launcher about a trap? */
- if (cpu->pending.trap) {
- if (copy_to_user(user, &cpu->pending,
- sizeof(cpu->pending)))
- return -EFAULT;
- return sizeof(cpu->pending);
- }
-
- /*
- * All long-lived kernel loops need to check with this horrible
- * thing called the freezer. If the Host is trying to suspend,
- * it stops us.
- */
- try_to_freeze();
-
- /* Check for signals */
- if (signal_pending(current))
- return -ERESTARTSYS;
-
- /*
- * Check if there are any interrupts which can be delivered now:
- * if so, this sets up the hander to be executed when we next
- * run the Guest.
- */
- irq = interrupt_pending(cpu, &more);
- if (irq < LGUEST_IRQS)
- try_deliver_interrupt(cpu, irq, more);
-
- /*
- * Just make absolutely sure the Guest is still alive. One of
- * those hypercalls could have been fatal, for example.
- */
- if (cpu->lg->dead)
- break;
-
- /*
- * If the Guest asked to be stopped, we sleep. The Guest's
- * clock timer will wake us.
- */
- if (cpu->halted) {
- set_current_state(TASK_INTERRUPTIBLE);
- /*
- * Just before we sleep, make sure no interrupt snuck in
- * which we should be doing.
- */
- if (interrupt_pending(cpu, &more) < LGUEST_IRQS)
- set_current_state(TASK_RUNNING);
- else
- schedule();
- continue;
- }
-
- /*
- * OK, now we're ready to jump into the Guest. First we put up
- * the "Do Not Disturb" sign:
- */
- local_irq_disable();
-
- /* Actually run the Guest until something happens. */
- lguest_arch_run_guest(cpu);
-
- /* Now we're ready to be interrupted or moved to other CPUs */
- local_irq_enable();
-
- /* Now we deal with whatever happened to the Guest. */
- lguest_arch_handle_trap(cpu);
- }
-
- /* Special case: Guest is 'dead' but wants a reboot. */
- if (cpu->lg->dead == ERR_PTR(-ERESTART))
- return -ERESTART;
-
- /* The Guest is dead => "No such file or directory" */
- return -ENOENT;
-}
-
-/*H:000
- * Welcome to the Host!
- *
- * By this point your brain has been tickled by the Guest code and numbed by
- * the Launcher code; prepare for it to be stretched by the Host code. This is
- * the heart. Let's begin at the initialization routine for the Host's lg
- * module.
- */
-static int __init init(void)
-{
- int err;
-
- /* Lguest can't run under Xen, VMI or itself. It does Tricky Stuff. */
- if (get_kernel_rpl() != 0) {
- printk("lguest is afraid of being a guest\n");
- return -EPERM;
- }
-
- /* First we put the Switcher up in very high virtual memory. */
- err = map_switcher();
- if (err)
- goto out;
-
- /* We might need to reserve an interrupt vector. */
- err = init_interrupts();
- if (err)
- goto unmap;
-
- /* /dev/lguest needs to be registered. */
- err = lguest_device_init();
- if (err)
- goto free_interrupts;
-
- /* Finally we do some architecture-specific setup. */
- lguest_arch_host_init();
-
- /* All good! */
- return 0;
-
-free_interrupts:
- free_interrupts();
-unmap:
- unmap_switcher();
-out:
- return err;
-}
-
-/* Cleaning up is just the same code, backwards. With a little French. */
-static void __exit fini(void)
-{
- lguest_device_remove();
- free_interrupts();
- unmap_switcher();
-
- lguest_arch_host_fini();
-}
-/*:*/
-
-/*
- * The Host side of lguest can be a module. This is a nice way for people to
- * play with it.
- */
-module_init(init);
-module_exit(fini);
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>");
diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
deleted file mode 100644
index 601f81c..0000000
--- a/drivers/lguest/hypercalls.c
+++ /dev/null
@@ -1,304 +0,0 @@
-/*P:500
- * Just as userspace programs request kernel operations through a system
- * call, the Guest requests Host operations through a "hypercall". You might
- * notice this nomenclature doesn't really follow any logic, but the name has
- * been around for long enough that we're stuck with it. As you'd expect, this
- * code is basically a one big switch statement.
-:*/
-
-/* Copyright (C) 2006 Rusty Russell IBM Corporation
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-#include <linux/uaccess.h>
-#include <linux/syscalls.h>
-#include <linux/mm.h>
-#include <linux/ktime.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include "lg.h"
-
-/*H:120
- * This is the core hypercall routine: where the Guest gets what it wants.
- * Or gets killed. Or, in the case of LHCALL_SHUTDOWN, both.
- */
-static void do_hcall(struct lg_cpu *cpu, struct hcall_args *args)
-{
- switch (args->arg0) {
- case LHCALL_FLUSH_ASYNC:
- /*
- * This call does nothing, except by breaking out of the Guest
- * it makes us process all the asynchronous hypercalls.
- */
- break;
- case LHCALL_SEND_INTERRUPTS:
- /*
- * This call does nothing too, but by breaking out of the Guest
- * it makes us process any pending interrupts.
- */
- break;
- case LHCALL_LGUEST_INIT:
- /*
- * You can't get here unless you're already initialized. Don't
- * do that.
- */
- kill_guest(cpu, "already have lguest_data");
- break;
- case LHCALL_SHUTDOWN: {
- char msg[128];
- /*
- * Shutdown is such a trivial hypercall that we do it in five
- * lines right here.
- *
- * If the lgread fails, it will call kill_guest() itself; the
- * kill_guest() with the message will be ignored.
- */
- __lgread(cpu, msg, args->arg1, sizeof(msg));
- msg[sizeof(msg)-1] = '\0';
- kill_guest(cpu, "CRASH: %s", msg);
- if (args->arg2 == LGUEST_SHUTDOWN_RESTART)
- cpu->lg->dead = ERR_PTR(-ERESTART);
- break;
- }
- case LHCALL_FLUSH_TLB:
- /* FLUSH_TLB comes in two flavors, depending on the argument: */
- if (args->arg1)
- guest_pagetable_clear_all(cpu);
- else
- guest_pagetable_flush_user(cpu);
- break;
-
- /*
- * All these calls simply pass the arguments through to the right
- * routines.
- */
- case LHCALL_NEW_PGTABLE:
- guest_new_pagetable(cpu, args->arg1);
- break;
- case LHCALL_SET_STACK:
- guest_set_stack(cpu, args->arg1, args->arg2, args->arg3);
- break;
- case LHCALL_SET_PTE:
-#ifdef CONFIG_X86_PAE
- guest_set_pte(cpu, args->arg1, args->arg2,
- __pte(args->arg3 | (u64)args->arg4 << 32));
-#else
- guest_set_pte(cpu, args->arg1, args->arg2, __pte(args->arg3));
-#endif
- break;
- case LHCALL_SET_PGD:
- guest_set_pgd(cpu->lg, args->arg1, args->arg2);
- break;
-#ifdef CONFIG_X86_PAE
- case LHCALL_SET_PMD:
- guest_set_pmd(cpu->lg, args->arg1, args->arg2);
- break;
-#endif
- case LHCALL_SET_CLOCKEVENT:
- guest_set_clockevent(cpu, args->arg1);
- break;
- case LHCALL_HALT:
- /* Similarly, this sets the halted flag for run_guest(). */
- cpu->halted = 1;
- break;
- default:
- /* It should be an architecture-specific hypercall. */
- if (lguest_arch_do_hcall(cpu, args))
- kill_guest(cpu, "Bad hypercall %li\n", args->arg0);
- }
-}
-
-/*H:124
- * Asynchronous hypercalls are easy: we just look in the array in the
- * Guest's "struct lguest_data" to see if any new ones are marked "ready".
- *
- * We are careful to do these in order: obviously we respect the order the
- * Guest put them in the ring, but we also promise the Guest that they will
- * happen before any normal hypercall (which is why we check this before
- * checking for a normal hcall).
- */
-static void do_async_hcalls(struct lg_cpu *cpu)
-{
- unsigned int i;
- u8 st[LHCALL_RING_SIZE];
-
- /* For simplicity, we copy the entire call status array in at once. */
- if (copy_from_user(&st, &cpu->lg->lguest_data->hcall_status, sizeof(st)))
- return;
-
- /* We process "struct lguest_data"s hcalls[] ring once. */
- for (i = 0; i < ARRAY_SIZE(st); i++) {
- struct hcall_args args;
- /*
- * We remember where we were up to from last time. This makes
- * sure that the hypercalls are done in the order the Guest
- * places them in the ring.
- */
- unsigned int n = cpu->next_hcall;
-
- /* 0xFF means there's no call here (yet). */
- if (st[n] == 0xFF)
- break;
-
- /*
- * OK, we have hypercall. Increment the "next_hcall" cursor,
- * and wrap back to 0 if we reach the end.
- */
- if (++cpu->next_hcall == LHCALL_RING_SIZE)
- cpu->next_hcall = 0;
-
- /*
- * Copy the hypercall arguments into a local copy of the
- * hcall_args struct.
- */
- if (copy_from_user(&args, &cpu->lg->lguest_data->hcalls[n],
- sizeof(struct hcall_args))) {
- kill_guest(cpu, "Fetching async hypercalls");
- break;
- }
-
- /* Do the hypercall, same as a normal one. */
- do_hcall(cpu, &args);
-
- /* Mark the hypercall done. */
- if (put_user(0xFF, &cpu->lg->lguest_data->hcall_status[n])) {
- kill_guest(cpu, "Writing result for async hypercall");
- break;
- }
-
- /*
- * Stop doing hypercalls if they want to notify the Launcher:
- * it needs to service this first.
- */
- if (cpu->pending.trap)
- break;
- }
-}
-
-/*
- * Last of all, we look at what happens first of all. The very first time the
- * Guest makes a hypercall, we end up here to set things up:
- */
-static void initialize(struct lg_cpu *cpu)
-{
- /*
- * You can't do anything until you're initialized. The Guest knows the
- * rules, so we're unforgiving here.
- */
- if (cpu->hcall->arg0 != LHCALL_LGUEST_INIT) {
- kill_guest(cpu, "hypercall %li before INIT", cpu->hcall->arg0);
- return;
- }
-
- if (lguest_arch_init_hypercalls(cpu))
- kill_guest(cpu, "bad guest page %p", cpu->lg->lguest_data);
-
- /*
- * The Guest tells us where we're not to deliver interrupts by putting
- * the instruction address into "struct lguest_data".
- */
- if (get_user(cpu->lg->noirq_iret, &cpu->lg->lguest_data->noirq_iret))
- kill_guest(cpu, "bad guest page %p", cpu->lg->lguest_data);
-
- /*
- * We write the current time into the Guest's data page once so it can
- * set its clock.
- */
- write_timestamp(cpu);
-
- /* page_tables.c will also do some setup. */
- page_table_guest_data_init(cpu);
-
- /*
- * This is the one case where the above accesses might have been the
- * first write to a Guest page. This may have caused a copy-on-write
- * fault, but the old page might be (read-only) in the Guest
- * pagetable.
- */
- guest_pagetable_clear_all(cpu);
-}
-/*:*/
-
-/*M:013
- * If a Guest reads from a page (so creates a mapping) that it has never
- * written to, and then the Launcher writes to it (ie. the output of a virtual
- * device), the Guest will still see the old page. In practice, this never
- * happens: why would the Guest read a page which it has never written to? But
- * a similar scenario might one day bite us, so it's worth mentioning.
- *
- * Note that if we used a shared anonymous mapping in the Launcher instead of
- * mapping /dev/zero private, we wouldn't worry about cop-on-write. And we
- * need that to switch the Launcher to processes (away from threads) anyway.
-:*/
-
-/*H:100
- * Hypercalls
- *
- * Remember from the Guest, hypercalls come in two flavors: normal and
- * asynchronous. This file handles both of types.
- */
-void do_hypercalls(struct lg_cpu *cpu)
-{
- /* Not initialized yet? This hypercall must do it. */
- if (unlikely(!cpu->lg->lguest_data)) {
- /* Set up the "struct lguest_data" */
- initialize(cpu);
- /* Hcall is done. */
- cpu->hcall = NULL;
- return;
- }
-
- /*
- * The Guest has initialized.
- *
- * Look in the hypercall ring for the async hypercalls:
- */
- do_async_hcalls(cpu);
-
- /*
- * If we stopped reading the hypercall ring because the Guest did a
- * NOTIFY to the Launcher, we want to return now. Otherwise we do
- * the hypercall.
- */
- if (!cpu->pending.trap) {
- do_hcall(cpu, cpu->hcall);
- /*
- * Tricky point: we reset the hcall pointer to mark the
- * hypercall as "done". We use the hcall pointer rather than
- * the trap number to indicate a hypercall is pending.
- * Normally it doesn't matter: the Guest will run again and
- * update the trap number before we come back here.
- *
- * However, if we are signalled or the Guest sends I/O to the
- * Launcher, the run_guest() loop will exit without running the
- * Guest. When it comes back it would try to re-run the
- * hypercall. Finding that bug sucked.
- */
- cpu->hcall = NULL;
- }
-}
-
-/*
- * This routine supplies the Guest with time: it's used for wallclock time at
- * initial boot and as a rough time source if the TSC isn't available.
- */
-void write_timestamp(struct lg_cpu *cpu)
-{
- struct timespec now;
- ktime_get_real_ts(&now);
- if (copy_to_user(&cpu->lg->lguest_data->time,
- &now, sizeof(struct timespec)))
- kill_guest(cpu, "Writing timestamp");
-}
diff --git a/drivers/lguest/interrupts_and_traps.c b/drivers/lguest/interrupts_and_traps.c
deleted file mode 100644
index 67392b6..0000000
--- a/drivers/lguest/interrupts_and_traps.c
+++ /dev/null
@@ -1,706 +0,0 @@
-/*P:800
- * Interrupts (traps) are complicated enough to earn their own file.
- * There are three classes of interrupts:
- *
- * 1) Real hardware interrupts which occur while we're running the Guest,
- * 2) Interrupts for virtual devices attached to the Guest, and
- * 3) Traps and faults from the Guest.
- *
- * Real hardware interrupts must be delivered to the Host, not the Guest.
- * Virtual interrupts must be delivered to the Guest, but we make them look
- * just like real hardware would deliver them. Traps from the Guest can be set
- * up to go directly back into the Guest, but sometimes the Host wants to see
- * them first, so we also have a way of "reflecting" them into the Guest as if
- * they had been delivered to it directly.
-:*/
-#include <linux/uaccess.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include "lg.h"
-
-/* Allow Guests to use a non-128 (ie. non-Linux) syscall trap. */
-static unsigned int syscall_vector = IA32_SYSCALL_VECTOR;
-module_param(syscall_vector, uint, 0444);
-
-/* The address of the interrupt handler is split into two bits: */
-static unsigned long idt_address(u32 lo, u32 hi)
-{
- return (lo & 0x0000FFFF) | (hi & 0xFFFF0000);
-}
-
-/*
- * The "type" of the interrupt handler is a 4 bit field: we only support a
- * couple of types.
- */
-static int idt_type(u32 lo, u32 hi)
-{
- return (hi >> 8) & 0xF;
-}
-
-/* An IDT entry can't be used unless the "present" bit is set. */
-static bool idt_present(u32 lo, u32 hi)
-{
- return (hi & 0x8000);
-}
-
-/*
- * We need a helper to "push" a value onto the Guest's stack, since that's a
- * big part of what delivering an interrupt does.
- */
-static void push_guest_stack(struct lg_cpu *cpu, unsigned long *gstack, u32 val)
-{
- /* Stack grows upwards: move stack then write value. */
- *gstack -= 4;
- lgwrite(cpu, *gstack, u32, val);
-}
-
-/*H:210
- * The push_guest_interrupt_stack() routine saves Guest state on the stack for
- * an interrupt or trap. The mechanics of delivering traps and interrupts to
- * the Guest are the same, except some traps have an "error code" which gets
- * pushed onto the stack as well: the caller tells us if this is one.
- *
- * We set up the stack just like the CPU does for a real interrupt, so it's
- * identical for the Guest (and the standard "iret" instruction will undo
- * it).
- */
-static void push_guest_interrupt_stack(struct lg_cpu *cpu, bool has_err)
-{
- unsigned long gstack, origstack;
- u32 eflags, ss, irq_enable;
- unsigned long virtstack;
-
- /*
- * There are two cases for interrupts: one where the Guest is already
- * in the kernel, and a more complex one where the Guest is in
- * userspace. We check the privilege level to find out.
- */
- if ((cpu->regs->ss&0x3) != GUEST_PL) {
- /*
- * The Guest told us their kernel stack with the SET_STACK
- * hypercall: both the virtual address and the segment.
- */
- virtstack = cpu->esp1;
- ss = cpu->ss1;
-
- origstack = gstack = guest_pa(cpu, virtstack);
- /*
- * We push the old stack segment and pointer onto the new
- * stack: when the Guest does an "iret" back from the interrupt
- * handler the CPU will notice they're dropping privilege
- * levels and expect these here.
- */
- push_guest_stack(cpu, &gstack, cpu->regs->ss);
- push_guest_stack(cpu, &gstack, cpu->regs->esp);
- } else {
- /* We're staying on the same Guest (kernel) stack. */
- virtstack = cpu->regs->esp;
- ss = cpu->regs->ss;
-
- origstack = gstack = guest_pa(cpu, virtstack);
- }
-
- /*
- * Remember that we never let the Guest actually disable interrupts, so
- * the "Interrupt Flag" bit is always set. We copy that bit from the
- * Guest's "irq_enabled" field into the eflags word: we saw the Guest
- * copy it back in "lguest_iret".
- */
- eflags = cpu->regs->eflags;
- if (get_user(irq_enable, &cpu->lg->lguest_data->irq_enabled) == 0
- && !(irq_enable & X86_EFLAGS_IF))
- eflags &= ~X86_EFLAGS_IF;
-
- /*
- * An interrupt is expected to push three things on the stack: the old
- * "eflags" word, the old code segment, and the old instruction
- * pointer.
- */
- push_guest_stack(cpu, &gstack, eflags);
- push_guest_stack(cpu, &gstack, cpu->regs->cs);
- push_guest_stack(cpu, &gstack, cpu->regs->eip);
-
- /* For the six traps which supply an error code, we push that, too. */
- if (has_err)
- push_guest_stack(cpu, &gstack, cpu->regs->errcode);
-
- /* Adjust the stack pointer and stack segment. */
- cpu->regs->ss = ss;
- cpu->regs->esp = virtstack + (gstack - origstack);
-}
-
-/*
- * This actually makes the Guest start executing the given interrupt/trap
- * handler.
- *
- * "lo" and "hi" are the two parts of the Interrupt Descriptor Table for this
- * interrupt or trap. It's split into two parts for traditional reasons: gcc
- * on i386 used to be frightened by 64 bit numbers.
- */
-static void guest_run_interrupt(struct lg_cpu *cpu, u32 lo, u32 hi)
-{
- /* If we're already in the kernel, we don't change stacks. */
- if ((cpu->regs->ss&0x3) != GUEST_PL)
- cpu->regs->ss = cpu->esp1;
-
- /*
- * Set the code segment and the address to execute.
- */
- cpu->regs->cs = (__KERNEL_CS|GUEST_PL);
- cpu->regs->eip = idt_address(lo, hi);
-
- /*
- * Trapping always clears these flags:
- * TF: Trap flag
- * VM: Virtual 8086 mode
- * RF: Resume
- * NT: Nested task.
- */
- cpu->regs->eflags &=
- ~(X86_EFLAGS_TF|X86_EFLAGS_VM|X86_EFLAGS_RF|X86_EFLAGS_NT);
-
- /*
- * There are two kinds of interrupt handlers: 0xE is an "interrupt
- * gate" which expects interrupts to be disabled on entry.
- */
- if (idt_type(lo, hi) == 0xE)
- if (put_user(0, &cpu->lg->lguest_data->irq_enabled))
- kill_guest(cpu, "Disabling interrupts");
-}
-
-/* This restores the eflags word which was pushed on the stack by a trap */
-static void restore_eflags(struct lg_cpu *cpu)
-{
- /* This is the physical address of the stack. */
- unsigned long stack_pa = guest_pa(cpu, cpu->regs->esp);
-
- /*
- * Stack looks like this:
- * Address Contents
- * esp EIP
- * esp + 4 CS
- * esp + 8 EFLAGS
- */
- cpu->regs->eflags = lgread(cpu, stack_pa + 8, u32);
- cpu->regs->eflags &=
- ~(X86_EFLAGS_TF|X86_EFLAGS_VM|X86_EFLAGS_RF|X86_EFLAGS_NT);
-}
-
-/*H:205
- * Virtual Interrupts.
- *
- * interrupt_pending() returns the first pending interrupt which isn't blocked
- * by the Guest. It is called before every entry to the Guest, and just before
- * we go to sleep when the Guest has halted itself.
- */
-unsigned int interrupt_pending(struct lg_cpu *cpu, bool *more)
-{
- unsigned int irq;
- DECLARE_BITMAP(blk, LGUEST_IRQS);
-
- /* If the Guest hasn't even initialized yet, we can do nothing. */
- if (!cpu->lg->lguest_data)
- return LGUEST_IRQS;
-
- /*
- * Take our "irqs_pending" array and remove any interrupts the Guest
- * wants blocked: the result ends up in "blk".
- */
- if (copy_from_user(&blk, cpu->lg->lguest_data->blocked_interrupts,
- sizeof(blk)))
- return LGUEST_IRQS;
- bitmap_andnot(blk, cpu->irqs_pending, blk, LGUEST_IRQS);
-
- /* Find the first interrupt. */
- irq = find_first_bit(blk, LGUEST_IRQS);
- *more = find_next_bit(blk, LGUEST_IRQS, irq+1);
-
- return irq;
-}
-
-/*
- * This actually diverts the Guest to running an interrupt handler, once an
- * interrupt has been identified by interrupt_pending().
- */
-void try_deliver_interrupt(struct lg_cpu *cpu, unsigned int irq, bool more)
-{
- struct desc_struct *idt;
-
- BUG_ON(irq >= LGUEST_IRQS);
-
- /* If they're halted, interrupts restart them. */
- if (cpu->halted) {
- /* Re-enable interrupts. */
- if (put_user(X86_EFLAGS_IF, &cpu->lg->lguest_data->irq_enabled))
- kill_guest(cpu, "Re-enabling interrupts");
- cpu->halted = 0;
- } else {
- /* Otherwise we check if they have interrupts disabled. */
- u32 irq_enabled;
- if (get_user(irq_enabled, &cpu->lg->lguest_data->irq_enabled))
- irq_enabled = 0;
- if (!irq_enabled) {
- /* Make sure they know an IRQ is pending. */
- put_user(X86_EFLAGS_IF,
- &cpu->lg->lguest_data->irq_pending);
- return;
- }
- }
-
- /*
- * Look at the IDT entry the Guest gave us for this interrupt. The
- * first 32 (FIRST_EXTERNAL_VECTOR) entries are for traps, so we skip
- * over them.
- */
- idt = &cpu->arch.idt[FIRST_EXTERNAL_VECTOR+irq];
- /* If they don't have a handler (yet?), we just ignore it */
- if (idt_present(idt->a, idt->b)) {
- /* OK, mark it no longer pending and deliver it. */
- clear_bit(irq, cpu->irqs_pending);
-
- /*
- * They may be about to iret, where they asked us never to
- * deliver interrupts. In this case, we can emulate that iret
- * then immediately deliver the interrupt. This is basically
- * a noop: the iret would pop the interrupt frame and restore
- * eflags, and then we'd set it up again. So just restore the
- * eflags word and jump straight to the handler in this case.
- *
- * Denys Vlasenko points out that this isn't quite right: if
- * the iret was returning to userspace, then that interrupt
- * would reset the stack pointer (which the Guest told us
- * about via LHCALL_SET_STACK). But unless the Guest is being
- * *really* weird, that will be the same as the current stack
- * anyway.
- */
- if (cpu->regs->eip == cpu->lg->noirq_iret) {
- restore_eflags(cpu);
- } else {
- /*
- * set_guest_interrupt() takes a flag to say whether
- * this interrupt pushes an error code onto the stack
- * as well: virtual interrupts never do.
- */
- push_guest_interrupt_stack(cpu, false);
- }
- /* Actually make Guest cpu jump to handler. */
- guest_run_interrupt(cpu, idt->a, idt->b);
- }
-
- /*
- * Every time we deliver an interrupt, we update the timestamp in the
- * Guest's lguest_data struct. It would be better for the Guest if we
- * did this more often, but it can actually be quite slow: doing it
- * here is a compromise which means at least it gets updated every
- * timer interrupt.
- */
- write_timestamp(cpu);
-
- /*
- * If there are no other interrupts we want to deliver, clear
- * the pending flag.
- */
- if (!more)
- put_user(0, &cpu->lg->lguest_data->irq_pending);
-}
-
-/* And this is the routine when we want to set an interrupt for the Guest. */
-void set_interrupt(struct lg_cpu *cpu, unsigned int irq)
-{
- /*
- * Next time the Guest runs, the core code will see if it can deliver
- * this interrupt.
- */
- set_bit(irq, cpu->irqs_pending);
-
- /*
- * Make sure it sees it; it might be asleep (eg. halted), or running
- * the Guest right now, in which case kick_process() will knock it out.
- */
- if (!wake_up_process(cpu->tsk))
- kick_process(cpu->tsk);
-}
-/*:*/
-
-/*
- * Linux uses trap 128 for system calls. Plan9 uses 64, and Ron Minnich sent
- * me a patch, so we support that too. It'd be a big step for lguest if half
- * the Plan 9 user base were to start using it.
- *
- * Actually now I think of it, it's possible that Ron *is* half the Plan 9
- * userbase. Oh well.
- */
-bool could_be_syscall(unsigned int num)
-{
- /* Normal Linux IA32_SYSCALL_VECTOR or reserved vector? */
- return num == IA32_SYSCALL_VECTOR || num == syscall_vector;
-}
-
-/* The syscall vector it wants must be unused by Host. */
-bool check_syscall_vector(struct lguest *lg)
-{
- u32 vector;
-
- if (get_user(vector, &lg->lguest_data->syscall_vec))
- return false;
-
- return could_be_syscall(vector);
-}
-
-int init_interrupts(void)
-{
- /* If they want some strange system call vector, reserve it now */
- if (syscall_vector != IA32_SYSCALL_VECTOR) {
- if (test_bit(syscall_vector, used_vectors) ||
- vector_used_by_percpu_irq(syscall_vector)) {
- printk(KERN_ERR "lg: couldn't reserve syscall %u\n",
- syscall_vector);
- return -EBUSY;
- }
- set_bit(syscall_vector, used_vectors);
- }
-
- return 0;
-}
-
-void free_interrupts(void)
-{
- if (syscall_vector != IA32_SYSCALL_VECTOR)
- clear_bit(syscall_vector, used_vectors);
-}
-
-/*H:220
- * Now we've got the routines to deliver interrupts, delivering traps like
- * page fault is easy. The only trick is that Intel decided that some traps
- * should have error codes:
- */
-static bool has_err(unsigned int trap)
-{
- return (trap == 8 || (trap >= 10 && trap <= 14) || trap == 17);
-}
-
-/* deliver_trap() returns true if it could deliver the trap. */
-bool deliver_trap(struct lg_cpu *cpu, unsigned int num)
-{
- /*
- * Trap numbers are always 8 bit, but we set an impossible trap number
- * for traps inside the Switcher, so check that here.
- */
- if (num >= ARRAY_SIZE(cpu->arch.idt))
- return false;
-
- /*
- * Early on the Guest hasn't set the IDT entries (or maybe it put a
- * bogus one in): if we fail here, the Guest will be killed.
- */
- if (!idt_present(cpu->arch.idt[num].a, cpu->arch.idt[num].b))
- return false;
- push_guest_interrupt_stack(cpu, has_err(num));
- guest_run_interrupt(cpu, cpu->arch.idt[num].a,
- cpu->arch.idt[num].b);
- return true;
-}
-
-/*H:250
- * Here's the hard part: returning to the Host every time a trap happens
- * and then calling deliver_trap() and re-entering the Guest is slow.
- * Particularly because Guest userspace system calls are traps (usually trap
- * 128).
- *
- * So we'd like to set up the IDT to tell the CPU to deliver traps directly
- * into the Guest. This is possible, but the complexities cause the size of
- * this file to double! However, 150 lines of code is worth writing for taking
- * system calls down from 1750ns to 270ns. Plus, if lguest didn't do it, all
- * the other hypervisors would beat it up at lunchtime.
- *
- * This routine indicates if a particular trap number could be delivered
- * directly.
- *
- * Unfortunately, Linux 4.6 started using an interrupt gate instead of a
- * trap gate for syscalls, so this trick is ineffective. See Mastery for
- * how we could do this anyway...
- */
-static bool direct_trap(unsigned int num)
-{
- /*
- * Hardware interrupts don't go to the Guest at all (except system
- * call).
- */
- if (num >= FIRST_EXTERNAL_VECTOR && !could_be_syscall(num))
- return false;
-
- /*
- * The Host needs to see page faults (for shadow paging and to save the
- * fault address), general protection faults (in/out emulation) and
- * device not available (TS handling) and of course, the hypercall trap.
- */
- return num != 14 && num != 13 && num != 7 && num != LGUEST_TRAP_ENTRY;
-}
-/*:*/
-
-/*M:005
- * The Guest has the ability to turn its interrupt gates into trap gates,
- * if it is careful. The Host will let trap gates can go directly to the
- * Guest, but the Guest needs the interrupts atomically disabled for an
- * interrupt gate. The Host could provide a mechanism to register more
- * "no-interrupt" regions, and the Guest could point the trap gate at
- * instructions within that region, where it can safely disable interrupts.
- */
-
-/*M:006
- * The Guests do not use the sysenter (fast system call) instruction,
- * because it's hardcoded to enter privilege level 0 and so can't go direct.
- * It's about twice as fast as the older "int 0x80" system call, so it might
- * still be worthwhile to handle it in the Switcher and lcall down to the
- * Guest. The sysenter semantics are hairy tho: search for that keyword in
- * entry.S
-:*/
-
-/*H:260
- * When we make traps go directly into the Guest, we need to make sure
- * the kernel stack is valid (ie. mapped in the page tables). Otherwise, the
- * CPU trying to deliver the trap will fault while trying to push the interrupt
- * words on the stack: this is called a double fault, and it forces us to kill
- * the Guest.
- *
- * Which is deeply unfair, because (literally!) it wasn't the Guests' fault.
- */
-void pin_stack_pages(struct lg_cpu *cpu)
-{
- unsigned int i;
-
- /*
- * Depending on the CONFIG_4KSTACKS option, the Guest can have one or
- * two pages of stack space.
- */
- for (i = 0; i < cpu->lg->stack_pages; i++)
- /*
- * The stack grows *upwards*, so the address we're given is the
- * start of the page after the kernel stack. Subtract one to
- * get back onto the first stack page, and keep subtracting to
- * get to the rest of the stack pages.
- */
- pin_page(cpu, cpu->esp1 - 1 - i * PAGE_SIZE);
-}
-
-/*
- * Direct traps also mean that we need to know whenever the Guest wants to use
- * a different kernel stack, so we can change the guest TSS to use that
- * stack. The TSS entries expect a virtual address, so unlike most addresses
- * the Guest gives us, the "esp" (stack pointer) value here is virtual, not
- * physical.
- *
- * In Linux each process has its own kernel stack, so this happens a lot: we
- * change stacks on each context switch.
- */
-void guest_set_stack(struct lg_cpu *cpu, u32 seg, u32 esp, unsigned int pages)
-{
- /*
- * You're not allowed a stack segment with privilege level 0: bad Guest!
- */
- if ((seg & 0x3) != GUEST_PL)
- kill_guest(cpu, "bad stack segment %i", seg);
- /* We only expect one or two stack pages. */
- if (pages > 2)
- kill_guest(cpu, "bad stack pages %u", pages);
- /* Save where the stack is, and how many pages */
- cpu->ss1 = seg;
- cpu->esp1 = esp;
- cpu->lg->stack_pages = pages;
- /* Make sure the new stack pages are mapped */
- pin_stack_pages(cpu);
-}
-
-/*
- * All this reference to mapping stacks leads us neatly into the other complex
- * part of the Host: page table handling.
- */
-
-/*H:235
- * This is the routine which actually checks the Guest's IDT entry and
- * transfers it into the entry in "struct lguest":
- */
-static void set_trap(struct lg_cpu *cpu, struct desc_struct *trap,
- unsigned int num, u32 lo, u32 hi)
-{
- u8 type = idt_type(lo, hi);
-
- /* We zero-out a not-present entry */
- if (!idt_present(lo, hi)) {
- trap->a = trap->b = 0;
- return;
- }
-
- /* We only support interrupt and trap gates. */
- if (type != 0xE && type != 0xF)
- kill_guest(cpu, "bad IDT type %i", type);
-
- /*
- * We only copy the handler address, present bit, privilege level and
- * type. The privilege level controls where the trap can be triggered
- * manually with an "int" instruction. This is usually GUEST_PL,
- * except for system calls which userspace can use.
- */
- trap->a = ((__KERNEL_CS|GUEST_PL)<<16) | (lo&0x0000FFFF);
- trap->b = (hi&0xFFFFEF00);
-}
-
-/*H:230
- * While we're here, dealing with delivering traps and interrupts to the
- * Guest, we might as well complete the picture: how the Guest tells us where
- * it wants them to go. This would be simple, except making traps fast
- * requires some tricks.
- *
- * We saw the Guest setting Interrupt Descriptor Table (IDT) entries with the
- * LHCALL_LOAD_IDT_ENTRY hypercall before: that comes here.
- */
-void load_guest_idt_entry(struct lg_cpu *cpu, unsigned int num, u32 lo, u32 hi)
-{
- /*
- * Guest never handles: NMI, doublefault, spurious interrupt or
- * hypercall. We ignore when it tries to set them.
- */
- if (num == 2 || num == 8 || num == 15 || num == LGUEST_TRAP_ENTRY)
- return;
-
- /*
- * Mark the IDT as changed: next time the Guest runs we'll know we have
- * to copy this again.
- */
- cpu->changed |= CHANGED_IDT;
-
- /* Check that the Guest doesn't try to step outside the bounds. */
- if (num >= ARRAY_SIZE(cpu->arch.idt))
- kill_guest(cpu, "Setting idt entry %u", num);
- else
- set_trap(cpu, &cpu->arch.idt[num], num, lo, hi);
-}
-
-/*
- * The default entry for each interrupt points into the Switcher routines which
- * simply return to the Host. The run_guest() loop will then call
- * deliver_trap() to bounce it back into the Guest.
- */
-static void default_idt_entry(struct desc_struct *idt,
- int trap,
- const unsigned long handler,
- const struct desc_struct *base)
-{
- /* A present interrupt gate. */
- u32 flags = 0x8e00;
-
- /*
- * Set the privilege level on the entry for the hypercall: this allows
- * the Guest to use the "int" instruction to trigger it.
- */
- if (trap == LGUEST_TRAP_ENTRY)
- flags |= (GUEST_PL << 13);
- else if (base)
- /*
- * Copy privilege level from what Guest asked for. This allows
- * debug (int 3) traps from Guest userspace, for example.
- */
- flags |= (base->b & 0x6000);
-
- /* Now pack it into the IDT entry in its weird format. */
- idt->a = (LGUEST_CS<<16) | (handler&0x0000FFFF);
- idt->b = (handler&0xFFFF0000) | flags;
-}
-
-/* When the Guest first starts, we put default entries into the IDT. */
-void setup_default_idt_entries(struct lguest_ro_state *state,
- const unsigned long *def)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(state->guest_idt); i++)
- default_idt_entry(&state->guest_idt[i], i, def[i], NULL);
-}
-
-/*H:240
- * We don't use the IDT entries in the "struct lguest" directly, instead
- * we copy them into the IDT which we've set up for Guests on this CPU, just
- * before we run the Guest. This routine does that copy.
- */
-void copy_traps(const struct lg_cpu *cpu, struct desc_struct *idt,
- const unsigned long *def)
-{
- unsigned int i;
-
- /*
- * We can simply copy the direct traps, otherwise we use the default
- * ones in the Switcher: they will return to the Host.
- */
- for (i = 0; i < ARRAY_SIZE(cpu->arch.idt); i++) {
- const struct desc_struct *gidt = &cpu->arch.idt[i];
-
- /* If no Guest can ever override this trap, leave it alone. */
- if (!direct_trap(i))
- continue;
-
- /*
- * Only trap gates (type 15) can go direct to the Guest.
- * Interrupt gates (type 14) disable interrupts as they are
- * entered, which we never let the Guest do. Not present
- * entries (type 0x0) also can't go direct, of course.
- *
- * If it can't go direct, we still need to copy the priv. level:
- * they might want to give userspace access to a software
- * interrupt.
- */
- if (idt_type(gidt->a, gidt->b) == 0xF)
- idt[i] = *gidt;
- else
- default_idt_entry(&idt[i], i, def[i], gidt);
- }
-}
-
-/*H:200
- * The Guest Clock.
- *
- * There are two sources of virtual interrupts. We saw one in lguest_user.c:
- * the Launcher sending interrupts for virtual devices. The other is the Guest
- * timer interrupt.
- *
- * The Guest uses the LHCALL_SET_CLOCKEVENT hypercall to tell us how long to
- * the next timer interrupt (in nanoseconds). We use the high-resolution timer
- * infrastructure to set a callback at that time.
- *
- * 0 means "turn off the clock".
- */
-void guest_set_clockevent(struct lg_cpu *cpu, unsigned long delta)
-{
- ktime_t expires;
-
- if (unlikely(delta == 0)) {
- /* Clock event device is shutting down. */
- hrtimer_cancel(&cpu->hrt);
- return;
- }
-
- /*
- * We use wallclock time here, so the Guest might not be running for
- * all the time between now and the timer interrupt it asked for. This
- * is almost always the right thing to do.
- */
- expires = ktime_add_ns(ktime_get_real(), delta);
- hrtimer_start(&cpu->hrt, expires, HRTIMER_MODE_ABS);
-}
-
-/* This is the function called when the Guest's timer expires. */
-static enum hrtimer_restart clockdev_fn(struct hrtimer *timer)
-{
- struct lg_cpu *cpu = container_of(timer, struct lg_cpu, hrt);
-
- /* Remember the first interrupt is the timer interrupt. */
- set_interrupt(cpu, 0);
- return HRTIMER_NORESTART;
-}
-
-/* This sets up the timer for this Guest. */
-void init_clockdev(struct lg_cpu *cpu)
-{
- hrtimer_init(&cpu->hrt, CLOCK_REALTIME, HRTIMER_MODE_ABS);
- cpu->hrt.function = clockdev_fn;
-}
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
deleted file mode 100644
index 2356a23..0000000
--- a/drivers/lguest/lg.h
+++ /dev/null
@@ -1,258 +0,0 @@
-#ifndef _LGUEST_H
-#define _LGUEST_H
-
-#ifndef __ASSEMBLY__
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/stringify.h>
-#include <linux/lguest.h>
-#include <linux/lguest_launcher.h>
-#include <linux/wait.h>
-#include <linux/hrtimer.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-
-#include <asm/lguest.h>
-
-struct pgdir {
- unsigned long gpgdir;
- bool switcher_mapped;
- int last_host_cpu;
- pgd_t *pgdir;
-};
-
-/* We have two pages shared with guests, per cpu. */
-struct lguest_pages {
- /* This is the stack page mapped rw in guest */
- char spare[PAGE_SIZE - sizeof(struct lguest_regs)];
- struct lguest_regs regs;
-
- /* This is the host state & guest descriptor page, ro in guest */
- struct lguest_ro_state state;
-} __attribute__((aligned(PAGE_SIZE)));
-
-#define CHANGED_IDT 1
-#define CHANGED_GDT 2
-#define CHANGED_GDT_TLS 4 /* Actually a subset of CHANGED_GDT */
-#define CHANGED_ALL 3
-
-struct lg_cpu {
- unsigned int id;
- struct lguest *lg;
- struct task_struct *tsk;
- struct mm_struct *mm; /* == tsk->mm, but that becomes NULL on exit */
-
- u32 cr2;
- u32 esp1;
- u16 ss1;
-
- /* Bitmap of what has changed: see CHANGED_* above. */
- int changed;
-
- /* Pending operation. */
- struct lguest_pending pending;
-
- unsigned long *reg_read; /* register from LHREQ_GETREG */
-
- /* At end of a page shared mapped over lguest_pages in guest. */
- unsigned long regs_page;
- struct lguest_regs *regs;
-
- struct lguest_pages *last_pages;
-
- /* Initialization mode: linear map everything. */
- bool linear_pages;
- int cpu_pgd; /* Which pgd this cpu is currently using */
-
- /* If a hypercall was asked for, this points to the arguments. */
- struct hcall_args *hcall;
- u32 next_hcall;
-
- /* Virtual clock device */
- struct hrtimer hrt;
-
- /* Did the Guest tell us to halt? */
- int halted;
-
- /* Pending virtual interrupts */
- DECLARE_BITMAP(irqs_pending, LGUEST_IRQS);
-
- struct lg_cpu_arch arch;
-};
-
-/* The private info the thread maintains about the guest. */
-struct lguest {
- struct lguest_data __user *lguest_data;
- struct lg_cpu cpus[NR_CPUS];
- unsigned int nr_cpus;
-
- /* Valid guest memory pages must be < this. */
- u32 pfn_limit;
-
- /* Device memory is >= pfn_limit and < device_limit. */
- u32 device_limit;
-
- /*
- * This provides the offset to the base of guest-physical memory in the
- * Launcher.
- */
- void __user *mem_base;
- unsigned long kernel_address;
-
- struct pgdir pgdirs[4];
-
- unsigned long noirq_iret;
-
- unsigned int stack_pages;
- u32 tsc_khz;
-
- /* Dead? */
- const char *dead;
-};
-
-extern struct mutex lguest_lock;
-
-/* core.c: */
-bool lguest_address_ok(const struct lguest *lg,
- unsigned long addr, unsigned long len);
-void __lgread(struct lg_cpu *, void *, unsigned long, unsigned);
-void __lgwrite(struct lg_cpu *, unsigned long, const void *, unsigned);
-extern struct page **lg_switcher_pages;
-
-/*H:035
- * Using memory-copy operations like that is usually inconvient, so we
- * have the following helper macros which read and write a specific type (often
- * an unsigned long).
- *
- * This reads into a variable of the given type then returns that.
- */
-#define lgread(cpu, addr, type) \
- ({ type _v; __lgread((cpu), &_v, (addr), sizeof(_v)); _v; })
-
-/* This checks that the variable is of the given type, then writes it out. */
-#define lgwrite(cpu, addr, type, val) \
- do { \
- typecheck(type, val); \
- __lgwrite((cpu), (addr), &(val), sizeof(val)); \
- } while(0)
-/* (end of memory access helper routines) :*/
-
-int run_guest(struct lg_cpu *cpu, unsigned long __user *user);
-
-/*
- * Helper macros to obtain the first 12 or the last 20 bits, this is only the
- * first step in the migration to the kernel types. pte_pfn is already defined
- * in the kernel.
- */
-#define pgd_flags(x) (pgd_val(x) & ~PAGE_MASK)
-#define pgd_pfn(x) (pgd_val(x) >> PAGE_SHIFT)
-#define pmd_flags(x) (pmd_val(x) & ~PAGE_MASK)
-#define pmd_pfn(x) (pmd_val(x) >> PAGE_SHIFT)
-
-/* interrupts_and_traps.c: */
-unsigned int interrupt_pending(struct lg_cpu *cpu, bool *more);
-void try_deliver_interrupt(struct lg_cpu *cpu, unsigned int irq, bool more);
-void set_interrupt(struct lg_cpu *cpu, unsigned int irq);
-bool deliver_trap(struct lg_cpu *cpu, unsigned int num);
-void load_guest_idt_entry(struct lg_cpu *cpu, unsigned int i,
- u32 low, u32 hi);
-void guest_set_stack(struct lg_cpu *cpu, u32 seg, u32 esp, unsigned int pages);
-void pin_stack_pages(struct lg_cpu *cpu);
-void setup_default_idt_entries(struct lguest_ro_state *state,
- const unsigned long *def);
-void copy_traps(const struct lg_cpu *cpu, struct desc_struct *idt,
- const unsigned long *def);
-void guest_set_clockevent(struct lg_cpu *cpu, unsigned long delta);
-bool send_notify_to_eventfd(struct lg_cpu *cpu);
-void init_clockdev(struct lg_cpu *cpu);
-bool check_syscall_vector(struct lguest *lg);
-bool could_be_syscall(unsigned int num);
-int init_interrupts(void);
-void free_interrupts(void);
-
-/* segments.c: */
-void setup_default_gdt_entries(struct lguest_ro_state *state);
-void setup_guest_gdt(struct lg_cpu *cpu);
-void load_guest_gdt_entry(struct lg_cpu *cpu, unsigned int i,
- u32 low, u32 hi);
-void guest_load_tls(struct lg_cpu *cpu, unsigned long tls_array);
-void copy_gdt(const struct lg_cpu *cpu, struct desc_struct *gdt);
-void copy_gdt_tls(const struct lg_cpu *cpu, struct desc_struct *gdt);
-
-/* page_tables.c: */
-int init_guest_pagetable(struct lguest *lg);
-void free_guest_pagetable(struct lguest *lg);
-void guest_new_pagetable(struct lg_cpu *cpu, unsigned long pgtable);
-void guest_set_pgd(struct lguest *lg, unsigned long gpgdir, u32 i);
-#ifdef CONFIG_X86_PAE
-void guest_set_pmd(struct lguest *lg, unsigned long gpgdir, u32 i);
-#endif
-void guest_pagetable_clear_all(struct lg_cpu *cpu);
-void guest_pagetable_flush_user(struct lg_cpu *cpu);
-void guest_set_pte(struct lg_cpu *cpu, unsigned long gpgdir,
- unsigned long vaddr, pte_t val);
-void map_switcher_in_guest(struct lg_cpu *cpu, struct lguest_pages *pages);
-bool demand_page(struct lg_cpu *cpu, unsigned long cr2, int errcode,
- unsigned long *iomem);
-void pin_page(struct lg_cpu *cpu, unsigned long vaddr);
-bool __guest_pa(struct lg_cpu *cpu, unsigned long vaddr, unsigned long *paddr);
-unsigned long guest_pa(struct lg_cpu *cpu, unsigned long vaddr);
-void page_table_guest_data_init(struct lg_cpu *cpu);
-
-/* <arch>/core.c: */
-void lguest_arch_host_init(void);
-void lguest_arch_host_fini(void);
-void lguest_arch_run_guest(struct lg_cpu *cpu);
-void lguest_arch_handle_trap(struct lg_cpu *cpu);
-int lguest_arch_init_hypercalls(struct lg_cpu *cpu);
-int lguest_arch_do_hcall(struct lg_cpu *cpu, struct hcall_args *args);
-void lguest_arch_setup_regs(struct lg_cpu *cpu, unsigned long start);
-unsigned long *lguest_arch_regptr(struct lg_cpu *cpu, size_t reg_off, bool any);
-
-/* <arch>/switcher.S: */
-extern char start_switcher_text[], end_switcher_text[], switch_to_guest[];
-
-/* lguest_user.c: */
-int lguest_device_init(void);
-void lguest_device_remove(void);
-
-/* hypercalls.c: */
-void do_hypercalls(struct lg_cpu *cpu);
-void write_timestamp(struct lg_cpu *cpu);
-
-/*L:035
- * Let's step aside for the moment, to study one important routine that's used
- * widely in the Host code.
- *
- * There are many cases where the Guest can do something invalid, like pass crap
- * to a hypercall. Since only the Guest kernel can make hypercalls, it's quite
- * acceptable to simply terminate the Guest and give the Launcher a nicely
- * formatted reason. It's also simpler for the Guest itself, which doesn't
- * need to check most hypercalls for "success"; if you're still running, it
- * succeeded.
- *
- * Once this is called, the Guest will never run again, so most Host code can
- * call this then continue as if nothing had happened. This means many
- * functions don't have to explicitly return an error code, which keeps the
- * code simple.
- *
- * It also means that this can be called more than once: only the first one is
- * remembered. The only trick is that we still need to kill the Guest even if
- * we can't allocate memory to store the reason. Linux has a neat way of
- * packing error codes into invalid pointers, so we use that here.
- *
- * Like any macro which uses an "if", it is safely wrapped in a run-once "do {
- * } while(0)".
- */
-#define kill_guest(cpu, fmt...) \
-do { \
- if (!(cpu)->lg->dead) { \
- (cpu)->lg->dead = kasprintf(GFP_ATOMIC, fmt); \
- if (!(cpu)->lg->dead) \
- (cpu)->lg->dead = ERR_PTR(-ENOMEM); \
- } \
-} while(0)
-/* (End of aside) :*/
-
-#endif /* __ASSEMBLY__ */
-#endif /* _LGUEST_H */
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
deleted file mode 100644
index 1a6787b..0000000
--- a/drivers/lguest/lguest_user.c
+++ /dev/null
@@ -1,446 +0,0 @@
-/*P:200 This contains all the /dev/lguest code, whereby the userspace
- * launcher controls and communicates with the Guest. For example,
- * the first write will tell us the Guest's memory layout and entry
- * point. A read will run the Guest until something happens, such as
- * a signal or the Guest accessing a device.
-:*/
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/fs.h>
-#include <linux/sched.h>
-#include <linux/sched/mm.h>
-#include <linux/file.h>
-#include <linux/slab.h>
-#include <linux/export.h>
-#include "lg.h"
-
-/*L:052
- The Launcher can get the registers, and also set some of them.
-*/
-static int getreg_setup(struct lg_cpu *cpu, const unsigned long __user *input)
-{
- unsigned long which;
-
- /* We re-use the ptrace structure to specify which register to read. */
- if (get_user(which, input) != 0)
- return -EFAULT;
-
- /*
- * We set up the cpu register pointer, and their next read will
- * actually get the value (instead of running the guest).
- *
- * The last argument 'true' says we can access any register.
- */
- cpu->reg_read = lguest_arch_regptr(cpu, which, true);
- if (!cpu->reg_read)
- return -ENOENT;
-
- /* And because this is a write() call, we return the length used. */
- return sizeof(unsigned long) * 2;
-}
-
-static int setreg(struct lg_cpu *cpu, const unsigned long __user *input)
-{
- unsigned long which, value, *reg;
-
- /* We re-use the ptrace structure to specify which register to read. */
- if (get_user(which, input) != 0)
- return -EFAULT;
- input++;
- if (get_user(value, input) != 0)
- return -EFAULT;
-
- /* The last argument 'false' means we can't access all registers. */
- reg = lguest_arch_regptr(cpu, which, false);
- if (!reg)
- return -ENOENT;
-
- *reg = value;
-
- /* And because this is a write() call, we return the length used. */
- return sizeof(unsigned long) * 3;
-}
-
-/*L:050
- * Sending an interrupt is done by writing LHREQ_IRQ and an interrupt
- * number to /dev/lguest.
- */
-static int user_send_irq(struct lg_cpu *cpu, const unsigned long __user *input)
-{
- unsigned long irq;
-
- if (get_user(irq, input) != 0)
- return -EFAULT;
- if (irq >= LGUEST_IRQS)
- return -EINVAL;
-
- /*
- * Next time the Guest runs, the core code will see if it can deliver
- * this interrupt.
- */
- set_interrupt(cpu, irq);
- return 0;
-}
-
-/*L:053
- * Deliver a trap: this is used by the Launcher if it can't emulate
- * an instruction.
- */
-static int trap(struct lg_cpu *cpu, const unsigned long __user *input)
-{
- unsigned long trapnum;
-
- if (get_user(trapnum, input) != 0)
- return -EFAULT;
-
- if (!deliver_trap(cpu, trapnum))
- return -EINVAL;
-
- return 0;
-}
-
-/*L:040
- * Once our Guest is initialized, the Launcher makes it run by reading
- * from /dev/lguest.
- */
-static ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o)
-{
- struct lguest *lg = file->private_data;
- struct lg_cpu *cpu;
- unsigned int cpu_id = *o;
-
- /* You must write LHREQ_INITIALIZE first! */
- if (!lg)
- return -EINVAL;
-
- /* Watch out for arbitrary vcpu indexes! */
- if (cpu_id >= lg->nr_cpus)
- return -EINVAL;
-
- cpu = &lg->cpus[cpu_id];
-
- /* If you're not the task which owns the Guest, go away. */
- if (current != cpu->tsk)
- return -EPERM;
-
- /* If the Guest is already dead, we indicate why */
- if (lg->dead) {
- size_t len;
-
- /* lg->dead either contains an error code, or a string. */
- if (IS_ERR(lg->dead))
- return PTR_ERR(lg->dead);
-
- /* We can only return as much as the buffer they read with. */
- len = min(size, strlen(lg->dead)+1);
- if (copy_to_user(user, lg->dead, len) != 0)
- return -EFAULT;
- return len;
- }
-
- /*
- * If we returned from read() last time because the Guest sent I/O,
- * clear the flag.
- */
- if (cpu->pending.trap)
- cpu->pending.trap = 0;
-
- /* Run the Guest until something interesting happens. */
- return run_guest(cpu, (unsigned long __user *)user);
-}
-
-/*L:025
- * This actually initializes a CPU. For the moment, a Guest is only
- * uniprocessor, so "id" is always 0.
- */
-static int lg_cpu_start(struct lg_cpu *cpu, unsigned id, unsigned long start_ip)
-{
- /* We have a limited number of CPUs in the lguest struct. */
- if (id >= ARRAY_SIZE(cpu->lg->cpus))
- return -EINVAL;
-
- /* Set up this CPU's id, and pointer back to the lguest struct. */
- cpu->id = id;
- cpu->lg = container_of(cpu, struct lguest, cpus[id]);
- cpu->lg->nr_cpus++;
-
- /* Each CPU has a timer it can set. */
- init_clockdev(cpu);
-
- /*
- * We need a complete page for the Guest registers: they are accessible
- * to the Guest and we can only grant it access to whole pages.
- */
- cpu->regs_page = get_zeroed_page(GFP_KERNEL);
- if (!cpu->regs_page)
- return -ENOMEM;
-
- /* We actually put the registers at the end of the page. */
- cpu->regs = (void *)cpu->regs_page + PAGE_SIZE - sizeof(*cpu->regs);
-
- /*
- * Now we initialize the Guest's registers, handing it the start
- * address.
- */
- lguest_arch_setup_regs(cpu, start_ip);
-
- /*
- * We keep a pointer to the Launcher task (ie. current task) for when
- * other Guests want to wake this one (eg. console input).
- */
- cpu->tsk = current;
-
- /*
- * We need to keep a pointer to the Launcher's memory map, because if
- * the Launcher dies we need to clean it up. If we don't keep a
- * reference, it is destroyed before close() is called.
- */
- cpu->mm = get_task_mm(cpu->tsk);
-
- /*
- * We remember which CPU's pages this Guest used last, for optimization
- * when the same Guest runs on the same CPU twice.
- */
- cpu->last_pages = NULL;
-
- /* No error == success. */
- return 0;
-}
-
-/*L:020
- * The initialization write supplies 3 pointer sized (32 or 64 bit) values (in
- * addition to the LHREQ_INITIALIZE value). These are:
- *
- * base: The start of the Guest-physical memory inside the Launcher memory.
- *
- * pfnlimit: The highest (Guest-physical) page number the Guest should be
- * allowed to access. The Guest memory lives inside the Launcher, so it sets
- * this to ensure the Guest can only reach its own memory.
- *
- * start: The first instruction to execute ("eip" in x86-speak).
- */
-static int initialize(struct file *file, const unsigned long __user *input)
-{
- /* "struct lguest" contains all we (the Host) know about a Guest. */
- struct lguest *lg;
- int err;
- unsigned long args[4];
-
- /*
- * We grab the Big Lguest lock, which protects against multiple
- * simultaneous initializations.
- */
- mutex_lock(&lguest_lock);
- /* You can't initialize twice! Close the device and start again... */
- if (file->private_data) {
- err = -EBUSY;
- goto unlock;
- }
-
- if (copy_from_user(args, input, sizeof(args)) != 0) {
- err = -EFAULT;
- goto unlock;
- }
-
- lg = kzalloc(sizeof(*lg), GFP_KERNEL);
- if (!lg) {
- err = -ENOMEM;
- goto unlock;
- }
-
- /* Populate the easy fields of our "struct lguest" */
- lg->mem_base = (void __user *)args[0];
- lg->pfn_limit = args[1];
- lg->device_limit = args[3];
-
- /* This is the first cpu (cpu 0) and it will start booting at args[2] */
- err = lg_cpu_start(&lg->cpus[0], 0, args[2]);
- if (err)
- goto free_lg;
-
- /*
- * Initialize the Guest's shadow page tables. This allocates
- * memory, so can fail.
- */
- err = init_guest_pagetable(lg);
- if (err)
- goto free_regs;
-
- /* We keep our "struct lguest" in the file's private_data. */
- file->private_data = lg;
-
- mutex_unlock(&lguest_lock);
-
- /* And because this is a write() call, we return the length used. */
- return sizeof(args);
-
-free_regs:
- /* FIXME: This should be in free_vcpu */
- free_page(lg->cpus[0].regs_page);
-free_lg:
- kfree(lg);
-unlock:
- mutex_unlock(&lguest_lock);
- return err;
-}
-
-/*L:010
- * The first operation the Launcher does must be a write. All writes
- * start with an unsigned long number: for the first write this must be
- * LHREQ_INITIALIZE to set up the Guest. After that the Launcher can use
- * writes of other values to send interrupts or set up receipt of notifications.
- *
- * Note that we overload the "offset" in the /dev/lguest file to indicate what
- * CPU number we're dealing with. Currently this is always 0 since we only
- * support uniprocessor Guests, but you can see the beginnings of SMP support
- * here.
- */
-static ssize_t write(struct file *file, const char __user *in,
- size_t size, loff_t *off)
-{
- /*
- * Once the Guest is initialized, we hold the "struct lguest" in the
- * file private data.
- */
- struct lguest *lg = file->private_data;
- const unsigned long __user *input = (const unsigned long __user *)in;
- unsigned long req;
- struct lg_cpu *uninitialized_var(cpu);
- unsigned int cpu_id = *off;
-
- /* The first value tells us what this request is. */
- if (get_user(req, input) != 0)
- return -EFAULT;
- input++;
-
- /* If you haven't initialized, you must do that first. */
- if (req != LHREQ_INITIALIZE) {
- if (!lg || (cpu_id >= lg->nr_cpus))
- return -EINVAL;
- cpu = &lg->cpus[cpu_id];
-
- /* Once the Guest is dead, you can only read() why it died. */
- if (lg->dead)
- return -ENOENT;
- }
-
- switch (req) {
- case LHREQ_INITIALIZE:
- return initialize(file, input);
- case LHREQ_IRQ:
- return user_send_irq(cpu, input);
- case LHREQ_GETREG:
- return getreg_setup(cpu, input);
- case LHREQ_SETREG:
- return setreg(cpu, input);
- case LHREQ_TRAP:
- return trap(cpu, input);
- default:
- return -EINVAL;
- }
-}
-
-static int open(struct inode *inode, struct file *file)
-{
- file->private_data = NULL;
-
- return 0;
-}
-
-/*L:060
- * The final piece of interface code is the close() routine. It reverses
- * everything done in initialize(). This is usually called because the
- * Launcher exited.
- *
- * Note that the close routine returns 0 or a negative error number: it can't
- * really fail, but it can whine. I blame Sun for this wart, and K&R C for
- * letting them do it.
-:*/
-static int close(struct inode *inode, struct file *file)
-{
- struct lguest *lg = file->private_data;
- unsigned int i;
-
- /* If we never successfully initialized, there's nothing to clean up */
- if (!lg)
- return 0;
-
- /*
- * We need the big lock, to protect from inter-guest I/O and other
- * Launchers initializing guests.
- */
- mutex_lock(&lguest_lock);
-
- /* Free up the shadow page tables for the Guest. */
- free_guest_pagetable(lg);
-
- for (i = 0; i < lg->nr_cpus; i++) {
- /* Cancels the hrtimer set via LHCALL_SET_CLOCKEVENT. */
- hrtimer_cancel(&lg->cpus[i].hrt);
- /* We can free up the register page we allocated. */
- free_page(lg->cpus[i].regs_page);
- /*
- * Now all the memory cleanups are done, it's safe to release
- * the Launcher's memory management structure.
- */
- mmput(lg->cpus[i].mm);
- }
-
- /*
- * If lg->dead doesn't contain an error code it will be NULL or a
- * kmalloc()ed string, either of which is ok to hand to kfree().
- */
- if (!IS_ERR(lg->dead))
- kfree(lg->dead);
- /* Free the memory allocated to the lguest_struct */
- kfree(lg);
- /* Release lock and exit. */
- mutex_unlock(&lguest_lock);
-
- return 0;
-}
-
-/*L:000
- * Welcome to our journey through the Launcher!
- *
- * The Launcher is the Host userspace program which sets up, runs and services
- * the Guest. In fact, many comments in the Drivers which refer to "the Host"
- * doing things are inaccurate: the Launcher does all the device handling for
- * the Guest, but the Guest can't know that.
- *
- * Just to confuse you: to the Host kernel, the Launcher *is* the Guest and we
- * shall see more of that later.
- *
- * We begin our understanding with the Host kernel interface which the Launcher
- * uses: reading and writing a character device called /dev/lguest. All the
- * work happens in the read(), write() and close() routines:
- */
-static const struct file_operations lguest_fops = {
- .owner = THIS_MODULE,
- .open = open,
- .release = close,
- .write = write,
- .read = read,
- .llseek = default_llseek,
-};
-/*:*/
-
-/*
- * This is a textbook example of a "misc" character device. Populate a "struct
- * miscdevice" and register it with misc_register().
- */
-static struct miscdevice lguest_dev = {
- .minor = MISC_DYNAMIC_MINOR,
- .name = "lguest",
- .fops = &lguest_fops,
-};
-
-int __init lguest_device_init(void)
-{
- return misc_register(&lguest_dev);
-}
-
-void __exit lguest_device_remove(void)
-{
- misc_deregister(&lguest_dev);
-}
diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
deleted file mode 100644
index 0bc127e..0000000
--- a/drivers/lguest/page_tables.c
+++ /dev/null
@@ -1,1239 +0,0 @@
-/*P:700
- * The pagetable code, on the other hand, still shows the scars of
- * previous encounters. It's functional, and as neat as it can be in the
- * circumstances, but be wary, for these things are subtle and break easily.
- * The Guest provides a virtual to physical mapping, but we can neither trust
- * it nor use it: we verify and convert it here then point the CPU to the
- * converted Guest pages when running the Guest.
-:*/
-
-/* Copyright (C) Rusty Russell IBM Corporation 2013.
- * GPL v2 and any later version */
-#include <linux/mm.h>
-#include <linux/gfp.h>
-#include <linux/types.h>
-#include <linux/spinlock.h>
-#include <linux/random.h>
-#include <linux/percpu.h>
-#include <asm/tlbflush.h>
-#include <linux/uaccess.h>
-#include "lg.h"
-
-/*M:008
- * We hold reference to pages, which prevents them from being swapped.
- * It'd be nice to have a callback in the "struct mm_struct" when Linux wants
- * to swap out. If we had this, and a shrinker callback to trim PTE pages, we
- * could probably consider launching Guests as non-root.
-:*/
-
-/*H:300
- * The Page Table Code
- *
- * We use two-level page tables for the Guest, or three-level with PAE. If
- * you're not entirely comfortable with virtual addresses, physical addresses
- * and page tables then I recommend you review arch/x86/lguest/boot.c's "Page
- * Table Handling" (with diagrams!).
- *
- * The Guest keeps page tables, but we maintain the actual ones here: these are
- * called "shadow" page tables. Which is a very Guest-centric name: these are
- * the real page tables the CPU uses, although we keep them up to date to
- * reflect the Guest's. (See what I mean about weird naming? Since when do
- * shadows reflect anything?)
- *
- * Anyway, this is the most complicated part of the Host code. There are seven
- * parts to this:
- * (i) Looking up a page table entry when the Guest faults,
- * (ii) Making sure the Guest stack is mapped,
- * (iii) Setting up a page table entry when the Guest tells us one has changed,
- * (iv) Switching page tables,
- * (v) Flushing (throwing away) page tables,
- * (vi) Mapping the Switcher when the Guest is about to run,
- * (vii) Setting up the page tables initially.
-:*/
-
-/*
- * The Switcher uses the complete top PTE page. That's 1024 PTE entries (4MB)
- * or 512 PTE entries with PAE (2MB).
- */
-#define SWITCHER_PGD_INDEX (PTRS_PER_PGD - 1)
-
-/*
- * For PAE we need the PMD index as well. We use the last 2MB, so we
- * will need the last pmd entry of the last pmd page.
- */
-#ifdef CONFIG_X86_PAE
-#define CHECK_GPGD_MASK _PAGE_PRESENT
-#else
-#define CHECK_GPGD_MASK _PAGE_TABLE
-#endif
-
-/*H:320
- * The page table code is curly enough to need helper functions to keep it
- * clear and clean. The kernel itself provides many of them; one advantage
- * of insisting that the Guest and Host use the same CONFIG_X86_PAE setting.
- *
- * There are two functions which return pointers to the shadow (aka "real")
- * page tables.
- *
- * spgd_addr() takes the virtual address and returns a pointer to the top-level
- * page directory entry (PGD) for that address. Since we keep track of several
- * page tables, the "i" argument tells us which one we're interested in (it's
- * usually the current one).
- */
-static pgd_t *spgd_addr(struct lg_cpu *cpu, u32 i, unsigned long vaddr)
-{
- unsigned int index = pgd_index(vaddr);
-
- /* Return a pointer index'th pgd entry for the i'th page table. */
- return &cpu->lg->pgdirs[i].pgdir[index];
-}
-
-#ifdef CONFIG_X86_PAE
-/*
- * This routine then takes the PGD entry given above, which contains the
- * address of the PMD page. It then returns a pointer to the PMD entry for the
- * given address.
- */
-static pmd_t *spmd_addr(struct lg_cpu *cpu, pgd_t spgd, unsigned long vaddr)
-{
- unsigned int index = pmd_index(vaddr);
- pmd_t *page;
-
- /* You should never call this if the PGD entry wasn't valid */
- BUG_ON(!(pgd_flags(spgd) & _PAGE_PRESENT));
- page = __va(pgd_pfn(spgd) << PAGE_SHIFT);
-
- return &page[index];
-}
-#endif
-
-/*
- * This routine then takes the page directory entry returned above, which
- * contains the address of the page table entry (PTE) page. It then returns a
- * pointer to the PTE entry for the given address.
- */
-static pte_t *spte_addr(struct lg_cpu *cpu, pgd_t spgd, unsigned long vaddr)
-{
-#ifdef CONFIG_X86_PAE
- pmd_t *pmd = spmd_addr(cpu, spgd, vaddr);
- pte_t *page = __va(pmd_pfn(*pmd) << PAGE_SHIFT);
-
- /* You should never call this if the PMD entry wasn't valid */
- BUG_ON(!(pmd_flags(*pmd) & _PAGE_PRESENT));
-#else
- pte_t *page = __va(pgd_pfn(spgd) << PAGE_SHIFT);
- /* You should never call this if the PGD entry wasn't valid */
- BUG_ON(!(pgd_flags(spgd) & _PAGE_PRESENT));
-#endif
-
- return &page[pte_index(vaddr)];
-}
-
-/*
- * These functions are just like the above, except they access the Guest
- * page tables. Hence they return a Guest address.
- */
-static unsigned long gpgd_addr(struct lg_cpu *cpu, unsigned long vaddr)
-{
- unsigned int index = vaddr >> (PGDIR_SHIFT);
- return cpu->lg->pgdirs[cpu->cpu_pgd].gpgdir + index * sizeof(pgd_t);
-}
-
-#ifdef CONFIG_X86_PAE
-/* Follow the PGD to the PMD. */
-static unsigned long gpmd_addr(pgd_t gpgd, unsigned long vaddr)
-{
- unsigned long gpage = pgd_pfn(gpgd) << PAGE_SHIFT;
- BUG_ON(!(pgd_flags(gpgd) & _PAGE_PRESENT));
- return gpage + pmd_index(vaddr) * sizeof(pmd_t);
-}
-
-/* Follow the PMD to the PTE. */
-static unsigned long gpte_addr(struct lg_cpu *cpu,
- pmd_t gpmd, unsigned long vaddr)
-{
- unsigned long gpage = pmd_pfn(gpmd) << PAGE_SHIFT;
-
- BUG_ON(!(pmd_flags(gpmd) & _PAGE_PRESENT));
- return gpage + pte_index(vaddr) * sizeof(pte_t);
-}
-#else
-/* Follow the PGD to the PTE (no mid-level for !PAE). */
-static unsigned long gpte_addr(struct lg_cpu *cpu,
- pgd_t gpgd, unsigned long vaddr)
-{
- unsigned long gpage = pgd_pfn(gpgd) << PAGE_SHIFT;
-
- BUG_ON(!(pgd_flags(gpgd) & _PAGE_PRESENT));
- return gpage + pte_index(vaddr) * sizeof(pte_t);
-}
-#endif
-/*:*/
-
-/*M:007
- * get_pfn is slow: we could probably try to grab batches of pages here as
- * an optimization (ie. pre-faulting).
-:*/
-
-/*H:350
- * This routine takes a page number given by the Guest and converts it to
- * an actual, physical page number. It can fail for several reasons: the
- * virtual address might not be mapped by the Launcher, the write flag is set
- * and the page is read-only, or the write flag was set and the page was
- * shared so had to be copied, but we ran out of memory.
- *
- * This holds a reference to the page, so release_pte() is careful to put that
- * back.
- */
-static unsigned long get_pfn(unsigned long virtpfn, int write)
-{
- struct page *page;
-
- /* gup me one page at this address please! */
- if (get_user_pages_fast(virtpfn << PAGE_SHIFT, 1, write, &page) == 1)
- return page_to_pfn(page);
-
- /* This value indicates failure. */
- return -1UL;
-}
-
-/*H:340
- * Converting a Guest page table entry to a shadow (ie. real) page table
- * entry can be a little tricky. The flags are (almost) the same, but the
- * Guest PTE contains a virtual page number: the CPU needs the real page
- * number.
- */
-static pte_t gpte_to_spte(struct lg_cpu *cpu, pte_t gpte, int write)
-{
- unsigned long pfn, base, flags;
-
- /*
- * The Guest sets the global flag, because it thinks that it is using
- * PGE. We only told it to use PGE so it would tell us whether it was
- * flushing a kernel mapping or a userspace mapping. We don't actually
- * use the global bit, so throw it away.
- */
- flags = (pte_flags(gpte) & ~_PAGE_GLOBAL);
-
- /* The Guest's pages are offset inside the Launcher. */
- base = (unsigned long)cpu->lg->mem_base / PAGE_SIZE;
-
- /*
- * We need a temporary "unsigned long" variable to hold the answer from
- * get_pfn(), because it returns 0xFFFFFFFF on failure, which wouldn't
- * fit in spte.pfn. get_pfn() finds the real physical number of the
- * page, given the virtual number.
- */
- pfn = get_pfn(base + pte_pfn(gpte), write);
- if (pfn == -1UL) {
- kill_guest(cpu, "failed to get page %lu", pte_pfn(gpte));
- /*
- * When we destroy the Guest, we'll go through the shadow page
- * tables and release_pte() them. Make sure we don't think
- * this one is valid!
- */
- flags = 0;
- }
- /* Now we assemble our shadow PTE from the page number and flags. */
- return pfn_pte(pfn, __pgprot(flags));
-}
-
-/*H:460 And to complete the chain, release_pte() looks like this: */
-static void release_pte(pte_t pte)
-{
- /*
- * Remember that get_user_pages_fast() took a reference to the page, in
- * get_pfn()? We have to put it back now.
- */
- if (pte_flags(pte) & _PAGE_PRESENT)
- put_page(pte_page(pte));
-}
-/*:*/
-
-static bool gpte_in_iomem(struct lg_cpu *cpu, pte_t gpte)
-{
- /* We don't handle large pages. */
- if (pte_flags(gpte) & _PAGE_PSE)
- return false;
-
- return (pte_pfn(gpte) >= cpu->lg->pfn_limit
- && pte_pfn(gpte) < cpu->lg->device_limit);
-}
-
-static bool check_gpte(struct lg_cpu *cpu, pte_t gpte)
-{
- if ((pte_flags(gpte) & _PAGE_PSE) ||
- pte_pfn(gpte) >= cpu->lg->pfn_limit) {
- kill_guest(cpu, "bad page table entry");
- return false;
- }
- return true;
-}
-
-static bool check_gpgd(struct lg_cpu *cpu, pgd_t gpgd)
-{
- if ((pgd_flags(gpgd) & ~CHECK_GPGD_MASK) ||
- (pgd_pfn(gpgd) >= cpu->lg->pfn_limit)) {
- kill_guest(cpu, "bad page directory entry");
- return false;
- }
- return true;
-}
-
-#ifdef CONFIG_X86_PAE
-static bool check_gpmd(struct lg_cpu *cpu, pmd_t gpmd)
-{
- if ((pmd_flags(gpmd) & ~_PAGE_TABLE) ||
- (pmd_pfn(gpmd) >= cpu->lg->pfn_limit)) {
- kill_guest(cpu, "bad page middle directory entry");
- return false;
- }
- return true;
-}
-#endif
-
-/*H:331
- * This is the core routine to walk the shadow page tables and find the page
- * table entry for a specific address.
- *
- * If allocate is set, then we allocate any missing levels, setting the flags
- * on the new page directory and mid-level directories using the arguments
- * (which are copied from the Guest's page table entries).
- */
-static pte_t *find_spte(struct lg_cpu *cpu, unsigned long vaddr, bool allocate,
- int pgd_flags, int pmd_flags)
-{
- pgd_t *spgd;
- /* Mid level for PAE. */
-#ifdef CONFIG_X86_PAE
- pmd_t *spmd;
-#endif
-
- /* Get top level entry. */
- spgd = spgd_addr(cpu, cpu->cpu_pgd, vaddr);
- if (!(pgd_flags(*spgd) & _PAGE_PRESENT)) {
- /* No shadow entry: allocate a new shadow PTE page. */
- unsigned long ptepage;
-
- /* If they didn't want us to allocate anything, stop. */
- if (!allocate)
- return NULL;
-
- ptepage = get_zeroed_page(GFP_KERNEL);
- /*
- * This is not really the Guest's fault, but killing it is
- * simple for this corner case.
- */
- if (!ptepage) {
- kill_guest(cpu, "out of memory allocating pte page");
- return NULL;
- }
- /*
- * And we copy the flags to the shadow PGD entry. The page
- * number in the shadow PGD is the page we just allocated.
- */
- set_pgd(spgd, __pgd(__pa(ptepage) | pgd_flags));
- }
-
- /*
- * Intel's Physical Address Extension actually uses three levels of
- * page tables, so we need to look in the mid-level.
- */
-#ifdef CONFIG_X86_PAE
- /* Now look at the mid-level shadow entry. */
- spmd = spmd_addr(cpu, *spgd, vaddr);
-
- if (!(pmd_flags(*spmd) & _PAGE_PRESENT)) {
- /* No shadow entry: allocate a new shadow PTE page. */
- unsigned long ptepage;
-
- /* If they didn't want us to allocate anything, stop. */
- if (!allocate)
- return NULL;
-
- ptepage = get_zeroed_page(GFP_KERNEL);
-
- /*
- * This is not really the Guest's fault, but killing it is
- * simple for this corner case.
- */
- if (!ptepage) {
- kill_guest(cpu, "out of memory allocating pmd page");
- return NULL;
- }
-
- /*
- * And we copy the flags to the shadow PMD entry. The page
- * number in the shadow PMD is the page we just allocated.
- */
- set_pmd(spmd, __pmd(__pa(ptepage) | pmd_flags));
- }
-#endif
-
- /* Get the pointer to the shadow PTE entry we're going to set. */
- return spte_addr(cpu, *spgd, vaddr);
-}
-
-/*H:330
- * (i) Looking up a page table entry when the Guest faults.
- *
- * We saw this call in run_guest(): when we see a page fault in the Guest, we
- * come here. That's because we only set up the shadow page tables lazily as
- * they're needed, so we get page faults all the time and quietly fix them up
- * and return to the Guest without it knowing.
- *
- * If we fixed up the fault (ie. we mapped the address), this routine returns
- * true. Otherwise, it was a real fault and we need to tell the Guest.
- *
- * There's a corner case: they're trying to access memory between
- * pfn_limit and device_limit, which is I/O memory. In this case, we
- * return false and set @iomem to the physical address, so the the
- * Launcher can handle the instruction manually.
- */
-bool demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode,
- unsigned long *iomem)
-{
- unsigned long gpte_ptr;
- pte_t gpte;
- pte_t *spte;
- pmd_t gpmd;
- pgd_t gpgd;
-
- *iomem = 0;
-
- /* We never demand page the Switcher, so trying is a mistake. */
- if (vaddr >= switcher_addr)
- return false;
-
- /* First step: get the top-level Guest page table entry. */
- if (unlikely(cpu->linear_pages)) {
- /* Faking up a linear mapping. */
- gpgd = __pgd(CHECK_GPGD_MASK);
- } else {
- gpgd = lgread(cpu, gpgd_addr(cpu, vaddr), pgd_t);
- /* Toplevel not present? We can't map it in. */
- if (!(pgd_flags(gpgd) & _PAGE_PRESENT))
- return false;
-
- /*
- * This kills the Guest if it has weird flags or tries to
- * refer to a "physical" address outside the bounds.
- */
- if (!check_gpgd(cpu, gpgd))
- return false;
- }
-
- /* This "mid-level" entry is only used for non-linear, PAE mode. */
- gpmd = __pmd(_PAGE_TABLE);
-
-#ifdef CONFIG_X86_PAE
- if (likely(!cpu->linear_pages)) {
- gpmd = lgread(cpu, gpmd_addr(gpgd, vaddr), pmd_t);
- /* Middle level not present? We can't map it in. */
- if (!(pmd_flags(gpmd) & _PAGE_PRESENT))
- return false;
-
- /*
- * This kills the Guest if it has weird flags or tries to
- * refer to a "physical" address outside the bounds.
- */
- if (!check_gpmd(cpu, gpmd))
- return false;
- }
-
- /*
- * OK, now we look at the lower level in the Guest page table: keep its
- * address, because we might update it later.
- */
- gpte_ptr = gpte_addr(cpu, gpmd, vaddr);
-#else
- /*
- * OK, now we look at the lower level in the Guest page table: keep its
- * address, because we might update it later.
- */
- gpte_ptr = gpte_addr(cpu, gpgd, vaddr);
-#endif
-
- if (unlikely(cpu->linear_pages)) {
- /* Linear? Make up a PTE which points to same page. */
- gpte = __pte((vaddr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
- } else {
- /* Read the actual PTE value. */
- gpte = lgread(cpu, gpte_ptr, pte_t);
- }
-
- /* If this page isn't in the Guest page tables, we can't page it in. */
- if (!(pte_flags(gpte) & _PAGE_PRESENT))
- return false;
-
- /*
- * Check they're not trying to write to a page the Guest wants
- * read-only (bit 2 of errcode == write).
- */
- if ((errcode & 2) && !(pte_flags(gpte) & _PAGE_RW))
- return false;
-
- /* User access to a kernel-only page? (bit 3 == user access) */
- if ((errcode & 4) && !(pte_flags(gpte) & _PAGE_USER))
- return false;
-
- /* If they're accessing io memory, we expect a fault. */
- if (gpte_in_iomem(cpu, gpte)) {
- *iomem = (pte_pfn(gpte) << PAGE_SHIFT) | (vaddr & ~PAGE_MASK);
- return false;
- }
-
- /*
- * Check that the Guest PTE flags are OK, and the page number is below
- * the pfn_limit (ie. not mapping the Launcher binary).
- */
- if (!check_gpte(cpu, gpte))
- return false;
-
- /* Add the _PAGE_ACCESSED and (for a write) _PAGE_DIRTY flag */
- gpte = pte_mkyoung(gpte);
- if (errcode & 2)
- gpte = pte_mkdirty(gpte);
-
- /* Get the pointer to the shadow PTE entry we're going to set. */
- spte = find_spte(cpu, vaddr, true, pgd_flags(gpgd), pmd_flags(gpmd));
- if (!spte)
- return false;
-
- /*
- * If there was a valid shadow PTE entry here before, we release it.
- * This can happen with a write to a previously read-only entry.
- */
- release_pte(*spte);
-
- /*
- * If this is a write, we insist that the Guest page is writable (the
- * final arg to gpte_to_spte()).
- */
- if (pte_dirty(gpte))
- *spte = gpte_to_spte(cpu, gpte, 1);
- else
- /*
- * If this is a read, don't set the "writable" bit in the page
- * table entry, even if the Guest says it's writable. That way
- * we will come back here when a write does actually occur, so
- * we can update the Guest's _PAGE_DIRTY flag.
- */
- set_pte(spte, gpte_to_spte(cpu, pte_wrprotect(gpte), 0));
-
- /*
- * Finally, we write the Guest PTE entry back: we've set the
- * _PAGE_ACCESSED and maybe the _PAGE_DIRTY flags.
- */
- if (likely(!cpu->linear_pages))
- lgwrite(cpu, gpte_ptr, pte_t, gpte);
-
- /*
- * The fault is fixed, the page table is populated, the mapping
- * manipulated, the result returned and the code complete. A small
- * delay and a trace of alliteration are the only indications the Guest
- * has that a page fault occurred at all.
- */
- return true;
-}
-
-/*H:360
- * (ii) Making sure the Guest stack is mapped.
- *
- * Remember that direct traps into the Guest need a mapped Guest kernel stack.
- * pin_stack_pages() calls us here: we could simply call demand_page(), but as
- * we've seen that logic is quite long, and usually the stack pages are already
- * mapped, so it's overkill.
- *
- * This is a quick version which answers the question: is this virtual address
- * mapped by the shadow page tables, and is it writable?
- */
-static bool page_writable(struct lg_cpu *cpu, unsigned long vaddr)
-{
- pte_t *spte;
- unsigned long flags;
-
- /* You can't put your stack in the Switcher! */
- if (vaddr >= switcher_addr)
- return false;
-
- /* If there's no shadow PTE, it's not writable. */
- spte = find_spte(cpu, vaddr, false, 0, 0);
- if (!spte)
- return false;
-
- /*
- * Check the flags on the pte entry itself: it must be present and
- * writable.
- */
- flags = pte_flags(*spte);
- return (flags & (_PAGE_PRESENT|_PAGE_RW)) == (_PAGE_PRESENT|_PAGE_RW);
-}
-
-/*
- * So, when pin_stack_pages() asks us to pin a page, we check if it's already
- * in the page tables, and if not, we call demand_page() with error code 2
- * (meaning "write").
- */
-void pin_page(struct lg_cpu *cpu, unsigned long vaddr)
-{
- unsigned long iomem;
-
- if (!page_writable(cpu, vaddr) && !demand_page(cpu, vaddr, 2, &iomem))
- kill_guest(cpu, "bad stack page %#lx", vaddr);
-}
-/*:*/
-
-#ifdef CONFIG_X86_PAE
-static void release_pmd(pmd_t *spmd)
-{
- /* If the entry's not present, there's nothing to release. */
- if (pmd_flags(*spmd) & _PAGE_PRESENT) {
- unsigned int i;
- pte_t *ptepage = __va(pmd_pfn(*spmd) << PAGE_SHIFT);
- /* For each entry in the page, we might need to release it. */
- for (i = 0; i < PTRS_PER_PTE; i++)
- release_pte(ptepage[i]);
- /* Now we can free the page of PTEs */
- free_page((long)ptepage);
- /* And zero out the PMD entry so we never release it twice. */
- set_pmd(spmd, __pmd(0));
- }
-}
-
-static void release_pgd(pgd_t *spgd)
-{
- /* If the entry's not present, there's nothing to release. */
- if (pgd_flags(*spgd) & _PAGE_PRESENT) {
- unsigned int i;
- pmd_t *pmdpage = __va(pgd_pfn(*spgd) << PAGE_SHIFT);
-
- for (i = 0; i < PTRS_PER_PMD; i++)
- release_pmd(&pmdpage[i]);
-
- /* Now we can free the page of PMDs */
- free_page((long)pmdpage);
- /* And zero out the PGD entry so we never release it twice. */
- set_pgd(spgd, __pgd(0));
- }
-}
-
-#else /* !CONFIG_X86_PAE */
-/*H:450
- * If we chase down the release_pgd() code, the non-PAE version looks like
- * this. The PAE version is almost identical, but instead of calling
- * release_pte it calls release_pmd(), which looks much like this.
- */
-static void release_pgd(pgd_t *spgd)
-{
- /* If the entry's not present, there's nothing to release. */
- if (pgd_flags(*spgd) & _PAGE_PRESENT) {
- unsigned int i;
- /*
- * Converting the pfn to find the actual PTE page is easy: turn
- * the page number into a physical address, then convert to a
- * virtual address (easy for kernel pages like this one).
- */
- pte_t *ptepage = __va(pgd_pfn(*spgd) << PAGE_SHIFT);
- /* For each entry in the page, we might need to release it. */
- for (i = 0; i < PTRS_PER_PTE; i++)
- release_pte(ptepage[i]);
- /* Now we can free the page of PTEs */
- free_page((long)ptepage);
- /* And zero out the PGD entry so we never release it twice. */
- *spgd = __pgd(0);
- }
-}
-#endif
-
-/*H:445
- * We saw flush_user_mappings() twice: once from the flush_user_mappings()
- * hypercall and once in new_pgdir() when we re-used a top-level pgdir page.
- * It simply releases every PTE page from 0 up to the Guest's kernel address.
- */
-static void flush_user_mappings(struct lguest *lg, int idx)
-{
- unsigned int i;
- /* Release every pgd entry up to the kernel's address. */
- for (i = 0; i < pgd_index(lg->kernel_address); i++)
- release_pgd(lg->pgdirs[idx].pgdir + i);
-}
-
-/*H:440
- * (v) Flushing (throwing away) page tables,
- *
- * The Guest has a hypercall to throw away the page tables: it's used when a
- * large number of mappings have been changed.
- */
-void guest_pagetable_flush_user(struct lg_cpu *cpu)
-{
- /* Drop the userspace part of the current page table. */
- flush_user_mappings(cpu->lg, cpu->cpu_pgd);
-}
-/*:*/
-
-/* We walk down the guest page tables to get a guest-physical address */
-bool __guest_pa(struct lg_cpu *cpu, unsigned long vaddr, unsigned long *paddr)
-{
- pgd_t gpgd;
- pte_t gpte;
-#ifdef CONFIG_X86_PAE
- pmd_t gpmd;
-#endif
-
- /* Still not set up? Just map 1:1. */
- if (unlikely(cpu->linear_pages)) {
- *paddr = vaddr;
- return true;
- }
-
- /* First step: get the top-level Guest page table entry. */
- gpgd = lgread(cpu, gpgd_addr(cpu, vaddr), pgd_t);
- /* Toplevel not present? We can't map it in. */
- if (!(pgd_flags(gpgd) & _PAGE_PRESENT))
- goto fail;
-
-#ifdef CONFIG_X86_PAE
- gpmd = lgread(cpu, gpmd_addr(gpgd, vaddr), pmd_t);
- if (!(pmd_flags(gpmd) & _PAGE_PRESENT))
- goto fail;
- gpte = lgread(cpu, gpte_addr(cpu, gpmd, vaddr), pte_t);
-#else
- gpte = lgread(cpu, gpte_addr(cpu, gpgd, vaddr), pte_t);
-#endif
- if (!(pte_flags(gpte) & _PAGE_PRESENT))
- goto fail;
-
- *paddr = pte_pfn(gpte) * PAGE_SIZE | (vaddr & ~PAGE_MASK);
- return true;
-
-fail:
- *paddr = -1UL;
- return false;
-}
-
-/*
- * This is the version we normally use: kills the Guest if it uses a
- * bad address
- */
-unsigned long guest_pa(struct lg_cpu *cpu, unsigned long vaddr)
-{
- unsigned long paddr;
-
- if (!__guest_pa(cpu, vaddr, &paddr))
- kill_guest(cpu, "Bad address %#lx", vaddr);
- return paddr;
-}
-
-/*
- * We keep several page tables. This is a simple routine to find the page
- * table (if any) corresponding to this top-level address the Guest has given
- * us.
- */
-static unsigned int find_pgdir(struct lguest *lg, unsigned long pgtable)
-{
- unsigned int i;
- for (i = 0; i < ARRAY_SIZE(lg->pgdirs); i++)
- if (lg->pgdirs[i].pgdir && lg->pgdirs[i].gpgdir == pgtable)
- break;
- return i;
-}
-
-/*H:435
- * And this is us, creating the new page directory. If we really do
- * allocate a new one (and so the kernel parts are not there), we set
- * blank_pgdir.
- */
-static unsigned int new_pgdir(struct lg_cpu *cpu,
- unsigned long gpgdir,
- int *blank_pgdir)
-{
- unsigned int next;
-
- /*
- * We pick one entry at random to throw out. Choosing the Least
- * Recently Used might be better, but this is easy.
- */
- next = prandom_u32() % ARRAY_SIZE(cpu->lg->pgdirs);
- /* If it's never been allocated at all before, try now. */
- if (!cpu->lg->pgdirs[next].pgdir) {
- cpu->lg->pgdirs[next].pgdir =
- (pgd_t *)get_zeroed_page(GFP_KERNEL);
- /* If the allocation fails, just keep using the one we have */
- if (!cpu->lg->pgdirs[next].pgdir)
- next = cpu->cpu_pgd;
- else {
- /*
- * This is a blank page, so there are no kernel
- * mappings: caller must map the stack!
- */
- *blank_pgdir = 1;
- }
- }
- /* Record which Guest toplevel this shadows. */
- cpu->lg->pgdirs[next].gpgdir = gpgdir;
- /* Release all the non-kernel mappings. */
- flush_user_mappings(cpu->lg, next);
-
- /* This hasn't run on any CPU at all. */
- cpu->lg->pgdirs[next].last_host_cpu = -1;
-
- return next;
-}
-
-/*H:501
- * We do need the Switcher code mapped at all times, so we allocate that
- * part of the Guest page table here. We map the Switcher code immediately,
- * but defer mapping of the guest register page and IDT/LDT etc page until
- * just before we run the guest in map_switcher_in_guest().
- *
- * We *could* do this setup in map_switcher_in_guest(), but at that point
- * we've interrupts disabled, and allocating pages like that is fraught: we
- * can't sleep if we need to free up some memory.
- */
-static bool allocate_switcher_mapping(struct lg_cpu *cpu)
-{
- int i;
-
- for (i = 0; i < TOTAL_SWITCHER_PAGES; i++) {
- pte_t *pte = find_spte(cpu, switcher_addr + i * PAGE_SIZE, true,
- CHECK_GPGD_MASK, _PAGE_TABLE);
- if (!pte)
- return false;
-
- /*
- * Map the switcher page if not already there. It might
- * already be there because we call allocate_switcher_mapping()
- * in guest_set_pgd() just in case it did discard our Switcher
- * mapping, but it probably didn't.
- */
- if (i == 0 && !(pte_flags(*pte) & _PAGE_PRESENT)) {
- /* Get a reference to the Switcher page. */
- get_page(lg_switcher_pages[0]);
- /* Create a read-only, exectuable, kernel-style PTE */
- set_pte(pte,
- mk_pte(lg_switcher_pages[0], PAGE_KERNEL_RX));
- }
- }
- cpu->lg->pgdirs[cpu->cpu_pgd].switcher_mapped = true;
- return true;
-}
-
-/*H:470
- * Finally, a routine which throws away everything: all PGD entries in all
- * the shadow page tables, including the Guest's kernel mappings. This is used
- * when we destroy the Guest.
- */
-static void release_all_pagetables(struct lguest *lg)
-{
- unsigned int i, j;
-
- /* Every shadow pagetable this Guest has */
- for (i = 0; i < ARRAY_SIZE(lg->pgdirs); i++) {
- if (!lg->pgdirs[i].pgdir)
- continue;
-
- /* Every PGD entry. */
- for (j = 0; j < PTRS_PER_PGD; j++)
- release_pgd(lg->pgdirs[i].pgdir + j);
- lg->pgdirs[i].switcher_mapped = false;
- lg->pgdirs[i].last_host_cpu = -1;
- }
-}
-
-/*
- * We also throw away everything when a Guest tells us it's changed a kernel
- * mapping. Since kernel mappings are in every page table, it's easiest to
- * throw them all away. This traps the Guest in amber for a while as
- * everything faults back in, but it's rare.
- */
-void guest_pagetable_clear_all(struct lg_cpu *cpu)
-{
- release_all_pagetables(cpu->lg);
- /* We need the Guest kernel stack mapped again. */
- pin_stack_pages(cpu);
- /* And we need Switcher allocated. */
- if (!allocate_switcher_mapping(cpu))
- kill_guest(cpu, "Cannot populate switcher mapping");
-}
-
-/*H:430
- * (iv) Switching page tables
- *
- * Now we've seen all the page table setting and manipulation, let's see
- * what happens when the Guest changes page tables (ie. changes the top-level
- * pgdir). This occurs on almost every context switch.
- */
-void guest_new_pagetable(struct lg_cpu *cpu, unsigned long pgtable)
-{
- int newpgdir, repin = 0;
-
- /*
- * The very first time they call this, we're actually running without
- * any page tables; we've been making it up. Throw them away now.
- */
- if (unlikely(cpu->linear_pages)) {
- release_all_pagetables(cpu->lg);
- cpu->linear_pages = false;
- /* Force allocation of a new pgdir. */
- newpgdir = ARRAY_SIZE(cpu->lg->pgdirs);
- } else {
- /* Look to see if we have this one already. */
- newpgdir = find_pgdir(cpu->lg, pgtable);
- }
-
- /*
- * If not, we allocate or mug an existing one: if it's a fresh one,
- * repin gets set to 1.
- */
- if (newpgdir == ARRAY_SIZE(cpu->lg->pgdirs))
- newpgdir = new_pgdir(cpu, pgtable, &repin);
- /* Change the current pgd index to the new one. */
- cpu->cpu_pgd = newpgdir;
- /*
- * If it was completely blank, we map in the Guest kernel stack and
- * the Switcher.
- */
- if (repin)
- pin_stack_pages(cpu);
-
- if (!cpu->lg->pgdirs[cpu->cpu_pgd].switcher_mapped) {
- if (!allocate_switcher_mapping(cpu))
- kill_guest(cpu, "Cannot populate switcher mapping");
- }
-}
-/*:*/
-
-/*M:009
- * Since we throw away all mappings when a kernel mapping changes, our
- * performance sucks for guests using highmem. In fact, a guest with
- * PAGE_OFFSET 0xc0000000 (the default) and more than about 700MB of RAM is
- * usually slower than a Guest with less memory.
- *
- * This, of course, cannot be fixed. It would take some kind of... well, I
- * don't know, but the term "puissant code-fu" comes to mind.
-:*/
-
-/*H:420
- * This is the routine which actually sets the page table entry for then
- * "idx"'th shadow page table.
- *
- * Normally, we can just throw out the old entry and replace it with 0: if they
- * use it demand_page() will put the new entry in. We need to do this anyway:
- * The Guest expects _PAGE_ACCESSED to be set on its PTE the first time a page
- * is read from, and _PAGE_DIRTY when it's written to.
- *
- * But Avi Kivity pointed out that most Operating Systems (Linux included) set
- * these bits on PTEs immediately anyway. This is done to save the CPU from
- * having to update them, but it helps us the same way: if they set
- * _PAGE_ACCESSED then we can put a read-only PTE entry in immediately, and if
- * they set _PAGE_DIRTY then we can put a writable PTE entry in immediately.
- */
-static void __guest_set_pte(struct lg_cpu *cpu, int idx,
- unsigned long vaddr, pte_t gpte)
-{
- /* Look up the matching shadow page directory entry. */
- pgd_t *spgd = spgd_addr(cpu, idx, vaddr);
-#ifdef CONFIG_X86_PAE
- pmd_t *spmd;
-#endif
-
- /* If the top level isn't present, there's no entry to update. */
- if (pgd_flags(*spgd) & _PAGE_PRESENT) {
-#ifdef CONFIG_X86_PAE
- spmd = spmd_addr(cpu, *spgd, vaddr);
- if (pmd_flags(*spmd) & _PAGE_PRESENT) {
-#endif
- /* Otherwise, start by releasing the existing entry. */
- pte_t *spte = spte_addr(cpu, *spgd, vaddr);
- release_pte(*spte);
-
- /*
- * If they're setting this entry as dirty or accessed,
- * we might as well put that entry they've given us in
- * now. This shaves 10% off a copy-on-write
- * micro-benchmark.
- */
- if ((pte_flags(gpte) & (_PAGE_DIRTY | _PAGE_ACCESSED))
- && !gpte_in_iomem(cpu, gpte)) {
- if (!check_gpte(cpu, gpte))
- return;
- set_pte(spte,
- gpte_to_spte(cpu, gpte,
- pte_flags(gpte) & _PAGE_DIRTY));
- } else {
- /*
- * Otherwise kill it and we can demand_page()
- * it in later.
- */
- set_pte(spte, __pte(0));
- }
-#ifdef CONFIG_X86_PAE
- }
-#endif
- }
-}
-
-/*H:410
- * Updating a PTE entry is a little trickier.
- *
- * We keep track of several different page tables (the Guest uses one for each
- * process, so it makes sense to cache at least a few). Each of these have
- * identical kernel parts: ie. every mapping above PAGE_OFFSET is the same for
- * all processes. So when the page table above that address changes, we update
- * all the page tables, not just the current one. This is rare.
- *
- * The benefit is that when we have to track a new page table, we can keep all
- * the kernel mappings. This speeds up context switch immensely.
- */
-void guest_set_pte(struct lg_cpu *cpu,
- unsigned long gpgdir, unsigned long vaddr, pte_t gpte)
-{
- /* We don't let you remap the Switcher; we need it to get back! */
- if (vaddr >= switcher_addr) {
- kill_guest(cpu, "attempt to set pte into Switcher pages");
- return;
- }
-
- /*
- * Kernel mappings must be changed on all top levels. Slow, but doesn't
- * happen often.
- */
- if (vaddr >= cpu->lg->kernel_address) {
- unsigned int i;
- for (i = 0; i < ARRAY_SIZE(cpu->lg->pgdirs); i++)
- if (cpu->lg->pgdirs[i].pgdir)
- __guest_set_pte(cpu, i, vaddr, gpte);
- } else {
- /* Is this page table one we have a shadow for? */
- int pgdir = find_pgdir(cpu->lg, gpgdir);
- if (pgdir != ARRAY_SIZE(cpu->lg->pgdirs))
- /* If so, do the update. */
- __guest_set_pte(cpu, pgdir, vaddr, gpte);
- }
-}
-
-/*H:400
- * (iii) Setting up a page table entry when the Guest tells us one has changed.
- *
- * Just like we did in interrupts_and_traps.c, it makes sense for us to deal
- * with the other side of page tables while we're here: what happens when the
- * Guest asks for a page table to be updated?
- *
- * We already saw that demand_page() will fill in the shadow page tables when
- * needed, so we can simply remove shadow page table entries whenever the Guest
- * tells us they've changed. When the Guest tries to use the new entry it will
- * fault and demand_page() will fix it up.
- *
- * So with that in mind here's our code to update a (top-level) PGD entry:
- */
-void guest_set_pgd(struct lguest *lg, unsigned long gpgdir, u32 idx)
-{
- int pgdir;
-
- if (idx > PTRS_PER_PGD) {
- kill_guest(&lg->cpus[0], "Attempt to set pgd %u/%u",
- idx, PTRS_PER_PGD);
- return;
- }
-
- /* If they're talking about a page table we have a shadow for... */
- pgdir = find_pgdir(lg, gpgdir);
- if (pgdir < ARRAY_SIZE(lg->pgdirs)) {
- /* ... throw it away. */
- release_pgd(lg->pgdirs[pgdir].pgdir + idx);
- /* That might have been the Switcher mapping, remap it. */
- if (!allocate_switcher_mapping(&lg->cpus[0])) {
- kill_guest(&lg->cpus[0],
- "Cannot populate switcher mapping");
- }
- lg->pgdirs[pgdir].last_host_cpu = -1;
- }
-}
-
-#ifdef CONFIG_X86_PAE
-/* For setting a mid-level, we just throw everything away. It's easy. */
-void guest_set_pmd(struct lguest *lg, unsigned long pmdp, u32 idx)
-{
- guest_pagetable_clear_all(&lg->cpus[0]);
-}
-#endif
-
-/*H:500
- * (vii) Setting up the page tables initially.
- *
- * When a Guest is first created, set initialize a shadow page table which
- * we will populate on future faults. The Guest doesn't have any actual
- * pagetables yet, so we set linear_pages to tell demand_page() to fake it
- * for the moment.
- *
- * We do need the Switcher to be mapped at all times, so we allocate that
- * part of the Guest page table here.
- */
-int init_guest_pagetable(struct lguest *lg)
-{
- struct lg_cpu *cpu = &lg->cpus[0];
- int allocated = 0;
-
- /* lg (and lg->cpus[]) starts zeroed: this allocates a new pgdir */
- cpu->cpu_pgd = new_pgdir(cpu, 0, &allocated);
- if (!allocated)
- return -ENOMEM;
-
- /* We start with a linear mapping until the initialize. */
- cpu->linear_pages = true;
-
- /* Allocate the page tables for the Switcher. */
- if (!allocate_switcher_mapping(cpu)) {
- release_all_pagetables(lg);
- return -ENOMEM;
- }
-
- return 0;
-}
-
-/*H:508 When the Guest calls LHCALL_LGUEST_INIT we do more setup. */
-void page_table_guest_data_init(struct lg_cpu *cpu)
-{
- /*
- * We tell the Guest that it can't use the virtual addresses
- * used by the Switcher. This trick is equivalent to 4GB -
- * switcher_addr.
- */
- u32 top = ~switcher_addr + 1;
-
- /* We get the kernel address: above this is all kernel memory. */
- if (get_user(cpu->lg->kernel_address,
- &cpu->lg->lguest_data->kernel_address)
- /*
- * We tell the Guest that it can't use the top virtual
- * addresses (used by the Switcher).
- */
- || put_user(top, &cpu->lg->lguest_data->reserve_mem)) {
- kill_guest(cpu, "bad guest page %p", cpu->lg->lguest_data);
- return;
- }
-
- /*
- * In flush_user_mappings() we loop from 0 to
- * "pgd_index(lg->kernel_address)". This assumes it won't hit the
- * Switcher mappings, so check that now.
- */
- if (cpu->lg->kernel_address >= switcher_addr)
- kill_guest(cpu, "bad kernel address %#lx",
- cpu->lg->kernel_address);
-}
-
-/* When a Guest dies, our cleanup is fairly simple. */
-void free_guest_pagetable(struct lguest *lg)
-{
- unsigned int i;
-
- /* Throw away all page table pages. */
- release_all_pagetables(lg);
- /* Now free the top levels: free_page() can handle 0 just fine. */
- for (i = 0; i < ARRAY_SIZE(lg->pgdirs); i++)
- free_page((long)lg->pgdirs[i].pgdir);
-}
-
-/*H:481
- * This clears the Switcher mappings for cpu #i.
- */
-static void remove_switcher_percpu_map(struct lg_cpu *cpu, unsigned int i)
-{
- unsigned long base = switcher_addr + PAGE_SIZE + i * PAGE_SIZE*2;
- pte_t *pte;
-
- /* Clear the mappings for both pages. */
- pte = find_spte(cpu, base, false, 0, 0);
- release_pte(*pte);
- set_pte(pte, __pte(0));
-
- pte = find_spte(cpu, base + PAGE_SIZE, false, 0, 0);
- release_pte(*pte);
- set_pte(pte, __pte(0));
-}
-
-/*H:480
- * (vi) Mapping the Switcher when the Guest is about to run.
- *
- * The Switcher and the two pages for this CPU need to be visible in the Guest
- * (and not the pages for other CPUs).
- *
- * The pages for the pagetables have all been allocated before: we just need
- * to make sure the actual PTEs are up-to-date for the CPU we're about to run
- * on.
- */
-void map_switcher_in_guest(struct lg_cpu *cpu, struct lguest_pages *pages)
-{
- unsigned long base;
- struct page *percpu_switcher_page, *regs_page;
- pte_t *pte;
- struct pgdir *pgdir = &cpu->lg->pgdirs[cpu->cpu_pgd];
-
- /* Switcher page should always be mapped by now! */
- BUG_ON(!pgdir->switcher_mapped);
-
- /*
- * Remember that we have two pages for each Host CPU, so we can run a
- * Guest on each CPU without them interfering. We need to make sure
- * those pages are mapped correctly in the Guest, but since we usually
- * run on the same CPU, we cache that, and only update the mappings
- * when we move.
- */
- if (pgdir->last_host_cpu == raw_smp_processor_id())
- return;
-
- /* -1 means unknown so we remove everything. */
- if (pgdir->last_host_cpu == -1) {
- unsigned int i;
- for_each_possible_cpu(i)
- remove_switcher_percpu_map(cpu, i);
- } else {
- /* We know exactly what CPU mapping to remove. */
- remove_switcher_percpu_map(cpu, pgdir->last_host_cpu);
- }
-
- /*
- * When we're running the Guest, we want the Guest's "regs" page to
- * appear where the first Switcher page for this CPU is. This is an
- * optimization: when the Switcher saves the Guest registers, it saves
- * them into the first page of this CPU's "struct lguest_pages": if we
- * make sure the Guest's register page is already mapped there, we
- * don't have to copy them out again.
- */
- /* Find the shadow PTE for this regs page. */
- base = switcher_addr + PAGE_SIZE
- + raw_smp_processor_id() * sizeof(struct lguest_pages);
- pte = find_spte(cpu, base, false, 0, 0);
- regs_page = pfn_to_page(__pa(cpu->regs_page) >> PAGE_SHIFT);
- get_page(regs_page);
- set_pte(pte, mk_pte(regs_page, __pgprot(__PAGE_KERNEL & ~_PAGE_GLOBAL)));
-
- /*
- * We map the second page of the struct lguest_pages read-only in
- * the Guest: the IDT, GDT and other things it's not supposed to
- * change.
- */
- pte = find_spte(cpu, base + PAGE_SIZE, false, 0, 0);
- percpu_switcher_page
- = lg_switcher_pages[1 + raw_smp_processor_id()*2 + 1];
- get_page(percpu_switcher_page);
- set_pte(pte, mk_pte(percpu_switcher_page,
- __pgprot(__PAGE_KERNEL_RO & ~_PAGE_GLOBAL)));
-
- pgdir->last_host_cpu = raw_smp_processor_id();
-}
-
-/*H:490
- * We've made it through the page table code. Perhaps our tired brains are
- * still processing the details, or perhaps we're simply glad it's over.
- *
- * If nothing else, note that all this complexity in juggling shadow page tables
- * in sync with the Guest's page tables is for one reason: for most Guests this
- * page table dance determines how bad performance will be. This is why Xen
- * uses exotic direct Guest pagetable manipulation, and why both Intel and AMD
- * have implemented shadow page table support directly into hardware.
- *
- * There is just one file remaining in the Host.
- */
diff --git a/drivers/lguest/segments.c b/drivers/lguest/segments.c
deleted file mode 100644
index c4fb424..0000000
--- a/drivers/lguest/segments.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*P:600
- * The x86 architecture has segments, which involve a table of descriptors
- * which can be used to do funky things with virtual address interpretation.
- * We originally used to use segments so the Guest couldn't alter the
- * Guest<->Host Switcher, and then we had to trim Guest segments, and restore
- * for userspace per-thread segments, but trim again for on userspace->kernel
- * transitions... This nightmarish creation was contained within this file,
- * where we knew not to tread without heavy armament and a change of underwear.
- *
- * In these modern times, the segment handling code consists of simple sanity
- * checks, and the worst you'll experience reading this code is butterfly-rash
- * from frolicking through its parklike serenity.
-:*/
-#include "lg.h"
-
-/*H:600
- * Segments & The Global Descriptor Table
- *
- * (That title sounds like a bad Nerdcore group. Not to suggest that there are
- * any good Nerdcore groups, but in high school a friend of mine had a band
- * called Joe Fish and the Chips, so there are definitely worse band names).
- *
- * To refresh: the GDT is a table of 8-byte values describing segments. Once
- * set up, these segments can be loaded into one of the 6 "segment registers".
- *
- * GDT entries are passed around as "struct desc_struct"s, which like IDT
- * entries are split into two 32-bit members, "a" and "b". One day, someone
- * will clean that up, and be declared a Hero. (No pressure, I'm just saying).
- *
- * Anyway, the GDT entry contains a base (the start address of the segment), a
- * limit (the size of the segment - 1), and some flags. Sounds simple, and it
- * would be, except those zany Intel engineers decided that it was too boring
- * to put the base at one end, the limit at the other, and the flags in
- * between. They decided to shotgun the bits at random throughout the 8 bytes,
- * like so:
- *
- * 0 16 40 48 52 56 63
- * [ limit part 1 ][ base part 1 ][ flags ][li][fl][base ]
- * mit ags part 2
- * part 2
- *
- * As a result, this file contains a certain amount of magic numeracy. Let's
- * begin.
- */
-
-/*
- * There are several entries we don't let the Guest set. The TSS entry is the
- * "Task State Segment" which controls all kinds of delicate things. The
- * LGUEST_CS and LGUEST_DS entries are reserved for the Switcher, and the
- * the Guest can't be trusted to deal with double faults.
- */
-static bool ignored_gdt(unsigned int num)
-{
- return (num == GDT_ENTRY_TSS
- || num == GDT_ENTRY_LGUEST_CS
- || num == GDT_ENTRY_LGUEST_DS
- || num == GDT_ENTRY_DOUBLEFAULT_TSS);
-}
-
-/*H:630
- * Once the Guest gave us new GDT entries, we fix them up a little. We
- * don't care if they're invalid: the worst that can happen is a General
- * Protection Fault in the Switcher when it restores a Guest segment register
- * which tries to use that entry. Then we kill the Guest for causing such a
- * mess: the message will be "unhandled trap 256".
- */
-static void fixup_gdt_table(struct lg_cpu *cpu, unsigned start, unsigned end)
-{
- unsigned int i;
-
- for (i = start; i < end; i++) {
- /*
- * We never copy these ones to real GDT, so we don't care what
- * they say
- */
- if (ignored_gdt(i))
- continue;
-
- /*
- * Segment descriptors contain a privilege level: the Guest is
- * sometimes careless and leaves this as 0, even though it's
- * running at privilege level 1. If so, we fix it here.
- */
- if (cpu->arch.gdt[i].dpl == 0)
- cpu->arch.gdt[i].dpl |= GUEST_PL;
-
- /*
- * Each descriptor has an "accessed" bit. If we don't set it
- * now, the CPU will try to set it when the Guest first loads
- * that entry into a segment register. But the GDT isn't
- * writable by the Guest, so bad things can happen.
- */
- cpu->arch.gdt[i].type |= 0x1;
- }
-}
-
-/*H:610
- * Like the IDT, we never simply use the GDT the Guest gives us. We keep
- * a GDT for each CPU, and copy across the Guest's entries each time we want to
- * run the Guest on that CPU.
- *
- * This routine is called at boot or modprobe time for each CPU to set up the
- * constant GDT entries: the ones which are the same no matter what Guest we're
- * running.
- */
-void setup_default_gdt_entries(struct lguest_ro_state *state)
-{
- struct desc_struct *gdt = state->guest_gdt;
- unsigned long tss = (unsigned long)&state->guest_tss;
-
- /* The Switcher segments are full 0-4G segments, privilege level 0 */
- gdt[GDT_ENTRY_LGUEST_CS] = FULL_EXEC_SEGMENT;
- gdt[GDT_ENTRY_LGUEST_DS] = FULL_SEGMENT;
-
- /*
- * The TSS segment refers to the TSS entry for this particular CPU.
- */
- gdt[GDT_ENTRY_TSS].a = 0;
- gdt[GDT_ENTRY_TSS].b = 0;
-
- gdt[GDT_ENTRY_TSS].limit0 = 0x67;
- gdt[GDT_ENTRY_TSS].base0 = tss & 0xFFFF;
- gdt[GDT_ENTRY_TSS].base1 = (tss >> 16) & 0xFF;
- gdt[GDT_ENTRY_TSS].base2 = tss >> 24;
- gdt[GDT_ENTRY_TSS].type = 0x9; /* 32-bit TSS (available) */
- gdt[GDT_ENTRY_TSS].p = 0x1; /* Entry is present */
- gdt[GDT_ENTRY_TSS].dpl = 0x0; /* Privilege level 0 */
- gdt[GDT_ENTRY_TSS].s = 0x0; /* system segment */
-
-}
-
-/*
- * This routine sets up the initial Guest GDT for booting. All entries start
- * as 0 (unusable).
- */
-void setup_guest_gdt(struct lg_cpu *cpu)
-{
- /*
- * Start with full 0-4G segments...except the Guest is allowed to use
- * them, so set the privilege level appropriately in the flags.
- */
- cpu->arch.gdt[GDT_ENTRY_KERNEL_CS] = FULL_EXEC_SEGMENT;
- cpu->arch.gdt[GDT_ENTRY_KERNEL_DS] = FULL_SEGMENT;
- cpu->arch.gdt[GDT_ENTRY_KERNEL_CS].dpl |= GUEST_PL;
- cpu->arch.gdt[GDT_ENTRY_KERNEL_DS].dpl |= GUEST_PL;
-}
-
-/*H:650
- * An optimization of copy_gdt(), for just the three "thead-local storage"
- * entries.
- */
-void copy_gdt_tls(const struct lg_cpu *cpu, struct desc_struct *gdt)
-{
- unsigned int i;
-
- for (i = GDT_ENTRY_TLS_MIN; i <= GDT_ENTRY_TLS_MAX; i++)
- gdt[i] = cpu->arch.gdt[i];
-}
-
-/*H:640
- * When the Guest is run on a different CPU, or the GDT entries have changed,
- * copy_gdt() is called to copy the Guest's GDT entries across to this CPU's
- * GDT.
- */
-void copy_gdt(const struct lg_cpu *cpu, struct desc_struct *gdt)
-{
- unsigned int i;
-
- /*
- * The default entries from setup_default_gdt_entries() are not
- * replaced. See ignored_gdt() above.
- */
- for (i = 0; i < GDT_ENTRIES; i++)
- if (!ignored_gdt(i))
- gdt[i] = cpu->arch.gdt[i];
-}
-
-/*H:620
- * This is where the Guest asks us to load a new GDT entry
- * (LHCALL_LOAD_GDT_ENTRY). We tweak the entry and copy it in.
- */
-void load_guest_gdt_entry(struct lg_cpu *cpu, u32 num, u32 lo, u32 hi)
-{
- /*
- * We assume the Guest has the same number of GDT entries as the
- * Host, otherwise we'd have to dynamically allocate the Guest GDT.
- */
- if (num >= ARRAY_SIZE(cpu->arch.gdt)) {
- kill_guest(cpu, "too many gdt entries %i", num);
- return;
- }
-
- /* Set it up, then fix it. */
- cpu->arch.gdt[num].a = lo;
- cpu->arch.gdt[num].b = hi;
- fixup_gdt_table(cpu, num, num+1);
- /*
- * Mark that the GDT changed so the core knows it has to copy it again,
- * even if the Guest is run on the same CPU.
- */
- cpu->changed |= CHANGED_GDT;
-}
-
-/*
- * This is the fast-track version for just changing the three TLS entries.
- * Remember that this happens on every context switch, so it's worth
- * optimizing. But wouldn't it be neater to have a single hypercall to cover
- * both cases?
- */
-void guest_load_tls(struct lg_cpu *cpu, unsigned long gtls)
-{
- struct desc_struct *tls = &cpu->arch.gdt[GDT_ENTRY_TLS_MIN];
-
- __lgread(cpu, tls, gtls, sizeof(*tls)*GDT_ENTRY_TLS_ENTRIES);
- fixup_gdt_table(cpu, GDT_ENTRY_TLS_MIN, GDT_ENTRY_TLS_MAX+1);
- /* Note that just the TLS entries have changed. */
- cpu->changed |= CHANGED_GDT_TLS;
-}
-
-/*H:660
- * With this, we have finished the Host.
- *
- * Five of the seven parts of our task are complete. You have made it through
- * the Bit of Despair (I think that's somewhere in the page table code,
- * myself).
- *
- * Next, we examine "make Switcher". It's short, but intense.
- */
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
deleted file mode 100644
index b4f79b9..0000000
--- a/drivers/lguest/x86/core.c
+++ /dev/null
@@ -1,724 +0,0 @@
-/*
- * Copyright (C) 2006, Rusty Russell <rusty@rustcorp.com.au> IBM Corporation.
- * Copyright (C) 2007, Jes Sorensen <jes@sgi.com> SGI.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-/*P:450
- * This file contains the x86-specific lguest code. It used to be all
- * mixed in with drivers/lguest/core.c but several foolhardy code slashers
- * wrestled most of the dependencies out to here in preparation for porting
- * lguest to other architectures (see what I mean by foolhardy?).
- *
- * This also contains a couple of non-obvious setup and teardown pieces which
- * were implemented after days of debugging pain.
-:*/
-#include <linux/kernel.h>
-#include <linux/start_kernel.h>
-#include <linux/string.h>
-#include <linux/console.h>
-#include <linux/screen_info.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
-#include <linux/cpu.h>
-#include <linux/lguest.h>
-#include <linux/lguest_launcher.h>
-#include <asm/paravirt.h>
-#include <asm/param.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/desc.h>
-#include <asm/setup.h>
-#include <asm/lguest.h>
-#include <linux/uaccess.h>
-#include <asm/fpu/internal.h>
-#include <asm/tlbflush.h>
-#include "../lg.h"
-
-static int cpu_had_pge;
-
-static struct {
- unsigned long offset;
- unsigned short segment;
-} lguest_entry;
-
-/* Offset from where switcher.S was compiled to where we've copied it */
-static unsigned long switcher_offset(void)
-{
- return switcher_addr - (unsigned long)start_switcher_text;
-}
-
-/* This cpu's struct lguest_pages (after the Switcher text page) */
-static struct lguest_pages *lguest_pages(unsigned int cpu)
-{
- return &(((struct lguest_pages *)(switcher_addr + PAGE_SIZE))[cpu]);
-}
-
-static DEFINE_PER_CPU(struct lg_cpu *, lg_last_cpu);
-
-/*S:010
- * We approach the Switcher.
- *
- * Remember that each CPU has two pages which are visible to the Guest when it
- * runs on that CPU. This has to contain the state for that Guest: we copy the
- * state in just before we run the Guest.
- *
- * Each Guest has "changed" flags which indicate what has changed in the Guest
- * since it last ran. We saw this set in interrupts_and_traps.c and
- * segments.c.
- */
-static void copy_in_guest_info(struct lg_cpu *cpu, struct lguest_pages *pages)
-{
- /*
- * Copying all this data can be quite expensive. We usually run the
- * same Guest we ran last time (and that Guest hasn't run anywhere else
- * meanwhile). If that's not the case, we pretend everything in the
- * Guest has changed.
- */
- if (__this_cpu_read(lg_last_cpu) != cpu || cpu->last_pages != pages) {
- __this_cpu_write(lg_last_cpu, cpu);
- cpu->last_pages = pages;
- cpu->changed = CHANGED_ALL;
- }
-
- /*
- * These copies are pretty cheap, so we do them unconditionally: */
- /* Save the current Host top-level page directory.
- */
- pages->state.host_cr3 = __pa(current->mm->pgd);
- /*
- * Set up the Guest's page tables to see this CPU's pages (and no
- * other CPU's pages).
- */
- map_switcher_in_guest(cpu, pages);
- /*
- * Set up the two "TSS" members which tell the CPU what stack to use
- * for traps which do directly into the Guest (ie. traps at privilege
- * level 1).
- */
- pages->state.guest_tss.sp1 = cpu->esp1;
- pages->state.guest_tss.ss1 = cpu->ss1;
-
- /* Copy direct-to-Guest trap entries. */
- if (cpu->changed & CHANGED_IDT)
- copy_traps(cpu, pages->state.guest_idt, default_idt_entries);
-
- /* Copy all GDT entries which the Guest can change. */
- if (cpu->changed & CHANGED_GDT)
- copy_gdt(cpu, pages->state.guest_gdt);
- /* If only the TLS entries have changed, copy them. */
- else if (cpu->changed & CHANGED_GDT_TLS)
- copy_gdt_tls(cpu, pages->state.guest_gdt);
-
- /* Mark the Guest as unchanged for next time. */
- cpu->changed = 0;
-}
-
-/* Finally: the code to actually call into the Switcher to run the Guest. */
-static void run_guest_once(struct lg_cpu *cpu, struct lguest_pages *pages)
-{
- /* This is a dummy value we need for GCC's sake. */
- unsigned int clobber;
-
- /*
- * Copy the guest-specific information into this CPU's "struct
- * lguest_pages".
- */
- copy_in_guest_info(cpu, pages);
-
- /*
- * Set the trap number to 256 (impossible value). If we fault while
- * switching to the Guest (bad segment registers or bug), this will
- * cause us to abort the Guest.
- */
- cpu->regs->trapnum = 256;
-
- /*
- * Now: we push the "eflags" register on the stack, then do an "lcall".
- * This is how we change from using the kernel code segment to using
- * the dedicated lguest code segment, as well as jumping into the
- * Switcher.
- *
- * The lcall also pushes the old code segment (KERNEL_CS) onto the
- * stack, then the address of this call. This stack layout happens to
- * exactly match the stack layout created by an interrupt...
- */
- asm volatile("pushf; lcall *%4"
- /*
- * This is how we tell GCC that %eax ("a") and %ebx ("b")
- * are changed by this routine. The "=" means output.
- */
- : "=a"(clobber), "=b"(clobber)
- /*
- * %eax contains the pages pointer. ("0" refers to the
- * 0-th argument above, ie "a"). %ebx contains the
- * physical address of the Guest's top-level page
- * directory.
- */
- : "0"(pages),
- "1"(__pa(cpu->lg->pgdirs[cpu->cpu_pgd].pgdir)),
- "m"(lguest_entry)
- /*
- * We tell gcc that all these registers could change,
- * which means we don't have to save and restore them in
- * the Switcher.
- */
- : "memory", "%edx", "%ecx", "%edi", "%esi");
-}
-/*:*/
-
-unsigned long *lguest_arch_regptr(struct lg_cpu *cpu, size_t reg_off, bool any)
-{
- switch (reg_off) {
- case offsetof(struct pt_regs, bx):
- return &cpu->regs->ebx;
- case offsetof(struct pt_regs, cx):
- return &cpu->regs->ecx;
- case offsetof(struct pt_regs, dx):
- return &cpu->regs->edx;
- case offsetof(struct pt_regs, si):
- return &cpu->regs->esi;
- case offsetof(struct pt_regs, di):
- return &cpu->regs->edi;
- case offsetof(struct pt_regs, bp):
- return &cpu->regs->ebp;
- case offsetof(struct pt_regs, ax):
- return &cpu->regs->eax;
- case offsetof(struct pt_regs, ip):
- return &cpu->regs->eip;
- case offsetof(struct pt_regs, sp):
- return &cpu->regs->esp;
- }
-
- /* Launcher can read these, but we don't allow any setting. */
- if (any) {
- switch (reg_off) {
- case offsetof(struct pt_regs, ds):
- return &cpu->regs->ds;
- case offsetof(struct pt_regs, es):
- return &cpu->regs->es;
- case offsetof(struct pt_regs, fs):
- return &cpu->regs->fs;
- case offsetof(struct pt_regs, gs):
- return &cpu->regs->gs;
- case offsetof(struct pt_regs, cs):
- return &cpu->regs->cs;
- case offsetof(struct pt_regs, flags):
- return &cpu->regs->eflags;
- case offsetof(struct pt_regs, ss):
- return &cpu->regs->ss;
- }
- }
-
- return NULL;
-}
-
-/*M:002
- * There are hooks in the scheduler which we can register to tell when we
- * get kicked off the CPU (preempt_notifier_register()). This would allow us
- * to lazily disable SYSENTER which would regain some performance, and should
- * also simplify copy_in_guest_info(). Note that we'd still need to restore
- * things when we exit to Launcher userspace, but that's fairly easy.
- *
- * We could also try using these hooks for PGE, but that might be too expensive.
- *
- * The hooks were designed for KVM, but we can also put them to good use.
-:*/
-
-/*H:040
- * This is the i386-specific code to setup and run the Guest. Interrupts
- * are disabled: we own the CPU.
- */
-void lguest_arch_run_guest(struct lg_cpu *cpu)
-{
- /*
- * SYSENTER is an optimized way of doing system calls. We can't allow
- * it because it always jumps to privilege level 0. A normal Guest
- * won't try it because we don't advertise it in CPUID, but a malicious
- * Guest (or malicious Guest userspace program) could, so we tell the
- * CPU to disable it before running the Guest.
- */
- if (boot_cpu_has(X86_FEATURE_SEP))
- wrmsr(MSR_IA32_SYSENTER_CS, 0, 0);
-
- /*
- * Now we actually run the Guest. It will return when something
- * interesting happens, and we can examine its registers to see what it
- * was doing.
- */
- run_guest_once(cpu, lguest_pages(raw_smp_processor_id()));
-
- /*
- * Note that the "regs" structure contains two extra entries which are
- * not really registers: a trap number which says what interrupt or
- * trap made the switcher code come back, and an error code which some
- * traps set.
- */
-
- /* Restore SYSENTER if it's supposed to be on. */
- if (boot_cpu_has(X86_FEATURE_SEP))
- wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
-
- /*
- * If the Guest page faulted, then the cr2 register will tell us the
- * bad virtual address. We have to grab this now, because once we
- * re-enable interrupts an interrupt could fault and thus overwrite
- * cr2, or we could even move off to a different CPU.
- */
- if (cpu->regs->trapnum == 14)
- cpu->arch.last_pagefault = read_cr2();
- /*
- * Similarly, if we took a trap because the Guest used the FPU,
- * we have to restore the FPU it expects to see.
- * fpu__restore() may sleep and we may even move off to
- * a different CPU. So all the critical stuff should be done
- * before this.
- */
- else if (cpu->regs->trapnum == 7 && !fpregs_active())
- fpu__restore(&current->thread.fpu);
-}
-
-/*H:130
- * Now we've examined the hypercall code; our Guest can make requests.
- * Our Guest is usually so well behaved; it never tries to do things it isn't
- * allowed to, and uses hypercalls instead. Unfortunately, Linux's paravirtual
- * infrastructure isn't quite complete, because it doesn't contain replacements
- * for the Intel I/O instructions. As a result, the Guest sometimes fumbles
- * across one during the boot process as it probes for various things which are
- * usually attached to a PC.
- *
- * When the Guest uses one of these instructions, we get a trap (General
- * Protection Fault) and come here. We queue this to be sent out to the
- * Launcher to handle.
- */
-
-/*
- * The eip contains the *virtual* address of the Guest's instruction:
- * we copy the instruction here so the Launcher doesn't have to walk
- * the page tables to decode it. We handle the case (eg. in a kernel
- * module) where the instruction is over two pages, and the pages are
- * virtually but not physically contiguous.
- *
- * The longest possible x86 instruction is 15 bytes, but we don't handle
- * anything that strange.
- */
-static void copy_from_guest(struct lg_cpu *cpu,
- void *dst, unsigned long vaddr, size_t len)
-{
- size_t to_page_end = PAGE_SIZE - (vaddr % PAGE_SIZE);
- unsigned long paddr;
-
- BUG_ON(len > PAGE_SIZE);
-
- /* If it goes over a page, copy in two parts. */
- if (len > to_page_end) {
- /* But make sure the next page is mapped! */
- if (__guest_pa(cpu, vaddr + to_page_end, &paddr))
- copy_from_guest(cpu, dst + to_page_end,
- vaddr + to_page_end,
- len - to_page_end);
- else
- /* Otherwise fill with zeroes. */
- memset(dst + to_page_end, 0, len - to_page_end);
- len = to_page_end;
- }
-
- /* This will kill the guest if it isn't mapped, but that
- * shouldn't happen. */
- __lgread(cpu, dst, guest_pa(cpu, vaddr), len);
-}
-
-
-static void setup_emulate_insn(struct lg_cpu *cpu)
-{
- cpu->pending.trap = 13;
- copy_from_guest(cpu, cpu->pending.insn, cpu->regs->eip,
- sizeof(cpu->pending.insn));
-}
-
-static void setup_iomem_insn(struct lg_cpu *cpu, unsigned long iomem_addr)
-{
- cpu->pending.trap = 14;
- cpu->pending.addr = iomem_addr;
- copy_from_guest(cpu, cpu->pending.insn, cpu->regs->eip,
- sizeof(cpu->pending.insn));
-}
-
-/*H:050 Once we've re-enabled interrupts, we look at why the Guest exited. */
-void lguest_arch_handle_trap(struct lg_cpu *cpu)
-{
- unsigned long iomem_addr;
-
- switch (cpu->regs->trapnum) {
- case 13: /* We've intercepted a General Protection Fault. */
- /* Hand to Launcher to emulate those pesky IN and OUT insns */
- if (cpu->regs->errcode == 0) {
- setup_emulate_insn(cpu);
- return;
- }
- break;
- case 14: /* We've intercepted a Page Fault. */
- /*
- * The Guest accessed a virtual address that wasn't mapped.
- * This happens a lot: we don't actually set up most of the page
- * tables for the Guest at all when we start: as it runs it asks
- * for more and more, and we set them up as required. In this
- * case, we don't even tell the Guest that the fault happened.
- *
- * The errcode tells whether this was a read or a write, and
- * whether kernel or userspace code.
- */
- if (demand_page(cpu, cpu->arch.last_pagefault,
- cpu->regs->errcode, &iomem_addr))
- return;
-
- /* Was this an access to memory mapped IO? */
- if (iomem_addr) {
- /* Tell Launcher, let it handle it. */
- setup_iomem_insn(cpu, iomem_addr);
- return;
- }
-
- /*
- * OK, it's really not there (or not OK): the Guest needs to
- * know. We write out the cr2 value so it knows where the
- * fault occurred.
- *
- * Note that if the Guest were really messed up, this could
- * happen before it's done the LHCALL_LGUEST_INIT hypercall, so
- * lg->lguest_data could be NULL
- */
- if (cpu->lg->lguest_data &&
- put_user(cpu->arch.last_pagefault,
- &cpu->lg->lguest_data->cr2))
- kill_guest(cpu, "Writing cr2");
- break;
- case 7: /* We've intercepted a Device Not Available fault. */
- /* No special handling is needed here. */
- break;
- case 32 ... 255:
- /* This might be a syscall. */
- if (could_be_syscall(cpu->regs->trapnum))
- break;
-
- /*
- * Other values mean a real interrupt occurred, in which case
- * the Host handler has already been run. We just do a
- * friendly check if another process should now be run, then
- * return to run the Guest again.
- */
- cond_resched();
- return;
- case LGUEST_TRAP_ENTRY:
- /*
- * Our 'struct hcall_args' maps directly over our regs: we set
- * up the pointer now to indicate a hypercall is pending.
- */
- cpu->hcall = (struct hcall_args *)cpu->regs;
- return;
- }
-
- /* We didn't handle the trap, so it needs to go to the Guest. */
- if (!deliver_trap(cpu, cpu->regs->trapnum))
- /*
- * If the Guest doesn't have a handler (either it hasn't
- * registered any yet, or it's one of the faults we don't let
- * it handle), it dies with this cryptic error message.
- */
- kill_guest(cpu, "unhandled trap %li at %#lx (%#lx)",
- cpu->regs->trapnum, cpu->regs->eip,
- cpu->regs->trapnum == 14 ? cpu->arch.last_pagefault
- : cpu->regs->errcode);
-}
-
-/*
- * Now we can look at each of the routines this calls, in increasing order of
- * complexity: do_hypercalls(), emulate_insn(), maybe_do_interrupt(),
- * deliver_trap() and demand_page(). After all those, we'll be ready to
- * examine the Switcher, and our philosophical understanding of the Host/Guest
- * duality will be complete.
-:*/
-static void adjust_pge(void *on)
-{
- if (on)
- cr4_set_bits(X86_CR4_PGE);
- else
- cr4_clear_bits(X86_CR4_PGE);
-}
-
-/*H:020
- * Now the Switcher is mapped and every thing else is ready, we need to do
- * some more i386-specific initialization.
- */
-void __init lguest_arch_host_init(void)
-{
- int i;
-
- /*
- * Most of the x86/switcher_32.S doesn't care that it's been moved; on
- * Intel, jumps are relative, and it doesn't access any references to
- * external code or data.
- *
- * The only exception is the interrupt handlers in switcher.S: their
- * addresses are placed in a table (default_idt_entries), so we need to
- * update the table with the new addresses. switcher_offset() is a
- * convenience function which returns the distance between the
- * compiled-in switcher code and the high-mapped copy we just made.
- */
- for (i = 0; i < IDT_ENTRIES; i++)
- default_idt_entries[i] += switcher_offset();
-
- /*
- * Set up the Switcher's per-cpu areas.
- *
- * Each CPU gets two pages of its own within the high-mapped region
- * (aka. "struct lguest_pages"). Much of this can be initialized now,
- * but some depends on what Guest we are running (which is set up in
- * copy_in_guest_info()).
- */
- for_each_possible_cpu(i) {
- /* lguest_pages() returns this CPU's two pages. */
- struct lguest_pages *pages = lguest_pages(i);
- /* This is a convenience pointer to make the code neater. */
- struct lguest_ro_state *state = &pages->state;
-
- /*
- * The Global Descriptor Table: the Host has a different one
- * for each CPU. We keep a descriptor for the GDT which says
- * where it is and how big it is (the size is actually the last
- * byte, not the size, hence the "-1").
- */
- state->host_gdt_desc.size = GDT_SIZE-1;
- state->host_gdt_desc.address = (long)get_cpu_gdt_rw(i);
-
- /*
- * All CPUs on the Host use the same Interrupt Descriptor
- * Table, so we just use store_idt(), which gets this CPU's IDT
- * descriptor.
- */
- store_idt(&state->host_idt_desc);
-
- /*
- * The descriptors for the Guest's GDT and IDT can be filled
- * out now, too. We copy the GDT & IDT into ->guest_gdt and
- * ->guest_idt before actually running the Guest.
- */
- state->guest_idt_desc.size = sizeof(state->guest_idt)-1;
- state->guest_idt_desc.address = (long)&state->guest_idt;
- state->guest_gdt_desc.size = sizeof(state->guest_gdt)-1;
- state->guest_gdt_desc.address = (long)&state->guest_gdt;
-
- /*
- * We know where we want the stack to be when the Guest enters
- * the Switcher: in pages->regs. The stack grows upwards, so
- * we start it at the end of that structure.
- */
- state->guest_tss.sp0 = (long)(&pages->regs + 1);
- /*
- * And this is the GDT entry to use for the stack: we keep a
- * couple of special LGUEST entries.
- */
- state->guest_tss.ss0 = LGUEST_DS;
-
- /*
- * x86 can have a finegrained bitmap which indicates what I/O
- * ports the process can use. We set it to the end of our
- * structure, meaning "none".
- */
- state->guest_tss.io_bitmap_base = sizeof(state->guest_tss);
-
- /*
- * Some GDT entries are the same across all Guests, so we can
- * set them up now.
- */
- setup_default_gdt_entries(state);
- /* Most IDT entries are the same for all Guests, too.*/
- setup_default_idt_entries(state, default_idt_entries);
-
- /*
- * The Host needs to be able to use the LGUEST segments on this
- * CPU, too, so put them in the Host GDT.
- */
- get_cpu_gdt_rw(i)[GDT_ENTRY_LGUEST_CS] = FULL_EXEC_SEGMENT;
- get_cpu_gdt_rw(i)[GDT_ENTRY_LGUEST_DS] = FULL_SEGMENT;
- }
-
- /*
- * In the Switcher, we want the %cs segment register to use the
- * LGUEST_CS GDT entry: we've put that in the Host and Guest GDTs, so
- * it will be undisturbed when we switch. To change %cs and jump we
- * need this structure to feed to Intel's "lcall" instruction.
- */
- lguest_entry.offset = (long)switch_to_guest + switcher_offset();
- lguest_entry.segment = LGUEST_CS;
-
- /*
- * Finally, we need to turn off "Page Global Enable". PGE is an
- * optimization where page table entries are specially marked to show
- * they never change. The Host kernel marks all the kernel pages this
- * way because it's always present, even when userspace is running.
- *
- * Lguest breaks this: unbeknownst to the rest of the Host kernel, we
- * switch to the Guest kernel. If you don't disable this on all CPUs,
- * you'll get really weird bugs that you'll chase for two days.
- *
- * I used to turn PGE off every time we switched to the Guest and back
- * on when we return, but that slowed the Switcher down noticibly.
- */
-
- /*
- * We don't need the complexity of CPUs coming and going while we're
- * doing this.
- */
- get_online_cpus();
- if (boot_cpu_has(X86_FEATURE_PGE)) { /* We have a broader idea of "global". */
- /* Remember that this was originally set (for cleanup). */
- cpu_had_pge = 1;
- /*
- * adjust_pge is a helper function which sets or unsets the PGE
- * bit on its CPU, depending on the argument (0 == unset).
- */
- on_each_cpu(adjust_pge, (void *)0, 1);
- /* Turn off the feature in the global feature set. */
- clear_cpu_cap(&boot_cpu_data, X86_FEATURE_PGE);
- }
- put_online_cpus();
-}
-/*:*/
-
-void __exit lguest_arch_host_fini(void)
-{
- /* If we had PGE before we started, turn it back on now. */
- get_online_cpus();
- if (cpu_had_pge) {
- set_cpu_cap(&boot_cpu_data, X86_FEATURE_PGE);
- /* adjust_pge's argument "1" means set PGE. */
- on_each_cpu(adjust_pge, (void *)1, 1);
- }
- put_online_cpus();
-}
-
-
-/*H:122 The i386-specific hypercalls simply farm out to the right functions. */
-int lguest_arch_do_hcall(struct lg_cpu *cpu, struct hcall_args *args)
-{
- switch (args->arg0) {
- case LHCALL_LOAD_GDT_ENTRY:
- load_guest_gdt_entry(cpu, args->arg1, args->arg2, args->arg3);
- break;
- case LHCALL_LOAD_IDT_ENTRY:
- load_guest_idt_entry(cpu, args->arg1, args->arg2, args->arg3);
- break;
- case LHCALL_LOAD_TLS:
- guest_load_tls(cpu, args->arg1);
- break;
- default:
- /* Bad Guest. Bad! */
- return -EIO;
- }
- return 0;
-}
-
-/*H:126 i386-specific hypercall initialization: */
-int lguest_arch_init_hypercalls(struct lg_cpu *cpu)
-{
- u32 tsc_speed;
-
- /*
- * The pointer to the Guest's "struct lguest_data" is the only argument.
- * We check that address now.
- */
- if (!lguest_address_ok(cpu->lg, cpu->hcall->arg1,
- sizeof(*cpu->lg->lguest_data)))
- return -EFAULT;
-
- /*
- * Having checked it, we simply set lg->lguest_data to point straight
- * into the Launcher's memory at the right place and then use
- * copy_to_user/from_user from now on, instead of lgread/write. I put
- * this in to show that I'm not immune to writing stupid
- * optimizations.
- */
- cpu->lg->lguest_data = cpu->lg->mem_base + cpu->hcall->arg1;
-
- /*
- * We insist that the Time Stamp Counter exist and doesn't change with
- * cpu frequency. Some devious chip manufacturers decided that TSC
- * changes could be handled in software. I decided that time going
- * backwards might be good for benchmarks, but it's bad for users.
- *
- * We also insist that the TSC be stable: the kernel detects unreliable
- * TSCs for its own purposes, and we use that here.
- */
- if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC) && !check_tsc_unstable())
- tsc_speed = tsc_khz;
- else
- tsc_speed = 0;
- if (put_user(tsc_speed, &cpu->lg->lguest_data->tsc_khz))
- return -EFAULT;
-
- /* The interrupt code might not like the system call vector. */
- if (!check_syscall_vector(cpu->lg))
- kill_guest(cpu, "bad syscall vector");
-
- return 0;
-}
-/*:*/
-
-/*L:030
- * Most of the Guest's registers are left alone: we used get_zeroed_page() to
- * allocate the structure, so they will be 0.
- */
-void lguest_arch_setup_regs(struct lg_cpu *cpu, unsigned long start)
-{
- struct lguest_regs *regs = cpu->regs;
-
- /*
- * There are four "segment" registers which the Guest needs to boot:
- * The "code segment" register (cs) refers to the kernel code segment
- * __KERNEL_CS, and the "data", "extra" and "stack" segment registers
- * refer to the kernel data segment __KERNEL_DS.
- *
- * The privilege level is packed into the lower bits. The Guest runs
- * at privilege level 1 (GUEST_PL).
- */
- regs->ds = regs->es = regs->ss = __KERNEL_DS|GUEST_PL;
- regs->cs = __KERNEL_CS|GUEST_PL;
-
- /*
- * The "eflags" register contains miscellaneous flags. Bit 1 (0x002)
- * is supposed to always be "1". Bit 9 (0x200) controls whether
- * interrupts are enabled. We always leave interrupts enabled while
- * running the Guest.
- */
- regs->eflags = X86_EFLAGS_IF | X86_EFLAGS_FIXED;
-
- /*
- * The "Extended Instruction Pointer" register says where the Guest is
- * running.
- */
- regs->eip = start;
-
- /*
- * %esi points to our boot information, at physical address 0, so don't
- * touch it.
- */
-
- /* There are a couple of GDT entries the Guest expects at boot. */
- setup_guest_gdt(cpu);
-}
diff --git a/drivers/lguest/x86/switcher_32.S b/drivers/lguest/x86/switcher_32.S
deleted file mode 100644
index 40634b0..0000000
--- a/drivers/lguest/x86/switcher_32.S
+++ /dev/null
@@ -1,388 +0,0 @@
-/*P:900
- * This is the Switcher: code which sits at 0xFFC00000 (or 0xFFE00000) astride
- * both the Host and Guest to do the low-level Guest<->Host switch. It is as
- * simple as it can be made, but it's naturally very specific to x86.
- *
- * You have now completed Preparation. If this has whet your appetite; if you
- * are feeling invigorated and refreshed then the next, more challenging stage
- * can be found in "make Guest".
- :*/
-
-/*M:012
- * Lguest is meant to be simple: my rule of thumb is that 1% more LOC must
- * gain at least 1% more performance. Since neither LOC nor performance can be
- * measured beforehand, it generally means implementing a feature then deciding
- * if it's worth it. And once it's implemented, who can say no?
- *
- * This is why I haven't implemented this idea myself. I want to, but I
- * haven't. You could, though.
- *
- * The main place where lguest performance sucks is Guest page faulting. When
- * a Guest userspace process hits an unmapped page we switch back to the Host,
- * walk the page tables, find it's not mapped, switch back to the Guest page
- * fault handler, which calls a hypercall to set the page table entry, then
- * finally returns to userspace. That's two round-trips.
- *
- * If we had a small walker in the Switcher, we could quickly check the Guest
- * page table and if the page isn't mapped, immediately reflect the fault back
- * into the Guest. This means the Switcher would have to know the top of the
- * Guest page table and the page fault handler address.
- *
- * For simplicity, the Guest should only handle the case where the privilege
- * level of the fault is 3 and probably only not present or write faults. It
- * should also detect recursive faults, and hand the original fault to the
- * Host (which is actually really easy).
- *
- * Two questions remain. Would the performance gain outweigh the complexity?
- * And who would write the verse documenting it?
-:*/
-
-/*M:011
- * Lguest64 handles NMI. This gave me NMI envy (until I looked at their
- * code). It's worth doing though, since it would let us use oprofile in the
- * Host when a Guest is running.
-:*/
-
-/*S:100
- * Welcome to the Switcher itself!
- *
- * This file contains the low-level code which changes the CPU to run the Guest
- * code, and returns to the Host when something happens. Understand this, and
- * you understand the heart of our journey.
- *
- * Because this is in assembler rather than C, our tale switches from prose to
- * verse. First I tried limericks:
- *
- * There once was an eax reg,
- * To which our pointer was fed,
- * It needed an add,
- * Which asm-offsets.h had
- * But this limerick is hurting my head.
- *
- * Next I tried haikus, but fitting the required reference to the seasons in
- * every stanza was quickly becoming tiresome:
- *
- * The %eax reg
- * Holds "struct lguest_pages" now:
- * Cherry blossoms fall.
- *
- * Then I started with Heroic Verse, but the rhyming requirement leeched away
- * the content density and led to some uniquely awful oblique rhymes:
- *
- * These constants are coming from struct offsets
- * For use within the asm switcher text.
- *
- * Finally, I settled for something between heroic hexameter, and normal prose
- * with inappropriate linebreaks. Anyway, it aint no Shakespeare.
- */
-
-// Not all kernel headers work from assembler
-// But these ones are needed: the ENTRY() define
-// And constants extracted from struct offsets
-// To avoid magic numbers and breakage:
-// Should they change the compiler can't save us
-// Down here in the depths of assembler code.
-#include <linux/linkage.h>
-#include <asm/asm-offsets.h>
-#include <asm/page.h>
-#include <asm/segment.h>
-#include <asm/lguest.h>
-
-// We mark the start of the code to copy
-// It's placed in .text tho it's never run here
-// You'll see the trick macro at the end
-// Which interleaves data and text to effect.
-.text
-ENTRY(start_switcher_text)
-
-// When we reach switch_to_guest we have just left
-// The safe and comforting shores of C code
-// %eax has the "struct lguest_pages" to use
-// Where we save state and still see it from the Guest
-// And %ebx holds the Guest shadow pagetable:
-// Once set we have truly left Host behind.
-ENTRY(switch_to_guest)
- // We told gcc all its regs could fade,
- // Clobbered by our journey into the Guest
- // We could have saved them, if we tried
- // But time is our master and cycles count.
-
- // Segment registers must be saved for the Host
- // We push them on the Host stack for later
- pushl %es
- pushl %ds
- pushl %gs
- pushl %fs
- // But the compiler is fickle, and heeds
- // No warning of %ebp clobbers
- // When frame pointers are used. That register
- // Must be saved and restored or chaos strikes.
- pushl %ebp
- // The Host's stack is done, now save it away
- // In our "struct lguest_pages" at offset
- // Distilled into asm-offsets.h
- movl %esp, LGUEST_PAGES_host_sp(%eax)
-
- // All saved and there's now five steps before us:
- // Stack, GDT, IDT, TSS
- // Then last of all the page tables are flipped.
-
- // Yet beware that our stack pointer must be
- // Always valid lest an NMI hits
- // %edx does the duty here as we juggle
- // %eax is lguest_pages: our stack lies within.
- movl %eax, %edx
- addl $LGUEST_PAGES_regs, %edx
- movl %edx, %esp
-
- // The Guest's GDT we so carefully
- // Placed in the "struct lguest_pages" before
- lgdt LGUEST_PAGES_guest_gdt_desc(%eax)
-
- // The Guest's IDT we did partially
- // Copy to "struct lguest_pages" as well.
- lidt LGUEST_PAGES_guest_idt_desc(%eax)
-
- // The TSS entry which controls traps
- // Must be loaded up with "ltr" now:
- // The GDT entry that TSS uses
- // Changes type when we load it: damn Intel!
- // For after we switch over our page tables
- // That entry will be read-only: we'd crash.
- movl $(GDT_ENTRY_TSS*8), %edx
- ltr %dx
-
- // Look back now, before we take this last step!
- // The Host's TSS entry was also marked used;
- // Let's clear it again for our return.
- // The GDT descriptor of the Host
- // Points to the table after two "size" bytes
- movl (LGUEST_PAGES_host_gdt_desc+2)(%eax), %edx
- // Clear "used" from type field (byte 5, bit 2)
- andb $0xFD, (GDT_ENTRY_TSS*8 + 5)(%edx)
-
- // Once our page table's switched, the Guest is live!
- // The Host fades as we run this final step.
- // Our "struct lguest_pages" is now read-only.
- movl %ebx, %cr3
-
- // The page table change did one tricky thing:
- // The Guest's register page has been mapped
- // Writable under our %esp (stack) --
- // We can simply pop off all Guest regs.
- popl %eax
- popl %ebx
- popl %ecx
- popl %edx
- popl %esi
- popl %edi
- popl %ebp
- popl %gs
- popl %fs
- popl %ds
- popl %es
-
- // Near the base of the stack lurk two strange fields
- // Which we fill as we exit the Guest
- // These are the trap number and its error
- // We can simply step past them on our way.
- addl $8, %esp
-
- // The last five stack slots hold return address
- // And everything needed to switch privilege
- // From Switcher's level 0 to Guest's 1,
- // And the stack where the Guest had last left it.
- // Interrupts are turned back on: we are Guest.
- iret
-
-// We tread two paths to switch back to the Host
-// Yet both must save Guest state and restore Host
-// So we put the routine in a macro.
-#define SWITCH_TO_HOST \
- /* We save the Guest state: all registers first \
- * Laid out just as "struct lguest_regs" defines */ \
- pushl %es; \
- pushl %ds; \
- pushl %fs; \
- pushl %gs; \
- pushl %ebp; \
- pushl %edi; \
- pushl %esi; \
- pushl %edx; \
- pushl %ecx; \
- pushl %ebx; \
- pushl %eax; \
- /* Our stack and our code are using segments \
- * Set in the TSS and IDT \
- * Yet if we were to touch data we'd use \
- * Whatever data segment the Guest had. \
- * Load the lguest ds segment for now. */ \
- movl $(LGUEST_DS), %eax; \
- movl %eax, %ds; \
- /* So where are we? Which CPU, which struct? \
- * The stack is our clue: our TSS starts \
- * It at the end of "struct lguest_pages". \
- * Or we may have stumbled while restoring \
- * Our Guest segment regs while in switch_to_guest, \
- * The fault pushed atop that part-unwound stack. \
- * If we round the stack down to the page start \
- * We're at the start of "struct lguest_pages". */ \
- movl %esp, %eax; \
- andl $(~(1 << PAGE_SHIFT - 1)), %eax; \
- /* Save our trap number: the switch will obscure it \
- * (In the Host the Guest regs are not mapped here) \
- * %ebx holds it safe for deliver_to_host */ \
- movl LGUEST_PAGES_regs_trapnum(%eax), %ebx; \
- /* The Host GDT, IDT and stack! \
- * All these lie safely hidden from the Guest: \
- * We must return to the Host page tables \
- * (Hence that was saved in struct lguest_pages) */ \
- movl LGUEST_PAGES_host_cr3(%eax), %edx; \
- movl %edx, %cr3; \
- /* As before, when we looked back at the Host \
- * As we left and marked TSS unused \
- * So must we now for the Guest left behind. */ \
- andb $0xFD, (LGUEST_PAGES_guest_gdt+GDT_ENTRY_TSS*8+5)(%eax); \
- /* Switch to Host's GDT, IDT. */ \
- lgdt LGUEST_PAGES_host_gdt_desc(%eax); \
- lidt LGUEST_PAGES_host_idt_desc(%eax); \
- /* Restore the Host's stack where its saved regs lie */ \
- movl LGUEST_PAGES_host_sp(%eax), %esp; \
- /* Last the TSS: our Host is returned */ \
- movl $(GDT_ENTRY_TSS*8), %edx; \
- ltr %dx; \
- /* Restore now the regs saved right at the first. */ \
- popl %ebp; \
- popl %fs; \
- popl %gs; \
- popl %ds; \
- popl %es
-
-// The first path is trod when the Guest has trapped:
-// (Which trap it was has been pushed on the stack).
-// We need only switch back, and the Host will decode
-// Why we came home, and what needs to be done.
-return_to_host:
- SWITCH_TO_HOST
- iret
-
-// We are lead to the second path like so:
-// An interrupt, with some cause external
-// Has ajerked us rudely from the Guest's code
-// Again we must return home to the Host
-deliver_to_host:
- SWITCH_TO_HOST
- // But now we must go home via that place
- // Where that interrupt was supposed to go
- // Had we not been ensconced, running the Guest.
- // Here we see the trickness of run_guest_once():
- // The Host stack is formed like an interrupt
- // With EIP, CS and EFLAGS layered.
- // Interrupt handlers end with "iret"
- // And that will take us home at long long last.
-
- // But first we must find the handler to call!
- // The IDT descriptor for the Host
- // Has two bytes for size, and four for address:
- // %edx will hold it for us for now.
- movl (LGUEST_PAGES_host_idt_desc+2)(%eax), %edx
- // We now know the table address we need,
- // And saved the trap's number inside %ebx.
- // Yet the pointer to the handler is smeared
- // Across the bits of the table entry.
- // What oracle can tell us how to extract
- // From such a convoluted encoding?
- // I consulted gcc, and it gave
- // These instructions, which I gladly credit:
- leal (%edx,%ebx,8), %eax
- movzwl (%eax),%edx
- movl 4(%eax), %eax
- xorw %ax, %ax
- orl %eax, %edx
- // Now the address of the handler's in %edx
- // We call it now: its "iret" drops us home.
- jmp *%edx
-
-// Every interrupt can come to us here
-// But we must truly tell each apart.
-// They number two hundred and fifty six
-// And each must land in a different spot,
-// Push its number on stack, and join the stream.
-
-// And worse, a mere six of the traps stand apart
-// And push on their stack an addition:
-// An error number, thirty two bits long
-// So we punish the other two fifty
-// And make them push a zero so they match.
-
-// Yet two fifty six entries is long
-// And all will look most the same as the last
-// So we create a macro which can make
-// As many entries as we need to fill.
-
-// Note the change to .data then .text:
-// We plant the address of each entry
-// Into a (data) table for the Host
-// To know where each Guest interrupt should go.
-.macro IRQ_STUB N TARGET
- .data; .long 1f; .text; 1:
- // Trap eight, ten through fourteen and seventeen
- // Supply an error number. Else zero.
- .if (\N <> 8) && (\N < 10 || \N > 14) && (\N <> 17)
- pushl $0
- .endif
- pushl $\N
- jmp \TARGET
- ALIGN
-.endm
-
-// This macro creates numerous entries
-// Using GAS macros which out-power C's.
-.macro IRQ_STUBS FIRST LAST TARGET
- irq=\FIRST
- .rept \LAST-\FIRST+1
- IRQ_STUB irq \TARGET
- irq=irq+1
- .endr
-.endm
-
-// Here's the marker for our pointer table
-// Laid in the data section just before
-// Each macro places the address of code
-// Forming an array: each one points to text
-// Which handles interrupt in its turn.
-.data
-.global default_idt_entries
-default_idt_entries:
-.text
- // The first two traps go straight back to the Host
- IRQ_STUBS 0 1 return_to_host
- // We'll say nothing, yet, about NMI
- IRQ_STUB 2 handle_nmi
- // Other traps also return to the Host
- IRQ_STUBS 3 31 return_to_host
- // All interrupts go via their handlers
- IRQ_STUBS 32 127 deliver_to_host
- // 'Cept system calls coming from userspace
- // Are to go to the Guest, never the Host.
- IRQ_STUB 128 return_to_host
- IRQ_STUBS 129 255 deliver_to_host
-
-// The NMI, what a fabulous beast
-// Which swoops in and stops us no matter that
-// We're suspended between heaven and hell,
-// (Or more likely between the Host and Guest)
-// When in it comes! We are dazed and confused
-// So we do the simplest thing which one can.
-// Though we've pushed the trap number and zero
-// We discard them, return, and hope we live.
-handle_nmi:
- addl $8, %esp
- iret
-
-// We are done; all that's left is Mastery
-// And "make Mastery" is a journey long
-// Designed to make your fingers itch to code.
-
-// Here ends the text, the file and poem.
-ENTRY(end_switcher_text)
diff --git a/drivers/mcb/mcb-core.c b/drivers/mcb/mcb-core.c
index 921a5d2..bb5c569 100644
--- a/drivers/mcb/mcb-core.c
+++ b/drivers/mcb/mcb-core.c
@@ -418,6 +418,22 @@ void mcb_bus_add_devices(const struct mcb_bus *bus)
EXPORT_SYMBOL_GPL(mcb_bus_add_devices);
/**
+ * mcb_get_resource() - get a resource for a mcb device
+ * @dev: the mcb device
+ * @type: the type of resource
+ */
+struct resource *mcb_get_resource(struct mcb_device *dev, unsigned int type)
+{
+ if (type == IORESOURCE_MEM)
+ return &dev->mem;
+ else if (type == IORESOURCE_IRQ)
+ return &dev->irq;
+ else
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(mcb_get_resource);
+
+/**
* mcb_request_mem() - Request memory
* @dev: The @mcb_device the memory is for
* @name: The name for the memory reference.
@@ -460,7 +476,9 @@ EXPORT_SYMBOL_GPL(mcb_release_mem);
static int __mcb_get_irq(struct mcb_device *dev)
{
- struct resource *irq = &dev->irq;
+ struct resource *irq;
+
+ irq = mcb_get_resource(dev, IORESOURCE_IRQ);
return irq->start;
}
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 0e8ab5b..d24e4b0 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -504,7 +504,6 @@ static int multipath_clone_and_map(struct dm_target *ti, struct request *rq,
if (queue_dying) {
atomic_inc(&m->pg_init_in_progress);
activate_or_offline_path(pgpath);
- return DM_MAPIO_REQUEUE;
}
return DM_MAPIO_DELAY_REQUEUE;
}
@@ -1458,7 +1457,6 @@ static int noretry_error(blk_status_t error)
case BLK_STS_TARGET:
case BLK_STS_NEXUS:
case BLK_STS_MEDIUM:
- case BLK_STS_RESOURCE:
return 1;
}
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 2edbcc2..d669fdd 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -27,16 +27,6 @@
#define DM_MSG_PREFIX "core"
-#ifdef CONFIG_PRINTK
-/*
- * ratelimit state to be used in DMXXX_LIMIT().
- */
-DEFINE_RATELIMIT_STATE(dm_ratelimit_state,
- DEFAULT_RATELIMIT_INTERVAL,
- DEFAULT_RATELIMIT_BURST);
-EXPORT_SYMBOL(dm_ratelimit_state);
-#endif
-
/*
* Cookies are numeric values sent with CHANGE and REMOVE
* uevents while resuming, removing or renaming the device.
@@ -1523,7 +1513,7 @@ static void __split_and_process_bio(struct mapped_device *md,
}
/* drop the extra reference count */
- dec_pending(ci.io, error);
+ dec_pending(ci.io, errno_to_blk_status(error));
}
/*-----------------------------------------------------------------
* CRUD END
diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
index 847963b..78ef838 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -41,11 +41,11 @@ struct vsp1_rwpf;
struct vsp1_sru;
struct vsp1_uds;
+#define VSP1_MAX_LIF 2
#define VSP1_MAX_RPF 5
#define VSP1_MAX_UDS 3
#define VSP1_MAX_WPF 4
-#define VSP1_HAS_LIF (1 << 0)
#define VSP1_HAS_LUT (1 << 1)
#define VSP1_HAS_SRU (1 << 2)
#define VSP1_HAS_BRU (1 << 3)
@@ -54,12 +54,14 @@ struct vsp1_uds;
#define VSP1_HAS_WPF_HFLIP (1 << 6)
#define VSP1_HAS_HGO (1 << 7)
#define VSP1_HAS_HGT (1 << 8)
+#define VSP1_HAS_BRS (1 << 9)
struct vsp1_device_info {
u32 version;
const char *model;
unsigned int gen;
unsigned int features;
+ unsigned int lif_count;
unsigned int rpf_count;
unsigned int uds_count;
unsigned int wpf_count;
@@ -76,13 +78,14 @@ struct vsp1_device {
struct rcar_fcp_device *fcp;
struct device *bus_master;
+ struct vsp1_bru *brs;
struct vsp1_bru *bru;
struct vsp1_clu *clu;
struct vsp1_hgo *hgo;
struct vsp1_hgt *hgt;
struct vsp1_hsit *hsi;
struct vsp1_hsit *hst;
- struct vsp1_lif *lif;
+ struct vsp1_lif *lif[VSP1_MAX_LIF];
struct vsp1_lut *lut;
struct vsp1_rwpf *rpf[VSP1_MAX_RPF];
struct vsp1_sru *sru;
diff --git a/drivers/media/platform/vsp1/vsp1_bru.c b/drivers/media/platform/vsp1/vsp1_bru.c
index 85362c5..e8fd2ae 100644
--- a/drivers/media/platform/vsp1/vsp1_bru.c
+++ b/drivers/media/platform/vsp1/vsp1_bru.c
@@ -33,7 +33,7 @@
static inline void vsp1_bru_write(struct vsp1_bru *bru, struct vsp1_dl_list *dl,
u32 reg, u32 data)
{
- vsp1_dl_list_write(dl, reg, data);
+ vsp1_dl_list_write(dl, bru->base + reg, data);
}
/* -----------------------------------------------------------------------------
@@ -332,11 +332,14 @@ static void bru_configure(struct vsp1_entity *entity,
/*
* Route BRU input 1 as SRC input to the ROP unit and configure the ROP
* unit with a NOP operation to make BRU input 1 available as the
- * Blend/ROP unit B SRC input.
+ * Blend/ROP unit B SRC input. Only needed for BRU, the BRS has no ROP
+ * unit.
*/
- vsp1_bru_write(bru, dl, VI6_BRU_ROP, VI6_BRU_ROP_DSTSEL_BRUIN(1) |
- VI6_BRU_ROP_CROP(VI6_ROP_NOP) |
- VI6_BRU_ROP_AROP(VI6_ROP_NOP));
+ if (entity->type == VSP1_ENTITY_BRU)
+ vsp1_bru_write(bru, dl, VI6_BRU_ROP,
+ VI6_BRU_ROP_DSTSEL_BRUIN(1) |
+ VI6_BRU_ROP_CROP(VI6_ROP_NOP) |
+ VI6_BRU_ROP_AROP(VI6_ROP_NOP));
for (i = 0; i < bru->entity.source_pad; ++i) {
bool premultiplied = false;
@@ -366,12 +369,13 @@ static void bru_configure(struct vsp1_entity *entity,
ctrl |= VI6_BRU_CTRL_DSTSEL_VRPF;
/*
- * Route BRU inputs 0 to 3 as SRC inputs to Blend/ROP units A to
- * D in that order. The Blend/ROP unit B SRC is hardwired to the
- * ROP unit output, the corresponding register bits must be set
- * to 0.
+ * Route inputs 0 to 3 as SRC inputs to Blend/ROP units A to D
+ * in that order. In the BRU the Blend/ROP unit B SRC is
+ * hardwired to the ROP unit output, the corresponding register
+ * bits must be set to 0. The BRS has no ROP unit and doesn't
+ * need any special processing.
*/
- if (i != 1)
+ if (!(entity->type == VSP1_ENTITY_BRU && i == 1))
ctrl |= VI6_BRU_CTRL_SRCSEL_BRUIN(i);
vsp1_bru_write(bru, dl, VI6_BRU_CTRL(i), ctrl);
@@ -407,20 +411,31 @@ static const struct vsp1_entity_operations bru_entity_ops = {
* Initialization and Cleanup
*/
-struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1)
+struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1,
+ enum vsp1_entity_type type)
{
struct vsp1_bru *bru;
+ unsigned int num_pads;
+ const char *name;
int ret;
bru = devm_kzalloc(vsp1->dev, sizeof(*bru), GFP_KERNEL);
if (bru == NULL)
return ERR_PTR(-ENOMEM);
+ bru->base = type == VSP1_ENTITY_BRU ? VI6_BRU_BASE : VI6_BRS_BASE;
bru->entity.ops = &bru_entity_ops;
- bru->entity.type = VSP1_ENTITY_BRU;
+ bru->entity.type = type;
+
+ if (type == VSP1_ENTITY_BRU) {
+ num_pads = vsp1->info->num_bru_inputs + 1;
+ name = "bru";
+ } else {
+ num_pads = 3;
+ name = "brs";
+ }
- ret = vsp1_entity_init(vsp1, &bru->entity, "bru",
- vsp1->info->num_bru_inputs + 1, &bru_ops,
+ ret = vsp1_entity_init(vsp1, &bru->entity, name, num_pads, &bru_ops,
MEDIA_ENT_F_PROC_VIDEO_COMPOSER);
if (ret < 0)
return ERR_PTR(ret);
@@ -435,7 +450,7 @@ struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1)
bru->entity.subdev.ctrl_handler = &bru->ctrls;
if (bru->ctrls.error) {
- dev_err(vsp1->dev, "bru: failed to initialize controls\n");
+ dev_err(vsp1->dev, "%s: failed to initialize controls\n", name);
ret = bru->ctrls.error;
vsp1_entity_destroy(&bru->entity);
return ERR_PTR(ret);
diff --git a/drivers/media/platform/vsp1/vsp1_bru.h b/drivers/media/platform/vsp1/vsp1_bru.h
index 828a3fc..c98ed96 100644
--- a/drivers/media/platform/vsp1/vsp1_bru.h
+++ b/drivers/media/platform/vsp1/vsp1_bru.h
@@ -26,6 +26,7 @@ struct vsp1_rwpf;
struct vsp1_bru {
struct vsp1_entity entity;
+ unsigned int base;
struct v4l2_ctrl_handler ctrls;
@@ -41,6 +42,7 @@ static inline struct vsp1_bru *to_bru(struct v4l2_subdev *subdev)
return container_of(subdev, struct vsp1_bru, entity.subdev);
}
-struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1);
+struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1,
+ enum vsp1_entity_type type);
#endif /* __VSP1_BRU_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
index aaf17b1..8b5cbb6 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -95,6 +95,7 @@ enum vsp1_dl_mode {
* struct vsp1_dl_manager - Display List manager
* @index: index of the related WPF
* @mode: display list operation mode (header or headerless)
+ * @singleshot: execute the display list in single-shot mode
* @vsp1: the VSP1 device
* @lock: protects the free, active, queued, pending and gc_fragments lists
* @free: array of all free display lists
@@ -107,6 +108,7 @@ enum vsp1_dl_mode {
struct vsp1_dl_manager {
unsigned int index;
enum vsp1_dl_mode mode;
+ bool singleshot;
struct vsp1_device *vsp1;
spinlock_t lock;
@@ -437,6 +439,7 @@ int vsp1_dl_list_add_chain(struct vsp1_dl_list *head,
static void vsp1_dl_list_fill_header(struct vsp1_dl_list *dl, bool is_last)
{
+ struct vsp1_dl_manager *dlm = dl->dlm;
struct vsp1_dl_header_list *hdr = dl->header->lists;
struct vsp1_dl_body *dlb;
unsigned int num_lists = 0;
@@ -461,106 +464,152 @@ static void vsp1_dl_list_fill_header(struct vsp1_dl_list *dl, bool is_last)
dl->header->num_lists = num_lists;
- /*
- * If this display list's chain is not empty, we are on a list, where
- * the next item in the list is the display list entity which should be
- * automatically queued by the hardware.
- */
if (!list_empty(&dl->chain) && !is_last) {
+ /*
+ * If this display list's chain is not empty, we are on a list,
+ * and the next item is the display list that we must queue for
+ * automatic processing by the hardware.
+ */
struct vsp1_dl_list *next = list_next_entry(dl, chain);
dl->header->next_header = next->dma;
dl->header->flags = VSP1_DLH_AUTO_START;
+ } else if (!dlm->singleshot) {
+ /*
+ * if the display list manager works in continuous mode, the VSP
+ * should loop over the display list continuously until
+ * instructed to do otherwise.
+ */
+ dl->header->next_header = dl->dma;
+ dl->header->flags = VSP1_DLH_INT_ENABLE | VSP1_DLH_AUTO_START;
} else {
+ /*
+ * Otherwise, in mem-to-mem mode, we work in single-shot mode
+ * and the next display list must not be started automatically.
+ */
dl->header->flags = VSP1_DLH_INT_ENABLE;
}
}
-void vsp1_dl_list_commit(struct vsp1_dl_list *dl)
+static bool vsp1_dl_list_hw_update_pending(struct vsp1_dl_manager *dlm)
{
- struct vsp1_dl_manager *dlm = dl->dlm;
struct vsp1_device *vsp1 = dlm->vsp1;
- unsigned long flags;
- bool update;
- spin_lock_irqsave(&dlm->lock, flags);
+ if (!dlm->queued)
+ return false;
- if (dl->dlm->mode == VSP1_DL_MODE_HEADER) {
- struct vsp1_dl_list *dl_child;
+ /*
+ * Check whether the VSP1 has taken the update. In headerless mode the
+ * hardware indicates this by clearing the UPD bit in the DL_BODY_SIZE
+ * register, and in header mode by clearing the UPDHDR bit in the CMD
+ * register.
+ */
+ if (dlm->mode == VSP1_DL_MODE_HEADERLESS)
+ return !!(vsp1_read(vsp1, VI6_DL_BODY_SIZE)
+ & VI6_DL_BODY_SIZE_UPD);
+ else
+ return !!(vsp1_read(vsp1, VI6_CMD(dlm->index) & VI6_CMD_UPDHDR));
+}
+static void vsp1_dl_list_hw_enqueue(struct vsp1_dl_list *dl)
+{
+ struct vsp1_dl_manager *dlm = dl->dlm;
+ struct vsp1_device *vsp1 = dlm->vsp1;
+
+ if (dlm->mode == VSP1_DL_MODE_HEADERLESS) {
/*
- * In header mode the caller guarantees that the hardware is
- * idle at this point.
+ * In headerless mode, program the hardware directly with the
+ * display list body address and size and set the UPD bit. The
+ * bit will be cleared by the hardware when the display list
+ * processing starts.
*/
-
- /* Fill the header for the head and chained display lists. */
- vsp1_dl_list_fill_header(dl, list_empty(&dl->chain));
-
- list_for_each_entry(dl_child, &dl->chain, chain) {
- bool last = list_is_last(&dl_child->chain, &dl->chain);
-
- vsp1_dl_list_fill_header(dl_child, last);
- }
-
+ vsp1_write(vsp1, VI6_DL_HDR_ADDR(0), dl->body0.dma);
+ vsp1_write(vsp1, VI6_DL_BODY_SIZE, VI6_DL_BODY_SIZE_UPD |
+ (dl->body0.num_entries * sizeof(*dl->header->lists)));
+ } else {
/*
- * Commit the head display list to hardware. Chained headers
- * will auto-start.
+ * In header mode, program the display list header address. If
+ * the hardware is idle (single-shot mode or first frame in
+ * continuous mode) it will then be started independently. If
+ * the hardware is operating, the VI6_DL_HDR_REF_ADDR register
+ * will be updated with the display list address.
*/
vsp1_write(vsp1, VI6_DL_HDR_ADDR(dlm->index), dl->dma);
-
- dlm->active = dl;
- goto done;
}
+}
+
+static void vsp1_dl_list_commit_continuous(struct vsp1_dl_list *dl)
+{
+ struct vsp1_dl_manager *dlm = dl->dlm;
/*
- * Once the UPD bit has been set the hardware can start processing the
- * display list at any time and we can't touch the address and size
- * registers. In that case mark the update as pending, it will be
- * queued up to the hardware by the frame end interrupt handler.
+ * If a previous display list has been queued to the hardware but not
+ * processed yet, the VSP can start processing it at any time. In that
+ * case we can't replace the queued list by the new one, as we could
+ * race with the hardware. We thus mark the update as pending, it will
+ * be queued up to the hardware by the frame end interrupt handler.
*/
- update = !!(vsp1_read(vsp1, VI6_DL_BODY_SIZE) & VI6_DL_BODY_SIZE_UPD);
- if (update) {
+ if (vsp1_dl_list_hw_update_pending(dlm)) {
__vsp1_dl_list_put(dlm->pending);
dlm->pending = dl;
- goto done;
+ return;
}
/*
- * Program the hardware with the display list body address and size.
- * The UPD bit will be cleared by the device when the display list is
- * processed.
+ * Pass the new display list to the hardware and mark it as queued. It
+ * will become active when the hardware starts processing it.
*/
- vsp1_write(vsp1, VI6_DL_HDR_ADDR(0), dl->body0.dma);
- vsp1_write(vsp1, VI6_DL_BODY_SIZE, VI6_DL_BODY_SIZE_UPD |
- (dl->body0.num_entries * sizeof(*dl->header->lists)));
+ vsp1_dl_list_hw_enqueue(dl);
__vsp1_dl_list_put(dlm->queued);
dlm->queued = dl;
-
-done:
- spin_unlock_irqrestore(&dlm->lock, flags);
}
-/* -----------------------------------------------------------------------------
- * Display List Manager
- */
-
-/* Interrupt Handling */
-void vsp1_dlm_irq_display_start(struct vsp1_dl_manager *dlm)
+static void vsp1_dl_list_commit_singleshot(struct vsp1_dl_list *dl)
{
- spin_lock(&dlm->lock);
+ struct vsp1_dl_manager *dlm = dl->dlm;
/*
- * The display start interrupt signals the end of the display list
- * processing by the device. The active display list, if any, won't be
- * accessed anymore and can be reused.
+ * When working in single-shot mode, the caller guarantees that the
+ * hardware is idle at this point. Just commit the head display list
+ * to hardware. Chained lists will be started automatically.
*/
- __vsp1_dl_list_put(dlm->active);
- dlm->active = NULL;
+ vsp1_dl_list_hw_enqueue(dl);
- spin_unlock(&dlm->lock);
+ dlm->active = dl;
+}
+
+void vsp1_dl_list_commit(struct vsp1_dl_list *dl)
+{
+ struct vsp1_dl_manager *dlm = dl->dlm;
+ struct vsp1_dl_list *dl_child;
+ unsigned long flags;
+
+ if (dlm->mode == VSP1_DL_MODE_HEADER) {
+ /* Fill the header for the head and chained display lists. */
+ vsp1_dl_list_fill_header(dl, list_empty(&dl->chain));
+
+ list_for_each_entry(dl_child, &dl->chain, chain) {
+ bool last = list_is_last(&dl_child->chain, &dl->chain);
+
+ vsp1_dl_list_fill_header(dl_child, last);
+ }
+ }
+
+ spin_lock_irqsave(&dlm->lock, flags);
+
+ if (dlm->singleshot)
+ vsp1_dl_list_commit_singleshot(dl);
+ else
+ vsp1_dl_list_commit_continuous(dl);
+
+ spin_unlock_irqrestore(&dlm->lock, flags);
}
+/* -----------------------------------------------------------------------------
+ * Display List Manager
+ */
+
/**
* vsp1_dlm_irq_frame_end - Display list handler for the frame end interrupt
* @dlm: the display list manager
@@ -572,31 +621,28 @@ void vsp1_dlm_irq_display_start(struct vsp1_dl_manager *dlm)
*/
bool vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm)
{
- struct vsp1_device *vsp1 = dlm->vsp1;
bool completed = false;
spin_lock(&dlm->lock);
- __vsp1_dl_list_put(dlm->active);
- dlm->active = NULL;
-
/*
- * Header mode is used for mem-to-mem pipelines only. We don't need to
- * perform any operation as there can't be any new display list queued
- * in that case.
+ * The mem-to-mem pipelines work in single-shot mode. No new display
+ * list can be queued, we don't have to do anything.
*/
- if (dlm->mode == VSP1_DL_MODE_HEADER) {
+ if (dlm->singleshot) {
+ __vsp1_dl_list_put(dlm->active);
+ dlm->active = NULL;
completed = true;
goto done;
}
/*
- * The UPD bit set indicates that the commit operation raced with the
- * interrupt and occurred after the frame end event and UPD clear but
- * before interrupt processing. The hardware hasn't taken the update
- * into account yet, we'll thus skip one frame and retry.
+ * If the commit operation raced with the interrupt and occurred after
+ * the frame end event but before interrupt processing, the hardware
+ * hasn't taken the update into account yet. We have to skip one frame
+ * and retry.
*/
- if (vsp1_read(vsp1, VI6_DL_BODY_SIZE) & VI6_DL_BODY_SIZE_UPD)
+ if (vsp1_dl_list_hw_update_pending(dlm))
goto done;
/*
@@ -604,24 +650,20 @@ bool vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm)
* frame end interrupt. The display list thus becomes active.
*/
if (dlm->queued) {
+ __vsp1_dl_list_put(dlm->active);
dlm->active = dlm->queued;
dlm->queued = NULL;
completed = true;
}
/*
- * Now that the UPD bit has been cleared we can queue the next display
- * list to the hardware if one has been prepared.
+ * Now that the VSP has started processing the queued display list, we
+ * can queue the pending display list to the hardware if one has been
+ * prepared.
*/
if (dlm->pending) {
- struct vsp1_dl_list *dl = dlm->pending;
-
- vsp1_write(vsp1, VI6_DL_HDR_ADDR(0), dl->body0.dma);
- vsp1_write(vsp1, VI6_DL_BODY_SIZE, VI6_DL_BODY_SIZE_UPD |
- (dl->body0.num_entries *
- sizeof(*dl->header->lists)));
-
- dlm->queued = dl;
+ vsp1_dl_list_hw_enqueue(dlm->pending);
+ dlm->queued = dlm->pending;
dlm->pending = NULL;
}
@@ -714,6 +756,7 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
dlm->index = index;
dlm->mode = index == 0 && !vsp1->info->uapi
? VSP1_DL_MODE_HEADERLESS : VSP1_DL_MODE_HEADER;
+ dlm->singleshot = vsp1->info->uapi;
dlm->vsp1 = vsp1;
spin_lock_init(&dlm->lock);
diff --git a/drivers/media/platform/vsp1/vsp1_dl.h b/drivers/media/platform/vsp1/vsp1_dl.h
index 6ec1380..ee35081 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.h
+++ b/drivers/media/platform/vsp1/vsp1_dl.h
@@ -27,7 +27,6 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
unsigned int prealloc);
void vsp1_dlm_destroy(struct vsp1_dl_manager *dlm);
void vsp1_dlm_reset(struct vsp1_dl_manager *dlm);
-void vsp1_dlm_irq_display_start(struct vsp1_dl_manager *dlm);
bool vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm);
struct vsp1_dl_list *vsp1_dl_list_get(struct vsp1_dl_manager *dlm);
diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
index 9377aaf..4dfbeac 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.c
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -32,17 +32,13 @@
* Interrupt Handling
*/
-void vsp1_drm_display_start(struct vsp1_device *vsp1)
+static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe,
+ bool completed)
{
- vsp1_dlm_irq_display_start(vsp1->drm->pipe.output->dlm);
-}
-
-static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe)
-{
- struct vsp1_drm *drm = to_vsp1_drm(pipe);
+ struct vsp1_drm_pipeline *drm_pipe = to_vsp1_drm_pipeline(pipe);
- if (drm->du_complete)
- drm->du_complete(drm->du_private);
+ if (drm_pipe->du_complete)
+ drm_pipe->du_complete(drm_pipe->du_private, completed);
}
/* -----------------------------------------------------------------------------
@@ -63,29 +59,44 @@ EXPORT_SYMBOL_GPL(vsp1_du_init);
/**
* vsp1_du_setup_lif - Setup the output part of the VSP pipeline
* @dev: the VSP device
+ * @pipe_index: the DRM pipeline index
* @cfg: the LIF configuration
*
* Configure the output part of VSP DRM pipeline for the given frame @cfg.width
- * and @cfg.height. This sets up formats on the BRU source pad, the WPF0 sink
- * and source pads, and the LIF sink pad.
+ * and @cfg.height. This sets up formats on the blend unit (BRU or BRS) source
+ * pad, the WPF sink and source pads, and the LIF sink pad.
+ *
+ * The @pipe_index argument selects which DRM pipeline to setup. The number of
+ * available pipelines depend on the VSP instance.
*
- * As the media bus code on the BRU source pad is conditioned by the
- * configuration of the BRU sink 0 pad, we also set up the formats on all BRU
+ * As the media bus code on the blend unit source pad is conditioned by the
+ * configuration of its sink 0 pad, we also set up the formats on all blend unit
* sinks, even if the configuration will be overwritten later by
- * vsp1_du_setup_rpf(). This ensures that the BRU configuration is set to a well
- * defined state.
+ * vsp1_du_setup_rpf(). This ensures that the blend unit configuration is set to
+ * a well defined state.
*
* Return 0 on success or a negative error code on failure.
*/
-int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg)
+int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index,
+ const struct vsp1_du_lif_config *cfg)
{
struct vsp1_device *vsp1 = dev_get_drvdata(dev);
- struct vsp1_pipeline *pipe = &vsp1->drm->pipe;
- struct vsp1_bru *bru = vsp1->bru;
+ struct vsp1_drm_pipeline *drm_pipe;
+ struct vsp1_pipeline *pipe;
+ struct vsp1_bru *bru;
struct v4l2_subdev_format format;
+ const char *bru_name;
unsigned int i;
int ret;
+ if (pipe_index >= vsp1->info->lif_count)
+ return -EINVAL;
+
+ drm_pipe = &vsp1->drm->pipe[pipe_index];
+ pipe = &drm_pipe->pipe;
+ bru = to_bru(&pipe->bru->subdev);
+ bru_name = pipe->bru->type == VSP1_ENTITY_BRU ? "BRU" : "BRS";
+
if (!cfg) {
/*
* NULL configuration means the CRTC is being disabled, stop
@@ -97,14 +108,25 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg)
media_pipeline_stop(&pipe->output->entity.subdev.entity);
- for (i = 0; i < bru->entity.source_pad; ++i) {
- vsp1->drm->inputs[i].enabled = false;
- bru->inputs[i].rpf = NULL;
+ for (i = 0; i < ARRAY_SIZE(pipe->inputs); ++i) {
+ struct vsp1_rwpf *rpf = pipe->inputs[i];
+
+ if (!rpf)
+ continue;
+
+ /*
+ * Remove the RPF from the pipe and the list of BRU
+ * inputs.
+ */
+ WARN_ON(list_empty(&rpf->entity.list_pipe));
+ list_del_init(&rpf->entity.list_pipe);
pipe->inputs[i] = NULL;
+
+ bru->inputs[rpf->bru_input].rpf = NULL;
}
+ drm_pipe->du_complete = NULL;
pipe->num_inputs = 0;
- vsp1->drm->du_complete = NULL;
vsp1_dlm_reset(pipe->output->dlm);
vsp1_device_put(vsp1);
@@ -114,8 +136,8 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg)
return 0;
}
- dev_dbg(vsp1->dev, "%s: configuring LIF with format %ux%u\n",
- __func__, cfg->width, cfg->height);
+ dev_dbg(vsp1->dev, "%s: configuring LIF%u with format %ux%u\n",
+ __func__, pipe_index, cfg->width, cfg->height);
/*
* Configure the format at the BRU sinks and propagate it through the
@@ -124,7 +146,7 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg)
memset(&format, 0, sizeof(format));
format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- for (i = 0; i < bru->entity.source_pad; ++i) {
+ for (i = 0; i < pipe->bru->source_pad; ++i) {
format.pad = i;
format.format.width = cfg->width;
@@ -132,60 +154,60 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg)
format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
format.format.field = V4L2_FIELD_NONE;
- ret = v4l2_subdev_call(&bru->entity.subdev, pad,
+ ret = v4l2_subdev_call(&pipe->bru->subdev, pad,
set_fmt, NULL, &format);
if (ret < 0)
return ret;
- dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on BRU pad %u\n",
+ dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on %s pad %u\n",
__func__, format.format.width, format.format.height,
- format.format.code, i);
+ format.format.code, bru_name, i);
}
- format.pad = bru->entity.source_pad;
+ format.pad = pipe->bru->source_pad;
format.format.width = cfg->width;
format.format.height = cfg->height;
format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
format.format.field = V4L2_FIELD_NONE;
- ret = v4l2_subdev_call(&bru->entity.subdev, pad, set_fmt, NULL,
+ ret = v4l2_subdev_call(&pipe->bru->subdev, pad, set_fmt, NULL,
&format);
if (ret < 0)
return ret;
- dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on BRU pad %u\n",
+ dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on %s pad %u\n",
__func__, format.format.width, format.format.height,
- format.format.code, i);
+ format.format.code, bru_name, i);
format.pad = RWPF_PAD_SINK;
- ret = v4l2_subdev_call(&vsp1->wpf[0]->entity.subdev, pad, set_fmt, NULL,
+ ret = v4l2_subdev_call(&pipe->output->entity.subdev, pad, set_fmt, NULL,
&format);
if (ret < 0)
return ret;
- dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on WPF0 sink\n",
+ dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on WPF%u sink\n",
__func__, format.format.width, format.format.height,
- format.format.code);
+ format.format.code, pipe->output->entity.index);
format.pad = RWPF_PAD_SOURCE;
- ret = v4l2_subdev_call(&vsp1->wpf[0]->entity.subdev, pad, get_fmt, NULL,
+ ret = v4l2_subdev_call(&pipe->output->entity.subdev, pad, get_fmt, NULL,
&format);
if (ret < 0)
return ret;
- dev_dbg(vsp1->dev, "%s: got format %ux%u (%x) on WPF0 source\n",
+ dev_dbg(vsp1->dev, "%s: got format %ux%u (%x) on WPF%u source\n",
__func__, format.format.width, format.format.height,
- format.format.code);
+ format.format.code, pipe->output->entity.index);
format.pad = LIF_PAD_SINK;
- ret = v4l2_subdev_call(&vsp1->lif->entity.subdev, pad, set_fmt, NULL,
+ ret = v4l2_subdev_call(&pipe->lif->subdev, pad, set_fmt, NULL,
&format);
if (ret < 0)
return ret;
- dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on LIF sink\n",
+ dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on LIF%u sink\n",
__func__, format.format.width, format.format.height,
- format.format.code);
+ format.format.code, pipe_index);
/*
* Verify that the format at the output of the pipeline matches the
@@ -213,8 +235,8 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg)
* Register a callback to allow us to notify the DRM driver of frame
* completion events.
*/
- vsp1->drm->du_complete = cfg->callback;
- vsp1->drm->du_private = cfg->callback_data;
+ drm_pipe->du_complete = cfg->callback;
+ drm_pipe->du_private = cfg->callback_data;
ret = media_pipeline_start(&pipe->output->entity.subdev.entity,
&pipe->pipe);
@@ -224,6 +246,10 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg)
return ret;
}
+ /* Disable the display interrupts. */
+ vsp1_write(vsp1, VI6_DISP_IRQ_STA, 0);
+ vsp1_write(vsp1, VI6_DISP_IRQ_ENB, 0);
+
dev_dbg(vsp1->dev, "%s: pipeline enabled\n", __func__);
return 0;
@@ -233,19 +259,21 @@ EXPORT_SYMBOL_GPL(vsp1_du_setup_lif);
/**
* vsp1_du_atomic_begin - Prepare for an atomic update
* @dev: the VSP device
+ * @pipe_index: the DRM pipeline index
*/
-void vsp1_du_atomic_begin(struct device *dev)
+void vsp1_du_atomic_begin(struct device *dev, unsigned int pipe_index)
{
struct vsp1_device *vsp1 = dev_get_drvdata(dev);
- struct vsp1_pipeline *pipe = &vsp1->drm->pipe;
+ struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
- vsp1->drm->num_inputs = pipe->num_inputs;
+ drm_pipe->enabled = drm_pipe->pipe.num_inputs != 0;
}
EXPORT_SYMBOL_GPL(vsp1_du_atomic_begin);
/**
* vsp1_du_atomic_update - Setup one RPF input of the VSP pipeline
* @dev: the VSP device
+ * @pipe_index: the DRM pipeline index
* @rpf_index: index of the RPF to setup (0-based)
* @cfg: the RPF configuration
*
@@ -272,10 +300,12 @@ EXPORT_SYMBOL_GPL(vsp1_du_atomic_begin);
*
* Return 0 on success or a negative error code on failure.
*/
-int vsp1_du_atomic_update(struct device *dev, unsigned int rpf_index,
+int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index,
+ unsigned int rpf_index,
const struct vsp1_du_atomic_config *cfg)
{
struct vsp1_device *vsp1 = dev_get_drvdata(dev);
+ struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
const struct vsp1_format_info *fmtinfo;
struct vsp1_rwpf *rpf;
@@ -288,7 +318,12 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int rpf_index,
dev_dbg(vsp1->dev, "%s: RPF%u: disable requested\n", __func__,
rpf_index);
- vsp1->drm->inputs[rpf_index].enabled = false;
+ /*
+ * Remove the RPF from the pipe's inputs. The atomic flush
+ * handler will disable the input and remove the entity from the
+ * pipe's entities list.
+ */
+ drm_pipe->pipe.inputs[rpf_index] = NULL;
return 0;
}
@@ -324,13 +359,15 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int rpf_index,
vsp1->drm->inputs[rpf_index].crop = cfg->src;
vsp1->drm->inputs[rpf_index].compose = cfg->dst;
vsp1->drm->inputs[rpf_index].zpos = cfg->zpos;
- vsp1->drm->inputs[rpf_index].enabled = true;
+
+ drm_pipe->pipe.inputs[rpf_index] = rpf;
return 0;
}
EXPORT_SYMBOL_GPL(vsp1_du_atomic_update);
static int vsp1_du_setup_rpf_pipe(struct vsp1_device *vsp1,
+ struct vsp1_pipeline *pipe,
struct vsp1_rwpf *rpf, unsigned int bru_input)
{
struct v4l2_subdev_selection sel;
@@ -404,7 +441,7 @@ static int vsp1_du_setup_rpf_pipe(struct vsp1_device *vsp1,
/* BRU sink, propagate the format from the RPF source. */
format.pad = bru_input;
- ret = v4l2_subdev_call(&vsp1->bru->entity.subdev, pad, set_fmt, NULL,
+ ret = v4l2_subdev_call(&pipe->bru->subdev, pad, set_fmt, NULL,
&format);
if (ret < 0)
return ret;
@@ -417,8 +454,8 @@ static int vsp1_du_setup_rpf_pipe(struct vsp1_device *vsp1,
sel.target = V4L2_SEL_TGT_COMPOSE;
sel.r = vsp1->drm->inputs[rpf->entity.index].compose;
- ret = v4l2_subdev_call(&vsp1->bru->entity.subdev, pad, set_selection,
- NULL, &sel);
+ ret = v4l2_subdev_call(&pipe->bru->subdev, pad, set_selection, NULL,
+ &sel);
if (ret < 0)
return ret;
@@ -438,18 +475,25 @@ static unsigned int rpf_zpos(struct vsp1_device *vsp1, struct vsp1_rwpf *rpf)
/**
* vsp1_du_atomic_flush - Commit an atomic update
* @dev: the VSP device
+ * @pipe_index: the DRM pipeline index
*/
-void vsp1_du_atomic_flush(struct device *dev)
+void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index)
{
struct vsp1_device *vsp1 = dev_get_drvdata(dev);
- struct vsp1_pipeline *pipe = &vsp1->drm->pipe;
+ struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
+ struct vsp1_pipeline *pipe = &drm_pipe->pipe;
struct vsp1_rwpf *inputs[VSP1_MAX_RPF] = { NULL, };
+ struct vsp1_bru *bru = to_bru(&pipe->bru->subdev);
struct vsp1_entity *entity;
+ struct vsp1_entity *next;
struct vsp1_dl_list *dl;
+ const char *bru_name;
unsigned long flags;
unsigned int i;
int ret;
+ bru_name = pipe->bru->type == VSP1_ENTITY_BRU ? "BRU" : "BRS";
+
/* Prepare the display list. */
dl = vsp1_dl_list_get(pipe->output->dlm);
@@ -460,12 +504,8 @@ void vsp1_du_atomic_flush(struct device *dev)
struct vsp1_rwpf *rpf = vsp1->rpf[i];
unsigned int j;
- if (!vsp1->drm->inputs[i].enabled) {
- pipe->inputs[i] = NULL;
+ if (!pipe->inputs[i])
continue;
- }
-
- pipe->inputs[i] = rpf;
/* Insert the RPF in the sorted RPFs array. */
for (j = pipe->num_inputs++; j > 0; --j) {
@@ -478,22 +518,26 @@ void vsp1_du_atomic_flush(struct device *dev)
}
/* Setup the RPF input pipeline for every enabled input. */
- for (i = 0; i < vsp1->info->num_bru_inputs; ++i) {
+ for (i = 0; i < pipe->bru->source_pad; ++i) {
struct vsp1_rwpf *rpf = inputs[i];
if (!rpf) {
- vsp1->bru->inputs[i].rpf = NULL;
+ bru->inputs[i].rpf = NULL;
continue;
}
- vsp1->bru->inputs[i].rpf = rpf;
+ if (list_empty(&rpf->entity.list_pipe))
+ list_add_tail(&rpf->entity.list_pipe, &pipe->entities);
+
+ bru->inputs[i].rpf = rpf;
rpf->bru_input = i;
+ rpf->entity.sink = pipe->bru;
rpf->entity.sink_pad = i;
- dev_dbg(vsp1->dev, "%s: connecting RPF.%u to BRU:%u\n",
- __func__, rpf->entity.index, i);
+ dev_dbg(vsp1->dev, "%s: connecting RPF.%u to %s:%u\n",
+ __func__, rpf->entity.index, bru_name, i);
- ret = vsp1_du_setup_rpf_pipe(vsp1, rpf, i);
+ ret = vsp1_du_setup_rpf_pipe(vsp1, pipe, rpf, i);
if (ret < 0)
dev_err(vsp1->dev,
"%s: failed to setup RPF.%u\n",
@@ -501,16 +545,16 @@ void vsp1_du_atomic_flush(struct device *dev)
}
/* Configure all entities in the pipeline. */
- list_for_each_entry(entity, &pipe->entities, list_pipe) {
+ list_for_each_entry_safe(entity, next, &pipe->entities, list_pipe) {
/* Disconnect unused RPFs from the pipeline. */
- if (entity->type == VSP1_ENTITY_RPF) {
- struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev);
+ if (entity->type == VSP1_ENTITY_RPF &&
+ !pipe->inputs[entity->index]) {
+ vsp1_dl_list_write(dl, entity->route->reg,
+ VI6_DPR_NODE_UNUSED);
- if (!pipe->inputs[rpf->entity.index]) {
- vsp1_dl_list_write(dl, entity->route->reg,
- VI6_DPR_NODE_UNUSED);
- continue;
- }
+ list_del_init(&entity->list_pipe);
+
+ continue;
}
vsp1_entity_route_setup(entity, pipe, dl);
@@ -528,14 +572,11 @@ void vsp1_du_atomic_flush(struct device *dev)
vsp1_dl_list_commit(dl);
/* Start or stop the pipeline if needed. */
- if (!vsp1->drm->num_inputs && pipe->num_inputs) {
- vsp1_write(vsp1, VI6_DISP_IRQ_STA, 0);
- vsp1_write(vsp1, VI6_DISP_IRQ_ENB, VI6_DISP_IRQ_ENB_DSTE);
+ if (!drm_pipe->enabled && pipe->num_inputs) {
spin_lock_irqsave(&pipe->irqlock, flags);
vsp1_pipeline_run(pipe);
spin_unlock_irqrestore(&pipe->irqlock, flags);
- } else if (vsp1->drm->num_inputs && !pipe->num_inputs) {
- vsp1_write(vsp1, VI6_DISP_IRQ_ENB, 0);
+ } else if (drm_pipe->enabled && !pipe->num_inputs) {
vsp1_pipeline_stop(pipe);
}
}
@@ -568,83 +609,48 @@ EXPORT_SYMBOL_GPL(vsp1_du_unmap_sg);
* Initialization
*/
-int vsp1_drm_create_links(struct vsp1_device *vsp1)
-{
- const u32 flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE;
- unsigned int i;
- int ret;
-
- /*
- * VSPD instances require a BRU to perform composition and a LIF to
- * output to the DU.
- */
- if (!vsp1->bru || !vsp1->lif)
- return -ENXIO;
-
- for (i = 0; i < vsp1->info->rpf_count; ++i) {
- struct vsp1_rwpf *rpf = vsp1->rpf[i];
-
- ret = media_create_pad_link(&rpf->entity.subdev.entity,
- RWPF_PAD_SOURCE,
- &vsp1->bru->entity.subdev.entity,
- i, flags);
- if (ret < 0)
- return ret;
-
- rpf->entity.sink = &vsp1->bru->entity.subdev.entity;
- rpf->entity.sink_pad = i;
- }
-
- ret = media_create_pad_link(&vsp1->bru->entity.subdev.entity,
- vsp1->bru->entity.source_pad,
- &vsp1->wpf[0]->entity.subdev.entity,
- RWPF_PAD_SINK, flags);
- if (ret < 0)
- return ret;
-
- vsp1->bru->entity.sink = &vsp1->wpf[0]->entity.subdev.entity;
- vsp1->bru->entity.sink_pad = RWPF_PAD_SINK;
-
- ret = media_create_pad_link(&vsp1->wpf[0]->entity.subdev.entity,
- RWPF_PAD_SOURCE,
- &vsp1->lif->entity.subdev.entity,
- LIF_PAD_SINK, flags);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
int vsp1_drm_init(struct vsp1_device *vsp1)
{
- struct vsp1_pipeline *pipe;
unsigned int i;
vsp1->drm = devm_kzalloc(vsp1->dev, sizeof(*vsp1->drm), GFP_KERNEL);
if (!vsp1->drm)
return -ENOMEM;
- pipe = &vsp1->drm->pipe;
+ /* Create one DRM pipeline per LIF. */
+ for (i = 0; i < vsp1->info->lif_count; ++i) {
+ struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[i];
+ struct vsp1_pipeline *pipe = &drm_pipe->pipe;
- vsp1_pipeline_init(pipe);
+ vsp1_pipeline_init(pipe);
- /* The DRM pipeline is static, add entities manually. */
+ /*
+ * The DRM pipeline is static, add entities manually. The first
+ * pipeline uses the BRU and the second pipeline the BRS.
+ */
+ pipe->bru = i == 0 ? &vsp1->bru->entity : &vsp1->brs->entity;
+ pipe->lif = &vsp1->lif[i]->entity;
+ pipe->output = vsp1->wpf[i];
+ pipe->output->pipe = pipe;
+ pipe->frame_end = vsp1_du_pipeline_frame_end;
+
+ pipe->bru->sink = &pipe->output->entity;
+ pipe->bru->sink_pad = 0;
+ pipe->output->entity.sink = pipe->lif;
+ pipe->output->entity.sink_pad = 0;
+
+ list_add_tail(&pipe->bru->list_pipe, &pipe->entities);
+ list_add_tail(&pipe->lif->list_pipe, &pipe->entities);
+ list_add_tail(&pipe->output->entity.list_pipe, &pipe->entities);
+ }
+
+ /* Disable all RPFs initially. */
for (i = 0; i < vsp1->info->rpf_count; ++i) {
struct vsp1_rwpf *input = vsp1->rpf[i];
- list_add_tail(&input->entity.list_pipe, &pipe->entities);
+ INIT_LIST_HEAD(&input->entity.list_pipe);
}
- list_add_tail(&vsp1->bru->entity.list_pipe, &pipe->entities);
- list_add_tail(&vsp1->wpf[0]->entity.list_pipe, &pipe->entities);
- list_add_tail(&vsp1->lif->entity.list_pipe, &pipe->entities);
-
- pipe->bru = &vsp1->bru->entity;
- pipe->lif = &vsp1->lif->entity;
- pipe->output = vsp1->wpf[0];
- pipe->output->pipe = pipe;
- pipe->frame_end = vsp1_du_pipeline_frame_end;
-
return 0;
}
diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h
index e9f8072..1cd9db7 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.h
+++ b/drivers/media/platform/vsp1/vsp1_drm.h
@@ -18,38 +18,44 @@
#include "vsp1_pipe.h"
/**
- * vsp1_drm - State for the API exposed to the DRM driver
+ * vsp1_drm_pipeline - State for the API exposed to the DRM driver
* @pipe: the VSP1 pipeline used for display
- * @num_inputs: number of active pipeline inputs at the beginning of an update
- * @inputs: source crop rectangle, destination compose rectangle and z-order
- * position for every input
+ * @enabled: pipeline state at the beginning of an update
* @du_complete: frame completion callback for the DU driver (optional)
* @du_private: data to be passed to the du_complete callback
*/
-struct vsp1_drm {
+struct vsp1_drm_pipeline {
struct vsp1_pipeline pipe;
- unsigned int num_inputs;
+ bool enabled;
+
+ /* Frame synchronisation */
+ void (*du_complete)(void *, bool);
+ void *du_private;
+};
+
+/**
+ * vsp1_drm - State for the API exposed to the DRM driver
+ * @pipe: the VSP1 DRM pipeline used for display
+ * @inputs: source crop rectangle, destination compose rectangle and z-order
+ * position for every input (indexed by RPF index)
+ */
+struct vsp1_drm {
+ struct vsp1_drm_pipeline pipe[VSP1_MAX_LIF];
+
struct {
- bool enabled;
struct v4l2_rect crop;
struct v4l2_rect compose;
unsigned int zpos;
} inputs[VSP1_MAX_RPF];
-
- /* Frame synchronisation */
- void (*du_complete)(void *);
- void *du_private;
};
-static inline struct vsp1_drm *to_vsp1_drm(struct vsp1_pipeline *pipe)
+static inline struct vsp1_drm_pipeline *
+to_vsp1_drm_pipeline(struct vsp1_pipeline *pipe)
{
- return container_of(pipe, struct vsp1_drm, pipe);
+ return container_of(pipe, struct vsp1_drm_pipeline, pipe);
}
int vsp1_drm_init(struct vsp1_device *vsp1);
void vsp1_drm_cleanup(struct vsp1_device *vsp1);
-int vsp1_drm_create_links(struct vsp1_device *vsp1);
-
-void vsp1_drm_display_start(struct vsp1_device *vsp1);
#endif /* __VSP1_DRM_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 95c26ed..962e4c3 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -68,14 +68,6 @@ static irqreturn_t vsp1_irq_handler(int irq, void *data)
}
}
- status = vsp1_read(vsp1, VI6_DISP_IRQ_STA);
- vsp1_write(vsp1, VI6_DISP_IRQ_STA, ~status & VI6_DISP_IRQ_STA_DST);
-
- if (status & VI6_DISP_IRQ_STA_DST) {
- vsp1_drm_display_start(vsp1);
- ret = IRQ_HANDLED;
- }
-
return ret;
}
@@ -92,6 +84,10 @@ static irqreturn_t vsp1_irq_handler(int irq, void *data)
*
* - from a UDS to a UDS (UDS entities can't be chained)
* - from an entity to itself (no loops are allowed)
+ *
+ * Furthermore, the BRS can't be connected to histogram generators, but no
+ * special check is currently needed as all VSP instances that include a BRS
+ * have no histogram generator.
*/
static int vsp1_create_sink_links(struct vsp1_device *vsp1,
struct vsp1_entity *sink)
@@ -129,7 +125,7 @@ static int vsp1_create_sink_links(struct vsp1_device *vsp1,
return ret;
if (flags & MEDIA_LNK_FL_ENABLED)
- source->sink = entity;
+ source->sink = sink;
}
}
@@ -172,10 +168,13 @@ static int vsp1_uapi_create_links(struct vsp1_device *vsp1)
return ret;
}
- if (vsp1->lif) {
- ret = media_create_pad_link(&vsp1->wpf[0]->entity.subdev.entity,
+ for (i = 0; i < vsp1->info->lif_count; ++i) {
+ if (!vsp1->lif[i])
+ continue;
+
+ ret = media_create_pad_link(&vsp1->wpf[i]->entity.subdev.entity,
RWPF_PAD_SOURCE,
- &vsp1->lif->entity.subdev.entity,
+ &vsp1->lif[i]->entity.subdev.entity,
LIF_PAD_SINK, 0);
if (ret < 0)
return ret;
@@ -269,8 +268,18 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
}
/* Instantiate all the entities. */
+ if (vsp1->info->features & VSP1_HAS_BRS) {
+ vsp1->brs = vsp1_bru_create(vsp1, VSP1_ENTITY_BRS);
+ if (IS_ERR(vsp1->brs)) {
+ ret = PTR_ERR(vsp1->brs);
+ goto done;
+ }
+
+ list_add_tail(&vsp1->brs->entity.list_dev, &vsp1->entities);
+ }
+
if (vsp1->info->features & VSP1_HAS_BRU) {
- vsp1->bru = vsp1_bru_create(vsp1);
+ vsp1->bru = vsp1_bru_create(vsp1, VSP1_ENTITY_BRU);
if (IS_ERR(vsp1->bru)) {
ret = PTR_ERR(vsp1->bru);
goto done;
@@ -328,18 +337,23 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
}
/*
- * The LIF is only supported when used in conjunction with the DU, in
+ * The LIFs are only supported when used in conjunction with the DU, in
* which case the userspace API is disabled. If the userspace API is
- * enabled skip the LIF, even when present.
+ * enabled skip the LIFs, even when present.
*/
- if (vsp1->info->features & VSP1_HAS_LIF && !vsp1->info->uapi) {
- vsp1->lif = vsp1_lif_create(vsp1);
- if (IS_ERR(vsp1->lif)) {
- ret = PTR_ERR(vsp1->lif);
- goto done;
- }
+ if (!vsp1->info->uapi) {
+ for (i = 0; i < vsp1->info->lif_count; ++i) {
+ struct vsp1_lif *lif;
+
+ lif = vsp1_lif_create(vsp1, i);
+ if (IS_ERR(lif)) {
+ ret = PTR_ERR(lif);
+ goto done;
+ }
- list_add_tail(&vsp1->lif->entity.list_dev, &vsp1->entities);
+ vsp1->lif[i] = lif;
+ list_add_tail(&lif->entity.list_dev, &vsp1->entities);
+ }
}
if (vsp1->info->features & VSP1_HAS_LUT) {
@@ -420,7 +434,6 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
}
list_add_tail(&video->list, &vsp1->videos);
- wpf->entity.sink = &video->video.entity;
}
}
@@ -432,19 +445,15 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
goto done;
}
- /* Create links. */
- if (vsp1->info->uapi)
- ret = vsp1_uapi_create_links(vsp1);
- else
- ret = vsp1_drm_create_links(vsp1);
- if (ret < 0)
- goto done;
-
/*
- * Register subdev nodes if the userspace API is enabled or initialize
- * the DRM pipeline otherwise.
+ * Create links and register subdev nodes if the userspace API is
+ * enabled or initialize the DRM pipeline otherwise.
*/
if (vsp1->info->uapi) {
+ ret = vsp1_uapi_create_links(vsp1);
+ if (ret < 0)
+ goto done;
+
ret = v4l2_device_register_subdev_nodes(&vsp1->v4l2_dev);
if (ret < 0)
goto done;
@@ -515,6 +524,9 @@ static int vsp1_device_init(struct vsp1_device *vsp1)
vsp1_write(vsp1, VI6_DPR_HSI_ROUTE, VI6_DPR_NODE_UNUSED);
vsp1_write(vsp1, VI6_DPR_BRU_ROUTE, VI6_DPR_NODE_UNUSED);
+ if (vsp1->info->features & VSP1_HAS_BRS)
+ vsp1_write(vsp1, VI6_DPR_ILV_BRS_ROUTE, VI6_DPR_NODE_UNUSED);
+
vsp1_write(vsp1, VI6_DPR_HGO_SMPPT, (7 << VI6_DPR_SMPPT_TGW_SHIFT) |
(VI6_DPR_NODE_UNUSED << VI6_DPR_SMPPT_PT_SHIFT));
vsp1_write(vsp1, VI6_DPR_HGT_SMPPT, (7 << VI6_DPR_SMPPT_TGW_SHIFT) |
@@ -634,8 +646,8 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
.version = VI6_IP_VERSION_MODEL_VSPD_GEN2,
.model = "VSP1-D",
.gen = 2,
- .features = VSP1_HAS_BRU | VSP1_HAS_HGO | VSP1_HAS_LIF
- | VSP1_HAS_LUT,
+ .features = VSP1_HAS_BRU | VSP1_HAS_HGO | VSP1_HAS_LUT,
+ .lif_count = 1,
.rpf_count = 4,
.uds_count = 1,
.wpf_count = 1,
@@ -668,8 +680,8 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
.version = VI6_IP_VERSION_MODEL_VSPD_V2H,
.model = "VSP1V-D",
.gen = 2,
- .features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_LUT
- | VSP1_HAS_LIF,
+ .features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_LUT,
+ .lif_count = 1,
.rpf_count = 4,
.uds_count = 1,
.wpf_count = 1,
@@ -706,10 +718,37 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
.num_bru_inputs = 5,
.uapi = true,
}, {
+ .version = VI6_IP_VERSION_MODEL_VSPBS_GEN3,
+ .model = "VSP2-BS",
+ .gen = 3,
+ .features = VSP1_HAS_BRS | VSP1_HAS_WPF_VFLIP,
+ .rpf_count = 2,
+ .wpf_count = 1,
+ .uapi = true,
+ }, {
.version = VI6_IP_VERSION_MODEL_VSPD_GEN3,
.model = "VSP2-D",
.gen = 3,
- .features = VSP1_HAS_BRU | VSP1_HAS_LIF | VSP1_HAS_WPF_VFLIP,
+ .features = VSP1_HAS_BRU | VSP1_HAS_WPF_VFLIP,
+ .lif_count = 1,
+ .rpf_count = 5,
+ .wpf_count = 2,
+ .num_bru_inputs = 5,
+ }, {
+ .version = VI6_IP_VERSION_MODEL_VSPD_V3,
+ .model = "VSP2-D",
+ .gen = 3,
+ .features = VSP1_HAS_BRS | VSP1_HAS_BRU,
+ .lif_count = 1,
+ .rpf_count = 5,
+ .wpf_count = 1,
+ .num_bru_inputs = 5,
+ }, {
+ .version = VI6_IP_VERSION_MODEL_VSPDL_GEN3,
+ .model = "VSP2-DL",
+ .gen = 3,
+ .features = VSP1_HAS_BRS | VSP1_HAS_BRU,
+ .lif_count = 2,
.rpf_count = 5,
.wpf_count = 2,
.num_bru_inputs = 5,
diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index 4bdb3b1..54de150 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -24,18 +24,12 @@
#include "vsp1_pipe.h"
#include "vsp1_rwpf.h"
-static inline struct vsp1_entity *
-media_entity_to_vsp1_entity(struct media_entity *entity)
-{
- return container_of(entity, struct vsp1_entity, subdev.entity);
-}
-
void vsp1_entity_route_setup(struct vsp1_entity *entity,
struct vsp1_pipeline *pipe,
struct vsp1_dl_list *dl)
{
struct vsp1_entity *source;
- struct vsp1_entity *sink;
+ u32 route;
if (entity->type == VSP1_ENTITY_HGO) {
u32 smppt;
@@ -44,7 +38,7 @@ void vsp1_entity_route_setup(struct vsp1_entity *entity,
* The HGO is a special case, its routing is configured on the
* sink pad.
*/
- source = media_entity_to_vsp1_entity(entity->sources[0]);
+ source = entity->sources[0];
smppt = (pipe->output->entity.index << VI6_DPR_SMPPT_TGW_SHIFT)
| (source->route->output << VI6_DPR_SMPPT_PT_SHIFT);
@@ -57,7 +51,7 @@ void vsp1_entity_route_setup(struct vsp1_entity *entity,
* The HGT is a special case, its routing is configured on the
* sink pad.
*/
- source = media_entity_to_vsp1_entity(entity->sources[0]);
+ source = entity->sources[0];
smppt = (pipe->output->entity.index << VI6_DPR_SMPPT_TGW_SHIFT)
| (source->route->output << VI6_DPR_SMPPT_PT_SHIFT);
@@ -69,9 +63,14 @@ void vsp1_entity_route_setup(struct vsp1_entity *entity,
if (source->route->reg == 0)
return;
- sink = media_entity_to_vsp1_entity(source->sink);
- vsp1_dl_list_write(dl, source->route->reg,
- sink->route->inputs[source->sink_pad]);
+ route = source->sink->route->inputs[source->sink_pad];
+ /*
+ * The ILV and BRS share the same data path route. The extra BRSSEL bit
+ * selects between the ILV and BRS.
+ */
+ if (source->type == VSP1_ENTITY_BRS)
+ route |= VI6_DPR_ROUTE_BRSSEL;
+ vsp1_dl_list_write(dl, source->route->reg, route);
}
/* -----------------------------------------------------------------------------
@@ -316,6 +315,12 @@ done:
* Media Operations
*/
+static inline struct vsp1_entity *
+media_entity_to_vsp1_entity(struct media_entity *entity)
+{
+ return container_of(entity, struct vsp1_entity, subdev.entity);
+}
+
static int vsp1_entity_link_setup_source(const struct media_pad *source_pad,
const struct media_pad *sink_pad,
u32 flags)
@@ -339,7 +344,7 @@ static int vsp1_entity_link_setup_source(const struct media_pad *source_pad,
sink->type != VSP1_ENTITY_HGT) {
if (source->sink)
return -EBUSY;
- source->sink = sink_pad->entity;
+ source->sink = sink;
source->sink_pad = sink_pad->index;
}
} else {
@@ -355,15 +360,17 @@ static int vsp1_entity_link_setup_sink(const struct media_pad *source_pad,
u32 flags)
{
struct vsp1_entity *sink;
+ struct vsp1_entity *source;
sink = media_entity_to_vsp1_entity(sink_pad->entity);
+ source = media_entity_to_vsp1_entity(source_pad->entity);
if (flags & MEDIA_LNK_FL_ENABLED) {
/* Fan-in is limited to one. */
if (sink->sources[sink_pad->index])
return -EBUSY;
- sink->sources[sink_pad->index] = source_pad->entity;
+ sink->sources[sink_pad->index] = source;
} else {
sink->sources[sink_pad->index] = NULL;
}
@@ -450,6 +457,8 @@ struct media_pad *vsp1_entity_remote_pad(struct media_pad *pad)
{ VI6_DPR_NODE_WPF(idx) }, VI6_DPR_NODE_WPF(idx) }
static const struct vsp1_route vsp1_routes[] = {
+ { VSP1_ENTITY_BRS, 0, VI6_DPR_ILV_BRS_ROUTE,
+ { VI6_DPR_NODE_BRS_IN(0), VI6_DPR_NODE_BRS_IN(1) }, 0 },
{ VSP1_ENTITY_BRU, 0, VI6_DPR_BRU_ROUTE,
{ VI6_DPR_NODE_BRU_IN(0), VI6_DPR_NODE_BRU_IN(1),
VI6_DPR_NODE_BRU_IN(2), VI6_DPR_NODE_BRU_IN(3),
@@ -459,7 +468,8 @@ static const struct vsp1_route vsp1_routes[] = {
{ VSP1_ENTITY_HGT, 0, 0, { 0, }, 0 },
VSP1_ENTITY_ROUTE(HSI),
VSP1_ENTITY_ROUTE(HST),
- { VSP1_ENTITY_LIF, 0, 0, { VI6_DPR_NODE_LIF, }, VI6_DPR_NODE_LIF },
+ { VSP1_ENTITY_LIF, 0, 0, { 0, }, 0 },
+ { VSP1_ENTITY_LIF, 1, 0, { 0, }, 0 },
VSP1_ENTITY_ROUTE(LUT),
VSP1_ENTITY_ROUTE_RPF(0),
VSP1_ENTITY_ROUTE_RPF(1),
diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
index c169a06..11f8363 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.h
+++ b/drivers/media/platform/vsp1/vsp1_entity.h
@@ -23,6 +23,7 @@ struct vsp1_dl_list;
struct vsp1_pipeline;
enum vsp1_entity_type {
+ VSP1_ENTITY_BRS,
VSP1_ENTITY_BRU,
VSP1_ENTITY_CLU,
VSP1_ENTITY_HGO,
@@ -104,8 +105,8 @@ struct vsp1_entity {
struct media_pad *pads;
unsigned int source_pad;
- struct media_entity **sources;
- struct media_entity *sink;
+ struct vsp1_entity **sources;
+ struct vsp1_entity *sink;
unsigned int sink_pad;
struct v4l2_subdev subdev;
diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
index 702487f..e6fa16d 100644
--- a/drivers/media/platform/vsp1/vsp1_lif.c
+++ b/drivers/media/platform/vsp1/vsp1_lif.c
@@ -30,7 +30,7 @@
static inline void vsp1_lif_write(struct vsp1_lif *lif, struct vsp1_dl_list *dl,
u32 reg, u32 data)
{
- vsp1_dl_list_write(dl, reg, data);
+ vsp1_dl_list_write(dl, reg + lif->entity.index * VI6_LIF_OFFSET, data);
}
/* -----------------------------------------------------------------------------
@@ -165,7 +165,7 @@ static const struct vsp1_entity_operations lif_entity_ops = {
* Initialization and Cleanup
*/
-struct vsp1_lif *vsp1_lif_create(struct vsp1_device *vsp1)
+struct vsp1_lif *vsp1_lif_create(struct vsp1_device *vsp1, unsigned int index)
{
struct vsp1_lif *lif;
int ret;
@@ -176,6 +176,7 @@ struct vsp1_lif *vsp1_lif_create(struct vsp1_device *vsp1)
lif->entity.ops = &lif_entity_ops;
lif->entity.type = VSP1_ENTITY_LIF;
+ lif->entity.index = index;
/*
* The LIF is never exposed to userspace, but media entity registration
diff --git a/drivers/media/platform/vsp1/vsp1_lif.h b/drivers/media/platform/vsp1/vsp1_lif.h
index 7b35879..3417339 100644
--- a/drivers/media/platform/vsp1/vsp1_lif.h
+++ b/drivers/media/platform/vsp1/vsp1_lif.h
@@ -32,6 +32,6 @@ static inline struct vsp1_lif *to_lif(struct v4l2_subdev *subdev)
return container_of(subdev, struct vsp1_lif, entity.subdev);
}
-struct vsp1_lif *vsp1_lif_create(struct vsp1_device *vsp1);
+struct vsp1_lif *vsp1_lif_create(struct vsp1_device *vsp1, unsigned int index);
#endif /* __VSP1_LIF_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c b/drivers/media/platform/vsp1/vsp1_pipe.c
index e817623..4f4b732 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.c
+++ b/drivers/media/platform/vsp1/vsp1_pipe.c
@@ -335,16 +335,12 @@ void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe)
if (pipe == NULL)
return;
+ /*
+ * If the DL commit raced with the frame end interrupt, the commit ends
+ * up being postponed by one frame. @completed represents whether the
+ * active frame was finished or postponed.
+ */
completed = vsp1_dlm_irq_frame_end(pipe->output->dlm);
- if (!completed) {
- /*
- * If the DL commit raced with the frame end interrupt, the
- * commit ends up being postponed by one frame. Return
- * immediately without calling the pipeline's frame end handler
- * or incrementing the sequence number.
- */
- return;
- }
if (pipe->hgo)
vsp1_hgo_frame_end(pipe->hgo);
@@ -352,8 +348,12 @@ void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe)
if (pipe->hgt)
vsp1_hgt_frame_end(pipe->hgt);
+ /*
+ * Regardless of frame completion we still need to notify the pipe
+ * frame_end to account for vblank events.
+ */
if (pipe->frame_end)
- pipe->frame_end(pipe);
+ pipe->frame_end(pipe, completed);
pipe->sequence++;
}
@@ -373,10 +373,11 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
return;
/*
- * The BRU background color has a fixed alpha value set to 255, the
- * output alpha value is thus always equal to 255.
+ * The BRU and BRS background color has a fixed alpha value set to 255,
+ * the output alpha value is thus always equal to 255.
*/
- if (pipe->uds_input->type == VSP1_ENTITY_BRU)
+ if (pipe->uds_input->type == VSP1_ENTITY_BRU ||
+ pipe->uds_input->type == VSP1_ENTITY_BRS)
alpha = 255;
vsp1_uds_set_alpha(pipe->uds, dl, alpha);
diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h
index 91a784a..c5d01a3 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.h
+++ b/drivers/media/platform/vsp1/vsp1_pipe.h
@@ -91,7 +91,7 @@ struct vsp1_pipeline {
enum vsp1_pipeline_state state;
wait_queue_head_t wq;
- void (*frame_end)(struct vsp1_pipeline *pipe);
+ void (*frame_end)(struct vsp1_pipeline *pipe, bool completed);
struct mutex lock;
struct kref kref;
diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
index cd3e32a..58d0bea 100644
--- a/drivers/media/platform/vsp1/vsp1_regs.h
+++ b/drivers/media/platform/vsp1/vsp1_regs.h
@@ -18,6 +18,7 @@
*/
#define VI6_CMD(n) (0x0000 + (n) * 4)
+#define VI6_CMD_UPDHDR (1 << 4)
#define VI6_CMD_STRCMD (1 << 0)
#define VI6_CLK_DCSWT 0x0018
@@ -238,6 +239,10 @@
#define VI6_WPF_SRCRPF_VIRACT_SUB (1 << 28)
#define VI6_WPF_SRCRPF_VIRACT_MST (2 << 28)
#define VI6_WPF_SRCRPF_VIRACT_MASK (3 << 28)
+#define VI6_WPF_SRCRPF_VIRACT2_DIS (0 << 24)
+#define VI6_WPF_SRCRPF_VIRACT2_SUB (1 << 24)
+#define VI6_WPF_SRCRPF_VIRACT2_MST (2 << 24)
+#define VI6_WPF_SRCRPF_VIRACT2_MASK (3 << 24)
#define VI6_WPF_SRCRPF_RPF_ACT_DIS(n) (0 << ((n) * 2))
#define VI6_WPF_SRCRPF_RPF_ACT_SUB(n) (1 << ((n) * 2))
#define VI6_WPF_SRCRPF_RPF_ACT_MST(n) (2 << ((n) * 2))
@@ -321,6 +326,8 @@
#define VI6_DPR_HST_ROUTE 0x2044
#define VI6_DPR_HSI_ROUTE 0x2048
#define VI6_DPR_BRU_ROUTE 0x204c
+#define VI6_DPR_ILV_BRS_ROUTE 0x2050
+#define VI6_DPR_ROUTE_BRSSEL (1 << 28)
#define VI6_DPR_ROUTE_FXA_MASK (0xff << 16)
#define VI6_DPR_ROUTE_FXA_SHIFT 16
#define VI6_DPR_ROUTE_FP_MASK (0x3f << 8)
@@ -344,7 +351,8 @@
#define VI6_DPR_NODE_CLU 29
#define VI6_DPR_NODE_HST 30
#define VI6_DPR_NODE_HSI 31
-#define VI6_DPR_NODE_LIF 55
+#define VI6_DPR_NODE_BRS_IN(n) (38 + (n))
+#define VI6_DPR_NODE_LIF 55 /* Gen2 only */
#define VI6_DPR_NODE_WPF(n) (56 + (n))
#define VI6_DPR_NODE_UNUSED 63
@@ -476,7 +484,7 @@
#define VI6_HSI_CTRL_EN (1 << 0)
/* -----------------------------------------------------------------------------
- * BRU Control Registers
+ * BRS and BRU Control Registers
*/
#define VI6_ROP_NOP 0
@@ -496,7 +504,10 @@
#define VI6_ROP_NAND 14
#define VI6_ROP_SET 15
-#define VI6_BRU_INCTRL 0x2c00
+#define VI6_BRU_BASE 0x2c00
+#define VI6_BRS_BASE 0x3900
+
+#define VI6_BRU_INCTRL 0x0000
#define VI6_BRU_INCTRL_NRM (1 << 28)
#define VI6_BRU_INCTRL_DnON (1 << (16 + (n)))
#define VI6_BRU_INCTRL_DITHn_OFF (0 << ((n) * 4))
@@ -508,19 +519,19 @@
#define VI6_BRU_INCTRL_DITHn_MASK (7 << ((n) * 4))
#define VI6_BRU_INCTRL_DITHn_SHIFT ((n) * 4)
-#define VI6_BRU_VIRRPF_SIZE 0x2c04
+#define VI6_BRU_VIRRPF_SIZE 0x0004
#define VI6_BRU_VIRRPF_SIZE_HSIZE_MASK (0x1fff << 16)
#define VI6_BRU_VIRRPF_SIZE_HSIZE_SHIFT 16
#define VI6_BRU_VIRRPF_SIZE_VSIZE_MASK (0x1fff << 0)
#define VI6_BRU_VIRRPF_SIZE_VSIZE_SHIFT 0
-#define VI6_BRU_VIRRPF_LOC 0x2c08
+#define VI6_BRU_VIRRPF_LOC 0x0008
#define VI6_BRU_VIRRPF_LOC_HCOORD_MASK (0x1fff << 16)
#define VI6_BRU_VIRRPF_LOC_HCOORD_SHIFT 16
#define VI6_BRU_VIRRPF_LOC_VCOORD_MASK (0x1fff << 0)
#define VI6_BRU_VIRRPF_LOC_VCOORD_SHIFT 0
-#define VI6_BRU_VIRRPF_COL 0x2c0c
+#define VI6_BRU_VIRRPF_COL 0x000c
#define VI6_BRU_VIRRPF_COL_A_MASK (0xff << 24)
#define VI6_BRU_VIRRPF_COL_A_SHIFT 24
#define VI6_BRU_VIRRPF_COL_RCR_MASK (0xff << 16)
@@ -530,7 +541,7 @@
#define VI6_BRU_VIRRPF_COL_BCB_MASK (0xff << 0)
#define VI6_BRU_VIRRPF_COL_BCB_SHIFT 0
-#define VI6_BRU_CTRL(n) (0x2c10 + (n) * 8 + ((n) <= 3 ? 0 : 4))
+#define VI6_BRU_CTRL(n) (0x0010 + (n) * 8 + ((n) <= 3 ? 0 : 4))
#define VI6_BRU_CTRL_RBC (1 << 31)
#define VI6_BRU_CTRL_DSTSEL_BRUIN(n) (((n) <= 3 ? (n) : (n)+1) << 20)
#define VI6_BRU_CTRL_DSTSEL_VRPF (4 << 20)
@@ -543,7 +554,7 @@
#define VI6_BRU_CTRL_AROP(rop) ((rop) << 0)
#define VI6_BRU_CTRL_AROP_MASK (0xf << 0)
-#define VI6_BRU_BLD(n) (0x2c14 + (n) * 8 + ((n) <= 3 ? 0 : 4))
+#define VI6_BRU_BLD(n) (0x0014 + (n) * 8 + ((n) <= 3 ? 0 : 4))
#define VI6_BRU_BLD_CBES (1 << 31)
#define VI6_BRU_BLD_CCMDX_DST_A (0 << 28)
#define VI6_BRU_BLD_CCMDX_255_DST_A (1 << 28)
@@ -576,7 +587,7 @@
#define VI6_BRU_BLD_COEFY_MASK (0xff << 0)
#define VI6_BRU_BLD_COEFY_SHIFT 0
-#define VI6_BRU_ROP 0x2c30
+#define VI6_BRU_ROP 0x0030 /* Only available on BRU */
#define VI6_BRU_ROP_DSTSEL_BRUIN(n) (((n) <= 3 ? (n) : (n)+1) << 20)
#define VI6_BRU_ROP_DSTSEL_VRPF (4 << 20)
#define VI6_BRU_ROP_DSTSEL_MASK (7 << 20)
@@ -653,6 +664,8 @@
* LIF Control Registers
*/
+#define VI6_LIF_OFFSET (-0x100)
+
#define VI6_LIF_CTRL 0x3b00
#define VI6_LIF_CTRL_OBTH_MASK (0x7ff << 16)
#define VI6_LIF_CTRL_OBTH_SHIFT 16
@@ -689,9 +702,20 @@
#define VI6_IP_VERSION_MODEL_VSPBD_GEN3 (0x15 << 8)
#define VI6_IP_VERSION_MODEL_VSPBC_GEN3 (0x16 << 8)
#define VI6_IP_VERSION_MODEL_VSPD_GEN3 (0x17 << 8)
+#define VI6_IP_VERSION_MODEL_VSPD_V3 (0x18 << 8)
+#define VI6_IP_VERSION_MODEL_VSPDL_GEN3 (0x19 << 8)
+#define VI6_IP_VERSION_MODEL_VSPBS_GEN3 (0x1a << 8)
#define VI6_IP_VERSION_SOC_MASK (0xff << 0)
-#define VI6_IP_VERSION_SOC_H (0x01 << 0)
-#define VI6_IP_VERSION_SOC_M (0x02 << 0)
+#define VI6_IP_VERSION_SOC_H2 (0x01 << 0)
+#define VI6_IP_VERSION_SOC_V2H (0x01 << 0)
+#define VI6_IP_VERSION_SOC_V3M (0x01 << 0)
+#define VI6_IP_VERSION_SOC_M2 (0x02 << 0)
+#define VI6_IP_VERSION_SOC_M3W (0x02 << 0)
+#define VI6_IP_VERSION_SOC_V3H (0x02 << 0)
+#define VI6_IP_VERSION_SOC_H3 (0x03 << 0)
+#define VI6_IP_VERSION_SOC_D3 (0x04 << 0)
+#define VI6_IP_VERSION_SOC_M3N (0x04 << 0)
+#define VI6_IP_VERSION_SOC_E3 (0x04 << 0)
/* -----------------------------------------------------------------------------
* RPF CLUT Registers
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 5af3486..e9f5dcb 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -440,13 +440,17 @@ static void vsp1_video_pipeline_run(struct vsp1_pipeline *pipe)
vsp1_pipeline_run(pipe);
}
-static void vsp1_video_pipeline_frame_end(struct vsp1_pipeline *pipe)
+static void vsp1_video_pipeline_frame_end(struct vsp1_pipeline *pipe,
+ bool completed)
{
struct vsp1_device *vsp1 = pipe->output->entity.vsp1;
enum vsp1_pipeline_state state;
unsigned long flags;
unsigned int i;
+ /* M2M Pipelines should never call here with an incomplete frame. */
+ WARN_ON_ONCE(!completed);
+
spin_lock_irqsave(&pipe->irqlock, flags);
/* Complete buffers on all video nodes. */
@@ -481,7 +485,7 @@ static int vsp1_video_pipeline_build_branch(struct vsp1_pipeline *pipe,
struct media_entity_enum ent_enum;
struct vsp1_entity *entity;
struct media_pad *pad;
- bool bru_found = false;
+ struct vsp1_bru *bru = NULL;
int ret;
ret = media_entity_enum_init(&ent_enum, &input->entity.vsp1->media_dev);
@@ -511,16 +515,20 @@ static int vsp1_video_pipeline_build_branch(struct vsp1_pipeline *pipe,
media_entity_to_v4l2_subdev(pad->entity));
/*
- * A BRU is present in the pipeline, store the BRU input pad
+ * A BRU or BRS is present in the pipeline, store its input pad
* number in the input RPF for use when configuring the RPF.
*/
- if (entity->type == VSP1_ENTITY_BRU) {
- struct vsp1_bru *bru = to_bru(&entity->subdev);
+ if (entity->type == VSP1_ENTITY_BRU ||
+ entity->type == VSP1_ENTITY_BRS) {
+ /* BRU and BRS can't be chained. */
+ if (bru) {
+ ret = -EPIPE;
+ goto out;
+ }
+ bru = to_bru(&entity->subdev);
bru->inputs[pad->index].rpf = input;
input->bru_input = pad->index;
-
- bru_found = true;
}
/* We've reached the WPF, we're done. */
@@ -542,8 +550,7 @@ static int vsp1_video_pipeline_build_branch(struct vsp1_pipeline *pipe,
}
pipe->uds = entity;
- pipe->uds_input = bru_found ? pipe->bru
- : &input->entity;
+ pipe->uds_input = bru ? &bru->entity : &input->entity;
}
/* Follow the source link, ignoring any HGO or HGT. */
@@ -589,30 +596,42 @@ static int vsp1_video_pipeline_build(struct vsp1_pipeline *pipe,
e = to_vsp1_entity(subdev);
list_add_tail(&e->list_pipe, &pipe->entities);
- if (e->type == VSP1_ENTITY_RPF) {
+ switch (e->type) {
+ case VSP1_ENTITY_RPF:
rwpf = to_rwpf(subdev);
pipe->inputs[rwpf->entity.index] = rwpf;
rwpf->video->pipe_index = ++pipe->num_inputs;
rwpf->pipe = pipe;
- } else if (e->type == VSP1_ENTITY_WPF) {
+ break;
+
+ case VSP1_ENTITY_WPF:
rwpf = to_rwpf(subdev);
pipe->output = rwpf;
rwpf->video->pipe_index = 0;
rwpf->pipe = pipe;
- } else if (e->type == VSP1_ENTITY_LIF) {
+ break;
+
+ case VSP1_ENTITY_LIF:
pipe->lif = e;
- } else if (e->type == VSP1_ENTITY_BRU) {
+ break;
+
+ case VSP1_ENTITY_BRU:
+ case VSP1_ENTITY_BRS:
pipe->bru = e;
- } else if (e->type == VSP1_ENTITY_HGO) {
- struct vsp1_hgo *hgo = to_hgo(subdev);
+ break;
+ case VSP1_ENTITY_HGO:
pipe->hgo = e;
- hgo->histo.pipe = pipe;
- } else if (e->type == VSP1_ENTITY_HGT) {
- struct vsp1_hgt *hgt = to_hgt(subdev);
+ to_hgo(subdev)->histo.pipe = pipe;
+ break;
+ case VSP1_ENTITY_HGT:
pipe->hgt = e;
- hgt->histo.pipe = pipe;
+ to_hgt(subdev)->histo.pipe = pipe;
+ break;
+
+ default:
+ break;
}
}
@@ -796,12 +815,14 @@ static int vsp1_video_setup_pipeline(struct vsp1_pipeline *pipe)
struct vsp1_uds *uds = to_uds(&pipe->uds->subdev);
/*
- * If a BRU is present in the pipeline before the UDS, the alpha
- * component doesn't need to be scaled as the BRU output alpha
- * value is fixed to 255. Otherwise we need to scale the alpha
- * component only when available at the input RPF.
+ * If a BRU or BRS is present in the pipeline before the UDS,
+ * the alpha component doesn't need to be scaled as the BRU and
+ * BRS output alpha value is fixed to 255. Otherwise we need to
+ * scale the alpha component only when available at the input
+ * RPF.
*/
- if (pipe->uds_input->type == VSP1_ENTITY_BRU) {
+ if (pipe->uds_input->type == VSP1_ENTITY_BRU ||
+ pipe->uds_input->type == VSP1_ENTITY_BRS) {
uds->scale_alpha = false;
} else {
struct vsp1_rwpf *rpf =
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index 32df109..b6c902b 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -453,7 +453,9 @@ static void wpf_configure(struct vsp1_entity *entity,
}
if (pipe->bru || pipe->num_inputs > 1)
- srcrpf |= VI6_WPF_SRCRPF_VIRACT_MST;
+ srcrpf |= pipe->bru->type == VSP1_ENTITY_BRU
+ ? VI6_WPF_SRCRPF_VIRACT_MST
+ : VI6_WPF_SRCRPF_VIRACT2_MST;
vsp1_wpf_write(wpf, dl, VI6_WPF_SRCRPF, srcrpf);
diff --git a/drivers/mfd/da9052-core.c b/drivers/mfd/da9052-core.c
index a88c206..a23a3a1 100644
--- a/drivers/mfd/da9052-core.c
+++ b/drivers/mfd/da9052-core.c
@@ -18,6 +18,7 @@
#include <linux/mfd/core.h>
#include <linux/slab.h>
#include <linux/module.h>
+#include <linux/property.h>
#include <linux/mfd/da9052/da9052.h>
#include <linux/mfd/da9052/pdata.h>
@@ -519,9 +520,6 @@ static const struct mfd_cell da9052_subdev_info[] = {
.name = "da9052-wled3",
},
{
- .name = "da9052-tsi",
- },
- {
.name = "da9052-bat",
},
{
@@ -529,6 +527,10 @@ static const struct mfd_cell da9052_subdev_info[] = {
},
};
+static const struct mfd_cell da9052_tsi_subdev_info[] = {
+ { .name = "da9052-tsi" },
+};
+
const struct regmap_config da9052_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
@@ -619,9 +621,27 @@ int da9052_device_init(struct da9052 *da9052, u8 chip_id)
goto err;
}
+ /*
+ * Check if touchscreen pins are used are analogue input instead
+ * of having a touchscreen connected to them. The analogue input
+ * functionality will be provided by hwmon driver (if enabled).
+ */
+ if (!device_property_read_bool(da9052->dev, "dlg,tsi-as-adc")) {
+ ret = mfd_add_devices(da9052->dev, PLATFORM_DEVID_AUTO,
+ da9052_tsi_subdev_info,
+ ARRAY_SIZE(da9052_tsi_subdev_info),
+ NULL, 0, NULL);
+ if (ret) {
+ dev_err(da9052->dev, "failed to add TSI subdev: %d\n",
+ ret);
+ goto err;
+ }
+ }
+
return 0;
err:
+ mfd_remove_devices(da9052->dev);
da9052_irq_exit(da9052);
return ret;
diff --git a/drivers/misc/mic/scif/scif_dma.c b/drivers/misc/mic/scif/scif_dma.c
index 64d5760..63d6246 100644
--- a/drivers/misc/mic/scif/scif_dma.c
+++ b/drivers/misc/mic/scif/scif_dma.c
@@ -200,16 +200,6 @@ static void scif_mmu_notifier_release(struct mmu_notifier *mn,
schedule_work(&scif_info.misc_work);
}
-static void scif_mmu_notifier_invalidate_page(struct mmu_notifier *mn,
- struct mm_struct *mm,
- unsigned long address)
-{
- struct scif_mmu_notif *mmn;
-
- mmn = container_of(mn, struct scif_mmu_notif, ep_mmu_notifier);
- scif_rma_destroy_tcw(mmn, address, PAGE_SIZE);
-}
-
static void scif_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
struct mm_struct *mm,
unsigned long start,
@@ -235,7 +225,6 @@ static void scif_mmu_notifier_invalidate_range_end(struct mmu_notifier *mn,
static const struct mmu_notifier_ops scif_mmu_notifier_ops = {
.release = scif_mmu_notifier_release,
.clear_flush_young = NULL,
- .invalidate_page = scif_mmu_notifier_invalidate_page,
.invalidate_range_start = scif_mmu_notifier_invalidate_range_start,
.invalidate_range_end = scif_mmu_notifier_invalidate_range_end};
diff --git a/drivers/misc/sgi-gru/grutlbpurge.c b/drivers/misc/sgi-gru/grutlbpurge.c
index e936d43..9918eda 100644
--- a/drivers/misc/sgi-gru/grutlbpurge.c
+++ b/drivers/misc/sgi-gru/grutlbpurge.c
@@ -247,17 +247,6 @@ static void gru_invalidate_range_end(struct mmu_notifier *mn,
gru_dbg(grudev, "gms %p, start 0x%lx, end 0x%lx\n", gms, start, end);
}
-static void gru_invalidate_page(struct mmu_notifier *mn, struct mm_struct *mm,
- unsigned long address)
-{
- struct gru_mm_struct *gms = container_of(mn, struct gru_mm_struct,
- ms_notifier);
-
- STAT(mmu_invalidate_page);
- gru_flush_tlb_range(gms, address, PAGE_SIZE);
- gru_dbg(grudev, "gms %p, address 0x%lx\n", gms, address);
-}
-
static void gru_release(struct mmu_notifier *mn, struct mm_struct *mm)
{
struct gru_mm_struct *gms = container_of(mn, struct gru_mm_struct,
@@ -269,7 +258,6 @@ static void gru_release(struct mmu_notifier *mn, struct mm_struct *mm)
static const struct mmu_notifier_ops gru_mmuops = {
- .invalidate_page = gru_invalidate_page,
.invalidate_range_start = gru_invalidate_range_start,
.invalidate_range_end = gru_invalidate_range_end,
.release = gru_release,
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index 80d1ec6..8bd7aba 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -1213,7 +1213,7 @@ static void mmc_blk_issue_drv_op(struct mmc_queue *mq, struct request *req)
break;
}
mq_rq->drv_op_result = ret;
- blk_end_request_all(req, ret);
+ blk_end_request_all(req, ret ? BLK_STS_IOERR : BLK_STS_OK);
}
static void mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
@@ -1718,9 +1718,9 @@ static bool mmc_blk_rw_cmd_err(struct mmc_blk_data *md, struct mmc_card *card,
if (err)
req_pending = old_req_pending;
else
- req_pending = blk_end_request(req, 0, blocks << 9);
+ req_pending = blk_end_request(req, BLK_STS_OK, blocks << 9);
} else {
- req_pending = blk_end_request(req, 0, brq->data.bytes_xfered);
+ req_pending = blk_end_request(req, BLK_STS_OK, brq->data.bytes_xfered);
}
return req_pending;
}
diff --git a/drivers/mmc/host/sdhci-xenon.c b/drivers/mmc/host/sdhci-xenon.c
index bc1781b..c580af0 100644
--- a/drivers/mmc/host/sdhci-xenon.c
+++ b/drivers/mmc/host/sdhci-xenon.c
@@ -210,8 +210,27 @@ static void xenon_set_uhs_signaling(struct sdhci_host *host,
sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
}
+static void xenon_set_power(struct sdhci_host *host, unsigned char mode,
+ unsigned short vdd)
+{
+ struct mmc_host *mmc = host->mmc;
+ u8 pwr = host->pwr;
+
+ sdhci_set_power_noreg(host, mode, vdd);
+
+ if (host->pwr == pwr)
+ return;
+
+ if (host->pwr == 0)
+ vdd = 0;
+
+ if (!IS_ERR(mmc->supply.vmmc))
+ mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
+}
+
static const struct sdhci_ops sdhci_xenon_ops = {
.set_clock = sdhci_set_clock,
+ .set_power = xenon_set_power,
.set_bus_width = sdhci_set_bus_width,
.reset = xenon_reset,
.set_uhs_signaling = xenon_set_uhs_signaling,
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 83a1616..aba0d65 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -333,7 +333,7 @@ config VIRTIO_NET
depends on VIRTIO
---help---
This is the virtual network driver for virtio. It can be used with
- lguest or QEMU based VMMs (like KVM or Xen). Say Y or M.
+ QEMU based VMMs (like KVM or Xen). Say Y or M.
config NLMON
tristate "Virtual netlink monitoring device"
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index 648f91b..9b6ce7c 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -1048,6 +1048,7 @@ struct bcm_sf2_of_data {
u32 type;
const u16 *reg_offsets;
unsigned int core_reg_align;
+ unsigned int num_cfp_rules;
};
/* Register offsets for the SWITCH_REG_* block */
@@ -1071,6 +1072,7 @@ static const struct bcm_sf2_of_data bcm_sf2_7445_data = {
.type = BCM7445_DEVICE_ID,
.core_reg_align = 0,
.reg_offsets = bcm_sf2_7445_reg_offsets,
+ .num_cfp_rules = 256,
};
static const u16 bcm_sf2_7278_reg_offsets[] = {
@@ -1093,6 +1095,7 @@ static const struct bcm_sf2_of_data bcm_sf2_7278_data = {
.type = BCM7278_DEVICE_ID,
.core_reg_align = 1,
.reg_offsets = bcm_sf2_7278_reg_offsets,
+ .num_cfp_rules = 128,
};
static const struct of_device_id bcm_sf2_of_match[] = {
@@ -1149,6 +1152,7 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev)
priv->type = data->type;
priv->reg_offsets = data->reg_offsets;
priv->core_reg_align = data->core_reg_align;
+ priv->num_cfp_rules = data->num_cfp_rules;
/* Auto-detection using standard registers will not work, so
* provide an indication of what kind of device we are for
diff --git a/drivers/net/dsa/bcm_sf2.h b/drivers/net/dsa/bcm_sf2.h
index 7d3030e..7f9125e 100644
--- a/drivers/net/dsa/bcm_sf2.h
+++ b/drivers/net/dsa/bcm_sf2.h
@@ -72,6 +72,7 @@ struct bcm_sf2_priv {
u32 type;
const u16 *reg_offsets;
unsigned int core_reg_align;
+ unsigned int num_cfp_rules;
/* spinlock protecting access to the indirect registers */
spinlock_t indir_lock;
diff --git a/drivers/net/dsa/bcm_sf2_cfp.c b/drivers/net/dsa/bcm_sf2_cfp.c
index 2fb32d6..8a1da7e 100644
--- a/drivers/net/dsa/bcm_sf2_cfp.c
+++ b/drivers/net/dsa/bcm_sf2_cfp.c
@@ -98,7 +98,7 @@ static inline void bcm_sf2_cfp_rule_addr_set(struct bcm_sf2_priv *priv,
{
u32 reg;
- WARN_ON(addr >= CFP_NUM_RULES);
+ WARN_ON(addr >= priv->num_cfp_rules);
reg = core_readl(priv, CORE_CFP_ACC);
reg &= ~(XCESS_ADDR_MASK << XCESS_ADDR_SHIFT);
@@ -109,7 +109,7 @@ static inline void bcm_sf2_cfp_rule_addr_set(struct bcm_sf2_priv *priv,
static inline unsigned int bcm_sf2_cfp_rule_size(struct bcm_sf2_priv *priv)
{
/* Entry #0 is reserved */
- return CFP_NUM_RULES - 1;
+ return priv->num_cfp_rules - 1;
}
static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port,
@@ -523,7 +523,7 @@ static int bcm_sf2_cfp_rule_get_all(struct bcm_sf2_priv *priv,
if (!(reg & OP_STR_DONE))
break;
- } while (index < CFP_NUM_RULES);
+ } while (index < priv->num_cfp_rules);
/* Put the TCAM size here */
nfc->data = bcm_sf2_cfp_rule_size(priv);
@@ -544,7 +544,7 @@ int bcm_sf2_get_rxnfc(struct dsa_switch *ds, int port,
case ETHTOOL_GRXCLSRLCNT:
/* Subtract the default, unusable rule */
nfc->rule_cnt = bitmap_weight(priv->cfp.used,
- CFP_NUM_RULES) - 1;
+ priv->num_cfp_rules) - 1;
/* We support specifying rule locations */
nfc->data |= RX_CLS_LOC_SPECIAL;
break;
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
index 1d307f2..6e253d9 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
@@ -1661,21 +1661,21 @@ static int xgene_enet_get_irqs(struct xgene_enet_pdata *pdata)
return 0;
}
-static int xgene_enet_check_phy_handle(struct xgene_enet_pdata *pdata)
+static void xgene_enet_check_phy_handle(struct xgene_enet_pdata *pdata)
{
int ret;
if (pdata->phy_mode == PHY_INTERFACE_MODE_XGMII)
- return 0;
+ return;
if (!IS_ENABLED(CONFIG_MDIO_XGENE))
- return 0;
+ return;
ret = xgene_enet_phy_connect(pdata->ndev);
if (!ret)
pdata->mdio_driver = true;
- return 0;
+ return;
}
static void xgene_enet_gpiod_get(struct xgene_enet_pdata *pdata)
@@ -1779,10 +1779,6 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
if (ret)
return ret;
- ret = xgene_enet_check_phy_handle(pdata);
- if (ret)
- return ret;
-
xgene_enet_gpiod_get(pdata);
pdata->clk = devm_clk_get(&pdev->dev, NULL);
@@ -2097,9 +2093,11 @@ static int xgene_enet_probe(struct platform_device *pdev)
goto err;
}
+ xgene_enet_check_phy_handle(pdata);
+
ret = xgene_enet_init_hw(pdata);
if (ret)
- goto err;
+ goto err2;
link_state = pdata->mac_ops->link_state;
if (pdata->phy_mode == PHY_INTERFACE_MODE_XGMII) {
@@ -2117,29 +2115,30 @@ static int xgene_enet_probe(struct platform_device *pdev)
spin_lock_init(&pdata->stats_lock);
ret = xgene_extd_stats_init(pdata);
if (ret)
- goto err2;
+ goto err1;
xgene_enet_napi_add(pdata);
ret = register_netdev(ndev);
if (ret) {
netdev_err(ndev, "Failed to register netdev\n");
- goto err2;
+ goto err1;
}
return 0;
-err2:
+err1:
/*
* If necessary, free_netdev() will call netif_napi_del() and undo
* the effects of xgene_enet_napi_add()'s calls to netif_napi_add().
*/
+ xgene_enet_delete_desc_rings(pdata);
+
+err2:
if (pdata->mdio_driver)
xgene_enet_phy_disconnect(pdata);
else if (phy_interface_mode_is_rgmii(pdata->phy_mode))
xgene_enet_mdio_remove(pdata);
-err1:
- xgene_enet_delete_desc_rings(pdata);
err:
free_netdev(ndev);
return ret;
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
index fce0fd3..bf9b3f0 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
@@ -105,8 +105,7 @@ struct aq_hw_ops {
int (*hw_set_mac_address)(struct aq_hw_s *self, u8 *mac_addr);
- int (*hw_get_link_status)(struct aq_hw_s *self,
- struct aq_hw_link_status_s *link_status);
+ int (*hw_get_link_status)(struct aq_hw_s *self);
int (*hw_set_link_speed)(struct aq_hw_s *self, u32 speed);
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 9ee1c50..6ac9e26 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -103,6 +103,8 @@ int aq_nic_cfg_start(struct aq_nic_s *self)
else
cfg->vecs = 1U;
+ cfg->num_rss_queues = min(cfg->vecs, AQ_CFG_NUM_RSS_QUEUES_DEF);
+
cfg->irq_type = aq_pci_func_get_irq_type(self->aq_pci_func);
if ((cfg->irq_type == AQ_HW_IRQ_LEGACY) ||
@@ -123,33 +125,30 @@ static void aq_nic_service_timer_cb(unsigned long param)
struct net_device *ndev = aq_nic_get_ndev(self);
int err = 0;
unsigned int i = 0U;
- struct aq_hw_link_status_s link_status;
struct aq_ring_stats_rx_s stats_rx;
struct aq_ring_stats_tx_s stats_tx;
if (aq_utils_obj_test(&self->header.flags, AQ_NIC_FLAGS_IS_NOT_READY))
goto err_exit;
- err = self->aq_hw_ops.hw_get_link_status(self->aq_hw, &link_status);
+ err = self->aq_hw_ops.hw_get_link_status(self->aq_hw);
if (err < 0)
goto err_exit;
- self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw,
- self->aq_nic_cfg.is_interrupt_moderation);
-
- if (memcmp(&link_status, &self->link_status, sizeof(link_status))) {
- if (link_status.mbps) {
- aq_utils_obj_set(&self->header.flags,
- AQ_NIC_FLAG_STARTED);
- aq_utils_obj_clear(&self->header.flags,
- AQ_NIC_LINK_DOWN);
- netif_carrier_on(self->ndev);
- } else {
- netif_carrier_off(self->ndev);
- aq_utils_obj_set(&self->header.flags, AQ_NIC_LINK_DOWN);
- }
+ self->link_status = self->aq_hw->aq_link_status;
- self->link_status = link_status;
+ self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw,
+ self->aq_nic_cfg.is_interrupt_moderation);
+
+ if (self->link_status.mbps) {
+ aq_utils_obj_set(&self->header.flags,
+ AQ_NIC_FLAG_STARTED);
+ aq_utils_obj_clear(&self->header.flags,
+ AQ_NIC_LINK_DOWN);
+ netif_carrier_on(self->ndev);
+ } else {
+ netif_carrier_off(self->ndev);
+ aq_utils_obj_set(&self->header.flags, AQ_NIC_LINK_DOWN);
}
memset(&stats_rx, 0U, sizeof(struct aq_ring_stats_rx_s));
@@ -597,14 +596,11 @@ exit:
}
int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb)
-__releases(&ring->lock)
-__acquires(&ring->lock)
{
struct aq_ring_s *ring = NULL;
unsigned int frags = 0U;
unsigned int vec = skb->queue_mapping % self->aq_nic_cfg.vecs;
unsigned int tc = 0U;
- unsigned int trys = AQ_CFG_LOCK_TRYS;
int err = NETDEV_TX_OK;
bool is_nic_in_bad_state;
@@ -628,36 +624,21 @@ __acquires(&ring->lock)
goto err_exit;
}
- do {
- if (spin_trylock(&ring->header.lock)) {
- frags = aq_nic_map_skb(self, skb, ring);
-
- if (likely(frags)) {
- err = self->aq_hw_ops.hw_ring_tx_xmit(
- self->aq_hw,
- ring, frags);
- if (err >= 0) {
- if (aq_ring_avail_dx(ring) <
- AQ_CFG_SKB_FRAGS_MAX + 1)
- aq_nic_ndev_queue_stop(
- self,
- ring->idx);
-
- ++ring->stats.tx.packets;
- ring->stats.tx.bytes += skb->len;
- }
- } else {
- err = NETDEV_TX_BUSY;
- }
+ frags = aq_nic_map_skb(self, skb, ring);
- spin_unlock(&ring->header.lock);
- break;
- }
- } while (--trys);
+ if (likely(frags)) {
+ err = self->aq_hw_ops.hw_ring_tx_xmit(self->aq_hw,
+ ring,
+ frags);
+ if (err >= 0) {
+ if (aq_ring_avail_dx(ring) < AQ_CFG_SKB_FRAGS_MAX + 1)
+ aq_nic_ndev_queue_stop(self, ring->idx);
- if (!trys) {
+ ++ring->stats.tx.packets;
+ ring->stats.tx.bytes += skb->len;
+ }
+ } else {
err = NETDEV_TX_BUSY;
- goto err_exit;
}
err_exit:
@@ -688,11 +669,26 @@ int aq_nic_set_multicast_list(struct aq_nic_s *self, struct net_device *ndev)
netdev_for_each_mc_addr(ha, ndev) {
ether_addr_copy(self->mc_list.ar[i++], ha->addr);
++self->mc_list.count;
+
+ if (i >= AQ_CFG_MULTICAST_ADDRESS_MAX)
+ break;
}
- return self->aq_hw_ops.hw_multicast_list_set(self->aq_hw,
+ if (i >= AQ_CFG_MULTICAST_ADDRESS_MAX) {
+ /* Number of filters is too big: atlantic does not support this.
+ * Force all multi filter to support this.
+ * With this we disable all UC filters and setup "all pass"
+ * multicast mask
+ */
+ self->packet_filter |= IFF_ALLMULTI;
+ self->aq_hw->aq_nic_cfg->mc_list_count = 0;
+ return self->aq_hw_ops.hw_packet_filter_set(self->aq_hw,
+ self->packet_filter);
+ } else {
+ return self->aq_hw_ops.hw_multicast_list_set(self->aq_hw,
self->mc_list.ar,
self->mc_list.count);
+ }
}
int aq_nic_set_mtu(struct aq_nic_s *self, int new_mtu)
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
index 9a08179..ec5579f 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
@@ -101,7 +101,6 @@ int aq_ring_init(struct aq_ring_s *self)
self->hw_head = 0;
self->sw_head = 0;
self->sw_tail = 0;
- spin_lock_init(&self->header.lock);
return 0;
}
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_utils.h b/drivers/net/ethernet/aquantia/atlantic/aq_utils.h
index f6012b3..e12bcdf 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_utils.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_utils.h
@@ -17,7 +17,6 @@
#define AQ_DIMOF(_ARY_) ARRAY_SIZE(_ARY_)
struct aq_obj_s {
- spinlock_t lock; /* spinlock for nic/rings processing */
atomic_t flags;
};
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
index ad5b4d4d..fee446a 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
@@ -34,8 +34,6 @@ struct aq_vec_s {
#define AQ_VEC_RX_ID 1
static int aq_vec_poll(struct napi_struct *napi, int budget)
-__releases(&self->lock)
-__acquires(&self->lock)
{
struct aq_vec_s *self = container_of(napi, struct aq_vec_s, napi);
struct aq_ring_s *ring = NULL;
@@ -47,7 +45,7 @@ __acquires(&self->lock)
if (!self) {
err = -EINVAL;
- } else if (spin_trylock(&self->header.lock)) {
+ } else {
for (i = 0U, ring = self->ring[0];
self->tx_rings > i; ++i, ring = self->ring[i]) {
if (self->aq_hw_ops->hw_ring_tx_head_update) {
@@ -105,11 +103,8 @@ __acquires(&self->lock)
self->aq_hw_ops->hw_irq_enable(self->aq_hw,
1U << self->aq_ring_param.vec_idx);
}
-
-err_exit:
- spin_unlock(&self->header.lock);
}
-
+err_exit:
return work_done;
}
@@ -185,8 +180,6 @@ int aq_vec_init(struct aq_vec_s *self, struct aq_hw_ops *aq_hw_ops,
self->aq_hw_ops = aq_hw_ops;
self->aq_hw = aq_hw;
- spin_lock_init(&self->header.lock);
-
for (i = 0U, ring = self->ring[0];
self->tx_rings > i; ++i, ring = self->ring[i]) {
err = aq_ring_init(&ring[AQ_VEC_TX_ID]);
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
index faeb493..c5a02df 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
@@ -629,6 +629,12 @@ static int hw_atl_a0_hw_ring_rx_receive(struct aq_hw_s *self,
buff->is_udp_cso = (is_err & 0x10U) ? 0 : 1;
else if (0x0U == (pkt_type & 0x1CU))
buff->is_tcp_cso = (is_err & 0x10U) ? 0 : 1;
+
+ /* Checksum offload workaround for small packets */
+ if (rxd_wb->pkt_len <= 60) {
+ buff->is_ip_cso = 0U;
+ buff->is_cso_err = 0U;
+ }
}
is_err &= ~0x18U;
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
index 1bceb73..21784cc 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
@@ -645,6 +645,12 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s *self,
buff->is_udp_cso = buff->is_cso_err ? 0U : 1U;
else if (0x0U == (pkt_type & 0x1CU))
buff->is_tcp_cso = buff->is_cso_err ? 0U : 1U;
+
+ /* Checksum offload workaround for small packets */
+ if (rxd_wb->pkt_len <= 60) {
+ buff->is_ip_cso = 0U;
+ buff->is_cso_err = 0U;
+ }
}
is_err &= ~0x18U;
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
index 8d6d8f5..4f5ec9a 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
@@ -141,6 +141,12 @@ static int hw_atl_utils_init_ucp(struct aq_hw_s *self,
err = hw_atl_utils_ver_match(aq_hw_caps->fw_ver_expected,
aq_hw_read_reg(self, 0x18U));
+
+ if (err < 0)
+ pr_err("%s: Bad FW version detected: expected=%x, actual=%x\n",
+ AQ_CFG_DRV_NAME,
+ aq_hw_caps->fw_ver_expected,
+ aq_hw_read_reg(self, 0x18U));
return err;
}
@@ -313,11 +319,11 @@ void hw_atl_utils_mpi_set(struct aq_hw_s *self,
err_exit:;
}
-int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self,
- struct aq_hw_link_status_s *link_status)
+int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self)
{
u32 cp0x036C = aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR);
u32 link_speed_mask = cp0x036C >> HW_ATL_MPI_SPEED_SHIFT;
+ struct aq_hw_link_status_s *link_status = &self->aq_link_status;
if (!link_speed_mask) {
link_status->mbps = 0U;
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
index a66aee5..e0360a6 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
@@ -180,8 +180,7 @@ void hw_atl_utils_mpi_set(struct aq_hw_s *self,
int hw_atl_utils_mpi_set_speed(struct aq_hw_s *self, u32 speed,
enum hal_atl_utils_fw_state_e state);
-int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self,
- struct aq_hw_link_status_s *link_status);
+int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self);
int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self,
struct aq_hw_caps_s *aq_hw_caps,
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c
index dc30527..c28fa5a 100644
--- a/drivers/net/ethernet/broadcom/bcmsysport.c
+++ b/drivers/net/ethernet/broadcom/bcmsysport.c
@@ -597,7 +597,7 @@ static int bcm_sysport_set_coalesce(struct net_device *dev,
static void bcm_sysport_free_cb(struct bcm_sysport_cb *cb)
{
- dev_kfree_skb_any(cb->skb);
+ dev_consume_skb_any(cb->skb);
cb->skb = NULL;
dma_unmap_addr_set(cb, dma_addr, 0);
}
@@ -1346,6 +1346,8 @@ static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv,
ring->cbs = kcalloc(size, sizeof(struct bcm_sysport_cb), GFP_KERNEL);
if (!ring->cbs) {
+ dma_free_coherent(kdev, sizeof(struct dma_desc),
+ ring->desc_cpu, ring->desc_dma);
netif_err(priv, hw, priv->netdev, "CB allocation failed\n");
return -ENOMEM;
}
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index e7c8539..f20b3d2 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -4647,7 +4647,6 @@ static int bnxt_hwrm_func_qcaps(struct bnxt *bp)
pf->port_id = le16_to_cpu(resp->port_id);
bp->dev->dev_port = pf->port_id;
memcpy(pf->mac_addr, resp->mac_address, ETH_ALEN);
- memcpy(bp->dev->dev_addr, pf->mac_addr, ETH_ALEN);
pf->max_rsscos_ctxs = le16_to_cpu(resp->max_rsscos_ctx);
pf->max_cp_rings = le16_to_cpu(resp->max_cmpl_rings);
pf->max_tx_rings = le16_to_cpu(resp->max_tx_rings);
@@ -4687,16 +4686,6 @@ static int bnxt_hwrm_func_qcaps(struct bnxt *bp)
vf->max_stat_ctxs = le16_to_cpu(resp->max_stat_ctx);
memcpy(vf->mac_addr, resp->mac_address, ETH_ALEN);
- mutex_unlock(&bp->hwrm_cmd_lock);
-
- if (is_valid_ether_addr(vf->mac_addr)) {
- /* overwrite netdev dev_adr with admin VF MAC */
- memcpy(bp->dev->dev_addr, vf->mac_addr, ETH_ALEN);
- } else {
- eth_hw_addr_random(bp->dev);
- rc = bnxt_approve_mac(bp, bp->dev->dev_addr);
- }
- return rc;
#endif
}
@@ -7152,6 +7141,7 @@ int bnxt_setup_mq_tc(struct net_device *dev, u8 tc)
bp->tx_nr_rings = bp->tx_nr_rings_per_tc;
netdev_reset_tc(dev);
}
+ bp->tx_nr_rings += bp->tx_nr_rings_xdp;
bp->cp_nr_rings = sh ? max_t(int, bp->tx_nr_rings, bp->rx_nr_rings) :
bp->tx_nr_rings + bp->rx_nr_rings;
bp->num_stat_ctxs = bp->cp_nr_rings;
@@ -7661,6 +7651,28 @@ void bnxt_restore_pf_fw_resources(struct bnxt *bp)
bnxt_subtract_ulp_resources(bp, BNXT_ROCE_ULP);
}
+static int bnxt_init_mac_addr(struct bnxt *bp)
+{
+ int rc = 0;
+
+ if (BNXT_PF(bp)) {
+ memcpy(bp->dev->dev_addr, bp->pf.mac_addr, ETH_ALEN);
+ } else {
+#ifdef CONFIG_BNXT_SRIOV
+ struct bnxt_vf_info *vf = &bp->vf;
+
+ if (is_valid_ether_addr(vf->mac_addr)) {
+ /* overwrite netdev dev_adr with admin VF MAC */
+ memcpy(bp->dev->dev_addr, vf->mac_addr, ETH_ALEN);
+ } else {
+ eth_hw_addr_random(bp->dev);
+ rc = bnxt_approve_mac(bp, bp->dev->dev_addr);
+ }
+#endif
+ }
+ return rc;
+}
+
static void bnxt_parse_log_pcie_link(struct bnxt *bp)
{
enum pcie_link_width width = PCIE_LNK_WIDTH_UNKNOWN;
@@ -7789,7 +7801,12 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
rc = -1;
goto init_err_pci_clean;
}
-
+ rc = bnxt_init_mac_addr(bp);
+ if (rc) {
+ dev_err(&pdev->dev, "Unable to initialize mac address.\n");
+ rc = -EADDRNOTAVAIL;
+ goto init_err_pci_clean;
+ }
rc = bnxt_hwrm_queue_qportcfg(bp);
if (rc) {
netdev_err(bp->dev, "hwrm query qportcfg failure rc: %x\n",
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c
index 77da75a..997e10e 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c
@@ -84,6 +84,8 @@ static int bnxt_unregister_dev(struct bnxt_en_dev *edev, int ulp_id)
max_stat_ctxs = bnxt_get_max_func_stat_ctxs(bp);
bnxt_set_max_func_stat_ctxs(bp, max_stat_ctxs + 1);
+ if (ulp->msix_requested)
+ edev->en_ops->bnxt_free_msix(edev, ulp_id);
}
if (ulp->max_async_event_id)
bnxt_hwrm_func_rgtr_async_events(bp, NULL, 0);
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index a981c4e..fea3f9a 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1360,7 +1360,7 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev,
if (skb) {
pkts_compl++;
bytes_compl += GENET_CB(skb)->bytes_sent;
- dev_kfree_skb_any(skb);
+ dev_consume_skb_any(skb);
}
txbds_processed++;
@@ -1875,7 +1875,7 @@ static int bcmgenet_alloc_rx_buffers(struct bcmgenet_priv *priv,
cb = ring->cbs + i;
skb = bcmgenet_rx_refill(priv, cb);
if (skb)
- dev_kfree_skb_any(skb);
+ dev_consume_skb_any(skb);
if (!cb->skb)
return -ENOMEM;
}
@@ -1894,7 +1894,7 @@ static void bcmgenet_free_rx_buffers(struct bcmgenet_priv *priv)
skb = bcmgenet_free_rx_cb(&priv->pdev->dev, cb);
if (skb)
- dev_kfree_skb_any(skb);
+ dev_consume_skb_any(skb);
}
}
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c
index 51583ae..120b6e537 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
@@ -2468,7 +2468,7 @@ static void liquidio_napi_drv_callback(void *arg)
if (OCTEON_CN23XX_PF(oct) || droq->cpu_id == this_cpu) {
napi_schedule_irqoff(&droq->napi);
} else {
- struct call_single_data *csd = &droq->csd;
+ call_single_data_t *csd = &droq->csd;
csd->func = napi_schedule_wrapper;
csd->info = &droq->napi;
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_droq.h b/drivers/net/ethernet/cavium/liquidio/octeon_droq.h
index 6efd139..f91bc84 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_droq.h
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_droq.h
@@ -328,7 +328,7 @@ struct octeon_droq {
u32 cpu_id;
- struct call_single_data csd;
+ call_single_data_t csd;
};
#define OCT_DROQ_SIZE (sizeof(struct octeon_droq))
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index 82bf7aa..0293b41 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -369,12 +369,12 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
list_del(&entry.list);
spin_unlock(&adap->mbox_lock);
ret = (v == MBOX_OWNER_FW) ? -EBUSY : -ETIMEDOUT;
- t4_record_mbox(adap, cmd, MBOX_LEN, access, ret);
+ t4_record_mbox(adap, cmd, size, access, ret);
return ret;
}
/* Copy in the new mailbox command and send it on its way ... */
- t4_record_mbox(adap, cmd, MBOX_LEN, access, 0);
+ t4_record_mbox(adap, cmd, size, access, 0);
for (i = 0; i < size; i += 8)
t4_write_reg64(adap, data_reg + i, be64_to_cpu(*p++));
@@ -426,7 +426,7 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
}
ret = (pcie_fw & PCIE_FW_ERR_F) ? -ENXIO : -ETIMEDOUT;
- t4_record_mbox(adap, cmd, MBOX_LEN, access, ret);
+ t4_record_mbox(adap, cmd, size, access, ret);
dev_err(adap->pdev_dev, "command %#x in mailbox %d timed out\n",
*(const u8 *)cmd, mbox);
t4_report_fw_error(adap);
diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c
index 34dae51..59da7ac 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -1863,7 +1863,6 @@ err_setup_mdio:
err_ioremap:
release_resource(priv->res);
err_req_mem:
- netif_napi_del(&priv->napi);
free_netdev(netdev);
err_alloc_etherdev:
return err;
diff --git a/drivers/net/ethernet/freescale/fman/mac.c b/drivers/net/ethernet/freescale/fman/mac.c
index 6e67d22..1c7da16 100644
--- a/drivers/net/ethernet/freescale/fman/mac.c
+++ b/drivers/net/ethernet/freescale/fman/mac.c
@@ -623,6 +623,8 @@ static struct platform_device *dpaa_eth_add_device(int fman_id,
goto no_mem;
}
+ pdev->dev.of_node = node;
+ pdev->dev.parent = priv->dev;
set_dma_ops(&pdev->dev, get_dma_ops(priv->dev));
ret = platform_device_add_data(pdev, &data, sizeof(data));
diff --git a/drivers/net/ethernet/i825xx/lasi_82596.c b/drivers/net/ethernet/i825xx/lasi_82596.c
index d787fdd..aa22e10 100644
--- a/drivers/net/ethernet/i825xx/lasi_82596.c
+++ b/drivers/net/ethernet/i825xx/lasi_82596.c
@@ -149,7 +149,7 @@ static void mpu_port(struct net_device *dev, int c, dma_addr_t x)
#define LAN_PROM_ADDR 0xF0810000
-static int
+static int __init
lan_init_chip(struct parisc_device *dev)
{
struct net_device *netdevice;
@@ -194,7 +194,7 @@ lan_init_chip(struct parisc_device *dev)
return retval;
}
-static int lan_remove_chip(struct parisc_device *pdev)
+static int __exit lan_remove_chip(struct parisc_device *pdev)
{
struct net_device *dev = parisc_get_drvdata(pdev);
struct i596_private *lp = netdev_priv(dev);
@@ -206,7 +206,7 @@ static int lan_remove_chip(struct parisc_device *pdev)
return 0;
}
-static struct parisc_device_id lan_tbl[] = {
+static const struct parisc_device_id lan_tbl[] __initconst = {
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008a },
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00072 },
{ 0, }
@@ -214,11 +214,11 @@ static struct parisc_device_id lan_tbl[] = {
MODULE_DEVICE_TABLE(parisc, lan_tbl);
-static struct parisc_driver lan_driver = {
+static struct parisc_driver lan_driver __refdata = {
.name = "lasi_82596",
.id_table = lan_tbl,
.probe = lan_init_chip,
- .remove = lan_remove_chip,
+ .remove = __exit_p(lan_remove_chip),
};
static int lasi_82596_init(void)
diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
index 48d21c1..4d598ca 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -6504,7 +6504,7 @@ static int mvpp2_port_probe(struct platform_device *pdev,
struct resource *res;
const char *dt_mac_addr;
const char *mac_from;
- char hw_mac_addr[ETH_ALEN];
+ char hw_mac_addr[ETH_ALEN] = {0};
u32 id;
int features;
int phy_mode;
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index 674773b..78b89ce 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -2535,8 +2535,8 @@ int mlx4_cmd_init(struct mlx4_dev *dev)
}
if (!priv->cmd.pool) {
- priv->cmd.pool = pci_pool_create("mlx4_cmd",
- dev->persist->pdev,
+ priv->cmd.pool = dma_pool_create("mlx4_cmd",
+ &dev->persist->pdev->dev,
MLX4_MAILBOX_SIZE,
MLX4_MAILBOX_SIZE, 0);
if (!priv->cmd.pool)
@@ -2607,7 +2607,7 @@ void mlx4_cmd_cleanup(struct mlx4_dev *dev, int cleanup_mask)
struct mlx4_priv *priv = mlx4_priv(dev);
if (priv->cmd.pool && (cleanup_mask & MLX4_CMD_CLEANUP_POOL)) {
- pci_pool_destroy(priv->cmd.pool);
+ dma_pool_destroy(priv->cmd.pool);
priv->cmd.pool = NULL;
}
@@ -2699,7 +2699,7 @@ struct mlx4_cmd_mailbox *mlx4_alloc_cmd_mailbox(struct mlx4_dev *dev)
if (!mailbox)
return ERR_PTR(-ENOMEM);
- mailbox->buf = pci_pool_zalloc(mlx4_priv(dev)->cmd.pool, GFP_KERNEL,
+ mailbox->buf = dma_pool_zalloc(mlx4_priv(dev)->cmd.pool, GFP_KERNEL,
&mailbox->dma);
if (!mailbox->buf) {
kfree(mailbox);
@@ -2716,7 +2716,7 @@ void mlx4_free_cmd_mailbox(struct mlx4_dev *dev,
if (!mailbox)
return;
- pci_pool_free(mlx4_priv(dev)->cmd.pool, mailbox->buf, mailbox->dma);
+ dma_pool_free(mlx4_priv(dev)->cmd.pool, mailbox->buf, mailbox->dma);
kfree(mailbox);
}
EXPORT_SYMBOL_GPL(mlx4_free_cmd_mailbox);
diff --git a/drivers/net/ethernet/mellanox/mlx4/cq.c b/drivers/net/ethernet/mellanox/mlx4/cq.c
index c56a511..72eb50c 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cq.c
@@ -241,13 +241,14 @@ err_out:
return err;
}
-static int mlx4_cq_alloc_icm(struct mlx4_dev *dev, int *cqn)
+static int mlx4_cq_alloc_icm(struct mlx4_dev *dev, int *cqn, u8 usage)
{
+ u32 in_modifier = RES_CQ | (((u32)usage & 3) << 30);
u64 out_param;
int err;
if (mlx4_is_mfunc(dev)) {
- err = mlx4_cmd_imm(dev, 0, &out_param, RES_CQ,
+ err = mlx4_cmd_imm(dev, 0, &out_param, in_modifier,
RES_OP_RESERVE_AND_MAP, MLX4_CMD_ALLOC_RES,
MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
if (err)
@@ -303,7 +304,7 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent,
cq->vector = vector;
- err = mlx4_cq_alloc_icm(dev, &cq->cqn);
+ err = mlx4_cq_alloc_icm(dev, &cq->cqn, cq->usage);
if (err)
return err;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_cq.c b/drivers/net/ethernet/mellanox/mlx4/en_cq.c
index 85fe17e..f849eec 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_cq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_cq.c
@@ -140,6 +140,7 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,
(cq->type == RX && priv->hwtstamp_config.rx_filter))
timestamp_en = 1;
+ cq->mcq.usage = MLX4_RES_USAGE_DRIVER;
err = mlx4_cq_alloc(mdev->dev, cq->size, &cq->wqres.mtt,
&mdev->priv_uar, cq->wqres.db.dma, &cq->mcq,
cq->vector, 0, timestamp_en);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 3a291fc..e3e6d9f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -651,7 +651,8 @@ static int mlx4_en_get_qp(struct mlx4_en_priv *priv)
return 0;
}
- err = mlx4_qp_reserve_range(dev, 1, 1, qpn, MLX4_RESERVE_A0_QP);
+ err = mlx4_qp_reserve_range(dev, 1, 1, qpn, MLX4_RESERVE_A0_QP,
+ MLX4_RES_USAGE_DRIVER);
en_dbg(DRV, priv, "Reserved qp %d\n", *qpn);
if (err) {
en_err(priv, "Failed to reserve qp for mac registration\n");
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
index bf16380..ec24c40 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
@@ -1088,7 +1088,8 @@ int mlx4_en_create_drop_qp(struct mlx4_en_priv *priv)
u32 qpn;
err = mlx4_qp_reserve_range(priv->mdev->dev, 1, 1, &qpn,
- MLX4_RESERVE_A0_QP);
+ MLX4_RESERVE_A0_QP,
+ MLX4_RES_USAGE_DRIVER);
if (err) {
en_err(priv, "Failed reserving drop qpn\n");
return err;
@@ -1134,7 +1135,8 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
flags = priv->rx_ring_num == 1 ? MLX4_RESERVE_A0_QP : 0;
err = mlx4_qp_reserve_range(mdev->dev, priv->rx_ring_num,
priv->rx_ring_num,
- &rss_map->base_qpn, flags);
+ &rss_map->base_qpn, flags,
+ MLX4_RES_USAGE_DRIVER);
if (err) {
en_err(priv, "Failed reserving %d qps\n", priv->rx_ring_num);
return err;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
index 73faa3d..a81db25 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
@@ -105,7 +105,8 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv,
(unsigned long long) ring->sp_wqres.buf.direct.map);
err = mlx4_qp_reserve_range(mdev->dev, 1, 1, &ring->qpn,
- MLX4_RESERVE_ETH_BF_QP);
+ MLX4_RESERVE_ETH_BF_QP,
+ MLX4_RES_USAGE_DRIVER);
if (err) {
en_err(priv, "failed reserving qp for TX ring\n");
goto err_hwq_res;
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 5fe5cdc..a594bfd 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -2477,7 +2477,7 @@ static int mlx4_allocate_default_counters(struct mlx4_dev *dev)
priv->def_counter[port] = -1;
for (port = 0; port < dev->caps.num_ports; port++) {
- err = mlx4_counter_alloc(dev, &idx);
+ err = mlx4_counter_alloc(dev, &idx, MLX4_RES_USAGE_DRIVER);
if (!err || err == -ENOSPC) {
priv->def_counter[port] = idx;
@@ -2519,13 +2519,14 @@ int __mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx)
return 0;
}
-int mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx)
+int mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx, u8 usage)
{
+ u32 in_modifier = RES_COUNTER | (((u32)usage & 3) << 30);
u64 out_param;
int err;
if (mlx4_is_mfunc(dev)) {
- err = mlx4_cmd_imm(dev, 0, &out_param, RES_COUNTER,
+ err = mlx4_cmd_imm(dev, 0, &out_param, in_modifier,
RES_OP_RESERVE, MLX4_CMD_ALLOC_RES,
MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
if (!err)
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index 706d7f2..852d00a 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -626,7 +626,7 @@ struct mlx4_mgm {
};
struct mlx4_cmd {
- struct pci_pool *pool;
+ struct dma_pool *pool;
void __iomem *hcr;
struct mutex slave_cmd_mutex;
struct semaphore poll_sem;
diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c
index 26747212..5e5b447 100644
--- a/drivers/net/ethernet/mellanox/mlx4/qp.c
+++ b/drivers/net/ethernet/mellanox/mlx4/qp.c
@@ -245,8 +245,9 @@ int __mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align,
}
int mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align,
- int *base, u8 flags)
+ int *base, u8 flags, u8 usage)
{
+ u32 in_modifier = RES_QP | (((u32)usage & 3) << 30);
u64 in_param = 0;
u64 out_param;
int err;
@@ -258,7 +259,7 @@ int mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align,
set_param_l(&in_param, (((u32)flags) << 24) | (u32)cnt);
set_param_h(&in_param, align);
err = mlx4_cmd_imm(dev, in_param, &out_param,
- RES_QP, RES_OP_RESERVE,
+ in_modifier, RES_OP_RESERVE,
MLX4_CMD_ALLOC_RES,
MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
if (err)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
index 31cbe5e..1acbb72 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
@@ -1110,7 +1110,7 @@ static struct mlx5_cmd_mailbox *alloc_cmd_box(struct mlx5_core_dev *dev,
if (!mailbox)
return ERR_PTR(-ENOMEM);
- mailbox->buf = pci_pool_zalloc(dev->cmd.pool, flags,
+ mailbox->buf = dma_pool_zalloc(dev->cmd.pool, flags,
&mailbox->dma);
if (!mailbox->buf) {
mlx5_core_dbg(dev, "failed allocation\n");
@@ -1125,7 +1125,7 @@ static struct mlx5_cmd_mailbox *alloc_cmd_box(struct mlx5_core_dev *dev,
static void free_cmd_box(struct mlx5_core_dev *dev,
struct mlx5_cmd_mailbox *mailbox)
{
- pci_pool_free(dev->cmd.pool, mailbox->buf, mailbox->dma);
+ dma_pool_free(dev->cmd.pool, mailbox->buf, mailbox->dma);
kfree(mailbox);
}
@@ -1776,7 +1776,8 @@ int mlx5_cmd_init(struct mlx5_core_dev *dev)
return -EINVAL;
}
- cmd->pool = pci_pool_create("mlx5_cmd", dev->pdev, size, align, 0);
+ cmd->pool = dma_pool_create("mlx5_cmd", &dev->pdev->dev, size, align,
+ 0);
if (!cmd->pool)
return -ENOMEM;
@@ -1866,7 +1867,7 @@ err_free_page:
free_cmd_page(dev, cmd);
err_free_pool:
- pci_pool_destroy(cmd->pool);
+ dma_pool_destroy(cmd->pool);
return err;
}
@@ -1880,6 +1881,6 @@ void mlx5_cmd_cleanup(struct mlx5_core_dev *dev)
destroy_workqueue(cmd->wq);
destroy_msg_cache(dev);
free_cmd_page(dev, cmd);
- pci_pool_destroy(cmd->pool);
+ dma_pool_destroy(cmd->pool);
}
EXPORT_SYMBOL(mlx5_cmd_cleanup);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 0039b47..040d1af 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -263,6 +263,7 @@ struct mlx5e_dcbx {
/* The only setting that cannot be read from FW */
u8 tc_tsa[IEEE_8021QAZ_MAX_TCS];
+ u8 cap;
};
#endif
@@ -595,7 +596,6 @@ struct mlx5e_channel {
struct mlx5_core_dev *mdev;
struct mlx5e_tstamp *tstamp;
int ix;
- int cpu;
};
struct mlx5e_channels {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
index 2eb54d3..c1d384f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
@@ -288,13 +288,8 @@ static int mlx5e_dcbnl_ieee_setpfc(struct net_device *dev,
static u8 mlx5e_dcbnl_getdcbx(struct net_device *dev)
{
struct mlx5e_priv *priv = netdev_priv(dev);
- struct mlx5e_dcbx *dcbx = &priv->dcbx;
- u8 mode = DCB_CAP_DCBX_VER_IEEE | DCB_CAP_DCBX_VER_CEE;
-
- if (dcbx->mode == MLX5E_DCBX_PARAM_VER_OPER_HOST)
- mode |= DCB_CAP_DCBX_HOST;
- return mode;
+ return priv->dcbx.cap;
}
static u8 mlx5e_dcbnl_setdcbx(struct net_device *dev, u8 mode)
@@ -312,6 +307,7 @@ static u8 mlx5e_dcbnl_setdcbx(struct net_device *dev, u8 mode)
/* set dcbx to fw controlled */
if (!mlx5e_dcbnl_set_dcbx_mode(priv, MLX5E_DCBX_PARAM_VER_OPER_AUTO)) {
dcbx->mode = MLX5E_DCBX_PARAM_VER_OPER_AUTO;
+ dcbx->cap &= ~DCB_CAP_DCBX_HOST;
return 0;
}
@@ -324,6 +320,8 @@ static u8 mlx5e_dcbnl_setdcbx(struct net_device *dev, u8 mode)
if (mlx5e_dcbnl_switch_to_host_mode(netdev_priv(dev)))
return 1;
+ dcbx->cap = mode;
+
return 0;
}
@@ -628,9 +626,9 @@ static u8 mlx5e_dcbnl_getcap(struct net_device *netdev,
*cap = false;
break;
case DCB_CAP_ATTR_DCBX:
- *cap = (DCB_CAP_DCBX_LLD_MANAGED |
- DCB_CAP_DCBX_VER_CEE |
- DCB_CAP_DCBX_STATIC);
+ *cap = priv->dcbx.cap |
+ DCB_CAP_DCBX_VER_CEE |
+ DCB_CAP_DCBX_VER_IEEE;
break;
default:
*cap = 0;
@@ -754,8 +752,16 @@ void mlx5e_dcbnl_initialize(struct mlx5e_priv *priv)
{
struct mlx5e_dcbx *dcbx = &priv->dcbx;
+ if (!MLX5_CAP_GEN(priv->mdev, qos))
+ return;
+
if (MLX5_CAP_GEN(priv->mdev, dcbx))
mlx5e_dcbnl_query_dcbx_mode(priv, &dcbx->mode);
+ priv->dcbx.cap = DCB_CAP_DCBX_VER_CEE |
+ DCB_CAP_DCBX_VER_IEEE;
+ if (priv->dcbx.mode == MLX5E_DCBX_PARAM_VER_OPER_HOST)
+ priv->dcbx.cap |= DCB_CAP_DCBX_HOST;
+
mlx5e_ets_init(priv);
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
index 917fade..f559401 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -641,8 +641,10 @@ int mlx5e_ethtool_set_channels(struct mlx5e_priv *priv,
new_channels.params = priv->channels.params;
new_channels.params.num_channels = count;
- mlx5e_build_default_indir_rqt(priv->mdev, new_channels.params.indirection_rqt,
- MLX5E_INDIR_RQT_SIZE, count);
+ if (!netif_is_rxfh_configured(priv->netdev))
+ mlx5e_build_default_indir_rqt(priv->mdev,
+ new_channels.params.indirection_rqt,
+ MLX5E_INDIR_RQT_SIZE, count);
if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
priv->channels.params = new_channels.params;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 57f31fa..d75f309 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -71,6 +71,11 @@ struct mlx5e_channel_param {
struct mlx5e_cq_param icosq_cq;
};
+static int mlx5e_get_node(struct mlx5e_priv *priv, int ix)
+{
+ return pci_irq_get_node(priv->mdev->pdev, MLX5_EQ_VEC_COMP_BASE + ix);
+}
+
static bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev)
{
return MLX5_CAP_GEN(mdev, striding_rq) &&
@@ -396,7 +401,7 @@ static void mlx5e_enable_async_events(struct mlx5e_priv *priv)
static void mlx5e_disable_async_events(struct mlx5e_priv *priv)
{
clear_bit(MLX5E_STATE_ASYNC_EVENTS_ENABLED, &priv->state);
- synchronize_irq(mlx5_get_msix_vec(priv->mdev, MLX5_EQ_VEC_ASYNC));
+ synchronize_irq(pci_irq_vector(priv->mdev->pdev, MLX5_EQ_VEC_ASYNC));
}
static inline int mlx5e_get_wqe_mtt_sz(void)
@@ -443,16 +448,17 @@ static int mlx5e_rq_alloc_mpwqe_info(struct mlx5e_rq *rq,
int wq_sz = mlx5_wq_ll_get_size(&rq->wq);
int mtt_sz = mlx5e_get_wqe_mtt_sz();
int mtt_alloc = mtt_sz + MLX5_UMR_ALIGN - 1;
+ int node = mlx5e_get_node(c->priv, c->ix);
int i;
rq->mpwqe.info = kzalloc_node(wq_sz * sizeof(*rq->mpwqe.info),
- GFP_KERNEL, cpu_to_node(c->cpu));
+ GFP_KERNEL, node);
if (!rq->mpwqe.info)
goto err_out;
/* We allocate more than mtt_sz as we will align the pointer */
- rq->mpwqe.mtt_no_align = kzalloc_node(mtt_alloc * wq_sz, GFP_KERNEL,
- cpu_to_node(c->cpu));
+ rq->mpwqe.mtt_no_align = kzalloc_node(mtt_alloc * wq_sz,
+ GFP_KERNEL, node);
if (unlikely(!rq->mpwqe.mtt_no_align))
goto err_free_wqe_info;
@@ -560,7 +566,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
int err;
int i;
- rqp->wq.db_numa_node = cpu_to_node(c->cpu);
+ rqp->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix);
err = mlx5_wq_ll_create(mdev, &rqp->wq, rqc_wq, &rq->wq,
&rq->wq_ctrl);
@@ -627,7 +633,8 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
default: /* MLX5_WQ_TYPE_LINKED_LIST */
rq->wqe.frag_info =
kzalloc_node(wq_sz * sizeof(*rq->wqe.frag_info),
- GFP_KERNEL, cpu_to_node(c->cpu));
+ GFP_KERNEL,
+ mlx5e_get_node(c->priv, c->ix));
if (!rq->wqe.frag_info) {
err = -ENOMEM;
goto err_rq_wq_destroy;
@@ -992,13 +999,13 @@ static int mlx5e_alloc_xdpsq(struct mlx5e_channel *c,
sq->uar_map = mdev->mlx5e_res.bfreg.map;
sq->min_inline_mode = params->tx_min_inline_mode;
- param->wq.db_numa_node = cpu_to_node(c->cpu);
+ param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix);
err = mlx5_wq_cyc_create(mdev, &param->wq, sqc_wq, &sq->wq, &sq->wq_ctrl);
if (err)
return err;
sq->wq.db = &sq->wq.db[MLX5_SND_DBR];
- err = mlx5e_alloc_xdpsq_db(sq, cpu_to_node(c->cpu));
+ err = mlx5e_alloc_xdpsq_db(sq, mlx5e_get_node(c->priv, c->ix));
if (err)
goto err_sq_wq_destroy;
@@ -1046,13 +1053,13 @@ static int mlx5e_alloc_icosq(struct mlx5e_channel *c,
sq->channel = c;
sq->uar_map = mdev->mlx5e_res.bfreg.map;
- param->wq.db_numa_node = cpu_to_node(c->cpu);
+ param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix);
err = mlx5_wq_cyc_create(mdev, &param->wq, sqc_wq, &sq->wq, &sq->wq_ctrl);
if (err)
return err;
sq->wq.db = &sq->wq.db[MLX5_SND_DBR];
- err = mlx5e_alloc_icosq_db(sq, cpu_to_node(c->cpu));
+ err = mlx5e_alloc_icosq_db(sq, mlx5e_get_node(c->priv, c->ix));
if (err)
goto err_sq_wq_destroy;
@@ -1118,13 +1125,13 @@ static int mlx5e_alloc_txqsq(struct mlx5e_channel *c,
if (MLX5_IPSEC_DEV(c->priv->mdev))
set_bit(MLX5E_SQ_STATE_IPSEC, &sq->state);
- param->wq.db_numa_node = cpu_to_node(c->cpu);
+ param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix);
err = mlx5_wq_cyc_create(mdev, &param->wq, sqc_wq, &sq->wq, &sq->wq_ctrl);
if (err)
return err;
sq->wq.db = &sq->wq.db[MLX5_SND_DBR];
- err = mlx5e_alloc_txqsq_db(sq, cpu_to_node(c->cpu));
+ err = mlx5e_alloc_txqsq_db(sq, mlx5e_get_node(c->priv, c->ix));
if (err)
goto err_sq_wq_destroy;
@@ -1496,8 +1503,8 @@ static int mlx5e_alloc_cq(struct mlx5e_channel *c,
struct mlx5_core_dev *mdev = c->priv->mdev;
int err;
- param->wq.buf_numa_node = cpu_to_node(c->cpu);
- param->wq.db_numa_node = cpu_to_node(c->cpu);
+ param->wq.buf_numa_node = mlx5e_get_node(c->priv, c->ix);
+ param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix);
param->eq_ix = c->ix;
err = mlx5e_alloc_cq_common(mdev, param, cq);
@@ -1596,11 +1603,6 @@ static void mlx5e_close_cq(struct mlx5e_cq *cq)
mlx5e_free_cq(cq);
}
-static int mlx5e_get_cpu(struct mlx5e_priv *priv, int ix)
-{
- return cpumask_first(priv->mdev->priv.irq_info[ix].mask);
-}
-
static int mlx5e_open_tx_cqs(struct mlx5e_channel *c,
struct mlx5e_params *params,
struct mlx5e_channel_param *cparam)
@@ -1749,11 +1751,10 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
{
struct mlx5e_cq_moder icocq_moder = {0, 0};
struct net_device *netdev = priv->netdev;
- int cpu = mlx5e_get_cpu(priv, ix);
struct mlx5e_channel *c;
int err;
- c = kzalloc_node(sizeof(*c), GFP_KERNEL, cpu_to_node(cpu));
+ c = kzalloc_node(sizeof(*c), GFP_KERNEL, mlx5e_get_node(priv, ix));
if (!c)
return -ENOMEM;
@@ -1761,7 +1762,6 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
c->mdev = priv->mdev;
c->tstamp = &priv->tstamp;
c->ix = ix;
- c->cpu = cpu;
c->pdev = &priv->mdev->pdev->dev;
c->netdev = priv->netdev;
c->mkey_be = cpu_to_be32(priv->mdev->mlx5e_res.mkey.key);
@@ -1847,7 +1847,8 @@ static void mlx5e_activate_channel(struct mlx5e_channel *c)
for (tc = 0; tc < c->num_tc; tc++)
mlx5e_activate_txqsq(&c->sq[tc]);
mlx5e_activate_rq(&c->rq);
- netif_set_xps_queue(c->netdev, get_cpu_mask(c->cpu), c->ix);
+ netif_set_xps_queue(c->netdev,
+ mlx5_get_vector_affinity(c->priv->mdev, c->ix), c->ix);
}
static void mlx5e_deactivate_channel(struct mlx5e_channel *c)
@@ -1969,6 +1970,7 @@ static void mlx5e_build_rx_cq_param(struct mlx5e_priv *priv,
}
mlx5e_build_common_cq_param(priv, param);
+ param->cq_period_mode = params->rx_cq_period_mode;
}
static void mlx5e_build_tx_cq_param(struct mlx5e_priv *priv,
@@ -3792,18 +3794,8 @@ void mlx5e_build_default_indir_rqt(struct mlx5_core_dev *mdev,
u32 *indirection_rqt, int len,
int num_channels)
{
- int node = mdev->priv.numa_node;
- int node_num_of_cores;
int i;
- if (node == -1)
- node = first_online_node;
-
- node_num_of_cores = cpumask_weight(cpumask_of_node(node));
-
- if (node_num_of_cores)
- num_channels = min_t(int, num_channels, node_num_of_cores);
-
for (i = 0; i < len; i++)
indirection_rqt[i] = i % num_channels;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index 325b2c8..7344433 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -222,13 +222,13 @@ static inline int mlx5e_page_alloc_mapped(struct mlx5e_rq *rq,
if (unlikely(!page))
return -ENOMEM;
- dma_info->page = page;
dma_info->addr = dma_map_page(rq->pdev, page, 0,
RQ_PAGE_SIZE(rq), rq->buff.map_dir);
if (unlikely(dma_mapping_error(rq->pdev, dma_info->addr))) {
put_page(page);
return -ENOMEM;
}
+ dma_info->page = page;
return 0;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c b/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c
index 898759f..1f1f8af 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c
@@ -189,6 +189,7 @@ struct mlx5e_lbt_priv {
struct packet_type pt;
struct completion comp;
bool loopback_ok;
+ bool local_lb;
};
static int
@@ -236,6 +237,13 @@ static int mlx5e_test_loopback_setup(struct mlx5e_priv *priv,
{
int err = 0;
+ /* Temporarily enable local_lb */
+ if (MLX5_CAP_GEN(priv->mdev, disable_local_lb)) {
+ mlx5_nic_vport_query_local_lb(priv->mdev, &lbtp->local_lb);
+ if (!lbtp->local_lb)
+ mlx5_nic_vport_update_local_lb(priv->mdev, true);
+ }
+
err = mlx5e_refresh_tirs(priv, true);
if (err)
return err;
@@ -254,6 +262,11 @@ static int mlx5e_test_loopback_setup(struct mlx5e_priv *priv,
static void mlx5e_test_loopback_cleanup(struct mlx5e_priv *priv,
struct mlx5e_lbt_priv *lbtp)
{
+ if (MLX5_CAP_GEN(priv->mdev, disable_local_lb)) {
+ if (!lbtp->local_lb)
+ mlx5_nic_vport_update_local_lb(priv->mdev, false);
+ }
+
dev_remove_pack(&lbtp->pt);
mlx5e_refresh_tirs(priv, false);
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index 3c536f5..7f282e8 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -1443,12 +1443,10 @@ static int mlx5e_route_lookup_ipv6(struct mlx5e_priv *priv,
struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
int ret;
- dst = ip6_route_output(dev_net(mirred_dev), NULL, fl6);
- ret = dst->error;
- if (ret) {
- dst_release(dst);
+ ret = ipv6_stub->ipv6_dst_lookup(dev_net(mirred_dev), NULL, &dst,
+ fl6);
+ if (ret < 0)
return ret;
- }
*out_ttl = ip6_dst_hoplimit(dst);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
index aaa0f4e..31353e5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
@@ -128,10 +128,10 @@ static inline int mlx5e_skb_l3_header_offset(struct sk_buff *skb)
return mlx5e_skb_l2_header_offset(skb);
}
-static inline unsigned int mlx5e_calc_min_inline(enum mlx5_inline_modes mode,
- struct sk_buff *skb)
+static inline u16 mlx5e_calc_min_inline(enum mlx5_inline_modes mode,
+ struct sk_buff *skb)
{
- int hlen;
+ u16 hlen;
switch (mode) {
case MLX5_INLINE_MODE_NONE:
@@ -140,19 +140,22 @@ static inline unsigned int mlx5e_calc_min_inline(enum mlx5_inline_modes mode,
hlen = eth_get_headlen(skb->data, skb_headlen(skb));
if (hlen == ETH_HLEN && !skb_vlan_tag_present(skb))
hlen += VLAN_HLEN;
- return hlen;
+ break;
case MLX5_INLINE_MODE_IP:
/* When transport header is set to zero, it means no transport
* header. When transport header is set to 0xff's, it means
* transport header wasn't set.
*/
- if (skb_transport_offset(skb))
- return mlx5e_skb_l3_header_offset(skb);
+ if (skb_transport_offset(skb)) {
+ hlen = mlx5e_skb_l3_header_offset(skb);
+ break;
+ }
/* fall through */
case MLX5_INLINE_MODE_L2:
default:
- return mlx5e_skb_l2_header_offset(skb);
+ hlen = mlx5e_skb_l2_header_offset(skb);
}
+ return min_t(u16, hlen, skb->len);
}
static inline void mlx5e_tx_skb_pull_inline(unsigned char **skb_data,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
index 52b9a64..edd11eb 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
@@ -161,6 +161,8 @@ static const char *eqe_type_str(u8 type)
return "MLX5_EVENT_TYPE_NIC_VPORT_CHANGE";
case MLX5_EVENT_TYPE_FPGA_ERROR:
return "MLX5_EVENT_TYPE_FPGA_ERROR";
+ case MLX5_EVENT_TYPE_GENERAL_EVENT:
+ return "MLX5_EVENT_TYPE_GENERAL_EVENT";
default:
return "Unrecognized event";
}
@@ -378,6 +380,20 @@ int mlx5_core_page_fault_resume(struct mlx5_core_dev *dev, u32 token,
EXPORT_SYMBOL_GPL(mlx5_core_page_fault_resume);
#endif
+static void general_event_handler(struct mlx5_core_dev *dev,
+ struct mlx5_eqe *eqe)
+{
+ switch (eqe->sub_type) {
+ case MLX5_GENERAL_SUBTYPE_DELAY_DROP_TIMEOUT:
+ if (dev->event)
+ dev->event(dev, MLX5_DEV_EVENT_DELAY_DROP_TIMEOUT, 0);
+ break;
+ default:
+ mlx5_core_dbg(dev, "General event with unrecognized subtype: sub_type %d\n",
+ eqe->sub_type);
+ }
+}
+
static irqreturn_t mlx5_eq_int(int irq, void *eq_ptr)
{
struct mlx5_eq *eq = eq_ptr;
@@ -486,6 +502,9 @@ static irqreturn_t mlx5_eq_int(int irq, void *eq_ptr)
mlx5_fpga_event(dev, eqe->type, &eqe->data.raw);
break;
+ case MLX5_EVENT_TYPE_GENERAL_EVENT:
+ general_event_handler(dev, eqe);
+ break;
default:
mlx5_core_warn(dev, "Unhandled event 0x%x on EQ 0x%x\n",
eqe->type, eq->eqn);
@@ -585,7 +604,7 @@ int mlx5_create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, u8 vecidx,
name, pci_name(dev->pdev));
eq->eqn = MLX5_GET(create_eq_out, out, eq_number);
- eq->irqn = priv->msix_arr[vecidx].vector;
+ eq->irqn = pci_irq_vector(dev->pdev, vecidx);
eq->dev = dev;
eq->doorbell = priv->uar->map + MLX5_EQ_DOORBEL_OFFSET;
err = request_irq(eq->irqn, handler, 0,
@@ -620,7 +639,7 @@ int mlx5_create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, u8 vecidx,
return 0;
err_irq:
- free_irq(priv->msix_arr[vecidx].vector, eq);
+ free_irq(eq->irqn, eq);
err_eq:
mlx5_cmd_destroy_eq(dev, eq->eqn);
@@ -661,11 +680,6 @@ int mlx5_destroy_unmap_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq)
}
EXPORT_SYMBOL_GPL(mlx5_destroy_unmap_eq);
-u32 mlx5_get_msix_vec(struct mlx5_core_dev *dev, int vecidx)
-{
- return dev->priv.msix_arr[MLX5_EQ_VEC_ASYNC].vector;
-}
-
int mlx5_eq_init(struct mlx5_core_dev *dev)
{
int err;
@@ -693,6 +707,10 @@ int mlx5_start_eqs(struct mlx5_core_dev *dev)
mlx5_core_is_pf(dev))
async_event_mask |= (1ull << MLX5_EVENT_TYPE_NIC_VPORT_CHANGE);
+ if (MLX5_CAP_GEN(dev, port_type) == MLX5_CAP_PORT_TYPE_ETH &&
+ MLX5_CAP_GEN(dev, general_notification_event))
+ async_event_mask |= (1ull << MLX5_EVENT_TYPE_GENERAL_EVENT);
+
if (MLX5_CAP_GEN(dev, port_module_event))
async_event_mask |= (1ull << MLX5_EVENT_TYPE_PORT_MODULE_EVENT);
else
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
index 8b18cc9..5b41f69 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
@@ -1585,7 +1585,7 @@ static void esw_disable_vport(struct mlx5_eswitch *esw, int vport_num)
/* Mark this vport as disabled to discard new events */
vport->enabled = false;
- synchronize_irq(mlx5_get_msix_vec(esw->dev, MLX5_EQ_VEC_ASYNC));
+ synchronize_irq(pci_irq_vector(esw->dev->pdev, MLX5_EQ_VEC_ASYNC));
/* Wait for current already scheduled events to complete */
flush_workqueue(esw->work_queue);
/* Disable events from this vport */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
index 95b6402..5bc0593 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
@@ -815,7 +815,7 @@ void esw_offloads_cleanup(struct mlx5_eswitch *esw, int nvports)
struct mlx5_eswitch_rep *rep;
int vport;
- for (vport = 0; vport < nvports; vport++) {
+ for (vport = nvports - 1; vport >= 0; vport--) {
rep = &esw->offloads.vport_reps[vport];
if (!rep->valid)
continue;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw.c b/drivers/net/ethernet/mellanox/mlx5/core/fw.c
index fa33d59..2c71557 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fw.c
@@ -120,6 +120,12 @@ int mlx5_query_hca_caps(struct mlx5_core_dev *dev)
return err;
}
+ if (MLX5_CAP_GEN(dev, ipoib_enhanced_offloads)) {
+ err = mlx5_core_get_caps(dev, MLX5_CAP_IPOIB_ENHANCED_OFFLOADS);
+ if (err)
+ return err;
+ }
+
if (MLX5_CAP_GEN(dev, pg)) {
err = mlx5_core_get_caps(dev, MLX5_CAP_ODP);
if (err)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/health.c b/drivers/net/ethernet/mellanox/mlx5/core/health.c
index 4b6b03d..8aea0a0 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/health.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c
@@ -81,7 +81,7 @@ static void trigger_cmd_completions(struct mlx5_core_dev *dev)
u64 vector;
/* wait for pending handlers to complete */
- synchronize_irq(dev->priv.msix_arr[MLX5_EQ_VEC_CMD].vector);
+ synchronize_irq(pci_irq_vector(dev->pdev, MLX5_EQ_VEC_CMD));
spin_lock_irqsave(&dev->cmd.alloc_lock, flags);
vector = ~dev->cmd.bitmask & ((1ul << (1 << dev->cmd.log_sz)) - 1);
if (!vector)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index c065132..8c4b45ef5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -47,6 +47,7 @@
#include <linux/debugfs.h>
#include <linux/kmod.h>
#include <linux/mlx5/mlx5_ifc.h>
+#include <linux/mlx5/vport.h>
#ifdef CONFIG_RFS_ACCEL
#include <linux/cpu_rmap.h>
#endif
@@ -312,13 +313,15 @@ static void release_bar(struct pci_dev *pdev)
pci_release_regions(pdev);
}
-static int mlx5_enable_msix(struct mlx5_core_dev *dev)
+static int mlx5_alloc_irq_vectors(struct mlx5_core_dev *dev)
{
struct mlx5_priv *priv = &dev->priv;
struct mlx5_eq_table *table = &priv->eq_table;
+ struct irq_affinity irqdesc = {
+ .pre_vectors = MLX5_EQ_VEC_COMP_BASE,
+ };
int num_eqs = 1 << MLX5_CAP_GEN(dev, log_max_eq);
int nvec;
- int i;
nvec = MLX5_CAP_GEN(dev, num_ports) * num_online_cpus() +
MLX5_EQ_VEC_COMP_BASE;
@@ -326,17 +329,14 @@ static int mlx5_enable_msix(struct mlx5_core_dev *dev)
if (nvec <= MLX5_EQ_VEC_COMP_BASE)
return -ENOMEM;
- priv->msix_arr = kcalloc(nvec, sizeof(*priv->msix_arr), GFP_KERNEL);
-
priv->irq_info = kcalloc(nvec, sizeof(*priv->irq_info), GFP_KERNEL);
- if (!priv->msix_arr || !priv->irq_info)
+ if (!priv->irq_info)
goto err_free_msix;
- for (i = 0; i < nvec; i++)
- priv->msix_arr[i].entry = i;
-
- nvec = pci_enable_msix_range(dev->pdev, priv->msix_arr,
- MLX5_EQ_VEC_COMP_BASE + 1, nvec);
+ nvec = pci_alloc_irq_vectors_affinity(dev->pdev,
+ MLX5_EQ_VEC_COMP_BASE + 1, nvec,
+ PCI_IRQ_MSIX | PCI_IRQ_AFFINITY,
+ &irqdesc);
if (nvec < 0)
return nvec;
@@ -346,17 +346,15 @@ static int mlx5_enable_msix(struct mlx5_core_dev *dev)
err_free_msix:
kfree(priv->irq_info);
- kfree(priv->msix_arr);
return -ENOMEM;
}
-static void mlx5_disable_msix(struct mlx5_core_dev *dev)
+static void mlx5_free_irq_vectors(struct mlx5_core_dev *dev)
{
struct mlx5_priv *priv = &dev->priv;
- pci_disable_msix(dev->pdev);
+ pci_free_irq_vectors(dev->pdev);
kfree(priv->irq_info);
- kfree(priv->msix_arr);
}
struct mlx5_reg_host_endianness {
@@ -579,6 +577,18 @@ static int set_hca_ctrl(struct mlx5_core_dev *dev)
return err;
}
+static int mlx5_core_set_hca_defaults(struct mlx5_core_dev *dev)
+{
+ int ret = 0;
+
+ /* Disable local_lb by default */
+ if ((MLX5_CAP_GEN(dev, port_type) == MLX5_CAP_PORT_TYPE_ETH) &&
+ MLX5_CAP_GEN(dev, disable_local_lb))
+ ret = mlx5_nic_vport_update_local_lb(dev, false);
+
+ return ret;
+}
+
int mlx5_core_enable_hca(struct mlx5_core_dev *dev, u16 func_id)
{
u32 out[MLX5_ST_SZ_DW(enable_hca_out)] = {0};
@@ -612,65 +622,6 @@ u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev)
return (u64)timer_l | (u64)timer_h1 << 32;
}
-static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i)
-{
- struct mlx5_priv *priv = &mdev->priv;
- struct msix_entry *msix = priv->msix_arr;
- int irq = msix[i + MLX5_EQ_VEC_COMP_BASE].vector;
-
- if (!zalloc_cpumask_var(&priv->irq_info[i].mask, GFP_KERNEL)) {
- mlx5_core_warn(mdev, "zalloc_cpumask_var failed");
- return -ENOMEM;
- }
-
- cpumask_set_cpu(cpumask_local_spread(i, priv->numa_node),
- priv->irq_info[i].mask);
-
- if (IS_ENABLED(CONFIG_SMP) &&
- irq_set_affinity_hint(irq, priv->irq_info[i].mask))
- mlx5_core_warn(mdev, "irq_set_affinity_hint failed, irq 0x%.4x", irq);
-
- return 0;
-}
-
-static void mlx5_irq_clear_affinity_hint(struct mlx5_core_dev *mdev, int i)
-{
- struct mlx5_priv *priv = &mdev->priv;
- struct msix_entry *msix = priv->msix_arr;
- int irq = msix[i + MLX5_EQ_VEC_COMP_BASE].vector;
-
- irq_set_affinity_hint(irq, NULL);
- free_cpumask_var(priv->irq_info[i].mask);
-}
-
-static int mlx5_irq_set_affinity_hints(struct mlx5_core_dev *mdev)
-{
- int err;
- int i;
-
- for (i = 0; i < mdev->priv.eq_table.num_comp_vectors; i++) {
- err = mlx5_irq_set_affinity_hint(mdev, i);
- if (err)
- goto err_out;
- }
-
- return 0;
-
-err_out:
- for (i--; i >= 0; i--)
- mlx5_irq_clear_affinity_hint(mdev, i);
-
- return err;
-}
-
-static void mlx5_irq_clear_affinity_hints(struct mlx5_core_dev *mdev)
-{
- int i;
-
- for (i = 0; i < mdev->priv.eq_table.num_comp_vectors; i++)
- mlx5_irq_clear_affinity_hint(mdev, i);
-}
-
int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn,
unsigned int *irqn)
{
@@ -760,8 +711,8 @@ static int alloc_comp_eqs(struct mlx5_core_dev *dev)
}
#ifdef CONFIG_RFS_ACCEL
- irq_cpu_rmap_add(dev->rmap,
- dev->priv.msix_arr[i + MLX5_EQ_VEC_COMP_BASE].vector);
+ irq_cpu_rmap_add(dev->rmap, pci_irq_vector(dev->pdev,
+ MLX5_EQ_VEC_COMP_BASE + i));
#endif
snprintf(name, MLX5_MAX_IRQ_NAME, "mlx5_comp%d", i);
err = mlx5_create_map_eq(dev, eq,
@@ -1119,9 +1070,9 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
goto err_stop_poll;
}
- err = mlx5_enable_msix(dev);
+ err = mlx5_alloc_irq_vectors(dev);
if (err) {
- dev_err(&pdev->dev, "enable msix failed\n");
+ dev_err(&pdev->dev, "alloc irq vectors failed\n");
goto err_cleanup_once;
}
@@ -1143,15 +1094,15 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
goto err_stop_eqs;
}
- err = mlx5_irq_set_affinity_hints(dev);
+ err = mlx5_init_fs(dev);
if (err) {
- dev_err(&pdev->dev, "Failed to alloc affinity hint cpumask\n");
- goto err_affinity_hints;
+ dev_err(&pdev->dev, "Failed to init flow steering\n");
+ goto err_fs;
}
- err = mlx5_init_fs(dev);
+ err = mlx5_core_set_hca_defaults(dev);
if (err) {
- dev_err(&pdev->dev, "Failed to init flow steering\n");
+ dev_err(&pdev->dev, "Failed to set hca defaults\n");
goto err_fs;
}
@@ -1186,7 +1137,6 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
}
}
- clear_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state);
set_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state);
out:
mutex_unlock(&dev->intf_state_mutex);
@@ -1208,9 +1158,6 @@ err_sriov:
mlx5_cleanup_fs(dev);
err_fs:
- mlx5_irq_clear_affinity_hints(dev);
-
-err_affinity_hints:
free_comp_eqs(dev);
err_stop_eqs:
@@ -1220,7 +1167,7 @@ err_put_uars:
mlx5_put_uars_page(dev, priv->uar);
err_disable_msix:
- mlx5_disable_msix(dev);
+ mlx5_free_irq_vectors(dev);
err_cleanup_once:
if (boot)
@@ -1261,7 +1208,7 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
mlx5_drain_health_recovery(dev);
mutex_lock(&dev->intf_state_mutex);
- if (test_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state)) {
+ if (!test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) {
dev_warn(&dev->pdev->dev, "%s: interface is down, NOP\n",
__func__);
if (cleanup)
@@ -1270,7 +1217,6 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
}
clear_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state);
- set_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state);
if (mlx5_device_registered(dev))
mlx5_detach_device(dev);
@@ -1283,11 +1229,10 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
mlx5_eswitch_detach(dev->priv.eswitch);
#endif
mlx5_cleanup_fs(dev);
- mlx5_irq_clear_affinity_hints(dev);
free_comp_eqs(dev);
mlx5_stop_eqs(dev);
mlx5_put_uars_page(dev, priv->uar);
- mlx5_disable_msix(dev);
+ mlx5_free_irq_vectors(dev);
if (cleanup)
mlx5_cleanup_once(dev);
mlx5_stop_health_poll(dev);
@@ -1565,8 +1510,6 @@ static void shutdown(struct pci_dev *pdev)
int err;
dev_info(&pdev->dev, "Shutdown was called\n");
- /* Notify mlx5 clients that the kernel is being shut down */
- set_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &dev->intf_state);
err = mlx5_try_fast_unload(dev);
if (err)
mlx5_unload_one(dev, priv, false);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
index 6a263e8..01d637d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
@@ -110,7 +110,6 @@ int mlx5_destroy_scheduling_element_cmd(struct mlx5_core_dev *dev, u8 hierarchy,
u32 element_id);
int mlx5_wait_for_vf_pages(struct mlx5_core_dev *dev);
u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev);
-u32 mlx5_get_msix_vec(struct mlx5_core_dev *dev, int vecidx);
struct mlx5_eq *mlx5_eqn2eq(struct mlx5_core_dev *dev, int eqn);
void mlx5_cq_tasklet_cb(unsigned long data);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/qp.c b/drivers/net/ethernet/mellanox/mlx5/core/qp.c
index 340f281..db9e665 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/qp.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/qp.c
@@ -242,6 +242,20 @@ int mlx5_core_destroy_qp(struct mlx5_core_dev *dev,
}
EXPORT_SYMBOL_GPL(mlx5_core_destroy_qp);
+int mlx5_core_set_delay_drop(struct mlx5_core_dev *dev,
+ u32 timeout_usec)
+{
+ u32 out[MLX5_ST_SZ_DW(set_delay_drop_params_out)] = {0};
+ u32 in[MLX5_ST_SZ_DW(set_delay_drop_params_in)] = {0};
+
+ MLX5_SET(set_delay_drop_params_in, in, opcode,
+ MLX5_CMD_OP_SET_DELAY_DROP_PARAMS);
+ MLX5_SET(set_delay_drop_params_in, in, delay_drop_timeout,
+ timeout_usec / 100);
+ return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
+}
+EXPORT_SYMBOL_GPL(mlx5_core_set_delay_drop);
+
struct mbox_info {
u32 *in;
u32 *out;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sriov.c b/drivers/net/ethernet/mellanox/mlx5/core/sriov.c
index bf99d40..28d8472 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/sriov.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/sriov.c
@@ -32,6 +32,7 @@
#include <linux/pci.h>
#include <linux/mlx5/driver.h>
+#include <linux/mlx5/vport.h>
#include "mlx5_core.h"
#ifdef CONFIG_MLX5_CORE_EN
#include "eswitch.h"
@@ -44,6 +45,38 @@ bool mlx5_sriov_is_enabled(struct mlx5_core_dev *dev)
return !!sriov->num_vfs;
}
+static int sriov_restore_guids(struct mlx5_core_dev *dev, int vf)
+{
+ struct mlx5_core_sriov *sriov = &dev->priv.sriov;
+ struct mlx5_hca_vport_context *in;
+ int err = 0;
+
+ /* Restore sriov guid and policy settings */
+ if (sriov->vfs_ctx[vf].node_guid ||
+ sriov->vfs_ctx[vf].port_guid ||
+ sriov->vfs_ctx[vf].policy != MLX5_POLICY_INVALID) {
+ in = kzalloc(sizeof(*in), GFP_KERNEL);
+ if (!in)
+ return -ENOMEM;
+
+ in->node_guid = sriov->vfs_ctx[vf].node_guid;
+ in->port_guid = sriov->vfs_ctx[vf].port_guid;
+ in->policy = sriov->vfs_ctx[vf].policy;
+ in->field_select =
+ !!(in->port_guid) * MLX5_HCA_VPORT_SEL_PORT_GUID |
+ !!(in->node_guid) * MLX5_HCA_VPORT_SEL_NODE_GUID |
+ !!(in->policy) * MLX5_HCA_VPORT_SEL_STATE_POLICY;
+
+ err = mlx5_core_modify_hca_vport_context(dev, 1, 1, vf + 1, in);
+ if (err)
+ mlx5_core_warn(dev, "modify vport context failed, unable to restore VF %d settings\n", vf);
+
+ kfree(in);
+ }
+
+ return err;
+}
+
static int mlx5_device_enable_sriov(struct mlx5_core_dev *dev, int num_vfs)
{
struct mlx5_core_sriov *sriov = &dev->priv.sriov;
@@ -74,6 +107,15 @@ static int mlx5_device_enable_sriov(struct mlx5_core_dev *dev, int num_vfs)
}
sriov->vfs_ctx[vf].enabled = 1;
sriov->enabled_vfs++;
+ if (MLX5_CAP_GEN(dev, port_type) == MLX5_CAP_PORT_TYPE_IB) {
+ err = sriov_restore_guids(dev, vf);
+ if (err) {
+ mlx5_core_warn(dev,
+ "failed to restore VF %d settings, err %d\n",
+ vf, err);
+ continue;
+ }
+ }
mlx5_core_dbg(dev, "successfully enabled VF* %d\n", vf);
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/srq.c b/drivers/net/ethernet/mellanox/mlx5/core/srq.c
index f774de6..23cc337 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/srq.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/srq.c
@@ -201,13 +201,13 @@ static int destroy_srq_cmd(struct mlx5_core_dev *dev,
static int arm_srq_cmd(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq,
u16 lwm, int is_srq)
{
- /* arm_srq structs missing using identical xrc ones */
- u32 srq_in[MLX5_ST_SZ_DW(arm_xrc_srq_in)] = {0};
- u32 srq_out[MLX5_ST_SZ_DW(arm_xrc_srq_out)] = {0};
+ u32 srq_in[MLX5_ST_SZ_DW(arm_rq_in)] = {0};
+ u32 srq_out[MLX5_ST_SZ_DW(arm_rq_out)] = {0};
- MLX5_SET(arm_xrc_srq_in, srq_in, opcode, MLX5_CMD_OP_ARM_XRC_SRQ);
- MLX5_SET(arm_xrc_srq_in, srq_in, xrc_srqn, srq->srqn);
- MLX5_SET(arm_xrc_srq_in, srq_in, lwm, lwm);
+ MLX5_SET(arm_rq_in, srq_in, opcode, MLX5_CMD_OP_ARM_RQ);
+ MLX5_SET(arm_rq_in, srq_in, op_mod, MLX5_ARM_RQ_IN_OP_MOD_SRQ);
+ MLX5_SET(arm_rq_in, srq_in, srq_number, srq->srqn);
+ MLX5_SET(arm_rq_in, srq_in, lwm, lwm);
return mlx5_cmd_exec(dev, srq_in, sizeof(srq_in),
srq_out, sizeof(srq_out));
@@ -435,16 +435,128 @@ out:
return err;
}
+static int create_xrq_cmd(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq,
+ struct mlx5_srq_attr *in)
+{
+ u32 create_out[MLX5_ST_SZ_DW(create_xrq_out)] = {0};
+ void *create_in;
+ void *xrqc;
+ void *wq;
+ int pas_size;
+ int inlen;
+ int err;
+
+ pas_size = get_pas_size(in);
+ inlen = MLX5_ST_SZ_BYTES(create_xrq_in) + pas_size;
+ create_in = kvzalloc(inlen, GFP_KERNEL);
+ if (!create_in)
+ return -ENOMEM;
+
+ xrqc = MLX5_ADDR_OF(create_xrq_in, create_in, xrq_context);
+ wq = MLX5_ADDR_OF(xrqc, xrqc, wq);
+
+ set_wq(wq, in);
+ memcpy(MLX5_ADDR_OF(xrqc, xrqc, wq.pas), in->pas, pas_size);
+
+ if (in->type == IB_SRQT_TM) {
+ MLX5_SET(xrqc, xrqc, topology, MLX5_XRQC_TOPOLOGY_TAG_MATCHING);
+ if (in->flags & MLX5_SRQ_FLAG_RNDV)
+ MLX5_SET(xrqc, xrqc, offload, MLX5_XRQC_OFFLOAD_RNDV);
+ MLX5_SET(xrqc, xrqc,
+ tag_matching_topology_context.log_matching_list_sz,
+ in->tm_log_list_size);
+ }
+ MLX5_SET(xrqc, xrqc, user_index, in->user_index);
+ MLX5_SET(xrqc, xrqc, cqn, in->cqn);
+ MLX5_SET(create_xrq_in, create_in, opcode, MLX5_CMD_OP_CREATE_XRQ);
+ err = mlx5_cmd_exec(dev, create_in, inlen, create_out,
+ sizeof(create_out));
+ kvfree(create_in);
+ if (!err)
+ srq->srqn = MLX5_GET(create_xrq_out, create_out, xrqn);
+
+ return err;
+}
+
+static int destroy_xrq_cmd(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq)
+{
+ u32 in[MLX5_ST_SZ_DW(destroy_xrq_in)] = {0};
+ u32 out[MLX5_ST_SZ_DW(destroy_xrq_out)] = {0};
+
+ MLX5_SET(destroy_xrq_in, in, opcode, MLX5_CMD_OP_DESTROY_XRQ);
+ MLX5_SET(destroy_xrq_in, in, xrqn, srq->srqn);
+
+ return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
+}
+
+static int arm_xrq_cmd(struct mlx5_core_dev *dev,
+ struct mlx5_core_srq *srq,
+ u16 lwm)
+{
+ u32 out[MLX5_ST_SZ_DW(arm_rq_out)] = {0};
+ u32 in[MLX5_ST_SZ_DW(arm_rq_in)] = {0};
+
+ MLX5_SET(arm_rq_in, in, opcode, MLX5_CMD_OP_ARM_RQ);
+ MLX5_SET(arm_rq_in, in, op_mod, MLX5_ARM_RQ_IN_OP_MOD_XRQ);
+ MLX5_SET(arm_rq_in, in, srq_number, srq->srqn);
+ MLX5_SET(arm_rq_in, in, lwm, lwm);
+
+ return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
+}
+
+static int query_xrq_cmd(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq,
+ struct mlx5_srq_attr *out)
+{
+ u32 in[MLX5_ST_SZ_DW(query_xrq_in)] = {0};
+ u32 *xrq_out;
+ int outlen = MLX5_ST_SZ_BYTES(query_xrq_out);
+ void *xrqc;
+ int err;
+
+ xrq_out = kvzalloc(outlen, GFP_KERNEL);
+ if (!xrq_out)
+ return -ENOMEM;
+
+ MLX5_SET(query_xrq_in, in, opcode, MLX5_CMD_OP_QUERY_XRQ);
+ MLX5_SET(query_xrq_in, in, xrqn, srq->srqn);
+
+ err = mlx5_cmd_exec(dev, in, sizeof(in), xrq_out, outlen);
+ if (err)
+ goto out;
+
+ xrqc = MLX5_ADDR_OF(query_xrq_out, xrq_out, xrq_context);
+ get_wq(MLX5_ADDR_OF(xrqc, xrqc, wq), out);
+ if (MLX5_GET(xrqc, xrqc, state) != MLX5_XRQC_STATE_GOOD)
+ out->flags |= MLX5_SRQ_FLAG_ERR;
+ out->tm_next_tag =
+ MLX5_GET(xrqc, xrqc,
+ tag_matching_topology_context.append_next_index);
+ out->tm_hw_phase_cnt =
+ MLX5_GET(xrqc, xrqc,
+ tag_matching_topology_context.hw_phase_cnt);
+ out->tm_sw_phase_cnt =
+ MLX5_GET(xrqc, xrqc,
+ tag_matching_topology_context.sw_phase_cnt);
+
+out:
+ kvfree(xrq_out);
+ return err;
+}
+
static int create_srq_split(struct mlx5_core_dev *dev,
struct mlx5_core_srq *srq,
struct mlx5_srq_attr *in)
{
if (!dev->issi)
return create_srq_cmd(dev, srq, in);
- else if (srq->common.res == MLX5_RES_XSRQ)
+ switch (srq->common.res) {
+ case MLX5_RES_XSRQ:
return create_xrc_srq_cmd(dev, srq, in);
- else
+ case MLX5_RES_XRQ:
+ return create_xrq_cmd(dev, srq, in);
+ default:
return create_rmp_cmd(dev, srq, in);
+ }
}
static int destroy_srq_split(struct mlx5_core_dev *dev,
@@ -452,10 +564,14 @@ static int destroy_srq_split(struct mlx5_core_dev *dev,
{
if (!dev->issi)
return destroy_srq_cmd(dev, srq);
- else if (srq->common.res == MLX5_RES_XSRQ)
+ switch (srq->common.res) {
+ case MLX5_RES_XSRQ:
return destroy_xrc_srq_cmd(dev, srq);
- else
+ case MLX5_RES_XRQ:
+ return destroy_xrq_cmd(dev, srq);
+ default:
return destroy_rmp_cmd(dev, srq);
+ }
}
int mlx5_core_create_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq,
@@ -464,10 +580,16 @@ int mlx5_core_create_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq,
int err;
struct mlx5_srq_table *table = &dev->priv.srq_table;
- if (in->type == IB_SRQT_XRC)
+ switch (in->type) {
+ case IB_SRQT_XRC:
srq->common.res = MLX5_RES_XSRQ;
- else
+ break;
+ case IB_SRQT_TM:
+ srq->common.res = MLX5_RES_XRQ;
+ break;
+ default:
srq->common.res = MLX5_RES_SRQ;
+ }
err = create_srq_split(dev, srq, in);
if (err)
@@ -528,10 +650,14 @@ int mlx5_core_query_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq,
{
if (!dev->issi)
return query_srq_cmd(dev, srq, out);
- else if (srq->common.res == MLX5_RES_XSRQ)
+ switch (srq->common.res) {
+ case MLX5_RES_XSRQ:
return query_xrc_srq_cmd(dev, srq, out);
- else
+ case MLX5_RES_XRQ:
+ return query_xrq_cmd(dev, srq, out);
+ default:
return query_rmp_cmd(dev, srq, out);
+ }
}
EXPORT_SYMBOL(mlx5_core_query_srq);
@@ -540,10 +666,14 @@ int mlx5_core_arm_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq,
{
if (!dev->issi)
return arm_srq_cmd(dev, srq, lwm, is_srq);
- else if (srq->common.res == MLX5_RES_XSRQ)
+ switch (srq->common.res) {
+ case MLX5_RES_XSRQ:
return arm_xrc_srq_cmd(dev, srq, lwm);
- else
+ case MLX5_RES_XRQ:
+ return arm_xrq_cmd(dev, srq, lwm);
+ default:
return arm_rmp_cmd(dev, srq, lwm);
+ }
}
EXPORT_SYMBOL(mlx5_core_arm_srq);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vport.c b/drivers/net/ethernet/mellanox/mlx5/core/vport.c
index 5abfec1..d653b00 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/vport.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/vport.c
@@ -897,6 +897,68 @@ int mlx5_modify_nic_vport_promisc(struct mlx5_core_dev *mdev,
}
EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_promisc);
+enum {
+ UC_LOCAL_LB,
+ MC_LOCAL_LB
+};
+
+int mlx5_nic_vport_update_local_lb(struct mlx5_core_dev *mdev, bool enable)
+{
+ int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
+ void *in;
+ int err;
+
+ mlx5_core_dbg(mdev, "%s local_lb\n", enable ? "enable" : "disable");
+ in = kvzalloc(inlen, GFP_KERNEL);
+ if (!in)
+ return -ENOMEM;
+
+ MLX5_SET(modify_nic_vport_context_in, in,
+ field_select.disable_mc_local_lb, 1);
+ MLX5_SET(modify_nic_vport_context_in, in,
+ nic_vport_context.disable_mc_local_lb, !enable);
+
+ MLX5_SET(modify_nic_vport_context_in, in,
+ field_select.disable_uc_local_lb, 1);
+ MLX5_SET(modify_nic_vport_context_in, in,
+ nic_vport_context.disable_uc_local_lb, !enable);
+
+ err = mlx5_modify_nic_vport_context(mdev, in, inlen);
+
+ kvfree(in);
+ return err;
+}
+EXPORT_SYMBOL_GPL(mlx5_nic_vport_update_local_lb);
+
+int mlx5_nic_vport_query_local_lb(struct mlx5_core_dev *mdev, bool *status)
+{
+ int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
+ u32 *out;
+ int value;
+ int err;
+
+ out = kzalloc(outlen, GFP_KERNEL);
+ if (!out)
+ return -ENOMEM;
+
+ err = mlx5_query_nic_vport_context(mdev, 0, out, outlen);
+ if (err)
+ goto out;
+
+ value = MLX5_GET(query_nic_vport_context_out, out,
+ nic_vport_context.disable_mc_local_lb) << MC_LOCAL_LB;
+
+ value |= MLX5_GET(query_nic_vport_context_out, out,
+ nic_vport_context.disable_uc_local_lb) << UC_LOCAL_LB;
+
+ *status = !value;
+
+out:
+ kfree(out);
+ return err;
+}
+EXPORT_SYMBOL_GPL(mlx5_nic_vport_query_local_lb);
+
enum mlx5_vport_roce_state {
MLX5_VPORT_ROCE_DISABLED = 0,
MLX5_VPORT_ROCE_ENABLED = 1,
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 60bf8f2..c6a3e61b 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -4139,6 +4139,8 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev,
return -EINVAL;
if (!info->linking)
break;
+ if (netdev_has_any_upper_dev(upper_dev))
+ return -EINVAL;
if (netif_is_lag_master(upper_dev) &&
!mlxsw_sp_master_lag_check(mlxsw_sp, upper_dev,
info->upper_info))
@@ -4258,6 +4260,10 @@ static int mlxsw_sp_netdevice_port_vlan_event(struct net_device *vlan_dev,
upper_dev = info->upper_dev;
if (!netif_is_bridge_master(upper_dev))
return -EINVAL;
+ if (!info->linking)
+ break;
+ if (netdev_has_any_upper_dev(upper_dev))
+ return -EINVAL;
break;
case NETDEV_CHANGEUPPER:
upper_dev = info->upper_dev;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index 5eb1606..d39ffbf 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -705,6 +705,7 @@ static int mlxsw_sp_port_attr_mc_router_set(struct mlxsw_sp_port *mlxsw_sp_port,
bool is_port_mc_router)
{
struct mlxsw_sp_bridge_port *bridge_port;
+ int err;
if (switchdev_trans_ph_prepare(trans))
return 0;
@@ -715,11 +716,17 @@ static int mlxsw_sp_port_attr_mc_router_set(struct mlxsw_sp_port *mlxsw_sp_port,
return 0;
if (!bridge_port->bridge_device->multicast_enabled)
- return 0;
+ goto out;
- return mlxsw_sp_bridge_port_flood_table_set(mlxsw_sp_port, bridge_port,
- MLXSW_SP_FLOOD_TYPE_MC,
- is_port_mc_router);
+ err = mlxsw_sp_bridge_port_flood_table_set(mlxsw_sp_port, bridge_port,
+ MLXSW_SP_FLOOD_TYPE_MC,
+ is_port_mc_router);
+ if (err)
+ return err;
+
+out:
+ bridge_port->mrouter = is_port_mc_router;
+ return 0;
}
static int mlxsw_sp_port_mc_disabled_set(struct mlxsw_sp_port *mlxsw_sp_port,
diff --git a/drivers/net/ethernet/netronome/nfp/flower/match.c b/drivers/net/ethernet/netronome/nfp/flower/match.c
index 0e08404..d25b503 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/match.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/match.c
@@ -42,33 +42,29 @@ nfp_flower_compile_meta_tci(struct nfp_flower_meta_two *frame,
struct tc_cls_flower_offload *flow, u8 key_type,
bool mask_version)
{
+ struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
struct flow_dissector_key_vlan *flow_vlan;
u16 tmp_tci;
+ memset(frame, 0, sizeof(struct nfp_flower_meta_two));
/* Populate the metadata frame. */
frame->nfp_flow_key_layer = key_type;
frame->mask_id = ~0;
- if (mask_version) {
- frame->tci = cpu_to_be16(~0);
- return;
- }
-
- flow_vlan = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_VLAN,
- flow->key);
-
- /* Populate the tci field. */
- if (!flow_vlan->vlan_id) {
- tmp_tci = 0;
- } else {
- tmp_tci = FIELD_PREP(NFP_FLOWER_MASK_VLAN_PRIO,
- flow_vlan->vlan_priority) |
- FIELD_PREP(NFP_FLOWER_MASK_VLAN_VID,
- flow_vlan->vlan_id) |
- NFP_FLOWER_MASK_VLAN_CFI;
+ if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_VLAN)) {
+ flow_vlan = skb_flow_dissector_target(flow->dissector,
+ FLOW_DISSECTOR_KEY_VLAN,
+ target);
+ /* Populate the tci field. */
+ if (flow_vlan->vlan_id) {
+ tmp_tci = FIELD_PREP(NFP_FLOWER_MASK_VLAN_PRIO,
+ flow_vlan->vlan_priority) |
+ FIELD_PREP(NFP_FLOWER_MASK_VLAN_VID,
+ flow_vlan->vlan_id) |
+ NFP_FLOWER_MASK_VLAN_CFI;
+ frame->tci = cpu_to_be16(tmp_tci);
+ }
}
- frame->tci = cpu_to_be16(tmp_tci);
}
static void
@@ -99,17 +95,18 @@ nfp_flower_compile_mac(struct nfp_flower_mac_mpls *frame,
bool mask_version)
{
struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
- struct flow_dissector_key_eth_addrs *flow_mac;
-
- flow_mac = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_ETH_ADDRS,
- target);
+ struct flow_dissector_key_eth_addrs *addr;
memset(frame, 0, sizeof(struct nfp_flower_mac_mpls));
- /* Populate mac frame. */
- ether_addr_copy(frame->mac_dst, &flow_mac->dst[0]);
- ether_addr_copy(frame->mac_src, &flow_mac->src[0]);
+ if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
+ addr = skb_flow_dissector_target(flow->dissector,
+ FLOW_DISSECTOR_KEY_ETH_ADDRS,
+ target);
+ /* Populate mac frame. */
+ ether_addr_copy(frame->mac_dst, &addr->dst[0]);
+ ether_addr_copy(frame->mac_src, &addr->src[0]);
+ }
if (mask_version)
frame->mpls_lse = cpu_to_be32(~0);
@@ -121,14 +118,17 @@ nfp_flower_compile_tport(struct nfp_flower_tp_ports *frame,
bool mask_version)
{
struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
- struct flow_dissector_key_ports *flow_tp;
+ struct flow_dissector_key_ports *tp;
- flow_tp = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_PORTS,
- target);
+ memset(frame, 0, sizeof(struct nfp_flower_tp_ports));
- frame->port_src = flow_tp->src;
- frame->port_dst = flow_tp->dst;
+ if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_PORTS)) {
+ tp = skb_flow_dissector_target(flow->dissector,
+ FLOW_DISSECTOR_KEY_PORTS,
+ target);
+ frame->port_src = tp->src;
+ frame->port_dst = tp->dst;
+ }
}
static void
@@ -137,25 +137,27 @@ nfp_flower_compile_ipv4(struct nfp_flower_ipv4 *frame,
bool mask_version)
{
struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
- struct flow_dissector_key_ipv4_addrs *flow_ipv4;
- struct flow_dissector_key_basic *flow_basic;
-
- flow_ipv4 = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_IPV4_ADDRS,
- target);
-
- flow_basic = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_BASIC,
- target);
+ struct flow_dissector_key_ipv4_addrs *addr;
+ struct flow_dissector_key_basic *basic;
- /* Populate IPv4 frame. */
- frame->reserved = 0;
- frame->ipv4_src = flow_ipv4->src;
- frame->ipv4_dst = flow_ipv4->dst;
- frame->proto = flow_basic->ip_proto;
/* Wildcard TOS/TTL for now. */
- frame->tos = 0;
- frame->ttl = 0;
+ memset(frame, 0, sizeof(struct nfp_flower_ipv4));
+
+ if (dissector_uses_key(flow->dissector,
+ FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
+ addr = skb_flow_dissector_target(flow->dissector,
+ FLOW_DISSECTOR_KEY_IPV4_ADDRS,
+ target);
+ frame->ipv4_src = addr->src;
+ frame->ipv4_dst = addr->dst;
+ }
+
+ if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
+ basic = skb_flow_dissector_target(flow->dissector,
+ FLOW_DISSECTOR_KEY_BASIC,
+ target);
+ frame->proto = basic->ip_proto;
+ }
}
static void
@@ -164,26 +166,27 @@ nfp_flower_compile_ipv6(struct nfp_flower_ipv6 *frame,
bool mask_version)
{
struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
- struct flow_dissector_key_ipv6_addrs *flow_ipv6;
- struct flow_dissector_key_basic *flow_basic;
-
- flow_ipv6 = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_IPV6_ADDRS,
- target);
+ struct flow_dissector_key_ipv6_addrs *addr;
+ struct flow_dissector_key_basic *basic;
- flow_basic = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_BASIC,
- target);
-
- /* Populate IPv6 frame. */
- frame->reserved = 0;
- frame->ipv6_src = flow_ipv6->src;
- frame->ipv6_dst = flow_ipv6->dst;
- frame->proto = flow_basic->ip_proto;
/* Wildcard LABEL/TOS/TTL for now. */
- frame->ipv6_flow_label_exthdr = 0;
- frame->tos = 0;
- frame->ttl = 0;
+ memset(frame, 0, sizeof(struct nfp_flower_ipv6));
+
+ if (dissector_uses_key(flow->dissector,
+ FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
+ addr = skb_flow_dissector_target(flow->dissector,
+ FLOW_DISSECTOR_KEY_IPV6_ADDRS,
+ target);
+ frame->ipv6_src = addr->src;
+ frame->ipv6_dst = addr->dst;
+ }
+
+ if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
+ basic = skb_flow_dissector_target(flow->dissector,
+ FLOW_DISSECTOR_KEY_BASIC,
+ target);
+ frame->proto = basic->ip_proto;
+ }
}
int nfp_flower_compile_flow_match(struct tc_cls_flower_offload *flow,
diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c
index 4ad10bd..74a96d6 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/offload.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c
@@ -105,43 +105,62 @@ static int
nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls,
struct tc_cls_flower_offload *flow)
{
- struct flow_dissector_key_control *mask_enc_ctl;
- struct flow_dissector_key_basic *mask_basic;
- struct flow_dissector_key_basic *key_basic;
+ struct flow_dissector_key_basic *mask_basic = NULL;
+ struct flow_dissector_key_basic *key_basic = NULL;
+ struct flow_dissector_key_ip *mask_ip = NULL;
u32 key_layer_two;
u8 key_layer;
int key_size;
- mask_enc_ctl = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_ENC_CONTROL,
- flow->mask);
+ if (dissector_uses_key(flow->dissector,
+ FLOW_DISSECTOR_KEY_ENC_CONTROL)) {
+ struct flow_dissector_key_control *mask_enc_ctl =
+ skb_flow_dissector_target(flow->dissector,
+ FLOW_DISSECTOR_KEY_ENC_CONTROL,
+ flow->mask);
+ /* We are expecting a tunnel. For now we ignore offloading. */
+ if (mask_enc_ctl->addr_type)
+ return -EOPNOTSUPP;
+ }
- mask_basic = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_BASIC,
- flow->mask);
+ if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
+ mask_basic = skb_flow_dissector_target(flow->dissector,
+ FLOW_DISSECTOR_KEY_BASIC,
+ flow->mask);
+
+ key_basic = skb_flow_dissector_target(flow->dissector,
+ FLOW_DISSECTOR_KEY_BASIC,
+ flow->key);
+ }
+
+ if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_IP))
+ mask_ip = skb_flow_dissector_target(flow->dissector,
+ FLOW_DISSECTOR_KEY_IP,
+ flow->mask);
- key_basic = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_BASIC,
- flow->key);
key_layer_two = 0;
key_layer = NFP_FLOWER_LAYER_PORT | NFP_FLOWER_LAYER_MAC;
key_size = sizeof(struct nfp_flower_meta_one) +
sizeof(struct nfp_flower_in_port) +
sizeof(struct nfp_flower_mac_mpls);
- /* We are expecting a tunnel. For now we ignore offloading. */
- if (mask_enc_ctl->addr_type)
- return -EOPNOTSUPP;
-
- if (mask_basic->n_proto) {
+ if (mask_basic && mask_basic->n_proto) {
/* Ethernet type is present in the key. */
switch (key_basic->n_proto) {
case cpu_to_be16(ETH_P_IP):
+ if (mask_ip && mask_ip->tos)
+ return -EOPNOTSUPP;
+ if (mask_ip && mask_ip->ttl)
+ return -EOPNOTSUPP;
key_layer |= NFP_FLOWER_LAYER_IPV4;
key_size += sizeof(struct nfp_flower_ipv4);
break;
case cpu_to_be16(ETH_P_IPV6):
+ if (mask_ip && mask_ip->tos)
+ return -EOPNOTSUPP;
+ if (mask_ip && mask_ip->ttl)
+ return -EOPNOTSUPP;
key_layer |= NFP_FLOWER_LAYER_IPV6;
key_size += sizeof(struct nfp_flower_ipv6);
break;
@@ -152,6 +171,11 @@ nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls,
case cpu_to_be16(ETH_P_ARP):
return -EOPNOTSUPP;
+ /* Currently we do not offload MPLS. */
+ case cpu_to_be16(ETH_P_MPLS_UC):
+ case cpu_to_be16(ETH_P_MPLS_MC):
+ return -EOPNOTSUPP;
+
/* Will be included in layer 2. */
case cpu_to_be16(ETH_P_8021Q):
break;
@@ -166,7 +190,7 @@ nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls,
}
}
- if (mask_basic->ip_proto) {
+ if (mask_basic && mask_basic->ip_proto) {
/* Ethernet type is present in the key. */
switch (key_basic->ip_proto) {
case IPPROTO_TCP:
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.c b/drivers/net/ethernet/netronome/nfp/nfp_main.c
index d67969d..3f199db 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_main.c
@@ -98,21 +98,20 @@ static int nfp_pcie_sriov_enable(struct pci_dev *pdev, int num_vfs)
struct nfp_pf *pf = pci_get_drvdata(pdev);
int err;
- mutex_lock(&pf->lock);
-
if (num_vfs > pf->limit_vfs) {
nfp_info(pf->cpp, "Firmware limits number of VFs to %u\n",
pf->limit_vfs);
- err = -EINVAL;
- goto err_unlock;
+ return -EINVAL;
}
err = pci_enable_sriov(pdev, num_vfs);
if (err) {
dev_warn(&pdev->dev, "Failed to enable PCI SR-IOV: %d\n", err);
- goto err_unlock;
+ return err;
}
+ mutex_lock(&pf->lock);
+
err = nfp_app_sriov_enable(pf->app, num_vfs);
if (err) {
dev_warn(&pdev->dev,
@@ -129,9 +128,8 @@ static int nfp_pcie_sriov_enable(struct pci_dev *pdev, int num_vfs)
return num_vfs;
err_sriov_disable:
- pci_disable_sriov(pdev);
-err_unlock:
mutex_unlock(&pf->lock);
+ pci_disable_sriov(pdev);
return err;
#endif
return 0;
@@ -158,10 +156,10 @@ static int nfp_pcie_sriov_disable(struct pci_dev *pdev)
pf->num_vfs = 0;
+ mutex_unlock(&pf->lock);
+
pci_disable_sriov(pdev);
dev_dbg(&pdev->dev, "Removed VFs.\n");
-
- mutex_unlock(&pf->lock);
#endif
return 0;
}
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index 9f77ce0..66a09e4 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -895,6 +895,8 @@ static int nfp_net_tx(struct sk_buff *skb, struct net_device *netdev)
netdev_tx_sent_queue(nd_q, txbuf->real_len);
+ skb_tx_timestamp(skb);
+
tx_ring->wr_p += nr_frags + 1;
if (nfp_net_tx_ring_should_stop(tx_ring))
nfp_net_tx_ring_stop(nd_q, tx_ring);
@@ -903,8 +905,6 @@ static int nfp_net_tx(struct sk_buff *skb, struct net_device *netdev)
if (!skb->xmit_more || netif_xmit_stopped(nd_q))
nfp_net_tx_xmit_more_flush(tx_ring);
- skb_tx_timestamp(skb);
-
return NETDEV_TX_OK;
err_unmap:
@@ -1751,6 +1751,10 @@ static int nfp_net_rx(struct nfp_net_rx_ring *rx_ring, int budget)
continue;
}
+ nfp_net_dma_unmap_rx(dp, rxbuf->dma_addr);
+
+ nfp_net_rx_give_one(dp, rx_ring, new_frag, new_dma_addr);
+
if (likely(!meta.portid)) {
netdev = dp->netdev;
} else {
@@ -1759,16 +1763,12 @@ static int nfp_net_rx(struct nfp_net_rx_ring *rx_ring, int budget)
nn = netdev_priv(dp->netdev);
netdev = nfp_app_repr_get(nn->app, meta.portid);
if (unlikely(!netdev)) {
- nfp_net_rx_drop(dp, r_vec, rx_ring, rxbuf, skb);
+ nfp_net_rx_drop(dp, r_vec, rx_ring, NULL, skb);
continue;
}
nfp_repr_inc_rx_stats(netdev, pkt_len);
}
- nfp_net_dma_unmap_rx(dp, rxbuf->dma_addr);
-
- nfp_net_rx_give_one(dp, rx_ring, new_frag, new_dma_addr);
-
skb_reserve(skb, pkt_off);
skb_put(skb, pkt_len);
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
index 5797dbf..34b9853 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
@@ -456,13 +456,9 @@ static int nfp_net_pf_app_start(struct nfp_pf *pf)
{
int err;
- err = nfp_net_pf_app_start_ctrl(pf);
- if (err)
- return err;
-
err = nfp_app_start(pf->app, pf->ctrl_vnic);
if (err)
- goto err_ctrl_stop;
+ return err;
if (pf->num_vfs) {
err = nfp_app_sriov_enable(pf->app, pf->num_vfs);
@@ -474,8 +470,6 @@ static int nfp_net_pf_app_start(struct nfp_pf *pf)
err_app_stop:
nfp_app_stop(pf->app);
-err_ctrl_stop:
- nfp_net_pf_app_stop_ctrl(pf);
return err;
}
@@ -484,7 +478,6 @@ static void nfp_net_pf_app_stop(struct nfp_pf *pf)
if (pf->num_vfs)
nfp_app_sriov_disable(pf->app);
nfp_app_stop(pf->app);
- nfp_net_pf_app_stop_ctrl(pf);
}
static void nfp_net_pci_unmap_mem(struct nfp_pf *pf)
@@ -559,7 +552,7 @@ err_unmap_ctrl:
static void nfp_net_pci_remove_finish(struct nfp_pf *pf)
{
- nfp_net_pf_app_stop(pf);
+ nfp_net_pf_app_stop_ctrl(pf);
/* stop app first, to avoid double free of ctrl vNIC's ddir */
nfp_net_debugfs_dir_clean(&pf->ddir);
@@ -690,6 +683,7 @@ int nfp_net_pci_probe(struct nfp_pf *pf)
{
struct nfp_net_fw_version fw_ver;
u8 __iomem *ctrl_bar, *qc_bar;
+ struct nfp_net *nn;
int stride;
int err;
@@ -766,7 +760,7 @@ int nfp_net_pci_probe(struct nfp_pf *pf)
if (err)
goto err_free_vnics;
- err = nfp_net_pf_app_start(pf);
+ err = nfp_net_pf_app_start_ctrl(pf);
if (err)
goto err_free_irqs;
@@ -774,12 +768,20 @@ int nfp_net_pci_probe(struct nfp_pf *pf)
if (err)
goto err_stop_app;
+ err = nfp_net_pf_app_start(pf);
+ if (err)
+ goto err_clean_vnics;
+
mutex_unlock(&pf->lock);
return 0;
+err_clean_vnics:
+ list_for_each_entry(nn, &pf->vnics, vnic_list)
+ if (nfp_net_is_data_vnic(nn))
+ nfp_net_pf_clean_vnic(pf, nn);
err_stop_app:
- nfp_net_pf_app_stop(pf);
+ nfp_net_pf_app_stop_ctrl(pf);
err_free_irqs:
nfp_net_pf_free_irqs(pf);
err_free_vnics:
@@ -803,6 +805,8 @@ void nfp_net_pci_remove(struct nfp_pf *pf)
if (list_empty(&pf->vnics))
goto out;
+ nfp_net_pf_app_stop(pf);
+
list_for_each_entry(nn, &pf->vnics, vnic_list)
if (nfp_net_is_data_vnic(nn))
nfp_net_pf_clean_vnic(pf, nn);
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c
index 28ea0af..e3223f2 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/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index bd07a15..e03fcf9 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -6863,8 +6863,7 @@ static void rtl8169_tx_clear_range(struct rtl8169_private *tp, u32 start,
rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb,
tp->TxDescArray + entry);
if (skb) {
- tp->dev->stats.tx_dropped++;
- dev_kfree_skb_any(skb);
+ dev_consume_skb_any(skb);
tx_skb->skb = NULL;
}
}
@@ -7319,7 +7318,7 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp)
tp->tx_stats.packets++;
tp->tx_stats.bytes += tx_skb->skb->len;
u64_stats_update_end(&tp->tx_stats.syncp);
- dev_kfree_skb_any(tx_skb->skb);
+ dev_consume_skb_any(tx_skb->skb);
tx_skb->skb = NULL;
}
dirty_tx++;
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c
index 73427e2..fbd00cb 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c
@@ -47,6 +47,8 @@ static int sxgbe_probe_config_dt(struct platform_device *pdev,
plat->mdio_bus_data = devm_kzalloc(&pdev->dev,
sizeof(*plat->mdio_bus_data),
GFP_KERNEL);
+ if (!plat->mdio_bus_data)
+ return -ENOMEM;
dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg), GFP_KERNEL);
if (!dma_cfg)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
index 17d4bba..6e35957 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -269,7 +269,10 @@ static int socfpga_dwmac_set_phy_mode(struct socfpga_dwmac *dwmac)
ctrl &= ~(SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << reg_shift);
ctrl |= val << reg_shift;
- if (dwmac->f2h_ptp_ref_clk) {
+ if (dwmac->f2h_ptp_ref_clk ||
+ phymode == PHY_INTERFACE_MODE_MII ||
+ phymode == PHY_INTERFACE_MODE_GMII ||
+ phymode == PHY_INTERFACE_MODE_SGMII) {
ctrl |= SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK << (reg_shift / 2);
regmap_read(sys_mgr_base_addr, SYSMGR_FPGAGRP_MODULE_REG,
&module);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index fffd6d5..39c2122 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -979,14 +979,6 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
}
static const struct of_device_id sun8i_dwmac_match[] = {
- { .compatible = "allwinner,sun8i-h3-emac",
- .data = &emac_variant_h3 },
- { .compatible = "allwinner,sun8i-v3s-emac",
- .data = &emac_variant_v3s },
- { .compatible = "allwinner,sun8i-a83t-emac",
- .data = &emac_variant_a83t },
- { .compatible = "allwinner,sun50i-a64-emac",
- .data = &emac_variant_a64 },
{ }
};
MODULE_DEVICE_TABLE(of, sun8i_dwmac_match);
diff --git a/drivers/net/ethernet/ti/cpsw-common.c b/drivers/net/ethernet/ti/cpsw-common.c
index 56ba411..38d1cc5 100644
--- a/drivers/net/ethernet/ti/cpsw-common.c
+++ b/drivers/net/ethernet/ti/cpsw-common.c
@@ -96,7 +96,7 @@ int ti_cm_get_macid(struct device *dev, int slave, u8 *mac_addr)
if (of_machine_is_compatible("ti,dra7"))
return davinci_emac_3517_get_macid(dev, 0x514, slave, mac_addr);
- dev_err(dev, "incompatible machine/device type for reading mac address\n");
+ dev_info(dev, "incompatible machine/device type for reading mac address\n");
return -ENOENT;
}
EXPORT_SYMBOL_GPL(ti_cm_get_macid);
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 0d78727..d91cbc6 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -1269,7 +1269,12 @@ static void netvsc_link_change(struct work_struct *w)
bool notify = false, reschedule = false;
unsigned long flags, next_reconfig, delay;
- rtnl_lock();
+ /* if changes are happening, comeback later */
+ if (!rtnl_trylock()) {
+ schedule_delayed_work(&ndev_ctx->dwork, LINKCHANGE_INT);
+ return;
+ }
+
net_device = rtnl_dereference(ndev_ctx->nvdev);
if (!net_device)
goto out_unlock;
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
index 5e1ab11..98e4dea 100644
--- a/drivers/net/macsec.c
+++ b/drivers/net/macsec.c
@@ -3521,6 +3521,7 @@ module_init(macsec_init);
module_exit(macsec_exit);
MODULE_ALIAS_RTNL_LINK("macsec");
+MODULE_ALIAS_GENL_FAMILY("macsec");
MODULE_DESCRIPTION("MACsec IEEE 802.1AE");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 5068c58..d0626bf 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -749,9 +749,6 @@ void phy_stop_machine(struct phy_device *phydev)
if (phydev->state > PHY_UP && phydev->state != PHY_HALTED)
phydev->state = PHY_UP;
mutex_unlock(&phydev->lock);
-
- /* Now we can run the state machine synchronously */
- phy_state_machine(&phydev->state_queue.work);
}
/**
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 1790f7f..2f742ae 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -864,15 +864,17 @@ EXPORT_SYMBOL(phy_attached_info);
#define ATTACHED_FMT "attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)"
void phy_attached_print(struct phy_device *phydev, const char *fmt, ...)
{
+ const char *drv_name = phydev->drv ? phydev->drv->name : "unbound";
+
if (!fmt) {
dev_info(&phydev->mdio.dev, ATTACHED_FMT "\n",
- phydev->drv->name, phydev_name(phydev),
+ drv_name, phydev_name(phydev),
phydev->irq);
} else {
va_list ap;
dev_info(&phydev->mdio.dev, ATTACHED_FMT,
- phydev->drv->name, phydev_name(phydev),
+ drv_name, phydev_name(phydev),
phydev->irq);
va_start(ap, fmt);
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 8f572b9..9c80e80 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -1758,6 +1758,13 @@ static const struct usb_device_id cdc_devs[] = {
.driver_info = (unsigned long)&wwan_noarp_info,
},
+ /* u-blox TOBY-L4 */
+ { USB_DEVICE_AND_INTERFACE_INFO(0x1546, 0x1010,
+ USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long)&wwan_info,
+ },
+
/* Generic CDC-NCM devices */
{ USB_INTERFACE_INFO(USB_CLASS_COMM,
USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 98f17b0..b06169e 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1058,7 +1058,7 @@ static void free_old_xmit_skbs(struct send_queue *sq)
bytes += skb->len;
packets++;
- dev_kfree_skb_any(skb);
+ dev_consume_skb_any(skb);
}
/* Avoid overhead when no packets have been processed
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
index fa315d8..a1ea9ef 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
@@ -787,6 +787,8 @@ int iwl_pci_fw_enter_d0i3(struct iwl_trans *trans);
void iwl_pcie_enable_rx_wake(struct iwl_trans *trans, bool enable);
+void iwl_pcie_rx_allocator_work(struct work_struct *data);
+
/* common functions that are used by gen2 transport */
void iwl_pcie_apm_config(struct iwl_trans *trans);
int iwl_pcie_prepare_card_hw(struct iwl_trans *trans);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index 351c442..942736d 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -597,7 +597,7 @@ static void iwl_pcie_rx_allocator_get(struct iwl_trans *trans,
rxq->free_count += RX_CLAIM_REQ_ALLOC;
}
-static void iwl_pcie_rx_allocator_work(struct work_struct *data)
+void iwl_pcie_rx_allocator_work(struct work_struct *data)
{
struct iwl_rb_allocator *rba_p =
container_of(data, struct iwl_rb_allocator, rx_alloc);
@@ -900,10 +900,6 @@ static int _iwl_pcie_rx_init(struct iwl_trans *trans)
return err;
}
def_rxq = trans_pcie->rxq;
- if (!rba->alloc_wq)
- rba->alloc_wq = alloc_workqueue("rb_allocator",
- WQ_HIGHPRI | WQ_UNBOUND, 1);
- INIT_WORK(&rba->rx_alloc, iwl_pcie_rx_allocator_work);
spin_lock(&rba->lock);
atomic_set(&rba->req_pending, 0);
@@ -1017,10 +1013,6 @@ void iwl_pcie_rx_free(struct iwl_trans *trans)
}
cancel_work_sync(&rba->rx_alloc);
- if (rba->alloc_wq) {
- destroy_workqueue(rba->alloc_wq);
- rba->alloc_wq = NULL;
- }
iwl_pcie_free_rbs_pool(trans);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index f95eec5..3927bbf 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -1786,6 +1786,11 @@ void iwl_trans_pcie_free(struct iwl_trans *trans)
iwl_pcie_tx_free(trans);
iwl_pcie_rx_free(trans);
+ if (trans_pcie->rba.alloc_wq) {
+ destroy_workqueue(trans_pcie->rba.alloc_wq);
+ trans_pcie->rba.alloc_wq = NULL;
+ }
+
if (trans_pcie->msix_enabled) {
for (i = 0; i < trans_pcie->alloc_vecs; i++) {
irq_set_affinity_hint(
@@ -3169,6 +3174,10 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
trans_pcie->inta_mask = CSR_INI_SET_MASK;
}
+ trans_pcie->rba.alloc_wq = alloc_workqueue("rb_allocator",
+ WQ_HIGHPRI | WQ_UNBOUND, 1);
+ INIT_WORK(&trans_pcie->rba.rx_alloc, iwl_pcie_rx_allocator_work);
+
#ifdef CONFIG_IWLWIFI_PCIE_RTPM
trans->runtime_pm_mode = IWL_PLAT_PM_MODE_D0I3;
#else
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c
index 08f0477..9915d83 100644
--- a/drivers/net/wireless/ti/wl1251/main.c
+++ b/drivers/net/wireless/ti/wl1251/main.c
@@ -1571,6 +1571,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void)
wl->state = WL1251_STATE_OFF;
mutex_init(&wl->mutex);
+ spin_lock_init(&wl->wl_lock);
wl->tx_mgmt_frm_rate = DEFAULT_HW_GEN_TX_RATE;
wl->tx_mgmt_frm_mod = DEFAULT_HW_GEN_MODULATION_TYPE;
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 925467b..ea892e7 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -109,6 +109,7 @@ struct nvme_dev {
/* host memory buffer support: */
u64 host_mem_size;
u32 nr_host_mem_descs;
+ dma_addr_t host_mem_descs_dma;
struct nvme_host_mem_buf_desc *host_mem_descs;
void **host_mem_desc_bufs;
};
@@ -1565,16 +1566,10 @@ static inline void nvme_release_cmb(struct nvme_dev *dev)
static int nvme_set_host_mem(struct nvme_dev *dev, u32 bits)
{
- size_t len = dev->nr_host_mem_descs * sizeof(*dev->host_mem_descs);
+ u64 dma_addr = dev->host_mem_descs_dma;
struct nvme_command c;
- u64 dma_addr;
int ret;
- dma_addr = dma_map_single(dev->dev, dev->host_mem_descs, len,
- DMA_TO_DEVICE);
- if (dma_mapping_error(dev->dev, dma_addr))
- return -ENOMEM;
-
memset(&c, 0, sizeof(c));
c.features.opcode = nvme_admin_set_features;
c.features.fid = cpu_to_le32(NVME_FEAT_HOST_MEM_BUF);
@@ -1591,7 +1586,6 @@ static int nvme_set_host_mem(struct nvme_dev *dev, u32 bits)
"failed to set host mem (err %d, flags %#x).\n",
ret, bits);
}
- dma_unmap_single(dev->dev, dma_addr, len, DMA_TO_DEVICE);
return ret;
}
@@ -1609,7 +1603,9 @@ static void nvme_free_host_mem(struct nvme_dev *dev)
kfree(dev->host_mem_desc_bufs);
dev->host_mem_desc_bufs = NULL;
- kfree(dev->host_mem_descs);
+ dma_free_coherent(dev->dev,
+ dev->nr_host_mem_descs * sizeof(*dev->host_mem_descs),
+ dev->host_mem_descs, dev->host_mem_descs_dma);
dev->host_mem_descs = NULL;
}
@@ -1617,6 +1613,7 @@ static int nvme_alloc_host_mem(struct nvme_dev *dev, u64 min, u64 preferred)
{
struct nvme_host_mem_buf_desc *descs;
u32 chunk_size, max_entries, len;
+ dma_addr_t descs_dma;
int i = 0;
void **bufs;
u64 size = 0, tmp;
@@ -1627,7 +1624,8 @@ retry:
tmp = (preferred + chunk_size - 1);
do_div(tmp, chunk_size);
max_entries = tmp;
- descs = kcalloc(max_entries, sizeof(*descs), GFP_KERNEL);
+ descs = dma_zalloc_coherent(dev->dev, max_entries * sizeof(*descs),
+ &descs_dma, GFP_KERNEL);
if (!descs)
goto out;
@@ -1661,6 +1659,7 @@ retry:
dev->nr_host_mem_descs = i;
dev->host_mem_size = size;
dev->host_mem_descs = descs;
+ dev->host_mem_descs_dma = descs_dma;
dev->host_mem_desc_bufs = bufs;
return 0;
@@ -1674,7 +1673,8 @@ out_free_bufs:
kfree(bufs);
out_free_descs:
- kfree(descs);
+ dma_free_coherent(dev->dev, max_entries * sizeof(*descs), descs,
+ descs_dma);
out:
/* try a smaller chunk size if we failed early */
if (chunk_size >= PAGE_SIZE * 2 && (i == 0 || size < min)) {
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index da04df1..a7f7d0a 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -19,6 +19,7 @@
#include <linux/string.h>
#include <linux/atomic.h>
#include <linux/blk-mq.h>
+#include <linux/blk-mq-rdma.h>
#include <linux/types.h>
#include <linux/list.h>
#include <linux/mutex.h>
@@ -463,14 +464,10 @@ static int nvme_rdma_create_queue_ib(struct nvme_rdma_queue *queue)
ibdev = queue->device->dev;
/*
- * The admin queue is barely used once the controller is live, so don't
- * bother to spread it out.
+ * Spread I/O queues completion vectors according their queue index.
+ * Admin queues can always go on completion vector 0.
*/
- if (idx == 0)
- comp_vector = 0;
- else
- comp_vector = idx % ibdev->num_comp_vectors;
-
+ comp_vector = idx == 0 ? idx : idx - 1;
/* +1 for ib_stop_cq */
queue->ib_cq = ib_alloc_cq(ibdev, queue,
@@ -611,10 +608,20 @@ out_free_queues:
static int nvme_rdma_init_io_queues(struct nvme_rdma_ctrl *ctrl)
{
struct nvmf_ctrl_options *opts = ctrl->ctrl.opts;
+ struct ib_device *ibdev = ctrl->device->dev;
unsigned int nr_io_queues;
int i, ret;
nr_io_queues = min(opts->nr_io_queues, num_online_cpus());
+
+ /*
+ * we map queues according to the device irq vectors for
+ * optimal locality so we don't need more queues than
+ * completion vectors.
+ */
+ nr_io_queues = min_t(unsigned int, nr_io_queues,
+ ibdev->num_comp_vectors);
+
ret = nvme_set_queue_count(&ctrl->ctrl, &nr_io_queues);
if (ret)
return ret;
@@ -920,7 +927,11 @@ static int nvme_rdma_map_sg_fr(struct nvme_rdma_queue *queue,
struct nvme_keyed_sgl_desc *sg = &c->common.dptr.ksgl;
int nr;
- nr = ib_map_mr_sg(req->mr, req->sg_table.sgl, count, NULL, PAGE_SIZE);
+ /*
+ * Align the MR to a 4K page size to match the ctrl page size and
+ * the block virtual boundary.
+ */
+ nr = ib_map_mr_sg(req->mr, req->sg_table.sgl, count, NULL, SZ_4K);
if (nr < count) {
if (nr < 0)
return nr;
@@ -1498,6 +1509,13 @@ static void nvme_rdma_complete_rq(struct request *rq)
nvme_complete_rq(rq);
}
+static int nvme_rdma_map_queues(struct blk_mq_tag_set *set)
+{
+ struct nvme_rdma_ctrl *ctrl = set->driver_data;
+
+ return blk_mq_rdma_map_queues(set, ctrl->device->dev, 0);
+}
+
static const struct blk_mq_ops nvme_rdma_mq_ops = {
.queue_rq = nvme_rdma_queue_rq,
.complete = nvme_rdma_complete_rq,
@@ -1507,6 +1525,7 @@ static const struct blk_mq_ops nvme_rdma_mq_ops = {
.init_hctx = nvme_rdma_init_hctx,
.poll = nvme_rdma_poll,
.timeout = nvme_rdma_timeout,
+ .map_queues = nvme_rdma_map_queues,
};
static const struct blk_mq_ops nvme_rdma_admin_mq_ops = {
@@ -1583,7 +1602,7 @@ static int nvme_rdma_configure_admin_queue(struct nvme_rdma_ctrl *ctrl)
goto out_cleanup_queue;
ctrl->ctrl.max_hw_sectors =
- (ctrl->max_fr_pages - 1) << (PAGE_SHIFT - 9);
+ (ctrl->max_fr_pages - 1) << (ilog2(SZ_4K) - 9);
error = nvme_init_identify(&ctrl->ctrl);
if (error)
@@ -1946,10 +1965,6 @@ static struct nvmf_transport_ops nvme_rdma_transport = {
.create_ctrl = nvme_rdma_create_ctrl,
};
-static void nvme_rdma_add_one(struct ib_device *ib_device)
-{
-}
-
static void nvme_rdma_remove_one(struct ib_device *ib_device, void *client_data)
{
struct nvme_rdma_ctrl *ctrl;
@@ -1971,7 +1986,6 @@ static void nvme_rdma_remove_one(struct ib_device *ib_device, void *client_data)
static struct ib_client nvme_rdma_ib_client = {
.name = "nvme_rdma",
- .add = nvme_rdma_add_one,
.remove = nvme_rdma_remove_one
};
diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c
index 56a4cba..76d2bb7 100644
--- a/drivers/nvme/target/rdma.c
+++ b/drivers/nvme/target/rdma.c
@@ -1510,10 +1510,6 @@ static struct nvmet_fabrics_ops nvmet_rdma_ops = {
.delete_ctrl = nvmet_rdma_delete_ctrl,
};
-static void nvmet_rdma_add_one(struct ib_device *ib_device)
-{
-}
-
static void nvmet_rdma_remove_one(struct ib_device *ib_device, void *client_data)
{
struct nvmet_rdma_queue *queue;
@@ -1534,7 +1530,6 @@ static void nvmet_rdma_remove_one(struct ib_device *ib_device, void *client_data
static struct ib_client nvmet_rdma_ib_client = {
.name = "nvmet_rdma",
- .add = nvmet_rdma_add_one,
.remove = nvmet_rdma_remove_one
};
diff --git a/drivers/parisc/asp.c b/drivers/parisc/asp.c
index 6a1ab25..3163b67 100644
--- a/drivers/parisc/asp.c
+++ b/drivers/parisc/asp.c
@@ -118,12 +118,12 @@ static int __init asp_init_chip(struct parisc_device *dev)
return ret;
}
-static struct parisc_device_id asp_tbl[] = {
+static const struct parisc_device_id asp_tbl[] __initconst = {
{ HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00070 },
{ 0, }
};
-struct parisc_driver asp_driver = {
+struct parisc_driver asp_driver __refdata = {
.name = "asp",
.id_table = asp_tbl,
.probe = asp_init_chip,
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index 6aa1e7f..acba1f5 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -1241,7 +1241,7 @@ ccio_get_iotlb_size(struct parisc_device *dev)
#endif /* 0 */
/* We *can't* support JAVA (T600). Venture there at your own risk. */
-static const struct parisc_device_id ccio_tbl[] = {
+static const struct parisc_device_id ccio_tbl[] __initconst = {
{ HPHW_IOA, HVERSION_REV_ANY_ID, U2_IOA_RUNWAY, 0xb }, /* U2 */
{ HPHW_IOA, HVERSION_REV_ANY_ID, UTURN_IOA_RUNWAY, 0xb }, /* UTurn */
{ 0, }
@@ -1249,7 +1249,7 @@ static const struct parisc_device_id ccio_tbl[] = {
static int ccio_probe(struct parisc_device *dev);
-static struct parisc_driver ccio_driver = {
+static struct parisc_driver ccio_driver __refdata = {
.name = "ccio",
.id_table = ccio_tbl,
.probe = ccio_probe,
diff --git a/drivers/parisc/ccio-rm-dma.c b/drivers/parisc/ccio-rm-dma.c
index 1bf9880..df7932a 100644
--- a/drivers/parisc/ccio-rm-dma.c
+++ b/drivers/parisc/ccio-rm-dma.c
@@ -163,7 +163,7 @@ static struct pci_dma_ops ccio_ops = {
** If so, initialize the chip and tell other partners in crime they
** have work to do.
*/
-static int
+static int __init
ccio_probe(struct parisc_device *dev)
{
printk(KERN_INFO "%s found %s at 0x%lx\n", MODULE_NAME,
@@ -184,13 +184,13 @@ ccio_probe(struct parisc_device *dev)
return 0;
}
-static struct parisc_device_id ccio_tbl[] = {
+static const struct parisc_device_id ccio_tbl[] __initconst = {
{ HPHW_BCPORT, HVERSION_REV_ANY_ID, U2_BC_GSC, 0xc },
{ HPHW_BCPORT, HVERSION_REV_ANY_ID, UTURN_BC_GSC, 0xc },
{ 0, }
};
-static struct parisc_driver ccio_driver = {
+static struct parisc_driver ccio_driver __refdata = {
.name = "U2/Uturn",
.id_table = ccio_tbl,
.probe = ccio_probe,
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index ed92c12..0b3fb99 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -1022,7 +1022,7 @@ static int __init dino_probe(struct parisc_device *dev)
* and 725 firmware misreport it as 0x08080 for no adequately explained
* reason.
*/
-static struct parisc_device_id dino_tbl[] = {
+static const struct parisc_device_id dino_tbl[] __initconst = {
{ HPHW_A_DMA, HVERSION_REV_ANY_ID, 0x004, 0x0009D },/* Card-mode Dino */
{ HPHW_A_DMA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x08080 }, /* XXX */
{ HPHW_BRIDGE, HVERSION_REV_ANY_ID, 0x680, 0xa }, /* Bridge-mode Dino */
@@ -1031,7 +1031,7 @@ static struct parisc_device_id dino_tbl[] = {
{ 0, }
};
-static struct parisc_driver dino_driver = {
+static struct parisc_driver dino_driver __refdata = {
.name = "dino",
.id_table = dino_tbl,
.probe = dino_probe,
diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c
index 7e2f6d5..9ff434f 100644
--- a/drivers/parisc/eisa.c
+++ b/drivers/parisc/eisa.c
@@ -393,7 +393,7 @@ error_release:
return result;
}
-static const struct parisc_device_id eisa_tbl[] = {
+static const struct parisc_device_id eisa_tbl[] __initconst = {
{ HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00076 }, /* Mongoose */
{ HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00090 }, /* Wax EISA */
{ 0, }
@@ -401,7 +401,7 @@ static const struct parisc_device_id eisa_tbl[] = {
MODULE_DEVICE_TABLE(parisc, eisa_tbl);
-static struct parisc_driver eisa_driver = {
+static struct parisc_driver eisa_driver __refdata = {
.name = "eisa_ba",
.id_table = eisa_tbl,
.probe = eisa_probe,
diff --git a/drivers/parisc/hppb.c b/drivers/parisc/hppb.c
index 898208e..ebc7b61 100644
--- a/drivers/parisc/hppb.c
+++ b/drivers/parisc/hppb.c
@@ -45,7 +45,7 @@ static struct hppb_card hppb_card_head = {
* (return 1). If so, initialize the chip and tell other partners in crime
* they have work to do.
*/
-static int hppb_probe(struct parisc_device *dev)
+static int __init hppb_probe(struct parisc_device *dev)
{
int status;
struct hppb_card *card = &hppb_card_head;
@@ -81,7 +81,7 @@ static int hppb_probe(struct parisc_device *dev)
return 0;
}
-static struct parisc_device_id hppb_tbl[] = {
+static const struct parisc_device_id hppb_tbl[] __initconst = {
{ HPHW_BCPORT, HVERSION_REV_ANY_ID, 0x500, 0xc }, /* E25 and K */
{ HPHW_BCPORT, 0x0, 0x501, 0xc }, /* E35 */
{ HPHW_BCPORT, 0x0, 0x502, 0xc }, /* E45 */
@@ -89,7 +89,7 @@ static struct parisc_device_id hppb_tbl[] = {
{ 0, }
};
-static struct parisc_driver hppb_driver = {
+static struct parisc_driver hppb_driver __refdata = {
.name = "gecko_boa",
.id_table = hppb_tbl,
.probe = hppb_probe,
diff --git a/drivers/parisc/lasi.c b/drivers/parisc/lasi.c
index e65727c..4c92254 100644
--- a/drivers/parisc/lasi.c
+++ b/drivers/parisc/lasi.c
@@ -227,12 +227,12 @@ static int __init lasi_init_chip(struct parisc_device *dev)
return ret;
}
-static struct parisc_device_id lasi_tbl[] = {
+static struct parisc_device_id lasi_tbl[] __initdata = {
{ HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00081 },
{ 0, }
};
-struct parisc_driver lasi_driver = {
+struct parisc_driver lasi_driver __refdata = {
.name = "lasi",
.id_table = lasi_tbl,
.probe = lasi_init_chip,
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index bc286cb..a25fed5 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -667,6 +667,42 @@ extend_lmmio_len(unsigned long start, unsigned long end, unsigned long lba_len)
#define truncate_pat_collision(r,n) (0)
#endif
+static void pcibios_allocate_bridge_resources(struct pci_dev *dev)
+{
+ int idx;
+ struct resource *r;
+
+ for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
+ r = &dev->resource[idx];
+ if (!r->flags)
+ continue;
+ if (r->parent) /* Already allocated */
+ continue;
+ if (!r->start || pci_claim_bridge_resource(dev, idx) < 0) {
+ /*
+ * Something is wrong with the region.
+ * Invalidate the resource to prevent
+ * child resource allocations in this
+ * range.
+ */
+ r->start = r->end = 0;
+ r->flags = 0;
+ }
+ }
+}
+
+static void pcibios_allocate_bus_resources(struct pci_bus *bus)
+{
+ struct pci_bus *child;
+
+ /* Depth-First Search on bus tree */
+ if (bus->self)
+ pcibios_allocate_bridge_resources(bus->self);
+ list_for_each_entry(child, &bus->children, node)
+ pcibios_allocate_bus_resources(child);
+}
+
+
/*
** The algorithm is generic code.
** But it needs to access local data structures to get the IRQ base.
@@ -693,11 +729,11 @@ lba_fixup_bus(struct pci_bus *bus)
** pci_alloc_primary_bus() mangles this.
*/
if (bus->parent) {
- int i;
/* PCI-PCI Bridge */
pci_read_bridge_bases(bus);
- for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++)
- pci_claim_bridge_resource(bus->self, i);
+
+ /* check and allocate bridge resources */
+ pcibios_allocate_bus_resources(bus);
} else {
/* Host-PCI Bridge */
int err;
@@ -1613,14 +1649,14 @@ lba_driver_probe(struct parisc_device *dev)
return 0;
}
-static struct parisc_device_id lba_tbl[] = {
+static const struct parisc_device_id lba_tbl[] __initconst = {
{ HPHW_BRIDGE, HVERSION_REV_ANY_ID, ELROY_HVERS, 0xa },
{ HPHW_BRIDGE, HVERSION_REV_ANY_ID, MERCURY_HVERS, 0xa },
{ HPHW_BRIDGE, HVERSION_REV_ANY_ID, QUICKSILVER_HVERS, 0xa },
{ 0, }
};
-static struct parisc_driver lba_driver = {
+static struct parisc_driver lba_driver __refdata = {
.name = MODULE_NAME,
.id_table = lba_tbl,
.probe = lba_driver_probe,
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index 4086f79..0a9c762 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -1905,7 +1905,7 @@ static const struct file_operations sba_proc_bitmap_fops = {
};
#endif /* CONFIG_PROC_FS */
-static struct parisc_device_id sba_tbl[] = {
+static const struct parisc_device_id sba_tbl[] __initconst = {
{ HPHW_IOA, HVERSION_REV_ANY_ID, ASTRO_RUNWAY_PORT, 0xb },
{ HPHW_BCPORT, HVERSION_REV_ANY_ID, IKE_MERCED_PORT, 0xc },
{ HPHW_BCPORT, HVERSION_REV_ANY_ID, REO_MERCED_PORT, 0xc },
@@ -1916,7 +1916,7 @@ static struct parisc_device_id sba_tbl[] = {
static int sba_driver_callback(struct parisc_device *);
-static struct parisc_driver sba_driver = {
+static struct parisc_driver sba_driver __refdata = {
.name = MODULE_NAME,
.id_table = sba_tbl,
.probe = sba_driver_callback,
@@ -1927,7 +1927,7 @@ static struct parisc_driver sba_driver = {
** If so, initialize the chip and tell other partners in crime they
** have work to do.
*/
-static int sba_driver_callback(struct parisc_device *dev)
+static int __init sba_driver_callback(struct parisc_device *dev)
{
struct sba_device *sba_dev;
u32 func_class;
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c
index deeaed5..0441777 100644
--- a/drivers/parisc/superio.c
+++ b/drivers/parisc/superio.c
@@ -482,14 +482,14 @@ superio_probe(struct pci_dev *dev, const struct pci_device_id *id)
return -ENODEV;
}
-static const struct pci_device_id superio_tbl[] = {
+static const struct pci_device_id superio_tbl[] __initconst = {
{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_LIO) },
{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_USB) },
{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415) },
{ 0, }
};
-static struct pci_driver superio_driver = {
+static struct pci_driver superio_driver __refdata = {
.name = SUPERIO,
.id_table = superio_tbl,
.probe = superio_probe,
diff --git a/drivers/parisc/wax.c b/drivers/parisc/wax.c
index da9d5ad..6a3e407 100644
--- a/drivers/parisc/wax.c
+++ b/drivers/parisc/wax.c
@@ -125,14 +125,14 @@ static int __init wax_init_chip(struct parisc_device *dev)
return ret;
}
-static struct parisc_device_id wax_tbl[] = {
+static const struct parisc_device_id wax_tbl[] __initconst = {
{ HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008e },
{ 0, }
};
MODULE_DEVICE_TABLE(parisc, wax_tbl);
-struct parisc_driver wax_driver = {
+struct parisc_driver wax_driver __refdata = {
.name = "wax",
.id_table = wax_tbl,
.probe = wax_init_chip,
diff --git a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c
index 3858b87..5f710aa 100644
--- a/drivers/parport/parport_gsc.c
+++ b/drivers/parport/parport_gsc.c
@@ -346,7 +346,7 @@ struct parport *parport_gsc_probe_port(unsigned long base,
static int parport_count;
-static int parport_init_chip(struct parisc_device *dev)
+static int __init parport_init_chip(struct parisc_device *dev)
{
struct parport *p;
unsigned long port;
@@ -381,7 +381,7 @@ static int parport_init_chip(struct parisc_device *dev)
return 0;
}
-static int parport_remove_chip(struct parisc_device *dev)
+static int __exit parport_remove_chip(struct parisc_device *dev)
{
struct parport *p = dev_get_drvdata(&dev->dev);
if (p) {
@@ -403,18 +403,18 @@ static int parport_remove_chip(struct parisc_device *dev)
return 0;
}
-static struct parisc_device_id parport_tbl[] = {
+static const struct parisc_device_id parport_tbl[] __initconst = {
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x74 },
{ 0, }
};
MODULE_DEVICE_TABLE(parisc, parport_tbl);
-static struct parisc_driver parport_driver = {
+static struct parisc_driver parport_driver __refdata = {
.name = "Parallel",
.id_table = parport_tbl,
.probe = parport_init_chip,
- .remove = parport_remove_chip,
+ .remove = __exit_p(parport_remove_chip),
};
int parport_gsc_init(void)
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index d51e873..4450fea 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -1307,6 +1307,7 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner,
drv->driver.bus = &pci_bus_type;
drv->driver.owner = owner;
drv->driver.mod_name = mod_name;
+ drv->driver.groups = drv->groups;
spin_lock_init(&drv->dynids.lock);
INIT_LIST_HEAD(&drv->dynids.list);
diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
index 1c5e0f3..d14fc2e 100644
--- a/drivers/perf/arm_pmu.c
+++ b/drivers/perf/arm_pmu.c
@@ -47,6 +47,9 @@ armpmu_map_cache_event(const unsigned (*cache_map)
if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
return -EINVAL;
+ if (!cache_map)
+ return -ENOENT;
+
ret = (int)(*cache_map)[cache_type][cache_op][cache_result];
if (ret == CACHE_OP_UNSUPPORTED)
@@ -63,6 +66,9 @@ armpmu_map_hw_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config)
if (config >= PERF_COUNT_HW_MAX)
return -EINVAL;
+ if (!event_map)
+ return -ENOENT;
+
mapping = (*event_map)[config];
return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping;
}
diff --git a/drivers/perf/xgene_pmu.c b/drivers/perf/xgene_pmu.c
index e841282..eb23311 100644
--- a/drivers/perf/xgene_pmu.c
+++ b/drivers/perf/xgene_pmu.c
@@ -1147,7 +1147,6 @@ xgene_pmu_dev_add(struct xgene_pmu *xgene_pmu, struct xgene_pmu_dev_ctx *ctx)
{
struct device *dev = xgene_pmu->dev;
struct xgene_pmu_dev *pmu;
- int rc;
pmu = devm_kzalloc(dev, sizeof(*pmu), GFP_KERNEL);
if (!pmu)
@@ -1159,7 +1158,7 @@ xgene_pmu_dev_add(struct xgene_pmu *xgene_pmu, struct xgene_pmu_dev_ctx *ctx)
switch (pmu->inf->type) {
case PMU_TYPE_L3C:
if (!(xgene_pmu->l3c_active_mask & pmu->inf->enable_mask))
- goto dev_err;
+ return -ENODEV;
if (xgene_pmu->version == PCP_PMU_V3)
pmu->attr_groups = l3c_pmu_v3_attr_groups;
else
@@ -1177,7 +1176,7 @@ xgene_pmu_dev_add(struct xgene_pmu *xgene_pmu, struct xgene_pmu_dev_ctx *ctx)
break;
case PMU_TYPE_MCB:
if (!(xgene_pmu->mcb_active_mask & pmu->inf->enable_mask))
- goto dev_err;
+ return -ENODEV;
if (xgene_pmu->version == PCP_PMU_V3)
pmu->attr_groups = mcb_pmu_v3_attr_groups;
else
@@ -1185,7 +1184,7 @@ xgene_pmu_dev_add(struct xgene_pmu *xgene_pmu, struct xgene_pmu_dev_ctx *ctx)
break;
case PMU_TYPE_MC:
if (!(xgene_pmu->mc_active_mask & pmu->inf->enable_mask))
- goto dev_err;
+ return -ENODEV;
if (xgene_pmu->version == PCP_PMU_V3)
pmu->attr_groups = mc_pmu_v3_attr_groups;
else
@@ -1195,19 +1194,14 @@ xgene_pmu_dev_add(struct xgene_pmu *xgene_pmu, struct xgene_pmu_dev_ctx *ctx)
return -EINVAL;
}
- rc = xgene_init_perf(pmu, ctx->name);
- if (rc) {
+ if (xgene_init_perf(pmu, ctx->name)) {
dev_err(dev, "%s PMU: Failed to init perf driver\n", ctx->name);
- goto dev_err;
+ return -ENODEV;
}
dev_info(dev, "%s PMU registered\n", ctx->name);
- return rc;
-
-dev_err:
- devm_kfree(dev, pmu);
- return -ENODEV;
+ return 0;
}
static void _xgene_pmu_isr(int irq, struct xgene_pmu_dev *pmu_dev)
@@ -1515,13 +1509,13 @@ xgene_pmu_dev_ctx *acpi_get_pmu_hw_inf(struct xgene_pmu *xgene_pmu,
acpi_dev_free_resource_list(&resource_list);
if (rc < 0) {
dev_err(dev, "PMU type %d: No resource address found\n", type);
- goto err;
+ return NULL;
}
dev_csr = devm_ioremap_resource(dev, &res);
if (IS_ERR(dev_csr)) {
dev_err(dev, "PMU type %d: Fail to map resource\n", type);
- goto err;
+ return NULL;
}
/* A PMU device node without enable-bit-index is always enabled */
@@ -1535,7 +1529,7 @@ xgene_pmu_dev_ctx *acpi_get_pmu_hw_inf(struct xgene_pmu *xgene_pmu,
ctx->name = xgene_pmu_dev_name(dev, type, enable_bit);
if (!ctx->name) {
dev_err(dev, "PMU type %d: Fail to get device name\n", type);
- goto err;
+ return NULL;
}
inf = &ctx->inf;
inf->type = type;
@@ -1543,9 +1537,6 @@ xgene_pmu_dev_ctx *acpi_get_pmu_hw_inf(struct xgene_pmu *xgene_pmu,
inf->enable_mask = 1 << enable_bit;
return ctx;
-err:
- devm_kfree(dev, ctx);
- return NULL;
}
static const struct acpi_device_id xgene_pmu_acpi_type_match[] = {
@@ -1663,20 +1654,20 @@ xgene_pmu_dev_ctx *fdt_get_pmu_hw_inf(struct xgene_pmu *xgene_pmu,
void __iomem *dev_csr;
struct resource res;
int enable_bit;
- int rc;
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return NULL;
- rc = of_address_to_resource(np, 0, &res);
- if (rc < 0) {
+
+ if (of_address_to_resource(np, 0, &res) < 0) {
dev_err(dev, "PMU type %d: No resource address found\n", type);
- goto err;
+ return NULL;
}
+
dev_csr = devm_ioremap_resource(dev, &res);
if (IS_ERR(dev_csr)) {
dev_err(dev, "PMU type %d: Fail to map resource\n", type);
- goto err;
+ return NULL;
}
/* A PMU device node without enable-bit-index is always enabled */
@@ -1686,17 +1677,15 @@ xgene_pmu_dev_ctx *fdt_get_pmu_hw_inf(struct xgene_pmu *xgene_pmu,
ctx->name = xgene_pmu_dev_name(dev, type, enable_bit);
if (!ctx->name) {
dev_err(dev, "PMU type %d: Fail to get device name\n", type);
- goto err;
+ return NULL;
}
+
inf = &ctx->inf;
inf->type = type;
inf->csr = dev_csr;
inf->enable_mask = 1 << enable_bit;
return ctx;
-err:
- devm_kfree(dev, ctx);
- return NULL;
}
static int fdt_pmu_probe_pmu_dev(struct xgene_pmu *xgene_pmu,
@@ -1868,22 +1857,20 @@ static int xgene_pmu_probe(struct platform_device *pdev)
xgene_pmu->pcppmu_csr = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(xgene_pmu->pcppmu_csr)) {
dev_err(&pdev->dev, "ioremap failed for PCP PMU resource\n");
- rc = PTR_ERR(xgene_pmu->pcppmu_csr);
- goto err;
+ return PTR_ERR(xgene_pmu->pcppmu_csr);
}
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "No IRQ resource\n");
- rc = -EINVAL;
- goto err;
+ return -EINVAL;
}
rc = devm_request_irq(&pdev->dev, irq, xgene_pmu_isr,
IRQF_NOBALANCING | IRQF_NO_THREAD,
dev_name(&pdev->dev), xgene_pmu);
if (rc) {
dev_err(&pdev->dev, "Could not request IRQ %d\n", irq);
- goto err;
+ return rc;
}
raw_spin_lock_init(&xgene_pmu->lock);
@@ -1903,42 +1890,29 @@ static int xgene_pmu_probe(struct platform_device *pdev)
rc = irq_set_affinity(irq, &xgene_pmu->cpu);
if (rc) {
dev_err(&pdev->dev, "Failed to set interrupt affinity!\n");
- goto err;
+ return rc;
}
/* Walk through the tree for all PMU perf devices */
rc = xgene_pmu_probe_pmu_dev(xgene_pmu, pdev);
if (rc) {
dev_err(&pdev->dev, "No PMU perf devices found!\n");
- goto err;
+ return rc;
}
/* Enable interrupt */
xgene_pmu->ops->unmask_int(xgene_pmu);
return 0;
-
-err:
- if (xgene_pmu->pcppmu_csr)
- devm_iounmap(&pdev->dev, xgene_pmu->pcppmu_csr);
- devm_kfree(&pdev->dev, xgene_pmu);
-
- return rc;
}
static void
xgene_pmu_dev_cleanup(struct xgene_pmu *xgene_pmu, struct list_head *pmus)
{
struct xgene_pmu_dev_ctx *ctx;
- struct device *dev = xgene_pmu->dev;
- struct xgene_pmu_dev *pmu_dev;
list_for_each_entry(ctx, pmus, next) {
- pmu_dev = ctx->pmu_dev;
- if (pmu_dev->inf->csr)
- devm_iounmap(dev, pmu_dev->inf->csr);
- devm_kfree(dev, ctx);
- devm_kfree(dev, pmu_dev);
+ perf_pmu_unregister(&ctx->pmu_dev->pmu);
}
}
@@ -1951,10 +1925,6 @@ static int xgene_pmu_remove(struct platform_device *pdev)
xgene_pmu_dev_cleanup(xgene_pmu, &xgene_pmu->mcbpmus);
xgene_pmu_dev_cleanup(xgene_pmu, &xgene_pmu->mcpmus);
- if (xgene_pmu->pcppmu_csr)
- devm_iounmap(&pdev->dev, xgene_pmu->pcppmu_csr);
- devm_kfree(&pdev->dev, xgene_pmu);
-
return 0;
}
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index c1807d4..441912c 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -26,14 +26,6 @@ config PHY_LPC18XX_USB_OTG
This driver is need for USB0 support on LPC18xx/43xx and takes
care of enabling and clock setup.
-config PHY_MT65XX_USB3
- tristate "Mediatek USB3.0 PHY Driver"
- depends on ARCH_MEDIATEK && OF
- select GENERIC_PHY
- help
- Say 'Y' here to add support for Mediatek USB3.0 PHY driver,
- it supports multiple usb2.0 and usb3.0 ports.
-
config PHY_PISTACHIO_USB
tristate "IMG Pistachio USB2.0 PHY driver"
depends on MACH_PISTACHIO
@@ -53,8 +45,10 @@ source "drivers/phy/amlogic/Kconfig"
source "drivers/phy/broadcom/Kconfig"
source "drivers/phy/hisilicon/Kconfig"
source "drivers/phy/marvell/Kconfig"
+source "drivers/phy/mediatek/Kconfig"
source "drivers/phy/motorola/Kconfig"
source "drivers/phy/qualcomm/Kconfig"
+source "drivers/phy/ralink/Kconfig"
source "drivers/phy/renesas/Kconfig"
source "drivers/phy/rockchip/Kconfig"
source "drivers/phy/samsung/Kconfig"
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index f252201..06f3c50 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -4,12 +4,12 @@
obj-$(CONFIG_GENERIC_PHY) += phy-core.o
obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o
-obj-$(CONFIG_PHY_MT65XX_USB3) += phy-mt65xx-usb3.o
obj-$(CONFIG_PHY_XGENE) += phy-xgene.o
obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o
obj-$(CONFIG_ARCH_SUNXI) += allwinner/
obj-$(CONFIG_ARCH_MESON) += amlogic/
+obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
obj-$(CONFIG_ARCH_RENESAS) += renesas/
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
obj-$(CONFIG_ARCH_TEGRA) += tegra/
@@ -18,6 +18,7 @@ obj-y += broadcom/ \
marvell/ \
motorola/ \
qualcomm/ \
+ ralink/ \
samsung/ \
st/ \
ti/
diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c
index bbf06cf..1161e11 100644
--- a/drivers/phy/allwinner/phy-sun4i-usb.c
+++ b/drivers/phy/allwinner/phy-sun4i-usb.c
@@ -87,6 +87,16 @@
#define PHY_DISCON_TH_SEL 0x2a
#define PHY_SQUELCH_DETECT 0x3c
+/* A83T specific control bits for PHY0 */
+#define PHY_CTL_VBUSVLDEXT BIT(5)
+#define PHY_CTL_SIDDQ BIT(3)
+
+/* A83T specific control bits for PHY2 HSIC */
+#define SUNXI_EHCI_HS_FORCE BIT(20)
+#define SUNXI_HSIC_CONNECT_DET BIT(17)
+#define SUNXI_HSIC_CONNECT_INT BIT(16)
+#define SUNXI_HSIC BIT(1)
+
#define MAX_PHYS 4
/*
@@ -100,6 +110,7 @@ enum sun4i_usb_phy_type {
sun4i_a10_phy,
sun6i_a31_phy,
sun8i_a33_phy,
+ sun8i_a83t_phy,
sun8i_h3_phy,
sun8i_v3s_phy,
sun50i_a64_phy,
@@ -107,6 +118,7 @@ enum sun4i_usb_phy_type {
struct sun4i_usb_phy_cfg {
int num_phys;
+ int hsic_index;
enum sun4i_usb_phy_type type;
u32 disc_thresh;
u8 phyctl_offset;
@@ -126,6 +138,7 @@ struct sun4i_usb_phy_data {
struct regulator *vbus;
struct reset_control *reset;
struct clk *clk;
+ struct clk *clk2;
bool regulator_on;
int index;
} phys[MAX_PHYS];
@@ -232,6 +245,7 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
static void sun4i_usb_phy_passby(struct sun4i_usb_phy *phy, int enable)
{
+ struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy);
u32 bits, reg_value;
if (!phy->pmu)
@@ -240,6 +254,11 @@ static void sun4i_usb_phy_passby(struct sun4i_usb_phy *phy, int enable)
bits = SUNXI_AHB_ICHR8_EN | SUNXI_AHB_INCR4_BURST_EN |
SUNXI_AHB_INCRX_ALIGN_EN | SUNXI_ULPI_BYPASS_EN;
+ /* A83T USB2 is HSIC */
+ if (phy_data->cfg->type == sun8i_a83t_phy && phy->index == 2)
+ bits |= SUNXI_EHCI_HS_FORCE | SUNXI_HSIC_CONNECT_INT |
+ SUNXI_HSIC;
+
reg_value = readl(phy->pmu);
if (enable)
@@ -261,27 +280,43 @@ static int sun4i_usb_phy_init(struct phy *_phy)
if (ret)
return ret;
- ret = reset_control_deassert(phy->reset);
+ ret = clk_prepare_enable(phy->clk2);
if (ret) {
clk_disable_unprepare(phy->clk);
return ret;
}
- if (phy->pmu && data->cfg->enable_pmu_unk1) {
- val = readl(phy->pmu + REG_PMU_UNK1);
- writel(val & ~2, phy->pmu + REG_PMU_UNK1);
+ ret = reset_control_deassert(phy->reset);
+ if (ret) {
+ clk_disable_unprepare(phy->clk2);
+ clk_disable_unprepare(phy->clk);
+ return ret;
}
- /* Enable USB 45 Ohm resistor calibration */
- if (phy->index == 0)
- sun4i_usb_phy_write(phy, PHY_RES45_CAL_EN, 0x01, 1);
+ if (data->cfg->type == sun8i_a83t_phy) {
+ if (phy->index == 0) {
+ val = readl(data->base + data->cfg->phyctl_offset);
+ val |= PHY_CTL_VBUSVLDEXT;
+ val &= ~PHY_CTL_SIDDQ;
+ writel(val, data->base + data->cfg->phyctl_offset);
+ }
+ } else {
+ if (phy->pmu && data->cfg->enable_pmu_unk1) {
+ val = readl(phy->pmu + REG_PMU_UNK1);
+ writel(val & ~2, phy->pmu + REG_PMU_UNK1);
+ }
- /* Adjust PHY's magnitude and rate */
- sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5);
+ /* Enable USB 45 Ohm resistor calibration */
+ if (phy->index == 0)
+ sun4i_usb_phy_write(phy, PHY_RES45_CAL_EN, 0x01, 1);
- /* Disconnect threshold adjustment */
- sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL,
- data->cfg->disc_thresh, 2);
+ /* Adjust PHY's magnitude and rate */
+ sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5);
+
+ /* Disconnect threshold adjustment */
+ sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL,
+ data->cfg->disc_thresh, 2);
+ }
sun4i_usb_phy_passby(phy, 1);
@@ -307,6 +342,13 @@ static int sun4i_usb_phy_exit(struct phy *_phy)
struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
if (phy->index == 0) {
+ if (data->cfg->type == sun8i_a83t_phy) {
+ void __iomem *phyctl = data->base +
+ data->cfg->phyctl_offset;
+
+ writel(readl(phyctl) | PHY_CTL_SIDDQ, phyctl);
+ }
+
/* Disable pull-ups */
sun4i_usb_phy0_update_iscr(_phy, ISCR_DPDM_PULLUP_EN, 0);
sun4i_usb_phy0_update_iscr(_phy, ISCR_ID_PULLUP_EN, 0);
@@ -315,6 +357,7 @@ static int sun4i_usb_phy_exit(struct phy *_phy)
sun4i_usb_phy_passby(phy, 0);
reset_control_assert(phy->reset);
+ clk_disable_unprepare(phy->clk2);
clk_disable_unprepare(phy->clk);
return 0;
@@ -653,19 +696,25 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
data->id_det_gpio = devm_gpiod_get_optional(dev, "usb0_id_det",
GPIOD_IN);
- if (IS_ERR(data->id_det_gpio))
+ if (IS_ERR(data->id_det_gpio)) {
+ dev_err(dev, "Couldn't request ID GPIO\n");
return PTR_ERR(data->id_det_gpio);
+ }
data->vbus_det_gpio = devm_gpiod_get_optional(dev, "usb0_vbus_det",
GPIOD_IN);
- if (IS_ERR(data->vbus_det_gpio))
+ if (IS_ERR(data->vbus_det_gpio)) {
+ dev_err(dev, "Couldn't request VBUS detect GPIO\n");
return PTR_ERR(data->vbus_det_gpio);
+ }
if (of_find_property(np, "usb0_vbus_power-supply", NULL)) {
data->vbus_power_supply = devm_power_supply_get_by_phandle(dev,
"usb0_vbus_power-supply");
- if (IS_ERR(data->vbus_power_supply))
+ if (IS_ERR(data->vbus_power_supply)) {
+ dev_err(dev, "Couldn't get the VBUS power supply\n");
return PTR_ERR(data->vbus_power_supply);
+ }
if (!data->vbus_power_supply)
return -EPROBE_DEFER;
@@ -674,8 +723,10 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
data->dr_mode = of_usb_get_dr_mode_by_phy(np, 0);
data->extcon = devm_extcon_dev_allocate(dev, sun4i_usb_phy0_cable);
- if (IS_ERR(data->extcon))
+ if (IS_ERR(data->extcon)) {
+ dev_err(dev, "Couldn't allocate our extcon device\n");
return PTR_ERR(data->extcon);
+ }
ret = devm_extcon_dev_register(dev, data->extcon);
if (ret) {
@@ -690,8 +741,13 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
snprintf(name, sizeof(name), "usb%d_vbus", i);
phy->vbus = devm_regulator_get_optional(dev, name);
if (IS_ERR(phy->vbus)) {
- if (PTR_ERR(phy->vbus) == -EPROBE_DEFER)
+ if (PTR_ERR(phy->vbus) == -EPROBE_DEFER) {
+ dev_err(dev,
+ "Couldn't get regulator %s... Deferring probe\n",
+ name);
return -EPROBE_DEFER;
+ }
+
phy->vbus = NULL;
}
@@ -706,6 +762,17 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
return PTR_ERR(phy->clk);
}
+ /* The first PHY is always tied to OTG, and never HSIC */
+ if (data->cfg->hsic_index && i == data->cfg->hsic_index) {
+ /* HSIC needs secondary clock */
+ snprintf(name, sizeof(name), "usb%d_hsic_12M", i);
+ phy->clk2 = devm_clk_get(dev, name);
+ if (IS_ERR(phy->clk2)) {
+ dev_err(dev, "failed to get clock %s\n", name);
+ return PTR_ERR(phy->clk2);
+ }
+ }
+
snprintf(name, sizeof(name), "usb%d_reset", i);
phy->reset = devm_reset_control_get(dev, name);
if (IS_ERR(phy->reset)) {
@@ -775,6 +842,8 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
return PTR_ERR(phy_provider);
}
+ dev_dbg(dev, "successfully loaded\n");
+
return 0;
}
@@ -832,6 +901,14 @@ static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = {
.enable_pmu_unk1 = false,
};
+static const struct sun4i_usb_phy_cfg sun8i_a83t_cfg = {
+ .num_phys = 3,
+ .hsic_index = 2,
+ .type = sun8i_a83t_phy,
+ .phyctl_offset = REG_PHYCTL_A33,
+ .dedicated_clocks = true,
+};
+
static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = {
.num_phys = 4,
.type = sun8i_h3_phy,
@@ -868,6 +945,7 @@ static const struct of_device_id sun4i_usb_phy_of_match[] = {
{ .compatible = "allwinner,sun7i-a20-usb-phy", .data = &sun7i_a20_cfg },
{ .compatible = "allwinner,sun8i-a23-usb-phy", .data = &sun8i_a23_cfg },
{ .compatible = "allwinner,sun8i-a33-usb-phy", .data = &sun8i_a33_cfg },
+ { .compatible = "allwinner,sun8i-a83t-usb-phy", .data = &sun8i_a83t_cfg },
{ .compatible = "allwinner,sun8i-h3-usb-phy", .data = &sun8i_h3_cfg },
{ .compatible = "allwinner,sun8i-v3s-usb-phy", .data = &sun8i_v3s_cfg },
{ .compatible = "allwinner,sun50i-a64-usb-phy",
diff --git a/drivers/phy/broadcom/phy-brcm-sata.c b/drivers/phy/broadcom/phy-brcm-sata.c
index e6544c8..9d7f74f 100644
--- a/drivers/phy/broadcom/phy-brcm-sata.c
+++ b/drivers/phy/broadcom/phy-brcm-sata.c
@@ -335,7 +335,7 @@ static int brcm_nsp_sata_init(struct brcm_sata_port *port)
/* Wait for pll_seq_done bit */
try = 50;
- while (try--) {
+ while (--try) {
val = brcm_sata_phy_rd(base, BLOCK0_REG_BANK,
BLOCK0_XGXSSTATUS);
if (val & BLOCK0_XGXSSTATUS_PLL_LOCK)
diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
new file mode 100644
index 0000000..88ab4e2
--- /dev/null
+++ b/drivers/phy/mediatek/Kconfig
@@ -0,0 +1,14 @@
+#
+# Phy drivers for Mediatek devices
+#
+config PHY_MTK_TPHY
+ tristate "MediaTek T-PHY Driver"
+ depends on ARCH_MEDIATEK && OF
+ select GENERIC_PHY
+ help
+ Say 'Y' here to add support for MediaTek T-PHY driver,
+ it supports multiple usb2.0, usb3.0 ports, PCIe and
+ SATA, and meanwhile supports two version T-PHY which have
+ different banks layout, the T-PHY with shared banks between
+ multi-ports is first version, otherwise is second veriosn,
+ so you can easily distinguish them by banks layout.
diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
new file mode 100644
index 0000000..763a92e
--- /dev/null
+++ b/drivers/phy/mediatek/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the phy drivers.
+#
+
+obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o
diff --git a/drivers/phy/phy-mt65xx-usb3.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index 59b110f..e3baad7 100644
--- a/drivers/phy/phy-mt65xx-usb3.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -29,7 +29,7 @@
#define SSUSB_SIFSLV_V1_U2FREQ 0x100 /* shared by u2 phys */
/* u2 phy bank */
#define SSUSB_SIFSLV_V1_U2PHY_COM 0x000
-/* u3 phy banks */
+/* u3/pcie/sata phy banks */
#define SSUSB_SIFSLV_V1_U3PHYD 0x000
#define SSUSB_SIFSLV_V1_U3PHYA 0x200
@@ -38,7 +38,7 @@
#define SSUSB_SIFSLV_V2_MISC 0x000
#define SSUSB_SIFSLV_V2_U2FREQ 0x100
#define SSUSB_SIFSLV_V2_U2PHY_COM 0x300
-/* u3 phy banks */
+/* u3/pcie/sata phy banks */
#define SSUSB_SIFSLV_V2_SPLLC 0x000
#define SSUSB_SIFSLV_V2_CHIP 0x100
#define SSUSB_SIFSLV_V2_U3PHYD 0x200
@@ -99,6 +99,23 @@
#define P2C_RG_SESSEND BIT(4)
#define P2C_RG_AVALID BIT(2)
+#define U3P_U3_CHIP_GPIO_CTLD 0x0c
+#define P3C_REG_IP_SW_RST BIT(31)
+#define P3C_MCU_BUS_CK_GATE_EN BIT(30)
+#define P3C_FORCE_IP_SW_RST BIT(29)
+
+#define U3P_U3_CHIP_GPIO_CTLE 0x10
+#define P3C_RG_SWRST_U3_PHYD BIT(25)
+#define P3C_RG_SWRST_U3_PHYD_FORCE_EN BIT(24)
+
+#define U3P_U3_PHYA_REG0 0x000
+#define P3A_RG_CLKDRV_OFF GENMASK(3, 2)
+#define P3A_RG_CLKDRV_OFF_VAL(x) ((0x3 & (x)) << 2)
+
+#define U3P_U3_PHYA_REG1 0x004
+#define P3A_RG_CLKDRV_AMP GENMASK(31, 29)
+#define P3A_RG_CLKDRV_AMP_VAL(x) ((0x7 & (x)) << 29)
+
#define U3P_U3_PHYA_REG6 0x018
#define P3A_RG_TX_EIDLE_CM GENMASK(31, 28)
#define P3A_RG_TX_EIDLE_CM_VAL(x) ((0xf & (x)) << 28)
@@ -108,9 +125,40 @@
#define P3A_RG_RX_DAC_MUX_VAL(x) ((0x1f & (x)) << 1)
#define U3P_U3_PHYA_DA_REG0 0x100
+#define P3A_RG_XTAL_EXT_PE2H GENMASK(17, 16)
+#define P3A_RG_XTAL_EXT_PE2H_VAL(x) ((0x3 & (x)) << 16)
+#define P3A_RG_XTAL_EXT_PE1H GENMASK(13, 12)
+#define P3A_RG_XTAL_EXT_PE1H_VAL(x) ((0x3 & (x)) << 12)
#define P3A_RG_XTAL_EXT_EN_U3 GENMASK(11, 10)
#define P3A_RG_XTAL_EXT_EN_U3_VAL(x) ((0x3 & (x)) << 10)
+#define U3P_U3_PHYA_DA_REG4 0x108
+#define P3A_RG_PLL_DIVEN_PE2H GENMASK(21, 19)
+#define P3A_RG_PLL_BC_PE2H GENMASK(7, 6)
+#define P3A_RG_PLL_BC_PE2H_VAL(x) ((0x3 & (x)) << 6)
+
+#define U3P_U3_PHYA_DA_REG5 0x10c
+#define P3A_RG_PLL_BR_PE2H GENMASK(29, 28)
+#define P3A_RG_PLL_BR_PE2H_VAL(x) ((0x3 & (x)) << 28)
+#define P3A_RG_PLL_IC_PE2H GENMASK(15, 12)
+#define P3A_RG_PLL_IC_PE2H_VAL(x) ((0xf & (x)) << 12)
+
+#define U3P_U3_PHYA_DA_REG6 0x110
+#define P3A_RG_PLL_IR_PE2H GENMASK(19, 16)
+#define P3A_RG_PLL_IR_PE2H_VAL(x) ((0xf & (x)) << 16)
+
+#define U3P_U3_PHYA_DA_REG7 0x114
+#define P3A_RG_PLL_BP_PE2H GENMASK(19, 16)
+#define P3A_RG_PLL_BP_PE2H_VAL(x) ((0xf & (x)) << 16)
+
+#define U3P_U3_PHYA_DA_REG20 0x13c
+#define P3A_RG_PLL_DELTA1_PE2H GENMASK(31, 16)
+#define P3A_RG_PLL_DELTA1_PE2H_VAL(x) ((0xffff & (x)) << 16)
+
+#define U3P_U3_PHYA_DA_REG25 0x148
+#define P3A_RG_PLL_DELTA_PE2H GENMASK(15, 0)
+#define P3A_RG_PLL_DELTA_PE2H_VAL(x) (0xffff & (x))
+
#define U3P_U3_PHYD_LFPS1 0x00c
#define P3D_RG_FWAKE_TH GENMASK(21, 16)
#define P3D_RG_FWAKE_TH_VAL(x) ((0x3f & (x)) << 16)
@@ -151,15 +199,74 @@
#define U3P_SR_COEF_DIVISOR 1000
#define U3P_FM_DET_CYCLE_CNT 1024
-enum mt_phy_version {
- MT_PHY_V1 = 1,
- MT_PHY_V2,
+/* SATA register setting */
+#define PHYD_CTRL_SIGNAL_MODE4 0x1c
+/* CDR Charge Pump P-path current adjustment */
+#define RG_CDR_BICLTD1_GEN1_MSK GENMASK(23, 20)
+#define RG_CDR_BICLTD1_GEN1_VAL(x) ((0xf & (x)) << 20)
+#define RG_CDR_BICLTD0_GEN1_MSK GENMASK(11, 8)
+#define RG_CDR_BICLTD0_GEN1_VAL(x) ((0xf & (x)) << 8)
+
+#define PHYD_DESIGN_OPTION2 0x24
+/* Symbol lock count selection */
+#define RG_LOCK_CNT_SEL_MSK GENMASK(5, 4)
+#define RG_LOCK_CNT_SEL_VAL(x) ((0x3 & (x)) << 4)
+
+#define PHYD_DESIGN_OPTION9 0x40
+/* COMWAK GAP width window */
+#define RG_TG_MAX_MSK GENMASK(20, 16)
+#define RG_TG_MAX_VAL(x) ((0x1f & (x)) << 16)
+/* COMINIT GAP width window */
+#define RG_T2_MAX_MSK GENMASK(13, 8)
+#define RG_T2_MAX_VAL(x) ((0x3f & (x)) << 8)
+/* COMWAK GAP width window */
+#define RG_TG_MIN_MSK GENMASK(7, 5)
+#define RG_TG_MIN_VAL(x) ((0x7 & (x)) << 5)
+/* COMINIT GAP width window */
+#define RG_T2_MIN_MSK GENMASK(4, 0)
+#define RG_T2_MIN_VAL(x) (0x1f & (x))
+
+#define ANA_RG_CTRL_SIGNAL1 0x4c
+/* TX driver tail current control for 0dB de-empahsis mdoe for Gen1 speed */
+#define RG_IDRV_0DB_GEN1_MSK GENMASK(13, 8)
+#define RG_IDRV_0DB_GEN1_VAL(x) ((0x3f & (x)) << 8)
+
+#define ANA_RG_CTRL_SIGNAL4 0x58
+#define RG_CDR_BICLTR_GEN1_MSK GENMASK(23, 20)
+#define RG_CDR_BICLTR_GEN1_VAL(x) ((0xf & (x)) << 20)
+/* Loop filter R1 resistance adjustment for Gen1 speed */
+#define RG_CDR_BR_GEN2_MSK GENMASK(10, 8)
+#define RG_CDR_BR_GEN2_VAL(x) ((0x7 & (x)) << 8)
+
+#define ANA_RG_CTRL_SIGNAL6 0x60
+/* I-path capacitance adjustment for Gen1 */
+#define RG_CDR_BC_GEN1_MSK GENMASK(28, 24)
+#define RG_CDR_BC_GEN1_VAL(x) ((0x1f & (x)) << 24)
+#define RG_CDR_BIRLTR_GEN1_MSK GENMASK(4, 0)
+#define RG_CDR_BIRLTR_GEN1_VAL(x) (0x1f & (x))
+
+#define ANA_EQ_EYE_CTRL_SIGNAL1 0x6c
+/* RX Gen1 LEQ tuning step */
+#define RG_EQ_DLEQ_LFI_GEN1_MSK GENMASK(11, 8)
+#define RG_EQ_DLEQ_LFI_GEN1_VAL(x) ((0xf & (x)) << 8)
+
+#define ANA_EQ_EYE_CTRL_SIGNAL4 0xd8
+#define RG_CDR_BIRLTD0_GEN1_MSK GENMASK(20, 16)
+#define RG_CDR_BIRLTD0_GEN1_VAL(x) ((0x1f & (x)) << 16)
+
+#define ANA_EQ_EYE_CTRL_SIGNAL5 0xdc
+#define RG_CDR_BIRLTD0_GEN3_MSK GENMASK(4, 0)
+#define RG_CDR_BIRLTD0_GEN3_VAL(x) (0x1f & (x))
+
+enum mtk_phy_version {
+ MTK_PHY_V1 = 1,
+ MTK_PHY_V2,
};
-struct mt65xx_phy_pdata {
+struct mtk_phy_pdata {
/* avoid RX sensitivity level degradation only for mt8173 */
bool avoid_rx_sen_degradation;
- enum mt_phy_version version;
+ enum mtk_phy_version version;
};
struct u2phy_banks {
@@ -175,7 +282,7 @@ struct u3phy_banks {
void __iomem *phya; /* include u3phya_da */
};
-struct mt65xx_phy_instance {
+struct mtk_phy_instance {
struct phy *phy;
void __iomem *port_base;
union {
@@ -187,18 +294,18 @@ struct mt65xx_phy_instance {
u8 type;
};
-struct mt65xx_u3phy {
+struct mtk_tphy {
struct device *dev;
void __iomem *sif_base; /* only shared sif */
/* deprecated, use @ref_clk instead in phy instance */
struct clk *u3phya_ref; /* reference clock of usb3 anolog phy */
- const struct mt65xx_phy_pdata *pdata;
- struct mt65xx_phy_instance **phys;
+ const struct mtk_phy_pdata *pdata;
+ struct mtk_phy_instance **phys;
int nphys;
};
-static void hs_slew_rate_calibrate(struct mt65xx_u3phy *u3phy,
- struct mt65xx_phy_instance *instance)
+static void hs_slew_rate_calibrate(struct mtk_tphy *tphy,
+ struct mtk_phy_instance *instance)
{
struct u2phy_banks *u2_banks = &instance->u2_banks;
void __iomem *fmreg = u2_banks->fmreg;
@@ -222,7 +329,7 @@ static void hs_slew_rate_calibrate(struct mt65xx_u3phy *u3phy,
tmp = readl(fmreg + U3P_U2FREQ_FMCR0);
tmp &= ~(P2F_RG_CYCLECNT | P2F_RG_MONCLK_SEL);
tmp |= P2F_RG_CYCLECNT_VAL(U3P_FM_DET_CYCLE_CNT);
- if (u3phy->pdata->version == MT_PHY_V1)
+ if (tphy->pdata->version == MTK_PHY_V1)
tmp |= P2F_RG_MONCLK_SEL_VAL(instance->index >> 1);
writel(tmp, fmreg + U3P_U2FREQ_FMCR0);
@@ -257,7 +364,7 @@ static void hs_slew_rate_calibrate(struct mt65xx_u3phy *u3phy,
/* if FM detection fail, set default value */
calibration_val = 4;
}
- dev_dbg(u3phy->dev, "phy:%d, fm_out:%d, calib:%d\n",
+ dev_dbg(tphy->dev, "phy:%d, fm_out:%d, calib:%d\n",
instance->index, fm_out, calibration_val);
/* set HS slew rate */
@@ -272,8 +379,8 @@ static void hs_slew_rate_calibrate(struct mt65xx_u3phy *u3phy,
writel(tmp, com + U3P_USBPHYACR5);
}
-static void u3_phy_instance_init(struct mt65xx_u3phy *u3phy,
- struct mt65xx_phy_instance *instance)
+static void u3_phy_instance_init(struct mtk_tphy *tphy,
+ struct mtk_phy_instance *instance)
{
struct u3phy_banks *u3_banks = &instance->u3_banks;
u32 tmp;
@@ -319,11 +426,11 @@ static void u3_phy_instance_init(struct mt65xx_u3phy *u3phy,
tmp |= P3D_RG_RXDET_STB2_SET_P3_VAL(0x10);
writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RXDET2);
- dev_dbg(u3phy->dev, "%s(%d)\n", __func__, instance->index);
+ dev_dbg(tphy->dev, "%s(%d)\n", __func__, instance->index);
}
-static void phy_instance_init(struct mt65xx_u3phy *u3phy,
- struct mt65xx_phy_instance *instance)
+static void u2_phy_instance_init(struct mtk_tphy *tphy,
+ struct mtk_phy_instance *instance)
{
struct u2phy_banks *u2_banks = &instance->u2_banks;
void __iomem *com = u2_banks->com;
@@ -355,7 +462,7 @@ static void phy_instance_init(struct mt65xx_u3phy *u3phy,
writel(tmp, com + U3P_U2PHYACR4);
}
- if (u3phy->pdata->avoid_rx_sen_degradation) {
+ if (tphy->pdata->avoid_rx_sen_degradation) {
if (!index) {
tmp = readl(com + U3P_USBPHYACR2);
tmp |= PA2_RG_SIF_U2PLL_FORCE_EN;
@@ -381,11 +488,11 @@ static void phy_instance_init(struct mt65xx_u3phy *u3phy,
tmp |= PA6_RG_U2_SQTH_VAL(2);
writel(tmp, com + U3P_USBPHYACR6);
- dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
+ dev_dbg(tphy->dev, "%s(%d)\n", __func__, index);
}
-static void phy_instance_power_on(struct mt65xx_u3phy *u3phy,
- struct mt65xx_phy_instance *instance)
+static void u2_phy_instance_power_on(struct mtk_tphy *tphy,
+ struct mtk_phy_instance *instance)
{
struct u2phy_banks *u2_banks = &instance->u2_banks;
void __iomem *com = u2_banks->com;
@@ -408,7 +515,7 @@ static void phy_instance_power_on(struct mt65xx_u3phy *u3phy,
tmp &= ~P2C_RG_SESSEND;
writel(tmp, com + U3P_U2PHYDTM1);
- if (u3phy->pdata->avoid_rx_sen_degradation && index) {
+ if (tphy->pdata->avoid_rx_sen_degradation && index) {
tmp = readl(com + U3D_U2PHYDCR0);
tmp |= P2C_RG_SIF_U2PLL_FORCE_ON;
writel(tmp, com + U3D_U2PHYDCR0);
@@ -417,11 +524,11 @@ static void phy_instance_power_on(struct mt65xx_u3phy *u3phy,
tmp |= P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM;
writel(tmp, com + U3P_U2PHYDTM0);
}
- dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
+ dev_dbg(tphy->dev, "%s(%d)\n", __func__, index);
}
-static void phy_instance_power_off(struct mt65xx_u3phy *u3phy,
- struct mt65xx_phy_instance *instance)
+static void u2_phy_instance_power_off(struct mtk_tphy *tphy,
+ struct mtk_phy_instance *instance)
{
struct u2phy_banks *u2_banks = &instance->u2_banks;
void __iomem *com = u2_banks->com;
@@ -449,24 +556,24 @@ static void phy_instance_power_off(struct mt65xx_u3phy *u3phy,
tmp |= P2C_RG_SESSEND;
writel(tmp, com + U3P_U2PHYDTM1);
- if (u3phy->pdata->avoid_rx_sen_degradation && index) {
+ if (tphy->pdata->avoid_rx_sen_degradation && index) {
tmp = readl(com + U3D_U2PHYDCR0);
tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON;
writel(tmp, com + U3D_U2PHYDCR0);
}
- dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
+ dev_dbg(tphy->dev, "%s(%d)\n", __func__, index);
}
-static void phy_instance_exit(struct mt65xx_u3phy *u3phy,
- struct mt65xx_phy_instance *instance)
+static void u2_phy_instance_exit(struct mtk_tphy *tphy,
+ struct mtk_phy_instance *instance)
{
struct u2phy_banks *u2_banks = &instance->u2_banks;
void __iomem *com = u2_banks->com;
u32 index = instance->index;
u32 tmp;
- if (u3phy->pdata->avoid_rx_sen_degradation && index) {
+ if (tphy->pdata->avoid_rx_sen_degradation && index) {
tmp = readl(com + U3D_U2PHYDCR0);
tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON;
writel(tmp, com + U3D_U2PHYDCR0);
@@ -477,109 +584,307 @@ static void phy_instance_exit(struct mt65xx_u3phy *u3phy,
}
}
-static void phy_v1_banks_init(struct mt65xx_u3phy *u3phy,
- struct mt65xx_phy_instance *instance)
+static void pcie_phy_instance_init(struct mtk_tphy *tphy,
+ struct mtk_phy_instance *instance)
+{
+ struct u3phy_banks *u3_banks = &instance->u3_banks;
+ u32 tmp;
+
+ if (tphy->pdata->version != MTK_PHY_V1)
+ return;
+
+ tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG0);
+ tmp &= ~(P3A_RG_XTAL_EXT_PE1H | P3A_RG_XTAL_EXT_PE2H);
+ tmp |= P3A_RG_XTAL_EXT_PE1H_VAL(0x2) | P3A_RG_XTAL_EXT_PE2H_VAL(0x2);
+ writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG0);
+
+ /* ref clk drive */
+ tmp = readl(u3_banks->phya + U3P_U3_PHYA_REG1);
+ tmp &= ~P3A_RG_CLKDRV_AMP;
+ tmp |= P3A_RG_CLKDRV_AMP_VAL(0x4);
+ writel(tmp, u3_banks->phya + U3P_U3_PHYA_REG1);
+
+ tmp = readl(u3_banks->phya + U3P_U3_PHYA_REG0);
+ tmp &= ~P3A_RG_CLKDRV_OFF;
+ tmp |= P3A_RG_CLKDRV_OFF_VAL(0x1);
+ writel(tmp, u3_banks->phya + U3P_U3_PHYA_REG0);
+
+ /* SSC delta -5000ppm */
+ tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG20);
+ tmp &= ~P3A_RG_PLL_DELTA1_PE2H;
+ tmp |= P3A_RG_PLL_DELTA1_PE2H_VAL(0x3c);
+ writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG20);
+
+ tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG25);
+ tmp &= ~P3A_RG_PLL_DELTA_PE2H;
+ tmp |= P3A_RG_PLL_DELTA_PE2H_VAL(0x36);
+ writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG25);
+
+ /* change pll BW 0.6M */
+ tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG5);
+ tmp &= ~(P3A_RG_PLL_BR_PE2H | P3A_RG_PLL_IC_PE2H);
+ tmp |= P3A_RG_PLL_BR_PE2H_VAL(0x1) | P3A_RG_PLL_IC_PE2H_VAL(0x1);
+ writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG5);
+
+ tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG4);
+ tmp &= ~(P3A_RG_PLL_DIVEN_PE2H | P3A_RG_PLL_BC_PE2H);
+ tmp |= P3A_RG_PLL_BC_PE2H_VAL(0x3);
+ writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG4);
+
+ tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG6);
+ tmp &= ~P3A_RG_PLL_IR_PE2H;
+ tmp |= P3A_RG_PLL_IR_PE2H_VAL(0x2);
+ writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG6);
+
+ tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG7);
+ tmp &= ~P3A_RG_PLL_BP_PE2H;
+ tmp |= P3A_RG_PLL_BP_PE2H_VAL(0xa);
+ writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG7);
+
+ /* Tx Detect Rx Timing: 10us -> 5us */
+ tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RXDET1);
+ tmp &= ~P3D_RG_RXDET_STB2_SET;
+ tmp |= P3D_RG_RXDET_STB2_SET_VAL(0x10);
+ writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RXDET1);
+
+ tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RXDET2);
+ tmp &= ~P3D_RG_RXDET_STB2_SET_P3;
+ tmp |= P3D_RG_RXDET_STB2_SET_P3_VAL(0x10);
+ writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RXDET2);
+
+ /* wait for PCIe subsys register to active */
+ usleep_range(2500, 3000);
+ dev_dbg(tphy->dev, "%s(%d)\n", __func__, instance->index);
+}
+
+static void pcie_phy_instance_power_on(struct mtk_tphy *tphy,
+ struct mtk_phy_instance *instance)
+{
+ struct u3phy_banks *bank = &instance->u3_banks;
+ u32 tmp;
+
+ tmp = readl(bank->chip + U3P_U3_CHIP_GPIO_CTLD);
+ tmp &= ~(P3C_FORCE_IP_SW_RST | P3C_MCU_BUS_CK_GATE_EN |
+ P3C_REG_IP_SW_RST);
+ writel(tmp, bank->chip + U3P_U3_CHIP_GPIO_CTLD);
+
+ tmp = readl(bank->chip + U3P_U3_CHIP_GPIO_CTLE);
+ tmp &= ~(P3C_RG_SWRST_U3_PHYD_FORCE_EN | P3C_RG_SWRST_U3_PHYD);
+ writel(tmp, bank->chip + U3P_U3_CHIP_GPIO_CTLE);
+}
+
+static void pcie_phy_instance_power_off(struct mtk_tphy *tphy,
+ struct mtk_phy_instance *instance)
+
+{
+ struct u3phy_banks *bank = &instance->u3_banks;
+ u32 tmp;
+
+ tmp = readl(bank->chip + U3P_U3_CHIP_GPIO_CTLD);
+ tmp |= P3C_FORCE_IP_SW_RST | P3C_REG_IP_SW_RST;
+ writel(tmp, bank->chip + U3P_U3_CHIP_GPIO_CTLD);
+
+ tmp = readl(bank->chip + U3P_U3_CHIP_GPIO_CTLE);
+ tmp |= P3C_RG_SWRST_U3_PHYD_FORCE_EN | P3C_RG_SWRST_U3_PHYD;
+ writel(tmp, bank->chip + U3P_U3_CHIP_GPIO_CTLE);
+}
+
+static void sata_phy_instance_init(struct mtk_tphy *tphy,
+ struct mtk_phy_instance *instance)
+{
+ struct u3phy_banks *u3_banks = &instance->u3_banks;
+ void __iomem *phyd = u3_banks->phyd;
+ u32 tmp;
+
+ /* charge current adjustment */
+ tmp = readl(phyd + ANA_RG_CTRL_SIGNAL6);
+ tmp &= ~(RG_CDR_BIRLTR_GEN1_MSK | RG_CDR_BC_GEN1_MSK);
+ tmp |= RG_CDR_BIRLTR_GEN1_VAL(0x6) | RG_CDR_BC_GEN1_VAL(0x1a);
+ writel(tmp, phyd + ANA_RG_CTRL_SIGNAL6);
+
+ tmp = readl(phyd + ANA_EQ_EYE_CTRL_SIGNAL4);
+ tmp &= ~RG_CDR_BIRLTD0_GEN1_MSK;
+ tmp |= RG_CDR_BIRLTD0_GEN1_VAL(0x18);
+ writel(tmp, phyd + ANA_EQ_EYE_CTRL_SIGNAL4);
+
+ tmp = readl(phyd + ANA_EQ_EYE_CTRL_SIGNAL5);
+ tmp &= ~RG_CDR_BIRLTD0_GEN3_MSK;
+ tmp |= RG_CDR_BIRLTD0_GEN3_VAL(0x06);
+ writel(tmp, phyd + ANA_EQ_EYE_CTRL_SIGNAL5);
+
+ tmp = readl(phyd + ANA_RG_CTRL_SIGNAL4);
+ tmp &= ~(RG_CDR_BICLTR_GEN1_MSK | RG_CDR_BR_GEN2_MSK);
+ tmp |= RG_CDR_BICLTR_GEN1_VAL(0x0c) | RG_CDR_BR_GEN2_VAL(0x07);
+ writel(tmp, phyd + ANA_RG_CTRL_SIGNAL4);
+
+ tmp = readl(phyd + PHYD_CTRL_SIGNAL_MODE4);
+ tmp &= ~(RG_CDR_BICLTD0_GEN1_MSK | RG_CDR_BICLTD1_GEN1_MSK);
+ tmp |= RG_CDR_BICLTD0_GEN1_VAL(0x08) | RG_CDR_BICLTD1_GEN1_VAL(0x02);
+ writel(tmp, phyd + PHYD_CTRL_SIGNAL_MODE4);
+
+ tmp = readl(phyd + PHYD_DESIGN_OPTION2);
+ tmp &= ~RG_LOCK_CNT_SEL_MSK;
+ tmp |= RG_LOCK_CNT_SEL_VAL(0x02);
+ writel(tmp, phyd + PHYD_DESIGN_OPTION2);
+
+ tmp = readl(phyd + PHYD_DESIGN_OPTION9);
+ tmp &= ~(RG_T2_MIN_MSK | RG_TG_MIN_MSK |
+ RG_T2_MAX_MSK | RG_TG_MAX_MSK);
+ tmp |= RG_T2_MIN_VAL(0x12) | RG_TG_MIN_VAL(0x04) |
+ RG_T2_MAX_VAL(0x31) | RG_TG_MAX_VAL(0x0e);
+ writel(tmp, phyd + PHYD_DESIGN_OPTION9);
+
+ tmp = readl(phyd + ANA_RG_CTRL_SIGNAL1);
+ tmp &= ~RG_IDRV_0DB_GEN1_MSK;
+ tmp |= RG_IDRV_0DB_GEN1_VAL(0x20);
+ writel(tmp, phyd + ANA_RG_CTRL_SIGNAL1);
+
+ tmp = readl(phyd + ANA_EQ_EYE_CTRL_SIGNAL1);
+ tmp &= ~RG_EQ_DLEQ_LFI_GEN1_MSK;
+ tmp |= RG_EQ_DLEQ_LFI_GEN1_VAL(0x03);
+ writel(tmp, phyd + ANA_EQ_EYE_CTRL_SIGNAL1);
+
+ dev_dbg(tphy->dev, "%s(%d)\n", __func__, instance->index);
+}
+
+static void phy_v1_banks_init(struct mtk_tphy *tphy,
+ struct mtk_phy_instance *instance)
{
struct u2phy_banks *u2_banks = &instance->u2_banks;
struct u3phy_banks *u3_banks = &instance->u3_banks;
- if (instance->type == PHY_TYPE_USB2) {
+ switch (instance->type) {
+ case PHY_TYPE_USB2:
u2_banks->misc = NULL;
- u2_banks->fmreg = u3phy->sif_base + SSUSB_SIFSLV_V1_U2FREQ;
+ u2_banks->fmreg = tphy->sif_base + SSUSB_SIFSLV_V1_U2FREQ;
u2_banks->com = instance->port_base + SSUSB_SIFSLV_V1_U2PHY_COM;
- } else if (instance->type == PHY_TYPE_USB3) {
- u3_banks->spllc = u3phy->sif_base + SSUSB_SIFSLV_V1_SPLLC;
+ break;
+ case PHY_TYPE_USB3:
+ case PHY_TYPE_PCIE:
+ u3_banks->spllc = tphy->sif_base + SSUSB_SIFSLV_V1_SPLLC;
u3_banks->chip = NULL;
u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V1_U3PHYD;
u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V1_U3PHYA;
+ break;
+ case PHY_TYPE_SATA:
+ u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V1_U3PHYD;
+ break;
+ default:
+ dev_err(tphy->dev, "incompatible PHY type\n");
+ return;
}
}
-static void phy_v2_banks_init(struct mt65xx_u3phy *u3phy,
- struct mt65xx_phy_instance *instance)
+static void phy_v2_banks_init(struct mtk_tphy *tphy,
+ struct mtk_phy_instance *instance)
{
struct u2phy_banks *u2_banks = &instance->u2_banks;
struct u3phy_banks *u3_banks = &instance->u3_banks;
- if (instance->type == PHY_TYPE_USB2) {
+ switch (instance->type) {
+ case PHY_TYPE_USB2:
u2_banks->misc = instance->port_base + SSUSB_SIFSLV_V2_MISC;
u2_banks->fmreg = instance->port_base + SSUSB_SIFSLV_V2_U2FREQ;
u2_banks->com = instance->port_base + SSUSB_SIFSLV_V2_U2PHY_COM;
- } else if (instance->type == PHY_TYPE_USB3) {
+ break;
+ case PHY_TYPE_USB3:
+ case PHY_TYPE_PCIE:
u3_banks->spllc = instance->port_base + SSUSB_SIFSLV_V2_SPLLC;
u3_banks->chip = instance->port_base + SSUSB_SIFSLV_V2_CHIP;
u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V2_U3PHYD;
u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V2_U3PHYA;
+ break;
+ default:
+ dev_err(tphy->dev, "incompatible PHY type\n");
+ return;
}
}
-static int mt65xx_phy_init(struct phy *phy)
+static int mtk_phy_init(struct phy *phy)
{
- struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
- struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
+ struct mtk_phy_instance *instance = phy_get_drvdata(phy);
+ struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
int ret;
- ret = clk_prepare_enable(u3phy->u3phya_ref);
+ ret = clk_prepare_enable(tphy->u3phya_ref);
if (ret) {
- dev_err(u3phy->dev, "failed to enable u3phya_ref\n");
+ dev_err(tphy->dev, "failed to enable u3phya_ref\n");
return ret;
}
ret = clk_prepare_enable(instance->ref_clk);
if (ret) {
- dev_err(u3phy->dev, "failed to enable ref_clk\n");
+ dev_err(tphy->dev, "failed to enable ref_clk\n");
return ret;
}
- if (instance->type == PHY_TYPE_USB2)
- phy_instance_init(u3phy, instance);
- else
- u3_phy_instance_init(u3phy, instance);
+ switch (instance->type) {
+ case PHY_TYPE_USB2:
+ u2_phy_instance_init(tphy, instance);
+ break;
+ case PHY_TYPE_USB3:
+ u3_phy_instance_init(tphy, instance);
+ break;
+ case PHY_TYPE_PCIE:
+ pcie_phy_instance_init(tphy, instance);
+ break;
+ case PHY_TYPE_SATA:
+ sata_phy_instance_init(tphy, instance);
+ break;
+ default:
+ dev_err(tphy->dev, "incompatible PHY type\n");
+ return -EINVAL;
+ }
return 0;
}
-static int mt65xx_phy_power_on(struct phy *phy)
+static int mtk_phy_power_on(struct phy *phy)
{
- struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
- struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
+ struct mtk_phy_instance *instance = phy_get_drvdata(phy);
+ struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
if (instance->type == PHY_TYPE_USB2) {
- phy_instance_power_on(u3phy, instance);
- hs_slew_rate_calibrate(u3phy, instance);
+ u2_phy_instance_power_on(tphy, instance);
+ hs_slew_rate_calibrate(tphy, instance);
+ } else if (instance->type == PHY_TYPE_PCIE) {
+ pcie_phy_instance_power_on(tphy, instance);
}
+
return 0;
}
-static int mt65xx_phy_power_off(struct phy *phy)
+static int mtk_phy_power_off(struct phy *phy)
{
- struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
- struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
+ struct mtk_phy_instance *instance = phy_get_drvdata(phy);
+ struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
if (instance->type == PHY_TYPE_USB2)
- phy_instance_power_off(u3phy, instance);
+ u2_phy_instance_power_off(tphy, instance);
+ else if (instance->type == PHY_TYPE_PCIE)
+ pcie_phy_instance_power_off(tphy, instance);
return 0;
}
-static int mt65xx_phy_exit(struct phy *phy)
+static int mtk_phy_exit(struct phy *phy)
{
- struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
- struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
+ struct mtk_phy_instance *instance = phy_get_drvdata(phy);
+ struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
if (instance->type == PHY_TYPE_USB2)
- phy_instance_exit(u3phy, instance);
+ u2_phy_instance_exit(tphy, instance);
clk_disable_unprepare(instance->ref_clk);
- clk_disable_unprepare(u3phy->u3phya_ref);
+ clk_disable_unprepare(tphy->u3phya_ref);
return 0;
}
-static struct phy *mt65xx_phy_xlate(struct device *dev,
+static struct phy *mtk_phy_xlate(struct device *dev,
struct of_phandle_args *args)
{
- struct mt65xx_u3phy *u3phy = dev_get_drvdata(dev);
- struct mt65xx_phy_instance *instance = NULL;
+ struct mtk_tphy *tphy = dev_get_drvdata(dev);
+ struct mtk_phy_instance *instance = NULL;
struct device_node *phy_np = args->np;
int index;
@@ -588,9 +893,9 @@ static struct phy *mt65xx_phy_xlate(struct device *dev,
return ERR_PTR(-EINVAL);
}
- for (index = 0; index < u3phy->nphys; index++)
- if (phy_np == u3phy->phys[index]->phy->dev.of_node) {
- instance = u3phy->phys[index];
+ for (index = 0; index < tphy->nphys; index++)
+ if (phy_np == tphy->phys[index]->phy->dev.of_node) {
+ instance = tphy->phys[index];
break;
}
@@ -601,15 +906,17 @@ static struct phy *mt65xx_phy_xlate(struct device *dev,
instance->type = args->args[0];
if (!(instance->type == PHY_TYPE_USB2 ||
- instance->type == PHY_TYPE_USB3)) {
+ instance->type == PHY_TYPE_USB3 ||
+ instance->type == PHY_TYPE_PCIE ||
+ instance->type == PHY_TYPE_SATA)) {
dev_err(dev, "unsupported device type: %d\n", instance->type);
return ERR_PTR(-EINVAL);
}
- if (u3phy->pdata->version == MT_PHY_V1) {
- phy_v1_banks_init(u3phy, instance);
- } else if (u3phy->pdata->version == MT_PHY_V2) {
- phy_v2_banks_init(u3phy, instance);
+ if (tphy->pdata->version == MTK_PHY_V1) {
+ phy_v1_banks_init(tphy, instance);
+ } else if (tphy->pdata->version == MTK_PHY_V2) {
+ phy_v2_banks_init(tphy, instance);
} else {
dev_err(dev, "phy version is not supported\n");
return ERR_PTR(-EINVAL);
@@ -618,38 +925,40 @@ static struct phy *mt65xx_phy_xlate(struct device *dev,
return instance->phy;
}
-static const struct phy_ops mt65xx_u3phy_ops = {
- .init = mt65xx_phy_init,
- .exit = mt65xx_phy_exit,
- .power_on = mt65xx_phy_power_on,
- .power_off = mt65xx_phy_power_off,
+static const struct phy_ops mtk_tphy_ops = {
+ .init = mtk_phy_init,
+ .exit = mtk_phy_exit,
+ .power_on = mtk_phy_power_on,
+ .power_off = mtk_phy_power_off,
.owner = THIS_MODULE,
};
-static const struct mt65xx_phy_pdata mt2701_pdata = {
+static const struct mtk_phy_pdata tphy_v1_pdata = {
.avoid_rx_sen_degradation = false,
- .version = MT_PHY_V1,
+ .version = MTK_PHY_V1,
};
-static const struct mt65xx_phy_pdata mt2712_pdata = {
+static const struct mtk_phy_pdata tphy_v2_pdata = {
.avoid_rx_sen_degradation = false,
- .version = MT_PHY_V2,
+ .version = MTK_PHY_V2,
};
-static const struct mt65xx_phy_pdata mt8173_pdata = {
+static const struct mtk_phy_pdata mt8173_pdata = {
.avoid_rx_sen_degradation = true,
- .version = MT_PHY_V1,
+ .version = MTK_PHY_V1,
};
-static const struct of_device_id mt65xx_u3phy_id_table[] = {
- { .compatible = "mediatek,mt2701-u3phy", .data = &mt2701_pdata },
- { .compatible = "mediatek,mt2712-u3phy", .data = &mt2712_pdata },
+static const struct of_device_id mtk_tphy_id_table[] = {
+ { .compatible = "mediatek,mt2701-u3phy", .data = &tphy_v1_pdata },
+ { .compatible = "mediatek,mt2712-u3phy", .data = &tphy_v2_pdata },
{ .compatible = "mediatek,mt8173-u3phy", .data = &mt8173_pdata },
+ { .compatible = "mediatek,generic-tphy-v1", .data = &tphy_v1_pdata },
+ { .compatible = "mediatek,generic-tphy-v2", .data = &tphy_v2_pdata },
{ },
};
-MODULE_DEVICE_TABLE(of, mt65xx_u3phy_id_table);
+MODULE_DEVICE_TABLE(of, mtk_tphy_id_table);
-static int mt65xx_u3phy_probe(struct platform_device *pdev)
+static int mtk_tphy_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
struct device *dev = &pdev->dev;
@@ -657,50 +966,50 @@ static int mt65xx_u3phy_probe(struct platform_device *pdev)
struct device_node *child_np;
struct phy_provider *provider;
struct resource *sif_res;
- struct mt65xx_u3phy *u3phy;
+ struct mtk_tphy *tphy;
struct resource res;
int port, retval;
- match = of_match_node(mt65xx_u3phy_id_table, pdev->dev.of_node);
+ match = of_match_node(mtk_tphy_id_table, pdev->dev.of_node);
if (!match)
return -EINVAL;
- u3phy = devm_kzalloc(dev, sizeof(*u3phy), GFP_KERNEL);
- if (!u3phy)
+ tphy = devm_kzalloc(dev, sizeof(*tphy), GFP_KERNEL);
+ if (!tphy)
return -ENOMEM;
- u3phy->pdata = match->data;
- u3phy->nphys = of_get_child_count(np);
- u3phy->phys = devm_kcalloc(dev, u3phy->nphys,
- sizeof(*u3phy->phys), GFP_KERNEL);
- if (!u3phy->phys)
+ tphy->pdata = match->data;
+ tphy->nphys = of_get_child_count(np);
+ tphy->phys = devm_kcalloc(dev, tphy->nphys,
+ sizeof(*tphy->phys), GFP_KERNEL);
+ if (!tphy->phys)
return -ENOMEM;
- u3phy->dev = dev;
- platform_set_drvdata(pdev, u3phy);
+ tphy->dev = dev;
+ platform_set_drvdata(pdev, tphy);
- if (u3phy->pdata->version == MT_PHY_V1) {
+ if (tphy->pdata->version == MTK_PHY_V1) {
/* get banks shared by multiple phys */
sif_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- u3phy->sif_base = devm_ioremap_resource(dev, sif_res);
- if (IS_ERR(u3phy->sif_base)) {
+ tphy->sif_base = devm_ioremap_resource(dev, sif_res);
+ if (IS_ERR(tphy->sif_base)) {
dev_err(dev, "failed to remap sif regs\n");
- return PTR_ERR(u3phy->sif_base);
+ return PTR_ERR(tphy->sif_base);
}
}
/* it's deprecated, make it optional for backward compatibility */
- u3phy->u3phya_ref = devm_clk_get(dev, "u3phya_ref");
- if (IS_ERR(u3phy->u3phya_ref)) {
- if (PTR_ERR(u3phy->u3phya_ref) == -EPROBE_DEFER)
+ tphy->u3phya_ref = devm_clk_get(dev, "u3phya_ref");
+ if (IS_ERR(tphy->u3phya_ref)) {
+ if (PTR_ERR(tphy->u3phya_ref) == -EPROBE_DEFER)
return -EPROBE_DEFER;
- u3phy->u3phya_ref = NULL;
+ tphy->u3phya_ref = NULL;
}
port = 0;
for_each_child_of_node(np, child_np) {
- struct mt65xx_phy_instance *instance;
+ struct mtk_phy_instance *instance;
struct phy *phy;
instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
@@ -709,9 +1018,9 @@ static int mt65xx_u3phy_probe(struct platform_device *pdev)
goto put_child;
}
- u3phy->phys[port] = instance;
+ tphy->phys[port] = instance;
- phy = devm_phy_create(dev, child_np, &mt65xx_u3phy_ops);
+ phy = devm_phy_create(dev, child_np, &mtk_tphy_ops);
if (IS_ERR(phy)) {
dev_err(dev, "failed to create phy\n");
retval = PTR_ERR(phy);
@@ -738,7 +1047,7 @@ static int mt65xx_u3phy_probe(struct platform_device *pdev)
port++;
/* if deprecated clock is provided, ignore instance's one */
- if (u3phy->u3phya_ref)
+ if (tphy->u3phya_ref)
continue;
instance->ref_clk = devm_clk_get(&phy->dev, "ref");
@@ -749,7 +1058,7 @@ static int mt65xx_u3phy_probe(struct platform_device *pdev)
}
}
- provider = devm_of_phy_provider_register(dev, mt65xx_phy_xlate);
+ provider = devm_of_phy_provider_register(dev, mtk_phy_xlate);
return PTR_ERR_OR_ZERO(provider);
put_child:
@@ -757,16 +1066,16 @@ put_child:
return retval;
}
-static struct platform_driver mt65xx_u3phy_driver = {
- .probe = mt65xx_u3phy_probe,
+static struct platform_driver mtk_tphy_driver = {
+ .probe = mtk_tphy_probe,
.driver = {
- .name = "mt65xx-u3phy",
- .of_match_table = mt65xx_u3phy_id_table,
+ .name = "mtk-tphy",
+ .of_match_table = mtk_tphy_id_table,
},
};
-module_platform_driver(mt65xx_u3phy_driver);
+module_platform_driver(mtk_tphy_driver);
MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>");
-MODULE_DESCRIPTION("mt65xx USB PHY driver");
+MODULE_DESCRIPTION("MediaTek T-PHY driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/motorola/phy-cpcap-usb.c b/drivers/phy/motorola/phy-cpcap-usb.c
index 9b63efa..accaaac 100644
--- a/drivers/phy/motorola/phy-cpcap-usb.c
+++ b/drivers/phy/motorola/phy-cpcap-usb.c
@@ -506,7 +506,7 @@ static void cpcap_usb_init_optional_gpios(struct cpcap_phy_ddata *ddata)
if (IS_ERR(ddata->gpio[i])) {
dev_info(ddata->dev, "no mode change GPIO%i: %li\n",
i, PTR_ERR(ddata->gpio[i]));
- ddata->gpio[i] = NULL;
+ ddata->gpio[i] = NULL;
}
}
}
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 78ca628..e17f035 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -59,6 +59,7 @@
#define QSERDES_COM_PLL_RCTRL_MODE1 0x088
#define QSERDES_COM_PLL_CCTRL_MODE0 0x090
#define QSERDES_COM_PLL_CCTRL_MODE1 0x094
+#define QSERDES_COM_BIAS_EN_CTRL_BY_PSM 0x0a8
#define QSERDES_COM_SYSCLK_EN_SEL 0x0ac
#define QSERDES_COM_RESETSM_CNTRL 0x0b4
#define QSERDES_COM_RESTRIM_CTRL 0x0bc
@@ -143,6 +144,11 @@
#define QPHY_LOCK_DETECT_CONFIG3 0x88
#define QPHY_PWRUP_RESET_DLY_TIME_AUXCLK 0xa0
#define QPHY_LP_WAKEUP_DLY_TIME_AUXCLK 0xa4
+#define QPHY_PLL_LOCK_CHK_DLY_TIME_AUXCLK_LSB 0x1A8
+#define QPHY_OSC_DTCT_ACTIONS 0x1AC
+#define QPHY_RX_SIGDET_LVL 0x1D8
+#define QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB 0x1DC
+#define QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB 0x1E0
/* QPHY_SW_RESET bit */
#define SW_RESET BIT(0)
@@ -382,6 +388,85 @@ static const struct qmp_phy_init_tbl msm8996_usb3_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG2, 0x08),
};
+static const struct qmp_phy_init_tbl ipq8074_pcie_serdes_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x18),
+ QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10),
+ QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0xf),
+ QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x1),
+ QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x0),
+ QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0x1f),
+ QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x6),
+ QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0xf),
+ QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x0),
+ QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x1),
+ QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0xa),
+ QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0xa),
+ QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0xa),
+ QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
+ QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x3),
+ QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
+ QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
+ QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x0),
+ QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0xD),
+ QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xD04),
+ QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x33),
+ QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x2),
+ QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1f),
+ QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0xb),
+ QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
+ QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x0),
+ QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
+ QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CTRL_BY_PSM, 0x1),
+ QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0xa),
+ QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x1),
+ QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
+ QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x1),
+ QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x2),
+ QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x0),
+ QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0x2f),
+ QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x19),
+ QMP_PHY_INIT_CFG(QSERDES_COM_CLK_EP_DIV, 0x19),
+ QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x7),
+};
+
+static const struct qmp_phy_init_tbl ipq8074_pcie_tx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
+ QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x6),
+ QMP_PHY_INIT_CFG(QSERDES_TX_RES_CODE_LANE_OFFSET, 0x2),
+ QMP_PHY_INIT_CFG(QSERDES_TX_RCV_DETECT_LVL_2, 0x12),
+};
+
+static const struct qmp_phy_init_tbl ipq8074_pcie_rx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_ENABLES, 0x1c),
+ QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x1),
+ QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x0),
+ QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xdb),
+ QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
+ QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x4),
+ QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN_HALF, 0x4),
+};
+
+static const struct qmp_phy_init_tbl ipq8074_pcie_pcs_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_ENDPOINT_REFCLK_DRIVE, 0x4),
+ QMP_PHY_INIT_CFG(QPHY_OSC_DTCT_ACTIONS, 0x0),
+ QMP_PHY_INIT_CFG(QPHY_PWRUP_RESET_DLY_TIME_AUXCLK, 0x40),
+ QMP_PHY_INIT_CFG(QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x0),
+ QMP_PHY_INIT_CFG(QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB, 0x40),
+ QMP_PHY_INIT_CFG(QPHY_PLL_LOCK_CHK_DLY_TIME_AUXCLK_LSB, 0x0),
+ QMP_PHY_INIT_CFG(QPHY_LP_WAKEUP_DLY_TIME_AUXCLK, 0x40),
+ QMP_PHY_INIT_CFG_L(QPHY_PLL_LOCK_CHK_DLY_TIME, 0x73),
+ QMP_PHY_INIT_CFG(QPHY_RX_SIGDET_LVL, 0x99),
+ QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M6DB_V0, 0x15),
+ QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M3P5DB_V0, 0xe),
+ QMP_PHY_INIT_CFG_L(QPHY_SW_RESET, 0x0),
+ QMP_PHY_INIT_CFG_L(QPHY_START_CTRL, 0x3),
+};
+
/* struct qmp_phy_cfg - per-PHY initialization config */
struct qmp_phy_cfg {
/* phy-type - PCIE/UFS/USB */
@@ -580,6 +665,42 @@ static const struct qmp_phy_cfg msm8996_usb3phy_cfg = {
.mask_pcs_ready = PHYSTATUS,
};
+/* list of resets */
+static const char * const ipq8074_pciephy_reset_l[] = {
+ "phy", "common",
+};
+
+static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
+ .type = PHY_TYPE_PCIE,
+ .nlanes = 1,
+
+ .serdes_tbl = ipq8074_pcie_serdes_tbl,
+ .serdes_tbl_num = ARRAY_SIZE(ipq8074_pcie_serdes_tbl),
+ .tx_tbl = ipq8074_pcie_tx_tbl,
+ .tx_tbl_num = ARRAY_SIZE(ipq8074_pcie_tx_tbl),
+ .rx_tbl = ipq8074_pcie_rx_tbl,
+ .rx_tbl_num = ARRAY_SIZE(ipq8074_pcie_rx_tbl),
+ .pcs_tbl = ipq8074_pcie_pcs_tbl,
+ .pcs_tbl_num = ARRAY_SIZE(ipq8074_pcie_pcs_tbl),
+ .clk_list = NULL,
+ .num_clks = 0,
+ .reset_list = ipq8074_pciephy_reset_l,
+ .num_resets = ARRAY_SIZE(ipq8074_pciephy_reset_l),
+ .vreg_list = NULL,
+ .num_vregs = 0,
+ .regs = pciephy_regs_layout,
+
+ .start_ctrl = SERDES_START | PCS_START,
+ .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
+ .mask_pcs_ready = PHYSTATUS,
+
+ .has_phy_com_ctrl = false,
+ .has_lane_rst = false,
+ .has_pwrdn_delay = true,
+ .pwrdn_delay_min = 995, /* us */
+ .pwrdn_delay_max = 1005, /* us */
+};
+
static void qcom_qmp_phy_configure(void __iomem *base,
const unsigned int *regs,
const struct qmp_phy_init_tbl tbl[],
@@ -654,8 +775,6 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
if (ret) {
dev_err(qmp->dev, "%s reset deassert failed\n",
qmp->cfg->reset_list[i]);
- while (--i >= 0)
- reset_control_assert(qmp->resets[i]);
goto err_rst;
}
}
@@ -684,7 +803,7 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
if (ret) {
dev_err(qmp->dev,
"phy common block init timed-out\n");
- goto err_com_init;
+ goto err_rst;
}
}
@@ -692,11 +811,11 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
return 0;
-err_com_init:
+err_rst:
while (--i >= 0)
reset_control_assert(qmp->resets[i]);
-err_rst:
mutex_unlock(&qmp->phy_mutex);
+
return ret;
}
@@ -749,14 +868,13 @@ static int qcom_qmp_phy_init(struct phy *phy)
if (ret) {
dev_err(qmp->dev, "failed to enable %s clk, err=%d\n",
qmp->cfg->clk_list[i], ret);
- while (--i >= 0)
- clk_disable_unprepare(qmp->clks[i]);
+ goto err_clk;
}
}
ret = qcom_qmp_phy_com_init(qmp);
if (ret)
- goto err_com_init;
+ goto err_clk;
if (cfg->has_lane_rst) {
ret = reset_control_deassert(qphy->lane_rst);
@@ -804,7 +922,7 @@ err_pcs_ready:
reset_control_assert(qphy->lane_rst);
err_lane_rst:
qcom_qmp_phy_com_exit(qmp);
-err_com_init:
+err_clk:
while (--i >= 0)
clk_disable_unprepare(qmp->clks[i]);
@@ -925,29 +1043,28 @@ static int qcom_qmp_phy_clk_init(struct device *dev)
* clk | +-------+ | +-----+
* +---------------+
*/
-static int phy_pipe_clk_register(struct qcom_qmp *qmp, int id)
+static int phy_pipe_clk_register(struct qcom_qmp *qmp, struct device_node *np)
{
- char name[24];
struct clk_fixed_rate *fixed;
struct clk_init_data init = { };
+ int ret;
- switch (qmp->cfg->type) {
- case PHY_TYPE_USB3:
- snprintf(name, sizeof(name), "usb3_phy_pipe_clk_src");
- break;
- case PHY_TYPE_PCIE:
- snprintf(name, sizeof(name), "pcie_%d_pipe_clk_src", id);
- break;
- default:
+ if ((qmp->cfg->type != PHY_TYPE_USB3) &&
+ (qmp->cfg->type != PHY_TYPE_PCIE)) {
/* not all phys register pipe clocks, so return success */
return 0;
}
+ ret = of_property_read_string(np, "clock-output-names", &init.name);
+ if (ret) {
+ dev_err(qmp->dev, "%s: No clock-output-names\n", np->name);
+ return ret;
+ }
+
fixed = devm_kzalloc(qmp->dev, sizeof(*fixed), GFP_KERNEL);
if (!fixed)
return -ENOMEM;
- init.name = name;
init.ops = &clk_fixed_rate_ops;
/* controllers using QMP phys use 125MHz pipe clock interface */
@@ -1049,6 +1166,9 @@ static const struct of_device_id qcom_qmp_phy_of_match_table[] = {
}, {
.compatible = "qcom,msm8996-qmp-usb3-phy",
.data = &msm8996_usb3phy_cfg,
+ }, {
+ .compatible = "qcom,ipq8074-qmp-pcie-phy",
+ .data = &ipq8074_pciephy_cfg,
},
{ },
};
@@ -1122,7 +1242,7 @@ static int qcom_qmp_phy_probe(struct platform_device *pdev)
* Register the pipe clock provided by phy.
* See function description to see details of this pipe clock.
*/
- ret = phy_pipe_clk_register(qmp, id);
+ ret = phy_pipe_clk_register(qmp, child);
if (ret) {
dev_err(qmp->dev,
"failed to register pipe clock source\n");
diff --git a/drivers/phy/ralink/Kconfig b/drivers/phy/ralink/Kconfig
new file mode 100644
index 0000000..b17635b
--- /dev/null
+++ b/drivers/phy/ralink/Kconfig
@@ -0,0 +1,11 @@
+#
+# PHY drivers for Ralink platforms.
+#
+config PHY_RALINK_USB
+ tristate "Ralink USB PHY driver"
+ depends on RALINK || COMPILE_TEST
+ select GENERIC_PHY
+ select MFD_SYSCON
+ help
+ This option enables support for the Ralink USB PHY found inside
+ RT3352, MT7620, MT7628 and MT7688.
diff --git a/drivers/phy/ralink/Makefile b/drivers/phy/ralink/Makefile
new file mode 100644
index 0000000..5c9e326
--- /dev/null
+++ b/drivers/phy/ralink/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_PHY_RALINK_USB) += phy-ralink-usb.o
diff --git a/drivers/phy/ralink/phy-ralink-usb.c b/drivers/phy/ralink/phy-ralink-usb.c
new file mode 100644
index 0000000..4fea31f
--- /dev/null
+++ b/drivers/phy/ralink/phy-ralink-usb.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2017 John Crispin <john@phrozen.org>
+ *
+ * Based on code from
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of_platform.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+
+#define RT_SYSC_REG_SYSCFG1 0x014
+#define RT_SYSC_REG_CLKCFG1 0x030
+#define RT_SYSC_REG_USB_PHY_CFG 0x05c
+
+#define OFS_U2_PHY_AC0 0x800
+#define OFS_U2_PHY_AC1 0x804
+#define OFS_U2_PHY_AC2 0x808
+#define OFS_U2_PHY_ACR0 0x810
+#define OFS_U2_PHY_ACR1 0x814
+#define OFS_U2_PHY_ACR2 0x818
+#define OFS_U2_PHY_ACR3 0x81C
+#define OFS_U2_PHY_ACR4 0x820
+#define OFS_U2_PHY_AMON0 0x824
+#define OFS_U2_PHY_DCR0 0x860
+#define OFS_U2_PHY_DCR1 0x864
+#define OFS_U2_PHY_DTM0 0x868
+#define OFS_U2_PHY_DTM1 0x86C
+
+#define RT_RSTCTRL_UDEV BIT(25)
+#define RT_RSTCTRL_UHST BIT(22)
+#define RT_SYSCFG1_USB0_HOST_MODE BIT(10)
+
+#define MT7620_CLKCFG1_UPHY0_CLK_EN BIT(25)
+#define MT7620_CLKCFG1_UPHY1_CLK_EN BIT(22)
+#define RT_CLKCFG1_UPHY1_CLK_EN BIT(20)
+#define RT_CLKCFG1_UPHY0_CLK_EN BIT(18)
+
+#define USB_PHY_UTMI_8B60M BIT(1)
+#define UDEV_WAKEUP BIT(0)
+
+struct ralink_usb_phy {
+ struct reset_control *rstdev;
+ struct reset_control *rsthost;
+ u32 clk;
+ struct phy *phy;
+ void __iomem *base;
+ struct regmap *sysctl;
+};
+
+static void u2_phy_w32(struct ralink_usb_phy *phy, u32 val, u32 reg)
+{
+ writel(val, phy->base + reg);
+}
+
+static u32 u2_phy_r32(struct ralink_usb_phy *phy, u32 reg)
+{
+ return readl(phy->base + reg);
+}
+
+static void ralink_usb_phy_init(struct ralink_usb_phy *phy)
+{
+ u2_phy_r32(phy, OFS_U2_PHY_AC2);
+ u2_phy_r32(phy, OFS_U2_PHY_ACR0);
+ u2_phy_r32(phy, OFS_U2_PHY_DCR0);
+
+ u2_phy_w32(phy, 0x00ffff02, OFS_U2_PHY_DCR0);
+ u2_phy_r32(phy, OFS_U2_PHY_DCR0);
+ u2_phy_w32(phy, 0x00555502, OFS_U2_PHY_DCR0);
+ u2_phy_r32(phy, OFS_U2_PHY_DCR0);
+ u2_phy_w32(phy, 0x00aaaa02, OFS_U2_PHY_DCR0);
+ u2_phy_r32(phy, OFS_U2_PHY_DCR0);
+ u2_phy_w32(phy, 0x00000402, OFS_U2_PHY_DCR0);
+ u2_phy_r32(phy, OFS_U2_PHY_DCR0);
+ u2_phy_w32(phy, 0x0048086a, OFS_U2_PHY_AC0);
+ u2_phy_w32(phy, 0x4400001c, OFS_U2_PHY_AC1);
+ u2_phy_w32(phy, 0xc0200000, OFS_U2_PHY_ACR3);
+ u2_phy_w32(phy, 0x02000000, OFS_U2_PHY_DTM0);
+}
+
+static int ralink_usb_phy_power_on(struct phy *_phy)
+{
+ struct ralink_usb_phy *phy = phy_get_drvdata(_phy);
+ u32 t;
+
+ /* enable the phy */
+ regmap_update_bits(phy->sysctl, RT_SYSC_REG_CLKCFG1,
+ phy->clk, phy->clk);
+
+ /* setup host mode */
+ regmap_update_bits(phy->sysctl, RT_SYSC_REG_SYSCFG1,
+ RT_SYSCFG1_USB0_HOST_MODE,
+ RT_SYSCFG1_USB0_HOST_MODE);
+
+ /* deassert the reset lines */
+ reset_control_deassert(phy->rsthost);
+ reset_control_deassert(phy->rstdev);
+
+ /*
+ * The SDK kernel had a delay of 100ms. however on device
+ * testing showed that 10ms is enough
+ */
+ mdelay(10);
+
+ if (phy->base)
+ ralink_usb_phy_init(phy);
+
+ /* print some status info */
+ regmap_read(phy->sysctl, RT_SYSC_REG_USB_PHY_CFG, &t);
+ dev_info(&phy->phy->dev, "remote usb device wakeup %s\n",
+ (t & UDEV_WAKEUP) ? ("enabled") : ("disabled"));
+ if (t & USB_PHY_UTMI_8B60M)
+ dev_info(&phy->phy->dev, "UTMI 8bit 60MHz\n");
+ else
+ dev_info(&phy->phy->dev, "UTMI 16bit 30MHz\n");
+
+ return 0;
+}
+
+static int ralink_usb_phy_power_off(struct phy *_phy)
+{
+ struct ralink_usb_phy *phy = phy_get_drvdata(_phy);
+
+ /* disable the phy */
+ regmap_update_bits(phy->sysctl, RT_SYSC_REG_CLKCFG1,
+ phy->clk, 0);
+
+ /* assert the reset lines */
+ reset_control_assert(phy->rstdev);
+ reset_control_assert(phy->rsthost);
+
+ return 0;
+}
+
+static struct phy_ops ralink_usb_phy_ops = {
+ .power_on = ralink_usb_phy_power_on,
+ .power_off = ralink_usb_phy_power_off,
+ .owner = THIS_MODULE,
+};
+
+static const struct of_device_id ralink_usb_phy_of_match[] = {
+ {
+ .compatible = "ralink,rt3352-usbphy",
+ .data = (void *)(uintptr_t)(RT_CLKCFG1_UPHY1_CLK_EN |
+ RT_CLKCFG1_UPHY0_CLK_EN)
+ },
+ {
+ .compatible = "mediatek,mt7620-usbphy",
+ .data = (void *)(uintptr_t)(MT7620_CLKCFG1_UPHY1_CLK_EN |
+ MT7620_CLKCFG1_UPHY0_CLK_EN)
+ },
+ {
+ .compatible = "mediatek,mt7628-usbphy",
+ .data = (void *)(uintptr_t)(MT7620_CLKCFG1_UPHY1_CLK_EN |
+ MT7620_CLKCFG1_UPHY0_CLK_EN) },
+ { },
+};
+MODULE_DEVICE_TABLE(of, ralink_usb_phy_of_match);
+
+static int ralink_usb_phy_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ struct phy_provider *phy_provider;
+ const struct of_device_id *match;
+ struct ralink_usb_phy *phy;
+
+ match = of_match_device(ralink_usb_phy_of_match, &pdev->dev);
+ if (!match)
+ return -ENODEV;
+
+ phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
+ if (!phy)
+ return -ENOMEM;
+
+ phy->clk = (uintptr_t)match->data;
+ phy->base = NULL;
+
+ phy->sysctl = syscon_regmap_lookup_by_phandle(dev->of_node, "ralink,sysctl");
+ if (IS_ERR(phy->sysctl)) {
+ dev_err(dev, "failed to get sysctl registers\n");
+ return PTR_ERR(phy->sysctl);
+ }
+
+ /* The MT7628 and MT7688 require extra setup of PHY registers. */
+ if (of_device_is_compatible(dev->of_node, "mediatek,mt7628-usbphy")) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ phy->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(phy->base)) {
+ dev_err(dev, "failed to remap register memory\n");
+ return PTR_ERR(phy->base);
+ }
+ }
+
+ phy->rsthost = devm_reset_control_get(&pdev->dev, "host");
+ if (IS_ERR(phy->rsthost)) {
+ dev_err(dev, "host reset is missing\n");
+ return PTR_ERR(phy->rsthost);
+ }
+
+ phy->rstdev = devm_reset_control_get(&pdev->dev, "device");
+ if (IS_ERR(phy->rstdev)) {
+ dev_err(dev, "device reset is missing\n");
+ return PTR_ERR(phy->rstdev);
+ }
+
+ phy->phy = devm_phy_create(dev, NULL, &ralink_usb_phy_ops);
+ if (IS_ERR(phy->phy)) {
+ dev_err(dev, "failed to create PHY\n");
+ return PTR_ERR(phy->phy);
+ }
+ phy_set_drvdata(phy->phy, phy);
+
+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+ return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static struct platform_driver ralink_usb_phy_driver = {
+ .probe = ralink_usb_phy_probe,
+ .driver = {
+ .of_match_table = ralink_usb_phy_of_match,
+ .name = "ralink-usb-phy",
+ }
+};
+module_platform_driver(ralink_usb_phy_driver);
+
+MODULE_DESCRIPTION("Ralink USB phy driver");
+MODULE_AUTHOR("John Crispin <john@phrozen.org>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index ef03308..ee7ce5e 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -172,6 +172,8 @@ struct rockchip_usb2phy_cfg {
* @vbus_attached: otg device vbus status.
* @bvalid_irq: IRQ number assigned for vbus valid rise detection.
* @ls_irq: IRQ number assigned for linestate detection.
+ * @otg_mux_irq: IRQ number which multiplex otg-id/otg-bvalid/linestate
+ * irqs to one irq in otg-port.
* @mutex: for register updating in sm_work.
* @chg_work: charge detect work.
* @otg_sm_work: OTG state machine work.
@@ -189,6 +191,7 @@ struct rockchip_usb2phy_port {
bool vbus_attached;
int bvalid_irq;
int ls_irq;
+ int otg_mux_irq;
struct mutex mutex;
struct delayed_work chg_work;
struct delayed_work otg_sm_work;
@@ -202,6 +205,7 @@ struct rockchip_usb2phy_port {
/**
* struct rockchip_usb2phy: usb2.0 phy driver data.
* @grf: General Register Files regmap.
+ * @usbgrf: USB General Register Files regmap.
* @clk: clock struct of phy input clk.
* @clk480m: clock struct of phy output clk.
* @clk_hw: clock struct of phy output clk management.
@@ -216,6 +220,7 @@ struct rockchip_usb2phy_port {
struct rockchip_usb2phy {
struct device *dev;
struct regmap *grf;
+ struct regmap *usbgrf;
struct clk *clk;
struct clk *clk480m;
struct clk_hw clk480m_hw;
@@ -227,7 +232,12 @@ struct rockchip_usb2phy {
struct rockchip_usb2phy_port ports[USB2PHY_NUM_PORTS];
};
-static inline int property_enable(struct rockchip_usb2phy *rphy,
+static inline struct regmap *get_reg_base(struct rockchip_usb2phy *rphy)
+{
+ return rphy->usbgrf == NULL ? rphy->grf : rphy->usbgrf;
+}
+
+static inline int property_enable(struct regmap *base,
const struct usb2phy_reg *reg, bool en)
{
unsigned int val, mask, tmp;
@@ -236,17 +246,17 @@ static inline int property_enable(struct rockchip_usb2phy *rphy,
mask = GENMASK(reg->bitend, reg->bitstart);
val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT);
- return regmap_write(rphy->grf, reg->offset, val);
+ return regmap_write(base, reg->offset, val);
}
-static inline bool property_enabled(struct rockchip_usb2phy *rphy,
+static inline bool property_enabled(struct regmap *base,
const struct usb2phy_reg *reg)
{
int ret;
unsigned int tmp, orig;
unsigned int mask = GENMASK(reg->bitend, reg->bitstart);
- ret = regmap_read(rphy->grf, reg->offset, &orig);
+ ret = regmap_read(base, reg->offset, &orig);
if (ret)
return false;
@@ -258,11 +268,12 @@ static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw)
{
struct rockchip_usb2phy *rphy =
container_of(hw, struct rockchip_usb2phy, clk480m_hw);
+ struct regmap *base = get_reg_base(rphy);
int ret;
/* turn on 480m clk output if it is off */
- if (!property_enabled(rphy, &rphy->phy_cfg->clkout_ctl)) {
- ret = property_enable(rphy, &rphy->phy_cfg->clkout_ctl, true);
+ if (!property_enabled(base, &rphy->phy_cfg->clkout_ctl)) {
+ ret = property_enable(base, &rphy->phy_cfg->clkout_ctl, true);
if (ret)
return ret;
@@ -277,17 +288,19 @@ static void rockchip_usb2phy_clk480m_unprepare(struct clk_hw *hw)
{
struct rockchip_usb2phy *rphy =
container_of(hw, struct rockchip_usb2phy, clk480m_hw);
+ struct regmap *base = get_reg_base(rphy);
/* turn off 480m clk output */
- property_enable(rphy, &rphy->phy_cfg->clkout_ctl, false);
+ property_enable(base, &rphy->phy_cfg->clkout_ctl, false);
}
static int rockchip_usb2phy_clk480m_prepared(struct clk_hw *hw)
{
struct rockchip_usb2phy *rphy =
container_of(hw, struct rockchip_usb2phy, clk480m_hw);
+ struct regmap *base = get_reg_base(rphy);
- return property_enabled(rphy, &rphy->phy_cfg->clkout_ctl);
+ return property_enabled(base, &rphy->phy_cfg->clkout_ctl);
}
static unsigned long
@@ -409,13 +422,13 @@ static int rockchip_usb2phy_init(struct phy *phy)
if (rport->mode != USB_DR_MODE_HOST &&
rport->mode != USB_DR_MODE_UNKNOWN) {
/* clear bvalid status and enable bvalid detect irq */
- ret = property_enable(rphy,
+ ret = property_enable(rphy->grf,
&rport->port_cfg->bvalid_det_clr,
true);
if (ret)
goto out;
- ret = property_enable(rphy,
+ ret = property_enable(rphy->grf,
&rport->port_cfg->bvalid_det_en,
true);
if (ret)
@@ -429,11 +442,13 @@ static int rockchip_usb2phy_init(struct phy *phy)
}
} else if (rport->port_id == USB2PHY_PORT_HOST) {
/* clear linestate and enable linestate detect irq */
- ret = property_enable(rphy, &rport->port_cfg->ls_det_clr, true);
+ ret = property_enable(rphy->grf,
+ &rport->port_cfg->ls_det_clr, true);
if (ret)
goto out;
- ret = property_enable(rphy, &rport->port_cfg->ls_det_en, true);
+ ret = property_enable(rphy->grf,
+ &rport->port_cfg->ls_det_en, true);
if (ret)
goto out;
@@ -449,6 +464,7 @@ static int rockchip_usb2phy_power_on(struct phy *phy)
{
struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
+ struct regmap *base = get_reg_base(rphy);
int ret;
dev_dbg(&rport->phy->dev, "port power on\n");
@@ -460,7 +476,7 @@ static int rockchip_usb2phy_power_on(struct phy *phy)
if (ret)
return ret;
- ret = property_enable(rphy, &rport->port_cfg->phy_sus, false);
+ ret = property_enable(base, &rport->port_cfg->phy_sus, false);
if (ret)
return ret;
@@ -475,6 +491,7 @@ static int rockchip_usb2phy_power_off(struct phy *phy)
{
struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
+ struct regmap *base = get_reg_base(rphy);
int ret;
dev_dbg(&rport->phy->dev, "port power off\n");
@@ -482,7 +499,7 @@ static int rockchip_usb2phy_power_off(struct phy *phy)
if (rport->suspended)
return 0;
- ret = property_enable(rphy, &rport->port_cfg->phy_sus, true);
+ ret = property_enable(base, &rport->port_cfg->phy_sus, true);
if (ret)
return ret;
@@ -526,11 +543,11 @@ static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)
bool vbus_attach, sch_work, notify_charger;
if (rport->utmi_avalid)
- vbus_attach =
- property_enabled(rphy, &rport->port_cfg->utmi_avalid);
+ vbus_attach = property_enabled(rphy->grf,
+ &rport->port_cfg->utmi_avalid);
else
- vbus_attach =
- property_enabled(rphy, &rport->port_cfg->utmi_bvalid);
+ vbus_attach = property_enabled(rphy->grf,
+ &rport->port_cfg->utmi_bvalid);
sch_work = false;
notify_charger = false;
@@ -650,22 +667,28 @@ static const char *chg_to_string(enum power_supply_type chg_type)
static void rockchip_chg_enable_dcd(struct rockchip_usb2phy *rphy,
bool en)
{
- property_enable(rphy, &rphy->phy_cfg->chg_det.rdm_pdwn_en, en);
- property_enable(rphy, &rphy->phy_cfg->chg_det.idp_src_en, en);
+ struct regmap *base = get_reg_base(rphy);
+
+ property_enable(base, &rphy->phy_cfg->chg_det.rdm_pdwn_en, en);
+ property_enable(base, &rphy->phy_cfg->chg_det.idp_src_en, en);
}
static void rockchip_chg_enable_primary_det(struct rockchip_usb2phy *rphy,
bool en)
{
- property_enable(rphy, &rphy->phy_cfg->chg_det.vdp_src_en, en);
- property_enable(rphy, &rphy->phy_cfg->chg_det.idm_sink_en, en);
+ struct regmap *base = get_reg_base(rphy);
+
+ property_enable(base, &rphy->phy_cfg->chg_det.vdp_src_en, en);
+ property_enable(base, &rphy->phy_cfg->chg_det.idm_sink_en, en);
}
static void rockchip_chg_enable_secondary_det(struct rockchip_usb2phy *rphy,
bool en)
{
- property_enable(rphy, &rphy->phy_cfg->chg_det.vdm_src_en, en);
- property_enable(rphy, &rphy->phy_cfg->chg_det.idp_sink_en, en);
+ struct regmap *base = get_reg_base(rphy);
+
+ property_enable(base, &rphy->phy_cfg->chg_det.vdm_src_en, en);
+ property_enable(base, &rphy->phy_cfg->chg_det.idp_sink_en, en);
}
#define CHG_DCD_POLL_TIME (100 * HZ / 1000)
@@ -677,6 +700,7 @@ static void rockchip_chg_detect_work(struct work_struct *work)
struct rockchip_usb2phy_port *rport =
container_of(work, struct rockchip_usb2phy_port, chg_work.work);
struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
+ struct regmap *base = get_reg_base(rphy);
bool is_dcd, tmout, vout;
unsigned long delay;
@@ -687,7 +711,7 @@ static void rockchip_chg_detect_work(struct work_struct *work)
if (!rport->suspended)
rockchip_usb2phy_power_off(rport->phy);
/* put the controller in non-driving mode */
- property_enable(rphy, &rphy->phy_cfg->chg_det.opmode, false);
+ property_enable(base, &rphy->phy_cfg->chg_det.opmode, false);
/* Start DCD processing stage 1 */
rockchip_chg_enable_dcd(rphy, true);
rphy->chg_state = USB_CHG_STATE_WAIT_FOR_DCD;
@@ -696,7 +720,8 @@ static void rockchip_chg_detect_work(struct work_struct *work)
break;
case USB_CHG_STATE_WAIT_FOR_DCD:
/* get data contact detection status */
- is_dcd = property_enabled(rphy, &rphy->phy_cfg->chg_det.dp_det);
+ is_dcd = property_enabled(rphy->grf,
+ &rphy->phy_cfg->chg_det.dp_det);
tmout = ++rphy->dcd_retries == CHG_DCD_MAX_RETRIES;
/* stage 2 */
if (is_dcd || tmout) {
@@ -713,7 +738,8 @@ static void rockchip_chg_detect_work(struct work_struct *work)
}
break;
case USB_CHG_STATE_DCD_DONE:
- vout = property_enabled(rphy, &rphy->phy_cfg->chg_det.cp_det);
+ vout = property_enabled(rphy->grf,
+ &rphy->phy_cfg->chg_det.cp_det);
rockchip_chg_enable_primary_det(rphy, false);
if (vout) {
/* Voltage Source on DM, Probe on DP */
@@ -734,7 +760,8 @@ static void rockchip_chg_detect_work(struct work_struct *work)
}
break;
case USB_CHG_STATE_PRIMARY_DONE:
- vout = property_enabled(rphy, &rphy->phy_cfg->chg_det.dcp_det);
+ vout = property_enabled(rphy->grf,
+ &rphy->phy_cfg->chg_det.dcp_det);
/* Turn off voltage source */
rockchip_chg_enable_secondary_det(rphy, false);
if (vout)
@@ -748,7 +775,7 @@ static void rockchip_chg_detect_work(struct work_struct *work)
/* fall through */
case USB_CHG_STATE_DETECTED:
/* put the controller in normal mode */
- property_enable(rphy, &rphy->phy_cfg->chg_det.opmode, true);
+ property_enable(base, &rphy->phy_cfg->chg_det.opmode, true);
rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
dev_info(&rport->phy->dev, "charger = %s\n",
chg_to_string(rphy->chg_type));
@@ -790,8 +817,7 @@ static void rockchip_usb2phy_sm_work(struct work_struct *work)
if (ret < 0)
goto next_schedule;
- ret = regmap_read(rphy->grf, rport->port_cfg->utmi_hstdet.offset,
- &uhd);
+ ret = regmap_read(rphy->grf, rport->port_cfg->utmi_hstdet.offset, &uhd);
if (ret < 0)
goto next_schedule;
@@ -845,8 +871,8 @@ static void rockchip_usb2phy_sm_work(struct work_struct *work)
* activate the linestate detection to get the next device
* plug-in irq.
*/
- property_enable(rphy, &rport->port_cfg->ls_det_clr, true);
- property_enable(rphy, &rport->port_cfg->ls_det_en, true);
+ property_enable(rphy->grf, &rport->port_cfg->ls_det_clr, true);
+ property_enable(rphy->grf, &rport->port_cfg->ls_det_en, true);
/*
* we don't need to rearm the delayed work when the phy port
@@ -869,14 +895,14 @@ static irqreturn_t rockchip_usb2phy_linestate_irq(int irq, void *data)
struct rockchip_usb2phy_port *rport = data;
struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
- if (!property_enabled(rphy, &rport->port_cfg->ls_det_st))
+ if (!property_enabled(rphy->grf, &rport->port_cfg->ls_det_st))
return IRQ_NONE;
mutex_lock(&rport->mutex);
/* disable linestate detect irq and clear its status */
- property_enable(rphy, &rport->port_cfg->ls_det_en, false);
- property_enable(rphy, &rport->port_cfg->ls_det_clr, true);
+ property_enable(rphy->grf, &rport->port_cfg->ls_det_en, false);
+ property_enable(rphy->grf, &rport->port_cfg->ls_det_clr, true);
mutex_unlock(&rport->mutex);
@@ -896,13 +922,13 @@ static irqreturn_t rockchip_usb2phy_bvalid_irq(int irq, void *data)
struct rockchip_usb2phy_port *rport = data;
struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
- if (!property_enabled(rphy, &rport->port_cfg->bvalid_det_st))
+ if (!property_enabled(rphy->grf, &rport->port_cfg->bvalid_det_st))
return IRQ_NONE;
mutex_lock(&rport->mutex);
/* clear bvalid detect irq pending status */
- property_enable(rphy, &rport->port_cfg->bvalid_det_clr, true);
+ property_enable(rphy->grf, &rport->port_cfg->bvalid_det_clr, true);
mutex_unlock(&rport->mutex);
@@ -911,6 +937,17 @@ static irqreturn_t rockchip_usb2phy_bvalid_irq(int irq, void *data)
return IRQ_HANDLED;
}
+static irqreturn_t rockchip_usb2phy_otg_mux_irq(int irq, void *data)
+{
+ struct rockchip_usb2phy_port *rport = data;
+ struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
+
+ if (property_enabled(rphy->grf, &rport->port_cfg->bvalid_det_st))
+ return rockchip_usb2phy_bvalid_irq(irq, data);
+ else
+ return IRQ_NONE;
+}
+
static int rockchip_usb2phy_host_port_init(struct rockchip_usb2phy *rphy,
struct rockchip_usb2phy_port *rport,
struct device_node *child_np)
@@ -987,20 +1024,43 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
rport->utmi_avalid =
of_property_read_bool(child_np, "rockchip,utmi-avalid");
- rport->bvalid_irq = of_irq_get_byname(child_np, "otg-bvalid");
- if (rport->bvalid_irq < 0) {
- dev_err(rphy->dev, "no vbus valid irq provided\n");
- ret = rport->bvalid_irq;
- goto out;
- }
+ /*
+ * Some SoCs use one interrupt with otg-id/otg-bvalid/linestate
+ * interrupts muxed together, so probe the otg-mux interrupt first,
+ * if not found, then look for the regular interrupts one by one.
+ */
+ rport->otg_mux_irq = of_irq_get_byname(child_np, "otg-mux");
+ if (rport->otg_mux_irq > 0) {
+ ret = devm_request_threaded_irq(rphy->dev, rport->otg_mux_irq,
+ NULL,
+ rockchip_usb2phy_otg_mux_irq,
+ IRQF_ONESHOT,
+ "rockchip_usb2phy_otg",
+ rport);
+ if (ret) {
+ dev_err(rphy->dev,
+ "failed to request otg-mux irq handle\n");
+ goto out;
+ }
+ } else {
+ rport->bvalid_irq = of_irq_get_byname(child_np, "otg-bvalid");
+ if (rport->bvalid_irq < 0) {
+ dev_err(rphy->dev, "no vbus valid irq provided\n");
+ ret = rport->bvalid_irq;
+ goto out;
+ }
- ret = devm_request_threaded_irq(rphy->dev, rport->bvalid_irq, NULL,
- rockchip_usb2phy_bvalid_irq,
- IRQF_ONESHOT,
- "rockchip_usb2phy_bvalid", rport);
- if (ret) {
- dev_err(rphy->dev, "failed to request otg-bvalid irq handle\n");
- goto out;
+ ret = devm_request_threaded_irq(rphy->dev, rport->bvalid_irq,
+ NULL,
+ rockchip_usb2phy_bvalid_irq,
+ IRQF_ONESHOT,
+ "rockchip_usb2phy_bvalid",
+ rport);
+ if (ret) {
+ dev_err(rphy->dev,
+ "failed to request otg-bvalid irq handle\n");
+ goto out;
+ }
}
if (!IS_ERR(rphy->edev)) {
@@ -1045,6 +1105,16 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
if (IS_ERR(rphy->grf))
return PTR_ERR(rphy->grf);
+ if (of_device_is_compatible(np, "rockchip,rv1108-usb2phy")) {
+ rphy->usbgrf =
+ syscon_regmap_lookup_by_phandle(dev->of_node,
+ "rockchip,usbgrf");
+ if (IS_ERR(rphy->usbgrf))
+ return PTR_ERR(rphy->usbgrf);
+ } else {
+ rphy->usbgrf = NULL;
+ }
+
if (of_property_read_u32(np, "reg", &reg)) {
dev_err(dev, "the reg property is not assigned in %s node\n",
np->name);
@@ -1327,11 +1397,54 @@ static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = {
{ /* sentinel */ }
};
+static const struct rockchip_usb2phy_cfg rv1108_phy_cfgs[] = {
+ {
+ .reg = 0x100,
+ .num_ports = 2,
+ .clkout_ctl = { 0x108, 4, 4, 1, 0 },
+ .port_cfgs = {
+ [USB2PHY_PORT_OTG] = {
+ .phy_sus = { 0x0100, 15, 0, 0, 0x1d1 },
+ .bvalid_det_en = { 0x0680, 3, 3, 0, 1 },
+ .bvalid_det_st = { 0x0690, 3, 3, 0, 1 },
+ .bvalid_det_clr = { 0x06a0, 3, 3, 0, 1 },
+ .ls_det_en = { 0x0680, 2, 2, 0, 1 },
+ .ls_det_st = { 0x0690, 2, 2, 0, 1 },
+ .ls_det_clr = { 0x06a0, 2, 2, 0, 1 },
+ .utmi_bvalid = { 0x0804, 10, 10, 0, 1 },
+ .utmi_ls = { 0x0804, 13, 12, 0, 1 },
+ },
+ [USB2PHY_PORT_HOST] = {
+ .phy_sus = { 0x0104, 15, 0, 0, 0x1d1 },
+ .ls_det_en = { 0x0680, 4, 4, 0, 1 },
+ .ls_det_st = { 0x0690, 4, 4, 0, 1 },
+ .ls_det_clr = { 0x06a0, 4, 4, 0, 1 },
+ .utmi_ls = { 0x0804, 9, 8, 0, 1 },
+ .utmi_hstdet = { 0x0804, 7, 7, 0, 1 }
+ }
+ },
+ .chg_det = {
+ .opmode = { 0x0100, 3, 0, 5, 1 },
+ .cp_det = { 0x0804, 1, 1, 0, 1 },
+ .dcp_det = { 0x0804, 0, 0, 0, 1 },
+ .dp_det = { 0x0804, 2, 2, 0, 1 },
+ .idm_sink_en = { 0x0108, 8, 8, 0, 1 },
+ .idp_sink_en = { 0x0108, 7, 7, 0, 1 },
+ .idp_src_en = { 0x0108, 9, 9, 0, 1 },
+ .rdm_pdwn_en = { 0x0108, 10, 10, 0, 1 },
+ .vdm_src_en = { 0x0108, 12, 12, 0, 1 },
+ .vdp_src_en = { 0x0108, 11, 11, 0, 1 },
+ },
+ },
+ { /* sentinel */ }
+};
+
static const struct of_device_id rockchip_usb2phy_dt_match[] = {
{ .compatible = "rockchip,rk3228-usb2phy", .data = &rk3228_phy_cfgs },
{ .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs },
{ .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
{ .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs },
+ { .compatible = "rockchip,rv1108-usb2phy", .data = &rv1108_phy_cfgs },
{}
};
MODULE_DEVICE_TABLE(of, rockchip_usb2phy_dt_match);
diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
index 7cfb0f8..4d2c57f 100644
--- a/drivers/phy/rockchip/phy-rockchip-typec.c
+++ b/drivers/phy/rockchip/phy-rockchip-typec.c
@@ -622,12 +622,11 @@ static int tcphy_get_mode(struct rockchip_typec_phy *tcphy)
struct extcon_dev *edev = tcphy->extcon;
union extcon_property_value property;
unsigned int id;
- bool dfp, ufp, dp;
+ bool ufp, dp;
u8 mode;
int ret;
ufp = extcon_get_state(edev, EXTCON_USB);
- dfp = extcon_get_state(edev, EXTCON_USB_HOST);
dp = extcon_get_state(edev, EXTCON_DISP_DP);
mode = MODE_DFP_USB;
diff --git a/drivers/phy/samsung/phy-exynos-dp-video.c b/drivers/phy/samsung/phy-exynos-dp-video.c
index bb3279d..2dd6dd1 100644
--- a/drivers/phy/samsung/phy-exynos-dp-video.c
+++ b/drivers/phy/samsung/phy-exynos-dp-video.c
@@ -16,6 +16,7 @@
#include <linux/mfd/syscon.h>
#include <linux/of.h>
#include <linux/of_address.h>
+#include <linux/of_device.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
@@ -78,7 +79,6 @@ static int exynos_dp_video_phy_probe(struct platform_device *pdev)
{
struct exynos_dp_video_phy *state;
struct device *dev = &pdev->dev;
- const struct of_device_id *match;
struct phy_provider *phy_provider;
struct phy *phy;
@@ -93,8 +93,7 @@ static int exynos_dp_video_phy_probe(struct platform_device *pdev)
return PTR_ERR(state->regs);
}
- match = of_match_node(exynos_dp_video_phy_of_match, dev->of_node);
- state->drvdata = match->data;
+ state->drvdata = of_device_get_match_data(dev);
phy = devm_phy_create(dev, NULL, &exynos_dp_video_phy_ops);
if (IS_ERR(phy)) {
diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index 7c41daa..22c68f5 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
+#include <linux/of_device.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
@@ -662,7 +663,6 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
struct exynos5_usbdrd_phy *phy_drd;
struct phy_provider *phy_provider;
struct resource *res;
- const struct of_device_id *match;
const struct exynos5_usbdrd_phy_drvdata *drv_data;
struct regmap *reg_pmu;
u32 pmu_offset;
@@ -681,9 +681,10 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
if (IS_ERR(phy_drd->reg_phy))
return PTR_ERR(phy_drd->reg_phy);
- match = of_match_node(exynos5_usbdrd_phy_of_match, pdev->dev.of_node);
+ drv_data = of_device_get_match_data(dev);
+ if (!drv_data)
+ return -EINVAL;
- drv_data = match->data;
phy_drd->drv_data = drv_data;
ret = exynos5_usbdrd_phy_clk_handle(phy_drd);
diff --git a/drivers/phy/samsung/phy-samsung-usb2.c b/drivers/phy/samsung/phy-samsung-usb2.c
index 1d22d93..ea81886 100644
--- a/drivers/phy/samsung/phy-samsung-usb2.c
+++ b/drivers/phy/samsung/phy-samsung-usb2.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
+#include <linux/of_device.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
@@ -142,7 +143,6 @@ MODULE_DEVICE_TABLE(of, samsung_usb2_phy_of_match);
static int samsung_usb2_phy_probe(struct platform_device *pdev)
{
- const struct of_device_id *match;
const struct samsung_usb2_phy_config *cfg;
struct device *dev = &pdev->dev;
struct phy_provider *phy_provider;
@@ -155,12 +155,9 @@ static int samsung_usb2_phy_probe(struct platform_device *pdev)
return -EINVAL;
}
- match = of_match_node(samsung_usb2_phy_of_match, pdev->dev.of_node);
- if (!match) {
- dev_err(dev, "of_match_node() failed\n");
+ cfg = of_device_get_match_data(dev);
+ if (!cfg)
return -EINVAL;
- }
- cfg = match->data;
drv = devm_kzalloc(dev, sizeof(struct samsung_usb2_phy_driver) +
cfg->num_phys * sizeof(struct samsung_usb2_phy_instance),
diff --git a/drivers/phy/ti/phy-ti-pipe3.c b/drivers/phy/ti/phy-ti-pipe3.c
index 9c84d32..0e564f3 100644
--- a/drivers/phy/ti/phy-ti-pipe3.c
+++ b/drivers/phy/ti/phy-ti-pipe3.c
@@ -118,12 +118,12 @@ static struct pipe3_dpll_map dpll_map_usb[] = {
};
static struct pipe3_dpll_map dpll_map_sata[] = {
- {12000000, {1000, 7, 4, 6, 0} }, /* 12 MHz */
- {16800000, {714, 7, 4, 6, 0} }, /* 16.8 MHz */
+ {12000000, {625, 4, 4, 6, 0} }, /* 12 MHz */
+ {16800000, {625, 6, 4, 7, 0} }, /* 16.8 MHz */
{19200000, {625, 7, 4, 6, 0} }, /* 19.2 MHz */
- {20000000, {600, 7, 4, 6, 0} }, /* 20 MHz */
- {26000000, {461, 7, 4, 6, 0} }, /* 26 MHz */
- {38400000, {312, 7, 4, 6, 0} }, /* 38.4 MHz */
+ {20000000, {750, 9, 4, 6, 0} }, /* 20 MHz */
+ {26000000, {750, 12, 4, 6, 0} }, /* 26 MHz */
+ {38400000, {625, 15, 4, 6, 0} }, /* 38.4 MHz */
{ }, /* Terminator */
};
diff --git a/drivers/phy/ti/phy-twl4030-usb.c b/drivers/phy/ti/phy-twl4030-usb.c
index 2990b39..0e90138 100644
--- a/drivers/phy/ti/phy-twl4030-usb.c
+++ b/drivers/phy/ti/phy-twl4030-usb.c
@@ -185,7 +185,7 @@ struct twl4030_usb {
static int twl4030_i2c_write_u8_verify(struct twl4030_usb *twl,
u8 module, u8 data, u8 address)
{
- u8 check;
+ u8 check = 0xFF;
if ((twl_i2c_write_u8(module, data, address) >= 0) &&
(twl_i2c_read_u8(module, &check, address) >= 0) &&
diff --git a/drivers/power/supply/wm831x_power.c b/drivers/power/supply/wm831x_power.c
index 7082301..927050d44 100644
--- a/drivers/power/supply/wm831x_power.c
+++ b/drivers/power/supply/wm831x_power.c
@@ -13,6 +13,7 @@
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/slab.h>
+#include <linux/usb/phy.h>
#include <linux/mfd/wm831x/core.h>
#include <linux/mfd/wm831x/auxadc.h>
@@ -31,6 +32,8 @@ struct wm831x_power {
char usb_name[20];
char battery_name[20];
bool have_battery;
+ struct usb_phy *usb_phy;
+ struct notifier_block usb_notify;
};
static int wm831x_power_check_online(struct wm831x *wm831x, int supply,
@@ -125,6 +128,43 @@ static enum power_supply_property wm831x_usb_props[] = {
POWER_SUPPLY_PROP_VOLTAGE_NOW,
};
+/* In milliamps */
+static const unsigned int wm831x_usb_limits[] = {
+ 0,
+ 2,
+ 100,
+ 500,
+ 900,
+ 1500,
+ 1800,
+ 550,
+};
+
+static int wm831x_usb_limit_change(struct notifier_block *nb,
+ unsigned long limit, void *data)
+{
+ struct wm831x_power *wm831x_power = container_of(nb,
+ struct wm831x_power,
+ usb_notify);
+ unsigned int i, best;
+
+ /* Find the highest supported limit */
+ best = 0;
+ for (i = 0; i < ARRAY_SIZE(wm831x_usb_limits); i++) {
+ if (limit >= wm831x_usb_limits[i] &&
+ wm831x_usb_limits[best] < wm831x_usb_limits[i])
+ best = i;
+ }
+
+ dev_dbg(wm831x_power->wm831x->dev,
+ "Limiting USB current to %umA", wm831x_usb_limits[best]);
+
+ wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE,
+ WM831X_USB_ILIM_MASK, best);
+
+ return 0;
+}
+
/*********************************************************************
* Battery properties
*********************************************************************/
@@ -607,6 +647,33 @@ static int wm831x_power_probe(struct platform_device *pdev)
}
}
+ power->usb_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "phys", 0);
+ ret = PTR_ERR_OR_ZERO(power->usb_phy);
+
+ switch (ret) {
+ case 0:
+ power->usb_notify.notifier_call = wm831x_usb_limit_change;
+ ret = usb_register_notifier(power->usb_phy, &power->usb_notify);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to register notifier: %d\n",
+ ret);
+ goto err_bat_irq;
+ }
+ break;
+ case -EINVAL:
+ case -ENODEV:
+ /* ignore missing usb-phy, it's optional */
+ power->usb_phy = NULL;
+ ret = 0;
+ break;
+ default:
+ dev_err(&pdev->dev, "Failed to find USB phy: %d\n", ret);
+ /* fall-through */
+ case -EPROBE_DEFER:
+ goto err_bat_irq;
+ break;
+ }
+
return ret;
err_bat_irq:
@@ -637,6 +704,11 @@ static int wm831x_power_remove(struct platform_device *pdev)
struct wm831x *wm831x = wm831x_power->wm831x;
int irq, i;
+ if (wm831x_power->usb_phy) {
+ usb_unregister_notifier(wm831x_power->usb_phy,
+ &wm831x_power->usb_notify);
+ }
+
for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
irq = wm831x_irq(wm831x,
platform_get_irq_byname(pdev,
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 670ac0a..9c97ad1 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -801,11 +801,12 @@ static void dasd_profile_end(struct dasd_block *block,
struct dasd_ccw_req *cqr,
struct request *req)
{
- long strtime, irqtime, endtime, tottime; /* in microseconds */
- long tottimeps, sectors;
+ unsigned long strtime, irqtime, endtime, tottime;
+ unsigned long tottimeps, sectors;
struct dasd_device *device;
int sectors_ind, tottime_ind, tottimeps_ind, strtime_ind;
int irqtime_ind, irqtimeps_ind, endtime_ind;
+ struct dasd_profile_info *data;
device = cqr->startdev;
if (!(dasd_global_profile_level ||
@@ -835,6 +836,11 @@ static void dasd_profile_end(struct dasd_block *block,
spin_lock(&dasd_global_profile.lock);
if (dasd_global_profile.data) {
+ data = dasd_global_profile.data;
+ data->dasd_sum_times += tottime;
+ data->dasd_sum_time_str += strtime;
+ data->dasd_sum_time_irq += irqtime;
+ data->dasd_sum_time_end += endtime;
dasd_profile_end_add_data(dasd_global_profile.data,
cqr->startdev != block->base,
cqr->cpmode == 1,
@@ -847,7 +853,12 @@ static void dasd_profile_end(struct dasd_block *block,
spin_unlock(&dasd_global_profile.lock);
spin_lock(&block->profile.lock);
- if (block->profile.data)
+ if (block->profile.data) {
+ data = block->profile.data;
+ data->dasd_sum_times += tottime;
+ data->dasd_sum_time_str += strtime;
+ data->dasd_sum_time_irq += irqtime;
+ data->dasd_sum_time_end += endtime;
dasd_profile_end_add_data(block->profile.data,
cqr->startdev != block->base,
cqr->cpmode == 1,
@@ -856,10 +867,16 @@ static void dasd_profile_end(struct dasd_block *block,
tottimeps_ind, strtime_ind,
irqtime_ind, irqtimeps_ind,
endtime_ind);
+ }
spin_unlock(&block->profile.lock);
spin_lock(&device->profile.lock);
- if (device->profile.data)
+ if (device->profile.data) {
+ data = device->profile.data;
+ data->dasd_sum_times += tottime;
+ data->dasd_sum_time_str += strtime;
+ data->dasd_sum_time_irq += irqtime;
+ data->dasd_sum_time_end += endtime;
dasd_profile_end_add_data(device->profile.data,
cqr->startdev != block->base,
cqr->cpmode == 1,
@@ -868,6 +885,7 @@ static void dasd_profile_end(struct dasd_block *block,
tottimeps_ind, strtime_ind,
irqtime_ind, irqtimeps_ind,
endtime_ind);
+ }
spin_unlock(&device->profile.lock);
}
@@ -989,6 +1007,14 @@ static void dasd_stats_seq_print(struct seq_file *m,
seq_printf(m, "total_sectors %u\n", data->dasd_io_sects);
seq_printf(m, "total_pav %u\n", data->dasd_io_alias);
seq_printf(m, "total_hpf %u\n", data->dasd_io_tpm);
+ seq_printf(m, "avg_total %lu\n", data->dasd_io_reqs ?
+ data->dasd_sum_times / data->dasd_io_reqs : 0UL);
+ seq_printf(m, "avg_build_to_ssch %lu\n", data->dasd_io_reqs ?
+ data->dasd_sum_time_str / data->dasd_io_reqs : 0UL);
+ seq_printf(m, "avg_ssch_to_irq %lu\n", data->dasd_io_reqs ?
+ data->dasd_sum_time_irq / data->dasd_io_reqs : 0UL);
+ seq_printf(m, "avg_irq_to_end %lu\n", data->dasd_io_reqs ?
+ data->dasd_sum_time_end / data->dasd_io_reqs : 0UL);
seq_puts(m, "histogram_sectors ");
dasd_stats_array(m, data->dasd_io_secs);
seq_puts(m, "histogram_io_times ");
@@ -1639,7 +1665,7 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
{
struct dasd_ccw_req *cqr, *next;
struct dasd_device *device;
- unsigned long long now;
+ unsigned long now;
int nrf_suppressed = 0;
int fp_suppressed = 0;
u8 *sense = NULL;
@@ -3152,7 +3178,9 @@ static int dasd_alloc_queue(struct dasd_block *block)
*/
static void dasd_setup_queue(struct dasd_block *block)
{
+ unsigned int logical_block_size = block->bp_block;
struct request_queue *q = block->request_queue;
+ unsigned int max_bytes, max_discard_sectors;
int max;
if (block->base->features & DASD_FEATURE_USERAW) {
@@ -3169,7 +3197,7 @@ static void dasd_setup_queue(struct dasd_block *block)
}
queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q);
q->limits.max_dev_sectors = max;
- blk_queue_logical_block_size(q, block->bp_block);
+ blk_queue_logical_block_size(q, logical_block_size);
blk_queue_max_hw_sectors(q, max);
blk_queue_max_segments(q, USHRT_MAX);
/* with page sized segments we can translate each segement into
@@ -3177,6 +3205,21 @@ static void dasd_setup_queue(struct dasd_block *block)
*/
blk_queue_max_segment_size(q, PAGE_SIZE);
blk_queue_segment_boundary(q, PAGE_SIZE - 1);
+
+ /* Only activate blocklayer discard support for devices that support it */
+ if (block->base->features & DASD_FEATURE_DISCARD) {
+ q->limits.discard_granularity = logical_block_size;
+ q->limits.discard_alignment = PAGE_SIZE;
+
+ /* Calculate max_discard_sectors and make it PAGE aligned */
+ max_bytes = USHRT_MAX * logical_block_size;
+ max_bytes = ALIGN(max_bytes, PAGE_SIZE) - PAGE_SIZE;
+ max_discard_sectors = max_bytes / logical_block_size;
+
+ blk_queue_max_discard_sectors(q, max_discard_sectors);
+ blk_queue_max_write_zeroes_sectors(q, max_discard_sectors);
+ queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
+ }
}
/*
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
index 107cd33..e448a0f 100644
--- a/drivers/s390/block/dasd_3990_erp.c
+++ b/drivers/s390/block/dasd_3990_erp.c
@@ -2231,7 +2231,7 @@ static void dasd_3990_erp_account_error(struct dasd_ccw_req *erp)
struct dasd_device *device = erp->startdev;
__u8 lpum = erp->refers->irb.esw.esw1.lpum;
int pos = pathmask_to_pos(lpum);
- unsigned long long clk;
+ unsigned long clk;
if (!device->path_thrhld)
return;
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index 779dce0..e38042c 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -1634,7 +1634,7 @@ static struct attribute * dasd_attrs[] = {
NULL,
};
-static struct attribute_group dasd_attr_group = {
+static const struct attribute_group dasd_attr_group = {
.attrs = dasd_attrs,
};
@@ -1676,6 +1676,7 @@ dasd_set_feature(struct ccw_device *cdev, int feature, int flag)
spin_unlock(&dasd_devmap_lock);
return 0;
}
+EXPORT_SYMBOL(dasd_set_feature);
int
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index 5667146..98fb28e 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -235,7 +235,7 @@ static void dasd_ext_handler(struct ext_code ext_code,
{
struct dasd_ccw_req *cqr, *next;
struct dasd_device *device;
- unsigned long long expires;
+ unsigned long expires;
unsigned long flags;
addr_t ip;
int rc;
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index c3e5ad6..8eafcd5 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -3254,11 +3254,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track(
/* 1x prefix + one read/write ccw per track */
cplength = 1 + trkcount;
- /* on 31-bit we need space for two 32 bit addresses per page
- * on 64-bit one 64 bit address
- */
- datasize = sizeof(struct PFX_eckd_data) +
- cidaw * sizeof(unsigned long long);
+ datasize = sizeof(struct PFX_eckd_data) + cidaw * sizeof(unsigned long);
/* Allocate the ccw request. */
cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, cplength, datasize,
@@ -3856,7 +3852,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_raw(struct dasd_device *startdev,
}
size = ALIGN(size, 8);
- datasize = size + cidaw * sizeof(unsigned long long);
+ datasize = size + cidaw * sizeof(unsigned long);
/* Allocate the ccw request. */
cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, cplength,
diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h
index fb1f537d..34e153a 100644
--- a/drivers/s390/block/dasd_eckd.h
+++ b/drivers/s390/block/dasd_eckd.h
@@ -165,7 +165,7 @@ struct DE_eckd_data {
__u8 ga_extended; /* Global Attributes Extended */
struct ch_t beg_ext;
struct ch_t end_ext;
- unsigned long long ep_sys_time; /* Ext Parameter - System Time Stamp */
+ unsigned long ep_sys_time; /* Ext Parameter - System Time Stamp */
__u8 ep_format; /* Extended Parameter format byte */
__u8 ep_prio; /* Extended Parameter priority I/O byte */
__u8 ep_reserved1; /* Extended Parameter Reserved */
diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c
index 9e34191..6389feb 100644
--- a/drivers/s390/block/dasd_erp.c
+++ b/drivers/s390/block/dasd_erp.c
@@ -124,7 +124,7 @@ dasd_default_erp_action(struct dasd_ccw_req *cqr)
struct dasd_ccw_req *dasd_default_erp_postaction(struct dasd_ccw_req *cqr)
{
int success;
- unsigned long long startclk, stopclk;
+ unsigned long startclk, stopclk;
struct dasd_device *startdev;
BUG_ON(cqr->refers == NULL || cqr->function == NULL);
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index 462cab5..6168ccd 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -174,6 +174,9 @@ dasd_fba_check_characteristics(struct dasd_device *device)
if (readonly)
set_bit(DASD_FLAG_DEVICE_RO, &device->flags);
+ /* FBA supports discard, set the according feature bit */
+ dasd_set_feature(cdev, DASD_FEATURE_DISCARD, 1);
+
dev_info(&device->cdev->dev,
"New FBA DASD %04X/%02X (CU %04X/%02X) with %d MB "
"and %d B/blk%s\n",
@@ -247,9 +250,192 @@ static void dasd_fba_check_for_device_change(struct dasd_device *device,
dasd_generic_handle_state_change(device);
};
-static struct dasd_ccw_req *dasd_fba_build_cp(struct dasd_device * memdev,
- struct dasd_block *block,
- struct request *req)
+
+/*
+ * Builds a CCW with no data payload
+ */
+static void ccw_write_no_data(struct ccw1 *ccw)
+{
+ ccw->cmd_code = DASD_FBA_CCW_WRITE;
+ ccw->flags |= CCW_FLAG_SLI;
+ ccw->count = 0;
+}
+
+/*
+ * Builds a CCW that writes only zeroes.
+ */
+static void ccw_write_zero(struct ccw1 *ccw, int count)
+{
+ ccw->cmd_code = DASD_FBA_CCW_WRITE;
+ ccw->flags |= CCW_FLAG_SLI;
+ ccw->count = count;
+ ccw->cda = (__u32) (addr_t) page_to_phys(ZERO_PAGE(0));
+}
+
+/*
+ * Helper function to count the amount of necessary CCWs within a given range
+ * with 4k alignment and command chaining in mind.
+ */
+static int count_ccws(sector_t first_rec, sector_t last_rec,
+ unsigned int blocks_per_page)
+{
+ sector_t wz_stop = 0, d_stop = 0;
+ int cur_pos = 0;
+ int count = 0;
+
+ if (first_rec % blocks_per_page != 0) {
+ wz_stop = first_rec + blocks_per_page -
+ (first_rec % blocks_per_page) - 1;
+ if (wz_stop > last_rec)
+ wz_stop = last_rec;
+ cur_pos = wz_stop - first_rec + 1;
+ count++;
+ }
+
+ if (last_rec - (first_rec + cur_pos) + 1 >= blocks_per_page) {
+ if ((last_rec - blocks_per_page + 1) % blocks_per_page != 0)
+ d_stop = last_rec - ((last_rec - blocks_per_page + 1) %
+ blocks_per_page);
+ else
+ d_stop = last_rec;
+
+ cur_pos += d_stop - (first_rec + cur_pos) + 1;
+ count++;
+ }
+
+ if (cur_pos == 0 || first_rec + cur_pos - 1 < last_rec)
+ count++;
+
+ return count;
+}
+
+/*
+ * This function builds a CCW request for block layer discard requests.
+ * Each page in the z/VM hypervisor that represents certain records of an FBA
+ * device will be padded with zeros. This is a special behaviour of the WRITE
+ * command which is triggered when no data payload is added to the CCW.
+ *
+ * Note: Due to issues in some z/VM versions, we can't fully utilise this
+ * special behaviour. We have to keep a 4k (or 8 block) alignment in mind to
+ * work around those issues and write actual zeroes to the unaligned parts in
+ * the request. This workaround might be removed in the future.
+ */
+static struct dasd_ccw_req *dasd_fba_build_cp_discard(
+ struct dasd_device *memdev,
+ struct dasd_block *block,
+ struct request *req)
+{
+ struct LO_fba_data *LO_data;
+ struct dasd_ccw_req *cqr;
+ struct ccw1 *ccw;
+
+ sector_t wz_stop = 0, d_stop = 0;
+ sector_t first_rec, last_rec;
+
+ unsigned int blksize = block->bp_block;
+ unsigned int blocks_per_page;
+ int wz_count = 0;
+ int d_count = 0;
+ int cur_pos = 0; /* Current position within the extent */
+ int count = 0;
+ int cplength;
+ int datasize;
+ int nr_ccws;
+
+ first_rec = blk_rq_pos(req) >> block->s2b_shift;
+ last_rec =
+ (blk_rq_pos(req) + blk_rq_sectors(req) - 1) >> block->s2b_shift;
+ count = last_rec - first_rec + 1;
+
+ blocks_per_page = BLOCKS_PER_PAGE(blksize);
+ nr_ccws = count_ccws(first_rec, last_rec, blocks_per_page);
+
+ /* define extent + nr_ccws * locate record + nr_ccws * single CCW */
+ cplength = 1 + 2 * nr_ccws;
+ datasize = sizeof(struct DE_fba_data) +
+ nr_ccws * (sizeof(struct LO_fba_data) + sizeof(struct ccw1));
+
+ cqr = dasd_smalloc_request(DASD_FBA_MAGIC, cplength, datasize, memdev);
+ if (IS_ERR(cqr))
+ return cqr;
+
+ ccw = cqr->cpaddr;
+
+ define_extent(ccw++, cqr->data, WRITE, blksize, first_rec, count);
+ LO_data = cqr->data + sizeof(struct DE_fba_data);
+
+ /* First part is not aligned. Calculate range to write zeroes. */
+ if (first_rec % blocks_per_page != 0) {
+ wz_stop = first_rec + blocks_per_page -
+ (first_rec % blocks_per_page) - 1;
+ if (wz_stop > last_rec)
+ wz_stop = last_rec;
+ wz_count = wz_stop - first_rec + 1;
+
+ ccw[-1].flags |= CCW_FLAG_CC;
+ locate_record(ccw++, LO_data++, WRITE, cur_pos, wz_count);
+
+ ccw[-1].flags |= CCW_FLAG_CC;
+ ccw_write_zero(ccw++, wz_count * blksize);
+
+ cur_pos = wz_count;
+ }
+
+ /* We can do proper discard when we've got at least blocks_per_page blocks. */
+ if (last_rec - (first_rec + cur_pos) + 1 >= blocks_per_page) {
+ /* is last record at page boundary? */
+ if ((last_rec - blocks_per_page + 1) % blocks_per_page != 0)
+ d_stop = last_rec - ((last_rec - blocks_per_page + 1) %
+ blocks_per_page);
+ else
+ d_stop = last_rec;
+
+ d_count = d_stop - (first_rec + cur_pos) + 1;
+
+ ccw[-1].flags |= CCW_FLAG_CC;
+ locate_record(ccw++, LO_data++, WRITE, cur_pos, d_count);
+
+ ccw[-1].flags |= CCW_FLAG_CC;
+ ccw_write_no_data(ccw++);
+
+ cur_pos += d_count;
+ }
+
+ /* We might still have some bits left which need to be zeroed. */
+ if (cur_pos == 0 || first_rec + cur_pos - 1 < last_rec) {
+ if (d_stop != 0)
+ wz_count = last_rec - d_stop;
+ else if (wz_stop != 0)
+ wz_count = last_rec - wz_stop;
+ else
+ wz_count = count;
+
+ ccw[-1].flags |= CCW_FLAG_CC;
+ locate_record(ccw++, LO_data++, WRITE, cur_pos, wz_count);
+
+ ccw[-1].flags |= CCW_FLAG_CC;
+ ccw_write_zero(ccw++, wz_count * blksize);
+ }
+
+ if (blk_noretry_request(req) ||
+ block->base->features & DASD_FEATURE_FAILFAST)
+ set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
+
+ cqr->startdev = memdev;
+ cqr->memdev = memdev;
+ cqr->block = block;
+ cqr->expires = memdev->default_expires * HZ; /* default 5 minutes */
+ cqr->retries = memdev->default_retries;
+ cqr->buildclk = get_tod_clock();
+ cqr->status = DASD_CQR_FILLED;
+
+ return cqr;
+}
+
+static struct dasd_ccw_req *dasd_fba_build_cp_regular(
+ struct dasd_device *memdev,
+ struct dasd_block *block,
+ struct request *req)
{
struct dasd_fba_private *private = block->base->private;
unsigned long *idaws;
@@ -372,6 +558,16 @@ static struct dasd_ccw_req *dasd_fba_build_cp(struct dasd_device * memdev,
return cqr;
}
+static struct dasd_ccw_req *dasd_fba_build_cp(struct dasd_device *memdev,
+ struct dasd_block *block,
+ struct request *req)
+{
+ if (req_op(req) == REQ_OP_DISCARD || req_op(req) == REQ_OP_WRITE_ZEROES)
+ return dasd_fba_build_cp_discard(memdev, block, req);
+ else
+ return dasd_fba_build_cp_regular(memdev, block, req);
+}
+
static int
dasd_fba_free_cp(struct dasd_ccw_req *cqr, struct request *req)
{
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index dca7cb1..f9e25fc 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -167,6 +167,9 @@ do { \
printk(d_loglevel PRINTK_HEADER " " d_string "\n", d_args); \
} while(0)
+/* Macro to calculate number of blocks per page */
+#define BLOCKS_PER_PAGE(blksize) (PAGE_SIZE / blksize)
+
struct dasd_ccw_req {
unsigned int magic; /* Eye catcher */
struct list_head devlist; /* for dasd_device request queue */
@@ -196,10 +199,10 @@ struct dasd_ccw_req {
void *function; /* originating ERP action */
/* these are for statistics only */
- unsigned long long buildclk; /* TOD-clock of request generation */
- unsigned long long startclk; /* TOD-clock of request start */
- unsigned long long stopclk; /* TOD-clock of request interrupt */
- unsigned long long endclk; /* TOD-clock of request termination */
+ unsigned long buildclk; /* TOD-clock of request generation */
+ unsigned long startclk; /* TOD-clock of request start */
+ unsigned long stopclk; /* TOD-clock of request interrupt */
+ unsigned long endclk; /* TOD-clock of request termination */
/* Callback that is called after reaching final status. */
void (*callback)(struct dasd_ccw_req *, void *data);
@@ -423,7 +426,7 @@ struct dasd_path {
u8 chpid;
struct dasd_conf_data *conf_data;
atomic_t error_count;
- unsigned long long errorclk;
+ unsigned long errorclk;
};
@@ -454,6 +457,10 @@ struct dasd_profile_info {
unsigned int dasd_read_time2[32]; /* hist. of time from start to irq */
unsigned int dasd_read_time3[32]; /* hist. of time from irq to end */
unsigned int dasd_read_nr_req[32]; /* hist. of # of requests in chanq */
+ unsigned long dasd_sum_times; /* sum of request times */
+ unsigned long dasd_sum_time_str; /* sum of time from build to start */
+ unsigned long dasd_sum_time_irq; /* sum of time from start to irq */
+ unsigned long dasd_sum_time_end; /* sum of time from irq to end */
};
struct dasd_profile {
@@ -535,7 +542,7 @@ struct dasd_block {
struct block_device *bdev;
atomic_t open_count;
- unsigned long long blocks; /* size of volume in blocks */
+ unsigned long blocks; /* size of volume in blocks */
unsigned int bp_block; /* bytes per block */
unsigned int s2b_shift; /* log2 (bp_block/512) */
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
index 70dc2c4..7104d67 100644
--- a/drivers/s390/block/dasd_proc.c
+++ b/drivers/s390/block/dasd_proc.c
@@ -90,7 +90,7 @@ dasd_devices_show(struct seq_file *m, void *v)
seq_printf(m, "n/f ");
else
seq_printf(m,
- "at blocksize: %d, %lld blocks, %lld MB",
+ "at blocksize: %u, %lu blocks, %lu MB",
block->bp_block, block->blocks,
((block->bp_block >> 9) *
block->blocks) >> 11);
diff --git a/drivers/s390/block/scm_blk.c b/drivers/s390/block/scm_blk.c
index 0071feb..2e7fd96 100644
--- a/drivers/s390/block/scm_blk.c
+++ b/drivers/s390/block/scm_blk.c
@@ -249,13 +249,13 @@ static void scm_request_requeue(struct scm_request *scmrq)
static void scm_request_finish(struct scm_request *scmrq)
{
struct scm_blk_dev *bdev = scmrq->bdev;
+ int *error;
int i;
for (i = 0; i < nr_requests_per_io && scmrq->request[i]; i++) {
- if (scmrq->error)
- blk_mq_end_request(scmrq->request[i], scmrq->error);
- else
- blk_mq_complete_request(scmrq->request[i]);
+ error = blk_mq_rq_to_pdu(scmrq->request[i]);
+ *error = scmrq->error;
+ blk_mq_complete_request(scmrq->request[i]);
}
atomic_dec(&bdev->queued_reqs);
@@ -415,7 +415,9 @@ void scm_blk_irq(struct scm_device *scmdev, void *data, blk_status_t error)
static void scm_blk_request_done(struct request *req)
{
- blk_mq_end_request(req, 0);
+ int *error = blk_mq_rq_to_pdu(req);
+
+ blk_mq_end_request(req, *error);
}
static const struct block_device_operations scm_blk_devops = {
@@ -448,6 +450,7 @@ int scm_blk_dev_setup(struct scm_blk_dev *bdev, struct scm_device *scmdev)
atomic_set(&bdev->queued_reqs, 0);
bdev->tag_set.ops = &scm_mq_ops;
+ bdev->tag_set.cmd_size = sizeof(int);
bdev->tag_set.nr_hw_queues = nr_requests;
bdev->tag_set.queue_depth = nr_requests_per_io * nr_requests;
bdev->tag_set.flags = BLK_MQ_F_SHOULD_MERGE;
diff --git a/drivers/s390/char/Kconfig b/drivers/s390/char/Kconfig
index b3f1c45..97c4c9f 100644
--- a/drivers/s390/char/Kconfig
+++ b/drivers/s390/char/Kconfig
@@ -169,10 +169,21 @@ config VMCP
def_bool y
prompt "Support for the z/VM CP interface"
depends on S390
+ select CMA
help
Select this option if you want to be able to interact with the control
program on z/VM
+config VMCP_CMA_SIZE
+ int "Memory in MiB reserved for z/VM CP interface"
+ default "4"
+ depends on VMCP
+ help
+ Specify the default amount of memory in MiB reserved for the z/VM CP
+ interface. If needed this memory is used for large contiguous memory
+ allocations. The default can be changed with the kernel command line
+ parameter "vmcp_cma".
+
config MONREADER
def_tristate m
prompt "API for reading z/VM monitor service records"
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 710f229..5d4f053 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -1082,7 +1082,7 @@ static struct attribute * raw3270_attrs[] = {
NULL,
};
-static struct attribute_group raw3270_attr_group = {
+static const struct attribute_group raw3270_attr_group = {
.attrs = raw3270_attrs,
};
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index b9c5522..dff8b94 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -252,6 +252,7 @@ static int sclp_attach_storage(u8 id)
if (!sccb)
return -ENOMEM;
sccb->header.length = PAGE_SIZE;
+ sccb->header.function_code = 0x40;
rc = sclp_sync_request_timeout(0x00080001 | id << 8, sccb,
SCLP_QUEUE_INTERVAL);
if (rc)
diff --git a/drivers/s390/char/sclp_config.c b/drivers/s390/char/sclp_config.c
index 1406fb6..7003d52 100644
--- a/drivers/s390/char/sclp_config.c
+++ b/drivers/s390/char/sclp_config.c
@@ -135,7 +135,7 @@ static ssize_t sysfs_ofb_data_write(struct file *filp, struct kobject *kobj,
return rc ?: count;
}
-static struct bin_attribute ofb_bin_attr = {
+static const struct bin_attribute ofb_bin_attr = {
.attr = {
.name = "event_data",
.mode = S_IWUSR,
diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c
index efd84d1..bc1fc00 100644
--- a/drivers/s390/char/sclp_early.c
+++ b/drivers/s390/char/sclp_early.c
@@ -39,7 +39,7 @@ struct read_info_sccb {
u8 fac84; /* 84 */
u8 fac85; /* 85 */
u8 _pad_86[91 - 86]; /* 86-90 */
- u8 flags; /* 91 */
+ u8 fac91; /* 91 */
u8 _pad_92[98 - 92]; /* 92-97 */
u8 fac98; /* 98 */
u8 hamaxpow; /* 99 */
@@ -103,6 +103,8 @@ static void __init sclp_early_facilities_detect(struct read_info_sccb *sccb)
sclp.has_kss = !!(sccb->fac98 & 0x01);
if (sccb->fac85 & 0x02)
S390_lowcore.machine_flags |= MACHINE_FLAG_ESOP;
+ if (sccb->fac91 & 0x40)
+ S390_lowcore.machine_flags |= MACHINE_FLAG_TLB_GUEST;
sclp.rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2;
sclp.rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2;
sclp.rzm <<= 20;
@@ -139,7 +141,7 @@ static void __init sclp_early_facilities_detect(struct read_info_sccb *sccb)
/* Save IPL information */
sclp_ipl_info.is_valid = 1;
- if (sccb->flags & 0x2)
+ if (sccb->fac91 & 0x2)
sclp_ipl_info.has_dump = 1;
memcpy(&sclp_ipl_info.loadparm, &sccb->loadparm, LOADPARM_LEN);
diff --git a/drivers/s390/char/sclp_ocf.c b/drivers/s390/char/sclp_ocf.c
index f59b717..f9cbb1a 100644
--- a/drivers/s390/char/sclp_ocf.c
+++ b/drivers/s390/char/sclp_ocf.c
@@ -126,7 +126,7 @@ static struct attribute *ocf_attrs[] = {
NULL,
};
-static struct attribute_group ocf_attr_group = {
+static const struct attribute_group ocf_attr_group = {
.attrs = ocf_attrs,
};
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index 3c379da..9dd4534 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -175,7 +175,7 @@ static struct attribute *tape_attrs[] = {
NULL
};
-static struct attribute_group tape_attr_group = {
+static const struct attribute_group tape_attr_group = {
.attrs = tape_attrs,
};
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c
index 98749fa..7898bbc 100644
--- a/drivers/s390/char/vmcp.c
+++ b/drivers/s390/char/vmcp.c
@@ -17,15 +17,85 @@
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
+#include <linux/uaccess.h>
#include <linux/export.h>
+#include <linux/mutex.h>
+#include <linux/cma.h>
+#include <linux/mm.h>
#include <asm/compat.h>
#include <asm/cpcmd.h>
#include <asm/debug.h>
-#include <linux/uaccess.h>
-#include "vmcp.h"
+#include <asm/vmcp.h>
+
+struct vmcp_session {
+ char *response;
+ unsigned int bufsize;
+ unsigned int cma_alloc : 1;
+ int resp_size;
+ int resp_code;
+ struct mutex mutex;
+};
static debug_info_t *vmcp_debug;
+static unsigned long vmcp_cma_size __initdata = CONFIG_VMCP_CMA_SIZE * 1024 * 1024;
+static struct cma *vmcp_cma;
+
+static int __init early_parse_vmcp_cma(char *p)
+{
+ vmcp_cma_size = ALIGN(memparse(p, NULL), PAGE_SIZE);
+ return 0;
+}
+early_param("vmcp_cma", early_parse_vmcp_cma);
+
+void __init vmcp_cma_reserve(void)
+{
+ if (!MACHINE_IS_VM)
+ return;
+ cma_declare_contiguous(0, vmcp_cma_size, 0, 0, 0, false, "vmcp", &vmcp_cma);
+}
+
+static void vmcp_response_alloc(struct vmcp_session *session)
+{
+ struct page *page = NULL;
+ int nr_pages, order;
+
+ order = get_order(session->bufsize);
+ nr_pages = ALIGN(session->bufsize, PAGE_SIZE) >> PAGE_SHIFT;
+ /*
+ * For anything below order 3 allocations rely on the buddy
+ * allocator. If such low-order allocations can't be handled
+ * anymore the system won't work anyway.
+ */
+ if (order > 2)
+ page = cma_alloc(vmcp_cma, nr_pages, 0, GFP_KERNEL);
+ if (page) {
+ session->response = (char *)page_to_phys(page);
+ session->cma_alloc = 1;
+ return;
+ }
+ session->response = (char *)__get_free_pages(GFP_KERNEL | __GFP_RETRY_MAYFAIL, order);
+}
+
+static void vmcp_response_free(struct vmcp_session *session)
+{
+ int nr_pages, order;
+ struct page *page;
+
+ if (!session->response)
+ return;
+ order = get_order(session->bufsize);
+ nr_pages = ALIGN(session->bufsize, PAGE_SIZE) >> PAGE_SHIFT;
+ if (session->cma_alloc) {
+ page = phys_to_page((unsigned long)session->response);
+ cma_release(vmcp_cma, page, nr_pages);
+ session->cma_alloc = 0;
+ } else {
+ free_pages((unsigned long)session->response, order);
+ }
+ session->response = NULL;
+}
+
static int vmcp_open(struct inode *inode, struct file *file)
{
struct vmcp_session *session;
@@ -51,7 +121,7 @@ static int vmcp_release(struct inode *inode, struct file *file)
session = file->private_data;
file->private_data = NULL;
- free_pages((unsigned long)session->response, get_order(session->bufsize));
+ vmcp_response_free(session);
kfree(session);
return 0;
}
@@ -97,9 +167,7 @@ vmcp_write(struct file *file, const char __user *buff, size_t count,
return -ERESTARTSYS;
}
if (!session->response)
- session->response = (char *)__get_free_pages(GFP_KERNEL
- | __GFP_RETRY_MAYFAIL | GFP_DMA,
- get_order(session->bufsize));
+ vmcp_response_alloc(session);
if (!session->response) {
mutex_unlock(&session->mutex);
kfree(cmd);
@@ -130,8 +198,8 @@ vmcp_write(struct file *file, const char __user *buff, size_t count,
static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct vmcp_session *session;
+ int ret = -ENOTTY;
int __user *argp;
- int temp;
session = file->private_data;
if (is_compat_task())
@@ -142,28 +210,26 @@ static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return -ERESTARTSYS;
switch (cmd) {
case VMCP_GETCODE:
- temp = session->resp_code;
- mutex_unlock(&session->mutex);
- return put_user(temp, argp);
+ ret = put_user(session->resp_code, argp);
+ break;
case VMCP_SETBUF:
- free_pages((unsigned long)session->response,
- get_order(session->bufsize));
- session->response=NULL;
- temp = get_user(session->bufsize, argp);
- if (get_order(session->bufsize) > 8) {
+ vmcp_response_free(session);
+ ret = get_user(session->bufsize, argp);
+ if (ret)
session->bufsize = PAGE_SIZE;
- temp = -EINVAL;
+ if (!session->bufsize || get_order(session->bufsize) > 8) {
+ session->bufsize = PAGE_SIZE;
+ ret = -EINVAL;
}
- mutex_unlock(&session->mutex);
- return temp;
+ break;
case VMCP_GETSIZE:
- temp = session->resp_size;
- mutex_unlock(&session->mutex);
- return put_user(temp, argp);
+ ret = put_user(session->resp_size, argp);
+ break;
default:
- mutex_unlock(&session->mutex);
- return -ENOIOCTLCMD;
+ break;
}
+ mutex_unlock(&session->mutex);
+ return ret;
}
static const struct file_operations vmcp_fops = {
diff --git a/drivers/s390/char/vmcp.h b/drivers/s390/char/vmcp.h
deleted file mode 100644
index 1e29b04..0000000
--- a/drivers/s390/char/vmcp.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright IBM Corp. 2004, 2005
- * Interface implementation for communication with the z/VM control program
- * Version 1.0
- * Author(s): Christian Borntraeger <cborntra@de.ibm.com>
- *
- *
- * z/VMs CP offers the possibility to issue commands via the diagnose code 8
- * this driver implements a character device that issues these commands and
- * returns the answer of CP.
- *
- * The idea of this driver is based on cpint from Neale Ferguson
- */
-
-#include <linux/ioctl.h>
-#include <linux/mutex.h>
-
-#define VMCP_GETCODE _IOR(0x10, 1, int)
-#define VMCP_SETBUF _IOW(0x10, 2, int)
-#define VMCP_GETSIZE _IOR(0x10, 3, int)
-
-struct vmcp_session {
- unsigned int bufsize;
- char *response;
- int resp_size;
- int resp_code;
- /* As we use copy_from/to_user, which might *
- * sleep and cannot use a spinlock */
- struct mutex mutex;
-};
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c
index 432fc40..f4166f8 100644
--- a/drivers/s390/cio/chp.c
+++ b/drivers/s390/cio/chp.c
@@ -143,7 +143,7 @@ static ssize_t chp_measurement_chars_read(struct file *filp,
sizeof(chp->cmg_chars));
}
-static struct bin_attribute chp_measurement_chars_attr = {
+static const struct bin_attribute chp_measurement_chars_attr = {
.attr = {
.name = "measurement_chars",
.mode = S_IRUSR,
@@ -197,7 +197,7 @@ static ssize_t chp_measurement_read(struct file *filp, struct kobject *kobj,
return count;
}
-static struct bin_attribute chp_measurement_attr = {
+static const struct bin_attribute chp_measurement_attr = {
.attr = {
.name = "measurement",
.mode = S_IRUSR,
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 7be01a5..489b583 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -612,7 +612,7 @@ static struct attribute *io_subchannel_attrs[] = {
NULL,
};
-static struct attribute_group io_subchannel_attr_group = {
+static const struct attribute_group io_subchannel_attr_group = {
.attrs = io_subchannel_attrs,
};
@@ -626,7 +626,7 @@ static struct attribute * ccwdev_attrs[] = {
NULL,
};
-static struct attribute_group ccwdev_attr_group = {
+static const struct attribute_group ccwdev_attr_group = {
.attrs = ccwdev_attrs,
};
diff --git a/drivers/s390/cio/vfio_ccw_cp.c b/drivers/s390/cio/vfio_ccw_cp.c
index ba6ac83..5ccfdc8 100644
--- a/drivers/s390/cio/vfio_ccw_cp.c
+++ b/drivers/s390/cio/vfio_ccw_cp.c
@@ -481,7 +481,7 @@ static int ccwchain_fetch_tic(struct ccwchain *chain,
ccw_tail = ccw_head + (iter->ch_len - 1) * sizeof(struct ccw1);
if ((ccw_head <= ccw->cda) && (ccw->cda <= ccw_tail)) {
- ccw->cda = (__u32) (addr_t) (iter->ch_ccw +
+ ccw->cda = (__u32) (addr_t) (((char *)iter->ch_ccw) +
(ccw->cda - ccw_head));
return 0;
}
diff --git a/drivers/s390/crypto/zcrypt_card.c b/drivers/s390/crypto/zcrypt_card.c
index 53436ea..f85dacf 100644
--- a/drivers/s390/crypto/zcrypt_card.c
+++ b/drivers/s390/crypto/zcrypt_card.c
@@ -98,7 +98,7 @@ static struct attribute *zcrypt_card_attrs[] = {
NULL,
};
-static struct attribute_group zcrypt_card_attr_group = {
+static const struct attribute_group zcrypt_card_attr_group = {
.attrs = zcrypt_card_attrs,
};
diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/crypto/zcrypt_msgtype6.c
index 4fddb43..afd20ce 100644
--- a/drivers/s390/crypto/zcrypt_msgtype6.c
+++ b/drivers/s390/crypto/zcrypt_msgtype6.c
@@ -140,7 +140,7 @@ struct function_and_rules_block {
* + 0x000A 'MRP ' (MCL3 'PK' or CEX2C 'PK')
* - VUD block
*/
-static struct CPRBX static_cprbx = {
+static const struct CPRBX static_cprbx = {
.cprb_len = 0x00DC,
.cprb_ver_id = 0x02,
.func_id = {0x54, 0x32},
diff --git a/drivers/s390/crypto/zcrypt_queue.c b/drivers/s390/crypto/zcrypt_queue.c
index a303f3b..4742be0 100644
--- a/drivers/s390/crypto/zcrypt_queue.c
+++ b/drivers/s390/crypto/zcrypt_queue.c
@@ -89,7 +89,7 @@ static struct attribute *zcrypt_queue_attrs[] = {
NULL,
};
-static struct attribute_group zcrypt_queue_attr_group = {
+static const struct attribute_group zcrypt_queue_attr_group = {
.attrs = zcrypt_queue_attrs,
};
diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c
index f2f94f5..1a80ce4 100644
--- a/drivers/s390/net/qeth_l3_sys.c
+++ b/drivers/s390/net/qeth_l3_sys.c
@@ -350,7 +350,7 @@ static struct attribute *qeth_l3_device_attrs[] = {
NULL,
};
-static struct attribute_group qeth_l3_device_attr_group = {
+static const struct attribute_group qeth_l3_device_attr_group = {
.attrs = qeth_l3_device_attrs,
};
@@ -680,7 +680,7 @@ static struct attribute *qeth_ipato_device_attrs[] = {
NULL,
};
-static struct attribute_group qeth_device_ipato_group = {
+static const struct attribute_group qeth_device_ipato_group = {
.name = "ipa_takeover",
.attrs = qeth_ipato_device_attrs,
};
@@ -843,7 +843,7 @@ static struct attribute *qeth_vipa_device_attrs[] = {
NULL,
};
-static struct attribute_group qeth_device_vipa_group = {
+static const struct attribute_group qeth_device_vipa_group = {
.name = "vipa",
.attrs = qeth_vipa_device_attrs,
};
@@ -1006,7 +1006,7 @@ static struct attribute *qeth_rxip_device_attrs[] = {
NULL,
};
-static struct attribute_group qeth_device_rxip_group = {
+static const struct attribute_group qeth_device_rxip_group = {
.name = "rxip",
.attrs = qeth_rxip_device_attrs,
};
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index da5bdbd..f838bd7 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -4945,6 +4945,7 @@ static int ipr_slave_configure(struct scsi_device *sdev)
}
if (ipr_is_vset_device(res)) {
sdev->scsi_level = SCSI_SPC_3;
+ sdev->no_report_opcodes = 1;
blk_queue_rq_timeout(sdev->request_queue,
IPR_VSET_RW_TIMEOUT);
blk_queue_max_hw_sectors(sdev->request_queue, IPR_VSET_MAX_SECTORS);
diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c
index 5c4ded9..dc83927 100644
--- a/drivers/scsi/lasi700.c
+++ b/drivers/scsi/lasi700.c
@@ -81,7 +81,7 @@ MODULE_LICENSE("GPL");
#define LASI710_CLOCK 40
#define LASI_SCSI_CORE_OFFSET 0x100
-static struct parisc_device_id lasi700_ids[] = {
+static const struct parisc_device_id lasi700_ids[] __initconst = {
LASI700_ID_TABLE,
LASI710_ID_TABLE,
{ 0 }
@@ -164,11 +164,11 @@ lasi700_driver_remove(struct parisc_device *dev)
return 0;
}
-static struct parisc_driver lasi700_driver = {
+static struct parisc_driver lasi700_driver __refdata = {
.name = "lasi_scsi",
.id_table = lasi700_ids,
.probe = lasi700_probe,
- .remove = lasi700_driver_remove,
+ .remove = __exit_p(lasi700_driver_remove),
};
static int __init
diff --git a/drivers/scsi/qedf/qedf_els.c b/drivers/scsi/qedf/qedf_els.c
index eb07f1d..59c18ca 100644
--- a/drivers/scsi/qedf/qedf_els.c
+++ b/drivers/scsi/qedf/qedf_els.c
@@ -489,7 +489,7 @@ static void qedf_srr_compl(struct qedf_els_cb_arg *cb_arg)
/* If a SRR times out, simply free resources */
if (srr_req->event == QEDF_IOREQ_EV_ELS_TMO)
- goto out_free;
+ goto out_put;
/* Normalize response data into struct fc_frame */
mp_req = &(srr_req->mp_req);
@@ -501,7 +501,7 @@ static void qedf_srr_compl(struct qedf_els_cb_arg *cb_arg)
if (!fp) {
QEDF_ERR(&(qedf->dbg_ctx),
"fc_frame_alloc failure.\n");
- goto out_free;
+ goto out_put;
}
/* Copy frame header from firmware into fp */
@@ -526,9 +526,10 @@ static void qedf_srr_compl(struct qedf_els_cb_arg *cb_arg)
}
fc_frame_free(fp);
-out_free:
+out_put:
/* Put reference for original command since SRR completed */
kref_put(&orig_io_req->refcount, qedf_release_cmd);
+out_free:
kfree(cb_arg);
}
@@ -780,7 +781,7 @@ static void qedf_rec_compl(struct qedf_els_cb_arg *cb_arg)
/* If a REC times out, free resources */
if (rec_req->event == QEDF_IOREQ_EV_ELS_TMO)
- goto out_free;
+ goto out_put;
/* Normalize response data into struct fc_frame */
mp_req = &(rec_req->mp_req);
@@ -792,7 +793,7 @@ static void qedf_rec_compl(struct qedf_els_cb_arg *cb_arg)
if (!fp) {
QEDF_ERR(&(qedf->dbg_ctx),
"fc_frame_alloc failure.\n");
- goto out_free;
+ goto out_put;
}
/* Copy frame header from firmware into fp */
@@ -884,9 +885,10 @@ static void qedf_rec_compl(struct qedf_els_cb_arg *cb_arg)
out_free_frame:
fc_frame_free(fp);
-out_free:
+out_put:
/* Put reference for original command since REC completed */
kref_put(&orig_io_req->refcount, qedf_release_cmd);
+out_free:
kfree(cb_arg);
}
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index d7ff71e..84e782d 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1021,7 +1021,7 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
read_lock_irqsave(&sfp->rq_list_lock, iflags);
val = 0;
list_for_each_entry(srp, &sfp->rq_list, entry) {
- if (val > SG_MAX_QUEUE)
+ if (val >= SG_MAX_QUEUE)
break;
memset(&rinfo[val], 0, SZ_SG_REQ_INFO);
rinfo[val].req_state = srp->done + 1;
diff --git a/drivers/scsi/zalon.c b/drivers/scsi/zalon.c
index b2cf1fa..4722660 100644
--- a/drivers/scsi/zalon.c
+++ b/drivers/scsi/zalon.c
@@ -160,14 +160,14 @@ zalon_probe(struct parisc_device *dev)
return error;
}
-static struct parisc_device_id zalon_tbl[] = {
+static const struct parisc_device_id zalon_tbl[] __initconst = {
{ HPHW_A_DMA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00089 },
{ 0, }
};
MODULE_DEVICE_TABLE(parisc, zalon_tbl);
-static int zalon_remove(struct parisc_device *dev)
+static int __exit zalon_remove(struct parisc_device *dev)
{
struct Scsi_Host *host = dev_get_drvdata(&dev->dev);
@@ -178,11 +178,11 @@ static int zalon_remove(struct parisc_device *dev)
return 0;
}
-static struct parisc_driver zalon_driver = {
+static struct parisc_driver zalon_driver __refdata = {
.name = "zalon",
.id_table = zalon_tbl,
.probe = zalon_probe,
- .remove = zalon_remove,
+ .remove = __exit_p(zalon_remove),
};
static int __init zalon7xx_init(void)
diff --git a/drivers/sfi/sfi_core.c b/drivers/sfi/sfi_core.c
index 296db7a..153b3f3 100644
--- a/drivers/sfi/sfi_core.c
+++ b/drivers/sfi/sfi_core.c
@@ -68,6 +68,7 @@
#include <linux/init.h>
#include <linux/sfi.h>
#include <linux/slab.h>
+#include <linux/io.h>
#include "sfi_core.h"
@@ -86,13 +87,13 @@ static struct sfi_table_simple *syst_va __read_mostly;
/*
* FW creates and saves the SFI tables in memory. When these tables get
* used, they may need to be mapped to virtual address space, and the mapping
- * can happen before or after the ioremap() is ready, so a flag is needed
+ * can happen before or after the memremap() is ready, so a flag is needed
* to indicating this
*/
-static u32 sfi_use_ioremap __read_mostly;
+static u32 sfi_use_memremap __read_mostly;
/*
- * sfi_un/map_memory calls early_ioremap/iounmap which is a __init function
+ * sfi_un/map_memory calls early_memremap/memunmap which is a __init function
* and introduces section mismatch. So use __ref to make it calm.
*/
static void __iomem * __ref sfi_map_memory(u64 phys, u32 size)
@@ -100,10 +101,10 @@ static void __iomem * __ref sfi_map_memory(u64 phys, u32 size)
if (!phys || !size)
return NULL;
- if (sfi_use_ioremap)
- return ioremap_cache(phys, size);
+ if (sfi_use_memremap)
+ return memremap(phys, size, MEMREMAP_WB);
else
- return early_ioremap(phys, size);
+ return early_memremap(phys, size);
}
static void __ref sfi_unmap_memory(void __iomem *virt, u32 size)
@@ -111,10 +112,10 @@ static void __ref sfi_unmap_memory(void __iomem *virt, u32 size)
if (!virt || !size)
return;
- if (sfi_use_ioremap)
- iounmap(virt);
+ if (sfi_use_memremap)
+ memunmap(virt);
else
- early_iounmap(virt, size);
+ early_memunmap(virt, size);
}
static void sfi_print_table_header(unsigned long long pa,
@@ -507,8 +508,8 @@ void __init sfi_init_late(void)
length = syst_va->header.len;
sfi_unmap_memory(syst_va, sizeof(struct sfi_table_simple));
- /* Use ioremap now after it is ready */
- sfi_use_ioremap = 1;
+ /* Use memremap now after it is ready */
+ sfi_use_memremap = 1;
syst_va = sfi_map_memory(syst_pa, length);
sfi_acpi_init();
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index ef28a1c..1b0a1be 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -40,6 +40,8 @@ source "drivers/staging/rtl8712/Kconfig"
source "drivers/staging/rtl8188eu/Kconfig"
+source "drivers/staging/rtlwifi/Kconfig"
+
source "drivers/staging/rts5208/Kconfig"
source "drivers/staging/octeon/Kconfig"
@@ -112,4 +114,6 @@ source "drivers/staging/typec/Kconfig"
source "drivers/staging/vboxvideo/Kconfig"
+source "drivers/staging/pi433/Kconfig"
+
endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 2918580..2b61cbd 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_RTL8192E) += rtl8192e/
obj-$(CONFIG_RTL8723BS) += rtl8723bs/
obj-$(CONFIG_R8712U) += rtl8712/
obj-$(CONFIG_R8188EU) += rtl8188eu/
+obj-$(CONFIG_R8822BE) += rtlwifi/
obj-$(CONFIG_RTS5208) += rts5208/
obj-$(CONFIG_NETLOGIC_XLR_NET) += netlogic/
obj-$(CONFIG_OCTEON_ETHERNET) += octeon/
@@ -45,3 +46,4 @@ obj-$(CONFIG_GREYBUS) += greybus/
obj-$(CONFIG_BCM2835_VCHIQ) += vc04_services/
obj-$(CONFIG_CRYPTO_DEV_CCREE) += ccree/
obj-$(CONFIG_DRM_VBOXVIDEO) += vboxvideo/
+obj-$(CONFIG_PI433) += pi433/
diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h
index fa9ed81..621e5f7 100644
--- a/drivers/staging/android/ion/ion.h
+++ b/drivers/staging/android/ion/ion.h
@@ -135,7 +135,7 @@ struct ion_heap_ops {
/**
* heap flags - flags between the heaps and core ion code
*/
-#define ION_HEAP_FLAG_DEFER_FREE (1 << 0)
+#define ION_HEAP_FLAG_DEFER_FREE BIT(0)
/**
* private flags - flags internal to ion
@@ -146,7 +146,7 @@ struct ion_heap_ops {
* any buffer storage that came from the system allocator will be
* returned to the system allocator.
*/
-#define ION_PRIV_FLAG_SHRINKER_FREE (1 << 0)
+#define ION_PRIV_FLAG_SHRINKER_FREE BIT(0)
/**
* struct ion_heap - represents a heap in the system
@@ -226,8 +226,8 @@ int ion_heap_buffer_zero(struct ion_buffer *buffer);
int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot);
int ion_alloc(size_t len,
- unsigned int heap_id_mask,
- unsigned int flags);
+ unsigned int heap_id_mask,
+ unsigned int flags);
/**
* ion_heap_init_shrinker
@@ -291,7 +291,7 @@ size_t ion_heap_freelist_drain(struct ion_heap *heap, size_t size);
* flag.
*/
size_t ion_heap_freelist_shrink(struct ion_heap *heap,
- size_t size);
+ size_t size);
/**
* ion_heap_freelist_size - returns the size of the freelist in bytes
@@ -352,7 +352,7 @@ void ion_page_pool_free(struct ion_page_pool *pool, struct page *page);
* returns the number of items freed in pages
*/
int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask,
- int nr_to_scan);
+ int nr_to_scan);
long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c
index a0949bc..dd5545d 100644
--- a/drivers/staging/android/ion/ion_cma_heap.c
+++ b/drivers/staging/android/ion/ion_cma_heap.c
@@ -31,7 +31,6 @@ struct ion_cma_heap {
#define to_cma_heap(x) container_of(x, struct ion_cma_heap, heap)
-
/* ION CMA heap operations functions */
static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer,
unsigned long len,
@@ -46,7 +45,7 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer,
if (!pages)
return -ENOMEM;
- table = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
+ table = kmalloc(sizeof(*table), GFP_KERNEL);
if (!table)
goto err;
@@ -106,7 +105,7 @@ static struct ion_heap *__ion_cma_heap_create(struct cma *cma)
return &cma_heap->heap;
}
-int __ion_add_cma_heaps(struct cma *cma, void *data)
+static int __ion_add_cma_heaps(struct cma *cma, void *data)
{
struct ion_heap *heap;
diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c
index 5964bf2..4dc5d7a 100644
--- a/drivers/staging/android/ion/ion_system_heap.c
+++ b/drivers/staging/android/ion/ion_system_heap.c
@@ -98,7 +98,6 @@ static void free_buffer_page(struct ion_system_heap *heap,
ion_page_pool_free(pool, page);
}
-
static struct page *alloc_largest_available(struct ion_system_heap *heap,
struct ion_buffer *buffer,
unsigned long size,
@@ -256,7 +255,6 @@ static struct ion_heap_ops system_heap_ops = {
static int ion_system_heap_debug_show(struct ion_heap *heap, struct seq_file *s,
void *unused)
{
-
struct ion_system_heap *sys_heap = container_of(heap,
struct ion_system_heap,
heap);
diff --git a/drivers/staging/ccree/Kconfig b/drivers/staging/ccree/Kconfig
index 36a87c6..0b3092b 100644
--- a/drivers/staging/ccree/Kconfig
+++ b/drivers/staging/ccree/Kconfig
@@ -23,12 +23,3 @@ config CRYPTO_DEV_CCREE
Choose this if you wish to use hardware acceleration of
cryptographic operations on the system REE.
If unsure say Y.
-
-config CCREE_FIPS_SUPPORT
- bool "Turn on CryptoCell 7XX REE FIPS mode support"
- depends on CRYPTO_DEV_CCREE
- default n
- help
- Say 'Y' to enable support for FIPS compliant mode by the
- CCREE driver.
- If unsure say N.
diff --git a/drivers/staging/ccree/Makefile b/drivers/staging/ccree/Makefile
index 318c2b3..ae702f3 100644
--- a/drivers/staging/ccree/Makefile
+++ b/drivers/staging/ccree/Makefile
@@ -1,3 +1,3 @@
obj-$(CONFIG_CRYPTO_DEV_CCREE) := ccree.o
ccree-y := ssi_driver.o ssi_sysfs.o ssi_buffer_mgr.o ssi_request_mgr.o ssi_cipher.o ssi_hash.o ssi_aead.o ssi_ivgen.o ssi_sram_mgr.o ssi_pm.o
-ccree-$(CCREE_FIPS_SUPPORT) += ssi_fips.o ssi_fips_ll.o ssi_fips_ext.o ssi_fips_local.o
+ccree-$(CONFIG_CRYPTO_FIPS) += ssi_fips.o
diff --git a/drivers/staging/ccree/cc_hw_queue_defs.h b/drivers/staging/ccree/cc_hw_queue_defs.h
index e6b8cea..2ae0f65 100644
--- a/drivers/staging/ccree/cc_hw_queue_defs.h
+++ b/drivers/staging/ccree/cc_hw_queue_defs.h
@@ -27,7 +27,8 @@
******************************************************************************/
#define HW_DESC_SIZE_WORDS 6
-#define HW_QUEUE_SLOTS_MAX 15 /* Max. available slots in HW queue */
+/* Define max. available slots in HW queue */
+#define HW_QUEUE_SLOTS_MAX 15
#define CC_REG_NAME(word, name) DX_DSCRPTR_QUEUE_WORD ## word ## _ ## name
diff --git a/drivers/staging/ccree/ssi_aead.c b/drivers/staging/ccree/ssi_aead.c
index 1fc0b05..5abe6b2 100644
--- a/drivers/staging/ccree/ssi_aead.c
+++ b/drivers/staging/ccree/ssi_aead.c
@@ -36,7 +36,6 @@
#include "ssi_hash.h"
#include "ssi_sysfs.h"
#include "ssi_sram_mgr.h"
-#include "ssi_fips_local.h"
#define template_aead template_u.aead
@@ -57,22 +56,26 @@ struct ssi_aead_handle {
struct list_head aead_list;
};
+struct cc_hmac_s {
+ u8 *padded_authkey;
+ u8 *ipad_opad; /* IPAD, OPAD*/
+ dma_addr_t padded_authkey_dma_addr;
+ dma_addr_t ipad_opad_dma_addr;
+};
+
+struct cc_xcbc_s {
+ u8 *xcbc_keys; /* K1,K2,K3 */
+ dma_addr_t xcbc_keys_dma_addr;
+};
+
struct ssi_aead_ctx {
struct ssi_drvdata *drvdata;
u8 ctr_nonce[MAX_NONCE_SIZE]; /* used for ctr3686 iv and aes ccm */
u8 *enckey;
dma_addr_t enckey_dma_addr;
union {
- struct {
- u8 *padded_authkey;
- u8 *ipad_opad; /* IPAD, OPAD*/
- dma_addr_t padded_authkey_dma_addr;
- dma_addr_t ipad_opad_dma_addr;
- } hmac;
- struct {
- u8 *xcbc_keys; /* K1,K2,K3 */
- dma_addr_t xcbc_keys_dma_addr;
- } xcbc;
+ struct cc_hmac_s hmac;
+ struct cc_xcbc_s xcbc;
} auth_state;
unsigned int enc_keylen;
unsigned int auth_keylen;
@@ -93,46 +96,50 @@ static void ssi_aead_exit(struct crypto_aead *tfm)
struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm);
SSI_LOG_DEBUG("Clearing context @%p for %s\n",
- crypto_aead_ctx(tfm), crypto_tfm_alg_name(&(tfm->base)));
+ crypto_aead_ctx(tfm), crypto_tfm_alg_name(&tfm->base));
dev = &ctx->drvdata->plat_dev->dev;
/* Unmap enckey buffer */
if (ctx->enckey) {
dma_free_coherent(dev, AES_MAX_KEY_SIZE, ctx->enckey, ctx->enckey_dma_addr);
- SSI_LOG_DEBUG("Freed enckey DMA buffer enckey_dma_addr=0x%llX\n",
- (unsigned long long)ctx->enckey_dma_addr);
+ SSI_LOG_DEBUG("Freed enckey DMA buffer enckey_dma_addr=%pad\n",
+ ctx->enckey_dma_addr);
ctx->enckey_dma_addr = 0;
ctx->enckey = NULL;
}
if (ctx->auth_mode == DRV_HASH_XCBC_MAC) { /* XCBC authetication */
- if (ctx->auth_state.xcbc.xcbc_keys) {
+ struct cc_xcbc_s *xcbc = &ctx->auth_state.xcbc;
+
+ if (xcbc->xcbc_keys) {
dma_free_coherent(dev, CC_AES_128_BIT_KEY_SIZE * 3,
- ctx->auth_state.xcbc.xcbc_keys,
- ctx->auth_state.xcbc.xcbc_keys_dma_addr);
+ xcbc->xcbc_keys,
+ xcbc->xcbc_keys_dma_addr);
}
- SSI_LOG_DEBUG("Freed xcbc_keys DMA buffer xcbc_keys_dma_addr=0x%llX\n",
- (unsigned long long)ctx->auth_state.xcbc.xcbc_keys_dma_addr);
- ctx->auth_state.xcbc.xcbc_keys_dma_addr = 0;
- ctx->auth_state.xcbc.xcbc_keys = NULL;
+ SSI_LOG_DEBUG("Freed xcbc_keys DMA buffer xcbc_keys_dma_addr=%pad\n",
+ xcbc->xcbc_keys_dma_addr);
+ xcbc->xcbc_keys_dma_addr = 0;
+ xcbc->xcbc_keys = NULL;
} else if (ctx->auth_mode != DRV_HASH_NULL) { /* HMAC auth. */
- if (ctx->auth_state.hmac.ipad_opad) {
+ struct cc_hmac_s *hmac = &ctx->auth_state.hmac;
+
+ if (hmac->ipad_opad) {
dma_free_coherent(dev, 2 * MAX_HMAC_DIGEST_SIZE,
- ctx->auth_state.hmac.ipad_opad,
- ctx->auth_state.hmac.ipad_opad_dma_addr);
- SSI_LOG_DEBUG("Freed ipad_opad DMA buffer ipad_opad_dma_addr=0x%llX\n",
- (unsigned long long)ctx->auth_state.hmac.ipad_opad_dma_addr);
- ctx->auth_state.hmac.ipad_opad_dma_addr = 0;
- ctx->auth_state.hmac.ipad_opad = NULL;
+ hmac->ipad_opad,
+ hmac->ipad_opad_dma_addr);
+ SSI_LOG_DEBUG("Freed ipad_opad DMA buffer ipad_opad_dma_addr=%pad\n",
+ hmac->ipad_opad_dma_addr);
+ hmac->ipad_opad_dma_addr = 0;
+ hmac->ipad_opad = NULL;
}
- if (ctx->auth_state.hmac.padded_authkey) {
+ if (hmac->padded_authkey) {
dma_free_coherent(dev, MAX_HMAC_BLOCK_SIZE,
- ctx->auth_state.hmac.padded_authkey,
- ctx->auth_state.hmac.padded_authkey_dma_addr);
- SSI_LOG_DEBUG("Freed padded_authkey DMA buffer padded_authkey_dma_addr=0x%llX\n",
- (unsigned long long)ctx->auth_state.hmac.padded_authkey_dma_addr);
- ctx->auth_state.hmac.padded_authkey_dma_addr = 0;
- ctx->auth_state.hmac.padded_authkey = NULL;
+ hmac->padded_authkey,
+ hmac->padded_authkey_dma_addr);
+ SSI_LOG_DEBUG("Freed padded_authkey DMA buffer padded_authkey_dma_addr=%pad\n",
+ hmac->padded_authkey_dma_addr);
+ hmac->padded_authkey_dma_addr = 0;
+ hmac->padded_authkey = NULL;
}
}
}
@@ -144,9 +151,7 @@ static int ssi_aead_init(struct crypto_aead *tfm)
struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm);
struct ssi_crypto_alg *ssi_alg =
container_of(alg, struct ssi_crypto_alg, aead_alg);
- SSI_LOG_DEBUG("Initializing context @%p for %s\n", ctx, crypto_tfm_alg_name(&(tfm->base)));
-
- CHECK_AND_RETURN_UPON_FIPS_ERROR();
+ SSI_LOG_DEBUG("Initializing context @%p for %s\n", ctx, crypto_tfm_alg_name(&tfm->base));
/* Initialize modes in instance */
ctx->cipher_mode = ssi_alg->cipher_mode;
@@ -158,7 +163,7 @@ static int ssi_aead_init(struct crypto_aead *tfm)
/* Allocate key buffer, cache line aligned */
ctx->enckey = dma_alloc_coherent(dev, AES_MAX_KEY_SIZE,
- &ctx->enckey_dma_addr, GFP_KERNEL);
+ &ctx->enckey_dma_addr, GFP_KERNEL);
if (!ctx->enckey) {
SSI_LOG_ERR("Failed allocating key buffer\n");
goto init_failed;
@@ -168,31 +173,42 @@ static int ssi_aead_init(struct crypto_aead *tfm)
/* Set default authlen value */
if (ctx->auth_mode == DRV_HASH_XCBC_MAC) { /* XCBC authetication */
+ struct cc_xcbc_s *xcbc = &ctx->auth_state.xcbc;
+ const unsigned int key_size = CC_AES_128_BIT_KEY_SIZE * 3;
+
/* Allocate dma-coherent buffer for XCBC's K1+K2+K3 */
/* (and temporary for user key - up to 256b) */
- ctx->auth_state.xcbc.xcbc_keys = dma_alloc_coherent(dev,
- CC_AES_128_BIT_KEY_SIZE * 3,
- &ctx->auth_state.xcbc.xcbc_keys_dma_addr, GFP_KERNEL);
- if (!ctx->auth_state.xcbc.xcbc_keys) {
+ xcbc->xcbc_keys = dma_alloc_coherent(dev, key_size,
+ &xcbc->xcbc_keys_dma_addr,
+ GFP_KERNEL);
+ if (!xcbc->xcbc_keys) {
SSI_LOG_ERR("Failed allocating buffer for XCBC keys\n");
goto init_failed;
}
} else if (ctx->auth_mode != DRV_HASH_NULL) { /* HMAC authentication */
+ struct cc_hmac_s *hmac = &ctx->auth_state.hmac;
+ const unsigned int digest_size = 2 * MAX_HMAC_DIGEST_SIZE;
+ dma_addr_t *pkey_dma = &hmac->padded_authkey_dma_addr;
+
/* Allocate dma-coherent buffer for IPAD + OPAD */
- ctx->auth_state.hmac.ipad_opad = dma_alloc_coherent(dev,
- 2 * MAX_HMAC_DIGEST_SIZE,
- &ctx->auth_state.hmac.ipad_opad_dma_addr, GFP_KERNEL);
- if (!ctx->auth_state.hmac.ipad_opad) {
+ hmac->ipad_opad = dma_alloc_coherent(dev, digest_size,
+ &hmac->ipad_opad_dma_addr,
+ GFP_KERNEL);
+
+ if (!hmac->ipad_opad) {
SSI_LOG_ERR("Failed allocating IPAD/OPAD buffer\n");
goto init_failed;
}
+
SSI_LOG_DEBUG("Allocated authkey buffer in context ctx->authkey=@%p\n",
- ctx->auth_state.hmac.ipad_opad);
+ hmac->ipad_opad);
+
+ hmac->padded_authkey = dma_alloc_coherent(dev,
+ MAX_HMAC_BLOCK_SIZE,
+ pkey_dma,
+ GFP_KERNEL);
- ctx->auth_state.hmac.padded_authkey = dma_alloc_coherent(dev,
- MAX_HMAC_BLOCK_SIZE,
- &ctx->auth_state.hmac.padded_authkey_dma_addr, GFP_KERNEL);
- if (!ctx->auth_state.hmac.padded_authkey) {
+ if (!hmac->padded_authkey) {
SSI_LOG_ERR("failed to allocate padded_authkey\n");
goto init_failed;
}
@@ -223,7 +239,7 @@ static void ssi_aead_complete(struct device *dev, void *ssi_req, void __iomem *c
if (areq_ctx->gen_ctx.op_type == DRV_CRYPTO_DIRECTION_DECRYPT) {
if (memcmp(areq_ctx->mac_buf, areq_ctx->icv_virt_addr,
- ctx->authsize) != 0) {
+ ctx->authsize) != 0) {
SSI_LOG_DEBUG("Payload authentication failure, "
"(auth-size=%d, cipher=%d).\n",
ctx->authsize, ctx->cipher_mode);
@@ -236,8 +252,8 @@ static void ssi_aead_complete(struct device *dev, void *ssi_req, void __iomem *c
} else { /*ENCRYPT*/
if (unlikely(areq_ctx->is_icv_fragmented))
ssi_buffer_mgr_copy_scatterlist_portion(
- areq_ctx->mac_buf, areq_ctx->dstSgl, areq->cryptlen + areq_ctx->dstOffset,
- areq->cryptlen + areq_ctx->dstOffset + ctx->authsize, SSI_SG_FROM_BUF);
+ areq_ctx->mac_buf, areq_ctx->dst_sgl, areq->cryptlen + areq_ctx->dst_offset,
+ areq->cryptlen + areq_ctx->dst_offset + ctx->authsize, SSI_SG_FROM_BUF);
/* If an IV was generated, copy it back to the user provided buffer. */
if (areq_ctx->backup_giv) {
@@ -292,12 +308,13 @@ static int xcbc_setkey(struct cc_hw_desc *desc, struct ssi_aead_ctx *ctx)
static int hmac_setkey(struct cc_hw_desc *desc, struct ssi_aead_ctx *ctx)
{
- unsigned int hmacPadConst[2] = { HMAC_IPAD_CONST, HMAC_OPAD_CONST };
+ unsigned int hmac_pad_const[2] = { HMAC_IPAD_CONST, HMAC_OPAD_CONST };
unsigned int digest_ofs = 0;
unsigned int hash_mode = (ctx->auth_mode == DRV_HASH_SHA1) ?
DRV_HASH_HW_SHA1 : DRV_HASH_HW_SHA256;
unsigned int digest_size = (ctx->auth_mode == DRV_HASH_SHA1) ?
CC_SHA1_DIGEST_SIZE : CC_SHA256_DIGEST_SIZE;
+ struct cc_hmac_s *hmac = &ctx->auth_state.hmac;
int idx = 0;
int i;
@@ -325,7 +342,7 @@ static int hmac_setkey(struct cc_hw_desc *desc, struct ssi_aead_ctx *ctx)
/* Prepare ipad key */
hw_desc_init(&desc[idx]);
- set_xor_val(&desc[idx], hmacPadConst[i]);
+ set_xor_val(&desc[idx], hmac_pad_const[i]);
set_cipher_mode(&desc[idx], hash_mode);
set_flow_mode(&desc[idx], S_DIN_to_HASH);
set_setup_mode(&desc[idx], SETUP_LOAD_STATE1);
@@ -334,7 +351,7 @@ static int hmac_setkey(struct cc_hw_desc *desc, struct ssi_aead_ctx *ctx)
/* Perform HASH update */
hw_desc_init(&desc[idx]);
set_din_type(&desc[idx], DMA_DLLI,
- ctx->auth_state.hmac.padded_authkey_dma_addr,
+ hmac->padded_authkey_dma_addr,
SHA256_BLOCK_SIZE, NS_BIT);
set_cipher_mode(&desc[idx], hash_mode);
set_xor_active(&desc[idx]);
@@ -345,8 +362,8 @@ static int hmac_setkey(struct cc_hw_desc *desc, struct ssi_aead_ctx *ctx)
hw_desc_init(&desc[idx]);
set_cipher_mode(&desc[idx], hash_mode);
set_dout_dlli(&desc[idx],
- (ctx->auth_state.hmac.ipad_opad_dma_addr +
- digest_ofs), digest_size, NS_BIT, 0);
+ (hmac->ipad_opad_dma_addr + digest_ofs),
+ digest_size, NS_BIT, 0);
set_flow_mode(&desc[idx], S_HASH_to_DOUT);
set_setup_mode(&desc[idx], SETUP_WRITE_STATE0);
set_cipher_config1(&desc[idx], HASH_PADDING_DISABLED);
@@ -361,7 +378,7 @@ static int hmac_setkey(struct cc_hw_desc *desc, struct ssi_aead_ctx *ctx)
static int validate_keys_sizes(struct ssi_aead_ctx *ctx)
{
SSI_LOG_DEBUG("enc_keylen=%u authkeylen=%u\n",
- ctx->enc_keylen, ctx->auth_keylen);
+ ctx->enc_keylen, ctx->auth_keylen);
switch (ctx->auth_mode) {
case DRV_HASH_SHA1:
@@ -385,7 +402,7 @@ static int validate_keys_sizes(struct ssi_aead_ctx *ctx)
if (unlikely(ctx->flow_mode == S_DIN_to_DES)) {
if (ctx->enc_keylen != DES3_EDE_KEY_SIZE) {
SSI_LOG_ERR("Invalid cipher(3DES) key size: %u\n",
- ctx->enc_keylen);
+ ctx->enc_keylen);
return -EINVAL;
}
} else { /* Default assumed to be AES ciphers */
@@ -393,7 +410,7 @@ static int validate_keys_sizes(struct ssi_aead_ctx *ctx)
(ctx->enc_keylen != AES_KEYSIZE_192) &&
(ctx->enc_keylen != AES_KEYSIZE_256)) {
SSI_LOG_ERR("Invalid cipher(AES) key size: %u\n",
- ctx->enc_keylen);
+ ctx->enc_keylen);
return -EINVAL;
}
}
@@ -536,9 +553,9 @@ ssi_aead_setkey(struct crypto_aead *tfm, const u8 *key, unsigned int keylen)
int seq_len = 0, rc = -EINVAL;
SSI_LOG_DEBUG("Setting key in context @%p for %s. key=%p keylen=%u\n",
- ctx, crypto_tfm_alg_name(crypto_aead_tfm(tfm)), key, keylen);
+ ctx, crypto_tfm_alg_name(crypto_aead_tfm(tfm)),
+ key, keylen);
- CHECK_AND_RETURN_UPON_FIPS_ERROR();
/* STAT_PHASE_0: Init and sanity checks */
if (ctx->auth_mode != DRV_HASH_NULL) { /* authenc() alg. */
@@ -654,7 +671,6 @@ static int ssi_aead_setauthsize(
{
struct ssi_aead_ctx *ctx = crypto_aead_ctx(authenc);
- CHECK_AND_RETURN_UPON_FIPS_ERROR();
/* Unsupported auth. sizes */
if ((authsize == 0) ||
(authsize > crypto_aead_maxauthsize(authenc))) {
@@ -669,7 +685,7 @@ static int ssi_aead_setauthsize(
#if SSI_CC_HAS_AES_CCM
static int ssi_rfc4309_ccm_setauthsize(struct crypto_aead *authenc,
- unsigned int authsize)
+ unsigned int authsize)
{
switch (authsize) {
case 8:
@@ -684,7 +700,7 @@ static int ssi_rfc4309_ccm_setauthsize(struct crypto_aead *authenc,
}
static int ssi_ccm_setauthsize(struct crypto_aead *authenc,
- unsigned int authsize)
+ unsigned int authsize)
{
switch (authsize) {
case 4:
@@ -762,11 +778,11 @@ ssi_aead_process_authenc_data_desc(
{
struct scatterlist *cipher =
(direct == DRV_CRYPTO_DIRECTION_ENCRYPT) ?
- areq_ctx->dstSgl : areq_ctx->srcSgl;
+ areq_ctx->dst_sgl : areq_ctx->src_sgl;
unsigned int offset =
(direct == DRV_CRYPTO_DIRECTION_ENCRYPT) ?
- areq_ctx->dstOffset : areq_ctx->srcOffset;
+ areq_ctx->dst_offset : areq_ctx->src_offset;
SSI_LOG_DEBUG("AUTHENC: SRC/DST buffer type DLLI\n");
hw_desc_init(&desc[idx]);
set_din_type(&desc[idx], DMA_DLLI,
@@ -828,11 +844,11 @@ ssi_aead_process_cipher_data_desc(
SSI_LOG_DEBUG("CIPHER: SRC/DST buffer type DLLI\n");
hw_desc_init(&desc[idx]);
set_din_type(&desc[idx], DMA_DLLI,
- (sg_dma_address(areq_ctx->srcSgl) +
- areq_ctx->srcOffset), areq_ctx->cryptlen, NS_BIT);
+ (sg_dma_address(areq_ctx->src_sgl) +
+ areq_ctx->src_offset), areq_ctx->cryptlen, NS_BIT);
set_dout_dlli(&desc[idx],
- (sg_dma_address(areq_ctx->dstSgl) +
- areq_ctx->dstOffset),
+ (sg_dma_address(areq_ctx->dst_sgl) +
+ areq_ctx->dst_offset),
areq_ctx->cryptlen, NS_BIT, 0);
set_flow_mode(&desc[idx], flow_mode);
break;
@@ -1168,8 +1184,8 @@ static inline void ssi_aead_load_mlli_to_sram(
(req_ctx->data_buff_type == SSI_DMA_BUF_MLLI) ||
!req_ctx->is_single_pass)) {
SSI_LOG_DEBUG("Copy-to-sram: mlli_dma=%08x, mlli_size=%u\n",
- (unsigned int)ctx->drvdata->mlli_sram_addr,
- req_ctx->mlli_params.mlli_len);
+ (unsigned int)ctx->drvdata->mlli_sram_addr,
+ req_ctx->mlli_params.mlli_len);
/* Copy MLLI table host-to-sram */
hw_desc_init(&desc[*seq_size]);
set_din_type(&desc[*seq_size], DMA_DLLI,
@@ -1313,7 +1329,8 @@ ssi_aead_xcbc_authenc(
}
static int validate_data_size(struct ssi_aead_ctx *ctx,
- enum drv_crypto_direction direct, struct aead_request *req)
+ enum drv_crypto_direction direct,
+ struct aead_request *req)
{
struct aead_req_ctx *areq_ctx = aead_request_ctx(req);
unsigned int assoclen = req->assoclen;
@@ -1321,7 +1338,7 @@ static int validate_data_size(struct ssi_aead_ctx *ctx,
(req->cryptlen - ctx->authsize) : req->cryptlen;
if (unlikely((direct == DRV_CRYPTO_DIRECTION_DECRYPT) &&
- (req->cryptlen < ctx->authsize)))
+ (req->cryptlen < ctx->authsize)))
goto data_size_err;
areq_ctx->is_single_pass = true; /*defaulted to fast flow*/
@@ -1329,7 +1346,7 @@ static int validate_data_size(struct ssi_aead_ctx *ctx,
switch (ctx->flow_mode) {
case S_DIN_to_AES:
if (unlikely((ctx->cipher_mode == DRV_CIPHER_CBC) &&
- !IS_ALIGNED(cipherlen, AES_BLOCK_SIZE)))
+ !IS_ALIGNED(cipherlen, AES_BLOCK_SIZE)))
goto data_size_err;
if (ctx->cipher_mode == DRV_CIPHER_CCM)
break;
@@ -1365,27 +1382,27 @@ data_size_err:
}
#if SSI_CC_HAS_AES_CCM
-static unsigned int format_ccm_a0(u8 *pA0Buff, u32 headerSize)
+static unsigned int format_ccm_a0(u8 *pa0_buff, u32 header_size)
{
unsigned int len = 0;
- if (headerSize == 0)
+ if (header_size == 0)
return 0;
- if (headerSize < ((1UL << 16) - (1UL << 8))) {
+ if (header_size < ((1UL << 16) - (1UL << 8))) {
len = 2;
- pA0Buff[0] = (headerSize >> 8) & 0xFF;
- pA0Buff[1] = headerSize & 0xFF;
+ pa0_buff[0] = (header_size >> 8) & 0xFF;
+ pa0_buff[1] = header_size & 0xFF;
} else {
len = 6;
- pA0Buff[0] = 0xFF;
- pA0Buff[1] = 0xFE;
- pA0Buff[2] = (headerSize >> 24) & 0xFF;
- pA0Buff[3] = (headerSize >> 16) & 0xFF;
- pA0Buff[4] = (headerSize >> 8) & 0xFF;
- pA0Buff[5] = headerSize & 0xFF;
+ pa0_buff[0] = 0xFF;
+ pa0_buff[1] = 0xFE;
+ pa0_buff[2] = (header_size >> 24) & 0xFF;
+ pa0_buff[3] = (header_size >> 16) & 0xFF;
+ pa0_buff[4] = (header_size >> 8) & 0xFF;
+ pa0_buff[5] = header_size & 0xFF;
}
return len;
@@ -1557,7 +1574,7 @@ static int config_ccm_adata(struct aead_request *req)
/* taken from crypto/ccm.c */
/* 2 <= L <= 8, so 1 <= L' <= 7. */
- if (2 > l || l > 8) {
+ if (l < 2 || l > 8) {
SSI_LOG_ERR("illegal iv value %X\n", req->iv[0]);
return -EINVAL;
}
@@ -1848,8 +1865,9 @@ static inline void ssi_aead_dump_gcm(
SSI_LOG_DEBUG("%s\n", title);
}
- SSI_LOG_DEBUG("cipher_mode %d, authsize %d, enc_keylen %d, assoclen %d, cryptlen %d\n", \
- ctx->cipher_mode, ctx->authsize, ctx->enc_keylen, req->assoclen, req_ctx->cryptlen);
+ SSI_LOG_DEBUG("cipher_mode %d, authsize %d, enc_keylen %d, assoclen %d, cryptlen %d\n",
+ ctx->cipher_mode, ctx->authsize, ctx->enc_keylen,
+ req->assoclen, req_ctx->cryptlen);
if (ctx->enckey)
dump_byte_array("mac key", ctx->enckey, 16);
@@ -1864,7 +1882,7 @@ static inline void ssi_aead_dump_gcm(
dump_byte_array("mac_buf", req_ctx->mac_buf, AES_BLOCK_SIZE);
- dump_byte_array("gcm_len_block", req_ctx->gcm_len_block.lenA, AES_BLOCK_SIZE);
+ dump_byte_array("gcm_len_block", req_ctx->gcm_len_block.len_a, AES_BLOCK_SIZE);
if (req->src && req->cryptlen)
dump_byte_array("req->src", sg_virt(req->src), req->cryptlen + req->assoclen);
@@ -1886,7 +1904,7 @@ static int config_gcm_context(struct aead_request *req)
(req->cryptlen - ctx->authsize);
__be32 counter = cpu_to_be32(2);
- SSI_LOG_DEBUG("config_gcm_context() cryptlen = %d, req->assoclen = %d ctx->authsize = %d\n", cryptlen, req->assoclen, ctx->authsize);
+ SSI_LOG_DEBUG("%s() cryptlen = %d, req->assoclen = %d ctx->authsize = %d\n", __func__, cryptlen, req->assoclen, ctx->authsize);
memset(req_ctx->hkey, 0, AES_BLOCK_SIZE);
@@ -1903,16 +1921,16 @@ static int config_gcm_context(struct aead_request *req)
__be64 temp64;
temp64 = cpu_to_be64(req->assoclen * 8);
- memcpy(&req_ctx->gcm_len_block.lenA, &temp64, sizeof(temp64));
+ memcpy(&req_ctx->gcm_len_block.len_a, &temp64, sizeof(temp64));
temp64 = cpu_to_be64(cryptlen * 8);
- memcpy(&req_ctx->gcm_len_block.lenC, &temp64, 8);
+ memcpy(&req_ctx->gcm_len_block.len_c, &temp64, 8);
} else { //rfc4543=> all data(AAD,IV,Plain) are considered additional data that is nothing is encrypted.
__be64 temp64;
temp64 = cpu_to_be64((req->assoclen + GCM_BLOCK_RFC4_IV_SIZE + cryptlen) * 8);
- memcpy(&req_ctx->gcm_len_block.lenA, &temp64, sizeof(temp64));
+ memcpy(&req_ctx->gcm_len_block.len_a, &temp64, sizeof(temp64));
temp64 = 0;
- memcpy(&req_ctx->gcm_len_block.lenC, &temp64, 8);
+ memcpy(&req_ctx->gcm_len_block.len_c, &temp64, 8);
}
return 0;
@@ -1944,16 +1962,16 @@ static int ssi_aead_process(struct aead_request *req, enum drv_crypto_direction
struct ssi_crypto_req ssi_req = {};
SSI_LOG_DEBUG("%s context=%p req=%p iv=%p src=%p src_ofs=%d dst=%p dst_ofs=%d cryptolen=%d\n",
- ((direct == DRV_CRYPTO_DIRECTION_ENCRYPT) ? "Encrypt" : "Decrypt"), ctx, req, req->iv,
- sg_virt(req->src), req->src->offset, sg_virt(req->dst), req->dst->offset, req->cryptlen);
- CHECK_AND_RETURN_UPON_FIPS_ERROR();
+ ((direct == DRV_CRYPTO_DIRECTION_ENCRYPT) ? "Encrypt" : "Decrypt"),
+ ctx, req, req->iv, sg_virt(req->src), req->src->offset,
+ sg_virt(req->dst), req->dst->offset, req->cryptlen);
/* STAT_PHASE_0: Init and sanity checks */
/* Check data length according to mode */
if (unlikely(validate_data_size(ctx, direct, req) != 0)) {
SSI_LOG_ERR("Unsupported crypt/assoc len %d/%d.\n",
- req->cryptlen, req->assoclen);
+ req->cryptlen, req->assoclen);
crypto_aead_set_flags(tfm, CRYPTO_TFM_RES_BAD_BLOCK_LEN);
return -EINVAL;
}
@@ -1976,7 +1994,7 @@ static int ssi_aead_process(struct aead_request *req, enum drv_crypto_direction
memcpy(areq_ctx->ctr_iv, ctx->ctr_nonce, CTR_RFC3686_NONCE_SIZE);
if (!areq_ctx->backup_giv) /*User none-generated IV*/
memcpy(areq_ctx->ctr_iv + CTR_RFC3686_NONCE_SIZE,
- req->iv, CTR_RFC3686_IV_SIZE);
+ req->iv, CTR_RFC3686_IV_SIZE);
/* Initialize counter portion of counter block */
*(__be32 *)(areq_ctx->ctr_iv + CTR_RFC3686_NONCE_SIZE +
CTR_RFC3686_IV_SIZE) = cpu_to_be32(1);
@@ -2198,7 +2216,7 @@ static int ssi_rfc4106_gcm_setkey(struct crypto_aead *tfm, const u8 *key, unsign
struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm);
int rc = 0;
- SSI_LOG_DEBUG("ssi_rfc4106_gcm_setkey() keylen %d, key %p\n", keylen, key);
+ SSI_LOG_DEBUG("%s() keylen %d, key %p\n", __func__, keylen, key);
if (keylen < 4)
return -EINVAL;
@@ -2216,7 +2234,7 @@ static int ssi_rfc4543_gcm_setkey(struct crypto_aead *tfm, const u8 *key, unsign
struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm);
int rc = 0;
- SSI_LOG_DEBUG("ssi_rfc4543_gcm_setkey() keylen %d, key %p\n", keylen, key);
+ SSI_LOG_DEBUG("%s() keylen %d, key %p\n", __func__, keylen, key);
if (keylen < 4)
return -EINVAL;
@@ -2230,7 +2248,7 @@ static int ssi_rfc4543_gcm_setkey(struct crypto_aead *tfm, const u8 *key, unsign
}
static int ssi_gcm_setauthsize(struct crypto_aead *authenc,
- unsigned int authsize)
+ unsigned int authsize)
{
switch (authsize) {
case 4:
@@ -2249,9 +2267,9 @@ static int ssi_gcm_setauthsize(struct crypto_aead *authenc,
}
static int ssi_rfc4106_gcm_setauthsize(struct crypto_aead *authenc,
- unsigned int authsize)
+ unsigned int authsize)
{
- SSI_LOG_DEBUG("ssi_rfc4106_gcm_setauthsize() authsize %d\n", authsize);
+ SSI_LOG_DEBUG("authsize %d\n", authsize);
switch (authsize) {
case 8:
@@ -2268,7 +2286,7 @@ static int ssi_rfc4106_gcm_setauthsize(struct crypto_aead *authenc,
static int ssi_rfc4543_gcm_setauthsize(struct crypto_aead *authenc,
unsigned int authsize)
{
- SSI_LOG_DEBUG("ssi_rfc4543_gcm_setauthsize() authsize %d\n", authsize);
+ SSI_LOG_DEBUG("authsize %d\n", authsize);
if (authsize != 16)
return -EINVAL;
@@ -2641,7 +2659,7 @@ static struct ssi_crypto_alg *ssi_aead_create_alg(struct ssi_alg_template *templ
struct ssi_crypto_alg *t_alg;
struct aead_alg *alg;
- t_alg = kzalloc(sizeof(struct ssi_crypto_alg), GFP_KERNEL);
+ t_alg = kzalloc(sizeof(*t_alg), GFP_KERNEL);
if (!t_alg) {
SSI_LOG_ERR("failed to allocate t_alg\n");
return ERR_PTR(-ENOMEM);
@@ -2696,7 +2714,7 @@ int ssi_aead_alloc(struct ssi_drvdata *drvdata)
int rc = -ENOMEM;
int alg;
- aead_handle = kmalloc(sizeof(struct ssi_aead_handle), GFP_KERNEL);
+ aead_handle = kmalloc(sizeof(*aead_handle), GFP_KERNEL);
if (!aead_handle) {
rc = -ENOMEM;
goto fail0;
@@ -2720,14 +2738,14 @@ int ssi_aead_alloc(struct ssi_drvdata *drvdata)
if (IS_ERR(t_alg)) {
rc = PTR_ERR(t_alg);
SSI_LOG_ERR("%s alg allocation failed\n",
- aead_algs[alg].driver_name);
+ aead_algs[alg].driver_name);
goto fail1;
}
t_alg->drvdata = drvdata;
rc = crypto_register_aead(&t_alg->aead_alg);
if (unlikely(rc != 0)) {
SSI_LOG_ERR("%s alg registration failed\n",
- t_alg->aead_alg.base.cra_driver_name);
+ t_alg->aead_alg.base.cra_driver_name);
goto fail2;
} else {
list_add_tail(&t_alg->entry, &aead_handle->aead_list);
diff --git a/drivers/staging/ccree/ssi_aead.h b/drivers/staging/ccree/ssi_aead.h
index 39cc633..e85bcd9 100644
--- a/drivers/staging/ccree/ssi_aead.h
+++ b/drivers/staging/ccree/ssi_aead.h
@@ -69,8 +69,8 @@ struct aead_req_ctx {
u8 gcm_iv_inc2[AES_BLOCK_SIZE] ____cacheline_aligned;
u8 hkey[AES_BLOCK_SIZE] ____cacheline_aligned;
struct {
- u8 lenA[GCM_BLOCK_LEN_SIZE] ____cacheline_aligned;
- u8 lenC[GCM_BLOCK_LEN_SIZE];
+ u8 len_a[GCM_BLOCK_LEN_SIZE] ____cacheline_aligned;
+ u8 len_c[GCM_BLOCK_LEN_SIZE];
} gcm_len_block;
u8 ccm_config[CCM_CONFIG_BUF_SIZE] ____cacheline_aligned;
@@ -94,10 +94,10 @@ struct aead_req_ctx {
struct ssi_mlli assoc;
struct ssi_mlli src;
struct ssi_mlli dst;
- struct scatterlist *srcSgl;
- struct scatterlist *dstSgl;
- unsigned int srcOffset;
- unsigned int dstOffset;
+ struct scatterlist *src_sgl;
+ struct scatterlist *dst_sgl;
+ unsigned int src_offset;
+ unsigned int dst_offset;
enum ssi_req_dma_buf_type assoc_buff_type;
enum ssi_req_dma_buf_type data_buff_type;
struct mlli_params mlli_params;
diff --git a/drivers/staging/ccree/ssi_buffer_mgr.c b/drivers/staging/ccree/ssi_buffer_mgr.c
index b35871e..6393609 100644
--- a/drivers/staging/ccree/ssi_buffer_mgr.c
+++ b/drivers/staging/ccree/ssi_buffer_mgr.c
@@ -150,7 +150,7 @@ static inline int ssi_buffer_mgr_render_buff_to_mlli(
u32 **mlli_entry_pp)
{
u32 *mlli_entry_p = *mlli_entry_pp;
- u32 new_nents;;
+ u32 new_nents;
/* Verify there is no memory overflow*/
new_nents = (*curr_nents + buff_size / CC_MAX_MLLI_ENTRY_SIZE + 1);
@@ -162,8 +162,8 @@ static inline int ssi_buffer_mgr_render_buff_to_mlli(
cc_lli_set_addr(mlli_entry_p, buff_dma);
cc_lli_set_size(mlli_entry_p, CC_MAX_MLLI_ENTRY_SIZE);
SSI_LOG_DEBUG("entry[%d]: single_buff=0x%08X size=%08X\n", *curr_nents,
- mlli_entry_p[LLI_WORD0_OFFSET],
- mlli_entry_p[LLI_WORD1_OFFSET]);
+ mlli_entry_p[LLI_WORD0_OFFSET],
+ mlli_entry_p[LLI_WORD1_OFFSET]);
buff_dma += CC_MAX_MLLI_ENTRY_SIZE;
buff_size -= CC_MAX_MLLI_ENTRY_SIZE;
mlli_entry_p = mlli_entry_p + 2;
@@ -173,8 +173,8 @@ static inline int ssi_buffer_mgr_render_buff_to_mlli(
cc_lli_set_addr(mlli_entry_p, buff_dma);
cc_lli_set_size(mlli_entry_p, buff_size);
SSI_LOG_DEBUG("entry[%d]: single_buff=0x%08X size=%08X\n", *curr_nents,
- mlli_entry_p[LLI_WORD0_OFFSET],
- mlli_entry_p[LLI_WORD1_OFFSET]);
+ mlli_entry_p[LLI_WORD0_OFFSET],
+ mlli_entry_p[LLI_WORD1_OFFSET]);
mlli_entry_p = mlli_entry_p + 2;
*mlli_entry_pp = mlli_entry_p;
(*curr_nents)++;
@@ -182,8 +182,8 @@ static inline int ssi_buffer_mgr_render_buff_to_mlli(
}
static inline int ssi_buffer_mgr_render_scatterlist_to_mlli(
- struct scatterlist *sgl, u32 sgl_data_len, u32 sglOffset, u32 *curr_nents,
- u32 **mlli_entry_pp)
+ struct scatterlist *sgl, u32 sgl_data_len, u32 sgl_offset,
+ u32 *curr_nents, u32 **mlli_entry_pp)
{
struct scatterlist *curr_sgl = sgl;
u32 *mlli_entry_p = *mlli_entry_pp;
@@ -192,16 +192,17 @@ static inline int ssi_buffer_mgr_render_scatterlist_to_mlli(
for ( ; (curr_sgl) && (sgl_data_len != 0);
curr_sgl = sg_next(curr_sgl)) {
u32 entry_data_len =
- (sgl_data_len > sg_dma_len(curr_sgl) - sglOffset) ?
- sg_dma_len(curr_sgl) - sglOffset : sgl_data_len;
+ (sgl_data_len > sg_dma_len(curr_sgl) - sgl_offset) ?
+ sg_dma_len(curr_sgl) - sgl_offset :
+ sgl_data_len;
sgl_data_len -= entry_data_len;
rc = ssi_buffer_mgr_render_buff_to_mlli(
- sg_dma_address(curr_sgl) + sglOffset, entry_data_len, curr_nents,
- &mlli_entry_p);
+ sg_dma_address(curr_sgl) + sgl_offset, entry_data_len,
+ curr_nents, &mlli_entry_p);
if (rc != 0)
return rc;
- sglOffset = 0;
+ sgl_offset = 0;
}
*mlli_entry_pp = mlli_entry_p;
return 0;
@@ -221,7 +222,7 @@ static int ssi_buffer_mgr_generate_mlli(
/* Allocate memory from the pointed pool */
mlli_params->mlli_virt_addr = dma_pool_alloc(
mlli_params->curr_pool, GFP_KERNEL,
- &(mlli_params->mlli_dma_addr));
+ &mlli_params->mlli_dma_addr);
if (unlikely(!mlli_params->mlli_virt_addr)) {
SSI_LOG_ERR("dma_pool_alloc() failed\n");
rc = -ENOMEM;
@@ -249,7 +250,7 @@ static int ssi_buffer_mgr_generate_mlli(
/*Calculate the current MLLI table length for the
*length field in the descriptor
*/
- *(sg_data->mlli_nents[i]) +=
+ *sg_data->mlli_nents[i] +=
(total_nents - prev_total_nents);
prev_total_nents = total_nents;
}
@@ -259,9 +260,9 @@ static int ssi_buffer_mgr_generate_mlli(
mlli_params->mlli_len = (total_nents * LLI_ENTRY_BYTE_SIZE);
SSI_LOG_DEBUG("MLLI params: "
- "virt_addr=%pK dma_addr=0x%llX mlli_len=0x%X\n",
+ "virt_addr=%pK dma_addr=%pad mlli_len=0x%X\n",
mlli_params->mlli_virt_addr,
- (unsigned long long)mlli_params->mlli_dma_addr,
+ mlli_params->mlli_dma_addr,
mlli_params->mlli_len);
build_mlli_exit:
@@ -275,9 +276,9 @@ static inline void ssi_buffer_mgr_add_buffer_entry(
{
unsigned int index = sgl_data->num_of_buffers;
- SSI_LOG_DEBUG("index=%u single_buff=0x%llX "
+ SSI_LOG_DEBUG("index=%u single_buff=%pad "
"buffer_len=0x%08X is_last=%d\n",
- index, (unsigned long long)buffer_dma, buffer_len, is_last_entry);
+ index, buffer_dma, buffer_len, is_last_entry);
sgl_data->nents[index] = 1;
sgl_data->entry[index].buffer_dma = buffer_dma;
sgl_data->offset[index] = 0;
@@ -302,7 +303,7 @@ static inline void ssi_buffer_mgr_add_scatterlist_entry(
unsigned int index = sgl_data->num_of_buffers;
SSI_LOG_DEBUG("index=%u nents=%u sgl=%pK data_len=0x%08X is_last=%d\n",
- index, nents, sgl, data_len, is_last_table);
+ index, nents, sgl, data_len, is_last_table);
sgl_data->nents[index] = nents;
sgl_data->entry[index].sgl = sgl;
sgl_data->offset[index] = data_offset;
@@ -317,7 +318,7 @@ static inline void ssi_buffer_mgr_add_scatterlist_entry(
static int
ssi_buffer_mgr_dma_map_sg(struct device *dev, struct scatterlist *sg, u32 nents,
- enum dma_data_direction direction)
+ enum dma_data_direction direction)
{
u32 i, j;
struct scatterlist *l_sg = sg;
@@ -358,10 +359,10 @@ static int ssi_buffer_mgr_map_scatterlist(
SSI_LOG_ERR("dma_map_sg() single buffer failed\n");
return -ENOMEM;
}
- SSI_LOG_DEBUG("Mapped sg: dma_address=0x%llX "
+ SSI_LOG_DEBUG("Mapped sg: dma_address=%pad "
"page=%p addr=%pK offset=%u "
"length=%u\n",
- (unsigned long long)sg_dma_address(sg),
+ sg_dma_address(sg),
sg_page(sg),
sg_virt(sg),
sg->offset, sg->length);
@@ -370,11 +371,11 @@ static int ssi_buffer_mgr_map_scatterlist(
*mapped_nents = 1;
} else { /*sg_is_last*/
*nents = ssi_buffer_mgr_get_sgl_nents(sg, nbytes, lbytes,
- &is_chained);
+ &is_chained);
if (*nents > max_sg_nents) {
*nents = 0;
SSI_LOG_ERR("Too many fragments. current %d max %d\n",
- *nents, max_sg_nents);
+ *nents, max_sg_nents);
return -ENOMEM;
}
if (!is_chained) {
@@ -392,9 +393,9 @@ static int ssi_buffer_mgr_map_scatterlist(
* must have the same nents before and after map
*/
*mapped_nents = ssi_buffer_mgr_dma_map_sg(dev,
- sg,
- *nents,
- direction);
+ sg,
+ *nents,
+ direction);
if (unlikely(*mapped_nents != *nents)) {
*nents = *mapped_nents;
SSI_LOG_ERR("dma_map_sg() sg buffer failed\n");
@@ -408,10 +409,10 @@ static int ssi_buffer_mgr_map_scatterlist(
static inline int
ssi_aead_handle_config_buf(struct device *dev,
- struct aead_req_ctx *areq_ctx,
- u8 *config_data,
- struct buffer_array *sg_data,
- unsigned int assoclen)
+ struct aead_req_ctx *areq_ctx,
+ u8 *config_data,
+ struct buffer_array *sg_data,
+ unsigned int assoclen)
{
SSI_LOG_DEBUG(" handle additional data config set to DLLI\n");
/* create sg for the current buffer */
@@ -422,10 +423,10 @@ ssi_aead_handle_config_buf(struct device *dev,
"config buffer failed\n");
return -ENOMEM;
}
- SSI_LOG_DEBUG("Mapped curr_buff: dma_address=0x%llX "
+ SSI_LOG_DEBUG("Mapped curr_buff: dma_address=%pad "
"page=%p addr=%pK "
"offset=%u length=%u\n",
- (unsigned long long)sg_dma_address(&areq_ctx->ccm_adata_sg),
+ sg_dma_address(&areq_ctx->ccm_adata_sg),
sg_page(&areq_ctx->ccm_adata_sg),
sg_virt(&areq_ctx->ccm_adata_sg),
areq_ctx->ccm_adata_sg.offset,
@@ -433,19 +434,18 @@ ssi_aead_handle_config_buf(struct device *dev,
/* prepare for case of MLLI */
if (assoclen > 0) {
ssi_buffer_mgr_add_scatterlist_entry(sg_data, 1,
- &areq_ctx->ccm_adata_sg,
- (AES_BLOCK_SIZE +
- areq_ctx->ccm_hdr_size), 0,
- false, NULL);
+ &areq_ctx->ccm_adata_sg,
+ (AES_BLOCK_SIZE + areq_ctx->ccm_hdr_size),
+ 0, false, NULL);
}
return 0;
}
static inline int ssi_ahash_handle_curr_buf(struct device *dev,
- struct ahash_req_ctx *areq_ctx,
- u8 *curr_buff,
- u32 curr_buff_cnt,
- struct buffer_array *sg_data)
+ struct ahash_req_ctx *areq_ctx,
+ u8 *curr_buff,
+ u32 curr_buff_cnt,
+ struct buffer_array *sg_data)
{
SSI_LOG_DEBUG(" handle curr buff %x set to DLLI\n", curr_buff_cnt);
/* create sg for the current buffer */
@@ -456,10 +456,10 @@ static inline int ssi_ahash_handle_curr_buf(struct device *dev,
"src buffer failed\n");
return -ENOMEM;
}
- SSI_LOG_DEBUG("Mapped curr_buff: dma_address=0x%llX "
+ SSI_LOG_DEBUG("Mapped curr_buff: dma_address=%pad "
"page=%p addr=%pK "
"offset=%u length=%u\n",
- (unsigned long long)sg_dma_address(areq_ctx->buff_sg),
+ sg_dma_address(areq_ctx->buff_sg),
sg_page(areq_ctx->buff_sg),
sg_virt(areq_ctx->buff_sg),
areq_ctx->buff_sg->offset,
@@ -469,7 +469,7 @@ static inline int ssi_ahash_handle_curr_buf(struct device *dev,
areq_ctx->in_nents = 0;
/* prepare for case of MLLI */
ssi_buffer_mgr_add_scatterlist_entry(sg_data, 1, areq_ctx->buff_sg,
- curr_buff_cnt, 0, false, NULL);
+ curr_buff_cnt, 0, false, NULL);
return 0;
}
@@ -483,9 +483,9 @@ void ssi_buffer_mgr_unmap_blkcipher_request(
struct blkcipher_req_ctx *req_ctx = (struct blkcipher_req_ctx *)ctx;
if (likely(req_ctx->gen_ctx.iv_dma_addr != 0)) {
- SSI_LOG_DEBUG("Unmapped iv: iv_dma_addr=0x%llX iv_size=%u\n",
- (unsigned long long)req_ctx->gen_ctx.iv_dma_addr,
- ivsize);
+ SSI_LOG_DEBUG("Unmapped iv: iv_dma_addr=%pad iv_size=%u\n",
+ req_ctx->gen_ctx.iv_dma_addr,
+ ivsize);
dma_unmap_single(dev, req_ctx->gen_ctx.iv_dma_addr,
ivsize,
req_ctx->is_giv ? DMA_BIDIRECTIONAL :
@@ -498,16 +498,12 @@ void ssi_buffer_mgr_unmap_blkcipher_request(
req_ctx->mlli_params.mlli_dma_addr);
}
- dma_unmap_sg(dev, src, req_ctx->in_nents,
- DMA_BIDIRECTIONAL);
- SSI_LOG_DEBUG("Unmapped req->src=%pK\n",
- sg_virt(src));
+ dma_unmap_sg(dev, src, req_ctx->in_nents, DMA_BIDIRECTIONAL);
+ SSI_LOG_DEBUG("Unmapped req->src=%pK\n", sg_virt(src));
if (src != dst) {
- dma_unmap_sg(dev, dst, req_ctx->out_nents,
- DMA_BIDIRECTIONAL);
- SSI_LOG_DEBUG("Unmapped req->dst=%pK\n",
- sg_virt(dst));
+ dma_unmap_sg(dev, dst, req_ctx->out_nents, DMA_BIDIRECTIONAL);
+ SSI_LOG_DEBUG("Unmapped req->dst=%pK\n", sg_virt(dst));
}
}
@@ -542,22 +538,24 @@ int ssi_buffer_mgr_map_blkcipher_request(
req_ctx->is_giv ? DMA_BIDIRECTIONAL :
DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(dev,
- req_ctx->gen_ctx.iv_dma_addr))) {
+ req_ctx->gen_ctx.iv_dma_addr))) {
SSI_LOG_ERR("Mapping iv %u B at va=%pK "
"for DMA failed\n", ivsize, info);
return -ENOMEM;
}
- SSI_LOG_DEBUG("Mapped iv %u B at va=%pK to dma=0x%llX\n",
- ivsize, info,
- (unsigned long long)req_ctx->gen_ctx.iv_dma_addr);
+ SSI_LOG_DEBUG("Mapped iv %u B at va=%pK to dma=%pad\n",
+ ivsize, info,
+ req_ctx->gen_ctx.iv_dma_addr);
} else {
req_ctx->gen_ctx.iv_dma_addr = 0;
}
/* Map the src SGL */
rc = ssi_buffer_mgr_map_scatterlist(dev, src,
- nbytes, DMA_BIDIRECTIONAL, &req_ctx->in_nents,
- LLI_MAX_NUM_OF_DATA_ENTRIES, &dummy, &mapped_nents);
+ nbytes, DMA_BIDIRECTIONAL,
+ &req_ctx->in_nents,
+ LLI_MAX_NUM_OF_DATA_ENTRIES, &dummy,
+ &mapped_nents);
if (unlikely(rc != 0)) {
rc = -ENOMEM;
goto ablkcipher_exit;
@@ -570,8 +568,10 @@ int ssi_buffer_mgr_map_blkcipher_request(
if (unlikely(req_ctx->dma_buf_type == SSI_DMA_BUF_MLLI)) {
req_ctx->out_nents = 0;
ssi_buffer_mgr_add_scatterlist_entry(&sg_data,
- req_ctx->in_nents, src,
- nbytes, 0, true, &req_ctx->in_mlli_nents);
+ req_ctx->in_nents,
+ src, nbytes, 0,
+ true,
+ &req_ctx->in_mlli_nents);
}
} else {
/* Map the dst sg */
@@ -588,13 +588,15 @@ int ssi_buffer_mgr_map_blkcipher_request(
if (unlikely((req_ctx->dma_buf_type == SSI_DMA_BUF_MLLI))) {
ssi_buffer_mgr_add_scatterlist_entry(&sg_data,
- req_ctx->in_nents, src,
- nbytes, 0, true,
- &req_ctx->in_mlli_nents);
+ req_ctx->in_nents,
+ src, nbytes, 0,
+ true,
+ &req_ctx->in_mlli_nents);
ssi_buffer_mgr_add_scatterlist_entry(&sg_data,
- req_ctx->out_nents, dst,
- nbytes, 0, true,
- &req_ctx->out_mlli_nents);
+ req_ctx->out_nents,
+ dst, nbytes, 0,
+ true,
+ &req_ctx->out_mlli_nents);
}
}
@@ -606,7 +608,7 @@ int ssi_buffer_mgr_map_blkcipher_request(
}
SSI_LOG_DEBUG("areq_ctx->dma_buf_type = %s\n",
- GET_DMA_BUFFER_TYPE(req_ctx->dma_buf_type));
+ GET_DMA_BUFFER_TYPE(req_ctx->dma_buf_type));
return 0;
@@ -628,7 +630,7 @@ void ssi_buffer_mgr_unmap_aead_request(
if (areq_ctx->mac_buf_dma_addr != 0) {
dma_unmap_single(dev, areq_ctx->mac_buf_dma_addr,
- MAX_MAC_SIZE, DMA_BIDIRECTIONAL);
+ MAX_MAC_SIZE, DMA_BIDIRECTIONAL);
}
#if SSI_CC_HAS_AES_GCM
@@ -645,12 +647,12 @@ void ssi_buffer_mgr_unmap_aead_request(
if (areq_ctx->gcm_iv_inc1_dma_addr != 0) {
dma_unmap_single(dev, areq_ctx->gcm_iv_inc1_dma_addr,
- AES_BLOCK_SIZE, DMA_TO_DEVICE);
+ AES_BLOCK_SIZE, DMA_TO_DEVICE);
}
if (areq_ctx->gcm_iv_inc2_dma_addr != 0) {
dma_unmap_single(dev, areq_ctx->gcm_iv_inc2_dma_addr,
- AES_BLOCK_SIZE, DMA_TO_DEVICE);
+ AES_BLOCK_SIZE, DMA_TO_DEVICE);
}
}
#endif
@@ -658,7 +660,7 @@ void ssi_buffer_mgr_unmap_aead_request(
if (areq_ctx->ccm_hdr_size != ccm_header_size_null) {
if (areq_ctx->ccm_iv0_dma_addr != 0) {
dma_unmap_single(dev, areq_ctx->ccm_iv0_dma_addr,
- AES_BLOCK_SIZE, DMA_TO_DEVICE);
+ AES_BLOCK_SIZE, DMA_TO_DEVICE);
}
dma_unmap_sg(dev, &areq_ctx->ccm_adata_sg, 1, DMA_TO_DEVICE);
@@ -672,9 +674,9 @@ void ssi_buffer_mgr_unmap_aead_request(
*allocated and should be released
*/
if (areq_ctx->mlli_params.curr_pool) {
- SSI_LOG_DEBUG("free MLLI buffer: dma=0x%08llX virt=%pK\n",
- (unsigned long long)areq_ctx->mlli_params.mlli_dma_addr,
- areq_ctx->mlli_params.mlli_virt_addr);
+ SSI_LOG_DEBUG("free MLLI buffer: dma=%pad virt=%pK\n",
+ areq_ctx->mlli_params.mlli_dma_addr,
+ areq_ctx->mlli_params.mlli_virt_addr);
dma_pool_free(areq_ctx->mlli_params.curr_pool,
areq_ctx->mlli_params.mlli_virt_addr,
areq_ctx->mlli_params.mlli_dma_addr);
@@ -690,14 +692,17 @@ void ssi_buffer_mgr_unmap_aead_request(
dma_unmap_sg(dev, req->src, ssi_buffer_mgr_get_sgl_nents(req->src, size_to_unmap, &dummy, &chained), DMA_BIDIRECTIONAL);
if (unlikely(req->src != req->dst)) {
SSI_LOG_DEBUG("Unmapping dst sgl: req->dst=%pK\n",
- sg_virt(req->dst));
- dma_unmap_sg(dev, req->dst, ssi_buffer_mgr_get_sgl_nents(req->dst, size_to_unmap, &dummy, &chained),
- DMA_BIDIRECTIONAL);
+ sg_virt(req->dst));
+ dma_unmap_sg(dev, req->dst,
+ ssi_buffer_mgr_get_sgl_nents(req->dst,
+ size_to_unmap,
+ &dummy,
+ &chained),
+ DMA_BIDIRECTIONAL);
}
if (drvdata->coherent &&
(areq_ctx->gen_ctx.op_type == DRV_CRYPTO_DIRECTION_DECRYPT) &&
- likely(req->src == req->dst))
- {
+ likely(req->src == req->dst)) {
u32 size_to_skip = req->assoclen;
if (areq_ctx->is_gcm4543)
@@ -753,11 +758,11 @@ static inline int ssi_buffer_mgr_get_aead_icv_nents(
*is_icv_fragmented = true;
} else {
SSI_LOG_ERR("Unsupported num. of ICV fragments (> %d)\n",
- MAX_ICV_NENTS_SUPPORTED);
+ MAX_ICV_NENTS_SUPPORTED);
nents = -1; /*unsupported*/
}
SSI_LOG_DEBUG("is_frag=%s icv_nents=%u\n",
- (*is_icv_fragmented ? "true" : "false"), nents);
+ (*is_icv_fragmented ? "true" : "false"), nents);
return nents;
}
@@ -778,18 +783,18 @@ static inline int ssi_buffer_mgr_aead_chain_iv(
goto chain_iv_exit;
}
- areq_ctx->gen_ctx.iv_dma_addr = dma_map_single(dev, req->iv,
- hw_iv_size, DMA_BIDIRECTIONAL);
+ areq_ctx->gen_ctx.iv_dma_addr = dma_map_single(dev, req->iv, hw_iv_size,
+ DMA_BIDIRECTIONAL);
if (unlikely(dma_mapping_error(dev, areq_ctx->gen_ctx.iv_dma_addr))) {
SSI_LOG_ERR("Mapping iv %u B at va=%pK for DMA failed\n",
- hw_iv_size, req->iv);
+ hw_iv_size, req->iv);
rc = -ENOMEM;
goto chain_iv_exit;
}
- SSI_LOG_DEBUG("Mapped iv %u B at va=%pK to dma=0x%llX\n",
- hw_iv_size, req->iv,
- (unsigned long long)areq_ctx->gen_ctx.iv_dma_addr);
+ SSI_LOG_DEBUG("Mapped iv %u B at va=%pK to dma=%pad\n",
+ hw_iv_size, req->iv,
+ areq_ctx->gen_ctx.iv_dma_addr);
if (do_chain && areq_ctx->plaintext_authenticate_only) { // TODO: what about CTR?? ask Ron
struct crypto_aead *tfm = crypto_aead_reqtfm(req);
unsigned int iv_size_to_authenc = crypto_aead_ivsize(tfm);
@@ -833,8 +838,8 @@ static inline int ssi_buffer_mgr_aead_chain_assoc(
areq_ctx->assoc.nents = 0;
areq_ctx->assoc.mlli_nents = 0;
SSI_LOG_DEBUG("Chain assoc of length 0: buff_type=%s nents=%u\n",
- GET_DMA_BUFFER_TYPE(areq_ctx->assoc_buff_type),
- areq_ctx->assoc.nents);
+ GET_DMA_BUFFER_TYPE(areq_ctx->assoc_buff_type),
+ areq_ctx->assoc.nents);
goto chain_assoc_exit;
}
@@ -868,10 +873,9 @@ static inline int ssi_buffer_mgr_aead_chain_assoc(
if (areq_ctx->ccm_hdr_size != ccm_header_size_null) {
if (unlikely((mapped_nents + 1) >
LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES)) {
- SSI_LOG_ERR("CCM case.Too many fragments. "
- "Current %d max %d\n",
- (areq_ctx->assoc.nents + 1),
- LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES);
+ SSI_LOG_ERR("CCM case.Too many fragments. Current %d max %d\n",
+ (areq_ctx->assoc.nents + 1),
+ LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES);
rc = -ENOMEM;
goto chain_assoc_exit;
}
@@ -884,10 +888,10 @@ static inline int ssi_buffer_mgr_aead_chain_assoc(
areq_ctx->assoc_buff_type = SSI_DMA_BUF_MLLI;
if (unlikely((do_chain) ||
- (areq_ctx->assoc_buff_type == SSI_DMA_BUF_MLLI))) {
+ (areq_ctx->assoc_buff_type == SSI_DMA_BUF_MLLI))) {
SSI_LOG_DEBUG("Chain assoc: buff_type=%s nents=%u\n",
- GET_DMA_BUFFER_TYPE(areq_ctx->assoc_buff_type),
- areq_ctx->assoc.nents);
+ GET_DMA_BUFFER_TYPE(areq_ctx->assoc_buff_type),
+ areq_ctx->assoc.nents);
ssi_buffer_mgr_add_scatterlist_entry(
sg_data, areq_ctx->assoc.nents,
req->src, req->assoclen, 0, is_last,
@@ -911,26 +915,26 @@ static inline void ssi_buffer_mgr_prepare_aead_data_dlli(
if (likely(req->src == req->dst)) {
/*INPLACE*/
areq_ctx->icv_dma_addr = sg_dma_address(
- areq_ctx->srcSgl) +
+ areq_ctx->src_sgl) +
(*src_last_bytes - authsize);
areq_ctx->icv_virt_addr = sg_virt(
- areq_ctx->srcSgl) +
+ areq_ctx->src_sgl) +
(*src_last_bytes - authsize);
} else if (direct == DRV_CRYPTO_DIRECTION_DECRYPT) {
/*NON-INPLACE and DECRYPT*/
areq_ctx->icv_dma_addr = sg_dma_address(
- areq_ctx->srcSgl) +
+ areq_ctx->src_sgl) +
(*src_last_bytes - authsize);
areq_ctx->icv_virt_addr = sg_virt(
- areq_ctx->srcSgl) +
+ areq_ctx->src_sgl) +
(*src_last_bytes - authsize);
} else {
/*NON-INPLACE and ENCRYPT*/
areq_ctx->icv_dma_addr = sg_dma_address(
- areq_ctx->dstSgl) +
+ areq_ctx->dst_sgl) +
(*dst_last_bytes - authsize);
areq_ctx->icv_virt_addr = sg_virt(
- areq_ctx->dstSgl) +
+ areq_ctx->dst_sgl) +
(*dst_last_bytes - authsize);
}
}
@@ -951,13 +955,18 @@ static inline int ssi_buffer_mgr_prepare_aead_data_mlli(
if (likely(req->src == req->dst)) {
/*INPLACE*/
ssi_buffer_mgr_add_scatterlist_entry(sg_data,
- areq_ctx->src.nents, areq_ctx->srcSgl,
- areq_ctx->cryptlen, areq_ctx->srcOffset, is_last_table,
- &areq_ctx->src.mlli_nents);
-
- icv_nents = ssi_buffer_mgr_get_aead_icv_nents(areq_ctx->srcSgl,
- areq_ctx->src.nents, authsize, *src_last_bytes,
- &areq_ctx->is_icv_fragmented);
+ areq_ctx->src.nents,
+ areq_ctx->src_sgl,
+ areq_ctx->cryptlen,
+ areq_ctx->src_offset,
+ is_last_table,
+ &areq_ctx->src.mlli_nents);
+
+ icv_nents = ssi_buffer_mgr_get_aead_icv_nents(areq_ctx->src_sgl,
+ areq_ctx->src.nents,
+ authsize,
+ *src_last_bytes,
+ &areq_ctx->is_icv_fragmented);
if (unlikely(icv_nents < 0)) {
rc = -ENOTSUPP;
goto prepare_data_mlli_exit;
@@ -995,27 +1004,35 @@ static inline int ssi_buffer_mgr_prepare_aead_data_mlli(
} else { /* Contig. ICV */
/*Should hanlde if the sg is not contig.*/
areq_ctx->icv_dma_addr = sg_dma_address(
- &areq_ctx->srcSgl[areq_ctx->src.nents - 1]) +
+ &areq_ctx->src_sgl[areq_ctx->src.nents - 1]) +
(*src_last_bytes - authsize);
areq_ctx->icv_virt_addr = sg_virt(
- &areq_ctx->srcSgl[areq_ctx->src.nents - 1]) +
+ &areq_ctx->src_sgl[areq_ctx->src.nents - 1]) +
(*src_last_bytes - authsize);
}
} else if (direct == DRV_CRYPTO_DIRECTION_DECRYPT) {
/*NON-INPLACE and DECRYPT*/
ssi_buffer_mgr_add_scatterlist_entry(sg_data,
- areq_ctx->src.nents, areq_ctx->srcSgl,
- areq_ctx->cryptlen, areq_ctx->srcOffset, is_last_table,
- &areq_ctx->src.mlli_nents);
+ areq_ctx->src.nents,
+ areq_ctx->src_sgl,
+ areq_ctx->cryptlen,
+ areq_ctx->src_offset,
+ is_last_table,
+ &areq_ctx->src.mlli_nents);
ssi_buffer_mgr_add_scatterlist_entry(sg_data,
- areq_ctx->dst.nents, areq_ctx->dstSgl,
- areq_ctx->cryptlen, areq_ctx->dstOffset, is_last_table,
- &areq_ctx->dst.mlli_nents);
-
- icv_nents = ssi_buffer_mgr_get_aead_icv_nents(areq_ctx->srcSgl,
- areq_ctx->src.nents, authsize, *src_last_bytes,
- &areq_ctx->is_icv_fragmented);
+ areq_ctx->dst.nents,
+ areq_ctx->dst_sgl,
+ areq_ctx->cryptlen,
+ areq_ctx->dst_offset,
+ is_last_table,
+ &areq_ctx->dst.mlli_nents);
+
+ icv_nents = ssi_buffer_mgr_get_aead_icv_nents(areq_ctx->src_sgl,
+ areq_ctx->src.nents,
+ authsize,
+ *src_last_bytes,
+ &areq_ctx->is_icv_fragmented);
if (unlikely(icv_nents < 0)) {
rc = -ENOTSUPP;
goto prepare_data_mlli_exit;
@@ -1039,26 +1056,34 @@ static inline int ssi_buffer_mgr_prepare_aead_data_mlli(
} else { /* Contig. ICV */
/*Should hanlde if the sg is not contig.*/
areq_ctx->icv_dma_addr = sg_dma_address(
- &areq_ctx->srcSgl[areq_ctx->src.nents - 1]) +
+ &areq_ctx->src_sgl[areq_ctx->src.nents - 1]) +
(*src_last_bytes - authsize);
areq_ctx->icv_virt_addr = sg_virt(
- &areq_ctx->srcSgl[areq_ctx->src.nents - 1]) +
+ &areq_ctx->src_sgl[areq_ctx->src.nents - 1]) +
(*src_last_bytes - authsize);
}
} else {
/*NON-INPLACE and ENCRYPT*/
ssi_buffer_mgr_add_scatterlist_entry(sg_data,
- areq_ctx->dst.nents, areq_ctx->dstSgl,
- areq_ctx->cryptlen, areq_ctx->dstOffset, is_last_table,
- &areq_ctx->dst.mlli_nents);
+ areq_ctx->dst.nents,
+ areq_ctx->dst_sgl,
+ areq_ctx->cryptlen,
+ areq_ctx->dst_offset,
+ is_last_table,
+ &areq_ctx->dst.mlli_nents);
ssi_buffer_mgr_add_scatterlist_entry(sg_data,
- areq_ctx->src.nents, areq_ctx->srcSgl,
- areq_ctx->cryptlen, areq_ctx->srcOffset, is_last_table,
- &areq_ctx->src.mlli_nents);
-
- icv_nents = ssi_buffer_mgr_get_aead_icv_nents(areq_ctx->dstSgl,
- areq_ctx->dst.nents, authsize, *dst_last_bytes,
+ areq_ctx->src.nents,
+ areq_ctx->src_sgl,
+ areq_ctx->cryptlen,
+ areq_ctx->src_offset,
+ is_last_table,
+ &areq_ctx->src.mlli_nents);
+
+ icv_nents = ssi_buffer_mgr_get_aead_icv_nents(areq_ctx->dst_sgl,
+ areq_ctx->dst.nents,
+ authsize,
+ *dst_last_bytes,
&areq_ctx->is_icv_fragmented);
if (unlikely(icv_nents < 0)) {
rc = -ENOTSUPP;
@@ -1068,10 +1093,10 @@ static inline int ssi_buffer_mgr_prepare_aead_data_mlli(
if (likely(!areq_ctx->is_icv_fragmented)) {
/* Contig. ICV */
areq_ctx->icv_dma_addr = sg_dma_address(
- &areq_ctx->dstSgl[areq_ctx->dst.nents - 1]) +
+ &areq_ctx->dst_sgl[areq_ctx->dst.nents - 1]) +
(*dst_last_bytes - authsize);
areq_ctx->icv_virt_addr = sg_virt(
- &areq_ctx->dstSgl[areq_ctx->dst.nents - 1]) +
+ &areq_ctx->dst_sgl[areq_ctx->dst.nents - 1]) +
(*dst_last_bytes - authsize);
} else {
areq_ctx->icv_dma_addr = areq_ctx->mac_buf_dma_addr;
@@ -1113,37 +1138,36 @@ static inline int ssi_buffer_mgr_aead_chain_data(
rc = -EINVAL;
goto chain_data_exit;
}
- areq_ctx->srcSgl = req->src;
- areq_ctx->dstSgl = req->dst;
+ areq_ctx->src_sgl = req->src;
+ areq_ctx->dst_sgl = req->dst;
if (is_gcm4543)
size_for_map += crypto_aead_ivsize(tfm);
size_for_map += (direct == DRV_CRYPTO_DIRECTION_ENCRYPT) ? authsize : 0;
src_mapped_nents = ssi_buffer_mgr_get_sgl_nents(req->src, size_for_map, &src_last_bytes, &chained);
- sg_index = areq_ctx->srcSgl->length;
+ sg_index = areq_ctx->src_sgl->length;
//check where the data starts
while (sg_index <= size_to_skip) {
- offset -= areq_ctx->srcSgl->length;
- areq_ctx->srcSgl = sg_next(areq_ctx->srcSgl);
+ offset -= areq_ctx->src_sgl->length;
+ areq_ctx->src_sgl = sg_next(areq_ctx->src_sgl);
//if have reached the end of the sgl, then this is unexpected
- if (!areq_ctx->srcSgl) {
+ if (!areq_ctx->src_sgl) {
SSI_LOG_ERR("reached end of sg list. unexpected\n");
BUG();
}
- sg_index += areq_ctx->srcSgl->length;
+ sg_index += areq_ctx->src_sgl->length;
src_mapped_nents--;
}
- if (unlikely(src_mapped_nents > LLI_MAX_NUM_OF_DATA_ENTRIES))
- {
+ if (unlikely(src_mapped_nents > LLI_MAX_NUM_OF_DATA_ENTRIES)) {
SSI_LOG_ERR("Too many fragments. current %d max %d\n",
- src_mapped_nents, LLI_MAX_NUM_OF_DATA_ENTRIES);
+ src_mapped_nents, LLI_MAX_NUM_OF_DATA_ENTRIES);
return -ENOMEM;
}
areq_ctx->src.nents = src_mapped_nents;
- areq_ctx->srcOffset = offset;
+ areq_ctx->src_offset = offset;
if (req->src != req->dst) {
size_for_map = req->assoclen + req->cryptlen;
@@ -1152,9 +1176,11 @@ static inline int ssi_buffer_mgr_aead_chain_data(
size_for_map += crypto_aead_ivsize(tfm);
rc = ssi_buffer_mgr_map_scatterlist(dev, req->dst, size_for_map,
- DMA_BIDIRECTIONAL, &(areq_ctx->dst.nents),
- LLI_MAX_NUM_OF_DATA_ENTRIES, &dst_last_bytes,
- &dst_mapped_nents);
+ DMA_BIDIRECTIONAL,
+ &areq_ctx->dst.nents,
+ LLI_MAX_NUM_OF_DATA_ENTRIES,
+ &dst_last_bytes,
+ &dst_mapped_nents);
if (unlikely(rc != 0)) {
rc = -ENOMEM;
goto chain_data_exit;
@@ -1162,35 +1188,37 @@ static inline int ssi_buffer_mgr_aead_chain_data(
}
dst_mapped_nents = ssi_buffer_mgr_get_sgl_nents(req->dst, size_for_map, &dst_last_bytes, &chained);
- sg_index = areq_ctx->dstSgl->length;
+ sg_index = areq_ctx->dst_sgl->length;
offset = size_to_skip;
//check where the data starts
while (sg_index <= size_to_skip) {
- offset -= areq_ctx->dstSgl->length;
- areq_ctx->dstSgl = sg_next(areq_ctx->dstSgl);
+ offset -= areq_ctx->dst_sgl->length;
+ areq_ctx->dst_sgl = sg_next(areq_ctx->dst_sgl);
//if have reached the end of the sgl, then this is unexpected
- if (!areq_ctx->dstSgl) {
+ if (!areq_ctx->dst_sgl) {
SSI_LOG_ERR("reached end of sg list. unexpected\n");
BUG();
}
- sg_index += areq_ctx->dstSgl->length;
+ sg_index += areq_ctx->dst_sgl->length;
dst_mapped_nents--;
}
- if (unlikely(dst_mapped_nents > LLI_MAX_NUM_OF_DATA_ENTRIES))
- {
+ if (unlikely(dst_mapped_nents > LLI_MAX_NUM_OF_DATA_ENTRIES)) {
SSI_LOG_ERR("Too many fragments. current %d max %d\n",
dst_mapped_nents, LLI_MAX_NUM_OF_DATA_ENTRIES);
return -ENOMEM;
}
areq_ctx->dst.nents = dst_mapped_nents;
- areq_ctx->dstOffset = offset;
+ areq_ctx->dst_offset = offset;
if ((src_mapped_nents > 1) ||
(dst_mapped_nents > 1) ||
do_chain) {
areq_ctx->data_buff_type = SSI_DMA_BUF_MLLI;
- rc = ssi_buffer_mgr_prepare_aead_data_mlli(drvdata, req, sg_data,
- &src_last_bytes, &dst_last_bytes, is_last_table);
+ rc = ssi_buffer_mgr_prepare_aead_data_mlli(drvdata, req,
+ sg_data,
+ &src_last_bytes,
+ &dst_last_bytes,
+ is_last_table);
} else {
areq_ctx->data_buff_type = SSI_DMA_BUF_DLLI;
ssi_buffer_mgr_prepare_aead_data_dlli(
@@ -1202,7 +1230,7 @@ chain_data_exit:
}
static void ssi_buffer_mgr_update_aead_mlli_nents(struct ssi_drvdata *drvdata,
- struct aead_request *req)
+ struct aead_request *req)
{
struct aead_req_ctx *areq_ctx = aead_request_ctx(req);
u32 curr_mlli_size = 0;
@@ -1274,8 +1302,7 @@ int ssi_buffer_mgr_map_aead_request(
if (drvdata->coherent &&
(areq_ctx->gen_ctx.op_type == DRV_CRYPTO_DIRECTION_DECRYPT) &&
- likely(req->src == req->dst))
- {
+ likely(req->src == req->dst)) {
u32 size_to_skip = req->assoclen;
if (is_gcm4543)
@@ -1296,19 +1323,21 @@ int ssi_buffer_mgr_map_aead_request(
req->cryptlen :
(req->cryptlen - authsize);
- areq_ctx->mac_buf_dma_addr = dma_map_single(dev,
- areq_ctx->mac_buf, MAX_MAC_SIZE, DMA_BIDIRECTIONAL);
+ areq_ctx->mac_buf_dma_addr = dma_map_single(dev, areq_ctx->mac_buf,
+ MAX_MAC_SIZE,
+ DMA_BIDIRECTIONAL);
if (unlikely(dma_mapping_error(dev, areq_ctx->mac_buf_dma_addr))) {
SSI_LOG_ERR("Mapping mac_buf %u B at va=%pK for DMA failed\n",
- MAX_MAC_SIZE, areq_ctx->mac_buf);
+ MAX_MAC_SIZE, areq_ctx->mac_buf);
rc = -ENOMEM;
goto aead_map_failure;
}
if (areq_ctx->ccm_hdr_size != ccm_header_size_null) {
areq_ctx->ccm_iv0_dma_addr = dma_map_single(dev,
- (areq_ctx->ccm_config + CCM_CTR_COUNT_0_OFFSET),
- AES_BLOCK_SIZE, DMA_TO_DEVICE);
+ (areq_ctx->ccm_config + CCM_CTR_COUNT_0_OFFSET),
+ AES_BLOCK_SIZE,
+ DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(dev, areq_ctx->ccm_iv0_dma_addr))) {
SSI_LOG_ERR("Mapping mac_buf %u B at va=%pK "
@@ -1319,7 +1348,8 @@ int ssi_buffer_mgr_map_aead_request(
goto aead_map_failure;
}
if (ssi_aead_handle_config_buf(dev, areq_ctx,
- areq_ctx->ccm_config, &sg_data, req->assoclen) != 0) {
+ areq_ctx->ccm_config, &sg_data,
+ req->assoclen) != 0) {
rc = -ENOMEM;
goto aead_map_failure;
}
@@ -1328,26 +1358,31 @@ int ssi_buffer_mgr_map_aead_request(
#if SSI_CC_HAS_AES_GCM
if (areq_ctx->cipher_mode == DRV_CIPHER_GCTR) {
areq_ctx->hkey_dma_addr = dma_map_single(dev,
- areq_ctx->hkey, AES_BLOCK_SIZE, DMA_BIDIRECTIONAL);
+ areq_ctx->hkey,
+ AES_BLOCK_SIZE,
+ DMA_BIDIRECTIONAL);
if (unlikely(dma_mapping_error(dev, areq_ctx->hkey_dma_addr))) {
SSI_LOG_ERR("Mapping hkey %u B at va=%pK for DMA failed\n",
- AES_BLOCK_SIZE, areq_ctx->hkey);
+ AES_BLOCK_SIZE, areq_ctx->hkey);
rc = -ENOMEM;
goto aead_map_failure;
}
areq_ctx->gcm_block_len_dma_addr = dma_map_single(dev,
- &areq_ctx->gcm_len_block, AES_BLOCK_SIZE, DMA_TO_DEVICE);
+ &areq_ctx->gcm_len_block,
+ AES_BLOCK_SIZE,
+ DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(dev, areq_ctx->gcm_block_len_dma_addr))) {
SSI_LOG_ERR("Mapping gcm_len_block %u B at va=%pK for DMA failed\n",
- AES_BLOCK_SIZE, &areq_ctx->gcm_len_block);
+ AES_BLOCK_SIZE, &areq_ctx->gcm_len_block);
rc = -ENOMEM;
goto aead_map_failure;
}
areq_ctx->gcm_iv_inc1_dma_addr = dma_map_single(dev,
- areq_ctx->gcm_iv_inc1,
- AES_BLOCK_SIZE, DMA_TO_DEVICE);
+ areq_ctx->gcm_iv_inc1,
+ AES_BLOCK_SIZE,
+ DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(dev, areq_ctx->gcm_iv_inc1_dma_addr))) {
SSI_LOG_ERR("Mapping gcm_iv_inc1 %u B at va=%pK "
@@ -1359,8 +1394,9 @@ int ssi_buffer_mgr_map_aead_request(
}
areq_ctx->gcm_iv_inc2_dma_addr = dma_map_single(dev,
- areq_ctx->gcm_iv_inc2,
- AES_BLOCK_SIZE, DMA_TO_DEVICE);
+ areq_ctx->gcm_iv_inc2,
+ AES_BLOCK_SIZE,
+ DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(dev, areq_ctx->gcm_iv_inc2_dma_addr))) {
SSI_LOG_ERR("Mapping gcm_iv_inc2 %u B at va=%pK "
@@ -1380,7 +1416,7 @@ int ssi_buffer_mgr_map_aead_request(
if (is_gcm4543)
size_to_map += crypto_aead_ivsize(tfm);
rc = ssi_buffer_mgr_map_scatterlist(dev, req->src,
- size_to_map, DMA_BIDIRECTIONAL, &(areq_ctx->src.nents),
+ size_to_map, DMA_BIDIRECTIONAL, &areq_ctx->src.nents,
LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES + LLI_MAX_NUM_OF_DATA_ENTRIES, &dummy, &mapped_nents);
if (unlikely(rc != 0)) {
rc = -ENOMEM;
@@ -1491,18 +1527,18 @@ int ssi_buffer_mgr_map_hash_request_final(
/* map the previous buffer */
if (*curr_buff_cnt != 0) {
if (ssi_ahash_handle_curr_buf(dev, areq_ctx, curr_buff,
- *curr_buff_cnt, &sg_data) != 0) {
+ *curr_buff_cnt, &sg_data) != 0) {
return -ENOMEM;
}
}
if (src && (nbytes > 0) && do_update) {
- if (unlikely(ssi_buffer_mgr_map_scatterlist(dev, src,
- nbytes,
- DMA_TO_DEVICE,
- &areq_ctx->in_nents,
- LLI_MAX_NUM_OF_DATA_ENTRIES,
- &dummy, &mapped_nents))){
+ if (unlikely(ssi_buffer_mgr_map_scatterlist(dev, src, nbytes,
+ DMA_TO_DEVICE,
+ &areq_ctx->in_nents,
+ LLI_MAX_NUM_OF_DATA_ENTRIES,
+ &dummy,
+ &mapped_nents))){
goto unmap_curr_buff;
}
if (src && (mapped_nents == 1)
@@ -1522,19 +1558,18 @@ int ssi_buffer_mgr_map_hash_request_final(
mlli_params->curr_pool = buff_mgr->mlli_buffs_pool;
/* add the src data to the sg_data */
ssi_buffer_mgr_add_scatterlist_entry(&sg_data,
- areq_ctx->in_nents,
- src,
- nbytes, 0,
- true, &areq_ctx->mlli_nents);
+ areq_ctx->in_nents,
+ src, nbytes, 0, true,
+ &areq_ctx->mlli_nents);
if (unlikely(ssi_buffer_mgr_generate_mlli(dev, &sg_data,
- mlli_params) != 0)) {
+ mlli_params) != 0)) {
goto fail_unmap_din;
}
}
/* change the buffer index for the unmap function */
areq_ctx->buff_index = (areq_ctx->buff_index ^ 1);
SSI_LOG_DEBUG("areq_ctx->data_dma_buf_type = %s\n",
- GET_DMA_BUFFER_TYPE(areq_ctx->data_dma_buf_type));
+ GET_DMA_BUFFER_TYPE(areq_ctx->data_dma_buf_type));
return 0;
fail_unmap_din:
@@ -1588,8 +1623,8 @@ int ssi_buffer_mgr_map_hash_request_update(
&curr_buff[*curr_buff_cnt]);
areq_ctx->in_nents =
ssi_buffer_mgr_get_sgl_nents(src,
- nbytes,
- &dummy, NULL);
+ nbytes,
+ &dummy, NULL);
sg_copy_to_buffer(src, areq_ctx->in_nents,
&curr_buff[*curr_buff_cnt], nbytes);
*curr_buff_cnt += nbytes;
@@ -1612,15 +1647,15 @@ int ssi_buffer_mgr_map_hash_request_update(
(update_data_len - *curr_buff_cnt),
*next_buff_cnt);
ssi_buffer_mgr_copy_scatterlist_portion(next_buff, src,
- (update_data_len - *curr_buff_cnt),
- nbytes, SSI_SG_TO_BUF);
+ (update_data_len - *curr_buff_cnt),
+ nbytes, SSI_SG_TO_BUF);
/* change the buffer index for next operation */
swap_index = 1;
}
if (*curr_buff_cnt != 0) {
if (ssi_ahash_handle_curr_buf(dev, areq_ctx, curr_buff,
- *curr_buff_cnt, &sg_data) != 0) {
+ *curr_buff_cnt, &sg_data) != 0) {
return -ENOMEM;
}
/* change the buffer index for next operation */
@@ -1629,11 +1664,12 @@ int ssi_buffer_mgr_map_hash_request_update(
if (update_data_len > *curr_buff_cnt) {
if (unlikely(ssi_buffer_mgr_map_scatterlist(dev, src,
- (update_data_len - *curr_buff_cnt),
- DMA_TO_DEVICE,
- &areq_ctx->in_nents,
- LLI_MAX_NUM_OF_DATA_ENTRIES,
- &dummy, &mapped_nents))){
+ (update_data_len - *curr_buff_cnt),
+ DMA_TO_DEVICE,
+ &areq_ctx->in_nents,
+ LLI_MAX_NUM_OF_DATA_ENTRIES,
+ &dummy,
+ &mapped_nents))){
goto unmap_curr_buff;
}
if ((mapped_nents == 1)
@@ -1653,12 +1689,14 @@ int ssi_buffer_mgr_map_hash_request_update(
mlli_params->curr_pool = buff_mgr->mlli_buffs_pool;
/* add the src data to the sg_data */
ssi_buffer_mgr_add_scatterlist_entry(&sg_data,
- areq_ctx->in_nents,
- src,
- (update_data_len - *curr_buff_cnt), 0,
- true, &areq_ctx->mlli_nents);
+ areq_ctx->in_nents,
+ src,
+ (update_data_len - *curr_buff_cnt),
+ 0,
+ true,
+ &areq_ctx->mlli_nents);
if (unlikely(ssi_buffer_mgr_generate_mlli(dev, &sg_data,
- mlli_params) != 0)) {
+ mlli_params) != 0)) {
goto fail_unmap_din;
}
}
@@ -1687,28 +1725,28 @@ void ssi_buffer_mgr_unmap_hash_request(
*allocated and should be released
*/
if (areq_ctx->mlli_params.curr_pool) {
- SSI_LOG_DEBUG("free MLLI buffer: dma=0x%llX virt=%pK\n",
- (unsigned long long)areq_ctx->mlli_params.mlli_dma_addr,
- areq_ctx->mlli_params.mlli_virt_addr);
+ SSI_LOG_DEBUG("free MLLI buffer: dma=%pad virt=%pK\n",
+ areq_ctx->mlli_params.mlli_dma_addr,
+ areq_ctx->mlli_params.mlli_virt_addr);
dma_pool_free(areq_ctx->mlli_params.curr_pool,
areq_ctx->mlli_params.mlli_virt_addr,
areq_ctx->mlli_params.mlli_dma_addr);
}
if ((src) && likely(areq_ctx->in_nents != 0)) {
- SSI_LOG_DEBUG("Unmapped sg src: virt=%pK dma=0x%llX len=0x%X\n",
- sg_virt(src),
- (unsigned long long)sg_dma_address(src),
- sg_dma_len(src));
+ SSI_LOG_DEBUG("Unmapped sg src: virt=%pK dma=%pad len=0x%X\n",
+ sg_virt(src),
+ sg_dma_address(src),
+ sg_dma_len(src));
dma_unmap_sg(dev, src,
areq_ctx->in_nents, DMA_TO_DEVICE);
}
if (*prev_len != 0) {
SSI_LOG_DEBUG("Unmapped buffer: areq_ctx->buff_sg=%pK"
- " dma=0x%llX len 0x%X\n",
+ " dma=%pad len 0x%X\n",
sg_virt(areq_ctx->buff_sg),
- (unsigned long long)sg_dma_address(areq_ctx->buff_sg),
+ sg_dma_address(areq_ctx->buff_sg),
sg_dma_len(areq_ctx->buff_sg));
dma_unmap_sg(dev, areq_ctx->buff_sg, 1, DMA_TO_DEVICE);
if (!do_revert) {
@@ -1725,8 +1763,7 @@ int ssi_buffer_mgr_init(struct ssi_drvdata *drvdata)
struct buff_mgr_handle *buff_mgr_handle;
struct device *dev = &drvdata->plat_dev->dev;
- buff_mgr_handle = (struct buff_mgr_handle *)
- kmalloc(sizeof(struct buff_mgr_handle), GFP_KERNEL);
+ buff_mgr_handle = kmalloc(sizeof(*buff_mgr_handle), GFP_KERNEL);
if (!buff_mgr_handle)
return -ENOMEM;
diff --git a/drivers/staging/ccree/ssi_cipher.c b/drivers/staging/ccree/ssi_cipher.c
index cd2eafc..8d31a93 100644
--- a/drivers/staging/ccree/ssi_cipher.c
+++ b/drivers/staging/ccree/ssi_cipher.c
@@ -23,6 +23,8 @@
#include <crypto/aes.h>
#include <crypto/ctr.h>
#include <crypto/des.h>
+#include <crypto/xts.h>
+#include <crypto/scatterwalk.h>
#include "ssi_config.h"
#include "ssi_driver.h"
@@ -31,7 +33,6 @@
#include "ssi_cipher.h"
#include "ssi_request_mgr.h"
#include "ssi_sysfs.h"
-#include "ssi_fips_local.h"
#define MAX_ABLKCIPHER_SEQ_LEN 6
@@ -68,7 +69,8 @@ struct ssi_ablkcipher_ctx {
static void ssi_ablkcipher_complete(struct device *dev, void *ssi_req, void __iomem *cc_base);
-static int validate_keys_sizes(struct ssi_ablkcipher_ctx *ctx_p, u32 size) {
+static int validate_keys_sizes(struct ssi_ablkcipher_ctx *ctx_p, u32 size)
+{
switch (ctx_p->flow_mode) {
case S_DIN_to_AES:
switch (size) {
@@ -92,8 +94,7 @@ static int validate_keys_sizes(struct ssi_ablkcipher_ctx *ctx_p, u32 size) {
break;
}
case S_DIN_to_DES:
- if (likely(size == DES3_EDE_KEY_SIZE ||
- size == DES_KEY_SIZE))
+ if (likely(size == DES3_EDE_KEY_SIZE || size == DES_KEY_SIZE))
return 0;
break;
#if SSI_CC_HAS_MULTI2
@@ -108,7 +109,8 @@ static int validate_keys_sizes(struct ssi_ablkcipher_ctx *ctx_p, u32 size) {
return -EINVAL;
}
-static int validate_data_size(struct ssi_ablkcipher_ctx *ctx_p, unsigned int size) {
+static int validate_data_size(struct ssi_ablkcipher_ctx *ctx_p, unsigned int size)
+{
switch (ctx_p->flow_mode) {
case S_DIN_to_AES:
switch (ctx_p->cipher_mode) {
@@ -183,10 +185,9 @@ static int ssi_blkcipher_init(struct crypto_tfm *tfm)
int rc = 0;
unsigned int max_key_buf_size = get_max_keysize(tfm);
- SSI_LOG_DEBUG("Initializing context @%p for %s\n", ctx_p,
- crypto_tfm_alg_name(tfm));
+ SSI_LOG_DEBUG("Initializing context @%p for %s\n",
+ ctx_p, crypto_tfm_alg_name(tfm));
- CHECK_AND_RETURN_UPON_FIPS_ERROR();
ctx_p->cipher_mode = ssi_alg->cipher_mode;
ctx_p->flow_mode = ssi_alg->flow_mode;
ctx_p->drvdata = ssi_alg->drvdata;
@@ -203,15 +204,16 @@ static int ssi_blkcipher_init(struct crypto_tfm *tfm)
/* Map key buffer */
ctx_p->user.key_dma_addr = dma_map_single(dev, (void *)ctx_p->user.key,
- max_key_buf_size, DMA_TO_DEVICE);
+ max_key_buf_size,
+ DMA_TO_DEVICE);
if (dma_mapping_error(dev, ctx_p->user.key_dma_addr)) {
SSI_LOG_ERR("Mapping Key %u B at va=%pK for DMA failed\n",
- max_key_buf_size, ctx_p->user.key);
+ max_key_buf_size, ctx_p->user.key);
return -ENOMEM;
}
- SSI_LOG_DEBUG("Mapped key %u B at va=%pK to dma=0x%llX\n",
- max_key_buf_size, ctx_p->user.key,
- (unsigned long long)ctx_p->user.key_dma_addr);
+ SSI_LOG_DEBUG("Mapped key %u B at va=%pK to dma=%pad\n",
+ max_key_buf_size, ctx_p->user.key,
+ ctx_p->user.key_dma_addr);
if (ctx_p->cipher_mode == DRV_CIPHER_ESSIV) {
/* Alloc hash tfm for essiv */
@@ -232,7 +234,7 @@ static void ssi_blkcipher_exit(struct crypto_tfm *tfm)
unsigned int max_key_buf_size = get_max_keysize(tfm);
SSI_LOG_DEBUG("Clearing context @%p for %s\n",
- crypto_tfm_ctx(tfm), crypto_tfm_alg_name(tfm));
+ crypto_tfm_ctx(tfm), crypto_tfm_alg_name(tfm));
if (ctx_p->cipher_mode == DRV_CIPHER_ESSIV) {
/* Free hash tfm for essiv */
@@ -242,9 +244,9 @@ static void ssi_blkcipher_exit(struct crypto_tfm *tfm)
/* Unmap key buffer */
dma_unmap_single(dev, ctx_p->user.key_dma_addr, max_key_buf_size,
- DMA_TO_DEVICE);
- SSI_LOG_DEBUG("Unmapped key buffer key_dma_addr=0x%llX\n",
- (unsigned long long)ctx_p->user.key_dma_addr);
+ DMA_TO_DEVICE);
+ SSI_LOG_DEBUG("Unmapped key buffer key_dma_addr=%pad\n",
+ ctx_p->user.key_dma_addr);
/* Free key buffer in context */
kfree(ctx_p->user.key);
@@ -263,31 +265,15 @@ static const u8 zero_buff[] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
/* The function verifies that tdes keys are not weak.*/
-static int ssi_fips_verify_3des_keys(const u8 *key, unsigned int keylen)
+static int ssi_verify_3des_keys(const u8 *key, unsigned int keylen)
{
-#ifdef CCREE_FIPS_SUPPORT
struct tdes_keys *tdes_key = (struct tdes_keys *)key;
/* verify key1 != key2 and key3 != key2*/
if (unlikely((memcmp((u8 *)tdes_key->key1, (u8 *)tdes_key->key2, sizeof(tdes_key->key1)) == 0) ||
- (memcmp((u8 *)tdes_key->key3, (u8 *)tdes_key->key2, sizeof(tdes_key->key3)) == 0))) {
+ (memcmp((u8 *)tdes_key->key3, (u8 *)tdes_key->key2, sizeof(tdes_key->key3)) == 0))) {
return -ENOEXEC;
}
-#endif /* CCREE_FIPS_SUPPORT */
-
- return 0;
-}
-
-/* The function verifies that xts keys are not weak.*/
-static int ssi_fips_verify_xts_keys(const u8 *key, unsigned int keylen)
-{
-#ifdef CCREE_FIPS_SUPPORT
- /* Weak key is define as key that its first half (128/256 lsb) equals its second half (128/256 msb) */
- int singleKeySize = keylen >> 1;
-
- if (unlikely(memcmp(key, &key[singleKeySize], singleKeySize) == 0))
- return -ENOEXEC;
-#endif /* CCREE_FIPS_SUPPORT */
return 0;
}
@@ -317,12 +303,10 @@ static int ssi_blkcipher_setkey(struct crypto_tfm *tfm,
unsigned int max_key_buf_size = get_max_keysize(tfm);
SSI_LOG_DEBUG("Setting key in context @%p for %s. keylen=%u\n",
- ctx_p, crypto_tfm_alg_name(tfm), keylen);
+ ctx_p, crypto_tfm_alg_name(tfm), keylen);
dump_byte_array("key", (u8 *)key, keylen);
- CHECK_AND_RETURN_UPON_FIPS_ERROR();
-
- SSI_LOG_DEBUG("ssi_blkcipher_setkey: after FIPS check");
+ SSI_LOG_DEBUG("after FIPS check");
/* STAT_PHASE_0: Init and sanity checks */
@@ -368,7 +352,7 @@ static int ssi_blkcipher_setkey(struct crypto_tfm *tfm,
}
ctx_p->keylen = keylen;
- SSI_LOG_DEBUG("ssi_blkcipher_setkey: ssi_is_hw_key ret 0");
+ SSI_LOG_DEBUG("ssi_is_hw_key ret 0");
return 0;
}
@@ -378,25 +362,25 @@ static int ssi_blkcipher_setkey(struct crypto_tfm *tfm,
if (unlikely(!des_ekey(tmp, key)) &&
(crypto_tfm_get_flags(tfm) & CRYPTO_TFM_REQ_WEAK_KEY)) {
tfm->crt_flags |= CRYPTO_TFM_RES_WEAK_KEY;
- SSI_LOG_DEBUG("ssi_blkcipher_setkey: weak DES key");
+ SSI_LOG_DEBUG("weak DES key");
return -EINVAL;
}
}
if ((ctx_p->cipher_mode == DRV_CIPHER_XTS) &&
- ssi_fips_verify_xts_keys(key, keylen) != 0) {
- SSI_LOG_DEBUG("ssi_blkcipher_setkey: weak XTS key");
+ xts_check_key(tfm, key, keylen) != 0) {
+ SSI_LOG_DEBUG("weak XTS key");
return -EINVAL;
}
if ((ctx_p->flow_mode == S_DIN_to_DES) &&
(keylen == DES3_EDE_KEY_SIZE) &&
- ssi_fips_verify_3des_keys(key, keylen) != 0) {
- SSI_LOG_DEBUG("ssi_blkcipher_setkey: weak 3DES key");
+ ssi_verify_3des_keys(key, keylen) != 0) {
+ SSI_LOG_DEBUG("weak 3DES key");
return -EINVAL;
}
/* STAT_PHASE_1: Copy key to ctx */
dma_sync_single_for_cpu(dev, ctx_p->user.key_dma_addr,
- max_key_buf_size, DMA_TO_DEVICE);
+ max_key_buf_size, DMA_TO_DEVICE);
if (ctx_p->flow_mode == S_DIN_to_MULTI2) {
#if SSI_CC_HAS_MULTI2
@@ -405,7 +389,7 @@ static int ssi_blkcipher_setkey(struct crypto_tfm *tfm,
if (ctx_p->key_round_number < CC_MULTI2_MIN_NUM_ROUNDS ||
ctx_p->key_round_number > CC_MULTI2_MAX_NUM_ROUNDS) {
crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
- SSI_LOG_DEBUG("ssi_blkcipher_setkey: SSI_CC_HAS_MULTI2 einval");
+ SSI_LOG_DEBUG("SSI_CC_HAS_MULTI2 einval");
return -EINVAL;
#endif /*SSI_CC_HAS_MULTI2*/
} else {
@@ -429,10 +413,10 @@ static int ssi_blkcipher_setkey(struct crypto_tfm *tfm,
}
}
dma_sync_single_for_device(dev, ctx_p->user.key_dma_addr,
- max_key_buf_size, DMA_TO_DEVICE);
+ max_key_buf_size, DMA_TO_DEVICE);
ctx_p->keylen = keylen;
- SSI_LOG_DEBUG("ssi_blkcipher_setkey: return safely");
+ SSI_LOG_DEBUG("return safely");
return 0;
}
@@ -632,17 +616,15 @@ ssi_blkcipher_create_data_desc(
break;
#endif /*SSI_CC_HAS_MULTI2*/
default:
- SSI_LOG_ERR("invalid flow mode, flow_mode = %d \n", flow_mode);
+ SSI_LOG_ERR("invalid flow mode, flow_mode = %d\n", flow_mode);
return;
}
/* Process */
if (likely(req_ctx->dma_buf_type == SSI_DMA_BUF_DLLI)) {
- SSI_LOG_DEBUG(" data params addr 0x%llX length 0x%X \n",
- (unsigned long long)sg_dma_address(src),
- nbytes);
- SSI_LOG_DEBUG(" data params addr 0x%llX length 0x%X \n",
- (unsigned long long)sg_dma_address(dst),
- nbytes);
+ SSI_LOG_DEBUG(" data params addr %pad length 0x%X\n",
+ sg_dma_address(src), nbytes);
+ SSI_LOG_DEBUG(" data params addr %pad length 0x%X\n",
+ sg_dma_address(dst), nbytes);
hw_desc_init(&desc[*seq_size]);
set_din_type(&desc[*seq_size], DMA_DLLI, sg_dma_address(src),
nbytes, NS_BIT);
@@ -655,9 +637,9 @@ ssi_blkcipher_create_data_desc(
(*seq_size)++;
} else {
/* bypass */
- SSI_LOG_DEBUG(" bypass params addr 0x%llX "
+ SSI_LOG_DEBUG(" bypass params addr %pad "
"length 0x%X addr 0x%08X\n",
- (unsigned long long)req_ctx->mlli_params.mlli_dma_addr,
+ req_ctx->mlli_params.mlli_dma_addr,
req_ctx->mlli_params.mlli_len,
(unsigned int)ctx_p->drvdata->mlli_sram_addr);
hw_desc_init(&desc[*seq_size]);
@@ -706,16 +688,17 @@ ssi_blkcipher_create_data_desc(
}
static int ssi_blkcipher_complete(struct device *dev,
- struct ssi_ablkcipher_ctx *ctx_p,
- struct blkcipher_req_ctx *req_ctx,
- struct scatterlist *dst,
- struct scatterlist *src,
- unsigned int ivsize,
- void *areq,
- void __iomem *cc_base)
+ struct ssi_ablkcipher_ctx *ctx_p,
+ struct blkcipher_req_ctx *req_ctx,
+ struct scatterlist *dst,
+ struct scatterlist *src,
+ unsigned int ivsize,
+ void *areq,
+ void __iomem *cc_base)
{
int completion_error = 0;
u32 inflight_counter;
+ struct ablkcipher_request *req = (struct ablkcipher_request *)areq;
ssi_buffer_mgr_unmap_blkcipher_request(dev, req_ctx, ivsize, src, dst);
@@ -726,6 +709,22 @@ static int ssi_blkcipher_complete(struct device *dev,
ctx_p->drvdata->inflight_counter--;
if (areq) {
+ /*
+ * The crypto API expects us to set the req->info to the last
+ * ciphertext block. For encrypt, simply copy from the result.
+ * For decrypt, we must copy from a saved buffer since this
+ * could be an in-place decryption operation and the src is
+ * lost by this point.
+ */
+ if (req_ctx->gen_ctx.op_type == DRV_CRYPTO_DIRECTION_DECRYPT) {
+ memcpy(req->info, req_ctx->backup_info, ivsize);
+ kfree(req_ctx->backup_info);
+ } else {
+ scatterwalk_map_and_copy(req->info, req->dst,
+ (req->nbytes - ivsize),
+ ivsize, 0);
+ }
+
ablkcipher_request_complete(areq, completion_error);
return 0;
}
@@ -749,21 +748,22 @@ static int ssi_blkcipher_process(
int rc, seq_len = 0, cts_restore_flag = 0;
SSI_LOG_DEBUG("%s areq=%p info=%p nbytes=%d\n",
- ((direction == DRV_CRYPTO_DIRECTION_ENCRYPT) ? "Encrypt" : "Decrypt"),
- areq, info, nbytes);
+ ((direction == DRV_CRYPTO_DIRECTION_ENCRYPT) ? "Encrypt" : "Decrypt"),
+ areq, info, nbytes);
- CHECK_AND_RETURN_UPON_FIPS_ERROR();
/* STAT_PHASE_0: Init and sanity checks */
/* TODO: check data length according to mode */
if (unlikely(validate_data_size(ctx_p, nbytes))) {
SSI_LOG_ERR("Unsupported data size %d.\n", nbytes);
crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_BLOCK_LEN);
- return -EINVAL;
+ rc = -EINVAL;
+ goto exit_process;
}
if (nbytes == 0) {
/* No data to process is valid */
- return 0;
+ rc = 0;
+ goto exit_process;
}
/*For CTS in case of data size aligned to 16 use CBC mode*/
if (((nbytes % AES_BLOCK_SIZE) == 0) && (ctx_p->cipher_mode == DRV_CIPHER_CBC_CTS)) {
@@ -804,12 +804,8 @@ static int ssi_blkcipher_process(
ssi_blkcipher_create_setup_desc(tfm, req_ctx, ivsize, nbytes,
desc, &seq_len);
/* Data processing */
- ssi_blkcipher_create_data_desc(tfm,
- req_ctx,
- dst, src,
- nbytes,
- areq,
- desc, &seq_len);
+ ssi_blkcipher_create_data_desc(tfm, req_ctx, dst, src, nbytes, areq,
+ desc, &seq_len);
/* do we need to generate IV? */
if (req_ctx->is_giv) {
@@ -842,6 +838,9 @@ exit_process:
if (cts_restore_flag != 0)
ctx_p->cipher_mode = DRV_CIPHER_CBC_CTS;
+ if (rc != -EINPROGRESS)
+ kfree(req_ctx->backup_info);
+
return rc;
}
@@ -853,8 +852,6 @@ static void ssi_ablkcipher_complete(struct device *dev, void *ssi_req, void __io
struct ssi_ablkcipher_ctx *ctx_p = crypto_ablkcipher_ctx(tfm);
unsigned int ivsize = crypto_ablkcipher_ivsize(tfm);
- CHECK_AND_RETURN_VOID_UPON_FIPS_ERROR();
-
ssi_blkcipher_complete(dev, ctx_p, req_ctx, areq->dst, areq->src,
ivsize, areq, cc_base);
}
@@ -871,8 +868,8 @@ static int ssi_ablkcipher_init(struct crypto_tfm *tfm)
}
static int ssi_ablkcipher_setkey(struct crypto_ablkcipher *tfm,
- const u8 *key,
- unsigned int keylen)
+ const u8 *key,
+ unsigned int keylen)
{
return ssi_blkcipher_setkey(crypto_ablkcipher_tfm(tfm), key, keylen);
}
@@ -884,7 +881,6 @@ static int ssi_ablkcipher_encrypt(struct ablkcipher_request *req)
struct blkcipher_req_ctx *req_ctx = ablkcipher_request_ctx(req);
unsigned int ivsize = crypto_ablkcipher_ivsize(ablk_tfm);
- req_ctx->backup_info = req->info;
req_ctx->is_giv = false;
return ssi_blkcipher_process(tfm, req_ctx, req->dst, req->src, req->nbytes, req->info, ivsize, (void *)req, DRV_CRYPTO_DIRECTION_ENCRYPT);
@@ -897,8 +893,18 @@ static int ssi_ablkcipher_decrypt(struct ablkcipher_request *req)
struct blkcipher_req_ctx *req_ctx = ablkcipher_request_ctx(req);
unsigned int ivsize = crypto_ablkcipher_ivsize(ablk_tfm);
- req_ctx->backup_info = req->info;
+ /*
+ * Allocate and save the last IV sized bytes of the source, which will
+ * be lost in case of in-place decryption and might be needed for CTS.
+ */
+ req_ctx->backup_info = kmalloc(ivsize, GFP_KERNEL);
+ if (!req_ctx->backup_info)
+ return -ENOMEM;
+
+ scatterwalk_map_and_copy(req_ctx->backup_info, req->src,
+ (req->nbytes - ivsize), ivsize, 0);
req_ctx->is_giv = false;
+
return ssi_blkcipher_process(tfm, req_ctx, req->dst, req->src, req->nbytes, req->info, ivsize, (void *)req, DRV_CRYPTO_DIRECTION_DECRYPT);
}
@@ -1244,7 +1250,7 @@ struct ssi_crypto_alg *ssi_ablkcipher_create_alg(struct ssi_alg_template *templa
struct ssi_crypto_alg *t_alg;
struct crypto_alg *alg;
- t_alg = kzalloc(sizeof(struct ssi_crypto_alg), GFP_KERNEL);
+ t_alg = kzalloc(sizeof(*t_alg), GFP_KERNEL);
if (!t_alg) {
SSI_LOG_ERR("failed to allocate t_alg\n");
return ERR_PTR(-ENOMEM);
@@ -1286,7 +1292,7 @@ int ssi_ablkcipher_free(struct ssi_drvdata *drvdata)
if (blkcipher_handle) {
/* Remove registered algs */
list_for_each_entry_safe(t_alg, n,
- &blkcipher_handle->blkcipher_alg_list,
+ &blkcipher_handle->blkcipher_alg_list,
entry) {
crypto_unregister_alg(&t_alg->crypto_alg);
list_del(&t_alg->entry);
@@ -1305,8 +1311,7 @@ int ssi_ablkcipher_alloc(struct ssi_drvdata *drvdata)
int rc = -ENOMEM;
int alg;
- ablkcipher_handle = kmalloc(sizeof(struct ssi_blkcipher_handle),
- GFP_KERNEL);
+ ablkcipher_handle = kmalloc(sizeof(*ablkcipher_handle), GFP_KERNEL);
if (!ablkcipher_handle)
return -ENOMEM;
@@ -1322,7 +1327,7 @@ int ssi_ablkcipher_alloc(struct ssi_drvdata *drvdata)
if (IS_ERR(t_alg)) {
rc = PTR_ERR(t_alg);
SSI_LOG_ERR("%s alg allocation failed\n",
- blkcipher_algs[alg].driver_name);
+ blkcipher_algs[alg].driver_name);
goto fail0;
}
t_alg->drvdata = drvdata;
@@ -1330,17 +1335,17 @@ int ssi_ablkcipher_alloc(struct ssi_drvdata *drvdata)
SSI_LOG_DEBUG("registering %s\n", blkcipher_algs[alg].driver_name);
rc = crypto_register_alg(&t_alg->crypto_alg);
SSI_LOG_DEBUG("%s alg registration rc = %x\n",
- t_alg->crypto_alg.cra_driver_name, rc);
+ t_alg->crypto_alg.cra_driver_name, rc);
if (unlikely(rc != 0)) {
SSI_LOG_ERR("%s alg registration failed\n",
- t_alg->crypto_alg.cra_driver_name);
+ t_alg->crypto_alg.cra_driver_name);
kfree(t_alg);
goto fail0;
} else {
list_add_tail(&t_alg->entry,
&ablkcipher_handle->blkcipher_alg_list);
SSI_LOG_DEBUG("Registered %s\n",
- t_alg->crypto_alg.cra_driver_name);
+ t_alg->crypto_alg.cra_driver_name);
}
}
return 0;
diff --git a/drivers/staging/ccree/ssi_driver.c b/drivers/staging/ccree/ssi_driver.c
index 78709b92..9c6f120 100644
--- a/drivers/staging/ccree/ssi_driver.c
+++ b/drivers/staging/ccree/ssi_driver.c
@@ -71,7 +71,7 @@
#include "ssi_ivgen.h"
#include "ssi_sram_mgr.h"
#include "ssi_pm.h"
-#include "ssi_fips_local.h"
+#include "ssi_fips.h"
#ifdef DX_DUMP_BYTES
void dump_byte_array(const char *name, const u8 *the_array, unsigned long size)
@@ -81,12 +81,11 @@ void dump_byte_array(const char *name, const u8 *the_array, unsigned long size)
char line_buf[80];
if (!the_array) {
- SSI_LOG_ERR("cannot dump_byte_array - NULL pointer\n");
+ SSI_LOG_ERR("cannot dump array - NULL pointer\n");
return;
}
- ret = snprintf(line_buf, sizeof(line_buf), "%s[%lu]: ",
- name, size);
+ ret = snprintf(line_buf, sizeof(line_buf), "%s[%lu]: ", name, size);
if (ret < 0) {
SSI_LOG_ERR("snprintf returned %d . aborting buffer array dump\n", ret);
return;
@@ -95,8 +94,8 @@ void dump_byte_array(const char *name, const u8 *the_array, unsigned long size)
for (i = 0, cur_byte = the_array;
(i < size) && (line_offset < sizeof(line_buf)); i++, cur_byte++) {
ret = snprintf(line_buf + line_offset,
- sizeof(line_buf) - line_offset,
- "0x%02X ", *cur_byte);
+ sizeof(line_buf) - line_offset,
+ "0x%02X ", *cur_byte);
if (ret < 0) {
SSI_LOG_ERR("snprintf returned %d . aborting buffer array dump\n", ret);
return;
@@ -193,11 +192,11 @@ int init_cc_regs(struct ssi_drvdata *drvdata, bool is_probe)
#ifdef DX_IRQ_DELAY
/* Set CC IRQ delay */
CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IRQ_TIMER_INIT_VAL),
- DX_IRQ_DELAY);
+ DX_IRQ_DELAY);
#endif
if (CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IRQ_TIMER_INIT_VAL)) > 0) {
SSI_LOG_DEBUG("irq_delay=%d CC cycles\n",
- CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IRQ_TIMER_INIT_VAL)));
+ CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IRQ_TIMER_INIT_VAL)));
}
#endif
@@ -224,7 +223,8 @@ static int init_cc_resources(struct platform_device *plat_dev)
struct resource *req_mem_cc_regs = NULL;
void __iomem *cc_base = NULL;
bool irq_registered = false;
- struct ssi_drvdata *new_drvdata = kzalloc(sizeof(struct ssi_drvdata), GFP_KERNEL);
+ struct ssi_drvdata *new_drvdata = kzalloc(sizeof(*new_drvdata),
+ GFP_KERNEL);
struct device *dev = &plat_dev->dev;
struct device_node *np = dev->of_node;
u32 signature_val;
@@ -251,10 +251,10 @@ static int init_cc_resources(struct platform_device *plat_dev)
rc = -ENODEV;
goto init_cc_res_err;
}
- SSI_LOG_DEBUG("Got MEM resource (%s): start=0x%llX end=0x%llX\n",
- new_drvdata->res_mem->name,
- (unsigned long long)new_drvdata->res_mem->start,
- (unsigned long long)new_drvdata->res_mem->end);
+ SSI_LOG_DEBUG("Got MEM resource (%s): start=%pad end=%pad\n",
+ new_drvdata->res_mem->name,
+ new_drvdata->res_mem->start,
+ new_drvdata->res_mem->end);
/* Map registers space */
req_mem_cc_regs = request_mem_region(new_drvdata->res_mem->start, resource_size(new_drvdata->res_mem), "arm_cc7x_regs");
if (unlikely(!req_mem_cc_regs)) {
@@ -266,7 +266,8 @@ static int init_cc_resources(struct platform_device *plat_dev)
cc_base = ioremap(new_drvdata->res_mem->start, resource_size(new_drvdata->res_mem));
if (unlikely(!cc_base)) {
SSI_LOG_ERR("ioremap[CC](0x%08X,0x%08X) failed\n",
- (unsigned int)new_drvdata->res_mem->start, (unsigned int)resource_size(new_drvdata->res_mem));
+ (unsigned int)new_drvdata->res_mem->start,
+ (unsigned int)resource_size(new_drvdata->res_mem));
rc = -ENOMEM;
goto init_cc_res_err;
}
@@ -284,15 +285,15 @@ static int init_cc_resources(struct platform_device *plat_dev)
IRQF_SHARED, "arm_cc7x", new_drvdata);
if (unlikely(rc != 0)) {
SSI_LOG_ERR("Could not register to interrupt %llu\n",
- (unsigned long long)new_drvdata->res_irq->start);
+ (unsigned long long)new_drvdata->res_irq->start);
goto init_cc_res_err;
}
init_completion(&new_drvdata->icache_setup_completion);
irq_registered = true;
SSI_LOG_DEBUG("Registered to IRQ (%s) %llu\n",
- new_drvdata->res_irq->name,
- (unsigned long long)new_drvdata->res_irq->start);
+ new_drvdata->res_irq->name,
+ (unsigned long long)new_drvdata->res_irq->start);
new_drvdata->plat_dev = plat_dev;
@@ -301,19 +302,16 @@ static int init_cc_resources(struct platform_device *plat_dev)
goto init_cc_res_err;
if (!new_drvdata->plat_dev->dev.dma_mask)
- {
new_drvdata->plat_dev->dev.dma_mask = &new_drvdata->plat_dev->dev.coherent_dma_mask;
- }
+
if (!new_drvdata->plat_dev->dev.coherent_dma_mask)
- {
new_drvdata->plat_dev->dev.coherent_dma_mask = DMA_BIT_MASK(DMA_BIT_MASK_LEN);
- }
/* Verify correct mapping */
signature_val = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_SIGNATURE));
if (signature_val != DX_DEV_SIGNATURE) {
SSI_LOG_ERR("Invalid CC signature: SIGNATURE=0x%08X != expected=0x%08X\n",
- signature_val, (u32)DX_DEV_SIGNATURE);
+ signature_val, (u32)DX_DEV_SIGNATURE);
rc = -EINVAL;
goto init_cc_res_err;
}
@@ -330,7 +328,7 @@ static int init_cc_resources(struct platform_device *plat_dev)
}
#ifdef ENABLE_CC_SYSFS
- rc = ssi_sysfs_init(&(plat_dev->dev.kobj), new_drvdata);
+ rc = ssi_sysfs_init(&plat_dev->dev.kobj, new_drvdata);
if (unlikely(rc != 0)) {
SSI_LOG_ERR("init_stat_db failed\n");
goto init_cc_res_err;
@@ -401,6 +399,12 @@ static int init_cc_resources(struct platform_device *plat_dev)
goto init_cc_res_err;
}
+ /* If we got here and FIPS mode is enabled
+ * it means all FIPS test passed, so let TEE
+ * know we're good.
+ */
+ cc_set_ree_fips_status(new_drvdata, true);
+
return 0;
init_cc_res_err:
@@ -428,7 +432,7 @@ init_cc_res_err:
new_drvdata->cc_base = NULL;
}
release_mem_region(new_drvdata->res_mem->start,
- resource_size(new_drvdata->res_mem));
+ resource_size(new_drvdata->res_mem));
new_drvdata->res_mem = NULL;
}
kfree(new_drvdata);
@@ -471,7 +475,7 @@ static void cleanup_cc_resources(struct platform_device *plat_dev)
if (drvdata->cc_base) {
iounmap(drvdata->cc_base);
release_mem_region(drvdata->res_mem->start,
- resource_size(drvdata->res_mem));
+ resource_size(drvdata->res_mem));
drvdata->cc_base = NULL;
drvdata->res_mem = NULL;
}
@@ -516,12 +520,12 @@ static int cc7x_probe(struct platform_device *plat_dev)
asm volatile("mrc p15, 0, %0, c0, c0, 1" : "=r" (ctr));
cacheline_size = 4 << ((ctr >> 16) & 0xf);
SSI_LOG_DEBUG("CP15(L1_CACHE_BYTES) = %u , Kconfig(L1_CACHE_BYTES) = %u\n",
- cacheline_size, L1_CACHE_BYTES);
+ cacheline_size, L1_CACHE_BYTES);
asm volatile("mrc p15, 0, %0, c0, c0, 0" : "=r" (ctr));
- SSI_LOG_DEBUG("Main ID register (MIDR): Implementer 0x%02X, Arch 0x%01X,"
- " Part 0x%03X, Rev r%dp%d\n",
- (ctr >> 24), (ctr >> 16) & 0xF, (ctr >> 4) & 0xFFF, (ctr >> 20) & 0xF, ctr & 0xF);
+ SSI_LOG_DEBUG("Main ID register (MIDR): Implementer 0x%02X, Arch 0x%01X, Part 0x%03X, Rev r%dp%d\n",
+ (ctr >> 24), (ctr >> 16) & 0xF, (ctr >> 4) & 0xFFF,
+ (ctr >> 20) & 0xF, ctr & 0xF);
#endif
/* Map registers space */
@@ -546,7 +550,7 @@ static int cc7x_remove(struct platform_device *plat_dev)
}
#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP)
-static struct dev_pm_ops arm_cc7x_driver_pm = {
+static const struct dev_pm_ops arm_cc7x_driver_pm = {
SET_RUNTIME_PM_OPS(ssi_power_mgr_runtime_suspend, ssi_power_mgr_runtime_resume, NULL)
};
#endif
diff --git a/drivers/staging/ccree/ssi_driver.h b/drivers/staging/ccree/ssi_driver.h
index c1ed61f..b6ad89a 100644
--- a/drivers/staging/ccree/ssi_driver.h
+++ b/drivers/staging/ccree/ssi_driver.h
@@ -48,7 +48,6 @@
#include "cc_crypto_ctx.h"
#include "ssi_sysfs.h"
#include "hash_defs.h"
-#include "ssi_fips_local.h"
#include "cc_hw_queue_defs.h"
#include "ssi_sram_mgr.h"
diff --git a/drivers/staging/ccree/ssi_fips.c b/drivers/staging/ccree/ssi_fips.c
index fdc40f3..33d53d6 100644
--- a/drivers/staging/ccree/ssi_fips.c
+++ b/drivers/staging/ccree/ssi_fips.c
@@ -14,48 +14,115 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-/**************************************************************
- * This file defines the driver FIPS APIs *
- **************************************************************/
+#include <linux/kernel.h>
+#include <linux/fips.h>
-#include <linux/module.h>
+#include "ssi_config.h"
+#include "ssi_driver.h"
+#include "cc_hal.h"
#include "ssi_fips.h"
-extern int ssi_fips_ext_get_state(enum cc_fips_state_t *p_state);
-extern int ssi_fips_ext_get_error(enum cc_fips_error *p_err);
+static void fips_dsr(unsigned long devarg);
+
+struct ssi_fips_handle {
+ struct tasklet_struct tasklet;
+};
+
+/* The function called once at driver entry point to check
+ * whether TEE FIPS error occurred.
+ */
+static bool cc_get_tee_fips_status(struct ssi_drvdata *drvdata)
+{
+ u32 reg;
+ void __iomem *cc_base = drvdata->cc_base;
+
+ reg = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, GPR_HOST));
+ return (reg == (CC_FIPS_SYNC_TEE_STATUS | CC_FIPS_SYNC_MODULE_OK));
+}
/*
- * This function returns the REE FIPS state.
- * It should be called by kernel module.
+ * This function should push the FIPS REE library status towards the TEE library
+ * by writing the error state to HOST_GPR0 register.
*/
-int ssi_fips_get_state(enum cc_fips_state_t *p_state)
+void cc_set_ree_fips_status(struct ssi_drvdata *drvdata, bool status)
+{
+ void __iomem *cc_base = drvdata->cc_base;
+ int val = CC_FIPS_SYNC_REE_STATUS;
+
+ val |= (status ? CC_FIPS_SYNC_MODULE_OK : CC_FIPS_SYNC_MODULE_ERROR);
+
+ CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_GPR0), val);
+}
+
+void ssi_fips_fini(struct ssi_drvdata *drvdata)
{
- int rc = 0;
+ struct ssi_fips_handle *fips_h = drvdata->fips_handle;
- if (!p_state)
- return -EINVAL;
+ if (!fips_h)
+ return; /* Not allocated */
- rc = ssi_fips_ext_get_state(p_state);
+ /* Kill tasklet */
+ tasklet_kill(&fips_h->tasklet);
- return rc;
+ kfree(fips_h);
+ drvdata->fips_handle = NULL;
}
-EXPORT_SYMBOL(ssi_fips_get_state);
+void fips_handler(struct ssi_drvdata *drvdata)
+{
+ struct ssi_fips_handle *fips_handle_ptr =
+ drvdata->fips_handle;
-/*
- * This function returns the REE FIPS error.
- * It should be called by kernel module.
- */
-int ssi_fips_get_error(enum cc_fips_error *p_err)
+ tasklet_schedule(&fips_handle_ptr->tasklet);
+}
+
+static inline void tee_fips_error(void)
{
- int rc = 0;
+ if (fips_enabled)
+ panic("ccree: TEE reported cryptographic error in fips mode!\n");
+ else
+ SSI_LOG_ERR("TEE reported error!\n");
+}
- if (!p_err)
- return -EINVAL;
+/* Deferred service handler, run as interrupt-fired tasklet */
+static void fips_dsr(unsigned long devarg)
+{
+ struct ssi_drvdata *drvdata = (struct ssi_drvdata *)devarg;
+ void __iomem *cc_base = drvdata->cc_base;
+ u32 irq, state, val;
- rc = ssi_fips_ext_get_error(p_err);
+ irq = (drvdata->irq & (SSI_GPR0_IRQ_MASK));
- return rc;
+ if (irq) {
+ state = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, GPR_HOST));
+
+ if (state != (CC_FIPS_SYNC_TEE_STATUS | CC_FIPS_SYNC_MODULE_OK))
+ tee_fips_error();
+ }
+
+ /* after verifing that there is nothing to do,
+ * unmask AXI completion interrupt.
+ */
+ val = (CC_REG_OFFSET(HOST_RGF, HOST_IMR) & ~irq);
+ CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR), val);
}
-EXPORT_SYMBOL(ssi_fips_get_error);
+/* The function called once at driver entry point .*/
+int ssi_fips_init(struct ssi_drvdata *p_drvdata)
+{
+ struct ssi_fips_handle *fips_h;
+
+ fips_h = kzalloc(sizeof(*fips_h), GFP_KERNEL);
+ if (!fips_h)
+ return -ENOMEM;
+
+ p_drvdata->fips_handle = fips_h;
+
+ SSI_LOG_DEBUG("Initializing fips tasklet\n");
+ tasklet_init(&fips_h->tasklet, fips_dsr, (unsigned long)p_drvdata);
+
+ if (!cc_get_tee_fips_status(p_drvdata))
+ tee_fips_error();
+
+ return 0;
+}
diff --git a/drivers/staging/ccree/ssi_fips.h b/drivers/staging/ccree/ssi_fips.h
index 4f5c6a9..369ddf9 100644
--- a/drivers/staging/ccree/ssi_fips.h
+++ b/drivers/staging/ccree/ssi_fips.h
@@ -17,45 +17,33 @@
#ifndef __SSI_FIPS_H__
#define __SSI_FIPS_H__
-/*!
- * @file
- * @brief This file contains FIPS related defintions and APIs.
- */
+#ifdef CONFIG_CRYPTO_FIPS
-enum cc_fips_state {
- CC_FIPS_STATE_NOT_SUPPORTED = 0,
- CC_FIPS_STATE_SUPPORTED,
- CC_FIPS_STATE_ERROR,
- CC_FIPS_STATE_RESERVE32B = S32_MAX
+enum cc_fips_status {
+ CC_FIPS_SYNC_MODULE_OK = 0x0,
+ CC_FIPS_SYNC_MODULE_ERROR = 0x1,
+ CC_FIPS_SYNC_REE_STATUS = 0x4,
+ CC_FIPS_SYNC_TEE_STATUS = 0x8,
+ CC_FIPS_SYNC_STATUS_RESERVE32B = S32_MAX
};
-enum cc_fips_error {
- CC_REE_FIPS_ERROR_OK = 0,
- CC_REE_FIPS_ERROR_GENERAL,
- CC_REE_FIPS_ERROR_FROM_TEE,
- CC_REE_FIPS_ERROR_AES_ECB_PUT,
- CC_REE_FIPS_ERROR_AES_CBC_PUT,
- CC_REE_FIPS_ERROR_AES_OFB_PUT,
- CC_REE_FIPS_ERROR_AES_CTR_PUT,
- CC_REE_FIPS_ERROR_AES_CBC_CTS_PUT,
- CC_REE_FIPS_ERROR_AES_XTS_PUT,
- CC_REE_FIPS_ERROR_AES_CMAC_PUT,
- CC_REE_FIPS_ERROR_AESCCM_PUT,
- CC_REE_FIPS_ERROR_AESGCM_PUT,
- CC_REE_FIPS_ERROR_DES_ECB_PUT,
- CC_REE_FIPS_ERROR_DES_CBC_PUT,
- CC_REE_FIPS_ERROR_SHA1_PUT,
- CC_REE_FIPS_ERROR_SHA256_PUT,
- CC_REE_FIPS_ERROR_SHA512_PUT,
- CC_REE_FIPS_ERROR_HMAC_SHA1_PUT,
- CC_REE_FIPS_ERROR_HMAC_SHA256_PUT,
- CC_REE_FIPS_ERROR_HMAC_SHA512_PUT,
- CC_REE_FIPS_ERROR_ROM_CHECKSUM,
- CC_REE_FIPS_ERROR_RESERVE32B = S32_MAX
-};
+int ssi_fips_init(struct ssi_drvdata *p_drvdata);
+void ssi_fips_fini(struct ssi_drvdata *drvdata);
+void fips_handler(struct ssi_drvdata *drvdata);
+void cc_set_ree_fips_status(struct ssi_drvdata *drvdata, bool ok);
+
+#else /* CONFIG_CRYPTO_FIPS */
+
+static inline int ssi_fips_init(struct ssi_drvdata *p_drvdata)
+{
+ return 0;
+}
+
+static inline void ssi_fips_fini(struct ssi_drvdata *drvdata) {}
+void cc_set_ree_fips_status(struct ssi_drvdata *drvdata, bool ok) {}
+void fips_handler(struct ssi_drvdata *drvdata) {}
-int ssi_fips_get_state(enum cc_fips_state *p_state);
-int ssi_fips_get_error(enum cc_fips_error *p_err);
+#endif /* CONFIG_CRYPTO_FIPS */
#endif /*__SSI_FIPS_H__*/
diff --git a/drivers/staging/ccree/ssi_fips_data.h b/drivers/staging/ccree/ssi_fips_data.h
deleted file mode 100644
index c41671d..0000000
--- a/drivers/staging/ccree/ssi_fips_data.h
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Copyright (C) 2012-2017 ARM Limited or its affiliates.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * The test vectors were taken from:
- *
- * * AES
- * NIST Special Publication 800-38A 2001 Edition
- * Recommendation for Block Cipher Modes of Operation
- * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
- * Appendix F: Example Vectors for Modes of Operation of the AES
- *
- * * AES CTS
- * Advanced Encryption Standard (AES) Encryption for Kerberos 5
- * February 2005
- * https://tools.ietf.org/html/rfc3962#appendix-B
- * B. Sample Test Vectors
- *
- * * AES XTS
- * http://csrc.nist.gov/groups/STM/cavp/#08
- * http://csrc.nist.gov/groups/STM/cavp/documents/aes/XTSTestVectors.zip
- *
- * * AES CMAC
- * http://csrc.nist.gov/groups/STM/cavp/index.html#07
- * http://csrc.nist.gov/groups/STM/cavp/documents/mac/cmactestvectors.zip
- *
- * * AES-CCM
- * http://csrc.nist.gov/groups/STM/cavp/#07
- * http://csrc.nist.gov/groups/STM/cavp/documents/mac/ccmtestvectors.zip
- *
- * * AES-GCM
- * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
- *
- * * Triple-DES
- * NIST Special Publication 800-67 January 2012
- * Recommendation for the Triple Data Encryption Algorithm (TDEA) Block Cipher
- * http://csrc.nist.gov/publications/nistpubs/800-67-Rev1/SP-800-67-Rev1.pdf
- * APPENDIX B: EXAMPLE OF TDEA FORWARD AND INVERSE CIPHER OPERATIONS
- * and
- * http://csrc.nist.gov/groups/STM/cavp/#01
- * http://csrc.nist.gov/groups/STM/cavp/documents/des/tdesmct_intermediate.zip
- *
- * * HASH
- * http://csrc.nist.gov/groups/STM/cavp/#03
- * http://csrc.nist.gov/groups/STM/cavp/documents/shs/shabytetestvectors.zip
- *
- * * HMAC
- * http://csrc.nist.gov/groups/STM/cavp/#07
- * http://csrc.nist.gov/groups/STM/cavp/documents/mac/hmactestvectors.zip
- */
-
-/* NIST AES */
-#define AES_128_BIT_KEY_SIZE 16
-#define AES_192_BIT_KEY_SIZE 24
-#define AES_256_BIT_KEY_SIZE 32
-#define AES_512_BIT_KEY_SIZE 64
-
-#define NIST_AES_IV_SIZE 16
-
-#define NIST_AES_128_KEY { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }
-#define NIST_AES_192_KEY { 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, \
- 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b }
-#define NIST_AES_256_KEY { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, \
- 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 }
-#define NIST_AES_VECTOR_SIZE 16
-#define NIST_AES_PLAIN_DATA { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a }
-
-#define NIST_AES_ECB_IV { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
-#define NIST_AES_128_ECB_CIPHER { 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97 }
-#define NIST_AES_192_ECB_CIPHER { 0xbd, 0x33, 0x4f, 0x1d, 0x6e, 0x45, 0xf2, 0x5f, 0xf7, 0x12, 0xa2, 0x14, 0x57, 0x1f, 0xa5, 0xcc }
-#define NIST_AES_256_ECB_CIPHER { 0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c, 0x06, 0x4b, 0x5a, 0x7e, 0x3d, 0xb1, 0x81, 0xf8 }
-
-#define NIST_AES_CBC_IV { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }
-#define NIST_AES_128_CBC_CIPHER { 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d }
-#define NIST_AES_192_CBC_CIPHER { 0x4f, 0x02, 0x1d, 0xb2, 0x43, 0xbc, 0x63, 0x3d, 0x71, 0x78, 0x18, 0x3a, 0x9f, 0xa0, 0x71, 0xe8 }
-#define NIST_AES_256_CBC_CIPHER { 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba, 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6 }
-
-#define NIST_AES_OFB_IV { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }
-#define NIST_AES_128_OFB_CIPHER { 0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20, 0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a }
-#define NIST_AES_192_OFB_CIPHER { 0xcd, 0xc8, 0x0d, 0x6f, 0xdd, 0xf1, 0x8c, 0xab, 0x34, 0xc2, 0x59, 0x09, 0xc9, 0x9a, 0x41, 0x74 }
-#define NIST_AES_256_OFB_CIPHER { 0xdc, 0x7e, 0x84, 0xbf, 0xda, 0x79, 0x16, 0x4b, 0x7e, 0xcd, 0x84, 0x86, 0x98, 0x5d, 0x38, 0x60 }
-
-#define NIST_AES_CTR_IV { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }
-#define NIST_AES_128_CTR_CIPHER { 0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26, 0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce }
-#define NIST_AES_192_CTR_CIPHER { 0x1a, 0xbc, 0x93, 0x24, 0x17, 0x52, 0x1c, 0xa2, 0x4f, 0x2b, 0x04, 0x59, 0xfe, 0x7e, 0x6e, 0x0b }
-#define NIST_AES_256_CTR_CIPHER { 0x60, 0x1e, 0xc3, 0x13, 0x77, 0x57, 0x89, 0xa5, 0xb7, 0xa7, 0xf5, 0x04, 0xbb, 0xf3, 0xd2, 0x28 }
-
-#define RFC3962_AES_128_KEY { 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20, 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69 }
-#define RFC3962_AES_VECTOR_SIZE 17
-#define RFC3962_AES_PLAIN_DATA { 0x49, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20 }
-#define RFC3962_AES_CBC_CTS_IV { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
-#define RFC3962_AES_128_CBC_CTS_CIPHER { 0xc6, 0x35, 0x35, 0x68, 0xf2, 0xbf, 0x8c, 0xb4, 0xd8, 0xa5, 0x80, 0x36, 0x2d, 0xa7, 0xff, 0x7f, 0x97 }
-
-#define NIST_AES_256_XTS_KEY { 0xa1, 0xb9, 0x0c, 0xba, 0x3f, 0x06, 0xac, 0x35, 0x3b, 0x2c, 0x34, 0x38, 0x76, 0x08, 0x17, 0x62, \
- 0x09, 0x09, 0x23, 0x02, 0x6e, 0x91, 0x77, 0x18, 0x15, 0xf2, 0x9d, 0xab, 0x01, 0x93, 0x2f, 0x2f }
-#define NIST_AES_256_XTS_IV { 0x4f, 0xae, 0xf7, 0x11, 0x7c, 0xda, 0x59, 0xc6, 0x6e, 0x4b, 0x92, 0x01, 0x3e, 0x76, 0x8a, 0xd5 }
-#define NIST_AES_256_XTS_VECTOR_SIZE 16
-#define NIST_AES_256_XTS_PLAIN { 0xeb, 0xab, 0xce, 0x95, 0xb1, 0x4d, 0x3c, 0x8d, 0x6f, 0xb3, 0x50, 0x39, 0x07, 0x90, 0x31, 0x1c }
-#define NIST_AES_256_XTS_CIPHER { 0x77, 0x8a, 0xe8, 0xb4, 0x3c, 0xb9, 0x8d, 0x5a, 0x82, 0x50, 0x81, 0xd5, 0xbe, 0x47, 0x1c, 0x63 }
-
-#define NIST_AES_512_XTS_KEY { 0x1e, 0xa6, 0x61, 0xc5, 0x8d, 0x94, 0x3a, 0x0e, 0x48, 0x01, 0xe4, 0x2f, 0x4b, 0x09, 0x47, 0x14, \
- 0x9e, 0x7f, 0x9f, 0x8e, 0x3e, 0x68, 0xd0, 0xc7, 0x50, 0x52, 0x10, 0xbd, 0x31, 0x1a, 0x0e, 0x7c, \
- 0xd6, 0xe1, 0x3f, 0xfd, 0xf2, 0x41, 0x8d, 0x8d, 0x19, 0x11, 0xc0, 0x04, 0xcd, 0xa5, 0x8d, 0xa3, \
- 0xd6, 0x19, 0xb7, 0xe2, 0xb9, 0x14, 0x1e, 0x58, 0x31, 0x8e, 0xea, 0x39, 0x2c, 0xf4, 0x1b, 0x08 }
-#define NIST_AES_512_XTS_IV { 0xad, 0xf8, 0xd9, 0x26, 0x27, 0x46, 0x4a, 0xd2, 0xf0, 0x42, 0x8e, 0x84, 0xa9, 0xf8, 0x75, 0x64, }
-#define NIST_AES_512_XTS_VECTOR_SIZE 32
-#define NIST_AES_512_XTS_PLAIN { 0x2e, 0xed, 0xea, 0x52, 0xcd, 0x82, 0x15, 0xe1, 0xac, 0xc6, 0x47, 0xe8, 0x10, 0xbb, 0xc3, 0x64, \
- 0x2e, 0x87, 0x28, 0x7f, 0x8d, 0x2e, 0x57, 0xe3, 0x6c, 0x0a, 0x24, 0xfb, 0xc1, 0x2a, 0x20, 0x2e }
-#define NIST_AES_512_XTS_CIPHER { 0xcb, 0xaa, 0xd0, 0xe2, 0xf6, 0xce, 0xa3, 0xf5, 0x0b, 0x37, 0xf9, 0x34, 0xd4, 0x6a, 0x9b, 0x13, \
- 0x0b, 0x9d, 0x54, 0xf0, 0x7e, 0x34, 0xf3, 0x6a, 0xf7, 0x93, 0xe8, 0x6f, 0x73, 0xc6, 0xd7, 0xdb }
-
-/* NIST AES-CMAC */
-#define NIST_AES_128_CMAC_KEY { 0x67, 0x08, 0xc9, 0x88, 0x7b, 0x84, 0x70, 0x84, 0xf1, 0x23, 0xd3, 0xdd, 0x9c, 0x3a, 0x81, 0x36 }
-#define NIST_AES_128_CMAC_PLAIN_DATA { 0xa8, 0xde, 0x55, 0x17, 0x0c, 0x6d, 0xc0, 0xd8, 0x0d, 0xe3, 0x2f, 0x50, 0x8b, 0xf4, 0x9b, 0x70 }
-#define NIST_AES_128_CMAC_MAC { 0xcf, 0xef, 0x9b, 0x78, 0x39, 0x84, 0x1f, 0xdb, 0xcc, 0xbb, 0x6c, 0x2c, 0xf2, 0x38, 0xf7 }
-#define NIST_AES_128_CMAC_VECTOR_SIZE 16
-#define NIST_AES_128_CMAC_OUTPUT_SIZE 15
-
-#define NIST_AES_192_CMAC_KEY { 0x20, 0x51, 0xaf, 0x34, 0x76, 0x2e, 0xbe, 0x55, 0x6f, 0x72, 0xa5, 0xc6, 0xed, 0xc7, 0x77, 0x1e, \
- 0xb9, 0x24, 0x5f, 0xad, 0x76, 0xf0, 0x34, 0xbe }
-#define NIST_AES_192_CMAC_PLAIN_DATA { 0xae, 0x8e, 0x93, 0xc9, 0xc9, 0x91, 0xcf, 0x89, 0x6a, 0x49, 0x1a, 0x89, 0x07, 0xdf, 0x4e, 0x4b, \
- 0xe5, 0x18, 0x6a, 0xe4, 0x96, 0xcd, 0x34, 0x0d, 0xc1, 0x9b, 0x23, 0x78, 0x21, 0xdb, 0x7b, 0x60 }
-#define NIST_AES_192_CMAC_MAC { 0x74, 0xf7, 0x46, 0x08, 0xc0, 0x4f, 0x0f, 0x4e, 0x47, 0xfa, 0x64, 0x04, 0x33, 0xb6, 0xe6, 0xfb }
-#define NIST_AES_192_CMAC_VECTOR_SIZE 32
-#define NIST_AES_192_CMAC_OUTPUT_SIZE 16
-
-#define NIST_AES_256_CMAC_KEY { 0x3a, 0x75, 0xa9, 0xd2, 0xbd, 0xb8, 0xc8, 0x04, 0xba, 0x4a, 0xb4, 0x98, 0x35, 0x73, 0xa6, 0xb2, \
- 0x53, 0x16, 0x0d, 0xd9, 0x0f, 0x8e, 0xdd, 0xfb, 0x2f, 0xdc, 0x2a, 0xb1, 0x76, 0x04, 0xf5, 0xc5 }
-#define NIST_AES_256_CMAC_PLAIN_DATA { 0x42, 0xf3, 0x5d, 0x5a, 0xa5, 0x33, 0xa7, 0xa0, 0xa5, 0xf7, 0x4e, 0x14, 0x4f, 0x2a, 0x5f, 0x20 }
-#define NIST_AES_256_CMAC_MAC { 0xf1, 0x53, 0x2f, 0x87, 0x32, 0xd9, 0xf5, 0x90, 0x30, 0x07 }
-#define NIST_AES_256_CMAC_VECTOR_SIZE 16
-#define NIST_AES_256_CMAC_OUTPUT_SIZE 10
-
-/* NIST TDES */
-#define TDES_NUM_OF_KEYS 3
-#define NIST_TDES_VECTOR_SIZE 8
-#define NIST_TDES_IV_SIZE 8
-
-#define NIST_TDES_ECB_IV { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
-
-#define NIST_TDES_ECB3_KEY { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, \
- 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, \
- 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23 }
-#define NIST_TDES_ECB3_PLAIN_DATA { 0x54, 0x68, 0x65, 0x20, 0x71, 0x75, 0x66, 0x63 }
-#define NIST_TDES_ECB3_CIPHER { 0xa8, 0x26, 0xfd, 0x8c, 0xe5, 0x3b, 0x85, 0x5f }
-
-#define NIST_TDES_CBC3_IV { 0xf8, 0xee, 0xe1, 0x35, 0x9c, 0x6e, 0x54, 0x40 }
-#define NIST_TDES_CBC3_KEY { 0xe9, 0xda, 0x37, 0xf8, 0xdc, 0x97, 0x6d, 0x5b, \
- 0xb6, 0x8c, 0x04, 0xe3, 0xec, 0x98, 0x20, 0x15, \
- 0xf4, 0x0e, 0x08, 0xb5, 0x97, 0x29, 0xf2, 0x8f }
-#define NIST_TDES_CBC3_PLAIN_DATA { 0x3b, 0xb7, 0xa7, 0xdb, 0xa3, 0xd5, 0x92, 0x91 }
-#define NIST_TDES_CBC3_CIPHER { 0x5b, 0x84, 0x24, 0xd2, 0x39, 0x3e, 0x55, 0xa2 }
-
-/* NIST AES-CCM */
-#define NIST_AESCCM_128_BIT_KEY_SIZE 16
-#define NIST_AESCCM_192_BIT_KEY_SIZE 24
-#define NIST_AESCCM_256_BIT_KEY_SIZE 32
-
-#define NIST_AESCCM_B0_VAL 0x79 /* L'[0:2]=1 , M'[3-5]=7 , Adata[6]=1, reserved[7]=0 */
-#define NIST_AESCCM_NONCE_SIZE 13
-#define NIST_AESCCM_IV_SIZE 16
-#define NIST_AESCCM_ADATA_SIZE 32
-#define NIST_AESCCM_TEXT_SIZE 16
-#define NIST_AESCCM_TAG_SIZE 16
-
-#define NIST_AESCCM_128_KEY { 0x70, 0x01, 0x0e, 0xd9, 0x0e, 0x61, 0x86, 0xec, 0xad, 0x41, 0xf0, 0xd3, 0xc7, 0xc4, 0x2f, 0xf8 }
-#define NIST_AESCCM_128_NONCE { 0xa5, 0xf4, 0xf4, 0x98, 0x6e, 0x98, 0x47, 0x29, 0x65, 0xf5, 0xab, 0xcc, 0x4b }
-#define NIST_AESCCM_128_ADATA { 0x3f, 0xec, 0x0e, 0x5c, 0xc2, 0x4d, 0x67, 0x13, 0x94, 0x37, 0xcb, 0xc8, 0x11, 0x24, 0x14, 0xfc, \
- 0x8d, 0xac, 0xcd, 0x1a, 0x94, 0xb4, 0x9a, 0x4c, 0x76, 0xe2, 0xd3, 0x93, 0x03, 0x54, 0x73, 0x17 }
-#define NIST_AESCCM_128_PLAIN_TEXT { 0xbe, 0x32, 0x2f, 0x58, 0xef, 0xa7, 0xf8, 0xc6, 0x8a, 0x63, 0x5e, 0x0b, 0x9c, 0xce, 0x77, 0xf2 }
-#define NIST_AESCCM_128_CIPHER { 0x8e, 0x44, 0x25, 0xae, 0x57, 0x39, 0x74, 0xf0, 0xf0, 0x69, 0x3a, 0x18, 0x8b, 0x52, 0x58, 0x12 }
-#define NIST_AESCCM_128_MAC { 0xee, 0xf0, 0x8e, 0x3f, 0xb1, 0x5f, 0x42, 0x27, 0xe0, 0xd9, 0x89, 0xa4, 0xd5, 0x87, 0xa8, 0xcf }
-
-#define NIST_AESCCM_192_KEY { 0x68, 0x73, 0xf1, 0xc6, 0xc3, 0x09, 0x75, 0xaf, 0xf6, 0xf0, 0x84, 0x70, 0x26, 0x43, 0x21, 0x13, \
- 0x0a, 0x6e, 0x59, 0x84, 0xad, 0xe3, 0x24, 0xe9 }
-#define NIST_AESCCM_192_NONCE { 0x7c, 0x4d, 0x2f, 0x7c, 0xec, 0x04, 0x36, 0x1f, 0x18, 0x7f, 0x07, 0x26, 0xd5 }
-#define NIST_AESCCM_192_ADATA { 0x77, 0x74, 0x3b, 0x5d, 0x83, 0xa0, 0x0d, 0x2c, 0x8d, 0x5f, 0x7e, 0x10, 0x78, 0x15, 0x31, 0xb4, \
- 0x96, 0xe0, 0x9f, 0x3b, 0xc9, 0x29, 0x5d, 0x7a, 0xe9, 0x79, 0x9e, 0x64, 0x66, 0x8e, 0xf8, 0xc5 }
-#define NIST_AESCCM_192_PLAIN_TEXT { 0x50, 0x51, 0xa0, 0xb0, 0xb6, 0x76, 0x6c, 0xd6, 0xea, 0x29, 0xa6, 0x72, 0x76, 0x9d, 0x40, 0xfe }
-#define NIST_AESCCM_192_CIPHER { 0x0c, 0xe5, 0xac, 0x8d, 0x6b, 0x25, 0x6f, 0xb7, 0x58, 0x0b, 0xf6, 0xac, 0xc7, 0x64, 0x26, 0xaf }
-#define NIST_AESCCM_192_MAC { 0x40, 0xbc, 0xe5, 0x8f, 0xd4, 0xcd, 0x65, 0x48, 0xdf, 0x90, 0xa0, 0x33, 0x7c, 0x84, 0x20, 0x04 }
-
-#define NIST_AESCCM_256_KEY { 0xee, 0x8c, 0xe1, 0x87, 0x16, 0x97, 0x79, 0xd1, 0x3e, 0x44, 0x3d, 0x64, 0x28, 0xe3, 0x8b, 0x38, \
- 0xb5, 0x5d, 0xfb, 0x90, 0xf0, 0x22, 0x8a, 0x8a, 0x4e, 0x62, 0xf8, 0xf5, 0x35, 0x80, 0x6e, 0x62 }
-#define NIST_AESCCM_256_NONCE { 0x12, 0x16, 0x42, 0xc4, 0x21, 0x8b, 0x39, 0x1c, 0x98, 0xe6, 0x26, 0x9c, 0x8a }
-#define NIST_AESCCM_256_ADATA { 0x71, 0x8d, 0x13, 0xe4, 0x75, 0x22, 0xac, 0x4c, 0xdf, 0x3f, 0x82, 0x80, 0x63, 0x98, 0x0b, 0x6d, \
- 0x45, 0x2f, 0xcd, 0xcd, 0x6e, 0x1a, 0x19, 0x04, 0xbf, 0x87, 0xf5, 0x48, 0xa5, 0xfd, 0x5a, 0x05 }
-#define NIST_AESCCM_256_PLAIN_TEXT { 0xd1, 0x5f, 0x98, 0xf2, 0xc6, 0xd6, 0x70, 0xf5, 0x5c, 0x78, 0xa0, 0x66, 0x48, 0x33, 0x2b, 0xc9 }
-#define NIST_AESCCM_256_CIPHER { 0xcc, 0x17, 0xbf, 0x87, 0x94, 0xc8, 0x43, 0x45, 0x7d, 0x89, 0x93, 0x91, 0x89, 0x8e, 0xd2, 0x2a }
-#define NIST_AESCCM_256_MAC { 0x6f, 0x9d, 0x28, 0xfc, 0xb6, 0x42, 0x34, 0xe1, 0xcd, 0x79, 0x3c, 0x41, 0x44, 0xf1, 0xda, 0x50 }
-
-/* NIST AES-GCM */
-#define NIST_AESGCM_128_BIT_KEY_SIZE 16
-#define NIST_AESGCM_192_BIT_KEY_SIZE 24
-#define NIST_AESGCM_256_BIT_KEY_SIZE 32
-
-#define NIST_AESGCM_IV_SIZE 12
-#define NIST_AESGCM_ADATA_SIZE 16
-#define NIST_AESGCM_TEXT_SIZE 16
-#define NIST_AESGCM_TAG_SIZE 16
-
-#define NIST_AESGCM_128_KEY { 0x81, 0x6e, 0x39, 0x07, 0x04, 0x10, 0xcf, 0x21, 0x84, 0x90, 0x4d, 0xa0, 0x3e, 0xa5, 0x07, 0x5a }
-#define NIST_AESGCM_128_IV { 0x32, 0xc3, 0x67, 0xa3, 0x36, 0x26, 0x13, 0xb2, 0x7f, 0xc3, 0xe6, 0x7e }
-#define NIST_AESGCM_128_ADATA { 0xf2, 0xa3, 0x07, 0x28, 0xed, 0x87, 0x4e, 0xe0, 0x29, 0x83, 0xc2, 0x94, 0x43, 0x5d, 0x3c, 0x16 }
-#define NIST_AESGCM_128_PLAIN_TEXT { 0xec, 0xaf, 0xe9, 0x6c, 0x67, 0xa1, 0x64, 0x67, 0x44, 0xf1, 0xc8, 0x91, 0xf5, 0xe6, 0x94, 0x27 }
-#define NIST_AESGCM_128_CIPHER { 0x55, 0x2e, 0xbe, 0x01, 0x2e, 0x7b, 0xcf, 0x90, 0xfc, 0xef, 0x71, 0x2f, 0x83, 0x44, 0xe8, 0xf1 }
-#define NIST_AESGCM_128_MAC { 0xec, 0xaa, 0xe9, 0xfc, 0x68, 0x27, 0x6a, 0x45, 0xab, 0x0c, 0xa3, 0xcb, 0x9d, 0xd9, 0x53, 0x9f }
-
-#define NIST_AESGCM_192_KEY { 0x0c, 0x44, 0xd6, 0xc9, 0x28, 0xee, 0x11, 0x2c, 0xe6, 0x65, 0xfe, 0x54, 0x7e, 0xbd, 0x38, 0x72, \
- 0x98, 0xa9, 0x54, 0xb4, 0x62, 0xf6, 0x95, 0xd8 }
-#define NIST_AESGCM_192_IV { 0x18, 0xb8, 0xf3, 0x20, 0xfe, 0xf4, 0xae, 0x8c, 0xcb, 0xe8, 0xf9, 0x52 }
-#define NIST_AESGCM_192_ADATA { 0x73, 0x41, 0xd4, 0x3f, 0x98, 0xcf, 0x38, 0x82, 0x21, 0x18, 0x09, 0x41, 0x97, 0x03, 0x76, 0xe8 }
-#define NIST_AESGCM_192_PLAIN_TEXT { 0x96, 0xad, 0x07, 0xf9, 0xb6, 0x28, 0xb6, 0x52, 0xcf, 0x86, 0xcb, 0x73, 0x17, 0x88, 0x6f, 0x51 }
-#define NIST_AESGCM_192_CIPHER { 0xa6, 0x64, 0x07, 0x81, 0x33, 0x40, 0x5e, 0xb9, 0x09, 0x4d, 0x36, 0xf7, 0xe0, 0x70, 0x19, 0x1f }
-#define NIST_AESGCM_192_MAC { 0xe8, 0xf9, 0xc3, 0x17, 0x84, 0x7c, 0xe3, 0xf3, 0xc2, 0x39, 0x94, 0xa4, 0x02, 0xf0, 0x65, 0x81 }
-
-#define NIST_AESGCM_256_KEY { 0x54, 0xe3, 0x52, 0xea, 0x1d, 0x84, 0xbf, 0xe6, 0x4a, 0x10, 0x11, 0x09, 0x61, 0x11, 0xfb, 0xe7, \
- 0x66, 0x8a, 0xd2, 0x20, 0x3d, 0x90, 0x2a, 0x01, 0x45, 0x8c, 0x3b, 0xbd, 0x85, 0xbf, 0xce, 0x14 }
-#define NIST_AESGCM_256_IV { 0xdf, 0x7c, 0x3b, 0xca, 0x00, 0x39, 0x6d, 0x0c, 0x01, 0x84, 0x95, 0xd9 }
-#define NIST_AESGCM_256_ADATA { 0x7e, 0x96, 0x8d, 0x71, 0xb5, 0x0c, 0x1f, 0x11, 0xfd, 0x00, 0x1f, 0x3f, 0xef, 0x49, 0xd0, 0x45 }
-#define NIST_AESGCM_256_PLAIN_TEXT { 0x85, 0xfc, 0x3d, 0xfa, 0xd9, 0xb5, 0xa8, 0xd3, 0x25, 0x8e, 0x4f, 0xc4, 0x45, 0x71, 0xbd, 0x3b }
-#define NIST_AESGCM_256_CIPHER { 0x42, 0x6e, 0x0e, 0xfc, 0x69, 0x3b, 0x7b, 0xe1, 0xf3, 0x01, 0x8d, 0xb7, 0xdd, 0xbb, 0x7e, 0x4d }
-#define NIST_AESGCM_256_MAC { 0xee, 0x82, 0x57, 0x79, 0x5b, 0xe6, 0xa1, 0x16, 0x4d, 0x7e, 0x1d, 0x2d, 0x6c, 0xac, 0x77, 0xa7 }
-
-/* NIST HASH */
-#define NIST_SHA_MSG_SIZE 16
-
-#define NIST_SHA_1_MSG { 0x35, 0x52, 0x69, 0x4c, 0xdf, 0x66, 0x3f, 0xd9, 0x4b, 0x22, 0x47, 0x47, 0xac, 0x40, 0x6a, 0xaf }
-#define NIST_SHA_1_MD { 0xa1, 0x50, 0xde, 0x92, 0x74, 0x54, 0x20, 0x2d, 0x94, 0xe6, 0x56, 0xde, 0x4c, 0x7c, 0x0c, 0xa6, \
- 0x91, 0xde, 0x95, 0x5d }
-
-#define NIST_SHA_256_MSG { 0x0a, 0x27, 0x84, 0x7c, 0xdc, 0x98, 0xbd, 0x6f, 0x62, 0x22, 0x0b, 0x04, 0x6e, 0xdd, 0x76, 0x2b }
-#define NIST_SHA_256_MD { 0x80, 0xc2, 0x5e, 0xc1, 0x60, 0x05, 0x87, 0xe7, 0xf2, 0x8b, 0x18, 0xb1, 0xb1, 0x8e, 0x3c, 0xdc, \
- 0x89, 0x92, 0x8e, 0x39, 0xca, 0xb3, 0xbc, 0x25, 0xe4, 0xd4, 0xa4, 0xc1, 0x39, 0xbc, 0xed, 0xc4 }
-
-#define NIST_SHA_512_MSG { 0xcd, 0x67, 0xbd, 0x40, 0x54, 0xaa, 0xa3, 0xba, 0xa0, 0xdb, 0x17, 0x8c, 0xe2, 0x32, 0xfd, 0x5a }
-#define NIST_SHA_512_MD { 0x0d, 0x85, 0x21, 0xf8, 0xf2, 0xf3, 0x90, 0x03, 0x32, 0xd1, 0xa1, 0xa5, 0x5c, 0x60, 0xba, 0x81, \
- 0xd0, 0x4d, 0x28, 0xdf, 0xe8, 0xc5, 0x04, 0xb6, 0x32, 0x8a, 0xe7, 0x87, 0x92, 0x5f, 0xe0, 0x18, \
- 0x8f, 0x2b, 0xa9, 0x1c, 0x3a, 0x9f, 0x0c, 0x16, 0x53, 0xc4, 0xbf, 0x0a, 0xda, 0x35, 0x64, 0x55, \
- 0xea, 0x36, 0xfd, 0x31, 0xf8, 0xe7, 0x3e, 0x39, 0x51, 0xca, 0xd4, 0xeb, 0xba, 0x8c, 0x6e, 0x04 }
-
-/* NIST HMAC */
-#define NIST_HMAC_MSG_SIZE 128
-
-#define NIST_HMAC_SHA1_KEY_SIZE 10
-#define NIST_HMAC_SHA1_KEY { 0x59, 0x78, 0x59, 0x28, 0xd7, 0x25, 0x16, 0xe3, 0x12, 0x72 }
-#define NIST_HMAC_SHA1_MSG { 0xa3, 0xce, 0x88, 0x99, 0xdf, 0x10, 0x22, 0xe8, 0xd2, 0xd5, 0x39, 0xb4, 0x7b, 0xf0, 0xe3, 0x09, \
- 0xc6, 0x6f, 0x84, 0x09, 0x5e, 0x21, 0x43, 0x8e, 0xc3, 0x55, 0xbf, 0x11, 0x9c, 0xe5, 0xfd, 0xcb, \
- 0x4e, 0x73, 0xa6, 0x19, 0xcd, 0xf3, 0x6f, 0x25, 0xb3, 0x69, 0xd8, 0xc3, 0x8f, 0xf4, 0x19, 0x99, \
- 0x7f, 0x0c, 0x59, 0x83, 0x01, 0x08, 0x22, 0x36, 0x06, 0xe3, 0x12, 0x23, 0x48, 0x3f, 0xd3, 0x9e, \
- 0xde, 0xaa, 0x4d, 0x3f, 0x0d, 0x21, 0x19, 0x88, 0x62, 0xd2, 0x39, 0xc9, 0xfd, 0x26, 0x07, 0x41, \
- 0x30, 0xff, 0x6c, 0x86, 0x49, 0x3f, 0x52, 0x27, 0xab, 0x89, 0x5c, 0x8f, 0x24, 0x4b, 0xd4, 0x2c, \
- 0x7a, 0xfc, 0xe5, 0xd1, 0x47, 0xa2, 0x0a, 0x59, 0x07, 0x98, 0xc6, 0x8e, 0x70, 0x8e, 0x96, 0x49, \
- 0x02, 0xd1, 0x24, 0xda, 0xde, 0xcd, 0xbd, 0xa9, 0xdb, 0xd0, 0x05, 0x1e, 0xd7, 0x10, 0xe9, 0xbf }
-#define NIST_HMAC_SHA1_MD { 0x3c, 0x81, 0x62, 0x58, 0x9a, 0xaf, 0xae, 0xe0, 0x24, 0xfc, 0x9a, 0x5c, 0xa5, 0x0d, 0xd2, 0x33, \
- 0x6f, 0xe3, 0xeb, 0x28 }
-
-#define NIST_HMAC_SHA256_KEY_SIZE 40
-#define NIST_HMAC_SHA256_KEY { 0x97, 0x79, 0xd9, 0x12, 0x06, 0x42, 0x79, 0x7f, 0x17, 0x47, 0x02, 0x5d, 0x5b, 0x22, 0xb7, 0xac, \
- 0x60, 0x7c, 0xab, 0x08, 0xe1, 0x75, 0x8f, 0x2f, 0x3a, 0x46, 0xc8, 0xbe, 0x1e, 0x25, 0xc5, 0x3b, \
- 0x8c, 0x6a, 0x8f, 0x58, 0xff, 0xef, 0xa1, 0x76 }
-#define NIST_HMAC_SHA256_MSG { 0xb1, 0x68, 0x9c, 0x25, 0x91, 0xea, 0xf3, 0xc9, 0xe6, 0x60, 0x70, 0xf8, 0xa7, 0x79, 0x54, 0xff, \
- 0xb8, 0x17, 0x49, 0xf1, 0xb0, 0x03, 0x46, 0xf9, 0xdf, 0xe0, 0xb2, 0xee, 0x90, 0x5d, 0xcc, 0x28, \
- 0x8b, 0xaf, 0x4a, 0x92, 0xde, 0x3f, 0x40, 0x01, 0xdd, 0x9f, 0x44, 0xc4, 0x68, 0xc3, 0xd0, 0x7d, \
- 0x6c, 0x6e, 0xe8, 0x2f, 0xac, 0xea, 0xfc, 0x97, 0xc2, 0xfc, 0x0f, 0xc0, 0x60, 0x17, 0x19, 0xd2, \
- 0xdc, 0xd0, 0xaa, 0x2a, 0xec, 0x92, 0xd1, 0xb0, 0xae, 0x93, 0x3c, 0x65, 0xeb, 0x06, 0xa0, 0x3c, \
- 0x9c, 0x93, 0x5c, 0x2b, 0xad, 0x04, 0x59, 0x81, 0x02, 0x41, 0x34, 0x7a, 0xb8, 0x7e, 0x9f, 0x11, \
- 0xad, 0xb3, 0x04, 0x15, 0x42, 0x4c, 0x6c, 0x7f, 0x5f, 0x22, 0xa0, 0x03, 0xb8, 0xab, 0x8d, 0xe5, \
- 0x4f, 0x6d, 0xed, 0x0e, 0x3a, 0xb9, 0x24, 0x5f, 0xa7, 0x95, 0x68, 0x45, 0x1d, 0xfa, 0x25, 0x8e }
-#define NIST_HMAC_SHA256_MD { 0x76, 0x9f, 0x00, 0xd3, 0xe6, 0xa6, 0xcc, 0x1f, 0xb4, 0x26, 0xa1, 0x4a, 0x4f, 0x76, 0xc6, 0x46, \
- 0x2e, 0x61, 0x49, 0x72, 0x6e, 0x0d, 0xee, 0x0e, 0xc0, 0xcf, 0x97, 0xa1, 0x66, 0x05, 0xac, 0x8b }
-
-#define NIST_HMAC_SHA512_KEY_SIZE 100
-#define NIST_HMAC_SHA512_KEY { 0x57, 0xc2, 0xeb, 0x67, 0x7b, 0x50, 0x93, 0xb9, 0xe8, 0x29, 0xea, 0x4b, 0xab, 0xb5, 0x0b, 0xde, \
- 0x55, 0xd0, 0xad, 0x59, 0xfe, 0xc3, 0x4a, 0x61, 0x89, 0x73, 0x80, 0x2b, 0x2a, 0xd9, 0xb7, 0x8e, \
- 0x26, 0xb2, 0x04, 0x5d, 0xda, 0x78, 0x4d, 0xf3, 0xff, 0x90, 0xae, 0x0f, 0x2c, 0xc5, 0x1c, 0xe3, \
- 0x9c, 0xf5, 0x48, 0x67, 0x32, 0x0a, 0xc6, 0xf3, 0xba, 0x2c, 0x6f, 0x0d, 0x72, 0x36, 0x04, 0x80, \
- 0xc9, 0x66, 0x14, 0xae, 0x66, 0x58, 0x1f, 0x26, 0x6c, 0x35, 0xfb, 0x79, 0xfd, 0x28, 0x77, 0x4a, \
- 0xfd, 0x11, 0x3f, 0xa5, 0x18, 0x7e, 0xff, 0x92, 0x06, 0xd7, 0xcb, 0xe9, 0x0d, 0xd8, 0xbf, 0x67, \
- 0xc8, 0x44, 0xe2, 0x02 }
-#define NIST_HMAC_SHA512_MSG { 0x24, 0x23, 0xdf, 0xf4, 0x8b, 0x31, 0x2b, 0xe8, 0x64, 0xcb, 0x34, 0x90, 0x64, 0x1f, 0x79, 0x3d, \
- 0x2b, 0x9f, 0xb6, 0x8a, 0x77, 0x63, 0xb8, 0xe2, 0x98, 0xc8, 0x6f, 0x42, 0x24, 0x5e, 0x45, 0x40, \
- 0xeb, 0x01, 0xae, 0x4d, 0x2d, 0x45, 0x00, 0x37, 0x0b, 0x18, 0x86, 0xf2, 0x3c, 0xa2, 0xcf, 0x97, \
- 0x01, 0x70, 0x4c, 0xad, 0x5b, 0xd2, 0x1b, 0xa8, 0x7b, 0x81, 0x1d, 0xaf, 0x7a, 0x85, 0x4e, 0xa2, \
- 0x4a, 0x56, 0x56, 0x5c, 0xed, 0x42, 0x5b, 0x35, 0xe4, 0x0e, 0x1a, 0xcb, 0xeb, 0xe0, 0x36, 0x03, \
- 0xe3, 0x5d, 0xcf, 0x4a, 0x10, 0x0e, 0x57, 0x21, 0x84, 0x08, 0xa1, 0xd8, 0xdb, 0xcc, 0x3b, 0x99, \
- 0x29, 0x6c, 0xfe, 0xa9, 0x31, 0xef, 0xe3, 0xeb, 0xd8, 0xf7, 0x19, 0xa6, 0xd9, 0xa1, 0x54, 0x87, \
- 0xb9, 0xad, 0x67, 0xea, 0xfe, 0xdf, 0x15, 0x55, 0x9c, 0xa4, 0x24, 0x45, 0xb0, 0xf9, 0xb4, 0x2e }
-#define NIST_HMAC_SHA512_MD { 0x33, 0xc5, 0x11, 0xe9, 0xbc, 0x23, 0x07, 0xc6, 0x27, 0x58, 0xdf, 0x61, 0x12, 0x5a, 0x98, 0x0e, \
- 0xe6, 0x4c, 0xef, 0xeb, 0xd9, 0x09, 0x31, 0xcb, 0x91, 0xc1, 0x37, 0x42, 0xd4, 0x71, 0x4c, 0x06, \
- 0xde, 0x40, 0x03, 0xfa, 0xf3, 0xc4, 0x1c, 0x06, 0xae, 0xfc, 0x63, 0x8a, 0xd4, 0x7b, 0x21, 0x90, \
- 0x6e, 0x6b, 0x10, 0x48, 0x16, 0xb7, 0x2d, 0xe6, 0x26, 0x9e, 0x04, 0x5a, 0x1f, 0x44, 0x29, 0xd4 }
-
diff --git a/drivers/staging/ccree/ssi_fips_ext.c b/drivers/staging/ccree/ssi_fips_ext.c
deleted file mode 100644
index e7bf184..0000000
--- a/drivers/staging/ccree/ssi_fips_ext.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2012-2017 ARM Limited or its affiliates.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/**************************************************************
- * This file defines the driver FIPS functions that should be
- * implemented by the driver user. Current implementation is sample code only.
- ***************************************************************/
-
-#include <linux/module.h>
-#include "ssi_fips_local.h"
-#include "ssi_driver.h"
-
-static bool tee_error;
-module_param(tee_error, bool, 0644);
-MODULE_PARM_DESC(tee_error, "Simulate TEE library failure flag: 0 - no error (default), 1 - TEE error occured ");
-
-static enum cc_fips_state_t fips_state = CC_FIPS_STATE_NOT_SUPPORTED;
-static enum cc_fips_error fips_error = CC_REE_FIPS_ERROR_OK;
-
-/*
- * This function returns the FIPS REE state.
- * The function should be implemented by the driver user, depends on where
- * the state value is stored.
- * The reference code uses global variable.
- */
-int ssi_fips_ext_get_state(enum cc_fips_state_t *p_state)
-{
- int rc = 0;
-
- if (!p_state)
- return -EINVAL;
-
- *p_state = fips_state;
-
- return rc;
-}
-
-/*
- * This function returns the FIPS REE error.
- * The function should be implemented by the driver user, depends on where
- * the error value is stored.
- * The reference code uses global variable.
- */
-int ssi_fips_ext_get_error(enum cc_fips_error *p_err)
-{
- int rc = 0;
-
- if (!p_err)
- return -EINVAL;
-
- *p_err = fips_error;
-
- return rc;
-}
-
-/*
- * This function sets the FIPS REE state.
- * The function should be implemented by the driver user, depends on where
- * the state value is stored.
- * The reference code uses global variable.
- */
-int ssi_fips_ext_set_state(enum cc_fips_state_t state)
-{
- fips_state = state;
- return 0;
-}
-
-/*
- * This function sets the FIPS REE error.
- * The function should be implemented by the driver user, depends on where
- * the error value is stored.
- * The reference code uses global variable.
- */
-int ssi_fips_ext_set_error(enum cc_fips_error err)
-{
- fips_error = err;
- return 0;
-}
-
diff --git a/drivers/staging/ccree/ssi_fips_ll.c b/drivers/staging/ccree/ssi_fips_ll.c
deleted file mode 100644
index 3557e20..0000000
--- a/drivers/staging/ccree/ssi_fips_ll.c
+++ /dev/null
@@ -1,1649 +0,0 @@
-/*
- * Copyright (C) 2012-2017 ARM Limited or its affiliates.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/**************************************************************
- * This file defines the driver FIPS Low Level implmentaion functions,
- * that executes the KAT.
- ***************************************************************/
-#include <linux/kernel.h>
-
-#include "ssi_driver.h"
-#include "ssi_fips_local.h"
-#include "ssi_fips_data.h"
-#include "cc_crypto_ctx.h"
-#include "ssi_hash.h"
-#include "ssi_request_mgr.h"
-
-static const u32 digest_len_init[] = {
- 0x00000040, 0x00000000, 0x00000000, 0x00000000 };
-static const u32 sha1_init[] = {
- SHA1_H4, SHA1_H3, SHA1_H2, SHA1_H1, SHA1_H0 };
-static const u32 sha256_init[] = {
- SHA256_H7, SHA256_H6, SHA256_H5, SHA256_H4,
- SHA256_H3, SHA256_H2, SHA256_H1, SHA256_H0 };
-#if (CC_SUPPORT_SHA > 256)
-static const u32 digest_len_sha512_init[] = {
- 0x00000080, 0x00000000, 0x00000000, 0x00000000 };
-static const u64 sha512_init[] = {
- SHA512_H7, SHA512_H6, SHA512_H5, SHA512_H4,
- SHA512_H3, SHA512_H2, SHA512_H1, SHA512_H0 };
-#endif
-
-#define NIST_CIPHER_AES_MAX_VECTOR_SIZE 32
-
-struct fips_cipher_ctx {
- u8 iv[CC_AES_IV_SIZE];
- u8 key[AES_512_BIT_KEY_SIZE];
- u8 din[NIST_CIPHER_AES_MAX_VECTOR_SIZE];
- u8 dout[NIST_CIPHER_AES_MAX_VECTOR_SIZE];
-};
-
-typedef struct _FipsCipherData {
- u8 isAes;
- u8 key[AES_512_BIT_KEY_SIZE];
- size_t keySize;
- u8 iv[CC_AES_IV_SIZE];
- enum drv_crypto_direction direction;
- enum drv_cipher_mode oprMode;
- u8 dataIn[NIST_CIPHER_AES_MAX_VECTOR_SIZE];
- u8 dataOut[NIST_CIPHER_AES_MAX_VECTOR_SIZE];
- size_t dataInSize;
-} FipsCipherData;
-
-struct fips_cmac_ctx {
- u8 key[AES_256_BIT_KEY_SIZE];
- u8 din[NIST_CIPHER_AES_MAX_VECTOR_SIZE];
- u8 mac_res[CC_DIGEST_SIZE_MAX];
-};
-
-typedef struct _FipsCmacData {
- enum drv_crypto_direction direction;
- u8 key[AES_256_BIT_KEY_SIZE];
- size_t key_size;
- u8 data_in[NIST_CIPHER_AES_MAX_VECTOR_SIZE];
- size_t data_in_size;
- u8 mac_res[CC_DIGEST_SIZE_MAX];
- size_t mac_res_size;
-} FipsCmacData;
-
-struct fips_hash_ctx {
- u8 initial_digest[CC_DIGEST_SIZE_MAX];
- u8 din[NIST_SHA_MSG_SIZE];
- u8 mac_res[CC_DIGEST_SIZE_MAX];
-};
-
-typedef struct _FipsHashData {
- enum drv_hash_mode hash_mode;
- u8 data_in[NIST_SHA_MSG_SIZE];
- size_t data_in_size;
- u8 mac_res[CC_DIGEST_SIZE_MAX];
-} FipsHashData;
-
-/* note that the hmac key length must be equal or less than block size (block size is 64 up to sha256 and 128 for sha384/512) */
-struct fips_hmac_ctx {
- u8 initial_digest[CC_DIGEST_SIZE_MAX];
- u8 key[CC_HMAC_BLOCK_SIZE_MAX];
- u8 k0[CC_HMAC_BLOCK_SIZE_MAX];
- u8 digest_bytes_len[HASH_LEN_SIZE];
- u8 tmp_digest[CC_DIGEST_SIZE_MAX];
- u8 din[NIST_HMAC_MSG_SIZE];
- u8 mac_res[CC_DIGEST_SIZE_MAX];
-};
-
-typedef struct _FipsHmacData {
- enum drv_hash_mode hash_mode;
- u8 key[CC_HMAC_BLOCK_SIZE_MAX];
- size_t key_size;
- u8 data_in[NIST_HMAC_MSG_SIZE];
- size_t data_in_size;
- u8 mac_res[CC_DIGEST_SIZE_MAX];
-} FipsHmacData;
-
-#define FIPS_CCM_B0_A0_ADATA_SIZE (NIST_AESCCM_IV_SIZE + NIST_AESCCM_IV_SIZE + NIST_AESCCM_ADATA_SIZE)
-
-struct fips_ccm_ctx {
- u8 b0_a0_adata[FIPS_CCM_B0_A0_ADATA_SIZE];
- u8 iv[NIST_AESCCM_IV_SIZE];
- u8 ctr_cnt_0[NIST_AESCCM_IV_SIZE];
- u8 key[CC_AES_KEY_SIZE_MAX];
- u8 din[NIST_AESCCM_TEXT_SIZE];
- u8 dout[NIST_AESCCM_TEXT_SIZE];
- u8 mac_res[NIST_AESCCM_TAG_SIZE];
-};
-
-typedef struct _FipsCcmData {
- enum drv_crypto_direction direction;
- u8 key[CC_AES_KEY_SIZE_MAX];
- size_t keySize;
- u8 nonce[NIST_AESCCM_NONCE_SIZE];
- u8 adata[NIST_AESCCM_ADATA_SIZE];
- size_t adataSize;
- u8 dataIn[NIST_AESCCM_TEXT_SIZE];
- size_t dataInSize;
- u8 dataOut[NIST_AESCCM_TEXT_SIZE];
- u8 tagSize;
- u8 macResOut[NIST_AESCCM_TAG_SIZE];
-} FipsCcmData;
-
-struct fips_gcm_ctx {
- u8 adata[NIST_AESGCM_ADATA_SIZE];
- u8 key[CC_AES_KEY_SIZE_MAX];
- u8 hkey[CC_AES_KEY_SIZE_MAX];
- u8 din[NIST_AESGCM_TEXT_SIZE];
- u8 dout[NIST_AESGCM_TEXT_SIZE];
- u8 mac_res[NIST_AESGCM_TAG_SIZE];
- u8 len_block[AES_BLOCK_SIZE];
- u8 iv_inc1[AES_BLOCK_SIZE];
- u8 iv_inc2[AES_BLOCK_SIZE];
-};
-
-typedef struct _FipsGcmData {
- enum drv_crypto_direction direction;
- u8 key[CC_AES_KEY_SIZE_MAX];
- size_t keySize;
- u8 iv[NIST_AESGCM_IV_SIZE];
- u8 adata[NIST_AESGCM_ADATA_SIZE];
- size_t adataSize;
- u8 dataIn[NIST_AESGCM_TEXT_SIZE];
- size_t dataInSize;
- u8 dataOut[NIST_AESGCM_TEXT_SIZE];
- u8 tagSize;
- u8 macResOut[NIST_AESGCM_TAG_SIZE];
-} FipsGcmData;
-
-typedef union _fips_ctx {
- struct fips_cipher_ctx cipher;
- struct fips_cmac_ctx cmac;
- struct fips_hash_ctx hash;
- struct fips_hmac_ctx hmac;
- struct fips_ccm_ctx ccm;
- struct fips_gcm_ctx gcm;
-} fips_ctx;
-
-/* test data tables */
-static const FipsCipherData FipsCipherDataTable[] = {
- /* AES */
- { 1, NIST_AES_128_KEY, CC_AES_128_BIT_KEY_SIZE, NIST_AES_ECB_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_ECB, NIST_AES_PLAIN_DATA, NIST_AES_128_ECB_CIPHER, NIST_AES_VECTOR_SIZE },
- { 1, NIST_AES_128_KEY, CC_AES_128_BIT_KEY_SIZE, NIST_AES_ECB_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_ECB, NIST_AES_128_ECB_CIPHER, NIST_AES_PLAIN_DATA, NIST_AES_VECTOR_SIZE },
- { 1, NIST_AES_192_KEY, CC_AES_192_BIT_KEY_SIZE, NIST_AES_ECB_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_ECB, NIST_AES_PLAIN_DATA, NIST_AES_192_ECB_CIPHER, NIST_AES_VECTOR_SIZE },
- { 1, NIST_AES_192_KEY, CC_AES_192_BIT_KEY_SIZE, NIST_AES_ECB_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_ECB, NIST_AES_192_ECB_CIPHER, NIST_AES_PLAIN_DATA, NIST_AES_VECTOR_SIZE },
- { 1, NIST_AES_256_KEY, CC_AES_256_BIT_KEY_SIZE, NIST_AES_ECB_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_ECB, NIST_AES_PLAIN_DATA, NIST_AES_256_ECB_CIPHER, NIST_AES_VECTOR_SIZE },
- { 1, NIST_AES_256_KEY, CC_AES_256_BIT_KEY_SIZE, NIST_AES_ECB_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_ECB, NIST_AES_256_ECB_CIPHER, NIST_AES_PLAIN_DATA, NIST_AES_VECTOR_SIZE },
- { 1, NIST_AES_128_KEY, CC_AES_128_BIT_KEY_SIZE, NIST_AES_CBC_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_CBC, NIST_AES_PLAIN_DATA, NIST_AES_128_CBC_CIPHER, NIST_AES_VECTOR_SIZE },
- { 1, NIST_AES_128_KEY, CC_AES_128_BIT_KEY_SIZE, NIST_AES_CBC_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_CBC, NIST_AES_128_CBC_CIPHER, NIST_AES_PLAIN_DATA, NIST_AES_VECTOR_SIZE },
- { 1, NIST_AES_192_KEY, CC_AES_192_BIT_KEY_SIZE, NIST_AES_CBC_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_CBC, NIST_AES_PLAIN_DATA, NIST_AES_192_CBC_CIPHER, NIST_AES_VECTOR_SIZE },
- { 1, NIST_AES_192_KEY, CC_AES_192_BIT_KEY_SIZE, NIST_AES_CBC_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_CBC, NIST_AES_192_CBC_CIPHER, NIST_AES_PLAIN_DATA, NIST_AES_VECTOR_SIZE },
- { 1, NIST_AES_256_KEY, CC_AES_256_BIT_KEY_SIZE, NIST_AES_CBC_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_CBC, NIST_AES_PLAIN_DATA, NIST_AES_256_CBC_CIPHER, NIST_AES_VECTOR_SIZE },
- { 1, NIST_AES_256_KEY, CC_AES_256_BIT_KEY_SIZE, NIST_AES_CBC_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_CBC, NIST_AES_256_CBC_CIPHER, NIST_AES_PLAIN_DATA, NIST_AES_VECTOR_SIZE },
- { 1, NIST_AES_128_KEY, CC_AES_128_BIT_KEY_SIZE, NIST_AES_OFB_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_OFB, NIST_AES_PLAIN_DATA, NIST_AES_128_OFB_CIPHER, NIST_AES_VECTOR_SIZE },
- { 1, NIST_AES_128_KEY, CC_AES_128_BIT_KEY_SIZE, NIST_AES_OFB_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_OFB, NIST_AES_128_OFB_CIPHER, NIST_AES_PLAIN_DATA, NIST_AES_VECTOR_SIZE },
- { 1, NIST_AES_192_KEY, CC_AES_192_BIT_KEY_SIZE, NIST_AES_OFB_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_OFB, NIST_AES_PLAIN_DATA, NIST_AES_192_OFB_CIPHER, NIST_AES_VECTOR_SIZE },
- { 1, NIST_AES_192_KEY, CC_AES_192_BIT_KEY_SIZE, NIST_AES_OFB_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_OFB, NIST_AES_192_OFB_CIPHER, NIST_AES_PLAIN_DATA, NIST_AES_VECTOR_SIZE },
- { 1, NIST_AES_256_KEY, CC_AES_256_BIT_KEY_SIZE, NIST_AES_OFB_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_OFB, NIST_AES_PLAIN_DATA, NIST_AES_256_OFB_CIPHER, NIST_AES_VECTOR_SIZE },
- { 1, NIST_AES_256_KEY, CC_AES_256_BIT_KEY_SIZE, NIST_AES_OFB_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_OFB, NIST_AES_256_OFB_CIPHER, NIST_AES_PLAIN_DATA, NIST_AES_VECTOR_SIZE },
- { 1, NIST_AES_128_KEY, CC_AES_128_BIT_KEY_SIZE, NIST_AES_CTR_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_CTR, NIST_AES_PLAIN_DATA, NIST_AES_128_CTR_CIPHER, NIST_AES_VECTOR_SIZE },
- { 1, NIST_AES_128_KEY, CC_AES_128_BIT_KEY_SIZE, NIST_AES_CTR_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_CTR, NIST_AES_128_CTR_CIPHER, NIST_AES_PLAIN_DATA, NIST_AES_VECTOR_SIZE },
- { 1, NIST_AES_192_KEY, CC_AES_192_BIT_KEY_SIZE, NIST_AES_CTR_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_CTR, NIST_AES_PLAIN_DATA, NIST_AES_192_CTR_CIPHER, NIST_AES_VECTOR_SIZE },
- { 1, NIST_AES_192_KEY, CC_AES_192_BIT_KEY_SIZE, NIST_AES_CTR_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_CTR, NIST_AES_192_CTR_CIPHER, NIST_AES_PLAIN_DATA, NIST_AES_VECTOR_SIZE },
- { 1, NIST_AES_256_KEY, CC_AES_256_BIT_KEY_SIZE, NIST_AES_CTR_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_CTR, NIST_AES_PLAIN_DATA, NIST_AES_256_CTR_CIPHER, NIST_AES_VECTOR_SIZE },
- { 1, NIST_AES_256_KEY, CC_AES_256_BIT_KEY_SIZE, NIST_AES_CTR_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_CTR, NIST_AES_256_CTR_CIPHER, NIST_AES_PLAIN_DATA, NIST_AES_VECTOR_SIZE },
- { 1, RFC3962_AES_128_KEY, CC_AES_128_BIT_KEY_SIZE, RFC3962_AES_CBC_CTS_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_CBC_CTS, RFC3962_AES_PLAIN_DATA, RFC3962_AES_128_CBC_CTS_CIPHER, RFC3962_AES_VECTOR_SIZE },
- { 1, RFC3962_AES_128_KEY, CC_AES_128_BIT_KEY_SIZE, RFC3962_AES_CBC_CTS_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_CBC_CTS, RFC3962_AES_128_CBC_CTS_CIPHER, RFC3962_AES_PLAIN_DATA, RFC3962_AES_VECTOR_SIZE },
- { 1, NIST_AES_256_XTS_KEY, CC_AES_256_BIT_KEY_SIZE, NIST_AES_256_XTS_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_XTS, NIST_AES_256_XTS_PLAIN, NIST_AES_256_XTS_CIPHER, NIST_AES_256_XTS_VECTOR_SIZE },
- { 1, NIST_AES_256_XTS_KEY, CC_AES_256_BIT_KEY_SIZE, NIST_AES_256_XTS_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_XTS, NIST_AES_256_XTS_CIPHER, NIST_AES_256_XTS_PLAIN, NIST_AES_256_XTS_VECTOR_SIZE },
-#if (CC_SUPPORT_SHA > 256)
- { 1, NIST_AES_512_XTS_KEY, 2 * CC_AES_256_BIT_KEY_SIZE, NIST_AES_512_XTS_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_XTS, NIST_AES_512_XTS_PLAIN, NIST_AES_512_XTS_CIPHER, NIST_AES_512_XTS_VECTOR_SIZE },
- { 1, NIST_AES_512_XTS_KEY, 2 * CC_AES_256_BIT_KEY_SIZE, NIST_AES_512_XTS_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_XTS, NIST_AES_512_XTS_CIPHER, NIST_AES_512_XTS_PLAIN, NIST_AES_512_XTS_VECTOR_SIZE },
-#endif
- /* DES */
- { 0, NIST_TDES_ECB3_KEY, CC_DRV_DES_TRIPLE_KEY_SIZE, NIST_TDES_ECB_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_ECB, NIST_TDES_ECB3_PLAIN_DATA, NIST_TDES_ECB3_CIPHER, NIST_TDES_VECTOR_SIZE },
- { 0, NIST_TDES_ECB3_KEY, CC_DRV_DES_TRIPLE_KEY_SIZE, NIST_TDES_ECB_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_ECB, NIST_TDES_ECB3_CIPHER, NIST_TDES_ECB3_PLAIN_DATA, NIST_TDES_VECTOR_SIZE },
- { 0, NIST_TDES_CBC3_KEY, CC_DRV_DES_TRIPLE_KEY_SIZE, NIST_TDES_CBC3_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_CBC, NIST_TDES_CBC3_PLAIN_DATA, NIST_TDES_CBC3_CIPHER, NIST_TDES_VECTOR_SIZE },
- { 0, NIST_TDES_CBC3_KEY, CC_DRV_DES_TRIPLE_KEY_SIZE, NIST_TDES_CBC3_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_CBC, NIST_TDES_CBC3_CIPHER, NIST_TDES_CBC3_PLAIN_DATA, NIST_TDES_VECTOR_SIZE },
-};
-
-#define FIPS_CIPHER_NUM_OF_TESTS (sizeof(FipsCipherDataTable) / sizeof(FipsCipherData))
-
-static const FipsCmacData FipsCmacDataTable[] = {
- { DRV_CRYPTO_DIRECTION_ENCRYPT, NIST_AES_128_CMAC_KEY, AES_128_BIT_KEY_SIZE, NIST_AES_128_CMAC_PLAIN_DATA, NIST_AES_128_CMAC_VECTOR_SIZE, NIST_AES_128_CMAC_MAC, NIST_AES_128_CMAC_OUTPUT_SIZE },
- { DRV_CRYPTO_DIRECTION_ENCRYPT, NIST_AES_192_CMAC_KEY, AES_192_BIT_KEY_SIZE, NIST_AES_192_CMAC_PLAIN_DATA, NIST_AES_192_CMAC_VECTOR_SIZE, NIST_AES_192_CMAC_MAC, NIST_AES_192_CMAC_OUTPUT_SIZE },
- { DRV_CRYPTO_DIRECTION_ENCRYPT, NIST_AES_256_CMAC_KEY, AES_256_BIT_KEY_SIZE, NIST_AES_256_CMAC_PLAIN_DATA, NIST_AES_256_CMAC_VECTOR_SIZE, NIST_AES_256_CMAC_MAC, NIST_AES_256_CMAC_OUTPUT_SIZE },
-};
-
-#define FIPS_CMAC_NUM_OF_TESTS (sizeof(FipsCmacDataTable) / sizeof(FipsCmacData))
-
-static const FipsHashData FipsHashDataTable[] = {
- { DRV_HASH_SHA1, NIST_SHA_1_MSG, NIST_SHA_MSG_SIZE, NIST_SHA_1_MD },
- { DRV_HASH_SHA256, NIST_SHA_256_MSG, NIST_SHA_MSG_SIZE, NIST_SHA_256_MD },
-#if (CC_SUPPORT_SHA > 256)
-// { DRV_HASH_SHA512, NIST_SHA_512_MSG, NIST_SHA_MSG_SIZE, NIST_SHA_512_MD },
-#endif
-};
-
-#define FIPS_HASH_NUM_OF_TESTS (sizeof(FipsHashDataTable) / sizeof(FipsHashData))
-
-static const FipsHmacData FipsHmacDataTable[] = {
- { DRV_HASH_SHA1, NIST_HMAC_SHA1_KEY, NIST_HMAC_SHA1_KEY_SIZE, NIST_HMAC_SHA1_MSG, NIST_HMAC_MSG_SIZE, NIST_HMAC_SHA1_MD },
- { DRV_HASH_SHA256, NIST_HMAC_SHA256_KEY, NIST_HMAC_SHA256_KEY_SIZE, NIST_HMAC_SHA256_MSG, NIST_HMAC_MSG_SIZE, NIST_HMAC_SHA256_MD },
-#if (CC_SUPPORT_SHA > 256)
-// { DRV_HASH_SHA512, NIST_HMAC_SHA512_KEY, NIST_HMAC_SHA512_KEY_SIZE, NIST_HMAC_SHA512_MSG, NIST_HMAC_MSG_SIZE, NIST_HMAC_SHA512_MD },
-#endif
-};
-
-#define FIPS_HMAC_NUM_OF_TESTS (sizeof(FipsHmacDataTable) / sizeof(FipsHmacData))
-
-static const FipsCcmData FipsCcmDataTable[] = {
- { DRV_CRYPTO_DIRECTION_ENCRYPT, NIST_AESCCM_128_KEY, NIST_AESCCM_128_BIT_KEY_SIZE, NIST_AESCCM_128_NONCE, NIST_AESCCM_128_ADATA, NIST_AESCCM_ADATA_SIZE, NIST_AESCCM_128_PLAIN_TEXT, NIST_AESCCM_TEXT_SIZE, NIST_AESCCM_128_CIPHER, NIST_AESCCM_TAG_SIZE, NIST_AESCCM_128_MAC },
- { DRV_CRYPTO_DIRECTION_DECRYPT, NIST_AESCCM_128_KEY, NIST_AESCCM_128_BIT_KEY_SIZE, NIST_AESCCM_128_NONCE, NIST_AESCCM_128_ADATA, NIST_AESCCM_ADATA_SIZE, NIST_AESCCM_128_CIPHER, NIST_AESCCM_TEXT_SIZE, NIST_AESCCM_128_PLAIN_TEXT, NIST_AESCCM_TAG_SIZE, NIST_AESCCM_128_MAC },
- { DRV_CRYPTO_DIRECTION_ENCRYPT, NIST_AESCCM_192_KEY, NIST_AESCCM_192_BIT_KEY_SIZE, NIST_AESCCM_192_NONCE, NIST_AESCCM_192_ADATA, NIST_AESCCM_ADATA_SIZE, NIST_AESCCM_192_PLAIN_TEXT, NIST_AESCCM_TEXT_SIZE, NIST_AESCCM_192_CIPHER, NIST_AESCCM_TAG_SIZE, NIST_AESCCM_192_MAC },
- { DRV_CRYPTO_DIRECTION_DECRYPT, NIST_AESCCM_192_KEY, NIST_AESCCM_192_BIT_KEY_SIZE, NIST_AESCCM_192_NONCE, NIST_AESCCM_192_ADATA, NIST_AESCCM_ADATA_SIZE, NIST_AESCCM_192_CIPHER, NIST_AESCCM_TEXT_SIZE, NIST_AESCCM_192_PLAIN_TEXT, NIST_AESCCM_TAG_SIZE, NIST_AESCCM_192_MAC },
- { DRV_CRYPTO_DIRECTION_ENCRYPT, NIST_AESCCM_256_KEY, NIST_AESCCM_256_BIT_KEY_SIZE, NIST_AESCCM_256_NONCE, NIST_AESCCM_256_ADATA, NIST_AESCCM_ADATA_SIZE, NIST_AESCCM_256_PLAIN_TEXT, NIST_AESCCM_TEXT_SIZE, NIST_AESCCM_256_CIPHER, NIST_AESCCM_TAG_SIZE, NIST_AESCCM_256_MAC },
- { DRV_CRYPTO_DIRECTION_DECRYPT, NIST_AESCCM_256_KEY, NIST_AESCCM_256_BIT_KEY_SIZE, NIST_AESCCM_256_NONCE, NIST_AESCCM_256_ADATA, NIST_AESCCM_ADATA_SIZE, NIST_AESCCM_256_CIPHER, NIST_AESCCM_TEXT_SIZE, NIST_AESCCM_256_PLAIN_TEXT, NIST_AESCCM_TAG_SIZE, NIST_AESCCM_256_MAC },
-};
-
-#define FIPS_CCM_NUM_OF_TESTS (sizeof(FipsCcmDataTable) / sizeof(FipsCcmData))
-
-static const FipsGcmData FipsGcmDataTable[] = {
- { DRV_CRYPTO_DIRECTION_ENCRYPT, NIST_AESGCM_128_KEY, NIST_AESGCM_128_BIT_KEY_SIZE, NIST_AESGCM_128_IV, NIST_AESGCM_128_ADATA, NIST_AESGCM_ADATA_SIZE, NIST_AESGCM_128_PLAIN_TEXT, NIST_AESGCM_TEXT_SIZE, NIST_AESGCM_128_CIPHER, NIST_AESGCM_TAG_SIZE, NIST_AESGCM_128_MAC },
- { DRV_CRYPTO_DIRECTION_DECRYPT, NIST_AESGCM_128_KEY, NIST_AESGCM_128_BIT_KEY_SIZE, NIST_AESGCM_128_IV, NIST_AESGCM_128_ADATA, NIST_AESGCM_ADATA_SIZE, NIST_AESGCM_128_CIPHER, NIST_AESGCM_TEXT_SIZE, NIST_AESGCM_128_PLAIN_TEXT, NIST_AESGCM_TAG_SIZE, NIST_AESGCM_128_MAC },
- { DRV_CRYPTO_DIRECTION_ENCRYPT, NIST_AESGCM_192_KEY, NIST_AESGCM_192_BIT_KEY_SIZE, NIST_AESGCM_192_IV, NIST_AESGCM_192_ADATA, NIST_AESGCM_ADATA_SIZE, NIST_AESGCM_192_PLAIN_TEXT, NIST_AESGCM_TEXT_SIZE, NIST_AESGCM_192_CIPHER, NIST_AESGCM_TAG_SIZE, NIST_AESGCM_192_MAC },
- { DRV_CRYPTO_DIRECTION_DECRYPT, NIST_AESGCM_192_KEY, NIST_AESGCM_192_BIT_KEY_SIZE, NIST_AESGCM_192_IV, NIST_AESGCM_192_ADATA, NIST_AESGCM_ADATA_SIZE, NIST_AESGCM_192_CIPHER, NIST_AESGCM_TEXT_SIZE, NIST_AESGCM_192_PLAIN_TEXT, NIST_AESGCM_TAG_SIZE, NIST_AESGCM_192_MAC },
- { DRV_CRYPTO_DIRECTION_ENCRYPT, NIST_AESGCM_256_KEY, NIST_AESGCM_256_BIT_KEY_SIZE, NIST_AESGCM_256_IV, NIST_AESGCM_256_ADATA, NIST_AESGCM_ADATA_SIZE, NIST_AESGCM_256_PLAIN_TEXT, NIST_AESGCM_TEXT_SIZE, NIST_AESGCM_256_CIPHER, NIST_AESGCM_TAG_SIZE, NIST_AESGCM_256_MAC },
- { DRV_CRYPTO_DIRECTION_DECRYPT, NIST_AESGCM_256_KEY, NIST_AESGCM_256_BIT_KEY_SIZE, NIST_AESGCM_256_IV, NIST_AESGCM_256_ADATA, NIST_AESGCM_ADATA_SIZE, NIST_AESGCM_256_CIPHER, NIST_AESGCM_TEXT_SIZE, NIST_AESGCM_256_PLAIN_TEXT, NIST_AESGCM_TAG_SIZE, NIST_AESGCM_256_MAC },
-};
-
-#define FIPS_GCM_NUM_OF_TESTS (sizeof(FipsGcmDataTable) / sizeof(FipsGcmData))
-
-static inline enum cc_fips_error
-FIPS_CipherToFipsError(enum drv_cipher_mode mode, bool is_aes)
-{
- switch (mode)
- {
- case DRV_CIPHER_ECB:
- return is_aes ? CC_REE_FIPS_ERROR_AES_ECB_PUT : CC_REE_FIPS_ERROR_DES_ECB_PUT;
- case DRV_CIPHER_CBC:
- return is_aes ? CC_REE_FIPS_ERROR_AES_CBC_PUT : CC_REE_FIPS_ERROR_DES_CBC_PUT;
- case DRV_CIPHER_OFB:
- return CC_REE_FIPS_ERROR_AES_OFB_PUT;
- case DRV_CIPHER_CTR:
- return CC_REE_FIPS_ERROR_AES_CTR_PUT;
- case DRV_CIPHER_CBC_CTS:
- return CC_REE_FIPS_ERROR_AES_CBC_CTS_PUT;
- case DRV_CIPHER_XTS:
- return CC_REE_FIPS_ERROR_AES_XTS_PUT;
- default:
- return CC_REE_FIPS_ERROR_GENERAL;
- }
-
- return CC_REE_FIPS_ERROR_GENERAL;
-}
-
-static inline int
-ssi_cipher_fips_run_test(struct ssi_drvdata *drvdata,
- bool is_aes,
- int cipher_mode,
- int direction,
- dma_addr_t key_dma_addr,
- size_t key_len,
- dma_addr_t iv_dma_addr,
- size_t iv_len,
- dma_addr_t din_dma_addr,
- dma_addr_t dout_dma_addr,
- size_t data_size)
-{
- /* max number of descriptors used for the flow */
- #define FIPS_CIPHER_MAX_SEQ_LEN 6
-
- int rc;
- struct ssi_crypto_req ssi_req = {0};
- struct cc_hw_desc desc[FIPS_CIPHER_MAX_SEQ_LEN];
- int idx = 0;
- int s_flow_mode = is_aes ? S_DIN_to_AES : S_DIN_to_DES;
-
- /* create setup descriptors */
- switch (cipher_mode) {
- case DRV_CIPHER_CBC:
- case DRV_CIPHER_CBC_CTS:
- case DRV_CIPHER_CTR:
- case DRV_CIPHER_OFB:
- /* Load cipher state */
- hw_desc_init(&desc[idx]);
- set_din_type(&desc[idx], DMA_DLLI,
- iv_dma_addr, iv_len, NS_BIT);
- set_cipher_config0(&desc[idx], direction);
- set_flow_mode(&desc[idx], s_flow_mode);
- set_cipher_mode(&desc[idx], cipher_mode);
- if ((cipher_mode == DRV_CIPHER_CTR) ||
- (cipher_mode == DRV_CIPHER_OFB)) {
- set_setup_mode(&desc[idx], SETUP_LOAD_STATE1);
- } else {
- set_setup_mode(&desc[idx], SETUP_LOAD_STATE0);
- }
- idx++;
- /*FALLTHROUGH*/
- case DRV_CIPHER_ECB:
- /* Load key */
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], cipher_mode);
- set_cipher_config0(&desc[idx], direction);
- if (is_aes) {
- set_din_type(&desc[idx], DMA_DLLI, key_dma_addr,
- ((key_len == 24) ? AES_MAX_KEY_SIZE :
- key_len), NS_BIT);
- set_key_size_aes(&desc[idx], key_len);
- } else {/*des*/
- set_din_type(&desc[idx], DMA_DLLI, key_dma_addr,
- key_len, NS_BIT);
- set_key_size_des(&desc[idx], key_len);
- }
- set_flow_mode(&desc[idx], s_flow_mode);
- set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
- idx++;
- break;
- case DRV_CIPHER_XTS:
- /* Load AES key */
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], cipher_mode);
- set_cipher_config0(&desc[idx], direction);
- set_din_type(&desc[idx], DMA_DLLI, key_dma_addr, (key_len / 2),
- NS_BIT);
- set_key_size_aes(&desc[idx], (key_len / 2));
- set_flow_mode(&desc[idx], s_flow_mode);
- set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
- idx++;
-
- /* load XEX key */
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], cipher_mode);
- set_cipher_config0(&desc[idx], direction);
- set_din_type(&desc[idx], DMA_DLLI,
- (key_dma_addr + (key_len / 2)),
- (key_len / 2), NS_BIT);
- set_xex_data_unit_size(&desc[idx], data_size);
- set_flow_mode(&desc[idx], s_flow_mode);
- set_key_size_aes(&desc[idx], (key_len / 2));
- set_setup_mode(&desc[idx], SETUP_LOAD_XEX_KEY);
- idx++;
-
- /* Set state */
- hw_desc_init(&desc[idx]);
- set_setup_mode(&desc[idx], SETUP_LOAD_STATE1);
- set_cipher_mode(&desc[idx], cipher_mode);
- set_cipher_config0(&desc[idx], direction);
- set_key_size_aes(&desc[idx], (key_len / 2));
- set_flow_mode(&desc[idx], s_flow_mode);
- set_din_type(&desc[idx], DMA_DLLI, iv_dma_addr,
- CC_AES_BLOCK_SIZE, NS_BIT);
- idx++;
- break;
- default:
- FIPS_LOG("Unsupported cipher mode (%d)\n", cipher_mode);
- BUG();
- }
-
- /* create data descriptor */
- hw_desc_init(&desc[idx]);
- set_din_type(&desc[idx], DMA_DLLI, din_dma_addr, data_size, NS_BIT);
- set_dout_dlli(&desc[idx], dout_dma_addr, data_size, NS_BIT, 0);
- set_flow_mode(&desc[idx], is_aes ? DIN_AES_DOUT : DIN_DES_DOUT);
- idx++;
-
- /* perform the operation - Lock HW and push sequence */
- BUG_ON(idx > FIPS_CIPHER_MAX_SEQ_LEN);
- rc = send_request(drvdata, &ssi_req, desc, idx, false);
-
- // send_request returns error just in some corner cases which should not appear in this flow.
- return rc;
-}
-
-enum cc_fips_error
-ssi_cipher_fips_power_up_tests(struct ssi_drvdata *drvdata, void *cpu_addr_buffer, dma_addr_t dma_coherent_buffer)
-{
- enum cc_fips_error error = CC_REE_FIPS_ERROR_OK;
- size_t i;
- struct fips_cipher_ctx *virt_ctx = (struct fips_cipher_ctx *)cpu_addr_buffer;
-
- /* set the phisical pointers for iv, key, din, dout */
- dma_addr_t iv_dma_addr = dma_coherent_buffer + offsetof(struct fips_cipher_ctx, iv);
- dma_addr_t key_dma_addr = dma_coherent_buffer + offsetof(struct fips_cipher_ctx, key);
- dma_addr_t din_dma_addr = dma_coherent_buffer + offsetof(struct fips_cipher_ctx, din);
- dma_addr_t dout_dma_addr = dma_coherent_buffer + offsetof(struct fips_cipher_ctx, dout);
-
- for (i = 0; i < FIPS_CIPHER_NUM_OF_TESTS; ++i)
- {
- FipsCipherData *cipherData = (FipsCipherData *)&FipsCipherDataTable[i];
- int rc = 0;
- size_t iv_size = cipherData->isAes ? NIST_AES_IV_SIZE : NIST_TDES_IV_SIZE;
-
- memset(cpu_addr_buffer, 0, sizeof(struct fips_cipher_ctx));
-
- /* copy into the allocated buffer */
- memcpy(virt_ctx->iv, cipherData->iv, iv_size);
- memcpy(virt_ctx->key, cipherData->key, cipherData->keySize);
- memcpy(virt_ctx->din, cipherData->dataIn, cipherData->dataInSize);
-
- FIPS_DBG("ssi_cipher_fips_run_test - (i = %d) \n", i);
- rc = ssi_cipher_fips_run_test(drvdata,
- cipherData->isAes,
- cipherData->oprMode,
- cipherData->direction,
- key_dma_addr,
- cipherData->keySize,
- iv_dma_addr,
- iv_size,
- din_dma_addr,
- dout_dma_addr,
- cipherData->dataInSize);
- if (rc != 0)
- {
- FIPS_LOG("ssi_cipher_fips_run_test %d returned error - rc = %d \n", i, rc);
- error = FIPS_CipherToFipsError(cipherData->oprMode, cipherData->isAes);
- break;
- }
-
- /* compare actual dout to expected */
- if (memcmp(virt_ctx->dout, cipherData->dataOut, cipherData->dataInSize) != 0)
- {
- FIPS_LOG("dout comparison error %d - oprMode=%d, isAes=%d\n", i, cipherData->oprMode, cipherData->isAes);
- FIPS_LOG(" i expected received \n");
- FIPS_LOG(" i 0x%08x 0x%08x (size=%d) \n", (size_t)cipherData->dataOut, (size_t)virt_ctx->dout, cipherData->dataInSize);
- for (i = 0; i < cipherData->dataInSize; ++i)
- {
- FIPS_LOG(" %d 0x%02x 0x%02x \n", i, cipherData->dataOut[i], virt_ctx->dout[i]);
- }
-
- error = FIPS_CipherToFipsError(cipherData->oprMode, cipherData->isAes);
- break;
- }
- }
-
- return error;
-}
-
-static inline int
-ssi_cmac_fips_run_test(struct ssi_drvdata *drvdata,
- dma_addr_t key_dma_addr,
- size_t key_len,
- dma_addr_t din_dma_addr,
- size_t din_len,
- dma_addr_t digest_dma_addr,
- size_t digest_len)
-{
- /* max number of descriptors used for the flow */
- #define FIPS_CMAC_MAX_SEQ_LEN 4
-
- int rc;
- struct ssi_crypto_req ssi_req = {0};
- struct cc_hw_desc desc[FIPS_CMAC_MAX_SEQ_LEN];
- int idx = 0;
-
- /* Setup CMAC Key */
- hw_desc_init(&desc[idx]);
- set_din_type(&desc[idx], DMA_DLLI, key_dma_addr,
- ((key_len == 24) ? AES_MAX_KEY_SIZE : key_len), NS_BIT);
- set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
- set_cipher_mode(&desc[idx], DRV_CIPHER_CMAC);
- set_cipher_config0(&desc[idx], DESC_DIRECTION_ENCRYPT_ENCRYPT);
- set_key_size_aes(&desc[idx], key_len);
- set_flow_mode(&desc[idx], S_DIN_to_AES);
- idx++;
-
- /* Load MAC state */
- hw_desc_init(&desc[idx]);
- set_din_type(&desc[idx], DMA_DLLI, digest_dma_addr, CC_AES_BLOCK_SIZE,
- NS_BIT);
- set_setup_mode(&desc[idx], SETUP_LOAD_STATE0);
- set_cipher_mode(&desc[idx], DRV_CIPHER_CMAC);
- set_cipher_config0(&desc[idx], DESC_DIRECTION_ENCRYPT_ENCRYPT);
- set_key_size_aes(&desc[idx], key_len);
- set_flow_mode(&desc[idx], S_DIN_to_AES);
- idx++;
-
- //ssi_hash_create_data_desc(state, ctx, DIN_AES_DOUT, desc, false, &idx);
- hw_desc_init(&desc[idx]);
- set_din_type(&desc[idx], DMA_DLLI, din_dma_addr, din_len, NS_BIT);
- set_flow_mode(&desc[idx], DIN_AES_DOUT);
- idx++;
-
- /* Get final MAC result */
- hw_desc_init(&desc[idx]);
- set_dout_dlli(&desc[idx], digest_dma_addr, CC_AES_BLOCK_SIZE, NS_BIT,
- 0);
- set_flow_mode(&desc[idx], S_AES_to_DOUT);
- set_setup_mode(&desc[idx], SETUP_WRITE_STATE0);
- set_cipher_config0(&desc[idx], DESC_DIRECTION_ENCRYPT_ENCRYPT);
- set_cipher_mode(&desc[idx], DRV_CIPHER_CMAC);
- idx++;
-
- /* perform the operation - Lock HW and push sequence */
- BUG_ON(idx > FIPS_CMAC_MAX_SEQ_LEN);
- rc = send_request(drvdata, &ssi_req, desc, idx, false);
-
- // send_request returns error just in some corner cases which should not appear in this flow.
- return rc;
-}
-
-enum cc_fips_error
-ssi_cmac_fips_power_up_tests(struct ssi_drvdata *drvdata, void *cpu_addr_buffer, dma_addr_t dma_coherent_buffer)
-{
- enum cc_fips_error error = CC_REE_FIPS_ERROR_OK;
- size_t i;
- struct fips_cmac_ctx *virt_ctx = (struct fips_cmac_ctx *)cpu_addr_buffer;
-
- /* set the phisical pointers for key, din, dout */
- dma_addr_t key_dma_addr = dma_coherent_buffer + offsetof(struct fips_cmac_ctx, key);
- dma_addr_t din_dma_addr = dma_coherent_buffer + offsetof(struct fips_cmac_ctx, din);
- dma_addr_t mac_res_dma_addr = dma_coherent_buffer + offsetof(struct fips_cmac_ctx, mac_res);
-
- for (i = 0; i < FIPS_CMAC_NUM_OF_TESTS; ++i)
- {
- FipsCmacData *cmac_data = (FipsCmacData *)&FipsCmacDataTable[i];
- int rc = 0;
-
- memset(cpu_addr_buffer, 0, sizeof(struct fips_cmac_ctx));
-
- /* copy into the allocated buffer */
- memcpy(virt_ctx->key, cmac_data->key, cmac_data->key_size);
- memcpy(virt_ctx->din, cmac_data->data_in, cmac_data->data_in_size);
-
- BUG_ON(cmac_data->direction != DRV_CRYPTO_DIRECTION_ENCRYPT);
-
- FIPS_DBG("ssi_cmac_fips_run_test - (i = %d) \n", i);
- rc = ssi_cmac_fips_run_test(drvdata,
- key_dma_addr,
- cmac_data->key_size,
- din_dma_addr,
- cmac_data->data_in_size,
- mac_res_dma_addr,
- cmac_data->mac_res_size);
- if (rc != 0)
- {
- FIPS_LOG("ssi_cmac_fips_run_test %d returned error - rc = %d \n", i, rc);
- error = CC_REE_FIPS_ERROR_AES_CMAC_PUT;
- break;
- }
-
- /* compare actual mac result to expected */
- if (memcmp(virt_ctx->mac_res, cmac_data->mac_res, cmac_data->mac_res_size) != 0)
- {
- FIPS_LOG("comparison error %d - digest_size=%d \n", i, cmac_data->mac_res_size);
- FIPS_LOG(" i expected received \n");
- FIPS_LOG(" i 0x%08x 0x%08x \n", (size_t)cmac_data->mac_res, (size_t)virt_ctx->mac_res);
- for (i = 0; i < cmac_data->mac_res_size; ++i)
- {
- FIPS_LOG(" %d 0x%02x 0x%02x \n", i, cmac_data->mac_res[i], virt_ctx->mac_res[i]);
- }
-
- error = CC_REE_FIPS_ERROR_AES_CMAC_PUT;
- break;
- }
- }
-
- return error;
-}
-
-static inline enum cc_fips_error
-FIPS_HashToFipsError(enum drv_hash_mode hash_mode)
-{
- switch (hash_mode) {
- case DRV_HASH_SHA1:
- return CC_REE_FIPS_ERROR_SHA1_PUT;
- case DRV_HASH_SHA256:
- return CC_REE_FIPS_ERROR_SHA256_PUT;
-#if (CC_SUPPORT_SHA > 256)
- case DRV_HASH_SHA512:
- return CC_REE_FIPS_ERROR_SHA512_PUT;
-#endif
- default:
- return CC_REE_FIPS_ERROR_GENERAL;
- }
-
- return CC_REE_FIPS_ERROR_GENERAL;
-}
-
-static inline int
-ssi_hash_fips_run_test(struct ssi_drvdata *drvdata,
- dma_addr_t initial_digest_dma_addr,
- dma_addr_t din_dma_addr,
- size_t data_in_size,
- dma_addr_t mac_res_dma_addr,
- enum drv_hash_mode hash_mode,
- enum drv_hash_hw_mode hw_mode,
- int digest_size,
- int inter_digestsize)
-{
- /* max number of descriptors used for the flow */
- #define FIPS_HASH_MAX_SEQ_LEN 4
-
- int rc;
- struct ssi_crypto_req ssi_req = {0};
- struct cc_hw_desc desc[FIPS_HASH_MAX_SEQ_LEN];
- int idx = 0;
-
- /* Load initial digest */
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], hw_mode);
- set_din_type(&desc[idx], DMA_DLLI, initial_digest_dma_addr,
- inter_digestsize, NS_BIT);
- set_flow_mode(&desc[idx], S_DIN_to_HASH);
- set_setup_mode(&desc[idx], SETUP_LOAD_STATE0);
- idx++;
-
- /* Load the hash current length */
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], hw_mode);
- set_din_const(&desc[idx], 0, HASH_LEN_SIZE);
- set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED);
- set_flow_mode(&desc[idx], S_DIN_to_HASH);
- set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
- idx++;
-
- /* data descriptor */
- hw_desc_init(&desc[idx]);
- set_din_type(&desc[idx], DMA_DLLI, din_dma_addr, data_in_size, NS_BIT);
- set_flow_mode(&desc[idx], DIN_HASH);
- idx++;
-
- /* Get final MAC result */
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], hw_mode);
- set_dout_dlli(&desc[idx], mac_res_dma_addr, digest_size, NS_BIT, 0);
- set_flow_mode(&desc[idx], S_HASH_to_DOUT);
- set_setup_mode(&desc[idx], SETUP_WRITE_STATE0);
- set_cipher_config1(&desc[idx], HASH_PADDING_DISABLED);
- if (unlikely((hash_mode == DRV_HASH_MD5) ||
- (hash_mode == DRV_HASH_SHA384) ||
- (hash_mode == DRV_HASH_SHA512))) {
- set_bytes_swap(&desc[idx], 1);
- } else {
- set_cipher_config0(&desc[idx],
- HASH_DIGEST_RESULT_LITTLE_ENDIAN);
- }
- idx++;
-
- /* perform the operation - Lock HW and push sequence */
- BUG_ON(idx > FIPS_HASH_MAX_SEQ_LEN);
- rc = send_request(drvdata, &ssi_req, desc, idx, false);
-
- return rc;
-}
-
-enum cc_fips_error
-ssi_hash_fips_power_up_tests(struct ssi_drvdata *drvdata, void *cpu_addr_buffer, dma_addr_t dma_coherent_buffer)
-{
- enum cc_fips_error error = CC_REE_FIPS_ERROR_OK;
- size_t i;
- struct fips_hash_ctx *virt_ctx = (struct fips_hash_ctx *)cpu_addr_buffer;
-
- /* set the phisical pointers for initial_digest, din, mac_res */
- dma_addr_t initial_digest_dma_addr = dma_coherent_buffer + offsetof(struct fips_hash_ctx, initial_digest);
- dma_addr_t din_dma_addr = dma_coherent_buffer + offsetof(struct fips_hash_ctx, din);
- dma_addr_t mac_res_dma_addr = dma_coherent_buffer + offsetof(struct fips_hash_ctx, mac_res);
-
- for (i = 0; i < FIPS_HASH_NUM_OF_TESTS; ++i)
- {
- FipsHashData *hash_data = (FipsHashData *)&FipsHashDataTable[i];
- int rc = 0;
- enum drv_hash_hw_mode hw_mode = 0;
- int digest_size = 0;
- int inter_digestsize = 0;
-
- memset(cpu_addr_buffer, 0, sizeof(struct fips_hash_ctx));
-
- switch (hash_data->hash_mode) {
- case DRV_HASH_SHA1:
- hw_mode = DRV_HASH_HW_SHA1;
- digest_size = CC_SHA1_DIGEST_SIZE;
- inter_digestsize = CC_SHA1_DIGEST_SIZE;
- /* copy the initial digest into the allocated cache coherent buffer */
- memcpy(virt_ctx->initial_digest, (void *)sha1_init, CC_SHA1_DIGEST_SIZE);
- break;
- case DRV_HASH_SHA256:
- hw_mode = DRV_HASH_HW_SHA256;
- digest_size = CC_SHA256_DIGEST_SIZE;
- inter_digestsize = CC_SHA256_DIGEST_SIZE;
- memcpy(virt_ctx->initial_digest, (void *)sha256_init, CC_SHA256_DIGEST_SIZE);
- break;
-#if (CC_SUPPORT_SHA > 256)
- case DRV_HASH_SHA512:
- hw_mode = DRV_HASH_HW_SHA512;
- digest_size = CC_SHA512_DIGEST_SIZE;
- inter_digestsize = CC_SHA512_DIGEST_SIZE;
- memcpy(virt_ctx->initial_digest, (void *)sha512_init, CC_SHA512_DIGEST_SIZE);
- break;
-#endif
- default:
- error = FIPS_HashToFipsError(hash_data->hash_mode);
- break;
- }
-
- /* copy the din data into the allocated buffer */
- memcpy(virt_ctx->din, hash_data->data_in, hash_data->data_in_size);
-
- /* run the test on HW */
- FIPS_DBG("ssi_hash_fips_run_test - (i = %d) \n", i);
- rc = ssi_hash_fips_run_test(drvdata,
- initial_digest_dma_addr,
- din_dma_addr,
- hash_data->data_in_size,
- mac_res_dma_addr,
- hash_data->hash_mode,
- hw_mode,
- digest_size,
- inter_digestsize);
- if (rc != 0)
- {
- FIPS_LOG("ssi_hash_fips_run_test %d returned error - rc = %d \n", i, rc);
- error = FIPS_HashToFipsError(hash_data->hash_mode);
- break;
- }
-
- /* compare actual mac result to expected */
- if (memcmp(virt_ctx->mac_res, hash_data->mac_res, digest_size) != 0)
- {
- FIPS_LOG("comparison error %d - hash_mode=%d digest_size=%d \n", i, hash_data->hash_mode, digest_size);
- FIPS_LOG(" i expected received \n");
- FIPS_LOG(" i 0x%08x 0x%08x \n", (size_t)hash_data->mac_res, (size_t)virt_ctx->mac_res);
- for (i = 0; i < digest_size; ++i)
- {
- FIPS_LOG(" %d 0x%02x 0x%02x \n", i, hash_data->mac_res[i], virt_ctx->mac_res[i]);
- }
-
- error = FIPS_HashToFipsError(hash_data->hash_mode);
- break;
- }
- }
-
- return error;
-}
-
-static inline enum cc_fips_error
-FIPS_HmacToFipsError(enum drv_hash_mode hash_mode)
-{
- switch (hash_mode) {
- case DRV_HASH_SHA1:
- return CC_REE_FIPS_ERROR_HMAC_SHA1_PUT;
- case DRV_HASH_SHA256:
- return CC_REE_FIPS_ERROR_HMAC_SHA256_PUT;
-#if (CC_SUPPORT_SHA > 256)
- case DRV_HASH_SHA512:
- return CC_REE_FIPS_ERROR_HMAC_SHA512_PUT;
-#endif
- default:
- return CC_REE_FIPS_ERROR_GENERAL;
- }
-
- return CC_REE_FIPS_ERROR_GENERAL;
-}
-
-static inline int
-ssi_hmac_fips_run_test(struct ssi_drvdata *drvdata,
- dma_addr_t initial_digest_dma_addr,
- dma_addr_t key_dma_addr,
- size_t key_size,
- dma_addr_t din_dma_addr,
- size_t data_in_size,
- dma_addr_t mac_res_dma_addr,
- enum drv_hash_mode hash_mode,
- enum drv_hash_hw_mode hw_mode,
- size_t digest_size,
- size_t inter_digestsize,
- size_t block_size,
- dma_addr_t k0_dma_addr,
- dma_addr_t tmp_digest_dma_addr,
- dma_addr_t digest_bytes_len_dma_addr)
-{
- /* The implemented flow is not the same as the one implemented in ssi_hash.c (setkey + digest flows).
- * In this flow, there is no need to store and reload some of the intermidiate results.
- */
-
- /* max number of descriptors used for the flow */
- #define FIPS_HMAC_MAX_SEQ_LEN 12
-
- int rc;
- struct ssi_crypto_req ssi_req = {0};
- struct cc_hw_desc desc[FIPS_HMAC_MAX_SEQ_LEN];
- int idx = 0;
- int i;
- /* calc the hash opad first and ipad only afterwards (unlike the flow in ssi_hash.c) */
- unsigned int hmacPadConst[2] = { HMAC_OPAD_CONST, HMAC_IPAD_CONST };
-
- // assume (key_size <= block_size)
- hw_desc_init(&desc[idx]);
- set_din_type(&desc[idx], DMA_DLLI, key_dma_addr, key_size, NS_BIT);
- set_flow_mode(&desc[idx], BYPASS);
- set_dout_dlli(&desc[idx], k0_dma_addr, key_size, NS_BIT, 0);
- idx++;
-
- // if needed, append Key with zeros to create K0
- if ((block_size - key_size) != 0) {
- hw_desc_init(&desc[idx]);
- set_din_const(&desc[idx], 0, (block_size - key_size));
- set_flow_mode(&desc[idx], BYPASS);
- set_dout_dlli(&desc[idx], (k0_dma_addr + key_size),
- (block_size - key_size), NS_BIT, 0);
- idx++;
- }
-
- BUG_ON(idx > FIPS_HMAC_MAX_SEQ_LEN);
- rc = send_request(drvdata, &ssi_req, desc, idx, 0);
- if (unlikely(rc != 0)) {
- SSI_LOG_ERR("send_request() failed (rc=%d)\n", rc);
- return rc;
- }
- idx = 0;
-
- /* calc derived HMAC key */
- for (i = 0; i < 2; i++) {
- /* Load hash initial state */
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], hw_mode);
- set_din_type(&desc[idx], DMA_DLLI, initial_digest_dma_addr,
- inter_digestsize, NS_BIT);
- set_flow_mode(&desc[idx], S_DIN_to_HASH);
- set_setup_mode(&desc[idx], SETUP_LOAD_STATE0);
- idx++;
-
- /* Load the hash current length*/
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], hw_mode);
- set_din_const(&desc[idx], 0, HASH_LEN_SIZE);
- set_flow_mode(&desc[idx], S_DIN_to_HASH);
- set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
- idx++;
-
- /* Prepare opad/ipad key */
- hw_desc_init(&desc[idx]);
- set_xor_val(&desc[idx], hmacPadConst[i]);
- set_cipher_mode(&desc[idx], hw_mode);
- set_flow_mode(&desc[idx], S_DIN_to_HASH);
- set_setup_mode(&desc[idx], SETUP_LOAD_STATE1);
- idx++;
-
- /* Perform HASH update */
- hw_desc_init(&desc[idx]);
- set_din_type(&desc[idx], DMA_DLLI, k0_dma_addr, block_size,
- NS_BIT);
- set_cipher_mode(&desc[idx], hw_mode);
- set_xor_active(&desc[idx]);
- set_flow_mode(&desc[idx], DIN_HASH);
- idx++;
-
- if (i == 0) {
- /* First iteration - calc H(K0^opad) into tmp_digest_dma_addr */
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], hw_mode);
- set_dout_dlli(&desc[idx], tmp_digest_dma_addr,
- inter_digestsize, NS_BIT, 0);
- set_flow_mode(&desc[idx], S_HASH_to_DOUT);
- set_setup_mode(&desc[idx], SETUP_WRITE_STATE0);
- idx++;
-
- // is this needed?? or continue with current descriptors??
- BUG_ON(idx > FIPS_HMAC_MAX_SEQ_LEN);
- rc = send_request(drvdata, &ssi_req, desc, idx, 0);
- if (unlikely(rc != 0)) {
- SSI_LOG_ERR("send_request() failed (rc=%d)\n", rc);
- return rc;
- }
- idx = 0;
- }
- }
-
- /* data descriptor */
- hw_desc_init(&desc[idx]);
- set_din_type(&desc[idx], DMA_DLLI, din_dma_addr, data_in_size, NS_BIT);
- set_flow_mode(&desc[idx], DIN_HASH);
- idx++;
-
- /* HW last hash block padding (aka. "DO_PAD") */
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], hw_mode);
- set_dout_dlli(&desc[idx], k0_dma_addr, HASH_LEN_SIZE, NS_BIT, 0);
- set_flow_mode(&desc[idx], S_HASH_to_DOUT);
- set_setup_mode(&desc[idx], SETUP_WRITE_STATE1);
- set_cipher_do(&desc[idx], DO_PAD);
- idx++;
-
- /* store the hash digest result in the context */
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], hw_mode);
- set_dout_dlli(&desc[idx], k0_dma_addr, digest_size, NS_BIT, 0);
- set_flow_mode(&desc[idx], S_HASH_to_DOUT);
- if (unlikely((hash_mode == DRV_HASH_MD5) ||
- (hash_mode == DRV_HASH_SHA384) ||
- (hash_mode == DRV_HASH_SHA512))) {
- set_bytes_swap(&desc[idx], 1);
- } else {
- set_cipher_config0(&desc[idx],
- HASH_DIGEST_RESULT_LITTLE_ENDIAN);
- }
- set_setup_mode(&desc[idx], SETUP_WRITE_STATE0);
- idx++;
-
- /* at this point:
- * tmp_digest = H(o_key_pad)
- * k0 = H(i_key_pad || m)
- */
-
- /* Loading hash opad xor key state */
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], hw_mode);
- set_din_type(&desc[idx], DMA_DLLI, tmp_digest_dma_addr,
- inter_digestsize, NS_BIT);
- set_flow_mode(&desc[idx], S_DIN_to_HASH);
- set_setup_mode(&desc[idx], SETUP_LOAD_STATE0);
- idx++;
-
- /* Load the hash current length */
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], hw_mode);
- set_din_type(&desc[idx], DMA_DLLI, digest_bytes_len_dma_addr,
- HASH_LEN_SIZE, NS_BIT);
- set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED);
- set_flow_mode(&desc[idx], S_DIN_to_HASH);
- set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
- idx++;
-
- /* Memory Barrier: wait for IPAD/OPAD axi write to complete */
- hw_desc_init(&desc[idx]);
- set_din_no_dma(&desc[idx], 0, 0xfffff0);
- set_dout_no_dma(&desc[idx], 0, 0, 1);
- idx++;
-
- /* Perform HASH update */
- hw_desc_init(&desc[idx]);
- set_din_type(&desc[idx], DMA_DLLI, k0_dma_addr, digest_size, NS_BIT);
- set_flow_mode(&desc[idx], DIN_HASH);
- idx++;
-
- /* Get final MAC result */
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], hw_mode);
- set_dout_dlli(&desc[idx], mac_res_dma_addr, digest_size, NS_BIT, 0);
- set_flow_mode(&desc[idx], S_HASH_to_DOUT);
- set_setup_mode(&desc[idx], SETUP_WRITE_STATE0);
- set_cipher_config1(&desc[idx], HASH_PADDING_DISABLED);
- if (unlikely((hash_mode == DRV_HASH_MD5) ||
- (hash_mode == DRV_HASH_SHA384) ||
- (hash_mode == DRV_HASH_SHA512))) {
- set_bytes_swap(&desc[idx], 1);
- } else {
- set_cipher_config0(&desc[idx],
- HASH_DIGEST_RESULT_LITTLE_ENDIAN);
- }
- idx++;
-
- /* perform the operation - Lock HW and push sequence */
- BUG_ON(idx > FIPS_HMAC_MAX_SEQ_LEN);
- rc = send_request(drvdata, &ssi_req, desc, idx, false);
-
- return rc;
-}
-
-enum cc_fips_error
-ssi_hmac_fips_power_up_tests(struct ssi_drvdata *drvdata, void *cpu_addr_buffer, dma_addr_t dma_coherent_buffer)
-{
- enum cc_fips_error error = CC_REE_FIPS_ERROR_OK;
- size_t i;
- struct fips_hmac_ctx *virt_ctx = (struct fips_hmac_ctx *)cpu_addr_buffer;
-
- /* set the phisical pointers */
- dma_addr_t initial_digest_dma_addr = dma_coherent_buffer + offsetof(struct fips_hmac_ctx, initial_digest);
- dma_addr_t key_dma_addr = dma_coherent_buffer + offsetof(struct fips_hmac_ctx, key);
- dma_addr_t k0_dma_addr = dma_coherent_buffer + offsetof(struct fips_hmac_ctx, k0);
- dma_addr_t tmp_digest_dma_addr = dma_coherent_buffer + offsetof(struct fips_hmac_ctx, tmp_digest);
- dma_addr_t digest_bytes_len_dma_addr = dma_coherent_buffer + offsetof(struct fips_hmac_ctx, digest_bytes_len);
- dma_addr_t din_dma_addr = dma_coherent_buffer + offsetof(struct fips_hmac_ctx, din);
- dma_addr_t mac_res_dma_addr = dma_coherent_buffer + offsetof(struct fips_hmac_ctx, mac_res);
-
- for (i = 0; i < FIPS_HMAC_NUM_OF_TESTS; ++i)
- {
- FipsHmacData *hmac_data = (FipsHmacData *)&FipsHmacDataTable[i];
- int rc = 0;
- enum drv_hash_hw_mode hw_mode = 0;
- int digest_size = 0;
- int block_size = 0;
- int inter_digestsize = 0;
-
- memset(cpu_addr_buffer, 0, sizeof(struct fips_hmac_ctx));
-
- switch (hmac_data->hash_mode) {
- case DRV_HASH_SHA1:
- hw_mode = DRV_HASH_HW_SHA1;
- digest_size = CC_SHA1_DIGEST_SIZE;
- block_size = CC_SHA1_BLOCK_SIZE;
- inter_digestsize = CC_SHA1_DIGEST_SIZE;
- memcpy(virt_ctx->initial_digest, (void *)sha1_init, CC_SHA1_DIGEST_SIZE);
- memcpy(virt_ctx->digest_bytes_len, digest_len_init, HASH_LEN_SIZE);
- break;
- case DRV_HASH_SHA256:
- hw_mode = DRV_HASH_HW_SHA256;
- digest_size = CC_SHA256_DIGEST_SIZE;
- block_size = CC_SHA256_BLOCK_SIZE;
- inter_digestsize = CC_SHA256_DIGEST_SIZE;
- memcpy(virt_ctx->initial_digest, (void *)sha256_init, CC_SHA256_DIGEST_SIZE);
- memcpy(virt_ctx->digest_bytes_len, digest_len_init, HASH_LEN_SIZE);
- break;
-#if (CC_SUPPORT_SHA > 256)
- case DRV_HASH_SHA512:
- hw_mode = DRV_HASH_HW_SHA512;
- digest_size = CC_SHA512_DIGEST_SIZE;
- block_size = CC_SHA512_BLOCK_SIZE;
- inter_digestsize = CC_SHA512_DIGEST_SIZE;
- memcpy(virt_ctx->initial_digest, (void *)sha512_init, CC_SHA512_DIGEST_SIZE);
- memcpy(virt_ctx->digest_bytes_len, digest_len_sha512_init, HASH_LEN_SIZE);
- break;
-#endif
- default:
- error = FIPS_HmacToFipsError(hmac_data->hash_mode);
- break;
- }
-
- /* copy into the allocated buffer */
- memcpy(virt_ctx->key, hmac_data->key, hmac_data->key_size);
- memcpy(virt_ctx->din, hmac_data->data_in, hmac_data->data_in_size);
-
- /* run the test on HW */
- FIPS_DBG("ssi_hmac_fips_run_test - (i = %d) \n", i);
- rc = ssi_hmac_fips_run_test(drvdata,
- initial_digest_dma_addr,
- key_dma_addr,
- hmac_data->key_size,
- din_dma_addr,
- hmac_data->data_in_size,
- mac_res_dma_addr,
- hmac_data->hash_mode,
- hw_mode,
- digest_size,
- inter_digestsize,
- block_size,
- k0_dma_addr,
- tmp_digest_dma_addr,
- digest_bytes_len_dma_addr);
- if (rc != 0)
- {
- FIPS_LOG("ssi_hmac_fips_run_test %d returned error - rc = %d \n", i, rc);
- error = FIPS_HmacToFipsError(hmac_data->hash_mode);
- break;
- }
-
- /* compare actual mac result to expected */
- if (memcmp(virt_ctx->mac_res, hmac_data->mac_res, digest_size) != 0)
- {
- FIPS_LOG("comparison error %d - hash_mode=%d digest_size=%d \n", i, hmac_data->hash_mode, digest_size);
- FIPS_LOG(" i expected received \n");
- FIPS_LOG(" i 0x%08x 0x%08x \n", (size_t)hmac_data->mac_res, (size_t)virt_ctx->mac_res);
- for (i = 0; i < digest_size; ++i)
- {
- FIPS_LOG(" %d 0x%02x 0x%02x \n", i, hmac_data->mac_res[i], virt_ctx->mac_res[i]);
- }
-
- error = FIPS_HmacToFipsError(hmac_data->hash_mode);
- break;
- }
- }
-
- return error;
-}
-
-static inline int
-ssi_ccm_fips_run_test(struct ssi_drvdata *drvdata,
- enum drv_crypto_direction direction,
- dma_addr_t key_dma_addr,
- size_t key_size,
- dma_addr_t iv_dma_addr,
- dma_addr_t ctr_cnt_0_dma_addr,
- dma_addr_t b0_a0_adata_dma_addr,
- size_t b0_a0_adata_size,
- dma_addr_t din_dma_addr,
- size_t din_size,
- dma_addr_t dout_dma_addr,
- dma_addr_t mac_res_dma_addr)
-{
- /* max number of descriptors used for the flow */
- #define FIPS_CCM_MAX_SEQ_LEN 10
-
- int rc;
- struct ssi_crypto_req ssi_req = {0};
- struct cc_hw_desc desc[FIPS_CCM_MAX_SEQ_LEN];
- unsigned int idx = 0;
- unsigned int cipher_flow_mode;
-
- if (direction == DRV_CRYPTO_DIRECTION_DECRYPT) {
- cipher_flow_mode = AES_to_HASH_and_DOUT;
- } else { /* Encrypt */
- cipher_flow_mode = AES_and_HASH;
- }
-
- /* load key */
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], DRV_CIPHER_CTR);
- set_din_type(&desc[idx], DMA_DLLI, key_dma_addr,
- ((key_size == NIST_AESCCM_192_BIT_KEY_SIZE) ?
- CC_AES_KEY_SIZE_MAX : key_size), NS_BIT)
- set_key_size_aes(&desc[idx], key_size);
- set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
- set_cipher_config0(&desc[idx], DESC_DIRECTION_ENCRYPT_ENCRYPT);
- set_flow_mode(&desc[idx], S_DIN_to_AES);
- idx++;
-
- /* load ctr state */
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], DRV_CIPHER_CTR);
- set_key_size_aes(&desc[idx], key_size);
- set_din_type(&desc[idx], DMA_DLLI, iv_dma_addr, AES_BLOCK_SIZE,
- NS_BIT);
- set_cipher_config0(&desc[idx], DESC_DIRECTION_ENCRYPT_ENCRYPT);
- set_setup_mode(&desc[idx], SETUP_LOAD_STATE1);
- set_flow_mode(&desc[idx], S_DIN_to_AES);
- idx++;
-
- /* load MAC key */
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], DRV_CIPHER_CBC_MAC);
- set_din_type(&desc[idx], DMA_DLLI, key_dma_addr,
- ((key_size == NIST_AESCCM_192_BIT_KEY_SIZE) ?
- CC_AES_KEY_SIZE_MAX : key_size), NS_BIT);
- set_key_size_aes(&desc[idx], key_size);
- set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
- set_cipher_config0(&desc[idx], DESC_DIRECTION_ENCRYPT_ENCRYPT);
- set_flow_mode(&desc[idx], S_DIN_to_HASH);
- set_aes_not_hash_mode(&desc[idx]);
- idx++;
-
- /* load MAC state */
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], DRV_CIPHER_CBC_MAC);
- set_key_size_aes(&desc[idx], key_size);
- set_din_type(&desc[idx], DMA_DLLI, mac_res_dma_addr,
- NIST_AESCCM_TAG_SIZE, NS_BIT);
- set_cipher_config0(&desc[idx], DESC_DIRECTION_ENCRYPT_ENCRYPT);
- set_setup_mode(&desc[idx], SETUP_LOAD_STATE0);
- set_flow_mode(&desc[idx], S_DIN_to_HASH);
- set_aes_not_hash_mode(&desc[idx]);
- idx++;
-
- /* prcess assoc data */
- hw_desc_init(&desc[idx]);
- set_din_type(&desc[idx], DMA_DLLI, b0_a0_adata_dma_addr,
- b0_a0_adata_size, NS_BIT);
- set_flow_mode(&desc[idx], DIN_HASH);
- idx++;
-
- /* process the cipher */
- hw_desc_init(&desc[idx]);
- set_din_type(&desc[idx], DMA_DLLI, din_dma_addr, din_size, NS_BIT);
- set_dout_dlli(&desc[idx], dout_dma_addr, din_size, NS_BIT, 0);
- set_flow_mode(&desc[idx], cipher_flow_mode);
- idx++;
-
- /* Read temporal MAC */
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], DRV_CIPHER_CBC_MAC);
- set_dout_dlli(&desc[idx], mac_res_dma_addr, NIST_AESCCM_TAG_SIZE,
- NS_BIT, 0);
- set_setup_mode(&desc[idx], SETUP_WRITE_STATE0);
- set_cipher_config0(&desc[idx], HASH_DIGEST_RESULT_LITTLE_ENDIAN);
- set_flow_mode(&desc[idx], S_HASH_to_DOUT);
- set_aes_not_hash_mode(&desc[idx]);
- idx++;
-
- /* load AES-CTR state (for last MAC calculation)*/
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], DRV_CIPHER_CTR);
- set_cipher_config0(&desc[idx], DRV_CRYPTO_DIRECTION_ENCRYPT);
- set_din_type(&desc[idx], DMA_DLLI, ctr_cnt_0_dma_addr, AES_BLOCK_SIZE,
- NS_BIT);
- set_key_size_aes(&desc[idx], key_size);
- set_setup_mode(&desc[idx], SETUP_LOAD_STATE1);
- set_flow_mode(&desc[idx], S_DIN_to_AES);
- idx++;
-
- /* Memory Barrier */
- hw_desc_init(&desc[idx]);
- set_din_no_dma(&desc[idx], 0, 0xfffff0);
- set_dout_no_dma(&desc[idx], 0, 0, 1);
- idx++;
-
- /* encrypt the "T" value and store MAC inplace */
- hw_desc_init(&desc[idx]);
- set_din_type(&desc[idx], DMA_DLLI, mac_res_dma_addr,
- NIST_AESCCM_TAG_SIZE, NS_BIT);
- set_dout_dlli(&desc[idx], mac_res_dma_addr, NIST_AESCCM_TAG_SIZE,
- NS_BIT, 0);
- set_flow_mode(&desc[idx], DIN_AES_DOUT);
- idx++;
-
- /* perform the operation - Lock HW and push sequence */
- BUG_ON(idx > FIPS_CCM_MAX_SEQ_LEN);
- rc = send_request(drvdata, &ssi_req, desc, idx, false);
-
- return rc;
-}
-
-enum cc_fips_error
-ssi_ccm_fips_power_up_tests(struct ssi_drvdata *drvdata, void *cpu_addr_buffer, dma_addr_t dma_coherent_buffer)
-{
- enum cc_fips_error error = CC_REE_FIPS_ERROR_OK;
- size_t i;
- struct fips_ccm_ctx *virt_ctx = (struct fips_ccm_ctx *)cpu_addr_buffer;
-
- /* set the phisical pointers */
- dma_addr_t b0_a0_adata_dma_addr = dma_coherent_buffer + offsetof(struct fips_ccm_ctx, b0_a0_adata);
- dma_addr_t iv_dma_addr = dma_coherent_buffer + offsetof(struct fips_ccm_ctx, iv);
- dma_addr_t ctr_cnt_0_dma_addr = dma_coherent_buffer + offsetof(struct fips_ccm_ctx, ctr_cnt_0);
- dma_addr_t key_dma_addr = dma_coherent_buffer + offsetof(struct fips_ccm_ctx, key);
- dma_addr_t din_dma_addr = dma_coherent_buffer + offsetof(struct fips_ccm_ctx, din);
- dma_addr_t dout_dma_addr = dma_coherent_buffer + offsetof(struct fips_ccm_ctx, dout);
- dma_addr_t mac_res_dma_addr = dma_coherent_buffer + offsetof(struct fips_ccm_ctx, mac_res);
-
- for (i = 0; i < FIPS_CCM_NUM_OF_TESTS; ++i)
- {
- FipsCcmData *ccmData = (FipsCcmData *)&FipsCcmDataTable[i];
- int rc = 0;
-
- memset(cpu_addr_buffer, 0, sizeof(struct fips_ccm_ctx));
-
- /* copy the nonce, key, adata, din data into the allocated buffer */
- memcpy(virt_ctx->key, ccmData->key, ccmData->keySize);
- memcpy(virt_ctx->din, ccmData->dataIn, ccmData->dataInSize);
- {
- /* build B0 -- B0, nonce, l(m) */
- __be16 data = cpu_to_be16(NIST_AESCCM_TEXT_SIZE);
-
- virt_ctx->b0_a0_adata[0] = NIST_AESCCM_B0_VAL;
- memcpy(virt_ctx->b0_a0_adata + 1, ccmData->nonce, NIST_AESCCM_NONCE_SIZE);
- memcpy(virt_ctx->b0_a0_adata + 14, (u8 *)&data, sizeof(__be16));
- /* build A0+ADATA */
- virt_ctx->b0_a0_adata[NIST_AESCCM_IV_SIZE + 0] = (ccmData->adataSize >> 8) & 0xFF;
- virt_ctx->b0_a0_adata[NIST_AESCCM_IV_SIZE + 1] = ccmData->adataSize & 0xFF;
- memcpy(virt_ctx->b0_a0_adata + NIST_AESCCM_IV_SIZE + 2, ccmData->adata, ccmData->adataSize);
- /* iv */
- virt_ctx->iv[0] = 1; /* L' */
- memcpy(virt_ctx->iv + 1, ccmData->nonce, NIST_AESCCM_NONCE_SIZE);
- virt_ctx->iv[15] = 1;
- /* ctr_count_0 */
- memcpy(virt_ctx->ctr_cnt_0, virt_ctx->iv, NIST_AESCCM_IV_SIZE);
- virt_ctx->ctr_cnt_0[15] = 0;
- }
-
- FIPS_DBG("ssi_ccm_fips_run_test - (i = %d) \n", i);
- rc = ssi_ccm_fips_run_test(drvdata,
- ccmData->direction,
- key_dma_addr,
- ccmData->keySize,
- iv_dma_addr,
- ctr_cnt_0_dma_addr,
- b0_a0_adata_dma_addr,
- FIPS_CCM_B0_A0_ADATA_SIZE,
- din_dma_addr,
- ccmData->dataInSize,
- dout_dma_addr,
- mac_res_dma_addr);
- if (rc != 0)
- {
- FIPS_LOG("ssi_ccm_fips_run_test %d returned error - rc = %d \n", i, rc);
- error = CC_REE_FIPS_ERROR_AESCCM_PUT;
- break;
- }
-
- /* compare actual dout to expected */
- if (memcmp(virt_ctx->dout, ccmData->dataOut, ccmData->dataInSize) != 0)
- {
- FIPS_LOG("dout comparison error %d - size=%d \n", i, ccmData->dataInSize);
- error = CC_REE_FIPS_ERROR_AESCCM_PUT;
- break;
- }
-
- /* compare actual mac result to expected */
- if (memcmp(virt_ctx->mac_res, ccmData->macResOut, ccmData->tagSize) != 0)
- {
- FIPS_LOG("mac_res comparison error %d - mac_size=%d \n", i, ccmData->tagSize);
- FIPS_LOG(" i expected received \n");
- FIPS_LOG(" i 0x%08x 0x%08x \n", (size_t)ccmData->macResOut, (size_t)virt_ctx->mac_res);
- for (i = 0; i < ccmData->tagSize; ++i)
- {
- FIPS_LOG(" %d 0x%02x 0x%02x \n", i, ccmData->macResOut[i], virt_ctx->mac_res[i]);
- }
-
- error = CC_REE_FIPS_ERROR_AESCCM_PUT;
- break;
- }
- }
-
- return error;
-}
-
-static inline int
-ssi_gcm_fips_run_test(struct ssi_drvdata *drvdata,
- enum drv_crypto_direction direction,
- dma_addr_t key_dma_addr,
- size_t key_size,
- dma_addr_t hkey_dma_addr,
- dma_addr_t block_len_dma_addr,
- dma_addr_t iv_inc1_dma_addr,
- dma_addr_t iv_inc2_dma_addr,
- dma_addr_t adata_dma_addr,
- size_t adata_size,
- dma_addr_t din_dma_addr,
- size_t din_size,
- dma_addr_t dout_dma_addr,
- dma_addr_t mac_res_dma_addr)
-{
- /* max number of descriptors used for the flow */
- #define FIPS_GCM_MAX_SEQ_LEN 15
-
- int rc;
- struct ssi_crypto_req ssi_req = {0};
- struct cc_hw_desc desc[FIPS_GCM_MAX_SEQ_LEN];
- unsigned int idx = 0;
- unsigned int cipher_flow_mode;
-
- if (direction == DRV_CRYPTO_DIRECTION_DECRYPT) {
- cipher_flow_mode = AES_and_HASH;
- } else { /* Encrypt */
- cipher_flow_mode = AES_to_HASH_and_DOUT;
- }
-
-///////////////////////////////// 1 ////////////////////////////////////
-// ssi_aead_gcm_setup_ghash_desc(req, desc, seq_size);
-///////////////////////////////// 1 ////////////////////////////////////
-
- /* load key to AES */
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], DRV_CIPHER_ECB);
- set_cipher_config0(&desc[idx], DRV_CRYPTO_DIRECTION_ENCRYPT);
- set_din_type(&desc[idx], DMA_DLLI, key_dma_addr, key_size, NS_BIT);
- set_key_size_aes(&desc[idx], key_size);
- set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
- set_flow_mode(&desc[idx], S_DIN_to_AES);
- idx++;
-
- /* process one zero block to generate hkey */
- hw_desc_init(&desc[idx]);
- set_din_const(&desc[idx], 0x0, AES_BLOCK_SIZE);
- set_dout_dlli(&desc[idx], hkey_dma_addr, AES_BLOCK_SIZE, NS_BIT, 0);
- set_flow_mode(&desc[idx], DIN_AES_DOUT);
- idx++;
-
- /* Memory Barrier */
- hw_desc_init(&desc[idx]);
- set_din_no_dma(&desc[idx], 0, 0xfffff0);
- set_dout_no_dma(&desc[idx], 0, 0, 1);
- idx++;
-
- /* Load GHASH subkey */
- hw_desc_init(&desc[idx]);
- set_din_type(&desc[idx], DMA_DLLI, hkey_dma_addr, AES_BLOCK_SIZE,
- NS_BIT);
- set_dout_no_dma(&desc[idx], 0, 0, 1);
- set_flow_mode(&desc[idx], S_DIN_to_HASH);
- set_aes_not_hash_mode(&desc[idx]);
- set_cipher_mode(&desc[idx], DRV_HASH_HW_GHASH);
- set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED);
- set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
- idx++;
-
- /* Configure Hash Engine to work with GHASH.
- * Since it was not possible to extend HASH submodes to add GHASH,
- * The following command is necessary in order to
- * select GHASH (according to HW designers)
- */
- hw_desc_init(&desc[idx]);
- set_din_no_dma(&desc[idx], 0, 0xfffff0);
- set_dout_no_dma(&desc[idx], 0, 0, 1);
- set_flow_mode(&desc[idx], S_DIN_to_HASH);
- set_aes_not_hash_mode(&desc[idx]);
- set_cipher_mode(&desc[idx], DRV_HASH_HW_GHASH);
- set_cipher_do(&desc[idx], 1); //1=AES_SK RKEK
- set_cipher_config0(&desc[idx], DRV_CRYPTO_DIRECTION_ENCRYPT);
- set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED);
- set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
- idx++;
-
- /* Load GHASH initial STATE (which is 0). (for any hash there is an initial state) */
- hw_desc_init(&desc[idx]);
- set_din_const(&desc[idx], 0x0, AES_BLOCK_SIZE);
- set_dout_no_dma(&desc[idx], 0, 0, 1);
- set_flow_mode(&desc[idx], S_DIN_to_HASH);
- set_aes_not_hash_mode(&desc[idx]);
- set_cipher_mode(&desc[idx], DRV_HASH_HW_GHASH);
- set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED);
- set_setup_mode(&desc[idx], SETUP_LOAD_STATE0);
- idx++;
-
-///////////////////////////////// 2 ////////////////////////////////////
- /* prcess(ghash) assoc data */
-// if (req->assoclen > 0)
-// ssi_aead_create_assoc_desc(req, DIN_HASH, desc, seq_size);
-///////////////////////////////// 2 ////////////////////////////////////
-
- hw_desc_init(&desc[idx]);
- set_din_type(&desc[idx], DMA_DLLI, adata_dma_addr, adata_size, NS_BIT);
- set_flow_mode(&desc[idx], DIN_HASH);
- idx++;
-
-///////////////////////////////// 3 ////////////////////////////////////
-// ssi_aead_gcm_setup_gctr_desc(req, desc, seq_size);
-///////////////////////////////// 3 ////////////////////////////////////
-
- /* load key to AES*/
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], DRV_CIPHER_GCTR);
- set_cipher_config0(&desc[idx], DRV_CRYPTO_DIRECTION_ENCRYPT);
- set_din_type(&desc[idx], DMA_DLLI, key_dma_addr, key_size, NS_BIT);
- set_key_size_aes(&desc[idx], key_size);
- set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
- set_flow_mode(&desc[idx], S_DIN_to_AES);
- idx++;
-
- /* load AES/CTR initial CTR value inc by 2*/
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], DRV_CIPHER_GCTR);
- set_key_size_aes(&desc[idx], key_size);
- set_din_type(&desc[idx], DMA_DLLI, iv_inc2_dma_addr, AES_BLOCK_SIZE,
- NS_BIT);
- set_cipher_config0(&desc[idx], DRV_CRYPTO_DIRECTION_ENCRYPT);
- set_setup_mode(&desc[idx], SETUP_LOAD_STATE1);
- set_flow_mode(&desc[idx], S_DIN_to_AES);
- idx++;
-
-///////////////////////////////// 4 ////////////////////////////////////
- /* process(gctr+ghash) */
-// if (req_ctx->cryptlen != 0)
-// ssi_aead_process_cipher_data_desc(req, cipher_flow_mode, desc, seq_size);
-///////////////////////////////// 4 ////////////////////////////////////
-
- hw_desc_init(&desc[idx]);
- set_din_type(&desc[idx], DMA_DLLI, din_dma_addr, din_size, NS_BIT);
- set_dout_dlli(&desc[idx], dout_dma_addr, din_size, NS_BIT, 0);
- set_flow_mode(&desc[idx], cipher_flow_mode);
- idx++;
-
-///////////////////////////////// 5 ////////////////////////////////////
-// ssi_aead_process_gcm_result_desc(req, desc, seq_size);
-///////////////////////////////// 5 ////////////////////////////////////
-
- /* prcess(ghash) gcm_block_len */
- hw_desc_init(&desc[idx]);
- set_din_type(&desc[idx], DMA_DLLI, block_len_dma_addr, AES_BLOCK_SIZE,
- NS_BIT);
- set_flow_mode(&desc[idx], DIN_HASH);
- idx++;
-
- /* Store GHASH state after GHASH(Associated Data + Cipher +LenBlock) */
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], DRV_HASH_HW_GHASH);
- set_din_no_dma(&desc[idx], 0, 0xfffff0);
- set_dout_dlli(&desc[idx], mac_res_dma_addr, AES_BLOCK_SIZE, NS_BIT, 0);
- set_setup_mode(&desc[idx], SETUP_WRITE_STATE0);
- set_flow_mode(&desc[idx], S_HASH_to_DOUT);
- set_aes_not_hash_mode(&desc[idx]);
- idx++;
-
- /* load AES/CTR initial CTR value inc by 1*/
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], DRV_CIPHER_GCTR);
- set_key_size_aes(&desc[idx], key_size);
- set_din_type(&desc[idx], DMA_DLLI, iv_inc1_dma_addr, AES_BLOCK_SIZE,
- NS_BIT);
- set_cipher_config0(&desc[idx], DRV_CRYPTO_DIRECTION_ENCRYPT);
- set_setup_mode(&desc[idx], SETUP_LOAD_STATE1);
- set_flow_mode(&desc[idx], S_DIN_to_AES);
- idx++;
-
- /* Memory Barrier */
- hw_desc_init(&desc[idx]);
- set_din_no_dma(&desc[idx], 0, 0xfffff0);
- set_dout_no_dma(&desc[idx], 0, 0, 1);
- idx++;
-
- /* process GCTR on stored GHASH and store MAC inplace */
- hw_desc_init(&desc[idx]);
- set_cipher_mode(&desc[idx], DRV_CIPHER_GCTR);
- set_din_type(&desc[idx], DMA_DLLI, mac_res_dma_addr, AES_BLOCK_SIZE,
- NS_BIT);
- set_dout_dlli(&desc[idx], mac_res_dma_addr, AES_BLOCK_SIZE, NS_BIT, 0);
- set_flow_mode(&desc[idx], DIN_AES_DOUT);
- idx++;
-
- /* perform the operation - Lock HW and push sequence */
- BUG_ON(idx > FIPS_GCM_MAX_SEQ_LEN);
- rc = send_request(drvdata, &ssi_req, desc, idx, false);
-
- return rc;
-}
-
-enum cc_fips_error
-ssi_gcm_fips_power_up_tests(struct ssi_drvdata *drvdata, void *cpu_addr_buffer, dma_addr_t dma_coherent_buffer)
-{
- enum cc_fips_error error = CC_REE_FIPS_ERROR_OK;
- size_t i;
- struct fips_gcm_ctx *virt_ctx = (struct fips_gcm_ctx *)cpu_addr_buffer;
-
- /* set the phisical pointers */
- dma_addr_t adata_dma_addr = dma_coherent_buffer + offsetof(struct fips_gcm_ctx, adata);
- dma_addr_t key_dma_addr = dma_coherent_buffer + offsetof(struct fips_gcm_ctx, key);
- dma_addr_t hkey_dma_addr = dma_coherent_buffer + offsetof(struct fips_gcm_ctx, hkey);
- dma_addr_t din_dma_addr = dma_coherent_buffer + offsetof(struct fips_gcm_ctx, din);
- dma_addr_t dout_dma_addr = dma_coherent_buffer + offsetof(struct fips_gcm_ctx, dout);
- dma_addr_t mac_res_dma_addr = dma_coherent_buffer + offsetof(struct fips_gcm_ctx, mac_res);
- dma_addr_t len_block_dma_addr = dma_coherent_buffer + offsetof(struct fips_gcm_ctx, len_block);
- dma_addr_t iv_inc1_dma_addr = dma_coherent_buffer + offsetof(struct fips_gcm_ctx, iv_inc1);
- dma_addr_t iv_inc2_dma_addr = dma_coherent_buffer + offsetof(struct fips_gcm_ctx, iv_inc2);
-
- for (i = 0; i < FIPS_GCM_NUM_OF_TESTS; ++i)
- {
- FipsGcmData *gcmData = (FipsGcmData *)&FipsGcmDataTable[i];
- int rc = 0;
-
- memset(cpu_addr_buffer, 0, sizeof(struct fips_gcm_ctx));
-
- /* copy the key, adata, din data - into the allocated buffer */
- memcpy(virt_ctx->key, gcmData->key, gcmData->keySize);
- memcpy(virt_ctx->adata, gcmData->adata, gcmData->adataSize);
- memcpy(virt_ctx->din, gcmData->dataIn, gcmData->dataInSize);
-
- /* len_block */
- {
- __be64 len_bits;
-
- len_bits = cpu_to_be64(gcmData->adataSize * 8);
- memcpy(virt_ctx->len_block, &len_bits, sizeof(len_bits));
- len_bits = cpu_to_be64(gcmData->dataInSize * 8);
- memcpy(virt_ctx->len_block + 8, &len_bits, sizeof(len_bits));
- }
- /* iv_inc1, iv_inc2 */
- {
- __be32 counter = cpu_to_be32(1);
-
- memcpy(virt_ctx->iv_inc1, gcmData->iv, NIST_AESGCM_IV_SIZE);
- memcpy(virt_ctx->iv_inc1 + NIST_AESGCM_IV_SIZE, &counter, sizeof(counter));
- counter = cpu_to_be32(2);
- memcpy(virt_ctx->iv_inc2, gcmData->iv, NIST_AESGCM_IV_SIZE);
- memcpy(virt_ctx->iv_inc2 + NIST_AESGCM_IV_SIZE, &counter, sizeof(counter));
- }
-
- FIPS_DBG("ssi_gcm_fips_run_test - (i = %d) \n", i);
- rc = ssi_gcm_fips_run_test(drvdata,
- gcmData->direction,
- key_dma_addr,
- gcmData->keySize,
- hkey_dma_addr,
- len_block_dma_addr,
- iv_inc1_dma_addr,
- iv_inc2_dma_addr,
- adata_dma_addr,
- gcmData->adataSize,
- din_dma_addr,
- gcmData->dataInSize,
- dout_dma_addr,
- mac_res_dma_addr);
- if (rc != 0)
- {
- FIPS_LOG("ssi_gcm_fips_run_test %d returned error - rc = %d \n", i, rc);
- error = CC_REE_FIPS_ERROR_AESGCM_PUT;
- break;
- }
-
- if (gcmData->direction == DRV_CRYPTO_DIRECTION_ENCRYPT) {
- /* compare actual dout to expected */
- if (memcmp(virt_ctx->dout, gcmData->dataOut, gcmData->dataInSize) != 0)
- {
- FIPS_LOG("dout comparison error %d - size=%d \n", i, gcmData->dataInSize);
- FIPS_LOG(" i expected received \n");
- FIPS_LOG(" i 0x%08x 0x%08x \n", (size_t)gcmData->dataOut, (size_t)virt_ctx->dout);
- for (i = 0; i < gcmData->dataInSize; ++i)
- {
- FIPS_LOG(" %d 0x%02x 0x%02x \n", i, gcmData->dataOut[i], virt_ctx->dout[i]);
- }
-
- error = CC_REE_FIPS_ERROR_AESGCM_PUT;
- break;
- }
- }
-
- /* compare actual mac result to expected */
- if (memcmp(virt_ctx->mac_res, gcmData->macResOut, gcmData->tagSize) != 0)
- {
- FIPS_LOG("mac_res comparison error %d - mac_size=%d \n", i, gcmData->tagSize);
- FIPS_LOG(" i expected received \n");
- FIPS_LOG(" i 0x%08x 0x%08x \n", (size_t)gcmData->macResOut, (size_t)virt_ctx->mac_res);
- for (i = 0; i < gcmData->tagSize; ++i)
- {
- FIPS_LOG(" %d 0x%02x 0x%02x \n", i, gcmData->macResOut[i], virt_ctx->mac_res[i]);
- }
-
- error = CC_REE_FIPS_ERROR_AESGCM_PUT;
- break;
- }
- }
- return error;
-}
-
-size_t ssi_fips_max_mem_alloc_size(void)
-{
- FIPS_DBG("sizeof(struct fips_cipher_ctx) %d \n", sizeof(struct fips_cipher_ctx));
- FIPS_DBG("sizeof(struct fips_cmac_ctx) %d \n", sizeof(struct fips_cmac_ctx));
- FIPS_DBG("sizeof(struct fips_hash_ctx) %d \n", sizeof(struct fips_hash_ctx));
- FIPS_DBG("sizeof(struct fips_hmac_ctx) %d \n", sizeof(struct fips_hmac_ctx));
- FIPS_DBG("sizeof(struct fips_ccm_ctx) %d \n", sizeof(struct fips_ccm_ctx));
- FIPS_DBG("sizeof(struct fips_gcm_ctx) %d \n", sizeof(struct fips_gcm_ctx));
-
- return sizeof(fips_ctx);
-}
-
diff --git a/drivers/staging/ccree/ssi_fips_local.c b/drivers/staging/ccree/ssi_fips_local.c
deleted file mode 100644
index aefb71d..0000000
--- a/drivers/staging/ccree/ssi_fips_local.c
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Copyright (C) 2012-2017 ARM Limited or its affiliates.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/**************************************************************
- * This file defines the driver FIPS internal function, used by the driver itself.
- ***************************************************************/
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <crypto/des.h>
-
-#include "ssi_config.h"
-#include "ssi_driver.h"
-#include "cc_hal.h"
-
-#define FIPS_POWER_UP_TEST_CIPHER 1
-#define FIPS_POWER_UP_TEST_CMAC 1
-#define FIPS_POWER_UP_TEST_HASH 1
-#define FIPS_POWER_UP_TEST_HMAC 1
-#define FIPS_POWER_UP_TEST_CCM 1
-#define FIPS_POWER_UP_TEST_GCM 1
-
-static bool ssi_fips_support = 1;
-module_param(ssi_fips_support, bool, 0644);
-MODULE_PARM_DESC(ssi_fips_support, "FIPS supported flag: 0 - off , 1 - on (default)");
-
-static void fips_dsr(unsigned long devarg);
-
-struct ssi_fips_handle {
-#ifdef COMP_IN_WQ
- struct workqueue_struct *workq;
- struct delayed_work fipswork;
-#else
- struct tasklet_struct fipstask;
-#endif
-};
-
-extern int ssi_fips_get_state(enum cc_fips_state_t *p_state);
-extern int ssi_fips_get_error(enum cc_fips_error *p_err);
-extern int ssi_fips_ext_set_state(enum cc_fips_state_t state);
-extern int ssi_fips_ext_set_error(enum cc_fips_error err);
-
-/* FIPS power-up tests */
-extern enum cc_fips_error ssi_cipher_fips_power_up_tests(struct ssi_drvdata *drvdata, void *cpu_addr_buffer, dma_addr_t dma_coherent_buffer);
-extern enum cc_fips_error ssi_cmac_fips_power_up_tests(struct ssi_drvdata *drvdata, void *cpu_addr_buffer, dma_addr_t dma_coherent_buffer);
-extern enum cc_fips_error ssi_hash_fips_power_up_tests(struct ssi_drvdata *drvdata, void *cpu_addr_buffer, dma_addr_t dma_coherent_buffer);
-extern enum cc_fips_error ssi_hmac_fips_power_up_tests(struct ssi_drvdata *drvdata, void *cpu_addr_buffer, dma_addr_t dma_coherent_buffer);
-extern enum cc_fips_error ssi_ccm_fips_power_up_tests(struct ssi_drvdata *drvdata, void *cpu_addr_buffer, dma_addr_t dma_coherent_buffer);
-extern enum cc_fips_error ssi_gcm_fips_power_up_tests(struct ssi_drvdata *drvdata, void *cpu_addr_buffer, dma_addr_t dma_coherent_buffer);
-extern size_t ssi_fips_max_mem_alloc_size(void);
-
-/* The function called once at driver entry point to check whether TEE FIPS error occured.*/
-static enum ssi_fips_error ssi_fips_get_tee_error(struct ssi_drvdata *drvdata)
-{
- u32 regVal;
- void __iomem *cc_base = drvdata->cc_base;
-
- regVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, GPR_HOST));
- if (regVal == (CC_FIPS_SYNC_TEE_STATUS | CC_FIPS_SYNC_MODULE_OK))
- return CC_REE_FIPS_ERROR_OK;
-
- return CC_REE_FIPS_ERROR_FROM_TEE;
-}
-
-/*
- * This function should push the FIPS REE library status towards the TEE library.
- * By writing the error state to HOST_GPR0 register. The function is called from
- * driver entry point so no need to protect by mutex.
- */
-static void ssi_fips_update_tee_upon_ree_status(struct ssi_drvdata *drvdata, enum cc_fips_error err)
-{
- void __iomem *cc_base = drvdata->cc_base;
-
- if (err == CC_REE_FIPS_ERROR_OK)
- CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_GPR0), (CC_FIPS_SYNC_REE_STATUS | CC_FIPS_SYNC_MODULE_OK));
- else
- CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_GPR0), (CC_FIPS_SYNC_REE_STATUS | CC_FIPS_SYNC_MODULE_ERROR));
-}
-
-void ssi_fips_fini(struct ssi_drvdata *drvdata)
-{
- struct ssi_fips_handle *fips_h = drvdata->fips_handle;
-
- if (!fips_h)
- return; /* Not allocated */
-
-#ifdef COMP_IN_WQ
- if (fips_h->workq) {
- flush_workqueue(fips_h->workq);
- destroy_workqueue(fips_h->workq);
- }
-#else
- /* Kill tasklet */
- tasklet_kill(&fips_h->fipstask);
-#endif
- memset(fips_h, 0, sizeof(struct ssi_fips_handle));
- kfree(fips_h);
- drvdata->fips_handle = NULL;
-}
-
-void fips_handler(struct ssi_drvdata *drvdata)
-{
- struct ssi_fips_handle *fips_handle_ptr =
- drvdata->fips_handle;
-#ifdef COMP_IN_WQ
- queue_delayed_work(fips_handle_ptr->workq, &fips_handle_ptr->fipswork, 0);
-#else
- tasklet_schedule(&fips_handle_ptr->fipstask);
-#endif
-}
-
-#ifdef COMP_IN_WQ
-static void fips_wq_handler(struct work_struct *work)
-{
- struct ssi_drvdata *drvdata =
- container_of(work, struct ssi_drvdata, fipswork.work);
-
- fips_dsr((unsigned long)drvdata);
-}
-#endif
-
-/* Deferred service handler, run as interrupt-fired tasklet */
-static void fips_dsr(unsigned long devarg)
-{
- struct ssi_drvdata *drvdata = (struct ssi_drvdata *)devarg;
- void __iomem *cc_base = drvdata->cc_base;
- u32 irq;
- u32 teeFipsError = 0;
-
- irq = (drvdata->irq & (SSI_GPR0_IRQ_MASK));
-
- if (irq & SSI_GPR0_IRQ_MASK) {
- teeFipsError = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, GPR_HOST));
- if (teeFipsError != (CC_FIPS_SYNC_TEE_STATUS | CC_FIPS_SYNC_MODULE_OK))
- ssi_fips_set_error(drvdata, CC_REE_FIPS_ERROR_FROM_TEE);
- }
-
- /* after verifing that there is nothing to do, Unmask AXI completion interrupt */
- CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR),
- CC_HAL_READ_REGISTER(
- CC_REG_OFFSET(HOST_RGF, HOST_IMR)) & ~irq);
-}
-
-enum cc_fips_error cc_fips_run_power_up_tests(struct ssi_drvdata *drvdata)
-{
- enum cc_fips_error fips_error = CC_REE_FIPS_ERROR_OK;
- void *cpu_addr_buffer = NULL;
- dma_addr_t dma_handle;
- size_t alloc_buff_size = ssi_fips_max_mem_alloc_size();
- struct device *dev = &drvdata->plat_dev->dev;
-
- // allocate memory using dma_alloc_coherent - for phisical, consecutive and cache coherent buffer (memory map is not needed)
- // the return value is the virtual address - use it to copy data into the buffer
- // the dma_handle is the returned phy address - use it in the HW descriptor
- FIPS_DBG("dma_alloc_coherent \n");
- cpu_addr_buffer = dma_alloc_coherent(dev, alloc_buff_size, &dma_handle, GFP_KERNEL);
- if (!cpu_addr_buffer)
- return CC_REE_FIPS_ERROR_GENERAL;
-
- FIPS_DBG("allocated coherent buffer - addr 0x%08X , size = %d \n", (size_t)cpu_addr_buffer, alloc_buff_size);
-
-#if FIPS_POWER_UP_TEST_CIPHER
- FIPS_DBG("ssi_cipher_fips_power_up_tests ...\n");
- fips_error = ssi_cipher_fips_power_up_tests(drvdata, cpu_addr_buffer, dma_handle);
- FIPS_DBG("ssi_cipher_fips_power_up_tests - done. (fips_error = %d) \n", fips_error);
-#endif
-#if FIPS_POWER_UP_TEST_CMAC
- if (likely(fips_error == CC_REE_FIPS_ERROR_OK)) {
- FIPS_DBG("ssi_cmac_fips_power_up_tests ...\n");
- fips_error = ssi_cmac_fips_power_up_tests(drvdata, cpu_addr_buffer, dma_handle);
- FIPS_DBG("ssi_cmac_fips_power_up_tests - done. (fips_error = %d) \n", fips_error);
- }
-#endif
-#if FIPS_POWER_UP_TEST_HASH
- if (likely(fips_error == CC_REE_FIPS_ERROR_OK)) {
- FIPS_DBG("ssi_hash_fips_power_up_tests ...\n");
- fips_error = ssi_hash_fips_power_up_tests(drvdata, cpu_addr_buffer, dma_handle);
- FIPS_DBG("ssi_hash_fips_power_up_tests - done. (fips_error = %d) \n", fips_error);
- }
-#endif
-#if FIPS_POWER_UP_TEST_HMAC
- if (likely(fips_error == CC_REE_FIPS_ERROR_OK)) {
- FIPS_DBG("ssi_hmac_fips_power_up_tests ...\n");
- fips_error = ssi_hmac_fips_power_up_tests(drvdata, cpu_addr_buffer, dma_handle);
- FIPS_DBG("ssi_hmac_fips_power_up_tests - done. (fips_error = %d) \n", fips_error);
- }
-#endif
-#if FIPS_POWER_UP_TEST_CCM
- if (likely(fips_error == CC_REE_FIPS_ERROR_OK)) {
- FIPS_DBG("ssi_ccm_fips_power_up_tests ...\n");
- fips_error = ssi_ccm_fips_power_up_tests(drvdata, cpu_addr_buffer, dma_handle);
- FIPS_DBG("ssi_ccm_fips_power_up_tests - done. (fips_error = %d) \n", fips_error);
- }
-#endif
-#if FIPS_POWER_UP_TEST_GCM
- if (likely(fips_error == CC_REE_FIPS_ERROR_OK)) {
- FIPS_DBG("ssi_gcm_fips_power_up_tests ...\n");
- fips_error = ssi_gcm_fips_power_up_tests(drvdata, cpu_addr_buffer, dma_handle);
- FIPS_DBG("ssi_gcm_fips_power_up_tests - done. (fips_error = %d) \n", fips_error);
- }
-#endif
- /* deallocate the buffer when all tests are done... */
- FIPS_DBG("dma_free_coherent \n");
- dma_free_coherent(dev, alloc_buff_size, cpu_addr_buffer, dma_handle);
-
- return fips_error;
-}
-
-/* The function checks if FIPS supported and FIPS error exists.*
- * It should be used in every driver API.
- */
-int ssi_fips_check_fips_error(void)
-{
- enum cc_fips_state_t fips_state;
-
- if (ssi_fips_get_state(&fips_state) != 0) {
- FIPS_LOG("ssi_fips_get_state FAILED, returning.. \n");
- return -ENOEXEC;
- }
- if (fips_state == CC_FIPS_STATE_ERROR) {
- FIPS_LOG("ssi_fips_get_state: fips_state is %d, returning.. \n", fips_state);
- return -ENOEXEC;
- }
- return 0;
-}
-
-/* The function sets the REE FIPS state.*
- * It should be used while driver is being loaded.
- */
-int ssi_fips_set_state(enum cc_fips_state_t state)
-{
- return ssi_fips_ext_set_state(state);
-}
-
-/* The function sets the REE FIPS error, and pushes the error to TEE library. *
- * It should be used when any of the KAT tests fails.
- */
-int ssi_fips_set_error(struct ssi_drvdata *p_drvdata, enum cc_fips_error err)
-{
- int rc = 0;
- enum cc_fips_error current_err;
-
- FIPS_LOG("ssi_fips_set_error - fips_error = %d \n", err);
-
- // setting no error is not allowed
- if (err == CC_REE_FIPS_ERROR_OK)
- return -ENOEXEC;
-
- // If error exists, do not set new error
- if (ssi_fips_get_error(&current_err) != 0)
- return -ENOEXEC;
-
- if (current_err != CC_REE_FIPS_ERROR_OK)
- return -ENOEXEC;
-
- // set REE internal error and state
- rc = ssi_fips_ext_set_error(err);
- if (rc != 0)
- return -ENOEXEC;
-
- rc = ssi_fips_ext_set_state(CC_FIPS_STATE_ERROR);
- if (rc != 0)
- return -ENOEXEC;
-
- // push error towards TEE libraray, if it's not TEE error
- if (err != CC_REE_FIPS_ERROR_FROM_TEE)
- ssi_fips_update_tee_upon_ree_status(p_drvdata, err);
-
- return rc;
-}
-
-/* The function called once at driver entry point .*/
-int ssi_fips_init(struct ssi_drvdata *p_drvdata)
-{
- enum cc_fips_error rc = CC_REE_FIPS_ERROR_OK;
- struct ssi_fips_handle *fips_h;
-
- FIPS_DBG("CC FIPS code .. (fips=%d) \n", ssi_fips_support);
-
- fips_h = kzalloc(sizeof(struct ssi_fips_handle), GFP_KERNEL);
- if (!fips_h) {
- ssi_fips_set_error(p_drvdata, CC_REE_FIPS_ERROR_GENERAL);
- return -ENOMEM;
- }
-
- p_drvdata->fips_handle = fips_h;
-
-#ifdef COMP_IN_WQ
- SSI_LOG_DEBUG("Initializing fips workqueue\n");
- fips_h->workq = create_singlethread_workqueue("arm_cc7x_fips_wq");
- if (unlikely(!fips_h->workq)) {
- SSI_LOG_ERR("Failed creating fips work queue\n");
- ssi_fips_set_error(p_drvdata, CC_REE_FIPS_ERROR_GENERAL);
- rc = -ENOMEM;
- goto ssi_fips_init_err;
- }
- INIT_DELAYED_WORK(&fips_h->fipswork, fips_wq_handler);
-#else
- SSI_LOG_DEBUG("Initializing fips tasklet\n");
- tasklet_init(&fips_h->fipstask, fips_dsr, (unsigned long)p_drvdata);
-#endif
-
- /* init fips driver data */
- rc = ssi_fips_set_state((ssi_fips_support == 0) ? CC_FIPS_STATE_NOT_SUPPORTED : CC_FIPS_STATE_SUPPORTED);
- if (unlikely(rc != 0)) {
- ssi_fips_set_error(p_drvdata, CC_REE_FIPS_ERROR_GENERAL);
- rc = -EAGAIN;
- goto ssi_fips_init_err;
- }
-
- /* Run power up tests (before registration and operating the HW engines) */
- FIPS_DBG("ssi_fips_get_tee_error \n");
- rc = ssi_fips_get_tee_error(p_drvdata);
- if (unlikely(rc != CC_REE_FIPS_ERROR_OK)) {
- ssi_fips_set_error(p_drvdata, CC_REE_FIPS_ERROR_FROM_TEE);
- rc = -EAGAIN;
- goto ssi_fips_init_err;
- }
-
- FIPS_DBG("cc_fips_run_power_up_tests \n");
- rc = cc_fips_run_power_up_tests(p_drvdata);
- if (unlikely(rc != CC_REE_FIPS_ERROR_OK)) {
- ssi_fips_set_error(p_drvdata, rc);
- rc = -EAGAIN;
- goto ssi_fips_init_err;
- }
- FIPS_LOG("cc_fips_run_power_up_tests - done ... fips_error = %d \n", rc);
-
- /* when all tests passed, update TEE with fips OK status after power up tests */
- ssi_fips_update_tee_upon_ree_status(p_drvdata, CC_REE_FIPS_ERROR_OK);
-
- if (unlikely(rc != 0)) {
- rc = -EAGAIN;
- ssi_fips_set_error(p_drvdata, CC_REE_FIPS_ERROR_GENERAL);
- goto ssi_fips_init_err;
- }
-
- return 0;
-
-ssi_fips_init_err:
- ssi_fips_fini(p_drvdata);
- return rc;
-}
-
diff --git a/drivers/staging/ccree/ssi_fips_local.h b/drivers/staging/ccree/ssi_fips_local.h
deleted file mode 100644
index 8c7994f..0000000
--- a/drivers/staging/ccree/ssi_fips_local.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2012-2017 ARM Limited or its affiliates.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __SSI_FIPS_LOCAL_H__
-#define __SSI_FIPS_LOCAL_H__
-
-#ifdef CONFIG_CCX7REE_FIPS_SUPPORT
-
-#include "ssi_fips.h"
-struct ssi_drvdata;
-
-#define CHECK_AND_RETURN_UPON_FIPS_ERROR() {\
- if (ssi_fips_check_fips_error() != 0) {\
- return -ENOEXEC;\
- } \
-}
-
-#define CHECK_AND_RETURN_VOID_UPON_FIPS_ERROR() {\
- if (ssi_fips_check_fips_error() != 0) {\
- return;\
- } \
-}
-
-#define SSI_FIPS_INIT(p_drvData) (ssi_fips_init(p_drvData))
-#define SSI_FIPS_FINI(p_drvData) (ssi_fips_fini(p_drvData))
-
-#define FIPS_LOG(...) SSI_LOG(KERN_INFO, __VA_ARGS__)
-#define FIPS_DBG(...) //SSI_LOG(KERN_INFO, __VA_ARGS__)
-
-/* FIPS functions */
-int ssi_fips_init(struct ssi_drvdata *p_drvdata);
-void ssi_fips_fini(struct ssi_drvdata *drvdata);
-int ssi_fips_check_fips_error(void);
-int ssi_fips_set_error(struct ssi_drvdata *p_drvdata, enum cc_fips_error err);
-void fips_handler(struct ssi_drvdata *drvdata);
-
-#else /* CONFIG_CC7XXREE_FIPS_SUPPORT */
-
-#define CHECK_AND_RETURN_UPON_FIPS_ERROR()
-#define CHECK_AND_RETURN_VOID_UPON_FIPS_ERROR()
-
-static inline int ssi_fips_init(struct ssi_drvdata *p_drvdata)
-{
- return 0;
-}
-
-static inline void ssi_fips_fini(struct ssi_drvdata *drvdata) {}
-
-void fips_handler(struct ssi_drvdata *drvdata);
-
-#endif /* CONFIG_CC7XXREE_FIPS_SUPPORT */
-
-#endif /*__SSI_FIPS_LOCAL_H__*/
-
diff --git a/drivers/staging/ccree/ssi_hash.c b/drivers/staging/ccree/ssi_hash.c
index ae8f36a..13291ae 100644
--- a/drivers/staging/ccree/ssi_hash.c
+++ b/drivers/staging/ccree/ssi_hash.c
@@ -30,7 +30,6 @@
#include "ssi_sysfs.h"
#include "ssi_hash.h"
#include "ssi_sram_mgr.h"
-#include "ssi_fips_local.h"
#define SSI_MAX_AHASH_SEQ_LEN 12
#define SSI_MAX_HASH_OPAD_TMP_KEYS_SIZE MAX(SSI_MAX_HASH_BLCK_SIZE, 3 * AES_BLOCK_SIZE)
@@ -71,8 +70,8 @@ static void ssi_hash_create_xcbc_setup(
unsigned int *seq_size);
static void ssi_hash_create_cmac_setup(struct ahash_request *areq,
- struct cc_hw_desc desc[],
- unsigned int *seq_size);
+ struct cc_hw_desc desc[],
+ unsigned int *seq_size);
struct ssi_hash_alg {
struct list_head entry;
@@ -118,8 +117,8 @@ static void ssi_hash_create_data_desc(
static inline void ssi_set_hash_endianity(u32 mode, struct cc_hw_desc *desc)
{
if (unlikely((mode == DRV_HASH_MD5) ||
- (mode == DRV_HASH_SHA384) ||
- (mode == DRV_HASH_SHA512))) {
+ (mode == DRV_HASH_SHA384) ||
+ (mode == DRV_HASH_SHA512))) {
set_bytes_swap(desc, 1);
} else {
set_cipher_config0(desc, HASH_DIGEST_RESULT_LITTLE_ENDIAN);
@@ -136,13 +135,13 @@ static int ssi_hash_map_result(struct device *dev,
DMA_BIDIRECTIONAL);
if (unlikely(dma_mapping_error(dev, state->digest_result_dma_addr))) {
SSI_LOG_ERR("Mapping digest result buffer %u B for DMA failed\n",
- digestsize);
+ digestsize);
return -ENOMEM;
}
SSI_LOG_DEBUG("Mapped digest result buffer %u B "
- "at va=%pK to dma=0x%llX\n",
+ "at va=%pK to dma=%pad\n",
digestsize, state->digest_result_buff,
- (unsigned long long)state->digest_result_dma_addr);
+ state->digest_result_dma_addr);
return 0;
}
@@ -201,12 +200,12 @@ static int ssi_hash_map_request(struct device *dev,
state->digest_buff_dma_addr = dma_map_single(dev, (void *)state->digest_buff, ctx->inter_digestsize, DMA_BIDIRECTIONAL);
if (dma_mapping_error(dev, state->digest_buff_dma_addr)) {
SSI_LOG_ERR("Mapping digest len %d B at va=%pK for DMA failed\n",
- ctx->inter_digestsize, state->digest_buff);
+ ctx->inter_digestsize, state->digest_buff);
goto fail3;
}
- SSI_LOG_DEBUG("Mapped digest %d B at va=%pK to dma=0x%llX\n",
- ctx->inter_digestsize, state->digest_buff,
- (unsigned long long)state->digest_buff_dma_addr);
+ SSI_LOG_DEBUG("Mapped digest %d B at va=%pK to dma=%pad\n",
+ ctx->inter_digestsize, state->digest_buff,
+ state->digest_buff_dma_addr);
if (is_hmac) {
dma_sync_single_for_cpu(dev, ctx->digest_buff_dma_addr, ctx->inter_digestsize, DMA_BIDIRECTIONAL);
@@ -250,12 +249,12 @@ static int ssi_hash_map_request(struct device *dev,
state->digest_bytes_len_dma_addr = dma_map_single(dev, (void *)state->digest_bytes_len, HASH_LEN_SIZE, DMA_BIDIRECTIONAL);
if (dma_mapping_error(dev, state->digest_bytes_len_dma_addr)) {
SSI_LOG_ERR("Mapping digest len %u B at va=%pK for DMA failed\n",
- HASH_LEN_SIZE, state->digest_bytes_len);
+ HASH_LEN_SIZE, state->digest_bytes_len);
goto fail4;
}
- SSI_LOG_DEBUG("Mapped digest len %u B at va=%pK to dma=0x%llX\n",
- HASH_LEN_SIZE, state->digest_bytes_len,
- (unsigned long long)state->digest_bytes_len_dma_addr);
+ SSI_LOG_DEBUG("Mapped digest len %u B at va=%pK to dma=%pad\n",
+ HASH_LEN_SIZE, state->digest_bytes_len,
+ state->digest_bytes_len_dma_addr);
} else {
state->digest_bytes_len_dma_addr = 0;
}
@@ -264,12 +263,13 @@ static int ssi_hash_map_request(struct device *dev,
state->opad_digest_dma_addr = dma_map_single(dev, (void *)state->opad_digest_buff, ctx->inter_digestsize, DMA_BIDIRECTIONAL);
if (dma_mapping_error(dev, state->opad_digest_dma_addr)) {
SSI_LOG_ERR("Mapping opad digest %d B at va=%pK for DMA failed\n",
- ctx->inter_digestsize, state->opad_digest_buff);
+ ctx->inter_digestsize,
+ state->opad_digest_buff);
goto fail5;
}
- SSI_LOG_DEBUG("Mapped opad digest %d B at va=%pK to dma=0x%llX\n",
- ctx->inter_digestsize, state->opad_digest_buff,
- (unsigned long long)state->opad_digest_dma_addr);
+ SSI_LOG_DEBUG("Mapped opad digest %d B at va=%pK to dma=%pad\n",
+ ctx->inter_digestsize, state->opad_digest_buff,
+ state->opad_digest_dma_addr);
} else {
state->opad_digest_dma_addr = 0;
}
@@ -297,20 +297,14 @@ fail2:
fail1:
kfree(state->digest_buff);
fail_digest_result_buff:
- if (state->digest_result_buff) {
- kfree(state->digest_result_buff);
- state->digest_result_buff = NULL;
- }
+ kfree(state->digest_result_buff);
+ state->digest_result_buff = NULL;
fail_buff1:
- if (state->buff1) {
- kfree(state->buff1);
- state->buff1 = NULL;
- }
+ kfree(state->buff1);
+ state->buff1 = NULL;
fail_buff0:
- if (state->buff0) {
- kfree(state->buff0);
- state->buff0 = NULL;
- }
+ kfree(state->buff0);
+ state->buff0 = NULL;
fail0:
return rc;
}
@@ -322,22 +316,22 @@ static void ssi_hash_unmap_request(struct device *dev,
if (state->digest_buff_dma_addr != 0) {
dma_unmap_single(dev, state->digest_buff_dma_addr,
ctx->inter_digestsize, DMA_BIDIRECTIONAL);
- SSI_LOG_DEBUG("Unmapped digest-buffer: digest_buff_dma_addr=0x%llX\n",
- (unsigned long long)state->digest_buff_dma_addr);
+ SSI_LOG_DEBUG("Unmapped digest-buffer: digest_buff_dma_addr=%pad\n",
+ state->digest_buff_dma_addr);
state->digest_buff_dma_addr = 0;
}
if (state->digest_bytes_len_dma_addr != 0) {
dma_unmap_single(dev, state->digest_bytes_len_dma_addr,
HASH_LEN_SIZE, DMA_BIDIRECTIONAL);
- SSI_LOG_DEBUG("Unmapped digest-bytes-len buffer: digest_bytes_len_dma_addr=0x%llX\n",
- (unsigned long long)state->digest_bytes_len_dma_addr);
+ SSI_LOG_DEBUG("Unmapped digest-bytes-len buffer: digest_bytes_len_dma_addr=%pad\n",
+ state->digest_bytes_len_dma_addr);
state->digest_bytes_len_dma_addr = 0;
}
if (state->opad_digest_dma_addr != 0) {
dma_unmap_single(dev, state->opad_digest_dma_addr,
ctx->inter_digestsize, DMA_BIDIRECTIONAL);
- SSI_LOG_DEBUG("Unmapped opad-digest: opad_digest_dma_addr=0x%llX\n",
- (unsigned long long)state->opad_digest_dma_addr);
+ SSI_LOG_DEBUG("Unmapped opad-digest: opad_digest_dma_addr=%pad\n",
+ state->opad_digest_dma_addr);
state->opad_digest_dma_addr = 0;
}
@@ -359,9 +353,9 @@ static void ssi_hash_unmap_result(struct device *dev,
digestsize,
DMA_BIDIRECTIONAL);
SSI_LOG_DEBUG("unmpa digest result buffer "
- "va (%pK) pa (%llx) len %u\n",
+ "va (%pK) pa (%pad) len %u\n",
state->digest_result_buff,
- (unsigned long long)state->digest_result_dma_addr,
+ state->digest_result_dma_addr,
digestsize);
memcpy(result,
state->digest_result_buff,
@@ -431,8 +425,6 @@ static int ssi_hash_digest(struct ahash_req_ctx *state,
SSI_LOG_DEBUG("===== %s-digest (%d) ====\n", is_hmac ? "hmac" : "hash", nbytes);
- CHECK_AND_RETURN_UPON_FIPS_ERROR();
-
if (unlikely(ssi_hash_map_request(dev, state, ctx) != 0)) {
SSI_LOG_ERR("map_ahash_source() failed\n");
return -ENOMEM;
@@ -596,16 +588,16 @@ static int ssi_hash_update(struct ahash_req_ctx *state,
SSI_LOG_DEBUG("===== %s-update (%d) ====\n", ctx->is_hmac ?
"hmac" : "hash", nbytes);
- CHECK_AND_RETURN_UPON_FIPS_ERROR();
if (nbytes == 0) {
/* no real updates required */
return 0;
}
- if (unlikely(rc = ssi_buffer_mgr_map_hash_request_update(ctx->drvdata, state, src, nbytes, block_size))) {
+ rc = ssi_buffer_mgr_map_hash_request_update(ctx->drvdata, state, src, nbytes, block_size);
+ if (unlikely(rc)) {
if (rc == 1) {
SSI_LOG_DEBUG(" data size not require HW update %x\n",
- nbytes);
+ nbytes);
/* No hardware updates are required */
return 0;
}
@@ -693,8 +685,6 @@ static int ssi_hash_finup(struct ahash_req_ctx *state,
SSI_LOG_DEBUG("===== %s-finup (%d) ====\n", is_hmac ? "hmac" : "hash", nbytes);
- CHECK_AND_RETURN_UPON_FIPS_ERROR();
-
if (unlikely(ssi_buffer_mgr_map_hash_request_final(ctx->drvdata, state, src, nbytes, 1) != 0)) {
SSI_LOG_ERR("map_ahash_request_final() failed\n");
return -ENOMEM;
@@ -829,8 +819,6 @@ static int ssi_hash_final(struct ahash_req_ctx *state,
SSI_LOG_DEBUG("===== %s-final (%d) ====\n", is_hmac ? "hmac" : "hash", nbytes);
- CHECK_AND_RETURN_UPON_FIPS_ERROR();
-
if (unlikely(ssi_buffer_mgr_map_hash_request_final(ctx->drvdata, state, src, nbytes, 0) != 0)) {
SSI_LOG_ERR("map_ahash_request_final() failed\n");
return -ENOMEM;
@@ -964,7 +952,6 @@ static int ssi_hash_init(struct ahash_req_ctx *state, struct ssi_hash_ctx *ctx)
state->xcbc_count = 0;
- CHECK_AND_RETURN_UPON_FIPS_ERROR();
ssi_hash_map_request(dev, state, ctx);
return 0;
@@ -975,7 +962,7 @@ static int ssi_hash_setkey(void *hash,
unsigned int keylen,
bool synchronize)
{
- unsigned int hmacPadConst[2] = { HMAC_IPAD_CONST, HMAC_OPAD_CONST };
+ unsigned int hmac_pad_const[2] = { HMAC_IPAD_CONST, HMAC_OPAD_CONST };
struct ssi_crypto_req ssi_req = {};
struct ssi_hash_ctx *ctx = NULL;
int blocksize = 0;
@@ -984,9 +971,8 @@ static int ssi_hash_setkey(void *hash,
struct cc_hw_desc desc[SSI_MAX_AHASH_SEQ_LEN];
ssi_sram_addr_t larval_addr;
- SSI_LOG_DEBUG("ssi_hash_setkey: start keylen: %d", keylen);
+ SSI_LOG_DEBUG("start keylen: %d", keylen);
- CHECK_AND_RETURN_UPON_FIPS_ERROR();
ctx = crypto_ahash_ctx(((struct crypto_ahash *)hash));
blocksize = crypto_tfm_alg_blocksize(&((struct crypto_ahash *)hash)->base);
digestsize = crypto_ahash_digestsize(((struct crypto_ahash *)hash));
@@ -1012,9 +998,8 @@ static int ssi_hash_setkey(void *hash,
" DMA failed\n", key, keylen);
return -ENOMEM;
}
- SSI_LOG_DEBUG("mapping key-buffer: key_dma_addr=0x%llX "
- "keylen=%u\n",
- (unsigned long long)ctx->key_params.key_dma_addr,
+ SSI_LOG_DEBUG("mapping key-buffer: key_dma_addr=%pad "
+ "keylen=%u\n", ctx->key_params.key_dma_addr,
ctx->key_params.keylen);
if (keylen > blocksize) {
@@ -1118,7 +1103,7 @@ static int ssi_hash_setkey(void *hash,
/* Prepare ipad key */
hw_desc_init(&desc[idx]);
- set_xor_val(&desc[idx], hmacPadConst[i]);
+ set_xor_val(&desc[idx], hmac_pad_const[i]);
set_cipher_mode(&desc[idx], ctx->hw_mode);
set_flow_mode(&desc[idx], S_DIN_to_HASH);
set_setup_mode(&desc[idx], SETUP_LOAD_STATE1);
@@ -1155,17 +1140,17 @@ out:
if (ctx->key_params.key_dma_addr) {
dma_unmap_single(&ctx->drvdata->plat_dev->dev,
- ctx->key_params.key_dma_addr,
- ctx->key_params.keylen, DMA_TO_DEVICE);
- SSI_LOG_DEBUG("Unmapped key-buffer: key_dma_addr=0x%llX keylen=%u\n",
- (unsigned long long)ctx->key_params.key_dma_addr,
- ctx->key_params.keylen);
+ ctx->key_params.key_dma_addr,
+ ctx->key_params.keylen, DMA_TO_DEVICE);
+ SSI_LOG_DEBUG("Unmapped key-buffer: key_dma_addr=%pad keylen=%u\n",
+ ctx->key_params.key_dma_addr,
+ ctx->key_params.keylen);
}
return rc;
}
static int ssi_xcbc_setkey(struct crypto_ahash *ahash,
- const u8 *key, unsigned int keylen)
+ const u8 *key, unsigned int keylen)
{
struct ssi_crypto_req ssi_req = {};
struct ssi_hash_ctx *ctx = crypto_ahash_ctx(ahash);
@@ -1173,15 +1158,14 @@ static int ssi_xcbc_setkey(struct crypto_ahash *ahash,
struct cc_hw_desc desc[SSI_MAX_AHASH_SEQ_LEN];
SSI_LOG_DEBUG("===== setkey (%d) ====\n", keylen);
- CHECK_AND_RETURN_UPON_FIPS_ERROR();
switch (keylen) {
- case AES_KEYSIZE_128:
- case AES_KEYSIZE_192:
- case AES_KEYSIZE_256:
- break;
- default:
- return -EINVAL;
+ case AES_KEYSIZE_128:
+ case AES_KEYSIZE_192:
+ case AES_KEYSIZE_256:
+ break;
+ default:
+ return -EINVAL;
}
ctx->key_params.keylen = keylen;
@@ -1196,9 +1180,9 @@ static int ssi_xcbc_setkey(struct crypto_ahash *ahash,
" DMA failed\n", key, keylen);
return -ENOMEM;
}
- SSI_LOG_DEBUG("mapping key-buffer: key_dma_addr=0x%llX "
+ SSI_LOG_DEBUG("mapping key-buffer: key_dma_addr=%pad "
"keylen=%u\n",
- (unsigned long long)ctx->key_params.key_dma_addr,
+ ctx->key_params.key_dma_addr,
ctx->key_params.keylen);
ctx->is_hmac = true;
@@ -1243,33 +1227,32 @@ static int ssi_xcbc_setkey(struct crypto_ahash *ahash,
crypto_ahash_set_flags(ahash, CRYPTO_TFM_RES_BAD_KEY_LEN);
dma_unmap_single(&ctx->drvdata->plat_dev->dev,
- ctx->key_params.key_dma_addr,
- ctx->key_params.keylen, DMA_TO_DEVICE);
- SSI_LOG_DEBUG("Unmapped key-buffer: key_dma_addr=0x%llX keylen=%u\n",
- (unsigned long long)ctx->key_params.key_dma_addr,
- ctx->key_params.keylen);
+ ctx->key_params.key_dma_addr,
+ ctx->key_params.keylen, DMA_TO_DEVICE);
+ SSI_LOG_DEBUG("Unmapped key-buffer: key_dma_addr=%pad keylen=%u\n",
+ ctx->key_params.key_dma_addr,
+ ctx->key_params.keylen);
return rc;
}
#if SSI_CC_HAS_CMAC
static int ssi_cmac_setkey(struct crypto_ahash *ahash,
- const u8 *key, unsigned int keylen)
+ const u8 *key, unsigned int keylen)
{
struct ssi_hash_ctx *ctx = crypto_ahash_ctx(ahash);
SSI_LOG_DEBUG("===== setkey (%d) ====\n", keylen);
- CHECK_AND_RETURN_UPON_FIPS_ERROR();
ctx->is_hmac = true;
switch (keylen) {
- case AES_KEYSIZE_128:
- case AES_KEYSIZE_192:
- case AES_KEYSIZE_256:
- break;
- default:
- return -EINVAL;
+ case AES_KEYSIZE_128:
+ case AES_KEYSIZE_192:
+ case AES_KEYSIZE_256:
+ break;
+ default:
+ return -EINVAL;
}
ctx->key_params.keylen = keylen;
@@ -1302,8 +1285,8 @@ static void ssi_hash_free_ctx(struct ssi_hash_ctx *ctx)
dma_unmap_single(dev, ctx->digest_buff_dma_addr,
sizeof(ctx->digest_buff), DMA_BIDIRECTIONAL);
SSI_LOG_DEBUG("Unmapped digest-buffer: "
- "digest_buff_dma_addr=0x%llX\n",
- (unsigned long long)ctx->digest_buff_dma_addr);
+ "digest_buff_dma_addr=%pad\n",
+ ctx->digest_buff_dma_addr);
ctx->digest_buff_dma_addr = 0;
}
if (ctx->opad_tmp_keys_dma_addr != 0) {
@@ -1311,8 +1294,8 @@ static void ssi_hash_free_ctx(struct ssi_hash_ctx *ctx)
sizeof(ctx->opad_tmp_keys_buff),
DMA_BIDIRECTIONAL);
SSI_LOG_DEBUG("Unmapped opad-digest: "
- "opad_tmp_keys_dma_addr=0x%llX\n",
- (unsigned long long)ctx->opad_tmp_keys_dma_addr);
+ "opad_tmp_keys_dma_addr=%pad\n",
+ ctx->opad_tmp_keys_dma_addr);
ctx->opad_tmp_keys_dma_addr = 0;
}
@@ -1328,23 +1311,23 @@ static int ssi_hash_alloc_ctx(struct ssi_hash_ctx *ctx)
ctx->digest_buff_dma_addr = dma_map_single(dev, (void *)ctx->digest_buff, sizeof(ctx->digest_buff), DMA_BIDIRECTIONAL);
if (dma_mapping_error(dev, ctx->digest_buff_dma_addr)) {
SSI_LOG_ERR("Mapping digest len %zu B at va=%pK for DMA failed\n",
- sizeof(ctx->digest_buff), ctx->digest_buff);
+ sizeof(ctx->digest_buff), ctx->digest_buff);
goto fail;
}
- SSI_LOG_DEBUG("Mapped digest %zu B at va=%pK to dma=0x%llX\n",
- sizeof(ctx->digest_buff), ctx->digest_buff,
- (unsigned long long)ctx->digest_buff_dma_addr);
+ SSI_LOG_DEBUG("Mapped digest %zu B at va=%pK to dma=%pad\n",
+ sizeof(ctx->digest_buff), ctx->digest_buff,
+ ctx->digest_buff_dma_addr);
ctx->opad_tmp_keys_dma_addr = dma_map_single(dev, (void *)ctx->opad_tmp_keys_buff, sizeof(ctx->opad_tmp_keys_buff), DMA_BIDIRECTIONAL);
if (dma_mapping_error(dev, ctx->opad_tmp_keys_dma_addr)) {
SSI_LOG_ERR("Mapping opad digest %zu B at va=%pK for DMA failed\n",
- sizeof(ctx->opad_tmp_keys_buff),
- ctx->opad_tmp_keys_buff);
+ sizeof(ctx->opad_tmp_keys_buff),
+ ctx->opad_tmp_keys_buff);
goto fail;
}
- SSI_LOG_DEBUG("Mapped opad_tmp_keys %zu B at va=%pK to dma=0x%llX\n",
- sizeof(ctx->opad_tmp_keys_buff), ctx->opad_tmp_keys_buff,
- (unsigned long long)ctx->opad_tmp_keys_dma_addr);
+ SSI_LOG_DEBUG("Mapped opad_tmp_keys %zu B at va=%pK to dma=%pad\n",
+ sizeof(ctx->opad_tmp_keys_buff), ctx->opad_tmp_keys_buff,
+ ctx->opad_tmp_keys_dma_addr);
ctx->is_hmac = false;
return 0;
@@ -1364,9 +1347,8 @@ static int ssi_ahash_cra_init(struct crypto_tfm *tfm)
struct ssi_hash_alg *ssi_alg =
container_of(ahash_alg, struct ssi_hash_alg, ahash_alg);
- CHECK_AND_RETURN_UPON_FIPS_ERROR();
crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
- sizeof(struct ahash_req_ctx));
+ sizeof(struct ahash_req_ctx));
ctx->hash_mode = ssi_alg->hash_mode;
ctx->hw_mode = ssi_alg->hw_mode;
@@ -1396,7 +1378,6 @@ static int ssi_mac_update(struct ahash_request *req)
int rc;
u32 idx = 0;
- CHECK_AND_RETURN_UPON_FIPS_ERROR();
if (req->nbytes == 0) {
/* no real updates required */
return 0;
@@ -1404,10 +1385,11 @@ static int ssi_mac_update(struct ahash_request *req)
state->xcbc_count++;
- if (unlikely(rc = ssi_buffer_mgr_map_hash_request_update(ctx->drvdata, state, req->src, req->nbytes, block_size))) {
+ rc = ssi_buffer_mgr_map_hash_request_update(ctx->drvdata, state, req->src, req->nbytes, block_size);
+ if (unlikely(rc)) {
if (rc == 1) {
SSI_LOG_DEBUG(" data size not require HW update %x\n",
- req->nbytes);
+ req->nbytes);
/* No hardware updates are required */
return 0;
}
@@ -1454,19 +1436,19 @@ static int ssi_mac_final(struct ahash_request *req)
struct cc_hw_desc desc[SSI_MAX_AHASH_SEQ_LEN];
int idx = 0;
int rc = 0;
- u32 keySize, keyLen;
+ u32 key_size, key_len;
u32 digestsize = crypto_ahash_digestsize(tfm);
u32 rem_cnt = state->buff_index ? state->buff1_cnt :
state->buff0_cnt;
- CHECK_AND_RETURN_UPON_FIPS_ERROR();
if (ctx->hw_mode == DRV_CIPHER_XCBC_MAC) {
- keySize = CC_AES_128_BIT_KEY_SIZE;
- keyLen = CC_AES_128_BIT_KEY_SIZE;
+ key_size = CC_AES_128_BIT_KEY_SIZE;
+ key_len = CC_AES_128_BIT_KEY_SIZE;
} else {
- keySize = (ctx->key_params.keylen == 24) ? AES_MAX_KEY_SIZE : ctx->key_params.keylen;
- keyLen = ctx->key_params.keylen;
+ key_size = (ctx->key_params.keylen == 24) ? AES_MAX_KEY_SIZE :
+ ctx->key_params.keylen;
+ key_len = ctx->key_params.keylen;
}
SSI_LOG_DEBUG("===== final xcbc reminder (%d) ====\n", rem_cnt);
@@ -1492,8 +1474,8 @@ static int ssi_mac_final(struct ahash_request *req)
set_cipher_config0(&desc[idx], DRV_CRYPTO_DIRECTION_DECRYPT);
set_din_type(&desc[idx], DMA_DLLI,
(ctx->opad_tmp_keys_dma_addr +
- XCBC_MAC_K1_OFFSET), keySize, NS_BIT);
- set_key_size_aes(&desc[idx], keyLen);
+ XCBC_MAC_K1_OFFSET), key_size, NS_BIT);
+ set_key_size_aes(&desc[idx], key_len);
set_flow_mode(&desc[idx], S_DIN_to_AES);
set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
idx++;
@@ -1522,7 +1504,7 @@ static int ssi_mac_final(struct ahash_request *req)
if (state->xcbc_count == 0) {
hw_desc_init(&desc[idx]);
set_cipher_mode(&desc[idx], ctx->hw_mode);
- set_key_size_aes(&desc[idx], keyLen);
+ set_key_size_aes(&desc[idx], key_len);
set_cmac_size0_mode(&desc[idx]);
set_flow_mode(&desc[idx], S_DIN_to_AES);
idx++;
@@ -1569,9 +1551,8 @@ static int ssi_mac_finup(struct ahash_request *req)
u32 digestsize = crypto_ahash_digestsize(tfm);
SSI_LOG_DEBUG("===== finup xcbc(%d) ====\n", req->nbytes);
- CHECK_AND_RETURN_UPON_FIPS_ERROR();
if (state->xcbc_count > 0 && req->nbytes == 0) {
- SSI_LOG_DEBUG("No data to update. Call to fdx_mac_final \n");
+ SSI_LOG_DEBUG("No data to update. Call to fdx_mac_final\n");
return ssi_mac_final(req);
}
@@ -1636,12 +1617,11 @@ static int ssi_mac_digest(struct ahash_request *req)
u32 digestsize = crypto_ahash_digestsize(tfm);
struct ssi_crypto_req ssi_req = {};
struct cc_hw_desc desc[SSI_MAX_AHASH_SEQ_LEN];
- u32 keyLen;
+ u32 key_len;
int idx = 0;
int rc;
SSI_LOG_DEBUG("===== -digest mac (%d) ====\n", req->nbytes);
- CHECK_AND_RETURN_UPON_FIPS_ERROR();
if (unlikely(ssi_hash_map_request(dev, state, ctx) != 0)) {
SSI_LOG_ERR("map_ahash_source() failed\n");
@@ -1662,17 +1642,17 @@ static int ssi_mac_digest(struct ahash_request *req)
ssi_req.user_arg = (void *)req;
if (ctx->hw_mode == DRV_CIPHER_XCBC_MAC) {
- keyLen = CC_AES_128_BIT_KEY_SIZE;
+ key_len = CC_AES_128_BIT_KEY_SIZE;
ssi_hash_create_xcbc_setup(req, desc, &idx);
} else {
- keyLen = ctx->key_params.keylen;
+ key_len = ctx->key_params.keylen;
ssi_hash_create_cmac_setup(req, desc, &idx);
}
if (req->nbytes == 0) {
hw_desc_init(&desc[idx]);
set_cipher_mode(&desc[idx], ctx->hw_mode);
- set_key_size_aes(&desc[idx], keyLen);
+ set_key_size_aes(&desc[idx], key_len);
set_cmac_size0_mode(&desc[idx]);
set_flow_mode(&desc[idx], S_DIN_to_AES);
idx++;
@@ -1764,8 +1744,6 @@ static int ssi_ahash_export(struct ahash_request *req, void *out)
state->buff0_cnt;
const u32 tmp = CC_EXPORT_MAGIC;
- CHECK_AND_RETURN_UPON_FIPS_ERROR();
-
memcpy(out, &tmp, sizeof(u32));
out += sizeof(u32);
@@ -1805,8 +1783,6 @@ static int ssi_ahash_import(struct ahash_request *req, const void *in)
u32 tmp;
int rc;
- CHECK_AND_RETURN_UPON_FIPS_ERROR();
-
memcpy(&tmp, in, sizeof(u32));
if (tmp != CC_EXPORT_MAGIC) {
rc = -EINVAL;
@@ -1856,7 +1832,7 @@ out:
}
static int ssi_ahash_setkey(struct crypto_ahash *ahash,
- const u8 *key, unsigned int keylen)
+ const u8 *key, unsigned int keylen)
{
return ssi_hash_setkey((void *)ahash, key, keylen, false);
}
@@ -2084,9 +2060,9 @@ ssi_hash_create_alg(struct ssi_hash_template *template, bool keyed)
struct crypto_alg *alg;
struct ahash_alg *halg;
- t_crypto_alg = kzalloc(sizeof(struct ssi_hash_alg), GFP_KERNEL);
+ t_crypto_alg = kzalloc(sizeof(*t_crypto_alg), GFP_KERNEL);
if (!t_crypto_alg) {
- SSI_LOG_ERR("failed to allocate t_alg\n");
+ SSI_LOG_ERR("failed to allocate t_crypto_alg\n");
return ERR_PTR(-ENOMEM);
}
@@ -2138,7 +2114,8 @@ int ssi_hash_init_sram_digest_consts(struct ssi_drvdata *drvdata)
/* Copy-to-sram digest-len */
ssi_sram_mgr_const2sram_desc(digest_len_init, sram_buff_ofs,
- ARRAY_SIZE(digest_len_init), larval_seq, &larval_seq_len);
+ ARRAY_SIZE(digest_len_init),
+ larval_seq, &larval_seq_len);
rc = send_request_init(drvdata, larval_seq, larval_seq_len);
if (unlikely(rc != 0))
goto init_digest_const_err;
@@ -2149,7 +2126,8 @@ int ssi_hash_init_sram_digest_consts(struct ssi_drvdata *drvdata)
#if (DX_DEV_SHA_MAX > 256)
/* Copy-to-sram digest-len for sha384/512 */
ssi_sram_mgr_const2sram_desc(digest_len_sha512_init, sram_buff_ofs,
- ARRAY_SIZE(digest_len_sha512_init), larval_seq, &larval_seq_len);
+ ARRAY_SIZE(digest_len_sha512_init),
+ larval_seq, &larval_seq_len);
rc = send_request_init(drvdata, larval_seq, larval_seq_len);
if (unlikely(rc != 0))
goto init_digest_const_err;
@@ -2163,7 +2141,8 @@ int ssi_hash_init_sram_digest_consts(struct ssi_drvdata *drvdata)
/* Copy-to-sram initial SHA* digests */
ssi_sram_mgr_const2sram_desc(md5_init, sram_buff_ofs,
- ARRAY_SIZE(md5_init), larval_seq, &larval_seq_len);
+ ARRAY_SIZE(md5_init), larval_seq,
+ &larval_seq_len);
rc = send_request_init(drvdata, larval_seq, larval_seq_len);
if (unlikely(rc != 0))
goto init_digest_const_err;
@@ -2171,7 +2150,8 @@ int ssi_hash_init_sram_digest_consts(struct ssi_drvdata *drvdata)
larval_seq_len = 0;
ssi_sram_mgr_const2sram_desc(sha1_init, sram_buff_ofs,
- ARRAY_SIZE(sha1_init), larval_seq, &larval_seq_len);
+ ARRAY_SIZE(sha1_init), larval_seq,
+ &larval_seq_len);
rc = send_request_init(drvdata, larval_seq, larval_seq_len);
if (unlikely(rc != 0))
goto init_digest_const_err;
@@ -2179,7 +2159,8 @@ int ssi_hash_init_sram_digest_consts(struct ssi_drvdata *drvdata)
larval_seq_len = 0;
ssi_sram_mgr_const2sram_desc(sha224_init, sram_buff_ofs,
- ARRAY_SIZE(sha224_init), larval_seq, &larval_seq_len);
+ ARRAY_SIZE(sha224_init), larval_seq,
+ &larval_seq_len);
rc = send_request_init(drvdata, larval_seq, larval_seq_len);
if (unlikely(rc != 0))
goto init_digest_const_err;
@@ -2187,7 +2168,8 @@ int ssi_hash_init_sram_digest_consts(struct ssi_drvdata *drvdata)
larval_seq_len = 0;
ssi_sram_mgr_const2sram_desc(sha256_init, sram_buff_ofs,
- ARRAY_SIZE(sha256_init), larval_seq, &larval_seq_len);
+ ARRAY_SIZE(sha256_init), larval_seq,
+ &larval_seq_len);
rc = send_request_init(drvdata, larval_seq, larval_seq_len);
if (unlikely(rc != 0))
goto init_digest_const_err;
@@ -2201,10 +2183,10 @@ int ssi_hash_init_sram_digest_consts(struct ssi_drvdata *drvdata)
const u32 const1 = ((u32 *)((u64 *)&sha384_init[i]))[0];
ssi_sram_mgr_const2sram_desc(&const0, sram_buff_ofs, 1,
- larval_seq, &larval_seq_len);
+ larval_seq, &larval_seq_len);
sram_buff_ofs += sizeof(u32);
ssi_sram_mgr_const2sram_desc(&const1, sram_buff_ofs, 1,
- larval_seq, &larval_seq_len);
+ larval_seq, &larval_seq_len);
sram_buff_ofs += sizeof(u32);
}
rc = send_request_init(drvdata, larval_seq, larval_seq_len);
@@ -2219,10 +2201,10 @@ int ssi_hash_init_sram_digest_consts(struct ssi_drvdata *drvdata)
const u32 const1 = ((u32 *)((u64 *)&sha512_init[i]))[0];
ssi_sram_mgr_const2sram_desc(&const0, sram_buff_ofs, 1,
- larval_seq, &larval_seq_len);
+ larval_seq, &larval_seq_len);
sram_buff_ofs += sizeof(u32);
ssi_sram_mgr_const2sram_desc(&const1, sram_buff_ofs, 1,
- larval_seq, &larval_seq_len);
+ larval_seq, &larval_seq_len);
sram_buff_ofs += sizeof(u32);
}
rc = send_request_init(drvdata, larval_seq, larval_seq_len);
@@ -2244,10 +2226,10 @@ int ssi_hash_alloc(struct ssi_drvdata *drvdata)
int rc = 0;
int alg;
- hash_handle = kzalloc(sizeof(struct ssi_hash_handle), GFP_KERNEL);
+ hash_handle = kzalloc(sizeof(*hash_handle), GFP_KERNEL);
if (!hash_handle) {
SSI_LOG_ERR("kzalloc failed to allocate %zu B\n",
- sizeof(struct ssi_hash_handle));
+ sizeof(*hash_handle));
rc = -ENOMEM;
goto fail;
}
@@ -2319,7 +2301,7 @@ int ssi_hash_alloc(struct ssi_drvdata *drvdata)
if (IS_ERR(t_alg)) {
rc = PTR_ERR(t_alg);
SSI_LOG_ERR("%s alg allocation failed\n",
- driver_hash[alg].driver_name);
+ driver_hash[alg].driver_name);
goto fail;
}
t_alg->drvdata = drvdata;
@@ -2338,11 +2320,8 @@ int ssi_hash_alloc(struct ssi_drvdata *drvdata)
return 0;
fail:
-
- if (drvdata->hash_handle) {
- kfree(drvdata->hash_handle);
- drvdata->hash_handle = NULL;
- }
+ kfree(drvdata->hash_handle);
+ drvdata->hash_handle = NULL;
return rc;
}
@@ -2365,8 +2344,9 @@ int ssi_hash_free(struct ssi_drvdata *drvdata)
}
static void ssi_hash_create_xcbc_setup(struct ahash_request *areq,
- struct cc_hw_desc desc[],
- unsigned int *seq_size) {
+ struct cc_hw_desc desc[],
+ unsigned int *seq_size)
+{
unsigned int idx = *seq_size;
struct ahash_req_ctx *state = ahash_request_ctx(areq);
struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
@@ -2422,8 +2402,8 @@ static void ssi_hash_create_xcbc_setup(struct ahash_request *areq,
}
static void ssi_hash_create_cmac_setup(struct ahash_request *areq,
- struct cc_hw_desc desc[],
- unsigned int *seq_size)
+ struct cc_hw_desc desc[],
+ unsigned int *seq_size)
{
unsigned int idx = *seq_size;
struct ahash_req_ctx *state = ahash_request_ctx(areq);
diff --git a/drivers/staging/ccree/ssi_ivgen.c b/drivers/staging/ccree/ssi_ivgen.c
index 5ff3368..b01e032 100644
--- a/drivers/staging/ccree/ssi_ivgen.c
+++ b/drivers/staging/ccree/ssi_ivgen.c
@@ -158,7 +158,7 @@ int ssi_ivgen_init_sram_pool(struct ssi_drvdata *drvdata)
void ssi_ivgen_fini(struct ssi_drvdata *drvdata)
{
struct ssi_ivgen_ctx *ivgen_ctx = drvdata->ivgen_handle;
- struct device *device = &(drvdata->plat_dev->dev);
+ struct device *device = &drvdata->plat_dev->dev;
if (!ivgen_ctx)
return;
@@ -166,7 +166,8 @@ void ssi_ivgen_fini(struct ssi_drvdata *drvdata)
if (ivgen_ctx->pool_meta) {
memset(ivgen_ctx->pool_meta, 0, SSI_IVPOOL_META_SIZE);
dma_free_coherent(device, SSI_IVPOOL_META_SIZE,
- ivgen_ctx->pool_meta, ivgen_ctx->pool_meta_dma);
+ ivgen_ctx->pool_meta,
+ ivgen_ctx->pool_meta_dma);
}
ivgen_ctx->pool = NULL_SRAM_ADDR;
@@ -190,10 +191,11 @@ int ssi_ivgen_init(struct ssi_drvdata *drvdata)
int rc;
/* Allocate "this" context */
- drvdata->ivgen_handle = kzalloc(sizeof(struct ssi_ivgen_ctx), GFP_KERNEL);
+ drvdata->ivgen_handle = kzalloc(sizeof(*drvdata->ivgen_handle),
+ GFP_KERNEL);
if (!drvdata->ivgen_handle) {
SSI_LOG_ERR("Not enough memory to allocate IVGEN context "
- "(%zu B)\n", sizeof(struct ssi_ivgen_ctx));
+ "(%zu B)\n", sizeof(*drvdata->ivgen_handle));
rc = -ENOMEM;
goto out;
}
@@ -201,7 +203,8 @@ int ssi_ivgen_init(struct ssi_drvdata *drvdata)
/* Allocate pool's header for intial enc. key/IV */
ivgen_ctx->pool_meta = dma_alloc_coherent(device, SSI_IVPOOL_META_SIZE,
- &ivgen_ctx->pool_meta_dma, GFP_KERNEL);
+ &ivgen_ctx->pool_meta_dma,
+ GFP_KERNEL);
if (!ivgen_ctx->pool_meta) {
SSI_LOG_ERR("Not enough memory to allocate DMA of pool_meta "
"(%u B)\n", SSI_IVPOOL_META_SIZE);
diff --git a/drivers/staging/ccree/ssi_pm.c b/drivers/staging/ccree/ssi_pm.c
index 52a8ed5..31325e6 100644
--- a/drivers/staging/ccree/ssi_pm.c
+++ b/drivers/staging/ccree/ssi_pm.c
@@ -40,7 +40,7 @@ int ssi_power_mgr_runtime_suspend(struct device *dev)
(struct ssi_drvdata *)dev_get_drvdata(dev);
int rc;
- SSI_LOG_DEBUG("ssi_power_mgr_runtime_suspend: set HOST_POWER_DOWN_EN\n");
+ SSI_LOG_DEBUG("set HOST_POWER_DOWN_EN\n");
WRITE_REGISTER(drvdata->cc_base + CC_REG_OFFSET(HOST_RGF, HOST_POWER_DOWN_EN), POWER_DOWN_ENABLE);
rc = ssi_request_mgr_runtime_suspend_queue(drvdata);
if (rc != 0) {
@@ -58,7 +58,7 @@ int ssi_power_mgr_runtime_resume(struct device *dev)
struct ssi_drvdata *drvdata =
(struct ssi_drvdata *)dev_get_drvdata(dev);
- SSI_LOG_DEBUG("ssi_power_mgr_runtime_resume , unset HOST_POWER_DOWN_EN\n");
+ SSI_LOG_DEBUG("unset HOST_POWER_DOWN_EN\n");
WRITE_REGISTER(drvdata->cc_base + CC_REG_OFFSET(HOST_RGF, HOST_POWER_DOWN_EN), POWER_DOWN_DISABLE);
rc = cc_clk_on(drvdata);
diff --git a/drivers/staging/ccree/ssi_request_mgr.c b/drivers/staging/ccree/ssi_request_mgr.c
index 46d9396..e5c2f92 100644
--- a/drivers/staging/ccree/ssi_request_mgr.c
+++ b/drivers/staging/ccree/ssi_request_mgr.c
@@ -30,8 +30,6 @@
#include "ssi_sysfs.h"
#include "ssi_ivgen.h"
#include "ssi_pm.h"
-#include "ssi_fips.h"
-#include "ssi_fips_local.h"
#define SSI_MAX_POLL_ITER 10
@@ -102,7 +100,7 @@ int request_mgr_init(struct ssi_drvdata *drvdata)
struct ssi_request_mgr_handle *req_mgr_h;
int rc = 0;
- req_mgr_h = kzalloc(sizeof(struct ssi_request_mgr_handle), GFP_KERNEL);
+ req_mgr_h = kzalloc(sizeof(*req_mgr_h), GFP_KERNEL);
if (!req_mgr_h) {
rc = -ENOMEM;
goto req_mgr_init_err;
@@ -129,7 +127,7 @@ int request_mgr_init(struct ssi_drvdata *drvdata)
SSI_LOG_DEBUG("hw_queue_size=0x%08X\n", req_mgr_h->hw_queue_size);
if (req_mgr_h->hw_queue_size < MIN_HW_QUEUE_SIZE) {
SSI_LOG_ERR("Invalid HW queue size = %u (Min. required is %u)\n",
- req_mgr_h->hw_queue_size, MIN_HW_QUEUE_SIZE);
+ req_mgr_h->hw_queue_size, MIN_HW_QUEUE_SIZE);
rc = -ENOMEM;
goto req_mgr_init_err;
}
@@ -138,7 +136,9 @@ int request_mgr_init(struct ssi_drvdata *drvdata)
/* Allocate DMA word for "dummy" completion descriptor use */
req_mgr_h->dummy_comp_buff = dma_alloc_coherent(&drvdata->plat_dev->dev,
- sizeof(u32), &req_mgr_h->dummy_comp_buff_dma, GFP_KERNEL);
+ sizeof(u32),
+ &req_mgr_h->dummy_comp_buff_dma,
+ GFP_KERNEL);
if (!req_mgr_h->dummy_comp_buff) {
SSI_LOG_ERR("Not enough memory to allocate DMA (%zu) dropped "
"buffer\n", sizeof(u32));
@@ -177,7 +177,8 @@ static inline void enqueue_seq(
writel_relaxed(seq[i].word[5], (volatile void __iomem *)(cc_base + CC_REG_OFFSET(CRY_KERNEL, DSCRPTR_QUEUE_WORD0)));
#ifdef DX_DUMP_DESCS
SSI_LOG_DEBUG("desc[%02d]: 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n", i,
- seq[i].word[0], seq[i].word[1], seq[i].word[2], seq[i].word[3], seq[i].word[4], seq[i].word[5]);
+ seq[i].word[0], seq[i].word[1], seq[i].word[2],
+ seq[i].word[3], seq[i].word[4], seq[i].word[5]);
#endif
}
}
@@ -211,7 +212,7 @@ static inline int request_mgr_queues_status_check(
(MAX_REQUEST_QUEUE_SIZE - 1)) ==
req_mgr_h->req_queue_tail)) {
SSI_LOG_ERR("SW FIFO is full. req_queue_head=%d sw_fifo_len=%d\n",
- req_mgr_h->req_queue_head, MAX_REQUEST_QUEUE_SIZE);
+ req_mgr_h->req_queue_head, MAX_REQUEST_QUEUE_SIZE);
return -EBUSY;
}
@@ -221,9 +222,8 @@ static inline int request_mgr_queues_status_check(
/* Wait for space in HW queue. Poll constant num of iterations. */
for (poll_queue = 0; poll_queue < SSI_MAX_POLL_ITER ; poll_queue++) {
req_mgr_h->q_free_slots =
- CC_HAL_READ_REGISTER(
- CC_REG_OFFSET(CRY_KERNEL,
- DSCRPTR_QUEUE_CONTENT));
+ CC_HAL_READ_REGISTER(CC_REG_OFFSET(CRY_KERNEL,
+ DSCRPTR_QUEUE_CONTENT));
if (unlikely(req_mgr_h->q_free_slots <
req_mgr_h->min_free_hw_slots)) {
req_mgr_h->min_free_hw_slots = req_mgr_h->q_free_slots;
@@ -235,7 +235,7 @@ static inline int request_mgr_queues_status_check(
}
SSI_LOG_DEBUG("HW FIFO is full. q_free_slots=%d total_seq_len=%d\n",
- req_mgr_h->q_free_slots, total_seq_len);
+ req_mgr_h->q_free_slots, total_seq_len);
}
/* No room in the HW queue try again later */
SSI_LOG_DEBUG("HW FIFO full, timeout. req_queue_head=%d "
@@ -291,9 +291,8 @@ int send_request(
* in case iv gen add the max size and in case of no dout add 1
* for the internal completion descriptor
*/
- rc = request_mgr_queues_status_check(req_mgr_h,
- cc_base,
- max_required_seq_len);
+ rc = request_mgr_queues_status_check(req_mgr_h, cc_base,
+ max_required_seq_len);
if (likely(rc == 0))
/* There is enough place in the queue */
break;
@@ -320,21 +319,22 @@ int send_request(
if (!is_dout) {
init_completion(&ssi_req->seq_compl);
ssi_req->user_cb = request_mgr_complete;
- ssi_req->user_arg = &(ssi_req->seq_compl);
+ ssi_req->user_arg = &ssi_req->seq_compl;
total_seq_len++;
}
if (ssi_req->ivgen_dma_addr_len > 0) {
- SSI_LOG_DEBUG("Acquire IV from pool into %d DMA addresses 0x%llX, 0x%llX, 0x%llX, IV-size=%u\n",
- ssi_req->ivgen_dma_addr_len,
- (unsigned long long)ssi_req->ivgen_dma_addr[0],
- (unsigned long long)ssi_req->ivgen_dma_addr[1],
- (unsigned long long)ssi_req->ivgen_dma_addr[2],
- ssi_req->ivgen_size);
+ SSI_LOG_DEBUG("Acquire IV from pool into %d DMA addresses %pad, %pad, %pad, IV-size=%u\n",
+ ssi_req->ivgen_dma_addr_len,
+ ssi_req->ivgen_dma_addr[0],
+ ssi_req->ivgen_dma_addr[1],
+ ssi_req->ivgen_dma_addr[2],
+ ssi_req->ivgen_size);
/* Acquire IV from pool */
- rc = ssi_ivgen_getiv(drvdata, ssi_req->ivgen_dma_addr, ssi_req->ivgen_dma_addr_len,
- ssi_req->ivgen_size, iv_seq, &iv_seq_len);
+ rc = ssi_ivgen_getiv(drvdata, ssi_req->ivgen_dma_addr,
+ ssi_req->ivgen_dma_addr_len,
+ ssi_req->ivgen_size, iv_seq, &iv_seq_len);
if (unlikely(rc != 0)) {
SSI_LOG_ERR("Failed to generate IV (rc=%d)\n", rc);
@@ -418,9 +418,8 @@ int send_request_init(
enqueue_seq(cc_base, desc, len);
/* Update the free slots in HW queue */
- req_mgr_h->q_free_slots = CC_HAL_READ_REGISTER(
- CC_REG_OFFSET(CRY_KERNEL,
- DSCRPTR_QUEUE_CONTENT));
+ req_mgr_h->q_free_slots = CC_HAL_READ_REGISTER(CC_REG_OFFSET(CRY_KERNEL,
+ DSCRPTR_QUEUE_CONTENT));
return 0;
}
@@ -545,8 +544,7 @@ static void comp_handler(unsigned long devarg)
}
/* after verifing that there is nothing to do, Unmask AXI completion interrupt */
CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR),
- CC_HAL_READ_REGISTER(
- CC_REG_OFFSET(HOST_RGF, HOST_IMR)) & ~irq);
+ CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR)) & ~irq);
}
/*
diff --git a/drivers/staging/ccree/ssi_sram_mgr.c b/drivers/staging/ccree/ssi_sram_mgr.c
index e05c0c1..f11116a 100644
--- a/drivers/staging/ccree/ssi_sram_mgr.c
+++ b/drivers/staging/ccree/ssi_sram_mgr.c
@@ -58,7 +58,7 @@ int ssi_sram_mgr_init(struct ssi_drvdata *drvdata)
sizeof(struct ssi_sram_mgr_ctx), GFP_KERNEL);
if (!drvdata->sram_mgr_handle) {
SSI_LOG_ERR("Not enough memory to allocate SRAM_MGR ctx (%zu)\n",
- sizeof(struct ssi_sram_mgr_ctx));
+ sizeof(struct ssi_sram_mgr_ctx));
rc = -ENOMEM;
goto out;
}
@@ -90,12 +90,12 @@ ssi_sram_addr_t ssi_sram_mgr_alloc(struct ssi_drvdata *drvdata, u32 size)
if (unlikely((size & 0x3) != 0)) {
SSI_LOG_ERR("Requested buffer size (%u) is not multiple of 4",
- size);
+ size);
return NULL_SRAM_ADDR;
}
if (unlikely(size > (SSI_CC_SRAM_SIZE - smgr_ctx->sram_free_offset))) {
SSI_LOG_ERR("Not enough space to allocate %u B (at offset %llu)\n",
- size, smgr_ctx->sram_free_offset);
+ size, smgr_ctx->sram_free_offset);
return NULL_SRAM_ADDR;
}
diff --git a/drivers/staging/ccree/ssi_sysfs.c b/drivers/staging/ccree/ssi_sysfs.c
index dbcd163..0655658 100644
--- a/drivers/staging/ccree/ssi_sysfs.c
+++ b/drivers/staging/ccree/ssi_sysfs.c
@@ -40,8 +40,7 @@ struct stat_name {
const char *stat_phase_name[MAX_STAT_PHASES];
};
-static struct stat_name stat_name_db[MAX_STAT_OP_TYPES] =
-{
+static struct stat_name stat_name_db[MAX_STAT_OP_TYPES] = {
{
/* STAT_OP_TYPE_NULL */
.op_type_name = "NULL",
@@ -144,8 +143,12 @@ static void display_db(struct stat_item item[MAX_STAT_OP_TYPES][MAX_STAT_PHASES]
avg = (u64)item[i][j].sum;
do_div(avg, item[i][j].count);
SSI_LOG_ERR("%s, %s: min=%d avg=%d max=%d sum=%lld count=%d\n",
- stat_name_db[i].op_type_name, stat_name_db[i].stat_phase_name[j],
- item[i][j].min, (int)avg, item[i][j].max, (long long)item[i][j].sum, item[i][j].count);
+ stat_name_db[i].op_type_name,
+ stat_name_db[i].stat_phase_name[j],
+ item[i][j].min, (int)avg,
+ item[i][j].max,
+ (long long)item[i][j].sum,
+ item[i][j].count);
}
}
}
@@ -156,21 +159,23 @@ static void display_db(struct stat_item item[MAX_STAT_OP_TYPES][MAX_STAT_PHASES]
**************************************/
static ssize_t ssi_sys_stats_host_db_clear(struct kobject *kobj,
- struct kobj_attribute *attr, const char *buf, size_t count)
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
{
init_db(stat_host_db);
return count;
}
static ssize_t ssi_sys_stats_cc_db_clear(struct kobject *kobj,
- struct kobj_attribute *attr, const char *buf, size_t count)
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
{
init_db(stat_cc_db);
return count;
}
static ssize_t ssi_sys_stat_host_db_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+ struct kobj_attribute *attr, char *buf)
{
int i, j;
char line[512];
@@ -179,7 +184,7 @@ static ssize_t ssi_sys_stat_host_db_show(struct kobject *kobj,
ssize_t buf_len, tmp_len = 0;
buf_len = scnprintf(buf, PAGE_SIZE,
- "phase\t\t\t\t\t\t\tmin[cy]\tavg[cy]\tmax[cy]\t#samples\n");
+ "phase\t\t\t\t\t\t\tmin[cy]\tavg[cy]\tmax[cy]\t#samples\n");
if (buf_len < 0)/* scnprintf shouldn't return negative value according to its implementation*/
return buf_len;
for (i = STAT_OP_TYPE_ENCODE; i < MAX_STAT_OP_TYPES; i++) {
@@ -193,11 +198,11 @@ static ssize_t ssi_sys_stat_host_db_show(struct kobject *kobj,
avg = min_cyc = max_cyc = 0;
}
tmp_len = scnprintf(line, 512,
- "%s::%s\t\t\t\t\t%6u\t%6u\t%6u\t%7u\n",
- stat_name_db[i].op_type_name,
- stat_name_db[i].stat_phase_name[j],
- min_cyc, (unsigned int)avg, max_cyc,
- stat_host_db[i][j].count);
+ "%s::%s\t\t\t\t\t%6u\t%6u\t%6u\t%7u\n",
+ stat_name_db[i].op_type_name,
+ stat_name_db[i].stat_phase_name[j],
+ min_cyc, (unsigned int)avg, max_cyc,
+ stat_host_db[i][j].count);
if (tmp_len < 0)/* scnprintf shouldn't return negative value according to its implementation*/
return buf_len;
if (buf_len + tmp_len >= PAGE_SIZE)
@@ -210,7 +215,7 @@ static ssize_t ssi_sys_stat_host_db_show(struct kobject *kobj,
}
static ssize_t ssi_sys_stat_cc_db_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+ struct kobj_attribute *attr, char *buf)
{
int i;
char line[256];
@@ -219,7 +224,7 @@ static ssize_t ssi_sys_stat_cc_db_show(struct kobject *kobj,
ssize_t buf_len, tmp_len = 0;
buf_len = scnprintf(buf, PAGE_SIZE,
- "phase\tmin[cy]\tavg[cy]\tmax[cy]\t#samples\n");
+ "phase\tmin[cy]\tavg[cy]\tmax[cy]\t#samples\n");
if (buf_len < 0)/* scnprintf shouldn't return negative value according to its implementation*/
return buf_len;
for (i = STAT_OP_TYPE_ENCODE; i < MAX_STAT_OP_TYPES; i++) {
@@ -231,13 +236,10 @@ static ssize_t ssi_sys_stat_cc_db_show(struct kobject *kobj,
} else {
avg = min_cyc = max_cyc = 0;
}
- tmp_len = scnprintf(line, 256,
- "%s\t%6u\t%6u\t%6u\t%7u\n",
- stat_name_db[i].op_type_name,
- min_cyc,
- (unsigned int)avg,
- max_cyc,
- stat_cc_db[i][STAT_PHASE_6].count);
+ tmp_len = scnprintf(line, 256, "%s\t%6u\t%6u\t%6u\t%7u\n",
+ stat_name_db[i].op_type_name, min_cyc,
+ (unsigned int)avg, max_cyc,
+ stat_cc_db[i][STAT_PHASE_6].count);
if (tmp_len < 0)/* scnprintf shouldn't return negative value according to its implementation*/
return buf_len;
@@ -255,7 +257,7 @@ void update_host_stat(unsigned int op_type, unsigned int phase, cycles_t result)
unsigned long flags;
spin_lock_irqsave(&stat_lock, flags);
- update_db(&(stat_host_db[op_type][phase]), (unsigned int)result);
+ update_db(&stat_host_db[op_type][phase], (unsigned int)result);
spin_unlock_irqrestore(&stat_lock, flags);
}
@@ -264,7 +266,7 @@ void update_cc_stat(
unsigned int phase,
unsigned int elapsed_cycles)
{
- update_db(&(stat_cc_db[op_type][phase]), elapsed_cycles);
+ update_db(&stat_cc_db[op_type][phase], elapsed_cycles);
}
void display_all_stat_db(void)
@@ -277,7 +279,7 @@ void display_all_stat_db(void)
#endif /*CC_CYCLE_COUNT*/
static ssize_t ssi_sys_regdump_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+ struct kobj_attribute *attr, char *buf)
{
struct ssi_drvdata *drvdata = sys_get_drvdata();
u32 register_value;
@@ -285,20 +287,20 @@ static ssize_t ssi_sys_regdump_show(struct kobject *kobj,
int offset = 0;
register_value = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_SIGNATURE));
- offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%s \t(0x%lX)\t 0x%08X \n", "HOST_SIGNATURE ", DX_HOST_SIGNATURE_REG_OFFSET, register_value);
+ offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%s \t(0x%lX)\t 0x%08X\n", "HOST_SIGNATURE ", DX_HOST_SIGNATURE_REG_OFFSET, register_value);
register_value = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IRR));
- offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%s \t(0x%lX)\t 0x%08X \n", "HOST_IRR ", DX_HOST_IRR_REG_OFFSET, register_value);
+ offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%s \t(0x%lX)\t 0x%08X\n", "HOST_IRR ", DX_HOST_IRR_REG_OFFSET, register_value);
register_value = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_POWER_DOWN_EN));
- offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%s \t(0x%lX)\t 0x%08X \n", "HOST_POWER_DOWN_EN ", DX_HOST_POWER_DOWN_EN_REG_OFFSET, register_value);
+ offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%s \t(0x%lX)\t 0x%08X\n", "HOST_POWER_DOWN_EN ", DX_HOST_POWER_DOWN_EN_REG_OFFSET, register_value);
register_value = CC_HAL_READ_REGISTER(CC_REG_OFFSET(CRY_KERNEL, AXIM_MON_ERR));
- offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%s \t(0x%lX)\t 0x%08X \n", "AXIM_MON_ERR ", DX_AXIM_MON_ERR_REG_OFFSET, register_value);
+ offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%s \t(0x%lX)\t 0x%08X\n", "AXIM_MON_ERR ", DX_AXIM_MON_ERR_REG_OFFSET, register_value);
register_value = CC_HAL_READ_REGISTER(CC_REG_OFFSET(CRY_KERNEL, DSCRPTR_QUEUE_CONTENT));
- offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%s \t(0x%lX)\t 0x%08X \n", "DSCRPTR_QUEUE_CONTENT", DX_DSCRPTR_QUEUE_CONTENT_REG_OFFSET, register_value);
+ offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%s \t(0x%lX)\t 0x%08X\n", "DSCRPTR_QUEUE_CONTENT", DX_DSCRPTR_QUEUE_CONTENT_REG_OFFSET, register_value);
return offset;
}
static ssize_t ssi_sys_help_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+ struct kobj_attribute *attr, char *buf)
{
char *help_str[] = {
"cat reg_dump ", "Print several of CC register values",
@@ -357,8 +359,8 @@ static struct ssi_drvdata *sys_get_drvdata(void)
}
static int sys_init_dir(struct sys_dir *sys_dir, struct ssi_drvdata *drvdata,
- struct kobject *parent_dir_kobj, const char *dir_name,
- struct kobj_attribute *attrs, u32 num_of_attrs)
+ struct kobject *parent_dir_kobj, const char *dir_name,
+ struct kobj_attribute *attrs, u32 num_of_attrs)
{
int i;
@@ -375,7 +377,7 @@ static int sys_init_dir(struct sys_dir *sys_dir, struct ssi_drvdata *drvdata,
/* allocate memory for directory's attributes list */
sys_dir->sys_dir_attr_list =
kzalloc(sizeof(struct attribute *) * (num_of_attrs + 1),
- GFP_KERNEL);
+ GFP_KERNEL);
if (!(sys_dir->sys_dir_attr_list)) {
kobject_put(sys_dir->sys_dir_kobj);
@@ -386,7 +388,7 @@ static int sys_init_dir(struct sys_dir *sys_dir, struct ssi_drvdata *drvdata,
/* initialize attributes list */
for (i = 0; i < num_of_attrs; ++i)
- sys_dir->sys_dir_attr_list[i] = &(attrs[i].attr);
+ sys_dir->sys_dir_attr_list[i] = &attrs[i].attr;
/* last list entry should be NULL */
sys_dir->sys_dir_attr_list[num_of_attrs] = NULL;
@@ -394,7 +396,7 @@ static int sys_init_dir(struct sys_dir *sys_dir, struct ssi_drvdata *drvdata,
sys_dir->sys_dir_attr_group.attrs = sys_dir->sys_dir_attr_list;
return sysfs_create_group(sys_dir->sys_dir_kobj,
- &(sys_dir->sys_dir_attr_group));
+ &sys_dir->sys_dir_attr_group);
}
static void sys_free_dir(struct sys_dir *sys_dir)
@@ -421,9 +423,9 @@ int ssi_sysfs_init(struct kobject *sys_dev_obj, struct ssi_drvdata *drvdata)
SSI_LOG_ERR("setup sysfs under %s\n", sys_dev_obj->name);
/* Initialize top directory */
- retval = sys_init_dir(&sys_top_dir, drvdata, sys_dev_obj,
- "cc_info", ssi_sys_top_level_attrs,
- ARRAY_SIZE(ssi_sys_top_level_attrs));
+ retval = sys_init_dir(&sys_top_dir, drvdata, sys_dev_obj, "cc_info",
+ ssi_sys_top_level_attrs,
+ ARRAY_SIZE(ssi_sys_top_level_attrs));
return retval;
}
diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c
index 8e9b30b..b455ff6 100644
--- a/drivers/staging/comedi/comedi_buf.c
+++ b/drivers/staging/comedi/comedi_buf.c
@@ -165,7 +165,7 @@ int comedi_buf_map_put(struct comedi_buf_map *bm)
int comedi_buf_map_access(struct comedi_buf_map *bm, unsigned long offset,
void *buf, int len, int write)
{
- unsigned int pgoff = offset & ~PAGE_MASK;
+ unsigned int pgoff = offset_in_page(offset);
unsigned long pg = offset >> PAGE_SHIFT;
int done = 0;
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index 34ca782..e19e395 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -745,7 +745,7 @@ static void do_become_nonbusy(struct comedi_device *dev,
wake_up_interruptible_all(&async->wait_head);
} else {
dev_err(dev->class_dev,
- "BUG: (?) do_become_nonbusy called with async=NULL\n");
+ "BUG: (?) %s called with async=NULL\n", __func__);
s->busy = NULL;
}
}
diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c
index a5bf2cc..0b43db6 100644
--- a/drivers/staging/comedi/drivers.c
+++ b/drivers/staging/comedi/drivers.c
@@ -995,12 +995,12 @@ int comedi_auto_config(struct device *hardware_device,
int ret;
if (!hardware_device) {
- pr_warn("BUG! comedi_auto_config called with NULL hardware_device\n");
+ pr_warn("BUG! %s called with NULL hardware_device\n", __func__);
return -EINVAL;
}
if (!driver) {
dev_warn(hardware_device,
- "BUG! comedi_auto_config called with NULL comedi driver\n");
+ "BUG! %s called with NULL comedi driver\n", __func__);
return -EINVAL;
}
diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c
index 2f7bfc1..398347f 100644
--- a/drivers/staging/comedi/drivers/ni_mio_common.c
+++ b/drivers/staging/comedi/drivers/ni_mio_common.c
@@ -1962,7 +1962,8 @@ static unsigned int ni_timer_to_ns(const struct comedi_device *dev, int timer)
static void ni_cmd_set_mite_transfer(struct mite_ring *ring,
struct comedi_subdevice *sdev,
const struct comedi_cmd *cmd,
- unsigned int max_count) {
+ unsigned int max_count)
+{
#ifdef PCIDMA
unsigned int nbytes = max_count;
diff --git a/drivers/staging/fbtft/fb_st7789v.c b/drivers/staging/fbtft/fb_st7789v.c
index 8935a97..a5d7c87 100644
--- a/drivers/staging/fbtft/fb_st7789v.c
+++ b/drivers/staging/fbtft/fb_st7789v.c
@@ -189,7 +189,7 @@ static int set_gamma(struct fbtft_par *par, u32 *curves)
* The masks are the same for both positive and negative voltage
* gamma curves.
*/
- const u8 gamma_par_mask[] = {
+ static const u8 gamma_par_mask[] = {
0xFF, /* V63[3:0], V0[3:0]*/
0x3F, /* V1[5:0] */
0x3F, /* V2[5:0] */
diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c
index b742ee7..6d0363d 100644
--- a/drivers/staging/fbtft/fbtft-core.c
+++ b/drivers/staging/fbtft/fbtft-core.c
@@ -84,7 +84,7 @@ static unsigned long fbtft_request_gpios_match(struct fbtft_par *par,
const struct fbtft_gpio *gpio)
{
int ret;
- long val;
+ unsigned int val;
fbtft_par_dbg(DEBUG_REQUEST_GPIOS_MATCH, par, "%s('%s')\n",
__func__, gpio->name);
@@ -108,7 +108,7 @@ static unsigned long fbtft_request_gpios_match(struct fbtft_par *par,
par->gpio.latch = gpio->gpio;
return GPIOF_OUT_INIT_LOW;
} else if (gpio->name[0] == 'd' && gpio->name[1] == 'b') {
- ret = kstrtol(&gpio->name[2], 10, &val);
+ ret = kstrtouint(&gpio->name[2], 10, &val);
if (ret == 0 && val < 16) {
par->gpio.db[val] = gpio->gpio;
return GPIOF_OUT_INIT_LOW;
diff --git a/drivers/staging/fsl-dpaa2/Kconfig b/drivers/staging/fsl-dpaa2/Kconfig
index 730fd6d..dfff675 100644
--- a/drivers/staging/fsl-dpaa2/Kconfig
+++ b/drivers/staging/fsl-dpaa2/Kconfig
@@ -4,7 +4,7 @@
config FSL_DPAA2
bool "Freescale DPAA2 devices"
- depends on FSL_MC_BUS
+ depends on FSL_MC_BUS && ARCH_LAYERSCAPE
---help---
Build drivers for Freescale DataPath Acceleration
Architecture (DPAA2) family of SoCs.
diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
index b9a0a31..26017fe 100644
--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
@@ -616,7 +616,7 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct net_device *net_dev)
free_tx_fd(priv, &fd, NULL);
} else {
percpu_stats->tx_packets++;
- percpu_stats->tx_bytes += skb->len;
+ percpu_stats->tx_bytes += dpaa2_fd_get_len(&fd);
}
return NETDEV_TX_OK;
@@ -656,7 +656,7 @@ static void dpaa2_eth_tx_conf(struct dpaa2_eth_priv *priv,
has_fas_errors = (fd_errors & DPAA2_FD_CTRL_FAERR) &&
!!(dpaa2_fd_get_frc(fd) & DPAA2_FD_FRC_FASV);
if (net_ratelimit())
- netdev_dbg(priv->net_dev, "TX frame FD error: %x08\n",
+ netdev_dbg(priv->net_dev, "TX frame FD error: 0x%08x\n",
fd_errors);
}
@@ -670,7 +670,7 @@ static void dpaa2_eth_tx_conf(struct dpaa2_eth_priv *priv,
percpu_stats->tx_errors++;
if (has_fas_errors && net_ratelimit())
- netdev_dbg(priv->net_dev, "TX frame FAS error: %x08\n",
+ netdev_dbg(priv->net_dev, "TX frame FAS error: 0x%08x\n",
status & DPAA2_FAS_TX_ERR_MASK);
}
diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h
index e6d28a2..bfbabae 100644
--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h
@@ -123,8 +123,8 @@ struct dpaa2_eth_swa {
/* Error bits in FD CTRL */
#define DPAA2_FD_CTRL_UFD 0x00000004
#define DPAA2_FD_CTRL_SBE 0x00000008
-#define DPAA2_FD_CTRL_FSE 0x00000010
-#define DPAA2_FD_CTRL_FAERR 0x00000020
+#define DPAA2_FD_CTRL_FSE 0x00000020
+#define DPAA2_FD_CTRL_FAERR 0x00000040
#define DPAA2_FD_RX_ERR_MASK (DPAA2_FD_CTRL_SBE | \
DPAA2_FD_CTRL_FAERR)
diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-ethtool.c b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-ethtool.c
index 5312edc..031179a 100644
--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-ethtool.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-ethtool.c
@@ -217,8 +217,6 @@ static void dpaa2_eth_get_ethtool_stats(struct net_device *net_dev,
case 2:
num_cnt = sizeof(dpni_stats.page_2) / sizeof(u64);
break;
- default:
- break;
}
for (k = 0; k < num_cnt; k++)
*(data + i++) = dpni_stats.raw.counter[k];
diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpni.c b/drivers/staging/fsl-dpaa2/ethernet/dpni.c
index 5b9d442..04a5b14 100644
--- a/drivers/staging/fsl-dpaa2/ethernet/dpni.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpni.c
@@ -1443,7 +1443,7 @@ int dpni_get_queue(struct fsl_mc_io *mc_io,
queue->destination.id = le32_to_cpu(rsp_params->dest_id);
queue->destination.priority = rsp_params->dest_prio;
queue->destination.type = dpni_get_field(rsp_params->flags,
- DEST_TYPE);
+ DEST_TYPE);
queue->flc.stash_control = dpni_get_field(rsp_params->flags,
STASH_CTRL);
queue->destination.hold_active = dpni_get_field(rsp_params->flags,
diff --git a/drivers/staging/fsl-mc/bus/Kconfig b/drivers/staging/fsl-mc/bus/Kconfig
index a10aaf0..504c987 100644
--- a/drivers/staging/fsl-mc/bus/Kconfig
+++ b/drivers/staging/fsl-mc/bus/Kconfig
@@ -8,7 +8,7 @@
config FSL_MC_BUS
bool "QorIQ DPAA2 fsl-mc bus driver"
- depends on OF && ARCH_LAYERSCAPE
+ depends on OF && (ARCH_LAYERSCAPE || (COMPILE_TEST && (ARM || ARM64 || X86 || PPC)))
select GENERIC_MSI_IRQ_DOMAIN
help
Driver to enable the bus infrastructure for the QorIQ DPAA2
@@ -18,7 +18,7 @@ config FSL_MC_BUS
config FSL_MC_DPIO
tristate "QorIQ DPAA2 DPIO driver"
- depends on FSL_MC_BUS
+ depends on FSL_MC_BUS && ARCH_LAYERSCAPE
help
Driver for the DPAA2 DPIO object. A DPIO provides queue and
buffer management facilities for software to interact with
diff --git a/drivers/staging/fsl-mc/bus/dpio/qbman-portal.c b/drivers/staging/fsl-mc/bus/dpio/qbman-portal.c
index 7988612..163bdac 100644
--- a/drivers/staging/fsl-mc/bus/dpio/qbman-portal.c
+++ b/drivers/staging/fsl-mc/bus/dpio/qbman-portal.c
@@ -136,18 +136,18 @@ static inline u32 qbman_set_swp_cfg(u8 max_fill, u8 wn, u8 est, u8 rpm, u8 dcm,
u8 epm, int sd, int sp, int se,
int dp, int de, int ep)
{
- return cpu_to_le32 (max_fill << SWP_CFG_DQRR_MF_SHIFT |
- est << SWP_CFG_EST_SHIFT |
- wn << SWP_CFG_WN_SHIFT |
- rpm << SWP_CFG_RPM_SHIFT |
- dcm << SWP_CFG_DCM_SHIFT |
- epm << SWP_CFG_EPM_SHIFT |
- sd << SWP_CFG_SD_SHIFT |
- sp << SWP_CFG_SP_SHIFT |
- se << SWP_CFG_SE_SHIFT |
- dp << SWP_CFG_DP_SHIFT |
- de << SWP_CFG_DE_SHIFT |
- ep << SWP_CFG_EP_SHIFT);
+ return (max_fill << SWP_CFG_DQRR_MF_SHIFT |
+ est << SWP_CFG_EST_SHIFT |
+ wn << SWP_CFG_WN_SHIFT |
+ rpm << SWP_CFG_RPM_SHIFT |
+ dcm << SWP_CFG_DCM_SHIFT |
+ epm << SWP_CFG_EPM_SHIFT |
+ sd << SWP_CFG_SD_SHIFT |
+ sp << SWP_CFG_SP_SHIFT |
+ se << SWP_CFG_SE_SHIFT |
+ dp << SWP_CFG_DP_SHIFT |
+ de << SWP_CFG_DE_SHIFT |
+ ep << SWP_CFG_EP_SHIFT);
}
/**
diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c b/drivers/staging/fsl-mc/bus/dprc-driver.c
index 4cdd190..06df528 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -29,7 +29,7 @@ static bool fsl_mc_device_match(struct fsl_mc_device *mc_dev,
struct fsl_mc_obj_desc *obj_desc)
{
return mc_dev->obj_desc.id == obj_desc->id &&
- !strcmp(mc_dev->obj_desc.type, obj_desc->type);
+ strcmp(mc_dev->obj_desc.type, obj_desc->type) == 0;
}
@@ -617,8 +617,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
if (WARN_ON(mc_dev->obj_desc.region_count == 0))
return -EINVAL;
- region_size = mc_dev->regions[0].end -
- mc_dev->regions[0].start + 1;
+ region_size = resource_size(mc_dev->regions);
error = fsl_create_mc_io(&mc_dev->dev,
mc_dev->regions[0].start,
diff --git a/drivers/staging/fsl-mc/bus/fsl-mc-bus.c b/drivers/staging/fsl-mc/bus/fsl-mc-bus.c
index 19606e8..409f2b9 100644
--- a/drivers/staging/fsl-mc/bus/fsl-mc-bus.c
+++ b/drivers/staging/fsl-mc/bus/fsl-mc-bus.c
@@ -757,8 +757,8 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
error = of_address_to_resource(pdev->dev.of_node, 0, &res);
if (error < 0) {
dev_err(&pdev->dev,
- "of_address_to_resource() failed for %s\n",
- pdev->dev.of_node->full_name);
+ "of_address_to_resource() failed for %pOF\n",
+ pdev->dev.of_node);
return error;
}
diff --git a/drivers/staging/fsl-mc/bus/fsl-mc-msi.c b/drivers/staging/fsl-mc/bus/fsl-mc-msi.c
index c04a2f2..038da4d 100644
--- a/drivers/staging/fsl-mc/bus/fsl-mc-msi.c
+++ b/drivers/staging/fsl-mc/bus/fsl-mc-msi.c
@@ -11,13 +11,13 @@
#include <linux/of_device.h>
#include <linux/of_address.h>
-#include <linux/irqchip/arm-gic-v3.h>
#include <linux/of_irq.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/msi.h>
#include "fsl-mc-private.h"
+#ifdef GENERIC_MSI_DOMAIN_OPS
/*
* Generate a unique ID identifying the interrupt (only used within the MSI
* irqdomain. Combine the icid with the interrupt index.
@@ -39,6 +39,9 @@ static void fsl_mc_msi_set_desc(msi_alloc_info_t *arg,
arg->hwirq = fsl_mc_domain_calc_hwirq(to_fsl_mc_device(desc->dev),
desc);
}
+#else
+#define fsl_mc_msi_set_desc NULL
+#endif
static void fsl_mc_msi_update_dom_ops(struct msi_domain_info *info)
{
@@ -183,8 +186,8 @@ int fsl_mc_find_msi_domain(struct device *mc_platform_dev,
msi_domain = of_msi_get_domain(mc_platform_dev, mc_of_node,
DOMAIN_BUS_FSL_MC_MSI);
if (!msi_domain) {
- pr_err("Unable to find fsl-mc MSI domain for %s\n",
- mc_of_node->full_name);
+ pr_err("Unable to find fsl-mc MSI domain for %pOF\n",
+ mc_of_node);
return -ENOENT;
}
diff --git a/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c
index 865d385..123e4af 100644
--- a/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c
+++ b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c
@@ -11,7 +11,6 @@
#include <linux/of_device.h>
#include <linux/of_address.h>
-#include <linux/irqchip/arm-gic-v3.h>
#include <linux/irq.h>
#include <linux/msi.h>
#include <linux/of.h>
@@ -46,7 +45,9 @@ static int its_fsl_mc_msi_prepare(struct irq_domain *msi_domain,
* NOTE: This device id corresponds to the IOMMU stream ID
* associated with the DPRC object (ICID).
*/
+#ifdef GENERIC_MSI_DOMAIN_OPS
info->scratchpad[0].ul = mc_bus_dev->icid;
+#endif
msi_info = msi_get_domain_info(msi_domain->parent);
return msi_info->ops->msi_prepare(msi_domain->parent, dev, nvec, info);
}
@@ -79,8 +80,7 @@ int __init its_fsl_mc_msi_init(void)
parent = irq_find_matching_host(np, DOMAIN_BUS_NEXUS);
if (!parent || !msi_get_domain_info(parent)) {
- pr_err("%s: unable to locate ITS domain\n",
- np->full_name);
+ pr_err("%pOF: unable to locate ITS domain\n", np);
continue;
}
@@ -89,15 +89,14 @@ int __init its_fsl_mc_msi_init(void)
&its_fsl_mc_msi_domain_info,
parent);
if (!mc_msi_domain) {
- pr_err("%s: unable to create fsl-mc domain\n",
- np->full_name);
+ pr_err("%pOF: unable to create fsl-mc domain\n", np);
continue;
}
WARN_ON(mc_msi_domain->host_data !=
&its_fsl_mc_msi_domain_info);
- pr_info("fsl-mc MSI: %s domain created\n", np->full_name);
+ pr_info("fsl-mc MSI: %pOF domain created\n", np);
}
return 0;
diff --git a/drivers/staging/fsl-mc/bus/mc-io.c b/drivers/staging/fsl-mc/bus/mc-io.c
index 35221a17..f65c23c 100644
--- a/drivers/staging/fsl-mc/bus/mc-io.c
+++ b/drivers/staging/fsl-mc/bus/mc-io.c
@@ -129,8 +129,8 @@ int __must_check fsl_create_mc_io(struct device *dev,
"mc_portal");
if (!res) {
dev_err(dev,
- "devm_request_mem_region failed for MC portal %#llx\n",
- mc_portal_phys_addr);
+ "devm_request_mem_region failed for MC portal %pa\n",
+ &mc_portal_phys_addr);
return -EBUSY;
}
@@ -139,8 +139,8 @@ int __must_check fsl_create_mc_io(struct device *dev,
mc_portal_size);
if (!mc_portal_virt_addr) {
dev_err(dev,
- "devm_ioremap_nocache failed for MC portal %#llx\n",
- mc_portal_phys_addr);
+ "devm_ioremap_nocache failed for MC portal %pa\n",
+ &mc_portal_phys_addr);
return -ENXIO;
}
@@ -242,8 +242,7 @@ int __must_check fsl_mc_portal_allocate(struct fsl_mc_device *mc_dev,
goto error_cleanup_resource;
mc_portal_phys_addr = dpmcp_dev->regions[0].start;
- mc_portal_size = dpmcp_dev->regions[0].end -
- dpmcp_dev->regions[0].start + 1;
+ mc_portal_size = resource_size(dpmcp_dev->regions);
if (WARN_ON(mc_portal_size != mc_bus_dev->mc_io->portal_size))
goto error_cleanup_resource;
diff --git a/drivers/staging/fsl-mc/bus/mc-sys.c b/drivers/staging/fsl-mc/bus/mc-sys.c
index a1704c3..7ce105b 100644
--- a/drivers/staging/fsl-mc/bus/mc-sys.c
+++ b/drivers/staging/fsl-mc/bus/mc-sys.c
@@ -37,6 +37,7 @@
#include <linux/ioport.h>
#include <linux/device.h>
#include <linux/io.h>
+#include <linux/io-64-nonatomic-hi-lo.h>
#include "../include/mc.h"
#include "dpmcp.h"
@@ -126,11 +127,15 @@ static inline void mc_write_command(struct mc_command __iomem *portal,
/* copy command parameters into the portal */
for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++)
- __raw_writeq(cmd->params[i], &portal->params[i]);
- __iowmb();
+ /*
+ * Data is already in the expected LE byte-order. Do an
+ * extra LE -> CPU conversion so that the CPU -> LE done in
+ * the device io write api puts it back in the right order.
+ */
+ writeq_relaxed(le64_to_cpu(cmd->params[i]), &portal->params[i]);
/* submit the command by writing the header */
- __raw_writeq(cmd->header, &portal->header);
+ writeq(le64_to_cpu(cmd->header), &portal->header);
}
/**
@@ -150,17 +155,20 @@ static inline enum mc_cmd_status mc_read_response(struct mc_command __iomem *
enum mc_cmd_status status;
/* Copy command response header from MC portal: */
- __iormb();
- resp->header = __raw_readq(&portal->header);
- __iormb();
+ resp->header = cpu_to_le64(readq_relaxed(&portal->header));
status = mc_cmd_hdr_read_status(resp);
if (status != MC_CMD_STATUS_OK)
return status;
/* Copy command response data from MC portal: */
for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++)
- resp->params[i] = __raw_readq(&portal->params[i]);
- __iormb();
+ /*
+ * Data is expected to be in LE byte-order. Do an
+ * extra CPU -> LE to revert the LE -> CPU done in
+ * the device io read api.
+ */
+ resp->params[i] =
+ cpu_to_le64(readq_relaxed(&portal->params[i]));
return status;
}
@@ -198,8 +206,8 @@ static int mc_polling_wait_preemptible(struct fsl_mc_io *mc_io,
if (time_after_eq(jiffies, jiffies_until_timeout)) {
dev_dbg(mc_io->dev,
- "MC command timed out (portal: %#llx, dprc handle: %#x, command: %#x)\n",
- mc_io->portal_phys_addr,
+ "MC command timed out (portal: %pa, dprc handle: %#x, command: %#x)\n",
+ &mc_io->portal_phys_addr,
(unsigned int)mc_cmd_hdr_read_token(cmd),
(unsigned int)mc_cmd_hdr_read_cmdid(cmd));
@@ -238,8 +246,8 @@ static int mc_polling_wait_atomic(struct fsl_mc_io *mc_io,
timeout_usecs -= MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS;
if (timeout_usecs == 0) {
dev_dbg(mc_io->dev,
- "MC command timed out (portal: %#llx, dprc handle: %#x, command: %#x)\n",
- mc_io->portal_phys_addr,
+ "MC command timed out (portal: %pa, dprc handle: %#x, command: %#x)\n",
+ &mc_io->portal_phys_addr,
(unsigned int)mc_cmd_hdr_read_token(cmd),
(unsigned int)mc_cmd_hdr_read_cmdid(cmd));
@@ -292,8 +300,8 @@ int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd)
if (status != MC_CMD_STATUS_OK) {
dev_dbg(mc_io->dev,
- "MC command failed: portal: %#llx, dprc handle: %#x, command: %#x, status: %s (%#x)\n",
- mc_io->portal_phys_addr,
+ "MC command failed: portal: %pa, dprc handle: %#x, command: %#x, status: %s (%#x)\n",
+ &mc_io->portal_phys_addr,
(unsigned int)mc_cmd_hdr_read_token(cmd),
(unsigned int)mc_cmd_hdr_read_cmdid(cmd),
mc_status_to_string(status),
diff --git a/drivers/staging/fsl-mc/include/dpaa2-io.h b/drivers/staging/fsl-mc/include/dpaa2-io.h
index 002829c..c564609 100644
--- a/drivers/staging/fsl-mc/include/dpaa2-io.h
+++ b/drivers/staging/fsl-mc/include/dpaa2-io.h
@@ -34,6 +34,7 @@
#include <linux/types.h>
#include <linux/cpumask.h>
+#include <linux/irqreturn.h>
#include "dpaa2-fd.h"
#include "dpaa2-global.h"
diff --git a/drivers/staging/goldfish/goldfish_nand.c b/drivers/staging/goldfish/goldfish_nand.c
index 8f92ff4..52cc136 100644
--- a/drivers/staging/goldfish/goldfish_nand.c
+++ b/drivers/staging/goldfish/goldfish_nand.c
@@ -153,12 +153,12 @@ static int goldfish_nand_read_oob(struct mtd_info *mtd, loff_t ofs,
ofs += mtd->writesize + ops->ooboffs;
if (ops->oobbuf)
ops->oobretlen = goldfish_nand_cmd(mtd, NAND_CMD_READ, ofs,
- ops->ooblen, ops->oobbuf);
+ ops->ooblen, ops->oobbuf);
return 0;
invalid_arg:
- pr_err("goldfish_nand_read_oob: invalid read, start %llx, len %zx, ooblen %zx, dev_size %llx, write_size %x\n",
- ofs, ops->len, ops->ooblen, mtd->size, mtd->writesize);
+ pr_err("%s: invalid read, start %llx, len %zx, ooblen %zx, dev_size %llx, write_size %x\n",
+ __func__, ofs, ops->len, ops->ooblen, mtd->size, mtd->writesize);
return -EINVAL;
}
@@ -185,12 +185,12 @@ static int goldfish_nand_write_oob(struct mtd_info *mtd, loff_t ofs,
ofs += mtd->writesize + ops->ooboffs;
if (ops->oobbuf)
ops->oobretlen = goldfish_nand_cmd(mtd, NAND_CMD_WRITE, ofs,
- ops->ooblen, ops->oobbuf);
+ ops->ooblen, ops->oobbuf);
return 0;
invalid_arg:
- pr_err("goldfish_nand_write_oob: invalid write, start %llx, len %zx, ooblen %zx, dev_size %llx, write_size %x\n",
- ofs, ops->len, ops->ooblen, mtd->size, mtd->writesize);
+ pr_err("%s: invalid write, start %llx, len %zx, ooblen %zx, dev_size %llx, write_size %x\n",
+ __func__, ofs, ops->len, ops->ooblen, mtd->size, mtd->writesize);
return -EINVAL;
}
@@ -211,8 +211,8 @@ static int goldfish_nand_read(struct mtd_info *mtd, loff_t from, size_t len,
return 0;
invalid_arg:
- pr_err("goldfish_nand_read: invalid read, start %llx, len %zx, dev_size %llx, write_size %x\n",
- from, len, mtd->size, mtd->writesize);
+ pr_err("%s: invalid read, start %llx, len %zx, dev_size %llx, write_size %x\n",
+ __func__, from, len, mtd->size, mtd->writesize);
return -EINVAL;
}
@@ -233,8 +233,8 @@ static int goldfish_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
return 0;
invalid_arg:
- pr_err("goldfish_nand_write: invalid write, start %llx, len %zx, dev_size %llx, write_size %x\n",
- to, len, mtd->size, mtd->writesize);
+ pr_err("%s: invalid write, start %llx, len %zx, dev_size %llx, write_size %x\n",
+ __func__, to, len, mtd->size, mtd->writesize);
return -EINVAL;
}
@@ -340,8 +340,8 @@ static int goldfish_nand_init_device(struct platform_device *pdev,
name);
if (result != name_len) {
dev_err(&pdev->dev,
- "goldfish_nand_init_device failed to get dev name %d != %d\n",
- result, name_len);
+ "%s: failed to get dev name %d != %d\n",
+ __func__, result, name_len);
return -ENODEV;
}
((char *)mtd->name)[name_len] = '\0';
diff --git a/drivers/staging/greybus/arche-platform.c b/drivers/staging/greybus/arche-platform.c
index eced2d2..21ac92d 100644
--- a/drivers/staging/greybus/arche-platform.c
+++ b/drivers/staging/greybus/arche-platform.c
@@ -176,7 +176,10 @@ static irqreturn_t arche_platform_wd_irq(int irq, void *devid)
arche_platform_set_wake_detect_state(arche_pdata,
WD_STATE_IDLE);
} else {
- /* Check we are not in middle of irq thread already */
+ /*
+ * Check we are not in middle of irq thread
+ * already
+ */
if (arche_pdata->wake_detect_state !=
WD_STATE_COLDBOOT_START) {
arche_platform_set_wake_detect_state(arche_pdata,
@@ -193,7 +196,7 @@ static irqreturn_t arche_platform_wd_irq(int irq, void *devid)
if (arche_pdata->wake_detect_state == WD_STATE_IDLE) {
arche_pdata->wake_detect_start = jiffies;
/*
- * In the begining, when wake/detect goes low
+ * In the beginning, when wake/detect goes low
* (first time), we assume it is meant for coldboot
* and set the flag. If wake/detect line stays low
* beyond 30msec, then it is coldboot else fallback
@@ -607,7 +610,6 @@ static int arche_platform_remove(struct platform_device *pdev)
device_remove_file(&pdev->dev, &dev_attr_state);
device_for_each_child(&pdev->dev, NULL, arche_remove_child);
arche_platform_poweroff_seq(arche_pdata);
- platform_set_drvdata(pdev, NULL);
if (usb3613_hub_mode_ctrl(false))
dev_warn(arche_pdata->dev, "failed to control hub device\n");
@@ -657,12 +659,14 @@ static SIMPLE_DEV_PM_OPS(arche_platform_pm_ops,
arche_platform_resume);
static const struct of_device_id arche_platform_of_match[] = {
- { .compatible = "google,arche-platform", }, /* Use PID/VID of SVC device */
+ /* Use PID/VID of SVC device */
+ { .compatible = "google,arche-platform", },
{ },
};
static const struct of_device_id arche_combined_id[] = {
- { .compatible = "google,arche-platform", }, /* Use PID/VID of SVC device */
+ /* Use PID/VID of SVC device */
+ { .compatible = "google,arche-platform", },
{ .compatible = "usbffff,2", },
{ },
};
diff --git a/drivers/staging/greybus/audio_codec.c b/drivers/staging/greybus/audio_codec.c
index 25c8bb4..a6d01f0 100644
--- a/drivers/staging/greybus/audio_codec.c
+++ b/drivers/staging/greybus/audio_codec.c
@@ -674,7 +674,7 @@ static int gbcodec_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
return ret;
}
-static struct snd_soc_dai_ops gbcodec_dai_ops = {
+static const struct snd_soc_dai_ops gbcodec_dai_ops = {
.startup = gbcodec_startup,
.shutdown = gbcodec_shutdown,
.hw_params = gbcodec_hw_params,
diff --git a/drivers/staging/greybus/gbphy.c b/drivers/staging/greybus/gbphy.c
index 603de6f..80c1da8 100644
--- a/drivers/staging/greybus/gbphy.c
+++ b/drivers/staging/greybus/gbphy.c
@@ -66,7 +66,7 @@ static const struct dev_pm_ops gb_gbphy_pm_ops = {
gb_gbphy_idle)
};
-static struct device_type greybus_gbphy_dev_type = {
+static const struct device_type greybus_gbphy_dev_type = {
.name = "gbphy_device",
.release = gbphy_dev_release,
.pm = &gb_gbphy_pm_ops,
diff --git a/drivers/staging/greybus/interface.c b/drivers/staging/greybus/interface.c
index a4fd516..71e5cc2 100644
--- a/drivers/staging/greybus/interface.c
+++ b/drivers/staging/greybus/interface.c
@@ -47,7 +47,7 @@ static int gb_interface_hibernate_link(struct gb_interface *intf);
static int gb_interface_refclk_set(struct gb_interface *intf, bool enable);
static int gb_interface_dme_attr_get(struct gb_interface *intf,
- u16 attr, u32 *val)
+ u16 attr, u32 *val)
{
return gb_svc_dme_peer_get(intf->hd->svc, intf->interface_id,
attr, DME_SELECTOR_INDEX_NULL, val);
@@ -64,7 +64,7 @@ static int gb_interface_read_ara_dme(struct gb_interface *intf)
*/
if (intf->ddbl1_manufacturer_id != TOSHIBA_DMID) {
dev_err(&intf->dev, "unknown manufacturer %08x\n",
- intf->ddbl1_manufacturer_id);
+ intf->ddbl1_manufacturer_id);
return -ENODEV;
}
@@ -110,7 +110,7 @@ static int gb_interface_read_dme(struct gb_interface *intf)
return ret;
if (intf->ddbl1_manufacturer_id == TOSHIBA_DMID &&
- intf->ddbl1_product_id == TOSHIBA_ES2_BRIDGE_DPID) {
+ intf->ddbl1_product_id == TOSHIBA_ES2_BRIDGE_DPID) {
intf->quirks |= GB_INTERFACE_QUIRK_NO_GMP_IDS;
intf->quirks |= GB_INTERFACE_QUIRK_NO_INIT_STATUS;
}
@@ -144,7 +144,7 @@ static int gb_interface_route_create(struct gb_interface *intf)
ret = gb_svc_intf_device_id(svc, intf_id, device_id);
if (ret) {
dev_err(&intf->dev, "failed to set device id %u: %d\n",
- device_id, ret);
+ device_id, ret);
goto err_ida_remove;
}
@@ -205,21 +205,21 @@ static int gb_interface_legacy_mode_switch(struct gb_interface *intf)
}
void gb_interface_mailbox_event(struct gb_interface *intf, u16 result,
- u32 mailbox)
+ u32 mailbox)
{
mutex_lock(&intf->mutex);
if (result) {
dev_warn(&intf->dev,
- "mailbox event with UniPro error: 0x%04x\n",
- result);
+ "mailbox event with UniPro error: 0x%04x\n",
+ result);
goto err_disable;
}
if (mailbox != GB_SVC_INTF_MAILBOX_GREYBUS) {
dev_warn(&intf->dev,
- "mailbox event with unexpected value: 0x%08x\n",
- mailbox);
+ "mailbox event with unexpected value: 0x%08x\n",
+ mailbox);
goto err_disable;
}
@@ -230,7 +230,7 @@ void gb_interface_mailbox_event(struct gb_interface *intf, u16 result,
if (!intf->mode_switch) {
dev_warn(&intf->dev, "unexpected mailbox event: 0x%08x\n",
- mailbox);
+ mailbox);
goto err_disable;
}
@@ -299,7 +299,7 @@ static void gb_interface_mode_switch_work(struct work_struct *work)
ret = gb_interface_enable(intf);
if (ret) {
dev_err(&intf->dev, "failed to re-enable interface: %d\n",
- ret);
+ ret);
gb_interface_deactivate(intf);
}
}
@@ -619,7 +619,7 @@ static struct attribute *interface_common_attrs[] = {
};
static umode_t interface_unipro_is_visible(struct kobject *kobj,
- struct attribute *attr, int n)
+ struct attribute *attr, int n)
{
struct device *dev = container_of(kobj, struct device, kobj);
struct gb_interface *intf = to_gb_interface(dev);
@@ -634,7 +634,7 @@ static umode_t interface_unipro_is_visible(struct kobject *kobj,
}
static umode_t interface_greybus_is_visible(struct kobject *kobj,
- struct attribute *attr, int n)
+ struct attribute *attr, int n)
{
struct device *dev = container_of(kobj, struct device, kobj);
struct gb_interface *intf = to_gb_interface(dev);
@@ -648,7 +648,7 @@ static umode_t interface_greybus_is_visible(struct kobject *kobj,
}
static umode_t interface_power_is_visible(struct kobject *kobj,
- struct attribute *attr, int n)
+ struct attribute *attr, int n)
{
struct device *dev = container_of(kobj, struct device, kobj);
struct gb_interface *intf = to_gb_interface(dev);
@@ -813,7 +813,7 @@ struct gb_interface *gb_interface_create(struct gb_module *module,
intf->dev.dma_mask = module->dev.dma_mask;
device_initialize(&intf->dev);
dev_set_name(&intf->dev, "%s.%u", dev_name(&module->dev),
- interface_id);
+ interface_id);
pm_runtime_set_autosuspend_delay(&intf->dev,
GB_INTERFACE_AUTOSUSPEND_MS);
@@ -1083,7 +1083,7 @@ int gb_interface_enable(struct gb_interface *intf)
control = gb_control_create(intf);
if (IS_ERR(control)) {
dev_err(&intf->dev, "failed to create control device: %ld\n",
- PTR_ERR(control));
+ PTR_ERR(control));
return PTR_ERR(control);
}
intf->control = control;
@@ -1228,17 +1228,17 @@ int gb_interface_add(struct gb_interface *intf)
trace_gb_interface_add(intf);
dev_info(&intf->dev, "Interface added (%s)\n",
- gb_interface_type_string(intf));
+ gb_interface_type_string(intf));
switch (intf->type) {
case GB_INTERFACE_TYPE_GREYBUS:
dev_info(&intf->dev, "GMP VID=0x%08x, PID=0x%08x\n",
- intf->vendor_id, intf->product_id);
+ intf->vendor_id, intf->product_id);
/* fall-through */
case GB_INTERFACE_TYPE_UNIPRO:
dev_info(&intf->dev, "DDBL1 Manufacturer=0x%08x, Product=0x%08x\n",
- intf->ddbl1_manufacturer_id,
- intf->ddbl1_product_id);
+ intf->ddbl1_manufacturer_id,
+ intf->ddbl1_product_id);
break;
default:
break;
diff --git a/drivers/staging/greybus/spilib.h b/drivers/staging/greybus/spilib.h
index 566d0dd..cb60925 100644
--- a/drivers/staging/greybus/spilib.h
+++ b/drivers/staging/greybus/spilib.h
@@ -18,7 +18,8 @@ struct spilib_ops {
void (*unprepare_transfer_hardware)(struct device *dev);
};
-int gb_spilib_master_init(struct gb_connection *connection, struct device *dev, struct spilib_ops *ops);
+int gb_spilib_master_init(struct gb_connection *connection,
+ struct device *dev, struct spilib_ops *ops);
void gb_spilib_master_exit(struct gb_connection *connection);
#endif /* __SPILIB_H */
diff --git a/drivers/staging/greybus/tools/loopback_test.c b/drivers/staging/greybus/tools/loopback_test.c
index 32a4369..fbe589f 100644
--- a/drivers/staging/greybus/tools/loopback_test.c
+++ b/drivers/staging/greybus/tools/loopback_test.c
@@ -420,10 +420,10 @@ void log_csv_error(int len, int err)
}
int format_output(struct loopback_test *t,
- struct loopback_results *r,
- const char *dev_name,
- char *buf, int buf_len,
- struct tm *tm)
+ struct loopback_results *r,
+ const char *dev_name,
+ char *buf, int buf_len,
+ struct tm *tm)
{
int len = 0;
@@ -528,14 +528,14 @@ static int log_results(struct loopback_test *t)
tm = *localtime(&local_time);
/*
- * file name will test_name_size_iteration_max.csv
- * every time the same test with the same parameters is run we will then
- * append to the same CSV with datestamp - representing each test
- * dataset.
- */
+ * file name will test_name_size_iteration_max.csv
+ * every time the same test with the same parameters is run we will then
+ * append to the same CSV with datestamp - representing each test
+ * dataset.
+ */
if (t->file_output && !t->porcelain) {
snprintf(file_name, sizeof(file_name), "%s_%d_%d.csv",
- t->test_name, t->size, t->iteration_max);
+ t->test_name, t->size, t->iteration_max);
fd = open(file_name, O_WRONLY | O_CREAT | O_APPEND, 0644);
if (fd < 0) {
@@ -549,8 +549,8 @@ static int log_results(struct loopback_test *t)
continue;
len = format_output(t, &t->devices[i].results,
- t->devices[i].name,
- data, sizeof(data), &tm);
+ t->devices[i].name,
+ data, sizeof(data), &tm);
if (t->file_output && !t->porcelain) {
ret = write(fd, data, len);
if (ret == -1)
@@ -562,7 +562,7 @@ static int log_results(struct loopback_test *t)
if (t->aggregate_output) {
len = format_output(t, &t->aggregate_results, "aggregate",
- data, sizeof(data), &tm);
+ data, sizeof(data), &tm);
if (t->file_output && !t->porcelain) {
ret = write(fd, data, len);
if (ret == -1)
@@ -623,14 +623,13 @@ int find_loopback_devices(struct loopback_test *t)
snprintf(d->name, MAX_STR_LEN, "gb_loopback%u", dev_id);
snprintf(d->sysfs_entry, MAX_SYSFS_PATH, "%s%s/",
- t->sysfs_prefix, d->name);
+ t->sysfs_prefix, d->name);
snprintf(d->debugfs_entry, MAX_SYSFS_PATH, "%sraw_latency_%s",
- t->debugfs_prefix, d->name);
+ t->debugfs_prefix, d->name);
if (t->debug)
- printf("add %s %s\n", d->sysfs_entry,
- d->debugfs_entry);
+ printf("add %s %s\n", d->sysfs_entry, d->debugfs_entry);
}
ret = 0;
@@ -779,7 +778,8 @@ static void prepare_devices(struct loopback_test *t)
{
int i;
- /* Cancel any running tests on enabled devices. If
+ /*
+ * Cancel any running tests on enabled devices. If
* stop_all option is given, stop test on all devices.
*/
for (i = 0; i < t->device_count; i++)
@@ -802,16 +802,14 @@ static void prepare_devices(struct loopback_test *t)
t->iteration_max);
if (t->use_async) {
+ write_sysfs_val(t->devices[i].sysfs_entry, "async", 1);
write_sysfs_val(t->devices[i].sysfs_entry,
- "async", 1);
+ "timeout", t->async_timeout);
write_sysfs_val(t->devices[i].sysfs_entry,
- "timeout", t->async_timeout);
- write_sysfs_val(t->devices[i].sysfs_entry,
- "outstanding_operations_max",
- t->async_outstanding_operations);
+ "outstanding_operations_max",
+ t->async_outstanding_operations);
} else
- write_sysfs_val(t->devices[i].sysfs_entry,
- "async", 0);
+ write_sysfs_val(t->devices[i].sysfs_entry, "async", 0);
}
}
diff --git a/drivers/staging/greybus/usb.c b/drivers/staging/greybus/usb.c
index ccadda0..f93a76d 100644
--- a/drivers/staging/greybus/usb.c
+++ b/drivers/staging/greybus/usb.c
@@ -139,7 +139,7 @@ out:
return ret;
}
-static struct hc_driver usb_gb_hc_driver = {
+static const struct hc_driver usb_gb_hc_driver = {
.description = "greybus-hcd",
.product_desc = "Greybus USB Host Controller",
.hcd_priv_size = sizeof(struct gb_usb_device),
diff --git a/drivers/staging/greybus/vibrator.c b/drivers/staging/greybus/vibrator.c
index 77a2365..5cd8a50 100644
--- a/drivers/staging/greybus/vibrator.c
+++ b/drivers/staging/greybus/vibrator.c
@@ -34,7 +34,7 @@ static int turn_off(struct gb_vibrator_device *vib)
int ret;
ret = gb_operation_sync(vib->connection, GB_VIBRATOR_TYPE_OFF,
- NULL, 0, NULL, 0);
+ NULL, 0, NULL, 0);
gb_pm_runtime_put_autosuspend(bundle);
@@ -55,7 +55,7 @@ static int turn_on(struct gb_vibrator_device *vib, u16 timeout_ms)
turn_off(vib);
ret = gb_operation_sync(vib->connection, GB_VIBRATOR_TYPE_ON,
- NULL, 0, NULL, 0);
+ NULL, 0, NULL, 0);
if (ret) {
gb_pm_runtime_put_autosuspend(bundle);
return ret;
@@ -116,7 +116,7 @@ static struct class vibrator_class = {
static DEFINE_IDA(minors);
static int gb_vibrator_probe(struct gb_bundle *bundle,
- const struct greybus_bundle_id *id)
+ const struct greybus_bundle_id *id)
{
struct greybus_descriptor_cport *cport_desc;
struct gb_connection *connection;
@@ -136,7 +136,7 @@ static int gb_vibrator_probe(struct gb_bundle *bundle,
return -ENOMEM;
connection = gb_connection_create(bundle, le16_to_cpu(cport_desc->id),
- NULL);
+ NULL);
if (IS_ERR(connection)) {
retval = PTR_ERR(connection);
goto err_free_vib;
diff --git a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c
index 19b550f..bcbdc73 100644
--- a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c
+++ b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c
@@ -23,6 +23,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/firmware.h>
+#include <asm/unaligned.h>
#include "gs_fpgaboot.h"
#include "io.h"
@@ -41,16 +42,16 @@ static char *file = "xlinx_fpga_firmware.bit";
module_param(file, charp, 0444);
MODULE_PARM_DESC(file, "Xilinx FPGA firmware file.");
-static void read_bitstream(char *bitdata, char *buf, int *offset, int rdsize)
+static void read_bitstream(u8 *bitdata, u8 *buf, int *offset, int rdsize)
{
memcpy(buf, bitdata + *offset, rdsize);
*offset += rdsize;
}
-static void readinfo_bitstream(char *bitdata, char *buf, int *offset)
+static int readinfo_bitstream(u8 *bitdata, u8 *buf, int size, int *offset)
{
- char tbuf[64];
- s32 len;
+ u8 tbuf[2];
+ u16 len;
/* read section char */
read_bitstream(bitdata, tbuf, offset, 1);
@@ -58,18 +59,24 @@ static void readinfo_bitstream(char *bitdata, char *buf, int *offset)
/* read length */
read_bitstream(bitdata, tbuf, offset, 2);
- len = tbuf[0] << 8 | tbuf[1];
+ len = get_unaligned_be16(tbuf);
+ if (len >= size) {
+ pr_err("error: readinfo buffer too small\n");
+ return -EINVAL;
+ }
read_bitstream(bitdata, buf, offset, len);
buf[len] = '\0';
+
+ return 0;
}
/*
* read bitdata length
*/
-static int readlength_bitstream(char *bitdata, int *lendata, int *offset)
+static int readlength_bitstream(u8 *bitdata, int *lendata, int *offset)
{
- char tbuf[64];
+ u8 tbuf[4];
/* read section char */
read_bitstream(bitdata, tbuf, offset, 1);
@@ -77,14 +84,13 @@ static int readlength_bitstream(char *bitdata, int *lendata, int *offset)
/* make sure it is section 'e' */
if (tbuf[0] != 'e') {
pr_err("error: length section is not 'e', but %c\n", tbuf[0]);
- return -1;
+ return -EINVAL;
}
/* read 4bytes length */
read_bitstream(bitdata, tbuf, offset, 4);
- *lendata = tbuf[0] << 24 | tbuf[1] << 16 |
- tbuf[2] << 8 | tbuf[3];
+ *lendata = get_unaligned_be32(tbuf);
return 0;
}
@@ -92,16 +98,16 @@ static int readlength_bitstream(char *bitdata, int *lendata, int *offset)
/*
* read first 13 bytes to check bitstream magic number
*/
-static int readmagic_bitstream(char *bitdata, int *offset)
+static int readmagic_bitstream(u8 *bitdata, int *offset)
{
- char buf[13];
+ u8 buf[13];
int r;
read_bitstream(bitdata, buf, offset, 13);
r = memcmp(buf, bits_magic, 13);
if (r) {
pr_err("error: corrupted header");
- return -1;
+ return -EINVAL;
}
pr_info("bitstream file magic number Ok\n");
@@ -113,7 +119,7 @@ static int readmagic_bitstream(char *bitdata, int *offset)
/*
* NOTE: supports only bitstream format
*/
-static enum fmt_image get_imageformat(struct fpgaimage *fimage)
+static enum fmt_image get_imageformat(void)
{
return f_bit;
}
@@ -127,38 +133,58 @@ static void gs_print_header(struct fpgaimage *fimage)
pr_info("lendata: %d\n", fimage->lendata);
}
-static void gs_read_bitstream(struct fpgaimage *fimage)
+static int gs_read_bitstream(struct fpgaimage *fimage)
{
- char *bitdata;
+ u8 *bitdata;
int offset;
+ int err;
offset = 0;
- bitdata = (char *)fimage->fw_entry->data;
+ bitdata = (u8 *)fimage->fw_entry->data;
+
+ err = readmagic_bitstream(bitdata, &offset);
+ if (err)
+ return err;
+
+ err = readinfo_bitstream(bitdata, fimage->filename, MAX_STR, &offset);
+ if (err)
+ return err;
+ err = readinfo_bitstream(bitdata, fimage->part, MAX_STR, &offset);
+ if (err)
+ return err;
+ err = readinfo_bitstream(bitdata, fimage->date, MAX_STR, &offset);
+ if (err)
+ return err;
+ err = readinfo_bitstream(bitdata, fimage->time, MAX_STR, &offset);
+ if (err)
+ return err;
- readmagic_bitstream(bitdata, &offset);
- readinfo_bitstream(bitdata, fimage->filename, &offset);
- readinfo_bitstream(bitdata, fimage->part, &offset);
- readinfo_bitstream(bitdata, fimage->date, &offset);
- readinfo_bitstream(bitdata, fimage->time, &offset);
- readlength_bitstream(bitdata, &fimage->lendata, &offset);
+ err = readlength_bitstream(bitdata, &fimage->lendata, &offset);
+ if (err)
+ return err;
fimage->fpgadata = bitdata + offset;
+
+ return 0;
}
static int gs_read_image(struct fpgaimage *fimage)
{
int img_fmt;
+ int err;
- img_fmt = get_imageformat(fimage);
+ img_fmt = get_imageformat();
switch (img_fmt) {
case f_bit:
pr_info("image is bitstream format\n");
- gs_read_bitstream(fimage);
+ err = gs_read_bitstream(fimage);
+ if (err)
+ return err;
break;
default:
pr_err("unsupported fpga image format\n");
- return -1;
+ return -EINVAL;
}
gs_print_header(fimage);
@@ -183,11 +209,11 @@ static int gs_load_image(struct fpgaimage *fimage, char *fw_file)
static int gs_download_image(struct fpgaimage *fimage, enum wbus bus_bytes)
{
- char *bitdata;
+ u8 *bitdata;
int size, i, cnt;
cnt = 0;
- bitdata = (char *)fimage->fpgadata;
+ bitdata = (u8 *)fimage->fpgadata;
size = fimage->lendata;
#ifdef DEBUG_FPGA
@@ -197,7 +223,7 @@ static int gs_download_image(struct fpgaimage *fimage, enum wbus bus_bytes)
if (!xl_supported_prog_bus_width(bus_bytes)) {
pr_err("unsupported program bus width %d\n",
bus_bytes);
- return -1;
+ return -EINVAL;
}
/* Bring csi_b, rdwr_b Low and program_b High */
@@ -224,7 +250,7 @@ static int gs_download_image(struct fpgaimage *fimage, enum wbus bus_bytes)
/* Check INIT_B */
if (xl_get_init_b() == 0) {
pr_err("init_b 0\n");
- return -1;
+ return -EIO;
}
while (xl_get_done_b() == 0) {
@@ -236,7 +262,7 @@ static int gs_download_image(struct fpgaimage *fimage, enum wbus bus_bytes)
if (cnt > MAX_WAIT_DONE) {
pr_err("fpga download fail\n");
- return -1;
+ return -EIO;
}
pr_info("download fpgaimage\n");
@@ -325,7 +351,7 @@ err_out2:
err_out1:
kfree(fimage);
- return -1;
+ return err;
}
static int __init gs_fpgaboot_init(void)
diff --git a/drivers/staging/gs_fpgaboot/gs_fpgaboot.h b/drivers/staging/gs_fpgaboot/gs_fpgaboot.h
index cd1eb2c..986e841 100644
--- a/drivers/staging/gs_fpgaboot/gs_fpgaboot.h
+++ b/drivers/staging/gs_fpgaboot/gs_fpgaboot.h
@@ -47,5 +47,5 @@ struct fpgaimage {
char date[MAX_STR];
char time[MAX_STR];
int lendata;
- char *fpgadata;
+ u8 *fpgadata;
};
diff --git a/drivers/staging/gs_fpgaboot/io.c b/drivers/staging/gs_fpgaboot/io.c
index c939119..83a13ca 100644
--- a/drivers/staging/gs_fpgaboot/io.c
+++ b/drivers/staging/gs_fpgaboot/io.c
@@ -9,10 +9,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/kernel.h>
diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c
index d5ab83f..f85dde9 100644
--- a/drivers/staging/iio/adc/ad7280a.c
+++ b/drivers/staging/iio/adc/ad7280a.c
@@ -99,9 +99,14 @@
#define AD7280A_DEVADDR_MASTER 0
#define AD7280A_DEVADDR_ALL 0x1F
/* 5-bit device address is sent LSB first */
-#define AD7280A_DEVADDR(addr) (((addr & 0x1) << 4) | ((addr & 0x2) << 3) | \
- (addr & 0x4) | ((addr & 0x8) >> 3) | \
- ((addr & 0x10) >> 4))
+static unsigned int ad7280a_devaddr(unsigned int addr)
+{
+ return ((addr & 0x1) << 4) |
+ ((addr & 0x2) << 3) |
+ (addr & 0x4) |
+ ((addr & 0x8) >> 3) |
+ ((addr & 0x10) >> 4);
+}
/* During a read a valid write is mandatory.
* So writing to the highest available address (Address 0x1F)
@@ -372,7 +377,7 @@ static int ad7280_chain_setup(struct ad7280_state *st)
if (ad7280_check_crc(st, val))
return -EIO;
- if (n != AD7280A_DEVADDR(val >> 27))
+ if (n != ad7280a_devaddr(val >> 27))
return -EIO;
}
@@ -511,7 +516,7 @@ static int ad7280_channel_init(struct ad7280_state *st)
st->channels[cnt].info_mask_shared_by_type =
BIT(IIO_CHAN_INFO_SCALE);
st->channels[cnt].address =
- AD7280A_DEVADDR(dev) << 8 | ch;
+ ad7280a_devaddr(dev) << 8 | ch;
st->channels[cnt].scan_index = cnt;
st->channels[cnt].scan_type.sign = 'u';
st->channels[cnt].scan_type.realbits = 12;
@@ -558,7 +563,7 @@ static int ad7280_attr_init(struct ad7280_state *st)
for (ch = AD7280A_CELL_VOLTAGE_1; ch <= AD7280A_CELL_VOLTAGE_6;
ch++, cnt++) {
st->iio_attr[cnt].address =
- AD7280A_DEVADDR(dev) << 8 | ch;
+ ad7280a_devaddr(dev) << 8 | ch;
st->iio_attr[cnt].dev_attr.attr.mode =
0644;
st->iio_attr[cnt].dev_attr.show =
@@ -574,7 +579,7 @@ static int ad7280_attr_init(struct ad7280_state *st)
&st->iio_attr[cnt].dev_attr.attr;
cnt++;
st->iio_attr[cnt].address =
- AD7280A_DEVADDR(dev) << 8 |
+ ad7280a_devaddr(dev) << 8 |
(AD7280A_CB1_TIMER + ch);
st->iio_attr[cnt].dev_attr.attr.mode =
0644;
@@ -918,7 +923,7 @@ static int ad7280_probe(struct spi_device *spi)
if (ret)
goto error_unregister;
- ret = ad7280_write(st, AD7280A_DEVADDR(st->slave_num),
+ ret = ad7280_write(st, ad7280a_devaddr(st->slave_num),
AD7280A_ALERT, 0,
AD7280A_ALERT_GEN_STATIC_HIGH |
(pdata->chain_last_alert_ignore & 0xF));
diff --git a/drivers/staging/iio/adc/ad7606_par.c b/drivers/staging/iio/adc/ad7606_par.c
index cd6c410c..3eb6f8f 100644
--- a/drivers/staging/iio/adc/ad7606_par.c
+++ b/drivers/staging/iio/adc/ad7606_par.c
@@ -57,8 +57,8 @@ static int ad7606_par_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
- dev_err(&pdev->dev, "no irq\n");
- return -ENODEV;
+ dev_err(&pdev->dev, "no irq: %d\n", irq);
+ return irq;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff --git a/drivers/staging/iio/light/tsl2x7x.c b/drivers/staging/iio/light/tsl2x7x.c
index 1467199..786e93f 100644
--- a/drivers/staging/iio/light/tsl2x7x.c
+++ b/drivers/staging/iio/light/tsl2x7x.c
@@ -285,35 +285,6 @@ static const u8 device_channel_config[] = {
};
/**
- * tsl2x7x_i2c_read() - Read a byte from a register.
- * @client: i2c client
- * @reg: device register to read from
- * @*val: pointer to location to store register contents.
- *
- */
-static int
-tsl2x7x_i2c_read(struct i2c_client *client, u8 reg, u8 *val)
-{
- int ret;
-
- /* select register to write */
- ret = i2c_smbus_write_byte(client, (TSL2X7X_CMD_REG | reg));
- if (ret < 0) {
- dev_err(&client->dev, "failed to write register %x\n", reg);
- return ret;
- }
-
- /* read the data */
- ret = i2c_smbus_read_byte(client);
- if (ret >= 0)
- *val = (u8)ret;
- else
- dev_err(&client->dev, "failed to read register %x\n", reg);
-
- return ret;
-}
-
-/**
* tsl2x7x_get_lux() - Reads and calculates current lux value.
* @indio_dev: pointer to IIO device
*
@@ -352,15 +323,15 @@ static int tsl2x7x_get_lux(struct iio_dev *indio_dev)
goto out_unlock;
}
- ret = tsl2x7x_i2c_read(chip->client,
- (TSL2X7X_CMD_REG | TSL2X7X_STATUS), &buf[0]);
+ ret = i2c_smbus_read_byte_data(chip->client,
+ TSL2X7X_CMD_REG | TSL2X7X_STATUS);
if (ret < 0) {
dev_err(&chip->client->dev,
"%s: Failed to read STATUS Reg\n", __func__);
goto out_unlock;
}
/* is data new & valid */
- if (!(buf[0] & TSL2X7X_STA_ADC_VALID)) {
+ if (!(ret & TSL2X7X_STA_ADC_VALID)) {
dev_err(&chip->client->dev,
"%s: data not valid yet\n", __func__);
ret = chip->als_cur_info.lux; /* return LAST VALUE */
@@ -368,14 +339,16 @@ static int tsl2x7x_get_lux(struct iio_dev *indio_dev)
}
for (i = 0; i < 4; i++) {
- ret = tsl2x7x_i2c_read(chip->client,
- (TSL2X7X_CMD_REG |
- (TSL2X7X_ALS_CHAN0LO + i)), &buf[i]);
+ int reg = TSL2X7X_CMD_REG | (TSL2X7X_ALS_CHAN0LO + i);
+
+ ret = i2c_smbus_read_byte_data(chip->client, reg);
if (ret < 0) {
dev_err(&chip->client->dev,
"failed to read. err=%x\n", ret);
goto out_unlock;
}
+
+ buf[i] = ret;
}
/* clear any existing interrupt status */
@@ -475,7 +448,6 @@ static int tsl2x7x_get_prox(struct iio_dev *indio_dev)
{
int i;
int ret;
- u8 status;
u8 chdata[2];
struct tsl2X7X_chip *chip = iio_priv(indio_dev);
@@ -485,8 +457,8 @@ static int tsl2x7x_get_prox(struct iio_dev *indio_dev)
return -EBUSY;
}
- ret = tsl2x7x_i2c_read(chip->client,
- (TSL2X7X_CMD_REG | TSL2X7X_STATUS), &status);
+ ret = i2c_smbus_read_byte_data(chip->client,
+ TSL2X7X_CMD_REG | TSL2X7X_STATUS);
if (ret < 0) {
dev_err(&chip->client->dev, "i2c err=%d\n", ret);
goto prox_poll_err;
@@ -498,7 +470,7 @@ static int tsl2x7x_get_prox(struct iio_dev *indio_dev)
case tmd2671:
case tsl2771:
case tmd2771:
- if (!(status & TSL2X7X_STA_ADC_VALID))
+ if (!(ret & TSL2X7X_STA_ADC_VALID))
goto prox_poll_err;
break;
case tsl2572:
@@ -506,17 +478,19 @@ static int tsl2x7x_get_prox(struct iio_dev *indio_dev)
case tmd2672:
case tsl2772:
case tmd2772:
- if (!(status & TSL2X7X_STA_PRX_VALID))
+ if (!(ret & TSL2X7X_STA_PRX_VALID))
goto prox_poll_err;
break;
}
for (i = 0; i < 2; i++) {
- ret = tsl2x7x_i2c_read(chip->client,
- (TSL2X7X_CMD_REG |
- (TSL2X7X_PRX_LO + i)), &chdata[i]);
+ int reg = TSL2X7X_CMD_REG | (TSL2X7X_PRX_LO + i);
+
+ ret = i2c_smbus_read_byte_data(chip->client, reg);
if (ret < 0)
goto prox_poll_err;
+
+ chdata[i] = ret;
}
chip->prox_data =
@@ -568,39 +542,29 @@ static void tsl2x7x_defaults(struct tsl2X7X_chip *chip)
static int tsl2x7x_als_calibrate(struct iio_dev *indio_dev)
{
struct tsl2X7X_chip *chip = iio_priv(indio_dev);
- u8 reg_val;
int gain_trim_val;
int ret;
int lux_val;
- ret = i2c_smbus_write_byte(chip->client,
- (TSL2X7X_CMD_REG | TSL2X7X_CNTRL));
+ ret = i2c_smbus_read_byte_data(chip->client,
+ TSL2X7X_CMD_REG | TSL2X7X_CNTRL);
if (ret < 0) {
dev_err(&chip->client->dev,
- "failed to write CNTRL register, ret=%d\n", ret);
+ "%s: failed to read from the CNTRL register\n",
+ __func__);
return ret;
}
- reg_val = i2c_smbus_read_byte(chip->client);
- if ((reg_val & (TSL2X7X_CNTL_ADC_ENBL | TSL2X7X_CNTL_PWR_ON))
- != (TSL2X7X_CNTL_ADC_ENBL | TSL2X7X_CNTL_PWR_ON)) {
- dev_err(&chip->client->dev,
- "%s: failed: ADC not enabled\n", __func__);
- return -1;
- }
-
- ret = i2c_smbus_write_byte(chip->client,
- (TSL2X7X_CMD_REG | TSL2X7X_CNTRL));
- if (ret < 0) {
+ if ((ret & (TSL2X7X_CNTL_ADC_ENBL | TSL2X7X_CNTL_PWR_ON))
+ != (TSL2X7X_CNTL_ADC_ENBL | TSL2X7X_CNTL_PWR_ON)) {
dev_err(&chip->client->dev,
- "failed to write ctrl reg: ret=%d\n", ret);
- return ret;
- }
-
- reg_val = i2c_smbus_read_byte(chip->client);
- if ((reg_val & TSL2X7X_STA_ADC_VALID) != TSL2X7X_STA_ADC_VALID) {
+ "%s: Device is not powered on and/or ADC is not enabled\n",
+ __func__);
+ return -EINVAL;
+ } else if ((ret & TSL2X7X_STA_ADC_VALID) != TSL2X7X_STA_ADC_VALID) {
dev_err(&chip->client->dev,
- "%s: failed: STATUS - ADC not valid.\n", __func__);
+ "%s: The two ADC channels have not completed an integration cycle\n",
+ __func__);
return -ENODATA;
}
@@ -722,7 +686,8 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev)
}
}
- mdelay(3); /* Power-on settling time */
+ /* Power-on settling time */
+ usleep_range(3000, 3500);
/*
* NOW enable the ADC
@@ -806,22 +771,24 @@ int tsl2x7x_invoke_change(struct iio_dev *indio_dev)
{
struct tsl2X7X_chip *chip = iio_priv(indio_dev);
int device_status = chip->tsl2x7x_chip_status;
+ int ret;
mutex_lock(&chip->als_mutex);
mutex_lock(&chip->prox_mutex);
- if (device_status == TSL2X7X_CHIP_WORKING)
- tsl2x7x_chip_off(indio_dev);
-
- tsl2x7x_chip_on(indio_dev);
+ if (device_status == TSL2X7X_CHIP_WORKING) {
+ ret = tsl2x7x_chip_off(indio_dev);
+ if (ret < 0)
+ goto unlock;
+ }
- if (device_status != TSL2X7X_CHIP_WORKING)
- tsl2x7x_chip_off(indio_dev);
+ ret = tsl2x7x_chip_on(indio_dev);
+unlock:
mutex_unlock(&chip->prox_mutex);
mutex_unlock(&chip->als_mutex);
- return 0;
+ return ret;
}
static
@@ -889,7 +856,7 @@ static void tsl2x7x_prox_cal(struct iio_dev *indio_dev)
/*gather the samples*/
for (i = 0; i < chip->tsl2x7x_settings.prox_max_samples_cal; i++) {
- mdelay(15);
+ usleep_range(15000, 17500);
tsl2x7x_get_prox(indio_dev);
prox_history[i] = chip->prox_data;
dev_info(&chip->client->dev, "2 i=%d prox data= %d\n",
@@ -915,33 +882,6 @@ static void tsl2x7x_prox_cal(struct iio_dev *indio_dev)
tsl2x7x_chip_on(indio_dev);
}
-static ssize_t power_state_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev));
-
- return snprintf(buf, PAGE_SIZE, "%d\n", chip->tsl2x7x_chip_status);
-}
-
-static ssize_t power_state_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- bool value;
-
- if (strtobool(buf, &value))
- return -EINVAL;
-
- if (value)
- tsl2x7x_chip_on(indio_dev);
- else
- tsl2x7x_chip_off(indio_dev);
-
- return len;
-}
-
static ssize_t in_illuminance0_calibscale_available_show(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -1027,6 +967,7 @@ static ssize_t in_illuminance0_target_input_store(struct device *dev,
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct tsl2X7X_chip *chip = iio_priv(indio_dev);
unsigned long value;
+ int ret;
if (kstrtoul(buf, 0, &value))
return -EINVAL;
@@ -1034,7 +975,9 @@ static ssize_t in_illuminance0_target_input_store(struct device *dev,
if (value)
chip->tsl2x7x_settings.als_cal_target = value;
- tsl2x7x_invoke_change(indio_dev);
+ ret = tsl2x7x_invoke_change(indio_dev);
+ if (ret < 0)
+ return ret;
return len;
}
@@ -1083,7 +1026,9 @@ static ssize_t in_intensity0_thresh_period_store(struct device *dev,
dev_info(&chip->client->dev, "%s: als persistence = %d",
__func__, filter_delay);
- tsl2x7x_invoke_change(indio_dev);
+ ret = tsl2x7x_invoke_change(indio_dev);
+ if (ret < 0)
+ return ret;
return IIO_VAL_INT_PLUS_MICRO;
}
@@ -1131,7 +1076,10 @@ static ssize_t in_proximity0_thresh_period_store(struct device *dev,
dev_info(&chip->client->dev, "%s: prox persistence = %d",
__func__, filter_delay);
- tsl2x7x_invoke_change(indio_dev);
+ ret = tsl2x7x_invoke_change(indio_dev);
+ if (ret < 0)
+ return ret;
+
return IIO_VAL_INT_PLUS_MICRO;
}
@@ -1142,6 +1090,7 @@ static ssize_t in_illuminance0_calibrate_store(struct device *dev,
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
bool value;
+ int ret;
if (strtobool(buf, &value))
return -EINVAL;
@@ -1149,7 +1098,9 @@ static ssize_t in_illuminance0_calibrate_store(struct device *dev,
if (value)
tsl2x7x_als_calibrate(indio_dev);
- tsl2x7x_invoke_change(indio_dev);
+ ret = tsl2x7x_invoke_change(indio_dev);
+ if (ret < 0)
+ return ret;
return len;
}
@@ -1189,7 +1140,7 @@ static ssize_t in_illuminance0_lux_table_store(struct device *dev,
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct tsl2X7X_chip *chip = iio_priv(indio_dev);
int value[ARRAY_SIZE(chip->tsl2x7x_device_lux) * 3 + 1];
- int n;
+ int n, ret;
get_options(buf, ARRAY_SIZE(value), value);
@@ -1217,7 +1168,9 @@ static ssize_t in_illuminance0_lux_table_store(struct device *dev,
memset(chip->tsl2x7x_device_lux, 0, sizeof(chip->tsl2x7x_device_lux));
memcpy(chip->tsl2x7x_device_lux, &value[1], (value[0] * 4));
- tsl2x7x_invoke_change(indio_dev);
+ ret = tsl2x7x_invoke_change(indio_dev);
+ if (ret < 0)
+ return ret;
return len;
}
@@ -1228,6 +1181,7 @@ static ssize_t in_proximity0_calibrate_store(struct device *dev,
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
bool value;
+ int ret;
if (strtobool(buf, &value))
return -EINVAL;
@@ -1235,7 +1189,9 @@ static ssize_t in_proximity0_calibrate_store(struct device *dev,
if (value)
tsl2x7x_prox_cal(indio_dev);
- tsl2x7x_invoke_change(indio_dev);
+ ret = tsl2x7x_invoke_change(indio_dev);
+ if (ret < 0)
+ return ret;
return len;
}
@@ -1263,6 +1219,7 @@ static int tsl2x7x_write_interrupt_config(struct iio_dev *indio_dev,
int val)
{
struct tsl2X7X_chip *chip = iio_priv(indio_dev);
+ int ret;
if (chan->type == IIO_INTENSITY) {
if (val)
@@ -1276,83 +1233,108 @@ static int tsl2x7x_write_interrupt_config(struct iio_dev *indio_dev,
chip->tsl2x7x_settings.interrupts_en &= 0x10;
}
- tsl2x7x_invoke_change(indio_dev);
+ ret = tsl2x7x_invoke_change(indio_dev);
+ if (ret < 0)
+ return ret;
return 0;
}
-static int tsl2x7x_write_thresh(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
- enum iio_event_info info,
- int val, int val2)
+static int tsl2x7x_write_event_value(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir,
+ enum iio_event_info info,
+ int val, int val2)
{
struct tsl2X7X_chip *chip = iio_priv(indio_dev);
+ int ret = -EINVAL;
- if (chan->type == IIO_INTENSITY) {
- switch (dir) {
- case IIO_EV_DIR_RISING:
- chip->tsl2x7x_settings.als_thresh_high = val;
- break;
- case IIO_EV_DIR_FALLING:
- chip->tsl2x7x_settings.als_thresh_low = val;
- break;
- default:
- return -EINVAL;
- }
- } else {
- switch (dir) {
- case IIO_EV_DIR_RISING:
- chip->tsl2x7x_settings.prox_thres_high = val;
- break;
- case IIO_EV_DIR_FALLING:
- chip->tsl2x7x_settings.prox_thres_low = val;
- break;
- default:
- return -EINVAL;
+ switch (info) {
+ case IIO_EV_INFO_VALUE:
+ if (chan->type == IIO_INTENSITY) {
+ switch (dir) {
+ case IIO_EV_DIR_RISING:
+ chip->tsl2x7x_settings.als_thresh_high = val;
+ ret = 0;
+ break;
+ case IIO_EV_DIR_FALLING:
+ chip->tsl2x7x_settings.als_thresh_low = val;
+ ret = 0;
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (dir) {
+ case IIO_EV_DIR_RISING:
+ chip->tsl2x7x_settings.prox_thres_high = val;
+ ret = 0;
+ break;
+ case IIO_EV_DIR_FALLING:
+ chip->tsl2x7x_settings.prox_thres_low = val;
+ ret = 0;
+ break;
+ default:
+ break;
+ }
}
+ break;
+ default:
+ break;
}
- tsl2x7x_invoke_change(indio_dev);
+ if (ret < 0)
+ return ret;
- return 0;
+ return tsl2x7x_invoke_change(indio_dev);
}
-static int tsl2x7x_read_thresh(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
- enum iio_event_info info,
- int *val, int *val2)
+static int tsl2x7x_read_event_value(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir,
+ enum iio_event_info info,
+ int *val, int *val2)
{
struct tsl2X7X_chip *chip = iio_priv(indio_dev);
+ int ret = -EINVAL;
- if (chan->type == IIO_INTENSITY) {
- switch (dir) {
- case IIO_EV_DIR_RISING:
- *val = chip->tsl2x7x_settings.als_thresh_high;
- break;
- case IIO_EV_DIR_FALLING:
- *val = chip->tsl2x7x_settings.als_thresh_low;
- break;
- default:
- return -EINVAL;
- }
- } else {
- switch (dir) {
- case IIO_EV_DIR_RISING:
- *val = chip->tsl2x7x_settings.prox_thres_high;
- break;
- case IIO_EV_DIR_FALLING:
- *val = chip->tsl2x7x_settings.prox_thres_low;
- break;
- default:
- return -EINVAL;
+ switch (info) {
+ case IIO_EV_INFO_VALUE:
+ if (chan->type == IIO_INTENSITY) {
+ switch (dir) {
+ case IIO_EV_DIR_RISING:
+ *val = chip->tsl2x7x_settings.als_thresh_high;
+ ret = IIO_VAL_INT;
+ break;
+ case IIO_EV_DIR_FALLING:
+ *val = chip->tsl2x7x_settings.als_thresh_low;
+ ret = IIO_VAL_INT;
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (dir) {
+ case IIO_EV_DIR_RISING:
+ *val = chip->tsl2x7x_settings.prox_thres_high;
+ ret = IIO_VAL_INT;
+ break;
+ case IIO_EV_DIR_FALLING:
+ *val = chip->tsl2x7x_settings.prox_thres_low;
+ ret = IIO_VAL_INT;
+ break;
+ default:
+ break;
+ }
}
+ break;
+ default:
+ break;
}
- return IIO_VAL_INT;
+ return ret;
}
static int tsl2x7x_read_raw(struct iio_dev *indio_dev,
@@ -1489,13 +1471,9 @@ static int tsl2x7x_write_raw(struct iio_dev *indio_dev,
return -EINVAL;
}
- tsl2x7x_invoke_change(indio_dev);
-
- return 0;
+ return tsl2x7x_invoke_change(indio_dev);
}
-static DEVICE_ATTR_RW(power_state);
-
static DEVICE_ATTR_RO(in_proximity0_calibscale_available);
static DEVICE_ATTR_RO(in_illuminance0_calibscale_available);
@@ -1515,7 +1493,7 @@ static DEVICE_ATTR_RW(in_intensity0_thresh_period);
static DEVICE_ATTR_RW(in_proximity0_thresh_period);
/* Use the default register values to identify the Taos device */
-static int tsl2x7x_device_id(unsigned char *id, int target)
+static int tsl2x7x_device_id(int *id, int target)
{
switch (target) {
case tsl2571:
@@ -1580,7 +1558,6 @@ static irqreturn_t tsl2x7x_event_handler(int irq, void *private)
}
static struct attribute *tsl2x7x_ALS_device_attrs[] = {
- &dev_attr_power_state.attr,
&dev_attr_in_illuminance0_calibscale_available.attr,
&dev_attr_in_illuminance0_integration_time.attr,
&iio_const_attr_in_illuminance0_integration_time_available.dev_attr.attr,
@@ -1591,13 +1568,11 @@ static struct attribute *tsl2x7x_ALS_device_attrs[] = {
};
static struct attribute *tsl2x7x_PRX_device_attrs[] = {
- &dev_attr_power_state.attr,
&dev_attr_in_proximity0_calibrate.attr,
NULL
};
static struct attribute *tsl2x7x_ALSPRX_device_attrs[] = {
- &dev_attr_power_state.attr,
&dev_attr_in_illuminance0_calibscale_available.attr,
&dev_attr_in_illuminance0_integration_time.attr,
&iio_const_attr_in_illuminance0_integration_time_available.dev_attr.attr,
@@ -1609,14 +1584,12 @@ static struct attribute *tsl2x7x_ALSPRX_device_attrs[] = {
};
static struct attribute *tsl2x7x_PRX2_device_attrs[] = {
- &dev_attr_power_state.attr,
&dev_attr_in_proximity0_calibrate.attr,
&dev_attr_in_proximity0_calibscale_available.attr,
NULL
};
static struct attribute *tsl2x7x_ALSPRX2_device_attrs[] = {
- &dev_attr_power_state.attr,
&dev_attr_in_illuminance0_calibscale_available.attr,
&dev_attr_in_illuminance0_integration_time.attr,
&iio_const_attr_in_illuminance0_integration_time_available.dev_attr.attr,
@@ -1684,8 +1657,8 @@ static const struct iio_info tsl2X7X_device_info[] = {
.driver_module = THIS_MODULE,
.read_raw = &tsl2x7x_read_raw,
.write_raw = &tsl2x7x_write_raw,
- .read_event_value = &tsl2x7x_read_thresh,
- .write_event_value = &tsl2x7x_write_thresh,
+ .read_event_value = &tsl2x7x_read_event_value,
+ .write_event_value = &tsl2x7x_write_event_value,
.read_event_config = &tsl2x7x_read_interrupt_config,
.write_event_config = &tsl2x7x_write_interrupt_config,
},
@@ -1695,8 +1668,8 @@ static const struct iio_info tsl2X7X_device_info[] = {
.driver_module = THIS_MODULE,
.read_raw = &tsl2x7x_read_raw,
.write_raw = &tsl2x7x_write_raw,
- .read_event_value = &tsl2x7x_read_thresh,
- .write_event_value = &tsl2x7x_write_thresh,
+ .read_event_value = &tsl2x7x_read_event_value,
+ .write_event_value = &tsl2x7x_write_event_value,
.read_event_config = &tsl2x7x_read_interrupt_config,
.write_event_config = &tsl2x7x_write_interrupt_config,
},
@@ -1706,8 +1679,8 @@ static const struct iio_info tsl2X7X_device_info[] = {
.driver_module = THIS_MODULE,
.read_raw = &tsl2x7x_read_raw,
.write_raw = &tsl2x7x_write_raw,
- .read_event_value = &tsl2x7x_read_thresh,
- .write_event_value = &tsl2x7x_write_thresh,
+ .read_event_value = &tsl2x7x_read_event_value,
+ .write_event_value = &tsl2x7x_write_event_value,
.read_event_config = &tsl2x7x_read_interrupt_config,
.write_event_config = &tsl2x7x_write_interrupt_config,
},
@@ -1717,8 +1690,8 @@ static const struct iio_info tsl2X7X_device_info[] = {
.driver_module = THIS_MODULE,
.read_raw = &tsl2x7x_read_raw,
.write_raw = &tsl2x7x_write_raw,
- .read_event_value = &tsl2x7x_read_thresh,
- .write_event_value = &tsl2x7x_write_thresh,
+ .read_event_value = &tsl2x7x_read_event_value,
+ .write_event_value = &tsl2x7x_write_event_value,
.read_event_config = &tsl2x7x_read_interrupt_config,
.write_event_config = &tsl2x7x_write_interrupt_config,
},
@@ -1728,8 +1701,8 @@ static const struct iio_info tsl2X7X_device_info[] = {
.driver_module = THIS_MODULE,
.read_raw = &tsl2x7x_read_raw,
.write_raw = &tsl2x7x_write_raw,
- .read_event_value = &tsl2x7x_read_thresh,
- .write_event_value = &tsl2x7x_write_thresh,
+ .read_event_value = &tsl2x7x_read_event_value,
+ .write_event_value = &tsl2x7x_write_event_value,
.read_event_config = &tsl2x7x_read_interrupt_config,
.write_event_config = &tsl2x7x_write_interrupt_config,
},
@@ -1877,7 +1850,6 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
const struct i2c_device_id *id)
{
int ret;
- unsigned char device_id;
struct iio_dev *indio_dev;
struct tsl2X7X_chip *chip;
@@ -1889,13 +1861,13 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
chip->client = clientp;
i2c_set_clientdata(clientp, indio_dev);
- ret = tsl2x7x_i2c_read(chip->client,
- TSL2X7X_CHIPID, &device_id);
+ ret = i2c_smbus_read_byte_data(chip->client,
+ TSL2X7X_CMD_REG | TSL2X7X_CHIPID);
if (ret < 0)
return ret;
- if ((!tsl2x7x_device_id(&device_id, id->driver_data)) ||
- (tsl2x7x_device_id(&device_id, id->driver_data) == -EINVAL)) {
+ if ((!tsl2x7x_device_id(&ret, id->driver_data)) ||
+ (tsl2x7x_device_id(&ret, id->driver_data) == -EINVAL)) {
dev_info(&chip->client->dev,
"%s: i2c device found does not match expected id\n",
__func__);
@@ -2026,6 +1998,21 @@ static struct i2c_device_id tsl2x7x_idtable[] = {
MODULE_DEVICE_TABLE(i2c, tsl2x7x_idtable);
+static const struct of_device_id tsl2x7x_of_match[] = {
+ { .compatible = "amstaos,tsl2571" },
+ { .compatible = "amstaos,tsl2671" },
+ { .compatible = "amstaos,tmd2671" },
+ { .compatible = "amstaos,tsl2771" },
+ { .compatible = "amstaos,tmd2771" },
+ { .compatible = "amstaos,tsl2572" },
+ { .compatible = "amstaos,tsl2672" },
+ { .compatible = "amstaos,tmd2672" },
+ { .compatible = "amstaos,tsl2772" },
+ { .compatible = "amstaos,tmd2772" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, tsl2x7x_of_match);
+
static const struct dev_pm_ops tsl2x7x_pm_ops = {
.suspend = tsl2x7x_suspend,
.resume = tsl2x7x_resume,
@@ -2035,6 +2022,7 @@ static const struct dev_pm_ops tsl2x7x_pm_ops = {
static struct i2c_driver tsl2x7x_driver = {
.driver = {
.name = "tsl2x7x",
+ .of_match_table = tsl2x7x_of_match,
.pm = &tsl2x7x_pm_ops,
},
.id_table = tsl2x7x_idtable,
diff --git a/drivers/staging/ks7010/ks7010_sdio.c b/drivers/staging/ks7010/ks7010_sdio.c
index 9b28ee1..8cfdff1 100644
--- a/drivers/staging/ks7010/ks7010_sdio.c
+++ b/drivers/staging/ks7010/ks7010_sdio.c
@@ -834,8 +834,6 @@ static int ks7010_sdio_probe(struct sdio_func *func,
unsigned char byte;
int ret;
- DPRINTK(5, "ks7010_sdio_probe()\n");
-
priv = NULL;
netdev = NULL;
@@ -1008,8 +1006,6 @@ static void ks7010_sdio_remove(struct sdio_func *func)
struct ks_sdio_card *card;
struct ks_wlan_private *priv;
- DPRINTK(1, "ks7010_sdio_remove()\n");
-
card = sdio_get_drvdata(func);
if (!card)
diff --git a/drivers/staging/ks7010/ks_hostif.c b/drivers/staging/ks7010/ks_hostif.c
index 24a6316..975dbbb 100644
--- a/drivers/staging/ks7010/ks_hostif.c
+++ b/drivers/staging/ks7010/ks_hostif.c
@@ -1658,8 +1658,8 @@ void hostif_phy_information_request(struct ks_wlan_private *priv)
static
void hostif_power_mgmt_request(struct ks_wlan_private *priv,
- unsigned long mode, unsigned long wake_up,
- unsigned long receive_dtims)
+ unsigned long mode, unsigned long wake_up,
+ unsigned long receive_dtims)
{
struct hostif_power_mgmt_request_t *pp;
diff --git a/drivers/staging/ks7010/ks_wlan_net.c b/drivers/staging/ks7010/ks_wlan_net.c
index 8aa12e8..0f9348b 100644
--- a/drivers/staging/ks7010/ks_wlan_net.c
+++ b/drivers/staging/ks7010/ks_wlan_net.c
@@ -1356,7 +1356,7 @@ static inline char *ks_wlan_translate_scan(struct net_device *dev,
/* Add mode */
iwe.cmd = SIOCGIWMODE;
- capabilities = le16_to_cpu(ap->capability);
+ capabilities = ap->capability;
if (capabilities & (BSS_CAP_ESS | BSS_CAP_IBSS)) {
if (capabilities & BSS_CAP_ESS)
iwe.u.mode = IW_MODE_INFRA;
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs.h b/drivers/staging/lustre/include/linux/libcfs/libcfs.h
index cc2c0e9..b48e2f0 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs.h
@@ -33,10 +33,21 @@
#ifndef __LIBCFS_LIBCFS_H__
#define __LIBCFS_LIBCFS_H__
-#include "linux/libcfs.h"
#include <linux/gfp.h>
+#include <linux/list.h>
-#include "curproc.h"
+#include <uapi/linux/lnet/libcfs_ioctl.h>
+#include <linux/libcfs/linux/libcfs.h>
+#include <linux/libcfs/libcfs_debug.h>
+#include <linux/libcfs/libcfs_private.h>
+#include <linux/libcfs/libcfs_cpu.h>
+#include <linux/libcfs/libcfs_prim.h>
+#include <linux/libcfs/libcfs_time.h>
+#include <linux/libcfs/libcfs_string.h>
+#include <linux/libcfs/libcfs_workitem.h>
+#include <linux/libcfs/libcfs_hash.h>
+#include <linux/libcfs/libcfs_fail.h>
+#include <linux/libcfs/curproc.h>
#define LIBCFS_VERSION "0.7.0"
@@ -49,8 +60,6 @@
#define LERRCHKSUM(hexnum) (((hexnum) & 0xf) ^ ((hexnum) >> 4 & 0xf) ^ \
((hexnum) >> 8 & 0xf))
-#include <linux/list.h>
-
/* need both kernel and user-land acceptor */
#define LNET_ACCEPTOR_MIN_RESERVED_PORT 512
#define LNET_ACCEPTOR_MAX_RESERVED_PORT 1023
@@ -74,17 +83,6 @@ unsigned int cfs_rand(void);
void cfs_srand(unsigned int seed1, unsigned int seed2);
void cfs_get_random_bytes(void *buf, int size);
-#include "libcfs_debug.h"
-#include "libcfs_cpu.h"
-#include "libcfs_private.h"
-#include "libcfs_ioctl.h"
-#include "libcfs_prim.h"
-#include "libcfs_time.h"
-#include "libcfs_string.h"
-#include "libcfs_workitem.h"
-#include "libcfs_hash.h"
-#include "libcfs_fail.h"
-
struct libcfs_ioctl_handler {
struct list_head item;
int (*handle_ioctl)(unsigned int cmd, struct libcfs_ioctl_hdr *hdr);
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h
index b7bd6e8..e7c3741 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h
@@ -38,6 +38,8 @@
#ifndef __LIBCFS_DEBUG_H__
#define __LIBCFS_DEBUG_H__
+#include <uapi/linux/lnet/libcfs_debug.h>
+
/*
* Debugging
*/
@@ -59,108 +61,6 @@ int libcfs_debug_str2mask(int *mask, const char *str, int is_subsys);
extern unsigned int libcfs_catastrophe;
extern unsigned int libcfs_panic_on_lbug;
-/**
- * Format for debug message headers
- */
-struct ptldebug_header {
- __u32 ph_len;
- __u32 ph_flags;
- __u32 ph_subsys;
- __u32 ph_mask;
- __u16 ph_cpu_id;
- __u16 ph_type;
- /* time_t overflow in 2106 */
- __u32 ph_sec;
- __u64 ph_usec;
- __u32 ph_stack;
- __u32 ph_pid;
- __u32 ph_extern_pid;
- __u32 ph_line_num;
-} __packed;
-
-#define PH_FLAG_FIRST_RECORD 1
-
-/* Debugging subsystems (32 bits, non-overlapping) */
-#define S_UNDEFINED 0x00000001
-#define S_MDC 0x00000002
-#define S_MDS 0x00000004
-#define S_OSC 0x00000008
-#define S_OST 0x00000010
-#define S_CLASS 0x00000020
-#define S_LOG 0x00000040
-#define S_LLITE 0x00000080
-#define S_RPC 0x00000100
-#define S_MGMT 0x00000200
-#define S_LNET 0x00000400
-#define S_LND 0x00000800 /* ALL LNDs */
-#define S_PINGER 0x00001000
-#define S_FILTER 0x00002000
-/* unused */
-#define S_ECHO 0x00008000
-#define S_LDLM 0x00010000
-#define S_LOV 0x00020000
-#define S_LQUOTA 0x00040000
-#define S_OSD 0x00080000
-#define S_LFSCK 0x00100000
-/* unused */
-/* unused */
-#define S_LMV 0x00800000 /* b_new_cmd */
-/* unused */
-#define S_SEC 0x02000000 /* upcall cache */
-#define S_GSS 0x04000000 /* b_new_cmd */
-/* unused */
-#define S_MGC 0x10000000
-#define S_MGS 0x20000000
-#define S_FID 0x40000000 /* b_new_cmd */
-#define S_FLD 0x80000000 /* b_new_cmd */
-
-#define LIBCFS_DEBUG_SUBSYS_NAMES { \
- "undefined", "mdc", "mds", "osc", "ost", "class", "log", \
- "llite", "rpc", "mgmt", "lnet", "lnd", "pinger", "filter", "", \
- "echo", "ldlm", "lov", "lquota", "osd", "lfsck", "", "", "lmv", \
- "", "sec", "gss", "", "mgc", "mgs", "fid", "fld", NULL }
-
-/* Debugging masks (32 bits, non-overlapping) */
-#define D_TRACE 0x00000001 /* ENTRY/EXIT markers */
-#define D_INODE 0x00000002
-#define D_SUPER 0x00000004
-#define D_EXT2 0x00000008 /* anything from ext2_debug */
-#define D_MALLOC 0x00000010 /* print malloc, free information */
-#define D_CACHE 0x00000020 /* cache-related items */
-#define D_INFO 0x00000040 /* general information */
-#define D_IOCTL 0x00000080 /* ioctl related information */
-#define D_NETERROR 0x00000100 /* network errors */
-#define D_NET 0x00000200 /* network communications */
-#define D_WARNING 0x00000400 /* CWARN(...) == CDEBUG (D_WARNING, ...) */
-#define D_BUFFS 0x00000800
-#define D_OTHER 0x00001000
-#define D_DENTRY 0x00002000
-#define D_NETTRACE 0x00004000
-#define D_PAGE 0x00008000 /* bulk page handling */
-#define D_DLMTRACE 0x00010000
-#define D_ERROR 0x00020000 /* CERROR(...) == CDEBUG (D_ERROR, ...) */
-#define D_EMERG 0x00040000 /* CEMERG(...) == CDEBUG (D_EMERG, ...) */
-#define D_HA 0x00080000 /* recovery and failover */
-#define D_RPCTRACE 0x00100000 /* for distributed debugging */
-#define D_VFSTRACE 0x00200000
-#define D_READA 0x00400000 /* read-ahead */
-#define D_MMAP 0x00800000
-#define D_CONFIG 0x01000000
-#define D_CONSOLE 0x02000000
-#define D_QUOTA 0x04000000
-#define D_SEC 0x08000000
-#define D_LFSCK 0x10000000 /* For both OI scrub and LFSCK */
-#define D_HSM 0x20000000
-
-#define LIBCFS_DEBUG_MASKS_NAMES { \
- "trace", "inode", "super", "ext2", "malloc", "cache", "info", \
- "ioctl", "neterror", "net", "warning", "buffs", "other", \
- "dentry", "nettrace", "page", "dlmtrace", "error", "emerg", \
- "ha", "rpctrace", "vfstrace", "reada", "mmap", "config", \
- "console", "quota", "sec", "lfsck", "hsm", NULL }
-
-#define D_CANTMASK (D_ERROR | D_EMERG | D_WARNING | D_CONSOLE)
-
#ifndef DEBUG_SUBSYSTEM
# define DEBUG_SUBSYSTEM S_UNDEFINED
#endif
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h
index e774c75..709771d 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h
@@ -154,18 +154,6 @@ do { \
/******************************************************************************/
-/* htonl hack - either this, or compile with -O2. Stupid byteorder/generic.h */
-#if defined(__GNUC__) && (__GNUC__ >= 2) && !defined(__OPTIMIZE__)
-#define ___htonl(x) __cpu_to_be32(x)
-#define ___htons(x) __cpu_to_be16(x)
-#define ___ntohl(x) __be32_to_cpu(x)
-#define ___ntohs(x) __be16_to_cpu(x)
-#define htonl(x) ___htonl(x)
-#define ntohl(x) ___ntohl(x)
-#define htons(x) ___htons(x)
-#define ntohs(x) ___ntohs(x)
-#endif
-
void libcfs_debug_dumplog(void);
int libcfs_debug_init(unsigned long bufsize);
int libcfs_debug_cleanup(void);
@@ -308,18 +296,4 @@ static inline size_t cfs_round_strlen(char *fset)
return cfs_size_round((int)strlen(fset) + 1);
}
-#define LOGL(var, len, ptr) \
-do { \
- if (var) \
- memcpy((char *)ptr, (const char *)var, len); \
- ptr += cfs_size_round(len); \
-} while (0)
-
-#define LOGU(var, len, ptr) \
-do { \
- if (var) \
- memcpy((char *)var, (const char *)ptr, len); \
- ptr += cfs_size_round(len); \
-} while (0)
-
#endif
diff --git a/drivers/staging/lustre/include/linux/lnet/api.h b/drivers/staging/lustre/include/linux/lnet/api.h
index f4b6de2..9c37f3e 100644
--- a/drivers/staging/lustre/include/linux/lnet/api.h
+++ b/drivers/staging/lustre/include/linux/lnet/api.h
@@ -44,7 +44,7 @@
* @{
*/
-#include "../lnet/types.h"
+#include <uapi/linux/lnet/lnet-types.h>
/** \defgroup lnet_init_fini Initialization and cleanup
* The LNet must be properly initialized before any LNet calls can be made.
diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
index 8ae7423..e0968ab 100644
--- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
+++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
@@ -35,11 +35,13 @@
#ifndef __LNET_LIB_LNET_H__
#define __LNET_LIB_LNET_H__
-#include "../libcfs/libcfs.h"
-#include "api.h"
-#include "lnet.h"
-#include "lib-types.h"
-#include "lib-dlc.h"
+#include <linux/libcfs/libcfs.h>
+#include <linux/lnet/api.h>
+#include <linux/lnet/lib-types.h>
+#include <uapi/linux/lnet/lnet-dlc.h>
+#include <uapi/linux/lnet/lnet-types.h>
+#include <uapi/linux/lnet/lnetctl.h>
+#include <uapi/linux/lnet/nidstr.h>
extern struct lnet the_lnet; /* THE network */
@@ -453,7 +455,8 @@ extern int portal_rotor;
int lnet_lib_init(void);
void lnet_lib_exit(void);
-int lnet_notify(struct lnet_ni *ni, lnet_nid_t peer, int alive, unsigned long when);
+int lnet_notify(struct lnet_ni *ni, lnet_nid_t peer, int alive,
+ unsigned long when);
void lnet_notify_locked(struct lnet_peer *lp, int notifylnd, int alive,
unsigned long when);
int lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway_nid,
diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h
index 321752d..eea3b8e 100644
--- a/drivers/staging/lustre/include/linux/lnet/lib-types.h
+++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h
@@ -40,8 +40,8 @@
#include <linux/types.h>
#include <linux/completion.h>
-#include "types.h"
-#include "lnetctl.h"
+#include <uapi/linux/lnet/lnet-types.h>
+#include <uapi/linux/lnet/lnetctl.h>
/* Max payload size */
#define LNET_MAX_PAYLOAD CONFIG_LNET_MAX_PAYLOAD
@@ -308,9 +308,11 @@ struct lnet_rc_data {
struct lnet_peer {
struct list_head lp_hashlist; /* chain on peer hash */
struct list_head lp_txq; /* messages blocking for
- tx credits */
+ * tx credits
+ */
struct list_head lp_rtrq; /* messages blocking for
- router credits */
+ * router credits
+ */
struct list_head lp_rtr_list; /* chain on router list */
int lp_txcredits; /* # tx credits available */
int lp_mintxcredits; /* low water mark */
@@ -319,23 +321,31 @@ struct lnet_peer {
unsigned int lp_alive:1; /* alive/dead? */
unsigned int lp_notify:1; /* notification outstanding? */
unsigned int lp_notifylnd:1;/* outstanding notification
- for LND? */
+ * for LND?
+ */
unsigned int lp_notifying:1; /* some thread is handling
- notification */
+ * notification
+ */
unsigned int lp_ping_notsent;/* SEND event outstanding
- from ping */
+ * from ping
+ */
int lp_alive_count; /* # times router went
- dead<->alive */
- long lp_txqnob; /* bytes queued for sending */
+ * dead<->alive
+ */
+ long lp_txqnob; /* ytes queued for sending */
unsigned long lp_timestamp; /* time of last aliveness
- news */
+ * news
+ */
unsigned long lp_ping_timestamp;/* time of last ping
- attempt */
+ * attempt
+ */
unsigned long lp_ping_deadline; /* != 0 if ping reply
- expected */
+ * expected
+ */
unsigned long lp_last_alive; /* when I was last alive */
unsigned long lp_last_query; /* when lp_ni was queried
- last time */
+ * last time
+ */
struct lnet_ni *lp_ni; /* interface peer is on */
lnet_nid_t lp_nid; /* peer's NID */
int lp_refcount; /* # refs */
@@ -386,7 +396,8 @@ struct lnet_route {
struct lnet_remotenet {
struct list_head lrn_list; /* chain on
- ln_remote_nets_hash */
+ * ln_remote_nets_hash
+ */
struct list_head lrn_routes; /* routes to me */
__u32 lrn_net; /* my net number */
};
@@ -399,14 +410,16 @@ struct lnet_remotenet {
struct lnet_rtrbufpool {
struct list_head rbp_bufs; /* my free buffer pool */
struct list_head rbp_msgs; /* messages blocking
- for a buffer */
+ * for a buffer
+ */
int rbp_npages; /* # pages in each buffer */
/* requested number of buffers */
int rbp_req_nbuffers;
/* # buffers actually allocated */
int rbp_nbuffers;
- int rbp_credits; /* # free buffers /
- blocked messages */
+ int rbp_credits; /* # free buffers
+ * blocked messages
+ */
int rbp_mincredits; /* low water mark */
};
@@ -442,7 +455,8 @@ enum lnet_match_flags {
#define LNET_PTL_LAZY (1 << 0)
#define LNET_PTL_MATCH_UNIQUE (1 << 1) /* unique match, for RDMA */
#define LNET_PTL_MATCH_WILDCARD (1 << 2) /* wildcard match,
- request portal */
+ * request portal
+ */
/* parameter for matching operations (GET, PUT) */
struct lnet_match_info {
diff --git a/drivers/staging/lustre/include/linux/lnet/socklnd.h b/drivers/staging/lustre/include/linux/lnet/socklnd.h
index dd5bc0e..553fb64 100644
--- a/drivers/staging/lustre/include/linux/lnet/socklnd.h
+++ b/drivers/staging/lustre/include/linux/lnet/socklnd.h
@@ -34,16 +34,8 @@
#ifndef __LNET_LNET_SOCKLND_H__
#define __LNET_LNET_SOCKLND_H__
-#include "types.h"
-
-#define SOCKLND_CONN_NONE (-1)
-#define SOCKLND_CONN_ANY 0
-#define SOCKLND_CONN_CONTROL 1
-#define SOCKLND_CONN_BULK_IN 2
-#define SOCKLND_CONN_BULK_OUT 3
-#define SOCKLND_CONN_NTYPES 4
-
-#define SOCKLND_CONN_ACK SOCKLND_CONN_BULK_IN
+#include <uapi/linux/lnet/lnet-types.h>
+#include <uapi/linux/lnet/socklnd.h>
struct ksock_hello_msg {
__u32 kshm_magic; /* magic number of socklnd message */
@@ -76,7 +68,8 @@ struct ksock_msg {
__u64 ksm_zc_cookies[2]; /* Zero-Copy request/ACK cookie */
union {
struct ksock_lnet_msg lnetmsg; /* lnet message, it's empty if
- * it's NOOP */
+ * it's NOOP
+ */
} WIRE_ATTR ksm_u;
} WIRE_ATTR;
diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/libcfs_debug.h b/drivers/staging/lustre/include/uapi/linux/lnet/libcfs_debug.h
new file mode 100644
index 0000000..c4d9472
--- /dev/null
+++ b/drivers/staging/lustre/include/uapi/linux/lnet/libcfs_debug.h
@@ -0,0 +1,149 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * 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 version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, 2014, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * libcfs/include/libcfs/libcfs_debug.h
+ *
+ * Debug messages and assertions
+ *
+ */
+
+#ifndef __UAPI_LIBCFS_DEBUG_H__
+#define __UAPI_LIBCFS_DEBUG_H__
+
+/**
+ * Format for debug message headers
+ */
+struct ptldebug_header {
+ __u32 ph_len;
+ __u32 ph_flags;
+ __u32 ph_subsys;
+ __u32 ph_mask;
+ __u16 ph_cpu_id;
+ __u16 ph_type;
+ /* time_t overflow in 2106 */
+ __u32 ph_sec;
+ __u64 ph_usec;
+ __u32 ph_stack;
+ __u32 ph_pid;
+ __u32 ph_extern_pid;
+ __u32 ph_line_num;
+} __attribute__((packed));
+
+#define PH_FLAG_FIRST_RECORD 1
+
+/* Debugging subsystems (32 bits, non-overlapping) */
+#define S_UNDEFINED 0x00000001
+#define S_MDC 0x00000002
+#define S_MDS 0x00000004
+#define S_OSC 0x00000008
+#define S_OST 0x00000010
+#define S_CLASS 0x00000020
+#define S_LOG 0x00000040
+#define S_LLITE 0x00000080
+#define S_RPC 0x00000100
+#define S_MGMT 0x00000200
+#define S_LNET 0x00000400
+#define S_LND 0x00000800 /* ALL LNDs */
+#define S_PINGER 0x00001000
+#define S_FILTER 0x00002000
+#define S_LIBCFS 0x00004000
+#define S_ECHO 0x00008000
+#define S_LDLM 0x00010000
+#define S_LOV 0x00020000
+#define S_LQUOTA 0x00040000
+#define S_OSD 0x00080000
+#define S_LFSCK 0x00100000
+#define S_SNAPSHOT 0x00200000
+/* unused */
+#define S_LMV 0x00800000 /* b_new_cmd */
+/* unused */
+#define S_SEC 0x02000000 /* upcall cache */
+#define S_GSS 0x04000000 /* b_new_cmd */
+/* unused */
+#define S_MGC 0x10000000
+#define S_MGS 0x20000000
+#define S_FID 0x40000000 /* b_new_cmd */
+#define S_FLD 0x80000000 /* b_new_cmd */
+
+#define LIBCFS_DEBUG_SUBSYS_NAMES { \
+ "undefined", "mdc", "mds", "osc", "ost", "class", "log", \
+ "llite", "rpc", "mgmt", "lnet", "lnd", "pinger", "filter", \
+ "libcfs", "echo", "ldlm", "lov", "lquota", "osd", "lfsck", \
+ "snapshot", "", "lmv", "", "sec", "gss", "", "mgc", "mgs", \
+ "fid", "fld", NULL }
+
+/* Debugging masks (32 bits, non-overlapping) */
+#define D_TRACE 0x00000001 /* ENTRY/EXIT markers */
+#define D_INODE 0x00000002
+#define D_SUPER 0x00000004
+#define D_EXT2 0x00000008 /* anything from ext2_debug */
+#define D_MALLOC 0x00000010 /* print malloc, free information */
+#define D_CACHE 0x00000020 /* cache-related items */
+#define D_INFO 0x00000040 /* general information */
+#define D_IOCTL 0x00000080 /* ioctl related information */
+#define D_NETERROR 0x00000100 /* network errors */
+#define D_NET 0x00000200 /* network communications */
+#define D_WARNING 0x00000400 /* CWARN(...) == CDEBUG (D_WARNING, ...) */
+#define D_BUFFS 0x00000800
+#define D_OTHER 0x00001000
+#define D_DENTRY 0x00002000
+#define D_NETTRACE 0x00004000
+#define D_PAGE 0x00008000 /* bulk page handling */
+#define D_DLMTRACE 0x00010000
+#define D_ERROR 0x00020000 /* CERROR(...) == CDEBUG (D_ERROR, ...) */
+#define D_EMERG 0x00040000 /* CEMERG(...) == CDEBUG (D_EMERG, ...) */
+#define D_HA 0x00080000 /* recovery and failover */
+#define D_RPCTRACE 0x00100000 /* for distributed debugging */
+#define D_VFSTRACE 0x00200000
+#define D_READA 0x00400000 /* read-ahead */
+#define D_MMAP 0x00800000
+#define D_CONFIG 0x01000000
+#define D_CONSOLE 0x02000000
+#define D_QUOTA 0x04000000
+#define D_SEC 0x08000000
+#define D_LFSCK 0x10000000 /* For both OI scrub and LFSCK */
+#define D_HSM 0x20000000
+#define D_SNAPSHOT 0x40000000 /* snapshot */
+#define D_LAYOUT 0x80000000
+
+#define LIBCFS_DEBUG_MASKS_NAMES { \
+ "trace", "inode", "super", "ext2", "malloc", "cache", "info", \
+ "ioctl", "neterror", "net", "warning", "buffs", "other", \
+ "dentry", "nettrace", "page", "dlmtrace", "error", "emerg", \
+ "ha", "rpctrace", "vfstrace", "reada", "mmap", "config", \
+ "console", "quota", "sec", "lfsck", "hsm", "snapshot", "layout",\
+ NULL }
+
+#define D_CANTMASK (D_ERROR | D_EMERG | D_WARNING | D_CONSOLE)
+
+#define LIBCFS_DEBUG_FILE_PATH_DEFAULT "/tmp/lustre-log"
+
+#endif /* __UAPI_LIBCFS_DEBUG_H__ */
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h b/drivers/staging/lustre/include/uapi/linux/lnet/libcfs_ioctl.h
index cce6b58..cce6b58 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h
+++ b/drivers/staging/lustre/include/uapi/linux/lnet/libcfs_ioctl.h
diff --git a/drivers/staging/lustre/include/linux/lnet/lib-dlc.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h
index dfff170..e45d828 100644
--- a/drivers/staging/lustre/include/linux/lnet/lib-dlc.h
+++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h
@@ -29,8 +29,8 @@
#ifndef LNET_DLC_H
#define LNET_DLC_H
-#include "../libcfs/libcfs_ioctl.h"
-#include "types.h"
+#include <uapi/linux/lnet/libcfs_ioctl.h>
+#include <uapi/linux/lnet/lnet-types.h>
#define MAX_NUM_SHOW_ENTRIES 32
#define LNET_MAX_STR_LEN 128
diff --git a/drivers/staging/lustre/include/linux/lnet/types.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-types.h
index 1be9b7a..1be9b7a 100644
--- a/drivers/staging/lustre/include/linux/lnet/types.h
+++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-types.h
diff --git a/drivers/staging/lustre/include/linux/lnet/lnetctl.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnetctl.h
index 3957507..d9da625 100644
--- a/drivers/staging/lustre/include/linux/lnet/lnetctl.h
+++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnetctl.h
@@ -15,7 +15,7 @@
#ifndef _LNETCTL_H_
#define _LNETCTL_H_
-#include "types.h"
+#include <uapi/linux/lnet/lnet-types.h>
/** \addtogroup lnet_fault_simulation
* @{
@@ -32,10 +32,10 @@ enum {
LNET_CTL_DELAY_LIST,
};
-#define LNET_ACK_BIT BIT(0)
-#define LNET_PUT_BIT BIT(1)
-#define LNET_GET_BIT BIT(2)
-#define LNET_REPLY_BIT BIT(3)
+#define LNET_ACK_BIT (1 << 0)
+#define LNET_PUT_BIT (1 << 1)
+#define LNET_GET_BIT (1 << 2)
+#define LNET_REPLY_BIT (1 << 3)
/** ioctl parameter for LNet fault simulation */
struct lnet_fault_attr {
@@ -131,45 +131,4 @@ struct lnet_fault_stat {
#define SMFS_DEV_MAJOR 10
#define SMFS_DEV_MINOR 242
-int ptl_initialize(int argc, char **argv);
-int jt_ptl_network(int argc, char **argv);
-int jt_ptl_list_nids(int argc, char **argv);
-int jt_ptl_which_nid(int argc, char **argv);
-int jt_ptl_print_interfaces(int argc, char **argv);
-int jt_ptl_add_interface(int argc, char **argv);
-int jt_ptl_del_interface(int argc, char **argv);
-int jt_ptl_print_peers(int argc, char **argv);
-int jt_ptl_add_peer(int argc, char **argv);
-int jt_ptl_del_peer(int argc, char **argv);
-int jt_ptl_print_connections(int argc, char **argv);
-int jt_ptl_disconnect(int argc, char **argv);
-int jt_ptl_push_connection(int argc, char **argv);
-int jt_ptl_print_active_txs(int argc, char **argv);
-int jt_ptl_ping(int argc, char **argv);
-int jt_ptl_mynid(int argc, char **argv);
-int jt_ptl_add_uuid(int argc, char **argv);
-int jt_ptl_add_uuid_old(int argc, char **argv); /* backwards compatibility */
-int jt_ptl_close_uuid(int argc, char **argv);
-int jt_ptl_del_uuid(int argc, char **argv);
-int jt_ptl_add_route(int argc, char **argv);
-int jt_ptl_del_route(int argc, char **argv);
-int jt_ptl_notify_router(int argc, char **argv);
-int jt_ptl_print_routes(int argc, char **argv);
-int jt_ptl_fail_nid(int argc, char **argv);
-int jt_ptl_lwt(int argc, char **argv);
-int jt_ptl_testprotocompat(int argc, char **argv);
-int jt_ptl_memhog(int argc, char **argv);
-
-int dbg_initialize(int argc, char **argv);
-int jt_dbg_filter(int argc, char **argv);
-int jt_dbg_show(int argc, char **argv);
-int jt_dbg_list(int argc, char **argv);
-int jt_dbg_debug_kernel(int argc, char **argv);
-int jt_dbg_debug_daemon(int argc, char **argv);
-int jt_dbg_debug_file(int argc, char **argv);
-int jt_dbg_clear_debug_buf(int argc, char **argv);
-int jt_dbg_mark_debug_buf(int argc, char **argv);
-int jt_dbg_modules(int argc, char **argv);
-int jt_dbg_panic(int argc, char **argv);
-
#endif
diff --git a/drivers/staging/lustre/include/linux/lnet/lnetst.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnetst.h
index ea736f8..a4f9ff0 100644
--- a/drivers/staging/lustre/include/linux/lnet/lnetst.h
+++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnetst.h
@@ -54,7 +54,8 @@
#define LSTIO_GROUP_ADD 0xC10 /* add group */
#define LSTIO_GROUP_LIST 0xC11 /* list all groups in session */
#define LSTIO_GROUP_INFO 0xC12 /* query default information of
- * specified group */
+ * specified group
+ */
#define LSTIO_GROUP_DEL 0xC13 /* delete group */
#define LSTIO_NODES_ADD 0xC14 /* add nodes to specified group */
#define LSTIO_GROUP_UPDATE 0xC15 /* update group */
@@ -102,27 +103,32 @@ struct lstcon_test_ent {
int tse_type; /* test type */
int tse_loop; /* loop count */
int tse_concur; /* concurrency of test */
-}; /*** test summary entry, for
- *** list_batch command */
+}; /* test summary entry, for
+ * list_batch command
+ */
struct lstcon_batch_ent {
int bae_state; /* batch status */
int bae_timeout; /* batch timeout */
int bae_ntest; /* # of tests in the batch */
-}; /*** batch summary entry, for
- *** list_batch command */
+}; /* batch summary entry, for
+ * list_batch command
+ */
struct lstcon_test_batch_ent {
struct lstcon_ndlist_ent tbe_cli_nle; /* client (group) node_list
- * entry */
+ * entry
+ */
struct lstcon_ndlist_ent tbe_srv_nle; /* server (group) node_list
- * entry */
+ * entry
+ */
union {
struct lstcon_test_ent tbe_test; /* test entry */
struct lstcon_batch_ent tbe_batch;/* batch entry */
} u;
-}; /*** test/batch verbose information entry,
- *** for list_batch command */
+}; /* test/batch verbose information entry,
+ * for list_batch command
+ */
struct lstcon_rpc_ent {
struct list_head rpe_link; /* link chain */
@@ -138,10 +144,10 @@ struct lstcon_rpc_ent {
};
struct lstcon_trans_stat {
- int trs_rpc_stat[4]; /* RPCs stat (0: total
- 1: failed
- 2: finished
- 4: reserved */
+ int trs_rpc_stat[4]; /* RPCs stat (0: total 1: failed
+ * 2: finished
+ * 4: reserved
+ */
int trs_rpc_errno; /* RPC errno */
int trs_fwk_stat[8]; /* framework stat */
int trs_fwk_errno; /* errno of the first remote error */
@@ -275,22 +281,28 @@ struct lstio_session_end_args {
struct lstio_debug_args {
int lstio_dbg_key; /* IN: session key */
int lstio_dbg_type; /* IN: debug
- session|batch|
- group|nodes
- list */
+ * session|batch|
+ * group|nodes list
+ */
int lstio_dbg_flags; /* IN: reserved debug
- flags */
+ * flags
+ */
int lstio_dbg_timeout; /* IN: timeout of
- debug */
+ * debug
+ */
int lstio_dbg_nmlen; /* IN: len of name */
char __user *lstio_dbg_namep; /* IN: name of
- group|batch */
+ * group|batch
+ */
int lstio_dbg_count; /* IN: # of test nodes
- to debug */
+ * to debug
+ */
struct lnet_process_id __user *lstio_dbg_idsp; /* IN: id of test
- nodes */
+ * nodes
+ */
struct list_head __user *lstio_dbg_resultp; /* OUT: list head of
- result buffer */
+ * result buffer
+ */
};
struct lstio_group_add_args {
@@ -307,7 +319,8 @@ struct lstio_group_del_args {
#define LST_GROUP_CLEAN 1 /* remove inactive nodes in the group */
#define LST_GROUP_REFRESH 2 /* refresh inactive nodes
- * in the group */
+ * in the group
+ */
#define LST_GROUP_RMND 3 /* delete nodes from the group */
struct lstio_group_update_args {
@@ -319,7 +332,8 @@ struct lstio_group_update_args {
int lstio_grp_count; /* IN: # of nodes id */
struct lnet_process_id __user *lstio_grp_idsp; /* IN: array of nodes */
struct list_head __user *lstio_grp_resultp; /* OUT: list head of
- result buffer */
+ * result buffer
+ */
};
struct lstio_group_nodes_args {
@@ -331,7 +345,8 @@ struct lstio_group_nodes_args {
unsigned int __user *lstio_grp_featp;
struct lnet_process_id __user *lstio_grp_idsp; /* IN: nodes */
struct list_head __user *lstio_grp_resultp; /* OUT: list head of
- result buffer */
+ * result buffer
+ */
};
struct lstio_group_list_args {
@@ -345,8 +360,9 @@ struct lstio_group_info_args {
int lstio_grp_key; /* IN: session key */
int lstio_grp_nmlen; /* IN: name len */
char __user *lstio_grp_namep; /* IN: name */
- struct lstcon_ndlist_ent __user *lstio_grp_entp;/* OUT: description of
- group */
+ struct lstcon_ndlist_ent __user *lstio_grp_entp;/* OUT: description
+ * of group
+ */
int __user *lstio_grp_idxp; /* IN/OUT: node index */
int __user *lstio_grp_ndentp; /* IN/OUT: # of nodent */
struct lstcon_node_ent __user *lstio_grp_dentsp;/* OUT: nodent array */
@@ -369,34 +385,41 @@ struct lstio_batch_del_args {
struct lstio_batch_run_args {
int lstio_bat_key; /* IN: session key */
int lstio_bat_timeout; /* IN: timeout for
- the batch */
+ * the batch
+ */
int lstio_bat_nmlen; /* IN: name length */
char __user *lstio_bat_namep; /* IN: batch name */
struct list_head __user *lstio_bat_resultp; /* OUT: list head of
- result buffer */
+ * result buffer
+ */
};
struct lstio_batch_stop_args {
int lstio_bat_key; /* IN: session key */
int lstio_bat_force; /* IN: abort unfinished
- test RPC */
+ * test RPC
+ */
int lstio_bat_nmlen; /* IN: name length */
char __user *lstio_bat_namep; /* IN: batch name */
struct list_head __user *lstio_bat_resultp; /* OUT: list head of
- result buffer */
+ * result buffer
+ */
};
struct lstio_batch_query_args {
int lstio_bat_key; /* IN: session key */
int lstio_bat_testidx; /* IN: test index */
int lstio_bat_client; /* IN: we testing
- client? */
+ * client?
+ */
int lstio_bat_timeout; /* IN: timeout for
- waiting */
+ * waiting
+ */
int lstio_bat_nmlen; /* IN: name length */
char __user *lstio_bat_namep; /* IN: batch name */
struct list_head __user *lstio_bat_resultp; /* OUT: list head of
- result buffer */
+ * result buffer
+ */
};
struct lstio_batch_list_args {
@@ -411,7 +434,8 @@ struct lstio_batch_info_args {
int lstio_bat_nmlen; /* IN: name length */
char __user *lstio_bat_namep; /* IN: name */
int lstio_bat_server; /* IN: query server
- or not */
+ * or not
+ */
int lstio_bat_testidx; /* IN: test index */
struct lstcon_test_batch_ent __user *lstio_bat_entp;/* OUT: batch ent */
@@ -424,14 +448,17 @@ struct lstio_batch_info_args {
struct lstio_stat_args {
int lstio_sta_key; /* IN: session key */
int lstio_sta_timeout; /* IN: timeout for
- stat request */
+ * stat request
+ */
int lstio_sta_nmlen; /* IN: group name
- length */
+ * length
+ */
char __user *lstio_sta_namep; /* IN: group name */
int lstio_sta_count; /* IN: # of pid */
struct lnet_process_id __user *lstio_sta_idsp; /* IN: pid */
struct list_head __user *lstio_sta_resultp; /* OUT: list head of
- result buffer */
+ * result buffer
+ */
};
enum lst_test_type {
@@ -452,26 +479,32 @@ struct lstio_test_args {
int lstio_tes_concur; /* IN: concurrency */
int lstio_tes_dist; /* IN: node distribution in
- destination groups */
+ * destination groups
+ */
int lstio_tes_span; /* IN: node span in
- destination groups */
+ * destination groups
+ */
int lstio_tes_sgrp_nmlen; /* IN: source group
- name length */
+ * name length
+ */
char __user *lstio_tes_sgrp_name; /* IN: group name */
int lstio_tes_dgrp_nmlen; /* IN: destination group
- name length */
+ * name length
+ */
char __user *lstio_tes_dgrp_name; /* IN: group name */
int lstio_tes_param_len; /* IN: param buffer len */
void __user *lstio_tes_param; /* IN: parameter for specified
- test:
- lstio_bulk_param_t,
- lstio_ping_param_t,
- ... more */
+ * test: lstio_bulk_param_t,
+ * lstio_ping_param_t,
+ * ... more
+ */
int __user *lstio_tes_retp; /* OUT: private returned
- value */
+ * value
+ */
struct list_head __user *lstio_tes_resultp;/* OUT: list head of
- result buffer */
+ * result buffer
+ */
};
enum lst_brw_type {
diff --git a/drivers/staging/lustre/include/linux/lnet/nidstr.h b/drivers/staging/lustre/include/uapi/linux/lnet/nidstr.h
index ecdd0db..882074e 100644
--- a/drivers/staging/lustre/include/linux/lnet/nidstr.h
+++ b/drivers/staging/lustre/include/uapi/linux/lnet/nidstr.h
@@ -28,7 +28,7 @@
#ifndef _LNET_NIDSTRINGS_H
#define _LNET_NIDSTRINGS_H
-#include "types.h"
+#include <uapi/linux/lnet/lnet-types.h>
/**
* Lustre Network Driver types.
diff --git a/drivers/staging/lustre/include/linux/lnet/lnet.h b/drivers/staging/lustre/include/uapi/linux/lnet/socklnd.h
index 5d1559a..6453e05 100644
--- a/drivers/staging/lustre/include/linux/lnet/lnet.h
+++ b/drivers/staging/lustre/include/uapi/linux/lnet/socklnd.h
@@ -22,23 +22,23 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
- *
- * Copyright (c) 2012 - 2015, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Seagate, Inc.
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * #defines shared between socknal implementation and utilities
*/
+#ifndef __UAPI_LNET_SOCKLND_H__
+#define __UAPI_LNET_SOCKLND_H__
-#ifndef __LNET_H__
-#define __LNET_H__
+#define SOCKLND_CONN_NONE (-1)
+#define SOCKLND_CONN_ANY 0
+#define SOCKLND_CONN_CONTROL 1
+#define SOCKLND_CONN_BULK_IN 2
+#define SOCKLND_CONN_BULK_OUT 3
+#define SOCKLND_CONN_NTYPES 4
-/*
- * lnet.h
- *
- * User application interface file
- */
-#include "types.h"
-#include "nidstr.h"
+#define SOCKLND_CONN_ACK SOCKLND_CONN_BULK_IN
#endif
diff --git a/drivers/staging/lustre/lustre/include/lustre_cfg.h b/drivers/staging/lustre/include/uapi/linux/lustre/lustre_cfg.h
index 8eb394e..11b51d9 100644
--- a/drivers/staging/lustre/lustre/include/lustre_cfg.h
+++ b/drivers/staging/lustre/include/uapi/linux/lustre/lustre_cfg.h
@@ -30,8 +30,12 @@
* Lustre is a trademark of Sun Microsystems, Inc.
*/
-#ifndef _LUSTRE_CFG_H
-#define _LUSTRE_CFG_H
+#ifndef _UAPI_LUSTRE_CFG_H_
+#define _UAPI_LUSTRE_CFG_H_
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <uapi/linux/lustre/lustre_user.h>
/** \defgroup cfg cfg
*
@@ -46,55 +50,68 @@
#define LUSTRE_CFG_MAX_BUFCOUNT 8
#define LCFG_HDR_SIZE(count) \
- cfs_size_round(offsetof(struct lustre_cfg, lcfg_buflens[(count)]))
+ __ALIGN_KERNEL(offsetof(struct lustre_cfg, lcfg_buflens[(count)]), 8)
/** If the LCFG_REQUIRED bit is set in a configuration command,
* then the client is required to understand this parameter
* in order to mount the filesystem. If it does not understand
* a REQUIRED command the client mount will fail.
*/
-#define LCFG_REQUIRED 0x0001000
+#define LCFG_REQUIRED 0x0001000
enum lcfg_command_type {
- LCFG_ATTACH = 0x00cf001, /**< create a new obd instance */
- LCFG_DETACH = 0x00cf002, /**< destroy obd instance */
- LCFG_SETUP = 0x00cf003, /**< call type-specific setup */
- LCFG_CLEANUP = 0x00cf004, /**< call type-specific cleanup */
- LCFG_ADD_UUID = 0x00cf005, /**< add a nid to a niduuid */
- LCFG_DEL_UUID = 0x00cf006, /**< remove a nid from a niduuid */
- LCFG_MOUNTOPT = 0x00cf007, /**< create a profile (mdc, osc) */
- LCFG_DEL_MOUNTOPT = 0x00cf008, /**< destroy a profile */
- LCFG_SET_TIMEOUT = 0x00cf009, /**< set obd_timeout */
- LCFG_SET_UPCALL = 0x00cf00a, /**< deprecated */
- LCFG_ADD_CONN = 0x00cf00b, /**< add a failover niduuid to an obd */
- LCFG_DEL_CONN = 0x00cf00c, /**< remove a failover niduuid */
- LCFG_LOV_ADD_OBD = 0x00cf00d, /**< add an osc to a lov */
- LCFG_LOV_DEL_OBD = 0x00cf00e, /**< remove an osc from a lov */
- LCFG_PARAM = 0x00cf00f, /**< set a proc parameter */
- LCFG_MARKER = 0x00cf010, /**< metadata about next cfg rec */
- LCFG_LOG_START = 0x00ce011, /**< mgc only, process a cfg log */
- LCFG_LOG_END = 0x00ce012, /**< stop processing updates */
- LCFG_LOV_ADD_INA = 0x00ce013, /**< like LOV_ADD_OBD, inactive */
- LCFG_ADD_MDC = 0x00cf014, /**< add an mdc to a lmv */
- LCFG_DEL_MDC = 0x00cf015, /**< remove an mdc from a lmv */
- LCFG_SPTLRPC_CONF = 0x00ce016, /**< security */
- LCFG_POOL_NEW = 0x00ce020, /**< create an ost pool name */
- LCFG_POOL_ADD = 0x00ce021, /**< add an ost to a pool */
- LCFG_POOL_REM = 0x00ce022, /**< remove an ost from a pool */
- LCFG_POOL_DEL = 0x00ce023, /**< destroy an ost pool name */
- LCFG_SET_LDLM_TIMEOUT = 0x00ce030, /**< set ldlm_timeout */
- LCFG_PRE_CLEANUP = 0x00cf031, /**< call type-specific pre
- * cleanup cleanup
- */
- LCFG_SET_PARAM = 0x00ce032, /**< use set_param syntax to set
- * a proc parameters
- */
+ LCFG_ATTACH = 0x00cf001, /**< create a new obd instance */
+ LCFG_DETACH = 0x00cf002, /**< destroy obd instance */
+ LCFG_SETUP = 0x00cf003, /**< call type-specific setup */
+ LCFG_CLEANUP = 0x00cf004, /**< call type-specific cleanup
+ */
+ LCFG_ADD_UUID = 0x00cf005, /**< add a nid to a niduuid */
+ LCFG_DEL_UUID = 0x00cf006, /**< remove a nid from
+ * a niduuid
+ */
+ LCFG_MOUNTOPT = 0x00cf007, /**< create a profile
+ * (mdc, osc)
+ */
+ LCFG_DEL_MOUNTOPT = 0x00cf008, /**< destroy a profile */
+ LCFG_SET_TIMEOUT = 0x00cf009, /**< set obd_timeout */
+ LCFG_SET_UPCALL = 0x00cf00a, /**< deprecated */
+ LCFG_ADD_CONN = 0x00cf00b, /**< add a failover niduuid to
+ * an obd
+ */
+ LCFG_DEL_CONN = 0x00cf00c, /**< remove a failover niduuid */
+ LCFG_LOV_ADD_OBD = 0x00cf00d, /**< add an osc to a lov */
+ LCFG_LOV_DEL_OBD = 0x00cf00e, /**< remove an osc from a lov */
+ LCFG_PARAM = 0x00cf00f, /**< set a proc parameter */
+ LCFG_MARKER = 0x00cf010, /**< metadata about next
+ * cfg rec
+ */
+ LCFG_LOG_START = 0x00ce011, /**< mgc only, process a
+ * cfg log
+ */
+ LCFG_LOG_END = 0x00ce012, /**< stop processing updates */
+ LCFG_LOV_ADD_INA = 0x00ce013, /**< like LOV_ADD_OBD,
+ * inactive
+ */
+ LCFG_ADD_MDC = 0x00cf014, /**< add an mdc to a lmv */
+ LCFG_DEL_MDC = 0x00cf015, /**< remove an mdc from a lmv */
+ LCFG_SPTLRPC_CONF = 0x00ce016, /**< security */
+ LCFG_POOL_NEW = 0x00ce020, /**< create an ost pool name */
+ LCFG_POOL_ADD = 0x00ce021, /**< add an ost to a pool */
+ LCFG_POOL_REM = 0x00ce022, /**< remove an ost from a pool */
+ LCFG_POOL_DEL = 0x00ce023, /**< destroy an ost pool name */
+ LCFG_SET_LDLM_TIMEOUT = 0x00ce030, /**< set ldlm_timeout */
+ LCFG_PRE_CLEANUP = 0x00cf031, /**< call type-specific pre
+ * cleanup cleanup
+ */
+ LCFG_SET_PARAM = 0x00ce032, /**< use set_param syntax to set
+ * a proc parameters
+ */
};
struct lustre_cfg_bufs {
- void *lcfg_buf[LUSTRE_CFG_MAX_BUFCOUNT];
- __u32 lcfg_buflen[LUSTRE_CFG_MAX_BUFCOUNT];
- __u32 lcfg_bufcount;
+ void *lcfg_buf[LUSTRE_CFG_MAX_BUFCOUNT];
+ __u32 lcfg_buflen[LUSTRE_CFG_MAX_BUFCOUNT];
+ __u32 lcfg_bufcount;
};
struct lustre_cfg {
@@ -111,40 +128,37 @@ struct lustre_cfg {
};
enum cfg_record_type {
- PORTALS_CFG_TYPE = 1,
- LUSTRE_CFG_TYPE = 123,
+ PORTALS_CFG_TYPE = 1,
+ LUSTRE_CFG_TYPE = 123,
};
-#define LUSTRE_CFG_BUFLEN(lcfg, idx) \
- ((lcfg)->lcfg_bufcount <= (idx) \
- ? 0 \
- : (lcfg)->lcfg_buflens[(idx)])
+#define LUSTRE_CFG_BUFLEN(lcfg, idx) \
+ ((lcfg)->lcfg_bufcount <= (idx) ? 0 : (lcfg)->lcfg_buflens[(idx)])
static inline void lustre_cfg_bufs_set(struct lustre_cfg_bufs *bufs,
- __u32 index,
- void *buf,
- __u32 buflen)
+ __u32 index, void *buf, __u32 buflen)
{
if (index >= LUSTRE_CFG_MAX_BUFCOUNT)
return;
+
if (!bufs)
return;
if (bufs->lcfg_bufcount <= index)
bufs->lcfg_bufcount = index + 1;
- bufs->lcfg_buf[index] = buf;
+ bufs->lcfg_buf[index] = buf;
bufs->lcfg_buflen[index] = buflen;
}
static inline void lustre_cfg_bufs_set_string(struct lustre_cfg_bufs *bufs,
- __u32 index,
- char *str)
+ __u32 index, char *str)
{
lustre_cfg_bufs_set(bufs, index, str, str ? strlen(str) + 1 : 0);
}
-static inline void lustre_cfg_bufs_reset(struct lustre_cfg_bufs *bufs, char *name)
+static inline void lustre_cfg_bufs_reset(struct lustre_cfg_bufs *bufs,
+ char *name)
{
memset((bufs), 0, sizeof(*bufs));
if (name)
@@ -157,13 +171,16 @@ static inline void *lustre_cfg_buf(struct lustre_cfg *lcfg, __u32 index)
size_t offset;
__u32 bufcount;
+ if (!lcfg)
+ return NULL;
+
bufcount = lcfg->lcfg_bufcount;
if (index >= bufcount)
return NULL;
offset = LCFG_HDR_SIZE(lcfg->lcfg_bufcount);
for (i = 0; i < index; i++)
- offset += cfs_size_round(lcfg->lcfg_buflens[i]);
+ offset += __ALIGN_KERNEL(lcfg->lcfg_buflens[i], 8);
return (char *)lcfg + offset;
}
@@ -179,35 +196,6 @@ static inline void lustre_cfg_bufs_init(struct lustre_cfg_bufs *bufs,
}
}
-static inline char *lustre_cfg_string(struct lustre_cfg *lcfg, __u32 index)
-{
- char *s;
-
- if (lcfg->lcfg_buflens[index] == 0)
- return NULL;
-
- s = lustre_cfg_buf(lcfg, index);
- if (!s)
- return NULL;
-
- /*
- * make sure it's NULL terminated, even if this kills a char
- * of data. Try to use the padding first though.
- */
- if (s[lcfg->lcfg_buflens[index] - 1] != '\0') {
- size_t last = min((size_t)lcfg->lcfg_buflens[index],
- cfs_size_round(lcfg->lcfg_buflens[index]) - 1);
- char lost = s[last];
-
- s[last] = '\0';
- if (lost != '\0') {
- CWARN("Truncated buf %d to '%s' (lost '%c'...)\n",
- index, s, lost);
- }
- }
- return s;
-}
-
static inline __u32 lustre_cfg_len(__u32 bufcount, __u32 *buflens)
{
__u32 i;
@@ -215,24 +203,16 @@ static inline __u32 lustre_cfg_len(__u32 bufcount, __u32 *buflens)
len = LCFG_HDR_SIZE(bufcount);
for (i = 0; i < bufcount; i++)
- len += cfs_size_round(buflens[i]);
+ len += __ALIGN_KERNEL(buflens[i], 8);
- return cfs_size_round(len);
+ return __ALIGN_KERNEL(len, 8);
}
-#include "obd_support.h"
-
-static inline struct lustre_cfg *lustre_cfg_new(int cmd,
- struct lustre_cfg_bufs *bufs)
+static inline void lustre_cfg_init(struct lustre_cfg *lcfg, int cmd,
+ struct lustre_cfg_bufs *bufs)
{
- struct lustre_cfg *lcfg;
char *ptr;
- int i;
-
- lcfg = kzalloc(lustre_cfg_len(bufs->lcfg_bufcount, bufs->lcfg_buflen),
- GFP_NOFS);
- if (!lcfg)
- return ERR_PTR(-ENOMEM);
+ __u32 i;
lcfg->lcfg_version = LUSTRE_CFG_VERSION;
lcfg->lcfg_command = cmd;
@@ -241,15 +221,11 @@ static inline struct lustre_cfg *lustre_cfg_new(int cmd,
ptr = (char *)lcfg + LCFG_HDR_SIZE(lcfg->lcfg_bufcount);
for (i = 0; i < lcfg->lcfg_bufcount; i++) {
lcfg->lcfg_buflens[i] = bufs->lcfg_buflen[i];
- LOGL((char *)bufs->lcfg_buf[i], bufs->lcfg_buflen[i], ptr);
+ if (bufs->lcfg_buf[i]) {
+ memcpy(ptr, bufs->lcfg_buf[i], bufs->lcfg_buflen[i]);
+ ptr += __ALIGN_KERNEL(bufs->lcfg_buflen[i], 8);
+ }
}
- return lcfg;
-}
-
-static inline void lustre_cfg_free(struct lustre_cfg *lcfg)
-{
- kfree(lcfg);
- return;
}
static inline int lustre_cfg_sanity_check(void *buf, size_t len)
@@ -280,8 +256,6 @@ static inline int lustre_cfg_sanity_check(void *buf, size_t len)
return 0;
}
-#include "lustre/lustre_user.h"
-
/** @} cfg */
-#endif /* _LUSTRE_CFG_H */
+#endif /* _UAPI_LUSTRE_CFG_H_ */
diff --git a/drivers/staging/lustre/include/uapi/linux/lustre/lustre_fid.h b/drivers/staging/lustre/include/uapi/linux/lustre/lustre_fid.h
new file mode 100644
index 0000000..2e7a8d1
--- /dev/null
+++ b/drivers/staging/lustre/include/uapi/linux/lustre/lustre_fid.h
@@ -0,0 +1,293 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * 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 version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2014, Intel Corporation.
+ *
+ * Copyright 2016 Cray Inc, all rights reserved.
+ * Author: Ben Evans.
+ *
+ * all fid manipulation functions go here
+ *
+ * FIDS are globally unique within a Lustre filessytem, and are made up
+ * of three parts: sequence, Object ID, and version.
+ *
+ */
+#ifndef _UAPI_LUSTRE_FID_H_
+#define _UAPI_LUSTRE_FID_H_
+
+#include <uapi/linux/lustre/lustre_idl.h>
+
+/** returns fid object sequence */
+static inline __u64 fid_seq(const struct lu_fid *fid)
+{
+ return fid->f_seq;
+}
+
+/** returns fid object id */
+static inline __u32 fid_oid(const struct lu_fid *fid)
+{
+ return fid->f_oid;
+}
+
+/** returns fid object version */
+static inline __u32 fid_ver(const struct lu_fid *fid)
+{
+ return fid->f_ver;
+}
+
+static inline void fid_zero(struct lu_fid *fid)
+{
+ memset(fid, 0, sizeof(*fid));
+}
+
+static inline __u64 fid_ver_oid(const struct lu_fid *fid)
+{
+ return (__u64)fid_ver(fid) << 32 | fid_oid(fid);
+}
+
+static inline bool fid_seq_is_mdt0(__u64 seq)
+{
+ return seq == FID_SEQ_OST_MDT0;
+}
+
+static inline bool fid_seq_is_mdt(__u64 seq)
+{
+ return seq == FID_SEQ_OST_MDT0 || seq >= FID_SEQ_NORMAL;
+};
+
+static inline bool fid_seq_is_echo(__u64 seq)
+{
+ return seq == FID_SEQ_ECHO;
+}
+
+static inline bool fid_is_echo(const struct lu_fid *fid)
+{
+ return fid_seq_is_echo(fid_seq(fid));
+}
+
+static inline bool fid_seq_is_llog(__u64 seq)
+{
+ return seq == FID_SEQ_LLOG;
+}
+
+static inline bool fid_is_llog(const struct lu_fid *fid)
+{
+ /* file with OID == 0 is not llog but contains last oid */
+ return fid_seq_is_llog(fid_seq(fid)) && fid_oid(fid) > 0;
+}
+
+static inline bool fid_seq_is_rsvd(__u64 seq)
+{
+ return seq > FID_SEQ_OST_MDT0 && seq <= FID_SEQ_RSVD;
+};
+
+static inline bool fid_seq_is_special(__u64 seq)
+{
+ return seq == FID_SEQ_SPECIAL;
+};
+
+static inline bool fid_seq_is_local_file(__u64 seq)
+{
+ return seq == FID_SEQ_LOCAL_FILE ||
+ seq == FID_SEQ_LOCAL_NAME;
+};
+
+static inline bool fid_seq_is_root(__u64 seq)
+{
+ return seq == FID_SEQ_ROOT;
+}
+
+static inline bool fid_seq_is_dot(__u64 seq)
+{
+ return seq == FID_SEQ_DOT_LUSTRE;
+}
+
+static inline bool fid_seq_is_default(__u64 seq)
+{
+ return seq == FID_SEQ_LOV_DEFAULT;
+}
+
+static inline bool fid_is_mdt0(const struct lu_fid *fid)
+{
+ return fid_seq_is_mdt0(fid_seq(fid));
+}
+
+/**
+ * Check if a fid is igif or not.
+ * \param fid the fid to be tested.
+ * \return true if the fid is an igif; otherwise false.
+ */
+static inline bool fid_seq_is_igif(__u64 seq)
+{
+ return seq >= FID_SEQ_IGIF && seq <= FID_SEQ_IGIF_MAX;
+}
+
+static inline bool fid_is_igif(const struct lu_fid *fid)
+{
+ return fid_seq_is_igif(fid_seq(fid));
+}
+
+/**
+ * Check if a fid is idif or not.
+ * \param fid the fid to be tested.
+ * \return true if the fid is an idif; otherwise false.
+ */
+static inline bool fid_seq_is_idif(__u64 seq)
+{
+ return seq >= FID_SEQ_IDIF && seq <= FID_SEQ_IDIF_MAX;
+}
+
+static inline bool fid_is_idif(const struct lu_fid *fid)
+{
+ return fid_seq_is_idif(fid_seq(fid));
+}
+
+static inline bool fid_is_local_file(const struct lu_fid *fid)
+{
+ return fid_seq_is_local_file(fid_seq(fid));
+}
+
+static inline bool fid_seq_is_norm(__u64 seq)
+{
+ return (seq >= FID_SEQ_NORMAL);
+}
+
+static inline bool fid_is_norm(const struct lu_fid *fid)
+{
+ return fid_seq_is_norm(fid_seq(fid));
+}
+
+/* convert an OST objid into an IDIF FID SEQ number */
+static inline __u64 fid_idif_seq(__u64 id, __u32 ost_idx)
+{
+ return FID_SEQ_IDIF | (ost_idx << 16) | ((id >> 32) & 0xffff);
+}
+
+/* convert a packed IDIF FID into an OST objid */
+static inline __u64 fid_idif_id(__u64 seq, __u32 oid, __u32 ver)
+{
+ return ((__u64)ver << 48) | ((seq & 0xffff) << 32) | oid;
+}
+
+static inline __u32 idif_ost_idx(__u64 seq)
+{
+ return (seq >> 16) & 0xffff;
+}
+
+/* extract ost index from IDIF FID */
+static inline __u32 fid_idif_ost_idx(const struct lu_fid *fid)
+{
+ return idif_ost_idx(fid_seq(fid));
+}
+
+/**
+ * Get inode number from an igif.
+ * \param fid an igif to get inode number from.
+ * \return inode number for the igif.
+ */
+static inline ino_t lu_igif_ino(const struct lu_fid *fid)
+{
+ return fid_seq(fid);
+}
+
+/**
+ * Get inode generation from an igif.
+ * \param fid an igif to get inode generation from.
+ * \return inode generation for the igif.
+ */
+static inline __u32 lu_igif_gen(const struct lu_fid *fid)
+{
+ return fid_oid(fid);
+}
+
+/**
+ * Build igif from the inode number/generation.
+ */
+static inline void lu_igif_build(struct lu_fid *fid, __u32 ino, __u32 gen)
+{
+ fid->f_seq = ino;
+ fid->f_oid = gen;
+ fid->f_ver = 0;
+}
+
+/*
+ * Fids are transmitted across network (in the sender byte-ordering),
+ * and stored on disk in big-endian order.
+ */
+static inline void fid_cpu_to_le(struct lu_fid *dst, const struct lu_fid *src)
+{
+ dst->f_seq = __cpu_to_le64(fid_seq(src));
+ dst->f_oid = __cpu_to_le32(fid_oid(src));
+ dst->f_ver = __cpu_to_le32(fid_ver(src));
+}
+
+static inline void fid_le_to_cpu(struct lu_fid *dst, const struct lu_fid *src)
+{
+ dst->f_seq = __le64_to_cpu(fid_seq(src));
+ dst->f_oid = __le32_to_cpu(fid_oid(src));
+ dst->f_ver = __le32_to_cpu(fid_ver(src));
+}
+
+static inline void fid_cpu_to_be(struct lu_fid *dst, const struct lu_fid *src)
+{
+ dst->f_seq = __cpu_to_be64(fid_seq(src));
+ dst->f_oid = __cpu_to_be32(fid_oid(src));
+ dst->f_ver = __cpu_to_be32(fid_ver(src));
+}
+
+static inline void fid_be_to_cpu(struct lu_fid *dst, const struct lu_fid *src)
+{
+ dst->f_seq = __be64_to_cpu(fid_seq(src));
+ dst->f_oid = __be32_to_cpu(fid_oid(src));
+ dst->f_ver = __be32_to_cpu(fid_ver(src));
+}
+
+static inline bool fid_is_sane(const struct lu_fid *fid)
+{
+ return fid && ((fid_seq(fid) >= FID_SEQ_START && !fid_ver(fid)) ||
+ fid_is_igif(fid) || fid_is_idif(fid) ||
+ fid_seq_is_rsvd(fid_seq(fid)));
+}
+
+static inline bool lu_fid_eq(const struct lu_fid *f0, const struct lu_fid *f1)
+{
+ return !memcmp(f0, f1, sizeof(*f0));
+}
+
+static inline int lu_fid_cmp(const struct lu_fid *f0,
+ const struct lu_fid *f1)
+{
+ if (fid_seq(f0) != fid_seq(f1))
+ return fid_seq(f0) > fid_seq(f1) ? 1 : -1;
+
+ if (fid_oid(f0) != fid_oid(f1))
+ return fid_oid(f0) > fid_oid(f1) ? 1 : -1;
+
+ if (fid_ver(f0) != fid_ver(f1))
+ return fid_ver(f0) > fid_ver(f1) ? 1 : -1;
+
+ return 0;
+}
+#endif
diff --git a/drivers/staging/lustre/lustre/include/lustre/ll_fiemap.h b/drivers/staging/lustre/include/uapi/linux/lustre/lustre_fiemap.h
index b8ad555..f5214dc3 100644
--- a/drivers/staging/lustre/lustre/include/lustre/ll_fiemap.h
+++ b/drivers/staging/lustre/include/uapi/linux/lustre/lustre_fiemap.h
@@ -29,8 +29,6 @@
* This file is part of Lustre, http://www.lustre.org/
* Lustre is a trademark of Sun Microsystems, Inc.
*
- * lustre/include/lustre/ll_fiemap.h
- *
* FIEMAP data structures and flags. This header file will be used until
* fiemap.h is available in the upstream kernel.
*
@@ -41,10 +39,8 @@
#ifndef _LUSTRE_FIEMAP_H
#define _LUSTRE_FIEMAP_H
-#ifndef __KERNEL__
#include <stddef.h>
-#include <fiemap.h>
-#endif
+#include <linux/fiemap.h>
/* XXX: We use fiemap_extent::fe_reserved[0] */
#define fe_device fe_reserved[0]
diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h b/drivers/staging/lustre/include/uapi/linux/lustre/lustre_idl.h
index 77995fa..aac98db 100644
--- a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
+++ b/drivers/staging/lustre/include/uapi/linux/lustre/lustre_idl.h
@@ -29,8 +29,6 @@
* This file is part of Lustre, http://www.lustre.org/
* Lustre is a trademark of Sun Microsystems, Inc.
*
- * lustre/include/lustre/lustre_idl.h
- *
* Lustre wire protocol definitions.
*/
@@ -69,13 +67,13 @@
#ifndef _LUSTRE_IDL_H_
#define _LUSTRE_IDL_H_
-#include "../../../include/linux/libcfs/libcfs.h"
-#include "../../../include/linux/lnet/types.h"
+#include <asm/byteorder.h>
+#include <linux/types.h>
+#include <uapi/linux/lnet/lnet-types.h>
/* Defn's shared with user-space. */
-#include "lustre_user.h"
-#include "lustre_errno.h"
-#include "../lustre_ver.h"
+#include <uapi/linux/lustre/lustre_user.h>
+#include <uapi/linux/lustre/lustre_ver.h>
/*
* GENERAL STUFF
@@ -217,34 +215,6 @@ enum {
LUSTRE_FID_INIT_OID = 1UL
};
-/** returns fid object sequence */
-static inline __u64 fid_seq(const struct lu_fid *fid)
-{
- return fid->f_seq;
-}
-
-/** returns fid object id */
-static inline __u32 fid_oid(const struct lu_fid *fid)
-{
- return fid->f_oid;
-}
-
-/** returns fid object version */
-static inline __u32 fid_ver(const struct lu_fid *fid)
-{
- return fid->f_ver;
-}
-
-static inline void fid_zero(struct lu_fid *fid)
-{
- memset(fid, 0, sizeof(*fid));
-}
-
-static inline __u64 fid_ver_oid(const struct lu_fid *fid)
-{
- return ((__u64)fid_ver(fid) << 32 | fid_oid(fid));
-}
-
/* copytool uses a 32b bitmask field to encode archive-Ids during register
* with MDT thru kuc.
* archive num = 0 => all
@@ -313,458 +283,12 @@ enum dot_lustre_oid {
FID_OID_DOT_LUSTRE_OBF = 2UL,
};
-static inline bool fid_seq_is_mdt0(__u64 seq)
-{
- return (seq == FID_SEQ_OST_MDT0);
-}
-
-static inline bool fid_seq_is_mdt(__u64 seq)
-{
- return seq == FID_SEQ_OST_MDT0 || seq >= FID_SEQ_NORMAL;
+/** OID for FID_SEQ_ROOT */
+enum root_oid {
+ FID_OID_ROOT = 1UL,
+ FID_OID_ECHO_ROOT = 2UL,
};
-static inline bool fid_seq_is_echo(__u64 seq)
-{
- return (seq == FID_SEQ_ECHO);
-}
-
-static inline bool fid_is_echo(const struct lu_fid *fid)
-{
- return fid_seq_is_echo(fid_seq(fid));
-}
-
-static inline bool fid_seq_is_llog(__u64 seq)
-{
- return (seq == FID_SEQ_LLOG);
-}
-
-static inline bool fid_is_llog(const struct lu_fid *fid)
-{
- /* file with OID == 0 is not llog but contains last oid */
- return fid_seq_is_llog(fid_seq(fid)) && fid_oid(fid) > 0;
-}
-
-static inline bool fid_seq_is_rsvd(__u64 seq)
-{
- return (seq > FID_SEQ_OST_MDT0 && seq <= FID_SEQ_RSVD);
-};
-
-static inline bool fid_seq_is_special(__u64 seq)
-{
- return seq == FID_SEQ_SPECIAL;
-};
-
-static inline bool fid_seq_is_local_file(__u64 seq)
-{
- return seq == FID_SEQ_LOCAL_FILE ||
- seq == FID_SEQ_LOCAL_NAME;
-};
-
-static inline bool fid_seq_is_root(__u64 seq)
-{
- return seq == FID_SEQ_ROOT;
-}
-
-static inline bool fid_seq_is_dot(__u64 seq)
-{
- return seq == FID_SEQ_DOT_LUSTRE;
-}
-
-static inline bool fid_seq_is_default(__u64 seq)
-{
- return seq == FID_SEQ_LOV_DEFAULT;
-}
-
-static inline bool fid_is_mdt0(const struct lu_fid *fid)
-{
- return fid_seq_is_mdt0(fid_seq(fid));
-}
-
-static inline void lu_root_fid(struct lu_fid *fid)
-{
- fid->f_seq = FID_SEQ_ROOT;
- fid->f_oid = 1;
- fid->f_ver = 0;
-}
-
-/**
- * Check if a fid is igif or not.
- * \param fid the fid to be tested.
- * \return true if the fid is a igif; otherwise false.
- */
-static inline bool fid_seq_is_igif(__u64 seq)
-{
- return seq >= FID_SEQ_IGIF && seq <= FID_SEQ_IGIF_MAX;
-}
-
-static inline bool fid_is_igif(const struct lu_fid *fid)
-{
- return fid_seq_is_igif(fid_seq(fid));
-}
-
-/**
- * Check if a fid is idif or not.
- * \param fid the fid to be tested.
- * \return true if the fid is a idif; otherwise false.
- */
-static inline bool fid_seq_is_idif(__u64 seq)
-{
- return seq >= FID_SEQ_IDIF && seq <= FID_SEQ_IDIF_MAX;
-}
-
-static inline bool fid_is_idif(const struct lu_fid *fid)
-{
- return fid_seq_is_idif(fid_seq(fid));
-}
-
-static inline bool fid_is_local_file(const struct lu_fid *fid)
-{
- return fid_seq_is_local_file(fid_seq(fid));
-}
-
-static inline bool fid_seq_is_norm(__u64 seq)
-{
- return (seq >= FID_SEQ_NORMAL);
-}
-
-static inline bool fid_is_norm(const struct lu_fid *fid)
-{
- return fid_seq_is_norm(fid_seq(fid));
-}
-
-/* convert an OST objid into an IDIF FID SEQ number */
-static inline __u64 fid_idif_seq(__u64 id, __u32 ost_idx)
-{
- return FID_SEQ_IDIF | (ost_idx << 16) | ((id >> 32) & 0xffff);
-}
-
-/* convert a packed IDIF FID into an OST objid */
-static inline __u64 fid_idif_id(__u64 seq, __u32 oid, __u32 ver)
-{
- return ((__u64)ver << 48) | ((seq & 0xffff) << 32) | oid;
-}
-
-/* extract ost index from IDIF FID */
-static inline __u32 fid_idif_ost_idx(const struct lu_fid *fid)
-{
- return (fid_seq(fid) >> 16) & 0xffff;
-}
-
-/* extract OST sequence (group) from a wire ost_id (id/seq) pair */
-static inline __u64 ostid_seq(const struct ost_id *ostid)
-{
- if (fid_seq_is_mdt0(ostid->oi.oi_seq))
- return FID_SEQ_OST_MDT0;
-
- if (unlikely(fid_seq_is_default(ostid->oi.oi_seq)))
- return FID_SEQ_LOV_DEFAULT;
-
- if (fid_is_idif(&ostid->oi_fid))
- return FID_SEQ_OST_MDT0;
-
- return fid_seq(&ostid->oi_fid);
-}
-
-/* extract OST objid from a wire ost_id (id/seq) pair */
-static inline __u64 ostid_id(const struct ost_id *ostid)
-{
- if (fid_seq_is_mdt0(ostid->oi.oi_seq))
- return ostid->oi.oi_id & IDIF_OID_MASK;
-
- if (unlikely(fid_seq_is_default(ostid->oi.oi_seq)))
- return ostid->oi.oi_id;
-
- if (fid_is_idif(&ostid->oi_fid))
- return fid_idif_id(fid_seq(&ostid->oi_fid),
- fid_oid(&ostid->oi_fid), 0);
-
- return fid_oid(&ostid->oi_fid);
-}
-
-static inline void ostid_set_seq(struct ost_id *oi, __u64 seq)
-{
- if (fid_seq_is_mdt0(seq) || fid_seq_is_default(seq)) {
- oi->oi.oi_seq = seq;
- } else {
- oi->oi_fid.f_seq = seq;
- /* Note: if f_oid + f_ver is zero, we need init it
- * to be 1, otherwise, ostid_seq will treat this
- * as old ostid (oi_seq == 0)
- */
- if (oi->oi_fid.f_oid == 0 && oi->oi_fid.f_ver == 0)
- oi->oi_fid.f_oid = LUSTRE_FID_INIT_OID;
- }
-}
-
-static inline void ostid_set_seq_mdt0(struct ost_id *oi)
-{
- ostid_set_seq(oi, FID_SEQ_OST_MDT0);
-}
-
-static inline void ostid_set_seq_echo(struct ost_id *oi)
-{
- ostid_set_seq(oi, FID_SEQ_ECHO);
-}
-
-static inline void ostid_set_seq_llog(struct ost_id *oi)
-{
- ostid_set_seq(oi, FID_SEQ_LLOG);
-}
-
-/**
- * Note: we need check oi_seq to decide where to set oi_id,
- * so oi_seq should always be set ahead of oi_id.
- */
-static inline void ostid_set_id(struct ost_id *oi, __u64 oid)
-{
- if (fid_seq_is_mdt0(oi->oi.oi_seq)) {
- if (oid >= IDIF_MAX_OID) {
- CERROR("Too large OID %#llx to set MDT0 " DOSTID "\n",
- oid, POSTID(oi));
- return;
- }
- oi->oi.oi_id = oid;
- } else if (fid_is_idif(&oi->oi_fid)) {
- if (oid >= IDIF_MAX_OID) {
- CERROR("Too large OID %#llx to set IDIF " DOSTID "\n",
- oid, POSTID(oi));
- return;
- }
- oi->oi_fid.f_seq = fid_idif_seq(oid,
- fid_idif_ost_idx(&oi->oi_fid));
- oi->oi_fid.f_oid = oid;
- oi->oi_fid.f_ver = oid >> 48;
- } else {
- if (oid >= OBIF_MAX_OID) {
- CERROR("Bad %llu to set " DOSTID "\n", oid, POSTID(oi));
- return;
- }
- oi->oi_fid.f_oid = oid;
- }
-}
-
-static inline int fid_set_id(struct lu_fid *fid, __u64 oid)
-{
- if (unlikely(fid_seq_is_igif(fid->f_seq))) {
- CERROR("bad IGIF, " DFID "\n", PFID(fid));
- return -EBADF;
- }
-
- if (fid_is_idif(fid)) {
- if (oid >= IDIF_MAX_OID) {
- CERROR("Too large OID %#llx to set IDIF " DFID "\n",
- (unsigned long long)oid, PFID(fid));
- return -EBADF;
- }
- fid->f_seq = fid_idif_seq(oid, fid_idif_ost_idx(fid));
- fid->f_oid = oid;
- fid->f_ver = oid >> 48;
- } else {
- if (oid >= OBIF_MAX_OID) {
- CERROR("Too large OID %#llx to set REG " DFID "\n",
- (unsigned long long)oid, PFID(fid));
- return -EBADF;
- }
- fid->f_oid = oid;
- }
- return 0;
-}
-
-/**
- * Unpack an OST object id/seq (group) into a FID. This is needed for
- * converting all obdo, lmm, lsm, etc. 64-bit id/seq pairs into proper
- * FIDs. Note that if an id/seq is already in FID/IDIF format it will
- * be passed through unchanged. Only legacy OST objects in "group 0"
- * will be mapped into the IDIF namespace so that they can fit into the
- * struct lu_fid fields without loss. For reference see:
- * http://wiki.old.lustre.org/index.php/Architecture_-_Interoperability_fids_zfs
- */
-static inline int ostid_to_fid(struct lu_fid *fid, struct ost_id *ostid,
- __u32 ost_idx)
-{
- __u64 seq = ostid_seq(ostid);
-
- if (ost_idx > 0xffff) {
- CERROR("bad ost_idx, " DOSTID " ost_idx:%u\n", POSTID(ostid),
- ost_idx);
- return -EBADF;
- }
-
- if (fid_seq_is_mdt0(seq)) {
- __u64 oid = ostid_id(ostid);
-
- /* This is a "legacy" (old 1.x/2.early) OST object in "group 0"
- * that we map into the IDIF namespace. It allows up to 2^48
- * objects per OST, as this is the object namespace that has
- * been in production for years. This can handle create rates
- * of 1M objects/s/OST for 9 years, or combinations thereof.
- */
- if (oid >= IDIF_MAX_OID) {
- CERROR("bad MDT0 id, " DOSTID " ost_idx:%u\n",
- POSTID(ostid), ost_idx);
- return -EBADF;
- }
- fid->f_seq = fid_idif_seq(oid, ost_idx);
- /* truncate to 32 bits by assignment */
- fid->f_oid = oid;
- /* in theory, not currently used */
- fid->f_ver = oid >> 48;
- } else if (likely(!fid_seq_is_default(seq))) {
- /* This is either an IDIF object, which identifies objects across
- * all OSTs, or a regular FID. The IDIF namespace maps legacy
- * OST objects into the FID namespace. In both cases, we just
- * pass the FID through, no conversion needed.
- */
- if (ostid->oi_fid.f_ver != 0) {
- CERROR("bad MDT0 id, " DOSTID " ost_idx:%u\n",
- POSTID(ostid), ost_idx);
- return -EBADF;
- }
- *fid = ostid->oi_fid;
- }
-
- return 0;
-}
-
-/* pack any OST FID into an ostid (id/seq) for the wire/disk */
-static inline int fid_to_ostid(const struct lu_fid *fid, struct ost_id *ostid)
-{
- if (unlikely(fid_seq_is_igif(fid->f_seq))) {
- CERROR("bad IGIF, " DFID "\n", PFID(fid));
- return -EBADF;
- }
-
- if (fid_is_idif(fid)) {
- ostid_set_seq_mdt0(ostid);
- ostid_set_id(ostid, fid_idif_id(fid_seq(fid), fid_oid(fid),
- fid_ver(fid)));
- } else {
- ostid->oi_fid = *fid;
- }
-
- return 0;
-}
-
-/* Check whether the fid is for LAST_ID */
-static inline bool fid_is_last_id(const struct lu_fid *fid)
-{
- return (fid_oid(fid) == 0);
-}
-
-/**
- * Get inode number from a igif.
- * \param fid a igif to get inode number from.
- * \return inode number for the igif.
- */
-static inline ino_t lu_igif_ino(const struct lu_fid *fid)
-{
- return fid_seq(fid);
-}
-
-/**
- * Get inode generation from a igif.
- * \param fid a igif to get inode generation from.
- * \return inode generation for the igif.
- */
-static inline __u32 lu_igif_gen(const struct lu_fid *fid)
-{
- return fid_oid(fid);
-}
-
-/**
- * Build igif from the inode number/generation.
- */
-static inline void lu_igif_build(struct lu_fid *fid, __u32 ino, __u32 gen)
-{
- fid->f_seq = ino;
- fid->f_oid = gen;
- fid->f_ver = 0;
-}
-
-/*
- * Fids are transmitted across network (in the sender byte-ordering),
- * and stored on disk in big-endian order.
- */
-static inline void fid_cpu_to_le(struct lu_fid *dst, const struct lu_fid *src)
-{
- dst->f_seq = cpu_to_le64(fid_seq(src));
- dst->f_oid = cpu_to_le32(fid_oid(src));
- dst->f_ver = cpu_to_le32(fid_ver(src));
-}
-
-static inline void fid_le_to_cpu(struct lu_fid *dst, const struct lu_fid *src)
-{
- dst->f_seq = le64_to_cpu(fid_seq(src));
- dst->f_oid = le32_to_cpu(fid_oid(src));
- dst->f_ver = le32_to_cpu(fid_ver(src));
-}
-
-static inline void fid_cpu_to_be(struct lu_fid *dst, const struct lu_fid *src)
-{
- dst->f_seq = cpu_to_be64(fid_seq(src));
- dst->f_oid = cpu_to_be32(fid_oid(src));
- dst->f_ver = cpu_to_be32(fid_ver(src));
-}
-
-static inline void fid_be_to_cpu(struct lu_fid *dst, const struct lu_fid *src)
-{
- dst->f_seq = be64_to_cpu(fid_seq(src));
- dst->f_oid = be32_to_cpu(fid_oid(src));
- dst->f_ver = be32_to_cpu(fid_ver(src));
-}
-
-static inline bool fid_is_sane(const struct lu_fid *fid)
-{
- return fid &&
- ((fid_seq(fid) >= FID_SEQ_START && fid_ver(fid) == 0) ||
- fid_is_igif(fid) || fid_is_idif(fid) ||
- fid_seq_is_rsvd(fid_seq(fid)));
-}
-
-static inline bool lu_fid_eq(const struct lu_fid *f0, const struct lu_fid *f1)
-{
- return memcmp(f0, f1, sizeof(*f0)) == 0;
-}
-
-#define __diff_normalize(val0, val1) \
-({ \
- typeof(val0) __val0 = (val0); \
- typeof(val1) __val1 = (val1); \
- \
- (__val0 == __val1 ? 0 : __val0 > __val1 ? 1 : -1); \
-})
-
-static inline int lu_fid_cmp(const struct lu_fid *f0,
- const struct lu_fid *f1)
-{
- return
- __diff_normalize(fid_seq(f0), fid_seq(f1)) ?:
- __diff_normalize(fid_oid(f0), fid_oid(f1)) ?:
- __diff_normalize(fid_ver(f0), fid_ver(f1));
-}
-
-static inline void ostid_cpu_to_le(const struct ost_id *src_oi,
- struct ost_id *dst_oi)
-{
- if (fid_seq_is_mdt0(ostid_seq(src_oi))) {
- dst_oi->oi.oi_id = cpu_to_le64(src_oi->oi.oi_id);
- dst_oi->oi.oi_seq = cpu_to_le64(src_oi->oi.oi_seq);
- } else {
- fid_cpu_to_le(&dst_oi->oi_fid, &src_oi->oi_fid);
- }
-}
-
-static inline void ostid_le_to_cpu(const struct ost_id *src_oi,
- struct ost_id *dst_oi)
-{
- if (fid_seq_is_mdt0(ostid_seq(src_oi))) {
- dst_oi->oi.oi_id = le64_to_cpu(src_oi->oi.oi_id);
- dst_oi->oi.oi_seq = le64_to_cpu(src_oi->oi.oi_seq);
- } else {
- fid_le_to_cpu(&dst_oi->oi_fid, &src_oi->oi_fid);
- }
-}
-
/** @} lu_fid */
/** \defgroup lu_dir lu_dir
@@ -866,7 +390,7 @@ enum lu_dirpage_flags {
static inline struct lu_dirent *lu_dirent_start(struct lu_dirpage *dp)
{
- if (le32_to_cpu(dp->ldp_flags) & LDF_EMPTY)
+ if (__le32_to_cpu(dp->ldp_flags) & LDF_EMPTY)
return NULL;
else
return dp->ldp_entries;
@@ -876,8 +400,8 @@ static inline struct lu_dirent *lu_dirent_next(struct lu_dirent *ent)
{
struct lu_dirent *next;
- if (le16_to_cpu(ent->lde_reclen) != 0)
- next = ((void *)ent) + le16_to_cpu(ent->lde_reclen);
+ if (__le16_to_cpu(ent->lde_reclen) != 0)
+ next = ((void *)ent) + __le16_to_cpu(ent->lde_reclen);
else
next = NULL;
@@ -1122,7 +646,7 @@ struct ptlrpc_body_v2 {
#define OBD_CONNECT_AT 0x1000000ULL /*client uses AT */
#define OBD_CONNECT_LRU_RESIZE 0x2000000ULL /*LRU resize feature. */
#define OBD_CONNECT_MDS_MDS 0x4000000ULL /*MDS-MDS connection */
-#define OBD_CONNECT_REAL 0x8000000ULL /*real connection */
+#define OBD_CONNECT_REAL 0x8000000ULL /* obsolete since 2.8 */
#define OBD_CONNECT_CHANGE_QS 0x10000000ULL /*Not used since 2.4 */
#define OBD_CONNECT_CKSUM 0x20000000ULL /*support several cksum algos*/
#define OBD_CONNECT_FID 0x40000000ULL /*FID is supported by server */
@@ -1384,71 +908,6 @@ struct lov_mds_md_v1 { /* LOV EA mds/wire data (little-endian) */
struct lov_ost_data_v1 lmm_objects[0]; /* per-stripe data */
};
-/**
- * Sigh, because pre-2.4 uses
- * struct lov_mds_md_v1 {
- * ........
- * __u64 lmm_object_id;
- * __u64 lmm_object_seq;
- * ......
- * }
- * to identify the LOV(MDT) object, and lmm_object_seq will
- * be normal_fid, which make it hard to combine these conversion
- * to ostid_to FID. so we will do lmm_oi/fid conversion separately
- *
- * We can tell the lmm_oi by this way,
- * 1.8: lmm_object_id = {inode}, lmm_object_gr = 0
- * 2.1: lmm_object_id = {oid < 128k}, lmm_object_seq = FID_SEQ_NORMAL
- * 2.4: lmm_oi.f_seq = FID_SEQ_NORMAL, lmm_oi.f_oid = {oid < 128k},
- * lmm_oi.f_ver = 0
- *
- * But currently lmm_oi/lsm_oi does not have any "real" usages,
- * except for printing some information, and the user can always
- * get the real FID from LMA, besides this multiple case check might
- * make swab more complicate. So we will keep using id/seq for lmm_oi.
- */
-
-static inline void fid_to_lmm_oi(const struct lu_fid *fid,
- struct ost_id *oi)
-{
- oi->oi.oi_id = fid_oid(fid);
- oi->oi.oi_seq = fid_seq(fid);
-}
-
-static inline void lmm_oi_set_seq(struct ost_id *oi, __u64 seq)
-{
- oi->oi.oi_seq = seq;
-}
-
-static inline void lmm_oi_set_id(struct ost_id *oi, __u64 oid)
-{
- oi->oi.oi_id = oid;
-}
-
-static inline __u64 lmm_oi_id(const struct ost_id *oi)
-{
- return oi->oi.oi_id;
-}
-
-static inline __u64 lmm_oi_seq(const struct ost_id *oi)
-{
- return oi->oi.oi_seq;
-}
-
-static inline void lmm_oi_le_to_cpu(struct ost_id *dst_oi,
- const struct ost_id *src_oi)
-{
- dst_oi->oi.oi_id = le64_to_cpu(src_oi->oi.oi_id);
- dst_oi->oi.oi_seq = le64_to_cpu(src_oi->oi.oi_seq);
-}
-
-static inline void lmm_oi_cpu_to_le(struct ost_id *dst_oi,
- const struct ost_id *src_oi)
-{
- dst_oi->oi.oi_id = cpu_to_le64(src_oi->oi.oi_id);
- dst_oi->oi.oi_seq = cpu_to_le64(src_oi->oi.oi_seq);
-}
-
#define MAX_MD_SIZE \
(sizeof(struct lov_mds_md) + 4 * sizeof(struct lov_ost_data))
#define MIN_MD_SIZE \
@@ -2095,8 +1554,8 @@ enum mds_op_bias {
MDS_CREATE_VOLATILE = 1 << 10,
MDS_OWNEROVERRIDE = 1 << 11,
MDS_HSM_RELEASE = 1 << 12,
- MDS_RENAME_MIGRATE = BIT(13),
- MDS_CLOSE_LAYOUT_SWAP = BIT(14),
+ MDS_RENAME_MIGRATE = 1 << 13,
+ MDS_CLOSE_LAYOUT_SWAP = 1 << 14,
};
/* instance of mdt_reint_rec */
@@ -2130,17 +1589,6 @@ struct mdt_rec_create {
__u32 cr_padding_4; /* rr_padding_4 */
};
-static inline void set_mrc_cr_flags(struct mdt_rec_create *mrc, __u64 flags)
-{
- mrc->cr_flags_l = (__u32)(flags & 0xFFFFFFFFUll);
- mrc->cr_flags_h = (__u32)(flags >> 32);
-}
-
-static inline __u64 get_mrc_cr_flags(struct mdt_rec_create *mrc)
-{
- return ((__u64)(mrc->cr_flags_l) | ((__u64)mrc->cr_flags_h << 32));
-}
-
/* instance of mdt_reint_rec */
struct mdt_rec_link {
__u32 lk_opcode;
@@ -2393,35 +1841,16 @@ static inline ssize_t lmv_mds_md_size(int stripe_count, unsigned int lmm_magic)
static inline int lmv_mds_md_stripe_count_get(const union lmv_mds_md *lmm)
{
- switch (le32_to_cpu(lmm->lmv_magic)) {
+ switch (__le32_to_cpu(lmm->lmv_magic)) {
case LMV_MAGIC_V1:
- return le32_to_cpu(lmm->lmv_md_v1.lmv_stripe_count);
+ return __le32_to_cpu(lmm->lmv_md_v1.lmv_stripe_count);
case LMV_USER_MAGIC:
- return le32_to_cpu(lmm->lmv_user_md.lum_stripe_count);
+ return __le32_to_cpu(lmm->lmv_user_md.lum_stripe_count);
default:
return -EINVAL;
}
}
-static inline int lmv_mds_md_stripe_count_set(union lmv_mds_md *lmm,
- unsigned int stripe_count)
-{
- int rc = 0;
-
- switch (le32_to_cpu(lmm->lmv_magic)) {
- case LMV_MAGIC_V1:
- lmm->lmv_md_v1.lmv_stripe_count = cpu_to_le32(stripe_count);
- break;
- case LMV_USER_MAGIC:
- lmm->lmv_user_md.lum_stripe_count = cpu_to_le32(stripe_count);
- break;
- default:
- rc = -EINVAL;
- break;
- }
- return rc;
-}
-
enum fld_rpc_opc {
FLD_QUERY = 900,
FLD_READ = 901,
@@ -2502,12 +1931,6 @@ struct ldlm_res_id {
#define PLDLMRES(res) (res)->lr_name.name[0], (res)->lr_name.name[1], \
(res)->lr_name.name[2], (res)->lr_name.name[3]
-static inline bool ldlm_res_eq(const struct ldlm_res_id *res0,
- const struct ldlm_res_id *res1)
-{
- return !memcmp(res0, res1, sizeof(*res0));
-}
-
/* lock types */
enum ldlm_mode {
LCK_MINMODE = 0,
@@ -2540,19 +1963,6 @@ struct ldlm_extent {
__u64 gid;
};
-static inline int ldlm_extent_overlap(const struct ldlm_extent *ex1,
- const struct ldlm_extent *ex2)
-{
- return (ex1->start <= ex2->end) && (ex2->start <= ex1->end);
-}
-
-/* check if @ex1 contains @ex2 */
-static inline int ldlm_extent_contain(const struct ldlm_extent *ex1,
- const struct ldlm_extent *ex2)
-{
- return (ex1->start <= ex2->start) && (ex1->end >= ex2->end);
-}
-
struct ldlm_inodebits {
__u64 bits;
};
@@ -2583,21 +1993,21 @@ union ldlm_gl_desc {
};
enum ldlm_intent_flags {
- IT_OPEN = BIT(0),
- IT_CREAT = BIT(1),
- IT_OPEN_CREAT = BIT(1) | BIT(0),
- IT_READDIR = BIT(2),
- IT_GETATTR = BIT(3),
- IT_LOOKUP = BIT(4),
- IT_UNLINK = BIT(5),
- IT_TRUNC = BIT(6),
- IT_GETXATTR = BIT(7),
- IT_EXEC = BIT(8),
- IT_PIN = BIT(9),
- IT_LAYOUT = BIT(10),
- IT_QUOTA_DQACQ = BIT(11),
- IT_QUOTA_CONN = BIT(12),
- IT_SETXATTR = BIT(13),
+ IT_OPEN = 0x00000001,
+ IT_CREAT = 0x00000002,
+ IT_OPEN_CREAT = 0x00000003,
+ IT_READDIR = 0x00000004,
+ IT_GETATTR = 0x00000008,
+ IT_LOOKUP = 0x00000010,
+ IT_UNLINK = 0x00000020,
+ IT_TRUNC = 0x00000040,
+ IT_GETXATTR = 0x00000080,
+ IT_EXEC = 0x00000100,
+ IT_PIN = 0x00000200,
+ IT_LAYOUT = 0x00000400,
+ IT_QUOTA_DQACQ = 0x00000800,
+ IT_QUOTA_CONN = 0x00001000,
+ IT_SETXATTR = 0x00002000,
};
struct ldlm_intent {
@@ -2627,18 +2037,6 @@ struct ldlm_request {
struct lustre_handle lock_handle[LDLM_LOCKREQ_HANDLES];
};
-/* If LDLM_ENQUEUE, 1 slot is already occupied, 1 is available.
- * Otherwise, 2 are available.
- */
-#define ldlm_request_bufsize(count, type) \
-({ \
- int _avail = LDLM_LOCKREQ_HANDLES; \
- _avail -= (type == LDLM_ENQUEUE ? LDLM_ENQUEUE_CANCEL_OFF : 0); \
- sizeof(struct ldlm_request) + \
- (count > _avail ? count - _avail : 0) * \
- sizeof(struct lustre_handle); \
-})
-
struct ldlm_reply {
__u32 lock_flags;
__u32 lock_padding; /* also fix lustre_swab_ldlm_reply */
@@ -2942,12 +2340,6 @@ static inline const char *agent_req_status2name(const enum agent_req_status ars)
}
}
-static inline bool agent_req_in_final_state(enum agent_req_status ars)
-{
- return ((ars == ARS_SUCCEED) || (ars == ARS_FAILED) ||
- (ars == ARS_CANCELED));
-}
-
struct llog_agent_req_rec {
struct llog_rec_hdr arr_hdr; /**< record header */
__u32 arr_status; /**< status of the request */
@@ -2983,8 +2375,8 @@ enum llog_flag {
LLOG_F_ZAP_WHEN_EMPTY = 0x1,
LLOG_F_IS_CAT = 0x2,
LLOG_F_IS_PLAIN = 0x4,
- LLOG_F_EXT_JOBID = BIT(3),
- LLOG_F_IS_FIXSIZE = BIT(4),
+ LLOG_F_EXT_JOBID = 0x8,
+ LLOG_F_IS_FIXSIZE = 0x10,
/*
* Note: Flags covered by LLOG_F_EXT_MASK will be inherited from
@@ -3142,12 +2534,6 @@ struct ll_fiemap_info_key {
struct fiemap lfik_fiemap;
};
-/* Functions for dumping PTLRPC fields */
-void dump_rniobuf(struct niobuf_remote *rnb);
-void dump_ioo(struct obd_ioobj *nb);
-void dump_ost_body(struct ost_body *ob);
-void dump_rcs(__u32 *rc);
-
/* security opcodes */
enum sec_cmd {
SEC_CTX_INIT = 801,
@@ -3217,9 +2603,8 @@ struct link_ea_header {
__u32 leh_magic;
__u32 leh_reccount;
__u64 leh_len; /* total size */
- /* future use */
- __u32 padding1;
- __u32 padding2;
+ __u32 leh_overflow_time;
+ __u32 leh_padding;
};
/** Hardlink data is name and parent fid.
diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_ioctl.h b/drivers/staging/lustre/include/uapi/linux/lustre/lustre_ioctl.h
index eb08df3..9590864 100644
--- a/drivers/staging/lustre/lustre/include/lustre/lustre_ioctl.h
+++ b/drivers/staging/lustre/include/uapi/linux/lustre/lustre_ioctl.h
@@ -25,22 +25,13 @@
*
* Copyright (c) 2011, 2015, Intel Corporation.
*/
-#ifndef LUSTRE_IOCTL_H_
-#define LUSTRE_IOCTL_H_
+#ifndef _UAPI_LUSTRE_IOCTL_H_
+#define _UAPI_LUSTRE_IOCTL_H_
+#include <linux/ioctl.h>
+#include <linux/kernel.h>
#include <linux/types.h>
-#include "../../../include/linux/libcfs/libcfs.h"
-#include "lustre_idl.h"
-
-#ifdef __KERNEL__
-# include <linux/ioctl.h>
-# include <linux/string.h>
-# include "../obd_support.h"
-#else /* __KERNEL__ */
-# include <malloc.h>
-# include <string.h>
-#include <libcfs/util/ioctl.h>
-#endif /* !__KERNEL__ */
+#include <uapi/linux/lustre/lustre_idl.h>
#if !defined(__KERNEL__) && !defined(LUSTRE_UTILS)
# error This file is for Lustre internal use only.
@@ -65,7 +56,6 @@ enum md_echo_cmd {
#define OBD_IOCTL_VERSION 0x00010004
#define OBD_DEV_BY_DEVNAME 0xffffd0de
-#define OBD_MAX_IOCTL_BUFFER CONFIG_LUSTRE_OBD_MAX_IOCTL_BUFFER
struct obd_ioctl_data {
__u32 ioc_len;
@@ -122,187 +112,16 @@ struct obd_ioctl_hdr {
static inline __u32 obd_ioctl_packlen(struct obd_ioctl_data *data)
{
- __u32 len = cfs_size_round(sizeof(*data));
+ __u32 len = __ALIGN_KERNEL(sizeof(*data), 8);
- len += cfs_size_round(data->ioc_inllen1);
- len += cfs_size_round(data->ioc_inllen2);
- len += cfs_size_round(data->ioc_inllen3);
- len += cfs_size_round(data->ioc_inllen4);
+ len += __ALIGN_KERNEL(data->ioc_inllen1, 8);
+ len += __ALIGN_KERNEL(data->ioc_inllen2, 8);
+ len += __ALIGN_KERNEL(data->ioc_inllen3, 8);
+ len += __ALIGN_KERNEL(data->ioc_inllen4, 8);
return len;
}
-static inline int obd_ioctl_is_invalid(struct obd_ioctl_data *data)
-{
- if (data->ioc_len > (1 << 30)) {
- CERROR("OBD ioctl: ioc_len larger than 1<<30\n");
- return 1;
- }
-
- if (data->ioc_inllen1 > (1 << 30)) {
- CERROR("OBD ioctl: ioc_inllen1 larger than 1<<30\n");
- return 1;
- }
-
- if (data->ioc_inllen2 > (1 << 30)) {
- CERROR("OBD ioctl: ioc_inllen2 larger than 1<<30\n");
- return 1;
- }
-
- if (data->ioc_inllen3 > (1 << 30)) {
- CERROR("OBD ioctl: ioc_inllen3 larger than 1<<30\n");
- return 1;
- }
-
- if (data->ioc_inllen4 > (1 << 30)) {
- CERROR("OBD ioctl: ioc_inllen4 larger than 1<<30\n");
- return 1;
- }
-
- if (data->ioc_inlbuf1 && !data->ioc_inllen1) {
- CERROR("OBD ioctl: inlbuf1 pointer but 0 length\n");
- return 1;
- }
-
- if (data->ioc_inlbuf2 && !data->ioc_inllen2) {
- CERROR("OBD ioctl: inlbuf2 pointer but 0 length\n");
- return 1;
- }
-
- if (data->ioc_inlbuf3 && !data->ioc_inllen3) {
- CERROR("OBD ioctl: inlbuf3 pointer but 0 length\n");
- return 1;
- }
-
- if (data->ioc_inlbuf4 && !data->ioc_inllen4) {
- CERROR("OBD ioctl: inlbuf4 pointer but 0 length\n");
- return 1;
- }
-
- if (data->ioc_pbuf1 && !data->ioc_plen1) {
- CERROR("OBD ioctl: pbuf1 pointer but 0 length\n");
- return 1;
- }
-
- if (data->ioc_pbuf2 && !data->ioc_plen2) {
- CERROR("OBD ioctl: pbuf2 pointer but 0 length\n");
- return 1;
- }
-
- if (!data->ioc_pbuf1 && data->ioc_plen1) {
- CERROR("OBD ioctl: plen1 set but NULL pointer\n");
- return 1;
- }
-
- if (!data->ioc_pbuf2 && data->ioc_plen2) {
- CERROR("OBD ioctl: plen2 set but NULL pointer\n");
- return 1;
- }
-
- if (obd_ioctl_packlen(data) > data->ioc_len) {
- CERROR("OBD ioctl: packlen exceeds ioc_len (%d > %d)\n",
- obd_ioctl_packlen(data), data->ioc_len);
- return 1;
- }
-
- return 0;
-}
-
-#ifdef __KERNEL__
-
-int obd_ioctl_getdata(char **buf, int *len, void __user *arg);
-int obd_ioctl_popdata(void __user *arg, void *data, int len);
-
-static inline void obd_ioctl_freedata(char *buf, size_t len)
-{
- kvfree(buf);
-}
-
-#else /* __KERNEL__ */
-
-static inline int obd_ioctl_pack(struct obd_ioctl_data *data, char **pbuf,
- int max_len)
-{
- char *ptr;
- struct obd_ioctl_data *overlay;
-
- data->ioc_len = obd_ioctl_packlen(data);
- data->ioc_version = OBD_IOCTL_VERSION;
-
- if (*pbuf && data->ioc_len > max_len) {
- fprintf(stderr, "pbuf = %p, ioc_len = %u, max_len = %d\n",
- *pbuf, data->ioc_len, max_len);
- return -EINVAL;
- }
-
- if (!*pbuf)
- *pbuf = malloc(data->ioc_len);
-
- if (!*pbuf)
- return -ENOMEM;
-
- overlay = (struct obd_ioctl_data *)*pbuf;
- memcpy(*pbuf, data, sizeof(*data));
-
- ptr = overlay->ioc_bulk;
- if (data->ioc_inlbuf1)
- LOGL(data->ioc_inlbuf1, data->ioc_inllen1, ptr);
-
- if (data->ioc_inlbuf2)
- LOGL(data->ioc_inlbuf2, data->ioc_inllen2, ptr);
-
- if (data->ioc_inlbuf3)
- LOGL(data->ioc_inlbuf3, data->ioc_inllen3, ptr);
-
- if (data->ioc_inlbuf4)
- LOGL(data->ioc_inlbuf4, data->ioc_inllen4, ptr);
-
- if (obd_ioctl_is_invalid(overlay)) {
- fprintf(stderr, "invalid ioctl data: ioc_len = %u, max_len = %d\n",
- data->ioc_len, max_len);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static inline int
-obd_ioctl_unpack(struct obd_ioctl_data *data, char *pbuf, int max_len)
-{
- char *ptr;
- struct obd_ioctl_data *overlay;
-
- if (!pbuf)
- return 1;
-
- overlay = (struct obd_ioctl_data *)pbuf;
-
- /* Preserve the caller's buffer pointers */
- overlay->ioc_inlbuf1 = data->ioc_inlbuf1;
- overlay->ioc_inlbuf2 = data->ioc_inlbuf2;
- overlay->ioc_inlbuf3 = data->ioc_inlbuf3;
- overlay->ioc_inlbuf4 = data->ioc_inlbuf4;
-
- memcpy(data, pbuf, sizeof(*data));
-
- ptr = overlay->ioc_bulk;
- if (data->ioc_inlbuf1)
- LOGU(data->ioc_inlbuf1, data->ioc_inllen1, ptr);
-
- if (data->ioc_inlbuf2)
- LOGU(data->ioc_inlbuf2, data->ioc_inllen2, ptr);
-
- if (data->ioc_inlbuf3)
- LOGU(data->ioc_inlbuf3, data->ioc_inllen3, ptr);
-
- if (data->ioc_inlbuf4)
- LOGU(data->ioc_inlbuf4, data->ioc_inllen4, ptr);
-
- return 0;
-}
-
-#endif /* !__KERNEL__ */
-
/*
* OBD_IOC_DATA_TYPE is only for compatibility reasons with older
* Linux Lustre user tools. New ioctls should NOT use this macro as
@@ -409,4 +228,4 @@ obd_ioctl_unpack(struct obd_ioctl_data *data, char *pbuf, int max_len)
#define IOC_OSC_SET_ACTIVE _IOWR('h', 21, void *)
-#endif /* LUSTRE_IOCTL_H_ */
+#endif /* _UAPI_LUSTRE_IOCTL_H_ */
diff --git a/drivers/staging/lustre/lustre/include/uapi_kernelcomm.h b/drivers/staging/lustre/include/uapi/linux/lustre/lustre_kernelcomm.h
index 5e99836..94dadbe 100644
--- a/drivers/staging/lustre/lustre/include/uapi_kernelcomm.h
+++ b/drivers/staging/lustre/include/uapi/linux/lustre/lustre_kernelcomm.h
@@ -34,8 +34,8 @@
* The definitions below are used in the kernel and userspace.
*/
-#ifndef __UAPI_KERNELCOMM_H__
-#define __UAPI_KERNELCOMM_H__
+#ifndef __UAPI_LUSTRE_KERNELCOMM_H__
+#define __UAPI_LUSTRE_KERNELCOMM_H__
#include <linux/types.h>
@@ -91,4 +91,4 @@ struct lustre_kernelcomm {
__u32 lk_flags;
} __packed;
-#endif /* __UAPI_KERNELCOMM_H__ */
+#endif /* __UAPI_LUSTRE_KERNELCOMM_H__ */
diff --git a/drivers/staging/lustre/include/uapi/linux/lustre/lustre_ostid.h b/drivers/staging/lustre/include/uapi/linux/lustre/lustre_ostid.h
new file mode 100644
index 0000000..3343b60
--- /dev/null
+++ b/drivers/staging/lustre/include/uapi/linux/lustre/lustre_ostid.h
@@ -0,0 +1,236 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * 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 version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2014, Intel Corporation.
+ *
+ * Copyright 2015 Cray Inc, all rights reserved.
+ * Author: Ben Evans.
+ *
+ * Define ost_id associated functions
+ */
+
+#ifndef _UAPI_LUSTRE_OSTID_H_
+#define _UAPI_LUSTRE_OSTID_H_
+
+#include <linux/errno.h>
+#include <uapi/linux/lustre/lustre_fid.h>
+
+static inline __u64 lmm_oi_id(const struct ost_id *oi)
+{
+ return oi->oi.oi_id;
+}
+
+static inline __u64 lmm_oi_seq(const struct ost_id *oi)
+{
+ return oi->oi.oi_seq;
+}
+
+static inline void lmm_oi_set_seq(struct ost_id *oi, __u64 seq)
+{
+ oi->oi.oi_seq = seq;
+}
+
+static inline void lmm_oi_set_id(struct ost_id *oi, __u64 oid)
+{
+ oi->oi.oi_id = oid;
+}
+
+static inline void lmm_oi_le_to_cpu(struct ost_id *dst_oi,
+ const struct ost_id *src_oi)
+{
+ dst_oi->oi.oi_id = __le64_to_cpu(src_oi->oi.oi_id);
+ dst_oi->oi.oi_seq = __le64_to_cpu(src_oi->oi.oi_seq);
+}
+
+static inline void lmm_oi_cpu_to_le(struct ost_id *dst_oi,
+ const struct ost_id *src_oi)
+{
+ dst_oi->oi.oi_id = __cpu_to_le64(src_oi->oi.oi_id);
+ dst_oi->oi.oi_seq = __cpu_to_le64(src_oi->oi.oi_seq);
+}
+
+/* extract OST sequence (group) from a wire ost_id (id/seq) pair */
+static inline __u64 ostid_seq(const struct ost_id *ostid)
+{
+ if (fid_seq_is_mdt0(ostid->oi.oi_seq))
+ return FID_SEQ_OST_MDT0;
+
+ if (fid_seq_is_default(ostid->oi.oi_seq))
+ return FID_SEQ_LOV_DEFAULT;
+
+ if (fid_is_idif(&ostid->oi_fid))
+ return FID_SEQ_OST_MDT0;
+
+ return fid_seq(&ostid->oi_fid);
+}
+
+/* extract OST objid from a wire ost_id (id/seq) pair */
+static inline __u64 ostid_id(const struct ost_id *ostid)
+{
+ if (fid_seq_is_mdt0(ostid->oi.oi_seq))
+ return ostid->oi.oi_id & IDIF_OID_MASK;
+
+ if (fid_seq_is_default(ostid->oi.oi_seq))
+ return ostid->oi.oi_id;
+
+ if (fid_is_idif(&ostid->oi_fid))
+ return fid_idif_id(fid_seq(&ostid->oi_fid),
+ fid_oid(&ostid->oi_fid), 0);
+
+ return fid_oid(&ostid->oi_fid);
+}
+
+static inline void ostid_set_seq(struct ost_id *oi, __u64 seq)
+{
+ if (fid_seq_is_mdt0(seq) || fid_seq_is_default(seq)) {
+ oi->oi.oi_seq = seq;
+ } else {
+ oi->oi_fid.f_seq = seq;
+ /*
+ * Note: if f_oid + f_ver is zero, we need init it
+ * to be 1, otherwise, ostid_seq will treat this
+ * as old ostid (oi_seq == 0)
+ */
+ if (!oi->oi_fid.f_oid && !oi->oi_fid.f_ver)
+ oi->oi_fid.f_oid = LUSTRE_FID_INIT_OID;
+ }
+}
+
+static inline void ostid_set_seq_mdt0(struct ost_id *oi)
+{
+ ostid_set_seq(oi, FID_SEQ_OST_MDT0);
+}
+
+static inline void ostid_set_seq_echo(struct ost_id *oi)
+{
+ ostid_set_seq(oi, FID_SEQ_ECHO);
+}
+
+static inline void ostid_set_seq_llog(struct ost_id *oi)
+{
+ ostid_set_seq(oi, FID_SEQ_LLOG);
+}
+
+static inline void ostid_cpu_to_le(const struct ost_id *src_oi,
+ struct ost_id *dst_oi)
+{
+ if (fid_seq_is_mdt0(src_oi->oi.oi_seq)) {
+ dst_oi->oi.oi_id = __cpu_to_le64(src_oi->oi.oi_id);
+ dst_oi->oi.oi_seq = __cpu_to_le64(src_oi->oi.oi_seq);
+ } else {
+ fid_cpu_to_le(&dst_oi->oi_fid, &src_oi->oi_fid);
+ }
+}
+
+static inline void ostid_le_to_cpu(const struct ost_id *src_oi,
+ struct ost_id *dst_oi)
+{
+ if (fid_seq_is_mdt0(src_oi->oi.oi_seq)) {
+ dst_oi->oi.oi_id = __le64_to_cpu(src_oi->oi.oi_id);
+ dst_oi->oi.oi_seq = __le64_to_cpu(src_oi->oi.oi_seq);
+ } else {
+ fid_le_to_cpu(&dst_oi->oi_fid, &src_oi->oi_fid);
+ }
+}
+
+/**
+ * Sigh, because pre-2.4 uses
+ * struct lov_mds_md_v1 {
+ * ........
+ * __u64 lmm_object_id;
+ * __u64 lmm_object_seq;
+ * ......
+ * }
+ * to identify the LOV(MDT) object, and lmm_object_seq will
+ * be normal_fid, which make it hard to combine these conversion
+ * to ostid_to FID. so we will do lmm_oi/fid conversion separately
+ *
+ * We can tell the lmm_oi by this way,
+ * 1.8: lmm_object_id = {inode}, lmm_object_gr = 0
+ * 2.1: lmm_object_id = {oid < 128k}, lmm_object_seq = FID_SEQ_NORMAL
+ * 2.4: lmm_oi.f_seq = FID_SEQ_NORMAL, lmm_oi.f_oid = {oid < 128k},
+ * lmm_oi.f_ver = 0
+ *
+ * But currently lmm_oi/lsm_oi does not have any "real" usages,
+ * except for printing some information, and the user can always
+ * get the real FID from LMA, besides this multiple case check might
+ * make swab more complicate. So we will keep using id/seq for lmm_oi.
+ */
+
+static inline void fid_to_lmm_oi(const struct lu_fid *fid,
+ struct ost_id *oi)
+{
+ oi->oi.oi_id = fid_oid(fid);
+ oi->oi.oi_seq = fid_seq(fid);
+}
+
+/**
+ * Unpack an OST object id/seq (group) into a FID. This is needed for
+ * converting all obdo, lmm, lsm, etc. 64-bit id/seq pairs into proper
+ * FIDs. Note that if an id/seq is already in FID/IDIF format it will
+ * be passed through unchanged. Only legacy OST objects in "group 0"
+ * will be mapped into the IDIF namespace so that they can fit into the
+ * struct lu_fid fields without loss.
+ */
+static inline int ostid_to_fid(struct lu_fid *fid, const struct ost_id *ostid,
+ __u32 ost_idx)
+{
+ __u64 seq = ostid_seq(ostid);
+
+ if (ost_idx > 0xffff)
+ return -EBADF;
+
+ if (fid_seq_is_mdt0(seq)) {
+ __u64 oid = ostid_id(ostid);
+
+ /* This is a "legacy" (old 1.x/2.early) OST object in "group 0"
+ * that we map into the IDIF namespace. It allows up to 2^48
+ * objects per OST, as this is the object namespace that has
+ * been in production for years. This can handle create rates
+ * of 1M objects/s/OST for 9 years, or combinations thereof.
+ */
+ if (oid >= IDIF_MAX_OID)
+ return -EBADF;
+
+ fid->f_seq = fid_idif_seq(oid, ost_idx);
+ /* truncate to 32 bits by assignment */
+ fid->f_oid = oid;
+ /* in theory, not currently used */
+ fid->f_ver = oid >> 48;
+ } else if (!fid_seq_is_default(seq)) {
+ /* This is either an IDIF object, which identifies objects
+ * across all OSTs, or a regular FID. The IDIF namespace
+ * maps legacy OST objects into the FID namespace. In both
+ * cases, we just pass the FID through, no conversion needed.
+ */
+ if (ostid->oi_fid.f_ver)
+ return -EBADF;
+
+ *fid = ostid->oi_fid;
+ }
+
+ return 0;
+}
+#endif /* _UAPI_LUSTRE_OSTID_H_ */
diff --git a/drivers/staging/lustre/include/uapi/linux/lustre/lustre_param.h b/drivers/staging/lustre/include/uapi/linux/lustre/lustre_param.h
new file mode 100644
index 0000000..1eab2ce
--- /dev/null
+++ b/drivers/staging/lustre/include/uapi/linux/lustre/lustre_param.h
@@ -0,0 +1,94 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * 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 version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2015, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * User-settable parameter keys
+ *
+ * Author: Nathan Rutman <nathan@clusterfs.com>
+ */
+
+#ifndef _UAPI_LUSTRE_PARAM_H_
+#define _UAPI_LUSTRE_PARAM_H_
+
+/** \defgroup param param
+ *
+ * @{
+ */
+
+/****************** User-settable parameter keys *********************/
+/* e.g.
+ * tunefs.lustre --param="failover.node=192.168.0.13@tcp0" /dev/sda
+ * lctl conf_param testfs-OST0000 failover.node=3@elan,192.168.0.3@tcp0
+ * ... testfs-MDT0000.lov.stripesize=4M
+ * ... testfs-OST0000.ost.client_cache_seconds=15
+ * ... testfs.sys.timeout=<secs>
+ * ... testfs.llite.max_read_ahead_mb=16
+ */
+
+/* System global or special params not handled in obd's proc
+ * See mgs_write_log_sys()
+ */
+#define PARAM_TIMEOUT "timeout=" /* global */
+#define PARAM_LDLM_TIMEOUT "ldlm_timeout=" /* global */
+#define PARAM_AT_MIN "at_min=" /* global */
+#define PARAM_AT_MAX "at_max=" /* global */
+#define PARAM_AT_EXTRA "at_extra=" /* global */
+#define PARAM_AT_EARLY_MARGIN "at_early_margin=" /* global */
+#define PARAM_AT_HISTORY "at_history=" /* global */
+#define PARAM_JOBID_VAR "jobid_var=" /* global */
+#define PARAM_MGSNODE "mgsnode=" /* only at mounttime */
+#define PARAM_FAILNODE "failover.node=" /* add failover nid */
+#define PARAM_FAILMODE "failover.mode=" /* initial mount only */
+#define PARAM_ACTIVE "active=" /* activate/deactivate */
+#define PARAM_NETWORK "network=" /* bind on nid */
+#define PARAM_ID_UPCALL "identity_upcall=" /* identity upcall */
+
+/* Prefixes for parameters handled by obd's proc methods (XXX_process_config) */
+#define PARAM_OST "ost."
+#define PARAM_OSD "osd."
+#define PARAM_OSC "osc."
+#define PARAM_MDT "mdt."
+#define PARAM_HSM "mdt.hsm."
+#define PARAM_MDD "mdd."
+#define PARAM_MDC "mdc."
+#define PARAM_LLITE "llite."
+#define PARAM_LOV "lov."
+#define PARAM_LOD "lod."
+#define PARAM_OSP "osp."
+#define PARAM_SYS "sys." /* global */
+#define PARAM_SRPC "srpc."
+#define PARAM_SRPC_FLVR "srpc.flavor."
+#define PARAM_SRPC_UDESC "srpc.udesc.cli2mdt"
+#define PARAM_SEC "security."
+#define PARAM_QUOTA "quota." /* global */
+
+/** @} param */
+
+#endif /* _UAPI_LUSTRE_PARAM_H_ */
diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_user.h b/drivers/staging/lustre/include/uapi/linux/lustre/lustre_user.h
index edff8dc..5e332e3 100644
--- a/drivers/staging/lustre/lustre/include/lustre/lustre_user.h
+++ b/drivers/staging/lustre/include/uapi/linux/lustre/lustre_user.h
@@ -43,6 +43,7 @@
*/
#ifdef __KERNEL__
+# include <linux/fs.h>
# include <linux/quota.h>
# include <linux/sched/signal.h>
# include <linux/string.h> /* snprintf() */
@@ -54,7 +55,7 @@
# include <sys/quota.h>
# include <sys/stat.h>
#endif /* __KERNEL__ */
-#include "ll_fiemap.h"
+#include <uapi/linux/lustre/lustre_fiemap.h>
/*
* We need to always use 64bit version because the structure
@@ -644,7 +645,7 @@ struct if_quotactl {
#define SWAP_LAYOUTS_CHECK_DV2 (1 << 1)
#define SWAP_LAYOUTS_KEEP_MTIME (1 << 2)
#define SWAP_LAYOUTS_KEEP_ATIME (1 << 3)
-#define SWAP_LAYOUTS_CLOSE BIT(4)
+#define SWAP_LAYOUTS_CLOSE (1 << 4)
/* Swap XATTR_NAME_HSM as well, only on the MDT so far */
#define SWAP_LAYOUTS_MDS_HSM (1 << 31)
@@ -791,15 +792,15 @@ static inline void hsm_set_cl_error(int *flags, int error)
enum changelog_send_flag {
/* Not yet implemented */
- CHANGELOG_FLAG_FOLLOW = BIT(0),
+ CHANGELOG_FLAG_FOLLOW = 0x01,
/*
* Blocking IO makes sense in case of slow user parsing of the records,
* but it also prevents us from cleaning up if the records are not
* consumed.
*/
- CHANGELOG_FLAG_BLOCK = BIT(1),
+ CHANGELOG_FLAG_BLOCK = 0x02,
/* Pack jobid into the changelog records if available. */
- CHANGELOG_FLAG_JOBID = BIT(2),
+ CHANGELOG_FLAG_JOBID = 0x04,
};
#define CR_MAXSIZE cfs_size_round(2 * NAME_MAX + 2 + \
@@ -980,8 +981,8 @@ struct ioc_data_version {
__u64 idv_flags; /* See LL_DV_xxx */
};
-#define LL_DV_RD_FLUSH BIT(0) /* Flush dirty pages from clients */
-#define LL_DV_WR_FLUSH BIT(1) /* Flush all caching pages from clients */
+#define LL_DV_RD_FLUSH (1 << 0) /* Flush dirty pages from clients */
+#define LL_DV_WR_FLUSH (1 << 1) /* Flush all caching pages from clients */
#ifndef offsetof
# define offsetof(typ, memb) ((unsigned long)((char *)&(((typ *)0)->memb)))
diff --git a/drivers/staging/lustre/lustre/include/lustre_ver.h b/drivers/staging/lustre/include/uapi/linux/lustre/lustre_ver.h
index 19c9135..19c9135 100644
--- a/drivers/staging/lustre/lustre/include/lustre_ver.h
+++ b/drivers/staging/lustre/include/uapi/linux/lustre/lustre_ver.h
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/Makefile b/drivers/staging/lustre/lnet/klnds/o2iblnd/Makefile
index e0a7aa7..4affe1d 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/Makefile
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/Makefile
@@ -1,2 +1,5 @@
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/include
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/lustre/include
+
obj-$(CONFIG_LNET_XPRT_IB) += ko2iblnd.o
ko2iblnd-y := o2iblnd.o o2iblnd_cb.o o2iblnd_modparams.o
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
index 0520f02..64763aa 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
@@ -2936,7 +2936,7 @@ failed:
net_failed:
kiblnd_shutdown(ni);
- CDEBUG(D_NET, "kiblnd_startup failed\n");
+ CDEBUG(D_NET, "%s failed\n", __func__);
return -ENETDOWN;
}
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h
index 16e437b..a1e994a 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h
@@ -63,9 +63,8 @@
#define DEBUG_SUBSYSTEM S_LND
-#include "../../../include/linux/libcfs/libcfs.h"
-#include "../../../include/linux/lnet/lnet.h"
-#include "../../../include/linux/lnet/lib-lnet.h"
+#include <linux/libcfs/libcfs.h>
+#include <linux/lnet/lib-lnet.h>
#define IBLND_PEER_HASH_SIZE 101 /* # peer lists */
/* # scheduler loops before reschedule */
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/Makefile b/drivers/staging/lustre/lnet/klnds/socklnd/Makefile
index c011581..a7da1ab 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/Makefile
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/Makefile
@@ -1,3 +1,6 @@
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/include
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/lustre/include
+
obj-$(CONFIG_LNET) += ksocklnd.o
ksocklnd-y := socklnd.o socklnd_cb.o socklnd_proto.o socklnd_modparams.o socklnd_lib.o
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h
index 5540de6..e6428c4 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h
@@ -46,10 +46,9 @@
#include <net/sock.h>
#include <net/tcp.h>
-#include "../../../include/linux/libcfs/libcfs.h"
-#include "../../../include/linux/lnet/lnet.h"
-#include "../../../include/linux/lnet/lib-lnet.h"
-#include "../../../include/linux/lnet/socklnd.h"
+#include <linux/libcfs/libcfs.h>
+#include <linux/lnet/lib-lnet.h>
+#include <linux/lnet/socklnd.h>
/* assume one thread for each connection type */
#define SOCKNAL_NSCHEDS 3
@@ -519,17 +518,6 @@ extern struct ksock_proto ksocknal_protocol_v3x;
#define CPU_MASK_NONE 0UL
#endif
-static inline __u32 ksocknal_csum(__u32 crc, unsigned char const *p, size_t len)
-{
-#if 1
- return crc32_le(crc, p, len);
-#else
- while (len-- > 0)
- crc = ((crc + 0x100) & ~0xff) | ((crc + *p++) & 0xff) ;
- return crc;
-#endif
-}
-
static inline int
ksocknal_route_mask(void)
{
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c
index 8a036f4..9c328dc 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c
@@ -201,9 +201,9 @@ ksocknal_lib_recv_iov(struct ksock_conn *conn)
if (fragnob > sum)
fragnob = sum;
- conn->ksnc_rx_csum = ksocknal_csum(conn->ksnc_rx_csum,
- iov[i].iov_base,
- fragnob);
+ conn->ksnc_rx_csum = crc32_le(conn->ksnc_rx_csum,
+ iov[i].iov_base,
+ fragnob);
}
conn->ksnc_msg.ksm_csum = saved_csum;
}
@@ -243,8 +243,8 @@ ksocknal_lib_recv_kiov(struct ksock_conn *conn)
if (fragnob > sum)
fragnob = sum;
- conn->ksnc_rx_csum = ksocknal_csum(conn->ksnc_rx_csum,
- base, fragnob);
+ conn->ksnc_rx_csum = crc32_le(conn->ksnc_rx_csum,
+ base, fragnob);
kunmap(kiov[i].bv_page);
}
@@ -265,22 +265,22 @@ ksocknal_lib_csum_tx(struct ksock_tx *tx)
tx->tx_msg.ksm_csum = 0;
- csum = ksocknal_csum(~0, tx->tx_iov[0].iov_base,
- tx->tx_iov[0].iov_len);
+ csum = crc32_le(~0, tx->tx_iov[0].iov_base,
+ tx->tx_iov[0].iov_len);
if (tx->tx_kiov) {
for (i = 0; i < tx->tx_nkiov; i++) {
base = kmap(tx->tx_kiov[i].bv_page) +
tx->tx_kiov[i].bv_offset;
- csum = ksocknal_csum(csum, base, tx->tx_kiov[i].bv_len);
+ csum = crc32_le(csum, base, tx->tx_kiov[i].bv_len);
kunmap(tx->tx_kiov[i].bv_page);
}
} else {
for (i = 1; i < tx->tx_niov; i++)
- csum = ksocknal_csum(csum, tx->tx_iov[i].iov_base,
- tx->tx_iov[i].iov_len);
+ csum = crc32_le(csum, tx->tx_iov[i].iov_base,
+ tx->tx_iov[i].iov_len);
}
if (*ksocknal_tunables.ksnd_inject_csum_error) {
diff --git a/drivers/staging/lustre/lnet/libcfs/Makefile b/drivers/staging/lustre/lnet/libcfs/Makefile
index 8c89455..215fa23 100644
--- a/drivers/staging/lustre/lnet/libcfs/Makefile
+++ b/drivers/staging/lustre/lnet/libcfs/Makefile
@@ -1,3 +1,6 @@
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/include
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/lustre/include
+
obj-$(CONFIG_LNET) += libcfs.o
libcfs-linux-objs := linux-tracefile.o linux-debug.o
diff --git a/drivers/staging/lustre/lnet/libcfs/debug.c b/drivers/staging/lustre/lnet/libcfs/debug.c
index 49deb44..1ab394c 100644
--- a/drivers/staging/lustre/lnet/libcfs/debug.c
+++ b/drivers/staging/lustre/lnet/libcfs/debug.c
@@ -37,7 +37,7 @@
# define DEBUG_SUBSYSTEM S_LNET
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
#include "tracefile.h"
static char debug_file_name[1024];
diff --git a/drivers/staging/lustre/lnet/libcfs/fail.c b/drivers/staging/lustre/lnet/libcfs/fail.c
index 12dd50a..24f4701 100644
--- a/drivers/staging/lustre/lnet/libcfs/fail.c
+++ b/drivers/staging/lustre/lnet/libcfs/fail.c
@@ -29,7 +29,7 @@
* Lustre is a trademark of Oracle Corporation, Inc.
*/
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
unsigned long cfs_fail_loc;
EXPORT_SYMBOL(cfs_fail_loc);
diff --git a/drivers/staging/lustre/lnet/libcfs/hash.c b/drivers/staging/lustre/lnet/libcfs/hash.c
index 5c2ce2e..49a04a2 100644
--- a/drivers/staging/lustre/lnet/libcfs/hash.c
+++ b/drivers/staging/lustre/lnet/libcfs/hash.c
@@ -105,7 +105,7 @@
#include <linux/seq_file.h>
#include <linux/log2.h>
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
#if CFS_HASH_DEBUG_LEVEL >= CFS_HASH_DEBUG_1
static unsigned int warn_on_depth = 8;
@@ -1008,7 +1008,7 @@ cfs_hash_create(char *name, unsigned int cur_bits, unsigned int max_bits,
LASSERT(ops->hs_object);
LASSERT(ops->hs_keycmp);
LASSERT(ops->hs_get);
- LASSERT(ops->hs_put_locked);
+ LASSERT(ops->hs_put || ops->hs_put_locked);
if (flags & CFS_HASH_REHASH)
flags |= CFS_HASH_COUNTER; /* must have counter */
@@ -1553,19 +1553,20 @@ static int
cfs_hash_for_each_relax(struct cfs_hash *hs, cfs_hash_for_each_cb_t func,
void *data, int start)
{
+ struct hlist_node *next = NULL;
struct hlist_node *hnode;
- struct hlist_node *tmp;
struct cfs_hash_bd bd;
u32 version;
int count = 0;
int stop_on_change;
+ int has_put_locked;
int end = -1;
int rc = 0;
int i;
stop_on_change = cfs_hash_with_rehash_key(hs) ||
- !cfs_hash_with_no_itemref(hs) ||
- !hs->hs_ops->hs_put_locked;
+ !cfs_hash_with_no_itemref(hs);
+ has_put_locked = hs->hs_ops->hs_put_locked != NULL;
cfs_hash_lock(hs, 0);
again:
LASSERT(!cfs_hash_is_rehashing(hs));
@@ -1582,38 +1583,52 @@ again:
version = cfs_hash_bd_version_get(&bd);
cfs_hash_bd_for_each_hlist(hs, &bd, hhead) {
- for (hnode = hhead->first; hnode;) {
+ hnode = hhead->first;
+ if (!hnode)
+ continue;
+ cfs_hash_get(hs, hnode);
+
+ for (; hnode; hnode = next) {
cfs_hash_bucket_validate(hs, &bd, hnode);
- cfs_hash_get(hs, hnode);
+ next = hnode->next;
+ if (next)
+ cfs_hash_get(hs, next);
cfs_hash_bd_unlock(hs, &bd, 0);
cfs_hash_unlock(hs, 0);
rc = func(hs, &bd, hnode, data);
- if (stop_on_change)
+ if (stop_on_change || !has_put_locked)
cfs_hash_put(hs, hnode);
cond_resched();
count++;
cfs_hash_lock(hs, 0);
cfs_hash_bd_lock(hs, &bd, 0);
- if (!stop_on_change) {
- tmp = hnode->next;
- cfs_hash_put_locked(hs, hnode);
- hnode = tmp;
- } else { /* bucket changed? */
+ if (stop_on_change) {
if (version !=
cfs_hash_bd_version_get(&bd))
- break;
- /* safe to continue because no change */
- hnode = hnode->next;
+ rc = -EINTR;
+ } else if (has_put_locked) {
+ cfs_hash_put_locked(hs, hnode);
}
if (rc) /* callback wants to break iteration */
break;
}
- if (rc) /* callback wants to break iteration */
+ if (next) {
+ if (has_put_locked) {
+ cfs_hash_put_locked(hs, next);
+ next = NULL;
+ }
break;
+ } else if (rc) {
+ break;
+ }
}
cfs_hash_bd_unlock(hs, &bd, 0);
+ if (next && !has_put_locked) {
+ cfs_hash_put(hs, next);
+ next = NULL;
+ }
if (rc) /* callback wants to break iteration */
break;
}
diff --git a/drivers/staging/lustre/lnet/libcfs/libcfs_cpu.c b/drivers/staging/lustre/lnet/libcfs/libcfs_cpu.c
index 55caa19..2ddd09a 100644
--- a/drivers/staging/lustre/lnet/libcfs/libcfs_cpu.c
+++ b/drivers/staging/lustre/lnet/libcfs/libcfs_cpu.c
@@ -30,7 +30,7 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
/** Global CPU partition table */
struct cfs_cpt_table *cfs_cpt_table __read_mostly;
diff --git a/drivers/staging/lustre/lnet/libcfs/libcfs_lock.c b/drivers/staging/lustre/lnet/libcfs/libcfs_lock.c
index 1967b97..77fd3d06 100644
--- a/drivers/staging/lustre/lnet/libcfs/libcfs_lock.c
+++ b/drivers/staging/lustre/lnet/libcfs/libcfs_lock.c
@@ -27,7 +27,7 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
/** destroy cpu-partition lock, see libcfs_private.h for more detail */
void
diff --git a/drivers/staging/lustre/lnet/libcfs/libcfs_mem.c b/drivers/staging/lustre/lnet/libcfs/libcfs_mem.c
index ef085ba..1a0c7ca 100644
--- a/drivers/staging/lustre/lnet/libcfs/libcfs_mem.c
+++ b/drivers/staging/lustre/lnet/libcfs/libcfs_mem.c
@@ -28,7 +28,7 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
struct cfs_var_array {
unsigned int va_count; /* # of buffers */
diff --git a/drivers/staging/lustre/lnet/libcfs/libcfs_string.c b/drivers/staging/lustre/lnet/libcfs/libcfs_string.c
index 02de1ee..333e47f 100644
--- a/drivers/staging/lustre/lnet/libcfs/libcfs_string.c
+++ b/drivers/staging/lustre/lnet/libcfs/libcfs_string.c
@@ -36,7 +36,7 @@
* Author: Nathan Rutman <nathan.rutman@sun.com>
*/
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
/* Convert a text string to a bitmask */
int cfs_str2mask(const char *str, const char *(*bit2str)(int bit),
diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-cpu.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-cpu.c
index 4d35a37..2da051c 100644
--- a/drivers/staging/lustre/lnet/libcfs/linux/linux-cpu.c
+++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-cpu.c
@@ -31,7 +31,7 @@
#include <linux/cpu.h>
#include <linux/sched.h>
-#include "../../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
#ifdef CONFIG_SMP
diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c
index 68e34b4..5566339 100644
--- a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c
+++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c
@@ -29,8 +29,8 @@
#include <crypto/hash.h>
#include <linux/scatterlist.h>
-#include "../../../include/linux/libcfs/libcfs.h"
-#include "../../../include/linux/libcfs/libcfs_crypto.h"
+#include <linux/libcfs/libcfs.h>
+#include <linux/libcfs/libcfs_crypto.h>
#include "linux-crypto.h"
/**
diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-curproc.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-curproc.c
index 3e22cad..528d497 100644
--- a/drivers/staging/lustre/lnet/libcfs/linux/linux-curproc.c
+++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-curproc.c
@@ -44,7 +44,7 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include "../../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
/*
* Implementation of cfs_curproc API (see portals/include/libcfs/curproc.h)
diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-debug.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-debug.c
index 7035356..972677b 100644
--- a/drivers/staging/lustre/lnet/libcfs/linux/linux-debug.c
+++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-debug.c
@@ -51,7 +51,7 @@
# define DEBUG_SUBSYSTEM S_LNET
-#include "../../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
#include "../tracefile.h"
diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-mem.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-mem.c
index 8f63826..3f5dec1 100644
--- a/drivers/staging/lustre/lnet/libcfs/linux/linux-mem.c
+++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-mem.c
@@ -29,7 +29,7 @@
#include <linux/slab.h>
#include <linux/vmalloc.h>
-#include "../../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
void *libcfs_kvzalloc(size_t size, gfp_t flags)
{
diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c
index 075826b..4357221 100644
--- a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c
+++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c
@@ -32,7 +32,7 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include "../../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
#define LNET_MINOR 240
@@ -134,7 +134,7 @@ int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp,
return -EINVAL;
}
- if (hdr.ioc_len < sizeof(struct libcfs_ioctl_data)) {
+ if (hdr.ioc_len < sizeof(hdr)) {
CERROR("libcfs ioctl: user buffer too small for ioctl\n");
return -EINVAL;
}
diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-prim.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-prim.c
index bcf9f3d..4e331e7 100644
--- a/drivers/staging/lustre/lnet/libcfs/linux/linux-prim.c
+++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-prim.c
@@ -36,7 +36,7 @@
#include <linux/fs_struct.h>
#include <linux/sched/signal.h>
-#include "../../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
#if defined(CONFIG_KGDB)
#include <linux/kgdb.h>
diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-tracefile.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-tracefile.c
index a5a9478..16a3ae7 100644
--- a/drivers/staging/lustre/lnet/libcfs/linux/linux-tracefile.c
+++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-tracefile.c
@@ -33,7 +33,7 @@
#define DEBUG_SUBSYSTEM S_LNET
#define LUSTRE_TRACEFILE_PRIVATE
-#include "../../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
#include "../tracefile.h"
/* percents to share the total debug memory for each type */
diff --git a/drivers/staging/lustre/lnet/libcfs/module.c b/drivers/staging/lustre/lnet/libcfs/module.c
index c388550..6aed98f 100644
--- a/drivers/staging/lustre/lnet/libcfs/module.c
+++ b/drivers/staging/lustre/lnet/libcfs/module.c
@@ -50,13 +50,12 @@
# define DEBUG_SUBSYSTEM S_LNET
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
#include <asm/div64.h>
-#include "../../include/linux/libcfs/libcfs_crypto.h"
-#include "../../include/linux/lnet/lib-lnet.h"
-#include "../../include/linux/lnet/lib-dlc.h"
-#include "../../include/linux/lnet/lnet.h"
+#include <linux/libcfs/libcfs_crypto.h>
+#include <linux/lnet/lib-lnet.h>
+#include <uapi/linux/lnet/lnet-dlc.h>
#include "tracefile.h"
static struct dentry *lnet_debugfs_root;
diff --git a/drivers/staging/lustre/lnet/libcfs/prng.c b/drivers/staging/lustre/lnet/libcfs/prng.c
index 21d5a39..963ef4a 100644
--- a/drivers/staging/lustre/lnet/libcfs/prng.c
+++ b/drivers/staging/lustre/lnet/libcfs/prng.c
@@ -35,7 +35,7 @@
* algorithm recommended by Marsaglia
*/
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
/*
* From: George Marsaglia <geo@stat.fsu.edu>
diff --git a/drivers/staging/lustre/lnet/libcfs/tracefile.c b/drivers/staging/lustre/lnet/libcfs/tracefile.c
index d1aa79b..68f283a 100644
--- a/drivers/staging/lustre/lnet/libcfs/tracefile.c
+++ b/drivers/staging/lustre/lnet/libcfs/tracefile.c
@@ -40,7 +40,7 @@
#define pr_fmt(fmt) "Lustre: " fmt
#include "tracefile.h"
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
/* XXX move things up to the top, comment */
union cfs_trace_data_union (*cfs_trace_data[TCD_MAX_TYPES])[NR_CPUS] __cacheline_aligned;
diff --git a/drivers/staging/lustre/lnet/libcfs/tracefile.h b/drivers/staging/lustre/lnet/libcfs/tracefile.h
index f644cbc..c3547cd 100644
--- a/drivers/staging/lustre/lnet/libcfs/tracefile.h
+++ b/drivers/staging/lustre/lnet/libcfs/tracefile.h
@@ -33,7 +33,7 @@
#ifndef __LIBCFS_TRACEFILE_H__
#define __LIBCFS_TRACEFILE_H__
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
enum cfs_trace_buf_type {
CFS_TCD_TYPE_PROC = 0,
diff --git a/drivers/staging/lustre/lnet/libcfs/workitem.c b/drivers/staging/lustre/lnet/libcfs/workitem.c
index dbc2a9b..038ed8c 100644
--- a/drivers/staging/lustre/lnet/libcfs/workitem.c
+++ b/drivers/staging/lustre/lnet/libcfs/workitem.c
@@ -37,7 +37,7 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
#define CFS_WS_NAME_LEN 16
diff --git a/drivers/staging/lustre/lnet/lnet/Makefile b/drivers/staging/lustre/lnet/lnet/Makefile
index 4c81fa1..fd8585c 100644
--- a/drivers/staging/lustre/lnet/lnet/Makefile
+++ b/drivers/staging/lustre/lnet/lnet/Makefile
@@ -1,3 +1,6 @@
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/include
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/lustre/include
+
obj-$(CONFIG_LNET) += lnet.o
lnet-y := api-ni.o config.o nidstrings.o net_fault.o \
diff --git a/drivers/staging/lustre/lnet/lnet/acceptor.c b/drivers/staging/lustre/lnet/lnet/acceptor.c
index a6f60c3..be2823f 100644
--- a/drivers/staging/lustre/lnet/lnet/acceptor.c
+++ b/drivers/staging/lustre/lnet/lnet/acceptor.c
@@ -33,7 +33,7 @@
#define DEBUG_SUBSYSTEM S_LNET
#include <linux/completion.h>
#include <net/sock.h>
-#include "../../include/linux/lnet/lib-lnet.h"
+#include <linux/lnet/lib-lnet.h>
static int accept_port = 988;
static int accept_backlog = 127;
diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c
index 0b91d18..ad83503 100644
--- a/drivers/staging/lustre/lnet/lnet/api-ni.c
+++ b/drivers/staging/lustre/lnet/lnet/api-ni.c
@@ -34,8 +34,8 @@
#include <linux/log2.h>
#include <linux/ktime.h>
-#include "../../include/linux/lnet/lib-lnet.h"
-#include "../../include/linux/lnet/lib-dlc.h"
+#include <linux/lnet/lib-lnet.h>
+#include <uapi/linux/lnet/lnet-dlc.h>
#define D_LNI D_CONSOLE
diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c
index 933988d..26841a7 100644
--- a/drivers/staging/lustre/lnet/lnet/config.c
+++ b/drivers/staging/lustre/lnet/lnet/config.c
@@ -33,7 +33,7 @@
#define DEBUG_SUBSYSTEM S_LNET
#include <linux/nsproxy.h>
#include <net/net_namespace.h>
-#include "../../include/linux/lnet/lib-lnet.h"
+#include <linux/lnet/lib-lnet.h>
struct lnet_text_buf { /* tmp struct for parsing routes */
struct list_head ltb_list; /* stash on lists */
diff --git a/drivers/staging/lustre/lnet/lnet/lib-eq.c b/drivers/staging/lustre/lnet/lnet/lib-eq.c
index 9ebba4e..6b446a5 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-eq.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-eq.c
@@ -35,7 +35,8 @@
*/
#define DEBUG_SUBSYSTEM S_LNET
-#include "../../include/linux/lnet/lib-lnet.h"
+
+#include <linux/lnet/lib-lnet.h>
/**
* Create an event queue that has room for \a count number of events.
diff --git a/drivers/staging/lustre/lnet/lnet/lib-md.c b/drivers/staging/lustre/lnet/lnet/lib-md.c
index f08e944..a0aef4b 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-md.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-md.c
@@ -36,7 +36,7 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include "../../include/linux/lnet/lib-lnet.h"
+#include <linux/lnet/lib-lnet.h>
/* must be called with lnet_res_lock held */
void
diff --git a/drivers/staging/lustre/lnet/lnet/lib-me.c b/drivers/staging/lustre/lnet/lnet/lib-me.c
index e9b3eed..f52a5e8 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-me.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-me.c
@@ -36,7 +36,7 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include "../../include/linux/lnet/lib-lnet.h"
+#include <linux/lnet/lib-lnet.h>
/**
* Create and attach a match entry to the match list of \a portal. The new
diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c
index 20ebe24..bc0779c 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-move.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-move.c
@@ -36,7 +36,7 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include "../../include/linux/lnet/lib-lnet.h"
+#include <linux/lnet/lib-lnet.h>
#include <linux/nsproxy.h>
#include <net/net_namespace.h>
@@ -2034,7 +2034,7 @@ LNetPut(lnet_nid_t self, struct lnet_handle_md mdh, enum lnet_ack_req ack,
return -ENOENT;
}
- CDEBUG(D_NET, "LNetPut -> %s\n", libcfs_id2str(target));
+ CDEBUG(D_NET, "%s -> %s\n", __func__, libcfs_id2str(target));
lnet_msg_attach_md(msg, md, 0, 0);
@@ -2239,7 +2239,7 @@ LNetGet(lnet_nid_t self, struct lnet_handle_md mdh,
return -ENOENT;
}
- CDEBUG(D_NET, "LNetGet -> %s\n", libcfs_id2str(target));
+ CDEBUG(D_NET, "%s -> %s\n", __func__, libcfs_id2str(target));
lnet_msg_attach_md(msg, md, 0, 0);
diff --git a/drivers/staging/lustre/lnet/lnet/lib-msg.c b/drivers/staging/lustre/lnet/lnet/lib-msg.c
index 008ac50..d04875e 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-msg.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-msg.c
@@ -36,7 +36,7 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include "../../include/linux/lnet/lib-lnet.h"
+#include <linux/lnet/lib-lnet.h>
void
lnet_build_unlink_event(struct lnet_libmd *md, struct lnet_event *ev)
diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c
index 3333272..5946848 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c
@@ -31,7 +31,7 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include "../../include/linux/lnet/lib-lnet.h"
+#include <linux/lnet/lib-lnet.h>
/* NB: add /proc interfaces in upcoming patches */
int portal_rotor = LNET_PTL_ROTOR_HASH_RT;
diff --git a/drivers/staging/lustre/lnet/lnet/lib-socket.c b/drivers/staging/lustre/lnet/lnet/lib-socket.c
index 800f4f6..7d0add0 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-socket.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-socket.c
@@ -40,8 +40,8 @@
#include <linux/syscalls.h>
#include <net/sock.h>
-#include "../../include/linux/libcfs/libcfs.h"
-#include "../../include/linux/lnet/lib-lnet.h"
+#include <linux/libcfs/libcfs.h>
+#include <linux/lnet/lib-lnet.h>
static int
kernel_sock_unlocked_ioctl(struct file *filp, int cmd, unsigned long arg)
diff --git a/drivers/staging/lustre/lnet/lnet/lo.c b/drivers/staging/lustre/lnet/lnet/lo.c
index a7504b8..80c06f4 100644
--- a/drivers/staging/lustre/lnet/lnet/lo.c
+++ b/drivers/staging/lustre/lnet/lnet/lo.c
@@ -29,7 +29,8 @@
*/
#define DEBUG_SUBSYSTEM S_LNET
-#include "../../include/linux/lnet/lib-lnet.h"
+
+#include <linux/lnet/lib-lnet.h>
static int
lolnd_send(struct lnet_ni *ni, void *private, struct lnet_msg *lntmsg)
diff --git a/drivers/staging/lustre/lnet/lnet/module.c b/drivers/staging/lustre/lnet/lnet/module.c
index 4ffbd3e..7d12a7f 100644
--- a/drivers/staging/lustre/lnet/lnet/module.c
+++ b/drivers/staging/lustre/lnet/lnet/module.c
@@ -31,8 +31,9 @@
*/
#define DEBUG_SUBSYSTEM S_LNET
-#include "../../include/linux/lnet/lib-lnet.h"
-#include "../../include/linux/lnet/lib-dlc.h"
+
+#include <linux/lnet/lib-lnet.h>
+#include <uapi/linux/lnet/lnet-dlc.h>
static int config_on_load;
module_param(config_on_load, int, 0444);
diff --git a/drivers/staging/lustre/lnet/lnet/net_fault.c b/drivers/staging/lustre/lnet/lnet/net_fault.c
index 18183cb..03f3d18 100644
--- a/drivers/staging/lustre/lnet/lnet/net_fault.c
+++ b/drivers/staging/lustre/lnet/lnet/net_fault.c
@@ -35,8 +35,8 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include "../../include/linux/lnet/lib-lnet.h"
-#include "../../include/linux/lnet/lnetctl.h"
+#include <linux/lnet/lib-lnet.h>
+#include <uapi/linux/lnet/lnetctl.h>
#define LNET_MSG_MASK (LNET_PUT_BIT | LNET_ACK_BIT | \
LNET_GET_BIT | LNET_REPLY_BIT)
diff --git a/drivers/staging/lustre/lnet/lnet/nidstrings.c b/drivers/staging/lustre/lnet/lnet/nidstrings.c
index 298533d..7bd1e6f 100644
--- a/drivers/staging/lustre/lnet/lnet/nidstrings.c
+++ b/drivers/staging/lustre/lnet/lnet/nidstrings.c
@@ -36,8 +36,8 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include "../../include/linux/libcfs/libcfs.h"
-#include "../../include/linux/lnet/lnet.h"
+#include <linux/libcfs/libcfs.h>
+#include <uapi/linux/lnet/nidstr.h>
/* max value for numeric network address */
#define MAX_NUMERIC_VALUE 0xffffffff
diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c
index e62b21f..4d55df8 100644
--- a/drivers/staging/lustre/lnet/lnet/peer.c
+++ b/drivers/staging/lustre/lnet/lnet/peer.c
@@ -34,8 +34,8 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include "../../include/linux/lnet/lib-lnet.h"
-#include "../../include/linux/lnet/lib-dlc.h"
+#include <linux/lnet/lib-lnet.h>
+#include <uapi/linux/lnet/lnet-dlc.h>
int
lnet_peer_tables_create(void)
diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c
index 12dd104..3df101b 100644
--- a/drivers/staging/lustre/lnet/lnet/router.c
+++ b/drivers/staging/lustre/lnet/lnet/router.c
@@ -18,8 +18,9 @@
*/
#define DEBUG_SUBSYSTEM S_LNET
+
#include <linux/completion.h>
-#include "../../include/linux/lnet/lib-lnet.h"
+#include <linux/lnet/lib-lnet.h>
#define LNET_NRB_TINY_MIN 512 /* min value for each CPT */
#define LNET_NRB_TINY (LNET_NRB_TINY_MIN * 4)
diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c
index 72b80c5..4a994d1 100644
--- a/drivers/staging/lustre/lnet/lnet/router_proc.c
+++ b/drivers/staging/lustre/lnet/lnet/router_proc.c
@@ -18,8 +18,9 @@
*/
#define DEBUG_SUBSYSTEM S_LNET
-#include "../../include/linux/libcfs/libcfs.h"
-#include "../../include/linux/lnet/lib-lnet.h"
+
+#include <linux/libcfs/libcfs.h>
+#include <linux/lnet/lib-lnet.h>
/*
* This is really lnet_proc.c. You might need to update sanity test 215
diff --git a/drivers/staging/lustre/lnet/selftest/Makefile b/drivers/staging/lustre/lnet/selftest/Makefile
index c0de6e2..3ccc896 100644
--- a/drivers/staging/lustre/lnet/selftest/Makefile
+++ b/drivers/staging/lustre/lnet/selftest/Makefile
@@ -1,3 +1,6 @@
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/include
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/lustre/include
+
obj-$(CONFIG_LNET_SELFTEST) := lnet_selftest.o
lnet_selftest-y := console.o conrpc.o conctl.o framework.o timer.o rpc.o \
diff --git a/drivers/staging/lustre/lnet/selftest/conctl.c b/drivers/staging/lustre/lnet/selftest/conctl.c
index 6ca7192..9619ecb 100644
--- a/drivers/staging/lustre/lnet/selftest/conctl.c
+++ b/drivers/staging/lustre/lnet/selftest/conctl.c
@@ -36,9 +36,9 @@
* Author: Liang Zhen <liangzhen@clusterfs.com>
*/
-#include "../../include/linux/libcfs/libcfs.h"
-#include "../../include/linux/lnet/lib-lnet.h"
-#include "../../include/linux/lnet/lnetst.h"
+#include <linux/libcfs/libcfs.h>
+#include <linux/lnet/lib-lnet.h>
+#include <uapi/linux/lnet/lnetst.h>
#include "console.h"
static int
@@ -69,8 +69,8 @@ lst_session_new_ioctl(struct lstio_session_new_args *args)
rc = lstcon_session_new(name,
args->lstio_ses_key,
args->lstio_ses_feats,
- args->lstio_ses_force,
args->lstio_ses_timeout,
+ args->lstio_ses_force,
args->lstio_ses_idp);
LIBCFS_FREE(name, args->lstio_ses_nmlen + 1);
diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.c b/drivers/staging/lustre/lnet/selftest/conrpc.c
index da36c55..196d23c 100644
--- a/drivers/staging/lustre/lnet/selftest/conrpc.c
+++ b/drivers/staging/lustre/lnet/selftest/conrpc.c
@@ -36,8 +36,8 @@
* Author: Liang Zhen <liang@whamcloud.com>
*/
-#include "../../include/linux/libcfs/libcfs.h"
-#include "../../include/linux/lnet/lib-lnet.h"
+#include <linux/libcfs/libcfs.h>
+#include <linux/lnet/lib-lnet.h>
#include "timer.h"
#include "conrpc.h"
#include "console.h"
@@ -487,10 +487,9 @@ lstcon_rpc_trans_interpreter(struct lstcon_rpc_trans *trans,
sizeof(struct list_head)))
return -EFAULT;
- if (tmp.next == head_up)
- return 0;
-
next = tmp.next;
+ if (next == head_up)
+ return 0;
ent = list_entry(next, struct lstcon_rpc_ent, rpe_link);
diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.h b/drivers/staging/lustre/lnet/selftest/conrpc.h
index 7141d2c..23932367 100644
--- a/drivers/staging/lustre/lnet/selftest/conrpc.h
+++ b/drivers/staging/lustre/lnet/selftest/conrpc.h
@@ -39,10 +39,9 @@
#ifndef __LST_CONRPC_H__
#define __LST_CONRPC_H__
-#include "../../include/linux/libcfs/libcfs.h"
-#include "../../include/linux/lnet/lnet.h"
-#include "../../include/linux/lnet/lib-types.h"
-#include "../../include/linux/lnet/lnetst.h"
+#include <linux/libcfs/libcfs.h>
+#include <linux/lnet/lib-types.h>
+#include <uapi/linux/lnet/lnetst.h>
#include "rpc.h"
#include "selftest.h"
diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c
index d62c448..289b202 100644
--- a/drivers/staging/lustre/lnet/selftest/console.c
+++ b/drivers/staging/lustre/lnet/selftest/console.c
@@ -36,8 +36,8 @@
* Author: Liang Zhen <liangzhen@clusterfs.com>
*/
-#include "../../include/linux/libcfs/libcfs.h"
-#include "../../include/linux/lnet/lib-lnet.h"
+#include <linux/libcfs/libcfs.h>
+#include <linux/lnet/lib-lnet.h>
#include "console.h"
#include "conrpc.h"
diff --git a/drivers/staging/lustre/lnet/selftest/console.h b/drivers/staging/lustre/lnet/selftest/console.h
index e3e11aa..143eae9 100644
--- a/drivers/staging/lustre/lnet/selftest/console.h
+++ b/drivers/staging/lustre/lnet/selftest/console.h
@@ -39,10 +39,9 @@
#ifndef __LST_CONSOLE_H__
#define __LST_CONSOLE_H__
-#include "../../include/linux/libcfs/libcfs.h"
-#include "../../include/linux/lnet/lnet.h"
-#include "../../include/linux/lnet/lib-types.h"
-#include "../../include/linux/lnet/lnetst.h"
+#include <linux/libcfs/libcfs.h>
+#include <linux/lnet/lib-types.h>
+#include <uapi/linux/lnet/lnetst.h>
#include "selftest.h"
#include "conrpc.h"
diff --git a/drivers/staging/lustre/lnet/selftest/rpc.h b/drivers/staging/lustre/lnet/selftest/rpc.h
index a765537..7bb442a 100644
--- a/drivers/staging/lustre/lnet/selftest/rpc.h
+++ b/drivers/staging/lustre/lnet/selftest/rpc.h
@@ -33,7 +33,7 @@
#ifndef __SELFTEST_RPC_H__
#define __SELFTEST_RPC_H__
-#include "../../include/linux/lnet/lnetst.h"
+#include <uapi/linux/lnet/lnetst.h>
/*
* LST wired structures
diff --git a/drivers/staging/lustre/lnet/selftest/selftest.h b/drivers/staging/lustre/lnet/selftest/selftest.h
index b614e6f..7adad430 100644
--- a/drivers/staging/lustre/lnet/selftest/selftest.h
+++ b/drivers/staging/lustre/lnet/selftest/selftest.h
@@ -38,11 +38,10 @@
#define LNET_ONLY
-#include "../../include/linux/libcfs/libcfs.h"
-#include "../../include/linux/lnet/lnet.h"
-#include "../../include/linux/lnet/lib-lnet.h"
-#include "../../include/linux/lnet/lib-types.h"
-#include "../../include/linux/lnet/lnetst.h"
+#include <linux/libcfs/libcfs.h>
+#include <linux/lnet/lib-lnet.h>
+#include <linux/lnet/lib-types.h>
+#include <uapi/linux/lnet/lnetst.h>
#include "rpc.h"
#include "timer.h"
diff --git a/drivers/staging/lustre/lustre/Kconfig b/drivers/staging/lustre/lustre/Kconfig
index 9f5d75f..90d8269 100644
--- a/drivers/staging/lustre/lustre/Kconfig
+++ b/drivers/staging/lustre/lustre/Kconfig
@@ -31,16 +31,6 @@ config LUSTRE_FS
See also http://wiki.lustre.org/
-config LUSTRE_OBD_MAX_IOCTL_BUFFER
- int "Lustre obd max ioctl buffer bytes (default 8KB)"
- depends on LUSTRE_FS
- default 8192
- help
- This option defines the maximum size of buffer in bytes that user space
- applications can pass to Lustre kernel module through ioctl interface.
-
- If unsure, use default.
-
config LUSTRE_DEBUG_EXPENSIVE_CHECK
bool "Enable Lustre DEBUG checks"
depends on LUSTRE_FS
diff --git a/drivers/staging/lustre/lustre/fid/Makefile b/drivers/staging/lustre/lustre/fid/Makefile
index b7ef314..77b65b9 100644
--- a/drivers/staging/lustre/lustre/fid/Makefile
+++ b/drivers/staging/lustre/lustre/fid/Makefile
@@ -1,2 +1,5 @@
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/include
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/lustre/include/
+
obj-$(CONFIG_LUSTRE_FS) += fid.o
fid-y := fid_request.o fid_lib.o lproc_fid.o
diff --git a/drivers/staging/lustre/lustre/fid/fid_internal.h b/drivers/staging/lustre/lustre/fid/fid_internal.h
index 5c53773e..f48ab9d 100644
--- a/drivers/staging/lustre/lustre/fid/fid_internal.h
+++ b/drivers/staging/lustre/lustre/fid/fid_internal.h
@@ -36,8 +36,8 @@
#ifndef __FID_INTERNAL_H
#define __FID_INTERNAL_H
-#include "../include/lustre/lustre_idl.h"
-#include "../../include/linux/libcfs/libcfs.h"
+#include <uapi/linux/lustre/lustre_idl.h>
+#include <linux/libcfs/libcfs.h>
/* Functions used internally in module. */
diff --git a/drivers/staging/lustre/lustre/fid/fid_lib.c b/drivers/staging/lustre/lustre/fid/fid_lib.c
index 9eb4059..c21a5f5 100644
--- a/drivers/staging/lustre/lustre/fid/fid_lib.c
+++ b/drivers/staging/lustre/lustre/fid/fid_lib.c
@@ -39,10 +39,9 @@
#define DEBUG_SUBSYSTEM S_FID
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
#include <linux/module.h>
-#include "../include/lustre/lustre_idl.h"
-#include "../include/lustre_fid.h"
+#include <lustre_fid.h>
/**
* A cluster-wide range from which fid-sequences are granted to servers and
diff --git a/drivers/staging/lustre/lustre/fid/fid_request.c b/drivers/staging/lustre/lustre/fid/fid_request.c
index 19895fa..ba73623 100644
--- a/drivers/staging/lustre/lustre/fid/fid_request.c
+++ b/drivers/staging/lustre/lustre/fid/fid_request.c
@@ -38,15 +38,15 @@
#define DEBUG_SUBSYSTEM S_FID
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
#include <linux/module.h>
-#include "../include/obd.h"
-#include "../include/obd_class.h"
-#include "../include/obd_support.h"
-#include "../include/lustre_fid.h"
+#include <obd.h>
+#include <obd_class.h>
+#include <obd_support.h>
+#include <lustre_fid.h>
/* mdc RPC locks */
-#include "../include/lustre_mdc.h"
+#include <lustre_mdc.h>
#include "fid_internal.h"
static struct dentry *seq_debugfs_dir;
diff --git a/drivers/staging/lustre/lustre/fid/lproc_fid.c b/drivers/staging/lustre/lustre/fid/lproc_fid.c
index 3eed838..1a269fb 100644
--- a/drivers/staging/lustre/lustre/fid/lproc_fid.c
+++ b/drivers/staging/lustre/lustre/fid/lproc_fid.c
@@ -38,14 +38,14 @@
#define DEBUG_SUBSYSTEM S_FID
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
#include <linux/module.h>
-#include "../include/obd.h"
-#include "../include/obd_class.h"
-#include "../include/obd_support.h"
-#include "../include/lustre_req_layout.h"
-#include "../include/lustre_fid.h"
+#include <obd.h>
+#include <obd_class.h>
+#include <obd_support.h>
+#include <lustre_req_layout.h>
+#include <lustre_fid.h>
#include "fid_internal.h"
/* Format: [0x64BIT_INT - 0x64BIT_INT] + 32 bytes just in case */
diff --git a/drivers/staging/lustre/lustre/fld/Makefile b/drivers/staging/lustre/lustre/fld/Makefile
index 646e315..426deba 100644
--- a/drivers/staging/lustre/lustre/fld/Makefile
+++ b/drivers/staging/lustre/lustre/fld/Makefile
@@ -1,2 +1,5 @@
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/include
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/lustre/include/
+
obj-$(CONFIG_LUSTRE_FS) += fld.o
fld-y := fld_request.o fld_cache.o lproc_fld.o
diff --git a/drivers/staging/lustre/lustre/fld/fld_cache.c b/drivers/staging/lustre/lustre/fld/fld_cache.c
index b852fed..b723ece 100644
--- a/drivers/staging/lustre/lustre/fld/fld_cache.c
+++ b/drivers/staging/lustre/lustre/fld/fld_cache.c
@@ -39,18 +39,18 @@
#define DEBUG_SUBSYSTEM S_FLD
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
#include <linux/module.h>
#include <asm/div64.h>
-#include "../include/obd.h"
-#include "../include/obd_class.h"
-#include "../include/lustre_ver.h"
-#include "../include/obd_support.h"
-#include "../include/lprocfs_status.h"
+#include <obd.h>
+#include <obd_class.h>
+#include <uapi/linux/lustre/lustre_ver.h>
+#include <obd_support.h>
+#include <lprocfs_status.h>
-#include "../include/lustre_req_layout.h"
-#include "../include/lustre_fld.h"
+#include <lustre_req_layout.h>
+#include <lustre_fld.h>
#include "fld_internal.h"
/**
@@ -348,9 +348,10 @@ static void fld_cache_overlap_handle(struct fld_cache *cache,
f_curr->fce_range.lsr_end = new_start;
fld_cache_entry_add(cache, f_new, &f_curr->fce_list);
- } else
+ } else {
CERROR("NEW range =" DRANGE " curr = " DRANGE "\n",
PRANGE(range), PRANGE(&f_curr->fce_range));
+ }
}
struct fld_cache_entry
diff --git a/drivers/staging/lustre/lustre/fld/fld_internal.h b/drivers/staging/lustre/lustre/fld/fld_internal.h
index 4a7f0b7..fe6f278 100644
--- a/drivers/staging/lustre/lustre/fld/fld_internal.h
+++ b/drivers/staging/lustre/lustre/fld/fld_internal.h
@@ -56,11 +56,11 @@
#ifndef __FLD_INTERNAL_H
#define __FLD_INTERNAL_H
-#include "../include/lustre/lustre_idl.h"
+#include <uapi/linux/lustre/lustre_idl.h>
-#include "../../include/linux/libcfs/libcfs.h"
-#include "../include/lustre_req_layout.h"
-#include "../include/lustre_fld.h"
+#include <linux/libcfs/libcfs.h>
+#include <lustre_req_layout.h>
+#include <lustre_fld.h>
struct fld_stats {
__u64 fst_count;
diff --git a/drivers/staging/lustre/lustre/fld/fld_request.c b/drivers/staging/lustre/lustre/fld/fld_request.c
index 4cade7a..5b18083 100644
--- a/drivers/staging/lustre/lustre/fld/fld_request.c
+++ b/drivers/staging/lustre/lustre/fld/fld_request.c
@@ -38,19 +38,19 @@
#define DEBUG_SUBSYSTEM S_FLD
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
#include <linux/module.h>
#include <asm/div64.h>
-#include "../include/obd.h"
-#include "../include/obd_class.h"
-#include "../include/lustre_ver.h"
-#include "../include/obd_support.h"
-#include "../include/lprocfs_status.h"
+#include <obd.h>
+#include <obd_class.h>
+#include <uapi/linux/lustre/lustre_ver.h>
+#include <obd_support.h>
+#include <lprocfs_status.h>
-#include "../include/lustre_req_layout.h"
-#include "../include/lustre_fld.h"
-#include "../include/lustre_mdc.h"
+#include <lustre_req_layout.h>
+#include <lustre_fld.h>
+#include <lustre_mdc.h>
#include "fld_internal.h"
static int fld_rrb_hash(struct lu_client_fld *fld, u64 seq)
diff --git a/drivers/staging/lustre/lustre/fld/lproc_fld.c b/drivers/staging/lustre/lustre/fld/lproc_fld.c
index b83d7eb..6cae803 100644
--- a/drivers/staging/lustre/lustre/fld/lproc_fld.c
+++ b/drivers/staging/lustre/lustre/fld/lproc_fld.c
@@ -39,15 +39,15 @@
#define DEBUG_SUBSYSTEM S_FLD
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
#include <linux/module.h>
-#include "../include/obd.h"
-#include "../include/obd_class.h"
-#include "../include/obd_support.h"
-#include "../include/lustre_req_layout.h"
-#include "../include/lustre_fld.h"
-#include "../include/lustre_fid.h"
+#include <obd.h>
+#include <obd_class.h>
+#include <obd_support.h>
+#include <lustre_req_layout.h>
+#include <lustre_fld.h>
+#include <lustre_fid.h>
#include "fld_internal.h"
static int
diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h
index 90a0c50..9ba184b 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -88,8 +88,8 @@
/*
* super-class definitions.
*/
-#include "lu_object.h"
-#include "lustre_compat.h"
+#include <lu_object.h>
+#include <lustre_compat.h>
#include <linux/atomic.h>
#include <linux/mutex.h>
#include <linux/radix-tree.h>
@@ -1358,7 +1358,7 @@ struct cl_2queue {
/** IO types */
enum cl_io_type {
/** read system call */
- CIT_READ,
+ CIT_READ = 1,
/** write system call */
CIT_WRITE,
/** truncate, utime system calls */
diff --git a/drivers/staging/lustre/lustre/include/interval_tree.h b/drivers/staging/lustre/lustre/include/interval_tree.h
index 0d4f92e..a4d7280 100644
--- a/drivers/staging/lustre/lustre/include/interval_tree.h
+++ b/drivers/staging/lustre/lustre/include/interval_tree.h
@@ -111,4 +111,8 @@ enum interval_iter interval_search(struct interval_node *root,
struct interval_node_extent *ex,
interval_callback_t func, void *data);
+enum interval_iter interval_iterate_reverse(struct interval_node *root,
+ interval_callback_t func,
+ void *data);
+
#endif
diff --git a/drivers/staging/lustre/lustre/include/llog_swab.h b/drivers/staging/lustre/lustre/include/llog_swab.h
index fd7ffb1..925271d 100644
--- a/drivers/staging/lustre/lustre/include/llog_swab.h
+++ b/drivers/staging/lustre/lustre/include/llog_swab.h
@@ -48,7 +48,8 @@
#ifndef _LLOG_SWAB_H_
#define _LLOG_SWAB_H_
-#include "lustre/lustre_idl.h"
+#include <uapi/linux/lustre/lustre_idl.h>
+
struct lustre_cfg;
void lustre_swab_lu_fid(struct lu_fid *fid);
diff --git a/drivers/staging/lustre/lustre/include/lprocfs_status.h b/drivers/staging/lustre/lustre/include/lprocfs_status.h
index 915283c..98d6b13 100644
--- a/drivers/staging/lustre/lustre/include/lprocfs_status.h
+++ b/drivers/staging/lustre/lustre/include/lprocfs_status.h
@@ -43,9 +43,9 @@
#include <linux/spinlock.h>
#include <linux/types.h>
-#include "../../include/linux/libcfs/libcfs.h"
-#include "lustre_cfg.h"
-#include "lustre/lustre_idl.h"
+#include <linux/libcfs/libcfs.h>
+#include <uapi/linux/lustre/lustre_cfg.h>
+#include <uapi/linux/lustre/lustre_idl.h>
struct lprocfs_vars {
const char *name;
@@ -59,7 +59,7 @@ struct lprocfs_vars {
struct lprocfs_static_vars {
struct lprocfs_vars *obd_vars;
- struct attribute_group *sysfs_vars;
+ const struct attribute_group *sysfs_vars;
};
/* if we find more consumers this could be generalized */
@@ -468,7 +468,7 @@ struct dentry *ldebugfs_register(const char *name,
void ldebugfs_remove(struct dentry **entryp);
int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list,
- struct attribute_group *attrs);
+ const struct attribute_group *attrs);
int lprocfs_obd_cleanup(struct obd_device *obd);
int ldebugfs_seq_create(struct dentry *parent,
diff --git a/drivers/staging/lustre/lustre/include/lu_object.h b/drivers/staging/lustre/lustre/include/lu_object.h
index 2e70602..4f213c4 100644
--- a/drivers/staging/lustre/lustre/include/lu_object.h
+++ b/drivers/staging/lustre/lustre/include/lu_object.h
@@ -35,9 +35,9 @@
#include <stdarg.h>
#include <linux/percpu_counter.h>
-#include "../../include/linux/libcfs/libcfs.h"
-#include "lustre/lustre_idl.h"
-#include "lu_ref.h"
+#include <linux/libcfs/libcfs.h>
+#include <uapi/linux/lustre/lustre_idl.h>
+#include <lu_ref.h>
struct seq_file;
struct lustre_cfg;
diff --git a/drivers/staging/lustre/lustre/include/lustre_compat.h b/drivers/staging/lustre/lustre/include/lustre_compat.h
index da9ce19..69bfd6a 100644
--- a/drivers/staging/lustre/lustre/include/lustre_compat.h
+++ b/drivers/staging/lustre/lustre/include/lustre_compat.h
@@ -37,7 +37,7 @@
#include <linux/namei.h>
#include <linux/cred.h>
-#include "lustre_patchless_compat.h"
+#include <lustre_patchless_compat.h>
/*
* set ATTR_BLOCKS to a high value to avoid any risk of collision with other
diff --git a/drivers/staging/lustre/lustre/include/lustre_debug.h b/drivers/staging/lustre/lustre/include/lustre_debug.h
index 93c1bda..0be6a53 100644
--- a/drivers/staging/lustre/lustre/include/lustre_debug.h
+++ b/drivers/staging/lustre/lustre/include/lustre_debug.h
@@ -38,8 +38,8 @@
* @{
*/
-#include "lustre_net.h"
-#include "obd.h"
+#include <lustre_net.h>
+#include <obd.h>
/* lib/debug.c */
int dump_req(struct ptlrpc_request *req);
diff --git a/drivers/staging/lustre/lustre/include/lustre_disk.h b/drivers/staging/lustre/lustre/include/lustre_disk.h
index a676bcc..2d862b3 100644
--- a/drivers/staging/lustre/lustre/include/lustre_disk.h
+++ b/drivers/staging/lustre/lustre/include/lustre_disk.h
@@ -44,9 +44,10 @@
* @{
*/
-#include "../../include/linux/libcfs/libcfs.h"
-#include "../../include/linux/lnet/types.h"
+#include <asm/byteorder.h>
+#include <linux/types.h>
#include <linux/backing-dev.h>
+#include <linux/libcfs/libcfs.h>
/****************** persistent mount data *********************/
@@ -108,14 +109,6 @@ struct lustre_mount_data {
#define lmd_is_client(x) ((x)->lmd_flags & LMD_FLG_CLIENT)
-/****************** last_rcvd file *********************/
-
-/** version recovery epoch */
-#define LR_EPOCH_BITS 32
-#define lr_epoch(a) ((a) >> LR_EPOCH_BITS)
-#define LR_EXPIRE_INTERVALS 16 /**< number of intervals to track transno */
-#define ENOENT_VERSION 1 /** 'virtual' version of non-existent object */
-
/****************** superblock additional info *********************/
struct ll_sb_info;
@@ -141,16 +134,6 @@ struct lustre_sb_info {
#define s2lsi_nocast(sb) ((sb)->s_fs_info)
#define get_profile_name(sb) (s2lsi(sb)->lsi_lmd->lmd_profile)
-#define get_mount_flags(sb) (s2lsi(sb)->lsi_lmd->lmd_flags)
-#define get_mntdev_name(sb) (s2lsi(sb)->lsi_lmd->lmd_dev)
-
-/****************** mount lookup info *********************/
-
-struct lustre_mount_info {
- char *lmi_name;
- struct super_block *lmi_sb;
- struct list_head lmi_list_chain;
-};
/****************** prototypes *********************/
diff --git a/drivers/staging/lustre/lustre/include/lustre_dlm.h b/drivers/staging/lustre/lustre/include/lustre_dlm.h
index 1e86fb5..13c3d2f 100644
--- a/drivers/staging/lustre/lustre/include/lustre_dlm.h
+++ b/drivers/staging/lustre/lustre/include/lustre_dlm.h
@@ -44,12 +44,12 @@
#ifndef _LUSTRE_DLM_H__
#define _LUSTRE_DLM_H__
-#include "lustre_lib.h"
-#include "lustre_net.h"
-#include "lustre_import.h"
-#include "lustre_handles.h"
-#include "interval_tree.h" /* for interval_node{}, ldlm_extent */
-#include "lu_ref.h"
+#include <lustre_lib.h>
+#include <lustre_net.h>
+#include <lustre_import.h>
+#include <lustre_handles.h>
+#include <interval_tree.h> /* for interval_node{}, ldlm_extent */
+#include <lu_ref.h>
#include "lustre_dlm_flags.h"
@@ -1336,5 +1336,18 @@ void ldlm_pool_add(struct ldlm_pool *pl, struct ldlm_lock *lock);
void ldlm_pool_del(struct ldlm_pool *pl, struct ldlm_lock *lock);
/** @} */
+static inline int ldlm_extent_overlap(const struct ldlm_extent *ex1,
+ const struct ldlm_extent *ex2)
+{
+ return ex1->start <= ex2->end && ex2->start <= ex1->end;
+}
+
+/* check if @ex1 contains @ex2 */
+static inline int ldlm_extent_contain(const struct ldlm_extent *ex1,
+ const struct ldlm_extent *ex2)
+{
+ return ex1->start <= ex2->start && ex1->end >= ex2->end;
+}
+
#endif
/** @} LDLM */
diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_errno.h b/drivers/staging/lustre/lustre/include/lustre_errno.h
index 35aefa2..35aefa2 100644
--- a/drivers/staging/lustre/lustre/include/lustre/lustre_errno.h
+++ b/drivers/staging/lustre/lustre/include/lustre_errno.h
diff --git a/drivers/staging/lustre/lustre/include/lustre_export.h b/drivers/staging/lustre/lustre/include/lustre_export.h
index 6e7cc46..3631a69 100644
--- a/drivers/staging/lustre/lustre/include/lustre_export.h
+++ b/drivers/staging/lustre/lustre/include/lustre_export.h
@@ -42,9 +42,9 @@
* @{
*/
-#include "lprocfs_status.h"
-#include "lustre/lustre_idl.h"
-#include "lustre_dlm.h"
+#include <lprocfs_status.h>
+#include <uapi/linux/lustre/lustre_idl.h>
+#include <lustre_dlm.h>
enum obd_option {
OBD_OPT_FORCE = 0x0001,
diff --git a/drivers/staging/lustre/lustre/include/lustre_fid.h b/drivers/staging/lustre/lustre/include/lustre_fid.h
index 6dc24a7..e0f2b82 100644
--- a/drivers/staging/lustre/lustre/include/lustre_fid.h
+++ b/drivers/staging/lustre/lustre/include/lustre_fid.h
@@ -41,7 +41,7 @@
*
* @{
*
- * http://wiki.old.lustre.org/index.php/Architecture_-_Interoperability_fids_zfs
+ * http://wiki.lustre.org/index.php/Architecture_-_Interoperability_fids_zfs
* describes the FID namespace and interoperability requirements for FIDs.
* The important parts of that document are included here for reference.
*
@@ -148,9 +148,10 @@
* Even so, the MDT and OST resources are also in different LDLM namespaces.
*/
-#include "../../include/linux/libcfs/libcfs.h"
-#include "lustre/lustre_idl.h"
-#include "seq_range.h"
+#include <linux/libcfs/libcfs.h>
+#include <uapi/linux/lustre/lustre_fid.h>
+#include <uapi/linux/lustre/lustre_idl.h>
+#include <uapi/linux/lustre/lustre_ostid.h>
struct lu_env;
struct lu_site;
@@ -288,18 +289,6 @@ static inline int fid_is_quota(const struct lu_fid *fid)
fid_seq(fid) == FID_SEQ_QUOTA_GLB;
}
-static inline int fid_is_namespace_visible(const struct lu_fid *fid)
-{
- const __u64 seq = fid_seq(fid);
-
- /* Here, we cannot distinguish whether the normal FID is for OST
- * object or not. It is caller's duty to check more if needed.
- */
- return (!fid_is_last_id(fid) &&
- (fid_seq_is_norm(seq) || fid_seq_is_igif(seq))) ||
- fid_is_root(fid) || fid_is_dot_lustre(fid);
-}
-
static inline int fid_seq_in_fldb(__u64 seq)
{
return fid_seq_is_igif(seq) || fid_seq_is_norm(seq) ||
@@ -506,6 +495,52 @@ static inline int ostid_res_name_eq(const struct ost_id *oi,
}
}
+/**
+ * Note: we need check oi_seq to decide where to set oi_id,
+ * so oi_seq should always be set ahead of oi_id.
+ */
+static inline int ostid_set_id(struct ost_id *oi, __u64 oid)
+{
+ if (fid_seq_is_mdt0(oi->oi.oi_seq)) {
+ if (oid >= IDIF_MAX_OID)
+ return -E2BIG;
+ oi->oi.oi_id = oid;
+ } else if (fid_is_idif(&oi->oi_fid)) {
+ if (oid >= IDIF_MAX_OID)
+ return -E2BIG;
+ oi->oi_fid.f_seq = fid_idif_seq(oid,
+ fid_idif_ost_idx(&oi->oi_fid));
+ oi->oi_fid.f_oid = oid;
+ oi->oi_fid.f_ver = oid >> 48;
+ } else {
+ if (oid >= OBIF_MAX_OID)
+ return -E2BIG;
+ oi->oi_fid.f_oid = oid;
+ }
+ return 0;
+}
+
+/* pack any OST FID into an ostid (id/seq) for the wire/disk */
+static inline int fid_to_ostid(const struct lu_fid *fid, struct ost_id *ostid)
+{
+ int rc = 0;
+
+ if (fid_seq_is_igif(fid->f_seq))
+ return -EBADF;
+
+ if (fid_is_idif(fid)) {
+ u64 objid = fid_idif_id(fid_seq(fid), fid_oid(fid),
+ fid_ver(fid));
+
+ ostid_set_seq_mdt0(ostid);
+ rc = ostid_set_id(ostid, objid);
+ } else {
+ ostid->oi_fid = *fid;
+ }
+
+ return rc;
+}
+
/* The same as osc_build_res_name() */
static inline void ost_fid_build_resid(const struct lu_fid *fid,
struct ldlm_res_id *resname)
@@ -522,23 +557,6 @@ static inline void ost_fid_build_resid(const struct lu_fid *fid,
}
}
-static inline void ost_fid_from_resid(struct lu_fid *fid,
- const struct ldlm_res_id *name,
- int ost_idx)
-{
- if (fid_seq_is_mdt0(name->name[LUSTRE_RES_ID_VER_OID_OFF])) {
- /* old resid */
- struct ost_id oi;
-
- ostid_set_seq(&oi, name->name[LUSTRE_RES_ID_VER_OID_OFF]);
- ostid_set_id(&oi, name->name[LUSTRE_RES_ID_SEQ_OFF]);
- ostid_to_fid(fid, &oi, ost_idx);
- } else {
- /* new resid */
- fid_extract_from_res_name(fid, name);
- }
-}
-
/**
* Flatten 128-bit FID values into a 64-bit value for use as an inode number.
* For non-IGIF FIDs this starts just over 2^32, and continues without
diff --git a/drivers/staging/lustre/lustre/include/lustre_fld.h b/drivers/staging/lustre/lustre/include/lustre_fld.h
index 6ef1b03..6125eb0 100644
--- a/drivers/staging/lustre/lustre/include/lustre_fld.h
+++ b/drivers/staging/lustre/lustre/include/lustre_fld.h
@@ -38,8 +38,9 @@
* @{
*/
-#include "lustre/lustre_idl.h"
-#include "../../include/linux/libcfs/libcfs.h"
+#include <uapi/linux/lustre/lustre_idl.h>
+#include <linux/libcfs/libcfs.h>
+#include <seq_range.h>
struct lu_client_fld;
struct lu_server_fld;
diff --git a/drivers/staging/lustre/lustre/include/lustre_handles.h b/drivers/staging/lustre/lustre/include/lustre_handles.h
index e071bac..d499326 100644
--- a/drivers/staging/lustre/lustre/include/lustre_handles.h
+++ b/drivers/staging/lustre/lustre/include/lustre_handles.h
@@ -44,7 +44,7 @@
#include <linux/spinlock.h>
#include <linux/types.h>
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
struct portals_handle_ops {
void (*hop_addref)(void *object);
diff --git a/drivers/staging/lustre/lustre/include/lustre_import.h b/drivers/staging/lustre/lustre/include/lustre_import.h
index f0c931c..d71d047 100644
--- a/drivers/staging/lustre/lustre/include/lustre_import.h
+++ b/drivers/staging/lustre/lustre/include/lustre_import.h
@@ -43,8 +43,8 @@
* @{
*/
-#include "lustre_handles.h"
-#include "lustre/lustre_idl.h"
+#include <lustre_handles.h>
+#include <uapi/linux/lustre/lustre_idl.h>
/**
* Adaptive Timeout stuff
diff --git a/drivers/staging/lustre/lustre/include/lustre_kernelcomm.h b/drivers/staging/lustre/lustre/include/lustre_kernelcomm.h
index 970610b..f1899a3d 100644
--- a/drivers/staging/lustre/lustre/include/lustre_kernelcomm.h
+++ b/drivers/staging/lustre/lustre/include/lustre_kernelcomm.h
@@ -38,7 +38,7 @@
#define __LUSTRE_KERNELCOMM_H__
/* For declarations shared with userspace */
-#include "uapi_kernelcomm.h"
+#include <uapi/linux/lustre/lustre_kernelcomm.h>
/* prototype for callback function on kuc groups */
typedef int (*libcfs_kkuc_cb_t)(void *data, void *cb_arg);
diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h
index f24970d..81b9cbf 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lib.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
@@ -45,18 +45,18 @@
#include <linux/sched/signal.h>
#include <linux/signal.h>
#include <linux/types.h>
-#include "../../include/linux/libcfs/libcfs.h"
-#include "lustre/lustre_idl.h"
-#include "lustre_ver.h"
-#include "lustre_cfg.h"
+#include <linux/libcfs/libcfs.h>
+#include <uapi/linux/lustre/lustre_idl.h>
+#include <uapi/linux/lustre/lustre_ver.h>
+#include <uapi/linux/lustre/lustre_cfg.h>
/* target.c */
struct ptlrpc_request;
struct obd_export;
struct lu_target;
struct l_wait_info;
-#include "lustre_ha.h"
-#include "lustre_net.h"
+#include <lustre_ha.h>
+#include <lustre_net.h>
#define LI_POISON 0x5a5a5a5a
#if BITS_PER_LONG > 32
diff --git a/drivers/staging/lustre/lustre/include/lustre_linkea.h b/drivers/staging/lustre/lustre/include/lustre_linkea.h
index 249e8bf..3ff008fe 100644
--- a/drivers/staging/lustre/lustre/include/lustre_linkea.h
+++ b/drivers/staging/lustre/lustre/include/lustre_linkea.h
@@ -26,7 +26,19 @@
* Author: di wang <di.wang@intel.com>
*/
-#define DEFAULT_LINKEA_SIZE 4096
+/* There are several reasons to restrict the linkEA size:
+ *
+ * 1. Under DNE mode, if we do not restrict the linkEA size, and if there
+ * are too many cross-MDTs hard links to the same object, then it will
+ * casue the llog overflow.
+ *
+ * 2. Some backend has limited size for EA. For example, if without large
+ * EA enabled, the ldiskfs will make all EAs to share one (4K) EA block.
+ *
+ * 3. Too many entries in linkEA will seriously affect linkEA performance
+ * because we only support to locate linkEA entry consecutively.
+ */
+#define MAX_LINKEA_SIZE 4096
struct linkea_data {
/**
@@ -43,6 +55,7 @@ struct linkea_data {
int linkea_data_new(struct linkea_data *ldata, struct lu_buf *buf);
int linkea_init(struct linkea_data *ldata);
+int linkea_init_with_rec(struct linkea_data *ldata);
void linkea_entry_unpack(const struct link_ea_entry *lee, int *reclen,
struct lu_name *lname, struct lu_fid *pfid);
int linkea_entry_pack(struct link_ea_entry *lee, const struct lu_name *lname,
diff --git a/drivers/staging/lustre/lustre/include/lustre_lmv.h b/drivers/staging/lustre/lustre/include/lustre_lmv.h
index 5aa3645..98a82be2 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lmv.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lmv.h
@@ -32,7 +32,7 @@
#ifndef _LUSTRE_LMV_H
#define _LUSTRE_LMV_H
-#include "lustre/lustre_idl.h"
+#include <uapi/linux/lustre/lustre_idl.h>
struct lmv_oinfo {
struct lu_fid lmo_fid;
diff --git a/drivers/staging/lustre/lustre/include/lustre_log.h b/drivers/staging/lustre/lustre/include/lustre_log.h
index 35e37eb..24a7777 100644
--- a/drivers/staging/lustre/lustre/include/lustre_log.h
+++ b/drivers/staging/lustre/lustre/include/lustre_log.h
@@ -52,8 +52,8 @@
* @{
*/
-#include "obd_class.h"
-#include "lustre/lustre_idl.h"
+#include <obd_class.h>
+#include <uapi/linux/lustre/lustre_idl.h>
#define LOG_NAME_LIMIT(logname, name) \
snprintf(logname, sizeof(logname), "LOGS/%s", name)
diff --git a/drivers/staging/lustre/lustre/include/lustre_mdc.h b/drivers/staging/lustre/lustre/include/lustre_mdc.h
index 198ceb0..c0c4497 100644
--- a/drivers/staging/lustre/lustre/include/lustre_mdc.h
+++ b/drivers/staging/lustre/lustre/include/lustre_mdc.h
@@ -46,14 +46,13 @@
#include <linux/fs.h>
#include <linux/dcache.h>
-#include "lustre_intent.h"
-#include "lustre_handles.h"
-#include "../../include/linux/libcfs/libcfs.h"
-#include "obd_class.h"
-#include "lustre/lustre_idl.h"
-#include "lustre_lib.h"
-#include "lustre_dlm.h"
-#include "lustre_export.h"
+#include <lustre_intent.h>
+#include <lustre_handles.h>
+#include <linux/libcfs/libcfs.h>
+#include <obd_class.h>
+#include <lustre_lib.h>
+#include <lustre_dlm.h>
+#include <lustre_export.h>
struct ptlrpc_client;
struct obd_export;
diff --git a/drivers/staging/lustre/lustre/include/lustre_mds.h b/drivers/staging/lustre/lustre/include/lustre_mds.h
index 23a7e4f..c424e12 100644
--- a/drivers/staging/lustre/lustre/include/lustre_mds.h
+++ b/drivers/staging/lustre/lustre/include/lustre_mds.h
@@ -43,12 +43,11 @@
* @{
*/
-#include "lustre_handles.h"
-#include "../../include/linux/libcfs/libcfs.h"
-#include "lustre/lustre_idl.h"
-#include "lustre_lib.h"
-#include "lustre_dlm.h"
-#include "lustre_export.h"
+#include <lustre_handles.h>
+#include <linux/libcfs/libcfs.h>
+#include <lustre_lib.h>
+#include <lustre_dlm.h>
+#include <lustre_export.h>
struct mds_group_info {
struct obd_uuid *uuid;
diff --git a/drivers/staging/lustre/lustre/include/lustre_net.h b/drivers/staging/lustre/lustre/include/lustre_net.h
index d61b000..c6d1646 100644
--- a/drivers/staging/lustre/lustre/include/lustre_net.h
+++ b/drivers/staging/lustre/lustre/include/lustre_net.h
@@ -51,19 +51,20 @@
*/
#include <linux/uio.h>
-#include "../../include/linux/libcfs/libcfs.h"
-#include "../../include/linux/lnet/nidstr.h"
-#include "../../include/linux/lnet/api.h"
-#include "lustre/lustre_idl.h"
-#include "lustre_ha.h"
-#include "lustre_sec.h"
-#include "lustre_import.h"
-#include "lprocfs_status.h"
-#include "lu_object.h"
-#include "lustre_req_layout.h"
-
-#include "obd_support.h"
-#include "lustre_ver.h"
+#include <linux/libcfs/libcfs.h>
+#include <uapi/linux/lnet/nidstr.h>
+#include <linux/lnet/api.h>
+#include <uapi/linux/lustre/lustre_idl.h>
+#include <lustre_errno.h>
+#include <lustre_ha.h>
+#include <lustre_sec.h>
+#include <lustre_import.h>
+#include <lprocfs_status.h>
+#include <lu_object.h>
+#include <lustre_req_layout.h>
+
+#include <obd_support.h>
+#include <uapi/linux/lustre/lustre_ver.h>
/* MD flags we _always_ use */
#define PTLRPC_MD_OPTIONS 0
@@ -521,7 +522,7 @@ struct lu_env;
struct ldlm_lock;
-#include "lustre_nrs.h"
+#include <lustre_nrs.h>
/**
* Basic request prioritization operations structure.
@@ -558,13 +559,13 @@ struct ptlrpc_cli_req {
/** request sent timeval */
struct timespec64 cr_sent_tv;
/** time for request really sent out */
- time_t cr_sent_out;
+ time64_t cr_sent_out;
/** when req reply unlink must finish. */
- time_t cr_reply_deadline;
+ time64_t cr_reply_deadline;
/** when req bulk unlink must finish. */
- time_t cr_bulk_deadline;
+ time64_t cr_bulk_deadline;
/** when req unlink must finish. */
- time_t cr_req_deadline;
+ time64_t cr_req_deadline;
/** Portal to which this request would be sent */
short cr_req_ptl;
/** Portal where to wait for reply and where reply would be sent */
@@ -663,7 +664,7 @@ struct ptlrpc_srv_req {
/** history sequence # */
__u64 sr_hist_seq;
/** the index of service's srv_at_array into which request is linked */
- time_t sr_at_index;
+ time64_t sr_at_index;
/** authed uid */
uid_t sr_auth_uid;
/** authed uid mapped to */
diff --git a/drivers/staging/lustre/lustre/include/lustre_nrs.h b/drivers/staging/lustre/lustre/include/lustre_nrs.h
index a5028aa..51f45f7 100644
--- a/drivers/staging/lustre/lustre/include/lustre_nrs.h
+++ b/drivers/staging/lustre/lustre/include/lustre_nrs.h
@@ -669,7 +669,7 @@ enum {
NRS_RES_MAX
};
-#include "lustre_nrs_fifo.h"
+#include <lustre_nrs_fifo.h>
/**
* NRS request
diff --git a/drivers/staging/lustre/lustre/include/lustre_obdo.h b/drivers/staging/lustre/lustre/include/lustre_obdo.h
index 1e12f8c..53379f8 100644
--- a/drivers/staging/lustre/lustre/include/lustre_obdo.h
+++ b/drivers/staging/lustre/lustre/include/lustre_obdo.h
@@ -35,7 +35,7 @@
#ifndef _LUSTRE_OBDO_H_
#define _LUSTRE_OBDO_H_
-#include "lustre/lustre_idl.h"
+#include <uapi/linux/lustre/lustre_idl.h>
/**
* Create an obdo to send over the wire
diff --git a/drivers/staging/lustre/lustre/include/lustre_param.h b/drivers/staging/lustre/lustre/include/lustre_param.h
deleted file mode 100644
index 8061a04..0000000
--- a/drivers/staging/lustre/lustre/include/lustre_param.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2011, 2015, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * lustre/include/lustre_param.h
- *
- * User-settable parameter keys
- *
- * Author: Nathan Rutman <nathan@clusterfs.com>
- */
-
-#ifndef _LUSTRE_PARAM_H
-#define _LUSTRE_PARAM_H
-
-#include "../../include/linux/libcfs/libcfs.h"
-#include "../../include/linux/lnet/types.h"
-
-/** \defgroup param param
- *
- * @{
- */
-
-/* For interoperability */
-struct cfg_interop_param {
- char *old_param;
- char *new_param;
-};
-
-/* obd_config.c */
-int class_find_param(char *buf, char *key, char **valp);
-int class_parse_nid(char *buf, lnet_nid_t *nid, char **endh);
-int class_parse_nid_quiet(char *buf, lnet_nid_t *nid, char **endh);
-
-/****************** User-settable parameter keys *********************/
-/* e.g.
- tunefs.lustre --param="failover.node=192.168.0.13@tcp0" /dev/sda
- lctl conf_param testfs-OST0000 failover.node=3@elan,192.168.0.3@tcp0
- ... testfs-MDT0000.lov.stripesize=4M
- ... testfs-OST0000.ost.client_cache_seconds=15
- ... testfs.sys.timeout=<secs>
- ... testfs.llite.max_read_ahead_mb=16
-*/
-
-/* System global or special params not handled in obd's proc
- * See mgs_write_log_sys()
- */
-#define PARAM_TIMEOUT "timeout=" /* global */
-#define PARAM_LDLM_TIMEOUT "ldlm_timeout=" /* global */
-#define PARAM_AT_MIN "at_min=" /* global */
-#define PARAM_AT_MAX "at_max=" /* global */
-#define PARAM_AT_EXTRA "at_extra=" /* global */
-#define PARAM_AT_EARLY_MARGIN "at_early_margin=" /* global */
-#define PARAM_AT_HISTORY "at_history=" /* global */
-#define PARAM_JOBID_VAR "jobid_var=" /* global */
-#define PARAM_MGSNODE "mgsnode=" /* only at mounttime */
-#define PARAM_FAILNODE "failover.node=" /* add failover nid */
-#define PARAM_FAILMODE "failover.mode=" /* initial mount only */
-#define PARAM_ACTIVE "active=" /* activate/deactivate */
-#define PARAM_NETWORK "network=" /* bind on nid */
-#define PARAM_ID_UPCALL "identity_upcall=" /* identity upcall */
-
-/* Prefixes for parameters handled by obd's proc methods (XXX_process_config) */
-#define PARAM_OST "ost."
-#define PARAM_OSD "osd."
-#define PARAM_OSC "osc."
-#define PARAM_MDT "mdt."
-#define PARAM_MDD "mdd."
-#define PARAM_MDC "mdc."
-#define PARAM_LLITE "llite."
-#define PARAM_LOV "lov."
-#define PARAM_LOD "lod."
-#define PARAM_OSP "osp."
-#define PARAM_SYS "sys." /* global */
-#define PARAM_SRPC "srpc."
-#define PARAM_SRPC_FLVR "srpc.flavor."
-#define PARAM_SRPC_UDESC "srpc.udesc.cli2mdt"
-#define PARAM_SEC "security."
-#define PARAM_QUOTA "quota." /* global */
-
-/** @} param */
-
-#endif /* _LUSTRE_PARAM_H */
diff --git a/drivers/staging/lustre/lustre/include/lustre_swab.h b/drivers/staging/lustre/lustre/include/lustre_swab.h
index 26d01c2..765e923 100644
--- a/drivers/staging/lustre/lustre/include/lustre_swab.h
+++ b/drivers/staging/lustre/lustre/include/lustre_swab.h
@@ -48,7 +48,7 @@
#ifndef _LUSTRE_SWAB_H_
#define _LUSTRE_SWAB_H_
-#include "lustre/lustre_idl.h"
+#include <uapi/linux/lustre/lustre_idl.h>
void lustre_swab_ptlrpc_body(struct ptlrpc_body *pb);
void lustre_swab_connect(struct obd_connect_data *ocd);
@@ -99,4 +99,10 @@ void lustre_swab_swap_layouts(struct mdc_swap_layouts *msl);
void lustre_swab_close_data(struct close_data *data);
void lustre_swab_lmv_user_md(struct lmv_user_md *lum);
+/* Functions for dumping PTLRPC fields */
+void dump_rniobuf(struct niobuf_remote *rnb);
+void dump_ioo(struct obd_ioobj *nb);
+void dump_ost_body(struct ost_body *ob);
+void dump_rcs(__u32 *rc);
+
#endif
diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h
index 4ce8506..a986737 100644
--- a/drivers/staging/lustre/lustre/include/obd.h
+++ b/drivers/staging/lustre/lustre/include/obd.h
@@ -35,15 +35,15 @@
#include <linux/spinlock.h>
-#include "lustre/lustre_idl.h"
-#include "lustre_lib.h"
-#include "lu_ref.h"
-#include "lustre_export.h"
-#include "lustre_fid.h"
-#include "lustre_fld.h"
-#include "lustre_handles.h"
-#include "lustre_intent.h"
-#include "cl_object.h"
+#include <uapi/linux/lustre/lustre_idl.h>
+#include <lustre_lib.h>
+#include <lu_ref.h>
+#include <lustre_export.h>
+#include <lustre_fid.h>
+#include <lustre_fld.h>
+#include <lustre_handles.h>
+#include <lustre_intent.h>
+#include <cl_object.h>
#define MAX_OBD_DEVICES 8192
@@ -404,12 +404,10 @@ struct lmv_tgt_desc {
};
struct lmv_obd {
- int refcount;
struct lu_client_fld lmv_fld;
spinlock_t lmv_lock;
struct lmv_desc desc;
struct obd_uuid cluuid;
- struct obd_export *exp;
struct mutex lmv_init_mutex;
int connected;
diff --git a/drivers/staging/lustre/lustre/include/obd_cksum.h b/drivers/staging/lustre/lustre/include/obd_cksum.h
index a8a81e6..cda3d28 100644
--- a/drivers/staging/lustre/lustre/include/obd_cksum.h
+++ b/drivers/staging/lustre/lustre/include/obd_cksum.h
@@ -30,9 +30,9 @@
#ifndef __OBD_CKSUM
#define __OBD_CKSUM
-#include "../../include/linux/libcfs/libcfs.h"
-#include "../../include/linux/libcfs/libcfs_crypto.h"
-#include "lustre/lustre_idl.h"
+#include <linux/libcfs/libcfs.h>
+#include <linux/libcfs/libcfs_crypto.h>
+#include <uapi/linux/lustre/lustre_idl.h>
static inline unsigned char cksum_obd2cfs(enum cksum_type cksum_type)
{
diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h
index 083a6ff..976005a 100644
--- a/drivers/staging/lustre/lustre/include/obd_class.h
+++ b/drivers/staging/lustre/lustre/include/obd_class.h
@@ -32,13 +32,12 @@
#ifndef __CLASS_OBD_H
#define __CLASS_OBD_H
-#include "obd_support.h"
-#include "lustre_import.h"
-#include "lustre_net.h"
-#include "obd.h"
-#include "lustre_lib.h"
-#include "lustre/lustre_idl.h"
-#include "lprocfs_status.h"
+#include <obd_support.h>
+#include <lustre_import.h>
+#include <lustre_net.h>
+#include <obd.h>
+#include <lustre_lib.h>
+#include <lprocfs_status.h>
#define OBD_STATFS_NODELAY 0x0001 /* requests should be send without delay
* and resends for avoid deadlocks
@@ -46,14 +45,7 @@
#define OBD_STATFS_FROM_CACHE 0x0002 /* the statfs callback should not update
* obd_osfs_age
*/
-#define OBD_STATFS_PTLRPCD 0x0004 /* requests will be sent via ptlrpcd
- * instead of a specific set. This
- * means that we cannot rely on the set
- * interpret routine to be called.
- * lov_statfs_fini() must thus be called
- * by the request interpret routine
- */
-#define OBD_STATFS_FOR_MDT0 0x0008 /* The statfs is only for retrieving
+#define OBD_STATFS_FOR_MDT0 0x0004 /* The statfs is only for retrieving
* information from MDT0.
*/
@@ -112,10 +104,29 @@ struct llog_handle;
struct llog_rec_hdr;
typedef int (*llog_cb_t)(const struct lu_env *, struct llog_handle *,
struct llog_rec_hdr *, void *);
+
/* obd_config.c */
+char *lustre_cfg_string(struct lustre_cfg *lcfg, u32 index);
int class_process_config(struct lustre_cfg *lcfg);
int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars,
struct lustre_cfg *lcfg, void *data);
+
+/* For interoperability */
+struct cfg_interop_param {
+ char *old_param;
+ char *new_param;
+};
+
+int class_find_param(char *buf, char *key, char **valp);
+struct cfg_interop_param *class_find_old_param(const char *param,
+ struct cfg_interop_param *ptr);
+int class_get_next_param(char **params, char *copy);
+int class_parse_nid(char *buf, lnet_nid_t *nid, char **endh);
+int class_parse_nid_quiet(char *buf, lnet_nid_t *nid, char **endh);
+int class_parse_net(char *buf, u32 *net, char **endh);
+int class_match_nid(char *buf, char *key, lnet_nid_t nid);
+int class_match_net(char *buf, char *key, u32 net);
+
struct obd_device *class_incref(struct obd_device *obd,
const char *scope, const void *source);
void class_decref(struct obd_device *obd,
@@ -1566,4 +1577,7 @@ struct root_squash_info {
struct rw_semaphore rsi_sem;
};
+/* linux-module.c */
+int obd_ioctl_getdata(char **buf, int *len, void __user *arg);
+
#endif /* __LINUX_OBD_CLASS_H */
diff --git a/drivers/staging/lustre/lustre/include/obd_support.h b/drivers/staging/lustre/lustre/include/obd_support.h
index 3330404..aea193a 100644
--- a/drivers/staging/lustre/lustre/include/obd_support.h
+++ b/drivers/staging/lustre/lustre/include/obd_support.h
@@ -36,9 +36,9 @@
#include <linux/slab.h>
#include <linux/sched/signal.h>
-#include "../../include/linux/libcfs/libcfs.h"
-#include "lustre_compat.h"
-#include "lprocfs_status.h"
+#include <linux/libcfs/libcfs.h>
+#include <lustre_compat.h>
+#include <lprocfs_status.h>
/* global variables */
extern unsigned int obd_debug_peer_on_timeout;
diff --git a/drivers/staging/lustre/lustre/include/seq_range.h b/drivers/staging/lustre/lustre/include/seq_range.h
index 30c4dd6..d717548 100644
--- a/drivers/staging/lustre/lustre/include/seq_range.h
+++ b/drivers/staging/lustre/lustre/include/seq_range.h
@@ -34,7 +34,7 @@
#ifndef _SEQ_RANGE_H_
#define _SEQ_RANGE_H_
-#include "lustre/lustre_idl.h"
+#include <uapi/linux/lustre/lustre_idl.h>
/**
* computes the sequence range type \a range
diff --git a/drivers/staging/lustre/lustre/ldlm/interval_tree.c b/drivers/staging/lustre/lustre/ldlm/interval_tree.c
index e106902..19e285d 100644
--- a/drivers/staging/lustre/lustre/ldlm/interval_tree.c
+++ b/drivers/staging/lustre/lustre/ldlm/interval_tree.c
@@ -34,9 +34,9 @@
* Author: Huang Wei <huangwei@clusterfs.com>
* Author: Jay Xiong <jinshan.xiong@sun.com>
*/
-#include "../include/lustre_dlm.h"
-#include "../include/obd_support.h"
-#include "../include/interval_tree.h"
+#include <lustre_dlm.h>
+#include <obd_support.h>
+#include <interval_tree.h>
enum {
INTERVAL_RED = 0,
@@ -110,6 +110,15 @@ static struct interval_node *interval_first(struct interval_node *node)
return node;
}
+static struct interval_node *interval_last(struct interval_node *node)
+{
+ if (!node)
+ return NULL;
+ while (node->in_right)
+ node = node->in_right;
+ return node;
+}
+
static struct interval_node *interval_next(struct interval_node *node)
{
if (!node)
@@ -121,6 +130,37 @@ static struct interval_node *interval_next(struct interval_node *node)
return node->in_parent;
}
+static struct interval_node *interval_prev(struct interval_node *node)
+{
+ if (!node)
+ return NULL;
+
+ if (node->in_left)
+ return interval_last(node->in_left);
+
+ while (node->in_parent && node_is_left_child(node))
+ node = node->in_parent;
+
+ return node->in_parent;
+}
+
+enum interval_iter interval_iterate_reverse(struct interval_node *root,
+ interval_callback_t func,
+ void *data)
+{
+ enum interval_iter rc = INTERVAL_ITER_CONT;
+ struct interval_node *node;
+
+ for (node = interval_last(root); node; node = interval_prev(node)) {
+ rc = func(node, data);
+ if (rc == INTERVAL_ITER_STOP)
+ break;
+ }
+
+ return rc;
+}
+EXPORT_SYMBOL(interval_iterate_reverse);
+
static void __rotate_change_maxhigh(struct interval_node *node,
struct interval_node *rotate)
{
diff --git a/drivers/staging/lustre/lustre/ldlm/l_lock.c b/drivers/staging/lustre/lustre/ldlm/l_lock.c
index 3845f38..57fd84e 100644
--- a/drivers/staging/lustre/lustre/ldlm/l_lock.c
+++ b/drivers/staging/lustre/lustre/ldlm/l_lock.c
@@ -31,10 +31,10 @@
*/
#define DEBUG_SUBSYSTEM S_LDLM
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
-#include "../include/lustre_dlm.h"
-#include "../include/lustre_lib.h"
+#include <lustre_dlm.h>
+#include <lustre_lib.h>
/**
* Lock a lock and its resource.
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c b/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c
index 08f97e2..2cc6dc2 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c
@@ -46,12 +46,12 @@
*/
#define DEBUG_SUBSYSTEM S_LDLM
-#include "../../include/linux/libcfs/libcfs.h"
-#include "../include/lustre_dlm.h"
-#include "../include/obd_support.h"
-#include "../include/obd.h"
-#include "../include/obd_class.h"
-#include "../include/lustre_lib.h"
+#include <linux/libcfs/libcfs.h>
+#include <lustre_dlm.h>
+#include <obd_support.h>
+#include <obd.h>
+#include <obd_class.h>
+#include <lustre_lib.h>
#include "ldlm_internal.h"
/* When a lock is cancelled by a client, the KMS may undergo change if this
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
index b7f28b3..d571b8b 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
@@ -52,10 +52,10 @@
#define DEBUG_SUBSYSTEM S_LDLM
-#include "../include/lustre_dlm.h"
-#include "../include/obd_support.h"
-#include "../include/obd_class.h"
-#include "../include/lustre_lib.h"
+#include <lustre_dlm.h>
+#include <obd_support.h>
+#include <obd_class.h>
+#include <lustre_lib.h>
#include <linux/list.h>
#include "ldlm_internal.h"
@@ -90,8 +90,8 @@ ldlm_flocks_overlap(struct ldlm_lock *lock, struct ldlm_lock *new)
static inline void
ldlm_flock_destroy(struct ldlm_lock *lock, enum ldlm_mode mode, __u64 flags)
{
- LDLM_DEBUG(lock, "ldlm_flock_destroy(mode: %d, flags: 0x%llx)",
- mode, flags);
+ LDLM_DEBUG(lock, "%s(mode: %d, flags: 0x%llx)",
+ __func__, mode, flags);
/* Safe to not lock here, since it should be empty anyway */
LASSERT(hlist_unhashed(&lock->l_exp_flock_hash));
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_inodebits.c b/drivers/staging/lustre/lustre/ldlm/ldlm_inodebits.c
index ae37c36..fcb6e44 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_inodebits.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_inodebits.c
@@ -49,9 +49,9 @@
#define DEBUG_SUBSYSTEM S_LDLM
-#include "../include/lustre_dlm.h"
-#include "../include/obd_support.h"
-#include "../include/lustre_lib.h"
+#include <lustre_dlm.h>
+#include <obd_support.h>
+#include <lustre_lib.h>
#include "ldlm_internal.h"
void ldlm_ibits_policy_wire_to_local(const union ldlm_wire_policy_data *wpolicy,
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h b/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h
index ec3b23c..36808db 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h
@@ -106,9 +106,6 @@ int ldlm_cancel_lru_local(struct ldlm_namespace *ns,
extern unsigned int ldlm_enqueue_min;
extern unsigned int ldlm_cancel_unused_locks_before_replay;
-/* ldlm_resource.c */
-int ldlm_resource_putref_locked(struct ldlm_resource *res);
-
/* ldlm_lock.c */
struct ldlm_cb_set_arg {
@@ -336,3 +333,9 @@ void ldlm_flock_policy_wire_to_local(const union ldlm_wire_policy_data *wpolicy,
union ldlm_policy_data *lpolicy);
void ldlm_flock_policy_local_to_wire(const union ldlm_policy_data *lpolicy,
union ldlm_wire_policy_data *wpolicy);
+
+static inline bool ldlm_res_eq(const struct ldlm_res_id *res0,
+ const struct ldlm_res_id *res1)
+{
+ return memcmp(res0, res1, sizeof(*res0)) == 0;
+}
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c
index 4dc7bae..22600c2 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c
@@ -39,12 +39,12 @@
#define DEBUG_SUBSYSTEM S_LDLM
-#include "../../include/linux/libcfs/libcfs.h"
-#include "../include/obd.h"
-#include "../include/obd_class.h"
-#include "../include/lustre_dlm.h"
-#include "../include/lustre_net.h"
-#include "../include/lustre_sec.h"
+#include <linux/libcfs/libcfs.h>
+#include <obd.h>
+#include <obd_class.h>
+#include <lustre_dlm.h>
+#include <lustre_net.h>
+#include <lustre_sec.h>
#include "ldlm_internal.h"
/* @priority: If non-zero, move the selected connection to the list head.
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
index ddb4642..b5d84f3 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
@@ -37,10 +37,10 @@
#define DEBUG_SUBSYSTEM S_LDLM
-#include "../../include/linux/libcfs/libcfs.h"
-#include "../include/lustre_intent.h"
-#include "../include/lustre_swab.h"
-#include "../include/obd_class.h"
+#include <linux/libcfs/libcfs.h>
+#include <lustre_intent.h>
+#include <lustre_swab.h>
+#include <obd_class.h>
#include "ldlm_internal.h"
/* lock types */
@@ -1029,11 +1029,11 @@ void ldlm_grant_lock(struct ldlm_lock *lock, struct list_head *work_list)
if (work_list && lock->l_completion_ast)
ldlm_add_ast_work_item(lock, NULL, work_list);
- if (res->lr_type == LDLM_PLAIN || res->lr_type == LDLM_IBITS)
+ if (res->lr_type == LDLM_PLAIN || res->lr_type == LDLM_IBITS) {
ldlm_grant_lock_with_skiplist(lock);
- else if (res->lr_type == LDLM_EXTENT)
+ } else if (res->lr_type == LDLM_EXTENT) {
ldlm_extent_add_lock(res, lock);
- else if (res->lr_type == LDLM_FLOCK) {
+ } else if (res->lr_type == LDLM_FLOCK) {
/*
* We should not add locks to granted list in the following cases:
* - this is an UNLOCK but not a real lock;
@@ -1045,8 +1045,9 @@ void ldlm_grant_lock(struct ldlm_lock *lock, struct list_head *work_list)
ldlm_is_test_lock(lock) || ldlm_is_flock_deadlock(lock))
return;
ldlm_resource_add_lock(res, &res->lr_granted, lock);
- } else
+ } else {
LBUG();
+ }
ldlm_pool_add(&ldlm_res_to_ns(res)->ns_pool, lock);
}
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c
index fff930f..e270733 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c
@@ -37,9 +37,9 @@
#define DEBUG_SUBSYSTEM S_LDLM
-#include "../../include/linux/libcfs/libcfs.h"
-#include "../include/lustre_dlm.h"
-#include "../include/obd_class.h"
+#include <linux/libcfs/libcfs.h>
+#include <lustre_dlm.h>
+#include <obd_class.h>
#include <linux/list.h>
#include "ldlm_internal.h"
@@ -926,7 +926,7 @@ static struct attribute *ldlm_attrs[] = {
NULL,
};
-static struct attribute_group ldlm_attr_group = {
+static const struct attribute_group ldlm_attr_group = {
.attrs = ldlm_attrs,
};
@@ -1138,7 +1138,7 @@ int ldlm_init(void)
void ldlm_exit(void)
{
if (ldlm_refcount)
- CERROR("ldlm_refcount is %d in ldlm_exit!\n", ldlm_refcount);
+ CERROR("ldlm_refcount is %d in %s!\n", ldlm_refcount, __func__);
kmem_cache_destroy(ldlm_resource_slab);
/* ldlm_lock_put() use RCU to call ldlm_lock_free, so need call
* synchronize_rcu() to wait a grace period elapsed, so that
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_plain.c b/drivers/staging/lustre/lustre/ldlm/ldlm_plain.c
index 862ea0a..1ca605f 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_plain.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_plain.c
@@ -48,9 +48,9 @@
#define DEBUG_SUBSYSTEM S_LDLM
-#include "../include/lustre_dlm.h"
-#include "../include/obd_support.h"
-#include "../include/lustre_lib.h"
+#include <lustre_dlm.h>
+#include <obd_support.h>
+#include <lustre_lib.h>
#include "ldlm_internal.h"
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
index cf3fc57..d77bf0b 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
@@ -94,10 +94,10 @@
#define DEBUG_SUBSYSTEM S_LDLM
-#include "../include/lustre_dlm.h"
-#include "../include/cl_object.h"
-#include "../include/obd_class.h"
-#include "../include/obd_support.h"
+#include <lustre_dlm.h>
+#include <cl_object.h>
+#include <obd_class.h>
+#include <obd_support.h>
#include "ldlm_internal.h"
/*
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
index 4028e11..f3bf238 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
@@ -57,9 +57,10 @@
#define DEBUG_SUBSYSTEM S_LDLM
-#include "../include/lustre_dlm.h"
-#include "../include/obd_class.h"
-#include "../include/obd.h"
+#include <lustre_errno.h>
+#include <lustre_dlm.h>
+#include <obd_class.h>
+#include <obd.h>
#include "ldlm_internal.h"
@@ -83,6 +84,33 @@ struct ldlm_async_args {
struct lustre_handle lock_handle;
};
+/**
+ * ldlm_request_bufsize
+ *
+ * @count: number of ldlm handles
+ * @type: ldlm opcode
+ *
+ * If opcode=LDLM_ENQUEUE, 1 slot is already occupied,
+ * LDLM_LOCKREQ_HANDLE -1 slots are available.
+ * Otherwise, LDLM_LOCKREQ_HANDLE slots are available.
+ *
+ * Return: size of the request buffer
+ */
+static int ldlm_request_bufsize(int count, int type)
+{
+ int avail = LDLM_LOCKREQ_HANDLES;
+
+ if (type == LDLM_ENQUEUE)
+ avail -= LDLM_ENQUEUE_CANCEL_OFF;
+
+ if (count > avail)
+ avail = (count - avail) * sizeof(struct lustre_handle);
+ else
+ avail = 0;
+
+ return sizeof(struct ldlm_request) + avail;
+}
+
static int ldlm_expired_completion_wait(void *data)
{
struct lock_wait_data *lwd = data;
@@ -1635,7 +1663,7 @@ int ldlm_cli_cancel_list(struct list_head *cancels, int count,
if (res < 0) {
CDEBUG_LIMIT(res == -ESHUTDOWN ? D_DLMTRACE : D_ERROR,
- "ldlm_cli_cancel_list: %d\n", res);
+ "%s: %d\n", __func__, res);
res = count;
}
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
index c9ef247..c2ddf73 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
@@ -36,9 +36,9 @@
*/
#define DEBUG_SUBSYSTEM S_LDLM
-#include "../include/lustre_dlm.h"
-#include "../include/lustre_fid.h"
-#include "../include/obd_class.h"
+#include <lustre_dlm.h>
+#include <lustre_fid.h>
+#include <obd_class.h>
#include "ldlm_internal.h"
struct kmem_cache *ldlm_resource_slab, *ldlm_lock_slab;
@@ -223,7 +223,7 @@ static ssize_t lru_size_show(struct kobject *kobj, struct attribute *attr,
if (ns_connect_lru_resize(ns))
nr = &ns->ns_nr_unused;
- return sprintf(buf, "%u", *nr);
+ return sprintf(buf, "%u\n", *nr);
}
static ssize_t lru_size_store(struct kobject *kobj, struct attribute *attr,
@@ -318,7 +318,7 @@ static ssize_t lru_max_age_show(struct kobject *kobj, struct attribute *attr,
struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace,
ns_kobj);
- return sprintf(buf, "%u", ns->ns_max_age);
+ return sprintf(buf, "%u\n", ns->ns_max_age);
}
static ssize_t lru_max_age_store(struct kobject *kobj, struct attribute *attr,
@@ -536,16 +536,6 @@ static void ldlm_res_hop_get_locked(struct cfs_hash *hs,
ldlm_resource_getref(res);
}
-static void ldlm_res_hop_put_locked(struct cfs_hash *hs,
- struct hlist_node *hnode)
-{
- struct ldlm_resource *res;
-
- res = hlist_entry(hnode, struct ldlm_resource, lr_hash);
- /* cfs_hash_for_each_nolock is the only chance we call it */
- ldlm_resource_putref_locked(res);
-}
-
static void ldlm_res_hop_put(struct cfs_hash *hs, struct hlist_node *hnode)
{
struct ldlm_resource *res;
@@ -561,7 +551,6 @@ static struct cfs_hash_ops ldlm_ns_hash_ops = {
.hs_keycpy = NULL,
.hs_object = ldlm_res_hop_object,
.hs_get = ldlm_res_hop_get_locked,
- .hs_put_locked = ldlm_res_hop_put_locked,
.hs_put = ldlm_res_hop_put
};
@@ -572,7 +561,6 @@ static struct cfs_hash_ops ldlm_ns_fid_hash_ops = {
.hs_keycpy = NULL,
.hs_object = ldlm_res_hop_object,
.hs_get = ldlm_res_hop_get_locked,
- .hs_put_locked = ldlm_res_hop_put_locked,
.hs_put = ldlm_res_hop_put
};
@@ -1249,37 +1237,6 @@ int ldlm_resource_putref(struct ldlm_resource *res)
}
EXPORT_SYMBOL(ldlm_resource_putref);
-/* Returns 1 if the resource was freed, 0 if it remains. */
-int ldlm_resource_putref_locked(struct ldlm_resource *res)
-{
- struct ldlm_namespace *ns = ldlm_res_to_ns(res);
-
- LASSERT_ATOMIC_GT_LT(&res->lr_refcount, 0, LI_POISON);
- CDEBUG(D_INFO, "putref res: %p count: %d\n",
- res, atomic_read(&res->lr_refcount) - 1);
-
- if (atomic_dec_and_test(&res->lr_refcount)) {
- struct cfs_hash_bd bd;
-
- cfs_hash_bd_get(ldlm_res_to_ns(res)->ns_rs_hash,
- &res->lr_name, &bd);
- __ldlm_resource_putref_final(&bd, res);
- cfs_hash_bd_unlock(ns->ns_rs_hash, &bd, 1);
- /* NB: ns_rs_hash is created with CFS_HASH_NO_ITEMREF,
- * so we should never be here while calling cfs_hash_del,
- * cfs_hash_for_each_nolock is the only case we can get
- * here, which is safe to release cfs_hash_bd_lock.
- */
- if (ns->ns_lvbo && ns->ns_lvbo->lvbo_free)
- ns->ns_lvbo->lvbo_free(res);
- kmem_cache_free(ldlm_resource_slab, res);
-
- cfs_hash_bd_lock(ns->ns_rs_hash, &bd, 1);
- return 1;
- }
- return 0;
-}
-
/**
* Add a lock into a given resource into specified lock list.
*/
diff --git a/drivers/staging/lustre/lustre/llite/Makefile b/drivers/staging/lustre/lustre/llite/Makefile
index 322d4fa..ef7adef 100644
--- a/drivers/staging/lustre/lustre/llite/Makefile
+++ b/drivers/staging/lustre/lustre/llite/Makefile
@@ -1,3 +1,6 @@
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/include
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/lustre/include
+
obj-$(CONFIG_LUSTRE_FS) += lustre.o
lustre-y := dcache.o dir.o file.o llite_lib.o llite_nfs.o \
rw.o rw26.o namei.o symlink.o llite_mmap.o range_lock.o \
diff --git a/drivers/staging/lustre/lustre/llite/dcache.c b/drivers/staging/lustre/lustre/llite/dcache.c
index d20425f..3670fca 100644
--- a/drivers/staging/lustre/lustre/llite/dcache.c
+++ b/drivers/staging/lustre/lustre/llite/dcache.c
@@ -36,9 +36,9 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include "../include/obd_support.h"
-#include "../include/lustre/lustre_idl.h"
-#include "../include/lustre_dlm.h"
+#include <obd_support.h>
+#include <uapi/linux/lustre/lustre_idl.h>
+#include <lustre_dlm.h>
#include "llite_internal.h"
diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c
index 03a72c0..1db3e7f 100644
--- a/drivers/staging/lustre/lustre/llite/dir.c
+++ b/drivers/staging/lustre/lustre/llite/dir.c
@@ -44,14 +44,14 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include "../include/obd_support.h"
-#include "../include/obd_class.h"
-#include "../include/lustre/lustre_ioctl.h"
-#include "../include/lustre_lib.h"
-#include "../include/lustre_dlm.h"
-#include "../include/lustre_fid.h"
-#include "../include/lustre_kernelcomm.h"
-#include "../include/lustre_swab.h"
+#include <obd_support.h>
+#include <obd_class.h>
+#include <uapi/linux/lustre/lustre_ioctl.h>
+#include <lustre_lib.h>
+#include <lustre_dlm.h>
+#include <lustre_fid.h>
+#include <lustre_kernelcomm.h>
+#include <lustre_swab.h>
#include "llite_internal.h"
@@ -1097,7 +1097,7 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
goto out_free;
}
out_free:
- obd_ioctl_freedata(buf, len);
+ kvfree(buf);
return rc;
}
case LL_IOC_LMV_SETSTRIPE: {
@@ -1147,7 +1147,7 @@ out_free:
#endif
rc = ll_dir_setdirstripe(inode, lum, filename, mode);
lmv_out_free:
- obd_ioctl_freedata(buf, len);
+ kvfree(buf);
return rc;
}
case LL_IOC_LMV_SET_DEFAULT_STRIPE: {
@@ -1626,7 +1626,7 @@ out_quotactl:
rc = ll_migrate(inode, file, mdtidx, filename, namelen - 1);
migrate_free:
- obd_ioctl_freedata(buf, len);
+ kvfree(buf);
return rc;
}
diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c
index ab1c85c..2c30e42 100644
--- a/drivers/staging/lustre/lustre/llite/file.c
+++ b/drivers/staging/lustre/lustre/llite/file.c
@@ -37,16 +37,16 @@
*/
#define DEBUG_SUBSYSTEM S_LLITE
-#include "../include/lustre_dlm.h"
+#include <lustre_dlm.h>
#include <linux/pagemap.h>
#include <linux/file.h>
#include <linux/sched.h>
#include <linux/mount.h>
-#include "../include/lustre/ll_fiemap.h"
-#include "../include/lustre/lustre_ioctl.h"
-#include "../include/lustre_swab.h"
+#include <uapi/linux/lustre/lustre_fiemap.h>
+#include <uapi/linux/lustre/lustre_ioctl.h>
+#include <lustre_swab.h>
-#include "../include/cl_object.h"
+#include <cl_object.h>
#include "llite_internal.h"
static int
@@ -3035,9 +3035,6 @@ struct posix_acl *ll_get_acl(struct inode *inode, int type)
spin_lock(&lli->lli_lock);
/* VFS' acl_permission_check->check_acl will release the refcount */
acl = posix_acl_dup(lli->lli_posix_acl);
-#ifdef CONFIG_FS_POSIX_ACL
- forget_cached_acl(inode, type);
-#endif
spin_unlock(&lli->lli_lock);
return acl;
diff --git a/drivers/staging/lustre/lustre/llite/glimpse.c b/drivers/staging/lustre/lustre/llite/glimpse.c
index 0143112..34c2cfe 100644
--- a/drivers/staging/lustre/lustre/llite/glimpse.c
+++ b/drivers/staging/lustre/lustre/llite/glimpse.c
@@ -36,18 +36,18 @@
* Author: Oleg Drokin <oleg.drokin@sun.com>
*/
-#include "../../include/linux/libcfs/libcfs.h"
-#include "../include/obd_class.h"
-#include "../include/obd_support.h"
-#include "../include/obd.h"
+#include <linux/libcfs/libcfs.h>
+#include <obd_class.h>
+#include <obd_support.h>
+#include <obd.h>
-#include "../include/lustre_dlm.h"
-#include "../include/lustre_mdc.h"
+#include <lustre_dlm.h>
+#include <lustre_mdc.h>
#include <linux/pagemap.h>
#include <linux/file.h>
-#include "../include/cl_object.h"
-#include "../llite/llite_internal.h"
+#include <cl_object.h>
+#include "llite_internal.h"
static const struct cl_lock_descr whole_file = {
.cld_start = 0,
diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
index 96515b8..d2392e4 100644
--- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c
+++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
@@ -37,24 +37,23 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include "../../include/linux/libcfs/libcfs.h"
-# include <linux/fs.h>
-# include <linux/sched.h>
-# include <linux/mm.h>
-# include <linux/quotaops.h>
-# include <linux/highmem.h>
-# include <linux/pagemap.h>
-# include <linux/rbtree.h>
-
-#include "../include/obd.h"
-#include "../include/obd_support.h"
-#include "../include/lustre_fid.h"
-#include "../include/lustre_dlm.h"
-#include "../include/lustre_ver.h"
-#include "../include/lustre_mdc.h"
-#include "../include/cl_object.h"
-
-#include "../llite/llite_internal.h"
+#include <linux/libcfs/libcfs.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/quotaops.h>
+#include <linux/highmem.h>
+#include <linux/pagemap.h>
+#include <linux/rbtree.h>
+
+#include <obd.h>
+#include <obd_support.h>
+#include <lustre_fid.h>
+#include <lustre_dlm.h>
+#include <lustre_mdc.h>
+#include <cl_object.h>
+
+#include "llite_internal.h"
/*
* ccc_ prefix stands for "Common Client Code".
diff --git a/drivers/staging/lustre/lustre/llite/lcommon_misc.c b/drivers/staging/lustre/lustre/llite/lcommon_misc.c
index 7f7f3f1..422f410 100644
--- a/drivers/staging/lustre/lustre/llite/lcommon_misc.c
+++ b/drivers/staging/lustre/lustre/llite/lcommon_misc.c
@@ -34,10 +34,10 @@
*
*/
#define DEBUG_SUBSYSTEM S_LLITE
-#include "../include/obd_class.h"
-#include "../include/obd_support.h"
-#include "../include/obd.h"
-#include "../include/cl_object.h"
+#include <obd_class.h>
+#include <obd_support.h>
+#include <obd.h>
+#include <cl_object.h>
#include "llite_internal.h"
diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h
index cd3311a..0287c75 100644
--- a/drivers/staging/lustre/lustre/llite/llite_internal.h
+++ b/drivers/staging/lustre/lustre/llite/llite_internal.h
@@ -32,18 +32,18 @@
#ifndef LLITE_INTERNAL_H
#define LLITE_INTERNAL_H
-#include "../include/lustre_debug.h"
-#include "../include/lustre_ver.h"
-#include "../include/lustre_disk.h" /* for s2sbi */
-#include "../include/lustre_linkea.h"
+#include <lustre_debug.h>
+#include <uapi/linux/lustre/lustre_ver.h>
+#include <lustre_disk.h> /* for s2sbi */
+#include <lustre_linkea.h>
/* for struct cl_lock_descr and struct cl_io */
-#include "../include/lustre_patchless_compat.h"
-#include "../include/lustre_compat.h"
-#include "../include/cl_object.h"
-#include "../include/lustre_lmv.h"
-#include "../include/lustre_mdc.h"
-#include "../include/lustre_intent.h"
+#include <lustre_patchless_compat.h>
+#include <lustre_compat.h>
+#include <cl_object.h>
+#include <lustre_lmv.h>
+#include <lustre_mdc.h>
+#include <lustre_intent.h>
#include <linux/compat.h>
#include <linux/namei.h>
#include <linux/xattr.h>
diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c
index 974a05d..d855129 100644
--- a/drivers/staging/lustre/lustre/llite/llite_lib.c
+++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
@@ -41,15 +41,15 @@
#include <linux/types.h>
#include <linux/mm.h>
-#include "../include/lustre/lustre_ioctl.h"
-#include "../include/lustre_ha.h"
-#include "../include/lustre_dlm.h"
-#include "../include/lprocfs_status.h"
-#include "../include/lustre_disk.h"
-#include "../include/lustre_param.h"
-#include "../include/lustre_log.h"
-#include "../include/cl_object.h"
-#include "../include/obd_cksum.h"
+#include <uapi/linux/lustre/lustre_ioctl.h>
+#include <lustre_ha.h>
+#include <lustre_dlm.h>
+#include <lprocfs_status.h>
+#include <lustre_disk.h>
+#include <uapi/linux/lustre/lustre_param.h>
+#include <lustre_log.h>
+#include <cl_object.h>
+#include <obd_cksum.h>
#include "llite_internal.h"
struct kmem_cache *ll_file_data_slab;
@@ -222,9 +222,6 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
else
sbi->ll_fop = &ll_file_operations_noflock;
- /* real client */
- data->ocd_connect_flags |= OBD_CONNECT_REAL;
-
/* always ping even if server suppress_pings */
if (sbi->ll_flags & LL_SBI_ALWAYS_PING)
data->ocd_connect_flags &= ~OBD_CONNECT_PINGLESS;
@@ -1319,6 +1316,7 @@ void ll_clear_inode(struct inode *inode)
ll_xattr_cache_destroy(inode);
#ifdef CONFIG_FS_POSIX_ACL
+ forget_all_cached_acls(inode);
if (lli->lli_posix_acl) {
posix_acl_release(lli->lli_posix_acl);
lli->lli_posix_acl = NULL;
@@ -2233,8 +2231,7 @@ int ll_obd_statfs(struct inode *inode, void __user *arg)
if (rc)
goto out_statfs;
out_statfs:
- if (buf)
- obd_ioctl_freedata(buf, len);
+ kvfree(buf);
return rc;
}
@@ -2543,7 +2540,7 @@ static int ll_linkea_decode(struct linkea_data *ldata, unsigned int linkno,
unsigned int idx;
int rc;
- rc = linkea_init(ldata);
+ rc = linkea_init_with_rec(ldata);
if (rc < 0)
return rc;
diff --git a/drivers/staging/lustre/lustre/llite/lproc_llite.c b/drivers/staging/lustre/lustre/llite/lproc_llite.c
index aeae667..e3bd2d1 100644
--- a/drivers/staging/lustre/lustre/llite/lproc_llite.c
+++ b/drivers/staging/lustre/lustre/llite/lproc_llite.c
@@ -31,9 +31,9 @@
*/
#define DEBUG_SUBSYSTEM S_LLITE
-#include "../include/lprocfs_status.h"
+#include <lprocfs_status.h>
#include <linux/seq_file.h>
-#include "../include/obd_support.h"
+#include <obd_support.h>
#include "llite_internal.h"
#include "vvp_internal.h"
diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c
index a208a8b..4897dbd 100644
--- a/drivers/staging/lustre/lustre/llite/namei.c
+++ b/drivers/staging/lustre/lustre/llite/namei.c
@@ -40,10 +40,9 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include "../include/obd_support.h"
-#include "../include/lustre_fid.h"
-#include "../include/lustre_dlm.h"
-#include "../include/lustre_ver.h"
+#include <obd_support.h>
+#include <lustre_fid.h>
+#include <lustre_dlm.h>
#include "llite_internal.h"
static int ll_create_it(struct inode *dir, struct dentry *dentry,
@@ -490,7 +489,7 @@ static int ll_lookup_it_finish(struct ptlrpc_request *request,
*de = alias;
if (!it_disposition(it, DISP_LOOKUP_NEG)) {
- /* we have lookup look - unhide dentry */
+ /* We have the "lookup" lock, so unhide dentry */
if (bits & MDS_INODELOCK_LOOKUP)
d_lustre_revalidate(*de);
} else if (!it_disposition(it, DISP_OPEN_CREATE)) {
diff --git a/drivers/staging/lustre/lustre/llite/range_lock.c b/drivers/staging/lustre/lustre/llite/range_lock.c
index 161391b..a32598b 100644
--- a/drivers/staging/lustre/lustre/llite/range_lock.c
+++ b/drivers/staging/lustre/lustre/llite/range_lock.c
@@ -34,7 +34,7 @@
* Author: Bobi Jam <bobijam.xu@intel.com>
*/
#include "range_lock.h"
-#include "../include/lustre/lustre_user.h"
+#include <uapi/linux/lustre/lustre_idl.h>
/**
* Initialize a range lock tree
diff --git a/drivers/staging/lustre/lustre/llite/range_lock.h b/drivers/staging/lustre/lustre/llite/range_lock.h
index 779091c..1e1519b 100644
--- a/drivers/staging/lustre/lustre/llite/range_lock.h
+++ b/drivers/staging/lustre/lustre/llite/range_lock.h
@@ -36,8 +36,8 @@
#ifndef _RANGE_LOCK_H
#define _RANGE_LOCK_H
-#include "../../include/linux/libcfs/libcfs.h"
-#include "../include/interval_tree.h"
+#include <linux/libcfs/libcfs.h>
+#include <interval_tree.h>
struct range_lock {
struct interval_node rl_node;
diff --git a/drivers/staging/lustre/lustre/llite/rw.c b/drivers/staging/lustre/lustre/llite/rw.c
index 1bac51f..e720905 100644
--- a/drivers/staging/lustre/lustre/llite/rw.c
+++ b/drivers/staging/lustre/lustre/llite/rw.c
@@ -51,7 +51,7 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include "../include/obd_cksum.h"
+#include <obd_cksum.h>
#include "llite_internal.h"
static void ll_ra_stats_inc_sbi(struct ll_sb_info *sbi, enum ra_stat which);
@@ -115,7 +115,7 @@ void ll_ra_count_put(struct ll_sb_info *sbi, unsigned long len)
static void ll_ra_stats_inc_sbi(struct ll_sb_info *sbi, enum ra_stat which)
{
- LASSERTF(which >= 0 && which < _NR_RA_STAT, "which: %u\n", which);
+ LASSERTF(which < _NR_RA_STAT, "which: %u\n", which);
lprocfs_counter_incr(sbi->ll_ra_stats, which);
}
diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c
index 9bbca01..ea9d59f 100644
--- a/drivers/staging/lustre/lustre/llite/statahead.c
+++ b/drivers/staging/lustre/lustre/llite/statahead.c
@@ -38,8 +38,8 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include "../include/obd_support.h"
-#include "../include/lustre_dlm.h"
+#include <obd_support.h>
+#include <lustre_dlm.h>
#include "llite_internal.h"
#define SA_OMITTED_ENTRY_MAX 8ULL
diff --git a/drivers/staging/lustre/lustre/llite/super25.c b/drivers/staging/lustre/lustre/llite/super25.c
index 56f4b10..0da4af8 100644
--- a/drivers/staging/lustre/lustre/llite/super25.c
+++ b/drivers/staging/lustre/lustre/llite/super25.c
@@ -34,11 +34,11 @@
#include <linux/module.h>
#include <linux/types.h>
-#include "../include/lustre_ha.h"
-#include "../include/lustre_dlm.h"
+#include <lustre_ha.h>
+#include <lustre_dlm.h>
#include <linux/init.h>
#include <linux/fs.h>
-#include "../include/lprocfs_status.h"
+#include <lprocfs_status.h>
#include "llite_internal.h"
static struct kmem_cache *ll_inode_cachep;
diff --git a/drivers/staging/lustre/lustre/llite/vvp_dev.c b/drivers/staging/lustre/lustre/llite/vvp_dev.c
index 8e45672..f9d9a16 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_dev.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_dev.c
@@ -37,7 +37,7 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include "../include/obd.h"
+#include <obd.h>
#include "llite_internal.h"
#include "vvp_internal.h"
@@ -591,9 +591,10 @@ static void *vvp_pgcache_start(struct seq_file *f, loff_t *pos)
env = cl_env_get(&refcheck);
if (!IS_ERR(env)) {
sbi = f->private;
- if (sbi->ll_site->ls_obj_hash->hs_cur_bits > 64 - PGC_OBJ_SHIFT)
+ if (sbi->ll_site->ls_obj_hash->hs_cur_bits >
+ 64 - PGC_OBJ_SHIFT) {
pos = ERR_PTR(-EFBIG);
- else {
+ } else {
*pos = vvp_pgcache_find(env, &sbi->ll_cl->cd_lu_dev,
*pos);
if (*pos == ~0ULL)
diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h b/drivers/staging/lustre/lustre/llite/vvp_internal.h
index f40fd7f..adce0ff 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_internal.h
+++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h
@@ -37,8 +37,8 @@
#ifndef VVP_INTERNAL_H
#define VVP_INTERNAL_H
-#include "../include/lustre/lustre_idl.h"
-#include "../include/cl_object.h"
+#include <uapi/linux/lustre/lustre_idl.h>
+#include <cl_object.h>
enum obd_notify_event;
struct inode;
diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c
index c5ba265..c83853f 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_io.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_io.c
@@ -37,7 +37,7 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include "../include/obd.h"
+#include <obd.h>
#include "llite_internal.h"
#include "vvp_internal.h"
diff --git a/drivers/staging/lustre/lustre/llite/vvp_lock.c b/drivers/staging/lustre/lustre/llite/vvp_lock.c
index 07eb26c..e522f7c 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_lock.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_lock.c
@@ -36,7 +36,7 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include "../include/obd_support.h"
+#include <obd_support.h>
#include "vvp_internal.h"
diff --git a/drivers/staging/lustre/lustre/llite/vvp_object.c b/drivers/staging/lustre/lustre/llite/vvp_object.c
index 9bfd72e..3953750 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_object.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_object.c
@@ -36,9 +36,9 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
-#include "../include/obd.h"
+#include <obd.h>
#include "llite_internal.h"
#include "vvp_internal.h"
diff --git a/drivers/staging/lustre/lustre/llite/xattr.c b/drivers/staging/lustre/lustre/llite/xattr.c
index bd30abd..0be5562 100644
--- a/drivers/staging/lustre/lustre/llite/xattr.c
+++ b/drivers/staging/lustre/lustre/llite/xattr.c
@@ -33,13 +33,13 @@
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/mm.h>
+#include <linux/xattr.h>
#include <linux/selinux.h>
#define DEBUG_SUBSYSTEM S_LLITE
-#include "../include/obd_support.h"
-#include "../include/lustre_dlm.h"
-#include "../include/lustre_ver.h"
+#include <obd_support.h>
+#include <lustre_dlm.h>
#include "llite_internal.h"
diff --git a/drivers/staging/lustre/lustre/llite/xattr_cache.c b/drivers/staging/lustre/lustre/llite/xattr_cache.c
index 82cf421..80ee392 100644
--- a/drivers/staging/lustre/lustre/llite/xattr_cache.c
+++ b/drivers/staging/lustre/lustre/llite/xattr_cache.c
@@ -12,9 +12,8 @@
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/mm.h>
-#include "../include/obd_support.h"
-#include "../include/lustre_dlm.h"
-#include "../include/lustre_ver.h"
+#include <obd_support.h>
+#include <lustre_dlm.h>
#include "llite_internal.h"
/* If we ever have hundreds of extended attributes, we might want to consider
diff --git a/drivers/staging/lustre/lustre/llite/xattr_security.c b/drivers/staging/lustre/lustre/llite/xattr_security.c
index d61d801..391fb25 100644
--- a/drivers/staging/lustre/lustre/llite/xattr_security.c
+++ b/drivers/staging/lustre/lustre/llite/xattr_security.c
@@ -28,7 +28,10 @@
* lustre/llite/xattr_security.c
* Handler for storing security labels as extended attributes.
*/
+
+#include <linux/types.h>
#include <linux/security.h>
+#include <linux/selinux.h>
#include <linux/xattr.h>
#include "llite_internal.h"
@@ -48,19 +51,23 @@ static int
ll_initxattrs(struct inode *inode, const struct xattr *xattr_array,
void *fs_info)
{
- const struct xattr_handler *handler;
struct dentry *dentry = fs_info;
const struct xattr *xattr;
int err = 0;
- handler = get_xattr_type(XATTR_SECURITY_PREFIX);
- if (!handler)
- return -ENXIO;
-
for (xattr = xattr_array; xattr->name; xattr++) {
- err = handler->set(handler, dentry, inode, xattr->name,
- xattr->value, xattr->value_len,
- XATTR_CREATE);
+ char *full_name;
+
+ full_name = kasprintf(GFP_KERNEL, "%s%s",
+ XATTR_SECURITY_PREFIX, xattr->name);
+ if (!full_name) {
+ err = -ENOMEM;
+ break;
+ }
+
+ err = __vfs_setxattr(dentry, inode, full_name, xattr->value,
+ xattr->value_len, XATTR_CREATE);
+ kfree(full_name);
if (err < 0)
break;
}
diff --git a/drivers/staging/lustre/lustre/lmv/Makefile b/drivers/staging/lustre/lustre/lmv/Makefile
index 1a24299..91c9911 100644
--- a/drivers/staging/lustre/lustre/lmv/Makefile
+++ b/drivers/staging/lustre/lustre/lmv/Makefile
@@ -1,2 +1,5 @@
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/include
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/lustre/include
+
obj-$(CONFIG_LUSTRE_FS) += lmv.o
lmv-y := lmv_obd.o lmv_intent.o lmv_fld.o lproc_lmv.o
diff --git a/drivers/staging/lustre/lustre/lmv/lmv_fld.c b/drivers/staging/lustre/lustre/lmv/lmv_fld.c
index 6f8070f..5937468 100644
--- a/drivers/staging/lustre/lustre/lmv/lmv_fld.c
+++ b/drivers/staging/lustre/lustre/lmv/lmv_fld.c
@@ -37,14 +37,13 @@
#include <asm/div64.h>
#include <linux/seq_file.h>
-#include "../include/obd_support.h"
-#include "../include/lustre/lustre_idl.h"
-#include "../include/lustre_fid.h"
-#include "../include/lustre_lib.h"
-#include "../include/lustre_net.h"
-#include "../include/lustre_dlm.h"
-#include "../include/obd_class.h"
-#include "../include/lprocfs_status.h"
+#include <obd_support.h>
+#include <lustre_fid.h>
+#include <lustre_lib.h>
+#include <lustre_net.h>
+#include <lustre_dlm.h>
+#include <obd_class.h>
+#include <lprocfs_status.h>
#include "lmv_internal.h"
int lmv_fld_lookup(struct lmv_obd *lmv, const struct lu_fid *fid, u32 *mds)
diff --git a/drivers/staging/lustre/lustre/lmv/lmv_intent.c b/drivers/staging/lustre/lustre/lmv/lmv_intent.c
index f49db6c..22c247a 100644
--- a/drivers/staging/lustre/lustre/lmv/lmv_intent.c
+++ b/drivers/staging/lustre/lustre/lmv/lmv_intent.c
@@ -37,15 +37,14 @@
#include <asm/div64.h>
#include <linux/seq_file.h>
#include <linux/namei.h>
-#include "../include/lustre_intent.h"
-#include "../include/obd_support.h"
-#include "../include/lustre/lustre_idl.h"
-#include "../include/lustre_lib.h"
-#include "../include/lustre_net.h"
-#include "../include/lustre_dlm.h"
-#include "../include/lustre_mdc.h"
-#include "../include/obd_class.h"
-#include "../include/lprocfs_status.h"
+#include <lustre_intent.h>
+#include <obd_support.h>
+#include <lustre_lib.h>
+#include <lustre_net.h>
+#include <lustre_dlm.h>
+#include <lustre_mdc.h>
+#include <obd_class.h>
+#include <lprocfs_status.h>
#include "lmv_internal.h"
static int lmv_intent_remote(struct obd_export *exp, struct lookup_intent *it,
@@ -474,7 +473,6 @@ int lmv_intent_lock(struct obd_export *exp, struct md_op_data *op_data,
ldlm_blocking_callback cb_blocking,
__u64 extra_lock_flags)
{
- struct obd_device *obd = exp->exp_obd;
int rc;
LASSERT(fid_is_sane(&op_data->op_fid1));
@@ -484,10 +482,6 @@ int lmv_intent_lock(struct obd_export *exp, struct md_op_data *op_data,
(int)op_data->op_namelen, op_data->op_name,
PFID(&op_data->op_fid1));
- rc = lmv_check_connect(obd);
- if (rc)
- return rc;
-
if (it->it_op & (IT_LOOKUP | IT_GETATTR | IT_LAYOUT))
rc = lmv_intent_lookup(exp, op_data, it, reqp, cb_blocking,
extra_lock_flags);
diff --git a/drivers/staging/lustre/lustre/lmv/lmv_internal.h b/drivers/staging/lustre/lustre/lmv/lmv_internal.h
index 12731a17..a047523 100644
--- a/drivers/staging/lustre/lustre/lmv/lmv_internal.h
+++ b/drivers/staging/lustre/lustre/lmv/lmv_internal.h
@@ -33,17 +33,15 @@
#ifndef _LMV_INTERNAL_H_
#define _LMV_INTERNAL_H_
-#include "../include/lustre/lustre_idl.h"
-#include "../include/obd.h"
-#include "../include/lustre_lmv.h"
+#include <uapi/linux/lustre/lustre_idl.h>
+#include <obd.h>
+#include <lustre_lmv.h>
#define LMV_MAX_TGT_COUNT 128
#define LL_IT2STR(it) \
((it) ? ldlm_it2str((it)->it_op) : "0")
-int lmv_check_connect(struct obd_device *obd);
-
int lmv_intent_lock(struct obd_export *exp, struct md_op_data *op_data,
struct lookup_intent *it, struct ptlrpc_request **reqp,
ldlm_blocking_callback cb_blocking,
diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c
index 64fcaef..6e16c93 100644
--- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c
+++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c
@@ -41,18 +41,19 @@
#include <linux/namei.h>
#include <linux/uaccess.h>
-#include "../include/lustre/lustre_idl.h"
-#include "../include/obd_support.h"
-#include "../include/lustre_net.h"
-#include "../include/obd_class.h"
-#include "../include/lustre_lmv.h"
-#include "../include/lprocfs_status.h"
-#include "../include/cl_object.h"
-#include "../include/lustre_fid.h"
-#include "../include/lustre/lustre_ioctl.h"
-#include "../include/lustre_kernelcomm.h"
+#include <obd_support.h>
+#include <lustre_net.h>
+#include <obd_class.h>
+#include <lustre_lmv.h>
+#include <lprocfs_status.h>
+#include <cl_object.h>
+#include <lustre_fid.h>
+#include <uapi/linux/lustre/lustre_ioctl.h>
+#include <lustre_kernelcomm.h>
#include "lmv_internal.h"
+static int lmv_check_connect(struct obd_device *obd);
+
static void lmv_activate_target(struct lmv_obd *lmv,
struct lmv_tgt_desc *tgt,
int activate)
@@ -183,59 +184,44 @@ static int lmv_notify(struct obd_device *obd, struct obd_device *watched,
return rc;
}
-/**
- * This is fake connect function. Its purpose is to initialize lmv and say
- * caller that everything is okay. Real connection will be performed later.
- */
static int lmv_connect(const struct lu_env *env,
- struct obd_export **exp, struct obd_device *obd,
+ struct obd_export **pexp, struct obd_device *obd,
struct obd_uuid *cluuid, struct obd_connect_data *data,
void *localdata)
{
struct lmv_obd *lmv = &obd->u.lmv;
struct lustre_handle conn = { 0 };
+ struct obd_export *exp;
int rc = 0;
- /*
- * We don't want to actually do the underlying connections more than
- * once, so keep track.
- */
- lmv->refcount++;
- if (lmv->refcount > 1) {
- *exp = NULL;
- return 0;
- }
-
rc = class_connect(&conn, obd, cluuid);
if (rc) {
CERROR("class_connection() returned %d\n", rc);
return rc;
}
- *exp = class_conn2export(&conn);
- class_export_get(*exp);
+ exp = class_conn2export(&conn);
- lmv->exp = *exp;
lmv->connected = 0;
lmv->cluuid = *cluuid;
-
- if (data)
- lmv->conn_data = *data;
+ lmv->conn_data = *data;
lmv->lmv_tgts_kobj = kobject_create_and_add("target_obds",
&obd->obd_kobj);
- /*
- * All real clients should perform actual connection right away, because
- * it is possible, that LMV will not have opportunity to connect targets
- * and MDC stuff will be called directly, for instance while reading
- * ../mdc/../kbytesfree procfs file, etc.
- */
- if (data && data->ocd_connect_flags & OBD_CONNECT_REAL)
- rc = lmv_check_connect(obd);
+ rc = lmv_check_connect(obd);
+ if (rc)
+ goto out_sysfs;
+
+ *pexp = exp;
- if (rc && lmv->lmv_tgts_kobj)
+ return rc;
+
+out_sysfs:
+ if (lmv->lmv_tgts_kobj)
kobject_put(lmv->lmv_tgts_kobj);
+ class_disconnect(exp);
+
return rc;
}
@@ -475,7 +461,7 @@ static int lmv_add_target(struct obd_device *obd, struct obd_uuid *uuidp,
return rc;
}
-int lmv_check_connect(struct obd_device *obd)
+static int lmv_check_connect(struct obd_device *obd)
{
struct lmv_obd *lmv = &obd->u.lmv;
struct lmv_tgt_desc *tgt;
@@ -519,7 +505,6 @@ int lmv_check_connect(struct obd_device *obd)
goto out_disc;
}
- class_export_put(lmv->exp);
lmv->connected = 1;
easize = lmv_mds_md_size(lmv->desc.ld_tgt_count, LMV_MAGIC);
lmv_init_ea_size(obd->obd_self_export, easize, 0);
@@ -543,7 +528,7 @@ int lmv_check_connect(struct obd_device *obd)
}
}
}
- class_disconnect(lmv->exp);
+
mutex_unlock(&lmv->lmv_init_mutex);
return rc;
}
@@ -598,13 +583,6 @@ static int lmv_disconnect(struct obd_export *exp)
if (!lmv->tgts)
goto out_local;
- /*
- * Only disconnect the underlying layers on the final disconnect.
- */
- lmv->refcount--;
- if (lmv->refcount != 0)
- goto out_local;
-
for (i = 0; i < lmv->desc.ld_tgt_count; i++) {
if (!lmv->tgts[i] || !lmv->tgts[i]->ltd_exp)
continue;
@@ -623,8 +601,7 @@ out_local:
if (!lmv->connected)
class_export_put(exp);
rc = class_disconnect(exp);
- if (lmv->refcount == 0)
- lmv->connected = 0;
+ lmv->connected = 0;
return rc;
}
@@ -657,8 +634,8 @@ repeat_fid2path:
char *ptr;
ori_gf = karg;
- if (strlen(ori_gf->gf_path) +
- strlen(gf->gf_path) > ori_gf->gf_pathlen) {
+ if (strlen(ori_gf->gf_path) + 1 +
+ strlen(gf->gf_path) + 1 > ori_gf->gf_pathlen) {
rc = -EOVERFLOW;
goto out_fid2path;
}
@@ -1122,7 +1099,8 @@ hsm_req_err:
err = obd_iocontrol(cmd, tgt->ltd_exp, len, karg, uarg);
if (err) {
if (tgt->ltd_active) {
- CERROR("error: iocontrol MDC %s on MDTidx %d cmd %x: err = %d\n",
+ CERROR("%s: error: iocontrol MDC %s on MDTidx %d cmd %x: err = %d\n",
+ lmv2obd_dev(lmv)->obd_name,
tgt->ltd_uuid.uuid, i, cmd, err);
if (!rc)
rc = err;
@@ -1368,10 +1346,6 @@ static int lmv_statfs(const struct lu_env *env, struct obd_export *exp,
int rc = 0;
u32 i;
- rc = lmv_check_connect(obd);
- if (rc)
- return rc;
-
temp = kzalloc(sizeof(*temp), GFP_NOFS);
if (!temp)
return -ENOMEM;
@@ -1418,11 +1392,6 @@ static int lmv_getstatus(struct obd_export *exp,
{
struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv;
- int rc;
-
- rc = lmv_check_connect(obd);
- if (rc)
- return rc;
return md_getstatus(lmv->tgts[0]->ltd_exp, fid);
}
@@ -1435,11 +1404,6 @@ static int lmv_getxattr(struct obd_export *exp, const struct lu_fid *fid,
struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv;
struct lmv_tgt_desc *tgt;
- int rc;
-
- rc = lmv_check_connect(obd);
- if (rc)
- return rc;
tgt = lmv_find_target(lmv, fid);
if (IS_ERR(tgt))
@@ -1458,11 +1422,6 @@ static int lmv_setxattr(struct obd_export *exp, const struct lu_fid *fid,
struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv;
struct lmv_tgt_desc *tgt;
- int rc;
-
- rc = lmv_check_connect(obd);
- if (rc)
- return rc;
tgt = lmv_find_target(lmv, fid);
if (IS_ERR(tgt))
@@ -1479,11 +1438,6 @@ static int lmv_getattr(struct obd_export *exp, struct md_op_data *op_data,
struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv;
struct lmv_tgt_desc *tgt;
- int rc;
-
- rc = lmv_check_connect(obd);
- if (rc)
- return rc;
tgt = lmv_find_target(lmv, &op_data->op_fid1);
if (IS_ERR(tgt))
@@ -1502,11 +1456,6 @@ static int lmv_null_inode(struct obd_export *exp, const struct lu_fid *fid)
struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv;
u32 i;
- int rc;
-
- rc = lmv_check_connect(obd);
- if (rc)
- return rc;
CDEBUG(D_INODE, "CBDATA for " DFID "\n", PFID(fid));
@@ -1530,11 +1479,6 @@ static int lmv_close(struct obd_export *exp, struct md_op_data *op_data,
struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv;
struct lmv_tgt_desc *tgt;
- int rc;
-
- rc = lmv_check_connect(obd);
- if (rc)
- return rc;
tgt = lmv_find_target(lmv, &op_data->op_fid1);
if (IS_ERR(tgt))
@@ -1661,10 +1605,6 @@ static int lmv_create(struct obd_export *exp, struct md_op_data *op_data,
struct lmv_tgt_desc *tgt;
int rc;
- rc = lmv_check_connect(obd);
- if (rc)
- return rc;
-
if (!lmv->desc.ld_active_tgt_count)
return -EIO;
@@ -1718,11 +1658,6 @@ lmv_enqueue(struct obd_export *exp, struct ldlm_enqueue_info *einfo,
struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv;
struct lmv_tgt_desc *tgt;
- int rc;
-
- rc = lmv_check_connect(obd);
- if (rc)
- return rc;
CDEBUG(D_INODE, "ENQUEUE '%s' on " DFID "\n",
LL_IT2STR(it), PFID(&op_data->op_fid1));
@@ -1749,10 +1684,6 @@ lmv_getattr_name(struct obd_export *exp, struct md_op_data *op_data,
struct mdt_body *body;
int rc;
- rc = lmv_check_connect(obd);
- if (rc)
- return rc;
-
tgt = lmv_locate_mds(lmv, op_data, &op_data->op_fid1);
if (IS_ERR(tgt))
return PTR_ERR(tgt);
@@ -1845,10 +1776,6 @@ static int lmv_link(struct obd_export *exp, struct md_op_data *op_data,
struct lmv_tgt_desc *tgt;
int rc;
- rc = lmv_check_connect(obd);
- if (rc)
- return rc;
-
LASSERT(op_data->op_namelen != 0);
CDEBUG(D_INODE, "LINK " DFID ":%*s to " DFID "\n",
@@ -1907,10 +1834,6 @@ static int lmv_rename(struct obd_export *exp, struct md_op_data *op_data,
(int)newlen, new, PFID(&op_data->op_fid2),
op_data->op_mea2 ? op_data->op_mea2->lsm_md_stripe_count : 0);
- rc = lmv_check_connect(obd);
- if (rc)
- return rc;
-
op_data->op_fsuid = from_kuid(&init_user_ns, current_fsuid());
op_data->op_fsgid = from_kgid(&init_user_ns, current_fsgid());
op_data->op_cap = cfs_curproc_cap_pack();
@@ -2063,11 +1986,6 @@ static int lmv_setattr(struct obd_export *exp, struct md_op_data *op_data,
struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv;
struct lmv_tgt_desc *tgt;
- int rc;
-
- rc = lmv_check_connect(obd);
- if (rc)
- return rc;
CDEBUG(D_INODE, "SETATTR for " DFID ", valid 0x%x\n",
PFID(&op_data->op_fid1), op_data->op_attr.ia_valid);
@@ -2086,11 +2004,6 @@ static int lmv_sync(struct obd_export *exp, const struct lu_fid *fid,
struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv;
struct lmv_tgt_desc *tgt;
- int rc;
-
- rc = lmv_check_connect(obd);
- if (rc)
- return rc;
tgt = lmv_find_target(lmv, fid);
if (IS_ERR(tgt))
@@ -2272,7 +2185,6 @@ static int lmv_read_striped_page(struct obd_export *exp,
{
struct inode *master_inode = op_data->op_data;
struct lu_fid master_fid = op_data->op_fid1;
- struct obd_device *obd = exp->exp_obd;
__u64 hash_offset = offset;
__u32 ldp_flags;
struct page *min_ent_page = NULL;
@@ -2286,10 +2198,6 @@ static int lmv_read_striped_page(struct obd_export *exp,
void *area;
int rc;
- rc = lmv_check_connect(obd);
- if (rc)
- return rc;
-
/*
* Allocate a page and read entries from all of stripes and fill
* the page by hash order
@@ -2408,11 +2316,6 @@ static int lmv_read_page(struct obd_export *exp, struct md_op_data *op_data,
struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv;
struct lmv_tgt_desc *tgt;
- int rc;
-
- rc = lmv_check_connect(obd);
- if (rc)
- return rc;
if (unlikely(lsm))
return lmv_read_striped_page(exp, op_data, cb_op, offset, ppage);
@@ -2460,9 +2363,6 @@ static int lmv_unlink(struct obd_export *exp, struct md_op_data *op_data,
int stripe_index = 0;
int rc;
- rc = lmv_check_connect(obd);
- if (rc)
- return rc;
retry_unlink:
/* For striped dir, we need to locate the parent as well */
if (lsm) {
@@ -2647,10 +2547,6 @@ static int lmv_get_info(const struct lu_env *env, struct obd_export *exp,
if (keylen >= strlen("remote_flag") && !strcmp(key, "remote_flag")) {
int i;
- rc = lmv_check_connect(obd);
- if (rc)
- return rc;
-
LASSERT(*vallen == sizeof(__u32));
for (i = 0; i < lmv->desc.ld_tgt_count; i++) {
struct lmv_tgt_desc *tgt = lmv->tgts[i];
@@ -2669,10 +2565,6 @@ static int lmv_get_info(const struct lu_env *env, struct obd_export *exp,
} else if (KEY_IS(KEY_MAX_EASIZE) ||
KEY_IS(KEY_DEFAULT_EASIZE) ||
KEY_IS(KEY_CONN_DATA)) {
- rc = lmv_check_connect(obd);
- if (rc)
- return rc;
-
/*
* Forwarding this request to first MDS, it should know LOV
* desc.
@@ -3021,15 +2913,10 @@ static int lmv_intent_getattr_async(struct obd_export *exp,
struct lmv_obd *lmv = &obd->u.lmv;
struct lmv_tgt_desc *ptgt = NULL;
struct lmv_tgt_desc *ctgt = NULL;
- int rc;
if (!fid_is_sane(&op_data->op_fid2))
return -EINVAL;
- rc = lmv_check_connect(obd);
- if (rc)
- return rc;
-
ptgt = lmv_locate_mds(lmv, op_data, &op_data->op_fid1);
if (IS_ERR(ptgt))
return PTR_ERR(ptgt);
@@ -3056,11 +2943,6 @@ static int lmv_revalidate_lock(struct obd_export *exp, struct lookup_intent *it,
struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv;
struct lmv_tgt_desc *tgt;
- int rc;
-
- rc = lmv_check_connect(obd);
- if (rc)
- return rc;
tgt = lmv_find_target(lmv, fid);
if (IS_ERR(tgt))
diff --git a/drivers/staging/lustre/lustre/lmv/lproc_lmv.c b/drivers/staging/lustre/lustre/lmv/lproc_lmv.c
index bf25f88..f16cfa4 100644
--- a/drivers/staging/lustre/lustre/lmv/lproc_lmv.c
+++ b/drivers/staging/lustre/lustre/lmv/lproc_lmv.c
@@ -34,8 +34,8 @@
#include <linux/seq_file.h>
#include <linux/statfs.h>
-#include "../include/lprocfs_status.h"
-#include "../include/obd_class.h"
+#include <lprocfs_status.h>
+#include <obd_class.h>
#include "lmv_internal.h"
static ssize_t numobd_show(struct kobject *kobj, struct attribute *attr,
@@ -161,7 +161,7 @@ static struct attribute *lmv_attrs[] = {
NULL,
};
-static struct attribute_group lmv_attr_group = {
+static const struct attribute_group lmv_attr_group = {
.attrs = lmv_attrs,
};
diff --git a/drivers/staging/lustre/lustre/lov/Makefile b/drivers/staging/lustre/lustre/lov/Makefile
index e4cc0db..3abfb4e 100644
--- a/drivers/staging/lustre/lustre/lov/Makefile
+++ b/drivers/staging/lustre/lustre/lov/Makefile
@@ -1,5 +1,8 @@
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/include
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/lustre/include
+
obj-$(CONFIG_LUSTRE_FS) += lov.o
lov-y := lov_obd.o lov_pack.o lov_offset.o lov_merge.o \
lov_request.o lov_ea.o lov_dev.o lov_object.o lov_page.o \
lov_lock.o lov_io.o lovsub_dev.o lovsub_object.o lovsub_page.o \
- lovsub_lock.o lovsub_io.o lov_pool.o lproc_lov.o
+ lovsub_lock.o lov_pool.o lproc_lov.o
diff --git a/drivers/staging/lustre/lustre/lov/lov_cl_internal.h b/drivers/staging/lustre/lustre/lov/lov_cl_internal.h
index e889d3a..89d92b0 100644
--- a/drivers/staging/lustre/lustre/lov/lov_cl_internal.h
+++ b/drivers/staging/lustre/lustre/lov/lov_cl_internal.h
@@ -42,10 +42,10 @@
#ifndef LOV_CL_INTERNAL_H
#define LOV_CL_INTERNAL_H
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
-#include "../include/obd.h"
-#include "../include/cl_object.h"
+#include <obd.h>
+#include <cl_object.h>
#include "lov_internal.h"
/** \defgroup lov lov
@@ -92,35 +92,6 @@ enum lov_device_flags {
* Upper half.
*/
-/**
- * Resources that are used in memory-cleaning path, and whose allocation
- * cannot fail even when memory is tight. They are preallocated in sufficient
- * quantities in lov_device::ld_emerg[], and access to them is serialized
- * lov_device::ld_mutex.
- */
-struct lov_device_emerg {
- /**
- * Page list used to submit IO when memory is in pressure.
- */
- struct cl_page_list emrg_page_list;
- /**
- * sub-io's shared by all threads accessing this device when memory is
- * too low to allocate sub-io's dynamically.
- */
- struct cl_io emrg_subio;
- /**
- * Environments used by sub-io's in
- * lov_device_emerg::emrg_subio.
- */
- struct lu_env *emrg_env;
- /**
- * Refchecks for lov_device_emerg::emrg_env.
- *
- * \see cl_env_get()
- */
- u16 emrg_refcheck;
-};
-
struct lov_device {
/*
* XXX Locking of lov-private data is missing.
@@ -131,14 +102,6 @@ struct lov_device {
__u32 ld_target_nr;
struct lovsub_device **ld_target;
__u32 ld_flags;
-
- /** Emergency resources used in memory-cleansing paths. */
- struct lov_device_emerg **ld_emrg;
- /**
- * Serializes access to lov_device::ld_emrg in low-memory
- * conditions.
- */
- struct mutex ld_mutex;
};
/**
@@ -299,8 +262,6 @@ struct lov_page {
struct lovsub_device {
struct cl_device acid_cl;
- struct lov_device *acid_super;
- int acid_idx;
struct cl_device *acid_next;
};
@@ -312,42 +273,10 @@ struct lovsub_object {
};
/**
- * A link between a top-lock and a sub-lock. Separate data-structure is
- * necessary, because top-locks and sub-locks are in M:N relationship.
- *
- * \todo This can be optimized for a (by far) most frequent case of a single
- * top-lock per sub-lock.
- */
-struct lov_lock_link {
- struct lov_lock *lll_super;
- /** An index within parent lock. */
- int lll_idx;
- /**
- * A linkage into per sub-lock list of all corresponding top-locks,
- * hanging off lovsub_lock::lss_parents.
- */
- struct list_head lll_list;
-};
-
-/**
* Lock state at lovsub layer.
*/
struct lovsub_lock {
struct cl_lock_slice lss_cl;
- /**
- * List of top-locks that have given sub-lock as their part. Protected
- * by cl_lock::cll_guard mutex.
- */
- struct list_head lss_parents;
- /**
- * Top-lock that initiated current operation on this sub-lock. This is
- * only set during top-to-bottom lock operations like enqueue, and is
- * used to optimize state change notification. Protected by
- * cl_lock::cll_guard mutex.
- *
- * \see lovsub_lock_state_one().
- */
- struct cl_lock *lss_active;
};
/**
@@ -356,7 +285,6 @@ struct lovsub_lock {
struct lov_sublock_env {
const struct lu_env *lse_env;
struct cl_io *lse_io;
- struct lov_io_sub *lse_sub;
};
struct lovsub_page {
@@ -366,12 +294,10 @@ struct lovsub_page {
struct lov_thread_info {
struct cl_object_conf lti_stripe_conf;
struct lu_fid lti_fid;
- struct cl_lock_descr lti_ldescr;
struct ost_lvb lti_lvb;
struct cl_2queue lti_cl2q;
struct cl_page_list lti_plist;
wait_queue_entry_t lti_waiter;
- struct cl_attr lti_attr;
};
/**
@@ -385,7 +311,6 @@ struct lov_io_sub {
* \see cl_env_get()
*/
u16 sub_refcheck;
- u16 sub_reenter;
/**
* true, iff cl_io_init() was successfully executed against
* lov_io_sub::sub_io.
@@ -445,7 +370,6 @@ struct lov_io {
*/
u64 lis_endpos;
- int lis_mem_frozen;
int lis_stripe_count;
int lis_active_subios;
@@ -485,8 +409,6 @@ extern struct kmem_cache *lov_session_kmem;
extern struct kmem_cache *lovsub_lock_kmem;
extern struct kmem_cache *lovsub_object_kmem;
-extern struct kmem_cache *lov_lock_link_kmem;
-
int lov_object_init(const struct lu_env *env, struct lu_object *obj,
const struct lu_object_conf *conf);
int lovsub_object_init(const struct lu_env *env, struct lu_object *obj,
@@ -508,15 +430,9 @@ int lov_io_init_empty(const struct lu_env *env, struct cl_object *obj,
struct cl_io *io);
int lov_io_init_released(const struct lu_env *env, struct cl_object *obj,
struct cl_io *io);
-void lov_lock_unlink(const struct lu_env *env, struct lov_lock_link *link,
- struct lovsub_lock *sub);
struct lov_io_sub *lov_sub_get(const struct lu_env *env, struct lov_io *lio,
int stripe);
-void lov_sub_put(struct lov_io_sub *sub);
-int lov_sublock_modify(const struct lu_env *env, struct lov_lock *lov,
- struct lovsub_lock *sublock,
- const struct cl_lock_descr *d, int idx);
int lov_page_init(const struct lu_env *env, struct cl_object *ob,
struct cl_page *page, pgoff_t index);
@@ -533,12 +449,6 @@ struct lu_object *lovsub_object_alloc(const struct lu_env *env,
const struct lu_object_header *hdr,
struct lu_device *dev);
-struct lov_lock_link *lov_lock_link_find(const struct lu_env *env,
- struct lov_lock *lck,
- struct lovsub_lock *sub);
-struct lov_io_sub *lov_page_subio(const struct lu_env *env, struct lov_io *lio,
- const struct cl_page_slice *slice);
-
struct lov_stripe_md *lov_lsm_addref(struct lov_object *lov);
int lov_page_stripe(const struct cl_page *page);
diff --git a/drivers/staging/lustre/lustre/lov/lov_dev.c b/drivers/staging/lustre/lustre/lov/lov_dev.c
index 7301f6e5..cea5f9d 100644
--- a/drivers/staging/lustre/lustre/lov/lov_dev.c
+++ b/drivers/staging/lustre/lustre/lov/lov_dev.c
@@ -37,7 +37,7 @@
#define DEBUG_SUBSYSTEM S_LOV
/* class_name2obd() */
-#include "../include/obd_class.h"
+#include <obd_class.h>
#include "lov_cl_internal.h"
#include "lov_internal.h"
@@ -50,11 +50,6 @@ struct kmem_cache *lov_session_kmem;
struct kmem_cache *lovsub_lock_kmem;
struct kmem_cache *lovsub_object_kmem;
-struct kmem_cache *lov_lock_link_kmem;
-
-/** Lock class of lov_device::ld_mutex. */
-static struct lock_class_key cl_lov_device_mutex_class;
-
struct lu_kmem_descr lov_caches[] = {
{
.ckd_cache = &lov_lock_kmem,
@@ -87,11 +82,6 @@ struct lu_kmem_descr lov_caches[] = {
.ckd_size = sizeof(struct lovsub_object)
},
{
- .ckd_cache = &lov_lock_link_kmem,
- .ckd_name = "lov_lock_link_kmem",
- .ckd_size = sizeof(struct lov_lock_link)
- },
- {
.ckd_cache = NULL
}
};
@@ -204,8 +194,6 @@ static int lov_device_init(const struct lu_env *env, struct lu_device *d,
break;
}
lsd = cl2lovsub_dev(cl);
- lsd->acid_idx = i;
- lsd->acid_super = ld;
ld->ld_target[i] = lsd;
}
@@ -217,34 +205,13 @@ static int lov_device_init(const struct lu_env *env, struct lu_device *d,
return rc;
}
-static void lov_emerg_free(struct lov_device_emerg **emrg, int nr)
-{
- int i;
-
- for (i = 0; i < nr; ++i) {
- struct lov_device_emerg *em;
-
- em = emrg[i];
- if (em) {
- LASSERT(em->emrg_page_list.pl_nr == 0);
- if (em->emrg_env)
- cl_env_put(em->emrg_env, &em->emrg_refcheck);
- kfree(em);
- }
- }
- kfree(emrg);
-}
-
static struct lu_device *lov_device_free(const struct lu_env *env,
struct lu_device *d)
{
struct lov_device *ld = lu2lov_dev(d);
- const int nr = ld->ld_target_nr;
cl_device_fini(lu2cl_dev(d));
kfree(ld->ld_target);
- if (ld->ld_emrg)
- lov_emerg_free(ld->ld_emrg, nr);
kfree(ld);
return NULL;
}
@@ -260,41 +227,6 @@ static void lov_cl_del_target(const struct lu_env *env, struct lu_device *dev,
}
}
-static struct lov_device_emerg **lov_emerg_alloc(int nr)
-{
- struct lov_device_emerg **emerg;
- int i;
- int result;
-
- emerg = kcalloc(nr, sizeof(emerg[0]), GFP_NOFS);
- if (!emerg)
- return ERR_PTR(-ENOMEM);
- for (result = i = 0; i < nr && result == 0; i++) {
- struct lov_device_emerg *em;
-
- em = kzalloc(sizeof(*em), GFP_NOFS);
- if (em) {
- emerg[i] = em;
- cl_page_list_init(&em->emrg_page_list);
- em->emrg_env = cl_env_alloc(&em->emrg_refcheck,
- LCT_REMEMBER | LCT_NOREF);
- if (!IS_ERR(em->emrg_env)) {
- em->emrg_env->le_ctx.lc_cookie = 0x2;
- } else {
- result = PTR_ERR(em->emrg_env);
- em->emrg_env = NULL;
- }
- } else {
- result = -ENOMEM;
- }
- }
- if (result != 0) {
- lov_emerg_free(emerg, nr);
- emerg = ERR_PTR(result);
- }
- return emerg;
-}
-
static int lov_expand_targets(const struct lu_env *env, struct lov_device *dev)
{
int result;
@@ -306,29 +238,17 @@ static int lov_expand_targets(const struct lu_env *env, struct lov_device *dev)
sub_size = dev->ld_target_nr;
if (sub_size < tgt_size) {
struct lovsub_device **newd;
- struct lov_device_emerg **emerg;
const size_t sz = sizeof(newd[0]);
- emerg = lov_emerg_alloc(tgt_size);
- if (IS_ERR(emerg))
- return PTR_ERR(emerg);
-
newd = kcalloc(tgt_size, sz, GFP_NOFS);
if (newd) {
- mutex_lock(&dev->ld_mutex);
if (sub_size > 0) {
memcpy(newd, dev->ld_target, sub_size * sz);
kfree(dev->ld_target);
}
dev->ld_target = newd;
dev->ld_target_nr = tgt_size;
-
- if (dev->ld_emrg)
- lov_emerg_free(dev->ld_emrg, sub_size);
- dev->ld_emrg = emerg;
- mutex_unlock(&dev->ld_mutex);
} else {
- lov_emerg_free(emerg, tgt_size);
result = -ENOMEM;
}
}
@@ -362,8 +282,6 @@ static int lov_cl_add_target(const struct lu_env *env, struct lu_device *dev,
tgt->ltd_obd->obd_lu_dev);
if (!IS_ERR(cl)) {
lsd = cl2lovsub_dev(cl);
- lsd->acid_idx = index;
- lsd->acid_super = ld;
ld->ld_target[index] = lsd;
} else {
CERROR("add failed (%d), deleting %s\n", rc,
@@ -428,9 +346,6 @@ static struct lu_device *lov_device_alloc(const struct lu_env *env,
d = lov2lu_dev(ld);
d->ld_ops = &lov_lu_ops;
- mutex_init(&ld->ld_mutex);
- lockdep_set_class(&ld->ld_mutex, &cl_lov_device_mutex_class);
-
/* setup the LOV OBD */
obd = class_name2obd(lustre_cfg_string(cfg, 0));
LASSERT(obd);
diff --git a/drivers/staging/lustre/lustre/lov/lov_ea.c b/drivers/staging/lustre/lustre/lov/lov_ea.c
index ac0bf64..1124fd5 100644
--- a/drivers/staging/lustre/lustre/lov/lov_ea.c
+++ b/drivers/staging/lustre/lustre/lov/lov_ea.c
@@ -37,10 +37,10 @@
#define DEBUG_SUBSYSTEM S_LOV
#include <asm/div64.h>
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
-#include "../include/obd_class.h"
-#include "../include/lustre/lustre_idl.h"
+#include <obd_class.h>
+#include <uapi/linux/lustre/lustre_idl.h>
#include "lov_internal.h"
@@ -150,9 +150,10 @@ static int lsm_unpackmd_common(struct lov_obd *lov,
struct lov_mds_md *lmm,
struct lov_ost_data_v1 *objects)
{
- loff_t stripe_maxbytes = LLONG_MAX;
+ loff_t min_stripe_maxbytes = 0;
unsigned int stripe_count;
struct lov_oinfo *loi;
+ loff_t lov_bytes;
unsigned int i;
/*
@@ -168,8 +169,6 @@ static int lsm_unpackmd_common(struct lov_obd *lov,
stripe_count = lsm_is_released(lsm) ? 0 : lsm->lsm_stripe_count;
for (i = 0; i < stripe_count; i++) {
- loff_t tgt_bytes;
-
loi = lsm->lsm_oinfo[i];
ostid_le_to_cpu(&objects[i].l_ost_oi, &loi->loi_oi);
loi->loi_ost_idx = le32_to_cpu(objects[i].l_ost_idx);
@@ -194,17 +193,21 @@ static int lsm_unpackmd_common(struct lov_obd *lov,
continue;
}
- tgt_bytes = lov_tgt_maxbytes(lov->lov_tgts[loi->loi_ost_idx]);
- stripe_maxbytes = min_t(loff_t, stripe_maxbytes, tgt_bytes);
+ lov_bytes = lov_tgt_maxbytes(lov->lov_tgts[loi->loi_ost_idx]);
+ if (min_stripe_maxbytes == 0 || lov_bytes < min_stripe_maxbytes)
+ min_stripe_maxbytes = lov_bytes;
}
- if (stripe_maxbytes == LLONG_MAX)
- stripe_maxbytes = LUSTRE_EXT3_STRIPE_MAXBYTES;
+ if (min_stripe_maxbytes == 0)
+ min_stripe_maxbytes = LUSTRE_EXT3_STRIPE_MAXBYTES;
+
+ stripe_count = lsm->lsm_stripe_count ?: lov->desc.ld_tgt_count;
+ lov_bytes = min_stripe_maxbytes * stripe_count;
- if (!lsm->lsm_stripe_count)
- lsm->lsm_maxbytes = stripe_maxbytes * lov->desc.ld_tgt_count;
+ if (lov_bytes < min_stripe_maxbytes) /* handle overflow */
+ lsm->lsm_maxbytes = MAX_LFS_FILESIZE;
else
- lsm->lsm_maxbytes = stripe_maxbytes * lsm->lsm_stripe_count;
+ lsm->lsm_maxbytes = lov_bytes;
return 0;
}
diff --git a/drivers/staging/lustre/lustre/lov/lov_internal.h b/drivers/staging/lustre/lustre/lov/lov_internal.h
index 774499c..a21f074 100644
--- a/drivers/staging/lustre/lustre/lov/lov_internal.h
+++ b/drivers/staging/lustre/lustre/lov/lov_internal.h
@@ -33,8 +33,8 @@
#ifndef LOV_INTERNAL_H
#define LOV_INTERNAL_H
-#include "../include/obd_class.h"
-#include "../include/lustre/lustre_user.h"
+#include <obd_class.h>
+#include <uapi/linux/lustre/lustre_idl.h>
/*
* If we are unable to get the maximum object size from the OST in
@@ -161,42 +161,21 @@ struct lov_request {
struct list_head rq_link;
int rq_idx; /* index in lov->tgts array */
- int rq_stripe; /* stripe number */
- int rq_complete;
- int rq_rc;
-
- u32 rq_oabufs;
- u32 rq_pgaidx;
};
struct lov_request_set {
struct obd_info *set_oi;
- atomic_t set_refcount;
- struct obd_export *set_exp;
- /* XXX: There is @set_exp already, however obd_statfs gets obd_device
- * only.
- */
struct obd_device *set_obd;
int set_count;
atomic_t set_completes;
atomic_t set_success;
- atomic_t set_finish_checked;
struct list_head set_list;
- wait_queue_head_t set_waitq;
};
extern struct kmem_cache *lov_oinfo_slab;
extern struct lu_kmem_descr lov_caches[];
-void lov_finish_set(struct lov_request_set *set);
-
-static inline void lov_put_reqset(struct lov_request_set *set)
-{
- if (atomic_dec_and_test(&set->set_refcount))
- lov_finish_set(set);
-}
-
#define lov_uuid2str(lv, index) \
(char *)((lv)->lov_tgts[index]->ltd_uuid.uuid)
@@ -217,15 +196,9 @@ pgoff_t lov_stripe_pgoff(struct lov_stripe_md *lsm, pgoff_t stripe_index,
int stripe);
/* lov_request.c */
-int lov_prep_getattr_set(struct obd_export *exp, struct obd_info *oinfo,
- struct lov_request_set **reqset);
-int lov_fini_getattr_set(struct lov_request_set *set);
int lov_prep_statfs_set(struct obd_device *obd, struct obd_info *oinfo,
struct lov_request_set **reqset);
-int lov_fini_statfs(struct obd_device *obd, struct obd_statfs *osfs,
- int success);
int lov_fini_statfs_set(struct lov_request_set *set);
-int lov_statfs_interpret(struct ptlrpc_request_set *rqset, void *data, int rc);
/* lov_obd.c */
void lov_stripe_lock(struct lov_stripe_md *md);
diff --git a/drivers/staging/lustre/lustre/lov/lov_io.c b/drivers/staging/lustre/lustre/lov/lov_io.c
index babf39a..9e3b150 100644
--- a/drivers/staging/lustre/lustre/lov/lov_io.c
+++ b/drivers/staging/lustre/lustre/lov/lov_io.c
@@ -43,24 +43,12 @@
* @{
*/
-static inline void lov_sub_enter(struct lov_io_sub *sub)
-{
- sub->sub_reenter++;
-}
-
-static inline void lov_sub_exit(struct lov_io_sub *sub)
-{
- sub->sub_reenter--;
-}
-
static void lov_io_sub_fini(const struct lu_env *env, struct lov_io *lio,
struct lov_io_sub *sub)
{
if (sub->sub_io) {
if (sub->sub_io_initialized) {
- lov_sub_enter(sub);
cl_io_fini(sub->sub_env, sub->sub_io);
- lov_sub_exit(sub);
sub->sub_io_initialized = 0;
lio->lis_active_subios--;
}
@@ -142,13 +130,11 @@ static int lov_io_sub_init(const struct lu_env *env, struct lov_io *lio,
struct lov_io_sub *sub)
{
struct lov_object *lov = lio->lis_object;
- struct lov_device *ld = lu2lov_dev(lov2cl(lov)->co_lu.lo_dev);
struct cl_io *sub_io;
struct cl_object *sub_obj;
struct cl_io *io = lio->lis_cl.cis_io;
-
int stripe = sub->sub_stripe;
- int result;
+ int rc;
LASSERT(!sub->sub_io);
LASSERT(!sub->sub_env);
@@ -157,63 +143,53 @@ static int lov_io_sub_init(const struct lu_env *env, struct lov_io *lio,
if (unlikely(!lov_r0(lov)->lo_sub[stripe]))
return -EIO;
- result = 0;
sub->sub_io_initialized = 0;
sub->sub_borrowed = 0;
- if (lio->lis_mem_frozen) {
- LASSERT(mutex_is_locked(&ld->ld_mutex));
- sub->sub_io = &ld->ld_emrg[stripe]->emrg_subio;
- sub->sub_env = ld->ld_emrg[stripe]->emrg_env;
- sub->sub_borrowed = 1;
- } else {
- sub->sub_env = cl_env_get(&sub->sub_refcheck);
- if (IS_ERR(sub->sub_env))
- result = PTR_ERR(sub->sub_env);
+ /* obtain new environment */
+ sub->sub_env = cl_env_get(&sub->sub_refcheck);
+ if (IS_ERR(sub->sub_env)) {
+ rc = PTR_ERR(sub->sub_env);
+ goto fini_lov_io;
+ }
- if (result == 0) {
- /*
- * First sub-io. Use ->lis_single_subio to
- * avoid dynamic allocation.
- */
- if (lio->lis_active_subios == 0) {
- sub->sub_io = &lio->lis_single_subio;
- lio->lis_single_subio_index = stripe;
- } else {
- sub->sub_io = kzalloc(sizeof(*sub->sub_io),
- GFP_NOFS);
- if (!sub->sub_io)
- result = -ENOMEM;
- }
+ /*
+ * First sub-io. Use ->lis_single_subio to
+ * avoid dynamic allocation.
+ */
+ if (lio->lis_active_subios == 0) {
+ sub->sub_io = &lio->lis_single_subio;
+ lio->lis_single_subio_index = stripe;
+ } else {
+ sub->sub_io = kzalloc(sizeof(*sub->sub_io),
+ GFP_NOFS);
+ if (!sub->sub_io) {
+ rc = -ENOMEM;
+ goto fini_lov_io;
}
}
- if (result == 0) {
- sub_obj = lovsub2cl(lov_r0(lov)->lo_sub[stripe]);
- sub_io = sub->sub_io;
-
- sub_io->ci_obj = sub_obj;
- sub_io->ci_result = 0;
-
- sub_io->ci_parent = io;
- sub_io->ci_lockreq = io->ci_lockreq;
- sub_io->ci_type = io->ci_type;
- sub_io->ci_no_srvlock = io->ci_no_srvlock;
- sub_io->ci_noatime = io->ci_noatime;
-
- lov_sub_enter(sub);
- result = cl_io_sub_init(sub->sub_env, sub_io,
- io->ci_type, sub_obj);
- lov_sub_exit(sub);
- if (result >= 0) {
- lio->lis_active_subios++;
- sub->sub_io_initialized = 1;
- result = 0;
- }
+ sub_obj = lovsub2cl(lov_r0(lov)->lo_sub[stripe]);
+ sub_io = sub->sub_io;
+
+ sub_io->ci_obj = sub_obj;
+ sub_io->ci_result = 0;
+ sub_io->ci_parent = io;
+ sub_io->ci_lockreq = io->ci_lockreq;
+ sub_io->ci_type = io->ci_type;
+ sub_io->ci_no_srvlock = io->ci_no_srvlock;
+ sub_io->ci_noatime = io->ci_noatime;
+
+ rc = cl_io_sub_init(sub->sub_env, sub_io, io->ci_type, sub_obj);
+ if (rc >= 0) {
+ lio->lis_active_subios++;
+ sub->sub_io_initialized = 1;
+ rc = 0;
}
- if (result != 0)
+fini_lov_io:
+ if (rc)
lov_io_sub_fini(env, lio, sub);
- return result;
+ return rc;
}
struct lov_io_sub *lov_sub_get(const struct lu_env *env,
@@ -230,16 +206,10 @@ struct lov_io_sub *lov_sub_get(const struct lu_env *env,
} else {
rc = 0;
}
- if (rc == 0)
- lov_sub_enter(sub);
- else
+ if (rc < 0)
sub = ERR_PTR(rc);
- return sub;
-}
-void lov_sub_put(struct lov_io_sub *sub)
-{
- lov_sub_exit(sub);
+ return sub;
}
/*****************************************************************************
@@ -258,22 +228,6 @@ int lov_page_stripe(const struct cl_page *page)
return cl2lov_page(slice)->lps_stripe;
}
-struct lov_io_sub *lov_page_subio(const struct lu_env *env, struct lov_io *lio,
- const struct cl_page_slice *slice)
-{
- struct lov_stripe_md *lsm = lio->lis_object->lo_lsm;
- struct cl_page *page = slice->cpl_page;
- int stripe;
-
- LASSERT(lio->lis_cl.cis_io);
- LASSERT(cl2lov(slice->cpl_obj) == lio->lis_object);
- LASSERT(lsm);
- LASSERT(lio->lis_nr_subios > 0);
-
- stripe = lov_page_stripe(page);
- return lov_sub_get(env, lio, stripe);
-}
-
static int lov_io_subio_init(const struct lu_env *env, struct lov_io *lio,
struct cl_io *io)
{
@@ -431,12 +385,10 @@ static int lov_io_iter_init(const struct lu_env *env,
lov_io_sub_inherit(sub->sub_io, lio, stripe, start, end);
rc = cl_io_iter_init(sub->sub_env, sub->sub_io);
- if (rc)
+ if (rc) {
cl_io_iter_fini(sub->sub_env, sub->sub_io);
- lov_sub_put(sub);
- if (rc)
break;
-
+ }
CDEBUG(D_VFSTRACE, "shrink: %d [%llu, %llu)\n",
stripe, start, end);
@@ -488,9 +440,7 @@ static int lov_io_call(const struct lu_env *env, struct lov_io *lio,
int rc = 0;
list_for_each_entry(sub, &lio->lis_active, sub_linkage) {
- lov_sub_enter(sub);
rc = iofunc(sub->sub_env, sub->sub_io);
- lov_sub_exit(sub);
if (rc)
break;
@@ -610,7 +560,6 @@ static int lov_io_read_ahead(const struct lu_env *env,
rc = cl_io_read_ahead(sub->sub_env, sub->sub_io,
cl_index(lovsub2cl(r0->lo_sub[stripe]), suboff),
ra);
- lov_sub_put(sub);
CDEBUG(D_READA, DFID " cra_end = %lu, stripes = %d, rc = %d\n",
PFID(lu_object_fid(lov2lu(loo))), ra->cra_end, r0->lo_nr, rc);
@@ -679,7 +628,6 @@ static int lov_io_submit(const struct lu_env *env,
LASSERT(sub->sub_io == &lio->lis_single_subio);
rc = cl_io_submit_rw(sub->sub_env, sub->sub_io,
crt, queue);
- lov_sub_put(sub);
return rc;
}
@@ -707,7 +655,6 @@ static int lov_io_submit(const struct lu_env *env,
if (!IS_ERR(sub)) {
rc = cl_io_submit_rw(sub->sub_env, sub->sub_io,
crt, cl2q);
- lov_sub_put(sub);
} else {
rc = PTR_ERR(sub);
}
@@ -746,7 +693,6 @@ static int lov_io_commit_async(const struct lu_env *env,
LASSERT(sub->sub_io == &lio->lis_single_subio);
rc = cl_io_commit_async(sub->sub_env, sub->sub_io, queue,
from, to, cb);
- lov_sub_put(sub);
return rc;
}
@@ -777,7 +723,6 @@ static int lov_io_commit_async(const struct lu_env *env,
if (!IS_ERR(sub)) {
rc = cl_io_commit_async(sub->sub_env, sub->sub_io,
plist, from, stripe_to, cb);
- lov_sub_put(sub);
} else {
rc = PTR_ERR(sub);
break;
@@ -813,7 +758,6 @@ static int lov_io_fault_start(const struct lu_env *env,
if (IS_ERR(sub))
return PTR_ERR(sub);
sub->sub_io->u.ci_fault.ft_nob = fio->ft_nob;
- lov_sub_put(sub);
return lov_io_start(env, ios);
}
@@ -828,9 +772,7 @@ static void lov_io_fsync_end(const struct lu_env *env,
list_for_each_entry(sub, &lio->lis_active, sub_linkage) {
struct cl_io *subio = sub->sub_io;
- lov_sub_enter(sub);
lov_io_end_wrapper(sub->sub_env, subio);
- lov_sub_exit(sub);
if (subio->ci_result == 0)
*written += subio->u.ci_fsync.fi_nr_written;
@@ -939,12 +881,6 @@ static const struct cl_io_operations lov_empty_io_ops = {
.op = {
[CIT_READ] = {
.cio_fini = lov_empty_io_fini,
-#if 0
- .cio_iter_init = LOV_EMPTY_IMPOSSIBLE,
- .cio_lock = LOV_EMPTY_IMPOSSIBLE,
- .cio_start = LOV_EMPTY_IMPOSSIBLE,
- .cio_end = LOV_EMPTY_IMPOSSIBLE
-#endif
},
[CIT_WRITE] = {
.cio_fini = lov_empty_io_fini,
@@ -1047,6 +983,8 @@ int lov_io_init_released(const struct lu_env *env, struct cl_object *obj,
switch (io->ci_type) {
default:
LASSERTF(0, "invalid type %d\n", io->ci_type);
+ result = -EOPNOTSUPP;
+ break;
case CIT_MISC:
case CIT_FSYNC:
case CIT_DATA_VERSION:
diff --git a/drivers/staging/lustre/lustre/lov/lov_lock.c b/drivers/staging/lustre/lustre/lov/lov_lock.c
index 8502128..e12dc5a 100644
--- a/drivers/staging/lustre/lustre/lov/lov_lock.c
+++ b/drivers/staging/lustre/lustre/lov/lov_lock.c
@@ -71,13 +71,11 @@ static struct lov_sublock_env *lov_sublock_env_get(const struct lu_env *env,
if (!io || !cl_object_same(io->ci_obj, parent->cll_descr.cld_obj)) {
subenv->lse_env = env;
subenv->lse_io = io;
- subenv->lse_sub = NULL;
} else {
sub = lov_sub_get(env, lio, lls->sub_stripe);
if (!IS_ERR(sub)) {
subenv->lse_env = sub->sub_env;
subenv->lse_io = sub->sub_io;
- subenv->lse_sub = sub;
} else {
subenv = (void *)sub;
}
@@ -85,12 +83,6 @@ static struct lov_sublock_env *lov_sublock_env_get(const struct lu_env *env,
return subenv;
}
-static void lov_sublock_env_put(struct lov_sublock_env *subenv)
-{
- if (subenv && subenv->lse_sub)
- lov_sub_put(subenv->lse_sub);
-}
-
static int lov_sublock_init(const struct lu_env *env,
const struct cl_lock *parent,
struct lov_lock_sub *lls)
@@ -102,7 +94,6 @@ static int lov_sublock_init(const struct lu_env *env,
if (!IS_ERR(subenv)) {
result = cl_lock_init(subenv->lse_env, &lls->sub_lock,
subenv->lse_io);
- lov_sublock_env_put(subenv);
} else {
/* error occurs. */
result = PTR_ERR(subenv);
@@ -244,7 +235,6 @@ static int lov_lock_enqueue(const struct lu_env *env,
}
rc = cl_lock_enqueue(subenv->lse_env, subenv->lse_io,
&lls->sub_lock, anchor);
- lov_sublock_env_put(subenv);
if (rc != 0)
break;
@@ -272,11 +262,10 @@ static void lov_lock_cancel(const struct lu_env *env,
subenv = lov_sublock_env_get(env, lock, lls);
if (!IS_ERR(subenv)) {
cl_lock_cancel(subenv->lse_env, sublock);
- lov_sublock_env_put(subenv);
} else {
CL_LOCK_DEBUG(D_ERROR, env, slice->cls_lock,
- "lov_lock_cancel fails with %ld.\n",
- PTR_ERR(subenv));
+ "%s fails with %ld.\n",
+ __func__, PTR_ERR(subenv));
}
}
}
diff --git a/drivers/staging/lustre/lustre/lov/lov_merge.c b/drivers/staging/lustre/lustre/lov/lov_merge.c
index 034b4fc..9163361 100644
--- a/drivers/staging/lustre/lustre/lov/lov_merge.c
+++ b/drivers/staging/lustre/lustre/lov/lov_merge.c
@@ -32,9 +32,9 @@
#define DEBUG_SUBSYSTEM S_LOV
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
-#include "../include/obd_class.h"
+#include <obd_class.h>
#include "lov_internal.h"
/** Merge the lock value block(&lvb) attributes and KMS from each of the
diff --git a/drivers/staging/lustre/lustre/lov/lov_obd.c b/drivers/staging/lustre/lustre/lov/lov_obd.c
index 25f15da..fefd3c5 100644
--- a/drivers/staging/lustre/lustre/lov/lov_obd.c
+++ b/drivers/staging/lustre/lustre/lov/lov_obd.c
@@ -38,22 +38,22 @@
*/
#define DEBUG_SUBSYSTEM S_LOV
-#include "../../include/linux/libcfs/libcfs.h"
-
-#include "../include/lustre/lustre_idl.h"
-#include "../include/lustre/lustre_ioctl.h"
-
-#include "../include/cl_object.h"
-#include "../include/lustre_dlm.h"
-#include "../include/lustre_fid.h"
-#include "../include/lustre_lib.h"
-#include "../include/lustre_mds.h"
-#include "../include/lustre_net.h"
-#include "../include/lustre_param.h"
-#include "../include/lustre_swab.h"
-#include "../include/lprocfs_status.h"
-#include "../include/obd_class.h"
-#include "../include/obd_support.h"
+#include <linux/libcfs/libcfs.h>
+
+#include <uapi/linux/lustre/lustre_idl.h>
+#include <uapi/linux/lustre/lustre_ioctl.h>
+
+#include <cl_object.h>
+#include <lustre_dlm.h>
+#include <lustre_fid.h>
+#include <lustre_lib.h>
+#include <lustre_mds.h>
+#include <lustre_net.h>
+#include <uapi/linux/lustre/lustre_param.h>
+#include <lustre_swab.h>
+#include <lprocfs_status.h>
+#include <obd_class.h>
+#include <obd_support.h>
#include "lov_internal.h"
@@ -947,7 +947,8 @@ out:
return rc;
}
-int lov_statfs_interpret(struct ptlrpc_request_set *rqset, void *data, int rc)
+static int
+lov_statfs_interpret(struct ptlrpc_request_set *rqset, void *data, int rc)
{
struct lov_request_set *lovset = (struct lov_request_set *)data;
int err;
@@ -1086,17 +1087,17 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
data = (struct obd_ioctl_data *)buf;
if (sizeof(*desc) > data->ioc_inllen1) {
- obd_ioctl_freedata(buf, len);
+ kvfree(buf);
return -EINVAL;
}
if (sizeof(uuidp->uuid) * count > data->ioc_inllen2) {
- obd_ioctl_freedata(buf, len);
+ kvfree(buf);
return -EINVAL;
}
if (sizeof(__u32) * count > data->ioc_inllen3) {
- obd_ioctl_freedata(buf, len);
+ kvfree(buf);
return -EINVAL;
}
@@ -1115,7 +1116,7 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
if (copy_to_user(uarg, buf, len))
rc = -EFAULT;
- obd_ioctl_freedata(buf, len);
+ kvfree(buf);
break;
}
case OBD_IOC_QUOTACTL: {
diff --git a/drivers/staging/lustre/lustre/lov/lov_object.c b/drivers/staging/lustre/lustre/lov/lov_object.c
index 14f3826..334ecb1 100644
--- a/drivers/staging/lustre/lustre/lov/lov_object.c
+++ b/drivers/staging/lustre/lustre/lov/lov_object.c
@@ -638,7 +638,7 @@ static const struct lov_layout_operations lov_dispatch[] = {
enum lov_layout_type __llt; \
\
__llt = __obj->lo_type; \
- LASSERT(0 <= __llt && __llt < ARRAY_SIZE(lov_dispatch)); \
+ LASSERT(__llt < ARRAY_SIZE(lov_dispatch)); \
lov_dispatch[__llt].op(__VA_ARGS__); \
})
@@ -697,7 +697,7 @@ do { \
\
lov_conf_freeze(__obj); \
__llt = __obj->lo_type; \
- LASSERT(0 <= __llt && __llt < ARRAY_SIZE(lov_dispatch)); \
+ LASSERT(__llt < ARRAY_SIZE(lov_dispatch)); \
lov_dispatch[__llt].op(__VA_ARGS__); \
lov_conf_thaw(__obj); \
} while (0)
@@ -748,13 +748,13 @@ static int lov_layout_change(const struct lu_env *unused,
u16 refcheck;
int rc;
- LASSERT(0 <= lov->lo_type && lov->lo_type < ARRAY_SIZE(lov_dispatch));
+ LASSERT(lov->lo_type < ARRAY_SIZE(lov_dispatch));
env = cl_env_get(&refcheck);
if (IS_ERR(env))
return PTR_ERR(env);
- LASSERT(0 <= llt && llt < ARRAY_SIZE(lov_dispatch));
+ LASSERT(llt < ARRAY_SIZE(lov_dispatch));
CDEBUG(D_INODE, DFID " from %s to %s\n",
PFID(lu_object_fid(lov2lu(lov))),
@@ -1003,12 +1003,12 @@ int lov_lock_init(const struct lu_env *env, struct cl_object *obj,
* \retval last_stripe return the last stripe of the mapping
*/
static int fiemap_calc_last_stripe(struct lov_stripe_md *lsm,
- loff_t fm_start, loff_t fm_end,
+ u64 fm_start, u64 fm_end,
int start_stripe, int *stripe_count)
{
int last_stripe;
- loff_t obd_start;
- loff_t obd_end;
+ u64 obd_start;
+ u64 obd_end;
int i, j;
if (fm_end - fm_start > lsm->lsm_stripe_size * lsm->lsm_stripe_count) {
@@ -1076,14 +1076,14 @@ static void fiemap_prepare_and_copy_exts(struct fiemap *fiemap,
* \param fm_end [in] logical end of mapping
* \param start_stripe [out] starting stripe will be returned in this
*/
-static loff_t fiemap_calc_fm_end_offset(struct fiemap *fiemap,
- struct lov_stripe_md *lsm,
- loff_t fm_start, loff_t fm_end,
- int *start_stripe)
+static u64 fiemap_calc_fm_end_offset(struct fiemap *fiemap,
+ struct lov_stripe_md *lsm,
+ u64 fm_start, u64 fm_end,
+ int *start_stripe)
{
- loff_t local_end = fiemap->fm_extents[0].fe_logical;
- loff_t lun_start, lun_end;
- loff_t fm_end_offset;
+ u64 local_end = fiemap->fm_extents[0].fe_logical;
+ u64 lun_start, lun_end;
+ u64 fm_end_offset;
int stripe_no = -1;
int i;
@@ -1126,6 +1126,190 @@ static loff_t fiemap_calc_fm_end_offset(struct fiemap *fiemap,
return fm_end_offset;
}
+struct fiemap_state {
+ struct fiemap *fs_fm;
+ u64 fs_start;
+ u64 fs_length;
+ u64 fs_end;
+ u64 fs_end_offset;
+ int fs_cur_extent;
+ int fs_cnt_need;
+ int fs_start_stripe;
+ int fs_last_stripe;
+ bool fs_device_done;
+ bool fs_finish;
+ bool fs_enough;
+};
+
+static int fiemap_for_stripe(const struct lu_env *env, struct cl_object *obj,
+ struct lov_stripe_md *lsm,
+ struct fiemap *fiemap, size_t *buflen,
+ struct ll_fiemap_info_key *fmkey, int stripeno,
+ struct fiemap_state *fs)
+{
+ struct cl_object *subobj;
+ struct lov_obd *lov = lu2lov_dev(obj->co_lu.lo_dev)->ld_lov;
+ struct fiemap_extent *fm_ext = &fs->fs_fm->fm_extents[0];
+ u64 req_fm_len; /* Stores length of required mapping */
+ u64 len_mapped_single_call;
+ u64 lun_start;
+ u64 lun_end;
+ u64 obd_object_end;
+ unsigned int ext_count;
+ /* EOF for object */
+ bool ost_eof = false;
+ /* done with required mapping for this OST? */
+ bool ost_done = false;
+ int ost_index;
+ int rc = 0;
+
+ fs->fs_device_done = false;
+ /* Find out range of mapping on this stripe */
+ if ((lov_stripe_intersects(lsm, stripeno, fs->fs_start, fs->fs_end,
+ &lun_start, &obd_object_end)) == 0)
+ return 0;
+
+ if (lov_oinfo_is_dummy(lsm->lsm_oinfo[stripeno]))
+ return -EIO;
+
+ /* If this is a continuation FIEMAP call and we are on
+ * starting stripe then lun_start needs to be set to
+ * end_offset */
+ if (fs->fs_end_offset != 0 && stripeno == fs->fs_start_stripe)
+ lun_start = fs->fs_end_offset;
+
+ lun_end = fs->fs_length;
+ if (lun_end != ~0ULL) {
+ /* Handle fs->fs_start + fs->fs_length overflow */
+ if (fs->fs_start + fs->fs_length < fs->fs_start)
+ fs->fs_length = ~0ULL - fs->fs_start;
+ lun_end = lov_size_to_stripe(lsm, fs->fs_start + fs->fs_length,
+ stripeno);
+ }
+
+ if (lun_start == lun_end)
+ return 0;
+
+ req_fm_len = obd_object_end - lun_start;
+ fs->fs_fm->fm_length = 0;
+ len_mapped_single_call = 0;
+
+ /* find lobsub object */
+ subobj = lov_find_subobj(env, cl2lov(obj), lsm, stripeno);
+ if (IS_ERR(subobj))
+ return PTR_ERR(subobj);
+ /* If the output buffer is very large and the objects have many
+ * extents we may need to loop on a single OST repeatedly */
+ do {
+ if (fiemap->fm_extent_count > 0) {
+ /* Don't get too many extents. */
+ if (fs->fs_cur_extent + fs->fs_cnt_need >
+ fiemap->fm_extent_count)
+ fs->fs_cnt_need = fiemap->fm_extent_count -
+ fs->fs_cur_extent;
+ }
+
+ lun_start += len_mapped_single_call;
+ fs->fs_fm->fm_length = req_fm_len - len_mapped_single_call;
+ req_fm_len = fs->fs_fm->fm_length;
+ fs->fs_fm->fm_extent_count = fs->fs_enough ?
+ 1 : fs->fs_cnt_need;
+ fs->fs_fm->fm_mapped_extents = 0;
+ fs->fs_fm->fm_flags = fiemap->fm_flags;
+
+ ost_index = lsm->lsm_oinfo[stripeno]->loi_ost_idx;
+
+ if (ost_index < 0 || ost_index >= lov->desc.ld_tgt_count) {
+ rc = -EINVAL;
+ goto obj_put;
+ }
+ /* If OST is inactive, return extent with UNKNOWN flag. */
+ if (!lov->lov_tgts[ost_index]->ltd_active) {
+ fs->fs_fm->fm_flags |= FIEMAP_EXTENT_LAST;
+ fs->fs_fm->fm_mapped_extents = 1;
+
+ fm_ext[0].fe_logical = lun_start;
+ fm_ext[0].fe_length = obd_object_end - lun_start;
+ fm_ext[0].fe_flags |= FIEMAP_EXTENT_UNKNOWN;
+
+ goto inactive_tgt;
+ }
+
+ fs->fs_fm->fm_start = lun_start;
+ fs->fs_fm->fm_flags &= ~FIEMAP_FLAG_DEVICE_ORDER;
+ memcpy(&fmkey->lfik_fiemap, fs->fs_fm, sizeof(*fs->fs_fm));
+ *buflen = fiemap_count_to_size(fs->fs_fm->fm_extent_count);
+
+ rc = cl_object_fiemap(env, subobj, fmkey, fs->fs_fm, buflen);
+ if (rc)
+ goto obj_put;
+inactive_tgt:
+ ext_count = fs->fs_fm->fm_mapped_extents;
+ if (ext_count == 0) {
+ ost_done = true;
+ fs->fs_device_done = true;
+ /* If last stripe has hold at the end,
+ * we need to return */
+ if (stripeno == fs->fs_last_stripe) {
+ fiemap->fm_mapped_extents = 0;
+ fs->fs_finish = true;
+ goto obj_put;
+ }
+ break;
+ } else if (fs->fs_enough) {
+ /*
+ * We've collected enough extents and there are
+ * more extents after it.
+ */
+ fs->fs_finish = true;
+ goto obj_put;
+ }
+
+ /* If we just need num of extents, got to next device */
+ if (fiemap->fm_extent_count == 0) {
+ fs->fs_cur_extent += ext_count;
+ break;
+ }
+
+ /* prepare to copy retrived map extents */
+ len_mapped_single_call = fm_ext[ext_count - 1].fe_logical +
+ fm_ext[ext_count - 1].fe_length -
+ lun_start;
+
+ /* Have we finished mapping on this device? */
+ if (req_fm_len <= len_mapped_single_call) {
+ ost_done = true;
+ fs->fs_device_done = true;
+ }
+
+ /* Clear the EXTENT_LAST flag which can be present on
+ * the last extent */
+ if (fm_ext[ext_count - 1].fe_flags & FIEMAP_EXTENT_LAST)
+ fm_ext[ext_count - 1].fe_flags &= ~FIEMAP_EXTENT_LAST;
+ if (lov_stripe_size(lsm, fm_ext[ext_count - 1].fe_logical +
+ fm_ext[ext_count - 1].fe_length,
+ stripeno) >= fmkey->lfik_oa.o_size) {
+ ost_eof = true;
+ fs->fs_device_done = true;
+ }
+
+ fiemap_prepare_and_copy_exts(fiemap, fm_ext, ost_index,
+ ext_count, fs->fs_cur_extent);
+ fs->fs_cur_extent += ext_count;
+
+ /* Ran out of available extents? */
+ if (fs->fs_cur_extent >= fiemap->fm_extent_count)
+ fs->fs_enough = true;
+ } while (!ost_done && !ost_eof);
+
+ if (stripeno == fs->fs_last_stripe)
+ fs->fs_finish = true;
+obj_put:
+ cl_object_put(env, subobj);
+
+ return rc;
+}
+
/**
* Break down the FIEMAP request and send appropriate calls to individual OSTs.
* This also handles the restarting of FIEMAP calls in case mapping overflows
@@ -1144,31 +1328,13 @@ static int lov_object_fiemap(const struct lu_env *env, struct cl_object *obj,
struct ll_fiemap_info_key *fmkey,
struct fiemap *fiemap, size_t *buflen)
{
- struct lov_obd *lov = lu2lov_dev(obj->co_lu.lo_dev)->ld_lov;
unsigned int buffer_size = FIEMAP_BUFFER_SIZE;
- struct fiemap_extent *lcl_fm_ext;
- struct cl_object *subobj = NULL;
struct fiemap *fm_local = NULL;
struct lov_stripe_md *lsm;
- loff_t fm_start;
- loff_t fm_end;
- loff_t fm_length;
- loff_t fm_end_offset;
- int count_local;
- int ost_index = 0;
- int start_stripe;
- int current_extent = 0;
int rc = 0;
- int last_stripe;
- int cur_stripe = 0;
- int cur_stripe_wrap = 0;
+ int cur_stripe;
int stripe_count;
- /* Whether have we collected enough extents */
- bool enough = false;
- /* EOF for object */
- bool ost_eof = false;
- /* done with required mapping for this OST? */
- bool ost_done = false;
+ struct fiemap_state fs = { 0 };
lsm = lov_lsm_addref(cl2lov(obj));
if (!lsm)
@@ -1215,28 +1381,37 @@ static int lov_object_fiemap(const struct lu_env *env, struct cl_object *obj,
rc = -ENOMEM;
goto out;
}
- lcl_fm_ext = &fm_local->fm_extents[0];
- count_local = fiemap_size_to_count(buffer_size);
+ fs.fs_fm = fm_local;
+ fs.fs_cnt_need = fiemap_size_to_count(buffer_size);
- fm_start = fiemap->fm_start;
- fm_length = fiemap->fm_length;
+ fs.fs_start = fiemap->fm_start;
+ /* fs_start is beyond the end of the file */
+ if (fs.fs_start > fmkey->lfik_oa.o_size) {
+ rc = -EINVAL;
+ goto out;
+ }
/* Calculate start stripe, last stripe and length of mapping */
- start_stripe = lov_stripe_number(lsm, fm_start);
- fm_end = (fm_length == ~0ULL) ? fmkey->lfik_oa.o_size :
- fm_start + fm_length - 1;
- /* If fm_length != ~0ULL but fm_start_fm_length-1 exceeds file size */
- if (fm_end > fmkey->lfik_oa.o_size)
- fm_end = fmkey->lfik_oa.o_size;
-
- last_stripe = fiemap_calc_last_stripe(lsm, fm_start, fm_end,
- start_stripe, &stripe_count);
- fm_end_offset = fiemap_calc_fm_end_offset(fiemap, lsm, fm_start, fm_end,
- &start_stripe);
- if (fm_end_offset == -EINVAL) {
+ fs.fs_start_stripe = lov_stripe_number(lsm, fs.fs_start);
+ fs.fs_end = (fs.fs_length == ~0ULL) ? fmkey->lfik_oa.o_size :
+ fs.fs_start + fs.fs_length - 1;
+ /* If fs_length != ~0ULL but fs_start+fs_length-1 exceeds file size */
+ if (fs.fs_end > fmkey->lfik_oa.o_size) {
+ fs.fs_end = fmkey->lfik_oa.o_size;
+ fs.fs_length = fs.fs_end - fs.fs_start;
+ }
+
+ fs.fs_last_stripe = fiemap_calc_last_stripe(lsm, fs.fs_start, fs.fs_end,
+ fs.fs_start_stripe,
+ &stripe_count);
+ fs.fs_end_offset = fiemap_calc_fm_end_offset(fiemap, lsm, fs.fs_start,
+ fs.fs_end,
+ &fs.fs_start_stripe);
+ if (fs.fs_end_offset == -EINVAL) {
rc = -EINVAL;
goto out;
}
+
/**
* Requested extent count exceeds the fiemap buffer size, shrink our
* ambition.
@@ -1244,186 +1419,23 @@ static int lov_object_fiemap(const struct lu_env *env, struct cl_object *obj,
if (fiemap_count_to_size(fiemap->fm_extent_count) > *buflen)
fiemap->fm_extent_count = fiemap_size_to_count(*buflen);
if (!fiemap->fm_extent_count)
- count_local = 0;
+ fs.fs_cnt_need = 0;
+
+ fs.fs_finish = false;
+ fs.fs_enough = false;
+ fs.fs_cur_extent = 0;
/* Check each stripe */
- for (cur_stripe = start_stripe; stripe_count > 0;
+ for (cur_stripe = fs.fs_start_stripe; stripe_count > 0;
--stripe_count,
cur_stripe = (cur_stripe + 1) % lsm->lsm_stripe_count) {
- loff_t req_fm_len; /* Stores length of required mapping */
- loff_t len_mapped_single_call;
- loff_t lun_start;
- loff_t lun_end;
- loff_t obd_object_end;
- unsigned int ext_count;
-
- cur_stripe_wrap = cur_stripe;
-
- /* Find out range of mapping on this stripe */
- if (!(lov_stripe_intersects(lsm, cur_stripe, fm_start, fm_end,
- &lun_start, &obd_object_end)))
- continue;
-
- if (lov_oinfo_is_dummy(lsm->lsm_oinfo[cur_stripe])) {
- rc = -EIO;
- goto out;
- }
-
- /*
- * If this is a continuation FIEMAP call and we are on
- * starting stripe then lun_start needs to be set to
- * fm_end_offset
- */
- if (fm_end_offset && cur_stripe == start_stripe)
- lun_start = fm_end_offset;
-
- if (fm_length != ~0ULL) {
- /* Handle fm_start + fm_length overflow */
- if (fm_start + fm_length < fm_start)
- fm_length = ~0ULL - fm_start;
- lun_end = lov_size_to_stripe(lsm, fm_start + fm_length,
- cur_stripe);
- } else {
- lun_end = ~0ULL;
- }
-
- if (lun_start == lun_end)
- continue;
-
- req_fm_len = obd_object_end - lun_start;
- fm_local->fm_length = 0;
- len_mapped_single_call = 0;
-
- /* find lobsub object */
- subobj = lov_find_subobj(env, cl2lov(obj), lsm,
- cur_stripe);
- if (IS_ERR(subobj)) {
- rc = PTR_ERR(subobj);
+ rc = fiemap_for_stripe(env, obj, lsm, fiemap, buflen, fmkey,
+ cur_stripe, &fs);
+ if (rc < 0)
goto out;
- }
- /*
- * If the output buffer is very large and the objects have many
- * extents we may need to loop on a single OST repeatedly
- */
- ost_eof = false;
- ost_done = false;
- do {
- if (fiemap->fm_extent_count > 0) {
- /* Don't get too many extents. */
- if (current_extent + count_local >
- fiemap->fm_extent_count)
- count_local = fiemap->fm_extent_count -
- current_extent;
- }
-
- lun_start += len_mapped_single_call;
- fm_local->fm_length = req_fm_len -
- len_mapped_single_call;
- req_fm_len = fm_local->fm_length;
- fm_local->fm_extent_count = enough ? 1 : count_local;
- fm_local->fm_mapped_extents = 0;
- fm_local->fm_flags = fiemap->fm_flags;
-
- ost_index = lsm->lsm_oinfo[cur_stripe]->loi_ost_idx;
-
- if (ost_index < 0 ||
- ost_index >= lov->desc.ld_tgt_count) {
- rc = -EINVAL;
- goto obj_put;
- }
- /*
- * If OST is inactive, return extent with UNKNOWN
- * flag.
- */
- if (!lov->lov_tgts[ost_index]->ltd_active) {
- fm_local->fm_flags |= FIEMAP_EXTENT_LAST;
- fm_local->fm_mapped_extents = 1;
-
- lcl_fm_ext[0].fe_logical = lun_start;
- lcl_fm_ext[0].fe_length = obd_object_end -
- lun_start;
- lcl_fm_ext[0].fe_flags |= FIEMAP_EXTENT_UNKNOWN;
-
- goto inactive_tgt;
- }
-
- fm_local->fm_start = lun_start;
- fm_local->fm_flags &= ~FIEMAP_FLAG_DEVICE_ORDER;
- memcpy(&fmkey->lfik_fiemap, fm_local, sizeof(*fm_local));
- *buflen = fiemap_count_to_size(fm_local->fm_extent_count);
-
- rc = cl_object_fiemap(env, subobj, fmkey, fm_local,
- buflen);
- if (rc)
- goto obj_put;
-inactive_tgt:
- ext_count = fm_local->fm_mapped_extents;
- if (!ext_count) {
- ost_done = true;
- /*
- * If last stripe has hold at the end,
- * we need to return
- */
- if (cur_stripe_wrap == last_stripe) {
- fiemap->fm_mapped_extents = 0;
- goto finish;
- }
- break;
- } else if (enough) {
- /*
- * We've collected enough extents and there are
- * more extents after it.
- */
- goto finish;
- }
-
- /* If we just need num of extents, got to next device */
- if (!fiemap->fm_extent_count) {
- current_extent += ext_count;
- break;
- }
-
- /* prepare to copy retrived map extents */
- len_mapped_single_call =
- lcl_fm_ext[ext_count - 1].fe_logical -
- lun_start + lcl_fm_ext[ext_count - 1].fe_length;
-
- /* Have we finished mapping on this device? */
- if (req_fm_len <= len_mapped_single_call)
- ost_done = true;
-
- /*
- * Clear the EXTENT_LAST flag which can be present on
- * the last extent
- */
- if (lcl_fm_ext[ext_count - 1].fe_flags &
- FIEMAP_EXTENT_LAST)
- lcl_fm_ext[ext_count - 1].fe_flags &=
- ~FIEMAP_EXTENT_LAST;
-
- if (lov_stripe_size(lsm,
- lcl_fm_ext[ext_count - 1].fe_logical +
- lcl_fm_ext[ext_count - 1].fe_length,
- cur_stripe) >= fmkey->lfik_oa.o_size)
- ost_eof = true;
-
- fiemap_prepare_and_copy_exts(fiemap, lcl_fm_ext,
- ost_index, ext_count,
- current_extent);
- current_extent += ext_count;
-
- /* Ran out of available extents? */
- if (current_extent >= fiemap->fm_extent_count)
- enough = true;
- } while (!ost_done && !ost_eof);
-
- cl_object_put(env, subobj);
- subobj = NULL;
-
- if (cur_stripe_wrap == last_stripe)
- goto finish;
+ if (fs.fs_finish)
+ break;
} /* for each stripe */
-finish:
/*
* Indicate that we are returning device offsets unless file just has
* single stripe
@@ -1438,14 +1450,11 @@ finish:
* Check if we have reached the last stripe and whether mapping for that
* stripe is done.
*/
- if ((cur_stripe_wrap == last_stripe) && (ost_done || ost_eof))
- fiemap->fm_extents[current_extent - 1].fe_flags |=
+ if ((cur_stripe == fs.fs_last_stripe) && fs.fs_device_done)
+ fiemap->fm_extents[fs.fs_cur_extent - 1].fe_flags |=
FIEMAP_EXTENT_LAST;
skip_last_device_calc:
- fiemap->fm_mapped_extents = current_extent;
-obj_put:
- if (subobj)
- cl_object_put(env, subobj);
+ fiemap->fm_mapped_extents = fs.fs_cur_extent;
out:
kvfree(fm_local);
lov_lsm_put(lsm);
diff --git a/drivers/staging/lustre/lustre/lov/lov_offset.c b/drivers/staging/lustre/lustre/lov/lov_offset.c
index ecca74f..899d12c 100644
--- a/drivers/staging/lustre/lustre/lov/lov_offset.c
+++ b/drivers/staging/lustre/lustre/lov/lov_offset.c
@@ -32,9 +32,9 @@
#define DEBUG_SUBSYSTEM S_LOV
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
-#include "../include/obd_class.h"
+#include <obd_class.h>
#include "lov_internal.h"
diff --git a/drivers/staging/lustre/lustre/lov/lov_pack.c b/drivers/staging/lustre/lustre/lov/lov_pack.c
index 638b764..24fb2a9 100644
--- a/drivers/staging/lustre/lustre/lov/lov_pack.c
+++ b/drivers/staging/lustre/lustre/lov/lov_pack.c
@@ -38,14 +38,11 @@
#define DEBUG_SUBSYSTEM S_LOV
-#include "../include/lustre/lustre_idl.h"
-#include "../include/lustre/lustre_user.h"
-
-#include "../include/lustre_net.h"
-#include "../include/lustre_swab.h"
-#include "../include/obd.h"
-#include "../include/obd_class.h"
-#include "../include/obd_support.h"
+#include <lustre_net.h>
+#include <lustre_swab.h>
+#include <obd.h>
+#include <obd_class.h>
+#include <obd_support.h>
#include "lov_cl_internal.h"
#include "lov_internal.h"
diff --git a/drivers/staging/lustre/lustre/lov/lov_page.c b/drivers/staging/lustre/lustre/lov/lov_page.c
index 62ceb6d..de43c60 100644
--- a/drivers/staging/lustre/lustre/lov/lov_page.c
+++ b/drivers/staging/lustre/lustre/lov/lov_page.c
@@ -100,7 +100,6 @@ int lov_page_init_raid0(const struct lu_env *env, struct cl_object *obj,
break;
}
}
- lov_sub_put(sub);
return rc;
}
diff --git a/drivers/staging/lustre/lustre/lov/lov_pool.c b/drivers/staging/lustre/lustre/lov/lov_pool.c
index 39daa17..d774ee2 100644
--- a/drivers/staging/lustre/lustre/lov/lov_pool.c
+++ b/drivers/staging/lustre/lustre/lov/lov_pool.c
@@ -40,9 +40,9 @@
#define DEBUG_SUBSYSTEM S_LOV
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
-#include "../include/obd.h"
+#include <obd.h>
#include "lov_internal.h"
#define pool_tgt(_p, _i) \
diff --git a/drivers/staging/lustre/lustre/lov/lov_request.c b/drivers/staging/lustre/lustre/lov/lov_request.c
index 3a74791..9d3b3f3 100644
--- a/drivers/staging/lustre/lustre/lov/lov_request.c
+++ b/drivers/staging/lustre/lustre/lov/lov_request.c
@@ -32,10 +32,10 @@
#define DEBUG_SUBSYSTEM S_LOV
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
-#include "../include/obd_class.h"
-#include "../include/lustre/lustre_idl.h"
+#include <obd_class.h>
+#include <uapi/linux/lustre/lustre_idl.h>
#include "lov_internal.h"
static void lov_init_set(struct lov_request_set *set)
@@ -43,13 +43,10 @@ static void lov_init_set(struct lov_request_set *set)
set->set_count = 0;
atomic_set(&set->set_completes, 0);
atomic_set(&set->set_success, 0);
- atomic_set(&set->set_finish_checked, 0);
INIT_LIST_HEAD(&set->set_list);
- atomic_set(&set->set_refcount, 1);
- init_waitqueue_head(&set->set_waitq);
}
-void lov_finish_set(struct lov_request_set *set)
+static void lov_finish_set(struct lov_request_set *set)
{
struct list_head *pos, *n;
@@ -66,32 +63,12 @@ void lov_finish_set(struct lov_request_set *set)
kfree(set);
}
-static int lov_set_finished(struct lov_request_set *set, int idempotent)
-{
- int completes = atomic_read(&set->set_completes);
-
- CDEBUG(D_INFO, "check set %d/%d\n", completes, set->set_count);
-
- if (completes == set->set_count) {
- if (idempotent)
- return 1;
- if (atomic_inc_return(&set->set_finish_checked) == 1)
- return 1;
- }
- return 0;
-}
-
static void lov_update_set(struct lov_request_set *set,
struct lov_request *req, int rc)
{
- req->rq_complete = 1;
- req->rq_rc = rc;
-
atomic_inc(&set->set_completes);
if (rc == 0)
atomic_inc(&set->set_success);
-
- wake_up(&set->set_waitq);
}
static void lov_set_add_req(struct lov_request *req,
@@ -173,8 +150,8 @@ out:
(tot) += (add); \
} while (0)
-int lov_fini_statfs(struct obd_device *obd, struct obd_statfs *osfs,
- int success)
+static int lov_fini_statfs(struct obd_device *obd, struct obd_statfs *osfs,
+ int success)
{
if (success) {
__u32 expected_stripes = lov_get_stripecnt(&obd->u.lov,
@@ -205,7 +182,9 @@ int lov_fini_statfs_set(struct lov_request_set *set)
rc = lov_fini_statfs(set->set_obd, set->set_oi->oi_osfs,
atomic_read(&set->set_success));
}
- lov_put_reqset(set);
+
+ lov_finish_set(set);
+
return rc;
}
@@ -307,14 +286,7 @@ static int cb_statfs_update(void *cookie, int rc)
out_update:
lov_update_statfs(osfs, lov_sfs, success);
obd_putref(lovobd);
-
out:
- if (set->set_oi->oi_flags & OBD_STATFS_PTLRPCD &&
- lov_set_finished(set, 0)) {
- lov_statfs_interpret(NULL, set, set->set_count !=
- atomic_read(&set->set_success));
- }
-
return 0;
}
diff --git a/drivers/staging/lustre/lustre/lov/lovsub_dev.c b/drivers/staging/lustre/lustre/lov/lovsub_dev.c
index 5d6536f..d4646a0 100644
--- a/drivers/staging/lustre/lustre/lov/lovsub_dev.c
+++ b/drivers/staging/lustre/lustre/lov/lovsub_dev.c
@@ -77,7 +77,6 @@ static struct lu_device *lovsub_device_fini(const struct lu_env *env,
lsd = lu2lovsub_dev(d);
next = cl2lu_dev(lsd->acid_next);
- lsd->acid_super = NULL;
lsd->acid_next = NULL;
return next;
}
diff --git a/drivers/staging/lustre/lustre/lov/lovsub_io.c b/drivers/staging/lustre/lustre/lov/lovsub_io.c
deleted file mode 100644
index 6a98202..0000000
--- a/drivers/staging/lustre/lustre/lov/lovsub_io.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * Implementation of cl_io for LOVSUB layer.
- *
- * Author: Nikita Danilov <nikita.danilov@sun.com>
- */
-
-#define DEBUG_SUBSYSTEM S_LOV
-
-#include "lov_cl_internal.h"
-
-/** \addtogroup lov
- * @{
- */
-
-/*****************************************************************************
- *
- * Lovsub io operations.
- *
- */
-
-/* All trivial */
-
-/** @} lov */
diff --git a/drivers/staging/lustre/lustre/lov/lovsub_lock.c b/drivers/staging/lustre/lustre/lov/lovsub_lock.c
index 38f9b73..d29f0bb 100644
--- a/drivers/staging/lustre/lustre/lov/lovsub_lock.c
+++ b/drivers/staging/lustre/lustre/lov/lovsub_lock.c
@@ -54,7 +54,6 @@ static void lovsub_lock_fini(const struct lu_env *env,
struct lovsub_lock *lsl;
lsl = cl2lovsub_lock(slice);
- LASSERT(list_empty(&lsl->lss_parents));
kmem_cache_free(lovsub_lock_kmem, lsl);
}
@@ -70,7 +69,6 @@ int lovsub_lock_init(const struct lu_env *env, struct cl_object *obj,
lsk = kmem_cache_zalloc(lovsub_lock_kmem, GFP_NOFS);
if (lsk) {
- INIT_LIST_HEAD(&lsk->lss_parents);
cl_lock_slice_add(lock, &lsk->lss_cl, obj, &lovsub_lock_ops);
result = 0;
} else {
diff --git a/drivers/staging/lustre/lustre/lov/lproc_lov.c b/drivers/staging/lustre/lustre/lov/lproc_lov.c
index eb6d30d..9bb7e9e 100644
--- a/drivers/staging/lustre/lustre/lov/lproc_lov.c
+++ b/drivers/staging/lustre/lustre/lov/lproc_lov.c
@@ -32,8 +32,8 @@
#define DEBUG_SUBSYSTEM S_CLASS
#include <linux/statfs.h>
-#include "../include/lprocfs_status.h"
-#include "../include/obd_class.h"
+#include <lprocfs_status.h>
+#include <obd_class.h>
#include <linux/seq_file.h>
#include "lov_internal.h"
@@ -279,7 +279,7 @@ static struct attribute *lov_attrs[] = {
NULL,
};
-static struct attribute_group lov_attr_group = {
+static const struct attribute_group lov_attr_group = {
.attrs = lov_attrs,
};
diff --git a/drivers/staging/lustre/lustre/mdc/Makefile b/drivers/staging/lustre/lustre/mdc/Makefile
index 99ba9ff..c7bc335 100644
--- a/drivers/staging/lustre/lustre/mdc/Makefile
+++ b/drivers/staging/lustre/lustre/mdc/Makefile
@@ -1,2 +1,5 @@
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/include
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/lustre/include
+
obj-$(CONFIG_LUSTRE_FS) += mdc.o
mdc-y := mdc_request.o mdc_reint.o mdc_lib.o mdc_locks.o lproc_mdc.o
diff --git a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c
index 9021c46..f685137 100644
--- a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c
+++ b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c
@@ -32,8 +32,8 @@
#define DEBUG_SUBSYSTEM S_CLASS
#include <linux/vfs.h>
-#include "../include/obd_class.h"
-#include "../include/lprocfs_status.h"
+#include <obd_class.h>
+#include <lprocfs_status.h>
#include "mdc_internal.h"
static ssize_t active_show(struct kobject *kobj, struct attribute *attr,
@@ -57,7 +57,7 @@ static ssize_t active_store(struct kobject *kobj, struct attribute *attr,
if (rc)
return rc;
- if (val < 0 || val > 1)
+ if (val > 1)
return -ERANGE;
/* opposite senses */
@@ -219,7 +219,7 @@ static struct attribute *mdc_attrs[] = {
NULL,
};
-static struct attribute_group mdc_attr_group = {
+static const struct attribute_group mdc_attr_group = {
.attrs = mdc_attrs,
};
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_internal.h b/drivers/staging/lustre/lustre/mdc/mdc_internal.h
index fecedc88..cbf0115 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_internal.h
+++ b/drivers/staging/lustre/lustre/mdc/mdc_internal.h
@@ -33,7 +33,7 @@
#ifndef _MDC_INTERNAL_H
#define _MDC_INTERNAL_H
-#include "../include/lustre_mdc.h"
+#include <lustre_mdc.h>
void lprocfs_mdc_init_vars(struct lprocfs_static_vars *lvars);
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_lib.c b/drivers/staging/lustre/lustre/mdc/mdc_lib.c
index b1853ff..ba13f089 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_lib.c
+++ b/drivers/staging/lustre/lustre/mdc/mdc_lib.c
@@ -31,10 +31,16 @@
*/
#define DEBUG_SUBSYSTEM S_MDC
-#include "../include/lustre_net.h"
-#include "../include/lustre/lustre_idl.h"
+#include <lustre_net.h>
+#include <uapi/linux/lustre/lustre_idl.h>
#include "mdc_internal.h"
+static void set_mrc_cr_flags(struct mdt_rec_create *mrc, u64 flags)
+{
+ mrc->cr_flags_l = (u32)(flags & 0xFFFFFFFFUll);
+ mrc->cr_flags_h = (u32)(flags >> 32);
+}
+
static void __mdc_pack_body(struct mdt_body *b, __u32 suppgid)
{
b->mbo_suppgid = suppgid;
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_locks.c b/drivers/staging/lustre/lustre/mdc/mdc_locks.c
index 3eb66ce..cbfea3d 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_locks.c
+++ b/drivers/staging/lustre/lustre/mdc/mdc_locks.c
@@ -32,17 +32,17 @@
#define DEBUG_SUBSYSTEM S_MDC
-# include <linux/module.h>
-
-#include "../include/lustre_intent.h"
-#include "../include/obd.h"
-#include "../include/obd_class.h"
-#include "../include/lustre_dlm.h"
-#include "../include/lustre_fid.h"
-#include "../include/lustre_mdc.h"
-#include "../include/lustre_net.h"
-#include "../include/lustre_req_layout.h"
-#include "../include/lustre_swab.h"
+#include <linux/module.h>
+
+#include <lustre_intent.h>
+#include <obd.h>
+#include <obd_class.h>
+#include <lustre_dlm.h>
+#include <lustre_fid.h>
+#include <lustre_mdc.h>
+#include <lustre_net.h>
+#include <lustre_req_layout.h>
+#include <lustre_swab.h>
#include "mdc_internal.h"
@@ -1030,7 +1030,7 @@ int mdc_revalidate_lock(struct obd_export *exp, struct lookup_intent *it,
* If we're performing a creation, that means that unless the creation
* failed with EEXIST, we should fake up a negative dentry.
*
- * For everything else, we want to lookup to succeed.
+ * For everything else, we want the lookup to succeed.
*
* One additional note: if CREATE or OPEN succeeded, we add an extra
* reference to the request because we need to keep it around until
@@ -1040,7 +1040,7 @@ int mdc_revalidate_lock(struct obd_export *exp, struct lookup_intent *it,
* exactly what it_status refers to.
*
* If DISP_OPEN_OPEN is set, then it_status refers to the open() call,
- * otherwise if DISP_OPEN_CREATE is set, then it status is the
+ * otherwise if DISP_OPEN_CREATE is set, then it_status is the
* creation failure mode. In either case, one of DISP_LOOKUP_NEG or
* DISP_LOOKUP_POS will be set, indicating whether the child lookup
* was successful.
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_reint.c b/drivers/staging/lustre/lustre/mdc/mdc_reint.c
index 2287bd4..f45c91d 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_reint.c
+++ b/drivers/staging/lustre/lustre/mdc/mdc_reint.c
@@ -35,9 +35,9 @@
# include <linux/module.h>
# include <linux/kernel.h>
-#include "../include/obd_class.h"
+#include <obd_class.h>
#include "mdc_internal.h"
-#include "../include/lustre_fid.h"
+#include <lustre_fid.h>
/* mdc_setattr does its own semaphore handling */
static int mdc_reint(struct ptlrpc_request *request, int level)
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c
index 1a3fa1b..6ef8dde 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_request.c
+++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c
@@ -38,18 +38,19 @@
# include <linux/init.h>
# include <linux/utsname.h>
-#include "../include/cl_object.h"
-#include "../include/llog_swab.h"
-#include "../include/lprocfs_status.h"
-#include "../include/lustre_acl.h"
-#include "../include/lustre_fid.h"
-#include "../include/lustre/lustre_ioctl.h"
-#include "../include/lustre_kernelcomm.h"
-#include "../include/lustre_lmv.h"
-#include "../include/lustre_log.h"
-#include "../include/lustre_param.h"
-#include "../include/lustre_swab.h"
-#include "../include/obd_class.h"
+#include <lustre_errno.h>
+#include <cl_object.h>
+#include <llog_swab.h>
+#include <lprocfs_status.h>
+#include <lustre_acl.h>
+#include <lustre_fid.h>
+#include <uapi/linux/lustre/lustre_ioctl.h>
+#include <lustre_kernelcomm.h>
+#include <lustre_lmv.h>
+#include <lustre_log.h>
+#include <uapi/linux/lustre/lustre_param.h>
+#include <lustre_swab.h>
+#include <obd_class.h>
#include "mdc_internal.h"
diff --git a/drivers/staging/lustre/lustre/mgc/Makefile b/drivers/staging/lustre/lustre/mgc/Makefile
index 8ea29a8..8abf108 100644
--- a/drivers/staging/lustre/lustre/mgc/Makefile
+++ b/drivers/staging/lustre/lustre/mgc/Makefile
@@ -1,2 +1,5 @@
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/include
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/lustre/include
+
obj-$(CONFIG_LUSTRE_FS) += mgc.o
mgc-y := mgc_request.o lproc_mgc.o
diff --git a/drivers/staging/lustre/lustre/mgc/lproc_mgc.c b/drivers/staging/lustre/lustre/mgc/lproc_mgc.c
index 0735220..2ec2d7f 100644
--- a/drivers/staging/lustre/lustre/mgc/lproc_mgc.c
+++ b/drivers/staging/lustre/lustre/mgc/lproc_mgc.c
@@ -32,8 +32,8 @@
#define DEBUG_SUBSYSTEM S_CLASS
#include <linux/vfs.h>
-#include "../include/obd_class.h"
-#include "../include/lprocfs_status.h"
+#include <obd_class.h>
+#include <lprocfs_status.h>
#include "mgc_internal.h"
LPROC_SEQ_FOPS_RO_TYPE(mgc, connect_flags);
diff --git a/drivers/staging/lustre/lustre/mgc/mgc_internal.h b/drivers/staging/lustre/lustre/mgc/mgc_internal.h
index f146f75..7a2f2b7 100644
--- a/drivers/staging/lustre/lustre/mgc/mgc_internal.h
+++ b/drivers/staging/lustre/lustre/mgc/mgc_internal.h
@@ -33,12 +33,11 @@
#ifndef _MGC_INTERNAL_H
#define _MGC_INTERNAL_H
-#include "../../include/linux/libcfs/libcfs.h"
-#include "../include/lustre/lustre_idl.h"
-#include "../include/lustre_lib.h"
-#include "../include/lustre_dlm.h"
-#include "../include/lustre_log.h"
-#include "../include/lustre_export.h"
+#include <linux/libcfs/libcfs.h>
+#include <lustre_lib.h>
+#include <lustre_dlm.h>
+#include <lustre_log.h>
+#include <lustre_export.h>
void lprocfs_mgc_init_vars(struct lprocfs_static_vars *lvars);
int lprocfs_mgc_rd_ir_state(struct seq_file *m, void *data);
diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c
index eee0b66..3d2b969 100644
--- a/drivers/staging/lustre/lustre/mgc/mgc_request.c
+++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c
@@ -39,12 +39,12 @@
#include <linux/module.h>
-#include "../include/lprocfs_status.h"
-#include "../include/lustre_dlm.h"
-#include "../include/lustre_disk.h"
-#include "../include/lustre_log.h"
-#include "../include/lustre_swab.h"
-#include "../include/obd_class.h"
+#include <lprocfs_status.h>
+#include <lustre_dlm.h>
+#include <lustre_disk.h>
+#include <lustre_log.h>
+#include <lustre_swab.h>
+#include <obd_class.h>
#include "mgc_internal.h"
@@ -288,7 +288,7 @@ config_log_add(struct obd_device *obd, char *logname,
struct config_llog_data *cld;
struct config_llog_data *sptlrpc_cld;
struct config_llog_data *params_cld;
- bool locked = false;
+ struct config_llog_data *recover_cld = NULL;
char seclogname[32];
char *ptr;
int rc;
@@ -333,20 +333,14 @@ config_log_add(struct obd_device *obd, char *logname,
goto out_params;
}
- cld->cld_sptlrpc = sptlrpc_cld;
- cld->cld_params = params_cld;
-
LASSERT(lsi->lsi_lmd);
if (!(lsi->lsi_lmd->lmd_flags & LMD_FLG_NOIR)) {
- struct config_llog_data *recover_cld;
-
ptr = strrchr(seclogname, '-');
if (ptr) {
*ptr = 0;
} else {
CERROR("%s: sptlrpc log name not correct, %s: rc = %d\n",
obd->obd_name, seclogname, -EINVAL);
- config_log_put(cld);
rc = -EINVAL;
goto out_cld;
}
@@ -355,14 +349,10 @@ config_log_add(struct obd_device *obd, char *logname,
rc = PTR_ERR(recover_cld);
goto out_cld;
}
-
- mutex_lock(&cld->cld_lock);
- locked = true;
- cld->cld_recover = recover_cld;
}
- if (!locked)
- mutex_lock(&cld->cld_lock);
+ mutex_lock(&cld->cld_lock);
+ cld->cld_recover = recover_cld;
cld->cld_params = params_cld;
cld->cld_sptlrpc = sptlrpc_cld;
mutex_unlock(&cld->cld_lock);
@@ -1165,6 +1155,7 @@ static int mgc_apply_recover_logs(struct obd_device *mgc,
char *cname;
char *params;
char *uuid;
+ size_t len;
rc = -EINVAL;
if (datalen < sizeof(*entry))
@@ -1293,17 +1284,19 @@ static int mgc_apply_recover_logs(struct obd_device *mgc,
lustre_cfg_bufs_set_string(&bufs, 1, params);
rc = -ENOMEM;
- lcfg = lustre_cfg_new(LCFG_PARAM, &bufs);
- if (IS_ERR(lcfg)) {
- CERROR("mgc: cannot allocate memory\n");
+ len = lustre_cfg_len(bufs.lcfg_bufcount, bufs.lcfg_buflen);
+ lcfg = kzalloc(len, GFP_NOFS);
+ if (!lcfg) {
+ rc = -ENOMEM;
break;
}
+ lustre_cfg_init(lcfg, LCFG_PARAM, &bufs);
CDEBUG(D_INFO, "ir apply logs %lld/%lld for %s -> %s\n",
prev_version, max_version, obdname, params);
rc = class_process_config(lcfg);
- lustre_cfg_free(lcfg);
+ kfree(lcfg);
if (rc)
CDEBUG(D_INFO, "process config for %s error %d\n",
obdname, rc);
diff --git a/drivers/staging/lustre/lustre/obdclass/Makefile b/drivers/staging/lustre/lustre/obdclass/Makefile
index af570c0..fa0ad654 100644
--- a/drivers/staging/lustre/lustre/obdclass/Makefile
+++ b/drivers/staging/lustre/lustre/obdclass/Makefile
@@ -1,3 +1,6 @@
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/include
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/lustre/include
+
obj-$(CONFIG_LUSTRE_FS) += obdclass.o
obdclass-y := linux/linux-module.o linux/linux-sysctl.o \
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
index ee7d677..2a70e21 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
@@ -37,12 +37,12 @@
#define DEBUG_SUBSYSTEM S_CLASS
-#include "../include/obd_class.h"
-#include "../include/obd_support.h"
-#include "../include/lustre_fid.h"
+#include <obd_class.h>
+#include <obd_support.h>
+#include <lustre_fid.h>
#include <linux/list.h>
#include <linux/sched.h>
-#include "../include/cl_object.h"
+#include <cl_object.h>
#include "cl_internal.h"
/*****************************************************************************
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_lock.c b/drivers/staging/lustre/lustre/obdclass/cl_lock.c
index a343e3a..20e6405 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_lock.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_lock.c
@@ -37,11 +37,11 @@
#define DEBUG_SUBSYSTEM S_CLASS
-#include "../include/obd_class.h"
-#include "../include/obd_support.h"
-#include "../include/lustre_fid.h"
+#include <obd_class.h>
+#include <obd_support.h>
+#include <lustre_fid.h>
#include <linux/list.h>
-#include "../include/cl_object.h"
+#include <cl_object.h>
#include "cl_internal.h"
static void cl_lock_trace0(int level, const struct lu_env *env,
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
index 08e55d4..95c7fa3 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
@@ -46,15 +46,15 @@
#define DEBUG_SUBSYSTEM S_CLASS
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
/* class_put_type() */
-#include "../include/obd_class.h"
-#include "../include/obd_support.h"
-#include "../include/lustre_fid.h"
+#include <obd_class.h>
+#include <obd_support.h>
+#include <lustre_fid.h>
#include <linux/list.h>
-#include "../../include/linux/libcfs/libcfs_hash.h" /* for cfs_hash stuff */
-#include "../include/cl_object.h"
-#include "../include/lu_object.h"
+#include <linux/libcfs/libcfs_hash.h> /* for cfs_hash stuff */
+#include <cl_object.h>
+#include <lu_object.h>
#include "cl_internal.h"
static struct kmem_cache *cl_env_kmem;
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c
index 6b8c41b..3dc084c 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_page.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c
@@ -37,12 +37,12 @@
#define DEBUG_SUBSYSTEM S_CLASS
-#include "../../include/linux/libcfs/libcfs.h"
-#include "../include/obd_class.h"
-#include "../include/obd_support.h"
+#include <linux/libcfs/libcfs.h>
+#include <obd_class.h>
+#include <obd_support.h>
#include <linux/list.h>
-#include "../include/cl_object.h"
+#include <cl_object.h>
#include "cl_internal.h"
static void cl_page_delete0(const struct lu_env *env, struct cl_page *pg);
diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c
index 76e1ee8..2df218b 100644
--- a/drivers/staging/lustre/lustre/obdclass/class_obd.c
+++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c
@@ -33,14 +33,14 @@
#define DEBUG_SUBSYSTEM S_CLASS
# include <linux/atomic.h>
-#include "../include/obd_support.h"
-#include "../include/obd_class.h"
-#include "../../include/linux/lnet/lnetctl.h"
-#include "../include/lustre_debug.h"
-#include "../include/lprocfs_status.h"
+#include <obd_support.h>
+#include <obd_class.h>
+#include <uapi/linux/lnet/lnetctl.h>
+#include <lustre_debug.h>
+#include <lprocfs_status.h>
#include <linux/list.h>
-#include "../include/cl_object.h"
-#include "../include/lustre/lustre_ioctl.h"
+#include <cl_object.h>
+#include <uapi/linux/lustre/lustre_ioctl.h>
#include "llog_internal.h"
struct obd_device *obd_devs[MAX_OBD_DEVICES];
@@ -180,7 +180,8 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg)
err = -ENOMEM;
goto out;
}
- err = copy_from_user(lcfg, data->ioc_pbuf1, data->ioc_plen1);
+ if (copy_from_user(lcfg, data->ioc_pbuf1, data->ioc_plen1))
+ err = -EFAULT;
if (!err)
err = lustre_cfg_sanity_check(lcfg, data->ioc_plen1);
if (!err)
@@ -206,8 +207,7 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg)
memcpy(data->ioc_bulk, LUSTRE_VERSION_STRING,
strlen(LUSTRE_VERSION_STRING) + 1);
- err = obd_ioctl_popdata((void __user *)arg, data, len);
- if (err)
+ if (copy_to_user((void __user *)arg, data, len))
err = -EFAULT;
goto out;
@@ -225,9 +225,7 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg)
goto out;
}
- err = obd_ioctl_popdata((void __user *)arg, data,
- sizeof(*data));
- if (err)
+ if (copy_to_user((void __user *)arg, data, sizeof(*data)))
err = -EFAULT;
goto out;
}
@@ -263,9 +261,8 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg)
CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1,
dev);
- err = obd_ioctl_popdata((void __user *)arg, data,
- sizeof(*data));
- if (err)
+
+ if (copy_to_user((void __user *)arg, data, sizeof(*data)))
err = -EFAULT;
goto out;
}
@@ -304,9 +301,9 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg)
(int)index, status, obd->obd_type->typ_name,
obd->obd_name, obd->obd_uuid.uuid,
atomic_read(&obd->obd_refcount));
- err = obd_ioctl_popdata((void __user *)arg, data, len);
- err = 0;
+ if (copy_to_user((void __user *)arg, data, len))
+ err = -EFAULT;
goto out;
}
}
@@ -361,16 +358,14 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg)
if (err)
goto out;
- err = obd_ioctl_popdata((void __user *)arg, data, len);
- if (err)
+ if (copy_to_user((void __user *)arg, data, len))
err = -EFAULT;
goto out;
}
}
out:
- if (buf)
- obd_ioctl_freedata(buf, len);
+ kvfree(buf);
return err;
} /* class_handle_ioctl */
@@ -453,7 +448,7 @@ static int __init obdclass_init(void)
obd_zombie_impexp_init();
err = obd_init_checks();
- if (err == -EOVERFLOW)
+ if (err)
return err;
class_init_uuidlist();
diff --git a/drivers/staging/lustre/lustre/obdclass/debug.c b/drivers/staging/lustre/lustre/obdclass/debug.c
index 0bd4ad2..7964cad 100644
--- a/drivers/staging/lustre/lustre/obdclass/debug.c
+++ b/drivers/staging/lustre/lustre/obdclass/debug.c
@@ -38,9 +38,9 @@
#include <asm/unaligned.h>
-#include "../include/obd_support.h"
-#include "../include/lustre_debug.h"
-#include "../include/lustre_net.h"
+#include <obd_support.h>
+#include <lustre_debug.h>
+#include <lustre_net.h>
#define LPDS sizeof(__u64)
int block_debug_setup(void *addr, int len, __u64 off, __u64 id)
diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c
index fa0d38d..739bfb9 100644
--- a/drivers/staging/lustre/lustre/obdclass/genops.c
+++ b/drivers/staging/lustre/lustre/obdclass/genops.c
@@ -36,9 +36,9 @@
*/
#define DEBUG_SUBSYSTEM S_CLASS
-#include "../include/obd_class.h"
-#include "../include/lprocfs_status.h"
-#include "../include/lustre_kernelcomm.h"
+#include <obd_class.h>
+#include <lprocfs_status.h>
+#include <lustre_kernelcomm.h>
spinlock_t obd_types_lock;
diff --git a/drivers/staging/lustre/lustre/obdclass/kernelcomm.c b/drivers/staging/lustre/lustre/obdclass/kernelcomm.c
index a0f65c4..8f0707a 100644
--- a/drivers/staging/lustre/lustre/obdclass/kernelcomm.c
+++ b/drivers/staging/lustre/lustre/obdclass/kernelcomm.c
@@ -38,8 +38,8 @@
#define DEBUG_SUBSYSTEM S_CLASS
#define D_KUC D_OTHER
-#include "../include/obd_support.h"
-#include "../include/lustre_kernelcomm.h"
+#include <obd_support.h>
+#include <lustre_kernelcomm.h>
/**
* libcfs_kkuc_msg_put - send an message from kernel to userspace
diff --git a/drivers/staging/lustre/lustre/obdclass/linkea.c b/drivers/staging/lustre/lustre/obdclass/linkea.c
index 0b1d2f0..9af86d3 100644
--- a/drivers/staging/lustre/lustre/obdclass/linkea.c
+++ b/drivers/staging/lustre/lustre/obdclass/linkea.c
@@ -26,9 +26,9 @@
* Author: Di Wang <di.wang@intel.com>
*/
-#include "../include/lustre/lustre_idl.h"
-#include "../include/obd.h"
-#include "../include/lustre_linkea.h"
+#include <uapi/linux/lustre/lustre_idl.h>
+#include <obd.h>
+#include <lustre_linkea.h>
int linkea_data_new(struct linkea_data *ldata, struct lu_buf *buf)
{
@@ -39,6 +39,8 @@ int linkea_data_new(struct linkea_data *ldata, struct lu_buf *buf)
ldata->ld_leh->leh_magic = LINK_EA_MAGIC;
ldata->ld_leh->leh_len = sizeof(struct link_ea_header);
ldata->ld_leh->leh_reccount = 0;
+ ldata->ld_leh->leh_overflow_time = 0;
+ ldata->ld_leh->leh_padding = 0;
return 0;
}
EXPORT_SYMBOL(linkea_data_new);
@@ -53,11 +55,15 @@ int linkea_init(struct linkea_data *ldata)
leh->leh_magic = LINK_EA_MAGIC;
leh->leh_reccount = __swab32(leh->leh_reccount);
leh->leh_len = __swab64(leh->leh_len);
- /* entries are swabbed by linkea_entry_unpack */
+ leh->leh_overflow_time = __swab32(leh->leh_overflow_time);
+ leh->leh_padding = __swab32(leh->leh_padding);
+ /* individual entries are swabbed by linkea_entry_unpack() */
}
+
if (leh->leh_magic != LINK_EA_MAGIC)
return -EINVAL;
- if (leh->leh_reccount == 0)
+
+ if (leh->leh_reccount == 0 && leh->leh_overflow_time == 0)
return -ENODATA;
ldata->ld_leh = leh;
@@ -65,6 +71,18 @@ int linkea_init(struct linkea_data *ldata)
}
EXPORT_SYMBOL(linkea_init);
+int linkea_init_with_rec(struct linkea_data *ldata)
+{
+ int rc;
+
+ rc = linkea_init(ldata);
+ if (!rc && ldata->ld_leh->leh_reccount == 0)
+ rc = -ENODATA;
+
+ return rc;
+}
+EXPORT_SYMBOL(linkea_init_with_rec);
+
/**
* Pack a link_ea_entry.
* All elements are stored as chars to avoid alignment issues.
@@ -94,6 +112,8 @@ EXPORT_SYMBOL(linkea_entry_pack);
void linkea_entry_unpack(const struct link_ea_entry *lee, int *reclen,
struct lu_name *lname, struct lu_fid *pfid)
{
+ LASSERT(lee);
+
*reclen = (lee->lee_reclen[0] << 8) | lee->lee_reclen[1];
memcpy(pfid, &lee->lee_parent_fid, sizeof(*pfid));
fid_be_to_cpu(pfid, pfid);
@@ -110,25 +130,44 @@ EXPORT_SYMBOL(linkea_entry_unpack);
int linkea_add_buf(struct linkea_data *ldata, const struct lu_name *lname,
const struct lu_fid *pfid)
{
- LASSERT(ldata->ld_leh);
+ struct link_ea_header *leh = ldata->ld_leh;
+ int reclen;
+
+ LASSERT(leh);
if (!lname || !pfid)
return -EINVAL;
- ldata->ld_reclen = lname->ln_namelen + sizeof(struct link_ea_entry);
- if (ldata->ld_leh->leh_len + ldata->ld_reclen >
- ldata->ld_buf->lb_len) {
+ reclen = lname->ln_namelen + sizeof(struct link_ea_entry);
+ if (unlikely(leh->leh_len + reclen > MAX_LINKEA_SIZE)) {
+ /*
+ * Use 32-bits to save the overflow time, although it will
+ * shrink the ktime_get_real_seconds() returned 64-bits value
+ * to 32-bits value, it is still quite large and can be used
+ * for about 140 years. That is enough.
+ */
+ leh->leh_overflow_time = ktime_get_real_seconds();
+ if (unlikely(leh->leh_overflow_time == 0))
+ leh->leh_overflow_time++;
+
+ CDEBUG(D_INODE, "No enough space to hold linkea entry '" DFID ": %.*s' at %u\n",
+ PFID(pfid), lname->ln_namelen,
+ lname->ln_name, leh->leh_overflow_time);
+ return 0;
+ }
+
+ if (leh->leh_len + reclen > ldata->ld_buf->lb_len) {
if (lu_buf_check_and_grow(ldata->ld_buf,
- ldata->ld_leh->leh_len +
- ldata->ld_reclen) < 0)
+ leh->leh_len + reclen) < 0)
return -ENOMEM;
+
+ leh = ldata->ld_leh = ldata->ld_buf->lb_buf;
}
- ldata->ld_leh = ldata->ld_buf->lb_buf;
- ldata->ld_lee = ldata->ld_buf->lb_buf + ldata->ld_leh->leh_len;
+ ldata->ld_lee = ldata->ld_buf->lb_buf + leh->leh_len;
ldata->ld_reclen = linkea_entry_pack(ldata->ld_lee, lname, pfid);
- ldata->ld_leh->leh_len += ldata->ld_reclen;
- ldata->ld_leh->leh_reccount++;
+ leh->leh_len += ldata->ld_reclen;
+ leh->leh_reccount++;
CDEBUG(D_INODE, "New link_ea name '" DFID ":%.*s' is added\n",
PFID(pfid), lname->ln_namelen, lname->ln_name);
return 0;
@@ -139,6 +178,7 @@ EXPORT_SYMBOL(linkea_add_buf);
void linkea_del_buf(struct linkea_data *ldata, const struct lu_name *lname)
{
LASSERT(ldata->ld_leh && ldata->ld_lee);
+ LASSERT(ldata->ld_leh->leh_reccount > 0);
ldata->ld_leh->leh_reccount--;
ldata->ld_leh->leh_len -= ldata->ld_reclen;
@@ -174,8 +214,9 @@ int linkea_links_find(struct linkea_data *ldata, const struct lu_name *lname,
LASSERT(ldata->ld_leh);
- /* link #0 */
- ldata->ld_lee = (struct link_ea_entry *)(ldata->ld_leh + 1);
+ /* link #0, if leh_reccount == 0 we skip the loop and return -ENOENT */
+ if (likely(ldata->ld_leh->leh_reccount > 0))
+ ldata->ld_lee = (struct link_ea_entry *)(ldata->ld_leh + 1);
for (count = 0; count < ldata->ld_leh->leh_reccount; count++) {
linkea_entry_unpack(ldata->ld_lee, &ldata->ld_reclen,
diff --git a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
index 9f5e829..6df9111 100644
--- a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
+++ b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
@@ -60,13 +60,91 @@
#include <linux/seq_file.h>
#include <linux/kobject.h>
-#include "../../../include/linux/libcfs/libcfs.h"
-#include "../../../include/linux/lnet/lnetctl.h"
-#include "../../include/obd_support.h"
-#include "../../include/obd_class.h"
-#include "../../include/lprocfs_status.h"
-#include "../../include/lustre/lustre_ioctl.h"
-#include "../../include/lustre_ver.h"
+#include <linux/libcfs/libcfs.h>
+#include <uapi/linux/lnet/lnetctl.h>
+#include <obd_support.h>
+#include <obd_class.h>
+#include <lprocfs_status.h>
+#include <uapi/linux/lustre/lustre_ioctl.h>
+#include <uapi/linux/lustre/lustre_ver.h>
+
+#define OBD_MAX_IOCTL_BUFFER 8192
+
+static int obd_ioctl_is_invalid(struct obd_ioctl_data *data)
+{
+ if (data->ioc_len > BIT(30)) {
+ CERROR("OBD ioctl: ioc_len larger than 1<<30\n");
+ return 1;
+ }
+
+ if (data->ioc_inllen1 > BIT(30)) {
+ CERROR("OBD ioctl: ioc_inllen1 larger than 1<<30\n");
+ return 1;
+ }
+
+ if (data->ioc_inllen2 > BIT(30)) {
+ CERROR("OBD ioctl: ioc_inllen2 larger than 1<<30\n");
+ return 1;
+ }
+
+ if (data->ioc_inllen3 > BIT(30)) {
+ CERROR("OBD ioctl: ioc_inllen3 larger than 1<<30\n");
+ return 1;
+ }
+
+ if (data->ioc_inllen4 > BIT(30)) {
+ CERROR("OBD ioctl: ioc_inllen4 larger than 1<<30\n");
+ return 1;
+ }
+
+ if (data->ioc_inlbuf1 && data->ioc_inllen1 == 0) {
+ CERROR("OBD ioctl: inlbuf1 pointer but 0 length\n");
+ return 1;
+ }
+
+ if (data->ioc_inlbuf2 && data->ioc_inllen2 == 0) {
+ CERROR("OBD ioctl: inlbuf2 pointer but 0 length\n");
+ return 1;
+ }
+
+ if (data->ioc_inlbuf3 && data->ioc_inllen3 == 0) {
+ CERROR("OBD ioctl: inlbuf3 pointer but 0 length\n");
+ return 1;
+ }
+
+ if (data->ioc_inlbuf4 && data->ioc_inllen4 == 0) {
+ CERROR("OBD ioctl: inlbuf4 pointer but 0 length\n");
+ return 1;
+ }
+
+ if (data->ioc_pbuf1 && data->ioc_plen1 == 0) {
+ CERROR("OBD ioctl: pbuf1 pointer but 0 length\n");
+ return 1;
+ }
+
+ if (data->ioc_pbuf2 && data->ioc_plen2 == 0) {
+ CERROR("OBD ioctl: pbuf2 pointer but 0 length\n");
+ return 1;
+ }
+
+ if (!data->ioc_pbuf1 && data->ioc_plen1 != 0) {
+ CERROR("OBD ioctl: plen1 set but NULL pointer\n");
+ return 1;
+ }
+
+ if (!data->ioc_pbuf2 && data->ioc_plen2 != 0) {
+ CERROR("OBD ioctl: plen2 set but NULL pointer\n");
+ return 1;
+ }
+
+ if (obd_ioctl_packlen(data) > data->ioc_len) {
+ CERROR("OBD ioctl: packlen exceeds ioc_len (%d > %d)\n",
+ obd_ioctl_packlen(data), data->ioc_len);
+ return 1;
+ }
+
+ return 0;
+}
/* buffer MUST be at least the size of obd_ioctl_hdr */
int obd_ioctl_getdata(char **buf, int *len, void __user *arg)
@@ -151,14 +229,6 @@ free_buf:
}
EXPORT_SYMBOL(obd_ioctl_getdata);
-int obd_ioctl_popdata(void __user *arg, void *data, int len)
-{
- int err;
-
- err = copy_to_user(arg, data, len) ? -EFAULT : 0;
- return err;
-}
-
/* opening /dev/obd */
static int obd_class_open(struct inode *inode, struct file *file)
{
@@ -405,7 +475,7 @@ static const struct file_operations obd_device_list_fops = {
struct kobject *lustre_kobj;
EXPORT_SYMBOL_GPL(lustre_kobj);
-static struct attribute_group lustre_attr_group = {
+static const struct attribute_group lustre_attr_group = {
.attrs = lustre_attrs,
};
diff --git a/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c b/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c
index e6c785a..e92cccc 100644
--- a/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c
+++ b/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c
@@ -43,9 +43,9 @@
#define DEBUG_SUBSYSTEM S_CLASS
-#include "../../include/obd_support.h"
-#include "../../include/lprocfs_status.h"
-#include "../../include/obd_class.h"
+#include <obd_support.h>
+#include <lprocfs_status.h>
+#include <obd_class.h>
struct static_lustre_uintvalue_attr {
struct {
@@ -151,7 +151,7 @@ static struct attribute *lustre_attrs[] = {
NULL,
};
-static struct attribute_group lustre_attr_group = {
+static const struct attribute_group lustre_attr_group = {
.attrs = lustre_attrs,
};
diff --git a/drivers/staging/lustre/lustre/obdclass/llog.c b/drivers/staging/lustre/lustre/obdclass/llog.c
index 736ea10..98021a2 100644
--- a/drivers/staging/lustre/lustre/obdclass/llog.c
+++ b/drivers/staging/lustre/lustre/obdclass/llog.c
@@ -43,9 +43,9 @@
#define DEBUG_SUBSYSTEM S_LOG
-#include "../include/llog_swab.h"
-#include "../include/lustre_log.h"
-#include "../include/obd_class.h"
+#include <llog_swab.h>
+#include <lustre_log.h>
+#include <obd_class.h>
#include "llog_internal.h"
/*
diff --git a/drivers/staging/lustre/lustre/obdclass/llog_cat.c b/drivers/staging/lustre/lustre/obdclass/llog_cat.c
index 8f1533c..8fa9691 100644
--- a/drivers/staging/lustre/lustre/obdclass/llog_cat.c
+++ b/drivers/staging/lustre/lustre/obdclass/llog_cat.c
@@ -44,7 +44,7 @@
#define DEBUG_SUBSYSTEM S_LOG
-#include "../include/obd_class.h"
+#include <obd_class.h>
#include "llog_internal.h"
diff --git a/drivers/staging/lustre/lustre/obdclass/llog_internal.h b/drivers/staging/lustre/lustre/obdclass/llog_internal.h
index 21a93c7..8de90bc 100644
--- a/drivers/staging/lustre/lustre/obdclass/llog_internal.h
+++ b/drivers/staging/lustre/lustre/obdclass/llog_internal.h
@@ -33,7 +33,7 @@
#ifndef __LLOG_INTERNAL_H__
#define __LLOG_INTERNAL_H__
-#include "../include/lustre_log.h"
+#include <lustre_log.h>
struct llog_process_info {
struct llog_handle *lpi_loghandle;
diff --git a/drivers/staging/lustre/lustre/obdclass/llog_obd.c b/drivers/staging/lustre/lustre/obdclass/llog_obd.c
index 8574ad4..3c42de9 100644
--- a/drivers/staging/lustre/lustre/obdclass/llog_obd.c
+++ b/drivers/staging/lustre/lustre/obdclass/llog_obd.c
@@ -32,8 +32,8 @@
#define DEBUG_SUBSYSTEM S_LOG
-#include "../include/obd_class.h"
-#include "../include/lustre_log.h"
+#include <obd_class.h>
+#include <lustre_log.h>
#include "llog_internal.h"
/* helper functions for calling the llog obd methods */
diff --git a/drivers/staging/lustre/lustre/obdclass/llog_swab.c b/drivers/staging/lustre/lustre/obdclass/llog_swab.c
index 016046d..d2d3114 100644
--- a/drivers/staging/lustre/lustre/obdclass/llog_swab.c
+++ b/drivers/staging/lustre/lustre/obdclass/llog_swab.c
@@ -38,8 +38,8 @@
#define DEBUG_SUBSYSTEM S_LOG
-#include "../include/llog_swab.h"
-#include "../include/lustre_log.h"
+#include <llog_swab.h>
+#include <lustre_log.h>
static void print_llogd_body(struct llogd_body *d)
{
diff --git a/drivers/staging/lustre/lustre/obdclass/lprocfs_counters.c b/drivers/staging/lustre/lustre/obdclass/lprocfs_counters.c
index 13aca5b..e482988 100644
--- a/drivers/staging/lustre/lustre/obdclass/lprocfs_counters.c
+++ b/drivers/staging/lustre/lustre/obdclass/lprocfs_counters.c
@@ -38,8 +38,8 @@
*/
#include <linux/module.h>
-#include "../include/lprocfs_status.h"
-#include "../include/obd_support.h"
+#include <lprocfs_status.h>
+#include <obd_support.h>
void lprocfs_counter_add(struct lprocfs_stats *stats, int idx, long amount)
{
diff --git a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c
index bc19f19..e79485b 100644
--- a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c
+++ b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c
@@ -36,9 +36,9 @@
#define DEBUG_SUBSYSTEM S_CLASS
-#include "../include/obd_class.h"
-#include "../include/lprocfs_status.h"
-#include "../include/lustre/lustre_idl.h"
+#include <obd_class.h>
+#include <lprocfs_status.h>
+#include <uapi/linux/lustre/lustre_idl.h>
#include <linux/seq_file.h>
#include <linux/ctype.h>
@@ -1031,7 +1031,7 @@ static struct kobj_type obd_ktype = {
};
int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list,
- struct attribute_group *attrs)
+ const struct attribute_group *attrs)
{
int rc = 0;
diff --git a/drivers/staging/lustre/lustre/obdclass/lu_object.c b/drivers/staging/lustre/lustre/obdclass/lu_object.c
index bb9d514..09c9818 100644
--- a/drivers/staging/lustre/lustre/obdclass/lu_object.c
+++ b/drivers/staging/lustre/lustre/obdclass/lu_object.c
@@ -40,19 +40,19 @@
#define DEBUG_SUBSYSTEM S_CLASS
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
-# include <linux/module.h>
+#include <linux/module.h>
/* hash_long() */
-#include "../../include/linux/libcfs/libcfs_hash.h"
-#include "../include/obd_class.h"
-#include "../include/obd_support.h"
-#include "../include/lustre_disk.h"
-#include "../include/lustre_fid.h"
-#include "../include/lu_object.h"
-#include "../include/cl_object.h"
-#include "../include/lu_ref.h"
+#include <linux/libcfs/libcfs_hash.h>
+#include <obd_class.h>
+#include <obd_support.h>
+#include <lustre_disk.h>
+#include <lustre_fid.h>
+#include <lu_object.h>
+#include <cl_object.h>
+#include <lu_ref.h>
#include <linux/list.h>
enum {
@@ -1409,9 +1409,9 @@ void lu_context_key_degister(struct lu_context_key *key)
*/
while (atomic_read(&key->lct_used) > 1) {
spin_unlock(&lu_keys_guard);
- CDEBUG(D_INFO, "lu_context_key_degister: \"%s\" %p, %d\n",
- key->lct_owner ? key->lct_owner->name : "", key,
- atomic_read(&key->lct_used));
+ CDEBUG(D_INFO, "%s: \"%s\" %p, %d\n",
+ __func__, key->lct_owner ? key->lct_owner->name : "",
+ key, atomic_read(&key->lct_used));
schedule();
spin_lock(&lu_keys_guard);
}
@@ -1548,7 +1548,8 @@ void lu_context_key_quiesce(struct lu_context_key *key)
*/
while (atomic_read(&lu_key_initing_cnt) > 0) {
spin_unlock(&lu_keys_guard);
- CDEBUG(D_INFO, "lu_context_key_quiesce: \"%s\" %p, %d (%d)\n",
+ CDEBUG(D_INFO, "%s: \"%s\" %p, %d (%d)\n",
+ __func__,
key->lct_owner ? key->lct_owner->name : "",
key, atomic_read(&key->lct_used),
atomic_read(&lu_key_initing_cnt));
diff --git a/drivers/staging/lustre/lustre/obdclass/lu_ref.c b/drivers/staging/lustre/lustre/obdclass/lu_ref.c
index e9f6040..fa690b2 100644
--- a/drivers/staging/lustre/lustre/obdclass/lu_ref.c
+++ b/drivers/staging/lustre/lustre/obdclass/lu_ref.c
@@ -38,9 +38,9 @@
#define DEBUG_SUBSYSTEM S_CLASS
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
-#include "../include/obd.h"
-#include "../include/obd_class.h"
-#include "../include/obd_support.h"
-#include "../include/lu_ref.h"
+#include <obd.h>
+#include <obd_class.h>
+#include <obd_support.h>
+#include <lu_ref.h>
diff --git a/drivers/staging/lustre/lustre/obdclass/lustre_handles.c b/drivers/staging/lustre/lustre/obdclass/lustre_handles.c
index c9445e5..e1273c9 100644
--- a/drivers/staging/lustre/lustre/obdclass/lustre_handles.c
+++ b/drivers/staging/lustre/lustre/obdclass/lustre_handles.c
@@ -36,9 +36,9 @@
#define DEBUG_SUBSYSTEM S_CLASS
-#include "../include/obd_support.h"
-#include "../include/lustre_handles.h"
-#include "../include/lustre_lib.h"
+#include <obd_support.h>
+#include <lustre_handles.h>
+#include <lustre_lib.h>
static __u64 handle_base;
#define HANDLE_INCR 7
diff --git a/drivers/staging/lustre/lustre/obdclass/lustre_peer.c b/drivers/staging/lustre/lustre/obdclass/lustre_peer.c
index ffa740a..2798d35 100644
--- a/drivers/staging/lustre/lustre/obdclass/lustre_peer.c
+++ b/drivers/staging/lustre/lustre/obdclass/lustre_peer.c
@@ -32,13 +32,13 @@
#define DEBUG_SUBSYSTEM S_RPC
-#include "../include/obd.h"
-#include "../include/obd_support.h"
-#include "../include/obd_class.h"
-#include "../include/lustre_lib.h"
-#include "../include/lustre_ha.h"
-#include "../include/lustre_net.h"
-#include "../include/lprocfs_status.h"
+#include <obd.h>
+#include <obd_support.h>
+#include <obd_class.h>
+#include <lustre_lib.h>
+#include <lustre_ha.h>
+#include <lustre_net.h>
+#include <lprocfs_status.h>
#define NIDS_MAX 32
diff --git a/drivers/staging/lustre/lustre/obdclass/obd_config.c b/drivers/staging/lustre/lustre/obdclass/obd_config.c
index 6a7e7a7..94a940f 100644
--- a/drivers/staging/lustre/lustre/obdclass/obd_config.c
+++ b/drivers/staging/lustre/lustre/obdclass/obd_config.c
@@ -38,12 +38,12 @@
#include <linux/string.h>
-#include "../include/lustre/lustre_ioctl.h"
-#include "../include/llog_swab.h"
-#include "../include/lprocfs_status.h"
-#include "../include/lustre_log.h"
-#include "../include/lustre_param.h"
-#include "../include/obd_class.h"
+#include <uapi/linux/lustre/lustre_ioctl.h>
+#include <llog_swab.h>
+#include <lprocfs_status.h>
+#include <lustre_log.h>
+#include <uapi/linux/lustre/lustre_param.h>
+#include <obd_class.h>
#include "llog_internal.h"
@@ -170,6 +170,40 @@ int class_parse_nid_quiet(char *buf, lnet_nid_t *nid, char **endh)
}
EXPORT_SYMBOL(class_parse_nid_quiet);
+char *lustre_cfg_string(struct lustre_cfg *lcfg, u32 index)
+{
+ char *s;
+
+ if (!lcfg->lcfg_buflens[index])
+ return NULL;
+
+ s = lustre_cfg_buf(lcfg, index);
+ if (!s)
+ return NULL;
+
+ /*
+ * make sure it's NULL terminated, even if this kills a char
+ * of data. Try to use the padding first though.
+ */
+ if (s[lcfg->lcfg_buflens[index] - 1] != '\0') {
+ size_t last = ALIGN(lcfg->lcfg_buflens[index], 8) - 1;
+ char lost;
+
+ /* Use the smaller value */
+ if (last > lcfg->lcfg_buflens[index])
+ last = lcfg->lcfg_buflens[index];
+
+ lost = s[last];
+ s[last] = '\0';
+ if (lost != '\0') {
+ CWARN("Truncated buf %d to '%s' (lost '%c'...)\n",
+ index, s, lost);
+ }
+ }
+ return s;
+}
+EXPORT_SYMBOL(lustre_cfg_string);
+
/********************** class fns **********************/
/**
@@ -1107,7 +1141,8 @@ int class_config_llog_handler(const struct lu_env *env,
struct lustre_cfg_bufs bufs;
char *inst_name = NULL;
int inst_len = 0;
- int inst = 0, swab = 0;
+ size_t lcfg_len;
+ int swab = 0;
lcfg = (struct lustre_cfg *)cfg_buf;
if (lcfg->lcfg_version == __swab32(LUSTRE_CFG_VERSION)) {
@@ -1198,7 +1233,6 @@ int class_config_llog_handler(const struct lu_env *env,
if (clli && clli->cfg_instance &&
LUSTRE_CFG_BUFLEN(lcfg, 0) > 0) {
- inst = 1;
inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) +
sizeof(clli->cfg_instance) * 2 + 4;
inst_name = kasprintf(GFP_NOFS, "%s-%p",
@@ -1238,8 +1272,14 @@ int class_config_llog_handler(const struct lu_env *env,
clli->cfg_obdname);
}
- lcfg_new = lustre_cfg_new(lcfg->lcfg_command, &bufs);
+ lcfg_len = lustre_cfg_len(bufs.lcfg_bufcount, bufs.lcfg_buflen);
+ lcfg_new = kzalloc(lcfg_len, GFP_NOFS);
+ if (!lcfg_new) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ lustre_cfg_init(lcfg_new, lcfg->lcfg_command, &bufs);
lcfg_new->lcfg_num = lcfg->lcfg_num;
lcfg_new->lcfg_flags = lcfg->lcfg_flags;
@@ -1262,10 +1302,8 @@ int class_config_llog_handler(const struct lu_env *env,
lcfg_new->lcfg_nal = 0; /* illegal value for obsolete field */
rc = class_process_config(lcfg_new);
- lustre_cfg_free(lcfg_new);
-
- if (inst)
- kfree(inst_name);
+ kfree(lcfg_new);
+ kfree(inst_name);
break;
}
default:
@@ -1426,9 +1464,11 @@ int class_manual_cleanup(struct obd_device *obd)
lustre_cfg_bufs_reset(&bufs, obd->obd_name);
lustre_cfg_bufs_set_string(&bufs, 1, flags);
- lcfg = lustre_cfg_new(LCFG_CLEANUP, &bufs);
- if (IS_ERR(lcfg))
- return PTR_ERR(lcfg);
+ lcfg = kzalloc(lustre_cfg_len(bufs.lcfg_bufcount, bufs.lcfg_buflen),
+ GFP_NOFS);
+ if (!lcfg)
+ return -ENOMEM;
+ lustre_cfg_init(lcfg, LCFG_CLEANUP, &bufs);
rc = class_process_config(lcfg);
if (rc) {
@@ -1442,7 +1482,7 @@ int class_manual_cleanup(struct obd_device *obd)
if (rc)
CERROR("detach failed %d: %s\n", rc, obd->obd_name);
out:
- lustre_cfg_free(lcfg);
+ kfree(lcfg);
return rc;
}
EXPORT_SYMBOL(class_manual_cleanup);
diff --git a/drivers/staging/lustre/lustre/obdclass/obd_mount.c b/drivers/staging/lustre/lustre/obdclass/obd_mount.c
index 8e0d4b1..1256034 100644
--- a/drivers/staging/lustre/lustre/obdclass/obd_mount.c
+++ b/drivers/staging/lustre/lustre/obdclass/obd_mount.c
@@ -40,13 +40,13 @@
#define D_MOUNT (D_SUPER | D_CONFIG/*|D_WARNING */)
#define PRINT_CMD CDEBUG
-#include "../include/obd.h"
-#include "../include/lustre_compat.h"
-#include "../include/obd_class.h"
-#include "../include/lustre/lustre_user.h"
-#include "../include/lustre_log.h"
-#include "../include/lustre_disk.h"
-#include "../include/lustre_param.h"
+#include <obd.h>
+#include <lustre_compat.h>
+#include <obd_class.h>
+#include <uapi/linux/lustre/lustre_idl.h>
+#include <lustre_log.h>
+#include <lustre_disk.h>
+#include <uapi/linux/lustre/lustre_param.h>
static int (*client_fill_super)(struct super_block *sb,
struct vfsmount *mnt);
@@ -88,10 +88,17 @@ int lustre_process_log(struct super_block *sb, char *logname,
lustre_cfg_bufs_set_string(bufs, 1, logname);
lustre_cfg_bufs_set(bufs, 2, cfg, sizeof(*cfg));
lustre_cfg_bufs_set(bufs, 3, &sb, sizeof(sb));
- lcfg = lustre_cfg_new(LCFG_LOG_START, bufs);
- rc = obd_process_config(mgc, sizeof(*lcfg), lcfg);
- lustre_cfg_free(lcfg);
+ lcfg = kzalloc(lustre_cfg_len(bufs->lcfg_bufcount, bufs->lcfg_buflen),
+ GFP_NOFS);
+ if (!lcfg) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ lustre_cfg_init(lcfg, LCFG_LOG_START, bufs);
+ rc = obd_process_config(mgc, sizeof(*lcfg), lcfg);
+ kfree(lcfg);
+out:
kfree(bufs);
if (rc == -EINVAL)
@@ -126,9 +133,14 @@ int lustre_end_log(struct super_block *sb, char *logname,
lustre_cfg_bufs_set_string(&bufs, 1, logname);
if (cfg)
lustre_cfg_bufs_set(&bufs, 2, cfg, sizeof(*cfg));
- lcfg = lustre_cfg_new(LCFG_LOG_END, &bufs);
+ lcfg = kzalloc(lustre_cfg_len(bufs.lcfg_bufcount, bufs.lcfg_buflen),
+ GFP_NOFS);
+ if (!lcfg)
+ return -ENOMEM;
+ lustre_cfg_init(lcfg, LCFG_LOG_END, &bufs);
+
rc = obd_process_config(mgc, sizeof(*lcfg), lcfg);
- lustre_cfg_free(lcfg);
+ kfree(lcfg);
return rc;
}
EXPORT_SYMBOL(lustre_end_log);
@@ -158,10 +170,14 @@ static int do_lcfg(char *cfgname, lnet_nid_t nid, int cmd,
if (s4)
lustre_cfg_bufs_set_string(&bufs, 4, s4);
- lcfg = lustre_cfg_new(cmd, &bufs);
+ lcfg = kzalloc(lustre_cfg_len(bufs.lcfg_bufcount, bufs.lcfg_buflen),
+ GFP_NOFS);
+ if (!lcfg)
+ return -ENOMEM;
+ lustre_cfg_init(lcfg, cmd, &bufs);
lcfg->lcfg_nid = nid;
rc = class_process_config(lcfg);
- lustre_cfg_free(lcfg);
+ kfree(lcfg);
return rc;
}
diff --git a/drivers/staging/lustre/lustre/obdclass/obdo.c b/drivers/staging/lustre/lustre/obdclass/obdo.c
index b1dfa16..7083f87 100644
--- a/drivers/staging/lustre/lustre/obdclass/obdo.c
+++ b/drivers/staging/lustre/lustre/obdclass/obdo.c
@@ -38,9 +38,9 @@
#define DEBUG_SUBSYSTEM S_CLASS
-#include "../include/obd_class.h"
-#include "../include/lustre/lustre_idl.h"
-#include "../include/lustre_obdo.h"
+#include <obd_class.h>
+#include <uapi/linux/lustre/lustre_idl.h>
+#include <lustre_obdo.h>
void obdo_set_parent_fid(struct obdo *dst, const struct lu_fid *parent)
{
diff --git a/drivers/staging/lustre/lustre/obdclass/statfs_pack.c b/drivers/staging/lustre/lustre/obdclass/statfs_pack.c
index 4bad1fa..89abea2 100644
--- a/drivers/staging/lustre/lustre/obdclass/statfs_pack.c
+++ b/drivers/staging/lustre/lustre/obdclass/statfs_pack.c
@@ -37,10 +37,10 @@
#define DEBUG_SUBSYSTEM S_CLASS
#include <linux/statfs.h>
-#include "../include/lustre_export.h"
-#include "../include/lustre_net.h"
-#include "../include/obd_support.h"
-#include "../include/obd_class.h"
+#include <lustre_export.h>
+#include <lustre_net.h>
+#include <obd_support.h>
+#include <obd_class.h>
void statfs_unpack(struct kstatfs *sfs, struct obd_statfs *osfs)
{
diff --git a/drivers/staging/lustre/lustre/obdclass/uuid.c b/drivers/staging/lustre/lustre/obdclass/uuid.c
index abd9b1a..9b1872b 100644
--- a/drivers/staging/lustre/lustre/obdclass/uuid.c
+++ b/drivers/staging/lustre/lustre/obdclass/uuid.c
@@ -34,10 +34,10 @@
#define DEBUG_SUBSYSTEM S_CLASS
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
-#include "../include/obd_support.h"
-#include "../include/obd_class.h"
+#include <obd_support.h>
+#include <obd_class.h>
void class_uuid_unparse(class_uuid_t uu, struct obd_uuid *out)
{
diff --git a/drivers/staging/lustre/lustre/obdecho/Makefile b/drivers/staging/lustre/lustre/obdecho/Makefile
index a659a37..6be66fb 100644
--- a/drivers/staging/lustre/lustre/obdecho/Makefile
+++ b/drivers/staging/lustre/lustre/obdecho/Makefile
@@ -1,2 +1,5 @@
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/include
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/lustre/include
+
obj-$(CONFIG_LUSTRE_FS) += obdecho.o
obdecho-y := echo_client.o
diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c
index 1c4a8fe..f9808d1 100644
--- a/drivers/staging/lustre/lustre/obdecho/echo_client.c
+++ b/drivers/staging/lustre/lustre/obdecho/echo_client.c
@@ -31,18 +31,18 @@
*/
#define DEBUG_SUBSYSTEM S_ECHO
-#include "../../include/linux/libcfs/libcfs.h"
-
-#include "../include/obd.h"
-#include "../include/obd_support.h"
-#include "../include/obd_class.h"
-#include "../include/lustre_debug.h"
-#include "../include/lprocfs_status.h"
-#include "../include/cl_object.h"
-#include "../include/lustre_fid.h"
-#include "../include/lustre_acl.h"
-#include "../include/lustre/lustre_ioctl.h"
-#include "../include/lustre_net.h"
+#include <linux/libcfs/libcfs.h>
+
+#include <obd.h>
+#include <obd_support.h>
+#include <obd_class.h>
+#include <lustre_debug.h>
+#include <lprocfs_status.h>
+#include <cl_object.h>
+#include <lustre_fid.h>
+#include <lustre_acl.h>
+#include <uapi/linux/lustre/lustre_ioctl.h>
+#include <lustre_net.h>
#include "echo_internal.h"
@@ -319,7 +319,7 @@ static void echo_lock_fini(const struct lu_env *env,
kmem_cache_free(echo_lock_kmem, ecl);
}
-static struct cl_lock_operations echo_lock_ops = {
+static const struct cl_lock_operations echo_lock_ops = {
.clo_fini = echo_lock_fini,
};
@@ -1102,8 +1102,11 @@ static int echo_create_object(const struct lu_env *env, struct echo_device *ed,
return -EINVAL;
}
- if (!ostid_id(&oa->o_oi))
- ostid_set_id(&oa->o_oi, ++last_object_id);
+ if (!ostid_id(&oa->o_oi)) {
+ rc = ostid_set_id(&oa->o_oi, ++last_object_id);
+ if (rc)
+ goto failed;
+ }
rc = obd_create(env, ec->ec_exp, oa);
if (rc != 0) {
diff --git a/drivers/staging/lustre/lustre/osc/Makefile b/drivers/staging/lustre/lustre/osc/Makefile
index 37cdeea..30dec90 100644
--- a/drivers/staging/lustre/lustre/osc/Makefile
+++ b/drivers/staging/lustre/lustre/osc/Makefile
@@ -1,3 +1,6 @@
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/include
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/lustre/include
+
obj-$(CONFIG_LUSTRE_FS) += osc.o
osc-y := osc_request.o osc_dev.o osc_object.o \
osc_page.o osc_lock.o osc_io.o osc_quota.o osc_cache.o lproc_osc.o
diff --git a/drivers/staging/lustre/lustre/osc/lproc_osc.c b/drivers/staging/lustre/lustre/osc/lproc_osc.c
index 86f252d..ae13eb055 100644
--- a/drivers/staging/lustre/lustre/osc/lproc_osc.c
+++ b/drivers/staging/lustre/lustre/osc/lproc_osc.c
@@ -32,9 +32,9 @@
#define DEBUG_SUBSYSTEM S_CLASS
#include <linux/statfs.h>
-#include "../include/obd_cksum.h"
-#include "../include/obd_class.h"
-#include "../include/lprocfs_status.h"
+#include <obd_cksum.h>
+#include <obd_class.h>
+#include <lprocfs_status.h>
#include <linux/seq_file.h>
#include "osc_internal.h"
@@ -831,7 +831,7 @@ static struct attribute *osc_attrs[] = {
NULL,
};
-static struct attribute_group osc_attr_group = {
+static const struct attribute_group osc_attr_group = {
.attrs = osc_attrs,
};
diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c
index d8a95f8..e1207c2 100644
--- a/drivers/staging/lustre/lustre/osc/osc_cache.c
+++ b/drivers/staging/lustre/lustre/osc/osc_cache.c
@@ -783,6 +783,7 @@ restart:
/* pull ext's start back to cover cur */
ext->oe_start = cur->oe_start;
ext->oe_grants += chunksize;
+ LASSERT(*grants >= chunksize);
*grants -= chunksize;
found = osc_extent_hold(ext);
@@ -790,6 +791,7 @@ restart:
/* rear merge */
ext->oe_end = cur->oe_end;
ext->oe_grants += chunksize;
+ LASSERT(*grants >= chunksize);
*grants -= chunksize;
/* try to merge with the next one because we just fill
@@ -819,8 +821,8 @@ restart:
/* create a new extent */
EASSERT(osc_extent_is_overlapped(obj, cur) == 0, cur);
cur->oe_grants = chunksize + cli->cl_extent_tax;
+ LASSERT(*grants >= cur->oe_grants);
*grants -= cur->oe_grants;
- LASSERT(*grants >= 0);
cur->oe_state = OES_CACHE;
found = osc_extent_hold(cur);
@@ -849,7 +851,6 @@ restart:
out:
osc_extent_put(env, cur);
- LASSERT(*grants >= 0);
return found;
}
@@ -1219,8 +1220,8 @@ static int osc_extent_expand(struct osc_extent *ext, pgoff_t index,
ext->oe_end = end_index;
ext->oe_grants += chunksize;
+ LASSERT(*grants >= chunksize);
*grants -= chunksize;
- LASSERT(*grants >= 0);
EASSERTF(osc_extent_is_overlapped(obj, ext) == 0, ext,
"overlapped after expanding for %lu.\n", index);
@@ -1887,6 +1888,7 @@ struct extent_rpc_data {
unsigned int erd_page_count;
unsigned int erd_max_pages;
unsigned int erd_max_chunks;
+ unsigned int erd_max_extents;
};
static inline unsigned int osc_extent_chunks(const struct osc_extent *ext)
@@ -1915,11 +1917,23 @@ static int try_to_add_extent_for_io(struct client_obd *cli,
EASSERT((ext->oe_state == OES_CACHE || ext->oe_state == OES_LOCK_DONE),
ext);
+ if (!data->erd_max_extents)
+ return 0;
+
chunk_count = osc_extent_chunks(ext);
+ EASSERTF(data->erd_page_count != 0 ||
+ chunk_count <= data->erd_max_chunks, ext,
+ "The first extent to be fit in a RPC contains %u chunks, which is over the limit %u.\n",
+ chunk_count, data->erd_max_chunks);
+
if (chunk_count > data->erd_max_chunks)
return 0;
data->erd_max_pages = max(ext->oe_mppr, data->erd_max_pages);
+ EASSERTF(data->erd_page_count != 0 ||
+ ext->oe_nr_pages <= data->erd_max_pages, ext,
+ "The first extent to be fit in a RPC contains %u pages, which is over the limit %u.\n",
+ ext->oe_nr_pages, data->erd_max_pages);
if (data->erd_page_count + ext->oe_nr_pages > data->erd_max_pages)
return 0;
@@ -1943,6 +1957,7 @@ static int try_to_add_extent_for_io(struct client_obd *cli,
break;
}
+ data->erd_max_extents--;
data->erd_max_chunks -= chunk_count;
data->erd_page_count += ext->oe_nr_pages;
list_move_tail(&ext->oe_link, data->erd_rpc_list);
@@ -1972,10 +1987,12 @@ static inline unsigned int osc_max_write_chunks(const struct client_obd *cli)
*
* This limitation doesn't apply to ldiskfs, which allows as many
* chunks in one RPC as we want. However, it won't have any benefits
- * to have too many discontiguous pages in one RPC. Therefore, it
- * can only have 256 chunks at most in one RPC.
+ * to have too many discontiguous pages in one RPC.
+ *
+ * An osc_extent won't cover over a RPC size, so the chunks in an
+ * osc_extent won't bigger than PTLRPC_MAX_BRW_SIZE >> chunkbits.
*/
- return min(PTLRPC_MAX_BRW_SIZE >> cli->cl_chunkbits, 256);
+ return PTLRPC_MAX_BRW_SIZE >> cli->cl_chunkbits;
}
/**
@@ -2002,6 +2019,7 @@ static unsigned int get_write_extents(struct osc_object *obj,
.erd_page_count = 0,
.erd_max_pages = cli->cl_max_pages_per_rpc,
.erd_max_chunks = osc_max_write_chunks(cli),
+ .erd_max_extents = 256,
};
LASSERT(osc_object_is_locked(obj));
@@ -2140,6 +2158,7 @@ osc_send_read_rpc(const struct lu_env *env, struct client_obd *cli,
.erd_page_count = 0,
.erd_max_pages = cli->cl_max_pages_per_rpc,
.erd_max_chunks = UINT_MAX,
+ .erd_max_extents = UINT_MAX,
};
int rc = 0;
diff --git a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h
index 270212f..35bdbfb 100644
--- a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h
+++ b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h
@@ -42,11 +42,11 @@
#ifndef OSC_CL_INTERNAL_H
#define OSC_CL_INTERNAL_H
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
-#include "../include/obd.h"
+#include <obd.h>
/* osc_build_res_name() */
-#include "../include/cl_object.h"
+#include <cl_object.h>
#include "osc_internal.h"
/** \defgroup osc osc
diff --git a/drivers/staging/lustre/lustre/osc/osc_dev.c b/drivers/staging/lustre/lustre/osc/osc_dev.c
index c5d62ae..cf7b887 100644
--- a/drivers/staging/lustre/lustre/osc/osc_dev.c
+++ b/drivers/staging/lustre/lustre/osc/osc_dev.c
@@ -37,7 +37,7 @@
#define DEBUG_SUBSYSTEM S_OSC
/* class_name2obd() */
-#include "../include/obd_class.h"
+#include <obd_class.h>
#include "osc_cl_internal.h"
diff --git a/drivers/staging/lustre/lustre/osc/osc_internal.h b/drivers/staging/lustre/lustre/osc/osc_internal.h
index 13a40f6..a536908 100644
--- a/drivers/staging/lustre/lustre/osc/osc_internal.h
+++ b/drivers/staging/lustre/lustre/osc/osc_internal.h
@@ -99,7 +99,7 @@ void osc_update_next_shrink(struct client_obd *cli);
/*
* cl integration.
*/
-#include "../include/cl_object.h"
+#include <cl_object.h>
extern struct ptlrpc_request_set *PTLRPCD_SET;
diff --git a/drivers/staging/lustre/lustre/osc/osc_io.c b/drivers/staging/lustre/lustre/osc/osc_io.c
index cbab800..f7969e3 100644
--- a/drivers/staging/lustre/lustre/osc/osc_io.c
+++ b/drivers/staging/lustre/lustre/osc/osc_io.c
@@ -37,7 +37,7 @@
#define DEBUG_SUBSYSTEM S_OSC
-#include "../include/lustre_obdo.h"
+#include <lustre_obdo.h>
#include "osc_cl_internal.h"
diff --git a/drivers/staging/lustre/lustre/osc/osc_lock.c b/drivers/staging/lustre/lustre/osc/osc_lock.c
index 940c10c..b4f1f74 100644
--- a/drivers/staging/lustre/lustre/osc/osc_lock.c
+++ b/drivers/staging/lustre/lustre/osc/osc_lock.c
@@ -37,9 +37,9 @@
#define DEBUG_SUBSYSTEM S_OSC
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
/* fid_build_reg_res_name() */
-#include "../include/lustre_fid.h"
+#include <lustre_fid.h>
#include "osc_cl_internal.h"
diff --git a/drivers/staging/lustre/lustre/osc/osc_object.c b/drivers/staging/lustre/lustre/osc/osc_object.c
index fa621bd..945ae6e 100644
--- a/drivers/staging/lustre/lustre/osc/osc_object.c
+++ b/drivers/staging/lustre/lustre/osc/osc_object.c
@@ -369,7 +369,14 @@ static void osc_req_attr_set(const struct lu_env *env, struct cl_object *obj,
oa->o_valid |= OBD_MD_FLGROUP;
}
if (flags & OBD_MD_FLID) {
- ostid_set_id(&oa->o_oi, ostid_id(&oinfo->loi_oi));
+ int rc;
+
+ rc = ostid_set_id(&oa->o_oi, ostid_id(&oinfo->loi_oi));
+ if (rc) {
+ CERROR("Bad %llu to set " DOSTID " : rc %d\n",
+ (unsigned long long)ostid_id(&oinfo->loi_oi),
+ POSTID(&oa->o_oi), rc);
+ }
oa->o_valid |= OBD_MD_FLID;
}
if (flags & OBD_MD_FLHANDLE) {
diff --git a/drivers/staging/lustre/lustre/osc/osc_quota.c b/drivers/staging/lustre/lustre/osc/osc_quota.c
index fed4da6..a6118f8 100644
--- a/drivers/staging/lustre/lustre/osc/osc_quota.c
+++ b/drivers/staging/lustre/lustre/osc/osc_quota.c
@@ -23,7 +23,7 @@
* Code originally extracted from quota directory
*/
-#include "../include/obd_class.h"
+#include <obd_class.h>
#include "osc_internal.h"
static inline struct osc_quota_info *osc_oqi_alloc(u32 id)
diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c
index 922d0cb..4c68c42 100644
--- a/drivers/staging/lustre/lustre/osc/osc_request.c
+++ b/drivers/staging/lustre/lustre/osc/osc_request.c
@@ -32,22 +32,22 @@
#define DEBUG_SUBSYSTEM S_OSC
-#include "../../include/linux/libcfs/libcfs.h"
-
-#include "../include/lustre_dlm.h"
-#include "../include/lustre_net.h"
-#include "../include/lustre/lustre_user.h"
-#include "../include/obd_cksum.h"
-
-#include "../include/lustre_ha.h"
-#include "../include/lprocfs_status.h"
-#include "../include/lustre/lustre_ioctl.h"
-#include "../include/lustre_debug.h"
-#include "../include/lustre_obdo.h"
-#include "../include/lustre_param.h"
-#include "../include/lustre_fid.h"
-#include "../include/obd_class.h"
-#include "../include/obd.h"
+#include <linux/libcfs/libcfs.h>
+
+#include <lustre_dlm.h>
+#include <lustre_net.h>
+#include <uapi/linux/lustre/lustre_idl.h>
+#include <obd_cksum.h>
+
+#include <lustre_ha.h>
+#include <lprocfs_status.h>
+#include <uapi/linux/lustre/lustre_ioctl.h>
+#include <lustre_debug.h>
+#include <lustre_obdo.h>
+#include <uapi/linux/lustre/lustre_param.h>
+#include <lustre_fid.h>
+#include <obd_class.h>
+#include <obd.h>
#include "osc_internal.h"
#include "osc_cl_internal.h"
diff --git a/drivers/staging/lustre/lustre/ptlrpc/Makefile b/drivers/staging/lustre/lustre/ptlrpc/Makefile
index 24bbac1..a518001 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/Makefile
+++ b/drivers/staging/lustre/lustre/ptlrpc/Makefile
@@ -1,3 +1,6 @@
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/include
+subdir-ccflags-y += -I$(srctree)/drivers/staging/lustre/lustre/include
+
obj-$(CONFIG_LUSTRE_FS) += ptlrpc.o
LDLM := ../../lustre/ldlm/
diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c
index 1c77792..b1d379a 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -34,12 +34,12 @@
#define DEBUG_SUBSYSTEM S_RPC
-#include "../include/obd_support.h"
-#include "../include/obd_class.h"
-#include "../include/lustre_lib.h"
-#include "../include/lustre_ha.h"
-#include "../include/lustre_import.h"
-#include "../include/lustre_req_layout.h"
+#include <obd_support.h>
+#include <obd_class.h>
+#include <lustre_lib.h>
+#include <lustre_ha.h>
+#include <lustre_import.h>
+#include <lustre_req_layout.h>
#include "ptlrpc_internal.h"
@@ -367,9 +367,8 @@ void ptlrpc_at_adj_net_latency(struct ptlrpc_request *req,
*/
CDEBUG((lustre_msg_get_flags(req->rq_reqmsg) & MSG_RESENT) ?
D_ADAPTTO : D_WARNING,
- "Reported service time %u > total measured time " CFS_DURATION_T "\n",
- service_time,
- (long)(now - req->rq_sent));
+ "Reported service time %u > total measured time %lld\n",
+ service_time, now - req->rq_sent);
return;
}
@@ -742,7 +741,7 @@ int ptlrpc_request_bufs_pack(struct ptlrpc_request *request,
/* Let's setup deadline for req/reply/bulk unlink for opcode. */
if (cfs_fail_val == opcode) {
- time_t *fail_t = NULL, *fail2_t = NULL;
+ time64_t *fail_t = NULL, *fail2_t = NULL;
if (CFS_FAIL_CHECK(OBD_FAIL_PTLRPC_LONG_BULK_UNLINK)) {
fail_t = &request->rq_bulk_deadline;
@@ -3116,13 +3115,20 @@ void ptlrpc_set_bulk_mbits(struct ptlrpc_request *req)
LASSERT(bd);
- if (!req->rq_resend) {
- /* this request has a new xid, just use it as bulk matchbits */
- req->rq_mbits = req->rq_xid;
-
- } else { /* needs to generate a new matchbits for resend */
+ /*
+ * Generate new matchbits for all resend requests, including
+ * resend replay.
+ */
+ if (req->rq_resend) {
u64 old_mbits = req->rq_mbits;
+ /*
+ * First time resend on -EINPROGRESS will generate new xid,
+ * so we can actually use the rq_xid as rq_mbits in such case,
+ * however, it's bit hard to distinguish such resend with a
+ * 'resend for the -EINPROGRESS resend'. To make it simple,
+ * we opt to generate mbits for all resend cases.
+ */
if ((bd->bd_import->imp_connect_data.ocd_connect_flags &
OBD_CONNECT_BULK_MBITS)) {
req->rq_mbits = ptlrpc_next_xid();
@@ -3131,12 +3137,21 @@ void ptlrpc_set_bulk_mbits(struct ptlrpc_request *req)
spin_lock(&req->rq_import->imp_lock);
list_del_init(&req->rq_unreplied_list);
ptlrpc_assign_next_xid_nolock(req);
- req->rq_mbits = req->rq_xid;
spin_unlock(&req->rq_import->imp_lock);
+ req->rq_mbits = req->rq_xid;
}
CDEBUG(D_HA, "resend bulk old x%llu new x%llu\n",
old_mbits, req->rq_mbits);
+ } else if (!(lustre_msg_get_flags(req->rq_reqmsg) & MSG_REPLAY)) {
+ /* Request being sent first time, use xid as matchbits. */
+ req->rq_mbits = req->rq_xid;
+ } else {
+ /*
+ * Replay request, xid and matchbits have already been
+ * correctly assigned.
+ */
+ return;
}
/*
diff --git a/drivers/staging/lustre/lustre/ptlrpc/connection.c b/drivers/staging/lustre/lustre/ptlrpc/connection.c
index 73a2dbb..cfdcbcec 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/connection.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/connection.c
@@ -31,9 +31,9 @@
*/
#define DEBUG_SUBSYSTEM S_RPC
-#include "../include/obd_support.h"
-#include "../include/obd_class.h"
-#include "../include/lustre_net.h"
+#include <obd_support.h>
+#include <obd_class.h>
+#include <lustre_net.h>
#include "ptlrpc_internal.h"
diff --git a/drivers/staging/lustre/lustre/ptlrpc/errno.c b/drivers/staging/lustre/lustre/ptlrpc/errno.c
index 73f8374..cb78836 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/errno.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/errno.c
@@ -25,8 +25,8 @@
* Copyright (c) 2013, Intel Corporation.
*/
-#include "../../include/linux/libcfs/libcfs.h"
-#include "../include/lustre/lustre_errno.h"
+#include <linux/libcfs/libcfs.h>
+#include <lustre_errno.h>
/*
* The two translation tables below must define a one-to-one mapping between
diff --git a/drivers/staging/lustre/lustre/ptlrpc/events.c b/drivers/staging/lustre/lustre/ptlrpc/events.c
index 978bdac..62951f1 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/events.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/events.c
@@ -32,14 +32,14 @@
#define DEBUG_SUBSYSTEM S_RPC
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
# ifdef __mips64__
# include <linux/kernel.h>
# endif
-#include "../include/obd_class.h"
-#include "../include/lustre_net.h"
-#include "../include/lustre_sec.h"
+#include <obd_class.h>
+#include <lustre_net.h>
+#include <lustre_sec.h>
#include "ptlrpc_internal.h"
struct lnet_handle_eq ptlrpc_eq_h;
diff --git a/drivers/staging/lustre/lustre/ptlrpc/import.c b/drivers/staging/lustre/lustre/ptlrpc/import.c
index 52cb1f0..21f5289 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/import.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/import.c
@@ -36,14 +36,14 @@
#define DEBUG_SUBSYSTEM S_RPC
-#include "../include/obd_support.h"
-#include "../include/lustre_ha.h"
-#include "../include/lustre_net.h"
-#include "../include/lustre_import.h"
-#include "../include/lustre_export.h"
-#include "../include/obd.h"
-#include "../include/obd_cksum.h"
-#include "../include/obd_class.h"
+#include <obd_support.h>
+#include <lustre_ha.h>
+#include <lustre_net.h>
+#include <lustre_import.h>
+#include <lustre_export.h>
+#include <obd.h>
+#include <obd_cksum.h>
+#include <obd_class.h>
#include "ptlrpc_internal.h"
@@ -1026,7 +1026,7 @@ static int ptlrpc_connect_interpret(const struct lu_env *env,
/* check that server granted subset of flags we asked for. */
if ((ocd->ocd_connect_flags & imp->imp_connect_flags_orig) !=
ocd->ocd_connect_flags) {
- CERROR("%s: Server didn't granted asked subset of flags: asked=%#llx grranted=%#llx\n",
+ CERROR("%s: Server didn't grant the asked for subset of flags: asked=%#llx granted=%#llx\n",
imp->imp_obd->obd_name, imp->imp_connect_flags_orig,
ocd->ocd_connect_flags);
rc = -EPROTO;
diff --git a/drivers/staging/lustre/lustre/ptlrpc/layout.c b/drivers/staging/lustre/lustre/ptlrpc/layout.c
index 5810bba..85854d9 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/layout.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/layout.c
@@ -46,18 +46,18 @@
#include <linux/module.h>
-#include "../include/lustre/lustre_idl.h"
+#include <uapi/linux/lustre/lustre_idl.h>
-#include "../include/llog_swab.h"
-#include "../include/lustre_debug.h"
-#include "../include/lustre_swab.h"
-#include "../include/lustre_ver.h"
-#include "../include/obd.h"
-#include "../include/obd_support.h"
+#include <llog_swab.h>
+#include <lustre_debug.h>
+#include <lustre_swab.h>
+#include <uapi/linux/lustre/lustre_ver.h>
+#include <obd.h>
+#include <obd_support.h>
/* struct ptlrpc_request, lustre_msg* */
-#include "../include/lustre_req_layout.h"
-#include "../include/lustre_acl.h"
+#include <lustre_req_layout.h>
+#include <lustre_acl.h>
/*
* RQFs (see below) refer to two struct req_msg_field arrays describing the
diff --git a/drivers/staging/lustre/lustre/ptlrpc/llog_client.c b/drivers/staging/lustre/lustre/ptlrpc/llog_client.c
index 110d9f5..480c20a 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/llog_client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/llog_client.c
@@ -38,11 +38,11 @@
#define DEBUG_SUBSYSTEM S_LOG
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
-#include "../include/obd_class.h"
-#include "../include/lustre_log.h"
-#include "../include/lustre_net.h"
+#include <obd_class.h>
+#include <lustre_log.h>
+#include <lustre_net.h>
#include <linux/list.h>
#define LLOG_CLIENT_ENTRY(ctxt, imp) do { \
diff --git a/drivers/staging/lustre/lustre/ptlrpc/llog_net.c b/drivers/staging/lustre/lustre/ptlrpc/llog_net.c
index bccdace..bc5aa7b 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/llog_net.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/llog_net.c
@@ -42,10 +42,10 @@
#define DEBUG_SUBSYSTEM S_LOG
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
-#include "../include/obd_class.h"
-#include "../include/lustre_log.h"
+#include <obd_class.h>
+#include <lustre_log.h>
#include <linux/list.h>
int llog_initiator_connect(struct llog_ctxt *ctxt)
diff --git a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c
index f874781..1392ae9 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c
@@ -31,12 +31,12 @@
*/
#define DEBUG_SUBSYSTEM S_CLASS
-#include "../include/obd_support.h"
-#include "../include/obd.h"
-#include "../include/lprocfs_status.h"
-#include "../include/lustre/lustre_idl.h"
-#include "../include/lustre_net.h"
-#include "../include/obd_class.h"
+#include <obd_support.h>
+#include <obd.h>
+#include <lprocfs_status.h>
+#include <uapi/linux/lustre/lustre_idl.h>
+#include <lustre_net.h>
+#include <obd_class.h>
#include "ptlrpc_internal.h"
static struct ll_rpc_opcode {
@@ -905,11 +905,18 @@ static int ptlrpc_lprocfs_svc_req_history_show(struct seq_file *s, void *iter)
rc = ptlrpc_lprocfs_svc_req_history_seek(svcpt, srhi, srhi->srhi_seq);
if (rc == 0) {
+ struct timespec64 arrival, sent, arrivaldiff;
char nidstr[LNET_NIDSTR_SIZE];
req = srhi->srhi_req;
libcfs_nid2str_r(req->rq_self, nidstr, sizeof(nidstr));
+ arrival.tv_sec = req->rq_arrival_time.tv_sec;
+ arrival.tv_nsec = req->rq_arrival_time.tv_nsec;
+ sent.tv_sec = req->rq_sent;
+ sent.tv_nsec = 0;
+ arrivaldiff = timespec64_sub(sent, arrival);
+
/* Print common req fields.
* CAVEAT EMPTOR: we're racing with the service handler
* here. The request could contain any old crap, so you
@@ -917,13 +924,15 @@ static int ptlrpc_lprocfs_svc_req_history_show(struct seq_file *s, void *iter)
* parser. Currently I only print stuff here I know is OK
* to look at coz it was set up in request_in_callback()!!!
*/
- seq_printf(s, "%lld:%s:%s:x%llu:%d:%s:%lld:%lds(%+lds) ",
+ seq_printf(s, "%lld:%s:%s:x%llu:%d:%s:%lld.%06lld:%lld.%06llds(%+lld.0s) ",
req->rq_history_seq, nidstr,
libcfs_id2str(req->rq_peer), req->rq_xid,
req->rq_reqlen, ptlrpc_rqphase2str(req),
(s64)req->rq_arrival_time.tv_sec,
- (long)(req->rq_sent - req->rq_arrival_time.tv_sec),
- (long)(req->rq_sent - req->rq_deadline));
+ (s64)req->rq_arrival_time.tv_nsec / NSEC_PER_USEC,
+ (s64)arrivaldiff.tv_sec,
+ (s64)(arrivaldiff.tv_nsec / NSEC_PER_USEC),
+ (s64)(req->rq_sent - req->rq_deadline));
if (!svc->srv_ops.so_req_printer)
seq_putc(s, '\n');
else
diff --git a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
index eddc192..12149fb 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
@@ -31,11 +31,11 @@
*/
#define DEBUG_SUBSYSTEM S_RPC
-#include "../include/obd_support.h"
-#include "../include/lustre_net.h"
-#include "../include/lustre_lib.h"
-#include "../include/obd.h"
-#include "../include/obd_class.h"
+#include <obd_support.h>
+#include <lustre_net.h>
+#include <lustre_lib.h>
+#include <obd.h>
+#include <obd_class.h>
#include "ptlrpc_internal.h"
/**
diff --git a/drivers/staging/lustre/lustre/ptlrpc/nrs.c b/drivers/staging/lustre/lustre/ptlrpc/nrs.c
index ef19dbe..2969d8d 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/nrs.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/nrs.c
@@ -36,11 +36,11 @@
*/
#define DEBUG_SUBSYSTEM S_RPC
-#include "../include/obd_support.h"
-#include "../include/obd_class.h"
-#include "../include/lustre_net.h"
-#include "../include/lprocfs_status.h"
-#include "../../include/linux/libcfs/libcfs.h"
+#include <obd_support.h>
+#include <obd_class.h>
+#include <lustre_net.h>
+#include <lprocfs_status.h>
+#include <linux/libcfs/libcfs.h>
#include "ptlrpc_internal.h"
/**
diff --git a/drivers/staging/lustre/lustre/ptlrpc/nrs_fifo.c b/drivers/staging/lustre/lustre/ptlrpc/nrs_fifo.c
index b123a93..df330e4 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/nrs_fifo.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/nrs_fifo.c
@@ -43,9 +43,9 @@
*/
#define DEBUG_SUBSYSTEM S_RPC
-#include "../include/obd_support.h"
-#include "../include/obd_class.h"
-#include "../../include/linux/libcfs/libcfs.h"
+#include <obd_support.h>
+#include <obd_class.h>
+#include <linux/libcfs/libcfs.h>
#include "ptlrpc_internal.h"
/**
diff --git a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
index 55e8696e..aad4ff1 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
@@ -40,16 +40,16 @@
#define DEBUG_SUBSYSTEM S_RPC
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
-#include "../include/lustre/ll_fiemap.h"
+#include <uapi/linux/lustre/lustre_fiemap.h>
-#include "../include/llog_swab.h"
-#include "../include/lustre_net.h"
-#include "../include/lustre_swab.h"
-#include "../include/obd_cksum.h"
-#include "../include/obd_support.h"
-#include "../include/obd_class.h"
+#include <llog_swab.h>
+#include <lustre_net.h>
+#include <lustre_swab.h>
+#include <obd_cksum.h>
+#include <obd_support.h>
+#include <obd_class.h>
#include "ptlrpc_internal.h"
@@ -186,7 +186,9 @@ void lustre_init_msg_v2(struct lustre_msg_v2 *msg, int count, __u32 *lens,
for (i = 0; i < count; i++) {
char *tmp = bufs[i];
- LOGL(tmp, lens[i], ptr);
+ if (tmp)
+ memcpy(ptr, tmp, lens[i]);
+ ptr += cfs_size_round(lens[i]);
}
}
EXPORT_SYMBOL(lustre_init_msg_v2);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/pers.c b/drivers/staging/lustre/lustre/ptlrpc/pers.c
index df4994f..643388b 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/pers.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/pers.c
@@ -32,11 +32,11 @@
#define DEBUG_SUBSYSTEM S_RPC
-#include "../include/obd_support.h"
-#include "../include/obd_class.h"
-#include "../include/lustre_lib.h"
-#include "../include/lustre_ha.h"
-#include "../include/lustre_import.h"
+#include <obd_support.h>
+#include <obd_class.h>
+#include <lustre_lib.h>
+#include <lustre_ha.h>
+#include <lustre_import.h>
#include "ptlrpc_internal.h"
diff --git a/drivers/staging/lustre/lustre/ptlrpc/pinger.c b/drivers/staging/lustre/lustre/ptlrpc/pinger.c
index 5504fc2..e4de50e 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/pinger.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/pinger.c
@@ -36,8 +36,8 @@
#define DEBUG_SUBSYSTEM S_RPC
-#include "../include/obd_support.h"
-#include "../include/obd_class.h"
+#include <obd_support.h>
+#include <obd_class.h>
#include "ptlrpc_internal.h"
struct mutex pinger_mutex;
diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_module.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_module.c
index a70d584..38e488d 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_module.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_module.c
@@ -32,10 +32,10 @@
#define DEBUG_SUBSYSTEM S_RPC
-#include "../include/obd_support.h"
-#include "../include/obd_class.h"
-#include "../include/lustre_net.h"
-#include "../include/lustre_req_layout.h"
+#include <obd_support.h>
+#include <obd_class.h>
+#include <lustre_net.h>
+#include <lustre_req_layout.h>
#include "ptlrpc_internal.h"
diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
index 59b5813..0e47682 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
@@ -51,15 +51,15 @@
#define DEBUG_SUBSYSTEM S_RPC
-#include "../../include/linux/libcfs/libcfs.h"
-
-#include "../include/lustre_net.h"
-#include "../include/lustre_lib.h"
-#include "../include/lustre_ha.h"
-#include "../include/obd_class.h" /* for obd_zombie */
-#include "../include/obd_support.h" /* for OBD_FAIL_CHECK */
-#include "../include/cl_object.h" /* cl_env_{get,put}() */
-#include "../include/lprocfs_status.h"
+#include <linux/libcfs/libcfs.h>
+
+#include <lustre_net.h>
+#include <lustre_lib.h>
+#include <lustre_ha.h>
+#include <obd_class.h> /* for obd_zombie */
+#include <obd_support.h> /* for OBD_FAIL_CHECK */
+#include <cl_object.h> /* cl_env_{get,put}() */
+#include <lprocfs_status.h>
#include "ptlrpc_internal.h"
diff --git a/drivers/staging/lustre/lustre/ptlrpc/recover.c b/drivers/staging/lustre/lustre/ptlrpc/recover.c
index 7b58545..72a19a3 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/recover.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/recover.c
@@ -35,15 +35,15 @@
*/
#define DEBUG_SUBSYSTEM S_RPC
-#include "../../include/linux/libcfs/libcfs.h"
-
-#include "../include/obd_support.h"
-#include "../include/lustre_ha.h"
-#include "../include/lustre_net.h"
-#include "../include/lustre_import.h"
-#include "../include/lustre_export.h"
-#include "../include/obd.h"
-#include "../include/obd_class.h"
+#include <linux/libcfs/libcfs.h>
+
+#include <obd_support.h>
+#include <lustre_ha.h>
+#include <lustre_net.h>
+#include <lustre_import.h>
+#include <lustre_export.h>
+#include <obd.h>
+#include <obd_class.h>
#include <linux/list.h>
#include "ptlrpc_internal.h"
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec.c b/drivers/staging/lustre/lustre/ptlrpc/sec.c
index 366f2ce..cd7a539 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec.c
@@ -36,19 +36,19 @@
#define DEBUG_SUBSYSTEM S_SEC
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
#include <linux/crypto.h>
#include <linux/cred.h>
#include <linux/key.h>
#include <linux/sched/task.h>
-#include "../include/obd.h"
-#include "../include/obd_class.h"
-#include "../include/obd_support.h"
-#include "../include/lustre_net.h"
-#include "../include/lustre_import.h"
-#include "../include/lustre_dlm.h"
-#include "../include/lustre_sec.h"
+#include <obd.h>
+#include <obd_class.h>
+#include <obd_support.h>
+#include <lustre_net.h>
+#include <lustre_import.h>
+#include <lustre_dlm.h>
+#include <lustre_sec.h>
#include "ptlrpc_internal.h"
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c
index 128838a..059294a 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c
@@ -36,16 +36,16 @@
#define DEBUG_SUBSYSTEM S_SEC
-#include "../../include/linux/libcfs/libcfs.h"
-
-#include "../include/obd.h"
-#include "../include/obd_cksum.h"
-#include "../include/obd_class.h"
-#include "../include/obd_support.h"
-#include "../include/lustre_net.h"
-#include "../include/lustre_import.h"
-#include "../include/lustre_dlm.h"
-#include "../include/lustre_sec.h"
+#include <linux/libcfs/libcfs.h>
+
+#include <obd.h>
+#include <obd_cksum.h>
+#include <obd_class.h>
+#include <obd_support.h>
+#include <lustre_net.h>
+#include <lustre_import.h>
+#include <lustre_dlm.h>
+#include <lustre_sec.h>
#include "ptlrpc_internal.h"
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_config.c b/drivers/staging/lustre/lustre/ptlrpc/sec_config.c
index 2181a85..0f4af66 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_config.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_config.c
@@ -32,15 +32,16 @@
#define DEBUG_SUBSYSTEM S_SEC
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
#include <linux/crypto.h>
#include <linux/key.h>
-#include "../include/obd.h"
-#include "../include/obd_support.h"
-#include "../include/lustre_import.h"
-#include "../include/lustre_param.h"
-#include "../include/lustre_sec.h"
+#include <obd.h>
+#include <obd_class.h>
+#include <obd_support.h>
+#include <lustre_import.h>
+#include <uapi/linux/lustre/lustre_param.h>
+#include <lustre_sec.h>
#include "ptlrpc_internal.h"
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
index 8ffd000..d10a805 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
@@ -36,12 +36,12 @@
#define DEBUG_SUBSYSTEM S_SEC
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
-#include "../include/obd_support.h"
-#include "../include/obd_class.h"
-#include "../include/lustre_net.h"
-#include "../include/lustre_sec.h"
+#include <obd_support.h>
+#include <obd_class.h>
+#include <lustre_net.h>
+#include <lustre_sec.h>
#include "ptlrpc_internal.h"
@@ -66,7 +66,7 @@ void sptlrpc_gc_add_sec(struct ptlrpc_sec *sec)
sec->ps_gc_next = ktime_get_real_seconds() + sec->ps_gc_interval;
spin_lock(&sec_gc_list_lock);
- list_add_tail(&sec_gc_list, &sec->ps_gc_list);
+ list_add_tail(&sec->ps_gc_list, &sec_gc_list);
spin_unlock(&sec_gc_list_lock);
CDEBUG(D_SEC, "added sec %p(%s)\n", sec, sec->ps_policy->sp_name);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_lproc.c b/drivers/staging/lustre/lustre/ptlrpc/sec_lproc.c
index 07273f5..7792132 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_lproc.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_lproc.c
@@ -34,16 +34,16 @@
#define DEBUG_SUBSYSTEM S_SEC
-#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/libcfs/libcfs.h>
#include <linux/crypto.h>
-#include "../include/obd.h"
-#include "../include/obd_class.h"
-#include "../include/obd_support.h"
-#include "../include/lustre_net.h"
-#include "../include/lustre_import.h"
-#include "../include/lustre_dlm.h"
-#include "../include/lustre_sec.h"
+#include <obd.h>
+#include <obd_class.h>
+#include <obd_support.h>
+#include <lustre_net.h>
+#include <lustre_import.h>
+#include <lustre_dlm.h>
+#include <lustre_sec.h>
#include "ptlrpc_internal.h"
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_null.c b/drivers/staging/lustre/lustre/ptlrpc/sec_null.c
index 70a61e1..dc39a54 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_null.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_null.c
@@ -36,11 +36,11 @@
#define DEBUG_SUBSYSTEM S_SEC
-#include "../include/obd_support.h"
-#include "../include/obd_cksum.h"
-#include "../include/obd_class.h"
-#include "../include/lustre_net.h"
-#include "../include/lustre_sec.h"
+#include <obd_support.h>
+#include <obd_cksum.h>
+#include <obd_class.h>
+#include <lustre_net.h>
+#include <lustre_sec.h>
#include "ptlrpc_internal.h"
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c b/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c
index c5e7a23..6aa9b65 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c
@@ -36,11 +36,11 @@
#define DEBUG_SUBSYSTEM S_SEC
-#include "../include/obd_support.h"
-#include "../include/obd_cksum.h"
-#include "../include/obd_class.h"
-#include "../include/lustre_net.h"
-#include "../include/lustre_sec.h"
+#include <obd_support.h>
+#include <obd_cksum.h>
+#include <obd_class.h>
+#include <lustre_net.h>
+#include <lustre_sec.h>
#include "ptlrpc_internal.h"
struct plain_sec {
diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c
index 759aa6c..155f6a4 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/service.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/service.c
@@ -31,11 +31,12 @@
*/
#define DEBUG_SUBSYSTEM S_RPC
-#include "../include/obd_support.h"
-#include "../include/obd_class.h"
-#include "../include/lustre_net.h"
-#include "../include/lu_object.h"
-#include "../../include/linux/lnet/types.h"
+
+#include <obd_support.h>
+#include <obd_class.h>
+#include <lustre_net.h>
+#include <lu_object.h>
+#include <uapi/linux/lnet/lnet-types.h>
#include "ptlrpc_internal.h"
/* The following are visible and mutable through /sys/module/ptlrpc */
@@ -1565,9 +1566,9 @@ ptlrpc_server_handle_req_in(struct ptlrpc_service_part *svcpt,
/* req_in handling should/must be fast */
if (ktime_get_real_seconds() - req->rq_arrival_time.tv_sec > 5)
- DEBUG_REQ(D_WARNING, req, "Slow req_in handling " CFS_DURATION_T "s",
- (long)(ktime_get_real_seconds() -
- req->rq_arrival_time.tv_sec));
+ DEBUG_REQ(D_WARNING, req, "Slow req_in handling %llds",
+ (s64)(ktime_get_real_seconds() -
+ req->rq_arrival_time.tv_sec));
/* Set rpc server deadline and add it to the timed list */
deadline = (lustre_msghdr_get_flags(req->rq_reqmsg) &
@@ -1674,12 +1675,11 @@ ptlrpc_server_handle_request(struct ptlrpc_service_part *svcpt,
* The deadline is increased if we send an early reply.
*/
if (ktime_get_real_seconds() > request->rq_deadline) {
- DEBUG_REQ(D_ERROR, request, "Dropping timed-out request from %s: deadline " CFS_DURATION_T ":" CFS_DURATION_T "s ago\n",
+ DEBUG_REQ(D_ERROR, request, "Dropping timed-out request from %s: deadline %lld:%llds ago\n",
libcfs_id2str(request->rq_peer),
- (long)(request->rq_deadline -
- request->rq_arrival_time.tv_sec),
- (long)(ktime_get_real_seconds() -
- request->rq_deadline));
+ request->rq_deadline -
+ request->rq_arrival_time.tv_sec,
+ ktime_get_real_seconds() - request->rq_deadline);
goto put_conn;
}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/wiretest.c b/drivers/staging/lustre/lustre/ptlrpc/wiretest.c
index 367f7e2..07b86a1 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/wiretest.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/wiretest.c
@@ -35,10 +35,10 @@
#include <linux/fs.h>
#include <linux/posix_acl_xattr.h>
-#include "../include/obd_support.h"
-#include "../include/obd_class.h"
-#include "../include/lustre_net.h"
-#include "../include/lustre_disk.h"
+#include <obd_support.h>
+#include <obd_class.h>
+#include <lustre_net.h>
+#include <lustre_disk.h>
#include "ptlrpc_internal.h"
void lustre_assert_wire_constants(void)
@@ -3820,14 +3820,14 @@ void lustre_assert_wire_constants(void)
(long long)(int)offsetof(struct link_ea_header, leh_len));
LASSERTF((int)sizeof(((struct link_ea_header *)0)->leh_len) == 8, "found %lld\n",
(long long)(int)sizeof(((struct link_ea_header *)0)->leh_len));
- LASSERTF((int)offsetof(struct link_ea_header, padding1) == 16, "found %lld\n",
- (long long)(int)offsetof(struct link_ea_header, padding1));
- LASSERTF((int)sizeof(((struct link_ea_header *)0)->padding1) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct link_ea_header *)0)->padding1));
- LASSERTF((int)offsetof(struct link_ea_header, padding2) == 20, "found %lld\n",
- (long long)(int)offsetof(struct link_ea_header, padding2));
- LASSERTF((int)sizeof(((struct link_ea_header *)0)->padding2) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct link_ea_header *)0)->padding2));
+ LASSERTF((int)offsetof(struct link_ea_header, leh_overflow_time) == 16, "found %lld\n",
+ (long long)(int)offsetof(struct link_ea_header, leh_overflow_time));
+ LASSERTF((int)sizeof(((struct link_ea_header *)0)->leh_overflow_time) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct link_ea_header *)0)->leh_overflow_time));
+ LASSERTF((int)offsetof(struct link_ea_header, leh_padding) == 20, "found %lld\n",
+ (long long)(int)offsetof(struct link_ea_header, leh_padding));
+ LASSERTF((int)sizeof(((struct link_ea_header *)0)->leh_padding) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct link_ea_header *)0)->leh_padding));
BUILD_BUG_ON(LINK_EA_MAGIC != 0x11EAF1DFUL);
/* Checks for struct link_ea_entry */
diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c
index 4607d03..df7021c 100644
--- a/drivers/staging/most/hdm-dim2/dim2_hdm.c
+++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c
@@ -761,8 +761,8 @@ static int dim2_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
- dev_err(&pdev->dev, "failed to get ahb0_int irq\n");
- return -ENODEV;
+ dev_err(&pdev->dev, "failed to get ahb0_int irq: %d\n", irq);
+ return irq;
}
ret = devm_request_irq(&pdev->dev, irq, dim2_ahb_isr, 0,
@@ -774,8 +774,8 @@ static int dim2_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 1);
if (irq < 0) {
- dev_err(&pdev->dev, "failed to get mlb_int irq\n");
- return -ENODEV;
+ dev_err(&pdev->dev, "failed to get mlb_int irq: %d\n", irq);
+ return irq;
}
ret = devm_request_irq(&pdev->dev, irq, dim2_mlb_isr, 0,
@@ -894,7 +894,7 @@ static int dim2_remove(struct platform_device *pdev)
return 0;
}
-static struct platform_device_id dim2_id[] = {
+static const struct platform_device_id dim2_id[] = {
{ "medialb_dim2" },
{ }, /* Terminating entry */
};
diff --git a/drivers/staging/most/hdm-usb/hdm_usb.c b/drivers/staging/most/hdm-usb/hdm_usb.c
index d0f68cb..85775da 100644
--- a/drivers/staging/most/hdm-usb/hdm_usb.c
+++ b/drivers/staging/most/hdm-usb/hdm_usb.c
@@ -832,7 +832,7 @@ static const struct file_operations hdm_usb_fops = {
/**
* usb_device_id - ID table for HCD device probing
*/
-static struct usb_device_id usbid[] = {
+static const struct usb_device_id usbid[] = {
{ USB_DEVICE(USB_VENDOR_ID_SMSC, USB_DEV_ID_BRDG), },
{ USB_DEVICE(USB_VENDOR_ID_SMSC, USB_DEV_ID_OS81118), },
{ USB_DEVICE(USB_VENDOR_ID_SMSC, USB_DEV_ID_OS81119), },
@@ -1301,25 +1301,7 @@ static struct usb_driver hdm_usb = {
.disconnect = hdm_disconnect,
};
-static int __init hdm_usb_init(void)
-{
- pr_info("hdm_usb_init()\n");
- if (usb_register(&hdm_usb)) {
- pr_err("could not register hdm_usb driver\n");
- return -EIO;
- }
-
- return 0;
-}
-
-static void __exit hdm_usb_exit(void)
-{
- pr_info("hdm_usb_exit()\n");
- usb_deregister(&hdm_usb);
-}
-
-module_init(hdm_usb_init);
-module_exit(hdm_usb_exit);
+module_usb_driver(hdm_usb);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Christian Gromm <christian.gromm@microchip.com>");
MODULE_DESCRIPTION("HDM_4_USB");
diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c
index c1feccf..4ff8f47 100644
--- a/drivers/staging/nvec/nvec.c
+++ b/drivers/staging/nvec/nvec.c
@@ -831,7 +831,7 @@ static int tegra_nvec_probe(struct platform_device *pdev)
return -ENODEV;
}
- nvec->rst = devm_reset_control_get(&pdev->dev, "i2c");
+ nvec->rst = devm_reset_control_get_exclusive(&pdev->dev, "i2c");
if (IS_ERR(nvec->rst)) {
dev_err(nvec->dev, "failed to get controller reset\n");
return PTR_ERR(nvec->rst);
diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c
index 72baede..1a44291 100644
--- a/drivers/staging/octeon/ethernet-rx.c
+++ b/drivers/staging/octeon/ethernet-rx.c
@@ -149,6 +149,46 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work)
return 0;
}
+static void copy_segments_to_skb(cvmx_wqe_t *work, struct sk_buff *skb)
+{
+ int segments = work->word2.s.bufs;
+ union cvmx_buf_ptr segment_ptr = work->packet_ptr;
+ int len = work->word1.len;
+ int segment_size;
+
+ while (segments--) {
+ union cvmx_buf_ptr next_ptr;
+
+ next_ptr = *(union cvmx_buf_ptr *)
+ cvmx_phys_to_ptr(segment_ptr.s.addr - 8);
+
+ /*
+ * Octeon Errata PKI-100: The segment size is wrong.
+ *
+ * Until it is fixed, calculate the segment size based on
+ * the packet pool buffer size.
+ * When it is fixed, the following line should be replaced
+ * with this one:
+ * int segment_size = segment_ptr.s.size;
+ */
+ segment_size =
+ CVMX_FPA_PACKET_POOL_SIZE -
+ (segment_ptr.s.addr -
+ (((segment_ptr.s.addr >> 7) -
+ segment_ptr.s.back) << 7));
+
+ /* Don't copy more than what is left in the packet */
+ if (segment_size > len)
+ segment_size = len;
+
+ /* Copy the data into the packet */
+ skb_put_data(skb, cvmx_phys_to_ptr(segment_ptr.s.addr),
+ segment_size);
+ len -= segment_size;
+ segment_ptr = next_ptr;
+ }
+}
+
static int cvm_oct_poll(struct oct_rx_group *rx_group, int budget)
{
const int coreid = cvmx_get_core_num();
@@ -290,44 +330,7 @@ static int cvm_oct_poll(struct oct_rx_group *rx_group, int budget)
skb_put_data(skb, ptr, work->word1.len);
/* No packet buffers to free */
} else {
- int segments = work->word2.s.bufs;
- union cvmx_buf_ptr segment_ptr =
- work->packet_ptr;
- int len = work->word1.len;
-
- while (segments--) {
- union cvmx_buf_ptr next_ptr =
- *(union cvmx_buf_ptr *)
- cvmx_phys_to_ptr(
- segment_ptr.s.addr - 8);
-
- /*
- * Octeon Errata PKI-100: The segment size is
- * wrong. Until it is fixed, calculate the
- * segment size based on the packet pool
- * buffer size. When it is fixed, the
- * following line should be replaced with this
- * one: int segment_size =
- * segment_ptr.s.size;
- */
- int segment_size =
- CVMX_FPA_PACKET_POOL_SIZE -
- (segment_ptr.s.addr -
- (((segment_ptr.s.addr >> 7) -
- segment_ptr.s.back) << 7));
- /*
- * Don't copy more than what
- * is left in the packet.
- */
- if (segment_size > len)
- segment_size = len;
- /* Copy the data into the packet */
- skb_put_data(skb,
- cvmx_phys_to_ptr(segment_ptr.s.addr),
- segment_size);
- len -= segment_size;
- segment_ptr = next_ptr;
- }
+ copy_segments_to_skb(work, skb);
}
packet_not_copied = 0;
}
diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c
index f7f3a78..82bffd9 100644
--- a/drivers/staging/olpc_dcon/olpc_dcon.c
+++ b/drivers/staging/olpc_dcon/olpc_dcon.c
@@ -456,8 +456,6 @@ static ssize_t dcon_freeze_store(struct device *dev,
if (ret)
return ret;
- pr_info("dcon_freeze_store: %lu\n", output);
-
switch (output) {
case 0:
dcon_set_source(dcon, DCON_SOURCE_CPU);
diff --git a/drivers/staging/pi433/Documentation/devicetree/pi433-overlay.dts b/drivers/staging/pi433/Documentation/devicetree/pi433-overlay.dts
new file mode 100644
index 0000000..004b502
--- /dev/null
+++ b/drivers/staging/pi433/Documentation/devicetree/pi433-overlay.dts
@@ -0,0 +1,53 @@
+// Definitions for Pi433
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "bcm,bcm2835", "bcm,bcm2708", "bcm,bcm2709";
+
+ fragment@0 {
+ target = <&spi0>;
+ __overlay__ {
+ status = "okay";
+
+ spidev@0{
+ status = "disabled";
+ };
+
+ spidev@1{
+ status = "disabled";
+ };
+ };
+ };
+
+ fragment@1 {
+ target = <&gpio>;
+ __overlay__ {
+ pi433_pins: pi433_pins {
+ brcm,pins = <7 25 24>;
+ brcm,function = <0 0 0>; // in in in
+ };
+ };
+ };
+
+ fragment@2 {
+ target = <&spi0>;
+ __overlay__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ pi433: pi433@0 {
+ compatible = "Smarthome-Wolf,pi433";
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+ status = "okay";
+
+ pinctrl-0 = <&pi433_pins>;
+ DIO0-gpio = <&gpio 24 0>;
+ DIO1-gpio = <&gpio 25 0>;
+ DIO2-gpio = <&gpio 7 0>;
+ };
+ };
+ };
+};
diff --git a/drivers/staging/pi433/Documentation/devicetree/pi433.txt b/drivers/staging/pi433/Documentation/devicetree/pi433.txt
new file mode 100644
index 0000000..9ff217f
--- /dev/null
+++ b/drivers/staging/pi433/Documentation/devicetree/pi433.txt
@@ -0,0 +1,62 @@
+* Smarthome-Wolf Pi433 - a 433MHz radio module/shield for Raspberry Pi (see www.pi433.de)
+
+Required properties:
+- compatible: must be "Smarthome-Wolf,pi433"
+- reg: chip select of SPI Interface
+- DIOx-gpio must be dedicated to the GPIO, connected with DIOx of the RFM69 module
+
+
+Example:
+
+With the following lines in gpio-section, the gpio pins, connected with pi433 are
+reserved/declared.
+
+&gpio{
+ [...]
+
+ pi433_pins: pi433_pins {
+ brcm,pins = <7 25 24>;
+ brcm,function = <0 0 0>; // in in in
+ };
+
+ [...]
+}
+
+With the following lines in spi section, the device pi433 is declared.
+It consists of the three gpio pins and an spi interface (here chip select 0)
+
+&spi0{
+ [...]
+
+ pi433: pi433@0 {
+ compatible = "Smarthome-Wolf,pi433";
+ reg = <0>; /* CE 0 */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ spi-max-frequency = <10000000>;
+
+ pinctrl-0 = <&pi433_pins>;
+ DIO0-gpio = <&gpio 24 0>;
+ DIO1-gpio = <&gpio 25 0>;
+ DIO2-gpio = <&gpio 7 0>;
+ };
+}
+
+
+
+For Raspbian users only
+=======================
+Since Raspbian supports device tree overlays, you may use and overlay, instead
+of editing your boards device tree.
+For using the overlay, you need to compile the file pi433-overlay.dts you can
+find aside to this documentation.
+The file needs to be compiled - either manually or by integration in your kernel
+source tree. For a manual compile, you may use a command line like the following:
+'linux/scripts/dtc/dtc -@ -I dts -O dtb -o pi433.dtbo pi433-overlay.dts'
+
+For compiling inside of the kernel tree, you need to copy pi433-overlay.dts to
+arch/arm/boot/dts/overlays and you need to add the file to the list of files
+in the Makefile over there. Execute 'make dtbs' in kernel tree root to make the
+kernel make files compile the device tree overlay for you.
+
+
diff --git a/drivers/staging/pi433/Documentation/pi433.txt b/drivers/staging/pi433/Documentation/pi433.txt
new file mode 100644
index 0000000..38b83b8
--- /dev/null
+++ b/drivers/staging/pi433/Documentation/pi433.txt
@@ -0,0 +1,274 @@
+=====
+Pi433
+=====
+
+
+Introduction
+============
+This driver is for controlling pi433, a radio module for the Raspberry Pi
+(www.pi433.de). It supports transmission and reception. It can be opened
+by multiple applications for transmission and reception. While transmit
+jobs were queued and process automatically in the background, the first
+application asking for reception will block out all other applications
+until something gets received terminates the read request.
+The driver supports on the fly reloading of the hardware fifo of the rf
+chip, thus enabling for much longer telegrams then hardware fifo size.
+
+Discription of driver operation
+===============================
+
+a) transmission
+
+Each transmission can take place with a different configuration of the rf
+module. Therfore each application can set its own set of parameters. The driver
+takes care, that each transmission takes place with the parameterset of the
+application, that requests the transmission. To allow the transmission to take
+place in the background, a tx thread is introduced.
+The transfer of data from the main thread to the tx thread is realised by a
+kfifo. With each write request of an application, the passed in data and the
+corresponding parameter set gets written to the kfifo.
+On the other "side" of the kfifo, the tx thread continuously checks, whether the
+kfifo is empty. If not, it gets one set of config and data from the kfifo. If
+there is no receive request or the receiver is still waiting for something in
+the air, the rf module is set to standby, the parameters for transmission gets
+set, the hardware fifo of the rf chip gets preloaded and the transmission gets
+started. Upon hardware fifo threshold interrupt it gets reloaded, thus enabling
+much longer telegrams then hardware fifo size. If the telegram is send and there
+is more data available in the kfifo, the procedure is repeated. If not the
+transmission cycle ends.
+
+b) reception
+
+Since there is only one application allowed to receive data at a time, for
+reception there is only one configuration set.
+As soon as an application sets an request for receiving a telegram, the reception
+configuration set is written to the rf module and it gets set into receiving mode.
+Now the driver is waiting, that a predefined RSSI level (signal strength at the
+receiver) is reached. Until this hasn't happened, the reception can be
+interrupted by the transmission thread at any time to insert a transmission cycle.
+As soon as the predefined RSSI level is meat, a receiving cycle starts. Similar
+as described for the transmission cycle the read out of the hardware fifo is done
+dynamically. Upon each hardware fifo threshold interrupt, a portion of data gets
+read. So also for reception it is possible to receive more data then the hardware
+fifo can hold.
+
+
+Driver API
+==========
+
+The driver is currently implemented as a character device. Therefore it supports
+the calls open, ioctl, read, write and close.
+
+
+params for ioctl
+----------------
+
+There are four options:
+PI433_IOC_RD_TX_CFG - get the transmission parameters from the driver
+PI433_IOC_WR_TX_CFG - set the transmission parameters
+PI433_IOC_RD_RX_CFG - get the receiving parameters from the driver
+PI433_IOC_WR_RX_CFG - set the receiving parameters
+
+The tx configuration is transfered via struct pi433_tx_cfg, the parameterset for transmission.
+It is devided into two sections: rf parameters and packet format.
+
+rf params:
+ frequency
+ frequency used for transmission.
+ Allowed values: 433050000...434790000
+ bit_rate
+ bit rate used for transmission.
+ Allowed values: #####
+ dev_frequency
+ frequency deviation in case of FSK.
+ Allowed values: 600...500000
+ modulation
+ FSK - frequency shift key
+ OOK - On-Off-key
+ modShaping
+ shapingOff - no shaping
+ shaping1_0 - gauss filter with BT 1 (FSK only)
+ shaping0_5 - gauss filter with BT 0.5 (FSK only)
+ shaping0_3 - gauss filter with BT 0.3 (FSK only)
+ shapingBR - filter cut off at BR (OOK only)
+ shaping2BR - filter cut off at 2*BR (OOK only)
+ paRamp (FSK only)
+ ramp3400 - amp ramps up in 3.4ms
+ ramp2000 - amp ramps up in 2.0ms
+ ramp1000 - amp ramps up in 1ms
+ ramp500 - amp ramps up in 500us
+ ramp250 - amp ramps up in 250us
+ ramp125 - amp ramps up in 125us
+ ramp100 - amp ramps up in 100us
+ ramp62 - amp ramps up in 62us
+ ramp50 - amp ramps up in 50us
+ ramp40 - amp ramps up in 40us
+ ramp31 - amp ramps up in 31us
+ ramp25 - amp ramps up in 25us
+ ramp20 - amp ramps up in 20us
+ ramp15 - amp ramps up in 15us
+ ramp12 - amp ramps up in 12us
+ ramp10 - amp ramps up in 10us
+ tx_start_condition
+ fifoLevel - transmission starts, if fifo is filled to
+ threshold level
+ fifoNotEmpty - transmission starts, as soon as there is one
+ byte in internal fifo
+ repetitions
+ This gives the option, to send a telegram multiple times. Default: 1
+
+packet format:
+ enable_preamble
+ optionOn - a preamble will be automatically generated
+ optionOff - no preamble will be generated
+ enable_sync
+ optionOn - a sync word will be automatically added to
+ the telegram after preamble
+ optionOff - no sync word will be added
+ Attention: While possible to generate sync without preamble, the
+ receiver won't be able to detect the sync without preamble.
+ enable_length_byte
+ optionOn - the length of the telegram will be automatically
+ added to the telegram. It's part of the payload
+ optionOff - no length information will be automatically added
+ to the telegram.
+ Attention: For telegram length over 255 bytes, this option can't be used
+ Attention: should be used in combination with sync, only
+ enable_address_byte
+ optionOn - the address byte will be automatically added to the
+ telgram. It's part of the payload
+ optionOff - the address byte will not be added to the telegram.
+ The address byte can be used for address filtering, so the receiver
+ will only receive telegrams with a given address byte.
+ Attention: should be used in combination with sync, only
+ enable_crc
+ optionOn - an crc will be automatically calculated over the
+ payload of the telegram and added to the telegram
+ after payload.
+ optionOff - no crc will be calculated
+ preamble_length
+ length of the preamble. Allowed values: 0...65536
+ sync_length
+ length of the sync word. Allowed values: 0...8
+ fixed_message_length
+ length of the payload of the telegram. Will override the length
+ given by the buffer, passed in with the write command. Will be
+ ignored if set to zero.
+ sync_pattern[8]
+ contains up to eight values, that are used as the sync pattern
+ on sync option
+ address_byte
+ one byte, used as address byte on address byte option.
+
+
+The rx configuration is transfered via struct pi433_rx_cfg, the parameterset for receiving. It is devided into two sections: rf parameters and packet format.
+
+rf params:
+ frequency
+ frequency used for transmission.
+ Allowed values: 433050000...434790000
+ bit_rate
+ bit rate used for transmission.
+ Allowed values: #####
+ dev_frequency
+ frequency deviation in case of FSK.
+ Allowed values: 600...500000
+ modulation
+ FSK - frequency shift key
+ OOK - on off key
+ rssi_threshold
+ threshold value for the signal strength on the receiver input.
+ If this value is exeeded, a reception cycle starts
+ Allowed values: 0...255
+ thresholdDecrement
+ in order to adapt to different levels of singnal strength, over
+ time the receiver gets more and more sensitive. This value
+ determs, how fast the sensitivity increases.
+ step_0_5db - increase in 0,5dB steps
+ step_1_0db - increase in 1 db steps
+ step_1_5db - increase in 1,5dB steps
+ step_2_0db - increase in 2 db steps
+ step_3_0db - increase in 3 db steps
+ step_4_0db - increase in 4 db steps
+ step_5_0db - increase in 5 db steps
+ step_6_0db - increase in 6 db steps
+ antennaImpedance
+ sets the electrical adoption of the antenna
+ fiftyOhm - for antennas with an impedance of 50Ohm
+ twohundretOhm - for antennas with an impedance of 200Ohm
+ lnaGain
+ sets the gain of the low noise amp
+ automatic - lna gain is determed by an agc
+ max - lna gain is set to maximum
+ maxMinus6 - lna gain is set to 6db below max
+ maxMinus12 - lna gain is set to 12db below max
+ maxMinus24 - lna gain is set to 24db below max
+ maxMinus36 - lna gain is set to 36db below max
+ maxMinus48 - lna gain is set to 48db below max
+ bw_mantisse
+ sets the bandwidth of the channel filter - part one: mantisse.
+ mantisse16 - mantisse is set to 16
+ mantisse20 - mantisse is set to 20
+ mantisse24 - mantisse is set to 24
+ bw_exponent
+ sets the bandwidth of the channel filter - part two: exponent.
+ Allowd values: 0...7
+ dagc;
+ operation mode of the digital automatic gain control
+ normalMode
+ improve
+ improve4LowModulationIndex
+
+ packet format:
+ enable_sync
+ optionOn - sync detection is enabled. If configured sync pattern
+ isn't found, telegram will be internally discarded
+ optionOff - sync detection is disabled.
+ enable_length_byte
+ optionOn - First byte of payload will be used as length byte,
+ regardless of the amount of bytes that were requested
+ by the read request.
+ optionOff - Number of bytes to be read will be set according to
+ amount of bytes that were requested by the read request.
+ Attention: should be used in combination with sync, only
+ enable_address_filtering;
+ filteringOff - no adress filtering will take place
+ nodeAddress - all telegrams, not matching the node
+ address will be internally discarded
+ nodeOrBroadcastAddress - all telegrams, neither matching the
+ node, nor the broadcast address will
+ be internally discarded
+ Attention: Sync option must be enabled in order to use this feature
+ enable_crc
+ optionOn - a crc will be calculated over the payload of
+ the telegram, that was received. If the
+ calculated crc doesn't match to two bytes,
+ that follow the payload, the telegram will be
+ internally discarded.
+ Attention: This option is only operational, if sync on and fixed length
+ or length byte is used
+ sync_length
+ Gives the length of the payload.
+ Attention: This setting must meet the setting of the transmitter,
+ if sync option is used.
+ fixed_message_length
+ Overrides the telegram length either given by the first byte of
+ payload or by the read request.
+ bytes_to_drop
+ gives the number of bytes, that will be dropped before transfering
+ data to the read buffer
+ This option is only usefull, if all packet helper are switched
+ off and the rf chip is used in raw receiving mode. This may be
+ needed, if a telegram of a third party device should be received,
+ using a protocol not compatible with the packet engine of the rf69 chip.
+ sync_pattern[8]
+ contains up to eight values, that are used as the sync pattern
+ on sync option.
+ This setting must meet the configuration of the transmitting device,
+ if sync option is enabled.
+ node_address
+ one byte, used as node address byte on address byte option.
+ broadcast_address
+ one byte, used as broadcast address byte on address byte option.
+
+
diff --git a/drivers/staging/pi433/Kconfig b/drivers/staging/pi433/Kconfig
new file mode 100644
index 0000000..87c2ee1
--- /dev/null
+++ b/drivers/staging/pi433/Kconfig
@@ -0,0 +1,16 @@
+config PI433
+ tristate "Pi433 - a 433MHz radio module for Raspberry Pi"
+ depends on SPI
+ ---help---
+ This option allows you to enable support for the radio module Pi433.
+
+ Pi433 is a shield that fits onto the GPIO header of a Raspberry Pi
+ or compatible. It extends the Raspberry Pi with the option, to
+ send and receive data in the 433MHz ISM band - for example to
+ communicate between two systems without using ethernet or bluetooth
+ or for control or read sockets, actors, sensors, widely available
+ for low price.
+
+ For details or the option to buy, please visit https://pi433.de/en.html
+
+ If in doubt, say N here, but saying yes most probably won't hurt
diff --git a/drivers/staging/pi433/Makefile b/drivers/staging/pi433/Makefile
new file mode 100644
index 0000000..417f3e4
--- /dev/null
+++ b/drivers/staging/pi433/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_PI433) += pi433.o
+
+pi433-objs := pi433_if.o rf69.o
diff --git a/drivers/staging/pi433/TODO b/drivers/staging/pi433/TODO
new file mode 100644
index 0000000..63a40bf
--- /dev/null
+++ b/drivers/staging/pi433/TODO
@@ -0,0 +1,5 @@
+* coding style does not fully comply with the kernel style guide.
+* still TODOs, annotated in the code
+* currently the code introduces new IOCTLs. I'm afraid this is a bad idea.
+ -> Replace this with another interface, hints are welcome!
+* Some missing data (marked with ###) needs to be added in the documentation
diff --git a/drivers/staging/pi433/pi433_if.c b/drivers/staging/pi433/pi433_if.c
new file mode 100644
index 0000000..93c0168
--- /dev/null
+++ b/drivers/staging/pi433/pi433_if.c
@@ -0,0 +1,1338 @@
+/*
+ * userspace interface for pi433 radio module
+ *
+ * Pi433 is a 433MHz radio module for the Raspberry Pi.
+ * It is based on the HopeRf Module RFM69CW. Therefore inside of this
+ * driver, you'll find an abstraction of the rf69 chip.
+ *
+ * If needed, this driver could be extended, to also support other
+ * devices, basing on HopeRfs rf69.
+ *
+ * The driver can also be extended, to support other modules of
+ * HopeRf with a similar interace - e. g. RFM69HCW, RFM12, RFM95, ...
+ *
+ * Copyright (C) 2016 Wolf-Entwicklungen
+ * Marcus Wolf <linux@wolf-entwicklungen.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+#undef DEBUG
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/idr.h>
+#include <linux/ioctl.h>
+#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/cdev.h>
+#include <linux/err.h>
+#include <linux/kfifo.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio/consumer.h>
+#include <linux/kthread.h>
+#include <linux/wait.h>
+#include <linux/spi/spi.h>
+#ifdef CONFIG_COMPAT
+#include <asm/compat.h>
+#endif
+
+#include "pi433_if.h"
+#include "rf69.h"
+
+
+#define N_PI433_MINORS (1U << MINORBITS) /*32*/ /* ... up to 256 */
+#define MAX_MSG_SIZE 900 /* min: FIFO_SIZE! */
+#define MSG_FIFO_SIZE 65536 /* 65536 = 2^16 */
+#define NUM_DIO 2
+
+static dev_t pi433_dev;
+static DEFINE_IDR(pi433_idr);
+static DEFINE_MUTEX(minor_lock); /* Protect idr accesses */
+
+static struct class *pi433_class; /* mainly for udev to create /dev/pi433 */
+
+/* tx config is instance specific
+ * so with each open a new tx config struct is needed
+ */
+/* rx config is device specific
+ * so we have just one rx config, ebedded in device struct
+ */
+struct pi433_device {
+ /* device handling related values */
+ dev_t devt;
+ int minor;
+ struct device *dev;
+ struct cdev *cdev;
+ struct spi_device *spi;
+ unsigned users;
+
+ /* irq related values */
+ struct gpio_desc *gpiod[NUM_DIO];
+ int irq_num[NUM_DIO];
+ u8 irq_state[NUM_DIO];
+
+ /* tx related values */
+ STRUCT_KFIFO_REC_1(MSG_FIFO_SIZE) tx_fifo;
+ struct mutex tx_fifo_lock; // TODO: check, whether necessary or obsolete
+ struct task_struct *tx_task_struct;
+ wait_queue_head_t tx_wait_queue;
+ u8 free_in_fifo;
+ char buffer[MAX_MSG_SIZE];
+
+ /* rx related values */
+ struct pi433_rx_cfg rx_cfg;
+ u8 *rx_buffer;
+ unsigned int rx_buffer_size;
+ u32 rx_bytes_to_drop;
+ u32 rx_bytes_dropped;
+ unsigned int rx_position;
+ struct mutex rx_lock;
+ wait_queue_head_t rx_wait_queue;
+
+ /* fifo wait queue */
+ struct task_struct *fifo_task_struct;
+ wait_queue_head_t fifo_wait_queue;
+
+ /* flags */
+ bool rx_active;
+ bool tx_active;
+ bool interrupt_rx_allowed;
+};
+
+struct pi433_instance {
+ struct pi433_device *device;
+ struct pi433_tx_cfg tx_cfg;
+};
+
+/*-------------------------------------------------------------------------*/
+
+/* macro for checked access of registers of radio module */
+#define SET_CHECKED(retval) \
+ if (retval < 0) \
+ return retval;
+
+/*-------------------------------------------------------------------------*/
+
+/* GPIO interrupt handlers */
+static irqreturn_t DIO0_irq_handler(int irq, void *dev_id)
+{
+ struct pi433_device *device = dev_id;
+
+ if (device->irq_state[DIO0] == DIO_PacketSent)
+ {
+ device->free_in_fifo = FIFO_SIZE;
+ printk("DIO0 irq: Packet sent\n"); // TODO: printk() should include KERN_ facility level
+ wake_up_interruptible(&device->fifo_wait_queue);
+ }
+ else if (device->irq_state[DIO0] == DIO_Rssi_DIO0)
+ {
+ printk("DIO0 irq: RSSI level over threshold\n");
+ wake_up_interruptible(&device->rx_wait_queue);
+ }
+ else if (device->irq_state[DIO0] == DIO_PayloadReady)
+ {
+ printk("DIO0 irq: PayloadReady\n");
+ device->free_in_fifo = 0;
+ wake_up_interruptible(&device->fifo_wait_queue);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t DIO1_irq_handler(int irq, void *dev_id)
+{
+ struct pi433_device *device = dev_id;
+
+ if (device->irq_state[DIO1] == DIO_FifoNotEmpty_DIO1)
+ {
+ device->free_in_fifo = FIFO_SIZE;
+ }
+ else if (device->irq_state[DIO1] == DIO_FifoLevel)
+ {
+ if (device->rx_active) device->free_in_fifo = FIFO_THRESHOLD - 1;
+ else device->free_in_fifo = FIFO_SIZE - FIFO_THRESHOLD - 1;
+ }
+ printk("DIO1 irq: %d bytes free in fifo\n", device->free_in_fifo); // TODO: printk() should include KERN_ facility level
+ wake_up_interruptible(&device->fifo_wait_queue);
+
+ return IRQ_HANDLED;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int
+rf69_set_rx_cfg(struct pi433_device *dev, struct pi433_rx_cfg *rx_cfg)
+{
+ int ret;
+ int payload_length;
+
+ /* receiver config */
+ SET_CHECKED(rf69_set_frequency (dev->spi, rx_cfg->frequency));
+ SET_CHECKED(rf69_set_bit_rate (dev->spi, rx_cfg->bit_rate));
+ SET_CHECKED(rf69_set_modulation (dev->spi, rx_cfg->modulation));
+ SET_CHECKED(rf69_set_antenna_impedance (dev->spi, rx_cfg->antenna_impedance));
+ SET_CHECKED(rf69_set_rssi_threshold (dev->spi, rx_cfg->rssi_threshold));
+ SET_CHECKED(rf69_set_ook_threshold_dec (dev->spi, rx_cfg->thresholdDecrement));
+ SET_CHECKED(rf69_set_bandwidth (dev->spi, rx_cfg->bw_mantisse, rx_cfg->bw_exponent));
+ SET_CHECKED(rf69_set_bandwidth_during_afc(dev->spi, rx_cfg->bw_mantisse, rx_cfg->bw_exponent));
+ SET_CHECKED(rf69_set_dagc (dev->spi, rx_cfg->dagc));
+
+ dev->rx_bytes_to_drop = rx_cfg->bytes_to_drop;
+
+ /* packet config */
+ /* enable */
+ SET_CHECKED(rf69_set_sync_enable(dev->spi, rx_cfg->enable_sync));
+ if (rx_cfg->enable_sync == optionOn)
+ {
+ SET_CHECKED(rf69_set_fifo_fill_condition(dev->spi, afterSyncInterrupt));
+ }
+ else
+ {
+ SET_CHECKED(rf69_set_fifo_fill_condition(dev->spi, always));
+ }
+ if (rx_cfg->enable_length_byte == optionOn) {
+ ret = rf69_set_packet_format(dev->spi, packetLengthVar);
+ if (ret < 0)
+ return ret;
+ } else {
+ ret = rf69_set_packet_format(dev->spi, packetLengthFix);
+ if (ret < 0)
+ return ret;
+ }
+ SET_CHECKED(rf69_set_adressFiltering(dev->spi, rx_cfg->enable_address_filtering));
+ SET_CHECKED(rf69_set_crc_enable (dev->spi, rx_cfg->enable_crc));
+
+ /* lengths */
+ SET_CHECKED(rf69_set_sync_size(dev->spi, rx_cfg->sync_length));
+ if (rx_cfg->enable_length_byte == optionOn)
+ {
+ SET_CHECKED(rf69_set_payload_length(dev->spi, 0xff));
+ }
+ else if (rx_cfg->fixed_message_length != 0)
+ {
+ payload_length = rx_cfg->fixed_message_length;
+ if (rx_cfg->enable_length_byte == optionOn) payload_length++;
+ if (rx_cfg->enable_address_filtering != filteringOff) payload_length++;
+ SET_CHECKED(rf69_set_payload_length(dev->spi, payload_length));
+ }
+ else
+ {
+ SET_CHECKED(rf69_set_payload_length(dev->spi, 0));
+ }
+
+ /* values */
+ if (rx_cfg->enable_sync == optionOn)
+ {
+ SET_CHECKED(rf69_set_sync_values(dev->spi, rx_cfg->sync_pattern));
+ }
+ if (rx_cfg->enable_address_filtering != filteringOff)
+ {
+ SET_CHECKED(rf69_set_node_address (dev->spi, rx_cfg->node_address));
+ SET_CHECKED(rf69_set_broadcast_address(dev->spi, rx_cfg->broadcast_address));
+ }
+
+ return 0;
+}
+
+static int
+rf69_set_tx_cfg(struct pi433_device *dev, struct pi433_tx_cfg *tx_cfg)
+{
+ int ret;
+
+ SET_CHECKED(rf69_set_frequency (dev->spi, tx_cfg->frequency));
+ SET_CHECKED(rf69_set_bit_rate (dev->spi, tx_cfg->bit_rate));
+ SET_CHECKED(rf69_set_modulation (dev->spi, tx_cfg->modulation));
+ SET_CHECKED(rf69_set_deviation (dev->spi, tx_cfg->dev_frequency));
+ SET_CHECKED(rf69_set_pa_ramp (dev->spi, tx_cfg->pa_ramp));
+ SET_CHECKED(rf69_set_modulation_shaping(dev->spi, tx_cfg->modShaping));
+ SET_CHECKED(rf69_set_tx_start_condition(dev->spi, tx_cfg->tx_start_condition));
+
+ /* packet format enable */
+ if (tx_cfg->enable_preamble == optionOn)
+ {
+ SET_CHECKED(rf69_set_preamble_length(dev->spi, tx_cfg->preamble_length));
+ }
+ else
+ {
+ SET_CHECKED(rf69_set_preamble_length(dev->spi, 0));
+ }
+ SET_CHECKED(rf69_set_sync_enable (dev->spi, tx_cfg->enable_sync));
+ if (tx_cfg->enable_length_byte == optionOn) {
+ ret = rf69_set_packet_format(dev->spi, packetLengthVar);
+ if (ret < 0)
+ return ret;
+ } else {
+ ret = rf69_set_packet_format(dev->spi, packetLengthFix);
+ if (ret < 0)
+ return ret;
+ }
+ SET_CHECKED(rf69_set_crc_enable (dev->spi, tx_cfg->enable_crc));
+
+ /* configure sync, if enabled */
+ if (tx_cfg->enable_sync == optionOn)
+ {
+ SET_CHECKED(rf69_set_sync_size(dev->spi, tx_cfg->sync_length));
+ SET_CHECKED(rf69_set_sync_values(dev->spi, tx_cfg->sync_pattern));
+ }
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int
+pi433_start_rx(struct pi433_device *dev)
+{
+ int retval;
+
+ /* return without action, if no pending read request */
+ if (!dev->rx_active)
+ return 0;
+
+ /* setup for receiving */
+ retval = rf69_set_rx_cfg(dev, &dev->rx_cfg);
+ if (retval) return retval;
+
+ /* setup rssi irq */
+ SET_CHECKED(rf69_set_dio_mapping(dev->spi, DIO0, DIO_Rssi_DIO0));
+ dev->irq_state[DIO0] = DIO_Rssi_DIO0;
+ irq_set_irq_type(dev->irq_num[DIO0], IRQ_TYPE_EDGE_RISING);
+
+ /* setup fifo level interrupt */
+ SET_CHECKED(rf69_set_fifo_threshold(dev->spi, FIFO_SIZE - FIFO_THRESHOLD));
+ SET_CHECKED(rf69_set_dio_mapping(dev->spi, DIO1, DIO_FifoLevel));
+ dev->irq_state[DIO1] = DIO_FifoLevel;
+ irq_set_irq_type(dev->irq_num[DIO1], IRQ_TYPE_EDGE_RISING);
+
+ /* set module to receiving mode */
+ SET_CHECKED(rf69_set_mode(dev->spi, receive));
+
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static int
+pi433_receive(void *data)
+{
+ struct pi433_device *dev = data;
+ struct spi_device *spi = dev->spi; /* needed for SET_CHECKED */
+ int bytes_to_read, bytes_total;
+ int retval;
+
+ dev->interrupt_rx_allowed = false;
+
+ /* wait for any tx to finish */
+ dev_dbg(dev->dev,"rx: going to wait for any tx to finish");
+ retval = wait_event_interruptible(dev->rx_wait_queue, !dev->tx_active);
+ if(retval) /* wait was interrupted */
+ {
+ dev->interrupt_rx_allowed = true;
+ wake_up_interruptible(&dev->tx_wait_queue);
+ return retval;
+ }
+
+ /* prepare status vars */
+ dev->free_in_fifo = FIFO_SIZE;
+ dev->rx_position = 0;
+ dev->rx_bytes_dropped = 0;
+
+ /* setup radio module to listen for something "in the air" */
+ retval = pi433_start_rx(dev);
+ if (retval)
+ return retval;
+
+ /* now check RSSI, if low wait for getting high (RSSI interrupt) */
+ while ( !rf69_get_flag(dev->spi, rssiExceededThreshold) )
+ {
+ /* allow tx to interrupt us while waiting for high RSSI */
+ dev->interrupt_rx_allowed = true;
+ wake_up_interruptible(&dev->tx_wait_queue);
+
+ /* wait for RSSI level to become high */
+ dev_dbg(dev->dev, "rx: going to wait for high RSSI level");
+ retval = wait_event_interruptible(dev->rx_wait_queue,
+ rf69_get_flag(dev->spi,
+ rssiExceededThreshold));
+ if (retval) goto abort; /* wait was interrupted */
+ dev->interrupt_rx_allowed = false;
+
+ /* cross check for ongoing tx */
+ if (!dev->tx_active) break;
+ }
+
+ /* configure payload ready irq */
+ SET_CHECKED(rf69_set_dio_mapping(spi, DIO0, DIO_PayloadReady));
+ dev->irq_state[DIO0] = DIO_PayloadReady;
+ irq_set_irq_type(dev->irq_num[DIO0], IRQ_TYPE_EDGE_RISING);
+
+ /* fixed or unlimited length? */
+ if (dev->rx_cfg.fixed_message_length != 0)
+ {
+ if (dev->rx_cfg.fixed_message_length > dev->rx_buffer_size)
+ {
+ retval = -1;
+ goto abort;
+ }
+ bytes_total = dev->rx_cfg.fixed_message_length;
+ dev_dbg(dev->dev,"rx: msg len set to %d by fixed length", bytes_total);
+ }
+ else
+ {
+ bytes_total = dev->rx_buffer_size;
+ dev_dbg(dev->dev, "rx: msg len set to %d as requested by read", bytes_total);
+ }
+
+ /* length byte enabled? */
+ if (dev->rx_cfg.enable_length_byte == optionOn)
+ {
+ retval = wait_event_interruptible(dev->fifo_wait_queue,
+ dev->free_in_fifo < FIFO_SIZE);
+ if (retval) goto abort; /* wait was interrupted */
+
+ rf69_read_fifo(spi, (u8 *)&bytes_total, 1);
+ if (bytes_total > dev->rx_buffer_size)
+ {
+ retval = -1;
+ goto abort;
+ }
+ dev->free_in_fifo++;
+ dev_dbg(dev->dev, "rx: msg len reset to %d due to length byte", bytes_total);
+ }
+
+ /* address byte enabled? */
+ if (dev->rx_cfg.enable_address_filtering != filteringOff)
+ {
+ u8 dummy;
+
+ bytes_total--;
+
+ retval = wait_event_interruptible(dev->fifo_wait_queue,
+ dev->free_in_fifo < FIFO_SIZE);
+ if (retval) goto abort; /* wait was interrupted */
+
+ rf69_read_fifo(spi, &dummy, 1);
+ dev->free_in_fifo++;
+ dev_dbg(dev->dev, "rx: address byte stripped off");
+ }
+
+ /* get payload */
+ while (dev->rx_position < bytes_total)
+ {
+ if ( !rf69_get_flag(dev->spi, payloadReady) )
+ {
+ retval = wait_event_interruptible(dev->fifo_wait_queue,
+ dev->free_in_fifo < FIFO_SIZE);
+ if (retval) goto abort; /* wait was interrupted */
+ }
+
+ /* need to drop bytes or acquire? */
+ if (dev->rx_bytes_to_drop > dev->rx_bytes_dropped)
+ bytes_to_read = dev->rx_bytes_to_drop - dev->rx_bytes_dropped;
+ else
+ bytes_to_read = bytes_total - dev->rx_position;
+
+
+ /* access the fifo */
+ if (bytes_to_read > FIFO_SIZE - dev->free_in_fifo)
+ bytes_to_read = FIFO_SIZE - dev->free_in_fifo;
+ retval = rf69_read_fifo(spi,
+ &dev->rx_buffer[dev->rx_position],
+ bytes_to_read);
+ if (retval) goto abort; /* read failed */
+ dev->free_in_fifo += bytes_to_read;
+
+ /* adjust status vars */
+ if (dev->rx_bytes_to_drop > dev->rx_bytes_dropped)
+ dev->rx_bytes_dropped += bytes_to_read;
+ else
+ dev->rx_position += bytes_to_read;
+ }
+
+
+ /* rx done, wait was interrupted or error occured */
+abort:
+ dev->interrupt_rx_allowed = true;
+ SET_CHECKED(rf69_set_mode(dev->spi, standby));
+ wake_up_interruptible(&dev->tx_wait_queue);
+
+ if (retval)
+ return retval;
+ else
+ return bytes_total;
+}
+
+static int
+pi433_tx_thread(void *data)
+{
+ struct pi433_device *device = data;
+ struct spi_device *spi = device->spi; /* needed for SET_CHECKED */
+ struct pi433_tx_cfg tx_cfg;
+ u8 *buffer = device->buffer;
+ size_t size;
+ bool rx_interrupted = false;
+ int position, repetitions;
+ int retval;
+
+ while (1)
+ {
+ /* wait for fifo to be populated or for request to terminate*/
+ dev_dbg(device->dev, "thread: going to wait for new messages");
+ wait_event_interruptible(device->tx_wait_queue,
+ ( !kfifo_is_empty(&device->tx_fifo) ||
+ kthread_should_stop() ));
+ if ( kthread_should_stop() )
+ return 0;
+
+ /* get data from fifo in the following order:
+ * - tx_cfg
+ * - size of message
+ * - message
+ */
+ mutex_lock(&device->tx_fifo_lock);
+
+ retval = kfifo_out(&device->tx_fifo, &tx_cfg, sizeof(tx_cfg));
+ if (retval != sizeof(tx_cfg))
+ {
+ dev_dbg(device->dev, "reading tx_cfg from fifo failed: got %d byte(s), expected %d", retval, (unsigned int)sizeof(tx_cfg) );
+ mutex_unlock(&device->tx_fifo_lock);
+ continue;
+ }
+
+ retval = kfifo_out(&device->tx_fifo, &size, sizeof(size_t));
+ if (retval != sizeof(size_t))
+ {
+ dev_dbg(device->dev, "reading msg size from fifo failed: got %d, expected %d", retval, (unsigned int)sizeof(size_t) );
+ mutex_unlock(&device->tx_fifo_lock);
+ continue;
+ }
+
+ /* use fixed message length, if requested */
+ if (tx_cfg.fixed_message_length != 0)
+ size = tx_cfg.fixed_message_length;
+
+ /* increase size, if len byte is requested */
+ if (tx_cfg.enable_length_byte == optionOn)
+ size++;
+
+ /* increase size, if adr byte is requested */
+ if (tx_cfg.enable_address_byte == optionOn)
+ size++;
+
+ /* prime buffer */
+ memset(buffer, 0, size);
+ position = 0;
+
+ /* add length byte, if requested */
+ if (tx_cfg.enable_length_byte == optionOn)
+ buffer[position++] = size-1; /* according to spec length byte itself must be excluded from the length calculation */
+
+ /* add adr byte, if requested */
+ if (tx_cfg.enable_address_byte == optionOn)
+ buffer[position++] = tx_cfg.address_byte;
+
+ /* finally get message data from fifo */
+ retval = kfifo_out(&device->tx_fifo, &buffer[position], sizeof(buffer)-position );
+ dev_dbg(device->dev, "read %d message byte(s) from fifo queue.", retval);
+ mutex_unlock(&device->tx_fifo_lock);
+
+ /* if rx is active, we need to interrupt the waiting for
+ * incoming telegrams, to be able to send something.
+ * We are only allowed, if currently no reception takes
+ * place otherwise we need to wait for the incoming telegram
+ * to finish
+ */
+ wait_event_interruptible(device->tx_wait_queue,
+ !device->rx_active ||
+ device->interrupt_rx_allowed == true);
+
+ /* prevent race conditions
+ * irq will be reenabled after tx config is set
+ */
+ disable_irq(device->irq_num[DIO0]);
+ device->tx_active = true;
+
+ if (device->rx_active && rx_interrupted == false)
+ {
+ /* rx is currently waiting for a telegram;
+ * we need to set the radio module to standby
+ */
+ SET_CHECKED(rf69_set_mode(device->spi, standby));
+ rx_interrupted = true;
+ }
+
+ /* clear fifo, set fifo threshold, set payload length */
+ SET_CHECKED(rf69_set_mode(spi, standby)); /* this clears the fifo */
+ SET_CHECKED(rf69_set_fifo_threshold(spi, FIFO_THRESHOLD));
+ if (tx_cfg.enable_length_byte == optionOn)
+ {
+ SET_CHECKED(rf69_set_payload_length(spi, size * tx_cfg.repetitions));
+ }
+ else
+ {
+ SET_CHECKED(rf69_set_payload_length(spi, 0));
+ }
+
+ /* configure the rf chip */
+ rf69_set_tx_cfg(device, &tx_cfg);
+
+ /* enable fifo level interrupt */
+ SET_CHECKED(rf69_set_dio_mapping(spi, DIO1, DIO_FifoLevel));
+ device->irq_state[DIO1] = DIO_FifoLevel;
+ irq_set_irq_type(device->irq_num[DIO1], IRQ_TYPE_EDGE_FALLING);
+
+ /* enable packet sent interrupt */
+ SET_CHECKED(rf69_set_dio_mapping(spi, DIO0, DIO_PacketSent));
+ device->irq_state[DIO0] = DIO_PacketSent;
+ irq_set_irq_type(device->irq_num[DIO0], IRQ_TYPE_EDGE_RISING);
+ enable_irq(device->irq_num[DIO0]); /* was disabled by rx active check */
+
+ /* enable transmission */
+ SET_CHECKED(rf69_set_mode(spi, transmit));
+
+ /* transfer this msg (and repetitions) to chip fifo */
+ device->free_in_fifo = FIFO_SIZE;
+ position = 0;
+ repetitions = tx_cfg.repetitions;
+ while( (repetitions > 0) && (size > position) )
+ {
+ if ( (size - position) > device->free_in_fifo)
+ { /* msg to big for fifo - take a part */
+ int temp = device->free_in_fifo;
+ device->free_in_fifo = 0;
+ rf69_write_fifo(spi,
+ &buffer[position],
+ temp);
+ position +=temp;
+ }
+ else
+ { /* msg fits into fifo - take all */
+ device->free_in_fifo -= size;
+ repetitions--;
+ rf69_write_fifo(spi,
+ &buffer[position],
+ (size - position) );
+ position = 0; /* reset for next repetition */
+ }
+
+ retval = wait_event_interruptible(device->fifo_wait_queue,
+ device->free_in_fifo > 0);
+ if (retval) { printk("ABORT\n"); goto abort; }
+ }
+
+ /* we are done. Wait for packet to get sent */
+ dev_dbg(device->dev, "thread: wait for packet to get sent/fifo to be empty");
+ wait_event_interruptible(device->fifo_wait_queue,
+ device->free_in_fifo == FIFO_SIZE ||
+ kthread_should_stop() );
+ if ( kthread_should_stop() ) printk("ABORT\n");
+
+
+ /* STOP_TRANSMISSION */
+ dev_dbg(device->dev, "thread: Packet sent. Set mode to stby.");
+ SET_CHECKED(rf69_set_mode(spi, standby));
+
+ /* everything sent? */
+ if ( kfifo_is_empty(&device->tx_fifo) )
+ {
+abort:
+ if (rx_interrupted)
+ {
+ rx_interrupted = false;
+ pi433_start_rx(device);
+ }
+ device->tx_active = false;
+ wake_up_interruptible(&device->rx_wait_queue);
+ }
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+
+static ssize_t
+pi433_read(struct file *filp, char __user *buf, size_t size, loff_t *f_pos)
+{
+ struct pi433_instance *instance;
+ struct pi433_device *device;
+ int bytes_received;
+ ssize_t retval;
+
+ /* check, whether internal buffer is big enough for requested size */
+ if (size > MAX_MSG_SIZE)
+ return -EMSGSIZE;
+
+ instance = filp->private_data;
+ device = instance->device;
+
+ /* just one read request at a time */
+ mutex_lock(&device->rx_lock);
+ if (device->rx_active)
+ {
+ mutex_unlock(&device->rx_lock);
+ return -EAGAIN;
+ }
+ else
+ {
+ device->rx_active = true;
+ mutex_unlock(&device->rx_lock);
+ }
+
+ /* start receiving */
+ /* will block until something was received*/
+ device->rx_buffer_size = size;
+ bytes_received = pi433_receive(device);
+
+ /* release rx */
+ mutex_lock(&device->rx_lock);
+ device->rx_active = false;
+ mutex_unlock(&device->rx_lock);
+
+ /* if read was successful copy to user space*/
+ if (bytes_received > 0)
+ {
+ retval = copy_to_user(buf, device->rx_buffer, bytes_received);
+ if (retval)
+ return -EFAULT;
+ }
+
+ return bytes_received;
+}
+
+
+static ssize_t
+pi433_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *f_pos)
+{
+ struct pi433_instance *instance;
+ struct pi433_device *device;
+ int copied, retval;
+
+ instance = filp->private_data;
+ device = instance->device;
+
+ /* check, whether internal buffer (tx thread) is big enough for requested size */
+ if (count > MAX_MSG_SIZE)
+ return -EMSGSIZE;
+
+ /* write the following sequence into fifo:
+ * - tx_cfg
+ * - size of message
+ * - message
+ */
+ mutex_lock(&device->tx_fifo_lock);
+ retval = kfifo_in(&device->tx_fifo, &instance->tx_cfg, sizeof(instance->tx_cfg));
+ if ( retval != sizeof(instance->tx_cfg) )
+ goto abort;
+
+ retval = kfifo_in (&device->tx_fifo, &count, sizeof(size_t));
+ if ( retval != sizeof(size_t) )
+ goto abort;
+
+ retval = kfifo_from_user(&device->tx_fifo, buf, count, &copied);
+ if (retval || copied != count)
+ goto abort;
+
+ mutex_unlock(&device->tx_fifo_lock);
+
+ /* start transfer */
+ wake_up_interruptible(&device->tx_wait_queue);
+ dev_dbg(device->dev, "write: generated new msg with %d bytes.", copied);
+
+ return 0;
+
+abort:
+ dev_dbg(device->dev, "write to fifo failed: 0x%x", retval);
+ kfifo_reset(&device->tx_fifo); // TODO: maybe find a solution, not to discard already stored, valid entries
+ mutex_unlock(&device->tx_fifo_lock);
+ return -EAGAIN;
+}
+
+
+static long
+pi433_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ int err = 0;
+ int retval = 0;
+ struct pi433_instance *instance;
+ struct pi433_device *device;
+ u32 tmp;
+
+ /* Check type and command number */
+ if (_IOC_TYPE(cmd) != PI433_IOC_MAGIC)
+ return -ENOTTY;
+
+ /* Check access direction once here; don't repeat below.
+ * IOC_DIR is from the user perspective, while access_ok is
+ * from the kernel perspective; so they look reversed.
+ */
+ if (_IOC_DIR(cmd) & _IOC_READ)
+ err = !access_ok(VERIFY_WRITE,
+ (void __user *)arg,
+ _IOC_SIZE(cmd));
+
+ if (err == 0 && _IOC_DIR(cmd) & _IOC_WRITE)
+ err = !access_ok(VERIFY_READ,
+ (void __user *)arg,
+ _IOC_SIZE(cmd));
+ if (err)
+ return -EFAULT;
+
+ /* TODO? guard against device removal before, or while,
+ * we issue this ioctl. --> device_get()
+ */
+ instance = filp->private_data;
+ device = instance->device;
+
+ if (device == NULL)
+ return -ESHUTDOWN;
+
+ switch (cmd) {
+ case PI433_IOC_RD_TX_CFG:
+ tmp = _IOC_SIZE(cmd);
+ if ( (tmp == 0) || ((tmp % sizeof(struct pi433_tx_cfg)) != 0) )
+ {
+ retval = -EINVAL;
+ break;
+ }
+
+ if (__copy_to_user((void __user *)arg,
+ &instance->tx_cfg,
+ tmp))
+ {
+ retval = -EFAULT;
+ break;
+ }
+
+ break;
+ case PI433_IOC_WR_TX_CFG:
+ tmp = _IOC_SIZE(cmd);
+ if ( (tmp == 0) || ((tmp % sizeof(struct pi433_tx_cfg)) != 0) )
+ {
+ retval = -EINVAL;
+ break;
+ }
+
+ if (__copy_from_user(&instance->tx_cfg,
+ (void __user *)arg,
+ tmp))
+ {
+ retval = -EFAULT;
+ break;
+ }
+
+ break;
+
+ case PI433_IOC_RD_RX_CFG:
+ tmp = _IOC_SIZE(cmd);
+ if ( (tmp == 0) || ((tmp % sizeof(struct pi433_rx_cfg)) != 0) ) {
+ retval = -EINVAL;
+ break;
+ }
+
+ if (__copy_to_user((void __user *)arg,
+ &device->rx_cfg,
+ tmp))
+ {
+ retval = -EFAULT;
+ break;
+ }
+
+ break;
+ case PI433_IOC_WR_RX_CFG:
+ tmp = _IOC_SIZE(cmd);
+ mutex_lock(&device->rx_lock);
+
+ /* during pendig read request, change of config not allowed */
+ if (device->rx_active) {
+ retval = -EAGAIN;
+ mutex_unlock(&device->rx_lock);
+ break;
+ }
+
+ if ( (tmp == 0) || ((tmp % sizeof(struct pi433_rx_cfg)) != 0) ) {
+ retval = -EINVAL;
+ mutex_unlock(&device->rx_lock);
+ break;
+ }
+
+ if (__copy_from_user(&device->rx_cfg,
+ (void __user *)arg,
+ tmp))
+ {
+ retval = -EFAULT;
+ mutex_unlock(&device->rx_lock);
+ break;
+ }
+
+ mutex_unlock(&device->rx_lock);
+ break;
+ default:
+ retval = -EINVAL;
+ }
+
+ return retval;
+}
+
+#ifdef CONFIG_COMPAT
+static long
+pi433_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ return pi433_ioctl(filp, cmd, (unsigned long)compat_ptr(arg));
+}
+#else
+#define pi433_compat_ioctl NULL
+#endif /* CONFIG_COMPAT */
+
+/*-------------------------------------------------------------------------*/
+
+static int pi433_open(struct inode *inode, struct file *filp)
+{
+ struct pi433_device *device;
+ struct pi433_instance *instance;
+
+ mutex_lock(&minor_lock);
+ device = idr_find(&pi433_idr, iminor(inode));
+ mutex_unlock(&minor_lock);
+ if (!device) {
+ pr_debug("device: minor %d unknown.\n", iminor(inode));
+ return -ENODEV;
+ }
+
+ if (!device->rx_buffer) {
+ device->rx_buffer = kmalloc(MAX_MSG_SIZE, GFP_KERNEL);
+ if (!device->rx_buffer)
+ {
+ dev_dbg(device->dev, "open/ENOMEM\n");
+ return -ENOMEM;
+ }
+ }
+
+ device->users++;
+ instance = kzalloc(sizeof(*instance), GFP_KERNEL);
+ if (!instance)
+ {
+ kfree(device->rx_buffer);
+ device->rx_buffer = NULL;
+ return -ENOMEM;
+ }
+
+ /* setup instance data*/
+ instance->device = device;
+ instance->tx_cfg.bit_rate = 4711;
+ // TODO: fill instance->tx_cfg;
+
+ /* instance data as context */
+ filp->private_data = instance;
+ nonseekable_open(inode, filp);
+
+ return 0;
+}
+
+static int pi433_release(struct inode *inode, struct file *filp)
+{
+ struct pi433_instance *instance;
+ struct pi433_device *device;
+
+ instance = filp->private_data;
+ device = instance->device;
+ kfree(instance);
+ filp->private_data = NULL;
+
+ /* last close? */
+ device->users--;
+
+ if (!device->users) {
+ kfree(device->rx_buffer);
+ device->rx_buffer = NULL;
+ if (device->spi == NULL)
+ kfree(device);
+ }
+
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static int setup_GPIOs(struct pi433_device *device)
+{
+ char name[5];
+ int retval;
+ int i;
+ const irq_handler_t DIO_irq_handler[NUM_DIO] = {
+ DIO0_irq_handler,
+ DIO1_irq_handler
+ };
+
+ for (i=0; i<NUM_DIO; i++)
+ {
+ /* "construct" name and get the gpio descriptor */
+ snprintf(name, sizeof(name), "DIO%d", i);
+ device->gpiod[i] = gpiod_get(&device->spi->dev, name, 0 /*GPIOD_IN*/);
+
+ if (device->gpiod[i] == ERR_PTR(-ENOENT))
+ {
+ dev_dbg(&device->spi->dev, "Could not find entry for %s. Ignoring.", name);
+ continue;
+ }
+
+ if (device->gpiod[i] == ERR_PTR(-EBUSY))
+ dev_dbg(&device->spi->dev, "%s is busy.", name);
+
+ if ( IS_ERR(device->gpiod[i]) )
+ {
+ retval = PTR_ERR(device->gpiod[i]);
+ /* release already allocated gpios */
+ for (i--; i>=0; i--)
+ {
+ free_irq(device->irq_num[i], device);
+ gpiod_put(device->gpiod[i]);
+ }
+ return retval;
+ }
+
+
+ /* configure the pin */
+ gpiod_unexport(device->gpiod[i]);
+ retval = gpiod_direction_input(device->gpiod[i]);
+ if (retval) return retval;
+
+
+ /* configure irq */
+ device->irq_num[i] = gpiod_to_irq(device->gpiod[i]);
+ if (device->irq_num[i] < 0)
+ {
+ device->gpiod[i] = ERR_PTR(-EINVAL);//(struct gpio_desc *)device->irq_num[i];
+ return device->irq_num[i];
+ }
+ retval = request_irq(device->irq_num[i],
+ DIO_irq_handler[i],
+ 0, /* flags */
+ name,
+ device);
+
+ if (retval)
+ return retval;
+
+ dev_dbg(&device->spi->dev, "%s succesfully configured", name);
+ }
+
+ return 0;
+}
+
+static void free_GPIOs(struct pi433_device *device)
+{
+ int i;
+
+ for (i=0; i<NUM_DIO; i++)
+ {
+ /* check if gpiod is valid */
+ if ( IS_ERR(device->gpiod[i]) )
+ continue;
+
+ free_irq(device->irq_num[i], device);
+ gpiod_put(device->gpiod[i]);
+ }
+ return;
+}
+
+static int pi433_get_minor(struct pi433_device *device)
+{
+ int retval = -ENOMEM;
+
+ mutex_lock(&minor_lock);
+ retval = idr_alloc(&pi433_idr, device, 0, N_PI433_MINORS, GFP_KERNEL);
+ if (retval >= 0) {
+ device->minor = retval;
+ retval = 0;
+ } else if (retval == -ENOSPC) {
+ dev_err(device->dev, "too many pi433 devices\n");
+ retval = -EINVAL;
+ }
+ mutex_unlock(&minor_lock);
+ return retval;
+}
+
+static void pi433_free_minor(struct pi433_device *dev)
+{
+ mutex_lock(&minor_lock);
+ idr_remove(&pi433_idr, dev->minor);
+ mutex_unlock(&minor_lock);
+}
+/*-------------------------------------------------------------------------*/
+
+static const struct file_operations pi433_fops = {
+ .owner = THIS_MODULE,
+ /* REVISIT switch to aio primitives, so that userspace
+ * gets more complete API coverage. It'll simplify things
+ * too, except for the locking.
+ */
+ .write = pi433_write,
+ .read = pi433_read,
+ .unlocked_ioctl = pi433_ioctl,
+ .compat_ioctl = pi433_compat_ioctl,
+ .open = pi433_open,
+ .release = pi433_release,
+ .llseek = no_llseek,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int pi433_probe(struct spi_device *spi)
+{
+ struct pi433_device *device;
+ int retval;
+
+ /* setup spi parameters */
+ spi->mode = 0x00;
+ spi->bits_per_word = 8;
+ /* spi->max_speed_hz = 10000000; 1MHz already set by device tree overlay */
+
+ retval = spi_setup(spi);
+ if (retval)
+ {
+ dev_dbg(&spi->dev, "configuration of SPI interface failed!\n");
+ return retval;
+ }
+ else
+ {
+ dev_dbg(&spi->dev,
+ "spi interface setup: mode 0x%2x, %d bits per word, %dhz max speed",
+ spi->mode, spi->bits_per_word, spi->max_speed_hz);
+ }
+
+ /* Ping the chip by reading the version register */
+ retval = spi_w8r8(spi, 0x10);
+ if (retval < 0)
+ return retval;
+
+ switch (retval) {
+ case 0x24:
+ dev_dbg(&spi->dev, "found pi433 (ver. 0x%x)", retval);
+ break;
+ default:
+ dev_dbg(&spi->dev, "unknown chip version: 0x%x", retval);
+ return -ENODEV;
+ }
+
+ /* Allocate driver data */
+ device = kzalloc(sizeof(*device), GFP_KERNEL);
+ if (!device)
+ return -ENOMEM;
+
+ /* Initialize the driver data */
+ device->spi = spi;
+ device->rx_active = false;
+ device->tx_active = false;
+ device->interrupt_rx_allowed = false;
+
+ /* init wait queues */
+ init_waitqueue_head(&device->tx_wait_queue);
+ init_waitqueue_head(&device->rx_wait_queue);
+ init_waitqueue_head(&device->fifo_wait_queue);
+
+ /* init fifo */
+ INIT_KFIFO(device->tx_fifo);
+
+ /* init mutexes and locks */
+ mutex_init(&device->tx_fifo_lock);
+ mutex_init(&device->rx_lock);
+
+ /* setup GPIO (including irq_handler) for the different DIOs */
+ retval = setup_GPIOs(device);
+ if (retval)
+ {
+ dev_dbg(&spi->dev, "setup of GPIOs failed");
+ goto GPIO_failed;
+ }
+
+ /* setup the radio module */
+ SET_CHECKED(rf69_set_mode (spi, standby));
+ SET_CHECKED(rf69_set_data_mode (spi, packet));
+ SET_CHECKED(rf69_set_amplifier_0 (spi, optionOn));
+ SET_CHECKED(rf69_set_amplifier_1 (spi, optionOff));
+ SET_CHECKED(rf69_set_amplifier_2 (spi, optionOff));
+ SET_CHECKED(rf69_set_output_power_level (spi, 13));
+ SET_CHECKED(rf69_set_antenna_impedance (spi, fiftyOhm));
+
+ /* start tx thread */
+ device->tx_task_struct = kthread_run(pi433_tx_thread,
+ device,
+ "pi433_tx_task");
+ if (IS_ERR(device->tx_task_struct))
+ {
+ dev_dbg(device->dev, "start of send thread failed");
+ goto send_thread_failed;
+ }
+
+ /* determ minor number */
+ retval = pi433_get_minor(device);
+ if (retval)
+ {
+ dev_dbg(device->dev, "get of minor number failed");
+ goto minor_failed;
+ }
+
+ /* create device */
+ device->devt = MKDEV(MAJOR(pi433_dev), device->minor);
+ device->dev = device_create(pi433_class,
+ &spi->dev,
+ device->devt,
+ device,
+ "pi433");
+ if (IS_ERR(device->dev)) {
+ pr_err("pi433: device register failed\n");
+ retval = PTR_ERR(device->dev);
+ goto device_create_failed;
+ }
+ else {
+ dev_dbg(device->dev,
+ "created device for major %d, minor %d\n",
+ MAJOR(pi433_dev),
+ device->minor);
+ }
+
+ /* create cdev */
+ device->cdev = cdev_alloc();
+ device->cdev->owner = THIS_MODULE;
+ cdev_init(device->cdev, &pi433_fops);
+ retval = cdev_add(device->cdev, device->devt, 1);
+ if (retval)
+ {
+ dev_dbg(device->dev, "register of cdev failed");
+ goto cdev_failed;
+ }
+
+ /* spi setup */
+ spi_set_drvdata(spi, device);
+
+ return 0;
+
+cdev_failed:
+ device_destroy(pi433_class, device->devt);
+device_create_failed:
+ pi433_free_minor(device);
+minor_failed:
+ kthread_stop(device->tx_task_struct);
+send_thread_failed:
+ free_GPIOs(device);
+GPIO_failed:
+ kfree(device);
+
+ return retval;
+}
+
+static int pi433_remove(struct spi_device *spi)
+{
+ struct pi433_device *device = spi_get_drvdata(spi);
+
+ /* free GPIOs */
+ free_GPIOs(device);
+
+ /* make sure ops on existing fds can abort cleanly */
+ device->spi = NULL;
+
+ kthread_stop(device->tx_task_struct);
+
+ device_destroy(pi433_class, device->devt);
+
+ cdev_del(device->cdev);
+
+ pi433_free_minor(device);
+
+ if (device->users == 0)
+ kfree(device);
+
+ return 0;
+}
+
+static const struct of_device_id pi433_dt_ids[] = {
+ { .compatible = "Smarthome-Wolf,pi433" },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, pi433_dt_ids);
+
+static struct spi_driver pi433_spi_driver = {
+ .driver = {
+ .name = "pi433",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(pi433_dt_ids),
+ },
+ .probe = pi433_probe,
+ .remove = pi433_remove,
+
+ /* NOTE: suspend/resume methods are not necessary here.
+ * We don't do anything except pass the requests to/from
+ * the underlying controller. The refrigerator handles
+ * most issues; the controller driver handles the rest.
+ */
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int __init pi433_init(void)
+{
+ int status;
+
+ /* If MAX_MSG_SIZE is smaller then FIFO_SIZE, the driver won't
+ * work stable - risk of buffer overflow
+ */
+ if (MAX_MSG_SIZE < FIFO_SIZE)
+ return -EINVAL;
+
+ /* Claim device numbers. Then register a class
+ * that will key udev/mdev to add/remove /dev nodes. Last, register
+ * Last, register the driver which manages those device numbers.
+ */
+ status = alloc_chrdev_region(&pi433_dev, 0 /*firstminor*/, N_PI433_MINORS /*count*/, "pi433" /*name*/);
+ if (status < 0)
+ return status;
+
+ pi433_class = class_create(THIS_MODULE, "pi433");
+ if (IS_ERR(pi433_class))
+ {
+ unregister_chrdev(MAJOR(pi433_dev), pi433_spi_driver.driver.name);
+ return PTR_ERR(pi433_class);
+ }
+
+ status = spi_register_driver(&pi433_spi_driver);
+ if (status < 0)
+ {
+ class_destroy(pi433_class);
+ unregister_chrdev(MAJOR(pi433_dev), pi433_spi_driver.driver.name);
+ }
+
+ return status;
+}
+
+module_init(pi433_init);
+
+static void __exit pi433_exit(void)
+{
+ spi_unregister_driver(&pi433_spi_driver);
+ class_destroy(pi433_class);
+ unregister_chrdev(MAJOR(pi433_dev), pi433_spi_driver.driver.name);
+}
+module_exit(pi433_exit);
+
+MODULE_AUTHOR("Marcus Wolf, <linux@wolf-entwicklungen.de>");
+MODULE_DESCRIPTION("Driver for Pi433");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("spi:pi433");
diff --git a/drivers/staging/pi433/pi433_if.h b/drivers/staging/pi433/pi433_if.h
new file mode 100644
index 0000000..e6ed3cd
--- /dev/null
+++ b/drivers/staging/pi433/pi433_if.h
@@ -0,0 +1,152 @@
+/*
+ * include/linux/TODO
+ *
+ * userspace interface for pi433 radio module
+ *
+ * Pi433 is a 433MHz radio module for the Raspberry Pi.
+ * It is based on the HopeRf Module RFM69CW. Therefore inside of this
+ * driver, you'll find an abstraction of the rf69 chip.
+ *
+ * If needed, this driver could be extended, to also support other
+ * devices, basing on HopeRfs rf69.
+ *
+ * The driver can also be extended, to support other modules of
+ * HopeRf with a similar interace - e. g. RFM69HCW, RFM12, RFM95, ...
+ * Copyright (C) 2016 Wolf-Entwicklungen
+ * Marcus Wolf <linux@wolf-entwicklungen.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 PI433_H
+#define PI433_H
+
+#include <linux/types.h>
+#include "rf69_enum.h"
+
+/*---------------------------------------------------------------------------*/
+
+
+/*---------------------------------------------------------------------------*/
+
+/* IOCTL structs and commands */
+
+/**
+ * struct pi433_tx_config - describes the configuration of the radio module for sending
+ * @frequency:
+ * @bit_rate:
+ * @modulation:
+ * @data_mode:
+ * @preamble_length:
+ * @sync_pattern:
+ * @tx_start_condition:
+ * @payload_length:
+ * @repetitions:
+ *
+ * ATTENTION:
+ * If the contents of 'pi433_tx_config' ever change
+ * incompatibly, then the ioctl number (see define below) must change.
+ *
+ * NOTE: struct layout is the same in 64bit and 32bit userspace.
+ */
+#define PI433_TX_CFG_IOCTL_NR 0
+struct pi433_tx_cfg
+{
+ __u32 frequency;
+ __u16 bit_rate;
+ __u32 dev_frequency;
+ enum modulation modulation;
+ enum modShaping modShaping;
+
+ enum paRamp pa_ramp;
+
+ enum txStartCondition tx_start_condition;
+
+ __u16 repetitions;
+
+
+ /* packet format */
+ enum optionOnOff enable_preamble;
+ enum optionOnOff enable_sync;
+ enum optionOnOff enable_length_byte;
+ enum optionOnOff enable_address_byte;
+ enum optionOnOff enable_crc;
+
+ __u16 preamble_length;
+ __u8 sync_length;
+ __u8 fixed_message_length;
+
+ __u8 sync_pattern[8];
+ __u8 address_byte;
+};
+
+
+/**
+ * struct pi433_rx_config - describes the configuration of the radio module for sending
+ * @frequency:
+ * @bit_rate:
+ * @modulation:
+ * @data_mode:
+ * @preamble_length:
+ * @sync_pattern:
+ * @tx_start_condition:
+ * @payload_length:
+ * @repetitions:
+ *
+ * ATTENTION:
+ * If the contents of 'pi433_rx_config' ever change
+ * incompatibly, then the ioctl number (see define below) must change
+ *
+ * NOTE: struct layout is the same in 64bit and 32bit userspace.
+ */
+#define PI433_RX_CFG_IOCTL_NR 1
+struct pi433_rx_cfg {
+ __u32 frequency;
+ __u16 bit_rate;
+ __u32 dev_frequency;
+
+ enum modulation modulation;
+
+ __u8 rssi_threshold;
+ enum thresholdDecrement thresholdDecrement;
+ enum antennaImpedance antenna_impedance;
+ enum lnaGain lna_gain;
+ enum mantisse bw_mantisse; /* normal: 0x50 */
+ __u8 bw_exponent; /* during AFC: 0x8b */
+ enum dagc dagc;
+
+
+
+ /* packet format */
+ enum optionOnOff enable_sync;
+ enum optionOnOff enable_length_byte; /* should be used in combination with sync, only */
+ enum addressFiltering enable_address_filtering; /* operational with sync, only */
+ enum optionOnOff enable_crc; /* only operational, if sync on and fixed length or length byte is used */
+
+ __u8 sync_length;
+ __u8 fixed_message_length;
+ __u32 bytes_to_drop;
+
+ __u8 sync_pattern[8];
+ __u8 node_address;
+ __u8 broadcast_address;
+};
+
+
+#define PI433_IOC_MAGIC 'r'
+
+#define PI433_IOC_RD_TX_CFG _IOR(PI433_IOC_MAGIC, PI433_TX_CFG_IOCTL_NR, char[sizeof(struct pi433_tx_cfg)])
+#define PI433_IOC_WR_TX_CFG _IOW(PI433_IOC_MAGIC, PI433_TX_CFG_IOCTL_NR, char[sizeof(struct pi433_tx_cfg)])
+
+#define PI433_IOC_RD_RX_CFG _IOR(PI433_IOC_MAGIC, PI433_RX_CFG_IOCTL_NR, char[sizeof(struct pi433_rx_cfg)])
+#define PI433_IOC_WR_RX_CFG _IOW(PI433_IOC_MAGIC, PI433_RX_CFG_IOCTL_NR, char[sizeof(struct pi433_rx_cfg)])
+
+#endif /* PI433_H */
diff --git a/drivers/staging/pi433/rf69.c b/drivers/staging/pi433/rf69.c
new file mode 100644
index 0000000..c4b1b21
--- /dev/null
+++ b/drivers/staging/pi433/rf69.c
@@ -0,0 +1,1032 @@
+/*
+ * abstraction of the spi interface of HopeRf rf69 radio module
+ *
+ * Copyright (C) 2016 Wolf-Entwicklungen
+ * Marcus Wolf <linux@wolf-entwicklungen.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+/* enable prosa debug info */
+#undef DEBUG
+/* enable print of values on reg access */
+#undef DEBUG_VALUES
+/* enable print of values on fifo access */
+#undef DEBUG_FIFO_ACCESS
+
+#include <linux/types.h>
+#include <linux/spi/spi.h>
+
+#include "rf69.h"
+#include "rf69_registers.h"
+
+#define F_OSC 32000000 /* in Hz */
+#define FIFO_SIZE 66 /* in byte */
+
+/*-------------------------------------------------------------------------*/
+
+#define READ_REG(x) rf69_read_reg (spi, x)
+#define WRITE_REG(x,y) rf69_write_reg(spi, x, y)
+
+/*-------------------------------------------------------------------------*/
+
+int rf69_set_mode(struct spi_device *spi, enum mode mode)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: mode");
+ #endif
+
+ switch (mode) {
+ case transmit: return WRITE_REG(REG_OPMODE, (READ_REG(REG_OPMODE) & ~MASK_OPMODE_MODE) | OPMODE_MODE_TRANSMIT);
+ case receive: return WRITE_REG(REG_OPMODE, (READ_REG(REG_OPMODE) & ~MASK_OPMODE_MODE) | OPMODE_MODE_RECEIVE);
+ case synthesizer: return WRITE_REG(REG_OPMODE, (READ_REG(REG_OPMODE) & ~MASK_OPMODE_MODE) | OPMODE_MODE_SYNTHESIZER);
+ case standby: return WRITE_REG(REG_OPMODE, (READ_REG(REG_OPMODE) & ~MASK_OPMODE_MODE) | OPMODE_MODE_STANDBY);
+ case mode_sleep: return WRITE_REG(REG_OPMODE, (READ_REG(REG_OPMODE) & ~MASK_OPMODE_MODE) | OPMODE_MODE_SLEEP);
+ default:
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+
+ // we are using packet mode, so this check is not really needed
+ // but waiting for mode ready is necessary when going from sleep because the FIFO may not be immediately available from previous mode
+ //while (_mode == RF69_MODE_SLEEP && (READ_REG(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00); // Wait for ModeReady
+
+}
+
+int rf69_set_data_mode(struct spi_device *spi, enum dataMode dataMode)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: data mode");
+ #endif
+
+ switch (dataMode) {
+ case packet: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODE) | DATAMODUL_MODE_PACKET);
+ case continuous: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODE) | DATAMODUL_MODE_CONTINUOUS);
+ case continuousNoSync: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODE) | DATAMODUL_MODE_CONTINUOUS_NOSYNC);
+ default:
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+}
+
+int rf69_set_modulation(struct spi_device *spi, enum modulation modulation)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: modulation");
+ #endif
+
+ switch (modulation) {
+ case OOK: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_TYPE) | DATAMODUL_MODULATION_TYPE_OOK);
+ case FSK: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_TYPE) | DATAMODUL_MODULATION_TYPE_FSK);
+ default:
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+}
+
+enum modulation rf69_get_modulation(struct spi_device *spi)
+{
+ u8 currentValue;
+
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "get: mode");
+ #endif
+
+ currentValue = READ_REG(REG_DATAMODUL);
+
+ switch (currentValue & MASK_DATAMODUL_MODULATION_TYPE >> 3) { // TODO improvement: change 3 to define
+ case DATAMODUL_MODULATION_TYPE_OOK: return OOK;
+ case DATAMODUL_MODULATION_TYPE_FSK: return FSK;
+ default: return undefined;
+ }
+}
+
+int rf69_set_modulation_shaping(struct spi_device *spi, enum modShaping modShaping)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: mod shaping");
+ #endif
+
+ if (rf69_get_modulation(spi) == FSK) {
+ switch (modShaping) {
+ case shapingOff: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_NONE);
+ case shaping1_0: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_1_0);
+ case shaping0_5: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_0_3);
+ case shaping0_3: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_0_5);
+ default:
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+ } else {
+ switch (modShaping) {
+ case shapingOff: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_NONE);
+ case shapingBR: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_BR);
+ case shaping2BR: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_2BR);
+ default:
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+ }
+}
+
+int rf69_set_bit_rate(struct spi_device *spi, u16 bitRate)
+{
+ int retval;
+ u32 bitRate_min;
+ u32 bitRate_reg;
+ u8 msb;
+ u8 lsb;
+
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: bit rate");
+ #endif
+
+ // check input value
+ bitRate_min = F_OSC / 8388608; // 8388608 = 2^23;
+ if (bitRate < bitRate_min) {
+ dev_dbg(&spi->dev, "setBitRate: illegal input param");
+ return -EINVAL;
+ }
+
+ // calculate reg settings
+ bitRate_reg = (F_OSC / bitRate);
+
+ msb = (bitRate_reg&0xff00) >> 8;
+ lsb = (bitRate_reg&0xff);
+
+ // transmit to RF 69
+ retval = WRITE_REG(REG_BITRATE_MSB, msb);
+ if (retval) return retval;
+ retval = WRITE_REG(REG_BITRATE_LSB, lsb);
+ if (retval) return retval;
+
+ return 0;
+}
+
+int rf69_set_deviation(struct spi_device *spi, u32 deviation)
+{
+ int retval;
+// u32 f_max; TODO: Abhängigkeit von Bitrate beachten!!
+ u64 f_reg;
+ u64 f_step;
+ u8 msb;
+ u8 lsb;
+ u64 factor = 1000000; // to improve precision of calculation
+
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: deviation");
+ #endif
+
+ if (deviation < 600 || deviation > 500000) { //TODO: Abhängigkeit von Bitrate beachten!!
+ dev_dbg(&spi->dev, "set_deviation: illegal input param");
+ return -EINVAL;
+ }
+
+ // calculat f step
+ f_step = F_OSC * factor;
+ do_div(f_step, 524288); // 524288 = 2^19
+
+ // calculate register settings
+ f_reg = deviation * factor;
+ do_div(f_reg , f_step);
+
+ msb = (f_reg&0xff00) >> 8;
+ lsb = (f_reg&0xff);
+
+ // check msb
+ if (msb & ~FDEVMASB_MASK) {
+ dev_dbg(&spi->dev, "set_deviation: err in calc of msb");
+ return -EINVAL;
+ }
+
+ // write to chip
+ retval = WRITE_REG(REG_FDEV_MSB, msb);
+ if (retval) return retval;
+ retval = WRITE_REG(REG_FDEV_LSB, lsb);
+ if (retval) return retval;
+
+ return 0;
+}
+
+int rf69_set_frequency(struct spi_device *spi, u32 frequency)
+{
+ int retval;
+ u32 f_max;
+ u64 f_reg;
+ u64 f_step;
+ u8 msb;
+ u8 mid;
+ u8 lsb;
+ u64 factor = 1000000; // to improve precision of calculation
+
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: frequency");
+ #endif
+
+ // calculat f step
+ f_step = F_OSC * factor;
+ do_div(f_step, 524288); // 524288 = 2^19
+
+ // check input value
+ f_max = div_u64(f_step * 8388608, factor);
+ if (frequency > f_max) {
+ dev_dbg(&spi->dev, "setFrequency: illegal input param");
+ return -EINVAL;
+ }
+
+ // calculate reg settings
+ f_reg = frequency * factor;
+ do_div(f_reg , f_step);
+
+ msb = (f_reg&0xff0000) >> 16;
+ mid = (f_reg&0xff00) >> 8;
+ lsb = (f_reg&0xff);
+
+ // write to chip
+ retval = WRITE_REG(REG_FRF_MSB, msb);
+ if (retval) return retval;
+ retval = WRITE_REG(REG_FRF_MID, mid);
+ if (retval) return retval;
+ retval = WRITE_REG(REG_FRF_LSB, lsb);
+ if (retval) return retval;
+
+ return 0;
+}
+
+int rf69_set_amplifier_0(struct spi_device *spi, enum optionOnOff optionOnOff)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: amp #0");
+ #endif
+
+ switch(optionOnOff) {
+ case optionOn: return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) | MASK_PALEVEL_PA0) );
+ case optionOff: return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) & ~MASK_PALEVEL_PA0) );
+ default:
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+}
+
+int rf69_set_amplifier_1(struct spi_device *spi, enum optionOnOff optionOnOff)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: amp #1");
+ #endif
+
+ switch(optionOnOff) {
+ case optionOn: return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) | MASK_PALEVEL_PA1) );
+ case optionOff: return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) & ~MASK_PALEVEL_PA1) );
+ default:
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+}
+
+int rf69_set_amplifier_2(struct spi_device *spi, enum optionOnOff optionOnOff)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: amp #2");
+ #endif
+
+ switch(optionOnOff) {
+ case optionOn: return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) | MASK_PALEVEL_PA2) );
+ case optionOff: return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) & ~MASK_PALEVEL_PA2) );
+ default:
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+}
+
+int rf69_set_output_power_level(struct spi_device *spi, u8 powerLevel)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: power level");
+ #endif
+
+ powerLevel +=18; // TODO Abhängigkeit von PA0,1,2 setting
+
+ // check input value
+ if (powerLevel > 0x1f) {
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+
+ // write value
+ return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) & ~MASK_PALEVEL_OUTPUT_POWER) | powerLevel);
+}
+
+int rf69_set_pa_ramp(struct spi_device *spi, enum paRamp paRamp)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: pa ramp");
+ #endif
+
+ switch(paRamp) {
+ case ramp3400: return WRITE_REG(REG_PARAMP, PARAMP_3400);
+ case ramp2000: return WRITE_REG(REG_PARAMP, PARAMP_2000);
+ case ramp1000: return WRITE_REG(REG_PARAMP, PARAMP_1000);
+ case ramp500: return WRITE_REG(REG_PARAMP, PARAMP_500);
+ case ramp250: return WRITE_REG(REG_PARAMP, PARAMP_250);
+ case ramp125: return WRITE_REG(REG_PARAMP, PARAMP_125);
+ case ramp100: return WRITE_REG(REG_PARAMP, PARAMP_100);
+ case ramp62: return WRITE_REG(REG_PARAMP, PARAMP_62);
+ case ramp50: return WRITE_REG(REG_PARAMP, PARAMP_50);
+ case ramp40: return WRITE_REG(REG_PARAMP, PARAMP_40);
+ case ramp31: return WRITE_REG(REG_PARAMP, PARAMP_31);
+ case ramp25: return WRITE_REG(REG_PARAMP, PARAMP_25);
+ case ramp20: return WRITE_REG(REG_PARAMP, PARAMP_20);
+ case ramp15: return WRITE_REG(REG_PARAMP, PARAMP_15);
+ case ramp12: return WRITE_REG(REG_PARAMP, PARAMP_12);
+ case ramp10: return WRITE_REG(REG_PARAMP, PARAMP_10);
+ default:
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+}
+
+int rf69_set_antenna_impedance(struct spi_device *spi, enum antennaImpedance antennaImpedance)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: antenna impedance");
+ #endif
+
+ switch(antennaImpedance) {
+ case fiftyOhm: return WRITE_REG(REG_LNA, (READ_REG(REG_LNA) & ~MASK_LNA_ZIN) );
+ case twohundretOhm: return WRITE_REG(REG_LNA, (READ_REG(REG_LNA) | MASK_LNA_ZIN) );
+ default:
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+}
+
+int rf69_set_lna_gain(struct spi_device *spi, enum lnaGain lnaGain)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: lna gain");
+ #endif
+
+ switch(lnaGain) {
+ case automatic: return WRITE_REG(REG_LNA, ( (READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_AUTO) );
+ case max: return WRITE_REG(REG_LNA, ( (READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_MAX) );
+ case maxMinus6: return WRITE_REG(REG_LNA, ( (READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_MAX_MINUS_6) );
+ case maxMinus12: return WRITE_REG(REG_LNA, ( (READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_MAX_MINUS_12) );
+ case maxMinus24: return WRITE_REG(REG_LNA, ( (READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_MAX_MINUS_24) );
+ case maxMinus36: return WRITE_REG(REG_LNA, ( (READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_MAX_MINUS_36) );
+ case maxMinus48: return WRITE_REG(REG_LNA, ( (READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_MAX_MINUS_48) );
+ default:
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+}
+
+enum lnaGain rf69_get_lna_gain(struct spi_device *spi)
+{
+ u8 currentValue;
+
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "get: lna gain");
+ #endif
+
+ currentValue = READ_REG(REG_LNA);
+
+ switch (currentValue & MASK_LNA_CURRENT_GAIN >> 3) { // improvement: change 3 to define
+ case LNA_GAIN_AUTO: return automatic;
+ case LNA_GAIN_MAX: return max;
+ case LNA_GAIN_MAX_MINUS_6: return maxMinus6;
+ case LNA_GAIN_MAX_MINUS_12: return maxMinus12;
+ case LNA_GAIN_MAX_MINUS_24: return maxMinus24;
+ case LNA_GAIN_MAX_MINUS_36: return maxMinus36;
+ case LNA_GAIN_MAX_MINUS_48: return maxMinus48;
+ default: return undefined;
+ }
+}
+
+int rf69_set_dc_cut_off_frequency_intern(struct spi_device *spi ,u8 reg, enum dccPercent dccPercent)
+{
+ switch (dccPercent) {
+ case dcc16Percent: return WRITE_REG(reg, ( (READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_16_PERCENT) );
+ case dcc8Percent: return WRITE_REG(reg, ( (READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_8_PERCENT) );
+ case dcc4Percent: return WRITE_REG(reg, ( (READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_4_PERCENT) );
+ case dcc2Percent: return WRITE_REG(reg, ( (READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_2_PERCENT) );
+ case dcc1Percent: return WRITE_REG(reg, ( (READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_1_PERCENT) );
+ case dcc0_5Percent: return WRITE_REG(reg, ( (READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_0_5_PERCENT) );
+ case dcc0_25Percent: return WRITE_REG(reg, ( (READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_0_25_PERCENT) );
+ case dcc0_125Percent: return WRITE_REG(reg, ( (READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_0_125_PERCENT) );
+ default:
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+}
+
+int rf69_set_dc_cut_off_frequency(struct spi_device *spi, enum dccPercent dccPercent)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: cut off freq");
+ #endif
+
+ return rf69_set_dc_cut_off_frequency_intern(spi, REG_RXBW, dccPercent);
+}
+
+int rf69_set_dc_cut_off_frequency_during_afc(struct spi_device *spi, enum dccPercent dccPercent)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: cut off freq during afc");
+ #endif
+
+ return rf69_set_dc_cut_off_frequency_intern(spi, REG_AFCBW, dccPercent);
+}
+
+static int rf69_set_bandwidth_intern(struct spi_device *spi, u8 reg,
+ enum mantisse mantisse, u8 exponent)
+{
+ u8 newValue;
+
+ // check value for mantisse and exponent
+ if (exponent > 7) {
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+
+ if ((mantisse != mantisse16) &&
+ (mantisse != mantisse20) &&
+ (mantisse != mantisse24)) {
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+
+ // read old value
+ newValue = READ_REG(reg);
+
+ // "delete" mantisse and exponent = just keep the DCC setting
+ newValue = newValue & MASK_BW_DCC_FREQ;
+
+ // add new mantisse
+ switch(mantisse) {
+ case mantisse16: newValue = newValue | BW_MANT_16; break;
+ case mantisse20: newValue = newValue | BW_MANT_20; break;
+ case mantisse24: newValue = newValue | BW_MANT_24; break;
+ }
+
+ // add new exponent
+ newValue = newValue | exponent;
+
+ // write back
+ return WRITE_REG(reg, newValue);
+}
+
+int rf69_set_bandwidth(struct spi_device *spi, enum mantisse mantisse, u8 exponent)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: band width");
+ #endif
+
+ return rf69_set_bandwidth_intern(spi, REG_RXBW, mantisse, exponent);
+}
+
+int rf69_set_bandwidth_during_afc(struct spi_device *spi, enum mantisse mantisse, u8 exponent)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: band width during afc");
+ #endif
+
+ return rf69_set_bandwidth_intern(spi, REG_AFCBW, mantisse, exponent);
+}
+
+int rf69_set_ook_threshold_type(struct spi_device *spi, enum thresholdType thresholdType)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: threshold type");
+ #endif
+
+ switch (thresholdType) {
+ case fixed: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESTYPE) | OOKPEAK_THRESHTYPE_FIXED) );
+ case peak: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESTYPE) | OOKPEAK_THRESHTYPE_PEAK) );
+ case average: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESTYPE) | OOKPEAK_THRESHTYPE_AVERAGE) );
+ default:
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+}
+
+int rf69_set_ook_threshold_step(struct spi_device *spi, enum thresholdStep thresholdStep)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: threshold step");
+ #endif
+
+ switch (thresholdStep) {
+ case step_0_5db: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_0_5_DB) );
+ case step_1_0db: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_1_0_DB) );
+ case step_1_5db: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_1_5_DB) );
+ case step_2_0db: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_2_0_DB) );
+ case step_3_0db: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_3_0_DB) );
+ case step_4_0db: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_4_0_DB) );
+ case step_5_0db: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_5_0_DB) );
+ case step_6_0db: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_6_0_DB) );
+ default:
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+}
+
+int rf69_set_ook_threshold_dec(struct spi_device *spi, enum thresholdDecrement thresholdDecrement)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: threshold decrement");
+ #endif
+
+ switch (thresholdDecrement) {
+ case dec_every8th: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_EVERY_8TH) );
+ case dec_every4th: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_EVERY_4TH) );
+ case dec_every2nd: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_EVERY_2ND) );
+ case dec_once: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_ONCE) );
+ case dec_twice: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_TWICE) );
+ case dec_4times: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_4_TIMES) );
+ case dec_8times: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_8_TIMES) );
+ case dec_16times: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_16_TIMES) );
+ default:
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+}
+
+int rf69_set_dio_mapping(struct spi_device *spi, u8 DIONumber, u8 value)
+{
+ u8 mask;
+ u8 shift;
+ u8 regaddr;
+ u8 regValue;
+
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: DIO mapping");
+ #endif
+
+ // check DIO number
+ if (DIONumber > 5) {
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+
+ switch (DIONumber) {
+ case 0: mask=MASK_DIO0; shift=SHIFT_DIO0; regaddr=REG_DIOMAPPING1; break;
+ case 1: mask=MASK_DIO1; shift=SHIFT_DIO1; regaddr=REG_DIOMAPPING1; break;
+ case 2: mask=MASK_DIO2; shift=SHIFT_DIO2; regaddr=REG_DIOMAPPING1; break;
+ case 3: mask=MASK_DIO3; shift=SHIFT_DIO3; regaddr=REG_DIOMAPPING1; break;
+ case 4: mask=MASK_DIO4; shift=SHIFT_DIO4; regaddr=REG_DIOMAPPING2; break;
+ case 5: mask=MASK_DIO5; shift=SHIFT_DIO5; regaddr=REG_DIOMAPPING2; break;
+ }
+
+ // read reg
+ regValue=READ_REG(regaddr);
+ // delete old value
+ regValue = regValue & ~mask;
+ // add new value
+ regValue = regValue | value << shift;
+ // write back
+ return WRITE_REG(regaddr,regValue);
+}
+
+bool rf69_get_flag(struct spi_device *spi, enum flag flag)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "get: flag");
+ #endif
+
+ switch(flag) {
+ case modeSwitchCompleted: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_MODE_READY);
+ case readyToReceive: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_RX_READY);
+ case readyToSend: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_TX_READY);
+ case pllLocked: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_PLL_LOCK);
+ case rssiExceededThreshold: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_RSSI);
+ case timeout: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_TIMEOUT);
+ case automode: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_AUTOMODE);
+ case syncAddressMatch: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_SYNC_ADDRESS_MATCH);
+ case fifoFull: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_FIFO_FULL);
+/* case fifoNotEmpty: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_FIFO_NOT_EMPTY); */
+ case fifoEmpty: return !(READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_FIFO_NOT_EMPTY);
+ case fifoLevelBelowThreshold: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_FIFO_LEVEL);
+ case fifoOverrun: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_FIFO_OVERRUN);
+ case packetSent: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_PACKET_SENT);
+ case payloadReady: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_PAYLOAD_READY);
+ case crcOk: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_CRC_OK);
+ case batteryLow: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_LOW_BAT);
+ default: return false;
+ }
+}
+
+int rf69_reset_flag(struct spi_device *spi, enum flag flag)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "reset: flag");
+ #endif
+
+ switch(flag) {
+ case rssiExceededThreshold: return WRITE_REG(REG_IRQFLAGS1, MASK_IRQFLAGS1_RSSI);
+ case syncAddressMatch: return WRITE_REG(REG_IRQFLAGS1, MASK_IRQFLAGS1_SYNC_ADDRESS_MATCH);
+ case fifoOverrun: return WRITE_REG(REG_IRQFLAGS2, MASK_IRQFLAGS2_FIFO_OVERRUN);
+ default:
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+}
+
+int rf69_set_rssi_threshold(struct spi_device *spi, u8 threshold)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: rssi threshold");
+ #endif
+
+ /* no value check needed - u8 exactly matches register size */
+
+ return WRITE_REG(REG_RSSITHRESH, threshold);
+}
+
+int rf69_set_rx_start_timeout(struct spi_device *spi, u8 timeout)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: start timeout");
+ #endif
+
+ /* no value check needed - u8 exactly matches register size */
+
+ return WRITE_REG(REG_RXTIMEOUT1, timeout);
+}
+
+int rf69_set_rssi_timeout(struct spi_device *spi, u8 timeout)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: rssi timeout");
+ #endif
+
+ /* no value check needed - u8 exactly matches register size */
+
+ return WRITE_REG(REG_RXTIMEOUT2, timeout);
+}
+
+int rf69_set_preamble_length(struct spi_device *spi, u16 preambleLength)
+{
+ int retval;
+ u8 msb, lsb;
+
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: preamble length");
+ #endif
+
+ /* no value check needed - u16 exactly matches register size */
+
+ /* calculate reg settings */
+ msb = (preambleLength&0xff00) >> 8;
+ lsb = (preambleLength&0xff);
+
+ /* transmit to chip */
+ retval = WRITE_REG(REG_PREAMBLE_MSB, msb);
+ if (retval) return retval;
+ retval = WRITE_REG(REG_PREAMBLE_LSB, lsb);
+
+ return retval;
+}
+
+int rf69_set_sync_enable(struct spi_device *spi, enum optionOnOff optionOnOff)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: sync enable");
+ #endif
+
+ switch(optionOnOff) {
+ case optionOn: return WRITE_REG(REG_SYNC_CONFIG, (READ_REG(REG_SYNC_CONFIG) | MASK_SYNC_CONFIG_SYNC_ON) );
+ case optionOff: return WRITE_REG(REG_SYNC_CONFIG, (READ_REG(REG_SYNC_CONFIG) & ~MASK_SYNC_CONFIG_SYNC_ON) );
+ default:
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+}
+
+int rf69_set_fifo_fill_condition(struct spi_device *spi, enum fifoFillCondition fifoFillCondition)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: fifo fill condition");
+ #endif
+
+ switch(fifoFillCondition) {
+ case always: return WRITE_REG(REG_SYNC_CONFIG, (READ_REG(REG_SYNC_CONFIG) | MASK_SYNC_CONFIG_FIFO_FILL_CONDITION) );
+ case afterSyncInterrupt: return WRITE_REG(REG_SYNC_CONFIG, (READ_REG(REG_SYNC_CONFIG) & ~MASK_SYNC_CONFIG_FIFO_FILL_CONDITION) );
+ default:
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+}
+
+int rf69_set_sync_size(struct spi_device *spi, u8 syncSize)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: sync size");
+ #endif
+
+ // check input value
+ if (syncSize > 0x07) {
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+
+ // write value
+ return WRITE_REG(REG_SYNC_CONFIG, (READ_REG(REG_SYNC_CONFIG) & ~MASK_SYNC_CONFIG_SYNC_SIZE) | (syncSize << 3) );
+}
+
+int rf69_set_sync_tolerance(struct spi_device *spi, u8 syncTolerance)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: sync tolerance");
+ #endif
+
+ // check input value
+ if (syncTolerance > 0x07) {
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+
+ // write value
+ return WRITE_REG(REG_SYNC_CONFIG, (READ_REG(REG_SYNC_CONFIG) & ~MASK_SYNC_CONFIG_SYNC_SIZE) | syncTolerance);
+}
+
+int rf69_set_sync_values(struct spi_device *spi, u8 syncValues[8])
+{
+ int retval = 0;
+
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: sync values");
+ #endif
+
+ retval += WRITE_REG(REG_SYNCVALUE1, syncValues[0]);
+ retval += WRITE_REG(REG_SYNCVALUE2, syncValues[1]);
+ retval += WRITE_REG(REG_SYNCVALUE3, syncValues[2]);
+ retval += WRITE_REG(REG_SYNCVALUE4, syncValues[3]);
+ retval += WRITE_REG(REG_SYNCVALUE5, syncValues[4]);
+ retval += WRITE_REG(REG_SYNCVALUE6, syncValues[5]);
+ retval += WRITE_REG(REG_SYNCVALUE7, syncValues[6]);
+ retval += WRITE_REG(REG_SYNCVALUE8, syncValues[7]);
+
+ return retval;
+}
+
+int rf69_set_packet_format(struct spi_device *spi, enum packetFormat packetFormat)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: packet format");
+ #endif
+
+ switch(packetFormat) {
+ case packetLengthVar: return WRITE_REG(REG_PACKETCONFIG1, (READ_REG(REG_PACKETCONFIG1) | MASK_PACKETCONFIG1_PAKET_FORMAT_VARIABLE) );
+ case packetLengthFix: return WRITE_REG(REG_PACKETCONFIG1, (READ_REG(REG_PACKETCONFIG1) & ~MASK_PACKETCONFIG1_PAKET_FORMAT_VARIABLE) );
+ default:
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+}
+
+int rf69_set_crc_enable(struct spi_device *spi, enum optionOnOff optionOnOff)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: crc enable");
+ #endif
+
+ switch(optionOnOff) {
+ case optionOn: return WRITE_REG(REG_PACKETCONFIG1, (READ_REG(REG_PACKETCONFIG1) | MASK_PACKETCONFIG1_CRC_ON) );
+ case optionOff: return WRITE_REG(REG_PACKETCONFIG1, (READ_REG(REG_PACKETCONFIG1) & ~MASK_PACKETCONFIG1_CRC_ON) );
+ default:
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+}
+
+int rf69_set_adressFiltering(struct spi_device *spi, enum addressFiltering addressFiltering)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: address filtering");
+ #endif
+
+ switch (addressFiltering) {
+ case filteringOff: return WRITE_REG(REG_PACKETCONFIG1, ( (READ_REG(REG_PACKETCONFIG1) & ~MASK_PACKETCONFIG1_ADDRESSFILTERING) | PACKETCONFIG1_ADDRESSFILTERING_OFF) );
+ case nodeAddress: return WRITE_REG(REG_PACKETCONFIG1, ( (READ_REG(REG_PACKETCONFIG1) & ~MASK_PACKETCONFIG1_ADDRESSFILTERING) | PACKETCONFIG1_ADDRESSFILTERING_NODE) );
+ case nodeOrBroadcastAddress: return WRITE_REG(REG_PACKETCONFIG1, ( (READ_REG(REG_PACKETCONFIG1) & ~MASK_PACKETCONFIG1_ADDRESSFILTERING) | PACKETCONFIG1_ADDRESSFILTERING_NODEBROADCAST) );
+ default:
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+}
+
+int rf69_set_payload_length(struct spi_device *spi, u8 payloadLength)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: payload length");
+ #endif
+
+ return WRITE_REG(REG_PAYLOAD_LENGTH, payloadLength);
+}
+
+u8 rf69_get_payload_length(struct spi_device *spi)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "get: payload length");
+ #endif
+
+ return (u8) READ_REG(REG_PAYLOAD_LENGTH);
+}
+
+int rf69_set_node_address(struct spi_device *spi, u8 nodeAddress)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: node address");
+ #endif
+
+ return WRITE_REG(REG_NODEADRS, nodeAddress);
+}
+
+int rf69_set_broadcast_address(struct spi_device *spi, u8 broadcastAddress)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: broadcast address");
+ #endif
+
+ return WRITE_REG(REG_BROADCASTADRS, broadcastAddress);
+}
+
+int rf69_set_tx_start_condition(struct spi_device *spi, enum txStartCondition txStartCondition)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: start condition");
+ #endif
+
+ switch(txStartCondition) {
+ case fifoLevel: return WRITE_REG(REG_FIFO_THRESH, (READ_REG(REG_FIFO_THRESH) & ~MASK_FIFO_THRESH_TXSTART) );
+ case fifoNotEmpty: return WRITE_REG(REG_FIFO_THRESH, (READ_REG(REG_FIFO_THRESH) | MASK_FIFO_THRESH_TXSTART) );
+ default:
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+}
+
+int rf69_set_fifo_threshold(struct spi_device *spi, u8 threshold)
+{
+ int retval;
+
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: fifo threshold");
+ #endif
+
+ // check input value
+ if (threshold & 0x80) {
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+
+ // write value
+ retval = WRITE_REG(REG_FIFO_THRESH, (READ_REG(REG_FIFO_THRESH) & ~MASK_FIFO_THRESH_VALUE) | threshold);
+ if (retval)
+ return retval;
+
+ // access the fifo to activate new threshold
+ return rf69_read_fifo (spi, (u8*) &retval, 1); // retval used as buffer
+}
+
+int rf69_set_dagc(struct spi_device *spi, enum dagc dagc)
+{
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "set: dagc");
+ #endif
+
+ switch(dagc) {
+ case normalMode: return WRITE_REG(REG_TESTDAGC, DAGC_NORMAL);
+ case improve: return WRITE_REG(REG_TESTDAGC, DAGC_IMPROVED_LOWBETA0);
+ case improve4LowModulationIndex: return WRITE_REG(REG_TESTDAGC, DAGC_IMPROVED_LOWBETA1);
+ default:
+ dev_dbg(&spi->dev, "set: illegal input param");
+ return -EINVAL;
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+
+int rf69_read_fifo (struct spi_device *spi, u8 *buffer, unsigned int size)
+{
+ #ifdef DEBUG_FIFO_ACCESS
+ int i;
+ #endif
+ struct spi_transfer transfer;
+ u8 local_buffer[FIFO_SIZE + 1];
+ int retval;
+
+ if (size > FIFO_SIZE) {
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "read fifo: passed in buffer bigger then internal buffer \n");
+ #endif
+ return -EMSGSIZE;
+ }
+
+ /* prepare a bidirectional transfer */
+ local_buffer[0] = REG_FIFO;
+ memset(&transfer, 0, sizeof(transfer));
+ transfer.tx_buf = local_buffer;
+ transfer.rx_buf = local_buffer;
+ transfer.len = size+1;
+
+ retval = spi_sync_transfer(spi, &transfer, 1);
+
+ #ifdef DEBUG_FIFO_ACCESS
+ for (i=0; i<size; i++)
+ dev_dbg(&spi->dev, "%d - 0x%x\n", i, local_buffer[i+1]);
+ #endif
+
+ memcpy(buffer, &local_buffer[1], size); // TODO: ohne memcopy wäre schöner
+
+ return retval;
+}
+
+int rf69_write_fifo(struct spi_device *spi, u8 *buffer, unsigned int size)
+{
+ #ifdef DEBUG_FIFO_ACCESS
+ int i;
+ #endif
+ char spi_address = REG_FIFO | WRITE_BIT;
+ u8 local_buffer[FIFO_SIZE + 1];
+
+ if (size > FIFO_SIZE) {
+ #ifdef DEBUG
+ dev_dbg(&spi->dev, "read fifo: passed in buffer bigger then internal buffer \n");
+ #endif
+ return -EMSGSIZE;
+ }
+
+ local_buffer[0] = spi_address;
+ memcpy(&local_buffer[1], buffer, size); // TODO: ohne memcopy wäre schöner
+
+ #ifdef DEBUG_FIFO_ACCESS
+ for (i=0; i<size; i++)
+ dev_dbg(&spi->dev, "0x%x\n",buffer[i]);
+ #endif
+
+ return spi_write (spi, local_buffer, size + 1);
+}
+
+/*-------------------------------------------------------------------------*/
+
+u8 rf69_read_reg(struct spi_device *spi, u8 addr)
+{
+ int retval;
+
+ retval = spi_w8r8(spi, addr);
+
+ #ifdef DEBUG_VALUES
+ if (retval < 0)
+ /* should never happen, since we already checked,
+ * that module is connected. Therefore no error
+ * handling, just an optional error message...
+ */
+ dev_dbg(&spi->dev, "read 0x%x FAILED\n",
+ addr);
+ else
+ dev_dbg(&spi->dev, "read 0x%x from reg 0x%x\n",
+ retval,
+ addr);
+ #endif
+
+ return retval;
+}
+
+int rf69_write_reg(struct spi_device *spi, u8 addr, u8 value)
+{
+ int retval;
+ char buffer[2];
+
+ buffer[0] = addr | WRITE_BIT;
+ buffer[1] = value;
+
+ retval = spi_write(spi, &buffer, 2);
+
+ #ifdef DEBUG_VALUES
+ if (retval < 0)
+ /* should never happen, since we already checked,
+ * that module is connected. Therefore no error
+ * handling, just an optional error message...
+ */
+ dev_dbg(&spi->dev, "write 0x%x to 0x%x FAILED\n",
+ value,
+ addr);
+ else
+ dev_dbg(&spi->dev, "wrote 0x%x to reg 0x%x\n",
+ value,
+ addr);
+ #endif
+
+ return retval;
+}
+
+
diff --git a/drivers/staging/pi433/rf69.h b/drivers/staging/pi433/rf69.h
new file mode 100644
index 0000000..5c0c956
--- /dev/null
+++ b/drivers/staging/pi433/rf69.h
@@ -0,0 +1,82 @@
+/*
+ * hardware abstraction/register access for HopeRf rf69 radio module
+ *
+ * Copyright (C) 2016 Wolf-Entwicklungen
+ * Marcus Wolf <linux@wolf-entwicklungen.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 RF69_H
+#define RF69_H
+
+#include "rf69_enum.h"
+#include "rf69_registers.h"
+
+#define F_OSC 32000000 /* in Hz */
+#define FREQUENCY 433920000 /* in Hz, modifying this value impacts CE certification */
+#define FIFO_SIZE 66 /* in byte */
+#define FIFO_THRESHOLD 15 /* in byte */
+
+int rf69_set_mode(struct spi_device *spi, enum mode mode);
+int rf69_set_data_mode(struct spi_device *spi, enum dataMode dataMode);
+int rf69_set_modulation(struct spi_device *spi, enum modulation modulation);
+enum modulation rf69_get_modulation(struct spi_device *spi);
+int rf69_set_modulation_shaping(struct spi_device *spi, enum modShaping modShaping);
+int rf69_set_bit_rate(struct spi_device *spi, u16 bitRate);
+int rf69_set_deviation(struct spi_device *spi, u32 deviation);
+int rf69_set_frequency(struct spi_device *spi, u32 frequency);
+int rf69_set_amplifier_0(struct spi_device *spi, enum optionOnOff optionOnOff);
+int rf69_set_amplifier_1(struct spi_device *spi, enum optionOnOff optionOnOff);
+int rf69_set_amplifier_2(struct spi_device *spi, enum optionOnOff optionOnOff);
+int rf69_set_output_power_level(struct spi_device *spi, u8 powerLevel);
+int rf69_set_pa_ramp(struct spi_device *spi, enum paRamp paRamp);
+int rf69_set_antenna_impedance(struct spi_device *spi, enum antennaImpedance antennaImpedance);
+int rf69_set_lna_gain(struct spi_device *spi, enum lnaGain lnaGain);
+enum lnaGain rf69_get_lna_gain(struct spi_device *spi);
+int rf69_set_dc_cut_off_frequency_intern(struct spi_device *spi, u8 reg, enum dccPercent dccPercent);
+int rf69_set_dc_cut_off_frequency(struct spi_device *spi, enum dccPercent dccPercent);
+int rf69_set_dc_cut_off_frequency_during_afc(struct spi_device *spi, enum dccPercent dccPercent);
+int rf69_set_bandwidth(struct spi_device *spi, enum mantisse mantisse, u8 exponent);
+int rf69_set_bandwidth_during_afc(struct spi_device *spi, enum mantisse mantisse, u8 exponent);
+int rf69_set_ook_threshold_type(struct spi_device *spi, enum thresholdType thresholdType);
+int rf69_set_ook_threshold_step(struct spi_device *spi, enum thresholdStep thresholdStep);
+int rf69_set_ook_threshold_dec(struct spi_device *spi, enum thresholdDecrement thresholdDecrement);
+int rf69_set_dio_mapping(struct spi_device *spi, u8 DIONumber, u8 value);
+bool rf69_get_flag(struct spi_device *spi, enum flag flag);
+int rf69_reset_flag(struct spi_device *spi, enum flag flag);
+int rf69_set_rssi_threshold(struct spi_device *spi, u8 threshold);
+int rf69_set_rx_start_timeout(struct spi_device *spi, u8 timeout);
+int rf69_set_rssi_timeout(struct spi_device *spi, u8 timeout);
+int rf69_set_preamble_length(struct spi_device *spi, u16 preambleLength);
+int rf69_set_sync_enable(struct spi_device *spi, enum optionOnOff optionOnOff);
+int rf69_set_fifo_fill_condition(struct spi_device *spi, enum fifoFillCondition fifoFillCondition);
+int rf69_set_sync_size(struct spi_device *spi, u8 sync_size);
+int rf69_set_sync_tolerance(struct spi_device *spi, u8 syncTolerance);
+int rf69_set_sync_values(struct spi_device *spi, u8 syncValues[8]);
+int rf69_set_packet_format(struct spi_device *spi, enum packetFormat packetFormat);
+int rf69_set_crc_enable(struct spi_device *spi, enum optionOnOff optionOnOff);
+int rf69_set_adressFiltering(struct spi_device *spi, enum addressFiltering addressFiltering);
+int rf69_set_payload_length(struct spi_device *spi, u8 payloadLength);
+u8 rf69_get_payload_length(struct spi_device *spi);
+int rf69_set_node_address(struct spi_device *spi, u8 nodeAddress);
+int rf69_set_broadcast_address(struct spi_device *spi, u8 broadcastAddress);
+int rf69_set_tx_start_condition(struct spi_device *spi, enum txStartCondition txStartCondition);
+int rf69_set_fifo_threshold(struct spi_device *spi, u8 threshold);
+int rf69_set_dagc(struct spi_device *spi, enum dagc dagc);
+
+int rf69_read_fifo (struct spi_device *spi, u8 *buffer, unsigned int size);
+int rf69_write_fifo(struct spi_device *spi, u8 *buffer, unsigned int size);
+
+u8 rf69_read_reg (struct spi_device *spi, u8 addr);
+int rf69_write_reg(struct spi_device *spi, u8 addr, u8 value);
+
+
+#endif
diff --git a/drivers/staging/pi433/rf69_enum.h b/drivers/staging/pi433/rf69_enum.h
new file mode 100644
index 0000000..fbfb59b
--- /dev/null
+++ b/drivers/staging/pi433/rf69_enum.h
@@ -0,0 +1,201 @@
+/*
+ * enumerations for HopeRf rf69 radio module
+ *
+ * Copyright (C) 2016 Wolf-Entwicklungen
+ * Marcus Wolf <linux@wolf-entwicklungen.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 RF69_ENUM_H
+#define RF69_ENUM_H
+
+enum optionOnOff
+{
+ optionOff,
+ optionOn
+};
+
+enum mode
+{
+ mode_sleep,
+ standby,
+ synthesizer,
+ transmit,
+ receive
+};
+
+enum dataMode
+{
+ packet,
+ continuous,
+ continuousNoSync
+};
+
+enum modulation
+{
+ OOK,
+ FSK
+};
+
+enum modShaping
+{
+ shapingOff,
+ shaping1_0,
+ shaping0_5,
+ shaping0_3,
+ shapingBR,
+ shaping2BR
+};
+
+enum paRamp
+{
+ ramp3400,
+ ramp2000,
+ ramp1000,
+ ramp500,
+ ramp250,
+ ramp125,
+ ramp100,
+ ramp62,
+ ramp50,
+ ramp40,
+ ramp31,
+ ramp25,
+ ramp20,
+ ramp15,
+ ramp12,
+ ramp10
+};
+
+enum antennaImpedance
+{
+ fiftyOhm,
+ twohundretOhm
+};
+
+enum lnaGain
+{
+ automatic,
+ max,
+ maxMinus6,
+ maxMinus12,
+ maxMinus24,
+ maxMinus36,
+ maxMinus48,
+ undefined
+};
+
+enum dccPercent
+{
+ dcc16Percent,
+ dcc8Percent,
+ dcc4Percent,
+ dcc2Percent,
+ dcc1Percent,
+ dcc0_5Percent,
+ dcc0_25Percent,
+ dcc0_125Percent
+};
+
+enum mantisse
+{
+ mantisse16,
+ mantisse20,
+ mantisse24
+};
+
+enum thresholdType
+{
+ fixed,
+ peak,
+ average
+};
+
+enum thresholdStep
+{
+ step_0_5db,
+ step_1_0db,
+ step_1_5db,
+ step_2_0db,
+ step_3_0db,
+ step_4_0db,
+ step_5_0db,
+ step_6_0db
+};
+
+enum thresholdDecrement
+{
+ dec_every8th,
+ dec_every4th,
+ dec_every2nd,
+ dec_once,
+ dec_twice,
+ dec_4times,
+ dec_8times,
+ dec_16times
+};
+
+enum flag
+{
+ modeSwitchCompleted,
+ readyToReceive,
+ readyToSend,
+ pllLocked,
+ rssiExceededThreshold,
+ timeout,
+ automode,
+ syncAddressMatch,
+ fifoFull,
+// fifoNotEmpty, collision with next enum; replaced by following enum...
+ fifoEmpty,
+ fifoLevelBelowThreshold,
+ fifoOverrun,
+ packetSent,
+ payloadReady,
+ crcOk,
+ batteryLow
+};
+
+enum fifoFillCondition
+{
+ afterSyncInterrupt,
+ always
+};
+
+enum packetFormat
+{
+ packetLengthFix,
+ packetLengthVar
+};
+
+enum txStartCondition
+{
+ fifoLevel,
+ fifoNotEmpty
+};
+
+enum addressFiltering
+{
+ filteringOff,
+ nodeAddress,
+ nodeOrBroadcastAddress
+};
+
+enum dagc
+{
+ normalMode,
+ improve,
+ improve4LowModulationIndex
+};
+
+
+#endif
diff --git a/drivers/staging/pi433/rf69_registers.h b/drivers/staging/pi433/rf69_registers.h
new file mode 100644
index 0000000..6335d42
--- /dev/null
+++ b/drivers/staging/pi433/rf69_registers.h
@@ -0,0 +1,489 @@
+/*
+ * register description for HopeRf rf69 radio module
+ *
+ * Copyright (C) 2016 Wolf-Entwicklungen
+ * Marcus Wolf <linux@wolf-entwicklungen.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+/*******************************************/
+/* RF69 register addresses */
+/*******************************************/
+#define REG_FIFO 0x00
+#define REG_OPMODE 0x01
+#define REG_DATAMODUL 0x02
+#define REG_BITRATE_MSB 0x03
+#define REG_BITRATE_LSB 0x04
+#define REG_FDEV_MSB 0x05
+#define REG_FDEV_LSB 0x06
+#define REG_FRF_MSB 0x07
+#define REG_FRF_MID 0x08
+#define REG_FRF_LSB 0x09
+#define REG_OSC1 0x0A
+#define REG_AFCCTRL 0x0B
+#define REG_LOWBAT 0x0C
+#define REG_LISTEN1 0x0D
+#define REG_LISTEN2 0x0E
+#define REG_LISTEN3 0x0F
+#define REG_VERSION 0x10
+#define REG_PALEVEL 0x11
+#define REG_PARAMP 0x12
+#define REG_OCP 0x13
+#define REG_AGCREF 0x14 /* not available on RF69 */
+#define REG_AGCTHRESH1 0x15 /* not available on RF69 */
+#define REG_AGCTHRESH2 0x16 /* not available on RF69 */
+#define REG_AGCTHRESH3 0x17 /* not available on RF69 */
+#define REG_LNA 0x18
+#define REG_RXBW 0x19
+#define REG_AFCBW 0x1A
+#define REG_OOKPEAK 0x1B
+#define REG_OOKAVG 0x1C
+#define REG_OOKFIX 0x1D
+#define REG_AFCFEI 0x1E
+#define REG_AFCMSB 0x1F
+#define REG_AFCLSB 0x20
+#define REG_FEIMSB 0x21
+#define REG_FEILSB 0x22
+#define REG_RSSICONFIG 0x23
+#define REG_RSSIVALUE 0x24
+#define REG_DIOMAPPING1 0x25
+#define REG_DIOMAPPING2 0x26
+#define REG_IRQFLAGS1 0x27
+#define REG_IRQFLAGS2 0x28
+#define REG_RSSITHRESH 0x29
+#define REG_RXTIMEOUT1 0x2A
+#define REG_RXTIMEOUT2 0x2B
+#define REG_PREAMBLE_MSB 0x2C
+#define REG_PREAMBLE_LSB 0x2D
+#define REG_SYNC_CONFIG 0x2E
+#define REG_SYNCVALUE1 0x2F
+#define REG_SYNCVALUE2 0x30
+#define REG_SYNCVALUE3 0x31
+#define REG_SYNCVALUE4 0x32
+#define REG_SYNCVALUE5 0x33
+#define REG_SYNCVALUE6 0x34
+#define REG_SYNCVALUE7 0x35
+#define REG_SYNCVALUE8 0x36
+#define REG_PACKETCONFIG1 0x37
+#define REG_PAYLOAD_LENGTH 0x38
+#define REG_NODEADRS 0x39
+#define REG_BROADCASTADRS 0x3A
+#define REG_AUTOMODES 0x3B
+#define REG_FIFO_THRESH 0x3C
+#define REG_PACKETCONFIG2 0x3D
+#define REG_AESKEY1 0x3E
+#define REG_AESKEY2 0x3F
+#define REG_AESKEY3 0x40
+#define REG_AESKEY4 0x41
+#define REG_AESKEY5 0x42
+#define REG_AESKEY6 0x43
+#define REG_AESKEY7 0x44
+#define REG_AESKEY8 0x45
+#define REG_AESKEY9 0x46
+#define REG_AESKEY10 0x47
+#define REG_AESKEY11 0x48
+#define REG_AESKEY12 0x49
+#define REG_AESKEY13 0x4A
+#define REG_AESKEY14 0x4B
+#define REG_AESKEY15 0x4C
+#define REG_AESKEY16 0x4D
+#define REG_TEMP1 0x4E
+#define REG_TEMP2 0x4F
+#define REG_TESTPA1 0x5A /* only present on RFM69HW */
+#define REG_TESTPA2 0x5C /* only present on RFM69HW */
+#define REG_TESTDAGC 0x6F
+
+/******************************************************/
+/* RF69/SX1231 bit definition */
+/******************************************************/
+/* write bit */
+#define WRITE_BIT 0x80
+
+/* RegOpMode */
+#define MASK_OPMODE_SEQUENCER_OFF 0x80
+#define MASK_OPMODE_LISTEN_ON 0x40
+#define MASK_OPMODE_LISTEN_ABORT 0x20
+#define MASK_OPMODE_MODE 0x1C
+
+#define OPMODE_MODE_SLEEP 0x00
+#define OPMODE_MODE_STANDBY 0x04 /* default */
+#define OPMODE_MODE_SYNTHESIZER 0x08
+#define OPMODE_MODE_TRANSMIT 0x0C
+#define OPMODE_MODE_RECEIVE 0x10
+
+/* RegDataModul */
+#define MASK_DATAMODUL_MODE 0x06
+#define MASK_DATAMODUL_MODULATION_TYPE 0x18
+#define MASK_DATAMODUL_MODULATION_SHAPE 0x03
+
+#define DATAMODUL_MODE_PACKET 0x00 /* default */
+#define DATAMODUL_MODE_CONTINUOUS 0x40
+#define DATAMODUL_MODE_CONTINUOUS_NOSYNC 0x60
+
+#define DATAMODUL_MODULATION_TYPE_FSK 0x00 /* default */
+#define DATAMODUL_MODULATION_TYPE_OOK 0x08
+
+#define DATAMODUL_MODULATION_SHAPE_NONE 0x00 /* default */
+#define DATAMODUL_MODULATION_SHAPE_1_0 0x01
+#define DATAMODUL_MODULATION_SHAPE_0_5 0x02
+#define DATAMODUL_MODULATION_SHAPE_0_3 0x03
+#define DATAMODUL_MODULATION_SHAPE_BR 0x01
+#define DATAMODUL_MODULATION_SHAPE_2BR 0x02
+
+/* RegFDevMsb (0x05)*/
+#define FDEVMASB_MASK 0x3f
+
+/*
+ * // RegOsc1
+ * #define OSC1_RCCAL_START 0x80
+ * #define OSC1_RCCAL_DONE 0x40
+ *
+ * // RegLowBat
+ * #define LOWBAT_MONITOR 0x10
+ * #define LOWBAT_ON 0x08
+ * #define LOWBAT_OFF 0x00 // Default
+ *
+ * #define LOWBAT_TRIM_1695 0x00
+ * #define LOWBAT_TRIM_1764 0x01
+ * #define LOWBAT_TRIM_1835 0x02 // Default
+ * #define LOWBAT_TRIM_1905 0x03
+ * #define LOWBAT_TRIM_1976 0x04
+ * #define LOWBAT_TRIM_2045 0x05
+ * #define LOWBAT_TRIM_2116 0x06
+ * #define LOWBAT_TRIM_2185 0x07
+ *
+ *
+ * // RegListen1
+ * #define LISTEN1_RESOL_64 0x50
+ * #define LISTEN1_RESOL_4100 0xA0 // Default
+ * #define LISTEN1_RESOL_262000 0xF0
+ *
+ * #define LISTEN1_CRITERIA_RSSI 0x00 // Default
+ * #define LISTEN1_CRITERIA_RSSIANDSYNC 0x08
+ *
+ * #define LISTEN1_END_00 0x00
+ * #define LISTEN1_END_01 0x02 // Default
+ * #define LISTEN1_END_10 0x04
+ *
+ *
+ * // RegListen2
+ * #define LISTEN2_COEFIDLE_VALUE 0xF5 // Default
+ *
+ * // RegListen3
+ * #define LISTEN3_COEFRX_VALUE 0x20 // Default
+ */
+
+// RegPaLevel
+#define MASK_PALEVEL_PA0 0x80
+#define MASK_PALEVEL_PA1 0x40
+#define MASK_PALEVEL_PA2 0x20
+#define MASK_PALEVEL_OUTPUT_POWER 0x1F
+
+
+
+// RegPaRamp
+#define PARAMP_3400 0x00
+#define PARAMP_2000 0x01
+#define PARAMP_1000 0x02
+#define PARAMP_500 0x03
+#define PARAMP_250 0x04
+#define PARAMP_125 0x05
+#define PARAMP_100 0x06
+#define PARAMP_62 0x07
+#define PARAMP_50 0x08
+#define PARAMP_40 0x09 /* default */
+#define PARAMP_31 0x0A
+#define PARAMP_25 0x0B
+#define PARAMP_20 0x0C
+#define PARAMP_15 0x0D
+#define PARAMP_12 0x0E
+#define PARAMP_10 0x0F
+
+#define MASK_PARAMP 0x0F
+
+/*
+ * // RegOcp
+ * #define OCP_OFF 0x0F
+ * #define OCP_ON 0x1A // Default
+ *
+ * #define OCP_TRIM_45 0x00
+ * #define OCP_TRIM_50 0x01
+ * #define OCP_TRIM_55 0x02
+ * #define OCP_TRIM_60 0x03
+ * #define OCP_TRIM_65 0x04
+ * #define OCP_TRIM_70 0x05
+ * #define OCP_TRIM_75 0x06
+ * #define OCP_TRIM_80 0x07
+ * #define OCP_TRIM_85 0x08
+ * #define OCP_TRIM_90 0x09
+ * #define OCP_TRIM_95 0x0A
+ * #define OCP_TRIM_100 0x0B // Default
+ * #define OCP_TRIM_105 0x0C
+ * #define OCP_TRIM_110 0x0D
+ * #define OCP_TRIM_115 0x0E
+ * #define OCP_TRIM_120 0x0F
+ */
+
+/* RegLna (0x18) */
+#define MASK_LNA_ZIN 0x80
+#define MASK_LNA_CURRENT_GAIN 0x38
+#define MASK_LNA_GAIN 0x07
+
+#define LNA_GAIN_AUTO 0x00 /* default */
+#define LNA_GAIN_MAX 0x01
+#define LNA_GAIN_MAX_MINUS_6 0x02
+#define LNA_GAIN_MAX_MINUS_12 0x03
+#define LNA_GAIN_MAX_MINUS_24 0x04
+#define LNA_GAIN_MAX_MINUS_36 0x05
+#define LNA_GAIN_MAX_MINUS_48 0x06
+
+
+/* RegRxBw (0x19) and RegAfcBw (0x1A) */
+#define MASK_BW_DCC_FREQ 0xE0
+#define MASK_BW_MANTISSE 0x18
+#define MASK_BW_EXPONENT 0x07
+
+#define BW_DCC_16_PERCENT 0x00
+#define BW_DCC_8_PERCENT 0x20
+#define BW_DCC_4_PERCENT 0x40 /* default */
+#define BW_DCC_2_PERCENT 0x60
+#define BW_DCC_1_PERCENT 0x80
+#define BW_DCC_0_5_PERCENT 0xA0
+#define BW_DCC_0_25_PERCENT 0xC0
+#define BW_DCC_0_125_PERCENT 0xE0
+
+#define BW_MANT_16 0x00
+#define BW_MANT_20 0x08
+#define BW_MANT_24 0x10 /* default */
+
+
+/* RegOokPeak (0x1B) */
+#define MASK_OOKPEAK_THRESTYPE 0xc0
+#define MASK_OOKPEAK_THRESSTEP 0x38
+#define MASK_OOKPEAK_THRESDEC 0x07
+
+#define OOKPEAK_THRESHTYPE_FIXED 0x00
+#define OOKPEAK_THRESHTYPE_PEAK 0x40 /* default */
+#define OOKPEAK_THRESHTYPE_AVERAGE 0x80
+
+#define OOKPEAK_THRESHSTEP_0_5_DB 0x00 /* default */
+#define OOKPEAK_THRESHSTEP_1_0_DB 0x08
+#define OOKPEAK_THRESHSTEP_1_5_DB 0x10
+#define OOKPEAK_THRESHSTEP_2_0_DB 0x18
+#define OOKPEAK_THRESHSTEP_3_0_DB 0x20
+#define OOKPEAK_THRESHSTEP_4_0_DB 0x28
+#define OOKPEAK_THRESHSTEP_5_0_DB 0x30
+#define OOKPEAK_THRESHSTEP_6_0_DB 0x38
+
+#define OOKPEAK_THRESHDEC_ONCE 0x00 /* default */
+#define OOKPEAK_THRESHDEC_EVERY_2ND 0x01
+#define OOKPEAK_THRESHDEC_EVERY_4TH 0x02
+#define OOKPEAK_THRESHDEC_EVERY_8TH 0x03
+#define OOKPEAK_THRESHDEC_TWICE 0x04
+#define OOKPEAK_THRESHDEC_4_TIMES 0x05
+#define OOKPEAK_THRESHDEC_8_TIMES 0x06
+#define OOKPEAK_THRESHDEC_16_TIMES 0x07
+
+/*
+ * // RegOokAvg
+ * #define OOKAVG_AVERAGETHRESHFILT_00 0x00
+ * #define OOKAVG_AVERAGETHRESHFILT_01 0x40
+ * #define OOKAVG_AVERAGETHRESHFILT_10 0x80 // Default
+ * #define OOKAVG_AVERAGETHRESHFILT_11 0xC0
+ *
+ *
+ * // RegAfcFei
+ * #define AFCFEI_FEI_DONE 0x40
+ * #define AFCFEI_FEI_START 0x20
+ * #define AFCFEI_AFC_DONE 0x10
+ * #define AFCFEI_AFCAUTOCLEAR_ON 0x08
+ * #define AFCFEI_AFCAUTOCLEAR_OFF 0x00 // Default
+ *
+ * #define AFCFEI_AFCAUTO_ON 0x04
+ * #define AFCFEI_AFCAUTO_OFF 0x00 // Default
+ *
+ * #define AFCFEI_AFC_CLEAR 0x02
+ * #define AFCFEI_AFC_START 0x01
+ *
+ * // RegRssiConfig
+ * #define RSSI_FASTRX_ON 0x08
+ * #define RSSI_FASTRX_OFF 0x00 // Default
+ * #define RSSI_DONE 0x02
+ * #define RSSI_START 0x01
+ */
+
+/* RegDioMapping1 */
+#define MASK_DIO0 0xC0
+#define MASK_DIO1 0x30
+#define MASK_DIO2 0x0C
+#define MASK_DIO3 0x03
+#define SHIFT_DIO0 6
+#define SHIFT_DIO1 4
+#define SHIFT_DIO2 2
+#define SHIFT_DIO3 0
+
+/* RegDioMapping2 */
+#define MASK_DIO4 0xC0
+#define MASK_DIO5 0x30
+#define SHIFT_DIO4 6
+#define SHIFT_DIO5 4
+
+/* DIO numbers */
+#define DIO0 0
+#define DIO1 1
+#define DIO2 2
+#define DIO3 3
+#define DIO4 4
+#define DIO5 5
+
+/* DIO Mapping values (packet mode) */
+#define DIO_ModeReady_DIO4 0x00
+#define DIO_ModeReady_DIO5 0x03
+#define DIO_ClkOut 0x00
+#define DIO_Data 0x01
+#define DIO_TimeOut_DIO1 0x03
+#define DIO_TimeOut_DIO4 0x00
+#define DIO_Rssi_DIO0 0x03
+#define DIO_Rssi_DIO3_4 0x01
+#define DIO_RxReady 0x02
+#define DIO_PLLLock 0x03
+#define DIO_TxReady 0x01
+#define DIO_FifoFull_DIO1 0x01
+#define DIO_FifoFull_DIO3 0x00
+#define DIO_SyncAddress 0x02
+#define DIO_FifoNotEmpty_DIO1 0x02
+#define DIO_FifoNotEmpty_FIO2 0x00
+#define DIO_Automode 0x04
+#define DIO_FifoLevel 0x00
+#define DIO_CrcOk 0x00
+#define DIO_PayloadReady 0x01
+#define DIO_PacketSent 0x00
+#define DIO_Dclk 0x00
+
+/* RegDioMapping2 CLK_OUT part */
+#define MASK_DIOMAPPING2_CLK_OUT 0x07
+
+#define DIOMAPPING2_CLK_OUT_NO_DIV 0x00
+#define DIOMAPPING2_CLK_OUT_DIV_2 0x01
+#define DIOMAPPING2_CLK_OUT_DIV_4 0x02
+#define DIOMAPPING2_CLK_OUT_DIV_8 0x03
+#define DIOMAPPING2_CLK_OUT_DIV_16 0x04
+#define DIOMAPPING2_CLK_OUT_DIV_32 0x05
+#define DIOMAPPING2_CLK_OUT_RC 0x06
+#define DIOMAPPING2_CLK_OUT_OFF 0x07 /* default */
+
+/* RegIrqFlags1 */
+#define MASK_IRQFLAGS1_MODE_READY 0x80
+#define MASK_IRQFLAGS1_RX_READY 0x40
+#define MASK_IRQFLAGS1_TX_READY 0x20
+#define MASK_IRQFLAGS1_PLL_LOCK 0x10
+#define MASK_IRQFLAGS1_RSSI 0x08
+#define MASK_IRQFLAGS1_TIMEOUT 0x04
+#define MASK_IRQFLAGS1_AUTOMODE 0x02
+#define MASK_IRQFLAGS1_SYNC_ADDRESS_MATCH 0x01
+
+/* RegIrqFlags2 */
+#define MASK_IRQFLAGS2_FIFO_FULL 0x80
+#define MASK_IRQFLAGS2_FIFO_NOT_EMPTY 0x40
+#define MASK_IRQFLAGS2_FIFO_LEVEL 0x20
+#define MASK_IRQFLAGS2_FIFO_OVERRUN 0x10
+#define MASK_IRQFLAGS2_PACKET_SENT 0x08
+#define MASK_IRQFLAGS2_PAYLOAD_READY 0x04
+#define MASK_IRQFLAGS2_CRC_OK 0x02
+#define MASK_IRQFLAGS2_LOW_BAT 0x01
+
+/* RegSyncConfig */
+#define MASK_SYNC_CONFIG_SYNC_ON 0x80 /* default */
+#define MASK_SYNC_CONFIG_FIFO_FILL_CONDITION 0x40
+#define MASK_SYNC_CONFIG_SYNC_SIZE 0x38
+#define MASK_SYNC_CONFIG_SYNC_TOLERANCE 0x07
+
+/* RegPacketConfig1 */
+#define MASK_PACKETCONFIG1_PAKET_FORMAT_VARIABLE 0x80
+#define MASK_PACKETCONFIG1_DCFREE 0x60
+#define MASK_PACKETCONFIG1_CRC_ON 0x10 /* default */
+#define MASK_PACKETCONFIG1_CRCAUTOCLEAR_OFF 0x08
+#define MASK_PACKETCONFIG1_ADDRESSFILTERING 0x06
+
+#define PACKETCONFIG1_DCFREE_OFF 0x00 /* default */
+#define PACKETCONFIG1_DCFREE_MANCHESTER 0x20
+#define PACKETCONFIG1_DCFREE_WHITENING 0x40
+#define PACKETCONFIG1_ADDRESSFILTERING_OFF 0x00 /* default */
+#define PACKETCONFIG1_ADDRESSFILTERING_NODE 0x02
+#define PACKETCONFIG1_ADDRESSFILTERING_NODEBROADCAST 0x04
+
+/*
+ * // RegAutoModes
+ * #define AUTOMODES_ENTER_OFF 0x00 // Default
+ * #define AUTOMODES_ENTER_FIFONOTEMPTY 0x20
+ * #define AUTOMODES_ENTER_FIFOLEVEL 0x40
+ * #define AUTOMODES_ENTER_CRCOK 0x60
+ * #define AUTOMODES_ENTER_PAYLOADREADY 0x80
+ * #define AUTOMODES_ENTER_SYNCADRSMATCH 0xA0
+ * #define AUTOMODES_ENTER_PACKETSENT 0xC0
+ * #define AUTOMODES_ENTER_FIFOEMPTY 0xE0
+ *
+ * #define AUTOMODES_EXIT_OFF 0x00 // Default
+ * #define AUTOMODES_EXIT_FIFOEMPTY 0x04
+ * #define AUTOMODES_EXIT_FIFOLEVEL 0x08
+ * #define AUTOMODES_EXIT_CRCOK 0x0C
+ * #define AUTOMODES_EXIT_PAYLOADREADY 0x10
+ * #define AUTOMODES_EXIT_SYNCADRSMATCH 0x14
+ * #define AUTOMODES_EXIT_PACKETSENT 0x18
+ * #define AUTOMODES_EXIT_RXTIMEOUT 0x1C
+ *
+ * #define AUTOMODES_INTERMEDIATE_SLEEP 0x00 // Default
+ * #define AUTOMODES_INTERMEDIATE_STANDBY 0x01
+ * #define AUTOMODES_INTERMEDIATE_RECEIVER 0x02
+ * #define AUTOMODES_INTERMEDIATE_TRANSMITTER 0x03
+ *
+ */
+/* RegFifoThresh (0x3c) */
+#define MASK_FIFO_THRESH_TXSTART 0x80
+#define MASK_FIFO_THRESH_VALUE 0x7F
+
+/*
+ *
+ * // RegPacketConfig2
+ * #define PACKET2_RXRESTARTDELAY_1BIT 0x00 // Default
+ * #define PACKET2_RXRESTARTDELAY_2BITS 0x10
+ * #define PACKET2_RXRESTARTDELAY_4BITS 0x20
+ * #define PACKET2_RXRESTARTDELAY_8BITS 0x30
+ * #define PACKET2_RXRESTARTDELAY_16BITS 0x40
+ * #define PACKET2_RXRESTARTDELAY_32BITS 0x50
+ * #define PACKET2_RXRESTARTDELAY_64BITS 0x60
+ * #define PACKET2_RXRESTARTDELAY_128BITS 0x70
+ * #define PACKET2_RXRESTARTDELAY_256BITS 0x80
+ * #define PACKET2_RXRESTARTDELAY_512BITS 0x90
+ * #define PACKET2_RXRESTARTDELAY_1024BITS 0xA0
+ * #define PACKET2_RXRESTARTDELAY_2048BITS 0xB0
+ * #define PACKET2_RXRESTARTDELAY_NONE 0xC0
+ * #define PACKET2_RXRESTART 0x04
+ *
+ * #define PACKET2_AUTORXRESTART_ON 0x02 // Default
+ * #define PACKET2_AUTORXRESTART_OFF 0x00
+ *
+ * #define PACKET2_AES_ON 0x01
+ * #define PACKET2_AES_OFF 0x00 // Default
+ *
+ *
+ * // RegTemp1
+ * #define TEMP1_MEAS_START 0x08
+ * #define TEMP1_MEAS_RUNNING 0x04
+ * #define TEMP1_ADCLOWPOWER_ON 0x01 // Default
+ * #define TEMP1_ADCLOWPOWER_OFF 0x00
+ */
+
+// RegTestDagc (0x6F)
+#define DAGC_NORMAL 0x00 /* Reset value */
+#define DAGC_IMPROVED_LOWBETA1 0x20
+#define DAGC_IMPROVED_LOWBETA0 0x30 /* Recommended val */
diff --git a/drivers/staging/rtl8188eu/core/rtw_ap.c b/drivers/staging/rtl8188eu/core/rtw_ap.c
index 647a922..32a4837 100644
--- a/drivers/staging/rtl8188eu/core/rtw_ap.c
+++ b/drivers/staging/rtl8188eu/core/rtw_ap.c
@@ -119,7 +119,7 @@ static void update_BCNTIM(struct adapter *padapter)
}
*dst_ie++ = _TIM_IE_;
- if ((pstapriv->tim_bitmap&0xff00) && (pstapriv->tim_bitmap&0x00fc))
+ if ((pstapriv->tim_bitmap & 0xff00) && (pstapriv->tim_bitmap & 0x00fc))
tim_ielen = 5;
else
tim_ielen = 4;
@@ -129,7 +129,7 @@ static void update_BCNTIM(struct adapter *padapter)
*dst_ie++ = 0;/* DTIM count */
*dst_ie++ = 1;/* DTIM period */
- if (pstapriv->tim_bitmap&BIT(0))/* for bc/mc frames */
+ if (pstapriv->tim_bitmap & BIT(0))/* for bc/mc frames */
*dst_ie++ = BIT(0);/* bitmap ctrl */
else
*dst_ie++ = 0;
@@ -583,10 +583,10 @@ static void update_bmc_sta(struct adapter *padapter)
{
u8 arg = 0;
- arg = psta->mac_id&0x1f;
+ arg = psta->mac_id & 0x1f;
arg |= BIT(7);
tx_ra_bitmap |= ((raid << 28) & 0xf0000000);
- DBG_88E("update_bmc_sta, mask = 0x%x, arg = 0x%x\n", tx_ra_bitmap, arg);
+ DBG_88E("%s, mask = 0x%x, arg = 0x%x\n", __func__, tx_ra_bitmap, arg);
/* bitmap[0:27] = tx_rate_bitmap */
/* bitmap[28:31]= Rate Adaptive id */
@@ -1043,7 +1043,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
(psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_CCMP))
pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY & (0x07 << 2));
else
- pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00);
+ pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY & 0x00);
/* set Max Rx AMPDU size to 64K */
pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_FACTOR & 0x03);
@@ -1719,7 +1719,7 @@ int rtw_sta_flush(struct adapter *padapter)
DBG_88E(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
- if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
+ if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
return 0;
spin_lock_bh(&pstapriv->asoc_list_lock);
@@ -1754,7 +1754,7 @@ void sta_info_update(struct adapter *padapter, struct sta_info *psta)
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
/* update wmm cap. */
- if (WLAN_STA_WME&flags)
+ if (WLAN_STA_WME & flags)
psta->qos_option = 1;
else
psta->qos_option = 0;
@@ -1763,7 +1763,7 @@ void sta_info_update(struct adapter *padapter, struct sta_info *psta)
psta->qos_option = 0;
/* update 802.11n ht cap. */
- if (WLAN_STA_HT&flags) {
+ if (WLAN_STA_HT & flags) {
psta->htpriv.ht_option = true;
psta->qos_option = 1;
} else {
diff --git a/drivers/staging/rtl8188eu/core/rtw_cmd.c b/drivers/staging/rtl8188eu/core/rtw_cmd.c
index a69007e..9461bce 100644
--- a/drivers/staging/rtl8188eu/core/rtw_cmd.c
+++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c
@@ -186,7 +186,7 @@ _next:
pcmd->res = H2C_DROPPED;
} else {
if (pcmd->cmdcode < ARRAY_SIZE(wlancmds)) {
- cmd_hdl = wlancmds[pcmd->cmdcode].h2cfuns;
+ cmd_hdl = wlancmds[pcmd->cmdcode].h2cfuns;
if (cmd_hdl) {
ret = cmd_hdl(pcmd->padapter, pcmd->parmbuf);
diff --git a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c
index d8d88b5..767928a 100644
--- a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c
+++ b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c
@@ -56,7 +56,7 @@ u8 rtw_do_join(struct adapter *padapter)
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("rtw_do_join(): site survey if scanned_queue is empty\n."));
/* submit site_survey_cmd */
ret = rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0);
- if (_SUCCESS != ret) {
+ if (ret != _SUCCESS) {
pmlmepriv->to_join = false;
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("rtw_do_join(): site survey return error\n."));
}
@@ -110,7 +110,7 @@ u8 rtw_do_join(struct adapter *padapter)
if (!pmlmepriv->LinkDetectInfo.bBusyTraffic ||
pmlmepriv->to_roaming > 0) {
ret = rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0);
- if (_SUCCESS != ret) {
+ if (ret != _SUCCESS) {
pmlmepriv->to_join = false;
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("do_join(): site survey return error\n."));
}
@@ -621,7 +621,7 @@ int rtw_set_country(struct adapter *adapter, const char *country_code)
DBG_88E("%s country_code:%s\n", __func__, country_code);
for (i = 0; i < ARRAY_SIZE(channel_table); i++) {
- if (0 == strcmp(channel_table[i].name, country_code)) {
+ if (strcmp(channel_table[i].name, country_code) == 0) {
channel_plan = channel_table[i].channel_plan;
break;
}
diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme.c b/drivers/staging/rtl8188eu/core/rtw_mlme.c
index fde3060..f663e6c 100644
--- a/drivers/staging/rtl8188eu/core/rtw_mlme.c
+++ b/drivers/staging/rtl8188eu/core/rtw_mlme.c
@@ -1502,7 +1502,7 @@ int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv)
pmlmepriv->pscanned = phead->next;
while (phead != pmlmepriv->pscanned) {
pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list);
- if (pnetwork == NULL) {
+ if (!pnetwork) {
RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("%s return _FAIL:(pnetwork==NULL)\n", __func__));
ret = _FAIL;
goto exit;
@@ -1566,7 +1566,6 @@ int rtw_set_auth(struct adapter *adapter, struct security_priv *psecuritypriv)
res = _FAIL;
goto exit;
}
- memset(psetauthparm, 0, sizeof(struct setauth_parm));
psetauthparm->mode = (unsigned char)psecuritypriv->dot11AuthAlgrthm;
pcmd->cmdcode = _SetAuth_CMD_;
pcmd->parmbuf = (unsigned char *)psetauthparm;
@@ -1601,8 +1600,6 @@ int rtw_set_key(struct adapter *adapter, struct security_priv *psecuritypriv, in
goto err_free_cmd;
}
- memset(psetkeyparm, 0, sizeof(struct setkey_parm));
-
if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) {
psetkeyparm->algorithm = (unsigned char)psecuritypriv->dot118021XGrpPrivacy;
RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
@@ -1708,14 +1705,9 @@ static int SecIsInPMKIDList(struct adapter *Adapter, u8 *bssid)
do {
if ((psecuritypriv->PMKIDList[i].bUsed) &&
- (!memcmp(psecuritypriv->PMKIDList[i].Bssid, bssid, ETH_ALEN))) {
+ (!memcmp(psecuritypriv->PMKIDList[i].Bssid, bssid, ETH_ALEN)))
break;
- } else {
- i++;
- /* continue; */
- }
-
- } while (i < NUM_PMKID_CACHE);
+ } while (++i < NUM_PMKID_CACHE);
if (i == NUM_PMKID_CACHE)
i = -1;/* Could not find. */
diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
index 88a3a2b..611c940 100644
--- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
@@ -3961,7 +3961,8 @@ static void init_mlme_ext_priv_value(struct adapter *padapter)
static int has_channel(struct rt_channel_info *channel_set,
u8 chanset_size,
- u8 chan) {
+ u8 chan)
+{
int i;
for (i = 0; i < chanset_size; i++) {
@@ -3973,7 +3974,8 @@ static int has_channel(struct rt_channel_info *channel_set,
static void init_channel_list(struct adapter *padapter, struct rt_channel_info *channel_set,
u8 chanset_size,
- struct p2p_channels *channel_list) {
+ struct p2p_channels *channel_list)
+{
struct p2p_oper_class_map op_class[] = {
{ IEEE80211G, 81, 1, 13, 1, BW20 },
{ IEEE80211G, 82, 14, 14, 1, BW20 },
diff --git a/drivers/staging/rtl8188eu/include/rtw_ioctl.h b/drivers/staging/rtl8188eu/include/rtw_ioctl.h
index 0fa78ed..4c925e6 100644
--- a/drivers/staging/rtl8188eu/include/rtw_ioctl.h
+++ b/drivers/staging/rtl8188eu/include/rtw_ioctl.h
@@ -75,7 +75,8 @@ struct oid_par_priv {
};
#if defined(_RTW_MP_IOCTL_C_)
-static int oid_null_function(struct oid_par_priv *poid_par_priv) {
+static int oid_null_function(struct oid_par_priv *poid_par_priv)
+{
return NDIS_STATUS_SUCCESS;
}
#endif
diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
index 763eccd..c0664dc 100644
--- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
@@ -2166,8 +2166,6 @@ static int set_group_key(struct adapter *padapter, u8 *key, u8 alg, int keyid)
goto exit;
}
- memset(psetkeyparm, 0, sizeof(struct setkey_parm));
-
psetkeyparm->keyid = (u8)keyid;
psetkeyparm->algorithm = alg;
diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c
index 56cd4e5..32c7225 100644
--- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c
+++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c
@@ -32,7 +32,7 @@
#define USB_VENDER_ID_REALTEK 0x0bda
/* DID_USB_v916_20130116 */
-static struct usb_device_id rtw_usb_id_tbl[] = {
+static const struct usb_device_id rtw_usb_id_tbl[] = {
/*=== Realtek demoboard ===*/
{USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8179)}, /* 8188EUS */
{USB_DEVICE(USB_VENDER_ID_REALTEK, 0x0179)}, /* 8188ETV */
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
index a4aedb4..cbf8eb4 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
@@ -2385,7 +2385,7 @@ static inline void ieee80211_process_probe_response(
struct ieee80211_probe_response *beacon,
struct ieee80211_rx_stats *stats)
{
- struct ieee80211_network network;
+ struct ieee80211_network *network;
struct ieee80211_network *target;
struct ieee80211_network *oldest = NULL;
#ifdef CONFIG_IEEE80211_DEBUG
@@ -2397,7 +2397,10 @@ static inline void ieee80211_process_probe_response(
u16 capability;
//u8 wmm_info;
- memset(&network, 0, sizeof(struct ieee80211_network));
+ network = kzalloc(sizeof(*network), GFP_ATOMIC);
+ if (!network)
+ goto out;
+
capability = le16_to_cpu(beacon->capability);
IEEE80211_DEBUG_SCAN(
"'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
@@ -2420,14 +2423,14 @@ static inline void ieee80211_process_probe_response(
(capability & (1 << 0x1)) ? '1' : '0',
(capability & (1 << 0x0)) ? '1' : '0');
- if (ieee80211_network_init(ieee, beacon, &network, stats)) {
+ if (ieee80211_network_init(ieee, beacon, network, stats)) {
IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n",
escape_essid(info_element->data,
info_element->len),
beacon->header.addr3,
fc == IEEE80211_STYPE_PROBE_RESP ?
"PROBE RESPONSE" : "BEACON");
- return;
+ goto out;
}
// For Asus EeePc request,
@@ -2437,8 +2440,8 @@ static inline void ieee80211_process_probe_response(
// then wireless adapter should do active scan from ch1~11 and
// passive scan from ch12~14
- if (!IsLegalChannel(ieee, network.channel))
- return;
+ if (!IsLegalChannel(ieee, network->channel))
+ goto out;
if (ieee->bGlobalDomain)
{
if (fc == IEEE80211_STYPE_PROBE_RESP)
@@ -2446,19 +2449,19 @@ static inline void ieee80211_process_probe_response(
// Case 1: Country code
if(IS_COUNTRY_IE_VALID(ieee) )
{
- if (!IsLegalChannel(ieee, network.channel)) {
- printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network.channel);
- return;
+ if (!IsLegalChannel(ieee, network->channel)) {
+ printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network->channel);
+ goto out;
}
}
// Case 2: No any country code.
else
{
// Filter over channel ch12~14
- if (network.channel > 11)
+ if (network->channel > 11)
{
- printk("GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network.channel);
- return;
+ printk("GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network->channel);
+ goto out;
}
}
}
@@ -2467,19 +2470,19 @@ static inline void ieee80211_process_probe_response(
// Case 1: Country code
if(IS_COUNTRY_IE_VALID(ieee) )
{
- if (!IsLegalChannel(ieee, network.channel)) {
- printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n",network.channel);
- return;
+ if (!IsLegalChannel(ieee, network->channel)) {
+ printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n",network->channel);
+ goto out;
}
}
// Case 2: No any country code.
else
{
// Filter over channel ch12~14
- if (network.channel > 14)
+ if (network->channel > 14)
{
- printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n",network.channel);
- return;
+ printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n",network->channel);
+ goto out;
}
}
}
@@ -2497,8 +2500,8 @@ static inline void ieee80211_process_probe_response(
spin_lock_irqsave(&ieee->lock, flags);
- if (is_same_network(&ieee->current_network, &network, ieee)) {
- update_network(&ieee->current_network, &network);
+ if (is_same_network(&ieee->current_network, network, ieee)) {
+ update_network(&ieee->current_network, network);
if ((ieee->current_network.mode == IEEE_N_24G || ieee->current_network.mode == IEEE_G)
&& ieee->current_network.berp_info_valid){
if(ieee->current_network.erp_value& ERP_UseProtection)
@@ -2512,11 +2515,11 @@ static inline void ieee80211_process_probe_response(
ieee->LinkDetectInfo.NumRecvBcnInPeriod++;
}
else //hidden AP
- network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & ieee->current_network.flags);
+ network->flags = (~NETWORK_EMPTY_ESSID & network->flags)|(NETWORK_EMPTY_ESSID & ieee->current_network.flags);
}
list_for_each_entry(target, &ieee->network_list, list) {
- if (is_same_network(target, &network, ieee))
+ if (is_same_network(target, network, ieee))
break;
if ((oldest == NULL) ||
(target->last_scanned < oldest->last_scanned))
@@ -2545,16 +2548,16 @@ static inline void ieee80211_process_probe_response(
#ifdef CONFIG_IEEE80211_DEBUG
IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
- escape_essid(network.ssid,
- network.ssid_len),
- network.bssid,
+ escape_essid(network->ssid,
+ network->ssid_len),
+ network->bssid,
fc == IEEE80211_STYPE_PROBE_RESP ?
"PROBE RESPONSE" : "BEACON");
#endif
- memcpy(target, &network, sizeof(*target));
+ memcpy(target, network, sizeof(*target));
list_add_tail(&target->list, &ieee->network_list);
if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
- ieee80211_softmac_new_net(ieee,&network);
+ ieee80211_softmac_new_net(ieee,network);
} else {
IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n",
escape_essid(target->ssid,
@@ -2570,27 +2573,30 @@ static inline void ieee80211_process_probe_response(
renew = !time_after(target->last_scanned + ieee->scan_age, jiffies);
//YJ,add,080819,for hidden ap
if(is_beacon(beacon->header.frame_ctl) == 0)
- network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & target->flags);
- //if(strncmp(network.ssid, "linksys-c",9) == 0)
- // printk("====>2 network.ssid=%s FLAG=%d target.ssid=%s FLAG=%d\n", network.ssid, network.flags, target->ssid, target->flags);
- if(((network.flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \
- && (((network.ssid_len > 0) && (strncmp(target->ssid, network.ssid, network.ssid_len)))\
- ||((ieee->current_network.ssid_len == network.ssid_len)&&(strncmp(ieee->current_network.ssid, network.ssid, network.ssid_len) == 0)&&(ieee->state == IEEE80211_NOLINK))))
+ network->flags = (~NETWORK_EMPTY_ESSID & network->flags)|(NETWORK_EMPTY_ESSID & target->flags);
+ //if(strncmp(network->ssid, "linksys-c",9) == 0)
+ // printk("====>2 network->ssid=%s FLAG=%d target.ssid=%s FLAG=%d\n", network->ssid, network->flags, target->ssid, target->flags);
+ if(((network->flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \
+ && (((network->ssid_len > 0) && (strncmp(target->ssid, network->ssid, network->ssid_len)))\
+ ||((ieee->current_network.ssid_len == network->ssid_len)&&(strncmp(ieee->current_network.ssid, network->ssid, network->ssid_len) == 0)&&(ieee->state == IEEE80211_NOLINK))))
renew = 1;
//YJ,add,080819,for hidden ap,end
- update_network(target, &network);
+ update_network(target, network);
if(renew && (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE))
- ieee80211_softmac_new_net(ieee,&network);
+ ieee80211_softmac_new_net(ieee,network);
}
spin_unlock_irqrestore(&ieee->lock, flags);
- if (is_beacon(beacon->header.frame_ctl)&&is_same_network(&ieee->current_network, &network, ieee)&&\
+ if (is_beacon(beacon->header.frame_ctl)&&is_same_network(&ieee->current_network, network, ieee)&&\
(ieee->state == IEEE80211_LINKED)) {
if (ieee->handle_beacon != NULL) {
ieee->handle_beacon(ieee->dev,beacon,&ieee->current_network);
}
}
+
+out:
+ kfree(network);
}
void ieee80211_rx_mgt(struct ieee80211_device *ieee,
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c
index 6072099..9248dbc 100644
--- a/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c
@@ -176,7 +176,7 @@ void HTDebugHTInfo(u8 *InfoIE, u8 *TitleString)
IEEE80211_DEBUG(IEEE80211_DL_HT, "<Log HT Information Element>. Called by %s\n", TitleString);
IEEE80211_DEBUG(IEEE80211_DL_HT, "\tPrimary channel = %d\n", pHTInfoEle->ControlChl);
- IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSenondary channel =");
+ IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSecondary channel =");
switch (pHTInfoEle->ExtChlOffset)
{
case 0:
diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c
index 779ecdb..46b3f19 100644
--- a/drivers/staging/rtl8192u/r8192U_core.c
+++ b/drivers/staging/rtl8192u/r8192U_core.c
@@ -270,8 +270,7 @@ int write_nic_byte_E(struct net_device *dev, int indx, u8 data)
kfree(usbdata);
if (status < 0) {
- netdev_err(dev, "write_nic_byte_E TimeOut! status: %d\n",
- status);
+ netdev_err(dev, "%s TimeOut! status: %d\n", __func__, status);
return status;
}
return 0;
@@ -321,7 +320,7 @@ int write_nic_byte(struct net_device *dev, int indx, u8 data)
kfree(usbdata);
if (status < 0) {
- netdev_err(dev, "write_nic_byte TimeOut! status: %d\n", status);
+ netdev_err(dev, "%s TimeOut! status: %d\n", __func__, status);
return status;
}
@@ -348,7 +347,7 @@ int write_nic_word(struct net_device *dev, int indx, u16 data)
kfree(usbdata);
if (status < 0) {
- netdev_err(dev, "write_nic_word TimeOut! status: %d\n", status);
+ netdev_err(dev, "%s TimeOut! status: %d\n", __func__, status);
return status;
}
@@ -376,8 +375,7 @@ int write_nic_dword(struct net_device *dev, int indx, u32 data)
if (status < 0) {
- netdev_err(dev, "write_nic_dword TimeOut! status: %d\n",
- status);
+ netdev_err(dev, "%s TimeOut! status: %d\n", __func__, status);
return status;
}
@@ -3095,7 +3093,8 @@ static RESET_TYPE TxCheckStuck(struct net_device *dev)
if (bCheckFwTxCnt) {
if (HalTxCheckStuck819xUsb(dev)) {
RT_TRACE(COMP_RESET,
- "TxCheckStuck(): Fw indicates no Tx condition!\n");
+ "%s: Fw indicates no Tx condition!\n",
+ __func__);
return RESET_TYPE_SILENT;
}
}
@@ -3237,7 +3236,7 @@ static void CamRestoreAllEntry(struct net_device *dev)
static u8 CAM_CONST_BROAD[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
- RT_TRACE(COMP_SEC, "CamRestoreAllEntry:\n");
+ RT_TRACE(COMP_SEC, "%s:\n", __func__);
if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40) ||
@@ -3835,8 +3834,8 @@ static u8 HwRateToMRate90(bool bIsHT, u8 rate)
default:
ret_rate = 0xff;
RT_TRACE(COMP_RECV,
- "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",
- rate, bIsHT);
+ "%s: Non supported Rate [%x], bIsHT = %d!!!\n",
+ __func__, rate, bIsHT);
break;
}
@@ -3897,8 +3896,8 @@ static u8 HwRateToMRate90(bool bIsHT, u8 rate)
default:
ret_rate = 0xff;
RT_TRACE(COMP_RECV,
- "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",
- rate, bIsHT);
+ "%s: Non supported Rate [%x], bIsHT = %d!!!\n",
+ __func__, rate, bIsHT);
break;
}
}
diff --git a/drivers/staging/rtl8192u/r8192U_hw.h b/drivers/staging/rtl8192u/r8192U_hw.h
index 174ccf6..00a123d 100644
--- a/drivers/staging/rtl8192u/r8192U_hw.h
+++ b/drivers/staging/rtl8192u/r8192U_hw.h
@@ -20,25 +20,24 @@
#ifndef R8192_HW
#define R8192_HW
-typedef enum _VERSION_819xU{
+typedef enum _VERSION_819xU {
VERSION_819xU_A, // A-cut
VERSION_819xU_B, // B-cut
VERSION_819xU_C,// C-cut
} VERSION_819xU, *PVERSION_819xU;
//added for different RF type
-typedef enum _RT_RF_TYPE_DEF
-{
+typedef enum _RT_RF_TYPE_DEF {
RF_1T2R = 0,
RF_2T4R,
RF_819X_MAX_TYPE
-}RT_RF_TYPE_DEF;
+} RT_RF_TYPE_DEF;
-typedef enum _BaseBand_Config_Type{
+typedef enum _BaseBand_Config_Type {
BaseBand_Config_PHY_REG = 0, //Radio Path A
BaseBand_Config_AGC_TAB = 1, //Radio Path B
-}BaseBand_Config_Type, *PBaseBand_Config_Type;
+} BaseBand_Config_Type, *PBaseBand_Config_Type;
#define RTL8187_REQT_READ 0xc0
#define RTL8187_REQT_WRITE 0x40
#define RTL8187_REQ_GET_REGS 0x05
diff --git a/drivers/staging/rtl8192u/r819xU_cmdpkt.c b/drivers/staging/rtl8192u/r819xU_cmdpkt.c
index 87ab3ba..ae9a4f1 100644
--- a/drivers/staging/rtl8192u/r819xU_cmdpkt.c
+++ b/drivers/staging/rtl8192u/r819xU_cmdpkt.c
@@ -294,7 +294,7 @@ static void cmpk_handle_query_config_rx(struct net_device *dev, u8 *pmsg)
* windows OS. So we have to read the content byte by byte or transfer
* endian type before copy the message copy.
*/
- rx_query_cfg.cfg_action = (pmsg[4] & 0x80000000) >> 31;
+ rx_query_cfg.cfg_action = (pmsg[4] & 0x80) >> 7;
rx_query_cfg.cfg_type = (pmsg[4] & 0x60) >> 5;
rx_query_cfg.cfg_size = (pmsg[4] & 0x18) >> 3;
rx_query_cfg.cfg_page = (pmsg[6] & 0x0F) >> 0;
diff --git a/drivers/staging/rtl8712/mlme_linux.c b/drivers/staging/rtl8712/mlme_linux.c
index 2037265..a077069 100644
--- a/drivers/staging/rtl8712/mlme_linux.c
+++ b/drivers/staging/rtl8712/mlme_linux.c
@@ -111,8 +111,8 @@ void r8712_os_indicate_disconnect(struct _adapter *adapter)
*/
memcpy(&backupPMKIDList[0],
- &adapter->securitypriv.PMKIDList[0],
- sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE);
+ &adapter->securitypriv.PMKIDList[0],
+ sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE);
backupPMKIDIndex = adapter->securitypriv.PMKIDIndex;
backupTKIPCountermeasure =
adapter->securitypriv.btkip_countermeasure;
diff --git a/drivers/staging/rtl8712/rtl8712_cmd.c b/drivers/staging/rtl8712/rtl8712_cmd.c
index 5346c65..0104ace 100644
--- a/drivers/staging/rtl8712/rtl8712_cmd.c
+++ b/drivers/staging/rtl8712/rtl8712_cmd.c
@@ -385,7 +385,7 @@ _next:
if (blnPending)
wr_sz += 8; /* Append 8 bytes */
r8712_write_mem(padapter, RTL8712_DMA_H2CCMD, wr_sz,
- (u8 *)pdesc);
+ (u8 *)pdesc);
pcmdpriv->cmd_seq++;
if (pcmd->cmdcode == GEN_CMD_CODE(_CreateBss)) {
pcmd->res = H2C_SUCCESS;
diff --git a/drivers/staging/rtl8712/rtl8712_efuse.c b/drivers/staging/rtl8712/rtl8712_efuse.c
index 205298e..d90213e 100644
--- a/drivers/staging/rtl8712/rtl8712_efuse.c
+++ b/drivers/staging/rtl8712/rtl8712_efuse.c
@@ -347,7 +347,7 @@ static u8 fix_header(struct _adapter *padapter, u8 header, u16 header_addr)
ret = false;
if (value == 0xFF) /* write again */
efuse_one_byte_write(padapter, addr,
- pkt.data[i * 2]);
+ pkt.data[i * 2]);
}
if (!efuse_one_byte_read(padapter, addr + 1, &value)) {
ret = false;
diff --git a/drivers/staging/rtl8712/rtl8712_xmit.c b/drivers/staging/rtl8712/rtl8712_xmit.c
index 7fe6265..42d0140 100644
--- a/drivers/staging/rtl8712/rtl8712_xmit.c
+++ b/drivers/staging/rtl8712/rtl8712_xmit.c
@@ -640,7 +640,7 @@ int r8712_xmitframe_complete(struct _adapter *padapter,
/* 1st frame dequeued */
pxmitframe = dequeue_xframe_ex(pxmitpriv, phwxmits, hwentry);
/* need to remember the 1st frame */
- if (pxmitframe != NULL) {
+ if (pxmitframe) {
#ifdef CONFIG_R8712_TX_AGGR
/* 1. dequeue 2nd frame
@@ -653,13 +653,13 @@ int r8712_xmitframe_complete(struct _adapter *padapter,
r8712_free_xmitbuf(pxmitpriv, pxmitbuf);
return false;
}
- if (p2ndxmitframe != NULL)
+ if (p2ndxmitframe)
if (p2ndxmitframe->frame_tag != DATA_FRAMETAG) {
r8712_free_xmitbuf(pxmitpriv, pxmitbuf);
return false;
}
r8712_xmitframe_aggr_1st(pxmitbuf, pxmitframe);
- if (p2ndxmitframe != NULL) {
+ if (p2ndxmitframe) {
u16 total_length;
total_length = r8712_xmitframe_aggr_next(
@@ -667,7 +667,7 @@ int r8712_xmitframe_complete(struct _adapter *padapter,
do {
p2ndxmitframe = dequeue_xframe_ex(
pxmitpriv, phwxmits, hwentry);
- if (p2ndxmitframe != NULL)
+ if (p2ndxmitframe)
total_length =
r8712_xmitframe_aggr_next(
pxmitbuf,
diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c
index 897d462..b3e266b 100644
--- a/drivers/staging/rtl8712/usb_intf.c
+++ b/drivers/staging/rtl8712/usb_intf.c
@@ -47,7 +47,7 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf,
static void r871xu_dev_remove(struct usb_interface *pusb_intf);
-static struct usb_device_id rtl871x_usb_id_tbl[] = {
+static const struct usb_device_id rtl871x_usb_id_tbl[] = {
/* RTL8188SU */
/* Realtek */
diff --git a/drivers/staging/rtl8723bs/core/rtw_btcoex.c b/drivers/staging/rtl8723bs/core/rtw_btcoex.c
index 3c5cb78..01f78d1 100644
--- a/drivers/staging/rtl8723bs/core/rtw_btcoex.c
+++ b/drivers/staging/rtl8723bs/core/rtw_btcoex.c
@@ -55,7 +55,7 @@ void rtw_btcoex_ConnectNotify(struct adapter *padapter, u8 action)
void rtw_btcoex_MediaStatusNotify(struct adapter *padapter, u8 mediaStatus)
{
- if ((RT_MEDIA_CONNECT == mediaStatus)
+ if ((mediaStatus == RT_MEDIA_CONNECT)
&& (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == true)) {
rtw_hal_set_hwreg(padapter, HW_VAR_DL_RSVD_PAGE, NULL);
}
diff --git a/drivers/staging/rtl8723bs/core/rtw_cmd.c b/drivers/staging/rtl8723bs/core/rtw_cmd.c
index 080c81b..d381827 100644
--- a/drivers/staging/rtl8723bs/core/rtw_cmd.c
+++ b/drivers/staging/rtl8723bs/core/rtw_cmd.c
@@ -432,7 +432,7 @@ int rtw_cmd_thread(void *context)
unsigned long cmd_process_time;
u8 (*cmd_hdl)(struct adapter *padapter, u8 *pbuf);
void (*pcmd_callback)(struct adapter *dev, struct cmd_obj *pcmd);
- struct adapter *padapter = (struct adapter *)context;
+ struct adapter *padapter = context;
struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
struct drvextra_cmd_parm *extra_parm = NULL;
diff --git a/drivers/staging/rtl8723bs/core/rtw_efuse.c b/drivers/staging/rtl8723bs/core/rtw_efuse.c
index 8e29802..44b92ef 100644
--- a/drivers/staging/rtl8723bs/core/rtw_efuse.c
+++ b/drivers/staging/rtl8723bs/core/rtw_efuse.c
@@ -163,7 +163,7 @@ Efuse_CalculateWordCnts(u8 word_en)
/* Description: */
/* 1. Execute E-Fuse read byte operation according as map offset and */
/* save to E-Fuse table. */
-/* 2. Refered from SD1 Richard. */
+/* 2. Referred from SD1 Richard. */
/* */
/* Assumption: */
/* 1. Boot from E-Fuse and successfully auto-load. */
diff --git a/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c b/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c
index e0793f8..d815a69 100644
--- a/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c
+++ b/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c
@@ -127,7 +127,6 @@ u8 rtw_do_join(struct adapter *padapter)
pibss = padapter->registrypriv.dev_network.MacAddress;
- memset(&pdev_network->Ssid, 0, sizeof(struct ndis_802_11_ssid));
memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid));
rtw_update_registrypriv_dev_network(padapter);
diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme.c b/drivers/staging/rtl8723bs/core/rtw_mlme.c
index d5ab123..6b77820 100644
--- a/drivers/staging/rtl8723bs/core/rtw_mlme.c
+++ b/drivers/staging/rtl8723bs/core/rtw_mlme.c
@@ -922,7 +922,6 @@ void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf)
RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("switching to adhoc master\n"));
- memset(&pdev_network->Ssid, 0, sizeof(struct ndis_802_11_ssid));
memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid));
rtw_update_registrypriv_dev_network(adapter);
@@ -1384,7 +1383,7 @@ static void rtw_joinbss_update_network(struct adapter *padapter, struct wlan_net
/* define REJOIN */
void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf)
{
- static u8 retry = 0;
+ static u8 retry;
u8 timer_cancelled;
struct sta_info *ptarget_sta = NULL, *pcur_sta = NULL;
struct sta_priv *pstapriv = &adapter->stapriv;
@@ -1774,7 +1773,6 @@ void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf)
memcpy(pdev_network, &tgt_network->network, get_wlan_bssid_ex_sz(&tgt_network->network));
- memset(&pdev_network->Ssid, 0, sizeof(struct ndis_802_11_ssid));
memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid));
rtw_update_registrypriv_dev_network(adapter);
@@ -2498,8 +2496,7 @@ sint rtw_restruct_sec_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, uint in
uint ndisauthmode = psecuritypriv->ndisauthtype;
RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
- ("+rtw_restruct_sec_ie: ndisauthmode =%d ndissecuritytype =%d\n",
- ndisauthmode, ndissecuritytype));
+ ("+rtw_restruct_sec_ie: ndisauthmode =%d\n", ndisauthmode));
/* copy fixed ie only */
memcpy(out_ie, in_ie, 12);
diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
index 17d881d..b6d137f 100644
--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
@@ -1228,7 +1228,7 @@ unsigned int OnAssocReq(struct adapter *padapter, union recv_frame *precv_frame)
}
pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
- if (pstat == (struct sta_info *)NULL) {
+ if (pstat == NULL) {
status = _RSON_CLS2_;
goto asoc_class2_error;
}
@@ -2392,7 +2392,7 @@ s32 dump_mgntframe_and_wait(struct adapter *padapter, struct xmit_frame *pmgntfr
s32 dump_mgntframe_and_wait_ack(struct adapter *padapter, struct xmit_frame *pmgntframe)
{
- static u8 seq_no = 0;
+ static u8 seq_no;
s32 ret = _FAIL;
u32 timeout_ms = 500;/* 500ms */
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
diff --git a/drivers/staging/rtl8723bs/core/rtw_odm.c b/drivers/staging/rtl8723bs/core/rtw_odm.c
index 3144e8e..edbcaeb 100644
--- a/drivers/staging/rtl8723bs/core/rtw_odm.c
+++ b/drivers/staging/rtl8723bs/core/rtw_odm.c
@@ -18,7 +18,7 @@
#include <rtw_odm.h>
#include <hal_data.h>
-static const char *odm_comp_str[] = {
+static const char * const odm_comp_str[] = {
/* BIT0 */"ODM_COMP_DIG",
/* BIT1 */"ODM_COMP_RA_MASK",
/* BIT2 */"ODM_COMP_DYNAMIC_TXPWR",
@@ -55,7 +55,7 @@ static const char *odm_comp_str[] = {
#define RTW_ODM_COMP_MAX 32
-static const char *odm_ability_str[] = {
+static const char * const odm_ability_str[] = {
/* BIT0 */"ODM_BB_DIG",
/* BIT1 */"ODM_BB_RA_MASK",
/* BIT2 */"ODM_BB_DYNAMIC_TXPWR",
@@ -87,7 +87,7 @@ static const char *odm_ability_str[] = {
#define RTW_ODM_ABILITY_MAX 27
-static const char *odm_dbg_level_str[] = {
+static const char * const odm_dbg_level_str[] = {
NULL,
"ODM_DBG_OFF",
"ODM_DBG_SERIOUS",
@@ -127,7 +127,8 @@ void rtw_odm_dbg_level_msg(void *sel, struct adapter *adapter)
DBG_871X_SEL_NL(sel, "odm.DebugLevel = %u\n", dbg_level);
for (i = 0; i < RTW_ODM_DBG_LEVEL_NUM; i++) {
if (odm_dbg_level_str[i])
- DBG_871X_SEL_NL(sel, "%u %s\n", i, odm_dbg_level_str[i]);
+ DBG_871X_SEL_NL(sel, "%u %s\n",
+ i, odm_dbg_level_str[i]);
}
}
@@ -161,20 +162,23 @@ void rtw_odm_adaptivity_parm_msg(void *sel, struct adapter *adapter)
struct hal_com_data *pHalData = GET_HAL_DATA(adapter);
DM_ODM_T *odm = &pHalData->odmpriv;
- DBG_871X_SEL_NL(sel, "%10s %16s %8s %10s %11s %14s\n"
- , "TH_L2H_ini", "TH_EDCCA_HL_diff", "IGI_Base", "ForceEDCCA", "AdapEn_RSSI", "IGI_LowerBound");
- DBG_871X_SEL_NL(sel, "0x%-8x %-16d 0x%-6x %-10d %-11u %-14u\n"
- , (u8)odm->TH_L2H_ini
- , odm->TH_EDCCA_HL_diff
- , odm->IGI_Base
- , odm->ForceEDCCA
- , odm->AdapEn_RSSI
- , odm->IGI_LowerBound
+ DBG_871X_SEL_NL(sel, "%10s %16s %8s %10s %11s %14s\n",
+ "TH_L2H_ini", "TH_EDCCA_HL_diff", "IGI_Base",
+ "ForceEDCCA", "AdapEn_RSSI", "IGI_LowerBound");
+ DBG_871X_SEL_NL(sel, "0x%-8x %-16d 0x%-6x %-10d %-11u %-14u\n",
+ (u8)odm->TH_L2H_ini,
+ odm->TH_EDCCA_HL_diff,
+ odm->IGI_Base,
+ odm->ForceEDCCA,
+ odm->AdapEn_RSSI,
+ odm->IGI_LowerBound
);
}
-void rtw_odm_adaptivity_parm_set(struct adapter *adapter, s8 TH_L2H_ini, s8 TH_EDCCA_HL_diff,
- s8 IGI_Base, bool ForceEDCCA, u8 AdapEn_RSSI, u8 IGI_LowerBound)
+void rtw_odm_adaptivity_parm_set(struct adapter *adapter, s8 TH_L2H_ini,
+ s8 TH_EDCCA_HL_diff, s8 IGI_Base,
+ bool ForceEDCCA, u8 AdapEn_RSSI,
+ u8 IGI_LowerBound)
{
struct hal_com_data *pHalData = GET_HAL_DATA(adapter);
DM_ODM_T *odm = &pHalData->odmpriv;
@@ -190,8 +194,8 @@ void rtw_odm_adaptivity_parm_set(struct adapter *adapter, s8 TH_L2H_ini, s8 TH_E
void rtw_odm_get_perpkt_rssi(void *sel, struct adapter *adapter)
{
struct hal_com_data *hal_data = GET_HAL_DATA(adapter);
- DM_ODM_T *odm = &(hal_data->odmpriv);
+ DM_ODM_T *odm = &hal_data->odmpriv;
DBG_871X_SEL_NL(sel, "RxRate = %s, RSSI_A = %d(%%), RSSI_B = %d(%%)\n",
- HDATA_RATE(odm->RxRate), odm->RSSI_A, odm->RSSI_B);
+ HDATA_RATE(odm->RxRate), odm->RSSI_A, odm->RSSI_B);
}
diff --git a/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c b/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c
index f708dbf..aabdaaf 100644
--- a/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c
+++ b/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c
@@ -210,8 +210,8 @@ void pwr_state_check_handler(RTW_TIMER_HDL_ARGS)
void traffic_check_for_leave_lps(struct adapter *padapter, u8 tx, u32 tx_packets)
{
- static unsigned long start_time = 0;
- static u32 xmit_cnt = 0;
+ static unsigned long start_time;
+ static u32 xmit_cnt;
u8 bLeaveLPS = false;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
@@ -829,7 +829,7 @@ static void pwr_rpwm_timeout_handler(void *FunctionContext)
struct pwrctrl_priv *pwrpriv;
- padapter = (struct adapter *)FunctionContext;
+ padapter = FunctionContext;
pwrpriv = adapter_to_pwrctl(padapter);
DBG_871X("+%s: rpwm = 0x%02X cpwm = 0x%02X\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm);
diff --git a/drivers/staging/rtl8723bs/core/rtw_recv.c b/drivers/staging/rtl8723bs/core/rtw_recv.c
index 695a5c9..68a6303 100644
--- a/drivers/staging/rtl8723bs/core/rtw_recv.c
+++ b/drivers/staging/rtl8723bs/core/rtw_recv.c
@@ -1005,7 +1005,7 @@ sint ap2sta_data_frame(
if (*psta == NULL) {
/* for AP multicast issue , modify by yiwei */
- static unsigned long send_issue_deauth_time = 0;
+ static unsigned long send_issue_deauth_time;
/* DBG_871X("After send deauth , %u ms has elapsed.\n", jiffies_to_msecs(jiffies - send_issue_deauth_time)); */
@@ -2360,7 +2360,7 @@ _err_exit:
void rtw_reordering_ctrl_timeout_handler(void *pcontext)
{
- struct recv_reorder_ctrl *preorder_ctrl = (struct recv_reorder_ctrl *)pcontext;
+ struct recv_reorder_ctrl *preorder_ctrl = pcontext;
struct adapter *padapter = preorder_ctrl->padapter;
struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
diff --git a/drivers/staging/rtl8723bs/core/rtw_security.c b/drivers/staging/rtl8723bs/core/rtw_security.c
index e832f16..06a7e40 100644
--- a/drivers/staging/rtl8723bs/core/rtw_security.c
+++ b/drivers/staging/rtl8723bs/core/rtw_security.c
@@ -162,7 +162,7 @@ static void arcfour_encrypt(
dest[i] = src[i] ^ (unsigned char)arcfour_byte(parc4ctx);
}
-static sint bcrc32initialized = 0;
+static sint bcrc32initialized;
static u32 crc32_table[256];
@@ -791,9 +791,9 @@ u32 rtw_tkip_decrypt(struct adapter *padapter, u8 *precvframe)
stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]);
if (stainfo != NULL) {
if (IS_MCAST(prxattrib->ra)) {
- static unsigned long start = 0;
- static u32 no_gkey_bc_cnt = 0;
- static u32 no_gkey_mc_cnt = 0;
+ static unsigned long start;
+ static u32 no_gkey_bc_cnt;
+ static u32 no_gkey_mc_cnt;
if (psecuritypriv->binstallGrpkey == false) {
res = _FAIL;
@@ -1882,9 +1882,9 @@ u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe)
RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_aes_decrypt: stainfo!= NULL!!!\n"));
if (IS_MCAST(prxattrib->ra)) {
- static unsigned long start = 0;
- static u32 no_gkey_bc_cnt = 0;
- static u32 no_gkey_mc_cnt = 0;
+ static unsigned long start;
+ static u32 no_gkey_bc_cnt;
+ static u32 no_gkey_mc_cnt;
/* DBG_871X("rx bc/mc packets, to perform sw rtw_aes_decrypt\n"); */
/* prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey; */
diff --git a/drivers/staging/rtl8723bs/core/rtw_xmit.c b/drivers/staging/rtl8723bs/core/rtw_xmit.c
index 8f2c9a6..022f654 100644
--- a/drivers/staging/rtl8723bs/core/rtw_xmit.c
+++ b/drivers/staging/rtl8723bs/core/rtw_xmit.c
@@ -2301,8 +2301,8 @@ static void do_queue_select(struct adapter *padapter, struct pkt_attrib *pattrib
*/
s32 rtw_xmit(struct adapter *padapter, _pkt **ppkt)
{
- static unsigned long start = 0;
- static u32 drop_cnt = 0;
+ static unsigned long start;
+ static u32 drop_cnt;
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct xmit_frame *pxmitframe = NULL;
@@ -3002,7 +3002,7 @@ int rtw_xmit_thread(void *context)
err = _SUCCESS;
- padapter = (struct adapter *)context;
+ padapter = context;
thread_enter("RTW_XMIT_THREAD");
diff --git a/drivers/staging/rtl8723bs/hal/hal_btcoex.c b/drivers/staging/rtl8723bs/hal/hal_btcoex.c
index 9e08a4d..86fee10 100644
--- a/drivers/staging/rtl8723bs/hal/hal_btcoex.c
+++ b/drivers/staging/rtl8723bs/hal/hal_btcoex.c
@@ -419,10 +419,10 @@ static u8 halbtcoutsrc_Get(void *pBtcContext, u8 getType, void *pOutBuf)
padapter = pBtCoexist->Adapter;
pHalData = GET_HAL_DATA(padapter);
mlmeext = &padapter->mlmeextpriv;
- pu8 = (u8 *)pOutBuf;
- pS4Tmp = (s32 *)pOutBuf;
- pU4Tmp = (u32 *)pOutBuf;
- pU1Tmp = (u8 *)pOutBuf;
+ pu8 = pOutBuf;
+ pS4Tmp = pOutBuf;
+ pU4Tmp = pOutBuf;
+ pU1Tmp = pOutBuf;
ret = true;
switch (getType) {
@@ -585,9 +585,9 @@ static u8 halbtcoutsrc_Set(void *pBtcContext, u8 setType, void *pInBuf)
pBtCoexist = (PBTC_COEXIST)pBtcContext;
padapter = pBtCoexist->Adapter;
pHalData = GET_HAL_DATA(padapter);
- pu8 = (u8 *)pInBuf;
- pU1Tmp = (u8 *)pInBuf;
- pU4Tmp = (u32 *)pInBuf;
+ pu8 = pInBuf;
+ pU1Tmp = pInBuf;
+ pU4Tmp = pInBuf;
ret = true;
if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
diff --git a/drivers/staging/rtl8723bs/hal/hal_com.c b/drivers/staging/rtl8723bs/hal/hal_com.c
index e3a9832..3e63b6d 100644
--- a/drivers/staging/rtl8723bs/hal/hal_com.c
+++ b/drivers/staging/rtl8723bs/hal/hal_com.c
@@ -1311,7 +1311,7 @@ void SetHalODMVar(
switch (eVariable) {
case HAL_ODM_STA_INFO:
{
- struct sta_info *psta = (struct sta_info *)pValue1;
+ struct sta_info *psta = pValue1;
if (bSet) {
DBG_8192C("### Set STA_(%d) info ###\n", psta->mac_id);
ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, psta);
@@ -1333,7 +1333,7 @@ void SetHalODMVar(
#if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
case HAL_ODM_NOISE_MONITOR:
{
- struct noise_info *pinfo = (struct noise_info *)pValue1;
+ struct noise_info *pinfo = pValue1;
#ifdef DBG_NOISE_MONITOR
DBG_8192C("### Noise monitor chan(%d)-bPauseDIG:%d, IGIValue:0x%02x, max_time:%d (ms) ###\n",
diff --git a/drivers/staging/rtl8723bs/hal/odm.c b/drivers/staging/rtl8723bs/hal/odm.c
index 2dbf199..ff43bb2 100644
--- a/drivers/staging/rtl8723bs/hal/odm.c
+++ b/drivers/staging/rtl8723bs/hal/odm.c
@@ -592,95 +592,95 @@ void ODM_CmnInfoHook(PDM_ODM_T pDM_Odm, ODM_CMNINFO_E CmnInfo, void *pValue)
/* Dynamic call by reference pointer. */
/* */
case ODM_CMNINFO_MAC_PHY_MODE:
- pDM_Odm->pMacPhyMode = (u8 *)pValue;
+ pDM_Odm->pMacPhyMode = pValue;
break;
case ODM_CMNINFO_TX_UNI:
- pDM_Odm->pNumTxBytesUnicast = (u64 *)pValue;
+ pDM_Odm->pNumTxBytesUnicast = pValue;
break;
case ODM_CMNINFO_RX_UNI:
- pDM_Odm->pNumRxBytesUnicast = (u64 *)pValue;
+ pDM_Odm->pNumRxBytesUnicast = pValue;
break;
case ODM_CMNINFO_WM_MODE:
- pDM_Odm->pwirelessmode = (u8 *)pValue;
+ pDM_Odm->pwirelessmode = pValue;
break;
case ODM_CMNINFO_BAND:
- pDM_Odm->pBandType = (u8 *)pValue;
+ pDM_Odm->pBandType = pValue;
break;
case ODM_CMNINFO_SEC_CHNL_OFFSET:
- pDM_Odm->pSecChOffset = (u8 *)pValue;
+ pDM_Odm->pSecChOffset = pValue;
break;
case ODM_CMNINFO_SEC_MODE:
- pDM_Odm->pSecurity = (u8 *)pValue;
+ pDM_Odm->pSecurity = pValue;
break;
case ODM_CMNINFO_BW:
- pDM_Odm->pBandWidth = (u8 *)pValue;
+ pDM_Odm->pBandWidth = pValue;
break;
case ODM_CMNINFO_CHNL:
- pDM_Odm->pChannel = (u8 *)pValue;
+ pDM_Odm->pChannel = pValue;
break;
case ODM_CMNINFO_DMSP_GET_VALUE:
- pDM_Odm->pbGetValueFromOtherMac = (bool *)pValue;
+ pDM_Odm->pbGetValueFromOtherMac = pValue;
break;
case ODM_CMNINFO_BUDDY_ADAPTOR:
- pDM_Odm->pBuddyAdapter = (struct adapter **)pValue;
+ pDM_Odm->pBuddyAdapter = pValue;
break;
case ODM_CMNINFO_DMSP_IS_MASTER:
- pDM_Odm->pbMasterOfDMSP = (bool *)pValue;
+ pDM_Odm->pbMasterOfDMSP = pValue;
break;
case ODM_CMNINFO_SCAN:
- pDM_Odm->pbScanInProcess = (bool *)pValue;
+ pDM_Odm->pbScanInProcess = pValue;
break;
case ODM_CMNINFO_POWER_SAVING:
- pDM_Odm->pbPowerSaving = (bool *)pValue;
+ pDM_Odm->pbPowerSaving = pValue;
break;
case ODM_CMNINFO_ONE_PATH_CCA:
- pDM_Odm->pOnePathCCA = (u8 *)pValue;
+ pDM_Odm->pOnePathCCA = pValue;
break;
case ODM_CMNINFO_DRV_STOP:
- pDM_Odm->pbDriverStopped = (bool *)pValue;
+ pDM_Odm->pbDriverStopped = pValue;
break;
case ODM_CMNINFO_PNP_IN:
- pDM_Odm->pbDriverIsGoingToPnpSetPowerSleep = (bool *)pValue;
+ pDM_Odm->pbDriverIsGoingToPnpSetPowerSleep = pValue;
break;
case ODM_CMNINFO_INIT_ON:
- pDM_Odm->pinit_adpt_in_progress = (bool *)pValue;
+ pDM_Odm->pinit_adpt_in_progress = pValue;
break;
case ODM_CMNINFO_ANT_TEST:
- pDM_Odm->pAntennaTest = (u8 *)pValue;
+ pDM_Odm->pAntennaTest = pValue;
break;
case ODM_CMNINFO_NET_CLOSED:
- pDM_Odm->pbNet_closed = (bool *)pValue;
+ pDM_Odm->pbNet_closed = pValue;
break;
case ODM_CMNINFO_FORCED_RATE:
- pDM_Odm->pForcedDataRate = (u16 *)pValue;
+ pDM_Odm->pForcedDataRate = pValue;
break;
case ODM_CMNINFO_FORCED_IGI_LB:
- pDM_Odm->pu1ForcedIgiLb = (u8 *)pValue;
+ pDM_Odm->pu1ForcedIgiLb = pValue;
break;
case ODM_CMNINFO_MP_MODE:
- pDM_Odm->mp_mode = (u8 *)pValue;
+ pDM_Odm->mp_mode = pValue;
break;
/* case ODM_CMNINFO_RTSTA_AID: */
diff --git a/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c b/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c
index 84a89ef..1565f2d 100644
--- a/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c
+++ b/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c
@@ -63,7 +63,7 @@ static int _BlockWrite(struct adapter *padapter, void *buffer, u32 buffSize)
u32 blockSize_p3 = 1; /* Phase #3 : Use 1-byte, the remnant of FW image. */
u32 blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0;
u32 remainSize_p1 = 0, remainSize_p2 = 0;
- u8 *bufferPtr = (u8 *)buffer;
+ u8 *bufferPtr = buffer;
u32 i = 0, offset = 0;
/* printk("====>%s %d\n", __func__, __LINE__); */
@@ -163,7 +163,7 @@ static int _WriteFW(struct adapter *padapter, void *buffer, u32 size)
int ret = _SUCCESS;
u32 pageNums, remainSize;
u32 page, offset;
- u8 *bufferPtr = (u8 *)buffer;
+ u8 *bufferPtr = buffer;
pageNums = size / MAX_DLFW_PAGE_SIZE;
/* RT_ASSERT((pageNums <= 4), ("Page numbers should not greater then 4\n")); */
@@ -643,7 +643,7 @@ static void Hal_GetEfuseDefinition(
case TYPE_EFUSE_MAX_SECTION:
{
u8 *pMax_section;
- pMax_section = (u8 *)pOut;
+ pMax_section = pOut;
if (efuseType == EFUSE_WIFI)
*pMax_section = EFUSE_MAX_SECTION_8723B;
@@ -655,7 +655,7 @@ static void Hal_GetEfuseDefinition(
case TYPE_EFUSE_REAL_CONTENT_LEN:
{
u16 *pu2Tmp;
- pu2Tmp = (u16 *)pOut;
+ pu2Tmp = pOut;
if (efuseType == EFUSE_WIFI)
*pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723B;
@@ -667,7 +667,7 @@ static void Hal_GetEfuseDefinition(
case TYPE_AVAILABLE_EFUSE_BYTES_BANK:
{
u16 *pu2Tmp;
- pu2Tmp = (u16 *)pOut;
+ pu2Tmp = pOut;
if (efuseType == EFUSE_WIFI)
*pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723B-EFUSE_OOB_PROTECT_BYTES);
@@ -679,7 +679,7 @@ static void Hal_GetEfuseDefinition(
case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL:
{
u16 *pu2Tmp;
- pu2Tmp = (u16 *)pOut;
+ pu2Tmp = pOut;
if (efuseType == EFUSE_WIFI)
*pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723B-EFUSE_OOB_PROTECT_BYTES);
@@ -691,7 +691,7 @@ static void Hal_GetEfuseDefinition(
case TYPE_EFUSE_MAP_LEN:
{
u16 *pu2Tmp;
- pu2Tmp = (u16 *)pOut;
+ pu2Tmp = pOut;
if (efuseType == EFUSE_WIFI)
*pu2Tmp = EFUSE_MAX_MAP_LEN;
@@ -703,7 +703,7 @@ static void Hal_GetEfuseDefinition(
case TYPE_EFUSE_PROTECT_BYTES_BANK:
{
u8 *pu1Tmp;
- pu1Tmp = (u8 *)pOut;
+ pu1Tmp = pOut;
if (efuseType == EFUSE_WIFI)
*pu1Tmp = EFUSE_OOB_PROTECT_BYTES;
@@ -715,7 +715,7 @@ static void Hal_GetEfuseDefinition(
case TYPE_EFUSE_CONTENT_LEN_BANK:
{
u16 *pu2Tmp;
- pu2Tmp = (u16 *)pOut;
+ pu2Tmp = pOut;
if (efuseType == EFUSE_WIFI)
*pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723B;
@@ -727,7 +727,7 @@ static void Hal_GetEfuseDefinition(
default:
{
u8 *pu1Tmp;
- pu1Tmp = (u8 *)pOut;
+ pu1Tmp = pOut;
*pu1Tmp = 0;
}
break;
diff --git a/drivers/staging/rtl8723bs/hal/rtl8723b_rxdesc.c b/drivers/staging/rtl8723bs/hal/rtl8723b_rxdesc.c
index 92e5a0e..14bfbe3 100644
--- a/drivers/staging/rtl8723bs/hal/rtl8723b_rxdesc.c
+++ b/drivers/staging/rtl8723bs/hal/rtl8723b_rxdesc.c
@@ -64,7 +64,7 @@ static void process_link_qual(struct adapter *padapter, union recv_frame *prfram
void rtl8723b_process_phy_info(struct adapter *padapter, void *prframe)
{
- union recv_frame *precvframe = (union recv_frame *)prframe;
+ union recv_frame *precvframe = prframe;
/* */
/* Check RSSI */
/* */
diff --git a/drivers/staging/rtl8723bs/hal/rtl8723bs_recv.c b/drivers/staging/rtl8723bs/hal/rtl8723bs_recv.c
index b002eb4..d9a4567 100644
--- a/drivers/staging/rtl8723bs/hal/rtl8723bs_recv.c
+++ b/drivers/staging/rtl8723bs/hal/rtl8723bs_recv.c
@@ -190,7 +190,7 @@ static void rtl8723bs_recv_tasklet(void *priv)
u8 shift_sz = 0, rx_report_sz = 0;
- padapter = (struct adapter *)priv;
+ padapter = priv;
pHalData = GET_HAL_DATA(padapter);
precvpriv = &padapter->recvpriv;
diff --git a/drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c b/drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c
index 9bee2e4..d0b3170 100644
--- a/drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c
+++ b/drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c
@@ -490,7 +490,7 @@ int rtl8723bs_xmit_thread(void *context)
ret = _SUCCESS;
- padapter = (struct adapter *)context;
+ padapter = context;
pxmitpriv = &padapter->xmitpriv;
rtw_sprintf(thread_name, 20, "%s-"ADPT_FMT, thread_name, ADPT_ARG(padapter));
diff --git a/drivers/staging/rtl8723bs/hal/sdio_ops.c b/drivers/staging/rtl8723bs/hal/sdio_ops.c
index 6285b72..1d1b14d 100644
--- a/drivers/staging/rtl8723bs/hal/sdio_ops.c
+++ b/drivers/staging/rtl8723bs/hal/sdio_ops.c
@@ -1121,7 +1121,7 @@ void sd_int_dpc(struct adapter *padapter)
}
} else {
/* Error handling for malloc fail */
- if (rtw_cbuf_push(padapter->evtpriv.c2h_queue, (void *)NULL) != _SUCCESS)
+ if (rtw_cbuf_push(padapter->evtpriv.c2h_queue, NULL) != _SUCCESS)
DBG_871X("%s rtw_cbuf_push fail\n", __func__);
_set_workitem(&padapter->evtpriv.c2h_wk);
}
diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
index 79d8383..d5e5f83 100644
--- a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
+++ b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
@@ -19,7 +19,7 @@
#include <rtw_mp.h>
#include <linux/jiffies.h>
-#define RTL_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
+#define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV+30)
#define SCAN_ITEM_SIZE 768
#define MAX_CUSTOM_LEN 64
@@ -44,8 +44,7 @@ extern u8 key_2char2num(u8 hch, u8 lch);
static u32 rtw_rates[] = {1000000, 2000000, 5500000, 11000000,
6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000};
-static const char * const iw_operation_mode[] =
-{
+static const char * const iw_operation_mode[] = {
"Auto", "Ad-Hoc", "Managed", "Master", "Repeater", "Secondary", "Monitor"
};
@@ -190,16 +189,12 @@ static char *translate_scan(struct adapter *padapter,
start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid);
/* parsing HT_CAP_IE */
- if (pnetwork->network.Reserved[0] == 2) /* Probe Request */
- {
+ if (pnetwork->network.Reserved[0] == 2) { /* Probe Request */
p = rtw_get_ie(&pnetwork->network.IEs[0], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength);
- }
- else
- {
+ } else {
p = rtw_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength-12);
}
- if (p && ht_ielen>0)
- {
+ if (p && ht_ielen>0) {
struct rtw_ieee80211_ht_cap *pht_capie;
ht_cap = true;
pht_capie = (struct rtw_ieee80211_ht_cap *)(p+2);
@@ -210,33 +205,25 @@ static char *translate_scan(struct adapter *padapter,
/* Add the protocol name */
iwe.cmd = SIOCGIWNAME;
- if ((rtw_is_cckratesonly_included((u8 *)&pnetwork->network.SupportedRates)) == true)
- {
+ if ((rtw_is_cckratesonly_included((u8 *)&pnetwork->network.SupportedRates)) == true) {
if (ht_cap == true)
snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
else
snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
- }
- else if ((rtw_is_cckrates_included((u8 *)&pnetwork->network.SupportedRates)) == true)
- {
+ } else if ((rtw_is_cckrates_included((u8 *)&pnetwork->network.SupportedRates)) == true) {
if (ht_cap == true)
snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
else
snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
- }
- else
- {
- if (pnetwork->network.Configuration.DSConfig > 14)
- {
+ } else {
+ if (pnetwork->network.Configuration.DSConfig > 14) {
if (vht_cap == true)
snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11AC");
else if (ht_cap == true)
snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11an");
else
snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11a");
- }
- else
- {
+ } else {
if (ht_cap == true)
snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
else
@@ -247,12 +234,9 @@ static char *translate_scan(struct adapter *padapter,
start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
/* Add mode */
- if (pnetwork->network.Reserved[0] == 2) /* Probe Request */
- {
+ if (pnetwork->network.Reserved[0] == 2) { /* Probe Request */
cap = 0;
- }
- else
- {
+ } else {
__le16 le_tmp;
iwe.cmd = SIOCGIWMODE;
@@ -295,8 +279,7 @@ static char *translate_scan(struct adapter *padapter,
return start;
p = custom;
p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
- while (pnetwork->network.SupportedRates[i]!= 0)
- {
+ while (pnetwork->network.SupportedRates[i]!= 0) {
rate = pnetwork->network.SupportedRates[i]&0x7F;
if (rate > max_rate)
max_rate = rate;
@@ -307,20 +290,12 @@ static char *translate_scan(struct adapter *padapter,
if (vht_cap == true) {
max_rate = vht_data_rate;
- }
- else if (ht_cap == true)
- {
- if (mcs_rate&0x8000)/* MCS15 */
- {
+ } else if (ht_cap == true) {
+ if (mcs_rate&0x8000) { /* MCS15 */
max_rate = (bw_40MHz) ? ((short_GI)?300:270):((short_GI)?144:130);
-
- }
- else if (mcs_rate&0x0080)/* MCS7 */
- {
+ } else if (mcs_rate&0x0080) { /* MCS7 */
max_rate = (bw_40MHz) ? ((short_GI)?150:135):((short_GI)?72:65);
- }
- else/* default MCS7 */
- {
+ } else { /* default MCS7 */
/* DBG_871X("wx_get_scan, mcs_rate_bitmap = 0x%x\n", mcs_rate); */
max_rate = (bw_40MHz) ? ((short_GI)?150:135):((short_GI)?72:65);
}
@@ -334,8 +309,7 @@ static char *translate_scan(struct adapter *padapter,
start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN);
/* parsing WPA/WPA2 IE */
- if (pnetwork->network.Reserved[0] != 2) /* Probe Request */
- {
+ if (pnetwork->network.Reserved[0] != 2) { /* Probe Request */
u8 *buf;
u8 wpa_ie[255], rsn_ie[255];
u16 wpa_len = 0, rsn_len = 0;
@@ -351,15 +325,13 @@ static char *translate_scan(struct adapter *padapter,
if (wpa_len > 0) {
p =buf;
p += sprintf(p, "wpa_ie =");
- for (i = 0; i < wpa_len; i++) {
+ for (i = 0; i < wpa_len; i++)
p += sprintf(p, "%02x", wpa_ie[i]);
- }
if (wpa_len > 100) {
printk("-----------------Len %d----------------\n", wpa_len);
- for (i = 0; i < wpa_len; i++) {
+ for (i = 0; i < wpa_len; i++)
printk("%02x ", wpa_ie[i]);
- }
printk("\n");
printk("-----------------Len %d----------------\n", wpa_len);
}
@@ -401,21 +373,16 @@ static char *translate_scan(struct adapter *padapter,
u8 *ie_ptr = pnetwork->network.IEs + ie_offset;
total_ielen = pnetwork->network.IELength - ie_offset;
- if (pnetwork->network.Reserved[0] == 2) /* Probe Request */
- {
+ if (pnetwork->network.Reserved[0] == 2) { /* Probe Request */
ie_ptr = pnetwork->network.IEs;
total_ielen = pnetwork->network.IELength;
- }
- else /* Beacon or Probe Respones */
- {
+ } else { /* Beacon or Probe Respones */
ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_;
total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_;
}
- while (cnt < total_ielen)
- {
- if (rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen>2))
- {
+ while (cnt < total_ielen) {
+ if (rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen>2)) {
wpsie_ptr = &ie_ptr[cnt];
iwe.cmd =IWEVGENIE;
iwe.u.data.length = (u16)wps_ielen;
@@ -507,38 +474,27 @@ static int wpa_set_auth_algs(struct net_device *dev, u32 value)
struct adapter *padapter = (struct adapter *) rtw_netdev_priv(dev);
int ret = 0;
- if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM))
- {
+ if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
DBG_871X("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY and AUTH_ALG_OPEN_SYSTEM [value:0x%x]\n", value);
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
- }
- else if (value & AUTH_ALG_SHARED_KEY)
- {
+ } else if (value & AUTH_ALG_SHARED_KEY) {
DBG_871X("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY [value:0x%x]\n", value);
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
- }
- else if (value & AUTH_ALG_OPEN_SYSTEM)
- {
+ } else if (value & AUTH_ALG_OPEN_SYSTEM) {
DBG_871X("wpa_set_auth_algs, AUTH_ALG_OPEN_SYSTEM\n");
/* padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; */
- if (padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK)
- {
+ if (padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK) {
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
}
-
- }
- else if (value & AUTH_ALG_LEAP)
- {
+ } else if (value & AUTH_ALG_LEAP) {
DBG_871X("wpa_set_auth_algs, AUTH_ALG_LEAP\n");
- }
- else
- {
+ } else {
DBG_871X("wpa_set_auth_algs, error!\n");
ret = -EINVAL;
}
@@ -559,33 +515,27 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
param->u.crypt.err = 0;
param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
- if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
- {
+ if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) {
ret = -EINVAL;
goto exit;
}
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
- param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
- {
-
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
if (param->u.crypt.idx >= WEP_KEYS ||
param->u.crypt.idx >= BIP_MAX_KEYID) {
ret = -EINVAL;
goto exit;
}
- }
- else
- {
+ } else {
{
ret = -EINVAL;
goto exit;
}
}
- if (strcmp(param->u.crypt.alg, "WEP") == 0)
- {
+ if (strcmp(param->u.crypt.alg, "WEP") == 0) {
RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("wpa_set_encryption, crypt.alg = WEP\n"));
DBG_871X("wpa_set_encryption, crypt.alg = WEP\n");
@@ -604,8 +554,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("(2)wep_key_idx =%d\n", wep_key_idx));
- if (wep_key_len > 0)
- {
+ if (wep_key_len > 0) {
wep_key_len = wep_key_len <= 5 ? 5 : 13;
wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
pwep =(struct ndis_802_11_wep *) rtw_malloc(wep_total_len);
@@ -619,13 +568,11 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
pwep->KeyLength = wep_key_len;
pwep->Length = wep_total_len;
- if (wep_key_len == 13)
- {
+ if (wep_key_len == 13) {
padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
}
- }
- else {
+ } else {
ret = -EINVAL;
goto exit;
}
@@ -635,17 +582,12 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
- if (param->u.crypt.set_tx)
- {
+ if (param->u.crypt.set_tx) {
DBG_871X("wep, set_tx = 1\n");
if (rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
- {
ret = -EOPNOTSUPP ;
- }
- }
- else
- {
+ } else {
DBG_871X("wep, set_tx = 0\n");
/* don't update "psecuritypriv->dot11PrivacyAlgrthm" and */
@@ -664,35 +606,28 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
goto exit;
}
- if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) /* 802_1x */
- {
+ if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { /* 802_1x */
struct sta_info * psta,*pbcmc_sta;
struct sta_priv * pstapriv = &padapter->stapriv;
- if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == true) /* sta mode */
- {
+ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == true) { /* sta mode */
psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
if (psta == NULL) {
/* DEBUG_ERR(("Set wpa_set_encryption: Obtain Sta_info fail\n")); */
- }
- else
- {
+ } else {
/* Jeff: don't disable ieee8021x_blocked while clearing key */
if (strcmp(param->u.crypt.alg, "none") != 0)
psta->ieee8021x_blocked = false;
if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
- (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
- {
+ (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) {
psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
}
- if (param->u.crypt.set_tx == 1)/* pairwise key */
- {
+ if (param->u.crypt.set_tx == 1) { /* pairwise key */
memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
- if (strcmp(param->u.crypt.alg, "TKIP") == 0)/* set mic key */
- {
+ if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
/* DEBUG_ERR(("\nset key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len)); */
memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
@@ -705,15 +640,11 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
DBG_871X(" ~~~~set sta key:unicastkey\n");
rtw_setstakey_cmd(padapter, psta, true, true);
- }
- else/* group key */
- {
- if (strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0)
- {
+ } else { /* group key */
+ if (strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0) {
memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
/* only TKIP group key need to install this */
- if (param->u.crypt.key_len > 16)
- {
+ if (param->u.crypt.key_len > 16) {
memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[16]), 8);
memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[24]), 8);
}
@@ -724,9 +655,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
rtw_set_key(padapter,&padapter->securitypriv, param->u.crypt.idx, 1, true);
- }
- else if (strcmp(param->u.crypt.alg, "BIP") == 0)
- {
+ } else if (strcmp(param->u.crypt.alg, "BIP") == 0) {
/* printk("BIP key_len =%d , index =%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx); */
/* save the IGTK key, length 16 bytes */
memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
@@ -742,25 +671,20 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
}
pbcmc_sta =rtw_get_bcmc_stainfo(padapter);
- if (pbcmc_sta == NULL)
- {
+ if (pbcmc_sta == NULL) {
/* DEBUG_ERR(("Set OID_802_11_ADD_KEY: bcmc stainfo is null\n")); */
- }
- else
- {
+ } else {
/* Jeff: don't disable ieee8021x_blocked while clearing key */
if (strcmp(param->u.crypt.alg, "none") != 0)
pbcmc_sta->ieee8021x_blocked = false;
if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
- (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
- {
+ (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) {
pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
}
}
- }
- else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) /* adhoc mode */
- {
+ } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
+ /* adhoc mode */
}
}
@@ -785,8 +709,7 @@ static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ie
return -EINVAL;
}
- if (ielen)
- {
+ if (ielen) {
buf = rtw_zmalloc(ielen);
if (buf == NULL) {
ret = -ENOMEM;
@@ -810,31 +733,24 @@ static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ie
goto exit;
}
- if (rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
- {
+ if (rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
padapter->securitypriv.ndisauthtype =Ndis802_11AuthModeWPAPSK;
memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
}
- if (rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
- {
+ if (rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
padapter->securitypriv.ndisauthtype =Ndis802_11AuthModeWPA2PSK;
memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
}
if (group_cipher == 0)
- {
group_cipher = WPA_CIPHER_NONE;
- }
if (pairwise_cipher == 0)
- {
pairwise_cipher = WPA_CIPHER_NONE;
- }
- switch (group_cipher)
- {
+ switch (group_cipher) {
case WPA_CIPHER_NONE:
padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
padapter->securitypriv.ndisencryptstatus =Ndis802_11EncryptionDisabled;
@@ -857,8 +773,7 @@ static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ie
break;
}
- switch (pairwise_cipher)
- {
+ switch (pairwise_cipher) {
case WPA_CIPHER_NONE:
padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
padapter->securitypriv.ndisencryptstatus =Ndis802_11EncryptionDisabled;
@@ -886,12 +801,10 @@ static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ie
u16 cnt = 0;
u8 eid, wps_oui[4]={0x0, 0x50, 0xf2, 0x04};
- while (cnt < ielen)
- {
+ while (cnt < ielen) {
eid = buf[cnt];
- if ((eid == _VENDOR_SPECIFIC_IE_) && (!memcmp(&buf[cnt+2], wps_oui, 4)))
- {
+ if ((eid == _VENDOR_SPECIFIC_IE_) && (!memcmp(&buf[cnt+2], wps_oui, 4))) {
DBG_871X("SET WPS_IE\n");
padapter->securitypriv.wps_ie_len = ((buf[cnt+1]+2) < MAX_WPS_IE_LEN) ? (buf[cnt+1]+2):MAX_WPS_IE_LEN;
@@ -947,48 +860,36 @@ static int rtw_wx_get_name(struct net_device *dev,
/* parsing HT_CAP_IE */
p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength-12);
if (p && ht_ielen>0)
- {
ht_cap = true;
- }
prates = &pcur_bss->SupportedRates;
- if (rtw_is_cckratesonly_included((u8 *)prates) == true)
- {
+ if (rtw_is_cckratesonly_included((u8 *)prates) == true) {
if (ht_cap == true)
snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bn");
else
snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");
- }
- else if ((rtw_is_cckrates_included((u8 *)prates)) == true)
- {
+ } else if ((rtw_is_cckrates_included((u8 *)prates)) == true) {
if (ht_cap == true)
snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bgn");
else
snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg");
- }
- else
- {
- if (pcur_bss->Configuration.DSConfig > 14)
- {
+ } else {
+ if (pcur_bss->Configuration.DSConfig > 14) {
if (vht_cap == true)
snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11AC");
else if (ht_cap == true)
snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11an");
else
snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11a");
- }
- else
- {
+ } else {
if (ht_cap == true)
snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn");
else
snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g");
}
}
- }
- else
- {
+ } else {
/* prates = &padapter->registrypriv.dev_network.SupportedRates; */
/* snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g"); */
snprintf(wrqu->name, IFNAMSIZ, "unassociated");
@@ -1013,15 +914,13 @@ static int rtw_wx_get_freq(struct net_device *dev,
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
- if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
- {
+ if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
/* wrqu->freq.m = ieee80211_wlan_frequencies[pcur_bss->Configuration.DSConfig-1] * 100000; */
wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000;
wrqu->freq.e = 1;
wrqu->freq.i = pcur_bss->Configuration.DSConfig;
- }
- else {
+ } else {
wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000;
wrqu->freq.e = 1;
wrqu->freq.i = padapter->mlmeextpriv.cur_channel;
@@ -1047,8 +946,7 @@ static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
goto exit;
}
- switch (wrqu->mode)
- {
+ switch (wrqu->mode) {
case IW_MODE_AUTO:
networkType = Ndis802_11AutoUnknown;
DBG_871X("set_mode = IW_MODE_AUTO\n");
@@ -1105,22 +1003,14 @@ static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, (" rtw_wx_get_mode\n"));
- if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
- {
+ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) {
wrqu->mode = IW_MODE_INFRA;
- }
- else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) ||
- (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true))
-
- {
+ } else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) ||
+ (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)) {
wrqu->mode = IW_MODE_ADHOC;
- }
- else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
- {
+ } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) {
wrqu->mode = IW_MODE_MASTER;
- }
- else
- {
+ } else {
wrqu->mode = IW_MODE_AUTO;
}
return 0;
@@ -1147,25 +1037,19 @@ static int rtw_wx_set_pmkid(struct net_device *dev,
*/
memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
- if (pPMK->cmd == IW_PMKSA_ADD)
- {
+ if (pPMK->cmd == IW_PMKSA_ADD) {
DBG_871X("[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n");
if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
- {
return(intReturn);
- }
else
- {
intReturn = true;
- }
+
blInserted = false;
/* overwrite PMKID */
- for (j = 0 ; j<NUM_PMKID_CACHE; j++)
- {
- if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN))
- { /* BSSID is matched, the same AP => rewrite with new PMKID. */
-
+ for (j = 0 ; j<NUM_PMKID_CACHE; j++) {
+ if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) {
+ /* BSSID is matched, the same AP => rewrite with new PMKID. */
DBG_871X("[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n");
memcpy(psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN);
@@ -1176,8 +1060,7 @@ static int rtw_wx_set_pmkid(struct net_device *dev,
}
}
- if (!blInserted)
- {
+ if (!blInserted) {
/* Find a new entry */
DBG_871X("[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n",
psecuritypriv->PMKIDIndex);
@@ -1188,27 +1071,20 @@ static int rtw_wx_set_pmkid(struct net_device *dev,
psecuritypriv->PMKIDList[ psecuritypriv->PMKIDIndex ].bUsed = true;
psecuritypriv->PMKIDIndex++ ;
if (psecuritypriv->PMKIDIndex == 16)
- {
psecuritypriv->PMKIDIndex = 0;
- }
}
- }
- else if (pPMK->cmd == IW_PMKSA_REMOVE)
- {
+ } else if (pPMK->cmd == IW_PMKSA_REMOVE) {
DBG_871X("[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n");
intReturn = true;
- for (j = 0 ; j<NUM_PMKID_CACHE; j++)
- {
- if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN))
- { /* BSSID is matched, the same AP => Remove this PMKID information and reset it. */
+ for (j = 0 ; j<NUM_PMKID_CACHE; j++) {
+ if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) {
+ /* BSSID is matched, the same AP => Remove this PMKID information and reset it. */
memset(psecuritypriv->PMKIDList[ j ].Bssid, 0x00, ETH_ALEN);
psecuritypriv->PMKIDList[ j ].bUsed = false;
break;
}
}
- }
- else if (pPMK->cmd == IW_PMKSA_FLUSH)
- {
+ } else if (pPMK->cmd == IW_PMKSA_FLUSH) {
DBG_871X("[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n");
memset(&psecuritypriv->PMKIDList[ 0 ], 0x00, sizeof(RT_PMKID_LIST) * NUM_PMKID_CACHE);
psecuritypriv->PMKIDIndex = 0;
@@ -1273,9 +1149,8 @@ static int rtw_wx_get_range(struct net_device *dev,
range->num_bitrates = RATE_COUNT;
- for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
+ for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
range->bitrate[i] = rtw_rates[i];
- }
range->min_frag = MIN_FRAG_THRESHOLD;
range->max_frag = MAX_FRAG_THRESHOLD;
@@ -1288,8 +1163,7 @@ static int rtw_wx_get_range(struct net_device *dev,
for (i = 0, val = 0; i < MAX_CHANNEL_NUM; i++) {
/* Include only legal frequencies for some countries */
- if (pmlmeext->channel_set[i].ChannelNum != 0)
- {
+ if (pmlmeext->channel_set[i].ChannelNum != 0) {
range->freq[val].i = pmlmeext->channel_set[i].ChannelNum;
range->freq[val].m = rtw_ch2freq(pmlmeext->channel_set[i].ChannelNum) * 100000;
range->freq[val].e = 1;
@@ -1349,8 +1223,7 @@ static int rtw_wx_set_wap(struct net_device *dev,
enum NDIS_802_11_AUTHENTICATION_MODE authmode;
rtw_ps_deny(padapter, PS_DENY_JOIN);
- if (_FAIL == rtw_pwr_wakeup(padapter))
- {
+ if (_FAIL == rtw_pwr_wakeup(padapter)) {
ret = -1;
goto exit;
}
@@ -1383,15 +1256,12 @@ static int rtw_wx_set_wap(struct net_device *dev,
src_bssid = temp->sa_data;
- if ((!memcmp(dst_bssid, src_bssid, ETH_ALEN)))
- {
- if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode))
- {
+ if ((!memcmp(dst_bssid, src_bssid, ETH_ALEN))) {
+ if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) {
ret = -1;
spin_unlock_bh(&queue->lock);
goto exit;
}
-
break;
}
@@ -1429,13 +1299,9 @@ static int rtw_wx_get_wap(struct net_device *dev,
if (((check_fwstate(pmlmepriv, _FW_LINKED)) == true) ||
((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == true) ||
- ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) == true))
- {
-
+ ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) == true)) {
memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
- }
- else
- {
+ } else {
memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
}
@@ -1461,8 +1327,7 @@ static int rtw_wx_set_mlme(struct net_device *dev,
DBG_871X("%s, cmd =%d, reason =%d\n", __func__, mlme->cmd, reason);
- switch (mlme->cmd)
- {
+ switch (mlme->cmd) {
case IW_MLME_DEAUTH:
if (!rtw_set_802_11_disassociate(padapter))
ret = -1;
@@ -1493,8 +1358,7 @@ static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
#endif
rtw_ps_deny(padapter, PS_DENY_SCAN);
- if (_FAIL == rtw_pwr_wakeup(padapter))
- {
+ if (_FAIL == rtw_pwr_wakeup(padapter)) {
ret = -1;
goto exit;
}
@@ -1518,26 +1382,22 @@ static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
/* When Busy Traffic, driver do not site survey. So driver return success. */
/* wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout. */
/* modify by thomas 2011-02-22. */
- if (pmlmepriv->LinkDetectInfo.bBusyTraffic == true)
- {
+ if (pmlmepriv->LinkDetectInfo.bBusyTraffic == true) {
indicate_wx_scan_complete_event(padapter);
goto exit;
}
- if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == true)
- {
+ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == true) {
indicate_wx_scan_complete_event(padapter);
goto exit;
}
memset(ssid, 0, sizeof(struct ndis_802_11_ssid)*RTW_SSID_SCAN_AMOUNT);
- if (wrqu->data.length == sizeof(struct iw_scan_req))
- {
+ if (wrqu->data.length == sizeof(struct iw_scan_req)) {
struct iw_scan_req *req = (struct iw_scan_req *)extra;
- if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
- {
+ if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE);
memcpy(ssid[0].Ssid, req->essid, len);
@@ -1551,17 +1411,12 @@ static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
spin_unlock_bh(&pmlmepriv->lock);
- }
- else if (req->scan_type == IW_SCAN_TYPE_PASSIVE)
- {
+ } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) {
DBG_871X("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n");
}
- }
- else if (wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE
- && !memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)
- )
- {
+ } else if (wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE
+ && !memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) {
int len = wrqu->data.length -WEXT_CSCAN_HEADER_SIZE;
char *pos = extra+WEXT_CSCAN_HEADER_SIZE;
char section;
@@ -1626,9 +1481,7 @@ static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
/* jeff: it has still some scan paramater to parse, we only do this now... */
_status = rtw_set_802_11_bssid_list_scan(padapter, ssid, RTW_SSID_SCAN_AMOUNT);
- } else
-
- {
+ } else {
_status = rtw_set_802_11_bssid_list_scan(padapter, NULL, 0);
}
@@ -1666,8 +1519,7 @@ static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
DBG_871X("DBG_IOCTL %s:%d\n", __func__, __LINE__);
#endif
- if (adapter_to_pwrctl(padapter)->brfoffbyhw && padapter->bDriverStopped)
- {
+ if (adapter_to_pwrctl(padapter)->brfoffbyhw && padapter->bDriverStopped) {
ret = -EINVAL;
goto exit;
}
@@ -1682,8 +1534,7 @@ static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
phead = get_list_head(queue);
plist = get_next(phead);
- while (1)
- {
+ while (1) {
if (phead == plist)
break;
@@ -1697,9 +1548,8 @@ static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
/* report network only if the current channel set contains the channel to which this network belongs */
if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
&& rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == true
- && true == rtw_validate_ssid(&(pnetwork->network.Ssid))
- )
- {
+ && true == rtw_validate_ssid(&(pnetwork->network.Ssid))) {
+
ev =translate_scan(padapter, a, pnetwork, ev, stop);
}
@@ -1750,8 +1600,7 @@ static int rtw_wx_set_essid(struct net_device *dev,
("+rtw_wx_set_essid: fw_state = 0x%08x\n", get_fwstate(pmlmepriv)));
rtw_ps_deny(padapter, PS_DENY_JOIN);
- if (_FAIL == rtw_pwr_wakeup(padapter))
- {
+ if (_FAIL == rtw_pwr_wakeup(padapter)) {
ret = -1;
goto exit;
}
@@ -1773,8 +1622,7 @@ static int rtw_wx_set_essid(struct net_device *dev,
authmode = padapter->securitypriv.ndisauthtype;
DBG_871X("=>%s\n", __func__);
- if (wrqu->essid.flags && wrqu->essid.length)
- {
+ if (wrqu->essid.flags && wrqu->essid.length) {
len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE;
if (wrqu->essid.length != 33)
@@ -1791,8 +1639,7 @@ static int rtw_wx_set_essid(struct net_device *dev,
pmlmepriv->pscanned = get_next(phead);
while (1) {
- if (phead == pmlmepriv->pscanned)
- {
+ if (phead == pmlmepriv->pscanned) {
RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_warning_,
("rtw_wx_set_essid: scan_q is empty, set ssid to check if scanning again!\n"));
@@ -1810,19 +1657,16 @@ static int rtw_wx_set_essid(struct net_device *dev,
pnetwork->network.Ssid.Ssid));
if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength)) &&
- (pnetwork->network.Ssid.SsidLength ==ndis_ssid.SsidLength))
- {
+ (pnetwork->network.Ssid.SsidLength ==ndis_ssid.SsidLength)) {
RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
("rtw_wx_set_essid: find match, set infra mode\n"));
- if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)
- {
+ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) {
if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
continue;
}
- if (rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode) == false)
- {
+ if (rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode) == false) {
ret = -1;
spin_unlock_bh(&queue->lock);
goto exit;
@@ -1867,8 +1711,7 @@ static int rtw_wx_get_essid(struct net_device *dev,
RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_essid\n"));
if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) ||
- (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true))
- {
+ (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) {
len = pcur_bss->Ssid.SsidLength;
wrqu->essid.length = len;
@@ -1876,9 +1719,7 @@ static int rtw_wx_get_essid(struct net_device *dev,
memcpy(extra, pcur_bss->Ssid.Ssid, len);
wrqu->essid.flags = 1;
- }
- else
- {
+ } else {
ret = -1;
goto exit;
}
@@ -1952,15 +1793,12 @@ static int rtw_wx_set_rate(struct net_device *dev,
set_rate:
- for (i = 0; i<NumRates; i++)
- {
- if (ratevalue ==mpdatarate[i])
- {
+ for (i = 0; i<NumRates; i++) {
+ if (ratevalue ==mpdatarate[i]) {
datarates[i] = mpdatarate[i];
if (fixed == 0)
break;
- }
- else {
+ } else {
datarates[i] = 0xff;
}
@@ -2097,8 +1935,7 @@ static int rtw_wx_set_enc(struct net_device *dev,
key = erq->flags & IW_ENCODE_INDEX;
- if (erq->flags & IW_ENCODE_DISABLED)
- {
+ if (erq->flags & IW_ENCODE_DISABLED) {
DBG_871X("EncryptionDisabled\n");
padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
@@ -2115,17 +1952,14 @@ static int rtw_wx_set_enc(struct net_device *dev,
return -EINVAL;
key--;
keyindex_provided = 1;
- }
- else
- {
+ } else {
keyindex_provided = 0;
key = padapter->securitypriv.dot11PrivacyKeyIndex;
DBG_871X("rtw_wx_set_enc, key =%d\n", key);
}
/* set authentication mode */
- if (erq->flags & IW_ENCODE_OPEN)
- {
+ if (erq->flags & IW_ENCODE_OPEN) {
DBG_871X("rtw_wx_set_enc():IW_ENCODE_OPEN\n");
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */
@@ -2135,9 +1969,7 @@ static int rtw_wx_set_enc(struct net_device *dev,
padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
authmode = Ndis802_11AuthModeOpen;
padapter->securitypriv.ndisauthtype =authmode;
- }
- else if (erq->flags & IW_ENCODE_RESTRICTED)
- {
+ } else if (erq->flags & IW_ENCODE_RESTRICTED) {
DBG_871X("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n");
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
@@ -2147,9 +1979,7 @@ static int rtw_wx_set_enc(struct net_device *dev,
padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
authmode = Ndis802_11AuthModeShared;
padapter->securitypriv.ndisauthtype =authmode;
- }
- else
- {
+ } else {
DBG_871X("rtw_wx_set_enc():erq->flags = 0x%x\n", erq->flags);
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */
@@ -2161,24 +1991,19 @@ static int rtw_wx_set_enc(struct net_device *dev,
}
wep.KeyIndex = key;
- if (erq->length > 0)
- {
+ if (erq->length > 0) {
wep.KeyLength = erq->length <= 5 ? 5 : 13;
wep.Length = wep.KeyLength + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
- }
- else
- {
+ } else {
wep.KeyLength = 0 ;
- if (keyindex_provided == 1)/* set key_id only, no given KeyMaterial(erq->length == 0). */
- {
+ if (keyindex_provided == 1) { /* set key_id only, no given KeyMaterial(erq->length == 0). */
padapter->securitypriv.dot11PrivacyKeyIndex = key;
DBG_871X("(keyindex_provided == 1), keyid =%d, key_len =%d\n", key, padapter->securitypriv.dot11DefKeylen[key]);
- switch (padapter->securitypriv.dot11DefKeylen[key])
- {
+ switch (padapter->securitypriv.dot11DefKeylen[key]) {
case 5:
padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
break;
@@ -2219,14 +2044,12 @@ static int rtw_wx_get_enc(struct net_device *dev,
struct iw_point *erq = &(wrqu->encoding);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- if (check_fwstate(pmlmepriv, _FW_LINKED) != true)
- {
- if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != true)
- {
- erq->length = 0;
- erq->flags |= IW_ENCODE_DISABLED;
- return 0;
- }
+ if (check_fwstate(pmlmepriv, _FW_LINKED) != true) {
+ if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != true) {
+ erq->length = 0;
+ erq->flags |= IW_ENCODE_DISABLED;
+ return 0;
+ }
}
@@ -2236,8 +2059,7 @@ static int rtw_wx_get_enc(struct net_device *dev,
if (key > WEP_KEYS)
return -EINVAL;
key--;
- } else
- {
+ } else {
key = padapter->securitypriv.dot11PrivacyKeyIndex;
}
@@ -2248,8 +2070,7 @@ static int rtw_wx_get_enc(struct net_device *dev,
/* erq->flags |= IW_ENCODE_OPEN; */
/* */
- switch (padapter->securitypriv.ndisencryptstatus)
- {
+ switch (padapter->securitypriv.ndisencryptstatus) {
case Ndis802_11EncryptionNotSupported:
case Ndis802_11EncryptionDisabled:
erq->length = 0;
@@ -2258,23 +2079,16 @@ static int rtw_wx_get_enc(struct net_device *dev,
case Ndis802_11Encryption1Enabled:
erq->length = padapter->securitypriv.dot11DefKeylen[key];
- if (erq->length)
- {
+ if (erq->length) {
memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]);
erq->flags |= IW_ENCODE_ENABLED;
if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen)
- {
erq->flags |= IW_ENCODE_OPEN;
- }
else if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared)
- {
- erq->flags |= IW_ENCODE_RESTRICTED;
- }
- }
- else
- {
+ erq->flags |= IW_ENCODE_RESTRICTED;
+ } else {
erq->length = 0;
erq->flags |= IW_ENCODE_DISABLED;
}
@@ -2343,14 +2157,13 @@ static int rtw_wx_set_auth(struct net_device *dev,
case IW_AUTH_TKIP_COUNTERMEASURES:
{
- if (param->value)
- { /* wpa_supplicant is enabling the tkip countermeasure. */
- padapter->securitypriv.btkip_countermeasure = true;
- }
- else
- { /* wpa_supplicant is disabling the tkip countermeasure. */
- padapter->securitypriv.btkip_countermeasure = false;
- }
+ if (param->value) {
+ /* wpa_supplicant is enabling the tkip countermeasure. */
+ padapter->securitypriv.btkip_countermeasure = true;
+ } else {
+ /* wpa_supplicant is disabling the tkip countermeasure. */
+ padapter->securitypriv.btkip_countermeasure = false;
+ }
break;
}
case IW_AUTH_DROP_UNENCRYPTED:
@@ -2367,8 +2180,7 @@ static int rtw_wx_set_auth(struct net_device *dev,
* be set.
*/
- if (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled)
- {
+ if (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled) {
break;/* it means init value, or using wep, ndisencryptstatus = Ndis802_11Encryption1Enabled, */
/* then it needn't reset it; */
}
@@ -2462,37 +2274,29 @@ static int rtw_wx_set_enc_ext(struct net_device *dev,
strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
- {
param->u.crypt.set_tx = 1;
- }
/* cliW: WEP does not have group key
* just not checking GROUP key setting
*/
if ((pext->alg != IW_ENCODE_ALG_WEP) &&
((pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
- || (pext->ext_flags & IW_ENCODE_ALG_AES_CMAC)
- ))
- {
+ || (pext->ext_flags & IW_ENCODE_ALG_AES_CMAC))) {
param->u.crypt.set_tx = 0;
}
param->u.crypt.idx = (pencoding->flags&0x00FF) -1 ;
if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
- {
memcpy(param->u.crypt.seq, pext->rx_seq, 8);
- }
- if (pext->key_len)
- {
+ if (pext->key_len) {
param->u.crypt.key_len = pext->key_len;
/* memcpy(param + 1, pext + 1, pext->key_len); */
memcpy(param->u.crypt.key, pext + 1, pext->key_len);
}
- if (pencoding->flags & IW_ENCODE_DISABLED)
- {
+ if (pencoding->flags & IW_ENCODE_DISABLED) {
/* todo: remove key */
/* remove = 1; */
}
@@ -2514,8 +2318,7 @@ static int rtw_wx_get_nick(struct net_device *dev,
/* struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); */
/* struct security_priv *psecuritypriv = &padapter->securitypriv; */
- if (extra)
- {
+ if (extra) {
wrqu->data.length = 14;
wrqu->data.flags = 1;
memcpy(extra, "<WIFI@REALTEK>", 14);
@@ -2683,9 +2486,9 @@ static int rtw_wx_set_channel_plan(struct net_device *dev,
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
u8 channel_plan_req = (u8) (*((int *)wrqu));
- if (_SUCCESS == rtw_set_chplan_cmd(padapter, channel_plan_req, 1, 1)) {
+ if (_SUCCESS == rtw_set_chplan_cmd(padapter, channel_plan_req, 1, 1))
DBG_871X("%s set channel_plan = 0x%02X\n", __func__, channel_plan_req);
- } else
+ else
return -EPERM;
return 0;
@@ -2751,14 +2554,12 @@ static int rtw_get_ap_info(struct net_device *dev,
DBG_871X("+rtw_get_aplist_info\n");
- if ((padapter->bDriverStopped) || (pdata == NULL))
- {
+ if ((padapter->bDriverStopped) || (pdata == NULL)) {
ret = -EINVAL;
goto exit;
}
- while ((check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) == true)
- {
+ while ((check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) == true) {
msleep(30);
cnt++;
if (cnt > 100)
@@ -2768,16 +2569,12 @@ static int rtw_get_ap_info(struct net_device *dev,
/* pdata->length = 0;? */
pdata->flags = 0;
- if (pdata->length>=32)
- {
- if (copy_from_user(data, pdata->pointer, 32))
- {
+ if (pdata->length>=32) {
+ if (copy_from_user(data, pdata->pointer, 32)) {
ret = -EINVAL;
goto exit;
}
- }
- else
- {
+ } else {
ret = -EINVAL;
goto exit;
}
@@ -2787,8 +2584,7 @@ static int rtw_get_ap_info(struct net_device *dev,
phead = get_list_head(queue);
plist = get_next(phead);
- while (1)
- {
+ while (1) {
if (phead == plist)
break;
@@ -2796,32 +2592,27 @@ static int rtw_get_ap_info(struct net_device *dev,
pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
/* if (hwaddr_aton_i(pdata->pointer, bssid)) */
- if (hwaddr_aton_i(data, bssid))
- {
+ if (hwaddr_aton_i(data, bssid)) {
DBG_871X("Invalid BSSID '%s'.\n", (u8 *)data);
spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
return -EINVAL;
}
- if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN))/* BSSID match, then check if supporting wpa/wpa2 */
- {
+ if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN)) { /* BSSID match, then check if supporting wpa/wpa2 */
DBG_871X("BSSID:" MAC_FMT "\n", MAC_ARG(bssid));
pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12);
- if (pbuf && (wpa_ielen>0))
- {
+ if (pbuf && (wpa_ielen>0)) {
pdata->flags = 1;
break;
}
pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12);
- if (pbuf && (wpa_ielen>0))
- {
+ if (pbuf && (wpa_ielen>0)) {
pdata->flags = 2;
break;
}
-
}
plist = get_next(plist);
@@ -2830,10 +2621,8 @@ static int rtw_get_ap_info(struct net_device *dev,
spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
- if (pdata->length>=34)
- {
- if (copy_to_user((u8 __force __user *)pdata->pointer+32, (u8 *)&pdata->flags, 1))
- {
+ if (pdata->length>=34) {
+ if (copy_to_user((u8 __force __user *)pdata->pointer+32, (u8 *)&pdata->flags, 1)) {
ret = -EINVAL;
goto exit;
}
@@ -2855,8 +2644,7 @@ static int rtw_set_pid(struct net_device *dev,
int *pdata = (int *)wrqu;
int selector;
- if ((padapter->bDriverStopped) || (pdata == NULL))
- {
+ if ((padapter->bDriverStopped) || (pdata == NULL)) {
ret = -EINVAL;
goto exit;
}
@@ -2886,17 +2674,14 @@ static int rtw_wps_start(struct net_device *dev,
u32 u32wps_start = 0;
unsigned int uintRet = 0;
- if ((true == padapter->bDriverStopped) ||(true ==padapter->bSurpriseRemoved) || (NULL == pdata))
- {
+ if ((true == padapter->bDriverStopped) ||(true ==padapter->bSurpriseRemoved) || (NULL == pdata)) {
ret = -EINVAL;
goto exit;
}
uintRet = copy_from_user((void*) &u32wps_start, pdata->pointer, 4);
if (u32wps_start == 0)
- {
u32wps_start = *extra;
- }
DBG_871X("[%s] wps_start = %d\n", __func__, u32wps_start);
@@ -2964,18 +2749,15 @@ static int rtw_rereg_nd_name(struct net_device *dev,
if (wrqu->data.length > IFNAMSIZ)
return -EFAULT;
- if (copy_from_user(new_ifname, wrqu->data.pointer, IFNAMSIZ)) {
+ if (copy_from_user(new_ifname, wrqu->data.pointer, IFNAMSIZ))
return -EFAULT;
- }
- if (0 == strcmp(rereg_priv->old_ifname, new_ifname)) {
+ if (0 == strcmp(rereg_priv->old_ifname, new_ifname))
return ret;
- }
DBG_871X("%s new_ifname:%s\n", __func__, new_ifname);
- if (0 != (ret = rtw_change_ifname(padapter, new_ifname))) {
+ if (0 != (ret = rtw_change_ifname(padapter, new_ifname)))
goto exit;
- }
strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ);
rereg_priv->old_ifname[IFNAMSIZ-1] = 0;
@@ -3021,11 +2803,9 @@ static int rtw_dbg_port(struct net_device *dev,
extra_arg = *(pdata+1);
- switch (major_cmd)
- {
+ switch (major_cmd) {
case 0x70:/* read_reg */
- switch (minor_cmd)
- {
+ switch (minor_cmd) {
case 1:
DBG_871X("rtw_read8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg));
break;
@@ -3038,8 +2818,7 @@ static int rtw_dbg_port(struct net_device *dev,
}
break;
case 0x71:/* write_reg */
- switch (minor_cmd)
- {
+ switch (minor_cmd) {
case 1:
rtw_write8(padapter, arg, extra_arg);
DBG_871X("rtw_write8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg));
@@ -3070,8 +2849,7 @@ static int rtw_dbg_port(struct net_device *dev,
break;
case 0x76:
- switch (minor_cmd)
- {
+ switch (minor_cmd) {
case 0x00: /* normal mode, */
padapter->recvpriv.is_signal_dbg = 0;
break;
@@ -3108,8 +2886,7 @@ static int rtw_dbg_port(struct net_device *dev,
, WLAN_REASON_EXPIRATION_CHK);
break;
case 0x7F:
- switch (minor_cmd)
- {
+ switch (minor_cmd) {
case 0x0:
DBG_871X("fwstate = 0x%x\n", get_fwstate(pmlmepriv));
break;
@@ -3137,8 +2914,7 @@ static int rtw_dbg_port(struct net_device *dev,
break;
case 0x05:
psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
- if (psta)
- {
+ if (psta) {
int i;
struct recv_reorder_ctrl *preorder_ctrl;
@@ -3152,18 +2928,13 @@ static int rtw_dbg_port(struct net_device *dev,
DBG_871X("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
DBG_871X("agg_enable_bitmap =%x, candidate_tid_bitmap =%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
- for (i = 0;i<16;i++)
- {
+ for (i = 0;i<16;i++) {
preorder_ctrl = &psta->recvreorder_ctrl[i];
if (preorder_ctrl->enable)
- {
DBG_871X("tid =%d, indicate_seq =%d\n", i, preorder_ctrl->indicate_seq);
- }
}
- }
- else
- {
+ } else {
DBG_871X("can't get sta's macaddr, cur_network's macaddr:" MAC_FMT "\n", MAC_ARG(cur_network->network.MacAddress));
}
break;
@@ -3196,19 +2967,16 @@ static int rtw_dbg_port(struct net_device *dev,
spin_lock_bh(&pstapriv->sta_hash_lock);
- for (i = 0; i< NUM_STA; i++)
- {
+ for (i = 0; i< NUM_STA; i++) {
phead = &(pstapriv->sta_hash[i]);
plist = get_next(phead);
- while (phead != plist)
- {
+ while (phead != plist) {
psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
plist = get_next(plist);
- if (extra_arg == psta->aid)
- {
+ if (extra_arg == psta->aid) {
DBG_871X("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr));
DBG_871X("rtsen =%d, cts2slef =%d\n", psta->rtsen, psta->cts2self);
DBG_871X("state = 0x%x, aid =%d, macid =%d, raid =%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
@@ -3226,17 +2994,12 @@ static int rtw_dbg_port(struct net_device *dev,
- for (j = 0;j<16;j++)
- {
+ for (j = 0;j<16;j++) {
preorder_ctrl = &psta->recvreorder_ctrl[j];
if (preorder_ctrl->enable)
- {
DBG_871X("tid =%d, indicate_seq =%d\n", j, preorder_ctrl->indicate_seq);
- }
}
-
}
-
}
}
@@ -3255,8 +3018,7 @@ static int rtw_dbg_port(struct net_device *dev,
if (arg == 0) {
DBG_871X("disable driver ctrl vcs\n");
padapter->driver_vcs_en = 0;
- }
- else if (arg == 1) {
+ } else if (arg == 1) {
DBG_871X("enable driver ctrl vcs = %d\n", extra_arg);
padapter->driver_vcs_en = 1;
@@ -3272,8 +3034,7 @@ static int rtw_dbg_port(struct net_device *dev,
DBG_871X("dump rx packet (%d)\n", extra_arg);
/* pHalData->bDumpRxPkt =extra_arg; */
rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_RXPKT, &(extra_arg));
- }
- else if (arg == 1) {
+ } else if (arg == 1) {
DBG_871X("dump tx packet (%d)\n", extra_arg);
rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(extra_arg));
}
@@ -3284,8 +3045,7 @@ static int rtw_dbg_port(struct net_device *dev,
if (arg == 0) {
DBG_871X("disable driver ctrl rx_ampdu_factor\n");
padapter->driver_rx_ampdu_factor = 0xFF;
- }
- else if (arg == 1) {
+ } else if (arg == 1) {
DBG_871X("enable driver ctrl rx_ampdu_factor = %d\n", extra_arg);
@@ -3310,12 +3070,10 @@ static int rtw_dbg_port(struct net_device *dev,
struct registry_priv *pregpriv = &padapter->registrypriv;
/* 0: disable, bit(0):enable 2.4g, bit(1):enable 5g, 0x3: enable both 2.4g and 5g */
/* default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ */
- if (pregpriv && (extra_arg == 0 || extra_arg == 1|| extra_arg == 2 || extra_arg == 3))
- {
+ if (pregpriv && (extra_arg == 0 || extra_arg == 1|| extra_arg == 2 || extra_arg == 3)) {
pregpriv->rx_stbc = extra_arg;
DBG_871X("set rx_stbc =%d\n", pregpriv->rx_stbc);
- }
- else
+ } else
DBG_871X("get rx_stbc =%d\n", pregpriv->rx_stbc);
}
@@ -3324,12 +3082,10 @@ static int rtw_dbg_port(struct net_device *dev,
{
struct registry_priv *pregpriv = &padapter->registrypriv;
/* 0: disable, 0x1:enable (but wifi_spec should be 0), 0x2: force enable (don't care wifi_spec) */
- if (pregpriv && extra_arg < 3)
- {
+ if (pregpriv && extra_arg < 3) {
pregpriv->ampdu_enable = extra_arg;
DBG_871X("set ampdu_enable =%d\n", pregpriv->ampdu_enable);
- }
- else
+ } else
DBG_871X("get ampdu_enable =%d\n", pregpriv->ampdu_enable);
}
@@ -3343,8 +3099,7 @@ static int rtw_dbg_port(struct net_device *dev,
{
if (arg == 0xff) {
rtw_odm_dbg_comp_msg(RTW_DBGDUMP, padapter);
- }
- else {
+ } else {
u64 dbg_comp = (u64)extra_arg;
rtw_odm_dbg_comp_set(padapter, dbg_comp);
}
@@ -3375,8 +3130,7 @@ static int rtw_dbg_port(struct net_device *dev,
if (arg == 0) {
DBG_871X("driver disable LDPC\n");
pregistrypriv->ldpc_cap = 0x00;
- }
- else if (arg == 1) {
+ } else if (arg == 1) {
DBG_871X("driver set LDPC cap = 0x%x\n", extra_arg);
pregistrypriv->ldpc_cap = (u8)(extra_arg&0x33);
}
@@ -3391,8 +3145,7 @@ static int rtw_dbg_port(struct net_device *dev,
if (arg == 0) {
DBG_871X("driver disable STBC\n");
pregistrypriv->stbc_cap = 0x00;
- }
- else if (arg == 1) {
+ } else if (arg == 1) {
DBG_871X("driver set STBC cap = 0x%x\n", extra_arg);
pregistrypriv->stbc_cap = (u8)(extra_arg&0x33);
}
@@ -3406,8 +3159,7 @@ static int rtw_dbg_port(struct net_device *dev,
DBG_871X("disable driver ctrl max_rx_rate, reset to default_rate_set\n");
init_mlme_default_rate_set(padapter);
pregistrypriv->ht_enable = (u8)rtw_ht_enable;
- }
- else if (arg == 1) {
+ } else if (arg == 1) {
int i;
u8 max_rx_rate;
@@ -3416,18 +3168,15 @@ static int rtw_dbg_port(struct net_device *dev,
max_rx_rate = (u8)extra_arg;
- if (max_rx_rate < 0xc) /* max_rx_rate < MSC0 -> B or G -> disable HT */
- {
+ if (max_rx_rate < 0xc) { /* max_rx_rate < MSC0 -> B or G -> disable HT */
pregistrypriv->ht_enable = 0;
- for (i = 0; i<NumRates; i++)
- {
+ for (i = 0; i<NumRates; i++) {
if (pmlmeext->datarate[i] > max_rx_rate)
pmlmeext->datarate[i] = 0xff;
}
}
- else if (max_rx_rate < 0x1c) /* mcs0~mcs15 */
- {
+ else if (max_rx_rate < 0x1c) { /* mcs0~mcs15 */
u32 mcs_bitmap = 0x0;
for (i = 0; i<((max_rx_rate+1)-0xc); i++)
@@ -3443,8 +3192,7 @@ static int rtw_dbg_port(struct net_device *dev,
if (arg == 0) {
DBG_871X("disable driver ctrl ampdu density\n");
padapter->driver_ampdu_spacing = 0xFF;
- }
- else if (arg == 1) {
+ } else if (arg == 1) {
DBG_871X("enable driver ctrl ampdu density = %d\n", extra_arg);
@@ -3531,15 +3279,12 @@ static int rtw_dbg_port(struct net_device *dev,
break;
case 0xdd:/* registers dump , 0 for mac reg, 1 for bb reg, 2 for rf reg */
{
- if (extra_arg == 0) {
+ if (extra_arg == 0)
mac_reg_dump(RTW_DBGDUMP, padapter);
- }
- else if (extra_arg == 1) {
+ else if (extra_arg == 1)
bb_reg_dump(RTW_DBGDUMP, padapter);
- }
- else if (extra_arg ==2) {
+ else if (extra_arg ==2)
rf_reg_dump(RTW_DBGDUMP, padapter);
- }
}
break;
@@ -3557,8 +3302,7 @@ static int rtw_dbg_port(struct net_device *dev,
DBG_871X("extra_arg = 4 - disable BT coexistence - BIT(3)\n");
DBG_871X("extra_arg = 5 - disable antenna diversity - BIT(4)\n");
DBG_871X("extra_arg = 6 - enable all dynamic func\n");
- }
- else {
+ } else {
/*extra_arg = 0 - disable all dynamic func
extra_arg = 1 - disable DIG
extra_arg = 2 - disable tx power tracking
@@ -3634,8 +3378,7 @@ static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
/* ret = ieee80211_wpa_enable(ieee, value); */
- switch ((value)&0xff)
- {
+ switch ((value)&0xff) {
case 1 : /* WPA */
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK; /* WPA_PSK */
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
@@ -3721,8 +3464,7 @@ static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
int ret = 0;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- switch (command)
- {
+ switch (command) {
case IEEE_MLME_STA_DEAUTH:
if (!rtw_set_802_11_disassociate(padapter))
@@ -3759,14 +3501,12 @@ static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
}
param = (struct ieee_param *)rtw_malloc(p->length);
- if (param == NULL)
- {
+ if (param == NULL) {
ret = -ENOMEM;
goto out;
}
- if (copy_from_user(param, p->pointer, p->length))
- {
+ if (copy_from_user(param, p->pointer, p->length)) {
kfree(param);
ret = -EFAULT;
goto out;
@@ -3829,35 +3569,28 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
/* sizeof(struct ieee_param) = 64 bytes; */
/* if (param_len != (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) */
- if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len)
- {
+ if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len) {
ret = -EINVAL;
goto exit;
}
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
- param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
- {
- if (param->u.crypt.idx >= WEP_KEYS)
- {
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+ if (param->u.crypt.idx >= WEP_KEYS) {
ret = -EINVAL;
goto exit;
}
- }
- else
- {
+ } else {
psta = rtw_get_stainfo(pstapriv, param->sta_addr);
- if (!psta)
- {
+ if (!psta) {
/* ret = -EINVAL; */
DBG_871X("rtw_set_encryption(), sta has already been removed or never been added\n");
goto exit;
}
}
- if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL))
- {
+ if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL)) {
/* todo:clear default encryption keys */
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
@@ -3871,8 +3604,7 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
}
- if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL))
- {
+ if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL)) {
DBG_871X("r871x_set_encryption, crypt.alg = WEP\n");
wep_key_idx = param->u.crypt.idx;
@@ -3880,15 +3612,13 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
DBG_871X("r871x_set_encryption, wep_key_idx =%d, len =%d\n", wep_key_idx, wep_key_len);
- if ((wep_key_idx >= WEP_KEYS) || (wep_key_len<= 0))
- {
+ if ((wep_key_idx >= WEP_KEYS) || (wep_key_len<= 0)) {
ret = -EINVAL;
goto exit;
}
- if (wep_key_len > 0)
- {
+ if (wep_key_len > 0) {
wep_key_len = wep_key_len <= 5 ? 5 : 13;
wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
pwep =(struct ndis_802_11_wep *)rtw_malloc(wep_total_len);
@@ -3908,8 +3638,7 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
- if (param->u.crypt.set_tx)
- {
+ if (param->u.crypt.set_tx) {
DBG_871X("wep, set_tx = 1\n");
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
@@ -3917,8 +3646,7 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
- if (pwep->KeyLength == 13)
- {
+ if (pwep->KeyLength == 13) {
psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
}
@@ -3931,9 +3659,7 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
psecuritypriv->dot11DefKeylen[wep_key_idx]=pwep->KeyLength;
rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 1);
- }
- else
- {
+ } else {
DBG_871X("wep, set_tx = 0\n");
/* don't update "psecuritypriv->dot11PrivacyAlgrthm" and */
@@ -3951,25 +3677,18 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
}
- if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) /* group key */
- {
- if (param->u.crypt.set_tx == 1)
- {
- if (strcmp(param->u.crypt.alg, "WEP") == 0)
- {
+ if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) { /* group key */
+ if (param->u.crypt.set_tx == 1) {
+ if (strcmp(param->u.crypt.alg, "WEP") == 0) {
DBG_871X("%s, set group_key, WEP\n", __func__);
memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
if (param->u.crypt.key_len == 13)
- {
psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
- }
- }
- else if (strcmp(param->u.crypt.alg, "TKIP") == 0)
- {
+ } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
DBG_871X("%s, set group_key, TKIP\n", __func__);
psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
@@ -3984,16 +3703,13 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
psecuritypriv->busetkipkey = true;
}
- else if (strcmp(param->u.crypt.alg, "CCMP") == 0)
- {
+ else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
DBG_871X("%s, set group_key, CCMP\n", __func__);
psecuritypriv->dot118021XGrpPrivacy = _AES_;
memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
- }
- else
- {
+ } else {
DBG_871X("%s, set group_key, none\n", __func__);
psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
@@ -4008,38 +3724,28 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
pbcmc_sta =rtw_get_bcmc_stainfo(padapter);
- if (pbcmc_sta)
- {
+ if (pbcmc_sta) {
pbcmc_sta->ieee8021x_blocked = false;
pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;/* rx will use bmc_sta's dot118021XPrivacy */
}
-
}
goto exit;
}
- if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) /* psk/802_1x */
- {
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
- {
- if (param->u.crypt.set_tx == 1)
- {
+ if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { /* psk/802_1x */
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
+ if (param->u.crypt.set_tx == 1) {
memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
- if (strcmp(param->u.crypt.alg, "WEP") == 0)
- {
+ if (strcmp(param->u.crypt.alg, "WEP") == 0) {
DBG_871X("%s, set pairwise key, WEP\n", __func__);
psta->dot118021XPrivacy = _WEP40_;
if (param->u.crypt.key_len == 13)
- {
psta->dot118021XPrivacy = _WEP104_;
- }
- }
- else if (strcmp(param->u.crypt.alg, "TKIP") == 0)
- {
+ } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
DBG_871X("%s, set pairwise key, TKIP\n", __func__);
psta->dot118021XPrivacy = _TKIP_;
@@ -4051,16 +3757,12 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
psecuritypriv->busetkipkey = true;
- }
- else if (strcmp(param->u.crypt.alg, "CCMP") == 0)
- {
+ } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
DBG_871X("%s, set pairwise key, CCMP\n", __func__);
psta->dot118021XPrivacy = _AES_;
- }
- else
- {
+ } else {
DBG_871X("%s, set pairwise key, none\n", __func__);
psta->dot118021XPrivacy = _NO_PRIVACY_;
@@ -4070,21 +3772,14 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
psta->ieee8021x_blocked = false;
- }
- else/* group key??? */
- {
- if (strcmp(param->u.crypt.alg, "WEP") == 0)
- {
+ } else { /* group key??? */
+ if (strcmp(param->u.crypt.alg, "WEP") == 0) {
memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
if (param->u.crypt.key_len == 13)
- {
psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
- }
- }
- else if (strcmp(param->u.crypt.alg, "TKIP") == 0)
- {
+ } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
@@ -4096,15 +3791,11 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
psecuritypriv->busetkipkey = true;
- }
- else if (strcmp(param->u.crypt.alg, "CCMP") == 0)
- {
+ } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
psecuritypriv->dot118021XGrpPrivacy = _AES_;
memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
- }
- else
- {
+ } else {
psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
}
@@ -4117,16 +3808,12 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
pbcmc_sta =rtw_get_bcmc_stainfo(padapter);
- if (pbcmc_sta)
- {
+ if (pbcmc_sta) {
pbcmc_sta->ieee8021x_blocked = false;
pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;/* rx will use bmc_sta's dot118021XPrivacy */
}
-
}
-
}
-
}
exit:
@@ -4196,14 +3883,11 @@ static int rtw_add_sta(struct net_device *dev, struct ieee_param *param)
DBG_871X("rtw_add_sta(aid =%d) =" MAC_FMT "\n", param->u.add_sta.aid, MAC_ARG(param->sta_addr));
if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
- {
return -EINVAL;
- }
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
- param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
- {
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
return -EINVAL;
}
@@ -4221,8 +3905,7 @@ static int rtw_add_sta(struct net_device *dev, struct ieee_param *param)
*/
/* psta = rtw_alloc_stainfo(pstapriv, param->sta_addr); */
psta = rtw_get_stainfo(pstapriv, param->sta_addr);
- if (psta)
- {
+ if (psta) {
int flags = param->u.add_sta.flags;
/* DBG_871X("rtw_add_sta(), init sta's variables, psta =%p\n", psta); */
@@ -4242,14 +3925,11 @@ static int rtw_add_sta(struct net_device *dev, struct ieee_param *param)
psta->qos_option = 0;
/* chec 802.11n ht cap. */
- if (WLAN_STA_HT&flags)
- {
+ if (WLAN_STA_HT&flags) {
psta->htpriv.ht_option = true;
psta->qos_option = 1;
memcpy((void*)&psta->htpriv.ht_cap, (void*)&param->u.add_sta.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));
- }
- else
- {
+ } else {
psta->htpriv.ht_option = false;
}
@@ -4259,9 +3939,7 @@ static int rtw_add_sta(struct net_device *dev, struct ieee_param *param)
update_sta_info_apmode(padapter, psta);
- }
- else
- {
+ } else {
ret = -ENOMEM;
}
@@ -4280,27 +3958,22 @@ static int rtw_del_sta(struct net_device *dev, struct ieee_param *param)
DBG_871X("rtw_del_sta =" MAC_FMT "\n", MAC_ARG(param->sta_addr));
if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
- {
return -EINVAL;
- }
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
- param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
- {
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
return -EINVAL;
}
psta = rtw_get_stainfo(pstapriv, param->sta_addr);
- if (psta)
- {
+ if (psta) {
u8 updated =false;
/* DBG_871X("free psta =%p, aid =%d\n", psta, psta->aid); */
spin_lock_bh(&pstapriv->asoc_list_lock);
- if (list_empty(&psta->asoc_list) ==false)
- {
+ if (list_empty(&psta->asoc_list) ==false) {
list_del_init(&psta->asoc_list);
pstapriv->asoc_list_cnt--;
updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
@@ -4312,9 +3985,7 @@ static int rtw_del_sta(struct net_device *dev, struct ieee_param *param)
psta = NULL;
- }
- else
- {
+ } else {
DBG_871X("rtw_del_sta(), sta has already been removed or never been added\n");
/* ret = -1; */
@@ -4338,20 +4009,16 @@ static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *par
DBG_871X("rtw_ioctl_get_sta_info, sta_addr: " MAC_FMT "\n", MAC_ARG(param_ex->sta_addr));
if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
- {
return -EINVAL;
- }
if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff &&
param_ex->sta_addr[2] == 0xff && param_ex->sta_addr[3] == 0xff &&
- param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff)
- {
+ param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff) {
return -EINVAL;
}
psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr);
- if (psta)
- {
+ if (psta) {
psta_data->aid = (u16)psta->aid;
psta_data->capability = psta->capability;
psta_data->flags = psta->flags;
@@ -4384,9 +4051,7 @@ static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *par
psta_data->tx_drops = psta->sta_stats.tx_drops;
- }
- else
- {
+ } else {
ret = -1;
}
@@ -4405,22 +4070,17 @@ static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param)
DBG_871X("rtw_get_sta_wpaie, sta_addr: " MAC_FMT "\n", MAC_ARG(param->sta_addr));
if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
- {
return -EINVAL;
- }
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
- param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
- {
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
return -EINVAL;
}
psta = rtw_get_stainfo(pstapriv, param->sta_addr);
- if (psta)
- {
- if ((psta->wpa_ie[0] == WLAN_EID_RSN) || (psta->wpa_ie[0] == WLAN_EID_GENERIC))
- {
+ if (psta) {
+ if ((psta->wpa_ie[0] == WLAN_EID_RSN) || (psta->wpa_ie[0] == WLAN_EID_GENERIC)) {
int wpa_ie_len;
int copy_len;
@@ -4431,15 +4091,11 @@ static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param)
param->u.wpa_ie.len = copy_len;
memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
- }
- else
- {
+ } else {
/* ret = -1; */
DBG_871X("sta's wpa_ie is NONE\n");
}
- }
- else
- {
+ } else {
ret = -1;
}
@@ -4464,14 +4120,10 @@ static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param,
ie_len = len-12-2;/* 12 = param header, 2:no packed */
- if (pmlmepriv->wps_beacon_ie)
- {
- kfree(pmlmepriv->wps_beacon_ie);
- pmlmepriv->wps_beacon_ie = NULL;
- }
+ kfree(pmlmepriv->wps_beacon_ie);
+ pmlmepriv->wps_beacon_ie = NULL;
- if (ie_len>0)
- {
+ if (ie_len>0) {
pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len);
pmlmepriv->wps_beacon_ie_len = ie_len;
if (pmlmepriv->wps_beacon_ie == NULL) {
@@ -4484,7 +4136,6 @@ static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param,
update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, true);
pmlmeext->bstart_bss = true;
-
}
@@ -4507,14 +4158,10 @@ static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *par
ie_len = len-12-2;/* 12 = param header, 2:no packed */
- if (pmlmepriv->wps_probe_resp_ie)
- {
- kfree(pmlmepriv->wps_probe_resp_ie);
- pmlmepriv->wps_probe_resp_ie = NULL;
- }
+ kfree(pmlmepriv->wps_probe_resp_ie);
+ pmlmepriv->wps_probe_resp_ie = NULL;
- if (ie_len>0)
- {
+ if (ie_len>0) {
pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len);
pmlmepriv->wps_probe_resp_ie_len = ie_len;
if (pmlmepriv->wps_probe_resp_ie == NULL) {
@@ -4544,14 +4191,10 @@ static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *par
ie_len = len-12-2;/* 12 = param header, 2:no packed */
- if (pmlmepriv->wps_assoc_resp_ie)
- {
- kfree(pmlmepriv->wps_assoc_resp_ie);
- pmlmepriv->wps_assoc_resp_ie = NULL;
- }
+ kfree(pmlmepriv->wps_assoc_resp_ie);
+ pmlmepriv->wps_assoc_resp_ie = NULL;
- if (ie_len>0)
- {
+ if (ie_len>0) {
pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
pmlmepriv->wps_assoc_resp_ie_len = ie_len;
if (pmlmepriv->wps_assoc_resp_ie == NULL) {
@@ -4632,8 +4275,7 @@ static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *p
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
- param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
- {
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
return -EINVAL;
}
@@ -4654,8 +4296,7 @@ static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *para
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
- param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
- {
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
return -EINVAL;
}
@@ -4705,14 +4346,12 @@ static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p)
}
param = (struct ieee_param *)rtw_malloc(p->length);
- if (param == NULL)
- {
+ if (param == NULL) {
ret = -ENOMEM;
goto out;
}
- if (copy_from_user(param, p->pointer, p->length))
- {
+ if (copy_from_user(param, p->pointer, p->length)) {
kfree(param);
ret = -EFAULT;
goto out;
@@ -4720,8 +4359,7 @@ static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p)
/* DBG_871X("%s, cmd =%d\n", __func__, param->cmd); */
- switch (param->cmd)
- {
+ switch (param->cmd) {
case RTL871X_HOSTAPD_FLUSH:
ret = rtw_hostapd_sta_flush(dev);
@@ -4861,8 +4499,7 @@ static int rtw_wx_set_priv(struct net_device *dev,
/* dev->name, ext)); */
#ifdef DEBUG_RTW_WX_SET_PRIV
- if (!(ext_dbg = vmalloc(len)))
- {
+ if (!(ext_dbg = vmalloc(len))) {
vfree(ext, len);
return -ENOMEM;
}
@@ -4871,8 +4508,7 @@ static int rtw_wx_set_priv(struct net_device *dev,
#endif
/* added for wps2.0 @20110524 */
- if (dwrq->flags == 0x8766 && len > 8)
- {
+ if (dwrq->flags == 0x8766 && len > 8) {
u32 cp_sz;
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
u8 *probereq_wpsie = ext;
@@ -4880,12 +4516,10 @@ static int rtw_wx_set_priv(struct net_device *dev,
u8 wps_oui[4]={0x0, 0x50, 0xf2, 0x04};
if ((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) &&
- (!memcmp(&probereq_wpsie[2], wps_oui, 4)))
- {
+ (!memcmp(&probereq_wpsie[2], wps_oui, 4))) {
cp_sz = probereq_wpsie_len>MAX_WPS_IE_LEN ? MAX_WPS_IE_LEN:probereq_wpsie_len;
- if (pmlmepriv->wps_probe_req_ie)
- {
+ if (pmlmepriv->wps_probe_req_ie) {
pmlmepriv->wps_probe_req_ie_len = 0;
kfree(pmlmepriv->wps_probe_req_ie);
pmlmepriv->wps_probe_req_ie = NULL;
@@ -4909,8 +4543,7 @@ static int rtw_wx_set_priv(struct net_device *dev,
}
if (len >= WEXT_CSCAN_HEADER_SIZE
- && !memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)
- ) {
+ && !memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) {
ret = rtw_wx_set_scan(dev, info, awrq, ext);
goto FREE_EXT;
}
@@ -4939,17 +4572,13 @@ static int rtw_pm_set(struct net_device *dev,
DBG_871X("[%s] extra = %s\n", __func__, extra);
- if (!memcmp(extra, "lps =", 4))
- {
+ if (!memcmp(extra, "lps =", 4)) {
sscanf(extra+4, "%u", &mode);
ret = rtw_pm_set_lps(padapter, mode);
- }
- else if (!memcmp(extra, "ips =", 4))
- {
+ } else if (!memcmp(extra, "ips =", 4)) {
sscanf(extra+4, "%u", &mode);
ret = rtw_pm_set_ips(padapter, mode);
- }
- else {
+ } else {
ret = -EINVAL;
}
@@ -5015,8 +4644,7 @@ static int rtw_widi_set_probe_request(struct net_device *dev,
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
pbuf = rtw_malloc(sizeof(l2_msg_t));
- if (pbuf)
- {
+ if (pbuf) {
if (copy_from_user(pbuf, wrqu->data.pointer, wrqu->data.length))
ret = -EFAULT;
/* memcpy(pbuf, wrqu->data.pointer, wrqu->data.length); */
@@ -5067,17 +4695,12 @@ static int rtw_test(
}
if (strcmp(pch, "bton") == 0)
- {
rtw_btcoex_SetManualControl(padapter, false);
- }
if (strcmp(pch, "btoff") == 0)
- {
rtw_btcoex_SetManualControl(padapter, true);
- }
- if (strcmp(pch, "h2c") == 0)
- {
+ if (strcmp(pch, "h2c") == 0) {
u8 param[8];
u8 count = 0;
u32 tmp;
@@ -5104,9 +4727,8 @@ static int rtw_test(
ret = rtw_hal_fill_h2c_cmd(padapter, param[0], count-1, &param[1]);
pos = sprintf(extra, "H2C ID = 0x%02x content =", param[0]);
- for (i = 1; i<count; i++) {
+ for (i = 1; i<count; i++)
pos += sprintf(extra+pos, "%02x,", param[i]);
- }
extra[pos] = 0;
pos--;
pos += sprintf(extra+pos, " %s", ret == _FAIL?"FAIL":"OK");
@@ -5118,8 +4740,7 @@ static int rtw_test(
return 0;
}
-static iw_handler rtw_handlers[] =
-{
+static iw_handler rtw_handlers[] = {
NULL, /* SIOCSIWCOMMIT */
rtw_wx_get_name, /* SIOCGIWNAME */
dummy, /* SIOCSIWNWID */
@@ -5293,8 +4914,7 @@ static const struct iw_priv_args rtw_private_args[] = {
#endif
};
-static iw_handler rtw_private_handler[] =
-{
+static iw_handler rtw_private_handler[] = {
rtw_wx_write32, /* 0x00 */
rtw_wx_read32, /* 0x01 */
rtw_drvext_hdl, /* 0x02 */
@@ -5350,14 +4970,12 @@ static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
int tmp_qual = 0;
int tmp_noise = 0;
- if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true)
- {
+ if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) {
piwstats->qual.qual = 0;
piwstats->qual.level = 0;
piwstats->qual.noise = 0;
/* DBG_871X("No link level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise); */
- }
- else {
+ } else {
#ifdef CONFIG_SIGNAL_DISPLAY_DBM
tmp_level = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
#else
@@ -5409,8 +5027,7 @@ static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
return &padapter->iwstats;
}
-struct iw_handler_def rtw_handlers_def =
-{
+struct iw_handler_def rtw_handlers_def = {
.standard = rtw_handlers,
.num_standard = sizeof(rtw_handlers) / sizeof(iw_handler),
#if defined(CONFIG_WEXT_PRIV)
@@ -5523,8 +5140,7 @@ static int rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_
}
/* Watch out for sub-ioctls ! */
- if (priv_args[k].cmd < SIOCDEVPRIVATE)
- {
+ if (priv_args[k].cmd < SIOCDEVPRIVATE) {
int j = -1;
/* Find the matching *real* ioctl */
@@ -5554,12 +5170,10 @@ static int rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_
/* If we have to set some data */
if ((priv_args[k].set_args & IW_PRIV_TYPE_MASK) &&
- (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
- {
+ (priv_args[k].set_args & IW_PRIV_SIZE_MASK)) {
u8 *str;
- switch (priv_args[k].set_args & IW_PRIV_TYPE_MASK)
- {
+ switch (priv_args[k].set_args & IW_PRIV_TYPE_MASK) {
case IW_PRIV_TYPE_BYTE:
/* Fetch args */
count = 0;
@@ -5597,8 +5211,7 @@ static int rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_
break;
case IW_PRIV_TYPE_CHAR:
- if (len > 0)
- {
+ if (len > 0) {
/* Size of the string to fetch */
wdata.data.length = len;
if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
@@ -5606,9 +5219,7 @@ static int rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_
/* Fetch string */
memcpy(buffer, ptr, wdata.data.length);
- }
- else
- {
+ } else {
wdata.data.length = 1;
buffer[0] = '\0';
}
@@ -5622,41 +5233,32 @@ static int rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_
}
if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
- (wdata.data.length != (priv_args[k].set_args & IW_PRIV_SIZE_MASK)))
- {
+ (wdata.data.length != (priv_args[k].set_args & IW_PRIV_SIZE_MASK))) {
DBG_8192C("%s: The command %s needs exactly %d argument(s)...\n",
__func__, cmdname, priv_args[k].set_args & IW_PRIV_SIZE_MASK);
err = -EINVAL;
goto exit;
}
- } /* if args to set */
- else
- {
+ } else { /* if args to set */
wdata.data.length = 0L;
}
/* Those two tests are important. They define how the driver
* will have to handle the data */
if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
- ((get_priv_size(priv_args[k].set_args) + offset) <= IFNAMSIZ))
- {
+ ((get_priv_size(priv_args[k].set_args) + offset) <= IFNAMSIZ)) {
/* First case : all SET args fit within wrq */
if (offset)
wdata.mode = subcmd;
memcpy(wdata.name + offset, buffer, IFNAMSIZ - offset);
- }
- else
- {
+ } else {
if ((priv_args[k].set_args == 0) &&
(priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
- (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ))
- {
+ (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ)) {
/* Second case : no SET args, GET args fit within wrq */
if (offset)
wdata.mode = subcmd;
- }
- else
- {
+ } else {
/* Third case : args won't fit in wrq, or variable number of args */
if (copy_to_user(wdata.data.pointer, buffer, buffer_len)) {
err = -EFAULT;
@@ -5670,8 +5272,7 @@ static int rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_
input = NULL;
extra_size = 0;
- if (IW_IS_SET(priv_args[k].cmd))
- {
+ if (IW_IS_SET(priv_args[k].cmd)) {
/* Size of set arguments */
extra_size = get_priv_size(priv_args[k].set_args);
@@ -5701,8 +5302,7 @@ static int rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_
/* If we have to get some data */
if ((priv_args[k].get_args & IW_PRIV_TYPE_MASK) &&
- (priv_args[k].get_args & IW_PRIV_SIZE_MASK))
- {
+ (priv_args[k].get_args & IW_PRIV_SIZE_MASK)) {
int j;
int n = 0; /* number of args */
u8 str[20] = {0};
@@ -5720,12 +5320,10 @@ static int rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_
goto exit;
}
- switch (priv_args[k].get_args & IW_PRIV_TYPE_MASK)
- {
+ switch (priv_args[k].get_args & IW_PRIV_TYPE_MASK) {
case IW_PRIV_TYPE_BYTE:
/* Display args */
- for (j = 0; j < n; j++)
- {
+ for (j = 0; j < n; j++) {
sprintf(str, "%d ", extra[j]);
len = strlen(str);
output_len = strlen(output);
@@ -5739,8 +5337,7 @@ static int rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_
case IW_PRIV_TYPE_INT:
/* Display args */
- for (j = 0; j < n; j++)
- {
+ for (j = 0; j < n; j++) {
sprintf(str, "%d ", ((__s32*)extra)[j]);
len = strlen(str);
output_len = strlen(output);
@@ -5769,9 +5366,7 @@ static int rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_
err = -EFAULT;
goto exit;
}
- } /* if args to set */
- else
- {
+ } else { /* if args to set */
wrq_data->data.length = 0;
}
@@ -5788,8 +5383,7 @@ int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
struct iwreq *wrq = (struct iwreq *)rq;
int ret = 0;
- switch (cmd)
- {
+ switch (cmd) {
case RTL_IOCTL_WPA_SUPPLICANT:
ret = wpa_supplicant_ioctl(dev, &wrq->u.data);
break;
diff --git a/drivers/staging/rtl8723bs/os_dep/mlme_linux.c b/drivers/staging/rtl8723bs/os_dep/mlme_linux.c
index 46315d1..80ca2d7 100644
--- a/drivers/staging/rtl8723bs/os_dep/mlme_linux.c
+++ b/drivers/staging/rtl8723bs/os_dep/mlme_linux.c
@@ -21,7 +21,7 @@
static void _dynamic_check_timer_handlder (void *FunctionContext)
{
- struct adapter *adapter = (struct adapter *)FunctionContext;
+ struct adapter *adapter = FunctionContext;
rtw_dynamic_check_timer_handlder(adapter);
@@ -30,7 +30,7 @@ static void _dynamic_check_timer_handlder (void *FunctionContext)
static void _rtw_set_scan_deny_timer_hdl(void *FunctionContext)
{
- struct adapter *adapter = (struct adapter *)FunctionContext;
+ struct adapter *adapter = FunctionContext;
rtw_set_scan_deny_timer_hdl(adapter);
}
@@ -91,8 +91,6 @@ void rtw_reset_securitypriv(struct adapter *adapter)
/* Backup the btkip_countermeasure information. */
/* When the countermeasure is trigger, the driver have to disconnect with AP for 60 seconds. */
- memset(&backupPMKIDList[ 0 ], 0x00, sizeof(RT_PMKID_LIST) * NUM_PMKID_CACHE);
-
memcpy(&backupPMKIDList[ 0 ], &adapter->securitypriv.PMKIDList[ 0 ], sizeof(RT_PMKID_LIST) * NUM_PMKID_CACHE);
backupPMKIDIndex = adapter->securitypriv.PMKIDIndex;
backupTKIPCountermeasure = adapter->securitypriv.btkip_countermeasure;
diff --git a/drivers/staging/rtl8723bs/os_dep/osdep_service.c b/drivers/staging/rtl8723bs/os_dep/osdep_service.c
index aa16d1a..a05daf0 100644
--- a/drivers/staging/rtl8723bs/os_dep/osdep_service.c
+++ b/drivers/staging/rtl8723bs/os_dep/osdep_service.c
@@ -73,7 +73,7 @@ inline int _rtw_netif_rx(_nic_hdl ndev, struct sk_buff *skb)
void rtw_init_timer(_timer *ptimer, void *padapter, void *pfunc)
{
- struct adapter *adapter = (struct adapter *)padapter;
+ struct adapter *adapter = padapter;
_init_timer(ptimer, adapter->pnetdev, pfunc, adapter);
}
diff --git a/drivers/staging/rtl8723bs/os_dep/sdio_intf.c b/drivers/staging/rtl8723bs/os_dep/sdio_intf.c
index d2fb489..94332487 100644
--- a/drivers/staging/rtl8723bs/os_dep/sdio_intf.c
+++ b/drivers/staging/rtl8723bs/os_dep/sdio_intf.c
@@ -138,7 +138,7 @@ static void sdio_free_irq(struct dvobj_priv *dvobj)
extern unsigned int oob_irq;
static irqreturn_t gpio_hostwakeup_irq_thread(int irq, void *data)
{
- struct adapter *padapter = (struct adapter *)data;
+ struct adapter *padapter = data;
DBG_871X_LEVEL(_drv_always_, "gpio_hostwakeup_irq_thread\n");
/* Disable interrupt before calling handler */
/* disable_irq_nosync(oob_irq); */
diff --git a/drivers/staging/rtl8723bs/os_dep/sdio_ops_linux.c b/drivers/staging/rtl8723bs/os_dep/sdio_ops_linux.c
index 3aa3e65..3108a62 100644
--- a/drivers/staging/rtl8723bs/os_dep/sdio_ops_linux.c
+++ b/drivers/staging/rtl8723bs/os_dep/sdio_ops_linux.c
@@ -431,7 +431,7 @@ s32 _sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
if (unlikely((cnt == 1) || (cnt == 2)))
{
int i;
- u8 *pbuf = (u8 *)pdata;
+ u8 *pbuf = pdata;
for (i = 0; i < cnt; i++)
{
@@ -534,7 +534,7 @@ s32 _sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
if (unlikely((cnt == 1) || (cnt == 2)))
{
int i;
- u8 *pbuf = (u8 *)pdata;
+ u8 *pbuf = pdata;
for (i = 0; i < cnt; i++)
{
diff --git a/drivers/staging/rtl8723bs/os_dep/xmit_linux.c b/drivers/staging/rtl8723bs/os_dep/xmit_linux.c
index 7696816..f29e110 100644
--- a/drivers/staging/rtl8723bs/os_dep/xmit_linux.c
+++ b/drivers/staging/rtl8723bs/os_dep/xmit_linux.c
@@ -37,7 +37,7 @@ uint _rtw_pktfile_read (struct pkt_file *pfile, u8 *rmem, uint rlen)
uint len = 0;
len = rtw_remainder_len(pfile);
- len = (rlen > len)? len: rlen;
+ len = (rlen > len) ? len : rlen;
if (rmem)
skb_copy_bits(pfile->pkt, pfile->buf_len-pfile->pkt_len, rmem, len);
@@ -134,7 +134,7 @@ static void rtw_check_xmit_resource(struct adapter *padapter, _pkt *pkt)
netif_stop_subqueue(padapter->pnetdev, queue);
}
} else {
- if (pxmitpriv->free_xmitframe_cnt<=4) {
+ if (pxmitpriv->free_xmitframe_cnt <= 4) {
if (!netif_tx_queue_stopped(netdev_get_tx_queue(padapter->pnetdev, queue)))
netif_stop_subqueue(padapter->pnetdev, queue);
}
@@ -150,8 +150,8 @@ static int rtw_mlcst2unicst(struct adapter *padapter, struct sk_buff *skb)
struct sta_info *psta = NULL;
u8 chk_alive_num = 0;
char chk_alive_list[NUM_STA];
- u8 bc_addr[6]={0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
- u8 null_addr[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ u8 bc_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ u8 null_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
int i;
s32 res;
@@ -177,7 +177,7 @@ static int rtw_mlcst2unicst(struct adapter *padapter, struct sk_buff *skb)
for (i = 0; i < chk_alive_num; i++) {
psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
- if (!(psta->state &_FW_LINKED))
+ if (!(psta->state & _FW_LINKED))
{
DBG_COUNTER(padapter->tx_logs.os_tx_m2u_ignore_fw_linked);
continue;
diff --git a/drivers/staging/rtlwifi/Kconfig b/drivers/staging/rtlwifi/Kconfig
new file mode 100644
index 0000000..cb3a29a
--- /dev/null
+++ b/drivers/staging/rtlwifi/Kconfig
@@ -0,0 +1,22 @@
+config R8822BE
+ tristate "Realtek RTL8822BE Wireless Network Adapter"
+ depends on PCI && MAC80211 && m
+ select FW_LOADER
+ ---help---
+ This is the staging driver for Realtek RTL8822BE 802.11ac PCIe
+ wireless network adapters.
+
+config RTLHALMAC_ST
+ tristate
+ depends on R8822BE
+ default m
+
+config RTLPHYDM_ST
+ tristate
+ depends on R8822BE
+ default m
+
+config RTLWIFI_DEBUG_ST
+ boolean
+ depends on R8822BE
+ default y
diff --git a/drivers/staging/rtlwifi/Makefile b/drivers/staging/rtlwifi/Makefile
new file mode 100644
index 0000000..0d738c1
--- /dev/null
+++ b/drivers/staging/rtlwifi/Makefile
@@ -0,0 +1,70 @@
+obj-$(CONFIG_R8822BE) += r8822be.o
+
+r8822be-objs := \
+ base.o \
+ cam.o \
+ core.o \
+ debug.o \
+ efuse.o \
+ ps.o \
+ rc.o \
+ regd.o \
+ stats.o \
+ pci.o \
+ rtl8822be/fw.o \
+ rtl8822be/hw.o \
+ rtl8822be/led.o \
+ rtl8822be/phy.o \
+ rtl8822be/sw.o \
+ rtl8822be/trx.o \
+ btcoexist/halbtc8822b2ant.o \
+ btcoexist/halbtc8822b1ant.o \
+ btcoexist/halbtc8822bwifionly.o \
+ btcoexist/halbtcoutsrc.o \
+ btcoexist/rtl_btc.o \
+ halmac/halmac_api.o \
+ halmac/halmac_88xx/halmac_api_88xx_usb.o \
+ halmac/halmac_88xx/halmac_api_88xx_sdio.o \
+ halmac/halmac_88xx/halmac_api_88xx.o \
+ halmac/halmac_88xx/halmac_api_88xx_pcie.o \
+ halmac/halmac_88xx/halmac_func_88xx.o \
+ halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_pcie.o \
+ halmac/halmac_88xx/halmac_8822b/halmac_func_8822b.o \
+ halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_sdio.o \
+ halmac/halmac_88xx/halmac_8822b/halmac_api_8822b.o \
+ halmac/halmac_88xx/halmac_8822b/halmac_8822b_phy.o \
+ halmac/halmac_88xx/halmac_8822b/halmac_8822b_pwr_seq.o \
+ halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_usb.o \
+ halmac/rtl_halmac.o \
+ phydm/phydm_debug.o \
+ phydm/phydm_antdiv.o\
+ phydm/phydm_interface.o\
+ phydm/phydm_hwconfig.o\
+ phydm/phydm.o\
+ phydm/halphyrf_ce.o\
+ phydm/phydm_edcaturbocheck.o\
+ phydm/phydm_dig.o\
+ phydm/phydm_rainfo.o\
+ phydm/phydm_dynamicbbpowersaving.o\
+ phydm/phydm_powertracking_ce.o\
+ phydm/phydm_dynamictxpower.o\
+ phydm/phydm_adaptivity.o\
+ phydm/phydm_cfotracking.o\
+ phydm/phydm_noisemonitor.o\
+ phydm/phydm_acs.o\
+ phydm/phydm_psd.o\
+ phydm/phydm_adc_sampling.o\
+ phydm/phydm_kfree.o\
+ phydm/phydm_ccx.o \
+ phydm/rtl8822b/halhwimg8822b_bb.o\
+ phydm/rtl8822b/halhwimg8822b_mac.o\
+ phydm/rtl8822b/halhwimg8822b_rf.o\
+ phydm/rtl8822b/halphyrf_8822b.o\
+ phydm/rtl8822b/phydm_hal_api8822b.o\
+ phydm/rtl8822b/phydm_iqk_8822b.o\
+ phydm/rtl8822b/phydm_regconfig8822b.o\
+ phydm/rtl8822b/phydm_rtl8822b.o \
+ phydm/rtl_phydm.o
+
+
+obj-$(CONFIG_R8822BE) += rtl8822be/
diff --git a/drivers/staging/rtlwifi/TODO b/drivers/staging/rtlwifi/TODO
new file mode 100644
index 0000000..4a084f2
--- /dev/null
+++ b/drivers/staging/rtlwifi/TODO
@@ -0,0 +1,11 @@
+TODO:
+- find and remove code blocks guarded by never set CONFIG_FOO defines
+- convert any remaining unusual variable types
+- find codes that can use %pM and %Nph formatting
+- checkpatch.pl fixes - most of the remaining ones are lines too long. Many
+ of them will require refactoring
+- merge Realtek's bugfixes and new features into the driver
+- address any reviewers comments
+
+Please send any patches to Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
+and Larry Finger <Larry.Finger@lwfinger.net>.
diff --git a/drivers/staging/rtlwifi/base.c b/drivers/staging/rtlwifi/base.c
new file mode 100644
index 0000000..b88b0e8
--- /dev/null
+++ b/drivers/staging/rtlwifi/base.c
@@ -0,0 +1,2826 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2012 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "wifi.h"
+#include "rc.h"
+#include "base.h"
+#include "efuse.h"
+#include "cam.h"
+#include "ps.h"
+#include "regd.h"
+#include "pci.h"
+#include <linux/ip.h>
+#include <linux/module.h>
+#include <linux/udp.h>
+
+/*
+ *NOTICE!!!: This file will be very big, we should
+ *keep it clear under following roles:
+ *
+ *This file include following parts, so, if you add new
+ *functions into this file, please check which part it
+ *should includes. or check if you should add new part
+ *for this file:
+ *
+ *1) mac80211 init functions
+ *2) tx information functions
+ *3) functions called by core.c
+ *4) wq & timer callback functions
+ *5) frame process functions
+ *6) IOT functions
+ *7) sysfs functions
+ *8) vif functions
+ *9) ...
+ */
+
+/*********************************************************
+ *
+ * mac80211 init functions
+ *
+ *********************************************************/
+static struct ieee80211_channel rtl_channeltable_2g[] = {
+ {.center_freq = 2412, .hw_value = 1,},
+ {.center_freq = 2417, .hw_value = 2,},
+ {.center_freq = 2422, .hw_value = 3,},
+ {.center_freq = 2427, .hw_value = 4,},
+ {.center_freq = 2432, .hw_value = 5,},
+ {.center_freq = 2437, .hw_value = 6,},
+ {.center_freq = 2442, .hw_value = 7,},
+ {.center_freq = 2447, .hw_value = 8,},
+ {.center_freq = 2452, .hw_value = 9,},
+ {.center_freq = 2457, .hw_value = 10,},
+ {.center_freq = 2462, .hw_value = 11,},
+ {.center_freq = 2467, .hw_value = 12,},
+ {.center_freq = 2472, .hw_value = 13,},
+ {.center_freq = 2484, .hw_value = 14,},
+};
+
+static struct ieee80211_channel rtl_channeltable_5g[] = {
+ {.center_freq = 5180, .hw_value = 36,},
+ {.center_freq = 5200, .hw_value = 40,},
+ {.center_freq = 5220, .hw_value = 44,},
+ {.center_freq = 5240, .hw_value = 48,},
+ {.center_freq = 5260, .hw_value = 52,},
+ {.center_freq = 5280, .hw_value = 56,},
+ {.center_freq = 5300, .hw_value = 60,},
+ {.center_freq = 5320, .hw_value = 64,},
+ {.center_freq = 5500, .hw_value = 100,},
+ {.center_freq = 5520, .hw_value = 104,},
+ {.center_freq = 5540, .hw_value = 108,},
+ {.center_freq = 5560, .hw_value = 112,},
+ {.center_freq = 5580, .hw_value = 116,},
+ {.center_freq = 5600, .hw_value = 120,},
+ {.center_freq = 5620, .hw_value = 124,},
+ {.center_freq = 5640, .hw_value = 128,},
+ {.center_freq = 5660, .hw_value = 132,},
+ {.center_freq = 5680, .hw_value = 136,},
+ {.center_freq = 5700, .hw_value = 140,},
+ {.center_freq = 5745, .hw_value = 149,},
+ {.center_freq = 5765, .hw_value = 153,},
+ {.center_freq = 5785, .hw_value = 157,},
+ {.center_freq = 5805, .hw_value = 161,},
+ {.center_freq = 5825, .hw_value = 165,},
+};
+
+static struct ieee80211_rate rtl_ratetable_2g[] = {
+ {.bitrate = 10, .hw_value = 0x00,},
+ {.bitrate = 20, .hw_value = 0x01,},
+ {.bitrate = 55, .hw_value = 0x02,},
+ {.bitrate = 110, .hw_value = 0x03,},
+ {.bitrate = 60, .hw_value = 0x04,},
+ {.bitrate = 90, .hw_value = 0x05,},
+ {.bitrate = 120, .hw_value = 0x06,},
+ {.bitrate = 180, .hw_value = 0x07,},
+ {.bitrate = 240, .hw_value = 0x08,},
+ {.bitrate = 360, .hw_value = 0x09,},
+ {.bitrate = 480, .hw_value = 0x0a,},
+ {.bitrate = 540, .hw_value = 0x0b,},
+};
+
+static struct ieee80211_rate rtl_ratetable_5g[] = {
+ {.bitrate = 60, .hw_value = 0x04,},
+ {.bitrate = 90, .hw_value = 0x05,},
+ {.bitrate = 120, .hw_value = 0x06,},
+ {.bitrate = 180, .hw_value = 0x07,},
+ {.bitrate = 240, .hw_value = 0x08,},
+ {.bitrate = 360, .hw_value = 0x09,},
+ {.bitrate = 480, .hw_value = 0x0a,},
+ {.bitrate = 540, .hw_value = 0x0b,},
+};
+
+static const struct ieee80211_supported_band rtl_band_2ghz = {
+ .band = NL80211_BAND_2GHZ,
+
+ .channels = rtl_channeltable_2g,
+ .n_channels = ARRAY_SIZE(rtl_channeltable_2g),
+
+ .bitrates = rtl_ratetable_2g,
+ .n_bitrates = ARRAY_SIZE(rtl_ratetable_2g),
+
+ .ht_cap = {0},
+};
+
+static struct ieee80211_supported_band rtl_band_5ghz = {
+ .band = NL80211_BAND_5GHZ,
+
+ .channels = rtl_channeltable_5g,
+ .n_channels = ARRAY_SIZE(rtl_channeltable_5g),
+
+ .bitrates = rtl_ratetable_5g,
+ .n_bitrates = ARRAY_SIZE(rtl_ratetable_5g),
+
+ .ht_cap = {0},
+};
+
+static const u8 tid_to_ac[] = {
+ 2, /* IEEE80211_AC_BE */
+ 3, /* IEEE80211_AC_BK */
+ 3, /* IEEE80211_AC_BK */
+ 2, /* IEEE80211_AC_BE */
+ 1, /* IEEE80211_AC_VI */
+ 1, /* IEEE80211_AC_VI */
+ 0, /* IEEE80211_AC_VO */
+ 0, /* IEEE80211_AC_VO */
+};
+
+u8 rtl_tid_to_ac(u8 tid)
+{
+ return tid_to_ac[tid];
+}
+
+static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw,
+ struct ieee80211_sta_ht_cap *ht_cap)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+
+ ht_cap->ht_supported = true;
+ ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
+ IEEE80211_HT_CAP_SGI_40 |
+ IEEE80211_HT_CAP_SGI_20 |
+ IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
+
+ if (rtlpriv->rtlhal.disable_amsdu_8k)
+ ht_cap->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU;
+
+ /*
+ *Maximum length of AMPDU that the STA can receive.
+ *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
+ */
+ ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
+
+ /*Minimum MPDU start spacing , */
+ ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
+
+ ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
+
+ /*hw->wiphy->bands[NL80211_BAND_2GHZ]
+ *base on ant_num
+ *rx_mask: RX mask
+ *if rx_ant = 1 rx_mask[0]= 0xff;==>MCS0-MCS7
+ *if rx_ant = 2 rx_mask[1]= 0xff;==>MCS8-MCS15
+ *if rx_ant >= 3 rx_mask[2]= 0xff;
+ *if BW_40 rx_mask[4]= 0x01;
+ *highest supported RX rate
+ */
+ if (rtlpriv->dm.supp_phymode_switch) {
+ pr_info("Support phy mode switch\n");
+
+ ht_cap->mcs.rx_mask[0] = 0xFF;
+ ht_cap->mcs.rx_mask[1] = 0xFF;
+ ht_cap->mcs.rx_mask[4] = 0x01;
+
+ ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15);
+ } else {
+ if (get_rf_type(rtlphy) == RF_1T2R ||
+ get_rf_type(rtlphy) == RF_2T2R) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ "1T2R or 2T2R\n");
+ ht_cap->mcs.rx_mask[0] = 0xFF;
+ ht_cap->mcs.rx_mask[1] = 0xFF;
+ ht_cap->mcs.rx_mask[4] = 0x01;
+
+ ht_cap->mcs.rx_highest =
+ cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15);
+ } else if (get_rf_type(rtlphy) == RF_1T1R) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "1T1R\n");
+
+ ht_cap->mcs.rx_mask[0] = 0xFF;
+ ht_cap->mcs.rx_mask[1] = 0x00;
+ ht_cap->mcs.rx_mask[4] = 0x01;
+
+ ht_cap->mcs.rx_highest =
+ cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS7);
+ }
+ }
+}
+
+static void _rtl_init_hw_vht_capab(struct ieee80211_hw *hw,
+ struct ieee80211_sta_vht_cap *vht_cap)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE ||
+ rtlhal->hw_type == HARDWARE_TYPE_RTL8822BE) {
+ u16 mcs_map;
+
+ vht_cap->vht_supported = true;
+ vht_cap->cap =
+ IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
+ IEEE80211_VHT_CAP_SHORT_GI_80 |
+ IEEE80211_VHT_CAP_TXSTBC |
+ IEEE80211_VHT_CAP_RXSTBC_1 |
+ IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
+ IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
+ IEEE80211_VHT_CAP_HTC_VHT |
+ IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK |
+ IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
+ IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN |
+ 0;
+
+ mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 |
+ IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 |
+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 |
+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 |
+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 |
+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 |
+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |
+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 14;
+
+ vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
+ vht_cap->vht_mcs.rx_highest =
+ cpu_to_le16(MAX_BIT_RATE_SHORT_GI_2NSS_80MHZ_MCS9);
+ vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
+ vht_cap->vht_mcs.tx_highest =
+ cpu_to_le16(MAX_BIT_RATE_SHORT_GI_2NSS_80MHZ_MCS9);
+ } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
+ u16 mcs_map;
+
+ vht_cap->vht_supported = true;
+ vht_cap->cap =
+ IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
+ IEEE80211_VHT_CAP_SHORT_GI_80 |
+ IEEE80211_VHT_CAP_TXSTBC |
+ IEEE80211_VHT_CAP_RXSTBC_1 |
+ IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
+ IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
+ IEEE80211_VHT_CAP_HTC_VHT |
+ IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK |
+ IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
+ IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN |
+ 0;
+
+ mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 |
+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 2 |
+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 |
+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 |
+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 |
+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 |
+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |
+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 14;
+
+ vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
+ vht_cap->vht_mcs.rx_highest =
+ cpu_to_le16(MAX_BIT_RATE_SHORT_GI_1NSS_80MHZ_MCS9);
+ vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
+ vht_cap->vht_mcs.tx_highest =
+ cpu_to_le16(MAX_BIT_RATE_SHORT_GI_1NSS_80MHZ_MCS9);
+ }
+}
+
+static void _rtl_init_mac80211(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+ struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ struct ieee80211_supported_band *sband;
+
+ if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY &&
+ rtlhal->bandset == BAND_ON_BOTH) {
+ /* 1: 2.4 G bands */
+ /* <1> use mac->bands as mem for hw->wiphy->bands */
+ sband = &rtlmac->bands[NL80211_BAND_2GHZ];
+
+ /* <2> set hw->wiphy->bands[NL80211_BAND_2GHZ]
+ * to default value(1T1R)
+ */
+ memcpy(&rtlmac->bands[NL80211_BAND_2GHZ], &rtl_band_2ghz,
+ sizeof(struct ieee80211_supported_band));
+
+ /* <3> init ht cap base on ant_num */
+ _rtl_init_hw_ht_capab(hw, &sband->ht_cap);
+
+ /* <4> set mac->sband to wiphy->sband */
+ hw->wiphy->bands[NL80211_BAND_2GHZ] = sband;
+
+ /* 2: 5 G bands */
+ /* <1> use mac->bands as mem for hw->wiphy->bands */
+ sband = &rtlmac->bands[NL80211_BAND_5GHZ];
+
+ /* <2> set hw->wiphy->bands[NL80211_BAND_5GHZ]
+ * to default value(1T1R)
+ */
+ memcpy(&rtlmac->bands[NL80211_BAND_5GHZ], &rtl_band_5ghz,
+ sizeof(struct ieee80211_supported_band));
+
+ /* <3> init ht cap base on ant_num */
+ _rtl_init_hw_ht_capab(hw, &sband->ht_cap);
+
+ _rtl_init_hw_vht_capab(hw, &sband->vht_cap);
+ /* <4> set mac->sband to wiphy->sband */
+ hw->wiphy->bands[NL80211_BAND_5GHZ] = sband;
+ } else {
+ if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+ /* <1> use mac->bands as mem for hw->wiphy->bands */
+ sband = &rtlmac->bands[NL80211_BAND_2GHZ];
+
+ /* <2> set hw->wiphy->bands[NL80211_BAND_2GHZ]
+ * to default value(1T1R)
+ */
+ memcpy(&rtlmac->bands[NL80211_BAND_2GHZ],
+ &rtl_band_2ghz,
+ sizeof(struct ieee80211_supported_band));
+
+ /* <3> init ht cap base on ant_num */
+ _rtl_init_hw_ht_capab(hw, &sband->ht_cap);
+
+ /* <4> set mac->sband to wiphy->sband */
+ hw->wiphy->bands[NL80211_BAND_2GHZ] = sband;
+ } else if (rtlhal->current_bandtype == BAND_ON_5G) {
+ /* <1> use mac->bands as mem for hw->wiphy->bands */
+ sband = &rtlmac->bands[NL80211_BAND_5GHZ];
+
+ /* <2> set hw->wiphy->bands[NL80211_BAND_5GHZ]
+ * to default value(1T1R)
+ */
+ memcpy(&rtlmac->bands[NL80211_BAND_5GHZ],
+ &rtl_band_5ghz,
+ sizeof(struct ieee80211_supported_band));
+
+ /* <3> init ht cap base on ant_num */
+ _rtl_init_hw_ht_capab(hw, &sband->ht_cap);
+
+ _rtl_init_hw_vht_capab(hw, &sband->vht_cap);
+ /* <4> set mac->sband to wiphy->sband */
+ hw->wiphy->bands[NL80211_BAND_5GHZ] = sband;
+ } else {
+ pr_err("Err BAND %d\n",
+ rtlhal->current_bandtype);
+ }
+ }
+ /* <5> set hw caps */
+ ieee80211_hw_set(hw, SIGNAL_DBM);
+ ieee80211_hw_set(hw, RX_INCLUDES_FCS);
+ ieee80211_hw_set(hw, AMPDU_AGGREGATION);
+ ieee80211_hw_set(hw, CONNECTION_MONITOR);
+ ieee80211_hw_set(hw, MFP_CAPABLE);
+ ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
+ ieee80211_hw_set(hw, SUPPORTS_TX_FRAG);
+ ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
+ ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
+
+ /* swlps or hwlps has been set in diff chip in init_sw_vars */
+ if (rtlpriv->psc.swctrl_lps) {
+ ieee80211_hw_set(hw, SUPPORTS_PS);
+ ieee80211_hw_set(hw, PS_NULLFUNC_STACK);
+ }
+ if (rtlpriv->psc.fwctrl_lps) {
+ ieee80211_hw_set(hw, SUPPORTS_PS);
+ ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
+ }
+ hw->wiphy->interface_modes =
+ BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_ADHOC) |
+ BIT(NL80211_IFTYPE_MESH_POINT) |
+ BIT(NL80211_IFTYPE_P2P_CLIENT) |
+ BIT(NL80211_IFTYPE_P2P_GO);
+ hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
+
+ hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
+
+ hw->wiphy->rts_threshold = 2347;
+
+ hw->queues = AC_MAX;
+ hw->extra_tx_headroom = RTL_TX_HEADER_SIZE;
+
+ /* TODO: Correct this value for our hw */
+ hw->max_listen_interval = MAX_LISTEN_INTERVAL;
+ hw->max_rate_tries = MAX_RATE_TRIES;
+ /* hw->max_rates = 1; */
+ hw->sta_data_size = sizeof(struct rtl_sta_info);
+
+/* wowlan is not supported by kernel if CONFIG_PM is not defined */
+#ifdef CONFIG_PM
+ if (rtlpriv->psc.wo_wlan_mode) {
+ if (rtlpriv->psc.wo_wlan_mode & WAKE_ON_MAGIC_PACKET)
+ rtlpriv->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT;
+ if (rtlpriv->psc.wo_wlan_mode & WAKE_ON_PATTERN_MATCH) {
+ rtlpriv->wowlan.n_patterns =
+ MAX_SUPPORT_WOL_PATTERN_NUM;
+ rtlpriv->wowlan.pattern_min_len = MIN_WOL_PATTERN_SIZE;
+ rtlpriv->wowlan.pattern_max_len = MAX_WOL_PATTERN_SIZE;
+ }
+ hw->wiphy->wowlan = &rtlpriv->wowlan;
+ }
+#endif
+
+ /* <6> mac address */
+ if (is_valid_ether_addr(rtlefuse->dev_addr)) {
+ SET_IEEE80211_PERM_ADDR(hw, rtlefuse->dev_addr);
+ } else {
+ u8 rtlmac1[] = { 0x00, 0xe0, 0x4c, 0x81, 0x92, 0x00 };
+
+ get_random_bytes((rtlmac1 + (ETH_ALEN - 1)), 1);
+ SET_IEEE80211_PERM_ADDR(hw, rtlmac1);
+ }
+}
+
+static void _rtl_init_deferred_work(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ /* <1> timer */
+ setup_timer(&rtlpriv->works.watchdog_timer,
+ rtl_watch_dog_timer_callback, (unsigned long)hw);
+ setup_timer(&rtlpriv->works.dualmac_easyconcurrent_retrytimer,
+ rtl_easy_concurrent_retrytimer_callback, (unsigned long)hw);
+ /* <2> work queue */
+ rtlpriv->works.hw = hw;
+ rtlpriv->works.rtl_wq = alloc_workqueue("%s", 0, 0, rtlpriv->cfg->name);
+ INIT_DELAYED_WORK(&rtlpriv->works.watchdog_wq,
+ (void *)rtl_watchdog_wq_callback);
+ INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq,
+ (void *)rtl_ips_nic_off_wq_callback);
+ INIT_DELAYED_WORK(&rtlpriv->works.ps_work,
+ (void *)rtl_swlps_wq_callback);
+ INIT_DELAYED_WORK(&rtlpriv->works.ps_rfon_wq,
+ (void *)rtl_swlps_rfon_wq_callback);
+ INIT_DELAYED_WORK(&rtlpriv->works.fwevt_wq,
+ (void *)rtl_fwevt_wq_callback);
+ INIT_DELAYED_WORK(&rtlpriv->works.c2hcmd_wq,
+ (void *)rtl_c2hcmd_wq_callback);
+}
+
+void rtl_deinit_deferred_work(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ del_timer_sync(&rtlpriv->works.watchdog_timer);
+
+ cancel_delayed_work(&rtlpriv->works.watchdog_wq);
+ cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq);
+ cancel_delayed_work(&rtlpriv->works.ps_work);
+ cancel_delayed_work(&rtlpriv->works.ps_rfon_wq);
+ cancel_delayed_work(&rtlpriv->works.fwevt_wq);
+ cancel_delayed_work(&rtlpriv->works.c2hcmd_wq);
+}
+
+void rtl_init_rfkill(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ bool radio_state;
+ bool blocked;
+ u8 valid = 0;
+
+ /*set init state to on */
+ rtlpriv->rfkill.rfkill_state = true;
+ wiphy_rfkill_set_hw_state(hw->wiphy, 0);
+
+ radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);
+
+ if (valid) {
+ pr_info("rtlwifi: wireless switch is %s\n",
+ rtlpriv->rfkill.rfkill_state ? "on" : "off");
+
+ rtlpriv->rfkill.rfkill_state = radio_state;
+
+ blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1;
+ wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
+ }
+
+ wiphy_rfkill_start_polling(hw->wiphy);
+}
+
+void rtl_deinit_rfkill(struct ieee80211_hw *hw)
+{
+ wiphy_rfkill_stop_polling(hw->wiphy);
+}
+
+int rtl_init_core(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
+
+ /* <1> init mac80211 */
+ _rtl_init_mac80211(hw);
+ rtlmac->hw = hw;
+
+ /* <2> rate control register */
+ hw->rate_control_algorithm = "rtl_rc";
+
+ /*
+ * <3> init CRDA must come after init
+ * mac80211 hw in _rtl_init_mac80211.
+ */
+ if (rtl_regd_init(hw, rtl_reg_notifier)) {
+ pr_err("REGD init failed\n");
+ return 1;
+ }
+
+ /* <4> locks */
+ mutex_init(&rtlpriv->locks.conf_mutex);
+ mutex_init(&rtlpriv->locks.ips_mutex);
+ mutex_init(&rtlpriv->locks.lps_mutex);
+ spin_lock_init(&rtlpriv->locks.irq_th_lock);
+ spin_lock_init(&rtlpriv->locks.h2c_lock);
+ spin_lock_init(&rtlpriv->locks.rf_ps_lock);
+ spin_lock_init(&rtlpriv->locks.rf_lock);
+ spin_lock_init(&rtlpriv->locks.waitq_lock);
+ spin_lock_init(&rtlpriv->locks.entry_list_lock);
+ spin_lock_init(&rtlpriv->locks.c2hcmd_lock);
+ spin_lock_init(&rtlpriv->locks.scan_list_lock);
+ spin_lock_init(&rtlpriv->locks.cck_and_rw_pagea_lock);
+ spin_lock_init(&rtlpriv->locks.fw_ps_lock);
+ spin_lock_init(&rtlpriv->locks.iqk_lock);
+ /* <5> init list */
+ INIT_LIST_HEAD(&rtlpriv->entry_list);
+ INIT_LIST_HEAD(&rtlpriv->c2hcmd_list);
+ INIT_LIST_HEAD(&rtlpriv->scan_list.list);
+
+ rtlmac->link_state = MAC80211_NOLINK;
+
+ /* <6> init deferred work */
+ _rtl_init_deferred_work(hw);
+
+ return 0;
+}
+
+static void rtl_free_entries_from_scan_list(struct ieee80211_hw *hw);
+
+void rtl_deinit_core(struct ieee80211_hw *hw)
+{
+ rtl_c2hcmd_launcher(hw, 0);
+ rtl_free_entries_from_scan_list(hw);
+}
+
+void rtl_init_rx_config(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+ rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)&mac->rx_conf);
+}
+
+/*********************************************************
+ *
+ * tx information functions
+ *
+ *********************************************************/
+static void _rtl_qurey_shortpreamble_mode(struct ieee80211_hw *hw,
+ struct rtl_tcb_desc *tcb_desc,
+ struct ieee80211_tx_info *info)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 rate_flag = info->control.rates[0].flags;
+
+ tcb_desc->use_shortpreamble = false;
+
+ /* 1M can only use Long Preamble. 11B spec */
+ if (tcb_desc->hw_rate == rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M])
+ return;
+ else if (rate_flag & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+ tcb_desc->use_shortpreamble = true;
+}
+
+static void _rtl_query_shortgi(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
+ struct rtl_tcb_desc *tcb_desc,
+ struct ieee80211_tx_info *info)
+{
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ u8 rate_flag = info->control.rates[0].flags;
+ u8 sgi_40 = 0, sgi_20 = 0, bw_40 = 0;
+ u8 sgi_80 = 0, bw_80 = 0;
+
+ tcb_desc->use_shortgi = false;
+
+ if (!sta)
+ return;
+
+ sgi_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40;
+ sgi_20 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20;
+ sgi_80 = sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80;
+
+ if ((!sta->ht_cap.ht_supported) && (!sta->vht_cap.vht_supported))
+ return;
+
+ if (!sgi_40 && !sgi_20)
+ return;
+
+ if (mac->opmode == NL80211_IFTYPE_STATION) {
+ bw_40 = mac->bw_40;
+ bw_80 = mac->bw_80;
+ } else if (mac->opmode == NL80211_IFTYPE_AP ||
+ mac->opmode == NL80211_IFTYPE_ADHOC ||
+ mac->opmode == NL80211_IFTYPE_MESH_POINT) {
+ bw_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+ bw_80 = sta->vht_cap.vht_supported;
+ }
+
+ if (bw_80) {
+ if (sgi_80)
+ tcb_desc->use_shortgi = true;
+ else
+ tcb_desc->use_shortgi = false;
+ } else {
+ if (bw_40 && sgi_40)
+ tcb_desc->use_shortgi = true;
+ else if (!bw_40 && sgi_20)
+ tcb_desc->use_shortgi = true;
+ }
+
+ if (!(rate_flag & IEEE80211_TX_RC_SHORT_GI))
+ tcb_desc->use_shortgi = false;
+}
+
+static void _rtl_query_protection_mode(struct ieee80211_hw *hw,
+ struct rtl_tcb_desc *tcb_desc,
+ struct ieee80211_tx_info *info)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 rate_flag = info->control.rates[0].flags;
+
+ /* Common Settings */
+ tcb_desc->rts_stbc = false;
+ tcb_desc->cts_enable = false;
+ tcb_desc->rts_sc = 0;
+ tcb_desc->rts_bw = false;
+ tcb_desc->rts_use_shortpreamble = false;
+ tcb_desc->rts_use_shortgi = false;
+
+ if (rate_flag & IEEE80211_TX_RC_USE_CTS_PROTECT) {
+ /* Use CTS-to-SELF in protection mode. */
+ tcb_desc->rts_enable = true;
+ tcb_desc->cts_enable = true;
+ tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M];
+ } else if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) {
+ /* Use RTS-CTS in protection mode. */
+ tcb_desc->rts_enable = true;
+ tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M];
+ }
+}
+
+u8 rtl_mrate_idx_to_arfr_id(
+ struct ieee80211_hw *hw, u8 rate_index,
+ enum wireless_mode wirelessmode)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ u8 ret = 0;
+
+ switch (rate_index) {
+ case RATR_INX_WIRELESS_NGB:
+ if (rtlphy->rf_type == RF_1T1R)
+ ret = RATEID_IDX_BGN_40M_1SS;
+ else
+ ret = RATEID_IDX_BGN_40M_2SS;
+ ; break;
+ case RATR_INX_WIRELESS_N:
+ case RATR_INX_WIRELESS_NG:
+ if (rtlphy->rf_type == RF_1T1R)
+ ret = RATEID_IDX_GN_N1SS;
+ else
+ ret = RATEID_IDX_GN_N2SS;
+ ; break;
+ case RATR_INX_WIRELESS_NB:
+ if (rtlphy->rf_type == RF_1T1R)
+ ret = RATEID_IDX_BGN_20M_1SS_BN;
+ else
+ ret = RATEID_IDX_BGN_20M_2SS_BN;
+ ; break;
+ case RATR_INX_WIRELESS_GB:
+ ret = RATEID_IDX_BG;
+ break;
+ case RATR_INX_WIRELESS_G:
+ ret = RATEID_IDX_G;
+ break;
+ case RATR_INX_WIRELESS_B:
+ ret = RATEID_IDX_B;
+ break;
+ case RATR_INX_WIRELESS_MC:
+ if ((wirelessmode == WIRELESS_MODE_B) ||
+ (wirelessmode == WIRELESS_MODE_G) ||
+ (wirelessmode == WIRELESS_MODE_N_24G) ||
+ (wirelessmode == WIRELESS_MODE_AC_24G))
+ ret = RATEID_IDX_BG;
+ else
+ ret = RATEID_IDX_G;
+ break;
+ case RATR_INX_WIRELESS_AC_5N:
+ if (rtlphy->rf_type == RF_1T1R)
+ ret = RATEID_IDX_VHT_1SS;
+ else
+ ret = RATEID_IDX_VHT_2SS;
+ break;
+ case RATR_INX_WIRELESS_AC_24N:
+ if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) {
+ if (rtlphy->rf_type == RF_1T1R)
+ ret = RATEID_IDX_VHT_1SS;
+ else
+ ret = RATEID_IDX_VHT_2SS;
+ } else {
+ if (rtlphy->rf_type == RF_1T1R)
+ ret = RATEID_IDX_MIX1;
+ else
+ ret = RATEID_IDX_MIX2;
+ }
+ break;
+ default:
+ ret = RATEID_IDX_BGN_40M_2SS;
+ break;
+ }
+ return ret;
+}
+
+static void _rtl_txrate_selectmode(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
+ struct rtl_tcb_desc *tcb_desc)
+{
+#define SET_RATE_ID(rate_id) \
+ ((rtlpriv->cfg->spec_ver & RTL_SPEC_NEW_RATEID) ? \
+ rtl_mrate_idx_to_arfr_id(hw, rate_id, \
+ (sta_entry ? sta_entry->wireless_mode : \
+ WIRELESS_MODE_G)) : \
+ rate_id)
+
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_sta_info *sta_entry = NULL;
+ u8 ratr_index = SET_RATE_ID(RATR_INX_WIRELESS_MC);
+
+ if (sta) {
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+ ratr_index = sta_entry->ratr_index;
+ }
+ if (!tcb_desc->disable_ratefallback || !tcb_desc->use_driver_rate) {
+ if (mac->opmode == NL80211_IFTYPE_STATION) {
+ tcb_desc->ratr_index = 0;
+ } else if (mac->opmode == NL80211_IFTYPE_ADHOC ||
+ mac->opmode == NL80211_IFTYPE_MESH_POINT) {
+ if (tcb_desc->multicast || tcb_desc->broadcast) {
+ tcb_desc->hw_rate =
+ rtlpriv->cfg->maps[RTL_RC_CCK_RATE2M];
+ tcb_desc->use_driver_rate = 1;
+ tcb_desc->ratr_index =
+ SET_RATE_ID(RATR_INX_WIRELESS_MC);
+ } else {
+ tcb_desc->ratr_index = ratr_index;
+ }
+ } else if (mac->opmode == NL80211_IFTYPE_AP) {
+ tcb_desc->ratr_index = ratr_index;
+ }
+ }
+
+ if (rtlpriv->dm.useramask) {
+ tcb_desc->ratr_index = ratr_index;
+ /* TODO we will differentiate adhoc and station future */
+ if (mac->opmode == NL80211_IFTYPE_STATION ||
+ mac->opmode == NL80211_IFTYPE_MESH_POINT) {
+ tcb_desc->mac_id = 0;
+
+ if (sta &&
+ (rtlpriv->cfg->spec_ver & RTL_SPEC_NEW_RATEID))
+ ; /* use sta_entry->ratr_index */
+ else if (mac->mode == WIRELESS_MODE_AC_5G)
+ tcb_desc->ratr_index =
+ SET_RATE_ID(RATR_INX_WIRELESS_AC_5N);
+ else if (mac->mode == WIRELESS_MODE_AC_24G)
+ tcb_desc->ratr_index =
+ SET_RATE_ID(RATR_INX_WIRELESS_AC_24N);
+ else if (mac->mode == WIRELESS_MODE_N_24G)
+ tcb_desc->ratr_index =
+ SET_RATE_ID(RATR_INX_WIRELESS_NGB);
+ else if (mac->mode == WIRELESS_MODE_N_5G)
+ tcb_desc->ratr_index =
+ SET_RATE_ID(RATR_INX_WIRELESS_NG);
+ else if (mac->mode & WIRELESS_MODE_G)
+ tcb_desc->ratr_index =
+ SET_RATE_ID(RATR_INX_WIRELESS_GB);
+ else if (mac->mode & WIRELESS_MODE_B)
+ tcb_desc->ratr_index =
+ SET_RATE_ID(RATR_INX_WIRELESS_B);
+ else if (mac->mode & WIRELESS_MODE_A)
+ tcb_desc->ratr_index =
+ SET_RATE_ID(RATR_INX_WIRELESS_G);
+
+ } else if (mac->opmode == NL80211_IFTYPE_AP ||
+ mac->opmode == NL80211_IFTYPE_ADHOC) {
+ if (sta) {
+ if (sta->aid > 0)
+ tcb_desc->mac_id = sta->aid + 1;
+ else
+ tcb_desc->mac_id = 1;
+ } else {
+ tcb_desc->mac_id = 0;
+ }
+ }
+ }
+#undef SET_RATE_ID
+}
+
+static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
+ struct rtl_tcb_desc *tcb_desc)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+ tcb_desc->packet_bw = false;
+ if (!sta)
+ return;
+ if (mac->opmode == NL80211_IFTYPE_AP ||
+ mac->opmode == NL80211_IFTYPE_ADHOC ||
+ mac->opmode == NL80211_IFTYPE_MESH_POINT) {
+ if (!(sta->ht_cap.ht_supported) ||
+ !(sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40))
+ return;
+ } else if (mac->opmode == NL80211_IFTYPE_STATION) {
+ if (!mac->bw_40 || !(sta->ht_cap.ht_supported))
+ return;
+ }
+ if (tcb_desc->multicast || tcb_desc->broadcast)
+ return;
+
+ /*use legency rate, shall use 20MHz */
+ if (tcb_desc->hw_rate <= rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M])
+ return;
+
+ tcb_desc->packet_bw = HT_CHANNEL_WIDTH_20_40;
+
+ if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE ||
+ rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8821AE ||
+ (rtlpriv->cfg->spec_ver & RTL_SPEC_SUPPORT_VHT)) {
+ if (mac->opmode == NL80211_IFTYPE_AP ||
+ mac->opmode == NL80211_IFTYPE_ADHOC ||
+ mac->opmode == NL80211_IFTYPE_MESH_POINT) {
+ if (!(sta->vht_cap.vht_supported))
+ return;
+ } else if (mac->opmode == NL80211_IFTYPE_STATION) {
+ if (!mac->bw_80 ||
+ !(sta->vht_cap.vht_supported))
+ return;
+ }
+ if (tcb_desc->hw_rate <=
+ rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS15])
+ return;
+ tcb_desc->packet_bw = HT_CHANNEL_WIDTH_80;
+ }
+}
+
+static u8 _rtl_get_vht_highest_n_rate(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ u8 hw_rate;
+ u16 tx_mcs_map = le16_to_cpu(sta->vht_cap.vht_mcs.tx_mcs_map);
+
+ if ((get_rf_type(rtlphy) == RF_2T2R) &&
+ (tx_mcs_map & 0x000c) != 0x000c) {
+ if ((tx_mcs_map & 0x000c) >> 2 ==
+ IEEE80211_VHT_MCS_SUPPORT_0_7)
+ hw_rate =
+ rtlpriv->cfg->maps[RTL_RC_VHT_RATE_2SS_MCS7];
+ else if ((tx_mcs_map & 0x000c) >> 2 ==
+ IEEE80211_VHT_MCS_SUPPORT_0_8)
+ hw_rate =
+ rtlpriv->cfg->maps[RTL_RC_VHT_RATE_2SS_MCS9];
+ else
+ hw_rate =
+ rtlpriv->cfg->maps[RTL_RC_VHT_RATE_2SS_MCS9];
+ } else {
+ if ((tx_mcs_map & 0x0003) ==
+ IEEE80211_VHT_MCS_SUPPORT_0_7)
+ hw_rate =
+ rtlpriv->cfg->maps[RTL_RC_VHT_RATE_1SS_MCS7];
+ else if ((tx_mcs_map & 0x0003) ==
+ IEEE80211_VHT_MCS_SUPPORT_0_8)
+ hw_rate =
+ rtlpriv->cfg->maps[RTL_RC_VHT_RATE_1SS_MCS9];
+ else
+ hw_rate =
+ rtlpriv->cfg->maps[RTL_RC_VHT_RATE_1SS_MCS9];
+ }
+
+ return hw_rate;
+}
+
+static u8 _rtl_get_highest_n_rate(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ u8 hw_rate;
+
+ if ((get_rf_type(rtlphy) == RF_2T2R) &&
+ (sta->ht_cap.mcs.rx_mask[1] != 0))
+ hw_rate = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS15];
+ else
+ hw_rate = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS7];
+
+ return hw_rate;
+}
+
+/* mac80211's rate_idx is like this:
+ *
+ * 2.4G band:rx_status->band == NL80211_BAND_2GHZ
+ *
+ * B/G rate:
+ * (rx_status->flag & RX_FLAG_HT) = 0,
+ * DESC_RATE1M-->DESC_RATE54M ==> idx is 0-->11,
+ *
+ * N rate:
+ * (rx_status->flag & RX_FLAG_HT) = 1,
+ * DESC_RATEMCS0-->DESC_RATEMCS15 ==> idx is 0-->15
+ *
+ * 5G band:rx_status->band == NL80211_BAND_5GHZ
+ * A rate:
+ * (rx_status->flag & RX_FLAG_HT) = 0,
+ * DESC_RATE6M-->DESC_RATE54M ==> idx is 0-->7,
+ *
+ * N rate:
+ * (rx_status->flag & RX_FLAG_HT) = 1,
+ * DESC_RATEMCS0-->DESC_RATEMCS15 ==> idx is 0-->15
+ *
+ * VHT rates:
+ * DESC_RATEVHT1SS_MCS0-->DESC_RATEVHT1SS_MCS9 ==> idx is 0-->9
+ * DESC_RATEVHT2SS_MCS0-->DESC_RATEVHT2SS_MCS9 ==> idx is 0-->9
+ */
+int rtlwifi_rate_mapping(struct ieee80211_hw *hw, bool isht, bool isvht,
+ u8 desc_rate)
+{
+ int rate_idx;
+
+ if (isvht) {
+ switch (desc_rate) {
+ case DESC_RATEVHT1SS_MCS0:
+ rate_idx = 0;
+ break;
+ case DESC_RATEVHT1SS_MCS1:
+ rate_idx = 1;
+ break;
+ case DESC_RATEVHT1SS_MCS2:
+ rate_idx = 2;
+ break;
+ case DESC_RATEVHT1SS_MCS3:
+ rate_idx = 3;
+ break;
+ case DESC_RATEVHT1SS_MCS4:
+ rate_idx = 4;
+ break;
+ case DESC_RATEVHT1SS_MCS5:
+ rate_idx = 5;
+ break;
+ case DESC_RATEVHT1SS_MCS6:
+ rate_idx = 6;
+ break;
+ case DESC_RATEVHT1SS_MCS7:
+ rate_idx = 7;
+ break;
+ case DESC_RATEVHT1SS_MCS8:
+ rate_idx = 8;
+ break;
+ case DESC_RATEVHT1SS_MCS9:
+ rate_idx = 9;
+ break;
+ case DESC_RATEVHT2SS_MCS0:
+ rate_idx = 0;
+ break;
+ case DESC_RATEVHT2SS_MCS1:
+ rate_idx = 1;
+ break;
+ case DESC_RATEVHT2SS_MCS2:
+ rate_idx = 2;
+ break;
+ case DESC_RATEVHT2SS_MCS3:
+ rate_idx = 3;
+ break;
+ case DESC_RATEVHT2SS_MCS4:
+ rate_idx = 4;
+ break;
+ case DESC_RATEVHT2SS_MCS5:
+ rate_idx = 5;
+ break;
+ case DESC_RATEVHT2SS_MCS6:
+ rate_idx = 6;
+ break;
+ case DESC_RATEVHT2SS_MCS7:
+ rate_idx = 7;
+ break;
+ case DESC_RATEVHT2SS_MCS8:
+ rate_idx = 8;
+ break;
+ case DESC_RATEVHT2SS_MCS9:
+ rate_idx = 9;
+ break;
+ default:
+ rate_idx = 0;
+ break;
+ }
+ return rate_idx;
+ }
+ if (!isht) {
+ if (hw->conf.chandef.chan->band == NL80211_BAND_2GHZ) {
+ switch (desc_rate) {
+ case DESC_RATE1M:
+ rate_idx = 0;
+ break;
+ case DESC_RATE2M:
+ rate_idx = 1;
+ break;
+ case DESC_RATE5_5M:
+ rate_idx = 2;
+ break;
+ case DESC_RATE11M:
+ rate_idx = 3;
+ break;
+ case DESC_RATE6M:
+ rate_idx = 4;
+ break;
+ case DESC_RATE9M:
+ rate_idx = 5;
+ break;
+ case DESC_RATE12M:
+ rate_idx = 6;
+ break;
+ case DESC_RATE18M:
+ rate_idx = 7;
+ break;
+ case DESC_RATE24M:
+ rate_idx = 8;
+ break;
+ case DESC_RATE36M:
+ rate_idx = 9;
+ break;
+ case DESC_RATE48M:
+ rate_idx = 10;
+ break;
+ case DESC_RATE54M:
+ rate_idx = 11;
+ break;
+ default:
+ rate_idx = 0;
+ break;
+ }
+ } else {
+ switch (desc_rate) {
+ case DESC_RATE6M:
+ rate_idx = 0;
+ break;
+ case DESC_RATE9M:
+ rate_idx = 1;
+ break;
+ case DESC_RATE12M:
+ rate_idx = 2;
+ break;
+ case DESC_RATE18M:
+ rate_idx = 3;
+ break;
+ case DESC_RATE24M:
+ rate_idx = 4;
+ break;
+ case DESC_RATE36M:
+ rate_idx = 5;
+ break;
+ case DESC_RATE48M:
+ rate_idx = 6;
+ break;
+ case DESC_RATE54M:
+ rate_idx = 7;
+ break;
+ default:
+ rate_idx = 0;
+ break;
+ }
+ }
+ } else {
+ switch (desc_rate) {
+ case DESC_RATEMCS0:
+ rate_idx = 0;
+ break;
+ case DESC_RATEMCS1:
+ rate_idx = 1;
+ break;
+ case DESC_RATEMCS2:
+ rate_idx = 2;
+ break;
+ case DESC_RATEMCS3:
+ rate_idx = 3;
+ break;
+ case DESC_RATEMCS4:
+ rate_idx = 4;
+ break;
+ case DESC_RATEMCS5:
+ rate_idx = 5;
+ break;
+ case DESC_RATEMCS6:
+ rate_idx = 6;
+ break;
+ case DESC_RATEMCS7:
+ rate_idx = 7;
+ break;
+ case DESC_RATEMCS8:
+ rate_idx = 8;
+ break;
+ case DESC_RATEMCS9:
+ rate_idx = 9;
+ break;
+ case DESC_RATEMCS10:
+ rate_idx = 10;
+ break;
+ case DESC_RATEMCS11:
+ rate_idx = 11;
+ break;
+ case DESC_RATEMCS12:
+ rate_idx = 12;
+ break;
+ case DESC_RATEMCS13:
+ rate_idx = 13;
+ break;
+ case DESC_RATEMCS14:
+ rate_idx = 14;
+ break;
+ case DESC_RATEMCS15:
+ rate_idx = 15;
+ break;
+ default:
+ rate_idx = 0;
+ break;
+ }
+ }
+ return rate_idx;
+}
+
+static u8 _rtl_get_tx_hw_rate(struct ieee80211_hw *hw,
+ struct ieee80211_tx_info *info)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct ieee80211_tx_rate *r = &info->status.rates[0];
+ struct ieee80211_rate *txrate;
+ u8 hw_value = 0x0;
+
+ if (r->flags & IEEE80211_TX_RC_MCS) {
+ /* HT MCS0-15 */
+ hw_value = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS15] - 15 +
+ r->idx;
+ } else if (r->flags & IEEE80211_TX_RC_VHT_MCS) {
+ /* VHT MCS0-9, NSS */
+ if (ieee80211_rate_get_vht_nss(r) == 2)
+ hw_value = rtlpriv->cfg->maps[RTL_RC_VHT_RATE_2SS_MCS9];
+ else
+ hw_value = rtlpriv->cfg->maps[RTL_RC_VHT_RATE_1SS_MCS9];
+
+ hw_value = hw_value - 9 + ieee80211_rate_get_vht_mcs(r);
+ } else {
+ /* legacy */
+ txrate = ieee80211_get_tx_rate(hw, info);
+
+ if (txrate)
+ hw_value = txrate->hw_value;
+ }
+
+ /* check 5G band */
+ if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G &&
+ hw_value < rtlpriv->cfg->maps[RTL_RC_OFDM_RATE6M])
+ hw_value = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE6M];
+
+ return hw_value;
+}
+
+void rtl_get_tcb_desc(struct ieee80211_hw *hw,
+ struct ieee80211_tx_info *info,
+ struct ieee80211_sta *sta,
+ struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc)
+{
+#define SET_RATE_ID(rate_id) \
+ ((rtlpriv->cfg->spec_ver & RTL_SPEC_NEW_RATEID) ? \
+ rtl_mrate_idx_to_arfr_id(hw, rate_id, \
+ (sta_entry ? sta_entry->wireless_mode : \
+ WIRELESS_MODE_G)) : \
+ rate_id)
+
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
+ struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
+ struct rtl_sta_info *sta_entry =
+ (sta ? (struct rtl_sta_info *)sta->drv_priv : NULL);
+
+ __le16 fc = rtl_get_fc(skb);
+
+ tcb_desc->hw_rate = _rtl_get_tx_hw_rate(hw, info);
+
+ if (rtl_is_tx_report_skb(hw, skb))
+ tcb_desc->use_spe_rpt = 1;
+
+ if (ieee80211_is_data(fc)) {
+ /*
+ *we set data rate INX 0
+ *in rtl_rc.c if skb is special data or
+ *mgt which need low data rate.
+ */
+
+ /*
+ *So tcb_desc->hw_rate is just used for
+ *special data and mgt frames
+ */
+ if (info->control.rates[0].idx == 0 ||
+ ieee80211_is_nullfunc(fc)) {
+ tcb_desc->use_driver_rate = true;
+ tcb_desc->ratr_index =
+ SET_RATE_ID(RATR_INX_WIRELESS_MC);
+
+ tcb_desc->disable_ratefallback = 1;
+ } else {
+ /* because hw will never use hw_rate
+ * when tcb_desc->use_driver_rate = false
+ * so we never set highest N rate here,
+ * and N rate will all be controlled by FW
+ * when tcb_desc->use_driver_rate = false
+ */
+ if (sta && sta->vht_cap.vht_supported) {
+ tcb_desc->hw_rate =
+ _rtl_get_vht_highest_n_rate(hw, sta);
+ } else {
+ if (sta && (sta->ht_cap.ht_supported)) {
+ tcb_desc->hw_rate =
+ _rtl_get_highest_n_rate(hw, sta);
+ } else {
+ if (rtlmac->mode == WIRELESS_MODE_B) {
+ tcb_desc->hw_rate =
+ rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M];
+ } else {
+ tcb_desc->hw_rate =
+ rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M];
+ }
+ }
+ }
+ }
+
+ if (is_multicast_ether_addr(hdr->addr1))
+ tcb_desc->multicast = 1;
+ else if (is_broadcast_ether_addr(hdr->addr1))
+ tcb_desc->broadcast = 1;
+
+ _rtl_txrate_selectmode(hw, sta, tcb_desc);
+ _rtl_query_bandwidth_mode(hw, sta, tcb_desc);
+ _rtl_qurey_shortpreamble_mode(hw, tcb_desc, info);
+ _rtl_query_shortgi(hw, sta, tcb_desc, info);
+ _rtl_query_protection_mode(hw, tcb_desc, info);
+ } else {
+ tcb_desc->use_driver_rate = true;
+ tcb_desc->ratr_index = SET_RATE_ID(RATR_INX_WIRELESS_MC);
+ tcb_desc->disable_ratefallback = 1;
+ tcb_desc->mac_id = 0;
+ tcb_desc->packet_bw = false;
+ }
+#undef SET_RATE_ID
+}
+
+bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ __le16 fc = rtl_get_fc(skb);
+
+ if (rtlpriv->dm.supp_phymode_switch &&
+ mac->link_state < MAC80211_LINKED &&
+ (ieee80211_is_auth(fc) || ieee80211_is_probe_req(fc))) {
+ if (rtlpriv->cfg->ops->chk_switch_dmdp)
+ rtlpriv->cfg->ops->chk_switch_dmdp(hw);
+ }
+ if (ieee80211_is_auth(fc)) {
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n");
+
+ mac->link_state = MAC80211_LINKING;
+ /* Dul mac */
+ rtlpriv->phy.need_iqk = true;
+ }
+ return true;
+}
+
+struct sk_buff *rtl_make_del_ba(struct ieee80211_hw *hw, u8 *sa,
+ u8 *bssid, u16 tid);
+
+static void process_agg_start(struct ieee80211_hw *hw,
+ struct ieee80211_hdr *hdr, u16 tid)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct ieee80211_rx_status rx_status = { 0 };
+ struct sk_buff *skb_delba = NULL;
+
+ skb_delba = rtl_make_del_ba(hw, hdr->addr2, hdr->addr3, tid);
+ if (skb_delba) {
+ rx_status.freq = hw->conf.chandef.chan->center_freq;
+ rx_status.band = hw->conf.chandef.chan->band;
+ rx_status.flag |= RX_FLAG_DECRYPTED;
+ rx_status.flag |= RX_FLAG_MACTIME_START;
+ rx_status.rate_idx = 0;
+ rx_status.signal = 50 + 10;
+ memcpy(IEEE80211_SKB_RXCB(skb_delba),
+ &rx_status, sizeof(rx_status));
+ RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG,
+ "fake del\n",
+ skb_delba->data,
+ skb_delba->len);
+ ieee80211_rx_irqsafe(hw, skb_delba);
+ }
+}
+
+bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
+{
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ __le16 fc = rtl_get_fc(skb);
+ u8 *act = (u8 *)(((u8 *)skb->data + MAC80211_3ADDR_LEN));
+ u8 category;
+
+ if (!ieee80211_is_action(fc))
+ return true;
+
+ category = *act;
+ act++;
+ switch (category) {
+ case ACT_CAT_BA:
+ switch (*act) {
+ case ACT_ADDBAREQ:
+ if (mac->act_scanning)
+ return false;
+
+ RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
+ "%s ACT_ADDBAREQ From :%pM\n",
+ is_tx ? "Tx" : "Rx", hdr->addr2);
+ RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "req\n",
+ skb->data, skb->len);
+ if (!is_tx) {
+ struct ieee80211_sta *sta = NULL;
+ struct rtl_sta_info *sta_entry = NULL;
+ struct rtl_tid_data *tid_data;
+ struct ieee80211_mgmt *mgmt = (void *)skb->data;
+ u16 capab = 0, tid = 0;
+
+ rcu_read_lock();
+ sta = rtl_find_sta(hw, hdr->addr3);
+ if (!sta) {
+ RT_TRACE(rtlpriv, COMP_SEND | COMP_RECV,
+ DBG_DMESG, "sta is NULL\n");
+ rcu_read_unlock();
+ return true;
+ }
+
+ sta_entry =
+ (struct rtl_sta_info *)sta->drv_priv;
+ if (!sta_entry) {
+ rcu_read_unlock();
+ return true;
+ }
+ capab =
+ le16_to_cpu(mgmt->u.action.u.addba_req.capab);
+ tid = (capab &
+ IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
+ if (tid >= MAX_TID_COUNT) {
+ rcu_read_unlock();
+ return true;
+ }
+ tid_data = &sta_entry->tids[tid];
+ if (tid_data->agg.rx_agg_state ==
+ RTL_RX_AGG_START)
+ process_agg_start(hw, hdr, tid);
+ rcu_read_unlock();
+ }
+ break;
+ case ACT_ADDBARSP:
+ RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
+ "%s ACT_ADDBARSP From :%pM\n",
+ is_tx ? "Tx" : "Rx", hdr->addr2);
+ break;
+ case ACT_DELBA:
+ RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
+ "ACT_ADDBADEL From :%pM\n", hdr->addr2);
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return true;
+}
+
+static void setup_special_tx(struct rtl_priv *rtlpriv, struct rtl_ps_ctl *ppsc,
+ int type)
+{
+ struct ieee80211_hw *hw = rtlpriv->hw;
+
+ rtlpriv->ra.is_special_data = true;
+ if (rtlpriv->cfg->ops->get_btc_status())
+ rtlpriv->btcoexist.btc_ops->btc_special_packet_notify(
+ rtlpriv, type);
+ rtl_lps_leave(hw);
+ ppsc->last_delaylps_stamp_jiffies = jiffies;
+}
+
+static const u8 *rtl_skb_ether_type_ptr(struct ieee80211_hw *hw,
+ struct sk_buff *skb, bool is_enc)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 mac_hdr_len = ieee80211_get_hdrlen_from_skb(skb);
+ u8 encrypt_header_len = 0;
+ u8 offset;
+
+ switch (rtlpriv->sec.pairwise_enc_algorithm) {
+ case WEP40_ENCRYPTION:
+ case WEP104_ENCRYPTION:
+ encrypt_header_len = 4;/*WEP_IV_LEN*/
+ break;
+ case TKIP_ENCRYPTION:
+ encrypt_header_len = 8;/*TKIP_IV_LEN*/
+ break;
+ case AESCCMP_ENCRYPTION:
+ encrypt_header_len = 8;/*CCMP_HDR_LEN;*/
+ break;
+ default:
+ break;
+ }
+
+ offset = mac_hdr_len + SNAP_SIZE;
+ if (is_enc)
+ offset += encrypt_header_len;
+
+ return skb->data + offset;
+}
+
+/*should call before software enc*/
+u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx,
+ bool is_enc)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ __le16 fc = rtl_get_fc(skb);
+ u16 ether_type;
+ const u8 *ether_type_ptr;
+ const struct iphdr *ip;
+
+ if (!ieee80211_is_data(fc))
+ goto end;
+
+ ether_type_ptr = rtl_skb_ether_type_ptr(hw, skb, is_enc);
+ ether_type = be16_to_cpup((__be16 *)ether_type_ptr);
+
+ if (ether_type == ETH_P_IP) {
+ ip = (struct iphdr *)((u8 *)ether_type_ptr +
+ PROTOC_TYPE_SIZE);
+ if (ip->protocol == IPPROTO_UDP) {
+ struct udphdr *udp = (struct udphdr *)((u8 *)ip +
+ (ip->ihl << 2));
+ if (((((u8 *)udp)[1] == 68) &&
+ (((u8 *)udp)[3] == 67)) ||
+ ((((u8 *)udp)[1] == 67) &&
+ (((u8 *)udp)[3] == 68))) {
+ /* 68 : UDP BOOTP client
+ * 67 : UDP BOOTP server
+ */
+ RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV),
+ DBG_DMESG, "dhcp %s !!\n",
+ (is_tx) ? "Tx" : "Rx");
+
+ if (is_tx)
+ setup_special_tx(rtlpriv, ppsc,
+ PACKET_DHCP);
+
+ return true;
+ }
+ }
+ } else if (ether_type == ETH_P_ARP) {
+ if (is_tx)
+ setup_special_tx(rtlpriv, ppsc, PACKET_ARP);
+
+ return true;
+ } else if (ether_type == ETH_P_PAE) {
+ /* EAPOL is seen as in-4way */
+ rtlpriv->btcoexist.btc_info.in_4way = true;
+ rtlpriv->btcoexist.btc_info.in_4way_ts = jiffies;
+ rtlpriv->btcoexist.btc_info.in_4way_ts = jiffies;
+
+ RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
+ "802.1X %s EAPOL pkt!!\n", (is_tx) ? "Tx" : "Rx");
+
+ if (is_tx) {
+ rtlpriv->ra.is_special_data = true;
+ rtl_lps_leave(hw);
+ ppsc->last_delaylps_stamp_jiffies = jiffies;
+
+ setup_special_tx(rtlpriv, ppsc, PACKET_EAPOL);
+ }
+
+ return true;
+ } else if (ether_type == ETH_P_IPV6) {
+ /* TODO: Handle any IPv6 cases that need special handling.
+ * For now, always return false
+ */
+ goto end;
+ }
+
+end:
+ rtlpriv->ra.is_special_data = false;
+ return false;
+}
+
+bool rtl_is_tx_report_skb(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ u16 ether_type;
+ const u8 *ether_type_ptr;
+
+ ether_type_ptr = rtl_skb_ether_type_ptr(hw, skb, true);
+ ether_type = be16_to_cpup((__be16 *)ether_type_ptr);
+
+ /* EAPOL */
+ if (ether_type == ETH_P_PAE)
+ return true;
+
+ return false;
+}
+
+static u16 rtl_get_tx_report_sn(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_tx_report *tx_report = &rtlpriv->tx_report;
+ u16 sn;
+
+ /*
+ * SW_DEFINE[11:8] are reserved (driver fills zeros)
+ * SW_DEFINE[7:2] are used by driver
+ * SW_DEFINE[1:0] are reserved for firmware (driver fills zeros)
+ */
+ sn = (atomic_inc_return(&tx_report->sn) & 0x003F) << 2;
+
+ tx_report->last_sent_sn = sn;
+ tx_report->last_sent_time = jiffies;
+
+ RT_TRACE(rtlpriv, COMP_TX_REPORT, DBG_DMESG,
+ "Send TX-Report sn=0x%X\n", sn);
+
+ return sn;
+}
+
+void rtl_get_tx_report(struct rtl_tcb_desc *ptcb_desc, u8 *pdesc,
+ struct ieee80211_hw *hw)
+{
+ if (ptcb_desc->use_spe_rpt) {
+ u16 sn = rtl_get_tx_report_sn(hw);
+
+ SET_TX_DESC_SPE_RPT(pdesc, 1);
+ SET_TX_DESC_SW_DEFINE(pdesc, sn);
+ }
+}
+
+void rtl_tx_report_handler(struct ieee80211_hw *hw, u8 *tmp_buf, u8 c2h_cmd_len)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_tx_report *tx_report = &rtlpriv->tx_report;
+ u16 sn;
+ u8 st, retry;
+
+ if (rtlpriv->cfg->spec_ver & RTL_SPEC_NEW_FW_C2H) {
+ sn = tmp_buf[6];
+ st = tmp_buf[7] & 0xC0;
+ retry = tmp_buf[8] & 0x3F;
+ } else {
+ sn = ((tmp_buf[7] & 0x0F) << 8) | tmp_buf[6];
+ st = tmp_buf[0] & 0xC0;
+ retry = tmp_buf[2] & 0x3F;
+ }
+
+ tx_report->last_recv_sn = sn;
+
+ RT_TRACE(rtlpriv, COMP_TX_REPORT, DBG_DMESG,
+ "Recv TX-Report st=0x%02X sn=0x%X retry=0x%X\n",
+ st, sn, retry);
+}
+
+bool rtl_check_tx_report_acked(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_tx_report *tx_report = &rtlpriv->tx_report;
+
+ if (tx_report->last_sent_sn == tx_report->last_recv_sn)
+ return true;
+
+ if (time_before(tx_report->last_sent_time + 3 * HZ, jiffies)) {
+ RT_TRACE(rtlpriv, COMP_TX_REPORT, DBG_WARNING,
+ "Check TX-Report timeout!! s_sn=0x%X r_sn=0x%X\n",
+ tx_report->last_sent_sn, tx_report->last_recv_sn);
+ return true; /* 3 sec. (timeout) seen as acked */
+ }
+
+ return false;
+}
+
+void rtl_wait_tx_report_acked(struct ieee80211_hw *hw, u32 wait_ms)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ int i;
+
+ for (i = 0; i < wait_ms; i++) {
+ if (rtl_check_tx_report_acked(hw))
+ break;
+ usleep_range(1000, 2000);
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ "Wait 1ms (%d/%d) to disable key.\n", i, wait_ms);
+ }
+}
+
+u32 rtl_get_hal_edca_param(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum wireless_mode wirelessmode,
+ struct ieee80211_tx_queue_params *param)
+{
+ u32 reg = 0;
+ u8 sifstime = 10;
+ u8 slottime = 20;
+
+ /* AIFS = AIFSN * slot time + SIFS */
+ switch (wirelessmode) {
+ case WIRELESS_MODE_A:
+ case WIRELESS_MODE_N_24G:
+ case WIRELESS_MODE_N_5G:
+ case WIRELESS_MODE_AC_5G:
+ case WIRELESS_MODE_AC_24G:
+ sifstime = 16;
+ slottime = 9;
+ break;
+ case WIRELESS_MODE_G:
+ slottime = (vif->bss_conf.use_short_slot ? 9 : 20);
+ break;
+ default:
+ break;
+ }
+
+ reg |= (param->txop & 0x7FF) << 16;
+ reg |= (fls(param->cw_max) & 0xF) << 12;
+ reg |= (fls(param->cw_min) & 0xF) << 8;
+ reg |= (param->aifs & 0x0F) * slottime + sifstime;
+
+ return reg;
+}
+
+/*********************************************************
+ *
+ * functions called by core.c
+ *
+ *********************************************************/
+int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta, u16 tid, u16 *ssn)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_tid_data *tid_data;
+ struct rtl_sta_info *sta_entry = NULL;
+
+ if (!sta)
+ return -EINVAL;
+
+ if (unlikely(tid >= MAX_TID_COUNT))
+ return -EINVAL;
+
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+ if (!sta_entry)
+ return -ENXIO;
+ tid_data = &sta_entry->tids[tid];
+
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
+ "on ra = %pM tid = %d seq:%d\n", sta->addr, tid,
+ tid_data->seq_number);
+
+ *ssn = tid_data->seq_number;
+ tid_data->agg.agg_state = RTL_AGG_START;
+
+ ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+ return 0;
+}
+
+int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta, u16 tid)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_tid_data *tid_data;
+ struct rtl_sta_info *sta_entry = NULL;
+
+ if (!sta)
+ return -EINVAL;
+
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
+ "on ra = %pM tid = %d\n", sta->addr, tid);
+
+ if (unlikely(tid >= MAX_TID_COUNT))
+ return -EINVAL;
+
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+ tid_data = &sta_entry->tids[tid];
+ sta_entry->tids[tid].agg.agg_state = RTL_AGG_STOP;
+
+ ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+ return 0;
+}
+
+int rtl_rx_agg_start(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u16 tid)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_tid_data *tid_data;
+ struct rtl_sta_info *sta_entry = NULL;
+ u8 reject_agg;
+
+ if (!sta)
+ return -EINVAL;
+
+ if (unlikely(tid >= MAX_TID_COUNT))
+ return -EINVAL;
+
+ if (rtlpriv->cfg->ops->get_btc_status()) {
+ rtlpriv->btcoexist.btc_ops->btc_get_ampdu_cfg(rtlpriv,
+ &reject_agg,
+ NULL, NULL);
+ if (reject_agg)
+ return -EINVAL;
+ }
+
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+ if (!sta_entry)
+ return -ENXIO;
+ tid_data = &sta_entry->tids[tid];
+
+ RT_TRACE(rtlpriv, COMP_RECV, DBG_DMESG,
+ "on ra = %pM tid = %d seq:%d\n", sta->addr, tid,
+ tid_data->seq_number);
+
+ tid_data->agg.rx_agg_state = RTL_RX_AGG_START;
+ return 0;
+}
+
+int rtl_rx_agg_stop(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u16 tid)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_sta_info *sta_entry = NULL;
+
+ if (!sta)
+ return -EINVAL;
+
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
+ "on ra = %pM tid = %d\n", sta->addr, tid);
+
+ if (unlikely(tid >= MAX_TID_COUNT))
+ return -EINVAL;
+
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+ sta_entry->tids[tid].agg.rx_agg_state = RTL_RX_AGG_STOP;
+
+ return 0;
+}
+
+int rtl_tx_agg_oper(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u16 tid)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_sta_info *sta_entry = NULL;
+
+ if (!sta)
+ return -EINVAL;
+
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
+ "on ra = %pM tid = %d\n", sta->addr, tid);
+
+ if (unlikely(tid >= MAX_TID_COUNT))
+ return -EINVAL;
+
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+ sta_entry->tids[tid].agg.agg_state = RTL_AGG_OPERATIONAL;
+
+ return 0;
+}
+
+void rtl_rx_ampdu_apply(struct rtl_priv *rtlpriv)
+{
+ struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
+ u8 reject_agg = 0, ctrl_agg_size = 0, agg_size = 0;
+
+ if (rtlpriv->cfg->ops->get_btc_status())
+ btc_ops->btc_get_ampdu_cfg(rtlpriv, &reject_agg,
+ &ctrl_agg_size, &agg_size);
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
+ "Set RX AMPDU: coex - reject=%d, ctrl_agg_size=%d, size=%d",
+ reject_agg, ctrl_agg_size, agg_size);
+
+ rtlpriv->hw->max_rx_aggregation_subframes =
+ (ctrl_agg_size ? agg_size : IEEE80211_MAX_AMPDU_BUF);
+}
+
+/*********************************************************
+ *
+ * wq & timer callback functions
+ *
+ *********************************************************/
+/* this function is used for roaming */
+void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+
+ if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION)
+ return;
+
+ if (rtlpriv->mac80211.link_state < MAC80211_LINKED)
+ return;
+
+ /* check if this really is a beacon */
+ if (!ieee80211_is_beacon(hdr->frame_control) &&
+ !ieee80211_is_probe_resp(hdr->frame_control))
+ return;
+
+ /* min. beacon length + FCS_LEN */
+ if (skb->len <= 40 + FCS_LEN)
+ return;
+
+ /* and only beacons from the associated BSSID, please */
+ if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid))
+ return;
+
+ rtlpriv->link_info.bcn_rx_inperiod++;
+}
+
+static void rtl_free_entries_from_scan_list(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_bssid_entry *entry, *next;
+
+ list_for_each_entry_safe(entry, next, &rtlpriv->scan_list.list, list) {
+ list_del(&entry->list);
+ kfree(entry);
+ rtlpriv->scan_list.num--;
+ }
+}
+
+void rtl_scan_list_expire(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_bssid_entry *entry, *next;
+ unsigned long flags;
+
+ spin_lock_irqsave(&rtlpriv->locks.scan_list_lock, flags);
+
+ list_for_each_entry_safe(entry, next, &rtlpriv->scan_list.list, list) {
+ /* 180 seconds */
+ if (jiffies_to_msecs(jiffies - entry->age) < 180000)
+ continue;
+
+ list_del(&entry->list);
+ rtlpriv->scan_list.num--;
+
+ RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
+ "BSSID=%pM is expire in scan list (total=%d)\n",
+ entry->bssid, rtlpriv->scan_list.num);
+ kfree(entry);
+ }
+
+ spin_unlock_irqrestore(&rtlpriv->locks.scan_list_lock, flags);
+
+ rtlpriv->btcoexist.btc_info.ap_num = rtlpriv->scan_list.num;
+}
+
+void rtl_collect_scan_list(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ unsigned long flags;
+
+ struct rtl_bssid_entry *entry;
+ bool entry_found = false;
+
+ /* check if it is scanning */
+ if (!mac->act_scanning)
+ return;
+
+ /* check if this really is a beacon */
+ if (!ieee80211_is_beacon(hdr->frame_control) &&
+ !ieee80211_is_probe_resp(hdr->frame_control))
+ return;
+
+ spin_lock_irqsave(&rtlpriv->locks.scan_list_lock, flags);
+
+ list_for_each_entry(entry, &rtlpriv->scan_list.list, list) {
+ if (memcmp(entry->bssid, hdr->addr3, ETH_ALEN) == 0) {
+ list_del_init(&entry->list);
+ entry_found = true;
+ RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
+ "Update BSSID=%pM to scan list (total=%d)\n",
+ hdr->addr3, rtlpriv->scan_list.num);
+ break;
+ }
+ }
+
+ if (!entry_found) {
+ entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
+
+ if (!entry)
+ goto label_err;
+
+ memcpy(entry->bssid, hdr->addr3, ETH_ALEN);
+ rtlpriv->scan_list.num++;
+
+ RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
+ "Add BSSID=%pM to scan list (total=%d)\n",
+ hdr->addr3, rtlpriv->scan_list.num);
+ }
+
+ entry->age = jiffies;
+
+ list_add_tail(&entry->list, &rtlpriv->scan_list.list);
+
+label_err:
+ spin_unlock_irqrestore(&rtlpriv->locks.scan_list_lock, flags);
+}
+
+void rtl_watchdog_wq_callback(void *data)
+{
+ struct rtl_works *rtlworks = container_of_dwork_rtl(data,
+ struct rtl_works,
+ watchdog_wq);
+ struct ieee80211_hw *hw = rtlworks->hw;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ bool busytraffic = false;
+ bool tx_busy_traffic = false;
+ bool rx_busy_traffic = false;
+ bool higher_busytraffic = false;
+ bool higher_busyrxtraffic = false;
+ u8 idx, tid;
+ u32 rx_cnt_inp4eriod = 0;
+ u32 tx_cnt_inp4eriod = 0;
+ u32 aver_rx_cnt_inperiod = 0;
+ u32 aver_tx_cnt_inperiod = 0;
+ u32 aver_tidtx_inperiod[MAX_TID_COUNT] = {0};
+ u32 tidtx_inp4eriod[MAX_TID_COUNT] = {0};
+
+ if (is_hal_stop(rtlhal))
+ return;
+
+ /* <1> Determine if action frame is allowed */
+ if (mac->link_state > MAC80211_NOLINK) {
+ if (mac->cnt_after_linked < 20)
+ mac->cnt_after_linked++;
+ } else {
+ mac->cnt_after_linked = 0;
+ }
+
+ /* <2> to check if traffic busy, if
+ * busytraffic we don't change channel
+ */
+ if (mac->link_state >= MAC80211_LINKED) {
+ /* (1) get aver_rx_cnt_inperiod & aver_tx_cnt_inperiod */
+ for (idx = 0; idx <= 2; idx++) {
+ rtlpriv->link_info.num_rx_in4period[idx] =
+ rtlpriv->link_info.num_rx_in4period[idx + 1];
+ rtlpriv->link_info.num_tx_in4period[idx] =
+ rtlpriv->link_info.num_tx_in4period[idx + 1];
+ }
+ rtlpriv->link_info.num_rx_in4period[3] =
+ rtlpriv->link_info.num_rx_inperiod;
+ rtlpriv->link_info.num_tx_in4period[3] =
+ rtlpriv->link_info.num_tx_inperiod;
+ for (idx = 0; idx <= 3; idx++) {
+ rx_cnt_inp4eriod +=
+ rtlpriv->link_info.num_rx_in4period[idx];
+ tx_cnt_inp4eriod +=
+ rtlpriv->link_info.num_tx_in4period[idx];
+ }
+ aver_rx_cnt_inperiod = rx_cnt_inp4eriod / 4;
+ aver_tx_cnt_inperiod = tx_cnt_inp4eriod / 4;
+
+ /* (2) check traffic busy */
+ if (aver_rx_cnt_inperiod > 100 || aver_tx_cnt_inperiod > 100) {
+ busytraffic = true;
+ if (aver_rx_cnt_inperiod > aver_tx_cnt_inperiod)
+ rx_busy_traffic = true;
+ else
+ tx_busy_traffic = false;
+ }
+
+ /* Higher Tx/Rx data. */
+ if (aver_rx_cnt_inperiod > 4000 ||
+ aver_tx_cnt_inperiod > 4000) {
+ higher_busytraffic = true;
+
+ /* Extremely high Rx data. */
+ if (aver_rx_cnt_inperiod > 5000)
+ higher_busyrxtraffic = true;
+ }
+
+ /* check every tid's tx traffic */
+ for (tid = 0; tid <= 7; tid++) {
+ for (idx = 0; idx <= 2; idx++)
+ rtlpriv->link_info.tidtx_in4period[tid][idx] =
+ rtlpriv->link_info.tidtx_in4period[tid]
+ [idx + 1];
+ rtlpriv->link_info.tidtx_in4period[tid][3] =
+ rtlpriv->link_info.tidtx_inperiod[tid];
+
+ for (idx = 0; idx <= 3; idx++)
+ tidtx_inp4eriod[tid] +=
+ rtlpriv->link_info.tidtx_in4period[tid][idx];
+ aver_tidtx_inperiod[tid] = tidtx_inp4eriod[tid] / 4;
+ if (aver_tidtx_inperiod[tid] > 5000)
+ rtlpriv->link_info.higher_busytxtraffic[tid] =
+ true;
+ else
+ rtlpriv->link_info.higher_busytxtraffic[tid] =
+ false;
+ }
+
+ /* PS is controlled by coex. */
+ if (rtlpriv->cfg->ops->get_btc_status() &&
+ rtlpriv->btcoexist.btc_ops->btc_is_bt_ctrl_lps(rtlpriv))
+ goto label_lps_done;
+
+ if (((rtlpriv->link_info.num_rx_inperiod +
+ rtlpriv->link_info.num_tx_inperiod) > 8) ||
+ (rtlpriv->link_info.num_rx_inperiod > 2))
+ rtl_lps_leave(hw);
+ else
+ rtl_lps_enter(hw);
+
+label_lps_done:
+ ;
+ }
+
+ rtlpriv->link_info.num_rx_inperiod = 0;
+ rtlpriv->link_info.num_tx_inperiod = 0;
+ for (tid = 0; tid <= 7; tid++)
+ rtlpriv->link_info.tidtx_inperiod[tid] = 0;
+
+ rtlpriv->link_info.busytraffic = busytraffic;
+ rtlpriv->link_info.higher_busytraffic = higher_busytraffic;
+ rtlpriv->link_info.rx_busy_traffic = rx_busy_traffic;
+ rtlpriv->link_info.tx_busy_traffic = tx_busy_traffic;
+ rtlpriv->link_info.higher_busyrxtraffic = higher_busyrxtraffic;
+
+ rtlpriv->stats.txbytesunicast_inperiod =
+ rtlpriv->stats.txbytesunicast -
+ rtlpriv->stats.txbytesunicast_last;
+ rtlpriv->stats.rxbytesunicast_inperiod =
+ rtlpriv->stats.rxbytesunicast -
+ rtlpriv->stats.rxbytesunicast_last;
+ rtlpriv->stats.txbytesunicast_last = rtlpriv->stats.txbytesunicast;
+ rtlpriv->stats.rxbytesunicast_last = rtlpriv->stats.rxbytesunicast;
+
+ rtlpriv->stats.txbytesunicast_inperiod_tp =
+ (u32)(rtlpriv->stats.txbytesunicast_inperiod * 8 / 2 /
+ 1024 / 1024);
+ rtlpriv->stats.rxbytesunicast_inperiod_tp =
+ (u32)(rtlpriv->stats.rxbytesunicast_inperiod * 8 / 2 /
+ 1024 / 1024);
+
+ /* <3> DM */
+ if (!rtlpriv->cfg->mod_params->disable_watchdog)
+ rtlpriv->cfg->ops->dm_watchdog(hw);
+
+ /* <4> roaming */
+ if (mac->link_state == MAC80211_LINKED &&
+ mac->opmode == NL80211_IFTYPE_STATION) {
+ if ((rtlpriv->link_info.bcn_rx_inperiod +
+ rtlpriv->link_info.num_rx_inperiod) == 0) {
+ rtlpriv->link_info.roam_times++;
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
+ "AP off for %d s\n",
+ (rtlpriv->link_info.roam_times * 2));
+
+ /* if we can't recv beacon for 10s,
+ * we should reconnect this AP
+ */
+ if (rtlpriv->link_info.roam_times >= 5) {
+ pr_err("AP off, try to reconnect now\n");
+ rtlpriv->link_info.roam_times = 0;
+ ieee80211_connection_loss(
+ rtlpriv->mac80211.vif);
+ }
+ } else {
+ rtlpriv->link_info.roam_times = 0;
+ }
+ }
+
+ if (rtlpriv->cfg->ops->get_btc_status())
+ rtlpriv->btcoexist.btc_ops->btc_periodical(rtlpriv);
+
+ if (rtlpriv->btcoexist.btc_info.in_4way) {
+ if (time_after(jiffies, rtlpriv->btcoexist.btc_info.in_4way_ts +
+ msecs_to_jiffies(IN_4WAY_TIMEOUT_TIME)))
+ rtlpriv->btcoexist.btc_info.in_4way = false;
+ }
+
+ rtlpriv->link_info.bcn_rx_inperiod = 0;
+
+ /* <6> scan list */
+ rtl_scan_list_expire(hw);
+}
+
+void rtl_watch_dog_timer_callback(unsigned long data)
+{
+ struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ queue_delayed_work(rtlpriv->works.rtl_wq,
+ &rtlpriv->works.watchdog_wq, 0);
+
+ mod_timer(&rtlpriv->works.watchdog_timer,
+ jiffies + MSECS(RTL_WATCH_DOG_TIME));
+}
+
+void rtl_fwevt_wq_callback(void *data)
+{
+ struct rtl_works *rtlworks =
+ container_of_dwork_rtl(data, struct rtl_works, fwevt_wq);
+ struct ieee80211_hw *hw = rtlworks->hw;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtlpriv->cfg->ops->c2h_command_handle(hw);
+}
+
+void rtl_c2hcmd_enqueue(struct ieee80211_hw *hw, u8 tag, u8 len, u8 *val)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ unsigned long flags;
+ struct rtl_c2hcmd *c2hcmd;
+
+ c2hcmd = kmalloc(sizeof(*c2hcmd),
+ in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
+
+ if (!c2hcmd)
+ goto label_err;
+
+ c2hcmd->val = kmalloc(len,
+ in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
+
+ if (!c2hcmd->val)
+ goto label_err2;
+
+ /* fill data */
+ c2hcmd->tag = tag;
+ c2hcmd->len = len;
+ memcpy(c2hcmd->val, val, len);
+
+ /* enqueue */
+ spin_lock_irqsave(&rtlpriv->locks.c2hcmd_lock, flags);
+
+ list_add_tail(&c2hcmd->list, &rtlpriv->c2hcmd_list);
+
+ spin_unlock_irqrestore(&rtlpriv->locks.c2hcmd_lock, flags);
+
+ /* wake up wq */
+ queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.c2hcmd_wq, 0);
+
+ return;
+
+label_err2:
+ kfree(c2hcmd);
+
+label_err:
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_WARNING,
+ "C2H cmd enqueue fail.\n");
+}
+
+void rtl_c2hcmd_launcher(struct ieee80211_hw *hw, int exec)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ unsigned long flags;
+ struct rtl_c2hcmd *c2hcmd;
+ int i;
+
+ for (i = 0; i < 200; i++) {
+ /* dequeue a task */
+ spin_lock_irqsave(&rtlpriv->locks.c2hcmd_lock, flags);
+
+ c2hcmd = list_first_entry_or_null(&rtlpriv->c2hcmd_list,
+ struct rtl_c2hcmd, list);
+
+ if (c2hcmd)
+ list_del(&c2hcmd->list);
+
+ spin_unlock_irqrestore(&rtlpriv->locks.c2hcmd_lock, flags);
+
+ /* do it */
+ if (!c2hcmd)
+ break;
+
+ if (rtlpriv->cfg->ops->c2h_content_parsing && exec)
+ rtlpriv->cfg->ops->c2h_content_parsing(hw,
+ c2hcmd->tag, c2hcmd->len, c2hcmd->val);
+
+ /* free */
+ kfree(c2hcmd->val);
+
+ kfree(c2hcmd);
+ }
+}
+
+void rtl_c2hcmd_wq_callback(void *data)
+{
+ struct rtl_works *rtlworks = container_of_dwork_rtl(data,
+ struct rtl_works,
+ c2hcmd_wq);
+ struct ieee80211_hw *hw = rtlworks->hw;
+
+ rtl_c2hcmd_launcher(hw, 1);
+}
+
+void rtl_easy_concurrent_retrytimer_callback(unsigned long data)
+{
+ struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_priv *buddy_priv = rtlpriv->buddy_priv;
+
+ if (!buddy_priv)
+ return;
+
+ rtlpriv->cfg->ops->dualmac_easy_concurrent(hw);
+}
+
+/*********************************************************
+ *
+ * frame process functions
+ *
+ *********************************************************/
+u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie)
+{
+ struct ieee80211_mgmt *mgmt = (void *)data;
+ u8 *pos, *end;
+
+ pos = (u8 *)mgmt->u.beacon.variable;
+ end = data + len;
+ while (pos < end) {
+ if (pos + 2 + pos[1] > end)
+ return NULL;
+
+ if (pos[0] == ie)
+ return pos;
+
+ pos += 2 + pos[1];
+ }
+ return NULL;
+}
+
+/* when we use 2 rx ants we send IEEE80211_SMPS_OFF */
+/* when we use 1 rx ant we send IEEE80211_SMPS_STATIC */
+static struct sk_buff *rtl_make_smps_action(struct ieee80211_hw *hw,
+ enum ieee80211_smps_mode smps,
+ u8 *da, u8 *bssid)
+{
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ struct sk_buff *skb;
+ struct ieee80211_mgmt *action_frame;
+
+ /* 27 = header + category + action + smps mode */
+ skb = dev_alloc_skb(27 + hw->extra_tx_headroom);
+ if (!skb)
+ return NULL;
+
+ skb_reserve(skb, hw->extra_tx_headroom);
+ action_frame = skb_put_zero(skb, 27);
+ memcpy(action_frame->da, da, ETH_ALEN);
+ memcpy(action_frame->sa, rtlefuse->dev_addr, ETH_ALEN);
+ memcpy(action_frame->bssid, bssid, ETH_ALEN);
+ action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+ IEEE80211_STYPE_ACTION);
+ action_frame->u.action.category = WLAN_CATEGORY_HT;
+ action_frame->u.action.u.ht_smps.action = WLAN_HT_ACTION_SMPS;
+ switch (smps) {
+ case IEEE80211_SMPS_AUTOMATIC:/* 0 */
+ case IEEE80211_SMPS_NUM_MODES:/* 4 */
+ WARN_ON(1);
+ /* Here will get a 'MISSING_BREAK' in Coverity Test, just ignore it.
+ * According to Kernel Code, here is right.
+ */
+ case IEEE80211_SMPS_OFF:/* 1 */ /*MIMO_PS_NOLIMIT*/
+ action_frame->u.action.u.ht_smps.smps_control =
+ WLAN_HT_SMPS_CONTROL_DISABLED;/* 0 */
+ break;
+ case IEEE80211_SMPS_STATIC:/* 2 */ /*MIMO_PS_STATIC*/
+ action_frame->u.action.u.ht_smps.smps_control =
+ WLAN_HT_SMPS_CONTROL_STATIC;/* 1 */
+ break;
+ case IEEE80211_SMPS_DYNAMIC:/* 3 */ /*MIMO_PS_DYNAMIC*/
+ action_frame->u.action.u.ht_smps.smps_control =
+ WLAN_HT_SMPS_CONTROL_DYNAMIC;/* 3 */
+ break;
+ }
+
+ return skb;
+}
+
+int rtl_send_smps_action(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
+ enum ieee80211_smps_mode smps)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct sk_buff *skb = NULL;
+ struct rtl_tcb_desc tcb_desc;
+ u8 bssid[ETH_ALEN] = {0};
+
+ memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
+
+ if (rtlpriv->mac80211.act_scanning)
+ goto err_free;
+
+ if (!sta)
+ goto err_free;
+
+ if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON))
+ goto err_free;
+
+ if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
+ goto err_free;
+
+ if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP)
+ memcpy(bssid, rtlpriv->efuse.dev_addr, ETH_ALEN);
+ else
+ memcpy(bssid, rtlpriv->mac80211.bssid, ETH_ALEN);
+
+ skb = rtl_make_smps_action(hw, smps, sta->addr, bssid);
+ /* this is a type = mgmt * stype = action frame */
+ if (skb) {
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct rtl_sta_info *sta_entry =
+ (struct rtl_sta_info *)sta->drv_priv;
+ sta_entry->mimo_ps = smps;
+ /* rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0, true); */
+
+ info->control.rates[0].idx = 0;
+ info->band = hw->conf.chandef.chan->band;
+ rtlpriv->intf_ops->adapter_tx(hw, sta, skb, &tcb_desc);
+ }
+ return 1;
+
+err_free:
+ return 0;
+}
+
+void rtl_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ enum io_type iotype;
+
+ if (!is_hal_stop(rtlhal)) {
+ switch (operation) {
+ case SCAN_OPT_BACKUP:
+ iotype = IO_CMD_PAUSE_DM_BY_SCAN;
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_IO_CMD,
+ (u8 *)&iotype);
+ break;
+ case SCAN_OPT_RESTORE:
+ iotype = IO_CMD_RESUME_DM_BY_SCAN;
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_IO_CMD,
+ (u8 *)&iotype);
+ break;
+ default:
+ pr_err("Unknown Scan Backup operation.\n");
+ break;
+ }
+ }
+}
+
+/* because mac80211 have issues when can receive del ba
+ * so here we just make a fake del_ba if we receive a ba_req
+ * but rx_agg was opened to let mac80211 release some ba
+ * related resources, so please this del_ba for tx
+ */
+struct sk_buff *rtl_make_del_ba(struct ieee80211_hw *hw,
+ u8 *sa, u8 *bssid, u16 tid)
+{
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ struct sk_buff *skb;
+ struct ieee80211_mgmt *action_frame;
+ u16 params;
+
+ /* 27 = header + category + action + smps mode */
+ skb = dev_alloc_skb(34 + hw->extra_tx_headroom);
+ if (!skb)
+ return NULL;
+
+ skb_reserve(skb, hw->extra_tx_headroom);
+ action_frame = skb_put_zero(skb, 34);
+ memcpy(action_frame->sa, sa, ETH_ALEN);
+ memcpy(action_frame->da, rtlefuse->dev_addr, ETH_ALEN);
+ memcpy(action_frame->bssid, bssid, ETH_ALEN);
+ action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+ IEEE80211_STYPE_ACTION);
+ action_frame->u.action.category = WLAN_CATEGORY_BACK;
+ action_frame->u.action.u.delba.action_code = WLAN_ACTION_DELBA;
+ params = (u16)(1 << 11); /* bit 11 initiator */
+ params |= (u16)(tid << 12); /* bit 15:12 TID number */
+
+ action_frame->u.action.u.delba.params = cpu_to_le16(params);
+ action_frame->u.action.u.delba.reason_code =
+ cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT);
+
+ return skb;
+}
+
+bool rtl_check_beacon_key(struct ieee80211_hw *hw, void *data, unsigned int len)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ struct ieee80211_hdr *hdr = data;
+ struct ieee80211_ht_cap *ht_cap_ie;
+ struct ieee80211_ht_operation *ht_oper_ie = NULL;
+ struct rtl_beacon_keys bcn_key = {};
+ struct rtl_beacon_keys *cur_bcn_key;
+ u8 *ht_cap;
+ u8 ht_cap_len;
+ u8 *ht_oper;
+ u8 ht_oper_len;
+ u8 *ds_param;
+ u8 ds_param_len;
+
+ if (mac->opmode != NL80211_IFTYPE_STATION)
+ return false;
+
+ /* check if this really is a beacon*/
+ if (!ieee80211_is_beacon(hdr->frame_control))
+ return false;
+
+ /* min. beacon length + FCS_LEN */
+ if (len <= 40 + FCS_LEN)
+ return false;
+
+ cur_bcn_key = &mac->cur_beacon_keys;
+
+ if (rtlpriv->mac80211.link_state == MAC80211_NOLINK) {
+ if (cur_bcn_key->valid) {
+ cur_bcn_key->valid = false;
+ RT_TRACE(rtlpriv, COMP_BEACON, DBG_LOUD,
+ "Reset cur_beacon_keys.valid to false!\n");
+ }
+ return false;
+ }
+
+ /* and only beacons from the associated BSSID, please */
+ if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid))
+ return false;
+
+ /***** Parsing DS Param IE ******/
+ ds_param = rtl_find_ie(data, len - FCS_LEN, WLAN_EID_DS_PARAMS);
+
+ if (ds_param && !(ds_param[1] < sizeof(*ds_param))) {
+ ds_param_len = ds_param[1];
+ bcn_key.bcn_channel = ds_param[2];
+ } else {
+ ds_param = NULL;
+ }
+
+ /***** Parsing HT Cap. IE ******/
+ ht_cap = rtl_find_ie(data, len - FCS_LEN, WLAN_EID_HT_CAPABILITY);
+
+ if (ht_cap && !(ht_cap[1] < sizeof(*ht_cap))) {
+ ht_cap_len = ht_cap[1];
+ ht_cap_ie = (struct ieee80211_ht_cap *)&ht_cap[2];
+ bcn_key.ht_cap_info = ht_cap_ie->cap_info;
+ } else {
+ ht_cap = NULL;
+ }
+
+ /***** Parsing HT Info. IE ******/
+ ht_oper = rtl_find_ie(data, len - FCS_LEN, WLAN_EID_HT_OPERATION);
+
+ if (ht_oper && !(ht_oper[1] < sizeof(*ht_oper))) {
+ ht_oper_len = ht_oper[1];
+ ht_oper_ie = (struct ieee80211_ht_operation *)&ht_oper[2];
+ } else {
+ ht_oper = NULL;
+ }
+
+ /* update bcn_key */
+
+ if (!ds_param && ht_oper && ht_oper_ie)
+ bcn_key.bcn_channel = ht_oper_ie->primary_chan;
+
+ if (ht_oper && ht_oper_ie)
+ bcn_key.ht_info_infos_0_sco = ht_oper_ie->ht_param & 0x03;
+
+ bcn_key.valid = true;
+
+ /* update cur_beacon_keys or compare beacon key */
+ if ((rtlpriv->mac80211.link_state != MAC80211_LINKED) &&
+ (rtlpriv->mac80211.link_state != MAC80211_LINKED_SCANNING))
+ return true;
+
+ if (!cur_bcn_key->valid) {
+ /* update cur_beacon_keys */
+ memcpy(cur_bcn_key, &bcn_key, sizeof(bcn_key));
+ cur_bcn_key->valid = true;
+
+ RT_TRACE(rtlpriv, COMP_BEACON, DBG_LOUD,
+ "Beacon key update!ch=%d, ht_cap_info=0x%x, sco=0x%x\n",
+ cur_bcn_key->bcn_channel,
+ cur_bcn_key->ht_cap_info,
+ cur_bcn_key->ht_info_infos_0_sco);
+ return true;
+ }
+
+ /* compare beacon key */
+ if (!memcmp(cur_bcn_key, &bcn_key, sizeof(bcn_key))) {
+ /* same beacon key */
+ mac->new_beacon_cnt = 0;
+ goto chk_exit;
+ }
+
+ if ((cur_bcn_key->bcn_channel == bcn_key.bcn_channel) &&
+ (cur_bcn_key->ht_cap_info == bcn_key.ht_cap_info)) {
+ /* Beacon HT info IE, secondary channel offset check */
+ /* 40M -> 20M */
+ if (cur_bcn_key->ht_info_infos_0_sco >
+ bcn_key.ht_info_infos_0_sco) {
+ /* Not a new beacon */
+ RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
+ "Beacon BW change! sco:0x%x -> 0x%x\n",
+ cur_bcn_key->ht_info_infos_0_sco,
+ bcn_key.ht_info_infos_0_sco);
+
+ cur_bcn_key->ht_info_infos_0_sco =
+ bcn_key.ht_info_infos_0_sco;
+ } else {
+ /* 20M -> 40M */
+ if (rtlphy->max_ht_chan_bw >= HT_CHANNEL_WIDTH_20_40) {
+ /* Not a new beacon */
+ RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
+ "Beacon BW change! sco:0x%x -> 0x%x\n",
+ cur_bcn_key->ht_info_infos_0_sco,
+ bcn_key.ht_info_infos_0_sco);
+
+ cur_bcn_key->ht_info_infos_0_sco =
+ bcn_key.ht_info_infos_0_sco;
+ } else {
+ mac->new_beacon_cnt++;
+ }
+ }
+ } else {
+ mac->new_beacon_cnt++;
+ }
+
+ if (mac->new_beacon_cnt == 1) {
+ RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
+ "Get new beacon.\n");
+ RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
+ "Cur : ch=%d, ht_cap=0x%x, sco=0x%x\n",
+ cur_bcn_key->bcn_channel,
+ cur_bcn_key->ht_cap_info,
+ cur_bcn_key->ht_info_infos_0_sco);
+ RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
+ "New RX : ch=%d, ht_cap=0x%x, sco=0x%x\n",
+ bcn_key.bcn_channel,
+ bcn_key.ht_cap_info,
+ bcn_key.ht_info_infos_0_sco);
+
+ } else if (mac->new_beacon_cnt > 1) {
+ RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
+ "new beacon cnt: %d\n",
+ mac->new_beacon_cnt);
+ }
+
+ if (mac->new_beacon_cnt > 3) {
+ ieee80211_connection_loss(rtlpriv->mac80211.vif);
+ RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
+ "new beacon cnt >3, disconnect !\n");
+ }
+
+chk_exit:
+
+ return true;
+}
+
+/*********************************************************
+ *
+ * IOT functions
+ *
+ *********************************************************/
+static bool rtl_chk_vendor_ouisub(struct ieee80211_hw *hw,
+ struct octet_string vendor_ie)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ bool matched = false;
+ static u8 athcap_1[] = { 0x00, 0x03, 0x7F };
+ static u8 athcap_2[] = { 0x00, 0x13, 0x74 };
+ static u8 broadcap_1[] = { 0x00, 0x10, 0x18 };
+ static u8 broadcap_2[] = { 0x00, 0x0a, 0xf7 };
+ static u8 broadcap_3[] = { 0x00, 0x05, 0xb5 };
+ static u8 racap[] = { 0x00, 0x0c, 0x43 };
+ static u8 ciscocap[] = { 0x00, 0x40, 0x96 };
+ static u8 marvcap[] = { 0x00, 0x50, 0x43 };
+
+ if (memcmp(vendor_ie.octet, athcap_1, 3) == 0 ||
+ memcmp(vendor_ie.octet, athcap_2, 3) == 0) {
+ rtlpriv->mac80211.vendor = PEER_ATH;
+ matched = true;
+ } else if (memcmp(vendor_ie.octet, broadcap_1, 3) == 0 ||
+ memcmp(vendor_ie.octet, broadcap_2, 3) == 0 ||
+ memcmp(vendor_ie.octet, broadcap_3, 3) == 0) {
+ rtlpriv->mac80211.vendor = PEER_BROAD;
+ matched = true;
+ } else if (memcmp(vendor_ie.octet, racap, 3) == 0) {
+ rtlpriv->mac80211.vendor = PEER_RAL;
+ matched = true;
+ } else if (memcmp(vendor_ie.octet, ciscocap, 3) == 0) {
+ rtlpriv->mac80211.vendor = PEER_CISCO;
+ matched = true;
+ } else if (memcmp(vendor_ie.octet, marvcap, 3) == 0) {
+ rtlpriv->mac80211.vendor = PEER_MARV;
+ matched = true;
+ }
+
+ return matched;
+}
+
+static bool rtl_find_221_ie(struct ieee80211_hw *hw, u8 *data,
+ unsigned int len)
+{
+ struct ieee80211_mgmt *mgmt = (void *)data;
+ struct octet_string vendor_ie;
+ u8 *pos, *end;
+
+ pos = (u8 *)mgmt->u.beacon.variable;
+ end = data + len;
+ while (pos < end) {
+ if (pos[0] == 221) {
+ vendor_ie.length = pos[1];
+ vendor_ie.octet = &pos[2];
+ if (rtl_chk_vendor_ouisub(hw, vendor_ie))
+ return true;
+ }
+
+ if (pos + 2 + pos[1] > end)
+ return false;
+
+ pos += 2 + pos[1];
+ }
+ return false;
+}
+
+void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct ieee80211_hdr *hdr = (void *)data;
+ u32 vendor = PEER_UNKNOWN;
+
+ static u8 ap3_1[3] = { 0x00, 0x14, 0xbf };
+ static u8 ap3_2[3] = { 0x00, 0x1a, 0x70 };
+ static u8 ap3_3[3] = { 0x00, 0x1d, 0x7e };
+ static u8 ap4_1[3] = { 0x00, 0x90, 0xcc };
+ static u8 ap4_2[3] = { 0x00, 0x0e, 0x2e };
+ static u8 ap4_3[3] = { 0x00, 0x18, 0x02 };
+ static u8 ap4_4[3] = { 0x00, 0x17, 0x3f };
+ static u8 ap4_5[3] = { 0x00, 0x1c, 0xdf };
+ static u8 ap5_1[3] = { 0x00, 0x1c, 0xf0 };
+ static u8 ap5_2[3] = { 0x00, 0x21, 0x91 };
+ static u8 ap5_3[3] = { 0x00, 0x24, 0x01 };
+ static u8 ap5_4[3] = { 0x00, 0x15, 0xe9 };
+ static u8 ap5_5[3] = { 0x00, 0x17, 0x9A };
+ static u8 ap5_6[3] = { 0x00, 0x18, 0xE7 };
+ static u8 ap6_1[3] = { 0x00, 0x17, 0x94 };
+ static u8 ap7_1[3] = { 0x00, 0x14, 0xa4 };
+
+ if (mac->opmode != NL80211_IFTYPE_STATION)
+ return;
+
+ if (mac->link_state == MAC80211_NOLINK) {
+ mac->vendor = PEER_UNKNOWN;
+ return;
+ }
+
+ if (mac->cnt_after_linked > 2)
+ return;
+
+ /* check if this really is a beacon */
+ if (!ieee80211_is_beacon(hdr->frame_control))
+ return;
+
+ /* min. beacon length + FCS_LEN */
+ if (len <= 40 + FCS_LEN)
+ return;
+
+ /* and only beacons from the associated BSSID, please */
+ if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid))
+ return;
+
+ if (rtl_find_221_ie(hw, data, len))
+ vendor = mac->vendor;
+
+ if ((memcmp(mac->bssid, ap5_1, 3) == 0) ||
+ (memcmp(mac->bssid, ap5_2, 3) == 0) ||
+ (memcmp(mac->bssid, ap5_3, 3) == 0) ||
+ (memcmp(mac->bssid, ap5_4, 3) == 0) ||
+ (memcmp(mac->bssid, ap5_5, 3) == 0) ||
+ (memcmp(mac->bssid, ap5_6, 3) == 0) ||
+ vendor == PEER_ATH) {
+ vendor = PEER_ATH;
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>ath find\n");
+ } else if ((memcmp(mac->bssid, ap4_4, 3) == 0) ||
+ (memcmp(mac->bssid, ap4_5, 3) == 0) ||
+ (memcmp(mac->bssid, ap4_1, 3) == 0) ||
+ (memcmp(mac->bssid, ap4_2, 3) == 0) ||
+ (memcmp(mac->bssid, ap4_3, 3) == 0) ||
+ vendor == PEER_RAL) {
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>ral find\n");
+ vendor = PEER_RAL;
+ } else if (memcmp(mac->bssid, ap6_1, 3) == 0 ||
+ vendor == PEER_CISCO) {
+ vendor = PEER_CISCO;
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>cisco find\n");
+ } else if ((memcmp(mac->bssid, ap3_1, 3) == 0) ||
+ (memcmp(mac->bssid, ap3_2, 3) == 0) ||
+ (memcmp(mac->bssid, ap3_3, 3) == 0) ||
+ vendor == PEER_BROAD) {
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>broad find\n");
+ vendor = PEER_BROAD;
+ } else if (memcmp(mac->bssid, ap7_1, 3) == 0 ||
+ vendor == PEER_MARV) {
+ vendor = PEER_MARV;
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>marv find\n");
+ }
+
+ mac->vendor = vendor;
+}
+
+MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>");
+MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
+MODULE_AUTHOR("Larry Finger <Larry.FInger@lwfinger.net>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core");
+
+struct rtl_global_var rtl_global_var = {};
+
+int rtl_core_module_init(void)
+{
+ if (rtl_rate_control_register())
+ pr_err("rtl: Unable to register rtl_rc, use default RC !!\n");
+
+ /* add debugfs */
+ rtl_debugfs_add_topdir();
+
+ /* init some global vars */
+ INIT_LIST_HEAD(&rtl_global_var.glb_priv_list);
+ spin_lock_init(&rtl_global_var.glb_list_lock);
+
+ return 0;
+}
+
+void rtl_core_module_exit(void)
+{
+ /*RC*/
+ rtl_rate_control_unregister();
+
+ /* remove debugfs */
+ rtl_debugfs_remove_topdir();
+}
diff --git a/drivers/staging/rtlwifi/base.h b/drivers/staging/rtlwifi/base.h
new file mode 100644
index 0000000..1829712
--- /dev/null
+++ b/drivers/staging/rtlwifi/base.h
@@ -0,0 +1,186 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2012 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL_BASE_H__
+#define __RTL_BASE_H__
+
+enum ap_peer {
+ PEER_UNKNOWN = 0,
+ PEER_RTL = 1,
+ PEER_RTL_92SE = 2,
+ PEER_BROAD = 3,
+ PEER_RAL = 4,
+ PEER_ATH = 5,
+ PEER_CISCO = 6,
+ PEER_MARV = 7,
+ PEER_AIRGO = 9,
+ PEER_MAX = 10,
+};
+
+#define RTL_DUMMY_OFFSET 0
+#define RTL_DUMMY_UNIT 8
+#define RTL_TX_DUMMY_SIZE (RTL_DUMMY_OFFSET * RTL_DUMMY_UNIT)
+#define RTL_TX_DESC_SIZE 32
+#define RTL_TX_HEADER_SIZE (RTL_TX_DESC_SIZE + RTL_TX_DUMMY_SIZE)
+
+#define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */
+#define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */
+
+#define MAX_BIT_RATE_SHORT_GI_2NSS_80MHZ_MCS9 867 /* Mbps */
+#define MAX_BIT_RATE_SHORT_GI_2NSS_80MHZ_MCS7 650 /* Mbps */
+#define MAX_BIT_RATE_LONG_GI_2NSS_80MHZ_MCS9 780 /* Mbps */
+#define MAX_BIT_RATE_LONG_GI_2NSS_80MHZ_MCS7 585 /* Mbps */
+
+#define MAX_BIT_RATE_SHORT_GI_1NSS_80MHZ_MCS9 434 /* Mbps */
+#define MAX_BIT_RATE_SHORT_GI_1NSS_80MHZ_MCS7 325 /* Mbps */
+#define MAX_BIT_RATE_LONG_GI_1NSS_80MHZ_MCS9 390 /* Mbps */
+#define MAX_BIT_RATE_LONG_GI_1NSS_80MHZ_MCS7 293 /* Mbps */
+
+#define FRAME_OFFSET_FRAME_CONTROL 0
+#define FRAME_OFFSET_DURATION 2
+#define FRAME_OFFSET_ADDRESS1 4
+#define FRAME_OFFSET_ADDRESS2 10
+#define FRAME_OFFSET_ADDRESS3 16
+#define FRAME_OFFSET_SEQUENCE 22
+#define FRAME_OFFSET_ADDRESS4 24
+#define MAX_LISTEN_INTERVAL 10
+#define MAX_RATE_TRIES 4
+
+#define SET_80211_HDR_FRAME_CONTROL(_hdr, _val) \
+ WRITEEF2BYTE(_hdr, _val)
+#define SET_80211_HDR_TYPE_AND_SUBTYPE(_hdr, _val) \
+ WRITEEF1BYTE(_hdr, _val)
+#define SET_80211_HDR_PWR_MGNT(_hdr, _val) \
+ SET_BITS_TO_LE_2BYTE(_hdr, 12, 1, _val)
+#define SET_80211_HDR_TO_DS(_hdr, _val) \
+ SET_BITS_TO_LE_2BYTE(_hdr, 8, 1, _val)
+
+#define SET_80211_PS_POLL_AID(_hdr, _val) \
+ (*(u16 *)((u8 *)(_hdr) + 2) = _val)
+#define SET_80211_PS_POLL_BSSID(_hdr, _val) \
+ ether_addr_copy(((u8 *)(_hdr)) + 4, (u8 *)(_val))
+#define SET_80211_PS_POLL_TA(_hdr, _val) \
+ ether_addr_copy(((u8 *)(_hdr)) + 10, (u8 *)(_val))
+
+#define SET_80211_HDR_DURATION(_hdr, _val) \
+ (*(u16 *)((u8 *)(_hdr) + FRAME_OFFSET_DURATION) = le16_to_cpu(_val))
+#define SET_80211_HDR_ADDRESS1(_hdr, _val) \
+ CP_MACADDR((u8 *)(_hdr) + FRAME_OFFSET_ADDRESS1, (u8 *)(_val))
+#define SET_80211_HDR_ADDRESS2(_hdr, _val) \
+ CP_MACADDR((u8 *)(_hdr) + FRAME_OFFSET_ADDRESS2, (u8 *)(_val))
+#define SET_80211_HDR_ADDRESS3(_hdr, _val) \
+ CP_MACADDR((u8 *)(_hdr) + FRAME_OFFSET_ADDRESS3, (u8 *)(_val))
+#define SET_80211_HDR_FRAGMENT_SEQUENCE(_hdr, _val) \
+ WRITEEF2BYTE((u8 *)(_hdr) + FRAME_OFFSET_SEQUENCE, _val)
+
+#define SET_BEACON_PROBE_RSP_TIME_STAMP_LOW(__phdr, __val) \
+ WRITEEF4BYTE(((u8 *)(__phdr)) + 24, __val)
+#define SET_BEACON_PROBE_RSP_TIME_STAMP_HIGH(__phdr, __val) \
+ WRITEEF4BYTE(((u8 *)(__phdr)) + 28, __val)
+#define SET_BEACON_PROBE_RSP_BEACON_INTERVAL(__phdr, __val) \
+ WRITEEF2BYTE(((u8 *)(__phdr)) + 32, __val)
+#define GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) \
+ READEF2BYTE(((u8 *)(__phdr)) + 34)
+#define SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \
+ WRITEEF2BYTE(((u8 *)(__phdr)) + 34, __val)
+#define MASK_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \
+ SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, \
+ (GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) & (~(__val))))
+
+#define SET_TX_DESC_SPE_RPT(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE((__pdesc) + 8, 19, 1, __val)
+#define SET_TX_DESC_SW_DEFINE(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE((__pdesc) + 24, 0, 12, __val)
+
+int rtl_init_core(struct ieee80211_hw *hw);
+void rtl_deinit_core(struct ieee80211_hw *hw);
+void rtl_init_rx_config(struct ieee80211_hw *hw);
+void rtl_init_rfkill(struct ieee80211_hw *hw);
+void rtl_deinit_rfkill(struct ieee80211_hw *hw);
+
+void rtl_watch_dog_timer_callback(unsigned long data);
+void rtl_deinit_deferred_work(struct ieee80211_hw *hw);
+
+bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx);
+int rtlwifi_rate_mapping(struct ieee80211_hw *hw, bool isht,
+ bool isvht, u8 desc_rate);
+bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb);
+u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx,
+ bool is_enc);
+
+bool rtl_is_tx_report_skb(struct ieee80211_hw *hw, struct sk_buff *skb);
+void rtl_get_tx_report(struct rtl_tcb_desc *ptcb_desc, u8 *pdesc,
+ struct ieee80211_hw *hw);
+void rtl_tx_report_handler(struct ieee80211_hw *hw, u8 *tmp_buf,
+ u8 c2h_cmd_len);
+bool rtl_check_tx_report_acked(struct ieee80211_hw *hw);
+void rtl_wait_tx_report_acked(struct ieee80211_hw *hw, u32 wait_ms);
+u32 rtl_get_hal_edca_param(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum wireless_mode wirelessmode,
+ struct ieee80211_tx_queue_params *param);
+
+void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb);
+void rtl_collect_scan_list(struct ieee80211_hw *hw, struct sk_buff *skb);
+void rtl_scan_list_expire(struct ieee80211_hw *hw);
+int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta, u16 tid, u16 *ssn);
+int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta, u16 tid);
+int rtl_tx_agg_oper(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u16 tid);
+int rtl_rx_agg_start(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u16 tid);
+int rtl_rx_agg_stop(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u16 tid);
+void rtl_rx_ampdu_apply(struct rtl_priv *rtlpriv);
+void rtl_watchdog_wq_callback(void *data);
+void rtl_fwevt_wq_callback(void *data);
+void rtl_c2hcmd_wq_callback(void *data);
+void rtl_c2hcmd_launcher(struct ieee80211_hw *hw, int exec);
+void rtl_c2hcmd_enqueue(struct ieee80211_hw *hw, u8 tag, u8 len, u8 *val);
+
+u8 rtl_mrate_idx_to_arfr_id(
+ struct ieee80211_hw *hw, u8 rate_index,
+ enum wireless_mode wirelessmode);
+void rtl_get_tcb_desc(struct ieee80211_hw *hw,
+ struct ieee80211_tx_info *info,
+ struct ieee80211_sta *sta,
+ struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc);
+
+int rtl_send_smps_action(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
+ enum ieee80211_smps_mode smps);
+u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie);
+void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len);
+u8 rtl_tid_to_ac(u8 tid);
+void rtl_easy_concurrent_retrytimer_callback(unsigned long data);
+extern struct rtl_global_var rtl_global_var;
+void rtl_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation);
+bool rtl_check_beacon_key(struct ieee80211_hw *hw, void *data,
+ unsigned int len);
+int rtl_core_module_init(void);
+void rtl_core_module_exit(void);
+#endif
diff --git a/drivers/staging/rtlwifi/btcoexist/Makefile b/drivers/staging/rtlwifi/btcoexist/Makefile
new file mode 100644
index 0000000..f600bcc
--- /dev/null
+++ b/drivers/staging/rtlwifi/btcoexist/Makefile
@@ -0,0 +1,8 @@
+btcoexist-objs := \
+ halbtc8822b1ant.o \
+ halbtc8822b2ant.o \
+ halbtc8822bwifionly.o \
+ halbtcoutsrc.o \
+ rtl_btc.o
+
+obj-$(CONFIG_RTLBTCOEXIST) += btcoexist.o
diff --git a/drivers/staging/rtlwifi/btcoexist/halbt_precomp.h b/drivers/staging/rtlwifi/btcoexist/halbt_precomp.h
new file mode 100644
index 0000000..d78cd93
--- /dev/null
+++ b/drivers/staging/rtlwifi/btcoexist/halbt_precomp.h
@@ -0,0 +1,85 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#ifndef __HALBT_PRECOMP_H__
+#define __HALBT_PRECOMP_H__
+/*************************************************************
+ * include files
+ *************************************************************/
+#include "../wifi.h"
+#include "../efuse.h"
+#include "../base.h"
+#include "../regd.h"
+#include "../cam.h"
+#include "../ps.h"
+#include "../pci.h"
+
+#include "halbtcoutsrc.h"
+
+/* Interface type */
+#define RT_PCI_INTERFACE 1
+#define RT_USB_INTERFACE 2
+#define RT_SDIO_INTERFACE 3
+#define DEV_BUS_TYPE RT_PCI_INTERFACE
+
+#include "halbtc8822b1ant.h"
+#include "halbtc8822b2ant.h"
+#include "halbtc8822bwifionly.h"
+
+#define GETDEFAULTADAPTER(padapter) padapter
+
+#define BIT0 0x00000001
+#define BIT1 0x00000002
+#define BIT2 0x00000004
+#define BIT3 0x00000008
+#define BIT4 0x00000010
+#define BIT5 0x00000020
+#define BIT6 0x00000040
+#define BIT7 0x00000080
+#define BIT8 0x00000100
+#define BIT9 0x00000200
+#define BIT10 0x00000400
+#define BIT11 0x00000800
+#define BIT12 0x00001000
+#define BIT13 0x00002000
+#define BIT14 0x00004000
+#define BIT15 0x00008000
+#define BIT16 0x00010000
+#define BIT17 0x00020000
+#define BIT18 0x00040000
+#define BIT19 0x00080000
+#define BIT20 0x00100000
+#define BIT21 0x00200000
+#define BIT22 0x00400000
+#define BIT23 0x00800000
+#define BIT24 0x01000000
+#define BIT25 0x02000000
+#define BIT26 0x04000000
+#define BIT27 0x08000000
+#define BIT28 0x10000000
+#define BIT29 0x20000000
+#define BIT30 0x40000000
+#define BIT31 0x80000000
+
+#endif /* __HALBT_PRECOMP_H__ */
diff --git a/drivers/staging/rtlwifi/btcoexist/halbtc8822b1ant.c b/drivers/staging/rtlwifi/btcoexist/halbtc8822b1ant.c
new file mode 100644
index 0000000..157395b
--- /dev/null
+++ b/drivers/staging/rtlwifi/btcoexist/halbtc8822b1ant.c
@@ -0,0 +1,5244 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+/* ************************************************************
+ * Description:
+ *
+ * This file is for RTL8822B Co-exist mechanism
+ *
+ * History
+ * 2012/11/15 Cosa first check in.
+ *
+ * *************************************************************/
+
+/* ************************************************************
+ * include files
+ * *************************************************************/
+/*only for rf4ce*/
+#include "halbt_precomp.h"
+
+/* ************************************************************
+ * Global variables, these are static variables
+ * *************************************************************/
+static struct coex_dm_8822b_1ant glcoex_dm_8822b_1ant;
+static struct coex_dm_8822b_1ant *coex_dm = &glcoex_dm_8822b_1ant;
+static struct coex_sta_8822b_1ant glcoex_sta_8822b_1ant;
+static struct coex_sta_8822b_1ant *coex_sta = &glcoex_sta_8822b_1ant;
+static struct psdscan_sta_8822b_1ant gl_psd_scan_8822b_1ant;
+static struct psdscan_sta_8822b_1ant *psd_scan = &gl_psd_scan_8822b_1ant;
+static struct rfe_type_8822b_1ant gl_rfe_type_8822b_1ant;
+static struct rfe_type_8822b_1ant *rfe_type = &gl_rfe_type_8822b_1ant;
+
+static const char *const glbt_info_src_8822b_1ant[] = {
+ "BT Info[wifi fw]", "BT Info[bt rsp]", "BT Info[bt auto report]",
+};
+
+static u32 glcoex_ver_date_8822b_1ant = 20170327;
+static u32 glcoex_ver_8822b_1ant = 0x44;
+static u32 glcoex_ver_btdesired_8822b_1ant = 0x42;
+
+/* ************************************************************
+ * local function proto type if needed
+ * ************************************************************
+ * ************************************************************
+ * local function start with halbtc8822b1ant_
+ * *************************************************************/
+
+static u8 halbtc8822b1ant_wifi_rssi_state(struct btc_coexist *btcoexist,
+ u8 index, u8 level_num,
+ u8 rssi_thresh, u8 rssi_thresh1)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ s32 wifi_rssi = 0;
+ u8 wifi_rssi_state = coex_sta->pre_wifi_rssi_state[index];
+
+ btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
+
+ if (level_num == 2) {
+ if ((coex_sta->pre_wifi_rssi_state[index] ==
+ BTC_RSSI_STATE_LOW) ||
+ (coex_sta->pre_wifi_rssi_state[index] ==
+ BTC_RSSI_STATE_STAY_LOW)) {
+ if (wifi_rssi >=
+ (rssi_thresh + BTC_RSSI_COEX_THRESH_TOL_8822B_1ANT))
+ wifi_rssi_state = BTC_RSSI_STATE_HIGH;
+ else
+ wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW;
+ } else {
+ if (wifi_rssi < rssi_thresh)
+ wifi_rssi_state = BTC_RSSI_STATE_LOW;
+ else
+ wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
+ }
+ } else if (level_num == 3) {
+ if (rssi_thresh > rssi_thresh1) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], wifi RSSI thresh error!!\n");
+ return coex_sta->pre_wifi_rssi_state[index];
+ }
+
+ if ((coex_sta->pre_wifi_rssi_state[index] ==
+ BTC_RSSI_STATE_LOW) ||
+ (coex_sta->pre_wifi_rssi_state[index] ==
+ BTC_RSSI_STATE_STAY_LOW)) {
+ if (wifi_rssi >=
+ (rssi_thresh + BTC_RSSI_COEX_THRESH_TOL_8822B_1ANT))
+ wifi_rssi_state = BTC_RSSI_STATE_MEDIUM;
+ else
+ wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW;
+ } else if ((coex_sta->pre_wifi_rssi_state[index] ==
+ BTC_RSSI_STATE_MEDIUM) ||
+ (coex_sta->pre_wifi_rssi_state[index] ==
+ BTC_RSSI_STATE_STAY_MEDIUM)) {
+ if (wifi_rssi >= (rssi_thresh1 +
+ BTC_RSSI_COEX_THRESH_TOL_8822B_1ANT))
+ wifi_rssi_state = BTC_RSSI_STATE_HIGH;
+ else if (wifi_rssi < rssi_thresh)
+ wifi_rssi_state = BTC_RSSI_STATE_LOW;
+ else
+ wifi_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM;
+ } else {
+ if (wifi_rssi < rssi_thresh1)
+ wifi_rssi_state = BTC_RSSI_STATE_MEDIUM;
+ else
+ wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
+ }
+ }
+
+ coex_sta->pre_wifi_rssi_state[index] = wifi_rssi_state;
+
+ return wifi_rssi_state;
+}
+
+static void halbtc8822b1ant_update_ra_mask(struct btc_coexist *btcoexist,
+ bool force_exec, u32 dis_rate_mask)
+{
+ coex_dm->cur_ra_mask = dis_rate_mask;
+
+ if (force_exec || (coex_dm->pre_ra_mask != coex_dm->cur_ra_mask))
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_UPDATE_RAMASK,
+ &coex_dm->cur_ra_mask);
+ coex_dm->pre_ra_mask = coex_dm->cur_ra_mask;
+}
+
+static void
+halbtc8822b1ant_auto_rate_fallback_retry(struct btc_coexist *btcoexist,
+ bool force_exec, u8 type)
+{
+ bool wifi_under_b_mode = false;
+
+ coex_dm->cur_arfr_type = type;
+
+ if (force_exec || (coex_dm->pre_arfr_type != coex_dm->cur_arfr_type)) {
+ switch (coex_dm->cur_arfr_type) {
+ case 0: /* normal mode */
+ btcoexist->btc_write_4byte(btcoexist, 0x430,
+ coex_dm->backup_arfr_cnt1);
+ btcoexist->btc_write_4byte(btcoexist, 0x434,
+ coex_dm->backup_arfr_cnt2);
+ break;
+ case 1:
+ btcoexist->btc_get(btcoexist,
+ BTC_GET_BL_WIFI_UNDER_B_MODE,
+ &wifi_under_b_mode);
+ if (wifi_under_b_mode) {
+ btcoexist->btc_write_4byte(btcoexist, 0x430,
+ 0x0);
+ btcoexist->btc_write_4byte(btcoexist, 0x434,
+ 0x01010101);
+ } else {
+ btcoexist->btc_write_4byte(btcoexist, 0x430,
+ 0x0);
+ btcoexist->btc_write_4byte(btcoexist, 0x434,
+ 0x04030201);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ coex_dm->pre_arfr_type = coex_dm->cur_arfr_type;
+}
+
+static void halbtc8822b1ant_retry_limit(struct btc_coexist *btcoexist,
+ bool force_exec, u8 type)
+{
+ coex_dm->cur_retry_limit_type = type;
+
+ if (force_exec ||
+ (coex_dm->pre_retry_limit_type != coex_dm->cur_retry_limit_type)) {
+ switch (coex_dm->cur_retry_limit_type) {
+ case 0: /* normal mode */
+ btcoexist->btc_write_2byte(btcoexist, 0x42a,
+ coex_dm->backup_retry_limit);
+ break;
+ case 1: /* retry limit=8 */
+ btcoexist->btc_write_2byte(btcoexist, 0x42a, 0x0808);
+ break;
+ default:
+ break;
+ }
+ }
+
+ coex_dm->pre_retry_limit_type = coex_dm->cur_retry_limit_type;
+}
+
+static void halbtc8822b1ant_ampdu_max_time(struct btc_coexist *btcoexist,
+ bool force_exec, u8 type)
+{
+ coex_dm->cur_ampdu_time_type = type;
+
+ if (force_exec ||
+ (coex_dm->pre_ampdu_time_type != coex_dm->cur_ampdu_time_type)) {
+ switch (coex_dm->cur_ampdu_time_type) {
+ case 0: /* normal mode */
+ btcoexist->btc_write_1byte(
+ btcoexist, 0x456,
+ coex_dm->backup_ampdu_max_time);
+ break;
+ case 1: /* AMPDU timw = 0x38 * 32us */
+ btcoexist->btc_write_1byte(btcoexist, 0x456, 0x38);
+ break;
+ default:
+ break;
+ }
+ }
+
+ coex_dm->pre_ampdu_time_type = coex_dm->cur_ampdu_time_type;
+}
+
+static void halbtc8822b1ant_limited_tx(struct btc_coexist *btcoexist,
+ bool force_exec, u8 ra_mask_type,
+ u8 arfr_type, u8 retry_limit_type,
+ u8 ampdu_time_type)
+{
+ switch (ra_mask_type) {
+ case 0: /* normal mode */
+ halbtc8822b1ant_update_ra_mask(btcoexist, force_exec, 0x0);
+ break;
+ case 1: /* disable cck 1/2 */
+ halbtc8822b1ant_update_ra_mask(btcoexist, force_exec,
+ 0x00000003);
+ break;
+ case 2: /* disable cck 1/2/5.5, ofdm 6/9/12/18/24, mcs 0/1/2/3/4 */
+ halbtc8822b1ant_update_ra_mask(btcoexist, force_exec,
+ 0x0001f1f7);
+ break;
+ default:
+ break;
+ }
+
+ halbtc8822b1ant_auto_rate_fallback_retry(btcoexist, force_exec,
+ arfr_type);
+ halbtc8822b1ant_retry_limit(btcoexist, force_exec, retry_limit_type);
+ halbtc8822b1ant_ampdu_max_time(btcoexist, force_exec, ampdu_time_type);
+}
+
+/*
+ * rx agg size setting :
+ * 1: true / don't care / don't care
+ * max: false / false / don't care
+ * 7: false / true / 7
+ */
+
+static void halbtc8822b1ant_limited_rx(struct btc_coexist *btcoexist,
+ bool force_exec, bool rej_ap_agg_pkt,
+ bool bt_ctrl_agg_buf_size,
+ u8 agg_buf_size)
+{
+ bool reject_rx_agg = rej_ap_agg_pkt;
+ bool bt_ctrl_rx_agg_size = bt_ctrl_agg_buf_size;
+ u8 rx_agg_size = agg_buf_size;
+
+ /* ============================================ */
+ /* Rx Aggregation related setting */
+ /* ============================================ */
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT,
+ &reject_rx_agg);
+ /* decide BT control aggregation buf size or not */
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE,
+ &bt_ctrl_rx_agg_size);
+ /* aggregation buf size, only work when BT control Rx aggregation size*/
+ btcoexist->btc_set(btcoexist, BTC_SET_U1_AGG_BUF_SIZE, &rx_agg_size);
+ /* real update aggregation setting */
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL);
+}
+
+static void halbtc8822b1ant_query_bt_info(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ u8 h2c_parameter[1] = {0};
+
+ if (coex_sta->bt_disabled) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], No query BT info because BT is disabled!\n");
+ return;
+ }
+
+ h2c_parameter[0] |= BIT(0); /* trigger */
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter);
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], WL query BT info!!\n");
+}
+
+static void halbtc8822b1ant_monitor_bt_ctr(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ u32 reg_hp_txrx, reg_lp_txrx, u32tmp;
+ u32 reg_hp_tx = 0, reg_hp_rx = 0, reg_lp_tx = 0, reg_lp_rx = 0;
+ static u8 num_of_bt_counter_chk, cnt_slave, cnt_autoslot_hang;
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+
+ reg_hp_txrx = 0x770;
+ reg_lp_txrx = 0x774;
+
+ u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_hp_txrx);
+ reg_hp_tx = u32tmp & MASKLWORD;
+ reg_hp_rx = (u32tmp & MASKHWORD) >> 16;
+
+ u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_lp_txrx);
+ reg_lp_tx = u32tmp & MASKLWORD;
+ reg_lp_rx = (u32tmp & MASKHWORD) >> 16;
+
+ coex_sta->high_priority_tx = reg_hp_tx;
+ coex_sta->high_priority_rx = reg_hp_rx;
+ coex_sta->low_priority_tx = reg_lp_tx;
+ coex_sta->low_priority_rx = reg_lp_rx;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Hi-Pri Rx/Tx: %d/%d, Lo-Pri Rx/Tx: %d/%d\n",
+ reg_hp_rx, reg_hp_tx, reg_lp_rx, reg_lp_tx);
+
+ /* reset counter */
+ btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc);
+
+ if ((coex_sta->low_priority_tx > 1150) &&
+ (!coex_sta->c2h_bt_inquiry_page))
+ coex_sta->pop_event_cnt++;
+
+ if ((coex_sta->low_priority_rx >= 1150) &&
+ (coex_sta->low_priority_rx >= coex_sta->low_priority_tx) &&
+ (!coex_sta->under_ips) && (!coex_sta->c2h_bt_inquiry_page) &&
+ (coex_sta->bt_link_exist)) {
+ if (cnt_slave >= 3) {
+ bt_link_info->slave_role = true;
+ cnt_slave = 3;
+ } else {
+ cnt_slave++;
+ }
+ } else {
+ if (cnt_slave == 0) {
+ bt_link_info->slave_role = false;
+ cnt_slave = 0;
+ } else {
+ cnt_slave--;
+ }
+ }
+
+ if (coex_sta->is_tdma_btautoslot) {
+ if ((coex_sta->low_priority_tx >= 1300) &&
+ (coex_sta->low_priority_rx <= 150)) {
+ if (cnt_autoslot_hang >= 2) {
+ coex_sta->is_tdma_btautoslot_hang = true;
+ cnt_autoslot_hang = 2;
+ } else {
+ cnt_autoslot_hang++;
+ }
+ } else {
+ if (cnt_autoslot_hang == 0) {
+ coex_sta->is_tdma_btautoslot_hang = false;
+ cnt_autoslot_hang = 0;
+ } else {
+ cnt_autoslot_hang--;
+ }
+ }
+ }
+
+ if (bt_link_info->hid_only) {
+ if (coex_sta->low_priority_rx > 50)
+ coex_sta->is_hid_low_pri_tx_overhead = true;
+ else
+ coex_sta->is_hid_low_pri_tx_overhead = false;
+ }
+
+ if ((coex_sta->high_priority_tx == 0) &&
+ (coex_sta->high_priority_rx == 0) &&
+ (coex_sta->low_priority_tx == 0) &&
+ (coex_sta->low_priority_rx == 0)) {
+ num_of_bt_counter_chk++;
+
+ if (num_of_bt_counter_chk >= 3) {
+ halbtc8822b1ant_query_bt_info(btcoexist);
+ num_of_bt_counter_chk = 0;
+ }
+ }
+}
+
+static void halbtc8822b1ant_monitor_wifi_ctr(struct btc_coexist *btcoexist)
+{
+ s32 wifi_rssi = 0;
+ bool wifi_busy = false, wifi_under_b_mode = false, wifi_scan = false;
+ static u8 cck_lock_counter, wl_noisy_count0, wl_noisy_count1 = 3,
+ wl_noisy_count2;
+ u32 total_cnt, cck_cnt;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+ btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_B_MODE,
+ &wifi_under_b_mode);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &wifi_scan);
+
+ coex_sta->crc_ok_cck = btcoexist->btc_phydm_query_phy_counter(
+ btcoexist, "PHYDM_INFO_CRC32_OK_CCK");
+ coex_sta->crc_ok_11g = btcoexist->btc_phydm_query_phy_counter(
+ btcoexist, "PHYDM_INFO_CRC32_OK_LEGACY");
+ coex_sta->crc_ok_11n = btcoexist->btc_phydm_query_phy_counter(
+ btcoexist, "PHYDM_INFO_CRC32_OK_HT");
+ coex_sta->crc_ok_11n_vht = btcoexist->btc_phydm_query_phy_counter(
+ btcoexist, "PHYDM_INFO_CRC32_OK_VHT");
+
+ coex_sta->crc_err_cck = btcoexist->btc_phydm_query_phy_counter(
+ btcoexist, "PHYDM_INFO_CRC32_ERROR_CCK");
+ coex_sta->crc_err_11g = btcoexist->btc_phydm_query_phy_counter(
+ btcoexist, "PHYDM_INFO_CRC32_ERROR_LEGACY");
+ coex_sta->crc_err_11n = btcoexist->btc_phydm_query_phy_counter(
+ btcoexist, "PHYDM_INFO_CRC32_ERROR_HT");
+ coex_sta->crc_err_11n_vht = btcoexist->btc_phydm_query_phy_counter(
+ btcoexist, "PHYDM_INFO_CRC32_ERROR_VHT");
+
+ cck_cnt = coex_sta->crc_ok_cck + coex_sta->crc_err_cck;
+
+ if (cck_cnt > 250) {
+ if (wl_noisy_count2 < 3)
+ wl_noisy_count2++;
+
+ if (wl_noisy_count2 == 3) {
+ wl_noisy_count0 = 0;
+ wl_noisy_count1 = 0;
+ }
+
+ } else if (cck_cnt < 50) {
+ if (wl_noisy_count0 < 3)
+ wl_noisy_count0++;
+
+ if (wl_noisy_count0 == 3) {
+ wl_noisy_count1 = 0;
+ wl_noisy_count2 = 0;
+ }
+
+ } else {
+ if (wl_noisy_count1 < 3)
+ wl_noisy_count1++;
+
+ if (wl_noisy_count1 == 3) {
+ wl_noisy_count0 = 0;
+ wl_noisy_count2 = 0;
+ }
+ }
+
+ if (wl_noisy_count2 == 3)
+ coex_sta->wl_noisy_level = 2;
+ else if (wl_noisy_count1 == 3)
+ coex_sta->wl_noisy_level = 1;
+ else
+ coex_sta->wl_noisy_level = 0;
+
+ if ((wifi_busy) && (wifi_rssi >= 30) && (!wifi_under_b_mode)) {
+ total_cnt = coex_sta->crc_ok_cck + coex_sta->crc_ok_11g +
+ coex_sta->crc_ok_11n + coex_sta->crc_ok_11n_vht;
+
+ if ((coex_dm->bt_status == BT_8822B_1ANT_BT_STATUS_ACL_BUSY) ||
+ (coex_dm->bt_status ==
+ BT_8822B_1ANT_BT_STATUS_ACL_SCO_BUSY) ||
+ (coex_dm->bt_status == BT_8822B_1ANT_BT_STATUS_SCO_BUSY)) {
+ if (coex_sta->crc_ok_cck >
+ (total_cnt - coex_sta->crc_ok_cck)) {
+ if (cck_lock_counter < 3)
+ cck_lock_counter++;
+ } else {
+ if (cck_lock_counter > 0)
+ cck_lock_counter--;
+ }
+
+ } else {
+ if (cck_lock_counter > 0)
+ cck_lock_counter--;
+ }
+ } else {
+ if (cck_lock_counter > 0)
+ cck_lock_counter--;
+ }
+
+ if (!coex_sta->pre_ccklock) {
+ if (cck_lock_counter >= 3)
+ coex_sta->cck_lock = true;
+ else
+ coex_sta->cck_lock = false;
+ } else {
+ if (cck_lock_counter == 0)
+ coex_sta->cck_lock = false;
+ else
+ coex_sta->cck_lock = true;
+ }
+
+ if (coex_sta->cck_lock)
+ coex_sta->cck_ever_lock = true;
+
+ coex_sta->pre_ccklock = coex_sta->cck_lock;
+}
+
+static bool
+halbtc8822b1ant_is_wifi_status_changed(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ static bool pre_wifi_busy, pre_under_4way, pre_bt_hs_on,
+ pre_rf4ce_enabled, pre_bt_off, pre_bt_slave,
+ pre_hid_low_pri_tx_overhead, pre_wifi_under_lps,
+ pre_bt_setup_link;
+ static u8 pre_hid_busy_num, pre_wl_noisy_level;
+ bool wifi_busy = false, under_4way = false, bt_hs_on = false,
+ rf4ce_enabled = false;
+ bool wifi_connected = false;
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
+ &wifi_connected);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS,
+ &under_4way);
+
+ if (coex_sta->bt_disabled != pre_bt_off) {
+ pre_bt_off = coex_sta->bt_disabled;
+
+ if (coex_sta->bt_disabled)
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT is disabled !!\n");
+ else
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT is enabled !!\n");
+
+ coex_sta->bt_coex_supported_feature = 0;
+ coex_sta->bt_coex_supported_version = 0;
+ return true;
+ }
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_RF4CE_CONNECTED,
+ &rf4ce_enabled);
+
+ if (rf4ce_enabled != pre_rf4ce_enabled) {
+ pre_rf4ce_enabled = rf4ce_enabled;
+
+ if (rf4ce_enabled)
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], rf4ce is enabled !!\n");
+ else
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], rf4ce is disabled !!\n");
+
+ return true;
+ }
+
+ if (wifi_connected) {
+ if (wifi_busy != pre_wifi_busy) {
+ pre_wifi_busy = wifi_busy;
+ return true;
+ }
+ if (under_4way != pre_under_4way) {
+ pre_under_4way = under_4way;
+ return true;
+ }
+ if (bt_hs_on != pre_bt_hs_on) {
+ pre_bt_hs_on = bt_hs_on;
+ return true;
+ }
+ if (coex_sta->wl_noisy_level != pre_wl_noisy_level) {
+ pre_wl_noisy_level = coex_sta->wl_noisy_level;
+ return true;
+ }
+ if (coex_sta->under_lps != pre_wifi_under_lps) {
+ pre_wifi_under_lps = coex_sta->under_lps;
+ if (coex_sta->under_lps)
+ return true;
+ }
+ }
+
+ if (!coex_sta->bt_disabled) {
+ if (coex_sta->hid_busy_num != pre_hid_busy_num) {
+ pre_hid_busy_num = coex_sta->hid_busy_num;
+ return true;
+ }
+
+ if (bt_link_info->slave_role != pre_bt_slave) {
+ pre_bt_slave = bt_link_info->slave_role;
+ return true;
+ }
+
+ if (pre_hid_low_pri_tx_overhead !=
+ coex_sta->is_hid_low_pri_tx_overhead) {
+ pre_hid_low_pri_tx_overhead =
+ coex_sta->is_hid_low_pri_tx_overhead;
+ return true;
+ }
+
+ if (pre_bt_setup_link != coex_sta->is_setup_link) {
+ pre_bt_setup_link = coex_sta->is_setup_link;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static void halbtc8822b1ant_update_bt_link_info(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+ bool bt_hs_on = false;
+ bool bt_busy = false;
+
+ coex_sta->num_of_profile = 0;
+
+ /* set link exist status */
+ if (!(coex_sta->bt_info & BT_INFO_8822B_1ANT_B_CONNECTION)) {
+ coex_sta->bt_link_exist = false;
+ coex_sta->pan_exist = false;
+ coex_sta->a2dp_exist = false;
+ coex_sta->hid_exist = false;
+ coex_sta->sco_exist = false;
+ } else { /* connection exists */
+ coex_sta->bt_link_exist = true;
+ if (coex_sta->bt_info & BT_INFO_8822B_1ANT_B_FTP) {
+ coex_sta->pan_exist = true;
+ coex_sta->num_of_profile++;
+ } else {
+ coex_sta->pan_exist = false;
+ }
+
+ if (coex_sta->bt_info & BT_INFO_8822B_1ANT_B_A2DP) {
+ coex_sta->a2dp_exist = true;
+ coex_sta->num_of_profile++;
+ } else {
+ coex_sta->a2dp_exist = false;
+ }
+
+ if (coex_sta->bt_info & BT_INFO_8822B_1ANT_B_HID) {
+ coex_sta->hid_exist = true;
+ coex_sta->num_of_profile++;
+ } else {
+ coex_sta->hid_exist = false;
+ }
+
+ if (coex_sta->bt_info & BT_INFO_8822B_1ANT_B_SCO_ESCO) {
+ coex_sta->sco_exist = true;
+ coex_sta->num_of_profile++;
+ } else {
+ coex_sta->sco_exist = false;
+ }
+ }
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+
+ bt_link_info->bt_link_exist = coex_sta->bt_link_exist;
+ bt_link_info->sco_exist = coex_sta->sco_exist;
+ bt_link_info->a2dp_exist = coex_sta->a2dp_exist;
+ bt_link_info->pan_exist = coex_sta->pan_exist;
+ bt_link_info->hid_exist = coex_sta->hid_exist;
+ bt_link_info->acl_busy = coex_sta->acl_busy;
+
+ /* work around for HS mode. */
+ if (bt_hs_on) {
+ bt_link_info->pan_exist = true;
+ bt_link_info->bt_link_exist = true;
+ }
+
+ /* check if Sco only */
+ if (bt_link_info->sco_exist && !bt_link_info->a2dp_exist &&
+ !bt_link_info->pan_exist && !bt_link_info->hid_exist)
+ bt_link_info->sco_only = true;
+ else
+ bt_link_info->sco_only = false;
+
+ /* check if A2dp only */
+ if (!bt_link_info->sco_exist && bt_link_info->a2dp_exist &&
+ !bt_link_info->pan_exist && !bt_link_info->hid_exist)
+ bt_link_info->a2dp_only = true;
+ else
+ bt_link_info->a2dp_only = false;
+
+ /* check if Pan only */
+ if (!bt_link_info->sco_exist && !bt_link_info->a2dp_exist &&
+ bt_link_info->pan_exist && !bt_link_info->hid_exist)
+ bt_link_info->pan_only = true;
+ else
+ bt_link_info->pan_only = false;
+
+ /* check if Hid only */
+ if (!bt_link_info->sco_exist && !bt_link_info->a2dp_exist &&
+ !bt_link_info->pan_exist && bt_link_info->hid_exist)
+ bt_link_info->hid_only = true;
+ else
+ bt_link_info->hid_only = false;
+
+ if (coex_sta->bt_info & BT_INFO_8822B_1ANT_B_INQ_PAGE) {
+ coex_dm->bt_status = BT_8822B_1ANT_BT_STATUS_INQ_PAGE;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BtInfoNotify(), BT Inq/page!!!\n");
+ } else if (!(coex_sta->bt_info & BT_INFO_8822B_1ANT_B_CONNECTION)) {
+ coex_dm->bt_status = BT_8822B_1ANT_BT_STATUS_NON_CONNECTED_IDLE;
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BtInfoNotify(), BT Non-Connected idle!!!\n");
+ } else if (coex_sta->bt_info == BT_INFO_8822B_1ANT_B_CONNECTION) {
+ /* connection exists but no busy */
+ coex_dm->bt_status = BT_8822B_1ANT_BT_STATUS_CONNECTED_IDLE;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n");
+ } else if (((coex_sta->bt_info & BT_INFO_8822B_1ANT_B_SCO_ESCO) ||
+ (coex_sta->bt_info & BT_INFO_8822B_1ANT_B_SCO_BUSY)) &&
+ (coex_sta->bt_info & BT_INFO_8822B_1ANT_B_ACL_BUSY)) {
+ coex_dm->bt_status = BT_8822B_1ANT_BT_STATUS_ACL_SCO_BUSY;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BtInfoNotify(), BT ACL SCO busy!!!\n");
+ } else if ((coex_sta->bt_info & BT_INFO_8822B_1ANT_B_SCO_ESCO) ||
+ (coex_sta->bt_info & BT_INFO_8822B_1ANT_B_SCO_BUSY)) {
+ coex_dm->bt_status = BT_8822B_1ANT_BT_STATUS_SCO_BUSY;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n");
+ } else if (coex_sta->bt_info & BT_INFO_8822B_1ANT_B_ACL_BUSY) {
+ coex_dm->bt_status = BT_8822B_1ANT_BT_STATUS_ACL_BUSY;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n");
+ } else {
+ coex_dm->bt_status = BT_8822B_1ANT_BT_STATUS_MAX;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BtInfoNotify(), BT Non-Defined state!!!\n");
+ }
+
+ if ((coex_dm->bt_status == BT_8822B_1ANT_BT_STATUS_ACL_BUSY) ||
+ (coex_dm->bt_status == BT_8822B_1ANT_BT_STATUS_SCO_BUSY) ||
+ (coex_dm->bt_status == BT_8822B_1ANT_BT_STATUS_ACL_SCO_BUSY))
+ bt_busy = true;
+ else
+ bt_busy = false;
+
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy);
+}
+
+static void halbtc8822b1ant_update_wifi_ch_info(struct btc_coexist *btcoexist,
+ u8 type)
+{
+ u8 h2c_parameter[3] = {0};
+ u32 wifi_bw;
+ u8 wifi_central_chnl;
+
+ /* only 2.4G we need to inform bt the chnl mask */
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL,
+ &wifi_central_chnl);
+ if ((type == BTC_MEDIA_CONNECT) && (wifi_central_chnl <= 14)) {
+ /* enable BT AFH skip WL channel for 8822b
+ * because BT Rx LO interference
+ */
+ h2c_parameter[0] = 0x1;
+ h2c_parameter[1] = wifi_central_chnl;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ if (wifi_bw == BTC_WIFI_BW_HT40)
+ h2c_parameter[2] = 0x30;
+ else
+ h2c_parameter[2] = 0x20;
+ }
+
+ coex_dm->wifi_chnl_info[0] = h2c_parameter[0];
+ coex_dm->wifi_chnl_info[1] = h2c_parameter[1];
+ coex_dm->wifi_chnl_info[2] = h2c_parameter[2];
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter);
+}
+
+static u8 halbtc8822b1ant_action_algorithm(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+ bool bt_hs_on = false;
+ u8 algorithm = BT_8822B_1ANT_COEX_ALGO_UNDEFINED;
+ u8 num_of_diff_profile = 0;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+
+ if (!bt_link_info->bt_link_exist) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], No BT link exists!!!\n");
+ return algorithm;
+ }
+
+ if (bt_link_info->sco_exist)
+ num_of_diff_profile++;
+ if (bt_link_info->hid_exist)
+ num_of_diff_profile++;
+ if (bt_link_info->pan_exist)
+ num_of_diff_profile++;
+ if (bt_link_info->a2dp_exist)
+ num_of_diff_profile++;
+
+ if (num_of_diff_profile == 1) {
+ if (bt_link_info->sco_exist) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT Profile = SCO only\n");
+ algorithm = BT_8822B_1ANT_COEX_ALGO_SCO;
+ } else {
+ if (bt_link_info->hid_exist) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT Profile = HID only\n");
+ algorithm = BT_8822B_1ANT_COEX_ALGO_HID;
+ } else if (bt_link_info->a2dp_exist) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT Profile = A2DP only\n");
+ algorithm = BT_8822B_1ANT_COEX_ALGO_A2DP;
+ } else if (bt_link_info->pan_exist) {
+ if (bt_hs_on) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], BT Profile = PAN(HS) only\n");
+ algorithm =
+ BT_8822B_1ANT_COEX_ALGO_PANHS;
+ } else {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], BT Profile = PAN(EDR) only\n");
+ algorithm =
+ BT_8822B_1ANT_COEX_ALGO_PANEDR;
+ }
+ }
+ }
+ } else if (num_of_diff_profile == 2) {
+ if (bt_link_info->sco_exist) {
+ if (bt_link_info->hid_exist) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT Profile = SCO + HID\n");
+ algorithm = BT_8822B_1ANT_COEX_ALGO_HID;
+ } else if (bt_link_info->a2dp_exist) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT Profile = SCO + A2DP ==> SCO\n");
+ algorithm = BT_8822B_1ANT_COEX_ALGO_SCO;
+ } else if (bt_link_info->pan_exist) {
+ if (bt_hs_on) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], BT Profile = SCO + PAN(HS)\n");
+ algorithm = BT_8822B_1ANT_COEX_ALGO_SCO;
+ } else {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], BT Profile = SCO + PAN(EDR)\n");
+ algorithm =
+ BT_8822B_1ANT_COEX_ALGO_PANEDR_HID;
+ }
+ }
+ } else {
+ if (bt_link_info->hid_exist &&
+ bt_link_info->a2dp_exist) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT Profile = HID + A2DP\n");
+ algorithm = BT_8822B_1ANT_COEX_ALGO_HID_A2DP;
+ } else if (bt_link_info->hid_exist &&
+ bt_link_info->pan_exist) {
+ if (bt_hs_on) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], BT Profile = HID + PAN(HS)\n");
+ algorithm =
+ BT_8822B_1ANT_COEX_ALGO_HID_A2DP;
+ } else {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], BT Profile = HID + PAN(EDR)\n");
+ algorithm =
+ BT_8822B_1ANT_COEX_ALGO_PANEDR_HID;
+ }
+ } else if (bt_link_info->pan_exist &&
+ bt_link_info->a2dp_exist) {
+ if (bt_hs_on) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], BT Profile = A2DP + PAN(HS)\n");
+ algorithm =
+ BT_8822B_1ANT_COEX_ALGO_A2DP_PANHS;
+ } else {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], BT Profile = A2DP + PAN(EDR)\n");
+ algorithm =
+ BT_8822B_1ANT_COEX_ALGO_PANEDR_A2DP;
+ }
+ }
+ }
+ } else if (num_of_diff_profile == 3) {
+ if (bt_link_info->sco_exist) {
+ if (bt_link_info->hid_exist &&
+ bt_link_info->a2dp_exist) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT Profile = SCO + HID + A2DP ==> HID\n");
+ algorithm = BT_8822B_1ANT_COEX_ALGO_HID;
+ } else if (bt_link_info->hid_exist &&
+ bt_link_info->pan_exist) {
+ if (bt_hs_on) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], BT Profile = SCO + HID + PAN(HS)\n");
+ algorithm =
+ BT_8822B_1ANT_COEX_ALGO_HID_A2DP;
+ } else {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], BT Profile = SCO + HID + PAN(EDR)\n");
+ algorithm =
+ BT_8822B_1ANT_COEX_ALGO_PANEDR_HID;
+ }
+ } else if (bt_link_info->pan_exist &&
+ bt_link_info->a2dp_exist) {
+ if (bt_hs_on) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], BT Profile = SCO + A2DP + PAN(HS)\n");
+ algorithm = BT_8822B_1ANT_COEX_ALGO_SCO;
+ } else {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], BT Profile = SCO + A2DP + PAN(EDR) ==> HID\n");
+ algorithm =
+ BT_8822B_1ANT_COEX_ALGO_PANEDR_HID;
+ }
+ }
+ } else {
+ if (bt_link_info->hid_exist &&
+ bt_link_info->pan_exist &&
+ bt_link_info->a2dp_exist) {
+ if (bt_hs_on) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], BT Profile = HID + A2DP + PAN(HS)\n");
+ algorithm =
+ BT_8822B_1ANT_COEX_ALGO_HID_A2DP;
+ } else {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], BT Profile = HID + A2DP + PAN(EDR)\n");
+ algorithm =
+ BT_8822B_1ANT_COEX_ALGO_HID_A2DP_PANEDR;
+ }
+ }
+ }
+ } else if (num_of_diff_profile >= 3) {
+ if (bt_link_info->sco_exist) {
+ if (bt_link_info->hid_exist &&
+ bt_link_info->pan_exist &&
+ bt_link_info->a2dp_exist) {
+ if (bt_hs_on) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], Error!!! BT Profile = SCO + HID + A2DP + PAN(HS)\n");
+
+ } else {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], BT Profile = SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n");
+ algorithm =
+ BT_8822B_1ANT_COEX_ALGO_PANEDR_HID;
+ }
+ }
+ }
+ }
+
+ return algorithm;
+}
+
+static void halbtc8822b1ant_low_penalty_ra(struct btc_coexist *btcoexist,
+ bool force_exec, bool low_penalty_ra)
+{
+ coex_dm->cur_low_penalty_ra = low_penalty_ra;
+
+ if (!force_exec) {
+ if (coex_dm->pre_low_penalty_ra == coex_dm->cur_low_penalty_ra)
+ return;
+ }
+
+ if (low_penalty_ra)
+ btcoexist->btc_phydm_modify_ra_pcr_threshold(btcoexist, 0, 25);
+ else
+ btcoexist->btc_phydm_modify_ra_pcr_threshold(btcoexist, 0, 0);
+
+ coex_dm->pre_low_penalty_ra = coex_dm->cur_low_penalty_ra;
+}
+
+static void halbtc8822b1ant_write_score_board(struct btc_coexist *btcoexist,
+ u16 bitpos, bool state)
+{
+ static u16 originalval = 0x8002;
+
+ if (state)
+ originalval = originalval | bitpos;
+ else
+ originalval = originalval & (~bitpos);
+
+ btcoexist->btc_write_2byte(btcoexist, 0xaa, originalval);
+}
+
+static void halbtc8822b1ant_read_score_board(struct btc_coexist *btcoexist,
+ u16 *score_board_val)
+{
+ *score_board_val =
+ (btcoexist->btc_read_2byte(btcoexist, 0xaa)) & 0x7fff;
+}
+
+static void halbtc8822b1ant_post_state_to_bt(struct btc_coexist *btcoexist,
+ u16 type, bool state)
+{
+ halbtc8822b1ant_write_score_board(btcoexist, (u16)type, state);
+}
+
+static void
+halbtc8822b1ant_monitor_bt_enable_disable(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ static u32 bt_disable_cnt;
+ bool bt_active = true, bt_disabled = false, wifi_under_5g = false;
+ u16 u16tmp;
+
+ /* This function check if bt is disabled */
+
+ /* Read BT on/off status from scoreboard[1],
+ * enable this only if BT patch support this feature
+ */
+ halbtc8822b1ant_read_score_board(btcoexist, &u16tmp);
+
+ bt_active = u16tmp & BIT(1);
+
+ if (bt_active) {
+ bt_disable_cnt = 0;
+ bt_disabled = false;
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE,
+ &bt_disabled);
+ } else {
+ bt_disable_cnt++;
+ if (bt_disable_cnt >= 2) {
+ bt_disabled = true;
+ bt_disable_cnt = 2;
+ }
+
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE,
+ &bt_disabled);
+ }
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
+
+ if ((wifi_under_5g) || (bt_disabled))
+ halbtc8822b1ant_low_penalty_ra(btcoexist, NORMAL_EXEC, false);
+ else
+ halbtc8822b1ant_low_penalty_ra(btcoexist, NORMAL_EXEC, true);
+
+ if (coex_sta->bt_disabled != bt_disabled) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT is from %s to %s!!\n",
+ (coex_sta->bt_disabled ? "disabled" : "enabled"),
+ (bt_disabled ? "disabled" : "enabled"));
+ coex_sta->bt_disabled = bt_disabled;
+ }
+}
+
+static void halbtc8822b1ant_enable_gnt_to_gpio(struct btc_coexist *btcoexist,
+ bool isenable)
+{
+ static u8 bit_val[5] = {0, 0, 0, 0, 0};
+ static bool state;
+
+ if (!btcoexist->dbg_mode_1ant)
+ return;
+
+ if (state == isenable)
+ return;
+
+ state = isenable;
+
+ if (isenable) {
+ /* enable GNT_WL, GNT_BT to GPIO for debug */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x73, 0x8, 0x1);
+
+ /* store original value */
+ bit_val[0] =
+ (btcoexist->btc_read_1byte(btcoexist, 0x66) & BIT(4)) >>
+ 4; /*0x66[4] */
+ bit_val[1] = (btcoexist->btc_read_1byte(btcoexist, 0x67) &
+ BIT(0)); /*0x66[8] */
+ bit_val[2] =
+ (btcoexist->btc_read_1byte(btcoexist, 0x42) & BIT(3)) >>
+ 3; /*0x40[19] */
+ bit_val[3] =
+ (btcoexist->btc_read_1byte(btcoexist, 0x65) & BIT(7)) >>
+ 7; /*0x64[15] */
+ bit_val[4] =
+ (btcoexist->btc_read_1byte(btcoexist, 0x72) & BIT(2)) >>
+ 2; /*0x70[18] */
+
+ /* switch GPIO Mux */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x66, BIT(4),
+ 0x0); /*0x66[4] = 0 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, BIT(0),
+ 0x0); /*0x66[8] = 0 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x42, BIT(3),
+ 0x0); /*0x40[19] = 0 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x65, BIT(7),
+ 0x0); /*0x64[15] = 0 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x72, BIT(2),
+ 0x0); /*0x70[18] = 0 */
+
+ } else {
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x73, 0x8, 0x0);
+
+ /* Restore original value */
+ /* switch GPIO Mux */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x66, BIT(4),
+ bit_val[0]); /*0x66[4] = 0 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, BIT(0),
+ bit_val[1]); /*0x66[8] = 0 */
+ btcoexist->btc_write_1byte_bitmask(
+ btcoexist, 0x42, BIT(3), bit_val[2]); /*0x40[19] = 0 */
+ btcoexist->btc_write_1byte_bitmask(
+ btcoexist, 0x65, BIT(7), bit_val[3]); /*0x64[15] = 0 */
+ btcoexist->btc_write_1byte_bitmask(
+ btcoexist, 0x72, BIT(2), bit_val[4]); /*0x70[18] = 0 */
+ }
+}
+
+static u32
+halbtc8822b1ant_ltecoex_indirect_read_reg(struct btc_coexist *btcoexist,
+ u16 reg_addr)
+{
+ u32 delay_count = 0;
+
+ /* wait for ready bit before access 0x1700 */
+ while (1) {
+ if ((btcoexist->btc_read_1byte(btcoexist, 0x1703) & BIT(5)) ==
+ 0) {
+ mdelay(50);
+ delay_count++;
+ if (delay_count >= 10) {
+ delay_count = 0;
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+
+ btcoexist->btc_write_4byte(btcoexist, 0x1700, 0x800F0000 | reg_addr);
+
+ return btcoexist->btc_read_4byte(btcoexist, 0x1708); /* get read data */
+}
+
+static void
+halbtc8822b1ant_ltecoex_indirect_write_reg(struct btc_coexist *btcoexist,
+ u16 reg_addr, u32 bit_mask,
+ u32 reg_value)
+{
+ u32 val, i = 0, bitpos = 0, delay_count = 0;
+
+ if (bit_mask == 0x0)
+ return;
+
+ if (bit_mask == 0xffffffff) {
+ /* wait for ready bit before access 0x1700/0x1704 */
+ while (1) {
+ if ((btcoexist->btc_read_1byte(btcoexist, 0x1703) &
+ BIT(5)) == 0) {
+ mdelay(50);
+ delay_count++;
+ if (delay_count >= 10) {
+ delay_count = 0;
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+
+ btcoexist->btc_write_4byte(btcoexist, 0x1704,
+ reg_value); /* put write data */
+
+ btcoexist->btc_write_4byte(btcoexist, 0x1700,
+ 0xc00F0000 | reg_addr);
+ } else {
+ for (i = 0; i <= 31; i++) {
+ if (((bit_mask >> i) & 0x1) == 0x1) {
+ bitpos = i;
+ break;
+ }
+ }
+
+ /* read back register value before write */
+ val = halbtc8822b1ant_ltecoex_indirect_read_reg(btcoexist,
+ reg_addr);
+ val = (val & (~bit_mask)) | (reg_value << bitpos);
+
+ /* wait for ready bit before access 0x1700/0x1704 */
+ while (1) {
+ if ((btcoexist->btc_read_1byte(btcoexist, 0x1703) &
+ BIT(5)) == 0) {
+ mdelay(50);
+ delay_count++;
+ if (delay_count >= 10) {
+ delay_count = 0;
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+
+ btcoexist->btc_write_4byte(btcoexist, 0x1704,
+ val); /* put write data */
+
+ btcoexist->btc_write_4byte(btcoexist, 0x1700,
+ 0xc00F0000 | reg_addr);
+ }
+}
+
+static void halbtc8822b1ant_ltecoex_enable(struct btc_coexist *btcoexist,
+ bool enable)
+{
+ u8 val;
+
+ val = (enable) ? 1 : 0;
+ /* 0x38[7] */
+ halbtc8822b1ant_ltecoex_indirect_write_reg(btcoexist, 0x38, 0x80, val);
+}
+
+static void
+halbtc8822b1ant_ltecoex_pathcontrol_owner(struct btc_coexist *btcoexist,
+ bool wifi_control)
+{
+ u8 val;
+
+ val = (wifi_control) ? 1 : 0;
+ /* 0x70[26] */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x73, 0x4, val);
+}
+
+static void halbtc8822b1ant_ltecoex_set_gnt_bt(struct btc_coexist *btcoexist,
+ u8 control_block,
+ bool sw_control, u8 state)
+{
+ u32 val = 0, bit_mask;
+
+ state = state & 0x1;
+ /*LTE indirect 0x38=0xccxx (sw : gnt_wl=1,sw gnt_bt=1)
+ *0x38=0xddxx (sw : gnt_bt=1 , sw gnt_wl=0)
+ *0x38=0x55xx(hw pta :gnt_wl /gnt_bt )
+ */
+ val = (sw_control) ? ((state << 1) | 0x1) : 0;
+
+ switch (control_block) {
+ case BT_8822B_1ANT_GNT_BLOCK_RFC_BB:
+ default:
+ bit_mask = 0xc000;
+ halbtc8822b1ant_ltecoex_indirect_write_reg(
+ btcoexist, 0x38, bit_mask, val); /* 0x38[15:14] */
+ bit_mask = 0x0c00;
+ halbtc8822b1ant_ltecoex_indirect_write_reg(
+ btcoexist, 0x38, bit_mask, val); /* 0x38[11:10] */
+ break;
+ case BT_8822B_1ANT_GNT_BLOCK_RFC:
+ bit_mask = 0xc000;
+ halbtc8822b1ant_ltecoex_indirect_write_reg(
+ btcoexist, 0x38, bit_mask, val); /* 0x38[15:14] */
+ break;
+ case BT_8822B_1ANT_GNT_BLOCK_BB:
+ bit_mask = 0x0c00;
+ halbtc8822b1ant_ltecoex_indirect_write_reg(
+ btcoexist, 0x38, bit_mask, val); /* 0x38[11:10] */
+ break;
+ }
+}
+
+static void halbtc8822b1ant_ltecoex_set_gnt_wl(struct btc_coexist *btcoexist,
+ u8 control_block,
+ bool sw_control, u8 state)
+{
+ u32 val = 0, bit_mask;
+ /*LTE indirect 0x38=0xccxx (sw : gnt_wl=1,sw gnt_bt=1)
+ *0x38=0xddxx (sw : gnt_bt=1 , sw gnt_wl=0)
+ *0x38=0x55xx(hw pta :gnt_wl /gnt_bt )
+ */
+
+ state = state & 0x1;
+ val = (sw_control) ? ((state << 1) | 0x1) : 0;
+
+ switch (control_block) {
+ case BT_8822B_1ANT_GNT_BLOCK_RFC_BB:
+ default:
+ bit_mask = 0x3000;
+ halbtc8822b1ant_ltecoex_indirect_write_reg(
+ btcoexist, 0x38, bit_mask, val); /* 0x38[13:12] */
+ bit_mask = 0x0300;
+ halbtc8822b1ant_ltecoex_indirect_write_reg(
+ btcoexist, 0x38, bit_mask, val); /* 0x38[9:8] */
+ break;
+ case BT_8822B_1ANT_GNT_BLOCK_RFC:
+ bit_mask = 0x3000;
+ halbtc8822b1ant_ltecoex_indirect_write_reg(
+ btcoexist, 0x38, bit_mask, val); /* 0x38[13:12] */
+ break;
+ case BT_8822B_1ANT_GNT_BLOCK_BB:
+ bit_mask = 0x0300;
+ halbtc8822b1ant_ltecoex_indirect_write_reg(
+ btcoexist, 0x38, bit_mask, val); /* 0x38[9:8] */
+ break;
+ }
+}
+
+static void
+halbtc8822b1ant_ltecoex_set_coex_table(struct btc_coexist *btcoexist,
+ u8 table_type, u16 table_content)
+{
+ u16 reg_addr = 0x0000;
+
+ switch (table_type) {
+ case BT_8822B_1ANT_CTT_WL_VS_LTE:
+ reg_addr = 0xa0;
+ break;
+ case BT_8822B_1ANT_CTT_BT_VS_LTE:
+ reg_addr = 0xa4;
+ break;
+ }
+
+ if (reg_addr != 0x0000)
+ halbtc8822b1ant_ltecoex_indirect_write_reg(
+ btcoexist, reg_addr, 0xffff,
+ table_content); /* 0xa0[15:0] or 0xa4[15:0] */
+}
+
+static void halbtc8822b1ant_set_wltoggle_coex_table(
+ struct btc_coexist *btcoexist, bool force_exec, u8 interval,
+ u8 val0x6c4_b0, u8 val0x6c4_b1, u8 val0x6c4_b2, u8 val0x6c4_b3)
+{
+ static u8 pre_h2c_parameter[6] = {0};
+ u8 cur_h2c_parameter[6] = {0};
+ u8 i, match_cnt = 0;
+
+ cur_h2c_parameter[0] = 0x7; /* op_code, 0x7= wlan toggle slot*/
+
+ cur_h2c_parameter[1] = interval;
+ cur_h2c_parameter[2] = val0x6c4_b0;
+ cur_h2c_parameter[3] = val0x6c4_b1;
+ cur_h2c_parameter[4] = val0x6c4_b2;
+ cur_h2c_parameter[5] = val0x6c4_b3;
+
+ if (!force_exec) {
+ for (i = 1; i <= 5; i++) {
+ if (cur_h2c_parameter[i] != pre_h2c_parameter[i])
+ break;
+
+ match_cnt++;
+ }
+
+ if (match_cnt == 5)
+ return;
+ }
+
+ for (i = 1; i <= 5; i++)
+ pre_h2c_parameter[i] = cur_h2c_parameter[i];
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x69, 6, cur_h2c_parameter);
+}
+
+static void halbtc8822b1ant_set_coex_table(struct btc_coexist *btcoexist,
+ u32 val0x6c0, u32 val0x6c4,
+ u32 val0x6c8, u8 val0x6cc)
+{
+ btcoexist->btc_write_4byte(btcoexist, 0x6c0, val0x6c0);
+
+ btcoexist->btc_write_4byte(btcoexist, 0x6c4, val0x6c4);
+
+ btcoexist->btc_write_4byte(btcoexist, 0x6c8, val0x6c8);
+
+ btcoexist->btc_write_1byte(btcoexist, 0x6cc, val0x6cc);
+}
+
+static void halbtc8822b1ant_coex_table(struct btc_coexist *btcoexist,
+ bool force_exec, u32 val0x6c0,
+ u32 val0x6c4, u32 val0x6c8, u8 val0x6cc)
+{
+ coex_dm->cur_val0x6c0 = val0x6c0;
+ coex_dm->cur_val0x6c4 = val0x6c4;
+ coex_dm->cur_val0x6c8 = val0x6c8;
+ coex_dm->cur_val0x6cc = val0x6cc;
+
+ if (!force_exec) {
+ if ((coex_dm->pre_val0x6c0 == coex_dm->cur_val0x6c0) &&
+ (coex_dm->pre_val0x6c4 == coex_dm->cur_val0x6c4) &&
+ (coex_dm->pre_val0x6c8 == coex_dm->cur_val0x6c8) &&
+ (coex_dm->pre_val0x6cc == coex_dm->cur_val0x6cc))
+ return;
+ }
+ halbtc8822b1ant_set_coex_table(btcoexist, val0x6c0, val0x6c4, val0x6c8,
+ val0x6cc);
+
+ coex_dm->pre_val0x6c0 = coex_dm->cur_val0x6c0;
+ coex_dm->pre_val0x6c4 = coex_dm->cur_val0x6c4;
+ coex_dm->pre_val0x6c8 = coex_dm->cur_val0x6c8;
+ coex_dm->pre_val0x6cc = coex_dm->cur_val0x6cc;
+}
+
+static void halbtc8822b1ant_coex_table_with_type(struct btc_coexist *btcoexist,
+ bool force_exec, u8 type)
+{
+ u32 break_table;
+ u8 select_table;
+
+ coex_sta->coex_table_type = type;
+
+ if (coex_sta->concurrent_rx_mode_on) {
+ break_table = 0xf0ffffff; /* set WL hi-pri can break BT */
+ select_table = 0x3; /* set Tx response = Hi-Pri
+ * (ex: Transmitting ACK,BA,CTS)
+ */
+ } else {
+ break_table = 0xffffff;
+ select_table = 0x3;
+ }
+
+ switch (type) {
+ case 0:
+ halbtc8822b1ant_coex_table(btcoexist, force_exec, 0x55555555,
+ 0x55555555, break_table,
+ select_table);
+ break;
+ case 1:
+ halbtc8822b1ant_coex_table(btcoexist, force_exec, 0x55555555,
+ 0x5a5a5a5a, break_table,
+ select_table);
+ break;
+ case 2:
+ halbtc8822b1ant_coex_table(btcoexist, force_exec, 0xaa5a5a5a,
+ 0xaa5a5a5a, break_table,
+ select_table);
+ break;
+ case 3:
+ halbtc8822b1ant_coex_table(btcoexist, force_exec, 0x55555555,
+ 0xaa5a5a5a, break_table,
+ select_table);
+ break;
+ case 4:
+ halbtc8822b1ant_coex_table(btcoexist, force_exec, 0xaa555555,
+ 0xaa5a5a5a, break_table,
+ select_table);
+ break;
+ case 5:
+ halbtc8822b1ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a,
+ 0x5a5a5a5a, break_table,
+ select_table);
+ break;
+ case 6:
+ halbtc8822b1ant_coex_table(btcoexist, force_exec, 0x55555555,
+ 0xaaaaaaaa, break_table,
+ select_table);
+ break;
+ case 7:
+ halbtc8822b1ant_coex_table(btcoexist, force_exec, 0xaaaaaaaa,
+ 0xaaaaaaaa, break_table,
+ select_table);
+ break;
+ case 8:
+ halbtc8822b1ant_coex_table(btcoexist, force_exec, 0xffffffff,
+ 0xffffffff, break_table,
+ select_table);
+ break;
+ case 9:
+ halbtc8822b1ant_coex_table(btcoexist, force_exec, 0x5a5a5555,
+ 0xaaaa5a5a, break_table,
+ select_table);
+ break;
+ case 10:
+ halbtc8822b1ant_coex_table(btcoexist, force_exec, 0xaaaa5aaa,
+ 0xaaaa5aaa, break_table,
+ select_table);
+ break;
+ case 11:
+ halbtc8822b1ant_coex_table(btcoexist, force_exec, 0xaaaaa5aa,
+ 0xaaaaaaaa, break_table,
+ select_table);
+ break;
+ case 12:
+ halbtc8822b1ant_coex_table(btcoexist, force_exec, 0xaaaaa5aa,
+ 0xaaaaa5aa, break_table,
+ select_table);
+ break;
+ case 13:
+ halbtc8822b1ant_coex_table(btcoexist, force_exec, 0x55555555,
+ 0xaaaa5a5a, break_table,
+ select_table);
+ break;
+ case 14:
+ halbtc8822b1ant_coex_table(btcoexist, force_exec, 0x5a5a555a,
+ 0xaaaa5a5a, break_table,
+ select_table);
+ break;
+ case 15:
+ halbtc8822b1ant_coex_table(btcoexist, force_exec, 0x55555555,
+ 0xaaaa55aa, break_table,
+ select_table);
+ break;
+ case 16:
+ halbtc8822b1ant_coex_table(btcoexist, force_exec, 0x5a5a555a,
+ 0x5a5a555a, break_table,
+ select_table);
+ break;
+ case 17:
+ halbtc8822b1ant_coex_table(btcoexist, force_exec, 0xaaaa55aa,
+ 0xaaaa55aa, break_table,
+ select_table);
+ break;
+ case 18:
+ halbtc8822b1ant_coex_table(btcoexist, force_exec, 0x55555555,
+ 0x5aaa5a5a, break_table,
+ select_table);
+ break;
+ case 19:
+ halbtc8822b1ant_coex_table(btcoexist, force_exec, 0xa5555555,
+ 0xaaaa5aaa, break_table,
+ select_table);
+ break;
+ case 20:
+ halbtc8822b1ant_coex_table(btcoexist, force_exec, 0x55555555,
+ 0xaaaa5aaa, break_table,
+ select_table);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+halbtc8822b1ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoexist,
+ bool enable)
+{
+ u8 h2c_parameter[1] = {0};
+
+ if (enable)
+ h2c_parameter[0] |= BIT(0); /* function enable */
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x63, 1, h2c_parameter);
+}
+
+static void halbtc8822b1ant_ignore_wlan_act(struct btc_coexist *btcoexist,
+ bool force_exec, bool enable)
+{
+ coex_dm->cur_ignore_wlan_act = enable;
+
+ if (!force_exec) {
+ if (coex_dm->pre_ignore_wlan_act ==
+ coex_dm->cur_ignore_wlan_act) {
+ coex_dm->pre_ignore_wlan_act =
+ coex_dm->cur_ignore_wlan_act;
+ return;
+ }
+ }
+
+ halbtc8822b1ant_set_fw_ignore_wlan_act(btcoexist, enable);
+
+ coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act;
+}
+
+static void halbtc8822b1ant_set_lps_rpwm(struct btc_coexist *btcoexist,
+ u8 lps_val, u8 rpwm_val)
+{
+ u8 lps = lps_val;
+ u8 rpwm = rpwm_val;
+
+ btcoexist->btc_set(btcoexist, BTC_SET_U1_LPS_VAL, &lps);
+ btcoexist->btc_set(btcoexist, BTC_SET_U1_RPWM_VAL, &rpwm);
+}
+
+static void halbtc8822b1ant_lps_rpwm(struct btc_coexist *btcoexist,
+ bool force_exec, u8 lps_val, u8 rpwm_val)
+{
+ coex_dm->cur_lps = lps_val;
+ coex_dm->cur_rpwm = rpwm_val;
+
+ if (!force_exec) {
+ if ((coex_dm->pre_lps == coex_dm->cur_lps) &&
+ (coex_dm->pre_rpwm == coex_dm->cur_rpwm))
+ return;
+ }
+ halbtc8822b1ant_set_lps_rpwm(btcoexist, lps_val, rpwm_val);
+
+ coex_dm->pre_lps = coex_dm->cur_lps;
+ coex_dm->pre_rpwm = coex_dm->cur_rpwm;
+}
+
+static void halbtc8822b1ant_ps_tdma_check_for_power_save_state(
+ struct btc_coexist *btcoexist, bool new_ps_state)
+{
+ u8 lps_mode = 0x0;
+ u8 h2c_parameter[5] = {0x8, 0, 0, 0, 0};
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_LPS_MODE, &lps_mode);
+
+ if (lps_mode) { /* already under LPS state */
+ if (new_ps_state) {
+ /* keep state under LPS, do nothing. */
+ } else {
+ /* will leave LPS state, turn off psTdma first */
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x60, 5,
+ h2c_parameter);
+ }
+ } else { /* NO PS state */
+ if (new_ps_state) {
+ /* will enter LPS state, turn off psTdma first */
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x60, 5,
+ h2c_parameter);
+ } else {
+ /* keep state under NO PS state, do nothing. */
+ }
+ }
+}
+
+static bool halbtc8822b1ant_power_save_state(struct btc_coexist *btcoexist,
+ u8 ps_type, u8 lps_val,
+ u8 rpwm_val)
+{
+ bool low_pwr_disable = false, result = true;
+
+ switch (ps_type) {
+ case BTC_PS_WIFI_NATIVE:
+ /* recover to original 32k low power setting */
+ coex_sta->force_lps_ctrl = false;
+ low_pwr_disable = false;
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
+ &low_pwr_disable);
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_NORMAL_LPS, NULL);
+ break;
+ case BTC_PS_LPS_ON:
+
+ coex_sta->force_lps_ctrl = true;
+ halbtc8822b1ant_ps_tdma_check_for_power_save_state(btcoexist,
+ true);
+ halbtc8822b1ant_lps_rpwm(btcoexist, NORMAL_EXEC, lps_val,
+ rpwm_val);
+ /* when coex force to enter LPS, do not enter 32k low power. */
+ low_pwr_disable = true;
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
+ &low_pwr_disable);
+ /* power save must executed before psTdma. */
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL);
+
+ break;
+ case BTC_PS_LPS_OFF:
+
+ coex_sta->force_lps_ctrl = true;
+ halbtc8822b1ant_ps_tdma_check_for_power_save_state(btcoexist,
+ false);
+ result = btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS,
+ NULL);
+
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+static void halbtc8822b1ant_set_fw_pstdma(struct btc_coexist *btcoexist,
+ u8 byte1, u8 byte2, u8 byte3,
+ u8 byte4, u8 byte5)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ u8 h2c_parameter[5] = {0};
+ u8 real_byte1 = byte1, real_byte5 = byte5;
+ bool ap_enable = false, result = false;
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+
+ if (byte5 & BIT(2))
+ coex_sta->is_tdma_btautoslot = true;
+ else
+ coex_sta->is_tdma_btautoslot = false;
+
+ /* release bt-auto slot for auto-slot hang is detected!! */
+ if (coex_sta->is_tdma_btautoslot)
+ if ((coex_sta->is_tdma_btautoslot_hang) ||
+ (bt_link_info->slave_role))
+ byte5 = byte5 & 0xfb;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
+ &ap_enable);
+
+ if ((ap_enable) && (byte1 & BIT(4) && !(byte1 & BIT(5)))) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], %s == FW for 1Ant AP mode\n", __func__);
+
+ real_byte1 &= ~BIT(4);
+ real_byte1 |= BIT(5);
+
+ real_byte5 |= BIT(5);
+ real_byte5 &= ~BIT(6);
+
+ halbtc8822b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
+ 0x0, 0x0);
+
+ } else if (byte1 & BIT(4) && !(byte1 & BIT(5))) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], %s == Force LPS (byte1 = 0x%x)\n",
+ __func__, byte1);
+ if (!halbtc8822b1ant_power_save_state(btcoexist, BTC_PS_LPS_OFF,
+ 0x50, 0x4))
+ result = true;
+ } else {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], %s == native power save (byte1 = 0x%x)\n",
+ __func__, byte1);
+ halbtc8822b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
+ 0x0, 0x0);
+ }
+
+ coex_sta->is_set_ps_state_fail = result;
+
+ if (!coex_sta->is_set_ps_state_fail) {
+ h2c_parameter[0] = real_byte1;
+ h2c_parameter[1] = byte2;
+ h2c_parameter[2] = byte3;
+ h2c_parameter[3] = byte4;
+ h2c_parameter[4] = real_byte5;
+
+ coex_dm->ps_tdma_para[0] = real_byte1;
+ coex_dm->ps_tdma_para[1] = byte2;
+ coex_dm->ps_tdma_para[2] = byte3;
+ coex_dm->ps_tdma_para[3] = byte4;
+ coex_dm->ps_tdma_para[4] = real_byte5;
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x60, 5, h2c_parameter);
+
+ } else {
+ coex_sta->cnt_set_ps_state_fail++;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], %s == Force Leave LPS Fail (cnt = %d)\n",
+ __func__, coex_sta->cnt_set_ps_state_fail);
+ }
+}
+
+static void halbtc8822b1ant_ps_tdma(struct btc_coexist *btcoexist,
+ bool force_exec, bool turn_on, u8 type)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+ bool wifi_busy = false;
+ static u8 ps_tdma_byte4_modify, pre_ps_tdma_byte4_modify;
+ static bool pre_wifi_busy;
+
+ coex_dm->cur_ps_tdma_on = turn_on;
+ coex_dm->cur_ps_tdma = type;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+
+ if (wifi_busy != pre_wifi_busy) {
+ force_exec = true;
+ pre_wifi_busy = wifi_busy;
+ }
+
+ /* 0x778 = 0x1 at wifi slot (no blocking BT Low-Pri pkts) */
+ if (bt_link_info->slave_role)
+ ps_tdma_byte4_modify = 0x1;
+ else
+ ps_tdma_byte4_modify = 0x0;
+
+ if (pre_ps_tdma_byte4_modify != ps_tdma_byte4_modify) {
+ force_exec = true;
+ pre_ps_tdma_byte4_modify = ps_tdma_byte4_modify;
+ }
+
+ if (!force_exec) {
+ if ((coex_dm->pre_ps_tdma_on == coex_dm->cur_ps_tdma_on) &&
+ (coex_dm->pre_ps_tdma == coex_dm->cur_ps_tdma)) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Skip TDMA because no change TDMA(%s, %d)\n",
+ (coex_dm->cur_ps_tdma_on ? "on" : "off"),
+ coex_dm->cur_ps_tdma);
+ return;
+ }
+ }
+
+ if (coex_dm->cur_ps_tdma_on) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** TDMA(on, %d) **********\n",
+ coex_dm->cur_ps_tdma);
+
+ btcoexist->btc_write_1byte_bitmask(
+ btcoexist, 0x550, 0x8, 0x1); /* enable TBTT nterrupt */
+ } else {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** TDMA(off, %d) **********\n",
+ coex_dm->cur_ps_tdma);
+ }
+
+ if (turn_on) {
+ /* enable TBTT nterrupt */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x550, 0x8, 0x1);
+
+ switch (type) {
+ default:
+ halbtc8822b1ant_set_fw_pstdma(btcoexist, 0x61, 0x35,
+ 0x03, 0x11, 0x11);
+ break;
+ case 1:
+ halbtc8822b1ant_set_fw_pstdma(btcoexist, 0x61, 0x3a,
+ 0x03, 0x11, 0x10);
+ break;
+ case 3:
+ halbtc8822b1ant_set_fw_pstdma(btcoexist, 0x51, 0x30,
+ 0x03, 0x10, 0x50);
+ break;
+ case 4:
+ halbtc8822b1ant_set_fw_pstdma(btcoexist, 0x51, 0x21,
+ 0x03, 0x10, 0x50);
+ break;
+ case 5:
+ halbtc8822b1ant_set_fw_pstdma(btcoexist, 0x61, 0x15,
+ 0x3, 0x11, 0x11);
+ break;
+ case 6:
+ halbtc8822b1ant_set_fw_pstdma(btcoexist, 0x61, 0x20,
+ 0x3, 0x11, 0x10);
+ break;
+ case 7:
+ halbtc8822b1ant_set_fw_pstdma(
+ btcoexist, 0x51, 0x10, 0x03, 0x10,
+ 0x54 | ps_tdma_byte4_modify);
+ break;
+ case 8:
+ halbtc8822b1ant_set_fw_pstdma(
+ btcoexist, 0x51, 0x10, 0x03, 0x10,
+ 0x14 | ps_tdma_byte4_modify);
+ break;
+ case 11:
+ halbtc8822b1ant_set_fw_pstdma(
+ btcoexist, 0x61, 0x25, 0x03, 0x11,
+ 0x10 | ps_tdma_byte4_modify);
+ break;
+ case 12:
+ halbtc8822b1ant_set_fw_pstdma(
+ btcoexist, 0x51, 0x30, 0x03, 0x10,
+ 0x50 | ps_tdma_byte4_modify);
+ break;
+ case 13:
+ halbtc8822b1ant_set_fw_pstdma(
+ btcoexist, 0x51, 0x10, 0x07, 0x10,
+ 0x54 | ps_tdma_byte4_modify);
+ break;
+ case 14:
+ halbtc8822b1ant_set_fw_pstdma(
+ btcoexist, 0x51, 0x15, 0x03, 0x10,
+ 0x50 | ps_tdma_byte4_modify);
+ break;
+ case 15:
+ halbtc8822b1ant_set_fw_pstdma(
+ btcoexist, 0x51, 0x20, 0x03, 0x10,
+ 0x10 | ps_tdma_byte4_modify);
+ break;
+ case 17:
+ halbtc8822b1ant_set_fw_pstdma(
+ btcoexist, 0x61, 0x10, 0x03, 0x11,
+ 0x14 | ps_tdma_byte4_modify);
+ break;
+ case 18:
+ halbtc8822b1ant_set_fw_pstdma(
+ btcoexist, 0x51, 0x10, 0x03, 0x10,
+ 0x50 | ps_tdma_byte4_modify);
+ break;
+
+ case 20:
+ halbtc8822b1ant_set_fw_pstdma(btcoexist, 0x61, 0x30,
+ 0x03, 0x11, 0x10);
+ break;
+ case 22:
+ halbtc8822b1ant_set_fw_pstdma(btcoexist, 0x61, 0x25,
+ 0x03, 0x11, 0x10);
+ break;
+ case 27:
+ halbtc8822b1ant_set_fw_pstdma(btcoexist, 0x61, 0x10,
+ 0x03, 0x11, 0x15);
+ break;
+ case 32:
+ halbtc8822b1ant_set_fw_pstdma(btcoexist, 0x61, 0x35,
+ 0x3, 0x11, 0x11);
+ break;
+ case 33:
+ halbtc8822b1ant_set_fw_pstdma(btcoexist, 0x61, 0x35,
+ 0x03, 0x11, 0x10);
+ break;
+ case 41:
+ halbtc8822b1ant_set_fw_pstdma(btcoexist, 0x51, 0x45,
+ 0x3, 0x11, 0x11);
+ break;
+ case 42:
+ halbtc8822b1ant_set_fw_pstdma(
+ btcoexist, 0x51, 0x1e, 0x3, 0x10,
+ 0x14 | ps_tdma_byte4_modify);
+ break;
+ case 43:
+ halbtc8822b1ant_set_fw_pstdma(btcoexist, 0x51, 0x45,
+ 0x3, 0x10, 0x14);
+ break;
+ case 44:
+ halbtc8822b1ant_set_fw_pstdma(btcoexist, 0x51, 0x25,
+ 0x3, 0x10, 0x10);
+ break;
+ case 45:
+ halbtc8822b1ant_set_fw_pstdma(btcoexist, 0x51, 0x29,
+ 0x3, 0x10, 0x10);
+ break;
+ case 46:
+ halbtc8822b1ant_set_fw_pstdma(btcoexist, 0x51, 0x1a,
+ 0x3, 0x10, 0x10);
+ break;
+ case 47:
+ halbtc8822b1ant_set_fw_pstdma(btcoexist, 0x51, 0x32,
+ 0x3, 0x10, 0x10);
+ break;
+ case 48:
+ halbtc8822b1ant_set_fw_pstdma(btcoexist, 0x51, 0x29,
+ 0x3, 0x10, 0x10);
+ break;
+ case 49:
+ halbtc8822b1ant_set_fw_pstdma(btcoexist, 0x55, 0x10,
+ 0x3, 0x10, 0x54);
+ break;
+ case 50:
+ halbtc8822b1ant_set_fw_pstdma(btcoexist, 0x51, 0x4a,
+ 0x3, 0x10, 0x10);
+ break;
+ case 51:
+ halbtc8822b1ant_set_fw_pstdma(btcoexist, 0x61, 0x35,
+ 0x3, 0x10, 0x11);
+ break;
+ }
+ } else {
+ switch (type) {
+ case 0:
+ default: /* Software control, Antenna at BT side */
+ halbtc8822b1ant_set_fw_pstdma(btcoexist, 0x0, 0x0, 0x0,
+ 0x0, 0x0);
+ break;
+ case 8: /* PTA Control */
+ halbtc8822b1ant_set_fw_pstdma(btcoexist, 0x8, 0x0, 0x0,
+ 0x0, 0x0);
+ break;
+ case 9: /* Software control, Antenna at WiFi side */
+ halbtc8822b1ant_set_fw_pstdma(btcoexist, 0x0, 0x0, 0x0,
+ 0x0, 0x0);
+ break;
+ case 10: /* under 5G , 0x778=1*/
+ halbtc8822b1ant_set_fw_pstdma(btcoexist, 0x0, 0x0, 0x0,
+ 0x0, 0x0);
+
+ break;
+ }
+ }
+
+ if (!coex_sta->is_set_ps_state_fail) {
+ /* update pre state */
+ coex_dm->pre_ps_tdma_on = coex_dm->cur_ps_tdma_on;
+ coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma;
+ }
+}
+
+static void halbtc8822b1ant_sw_mechanism(struct btc_coexist *btcoexist,
+ bool low_penalty_ra)
+{
+ halbtc8822b1ant_low_penalty_ra(btcoexist, NORMAL_EXEC, low_penalty_ra);
+}
+
+/* rf4 type by efuse, and for ant at main aux inverse use,
+ * because is 2x2, and control types are the same, does not need
+ */
+
+static void halbtc8822b1ant_set_rfe_type(struct btc_coexist *btcoexist)
+{
+ struct btc_board_info *board_info = &btcoexist->board_info;
+
+ /* Ext switch buffer mux */
+ btcoexist->btc_write_1byte(btcoexist, 0x974, 0xff);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x1991, 0x3, 0x0);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcbe, 0x8, 0x0);
+
+ /* the following setup should be got from Efuse in the future */
+ rfe_type->rfe_module_type = board_info->rfe_type;
+
+ rfe_type->ext_ant_switch_ctrl_polarity = 0;
+
+ switch (rfe_type->rfe_module_type) {
+ case 0:
+ default:
+ rfe_type->ext_ant_switch_exist = true;
+ rfe_type->ext_ant_switch_type =
+ BT_8822B_1ANT_EXT_ANT_SWITCH_USE_SPDT;
+ break;
+ case 1:
+ rfe_type->ext_ant_switch_exist = true;
+ rfe_type->ext_ant_switch_type =
+ BT_8822B_1ANT_EXT_ANT_SWITCH_USE_SPDT;
+ break;
+ case 2:
+ rfe_type->ext_ant_switch_exist = true;
+ rfe_type->ext_ant_switch_type =
+ BT_8822B_1ANT_EXT_ANT_SWITCH_USE_SPDT;
+ break;
+ case 3:
+ rfe_type->ext_ant_switch_exist = true;
+ rfe_type->ext_ant_switch_type =
+ BT_8822B_1ANT_EXT_ANT_SWITCH_USE_SPDT;
+ break;
+ case 4:
+ rfe_type->ext_ant_switch_exist = true;
+ rfe_type->ext_ant_switch_type =
+ BT_8822B_1ANT_EXT_ANT_SWITCH_USE_SPDT;
+ break;
+ case 5:
+ rfe_type->ext_ant_switch_exist = true;
+ rfe_type->ext_ant_switch_type =
+ BT_8822B_1ANT_EXT_ANT_SWITCH_USE_SPDT;
+ break;
+ case 6:
+ rfe_type->ext_ant_switch_exist = true;
+ rfe_type->ext_ant_switch_type =
+ BT_8822B_1ANT_EXT_ANT_SWITCH_USE_SPDT;
+ break;
+ case 7:
+ rfe_type->ext_ant_switch_exist = true;
+ rfe_type->ext_ant_switch_type =
+ BT_8822B_1ANT_EXT_ANT_SWITCH_USE_SPDT;
+ break;
+ }
+}
+
+/*anttenna control by bb mac bt antdiv pta to write 0x4c 0xcb4,0xcbd*/
+
+static void halbtc8822b1ant_set_ext_ant_switch(struct btc_coexist *btcoexist,
+ bool force_exec, u8 ctrl_type,
+ u8 pos_type)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ bool switch_polatiry_inverse = false;
+ u8 regval_0xcbd = 0, regval_0x64;
+ u32 u32tmp1 = 0, u32tmp2 = 0, u32tmp3 = 0;
+
+ /* Ext switch buffer mux */
+ btcoexist->btc_write_1byte(btcoexist, 0x974, 0xff);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x1991, 0x3, 0x0);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcbe, 0x8, 0x0);
+
+ if (!rfe_type->ext_ant_switch_exist)
+ return;
+
+ coex_dm->cur_ext_ant_switch_status = (ctrl_type << 8) + pos_type;
+
+ if (!force_exec) {
+ if (coex_dm->pre_ext_ant_switch_status ==
+ coex_dm->cur_ext_ant_switch_status)
+ return;
+ }
+
+ coex_dm->pre_ext_ant_switch_status = coex_dm->cur_ext_ant_switch_status;
+
+ /* swap control polarity if use different switch control polarity*/
+ /* Normal switch polarity for SPDT,
+ * 0xcbd[1:0] = 2b'01 => Ant to BTG,
+ * 0xcbd[1:0] = 2b'10 => Ant to WLG
+ */
+ switch_polatiry_inverse = rfe_type->ext_ant_switch_ctrl_polarity == 1;
+
+ switch (pos_type) {
+ default:
+ case BT_8822B_1ANT_EXT_ANT_SWITCH_TO_BT:
+ case BT_8822B_1ANT_EXT_ANT_SWITCH_TO_NOCARE:
+
+ break;
+ case BT_8822B_1ANT_EXT_ANT_SWITCH_TO_WLG:
+ break;
+ case BT_8822B_1ANT_EXT_ANT_SWITCH_TO_WLA:
+ break;
+ }
+
+ if (rfe_type->ext_ant_switch_type ==
+ BT_8822B_1ANT_EXT_ANT_SWITCH_USE_SPDT) {
+ switch (ctrl_type) {
+ default:
+ case BT_8822B_1ANT_EXT_ANT_SWITCH_CTRL_BY_BBSW:
+ /* 0x4c[23] = 0 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4e,
+ 0x80, 0x0);
+ /* 0x4c[24] = 1 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4f,
+ 0x01, 0x1);
+ /* BB SW, DPDT use RFE_ctrl8 and RFE_ctrl9 as ctrl pin*/
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb4,
+ 0xff, 0x77);
+
+ /* 0xcbd[1:0] = 2b'01 for no switch_polatiry_inverse,
+ * ANTSWB =1, ANTSW =0
+ */
+ regval_0xcbd = (!switch_polatiry_inverse ? 0x1 : 0x2);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcbd,
+ 0x3, regval_0xcbd);
+
+ break;
+ case BT_8822B_1ANT_EXT_ANT_SWITCH_CTRL_BY_PTA:
+ /* 0x4c[23] = 0 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4e,
+ 0x80, 0x0);
+ /* 0x4c[24] = 1 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4f,
+ 0x01, 0x1);
+ /* PTA, DPDT use RFE_ctrl8 and RFE_ctrl9 as ctrl pin */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb4,
+ 0xff, 0x66);
+
+ /* 0xcbd[1:0] = 2b'10 for no switch_polatiry_inverse,
+ * ANTSWB =1, ANTSW =0 @ GNT_BT=1
+ */
+ regval_0xcbd = (!switch_polatiry_inverse ? 0x2 : 0x1);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcbd,
+ 0x3, regval_0xcbd);
+
+ break;
+ case BT_8822B_1ANT_EXT_ANT_SWITCH_CTRL_BY_ANTDIV:
+ /* 0x4c[23] = 0 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4e,
+ 0x80, 0x0);
+ /* 0x4c[24] = 1 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4f,
+ 0x01, 0x1);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb4,
+ 0xff, 0x88);
+
+ /* no regval_0xcbd setup required, because
+ * antenna switch control value by antenna diversity
+ */
+
+ break;
+ case BT_8822B_1ANT_EXT_ANT_SWITCH_CTRL_BY_MAC:
+ /* 0x4c[23] = 1 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4e,
+ 0x80, 0x1);
+
+ /* 0x64[0] = 1b'0 for no switch_polatiry_inverse,
+ * DPDT_SEL_N =1, DPDT_SEL_P =0
+ */
+ regval_0x64 = (!switch_polatiry_inverse ? 0x0 : 0x1);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x64, 0x1,
+ regval_0x64);
+ break;
+ case BT_8822B_1ANT_EXT_ANT_SWITCH_CTRL_BY_BT:
+ /* 0x4c[23] = 0 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4e,
+ 0x80, 0x0);
+ /* 0x4c[24] = 0 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4f,
+ 0x01, 0x0);
+
+ /* no setup required, because antenna switch control
+ * value by BT vendor 0xac[1:0]
+ */
+ break;
+ }
+ }
+
+ u32tmp1 = btcoexist->btc_read_4byte(btcoexist, 0xcbc);
+ u32tmp2 = btcoexist->btc_read_4byte(btcoexist, 0x4c);
+ u32tmp3 = btcoexist->btc_read_4byte(btcoexist, 0x64) & 0xff;
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (After Ext Ant switch setup) 0xcbc = 0x%08x, 0x4c = 0x%08x, 0x64= 0x%02x**********\n",
+ u32tmp1, u32tmp2, u32tmp3);
+}
+
+/* set gnt_wl gnt_bt control by sw high low, or
+ * hwpta while in power on, ini, wlan off, wlan only, wl2g non-currrent,
+ * wl2g current, wl5g
+ */
+
+static void halbtc8822b1ant_set_ant_path(struct btc_coexist *btcoexist,
+ u8 ant_pos_type, bool force_exec,
+ u8 phase)
+
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ u8 u8tmp = 0;
+ u32 u32tmp1 = 0;
+ u32 u32tmp2 = 0, u32tmp3 = 0;
+
+ u32tmp1 = halbtc8822b1ant_ltecoex_indirect_read_reg(btcoexist, 0x38);
+
+ /* To avoid indirect access fail */
+ if (((u32tmp1 & 0xf000) >> 12) != ((u32tmp1 & 0x0f00) >> 8)) {
+ force_exec = true;
+ coex_sta->gnt_error_cnt++;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex],(Before Ant Setup) 0x38= 0x%x\n", u32tmp1);
+ }
+
+ /* Ext switch buffer mux */
+ btcoexist->btc_write_1byte(btcoexist, 0x974, 0xff);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x1991, 0x3, 0x0);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcbe, 0x8, 0x0);
+
+ coex_dm->cur_ant_pos_type = (ant_pos_type << 8) + phase;
+
+ if (!force_exec) {
+ if (coex_dm->cur_ant_pos_type == coex_dm->pre_ant_pos_type)
+ return;
+ }
+
+ coex_dm->pre_ant_pos_type = coex_dm->cur_ant_pos_type;
+
+ if (btcoexist->dbg_mode_1ant) {
+ u32tmp1 = halbtc8822b1ant_ltecoex_indirect_read_reg(btcoexist,
+ 0x38);
+ u32tmp2 = halbtc8822b1ant_ltecoex_indirect_read_reg(btcoexist,
+ 0x54);
+ u32tmp3 = btcoexist->btc_read_4byte(btcoexist, 0xcb4);
+
+ u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x73);
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (Before Ant Setup) 0xcb4 = 0x%x, 0x73 = 0x%x, 0x38= 0x%x, 0x54= 0x%x**********\n",
+ u32tmp3, u8tmp, u32tmp1, u32tmp2);
+ }
+
+ switch (phase) {
+ case BT_8822B_1ANT_PHASE_COEX_INIT:
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (set_ant_path - 1ANT_PHASE_COEX_INIT) **********\n");
+
+ /* Disable LTE Coex Function in WiFi side
+ * (this should be on if LTE coex is required)
+ */
+ halbtc8822b1ant_ltecoex_enable(btcoexist, 0x0);
+
+ /* GNT_WL_LTE always = 1
+ * (this should be config if LTE coex is required)
+ */
+ halbtc8822b1ant_ltecoex_set_coex_table(
+ btcoexist, BT_8822B_1ANT_CTT_WL_VS_LTE, 0xffff);
+
+ /* GNT_BT_LTE always = 1
+ * (this should be config if LTE coex is required)
+ */
+ halbtc8822b1ant_ltecoex_set_coex_table(
+ btcoexist, BT_8822B_1ANT_CTT_BT_VS_LTE, 0xffff);
+
+ /* set GNT_BT to SW high */
+ halbtc8822b1ant_ltecoex_set_gnt_bt(
+ btcoexist, BT_8822B_1ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_1ANT_GNT_CTRL_BY_SW,
+ BT_8822B_1ANT_SIG_STA_SET_TO_HIGH);
+
+ /* set GNT_WL to SW low */
+ halbtc8822b1ant_ltecoex_set_gnt_wl(
+ btcoexist, BT_8822B_1ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_1ANT_GNT_CTRL_BY_SW,
+ BT_8822B_1ANT_SIG_STA_SET_TO_LOW);
+
+ /* set Path control owner to WL at initial step */
+ halbtc8822b1ant_ltecoex_pathcontrol_owner(
+ btcoexist, BT_8822B_1ANT_PCO_WLSIDE);
+
+ coex_sta->run_time_state = false;
+
+ /* Ext switch buffer mux */
+ btcoexist->btc_write_1byte(btcoexist, 0x974, 0xff);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x1991, 0x3, 0x0);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcbe, 0x8, 0x0);
+
+ if (ant_pos_type == BTC_ANT_PATH_AUTO)
+ ant_pos_type = BTC_ANT_PATH_BT;
+
+ break;
+ case BT_8822B_1ANT_PHASE_WLANONLY_INIT:
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (set_ant_path - 1ANT_PHASE_WLANONLY_INIT) **********\n");
+
+ /* Disable LTE Coex Function in WiFi side
+ * (this should be on if LTE coex is required)
+ */
+ halbtc8822b1ant_ltecoex_enable(btcoexist, 0x0);
+
+ /* GNT_WL_LTE always = 1
+ * (this should be config if LTE coex is required)
+ */
+ halbtc8822b1ant_ltecoex_set_coex_table(
+ btcoexist, BT_8822B_1ANT_CTT_WL_VS_LTE, 0xffff);
+
+ /* GNT_BT_LTE always = 1
+ * (this should be config if LTE coex is required)
+ */
+ halbtc8822b1ant_ltecoex_set_coex_table(
+ btcoexist, BT_8822B_1ANT_CTT_BT_VS_LTE, 0xffff);
+
+ /* set GNT_BT to SW Low */
+ halbtc8822b1ant_ltecoex_set_gnt_bt(
+ btcoexist, BT_8822B_1ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_1ANT_GNT_CTRL_BY_SW,
+ BT_8822B_1ANT_SIG_STA_SET_TO_LOW);
+
+ /* Set GNT_WL to SW high */
+ halbtc8822b1ant_ltecoex_set_gnt_wl(
+ btcoexist, BT_8822B_1ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_1ANT_GNT_CTRL_BY_SW,
+ BT_8822B_1ANT_SIG_STA_SET_TO_HIGH);
+
+ /* set Path control owner to WL at initial step */
+ halbtc8822b1ant_ltecoex_pathcontrol_owner(
+ btcoexist, BT_8822B_1ANT_PCO_WLSIDE);
+
+ coex_sta->run_time_state = false;
+
+ /* Ext switch buffer mux */
+ btcoexist->btc_write_1byte(btcoexist, 0x974, 0xff);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x1991, 0x3, 0x0);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcbe, 0x8, 0x0);
+
+ if (ant_pos_type == BTC_ANT_PATH_AUTO)
+ ant_pos_type = BTC_ANT_PATH_WIFI;
+
+ break;
+ case BT_8822B_1ANT_PHASE_WLAN_OFF:
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (set_ant_path - 1ANT_PHASE_WLAN_OFF) **********\n");
+
+ /* Disable LTE Coex Function in WiFi side */
+ halbtc8822b1ant_ltecoex_enable(btcoexist, 0x0);
+
+ /* set Path control owner to BT */
+ halbtc8822b1ant_ltecoex_pathcontrol_owner(
+ btcoexist, BT_8822B_1ANT_PCO_BTSIDE);
+
+ /* Set Ext Ant Switch to BT control at wifi off step */
+ halbtc8822b1ant_set_ext_ant_switch(
+ btcoexist, FORCE_EXEC,
+ BT_8822B_1ANT_EXT_ANT_SWITCH_CTRL_BY_BT,
+ BT_8822B_1ANT_EXT_ANT_SWITCH_TO_NOCARE);
+
+ coex_sta->run_time_state = false;
+
+ break;
+ case BT_8822B_1ANT_PHASE_2G_RUNTIME:
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (set_ant_path - 1ANT_PHASE_2G_RUNTIME) **********\n");
+
+ /* set GNT_BT to PTA */
+ halbtc8822b1ant_ltecoex_set_gnt_bt(
+ btcoexist, BT_8822B_1ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_1ANT_GNT_CTRL_BY_PTA,
+ BT_8822B_1ANT_SIG_STA_SET_BY_HW);
+
+ /* Set GNT_WL to PTA */
+ halbtc8822b1ant_ltecoex_set_gnt_wl(
+ btcoexist, BT_8822B_1ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_1ANT_GNT_CTRL_BY_PTA,
+ BT_8822B_1ANT_SIG_STA_SET_BY_HW);
+
+ /* set Path control owner to WL at runtime step */
+ halbtc8822b1ant_ltecoex_pathcontrol_owner(
+ btcoexist, BT_8822B_1ANT_PCO_WLSIDE);
+
+ coex_sta->run_time_state = true;
+
+ if (ant_pos_type == BTC_ANT_PATH_AUTO)
+ ant_pos_type = BTC_ANT_PATH_PTA;
+
+ break;
+ case BT_8822B_1ANT_PHASE_5G_RUNTIME:
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (set_ant_path - 1ANT_PHASE_5G_RUNTIME) **********\n");
+
+ /* set GNT_BT to SW Hi */
+ halbtc8822b1ant_ltecoex_set_gnt_bt(
+ btcoexist, BT_8822B_1ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_1ANT_GNT_CTRL_BY_SW,
+ BT_8822B_1ANT_SIG_STA_SET_TO_HIGH);
+
+ /* Set GNT_WL to SW Hi */
+ halbtc8822b1ant_ltecoex_set_gnt_wl(
+ btcoexist, BT_8822B_1ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_1ANT_GNT_CTRL_BY_SW,
+ BT_8822B_1ANT_SIG_STA_SET_TO_HIGH);
+
+ /* set Path control owner to WL at runtime step */
+ halbtc8822b1ant_ltecoex_pathcontrol_owner(
+ btcoexist, BT_8822B_1ANT_PCO_WLSIDE);
+
+ coex_sta->run_time_state = true;
+
+ if (ant_pos_type == BTC_ANT_PATH_AUTO)
+ ant_pos_type = BTC_ANT_PATH_WIFI5G;
+
+ break;
+ case BT_8822B_1ANT_PHASE_BTMPMODE:
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (set_ant_path - 1ANT_PHASE_BTMPMODE) **********\n");
+
+ /* Disable LTE Coex Function in WiFi side */
+ halbtc8822b1ant_ltecoex_enable(btcoexist, 0x0);
+
+ /* set GNT_BT to SW Hi */
+ halbtc8822b1ant_ltecoex_set_gnt_bt(
+ btcoexist, BT_8822B_1ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_1ANT_GNT_CTRL_BY_SW,
+ BT_8822B_1ANT_SIG_STA_SET_TO_HIGH);
+
+ /* Set GNT_WL to SW Lo */
+ halbtc8822b1ant_ltecoex_set_gnt_wl(
+ btcoexist, BT_8822B_1ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_1ANT_GNT_CTRL_BY_SW,
+ BT_8822B_1ANT_SIG_STA_SET_TO_LOW);
+
+ /* set Path control owner to WL */
+ halbtc8822b1ant_ltecoex_pathcontrol_owner(
+ btcoexist, BT_8822B_1ANT_PCO_WLSIDE);
+
+ coex_sta->run_time_state = false;
+
+ /* Set Ext Ant Switch to BT side at BT MP mode */
+ if (ant_pos_type == BTC_ANT_PATH_AUTO)
+ ant_pos_type = BTC_ANT_PATH_BT;
+
+ break;
+ }
+
+ if (phase != BT_8822B_1ANT_PHASE_WLAN_OFF) {
+ switch (ant_pos_type) {
+ case BTC_ANT_PATH_WIFI:
+ halbtc8822b1ant_set_ext_ant_switch(
+ btcoexist, force_exec,
+ BT_8822B_1ANT_EXT_ANT_SWITCH_CTRL_BY_BBSW,
+ BT_8822B_1ANT_EXT_ANT_SWITCH_TO_WLG);
+ break;
+ case BTC_ANT_PATH_WIFI5G:
+ halbtc8822b1ant_set_ext_ant_switch(
+ btcoexist, force_exec,
+ BT_8822B_1ANT_EXT_ANT_SWITCH_CTRL_BY_BBSW,
+ BT_8822B_1ANT_EXT_ANT_SWITCH_TO_WLA);
+ break;
+ case BTC_ANT_PATH_BT:
+ halbtc8822b1ant_set_ext_ant_switch(
+ btcoexist, force_exec,
+ BT_8822B_1ANT_EXT_ANT_SWITCH_CTRL_BY_BBSW,
+ BT_8822B_1ANT_EXT_ANT_SWITCH_TO_BT);
+ break;
+ default:
+ case BTC_ANT_PATH_PTA:
+ halbtc8822b1ant_set_ext_ant_switch(
+ btcoexist, force_exec,
+ BT_8822B_1ANT_EXT_ANT_SWITCH_CTRL_BY_PTA,
+ BT_8822B_1ANT_EXT_ANT_SWITCH_TO_NOCARE);
+ break;
+ }
+ }
+
+ if (btcoexist->dbg_mode_1ant) {
+ u32tmp1 = halbtc8822b1ant_ltecoex_indirect_read_reg(btcoexist,
+ 0x38);
+ u32tmp2 = halbtc8822b1ant_ltecoex_indirect_read_reg(btcoexist,
+ 0x54);
+ u32tmp3 = btcoexist->btc_read_4byte(btcoexist, 0xcb4);
+
+ u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x73);
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (After Ant Setup) 0xcb4 = 0x%x, 0x73 = 0x%x, 0x38= 0x%x, 0x54= 0x%x**********\n",
+ u32tmp3, u8tmp, u32tmp1, u32tmp2);
+ }
+}
+
+static bool halbtc8822b1ant_is_common_action(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ bool common = false, wifi_connected = false, wifi_busy = false;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
+ &wifi_connected);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+
+ if (!wifi_connected &&
+ coex_dm->bt_status == BT_8822B_1ANT_BT_STATUS_NON_CONNECTED_IDLE) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Wifi non connected-idle + BT non connected-idle!!\n");
+
+ /* halbtc8822b1ant_sw_mechanism(btcoexist, false); */
+
+ common = true;
+ } else if (wifi_connected &&
+ (coex_dm->bt_status ==
+ BT_8822B_1ANT_BT_STATUS_NON_CONNECTED_IDLE)) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Wifi connected + BT non connected-idle!!\n");
+
+ /* halbtc8822b1ant_sw_mechanism(btcoexist, false); */
+
+ common = true;
+ } else if (!wifi_connected && (BT_8822B_1ANT_BT_STATUS_CONNECTED_IDLE ==
+ coex_dm->bt_status)) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Wifi non connected-idle + BT connected-idle!!\n");
+
+ /* halbtc8822b1ant_sw_mechanism(btcoexist, false); */
+
+ common = true;
+ } else if (wifi_connected && (BT_8822B_1ANT_BT_STATUS_CONNECTED_IDLE ==
+ coex_dm->bt_status)) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Wifi connected + BT connected-idle!!\n");
+
+ /* halbtc8822b1ant_sw_mechanism(btcoexist, false); */
+
+ common = true;
+ } else if (!wifi_connected && (BT_8822B_1ANT_BT_STATUS_CONNECTED_IDLE !=
+ coex_dm->bt_status)) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Wifi non connected-idle + BT Busy!!\n");
+
+ /* halbtc8822b1ant_sw_mechanism(btcoexist, false); */
+
+ common = true;
+ } else {
+ if (wifi_busy) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Wifi Connected-Busy + BT Busy!!\n");
+ } else {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Wifi Connected-Idle + BT Busy!!\n");
+ }
+
+ common = false;
+ }
+
+ return common;
+}
+
+static void halbtc8822b1ant_action_wifi_under5g(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], under 5g start\n");
+ /* for test : s3 bt disappear , fail rate 1/600*/
+ /*set sw gnt wl bt high*/
+ halbtc8822b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO, FORCE_EXEC,
+ BT_8822B_1ANT_PHASE_5G_RUNTIME);
+
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcbd, 0x3, 1);
+}
+
+static void halbtc8822b1ant_action_wifi_only(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ bool wifi_under_5g = false, rf4ce_enabled = false;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
+ if (wifi_under_5g) {
+ halbtc8822b1ant_action_wifi_under5g(btcoexist);
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (wlan only -- under 5g ) **********\n");
+ return;
+ }
+
+ if (rf4ce_enabled) {
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x45e, 0x8, 0x1);
+
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 50);
+
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
+ return;
+ }
+ halbtc8822b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0);
+ halbtc8822b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8);
+
+ halbtc8822b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO, FORCE_EXEC,
+ BT_8822B_1ANT_PHASE_2G_RUNTIME);
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (wlan only -- under 2g ) **********\n");
+}
+
+static void
+halbtc8822b1ant_action_wifi_native_lps(struct btc_coexist *btcoexist)
+{
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5);
+
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
+}
+
+/* *********************************************
+ *
+ * Non-Software Coex Mechanism start
+ *
+ * **********************************************/
+
+static void halbtc8822b1ant_action_bt_whck_test(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex],action_bt_whck_test\n");
+
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
+
+ halbtc8822b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO, NORMAL_EXEC,
+ BT_8822B_1ANT_PHASE_2G_RUNTIME);
+
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+}
+
+static void
+halbtc8822b1ant_action_wifi_multi_port(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex],action_wifi_multi_port\n");
+
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
+
+ halbtc8822b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO, NORMAL_EXEC,
+ BT_8822B_1ANT_PHASE_2G_RUNTIME);
+
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+}
+
+static void halbtc8822b1ant_action_hs(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, "[BTCoex], action_hs\n");
+
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5);
+
+ halbtc8822b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO, NORMAL_EXEC,
+ BT_8822B_1ANT_PHASE_2G_RUNTIME);
+
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5);
+}
+
+static void halbtc8822b1ant_action_bt_relink(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], run bt multi link function\n");
+
+ if (coex_sta->is_bt_multi_link)
+ return;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], run bt_re-link function\n");
+
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+}
+
+/*"""bt inquiry"""" + wifi any + bt any*/
+
+static void halbtc8822b1ant_action_bt_inquiry(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+ bool wifi_connected = false, ap_enable = false, wifi_busy = false,
+ bt_busy = false, rf4ce_enabled = false;
+
+ bool wifi_scan = false, link = false, roam = false;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (bt inquiry) **********\n");
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
+ &ap_enable);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
+ &wifi_connected);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &wifi_scan);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** scan = %d, link =%d, roam = %d**********\n",
+ wifi_scan, link, roam);
+
+ if ((link) || (roam) || (coex_sta->wifi_is_high_pri_task)) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (bt inquiry wifi connect or scan ) **********\n");
+
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 1);
+
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 6);
+
+ } else if ((wifi_scan) && (coex_sta->bt_create_connection)) {
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 22);
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 6);
+
+ } else if ((!wifi_connected) && (!wifi_scan)) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (bt inquiry wifi non connect) **********\n");
+
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
+
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+
+ } else if ((bt_link_info->a2dp_exist) && (bt_link_info->pan_exist)) {
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 22);
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
+ } else if (bt_link_info->a2dp_exist) {
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32);
+
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 3);
+ } else if (wifi_scan) {
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20);
+
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
+ } else if (wifi_busy) {
+ /* for BT inquiry/page fail after S4 resume */
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32);
+ /*aaaa->55aa for bt connect while wl busy*/
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC,
+ 15);
+ if (rf4ce_enabled) {
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x45e,
+ 0x8, 0x1);
+
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 50);
+
+ halbtc8822b1ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 0);
+ }
+ } else {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (bt inquiry wifi connect) **********\n");
+
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 22);
+
+ halbtc8822b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO,
+ NORMAL_EXEC,
+ BT_8822B_1ANT_PHASE_2G_RUNTIME);
+
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
+ }
+}
+
+static void
+halbtc8822b1ant_action_bt_sco_hid_only_busy(struct btc_coexist *btcoexist)
+{
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+ bool wifi_connected = false, wifi_busy = false;
+ u32 wifi_bw = 1;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
+ &wifi_connected);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+
+ if (bt_link_info->sco_exist) {
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5);
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5);
+ } else {
+ if (coex_sta->is_hid_low_pri_tx_overhead) {
+ halbtc8822b1ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 6);
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 18);
+ } else if (wifi_bw == 0) { /* if 11bg mode */
+
+ if (coex_sta->is_bt_multi_link) {
+ halbtc8822b1ant_coex_table_with_type(
+ btcoexist, NORMAL_EXEC, 11);
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+ true, 11);
+ } else {
+ halbtc8822b1ant_coex_table_with_type(
+ btcoexist, NORMAL_EXEC, 6);
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+ true, 11);
+ }
+ } else {
+ halbtc8822b1ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 6);
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 11);
+ }
+ }
+}
+
+static void
+halbtc8822b1ant_action_wifi_connected_bt_acl_busy(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+ bool wifi_busy = false, wifi_turbo = false;
+ u32 wifi_bw = 1;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM,
+ &coex_sta->scan_ap_num);
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "############# [BTCoex], scan_ap_num = %d, wl_noisy_level = %d\n",
+ coex_sta->scan_ap_num, coex_sta->wl_noisy_level);
+
+ if ((wifi_busy) && (coex_sta->wl_noisy_level == 0))
+ wifi_turbo = true;
+
+ if ((coex_sta->bt_relink_downcount != 0) &&
+ (!bt_link_info->pan_exist) && (wifi_busy)) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "############# [BTCoex], BT Re-Link + A2DP + WL busy\n");
+
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+
+ } else if ((bt_link_info->a2dp_exist) && (coex_sta->is_bt_a2dp_sink)) {
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 12);
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 6);
+ } else if (bt_link_info->a2dp_only) { /* A2DP */
+
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 7);
+
+ if (wifi_turbo)
+ halbtc8822b1ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 19);
+ else
+ halbtc8822b1ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 4);
+ } else if (((bt_link_info->a2dp_exist) && (bt_link_info->pan_exist)) ||
+ (bt_link_info->hid_exist && bt_link_info->a2dp_exist &&
+ bt_link_info->pan_exist)) {
+ /* A2DP+PAN(OPP,FTP), HID+A2DP+PAN(OPP,FTP) */
+
+ if (wifi_busy)
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 13);
+ else
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 14);
+
+ if (bt_link_info->hid_exist)
+ halbtc8822b1ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 1);
+ else if (wifi_turbo)
+ halbtc8822b1ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 19);
+ else
+ halbtc8822b1ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 4);
+ } else if (bt_link_info->hid_exist &&
+ bt_link_info->a2dp_exist) { /* HID+A2DP */
+
+ if (wifi_bw == 0) { /* if 11bg mode */
+ halbtc8822b1ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 1);
+ halbtc8822b1ant_set_wltoggle_coex_table(
+ btcoexist, NORMAL_EXEC, 1, 0xaa, 0x5a, 0xaa,
+ 0xaa);
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 49);
+ } else {
+ halbtc8822b1ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 1);
+ halbtc8822b1ant_limited_rx(btcoexist, NORMAL_EXEC,
+ false, true, 8);
+ halbtc8822b1ant_set_wltoggle_coex_table(
+ btcoexist, NORMAL_EXEC, 1, 0xaa, 0x5a, 0xaa,
+ 0xaa);
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 49);
+ }
+ /* PAN(OPP,FTP), HID+PAN(OPP,FTP) */
+
+ } else if ((bt_link_info->pan_only) ||
+ (bt_link_info->hid_exist && bt_link_info->pan_exist)) {
+ if (!wifi_busy)
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 4);
+ else
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 3);
+
+ if (bt_link_info->hid_exist)
+ halbtc8822b1ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 1);
+ else if (wifi_turbo)
+ halbtc8822b1ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 19);
+ else
+ halbtc8822b1ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 4);
+ } else {
+ /* BT no-profile busy (0x9) */
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 33);
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
+ }
+}
+
+/*wifi not connected + bt action*/
+
+static void
+halbtc8822b1ant_action_wifi_not_connected(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ bool rf4ce_enabled = false;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (wifi not connect) **********\n");
+
+ /* tdma and coex table */
+ if (rf4ce_enabled) {
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x45e, 0x8, 0x1);
+
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 50);
+
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
+ return;
+ }
+ halbtc8822b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8);
+
+ halbtc8822b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO, NORMAL_EXEC,
+ BT_8822B_1ANT_PHASE_2G_RUNTIME);
+
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+}
+
+/*""""wl not connected scan"""" + bt action*/
+static void
+halbtc8822b1ant_action_wifi_not_connected_scan(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+ bool bt_hs_on = false;
+ u32 wifi_link_status = 0;
+ u32 num_of_wifi_link = 0;
+ bool bt_ctrl_agg_buf_size = false;
+ u8 agg_buf_size = 5;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (wifi non connect scan) **********\n");
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS,
+ &wifi_link_status);
+
+ num_of_wifi_link = wifi_link_status >> 16;
+
+ if (num_of_wifi_link >= 2) {
+ halbtc8822b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
+ halbtc8822b1ant_limited_rx(btcoexist, NORMAL_EXEC, false,
+ bt_ctrl_agg_buf_size, agg_buf_size);
+
+ if (coex_sta->c2h_bt_inquiry_page) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "############# [BTCoex], BT Is Inquirying\n");
+ halbtc8822b1ant_action_bt_inquiry(btcoexist);
+ } else {
+ halbtc8822b1ant_action_wifi_multi_port(btcoexist);
+ }
+ return;
+ }
+
+ if (coex_sta->c2h_bt_inquiry_page) {
+ halbtc8822b1ant_action_bt_inquiry(btcoexist);
+ return;
+ } else if (bt_hs_on) {
+ halbtc8822b1ant_action_hs(btcoexist);
+ return;
+ }
+
+ /* tdma and coex table */
+ if (coex_dm->bt_status == BT_8822B_1ANT_BT_STATUS_ACL_BUSY) {
+ if (bt_link_info->a2dp_exist) {
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 32);
+ halbtc8822b1ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 1);
+ } else if (bt_link_info->a2dp_exist &&
+ bt_link_info->pan_exist) {
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 22);
+ halbtc8822b1ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 1);
+ } else {
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 20);
+ halbtc8822b1ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 1);
+ }
+ } else if ((coex_dm->bt_status == BT_8822B_1ANT_BT_STATUS_SCO_BUSY) ||
+ (BT_8822B_1ANT_BT_STATUS_ACL_SCO_BUSY ==
+ coex_dm->bt_status)) {
+ halbtc8822b1ant_action_bt_sco_hid_only_busy(btcoexist);
+ } else {
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
+
+ halbtc8822b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO,
+ NORMAL_EXEC,
+ BT_8822B_1ANT_PHASE_2G_RUNTIME);
+
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5);
+ }
+}
+
+/*""""wl not connected asso"""" + bt action*/
+
+static void halbtc8822b1ant_action_wifi_not_connected_asso_auth(
+ struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+ bool bt_hs_on = false;
+ u32 wifi_link_status = 0;
+ u32 num_of_wifi_link = 0;
+ bool bt_ctrl_agg_buf_size = false;
+ u8 agg_buf_size = 5;
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (wifi non connect asso_auth) **********\n");
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS,
+ &wifi_link_status);
+
+ num_of_wifi_link = wifi_link_status >> 16;
+
+ if (num_of_wifi_link >= 2) {
+ halbtc8822b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
+ halbtc8822b1ant_limited_rx(btcoexist, NORMAL_EXEC, false,
+ bt_ctrl_agg_buf_size, agg_buf_size);
+
+ if (coex_sta->c2h_bt_inquiry_page) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "############# [BTCoex], BT Is Inquirying\n");
+ halbtc8822b1ant_action_bt_inquiry(btcoexist);
+ } else {
+ halbtc8822b1ant_action_wifi_multi_port(btcoexist);
+ }
+ return;
+ }
+
+ if (coex_sta->c2h_bt_inquiry_page) {
+ halbtc8822b1ant_action_bt_inquiry(btcoexist);
+ return;
+ } else if (bt_hs_on) {
+ halbtc8822b1ant_action_hs(btcoexist);
+ return;
+ }
+
+ /* tdma and coex table */
+ if ((bt_link_info->sco_exist) || (bt_link_info->hid_exist) ||
+ (bt_link_info->a2dp_exist)) {
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32);
+ halbtc8822b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 4);
+ } else if (bt_link_info->pan_exist) {
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20);
+ halbtc8822b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 4);
+ } else {
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
+
+ halbtc8822b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO,
+ NORMAL_EXEC,
+ BT_8822B_1ANT_PHASE_2G_RUNTIME);
+
+ halbtc8822b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 2);
+ }
+}
+
+/*""""wl connected scan"""" + bt action*/
+
+static void
+halbtc8822b1ant_action_wifi_connected_scan(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+ bool bt_hs_on = false;
+ u32 wifi_link_status = 0;
+ u32 num_of_wifi_link = 0;
+ bool bt_ctrl_agg_buf_size = false;
+ u8 agg_buf_size = 5;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (wifi connect scan) **********\n");
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS,
+ &wifi_link_status);
+
+ num_of_wifi_link = wifi_link_status >> 16;
+
+ if (num_of_wifi_link >= 2) {
+ halbtc8822b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
+ halbtc8822b1ant_limited_rx(btcoexist, NORMAL_EXEC, false,
+ bt_ctrl_agg_buf_size, agg_buf_size);
+
+ if (coex_sta->c2h_bt_inquiry_page) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "############# [BTCoex], BT Is Inquirying\n");
+ halbtc8822b1ant_action_bt_inquiry(btcoexist);
+ } else {
+ halbtc8822b1ant_action_wifi_multi_port(btcoexist);
+ }
+ return;
+ }
+
+ if (coex_sta->c2h_bt_inquiry_page) {
+ halbtc8822b1ant_action_bt_inquiry(btcoexist);
+ return;
+ } else if (bt_hs_on) {
+ halbtc8822b1ant_action_hs(btcoexist);
+ return;
+ }
+
+ /* tdma and coex table */
+ if (coex_dm->bt_status == BT_8822B_1ANT_BT_STATUS_ACL_BUSY) {
+ if (bt_link_info->a2dp_exist) {
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 32);
+ halbtc8822b1ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 1);
+ } else if (bt_link_info->a2dp_exist &&
+ bt_link_info->pan_exist) {
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 22);
+ halbtc8822b1ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 1);
+ } else {
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 20);
+ halbtc8822b1ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 1);
+ }
+ } else if ((coex_dm->bt_status == BT_8822B_1ANT_BT_STATUS_SCO_BUSY) ||
+ (BT_8822B_1ANT_BT_STATUS_ACL_SCO_BUSY ==
+ coex_dm->bt_status)) {
+ halbtc8822b1ant_action_bt_sco_hid_only_busy(btcoexist);
+ } else {
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
+
+ halbtc8822b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO,
+ NORMAL_EXEC,
+ BT_8822B_1ANT_PHASE_2G_RUNTIME);
+
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 6);
+ }
+}
+
+/*""""wl connected specific packet"""" + bt action*/
+
+static void halbtc8822b1ant_action_wifi_connected_specific_packet(
+ struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+ bool bt_hs_on = false;
+ u32 wifi_link_status = 0;
+ u32 num_of_wifi_link = 0;
+ bool bt_ctrl_agg_buf_size = false;
+ u8 agg_buf_size = 5;
+ bool wifi_busy = false;
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (wifi connect specific packet) **********\n");
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS,
+ &wifi_link_status);
+
+ num_of_wifi_link = wifi_link_status >> 16;
+
+ if (num_of_wifi_link >= 2) {
+ halbtc8822b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
+ halbtc8822b1ant_limited_rx(btcoexist, NORMAL_EXEC, false,
+ bt_ctrl_agg_buf_size, agg_buf_size);
+
+ if (coex_sta->c2h_bt_inquiry_page) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "############# [BTCoex], BT Is Inquirying\n");
+ halbtc8822b1ant_action_bt_inquiry(btcoexist);
+ } else {
+ halbtc8822b1ant_action_wifi_multi_port(btcoexist);
+ }
+ return;
+ }
+
+ if (coex_sta->c2h_bt_inquiry_page) {
+ halbtc8822b1ant_action_bt_inquiry(btcoexist);
+ return;
+ } else if (bt_hs_on) {
+ halbtc8822b1ant_action_hs(btcoexist);
+ return;
+ }
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+
+ /* no specific packet process for both WiFi and BT very busy */
+ if ((wifi_busy) &&
+ ((bt_link_info->pan_exist) || (coex_sta->num_of_profile >= 2)))
+ return;
+
+ /* tdma and coex table */
+ if ((bt_link_info->sco_exist) || (bt_link_info->hid_exist)) {
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32);
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5);
+ } else if (bt_link_info->a2dp_exist) {
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32);
+ /*for a2dp glitch,change from 1 to 15*/
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC,
+ 15);
+ } else if (bt_link_info->pan_exist) {
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20);
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
+ } else {
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
+
+ halbtc8822b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO,
+ NORMAL_EXEC,
+ BT_8822B_1ANT_PHASE_2G_RUNTIME);
+
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5);
+ }
+}
+
+/* wifi connected input point:
+ * to set different ps and tdma case (+bt different case)
+ */
+
+static void halbtc8822b1ant_action_wifi_connected(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ bool wifi_busy = false, rf4ce_enabled = false;
+ bool scan = false, link = false, roam = false;
+ bool under_4way = false, ap_enable = false, wifi_under_5g = false;
+ u8 wifi_rssi_state;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], CoexForWifiConnect()===>\n");
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
+
+ if (wifi_under_5g) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], CoexForWifiConnect(), return for wifi is under 5g<===\n");
+
+ halbtc8822b1ant_action_wifi_under5g(btcoexist);
+
+ return;
+ }
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], CoexForWifiConnect(), return for wifi is under 2g<===\n");
+
+ halbtc8822b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO, NORMAL_EXEC,
+ BT_8822B_1ANT_PHASE_2G_RUNTIME);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS,
+ &under_4way);
+
+ if (under_4way) {
+ halbtc8822b1ant_action_wifi_connected_specific_packet(
+ btcoexist);
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], CoexForWifiConnect(), return for wifi is under 4way<===\n");
+ return;
+ }
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
+ if (scan || link || roam) {
+ if (scan)
+ halbtc8822b1ant_action_wifi_connected_scan(btcoexist);
+ else
+ halbtc8822b1ant_action_wifi_connected_specific_packet(
+ btcoexist);
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], CoexForWifiConnect(), return for wifi is under scan<===\n");
+ return;
+ }
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
+ &ap_enable);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+
+ /* tdma and coex table */
+ if (!wifi_busy) {
+ if (coex_dm->bt_status == BT_8822B_1ANT_BT_STATUS_ACL_BUSY) {
+ halbtc8822b1ant_action_wifi_connected_bt_acl_busy(
+ btcoexist);
+ } else if ((BT_8822B_1ANT_BT_STATUS_SCO_BUSY ==
+ coex_dm->bt_status) ||
+ (BT_8822B_1ANT_BT_STATUS_ACL_SCO_BUSY ==
+ coex_dm->bt_status)) {
+ halbtc8822b1ant_action_bt_sco_hid_only_busy(btcoexist);
+ } else {
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false,
+ 8);
+
+ halbtc8822b1ant_set_ant_path(
+ btcoexist, BTC_ANT_PATH_AUTO, NORMAL_EXEC,
+ BT_8822B_1ANT_PHASE_2G_RUNTIME);
+
+ if ((coex_sta->high_priority_tx) +
+ (coex_sta->high_priority_rx) <=
+ 60)
+ /*sy modify case16 -> case17*/
+ halbtc8822b1ant_coex_table_with_type(
+ btcoexist, NORMAL_EXEC, 1);
+ else
+ halbtc8822b1ant_coex_table_with_type(
+ btcoexist, NORMAL_EXEC, 1);
+ }
+ } else {
+ if (coex_dm->bt_status == BT_8822B_1ANT_BT_STATUS_ACL_BUSY) {
+ halbtc8822b1ant_action_wifi_connected_bt_acl_busy(
+ btcoexist);
+ } else if ((BT_8822B_1ANT_BT_STATUS_SCO_BUSY ==
+ coex_dm->bt_status) ||
+ (BT_8822B_1ANT_BT_STATUS_ACL_SCO_BUSY ==
+ coex_dm->bt_status)) {
+ halbtc8822b1ant_action_bt_sco_hid_only_busy(btcoexist);
+ } else {
+ if (rf4ce_enabled) {
+ btcoexist->btc_write_1byte_bitmask(
+ btcoexist, 0x45e, 0x8, 0x1);
+
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+ true, 50);
+
+ halbtc8822b1ant_coex_table_with_type(
+ btcoexist, NORMAL_EXEC, 1);
+ return;
+ }
+
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false,
+ 8);
+
+ halbtc8822b1ant_set_ant_path(
+ btcoexist, BTC_ANT_PATH_AUTO, NORMAL_EXEC,
+ BT_8822B_1ANT_PHASE_2G_RUNTIME);
+
+ wifi_rssi_state = halbtc8822b1ant_wifi_rssi_state(
+ btcoexist, 1, 2, 25, 0);
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** before **********\n");
+ if (BT_8822B_1ANT_BT_STATUS_NON_CONNECTED_IDLE ==
+ coex_dm->bt_status) {
+ if (rf4ce_enabled) {
+ btcoexist->btc_write_1byte_bitmask(
+ btcoexist, 0x45e, 0x8, 0x1);
+
+ halbtc8822b1ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 50);
+
+ halbtc8822b1ant_coex_table_with_type(
+ btcoexist, NORMAL_EXEC, 1);
+ return;
+ }
+
+ halbtc8822b1ant_coex_table_with_type(
+ btcoexist, NORMAL_EXEC, 1);
+ } else {
+ halbtc8822b1ant_coex_table_with_type(
+ btcoexist, NORMAL_EXEC, 1);
+ }
+ }
+ }
+}
+
+static void
+halbtc8822b1ant_run_sw_coexist_mechanism(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ u8 algorithm = 0;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (run sw coexmech) **********\n");
+ algorithm = halbtc8822b1ant_action_algorithm(btcoexist);
+ coex_dm->cur_algorithm = algorithm;
+
+ if (halbtc8822b1ant_is_common_action(btcoexist)) {
+ } else {
+ switch (coex_dm->cur_algorithm) {
+ case BT_8822B_1ANT_COEX_ALGO_SCO:
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action algorithm = SCO.\n");
+ break;
+ case BT_8822B_1ANT_COEX_ALGO_HID:
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action algorithm = HID.\n");
+ break;
+ case BT_8822B_1ANT_COEX_ALGO_A2DP:
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action algorithm = A2DP.\n");
+ break;
+ case BT_8822B_1ANT_COEX_ALGO_A2DP_PANHS:
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action algorithm = A2DP+PAN(HS).\n");
+ break;
+ case BT_8822B_1ANT_COEX_ALGO_PANEDR:
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action algorithm = PAN(EDR).\n");
+ break;
+ case BT_8822B_1ANT_COEX_ALGO_PANHS:
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action algorithm = HS mode.\n");
+ break;
+ case BT_8822B_1ANT_COEX_ALGO_PANEDR_A2DP:
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action algorithm = PAN+A2DP.\n");
+ break;
+ case BT_8822B_1ANT_COEX_ALGO_PANEDR_HID:
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action algorithm = PAN(EDR)+HID.\n");
+ break;
+ case BT_8822B_1ANT_COEX_ALGO_HID_A2DP_PANEDR:
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action algorithm = HID+A2DP+PAN.\n");
+ break;
+ case BT_8822B_1ANT_COEX_ALGO_HID_A2DP:
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action algorithm = HID+A2DP.\n");
+ break;
+ default:
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action algorithm = coexist All Off!!\n");
+ break;
+ }
+ coex_dm->pre_algorithm = coex_dm->cur_algorithm;
+ }
+}
+
+static void halbtc8822b1ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+ bool wifi_connected = false, bt_hs_on = false;
+ bool increase_scan_dev_num = false;
+ bool bt_ctrl_agg_buf_size = false;
+ bool miracast_plus_bt = false;
+ u8 agg_buf_size = 5;
+ u32 wifi_link_status = 0;
+ u32 num_of_wifi_link = 0, wifi_bw;
+ u8 iot_peer = BTC_IOT_PEER_UNKNOWN;
+ bool wifi_under_5g = false;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], RunCoexistMechanism()===>\n");
+
+ if (btcoexist->manual_control) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n");
+ return;
+ }
+
+ if (btcoexist->stop_coex_dm) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], RunCoexistMechanism(), return for Stop Coex DM <===\n");
+ return;
+ }
+
+ if (coex_sta->under_ips) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], wifi is under IPS !!!\n");
+ return;
+ }
+
+ if ((coex_sta->under_lps) &&
+ (coex_dm->bt_status != BT_8822B_1ANT_BT_STATUS_ACL_BUSY)) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], RunCoexistMechanism(), wifi is under LPS !!!\n");
+ halbtc8822b1ant_action_wifi_native_lps(btcoexist);
+ return;
+ }
+
+ if (!coex_sta->run_time_state) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], return for run_time_state = false !!!\n");
+ return;
+ }
+
+ if (coex_sta->freeze_coexrun_by_btinfo) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BtInfoNotify(), return for freeze_coexrun_by_btinfo\n");
+ return;
+ }
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
+ if (wifi_under_5g) {
+ halbtc8822b1ant_action_wifi_under5g(btcoexist);
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], WiFi is under 5G!!!\n");
+ return;
+ }
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], WiFi is under 2G!!!\n");
+
+ halbtc8822b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO, NORMAL_EXEC,
+ BT_8822B_1ANT_PHASE_2G_RUNTIME);
+
+ if (coex_sta->bt_whck_test) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT is under WHCK TEST!!!\n");
+ halbtc8822b1ant_action_bt_whck_test(btcoexist);
+ return;
+ }
+
+ if (coex_sta->bt_disabled) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT is disabled !!!\n");
+ halbtc8822b1ant_action_wifi_only(btcoexist);
+ return;
+ }
+
+ if (coex_sta->is_setup_link) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT is re-link !!!\n");
+ halbtc8822b1ant_action_bt_relink(btcoexist);
+ return;
+ }
+
+ if ((coex_dm->bt_status == BT_8822B_1ANT_BT_STATUS_ACL_BUSY) ||
+ (coex_dm->bt_status == BT_8822B_1ANT_BT_STATUS_SCO_BUSY) ||
+ (coex_dm->bt_status == BT_8822B_1ANT_BT_STATUS_ACL_SCO_BUSY))
+ increase_scan_dev_num = true;
+
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_INC_SCAN_DEV_NUM,
+ &increase_scan_dev_num);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
+ &wifi_connected);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS,
+ &wifi_link_status);
+ num_of_wifi_link = wifi_link_status >> 16;
+
+ if ((num_of_wifi_link >= 2) ||
+ (wifi_link_status & WIFI_P2P_GO_CONNECTED)) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "############# [BTCoex], Multi-Port num_of_wifi_link = %d, wifi_link_status = 0x%x\n",
+ num_of_wifi_link, wifi_link_status);
+
+ if (bt_link_info->bt_link_exist) {
+ halbtc8822b1ant_limited_tx(btcoexist, NORMAL_EXEC, 1, 1,
+ 0, 1);
+ miracast_plus_bt = true;
+ } else {
+ halbtc8822b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0,
+ 0, 0);
+ miracast_plus_bt = false;
+ }
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_MIRACAST_PLUS_BT,
+ &miracast_plus_bt);
+ halbtc8822b1ant_limited_rx(btcoexist, NORMAL_EXEC, false,
+ bt_ctrl_agg_buf_size, agg_buf_size);
+
+ if ((bt_link_info->a2dp_exist) &&
+ (coex_sta->c2h_bt_inquiry_page)) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "############# [BTCoex], BT Is Inquirying\n");
+ halbtc8822b1ant_action_bt_inquiry(btcoexist);
+ } else {
+ halbtc8822b1ant_action_wifi_multi_port(btcoexist);
+ }
+
+ return;
+ }
+
+ miracast_plus_bt = false;
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_MIRACAST_PLUS_BT,
+ &miracast_plus_bt);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ if ((bt_link_info->bt_link_exist) && (wifi_connected)) {
+ halbtc8822b1ant_limited_tx(btcoexist, NORMAL_EXEC, 1, 1, 0, 1);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_IOT_PEER, &iot_peer);
+
+ if (iot_peer != BTC_IOT_PEER_CISCO) {
+ if (bt_link_info->sco_exist)
+ halbtc8822b1ant_limited_rx(btcoexist,
+ NORMAL_EXEC, true,
+ false, 0x5);
+ else
+ halbtc8822b1ant_limited_rx(btcoexist,
+ NORMAL_EXEC, false,
+ false, 0x5);
+ } else {
+ if (bt_link_info->sco_exist) {
+ halbtc8822b1ant_limited_rx(btcoexist,
+ NORMAL_EXEC, true,
+ false, 0x5);
+ } else {
+ if (wifi_bw == BTC_WIFI_BW_HT40)
+ halbtc8822b1ant_limited_rx(
+ btcoexist, NORMAL_EXEC, false,
+ true, 0x10);
+ else
+ halbtc8822b1ant_limited_rx(
+ btcoexist, NORMAL_EXEC, false,
+ true, 0x8);
+ }
+ }
+
+ halbtc8822b1ant_sw_mechanism(btcoexist, true);
+ halbtc8822b1ant_run_sw_coexist_mechanism(
+ btcoexist); /* just print debug message */
+ } else {
+ halbtc8822b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
+
+ halbtc8822b1ant_limited_rx(btcoexist, NORMAL_EXEC, false, false,
+ 0x5);
+
+ halbtc8822b1ant_sw_mechanism(btcoexist, false);
+ halbtc8822b1ant_run_sw_coexist_mechanism(
+ btcoexist); /* just print debug message */
+ }
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+ if (coex_sta->c2h_bt_inquiry_page) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "############# [BTCoex], BT Is Inquirying\n");
+ halbtc8822b1ant_action_bt_inquiry(btcoexist);
+ return;
+ } else if (bt_hs_on) {
+ halbtc8822b1ant_action_hs(btcoexist);
+ return;
+ }
+
+ if (!wifi_connected) {
+ bool scan = false, link = false, roam = false;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], wifi is non connected-idle !!!\n");
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
+
+ if (scan)
+ halbtc8822b1ant_action_wifi_not_connected_scan(
+ btcoexist);
+ else if (link || roam)
+ halbtc8822b1ant_action_wifi_not_connected_asso_auth(
+ btcoexist);
+ else
+ halbtc8822b1ant_action_wifi_not_connected(btcoexist);
+ } else { /* wifi LPS/Busy */
+ halbtc8822b1ant_action_wifi_connected(btcoexist);
+ }
+}
+
+static void halbtc8822b1ant_init_coex_dm(struct btc_coexist *btcoexist)
+{
+ /* force to reset coex mechanism */
+
+ halbtc8822b1ant_low_penalty_ra(btcoexist, NORMAL_EXEC, false);
+
+ /* sw all off */
+ halbtc8822b1ant_sw_mechanism(btcoexist, false);
+
+ coex_sta->pop_event_cnt = 0;
+}
+
+static void halbtc8822b1ant_init_hw_config(struct btc_coexist *btcoexist,
+ bool back_up, bool wifi_only)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ u8 u8tmp = 0, i = 0;
+ u32 u32tmp1 = 0, u32tmp2 = 0, u32tmp3 = 0;
+
+ u32tmp3 = btcoexist->btc_read_4byte(btcoexist, 0xcb4);
+ u32tmp1 = halbtc8822b1ant_ltecoex_indirect_read_reg(btcoexist, 0x38);
+ u32tmp2 = halbtc8822b1ant_ltecoex_indirect_read_reg(btcoexist, 0x54);
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (Before Init HW config) 0xcb4 = 0x%x, 0x38= 0x%x, 0x54= 0x%x**********\n",
+ u32tmp3, u32tmp1, u32tmp2);
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], 1Ant Init HW Config!!\n");
+
+ coex_sta->bt_coex_supported_feature = 0;
+ coex_sta->bt_coex_supported_version = 0;
+ coex_sta->bt_ble_scan_type = 0;
+ coex_sta->bt_ble_scan_para[0] = 0;
+ coex_sta->bt_ble_scan_para[1] = 0;
+ coex_sta->bt_ble_scan_para[2] = 0;
+ coex_sta->bt_reg_vendor_ac = 0xffff;
+ coex_sta->bt_reg_vendor_ae = 0xffff;
+ coex_sta->isolation_btween_wb = BT_8822B_1ANT_DEFAULT_ISOLATION;
+ coex_sta->gnt_error_cnt = 0;
+ coex_sta->bt_relink_downcount = 0;
+ coex_sta->is_set_ps_state_fail = false;
+ coex_sta->cnt_set_ps_state_fail = 0;
+
+ for (i = 0; i <= 9; i++)
+ coex_sta->bt_afh_map[i] = 0;
+
+ /* Setup RF front end type */
+ halbtc8822b1ant_set_rfe_type(btcoexist);
+
+ /* 0xf0[15:12] --> Chip Cut information */
+ coex_sta->cut_version =
+ (btcoexist->btc_read_1byte(btcoexist, 0xf1) & 0xf0) >> 4;
+
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x550, 0x8,
+ 0x1); /* enable TBTT nterrupt */
+
+ /* BT report packet sample rate */
+ /* 0x790[5:0]=0x5 */
+ u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x790);
+ u8tmp &= 0xc0;
+ u8tmp |= 0x5;
+ btcoexist->btc_write_1byte(btcoexist, 0x790, u8tmp);
+
+ /* Enable BT counter statistics */
+ btcoexist->btc_write_1byte(btcoexist, 0x778, 0x1);
+
+ /* Enable PTA (3-wire function form BT side) */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x41, 0x02, 0x1);
+
+ /* Enable PTA (tx/rx signal form WiFi side) */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4c6, 0x10, 0x1);
+ /*GNT_BT=1 while select both */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x763, 0x10, 0x1);
+
+ /* enable GNT_WL */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4e, 0x40, 0x0);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 0x1, 0x0);
+
+ if (btcoexist->btc_read_1byte(btcoexist, 0x80) == 0xc6)
+ halbtc8822b1ant_post_state_to_bt(
+ btcoexist, BT_8822B_1ANT_SCOREBOARD_ONOFF, true);
+
+ /* Antenna config */
+ if (coex_sta->is_rf_state_off) {
+ halbtc8822b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO,
+ FORCE_EXEC,
+ BT_8822B_1ANT_PHASE_WLAN_OFF);
+
+ btcoexist->stop_coex_dm = true;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** %s (RF Off)**********\n",
+ __func__);
+ } else if (wifi_only) {
+ coex_sta->concurrent_rx_mode_on = false;
+ halbtc8822b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_WIFI,
+ FORCE_EXEC,
+ BT_8822B_1ANT_PHASE_WLANONLY_INIT);
+ } else {
+ coex_sta->concurrent_rx_mode_on = true;
+
+ halbtc8822b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO,
+ FORCE_EXEC,
+ BT_8822B_1ANT_PHASE_COEX_INIT);
+ }
+
+ /* PTA parameter */
+ halbtc8822b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0);
+
+ halbtc8822b1ant_enable_gnt_to_gpio(btcoexist, true);
+}
+
+void ex_btc8822b1ant_power_on_setting(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ struct btc_board_info *board_info = &btcoexist->board_info;
+ u8 u8tmp = 0x0;
+ u16 u16tmp = 0x0;
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "xxxxxxxxxxxxxxxx Execute 8822b 1-Ant PowerOn Setting!! xxxxxxxxxxxxxxxx\n");
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "Ant Det Finish = %s, Ant Det Number = %d\n",
+ board_info->btdm_ant_det_finish ? "Yes" : "No",
+ board_info->btdm_ant_num_by_ant_det);
+
+ btcoexist->dbg_mode_1ant = false;
+ btcoexist->stop_coex_dm = true;
+
+ /* enable BB, REG_SYS_FUNC_EN such that we can write 0x948 correctly. */
+ u16tmp = btcoexist->btc_read_2byte(btcoexist, 0x2);
+ btcoexist->btc_write_2byte(btcoexist, 0x2, u16tmp | BIT(0) | BIT(1));
+
+ /* set Path control owner to WiFi */
+ halbtc8822b1ant_ltecoex_pathcontrol_owner(btcoexist,
+ BT_8822B_1ANT_PCO_WLSIDE);
+
+ /* set GNT_BT to high */
+ halbtc8822b1ant_ltecoex_set_gnt_bt(btcoexist,
+ BT_8822B_1ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_1ANT_GNT_CTRL_BY_SW,
+ BT_8822B_1ANT_SIG_STA_SET_TO_HIGH);
+ /* Set GNT_WL to low */
+ halbtc8822b1ant_ltecoex_set_gnt_wl(
+ btcoexist, BT_8822B_1ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_1ANT_GNT_CTRL_BY_SW, BT_8822B_1ANT_SIG_STA_SET_TO_LOW);
+
+ /* set WLAN_ACT = 0 */
+ /* btcoexist->btc_write_1byte(btcoexist, 0x76e, 0x4); */
+
+ /* SD1 Chunchu red x issue */
+ btcoexist->btc_write_1byte(btcoexist, 0xff1a, 0x0);
+
+ halbtc8822b1ant_enable_gnt_to_gpio(btcoexist, true);
+
+ /* */
+ /* S0 or S1 setting and Local register setting
+ * (By the setting fw can get ant number, S0/S1, ... info)
+ */
+ /* Local setting bit define */
+ /* BIT0: "0" for no antenna inverse; "1" for antenna inverse */
+ /* BIT1: "0" for internal switch; "1" for external switch */
+ /* BIT2: "0" for one antenna; "1" for two antenna */
+ /* NOTE: here default all internal switch and 1-antenna ==>
+ * BIT1=0 and BIT2=0
+ */
+
+ u8tmp = 0;
+ board_info->btdm_ant_pos = BTC_ANTENNA_AT_MAIN_PORT;
+
+ if (btcoexist->chip_interface == BTC_INTF_USB)
+ btcoexist->btc_write_local_reg_1byte(btcoexist, 0xfe08, u8tmp);
+ else if (btcoexist->chip_interface == BTC_INTF_SDIO)
+ btcoexist->btc_write_local_reg_1byte(btcoexist, 0x60, u8tmp);
+}
+
+void ex_btc8822b1ant_pre_load_firmware(struct btc_coexist *btcoexist) {}
+
+void ex_btc8822b1ant_init_hw_config(struct btc_coexist *btcoexist,
+ bool wifi_only)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (ini hw config) **********\n");
+
+ halbtc8822b1ant_init_hw_config(btcoexist, true, wifi_only);
+ btcoexist->stop_coex_dm = false;
+ btcoexist->auto_report_1ant = true;
+}
+
+void ex_btc8822b1ant_init_coex_dm(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Coex Mechanism Init!!\n");
+
+ btcoexist->stop_coex_dm = false;
+
+ halbtc8822b1ant_init_coex_dm(btcoexist);
+
+ halbtc8822b1ant_query_bt_info(btcoexist);
+}
+
+void ex_btc8822b1ant_display_coex_info(struct btc_coexist *btcoexist,
+ struct seq_file *m)
+{
+ struct btc_board_info *board_info = &btcoexist->board_info;
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+
+ u8 u8tmp[4], i, ps_tdma_case = 0;
+ u16 u16tmp[4];
+ u32 u32tmp[4];
+ u32 fa_ofdm, fa_cck, cca_ofdm, cca_cck;
+ u32 fw_ver = 0, bt_patch_ver = 0, bt_coex_ver = 0;
+ static u8 pop_report_in_10s;
+ u32 phyver = 0;
+ bool lte_coex_on = false;
+ static u8 cnt;
+
+ seq_puts(m, "\r\n ============[BT Coexist info]============");
+
+ if (btcoexist->manual_control) {
+ seq_puts(m,
+ "\r\n ============[Under Manual Control]============");
+ seq_puts(m, "\r\n ==========================================");
+ }
+ if (btcoexist->stop_coex_dm) {
+ seq_puts(m, "\r\n ============[Coex is STOPPED]============");
+ seq_puts(m, "\r\n ==========================================");
+ }
+
+ if (!coex_sta->bt_disabled) {
+ if (coex_sta->bt_coex_supported_feature == 0)
+ btcoexist->btc_get(
+ btcoexist, BTC_GET_U4_SUPPORTED_FEATURE,
+ &coex_sta->bt_coex_supported_feature);
+
+ if ((coex_sta->bt_coex_supported_version == 0) ||
+ (coex_sta->bt_coex_supported_version == 0xffff))
+ btcoexist->btc_get(
+ btcoexist, BTC_GET_U4_SUPPORTED_VERSION,
+ &coex_sta->bt_coex_supported_version);
+
+ if (coex_sta->bt_reg_vendor_ac == 0xffff)
+ coex_sta->bt_reg_vendor_ac = (u16)(
+ btcoexist->btc_get_bt_reg(btcoexist, 3, 0xac) &
+ 0xffff);
+
+ if (coex_sta->bt_reg_vendor_ae == 0xffff)
+ coex_sta->bt_reg_vendor_ae = (u16)(
+ btcoexist->btc_get_bt_reg(btcoexist, 3, 0xae) &
+ 0xffff);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER,
+ &bt_patch_ver);
+ btcoexist->bt_info.bt_get_fw_ver = bt_patch_ver;
+
+ if (coex_sta->num_of_profile > 0) {
+ cnt++;
+
+ if (cnt >= 3) {
+ btcoexist->btc_get_bt_afh_map_from_bt(
+ btcoexist, 0, &coex_sta->bt_afh_map[0]);
+ cnt = 0;
+ }
+ }
+ }
+
+ if (psd_scan->ant_det_try_count == 0) {
+ seq_printf(
+ m, "\r\n %-35s = %d/ %d/ %s / %d",
+ "Ant PG Num/ Mech/ Pos/ RFE", board_info->pg_ant_num,
+ board_info->btdm_ant_num,
+ (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT ?
+ "Main" :
+ "Aux"),
+ rfe_type->rfe_module_type);
+ } else {
+ seq_printf(
+ m, "\r\n %-35s = %d/ %d/ %s/ %d (%d/%d/%d)",
+ "Ant PG Num/ Mech(Ant_Det)/ Pos/ RFE",
+ board_info->pg_ant_num,
+ board_info->btdm_ant_num_by_ant_det,
+ (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT ?
+ "Main" :
+ "Aux"),
+ rfe_type->rfe_module_type, psd_scan->ant_det_try_count,
+ psd_scan->ant_det_fail_count, psd_scan->ant_det_result);
+
+ if (board_info->btdm_ant_det_finish) {
+ if (psd_scan->ant_det_result != 12)
+ seq_printf(m, "\r\n %-35s = %s",
+ "Ant Det PSD Value",
+ psd_scan->ant_det_peak_val);
+ else
+ seq_printf(m, "\r\n %-35s = %d",
+ "Ant Det PSD Value",
+ psd_scan->ant_det_psd_scan_peak_val /
+ 100);
+ }
+ }
+
+ bt_patch_ver = btcoexist->bt_info.bt_get_fw_ver;
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
+ phyver = btcoexist->btc_get_bt_phydm_version(btcoexist);
+
+ bt_coex_ver = ((coex_sta->bt_coex_supported_version & 0xff00) >> 8);
+
+ seq_printf(
+ m, "\r\n %-35s = %d_%02x/ 0x%02x/ 0x%02x (%s)",
+ "CoexVer WL/ BT_Desired/ BT_Report",
+ glcoex_ver_date_8822b_1ant, glcoex_ver_8822b_1ant,
+ glcoex_ver_btdesired_8822b_1ant, bt_coex_ver,
+ (bt_coex_ver == 0xff ?
+ "Unknown" :
+ (coex_sta->bt_disabled ? "BT-disable" :
+ (bt_coex_ver >= glcoex_ver_btdesired_8822b_1ant ?
+ "Match" :
+ "Mis-Match"))));
+
+ seq_printf(m, "\r\n %-35s = 0x%x/ 0x%x/ v%d/ %c", "W_FW/ B_FW/ Phy/ Kt",
+ fw_ver, bt_patch_ver, phyver, coex_sta->cut_version + 65);
+
+ seq_printf(m, "\r\n %-35s = %02x %02x %02x ", "AFH Map to BT",
+ coex_dm->wifi_chnl_info[0], coex_dm->wifi_chnl_info[1],
+ coex_dm->wifi_chnl_info[2]);
+
+ /* wifi status */
+ seq_printf(m, "\r\n %-35s", "============[Wifi Status]============");
+ btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_WIFI_STATUS, m);
+
+ seq_printf(m, "\r\n %-35s", "============[BT Status]============");
+
+ pop_report_in_10s++;
+ seq_printf(
+ m, "\r\n %-35s = [%s/ %d dBm/ %d/ %d] ",
+ "BT [status/ rssi/ retryCnt/ popCnt]",
+ ((coex_sta->bt_disabled) ?
+ ("disabled") :
+ ((coex_sta->c2h_bt_inquiry_page) ? ("inquiry/page") :
+ ((BT_8822B_1ANT_BT_STATUS_NON_CONNECTED_IDLE ==
+ coex_dm->bt_status) ?
+ "non-connected idle" :
+ ((coex_dm->bt_status ==
+ BT_8822B_1ANT_BT_STATUS_CONNECTED_IDLE) ?
+ "connected-idle" :
+ "busy")))),
+ coex_sta->bt_rssi - 100, coex_sta->bt_retry_cnt,
+ coex_sta->pop_event_cnt);
+
+ if (pop_report_in_10s >= 5) {
+ coex_sta->pop_event_cnt = 0;
+ pop_report_in_10s = 0;
+ }
+
+ if (coex_sta->num_of_profile != 0)
+ seq_printf(
+ m, "\r\n %-35s = %s%s%s%s%s", "Profiles",
+ ((bt_link_info->a2dp_exist) ?
+ ((coex_sta->is_bt_a2dp_sink) ? "A2DP sink," :
+ "A2DP,") :
+ ""),
+ ((bt_link_info->sco_exist) ? "HFP," : ""),
+ ((bt_link_info->hid_exist) ?
+ ((coex_sta->hid_busy_num >= 2) ?
+ "HID(4/18)," :
+ "HID(2/18),") :
+ ""),
+ ((bt_link_info->pan_exist) ? "PAN," : ""),
+ ((coex_sta->voice_over_HOGP) ? "Voice" : ""));
+ else
+ seq_printf(m, "\r\n %-35s = None", "Profiles");
+
+ if (bt_link_info->a2dp_exist) {
+ seq_printf(m, "\r\n %-35s = %s/ %d/ %s",
+ "A2DP Rate/Bitpool/Auto_Slot",
+ ((coex_sta->is_A2DP_3M) ? "3M" : "No_3M"),
+ coex_sta->a2dp_bit_pool,
+ ((coex_sta->is_autoslot) ? "On" : "Off"));
+ }
+
+ if (bt_link_info->hid_exist) {
+ seq_printf(m, "\r\n %-35s = %d/ %d", "HID PairNum/Forbid_Slot",
+ coex_sta->hid_pair_cnt, coex_sta->forbidden_slot);
+ }
+
+ seq_printf(m, "\r\n %-35s = %s/ %d/ %s/ 0x%x",
+ "Role/RoleSwCnt/IgnWlact/Feature",
+ ((bt_link_info->slave_role) ? "Slave" : "Master"),
+ coex_sta->cnt_role_switch,
+ ((coex_dm->cur_ignore_wlan_act) ? "Yes" : "No"),
+ coex_sta->bt_coex_supported_feature);
+
+ if ((coex_sta->bt_ble_scan_type & 0x7) != 0x0) {
+ seq_printf(m, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
+ "BLEScan Type/TV/Init/Ble",
+ coex_sta->bt_ble_scan_type,
+ (coex_sta->bt_ble_scan_type & 0x1 ?
+ coex_sta->bt_ble_scan_para[0] :
+ 0x0),
+ (coex_sta->bt_ble_scan_type & 0x2 ?
+ coex_sta->bt_ble_scan_para[1] :
+ 0x0),
+ (coex_sta->bt_ble_scan_type & 0x4 ?
+ coex_sta->bt_ble_scan_para[2] :
+ 0x0));
+ }
+
+ seq_printf(m, "\r\n %-35s = %d/ %d/ %d/ %d/ %d",
+ "ReInit/ReLink/IgnWlact/Page/NameReq", coex_sta->cnt_reinit,
+ coex_sta->cnt_setup_link, coex_sta->cnt_ign_wlan_act,
+ coex_sta->cnt_page, coex_sta->cnt_remote_name_req);
+
+ halbtc8822b1ant_read_score_board(btcoexist, &u16tmp[0]);
+
+ if ((coex_sta->bt_reg_vendor_ae == 0xffff) ||
+ (coex_sta->bt_reg_vendor_ac == 0xffff))
+ seq_printf(m, "\r\n %-35s = x/ x/ %04x",
+ "0xae[4]/0xac[1:0]/Scoreboard", u16tmp[0]);
+ else
+ seq_printf(m, "\r\n %-35s = 0x%x/ 0x%x/ %04x",
+ "0xae[4]/0xac[1:0]/Scoreboard",
+ (int)((coex_sta->bt_reg_vendor_ae & BIT(4)) >> 4),
+ coex_sta->bt_reg_vendor_ac & 0x3, u16tmp[0]);
+
+ if (coex_sta->num_of_profile > 0) {
+ seq_printf(
+ m,
+ "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
+ "AFH MAP", coex_sta->bt_afh_map[0],
+ coex_sta->bt_afh_map[1], coex_sta->bt_afh_map[2],
+ coex_sta->bt_afh_map[3], coex_sta->bt_afh_map[4],
+ coex_sta->bt_afh_map[5], coex_sta->bt_afh_map[6],
+ coex_sta->bt_afh_map[7], coex_sta->bt_afh_map[8],
+ coex_sta->bt_afh_map[9]);
+ }
+
+ for (i = 0; i < BT_INFO_SRC_8822B_1ANT_MAX; i++) {
+ if (coex_sta->bt_info_c2h_cnt[i]) {
+ seq_printf(
+ m,
+ "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)",
+ glbt_info_src_8822b_1ant[i],
+ coex_sta->bt_info_c2h[i][0],
+ coex_sta->bt_info_c2h[i][1],
+ coex_sta->bt_info_c2h[i][2],
+ coex_sta->bt_info_c2h[i][3],
+ coex_sta->bt_info_c2h[i][4],
+ coex_sta->bt_info_c2h[i][5],
+ coex_sta->bt_info_c2h[i][6],
+ coex_sta->bt_info_c2h_cnt[i]);
+ }
+ }
+
+ if (btcoexist->manual_control)
+ seq_printf(
+ m, "\r\n %-35s",
+ "============[mechanisms] (before Manual)============");
+ else
+ seq_printf(m, "\r\n %-35s",
+ "============[Mechanisms]============");
+
+ ps_tdma_case = coex_dm->cur_ps_tdma;
+ seq_printf(m, "\r\n %-35s = %02x %02x %02x %02x %02x (case-%d, %s)",
+ "TDMA", coex_dm->ps_tdma_para[0], coex_dm->ps_tdma_para[1],
+ coex_dm->ps_tdma_para[2], coex_dm->ps_tdma_para[3],
+ coex_dm->ps_tdma_para[4], ps_tdma_case,
+ (coex_dm->cur_ps_tdma_on ? "TDMA On" : "TDMA Off"));
+
+ u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0);
+ u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4);
+ u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8);
+ seq_printf(m, "\r\n %-35s = %d/ 0x%x/ 0x%x/ 0x%x",
+ "Table/0x6c0/0x6c4/0x6c8", coex_sta->coex_table_type,
+ u32tmp[0], u32tmp[1], u32tmp[2]);
+
+ u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778);
+ u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6cc);
+ seq_printf(m, "\r\n %-35s = 0x%x/ 0x%x", "0x778/0x6cc", u8tmp[0],
+ u32tmp[0]);
+
+ seq_printf(m, "\r\n %-35s = %s/ %s/ %s/ %d",
+ "AntDiv/BtCtrlLPS/LPRA/PsFail",
+ ((board_info->ant_div_cfg) ? "On" : "Off"),
+ ((coex_sta->force_lps_ctrl) ? "On" : "Off"),
+ ((coex_dm->cur_low_penalty_ra) ? "On" : "Off"),
+ coex_sta->cnt_set_ps_state_fail);
+
+ u32tmp[0] = halbtc8822b1ant_ltecoex_indirect_read_reg(btcoexist, 0x38);
+ lte_coex_on = ((u32tmp[0] & BIT(7)) >> 7) ? true : false;
+
+ if (lte_coex_on) {
+ u32tmp[0] = halbtc8822b1ant_ltecoex_indirect_read_reg(btcoexist,
+ 0xa0);
+ u32tmp[1] = halbtc8822b1ant_ltecoex_indirect_read_reg(btcoexist,
+ 0xa4);
+
+ seq_printf(m, "\r\n %-35s = 0x%x/ 0x%x",
+ "LTE Coex Table W_L/B_L", u32tmp[0] & 0xffff,
+ u32tmp[1] & 0xffff);
+
+ u32tmp[0] = halbtc8822b1ant_ltecoex_indirect_read_reg(btcoexist,
+ 0xa8);
+ u32tmp[1] = halbtc8822b1ant_ltecoex_indirect_read_reg(btcoexist,
+ 0xac);
+ u32tmp[2] = halbtc8822b1ant_ltecoex_indirect_read_reg(btcoexist,
+ 0xb0);
+ u32tmp[3] = halbtc8822b1ant_ltecoex_indirect_read_reg(btcoexist,
+ 0xb4);
+
+ seq_printf(m, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
+ "LTE Break Table W_L/B_L/L_W/L_B",
+ u32tmp[0] & 0xffff, u32tmp[1] & 0xffff,
+ u32tmp[2] & 0xffff, u32tmp[3] & 0xffff);
+ }
+
+ /* Hw setting */
+ seq_printf(m, "\r\n %-35s", "============[Hw setting]============");
+
+ u32tmp[0] = halbtc8822b1ant_ltecoex_indirect_read_reg(btcoexist, 0x38);
+ u32tmp[1] = halbtc8822b1ant_ltecoex_indirect_read_reg(btcoexist, 0x54);
+ u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x73);
+
+ seq_printf(m, "\r\n %-35s = %s/ %s", "LTE Coex/Path Owner",
+ ((lte_coex_on) ? "On" : "Off"),
+ ((u8tmp[0] & BIT(2)) ? "WL" : "BT"));
+
+ if (lte_coex_on) {
+ seq_printf(m, "\r\n %-35s = %d/ %d/ %d/ %d",
+ "LTE 3Wire/OPMode/UART/UARTMode",
+ (int)((u32tmp[0] & BIT(6)) >> 6),
+ (int)((u32tmp[0] & (BIT(5) | BIT(4))) >> 4),
+ (int)((u32tmp[0] & BIT(3)) >> 3),
+ (int)(u32tmp[0] & (BIT(2) | BIT(1) | BIT(0))));
+
+ seq_printf(m, "\r\n %-35s = %d/ %d", "LTE_Busy/UART_Busy",
+ (int)((u32tmp[1] & BIT(1)) >> 1),
+ (int)(u32tmp[1] & BIT(0)));
+ }
+ seq_printf(m, "\r\n %-35s = %s (BB:%s)/ %s (BB:%s)/ %s %d",
+ "GNT_WL_Ctrl/GNT_BT_Ctrl/Dbg",
+ ((u32tmp[0] & BIT(12)) ? "SW" : "HW"),
+ ((u32tmp[0] & BIT(8)) ? "SW" : "HW"),
+ ((u32tmp[0] & BIT(14)) ? "SW" : "HW"),
+ ((u32tmp[0] & BIT(10)) ? "SW" : "HW"),
+ ((u8tmp[0] & BIT(3)) ? "On" : "Off"),
+ coex_sta->gnt_error_cnt);
+
+ seq_printf(m, "\r\n %-35s = %d/ %d", "GNT_WL/GNT_BT",
+ (int)((u32tmp[1] & BIT(2)) >> 2),
+ (int)((u32tmp[1] & BIT(3)) >> 3));
+
+ u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xcb0);
+ u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0xcb4);
+ u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xcba);
+
+ seq_printf(m, "\r\n %-35s = 0x%04x/ 0x%04x/ 0x%02x %s",
+ "0xcb0/0xcb4/0xcb8[23:16]", u32tmp[0], u32tmp[1], u8tmp[0],
+ ((u8tmp[0] & 0x1) == 0x1 ? "(BTG)" : "(WL_A+G)"));
+
+ u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c);
+ u8tmp[2] = btcoexist->btc_read_1byte(btcoexist, 0x64);
+ u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x4c6);
+ u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x40);
+
+ seq_printf(m, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
+ "4c[24:23]/64[0]/4c6[4]/40[5]",
+ (int)((u32tmp[0] & (BIT(24) | BIT(23))) >> 23),
+ u8tmp[2] & 0x1, (int)((u8tmp[0] & BIT(4)) >> 4),
+ (int)((u8tmp[1] & BIT(5)) >> 5));
+
+ u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550);
+ u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522);
+ u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x953);
+ u8tmp[2] = btcoexist->btc_read_1byte(btcoexist, 0xc50);
+
+ seq_printf(m, "\r\n %-35s = 0x%x/ 0x%x/ %s/ 0x%x",
+ "0x550/0x522/4-RxAGC/0xc50", u32tmp[0], u8tmp[0],
+ (u8tmp[1] & 0x2) ? "On" : "Off", u8tmp[2]);
+
+ fa_ofdm = btcoexist->btc_phydm_query_phy_counter(btcoexist,
+ "PHYDM_INFO_FA_OFDM");
+ fa_cck = btcoexist->btc_phydm_query_phy_counter(btcoexist,
+ "PHYDM_INFO_FA_CCK");
+ cca_ofdm = btcoexist->btc_phydm_query_phy_counter(
+ btcoexist, "PHYDM_INFO_CCA_OFDM");
+ cca_cck = btcoexist->btc_phydm_query_phy_counter(btcoexist,
+ "PHYDM_INFO_CCA_CCK");
+
+ seq_printf(m, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
+ "CCK-CCA/CCK-FA/OFDM-CCA/OFDM-FA", cca_cck, fa_cck, cca_ofdm,
+ fa_ofdm);
+
+ seq_printf(m, "\r\n %-35s = %d/ %d/ %d/ %d", "CRC_OK CCK/11g/11n/11ac",
+ coex_sta->crc_ok_cck, coex_sta->crc_ok_11g,
+ coex_sta->crc_ok_11n, coex_sta->crc_ok_11n_vht);
+
+ seq_printf(m, "\r\n %-35s = %d/ %d/ %d/ %d", "CRC_Err CCK/11g/11n/11ac",
+ coex_sta->crc_err_cck, coex_sta->crc_err_11g,
+ coex_sta->crc_err_11n, coex_sta->crc_err_11n_vht);
+
+ seq_printf(m, "\r\n %-35s = %s/ %s/ %s/ %d",
+ "WlHiPri/ Locking/ Locked/ Noisy",
+ (coex_sta->wifi_is_high_pri_task ? "Yes" : "No"),
+ (coex_sta->cck_lock ? "Yes" : "No"),
+ (coex_sta->cck_ever_lock ? "Yes" : "No"),
+ coex_sta->wl_noisy_level);
+
+ seq_printf(m, "\r\n %-35s = %d/ %d", "0x770(Hi-pri rx/tx)",
+ coex_sta->high_priority_rx, coex_sta->high_priority_tx);
+
+ seq_printf(m, "\r\n %-35s = %d/ %d %s", "0x774(Lo-pri rx/tx)",
+ coex_sta->low_priority_rx, coex_sta->low_priority_tx,
+ (bt_link_info->slave_role ?
+ "(Slave!!)" :
+ (coex_sta->is_tdma_btautoslot_hang ?
+ "(auto-slot hang!!)" :
+ "")));
+
+ btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS, m);
+}
+
+void ex_btc8822b1ant_ips_notify(struct btc_coexist *btcoexist, u8 type)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ if (btcoexist->manual_control || btcoexist->stop_coex_dm)
+ return;
+
+ if (type == BTC_IPS_ENTER) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], IPS ENTER notify\n");
+ coex_sta->under_ips = true;
+
+ /* Write WL "Active" in Score-board for LPS off */
+ halbtc8822b1ant_post_state_to_bt(
+ btcoexist, BT_8822B_1ANT_SCOREBOARD_ACTIVE, false);
+
+ halbtc8822b1ant_post_state_to_bt(
+ btcoexist, BT_8822B_1ANT_SCOREBOARD_ONOFF, false);
+
+ halbtc8822b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
+
+ halbtc8822b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO,
+ FORCE_EXEC,
+ BT_8822B_1ANT_PHASE_WLAN_OFF);
+
+ halbtc8822b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+ } else if (type == BTC_IPS_LEAVE) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], IPS LEAVE notify\n");
+ halbtc8822b1ant_post_state_to_bt(
+ btcoexist, BT_8822B_1ANT_SCOREBOARD_ACTIVE, true);
+
+ halbtc8822b1ant_post_state_to_bt(
+ btcoexist, BT_8822B_1ANT_SCOREBOARD_ONOFF, true);
+
+ /*leave IPS : run ini hw config (exclude wifi only)*/
+ halbtc8822b1ant_init_hw_config(btcoexist, false, false);
+ /*sw all off*/
+ halbtc8822b1ant_init_coex_dm(btcoexist);
+ /*leave IPS : Query bt info*/
+ halbtc8822b1ant_query_bt_info(btcoexist);
+
+ coex_sta->under_ips = false;
+ }
+}
+
+void ex_btc8822b1ant_lps_notify(struct btc_coexist *btcoexist, u8 type)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ static bool pre_force_lps_on;
+
+ if (btcoexist->manual_control || btcoexist->stop_coex_dm)
+ return;
+
+ if (type == BTC_LPS_ENABLE) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], LPS ENABLE notify\n");
+ coex_sta->under_lps = true;
+
+ if (coex_sta->force_lps_ctrl) { /* LPS No-32K */
+ /* Write WL "Active" in Score-board for PS-TDMA */
+ pre_force_lps_on = true;
+ halbtc8822b1ant_post_state_to_bt(
+ btcoexist, BT_8822B_1ANT_SCOREBOARD_ACTIVE,
+ true);
+ } else {
+ /* LPS-32K, need check if this h2c 0x71 can work??
+ * (2015/08/28)
+ */
+ /* Write WL "Non-Active" in Score-board for Native-PS */
+ pre_force_lps_on = false;
+ halbtc8822b1ant_post_state_to_bt(
+ btcoexist, BT_8822B_1ANT_SCOREBOARD_ACTIVE,
+ false);
+ }
+ } else if (type == BTC_LPS_DISABLE) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], LPS DISABLE notify\n");
+ coex_sta->under_lps = false;
+
+ /* Write WL "Active" in Score-board for LPS off */
+ halbtc8822b1ant_post_state_to_bt(
+ btcoexist, BT_8822B_1ANT_SCOREBOARD_ACTIVE, true);
+
+ if ((!pre_force_lps_on) && (!coex_sta->force_lps_ctrl))
+ halbtc8822b1ant_query_bt_info(btcoexist);
+ }
+}
+
+void ex_btc8822b1ant_scan_notify(struct btc_coexist *btcoexist, u8 type)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ bool wifi_connected = false;
+ bool wifi_under_5g = false;
+
+ if (btcoexist->manual_control || btcoexist->stop_coex_dm)
+ return;
+
+ coex_sta->freeze_coexrun_by_btinfo = false;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
+ &wifi_connected);
+
+ if (wifi_connected)
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** WL connected before SCAN\n");
+ else
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** WL is not connected before SCAN\n");
+
+ halbtc8822b1ant_query_bt_info(btcoexist);
+
+ /*2.4 g 1*/
+ if (type == BTC_SCAN_START) {
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G,
+ &wifi_under_5g);
+ /*5 g 1*/
+
+ if (wifi_under_5g) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (scan_notify_5g_scan_start) **********\n");
+ halbtc8822b1ant_action_wifi_under5g(btcoexist);
+ return;
+ }
+
+ /* 2.4G.2.3*/
+ coex_sta->wifi_is_high_pri_task = true;
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (scan_notify_2g_scan_start) **********\n");
+
+ if (!wifi_connected) { /* non-connected scan */
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** wifi is not connected scan **********\n");
+ halbtc8822b1ant_action_wifi_not_connected_scan(
+ btcoexist);
+ } else { /* wifi is connected */
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** wifi is connected scan **********\n");
+ halbtc8822b1ant_action_wifi_connected_scan(btcoexist);
+ }
+
+ return;
+ }
+
+ if (type == BTC_SCAN_START_2G) {
+ coex_sta->wifi_is_high_pri_task = true;
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (scan_notify_2g_sacn_start_for_switch_band_used) **********\n");
+
+ if (!wifi_connected) { /* non-connected scan */
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** wifi is not connected **********\n");
+
+ halbtc8822b1ant_action_wifi_not_connected_scan(
+ btcoexist);
+ } else { /* wifi is connected */
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** wifi is connected **********\n");
+ halbtc8822b1ant_action_wifi_connected_scan(btcoexist);
+ }
+ } else {
+ coex_sta->wifi_is_high_pri_task = false;
+
+ /* 2.4G 5 WL scan finish, then get and update sacn ap numbers */
+ /*5 g 4*/
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM,
+ &coex_sta->scan_ap_num);
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (scan_finish_notify) **********\n");
+
+ if (!wifi_connected) { /* non-connected scan */
+ halbtc8822b1ant_action_wifi_not_connected(btcoexist);
+ } else {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** scan_finish_notify wifi is connected **********\n");
+ halbtc8822b1ant_action_wifi_connected(btcoexist);
+ }
+ }
+}
+
+void ex_btc8822b1ant_scan_notify_without_bt(struct btc_coexist *btcoexist,
+ u8 type)
+{
+ bool wifi_under_5g = false;
+
+ if (type == BTC_SCAN_START) {
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G,
+ &wifi_under_5g);
+
+ if (wifi_under_5g) {
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcbd,
+ 0x3, 1);
+ return;
+ }
+
+ /* under 2.4G */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcbd, 0x3, 2);
+ return;
+ }
+ if (type == BTC_SCAN_START_2G)
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcbd, 0x3, 2);
+}
+
+void ex_btc8822b1ant_switchband_notify(struct btc_coexist *btcoexist, u8 type)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (switchband_notify) **********\n");
+
+ if (btcoexist->manual_control || btcoexist->stop_coex_dm)
+ return;
+
+ coex_sta->switch_band_notify_to = type;
+ /*2.4g 4.*/ /*5 g 2*/
+ if (type == BTC_SWITCH_TO_5G) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (switchband_notify BTC_SWITCH_TO_5G) **********\n");
+
+ halbtc8822b1ant_action_wifi_under5g(btcoexist);
+ return;
+ } else if (type == BTC_SWITCH_TO_24G_NOFORSCAN) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (switchband_notify BTC_SWITCH_TO_2G (no for scan)) **********\n");
+
+ halbtc8822b1ant_run_coexist_mechanism(btcoexist);
+ /*5 g 3*/
+
+ } else {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (switchband_notify BTC_SWITCH_TO_2G) **********\n");
+
+ ex_btc8822b1ant_scan_notify(btcoexist, BTC_SCAN_START_2G);
+ }
+ coex_sta->switch_band_notify_to = BTC_NOT_SWITCH;
+}
+
+void ex_btc8822b1ant_switchband_notify_without_bt(struct btc_coexist *btcoexist,
+ u8 type)
+{
+ bool wifi_under_5g = false;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
+
+ if (type == BTC_SWITCH_TO_5G) {
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcbd, 0x3, 1);
+ return;
+ } else if (type == BTC_SWITCH_TO_24G_NOFORSCAN) {
+ if (wifi_under_5g)
+
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcbd,
+ 0x3, 1);
+
+ else
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcbd,
+ 0x3, 2);
+ } else {
+ ex_btc8822b1ant_scan_notify_without_bt(btcoexist,
+ BTC_SCAN_START_2G);
+ }
+}
+
+void ex_btc8822b1ant_connect_notify(struct btc_coexist *btcoexist, u8 type)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ bool wifi_connected = false;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (connect notify) **********\n");
+
+ halbtc8822b1ant_post_state_to_bt(btcoexist,
+ BT_8822B_1ANT_SCOREBOARD_SCAN, true);
+
+ if (btcoexist->manual_control || btcoexist->stop_coex_dm)
+ return;
+
+ if ((type == BTC_ASSOCIATE_5G_START) ||
+ (type == BTC_ASSOCIATE_5G_FINISH)) {
+ if (type == BTC_ASSOCIATE_5G_START) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (5G associate start notify) **********\n");
+
+ halbtc8822b1ant_action_wifi_under5g(btcoexist);
+
+ } else if (type == BTC_ASSOCIATE_5G_FINISH) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (5G associate finish notify) **********\n");
+ }
+
+ return;
+ }
+
+ if (type == BTC_ASSOCIATE_START) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], 2G CONNECT START notify\n");
+
+ coex_sta->wifi_is_high_pri_task = true;
+
+ halbtc8822b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO,
+ FORCE_EXEC,
+ BT_8822B_1ANT_PHASE_2G_RUNTIME);
+
+ coex_dm->arp_cnt = 0;
+
+ halbtc8822b1ant_action_wifi_not_connected_asso_auth(btcoexist);
+
+ coex_sta->freeze_coexrun_by_btinfo = true;
+
+ } else {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], 2G CONNECT Finish notify\n");
+ coex_sta->wifi_is_high_pri_task = false;
+ coex_sta->freeze_coexrun_by_btinfo = false;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
+ &wifi_connected);
+
+ if (!wifi_connected) /* non-connected scan */
+ halbtc8822b1ant_action_wifi_not_connected(btcoexist);
+ else
+ halbtc8822b1ant_action_wifi_connected(btcoexist);
+ }
+}
+
+void ex_btc8822b1ant_media_status_notify(struct btc_coexist *btcoexist, u8 type)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ bool wifi_under_b_mode = false;
+ bool wifi_under_5g = false;
+
+ if (btcoexist->manual_control || btcoexist->stop_coex_dm)
+ return;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
+
+ if (type == BTC_MEDIA_CONNECT) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], 2g media connect notify");
+
+ halbtc8822b1ant_post_state_to_bt(
+ btcoexist, BT_8822B_1ANT_SCOREBOARD_ACTIVE, true);
+
+ if (wifi_under_5g) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], 5g media notify\n");
+
+ halbtc8822b1ant_action_wifi_under5g(btcoexist);
+ return;
+ }
+ /* Force antenna setup for no scan result issue */
+ halbtc8822b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO,
+ FORCE_EXEC,
+ BT_8822B_1ANT_PHASE_2G_RUNTIME);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_B_MODE,
+ &wifi_under_b_mode);
+
+ /* Set CCK Tx/Rx high Pri except 11b mode */
+ if (wifi_under_b_mode) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (media status notity under b mode) **********\n");
+ btcoexist->btc_write_1byte(btcoexist, 0x6cd,
+ 0x00); /* CCK Tx */
+ btcoexist->btc_write_1byte(btcoexist, 0x6cf,
+ 0x00); /* CCK Rx */
+ } else {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** (media status notity not under b mode) **********\n");
+ btcoexist->btc_write_1byte(btcoexist, 0x6cd,
+ 0x00); /* CCK Tx */
+ btcoexist->btc_write_1byte(btcoexist, 0x6cf,
+ 0x10); /* CCK Rx */
+ }
+
+ coex_dm->backup_arfr_cnt1 =
+ btcoexist->btc_read_4byte(btcoexist, 0x430);
+ coex_dm->backup_arfr_cnt2 =
+ btcoexist->btc_read_4byte(btcoexist, 0x434);
+ coex_dm->backup_retry_limit =
+ btcoexist->btc_read_2byte(btcoexist, 0x42a);
+ coex_dm->backup_ampdu_max_time =
+ btcoexist->btc_read_1byte(btcoexist, 0x456);
+ } else {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], 2g media disconnect notify\n");
+ coex_dm->arp_cnt = 0;
+
+ halbtc8822b1ant_post_state_to_bt(
+ btcoexist, BT_8822B_1ANT_SCOREBOARD_ACTIVE, false);
+
+ btcoexist->btc_write_1byte(btcoexist, 0x6cd, 0x0); /* CCK Tx */
+ btcoexist->btc_write_1byte(btcoexist, 0x6cf, 0x0); /* CCK Rx */
+
+ coex_sta->cck_ever_lock = false;
+ }
+
+ halbtc8822b1ant_update_wifi_ch_info(btcoexist, type);
+}
+
+void ex_btc8822b1ant_specific_packet_notify(struct btc_coexist *btcoexist,
+ u8 type)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ bool under_4way = false, wifi_under_5g = false;
+
+ if (btcoexist->manual_control || btcoexist->stop_coex_dm)
+ return;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
+ if (wifi_under_5g) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], 5g special packet notify\n");
+
+ halbtc8822b1ant_action_wifi_under5g(btcoexist);
+ return;
+ }
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS,
+ &under_4way);
+
+ if (under_4way) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], specific Packet ---- under_4way!!\n");
+
+ coex_sta->wifi_is_high_pri_task = true;
+ coex_sta->specific_pkt_period_cnt = 2;
+ } else if (type == BTC_PACKET_ARP) {
+ coex_dm->arp_cnt++;
+
+ if (coex_sta->wifi_is_high_pri_task) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], specific Packet ARP notify -cnt = %d\n",
+ coex_dm->arp_cnt);
+ }
+
+ } else {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], specific Packet DHCP or EAPOL notify [Type = %d]\n",
+ type);
+
+ coex_sta->wifi_is_high_pri_task = true;
+ coex_sta->specific_pkt_period_cnt = 2;
+ }
+
+ if (coex_sta->wifi_is_high_pri_task)
+ halbtc8822b1ant_action_wifi_connected_specific_packet(
+ btcoexist);
+}
+
+void ex_btc8822b1ant_bt_info_notify(struct btc_coexist *btcoexist, u8 *tmp_buf,
+ u8 length)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ u8 i, rsp_source = 0;
+ bool wifi_connected = false;
+ bool wifi_scan = false, wifi_link = false, wifi_roam = false,
+ wifi_busy = false;
+ static bool is_scoreboard_scan;
+
+ if (psd_scan->is_ant_det_running) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], bt_info_notify return for AntDet is running\n");
+ return;
+ }
+
+ rsp_source = tmp_buf[0] & 0xf;
+ if (rsp_source >= BT_INFO_SRC_8822B_1ANT_MAX)
+ rsp_source = BT_INFO_SRC_8822B_1ANT_WIFI_FW;
+ coex_sta->bt_info_c2h_cnt[rsp_source]++;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Bt_info[%d], len=%d, data=[", rsp_source, length);
+
+ for (i = 0; i < length; i++) {
+ coex_sta->bt_info_c2h[rsp_source][i] = tmp_buf[i];
+
+ if (i == length - 1) {
+ /* last one */
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "0x%02x]\n", tmp_buf[i]);
+ } else {
+ /* normal */
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, "0x%02x, ",
+ tmp_buf[i]);
+ }
+ }
+
+ coex_sta->bt_info = coex_sta->bt_info_c2h[rsp_source][1];
+ coex_sta->bt_info_ext = coex_sta->bt_info_c2h[rsp_source][4];
+ coex_sta->bt_info_ext2 = coex_sta->bt_info_c2h[rsp_source][5];
+
+ if (rsp_source != BT_INFO_SRC_8822B_1ANT_WIFI_FW) {
+ /* if 0xff, it means BT is under WHCK test */
+ coex_sta->bt_whck_test =
+ ((coex_sta->bt_info == 0xff) ? true : false);
+
+ coex_sta->bt_create_connection =
+ ((coex_sta->bt_info_c2h[rsp_source][2] & 0x80) ? true :
+ false);
+
+ /* unit: %, value-100 to translate to unit: dBm */
+ coex_sta->bt_rssi =
+ coex_sta->bt_info_c2h[rsp_source][3] * 2 + 10;
+
+ coex_sta->c2h_bt_remote_name_req =
+ ((coex_sta->bt_info_c2h[rsp_source][2] & 0x20) ? true :
+ false);
+
+ coex_sta->is_A2DP_3M =
+ ((coex_sta->bt_info_c2h[rsp_source][2] & 0x10) ? true :
+ false);
+
+ coex_sta->acl_busy =
+ ((coex_sta->bt_info_c2h[rsp_source][1] & 0x9) ? true :
+ false);
+
+ coex_sta->voice_over_HOGP =
+ ((coex_sta->bt_info_ext & 0x10) ? true : false);
+
+ coex_sta->c2h_bt_inquiry_page =
+ ((coex_sta->bt_info & BT_INFO_8822B_1ANT_B_INQ_PAGE) ?
+ true :
+ false);
+
+ coex_sta->a2dp_bit_pool =
+ (((coex_sta->bt_info_c2h[rsp_source][1] & 0x49) ==
+ 0x49) ?
+ (coex_sta->bt_info_c2h[rsp_source][6] & 0x7f) :
+ 0);
+
+ coex_sta->is_bt_a2dp_sink =
+ (coex_sta->bt_info_c2h[rsp_source][6] & 0x80) ? true :
+ false;
+
+ coex_sta->bt_retry_cnt =
+ coex_sta->bt_info_c2h[rsp_source][2] & 0xf;
+
+ coex_sta->is_autoslot = coex_sta->bt_info_ext2 & 0x8;
+
+ coex_sta->forbidden_slot = coex_sta->bt_info_ext2 & 0x7;
+
+ coex_sta->hid_busy_num = (coex_sta->bt_info_ext2 & 0x30) >> 4;
+
+ coex_sta->hid_pair_cnt = (coex_sta->bt_info_ext2 & 0xc0) >> 6;
+ if (coex_sta->bt_retry_cnt >= 1)
+ coex_sta->pop_event_cnt++;
+
+ if (coex_sta->c2h_bt_remote_name_req)
+ coex_sta->cnt_remote_name_req++;
+
+ if (coex_sta->bt_info_ext & BIT(1))
+ coex_sta->cnt_reinit++;
+
+ if (coex_sta->bt_info_ext & BIT(2)) {
+ coex_sta->cnt_setup_link++;
+ coex_sta->is_setup_link = true;
+ coex_sta->bt_relink_downcount = 2;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Re-Link start in BT info!!\n");
+ } else {
+ coex_sta->is_setup_link = false;
+ coex_sta->bt_relink_downcount = 0;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Re-Link stop in BT info!!\n");
+ }
+
+ if (coex_sta->bt_info_ext & BIT(3))
+ coex_sta->cnt_ign_wlan_act++;
+
+ if (coex_sta->bt_info_ext & BIT(6))
+ coex_sta->cnt_role_switch++;
+
+ if (coex_sta->bt_info_ext & BIT(7))
+ coex_sta->is_bt_multi_link = true;
+ else
+ coex_sta->is_bt_multi_link = false;
+
+ if (coex_sta->bt_create_connection) {
+ coex_sta->cnt_page++;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY,
+ &wifi_busy);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN,
+ &wifi_scan);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK,
+ &wifi_link);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM,
+ &wifi_roam);
+
+ if ((wifi_link) || (wifi_roam) || (wifi_scan) ||
+ (coex_sta->wifi_is_high_pri_task) || (wifi_busy)) {
+ is_scoreboard_scan = true;
+ halbtc8822b1ant_post_state_to_bt(
+ btcoexist,
+ BT_8822B_1ANT_SCOREBOARD_SCAN, true);
+
+ } else {
+ halbtc8822b1ant_post_state_to_bt(
+ btcoexist,
+ BT_8822B_1ANT_SCOREBOARD_SCAN, false);
+ }
+ } else {
+ if (is_scoreboard_scan) {
+ halbtc8822b1ant_post_state_to_bt(
+ btcoexist,
+ BT_8822B_1ANT_SCOREBOARD_SCAN, false);
+ is_scoreboard_scan = false;
+ }
+ }
+
+ /* Here we need to resend some wifi info to BT */
+ /* because bt is reset and loss of the info. */
+
+ if ((!btcoexist->manual_control) &&
+ (!btcoexist->stop_coex_dm)) {
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
+ &wifi_connected);
+
+ /* Re-Init */
+ if ((coex_sta->bt_info_ext & BIT(1))) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n");
+ if (wifi_connected)
+ halbtc8822b1ant_update_wifi_ch_info(
+ btcoexist, BTC_MEDIA_CONNECT);
+ else
+ halbtc8822b1ant_update_wifi_ch_info(
+ btcoexist,
+ BTC_MEDIA_DISCONNECT);
+ }
+
+ /* If Ignore_WLanAct && not SetUp_Link */
+ if ((coex_sta->bt_info_ext & BIT(3)) &&
+ (!(coex_sta->bt_info_ext & BIT(2)))) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n");
+ halbtc8822b1ant_ignore_wlan_act(
+ btcoexist, FORCE_EXEC, false);
+ }
+ }
+ }
+
+ if ((coex_sta->bt_info_ext & BIT(5))) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT ext info bit4 check, query BLE Scan type!!\n");
+ coex_sta->bt_ble_scan_type =
+ btcoexist->btc_get_ble_scan_type_from_bt(btcoexist);
+
+ if ((coex_sta->bt_ble_scan_type & 0x1) == 0x1)
+ coex_sta->bt_ble_scan_para[0] =
+ btcoexist->btc_get_ble_scan_para_from_bt(
+ btcoexist, 0x1);
+ if ((coex_sta->bt_ble_scan_type & 0x2) == 0x2)
+ coex_sta->bt_ble_scan_para[1] =
+ btcoexist->btc_get_ble_scan_para_from_bt(
+ btcoexist, 0x2);
+ if ((coex_sta->bt_ble_scan_type & 0x4) == 0x4)
+ coex_sta->bt_ble_scan_para[2] =
+ btcoexist->btc_get_ble_scan_para_from_bt(
+ btcoexist, 0x4);
+ }
+
+ halbtc8822b1ant_update_bt_link_info(btcoexist);
+
+ halbtc8822b1ant_run_coexist_mechanism(btcoexist);
+}
+
+void ex_btc8822b1ant_rf_status_notify(struct btc_coexist *btcoexist, u8 type)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], RF Status notify\n");
+
+ if (type == BTC_RF_ON) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], RF is turned ON!!\n");
+ btcoexist->stop_coex_dm = false;
+
+ halbtc8822b1ant_post_state_to_bt(
+ btcoexist, BT_8822B_1ANT_SCOREBOARD_ACTIVE, true);
+ halbtc8822b1ant_post_state_to_bt(
+ btcoexist, BT_8822B_1ANT_SCOREBOARD_ONOFF, true);
+
+ } else if (type == BTC_RF_OFF) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], RF is turned OFF!!\n");
+
+ halbtc8822b1ant_post_state_to_bt(
+ btcoexist, BT_8822B_1ANT_SCOREBOARD_ACTIVE, false);
+ halbtc8822b1ant_post_state_to_bt(
+ btcoexist, BT_8822B_1ANT_SCOREBOARD_ONOFF, false);
+ halbtc8822b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 0);
+
+ halbtc8822b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO,
+ FORCE_EXEC,
+ BT_8822B_1ANT_PHASE_WLAN_OFF);
+ /* for test : s3 bt disppear , fail rate 1/600*/
+
+ halbtc8822b1ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true);
+
+ btcoexist->stop_coex_dm = true;
+ }
+}
+
+void ex_btc8822b1ant_halt_notify(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, "[BTCoex], Halt notify\n");
+
+ halbtc8822b1ant_post_state_to_bt(
+ btcoexist, BT_8822B_1ANT_SCOREBOARD_ACTIVE, false);
+ halbtc8822b1ant_post_state_to_bt(btcoexist,
+ BT_8822B_1ANT_SCOREBOARD_ONOFF, false);
+
+ halbtc8822b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 0);
+
+ halbtc8822b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO, FORCE_EXEC,
+ BT_8822B_1ANT_PHASE_WLAN_OFF);
+ /* for test : s3 bt disppear , fail rate 1/600*/
+
+ halbtc8822b1ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true);
+
+ ex_btc8822b1ant_media_status_notify(btcoexist, BTC_MEDIA_DISCONNECT);
+ btcoexist->stop_coex_dm = true;
+}
+
+void ex_btc8822b1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ bool wifi_under_5g = false;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, "[BTCoex], Pnp notify\n");
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
+
+ if ((pnp_state == BTC_WIFI_PNP_SLEEP) ||
+ (pnp_state == BTC_WIFI_PNP_SLEEP_KEEP_ANT)) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Pnp notify to SLEEP\n");
+
+ halbtc8822b1ant_post_state_to_bt(
+ btcoexist, BT_8822B_1ANT_SCOREBOARD_ACTIVE |
+ BT_8822B_1ANT_SCOREBOARD_ONOFF |
+ BT_8822B_1ANT_SCOREBOARD_SCAN |
+ BT_8822B_1ANT_SCOREBOARD_UNDERTEST,
+ false);
+
+ if (pnp_state == BTC_WIFI_PNP_SLEEP_KEEP_ANT) {
+ if (wifi_under_5g)
+ halbtc8822b1ant_set_ant_path(
+ btcoexist, BTC_ANT_PATH_AUTO,
+ FORCE_EXEC,
+ BT_8822B_1ANT_PHASE_5G_RUNTIME);
+ else
+ halbtc8822b1ant_set_ant_path(
+ btcoexist, BTC_ANT_PATH_AUTO,
+ FORCE_EXEC,
+ BT_8822B_1ANT_PHASE_2G_RUNTIME);
+ } else {
+ halbtc8822b1ant_set_ant_path(
+ btcoexist, BTC_ANT_PATH_AUTO, FORCE_EXEC,
+ BT_8822B_1ANT_PHASE_WLAN_OFF);
+ }
+
+ btcoexist->stop_coex_dm = true;
+ } else if (pnp_state == BTC_WIFI_PNP_WAKE_UP) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Pnp notify to WAKE UP\n");
+ btcoexist->stop_coex_dm = false;
+ }
+}
+
+void ex_btc8822b1ant_coex_dm_reset(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], *****************Coex DM Reset*****************\n");
+
+ halbtc8822b1ant_init_hw_config(btcoexist, false, false);
+ halbtc8822b1ant_init_coex_dm(btcoexist);
+}
+
+void ex_btc8822b1ant_periodical(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ bool bt_relink_finish = false;
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ==========================Periodical===========================\n");
+
+ if (!btcoexist->auto_report_1ant)
+ halbtc8822b1ant_query_bt_info(btcoexist);
+
+ halbtc8822b1ant_monitor_bt_ctr(btcoexist);
+ halbtc8822b1ant_monitor_wifi_ctr(btcoexist);
+
+ halbtc8822b1ant_monitor_bt_enable_disable(btcoexist);
+
+ if (coex_sta->bt_relink_downcount != 0) {
+ coex_sta->bt_relink_downcount--;
+
+ if (coex_sta->bt_relink_downcount == 0) {
+ coex_sta->is_setup_link = false;
+ bt_relink_finish = true;
+ }
+ }
+
+ /* for 4-way, DHCP, EAPOL packet */
+ if (coex_sta->specific_pkt_period_cnt > 0) {
+ coex_sta->specific_pkt_period_cnt--;
+
+ if ((coex_sta->specific_pkt_period_cnt == 0) &&
+ (coex_sta->wifi_is_high_pri_task))
+ coex_sta->wifi_is_high_pri_task = false;
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ***************** Hi-Pri Task = %s*****************\n",
+ (coex_sta->wifi_is_high_pri_task ? "Yes" : "No"));
+ }
+
+ if (halbtc8822b1ant_is_wifi_status_changed(btcoexist) ||
+ (bt_relink_finish) || (coex_sta->is_set_ps_state_fail))
+ halbtc8822b1ant_run_coexist_mechanism(btcoexist);
+}
+
+void ex_btc8822b1ant_antenna_detection(struct btc_coexist *btcoexist,
+ u32 cent_freq, u32 offset, u32 span,
+ u32 seconds)
+{
+}
+
+void ex_btc8822b1ant_antenna_isolation(struct btc_coexist *btcoexist,
+ u32 cent_freq, u32 offset, u32 span,
+ u32 seconds)
+{
+}
+
+void ex_btc8822b1ant_psd_scan(struct btc_coexist *btcoexist, u32 cent_freq,
+ u32 offset, u32 span, u32 seconds)
+{
+}
+
+void ex_btc8822b1ant_display_ant_detection(struct btc_coexist *btcoexist) {}
+
+void ex_btc8822b1ant_dbg_control(struct btc_coexist *btcoexist, u8 op_code,
+ u8 op_len, u8 *pdata)
+{
+}
diff --git a/drivers/staging/rtlwifi/btcoexist/halbtc8822b1ant.h b/drivers/staging/rtlwifi/btcoexist/halbtc8822b1ant.h
new file mode 100644
index 0000000..583e99d
--- /dev/null
+++ b/drivers/staging/rtlwifi/btcoexist/halbtc8822b1ant.h
@@ -0,0 +1,444 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+/* *******************************************
+ * The following is for 8822B 1ANT BT Co-exist definition
+ * ********************************************/
+#define BT_INFO_8822B_1ANT_B_FTP BIT(7)
+#define BT_INFO_8822B_1ANT_B_A2DP BIT(6)
+#define BT_INFO_8822B_1ANT_B_HID BIT(5)
+#define BT_INFO_8822B_1ANT_B_SCO_BUSY BIT(4)
+#define BT_INFO_8822B_1ANT_B_ACL_BUSY BIT(3)
+#define BT_INFO_8822B_1ANT_B_INQ_PAGE BIT(2)
+#define BT_INFO_8822B_1ANT_B_SCO_ESCO BIT(1)
+#define BT_INFO_8822B_1ANT_B_CONNECTION BIT(0)
+
+#define BT_INFO_8822B_1ANT_A2DP_BASIC_RATE(_BT_INFO_EXT_) \
+ (((_BT_INFO_EXT_ & BIT(0))) ? true : false)
+
+#define BTC_RSSI_COEX_THRESH_TOL_8822B_1ANT 2
+
+#define BT_8822B_1ANT_WIFI_NOISY_THRESH 150 /* max: 255 */
+#define BT_8822B_1ANT_DEFAULT_ISOLATION 15 /* unit: dB */
+
+/* for Antenna detection */
+#define BT_8822B_1ANT_ANTDET_PSDTHRES_BACKGROUND 50
+#define BT_8822B_1ANT_ANTDET_PSDTHRES_2ANT_BADISOLATION 70
+#define BT_8822B_1ANT_ANTDET_PSDTHRES_2ANT_GOODISOLATION 55
+#define BT_8822B_1ANT_ANTDET_PSDTHRES_1ANT 35
+#define BT_8822B_1ANT_ANTDET_RETRY_INTERVAL \
+ 10 /* retry timer if ant det is fail, unit: second */
+#define BT_8822B_1ANT_ANTDET_ENABLE 0
+#define BT_8822B_1ANT_ANTDET_COEXMECHANISMSWITCH_ENABLE 0
+
+#define BT_8822B_1ANT_LTECOEX_INDIRECTREG_ACCESS_TIMEOUT 30000
+
+enum bt_8822b_1ant_signal_state {
+ BT_8822B_1ANT_SIG_STA_SET_TO_LOW = 0x0,
+ BT_8822B_1ANT_SIG_STA_SET_BY_HW = 0x0,
+ BT_8822B_1ANT_SIG_STA_SET_TO_HIGH = 0x1,
+ BT_8822B_1ANT_SIG_STA_MAX
+};
+
+enum bt_8822b_1ant_path_ctrl_owner {
+ BT_8822B_1ANT_PCO_BTSIDE = 0x0,
+ BT_8822B_1ANT_PCO_WLSIDE = 0x1,
+ BT_8822B_1ANT_PCO_MAX
+};
+
+enum bt_8822b_1ant_gnt_ctrl_type {
+ BT_8822B_1ANT_GNT_CTRL_BY_PTA = 0x0,
+ BT_8822B_1ANT_GNT_CTRL_BY_SW = 0x1,
+ BT_8822B_1ANT_GNT_CTRL_MAX
+};
+
+enum bt_8822b_1ant_gnt_ctrl_block {
+ BT_8822B_1ANT_GNT_BLOCK_RFC_BB = 0x0,
+ BT_8822B_1ANT_GNT_BLOCK_RFC = 0x1,
+ BT_8822B_1ANT_GNT_BLOCK_BB = 0x2,
+ BT_8822B_1ANT_GNT_BLOCK_MAX
+};
+
+enum bt_8822b_1ant_lte_coex_table_type {
+ BT_8822B_1ANT_CTT_WL_VS_LTE = 0x0,
+ BT_8822B_1ANT_CTT_BT_VS_LTE = 0x1,
+ BT_8822B_1ANT_CTT_MAX
+};
+
+enum bt_8822b_1ant_lte_break_table_type {
+ BT_8822B_1ANT_LBTT_WL_BREAK_LTE = 0x0,
+ BT_8822B_1ANT_LBTT_BT_BREAK_LTE = 0x1,
+ BT_8822B_1ANT_LBTT_LTE_BREAK_WL = 0x2,
+ BT_8822B_1ANT_LBTT_LTE_BREAK_BT = 0x3,
+ BT_8822B_1ANT_LBTT_MAX
+};
+
+enum bt_info_src_8822b_1ant {
+ BT_INFO_SRC_8822B_1ANT_WIFI_FW = 0x0,
+ BT_INFO_SRC_8822B_1ANT_BT_RSP = 0x1,
+ BT_INFO_SRC_8822B_1ANT_BT_ACTIVE_SEND = 0x2,
+ BT_INFO_SRC_8822B_1ANT_MAX
+};
+
+enum bt_8822b_1ant_bt_status {
+ BT_8822B_1ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0,
+ BT_8822B_1ANT_BT_STATUS_CONNECTED_IDLE = 0x1,
+ BT_8822B_1ANT_BT_STATUS_INQ_PAGE = 0x2,
+ BT_8822B_1ANT_BT_STATUS_ACL_BUSY = 0x3,
+ BT_8822B_1ANT_BT_STATUS_SCO_BUSY = 0x4,
+ BT_8822B_1ANT_BT_STATUS_ACL_SCO_BUSY = 0x5,
+ BT_8822B_1ANT_BT_STATUS_MAX
+};
+
+enum bt_8822b_1ant_wifi_status {
+ BT_8822B_1ANT_WIFI_STATUS_NON_CONNECTED_IDLE = 0x0,
+ BT_8822B_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN = 0x1,
+ BT_8822B_1ANT_WIFI_STATUS_CONNECTED_SCAN = 0x2,
+ BT_8822B_1ANT_WIFI_STATUS_CONNECTED_SPECIFIC_PKT = 0x3,
+ BT_8822B_1ANT_WIFI_STATUS_CONNECTED_IDLE = 0x4,
+ BT_8822B_1ANT_WIFI_STATUS_CONNECTED_BUSY = 0x5,
+ BT_8822B_1ANT_WIFI_STATUS_MAX
+};
+
+enum bt_8822b_1ant_coex_algo {
+ BT_8822B_1ANT_COEX_ALGO_UNDEFINED = 0x0,
+ BT_8822B_1ANT_COEX_ALGO_SCO = 0x1,
+ BT_8822B_1ANT_COEX_ALGO_HID = 0x2,
+ BT_8822B_1ANT_COEX_ALGO_A2DP = 0x3,
+ BT_8822B_1ANT_COEX_ALGO_A2DP_PANHS = 0x4,
+ BT_8822B_1ANT_COEX_ALGO_PANEDR = 0x5,
+ BT_8822B_1ANT_COEX_ALGO_PANHS = 0x6,
+ BT_8822B_1ANT_COEX_ALGO_PANEDR_A2DP = 0x7,
+ BT_8822B_1ANT_COEX_ALGO_PANEDR_HID = 0x8,
+ BT_8822B_1ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9,
+ BT_8822B_1ANT_COEX_ALGO_HID_A2DP = 0xa,
+ BT_8822B_1ANT_COEX_ALGO_MAX = 0xb,
+};
+
+enum bt_8822b_1ant_ext_ant_switch_type {
+ BT_8822B_1ANT_EXT_ANT_SWITCH_USE_SPDT = 0x0,
+ BT_8822B_1ANT_EXT_ANT_SWITCH_USE_SP3T = 0x1,
+ BT_8822B_1ANT_EXT_ANT_SWITCH_MAX
+};
+
+enum bt_8822b_1ant_ext_ant_switch_ctrl_type {
+ BT_8822B_1ANT_EXT_ANT_SWITCH_CTRL_BY_BBSW = 0x0,
+ BT_8822B_1ANT_EXT_ANT_SWITCH_CTRL_BY_PTA = 0x1,
+ BT_8822B_1ANT_EXT_ANT_SWITCH_CTRL_BY_ANTDIV = 0x2,
+ BT_8822B_1ANT_EXT_ANT_SWITCH_CTRL_BY_MAC = 0x3,
+ BT_8822B_1ANT_EXT_ANT_SWITCH_CTRL_BY_BT = 0x4,
+ BT_8822B_1ANT_EXT_ANT_SWITCH_CTRL_MAX
+};
+
+enum bt_8822b_1ant_ext_ant_switch_pos_type {
+ BT_8822B_1ANT_EXT_ANT_SWITCH_TO_BT = 0x0,
+ BT_8822B_1ANT_EXT_ANT_SWITCH_TO_WLG = 0x1,
+ BT_8822B_1ANT_EXT_ANT_SWITCH_TO_WLA = 0x2,
+ BT_8822B_1ANT_EXT_ANT_SWITCH_TO_NOCARE = 0x3,
+ BT_8822B_1ANT_EXT_ANT_SWITCH_TO_MAX
+};
+
+enum bt_8822b_1ant_phase {
+ BT_8822B_1ANT_PHASE_COEX_INIT = 0x0,
+ BT_8822B_1ANT_PHASE_WLANONLY_INIT = 0x1,
+ BT_8822B_1ANT_PHASE_WLAN_OFF = 0x2,
+ BT_8822B_1ANT_PHASE_2G_RUNTIME = 0x3,
+ BT_8822B_1ANT_PHASE_5G_RUNTIME = 0x4,
+ BT_8822B_1ANT_PHASE_BTMPMODE = 0x5,
+ BT_8822B_1ANT_PHASE_MAX
+};
+
+/*ADD SCOREBOARD TO FIX BT LPS 32K ISSUE WHILE WL BUSY*/
+enum bt_8822b_1ant_scoreboard {
+ BT_8822B_1ANT_SCOREBOARD_ACTIVE = BIT(0),
+ BT_8822B_1ANT_SCOREBOARD_ONOFF = BIT(1),
+ BT_8822B_1ANT_SCOREBOARD_SCAN = BIT(2),
+ BT_8822B_1ANT_SCOREBOARD_UNDERTEST = BIT(3),
+ BT_8822B_1ANT_SCOREBOARD_WLBUSY = BIT(6)
+};
+
+struct coex_dm_8822b_1ant {
+ /* hw setting */
+ u32 pre_ant_pos_type;
+ u32 cur_ant_pos_type;
+ /* fw mechanism */
+ bool cur_ignore_wlan_act;
+ bool pre_ignore_wlan_act;
+ u8 pre_ps_tdma;
+ u8 cur_ps_tdma;
+ u8 ps_tdma_para[5];
+ u8 ps_tdma_du_adj_type;
+ bool auto_tdma_adjust;
+ bool pre_ps_tdma_on;
+ bool cur_ps_tdma_on;
+ bool pre_bt_auto_report;
+ bool cur_bt_auto_report;
+ u8 pre_lps;
+ u8 cur_lps;
+ u8 pre_rpwm;
+ u8 cur_rpwm;
+
+ /* sw mechanism */
+ bool pre_low_penalty_ra;
+ bool cur_low_penalty_ra;
+ u32 pre_val0x6c0;
+ u32 cur_val0x6c0;
+ u32 pre_val0x6c4;
+ u32 cur_val0x6c4;
+ u32 pre_val0x6c8;
+ u32 cur_val0x6c8;
+ u8 pre_val0x6cc;
+ u8 cur_val0x6cc;
+ bool limited_dig;
+
+ u32 backup_arfr_cnt1; /* Auto Rate Fallback Retry cnt */
+ u32 backup_arfr_cnt2; /* Auto Rate Fallback Retry cnt */
+ u16 backup_retry_limit;
+ u8 backup_ampdu_max_time;
+
+ /* algorithm related */
+ u8 pre_algorithm;
+ u8 cur_algorithm;
+ u8 bt_status;
+ u8 wifi_chnl_info[3];
+
+ u32 pre_ra_mask;
+ u32 cur_ra_mask;
+ u8 pre_arfr_type;
+ u8 cur_arfr_type;
+ u8 pre_retry_limit_type;
+ u8 cur_retry_limit_type;
+ u8 pre_ampdu_time_type;
+ u8 cur_ampdu_time_type;
+ u32 arp_cnt;
+
+ u32 pre_ext_ant_switch_status;
+ u32 cur_ext_ant_switch_status;
+
+ u8 error_condition;
+};
+
+struct coex_sta_8822b_1ant {
+ bool bt_disabled;
+ bool bt_link_exist;
+ bool sco_exist;
+ bool a2dp_exist;
+ bool hid_exist;
+ bool pan_exist;
+ u8 num_of_profile;
+
+ bool under_lps;
+ bool under_ips;
+ u32 specific_pkt_period_cnt;
+ u32 high_priority_tx;
+ u32 high_priority_rx;
+ u32 low_priority_tx;
+ u32 low_priority_rx;
+ bool is_hi_pri_rx_overhead;
+ s8 bt_rssi;
+ u8 pre_bt_rssi_state;
+ u8 pre_wifi_rssi_state[4];
+ u8 bt_info_c2h[BT_INFO_SRC_8822B_1ANT_MAX][10];
+ u32 bt_info_c2h_cnt[BT_INFO_SRC_8822B_1ANT_MAX];
+ bool bt_whck_test;
+ bool c2h_bt_inquiry_page;
+ bool c2h_bt_remote_name_req;
+ bool c2h_bt_page; /* Add for win8.1 page out issue */
+ bool wifi_is_high_pri_task; /* Add for win8.1 page out issue */
+
+ u8 bt_info_ext;
+ u8 bt_info_ext2;
+ u32 pop_event_cnt;
+ u8 scan_ap_num;
+ u8 bt_retry_cnt;
+
+ u32 crc_ok_cck;
+ u32 crc_ok_11g;
+ u32 crc_ok_11n;
+ u32 crc_ok_11n_vht;
+
+ u32 crc_err_cck;
+ u32 crc_err_11g;
+ u32 crc_err_11n;
+ u32 crc_err_11n_vht;
+
+ bool cck_lock;
+ bool pre_ccklock;
+ bool cck_ever_lock;
+ u8 coex_table_type;
+
+ bool force_lps_ctrl;
+
+ bool concurrent_rx_mode_on;
+
+ u16 score_board;
+ u8 isolation_btween_wb; /* 0~ 50 */
+
+ u8 a2dp_bit_pool;
+ u8 cut_version;
+ bool acl_busy;
+ bool bt_create_connection;
+
+ u32 bt_coex_supported_feature;
+ u32 bt_coex_supported_version;
+
+ u8 bt_ble_scan_type;
+ u32 bt_ble_scan_para[3];
+
+ bool run_time_state;
+ bool freeze_coexrun_by_btinfo;
+
+ bool is_A2DP_3M;
+ bool voice_over_HOGP;
+ u8 bt_info;
+ bool is_autoslot;
+ u8 forbidden_slot;
+ u8 hid_busy_num;
+ u8 hid_pair_cnt;
+
+ u32 cnt_remote_name_req;
+ u32 cnt_setup_link;
+ u32 cnt_reinit;
+ u32 cnt_ign_wlan_act;
+ u32 cnt_page;
+ u32 cnt_role_switch;
+
+ u16 bt_reg_vendor_ac;
+ u16 bt_reg_vendor_ae;
+
+ bool is_setup_link;
+ u8 wl_noisy_level;
+ u32 gnt_error_cnt;
+ u8 bt_afh_map[10];
+ u8 bt_relink_downcount;
+ bool is_tdma_btautoslot;
+ bool is_tdma_btautoslot_hang;
+
+ u8 switch_band_notify_to;
+ bool is_rf_state_off;
+
+ bool is_hid_low_pri_tx_overhead;
+ bool is_bt_multi_link;
+ bool is_bt_a2dp_sink;
+ bool rf4ce_enabled;
+
+ bool is_set_ps_state_fail;
+ u8 cnt_set_ps_state_fail;
+};
+
+struct rfe_type_8822b_1ant {
+ u8 rfe_module_type;
+ bool ext_ant_switch_exist;
+ u8 ext_ant_switch_type;
+ /* iF 0: ANTSW(rfe_sel9)=0, ANTSWB(rfe_sel8)=1 => Ant to BT/5G */
+ u8 ext_ant_switch_ctrl_polarity;
+};
+
+#define BT_8822B_1ANT_ANTDET_PSD_POINTS 256 /* MAX:1024 */
+#define BT_8822B_1ANT_ANTDET_PSD_AVGNUM 1 /* MAX:3 */
+#define BT_8822B_1ANT_ANTDET_BUF_LEN 16
+
+struct psdscan_sta_8822b_1ant {
+ u32 ant_det_bt_le_channel; /* BT LE Channel ex:2412 */
+ u32 ant_det_bt_tx_time;
+ u32 ant_det_pre_psdscan_peak_val;
+ bool ant_det_is_ant_det_available;
+ u32 ant_det_psd_scan_peak_val;
+ bool ant_det_is_btreply_available;
+ u32 ant_det_psd_scan_peak_freq;
+
+ u8 ant_det_result;
+ u8 ant_det_peak_val[BT_8822B_1ANT_ANTDET_BUF_LEN];
+ u8 ant_det_peak_freq[BT_8822B_1ANT_ANTDET_BUF_LEN];
+ u32 ant_det_try_count;
+ u32 ant_det_fail_count;
+ u32 ant_det_inteval_count;
+ u32 ant_det_thres_offset;
+
+ u32 real_cent_freq;
+ s32 real_offset;
+ u32 real_span;
+
+ u32 psd_band_width; /* unit: Hz */
+ u32 psd_point; /* 128/256/512/1024 */
+ u32 psd_report[1024]; /* unit:dB (20logx), 0~255 */
+ u32 psd_report_max_hold[1024]; /* unit:dB (20logx), 0~255 */
+ u32 psd_start_point;
+ u32 psd_stop_point;
+ u32 psd_max_value_point;
+ u32 psd_max_value;
+ u32 psd_start_base;
+ u32 psd_avg_num; /* 1/8/16/32 */
+ u32 psd_gen_count;
+ bool is_psd_running;
+ bool is_psd_show_max_only;
+ bool is_ant_det_running;
+};
+
+/* *******************************************
+ * The following is interface which will notify coex module.
+ * ********************************************/
+void ex_btc8822b1ant_power_on_setting(struct btc_coexist *btcoexist);
+void ex_btc8822b1ant_pre_load_firmware(struct btc_coexist *btcoexist);
+void ex_btc8822b1ant_init_hw_config(struct btc_coexist *btcoexist,
+ bool wifi_only);
+void ex_btc8822b1ant_init_coex_dm(struct btc_coexist *btcoexist);
+void ex_btc8822b1ant_ips_notify(struct btc_coexist *btcoexist, u8 type);
+void ex_btc8822b1ant_lps_notify(struct btc_coexist *btcoexist, u8 type);
+void ex_btc8822b1ant_scan_notify(struct btc_coexist *btcoexist, u8 type);
+void ex_btc8822b1ant_scan_notify_without_bt(struct btc_coexist *btcoexist,
+ u8 type);
+void ex_btc8822b1ant_switchband_notify(struct btc_coexist *btcoexist, u8 type);
+void ex_btc8822b1ant_switchband_notify_without_bt(struct btc_coexist *btcoexist,
+ u8 type);
+void ex_btc8822b1ant_connect_notify(struct btc_coexist *btcoexist, u8 type);
+void ex_btc8822b1ant_media_status_notify(struct btc_coexist *btcoexist,
+ u8 type);
+void ex_btc8822b1ant_specific_packet_notify(struct btc_coexist *btcoexist,
+ u8 type);
+void ex_btc8822b1ant_bt_info_notify(struct btc_coexist *btcoexist, u8 *tmp_buf,
+ u8 length);
+void ex_btc8822b1ant_rf_status_notify(struct btc_coexist *btcoexist, u8 type);
+void ex_btc8822b1ant_halt_notify(struct btc_coexist *btcoexist);
+void ex_btc8822b1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state);
+void ex_halbtc8822b1ant_score_board_status_notify(struct btc_coexist *btcoexist,
+ u8 *tmp_buf, u8 length);
+void ex_btc8822b1ant_coex_dm_reset(struct btc_coexist *btcoexist);
+void ex_btc8822b1ant_periodical(struct btc_coexist *btcoexist);
+void ex_btc8822b1ant_display_coex_info(struct btc_coexist *btcoexist,
+ struct seq_file *m);
+void ex_btc8822b1ant_antenna_detection(struct btc_coexist *btcoexist,
+ u32 cent_freq, u32 offset, u32 span,
+ u32 seconds);
+void ex_btc8822b1ant_antenna_isolation(struct btc_coexist *btcoexist,
+ u32 cent_freq, u32 offset, u32 span,
+ u32 seconds);
+
+void ex_btc8822b1ant_psd_scan(struct btc_coexist *btcoexist, u32 cent_freq,
+ u32 offset, u32 span, u32 seconds);
+void ex_btc8822b1ant_display_ant_detection(struct btc_coexist *btcoexist);
+
+void ex_btc8822b1ant_dbg_control(struct btc_coexist *btcoexist, u8 op_code,
+ u8 op_len, u8 *pdata);
diff --git a/drivers/staging/rtlwifi/btcoexist/halbtc8822b2ant.c b/drivers/staging/rtlwifi/btcoexist/halbtc8822b2ant.c
new file mode 100644
index 0000000..ffff5b0
--- /dev/null
+++ b/drivers/staging/rtlwifi/btcoexist/halbtc8822b2ant.c
@@ -0,0 +1,5225 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+/* ************************************************************
+ * Description:
+ *
+ * This file is for RTL8822B Co-exist mechanism
+ *
+ * History
+ * 2012/11/15 Cosa first check in.
+ *
+ * *************************************************************/
+
+/* ************************************************************
+ * include files
+ * *************************************************************/
+#include "halbt_precomp.h"
+
+/* ************************************************************
+ * Global variables, these are static variables
+ * *************************************************************/
+static struct coex_dm_8822b_2ant glcoex_dm_8822b_2ant;
+static struct coex_dm_8822b_2ant *coex_dm = &glcoex_dm_8822b_2ant;
+static struct coex_sta_8822b_2ant glcoex_sta_8822b_2ant;
+static struct coex_sta_8822b_2ant *coex_sta = &glcoex_sta_8822b_2ant;
+static struct psdscan_sta_8822b_2ant gl_psd_scan_8822b_2ant;
+static struct psdscan_sta_8822b_2ant *psd_scan = &gl_psd_scan_8822b_2ant;
+static struct rfe_type_8822b_2ant gl_rfe_type_8822b_2ant;
+static struct rfe_type_8822b_2ant *rfe_type = &gl_rfe_type_8822b_2ant;
+
+static const char *const glbt_info_src_8822b_2ant[] = {
+ "BT Info[wifi fw]", "BT Info[bt rsp]", "BT Info[bt auto report]",
+};
+
+static u32 glcoex_ver_date_8822b_2ant = 20170327;
+static u32 glcoex_ver_8822b_2ant = 0x44;
+static u32 glcoex_ver_btdesired_8822b_2ant = 0x42;
+
+/* ************************************************************
+ * local function proto type if needed
+ * ************************************************************
+ * ************************************************************
+ * local function start with halbtc8822b2ant_
+ * *************************************************************/
+static u8 halbtc8822b2ant_bt_rssi_state(struct btc_coexist *btcoexist,
+ u8 *ppre_bt_rssi_state, u8 level_num,
+ u8 rssi_thresh, u8 rssi_thresh1)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ s32 bt_rssi = 0;
+ u8 bt_rssi_state = *ppre_bt_rssi_state;
+
+ bt_rssi = coex_sta->bt_rssi;
+
+ if (level_num == 2) {
+ if ((*ppre_bt_rssi_state == BTC_RSSI_STATE_LOW) ||
+ (*ppre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
+ if (bt_rssi >=
+ (rssi_thresh + BTC_RSSI_COEX_THRESH_TOL_8822B_2ANT))
+ bt_rssi_state = BTC_RSSI_STATE_HIGH;
+ else
+ bt_rssi_state = BTC_RSSI_STATE_STAY_LOW;
+ } else {
+ if (bt_rssi < rssi_thresh)
+ bt_rssi_state = BTC_RSSI_STATE_LOW;
+ else
+ bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
+ }
+ } else if (level_num == 3) {
+ if (rssi_thresh > rssi_thresh1) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT Rssi thresh error!!\n");
+ return *ppre_bt_rssi_state;
+ }
+
+ if ((*ppre_bt_rssi_state == BTC_RSSI_STATE_LOW) ||
+ (*ppre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
+ if (bt_rssi >=
+ (rssi_thresh + BTC_RSSI_COEX_THRESH_TOL_8822B_2ANT))
+ bt_rssi_state = BTC_RSSI_STATE_MEDIUM;
+ else
+ bt_rssi_state = BTC_RSSI_STATE_STAY_LOW;
+ } else if ((*ppre_bt_rssi_state == BTC_RSSI_STATE_MEDIUM) ||
+ (*ppre_bt_rssi_state ==
+ BTC_RSSI_STATE_STAY_MEDIUM)) {
+ if (bt_rssi >= (rssi_thresh1 +
+ BTC_RSSI_COEX_THRESH_TOL_8822B_2ANT))
+ bt_rssi_state = BTC_RSSI_STATE_HIGH;
+ else if (bt_rssi < rssi_thresh)
+ bt_rssi_state = BTC_RSSI_STATE_LOW;
+ else
+ bt_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM;
+ } else {
+ if (bt_rssi < rssi_thresh1)
+ bt_rssi_state = BTC_RSSI_STATE_MEDIUM;
+ else
+ bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
+ }
+ }
+
+ *ppre_bt_rssi_state = bt_rssi_state;
+
+ return bt_rssi_state;
+}
+
+static u8 halbtc8822b2ant_wifi_rssi_state(struct btc_coexist *btcoexist,
+ u8 *pprewifi_rssi_state, u8 level_num,
+ u8 rssi_thresh, u8 rssi_thresh1)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ s32 wifi_rssi = 0;
+ u8 wifi_rssi_state = *pprewifi_rssi_state;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
+
+ if (level_num == 2) {
+ if ((*pprewifi_rssi_state == BTC_RSSI_STATE_LOW) ||
+ (*pprewifi_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
+ if (wifi_rssi >=
+ (rssi_thresh + BTC_RSSI_COEX_THRESH_TOL_8822B_2ANT))
+ wifi_rssi_state = BTC_RSSI_STATE_HIGH;
+ else
+ wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW;
+ } else {
+ if (wifi_rssi < rssi_thresh)
+ wifi_rssi_state = BTC_RSSI_STATE_LOW;
+ else
+ wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
+ }
+ } else if (level_num == 3) {
+ if (rssi_thresh > rssi_thresh1) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], wifi RSSI thresh error!!\n");
+ return *pprewifi_rssi_state;
+ }
+
+ if ((*pprewifi_rssi_state == BTC_RSSI_STATE_LOW) ||
+ (*pprewifi_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
+ if (wifi_rssi >=
+ (rssi_thresh + BTC_RSSI_COEX_THRESH_TOL_8822B_2ANT))
+ wifi_rssi_state = BTC_RSSI_STATE_MEDIUM;
+ else
+ wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW;
+ } else if ((*pprewifi_rssi_state == BTC_RSSI_STATE_MEDIUM) ||
+ (*pprewifi_rssi_state ==
+ BTC_RSSI_STATE_STAY_MEDIUM)) {
+ if (wifi_rssi >= (rssi_thresh1 +
+ BTC_RSSI_COEX_THRESH_TOL_8822B_2ANT))
+ wifi_rssi_state = BTC_RSSI_STATE_HIGH;
+ else if (wifi_rssi < rssi_thresh)
+ wifi_rssi_state = BTC_RSSI_STATE_LOW;
+ else
+ wifi_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM;
+ } else {
+ if (wifi_rssi < rssi_thresh1)
+ wifi_rssi_state = BTC_RSSI_STATE_MEDIUM;
+ else
+ wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
+ }
+ }
+
+ *pprewifi_rssi_state = wifi_rssi_state;
+
+ return wifi_rssi_state;
+}
+
+static void halbtc8822b2ant_coex_switch_threshold(struct btc_coexist *btcoexist,
+ u8 isolation_measuared)
+{
+ s8 interference_wl_tx = 0, interference_bt_tx = 0;
+
+ interference_wl_tx =
+ BT_8822B_2ANT_WIFI_MAX_TX_POWER - isolation_measuared;
+ interference_bt_tx =
+ BT_8822B_2ANT_BT_MAX_TX_POWER - isolation_measuared;
+
+ coex_sta->wifi_coex_thres = BT_8822B_2ANT_WIFI_RSSI_COEXSWITCH_THRES1;
+ coex_sta->wifi_coex_thres2 = BT_8822B_2ANT_WIFI_RSSI_COEXSWITCH_THRES2;
+
+ coex_sta->bt_coex_thres = BT_8822B_2ANT_BT_RSSI_COEXSWITCH_THRES1;
+ coex_sta->bt_coex_thres2 = BT_8822B_2ANT_BT_RSSI_COEXSWITCH_THRES2;
+}
+
+static void halbtc8822b2ant_query_bt_info(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ u8 h2c_parameter[1] = {0};
+
+ if (coex_sta->bt_disabled) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], No query BT info because BT is disabled!\n");
+ return;
+ }
+
+ h2c_parameter[0] |= BIT(0); /* trigger */
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter);
+}
+
+static void halbtc8822b2ant_monitor_bt_ctr(struct btc_coexist *btcoexist)
+{
+ u32 reg_hp_txrx, reg_lp_txrx, u32tmp;
+ u32 reg_hp_tx = 0, reg_hp_rx = 0, reg_lp_tx = 0, reg_lp_rx = 0;
+ static u8 num_of_bt_counter_chk, cnt_slave, cnt_autoslot_hang;
+
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+
+ reg_hp_txrx = 0x770;
+ reg_lp_txrx = 0x774;
+
+ u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_hp_txrx);
+ reg_hp_tx = u32tmp & MASKLWORD;
+ reg_hp_rx = (u32tmp & MASKHWORD) >> 16;
+
+ u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_lp_txrx);
+ reg_lp_tx = u32tmp & MASKLWORD;
+ reg_lp_rx = (u32tmp & MASKHWORD) >> 16;
+
+ coex_sta->high_priority_tx = reg_hp_tx;
+ coex_sta->high_priority_rx = reg_hp_rx;
+ coex_sta->low_priority_tx = reg_lp_tx;
+ coex_sta->low_priority_rx = reg_lp_rx;
+
+ /* reset counter */
+ btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc);
+
+ if ((coex_sta->low_priority_tx > 1050) &&
+ (!coex_sta->c2h_bt_inquiry_page))
+ coex_sta->pop_event_cnt++;
+
+ if ((coex_sta->low_priority_rx >= 950) &&
+ (coex_sta->low_priority_rx >= coex_sta->low_priority_tx) &&
+ (!coex_sta->under_ips) && (!coex_sta->c2h_bt_inquiry_page) &&
+ (coex_sta->bt_link_exist)) {
+ if (cnt_slave >= 2) {
+ bt_link_info->slave_role = true;
+ cnt_slave = 2;
+ } else {
+ cnt_slave++;
+ }
+ } else {
+ if (cnt_slave == 0) {
+ bt_link_info->slave_role = false;
+ cnt_slave = 0;
+ } else {
+ cnt_slave--;
+ }
+ }
+
+ if (coex_sta->is_tdma_btautoslot) {
+ if ((coex_sta->low_priority_tx >= 1300) &&
+ (coex_sta->low_priority_rx <= 150)) {
+ if (cnt_autoslot_hang >= 2) {
+ coex_sta->is_tdma_btautoslot_hang = true;
+ cnt_autoslot_hang = 2;
+ } else {
+ cnt_autoslot_hang++;
+ }
+ } else {
+ if (cnt_autoslot_hang == 0) {
+ coex_sta->is_tdma_btautoslot_hang = false;
+ cnt_autoslot_hang = 0;
+ } else {
+ cnt_autoslot_hang--;
+ }
+ }
+ }
+
+ if (coex_sta->sco_exist) {
+ if ((coex_sta->high_priority_tx >= 400) &&
+ (coex_sta->high_priority_rx >= 400))
+ coex_sta->is_esco_mode = false;
+ else
+ coex_sta->is_esco_mode = true;
+ }
+
+ if (bt_link_info->hid_only) {
+ if (coex_sta->low_priority_rx > 50)
+ coex_sta->is_hid_low_pri_tx_overhead = true;
+ else
+ coex_sta->is_hid_low_pri_tx_overhead = false;
+ }
+
+ if ((coex_sta->high_priority_tx == 0) &&
+ (coex_sta->high_priority_rx == 0) &&
+ (coex_sta->low_priority_tx == 0) &&
+ (coex_sta->low_priority_rx == 0)) {
+ num_of_bt_counter_chk++;
+ if (num_of_bt_counter_chk >= 3) {
+ halbtc8822b2ant_query_bt_info(btcoexist);
+ num_of_bt_counter_chk = 0;
+ }
+ }
+}
+
+static void halbtc8822b2ant_monitor_wifi_ctr(struct btc_coexist *btcoexist)
+{
+ s32 wifi_rssi = 0;
+ bool wifi_busy = false, wifi_under_b_mode = false, wifi_scan = false;
+ bool bt_idle = false;
+ static u8 cck_lock_counter, wl_noisy_count0, wl_noisy_count1 = 3,
+ wl_noisy_count2;
+ u32 total_cnt, cck_cnt;
+ u32 cnt_crcok = 0, cnt_crcerr = 0;
+ static u8 cnt;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+ btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_B_MODE,
+ &wifi_under_b_mode);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &wifi_scan);
+
+ coex_sta->crc_ok_cck = btcoexist->btc_phydm_query_phy_counter(
+ btcoexist, "PHYDM_INFO_CRC32_OK_CCK");
+ coex_sta->crc_ok_11g = btcoexist->btc_phydm_query_phy_counter(
+ btcoexist, "PHYDM_INFO_CRC32_OK_LEGACY");
+ coex_sta->crc_ok_11n = btcoexist->btc_phydm_query_phy_counter(
+ btcoexist, "PHYDM_INFO_CRC32_OK_HT");
+ coex_sta->crc_ok_11n_vht = btcoexist->btc_phydm_query_phy_counter(
+ btcoexist, "PHYDM_INFO_CRC32_OK_VHT");
+
+ coex_sta->crc_err_cck = btcoexist->btc_phydm_query_phy_counter(
+ btcoexist, "PHYDM_INFO_CRC32_ERROR_CCK");
+ coex_sta->crc_err_11g = btcoexist->btc_phydm_query_phy_counter(
+ btcoexist, "PHYDM_INFO_CRC32_ERROR_LEGACY");
+ coex_sta->crc_err_11n = btcoexist->btc_phydm_query_phy_counter(
+ btcoexist, "PHYDM_INFO_CRC32_ERROR_HT");
+ coex_sta->crc_err_11n_vht = btcoexist->btc_phydm_query_phy_counter(
+ btcoexist, "PHYDM_INFO_CRC32_ERROR_VHT");
+
+ cnt_crcok = coex_sta->crc_ok_cck + coex_sta->crc_ok_11g +
+ coex_sta->crc_ok_11n + coex_sta->crc_ok_11n_vht;
+
+ cnt_crcerr = coex_sta->crc_err_cck + coex_sta->crc_err_11g +
+ coex_sta->crc_err_11n + coex_sta->crc_err_11n_vht;
+
+ if ((wifi_busy) && (cnt_crcerr != 0)) {
+ coex_sta->now_crc_ratio = cnt_crcok / cnt_crcerr;
+
+ if (cnt == 0)
+ coex_sta->acc_crc_ratio = coex_sta->now_crc_ratio;
+ else
+ coex_sta->acc_crc_ratio =
+ (coex_sta->acc_crc_ratio * 7 +
+ coex_sta->now_crc_ratio * 3) /
+ 10;
+
+ if (cnt >= 10)
+ cnt = 0;
+ else
+ cnt++;
+ }
+
+ cck_cnt = coex_sta->crc_ok_cck + coex_sta->crc_err_cck;
+
+ if ((coex_dm->bt_status ==
+ BT_8822B_2ANT_BT_STATUS_NON_CONNECTED_IDLE) ||
+ (coex_dm->bt_status == BT_8822B_2ANT_BT_STATUS_CONNECTED_IDLE) ||
+ (coex_sta->bt_disabled))
+ bt_idle = true;
+
+ if (cck_cnt > 250) {
+ if (wl_noisy_count2 < 3)
+ wl_noisy_count2++;
+
+ if (wl_noisy_count2 == 3) {
+ wl_noisy_count0 = 0;
+ wl_noisy_count1 = 0;
+ }
+
+ } else if (cck_cnt < 50) {
+ if (wl_noisy_count0 < 3)
+ wl_noisy_count0++;
+
+ if (wl_noisy_count0 == 3) {
+ wl_noisy_count1 = 0;
+ wl_noisy_count2 = 0;
+ }
+
+ } else {
+ if (wl_noisy_count1 < 3)
+ wl_noisy_count1++;
+
+ if (wl_noisy_count1 == 3) {
+ wl_noisy_count0 = 0;
+ wl_noisy_count2 = 0;
+ }
+ }
+
+ if (wl_noisy_count2 == 3)
+ coex_sta->wl_noisy_level = 2;
+ else if (wl_noisy_count1 == 3)
+ coex_sta->wl_noisy_level = 1;
+ else
+ coex_sta->wl_noisy_level = 0;
+
+ if ((wifi_busy) && (wifi_rssi >= 30) && (!wifi_under_b_mode)) {
+ total_cnt = cnt_crcok;
+
+ if ((coex_dm->bt_status == BT_8822B_1ANT_BT_STATUS_ACL_BUSY) ||
+ (coex_dm->bt_status ==
+ BT_8822B_1ANT_BT_STATUS_ACL_SCO_BUSY) ||
+ (coex_dm->bt_status == BT_8822B_1ANT_BT_STATUS_SCO_BUSY)) {
+ if (coex_sta->crc_ok_cck >
+ (total_cnt - coex_sta->crc_ok_cck)) {
+ if (cck_lock_counter < 3)
+ cck_lock_counter++;
+ } else {
+ if (cck_lock_counter > 0)
+ cck_lock_counter--;
+ }
+
+ } else {
+ if (cck_lock_counter > 0)
+ cck_lock_counter--;
+ }
+ } else {
+ if (cck_lock_counter > 0)
+ cck_lock_counter--;
+ }
+
+ if (!coex_sta->pre_ccklock) {
+ if (cck_lock_counter >= 3)
+ coex_sta->cck_lock = true;
+ else
+ coex_sta->cck_lock = false;
+ } else {
+ if (cck_lock_counter == 0)
+ coex_sta->cck_lock = false;
+ else
+ coex_sta->cck_lock = true;
+ }
+
+ if (coex_sta->cck_lock)
+ coex_sta->cck_ever_lock = true;
+
+ coex_sta->pre_ccklock = coex_sta->cck_lock;
+}
+
+static bool
+halbtc8822b2ant_is_wifibt_status_changed(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ static bool pre_wifi_busy, pre_under_4way, pre_bt_hs_on, pre_bt_off,
+ pre_bt_slave, pre_hid_low_pri_tx_overhead, pre_wifi_under_lps,
+ pre_bt_setup_link;
+ static u8 pre_hid_busy_num, pre_wl_noisy_level;
+ bool wifi_busy = false, under_4way = false, bt_hs_on = false;
+ bool wifi_connected = false;
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
+ &wifi_connected);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS,
+ &under_4way);
+
+ if (coex_sta->bt_disabled != pre_bt_off) {
+ pre_bt_off = coex_sta->bt_disabled;
+
+ if (coex_sta->bt_disabled)
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT is disabled !!\n");
+ else
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT is enabled !!\n");
+
+ coex_sta->bt_coex_supported_feature = 0;
+ coex_sta->bt_coex_supported_version = 0;
+ coex_sta->bt_ble_scan_type = 0;
+ coex_sta->bt_ble_scan_para[0] = 0;
+ coex_sta->bt_ble_scan_para[1] = 0;
+ coex_sta->bt_ble_scan_para[2] = 0;
+ coex_sta->bt_reg_vendor_ac = 0xffff;
+ coex_sta->bt_reg_vendor_ae = 0xffff;
+ return true;
+ }
+
+ if (wifi_connected) {
+ if (wifi_busy != pre_wifi_busy) {
+ pre_wifi_busy = wifi_busy;
+ return true;
+ }
+ if (under_4way != pre_under_4way) {
+ pre_under_4way = under_4way;
+ return true;
+ }
+ if (bt_hs_on != pre_bt_hs_on) {
+ pre_bt_hs_on = bt_hs_on;
+ return true;
+ }
+ if (coex_sta->wl_noisy_level != pre_wl_noisy_level) {
+ pre_wl_noisy_level = coex_sta->wl_noisy_level;
+ return true;
+ }
+ if (coex_sta->under_lps != pre_wifi_under_lps) {
+ pre_wifi_under_lps = coex_sta->under_lps;
+ if (coex_sta->under_lps)
+ return true;
+ }
+ }
+
+ if (!coex_sta->bt_disabled) {
+ if (coex_sta->hid_busy_num != pre_hid_busy_num) {
+ pre_hid_busy_num = coex_sta->hid_busy_num;
+ return true;
+ }
+
+ if (bt_link_info->slave_role != pre_bt_slave) {
+ pre_bt_slave = bt_link_info->slave_role;
+ return true;
+ }
+
+ if (pre_hid_low_pri_tx_overhead !=
+ coex_sta->is_hid_low_pri_tx_overhead) {
+ pre_hid_low_pri_tx_overhead =
+ coex_sta->is_hid_low_pri_tx_overhead;
+ return true;
+ }
+
+ if (pre_bt_setup_link != coex_sta->is_setup_link) {
+ pre_bt_setup_link = coex_sta->is_setup_link;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static void halbtc8822b2ant_update_bt_link_info(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+ bool bt_hs_on = false;
+ bool bt_busy = false;
+
+ coex_sta->num_of_profile = 0;
+
+ /* set link exist status */
+ if (!(coex_sta->bt_info & BT_INFO_8822B_1ANT_B_CONNECTION)) {
+ coex_sta->bt_link_exist = false;
+ coex_sta->pan_exist = false;
+ coex_sta->a2dp_exist = false;
+ coex_sta->hid_exist = false;
+ coex_sta->sco_exist = false;
+ } else { /* connection exists */
+ coex_sta->bt_link_exist = true;
+ if (coex_sta->bt_info & BT_INFO_8822B_1ANT_B_FTP) {
+ coex_sta->pan_exist = true;
+ coex_sta->num_of_profile++;
+ } else {
+ coex_sta->pan_exist = false;
+ }
+
+ if (coex_sta->bt_info & BT_INFO_8822B_1ANT_B_A2DP) {
+ coex_sta->a2dp_exist = true;
+ coex_sta->num_of_profile++;
+ } else {
+ coex_sta->a2dp_exist = false;
+ }
+
+ if (coex_sta->bt_info & BT_INFO_8822B_1ANT_B_HID) {
+ coex_sta->hid_exist = true;
+ coex_sta->num_of_profile++;
+ } else {
+ coex_sta->hid_exist = false;
+ }
+
+ if (coex_sta->bt_info & BT_INFO_8822B_1ANT_B_SCO_ESCO) {
+ coex_sta->sco_exist = true;
+ coex_sta->num_of_profile++;
+ } else {
+ coex_sta->sco_exist = false;
+ }
+ }
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+
+ bt_link_info->bt_link_exist = coex_sta->bt_link_exist;
+ bt_link_info->sco_exist = coex_sta->sco_exist;
+ bt_link_info->a2dp_exist = coex_sta->a2dp_exist;
+ bt_link_info->pan_exist = coex_sta->pan_exist;
+ bt_link_info->hid_exist = coex_sta->hid_exist;
+ bt_link_info->acl_busy = coex_sta->acl_busy;
+
+ /* work around for HS mode. */
+ if (bt_hs_on) {
+ bt_link_info->pan_exist = true;
+ bt_link_info->bt_link_exist = true;
+ }
+
+ /* check if Sco only */
+ if (bt_link_info->sco_exist && !bt_link_info->a2dp_exist &&
+ !bt_link_info->pan_exist && !bt_link_info->hid_exist)
+ bt_link_info->sco_only = true;
+ else
+ bt_link_info->sco_only = false;
+
+ /* check if A2dp only */
+ if (!bt_link_info->sco_exist && bt_link_info->a2dp_exist &&
+ !bt_link_info->pan_exist && !bt_link_info->hid_exist)
+ bt_link_info->a2dp_only = true;
+ else
+ bt_link_info->a2dp_only = false;
+
+ /* check if Pan only */
+ if (!bt_link_info->sco_exist && !bt_link_info->a2dp_exist &&
+ bt_link_info->pan_exist && !bt_link_info->hid_exist)
+ bt_link_info->pan_only = true;
+ else
+ bt_link_info->pan_only = false;
+
+ /* check if Hid only */
+ if (!bt_link_info->sco_exist && !bt_link_info->a2dp_exist &&
+ !bt_link_info->pan_exist && bt_link_info->hid_exist)
+ bt_link_info->hid_only = true;
+ else
+ bt_link_info->hid_only = false;
+
+ if (coex_sta->bt_info & BT_INFO_8822B_2ANT_B_INQ_PAGE) {
+ coex_dm->bt_status = BT_8822B_2ANT_BT_STATUS_INQ_PAGE;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BtInfoNotify(), BT Inq/page!!!\n");
+ } else if (!(coex_sta->bt_info & BT_INFO_8822B_2ANT_B_CONNECTION)) {
+ coex_dm->bt_status = BT_8822B_2ANT_BT_STATUS_NON_CONNECTED_IDLE;
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BtInfoNotify(), BT Non-Connected idle!!!\n");
+ } else if (coex_sta->bt_info == BT_INFO_8822B_2ANT_B_CONNECTION) {
+ /* connection exists but no busy */
+ coex_dm->bt_status = BT_8822B_2ANT_BT_STATUS_CONNECTED_IDLE;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n");
+ } else if (((coex_sta->bt_info & BT_INFO_8822B_2ANT_B_SCO_ESCO) ||
+ (coex_sta->bt_info & BT_INFO_8822B_2ANT_B_SCO_BUSY)) &&
+ (coex_sta->bt_info & BT_INFO_8822B_2ANT_B_ACL_BUSY)) {
+ coex_dm->bt_status = BT_8822B_2ANT_BT_STATUS_ACL_SCO_BUSY;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BtInfoNotify(), BT ACL SCO busy!!!\n");
+ } else if ((coex_sta->bt_info & BT_INFO_8822B_2ANT_B_SCO_ESCO) ||
+ (coex_sta->bt_info & BT_INFO_8822B_2ANT_B_SCO_BUSY)) {
+ coex_dm->bt_status = BT_8822B_2ANT_BT_STATUS_SCO_BUSY;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n");
+ } else if (coex_sta->bt_info & BT_INFO_8822B_2ANT_B_ACL_BUSY) {
+ coex_dm->bt_status = BT_8822B_2ANT_BT_STATUS_ACL_BUSY;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n");
+ } else {
+ coex_dm->bt_status = BT_8822B_2ANT_BT_STATUS_MAX;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BtInfoNotify(), BT Non-Defined state!!!\n");
+ }
+
+ if ((coex_dm->bt_status == BT_8822B_2ANT_BT_STATUS_ACL_BUSY) ||
+ (coex_dm->bt_status == BT_8822B_2ANT_BT_STATUS_SCO_BUSY) ||
+ (coex_dm->bt_status == BT_8822B_2ANT_BT_STATUS_ACL_SCO_BUSY))
+ bt_busy = true;
+ else
+ bt_busy = false;
+
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy);
+}
+
+static void halbtc8822b2ant_update_wifi_ch_info(struct btc_coexist *btcoexist,
+ u8 type)
+{
+ u8 h2c_parameter[3] = {0};
+ u32 wifi_bw;
+ u8 wifi_central_chnl;
+ u32 RTL97F_8822B = 0;
+
+ if (RTL97F_8822B)
+ return;
+
+ /* only 2.4G we need to inform bt the chnl mask */
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL,
+ &wifi_central_chnl);
+ if ((type == BTC_MEDIA_CONNECT) && (wifi_central_chnl <= 14)) {
+ /* enable BT AFH skip WL channel for 8822b
+ * because BT Rx LO interference
+ */
+ h2c_parameter[0] = 0x1;
+ h2c_parameter[1] = wifi_central_chnl;
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+ if (wifi_bw == BTC_WIFI_BW_HT40)
+ h2c_parameter[2] = 0x30;
+ else
+ h2c_parameter[2] = 0x20;
+ }
+
+ coex_dm->wifi_chnl_info[0] = h2c_parameter[0];
+ coex_dm->wifi_chnl_info[1] = h2c_parameter[1];
+ coex_dm->wifi_chnl_info[2] = h2c_parameter[2];
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter);
+}
+
+static void
+halbtc8822b2ant_set_fw_dac_swing_level(struct btc_coexist *btcoexist,
+ u8 dac_swing_lvl)
+{
+ u8 h2c_parameter[1] = {0};
+ u32 RTL97F_8822B = 0;
+
+ if (RTL97F_8822B)
+ return;
+
+ /* There are several type of dacswing */
+ /* 0x18/ 0x10/ 0xc/ 0x8/ 0x4/ 0x6 */
+ h2c_parameter[0] = dac_swing_lvl;
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x64, 1, h2c_parameter);
+}
+
+static void halbtc8822b2ant_fw_dac_swing_lvl(struct btc_coexist *btcoexist,
+ bool force_exec,
+ u8 fw_dac_swing_lvl)
+{
+ u32 RTL97F_8822B = 0;
+
+ if (RTL97F_8822B)
+ return;
+
+ coex_dm->cur_fw_dac_swing_lvl = fw_dac_swing_lvl;
+
+ if (!force_exec) {
+ if (coex_dm->pre_fw_dac_swing_lvl ==
+ coex_dm->cur_fw_dac_swing_lvl)
+ return;
+ }
+
+ halbtc8822b2ant_set_fw_dac_swing_level(btcoexist,
+ coex_dm->cur_fw_dac_swing_lvl);
+
+ coex_dm->pre_fw_dac_swing_lvl = coex_dm->cur_fw_dac_swing_lvl;
+}
+
+static void halbtc8822b2ant_set_fw_dec_bt_pwr(struct btc_coexist *btcoexist,
+ u8 dec_bt_pwr_lvl)
+{
+ u32 RTL97F_8822B = 0;
+ u8 h2c_parameter[1] = {0};
+
+ if (RTL97F_8822B)
+ return;
+
+ h2c_parameter[0] = dec_bt_pwr_lvl;
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x62, 1, h2c_parameter);
+}
+
+static void halbtc8822b2ant_dec_bt_pwr(struct btc_coexist *btcoexist,
+ bool force_exec, u8 dec_bt_pwr_lvl)
+{
+ coex_dm->cur_bt_dec_pwr_lvl = dec_bt_pwr_lvl;
+
+ if (!force_exec) {
+ if (coex_dm->pre_bt_dec_pwr_lvl == coex_dm->cur_bt_dec_pwr_lvl)
+ return;
+ }
+ halbtc8822b2ant_set_fw_dec_bt_pwr(btcoexist,
+ coex_dm->cur_bt_dec_pwr_lvl);
+
+ coex_dm->pre_bt_dec_pwr_lvl = coex_dm->cur_bt_dec_pwr_lvl;
+}
+
+static void halbtc8822b2ant_low_penalty_ra(struct btc_coexist *btcoexist,
+ bool force_exec, bool low_penalty_ra)
+{
+ coex_dm->cur_low_penalty_ra = low_penalty_ra;
+
+ if (!force_exec) {
+ if (coex_dm->pre_low_penalty_ra == coex_dm->cur_low_penalty_ra)
+ return;
+ }
+
+ if (low_penalty_ra)
+ btcoexist->btc_phydm_modify_ra_pcr_threshold(btcoexist, 0, 50);
+ else
+ btcoexist->btc_phydm_modify_ra_pcr_threshold(btcoexist, 0, 0);
+
+ coex_dm->pre_low_penalty_ra = coex_dm->cur_low_penalty_ra;
+}
+
+static void halbtc8822b2ant_write_score_board(struct btc_coexist *btcoexist,
+ u16 bitpos, bool state)
+{
+ static u16 originalval = 0x8002;
+
+ if (state)
+ originalval = originalval | bitpos;
+ else
+ originalval = originalval & (~bitpos);
+
+ btcoexist->btc_write_2byte(btcoexist, 0xaa, originalval);
+}
+
+static void halbtc8822b2ant_read_score_board(struct btc_coexist *btcoexist,
+ u16 *score_board_val)
+{
+ *score_board_val =
+ (btcoexist->btc_read_2byte(btcoexist, 0xaa)) & 0x7fff;
+}
+
+static void halbtc8822b2ant_post_state_to_bt(struct btc_coexist *btcoexist,
+ u16 type, bool state)
+{
+ halbtc8822b2ant_write_score_board(btcoexist, (u16)type, state);
+}
+
+static void
+halbtc8822b2ant_monitor_bt_enable_disable(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ static u32 bt_disable_cnt;
+ bool bt_active = true, bt_disabled = false, wifi_under_5g = false;
+ u16 u16tmp;
+
+ /* This function check if bt is disabled */
+
+ /* Read BT on/off status from scoreboard[1],
+ * enable this only if BT patch support this feature
+ */
+ halbtc8822b2ant_read_score_board(btcoexist, &u16tmp);
+
+ bt_active = u16tmp & BIT(1);
+
+ if (bt_active) {
+ bt_disable_cnt = 0;
+ bt_disabled = false;
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE,
+ &bt_disabled);
+ } else {
+ bt_disable_cnt++;
+ if (bt_disable_cnt >= 10) {
+ bt_disabled = true;
+ bt_disable_cnt = 10;
+ }
+
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE,
+ &bt_disabled);
+ }
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
+
+ if ((wifi_under_5g) || (bt_disabled))
+ halbtc8822b2ant_low_penalty_ra(btcoexist, NORMAL_EXEC, false);
+ else
+ halbtc8822b2ant_low_penalty_ra(btcoexist, NORMAL_EXEC, true);
+
+ if (coex_sta->bt_disabled != bt_disabled) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT is from %s to %s!!\n",
+ (coex_sta->bt_disabled ? "disabled" : "enabled"),
+ (bt_disabled ? "disabled" : "enabled"));
+ coex_sta->bt_disabled = bt_disabled;
+ }
+}
+
+static void halbtc8822b2ant_enable_gnt_to_gpio(struct btc_coexist *btcoexist,
+ bool isenable)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ static u8 bit_val[5] = {0, 0, 0, 0, 0};
+
+ if (!btcoexist->dbg_mode_2ant)
+ return;
+
+ if (isenable) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], enable_gnt_to_gpio!!\n");
+
+ /* enable GNT_WL, GNT_BT to GPIO for debug */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x73, 0x8, 0x1);
+
+ /* store original value */
+ bit_val[0] =
+ (btcoexist->btc_read_1byte(btcoexist, 0x66) & BIT(4)) >>
+ 4; /*0x66[4] */
+ bit_val[1] = (btcoexist->btc_read_1byte(btcoexist, 0x67) &
+ BIT(0)); /*0x66[8] */
+ bit_val[2] =
+ (btcoexist->btc_read_1byte(btcoexist, 0x42) & BIT(3)) >>
+ 3; /*0x40[19] */
+ bit_val[3] =
+ (btcoexist->btc_read_1byte(btcoexist, 0x65) & BIT(7)) >>
+ 7; /*0x64[15] */
+ bit_val[4] =
+ (btcoexist->btc_read_1byte(btcoexist, 0x72) & BIT(2)) >>
+ 2; /*0x70[18] */
+
+ /* switch GPIO Mux */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x66, BIT(4),
+ 0x0); /*0x66[4] = 0 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, BIT(0),
+ 0x0); /*0x66[8] = 0 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x42, BIT(3),
+ 0x0); /*0x40[19] = 0 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x65, BIT(7),
+ 0x0); /*0x64[15] = 0 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x72, BIT(2),
+ 0x0); /*0x70[18] = 0 */
+
+ } else {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], disable_gnt_to_gpio!!\n");
+
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x73, 0x8, 0x0);
+
+ /* Restore original value */
+ /* switch GPIO Mux */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x66, BIT(4),
+ bit_val[0]); /*0x66[4] = 0 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, BIT(0),
+ bit_val[1]); /*0x66[8] = 0 */
+ btcoexist->btc_write_1byte_bitmask(
+ btcoexist, 0x42, BIT(3), bit_val[2]); /*0x40[19] = 0 */
+ btcoexist->btc_write_1byte_bitmask(
+ btcoexist, 0x65, BIT(7), bit_val[3]); /*0x64[15] = 0 */
+ btcoexist->btc_write_1byte_bitmask(
+ btcoexist, 0x72, BIT(2), bit_val[4]); /*0x70[18] = 0 */
+ }
+}
+
+static u32
+halbtc8822b2ant_ltecoex_indirect_read_reg(struct btc_coexist *btcoexist,
+ u16 reg_addr)
+{
+ u32 delay_count = 0;
+
+ while (1) {
+ if ((btcoexist->btc_read_1byte(btcoexist, 0x1703) & BIT(5)) ==
+ 0) {
+ mdelay(50);
+ delay_count++;
+ if (delay_count >= 10) {
+ delay_count = 0;
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+
+ /* wait for ready bit before access 0x1700 */
+ btcoexist->btc_write_4byte(btcoexist, 0x1700, 0x800F0000 | reg_addr);
+
+ return btcoexist->btc_read_4byte(btcoexist, 0x1708); /* get read data */
+}
+
+static void
+halbtc8822b2ant_ltecoex_indirect_write_reg(struct btc_coexist *btcoexist,
+ u16 reg_addr, u32 bit_mask,
+ u32 reg_value)
+{
+ u32 val, i = 0, bitpos = 0, delay_count = 0;
+
+ if (bit_mask == 0x0)
+ return;
+ if (bit_mask == 0xffffffff) {
+ /* wait for ready bit before access 0x1700/0x1704 */
+ while (1) {
+ if ((btcoexist->btc_read_1byte(btcoexist, 0x1703) &
+ BIT(5)) == 0) {
+ mdelay(50);
+ delay_count++;
+ if (delay_count >= 10) {
+ delay_count = 0;
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+
+ btcoexist->btc_write_4byte(btcoexist, 0x1704,
+ reg_value); /* put write data */
+
+ btcoexist->btc_write_4byte(btcoexist, 0x1700,
+ 0xc00F0000 | reg_addr);
+ } else {
+ for (i = 0; i <= 31; i++) {
+ if (((bit_mask >> i) & 0x1) == 0x1) {
+ bitpos = i;
+ break;
+ }
+ }
+
+ /* read back register value before write */
+ val = halbtc8822b2ant_ltecoex_indirect_read_reg(btcoexist,
+ reg_addr);
+ val = (val & (~bit_mask)) | (reg_value << bitpos);
+
+ /* wait for ready bit before access 0x1700/0x1704 */
+ while (1) {
+ if ((btcoexist->btc_read_1byte(btcoexist, 0x1703) &
+ BIT(5)) == 0) {
+ mdelay(50);
+ delay_count++;
+ if (delay_count >= 10) {
+ delay_count = 0;
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+
+ btcoexist->btc_write_4byte(btcoexist, 0x1704,
+ val); /* put write data */
+
+ btcoexist->btc_write_4byte(btcoexist, 0x1700,
+ 0xc00F0000 | reg_addr);
+ }
+}
+
+static void halbtc8822b2ant_ltecoex_enable(struct btc_coexist *btcoexist,
+ bool enable)
+{
+ u8 val;
+
+ val = (enable) ? 1 : 0;
+ halbtc8822b2ant_ltecoex_indirect_write_reg(btcoexist, 0x38, 0x80,
+ val); /* 0x38[7] */
+}
+
+static void
+halbtc8822b2ant_ltecoex_pathcontrol_owner(struct btc_coexist *btcoexist,
+ bool wifi_control)
+{
+ u8 val;
+
+ val = (wifi_control) ? 1 : 0;
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x73, 0x4,
+ val); /* 0x70[26] */
+}
+
+static void halbtc8822b2ant_ltecoex_set_gnt_bt(struct btc_coexist *btcoexist,
+ u8 control_block,
+ bool sw_control, u8 state)
+{
+ u32 val = 0, bit_mask;
+
+ state = state & 0x1;
+ val = (sw_control) ? ((state << 1) | 0x1) : 0;
+
+ switch (control_block) {
+ case BT_8822B_2ANT_GNT_BLOCK_RFC_BB:
+ default:
+ bit_mask = 0xc000;
+ halbtc8822b2ant_ltecoex_indirect_write_reg(
+ btcoexist, 0x38, bit_mask, val); /* 0x38[15:14] */
+ bit_mask = 0x0c00;
+ halbtc8822b2ant_ltecoex_indirect_write_reg(
+ btcoexist, 0x38, bit_mask, val); /* 0x38[11:10] */
+ break;
+ case BT_8822B_2ANT_GNT_BLOCK_RFC:
+ bit_mask = 0xc000;
+ halbtc8822b2ant_ltecoex_indirect_write_reg(
+ btcoexist, 0x38, bit_mask, val); /* 0x38[15:14] */
+ break;
+ case BT_8822B_2ANT_GNT_BLOCK_BB:
+ bit_mask = 0x0c00;
+ halbtc8822b2ant_ltecoex_indirect_write_reg(
+ btcoexist, 0x38, bit_mask, val); /* 0x38[11:10] */
+ break;
+ }
+}
+
+static void halbtc8822b2ant_ltecoex_set_gnt_wl(struct btc_coexist *btcoexist,
+ u8 control_block,
+ bool sw_control, u8 state)
+{
+ u32 val = 0, bit_mask;
+
+ state = state & 0x1;
+ val = (sw_control) ? ((state << 1) | 0x1) : 0;
+
+ switch (control_block) {
+ case BT_8822B_2ANT_GNT_BLOCK_RFC_BB:
+ default:
+ bit_mask = 0x3000;
+ halbtc8822b2ant_ltecoex_indirect_write_reg(
+ btcoexist, 0x38, bit_mask, val); /* 0x38[13:12] */
+ bit_mask = 0x0300;
+ halbtc8822b2ant_ltecoex_indirect_write_reg(
+ btcoexist, 0x38, bit_mask, val); /* 0x38[9:8] */
+ break;
+ case BT_8822B_2ANT_GNT_BLOCK_RFC:
+ bit_mask = 0x3000;
+ halbtc8822b2ant_ltecoex_indirect_write_reg(
+ btcoexist, 0x38, bit_mask, val); /* 0x38[13:12] */
+ break;
+ case BT_8822B_2ANT_GNT_BLOCK_BB:
+ bit_mask = 0x0300;
+ halbtc8822b2ant_ltecoex_indirect_write_reg(
+ btcoexist, 0x38, bit_mask, val); /* 0x38[9:8] */
+ break;
+ }
+}
+
+static void
+halbtc8822b2ant_ltecoex_set_coex_table(struct btc_coexist *btcoexist,
+ u8 table_type, u16 table_content)
+{
+ u16 reg_addr = 0x0000;
+
+ switch (table_type) {
+ case BT_8822B_2ANT_CTT_WL_VS_LTE:
+ reg_addr = 0xa0;
+ break;
+ case BT_8822B_2ANT_CTT_BT_VS_LTE:
+ reg_addr = 0xa4;
+ break;
+ }
+
+ if (reg_addr != 0x0000)
+ halbtc8822b2ant_ltecoex_indirect_write_reg(
+ btcoexist, reg_addr, 0xffff,
+ table_content); /* 0xa0[15:0] or 0xa4[15:0] */
+}
+
+static void halbtc8822b2ant_set_wltoggle_coex_table(
+ struct btc_coexist *btcoexist, bool force_exec, u8 interval,
+ u8 val0x6c4_b0, u8 val0x6c4_b1, u8 val0x6c4_b2, u8 val0x6c4_b3)
+{
+ static u8 pre_h2c_parameter[6] = {0};
+ u8 cur_h2c_parameter[6] = {0};
+ u8 i, match_cnt = 0;
+
+ cur_h2c_parameter[0] = 0x7; /* op_code, 0x7= wlan toggle slot*/
+
+ cur_h2c_parameter[1] = interval;
+ cur_h2c_parameter[2] = val0x6c4_b0;
+ cur_h2c_parameter[3] = val0x6c4_b1;
+ cur_h2c_parameter[4] = val0x6c4_b2;
+ cur_h2c_parameter[5] = val0x6c4_b3;
+
+ if (!force_exec) {
+ for (i = 1; i <= 5; i++) {
+ if (cur_h2c_parameter[i] != pre_h2c_parameter[i])
+ break;
+
+ match_cnt++;
+ }
+
+ if (match_cnt == 5)
+ return;
+ }
+
+ for (i = 1; i <= 5; i++)
+ pre_h2c_parameter[i] = cur_h2c_parameter[i];
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x69, 6, cur_h2c_parameter);
+}
+
+static void halbtc8822b2ant_set_coex_table(struct btc_coexist *btcoexist,
+ u32 val0x6c0, u32 val0x6c4,
+ u32 val0x6c8, u8 val0x6cc)
+{
+ btcoexist->btc_write_4byte(btcoexist, 0x6c0, val0x6c0);
+
+ btcoexist->btc_write_4byte(btcoexist, 0x6c4, val0x6c4);
+
+ btcoexist->btc_write_4byte(btcoexist, 0x6c8, val0x6c8);
+
+ btcoexist->btc_write_1byte(btcoexist, 0x6cc, val0x6cc);
+}
+
+static void halbtc8822b2ant_coex_table(struct btc_coexist *btcoexist,
+ bool force_exec, u32 val0x6c0,
+ u32 val0x6c4, u32 val0x6c8, u8 val0x6cc)
+{
+ coex_dm->cur_val0x6c0 = val0x6c0;
+ coex_dm->cur_val0x6c4 = val0x6c4;
+ coex_dm->cur_val0x6c8 = val0x6c8;
+ coex_dm->cur_val0x6cc = val0x6cc;
+
+ if (!force_exec) {
+ if ((coex_dm->pre_val0x6c0 == coex_dm->cur_val0x6c0) &&
+ (coex_dm->pre_val0x6c4 == coex_dm->cur_val0x6c4) &&
+ (coex_dm->pre_val0x6c8 == coex_dm->cur_val0x6c8) &&
+ (coex_dm->pre_val0x6cc == coex_dm->cur_val0x6cc))
+ return;
+ }
+ halbtc8822b2ant_set_coex_table(btcoexist, val0x6c0, val0x6c4, val0x6c8,
+ val0x6cc);
+
+ coex_dm->pre_val0x6c0 = coex_dm->cur_val0x6c0;
+ coex_dm->pre_val0x6c4 = coex_dm->cur_val0x6c4;
+ coex_dm->pre_val0x6c8 = coex_dm->cur_val0x6c8;
+ coex_dm->pre_val0x6cc = coex_dm->cur_val0x6cc;
+}
+
+static void halbtc8822b2ant_coex_table_with_type(struct btc_coexist *btcoexist,
+ bool force_exec, u8 type)
+{
+ u32 break_table;
+ u8 select_table;
+
+ coex_sta->coex_table_type = type;
+
+ if (coex_sta->concurrent_rx_mode_on) {
+ break_table = 0xf0ffffff; /* set WL hi-pri can break BT */
+ /* set Tx response = Hi-Pri (ex: Transmitting ACK,BA,CTS) */
+ select_table = 0xb;
+ } else {
+ break_table = 0xffffff;
+ select_table = 0x3;
+ }
+
+ switch (type) {
+ case 0:
+ halbtc8822b2ant_coex_table(btcoexist, force_exec, 0xffffffff,
+ 0xffffffff, break_table,
+ select_table);
+ break;
+ case 1:
+ halbtc8822b2ant_coex_table(btcoexist, force_exec, 0x55555555,
+ 0x5a5a5a5a, break_table,
+ select_table);
+ break;
+ case 2:
+ halbtc8822b2ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a,
+ 0x5a5a5a5a, break_table,
+ select_table);
+ break;
+ case 3:
+ halbtc8822b2ant_coex_table(btcoexist, force_exec, 0x55555555,
+ 0x5a5a5a5a, break_table,
+ select_table);
+ break;
+ case 4:
+ halbtc8822b2ant_coex_table(btcoexist, force_exec, 0x55555555,
+ 0x5a5a5a5a, break_table,
+ select_table);
+ break;
+ case 5:
+ halbtc8822b2ant_coex_table(btcoexist, force_exec, 0x55555555,
+ 0x55555555, break_table,
+ select_table);
+ break;
+ case 6:
+ halbtc8822b2ant_coex_table(btcoexist, force_exec, 0xa5555555,
+ 0xfafafafa, break_table,
+ select_table);
+ break;
+ case 7:
+ halbtc8822b2ant_coex_table(btcoexist, force_exec, 0xa5555555,
+ 0xaa5a5a5a, break_table,
+ select_table);
+ break;
+ case 8:
+ halbtc8822b2ant_coex_table(btcoexist, force_exec, 0xa5555555,
+ 0xfafafafa, break_table,
+ select_table);
+ break;
+ case 9:
+ halbtc8822b2ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a,
+ 0xaaaa5aaa, break_table,
+ select_table);
+ break;
+ case 10:
+ halbtc8822b2ant_coex_table(btcoexist, force_exec, 0x55555555,
+ 0x5a5a555a, break_table,
+ select_table);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+halbtc8822b2ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoexist,
+ bool enable)
+{
+ u8 h2c_parameter[1] = {0};
+ u32 RTL97F_8822B = 0;
+
+ if (RTL97F_8822B)
+ return;
+
+ if (enable)
+ h2c_parameter[0] |= BIT(0); /* function enable */
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x63, 1, h2c_parameter);
+}
+
+static void halbtc8822b2ant_ignore_wlan_act(struct btc_coexist *btcoexist,
+ bool force_exec, bool enable)
+{
+ coex_dm->cur_ignore_wlan_act = enable;
+
+ if (!force_exec) {
+ if (coex_dm->pre_ignore_wlan_act ==
+ coex_dm->cur_ignore_wlan_act)
+ return;
+ }
+ halbtc8822b2ant_set_fw_ignore_wlan_act(btcoexist, enable);
+
+ coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act;
+}
+
+static void halbtc8822b2ant_set_lps_rpwm(struct btc_coexist *btcoexist,
+ u8 lps_val, u8 rpwm_val)
+{
+ u8 lps = lps_val;
+ u8 rpwm = rpwm_val;
+
+ btcoexist->btc_set(btcoexist, BTC_SET_U1_LPS_VAL, &lps);
+ btcoexist->btc_set(btcoexist, BTC_SET_U1_RPWM_VAL, &rpwm);
+}
+
+static void halbtc8822b2ant_lps_rpwm(struct btc_coexist *btcoexist,
+ bool force_exec, u8 lps_val, u8 rpwm_val)
+{
+ coex_dm->cur_lps = lps_val;
+ coex_dm->cur_rpwm = rpwm_val;
+
+ if (!force_exec) {
+ if ((coex_dm->pre_lps == coex_dm->cur_lps) &&
+ (coex_dm->pre_rpwm == coex_dm->cur_rpwm))
+ return;
+ }
+ halbtc8822b2ant_set_lps_rpwm(btcoexist, lps_val, rpwm_val);
+
+ coex_dm->pre_lps = coex_dm->cur_lps;
+ coex_dm->pre_rpwm = coex_dm->cur_rpwm;
+}
+
+static void halbtc8822b2ant_ps_tdma_check_for_power_save_state(
+ struct btc_coexist *btcoexist, bool new_ps_state)
+{
+ u8 lps_mode = 0x0;
+ u8 h2c_parameter[5] = {0, 0, 0, 0x40, 0};
+ u32 RTL97F_8822B = 0;
+
+ if (RTL97F_8822B)
+ return;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_LPS_MODE, &lps_mode);
+
+ if (lps_mode) { /* already under LPS state */
+ if (new_ps_state) {
+ /* keep state under LPS, do nothing. */
+ } else {
+ /* will leave LPS state, turn off psTdma first */
+ btcoexist->btc_fill_h2c(btcoexist, 0x60, 5,
+ h2c_parameter);
+ }
+ } else { /* NO PS state */
+ if (new_ps_state) {
+ /* will enter LPS state, turn off psTdma first */
+ btcoexist->btc_fill_h2c(btcoexist, 0x60, 5,
+ h2c_parameter);
+ } else {
+ /* keep state under NO PS state, do nothing. */
+ }
+ }
+}
+
+static bool halbtc8822b2ant_power_save_state(struct btc_coexist *btcoexist,
+ u8 ps_type, u8 lps_val,
+ u8 rpwm_val)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ bool low_pwr_disable = false, result = true;
+
+ switch (ps_type) {
+ case BTC_PS_WIFI_NATIVE:
+ coex_sta->force_lps_ctrl = false;
+ /* recover to original 32k low power setting */
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], %s == BTC_PS_WIFI_NATIVE\n", __func__);
+
+ low_pwr_disable = false;
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
+ &low_pwr_disable);
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_NORMAL_LPS, NULL);
+ break;
+ case BTC_PS_LPS_ON:
+ coex_sta->force_lps_ctrl = true;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], %s == BTC_PS_LPS_ON\n", __func__);
+
+ halbtc8822b2ant_ps_tdma_check_for_power_save_state(btcoexist,
+ true);
+ halbtc8822b2ant_lps_rpwm(btcoexist, NORMAL_EXEC, lps_val,
+ rpwm_val);
+ /* when coex force to enter LPS, do not enter 32k low power. */
+ low_pwr_disable = true;
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
+ &low_pwr_disable);
+ /* power save must executed before psTdma. */
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL);
+ break;
+ case BTC_PS_LPS_OFF:
+ coex_sta->force_lps_ctrl = true;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], %s == BTC_PS_LPS_OFF\n", __func__);
+
+ halbtc8822b2ant_ps_tdma_check_for_power_save_state(btcoexist,
+ false);
+ result = btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS,
+ NULL);
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+static void halbtc8822b2ant_set_fw_pstdma(struct btc_coexist *btcoexist,
+ u8 byte1, u8 byte2, u8 byte3,
+ u8 byte4, u8 byte5)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ u8 h2c_parameter[5] = {0};
+ u8 real_byte1 = byte1, real_byte5 = byte5;
+ bool ap_enable = false, result = false;
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+
+ if (byte5 & BIT(2))
+ coex_sta->is_tdma_btautoslot = true;
+ else
+ coex_sta->is_tdma_btautoslot = false;
+
+ /* release bt-auto slot for auto-slot hang is detected!! */
+ if (coex_sta->is_tdma_btautoslot)
+ if ((coex_sta->is_tdma_btautoslot_hang) ||
+ (bt_link_info->slave_role))
+ byte5 = byte5 & 0xfb;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
+ &ap_enable);
+
+ if ((ap_enable) && (byte1 & BIT(4) && !(byte1 & BIT(5)))) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], %s == FW for AP mode\n", __func__);
+
+ real_byte1 &= ~BIT(4);
+ real_byte1 |= BIT(5);
+
+ real_byte5 |= BIT(5);
+ real_byte5 &= ~BIT(6);
+
+ halbtc8822b2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
+ 0x0, 0x0);
+ } else if (byte1 & BIT(4) && !(byte1 & BIT(5))) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], %s == Force LPS (byte1 = 0x%x)\n",
+ __func__, byte1);
+
+ if (!halbtc8822b2ant_power_save_state(btcoexist, BTC_PS_LPS_OFF,
+ 0x50, 0x4))
+ result = true;
+ } else {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], %s == Native LPS (byte1 = 0x%x)\n",
+ __func__, byte1);
+
+ halbtc8822b2ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
+ 0x0, 0x0);
+ }
+
+ coex_sta->is_set_ps_state_fail = result;
+
+ if (!coex_sta->is_set_ps_state_fail) {
+ h2c_parameter[0] = real_byte1;
+ h2c_parameter[1] = byte2;
+ h2c_parameter[2] = byte3;
+ h2c_parameter[3] = byte4;
+ h2c_parameter[4] = real_byte5;
+
+ coex_dm->ps_tdma_para[0] = real_byte1;
+ coex_dm->ps_tdma_para[1] = byte2;
+ coex_dm->ps_tdma_para[2] = byte3;
+ coex_dm->ps_tdma_para[3] = byte4;
+ coex_dm->ps_tdma_para[4] = real_byte5;
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x60, 5, h2c_parameter);
+ } else {
+ coex_sta->cnt_set_ps_state_fail++;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], %s == Force Leave LPS Fail (cnt = %d)\n",
+ __func__, coex_sta->cnt_set_ps_state_fail);
+ }
+}
+
+static void halbtc8822b2ant_ps_tdma(struct btc_coexist *btcoexist,
+ bool force_exec, bool turn_on, u8 type)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ static u8 ps_tdma_byte4_modify, pre_ps_tdma_byte4_modify;
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+
+ coex_dm->cur_ps_tdma_on = turn_on;
+ coex_dm->cur_ps_tdma = type;
+
+ /* 0x778 = 0x1 at wifi slot (no blocking BT Low-Pri pkts) */
+ if (bt_link_info->slave_role)
+ ps_tdma_byte4_modify = 0x1;
+ else
+ ps_tdma_byte4_modify = 0x0;
+
+ if (pre_ps_tdma_byte4_modify != ps_tdma_byte4_modify) {
+ force_exec = true;
+ pre_ps_tdma_byte4_modify = ps_tdma_byte4_modify;
+ }
+
+ if (!force_exec) {
+ if ((coex_dm->pre_ps_tdma_on == coex_dm->cur_ps_tdma_on) &&
+ (coex_dm->pre_ps_tdma == coex_dm->cur_ps_tdma)) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Skip TDMA because no change TDMA(%s, %d)\n",
+ (coex_dm->cur_ps_tdma_on ? "on" : "off"),
+ coex_dm->cur_ps_tdma);
+ return;
+ }
+ }
+
+ if (coex_dm->cur_ps_tdma_on) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** TDMA(on, %d) **********\n",
+ coex_dm->cur_ps_tdma);
+
+ btcoexist->btc_write_1byte_bitmask(
+ btcoexist, 0x550, 0x8, 0x1); /* enable TBTT nterrupt */
+ } else {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** TDMA(off, %d) **********\n",
+ coex_dm->cur_ps_tdma);
+ }
+
+ if (turn_on) {
+ switch (type) {
+ case 1:
+ halbtc8822b2ant_set_fw_pstdma(
+ btcoexist, 0x61, 0x10, 0x03, 0x91,
+ 0x54 | ps_tdma_byte4_modify);
+ break;
+ case 2:
+ default:
+ halbtc8822b2ant_set_fw_pstdma(
+ btcoexist, 0x61, 0x35, 0x03, 0x11,
+ 0x11 | ps_tdma_byte4_modify);
+ break;
+ case 3:
+ halbtc8822b2ant_set_fw_pstdma(
+ btcoexist, 0x61, 0x3a, 0x3, 0x91,
+ 0x10 | ps_tdma_byte4_modify);
+ break;
+ case 4:
+ halbtc8822b2ant_set_fw_pstdma(
+ btcoexist, 0x61, 0x21, 0x3, 0x91,
+ 0x10 | ps_tdma_byte4_modify);
+ break;
+ case 5:
+ halbtc8822b2ant_set_fw_pstdma(
+ btcoexist, 0x61, 0x25, 0x3, 0x91,
+ 0x10 | ps_tdma_byte4_modify);
+ break;
+ case 6:
+ halbtc8822b2ant_set_fw_pstdma(
+ btcoexist, 0x61, 0x10, 0x3, 0x91,
+ 0x10 | ps_tdma_byte4_modify);
+ break;
+ case 7:
+ halbtc8822b2ant_set_fw_pstdma(
+ btcoexist, 0x61, 0x20, 0x3, 0x91,
+ 0x10 | ps_tdma_byte4_modify);
+ break;
+ case 8:
+ halbtc8822b2ant_set_fw_pstdma(btcoexist, 0x61, 0x15,
+ 0x03, 0x11, 0x11);
+ break;
+ case 10:
+ halbtc8822b2ant_set_fw_pstdma(btcoexist, 0x61, 0x30,
+ 0x03, 0x11, 0x10);
+ break;
+ case 11:
+ halbtc8822b2ant_set_fw_pstdma(
+ btcoexist, 0x61, 0x35, 0x03, 0x11,
+ 0x10 | ps_tdma_byte4_modify);
+ break;
+ case 12:
+ halbtc8822b2ant_set_fw_pstdma(btcoexist, 0x61, 0x35,
+ 0x03, 0x11, 0x11);
+ break;
+ case 13:
+ halbtc8822b2ant_set_fw_pstdma(
+ btcoexist, 0x61, 0x1c, 0x03, 0x11,
+ 0x10 | ps_tdma_byte4_modify);
+ break;
+ case 14:
+ halbtc8822b2ant_set_fw_pstdma(btcoexist, 0x61, 0x20,
+ 0x03, 0x11, 0x11);
+ break;
+ case 15:
+ halbtc8822b2ant_set_fw_pstdma(btcoexist, 0x61, 0x10,
+ 0x03, 0x11, 0x14);
+ break;
+ case 16:
+ halbtc8822b2ant_set_fw_pstdma(btcoexist, 0x61, 0x10,
+ 0x03, 0x11, 0x15);
+ break;
+ case 21:
+ halbtc8822b2ant_set_fw_pstdma(btcoexist, 0x61, 0x30,
+ 0x03, 0x11, 0x10);
+ break;
+ case 22:
+ halbtc8822b2ant_set_fw_pstdma(btcoexist, 0x61, 0x25,
+ 0x03, 0x11, 0x10);
+ break;
+ case 23:
+ halbtc8822b2ant_set_fw_pstdma(btcoexist, 0x61, 0x10,
+ 0x03, 0x11, 0x10);
+ break;
+ case 51:
+ halbtc8822b2ant_set_fw_pstdma(
+ btcoexist, 0x61, 0x10, 0x03, 0x91,
+ 0x10 | ps_tdma_byte4_modify);
+ break;
+ case 101:
+ halbtc8822b2ant_set_fw_pstdma(
+ btcoexist, 0x61, 0x25, 0x03, 0x11,
+ 0x11 | ps_tdma_byte4_modify);
+ break;
+ case 102:
+ halbtc8822b2ant_set_fw_pstdma(
+ btcoexist, 0x61, 0x35, 0x03, 0x11,
+ 0x11 | ps_tdma_byte4_modify);
+ break;
+ case 103:
+ halbtc8822b2ant_set_fw_pstdma(
+ btcoexist, 0x51, 0x3a, 0x3, 0x10,
+ 0x50 | ps_tdma_byte4_modify);
+ break;
+ case 104:
+ halbtc8822b2ant_set_fw_pstdma(
+ btcoexist, 0x51, 0x21, 0x3, 0x10,
+ 0x50 | ps_tdma_byte4_modify);
+ break;
+ case 105:
+ halbtc8822b2ant_set_fw_pstdma(
+ btcoexist, 0x51, 0x30, 0x3, 0x10,
+ 0x50 | ps_tdma_byte4_modify);
+ break;
+ case 106:
+ halbtc8822b2ant_set_fw_pstdma(
+ btcoexist, 0x51, 0x10, 0x3, 0x10,
+ 0x50 | ps_tdma_byte4_modify);
+ break;
+ case 107:
+ halbtc8822b2ant_set_fw_pstdma(
+ btcoexist, 0x51, 0x10, 0x7, 0x10,
+ 0x54 | ps_tdma_byte4_modify);
+ break;
+ case 108:
+ halbtc8822b2ant_set_fw_pstdma(
+ btcoexist, 0x51, 0x30, 0x3, 0x10,
+ 0x50 | ps_tdma_byte4_modify);
+ break;
+ case 109:
+ halbtc8822b2ant_set_fw_pstdma(
+ btcoexist, 0x51, 0x10, 0x03, 0x10,
+ 0x54 | ps_tdma_byte4_modify);
+ break;
+ case 110:
+ halbtc8822b2ant_set_fw_pstdma(
+ btcoexist, 0x55, 0x30, 0x03, 0x10,
+ 0x50 | ps_tdma_byte4_modify);
+ break;
+ case 111:
+ halbtc8822b2ant_set_fw_pstdma(
+ btcoexist, 0x61, 0x25, 0x03, 0x11,
+ 0x11 | ps_tdma_byte4_modify);
+ break;
+ case 151:
+ halbtc8822b2ant_set_fw_pstdma(
+ btcoexist, 0x51, 0x10, 0x03, 0x10,
+ 0x50 | ps_tdma_byte4_modify);
+ break;
+ }
+ } else {
+ /* disable PS tdma */
+ switch (type) {
+ case 0:
+ halbtc8822b2ant_set_fw_pstdma(btcoexist, 0x0, 0x0, 0x0,
+ 0x40, 0x0);
+ break;
+ case 1:
+ halbtc8822b2ant_set_fw_pstdma(btcoexist, 0x0, 0x0, 0x0,
+ 0x48, 0x0);
+ break;
+ default:
+ halbtc8822b2ant_set_fw_pstdma(btcoexist, 0x0, 0x0, 0x0,
+ 0x40, 0x0);
+ break;
+ }
+ }
+
+ if (!coex_sta->is_set_ps_state_fail) {
+ /* update pre state */
+ coex_dm->pre_ps_tdma_on = coex_dm->cur_ps_tdma_on;
+ coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma;
+ }
+}
+
+/*anttenna control by bb mac bt antdiv pta to write 0x4c 0xcb4,0xcbd*/
+static void halbtc8822b2ant_set_ext_ant_switch(struct btc_coexist *btcoexist,
+ bool force_exec, u8 ctrl_type,
+ u8 pos_type)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ bool switch_polatiry_inverse = false;
+ u8 regval_0xcbc = 0, regval_0x64;
+ u32 u32tmp1 = 0, u32tmp2 = 0, u32tmp3 = 0;
+
+ if (!rfe_type->ext_ant_switch_exist)
+ return;
+
+ coex_dm->cur_ext_ant_switch_status = (ctrl_type << 8) + pos_type;
+
+ if (!force_exec) {
+ if (coex_dm->pre_ext_ant_switch_status ==
+ coex_dm->cur_ext_ant_switch_status)
+ return;
+ }
+ coex_dm->pre_ext_ant_switch_status = coex_dm->cur_ext_ant_switch_status;
+
+ /* Ext switch buffer mux */
+ btcoexist->btc_write_1byte(btcoexist, 0x974, 0xff);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x1991, 0x3, 0x0);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcbe, 0x8, 0x0);
+
+ switch (ctrl_type) {
+ default:
+ case BT_8822B_2ANT_EXT_ANT_SWITCH_CTRL_BY_BBSW:
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4e, 0x80,
+ 0x0); /* 0x4c[23] = 0 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4f, 0x01,
+ 0x1); /* 0x4c[24] = 1 */
+ /* BB SW, DPDT use RFE_ctrl8 and RFE_ctrl9 as conctrol pin */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb4, 0xff,
+ 0x77);
+
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcbd, 0x03, 01);
+
+ break;
+ case BT_8822B_2ANT_EXT_ANT_SWITCH_CTRL_BY_PTA:
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4e, 0x80,
+ 0x0); /* 0x4c[23] = 0 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4f, 0x01,
+ 0x1); /* 0x4c[24] = 1 */
+ /* PTA, DPDT use RFE_ctrl8 and RFE_ctrl9 as conctrol pin */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb4, 0xff,
+ 0x66);
+
+ /* 0xcb4[29:28] = 2b'10 for no switch_polatiry_inverse,
+ * DPDT_SEL_N =1, DPDT_SEL_P =0 @ GNT_BT=1
+ */
+ regval_0xcbc = (!switch_polatiry_inverse ? 0x2 : 0x1);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcbc, 0x03,
+ regval_0xcbc);
+
+ break;
+ case BT_8822B_2ANT_EXT_ANT_SWITCH_CTRL_BY_ANTDIV:
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4e, 0x80,
+ 0x0); /* 0x4c[23] = 0 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4f, 0x01,
+ 0x1); /* 0x4c[24] = 1 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb4, 0xff,
+ 0x88);
+ break;
+ case BT_8822B_2ANT_EXT_ANT_SWITCH_CTRL_BY_MAC:
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4e, 0x80,
+ 0x1); /* 0x4c[23] = 1 */
+
+ /* 0x64[0] = 1b'0 for no switch_polatiry_inverse,
+ * DPDT_SEL_N =1, DPDT_SEL_P =0
+ */
+ regval_0x64 = (!switch_polatiry_inverse ? 0x0 : 0x1);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x64, 0x1,
+ regval_0x64);
+ break;
+ case BT_8822B_2ANT_EXT_ANT_SWITCH_CTRL_BY_BT:
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4e, 0x80,
+ 0x0); /* 0x4c[23] = 0 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4f, 0x01,
+ 0x0); /* 0x4c[24] = 0 */
+
+ /* no setup required, because antenna switch control value by
+ * BT vendor 0x1c[1:0]
+ */
+ break;
+ }
+
+ /* PAPE, LNA_ON control by BT while WLAN off for current leakage issue*/
+ if (ctrl_type == BT_8822B_2ANT_EXT_ANT_SWITCH_CTRL_BY_BT) {
+ btcoexist->btc_write_1byte_bitmask(
+ btcoexist, 0x67, 0x20, 0x0); /* PAPE 0x64[29] = 0 */
+ btcoexist->btc_write_1byte_bitmask(
+ btcoexist, 0x67, 0x10, 0x0); /* LNA_ON 0x64[28] = 0 */
+ } else {
+ btcoexist->btc_write_1byte_bitmask(
+ btcoexist, 0x67, 0x20, 0x1); /* PAPE 0x64[29] = 1 */
+ btcoexist->btc_write_1byte_bitmask(
+ btcoexist, 0x67, 0x10, 0x1); /* LNA_ON 0x64[28] = 1 */
+ }
+
+ if (btcoexist->dbg_mode_2ant) {
+ u32tmp1 = btcoexist->btc_read_4byte(btcoexist, 0xcb4);
+ u32tmp2 = btcoexist->btc_read_4byte(btcoexist, 0x4c);
+ u32tmp3 = btcoexist->btc_read_4byte(btcoexist, 0x64) & 0xff;
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], (After Ext Ant switch setup) 0xcb4 = 0x%08x, 0x4c = 0x%08x, 0x64= 0x%02x\n",
+ u32tmp1, u32tmp2, u32tmp3);
+ }
+}
+
+/* rf4 type by efuse, and for ant at main aux inverse use,
+ * because is 2x2, and control types are the same, does not need
+ */
+static void halbtc8822b2ant_set_rfe_type(struct btc_coexist *btcoexist)
+{
+ struct btc_board_info *board_info = &btcoexist->board_info;
+
+ rfe_type->ext_band_switch_exist = false;
+ rfe_type->ext_band_switch_type =
+ BT_8822B_2ANT_EXT_BAND_SWITCH_USE_SPDT; /* SPDT; */
+ rfe_type->ext_band_switch_ctrl_polarity = 0;
+ /* Ext switch buffer mux */
+ btcoexist->btc_write_1byte(btcoexist, 0x974, 0xff);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x1991, 0x3, 0x0);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcbe, 0x8, 0x0);
+
+ if (rfe_type->ext_band_switch_exist) {
+ /* band switch use RFE_ctrl1 (pin name: PAPE_A) and
+ * RFE_ctrl3 (pin name: LNAON_A)
+ */
+
+ /* set RFE_ctrl1 as software control */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb0, 0xf0, 0x7);
+
+ /* set RFE_ctrl3 as software control */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb1, 0xf0, 0x7);
+ }
+
+ /* the following setup should be got from Efuse in the future */
+ rfe_type->rfe_module_type = board_info->rfe_type;
+
+ rfe_type->ext_ant_switch_ctrl_polarity = 0;
+
+ switch (rfe_type->rfe_module_type) {
+ case 0:
+ default:
+ rfe_type->ext_ant_switch_exist = true;
+ rfe_type->ext_ant_switch_type =
+ BT_8822B_2ANT_EXT_ANT_SWITCH_USE_SPDT;
+ break;
+ case 1:
+ rfe_type->ext_ant_switch_exist = true;
+ rfe_type->ext_ant_switch_type =
+ BT_8822B_2ANT_EXT_ANT_SWITCH_USE_SPDT;
+ break;
+ case 2:
+ rfe_type->ext_ant_switch_exist = true;
+ rfe_type->ext_ant_switch_type =
+ BT_8822B_2ANT_EXT_ANT_SWITCH_USE_SPDT;
+ break;
+ case 3:
+ rfe_type->ext_ant_switch_exist = true;
+ rfe_type->ext_ant_switch_type =
+ BT_8822B_2ANT_EXT_ANT_SWITCH_USE_SPDT;
+ break;
+ case 4:
+ rfe_type->ext_ant_switch_exist = true;
+ rfe_type->ext_ant_switch_type =
+ BT_8822B_2ANT_EXT_ANT_SWITCH_USE_SPDT;
+ break;
+ case 5:
+ rfe_type->ext_ant_switch_exist = true;
+ rfe_type->ext_ant_switch_type =
+ BT_8822B_2ANT_EXT_ANT_SWITCH_USE_SPDT;
+ break;
+ case 6:
+ rfe_type->ext_ant_switch_exist = true;
+ rfe_type->ext_ant_switch_type =
+ BT_8822B_2ANT_EXT_ANT_SWITCH_USE_SPDT;
+ break;
+ case 7:
+ rfe_type->ext_ant_switch_exist = true;
+ rfe_type->ext_ant_switch_type =
+ BT_8822B_2ANT_EXT_ANT_SWITCH_USE_SPDT;
+ break;
+ }
+}
+
+/* set gnt_wl gnt_bt control by sw high low, or hwpta while in
+ * power on, ini, wlan off, wlan only, wl2g non-currrent, wl2g current, wl5g
+ */
+static void halbtc8822b2ant_set_ant_path(struct btc_coexist *btcoexist,
+ u8 ant_pos_type, bool force_exec,
+ u8 phase)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ u8 u8tmp = 0;
+ u32 u32tmp1 = 0;
+ u32 u32tmp2 = 0, u32tmp3 = 0;
+
+ u32tmp1 = halbtc8822b2ant_ltecoex_indirect_read_reg(btcoexist, 0x38);
+
+ /* To avoid indirect access fail */
+ if (((u32tmp1 & 0xf000) >> 12) != ((u32tmp1 & 0x0f00) >> 8)) {
+ force_exec = true;
+ coex_sta->gnt_error_cnt++;
+ }
+
+ /* Ext switch buffer mux */
+ btcoexist->btc_write_1byte(btcoexist, 0x974, 0xff);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x1991, 0x3, 0x0);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcbe, 0x8, 0x0);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4e, 0x80,
+ 0x0); /* 0x4c[23] = 0 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4f, 0x01,
+ 0x1); /* 0x4c[24] = 1 */
+
+ coex_dm->cur_ant_pos_type = (ant_pos_type << 8) + phase;
+
+ if (!force_exec) {
+ if (coex_dm->cur_ant_pos_type == coex_dm->pre_ant_pos_type)
+ return;
+ }
+
+ coex_dm->pre_ant_pos_type = coex_dm->cur_ant_pos_type;
+
+ if (btcoexist->dbg_mode_2ant) {
+ u32tmp1 = halbtc8822b2ant_ltecoex_indirect_read_reg(btcoexist,
+ 0x38);
+ u32tmp2 = halbtc8822b2ant_ltecoex_indirect_read_reg(btcoexist,
+ 0x54);
+ u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x73);
+
+ u32tmp3 = btcoexist->btc_read_4byte(btcoexist, 0xcb4);
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], (Before Ant Setup) 0xcb4 = 0x%x, 0x73 = 0x%x, 0x38= 0x%x, 0x54= 0x%x\n",
+ u32tmp3, u8tmp, u32tmp1, u32tmp2);
+ }
+
+ switch (phase) {
+ case BT_8822B_2ANT_PHASE_COEX_POWERON:
+
+ /* set Path control owner to WL at initial step */
+ halbtc8822b2ant_ltecoex_pathcontrol_owner(
+ btcoexist, BT_8822B_2ANT_PCO_BTSIDE);
+
+ /* set GNT_BT to SW high */
+ halbtc8822b2ant_ltecoex_set_gnt_bt(
+ btcoexist, BT_8822B_2ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_2ANT_GNT_TYPE_CTRL_BY_SW,
+ BT_8822B_2ANT_SIG_STA_SET_TO_HIGH);
+ /* Set GNT_WL to SW high */
+ halbtc8822b2ant_ltecoex_set_gnt_wl(
+ btcoexist, BT_8822B_2ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_2ANT_GNT_TYPE_CTRL_BY_SW,
+ BT_8822B_2ANT_SIG_STA_SET_TO_HIGH);
+
+ coex_sta->run_time_state = false;
+
+ break;
+ case BT_8822B_2ANT_PHASE_COEX_INIT:
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4e, 0x80,
+ 0x0); /* 0x4c[23] = 0 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4f, 0x01,
+ 0x1); /* 0x4c[24] = 1 */
+ /* Disable LTE Coex Function in WiFi side
+ * (this should be on if LTE coex is required)
+ */
+ halbtc8822b2ant_ltecoex_enable(btcoexist, 0x0);
+
+ /* GNT_WL_LTE always = 1
+ * (this should be config if LTE coex is required)
+ */
+ halbtc8822b2ant_ltecoex_set_coex_table(
+ btcoexist, BT_8822B_2ANT_CTT_WL_VS_LTE, 0xffff);
+
+ /* GNT_BT_LTE always = 1
+ * (this should be config if LTE coex is required)
+ */
+ halbtc8822b2ant_ltecoex_set_coex_table(
+ btcoexist, BT_8822B_2ANT_CTT_BT_VS_LTE, 0xffff);
+
+ /* set Path control owner to WL at initial step */
+ halbtc8822b2ant_ltecoex_pathcontrol_owner(
+ btcoexist, BT_8822B_2ANT_PCO_WLSIDE);
+
+ /* set GNT_BT to SW high */
+ halbtc8822b2ant_ltecoex_set_gnt_bt(
+ btcoexist, BT_8822B_2ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_2ANT_GNT_TYPE_CTRL_BY_SW,
+ BT_8822B_2ANT_SIG_STA_SET_TO_HIGH);
+ /* Set GNT_WL to SW high */
+ halbtc8822b2ant_ltecoex_set_gnt_wl(
+ btcoexist, BT_8822B_2ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_2ANT_GNT_TYPE_CTRL_BY_SW,
+ BT_8822B_2ANT_SIG_STA_SET_TO_HIGH);
+
+ coex_sta->run_time_state = false;
+
+ break;
+ case BT_8822B_2ANT_PHASE_WLANONLY_INIT:
+ /* Disable LTE Coex Function in WiFi side
+ * (this should be on if LTE coex is required)
+ */
+ halbtc8822b2ant_ltecoex_enable(btcoexist, 0x0);
+
+ /* GNT_WL_LTE always = 1
+ * (this should be config if LTE coex is required)
+ */
+ halbtc8822b2ant_ltecoex_set_coex_table(
+ btcoexist, BT_8822B_2ANT_CTT_WL_VS_LTE, 0xffff);
+
+ /* GNT_BT_LTE always = 1
+ * (this should be config if LTE coex is required)
+ */
+ halbtc8822b2ant_ltecoex_set_coex_table(
+ btcoexist, BT_8822B_2ANT_CTT_BT_VS_LTE, 0xffff);
+
+ /* set Path control owner to WL at initial step */
+ halbtc8822b2ant_ltecoex_pathcontrol_owner(
+ btcoexist, BT_8822B_2ANT_PCO_WLSIDE);
+
+ /* set GNT_BT to SW Low */
+ halbtc8822b2ant_ltecoex_set_gnt_bt(
+ btcoexist, BT_8822B_2ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_2ANT_GNT_TYPE_CTRL_BY_SW,
+ BT_8822B_2ANT_SIG_STA_SET_TO_LOW);
+ /* Set GNT_WL to SW high */
+ halbtc8822b2ant_ltecoex_set_gnt_wl(
+ btcoexist, BT_8822B_2ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_2ANT_GNT_TYPE_CTRL_BY_SW,
+ BT_8822B_2ANT_SIG_STA_SET_TO_HIGH);
+
+ coex_sta->run_time_state = false;
+
+ break;
+ case BT_8822B_2ANT_PHASE_WLAN_OFF:
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4e, 0x80,
+ 0x0); /* 0x4c[23] = 0 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4f, 0x01,
+ 0x0); /* 0x4c[24] = 0 */
+ /* Disable LTE Coex Function in WiFi side */
+ halbtc8822b2ant_ltecoex_enable(btcoexist, 0x0);
+
+ /* set Path control owner to BT */
+ halbtc8822b2ant_ltecoex_pathcontrol_owner(
+ btcoexist, BT_8822B_2ANT_PCO_BTSIDE);
+
+ /* Set Ext Ant Switch to BT control at wifi off step */
+ halbtc8822b2ant_set_ext_ant_switch(
+ btcoexist, FORCE_EXEC,
+ BT_8822B_2ANT_EXT_ANT_SWITCH_CTRL_BY_BT,
+ BT_8822B_2ANT_EXT_ANT_SWITCH_MAIN_TO_NOCARE);
+ coex_sta->run_time_state = false;
+ break;
+ case BT_8822B_2ANT_PHASE_2G_RUNTIME:
+ case BT_8822B_2ANT_PHASE_2G_RUNTIME_CONCURRENT:
+
+ /* set Path control owner to WL at runtime step */
+ halbtc8822b2ant_ltecoex_pathcontrol_owner(
+ btcoexist, BT_8822B_2ANT_PCO_WLSIDE);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb4, 0xff,
+ 0x66);
+ if (phase == BT_8822B_2ANT_PHASE_2G_RUNTIME_CONCURRENT) {
+ /* set GNT_BT to PTA */
+ halbtc8822b2ant_ltecoex_set_gnt_bt(
+ btcoexist, BT_8822B_2ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_2ANT_GNT_TYPE_CTRL_BY_PTA,
+ BT_8822B_2ANT_SIG_STA_SET_BY_HW);
+
+ /* Set GNT_WL to SW High */
+ halbtc8822b2ant_ltecoex_set_gnt_wl(
+ btcoexist, BT_8822B_2ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_2ANT_GNT_TYPE_CTRL_BY_SW,
+ BT_8822B_2ANT_SIG_STA_SET_TO_HIGH);
+ } else {
+ /* set GNT_BT to PTA */
+ halbtc8822b2ant_ltecoex_set_gnt_bt(
+ btcoexist, BT_8822B_2ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_2ANT_GNT_TYPE_CTRL_BY_PTA,
+ BT_8822B_2ANT_SIG_STA_SET_BY_HW);
+
+ /* Set GNT_WL to PTA */
+ halbtc8822b2ant_ltecoex_set_gnt_wl(
+ btcoexist, BT_8822B_2ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_2ANT_GNT_TYPE_CTRL_BY_PTA,
+ BT_8822B_2ANT_SIG_STA_SET_BY_HW);
+ }
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ************* under2g 0xcbd setting =2 *************\n");
+
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcbd, 0x03, 02);
+ break;
+
+ case BT_8822B_2ANT_PHASE_5G_RUNTIME:
+
+ /* set Path control owner to WL at runtime step */
+ halbtc8822b2ant_ltecoex_pathcontrol_owner(
+ btcoexist, BT_8822B_2ANT_PCO_WLSIDE);
+
+ /* set GNT_BT to SW Hi */
+ halbtc8822b2ant_ltecoex_set_gnt_bt(
+ btcoexist, BT_8822B_2ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_2ANT_GNT_TYPE_CTRL_BY_SW,
+ BT_8822B_2ANT_SIG_STA_SET_TO_HIGH);
+ /* Set GNT_WL to SW Hi */
+ halbtc8822b2ant_ltecoex_set_gnt_wl(
+ btcoexist, BT_8822B_2ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_2ANT_GNT_TYPE_CTRL_BY_SW,
+ BT_8822B_2ANT_SIG_STA_SET_TO_HIGH);
+ coex_sta->run_time_state = true;
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ************* under5g 0xcbd setting =1 *************\n");
+
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcbd, 0x03, 01);
+
+ break;
+ case BT_8822B_2ANT_PHASE_BTMPMODE:
+ /* Disable LTE Coex Function in WiFi side */
+ halbtc8822b2ant_ltecoex_enable(btcoexist, 0x0);
+
+ /* set Path control owner to WL */
+ halbtc8822b2ant_ltecoex_pathcontrol_owner(
+ btcoexist, BT_8822B_2ANT_PCO_WLSIDE);
+
+ /* set GNT_BT to SW Hi */
+ halbtc8822b2ant_ltecoex_set_gnt_bt(
+ btcoexist, BT_8822B_2ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_2ANT_GNT_TYPE_CTRL_BY_SW,
+ BT_8822B_2ANT_SIG_STA_SET_TO_HIGH);
+
+ /* Set GNT_WL to SW Lo */
+ halbtc8822b2ant_ltecoex_set_gnt_wl(
+ btcoexist, BT_8822B_2ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_2ANT_GNT_TYPE_CTRL_BY_SW,
+ BT_8822B_2ANT_SIG_STA_SET_TO_LOW);
+
+ coex_sta->run_time_state = false;
+ break;
+ }
+
+ if (btcoexist->dbg_mode_2ant) {
+ u32tmp1 = halbtc8822b2ant_ltecoex_indirect_read_reg(btcoexist,
+ 0x38);
+ u32tmp2 = halbtc8822b2ant_ltecoex_indirect_read_reg(btcoexist,
+ 0x54);
+ u32tmp3 = btcoexist->btc_read_4byte(btcoexist, 0xcb4);
+ u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x73);
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], (After Ant-Setup phase---%d) 0xcb4 = 0x%x, 0x73 = 0x%x, 0x38= 0x%x, 0x54= 0x%x\n",
+ phase, u32tmp3, u8tmp, u32tmp1, u32tmp2);
+ }
+}
+
+static u8 halbtc8822b2ant_action_algorithm(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+ bool bt_hs_on = false;
+ u8 algorithm = BT_8822B_2ANT_COEX_ALGO_UNDEFINED;
+ u8 num_of_diff_profile = 0;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+
+ if (!bt_link_info->bt_link_exist) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], No BT link exists!!!\n");
+ return algorithm;
+ }
+
+ if (bt_link_info->sco_exist)
+ num_of_diff_profile++;
+ if (bt_link_info->hid_exist)
+ num_of_diff_profile++;
+ if (bt_link_info->pan_exist)
+ num_of_diff_profile++;
+ if (bt_link_info->a2dp_exist)
+ num_of_diff_profile++;
+
+ if (num_of_diff_profile == 0) {
+ if (bt_link_info->acl_busy) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], No-Profile busy\n");
+ algorithm = BT_8822B_2ANT_COEX_ALGO_NOPROFILEBUSY;
+ }
+ } else if ((bt_link_info->a2dp_exist) && (coex_sta->is_bt_a2dp_sink)) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], A2DP Sink\n");
+ algorithm = BT_8822B_2ANT_COEX_ALGO_A2DPSINK;
+ } else if (num_of_diff_profile == 1) {
+ if (bt_link_info->sco_exist) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], SCO only\n");
+ algorithm = BT_8822B_2ANT_COEX_ALGO_SCO;
+ } else {
+ if (bt_link_info->hid_exist) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], HID only\n");
+ algorithm = BT_8822B_2ANT_COEX_ALGO_HID;
+ } else if (bt_link_info->a2dp_exist) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], A2DP only\n");
+ algorithm = BT_8822B_2ANT_COEX_ALGO_A2DP;
+ } else if (bt_link_info->pan_exist) {
+ if (bt_hs_on) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], PAN(HS) only\n");
+ algorithm =
+ BT_8822B_2ANT_COEX_ALGO_PANHS;
+ } else {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], PAN(EDR) only\n");
+ algorithm =
+ BT_8822B_2ANT_COEX_ALGO_PANEDR;
+ }
+ }
+ }
+ } else if (num_of_diff_profile == 2) {
+ if (bt_link_info->sco_exist) {
+ if (bt_link_info->hid_exist) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], SCO + HID\n");
+ algorithm = BT_8822B_2ANT_COEX_ALGO_SCO;
+ } else if (bt_link_info->a2dp_exist) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], SCO + A2DP ==> A2DP\n");
+ algorithm = BT_8822B_2ANT_COEX_ALGO_A2DP;
+ } else if (bt_link_info->pan_exist) {
+ if (bt_hs_on) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], SCO + PAN(HS)\n");
+ algorithm = BT_8822B_2ANT_COEX_ALGO_SCO;
+ } else {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], SCO + PAN(EDR)\n");
+ algorithm =
+ BT_8822B_2ANT_COEX_ALGO_PANEDR;
+ }
+ }
+ } else {
+ if (bt_link_info->hid_exist &&
+ bt_link_info->a2dp_exist) {
+ {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], HID + A2DP\n");
+ algorithm =
+ BT_8822B_2ANT_COEX_ALGO_HID_A2DP;
+ }
+ } else if (bt_link_info->hid_exist &&
+ bt_link_info->pan_exist) {
+ if (bt_hs_on) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], HID + PAN(HS)\n");
+ algorithm = BT_8822B_2ANT_COEX_ALGO_HID;
+ } else {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], HID + PAN(EDR)\n");
+ algorithm =
+ BT_8822B_2ANT_COEX_ALGO_PANEDR_HID;
+ }
+ } else if (bt_link_info->pan_exist &&
+ bt_link_info->a2dp_exist) {
+ if (bt_hs_on) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], A2DP + PAN(HS)\n");
+ algorithm =
+ BT_8822B_2ANT_COEX_ALGO_A2DP_PANHS;
+ } else {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], A2DP + PAN(EDR)\n");
+ algorithm =
+ BT_8822B_2ANT_COEX_ALGO_PANEDR_A2DP;
+ }
+ }
+ }
+ } else if (num_of_diff_profile == 3) {
+ if (bt_link_info->sco_exist) {
+ if (bt_link_info->hid_exist &&
+ bt_link_info->a2dp_exist) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], SCO + HID + A2DP ==> HID + A2DP\n");
+ algorithm = BT_8822B_2ANT_COEX_ALGO_HID_A2DP;
+ } else if (bt_link_info->hid_exist &&
+ bt_link_info->pan_exist) {
+ if (bt_hs_on) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], SCO + HID + PAN(HS)\n");
+ algorithm =
+ BT_8822B_2ANT_COEX_ALGO_PANEDR_HID;
+ } else {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], SCO + HID + PAN(EDR)\n");
+ algorithm =
+ BT_8822B_2ANT_COEX_ALGO_PANEDR_HID;
+ }
+ } else if (bt_link_info->pan_exist &&
+ bt_link_info->a2dp_exist) {
+ if (bt_hs_on) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], SCO + A2DP + PAN(HS)\n");
+ algorithm =
+ BT_8822B_2ANT_COEX_ALGO_A2DP_PANHS;
+ } else {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], SCO + A2DP + PAN(EDR) ==> HID\n");
+ algorithm =
+ BT_8822B_2ANT_COEX_ALGO_PANEDR_A2DP;
+ }
+ }
+ } else {
+ if (bt_link_info->hid_exist &&
+ bt_link_info->pan_exist &&
+ bt_link_info->a2dp_exist) {
+ if (bt_hs_on) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], HID + A2DP + PAN(HS)\n");
+ algorithm =
+ BT_8822B_2ANT_COEX_ALGO_HID_A2DP_PANEDR;
+ } else {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], HID + A2DP + PAN(EDR)\n");
+ algorithm =
+ BT_8822B_2ANT_COEX_ALGO_HID_A2DP_PANEDR;
+ }
+ }
+ }
+ } else if (num_of_diff_profile >= 3) {
+ if (bt_link_info->sco_exist) {
+ if (bt_link_info->hid_exist &&
+ bt_link_info->pan_exist &&
+ bt_link_info->a2dp_exist) {
+ if (bt_hs_on) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], Error!!! SCO + HID + A2DP + PAN(HS)\n");
+ algorithm =
+ BT_8822B_2ANT_COEX_ALGO_HID_A2DP_PANEDR;
+ } else {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n");
+ algorithm =
+ BT_8822B_2ANT_COEX_ALGO_HID_A2DP_PANEDR;
+ }
+ }
+ }
+ }
+
+ return algorithm;
+}
+
+static void halbtc8822b2ant_action_coex_all_off(struct btc_coexist *btcoexist)
+{
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5);
+
+ /* fw all off */
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
+
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+}
+
+static void halbtc8822b2ant_action_wifi_under5g(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ /* fw all off */
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ************* under5g *************\n");
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+
+ halbtc8822b2ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO, FORCE_EXEC,
+ BT_8822B_2ANT_PHASE_5G_RUNTIME);
+}
+
+static void
+halbtc8822b2ant_action_wifi_native_lps(struct btc_coexist *btcoexist)
+{
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5);
+
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
+}
+
+static void halbtc8822b2ant_action_bt_inquiry(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ bool wifi_connected = false;
+ bool wifi_scan = false, wifi_link = false, wifi_roam = false;
+ bool wifi_busy = false;
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
+ &wifi_connected);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &wifi_scan);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &wifi_link);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &wifi_roam);
+
+ if ((coex_sta->bt_create_connection) &&
+ ((wifi_link) || (wifi_roam) || (wifi_scan) || (wifi_busy) ||
+ (coex_sta->wifi_is_high_pri_task))) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Wifi link/roam/Scan/busy/hi-pri-task + BT Inq/Page!!\n");
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 8);
+
+ if ((bt_link_info->a2dp_exist) && (!bt_link_info->pan_exist))
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 15);
+ else
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 11);
+ } else if ((!wifi_connected) && (!wifi_scan)) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Wifi no-link + no-scan + BT Inq/Page!!\n");
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5);
+
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
+ } else if (bt_link_info->pan_exist) {
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 22);
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 8);
+
+ } else if (bt_link_info->a2dp_exist) {
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 8);
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC,
+ 10);
+ } else {
+ if ((wifi_link) || (wifi_roam) || (wifi_scan) || (wifi_busy) ||
+ (coex_sta->wifi_is_high_pri_task))
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 21);
+ else
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 23);
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 8);
+ }
+
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, FORCE_EXEC, 0xd8);
+}
+
+static void
+halbtc8822b2ant_action_wifi_link_process(struct btc_coexist *btcoexist)
+{
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, FORCE_EXEC, 0xd4);
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 8);
+
+ if (bt_link_info->pan_exist) {
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 22);
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 8);
+
+ } else if (bt_link_info->a2dp_exist) {
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 16);
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 8);
+ } else {
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 21);
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 8);
+ }
+}
+
+static void
+halbtc8822b2ant_action_wifi_nonconnected(struct btc_coexist *btcoexist)
+{
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+
+ /* fw all off */
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
+
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+}
+
+static void halbtc8822b2ant_action_bt_relink(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], run bt multi link function\n");
+
+ if (coex_sta->is_bt_multi_link)
+ return;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], run bt re-link function\n");
+
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5);
+}
+
+static void halbtc8822b2ant_action_bt_idle(struct btc_coexist *btcoexist)
+{
+ bool wifi_busy = false;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+
+ if (!wifi_busy) {
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 8);
+
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14);
+ } else { /* if wl busy */
+
+ if (BT_8822B_2ANT_BT_STATUS_NON_CONNECTED_IDLE ==
+ coex_dm->bt_status) {
+ halbtc8822b2ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 0);
+
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false,
+ 0);
+ } else {
+ halbtc8822b2ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 8);
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 12);
+ }
+ }
+
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, FORCE_EXEC, 0xd8);
+}
+
+/* SCO only or SCO+PAN(HS) */
+static void halbtc8822b2ant_action_sco(struct btc_coexist *btcoexist)
+{
+ static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW;
+ static u8 pre_bt_rssi_state = BTC_RSSI_STATE_LOW;
+ u8 wifi_rssi_state, bt_rssi_state;
+
+ static u8 prewifi_rssi_state2 = BTC_RSSI_STATE_LOW;
+ static u8 pre_bt_rssi_state2 = BTC_RSSI_STATE_LOW;
+ u8 wifi_rssi_state2, bt_rssi_state2;
+ bool wifi_busy = false;
+ u32 wifi_bw = 1;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+
+ wifi_rssi_state = halbtc8822b2ant_wifi_rssi_state(
+ btcoexist, &prewifi_rssi_state, 2, coex_sta->wifi_coex_thres,
+ 0);
+
+ wifi_rssi_state2 = halbtc8822b2ant_wifi_rssi_state(
+ btcoexist, &prewifi_rssi_state2, 2, coex_sta->wifi_coex_thres2,
+ 0);
+
+ bt_rssi_state = halbtc8822b2ant_bt_rssi_state(
+ btcoexist, &pre_bt_rssi_state, 2, coex_sta->bt_coex_thres, 0);
+
+ bt_rssi_state2 = halbtc8822b2ant_bt_rssi_state(
+ btcoexist, &pre_bt_rssi_state2, 2, coex_sta->bt_coex_thres2, 0);
+
+ if (BTC_RSSI_HIGH(wifi_rssi_state) && BTC_RSSI_HIGH(bt_rssi_state)) {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+ halbtc8822b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0);
+
+ coex_dm->is_switch_to_1dot5_ant = false;
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5);
+
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
+ } else {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+ halbtc8822b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0);
+
+ coex_dm->is_switch_to_1dot5_ant = false;
+
+ if (coex_sta->is_esco_mode)
+ halbtc8822b2ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 1);
+ else /* 2-Ant free run if SCO mode */
+ halbtc8822b2ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 0);
+
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 8);
+ }
+}
+
+static void halbtc8822b2ant_action_hid(struct btc_coexist *btcoexist)
+{
+ static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW;
+ static u8 pre_bt_rssi_state = BTC_RSSI_STATE_LOW;
+ u8 wifi_rssi_state, bt_rssi_state;
+
+ static u8 prewifi_rssi_state2 = BTC_RSSI_STATE_LOW;
+ static u8 pre_bt_rssi_state2 = BTC_RSSI_STATE_LOW;
+ u8 wifi_rssi_state2, bt_rssi_state2;
+ bool wifi_busy = false;
+ u32 wifi_bw = 1;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ wifi_rssi_state = halbtc8822b2ant_wifi_rssi_state(
+ btcoexist, &prewifi_rssi_state, 2, coex_sta->wifi_coex_thres,
+ 0);
+
+ wifi_rssi_state2 = halbtc8822b2ant_wifi_rssi_state(
+ btcoexist, &prewifi_rssi_state2, 2, coex_sta->wifi_coex_thres2,
+ 0);
+
+ bt_rssi_state = halbtc8822b2ant_bt_rssi_state(
+ btcoexist, &pre_bt_rssi_state, 2, coex_sta->bt_coex_thres, 0);
+
+ bt_rssi_state2 = halbtc8822b2ant_bt_rssi_state(
+ btcoexist, &pre_bt_rssi_state2, 2, coex_sta->bt_coex_thres2, 0);
+
+ if (BTC_RSSI_HIGH(wifi_rssi_state) && BTC_RSSI_HIGH(bt_rssi_state)) {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+ halbtc8822b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0);
+
+ coex_dm->is_switch_to_1dot5_ant = false;
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
+ } else {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+ halbtc8822b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0);
+
+ coex_dm->is_switch_to_1dot5_ant = false;
+
+ if (coex_sta->is_hid_low_pri_tx_overhead) {
+ halbtc8822b2ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 4);
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 108);
+ } else if (wifi_bw == 0) { /* if 11bg mode */
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 8);
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 111);
+ } else {
+ halbtc8822b2ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 8);
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 111);
+ }
+ }
+}
+
+static void halbtc8822b2ant_action_a2dpsink(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW;
+ static u8 pre_bt_rssi_state = BTC_RSSI_STATE_LOW;
+ u8 wifi_rssi_state, bt_rssi_state;
+
+ static u8 prewifi_rssi_state2 = BTC_RSSI_STATE_LOW;
+ static u8 pre_bt_rssi_state2 = BTC_RSSI_STATE_LOW;
+ u8 wifi_rssi_state2, bt_rssi_state2;
+ bool wifi_busy = false, wifi_turbo = false;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM,
+ &coex_sta->scan_ap_num);
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "############# [BTCoex], scan_ap_num = %d, wl_noisy = %d\n",
+ coex_sta->scan_ap_num, coex_sta->wl_noisy_level);
+
+ if ((wifi_busy) && (coex_sta->wl_noisy_level == 0))
+ wifi_turbo = true;
+
+ wifi_rssi_state = halbtc8822b2ant_wifi_rssi_state(
+ btcoexist, &prewifi_rssi_state, 2, coex_sta->wifi_coex_thres,
+ 0);
+
+ wifi_rssi_state2 = halbtc8822b2ant_wifi_rssi_state(
+ btcoexist, &prewifi_rssi_state2, 2, coex_sta->wifi_coex_thres2,
+ 0);
+
+ bt_rssi_state = halbtc8822b2ant_bt_rssi_state(
+ btcoexist, &pre_bt_rssi_state, 2, coex_sta->bt_coex_thres, 0);
+
+ bt_rssi_state2 = halbtc8822b2ant_bt_rssi_state(
+ btcoexist, &pre_bt_rssi_state2, 2, coex_sta->bt_coex_thres2, 0);
+
+ if (BTC_RSSI_HIGH(wifi_rssi_state) && BTC_RSSI_HIGH(bt_rssi_state)) {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+ halbtc8822b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0);
+
+ coex_dm->is_switch_to_1dot5_ant = false;
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
+ } else if (BTC_RSSI_HIGH(wifi_rssi_state2) &&
+ BTC_RSSI_HIGH(bt_rssi_state2)) {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xc8);
+ halbtc8822b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2);
+
+ coex_dm->is_switch_to_1dot5_ant = false;
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
+
+ if (wifi_busy)
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 1);
+ else
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 16);
+ } else {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+ halbtc8822b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0);
+
+ coex_dm->is_switch_to_1dot5_ant = true;
+
+ if ((coex_sta->bt_relink_downcount != 0) && (wifi_busy)) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "############# [BTCoex], BT Re-Link + A2DP + WL busy\n");
+
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false,
+ 0);
+ halbtc8822b2ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 5);
+
+ } else {
+ halbtc8822b2ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 8);
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 105);
+ }
+ }
+}
+
+/* A2DP only / PAN(EDR) only/ A2DP+PAN(HS) */
+static void halbtc8822b2ant_action_a2dp(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW;
+ static u8 pre_bt_rssi_state = BTC_RSSI_STATE_LOW;
+ u8 wifi_rssi_state, bt_rssi_state;
+
+ static u8 prewifi_rssi_state2 = BTC_RSSI_STATE_LOW;
+ static u8 pre_bt_rssi_state2 = BTC_RSSI_STATE_LOW;
+ u8 wifi_rssi_state2, bt_rssi_state2;
+ bool wifi_busy = false, wifi_turbo = false;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM,
+ &coex_sta->scan_ap_num);
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "############# [BTCoex], scan_ap_num = %d, wl_noisy = %d\n",
+ coex_sta->scan_ap_num, coex_sta->wl_noisy_level);
+
+ if ((wifi_busy) && (coex_sta->wl_noisy_level == 0))
+ wifi_turbo = true;
+
+ wifi_rssi_state = halbtc8822b2ant_wifi_rssi_state(
+ btcoexist, &prewifi_rssi_state, 2, coex_sta->wifi_coex_thres,
+ 0);
+
+ wifi_rssi_state2 = halbtc8822b2ant_wifi_rssi_state(
+ btcoexist, &prewifi_rssi_state2, 2, coex_sta->wifi_coex_thres2,
+ 0);
+
+ bt_rssi_state = halbtc8822b2ant_bt_rssi_state(
+ btcoexist, &pre_bt_rssi_state, 2, coex_sta->bt_coex_thres, 0);
+
+ bt_rssi_state2 = halbtc8822b2ant_bt_rssi_state(
+ btcoexist, &pre_bt_rssi_state2, 2, coex_sta->bt_coex_thres2, 0);
+
+ if (BTC_RSSI_HIGH(wifi_rssi_state) && BTC_RSSI_HIGH(bt_rssi_state)) {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+ halbtc8822b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0);
+
+ coex_dm->is_switch_to_1dot5_ant = false;
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
+ } else if (BTC_RSSI_HIGH(wifi_rssi_state2) &&
+ BTC_RSSI_HIGH(bt_rssi_state2)) {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xc8);
+ halbtc8822b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2);
+
+ coex_dm->is_switch_to_1dot5_ant = false;
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
+
+ if (wifi_busy)
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 1);
+ else
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 16);
+ } else {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+ halbtc8822b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0);
+
+ coex_dm->is_switch_to_1dot5_ant = true;
+
+ if ((coex_sta->bt_relink_downcount != 0) && (wifi_busy)) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "############# [BTCoex], BT Re-Link + A2DP + WL busy\n");
+
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false,
+ 0);
+ halbtc8822b2ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 5);
+
+ } else {
+ if (wifi_turbo)
+ halbtc8822b2ant_coex_table_with_type(
+ btcoexist, NORMAL_EXEC, 10);
+ else
+ halbtc8822b2ant_coex_table_with_type(
+ btcoexist, NORMAL_EXEC, 10);
+
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 109);
+ }
+ }
+}
+
+static void halbtc8822b2ant_action_pan_edr(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW;
+ static u8 pre_bt_rssi_state = BTC_RSSI_STATE_LOW;
+ u8 wifi_rssi_state, bt_rssi_state;
+
+ static u8 prewifi_rssi_state2 = BTC_RSSI_STATE_LOW;
+ static u8 pre_bt_rssi_state2 = BTC_RSSI_STATE_LOW;
+ u8 wifi_rssi_state2, bt_rssi_state2;
+ bool wifi_busy = false, wifi_turbo = false;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM,
+ &coex_sta->scan_ap_num);
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "############# [BTCoex], scan_ap_num = %d, wl_noisy = %d\n",
+ coex_sta->scan_ap_num, coex_sta->wl_noisy_level);
+
+ if ((wifi_busy) && (coex_sta->wl_noisy_level == 0))
+ wifi_turbo = true;
+
+ wifi_rssi_state = halbtc8822b2ant_wifi_rssi_state(
+ btcoexist, &prewifi_rssi_state, 2, coex_sta->wifi_coex_thres,
+ 0);
+
+ wifi_rssi_state2 = halbtc8822b2ant_wifi_rssi_state(
+ btcoexist, &prewifi_rssi_state2, 2, coex_sta->wifi_coex_thres2,
+ 0);
+
+ bt_rssi_state = halbtc8822b2ant_bt_rssi_state(
+ btcoexist, &pre_bt_rssi_state, 2, coex_sta->bt_coex_thres, 0);
+
+ bt_rssi_state2 = halbtc8822b2ant_bt_rssi_state(
+ btcoexist, &pre_bt_rssi_state2, 2, coex_sta->bt_coex_thres2, 0);
+
+ if (BTC_RSSI_HIGH(wifi_rssi_state) && BTC_RSSI_HIGH(bt_rssi_state)) {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+ halbtc8822b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0);
+
+ coex_dm->is_switch_to_1dot5_ant = false;
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
+ } else if (BTC_RSSI_HIGH(wifi_rssi_state2) &&
+ BTC_RSSI_HIGH(bt_rssi_state2)) {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xc8);
+ halbtc8822b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2);
+
+ coex_dm->is_switch_to_1dot5_ant = false;
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
+
+ if (wifi_busy)
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 3);
+ else
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 4);
+ } else {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+ halbtc8822b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0);
+
+ coex_dm->is_switch_to_1dot5_ant = true;
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 8);
+
+ if (wifi_busy)
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 103);
+ else
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 104);
+ }
+}
+
+static void halbtc8822b2ant_action_hid_a2dp(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW;
+ static u8 pre_bt_rssi_state = BTC_RSSI_STATE_LOW;
+ u8 wifi_rssi_state, bt_rssi_state;
+
+ static u8 prewifi_rssi_state2 = BTC_RSSI_STATE_LOW;
+ static u8 pre_bt_rssi_state2 = BTC_RSSI_STATE_LOW;
+ u8 wifi_rssi_state2, bt_rssi_state2;
+ bool wifi_busy = false;
+ u32 wifi_bw = 1;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+
+ wifi_rssi_state = halbtc8822b2ant_wifi_rssi_state(
+ btcoexist, &prewifi_rssi_state, 2, coex_sta->wifi_coex_thres,
+ 0);
+
+ wifi_rssi_state2 = halbtc8822b2ant_wifi_rssi_state(
+ btcoexist, &prewifi_rssi_state2, 2, coex_sta->wifi_coex_thres2,
+ 0);
+
+ bt_rssi_state = halbtc8822b2ant_bt_rssi_state(
+ btcoexist, &pre_bt_rssi_state, 2, coex_sta->bt_coex_thres, 0);
+
+ bt_rssi_state2 = halbtc8822b2ant_bt_rssi_state(
+ btcoexist, &pre_bt_rssi_state2, 2, coex_sta->bt_coex_thres2, 0);
+
+ if (BTC_RSSI_HIGH(wifi_rssi_state) && BTC_RSSI_HIGH(bt_rssi_state)) {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+ halbtc8822b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0);
+
+ coex_dm->is_switch_to_1dot5_ant = false;
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
+ } else if (BTC_RSSI_HIGH(wifi_rssi_state2) &&
+ BTC_RSSI_HIGH(bt_rssi_state2)) {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xc8);
+ halbtc8822b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2);
+
+ coex_dm->is_switch_to_1dot5_ant = false;
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
+
+ if (wifi_busy)
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 1);
+ else
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 16);
+ } else {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+ halbtc8822b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0);
+
+ coex_dm->is_switch_to_1dot5_ant = true;
+
+ if ((coex_sta->bt_relink_downcount != 0) && (wifi_busy)) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "############# [BTCoex], BT Re-Link + A2DP + WL busy\n");
+
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false,
+ 0);
+ halbtc8822b2ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 5);
+ } else {
+ halbtc8822b2ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 8);
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 109);
+ }
+ }
+}
+
+static void halbtc8822b2ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW;
+ static u8 pre_bt_rssi_state = BTC_RSSI_STATE_LOW;
+ u8 wifi_rssi_state, bt_rssi_state;
+
+ static u8 prewifi_rssi_state2 = BTC_RSSI_STATE_LOW;
+ static u8 pre_bt_rssi_state2 = BTC_RSSI_STATE_LOW;
+ u8 wifi_rssi_state2, bt_rssi_state2;
+ bool wifi_busy = false, wifi_turbo = false;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM,
+ &coex_sta->scan_ap_num);
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "############# [BTCoex], scan_ap_num = %d, wl_noisy = %d\n",
+ coex_sta->scan_ap_num, coex_sta->wl_noisy_level);
+
+ if ((wifi_busy) && (coex_sta->wl_noisy_level == 0))
+ wifi_turbo = true;
+
+ wifi_rssi_state = halbtc8822b2ant_wifi_rssi_state(
+ btcoexist, &prewifi_rssi_state, 2, coex_sta->wifi_coex_thres,
+ 0);
+
+ wifi_rssi_state2 = halbtc8822b2ant_wifi_rssi_state(
+ btcoexist, &prewifi_rssi_state2, 2, coex_sta->wifi_coex_thres2,
+ 0);
+
+ bt_rssi_state = halbtc8822b2ant_bt_rssi_state(
+ btcoexist, &pre_bt_rssi_state, 2, coex_sta->bt_coex_thres, 0);
+
+ bt_rssi_state2 = halbtc8822b2ant_bt_rssi_state(
+ btcoexist, &pre_bt_rssi_state2, 2, coex_sta->bt_coex_thres2, 0);
+
+ if (BTC_RSSI_HIGH(wifi_rssi_state) && BTC_RSSI_HIGH(bt_rssi_state)) {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+ /*halbtc8822b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0);*/
+
+ coex_dm->is_switch_to_1dot5_ant = false;
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
+ } else if (BTC_RSSI_HIGH(wifi_rssi_state2) &&
+ BTC_RSSI_HIGH(bt_rssi_state2)) {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xc8);
+ /*halbtc8822b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2);*/
+
+ coex_dm->is_switch_to_1dot5_ant = false;
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
+
+ if (wifi_busy) {
+ if ((coex_sta->a2dp_bit_pool > 40) &&
+ (coex_sta->a2dp_bit_pool < 255))
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
+ true, 7);
+ else
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
+ true, 5);
+ } else {
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 6);
+ }
+ } else {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+ /*halbtc8822b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0);*/
+
+ coex_dm->is_switch_to_1dot5_ant = true;
+
+ if (wifi_turbo)
+ halbtc8822b2ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 6);
+ else
+ halbtc8822b2ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 7);
+
+ if (wifi_busy) {
+ if ((coex_sta->a2dp_bit_pool > 40) &&
+ (coex_sta->a2dp_bit_pool < 255))
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
+ true, 107);
+ else
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
+ true, 105);
+ } else {
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 106);
+ }
+ }
+}
+
+/* PAN(EDR)+A2DP */
+static void halbtc8822b2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW;
+ static u8 pre_bt_rssi_state = BTC_RSSI_STATE_LOW;
+ u8 wifi_rssi_state, bt_rssi_state;
+
+ static u8 prewifi_rssi_state2 = BTC_RSSI_STATE_LOW;
+ static u8 pre_bt_rssi_state2 = BTC_RSSI_STATE_LOW;
+ u8 wifi_rssi_state2, bt_rssi_state2;
+ bool wifi_busy = false, wifi_turbo = false;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM,
+ &coex_sta->scan_ap_num);
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "############# [BTCoex], scan_ap_num = %d, wl_noisy = %d\n",
+ coex_sta->scan_ap_num, coex_sta->wl_noisy_level);
+
+ if ((wifi_busy) && (coex_sta->wl_noisy_level == 0))
+ wifi_turbo = true;
+
+ wifi_rssi_state = halbtc8822b2ant_wifi_rssi_state(
+ btcoexist, &prewifi_rssi_state, 2, coex_sta->wifi_coex_thres,
+ 0);
+
+ wifi_rssi_state2 = halbtc8822b2ant_wifi_rssi_state(
+ btcoexist, &prewifi_rssi_state2, 2, coex_sta->wifi_coex_thres2,
+ 0);
+
+ bt_rssi_state = halbtc8822b2ant_bt_rssi_state(
+ btcoexist, &pre_bt_rssi_state, 2, coex_sta->bt_coex_thres, 0);
+
+ bt_rssi_state2 = halbtc8822b2ant_bt_rssi_state(
+ btcoexist, &pre_bt_rssi_state2, 2, coex_sta->bt_coex_thres2, 0);
+
+ if (BTC_RSSI_HIGH(wifi_rssi_state) && BTC_RSSI_HIGH(bt_rssi_state)) {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+ halbtc8822b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0);
+
+ coex_dm->is_switch_to_1dot5_ant = false;
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
+ } else if (BTC_RSSI_HIGH(wifi_rssi_state2) &&
+ BTC_RSSI_HIGH(bt_rssi_state2)) {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xc8);
+ halbtc8822b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2);
+
+ coex_dm->is_switch_to_1dot5_ant = false;
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
+
+ if (wifi_busy) {
+ if (((coex_sta->a2dp_bit_pool > 40) &&
+ (coex_sta->a2dp_bit_pool < 255)) ||
+ (!coex_sta->is_A2DP_3M))
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
+ true, 7);
+ else
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
+ true, 5);
+ } else {
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 6);
+ }
+ } else {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+ halbtc8822b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0);
+
+ coex_dm->is_switch_to_1dot5_ant = true;
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 8);
+ if (wifi_busy)
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 107);
+ else
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 106);
+ }
+}
+
+static void halbtc8822b2ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
+{
+ static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW;
+ static u8 pre_bt_rssi_state = BTC_RSSI_STATE_LOW;
+ u8 wifi_rssi_state, bt_rssi_state;
+
+ static u8 prewifi_rssi_state2 = BTC_RSSI_STATE_LOW;
+ static u8 pre_bt_rssi_state2 = BTC_RSSI_STATE_LOW;
+ u8 wifi_rssi_state2, bt_rssi_state2;
+ bool wifi_busy = false;
+ u32 wifi_bw = 1;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+
+ wifi_rssi_state = halbtc8822b2ant_wifi_rssi_state(
+ btcoexist, &prewifi_rssi_state, 2, coex_sta->wifi_coex_thres,
+ 0);
+
+ wifi_rssi_state2 = halbtc8822b2ant_wifi_rssi_state(
+ btcoexist, &prewifi_rssi_state2, 2, coex_sta->wifi_coex_thres2,
+ 0);
+
+ bt_rssi_state = halbtc8822b2ant_bt_rssi_state(
+ btcoexist, &pre_bt_rssi_state, 2, coex_sta->bt_coex_thres, 0);
+
+ bt_rssi_state2 = halbtc8822b2ant_bt_rssi_state(
+ btcoexist, &pre_bt_rssi_state2, 2, coex_sta->bt_coex_thres2, 0);
+
+ if (BTC_RSSI_HIGH(wifi_rssi_state) && BTC_RSSI_HIGH(bt_rssi_state)) {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+ halbtc8822b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0);
+
+ coex_dm->is_switch_to_1dot5_ant = false;
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
+ } else if (BTC_RSSI_HIGH(wifi_rssi_state2) &&
+ BTC_RSSI_HIGH(bt_rssi_state2)) {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xc8);
+ halbtc8822b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2);
+
+ coex_dm->is_switch_to_1dot5_ant = false;
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
+
+ if (wifi_busy)
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 3);
+ else
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 4);
+ } else {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+ halbtc8822b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0);
+
+ coex_dm->is_switch_to_1dot5_ant = true;
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 8);
+
+ if (wifi_busy)
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 103);
+ else
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 104);
+ }
+}
+
+/* HID+A2DP+PAN(EDR) */
+static void
+halbtc8822b2ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
+{
+ static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW;
+ static u8 pre_bt_rssi_state = BTC_RSSI_STATE_LOW;
+ u8 wifi_rssi_state, bt_rssi_state;
+
+ static u8 prewifi_rssi_state2 = BTC_RSSI_STATE_LOW;
+ static u8 pre_bt_rssi_state2 = BTC_RSSI_STATE_LOW;
+ u8 wifi_rssi_state2, bt_rssi_state2;
+ bool wifi_busy = false;
+ u32 wifi_bw = 1;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+
+ wifi_rssi_state = halbtc8822b2ant_wifi_rssi_state(
+ btcoexist, &prewifi_rssi_state, 2, coex_sta->wifi_coex_thres,
+ 0);
+
+ wifi_rssi_state2 = halbtc8822b2ant_wifi_rssi_state(
+ btcoexist, &prewifi_rssi_state2, 2, coex_sta->wifi_coex_thres2,
+ 0);
+
+ bt_rssi_state = halbtc8822b2ant_bt_rssi_state(
+ btcoexist, &pre_bt_rssi_state, 2, coex_sta->bt_coex_thres, 0);
+
+ bt_rssi_state2 = halbtc8822b2ant_bt_rssi_state(
+ btcoexist, &pre_bt_rssi_state2, 2, coex_sta->bt_coex_thres2, 0);
+
+ if (BTC_RSSI_HIGH(wifi_rssi_state) && BTC_RSSI_HIGH(bt_rssi_state)) {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+
+ coex_dm->is_switch_to_1dot5_ant = false;
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
+ } else if (BTC_RSSI_HIGH(wifi_rssi_state2) &&
+ BTC_RSSI_HIGH(bt_rssi_state2)) {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xc8);
+
+ coex_dm->is_switch_to_1dot5_ant = false;
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
+
+ if (wifi_busy) {
+ if (((coex_sta->a2dp_bit_pool > 40) &&
+ (coex_sta->a2dp_bit_pool < 255)) ||
+ (!coex_sta->is_A2DP_3M))
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
+ true, 7);
+ else
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
+ true, 5);
+ } else {
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 6);
+ }
+ } else {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+
+ coex_dm->is_switch_to_1dot5_ant = true;
+
+ if (coex_sta->hid_busy_num >= 2) {
+ halbtc8822b2ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 8);
+
+ if (wifi_bw == 0) {
+ halbtc8822b2ant_set_wltoggle_coex_table(
+ btcoexist, NORMAL_EXEC, 0x1, 0xaa, 0x5a,
+ 0xaa, 0xaa);
+ } else {
+ halbtc8822b2ant_set_wltoggle_coex_table(
+ btcoexist, NORMAL_EXEC, 0x2, 0xaa, 0x5a,
+ 0xaa, 0xaa);
+ }
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 110);
+ } else {
+ halbtc8822b2ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 1);
+
+ if (wifi_busy) {
+ if ((coex_sta->a2dp_bit_pool > 40) &&
+ (coex_sta->a2dp_bit_pool < 255))
+ halbtc8822b2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 107);
+ else
+ halbtc8822b2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 105);
+ } else {
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
+ true, 106);
+ }
+ }
+ }
+}
+
+static void halbtc8822b2ant_action_bt_whck_test(struct btc_coexist *btcoexist)
+{
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
+}
+
+static void halbtc8822b2ant_action_bt_hs(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW;
+ static u8 pre_bt_rssi_state = BTC_RSSI_STATE_LOW;
+ u8 wifi_rssi_state, bt_rssi_state;
+
+ static u8 prewifi_rssi_state2 = BTC_RSSI_STATE_LOW;
+ static u8 pre_bt_rssi_state2 = BTC_RSSI_STATE_LOW;
+ u8 wifi_rssi_state2, bt_rssi_state2;
+ bool wifi_busy = false, wifi_turbo = false;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM,
+ &coex_sta->scan_ap_num);
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "############# [BTCoex], scan_ap_num = %d, wl_noisy = %d\n",
+ coex_sta->scan_ap_num, coex_sta->wl_noisy_level);
+
+ if ((wifi_busy) && (coex_sta->wl_noisy_level == 0))
+ wifi_turbo = true;
+
+ wifi_rssi_state = halbtc8822b2ant_wifi_rssi_state(
+ btcoexist, &prewifi_rssi_state, 2, coex_sta->wifi_coex_thres,
+ 0);
+
+ wifi_rssi_state2 = halbtc8822b2ant_wifi_rssi_state(
+ btcoexist, &prewifi_rssi_state2, 2, coex_sta->wifi_coex_thres2,
+ 0);
+
+ bt_rssi_state = halbtc8822b2ant_bt_rssi_state(
+ btcoexist, &pre_bt_rssi_state, 2, coex_sta->bt_coex_thres, 0);
+
+ bt_rssi_state2 = halbtc8822b2ant_bt_rssi_state(
+ btcoexist, &pre_bt_rssi_state2, 2, coex_sta->bt_coex_thres2, 0);
+
+ if (BTC_RSSI_HIGH(wifi_rssi_state) && BTC_RSSI_HIGH(bt_rssi_state)) {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+
+ coex_dm->is_switch_to_1dot5_ant = false;
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
+ } else if (BTC_RSSI_HIGH(wifi_rssi_state2) &&
+ BTC_RSSI_HIGH(bt_rssi_state2)) {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xc8);
+
+ coex_dm->is_switch_to_1dot5_ant = false;
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
+
+ } else {
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+
+ coex_dm->is_switch_to_1dot5_ant = true;
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
+ }
+}
+
+static void
+halbtc8822b2ant_action_wifi_multi_port(struct btc_coexist *btcoexist)
+{
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+
+ /* hw all off */
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
+}
+
+static void halbtc8822b2ant_action_wifi_connected(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ switch (coex_dm->cur_algorithm) {
+ case BT_8822B_2ANT_COEX_ALGO_SCO:
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action 2-Ant, algorithm = SCO.\n");
+ halbtc8822b2ant_action_sco(btcoexist);
+ break;
+ case BT_8822B_2ANT_COEX_ALGO_HID:
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action 2-Ant, algorithm = HID.\n");
+ halbtc8822b2ant_action_hid(btcoexist);
+ break;
+ case BT_8822B_2ANT_COEX_ALGO_A2DP:
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action 2-Ant, algorithm = A2DP.\n");
+ halbtc8822b2ant_action_a2dp(btcoexist);
+ break;
+ case BT_8822B_2ANT_COEX_ALGO_A2DPSINK:
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action 2-Ant, algorithm = A2DP Sink.\n");
+ halbtc8822b2ant_action_a2dpsink(btcoexist);
+ break;
+ case BT_8822B_2ANT_COEX_ALGO_A2DP_PANHS:
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action 2-Ant, algorithm = A2DP+PAN(HS).\n");
+ halbtc8822b2ant_action_a2dp_pan_hs(btcoexist);
+ break;
+ case BT_8822B_2ANT_COEX_ALGO_PANEDR:
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action 2-Ant, algorithm = PAN(EDR).\n");
+ halbtc8822b2ant_action_pan_edr(btcoexist);
+ break;
+ case BT_8822B_2ANT_COEX_ALGO_PANEDR_A2DP:
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action 2-Ant, algorithm = PAN+A2DP.\n");
+ halbtc8822b2ant_action_pan_edr_a2dp(btcoexist);
+ break;
+ case BT_8822B_2ANT_COEX_ALGO_PANEDR_HID:
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action 2-Ant, algorithm = PAN(EDR)+HID.\n");
+ halbtc8822b2ant_action_pan_edr_hid(btcoexist);
+ break;
+ case BT_8822B_2ANT_COEX_ALGO_HID_A2DP_PANEDR:
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action 2-Ant, algorithm = HID+A2DP+PAN.\n");
+ halbtc8822b2ant_action_hid_a2dp_pan_edr(btcoexist);
+ break;
+ case BT_8822B_2ANT_COEX_ALGO_HID_A2DP:
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action 2-Ant, algorithm = HID+A2DP.\n");
+ halbtc8822b2ant_action_hid_a2dp(btcoexist);
+ break;
+ case BT_8822B_2ANT_COEX_ALGO_NOPROFILEBUSY:
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action 2-Ant, algorithm = No-Profile busy.\n");
+ halbtc8822b2ant_action_bt_idle(btcoexist);
+ break;
+ default:
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action 2-Ant, algorithm = coexist All Off!!\n");
+ halbtc8822b2ant_action_coex_all_off(btcoexist);
+ break;
+ }
+
+ coex_dm->pre_algorithm = coex_dm->cur_algorithm;
+}
+
+static void halbtc8822b2ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ u8 algorithm = 0;
+ u32 num_of_wifi_link = 0;
+ u32 wifi_link_status = 0;
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+ bool miracast_plus_bt = false;
+ bool scan = false, link = false, roam = false, under_4way = false,
+ wifi_connected = false, wifi_under_5g = false, bt_hs_on = false;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS,
+ &under_4way);
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], RunCoexistMechanism()===>\n");
+
+ if (btcoexist->manual_control) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n");
+ return;
+ }
+
+ if (btcoexist->stop_coex_dm) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], RunCoexistMechanism(), return for Stop Coex DM <===\n");
+ return;
+ }
+
+ if (coex_sta->under_ips) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], wifi is under IPS !!!\n");
+ return;
+ }
+
+ if ((coex_sta->under_lps) &&
+ (coex_dm->bt_status != BT_8822B_2ANT_BT_STATUS_ACL_BUSY)) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], RunCoexistMechanism(), wifi is under LPS !!!\n");
+ halbtc8822b2ant_action_wifi_native_lps(btcoexist);
+ return;
+ }
+
+ if (!coex_sta->run_time_state) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], return for run_time_state = false !!!\n");
+ return;
+ }
+
+ if (coex_sta->freeze_coexrun_by_btinfo) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BtInfoNotify(), return for freeze_coexrun_by_btinfo\n");
+ return;
+ }
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
+
+ if ((wifi_under_5g) &&
+ (coex_sta->switch_band_notify_to != BTC_SWITCH_TO_24G) &&
+ (coex_sta->switch_band_notify_to != BTC_SWITCH_TO_24G_NOFORSCAN)) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], WiFi is under 5G!!!\n");
+
+ halbtc8822b2ant_action_wifi_under5g(btcoexist);
+ return;
+ }
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], WiFi is under 2G!!!\n");
+
+ halbtc8822b2ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO, NORMAL_EXEC,
+ BT_8822B_2ANT_PHASE_2G_RUNTIME);
+
+ if (coex_sta->bt_whck_test) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT is under WHCK TEST!!!\n");
+ halbtc8822b2ant_action_bt_whck_test(btcoexist);
+ return;
+ }
+
+ if (coex_sta->bt_disabled) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT is disabled!!!\n");
+ halbtc8822b2ant_action_coex_all_off(btcoexist);
+ return;
+ }
+
+ if (coex_sta->c2h_bt_inquiry_page) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT is under inquiry/page scan !!\n");
+ halbtc8822b2ant_action_bt_inquiry(btcoexist);
+ return;
+ }
+
+ if (coex_sta->is_setup_link) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT is re-link !!!\n");
+ halbtc8822b2ant_action_bt_relink(btcoexist);
+ return;
+ }
+
+ /* for P2P */
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS,
+ &wifi_link_status);
+ num_of_wifi_link = wifi_link_status >> 16;
+
+ if ((num_of_wifi_link >= 2) ||
+ (wifi_link_status & WIFI_P2P_GO_CONNECTED)) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "############# [BTCoex], Multi-Port num_of_wifi_link = %d, wifi_link_status = 0x%x\n",
+ num_of_wifi_link, wifi_link_status);
+
+ if (bt_link_info->bt_link_exist)
+ miracast_plus_bt = true;
+ else
+ miracast_plus_bt = false;
+
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_MIRACAST_PLUS_BT,
+ &miracast_plus_bt);
+
+ if (scan || link || roam || under_4way) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], scan = %d, link = %d, roam = %d 4way = %d!!!\n",
+ scan, link, roam, under_4way);
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], wifi is under linkscan process + Multi-Port !!\n");
+
+ halbtc8822b2ant_action_wifi_link_process(btcoexist);
+ } else {
+ halbtc8822b2ant_action_wifi_multi_port(btcoexist);
+ }
+
+ return;
+ }
+
+ miracast_plus_bt = false;
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_MIRACAST_PLUS_BT,
+ &miracast_plus_bt);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+
+ if (bt_hs_on) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "############# [BTCoex], BT Is hs\n");
+ halbtc8822b2ant_action_bt_hs(btcoexist);
+ return;
+ }
+
+ if ((BT_8822B_2ANT_BT_STATUS_NON_CONNECTED_IDLE ==
+ coex_dm->bt_status) ||
+ (coex_dm->bt_status == BT_8822B_2ANT_BT_STATUS_CONNECTED_IDLE)) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action 2-Ant, bt idle!!.\n");
+
+ halbtc8822b2ant_action_bt_idle(btcoexist);
+ return;
+ }
+
+ algorithm = halbtc8822b2ant_action_algorithm(btcoexist);
+ coex_dm->cur_algorithm = algorithm;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Algorithm = %d\n", coex_dm->cur_algorithm);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
+ &wifi_connected);
+
+ if (scan || link || roam || under_4way) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], WiFi is under Link Process !!\n");
+ halbtc8822b2ant_action_wifi_link_process(btcoexist);
+ } else if (wifi_connected) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action 2-Ant, wifi connected!!.\n");
+ halbtc8822b2ant_action_wifi_connected(btcoexist);
+
+ } else {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Action 2-Ant, wifi not-connected!!.\n");
+ halbtc8822b2ant_action_wifi_nonconnected(btcoexist);
+ }
+}
+
+static void halbtc8822b2ant_init_coex_dm(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Coex Mechanism Init!!\n");
+
+ halbtc8822b2ant_low_penalty_ra(btcoexist, NORMAL_EXEC, false);
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5);
+
+ /* fw all off */
+ halbtc8822b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
+
+ halbtc8822b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0xd8);
+
+ coex_sta->pop_event_cnt = 0;
+ coex_sta->cnt_remote_name_req = 0;
+ coex_sta->cnt_reinit = 0;
+ coex_sta->cnt_setup_link = 0;
+ coex_sta->cnt_ign_wlan_act = 0;
+ coex_sta->cnt_page = 0;
+ coex_sta->cnt_role_switch = 0;
+ coex_sta->switch_band_notify_to = BTC_NOT_SWITCH;
+
+ halbtc8822b2ant_query_bt_info(btcoexist);
+}
+
+static void halbtc8822b2ant_init_hw_config(struct btc_coexist *btcoexist,
+ bool wifi_only)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ u32 u32tmp1 = 0, u32tmp2 = 0, u32tmp3 = 0;
+ u32 RTL97F_8822B = 0;
+ u8 i = 0;
+
+ u32tmp3 = btcoexist->btc_read_4byte(btcoexist, 0xcb4);
+ u32tmp1 = halbtc8822b2ant_ltecoex_indirect_read_reg(btcoexist, 0x38);
+ u32tmp2 = halbtc8822b2ant_ltecoex_indirect_read_reg(btcoexist, 0x54);
+
+ if (RTL97F_8822B) {
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x66, 0x04, 0x0);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x41, 0x02, 0x0);
+
+ /* set GNT_BT to SW high */
+ halbtc8822b2ant_ltecoex_set_gnt_bt(
+ btcoexist, BT_8822B_2ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_2ANT_GNT_TYPE_CTRL_BY_SW,
+ BT_8822B_2ANT_SIG_STA_SET_TO_HIGH);
+ /* Set GNT_WL to SW high */
+ halbtc8822b2ant_ltecoex_set_gnt_wl(
+ btcoexist, BT_8822B_2ANT_GNT_BLOCK_RFC_BB,
+ BT_8822B_2ANT_GNT_TYPE_CTRL_BY_SW,
+ BT_8822B_2ANT_SIG_STA_SET_TO_HIGH);
+ return;
+ }
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], (Before Init HW config) 0xcb4 = 0x%x, 0x38= 0x%x, 0x54= 0x%x\n",
+ u32tmp3, u32tmp1, u32tmp2);
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], 2Ant Init HW Config!!\n");
+
+ coex_sta->bt_coex_supported_feature = 0;
+ coex_sta->bt_coex_supported_version = 0;
+ coex_sta->bt_ble_scan_type = 0;
+ coex_sta->bt_ble_scan_para[0] = 0;
+ coex_sta->bt_ble_scan_para[1] = 0;
+ coex_sta->bt_ble_scan_para[2] = 0;
+ coex_sta->bt_reg_vendor_ac = 0xffff;
+ coex_sta->bt_reg_vendor_ae = 0xffff;
+ coex_sta->isolation_btween_wb = BT_8822B_2ANT_DEFAULT_ISOLATION;
+ coex_sta->gnt_error_cnt = 0;
+ coex_sta->bt_relink_downcount = 0;
+ coex_sta->is_set_ps_state_fail = false;
+ coex_sta->cnt_set_ps_state_fail = 0;
+
+ for (i = 0; i <= 9; i++)
+ coex_sta->bt_afh_map[i] = 0;
+
+ /* 0xf0[15:12] --> Chip Cut information */
+ coex_sta->cut_version =
+ (btcoexist->btc_read_1byte(btcoexist, 0xf1) & 0xf0) >> 4;
+
+ coex_sta->dis_ver_info_cnt = 0;
+
+ halbtc8822b2ant_coex_switch_threshold(btcoexist,
+ coex_sta->isolation_btween_wb);
+
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x550, 0x8,
+ 0x1); /* enable TBTT nterrupt */
+
+ /* BT report packet sample rate */
+ btcoexist->btc_write_1byte(btcoexist, 0x790, 0x5);
+
+ /* Init 0x778 = 0x1 for 2-Ant */
+ btcoexist->btc_write_1byte(btcoexist, 0x778, 0x1);
+
+ /* Enable PTA (3-wire function form BT side) */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x41, 0x02, 0x1);
+
+ /* Enable PTA (tx/rx signal form WiFi side) */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x4c6, 0x10, 0x1);
+
+ halbtc8822b2ant_enable_gnt_to_gpio(btcoexist, true);
+
+ /*GNT_BT=1 while select both */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x763, 0x10, 0x1);
+
+ /* check if WL firmware download ok */
+ halbtc8822b2ant_post_state_to_bt(btcoexist,
+ BT_8822B_2ANT_SCOREBOARD_ONOFF, true);
+
+ /* Enable counter statistics */
+ btcoexist->btc_write_1byte(
+ btcoexist, 0x76e,
+ 0x4); /* 0x76e[3] =1, WLAN_Act control by PTA */
+
+ halbtc8822b2ant_coex_table_with_type(btcoexist, FORCE_EXEC, 5);
+
+ halbtc8822b2ant_ps_tdma(btcoexist, FORCE_EXEC, false, 0);
+
+ psd_scan->ant_det_is_ant_det_available = true;
+
+ if (coex_sta->is_rf_state_off) {
+ halbtc8822b2ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO,
+ FORCE_EXEC,
+ BT_8822B_2ANT_PHASE_WLAN_OFF);
+
+ btcoexist->stop_coex_dm = true;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** %s (RF Off)**********\n",
+ __func__);
+ } else if (wifi_only) {
+ coex_sta->concurrent_rx_mode_on = false;
+ /* Path config */
+ /* Set Antenna Path */
+ halbtc8822b2ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO,
+ FORCE_EXEC,
+ BT_8822B_2ANT_PHASE_WLANONLY_INIT);
+
+ btcoexist->stop_coex_dm = true;
+ } else {
+ /* Set BT polluted packet on for Tx rate adaptive not including
+ * Tx retry break by PTA, 0x45c[19] =1
+ */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x45e, 0x8, 0x1);
+
+ coex_sta->concurrent_rx_mode_on = true;
+
+ /* RF 0x1[1] = 0->Set GNT_WL_RF_Rx always = 1 for
+ * con-current Rx, mask Tx only
+ */
+ btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0x2, 0x0);
+
+ /* Set Antenna Path */
+ halbtc8822b2ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO,
+ FORCE_EXEC,
+ BT_8822B_2ANT_PHASE_COEX_INIT);
+
+ btcoexist->stop_coex_dm = false;
+ }
+}
+
+/* ************************************************************
+ * work around function start with wa_halbtc8822b2ant_
+ * ************************************************************
+ * ************************************************************
+ * extern function start with ex_halbtc8822b2ant_
+ * *************************************************************/
+void ex_btc8822b2ant_power_on_setting(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ struct btc_board_info *board_info = &btcoexist->board_info;
+ u8 u8tmp = 0x0;
+ u16 u16tmp = 0x0;
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "xxxxxxxxxxxxxxxx Execute 8822b 2-Ant PowerOn Setting xxxxxxxxxxxxxxxx!!\n");
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "Ant Det Finish = %s, Ant Det Number = %d\n",
+ (board_info->btdm_ant_det_finish ? "Yes" : "No"),
+ board_info->btdm_ant_num_by_ant_det);
+
+ btcoexist->dbg_mode_2ant = false;
+ btcoexist->stop_coex_dm = true;
+ psd_scan->ant_det_is_ant_det_available = false;
+
+ /* enable BB, REG_SYS_FUNC_EN such that we can write BB Reg correctly */
+ u16tmp = btcoexist->btc_read_2byte(btcoexist, 0x2);
+ btcoexist->btc_write_2byte(btcoexist, 0x2, u16tmp | BIT(0) | BIT(1));
+
+ /* Local setting bit define */
+ /* BIT0: "0" for no antenna inverse; "1" for antenna inverse */
+ /* BIT1: "0" for internal switch; "1" for external switch */
+ /* BIT2: "0" for one antenna; "1" for two antenna */
+ /* NOTE: here default all internal switch and 1-antenna ==>
+ * BIT1=0 and BIT2=0
+ */
+
+ /* Check efuse 0xc3[6] for Single Antenna Path */
+
+ /* Setup RF front end type */
+ halbtc8822b2ant_set_rfe_type(btcoexist);
+
+ /* Set Antenna Path to BT side */
+ halbtc8822b2ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO, FORCE_EXEC,
+ BT_8822B_2ANT_PHASE_COEX_POWERON);
+
+ /* Save"single antenna position" info in Local register setting for
+ * FW reading, because FW may not ready at power on
+ */
+ if (btcoexist->chip_interface == BTC_INTF_PCI)
+ btcoexist->btc_write_local_reg_1byte(btcoexist, 0x3e0, u8tmp);
+ else if (btcoexist->chip_interface == BTC_INTF_USB)
+ btcoexist->btc_write_local_reg_1byte(btcoexist, 0xfe08, u8tmp);
+ else if (btcoexist->chip_interface == BTC_INTF_SDIO)
+ btcoexist->btc_write_local_reg_1byte(btcoexist, 0x60, u8tmp);
+
+ /* enable GNT_WL/GNT_BT debug signal to GPIO14/15 */
+ halbtc8822b2ant_enable_gnt_to_gpio(btcoexist, true);
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** LTE coex Reg 0x38 (Power-On) = 0x%x**********\n",
+ halbtc8822b2ant_ltecoex_indirect_read_reg(btcoexist, 0x38));
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** MAC Reg 0x70/ BB Reg 0xcb4 (Power-On) = 0x%x / 0x%x\n",
+ btcoexist->btc_read_4byte(btcoexist, 0x70),
+ btcoexist->btc_read_4byte(btcoexist, 0xcb4));
+}
+
+void ex_btc8822b2ant_pre_load_firmware(struct btc_coexist *btcoexist)
+{
+ struct btc_board_info *board_info = &btcoexist->board_info;
+ u8 u8tmp = 0x4; /* Set BIT2 by default since it's 2ant case */
+
+ /* */
+ /* S0 or S1 setting and Local register setting
+ * (By the setting fw can get ant number, S0/S1, ... info)
+ */
+ /* Local setting bit define */
+ /* BIT0: "0" for no antenna inverse; "1" for antenna inverse */
+ /* BIT1: "0" for internal switch; "1" for external switch */
+ /* BIT2: "0" for one antenna; "1" for two antenna */
+ /* NOTE: here default all internal switch and 1-antenna ==>
+ * BIT1=0 and BIT2=0
+ */
+ if (btcoexist->chip_interface == BTC_INTF_USB) {
+ /* fixed at S0 for USB interface */
+ u8tmp |= 0x1; /* antenna inverse */
+ btcoexist->btc_write_local_reg_1byte(btcoexist, 0xfe08, u8tmp);
+ } else {
+ /* for PCIE and SDIO interface, we check efuse 0xc3[6] */
+ if (board_info->single_ant_path == 0) {
+ } else if (board_info->single_ant_path == 1) {
+ /* set to S0 */
+ u8tmp |= 0x1; /* antenna inverse */
+ }
+
+ if (btcoexist->chip_interface == BTC_INTF_PCI)
+ btcoexist->btc_write_local_reg_1byte(btcoexist, 0x3e0,
+ u8tmp);
+ else if (btcoexist->chip_interface == BTC_INTF_SDIO)
+ btcoexist->btc_write_local_reg_1byte(btcoexist, 0x60,
+ u8tmp);
+ }
+}
+
+void ex_btc8822b2ant_init_hw_config(struct btc_coexist *btcoexist,
+ bool wifi_only)
+{
+ halbtc8822b2ant_init_hw_config(btcoexist, wifi_only);
+ btcoexist->auto_report_2ant = true;
+}
+
+void ex_btc8822b2ant_init_coex_dm(struct btc_coexist *btcoexist)
+{
+ halbtc8822b2ant_init_coex_dm(btcoexist);
+}
+
+void ex_btc8822b2ant_display_coex_info(struct btc_coexist *btcoexist,
+ struct seq_file *m)
+{
+ struct btc_board_info *board_info = &btcoexist->board_info;
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+
+ u8 u8tmp[4], i, ps_tdma_case = 0;
+ u32 u32tmp[4];
+ u16 u16tmp[4];
+ u32 fa_ofdm, fa_cck, cca_ofdm, cca_cck, ratio_ofdm;
+ u32 fw_ver = 0, bt_patch_ver = 0, bt_coex_ver = 0;
+ static u8 pop_report_in_10s;
+ u32 phyver = 0;
+ bool lte_coex_on = false;
+ static u8 cnt;
+
+ seq_puts(m, "\r\n ============[BT Coexist info]============");
+
+ if (btcoexist->manual_control) {
+ seq_puts(m,
+ "\r\n ============[Under Manual Control]============");
+ seq_puts(m, "\r\n ==========================================");
+ }
+
+ if (!coex_sta->bt_disabled) {
+ if (coex_sta->bt_coex_supported_feature == 0)
+ btcoexist->btc_get(
+ btcoexist, BTC_GET_U4_SUPPORTED_FEATURE,
+ &coex_sta->bt_coex_supported_feature);
+
+ if ((coex_sta->bt_coex_supported_version == 0) ||
+ (coex_sta->bt_coex_supported_version == 0xffff))
+ btcoexist->btc_get(
+ btcoexist, BTC_GET_U4_SUPPORTED_VERSION,
+ &coex_sta->bt_coex_supported_version);
+
+ if (coex_sta->bt_reg_vendor_ac == 0xffff)
+ coex_sta->bt_reg_vendor_ac = (u16)(
+ btcoexist->btc_get_bt_reg(btcoexist, 3, 0xac) &
+ 0xffff);
+
+ if (coex_sta->bt_reg_vendor_ae == 0xffff)
+ coex_sta->bt_reg_vendor_ae = (u16)(
+ btcoexist->btc_get_bt_reg(btcoexist, 3, 0xae) &
+ 0xffff);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER,
+ &bt_patch_ver);
+ btcoexist->bt_info.bt_get_fw_ver = bt_patch_ver;
+
+ if (coex_sta->num_of_profile > 0) {
+ cnt++;
+
+ if (cnt >= 3) {
+ btcoexist->btc_get_bt_afh_map_from_bt(
+ btcoexist, 0, &coex_sta->bt_afh_map[0]);
+ cnt = 0;
+ }
+ }
+ }
+
+ if (psd_scan->ant_det_try_count == 0) {
+ seq_printf(
+ m, "\r\n %-35s = %d/ %d/ %s / %d",
+ "Ant PG Num/ Mech/ Pos/ RFE", board_info->pg_ant_num,
+ board_info->btdm_ant_num,
+ (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT ?
+ "Main" :
+ "Aux"),
+ rfe_type->rfe_module_type);
+ } else {
+ seq_printf(
+ m, "\r\n %-35s = %d/ %d/ %s/ %d (%d/%d/%d)",
+ "Ant PG Num/ Mech(Ant_Det)/ Pos/ RFE",
+ board_info->pg_ant_num,
+ board_info->btdm_ant_num_by_ant_det,
+ (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT ?
+ "Main" :
+ "Aux"),
+ rfe_type->rfe_module_type, psd_scan->ant_det_try_count,
+ psd_scan->ant_det_fail_count, psd_scan->ant_det_result);
+
+ if (board_info->btdm_ant_det_finish) {
+ if (psd_scan->ant_det_result != 12)
+ seq_printf(m, "\r\n %-35s = %s",
+ "Ant Det PSD Value",
+ psd_scan->ant_det_peak_val);
+ else
+ seq_printf(m, "\r\n %-35s = %d",
+ "Ant Det PSD Value",
+ psd_scan->ant_det_psd_scan_peak_val /
+ 100);
+ }
+ }
+
+ bt_patch_ver = btcoexist->bt_info.bt_get_fw_ver;
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
+ phyver = btcoexist->btc_get_bt_phydm_version(btcoexist);
+
+ bt_coex_ver = (coex_sta->bt_coex_supported_version & 0xff);
+
+ seq_printf(
+ m, "\r\n %-35s = %d_%02x/ 0x%02x/ 0x%02x (%s)",
+ "CoexVer WL/ BT_Desired/ BT_Report",
+ glcoex_ver_date_8822b_2ant, glcoex_ver_8822b_2ant,
+ glcoex_ver_btdesired_8822b_2ant, bt_coex_ver,
+ (bt_coex_ver == 0xff ?
+ "Unknown" :
+ (coex_sta->bt_disabled ? "BT-disable" :
+ (bt_coex_ver >= glcoex_ver_btdesired_8822b_2ant ?
+ "Match" :
+ "Mis-Match"))));
+
+ seq_printf(m, "\r\n %-35s = 0x%x/ 0x%x/ v%d/ %c", "W_FW/ B_FW/ Phy/ Kt",
+ fw_ver, bt_patch_ver, phyver, coex_sta->cut_version + 65);
+
+ seq_printf(m, "\r\n %-35s = %02x %02x %02x ", "AFH Map to BT",
+ coex_dm->wifi_chnl_info[0], coex_dm->wifi_chnl_info[1],
+ coex_dm->wifi_chnl_info[2]);
+
+ seq_printf(m, "\r\n %-35s = %d / %d / %d ",
+ "Isolation/WL_Thres/BT_Thres", coex_sta->isolation_btween_wb,
+ coex_sta->wifi_coex_thres, coex_sta->bt_coex_thres);
+
+ /* wifi status */
+ seq_printf(m, "\r\n %-35s", "============[Wifi Status]============");
+ btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_WIFI_STATUS, m);
+
+ seq_printf(m, "\r\n %-35s", "============[BT Status]============");
+
+ pop_report_in_10s++;
+ seq_printf(
+ m, "\r\n %-35s = [%s/ %d dBm/ %d/ %d] ",
+ "BT [status/ rssi/ retryCnt/ popCnt]",
+ ((coex_sta->bt_disabled) ?
+ ("disabled") :
+ ((coex_sta->c2h_bt_inquiry_page) ? ("inquiry/page") :
+ ((BT_8822B_2ANT_BT_STATUS_NON_CONNECTED_IDLE ==
+ coex_dm->bt_status) ?
+ "non-connected idle" :
+ ((coex_dm->bt_status ==
+ BT_8822B_2ANT_BT_STATUS_CONNECTED_IDLE) ?
+ "connected-idle" :
+ "busy")))),
+ coex_sta->bt_rssi - 100, coex_sta->bt_retry_cnt,
+ coex_sta->pop_event_cnt);
+
+ if (pop_report_in_10s >= 5) {
+ coex_sta->pop_event_cnt = 0;
+ pop_report_in_10s = 0;
+ }
+
+ if (coex_sta->num_of_profile != 0)
+ seq_printf(
+ m, "\r\n %-35s = %s%s%s%s%s", "Profiles",
+ ((bt_link_info->a2dp_exist) ?
+ ((coex_sta->is_bt_a2dp_sink) ? "A2DP sink," :
+ "A2DP,") :
+ ""),
+ ((bt_link_info->sco_exist) ? "HFP," : ""),
+ ((bt_link_info->hid_exist) ?
+ ((coex_sta->hid_busy_num >= 2) ?
+ "HID(4/18)," :
+ "HID(2/18),") :
+ ""),
+ ((bt_link_info->pan_exist) ? "PAN," : ""),
+ ((coex_sta->voice_over_HOGP) ? "Voice" : ""));
+ else
+ seq_printf(m, "\r\n %-35s = None", "Profiles");
+
+ if (bt_link_info->a2dp_exist) {
+ seq_printf(m, "\r\n %-35s = %s/ %d/ %s",
+ "A2DP Rate/Bitpool/Auto_Slot",
+ ((coex_sta->is_A2DP_3M) ? "3M" : "No_3M"),
+ coex_sta->a2dp_bit_pool,
+ ((coex_sta->is_autoslot) ? "On" : "Off"));
+ }
+
+ if (bt_link_info->hid_exist) {
+ seq_printf(m, "\r\n %-35s = %d/ %d", "HID PairNum/Forbid_Slot",
+ coex_sta->hid_pair_cnt, coex_sta->forbidden_slot);
+ }
+
+ seq_printf(m, "\r\n %-35s = %s/ %d/ %s/ 0x%x",
+ "Role/RoleSwCnt/IgnWlact/Feature",
+ ((bt_link_info->slave_role) ? "Slave" : "Master"),
+ coex_sta->cnt_role_switch,
+ ((coex_dm->cur_ignore_wlan_act) ? "Yes" : "No"),
+ coex_sta->bt_coex_supported_feature);
+
+ if ((coex_sta->bt_ble_scan_type & 0x7) != 0x0) {
+ seq_printf(m, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
+ "BLEScan Type/TV/Init/Ble",
+ coex_sta->bt_ble_scan_type,
+ (coex_sta->bt_ble_scan_type & 0x1 ?
+ coex_sta->bt_ble_scan_para[0] :
+ 0x0),
+ (coex_sta->bt_ble_scan_type & 0x2 ?
+ coex_sta->bt_ble_scan_para[1] :
+ 0x0),
+ (coex_sta->bt_ble_scan_type & 0x4 ?
+ coex_sta->bt_ble_scan_para[2] :
+ 0x0));
+ }
+
+ seq_printf(m, "\r\n %-35s = %d/ %d/ %d/ %d/ %d",
+ "ReInit/ReLink/IgnWlact/Page/NameReq", coex_sta->cnt_reinit,
+ coex_sta->cnt_setup_link, coex_sta->cnt_ign_wlan_act,
+ coex_sta->cnt_page, coex_sta->cnt_remote_name_req);
+
+ halbtc8822b2ant_read_score_board(btcoexist, &u16tmp[0]);
+
+ if ((coex_sta->bt_reg_vendor_ae == 0xffff) ||
+ (coex_sta->bt_reg_vendor_ac == 0xffff))
+ seq_printf(m, "\r\n %-35s = x/ x/ %04x",
+ "0xae[4]/0xac[1:0]/Scoreboard", u16tmp[0]);
+ else
+ seq_printf(m, "\r\n %-35s = 0x%x/ 0x%x/ %04x",
+ "0xae[4]/0xac[1:0]/Scoreboard",
+ (int)((coex_sta->bt_reg_vendor_ae & BIT(4)) >> 4),
+ coex_sta->bt_reg_vendor_ac & 0x3, u16tmp[0]);
+
+ if (coex_sta->num_of_profile > 0) {
+ seq_printf(
+ m,
+ "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
+ "AFH MAP", coex_sta->bt_afh_map[0],
+ coex_sta->bt_afh_map[1], coex_sta->bt_afh_map[2],
+ coex_sta->bt_afh_map[3], coex_sta->bt_afh_map[4],
+ coex_sta->bt_afh_map[5], coex_sta->bt_afh_map[6],
+ coex_sta->bt_afh_map[7], coex_sta->bt_afh_map[8],
+ coex_sta->bt_afh_map[9]);
+ }
+
+ for (i = 0; i < BT_INFO_SRC_8822B_2ANT_MAX; i++) {
+ if (coex_sta->bt_info_c2h_cnt[i]) {
+ seq_printf(
+ m,
+ "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)",
+ glbt_info_src_8822b_2ant[i],
+ coex_sta->bt_info_c2h[i][0],
+ coex_sta->bt_info_c2h[i][1],
+ coex_sta->bt_info_c2h[i][2],
+ coex_sta->bt_info_c2h[i][3],
+ coex_sta->bt_info_c2h[i][4],
+ coex_sta->bt_info_c2h[i][5],
+ coex_sta->bt_info_c2h[i][6],
+ coex_sta->bt_info_c2h_cnt[i]);
+ }
+ }
+
+ /* Sw mechanism */
+ if (btcoexist->manual_control)
+ seq_printf(
+ m, "\r\n %-35s",
+ "============[mechanism] (before Manual)============");
+ else
+ seq_printf(m, "\r\n %-35s",
+ "============[Mechanism]============");
+
+ ps_tdma_case = coex_dm->cur_ps_tdma;
+
+ seq_printf(m, "\r\n %-35s = %02x %02x %02x %02x %02x (case-%d, %s, %s)",
+ "TDMA", coex_dm->ps_tdma_para[0], coex_dm->ps_tdma_para[1],
+ coex_dm->ps_tdma_para[2], coex_dm->ps_tdma_para[3],
+ coex_dm->ps_tdma_para[4], ps_tdma_case,
+ (coex_dm->cur_ps_tdma_on ? "TDMA On" : "TDMA Off"),
+ (coex_dm->is_switch_to_1dot5_ant ? "1.5Ant" : "2Ant"));
+
+ u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0);
+ u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4);
+ u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8);
+ seq_printf(m, "\r\n %-35s = %d/ 0x%x/ 0x%x/ 0x%x",
+ "Table/0x6c0/0x6c4/0x6c8", coex_sta->coex_table_type,
+ u32tmp[0], u32tmp[1], u32tmp[2]);
+
+ u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778);
+ u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6cc);
+ seq_printf(m, "\r\n %-35s = 0x%x/ 0x%x", "0x778/0x6cc", u8tmp[0],
+ u32tmp[0]);
+
+ seq_printf(m, "\r\n %-35s = %s/ %s/ %s/ %d",
+ "AntDiv/BtCtrlLPS/LPRA/PsFail",
+ ((board_info->ant_div_cfg) ? "On" : "Off"),
+ ((coex_sta->force_lps_ctrl) ? "On" : "Off"),
+ ((coex_dm->cur_low_penalty_ra) ? "On" : "Off"),
+ coex_sta->cnt_set_ps_state_fail);
+
+ seq_printf(m, "\r\n %-35s = 0x%x/ 0x%x", "WL_DACSwing/ BT_Dec_Pwr",
+ coex_dm->cur_fw_dac_swing_lvl, coex_dm->cur_bt_dec_pwr_lvl);
+
+ u32tmp[0] = halbtc8822b2ant_ltecoex_indirect_read_reg(btcoexist, 0x38);
+ lte_coex_on = ((u32tmp[0] & BIT(7)) >> 7) ? true : false;
+
+ if (lte_coex_on) {
+ u32tmp[0] = halbtc8822b2ant_ltecoex_indirect_read_reg(btcoexist,
+ 0xa0);
+ u32tmp[1] = halbtc8822b2ant_ltecoex_indirect_read_reg(btcoexist,
+ 0xa4);
+ seq_printf(m, "\r\n %-35s = 0x%x/ 0x%x",
+ "LTE Coex Table W_L/B_L", u32tmp[0] & 0xffff,
+ u32tmp[1] & 0xffff);
+
+ u32tmp[0] = halbtc8822b2ant_ltecoex_indirect_read_reg(btcoexist,
+ 0xa8);
+ u32tmp[1] = halbtc8822b2ant_ltecoex_indirect_read_reg(btcoexist,
+ 0xac);
+ u32tmp[2] = halbtc8822b2ant_ltecoex_indirect_read_reg(btcoexist,
+ 0xb0);
+ u32tmp[3] = halbtc8822b2ant_ltecoex_indirect_read_reg(btcoexist,
+ 0xb4);
+ seq_printf(m, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
+ "LTE Break Table W_L/B_L/L_W/L_B",
+ u32tmp[0] & 0xffff, u32tmp[1] & 0xffff,
+ u32tmp[2] & 0xffff, u32tmp[3] & 0xffff);
+ }
+
+ /* Hw setting */
+ seq_printf(m, "\r\n %-35s", "============[Hw setting]============");
+
+ u32tmp[0] = halbtc8822b2ant_ltecoex_indirect_read_reg(btcoexist, 0x38);
+ u32tmp[1] = halbtc8822b2ant_ltecoex_indirect_read_reg(btcoexist, 0x54);
+ u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x73);
+
+ seq_printf(m, "\r\n %-35s = %s/ %s", "LTE Coex/Path Owner",
+ ((lte_coex_on) ? "On" : "Off"),
+ ((u8tmp[0] & BIT(2)) ? "WL" : "BT"));
+
+ if (lte_coex_on) {
+ seq_printf(m, "\r\n %-35s = %d/ %d/ %d/ %d",
+ "LTE 3Wire/OPMode/UART/UARTMode",
+ (int)((u32tmp[0] & BIT(6)) >> 6),
+ (int)((u32tmp[0] & (BIT(5) | BIT(4))) >> 4),
+ (int)((u32tmp[0] & BIT(3)) >> 3),
+ (int)(u32tmp[0] & (BIT(2) | BIT(1) | BIT(0))));
+
+ seq_printf(m, "\r\n %-35s = %d/ %d", "LTE_Busy/UART_Busy",
+ (int)((u32tmp[1] & BIT(1)) >> 1),
+ (int)(u32tmp[1] & BIT(0)));
+ }
+ seq_printf(m, "\r\n %-35s = %s (BB:%s)/ %s (BB:%s)/ %s %d",
+ "GNT_WL_Ctrl/GNT_BT_Ctrl/Dbg",
+ ((u32tmp[0] & BIT(12)) ? "SW" : "HW"),
+ ((u32tmp[0] & BIT(8)) ? "SW" : "HW"),
+ ((u32tmp[0] & BIT(14)) ? "SW" : "HW"),
+ ((u32tmp[0] & BIT(10)) ? "SW" : "HW"),
+ ((u8tmp[0] & BIT(3)) ? "On" : "Off"),
+ coex_sta->gnt_error_cnt);
+
+ seq_printf(m, "\r\n %-35s = %d/ %d", "GNT_WL/GNT_BT",
+ (int)((u32tmp[1] & BIT(2)) >> 2),
+ (int)((u32tmp[1] & BIT(3)) >> 3));
+
+ u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xcbc);
+ u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0xcb4);
+ u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xcba);
+
+ seq_printf(m, "\r\n %-35s = 0x%04x/ 0x%04x/ 0x%02x %s",
+ "0xcbc/0xcb4/0xcb8[23:16]", u32tmp[0], u32tmp[1], u8tmp[0],
+ ((u8tmp[0] & 0x1) == 0x1 ? "(BTG)" : "(WL_A+G)"));
+
+ u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c);
+ u8tmp[2] = btcoexist->btc_read_1byte(btcoexist, 0x64);
+ u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x4c6);
+ u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x40);
+
+ seq_printf(m, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
+ "4c[24:23]/64[0]/4c6[4]/40[5]",
+ (int)(u32tmp[0] & (BIT(24) | BIT(23))) >> 23, u8tmp[2] & 0x1,
+ (int)((u8tmp[0] & BIT(4)) >> 4),
+ (int)((u8tmp[1] & BIT(5)) >> 5));
+
+ u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550);
+ u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522);
+ u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x953);
+ u8tmp[2] = btcoexist->btc_read_1byte(btcoexist, 0xc50);
+
+ seq_printf(m, "\r\n %-35s = 0x%x/ 0x%x/ %s/ 0x%x",
+ "0x550/0x522/4-RxAGC/0xc50", u32tmp[0], u8tmp[0],
+ (u8tmp[1] & 0x2) ? "On" : "Off", u8tmp[2]);
+
+ fa_ofdm = btcoexist->btc_phydm_query_phy_counter(btcoexist,
+ "PHYDM_INFO_FA_OFDM");
+ fa_cck = btcoexist->btc_phydm_query_phy_counter(btcoexist,
+ "PHYDM_INFO_FA_CCK");
+ cca_ofdm = btcoexist->btc_phydm_query_phy_counter(
+ btcoexist, "PHYDM_INFO_CCA_OFDM");
+ cca_cck = btcoexist->btc_phydm_query_phy_counter(btcoexist,
+ "PHYDM_INFO_CCA_CCK");
+
+ ratio_ofdm = (fa_ofdm == 0) ? 1000 : (cca_ofdm / fa_ofdm);
+
+ seq_printf(m, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x (%d)",
+ "CCK-CCA/CCK-FA/OFDM-CCA/OFDM-FA", cca_cck, fa_cck, cca_ofdm,
+ fa_ofdm, ratio_ofdm);
+
+ seq_printf(m, "\r\n %-35s = %d/ %d/ %d/ %d", "CRC_OK CCK/11g/11n/11ac",
+ coex_sta->crc_ok_cck, coex_sta->crc_ok_11g,
+ coex_sta->crc_ok_11n, coex_sta->crc_ok_11n_vht);
+
+ seq_printf(m, "\r\n %-35s = %d/ %d/ %d/ %d (%d, %d)",
+ "CRC_Err CCK/11g/11n/11ac", coex_sta->crc_err_cck,
+ coex_sta->crc_err_11g, coex_sta->crc_err_11n,
+ coex_sta->crc_err_11n_vht, coex_sta->now_crc_ratio,
+ coex_sta->acc_crc_ratio);
+
+ seq_printf(m, "\r\n %-35s = %s/ %s/ %s/ %d",
+ "WlHiPri/ Locking/ Locked/ Noisy",
+ (coex_sta->wifi_is_high_pri_task ? "Yes" : "No"),
+ (coex_sta->cck_lock ? "Yes" : "No"),
+ (coex_sta->cck_ever_lock ? "Yes" : "No"),
+ coex_sta->wl_noisy_level);
+
+ seq_printf(m, "\r\n %-35s = %d/ %d", "0x770(Hi-pri rx/tx)",
+ coex_sta->high_priority_rx, coex_sta->high_priority_tx);
+
+ seq_printf(m, "\r\n %-35s = %d/ %d %s", "0x774(Lo-pri rx/tx)",
+ coex_sta->low_priority_rx, coex_sta->low_priority_tx,
+ (bt_link_info->slave_role ?
+ "(Slave!!)" :
+ (coex_sta->is_tdma_btautoslot_hang ?
+ "(auto-slot hang!!)" :
+ "")));
+
+ btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS, m);
+}
+
+void ex_btc8822b2ant_ips_notify(struct btc_coexist *btcoexist, u8 type)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ if (btcoexist->manual_control || btcoexist->stop_coex_dm)
+ return;
+
+ if (type == BTC_IPS_ENTER) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], IPS ENTER notify\n");
+ coex_sta->under_ips = true;
+ coex_sta->under_lps = false;
+
+ halbtc8822b2ant_post_state_to_bt(
+ btcoexist, BT_8822B_2ANT_SCOREBOARD_ACTIVE, false);
+
+ halbtc8822b2ant_post_state_to_bt(
+ btcoexist, BT_8822B_2ANT_SCOREBOARD_ONOFF, false);
+
+ halbtc8822b2ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO,
+ FORCE_EXEC,
+ BT_8822B_2ANT_PHASE_WLAN_OFF);
+
+ halbtc8822b2ant_action_coex_all_off(btcoexist);
+ } else if (type == BTC_IPS_LEAVE) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], IPS LEAVE notify\n");
+ coex_sta->under_ips = false;
+
+ halbtc8822b2ant_post_state_to_bt(
+ btcoexist, BT_8822B_2ANT_SCOREBOARD_ACTIVE, true);
+ halbtc8822b2ant_post_state_to_bt(
+ btcoexist, BT_8822B_2ANT_SCOREBOARD_ONOFF, true);
+ halbtc8822b2ant_init_hw_config(btcoexist, false);
+ halbtc8822b2ant_init_coex_dm(btcoexist);
+ halbtc8822b2ant_query_bt_info(btcoexist);
+ }
+}
+
+void ex_btc8822b2ant_lps_notify(struct btc_coexist *btcoexist, u8 type)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ static bool pre_force_lps_on;
+
+ if (btcoexist->manual_control || btcoexist->stop_coex_dm)
+ return;
+
+ if (type == BTC_LPS_ENABLE) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], LPS ENABLE notify\n");
+ coex_sta->under_lps = true;
+ coex_sta->under_ips = false;
+
+ if (coex_sta->force_lps_ctrl) { /* LPS No-32K */
+ /* Write WL "Active" in Score-board for PS-TDMA */
+ pre_force_lps_on = true;
+ halbtc8822b2ant_post_state_to_bt(
+ btcoexist, BT_8822B_2ANT_SCOREBOARD_ACTIVE,
+ true);
+
+ } else {
+ /* LPS-32K, need check if this h2c 0x71 can work??
+ * (2015/08/28)
+ */
+ /* Write WL "Non-Active" in Score-board for Native-PS */
+ pre_force_lps_on = false;
+ halbtc8822b2ant_post_state_to_bt(
+ btcoexist, BT_8822B_2ANT_SCOREBOARD_ACTIVE,
+ false);
+ }
+
+ } else if (type == BTC_LPS_DISABLE) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], LPS DISABLE notify\n");
+ coex_sta->under_lps = false;
+
+ halbtc8822b2ant_post_state_to_bt(
+ btcoexist, BT_8822B_2ANT_SCOREBOARD_ACTIVE, true);
+
+ if ((!pre_force_lps_on) && (!coex_sta->force_lps_ctrl))
+ halbtc8822b2ant_query_bt_info(btcoexist);
+ }
+}
+
+void ex_btc8822b2ant_scan_notify(struct btc_coexist *btcoexist, u8 type)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ bool wifi_connected = false;
+ bool wifi_under_5g = false;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], SCAN notify()\n");
+
+ halbtc8822b2ant_post_state_to_bt(btcoexist,
+ BT_8822B_2ANT_SCOREBOARD_ACTIVE, true);
+
+ if (btcoexist->manual_control || btcoexist->stop_coex_dm)
+ return;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
+ &wifi_connected);
+
+ /* this can't be removed for RF off_on event, or BT would dis-connect */
+ halbtc8822b2ant_query_bt_info(btcoexist);
+
+ if (type == BTC_SCAN_START) {
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G,
+ &wifi_under_5g);
+
+ if (wifi_under_5g) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** SCAN START notify (5g)\n");
+
+ halbtc8822b2ant_action_wifi_under5g(btcoexist);
+ return;
+ }
+
+ coex_sta->wifi_is_high_pri_task = true;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** SCAN START notify (2g)\n");
+
+ halbtc8822b2ant_run_coexist_mechanism(btcoexist);
+
+ return;
+ }
+
+ if (type == BTC_SCAN_START_2G) {
+ if (!wifi_connected)
+ coex_sta->wifi_is_high_pri_task = true;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], SCAN START notify (2G)\n");
+
+ halbtc8822b2ant_post_state_to_bt(
+ btcoexist, BT_8822B_2ANT_SCOREBOARD_SCAN, true);
+ halbtc8822b2ant_post_state_to_bt(
+ btcoexist, BT_8822B_2ANT_SCOREBOARD_ACTIVE, true);
+
+ halbtc8822b2ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO,
+ FORCE_EXEC,
+ BT_8822B_2ANT_PHASE_2G_RUNTIME);
+
+ halbtc8822b2ant_run_coexist_mechanism(btcoexist);
+
+ } else if (type == BTC_SCAN_FINISH) {
+ coex_sta->wifi_is_high_pri_task = false;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM,
+ &coex_sta->scan_ap_num);
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], SCAN FINISH notify (Scan-AP = %d)\n",
+ coex_sta->scan_ap_num);
+
+ halbtc8822b2ant_post_state_to_bt(
+ btcoexist, BT_8822B_2ANT_SCOREBOARD_SCAN, false);
+
+ halbtc8822b2ant_run_coexist_mechanism(btcoexist);
+ }
+}
+
+void ex_btc8822b2ant_switchband_notify(struct btc_coexist *btcoexist, u8 type)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ if (btcoexist->manual_control || btcoexist->stop_coex_dm)
+ return;
+ coex_sta->switch_band_notify_to = type;
+
+ if (type == BTC_SWITCH_TO_5G) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], switchband_notify --- switch to 5G\n");
+
+ halbtc8822b2ant_action_wifi_under5g(btcoexist);
+
+ } else if (type == BTC_SWITCH_TO_24G_NOFORSCAN) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ********** switchband_notify BTC_SWITCH_TO_2G (no for scan)\n");
+
+ halbtc8822b2ant_run_coexist_mechanism(btcoexist);
+
+ } else {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], switchband_notify --- switch to 2G\n");
+
+ ex_btc8822b2ant_scan_notify(btcoexist, BTC_SCAN_START_2G);
+ }
+ coex_sta->switch_band_notify_to = BTC_NOT_SWITCH;
+}
+
+void ex_btc8822b2ant_connect_notify(struct btc_coexist *btcoexist, u8 type)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ halbtc8822b2ant_post_state_to_bt(btcoexist,
+ BT_8822B_2ANT_SCOREBOARD_ACTIVE, true);
+ if (btcoexist->manual_control || btcoexist->stop_coex_dm)
+ return;
+
+ if ((type == BTC_ASSOCIATE_5G_START) ||
+ (type == BTC_ASSOCIATE_5G_FINISH)) {
+ if (type == BTC_ASSOCIATE_5G_START)
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], connect_notify --- 5G start\n");
+ else
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], connect_notify --- 5G finish\n");
+
+ halbtc8822b2ant_action_wifi_under5g(btcoexist);
+ return;
+ }
+
+ if (type == BTC_ASSOCIATE_START) {
+ coex_sta->wifi_is_high_pri_task = true;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], CONNECT START notify (2G)\n");
+
+ halbtc8822b2ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO,
+ FORCE_EXEC,
+ BT_8822B_2ANT_PHASE_2G_RUNTIME);
+
+ halbtc8822b2ant_action_wifi_link_process(btcoexist);
+
+ /* To keep TDMA case during connect process,
+ * to avoid changed by Btinfo and runcoexmechanism
+ */
+ coex_sta->freeze_coexrun_by_btinfo = true;
+
+ coex_dm->arp_cnt = 0;
+
+ } else if (type == BTC_ASSOCIATE_FINISH) {
+ coex_sta->wifi_is_high_pri_task = false;
+ coex_sta->freeze_coexrun_by_btinfo = false;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], CONNECT FINISH notify (2G)\n");
+
+ halbtc8822b2ant_run_coexist_mechanism(btcoexist);
+ }
+}
+
+void ex_btc8822b2ant_media_status_notify(struct btc_coexist *btcoexist, u8 type)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ bool wifi_under_b_mode = false, wifi_under_5g = false;
+
+ if (btcoexist->manual_control || btcoexist->stop_coex_dm)
+ return;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
+
+ if (type == BTC_MEDIA_CONNECT) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], MEDIA connect notify\n");
+
+ halbtc8822b2ant_post_state_to_bt(
+ btcoexist, BT_8822B_2ANT_SCOREBOARD_ACTIVE, true);
+
+ if (wifi_under_5g) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], WiFi is under 5G!!!\n");
+
+ halbtc8822b2ant_action_wifi_under5g(btcoexist);
+ return;
+ }
+
+ halbtc8822b2ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO,
+ FORCE_EXEC,
+ BT_8822B_2ANT_PHASE_2G_RUNTIME);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_B_MODE,
+ &wifi_under_b_mode);
+
+ /* Set CCK Tx/Rx high Pri except 11b mode */
+ if (wifi_under_b_mode) {
+ btcoexist->btc_write_1byte(btcoexist, 0x6cd,
+ 0x00); /* CCK Tx */
+ btcoexist->btc_write_1byte(btcoexist, 0x6cf,
+ 0x00); /* CCK Rx */
+ } else {
+ btcoexist->btc_write_1byte(btcoexist, 0x6cd,
+ 0x00); /* CCK Tx */
+ btcoexist->btc_write_1byte(btcoexist, 0x6cf,
+ 0x10); /* CCK Rx */
+ }
+
+ } else {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], MEDIA disconnect notify\n");
+
+ btcoexist->btc_write_1byte(btcoexist, 0x6cd, 0x0); /* CCK Tx */
+ btcoexist->btc_write_1byte(btcoexist, 0x6cf, 0x0); /* CCK Rx */
+
+ halbtc8822b2ant_post_state_to_bt(
+ btcoexist, BT_8822B_2ANT_SCOREBOARD_ACTIVE, false);
+ }
+
+ halbtc8822b2ant_update_wifi_ch_info(btcoexist, type);
+}
+
+void ex_btc8822b2ant_specific_packet_notify(struct btc_coexist *btcoexist,
+ u8 type)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ bool under_4way = false, wifi_under_5g = false;
+
+ if (btcoexist->manual_control || btcoexist->stop_coex_dm)
+ return;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
+
+ if (wifi_under_5g) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], WiFi is under 5G!!!\n");
+
+ halbtc8822b2ant_action_wifi_under5g(btcoexist);
+ return;
+ }
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS,
+ &under_4way);
+
+ if (under_4way) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], specific Packet ---- under_4way!!\n");
+
+ coex_sta->wifi_is_high_pri_task = true;
+ coex_sta->specific_pkt_period_cnt = 2;
+
+ } else if (type == BTC_PACKET_ARP) {
+ coex_dm->arp_cnt++;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], specific Packet ARP notify -cnt = %d\n",
+ coex_dm->arp_cnt);
+
+ } else {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], specific Packet DHCP or EAPOL notify [Type = %d]\n",
+ type);
+
+ coex_sta->wifi_is_high_pri_task = true;
+ coex_sta->specific_pkt_period_cnt = 2;
+ }
+
+ if (coex_sta->wifi_is_high_pri_task)
+ halbtc8822b2ant_run_coexist_mechanism(btcoexist);
+}
+
+void ex_btc8822b2ant_bt_info_notify(struct btc_coexist *btcoexist, u8 *tmp_buf,
+ u8 length)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ u8 i, rsp_source = 0;
+ bool wifi_connected = false;
+ bool wifi_scan = false, wifi_link = false, wifi_roam = false,
+ wifi_busy = false;
+ static bool is_scoreboard_scan;
+
+ rsp_source = tmp_buf[0] & 0xf;
+ if (rsp_source >= BT_INFO_SRC_8822B_2ANT_MAX)
+ rsp_source = BT_INFO_SRC_8822B_2ANT_WIFI_FW;
+ coex_sta->bt_info_c2h_cnt[rsp_source]++;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Bt_info[%d], len=%d, data=[", rsp_source, length);
+
+ for (i = 0; i < length; i++) {
+ coex_sta->bt_info_c2h[rsp_source][i] = tmp_buf[i];
+
+ if (i == length - 1) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "0x%02x]\n", tmp_buf[i]);
+ } else {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, "0x%02x, ",
+ tmp_buf[i]);
+ }
+ }
+
+ coex_sta->bt_info = coex_sta->bt_info_c2h[rsp_source][1];
+ coex_sta->bt_info_ext = coex_sta->bt_info_c2h[rsp_source][4];
+ coex_sta->bt_info_ext2 = coex_sta->bt_info_c2h[rsp_source][5];
+
+ if (rsp_source != BT_INFO_SRC_8822B_2ANT_WIFI_FW) {
+ /* if 0xff, it means BT is under WHCK test */
+ coex_sta->bt_whck_test =
+ ((coex_sta->bt_info == 0xff) ? true : false);
+
+ coex_sta->bt_create_connection =
+ ((coex_sta->bt_info_c2h[rsp_source][2] & 0x80) ? true :
+ false);
+
+ /* unit: %, value-100 to translate to unit: dBm */
+ coex_sta->bt_rssi =
+ coex_sta->bt_info_c2h[rsp_source][3] * 2 + 10;
+
+ coex_sta->c2h_bt_remote_name_req =
+ ((coex_sta->bt_info_c2h[rsp_source][2] & 0x20) ? true :
+ false);
+
+ coex_sta->is_A2DP_3M =
+ ((coex_sta->bt_info_c2h[rsp_source][2] & 0x10) ? true :
+ false);
+
+ coex_sta->acl_busy =
+ ((coex_sta->bt_info_c2h[rsp_source][1] & 0x9) ? true :
+ false);
+
+ coex_sta->voice_over_HOGP =
+ ((coex_sta->bt_info_ext & 0x10) ? true : false);
+
+ coex_sta->c2h_bt_inquiry_page =
+ ((coex_sta->bt_info & BT_INFO_8822B_2ANT_B_INQ_PAGE) ?
+ true :
+ false);
+
+ coex_sta->a2dp_bit_pool =
+ (((coex_sta->bt_info_c2h[rsp_source][1] & 0x49) ==
+ 0x49) ?
+ (coex_sta->bt_info_c2h[rsp_source][6] & 0x7f) :
+ 0);
+
+ coex_sta->is_bt_a2dp_sink =
+ (coex_sta->bt_info_c2h[rsp_source][6] & 0x80) ? true :
+ false;
+
+ coex_sta->bt_retry_cnt =
+ coex_sta->bt_info_c2h[rsp_source][2] & 0xf;
+
+ coex_sta->is_autoslot = coex_sta->bt_info_ext2 & 0x8;
+
+ coex_sta->forbidden_slot = coex_sta->bt_info_ext2 & 0x7;
+
+ coex_sta->hid_busy_num = (coex_sta->bt_info_ext2 & 0x30) >> 4;
+
+ coex_sta->hid_pair_cnt = (coex_sta->bt_info_ext2 & 0xc0) >> 6;
+
+ if (coex_sta->bt_retry_cnt >= 1)
+ coex_sta->pop_event_cnt++;
+
+ if (coex_sta->c2h_bt_remote_name_req)
+ coex_sta->cnt_remote_name_req++;
+
+ if (coex_sta->bt_info_ext & BIT(1))
+ coex_sta->cnt_reinit++;
+
+ if (coex_sta->bt_info_ext & BIT(2)) {
+ coex_sta->cnt_setup_link++;
+ coex_sta->is_setup_link = true;
+ coex_sta->bt_relink_downcount = 2;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Re-Link start in BT info!!\n");
+ } else {
+ coex_sta->is_setup_link = false;
+ coex_sta->bt_relink_downcount = 0;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Re-Link stop in BT info!!\n");
+ }
+
+ if (coex_sta->bt_info_ext & BIT(3))
+ coex_sta->cnt_ign_wlan_act++;
+
+ if (coex_sta->bt_info_ext & BIT(6))
+ coex_sta->cnt_role_switch++;
+
+ if (coex_sta->bt_info_ext & BIT(7))
+ coex_sta->is_bt_multi_link = true;
+ else
+ coex_sta->is_bt_multi_link = false;
+
+ if (coex_sta->bt_create_connection) {
+ coex_sta->cnt_page++;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY,
+ &wifi_busy);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN,
+ &wifi_scan);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK,
+ &wifi_link);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM,
+ &wifi_roam);
+
+ if ((wifi_link) || (wifi_roam) || (wifi_scan) ||
+ (coex_sta->wifi_is_high_pri_task) || (wifi_busy)) {
+ is_scoreboard_scan = true;
+ halbtc8822b2ant_post_state_to_bt(
+ btcoexist,
+ BT_8822B_2ANT_SCOREBOARD_SCAN, true);
+
+ } else {
+ halbtc8822b2ant_post_state_to_bt(
+ btcoexist,
+ BT_8822B_2ANT_SCOREBOARD_SCAN, false);
+ }
+ } else {
+ if (is_scoreboard_scan) {
+ halbtc8822b2ant_post_state_to_bt(
+ btcoexist,
+ BT_8822B_2ANT_SCOREBOARD_SCAN, false);
+ is_scoreboard_scan = false;
+ }
+ }
+
+ /* Here we need to resend some wifi info to BT */
+ /* because bt is reset and loss of the info. */
+
+ if ((!btcoexist->manual_control) &&
+ (!btcoexist->stop_coex_dm)) {
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
+ &wifi_connected);
+
+ /* Re-Init */
+ if ((coex_sta->bt_info_ext & BIT(1))) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n");
+ if (wifi_connected)
+ halbtc8822b2ant_update_wifi_ch_info(
+ btcoexist, BTC_MEDIA_CONNECT);
+ else
+ halbtc8822b2ant_update_wifi_ch_info(
+ btcoexist,
+ BTC_MEDIA_DISCONNECT);
+ }
+
+ /* If Ignore_WLanAct && not SetUp_Link */
+ if ((coex_sta->bt_info_ext & BIT(3)) &&
+ (!(coex_sta->bt_info_ext & BIT(2))) &&
+ (!(coex_sta->bt_info_ext & BIT(6)))) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n");
+ halbtc8822b2ant_ignore_wlan_act(
+ btcoexist, FORCE_EXEC, false);
+ } else {
+ if (coex_sta->bt_info_ext & BIT(2)) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], BT ignore Wlan active because Re-link!!\n");
+ } else if (coex_sta->bt_info_ext & BIT(6)) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], BT ignore Wlan active because Role-Switch!!\n");
+ }
+ }
+ }
+ }
+
+ if ((coex_sta->bt_info_ext & BIT(5))) {
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT ext info bit4 check, query BLE Scan type!!\n");
+ coex_sta->bt_ble_scan_type =
+ btcoexist->btc_get_ble_scan_type_from_bt(btcoexist);
+
+ if ((coex_sta->bt_ble_scan_type & 0x1) == 0x1)
+ coex_sta->bt_ble_scan_para[0] =
+ btcoexist->btc_get_ble_scan_para_from_bt(
+ btcoexist, 0x1);
+ if ((coex_sta->bt_ble_scan_type & 0x2) == 0x2)
+ coex_sta->bt_ble_scan_para[1] =
+ btcoexist->btc_get_ble_scan_para_from_bt(
+ btcoexist, 0x2);
+ if ((coex_sta->bt_ble_scan_type & 0x4) == 0x4)
+ coex_sta->bt_ble_scan_para[2] =
+ btcoexist->btc_get_ble_scan_para_from_bt(
+ btcoexist, 0x4);
+ }
+
+ halbtc8822b2ant_update_bt_link_info(btcoexist);
+
+ halbtc8822b2ant_run_coexist_mechanism(btcoexist);
+}
+
+void ex_btc8822b2ant_rf_status_notify(struct btc_coexist *btcoexist, u8 type)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], RF Status notify\n");
+
+ if (type == BTC_RF_ON) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], RF is turned ON!!\n");
+
+ btcoexist->stop_coex_dm = false;
+ coex_sta->is_rf_state_off = false;
+ } else if (type == BTC_RF_OFF) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], RF is turned OFF!!\n");
+
+ halbtc8822b2ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO,
+ FORCE_EXEC,
+ BT_8822B_2ANT_PHASE_WLAN_OFF);
+
+ halbtc8822b2ant_action_coex_all_off(btcoexist);
+
+ halbtc8822b2ant_post_state_to_bt(
+ btcoexist, BT_8822B_2ANT_SCOREBOARD_ACTIVE |
+ BT_8822B_2ANT_SCOREBOARD_ONOFF |
+ BT_8822B_2ANT_SCOREBOARD_SCAN |
+ BT_8822B_2ANT_SCOREBOARD_UNDERTEST,
+ false);
+
+ btcoexist->stop_coex_dm = true;
+ coex_sta->is_rf_state_off = true;
+ }
+}
+
+void ex_btc8822b2ant_halt_notify(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, "[BTCoex], Halt notify\n");
+
+ halbtc8822b2ant_set_ant_path(btcoexist, BTC_ANT_PATH_AUTO, FORCE_EXEC,
+ BT_8822B_2ANT_PHASE_WLAN_OFF);
+
+ ex_btc8822b2ant_media_status_notify(btcoexist, BTC_MEDIA_DISCONNECT);
+
+ halbtc8822b2ant_post_state_to_bt(
+ btcoexist, BT_8822B_2ANT_SCOREBOARD_ACTIVE, false);
+ halbtc8822b2ant_post_state_to_bt(btcoexist,
+ BT_8822B_2ANT_SCOREBOARD_ONOFF, false);
+}
+
+void ex_btc8822b2ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ bool wifi_under_5g = false;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, "[BTCoex], Pnp notify\n");
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
+
+ if ((pnp_state == BTC_WIFI_PNP_SLEEP) ||
+ (pnp_state == BTC_WIFI_PNP_SLEEP_KEEP_ANT)) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Pnp notify to SLEEP\n");
+
+ /* Sinda 20150819, workaround for driver skip leave IPS/LPS to
+ * speed up sleep time.
+ * Driver do not leave IPS/LPS when driver is going to sleep,
+ * so BTCoexistence think wifi is still under IPS/LPS.
+ * BT should clear UnderIPS/UnderLPS state to avoid mismatch
+ * state after wakeup.
+ */
+ coex_sta->under_ips = false;
+ coex_sta->under_lps = false;
+
+ halbtc8822b2ant_post_state_to_bt(
+ btcoexist, BT_8822B_2ANT_SCOREBOARD_ACTIVE, false);
+ halbtc8822b2ant_post_state_to_bt(
+ btcoexist, BT_8822B_2ANT_SCOREBOARD_ONOFF, false);
+
+ if (pnp_state == BTC_WIFI_PNP_SLEEP_KEEP_ANT) {
+ if (wifi_under_5g)
+ halbtc8822b2ant_set_ant_path(
+ btcoexist, BTC_ANT_PATH_AUTO,
+ FORCE_EXEC,
+ BT_8822B_2ANT_PHASE_5G_RUNTIME);
+ else
+ halbtc8822b2ant_set_ant_path(
+ btcoexist, BTC_ANT_PATH_AUTO,
+ FORCE_EXEC,
+ BT_8822B_2ANT_PHASE_2G_RUNTIME);
+ } else {
+ halbtc8822b2ant_set_ant_path(
+ btcoexist, BTC_ANT_PATH_AUTO, FORCE_EXEC,
+ BT_8822B_2ANT_PHASE_WLAN_OFF);
+ }
+ } else if (pnp_state == BTC_WIFI_PNP_WAKE_UP) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Pnp notify to WAKE UP\n");
+
+ halbtc8822b2ant_post_state_to_bt(
+ btcoexist, BT_8822B_2ANT_SCOREBOARD_ACTIVE, true);
+ halbtc8822b2ant_post_state_to_bt(
+ btcoexist, BT_8822B_2ANT_SCOREBOARD_ONOFF, true);
+ }
+}
+
+void ex_btc8822b2ant_periodical(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ bool wifi_busy = false;
+ u16 bt_scoreboard_val = 0;
+ bool bt_relink_finish = false;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ************* Periodical *************\n");
+
+ if (!btcoexist->auto_report_2ant)
+ halbtc8822b2ant_query_bt_info(btcoexist);
+
+ halbtc8822b2ant_monitor_bt_ctr(btcoexist);
+ halbtc8822b2ant_monitor_wifi_ctr(btcoexist);
+ halbtc8822b2ant_monitor_bt_enable_disable(btcoexist);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+ halbtc8822b2ant_read_score_board(btcoexist, &bt_scoreboard_val);
+
+ if (wifi_busy) {
+ halbtc8822b2ant_post_state_to_bt(
+ btcoexist, BT_8822B_2ANT_SCOREBOARD_UNDERTEST, true);
+ /*for bt lps32 clock offset*/
+ if (bt_scoreboard_val & BIT(6))
+ halbtc8822b2ant_query_bt_info(btcoexist);
+ } else {
+ halbtc8822b2ant_post_state_to_bt(
+ btcoexist, BT_8822B_2ANT_SCOREBOARD_UNDERTEST, false);
+ }
+
+ if (coex_sta->bt_relink_downcount != 0) {
+ coex_sta->bt_relink_downcount--;
+
+ if (coex_sta->bt_relink_downcount == 0) {
+ coex_sta->is_setup_link = false;
+ bt_relink_finish = true;
+ }
+ }
+
+ /* for 4-way, DHCP, EAPOL packet */
+ if (coex_sta->specific_pkt_period_cnt > 0) {
+ coex_sta->specific_pkt_period_cnt--;
+
+ if ((coex_sta->specific_pkt_period_cnt == 0) &&
+ (coex_sta->wifi_is_high_pri_task))
+ coex_sta->wifi_is_high_pri_task = false;
+
+ RT_TRACE(
+ rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ***************** Hi-Pri Task = %s*****************\n",
+ (coex_sta->wifi_is_high_pri_task ? "Yes" : "No"));
+ }
+
+ if (halbtc8822b2ant_is_wifibt_status_changed(btcoexist) ||
+ (bt_relink_finish) || (coex_sta->is_set_ps_state_fail))
+ halbtc8822b2ant_run_coexist_mechanism(btcoexist);
+}
+
+void ex_btc8822b2ant_antenna_detection(struct btc_coexist *btcoexist,
+ u32 cent_freq, u32 offset, u32 span,
+ u32 seconds)
+{
+}
+
+void ex_btc8822b2ant_display_ant_detection(struct btc_coexist *btcoexist) {}
diff --git a/drivers/staging/rtlwifi/btcoexist/halbtc8822b2ant.h b/drivers/staging/rtlwifi/btcoexist/halbtc8822b2ant.h
new file mode 100644
index 0000000..212e0c8
--- /dev/null
+++ b/drivers/staging/rtlwifi/btcoexist/halbtc8822b2ant.h
@@ -0,0 +1,498 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+/* *******************************************
+ * The following is for 8822B 2Ant BT Co-exist definition
+ * ********************************************/
+#define BT_INFO_8822B_2ANT_B_FTP BIT(7)
+#define BT_INFO_8822B_2ANT_B_A2DP BIT(6)
+#define BT_INFO_8822B_2ANT_B_HID BIT(5)
+#define BT_INFO_8822B_2ANT_B_SCO_BUSY BIT(4)
+#define BT_INFO_8822B_2ANT_B_ACL_BUSY BIT(3)
+#define BT_INFO_8822B_2ANT_B_INQ_PAGE BIT(2)
+#define BT_INFO_8822B_2ANT_B_SCO_ESCO BIT(1)
+#define BT_INFO_8822B_2ANT_B_CONNECTION BIT(0)
+
+#define BTC_RSSI_COEX_THRESH_TOL_8822B_2ANT 2
+
+/* unit: % WiFi RSSI Threshold for 2-Ant free-run/2-Ant TDMA translation.
+ * (default = 42)
+ */
+#define BT_8822B_2ANT_WIFI_RSSI_COEXSWITCH_THRES1 80
+/* unit: % BT RSSI Threshold for 2-Ant free-run/2-Ant TDMA translation.
+ * (default = 46)
+ */
+#define BT_8822B_2ANT_BT_RSSI_COEXSWITCH_THRES1 80
+/* unit: % WiFi RSSI Threshold for 1-Ant TDMA/1-Ant PS-TDMA translation.
+ * (default = 42)
+ */
+#define BT_8822B_2ANT_WIFI_RSSI_COEXSWITCH_THRES2 80
+/* unit: % BT RSSI Threshold for 1-Ant TDMA/1-Ant PS-TDMA translation.
+ * (default = 46)
+ */
+#define BT_8822B_2ANT_BT_RSSI_COEXSWITCH_THRES2 80
+#define BT_8822B_2ANT_DEFAULT_ISOLATION 15 /* unit: dB */
+#define BT_8822B_2ANT_WIFI_MAX_TX_POWER 15 /* unit: dBm */
+#define BT_8822B_2ANT_BT_MAX_TX_POWER 3 /* unit: dBm */
+#define BT_8822B_2ANT_WIFI_SIR_THRES1 -15 /* unit: dB */
+#define BT_8822B_2ANT_WIFI_SIR_THRES2 -30 /* unit: dB */
+#define BT_8822B_2ANT_BT_SIR_THRES1 -15 /* unit: dB */
+#define BT_8822B_2ANT_BT_SIR_THRES2 -30 /* unit: dB */
+
+/* for Antenna detection */
+#define BT_8822B_2ANT_ANTDET_PSDTHRES_BACKGROUND 50
+#define BT_8822B_2ANT_ANTDET_PSDTHRES_2ANT_BADISOLATION 70
+#define BT_8822B_2ANT_ANTDET_PSDTHRES_2ANT_GOODISOLATION 52
+#define BT_8822B_2ANT_ANTDET_PSDTHRES_1ANT 40
+#define BT_8822B_2ANT_ANTDET_RETRY_INTERVAL \
+ 10 /* retry timer if ant det is fail, unit: second */
+#define BT_8822B_2ANT_ANTDET_SWEEPPOINT_DELAY 60000
+#define BT_8822B_2ANT_ANTDET_ENABLE 0
+#define BT_8822B_2ANT_ANTDET_BTTXTIME 100
+#define BT_8822B_2ANT_ANTDET_BTTXCHANNEL 39
+#define BT_8822B_2ANT_ANTDET_PSD_SWWEEPCOUNT 50
+
+#define BT_8822B_2ANT_LTECOEX_INDIRECTREG_ACCESS_TIMEOUT 30000
+
+enum bt_8822b_2ant_signal_state {
+ BT_8822B_2ANT_SIG_STA_SET_TO_LOW = 0x0,
+ BT_8822B_2ANT_SIG_STA_SET_BY_HW = 0x0,
+ BT_8822B_2ANT_SIG_STA_SET_TO_HIGH = 0x1,
+ BT_8822B_2ANT_SIG_STA_MAX
+};
+
+enum bt_8822b_2ant_path_ctrl_owner {
+ BT_8822B_2ANT_PCO_BTSIDE = 0x0,
+ BT_8822B_2ANT_PCO_WLSIDE = 0x1,
+ BT_8822B_2ANT_PCO_MAX
+};
+
+enum bt_8822b_2ant_gnt_ctrl_type {
+ BT_8822B_2ANT_GNT_TYPE_CTRL_BY_PTA = 0x0,
+ BT_8822B_2ANT_GNT_TYPE_CTRL_BY_SW = 0x1,
+ BT_8822B_2ANT_GNT_TYPE_MAX
+};
+
+enum bt_8822b_2ant_gnt_ctrl_block {
+ BT_8822B_2ANT_GNT_BLOCK_RFC_BB = 0x0,
+ BT_8822B_2ANT_GNT_BLOCK_RFC = 0x1,
+ BT_8822B_2ANT_GNT_BLOCK_BB = 0x2,
+ BT_8822B_2ANT_GNT_BLOCK_MAX
+};
+
+enum bt_8822b_2ant_lte_coex_table_type {
+ BT_8822B_2ANT_CTT_WL_VS_LTE = 0x0,
+ BT_8822B_2ANT_CTT_BT_VS_LTE = 0x1,
+ BT_8822B_2ANT_CTT_MAX
+};
+
+enum bt_8822b_2ant_lte_break_table_type {
+ BT_8822B_2ANT_LBTT_WL_BREAK_LTE = 0x0,
+ BT_8822B_2ANT_LBTT_BT_BREAK_LTE = 0x1,
+ BT_8822B_2ANT_LBTT_LTE_BREAK_WL = 0x2,
+ BT_8822B_2ANT_LBTT_LTE_BREAK_BT = 0x3,
+ BT_8822B_2ANT_LBTT_MAX
+};
+
+enum bt_info_src_8822b_2ant {
+ BT_INFO_SRC_8822B_2ANT_WIFI_FW = 0x0,
+ BT_INFO_SRC_8822B_2ANT_BT_RSP = 0x1,
+ BT_INFO_SRC_8822B_2ANT_BT_ACTIVE_SEND = 0x2,
+ BT_INFO_SRC_8822B_2ANT_MAX
+};
+
+enum bt_8822b_2ant_bt_status {
+ BT_8822B_2ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0,
+ BT_8822B_2ANT_BT_STATUS_CONNECTED_IDLE = 0x1,
+ BT_8822B_2ANT_BT_STATUS_INQ_PAGE = 0x2,
+ BT_8822B_2ANT_BT_STATUS_ACL_BUSY = 0x3,
+ BT_8822B_2ANT_BT_STATUS_SCO_BUSY = 0x4,
+ BT_8822B_2ANT_BT_STATUS_ACL_SCO_BUSY = 0x5,
+ BT_8822B_2ANT_BT_STATUS_MAX
+};
+
+enum bt_8822b_2ant_coex_algo {
+ BT_8822B_2ANT_COEX_ALGO_UNDEFINED = 0x0,
+ BT_8822B_2ANT_COEX_ALGO_SCO = 0x1,
+ BT_8822B_2ANT_COEX_ALGO_HID = 0x2,
+ BT_8822B_2ANT_COEX_ALGO_A2DP = 0x3,
+ BT_8822B_2ANT_COEX_ALGO_A2DP_PANHS = 0x4,
+ BT_8822B_2ANT_COEX_ALGO_PANEDR = 0x5,
+ BT_8822B_2ANT_COEX_ALGO_PANHS = 0x6,
+ BT_8822B_2ANT_COEX_ALGO_PANEDR_A2DP = 0x7,
+ BT_8822B_2ANT_COEX_ALGO_PANEDR_HID = 0x8,
+ BT_8822B_2ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9,
+ BT_8822B_2ANT_COEX_ALGO_HID_A2DP = 0xa,
+ BT_8822B_2ANT_COEX_ALGO_NOPROFILEBUSY = 0xb,
+ BT_8822B_2ANT_COEX_ALGO_A2DPSINK = 0xc,
+ BT_8822B_2ANT_COEX_ALGO_MAX
+};
+
+enum bt_8822b_2ant_ext_ant_switch_type {
+ BT_8822B_2ANT_EXT_ANT_SWITCH_USE_DPDT = 0x0,
+ BT_8822B_2ANT_EXT_ANT_SWITCH_USE_SPDT = 0x1,
+ BT_8822B_2ANT_EXT_ANT_SWITCH_NONE = 0x2,
+ BT_8822B_2ANT_EXT_ANT_SWITCH_MAX
+};
+
+enum bt_8822b_2ant_ext_ant_switch_ctrl_type {
+ BT_8822B_2ANT_EXT_ANT_SWITCH_CTRL_BY_BBSW = 0x0,
+ BT_8822B_2ANT_EXT_ANT_SWITCH_CTRL_BY_PTA = 0x1,
+ BT_8822B_2ANT_EXT_ANT_SWITCH_CTRL_BY_ANTDIV = 0x2,
+ BT_8822B_2ANT_EXT_ANT_SWITCH_CTRL_BY_MAC = 0x3,
+ BT_8822B_2ANT_EXT_ANT_SWITCH_CTRL_BY_BT = 0x4,
+ BT_8822B_2ANT_EXT_ANT_SWITCH_CTRL_MAX
+};
+
+enum bt_8822b_2ant_ext_ant_switch_pos_type {
+ BT_8822B_2ANT_EXT_ANT_SWITCH_MAIN_TO_BT = 0x0,
+ BT_8822B_2ANT_EXT_ANT_SWITCH_MAIN_TO_WLG = 0x1,
+ BT_8822B_2ANT_EXT_ANT_SWITCH_MAIN_TO_WLA = 0x2,
+ BT_8822B_2ANT_EXT_ANT_SWITCH_MAIN_TO_NOCARE = 0x3,
+ BT_8822B_2ANT_EXT_ANT_SWITCH_MAIN_TO_MAX
+};
+
+enum bt_8822b_2ant_ext_band_switch_pos_type {
+ BT_8822B_2ANT_EXT_BAND_SWITCH_TO_WLG = 0x0,
+ BT_8822B_2ANT_EXT_BAND_SWITCH_TO_WLA = 0x1,
+ BT_8822B_2ANT_EXT_BAND_SWITCH_TO_MAX
+};
+
+enum bt_8822b_2ant_int_block {
+ BT_8822B_2ANT_INT_BLOCK_SWITCH_TO_WLG_OF_BTG = 0x0,
+ BT_8822B_2ANT_INT_BLOCK_SWITCH_TO_WLG_OF_WLAG = 0x1,
+ BT_8822B_2ANT_INT_BLOCK_SWITCH_TO_WLA_OF_WLAG = 0x2,
+ BT_8822B_2ANT_INT_BLOCK_SWITCH_TO_MAX
+};
+
+enum bt_8822b_2ant_phase {
+ BT_8822B_2ANT_PHASE_COEX_INIT = 0x0,
+ BT_8822B_2ANT_PHASE_WLANONLY_INIT = 0x1,
+ BT_8822B_2ANT_PHASE_WLAN_OFF = 0x2,
+ BT_8822B_2ANT_PHASE_2G_RUNTIME = 0x3,
+ BT_8822B_2ANT_PHASE_5G_RUNTIME = 0x4,
+ BT_8822B_2ANT_PHASE_BTMPMODE = 0x5,
+ BT_8822B_2ANT_PHASE_ANTENNA_DET = 0x6,
+ BT_8822B_2ANT_PHASE_COEX_POWERON = 0x7,
+ BT_8822B_2ANT_PHASE_2G_RUNTIME_CONCURRENT = 0x8,
+ BT_8822B_2ANT_PHASE_MAX
+};
+
+/*ADD SCOREBOARD TO FIX BT LPS 32K ISSUE WHILE WL BUSY*/
+
+enum bt_8822b_2ant_scoreboard {
+ BT_8822B_2ANT_SCOREBOARD_ACTIVE = BIT(0),
+ BT_8822B_2ANT_SCOREBOARD_ONOFF = BIT(1),
+ BT_8822B_2ANT_SCOREBOARD_SCAN = BIT(2),
+ BT_8822B_2ANT_SCOREBOARD_UNDERTEST = BIT(3),
+ BT_8822B_2ANT_SCOREBOARD_WLBUSY = BIT(6)
+};
+
+struct coex_dm_8822b_2ant {
+ /* hw setting */
+ u32 pre_ant_pos_type;
+ u32 cur_ant_pos_type;
+ /* fw mechanism */
+ u8 pre_bt_dec_pwr_lvl;
+ u8 cur_bt_dec_pwr_lvl;
+ u8 pre_fw_dac_swing_lvl;
+ u8 cur_fw_dac_swing_lvl;
+ bool cur_ignore_wlan_act;
+ bool pre_ignore_wlan_act;
+ u8 pre_ps_tdma;
+ u8 cur_ps_tdma;
+ u8 ps_tdma_para[5];
+ u8 ps_tdma_du_adj_type;
+ bool reset_tdma_adjust;
+ bool pre_ps_tdma_on;
+ bool cur_ps_tdma_on;
+ bool pre_bt_auto_report;
+ bool cur_bt_auto_report;
+
+ /* sw mechanism */
+ bool pre_rf_rx_lpf_shrink;
+ bool cur_rf_rx_lpf_shrink;
+ u32 bt_rf_0x1e_backup;
+ bool pre_low_penalty_ra;
+ bool cur_low_penalty_ra;
+ bool pre_dac_swing_on;
+ u32 pre_dac_swing_lvl;
+ bool cur_dac_swing_on;
+ u32 cur_dac_swing_lvl;
+ bool pre_adc_back_off;
+ bool cur_adc_back_off;
+ bool pre_agc_table_en;
+ bool cur_agc_table_en;
+ u32 pre_val0x6c0;
+ u32 cur_val0x6c0;
+ u32 pre_val0x6c4;
+ u32 cur_val0x6c4;
+ u32 pre_val0x6c8;
+ u32 cur_val0x6c8;
+ u8 pre_val0x6cc;
+ u8 cur_val0x6cc;
+ bool limited_dig;
+
+ /* algorithm related */
+ u8 pre_algorithm;
+ u8 cur_algorithm;
+ u8 bt_status;
+ u8 wifi_chnl_info[3];
+
+ bool need_recover0x948;
+ u32 backup0x948;
+
+ u8 pre_lps;
+ u8 cur_lps;
+ u8 pre_rpwm;
+ u8 cur_rpwm;
+
+ bool is_switch_to_1dot5_ant;
+ u8 switch_thres_offset;
+ u32 arp_cnt;
+
+ u32 pre_ext_ant_switch_status;
+ u32 cur_ext_ant_switch_status;
+
+ u8 pre_ext_band_switch_status;
+ u8 cur_ext_band_switch_status;
+
+ u8 pre_int_block_status;
+ u8 cur_int_block_status;
+};
+
+struct coex_sta_8822b_2ant {
+ bool bt_disabled;
+ bool bt_link_exist;
+ bool sco_exist;
+ bool a2dp_exist;
+ bool hid_exist;
+ bool pan_exist;
+
+ bool under_lps;
+ bool under_ips;
+ u32 high_priority_tx;
+ u32 high_priority_rx;
+ u32 low_priority_tx;
+ u32 low_priority_rx;
+ bool is_hi_pri_rx_overhead;
+ u8 bt_rssi;
+ u8 pre_bt_rssi_state;
+ u8 pre_wifi_rssi_state[4];
+ u8 bt_info_c2h[BT_INFO_SRC_8822B_2ANT_MAX][10];
+ u32 bt_info_c2h_cnt[BT_INFO_SRC_8822B_2ANT_MAX];
+ bool bt_whck_test;
+ bool c2h_bt_inquiry_page;
+ bool c2h_bt_remote_name_req;
+
+ u8 bt_info_ext;
+ u8 bt_info_ext2;
+ u32 pop_event_cnt;
+ u8 scan_ap_num;
+ u8 bt_retry_cnt;
+
+ u32 crc_ok_cck;
+ u32 crc_ok_11g;
+ u32 crc_ok_11n;
+ u32 crc_ok_11n_vht;
+
+ u32 crc_err_cck;
+ u32 crc_err_11g;
+ u32 crc_err_11n;
+ u32 crc_err_11n_vht;
+
+ u32 acc_crc_ratio;
+ u32 now_crc_ratio;
+
+ bool cck_lock;
+ bool pre_ccklock;
+ bool cck_ever_lock;
+
+ u8 coex_table_type;
+ bool force_lps_ctrl;
+
+ u8 dis_ver_info_cnt;
+
+ u8 a2dp_bit_pool;
+ u8 cut_version;
+
+ bool concurrent_rx_mode_on;
+
+ u16 score_board;
+ u8 isolation_btween_wb; /* 0~ 50 */
+ u8 wifi_coex_thres;
+ u8 bt_coex_thres;
+ u8 wifi_coex_thres2;
+ u8 bt_coex_thres2;
+
+ u8 num_of_profile;
+ bool acl_busy;
+ bool bt_create_connection;
+ bool wifi_is_high_pri_task;
+ u32 specific_pkt_period_cnt;
+ u32 bt_coex_supported_feature;
+ u32 bt_coex_supported_version;
+
+ u8 bt_ble_scan_type;
+ u32 bt_ble_scan_para[3];
+
+ bool run_time_state;
+ bool freeze_coexrun_by_btinfo;
+
+ bool is_A2DP_3M;
+ bool voice_over_HOGP;
+ u8 bt_info;
+ bool is_autoslot;
+ u8 forbidden_slot;
+ u8 hid_busy_num;
+ u8 hid_pair_cnt;
+
+ u32 cnt_remote_name_req;
+ u32 cnt_setup_link;
+ u32 cnt_reinit;
+ u32 cnt_ign_wlan_act;
+ u32 cnt_page;
+ u32 cnt_role_switch;
+
+ u16 bt_reg_vendor_ac;
+ u16 bt_reg_vendor_ae;
+
+ bool is_setup_link;
+ u8 wl_noisy_level;
+ u32 gnt_error_cnt;
+
+ u8 bt_afh_map[10];
+ u8 bt_relink_downcount;
+ bool is_tdma_btautoslot;
+ bool is_tdma_btautoslot_hang;
+
+ bool is_esco_mode;
+ u8 switch_band_notify_to;
+ bool is_rf_state_off;
+
+ bool is_hid_low_pri_tx_overhead;
+ bool is_bt_multi_link;
+ bool is_bt_a2dp_sink;
+
+ bool is_set_ps_state_fail;
+ u8 cnt_set_ps_state_fail;
+};
+
+#define BT_8822B_2ANT_EXT_BAND_SWITCH_USE_DPDT 0
+#define BT_8822B_2ANT_EXT_BAND_SWITCH_USE_SPDT 1
+
+struct rfe_type_8822b_2ant {
+ u8 rfe_module_type;
+ bool ext_ant_switch_exist;
+ u8 ext_ant_switch_type; /* 0:DPDT, 1:SPDT */
+ /* iF 0: DPDT_P=0, DPDT_N=1 => BTG to Main, WL_A+G to Aux */
+ u8 ext_ant_switch_ctrl_polarity;
+
+ bool ext_band_switch_exist;
+ u8 ext_band_switch_type; /* 0:DPDT, 1:SPDT */
+ u8 ext_band_switch_ctrl_polarity;
+
+ /* If true: WLG at BTG, If false: WLG at WLAG */
+ bool wlg_locate_at_btg;
+
+ bool ext_ant_switch_diversity; /* If diversity on */
+};
+
+#define BT_8822B_2ANT_ANTDET_PSD_POINTS 256 /* MAX:1024 */
+#define BT_8822B_2ANT_ANTDET_PSD_AVGNUM 1 /* MAX:3 */
+#define BT_8822B_2ANT_ANTDET_BUF_LEN 16
+
+struct psdscan_sta_8822b_2ant {
+ u32 ant_det_bt_le_channel; /* BT LE Channel ex:2412 */
+ u32 ant_det_bt_tx_time;
+ u32 ant_det_pre_psdscan_peak_val;
+ bool ant_det_is_ant_det_available;
+ u32 ant_det_psd_scan_peak_val;
+ bool ant_det_is_btreply_available;
+ u32 ant_det_psd_scan_peak_freq;
+
+ u8 ant_det_result;
+ u8 ant_det_peak_val[BT_8822B_2ANT_ANTDET_BUF_LEN];
+ u8 ant_det_peak_freq[BT_8822B_2ANT_ANTDET_BUF_LEN];
+ u32 ant_det_try_count;
+ u32 ant_det_fail_count;
+ u32 ant_det_inteval_count;
+ u32 ant_det_thres_offset;
+
+ u32 real_cent_freq;
+ s32 real_offset;
+ u32 real_span;
+
+ u32 psd_band_width; /* unit: Hz */
+ u32 psd_point; /* 128/256/512/1024 */
+ u32 psd_report[1024]; /* unit:dB (20logx), 0~255 */
+ u32 psd_report_max_hold[1024]; /* unit:dB (20logx), 0~255 */
+ u32 psd_start_point;
+ u32 psd_stop_point;
+ u32 psd_max_value_point;
+ u32 psd_max_value;
+ u32 psd_max_value2;
+ /* filter loop_max_value that below BT_8822B_1ANT_ANTDET_PSDTHRES_1ANT,
+ * and average the rest
+ */
+ u32 psd_avg_value;
+ /*max value in each loop */
+ u32 psd_loop_max_value[BT_8822B_2ANT_ANTDET_PSD_SWWEEPCOUNT];
+ u32 psd_start_base;
+ u32 psd_avg_num; /* 1/8/16/32 */
+ u32 psd_gen_count;
+ bool is_ant_det_running;
+ bool is_psd_show_max_only;
+};
+
+/* *******************************************
+ * The following is interface which will notify coex module.
+ * ********************************************/
+void ex_btc8822b2ant_power_on_setting(struct btc_coexist *btcoexist);
+void ex_btc8822b2ant_pre_load_firmware(struct btc_coexist *btcoexist);
+void ex_btc8822b2ant_init_hw_config(struct btc_coexist *btcoexist,
+ bool wifi_only);
+void ex_btc8822b2ant_init_coex_dm(struct btc_coexist *btcoexist);
+void ex_btc8822b2ant_ips_notify(struct btc_coexist *btcoexist, u8 type);
+void ex_btc8822b2ant_lps_notify(struct btc_coexist *btcoexist, u8 type);
+void ex_btc8822b2ant_scan_notify(struct btc_coexist *btcoexist, u8 type);
+void ex_btc8822b2ant_switchband_notify(struct btc_coexist *btcoexist, u8 type);
+void ex_btc8822b2ant_connect_notify(struct btc_coexist *btcoexist, u8 type);
+void ex_btc8822b2ant_media_status_notify(struct btc_coexist *btcoexist,
+ u8 type);
+void ex_btc8822b2ant_specific_packet_notify(struct btc_coexist *btcoexist,
+ u8 type);
+void ex_btc8822b2ant_bt_info_notify(struct btc_coexist *btcoexist, u8 *tmp_buf,
+ u8 length);
+void ex_btc8822b2ant_rf_status_notify(struct btc_coexist *btcoexist, u8 type);
+void ex_btc8822b2ant_halt_notify(struct btc_coexist *btcoexist);
+void ex_btc8822b2ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state);
+void ex_btc8822b2ant_periodical(struct btc_coexist *btcoexist);
+void ex_btc8822b2ant_display_coex_info(struct btc_coexist *btcoexist,
+ struct seq_file *m);
+void ex_btc8822b2ant_antenna_detection(struct btc_coexist *btcoexist,
+ u32 cent_freq, u32 offset, u32 span,
+ u32 seconds);
+void ex_btc8822b2ant_display_ant_detection(struct btc_coexist *btcoexist);
diff --git a/drivers/staging/rtlwifi/btcoexist/halbtc8822bwifionly.c b/drivers/staging/rtlwifi/btcoexist/halbtc8822bwifionly.c
new file mode 100644
index 0000000..43d628a
--- /dev/null
+++ b/drivers/staging/rtlwifi/btcoexist/halbtc8822bwifionly.c
@@ -0,0 +1,65 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#include "halbt_precomp.h"
+
+void ex_hal8822b_wifi_only_hw_config(struct wifi_only_cfg *wifionlycfg)
+{
+ /*BB control*/
+ halwifionly_phy_set_bb_reg(wifionlycfg, 0x4c, 0x01800000, 0x2);
+ /*SW control*/
+ halwifionly_phy_set_bb_reg(wifionlycfg, 0xcb4, 0xff, 0x77);
+ /*antenna mux switch */
+ halwifionly_phy_set_bb_reg(wifionlycfg, 0x974, 0x300, 0x3);
+
+ halwifionly_phy_set_bb_reg(wifionlycfg, 0x1990, 0x300, 0x0);
+
+ halwifionly_phy_set_bb_reg(wifionlycfg, 0xcbc, 0x80000, 0x0);
+ /*switch to WL side controller and gnt_wl gnt_bt debug signal */
+ halwifionly_phy_set_bb_reg(wifionlycfg, 0x70, 0xff000000, 0x0e);
+ /*gnt_wl=1 , gnt_bt=0*/
+ halwifionly_phy_set_bb_reg(wifionlycfg, 0x1704, 0xffffffff, 0x7700);
+ halwifionly_phy_set_bb_reg(wifionlycfg, 0x1700, 0xffffffff, 0xc00f0038);
+}
+
+void ex_hal8822b_wifi_only_scannotify(struct wifi_only_cfg *wifionlycfg,
+ u8 is_5g)
+{
+ hal8822b_wifi_only_switch_antenna(wifionlycfg, is_5g);
+}
+
+void ex_hal8822b_wifi_only_switchbandnotify(struct wifi_only_cfg *wifionlycfg,
+ u8 is_5g)
+{
+ hal8822b_wifi_only_switch_antenna(wifionlycfg, is_5g);
+}
+
+void hal8822b_wifi_only_switch_antenna(struct wifi_only_cfg *wifionlycfg,
+ u8 is_5g)
+{
+ if (is_5g)
+ halwifionly_phy_set_bb_reg(wifionlycfg, 0xcbc, 0x300, 0x1);
+ else
+ halwifionly_phy_set_bb_reg(wifionlycfg, 0xcbc, 0x300, 0x2);
+}
diff --git a/drivers/staging/rtlwifi/btcoexist/halbtc8822bwifionly.h b/drivers/staging/rtlwifi/btcoexist/halbtc8822bwifionly.h
new file mode 100644
index 0000000..464774e
--- /dev/null
+++ b/drivers/staging/rtlwifi/btcoexist/halbtc8822bwifionly.h
@@ -0,0 +1,35 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __INC_HAL8822BWIFIONLYHWCFG_H
+#define __INC_HAL8822BWIFIONLYHWCFG_H
+
+void ex_hal8822b_wifi_only_hw_config(struct wifi_only_cfg *wifionlycfg);
+void ex_hal8822b_wifi_only_scannotify(struct wifi_only_cfg *wifionlycfg,
+ u8 is_5g);
+void ex_hal8822b_wifi_only_switchbandnotify(struct wifi_only_cfg *wifionlycfg,
+ u8 is_5g);
+void hal8822b_wifi_only_switch_antenna(struct wifi_only_cfg *wifionlycfg,
+ u8 is_5g);
+#endif
diff --git a/drivers/staging/rtlwifi/btcoexist/halbtcoutsrc.c b/drivers/staging/rtlwifi/btcoexist/halbtcoutsrc.c
new file mode 100644
index 0000000..52620b7
--- /dev/null
+++ b/drivers/staging/rtlwifi/btcoexist/halbtcoutsrc.c
@@ -0,0 +1,1881 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2013 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#include "halbt_precomp.h"
+
+/***************************************************
+ * Debug related function
+ ***************************************************/
+
+static const char *const gl_btc_wifi_bw_string[] = {
+ "11bg",
+ "HT20",
+ "HT40",
+ "HT80",
+ "HT160"
+};
+
+static const char *const gl_btc_wifi_freq_string[] = {
+ "2.4G",
+ "5G"
+};
+
+static bool halbtc_is_bt_coexist_available(struct btc_coexist *btcoexist)
+{
+ if (!btcoexist->binded || NULL == btcoexist->adapter)
+ return false;
+
+ return true;
+}
+
+static bool halbtc_is_wifi_busy(struct rtl_priv *rtlpriv)
+{
+ if (rtlpriv->link_info.busytraffic)
+ return true;
+ else
+ return false;
+}
+
+static void halbtc_dbg_init(void)
+{
+}
+
+/***************************************************
+ * helper function
+ ***************************************************/
+static bool is_any_client_connect_to_ap(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ struct rtl_mac *mac = rtl_mac(rtlpriv);
+ struct rtl_sta_info *drv_priv;
+ u8 cnt = 0;
+
+ if (mac->opmode == NL80211_IFTYPE_ADHOC ||
+ mac->opmode == NL80211_IFTYPE_MESH_POINT ||
+ mac->opmode == NL80211_IFTYPE_AP) {
+ if (in_interrupt() > 0) {
+ list_for_each_entry(drv_priv, &rtlpriv->entry_list,
+ list) {
+ cnt++;
+ }
+ } else {
+ spin_lock_bh(&rtlpriv->locks.entry_list_lock);
+ list_for_each_entry(drv_priv, &rtlpriv->entry_list,
+ list) {
+ cnt++;
+ }
+ spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
+ }
+ }
+ if (cnt > 0)
+ return true;
+ else
+ return false;
+}
+
+static bool halbtc_legacy(struct rtl_priv *adapter)
+{
+ struct rtl_priv *rtlpriv = adapter;
+ struct rtl_mac *mac = rtl_mac(rtlpriv);
+
+ bool is_legacy = false;
+
+ if ((mac->mode == WIRELESS_MODE_B) || (mac->mode == WIRELESS_MODE_G))
+ is_legacy = true;
+
+ return is_legacy;
+}
+
+bool halbtc_is_wifi_uplink(struct rtl_priv *adapter)
+{
+ struct rtl_priv *rtlpriv = adapter;
+
+ if (rtlpriv->link_info.tx_busy_traffic)
+ return true;
+ else
+ return false;
+}
+
+static u32 halbtc_get_wifi_bw(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv =
+ (struct rtl_priv *)btcoexist->adapter;
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ u32 wifi_bw = BTC_WIFI_BW_HT20;
+
+ if (halbtc_legacy(rtlpriv)) {
+ wifi_bw = BTC_WIFI_BW_LEGACY;
+ } else {
+ switch (rtlphy->current_chan_bw) {
+ case HT_CHANNEL_WIDTH_20:
+ wifi_bw = BTC_WIFI_BW_HT20;
+ break;
+ case HT_CHANNEL_WIDTH_20_40:
+ wifi_bw = BTC_WIFI_BW_HT40;
+ break;
+ case HT_CHANNEL_WIDTH_80:
+ wifi_bw = BTC_WIFI_BW_HT80;
+ break;
+ }
+ }
+
+ return wifi_bw;
+}
+
+static u8 halbtc_get_wifi_central_chnl(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ u8 chnl = 1;
+
+ if (rtlphy->current_channel != 0)
+ chnl = rtlphy->current_channel;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "%s:%d\n", __func__, chnl);
+ return chnl;
+}
+
+static u8 rtl_get_hwpg_single_ant_path(struct rtl_priv *rtlpriv)
+{
+ return rtlpriv->btcoexist.btc_info.single_ant_path;
+}
+
+static u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv)
+{
+ return rtlpriv->btcoexist.btc_info.bt_type;
+}
+
+static u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv)
+{
+ u8 num;
+
+ if (rtlpriv->btcoexist.btc_info.ant_num == ANT_X2)
+ num = 2;
+ else
+ num = 1;
+
+ return num;
+}
+
+static u8 rtl_get_hwpg_package_type(struct rtl_priv *rtlpriv)
+{
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+
+ return rtlhal->package_type;
+}
+
+static
+u8 rtl_get_hwpg_rfe_type(struct rtl_priv *rtlpriv)
+{
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+
+ return rtlhal->rfe_type;
+}
+
+/* ************************************
+ * Hal helper function
+ * ************************************
+ */
+static
+bool halbtc_is_hw_mailbox_exist(struct btc_coexist *btcoexist)
+{
+ if (IS_HARDWARE_TYPE_8812(btcoexist->adapter))
+ return false;
+ else
+ return true;
+}
+
+static
+bool halbtc_send_bt_mp_operation(struct btc_coexist *btcoexist, u8 op_code,
+ u8 *cmd, u32 len, unsigned long wait_ms)
+{
+ struct rtl_priv *rtlpriv;
+ const u8 oper_ver = 0;
+ u8 req_num;
+
+ if (!halbtc_is_hw_mailbox_exist(btcoexist))
+ return false;
+
+ if (wait_ms) /* before h2c to avoid race condition */
+ reinit_completion(&btcoexist->bt_mp_comp);
+
+ rtlpriv = btcoexist->adapter;
+
+ /*
+ * fill req_num by op_code, and rtl_btc_btmpinfo_notify() use it
+ * to know message type
+ */
+ switch (op_code) {
+ case BT_OP_GET_BT_VERSION:
+ req_num = BT_SEQ_GET_BT_VERSION;
+ break;
+ case BT_OP_GET_AFH_MAP_L:
+ req_num = BT_SEQ_GET_AFH_MAP_L;
+ break;
+ case BT_OP_GET_AFH_MAP_M:
+ req_num = BT_SEQ_GET_AFH_MAP_M;
+ break;
+ case BT_OP_GET_AFH_MAP_H:
+ req_num = BT_SEQ_GET_AFH_MAP_H;
+ break;
+ case BT_OP_GET_BT_COEX_SUPPORTED_FEATURE:
+ req_num = BT_SEQ_GET_BT_COEX_SUPPORTED_FEATURE;
+ break;
+ case BT_OP_GET_BT_COEX_SUPPORTED_VERSION:
+ req_num = BT_SEQ_GET_BT_COEX_SUPPORTED_VERSION;
+ break;
+ case BT_OP_GET_BT_ANT_DET_VAL:
+ req_num = BT_SEQ_GET_BT_ANT_DET_VAL;
+ break;
+ case BT_OP_GET_BT_BLE_SCAN_PARA:
+ req_num = BT_SEQ_GET_BT_BLE_SCAN_PARA;
+ break;
+ case BT_OP_GET_BT_BLE_SCAN_TYPE:
+ req_num = BT_SEQ_GET_BT_BLE_SCAN_TYPE;
+ break;
+ case BT_OP_WRITE_REG_ADDR:
+ case BT_OP_WRITE_REG_VALUE:
+ case BT_OP_READ_REG:
+ default:
+ req_num = BT_SEQ_DONT_CARE;
+ break;
+ }
+
+ cmd[0] |= (oper_ver & 0x0f); /* Set OperVer */
+ cmd[0] |= ((req_num << 4) & 0xf0); /* Set ReqNum */
+ cmd[1] = op_code;
+ rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->mac80211.hw, 0x67, len, cmd);
+
+ /* wait? */
+ if (!wait_ms)
+ return true;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "btmpinfo wait req_num=%d wait=%ld\n", req_num, wait_ms);
+
+ if (in_interrupt())
+ return false;
+
+ if (wait_for_completion_timeout(&btcoexist->bt_mp_comp,
+ msecs_to_jiffies(wait_ms)) == 0) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
+ "btmpinfo wait (req_num=%d) timeout\n", req_num);
+
+ return false; /* timeout */
+ }
+
+ return true;
+}
+
+static void halbtc_leave_lps(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv;
+ struct rtl_ps_ctl *ppsc;
+ bool ap_enable = false;
+
+ rtlpriv = btcoexist->adapter;
+ ppsc = rtl_psc(rtlpriv);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
+ &ap_enable);
+
+ if (ap_enable) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
+ "%s()<--dont leave lps under AP mode\n", __func__);
+ return;
+ }
+
+ btcoexist->bt_info.bt_ctrl_lps = true;
+ btcoexist->bt_info.bt_lps_on = false;
+ rtl_lps_leave(rtlpriv->mac80211.hw);
+}
+
+static void halbtc_enter_lps(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv;
+ struct rtl_ps_ctl *ppsc;
+ bool ap_enable = false;
+
+ rtlpriv = btcoexist->adapter;
+ ppsc = rtl_psc(rtlpriv);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
+ &ap_enable);
+
+ if (ap_enable) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
+ "%s()<--dont enter lps under AP mode\n", __func__);
+ return;
+ }
+
+ btcoexist->bt_info.bt_ctrl_lps = true;
+ btcoexist->bt_info.bt_lps_on = true;
+ rtl_lps_enter(rtlpriv->mac80211.hw);
+}
+
+static void halbtc_normal_lps(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv;
+
+ rtlpriv = btcoexist->adapter;
+
+ if (btcoexist->bt_info.bt_ctrl_lps) {
+ btcoexist->bt_info.bt_lps_on = false;
+ rtl_lps_leave(rtlpriv->mac80211.hw);
+ btcoexist->bt_info.bt_ctrl_lps = false;
+ }
+}
+
+static void halbtc_leave_low_power(struct btc_coexist *btcoexist)
+{
+}
+
+static void halbtc_normal_low_power(struct btc_coexist *btcoexist)
+{
+}
+
+static void halbtc_disable_low_power(struct btc_coexist *btcoexist,
+ bool low_pwr_disable)
+{
+ /* TODO: original/leave 32k low power */
+ btcoexist->bt_info.bt_disable_low_pwr = low_pwr_disable;
+}
+
+static void halbtc_aggregation_check(struct btc_coexist *btcoexist)
+{
+ bool need_to_act = false;
+ static unsigned long pre_time;
+ unsigned long cur_time = 0;
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ /* To void continuous deleteBA=>addBA=>deleteBA=>addBA
+ * This function is not allowed to continuous called
+ * It can only be called after 8 seconds
+ */
+
+ cur_time = jiffies;
+ if (jiffies_to_msecs(cur_time - pre_time) <= 8000) {
+ /* over 8 seconds you can execute this function again. */
+ return;
+ }
+ pre_time = cur_time;
+
+ if (btcoexist->bt_info.reject_agg_pkt) {
+ need_to_act = true;
+ btcoexist->bt_info.pre_reject_agg_pkt =
+ btcoexist->bt_info.reject_agg_pkt;
+ } else {
+ if (btcoexist->bt_info.pre_reject_agg_pkt) {
+ need_to_act = true;
+ btcoexist->bt_info.pre_reject_agg_pkt =
+ btcoexist->bt_info.reject_agg_pkt;
+ }
+
+ if (btcoexist->bt_info.pre_bt_ctrl_agg_buf_size !=
+ btcoexist->bt_info.bt_ctrl_agg_buf_size) {
+ need_to_act = true;
+ btcoexist->bt_info.pre_bt_ctrl_agg_buf_size =
+ btcoexist->bt_info.bt_ctrl_agg_buf_size;
+ }
+
+ if (btcoexist->bt_info.bt_ctrl_agg_buf_size) {
+ if (btcoexist->bt_info.pre_agg_buf_size !=
+ btcoexist->bt_info.agg_buf_size) {
+ need_to_act = true;
+ }
+ btcoexist->bt_info.pre_agg_buf_size =
+ btcoexist->bt_info.agg_buf_size;
+ }
+
+ if (need_to_act)
+ rtl_rx_ampdu_apply(rtlpriv);
+ }
+}
+
+static u32 halbtc_get_bt_patch_version(struct btc_coexist *btcoexist)
+{
+ u8 cmd_buffer[4] = {0};
+
+ if (btcoexist->bt_info.bt_real_fw_ver)
+ goto label_done;
+
+ /* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
+ halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_BT_VERSION,
+ cmd_buffer, 4, 200);
+
+label_done:
+ return btcoexist->bt_info.bt_real_fw_ver;
+}
+
+static u32 halbtc_get_bt_coex_supported_feature(void *btc_context)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
+ u8 cmd_buffer[4] = {0};
+
+ if (btcoexist->bt_info.bt_supported_feature)
+ goto label_done;
+
+ /* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
+ halbtc_send_bt_mp_operation(btcoexist,
+ BT_OP_GET_BT_COEX_SUPPORTED_FEATURE,
+ cmd_buffer, 4, 200);
+
+label_done:
+ return btcoexist->bt_info.bt_supported_feature;
+}
+
+static u32 halbtc_get_bt_coex_supported_version(void *btc_context)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
+ u8 cmd_buffer[4] = {0};
+
+ if (btcoexist->bt_info.bt_supported_version)
+ goto label_done;
+
+ /* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
+ halbtc_send_bt_mp_operation(btcoexist,
+ BT_OP_GET_BT_COEX_SUPPORTED_VERSION,
+ cmd_buffer, 4, 200);
+
+label_done:
+ return btcoexist->bt_info.bt_supported_version;
+}
+
+static u32 halbtc_get_wifi_link_status(struct btc_coexist *btcoexist)
+{
+ /* return value:
+ * [31:16] => connected port number
+ * [15:0] => port connected bit define
+ */
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ struct rtl_mac *mac = rtl_mac(rtlpriv);
+ u32 ret_val = 0;
+ u32 port_connected_status = 0, num_of_connected_port = 0;
+
+ if (mac->opmode == NL80211_IFTYPE_STATION &&
+ mac->link_state >= MAC80211_LINKED) {
+ port_connected_status |= WIFI_STA_CONNECTED;
+ num_of_connected_port++;
+ }
+ /* AP & ADHOC & MESH */
+ if (is_any_client_connect_to_ap(btcoexist)) {
+ port_connected_status |= WIFI_AP_CONNECTED;
+ num_of_connected_port++;
+ }
+ /* TODO: P2P Connected Status */
+
+ ret_val = (num_of_connected_port << 16) | port_connected_status;
+
+ return ret_val;
+}
+
+static s32 halbtc_get_wifi_rssi(struct rtl_priv *rtlpriv)
+{
+ int undec_sm_pwdb = 0;
+
+ if (rtlpriv->mac80211.link_state >= MAC80211_LINKED)
+ undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
+ else /* associated entry pwdb */
+ undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
+ return undec_sm_pwdb;
+}
+
+static bool halbtc_get(void *void_btcoexist, u8 get_type, void *out_buf)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)void_btcoexist;
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ struct rtl_mac *mac = rtl_mac(rtlpriv);
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+ bool *bool_tmp = (bool *)out_buf;
+ int *s32_tmp = (int *)out_buf;
+ u32 *u32_tmp = (u32 *)out_buf;
+ u8 *u8_tmp = (u8 *)out_buf;
+ bool tmp = false;
+ bool ret = true;
+
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return false;
+
+ switch (get_type) {
+ case BTC_GET_BL_HS_OPERATION:
+ *bool_tmp = false;
+ ret = false;
+ break;
+ case BTC_GET_BL_HS_CONNECTING:
+ *bool_tmp = false;
+ ret = false;
+ break;
+ case BTC_GET_BL_WIFI_CONNECTED:
+ if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION &&
+ rtlpriv->mac80211.link_state >= MAC80211_LINKED)
+ tmp = true;
+ if (is_any_client_connect_to_ap(btcoexist))
+ tmp = true;
+ *bool_tmp = tmp;
+ break;
+ case BTC_GET_BL_WIFI_BUSY:
+ if (halbtc_is_wifi_busy(rtlpriv))
+ *bool_tmp = true;
+ else
+ *bool_tmp = false;
+ break;
+ case BTC_GET_BL_WIFI_SCAN:
+ if (mac->act_scanning)
+ *bool_tmp = true;
+ else
+ *bool_tmp = false;
+ break;
+ case BTC_GET_BL_WIFI_LINK:
+ if (mac->link_state == MAC80211_LINKING)
+ *bool_tmp = true;
+ else
+ *bool_tmp = false;
+ break;
+ case BTC_GET_BL_WIFI_ROAM:
+ if (mac->link_state == MAC80211_LINKING)
+ *bool_tmp = true;
+ else
+ *bool_tmp = false;
+ break;
+ case BTC_GET_BL_WIFI_4_WAY_PROGRESS:
+ *bool_tmp = rtlpriv->btcoexist.btc_info.in_4way;
+ break;
+ case BTC_GET_BL_WIFI_UNDER_5G:
+ if (rtlhal->current_bandtype == BAND_ON_5G)
+ *bool_tmp = true;
+ else
+ *bool_tmp = false;
+ break;
+ case BTC_GET_BL_WIFI_AP_MODE_ENABLE:
+ if (mac->opmode == NL80211_IFTYPE_AP)
+ *bool_tmp = true;
+ else
+ *bool_tmp = false;
+ break;
+ case BTC_GET_BL_WIFI_ENABLE_ENCRYPTION:
+ if (rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION)
+ *bool_tmp = false;
+ else
+ *bool_tmp = true;
+ break;
+ case BTC_GET_BL_WIFI_UNDER_B_MODE:
+ if (rtlpriv->mac80211.mode == WIRELESS_MODE_B)
+ *bool_tmp = true;
+ else
+ *bool_tmp = false;
+ break;
+ case BTC_GET_BL_EXT_SWITCH:
+ *bool_tmp = false;
+ break;
+ case BTC_GET_BL_WIFI_IS_IN_MP_MODE:
+ *bool_tmp = false;
+ break;
+ case BTC_GET_BL_IS_ASUS_8723B:
+ *bool_tmp = false;
+ break;
+ case BTC_GET_BL_RF4CE_CONNECTED:
+ *bool_tmp = false;
+ break;
+ case BTC_GET_S4_WIFI_RSSI:
+ *s32_tmp = halbtc_get_wifi_rssi(rtlpriv);
+ break;
+ case BTC_GET_S4_HS_RSSI:
+ *s32_tmp = 0;
+ ret = false;
+ break;
+ case BTC_GET_U4_WIFI_BW:
+ *u32_tmp = halbtc_get_wifi_bw(btcoexist);
+ break;
+ case BTC_GET_U4_WIFI_TRAFFIC_DIRECTION:
+ if (halbtc_is_wifi_uplink(rtlpriv))
+ *u32_tmp = BTC_WIFI_TRAFFIC_TX;
+ else
+ *u32_tmp = BTC_WIFI_TRAFFIC_RX;
+ break;
+ case BTC_GET_U4_WIFI_FW_VER:
+ *u32_tmp = (rtlhal->fw_version << 16) | rtlhal->fw_subversion;
+ break;
+ case BTC_GET_U4_WIFI_LINK_STATUS:
+ *u32_tmp = halbtc_get_wifi_link_status(btcoexist);
+ break;
+ case BTC_GET_U4_BT_PATCH_VER:
+ *u32_tmp = halbtc_get_bt_patch_version(btcoexist);
+ break;
+ case BTC_GET_U4_VENDOR:
+ *u32_tmp = BTC_VENDOR_OTHER;
+ break;
+ case BTC_GET_U4_SUPPORTED_VERSION:
+ *u32_tmp = halbtc_get_bt_coex_supported_version(btcoexist);
+ break;
+ case BTC_GET_U4_SUPPORTED_FEATURE:
+ *u32_tmp = halbtc_get_bt_coex_supported_feature(btcoexist);
+ break;
+ case BTC_GET_U4_WIFI_IQK_TOTAL:
+ *u32_tmp = btcoexist->btc_phydm_query_phy_counter(btcoexist,
+ "IQK_TOTAL");
+ break;
+ case BTC_GET_U4_WIFI_IQK_OK:
+ *u32_tmp = btcoexist->btc_phydm_query_phy_counter(btcoexist,
+ "IQK_OK");
+ break;
+ case BTC_GET_U4_WIFI_IQK_FAIL:
+ *u32_tmp = btcoexist->btc_phydm_query_phy_counter(btcoexist,
+ "IQK_FAIL");
+ break;
+ case BTC_GET_U1_WIFI_DOT11_CHNL:
+ *u8_tmp = rtlphy->current_channel;
+ break;
+ case BTC_GET_U1_WIFI_CENTRAL_CHNL:
+ *u8_tmp = halbtc_get_wifi_central_chnl(btcoexist);
+ break;
+ case BTC_GET_U1_WIFI_HS_CHNL:
+ *u8_tmp = 0;
+ ret = false;
+ break;
+ case BTC_GET_U1_AP_NUM:
+ *u8_tmp = rtlpriv->btcoexist.btc_info.ap_num;
+ break;
+ case BTC_GET_U1_ANT_TYPE:
+ *u8_tmp = (u8)BTC_ANT_TYPE_0;
+ break;
+ case BTC_GET_U1_IOT_PEER:
+ *u8_tmp = 0;
+ break;
+
+ /************* 1Ant **************/
+ case BTC_GET_U1_LPS_MODE:
+ *u8_tmp = btcoexist->pwr_mode_val[0];
+ break;
+
+ default:
+ ret = false;
+ break;
+ }
+
+ return ret;
+}
+
+static bool halbtc_set(void *void_btcoexist, u8 set_type, void *in_buf)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)void_btcoexist;
+ bool *bool_tmp = (bool *)in_buf;
+ u8 *u8_tmp = (u8 *)in_buf;
+ u32 *u32_tmp = (u32 *)in_buf;
+ bool ret = true;
+
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return false;
+
+ switch (set_type) {
+ /* set some bool type variables. */
+ case BTC_SET_BL_BT_DISABLE:
+ btcoexist->bt_info.bt_disabled = *bool_tmp;
+ break;
+ case BTC_SET_BL_BT_TRAFFIC_BUSY:
+ btcoexist->bt_info.bt_busy = *bool_tmp;
+ break;
+ case BTC_SET_BL_BT_LIMITED_DIG:
+ btcoexist->bt_info.limited_dig = *bool_tmp;
+ break;
+ case BTC_SET_BL_FORCE_TO_ROAM:
+ btcoexist->bt_info.force_to_roam = *bool_tmp;
+ break;
+ case BTC_SET_BL_TO_REJ_AP_AGG_PKT:
+ btcoexist->bt_info.reject_agg_pkt = *bool_tmp;
+ break;
+ case BTC_SET_BL_BT_CTRL_AGG_SIZE:
+ btcoexist->bt_info.bt_ctrl_agg_buf_size = *bool_tmp;
+ break;
+ case BTC_SET_BL_INC_SCAN_DEV_NUM:
+ btcoexist->bt_info.increase_scan_dev_num = *bool_tmp;
+ break;
+ case BTC_SET_BL_BT_TX_RX_MASK:
+ btcoexist->bt_info.bt_tx_rx_mask = *bool_tmp;
+ break;
+ case BTC_SET_BL_MIRACAST_PLUS_BT:
+ btcoexist->bt_info.miracast_plus_bt = *bool_tmp;
+ break;
+ /* set some u1Byte type variables. */
+ case BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON:
+ btcoexist->bt_info.rssi_adjust_for_agc_table_on = *u8_tmp;
+ break;
+ case BTC_SET_U1_AGG_BUF_SIZE:
+ btcoexist->bt_info.agg_buf_size = *u8_tmp;
+ break;
+
+ /* the following are some action which will be triggered */
+ case BTC_SET_ACT_GET_BT_RSSI:
+ ret = false;
+ break;
+ case BTC_SET_ACT_AGGREGATE_CTRL:
+ halbtc_aggregation_check(btcoexist);
+ break;
+
+ /* 1Ant */
+ case BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE:
+ btcoexist->bt_info.rssi_adjust_for_1ant_coex_type = *u8_tmp;
+ break;
+ case BTC_SET_UI_SCAN_SIG_COMPENSATION:
+ break;
+ case BTC_SET_U1_LPS_VAL:
+ btcoexist->bt_info.lps_val = *u8_tmp;
+ break;
+ case BTC_SET_U1_RPWM_VAL:
+ btcoexist->bt_info.rpwm_val = *u8_tmp;
+ break;
+ /* the following are some action which will be triggered */
+ case BTC_SET_ACT_LEAVE_LPS:
+ halbtc_leave_lps(btcoexist);
+ break;
+ case BTC_SET_ACT_ENTER_LPS:
+ halbtc_enter_lps(btcoexist);
+ break;
+ case BTC_SET_ACT_NORMAL_LPS:
+ halbtc_normal_lps(btcoexist);
+ break;
+ case BTC_SET_ACT_DISABLE_LOW_POWER:
+ halbtc_disable_low_power(btcoexist, *bool_tmp);
+ break;
+ case BTC_SET_ACT_UPDATE_RAMASK:
+ btcoexist->bt_info.ra_mask = *u32_tmp;
+ break;
+ case BTC_SET_ACT_SEND_MIMO_PS:
+ break;
+ case BTC_SET_ACT_CTRL_BT_INFO: /*wait for 8812/8821*/
+ break;
+ case BTC_SET_ACT_CTRL_BT_COEX:
+ break;
+ case BTC_SET_ACT_CTRL_8723B_ANT:
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static void halbtc_display_coex_statistics(struct btc_coexist *btcoexist,
+ struct seq_file *m)
+{
+}
+
+static void halbtc_display_bt_link_info(struct btc_coexist *btcoexist,
+ struct seq_file *m)
+{
+}
+
+static void halbtc_display_wifi_status(struct btc_coexist *btcoexist,
+ struct seq_file *m)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ s32 wifi_rssi = 0, bt_hs_rssi = 0;
+ bool scan = false, link = false, roam = false, wifi_busy = false;
+ bool wifi_under_b_mode = false, wifi_under_5g = false;
+ u32 wifi_bw = BTC_WIFI_BW_HT20;
+ u32 wifi_traffic_dir = BTC_WIFI_TRAFFIC_TX;
+ u32 wifi_freq = BTC_FREQ_2_4G;
+ u32 wifi_link_status = 0x0;
+ bool bt_hs_on = false, under_ips = false, under_lps = false;
+ bool low_power = false, dc_mode = false;
+ u8 wifi_chnl = 0, wifi_hs_chnl = 0, fw_ps_state;
+ u8 ap_num = 0;
+
+ wifi_link_status = halbtc_get_wifi_link_status(btcoexist);
+ seq_printf(m, "\n %-35s = %d/ %d/ %d/ %d/ %d",
+ "STA/vWifi/HS/p2pGo/p2pGc",
+ ((wifi_link_status & WIFI_STA_CONNECTED) ? 1 : 0),
+ ((wifi_link_status & WIFI_AP_CONNECTED) ? 1 : 0),
+ ((wifi_link_status & WIFI_HS_CONNECTED) ? 1 : 0),
+ ((wifi_link_status & WIFI_P2P_GO_CONNECTED) ? 1 : 0),
+ ((wifi_link_status & WIFI_P2P_GC_CONNECTED) ? 1 : 0));
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL, &wifi_chnl);
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl);
+ seq_printf(m, "\n %-35s = %d / %d(%d)",
+ "Dot11 channel / HsChnl(High Speed)",
+ wifi_chnl, wifi_hs_chnl, bt_hs_on);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
+ btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi);
+ seq_printf(m, "\n %-35s = %d/ %d",
+ "Wifi rssi/ HS rssi",
+ wifi_rssi - 100, bt_hs_rssi - 100);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
+ seq_printf(m, "\n %-35s = %d/ %d/ %d ",
+ "Wifi link/ roam/ scan",
+ link, roam, scan);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION,
+ &wifi_traffic_dir);
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM, &ap_num);
+ wifi_freq = (wifi_under_5g ? BTC_FREQ_5G : BTC_FREQ_2_4G);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_B_MODE,
+ &wifi_under_b_mode);
+
+ seq_printf(m, "\n %-35s = %s / %s/ %s/ AP=%d ",
+ "Wifi freq/ bw/ traffic",
+ gl_btc_wifi_freq_string[wifi_freq],
+ ((wifi_under_b_mode) ? "11b" :
+ gl_btc_wifi_bw_string[wifi_bw]),
+ ((!wifi_busy) ? "idle" : ((BTC_WIFI_TRAFFIC_TX ==
+ wifi_traffic_dir) ? "uplink" :
+ "downlink")),
+ ap_num);
+
+ /* power status */
+ dc_mode = true; /*TODO*/
+ under_ips = rtlpriv->psc.inactive_pwrstate == ERFOFF ? 1 : 0;
+ under_lps = rtlpriv->psc.dot11_psmode == EACTIVE ? 0 : 1;
+ fw_ps_state = 0;
+ low_power = 0; /*TODO*/
+ seq_printf(m, "\n %-35s = %s%s%s%s",
+ "Power Status",
+ (dc_mode ? "DC mode" : "AC mode"),
+ (under_ips ? ", IPS ON" : ""),
+ (under_lps ? ", LPS ON" : ""),
+ (low_power ? ", 32k" : ""));
+
+ seq_printf(m,
+ "\n %-35s = %02x %02x %02x %02x %02x %02x (0x%x/0x%x)",
+ "Power mode cmd(lps/rpwm)",
+ btcoexist->pwr_mode_val[0], btcoexist->pwr_mode_val[1],
+ btcoexist->pwr_mode_val[2], btcoexist->pwr_mode_val[3],
+ btcoexist->pwr_mode_val[4], btcoexist->pwr_mode_val[5],
+ btcoexist->bt_info.lps_val,
+ btcoexist->bt_info.rpwm_val);
+}
+
+/************************************************************
+ * IO related function
+ ************************************************************/
+static u8 halbtc_read_1byte(void *bt_context, u32 reg_addr)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ return rtl_read_byte(rtlpriv, reg_addr);
+}
+
+static u16 halbtc_read_2byte(void *bt_context, u32 reg_addr)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ return rtl_read_word(rtlpriv, reg_addr);
+}
+
+static u32 halbtc_read_4byte(void *bt_context, u32 reg_addr)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ return rtl_read_dword(rtlpriv, reg_addr);
+}
+
+static void halbtc_write_1byte(void *bt_context, u32 reg_addr, u32 data)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ rtl_write_byte(rtlpriv, reg_addr, data);
+}
+
+static void halbtc_bitmask_write_1byte(void *bt_context, u32 reg_addr,
+ u32 bit_mask, u8 data)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ u8 original_value, bit_shift = 0;
+ u8 i;
+
+ if (bit_mask != MASKDWORD) {/*if not "double word" write*/
+ original_value = rtl_read_byte(rtlpriv, reg_addr);
+ for (i = 0; i <= 7; i++) {
+ if ((bit_mask >> i) & 0x1)
+ break;
+ }
+ bit_shift = i;
+ data = (original_value & (~bit_mask)) |
+ ((data << bit_shift) & bit_mask);
+ }
+ rtl_write_byte(rtlpriv, reg_addr, data);
+}
+
+static void halbtc_write_2byte(void *bt_context, u32 reg_addr, u16 data)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ rtl_write_word(rtlpriv, reg_addr, data);
+}
+
+static void halbtc_write_4byte(void *bt_context, u32 reg_addr, u32 data)
+{
+ struct btc_coexist *btcoexist =
+ (struct btc_coexist *)bt_context;
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ rtl_write_dword(rtlpriv, reg_addr, data);
+}
+
+static void halbtc_write_local_reg_1byte(void *btc_context, u32 reg_addr,
+ u8 data)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ if (btcoexist->chip_interface == BTC_INTF_SDIO)
+ ;
+ else if (btcoexist->chip_interface == BTC_INTF_PCI)
+ rtl_write_byte(rtlpriv, reg_addr, data);
+ else if (btcoexist->chip_interface == BTC_INTF_USB)
+ rtl_write_byte(rtlpriv, reg_addr, data);
+}
+
+static void halbtc_set_bbreg(void *bt_context, u32 reg_addr, u32 bit_mask,
+ u32 data)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ rtl_set_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask, data);
+}
+
+static u32 halbtc_get_bbreg(void *bt_context, u32 reg_addr, u32 bit_mask)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ return rtl_get_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask);
+}
+
+static void halbtc_set_rfreg(void *bt_context, u8 rf_path, u32 reg_addr,
+ u32 bit_mask, u32 data)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ rtl_set_rfreg(rtlpriv->mac80211.hw, rf_path, reg_addr, bit_mask, data);
+}
+
+static u32 halbtc_get_rfreg(void *bt_context, u8 rf_path, u32 reg_addr,
+ u32 bit_mask)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ return rtl_get_rfreg(rtlpriv->mac80211.hw, rf_path, reg_addr, bit_mask);
+}
+
+static void halbtc_fill_h2c_cmd(void *bt_context, u8 element_id,
+ u32 cmd_len, u8 *cmd_buf)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->mac80211.hw, element_id,
+ cmd_len, cmd_buf);
+}
+
+static void halbtc_send_wifi_port_id_cmd(void *bt_context)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ u8 cmd_buf[1] = {0}; /* port id [2:0] = 0 */
+
+ rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->mac80211.hw, 0x71, 1,
+ cmd_buf);
+}
+
+static void halbtc_set_default_port_id_cmd(void *bt_context)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ struct ieee80211_hw *hw = rtlpriv->mac80211.hw;
+
+ if (!rtlpriv->cfg->ops->set_default_port_id_cmd)
+ return;
+
+ rtlpriv->cfg->ops->set_default_port_id_cmd(hw);
+}
+
+static
+void halbtc_set_bt_reg(void *btc_context, u8 reg_type, u32 offset, u32 set_val)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
+ u8 cmd_buffer1[4] = {0};
+ u8 cmd_buffer2[4] = {0};
+
+ /* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
+ *((__le16 *)&cmd_buffer1[2]) = cpu_to_le16((u16)set_val);
+ if (!halbtc_send_bt_mp_operation(btcoexist, BT_OP_WRITE_REG_VALUE,
+ cmd_buffer1, 4, 200))
+ return;
+
+ /* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
+ cmd_buffer2[2] = reg_type;
+ *((u8 *)&cmd_buffer2[3]) = (u8)offset;
+ halbtc_send_bt_mp_operation(btcoexist, BT_OP_WRITE_REG_ADDR,
+ cmd_buffer2, 4, 200);
+}
+
+static void halbtc_display_dbg_msg(void *bt_context, u8 disp_type,
+ struct seq_file *m)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+
+ switch (disp_type) {
+ case BTC_DBG_DISP_COEX_STATISTICS:
+ halbtc_display_coex_statistics(btcoexist, m);
+ break;
+ case BTC_DBG_DISP_BT_LINK_INFO:
+ halbtc_display_bt_link_info(btcoexist, m);
+ break;
+ case BTC_DBG_DISP_WIFI_STATUS:
+ halbtc_display_wifi_status(btcoexist, m);
+ break;
+ default:
+ break;
+ }
+}
+
+static u32 halbtc_get_bt_reg(void *btc_context, u8 reg_type, u32 offset)
+{
+ return 0;
+}
+
+static
+u32 halbtc_get_phydm_version(void *btc_context)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+ if (rtlpriv->phydm.ops)
+ return rtlpriv->phydm.ops->phydm_get_version(rtlpriv);
+
+ return 0;
+}
+
+static
+void halbtc_phydm_modify_ra_pcr_threshold(void *btc_context,
+ u8 ra_offset_direction,
+ u8 ra_threshold_offset)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ struct rtl_phydm_ops *phydm_ops = rtlpriv->phydm.ops;
+
+ if (phydm_ops)
+ phydm_ops->phydm_modify_ra_pcr_threshold(rtlpriv,
+ ra_offset_direction,
+ ra_threshold_offset);
+}
+
+static
+u32 halbtc_phydm_query_phy_counter(void *btc_context, const char *info_type)
+{
+ /* info_type may be strings below:
+ * PHYDM_INFO_FA_OFDM, PHYDM_INFO_FA_CCK, PHYDM_INFO_CCA_OFDM,
+ * PHYDM_INFO_CCA_CCK
+ * IQK_TOTAL, IQK_OK, IQK_FAIL
+ */
+
+ struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ struct rtl_phydm_ops *phydm_ops = rtlpriv->phydm.ops;
+
+ if (phydm_ops)
+ return phydm_ops->phydm_query_counter(rtlpriv, info_type);
+
+ return 0;
+}
+
+static u8 halbtc_get_ant_det_val_from_bt(void *btc_context)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
+ u8 cmd_buffer[4] = {0};
+
+ /* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
+ halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_BT_ANT_DET_VAL,
+ cmd_buffer, 4, 200);
+
+ /* need wait completion to return correct value */
+
+ return btcoexist->bt_info.bt_ant_det_val;
+}
+
+static u8 halbtc_get_ble_scan_type_from_bt(void *btc_context)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
+ u8 cmd_buffer[4] = {0};
+
+ /* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
+ halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_BT_BLE_SCAN_TYPE,
+ cmd_buffer, 4, 200);
+
+ /* need wait completion to return correct value */
+
+ return btcoexist->bt_info.bt_ble_scan_type;
+}
+
+static u32 halbtc_get_ble_scan_para_from_bt(void *btc_context, u8 scan_type)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
+ u8 cmd_buffer[4] = {0};
+
+ /* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
+ halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_BT_BLE_SCAN_PARA,
+ cmd_buffer, 4, 200);
+
+ /* need wait completion to return correct value */
+
+ return btcoexist->bt_info.bt_ble_scan_para;
+}
+
+static bool halbtc_get_bt_afh_map_from_bt(void *btc_context, u8 map_type,
+ u8 *afh_map)
+{
+ struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
+ u8 cmd_buffer[2] = {0};
+ bool ret;
+ u32 *afh_map_l = (u32 *)afh_map;
+ u32 *afh_map_m = (u32 *)(afh_map + 4);
+ u16 *afh_map_h = (u16 *)(afh_map + 8);
+
+ /* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
+ ret = halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_AFH_MAP_L,
+ cmd_buffer, 2, 200);
+ if (!ret)
+ goto exit;
+
+ *afh_map_l = btcoexist->bt_info.afh_map_l;
+
+ /* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
+ ret = halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_AFH_MAP_M,
+ cmd_buffer, 2, 200);
+ if (!ret)
+ goto exit;
+
+ *afh_map_m = btcoexist->bt_info.afh_map_m;
+
+ /* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
+ ret = halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_AFH_MAP_H,
+ cmd_buffer, 2, 200);
+ if (!ret)
+ goto exit;
+
+ *afh_map_h = btcoexist->bt_info.afh_map_h;
+
+exit:
+ return ret;
+}
+
+/*****************************************************************
+ * Extern functions called by other module
+ *****************************************************************/
+bool exhalbtc_initlize_variables(struct rtl_priv *rtlpriv)
+{
+ struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+
+ if (!btcoexist)
+ return false;
+
+ halbtc_dbg_init();
+
+ btcoexist->btc_read_1byte = halbtc_read_1byte;
+ btcoexist->btc_write_1byte = halbtc_write_1byte;
+ btcoexist->btc_write_1byte_bitmask = halbtc_bitmask_write_1byte;
+ btcoexist->btc_read_2byte = halbtc_read_2byte;
+ btcoexist->btc_write_2byte = halbtc_write_2byte;
+ btcoexist->btc_read_4byte = halbtc_read_4byte;
+ btcoexist->btc_write_4byte = halbtc_write_4byte;
+ btcoexist->btc_write_local_reg_1byte = halbtc_write_local_reg_1byte;
+
+ btcoexist->btc_set_bb_reg = halbtc_set_bbreg;
+ btcoexist->btc_get_bb_reg = halbtc_get_bbreg;
+
+ btcoexist->btc_set_rf_reg = halbtc_set_rfreg;
+ btcoexist->btc_get_rf_reg = halbtc_get_rfreg;
+
+ btcoexist->btc_fill_h2c = halbtc_fill_h2c_cmd;
+ btcoexist->btc_disp_dbg_msg = halbtc_display_dbg_msg;
+
+ btcoexist->btc_get = halbtc_get;
+ btcoexist->btc_set = halbtc_set;
+ btcoexist->btc_set_bt_reg = halbtc_set_bt_reg;
+ btcoexist->btc_get_bt_reg = halbtc_get_bt_reg;
+
+ btcoexist->bt_info.bt_ctrl_buf_size = false;
+ btcoexist->bt_info.agg_buf_size = 5;
+
+ btcoexist->bt_info.increase_scan_dev_num = false;
+
+ btcoexist->btc_get_bt_coex_supported_feature =
+ halbtc_get_bt_coex_supported_feature;
+ btcoexist->btc_get_bt_coex_supported_version =
+ halbtc_get_bt_coex_supported_version;
+ btcoexist->btc_get_bt_phydm_version = halbtc_get_phydm_version;
+ btcoexist->btc_phydm_modify_ra_pcr_threshold =
+ halbtc_phydm_modify_ra_pcr_threshold;
+ btcoexist->btc_phydm_query_phy_counter = halbtc_phydm_query_phy_counter;
+ btcoexist->btc_get_ant_det_val_from_bt = halbtc_get_ant_det_val_from_bt;
+ btcoexist->btc_get_ble_scan_type_from_bt =
+ halbtc_get_ble_scan_type_from_bt;
+ btcoexist->btc_get_ble_scan_para_from_bt =
+ halbtc_get_ble_scan_para_from_bt;
+ btcoexist->btc_get_bt_afh_map_from_bt =
+ halbtc_get_bt_afh_map_from_bt;
+
+ init_completion(&btcoexist->bt_mp_comp);
+
+ return true;
+}
+
+bool exhalbtc_initlize_variables_wifi_only(struct rtl_priv *rtlpriv)
+{
+ struct wifi_only_cfg *wifionly_cfg = rtl_btc_wifi_only(rtlpriv);
+ struct wifi_only_haldata *wifionly_haldata;
+
+ if (!wifionly_cfg)
+ return false;
+
+ wifionly_cfg->adapter = rtlpriv;
+
+ switch (rtlpriv->rtlhal.interface) {
+ case INTF_PCI:
+ wifionly_cfg->chip_interface = BTC_INTF_PCI;
+ break;
+ case INTF_USB:
+ wifionly_cfg->chip_interface = BTC_INTF_USB;
+ break;
+ default:
+ wifionly_cfg->chip_interface = BTC_INTF_UNKNOWN;
+ break;
+ }
+
+ wifionly_haldata = &wifionly_cfg->haldata_info;
+
+ wifionly_haldata->customer_id = CUSTOMER_NORMAL;
+ wifionly_haldata->efuse_pg_antnum = rtl_get_hwpg_ant_num(rtlpriv);
+ wifionly_haldata->efuse_pg_antpath =
+ rtl_get_hwpg_single_ant_path(rtlpriv);
+ wifionly_haldata->rfe_type = rtl_get_hwpg_rfe_type(rtlpriv);
+ wifionly_haldata->ant_div_cfg = 0;
+
+ return true;
+}
+
+bool exhalbtc_bind_bt_coex_withadapter(void *adapter)
+{
+ struct rtl_priv *rtlpriv = adapter;
+ struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+ u8 ant_num = 2, chip_type, single_ant_path = 0;
+
+ if (!btcoexist)
+ return false;
+
+ if (btcoexist->binded)
+ return false;
+
+ switch (rtlpriv->rtlhal.interface) {
+ case INTF_PCI:
+ btcoexist->chip_interface = BTC_INTF_PCI;
+ break;
+ case INTF_USB:
+ btcoexist->chip_interface = BTC_INTF_USB;
+ break;
+ default:
+ btcoexist->chip_interface = BTC_INTF_UNKNOWN;
+ break;
+ }
+
+ btcoexist->binded = true;
+ btcoexist->statistics.cnt_bind++;
+
+ btcoexist->adapter = adapter;
+
+ btcoexist->stack_info.profile_notified = false;
+
+ btcoexist->bt_info.bt_ctrl_agg_buf_size = false;
+ btcoexist->bt_info.agg_buf_size = 5;
+
+ btcoexist->bt_info.increase_scan_dev_num = false;
+ btcoexist->bt_info.miracast_plus_bt = false;
+
+ chip_type = rtl_get_hwpg_bt_type(rtlpriv);
+ exhalbtc_set_chip_type(btcoexist, chip_type);
+ ant_num = rtl_get_hwpg_ant_num(rtlpriv);
+ exhalbtc_set_ant_num(rtlpriv, BT_COEX_ANT_TYPE_PG, ant_num);
+
+ /* set default antenna position to main port */
+ btcoexist->board_info.btdm_ant_pos = BTC_ANTENNA_AT_MAIN_PORT;
+
+ single_ant_path = rtl_get_hwpg_single_ant_path(rtlpriv);
+ exhalbtc_set_single_ant_path(btcoexist, single_ant_path);
+
+ if (rtl_get_hwpg_package_type(rtlpriv) == 0)
+ btcoexist->board_info.tfbga_package = false;
+ else if (rtl_get_hwpg_package_type(rtlpriv) == 1)
+ btcoexist->board_info.tfbga_package = false;
+ else
+ btcoexist->board_info.tfbga_package = true;
+
+ if (btcoexist->board_info.tfbga_package)
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Package Type = TFBGA\n");
+ else
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Package Type = Non-TFBGA\n");
+
+ btcoexist->board_info.rfe_type = rtl_get_hwpg_rfe_type(rtlpriv);
+ btcoexist->board_info.ant_div_cfg = 0;
+
+ return true;
+}
+
+void exhalbtc_power_on_setting(struct btc_coexist *btcoexist)
+{
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return;
+
+ btcoexist->statistics.cnt_power_on++;
+
+ if (IS_HARDWARE_TYPE_8822B(btcoexist->adapter)) {
+ if (btcoexist->board_info.btdm_ant_num == 1)
+ ex_btc8822b1ant_power_on_setting(btcoexist);
+ else if (btcoexist->board_info.btdm_ant_num == 2)
+ ex_btc8822b2ant_power_on_setting(btcoexist);
+ }
+}
+
+void exhalbtc_pre_load_firmware(struct btc_coexist *btcoexist)
+{
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return;
+
+ btcoexist->statistics.cnt_pre_load_firmware++;
+
+ if (IS_HARDWARE_TYPE_8822B(btcoexist->adapter)) {
+ if (btcoexist->board_info.btdm_ant_num == 1)
+ ex_btc8822b1ant_pre_load_firmware(btcoexist);
+ else if (btcoexist->board_info.btdm_ant_num == 2)
+ ex_btc8822b2ant_pre_load_firmware(btcoexist);
+ }
+}
+
+void exhalbtc_init_hw_config(struct btc_coexist *btcoexist, bool wifi_only)
+{
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return;
+
+ btcoexist->statistics.cnt_init_hw_config++;
+
+ if (IS_HARDWARE_TYPE_8822B(btcoexist->adapter)) {
+ if (btcoexist->board_info.btdm_ant_num == 1)
+ ex_btc8822b1ant_init_hw_config(btcoexist, wifi_only);
+ else if (btcoexist->board_info.btdm_ant_num == 2)
+ ex_btc8822b2ant_init_hw_config(btcoexist, wifi_only);
+
+ halbtc_set_default_port_id_cmd(btcoexist);
+ halbtc_send_wifi_port_id_cmd(btcoexist);
+ }
+}
+
+void exhalbtc_init_hw_config_wifi_only(struct wifi_only_cfg *wifionly_cfg)
+{
+ if (IS_HARDWARE_TYPE_8822B(wifionly_cfg->adapter))
+ ex_hal8822b_wifi_only_hw_config(wifionly_cfg);
+}
+
+void exhalbtc_init_coex_dm(struct btc_coexist *btcoexist)
+{
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return;
+
+ btcoexist->statistics.cnt_init_coex_dm++;
+
+ if (IS_HARDWARE_TYPE_8822B(btcoexist->adapter)) {
+ if (btcoexist->board_info.btdm_ant_num == 1)
+ ex_btc8822b1ant_init_coex_dm(btcoexist);
+ else if (btcoexist->board_info.btdm_ant_num == 2)
+ ex_btc8822b2ant_init_coex_dm(btcoexist);
+ }
+
+ btcoexist->initilized = true;
+}
+
+void exhalbtc_ips_notify(struct btc_coexist *btcoexist, u8 type)
+{
+ u8 ips_type;
+
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return;
+ btcoexist->statistics.cnt_ips_notify++;
+ if (btcoexist->manual_control)
+ return;
+
+ if (type == ERFOFF)
+ ips_type = BTC_IPS_ENTER;
+ else
+ ips_type = BTC_IPS_LEAVE;
+
+ halbtc_leave_low_power(btcoexist);
+
+ if (IS_HARDWARE_TYPE_8822B(btcoexist->adapter)) {
+ if (btcoexist->board_info.btdm_ant_num == 1)
+ ex_btc8822b1ant_ips_notify(btcoexist, ips_type);
+ else if (btcoexist->board_info.btdm_ant_num == 2)
+ ex_btc8822b2ant_ips_notify(btcoexist, ips_type);
+ }
+
+ halbtc_normal_low_power(btcoexist);
+}
+
+void exhalbtc_lps_notify(struct btc_coexist *btcoexist, u8 type)
+{
+ u8 lps_type;
+
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return;
+ btcoexist->statistics.cnt_lps_notify++;
+ if (btcoexist->manual_control)
+ return;
+
+ if (type == EACTIVE)
+ lps_type = BTC_LPS_DISABLE;
+ else
+ lps_type = BTC_LPS_ENABLE;
+
+ if (IS_HARDWARE_TYPE_8822B(btcoexist->adapter)) {
+ if (btcoexist->board_info.btdm_ant_num == 1)
+ ex_btc8822b1ant_lps_notify(btcoexist, lps_type);
+ else if (btcoexist->board_info.btdm_ant_num == 2)
+ ex_btc8822b2ant_lps_notify(btcoexist, lps_type);
+ }
+}
+
+void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type)
+{
+ u8 scan_type;
+
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return;
+ btcoexist->statistics.cnt_scan_notify++;
+ if (btcoexist->manual_control)
+ return;
+
+ if (type)
+ scan_type = BTC_SCAN_START;
+ else
+ scan_type = BTC_SCAN_FINISH;
+
+ halbtc_leave_low_power(btcoexist);
+
+ if (IS_HARDWARE_TYPE_8822B(btcoexist->adapter)) {
+ if (btcoexist->board_info.btdm_ant_num == 1)
+ ex_btc8822b1ant_scan_notify(btcoexist, scan_type);
+ else if (btcoexist->board_info.btdm_ant_num == 2)
+ ex_btc8822b2ant_scan_notify(btcoexist, scan_type);
+ }
+
+ halbtc_normal_low_power(btcoexist);
+}
+
+void exhalbtc_scan_notify_wifi_only(struct wifi_only_cfg *wifionly_cfg,
+ u8 is_5g)
+{
+ if (IS_HARDWARE_TYPE_8822B(wifionly_cfg->adapter))
+ ex_hal8822b_wifi_only_scannotify(wifionly_cfg, is_5g);
+}
+
+void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action)
+{
+ u8 asso_type;
+
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return;
+ btcoexist->statistics.cnt_connect_notify++;
+ if (btcoexist->manual_control)
+ return;
+
+ if (action)
+ asso_type = BTC_ASSOCIATE_START;
+ else
+ asso_type = BTC_ASSOCIATE_FINISH;
+
+ halbtc_leave_low_power(btcoexist);
+
+ if (IS_HARDWARE_TYPE_8822B(btcoexist->adapter)) {
+ if (btcoexist->board_info.btdm_ant_num == 1)
+ ex_btc8822b1ant_connect_notify(btcoexist, asso_type);
+ else if (btcoexist->board_info.btdm_ant_num == 2)
+ ex_btc8822b2ant_connect_notify(btcoexist, asso_type);
+ }
+
+ halbtc_normal_low_power(btcoexist);
+}
+
+void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist,
+ enum rt_media_status media_status)
+{
+ u8 status;
+
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return;
+ btcoexist->statistics.cnt_media_status_notify++;
+ if (btcoexist->manual_control)
+ return;
+
+ if (media_status == RT_MEDIA_CONNECT)
+ status = BTC_MEDIA_CONNECT;
+ else
+ status = BTC_MEDIA_DISCONNECT;
+
+ halbtc_leave_low_power(btcoexist);
+
+ if (IS_HARDWARE_TYPE_8822B(btcoexist->adapter)) {
+ if (btcoexist->board_info.btdm_ant_num == 1)
+ ex_btc8822b1ant_media_status_notify(btcoexist, status);
+ else if (btcoexist->board_info.btdm_ant_num == 2)
+ ex_btc8822b2ant_media_status_notify(btcoexist, status);
+ }
+
+ halbtc_normal_low_power(btcoexist);
+}
+
+void exhalbtc_special_packet_notify(struct btc_coexist *btcoexist, u8 pkt_type)
+{
+ u8 packet_type;
+
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return;
+ btcoexist->statistics.cnt_special_packet_notify++;
+ if (btcoexist->manual_control)
+ return;
+
+ if (pkt_type == PACKET_DHCP) {
+ packet_type = BTC_PACKET_DHCP;
+ } else if (pkt_type == PACKET_EAPOL) {
+ packet_type = BTC_PACKET_EAPOL;
+ } else if (pkt_type == PACKET_ARP) {
+ packet_type = BTC_PACKET_ARP;
+ } else {
+ packet_type = BTC_PACKET_UNKNOWN;
+ return;
+ }
+
+ halbtc_leave_low_power(btcoexist);
+
+ if (IS_HARDWARE_TYPE_8822B(btcoexist->adapter)) {
+ if (btcoexist->board_info.btdm_ant_num == 1)
+ ex_btc8822b1ant_specific_packet_notify(btcoexist,
+ packet_type);
+ else if (btcoexist->board_info.btdm_ant_num == 2)
+ ex_btc8822b2ant_specific_packet_notify(btcoexist,
+ packet_type);
+ }
+
+ halbtc_normal_low_power(btcoexist);
+}
+
+void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist,
+ u8 *tmp_buf, u8 length)
+{
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return;
+ btcoexist->statistics.cnt_bt_info_notify++;
+
+ halbtc_leave_low_power(btcoexist);
+
+ if (IS_HARDWARE_TYPE_8822B(btcoexist->adapter)) {
+ if (btcoexist->board_info.btdm_ant_num == 1)
+ ex_btc8822b1ant_bt_info_notify(btcoexist, tmp_buf,
+ length);
+ else if (btcoexist->board_info.btdm_ant_num == 2)
+ ex_btc8822b2ant_bt_info_notify(btcoexist, tmp_buf,
+ length);
+ }
+
+ halbtc_normal_low_power(btcoexist);
+}
+
+void exhalbtc_rf_status_notify(struct btc_coexist *btcoexist, u8 type)
+{
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return;
+
+ if (IS_HARDWARE_TYPE_8822B(btcoexist->adapter)) {
+ if (btcoexist->board_info.btdm_ant_num == 1)
+ ex_btc8822b1ant_rf_status_notify(btcoexist, type);
+ else if (btcoexist->board_info.btdm_ant_num == 2)
+ ex_btc8822b2ant_rf_status_notify(btcoexist, type);
+ }
+}
+
+void exhalbtc_stack_operation_notify(struct btc_coexist *btcoexist, u8 type)
+{
+ u8 stack_op_type;
+
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return;
+ btcoexist->statistics.cnt_stack_operation_notify++;
+ if (btcoexist->manual_control)
+ return;
+
+ if ((type == HCI_BT_OP_INQUIRY_START) ||
+ (type == HCI_BT_OP_PAGING_START) ||
+ (type == HCI_BT_OP_PAIRING_START)) {
+ stack_op_type = BTC_STACK_OP_INQ_PAGE_PAIR_START;
+ } else if ((type == HCI_BT_OP_INQUIRY_FINISH) ||
+ (type == HCI_BT_OP_PAGING_SUCCESS) ||
+ (type == HCI_BT_OP_PAGING_UNSUCCESS) ||
+ (type == HCI_BT_OP_PAIRING_FINISH)) {
+ stack_op_type = BTC_STACK_OP_INQ_PAGE_PAIR_FINISH;
+ } else {
+ stack_op_type = BTC_STACK_OP_NONE;
+ }
+}
+
+void exhalbtc_halt_notify(struct btc_coexist *btcoexist)
+{
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return;
+
+ if (IS_HARDWARE_TYPE_8822B(btcoexist->adapter)) {
+ if (btcoexist->board_info.btdm_ant_num == 1)
+ ex_btc8822b1ant_halt_notify(btcoexist);
+ else if (btcoexist->board_info.btdm_ant_num == 2)
+ ex_btc8822b2ant_halt_notify(btcoexist);
+ }
+
+ btcoexist->binded = false;
+}
+
+void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state)
+{
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return;
+
+ /* currently only 1ant we have to do the notification,
+ * once pnp is notified to sleep state, we have to leave LPS that
+ * we can sleep normally.
+ */
+
+ if (IS_HARDWARE_TYPE_8822B(btcoexist->adapter)) {
+ if (btcoexist->board_info.btdm_ant_num == 1)
+ ex_btc8822b1ant_pnp_notify(btcoexist, pnp_state);
+ else if (btcoexist->board_info.btdm_ant_num == 2)
+ ex_btc8822b2ant_pnp_notify(btcoexist, pnp_state);
+ }
+}
+
+void exhalbtc_coex_dm_switch(struct btc_coexist *btcoexist)
+{
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return;
+ btcoexist->statistics.cnt_coex_dm_switch++;
+
+ halbtc_leave_low_power(btcoexist);
+
+ halbtc_normal_low_power(btcoexist);
+}
+
+void exhalbtc_periodical(struct btc_coexist *btcoexist)
+{
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return;
+ btcoexist->statistics.cnt_periodical++;
+
+ halbtc_leave_low_power(btcoexist);
+
+ if (IS_HARDWARE_TYPE_8822B(btcoexist->adapter)) {
+ if (btcoexist->board_info.btdm_ant_num == 1)
+ ex_btc8822b1ant_periodical(btcoexist);
+ else if (btcoexist->board_info.btdm_ant_num == 2)
+ ex_btc8822b2ant_periodical(btcoexist);
+ }
+
+ halbtc_normal_low_power(btcoexist);
+}
+
+void exhalbtc_dbg_control(struct btc_coexist *btcoexist,
+ u8 code, u8 len, u8 *data)
+{
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return;
+ btcoexist->statistics.cnt_dbg_ctrl++;
+
+ halbtc_leave_low_power(btcoexist);
+
+ halbtc_normal_low_power(btcoexist);
+}
+
+void exhalbtc_antenna_detection(struct btc_coexist *btcoexist, u32 cent_freq,
+ u32 offset, u32 span, u32 seconds)
+{
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return;
+}
+
+void exhalbtc_stack_update_profile_info(void)
+{
+}
+
+void exhalbtc_update_min_bt_rssi(struct btc_coexist *btcoexist, s8 bt_rssi)
+{
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return;
+
+ btcoexist->stack_info.min_bt_rssi = bt_rssi;
+}
+
+void exhalbtc_set_hci_version(struct btc_coexist *btcoexist, u16 hci_version)
+{
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return;
+
+ btcoexist->stack_info.hci_version = hci_version;
+}
+
+void exhalbtc_set_bt_patch_version(struct btc_coexist *btcoexist,
+ u16 bt_hci_version, u16 bt_patch_version)
+{
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return;
+
+ btcoexist->bt_info.bt_real_fw_ver = bt_patch_version;
+ btcoexist->bt_info.bt_hci_ver = bt_hci_version;
+}
+
+void exhalbtc_set_chip_type(struct btc_coexist *btcoexist, u8 chip_type)
+{
+ switch (chip_type) {
+ default:
+ case BT_2WIRE:
+ case BT_ISSC_3WIRE:
+ case BT_ACCEL:
+ case BT_RTL8756:
+ btcoexist->board_info.bt_chip_type = BTC_CHIP_UNDEF;
+ break;
+ case BT_CSR_BC4:
+ btcoexist->board_info.bt_chip_type = BTC_CHIP_CSR_BC4;
+ break;
+ case BT_CSR_BC8:
+ btcoexist->board_info.bt_chip_type = BTC_CHIP_CSR_BC8;
+ break;
+ case BT_RTL8723A:
+ btcoexist->board_info.bt_chip_type = BTC_CHIP_RTL8723A;
+ break;
+ case BT_RTL8821A:
+ btcoexist->board_info.bt_chip_type = BTC_CHIP_RTL8821;
+ break;
+ case BT_RTL8723B:
+ btcoexist->board_info.bt_chip_type = BTC_CHIP_RTL8723B;
+ break;
+ }
+}
+
+void exhalbtc_set_ant_num(struct rtl_priv *rtlpriv, u8 type, u8 ant_num)
+{
+ struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+
+ if (!btcoexist)
+ return;
+
+ if (type == BT_COEX_ANT_TYPE_PG) {
+ btcoexist->board_info.pg_ant_num = ant_num;
+ btcoexist->board_info.btdm_ant_num = ant_num;
+ } else if (type == BT_COEX_ANT_TYPE_ANTDIV) {
+ btcoexist->board_info.btdm_ant_num = ant_num;
+ } else if (type == BT_COEX_ANT_TYPE_DETECTED) {
+ btcoexist->board_info.btdm_ant_num = ant_num;
+ if (rtlpriv->cfg->mod_params->ant_sel == 1)
+ btcoexist->board_info.btdm_ant_pos =
+ BTC_ANTENNA_AT_AUX_PORT;
+ else
+ btcoexist->board_info.btdm_ant_pos =
+ BTC_ANTENNA_AT_MAIN_PORT;
+ }
+}
+
+/* Currently used by 8723b only, S0 or S1 */
+void exhalbtc_set_single_ant_path(struct btc_coexist *btcoexist,
+ u8 single_ant_path)
+{
+ btcoexist->board_info.single_ant_path = single_ant_path;
+}
+
+void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist,
+ struct seq_file *m)
+{
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return;
+
+ halbtc_leave_low_power(btcoexist);
+
+ if (IS_HARDWARE_TYPE_8822B(btcoexist->adapter)) {
+ if (btcoexist->board_info.btdm_ant_num == 1)
+ ex_btc8822b1ant_display_coex_info(btcoexist, m);
+ else if (btcoexist->board_info.btdm_ant_num == 2)
+ ex_btc8822b2ant_display_coex_info(btcoexist, m);
+ }
+
+ halbtc_normal_low_power(btcoexist);
+}
+
+void exhalbtc_switch_band_notify(struct btc_coexist *btcoexist, u8 type)
+{
+ if (!halbtc_is_bt_coexist_available(btcoexist))
+ return;
+
+ if (btcoexist->manual_control)
+ return;
+
+ halbtc_leave_low_power(btcoexist);
+
+ if (IS_HARDWARE_TYPE_8822B(btcoexist->adapter)) {
+ if (btcoexist->board_info.btdm_ant_num == 1)
+ ex_btc8822b1ant_switchband_notify(btcoexist, type);
+ else if (btcoexist->board_info.btdm_ant_num == 2)
+ ex_btc8822b2ant_switchband_notify(btcoexist, type);
+ }
+
+ halbtc_normal_low_power(btcoexist);
+}
+
+void exhalbtc_switch_band_notify_wifi_only(struct wifi_only_cfg *wifionly_cfg,
+ u8 is_5g)
+{
+ if (IS_HARDWARE_TYPE_8822B(wifionly_cfg->adapter))
+ ex_hal8822b_wifi_only_switchbandnotify(wifionly_cfg, is_5g);
+}
diff --git a/drivers/staging/rtlwifi/btcoexist/halbtcoutsrc.h b/drivers/staging/rtlwifi/btcoexist/halbtcoutsrc.h
new file mode 100644
index 0000000..8913983
--- /dev/null
+++ b/drivers/staging/rtlwifi/btcoexist/halbtcoutsrc.h
@@ -0,0 +1,802 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2012 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __HALBTC_OUT_SRC_H__
+#define __HALBTC_OUT_SRC_H__
+
+#include "../wifi.h"
+
+#define BTC_COEX_OFFLOAD 0
+
+#define NORMAL_EXEC false
+#define FORCE_EXEC true
+
+#define BTC_RF_OFF 0x0
+#define BTC_RF_ON 0x1
+
+#define BTC_RF_A RF90_PATH_A
+#define BTC_RF_B RF90_PATH_B
+#define BTC_RF_C RF90_PATH_C
+#define BTC_RF_D RF90_PATH_D
+
+#define BTC_SMSP SINGLEMAC_SINGLEPHY
+#define BTC_DMDP DUALMAC_DUALPHY
+#define BTC_DMSP DUALMAC_SINGLEPHY
+#define BTC_MP_UNKNOWN 0xff
+
+#define IN
+#define OUT
+
+#define BT_TMP_BUF_SIZE 100
+
+#define BT_COEX_ANT_TYPE_PG 0
+#define BT_COEX_ANT_TYPE_ANTDIV 1
+#define BT_COEX_ANT_TYPE_DETECTED 2
+
+#define BTC_MIMO_PS_STATIC 0
+#define BTC_MIMO_PS_DYNAMIC 1
+
+#define BTC_RATE_DISABLE 0
+#define BTC_RATE_ENABLE 1
+
+/* single Antenna definition */
+#define BTC_ANT_PATH_WIFI 0
+#define BTC_ANT_PATH_BT 1
+#define BTC_ANT_PATH_PTA 2
+#define BTC_ANT_PATH_WIFI5G 3
+#define BTC_ANT_PATH_AUTO 4
+/* dual Antenna definition */
+#define BTC_ANT_WIFI_AT_MAIN 0
+#define BTC_ANT_WIFI_AT_AUX 1
+#define BTC_ANT_WIFI_AT_DIVERSITY 2
+/* coupler Antenna definition */
+#define BTC_ANT_WIFI_AT_CPL_MAIN 0
+#define BTC_ANT_WIFI_AT_CPL_AUX 1
+
+enum btc_bt_reg_type {
+ BTC_BT_REG_RF = 0,
+ BTC_BT_REG_MODEM = 1,
+ BTC_BT_REG_BLUEWIZE = 2,
+ BTC_BT_REG_VENDOR = 3,
+ BTC_BT_REG_LE = 4,
+ BTC_BT_REG_MAX
+};
+
+enum btc_chip_interface {
+ BTC_INTF_UNKNOWN = 0,
+ BTC_INTF_PCI = 1,
+ BTC_INTF_USB = 2,
+ BTC_INTF_SDIO = 3,
+ BTC_INTF_GSPI = 4,
+ BTC_INTF_MAX
+};
+
+enum btc_chip_type {
+ BTC_CHIP_UNDEF = 0,
+ BTC_CHIP_CSR_BC4 = 1,
+ BTC_CHIP_CSR_BC8 = 2,
+ BTC_CHIP_RTL8723A = 3,
+ BTC_CHIP_RTL8821 = 4,
+ BTC_CHIP_RTL8723B = 5,
+ BTC_CHIP_MAX
+};
+
+enum btc_msg_type {
+ BTC_MSG_INTERFACE = 0x0,
+ BTC_MSG_ALGORITHM = 0x1,
+ BTC_MSG_MAX
+};
+
+/* following is for BTC_MSG_INTERFACE */
+#define INTF_INIT BIT0
+#define INTF_NOTIFY BIT2
+
+/* following is for BTC_ALGORITHM */
+#define ALGO_BT_RSSI_STATE BIT0
+#define ALGO_WIFI_RSSI_STATE BIT1
+#define ALGO_BT_MONITOR BIT2
+#define ALGO_TRACE BIT3
+#define ALGO_TRACE_FW BIT4
+#define ALGO_TRACE_FW_DETAIL BIT5
+#define ALGO_TRACE_FW_EXEC BIT6
+#define ALGO_TRACE_SW BIT7
+#define ALGO_TRACE_SW_DETAIL BIT8
+#define ALGO_TRACE_SW_EXEC BIT9
+
+/* following is for wifi link status */
+#define WIFI_STA_CONNECTED BIT0
+#define WIFI_AP_CONNECTED BIT1
+#define WIFI_HS_CONNECTED BIT2
+#define WIFI_P2P_GO_CONNECTED BIT3
+#define WIFI_P2P_GC_CONNECTED BIT4
+
+#define BTC_RSSI_HIGH(_rssi_) \
+ ((_rssi_ == BTC_RSSI_STATE_HIGH || \
+ _rssi_ == BTC_RSSI_STATE_STAY_HIGH) ? true : false)
+#define BTC_RSSI_MEDIUM(_rssi_) \
+ ((_rssi_ == BTC_RSSI_STATE_MEDIUM || \
+ _rssi_ == BTC_RSSI_STATE_STAY_MEDIUM) ? true : false)
+#define BTC_RSSI_LOW(_rssi_) \
+ ((_rssi_ == BTC_RSSI_STATE_LOW || \
+ _rssi_ == BTC_RSSI_STATE_STAY_LOW) ? true : false)
+
+enum btc_power_save_type {
+ BTC_PS_WIFI_NATIVE = 0,
+ BTC_PS_LPS_ON = 1,
+ BTC_PS_LPS_OFF = 2,
+ BTC_PS_LPS_MAX
+};
+
+struct btc_board_info {
+ /* The following is some board information */
+ u8 bt_chip_type;
+ u8 pg_ant_num; /* pg ant number */
+ u8 btdm_ant_num; /* ant number for btdm */
+ u8 btdm_ant_num_by_ant_det;
+ u8 btdm_ant_pos;
+ u8 single_ant_path; /* current used for 8723b only, 1=>s0, 0=>s1 */
+ bool tfbga_package;
+ bool btdm_ant_det_finish;
+
+ u8 rfe_type;
+ u8 ant_div_cfg;
+};
+
+enum btc_dbg_opcode {
+ BTC_DBG_SET_COEX_NORMAL = 0x0,
+ BTC_DBG_SET_COEX_WIFI_ONLY = 0x1,
+ BTC_DBG_SET_COEX_BT_ONLY = 0x2,
+ BTC_DBG_MAX
+};
+
+enum btc_rssi_state {
+ BTC_RSSI_STATE_HIGH = 0x0,
+ BTC_RSSI_STATE_MEDIUM = 0x1,
+ BTC_RSSI_STATE_LOW = 0x2,
+ BTC_RSSI_STATE_STAY_HIGH = 0x3,
+ BTC_RSSI_STATE_STAY_MEDIUM = 0x4,
+ BTC_RSSI_STATE_STAY_LOW = 0x5,
+ BTC_RSSI_MAX
+};
+
+enum btc_wifi_role {
+ BTC_ROLE_STATION = 0x0,
+ BTC_ROLE_AP = 0x1,
+ BTC_ROLE_IBSS = 0x2,
+ BTC_ROLE_HS_MODE = 0x3,
+ BTC_ROLE_MAX
+};
+
+enum btc_wireless_freq {
+ BTC_FREQ_2_4G = 0x0,
+ BTC_FREQ_5G = 0x1,
+ BTC_FREQ_MAX
+};
+
+enum btc_wifi_bw_mode {
+ BTC_WIFI_BW_LEGACY = 0x0,
+ BTC_WIFI_BW_HT20 = 0x1,
+ BTC_WIFI_BW_HT40 = 0x2,
+ BTC_WIFI_BW_HT80 = 0x3,
+ BTC_WIFI_BW_MAX
+};
+
+enum btc_wifi_traffic_dir {
+ BTC_WIFI_TRAFFIC_TX = 0x0,
+ BTC_WIFI_TRAFFIC_RX = 0x1,
+ BTC_WIFI_TRAFFIC_MAX
+};
+
+enum btc_wifi_pnp {
+ BTC_WIFI_PNP_WAKE_UP = 0x0,
+ BTC_WIFI_PNP_SLEEP = 0x1,
+ BTC_WIFI_PNP_SLEEP_KEEP_ANT = 0x2,
+ BTC_WIFI_PNP_MAX
+};
+
+enum btc_iot_peer {
+ BTC_IOT_PEER_UNKNOWN = 0,
+ BTC_IOT_PEER_REALTEK = 1,
+ BTC_IOT_PEER_REALTEK_92SE = 2,
+ BTC_IOT_PEER_BROADCOM = 3,
+ BTC_IOT_PEER_RALINK = 4,
+ BTC_IOT_PEER_ATHEROS = 5,
+ BTC_IOT_PEER_CISCO = 6,
+ BTC_IOT_PEER_MERU = 7,
+ BTC_IOT_PEER_MARVELL = 8,
+ BTC_IOT_PEER_REALTEK_SOFTAP = 9,
+ BTC_IOT_PEER_SELF_SOFTAP = 10, /* Self is SoftAP */
+ BTC_IOT_PEER_AIRGO = 11,
+ BTC_IOT_PEER_REALTEK_JAGUAR_BCUTAP = 12,
+ BTC_IOT_PEER_REALTEK_JAGUAR_CCUTAP = 13,
+ BTC_IOT_PEER_MAX,
+};
+
+/* for 8723b-d cut large current issue */
+enum bt_wifi_coex_state {
+ BTC_WIFI_STAT_INIT,
+ BTC_WIFI_STAT_IQK,
+ BTC_WIFI_STAT_NORMAL_OFF,
+ BTC_WIFI_STAT_MP_OFF,
+ BTC_WIFI_STAT_NORMAL,
+ BTC_WIFI_STAT_ANT_DIV,
+ BTC_WIFI_STAT_MAX
+};
+
+enum bt_ant_type {
+ BTC_ANT_TYPE_0,
+ BTC_ANT_TYPE_1,
+ BTC_ANT_TYPE_2,
+ BTC_ANT_TYPE_3,
+ BTC_ANT_TYPE_4,
+ BTC_ANT_TYPE_MAX
+};
+
+enum btc_get_type {
+ /* type bool */
+ BTC_GET_BL_HS_OPERATION,
+ BTC_GET_BL_HS_CONNECTING,
+ BTC_GET_BL_WIFI_CONNECTED,
+ BTC_GET_BL_WIFI_BUSY,
+ BTC_GET_BL_WIFI_SCAN,
+ BTC_GET_BL_WIFI_LINK,
+ BTC_GET_BL_WIFI_DHCP,
+ BTC_GET_BL_WIFI_SOFTAP_IDLE,
+ BTC_GET_BL_WIFI_SOFTAP_LINKING,
+ BTC_GET_BL_WIFI_IN_EARLY_SUSPEND,
+ BTC_GET_BL_WIFI_ROAM,
+ BTC_GET_BL_WIFI_4_WAY_PROGRESS,
+ BTC_GET_BL_WIFI_UNDER_5G,
+ BTC_GET_BL_WIFI_AP_MODE_ENABLE,
+ BTC_GET_BL_WIFI_ENABLE_ENCRYPTION,
+ BTC_GET_BL_WIFI_UNDER_B_MODE,
+ BTC_GET_BL_EXT_SWITCH,
+ BTC_GET_BL_WIFI_IS_IN_MP_MODE,
+ BTC_GET_BL_IS_ASUS_8723B,
+ BTC_GET_BL_FW_READY,
+ BTC_GET_BL_RF4CE_CONNECTED,
+
+ /* type s4Byte */
+ BTC_GET_S4_WIFI_RSSI,
+ BTC_GET_S4_HS_RSSI,
+
+ /* type u32 */
+ BTC_GET_U4_WIFI_BW,
+ BTC_GET_U4_WIFI_TRAFFIC_DIRECTION,
+ BTC_GET_U4_WIFI_FW_VER,
+ BTC_GET_U4_WIFI_LINK_STATUS,
+ BTC_GET_U4_BT_PATCH_VER,
+ BTC_GET_U4_VENDOR,
+ BTC_GET_U4_SUPPORTED_VERSION,
+ BTC_GET_U4_SUPPORTED_FEATURE,
+ BTC_GET_U4_WIFI_IQK_TOTAL,
+ BTC_GET_U4_WIFI_IQK_OK,
+ BTC_GET_U4_WIFI_IQK_FAIL,
+
+ /* type u1Byte */
+ BTC_GET_U1_WIFI_DOT11_CHNL,
+ BTC_GET_U1_WIFI_CENTRAL_CHNL,
+ BTC_GET_U1_WIFI_HS_CHNL,
+ BTC_GET_U1_MAC_PHY_MODE,
+ BTC_GET_U1_AP_NUM,
+ BTC_GET_U1_ANT_TYPE,
+ BTC_GET_U1_IOT_PEER,
+
+ /* for 1Ant */
+ BTC_GET_U1_LPS_MODE,
+ BTC_GET_BL_BT_SCO_BUSY,
+
+ /* for test mode */
+ BTC_GET_DRIVER_TEST_CFG,
+ BTC_GET_MAX
+};
+
+enum btc_vendor {
+ BTC_VENDOR_LENOVO,
+ BTC_VENDOR_ASUS,
+ BTC_VENDOR_OTHER
+};
+
+enum btc_set_type {
+ /* type bool */
+ BTC_SET_BL_BT_DISABLE,
+ BTC_SET_BL_BT_ENABLE_DISABLE_CHANGE,
+ BTC_SET_BL_BT_TRAFFIC_BUSY,
+ BTC_SET_BL_BT_LIMITED_DIG,
+ BTC_SET_BL_FORCE_TO_ROAM,
+ BTC_SET_BL_TO_REJ_AP_AGG_PKT,
+ BTC_SET_BL_BT_CTRL_AGG_SIZE,
+ BTC_SET_BL_INC_SCAN_DEV_NUM,
+ BTC_SET_BL_BT_TX_RX_MASK,
+ BTC_SET_BL_MIRACAST_PLUS_BT,
+
+ /* type u1Byte */
+ BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON,
+ BTC_SET_UI_SCAN_SIG_COMPENSATION,
+ BTC_SET_U1_AGG_BUF_SIZE,
+
+ /* type trigger some action */
+ BTC_SET_ACT_GET_BT_RSSI,
+ BTC_SET_ACT_AGGREGATE_CTRL,
+ BTC_SET_ACT_ANTPOSREGRISTRY_CTRL,
+
+ /********* for 1Ant **********/
+ /* type bool */
+ BTC_SET_BL_BT_SCO_BUSY,
+ /* type u1Byte */
+ BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE,
+ BTC_SET_U1_LPS_VAL,
+ BTC_SET_U1_RPWM_VAL,
+ BTC_SET_U1_1ANT_LPS,
+ BTC_SET_U1_1ANT_RPWM,
+ /* type trigger some action */
+ BTC_SET_ACT_LEAVE_LPS,
+ BTC_SET_ACT_ENTER_LPS,
+ BTC_SET_ACT_NORMAL_LPS,
+ BTC_SET_ACT_INC_FORCE_EXEC_PWR_CMD_CNT,
+ BTC_SET_ACT_DISABLE_LOW_POWER,
+ BTC_SET_ACT_UPDATE_RAMASK,
+ BTC_SET_ACT_SEND_MIMO_PS,
+ /* BT Coex related */
+ BTC_SET_ACT_CTRL_BT_INFO,
+ BTC_SET_ACT_CTRL_BT_COEX,
+ BTC_SET_ACT_CTRL_8723B_ANT,
+ /***************************/
+ BTC_SET_MAX
+};
+
+enum btc_dbg_disp_type {
+ BTC_DBG_DISP_COEX_STATISTICS = 0x0,
+ BTC_DBG_DISP_BT_LINK_INFO = 0x1,
+ BTC_DBG_DISP_BT_FW_VER = 0x2,
+ BTC_DBG_DISP_FW_PWR_MODE_CMD = 0x3,
+ BTC_DBG_DISP_WIFI_STATUS = 0x04,
+ BTC_DBG_DISP_MAX
+};
+
+enum btc_notify_type_ips {
+ BTC_IPS_LEAVE = 0x0,
+ BTC_IPS_ENTER = 0x1,
+ BTC_IPS_MAX
+};
+
+enum btc_notify_type_lps {
+ BTC_LPS_DISABLE = 0x0,
+ BTC_LPS_ENABLE = 0x1,
+ BTC_LPS_MAX
+};
+
+enum btc_notify_type_scan {
+ BTC_SCAN_FINISH = 0x0,
+ BTC_SCAN_START = 0x1,
+ BTC_SCAN_START_2G = 0x2,
+ BTC_SCAN_MAX
+};
+
+enum btc_notify_type_switchband {
+ BTC_NOT_SWITCH = 0x0,
+ BTC_SWITCH_TO_24G = 0x1,
+ BTC_SWITCH_TO_5G = 0x2,
+ BTC_SWITCH_TO_24G_NOFORSCAN = 0x3,
+ BTC_SWITCH_MAX
+};
+
+enum btc_notify_type_associate {
+ BTC_ASSOCIATE_FINISH = 0x0,
+ BTC_ASSOCIATE_START = 0x1,
+ BTC_ASSOCIATE_5G_FINISH = 0x2,
+ BTC_ASSOCIATE_5G_START = 0x3,
+ BTC_ASSOCIATE_MAX
+};
+
+enum btc_notify_type_media_status {
+ BTC_MEDIA_DISCONNECT = 0x0,
+ BTC_MEDIA_CONNECT = 0x1,
+ BTC_MEDIA_MAX
+};
+
+enum btc_notify_type_special_packet {
+ BTC_PACKET_UNKNOWN = 0x0,
+ BTC_PACKET_DHCP = 0x1,
+ BTC_PACKET_ARP = 0x2,
+ BTC_PACKET_EAPOL = 0x3,
+ BTC_PACKET_MAX
+};
+
+enum hci_ext_bt_operation {
+ HCI_BT_OP_NONE = 0x0,
+ HCI_BT_OP_INQUIRY_START = 0x1,
+ HCI_BT_OP_INQUIRY_FINISH = 0x2,
+ HCI_BT_OP_PAGING_START = 0x3,
+ HCI_BT_OP_PAGING_SUCCESS = 0x4,
+ HCI_BT_OP_PAGING_UNSUCCESS = 0x5,
+ HCI_BT_OP_PAIRING_START = 0x6,
+ HCI_BT_OP_PAIRING_FINISH = 0x7,
+ HCI_BT_OP_BT_DEV_ENABLE = 0x8,
+ HCI_BT_OP_BT_DEV_DISABLE = 0x9,
+ HCI_BT_OP_MAX
+};
+
+enum btc_notify_type_stack_operation {
+ BTC_STACK_OP_NONE = 0x0,
+ BTC_STACK_OP_INQ_PAGE_PAIR_START = 0x1,
+ BTC_STACK_OP_INQ_PAGE_PAIR_FINISH = 0x2,
+ BTC_STACK_OP_MAX
+};
+
+typedef u8 (*bfp_btc_r1)(void *btc_context, u32 reg_addr);
+
+typedef u16 (*bfp_btc_r2)(void *btc_context, u32 reg_addr);
+
+typedef u32 (*bfp_btc_r4)(void *btc_context, u32 reg_addr);
+
+typedef void (*bfp_btc_w1)(void *btc_context, u32 reg_addr, u32 data);
+
+typedef void (*bfp_btc_w1_bit_mak)(void *btc_context, u32 reg_addr,
+ u32 bit_mask, u8 data1b);
+
+typedef void (*bfp_btc_w2)(void *btc_context, u32 reg_addr, u16 data);
+
+typedef void (*bfp_btc_w4)(void *btc_context, u32 reg_addr, u32 data);
+
+typedef void (*bfp_btc_local_reg_w1)(void *btc_context, u32 reg_addr, u8 data);
+typedef void (*bfp_btc_wr_1byte_bit_mask)(void *btc_context, u32 reg_addr,
+ u8 bit_mask, u8 data);
+
+typedef void (*bfp_btc_set_bb_reg)(void *btc_context, u32 reg_addr,
+ u32 bit_mask, u32 data);
+
+typedef u32 (*bfp_btc_get_bb_reg)(void *btc_context, u32 reg_addr,
+ u32 bit_mask);
+
+typedef void (*bfp_btc_set_rf_reg)(void *btc_context, u8 rf_path, u32 reg_addr,
+ u32 bit_mask, u32 data);
+
+typedef u32 (*bfp_btc_get_rf_reg)(void *btc_context, u8 rf_path,
+ u32 reg_addr, u32 bit_mask);
+
+typedef void (*bfp_btc_fill_h2c)(void *btc_context, u8 element_id,
+ u32 cmd_len, u8 *cmd_buffer);
+
+typedef bool (*bfp_btc_get)(void *btcoexist, u8 get_type, void *out_buf);
+
+typedef bool (*bfp_btc_set)(void *btcoexist, u8 set_type, void *in_buf);
+
+typedef u32 (*bfp_btc_get_bt_coex_supported_feature)(void *btcoexist);
+
+typedef u32 (*bfp_btc_get_bt_coex_supported_version)(void *btcoexist);
+
+typedef u32 (*bfp_btc_get_bt_phydm_version)(void *btcoexist);
+
+typedef void (*bfp_btc_phydm_modify_ra_pcr_threshold)(void *btcoexist,
+ u8 ra_offset_direction,
+ u8 ra_threshold_offset);
+
+typedef u32 (*bfp_btc_phydm_query_phy_counter)(void *btcoexist,
+ const char *info_type);
+
+typedef u8 (*bfp_btc_get_ant_det_val_from_bt)(void *btcoexist);
+
+typedef u8 (*bfp_btc_get_ble_scan_type_from_bt)(void *btcoexist);
+
+typedef u32 (*bfp_btc_get_ble_scan_para_from_bt)(void *btcoexist, u8 scan_type);
+
+typedef bool (*bfp_btc_get_bt_afh_map_from_bt)(void *btcoexist, u8 map_type,
+ u8 *afh_map);
+
+typedef void (*bfp_btc_set_bt_reg)(void *btc_context, u8 reg_type, u32 offset,
+ u32 value);
+typedef u32 (*bfp_btc_get_bt_reg)(void *btc_context, u8 reg_type, u32 offset);
+
+typedef void (*bfp_btc_disp_dbg_msg)(void *btcoexist, u8 disp_type,
+ struct seq_file *m);
+
+struct btc_bt_info {
+ bool bt_disabled;
+ u8 rssi_adjust_for_agc_table_on;
+ u8 rssi_adjust_for_1ant_coex_type;
+ bool pre_bt_ctrl_agg_buf_size;
+ bool bt_busy;
+ u8 pre_agg_buf_size;
+ u8 agg_buf_size;
+ bool limited_dig;
+ bool pre_reject_agg_pkt;
+ bool reject_agg_pkt;
+ bool bt_ctrl_buf_size;
+ bool increase_scan_dev_num;
+ bool miracast_plus_bt;
+ bool bt_ctrl_agg_buf_size;
+ bool bt_tx_rx_mask;
+ u16 bt_hci_ver;
+ u16 bt_real_fw_ver;
+ u8 bt_fw_ver;
+ u32 bt_get_fw_ver;
+
+ bool bt_disable_low_pwr;
+
+ /* the following is for 1Ant solution */
+ bool bt_ctrl_lps;
+ bool bt_pwr_save_mode;
+ bool bt_lps_on;
+ bool force_to_roam;
+ u8 force_exec_pwr_cmd_cnt;
+ u8 lps_val;
+ u8 rpwm_val;
+ u32 ra_mask;
+
+ u32 afh_map_l;
+ u32 afh_map_m;
+ u16 afh_map_h;
+ u32 bt_supported_feature;
+ u32 bt_supported_version;
+ u8 bt_ant_det_val;
+ u8 bt_ble_scan_type;
+ u32 bt_ble_scan_para;
+};
+
+struct btc_stack_info {
+ bool profile_notified;
+ u16 hci_version; /* stack hci version */
+ u8 num_of_link;
+ bool bt_link_exist;
+ bool sco_exist;
+ bool acl_exist;
+ bool a2dp_exist;
+ bool hid_exist;
+ u8 num_of_hid;
+ bool pan_exist;
+ bool unknown_acl_exist;
+ s8 min_bt_rssi;
+};
+
+struct btc_statistics {
+ u32 cnt_bind;
+ u32 cnt_init_hw_config;
+ u32 cnt_init_coex_dm;
+ u32 cnt_ips_notify;
+ u32 cnt_lps_notify;
+ u32 cnt_scan_notify;
+ u32 cnt_connect_notify;
+ u32 cnt_media_status_notify;
+ u32 cnt_special_packet_notify;
+ u32 cnt_bt_info_notify;
+ u32 cnt_periodical;
+ u32 cnt_coex_dm_switch;
+ u32 cnt_stack_operation_notify;
+ u32 cnt_dbg_ctrl;
+ u32 cnt_pre_load_firmware;
+ u32 cnt_power_on;
+};
+
+struct btc_bt_link_info {
+ bool bt_link_exist;
+ bool bt_hi_pri_link_exist;
+ bool sco_exist;
+ bool sco_only;
+ bool a2dp_exist;
+ bool a2dp_only;
+ bool hid_exist;
+ bool hid_only;
+ bool pan_exist;
+ bool pan_only;
+ bool slave_role;
+ bool acl_busy;
+};
+
+enum btc_antenna_pos {
+ BTC_ANTENNA_AT_MAIN_PORT = 0x1,
+ BTC_ANTENNA_AT_AUX_PORT = 0x2,
+};
+
+enum btc_mp_h2c_op_code {
+ BT_OP_GET_BT_VERSION = 0,
+ BT_OP_WRITE_REG_ADDR = 12,
+ BT_OP_WRITE_REG_VALUE = 13,
+ BT_OP_READ_REG = 17,
+ BT_OP_GET_AFH_MAP_L = 30,
+ BT_OP_GET_AFH_MAP_M = 31,
+ BT_OP_GET_AFH_MAP_H = 32,
+ BT_OP_GET_BT_COEX_SUPPORTED_FEATURE = 42,
+ BT_OP_GET_BT_COEX_SUPPORTED_VERSION = 43,
+ BT_OP_GET_BT_ANT_DET_VAL = 44,
+ BT_OP_GET_BT_BLE_SCAN_PARA = 45,
+ BT_OP_GET_BT_BLE_SCAN_TYPE = 46,
+ BT_OP_MAX
+};
+
+enum btc_mp_h2c_req_num {
+ /* 4 bits only */
+ BT_SEQ_DONT_CARE = 0,
+ BT_SEQ_GET_BT_VERSION = 0xE,
+ BT_SEQ_GET_AFH_MAP_L = 0x5,
+ BT_SEQ_GET_AFH_MAP_M = 0x6,
+ BT_SEQ_GET_AFH_MAP_H = 0x9,
+ BT_SEQ_GET_BT_COEX_SUPPORTED_FEATURE = 0x7,
+ BT_SEQ_GET_BT_COEX_SUPPORTED_VERSION = 0x8,
+ BT_SEQ_GET_BT_ANT_DET_VAL = 0x2,
+ BT_SEQ_GET_BT_BLE_SCAN_PARA = 0x3,
+ BT_SEQ_GET_BT_BLE_SCAN_TYPE = 0x4,
+};
+
+struct btc_coexist {
+ /* make sure only one adapter can bind the data context */
+ bool binded;
+ /* default adapter */
+ void *adapter;
+ struct btc_board_info board_info;
+ /* some bt info referenced by non-bt module */
+ struct btc_bt_info bt_info;
+ struct btc_stack_info stack_info;
+ enum btc_chip_interface chip_interface;
+ struct btc_bt_link_info bt_link_info;
+
+ /* boolean variables to replace BT_AUTO_REPORT_ONLY_XXXXY_ZANT
+ * configuration parameters
+ */
+ bool auto_report_1ant;
+ bool auto_report_2ant;
+ bool dbg_mode_1ant;
+ bool dbg_mode_2ant;
+ bool initilized;
+ bool stop_coex_dm;
+ bool manual_control;
+ struct btc_statistics statistics;
+ u8 pwr_mode_val[10];
+
+ struct completion bt_mp_comp;
+
+ /* function pointers - io related */
+ bfp_btc_r1 btc_read_1byte;
+ bfp_btc_w1 btc_write_1byte;
+ bfp_btc_w1_bit_mak btc_write_1byte_bitmask;
+ bfp_btc_r2 btc_read_2byte;
+ bfp_btc_w2 btc_write_2byte;
+ bfp_btc_r4 btc_read_4byte;
+ bfp_btc_w4 btc_write_4byte;
+ bfp_btc_local_reg_w1 btc_write_local_reg_1byte;
+
+ bfp_btc_set_bb_reg btc_set_bb_reg;
+ bfp_btc_get_bb_reg btc_get_bb_reg;
+
+ bfp_btc_set_rf_reg btc_set_rf_reg;
+ bfp_btc_get_rf_reg btc_get_rf_reg;
+
+ bfp_btc_fill_h2c btc_fill_h2c;
+
+ bfp_btc_disp_dbg_msg btc_disp_dbg_msg;
+
+ bfp_btc_get btc_get;
+ bfp_btc_set btc_set;
+
+ bfp_btc_set_bt_reg btc_set_bt_reg;
+ bfp_btc_get_bt_reg btc_get_bt_reg;
+
+ bfp_btc_get_bt_coex_supported_feature btc_get_bt_coex_supported_feature;
+ bfp_btc_get_bt_coex_supported_version btc_get_bt_coex_supported_version;
+ bfp_btc_get_bt_phydm_version btc_get_bt_phydm_version;
+ bfp_btc_phydm_modify_ra_pcr_threshold btc_phydm_modify_ra_pcr_threshold;
+ bfp_btc_phydm_query_phy_counter btc_phydm_query_phy_counter;
+ bfp_btc_get_ant_det_val_from_bt btc_get_ant_det_val_from_bt;
+ bfp_btc_get_ble_scan_type_from_bt btc_get_ble_scan_type_from_bt;
+ bfp_btc_get_ble_scan_para_from_bt btc_get_ble_scan_para_from_bt;
+ bfp_btc_get_bt_afh_map_from_bt btc_get_bt_afh_map_from_bt;
+
+};
+
+bool halbtc_is_wifi_uplink(struct rtl_priv *adapter);
+
+#define rtl_btc_coexist(rtlpriv) \
+ ((struct btc_coexist *)((rtlpriv)->btcoexist.btc_context))
+#define rtl_btc_wifi_only(rtlpriv) \
+ ((struct wifi_only_cfg *)((rtlpriv)->btcoexist.wifi_only_context))
+
+struct wifi_only_cfg;
+
+bool exhalbtc_initlize_variables(struct rtl_priv *rtlpriv);
+bool exhalbtc_initlize_variables_wifi_only(struct rtl_priv *rtlpriv);
+bool exhalbtc_bind_bt_coex_withadapter(void *adapter);
+void exhalbtc_power_on_setting(struct btc_coexist *btcoexist);
+void exhalbtc_pre_load_firmware(struct btc_coexist *btcoexist);
+void exhalbtc_init_hw_config(struct btc_coexist *btcoexist, bool wifi_only);
+void exhalbtc_init_hw_config_wifi_only(struct wifi_only_cfg *wifionly_cfg);
+void exhalbtc_init_coex_dm(struct btc_coexist *btcoexist);
+void exhalbtc_ips_notify(struct btc_coexist *btcoexist, u8 type);
+void exhalbtc_lps_notify(struct btc_coexist *btcoexist, u8 type);
+void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type);
+void exhalbtc_scan_notify_wifi_only(struct wifi_only_cfg *wifionly_cfg,
+ u8 is_5g);
+void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action);
+void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist,
+ enum rt_media_status media_status);
+void exhalbtc_special_packet_notify(struct btc_coexist *btcoexist, u8 pkt_type);
+void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist, u8 *tmp_buf,
+ u8 length);
+void exhalbtc_rf_status_notify(struct btc_coexist *btcoexist, u8 type);
+void exhalbtc_stack_operation_notify(struct btc_coexist *btcoexist, u8 type);
+void exhalbtc_halt_notify(struct btc_coexist *btcoexist);
+void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state);
+void exhalbtc_coex_dm_switch(struct btc_coexist *btcoexist);
+void exhalbtc_periodical(struct btc_coexist *btcoexist);
+void exhalbtc_dbg_control(struct btc_coexist *btcoexist, u8 code, u8 len,
+ u8 *data);
+void exhalbtc_antenna_detection(struct btc_coexist *btcoexist, u32 cent_freq,
+ u32 offset, u32 span, u32 seconds);
+void exhalbtc_stack_update_profile_info(void);
+void exhalbtc_set_hci_version(struct btc_coexist *btcoexist, u16 hci_version);
+void exhalbtc_set_bt_patch_version(struct btc_coexist *btcoexist,
+ u16 bt_hci_version, u16 bt_patch_version);
+void exhalbtc_update_min_bt_rssi(struct btc_coexist *btcoexist, s8 bt_rssi);
+void exhalbtc_set_bt_exist(struct btc_coexist *btcoexist, bool bt_exist);
+void exhalbtc_set_chip_type(struct btc_coexist *btcoexist, u8 chip_type);
+void exhalbtc_set_ant_num(struct rtl_priv *rtlpriv, u8 type, u8 ant_num);
+void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist,
+ struct seq_file *m);
+void exhalbtc_switch_band_notify(struct btc_coexist *btcoexist, u8 type);
+void exhalbtc_switch_band_notify_wifi_only(struct wifi_only_cfg *wifionly_cfg,
+ u8 is_5g);
+void exhalbtc_signal_compensation(struct btc_coexist *btcoexist,
+ u8 *rssi_wifi, u8 *rssi_bt);
+void exhalbtc_lps_leave(struct btc_coexist *btcoexist);
+void exhalbtc_low_wifi_traffic_notify(struct btc_coexist *btcoexist);
+void exhalbtc_set_single_ant_path(struct btc_coexist *btcoexist,
+ u8 single_ant_path);
+
+/* The following are used by wifi_only case */
+enum wifionly_chip_interface {
+ WIFIONLY_INTF_UNKNOWN = 0,
+ WIFIONLY_INTF_PCI = 1,
+ WIFIONLY_INTF_USB = 2,
+ WIFIONLY_INTF_SDIO = 3,
+ WIFIONLY_INTF_MAX
+};
+
+enum wifionly_customer_id {
+ CUSTOMER_NORMAL = 0,
+ CUSTOMER_HP_1 = 1,
+};
+
+struct wifi_only_haldata {
+ u16 customer_id;
+ u8 efuse_pg_antnum;
+ u8 efuse_pg_antpath;
+ u8 rfe_type;
+ u8 ant_div_cfg;
+};
+
+struct wifi_only_cfg {
+ void *adapter;
+ struct wifi_only_haldata haldata_info;
+ enum wifionly_chip_interface chip_interface;
+};
+
+static inline
+void halwifionly_phy_set_bb_reg(struct wifi_only_cfg *wifi_conly_cfg,
+ u32 regaddr, u32 bitmask, u32 data)
+{
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)wifi_conly_cfg->adapter;
+
+ rtl_set_bbreg(rtlpriv->hw, regaddr, bitmask, data);
+}
+
+#endif
diff --git a/drivers/staging/rtlwifi/btcoexist/rtl_btc.c b/drivers/staging/rtlwifi/btcoexist/rtl_btc.c
new file mode 100644
index 0000000..18a4f5b
--- /dev/null
+++ b/drivers/staging/rtlwifi/btcoexist/rtl_btc.c
@@ -0,0 +1,528 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2013 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#include "../wifi.h"
+#include <linux/vmalloc.h>
+#include <linux/module.h>
+
+#include "rtl_btc.h"
+#include "halbt_precomp.h"
+
+static struct rtl_btc_ops rtl_btc_operation = {
+ .btc_init_variables = rtl_btc_init_variables,
+ .btc_init_variables_wifi_only = rtl_btc_init_variables_wifi_only,
+ .btc_deinit_variables = rtl_btc_deinit_variables,
+ .btc_init_hal_vars = rtl_btc_init_hal_vars,
+ .btc_power_on_setting = rtl_btc_power_on_setting,
+ .btc_init_hw_config = rtl_btc_init_hw_config,
+ .btc_init_hw_config_wifi_only = rtl_btc_init_hw_config_wifi_only,
+ .btc_ips_notify = rtl_btc_ips_notify,
+ .btc_lps_notify = rtl_btc_lps_notify,
+ .btc_scan_notify = rtl_btc_scan_notify,
+ .btc_scan_notify_wifi_only = rtl_btc_scan_notify_wifi_only,
+ .btc_connect_notify = rtl_btc_connect_notify,
+ .btc_mediastatus_notify = rtl_btc_mediastatus_notify,
+ .btc_periodical = rtl_btc_periodical,
+ .btc_halt_notify = rtl_btc_halt_notify,
+ .btc_btinfo_notify = rtl_btc_btinfo_notify,
+ .btc_btmpinfo_notify = rtl_btc_btmpinfo_notify,
+ .btc_is_limited_dig = rtl_btc_is_limited_dig,
+ .btc_is_disable_edca_turbo = rtl_btc_is_disable_edca_turbo,
+ .btc_is_bt_disabled = rtl_btc_is_bt_disabled,
+ .btc_special_packet_notify = rtl_btc_special_packet_notify,
+ .btc_switch_band_notify = rtl_btc_switch_band_notify,
+ .btc_switch_band_notify_wifi_only = rtl_btc_switch_band_notify_wifionly,
+ .btc_record_pwr_mode = rtl_btc_record_pwr_mode,
+ .btc_get_lps_val = rtl_btc_get_lps_val,
+ .btc_get_rpwm_val = rtl_btc_get_rpwm_val,
+ .btc_is_bt_ctrl_lps = rtl_btc_is_bt_ctrl_lps,
+ .btc_is_bt_lps_on = rtl_btc_is_bt_lps_on,
+ .btc_get_ampdu_cfg = rtl_btc_get_ampdu_cfg,
+ .btc_display_bt_coex_info = rtl_btc_display_bt_coex_info,
+};
+
+void rtl_btc_display_bt_coex_info(struct rtl_priv *rtlpriv, struct seq_file *m)
+{
+ struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+
+ if (!btcoexist) {
+ seq_puts(m, "btc_coexist context is NULL!\n");
+ return;
+ }
+
+ exhalbtc_display_bt_coex_info(btcoexist, m);
+}
+
+void rtl_btc_record_pwr_mode(struct rtl_priv *rtlpriv, u8 *buf, u8 len)
+{
+ struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+ u8 safe_len;
+
+ if (!btcoexist)
+ return;
+
+ safe_len = sizeof(btcoexist->pwr_mode_val);
+
+ if (safe_len > len)
+ safe_len = len;
+
+ memcpy(btcoexist->pwr_mode_val, buf, safe_len);
+}
+
+u8 rtl_btc_get_lps_val(struct rtl_priv *rtlpriv)
+{
+ struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+
+ if (!btcoexist)
+ return 0;
+
+ return btcoexist->bt_info.lps_val;
+}
+
+u8 rtl_btc_get_rpwm_val(struct rtl_priv *rtlpriv)
+{
+ struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+
+ if (!btcoexist)
+ return 0;
+
+ return btcoexist->bt_info.rpwm_val;
+}
+
+bool rtl_btc_is_bt_ctrl_lps(struct rtl_priv *rtlpriv)
+{
+ struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+
+ if (!btcoexist)
+ return false;
+
+ return btcoexist->bt_info.bt_ctrl_lps;
+}
+
+bool rtl_btc_is_bt_lps_on(struct rtl_priv *rtlpriv)
+{
+ struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+
+ if (!btcoexist)
+ return false;
+
+ return btcoexist->bt_info.bt_lps_on;
+}
+
+void rtl_btc_get_ampdu_cfg(struct rtl_priv *rtlpriv, u8 *reject_agg,
+ u8 *ctrl_agg_size, u8 *agg_size)
+{
+ struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+
+ if (!btcoexist) {
+ *reject_agg = false;
+ *ctrl_agg_size = false;
+ return;
+ }
+
+ if (reject_agg)
+ *reject_agg = btcoexist->bt_info.reject_agg_pkt;
+ if (ctrl_agg_size)
+ *ctrl_agg_size = btcoexist->bt_info.bt_ctrl_agg_buf_size;
+ if (agg_size)
+ *agg_size = btcoexist->bt_info.agg_buf_size;
+}
+
+static void rtl_btc_alloc_variable(struct rtl_priv *rtlpriv, bool wifi_only)
+{
+ if (wifi_only)
+ rtlpriv->btcoexist.wifi_only_context =
+ kzalloc(sizeof(struct wifi_only_cfg), GFP_KERNEL);
+ else
+ rtlpriv->btcoexist.btc_context =
+ kzalloc(sizeof(struct btc_coexist), GFP_KERNEL);
+}
+
+static void rtl_btc_free_variable(struct rtl_priv *rtlpriv)
+{
+ kfree(rtlpriv->btcoexist.btc_context);
+ rtlpriv->btcoexist.btc_context = NULL;
+
+ kfree(rtlpriv->btcoexist.wifi_only_context);
+ rtlpriv->btcoexist.wifi_only_context = NULL;
+}
+
+void rtl_btc_init_variables(struct rtl_priv *rtlpriv)
+{
+ rtl_btc_alloc_variable(rtlpriv, false);
+
+ exhalbtc_initlize_variables(rtlpriv);
+ exhalbtc_bind_bt_coex_withadapter(rtlpriv);
+}
+
+void rtl_btc_init_variables_wifi_only(struct rtl_priv *rtlpriv)
+{
+ rtl_btc_alloc_variable(rtlpriv, true);
+
+ exhalbtc_initlize_variables_wifi_only(rtlpriv);
+}
+
+void rtl_btc_deinit_variables(struct rtl_priv *rtlpriv)
+{
+ rtl_btc_free_variable(rtlpriv);
+}
+
+void rtl_btc_init_hal_vars(struct rtl_priv *rtlpriv)
+{
+ /* move ant_num, bt_type and single_ant_path to
+ * exhalbtc_bind_bt_coex_withadapter()
+ */
+}
+
+void rtl_btc_power_on_setting(struct rtl_priv *rtlpriv)
+{
+ struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+
+ if (!btcoexist)
+ return;
+
+ exhalbtc_power_on_setting(btcoexist);
+}
+
+void rtl_btc_init_hw_config(struct rtl_priv *rtlpriv)
+{
+ struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+
+ u8 bt_exist;
+
+ bt_exist = rtl_get_hwpg_bt_exist(rtlpriv);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ "%s, bt_exist is %d\n", __func__, bt_exist);
+
+ if (!btcoexist)
+ return;
+
+ exhalbtc_init_hw_config(btcoexist, !bt_exist);
+ exhalbtc_init_coex_dm(btcoexist);
+}
+
+void rtl_btc_init_hw_config_wifi_only(struct rtl_priv *rtlpriv)
+{
+ struct wifi_only_cfg *wifionly_cfg = rtl_btc_wifi_only(rtlpriv);
+
+ if (!wifionly_cfg)
+ return;
+
+ exhalbtc_init_hw_config_wifi_only(wifionly_cfg);
+}
+
+void rtl_btc_ips_notify(struct rtl_priv *rtlpriv, u8 type)
+{
+ struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+
+ if (!btcoexist)
+ return;
+
+ exhalbtc_ips_notify(btcoexist, type);
+
+ if (type == ERFON) {
+ /*
+ * In some situation, it doesn't scan after leaving IPS, and
+ * this will cause btcoex in wrong state.
+ */
+ exhalbtc_scan_notify(btcoexist, 1);
+ exhalbtc_scan_notify(btcoexist, 0);
+ }
+}
+
+void rtl_btc_lps_notify(struct rtl_priv *rtlpriv, u8 type)
+{
+ struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+
+ if (!btcoexist)
+ return;
+
+ exhalbtc_lps_notify(btcoexist, type);
+}
+
+void rtl_btc_scan_notify(struct rtl_priv *rtlpriv, u8 scantype)
+{
+ struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+
+ if (!btcoexist)
+ return;
+
+ exhalbtc_scan_notify(btcoexist, scantype);
+}
+
+void rtl_btc_scan_notify_wifi_only(struct rtl_priv *rtlpriv, u8 scantype)
+{
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+ struct wifi_only_cfg *wifionly_cfg = rtl_btc_wifi_only(rtlpriv);
+ u8 is_5g = (rtlhal->current_bandtype == BAND_ON_5G);
+
+ if (!wifionly_cfg)
+ return;
+
+ exhalbtc_scan_notify_wifi_only(wifionly_cfg, is_5g);
+}
+
+void rtl_btc_connect_notify(struct rtl_priv *rtlpriv, u8 action)
+{
+ struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+
+ if (!btcoexist)
+ return;
+
+ exhalbtc_connect_notify(btcoexist, action);
+}
+
+void rtl_btc_mediastatus_notify(struct rtl_priv *rtlpriv,
+ enum rt_media_status mstatus)
+{
+ struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+
+ if (!btcoexist)
+ return;
+
+ exhalbtc_mediastatus_notify(btcoexist, mstatus);
+}
+
+void rtl_btc_periodical(struct rtl_priv *rtlpriv)
+{
+ struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+
+ if (!btcoexist)
+ return;
+
+ /*rtl_bt_dm_monitor();*/
+ exhalbtc_periodical(btcoexist);
+}
+
+void rtl_btc_halt_notify(struct rtl_priv *rtlpriv)
+{
+ struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+
+ if (!btcoexist)
+ return;
+
+ exhalbtc_halt_notify(btcoexist);
+}
+
+void rtl_btc_btinfo_notify(struct rtl_priv *rtlpriv, u8 *tmp_buf, u8 length)
+{
+ struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+
+ if (!btcoexist)
+ return;
+
+ exhalbtc_bt_info_notify(btcoexist, tmp_buf, length);
+}
+
+void rtl_btc_btmpinfo_notify(struct rtl_priv *rtlpriv, u8 *tmp_buf, u8 length)
+{
+ struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+ u8 extid, seq, len;
+ u16 bt_real_fw_ver;
+ u8 bt_fw_ver;
+ u8 *data;
+
+ if (!btcoexist)
+ return;
+
+ if ((length < 4) || (!tmp_buf))
+ return;
+
+ extid = tmp_buf[0];
+ /* not response from BT FW then exit*/
+ if (extid != 1) /* C2H_TRIG_BY_BT_FW = 1 */
+ return;
+
+ len = tmp_buf[1] >> 4;
+ seq = tmp_buf[2] >> 4;
+ data = &tmp_buf[3];
+
+ /* BT Firmware version response */
+ switch (seq) {
+ case BT_SEQ_GET_BT_VERSION:
+ bt_real_fw_ver = tmp_buf[3] | (tmp_buf[4] << 8);
+ bt_fw_ver = tmp_buf[5];
+
+ btcoexist->bt_info.bt_real_fw_ver = bt_real_fw_ver;
+ btcoexist->bt_info.bt_fw_ver = bt_fw_ver;
+ break;
+ case BT_SEQ_GET_AFH_MAP_L:
+ btcoexist->bt_info.afh_map_l = le32_to_cpu(*(__le32 *)data);
+ break;
+ case BT_SEQ_GET_AFH_MAP_M:
+ btcoexist->bt_info.afh_map_m = le32_to_cpu(*(__le32 *)data);
+ break;
+ case BT_SEQ_GET_AFH_MAP_H:
+ btcoexist->bt_info.afh_map_h = le16_to_cpu(*(__le16 *)data);
+ break;
+ case BT_SEQ_GET_BT_COEX_SUPPORTED_FEATURE:
+ btcoexist->bt_info.bt_supported_feature = tmp_buf[3] |
+ (tmp_buf[4] << 8);
+ break;
+ case BT_SEQ_GET_BT_COEX_SUPPORTED_VERSION:
+ btcoexist->bt_info.bt_supported_version = tmp_buf[3] |
+ (tmp_buf[4] << 8);
+ break;
+ case BT_SEQ_GET_BT_ANT_DET_VAL:
+ btcoexist->bt_info.bt_ant_det_val = tmp_buf[3];
+ break;
+ case BT_SEQ_GET_BT_BLE_SCAN_PARA:
+ btcoexist->bt_info.bt_ble_scan_para = tmp_buf[3] |
+ (tmp_buf[4] << 8) |
+ (tmp_buf[5] << 16) |
+ (tmp_buf[6] << 24);
+ break;
+ case BT_SEQ_GET_BT_BLE_SCAN_TYPE:
+ btcoexist->bt_info.bt_ble_scan_type = tmp_buf[3];
+ break;
+ }
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "btmpinfo complete req_num=%d\n", seq);
+
+ complete(&btcoexist->bt_mp_comp);
+}
+
+bool rtl_btc_is_limited_dig(struct rtl_priv *rtlpriv)
+{
+ struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+
+ if (!btcoexist)
+ return false;
+
+ return btcoexist->bt_info.limited_dig;
+}
+
+bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv)
+{
+ bool bt_change_edca = false;
+ u32 cur_edca_val;
+ u32 edca_bt_hs_uplink = 0x5ea42b, edca_bt_hs_downlink = 0x5ea42b;
+ u32 edca_hs;
+ u32 edca_addr = 0x504;
+
+ cur_edca_val = rtl_read_dword(rtlpriv, edca_addr);
+ if (halbtc_is_wifi_uplink(rtlpriv)) {
+ if (cur_edca_val != edca_bt_hs_uplink) {
+ edca_hs = edca_bt_hs_uplink;
+ bt_change_edca = true;
+ }
+ } else {
+ if (cur_edca_val != edca_bt_hs_downlink) {
+ edca_hs = edca_bt_hs_downlink;
+ bt_change_edca = true;
+ }
+ }
+
+ if (bt_change_edca)
+ rtl_write_dword(rtlpriv, edca_addr, edca_hs);
+
+ return true;
+}
+
+bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv)
+{
+ struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+
+ if (!btcoexist)
+ return true;
+
+ /* It seems 'bt_disabled' is never be initialized or set. */
+ if (btcoexist->bt_info.bt_disabled)
+ return true;
+ else
+ return false;
+}
+
+void rtl_btc_special_packet_notify(struct rtl_priv *rtlpriv, u8 pkt_type)
+{
+ struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+
+ if (!btcoexist)
+ return;
+
+ return exhalbtc_special_packet_notify(btcoexist, pkt_type);
+}
+
+void rtl_btc_switch_band_notify(struct rtl_priv *rtlpriv, u8 band_type,
+ bool scanning)
+{
+ struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+ u8 type = BTC_NOT_SWITCH;
+
+ if (!btcoexist)
+ return;
+
+ switch (band_type) {
+ case BAND_ON_2_4G:
+ if (scanning)
+ type = BTC_SWITCH_TO_24G;
+ else
+ type = BTC_SWITCH_TO_24G_NOFORSCAN;
+ break;
+
+ case BAND_ON_5G:
+ type = BTC_SWITCH_TO_5G;
+ break;
+ }
+
+ if (type != BTC_NOT_SWITCH)
+ exhalbtc_switch_band_notify(btcoexist, type);
+}
+
+void rtl_btc_switch_band_notify_wifionly(struct rtl_priv *rtlpriv, u8 band_type,
+ bool scanning)
+{
+ struct wifi_only_cfg *wifionly_cfg = rtl_btc_wifi_only(rtlpriv);
+ u8 is_5g = (band_type == BAND_ON_5G);
+
+ if (!wifionly_cfg)
+ return;
+
+ exhalbtc_switch_band_notify_wifi_only(wifionly_cfg, is_5g);
+}
+
+struct rtl_btc_ops *rtl_btc_get_ops_pointer(void)
+{
+ return &rtl_btc_operation;
+}
+
+enum rt_media_status mgnt_link_status_query(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ enum rt_media_status m_status = RT_MEDIA_DISCONNECT;
+
+ u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0;
+
+ if (bibss || rtlpriv->mac80211.link_state >= MAC80211_LINKED)
+ m_status = RT_MEDIA_CONNECT;
+
+ return m_status;
+}
+
+u8 rtl_get_hwpg_bt_exist(struct rtl_priv *rtlpriv)
+{
+ return rtlpriv->btcoexist.btc_info.btcoexist;
+}
diff --git a/drivers/staging/rtlwifi/btcoexist/rtl_btc.h b/drivers/staging/rtlwifi/btcoexist/rtl_btc.h
new file mode 100644
index 0000000..8c99605
--- /dev/null
+++ b/drivers/staging/rtlwifi/btcoexist/rtl_btc.h
@@ -0,0 +1,75 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL_BTC_H__
+#define __RTL_BTC_H__
+
+#include "halbt_precomp.h"
+
+void rtl_btc_init_variables(struct rtl_priv *rtlpriv);
+void rtl_btc_init_variables_wifi_only(struct rtl_priv *rtlpriv);
+void rtl_btc_deinit_variables(struct rtl_priv *rtlpriv);
+void rtl_btc_init_hal_vars(struct rtl_priv *rtlpriv);
+void rtl_btc_power_on_setting(struct rtl_priv *rtlpriv);
+void rtl_btc_init_hw_config(struct rtl_priv *rtlpriv);
+void rtl_btc_init_hw_config_wifi_only(struct rtl_priv *rtlpriv);
+void rtl_btc_ips_notify(struct rtl_priv *rtlpriv, u8 type);
+void rtl_btc_lps_notify(struct rtl_priv *rtlpriv, u8 type);
+void rtl_btc_scan_notify(struct rtl_priv *rtlpriv, u8 scantype);
+void rtl_btc_scan_notify_wifi_only(struct rtl_priv *rtlpriv, u8 scantype);
+void rtl_btc_connect_notify(struct rtl_priv *rtlpriv, u8 action);
+void rtl_btc_mediastatus_notify(struct rtl_priv *rtlpriv,
+ enum rt_media_status mstatus);
+void rtl_btc_periodical(struct rtl_priv *rtlpriv);
+void rtl_btc_halt_notify(struct rtl_priv *rtlpriv);
+void rtl_btc_btinfo_notify(struct rtl_priv *rtlpriv, u8 *tmpbuf, u8 length);
+void rtl_btc_btmpinfo_notify(struct rtl_priv *rtlpriv, u8 *tmp_buf, u8 length);
+bool rtl_btc_is_limited_dig(struct rtl_priv *rtlpriv);
+bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv);
+bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv);
+void rtl_btc_special_packet_notify(struct rtl_priv *rtlpriv, u8 pkt_type);
+void rtl_btc_switch_band_notify(struct rtl_priv *rtlpriv, u8 band_type,
+ bool scanning);
+void rtl_btc_switch_band_notify_wifionly(struct rtl_priv *rtlpriv, u8 band_type,
+ bool scanning);
+void rtl_btc_display_bt_coex_info(struct rtl_priv *rtlpriv, struct seq_file *m);
+void rtl_btc_record_pwr_mode(struct rtl_priv *rtlpriv, u8 *buf, u8 len);
+u8 rtl_btc_get_lps_val(struct rtl_priv *rtlpriv);
+u8 rtl_btc_get_rpwm_val(struct rtl_priv *rtlpriv);
+bool rtl_btc_is_bt_ctrl_lps(struct rtl_priv *rtlpriv);
+bool rtl_btc_is_bt_lps_on(struct rtl_priv *rtlpriv);
+void rtl_btc_get_ampdu_cfg(struct rtl_priv *rtlpriv, u8 *reject_agg,
+ u8 *ctrl_agg_size, u8 *agg_size);
+
+struct rtl_btc_ops *rtl_btc_get_ops_pointer(void);
+
+u8 rtl_get_hwpg_bt_exist(struct rtl_priv *rtlpriv);
+u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv);
+u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv);
+u8 rtl_get_hwpg_single_ant_path(struct rtl_priv *rtlpriv);
+u8 rtl_get_hwpg_package_type(struct rtl_priv *rtlpriv);
+
+enum rt_media_status mgnt_link_status_query(struct ieee80211_hw *hw);
+
+#endif
diff --git a/drivers/staging/rtlwifi/cam.c b/drivers/staging/rtlwifi/cam.c
new file mode 100644
index 0000000..9c8c907
--- /dev/null
+++ b/drivers/staging/rtlwifi/cam.c
@@ -0,0 +1,326 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2012 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#include "wifi.h"
+#include "cam.h"
+#include <linux/export.h>
+
+void rtl_cam_reset_sec_info(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtlpriv->sec.use_defaultkey = false;
+ rtlpriv->sec.pairwise_enc_algorithm = NO_ENCRYPTION;
+ rtlpriv->sec.group_enc_algorithm = NO_ENCRYPTION;
+ memset(rtlpriv->sec.key_buf, 0, KEY_BUF_SIZE * MAX_KEY_LEN);
+ memset(rtlpriv->sec.key_len, 0, KEY_BUF_SIZE);
+ rtlpriv->sec.pairwise_key = NULL;
+}
+
+static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,
+ u8 *mac_addr, u8 *key_cont_128, u16 us_config)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ u32 target_command;
+ u32 target_content = 0;
+ int entry_i;
+
+ RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_DMESG, "Key content :",
+ key_cont_128, 16);
+
+ /* 0-1 config + mac, 2-5 fill 128key,6-7 are reserved */
+ for (entry_i = CAM_CONTENT_COUNT - 1; entry_i >= 0; entry_i--) {
+ target_command = entry_i + CAM_CONTENT_COUNT * entry_no;
+ target_command = target_command | BIT(31) | BIT(16);
+
+ if (entry_i == 0) {
+ target_content = (u32)(*(mac_addr + 0)) << 16 |
+ (u32)(*(mac_addr + 1)) << 24 |
+ (u32)us_config;
+
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI],
+ target_content);
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
+ target_command);
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+ "WRITE %x: %x\n",
+ rtlpriv->cfg->maps[WCAMI], target_content);
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+ "The Key ID is %d\n", entry_no);
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+ "WRITE %x: %x\n",
+ rtlpriv->cfg->maps[RWCAM], target_command);
+
+ } else if (entry_i == 1) {
+ target_content = (u32)(*(mac_addr + 5)) << 24 |
+ (u32)(*(mac_addr + 4)) << 16 |
+ (u32)(*(mac_addr + 3)) << 8 |
+ (u32)(*(mac_addr + 2));
+
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI],
+ target_content);
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
+ target_command);
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+ "WRITE A4: %x\n", target_content);
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+ "WRITE A0: %x\n", target_command);
+ } else {
+ target_content =
+ (u32)(*(key_cont_128 + (entry_i * 4 - 8) + 3)) <<
+ 24 | (u32)(*(key_cont_128 + (entry_i * 4 - 8) + 2))
+ << 16 |
+ (u32)(*(key_cont_128 + (entry_i * 4 - 8) + 1)) << 8
+ | (u32)(*(key_cont_128 + (entry_i * 4 - 8) + 0));
+
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI],
+ target_content);
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
+ target_command);
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+ "WRITE A4: %x\n", target_content);
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+ "WRITE A0: %x\n", target_command);
+ }
+ }
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+ "after set key, usconfig:%x\n", us_config);
+}
+
+u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
+ u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg,
+ u32 ul_default_key, u8 *key_content)
+{
+ u32 us_config;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ "EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, ulUseDK=%x MacAddr %pM\n",
+ ul_entry_idx, ul_key_id, ul_enc_alg,
+ ul_default_key, mac_addr);
+
+ if (ul_key_id == TOTAL_CAM_ENTRY) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ "ulKeyId exceed!\n");
+ return 0;
+ }
+
+ if (ul_default_key == 1)
+ us_config = CFG_VALID | ((u16)(ul_enc_alg) << 2);
+ else
+ us_config = CFG_VALID | ((ul_enc_alg) << 2) | ul_key_id;
+
+ rtl_cam_program_entry(hw, ul_entry_idx, mac_addr,
+ (u8 *)key_content, us_config);
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "end\n");
+
+ return 1;
+}
+
+int rtl_cam_delete_one_entry(struct ieee80211_hw *hw,
+ u8 *mac_addr, u32 ul_key_id)
+{
+ u32 ul_command;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "key_idx:%d\n", ul_key_id);
+
+ ul_command = ul_key_id * CAM_CONTENT_COUNT;
+ ul_command = ul_command | BIT(31) | BIT(16);
+
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], 0);
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ "%s(): WRITE A4: %x\n", __func__, 0);
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ "%s(): WRITE A0: %x\n", __func__, ul_command);
+
+ return 0;
+}
+
+void rtl_cam_reset_all_entry(struct ieee80211_hw *hw)
+{
+ u32 ul_command;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ ul_command = BIT(31) | BIT(30);
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
+}
+
+void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ u32 ul_command;
+ u32 ul_content;
+ u32 ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES];
+
+ switch (rtlpriv->sec.pairwise_enc_algorithm) {
+ case WEP40_ENCRYPTION:
+ ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_WEP40];
+ break;
+ case WEP104_ENCRYPTION:
+ ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_WEP104];
+ break;
+ case TKIP_ENCRYPTION:
+ ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_TKIP];
+ break;
+ case AESCCMP_ENCRYPTION:
+ ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES];
+ break;
+ default:
+ ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES];
+ }
+
+ ul_content = (uc_index & 3) | ((u16)(ul_enc_algo) << 2);
+
+ ul_content |= BIT(15);
+ ul_command = CAM_CONTENT_COUNT * uc_index;
+ ul_command = ul_command | BIT(31) | BIT(16);
+
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], ul_content);
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ "%s(): WRITE A4: %x\n", __func__, ul_content);
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ "%s(): WRITE A0: %x\n", __func__, ul_command);
+}
+
+void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ u32 ul_command;
+ u32 ul_content;
+ u32 ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES];
+ u8 entry_i;
+
+ switch (rtlpriv->sec.pairwise_enc_algorithm) {
+ case WEP40_ENCRYPTION:
+ ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_WEP40];
+ break;
+ case WEP104_ENCRYPTION:
+ ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_WEP104];
+ break;
+ case TKIP_ENCRYPTION:
+ ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_TKIP];
+ break;
+ case AESCCMP_ENCRYPTION:
+ ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES];
+ break;
+ default:
+ ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES];
+ }
+
+ for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
+ if (entry_i == 0) {
+ ul_content =
+ (uc_index & 0x03) | ((u16)(ul_encalgo) << 2);
+ ul_content |= BIT(15);
+ } else {
+ ul_content = 0;
+ }
+
+ ul_command = CAM_CONTENT_COUNT * uc_index + entry_i;
+ ul_command = ul_command | BIT(31) | BIT(16);
+
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], ul_content);
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+ "%s(): WRITE A4: %x\n", __func__, ul_content);
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+ "%s(): WRITE A0: %x\n", __func__, ul_command);
+ }
+}
+
+u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 bitmap = (rtlpriv->sec.hwsec_cam_bitmap) >> 4;
+ u8 entry_idx = 0;
+ u8 i, *addr;
+
+ if (!sta_addr) {
+ pr_err("sta_addr is NULL.\n");
+ return TOTAL_CAM_ENTRY;
+ }
+ /* Does STA already exist? */
+ for (i = 4; i < TOTAL_CAM_ENTRY; i++) {
+ addr = rtlpriv->sec.hwsec_cam_sta_addr[i];
+ if (ether_addr_equal_unaligned(addr, sta_addr))
+ return i;
+ }
+ /* Get a free CAM entry. */
+ for (entry_idx = 4; entry_idx < TOTAL_CAM_ENTRY; entry_idx++) {
+ if ((bitmap & BIT(0)) == 0) {
+ pr_err("-----hwsec_cam_bitmap: 0x%x entry_idx=%d\n",
+ rtlpriv->sec.hwsec_cam_bitmap, entry_idx);
+ rtlpriv->sec.hwsec_cam_bitmap |= BIT(0) << entry_idx;
+ memcpy(rtlpriv->sec.hwsec_cam_sta_addr[entry_idx],
+ sta_addr, ETH_ALEN);
+ return entry_idx;
+ }
+ bitmap = bitmap >> 1;
+ }
+ return TOTAL_CAM_ENTRY;
+}
+
+void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 bitmap;
+ u8 i, *addr;
+
+ if (!sta_addr) {
+ pr_err("sta_addr is NULL.\n");
+ return;
+ }
+
+ if (is_zero_ether_addr(sta_addr)) {
+ pr_err("sta_addr is %pM\n", sta_addr);
+ return;
+ }
+ /* Does STA already exist? */
+ for (i = 4; i < TOTAL_CAM_ENTRY; i++) {
+ addr = rtlpriv->sec.hwsec_cam_sta_addr[i];
+ bitmap = (rtlpriv->sec.hwsec_cam_bitmap) >> i;
+ if (((bitmap & BIT(0)) == BIT(0)) &&
+ (ether_addr_equal_unaligned(addr, sta_addr))) {
+ /* Remove from HW Security CAM */
+ eth_zero_addr(rtlpriv->sec.hwsec_cam_sta_addr[i]);
+ rtlpriv->sec.hwsec_cam_bitmap &= ~(BIT(0) << i);
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ "&&&&&&&&&del entry %d\n", i);
+ }
+ }
+}
diff --git a/drivers/staging/rtlwifi/cam.h b/drivers/staging/rtlwifi/cam.h
new file mode 100644
index 0000000..b25729e
--- /dev/null
+++ b/drivers/staging/rtlwifi/cam.h
@@ -0,0 +1,50 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2012 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL_CAM_H_
+#define __RTL_CAM_H_
+
+#define CAM_CONTENT_COUNT 8
+
+#define CFG_VALID BIT(15)
+
+#define PAIRWISE_KEYIDX 0
+#define CAM_PAIRWISE_KEY_POSITION 4
+
+#define CAM_CONFIG_NO_USEDK 0
+
+void rtl_cam_reset_all_entry(struct ieee80211_hw *hw);
+u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
+ u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg,
+ u32 ul_default_key, u8 *key_content);
+int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
+ u32 ul_key_id);
+void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index);
+void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index);
+void rtl_cam_reset_sec_info(struct ieee80211_hw *hw);
+u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr);
+void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr);
+
+#endif
diff --git a/drivers/staging/rtlwifi/core.c b/drivers/staging/rtlwifi/core.c
new file mode 100644
index 0000000..d33847d
--- /dev/null
+++ b/drivers/staging/rtlwifi/core.c
@@ -0,0 +1,2046 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2012 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "wifi.h"
+#include "core.h"
+#include "cam.h"
+#include "base.h"
+#include "ps.h"
+#include "pwrseqcmd.h"
+
+#include "btcoexist/rtl_btc.h"
+#include <linux/firmware.h>
+#include <linux/export.h>
+#include <net/cfg80211.h>
+
+u8 channel5g[CHANNEL_MAX_NUMBER_5G] = {
+ 36, 38, 40, 42, 44, 46, 48, /* Band 1 */
+ 52, 54, 56, 58, 60, 62, 64, /* Band 2 */
+ 100, 102, 104, 106, 108, 110, 112, /* Band 3 */
+ 116, 118, 120, 122, 124, 126, 128, /* Band 3 */
+ 132, 134, 136, 138, 140, 142, 144, /* Band 3 */
+ 149, 151, 153, 155, 157, 159, 161, /* Band 4 */
+ 165, 167, 169, 171, 173, 175, 177 /* Band 4 */
+};
+
+u8 channel5g_80m[CHANNEL_MAX_NUMBER_5G_80M] = {
+ 42, 58, 106, 122, 138, 155, 171
+};
+
+void rtl_addr_delay(u32 addr)
+{
+ if (addr == 0xfe)
+ mdelay(50);
+ else if (addr == 0xfd)
+ msleep(5);
+ else if (addr == 0xfc)
+ msleep(1);
+ else if (addr == 0xfb)
+ usleep_range(50, 100);
+ else if (addr == 0xfa)
+ usleep_range(5, 10);
+ else if (addr == 0xf9)
+ usleep_range(1, 2);
+}
+
+void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr,
+ u32 mask, u32 data)
+{
+ if (addr >= 0xf9 && addr <= 0xfe) {
+ rtl_addr_delay(addr);
+ } else {
+ rtl_set_rfreg(hw, rfpath, addr, mask, data);
+ udelay(1);
+ }
+}
+
+void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data)
+{
+ if (addr >= 0xf9 && addr <= 0xfe) {
+ rtl_addr_delay(addr);
+ } else {
+ rtl_set_bbreg(hw, addr, MASKDWORD, data);
+ udelay(1);
+ }
+}
+
+static void rtl_fw_do_work(const struct firmware *firmware, void *context,
+ bool is_wow)
+{
+ struct ieee80211_hw *hw = context;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ int err;
+
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
+ "Firmware callback routine entered!\n");
+ complete(&rtlpriv->firmware_loading_complete);
+ if (!firmware) {
+ if (rtlpriv->cfg->alt_fw_name) {
+ err = request_firmware(&firmware,
+ rtlpriv->cfg->alt_fw_name,
+ rtlpriv->io.dev);
+ pr_info("Loading alternative firmware %s\n",
+ rtlpriv->cfg->alt_fw_name);
+ if (!err)
+ goto found_alt;
+ }
+ pr_err("Selected firmware is not available\n");
+ rtlpriv->max_fw_size = 0;
+ return;
+ }
+found_alt:
+ if (firmware->size > rtlpriv->max_fw_size) {
+ pr_err("Firmware is too big!\n");
+ release_firmware(firmware);
+ return;
+ }
+ if (!is_wow) {
+ memcpy(rtlpriv->rtlhal.pfirmware, firmware->data,
+ firmware->size);
+ rtlpriv->rtlhal.fwsize = firmware->size;
+ } else {
+ memcpy(rtlpriv->rtlhal.wowlan_firmware, firmware->data,
+ firmware->size);
+ rtlpriv->rtlhal.wowlan_fwsize = firmware->size;
+ }
+ rtlpriv->rtlhal.fwsize = firmware->size;
+ release_firmware(firmware);
+}
+
+void rtl_fw_cb(const struct firmware *firmware, void *context)
+{
+ rtl_fw_do_work(firmware, context, false);
+}
+
+void rtl_wowlan_fw_cb(const struct firmware *firmware, void *context)
+{
+ rtl_fw_do_work(firmware, context, true);
+}
+
+/*mutex for start & stop is must here. */
+static int rtl_op_start(struct ieee80211_hw *hw)
+{
+ int err = 0;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ if (!is_hal_stop(rtlhal))
+ return 0;
+ if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
+ return 0;
+ mutex_lock(&rtlpriv->locks.conf_mutex);
+ err = rtlpriv->intf_ops->adapter_start(hw);
+ if (!err)
+ rtl_watch_dog_timer_callback((unsigned long)hw);
+ mutex_unlock(&rtlpriv->locks.conf_mutex);
+ return err;
+}
+
+static void rtl_op_stop(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ bool support_remote_wakeup = false;
+
+ if (is_hal_stop(rtlhal))
+ return;
+
+ rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN,
+ (u8 *)(&support_remote_wakeup));
+ /* here is must, because adhoc do stop and start,
+ * but stop with RFOFF may cause something wrong,
+ * like adhoc TP
+ */
+ if (unlikely(ppsc->rfpwr_state == ERFOFF))
+ rtl_ips_nic_on(hw);
+
+ mutex_lock(&rtlpriv->locks.conf_mutex);
+ /* if wowlan supported, DON'T clear connected info */
+ if (!(support_remote_wakeup &&
+ rtlhal->enter_pnp_sleep)) {
+ mac->link_state = MAC80211_NOLINK;
+ eth_zero_addr(mac->bssid);
+ mac->vendor = PEER_UNKNOWN;
+
+ /* reset sec info */
+ rtl_cam_reset_sec_info(hw);
+
+ rtl_deinit_deferred_work(hw);
+ }
+ rtlpriv->intf_ops->adapter_stop(hw);
+
+ mutex_unlock(&rtlpriv->locks.conf_mutex);
+}
+
+static void rtl_op_tx(struct ieee80211_hw *hw,
+ struct ieee80211_tx_control *control,
+ struct sk_buff *skb)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_tcb_desc tcb_desc;
+
+ memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
+
+ if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON))
+ goto err_free;
+
+ if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
+ goto err_free;
+
+ if (!rtlpriv->intf_ops->waitq_insert(hw, control->sta, skb))
+ rtlpriv->intf_ops->adapter_tx(hw, control->sta, skb, &tcb_desc);
+ return;
+
+err_free:
+ dev_kfree_skb_any(skb);
+}
+
+static int rtl_op_add_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ int err = 0;
+ u8 retry_limit = 0x30;
+
+ if (mac->vif) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ "vif has been set!! mac->vif = 0x%p\n", mac->vif);
+ return -EOPNOTSUPP;
+ }
+
+ vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
+
+ rtl_ips_nic_on(hw);
+
+ mutex_lock(&rtlpriv->locks.conf_mutex);
+ switch (ieee80211_vif_type_p2p(vif)) {
+ case NL80211_IFTYPE_P2P_CLIENT:
+ mac->p2p = P2P_ROLE_CLIENT;
+ /*fall through*/
+ case NL80211_IFTYPE_STATION:
+ if (mac->beacon_enabled == 1) {
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ "NL80211_IFTYPE_STATION\n");
+ mac->beacon_enabled = 0;
+ rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
+ rtlpriv->cfg->maps[RTL_IBSS_INT_MASKS]);
+ }
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ "NL80211_IFTYPE_ADHOC\n");
+
+ mac->link_state = MAC80211_LINKED;
+ rtlpriv->cfg->ops->set_bcn_reg(hw);
+ if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
+ mac->basic_rates = 0xfff;
+ else
+ mac->basic_rates = 0xff0;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
+ (u8 *)(&mac->basic_rates));
+
+ retry_limit = 0x07;
+ break;
+ case NL80211_IFTYPE_P2P_GO:
+ mac->p2p = P2P_ROLE_GO;
+ /*fall through*/
+ case NL80211_IFTYPE_AP:
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ "NL80211_IFTYPE_AP\n");
+
+ mac->link_state = MAC80211_LINKED;
+ rtlpriv->cfg->ops->set_bcn_reg(hw);
+ if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
+ mac->basic_rates = 0xfff;
+ else
+ mac->basic_rates = 0xff0;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
+ (u8 *)(&mac->basic_rates));
+
+ retry_limit = 0x07;
+ break;
+ case NL80211_IFTYPE_MESH_POINT:
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ "NL80211_IFTYPE_MESH_POINT\n");
+
+ mac->link_state = MAC80211_LINKED;
+ rtlpriv->cfg->ops->set_bcn_reg(hw);
+ if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
+ mac->basic_rates = 0xfff;
+ else
+ mac->basic_rates = 0xff0;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
+ (u8 *)(&mac->basic_rates));
+
+ retry_limit = 0x07;
+ break;
+ default:
+ pr_err("operation mode %d is not supported!\n",
+ vif->type);
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if (mac->p2p) {
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ "p2p role %x\n", vif->type);
+ mac->basic_rates = 0xff0;/*disable cck rate for p2p*/
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
+ (u8 *)(&mac->basic_rates));
+ }
+ mac->vif = vif;
+ mac->opmode = vif->type;
+ rtlpriv->cfg->ops->set_network_type(hw, vif->type);
+ memcpy(mac->mac_addr, vif->addr, ETH_ALEN);
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
+
+ mac->retry_long = retry_limit;
+ mac->retry_short = retry_limit;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,
+ (u8 *)(&retry_limit));
+out:
+ mutex_unlock(&rtlpriv->locks.conf_mutex);
+ return err;
+}
+
+static void rtl_op_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+ mutex_lock(&rtlpriv->locks.conf_mutex);
+
+ /* Free beacon resources */
+ if ((vif->type == NL80211_IFTYPE_AP) ||
+ (vif->type == NL80211_IFTYPE_ADHOC) ||
+ (vif->type == NL80211_IFTYPE_MESH_POINT)) {
+ if (mac->beacon_enabled == 1) {
+ mac->beacon_enabled = 0;
+ rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
+ rtlpriv->cfg->maps[RTL_IBSS_INT_MASKS]);
+ }
+ }
+
+ /*
+ *Note: We assume NL80211_IFTYPE_UNSPECIFIED as
+ *NO LINK for our hardware.
+ */
+ mac->p2p = 0;
+ mac->vif = NULL;
+ mac->link_state = MAC80211_NOLINK;
+ eth_zero_addr(mac->bssid);
+ mac->vendor = PEER_UNKNOWN;
+ mac->opmode = NL80211_IFTYPE_UNSPECIFIED;
+ rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);
+
+ mutex_unlock(&rtlpriv->locks.conf_mutex);
+}
+
+static int rtl_op_change_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum nl80211_iftype new_type, bool p2p)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ int ret;
+
+ rtl_op_remove_interface(hw, vif);
+
+ vif->type = new_type;
+ vif->p2p = p2p;
+ ret = rtl_op_add_interface(hw, vif);
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ "p2p %x\n", p2p);
+ return ret;
+}
+
+#ifdef CONFIG_PM
+static u16 crc16_ccitt(u8 data, u16 crc)
+{
+ u8 shift_in, data_bit, crc_bit11, crc_bit4, crc_bit15;
+ u8 i;
+ u16 result;
+
+ for (i = 0; i < 8; i++) {
+ crc_bit15 = ((crc & BIT(15)) ? 1 : 0);
+ data_bit = (data & (BIT(0) << i) ? 1 : 0);
+ shift_in = crc_bit15 ^ data_bit;
+
+ result = crc << 1;
+ if (shift_in == 0)
+ result &= (~BIT(0));
+ else
+ result |= BIT(0);
+
+ crc_bit11 = ((crc & BIT(11)) ? 1 : 0) ^ shift_in;
+ if (crc_bit11 == 0)
+ result &= (~BIT(12));
+ else
+ result |= BIT(12);
+
+ crc_bit4 = ((crc & BIT(4)) ? 1 : 0) ^ shift_in;
+ if (crc_bit4 == 0)
+ result &= (~BIT(5));
+ else
+ result |= BIT(5);
+
+ crc = result;
+ }
+
+ return crc;
+}
+
+static u16 _calculate_wol_pattern_crc(u8 *pattern, u16 len)
+{
+ u16 crc = 0xffff;
+ u32 i;
+
+ for (i = 0; i < len; i++)
+ crc = crc16_ccitt(pattern[i], crc);
+
+ crc = ~crc;
+
+ return crc;
+}
+
+static void _rtl_add_wowlan_patterns(struct ieee80211_hw *hw,
+ struct cfg80211_wowlan *wow)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = &rtlpriv->mac80211;
+ struct cfg80211_pkt_pattern *patterns = wow->patterns;
+ struct rtl_wow_pattern rtl_pattern;
+ const u8 *pattern_os, *mask_os;
+ u8 mask[MAX_WOL_BIT_MASK_SIZE] = {0};
+ u8 content[MAX_WOL_PATTERN_SIZE] = {0};
+ u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ u8 multicast_addr1[2] = {0x33, 0x33};
+ u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
+ u8 i, mask_len;
+ u16 j, len;
+
+ for (i = 0; i < wow->n_patterns; i++) {
+ memset(&rtl_pattern, 0, sizeof(struct rtl_wow_pattern));
+ memset(mask, 0, MAX_WOL_BIT_MASK_SIZE);
+ if (patterns[i].pattern_len > MAX_WOL_PATTERN_SIZE) {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_WARNING,
+ "Pattern[%d] is too long\n", i);
+ continue;
+ }
+ pattern_os = patterns[i].pattern;
+ mask_len = DIV_ROUND_UP(patterns[i].pattern_len, 8);
+ mask_os = patterns[i].mask;
+ RT_PRINT_DATA(rtlpriv, COMP_POWER, DBG_TRACE,
+ "pattern content\n", pattern_os,
+ patterns[i].pattern_len);
+ RT_PRINT_DATA(rtlpriv, COMP_POWER, DBG_TRACE,
+ "mask content\n", mask_os, mask_len);
+ /* 1. unicast? multicast? or broadcast? */
+ if (memcmp(pattern_os, broadcast_addr, 6) == 0)
+ rtl_pattern.type = BROADCAST_PATTERN;
+ else if (memcmp(pattern_os, multicast_addr1, 2) == 0 ||
+ memcmp(pattern_os, multicast_addr2, 3) == 0)
+ rtl_pattern.type = MULTICAST_PATTERN;
+ else if (memcmp(pattern_os, mac->mac_addr, 6) == 0)
+ rtl_pattern.type = UNICAST_PATTERN;
+ else
+ rtl_pattern.type = UNKNOWN_TYPE;
+
+ /* 2. translate mask_from_os to mask_for_hw */
+
+/******************************************************************************
+ * pattern from OS uses 'ethenet frame', like this:
+
+ | 6 | 6 | 2 | 20 | Variable | 4 |
+ |--------+--------+------+-----------+------------+-----|
+ | 802.3 Mac Header | IP Header | TCP Packet | FCS |
+ | DA | SA | Type |
+
+ * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
+
+ | 24 or 30 | 6 | 2 | 20 | Variable | 4 |
+ |-------------------+--------+------+-----------+------------+-----|
+ | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |
+ | Others | Tpye |
+
+ * Therefore, we need translate mask_from_OS to mask_to_hw.
+ * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
+ * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
+ * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
+ ******************************************************************************/
+
+ /* Shift 6 bits */
+ for (j = 0; j < mask_len - 1; j++) {
+ mask[j] = mask_os[j] >> 6;
+ mask[j] |= (mask_os[j + 1] & 0x3F) << 2;
+ }
+ mask[j] = (mask_os[j] >> 6) & 0x3F;
+ /* Set bit 0-5 to zero */
+ mask[0] &= 0xC0;
+
+ RT_PRINT_DATA(rtlpriv, COMP_POWER, DBG_TRACE,
+ "mask to hw\n", mask, mask_len);
+ for (j = 0; j < (MAX_WOL_BIT_MASK_SIZE + 1) / 4; j++) {
+ rtl_pattern.mask[j] = mask[j * 4];
+ rtl_pattern.mask[j] |= (mask[j * 4 + 1] << 8);
+ rtl_pattern.mask[j] |= (mask[j * 4 + 2] << 16);
+ rtl_pattern.mask[j] |= (mask[j * 4 + 3] << 24);
+ }
+
+ /* To get the wake up pattern from the mask.
+ * We do not count first 12 bits which means
+ * DA[6] and SA[6] in the pattern to match HW design.
+ */
+ len = 0;
+ for (j = 12; j < patterns[i].pattern_len; j++) {
+ if ((mask_os[j / 8] >> (j % 8)) & 0x01) {
+ content[len] = pattern_os[j];
+ len++;
+ }
+ }
+
+ RT_PRINT_DATA(rtlpriv, COMP_POWER, DBG_TRACE,
+ "pattern to hw\n", content, len);
+ /* 3. calculate crc */
+ rtl_pattern.crc = _calculate_wol_pattern_crc(content, len);
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
+ "CRC_Remainder = 0x%x\n", rtl_pattern.crc);
+
+ /* 4. write crc & mask_for_hw to hw */
+ rtlpriv->cfg->ops->add_wowlan_pattern(hw, &rtl_pattern, i);
+ }
+ rtl_write_byte(rtlpriv, 0x698, wow->n_patterns);
+}
+
+static int rtl_op_suspend(struct ieee80211_hw *hw,
+ struct cfg80211_wowlan *wow)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct timeval ts;
+
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "\n");
+ if (WARN_ON(!wow))
+ return -EINVAL;
+
+ /* to resolve s4 can not wake up*/
+ do_gettimeofday(&ts);
+ rtlhal->last_suspend_sec = ts.tv_sec;
+
+ if ((ppsc->wo_wlan_mode & WAKE_ON_PATTERN_MATCH) && wow->n_patterns)
+ _rtl_add_wowlan_patterns(hw, wow);
+
+ rtlhal->driver_is_goingto_unload = true;
+ rtlhal->enter_pnp_sleep = true;
+
+ rtl_lps_leave(hw);
+ rtl_op_stop(hw);
+ device_set_wakeup_enable(wiphy_dev(hw->wiphy), true);
+ return 0;
+}
+
+static int rtl_op_resume(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct timeval ts;
+
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "\n");
+ rtlhal->driver_is_goingto_unload = false;
+ rtlhal->enter_pnp_sleep = false;
+ rtlhal->wake_from_pnp_sleep = true;
+
+ /* to resovle s4 can not wake up*/
+ do_gettimeofday(&ts);
+ if (ts.tv_sec - rtlhal->last_suspend_sec < 5)
+ return -1;
+
+ rtl_op_start(hw);
+ device_set_wakeup_enable(wiphy_dev(hw->wiphy), false);
+ ieee80211_resume_disconnect(mac->vif);
+ rtlhal->wake_from_pnp_sleep = false;
+ return 0;
+}
+#endif
+
+static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct ieee80211_conf *conf = &hw->conf;
+
+ if (mac->skip_scan)
+ return 1;
+
+ mutex_lock(&rtlpriv->locks.conf_mutex);
+ if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { /* BIT(2)*/
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ "IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n");
+ }
+
+ /*For IPS */
+ if (changed & IEEE80211_CONF_CHANGE_IDLE) {
+ if (hw->conf.flags & IEEE80211_CONF_IDLE)
+ rtl_ips_nic_off(hw);
+ else
+ rtl_ips_nic_on(hw);
+ } else {
+ /*
+ *although rfoff may not cause by ips, but we will
+ *check the reason in set_rf_power_state function
+ */
+ if (unlikely(ppsc->rfpwr_state == ERFOFF))
+ rtl_ips_nic_on(hw);
+ }
+
+ /*For LPS */
+ if ((changed & IEEE80211_CONF_CHANGE_PS) &&
+ rtlpriv->psc.swctrl_lps && !rtlpriv->psc.fwctrl_lps) {
+ cancel_delayed_work(&rtlpriv->works.ps_work);
+ cancel_delayed_work(&rtlpriv->works.ps_rfon_wq);
+ if (conf->flags & IEEE80211_CONF_PS) {
+ rtlpriv->psc.sw_ps_enabled = true;
+ /* sleep here is must, or we may recv the beacon and
+ * cause mac80211 into wrong ps state, this will cause
+ * power save nullfunc send fail, and further cause
+ * pkt loss, So sleep must quickly but not immediately
+ * because that will cause nullfunc send by mac80211
+ * fail, and cause pkt loss, we have tested that 5mA
+ * works very well
+ */
+ if (!rtlpriv->psc.multi_buffered)
+ queue_delayed_work(rtlpriv->works.rtl_wq,
+ &rtlpriv->works.ps_work,
+ MSECS(5));
+ } else {
+ rtl_swlps_rf_awake(hw);
+ rtlpriv->psc.sw_ps_enabled = false;
+ }
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ "IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n",
+ hw->conf.long_frame_max_tx_count);
+ /* brought up everything changes (changed == ~0) indicates first
+ * open, so use our default value instead of that of wiphy.
+ */
+ if (changed != ~0) {
+ mac->retry_long = hw->conf.long_frame_max_tx_count;
+ mac->retry_short = hw->conf.long_frame_max_tx_count;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,
+ (u8 *)(&hw->conf.long_frame_max_tx_count));
+ }
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_CHANNEL &&
+ !rtlpriv->proximity.proxim_on) {
+ struct ieee80211_channel *channel = hw->conf.chandef.chan;
+ enum nl80211_chan_width width = hw->conf.chandef.width;
+ enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
+ u8 wide_chan = (u8)channel->hw_value;
+
+ /* channel_type is for 20&40M */
+ if (width < NL80211_CHAN_WIDTH_80)
+ channel_type =
+ cfg80211_get_chandef_type(&hw->conf.chandef);
+ if (mac->act_scanning)
+ mac->n_channels++;
+
+ if (rtlpriv->dm.supp_phymode_switch &&
+ mac->link_state < MAC80211_LINKED &&
+ !mac->act_scanning) {
+ if (rtlpriv->cfg->ops->chk_switch_dmdp)
+ rtlpriv->cfg->ops->chk_switch_dmdp(hw);
+ }
+
+ /*
+ *because we should back channel to
+ *current_network.chan in in scanning,
+ *So if set_chan == current_network.chan
+ *we should set it.
+ *because mac80211 tell us wrong bw40
+ *info for cisco1253 bw20, so we modify
+ *it here based on UPPER & LOWER
+ */
+
+ if (width >= NL80211_CHAN_WIDTH_80) {
+ if (width == NL80211_CHAN_WIDTH_80) {
+ u32 center = hw->conf.chandef.center_freq1;
+ u32 primary =
+ (u32)hw->conf.chandef.chan->center_freq;
+
+ rtlphy->current_chan_bw =
+ HT_CHANNEL_WIDTH_80;
+ mac->bw_80 = true;
+ mac->bw_40 = true;
+ if (center > primary) {
+ mac->cur_80_prime_sc =
+ PRIME_CHNL_OFFSET_LOWER;
+ if (center - primary == 10) {
+ mac->cur_40_prime_sc =
+ PRIME_CHNL_OFFSET_UPPER;
+
+ wide_chan += 2;
+ } else if (center - primary == 30) {
+ mac->cur_40_prime_sc =
+ PRIME_CHNL_OFFSET_LOWER;
+
+ wide_chan += 6;
+ }
+ } else {
+ mac->cur_80_prime_sc =
+ PRIME_CHNL_OFFSET_UPPER;
+ if (primary - center == 10) {
+ mac->cur_40_prime_sc =
+ PRIME_CHNL_OFFSET_LOWER;
+
+ wide_chan -= 2;
+ } else if (primary - center == 30) {
+ mac->cur_40_prime_sc =
+ PRIME_CHNL_OFFSET_UPPER;
+
+ wide_chan -= 6;
+ }
+ }
+ }
+ } else {
+ switch (channel_type) {
+ case NL80211_CHAN_HT20:
+ case NL80211_CHAN_NO_HT:
+ /* SC */
+ mac->cur_40_prime_sc =
+ PRIME_CHNL_OFFSET_DONT_CARE;
+ rtlphy->current_chan_bw =
+ HT_CHANNEL_WIDTH_20;
+ mac->bw_40 = false;
+ mac->bw_80 = false;
+ break;
+ case NL80211_CHAN_HT40MINUS:
+ /* SC */
+ mac->cur_40_prime_sc =
+ PRIME_CHNL_OFFSET_UPPER;
+ rtlphy->current_chan_bw =
+ HT_CHANNEL_WIDTH_20_40;
+ mac->bw_40 = true;
+ mac->bw_80 = false;
+
+ /*wide channel */
+ wide_chan -= 2;
+
+ break;
+ case NL80211_CHAN_HT40PLUS:
+ /* SC */
+ mac->cur_40_prime_sc =
+ PRIME_CHNL_OFFSET_LOWER;
+ rtlphy->current_chan_bw =
+ HT_CHANNEL_WIDTH_20_40;
+ mac->bw_40 = true;
+ mac->bw_80 = false;
+
+ /*wide channel */
+ wide_chan += 2;
+
+ break;
+ default:
+ mac->bw_40 = false;
+ mac->bw_80 = false;
+ pr_err("switch case %#x not processed\n",
+ channel_type);
+ break;
+ }
+ }
+
+ if (wide_chan <= 0)
+ wide_chan = 1;
+
+ /* In scanning, when before we offchannel we may send a ps=1
+ * null to AP, and then we may send a ps = 0 null to AP quickly,
+ * but first null may have caused AP to put lots of packet to
+ * hw tx buffer. These packets must be tx'd before we go off
+ * channel so we must delay more time to let AP flush these
+ * packets before going offchannel, or dis-association or
+ * delete BA will be caused by AP
+ */
+ if (rtlpriv->mac80211.offchan_delay) {
+ rtlpriv->mac80211.offchan_delay = false;
+ mdelay(50);
+ }
+
+ rtlphy->current_channel = wide_chan;
+
+ rtlpriv->cfg->ops->switch_channel(hw);
+ rtlpriv->cfg->ops->set_channel_access(hw);
+ rtlpriv->cfg->ops->set_bw_mode(hw, channel_type);
+ }
+
+ mutex_unlock(&rtlpriv->locks.conf_mutex);
+
+ return 0;
+}
+
+static void rtl_op_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *new_flags, u64 multicast)
+{
+ bool update_rcr = false;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+ *new_flags &= RTL_SUPPORTED_FILTERS;
+ if (changed_flags == 0)
+ return;
+
+ /*TODO: we disable broadcase now, so enable here */
+ if (changed_flags & FIF_ALLMULTI) {
+ if (*new_flags & FIF_ALLMULTI) {
+ mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AM] |
+ rtlpriv->cfg->maps[MAC_RCR_AB];
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ "Enable receive multicast frame\n");
+ } else {
+ mac->rx_conf &= ~(rtlpriv->cfg->maps[MAC_RCR_AM] |
+ rtlpriv->cfg->maps[MAC_RCR_AB]);
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ "Disable receive multicast frame\n");
+ }
+ update_rcr = true;
+ }
+
+ if (changed_flags & FIF_FCSFAIL) {
+ if (*new_flags & FIF_FCSFAIL) {
+ mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACRC32];
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ "Enable receive FCS error frame\n");
+ } else {
+ mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACRC32];
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ "Disable receive FCS error frame\n");
+ }
+ if (!update_rcr)
+ update_rcr = true;
+ }
+
+ /* if ssid not set to hw don't check bssid
+ * here just used for linked scanning, & linked
+ * and nolink check bssid is set in set network_type
+ */
+ if ((changed_flags & FIF_BCN_PRBRESP_PROMISC) &&
+ (mac->link_state >= MAC80211_LINKED)) {
+ if (mac->opmode != NL80211_IFTYPE_AP &&
+ mac->opmode != NL80211_IFTYPE_MESH_POINT) {
+ if (*new_flags & FIF_BCN_PRBRESP_PROMISC)
+ rtlpriv->cfg->ops->set_chk_bssid(hw, false);
+ else
+ rtlpriv->cfg->ops->set_chk_bssid(hw, true);
+ if (update_rcr)
+ update_rcr = false;
+ }
+ }
+
+ if (changed_flags & FIF_CONTROL) {
+ if (*new_flags & FIF_CONTROL) {
+ mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF];
+
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ "Enable receive control frame.\n");
+ } else {
+ mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF];
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ "Disable receive control frame.\n");
+ }
+ if (!update_rcr)
+ update_rcr = true;
+ }
+
+ if (changed_flags & FIF_OTHER_BSS) {
+ if (*new_flags & FIF_OTHER_BSS) {
+ mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AAP];
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ "Enable receive other BSS's frame.\n");
+ } else {
+ mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_AAP];
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ "Disable receive other BSS's frame.\n");
+ }
+ if (!update_rcr)
+ update_rcr = true;
+ }
+
+ if (update_rcr)
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
+ (u8 *)(&mac->rx_conf));
+}
+
+static int rtl_op_sta_add(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_sta_info *sta_entry;
+
+ if (sta) {
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+ spin_lock_bh(&rtlpriv->locks.entry_list_lock);
+ list_add_tail(&sta_entry->list, &rtlpriv->entry_list);
+ spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
+ if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+ sta_entry->wireless_mode = WIRELESS_MODE_G;
+ if (sta->supp_rates[0] <= 0xf)
+ sta_entry->wireless_mode = WIRELESS_MODE_B;
+ if (sta->ht_cap.ht_supported)
+ sta_entry->wireless_mode = WIRELESS_MODE_N_24G;
+
+ if (vif->type == NL80211_IFTYPE_ADHOC)
+ sta_entry->wireless_mode = WIRELESS_MODE_G;
+ } else if (rtlhal->current_bandtype == BAND_ON_5G) {
+ sta_entry->wireless_mode = WIRELESS_MODE_A;
+ if (sta->ht_cap.ht_supported)
+ sta_entry->wireless_mode = WIRELESS_MODE_N_5G;
+ if (sta->vht_cap.vht_supported)
+ sta_entry->wireless_mode = WIRELESS_MODE_AC_5G;
+
+ if (vif->type == NL80211_IFTYPE_ADHOC)
+ sta_entry->wireless_mode = WIRELESS_MODE_A;
+ }
+ /*disable cck rate for p2p*/
+ if (mac->p2p)
+ sta->supp_rates[0] &= 0xfffffff0;
+
+ if (sta->ht_cap.ht_supported) {
+ if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
+ rtlphy->max_ht_chan_bw = HT_CHANNEL_WIDTH_20_40;
+ else
+ rtlphy->max_ht_chan_bw = HT_CHANNEL_WIDTH_20;
+ }
+
+ if (sta->vht_cap.vht_supported)
+ rtlphy->max_vht_chan_bw = HT_CHANNEL_WIDTH_80;
+
+ memcpy(sta_entry->mac_addr, sta->addr, ETH_ALEN);
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
+ "Add sta addr is %pM\n", sta->addr);
+ rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0, true);
+
+ if (rtlpriv->phydm.ops)
+ rtlpriv->phydm.ops->phydm_add_sta(rtlpriv, sta);
+ }
+
+ return 0;
+}
+
+static int rtl_op_sta_remove(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_sta_info *sta_entry;
+
+ if (sta) {
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
+ "Remove sta addr is %pM\n", sta->addr);
+
+ if (rtlpriv->phydm.ops)
+ rtlpriv->phydm.ops->phydm_del_sta(rtlpriv, sta);
+
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+ sta_entry->wireless_mode = 0;
+ sta_entry->ratr_index = 0;
+ spin_lock_bh(&rtlpriv->locks.entry_list_lock);
+ list_del(&sta_entry->list);
+ spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
+ }
+ return 0;
+}
+
+static int _rtl_get_hal_qnum(u16 queue)
+{
+ int qnum;
+
+ switch (queue) {
+ case 0:
+ qnum = AC3_VO;
+ break;
+ case 1:
+ qnum = AC2_VI;
+ break;
+ case 2:
+ qnum = AC0_BE;
+ break;
+ case 3:
+ qnum = AC1_BK;
+ break;
+ default:
+ qnum = AC0_BE;
+ break;
+ }
+ return qnum;
+}
+
+static void rtl_op_sta_statistics(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct station_info *sinfo)
+{
+ /* nothing filled by driver, so mac80211 will update all info */
+ sinfo->filled = 0;
+}
+
+static int rtl_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
+{
+ return -EOPNOTSUPP;
+}
+
+/*
+ *for mac80211 VO = 0, VI = 1, BE = 2, BK = 3
+ *for rtl819x BE = 0, BK = 1, VI = 2, VO = 3
+ */
+static int rtl_op_conf_tx(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif, u16 queue,
+ const struct ieee80211_tx_queue_params *param)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ int aci;
+
+ if (queue >= AC_MAX) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ "queue number %d is incorrect!\n", queue);
+ return -EINVAL;
+ }
+
+ aci = _rtl_get_hal_qnum(queue);
+ mac->ac[aci].aifs = param->aifs;
+ mac->ac[aci].cw_min = cpu_to_le16(param->cw_min);
+ mac->ac[aci].cw_max = cpu_to_le16(param->cw_max);
+ mac->ac[aci].tx_op = cpu_to_le16(param->txop);
+ memcpy(&mac->edca_param[aci], param, sizeof(*param));
+ rtlpriv->cfg->ops->set_qos(hw, aci);
+ return 0;
+}
+
+static void send_beacon_frame(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct sk_buff *skb = ieee80211_beacon_get(hw, vif);
+ struct rtl_tcb_desc tcb_desc;
+
+ if (skb) {
+ memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
+ rtlpriv->intf_ops->adapter_tx(hw, NULL, skb, &tcb_desc);
+ }
+}
+
+static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf,
+ u32 changed)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+ mutex_lock(&rtlpriv->locks.conf_mutex);
+ if ((vif->type == NL80211_IFTYPE_ADHOC) ||
+ (vif->type == NL80211_IFTYPE_AP) ||
+ (vif->type == NL80211_IFTYPE_MESH_POINT)) {
+ if ((changed & BSS_CHANGED_BEACON) ||
+ (changed & BSS_CHANGED_BEACON_ENABLED &&
+ bss_conf->enable_beacon)) {
+ if (mac->beacon_enabled == 0) {
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
+ "BSS_CHANGED_BEACON_ENABLED\n");
+
+ /*start hw beacon interrupt. */
+ /*rtlpriv->cfg->ops->set_bcn_reg(hw); */
+ mac->beacon_enabled = 1;
+ rtlpriv->cfg->ops->update_interrupt_mask(hw,
+ rtlpriv->cfg->maps
+ [RTL_IBSS_INT_MASKS], 0);
+
+ if (rtlpriv->cfg->ops->linked_set_reg)
+ rtlpriv->cfg->ops->linked_set_reg(hw);
+ send_beacon_frame(hw, vif);
+ }
+ }
+ if ((changed & BSS_CHANGED_BEACON_ENABLED &&
+ !bss_conf->enable_beacon)) {
+ if (mac->beacon_enabled == 1) {
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
+ "ADHOC DISABLE BEACON\n");
+
+ mac->beacon_enabled = 0;
+ rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
+ rtlpriv->cfg->maps
+ [RTL_IBSS_INT_MASKS]);
+ }
+ }
+ if (changed & BSS_CHANGED_BEACON_INT) {
+ RT_TRACE(rtlpriv, COMP_BEACON, DBG_TRACE,
+ "BSS_CHANGED_BEACON_INT\n");
+ mac->beacon_interval = bss_conf->beacon_int;
+ rtlpriv->cfg->ops->set_bcn_intv(hw);
+ }
+ }
+
+ /*TODO: reference to enum ieee80211_bss_change */
+ if (changed & BSS_CHANGED_ASSOC) {
+ u8 mstatus;
+
+ if (bss_conf->assoc) {
+ struct ieee80211_sta *sta = NULL;
+ u8 keep_alive = 10;
+
+ mstatus = RT_MEDIA_CONNECT;
+ /* we should reset all sec info & cam
+ * before set cam after linked, we should not
+ * reset in disassoc, that will cause tkip->wep
+ * fail because some flag will be wrong
+ * reset sec info
+ */
+ rtl_cam_reset_sec_info(hw);
+ /* reset cam to fix wep fail issue
+ * when change from wpa to wep
+ */
+ rtl_cam_reset_all_entry(hw);
+
+ mac->link_state = MAC80211_LINKED;
+ mac->cnt_after_linked = 0;
+ mac->assoc_id = bss_conf->aid;
+ memcpy(mac->bssid, bss_conf->bssid, ETH_ALEN);
+
+ if (rtlpriv->cfg->ops->linked_set_reg)
+ rtlpriv->cfg->ops->linked_set_reg(hw);
+
+ rcu_read_lock();
+ sta = ieee80211_find_sta(vif, (u8 *)bss_conf->bssid);
+ if (!sta) {
+ rcu_read_unlock();
+ goto out;
+ }
+ RT_TRACE(rtlpriv, COMP_EASY_CONCURRENT, DBG_LOUD,
+ "send PS STATIC frame\n");
+ if (rtlpriv->dm.supp_phymode_switch) {
+ if (sta->ht_cap.ht_supported)
+ rtl_send_smps_action(hw, sta,
+ IEEE80211_SMPS_STATIC);
+ }
+
+ if (rtlhal->current_bandtype == BAND_ON_5G) {
+ mac->mode = WIRELESS_MODE_A;
+ } else {
+ if (sta->supp_rates[0] <= 0xf)
+ mac->mode = WIRELESS_MODE_B;
+ else
+ mac->mode = WIRELESS_MODE_G;
+ }
+
+ if (sta->ht_cap.ht_supported) {
+ if (rtlhal->current_bandtype == BAND_ON_2_4G)
+ mac->mode = WIRELESS_MODE_N_24G;
+ else
+ mac->mode = WIRELESS_MODE_N_5G;
+ }
+
+ if (sta->vht_cap.vht_supported) {
+ if (rtlhal->current_bandtype == BAND_ON_5G)
+ mac->mode = WIRELESS_MODE_AC_5G;
+ else
+ mac->mode = WIRELESS_MODE_AC_24G;
+ }
+
+ if (vif->type == NL80211_IFTYPE_STATION)
+ rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0,
+ true);
+ rcu_read_unlock();
+
+ /* to avoid AP Disassociation caused by inactivity */
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_KEEP_ALIVE,
+ (u8 *)(&keep_alive));
+
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
+ "BSS_CHANGED_ASSOC\n");
+ } else {
+ struct cfg80211_bss *bss = NULL;
+
+ mstatus = RT_MEDIA_DISCONNECT;
+
+ if (mac->link_state == MAC80211_LINKED)
+ rtl_lps_leave(hw);
+ if (ppsc->p2p_ps_info.p2p_ps_mode > P2P_PS_NONE)
+ rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE);
+ mac->link_state = MAC80211_NOLINK;
+
+ bss = cfg80211_get_bss(hw->wiphy, NULL,
+ (u8 *)mac->bssid, NULL, 0,
+ IEEE80211_BSS_TYPE_ESS,
+ IEEE80211_PRIVACY_OFF);
+
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
+ "bssid = %x-%x-%x-%x-%x-%x\n",
+ mac->bssid[0], mac->bssid[1],
+ mac->bssid[2], mac->bssid[3],
+ mac->bssid[4], mac->bssid[5]);
+
+ if (bss) {
+ cfg80211_unlink_bss(hw->wiphy, bss);
+ cfg80211_put_bss(hw->wiphy, bss);
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
+ "cfg80211_unlink !!\n");
+ }
+
+ eth_zero_addr(mac->bssid);
+ mac->vendor = PEER_UNKNOWN;
+ mac->mode = 0;
+
+ if (rtlpriv->dm.supp_phymode_switch) {
+ if (rtlpriv->cfg->ops->chk_switch_dmdp)
+ rtlpriv->cfg->ops->chk_switch_dmdp(hw);
+ }
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
+ "BSS_CHANGED_UN_ASSOC\n");
+ }
+ rtlpriv->cfg->ops->set_network_type(hw, vif->type);
+ /* For FW LPS:
+ * To tell firmware we have connected or disconnected
+ */
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_H2C_FW_JOINBSSRPT,
+ (u8 *)(&mstatus));
+ ppsc->report_linked = (mstatus == RT_MEDIA_CONNECT) ?
+ true : false;
+
+ if (rtlpriv->cfg->ops->get_btc_status())
+ rtlpriv->btcoexist.btc_ops->btc_mediastatus_notify(
+ rtlpriv, mstatus);
+ }
+
+ if (changed & BSS_CHANGED_ERP_CTS_PROT) {
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
+ "BSS_CHANGED_ERP_CTS_PROT\n");
+ mac->use_cts_protect = bss_conf->use_cts_prot;
+ }
+
+ if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ "BSS_CHANGED_ERP_PREAMBLE use short preamble:%x\n",
+ bss_conf->use_short_preamble);
+
+ mac->short_preamble = bss_conf->use_short_preamble;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACK_PREAMBLE,
+ (u8 *)(&mac->short_preamble));
+ }
+
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
+ "BSS_CHANGED_ERP_SLOT\n");
+
+ if (bss_conf->use_short_slot)
+ mac->slot_time = RTL_SLOT_TIME_9;
+ else
+ mac->slot_time = RTL_SLOT_TIME_20;
+
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
+ (u8 *)(&mac->slot_time));
+ }
+
+ if (changed & BSS_CHANGED_HT) {
+ struct ieee80211_sta *sta = NULL;
+
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
+ "BSS_CHANGED_HT\n");
+
+ rcu_read_lock();
+ sta = ieee80211_find_sta(vif, (u8 *)bss_conf->bssid);
+ if (sta) {
+ if (sta->ht_cap.ampdu_density >
+ mac->current_ampdu_density)
+ mac->current_ampdu_density =
+ sta->ht_cap.ampdu_density;
+ if (sta->ht_cap.ampdu_factor <
+ mac->current_ampdu_factor)
+ mac->current_ampdu_factor =
+ sta->ht_cap.ampdu_factor;
+
+ if (sta->ht_cap.ht_supported) {
+ if (sta->ht_cap.cap &
+ IEEE80211_HT_CAP_SUP_WIDTH_20_40)
+ rtlphy->max_ht_chan_bw =
+ HT_CHANNEL_WIDTH_20_40;
+ else
+ rtlphy->max_ht_chan_bw =
+ HT_CHANNEL_WIDTH_20;
+ }
+ }
+ rcu_read_unlock();
+
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SHORTGI_DENSITY,
+ (u8 *)(&mac->max_mss_density));
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_FACTOR,
+ &mac->current_ampdu_factor);
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_MIN_SPACE,
+ &mac->current_ampdu_density);
+ }
+
+ if (changed & BSS_CHANGED_BANDWIDTH) {
+ struct ieee80211_sta *sta = NULL;
+
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
+ "BSS_CHANGED_BANDWIDTH\n");
+
+ rcu_read_lock();
+ sta = ieee80211_find_sta(vif, (u8 *)bss_conf->bssid);
+
+ if (sta) {
+ if (sta->ht_cap.ht_supported) {
+ if (sta->ht_cap.cap &
+ IEEE80211_HT_CAP_SUP_WIDTH_20_40)
+ rtlphy->max_ht_chan_bw =
+ HT_CHANNEL_WIDTH_20_40;
+ else
+ rtlphy->max_ht_chan_bw =
+ HT_CHANNEL_WIDTH_20;
+ }
+
+ if (sta->vht_cap.vht_supported)
+ rtlphy->max_vht_chan_bw = HT_CHANNEL_WIDTH_80;
+ }
+ rcu_read_unlock();
+ }
+
+ if (changed & BSS_CHANGED_BSSID) {
+ u32 basic_rates;
+ struct ieee80211_sta *sta = NULL;
+
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID,
+ (u8 *)bss_conf->bssid);
+
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
+ "bssid: %pM\n", bss_conf->bssid);
+
+ mac->vendor = PEER_UNKNOWN;
+ memcpy(mac->bssid, bss_conf->bssid, ETH_ALEN);
+
+ rcu_read_lock();
+ sta = ieee80211_find_sta(vif, (u8 *)bss_conf->bssid);
+ if (!sta) {
+ rcu_read_unlock();
+ goto out;
+ }
+
+ if (rtlhal->current_bandtype == BAND_ON_5G) {
+ mac->mode = WIRELESS_MODE_A;
+ } else {
+ if (sta->supp_rates[0] <= 0xf)
+ mac->mode = WIRELESS_MODE_B;
+ else
+ mac->mode = WIRELESS_MODE_G;
+ }
+
+ if (sta->ht_cap.ht_supported) {
+ if (rtlhal->current_bandtype == BAND_ON_2_4G)
+ mac->mode = WIRELESS_MODE_N_24G;
+ else
+ mac->mode = WIRELESS_MODE_N_5G;
+ }
+
+ if (sta->vht_cap.vht_supported) {
+ if (rtlhal->current_bandtype == BAND_ON_5G)
+ mac->mode = WIRELESS_MODE_AC_5G;
+ else
+ mac->mode = WIRELESS_MODE_AC_24G;
+ }
+
+ /* just station need it, because ibss & ap mode will
+ * set in sta_add, and will be NULL here
+ */
+ if (vif->type == NL80211_IFTYPE_STATION) {
+ struct rtl_sta_info *sta_entry;
+
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+ sta_entry->wireless_mode = mac->mode;
+ }
+
+ if (sta->ht_cap.ht_supported) {
+ mac->ht_enable = true;
+
+ /* for cisco 1252 bw20 it's wrong
+ * if (ht_cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
+ * mac->bw_40 = true;
+ * }
+ */
+ }
+
+ if (sta->vht_cap.vht_supported)
+ mac->vht_enable = true;
+
+ if (changed & BSS_CHANGED_BASIC_RATES) {
+ /* for 5G must << RATE_6M_INDEX = 4,
+ * because 5G have no cck rate
+ */
+ if (rtlhal->current_bandtype == BAND_ON_5G)
+ basic_rates = sta->supp_rates[1] << 4;
+ else
+ basic_rates = sta->supp_rates[0];
+
+ mac->basic_rates = basic_rates;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
+ (u8 *)(&basic_rates));
+ }
+ rcu_read_unlock();
+ }
+out:
+ mutex_unlock(&rtlpriv->locks.conf_mutex);
+}
+
+static u64 rtl_op_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u64 tsf;
+
+ rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *)(&tsf));
+ return tsf;
+}
+
+static void rtl_op_set_tsf(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif, u64 tsf)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0;
+
+ mac->tsf = tsf;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *)(&bibss));
+}
+
+static void rtl_op_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 tmp = 0;
+
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_DUAL_TSF_RST, (u8 *)(&tmp));
+}
+
+static void rtl_op_sta_notify(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum sta_notify_cmd cmd,
+ struct ieee80211_sta *sta)
+{
+ switch (cmd) {
+ case STA_NOTIFY_SLEEP:
+ break;
+ case STA_NOTIFY_AWAKE:
+ break;
+ default:
+ break;
+ }
+}
+
+static int rtl_op_ampdu_action(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_ampdu_params *params)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct ieee80211_sta *sta = params->sta;
+ enum ieee80211_ampdu_mlme_action action = params->action;
+ u16 tid = params->tid;
+ u16 *ssn = &params->ssn;
+
+ switch (action) {
+ case IEEE80211_AMPDU_TX_START:
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
+ "IEEE80211_AMPDU_TX_START: TID:%d\n", tid);
+ return rtl_tx_agg_start(hw, vif, sta, tid, ssn);
+ case IEEE80211_AMPDU_TX_STOP_CONT:
+ case IEEE80211_AMPDU_TX_STOP_FLUSH:
+ case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
+ "IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid);
+ return rtl_tx_agg_stop(hw, vif, sta, tid);
+ case IEEE80211_AMPDU_TX_OPERATIONAL:
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
+ "IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid);
+ rtl_tx_agg_oper(hw, sta, tid);
+ break;
+ case IEEE80211_AMPDU_RX_START:
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
+ "IEEE80211_AMPDU_RX_START:TID:%d\n", tid);
+ return rtl_rx_agg_start(hw, sta, tid);
+ case IEEE80211_AMPDU_RX_STOP:
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
+ "IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid);
+ return rtl_rx_agg_stop(hw, sta, tid);
+ default:
+ pr_err("IEEE80211_AMPDU_ERR!!!!:\n");
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
+static void rtl_op_sw_scan_start(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ const u8 *mac_addr)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n");
+ mac->act_scanning = true;
+ if (rtlpriv->link_info.higher_busytraffic) {
+ mac->skip_scan = true;
+ return;
+ }
+
+ if (rtlpriv->phydm.ops)
+ rtlpriv->phydm.ops->phydm_pause_dig(rtlpriv, 1);
+
+ if (rtlpriv->cfg->ops->get_btc_status())
+ rtlpriv->btcoexist.btc_ops->btc_scan_notify(rtlpriv, 1);
+ else if (rtlpriv->btcoexist.btc_ops)
+ rtlpriv->btcoexist.btc_ops->btc_scan_notify_wifi_only(rtlpriv,
+ 1);
+
+ if (rtlpriv->dm.supp_phymode_switch) {
+ if (rtlpriv->cfg->ops->chk_switch_dmdp)
+ rtlpriv->cfg->ops->chk_switch_dmdp(hw);
+ }
+
+ if (mac->link_state == MAC80211_LINKED) {
+ rtl_lps_leave(hw);
+ mac->link_state = MAC80211_LINKED_SCANNING;
+ } else {
+ rtl_ips_nic_on(hw);
+ }
+
+ /* Dul mac */
+ rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false;
+
+ rtlpriv->cfg->ops->led_control(hw, LED_CTL_SITE_SURVEY);
+ rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_BACKUP_BAND0);
+}
+
+static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n");
+ mac->act_scanning = false;
+ mac->skip_scan = false;
+
+ rtlpriv->btcoexist.btc_info.ap_num = rtlpriv->scan_list.num;
+
+ if (rtlpriv->link_info.higher_busytraffic)
+ return;
+
+ /* p2p will use 1/6/11 to scan */
+ if (mac->n_channels == 3)
+ mac->p2p_in_use = true;
+ else
+ mac->p2p_in_use = false;
+ mac->n_channels = 0;
+ /* Dul mac */
+ rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false;
+
+ if (mac->link_state == MAC80211_LINKED_SCANNING) {
+ mac->link_state = MAC80211_LINKED;
+ if (mac->opmode == NL80211_IFTYPE_STATION) {
+ /* fix fwlps issue */
+ rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);
+ }
+ }
+
+ rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_RESTORE);
+ if (rtlpriv->cfg->ops->get_btc_status())
+ rtlpriv->btcoexist.btc_ops->btc_scan_notify(rtlpriv, 0);
+ else if (rtlpriv->btcoexist.btc_ops)
+ rtlpriv->btcoexist.btc_ops->btc_scan_notify_wifi_only(rtlpriv,
+ 0);
+
+ if (rtlpriv->phydm.ops)
+ rtlpriv->phydm.ops->phydm_pause_dig(rtlpriv, 0);
+}
+
+static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 key_type = NO_ENCRYPTION;
+ u8 key_idx;
+ bool group_key = false;
+ bool wep_only = false;
+ int err = 0;
+ u8 mac_addr[ETH_ALEN];
+ u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+ rtlpriv->btcoexist.btc_info.in_4way = false;
+
+ if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ "not open hw encryption\n");
+ return -ENOSPC; /*User disabled HW-crypto */
+ }
+ /* To support IBSS, use sw-crypto for GTK */
+ if (((vif->type == NL80211_IFTYPE_ADHOC) ||
+ (vif->type == NL80211_IFTYPE_MESH_POINT)) &&
+ !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
+ return -ENOSPC;
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ "%s hardware based encryption for keyidx: %d, mac: %pM\n",
+ cmd == SET_KEY ? "Using" : "Disabling", key->keyidx,
+ sta ? sta->addr : bcast_addr);
+ rtlpriv->sec.being_setkey = true;
+ rtl_ips_nic_on(hw);
+ mutex_lock(&rtlpriv->locks.conf_mutex);
+ /* <1> get encryption alg */
+
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ key_type = WEP40_ENCRYPTION;
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP40\n");
+ break;
+ case WLAN_CIPHER_SUITE_WEP104:
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP104\n");
+ key_type = WEP104_ENCRYPTION;
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+ key_type = TKIP_ENCRYPTION;
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:TKIP\n");
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ key_type = AESCCMP_ENCRYPTION;
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:CCMP\n");
+ break;
+ case WLAN_CIPHER_SUITE_AES_CMAC:
+ /* HW don't support CMAC encryption,
+ * use software CMAC encryption
+ */
+ key_type = AESCMAC_ENCRYPTION;
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:CMAC\n");
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ "HW don't support CMAC encryption, use software CMAC encryption\n");
+ err = -EOPNOTSUPP;
+ goto out_unlock;
+ default:
+ pr_err("alg_err:%x!!!!:\n", key->cipher);
+ goto out_unlock;
+ }
+ if (key_type == WEP40_ENCRYPTION ||
+ key_type == WEP104_ENCRYPTION ||
+ vif->type == NL80211_IFTYPE_ADHOC)
+ rtlpriv->sec.use_defaultkey = true;
+
+ /* <2> get key_idx */
+ key_idx = (u8)(key->keyidx);
+ if (key_idx > 3)
+ goto out_unlock;
+ /* <3> if pairwise key enable_hw_sec */
+ group_key = !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE);
+
+ /* wep always be group key, but there are two conditions:
+ * 1) wep only: is just for wep enc, in this condition
+ * rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION
+ * will be true & enable_hw_sec will be set when wep
+ * ke setting.
+ * 2) wep(group) + AES(pairwise): some AP like cisco
+ * may use it, in this condition enable_hw_sec will not
+ * be set when wep key setting.
+ * we must reset sec_info after lingked before set key,
+ * or some flag will be wrong
+ */
+ if (vif->type == NL80211_IFTYPE_AP ||
+ vif->type == NL80211_IFTYPE_MESH_POINT) {
+ if (!group_key || key_type == WEP40_ENCRYPTION ||
+ key_type == WEP104_ENCRYPTION) {
+ if (group_key)
+ wep_only = true;
+ rtlpriv->cfg->ops->enable_hw_sec(hw);
+ }
+ } else {
+ if ((!group_key) || (vif->type == NL80211_IFTYPE_ADHOC) ||
+ rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION) {
+ if (rtlpriv->sec.pairwise_enc_algorithm ==
+ NO_ENCRYPTION &&
+ (key_type == WEP40_ENCRYPTION ||
+ key_type == WEP104_ENCRYPTION))
+ wep_only = true;
+ rtlpriv->sec.pairwise_enc_algorithm = key_type;
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ "set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1 TKIP:2 AES:4 WEP104:5)\n",
+ key_type);
+ rtlpriv->cfg->ops->enable_hw_sec(hw);
+ }
+ }
+ /* <4> set key based on cmd */
+ switch (cmd) {
+ case SET_KEY:
+ if (wep_only) {
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ "set WEP(group/pairwise) key\n");
+ /* Pairwise key with an assigned MAC address. */
+ rtlpriv->sec.pairwise_enc_algorithm = key_type;
+ rtlpriv->sec.group_enc_algorithm = key_type;
+ /*set local buf about wep key. */
+ memcpy(rtlpriv->sec.key_buf[key_idx],
+ key->key, key->keylen);
+ rtlpriv->sec.key_len[key_idx] = key->keylen;
+ eth_zero_addr(mac_addr);
+ } else if (group_key) { /* group key */
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ "set group key\n");
+ /* group key */
+ rtlpriv->sec.group_enc_algorithm = key_type;
+ /*set local buf about group key. */
+ memcpy(rtlpriv->sec.key_buf[key_idx],
+ key->key, key->keylen);
+ rtlpriv->sec.key_len[key_idx] = key->keylen;
+ memcpy(mac_addr, bcast_addr, ETH_ALEN);
+ } else { /* pairwise key */
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ "set pairwise key\n");
+ if (!sta) {
+ WARN_ONCE(true,
+ "rtlwifi: pairwise key without mac_addr\n");
+
+ err = -EOPNOTSUPP;
+ goto out_unlock;
+ }
+ /* Pairwise key with an assigned MAC address. */
+ rtlpriv->sec.pairwise_enc_algorithm = key_type;
+ /*set local buf about pairwise key. */
+ memcpy(rtlpriv->sec.key_buf[PAIRWISE_KEYIDX],
+ key->key, key->keylen);
+ rtlpriv->sec.key_len[PAIRWISE_KEYIDX] = key->keylen;
+ rtlpriv->sec.pairwise_key =
+ rtlpriv->sec.key_buf[PAIRWISE_KEYIDX];
+ memcpy(mac_addr, sta->addr, ETH_ALEN);
+ }
+ rtlpriv->cfg->ops->set_key(hw, key_idx, mac_addr,
+ group_key, key_type, wep_only,
+ false);
+ /* <5> tell mac80211 do something: */
+ /*must use sw generate IV, or can not work !!!!. */
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+ key->hw_key_idx = key_idx;
+ if (key_type == TKIP_ENCRYPTION)
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+ /*use software CCMP encryption for management frames (MFP) */
+ if (key_type == AESCCMP_ENCRYPTION)
+ key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
+ break;
+ case DISABLE_KEY:
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ "disable key delete one entry\n");
+ /*set local buf about wep key. */
+ if (vif->type == NL80211_IFTYPE_AP ||
+ vif->type == NL80211_IFTYPE_MESH_POINT) {
+ if (sta)
+ rtl_cam_del_entry(hw, sta->addr);
+ }
+ memset(rtlpriv->sec.key_buf[key_idx], 0, key->keylen);
+ rtlpriv->sec.key_len[key_idx] = 0;
+ eth_zero_addr(mac_addr);
+ /*
+ *mac80211 will delete entries one by one,
+ *so don't use rtl_cam_reset_all_entry
+ *or clear all entries here.
+ */
+ rtl_wait_tx_report_acked(hw, 500); /* wait 500ms for TX ack */
+
+ rtl_cam_delete_one_entry(hw, mac_addr, key_idx);
+ break;
+ default:
+ pr_err("cmd_err:%x!!!!:\n", cmd);
+ }
+out_unlock:
+ mutex_unlock(&rtlpriv->locks.conf_mutex);
+ rtlpriv->sec.being_setkey = false;
+ return err;
+}
+
+static void rtl_op_rfkill_poll(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ bool radio_state;
+ bool blocked;
+ u8 valid = 0;
+
+ if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
+ return;
+
+ mutex_lock(&rtlpriv->locks.conf_mutex);
+
+ /*if Radio On return true here */
+ radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);
+
+ if (valid) {
+ if (unlikely(radio_state != rtlpriv->rfkill.rfkill_state)) {
+ rtlpriv->rfkill.rfkill_state = radio_state;
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+ "wireless radio switch turned %s\n",
+ radio_state ? "on" : "off");
+
+ blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1;
+ wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
+ }
+ }
+
+ mutex_unlock(&rtlpriv->locks.conf_mutex);
+}
+
+/* this function is called by mac80211 to flush tx buffer
+ * before switch channel or power save, or tx buffer packet
+ * maybe send after offchannel or rf sleep, this may cause
+ * dis-association by AP
+ */
+static void rtl_op_flush(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ u32 queues,
+ bool drop)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ if (rtlpriv->intf_ops->flush)
+ rtlpriv->intf_ops->flush(hw, queues, drop);
+}
+
+/* Description:
+ * This routine deals with the Power Configuration CMD
+ * parsing for RTL8723/RTL8188E Series IC.
+ * Assumption:
+ * We should follow specific format that was released from HW SD.
+ */
+bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version,
+ u8 faversion, u8 interface_type,
+ struct wlan_pwr_cfg pwrcfgcmd[])
+{
+ struct wlan_pwr_cfg cfg_cmd = {0};
+ bool polling_bit = false;
+ u32 ary_idx = 0;
+ u8 value = 0;
+ u32 offset = 0;
+ u32 polling_count = 0;
+ u32 max_polling_cnt = 5000;
+
+ do {
+ cfg_cmd = pwrcfgcmd[ary_idx];
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ "%s(): offset(%#x),cut_msk(%#x), famsk(%#x), interface_msk(%#x), base(%#x), cmd(%#x), msk(%#x), value(%#x)\n",
+ __func__, GET_PWR_CFG_OFFSET(cfg_cmd),
+ GET_PWR_CFG_CUT_MASK(cfg_cmd),
+ GET_PWR_CFG_FAB_MASK(cfg_cmd),
+ GET_PWR_CFG_INTF_MASK(cfg_cmd),
+ GET_PWR_CFG_BASE(cfg_cmd), GET_PWR_CFG_CMD(cfg_cmd),
+ GET_PWR_CFG_MASK(cfg_cmd), GET_PWR_CFG_VALUE(cfg_cmd));
+
+ if ((GET_PWR_CFG_FAB_MASK(cfg_cmd) & faversion) &&
+ (GET_PWR_CFG_CUT_MASK(cfg_cmd) & cut_version) &&
+ (GET_PWR_CFG_INTF_MASK(cfg_cmd) & interface_type)) {
+ switch (GET_PWR_CFG_CMD(cfg_cmd)) {
+ case PWR_CMD_READ:
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ "%s(): PWR_CMD_READ\n", __func__);
+ break;
+ case PWR_CMD_WRITE:
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ "%s(): PWR_CMD_WRITE\n", __func__);
+ offset = GET_PWR_CFG_OFFSET(cfg_cmd);
+
+ /*Read the value from system register*/
+ value = rtl_read_byte(rtlpriv, offset);
+ value &= (~(GET_PWR_CFG_MASK(cfg_cmd)));
+ value |= (GET_PWR_CFG_VALUE(cfg_cmd) &
+ GET_PWR_CFG_MASK(cfg_cmd));
+
+ /*Write the value back to system register*/
+ rtl_write_byte(rtlpriv, offset, value);
+ break;
+ case PWR_CMD_POLLING:
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ "%s(): PWR_CMD_POLLING\n", __func__);
+ polling_bit = false;
+ offset = GET_PWR_CFG_OFFSET(cfg_cmd);
+
+ do {
+ value = rtl_read_byte(rtlpriv, offset);
+
+ value &= GET_PWR_CFG_MASK(cfg_cmd);
+ if (value ==
+ (GET_PWR_CFG_VALUE(cfg_cmd) &
+ GET_PWR_CFG_MASK(cfg_cmd)))
+ polling_bit = true;
+ else
+ udelay(10);
+
+ if (polling_count++ > max_polling_cnt)
+ return false;
+ } while (!polling_bit);
+ break;
+ case PWR_CMD_DELAY:
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ "%s(): PWR_CMD_DELAY\n", __func__);
+ if (GET_PWR_CFG_VALUE(cfg_cmd) ==
+ PWRSEQ_DELAY_US)
+ udelay(GET_PWR_CFG_OFFSET(cfg_cmd));
+ else
+ mdelay(GET_PWR_CFG_OFFSET(cfg_cmd));
+ break;
+ case PWR_CMD_END:
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ "%s(): PWR_CMD_END\n", __func__);
+ return true;
+ default:
+ WARN_ONCE(true,
+ "rtlwifi: %s(): Unknown CMD!!\n", __func__);
+ break;
+ }
+ }
+ ary_idx++;
+ } while (1);
+
+ return true;
+}
+
+bool rtl_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl8192_tx_ring *ring;
+ struct rtl_tx_desc *pdesc;
+ unsigned long flags;
+ struct sk_buff *pskb = NULL;
+
+ ring = &rtlpci->tx_ring[BEACON_QUEUE];
+
+ spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
+ pskb = __skb_dequeue(&ring->queue);
+ if (pskb)
+ dev_kfree_skb_irq(pskb);
+
+ /*this is wrong, fill_tx_cmddesc needs update*/
+ pdesc = &ring->desc[0];
+
+ rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, 1, 1, skb);
+
+ __skb_queue_tail(&ring->queue, skb);
+
+ spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+
+ rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
+
+ return true;
+}
+
+const struct ieee80211_ops rtl_ops = {
+ .start = rtl_op_start,
+ .stop = rtl_op_stop,
+ .tx = rtl_op_tx,
+ .add_interface = rtl_op_add_interface,
+ .remove_interface = rtl_op_remove_interface,
+ .change_interface = rtl_op_change_interface,
+#ifdef CONFIG_PM
+ .suspend = rtl_op_suspend,
+ .resume = rtl_op_resume,
+#endif
+ .config = rtl_op_config,
+ .configure_filter = rtl_op_configure_filter,
+ .set_key = rtl_op_set_key,
+ .sta_statistics = rtl_op_sta_statistics,
+ .set_frag_threshold = rtl_op_set_frag_threshold,
+ .conf_tx = rtl_op_conf_tx,
+ .bss_info_changed = rtl_op_bss_info_changed,
+ .get_tsf = rtl_op_get_tsf,
+ .set_tsf = rtl_op_set_tsf,
+ .reset_tsf = rtl_op_reset_tsf,
+ .sta_notify = rtl_op_sta_notify,
+ .ampdu_action = rtl_op_ampdu_action,
+ .sw_scan_start = rtl_op_sw_scan_start,
+ .sw_scan_complete = rtl_op_sw_scan_complete,
+ .rfkill_poll = rtl_op_rfkill_poll,
+ .sta_add = rtl_op_sta_add,
+ .sta_remove = rtl_op_sta_remove,
+ .flush = rtl_op_flush,
+};
+
+bool rtl_btc_status_false(void)
+{
+ return false;
+}
+
+void rtl_dm_diginit(struct ieee80211_hw *hw, u32 cur_igvalue)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
+
+ dm_digtable->dig_enable_flag = true;
+ dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
+ dm_digtable->cur_igvalue = cur_igvalue;
+ dm_digtable->pre_igvalue = 0;
+ dm_digtable->cur_sta_cstate = DIG_STA_DISCONNECT;
+ dm_digtable->presta_cstate = DIG_STA_DISCONNECT;
+ dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT;
+ dm_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW;
+ dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH;
+ dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
+ dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
+ dm_digtable->rx_gain_max = DM_DIG_MAX;
+ dm_digtable->rx_gain_min = DM_DIG_MIN;
+ dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
+ dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX;
+ dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN;
+ dm_digtable->pre_cck_cca_thres = 0xff;
+ dm_digtable->cur_cck_cca_thres = 0x83;
+ dm_digtable->forbidden_igi = DM_DIG_MIN;
+ dm_digtable->large_fa_hit = 0;
+ dm_digtable->recover_cnt = 0;
+ dm_digtable->dig_min_0 = 0x25;
+ dm_digtable->dig_min_1 = 0x25;
+ dm_digtable->media_connect_0 = false;
+ dm_digtable->media_connect_1 = false;
+ rtlpriv->dm.dm_initialgain_enable = true;
+ dm_digtable->bt30_cur_igi = 0x32;
+ dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX;
+ dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_LOWRSSI;
+}
diff --git a/drivers/staging/rtlwifi/core.h b/drivers/staging/rtlwifi/core.h
new file mode 100644
index 0000000..782ac2f
--- /dev/null
+++ b/drivers/staging/rtlwifi/core.h
@@ -0,0 +1,86 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2012 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL_CORE_H__
+#define __RTL_CORE_H__
+
+#define RTL_SUPPORTED_FILTERS \
+ (FIF_ALLMULTI | FIF_CONTROL | \
+ FIF_OTHER_BSS | \
+ FIF_FCSFAIL | \
+ FIF_BCN_PRBRESP_PROMISC)
+
+#define DM_DIG_THRESH_HIGH 40
+#define DM_DIG_THRESH_LOW 35
+#define DM_FALSEALARM_THRESH_LOW 400
+#define DM_FALSEALARM_THRESH_HIGH 1000
+
+#define DM_DIG_MAX 0x3e
+#define DM_DIG_MIN 0x1e
+#define DM_DIG_MAX_AP 0x32
+#define DM_DIG_BACKOFF_MAX 12
+#define DM_DIG_BACKOFF_MIN -4
+#define DM_DIG_BACKOFF_DEFAULT 10
+
+enum cck_packet_detection_threshold {
+ CCK_PD_STAGE_LOWRSSI = 0,
+ CCK_PD_STAGE_HIGHRSSI = 1,
+ CCK_FA_STAGE_LOW = 2,
+ CCK_FA_STAGE_HIGH = 3,
+ CCK_PD_STAGE_MAX = 4,
+};
+
+enum dm_dig_ext_port_alg_e {
+ DIG_EXT_PORT_STAGE_0 = 0,
+ DIG_EXT_PORT_STAGE_1 = 1,
+ DIG_EXT_PORT_STAGE_2 = 2,
+ DIG_EXT_PORT_STAGE_3 = 3,
+ DIG_EXT_PORT_STAGE_MAX = 4,
+};
+
+enum dm_dig_connect_e {
+ DIG_STA_DISCONNECT,
+ DIG_STA_CONNECT,
+ DIG_STA_BEFORE_CONNECT,
+ DIG_MULTISTA_DISCONNECT,
+ DIG_MULTISTA_CONNECT,
+ DIG_AP_DISCONNECT,
+ DIG_AP_CONNECT,
+ DIG_AP_ADD_STATION,
+ DIG_CONNECT_MAX
+};
+
+extern const struct ieee80211_ops rtl_ops;
+void rtl_fw_cb(const struct firmware *firmware, void *context);
+void rtl_wowlan_fw_cb(const struct firmware *firmware, void *context);
+void rtl_addr_delay(u32 addr);
+void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr,
+ u32 mask, u32 data);
+void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data);
+bool rtl_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb);
+bool rtl_btc_status_false(void);
+void rtl_dm_diginit(struct ieee80211_hw *hw, u32 cur_igval);
+
+#endif
diff --git a/drivers/staging/rtlwifi/debug.c b/drivers/staging/rtlwifi/debug.c
new file mode 100644
index 0000000..7446d71
--- /dev/null
+++ b/drivers/staging/rtlwifi/debug.c
@@ -0,0 +1,636 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2012 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *****************************************************************************/
+
+#include "wifi.h"
+#include "cam.h"
+
+#include <linux/moduleparam.h>
+#include <linux/vmalloc.h>
+
+#ifdef CONFIG_RTLWIFI_DEBUG_ST
+void _rtl_dbg_trace(struct rtl_priv *rtlpriv, u64 comp, int level,
+ const char *fmt, ...)
+{
+ if (unlikely((comp & rtlpriv->cfg->mod_params->debug_mask) &&
+ (level <= rtlpriv->cfg->mod_params->debug_level))) {
+ struct va_format vaf;
+ va_list args;
+
+ va_start(args, fmt);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ pr_info(":<%lx> %pV", in_interrupt(), &vaf);
+
+ va_end(args);
+ }
+}
+
+void _rtl_dbg_print(struct rtl_priv *rtlpriv, u64 comp, int level,
+ const char *fmt, ...)
+{
+ if (unlikely((comp & rtlpriv->cfg->mod_params->debug_mask) &&
+ (level <= rtlpriv->cfg->mod_params->debug_level))) {
+ struct va_format vaf;
+ va_list args;
+
+ va_start(args, fmt);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ pr_info("%pV", &vaf);
+
+ va_end(args);
+ }
+}
+
+void _rtl_dbg_print_data(struct rtl_priv *rtlpriv, u64 comp, int level,
+ const char *titlestring,
+ const void *hexdata, int hexdatalen)
+{
+ if (unlikely(((comp) & rtlpriv->cfg->mod_params->debug_mask) &&
+ ((level) <= rtlpriv->cfg->mod_params->debug_level))) {
+ pr_info("In process \"%s\" (pid %i): %s\n",
+ current->comm, current->pid, titlestring);
+ print_hex_dump_bytes("", DUMP_PREFIX_NONE,
+ hexdata, hexdatalen);
+ }
+}
+
+struct rtl_debugfs_priv {
+ struct rtl_priv *rtlpriv;
+ int (*cb_read)(struct seq_file *m, void *v);
+ ssize_t (*cb_write)(struct file *filp, const char __user *buffer,
+ size_t count, loff_t *loff);
+ u32 cb_data;
+};
+
+static struct dentry *debugfs_topdir;
+
+static int rtl_debug_get_common(struct seq_file *m, void *v)
+{
+ struct rtl_debugfs_priv *debugfs_priv = m->private;
+
+ return debugfs_priv->cb_read(m, v);
+}
+
+static int dl_debug_open_common(struct inode *inode, struct file *file)
+{
+ return single_open(file, rtl_debug_get_common, inode->i_private);
+}
+
+static const struct file_operations file_ops_common = {
+ .open = dl_debug_open_common,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static int rtl_debug_get_mac_page(struct seq_file *m, void *v)
+{
+ struct rtl_debugfs_priv *debugfs_priv = m->private;
+ struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
+ u32 page = debugfs_priv->cb_data;
+ int i, n;
+ int max = 0xff;
+
+ for (n = 0; n <= max; ) {
+ seq_printf(m, "\n%8.8x ", n + page);
+ for (i = 0; i < 4 && n <= max; i++, n += 4)
+ seq_printf(m, "%8.8x ",
+ rtl_read_dword(rtlpriv, (page | n)));
+ }
+ seq_puts(m, "\n");
+ return 0;
+}
+
+#define RTL_DEBUG_IMPL_MAC_SERIES(page, addr) \
+struct rtl_debugfs_priv rtl_debug_priv_mac_ ##page = { \
+ .cb_read = rtl_debug_get_mac_page, \
+ .cb_data = addr, \
+}
+
+RTL_DEBUG_IMPL_MAC_SERIES(0, 0x0000);
+RTL_DEBUG_IMPL_MAC_SERIES(1, 0x0100);
+RTL_DEBUG_IMPL_MAC_SERIES(2, 0x0200);
+RTL_DEBUG_IMPL_MAC_SERIES(3, 0x0300);
+RTL_DEBUG_IMPL_MAC_SERIES(4, 0x0400);
+RTL_DEBUG_IMPL_MAC_SERIES(5, 0x0500);
+RTL_DEBUG_IMPL_MAC_SERIES(6, 0x0600);
+RTL_DEBUG_IMPL_MAC_SERIES(7, 0x0700);
+RTL_DEBUG_IMPL_MAC_SERIES(10, 0x1000);
+RTL_DEBUG_IMPL_MAC_SERIES(11, 0x1100);
+RTL_DEBUG_IMPL_MAC_SERIES(12, 0x1200);
+RTL_DEBUG_IMPL_MAC_SERIES(13, 0x1300);
+RTL_DEBUG_IMPL_MAC_SERIES(14, 0x1400);
+RTL_DEBUG_IMPL_MAC_SERIES(15, 0x1500);
+RTL_DEBUG_IMPL_MAC_SERIES(16, 0x1600);
+RTL_DEBUG_IMPL_MAC_SERIES(17, 0x1700);
+
+static int rtl_debug_get_bb_page(struct seq_file *m, void *v)
+{
+ struct rtl_debugfs_priv *debugfs_priv = m->private;
+ struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
+ struct ieee80211_hw *hw = rtlpriv->hw;
+ u32 page = debugfs_priv->cb_data;
+ int i, n;
+ int max = 0xff;
+
+ for (n = 0; n <= max; ) {
+ seq_printf(m, "\n%8.8x ", n + page);
+ for (i = 0; i < 4 && n <= max; i++, n += 4)
+ seq_printf(m, "%8.8x ",
+ rtl_get_bbreg(hw, (page | n), 0xffffffff));
+ }
+ seq_puts(m, "\n");
+ return 0;
+}
+
+#define RTL_DEBUG_IMPL_BB_SERIES(page, addr) \
+struct rtl_debugfs_priv rtl_debug_priv_bb_ ##page = { \
+ .cb_read = rtl_debug_get_bb_page, \
+ .cb_data = addr, \
+}
+
+RTL_DEBUG_IMPL_BB_SERIES(8, 0x0800);
+RTL_DEBUG_IMPL_BB_SERIES(9, 0x0900);
+RTL_DEBUG_IMPL_BB_SERIES(a, 0x0a00);
+RTL_DEBUG_IMPL_BB_SERIES(b, 0x0b00);
+RTL_DEBUG_IMPL_BB_SERIES(c, 0x0c00);
+RTL_DEBUG_IMPL_BB_SERIES(d, 0x0d00);
+RTL_DEBUG_IMPL_BB_SERIES(e, 0x0e00);
+RTL_DEBUG_IMPL_BB_SERIES(f, 0x0f00);
+RTL_DEBUG_IMPL_BB_SERIES(18, 0x1800);
+RTL_DEBUG_IMPL_BB_SERIES(19, 0x1900);
+RTL_DEBUG_IMPL_BB_SERIES(1a, 0x1a00);
+RTL_DEBUG_IMPL_BB_SERIES(1b, 0x1b00);
+RTL_DEBUG_IMPL_BB_SERIES(1c, 0x1c00);
+RTL_DEBUG_IMPL_BB_SERIES(1d, 0x1d00);
+RTL_DEBUG_IMPL_BB_SERIES(1e, 0x1e00);
+RTL_DEBUG_IMPL_BB_SERIES(1f, 0x1f00);
+
+static int rtl_debug_get_reg_rf(struct seq_file *m, void *v)
+{
+ struct rtl_debugfs_priv *debugfs_priv = m->private;
+ struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
+ struct ieee80211_hw *hw = rtlpriv->hw;
+ enum radio_path rfpath = debugfs_priv->cb_data;
+ int i, n;
+ int max = 0x40;
+
+ if (IS_HARDWARE_TYPE_8822B(rtlpriv))
+ max = 0xff;
+
+ seq_printf(m, "\nPATH(%d)", rfpath);
+
+ for (n = 0; n <= max; ) {
+ seq_printf(m, "\n%8.8x ", n);
+ for (i = 0; i < 4 && n <= max; n += 1, i++)
+ seq_printf(m, "%8.8x ",
+ rtl_get_rfreg(hw, rfpath, n, 0xffffffff));
+ }
+ seq_puts(m, "\n");
+ return 0;
+}
+
+#define RTL_DEBUG_IMPL_RF_SERIES(page, addr) \
+struct rtl_debugfs_priv rtl_debug_priv_rf_ ##page = { \
+ .cb_read = rtl_debug_get_reg_rf, \
+ .cb_data = addr, \
+}
+
+RTL_DEBUG_IMPL_RF_SERIES(a, RF90_PATH_A);
+RTL_DEBUG_IMPL_RF_SERIES(b, RF90_PATH_B);
+
+static int rtl_debug_get_cam_register(struct seq_file *m, void *v)
+{
+ struct rtl_debugfs_priv *debugfs_priv = m->private;
+ struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
+ int start = debugfs_priv->cb_data;
+ u32 target_cmd = 0;
+ u32 target_val = 0;
+ u8 entry_i = 0;
+ u32 ulstatus;
+ int i = 100, j = 0;
+ int end = (start + 11 > TOTAL_CAM_ENTRY ? TOTAL_CAM_ENTRY : start + 11);
+
+ /* This dump the current register page */
+ seq_printf(m,
+ "\n#################### SECURITY CAM (%d-%d) ##################\n",
+ start, end - 1);
+
+ for (j = start; j < end; j++) {
+ seq_printf(m, "\nD: %2x > ", j);
+ for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
+ /* polling bit, and No Write enable, and address */
+ target_cmd = entry_i + CAM_CONTENT_COUNT * j;
+ target_cmd = target_cmd | BIT(31);
+
+ /* Check polling bit is clear */
+ while ((i--) >= 0) {
+ ulstatus = rtl_read_dword(
+ rtlpriv,
+ rtlpriv->cfg->maps[RWCAM]);
+ if (ulstatus & BIT(31))
+ continue;
+ else
+ break;
+ }
+
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
+ target_cmd);
+ target_val = rtl_read_dword(rtlpriv,
+ rtlpriv->cfg->maps[RCAMO]);
+ seq_printf(m, "%8.8x ", target_val);
+ }
+ }
+ seq_puts(m, "\n");
+ return 0;
+}
+
+#define RTL_DEBUG_IMPL_CAM_SERIES(page, addr) \
+struct rtl_debugfs_priv rtl_debug_priv_cam_ ##page = { \
+ .cb_read = rtl_debug_get_cam_register, \
+ .cb_data = addr, \
+}
+
+RTL_DEBUG_IMPL_CAM_SERIES(1, 0);
+RTL_DEBUG_IMPL_CAM_SERIES(2, 11);
+RTL_DEBUG_IMPL_CAM_SERIES(3, 22);
+
+static int rtl_debug_get_btcoex(struct seq_file *m, void *v)
+{
+ struct rtl_debugfs_priv *debugfs_priv = m->private;
+ struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
+
+ if (rtlpriv->cfg->ops->get_btc_status())
+ rtlpriv->btcoexist.btc_ops->btc_display_bt_coex_info(rtlpriv,
+ m);
+
+ seq_puts(m, "\n");
+
+ return 0;
+}
+
+static struct rtl_debugfs_priv rtl_debug_priv_btcoex = {
+ .cb_read = rtl_debug_get_btcoex,
+ .cb_data = 0,
+};
+
+static ssize_t rtl_debugfs_set_write_reg(struct file *filp,
+ const char __user *buffer,
+ size_t count, loff_t *loff)
+{
+ struct rtl_debugfs_priv *debugfs_priv = filp->private_data;
+ struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
+ char tmp[32 + 1];
+ int tmp_len;
+ u32 addr, val, len;
+ int num;
+
+ if (count < 3)
+ return -EFAULT;
+
+ tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
+
+ if (!buffer || copy_from_user(tmp, buffer, tmp_len))
+ return count;
+
+ tmp[tmp_len] = '\0';
+
+ /* write BB/MAC register */
+ num = sscanf(tmp, "%x %x %x", &addr, &val, &len);
+
+ if (num != 3)
+ return count;
+
+ switch (len) {
+ case 1:
+ rtl_write_byte(rtlpriv, addr, (u8)val);
+ break;
+ case 2:
+ rtl_write_word(rtlpriv, addr, (u16)val);
+ break;
+ case 4:
+ rtl_write_dword(rtlpriv, addr, val);
+ break;
+ default:
+ /*printk("error write length=%d", len);*/
+ break;
+ }
+
+ return count;
+}
+
+static struct rtl_debugfs_priv rtl_debug_priv_write_reg = {
+ .cb_write = rtl_debugfs_set_write_reg,
+};
+
+static ssize_t rtl_debugfs_set_write_h2c(struct file *filp,
+ const char __user *buffer,
+ size_t count, loff_t *loff)
+{
+ struct rtl_debugfs_priv *debugfs_priv = filp->private_data;
+ struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
+ struct ieee80211_hw *hw = rtlpriv->hw;
+ char tmp[32 + 1];
+ int tmp_len;
+ u8 h2c_len, h2c_data_packed[8];
+ int h2c_data[8]; /* idx 0: cmd */
+ int i;
+
+ if (count < 3)
+ return -EFAULT;
+
+ tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
+
+ if (!buffer || copy_from_user(tmp, buffer, tmp_len))
+ return count;
+
+ tmp[tmp_len] = '\0';
+
+ h2c_len = sscanf(tmp, "%X %X %X %X %X %X %X %X",
+ &h2c_data[0], &h2c_data[1],
+ &h2c_data[2], &h2c_data[3],
+ &h2c_data[4], &h2c_data[5],
+ &h2c_data[6], &h2c_data[7]);
+
+ if (h2c_len <= 0)
+ return count;
+
+ for (i = 0; i < h2c_len; i++)
+ h2c_data_packed[i] = (u8)h2c_data[i];
+
+ rtlpriv->cfg->ops->fill_h2c_cmd(hw, h2c_data_packed[0],
+ h2c_len - 1,
+ &h2c_data_packed[1]);
+
+ return count;
+}
+
+static struct rtl_debugfs_priv rtl_debug_priv_write_h2c = {
+ .cb_write = rtl_debugfs_set_write_h2c,
+};
+
+static ssize_t rtl_debugfs_set_write_rfreg(struct file *filp,
+ const char __user *buffer,
+ size_t count, loff_t *loff)
+{
+ struct rtl_debugfs_priv *debugfs_priv = filp->private_data;
+ struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
+ struct ieee80211_hw *hw = rtlpriv->hw;
+ char tmp[32 + 1];
+ int tmp_len;
+ int num;
+ int path;
+ u32 addr, bitmask, data;
+
+ if (count < 3)
+ return -EFAULT;
+
+ tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
+
+ if (!buffer || copy_from_user(tmp, buffer, tmp_len))
+ return count;
+
+ tmp[tmp_len] = '\0';
+
+ num = sscanf(tmp, "%X %X %X %X",
+ &path, &addr, &bitmask, &data);
+
+ if (num != 4) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
+ "Format is <path> <addr> <mask> <data>\n");
+ return count;
+ }
+
+ rtl_set_rfreg(hw, path, addr, bitmask, data);
+
+ return count;
+}
+
+static struct rtl_debugfs_priv rtl_debug_priv_write_rfreg = {
+ .cb_write = rtl_debugfs_set_write_rfreg,
+};
+
+static int rtl_debugfs_close(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+static ssize_t rtl_debugfs_common_write(struct file *filp,
+ const char __user *buffer,
+ size_t count, loff_t *loff)
+{
+ struct rtl_debugfs_priv *debugfs_priv = filp->private_data;
+
+ return debugfs_priv->cb_write(filp, buffer, count, loff);
+}
+
+static const struct file_operations file_ops_common_write = {
+ .owner = THIS_MODULE,
+ .write = rtl_debugfs_common_write,
+ .open = simple_open,
+ .release = rtl_debugfs_close,
+};
+
+static ssize_t rtl_debugfs_phydm_cmd(struct file *filp,
+ const char __user *buffer,
+ size_t count, loff_t *loff)
+{
+ struct rtl_debugfs_priv *debugfs_priv = filp->private_data;
+ struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
+
+ char tmp[64];
+
+ if (!rtlpriv->dbg.msg_buf)
+ return -ENOMEM;
+
+ if (!rtlpriv->phydm.ops)
+ return -EFAULT;
+
+ if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
+ tmp[count] = '\0';
+
+ rtlpriv->phydm.ops->phydm_debug_cmd(rtlpriv, tmp, count,
+ rtlpriv->dbg.msg_buf,
+ 80 * 25);
+ }
+
+ return count;
+}
+
+static int rtl_debug_get_phydm_cmd(struct seq_file *m, void *v)
+{
+ struct rtl_debugfs_priv *debugfs_priv = m->private;
+ struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
+
+ if (rtlpriv->dbg.msg_buf)
+ seq_puts(m, rtlpriv->dbg.msg_buf);
+
+ return 0;
+}
+
+static int rtl_debugfs_open_rw(struct inode *inode, struct file *filp)
+{
+ if (filp->f_mode & FMODE_READ)
+ single_open(filp, rtl_debug_get_common, inode->i_private);
+ else
+ filp->private_data = inode->i_private;
+
+ return 0;
+}
+
+static int rtl_debugfs_close_rw(struct inode *inode, struct file *filp)
+{
+ if (filp->f_mode == FMODE_READ)
+ seq_release(inode, filp);
+
+ return 0;
+}
+
+static struct rtl_debugfs_priv rtl_debug_priv_phydm_cmd = {
+ .cb_read = rtl_debug_get_phydm_cmd,
+ .cb_write = rtl_debugfs_phydm_cmd,
+ .cb_data = 0,
+};
+
+static const struct file_operations file_ops_common_rw = {
+ .owner = THIS_MODULE,
+ .open = rtl_debugfs_open_rw,
+ .release = rtl_debugfs_close_rw,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .write = rtl_debugfs_common_write,
+};
+
+#define RTL_DEBUGFS_ADD_CORE(name, mode, fopname) \
+ do { \
+ rtl_debug_priv_ ##name.rtlpriv = rtlpriv; \
+ if (!debugfs_create_file(#name, mode, \
+ parent, &rtl_debug_priv_ ##name, \
+ &file_ops_ ##fopname)) \
+ pr_err("Unable to initialize debugfs:%s/%s\n", \
+ rtlpriv->dbg.debugfs_name, \
+ #name); \
+ } while (0)
+
+#define RTL_DEBUGFS_ADD(name) \
+ RTL_DEBUGFS_ADD_CORE(name, S_IFREG | 0444, common)
+#define RTL_DEBUGFS_ADD_W(name) \
+ RTL_DEBUGFS_ADD_CORE(name, S_IFREG | 0222, common_write)
+#define RTL_DEBUGFS_ADD_RW(name) \
+ RTL_DEBUGFS_ADD_CORE(name, S_IFREG | 0666, common_rw)
+
+void rtl_debug_add_one(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ struct dentry *parent;
+
+ rtlpriv->dbg.msg_buf = vzalloc(80 * 25);
+
+ snprintf(rtlpriv->dbg.debugfs_name, 18, "%pMF", rtlefuse->dev_addr);
+
+ rtlpriv->dbg.debugfs_dir =
+ debugfs_create_dir(rtlpriv->dbg.debugfs_name, debugfs_topdir);
+ if (!rtlpriv->dbg.debugfs_dir) {
+ pr_err("Unable to init debugfs:/%s/%s\n", rtlpriv->cfg->name,
+ rtlpriv->dbg.debugfs_name);
+ return;
+ }
+
+ parent = rtlpriv->dbg.debugfs_dir;
+
+ RTL_DEBUGFS_ADD(mac_0);
+ RTL_DEBUGFS_ADD(mac_1);
+ RTL_DEBUGFS_ADD(mac_2);
+ RTL_DEBUGFS_ADD(mac_3);
+ RTL_DEBUGFS_ADD(mac_4);
+ RTL_DEBUGFS_ADD(mac_5);
+ RTL_DEBUGFS_ADD(mac_6);
+ RTL_DEBUGFS_ADD(mac_7);
+ RTL_DEBUGFS_ADD(bb_8);
+ RTL_DEBUGFS_ADD(bb_9);
+ RTL_DEBUGFS_ADD(bb_a);
+ RTL_DEBUGFS_ADD(bb_b);
+ RTL_DEBUGFS_ADD(bb_c);
+ RTL_DEBUGFS_ADD(bb_d);
+ RTL_DEBUGFS_ADD(bb_e);
+ RTL_DEBUGFS_ADD(bb_f);
+ RTL_DEBUGFS_ADD(mac_10);
+ RTL_DEBUGFS_ADD(mac_11);
+ RTL_DEBUGFS_ADD(mac_12);
+ RTL_DEBUGFS_ADD(mac_13);
+ RTL_DEBUGFS_ADD(mac_14);
+ RTL_DEBUGFS_ADD(mac_15);
+ RTL_DEBUGFS_ADD(mac_16);
+ RTL_DEBUGFS_ADD(mac_17);
+ RTL_DEBUGFS_ADD(bb_18);
+ RTL_DEBUGFS_ADD(bb_19);
+ RTL_DEBUGFS_ADD(bb_1a);
+ RTL_DEBUGFS_ADD(bb_1b);
+ RTL_DEBUGFS_ADD(bb_1c);
+ RTL_DEBUGFS_ADD(bb_1d);
+ RTL_DEBUGFS_ADD(bb_1e);
+ RTL_DEBUGFS_ADD(bb_1f);
+ RTL_DEBUGFS_ADD(rf_a);
+ RTL_DEBUGFS_ADD(rf_b);
+
+ RTL_DEBUGFS_ADD(cam_1);
+ RTL_DEBUGFS_ADD(cam_2);
+ RTL_DEBUGFS_ADD(cam_3);
+
+ RTL_DEBUGFS_ADD(btcoex);
+
+ RTL_DEBUGFS_ADD_W(write_reg);
+ RTL_DEBUGFS_ADD_W(write_h2c);
+ RTL_DEBUGFS_ADD_W(write_rfreg);
+
+ RTL_DEBUGFS_ADD_RW(phydm_cmd);
+}
+
+void rtl_debug_remove_one(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ debugfs_remove_recursive(rtlpriv->dbg.debugfs_dir);
+ rtlpriv->dbg.debugfs_dir = NULL;
+
+ vfree(rtlpriv->dbg.msg_buf);
+}
+
+void rtl_debugfs_add_topdir(void)
+{
+ debugfs_topdir = debugfs_create_dir("rtlwifi", NULL);
+}
+
+void rtl_debugfs_remove_topdir(void)
+{
+ debugfs_remove_recursive(debugfs_topdir);
+}
+
+#endif
diff --git a/drivers/staging/rtlwifi/debug.h b/drivers/staging/rtlwifi/debug.h
new file mode 100644
index 0000000..ac942477
--- /dev/null
+++ b/drivers/staging/rtlwifi/debug.h
@@ -0,0 +1,234 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2012 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *****************************************************************************/
+
+#ifndef __RTL_DEBUG_H__
+#define __RTL_DEBUG_H__
+
+/*--------------------------------------------------------------
+ * Debug level
+ *------------------------------------------------------------
+ *
+ *Fatal bug.
+ *For example, Tx/Rx/IO locked up,
+ *memory access violation,
+ *resource allocation failed,
+ *unexpected HW behavior, HW BUG
+ *and so on.
+ */
+/*#define DBG_EMERG 0 */
+
+/*Abnormal, rare, or unexpected cases.
+ *For example, Packet/IO Ctl canceled,
+ *device surprisingly removed and so on.
+ */
+#define DBG_WARNING 2
+
+/*Normal case driver developer should
+ *open, we can see link status like
+ *assoc/AddBA/DHCP/adapter start and
+ *so on basic and useful infromations.
+ */
+#define DBG_DMESG 3
+
+/*Normal case with useful information
+ *about current SW or HW state.
+ *For example, Tx/Rx descriptor to fill,
+ *Tx/Rx descriptor completed status,
+ *SW protocol state change, dynamic
+ *mechanism state change and so on.
+ */
+#define DBG_LOUD 4
+
+/*Normal case with detail execution
+ *flow or information.
+ */
+#define DBG_TRACE 5
+
+/*--------------------------------------------------------------
+ * Define the rt_trace components
+ *--------------------------------------------------------------
+ */
+#define COMP_ERR BIT(0)
+#define COMP_FW BIT(1)
+#define COMP_INIT BIT(2) /*For init/deinit */
+#define COMP_RECV BIT(3) /*For Rx. */
+#define COMP_SEND BIT(4) /*For Tx. */
+#define COMP_MLME BIT(5) /*For MLME. */
+#define COMP_SCAN BIT(6) /*For Scan. */
+#define COMP_INTR BIT(7) /*For interrupt Related. */
+#define COMP_LED BIT(8) /*For LED. */
+#define COMP_SEC BIT(9) /*For sec. */
+#define COMP_BEACON BIT(10) /*For beacon. */
+#define COMP_RATE BIT(11) /*For rate. */
+#define COMP_RXDESC BIT(12) /*For rx desc. */
+#define COMP_DIG BIT(13) /*For DIG */
+#define COMP_TXAGC BIT(14) /*For Tx power */
+#define COMP_HIPWR BIT(15) /*For High Power Mechanism */
+#define COMP_POWER BIT(16) /*For lps/ips/aspm. */
+#define COMP_POWER_TRACKING BIT(17) /*For TX POWER TRACKING */
+#define COMP_BB_POWERSAVING BIT(18)
+#define COMP_SWAS BIT(19) /*For SW Antenna Switch */
+#define COMP_RF BIT(20) /*For RF. */
+#define COMP_TURBO BIT(21) /*For EDCA TURBO. */
+#define COMP_RATR BIT(22)
+#define COMP_CMD BIT(23)
+#define COMP_EFUSE BIT(24)
+#define COMP_QOS BIT(25)
+#define COMP_MAC80211 BIT(26)
+#define COMP_REGD BIT(27)
+#define COMP_CHAN BIT(28)
+#define COMP_USB BIT(29)
+#define COMP_EASY_CONCURRENT COMP_USB /* reuse of this bit is OK */
+#define COMP_BT_COEXIST BIT(30)
+#define COMP_IQK BIT(31)
+#define COMP_TX_REPORT BIT_ULL(32)
+#define COMP_HALMAC BIT_ULL(34)
+#define COMP_PHYDM BIT_ULL(35)
+
+/*--------------------------------------------------------------
+ * Define the rt_print components
+ *--------------------------------------------------------------
+ */
+/* Define EEPROM and EFUSE check module bit*/
+#define EEPROM_W BIT(0)
+#define EFUSE_PG BIT(1)
+#define EFUSE_READ_ALL BIT(2)
+
+/* Define init check for module bit*/
+#define INIT_EEPROM BIT(0)
+#define INIT_TXPOWER BIT(1)
+#define INIT_IQK BIT(2)
+#define INIT_RF BIT(3)
+
+/* Define PHY-BB/RF/MAC check module bit */
+#define PHY_BBR BIT(0)
+#define PHY_BBW BIT(1)
+#define PHY_RFR BIT(2)
+#define PHY_RFW BIT(3)
+#define PHY_MACR BIT(4)
+#define PHY_MACW BIT(5)
+#define PHY_ALLR BIT(6)
+#define PHY_ALLW BIT(7)
+#define PHY_TXPWR BIT(8)
+#define PHY_PWRDIFF BIT(9)
+
+/* Define Dynamic Mechanism check module bit --> FDM */
+#define WA_IOT BIT(0)
+#define DM_PWDB BIT(1)
+#define DM_MONITOR BIT(2)
+#define DM_DIG BIT(3)
+#define DM_EDCA_TURBO BIT(4)
+
+#define DM_PWDB BIT(1)
+
+enum dbgp_flag_e {
+ FQOS = 0,
+ FTX = 1,
+ FRX = 2,
+ FSEC = 3,
+ FMGNT = 4,
+ FMLME = 5,
+ FRESOURCE = 6,
+ FBEACON = 7,
+ FISR = 8,
+ FPHY = 9,
+ FMP = 10,
+ FEEPROM = 11,
+ FPWR = 12,
+ FDM = 13,
+ FDBGCTRL = 14,
+ FC2H = 15,
+ FBT = 16,
+ FINIT = 17,
+ FIOCTL = 18,
+ DBGP_TYPE_MAX
+};
+
+#ifdef CONFIG_RTLWIFI_DEBUG_ST
+
+struct rtl_priv;
+
+__printf(4, 5)
+void _rtl_dbg_trace(struct rtl_priv *rtlpriv, u64 comp, int level,
+ const char *fmt, ...);
+
+__printf(4, 5)
+void _rtl_dbg_print(struct rtl_priv *rtlpriv, u64 comp, int level,
+ const char *fmt, ...);
+
+void _rtl_dbg_print_data(struct rtl_priv *rtlpriv, u64 comp, int level,
+ const char *titlestring,
+ const void *hexdata, int hexdatalen);
+
+#define RT_TRACE(rtlpriv, comp, level, fmt, ...) \
+ _rtl_dbg_trace(rtlpriv, comp, level, \
+ fmt, ##__VA_ARGS__)
+
+#define RTPRINT(rtlpriv, dbgtype, dbgflag, fmt, ...) \
+ _rtl_dbg_print(rtlpriv, dbgtype, dbgflag, fmt, ##__VA_ARGS__)
+
+#define RT_PRINT_DATA(rtlpriv, _comp, _level, _titlestring, _hexdata, \
+ _hexdatalen) \
+ _rtl_dbg_print_data(rtlpriv, _comp, _level, \
+ _titlestring, _hexdata, _hexdatalen)
+
+#else
+
+struct rtl_priv;
+
+__printf(4, 5)
+static inline void RT_TRACE(struct rtl_priv *rtlpriv,
+ u64 comp, int level,
+ const char *fmt, ...)
+{
+}
+
+__printf(4, 5)
+static inline void RTPRINT(struct rtl_priv *rtlpriv,
+ int dbgtype, int dbgflag,
+ const char *fmt, ...)
+{
+}
+
+static inline void RT_PRINT_DATA(struct rtl_priv *rtlpriv,
+ u64 comp, int level,
+ const char *titlestring,
+ const void *hexdata, size_t hexdatalen)
+{
+}
+
+#endif
+
+#ifdef CONFIG_RTLWIFI_DEBUG_ST
+void rtl_debug_add_one(struct ieee80211_hw *hw);
+void rtl_debug_remove_one(struct ieee80211_hw *hw);
+void rtl_debugfs_add_topdir(void);
+void rtl_debugfs_remove_topdir(void);
+#else
+#define rtl_debug_add_one(hw)
+#define rtl_debug_remove_one(hw)
+#define rtl_debugfs_add_topdir()
+#define rtl_debugfs_remove_topdir()
+#endif
+#endif
diff --git a/drivers/staging/rtlwifi/efuse.c b/drivers/staging/rtlwifi/efuse.c
new file mode 100644
index 0000000..6d5e657
--- /dev/null
+++ b/drivers/staging/rtlwifi/efuse.c
@@ -0,0 +1,1342 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2012 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#include "wifi.h"
+#include "efuse.h"
+#include "pci.h"
+#include <linux/export.h>
+
+static const u8 MAX_PGPKT_SIZE = 9;
+static const u8 PGPKT_DATA_SIZE = 8;
+static const int EFUSE_MAX_SIZE = 512;
+
+#define START_ADDRESS 0x1000
+#define REG_MCUFWDL 0x0080
+
+static const struct efuse_map RTL8712_SDIO_EFUSE_TABLE[] = {
+ {0, 0, 0, 2},
+ {0, 1, 0, 2},
+ {0, 2, 0, 2},
+ {1, 0, 0, 1},
+ {1, 0, 1, 1},
+ {1, 1, 0, 1},
+ {1, 1, 1, 3},
+ {1, 3, 0, 17},
+ {3, 3, 1, 48},
+ {10, 0, 0, 6},
+ {10, 3, 0, 1},
+ {10, 3, 1, 1},
+ {11, 0, 0, 28}
+};
+
+static void efuse_shadow_read_1byte(struct ieee80211_hw *hw, u16 offset,
+ u8 *value);
+static void efuse_shadow_read_2byte(struct ieee80211_hw *hw, u16 offset,
+ u16 *value);
+static void efuse_shadow_read_4byte(struct ieee80211_hw *hw, u16 offset,
+ u32 *value);
+static void efuse_shadow_write_1byte(struct ieee80211_hw *hw, u16 offset,
+ u8 value);
+static void efuse_shadow_write_2byte(struct ieee80211_hw *hw, u16 offset,
+ u16 value);
+static void efuse_shadow_write_4byte(struct ieee80211_hw *hw, u16 offset,
+ u32 value);
+static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr,
+ u8 data);
+static void efuse_read_all_map(struct ieee80211_hw *hw, u8 *efuse);
+static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset,
+ u8 *data);
+static int efuse_pg_packet_write(struct ieee80211_hw *hw, u8 offset,
+ u8 word_en, u8 *data);
+static void efuse_word_enable_data_read(u8 word_en, u8 *sourdata,
+ u8 *targetdata);
+static u8 enable_efuse_data_write(struct ieee80211_hw *hw,
+ u16 efuse_addr, u8 word_en, u8 *data);
+static u16 efuse_get_current_size(struct ieee80211_hw *hw);
+static u8 efuse_calculate_word_cnts(u8 word_en);
+
+void efuse_initialize(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 bytetemp;
+ u8 temp;
+
+ bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN] + 1);
+ temp = bytetemp | 0x20;
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN] + 1, temp);
+
+ bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[SYS_ISO_CTRL] + 1);
+ temp = bytetemp & 0xFE;
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_ISO_CTRL] + 1, temp);
+
+ bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3);
+ temp = bytetemp | 0x80;
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3, temp);
+
+ rtl_write_byte(rtlpriv, 0x2F8, 0x3);
+
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0x72);
+}
+
+u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 data;
+ u8 bytetemp;
+ u8 temp;
+ u32 k = 0;
+ const u32 efuse_len =
+ rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
+
+ if (address < efuse_len) {
+ temp = address & 0xFF;
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
+ temp);
+ bytetemp = rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
+ temp = ((address >> 8) & 0x03) | (bytetemp & 0xFC);
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
+ temp);
+
+ bytetemp = rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
+ temp = bytetemp & 0x7F;
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3,
+ temp);
+
+ bytetemp = rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
+ while (!(bytetemp & 0x80)) {
+ bytetemp =
+ rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
+ k++;
+ if (k == 1000) {
+ k = 0;
+ break;
+ }
+ }
+ data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
+ return data;
+ }
+ return 0xFF;
+}
+
+void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 bytetemp;
+ u8 temp;
+ u32 k = 0;
+ const u32 efuse_len =
+ rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
+
+ RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "Addr=%x Data =%x\n",
+ address, value);
+
+ if (address < efuse_len) {
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], value);
+
+ temp = address & 0xFF;
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
+ temp);
+ bytetemp = rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
+
+ temp = ((address >> 8) & 0x03) | (bytetemp & 0xFC);
+ rtl_write_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] + 2, temp);
+
+ bytetemp = rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
+ temp = bytetemp | 0x80;
+ rtl_write_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] + 3, temp);
+
+ bytetemp = rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
+
+ while (bytetemp & 0x80) {
+ bytetemp =
+ rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
+ k++;
+ if (k == 100) {
+ k = 0;
+ break;
+ }
+ }
+ }
+}
+
+void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 value32;
+ u8 readbyte;
+ u16 retry;
+
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
+ (_offset & 0xff));
+ readbyte = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
+ ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
+
+ readbyte = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3,
+ (readbyte & 0x7f));
+
+ retry = 0;
+ value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
+ while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < 10000)) {
+ value32 = rtl_read_dword(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL]);
+ retry++;
+ }
+
+ udelay(50);
+ value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
+
+ *pbuf = (u8)(value32 & 0xff);
+}
+
+void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u8 *efuse_tbl;
+ u8 rtemp8[1];
+ u16 efuse_addr = 0;
+ u8 offset, wren;
+ u8 u1temp = 0;
+ u16 i;
+ u16 j;
+ const u16 efuse_max_section =
+ rtlpriv->cfg->maps[EFUSE_MAX_SECTION_MAP];
+ const u32 efuse_len =
+ rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
+ u16 **efuse_word;
+ u16 efuse_utilized = 0;
+ u8 efuse_usage;
+
+ if ((_offset + _size_byte) > rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]) {
+ RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
+ "%s(): Invalid offset(%#x) with read bytes(%#x)!!\n",
+ __func__, _offset, _size_byte);
+ return;
+ }
+
+ /* allocate memory for efuse_tbl and efuse_word */
+ efuse_tbl = kzalloc(rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE] *
+ sizeof(u8), GFP_ATOMIC);
+ if (!efuse_tbl)
+ return;
+ efuse_word = kzalloc(EFUSE_MAX_WORD_UNIT * sizeof(u16 *), GFP_ATOMIC);
+ if (!efuse_word)
+ goto out;
+ for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
+ efuse_word[i] = kzalloc(efuse_max_section * sizeof(u16),
+ GFP_ATOMIC);
+ if (!efuse_word[i])
+ goto done;
+ }
+
+ for (i = 0; i < efuse_max_section; i++)
+ for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
+ efuse_word[j][i] = 0xFFFF;
+
+ read_efuse_byte(hw, efuse_addr, rtemp8);
+ if (*rtemp8 != 0xFF) {
+ efuse_utilized++;
+ RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
+ "Addr=%d\n", efuse_addr);
+ efuse_addr++;
+ }
+
+ while ((*rtemp8 != 0xFF) && (efuse_addr < efuse_len)) {
+ /* Check PG header for section num. */
+ if ((*rtemp8 & 0x1F) == 0x0F) {/* extended header */
+ u1temp = ((*rtemp8 & 0xE0) >> 5);
+ read_efuse_byte(hw, efuse_addr, rtemp8);
+
+ if ((*rtemp8 & 0x0F) == 0x0F) {
+ efuse_addr++;
+ read_efuse_byte(hw, efuse_addr, rtemp8);
+
+ if (*rtemp8 != 0xFF &&
+ (efuse_addr < efuse_len)) {
+ efuse_addr++;
+ }
+ continue;
+ } else {
+ offset = ((*rtemp8 & 0xF0) >> 1) | u1temp;
+ wren = (*rtemp8 & 0x0F);
+ efuse_addr++;
+ }
+ } else {
+ offset = ((*rtemp8 >> 4) & 0x0f);
+ wren = (*rtemp8 & 0x0f);
+ }
+
+ if (offset < efuse_max_section) {
+ RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
+ "offset-%d Worden=%x\n", offset, wren);
+
+ for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
+ if (!(wren & 0x01)) {
+ RTPRINT(rtlpriv, FEEPROM,
+ EFUSE_READ_ALL,
+ "Addr=%d\n", efuse_addr);
+
+ read_efuse_byte(hw, efuse_addr, rtemp8);
+ efuse_addr++;
+ efuse_utilized++;
+ efuse_word[i][offset] =
+ (*rtemp8 & 0xff);
+
+ if (efuse_addr >= efuse_len)
+ break;
+
+ RTPRINT(rtlpriv, FEEPROM,
+ EFUSE_READ_ALL,
+ "Addr=%d\n", efuse_addr);
+
+ read_efuse_byte(hw, efuse_addr, rtemp8);
+ efuse_addr++;
+ efuse_utilized++;
+ efuse_word[i][offset] |=
+ (((u16)*rtemp8 << 8) & 0xff00);
+
+ if (efuse_addr >= efuse_len)
+ break;
+ }
+
+ wren >>= 1;
+ }
+ }
+
+ RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
+ "Addr=%d\n", efuse_addr);
+ read_efuse_byte(hw, efuse_addr, rtemp8);
+ if (*rtemp8 != 0xFF && (efuse_addr < efuse_len)) {
+ efuse_utilized++;
+ efuse_addr++;
+ }
+ }
+
+ for (i = 0; i < efuse_max_section; i++) {
+ for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
+ efuse_tbl[(i * 8) + (j * 2)] =
+ (efuse_word[j][i] & 0xff);
+ efuse_tbl[(i * 8) + ((j * 2) + 1)] =
+ ((efuse_word[j][i] >> 8) & 0xff);
+ }
+ }
+
+ for (i = 0; i < _size_byte; i++)
+ pbuf[i] = efuse_tbl[_offset + i];
+
+ rtlefuse->efuse_usedbytes = efuse_utilized;
+ efuse_usage = (u8)((efuse_utilized * 100) / efuse_len);
+ rtlefuse->efuse_usedpercentage = efuse_usage;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_BYTES,
+ (u8 *)&efuse_utilized);
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_USAGE,
+ &efuse_usage);
+done:
+ for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++)
+ kfree(efuse_word[i]);
+ kfree(efuse_word);
+out:
+ kfree(efuse_tbl);
+}
+
+bool efuse_shadow_update_chk(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u8 section_idx, i, base;
+ u16 words_need = 0, hdr_num = 0, totalbytes, efuse_used;
+ bool wordchanged, result = true;
+
+ for (section_idx = 0; section_idx < 16; section_idx++) {
+ base = section_idx * 8;
+ wordchanged = false;
+
+ for (i = 0; i < 8; i = i + 2) {
+ if ((rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] !=
+ rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i]) ||
+ (rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i + 1] !=
+ rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i +
+ 1])) {
+ words_need++;
+ wordchanged = true;
+ }
+ }
+
+ if (wordchanged)
+ hdr_num++;
+ }
+
+ totalbytes = hdr_num + words_need * 2;
+ efuse_used = rtlefuse->efuse_usedbytes;
+
+ if ((totalbytes + efuse_used) >=
+ (EFUSE_MAX_SIZE - rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN]))
+ result = false;
+
+ RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
+ "%s(): totalbytes(%#x), hdr_num(%#x), words_need(%#x), efuse_used(%d)\n",
+ __func__, totalbytes, hdr_num, words_need, efuse_used);
+
+ return result;
+}
+
+void efuse_shadow_read(struct ieee80211_hw *hw, u8 type,
+ u16 offset, u32 *value)
+{
+ if (type == 1)
+ efuse_shadow_read_1byte(hw, offset, (u8 *)value);
+ else if (type == 2)
+ efuse_shadow_read_2byte(hw, offset, (u16 *)value);
+ else if (type == 4)
+ efuse_shadow_read_4byte(hw, offset, value);
+}
+
+void efuse_shadow_write(struct ieee80211_hw *hw, u8 type, u16 offset,
+ u32 value)
+{
+ if (type == 1)
+ efuse_shadow_write_1byte(hw, offset, (u8)value);
+ else if (type == 2)
+ efuse_shadow_write_2byte(hw, offset, (u16)value);
+ else if (type == 4)
+ efuse_shadow_write_4byte(hw, offset, value);
+}
+
+bool efuse_shadow_update(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u16 i, offset, base;
+ u8 word_en = 0x0F;
+ u8 first_pg = false;
+
+ RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "\n");
+
+ if (!efuse_shadow_update_chk(hw)) {
+ efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
+ memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
+ &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
+ rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
+
+ RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
+ "efuse out of capacity!!\n");
+ return false;
+ }
+ efuse_power_switch(hw, true, true);
+
+ for (offset = 0; offset < 16; offset++) {
+ word_en = 0x0F;
+ base = offset * 8;
+
+ for (i = 0; i < 8; i++) {
+ if (first_pg) {
+ word_en &= ~(BIT(i / 2));
+
+ rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] =
+ rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i];
+ } else {
+ if (rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] !=
+ rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i]) {
+ word_en &= ~(BIT(i / 2));
+
+ rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] =
+ rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i];
+ }
+ }
+ }
+ if (word_en != 0x0F) {
+ u8 tmpdata[8];
+
+ memcpy(tmpdata,
+ &rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base],
+ 8);
+ RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD,
+ "U-efuse\n", tmpdata, 8);
+
+ if (!efuse_pg_packet_write(hw, (u8)offset, word_en,
+ tmpdata)) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ "PG section(%#x) fail!!\n", offset);
+ break;
+ }
+ }
+ }
+
+ efuse_power_switch(hw, true, false);
+ efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
+
+ memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
+ &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
+ rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
+
+ RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "\n");
+ return true;
+}
+
+void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+
+ if (rtlefuse->autoload_failflag)
+ memset((&rtlefuse->efuse_map[EFUSE_INIT_MAP][0]),
+ 0xFF, rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
+ else
+ efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
+
+ memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
+ &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
+ rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
+}
+
+void efuse_force_write_vendor_id(struct ieee80211_hw *hw)
+{
+ u8 tmpdata[8] = { 0xFF, 0xFF, 0xEC, 0x10, 0xFF, 0xFF, 0xFF, 0xFF };
+
+ efuse_power_switch(hw, true, true);
+
+ efuse_pg_packet_write(hw, 1, 0xD, tmpdata);
+
+ efuse_power_switch(hw, true, false);
+}
+
+void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx)
+{
+}
+
+static void efuse_shadow_read_1byte(struct ieee80211_hw *hw,
+ u16 offset, u8 *value)
+{
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset];
+}
+
+static void efuse_shadow_read_2byte(struct ieee80211_hw *hw,
+ u16 offset, u16 *value)
+{
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+
+ *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset];
+ *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] << 8;
+}
+
+static void efuse_shadow_read_4byte(struct ieee80211_hw *hw,
+ u16 offset, u32 *value)
+{
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+
+ *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset];
+ *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] << 8;
+ *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 2] << 16;
+ *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 3] << 24;
+}
+
+static void efuse_shadow_write_1byte(struct ieee80211_hw *hw,
+ u16 offset, u8 value)
+{
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+
+ rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] = value;
+}
+
+static void efuse_shadow_write_2byte(struct ieee80211_hw *hw,
+ u16 offset, u16 value)
+{
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+
+ rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] = value & 0x00FF;
+ rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] = value >> 8;
+}
+
+static void efuse_shadow_write_4byte(struct ieee80211_hw *hw,
+ u16 offset, u32 value)
+{
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+
+ rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] =
+ (u8)(value & 0x000000FF);
+ rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] =
+ (u8)((value >> 8) & 0x0000FF);
+ rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 2] =
+ (u8)((value >> 16) & 0x00FF);
+ rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 3] =
+ (u8)((value >> 24) & 0xFF);
+}
+
+int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, u8 *data)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 tmpidx = 0;
+ int result;
+
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
+ (u8)(addr & 0xff));
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
+ ((u8)((addr >> 8) & 0x03)) |
+ (rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] + 2) &
+ 0xFC));
+
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0x72);
+
+ while (!(0x80 & rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] + 3)) &&
+ (tmpidx < 100)) {
+ tmpidx++;
+ }
+
+ if (tmpidx < 100) {
+ *data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
+ result = true;
+ } else {
+ *data = 0xff;
+ result = false;
+ }
+ return result;
+}
+
+static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 tmpidx = 0;
+
+ RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
+ "Addr = %x Data=%x\n", addr, data);
+
+ rtl_write_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] + 1, (u8)(addr & 0xff));
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
+ (rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] +
+ 2) & 0xFC) | (u8)((addr >> 8) & 0x03));
+
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], data);
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0xF2);
+
+ while ((0x80 &
+ rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3)) &&
+ (tmpidx < 100)) {
+ tmpidx++;
+ }
+
+ if (tmpidx < 100)
+ return true;
+ return false;
+}
+
+static void efuse_read_all_map(struct ieee80211_hw *hw, u8 *efuse)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ efuse_power_switch(hw, false, true);
+ read_efuse(hw, 0, rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE], efuse);
+ efuse_power_switch(hw, false, false);
+}
+
+static void efuse_read_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
+ u8 efuse_data, u8 offset, u8 *tmpdata,
+ u8 *readstate)
+{
+ bool dataempty = true;
+ u8 hoffset;
+ u8 tmpidx;
+ u8 hworden;
+ u8 word_cnts;
+
+ hoffset = (efuse_data >> 4) & 0x0F;
+ hworden = efuse_data & 0x0F;
+ word_cnts = efuse_calculate_word_cnts(hworden);
+
+ if (hoffset == offset) {
+ for (tmpidx = 0; tmpidx < word_cnts * 2; tmpidx++) {
+ if (efuse_one_byte_read(hw, *efuse_addr + 1 + tmpidx,
+ &efuse_data)) {
+ tmpdata[tmpidx] = efuse_data;
+ if (efuse_data != 0xff)
+ dataempty = false;
+ }
+ }
+
+ if (!dataempty) {
+ *readstate = PG_STATE_DATA;
+ } else {
+ *efuse_addr = *efuse_addr + (word_cnts * 2) + 1;
+ *readstate = PG_STATE_HEADER;
+ }
+
+ } else {
+ *efuse_addr = *efuse_addr + (word_cnts * 2) + 1;
+ *readstate = PG_STATE_HEADER;
+ }
+}
+
+static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data)
+{
+ u8 readstate = PG_STATE_HEADER;
+
+ bool continual = true;
+
+ u8 efuse_data, word_cnts = 0;
+ u16 efuse_addr = 0;
+ u8 tmpdata[8];
+
+ if (!data)
+ return false;
+ if (offset > 15)
+ return false;
+
+ memset(data, 0xff, PGPKT_DATA_SIZE * sizeof(u8));
+ memset(tmpdata, 0xff, PGPKT_DATA_SIZE * sizeof(u8));
+
+ while (continual && (efuse_addr < EFUSE_MAX_SIZE)) {
+ if (readstate & PG_STATE_HEADER) {
+ if (efuse_one_byte_read(hw, efuse_addr, &efuse_data) &&
+ (efuse_data != 0xFF))
+ efuse_read_data_case1(hw, &efuse_addr,
+ efuse_data, offset,
+ tmpdata, &readstate);
+ else
+ continual = false;
+ } else if (readstate & PG_STATE_DATA) {
+ efuse_word_enable_data_read(0, tmpdata, data);
+ efuse_addr = efuse_addr + (word_cnts * 2) + 1;
+ readstate = PG_STATE_HEADER;
+ }
+ }
+
+ if ((data[0] == 0xff) && (data[1] == 0xff) &&
+ (data[2] == 0xff) && (data[3] == 0xff) &&
+ (data[4] == 0xff) && (data[5] == 0xff) &&
+ (data[6] == 0xff) && (data[7] == 0xff))
+ return false;
+ return true;
+}
+
+static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
+ u8 efuse_data, u8 offset,
+ int *continual, u8 *write_state,
+ struct pgpkt_struct *target_pkt,
+ int *repeat_times, int *result, u8 word_en)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct pgpkt_struct tmp_pkt;
+ int dataempty = true;
+ u8 originaldata[8 * sizeof(u8)];
+ u8 badworden = 0x0F;
+ u8 match_word_en, tmp_word_en;
+ u8 tmpindex;
+ u8 tmp_header = efuse_data;
+ u8 tmp_word_cnts;
+
+ tmp_pkt.offset = (tmp_header >> 4) & 0x0F;
+ tmp_pkt.word_en = tmp_header & 0x0F;
+ tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en);
+
+ if (tmp_pkt.offset != target_pkt->offset) {
+ *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
+ *write_state = PG_STATE_HEADER;
+ } else {
+ for (tmpindex = 0; tmpindex < (tmp_word_cnts * 2); tmpindex++) {
+ if (efuse_one_byte_read(hw,
+ (*efuse_addr + 1 + tmpindex),
+ &efuse_data) &&
+ (efuse_data != 0xFF))
+ dataempty = false;
+ }
+
+ if (!dataempty) {
+ *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
+ *write_state = PG_STATE_HEADER;
+ } else {
+ match_word_en = 0x0F;
+ if (!((target_pkt->word_en & BIT(0)) |
+ (tmp_pkt.word_en & BIT(0))))
+ match_word_en &= (~BIT(0));
+
+ if (!((target_pkt->word_en & BIT(1)) |
+ (tmp_pkt.word_en & BIT(1))))
+ match_word_en &= (~BIT(1));
+
+ if (!((target_pkt->word_en & BIT(2)) |
+ (tmp_pkt.word_en & BIT(2))))
+ match_word_en &= (~BIT(2));
+
+ if (!((target_pkt->word_en & BIT(3)) |
+ (tmp_pkt.word_en & BIT(3))))
+ match_word_en &= (~BIT(3));
+
+ if ((match_word_en & 0x0F) != 0x0F) {
+ badworden =
+ enable_efuse_data_write(hw,
+ *efuse_addr + 1,
+ tmp_pkt.word_en,
+ target_pkt->data);
+
+ if (0x0F != (badworden & 0x0F)) {
+ u8 reorg_offset = offset;
+ u8 reorg_worden = badworden;
+
+ efuse_pg_packet_write(hw, reorg_offset,
+ reorg_worden,
+ originaldata);
+ }
+
+ tmp_word_en = 0x0F;
+ if ((target_pkt->word_en & BIT(0)) ^
+ (match_word_en & BIT(0)))
+ tmp_word_en &= (~BIT(0));
+
+ if ((target_pkt->word_en & BIT(1)) ^
+ (match_word_en & BIT(1)))
+ tmp_word_en &= (~BIT(1));
+
+ if ((target_pkt->word_en & BIT(2)) ^
+ (match_word_en & BIT(2)))
+ tmp_word_en &= (~BIT(2));
+
+ if ((target_pkt->word_en & BIT(3)) ^
+ (match_word_en & BIT(3)))
+ tmp_word_en &= (~BIT(3));
+
+ if ((tmp_word_en & 0x0F) != 0x0F) {
+ *efuse_addr =
+ efuse_get_current_size(hw);
+ target_pkt->offset = offset;
+ target_pkt->word_en = tmp_word_en;
+ } else {
+ *continual = false;
+ }
+ *write_state = PG_STATE_HEADER;
+ *repeat_times += 1;
+ if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
+ *continual = false;
+ *result = false;
+ }
+ } else {
+ *efuse_addr += (2 * tmp_word_cnts) + 1;
+ target_pkt->offset = offset;
+ target_pkt->word_en = word_en;
+ *write_state = PG_STATE_HEADER;
+ }
+ }
+ }
+ RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, "efuse PG_STATE_HEADER-1\n");
+}
+
+static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr,
+ int *continual, u8 *write_state,
+ struct pgpkt_struct target_pkt,
+ int *repeat_times, int *result)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct pgpkt_struct tmp_pkt;
+ u8 pg_header;
+ u8 tmp_header;
+ u8 originaldata[8 * sizeof(u8)];
+ u8 tmp_word_cnts;
+ u8 badworden = 0x0F;
+
+ pg_header = ((target_pkt.offset << 4) & 0xf0) | target_pkt.word_en;
+ efuse_one_byte_write(hw, *efuse_addr, pg_header);
+ efuse_one_byte_read(hw, *efuse_addr, &tmp_header);
+
+ if (tmp_header == pg_header) {
+ *write_state = PG_STATE_DATA;
+ } else if (tmp_header == 0xFF) {
+ *write_state = PG_STATE_HEADER;
+ *repeat_times += 1;
+ if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
+ *continual = false;
+ *result = false;
+ }
+ } else {
+ tmp_pkt.offset = (tmp_header >> 4) & 0x0F;
+ tmp_pkt.word_en = tmp_header & 0x0F;
+
+ tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en);
+
+ memset(originaldata, 0xff, 8 * sizeof(u8));
+
+ if (efuse_pg_packet_read(hw, tmp_pkt.offset, originaldata)) {
+ badworden = enable_efuse_data_write(hw,
+ *efuse_addr + 1,
+ tmp_pkt.word_en,
+ originaldata);
+
+ if (0x0F != (badworden & 0x0F)) {
+ u8 reorg_offset = tmp_pkt.offset;
+ u8 reorg_worden = badworden;
+
+ efuse_pg_packet_write(hw, reorg_offset,
+ reorg_worden,
+ originaldata);
+ *efuse_addr = efuse_get_current_size(hw);
+ } else {
+ *efuse_addr = *efuse_addr +
+ (tmp_word_cnts * 2) + 1;
+ }
+ } else {
+ *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
+ }
+
+ *write_state = PG_STATE_HEADER;
+ *repeat_times += 1;
+ if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
+ *continual = false;
+ *result = false;
+ }
+
+ RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
+ "efuse PG_STATE_HEADER-2\n");
+ }
+}
+
+static int efuse_pg_packet_write(struct ieee80211_hw *hw,
+ u8 offset, u8 word_en, u8 *data)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct pgpkt_struct target_pkt;
+ u8 write_state = PG_STATE_HEADER;
+ int continual = true, dataempty = true, result = true;
+ u16 efuse_addr = 0;
+ u8 efuse_data;
+ u8 target_word_cnts = 0;
+ u8 badworden = 0x0F;
+ static int repeat_times;
+
+ if (efuse_get_current_size(hw) >= (EFUSE_MAX_SIZE -
+ rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) {
+ RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
+ "%s error\n", __func__);
+ return false;
+ }
+
+ target_pkt.offset = offset;
+ target_pkt.word_en = word_en;
+
+ memset(target_pkt.data, 0xFF, 8 * sizeof(u8));
+
+ efuse_word_enable_data_read(word_en, data, target_pkt.data);
+ target_word_cnts = efuse_calculate_word_cnts(target_pkt.word_en);
+
+ RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, "efuse Power ON\n");
+
+ while (continual && (efuse_addr < (EFUSE_MAX_SIZE -
+ rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN]))) {
+ if (write_state == PG_STATE_HEADER) {
+ dataempty = true;
+ badworden = 0x0F;
+ RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
+ "efuse PG_STATE_HEADER\n");
+
+ if (efuse_one_byte_read(hw, efuse_addr, &efuse_data) &&
+ (efuse_data != 0xFF))
+ efuse_write_data_case1(hw, &efuse_addr,
+ efuse_data, offset,
+ &continual,
+ &write_state,
+ &target_pkt,
+ &repeat_times, &result,
+ word_en);
+ else
+ efuse_write_data_case2(hw, &efuse_addr,
+ &continual,
+ &write_state,
+ target_pkt,
+ &repeat_times,
+ &result);
+
+ } else if (write_state == PG_STATE_DATA) {
+ RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
+ "efuse PG_STATE_DATA\n");
+ badworden = 0x0f;
+ badworden =
+ enable_efuse_data_write(hw, efuse_addr + 1,
+ target_pkt.word_en,
+ target_pkt.data);
+
+ if ((badworden & 0x0F) == 0x0F) {
+ continual = false;
+ } else {
+ efuse_addr =
+ efuse_addr + (2 * target_word_cnts) + 1;
+
+ target_pkt.offset = offset;
+ target_pkt.word_en = badworden;
+ target_word_cnts =
+ efuse_calculate_word_cnts(target_pkt.word_en);
+ write_state = PG_STATE_HEADER;
+ repeat_times++;
+ if (repeat_times > EFUSE_REPEAT_THRESHOLD_) {
+ continual = false;
+ result = false;
+ }
+ RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
+ "efuse PG_STATE_HEADER-3\n");
+ }
+ }
+ }
+
+ if (efuse_addr >= (EFUSE_MAX_SIZE -
+ rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) {
+ RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
+ "efuse_addr(%#x) Out of size!!\n", efuse_addr);
+ }
+
+ return true;
+}
+
+static void efuse_word_enable_data_read(u8 word_en, u8 *sourdata,
+ u8 *targetdata)
+{
+ if (!(word_en & BIT(0))) {
+ targetdata[0] = sourdata[0];
+ targetdata[1] = sourdata[1];
+ }
+
+ if (!(word_en & BIT(1))) {
+ targetdata[2] = sourdata[2];
+ targetdata[3] = sourdata[3];
+ }
+
+ if (!(word_en & BIT(2))) {
+ targetdata[4] = sourdata[4];
+ targetdata[5] = sourdata[5];
+ }
+
+ if (!(word_en & BIT(3))) {
+ targetdata[6] = sourdata[6];
+ targetdata[7] = sourdata[7];
+ }
+}
+
+static u8 enable_efuse_data_write(struct ieee80211_hw *hw,
+ u16 efuse_addr, u8 word_en, u8 *data)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u16 tmpaddr;
+ u16 start_addr = efuse_addr;
+ u8 badworden = 0x0F;
+ u8 tmpdata[8];
+
+ memset(tmpdata, 0xff, PGPKT_DATA_SIZE);
+ RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
+ "word_en = %x efuse_addr=%x\n", word_en, efuse_addr);
+
+ if (!(word_en & BIT(0))) {
+ tmpaddr = start_addr;
+ efuse_one_byte_write(hw, start_addr++, data[0]);
+ efuse_one_byte_write(hw, start_addr++, data[1]);
+
+ efuse_one_byte_read(hw, tmpaddr, &tmpdata[0]);
+ efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[1]);
+ if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1]))
+ badworden &= (~BIT(0));
+ }
+
+ if (!(word_en & BIT(1))) {
+ tmpaddr = start_addr;
+ efuse_one_byte_write(hw, start_addr++, data[2]);
+ efuse_one_byte_write(hw, start_addr++, data[3]);
+
+ efuse_one_byte_read(hw, tmpaddr, &tmpdata[2]);
+ efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[3]);
+ if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3]))
+ badworden &= (~BIT(1));
+ }
+
+ if (!(word_en & BIT(2))) {
+ tmpaddr = start_addr;
+ efuse_one_byte_write(hw, start_addr++, data[4]);
+ efuse_one_byte_write(hw, start_addr++, data[5]);
+
+ efuse_one_byte_read(hw, tmpaddr, &tmpdata[4]);
+ efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[5]);
+ if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5]))
+ badworden &= (~BIT(2));
+ }
+
+ if (!(word_en & BIT(3))) {
+ tmpaddr = start_addr;
+ efuse_one_byte_write(hw, start_addr++, data[6]);
+ efuse_one_byte_write(hw, start_addr++, data[7]);
+
+ efuse_one_byte_read(hw, tmpaddr, &tmpdata[6]);
+ efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[7]);
+ if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7]))
+ badworden &= (~BIT(3));
+ }
+
+ return badworden;
+}
+
+void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ u8 tempval;
+ u16 tmpv16;
+
+ if (pwrstate && (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE)) {
+ if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192CE &&
+ rtlhal->hw_type != HARDWARE_TYPE_RTL8192DE) {
+ rtl_write_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_ACCESS], 0x69);
+ } else {
+ tmpv16 =
+ rtl_read_word(rtlpriv,
+ rtlpriv->cfg->maps[SYS_ISO_CTRL]);
+ if (!(tmpv16 & rtlpriv->cfg->maps[EFUSE_PWC_EV12V])) {
+ tmpv16 |= rtlpriv->cfg->maps[EFUSE_PWC_EV12V];
+ rtl_write_word(rtlpriv,
+ rtlpriv->cfg->maps[SYS_ISO_CTRL],
+ tmpv16);
+ }
+ }
+ tmpv16 = rtl_read_word(rtlpriv,
+ rtlpriv->cfg->maps[SYS_FUNC_EN]);
+ if (!(tmpv16 & rtlpriv->cfg->maps[EFUSE_FEN_ELDR])) {
+ tmpv16 |= rtlpriv->cfg->maps[EFUSE_FEN_ELDR];
+ rtl_write_word(rtlpriv,
+ rtlpriv->cfg->maps[SYS_FUNC_EN], tmpv16);
+ }
+
+ tmpv16 = rtl_read_word(rtlpriv, rtlpriv->cfg->maps[SYS_CLK]);
+ if ((!(tmpv16 & rtlpriv->cfg->maps[EFUSE_LOADER_CLK_EN])) ||
+ (!(tmpv16 & rtlpriv->cfg->maps[EFUSE_ANA8M]))) {
+ tmpv16 |= (rtlpriv->cfg->maps[EFUSE_LOADER_CLK_EN] |
+ rtlpriv->cfg->maps[EFUSE_ANA8M]);
+ rtl_write_word(rtlpriv,
+ rtlpriv->cfg->maps[SYS_CLK], tmpv16);
+ }
+ }
+
+ if (pwrstate) {
+ if (write) {
+ tempval = rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_TEST] +
+ 3);
+
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
+ tempval &= ~(BIT(3) | BIT(4) | BIT(5) | BIT(6));
+ tempval |= (VOLTAGE_V25 << 3);
+ } else if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE) {
+ tempval &= 0x0F;
+ tempval |= (VOLTAGE_V25 << 4);
+ }
+
+ rtl_write_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_TEST] + 3,
+ (tempval | 0x80));
+ }
+
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) {
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK],
+ 0x03);
+ }
+ } else {
+ if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192CE &&
+ rtlhal->hw_type != HARDWARE_TYPE_RTL8192DE)
+ rtl_write_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_ACCESS], 0);
+
+ if (write) {
+ tempval = rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_TEST] +
+ 3);
+ rtl_write_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_TEST] + 3,
+ (tempval & 0x7F));
+ }
+
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) {
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK],
+ 0x02);
+ }
+ }
+}
+
+static u16 efuse_get_current_size(struct ieee80211_hw *hw)
+{
+ int continual = true;
+ u16 efuse_addr = 0;
+ u8 hoffset, hworden;
+ u8 efuse_data, word_cnts;
+
+ while (continual && efuse_one_byte_read(hw, efuse_addr, &efuse_data) &&
+ (efuse_addr < EFUSE_MAX_SIZE)) {
+ if (efuse_data != 0xFF) {
+ hoffset = (efuse_data >> 4) & 0x0F;
+ hworden = efuse_data & 0x0F;
+ word_cnts = efuse_calculate_word_cnts(hworden);
+ efuse_addr = efuse_addr + (word_cnts * 2) + 1;
+ } else {
+ continual = false;
+ }
+ }
+
+ return efuse_addr;
+}
+
+static u8 efuse_calculate_word_cnts(u8 word_en)
+{
+ u8 word_cnts = 0;
+
+ if (!(word_en & BIT(0)))
+ word_cnts++;
+ if (!(word_en & BIT(1)))
+ word_cnts++;
+ if (!(word_en & BIT(2)))
+ word_cnts++;
+ if (!(word_en & BIT(3)))
+ word_cnts++;
+ return word_cnts;
+}
+
+int rtl_get_hwinfo(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv,
+ int max_size, u8 *hwinfo, int *params)
+{
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+ struct device *dev = &rtlpcipriv->dev.pdev->dev;
+ u16 eeprom_id;
+ u16 i, usvalue;
+
+ switch (rtlefuse->epromtype) {
+ case EEPROM_BOOT_EFUSE:
+ rtl_efuse_shadow_map_update(hw);
+ break;
+
+ case EEPROM_93C46:
+ pr_err("RTL8XXX did not boot from eeprom, check it !!\n");
+ return 1;
+
+ default:
+ dev_warn(dev, "no efuse data\n");
+ return 1;
+ }
+
+ memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], max_size);
+
+ RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP",
+ hwinfo, max_size);
+
+ eeprom_id = *((u16 *)&hwinfo[0]);
+ if (eeprom_id != params[0]) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ "EEPROM ID(%#x) is invalid!!\n", eeprom_id);
+ rtlefuse->autoload_failflag = true;
+ } else {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
+ rtlefuse->autoload_failflag = false;
+ }
+
+ if (rtlefuse->autoload_failflag)
+ return 1;
+
+ rtlefuse->eeprom_vid = *(u16 *)&hwinfo[params[1]];
+ rtlefuse->eeprom_did = *(u16 *)&hwinfo[params[2]];
+ rtlefuse->eeprom_svid = *(u16 *)&hwinfo[params[3]];
+ rtlefuse->eeprom_smid = *(u16 *)&hwinfo[params[4]];
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "EEPROMId = 0x%4x\n", eeprom_id);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid);
+
+ for (i = 0; i < 6; i += 2) {
+ usvalue = *(u16 *)&hwinfo[params[5] + i];
+ *((u16 *)(&rtlefuse->dev_addr[i])) = usvalue;
+ }
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr);
+
+ rtlefuse->eeprom_channelplan = *&hwinfo[params[6]];
+ rtlefuse->eeprom_version = *(u16 *)&hwinfo[params[7]];
+ rtlefuse->txpwr_fromeprom = true;
+ rtlefuse->eeprom_oemid = *&hwinfo[params[8]];
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid);
+
+ /* set channel plan to world wide 13 */
+ rtlefuse->channel_plan = params[9];
+
+ return 0;
+}
+
+void rtl_fw_block_write(struct ieee80211_hw *hw, const u8 *buffer, u32 size)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 *pu4byteptr = (u8 *)buffer;
+ u32 i;
+
+ for (i = 0; i < size; i++)
+ rtl_write_byte(rtlpriv, (START_ADDRESS + i), *(pu4byteptr + i));
+}
+
+void rtl_fw_page_write(struct ieee80211_hw *hw, u32 page, const u8 *buffer,
+ u32 size)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 value8;
+ u8 u8page = (u8)(page & 0x07);
+
+ value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
+
+ rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
+ rtl_fw_block_write(hw, buffer, size);
+}
+
+void rtl_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
+{
+ u32 fwlen = *pfwlen;
+ u8 remain = (u8)(fwlen % 4);
+
+ remain = (remain == 0) ? 0 : (4 - remain);
+
+ while (remain > 0) {
+ pfwbuf[fwlen] = 0;
+ fwlen++;
+ remain--;
+ }
+
+ *pfwlen = fwlen;
+}
diff --git a/drivers/staging/rtlwifi/efuse.h b/drivers/staging/rtlwifi/efuse.h
new file mode 100644
index 0000000..0a23305
--- /dev/null
+++ b/drivers/staging/rtlwifi/efuse.h
@@ -0,0 +1,120 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2012 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL_EFUSE_H_
+#define __RTL_EFUSE_H_
+
+#define EFUSE_IC_ID_OFFSET 506
+
+#define EFUSE_MAX_WORD_UNIT 4
+
+#define EFUSE_INIT_MAP 0
+#define EFUSE_MODIFY_MAP 1
+
+#define PG_STATE_HEADER 0x01
+#define PG_STATE_WORD_0 0x02
+#define PG_STATE_WORD_1 0x04
+#define PG_STATE_WORD_2 0x08
+#define PG_STATE_WORD_3 0x10
+#define PG_STATE_DATA 0x20
+
+#define EFUSE_REPEAT_THRESHOLD_ 3
+#define EFUSE_ERROE_HANDLE 1
+
+struct efuse_map {
+ u8 offset;
+ u8 word_start;
+ u8 byte_start;
+ u8 byte_cnts;
+};
+
+struct pgpkt_struct {
+ u8 offset;
+ u8 word_en;
+ u8 data[8];
+};
+
+enum efuse_data_item {
+ EFUSE_CHIP_ID = 0,
+ EFUSE_LDO_SETTING,
+ EFUSE_CLK_SETTING,
+ EFUSE_SDIO_SETTING,
+ EFUSE_CCCR,
+ EFUSE_SDIO_MODE,
+ EFUSE_OCR,
+ EFUSE_F0CIS,
+ EFUSE_F1CIS,
+ EFUSE_MAC_ADDR,
+ EFUSE_EEPROM_VER,
+ EFUSE_CHAN_PLAN,
+ EFUSE_TXPW_TAB
+};
+
+enum {
+ VOLTAGE_V25 = 0x03,
+ LDOE25_SHIFT = 28,
+};
+
+struct efuse_priv {
+ u8 id[2];
+ u8 ldo_setting[2];
+ u8 clk_setting[2];
+ u8 cccr;
+ u8 sdio_mode;
+ u8 ocr[3];
+ u8 cis0[17];
+ u8 cis1[48];
+ u8 mac_addr[6];
+ u8 eeprom_verno;
+ u8 channel_plan;
+ u8 tx_power_b[14];
+ u8 tx_power_g[14];
+};
+
+void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf);
+void efuse_initialize(struct ieee80211_hw *hw);
+u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address);
+int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, u8 *data);
+void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value);
+void read_efuse(struct ieee80211_hw *hw, u16 _offset,
+ u16 _size_byte, u8 *pbuf);
+void efuse_shadow_read(struct ieee80211_hw *hw, u8 type,
+ u16 offset, u32 *value);
+void efuse_shadow_write(struct ieee80211_hw *hw, u8 type,
+ u16 offset, u32 value);
+bool efuse_shadow_update(struct ieee80211_hw *hw);
+bool efuse_shadow_update_chk(struct ieee80211_hw *hw);
+void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw);
+void efuse_force_write_vendor_id(struct ieee80211_hw *hw);
+void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx);
+void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate);
+int rtl_get_hwinfo(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv,
+ int max_size, u8 *hwinfo, int *params);
+void rtl_fill_dummy(u8 *pfwbuf, u32 *pfwlen);
+void rtl_fw_page_write(struct ieee80211_hw *hw, u32 page, const u8 *buffer,
+ u32 size);
+void rtl_fw_block_write(struct ieee80211_hw *hw, const u8 *buffer, u32 size);
+
+#endif
diff --git a/drivers/staging/rtlwifi/halmac/halmac_2_platform.h b/drivers/staging/rtlwifi/halmac/halmac_2_platform.h
new file mode 100644
index 0000000..26e60cb
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_2_platform.h
@@ -0,0 +1,52 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HALMAC_2_PLATFORM_H_
+#define _HALMAC_2_PLATFORM_H_
+
+#include "../wifi.h"
+#include <asm/byteorder.h>
+
+#define HALMAC_PLATFORM_LITTLE_ENDIAN 1
+#define HALMAC_PLATFORM_BIG_ENDIAN 0
+
+/* Note : Named HALMAC_PLATFORM_LITTLE_ENDIAN / HALMAC_PLATFORM_BIG_ENDIAN
+ * is not mandatory. But Little endian must be '1'. Big endian must be '0'
+ */
+#if defined(__LITTLE_ENDIAN)
+#define HALMAC_SYSTEM_ENDIAN HALMAC_PLATFORM_LITTLE_ENDIAN
+#elif defined(__BIG_ENDIAN)
+#define HALMAC_SYSTEM_ENDIAN HALMAC_PLATFORM_BIG_ENDIAN
+#else
+#error
+#endif
+
+/* define the Platform SDIO Bus CLK */
+#define PLATFORM_SD_CLK 50000000 /*50MHz*/
+
+/* define the Rx FIFO expanding mode packet size unit for 8821C and 8822B */
+/* Should be 8 Byte alignment */
+#define HALMAC_RX_FIFO_EXPANDING_MODE_PKT_SIZE 16 /*Bytes*/
+
+#endif /* _HALMAC_2_PLATFORM_H_ */
diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_8822b_cfg.h b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_8822b_cfg.h
new file mode 100644
index 0000000..04e44ae
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_8822b_cfg.h
@@ -0,0 +1,132 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HALMAC_8822B_CFG_H_
+#define _HALMAC_8822B_CFG_H_
+
+#include "halmac_8822b_pwr_seq.h"
+#include "halmac_api_8822b.h"
+#include "halmac_api_8822b_usb.h"
+#include "halmac_api_8822b_sdio.h"
+#include "halmac_api_8822b_pcie.h"
+#include "../../halmac_bit2.h"
+#include "../../halmac_reg2.h"
+#include "../../halmac_api.h"
+
+#define HALMAC_TX_FIFO_SIZE_8822B 262144 /* 256k */
+#define HALMAC_TX_FIFO_SIZE_LA_8822B 131072 /* 128k */
+#define HALMAC_RX_FIFO_SIZE_8822B 24576 /* 24k */
+#define HALMAC_TX_PAGE_SIZE_8822B 128 /* PageSize 128Byte */
+#define HALMAC_TX_ALIGN_SIZE_8822B 8
+#define HALMAC_TX_PAGE_SIZE_2_POWER_8822B 7 /* 128 = 2^7 */
+#define HALMAC_SECURITY_CAM_ENTRY_NUM_8822B 64 /* CAM Entry size */
+#define HALMAC_TX_AGG_ALIGNMENT_SIZE_8822B 8
+#define HALMAC_TX_DESC_SIZE_8822B 48
+#define HALMAC_RX_DESC_SIZE_8822B 24
+#define HALMAC_RX_DESC_DUMMY_SIZE_MAX_8822B 120
+#define HALMAC_C2H_PKT_BUF_8822B 256
+#define HALMAC_RX_FIFO_EXPANDING_MODE_PKT_SIZE_MAX_8822B 80 /* align 8 Byte*/
+#define HALMAC_RX_FIFO_EXPANDING_UNIT_8822B \
+ (HALMAC_RX_DESC_SIZE_8822B + HALMAC_RX_DESC_DUMMY_SIZE_MAX_8822B + \
+ HALMAC_RX_FIFO_EXPANDING_MODE_PKT_SIZE) /* align 8 Byte*/
+#define HALMAC_RX_FIFO_EXPANDING_UNIT_MAX_8822B \
+ (HALMAC_RX_DESC_SIZE_8822B + HALMAC_RX_DESC_DUMMY_SIZE_MAX_8822B + \
+ HALMAC_RX_FIFO_EXPANDING_MODE_PKT_SIZE_MAX_8822B) /* align 8 Byte*/
+
+#define HALMAC_TX_FIFO_SIZE_EX_1_BLK_8822B 196608 /* 192k */
+#define HALMAC_RX_FIFO_SIZE_EX_1_BLK_8822B \
+ ((((HALMAC_RX_FIFO_EXPANDING_UNIT_8822B << 8) - 1) >> 10) \
+ << 10) /* < 56k*/
+#define HALMAC_RX_FIFO_SIZE_EX_1_BLK_MAX_8822B \
+ ((((HALMAC_RX_FIFO_EXPANDING_UNIT_MAX_8822B << 8) - 1) >> 10) \
+ << 10) /* 55k*/
+#define HALMAC_TX_FIFO_SIZE_EX_2_BLK_8822B 131072 /* 128k */
+#define HALMAC_RX_FIFO_SIZE_EX_2_BLK_8822B 155648 /* 152k */
+#define HALMAC_TX_FIFO_SIZE_EX_3_BLK_8822B 65536 /* 64k */
+#define HALMAC_RX_FIFO_SIZE_EX_3_BLK_8822B 221184 /* 216k */
+
+/* TXFIFO LAYOUT
+ * HIGH_QUEUE
+ * NORMAL_QUEUE
+ * LOW_QUEUE
+ * EXTRA_QUEUE
+ * PUBLIC_QUEUE -- decided after all other queue are defined
+ * GAP_QUEUE -- Used to separate AC queue and Rsvd page
+ *
+ * RSVD_DRIVER -- Driver used rsvd page area
+ * RSVD_H2C_EXTRAINFO -- Extra Information for h2c
+ * RSVD_H2C_QUEUE -- h2c queue in rsvd page
+ * RSVD_CPU_INSTRUCTION -- extend fw code
+ * RSVD_FW_TXBUFF -- fw used this area to send packet
+ *
+ * Symbol: HALMAC_MODE_QUEUE_UNIT_CHIP, ex: HALMAC_LB_2BULKOUT_FWCMD_PGNUM_8822B
+ */
+#define HALMAC_EXTRA_INFO_BUFF_SIZE_FULL_FIFO_8822B \
+ 16384 /*16K, only used in init case*/
+
+#define HALMAC_RSVD_DRV_PGNUM_8822B 16 /*2048*/
+#define HALMAC_RSVD_H2C_EXTRAINFO_PGNUM_8822B 32 /*4096*/
+#define HALMAC_RSVD_H2C_QUEUE_PGNUM_8822B 8 /*1024*/
+#define HALMAC_RSVD_CPU_INSTRUCTION_PGNUM_8822B 0 /*0*/
+#define HALMAC_RSVD_FW_TXBUFF_PGNUM_8822B 4 /*512*/
+
+#define HALMAC_EFUSE_SIZE_8822B 1024 /* 0x400 */
+#define HALMAC_BT_EFUSE_SIZE_8822B 128 /* 0x80 */
+#define HALMAC_EEPROM_SIZE_8822B 0x300
+#define HALMAC_CR_TRX_ENABLE_8822B \
+ (BIT_HCI_TXDMA_EN | BIT_HCI_RXDMA_EN | BIT_TXDMA_EN | BIT_RXDMA_EN | \
+ BIT_PROTOCOL_EN | BIT_SCHEDULE_EN | BIT_MACTXEN | BIT_MACRXEN)
+
+#define HALMAC_BLK_DESC_NUM_8822B 0x3 /* Only for USB */
+
+/* AMPDU max time (unit : 32us) */
+#define HALMAC_AMPDU_MAX_TIME_8822B 0x70
+
+/* Protect mode control */
+#define HALMAC_PROT_RTS_LEN_TH_8822B 0xFF
+#define HALMAC_PROT_RTS_TX_TIME_TH_8822B 0x08
+#define HALMAC_PROT_MAX_AGG_PKT_LIMIT_8822B 0x20
+#define HALMAC_PROT_RTS_MAX_AGG_PKT_LIMIT_8822B 0x20
+
+/* Fast EDCA setting */
+#define HALMAC_FAST_EDCA_VO_TH_8822B 0x06
+#define HALMAC_FAST_EDCA_VI_TH_8822B 0x06
+#define HALMAC_FAST_EDCA_BE_TH_8822B 0x06
+#define HALMAC_FAST_EDCA_BK_TH_8822B 0x06
+
+/* BAR setting */
+#define HALMAC_BAR_RETRY_LIMIT_8822B 0x01
+#define HALMAC_RA_TRY_RATE_AGG_LIMIT_8822B 0x08
+
+enum halmac_normal_rxagg_th_to_8822b {
+ HALMAC_NORMAL_RXAGG_THRESHOLD_8822B = 0xFF,
+ HALMAC_NORMAL_RXAGG_TIMEOUT_8822B = 0x01,
+};
+
+enum halmac_loopback_rxagg_th_to_8822b {
+ HALMAC_LOOPBACK_RXAGG_THRESHOLD_8822B = 0xFF,
+ HALMAC_LOOPBACK_RXAGG_TIMEOUT_8822B = 0x01,
+};
+
+#endif
diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_8822b_phy.c b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_8822b_phy.c
new file mode 100644
index 0000000..b2a5aed
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_8822b_phy.c
@@ -0,0 +1,106 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#include "../halmac_88xx_cfg.h"
+#include "halmac_8822b_cfg.h"
+
+/**
+ * ============ip sel item list============
+ * HALMAC_IP_SEL_INTF_PHY
+ * USB2 : usb2 phy, 1byte value
+ * USB3 : usb3 phy, 2byte value
+ * PCIE1 : pcie gen1 mdio, 2byte value
+ * PCIE2 : pcie gen2 mdio, 2byte value
+ * HALMAC_IP_SEL_MAC
+ * USB2, USB3, PCIE1, PCIE2 : mac ip, 1byte value
+ * HALMAC_IP_SEL_PCIE_DBI
+ * USB2 USB3 : none
+ * PCIE1, PCIE2 : pcie dbi, 1byte value
+ */
+
+struct halmac_intf_phy_para_ HALMAC_RTL8822B_USB2_PHY[] = {
+ /* {offset, value, ip sel, cut mask, platform mask} */
+ {0xFFFF, 0x00, HALMAC_IP_SEL_INTF_PHY, HALMAC_INTF_PHY_CUT_ALL,
+ HALMAC_INTF_PHY_PLATFORM_ALL},
+};
+
+struct halmac_intf_phy_para_ HALMAC_RTL8822B_USB3_PHY[] = {
+ /* {offset, value, ip sel, cut mask, platform mask} */
+ {0x0001, 0xA841, HALMAC_IP_SEL_INTF_PHY, HALMAC_INTF_PHY_CUT_D,
+ HALMAC_INTF_PHY_PLATFORM_ALL},
+ {0xFFFF, 0x0000, HALMAC_IP_SEL_INTF_PHY, HALMAC_INTF_PHY_CUT_ALL,
+ HALMAC_INTF_PHY_PLATFORM_ALL},
+};
+
+struct halmac_intf_phy_para_ HALMAC_RTL8822B_PCIE_PHY_GEN1[] = {
+ /* {offset, value, ip sel, cut mask, platform mask} */
+ {0x0001, 0xA841, HALMAC_IP_SEL_INTF_PHY, HALMAC_INTF_PHY_CUT_C,
+ HALMAC_INTF_PHY_PLATFORM_ALL},
+ {0x0002, 0x60C6, HALMAC_IP_SEL_INTF_PHY, HALMAC_INTF_PHY_CUT_C,
+ HALMAC_INTF_PHY_PLATFORM_ALL},
+ {0x0008, 0x3596, HALMAC_IP_SEL_INTF_PHY, HALMAC_INTF_PHY_CUT_C,
+ HALMAC_INTF_PHY_PLATFORM_ALL},
+ {0x0009, 0x321C, HALMAC_IP_SEL_INTF_PHY, HALMAC_INTF_PHY_CUT_C,
+ HALMAC_INTF_PHY_PLATFORM_ALL},
+ {0x000A, 0x9623, HALMAC_IP_SEL_INTF_PHY, HALMAC_INTF_PHY_CUT_C,
+ HALMAC_INTF_PHY_PLATFORM_ALL},
+ {0x0020, 0x94FF, HALMAC_IP_SEL_INTF_PHY, HALMAC_INTF_PHY_CUT_C,
+ HALMAC_INTF_PHY_PLATFORM_ALL},
+ {0x0021, 0xFFCF, HALMAC_IP_SEL_INTF_PHY, HALMAC_INTF_PHY_CUT_C,
+ HALMAC_INTF_PHY_PLATFORM_ALL},
+ {0x0026, 0xC006, HALMAC_IP_SEL_INTF_PHY, HALMAC_INTF_PHY_CUT_C,
+ HALMAC_INTF_PHY_PLATFORM_ALL},
+ {0x0029, 0xFF0E, HALMAC_IP_SEL_INTF_PHY, HALMAC_INTF_PHY_CUT_C,
+ HALMAC_INTF_PHY_PLATFORM_ALL},
+ {0x002A, 0x1840, HALMAC_IP_SEL_INTF_PHY, HALMAC_INTF_PHY_CUT_C,
+ HALMAC_INTF_PHY_PLATFORM_ALL},
+ {0xFFFF, 0x0000, HALMAC_IP_SEL_INTF_PHY, HALMAC_INTF_PHY_CUT_ALL,
+ HALMAC_INTF_PHY_PLATFORM_ALL},
+};
+
+struct halmac_intf_phy_para_ HALMAC_RTL8822B_PCIE_PHY_GEN2[] = {
+ /* {offset, value, ip sel, cut mask, platform mask} */
+ {0x0001, 0xA841, HALMAC_IP_SEL_INTF_PHY, HALMAC_INTF_PHY_CUT_C,
+ HALMAC_INTF_PHY_PLATFORM_ALL},
+ {0x0002, 0x60C6, HALMAC_IP_SEL_INTF_PHY, HALMAC_INTF_PHY_CUT_C,
+ HALMAC_INTF_PHY_PLATFORM_ALL},
+ {0x0008, 0x3597, HALMAC_IP_SEL_INTF_PHY, HALMAC_INTF_PHY_CUT_C,
+ HALMAC_INTF_PHY_PLATFORM_ALL},
+ {0x0009, 0x321C, HALMAC_IP_SEL_INTF_PHY, HALMAC_INTF_PHY_CUT_C,
+ HALMAC_INTF_PHY_PLATFORM_ALL},
+ {0x000A, 0x9623, HALMAC_IP_SEL_INTF_PHY, HALMAC_INTF_PHY_CUT_C,
+ HALMAC_INTF_PHY_PLATFORM_ALL},
+ {0x0020, 0x94FF, HALMAC_IP_SEL_INTF_PHY, HALMAC_INTF_PHY_CUT_C,
+ HALMAC_INTF_PHY_PLATFORM_ALL},
+ {0x0021, 0xFFCF, HALMAC_IP_SEL_INTF_PHY, HALMAC_INTF_PHY_CUT_C,
+ HALMAC_INTF_PHY_PLATFORM_ALL},
+ {0x0026, 0xC006, HALMAC_IP_SEL_INTF_PHY, HALMAC_INTF_PHY_CUT_C,
+ HALMAC_INTF_PHY_PLATFORM_ALL},
+ {0x0029, 0xFF0E, HALMAC_IP_SEL_INTF_PHY, HALMAC_INTF_PHY_CUT_C,
+ HALMAC_INTF_PHY_PLATFORM_ALL},
+ {0x002A, 0x3040, HALMAC_IP_SEL_INTF_PHY, HALMAC_INTF_PHY_CUT_C,
+ HALMAC_INTF_PHY_PLATFORM_ALL},
+ {0xFFFF, 0x0000, HALMAC_IP_SEL_INTF_PHY, HALMAC_INTF_PHY_CUT_ALL,
+ HALMAC_INTF_PHY_PLATFORM_ALL},
+};
diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_8822b_pwr_seq.c b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_8822b_pwr_seq.c
new file mode 100644
index 0000000..0edd1f5
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_8822b_pwr_seq.c
@@ -0,0 +1,563 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#include "../halmac_88xx_cfg.h"
+#include "halmac_8822b_cfg.h"
+
+static struct halmac_wl_pwr_cfg_ HALMAC_RTL8822B_TRANS_CARDEMU_TO_ACT[] = {
+ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value } */
+ {0x0012, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(1), 0}, /*SWR OCP = SWR OCP = 010 1382.40*/
+ {0x0012, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(0), BIT(0)}, /*SWR OCP = 010 1382.40 */
+ {0x0020, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_USB_MSK | HALMAC_PWR_INTF_SDIO_MSK,
+ HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE, BIT(0),
+ BIT(0)}, /*0x20[0] = 1b'1 enable LDOA12 MACRO block for all interface*/
+ {0x0001, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_USB_MSK | HALMAC_PWR_INTF_SDIO_MSK,
+ HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_DELAY, 1,
+ HALMAC_PWRSEQ_DELAY_MS}, /*Delay 1ms*/
+ {0x0000, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_USB_MSK | HALMAC_PWR_INTF_SDIO_MSK,
+ HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE, BIT(5),
+ 0}, /*0x00[5] = 1b'0 release analog Ips to digital ,1:isolation*/
+ {0x0005, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ (BIT(4) | BIT(3) | BIT(2)),
+ 0}, /* disable SW LPS 0x04[10]=0 and WLSUS_EN 0x04[12:11]=0*/
+ {0x0075, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_PCI_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(0), BIT(0)}, /* Disable USB suspend */
+ {0x0006, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_POLLING, BIT(1),
+ BIT(1)}, /* wait till 0x04[17] = 1 power ready*/
+ {0x0075, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_PCI_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(0), 0}, /* Enable USB suspend */
+ {0xFF1A, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_USB_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0}, /*0xFF1A = 0 to release resume signals*/
+ {0x0006, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(0), BIT(0)}, /* release WLON reset 0x04[16]=1*/
+ {0x0005, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(7), 0}, /* disable HWPDN 0x04[15]=0*/
+ {0x0005, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ (BIT(4) | BIT(3)), 0}, /* disable WL suspend*/
+ {0x0005, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(0), BIT(0)}, /* polling until return 0*/
+ {0x0005, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_POLLING, BIT(0), 0},
+ {0x0020, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(3), BIT(3)}, /*Enable XTAL_CLK*/
+ {0x10A8, HALMAC_PWR_CUT_C_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0}, /*NFC pad enabled*/
+ {0x10A9, HALMAC_PWR_CUT_C_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0xef}, /*NFC pad enabled*/
+ {0x10AA, HALMAC_PWR_CUT_C_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0x0c}, /*NFC pad enabled*/
+ {0x0068, HALMAC_PWR_CUT_C_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_WRITE, BIT(4), BIT(4)}, /*SDIO pad power down disabled*/
+ {0x0029, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0xF9}, /*PLL seting*/
+ {0x0024, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(2), 0}, /*Improve TX EVM of CH13 and some 5G channles */
+ {0x0074, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_PCI_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(5), BIT(5)}, /*PCIE WAKE# enabled*/
+ {0xFFFF, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, 0, HALMAC_PWR_CMD_END, 0, 0},
+};
+
+static struct halmac_wl_pwr_cfg_ HALMAC_RTL8822B_TRANS_ACT_TO_CARDEMU[] = {
+ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value } */
+ {0x0003, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_WRITE, BIT(2), 0}, /*0x02[10] = 0 Disable MCU Core*/
+ {0x0093, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(3), 0}, /*LPS option 0x93[3]=0 , SWR PFM*/
+ {0x001F, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0}, /*0x1F[7:0] = 0 turn off RF*/
+ {0x00EF, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0}, /*0xEF[7:0] = 0 turn off RF*/
+ {0xFF1A, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_USB_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0x30}, /*0xFF1A = 0x30 to block resume signals*/
+ {0x0049, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(1), 0}, /*Enable rising edge triggering interrupt*/
+ {0x0006, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(0), BIT(0)}, /* release WLON reset 0x04[16]=1*/
+ {0x0002, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(1), 0}, /* Whole BB is reset */
+ {0x0005, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(1), BIT(1)}, /*0x04[9] = 1 turn off MAC by HW state machine*/
+ {0x0005, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_POLLING, BIT(1),
+ 0}, /*wait till 0x04[9] = 0 polling until return 0 to disable*/
+ {0x0020, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(3), 0}, /* XTAL_CLK gated*/
+ {0x0000, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_USB_MSK | HALMAC_PWR_INTF_SDIO_MSK,
+ HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE, BIT(5),
+ BIT(5)}, /*0x00[5] = 1b'1 analog Ips to digital ,1:isolation*/
+ {0xFFFF, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, 0, HALMAC_PWR_CMD_END, 0, 0},
+};
+
+static struct halmac_wl_pwr_cfg_ HALMAC_RTL8822B_TRANS_CARDEMU_TO_SUS[] = {
+ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value } */
+ {0x0005, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_PCI_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(4) | BIT(3),
+ (BIT(4) | BIT(3))}, /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/
+ {0x0005, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_USB_MSK | HALMAC_PWR_INTF_SDIO_MSK,
+ HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE, BIT(3) | BIT(4),
+ BIT(3)}, /*0x04[12:11] = 2b'01 enable WL suspend*/
+ {0x0007, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_WRITE, 0xFF,
+ 0x20}, /*0x07[7:0] = 0x20 SDIO SOP option to disable BG/MB/ACK/SWR*/
+ {0x0005, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_PCI_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(3) | BIT(4),
+ BIT(3) | BIT(4)}, /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/
+ {0x0086, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_SDIO,
+ HALMAC_PWR_CMD_WRITE, BIT(0),
+ BIT(0)}, /*Set SDIO suspend local register*/
+ {0x0086, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_SDIO,
+ HALMAC_PWR_CMD_POLLING, BIT(1), 0}, /*wait power state to suspend*/
+ {0xFFFF, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, 0, HALMAC_PWR_CMD_END, 0, 0},
+};
+
+static struct halmac_wl_pwr_cfg_ HALMAC_RTL8822B_TRANS_SUS_TO_CARDEMU[] = {
+ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value } */
+ {0x0005, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(3) | BIT(7), 0}, /*clear suspend enable and power down enable*/
+ {0x0086, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_SDIO,
+ HALMAC_PWR_CMD_WRITE, BIT(0), 0}, /*Set SDIO suspend local register*/
+ {0x0086, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_SDIO,
+ HALMAC_PWR_CMD_POLLING, BIT(1),
+ BIT(1)}, /*wait power state to suspend*/
+ {0x0005, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(3) | BIT(4), 0}, /*0x04[12:11] = 2b'01enable WL suspend*/
+ {0xFFFF, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, 0, HALMAC_PWR_CMD_END, 0, 0},
+};
+
+static struct halmac_wl_pwr_cfg_ HALMAC_RTL8822B_TRANS_CARDEMU_TO_CARDDIS[] = {
+ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value } */
+ {0x0005, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_WRITE, BIT(7),
+ BIT(7)}, /*suspend enable and power down enable*/
+ {0x0007, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_USB_MSK | HALMAC_PWR_INTF_SDIO_MSK,
+ HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE, 0xFF,
+ 0x20}, /*0x07=0x20 , SOP option to disable BG/MB*/
+ {0x0067, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(5), 0}, /*0x67[5]=0 , BIT_PAPE_WLBT_SEL*/
+ {0x0005, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_USB_MSK | HALMAC_PWR_INTF_SDIO_MSK,
+ HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE, BIT(3) | BIT(4),
+ BIT(3)}, /*0x04[12:11] = 2b'01 enable WL suspend*/
+ {0x0005, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_PCI_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(2), BIT(2)}, /*0x04[10] = 1, enable SW LPS*/
+ {0x004A, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_USB_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(0), 0}, /*0x48[16] = 0 to disable GPIO9 as EXT WAKEUP*/
+ {0x0067, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_WRITE, BIT(5),
+ 0}, /* 0: BT PAPE control ; 1: WL BB LNAON control*/
+ {0x0067, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_WRITE, BIT(4),
+ 0}, /* 0: BT GPIO[11:10] control ; 1: WL BB LNAON control*/
+ {0x004F, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_WRITE, BIT(0), 0}, /* 0: BT Control*/
+ {0x0067, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_WRITE, BIT(1),
+ 0}, /* turn off BT_3DD_SYNC_B and BT_GPIO[18] */
+ {0x0046, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_WRITE, BIT(6), BIT(6)}, /* GPIO[6] : Output mode*/
+ {0x0067, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_WRITE, BIT(2), 0}, /* turn off BT_GPIO[16] */
+ {0x0046, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_WRITE, BIT(7), BIT(7)}, /* GPIO[7] : Output mode*/
+ {0x0062, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_WRITE, BIT(4), BIT(4)}, /* GPIO[12] : Output mode */
+ {0x0086, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_SDIO,
+ HALMAC_PWR_CMD_WRITE, BIT(0),
+ BIT(0)}, /*Set SDIO suspend local register*/
+ {0x0086, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_SDIO,
+ HALMAC_PWR_CMD_POLLING, BIT(1), 0}, /*wait power state to suspend*/
+ {0x0090, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_USB_MSK | HALMAC_PWR_INTF_PCI_MSK,
+ HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE, BIT(1),
+ 0}, /*0x90[1]=0 , disable 32k clock*/
+ {0x0044, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_SDIO,
+ HALMAC_PWR_CMD_WRITE, 0xFF,
+ 0}, /*0x90[1]=0 , disable 32k clock by indirect access*/
+ {0x0040, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_SDIO,
+ HALMAC_PWR_CMD_WRITE, 0xFF,
+ 0x90}, /*0x90[1]=0 , disable 32k clock by indirect access*/
+ {0x0041, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_SDIO,
+ HALMAC_PWR_CMD_WRITE, 0xFF,
+ 0x00}, /*0x90[1]=0 , disable 32k clock by indirect access*/
+ {0x0042, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_SDIO,
+ HALMAC_PWR_CMD_WRITE, 0xFF,
+ 0x04}, /*0x90[1]=0 , disable 32k clock by indirect access*/
+ {0x0081, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(7), 0}, /*0x80[15]clean fw init ready bit*/
+ {0xFFFF, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, 0, HALMAC_PWR_CMD_END, 0, 0},
+};
+
+static struct halmac_wl_pwr_cfg_ HALMAC_RTL8822B_TRANS_CARDDIS_TO_CARDEMU[] = {
+ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value } */
+ {0x0086, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_SDIO,
+ HALMAC_PWR_CMD_WRITE, BIT(0), 0}, /*Set SDIO suspend local register*/
+ {0x0086, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_SDIO,
+ HALMAC_PWR_CMD_POLLING, BIT(1),
+ BIT(1)}, /*wait power state to suspend*/
+ {0x004A, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_USB_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(0), 0}, /*0x48[16] = 0 to disable GPIO9 as EXT WAKEUP*/
+ {0x0005, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(3) | BIT(4) | BIT(7),
+ 0}, /*clear suspend enable and power down enable*/
+ {0x0301, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_PCI_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0},
+ {0xFFFF, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, 0, HALMAC_PWR_CMD_END, 0, 0},
+};
+
+static struct halmac_wl_pwr_cfg_ HALMAC_RTL8822B_TRANS_ACT_TO_LPS[] = {
+ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value } */
+ {0x0101, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(2), BIT(2)}, /*Enable 32k calibration and thermal meter*/
+ {0x0199, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(3), BIT(3)}, /*Register write data of 32K calibration*/
+ {0x019B, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(7), BIT(7)}, /*Enable 32k calibration reg write*/
+ {0x1138, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(0) | BIT(1), BIT(0) | BIT(1)}, /*set RPWM IMR*/
+ {0x0194, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(0), BIT(0)}, /* enable 32K CLK*/
+ {0x0093, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0x42}, /* LPS Option MAC OFF enable*/
+ {0x0092, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0x20}, /* LPS Option Enable memory to deep sleep mode*/
+ {0x0090, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(1), BIT(1)}, /* enable reg use 32K CLK*/
+ {0x0301, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_PCI_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0xFF}, /*PCIe DMA stop*/
+ {0x0522, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0xFF}, /*Tx Pause*/
+ {0x05F8, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_POLLING, 0xFF,
+ 0}, /*Should be zero if no packet is transmitting*/
+ {0x05F9, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_POLLING, 0xFF,
+ 0}, /*Should be zero if no packet is transmitting*/
+ {0x05FA, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_POLLING, 0xFF,
+ 0}, /*Should be zero if no packet is transmitting*/
+ {0x05FB, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_POLLING, 0xFF,
+ 0}, /*Should be zero if no packet is transmitting*/
+ {0x0002, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(0), 0}, /*CCK and OFDM are disabled,and clock are gated*/
+ {0x0002, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_DELAY,
+ 0, HALMAC_PWRSEQ_DELAY_US}, /*Delay 1us*/
+ {0x0002, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(1), 0}, /*Whole BB is reset*/
+ {0x0100, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0x3F}, /*Reset MAC TRX*/
+ {0x0101, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(1), 0}, /*check if removed later*/
+ {0x0553, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(5), BIT(5)}, /*Respond TxOK to scheduler*/
+ {0x0008, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(4), BIT(4)}, /* switch TSF clock to 32K*/
+ {0x0109, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_POLLING, BIT(7),
+ BIT(7)}, /*Polling 0x109[7]=0 TSF in 40M*/
+ {0x0090, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(0), BIT(0)}, /* enable WL_LPS_EN*/
+ {0xFFFF, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, 0, HALMAC_PWR_CMD_END, 0, 0},
+};
+
+static struct halmac_wl_pwr_cfg_ HALMAC_RTL8822B_TRANS_ACT_TO_DEEP_LPS[] = {
+ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value } */
+ {0x0101, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(2), BIT(2)}, /*Enable 32k calibration and thermal meter*/
+ {0x0199, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(3), BIT(3)}, /*Register write data of 32K calibration*/
+ {0x019B, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(7), BIT(7)}, /*Enable 32k calibration reg write*/
+ {0x1138, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(0) | BIT(1), BIT(0) | BIT(1)}, /*set RPWM IMR*/
+ {0x0194, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(0), BIT(0)}, /* enable 32K CLK*/
+ {0x0093, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0x40}, /* LPS Option MAC OFF enable*/
+ {0x0092, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0x20}, /* LPS Option Enable memory to deep sleep mode*/
+ {0x0090, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(1), BIT(1)}, /* enable reg use 32K CLK*/
+ {0x0301, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_PCI_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0xFF}, /*PCIe DMA stop*/
+ {0x0522, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0xFF}, /*Tx Pause*/
+ {0x05F8, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_POLLING, 0xFF,
+ 0}, /*Should be zero if no packet is transmitting*/
+ {0x05F9, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_POLLING, 0xFF,
+ 0}, /*Should be zero if no packet is transmitting*/
+ {0x05FA, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_POLLING, 0xFF,
+ 0}, /*Should be zero if no packet is transmitting*/
+ {0x05FB, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_POLLING, 0xFF,
+ 0}, /*Should be zero if no packet is transmitting*/
+ {0x0002, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(0), 0}, /*CCK and OFDM are disabled,and clock are gated*/
+ {0x0002, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_DELAY,
+ 0, HALMAC_PWRSEQ_DELAY_US}, /*Delay 1us*/
+ {0x0002, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(1), 0}, /*Whole BB is reset*/
+ {0x0100, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0x3F}, /*Reset MAC TRX*/
+ {0x0101, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(1), 0}, /*check if removed later*/
+ {0x0553, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(5), BIT(5)}, /*Respond TxOK to scheduler*/
+ {0x0008, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(4), BIT(4)}, /* switch TSF clock to 32K*/
+ {0x0109, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_POLLING, BIT(7),
+ BIT(7)}, /*Polling 0x109[7]=1 TSF in 32K*/
+ {0x0090, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(0), BIT(0)}, /* enable WL_LPS_EN*/
+ {0xFFFF, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, 0, HALMAC_PWR_CMD_END, 0, 0},
+};
+
+static struct halmac_wl_pwr_cfg_ HALMAC_RTL8822B_TRANS_LPS_TO_ACT[] = {
+ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value } */
+ {0x0080, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_SDIO,
+ HALMAC_PWR_CMD_WRITE, BIT(7), BIT(7)}, /*SDIO RPWM*/
+ {0x0002, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_DELAY,
+ 0, HALMAC_PWRSEQ_DELAY_MS}, /*Delay*/
+ {0x0080, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_SDIO_MSK, HALMAC_PWR_BASEADDR_SDIO,
+ HALMAC_PWR_CMD_WRITE, BIT(7), 0}, /*SDIO RPWM*/
+ {0xFE58, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_USB_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0x84}, /*USB RPWM*/
+ {0x0361, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_PCI_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0x84}, /*PCIe RPWM*/
+ {0x0002, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_DELAY,
+ 0, HALMAC_PWRSEQ_DELAY_MS}, /*Delay*/
+ {0x0008, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(4), 0}, /* switch TSF to 40M*/
+ {0x0109, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC,
+ HALMAC_PWR_CMD_POLLING, BIT(7), 0}, /*Polling 0x109[7]=0 TSF in 40M*/
+ {0x0101, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(1), BIT(1)},
+ {0x0100, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0xFF}, /*nable WMAC TRX*/
+ {0x0002, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(1) | BIT(0), BIT(1) | BIT(0)}, /*nable BB macro*/
+ {0x0522, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0},
+ {0x113C, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0x03}, /*clear RPWM INT*/
+ {0x0124, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0xFF}, /*clear FW INT*/
+ {0x0125, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0xFF}, /*clear FW INT*/
+ {0x0126, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0xFF}, /*clear FW INT*/
+ {0x0127, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ 0xFF, 0xFF}, /*clear FW INT*/
+ {0x0090, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(1), 0}, /* disable reg use 32K CLK*/
+ {0x0101, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, HALMAC_PWR_BASEADDR_MAC, HALMAC_PWR_CMD_WRITE,
+ BIT(2), 0}, /*disable 32k calibration and thermal meter*/
+ {0xFFFF, HALMAC_PWR_CUT_ALL_MSK, HALMAC_PWR_FAB_ALL_MSK,
+ HALMAC_PWR_INTF_ALL_MSK, 0, HALMAC_PWR_CMD_END, 0, 0},
+};
+
+/* Card Enable Array */
+struct halmac_wl_pwr_cfg_ *halmac_8822b_card_enable_flow[] = {
+ HALMAC_RTL8822B_TRANS_CARDDIS_TO_CARDEMU,
+ HALMAC_RTL8822B_TRANS_CARDEMU_TO_ACT, NULL};
+
+/* Card Disable Array */
+struct halmac_wl_pwr_cfg_ *halmac_8822b_card_disable_flow[] = {
+ HALMAC_RTL8822B_TRANS_ACT_TO_CARDEMU,
+ HALMAC_RTL8822B_TRANS_CARDEMU_TO_CARDDIS, NULL};
+
+/* Suspend Array */
+struct halmac_wl_pwr_cfg_ *halmac_8822b_suspend_flow[] = {
+ HALMAC_RTL8822B_TRANS_ACT_TO_CARDEMU,
+ HALMAC_RTL8822B_TRANS_CARDEMU_TO_SUS, NULL};
+
+/* Resume Array */
+struct halmac_wl_pwr_cfg_ *halmac_8822b_resume_flow[] = {
+ HALMAC_RTL8822B_TRANS_SUS_TO_CARDEMU,
+ HALMAC_RTL8822B_TRANS_CARDEMU_TO_ACT, NULL};
+
+/* HWPDN Array - HW behavior */
+struct halmac_wl_pwr_cfg_ *halmac_8822b_hwpdn_flow[] = {NULL};
+
+/* Enter LPS - FW behavior */
+struct halmac_wl_pwr_cfg_ *halmac_8822b_enter_lps_flow[] = {
+ HALMAC_RTL8822B_TRANS_ACT_TO_LPS, NULL};
+
+/* Enter Deep LPS - FW behavior */
+struct halmac_wl_pwr_cfg_ *halmac_8822b_enter_deep_lps_flow[] = {
+ HALMAC_RTL8822B_TRANS_ACT_TO_DEEP_LPS, NULL};
+
+/* Leave LPS -FW behavior */
+struct halmac_wl_pwr_cfg_ *halmac_8822b_leave_lps_flow[] = {
+ HALMAC_RTL8822B_TRANS_LPS_TO_ACT, NULL};
diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_8822b_pwr_seq.h b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_8822b_pwr_seq.h
new file mode 100644
index 0000000..79a6072
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_8822b_pwr_seq.h
@@ -0,0 +1,40 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef HALMAC_POWER_SEQUENCE_8822B
+#define HALMAC_POWER_SEQUENCE_8822B
+
+#include "../../halmac_pwr_seq_cmd.h"
+
+#define HALMAC_8822B_PWR_SEQ_VER "V17"
+extern struct halmac_wl_pwr_cfg_ *halmac_8822b_card_disable_flow[];
+extern struct halmac_wl_pwr_cfg_ *halmac_8822b_card_enable_flow[];
+extern struct halmac_wl_pwr_cfg_ *halmac_8822b_suspend_flow[];
+extern struct halmac_wl_pwr_cfg_ *halmac_8822b_resume_flow[];
+extern struct halmac_wl_pwr_cfg_ *halmac_8822b_hwpdn_flow[];
+extern struct halmac_wl_pwr_cfg_ *halmac_8822b_enter_lps_flow[];
+extern struct halmac_wl_pwr_cfg_ *halmac_8822b_enter_deep_lps_flow[];
+extern struct halmac_wl_pwr_cfg_ *halmac_8822b_leave_lps_flow[];
+
+#endif
diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b.c b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b.c
new file mode 100644
index 0000000..6b729fe
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b.c
@@ -0,0 +1,343 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#include "halmac_8822b_cfg.h"
+#include "halmac_func_8822b.h"
+#include "../halmac_func_88xx.h"
+
+/**
+ * halmac_mount_api_8822b() - attach functions to function pointer
+ * @halmac_adapter
+ *
+ * SD1 internal use
+ *
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ */
+enum halmac_ret_status
+halmac_mount_api_8822b(struct halmac_adapter *halmac_adapter)
+{
+ struct halmac_api *halmac_api =
+ (struct halmac_api *)halmac_adapter->halmac_api;
+
+ halmac_adapter->chip_id = HALMAC_CHIP_ID_8822B;
+ halmac_adapter->hw_config_info.efuse_size = HALMAC_EFUSE_SIZE_8822B;
+ halmac_adapter->hw_config_info.eeprom_size = HALMAC_EEPROM_SIZE_8822B;
+ halmac_adapter->hw_config_info.bt_efuse_size =
+ HALMAC_BT_EFUSE_SIZE_8822B;
+ halmac_adapter->hw_config_info.cam_entry_num =
+ HALMAC_SECURITY_CAM_ENTRY_NUM_8822B;
+ halmac_adapter->hw_config_info.txdesc_size = HALMAC_TX_DESC_SIZE_8822B;
+ halmac_adapter->hw_config_info.rxdesc_size = HALMAC_RX_DESC_SIZE_8822B;
+ halmac_adapter->hw_config_info.tx_fifo_size = HALMAC_TX_FIFO_SIZE_8822B;
+ halmac_adapter->hw_config_info.rx_fifo_size = HALMAC_RX_FIFO_SIZE_8822B;
+ halmac_adapter->hw_config_info.page_size = HALMAC_TX_PAGE_SIZE_8822B;
+ halmac_adapter->hw_config_info.tx_align_size =
+ HALMAC_TX_ALIGN_SIZE_8822B;
+ halmac_adapter->hw_config_info.page_size_2_power =
+ HALMAC_TX_PAGE_SIZE_2_POWER_8822B;
+
+ halmac_adapter->txff_allocation.rsvd_drv_pg_num =
+ HALMAC_RSVD_DRV_PGNUM_8822B;
+
+ halmac_api->halmac_init_trx_cfg = halmac_init_trx_cfg_8822b;
+ halmac_api->halmac_init_protocol_cfg = halmac_init_protocol_cfg_8822b;
+ halmac_api->halmac_init_h2c = halmac_init_h2c_8822b;
+
+ if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
+ halmac_api->halmac_tx_allowed_sdio =
+ halmac_tx_allowed_sdio_88xx;
+ halmac_api->halmac_cfg_tx_agg_align =
+ halmac_cfg_tx_agg_align_sdio_not_support_88xx;
+ halmac_api->halmac_mac_power_switch =
+ halmac_mac_power_switch_8822b_sdio;
+ halmac_api->halmac_phy_cfg = halmac_phy_cfg_8822b_sdio;
+ halmac_api->halmac_interface_integration_tuning =
+ halmac_interface_integration_tuning_8822b_sdio;
+ } else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_USB) {
+ halmac_api->halmac_mac_power_switch =
+ halmac_mac_power_switch_8822b_usb;
+ halmac_api->halmac_cfg_tx_agg_align =
+ halmac_cfg_tx_agg_align_usb_not_support_88xx;
+ halmac_api->halmac_phy_cfg = halmac_phy_cfg_8822b_usb;
+ halmac_api->halmac_interface_integration_tuning =
+ halmac_interface_integration_tuning_8822b_usb;
+ } else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_PCIE) {
+ halmac_api->halmac_mac_power_switch =
+ halmac_mac_power_switch_8822b_pcie;
+ halmac_api->halmac_cfg_tx_agg_align =
+ halmac_cfg_tx_agg_align_pcie_not_support_88xx;
+ halmac_api->halmac_pcie_switch = halmac_pcie_switch_8822b;
+ halmac_api->halmac_phy_cfg = halmac_phy_cfg_8822b_pcie;
+ halmac_api->halmac_interface_integration_tuning =
+ halmac_interface_integration_tuning_8822b_pcie;
+ } else {
+ halmac_api->halmac_pcie_switch = halmac_pcie_switch_8822b_nc;
+ }
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_init_trx_cfg_8822b() - config trx dma register
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_trx_mode : trx mode selection
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_init_trx_cfg_8822b(struct halmac_adapter *halmac_adapter,
+ enum halmac_trx_mode halmac_trx_mode)
+{
+ u8 value8;
+ u32 value32;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_TRX_CFG);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+ halmac_adapter->trx_mode = halmac_trx_mode;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "halmac_init_trx_cfg ==========>halmac_trx_mode = %d\n",
+ halmac_trx_mode);
+
+ status = halmac_txdma_queue_mapping_8822b(halmac_adapter,
+ halmac_trx_mode);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "halmac_txdma_queue_mapping fail!\n");
+ return status;
+ }
+
+ value8 = 0;
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_CR, value8);
+ value8 = HALMAC_CR_TRX_ENABLE_8822B;
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_CR, value8);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_H2CQ_CSR, BIT(31));
+
+ status = halmac_priority_queue_config_8822b(halmac_adapter,
+ halmac_trx_mode);
+ if (halmac_adapter->txff_allocation.rx_fifo_expanding_mode !=
+ HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE)
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_RX_DRVINFO_SZ, 0xF);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "halmac_txdma_queue_mapping fail!\n");
+ return status;
+ }
+
+ /* Config H2C packet buffer */
+ value32 = HALMAC_REG_READ_32(halmac_adapter, REG_H2C_HEAD);
+ value32 = (value32 & 0xFFFC0000) |
+ (halmac_adapter->txff_allocation.rsvd_h2c_queue_pg_bndy
+ << HALMAC_TX_PAGE_SIZE_2_POWER_8822B);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_H2C_HEAD, value32);
+
+ value32 = HALMAC_REG_READ_32(halmac_adapter, REG_H2C_READ_ADDR);
+ value32 = (value32 & 0xFFFC0000) |
+ (halmac_adapter->txff_allocation.rsvd_h2c_queue_pg_bndy
+ << HALMAC_TX_PAGE_SIZE_2_POWER_8822B);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_H2C_READ_ADDR, value32);
+
+ value32 = HALMAC_REG_READ_32(halmac_adapter, REG_H2C_TAIL);
+ value32 = (value32 & 0xFFFC0000) |
+ ((halmac_adapter->txff_allocation.rsvd_h2c_queue_pg_bndy
+ << HALMAC_TX_PAGE_SIZE_2_POWER_8822B) +
+ (HALMAC_RSVD_H2C_QUEUE_PGNUM_8822B
+ << HALMAC_TX_PAGE_SIZE_2_POWER_8822B));
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_H2C_TAIL, value32);
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_H2C_INFO);
+ value8 = (u8)((value8 & 0xFC) | 0x01);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_H2C_INFO, value8);
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_H2C_INFO);
+ value8 = (u8)((value8 & 0xFB) | 0x04);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_H2C_INFO, value8);
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_TXDMA_OFFSET_CHK + 1);
+ value8 = (u8)((value8 & 0x7f) | 0x80);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_TXDMA_OFFSET_CHK + 1, value8);
+
+ halmac_adapter->h2c_buff_size = HALMAC_RSVD_H2C_QUEUE_PGNUM_8822B
+ << HALMAC_TX_PAGE_SIZE_2_POWER_8822B;
+ halmac_get_h2c_buff_free_space_88xx(halmac_adapter);
+
+ if (halmac_adapter->h2c_buff_size !=
+ halmac_adapter->h2c_buf_free_space) {
+ pr_err("get h2c free space error!\n");
+ return HALMAC_RET_GET_H2C_SPACE_ERR;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "halmac_init_trx_cfg <==========\n");
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_init_protocol_cfg_8822b() - config protocol register
+ * @halmac_adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_init_protocol_cfg_8822b(struct halmac_adapter *halmac_adapter)
+{
+ u32 value32;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_PROTOCOL_CFG);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "[TRACE]%s ==========>\n", __func__);
+
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_AMPDU_MAX_TIME_V1,
+ HALMAC_AMPDU_MAX_TIME_8822B);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_TX_HANG_CTRL, BIT_EN_EOF_V1);
+
+ value32 = HALMAC_PROT_RTS_LEN_TH_8822B |
+ (HALMAC_PROT_RTS_TX_TIME_TH_8822B << 8) |
+ (HALMAC_PROT_MAX_AGG_PKT_LIMIT_8822B << 16) |
+ (HALMAC_PROT_RTS_MAX_AGG_PKT_LIMIT_8822B << 24);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_PROT_MODE_CTRL, value32);
+
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_BAR_MODE_CTRL + 2,
+ HALMAC_BAR_RETRY_LIMIT_8822B |
+ HALMAC_RA_TRY_RATE_AGG_LIMIT_8822B << 8);
+
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_FAST_EDCA_VOVI_SETTING,
+ HALMAC_FAST_EDCA_VO_TH_8822B);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_FAST_EDCA_VOVI_SETTING + 2,
+ HALMAC_FAST_EDCA_VI_TH_8822B);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_FAST_EDCA_BEBK_SETTING,
+ HALMAC_FAST_EDCA_BE_TH_8822B);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_FAST_EDCA_BEBK_SETTING + 2,
+ HALMAC_FAST_EDCA_BK_TH_8822B);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "[TRACE]%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_init_h2c_8822b() - config h2c packet buffer
+ * @halmac_adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_init_h2c_8822b(struct halmac_adapter *halmac_adapter)
+{
+ u8 value8;
+ u32 value32;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ value8 = 0;
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_CR, value8);
+ value8 = HALMAC_CR_TRX_ENABLE_8822B;
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_CR, value8);
+
+ value32 = HALMAC_REG_READ_32(halmac_adapter, REG_H2C_HEAD);
+ value32 = (value32 & 0xFFFC0000) |
+ (halmac_adapter->txff_allocation.rsvd_h2c_queue_pg_bndy
+ << HALMAC_TX_PAGE_SIZE_2_POWER_8822B);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_H2C_HEAD, value32);
+
+ value32 = HALMAC_REG_READ_32(halmac_adapter, REG_H2C_READ_ADDR);
+ value32 = (value32 & 0xFFFC0000) |
+ (halmac_adapter->txff_allocation.rsvd_h2c_queue_pg_bndy
+ << HALMAC_TX_PAGE_SIZE_2_POWER_8822B);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_H2C_READ_ADDR, value32);
+
+ value32 = HALMAC_REG_READ_32(halmac_adapter, REG_H2C_TAIL);
+ value32 = (value32 & 0xFFFC0000) |
+ ((halmac_adapter->txff_allocation.rsvd_h2c_queue_pg_bndy
+ << HALMAC_TX_PAGE_SIZE_2_POWER_8822B) +
+ (HALMAC_RSVD_H2C_QUEUE_PGNUM_8822B
+ << HALMAC_TX_PAGE_SIZE_2_POWER_8822B));
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_H2C_TAIL, value32);
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_H2C_INFO);
+ value8 = (u8)((value8 & 0xFC) | 0x01);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_H2C_INFO, value8);
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_H2C_INFO);
+ value8 = (u8)((value8 & 0xFB) | 0x04);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_H2C_INFO, value8);
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_TXDMA_OFFSET_CHK + 1);
+ value8 = (u8)((value8 & 0x7f) | 0x80);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_TXDMA_OFFSET_CHK + 1, value8);
+
+ halmac_adapter->h2c_buff_size = HALMAC_RSVD_H2C_QUEUE_PGNUM_8822B
+ << HALMAC_TX_PAGE_SIZE_2_POWER_8822B;
+ halmac_get_h2c_buff_free_space_88xx(halmac_adapter);
+
+ if (halmac_adapter->h2c_buff_size !=
+ halmac_adapter->h2c_buf_free_space) {
+ pr_err("get h2c free space error!\n");
+ return HALMAC_RET_GET_H2C_SPACE_ERR;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "h2c free space : %d\n",
+ halmac_adapter->h2c_buf_free_space);
+
+ return HALMAC_RET_SUCCESS;
+}
diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b.h b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b.h
new file mode 100644
index 0000000..cf21e3d
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b.h
@@ -0,0 +1,44 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HALMAC_API_8822B_H_
+#define _HALMAC_API_8822B_H_
+
+#include "../../halmac_2_platform.h"
+#include "../../halmac_type.h"
+
+enum halmac_ret_status
+halmac_mount_api_8822b(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_init_trx_cfg_8822b(struct halmac_adapter *halmac_adapter,
+ enum halmac_trx_mode halmac_trx_mode);
+
+enum halmac_ret_status
+halmac_init_protocol_cfg_8822b(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_init_h2c_8822b(struct halmac_adapter *halmac_adapter);
+
+#endif /* _HALMAC_API_8822B_H_ */
diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_pcie.c b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_pcie.c
new file mode 100644
index 0000000..e25e2b0
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_pcie.c
@@ -0,0 +1,323 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#include "../halmac_88xx_cfg.h"
+#include "../halmac_api_88xx_pcie.h"
+#include "halmac_8822b_cfg.h"
+
+/**
+ * halmac_mac_power_switch_8822b_pcie() - switch mac power
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_power : power state
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_mac_power_switch_8822b_pcie(struct halmac_adapter *halmac_adapter,
+ enum halmac_mac_power halmac_power)
+{
+ u8 interface_mask;
+ u8 value8;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_MAC_POWER_SWITCH);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "halmac_mac_power_switch_88xx_pcie halmac_power = %x ==========>\n",
+ halmac_power);
+ interface_mask = HALMAC_PWR_INTF_PCI_MSK;
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_CR);
+ if (value8 == 0xEA)
+ halmac_adapter->halmac_state.mac_power = HALMAC_MAC_POWER_OFF;
+ else
+ halmac_adapter->halmac_state.mac_power = HALMAC_MAC_POWER_ON;
+
+ /* Check if power switch is needed */
+ if (halmac_power == HALMAC_MAC_POWER_ON &&
+ halmac_adapter->halmac_state.mac_power == HALMAC_MAC_POWER_ON) {
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_PWR, DBG_WARNING,
+ "halmac_mac_power_switch power state unchange!\n");
+ return HALMAC_RET_PWR_UNCHANGE;
+ }
+
+ if (halmac_power == HALMAC_MAC_POWER_OFF) {
+ if (halmac_pwr_seq_parser_88xx(
+ halmac_adapter, HALMAC_PWR_CUT_ALL_MSK,
+ HALMAC_PWR_FAB_TSMC_MSK, interface_mask,
+ halmac_8822b_card_disable_flow) !=
+ HALMAC_RET_SUCCESS) {
+ pr_err("Handle power off cmd error\n");
+ return HALMAC_RET_POWER_OFF_FAIL;
+ }
+
+ halmac_adapter->halmac_state.mac_power = HALMAC_MAC_POWER_OFF;
+ halmac_adapter->halmac_state.ps_state =
+ HALMAC_PS_STATE_UNDEFINE;
+ halmac_adapter->halmac_state.dlfw_state = HALMAC_DLFW_NONE;
+ halmac_init_adapter_dynamic_para_88xx(halmac_adapter);
+ } else {
+ if (halmac_pwr_seq_parser_88xx(
+ halmac_adapter, HALMAC_PWR_CUT_ALL_MSK,
+ HALMAC_PWR_FAB_TSMC_MSK, interface_mask,
+ halmac_8822b_card_enable_flow) !=
+ HALMAC_RET_SUCCESS) {
+ pr_err("Handle power on cmd error\n");
+ return HALMAC_RET_POWER_ON_FAIL;
+ }
+
+ halmac_adapter->halmac_state.mac_power = HALMAC_MAC_POWER_ON;
+ halmac_adapter->halmac_state.ps_state = HALMAC_PS_STATE_ACT;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "halmac_mac_power_switch_88xx_pcie <==========\n");
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_pcie_switch_8822b() - pcie gen1/gen2 switch
+ * @halmac_adapter : the adapter of halmac
+ * @pcie_cfg : gen1/gen2 selection
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_pcie_switch_8822b(struct halmac_adapter *halmac_adapter,
+ enum halmac_pcie_cfg pcie_cfg)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ u8 current_link_speed = 0;
+ u32 count = 0;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_PCIE_SWITCH);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ /* Link Control 2 Register[3:0] Target Link Speed
+ * Defined encodings are:
+ * 0001b Target Link 2.5 GT/s
+ * 0010b Target Link 5.0 GT/s
+ * 0100b Target Link 8.0 GT/s
+ */
+
+ if (pcie_cfg == HALMAC_PCIE_GEN1) {
+ /* cfg 0xA0[3:0]=4'b0001 */
+ halmac_dbi_write8_88xx(
+ halmac_adapter, LINK_CTRL2_REG_OFFSET,
+ (halmac_dbi_read8_88xx(halmac_adapter,
+ LINK_CTRL2_REG_OFFSET) &
+ 0xF0) | BIT(0));
+
+ /* cfg 0x80C[17]=1 //PCIe DesignWave */
+ halmac_dbi_write32_88xx(
+ halmac_adapter, GEN2_CTRL_OFFSET,
+ halmac_dbi_read32_88xx(halmac_adapter,
+ GEN2_CTRL_OFFSET) |
+ BIT(17));
+
+ /* check link speed if GEN1 */
+ /* cfg 0x82[3:0]=4'b0001 */
+ current_link_speed =
+ halmac_dbi_read8_88xx(halmac_adapter,
+ LINK_STATUS_REG_OFFSET) &
+ 0x0F;
+ count = 2000;
+
+ while (current_link_speed != GEN1_SPEED && count != 0) {
+ usleep_range(50, 60);
+ current_link_speed =
+ halmac_dbi_read8_88xx(halmac_adapter,
+ LINK_STATUS_REG_OFFSET) &
+ 0x0F;
+ count--;
+ }
+
+ if (current_link_speed != GEN1_SPEED) {
+ pr_err("Speed change to GEN1 fail !\n");
+ return HALMAC_RET_FAIL;
+ }
+
+ } else if (pcie_cfg == HALMAC_PCIE_GEN2) {
+ /* cfg 0xA0[3:0]=4'b0010 */
+ halmac_dbi_write8_88xx(
+ halmac_adapter, LINK_CTRL2_REG_OFFSET,
+ (halmac_dbi_read8_88xx(halmac_adapter,
+ LINK_CTRL2_REG_OFFSET) &
+ 0xF0) | BIT(1));
+
+ /* cfg 0x80C[17]=1 //PCIe DesignWave */
+ halmac_dbi_write32_88xx(
+ halmac_adapter, GEN2_CTRL_OFFSET,
+ halmac_dbi_read32_88xx(halmac_adapter,
+ GEN2_CTRL_OFFSET) |
+ BIT(17));
+
+ /* check link speed if GEN2 */
+ /* cfg 0x82[3:0]=4'b0010 */
+ current_link_speed =
+ halmac_dbi_read8_88xx(halmac_adapter,
+ LINK_STATUS_REG_OFFSET) &
+ 0x0F;
+ count = 2000;
+
+ while (current_link_speed != GEN2_SPEED && count != 0) {
+ usleep_range(50, 60);
+ current_link_speed =
+ halmac_dbi_read8_88xx(halmac_adapter,
+ LINK_STATUS_REG_OFFSET) &
+ 0x0F;
+ count--;
+ }
+
+ if (current_link_speed != GEN2_SPEED) {
+ pr_err("Speed change to GEN1 fail !\n");
+ return HALMAC_RET_FAIL;
+ }
+
+ } else {
+ pr_err("Error Speed !\n");
+ return HALMAC_RET_FAIL;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_pcie_switch_8822b_nc(struct halmac_adapter *halmac_adapter,
+ enum halmac_pcie_cfg pcie_cfg)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_PCIE_SWITCH);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_phy_cfg_8822b_pcie() - phy config
+ * @halmac_adapter : the adapter of halmac
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_phy_cfg_8822b_pcie(struct halmac_adapter *halmac_adapter,
+ enum halmac_intf_phy_platform platform)
+{
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_PHY_CFG);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "halmac_phy_cfg ==========>\n");
+
+ status = halmac_parse_intf_phy_88xx(halmac_adapter,
+ HALMAC_RTL8822B_PCIE_PHY_GEN1,
+ platform, HAL_INTF_PHY_PCIE_GEN1);
+
+ if (status != HALMAC_RET_SUCCESS)
+ return status;
+
+ status = halmac_parse_intf_phy_88xx(halmac_adapter,
+ HALMAC_RTL8822B_PCIE_PHY_GEN2,
+ platform, HAL_INTF_PHY_PCIE_GEN2);
+
+ if (status != HALMAC_RET_SUCCESS)
+ return status;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "halmac_phy_cfg <==========\n");
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_interface_integration_tuning_8822b_pcie() - pcie interface fine tuning
+ * @halmac_adapter : the adapter of halmac
+ * Author : Rick Liu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status halmac_interface_integration_tuning_8822b_pcie(
+ struct halmac_adapter *halmac_adapter)
+{
+ return HALMAC_RET_SUCCESS;
+}
diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_pcie.h b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_pcie.h
new file mode 100644
index 0000000..c68ea00
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_pcie.h
@@ -0,0 +1,53 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HALMAC_API_8822B_PCIE_H_
+#define _HALMAC_API_8822B_PCIE_H_
+
+#include "../../halmac_2_platform.h"
+#include "../../halmac_type.h"
+
+extern struct halmac_intf_phy_para_ HALMAC_RTL8822B_PCIE_PHY_GEN1[];
+extern struct halmac_intf_phy_para_ HALMAC_RTL8822B_PCIE_PHY_GEN2[];
+
+enum halmac_ret_status
+halmac_mac_power_switch_8822b_pcie(struct halmac_adapter *halmac_adapter,
+ enum halmac_mac_power halmac_power);
+
+enum halmac_ret_status
+halmac_pcie_switch_8822b(struct halmac_adapter *halmac_adapter,
+ enum halmac_pcie_cfg pcie_cfg);
+
+enum halmac_ret_status
+halmac_pcie_switch_8822b_nc(struct halmac_adapter *halmac_adapter,
+ enum halmac_pcie_cfg pcie_cfg);
+
+enum halmac_ret_status
+halmac_phy_cfg_8822b_pcie(struct halmac_adapter *halmac_adapter,
+ enum halmac_intf_phy_platform platform);
+
+enum halmac_ret_status halmac_interface_integration_tuning_8822b_pcie(
+ struct halmac_adapter *halmac_adapter);
+
+#endif /* _HALMAC_API_8822B_PCIE_H_ */
diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_sdio.c b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_sdio.c
new file mode 100644
index 0000000..4d708d8
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_sdio.c
@@ -0,0 +1,184 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#include "halmac_8822b_cfg.h"
+
+/**
+ * halmac_mac_power_switch_8822b_sdio() - switch mac power
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_power : power state
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_mac_power_switch_8822b_sdio(struct halmac_adapter *halmac_adapter,
+ enum halmac_mac_power halmac_power)
+{
+ u8 interface_mask;
+ u8 value8;
+ u8 rpwm;
+ u32 imr_backup;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "[TRACE]halmac_mac_power_switch_88xx_sdio==========>\n");
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "[TRACE]halmac_power = %x ==========>\n", halmac_power);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "[TRACE]8822B pwr seq ver = %s\n",
+ HALMAC_8822B_PWR_SEQ_VER);
+
+ interface_mask = HALMAC_PWR_INTF_SDIO_MSK;
+
+ halmac_adapter->rpwm_record =
+ HALMAC_REG_READ_8(halmac_adapter, REG_SDIO_HRPWM1);
+
+ /* Check FW still exist or not */
+ if (HALMAC_REG_READ_16(halmac_adapter, REG_MCUFW_CTRL) == 0xC078) {
+ /* Leave 32K */
+ rpwm = (u8)((halmac_adapter->rpwm_record ^ BIT(7)) & 0x80);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_SDIO_HRPWM1, rpwm);
+ }
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_CR);
+ if (value8 == 0xEA)
+ halmac_adapter->halmac_state.mac_power = HALMAC_MAC_POWER_OFF;
+ else
+ halmac_adapter->halmac_state.mac_power = HALMAC_MAC_POWER_ON;
+
+ /*Check if power switch is needed*/
+ if (halmac_power == HALMAC_MAC_POWER_ON &&
+ halmac_adapter->halmac_state.mac_power == HALMAC_MAC_POWER_ON) {
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_PWR, DBG_WARNING,
+ "[WARN]halmac_mac_power_switch power state unchange!\n");
+ return HALMAC_RET_PWR_UNCHANGE;
+ }
+
+ imr_backup = HALMAC_REG_READ_32(halmac_adapter, REG_SDIO_HIMR);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_SDIO_HIMR, 0);
+
+ if (halmac_power == HALMAC_MAC_POWER_OFF) {
+ if (halmac_pwr_seq_parser_88xx(
+ halmac_adapter, HALMAC_PWR_CUT_ALL_MSK,
+ HALMAC_PWR_FAB_TSMC_MSK, interface_mask,
+ halmac_8822b_card_disable_flow) !=
+ HALMAC_RET_SUCCESS) {
+ pr_err("[ERR]Handle power off cmd error\n");
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_SDIO_HIMR,
+ imr_backup);
+ return HALMAC_RET_POWER_OFF_FAIL;
+ }
+
+ halmac_adapter->halmac_state.mac_power = HALMAC_MAC_POWER_OFF;
+ halmac_adapter->halmac_state.ps_state =
+ HALMAC_PS_STATE_UNDEFINE;
+ halmac_adapter->halmac_state.dlfw_state = HALMAC_DLFW_NONE;
+ halmac_init_adapter_dynamic_para_88xx(halmac_adapter);
+ } else {
+ if (halmac_pwr_seq_parser_88xx(
+ halmac_adapter, HALMAC_PWR_CUT_ALL_MSK,
+ HALMAC_PWR_FAB_TSMC_MSK, interface_mask,
+ halmac_8822b_card_enable_flow) !=
+ HALMAC_RET_SUCCESS) {
+ pr_err("[ERR]Handle power on cmd error\n");
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_SDIO_HIMR,
+ imr_backup);
+ return HALMAC_RET_POWER_ON_FAIL;
+ }
+
+ halmac_adapter->halmac_state.mac_power = HALMAC_MAC_POWER_ON;
+ halmac_adapter->halmac_state.ps_state = HALMAC_PS_STATE_ACT;
+ }
+
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_SDIO_HIMR, imr_backup);
+
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "[TRACE]halmac_mac_power_switch_88xx_sdio <==========\n");
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_phy_cfg_8822b_sdio() - phy config
+ * @halmac_adapter : the adapter of halmac
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_phy_cfg_8822b_sdio(struct halmac_adapter *halmac_adapter,
+ enum halmac_intf_phy_platform platform)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_PHY_CFG);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "halmac_phy_cfg ==========>\n");
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "sdio no phy\n");
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "halmac_phy_cfg <==========\n");
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_interface_integration_tuning_8822b_sdio() - sdio interface fine tuning
+ * @halmac_adapter : the adapter of halmac
+ * Author : Ivan
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status halmac_interface_integration_tuning_8822b_sdio(
+ struct halmac_adapter *halmac_adapter)
+{
+ return HALMAC_RET_SUCCESS;
+}
diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_sdio.h b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_sdio.h
new file mode 100644
index 0000000..07ffb3b
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_sdio.h
@@ -0,0 +1,42 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HALMAC_API_8822B_SDIO_H_
+#define _HALMAC_API_8822B_SDIO_H_
+
+#include "../../halmac_2_platform.h"
+#include "../../halmac_type.h"
+
+enum halmac_ret_status
+halmac_mac_power_switch_8822b_sdio(struct halmac_adapter *halmac_adapter,
+ enum halmac_mac_power halmac_power);
+
+enum halmac_ret_status
+halmac_phy_cfg_8822b_sdio(struct halmac_adapter *halmac_adapter,
+ enum halmac_intf_phy_platform platform);
+
+enum halmac_ret_status halmac_interface_integration_tuning_8822b_sdio(
+ struct halmac_adapter *halmac_adapter);
+
+#endif /* _HALMAC_API_8822B_SDIO_H_ */
diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_usb.c b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_usb.c
new file mode 100644
index 0000000..5f27eb1
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_usb.c
@@ -0,0 +1,185 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#include "../halmac_88xx_cfg.h"
+#include "halmac_8822b_cfg.h"
+
+/**
+ * halmac_mac_power_switch_8822b_usb() - switch mac power
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_power : power state
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_mac_power_switch_8822b_usb(struct halmac_adapter *halmac_adapter,
+ enum halmac_mac_power halmac_power)
+{
+ u8 interface_mask;
+ u8 value8;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_MAC_POWER_SWITCH);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "halmac_mac_power_switch_88xx_usb halmac_power = %x ==========>\n",
+ halmac_power);
+
+ interface_mask = HALMAC_PWR_INTF_USB_MSK;
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_CR);
+ if (value8 == 0xEA) {
+ halmac_adapter->halmac_state.mac_power = HALMAC_MAC_POWER_OFF;
+ } else {
+ if (BIT(0) ==
+ (HALMAC_REG_READ_8(halmac_adapter, REG_SYS_STATUS1 + 1) &
+ BIT(0)))
+ halmac_adapter->halmac_state.mac_power =
+ HALMAC_MAC_POWER_OFF;
+ else
+ halmac_adapter->halmac_state.mac_power =
+ HALMAC_MAC_POWER_ON;
+ }
+
+ /*Check if power switch is needed*/
+ if (halmac_power == HALMAC_MAC_POWER_ON &&
+ halmac_adapter->halmac_state.mac_power == HALMAC_MAC_POWER_ON) {
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_PWR, DBG_WARNING,
+ "halmac_mac_power_switch power state unchange!\n");
+ return HALMAC_RET_PWR_UNCHANGE;
+ }
+ if (halmac_power == HALMAC_MAC_POWER_OFF) {
+ if (halmac_pwr_seq_parser_88xx(
+ halmac_adapter, HALMAC_PWR_CUT_ALL_MSK,
+ HALMAC_PWR_FAB_TSMC_MSK, interface_mask,
+ halmac_8822b_card_disable_flow) !=
+ HALMAC_RET_SUCCESS) {
+ pr_err("Handle power off cmd error\n");
+ return HALMAC_RET_POWER_OFF_FAIL;
+ }
+
+ halmac_adapter->halmac_state.mac_power = HALMAC_MAC_POWER_OFF;
+ halmac_adapter->halmac_state.ps_state =
+ HALMAC_PS_STATE_UNDEFINE;
+ halmac_adapter->halmac_state.dlfw_state = HALMAC_DLFW_NONE;
+ halmac_init_adapter_dynamic_para_88xx(halmac_adapter);
+ } else {
+ if (halmac_pwr_seq_parser_88xx(
+ halmac_adapter, HALMAC_PWR_CUT_ALL_MSK,
+ HALMAC_PWR_FAB_TSMC_MSK, interface_mask,
+ halmac_8822b_card_enable_flow) !=
+ HALMAC_RET_SUCCESS) {
+ pr_err("Handle power on cmd error\n");
+ return HALMAC_RET_POWER_ON_FAIL;
+ }
+
+ HALMAC_REG_WRITE_8(
+ halmac_adapter, REG_SYS_STATUS1 + 1,
+ HALMAC_REG_READ_8(halmac_adapter, REG_SYS_STATUS1 + 1) &
+ ~(BIT(0)));
+
+ halmac_adapter->halmac_state.mac_power = HALMAC_MAC_POWER_ON;
+ halmac_adapter->halmac_state.ps_state = HALMAC_PS_STATE_ACT;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "halmac_mac_power_switch_88xx_usb <==========\n");
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_phy_cfg_8822b_usb() - phy config
+ * @halmac_adapter : the adapter of halmac
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_phy_cfg_8822b_usb(struct halmac_adapter *halmac_adapter,
+ enum halmac_intf_phy_platform platform)
+{
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_PHY_CFG);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "halmac_phy_cfg ==========>\n");
+
+ status = halmac_parse_intf_phy_88xx(halmac_adapter,
+ HALMAC_RTL8822B_USB2_PHY, platform,
+ HAL_INTF_PHY_USB2);
+
+ if (status != HALMAC_RET_SUCCESS)
+ return status;
+
+ status = halmac_parse_intf_phy_88xx(halmac_adapter,
+ HALMAC_RTL8822B_USB3_PHY, platform,
+ HAL_INTF_PHY_USB3);
+
+ if (status != HALMAC_RET_SUCCESS)
+ return status;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "halmac_phy_cfg <==========\n");
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_interface_integration_tuning_8822b_usb() - usb interface fine tuning
+ * @halmac_adapter : the adapter of halmac
+ * Author : Ivan
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status halmac_interface_integration_tuning_8822b_usb(
+ struct halmac_adapter *halmac_adapter)
+{
+ return HALMAC_RET_SUCCESS;
+}
diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_usb.h b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_usb.h
new file mode 100644
index 0000000..3a99fd5
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_api_8822b_usb.h
@@ -0,0 +1,45 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HALMAC_API_8822B_USB_H_
+#define _HALMAC_API_8822B_USB_H_
+
+extern struct halmac_intf_phy_para_ HALMAC_RTL8822B_USB2_PHY[];
+extern struct halmac_intf_phy_para_ HALMAC_RTL8822B_USB3_PHY[];
+
+#include "../../halmac_2_platform.h"
+#include "../../halmac_type.h"
+
+enum halmac_ret_status
+halmac_mac_power_switch_8822b_usb(struct halmac_adapter *halmac_adapter,
+ enum halmac_mac_power halmac_power);
+
+enum halmac_ret_status
+halmac_phy_cfg_8822b_usb(struct halmac_adapter *halmac_adapter,
+ enum halmac_intf_phy_platform platform);
+
+enum halmac_ret_status halmac_interface_integration_tuning_8822b_usb(
+ struct halmac_adapter *halmac_adapter);
+
+#endif /* _HALMAC_API_8822B_USB_H_ */
diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_func_8822b.c b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_func_8822b.c
new file mode 100644
index 0000000..5f1dff8
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_func_8822b.c
@@ -0,0 +1,414 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#include "halmac_8822b_cfg.h"
+#include "halmac_func_8822b.h"
+
+/*SDIO RQPN Mapping*/
+static struct halmac_rqpn_ HALMAC_RQPN_SDIO_8822B[] = {
+ /* { mode, vo_map, vi_map, be_map, bk_map, mg_map, hi_map } */
+ {HALMAC_TRX_MODE_NORMAL, HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ,
+ HALMAC_MAP2_LQ, HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+ {HALMAC_TRX_MODE_TRXSHARE, HALMAC_MAP2_NQ, HALMAC_MAP2_NQ,
+ HALMAC_MAP2_LQ, HALMAC_MAP2_LQ, HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+ {HALMAC_TRX_MODE_WMM, HALMAC_MAP2_HQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ,
+ HALMAC_MAP2_NQ, HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+ {HALMAC_TRX_MODE_P2P, HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ,
+ HALMAC_MAP2_LQ, HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+ {HALMAC_TRX_MODE_LOOPBACK, HALMAC_MAP2_NQ, HALMAC_MAP2_NQ,
+ HALMAC_MAP2_LQ, HALMAC_MAP2_LQ, HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+ {HALMAC_TRX_MODE_DELAY_LOOPBACK, HALMAC_MAP2_NQ, HALMAC_MAP2_NQ,
+ HALMAC_MAP2_LQ, HALMAC_MAP2_LQ, HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+};
+
+/*PCIE RQPN Mapping*/
+static struct halmac_rqpn_ HALMAC_RQPN_PCIE_8822B[] = {
+ /* { mode, vo_map, vi_map, be_map, bk_map, mg_map, hi_map } */
+ {HALMAC_TRX_MODE_NORMAL, HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ,
+ HALMAC_MAP2_LQ, HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+ {HALMAC_TRX_MODE_TRXSHARE, HALMAC_MAP2_NQ, HALMAC_MAP2_NQ,
+ HALMAC_MAP2_LQ, HALMAC_MAP2_LQ, HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+ {HALMAC_TRX_MODE_WMM, HALMAC_MAP2_HQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ,
+ HALMAC_MAP2_NQ, HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+ {HALMAC_TRX_MODE_P2P, HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ,
+ HALMAC_MAP2_LQ, HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+ {HALMAC_TRX_MODE_LOOPBACK, HALMAC_MAP2_NQ, HALMAC_MAP2_NQ,
+ HALMAC_MAP2_LQ, HALMAC_MAP2_LQ, HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+ {HALMAC_TRX_MODE_DELAY_LOOPBACK, HALMAC_MAP2_NQ, HALMAC_MAP2_NQ,
+ HALMAC_MAP2_LQ, HALMAC_MAP2_LQ, HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+};
+
+/*USB 2 Bulkout RQPN Mapping*/
+static struct halmac_rqpn_ HALMAC_RQPN_2BULKOUT_8822B[] = {
+ /* { mode, vo_map, vi_map, be_map, bk_map, mg_map, hi_map } */
+ {HALMAC_TRX_MODE_NORMAL, HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_NQ,
+ HALMAC_MAP2_HQ, HALMAC_MAP2_HQ, HALMAC_MAP2_HQ},
+ {HALMAC_TRX_MODE_TRXSHARE, HALMAC_MAP2_NQ, HALMAC_MAP2_NQ,
+ HALMAC_MAP2_NQ, HALMAC_MAP2_HQ, HALMAC_MAP2_HQ, HALMAC_MAP2_HQ},
+ {HALMAC_TRX_MODE_WMM, HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_NQ,
+ HALMAC_MAP2_HQ, HALMAC_MAP2_HQ, HALMAC_MAP2_HQ},
+ {HALMAC_TRX_MODE_P2P, HALMAC_MAP2_HQ, HALMAC_MAP2_HQ, HALMAC_MAP2_HQ,
+ HALMAC_MAP2_NQ, HALMAC_MAP2_HQ, HALMAC_MAP2_HQ},
+ {HALMAC_TRX_MODE_LOOPBACK, HALMAC_MAP2_HQ, HALMAC_MAP2_HQ,
+ HALMAC_MAP2_HQ, HALMAC_MAP2_NQ, HALMAC_MAP2_HQ, HALMAC_MAP2_HQ},
+ {HALMAC_TRX_MODE_DELAY_LOOPBACK, HALMAC_MAP2_HQ, HALMAC_MAP2_HQ,
+ HALMAC_MAP2_HQ, HALMAC_MAP2_NQ, HALMAC_MAP2_HQ, HALMAC_MAP2_HQ},
+};
+
+/*USB 3 Bulkout RQPN Mapping*/
+static struct halmac_rqpn_ HALMAC_RQPN_3BULKOUT_8822B[] = {
+ /* { mode, vo_map, vi_map, be_map, bk_map, mg_map, hi_map } */
+ {HALMAC_TRX_MODE_NORMAL, HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ,
+ HALMAC_MAP2_LQ, HALMAC_MAP2_HQ, HALMAC_MAP2_HQ},
+ {HALMAC_TRX_MODE_TRXSHARE, HALMAC_MAP2_NQ, HALMAC_MAP2_NQ,
+ HALMAC_MAP2_LQ, HALMAC_MAP2_LQ, HALMAC_MAP2_HQ, HALMAC_MAP2_HQ},
+ {HALMAC_TRX_MODE_WMM, HALMAC_MAP2_HQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ,
+ HALMAC_MAP2_NQ, HALMAC_MAP2_HQ, HALMAC_MAP2_HQ},
+ {HALMAC_TRX_MODE_P2P, HALMAC_MAP2_HQ, HALMAC_MAP2_HQ, HALMAC_MAP2_LQ,
+ HALMAC_MAP2_NQ, HALMAC_MAP2_HQ, HALMAC_MAP2_HQ},
+ {HALMAC_TRX_MODE_LOOPBACK, HALMAC_MAP2_HQ, HALMAC_MAP2_HQ,
+ HALMAC_MAP2_LQ, HALMAC_MAP2_NQ, HALMAC_MAP2_HQ, HALMAC_MAP2_HQ},
+ {HALMAC_TRX_MODE_DELAY_LOOPBACK, HALMAC_MAP2_HQ, HALMAC_MAP2_HQ,
+ HALMAC_MAP2_LQ, HALMAC_MAP2_NQ, HALMAC_MAP2_HQ, HALMAC_MAP2_HQ},
+};
+
+/*USB 4 Bulkout RQPN Mapping*/
+static struct halmac_rqpn_ HALMAC_RQPN_4BULKOUT_8822B[] = {
+ /* { mode, vo_map, vi_map, be_map, bk_map, mg_map, hi_map } */
+ {HALMAC_TRX_MODE_NORMAL, HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ,
+ HALMAC_MAP2_LQ, HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+ {HALMAC_TRX_MODE_TRXSHARE, HALMAC_MAP2_NQ, HALMAC_MAP2_NQ,
+ HALMAC_MAP2_LQ, HALMAC_MAP2_LQ, HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+ {HALMAC_TRX_MODE_WMM, HALMAC_MAP2_HQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ,
+ HALMAC_MAP2_NQ, HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+ {HALMAC_TRX_MODE_P2P, HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ,
+ HALMAC_MAP2_LQ, HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+ {HALMAC_TRX_MODE_LOOPBACK, HALMAC_MAP2_NQ, HALMAC_MAP2_NQ,
+ HALMAC_MAP2_LQ, HALMAC_MAP2_LQ, HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+ {HALMAC_TRX_MODE_DELAY_LOOPBACK, HALMAC_MAP2_NQ, HALMAC_MAP2_NQ,
+ HALMAC_MAP2_LQ, HALMAC_MAP2_LQ, HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+};
+
+/*SDIO Page Number*/
+static struct halmac_pg_num_ HALMAC_PG_NUM_SDIO_8822B[] = {
+ /* { mode, hq_num, nq_num, lq_num, exq_num, gap_num} */
+ {HALMAC_TRX_MODE_NORMAL, 64, 64, 64, 64, 1},
+ {HALMAC_TRX_MODE_TRXSHARE, 32, 32, 32, 32, 1},
+ {HALMAC_TRX_MODE_WMM, 64, 64, 64, 64, 1},
+ {HALMAC_TRX_MODE_P2P, 64, 64, 64, 64, 1},
+ {HALMAC_TRX_MODE_LOOPBACK, 64, 64, 64, 64, 640},
+ {HALMAC_TRX_MODE_DELAY_LOOPBACK, 64, 64, 64, 64, 640},
+};
+
+/*PCIE Page Number*/
+static struct halmac_pg_num_ HALMAC_PG_NUM_PCIE_8822B[] = {
+ /* { mode, hq_num, nq_num, lq_num, exq_num, gap_num} */
+ {HALMAC_TRX_MODE_NORMAL, 64, 64, 64, 64, 1},
+ {HALMAC_TRX_MODE_TRXSHARE, 64, 64, 64, 64, 1},
+ {HALMAC_TRX_MODE_WMM, 64, 64, 64, 64, 1},
+ {HALMAC_TRX_MODE_P2P, 64, 64, 64, 64, 1},
+ {HALMAC_TRX_MODE_LOOPBACK, 64, 64, 64, 64, 640},
+ {HALMAC_TRX_MODE_DELAY_LOOPBACK, 64, 64, 64, 64, 640},
+};
+
+/*USB 2 Bulkout Page Number*/
+static struct halmac_pg_num_ HALMAC_PG_NUM_2BULKOUT_8822B[] = {
+ /* { mode, hq_num, nq_num, lq_num, exq_num, gap_num} */
+ {HALMAC_TRX_MODE_NORMAL, 64, 64, 0, 0, 1},
+ {HALMAC_TRX_MODE_TRXSHARE, 64, 64, 0, 0, 1},
+ {HALMAC_TRX_MODE_WMM, 64, 64, 0, 0, 1},
+ {HALMAC_TRX_MODE_P2P, 64, 64, 0, 0, 1},
+ {HALMAC_TRX_MODE_LOOPBACK, 64, 64, 0, 0, 1024},
+ {HALMAC_TRX_MODE_DELAY_LOOPBACK, 64, 64, 0, 0, 1024},
+};
+
+/*USB 3 Bulkout Page Number*/
+static struct halmac_pg_num_ HALMAC_PG_NUM_3BULKOUT_8822B[] = {
+ /* { mode, hq_num, nq_num, lq_num, exq_num, gap_num} */
+ {HALMAC_TRX_MODE_NORMAL, 64, 64, 64, 0, 1},
+ {HALMAC_TRX_MODE_TRXSHARE, 64, 64, 64, 0, 1},
+ {HALMAC_TRX_MODE_WMM, 64, 64, 64, 0, 1},
+ {HALMAC_TRX_MODE_P2P, 64, 64, 64, 0, 1},
+ {HALMAC_TRX_MODE_LOOPBACK, 64, 64, 64, 0, 1024},
+ {HALMAC_TRX_MODE_DELAY_LOOPBACK, 64, 64, 64, 0, 1024},
+};
+
+/*USB 4 Bulkout Page Number*/
+static struct halmac_pg_num_ HALMAC_PG_NUM_4BULKOUT_8822B[] = {
+ /* { mode, hq_num, nq_num, lq_num, exq_num, gap_num} */
+ {HALMAC_TRX_MODE_NORMAL, 64, 64, 64, 64, 1},
+ {HALMAC_TRX_MODE_TRXSHARE, 64, 64, 64, 64, 1},
+ {HALMAC_TRX_MODE_WMM, 64, 64, 64, 64, 1},
+ {HALMAC_TRX_MODE_P2P, 64, 64, 64, 64, 1},
+ {HALMAC_TRX_MODE_LOOPBACK, 64, 64, 64, 64, 640},
+ {HALMAC_TRX_MODE_DELAY_LOOPBACK, 64, 64, 64, 64, 640},
+};
+
+enum halmac_ret_status
+halmac_txdma_queue_mapping_8822b(struct halmac_adapter *halmac_adapter,
+ enum halmac_trx_mode halmac_trx_mode)
+{
+ u16 value16;
+ void *driver_adapter = NULL;
+ struct halmac_rqpn_ *curr_rqpn_sel = NULL;
+ enum halmac_ret_status status;
+ struct halmac_api *halmac_api;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
+ curr_rqpn_sel = HALMAC_RQPN_SDIO_8822B;
+ } else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_PCIE) {
+ curr_rqpn_sel = HALMAC_RQPN_PCIE_8822B;
+ } else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_USB) {
+ if (halmac_adapter->halmac_bulkout_num == 2) {
+ curr_rqpn_sel = HALMAC_RQPN_2BULKOUT_8822B;
+ } else if (halmac_adapter->halmac_bulkout_num == 3) {
+ curr_rqpn_sel = HALMAC_RQPN_3BULKOUT_8822B;
+ } else if (halmac_adapter->halmac_bulkout_num == 4) {
+ curr_rqpn_sel = HALMAC_RQPN_4BULKOUT_8822B;
+ } else {
+ pr_err("[ERR]interface not support\n");
+ return HALMAC_RET_NOT_SUPPORT;
+ }
+ } else {
+ return HALMAC_RET_NOT_SUPPORT;
+ }
+
+ status = halmac_rqpn_parser_88xx(halmac_adapter, halmac_trx_mode,
+ curr_rqpn_sel);
+ if (status != HALMAC_RET_SUCCESS)
+ return status;
+
+ value16 = 0;
+ value16 |= BIT_TXDMA_HIQ_MAP(
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_HI]);
+ value16 |= BIT_TXDMA_MGQ_MAP(
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_MG]);
+ value16 |= BIT_TXDMA_BKQ_MAP(
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BK]);
+ value16 |= BIT_TXDMA_BEQ_MAP(
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BE]);
+ value16 |= BIT_TXDMA_VIQ_MAP(
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VI]);
+ value16 |= BIT_TXDMA_VOQ_MAP(
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VO]);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_TXDMA_PQ_MAP, value16);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_priority_queue_config_8822b(struct halmac_adapter *halmac_adapter,
+ enum halmac_trx_mode halmac_trx_mode)
+{
+ u8 transfer_mode = 0;
+ u8 value8;
+ u32 counter;
+ enum halmac_ret_status status;
+ struct halmac_pg_num_ *curr_pg_num = NULL;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ if (halmac_adapter->txff_allocation.la_mode == HALMAC_LA_MODE_DISABLE) {
+ if (halmac_adapter->txff_allocation.rx_fifo_expanding_mode ==
+ HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE) {
+ halmac_adapter->txff_allocation.tx_fifo_pg_num =
+ HALMAC_TX_FIFO_SIZE_8822B >>
+ HALMAC_TX_PAGE_SIZE_2_POWER_8822B;
+ } else if (halmac_adapter->txff_allocation
+ .rx_fifo_expanding_mode ==
+ HALMAC_RX_FIFO_EXPANDING_MODE_1_BLOCK) {
+ halmac_adapter->txff_allocation.tx_fifo_pg_num =
+ HALMAC_TX_FIFO_SIZE_EX_1_BLK_8822B >>
+ HALMAC_TX_PAGE_SIZE_2_POWER_8822B;
+ halmac_adapter->hw_config_info.tx_fifo_size =
+ HALMAC_TX_FIFO_SIZE_EX_1_BLK_8822B;
+ if (HALMAC_RX_FIFO_SIZE_EX_1_BLK_8822B <=
+ HALMAC_RX_FIFO_SIZE_EX_1_BLK_MAX_8822B)
+ halmac_adapter->hw_config_info.rx_fifo_size =
+ HALMAC_RX_FIFO_SIZE_EX_1_BLK_8822B;
+ else
+ halmac_adapter->hw_config_info.rx_fifo_size =
+ HALMAC_RX_FIFO_SIZE_EX_1_BLK_MAX_8822B;
+ } else {
+ halmac_adapter->txff_allocation.tx_fifo_pg_num =
+ HALMAC_TX_FIFO_SIZE_8822B >>
+ HALMAC_TX_PAGE_SIZE_2_POWER_8822B;
+ pr_err("[ERR]rx_fifo_expanding_mode = %d not support\n",
+ halmac_adapter->txff_allocation
+ .rx_fifo_expanding_mode);
+ }
+ } else {
+ halmac_adapter->txff_allocation.tx_fifo_pg_num =
+ HALMAC_TX_FIFO_SIZE_LA_8822B >>
+ HALMAC_TX_PAGE_SIZE_2_POWER_8822B;
+ }
+ halmac_adapter->txff_allocation.rsvd_pg_num =
+ (halmac_adapter->txff_allocation.rsvd_drv_pg_num +
+ HALMAC_RSVD_H2C_EXTRAINFO_PGNUM_8822B +
+ HALMAC_RSVD_H2C_QUEUE_PGNUM_8822B +
+ HALMAC_RSVD_CPU_INSTRUCTION_PGNUM_8822B +
+ HALMAC_RSVD_FW_TXBUFF_PGNUM_8822B);
+ if (halmac_adapter->txff_allocation.rsvd_pg_num >
+ halmac_adapter->txff_allocation.tx_fifo_pg_num)
+ return HALMAC_RET_CFG_TXFIFO_PAGE_FAIL;
+
+ halmac_adapter->txff_allocation.ac_q_pg_num =
+ halmac_adapter->txff_allocation.tx_fifo_pg_num -
+ halmac_adapter->txff_allocation.rsvd_pg_num;
+ halmac_adapter->txff_allocation.rsvd_pg_bndy =
+ halmac_adapter->txff_allocation.tx_fifo_pg_num -
+ halmac_adapter->txff_allocation.rsvd_pg_num;
+ halmac_adapter->txff_allocation.rsvd_fw_txbuff_pg_bndy =
+ halmac_adapter->txff_allocation.tx_fifo_pg_num -
+ HALMAC_RSVD_FW_TXBUFF_PGNUM_8822B;
+ halmac_adapter->txff_allocation.rsvd_cpu_instr_pg_bndy =
+ halmac_adapter->txff_allocation.rsvd_fw_txbuff_pg_bndy -
+ HALMAC_RSVD_CPU_INSTRUCTION_PGNUM_8822B;
+ halmac_adapter->txff_allocation.rsvd_h2c_queue_pg_bndy =
+ halmac_adapter->txff_allocation.rsvd_cpu_instr_pg_bndy -
+ HALMAC_RSVD_H2C_QUEUE_PGNUM_8822B;
+ halmac_adapter->txff_allocation.rsvd_h2c_extra_info_pg_bndy =
+ halmac_adapter->txff_allocation.rsvd_h2c_queue_pg_bndy -
+ HALMAC_RSVD_H2C_EXTRAINFO_PGNUM_8822B;
+ halmac_adapter->txff_allocation.rsvd_drv_pg_bndy =
+ halmac_adapter->txff_allocation.rsvd_h2c_extra_info_pg_bndy -
+ halmac_adapter->txff_allocation.rsvd_drv_pg_num;
+
+ if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
+ curr_pg_num = HALMAC_PG_NUM_SDIO_8822B;
+ } else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_PCIE) {
+ curr_pg_num = HALMAC_PG_NUM_PCIE_8822B;
+ } else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_USB) {
+ if (halmac_adapter->halmac_bulkout_num == 2) {
+ curr_pg_num = HALMAC_PG_NUM_2BULKOUT_8822B;
+ } else if (halmac_adapter->halmac_bulkout_num == 3) {
+ curr_pg_num = HALMAC_PG_NUM_3BULKOUT_8822B;
+ } else if (halmac_adapter->halmac_bulkout_num == 4) {
+ curr_pg_num = HALMAC_PG_NUM_4BULKOUT_8822B;
+ } else {
+ pr_err("[ERR]interface not support\n");
+ return HALMAC_RET_NOT_SUPPORT;
+ }
+ } else {
+ return HALMAC_RET_NOT_SUPPORT;
+ }
+
+ status = halmac_pg_num_parser_88xx(halmac_adapter, halmac_trx_mode,
+ curr_pg_num);
+ if (status != HALMAC_RET_SUCCESS)
+ return status;
+
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_INFO_1,
+ halmac_adapter->txff_allocation.high_queue_pg_num);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_INFO_2,
+ halmac_adapter->txff_allocation.low_queue_pg_num);
+ HALMAC_REG_WRITE_16(
+ halmac_adapter, REG_FIFOPAGE_INFO_3,
+ halmac_adapter->txff_allocation.normal_queue_pg_num);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_INFO_4,
+ halmac_adapter->txff_allocation.extra_queue_pg_num);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_INFO_5,
+ halmac_adapter->txff_allocation.pub_queue_pg_num);
+
+ halmac_adapter->sdio_free_space.high_queue_number =
+ halmac_adapter->txff_allocation.high_queue_pg_num;
+ halmac_adapter->sdio_free_space.normal_queue_number =
+ halmac_adapter->txff_allocation.normal_queue_pg_num;
+ halmac_adapter->sdio_free_space.low_queue_number =
+ halmac_adapter->txff_allocation.low_queue_pg_num;
+ halmac_adapter->sdio_free_space.public_queue_number =
+ halmac_adapter->txff_allocation.pub_queue_pg_num;
+ halmac_adapter->sdio_free_space.extra_queue_number =
+ halmac_adapter->txff_allocation.extra_queue_pg_num;
+
+ HALMAC_REG_WRITE_32(
+ halmac_adapter, REG_RQPN_CTRL_2,
+ HALMAC_REG_READ_32(halmac_adapter, REG_RQPN_CTRL_2) | BIT(31));
+
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
+ (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
+ BIT_MASK_BCN_HEAD_1_V1));
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_BCNQ_BDNY_V1,
+ (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
+ BIT_MASK_BCNQ_PGBNDY_V1));
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2 + 2,
+ (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
+ BIT_MASK_BCN_HEAD_1_V1));
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_BCNQ1_BDNY_V1,
+ (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
+ BIT_MASK_BCNQ_PGBNDY_V1));
+
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_RXFF_BNDY,
+ halmac_adapter->hw_config_info.rx_fifo_size -
+ HALMAC_C2H_PKT_BUF_8822B - 1);
+
+ if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_USB) {
+ value8 = (u8)(
+ HALMAC_REG_READ_8(halmac_adapter, REG_AUTO_LLT_V1) &
+ ~(BIT_MASK_BLK_DESC_NUM << BIT_SHIFT_BLK_DESC_NUM));
+ value8 = (u8)(value8 | (HALMAC_BLK_DESC_NUM_8822B
+ << BIT_SHIFT_BLK_DESC_NUM));
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_AUTO_LLT_V1, value8);
+
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_AUTO_LLT_V1 + 3,
+ HALMAC_BLK_DESC_NUM_8822B);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_TXDMA_OFFSET_CHK + 1,
+ HALMAC_REG_READ_8(halmac_adapter,
+ REG_TXDMA_OFFSET_CHK + 1) |
+ BIT(1));
+ }
+
+ HALMAC_REG_WRITE_8(
+ halmac_adapter, REG_AUTO_LLT_V1,
+ (u8)(HALMAC_REG_READ_8(halmac_adapter, REG_AUTO_LLT_V1) |
+ BIT_AUTO_INIT_LLT_V1));
+ counter = 1000;
+ while (HALMAC_REG_READ_8(halmac_adapter, REG_AUTO_LLT_V1) &
+ BIT_AUTO_INIT_LLT_V1) {
+ counter--;
+ if (counter == 0)
+ return HALMAC_RET_INIT_LLT_FAIL;
+ }
+
+ if (halmac_trx_mode == HALMAC_TRX_MODE_DELAY_LOOPBACK) {
+ transfer_mode = HALMAC_TRNSFER_LOOPBACK_DELAY;
+ HALMAC_REG_WRITE_16(
+ halmac_adapter, REG_WMAC_LBK_BUF_HD_V1,
+ (u16)halmac_adapter->txff_allocation.rsvd_pg_bndy);
+ } else if (halmac_trx_mode == HALMAC_TRX_MODE_LOOPBACK) {
+ transfer_mode = HALMAC_TRNSFER_LOOPBACK_DIRECT;
+ } else {
+ transfer_mode = HALMAC_TRNSFER_NORMAL;
+ }
+
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_CR + 3, (u8)transfer_mode);
+
+ return HALMAC_RET_SUCCESS;
+}
diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_func_8822b.h b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_func_8822b.h
new file mode 100644
index 0000000..5ac2b15
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_func_8822b.h
@@ -0,0 +1,38 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HALMAC_FUNC_8822B_H_
+#define _HALMAC_FUNC_8822B_H_
+
+#include "../../halmac_type.h"
+
+enum halmac_ret_status
+halmac_txdma_queue_mapping_8822b(struct halmac_adapter *halmac_adapter,
+ enum halmac_trx_mode halmac_trx_mode);
+
+enum halmac_ret_status
+halmac_priority_queue_config_8822b(struct halmac_adapter *halmac_adapter,
+ enum halmac_trx_mode halmac_trx_mode);
+
+#endif /* _HALMAC_FUNC_8822B_H_ */
diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_88xx_cfg.h b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_88xx_cfg.h
new file mode 100644
index 0000000..ea12067
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_88xx_cfg.h
@@ -0,0 +1,171 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HALMAC_88XX_CFG_H_
+#define _HALMAC_88XX_CFG_H_
+
+#include "../halmac_2_platform.h"
+#include "../halmac_type.h"
+#include "../halmac_api.h"
+#include "../halmac_bit2.h"
+#include "../halmac_reg2.h"
+#include "../halmac_pwr_seq_cmd.h"
+#include "halmac_func_88xx.h"
+#include "halmac_api_88xx.h"
+#include "halmac_api_88xx_usb.h"
+#include "halmac_api_88xx_pcie.h"
+#include "halmac_api_88xx_sdio.h"
+
+#define HALMAC_SVN_VER_88XX "13359M"
+
+#define HALMAC_MAJOR_VER_88XX 0x0001 /* major version, ver_1 for async_api */
+/* For halmac_api num change or prototype change, increment prototype version.
+ * Otherwise, increase minor version
+ */
+#define HALMAC_PROTOTYPE_VER_88XX 0x0003 /* prototype version */
+#define HALMAC_MINOR_VER_88XX 0x0005 /* minor version */
+#define HALMAC_PATCH_VER_88XX 0x0000 /* patch version */
+
+#define HALMAC_C2H_DATA_OFFSET_88XX 10
+#define HALMAC_RX_AGG_ALIGNMENT_SIZE_88XX 8
+#define HALMAC_TX_AGG_ALIGNMENT_SIZE_88XX 8
+#define HALMAC_TX_AGG_BUFF_SIZE_88XX 32768
+
+#define HALMAC_EXTRA_INFO_BUFF_SIZE_88XX 4096 /*4K*/
+#define HALMAC_EXTRA_INFO_BUFF_SIZE_FULL_FIFO_88XX 16384 /*16K*/
+#define HALMAC_FW_OFFLOAD_CMD_SIZE_88XX \
+ 12 /*Fw config parameter cmd size, each 12 byte*/
+
+#define HALMAC_H2C_CMD_ORIGINAL_SIZE_88XX 8
+#define HALMAC_H2C_CMD_SIZE_UNIT_88XX 32 /* Only support 32 byte packet now */
+
+#define HALMAC_NLO_INFO_SIZE_88XX 1024
+
+/* Download FW */
+#define HALMAC_FW_SIZE_MAX_88XX 0x40000
+#define HALMAC_FWHDR_SIZE_88XX 64
+#define HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX 8
+#define HALMAC_FW_MAX_DL_SIZE_88XX 0x2000 /* need power of 2 */
+/* Max dlfw size can not over 31K, because SDIO HW restriction */
+#define HALMAC_FW_CFG_MAX_DL_SIZE_MAX_88XX 0x7C00
+
+#define DLFW_RESTORE_REG_NUM_88XX 9
+#define ID_INFORM_DLEMEM_RDY 0x80
+
+/* FW header information */
+#define HALMAC_FWHDR_OFFSET_VERSION_88XX 4
+#define HALMAC_FWHDR_OFFSET_SUBVERSION_88XX 6
+#define HALMAC_FWHDR_OFFSET_SUBINDEX_88XX 7
+#define HALMAC_FWHDR_OFFSET_MEM_USAGE_88XX 24
+#define HALMAC_FWHDR_OFFSET_H2C_FORMAT_VER_88XX 28
+#define HALMAC_FWHDR_OFFSET_DMEM_ADDR_88XX 32
+#define HALMAC_FWHDR_OFFSET_DMEM_SIZE_88XX 36
+#define HALMAC_FWHDR_OFFSET_IRAM_SIZE_88XX 48
+#define HALMAC_FWHDR_OFFSET_ERAM_SIZE_88XX 52
+#define HALMAC_FWHDR_OFFSET_EMEM_ADDR_88XX 56
+#define HALMAC_FWHDR_OFFSET_IRAM_ADDR_88XX 60
+
+/* HW memory address */
+#define HALMAC_OCPBASE_TXBUF_88XX 0x18780000
+#define HALMAC_OCPBASE_DMEM_88XX 0x00200000
+#define HALMAC_OCPBASE_IMEM_88XX 0x00000000
+
+/* define the SDIO Bus CLK threshold, for avoiding CMD53 fails that
+ * result from SDIO CLK sync to ana_clk fail
+ */
+#define HALMAC_SD_CLK_THRESHOLD_88XX 150000000 /* 150MHz */
+
+/* MAC clock */
+#define HALMAC_MAC_CLOCK_88XX 80 /* 80M */
+
+/* H2C/C2H*/
+#define HALMAC_H2C_CMD_SIZE_88XX 32
+#define HALMAC_H2C_CMD_HDR_SIZE_88XX 8
+
+#define HALMAC_PROTECTED_EFUSE_SIZE_88XX 0x60
+
+/* Function enable */
+#define HALMAC_FUNCTION_ENABLE_88XX 0xDC
+
+/* FIFO size & packet size */
+/* #define HALMAC_WOWLAN_PATTERN_SIZE 256 */
+
+/* CFEND rate */
+#define HALMAC_BASIC_CFEND_RATE_88XX 0x5
+#define HALMAC_STBC_CFEND_RATE_88XX 0xF
+
+/* Response rate */
+#define HALMAC_RESPONSE_RATE_BITMAP_ALL_88XX 0xFFFFF
+#define HALMAC_RESPONSE_RATE_88XX HALMAC_RESPONSE_RATE_BITMAP_ALL_88XX
+
+/* Spec SIFS */
+#define HALMAC_SIFS_CCK_PTCL_88XX 16
+#define HALMAC_SIFS_OFDM_PTCL_88XX 16
+
+/* Retry limit */
+#define HALMAC_LONG_RETRY_LIMIT_88XX 8
+#define HALMAC_SHORT_RETRY_LIMIT_88XX 7
+
+/* Slot, SIFS, PIFS time */
+#define HALMAC_SLOT_TIME_88XX 0x05
+#define HALMAC_PIFS_TIME_88XX 0x19
+#define HALMAC_SIFS_CCK_CTX_88XX 0xA
+#define HALMAC_SIFS_OFDM_CTX_88XX 0xA
+#define HALMAC_SIFS_CCK_TRX_88XX 0x10
+#define HALMAC_SIFS_OFDM_TRX_88XX 0x10
+
+/* TXOP limit */
+#define HALMAC_VO_TXOP_LIMIT_88XX 0x186
+#define HALMAC_VI_TXOP_LIMIT_88XX 0x3BC
+
+/* NAV */
+#define HALMAC_RDG_NAV_88XX 0x05
+#define HALMAC_TXOP_NAV_88XX 0x1B
+
+/* TSF */
+#define HALMAC_CCK_RX_TSF_88XX 0x30
+#define HALMAC_OFDM_RX_TSF_88XX 0x30
+
+/* Send beacon related */
+#define HALMAC_TBTT_PROHIBIT_88XX 0x04
+#define HALMAC_TBTT_HOLD_TIME_88XX 0x064
+#define HALMAC_DRIVER_EARLY_INT_88XX 0x04
+#define HALMAC_BEACON_DMA_TIM_88XX 0x02
+
+/* RX filter */
+#define HALMAC_RX_FILTER0_RECIVE_ALL_88XX 0xFFFFFFF
+#define HALMAC_RX_FILTER0_88XX HALMAC_RX_FILTER0_RECIVE_ALL_88XX
+#define HALMAC_RX_FILTER_RECIVE_ALL_88XX 0xFFFF
+#define HALMAC_RX_FILTER_88XX HALMAC_RX_FILTER_RECIVE_ALL_88XX
+
+/* RCR */
+#define HALMAC_RCR_CONFIG_88XX 0xE400631E
+
+/* Security config */
+#define HALMAC_SECURITY_CONFIG_88XX 0x01CC
+
+/* CCK rate ACK timeout */
+#define HALMAC_ACK_TO_CCK_88XX 0x40
+
+#endif
diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx.c b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx.c
new file mode 100644
index 0000000..5f84526
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx.c
@@ -0,0 +1,5979 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#include "halmac_88xx_cfg.h"
+
+/**
+ * halmac_init_adapter_para_88xx() - int halmac adapter
+ * @halmac_adapter
+ *
+ * SD1 internal use
+ *
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : void
+ */
+void halmac_init_adapter_para_88xx(struct halmac_adapter *halmac_adapter)
+{
+ halmac_adapter->api_record.array_wptr = 0;
+ halmac_adapter->hal_adapter_backup = halmac_adapter;
+ halmac_adapter->hal_efuse_map = (u8 *)NULL;
+ halmac_adapter->hal_efuse_map_valid = false;
+ halmac_adapter->efuse_end = 0;
+ halmac_adapter->hal_mac_addr[0].address_l_h.address_low = 0;
+ halmac_adapter->hal_mac_addr[0].address_l_h.address_high = 0;
+ halmac_adapter->hal_mac_addr[1].address_l_h.address_low = 0;
+ halmac_adapter->hal_mac_addr[1].address_l_h.address_high = 0;
+ halmac_adapter->hal_bss_addr[0].address_l_h.address_low = 0;
+ halmac_adapter->hal_bss_addr[0].address_l_h.address_high = 0;
+ halmac_adapter->hal_bss_addr[1].address_l_h.address_low = 0;
+ halmac_adapter->hal_bss_addr[1].address_l_h.address_high = 0;
+
+ halmac_adapter->low_clk = false;
+ halmac_adapter->max_download_size = HALMAC_FW_MAX_DL_SIZE_88XX;
+
+ /* Init LPS Option */
+ halmac_adapter->fwlps_option.mode = 0x01; /*0:Active 1:LPS 2:WMMPS*/
+ halmac_adapter->fwlps_option.awake_interval = 1;
+ halmac_adapter->fwlps_option.enter_32K = 1;
+ halmac_adapter->fwlps_option.clk_request = 0;
+ halmac_adapter->fwlps_option.rlbm = 0;
+ halmac_adapter->fwlps_option.smart_ps = 0;
+ halmac_adapter->fwlps_option.awake_interval = 1;
+ halmac_adapter->fwlps_option.all_queue_uapsd = 0;
+ halmac_adapter->fwlps_option.pwr_state = 0;
+ halmac_adapter->fwlps_option.low_pwr_rx_beacon = 0;
+ halmac_adapter->fwlps_option.ant_auto_switch = 0;
+ halmac_adapter->fwlps_option.ps_allow_bt_high_priority = 0;
+ halmac_adapter->fwlps_option.protect_bcn = 0;
+ halmac_adapter->fwlps_option.silence_period = 0;
+ halmac_adapter->fwlps_option.fast_bt_connect = 0;
+ halmac_adapter->fwlps_option.two_antenna_en = 0;
+ halmac_adapter->fwlps_option.adopt_user_setting = 1;
+ halmac_adapter->fwlps_option.drv_bcn_early_shift = 0;
+
+ halmac_adapter->config_para_info.cfg_para_buf = NULL;
+ halmac_adapter->config_para_info.para_buf_w = NULL;
+ halmac_adapter->config_para_info.para_num = 0;
+ halmac_adapter->config_para_info.full_fifo_mode = false;
+ halmac_adapter->config_para_info.para_buf_size = 0;
+ halmac_adapter->config_para_info.avai_para_buf_size = 0;
+ halmac_adapter->config_para_info.offset_accumulation = 0;
+ halmac_adapter->config_para_info.value_accumulation = 0;
+ halmac_adapter->config_para_info.datapack_segment = 0;
+
+ halmac_adapter->ch_sw_info.ch_info_buf = NULL;
+ halmac_adapter->ch_sw_info.ch_info_buf_w = NULL;
+ halmac_adapter->ch_sw_info.extra_info_en = 0;
+ halmac_adapter->ch_sw_info.buf_size = 0;
+ halmac_adapter->ch_sw_info.avai_buf_size = 0;
+ halmac_adapter->ch_sw_info.total_size = 0;
+ halmac_adapter->ch_sw_info.ch_num = 0;
+
+ halmac_adapter->drv_info_size = 0;
+
+ memset(halmac_adapter->api_record.api_array, HALMAC_API_STUFF,
+ sizeof(halmac_adapter->api_record.api_array));
+
+ halmac_adapter->txff_allocation.tx_fifo_pg_num = 0;
+ halmac_adapter->txff_allocation.ac_q_pg_num = 0;
+ halmac_adapter->txff_allocation.rsvd_pg_bndy = 0;
+ halmac_adapter->txff_allocation.rsvd_drv_pg_bndy = 0;
+ halmac_adapter->txff_allocation.rsvd_h2c_extra_info_pg_bndy = 0;
+ halmac_adapter->txff_allocation.rsvd_h2c_queue_pg_bndy = 0;
+ halmac_adapter->txff_allocation.rsvd_cpu_instr_pg_bndy = 0;
+ halmac_adapter->txff_allocation.rsvd_fw_txbuff_pg_bndy = 0;
+ halmac_adapter->txff_allocation.pub_queue_pg_num = 0;
+ halmac_adapter->txff_allocation.high_queue_pg_num = 0;
+ halmac_adapter->txff_allocation.low_queue_pg_num = 0;
+ halmac_adapter->txff_allocation.normal_queue_pg_num = 0;
+ halmac_adapter->txff_allocation.extra_queue_pg_num = 0;
+
+ halmac_adapter->txff_allocation.la_mode = HALMAC_LA_MODE_DISABLE;
+ halmac_adapter->txff_allocation.rx_fifo_expanding_mode =
+ HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE;
+
+ halmac_init_adapter_dynamic_para_88xx(halmac_adapter);
+ halmac_init_state_machine_88xx(halmac_adapter);
+}
+
+/**
+ * halmac_init_adapter_dynamic_para_88xx() - int halmac adapter
+ * @halmac_adapter
+ *
+ * SD1 internal use
+ *
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : void
+ */
+void halmac_init_adapter_dynamic_para_88xx(
+ struct halmac_adapter *halmac_adapter)
+{
+ halmac_adapter->h2c_packet_seq = 0;
+ halmac_adapter->h2c_buf_free_space = 0;
+ halmac_adapter->gen_info_valid = false;
+}
+
+/**
+ * halmac_init_state_machine_88xx() - init halmac software state machine
+ * @halmac_adapter
+ *
+ * SD1 internal use.
+ *
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : void
+ */
+void halmac_init_state_machine_88xx(struct halmac_adapter *halmac_adapter)
+{
+ struct halmac_state *state = &halmac_adapter->halmac_state;
+
+ halmac_init_offload_feature_state_machine_88xx(halmac_adapter);
+
+ state->api_state = HALMAC_API_STATE_INIT;
+
+ state->dlfw_state = HALMAC_DLFW_NONE;
+ state->mac_power = HALMAC_MAC_POWER_OFF;
+ state->ps_state = HALMAC_PS_STATE_UNDEFINE;
+}
+
+/**
+ * halmac_mount_api_88xx() - attach functions to function pointer
+ * @halmac_adapter
+ *
+ * SD1 internal use
+ *
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ */
+enum halmac_ret_status
+halmac_mount_api_88xx(struct halmac_adapter *halmac_adapter)
+{
+ void *driver_adapter = halmac_adapter->driver_adapter;
+ struct halmac_api *halmac_api = (struct halmac_api *)NULL;
+
+ halmac_adapter->halmac_api =
+ kzalloc(sizeof(struct halmac_api), GFP_KERNEL);
+ if (!halmac_adapter->halmac_api)
+ return HALMAC_RET_MALLOC_FAIL;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ HALMAC_SVN_VER_88XX "\n");
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "HALMAC_MAJOR_VER_88XX = %x\n", HALMAC_MAJOR_VER_88XX);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "HALMAC_PROTOTYPE_88XX = %x\n",
+ HALMAC_PROTOTYPE_VER_88XX);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "HALMAC_MINOR_VER_88XX = %x\n", HALMAC_MINOR_VER_88XX);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "HALMAC_PATCH_VER_88XX = %x\n", HALMAC_PATCH_VER_88XX);
+
+ /* Mount function pointer */
+ halmac_api->halmac_download_firmware = halmac_download_firmware_88xx;
+ halmac_api->halmac_free_download_firmware =
+ halmac_free_download_firmware_88xx;
+ halmac_api->halmac_get_fw_version = halmac_get_fw_version_88xx;
+ halmac_api->halmac_cfg_mac_addr = halmac_cfg_mac_addr_88xx;
+ halmac_api->halmac_cfg_bssid = halmac_cfg_bssid_88xx;
+ halmac_api->halmac_cfg_multicast_addr = halmac_cfg_multicast_addr_88xx;
+ halmac_api->halmac_pre_init_system_cfg =
+ halmac_pre_init_system_cfg_88xx;
+ halmac_api->halmac_init_system_cfg = halmac_init_system_cfg_88xx;
+ halmac_api->halmac_init_edca_cfg = halmac_init_edca_cfg_88xx;
+ halmac_api->halmac_cfg_operation_mode = halmac_cfg_operation_mode_88xx;
+ halmac_api->halmac_cfg_ch_bw = halmac_cfg_ch_bw_88xx;
+ halmac_api->halmac_cfg_bw = halmac_cfg_bw_88xx;
+ halmac_api->halmac_init_wmac_cfg = halmac_init_wmac_cfg_88xx;
+ halmac_api->halmac_init_mac_cfg = halmac_init_mac_cfg_88xx;
+ halmac_api->halmac_init_sdio_cfg = halmac_init_sdio_cfg_88xx;
+ halmac_api->halmac_init_usb_cfg = halmac_init_usb_cfg_88xx;
+ halmac_api->halmac_init_pcie_cfg = halmac_init_pcie_cfg_88xx;
+ halmac_api->halmac_deinit_sdio_cfg = halmac_deinit_sdio_cfg_88xx;
+ halmac_api->halmac_deinit_usb_cfg = halmac_deinit_usb_cfg_88xx;
+ halmac_api->halmac_deinit_pcie_cfg = halmac_deinit_pcie_cfg_88xx;
+ halmac_api->halmac_dump_efuse_map = halmac_dump_efuse_map_88xx;
+ halmac_api->halmac_dump_efuse_map_bt = halmac_dump_efuse_map_bt_88xx;
+ halmac_api->halmac_write_efuse_bt = halmac_write_efuse_bt_88xx;
+ halmac_api->halmac_dump_logical_efuse_map =
+ halmac_dump_logical_efuse_map_88xx;
+ halmac_api->halmac_pg_efuse_by_map = halmac_pg_efuse_by_map_88xx;
+ halmac_api->halmac_get_efuse_size = halmac_get_efuse_size_88xx;
+ halmac_api->halmac_get_efuse_available_size =
+ halmac_get_efuse_available_size_88xx;
+ halmac_api->halmac_get_c2h_info = halmac_get_c2h_info_88xx;
+
+ halmac_api->halmac_get_logical_efuse_size =
+ halmac_get_logical_efuse_size_88xx;
+
+ halmac_api->halmac_write_logical_efuse =
+ halmac_write_logical_efuse_88xx;
+ halmac_api->halmac_read_logical_efuse = halmac_read_logical_efuse_88xx;
+
+ halmac_api->halmac_cfg_fwlps_option = halmac_cfg_fwlps_option_88xx;
+ halmac_api->halmac_cfg_fwips_option = halmac_cfg_fwips_option_88xx;
+ halmac_api->halmac_enter_wowlan = halmac_enter_wowlan_88xx;
+ halmac_api->halmac_leave_wowlan = halmac_leave_wowlan_88xx;
+ halmac_api->halmac_enter_ps = halmac_enter_ps_88xx;
+ halmac_api->halmac_leave_ps = halmac_leave_ps_88xx;
+ halmac_api->halmac_h2c_lb = halmac_h2c_lb_88xx;
+ halmac_api->halmac_debug = halmac_debug_88xx;
+ halmac_api->halmac_cfg_parameter = halmac_cfg_parameter_88xx;
+ halmac_api->halmac_update_datapack = halmac_update_datapack_88xx;
+ halmac_api->halmac_run_datapack = halmac_run_datapack_88xx;
+ halmac_api->halmac_cfg_drv_info = halmac_cfg_drv_info_88xx;
+ halmac_api->halmac_send_bt_coex = halmac_send_bt_coex_88xx;
+ halmac_api->halmac_verify_platform_api =
+ halmac_verify_platform_api_88xx;
+ halmac_api->halmac_update_packet = halmac_update_packet_88xx;
+ halmac_api->halmac_bcn_ie_filter = halmac_bcn_ie_filter_88xx;
+ halmac_api->halmac_cfg_txbf = halmac_cfg_txbf_88xx;
+ halmac_api->halmac_cfg_mumimo = halmac_cfg_mumimo_88xx;
+ halmac_api->halmac_cfg_sounding = halmac_cfg_sounding_88xx;
+ halmac_api->halmac_del_sounding = halmac_del_sounding_88xx;
+ halmac_api->halmac_su_bfer_entry_init = halmac_su_bfer_entry_init_88xx;
+ halmac_api->halmac_su_bfee_entry_init = halmac_su_bfee_entry_init_88xx;
+ halmac_api->halmac_mu_bfer_entry_init = halmac_mu_bfer_entry_init_88xx;
+ halmac_api->halmac_mu_bfee_entry_init = halmac_mu_bfee_entry_init_88xx;
+ halmac_api->halmac_su_bfer_entry_del = halmac_su_bfer_entry_del_88xx;
+ halmac_api->halmac_su_bfee_entry_del = halmac_su_bfee_entry_del_88xx;
+ halmac_api->halmac_mu_bfer_entry_del = halmac_mu_bfer_entry_del_88xx;
+ halmac_api->halmac_mu_bfee_entry_del = halmac_mu_bfee_entry_del_88xx;
+
+ halmac_api->halmac_add_ch_info = halmac_add_ch_info_88xx;
+ halmac_api->halmac_add_extra_ch_info = halmac_add_extra_ch_info_88xx;
+ halmac_api->halmac_ctrl_ch_switch = halmac_ctrl_ch_switch_88xx;
+ halmac_api->halmac_p2pps = halmac_p2pps_88xx;
+ halmac_api->halmac_clear_ch_info = halmac_clear_ch_info_88xx;
+ halmac_api->halmac_send_general_info = halmac_send_general_info_88xx;
+
+ halmac_api->halmac_start_iqk = halmac_start_iqk_88xx;
+ halmac_api->halmac_ctrl_pwr_tracking = halmac_ctrl_pwr_tracking_88xx;
+ halmac_api->halmac_psd = halmac_psd_88xx;
+ halmac_api->halmac_cfg_la_mode = halmac_cfg_la_mode_88xx;
+ halmac_api->halmac_cfg_rx_fifo_expanding_mode =
+ halmac_cfg_rx_fifo_expanding_mode_88xx;
+
+ halmac_api->halmac_config_security = halmac_config_security_88xx;
+ halmac_api->halmac_get_used_cam_entry_num =
+ halmac_get_used_cam_entry_num_88xx;
+ halmac_api->halmac_read_cam_entry = halmac_read_cam_entry_88xx;
+ halmac_api->halmac_write_cam = halmac_write_cam_88xx;
+ halmac_api->halmac_clear_cam_entry = halmac_clear_cam_entry_88xx;
+
+ halmac_api->halmac_get_hw_value = halmac_get_hw_value_88xx;
+ halmac_api->halmac_set_hw_value = halmac_set_hw_value_88xx;
+
+ halmac_api->halmac_cfg_drv_rsvd_pg_num =
+ halmac_cfg_drv_rsvd_pg_num_88xx;
+ halmac_api->halmac_get_chip_version = halmac_get_chip_version_88xx;
+
+ halmac_api->halmac_query_status = halmac_query_status_88xx;
+ halmac_api->halmac_reset_feature = halmac_reset_feature_88xx;
+ halmac_api->halmac_check_fw_status = halmac_check_fw_status_88xx;
+ halmac_api->halmac_dump_fw_dmem = halmac_dump_fw_dmem_88xx;
+ halmac_api->halmac_cfg_max_dl_size = halmac_cfg_max_dl_size_88xx;
+
+ halmac_api->halmac_dump_fifo = halmac_dump_fifo_88xx;
+ halmac_api->halmac_get_fifo_size = halmac_get_fifo_size_88xx;
+
+ halmac_api->halmac_chk_txdesc = halmac_chk_txdesc_88xx;
+ halmac_api->halmac_dl_drv_rsvd_page = halmac_dl_drv_rsvd_page_88xx;
+ halmac_api->halmac_cfg_csi_rate = halmac_cfg_csi_rate_88xx;
+
+ halmac_api->halmac_sdio_cmd53_4byte = halmac_sdio_cmd53_4byte_88xx;
+ halmac_api->halmac_txfifo_is_empty = halmac_txfifo_is_empty_88xx;
+
+ if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
+ halmac_api->halmac_cfg_rx_aggregation =
+ halmac_cfg_rx_aggregation_88xx_sdio;
+ halmac_api->halmac_init_interface_cfg =
+ halmac_init_sdio_cfg_88xx;
+ halmac_api->halmac_deinit_interface_cfg =
+ halmac_deinit_sdio_cfg_88xx;
+ halmac_api->halmac_reg_read_8 = halmac_reg_read_8_sdio_88xx;
+ halmac_api->halmac_reg_write_8 = halmac_reg_write_8_sdio_88xx;
+ halmac_api->halmac_reg_read_16 = halmac_reg_read_16_sdio_88xx;
+ halmac_api->halmac_reg_write_16 = halmac_reg_write_16_sdio_88xx;
+ halmac_api->halmac_reg_read_32 = halmac_reg_read_32_sdio_88xx;
+ halmac_api->halmac_reg_write_32 = halmac_reg_write_32_sdio_88xx;
+ halmac_api->halmac_reg_read_indirect_32 =
+ halmac_reg_read_indirect_32_sdio_88xx;
+ halmac_api->halmac_reg_sdio_cmd53_read_n =
+ halmac_reg_read_nbyte_sdio_88xx;
+ } else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_USB) {
+ halmac_api->halmac_cfg_rx_aggregation =
+ halmac_cfg_rx_aggregation_88xx_usb;
+ halmac_api->halmac_init_interface_cfg =
+ halmac_init_usb_cfg_88xx;
+ halmac_api->halmac_deinit_interface_cfg =
+ halmac_deinit_usb_cfg_88xx;
+ halmac_api->halmac_reg_read_8 = halmac_reg_read_8_usb_88xx;
+ halmac_api->halmac_reg_write_8 = halmac_reg_write_8_usb_88xx;
+ halmac_api->halmac_reg_read_16 = halmac_reg_read_16_usb_88xx;
+ halmac_api->halmac_reg_write_16 = halmac_reg_write_16_usb_88xx;
+ halmac_api->halmac_reg_read_32 = halmac_reg_read_32_usb_88xx;
+ halmac_api->halmac_reg_write_32 = halmac_reg_write_32_usb_88xx;
+ } else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_PCIE) {
+ halmac_api->halmac_cfg_rx_aggregation =
+ halmac_cfg_rx_aggregation_88xx_pcie;
+ halmac_api->halmac_init_interface_cfg =
+ halmac_init_pcie_cfg_88xx;
+ halmac_api->halmac_deinit_interface_cfg =
+ halmac_deinit_pcie_cfg_88xx;
+ halmac_api->halmac_reg_read_8 = halmac_reg_read_8_pcie_88xx;
+ halmac_api->halmac_reg_write_8 = halmac_reg_write_8_pcie_88xx;
+ halmac_api->halmac_reg_read_16 = halmac_reg_read_16_pcie_88xx;
+ halmac_api->halmac_reg_write_16 = halmac_reg_write_16_pcie_88xx;
+ halmac_api->halmac_reg_read_32 = halmac_reg_read_32_pcie_88xx;
+ halmac_api->halmac_reg_write_32 = halmac_reg_write_32_pcie_88xx;
+ } else {
+ pr_err("Set halmac io function Error!!\n");
+ }
+
+ halmac_api->halmac_set_bulkout_num = halmac_set_bulkout_num_88xx;
+ halmac_api->halmac_get_sdio_tx_addr = halmac_get_sdio_tx_addr_88xx;
+ halmac_api->halmac_get_usb_bulkout_id = halmac_get_usb_bulkout_id_88xx;
+ halmac_api->halmac_timer_2s = halmac_timer_2s_88xx;
+ halmac_api->halmac_fill_txdesc_checksum =
+ halmac_fill_txdesc_check_sum_88xx;
+
+ if (halmac_adapter->chip_id == HALMAC_CHIP_ID_8822B) {
+ /*mount 8822b function and data*/
+ halmac_mount_api_8822b(halmac_adapter);
+
+ } else if (halmac_adapter->chip_id == HALMAC_CHIP_ID_8821C) {
+ } else if (halmac_adapter->chip_id == HALMAC_CHIP_ID_8814B) {
+ } else if (halmac_adapter->chip_id == HALMAC_CHIP_ID_8197F) {
+ } else {
+ pr_err("Chip ID undefine!!\n");
+ return HALMAC_RET_CHIP_NOT_SUPPORT;
+ }
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_download_firmware_88xx() - download Firmware
+ * @halmac_adapter : the adapter of halmac
+ * @hamacl_fw : firmware bin
+ * @halmac_fw_size : firmware size
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_download_firmware_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *hamacl_fw, u32 halmac_fw_size)
+{
+ u8 value8;
+ u8 *file_ptr;
+ u32 dest;
+ u16 value16;
+ u32 restore_index = 0;
+ u32 halmac_h2c_ver = 0, fw_h2c_ver = 0;
+ u32 iram_pkt_size, dmem_pkt_size, eram_pkt_size = 0;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ struct halmac_restore_info restore_info[DLFW_RESTORE_REG_NUM_88XX];
+ u32 temp;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DOWNLOAD_FIRMWARE);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s start!!\n", __func__);
+
+ if (halmac_fw_size > HALMAC_FW_SIZE_MAX_88XX ||
+ halmac_fw_size < HALMAC_FWHDR_SIZE_88XX) {
+ pr_err("FW size error!\n");
+ return HALMAC_RET_FW_SIZE_ERR;
+ }
+
+ fw_h2c_ver = le32_to_cpu(
+ *((__le32 *)
+ (hamacl_fw + HALMAC_FWHDR_OFFSET_H2C_FORMAT_VER_88XX)));
+ halmac_h2c_ver = H2C_FORMAT_VERSION;
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "halmac h2c/c2h format = %x, fw h2c/c2h format = %x!!\n",
+ halmac_h2c_ver, fw_h2c_ver);
+ if (fw_h2c_ver != halmac_h2c_ver)
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_INIT, DBG_WARNING,
+ "[WARN]H2C/C2H version between HALMAC and FW is compatible!!\n");
+
+ halmac_adapter->halmac_state.dlfw_state = HALMAC_DLFW_NONE;
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_SYS_FUNC_EN + 1);
+ value8 = (u8)(value8 & ~(BIT(2)));
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_SYS_FUNC_EN + 1,
+ value8); /* Disable CPU reset */
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RSV_CTRL + 1);
+ value8 = (u8)(value8 & ~(BIT(0)));
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_RSV_CTRL + 1, value8);
+
+ restore_info[restore_index].length = 1;
+ restore_info[restore_index].mac_register = REG_TXDMA_PQ_MAP + 1;
+ restore_info[restore_index].value =
+ HALMAC_REG_READ_8(halmac_adapter, REG_TXDMA_PQ_MAP + 1);
+ restore_index++;
+ value8 = HALMAC_DMA_MAPPING_HIGH << 6;
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_TXDMA_PQ_MAP + 1,
+ value8); /* set HIQ to hi priority */
+
+ /* DLFW only use HIQ, map HIQ to hi priority */
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_HI] =
+ HALMAC_DMA_MAPPING_HIGH;
+ restore_info[restore_index].length = 1;
+ restore_info[restore_index].mac_register = REG_CR;
+ restore_info[restore_index].value =
+ HALMAC_REG_READ_8(halmac_adapter, REG_CR);
+ restore_index++;
+ restore_info[restore_index].length = 4;
+ restore_info[restore_index].mac_register = REG_H2CQ_CSR;
+ restore_info[restore_index].value = BIT(31);
+ restore_index++;
+ value8 = BIT_HCI_TXDMA_EN | BIT_TXDMA_EN;
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_CR, value8);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_H2CQ_CSR, BIT(31));
+
+ /* Config hi priority queue and public priority queue page number
+ * (only for DLFW)
+ */
+ restore_info[restore_index].length = 2;
+ restore_info[restore_index].mac_register = REG_FIFOPAGE_INFO_1;
+ restore_info[restore_index].value =
+ HALMAC_REG_READ_16(halmac_adapter, REG_FIFOPAGE_INFO_1);
+ restore_index++;
+ restore_info[restore_index].length = 4;
+ restore_info[restore_index].mac_register = REG_RQPN_CTRL_2;
+ restore_info[restore_index].value =
+ HALMAC_REG_READ_32(halmac_adapter, REG_RQPN_CTRL_2) | BIT(31);
+ restore_index++;
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_INFO_1, 0x200);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_RQPN_CTRL_2,
+ restore_info[restore_index - 1].value);
+
+ if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
+ HALMAC_REG_READ_32(halmac_adapter, REG_SDIO_FREE_TXPG);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_SDIO_TX_CTRL,
+ 0x00000000);
+ }
+
+ halmac_adapter->fw_version.version = le16_to_cpu(
+ *((__le16 *)(hamacl_fw + HALMAC_FWHDR_OFFSET_VERSION_88XX)));
+ halmac_adapter->fw_version.sub_version =
+ *(hamacl_fw + HALMAC_FWHDR_OFFSET_SUBVERSION_88XX);
+ halmac_adapter->fw_version.sub_index =
+ *(hamacl_fw + HALMAC_FWHDR_OFFSET_SUBINDEX_88XX);
+ halmac_adapter->fw_version.h2c_version = (u16)fw_h2c_ver;
+
+ dmem_pkt_size = le32_to_cpu(*((__le32 *)(hamacl_fw +
+ HALMAC_FWHDR_OFFSET_DMEM_SIZE_88XX)));
+ iram_pkt_size = le32_to_cpu(*((__le32 *)(hamacl_fw +
+ HALMAC_FWHDR_OFFSET_IRAM_SIZE_88XX)));
+ if (((*(hamacl_fw + HALMAC_FWHDR_OFFSET_MEM_USAGE_88XX)) & BIT(4)) != 0)
+ eram_pkt_size =
+ le32_to_cpu(*((__le32 *)(hamacl_fw +
+ HALMAC_FWHDR_OFFSET_ERAM_SIZE_88XX)));
+
+ dmem_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
+ iram_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
+ if (eram_pkt_size != 0)
+ eram_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
+
+ if (halmac_fw_size != (HALMAC_FWHDR_SIZE_88XX + dmem_pkt_size +
+ iram_pkt_size + eram_pkt_size)) {
+ pr_err("FW size mismatch the real fw size!\n");
+ goto DLFW_FAIL;
+ }
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_CR + 1);
+ restore_info[restore_index].length = 1;
+ restore_info[restore_index].mac_register = REG_CR + 1;
+ restore_info[restore_index].value = value8;
+ restore_index++;
+ value8 = (u8)(value8 | BIT(0));
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_CR + 1,
+ value8); /* Enable SW TX beacon */
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_BCN_CTRL);
+ restore_info[restore_index].length = 1;
+ restore_info[restore_index].mac_register = REG_BCN_CTRL;
+ restore_info[restore_index].value = value8;
+ restore_index++;
+ value8 = (u8)((value8 & (~BIT(3))) | BIT(4));
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_BCN_CTRL,
+ value8); /* Disable beacon related functions */
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_FWHW_TXQ_CTRL + 2);
+ restore_info[restore_index].length = 1;
+ restore_info[restore_index].mac_register = REG_FWHW_TXQ_CTRL + 2;
+ restore_info[restore_index].value = value8;
+ restore_index++;
+ value8 = (u8)(value8 & ~(BIT(6)));
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_FWHW_TXQ_CTRL + 2,
+ value8); /* Disable ptcl tx bcnq */
+
+ restore_info[restore_index].length = 2;
+ restore_info[restore_index].mac_register = REG_FIFOPAGE_CTRL_2;
+ restore_info[restore_index].value =
+ HALMAC_REG_READ_16(halmac_adapter, REG_FIFOPAGE_CTRL_2) |
+ BIT(15);
+ restore_index++;
+ value16 = 0x8000;
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
+ value16); /* Set beacon header to 0 */
+
+ value16 = (u16)(HALMAC_REG_READ_16(halmac_adapter, REG_MCUFW_CTRL) &
+ 0x3800);
+ value16 |= BIT(0);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_MCUFW_CTRL,
+ value16); /* MCU/FW setting */
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_CPU_DMEM_CON + 2);
+ value8 &= ~(BIT(0));
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_CPU_DMEM_CON + 2, value8);
+ value8 |= BIT(0);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_CPU_DMEM_CON + 2, value8);
+
+ /* Download to DMEM */
+ file_ptr = hamacl_fw + HALMAC_FWHDR_SIZE_88XX;
+ temp = le32_to_cpu(*((__le32 *)(hamacl_fw +
+ HALMAC_FWHDR_OFFSET_DMEM_ADDR_88XX))) &
+ ~(BIT(31));
+ if (halmac_dlfw_to_mem_88xx(halmac_adapter, file_ptr, temp,
+ dmem_pkt_size) != HALMAC_RET_SUCCESS)
+ goto DLFW_END;
+
+ /* Download to IMEM */
+ file_ptr = hamacl_fw + HALMAC_FWHDR_SIZE_88XX + dmem_pkt_size;
+ temp = le32_to_cpu(*((__le32 *)(hamacl_fw +
+ HALMAC_FWHDR_OFFSET_IRAM_ADDR_88XX))) &
+ ~(BIT(31));
+ if (halmac_dlfw_to_mem_88xx(halmac_adapter, file_ptr, temp,
+ iram_pkt_size) != HALMAC_RET_SUCCESS)
+ goto DLFW_END;
+
+ /* Download to EMEM */
+ if (eram_pkt_size != 0) {
+ file_ptr = hamacl_fw + HALMAC_FWHDR_SIZE_88XX + dmem_pkt_size +
+ iram_pkt_size;
+ dest = le32_to_cpu((*((__le32 *)(hamacl_fw +
+ HALMAC_FWHDR_OFFSET_EMEM_ADDR_88XX)))) &
+ ~(BIT(31));
+ if (halmac_dlfw_to_mem_88xx(halmac_adapter, file_ptr, dest,
+ eram_pkt_size) !=
+ HALMAC_RET_SUCCESS)
+ goto DLFW_END;
+ }
+
+ halmac_init_offload_feature_state_machine_88xx(halmac_adapter);
+DLFW_END:
+
+ halmac_restore_mac_register_88xx(halmac_adapter, restore_info,
+ DLFW_RESTORE_REG_NUM_88XX);
+
+ if (halmac_dlfw_end_flow_88xx(halmac_adapter) != HALMAC_RET_SUCCESS)
+ goto DLFW_FAIL;
+
+ halmac_adapter->halmac_state.dlfw_state = HALMAC_DLFW_DONE;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+
+DLFW_FAIL:
+
+ /* Disable FWDL_EN */
+ HALMAC_REG_WRITE_8(
+ halmac_adapter, REG_MCUFW_CTRL,
+ (u8)(HALMAC_REG_READ_8(halmac_adapter, REG_MCUFW_CTRL) &
+ ~(BIT(0))));
+
+ return HALMAC_RET_DLFW_FAIL;
+}
+
+/**
+ * halmac_free_download_firmware_88xx() - download specific memory firmware
+ * @halmac_adapter
+ * @dlfw_mem : memory selection
+ * @hamacl_fw : firmware bin
+ * @halmac_fw_size : firmware size
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ */
+enum halmac_ret_status
+halmac_free_download_firmware_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_dlfw_mem dlfw_mem, u8 *hamacl_fw,
+ u32 halmac_fw_size)
+{
+ u8 tx_pause_backup;
+ u8 *file_ptr;
+ u32 dest;
+ u16 bcn_head_backup;
+ u32 iram_pkt_size, dmem_pkt_size, eram_pkt_size = 0;
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_DLFW_FAIL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_NO_DLFW;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "[TRACE]%s ==========>\n", __func__);
+
+ if (halmac_fw_size > HALMAC_FW_SIZE_MAX_88XX ||
+ halmac_fw_size < HALMAC_FWHDR_SIZE_88XX) {
+ pr_err("[ERR]FW size error!\n");
+ return HALMAC_RET_FW_SIZE_ERR;
+ }
+
+ dmem_pkt_size =
+ le32_to_cpu(*(__le32 *)(hamacl_fw +
+ HALMAC_FWHDR_OFFSET_DMEM_SIZE_88XX));
+ iram_pkt_size =
+ le32_to_cpu(*(__le32 *)(hamacl_fw +
+ HALMAC_FWHDR_OFFSET_IRAM_SIZE_88XX));
+ if (((*(hamacl_fw + HALMAC_FWHDR_OFFSET_MEM_USAGE_88XX)) & BIT(4)) != 0)
+ eram_pkt_size =
+ le32_to_cpu(*(__le32 *)(hamacl_fw +
+ HALMAC_FWHDR_OFFSET_ERAM_SIZE_88XX));
+
+ dmem_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
+ iram_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
+ if (eram_pkt_size != 0)
+ eram_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
+
+ if (halmac_fw_size != (HALMAC_FWHDR_SIZE_88XX + dmem_pkt_size +
+ iram_pkt_size + eram_pkt_size)) {
+ pr_err("[ERR]FW size mismatch the real fw size!\n");
+ return HALMAC_RET_DLFW_FAIL;
+ }
+
+ tx_pause_backup = HALMAC_REG_READ_8(halmac_adapter, REG_TXPAUSE);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_TXPAUSE,
+ tx_pause_backup | BIT(7));
+
+ bcn_head_backup =
+ HALMAC_REG_READ_16(halmac_adapter, REG_FIFOPAGE_CTRL_2) |
+ BIT(15);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2, 0x8000);
+
+ if (eram_pkt_size != 0) {
+ file_ptr = hamacl_fw + HALMAC_FWHDR_SIZE_88XX + dmem_pkt_size +
+ iram_pkt_size;
+ dest = le32_to_cpu(*((__le32 *)(hamacl_fw +
+ HALMAC_FWHDR_OFFSET_EMEM_ADDR_88XX))) &
+ ~(BIT(31));
+ status = halmac_dlfw_to_mem_88xx(halmac_adapter, file_ptr, dest,
+ eram_pkt_size);
+ if (status != HALMAC_RET_SUCCESS)
+ goto DL_FREE_FW_END;
+ }
+
+ status = halmac_free_dl_fw_end_flow_88xx(halmac_adapter);
+
+DL_FREE_FW_END:
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_TXPAUSE, tx_pause_backup);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
+ bcn_head_backup);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "[TRACE]%s <==========\n", __func__);
+
+ return status;
+}
+
+/**
+ * halmac_get_fw_version_88xx() - get FW version
+ * @halmac_adapter : the adapter of halmac
+ * @fw_version : fw version info
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_get_fw_version_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_fw_version *fw_version)
+{
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_adapter->halmac_state.dlfw_state == 0)
+ return HALMAC_RET_DLFW_FAIL;
+
+ fw_version->version = halmac_adapter->fw_version.version;
+ fw_version->sub_version = halmac_adapter->fw_version.sub_version;
+ fw_version->sub_index = halmac_adapter->fw_version.sub_index;
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_cfg_mac_addr_88xx() - config mac address
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_port :0 for port0, 1 for port1, 2 for port2, 3 for port3, 4 for port4
+ * @hal_address : mac address
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_cfg_mac_addr_88xx(struct halmac_adapter *halmac_adapter, u8 halmac_port,
+ union halmac_wlan_addr *hal_address)
+{
+ u16 mac_address_H;
+ u32 mac_address_L;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "[TRACE]%s ==========>\n", __func__);
+
+ if (halmac_port >= HALMAC_PORTIDMAX) {
+ pr_err("[ERR]port index > 5\n");
+ return HALMAC_RET_PORT_NOT_SUPPORT;
+ }
+
+ mac_address_L = le32_to_cpu(hal_address->address_l_h.le_address_low);
+ mac_address_H = le16_to_cpu(hal_address->address_l_h.le_address_high);
+
+ halmac_adapter->hal_mac_addr[halmac_port].address_l_h.address_low =
+ mac_address_L;
+ halmac_adapter->hal_mac_addr[halmac_port].address_l_h.address_high =
+ mac_address_H;
+
+ switch (halmac_port) {
+ case HALMAC_PORTID0:
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_MACID, mac_address_L);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_MACID + 4,
+ mac_address_H);
+ break;
+
+ case HALMAC_PORTID1:
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_MACID1, mac_address_L);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_MACID1 + 4,
+ mac_address_H);
+ break;
+
+ case HALMAC_PORTID2:
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_MACID2, mac_address_L);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_MACID2 + 4,
+ mac_address_H);
+ break;
+
+ case HALMAC_PORTID3:
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_MACID3, mac_address_L);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_MACID3 + 4,
+ mac_address_H);
+ break;
+
+ case HALMAC_PORTID4:
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_MACID4, mac_address_L);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_MACID4 + 4,
+ mac_address_H);
+ break;
+
+ default:
+
+ break;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "[TRACE]%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_cfg_bssid_88xx() - config BSSID
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_port :0 for port0, 1 for port1, 2 for port2, 3 for port3, 4 for port4
+ * @hal_address : bssid
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_cfg_bssid_88xx(struct halmac_adapter *halmac_adapter, u8 halmac_port,
+ union halmac_wlan_addr *hal_address)
+{
+ u16 bssid_address_H;
+ u32 bssid_address_L;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "[TRACE]%s ==========>\n", __func__);
+
+ if (halmac_port >= HALMAC_PORTIDMAX) {
+ pr_err("[ERR]port index > 5\n");
+ return HALMAC_RET_PORT_NOT_SUPPORT;
+ }
+
+ bssid_address_L = le32_to_cpu(hal_address->address_l_h.le_address_low);
+ bssid_address_H = le16_to_cpu(hal_address->address_l_h.le_address_high);
+
+ halmac_adapter->hal_bss_addr[halmac_port].address_l_h.address_low =
+ bssid_address_L;
+ halmac_adapter->hal_bss_addr[halmac_port].address_l_h.address_high =
+ bssid_address_H;
+
+ switch (halmac_port) {
+ case HALMAC_PORTID0:
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_BSSID, bssid_address_L);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_BSSID + 4,
+ bssid_address_H);
+ break;
+
+ case HALMAC_PORTID1:
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_BSSID1,
+ bssid_address_L);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_BSSID1 + 4,
+ bssid_address_H);
+ break;
+
+ case HALMAC_PORTID2:
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_BSSID2,
+ bssid_address_L);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_BSSID2 + 4,
+ bssid_address_H);
+ break;
+
+ case HALMAC_PORTID3:
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_BSSID3,
+ bssid_address_L);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_BSSID3 + 4,
+ bssid_address_H);
+ break;
+
+ case HALMAC_PORTID4:
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_BSSID4,
+ bssid_address_L);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_BSSID4 + 4,
+ bssid_address_H);
+ break;
+
+ default:
+
+ break;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "[TRACE]%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_cfg_multicast_addr_88xx() - config multicast address
+ * @halmac_adapter : the adapter of halmac
+ * @hal_address : multicast address
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_cfg_multicast_addr_88xx(struct halmac_adapter *halmac_adapter,
+ union halmac_wlan_addr *hal_address)
+{
+ u16 address_H;
+ u32 address_L;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter,
+ HALMAC_API_CFG_MULTICAST_ADDR);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ address_L = le32_to_cpu(hal_address->address_l_h.le_address_low);
+ address_H = le16_to_cpu(hal_address->address_l_h.le_address_high);
+
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_MAR, address_L);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_MAR + 4, address_H);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_pre_init_system_cfg_88xx() - pre-init system config
+ * @halmac_adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_pre_init_system_cfg_88xx(struct halmac_adapter *halmac_adapter)
+{
+ u32 value32, counter;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ bool enable_bb;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter,
+ HALMAC_API_PRE_INIT_SYSTEM_CFG);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "halmac_pre_init_system_cfg ==========>\n");
+
+ if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
+ HALMAC_REG_WRITE_8(
+ halmac_adapter, REG_SDIO_HSUS_CTRL,
+ HALMAC_REG_READ_8(halmac_adapter, REG_SDIO_HSUS_CTRL) &
+ ~(BIT(0)));
+ counter = 10000;
+ while (!(HALMAC_REG_READ_8(halmac_adapter, REG_SDIO_HSUS_CTRL) &
+ 0x02)) {
+ counter--;
+ if (counter == 0)
+ return HALMAC_RET_SDIO_LEAVE_SUSPEND_FAIL;
+ }
+ } else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_USB) {
+ if (HALMAC_REG_READ_8(halmac_adapter, REG_SYS_CFG2 + 3) ==
+ 0x20) /* usb3.0 */
+ HALMAC_REG_WRITE_8(
+ halmac_adapter, 0xFE5B,
+ HALMAC_REG_READ_8(halmac_adapter, 0xFE5B) |
+ BIT(4));
+ }
+
+ /* Config PIN Mux */
+ value32 = HALMAC_REG_READ_32(halmac_adapter, REG_PAD_CTRL1);
+ value32 = value32 & (~(BIT(28) | BIT(29)));
+ value32 = value32 | BIT(28) | BIT(29);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_PAD_CTRL1, value32);
+
+ value32 = HALMAC_REG_READ_32(halmac_adapter, REG_LED_CFG);
+ value32 = value32 & (~(BIT(25) | BIT(26)));
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_LED_CFG, value32);
+
+ value32 = HALMAC_REG_READ_32(halmac_adapter, REG_GPIO_MUXCFG);
+ value32 = value32 & (~(BIT(2)));
+ value32 = value32 | BIT(2);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_GPIO_MUXCFG, value32);
+
+ enable_bb = false;
+ halmac_set_hw_value_88xx(halmac_adapter, HALMAC_HW_EN_BB_RF,
+ &enable_bb);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "halmac_pre_init_system_cfg <==========\n");
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_init_system_cfg_88xx() - init system config
+ * @halmac_adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_init_system_cfg_88xx(struct halmac_adapter *halmac_adapter)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_SYSTEM_CFG);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "halmac_init_system_cfg ==========>\n");
+
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_SYS_FUNC_EN + 1,
+ HALMAC_FUNCTION_ENABLE_88XX);
+ HALMAC_REG_WRITE_32(
+ halmac_adapter, REG_SYS_SDIO_CTRL,
+ (u32)(HALMAC_REG_READ_32(halmac_adapter, REG_SYS_SDIO_CTRL) |
+ BIT_LTE_MUX_CTRL_PATH));
+ HALMAC_REG_WRITE_32(
+ halmac_adapter, REG_CPU_DMEM_CON,
+ (u32)(HALMAC_REG_READ_32(halmac_adapter, REG_CPU_DMEM_CON) |
+ BIT_WL_PLATFORM_RST));
+
+ /* halmac_api->halmac_init_h2c(halmac_adapter); */
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "halmac_init_system_cfg <==========\n");
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_init_edca_cfg_88xx() - init EDCA config
+ * @halmac_adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_init_edca_cfg_88xx(struct halmac_adapter *halmac_adapter)
+{
+ u8 value8;
+ u32 value32;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_EDCA_CFG);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ /* Clear TX pause */
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_TXPAUSE, 0x0000);
+
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_SLOT, HALMAC_SLOT_TIME_88XX);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_PIFS, HALMAC_PIFS_TIME_88XX);
+ value32 = HALMAC_SIFS_CCK_CTX_88XX |
+ (HALMAC_SIFS_OFDM_CTX_88XX << BIT_SHIFT_SIFS_OFDM_CTX) |
+ (HALMAC_SIFS_CCK_TRX_88XX << BIT_SHIFT_SIFS_CCK_TRX) |
+ (HALMAC_SIFS_OFDM_TRX_88XX << BIT_SHIFT_SIFS_OFDM_TRX);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_SIFS, value32);
+
+ HALMAC_REG_WRITE_32(
+ halmac_adapter, REG_EDCA_VO_PARAM,
+ HALMAC_REG_READ_32(halmac_adapter, REG_EDCA_VO_PARAM) & 0xFFFF);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_EDCA_VO_PARAM + 2,
+ HALMAC_VO_TXOP_LIMIT_88XX);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_EDCA_VI_PARAM + 2,
+ HALMAC_VI_TXOP_LIMIT_88XX);
+
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_RD_NAV_NXT,
+ HALMAC_RDG_NAV_88XX | (HALMAC_TXOP_NAV_88XX << 16));
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_RXTSF_OFFSET_CCK,
+ HALMAC_CCK_RX_TSF_88XX |
+ (HALMAC_OFDM_RX_TSF_88XX) << 8);
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RD_CTRL + 1);
+ value8 |=
+ (BIT_VOQ_RD_INIT_EN | BIT_VIQ_RD_INIT_EN | BIT_BEQ_RD_INIT_EN);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_RD_CTRL + 1, value8);
+
+ /* Set beacon cotnrol - enable TSF and other related functions */
+ HALMAC_REG_WRITE_8(
+ halmac_adapter, REG_BCN_CTRL,
+ (u8)(HALMAC_REG_READ_8(halmac_adapter, REG_BCN_CTRL) |
+ BIT_EN_BCN_FUNCTION));
+
+ /* Set send beacon related registers */
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_TBTT_PROHIBIT,
+ HALMAC_TBTT_PROHIBIT_88XX |
+ (HALMAC_TBTT_HOLD_TIME_88XX
+ << BIT_SHIFT_TBTT_HOLD_TIME_AP));
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_DRVERLYINT,
+ HALMAC_DRIVER_EARLY_INT_88XX);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_BCNDMATIM,
+ HALMAC_BEACON_DMA_TIM_88XX);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_init_wmac_cfg_88xx() - init wmac config
+ * @halmac_adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_init_wmac_cfg_88xx(struct halmac_adapter *halmac_adapter)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_WMAC_CFG);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_RXFLTMAP0,
+ HALMAC_RX_FILTER0_88XX);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_RXFLTMAP,
+ HALMAC_RX_FILTER_88XX);
+
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_RCR, HALMAC_RCR_CONFIG_88XX);
+
+ HALMAC_REG_WRITE_8(
+ halmac_adapter, REG_TCR + 1,
+ (u8)(HALMAC_REG_READ_8(halmac_adapter, REG_TCR + 1) | 0x30));
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_TCR + 2, 0x30);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_TCR + 1, 0x00);
+
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_WMAC_OPTION_FUNCTION + 8,
+ 0x30810041);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_WMAC_OPTION_FUNCTION + 4,
+ 0x50802080);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_init_mac_cfg_88xx() - config page1~page7 register
+ * @halmac_adapter : the adapter of halmac
+ * @mode : trx mode
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_init_mac_cfg_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_trx_mode mode)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_MAC_CFG);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>mode = %d\n", __func__,
+ mode);
+
+ status = halmac_api->halmac_init_trx_cfg(halmac_adapter, mode);
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_init_trx_cfg error = %x\n", status);
+ return status;
+ }
+ status = halmac_api->halmac_init_protocol_cfg(halmac_adapter);
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_init_protocol_cfg_88xx error = %x\n", status);
+ return status;
+ }
+
+ status = halmac_init_edca_cfg_88xx(halmac_adapter);
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_init_edca_cfg_88xx error = %x\n", status);
+ return status;
+ }
+
+ status = halmac_init_wmac_cfg_88xx(halmac_adapter);
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_init_wmac_cfg_88xx error = %x\n", status);
+ return status;
+ }
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return status;
+}
+
+/**
+ * halmac_cfg_operation_mode_88xx() - config operation mode
+ * @halmac_adapter : the adapter of halmac
+ * @wireless_mode : 802.11 standard(b/g/n/ac)
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_cfg_operation_mode_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_wireless_mode wireless_mode)
+{
+ void *driver_adapter = NULL;
+ enum halmac_wireless_mode wireless_mode_local =
+ HALMAC_WIRELESS_MODE_UNDEFINE;
+
+ wireless_mode_local = wireless_mode;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter,
+ HALMAC_API_CFG_OPERATION_MODE);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>wireless_mode = %d\n", __func__,
+ wireless_mode);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_cfg_ch_bw_88xx() - config channel & bandwidth
+ * @halmac_adapter : the adapter of halmac
+ * @channel : WLAN channel, support 2.4G & 5G
+ * @pri_ch_idx : primary channel index, idx1, idx2, idx3, idx4
+ * @bw : band width, 20, 40, 80, 160, 5 ,10
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_cfg_ch_bw_88xx(struct halmac_adapter *halmac_adapter, u8 channel,
+ enum halmac_pri_ch_idx pri_ch_idx, enum halmac_bw bw)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_CH_BW);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>ch = %d, idx=%d, bw=%d\n", __func__,
+ channel, pri_ch_idx, bw);
+
+ halmac_cfg_pri_ch_idx_88xx(halmac_adapter, pri_ch_idx);
+
+ halmac_cfg_bw_88xx(halmac_adapter, bw);
+
+ halmac_cfg_ch_88xx(halmac_adapter, channel);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status halmac_cfg_ch_88xx(struct halmac_adapter *halmac_adapter,
+ u8 channel)
+{
+ u8 value8;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_CH_BW);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>ch = %d\n", __func__, channel);
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_CCK_CHECK);
+ value8 = value8 & (~(BIT(7)));
+
+ if (channel > 35)
+ value8 = value8 | BIT(7);
+
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_CCK_CHECK, value8);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_cfg_pri_ch_idx_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_pri_ch_idx pri_ch_idx)
+{
+ u8 txsc_40 = 0, txsc_20 = 0;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_CH_BW);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========> idx=%d\n", __func__,
+ pri_ch_idx);
+
+ txsc_20 = pri_ch_idx;
+ if (txsc_20 == HALMAC_CH_IDX_1 || txsc_20 == HALMAC_CH_IDX_3)
+ txsc_40 = 9;
+ else
+ txsc_40 = 10;
+
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_DATA_SC,
+ BIT_TXSC_20M(txsc_20) | BIT_TXSC_40M(txsc_40));
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_cfg_bw_88xx() - config bandwidth
+ * @halmac_adapter : the adapter of halmac
+ * @bw : band width, 20, 40, 80, 160, 5 ,10
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status halmac_cfg_bw_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_bw bw)
+{
+ u32 value32;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_BW);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>bw=%d\n", __func__, bw);
+
+ /* RF mode */
+ value32 = HALMAC_REG_READ_32(halmac_adapter, REG_WMAC_TRXPTCL_CTL);
+ value32 = value32 & (~(BIT(7) | BIT(8)));
+
+ switch (bw) {
+ case HALMAC_BW_80:
+ value32 = value32 | BIT(7);
+ break;
+ case HALMAC_BW_40:
+ value32 = value32 | BIT(8);
+ break;
+ case HALMAC_BW_20:
+ case HALMAC_BW_10:
+ case HALMAC_BW_5:
+ break;
+ default:
+ pr_err("%s switch case not support\n", __func__);
+ break;
+ }
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_WMAC_TRXPTCL_CTL, value32);
+
+ /* MAC CLK */
+ value32 = HALMAC_REG_READ_32(halmac_adapter, REG_AFE_CTRL1);
+ value32 = (value32 & (~(BIT(20) | BIT(21)))) |
+ (HALMAC_MAC_CLOCK_HW_DEF_80M << BIT_SHIFT_MAC_CLK_SEL);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_AFE_CTRL1, value32);
+
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_USTIME_TSF,
+ HALMAC_MAC_CLOCK_88XX);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_USTIME_EDCA,
+ HALMAC_MAC_CLOCK_88XX);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_dump_efuse_map_88xx() - dump "physical" efuse map
+ * @halmac_adapter : the adapter of halmac
+ * @cfg : dump efuse method
+ * Author : Ivan Lin/KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_dump_efuse_map_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_efuse_read_cfg cfg)
+{
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+ enum halmac_cmd_process_status *process_status =
+ &halmac_adapter->halmac_state.efuse_state_set.process_status;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DUMP_EFUSE_MAP);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>cfg=%d\n", __func__, cfg);
+
+ if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Wait event(dump efuse)...\n");
+ return HALMAC_RET_BUSY_STATE;
+ }
+
+ if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
+ HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Not idle state(dump efuse)...\n");
+ return HALMAC_RET_ERROR_STATE;
+ }
+
+ if (halmac_adapter->halmac_state.mac_power == HALMAC_MAC_POWER_OFF)
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_WARNING,
+ "[WARN]Dump efuse in suspend mode\n");
+
+ *process_status = HALMAC_CMD_PROCESS_IDLE;
+ halmac_adapter->event_trigger.physical_efuse_map = 1;
+
+ status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
+ HALMAC_EFUSE_BANK_WIFI);
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
+ return status;
+ }
+
+ status = halmac_dump_efuse_88xx(halmac_adapter, cfg);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_read_efuse error = %x\n", status);
+ return status;
+ }
+
+ if (halmac_adapter->hal_efuse_map_valid) {
+ *process_status = HALMAC_CMD_PROCESS_DONE;
+
+ PLATFORM_EVENT_INDICATION(
+ driver_adapter, HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE,
+ *process_status, halmac_adapter->hal_efuse_map,
+ halmac_adapter->hw_config_info.efuse_size);
+ halmac_adapter->event_trigger.physical_efuse_map = 0;
+ }
+
+ if (halmac_transition_efuse_state_88xx(
+ halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
+ HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ERROR_STATE;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_dump_efuse_map_bt_88xx() - dump "BT physical" efuse map
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_efuse_bank : bt efuse bank
+ * @bt_efuse_map_size : bt efuse map size. get from halmac_get_efuse_size API
+ * @bt_efuse_map : bt efuse map
+ * Author : Soar / Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_dump_efuse_map_bt_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_efuse_bank halmac_efuse_bank,
+ u32 bt_efuse_map_size, u8 *bt_efuse_map)
+{
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+ enum halmac_cmd_process_status *process_status =
+ &halmac_adapter->halmac_state.efuse_state_set.process_status;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DUMP_EFUSE_MAP_BT);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ if (halmac_adapter->hw_config_info.bt_efuse_size != bt_efuse_map_size)
+ return HALMAC_RET_EFUSE_SIZE_INCORRECT;
+
+ if ((halmac_efuse_bank >= HALMAC_EFUSE_BANK_MAX) ||
+ halmac_efuse_bank == HALMAC_EFUSE_BANK_WIFI) {
+ pr_err("Undefined BT bank\n");
+ return HALMAC_RET_EFUSE_BANK_INCORRECT;
+ }
+
+ if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Wait event(dump efuse)...\n");
+ return HALMAC_RET_BUSY_STATE;
+ }
+
+ if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
+ HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Not idle state(dump efuse)...\n");
+ return HALMAC_RET_ERROR_STATE;
+ }
+
+ status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
+ halmac_efuse_bank);
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
+ return status;
+ }
+
+ status = halmac_read_hw_efuse_88xx(halmac_adapter, 0, bt_efuse_map_size,
+ bt_efuse_map);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_read_hw_efuse_88xx error = %x\n", status);
+ return status;
+ }
+
+ if (halmac_transition_efuse_state_88xx(
+ halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
+ HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ERROR_STATE;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_write_efuse_bt_88xx() - write "BT physical" efuse offset
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_offset : offset
+ * @halmac_value : Write value
+ * @bt_efuse_map : bt efuse map
+ * Author : Soar
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_write_efuse_bt_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u8 halmac_value,
+ enum halmac_efuse_bank halmac_efuse_bank)
+{
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ enum halmac_cmd_process_status *process_status =
+ &halmac_adapter->halmac_state.efuse_state_set.process_status;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_WRITE_EFUSE_BT);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
+ "%s ==========>\n", __func__);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
+ "offset : %X value : %X Bank : %X\n", halmac_offset,
+ halmac_value, halmac_efuse_bank);
+
+ if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Wait/Rcvd event(dump efuse)...\n");
+ return HALMAC_RET_BUSY_STATE;
+ }
+
+ if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
+ HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Not idle state(dump efuse)...\n");
+ return HALMAC_RET_ERROR_STATE;
+ }
+
+ if (halmac_offset >= halmac_adapter->hw_config_info.efuse_size) {
+ pr_err("Offset is too large\n");
+ return HALMAC_RET_EFUSE_SIZE_INCORRECT;
+ }
+
+ if (halmac_efuse_bank > HALMAC_EFUSE_BANK_MAX ||
+ halmac_efuse_bank == HALMAC_EFUSE_BANK_WIFI) {
+ pr_err("Undefined BT bank\n");
+ return HALMAC_RET_EFUSE_BANK_INCORRECT;
+ }
+
+ status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
+ halmac_efuse_bank);
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
+ return status;
+ }
+
+ status = halmac_func_write_efuse_88xx(halmac_adapter, halmac_offset,
+ halmac_value);
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_func_write_efuse error = %x\n", status);
+ return status;
+ }
+
+ if (halmac_transition_efuse_state_88xx(
+ halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
+ HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ERROR_STATE;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_get_efuse_available_size_88xx() - get efuse available size
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_size : physical efuse available size
+ * Author : Soar
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_get_efuse_available_size_88xx(struct halmac_adapter *halmac_adapter,
+ u32 *halmac_size)
+{
+ enum halmac_ret_status status;
+ void *driver_adapter = NULL;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ status = halmac_dump_logical_efuse_map_88xx(halmac_adapter,
+ HALMAC_EFUSE_R_DRV);
+
+ if (status != HALMAC_RET_SUCCESS)
+ return status;
+
+ *halmac_size = halmac_adapter->hw_config_info.efuse_size -
+ HALMAC_PROTECTED_EFUSE_SIZE_88XX -
+ halmac_adapter->efuse_end;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_get_efuse_size_88xx() - get "physical" efuse size
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_size : physical efuse size
+ * Author : Ivan Lin/KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_get_efuse_size_88xx(struct halmac_adapter *halmac_adapter,
+ u32 *halmac_size)
+{
+ void *driver_adapter = NULL;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_GET_EFUSE_SIZE);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ *halmac_size = halmac_adapter->hw_config_info.efuse_size;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_get_logical_efuse_size_88xx() - get "logical" efuse size
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_size : logical efuse size
+ * Author : Ivan Lin/KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_get_logical_efuse_size_88xx(struct halmac_adapter *halmac_adapter,
+ u32 *halmac_size)
+{
+ void *driver_adapter = NULL;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter,
+ HALMAC_API_GET_LOGICAL_EFUSE_SIZE);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ *halmac_size = halmac_adapter->hw_config_info.eeprom_size;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_dump_logical_efuse_map_88xx() - dump "logical" efuse map
+ * @halmac_adapter : the adapter of halmac
+ * @cfg : dump efuse method
+ * Author : Soar
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_dump_logical_efuse_map_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_efuse_read_cfg cfg)
+{
+ u8 *eeprom_map = NULL;
+ u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+ enum halmac_cmd_process_status *process_status =
+ &halmac_adapter->halmac_state.efuse_state_set.process_status;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter,
+ HALMAC_API_DUMP_LOGICAL_EFUSE_MAP);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
+ "%s ==========>cfg = %d\n", __func__, cfg);
+
+ if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Wait/Rcvd event(dump efuse)...\n");
+ return HALMAC_RET_BUSY_STATE;
+ }
+
+ if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
+ HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Not idle state(dump efuse)...\n");
+ return HALMAC_RET_ERROR_STATE;
+ }
+
+ if (halmac_adapter->halmac_state.mac_power == HALMAC_MAC_POWER_OFF)
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_WARNING,
+ "[WARN]Dump logical efuse in suspend mode\n");
+
+ *process_status = HALMAC_CMD_PROCESS_IDLE;
+ halmac_adapter->event_trigger.logical_efuse_map = 1;
+
+ status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
+ HALMAC_EFUSE_BANK_WIFI);
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
+ return status;
+ }
+
+ status = halmac_dump_efuse_88xx(halmac_adapter, cfg);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_eeprom_parser_88xx error = %x\n", status);
+ return status;
+ }
+
+ if (halmac_adapter->hal_efuse_map_valid) {
+ *process_status = HALMAC_CMD_PROCESS_DONE;
+
+ eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
+ if (!eeprom_map) {
+ /* out of memory */
+ return HALMAC_RET_MALLOC_FAIL;
+ }
+ memset(eeprom_map, 0xFF, eeprom_size);
+
+ if (halmac_eeprom_parser_88xx(halmac_adapter,
+ halmac_adapter->hal_efuse_map,
+ eeprom_map) != HALMAC_RET_SUCCESS) {
+ kfree(eeprom_map);
+ return HALMAC_RET_EEPROM_PARSING_FAIL;
+ }
+
+ PLATFORM_EVENT_INDICATION(
+ driver_adapter, HALMAC_FEATURE_DUMP_LOGICAL_EFUSE,
+ *process_status, eeprom_map, eeprom_size);
+ halmac_adapter->event_trigger.logical_efuse_map = 0;
+
+ kfree(eeprom_map);
+ }
+
+ if (halmac_transition_efuse_state_88xx(
+ halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
+ HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ERROR_STATE;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_read_logical_efuse_88xx() - read logical efuse map 1 byte
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_offset : offset
+ * @value : 1 byte efuse value
+ * Author : Soar
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_read_logical_efuse_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u8 *value)
+{
+ u8 *eeprom_map = NULL;
+ u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ enum halmac_cmd_process_status *process_status =
+ &halmac_adapter->halmac_state.efuse_state_set.process_status;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter,
+ HALMAC_API_READ_LOGICAL_EFUSE);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ if (halmac_offset >= eeprom_size) {
+ pr_err("Offset is too large\n");
+ return HALMAC_RET_EFUSE_SIZE_INCORRECT;
+ }
+
+ if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Wait/Rcvd event(dump efuse)...\n");
+ return HALMAC_RET_BUSY_STATE;
+ }
+ if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
+ HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Not idle state(dump efuse)...\n");
+ return HALMAC_RET_ERROR_STATE;
+ }
+
+ status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
+ HALMAC_EFUSE_BANK_WIFI);
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
+ return status;
+ }
+
+ eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
+ if (!eeprom_map) {
+ /* out of memory */
+ return HALMAC_RET_MALLOC_FAIL;
+ }
+ memset(eeprom_map, 0xFF, eeprom_size);
+
+ status = halmac_read_logical_efuse_map_88xx(halmac_adapter, eeprom_map);
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_read_logical_efuse_map error = %x\n", status);
+ kfree(eeprom_map);
+ return status;
+ }
+
+ *value = *(eeprom_map + halmac_offset);
+
+ if (halmac_transition_efuse_state_88xx(
+ halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
+ HALMAC_RET_SUCCESS) {
+ kfree(eeprom_map);
+ return HALMAC_RET_ERROR_STATE;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ kfree(eeprom_map);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_write_logical_efuse_88xx() - write "logical" efuse offset
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_offset : offset
+ * @halmac_value : value
+ * Author : Soar
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_write_logical_efuse_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u8 halmac_value)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ enum halmac_cmd_process_status *process_status =
+ &halmac_adapter->halmac_state.efuse_state_set.process_status;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter,
+ HALMAC_API_WRITE_LOGICAL_EFUSE);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ if (halmac_offset >= halmac_adapter->hw_config_info.eeprom_size) {
+ pr_err("Offset is too large\n");
+ return HALMAC_RET_EFUSE_SIZE_INCORRECT;
+ }
+
+ if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Wait/Rcvd event(dump efuse)...\n");
+ return HALMAC_RET_BUSY_STATE;
+ }
+
+ if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
+ HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Not idle state(dump efuse)...\n");
+ return HALMAC_RET_ERROR_STATE;
+ }
+
+ status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
+ HALMAC_EFUSE_BANK_WIFI);
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
+ return status;
+ }
+
+ status = halmac_func_write_logical_efuse_88xx(
+ halmac_adapter, halmac_offset, halmac_value);
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_write_logical_efuse error = %x\n", status);
+ return status;
+ }
+
+ if (halmac_transition_efuse_state_88xx(
+ halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
+ HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ERROR_STATE;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_pg_efuse_by_map_88xx() - pg logical efuse by map
+ * @halmac_adapter : the adapter of halmac
+ * @pg_efuse_info : efuse map information
+ * @cfg : dump efuse method
+ * Author : Soar
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_pg_efuse_by_map_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_pg_efuse_info *pg_efuse_info,
+ enum halmac_efuse_read_cfg cfg)
+{
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ enum halmac_cmd_process_status *process_status =
+ &halmac_adapter->halmac_state.efuse_state_set.process_status;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_PG_EFUSE_BY_MAP);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ if (pg_efuse_info->efuse_map_size !=
+ halmac_adapter->hw_config_info.eeprom_size) {
+ pr_err("efuse_map_size is incorrect, should be %d bytes\n",
+ halmac_adapter->hw_config_info.eeprom_size);
+ return HALMAC_RET_EFUSE_SIZE_INCORRECT;
+ }
+
+ if ((pg_efuse_info->efuse_map_size & 0xF) > 0) {
+ pr_err("efuse_map_size should be multiple of 16\n");
+ return HALMAC_RET_EFUSE_SIZE_INCORRECT;
+ }
+
+ if (pg_efuse_info->efuse_mask_size !=
+ pg_efuse_info->efuse_map_size >> 4) {
+ pr_err("efuse_mask_size is incorrect, should be %d bytes\n",
+ pg_efuse_info->efuse_map_size >> 4);
+ return HALMAC_RET_EFUSE_SIZE_INCORRECT;
+ }
+
+ if (!pg_efuse_info->efuse_map) {
+ pr_err("efuse_map is NULL\n");
+ return HALMAC_RET_NULL_POINTER;
+ }
+
+ if (!pg_efuse_info->efuse_mask) {
+ pr_err("efuse_mask is NULL\n");
+ return HALMAC_RET_NULL_POINTER;
+ }
+
+ if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Wait/Rcvd event(dump efuse)...\n");
+ return HALMAC_RET_BUSY_STATE;
+ }
+
+ if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
+ HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Not idle state(dump efuse)...\n");
+ return HALMAC_RET_ERROR_STATE;
+ }
+
+ status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
+ HALMAC_EFUSE_BANK_WIFI);
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
+ return status;
+ }
+
+ status = halmac_func_pg_efuse_by_map_88xx(halmac_adapter, pg_efuse_info,
+ cfg);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_pg_efuse_by_map error = %x\n", status);
+ return status;
+ }
+
+ if (halmac_transition_efuse_state_88xx(
+ halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
+ HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ERROR_STATE;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_get_c2h_info_88xx() - process halmac C2H packet
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_buf : RX Packet pointer
+ * @halmac_size : RX Packet size
+ * Author : KaiYuan Chang/Ivan Lin
+ *
+ * Used to process c2h packet info from RX path. After receiving the packet,
+ * user need to call this api and pass the packet pointer.
+ *
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_get_c2h_info_88xx(struct halmac_adapter *halmac_adapter, u8 *halmac_buf,
+ u32 halmac_size)
+{
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_GET_C2H_INFO);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ /* Check if it is C2H packet */
+ if (GET_RX_DESC_C2H(halmac_buf)) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "C2H packet, start parsing!\n");
+
+ status = halmac_parse_c2h_packet_88xx(halmac_adapter,
+ halmac_buf, halmac_size);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_parse_c2h_packet_88xx error = %x\n",
+ status);
+ return status;
+ }
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_cfg_fwlps_option_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_fwlps_option *lps_option)
+{
+ void *driver_adapter = NULL;
+ struct halmac_fwlps_option *hal_fwlps_option;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_FWLPS_OPTION);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ hal_fwlps_option = &halmac_adapter->fwlps_option;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ hal_fwlps_option->mode = lps_option->mode;
+ hal_fwlps_option->clk_request = lps_option->clk_request;
+ hal_fwlps_option->rlbm = lps_option->rlbm;
+ hal_fwlps_option->smart_ps = lps_option->smart_ps;
+ hal_fwlps_option->awake_interval = lps_option->awake_interval;
+ hal_fwlps_option->all_queue_uapsd = lps_option->all_queue_uapsd;
+ hal_fwlps_option->pwr_state = lps_option->pwr_state;
+ hal_fwlps_option->low_pwr_rx_beacon = lps_option->low_pwr_rx_beacon;
+ hal_fwlps_option->ant_auto_switch = lps_option->ant_auto_switch;
+ hal_fwlps_option->ps_allow_bt_high_priority =
+ lps_option->ps_allow_bt_high_priority;
+ hal_fwlps_option->protect_bcn = lps_option->protect_bcn;
+ hal_fwlps_option->silence_period = lps_option->silence_period;
+ hal_fwlps_option->fast_bt_connect = lps_option->fast_bt_connect;
+ hal_fwlps_option->two_antenna_en = lps_option->two_antenna_en;
+ hal_fwlps_option->adopt_user_setting = lps_option->adopt_user_setting;
+ hal_fwlps_option->drv_bcn_early_shift = lps_option->drv_bcn_early_shift;
+ hal_fwlps_option->enter_32K = lps_option->enter_32K;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_cfg_fwips_option_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_fwips_option *ips_option)
+{
+ void *driver_adapter = NULL;
+ struct halmac_fwips_option *ips_option_local;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_FWIPS_OPTION);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ ips_option_local = ips_option;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_enter_wowlan_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_wowlan_option *wowlan_option)
+{
+ void *driver_adapter = NULL;
+ struct halmac_wowlan_option *wowlan_option_local;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_ENTER_WOWLAN);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ wowlan_option_local = wowlan_option;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_leave_wowlan_88xx(struct halmac_adapter *halmac_adapter)
+{
+ void *driver_adapter = NULL;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_LEAVE_WOWLAN);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_enter_ps_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_ps_state ps_state)
+{
+ u8 rpwm;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_NO_DLFW;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_ENTER_PS);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ if (ps_state == halmac_adapter->halmac_state.ps_state) {
+ pr_err("power state is already in PS State!!\n");
+ return HALMAC_RET_SUCCESS;
+ }
+
+ if (ps_state == HALMAC_PS_STATE_LPS) {
+ status = halmac_send_h2c_set_pwr_mode_88xx(
+ halmac_adapter, &halmac_adapter->fwlps_option);
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_send_h2c_set_pwr_mode_88xx error = %x!!\n",
+ status);
+ return status;
+ }
+ } else if (ps_state == HALMAC_PS_STATE_IPS) {
+ }
+
+ halmac_adapter->halmac_state.ps_state = ps_state;
+
+ /* Enter 32K */
+ if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
+ if (halmac_adapter->fwlps_option.enter_32K) {
+ rpwm = (u8)(((halmac_adapter->rpwm_record ^ (BIT(7))) |
+ (BIT(0))) &
+ 0x81);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_SDIO_HRPWM1,
+ rpwm);
+ halmac_adapter->low_clk = true;
+ }
+ } else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_USB) {
+ if (halmac_adapter->fwlps_option.enter_32K) {
+ rpwm = (u8)(((halmac_adapter->rpwm_record ^ (BIT(7))) |
+ (BIT(0))) &
+ 0x81);
+ HALMAC_REG_WRITE_8(halmac_adapter, 0xFE58, rpwm);
+ halmac_adapter->low_clk = true;
+ }
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_leave_ps_88xx(struct halmac_adapter *halmac_adapter)
+{
+ u8 rpwm, cpwm;
+ u32 counter;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ struct halmac_fwlps_option fw_lps_option;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_NO_DLFW;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_LEAVE_PS);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ if (halmac_adapter->halmac_state.ps_state == HALMAC_PS_STATE_ACT) {
+ pr_err("power state is already in active!!\n");
+ return HALMAC_RET_SUCCESS;
+ }
+
+ if (halmac_adapter->low_clk) {
+ cpwm = HALMAC_REG_READ_8(halmac_adapter, REG_SDIO_HRPWM1);
+ rpwm = (u8)(
+ ((halmac_adapter->rpwm_record ^ (BIT(7))) | (BIT(6))) &
+ 0xC0);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_SDIO_HRPWM1, rpwm);
+
+ cpwm = (u8)((cpwm ^ BIT(7)) & BIT(7));
+ counter = 100;
+ while (cpwm !=
+ (HALMAC_REG_READ_8(halmac_adapter, REG_SDIO_HRPWM1) &
+ BIT(7))) {
+ usleep_range(50, 60);
+ counter--;
+ if (counter == 0)
+ return HALMAC_RET_CHANGE_PS_FAIL;
+ }
+ halmac_adapter->low_clk = false;
+ }
+
+ memcpy(&fw_lps_option, &halmac_adapter->fwlps_option,
+ sizeof(struct halmac_fwlps_option));
+ fw_lps_option.mode = 0;
+
+ status = halmac_send_h2c_set_pwr_mode_88xx(halmac_adapter,
+ &fw_lps_option);
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_send_h2c_set_pwr_mode_88xx error!!=%x\n",
+ status);
+ return status;
+ }
+
+ halmac_adapter->halmac_state.ps_state = HALMAC_PS_STATE_ACT;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * (debug API)halmac_h2c_lb_88xx() - send h2c loopback packet
+ * @halmac_adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status halmac_h2c_lb_88xx(struct halmac_adapter *halmac_adapter)
+{
+ void *driver_adapter = NULL;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_H2C_LB);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_debug_88xx() - dump information for debugging
+ * @halmac_adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status halmac_debug_88xx(struct halmac_adapter *halmac_adapter)
+{
+ u8 temp8 = 0;
+ u32 i = 0, temp32 = 0;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DEBUG);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
+ /* Dump CCCR, it needs new platform api */
+
+ /*Dump SDIO Local Register, use CMD52*/
+ for (i = 0x10250000; i < 0x102500ff; i++) {
+ temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "halmac_debug: sdio[%x]=%x\n", i, temp8);
+ }
+
+ /*Dump MAC Register*/
+ for (i = 0x0000; i < 0x17ff; i++) {
+ temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
+ DBG_DMESG, "halmac_debug: mac[%x]=%x\n",
+ i, temp8);
+ }
+
+ /*Check RX Fifo status*/
+ i = REG_RXFF_PTR_V1;
+ temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "halmac_debug: mac[%x]=%x\n", i, temp8);
+ i = REG_RXFF_WTR_V1;
+ temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "halmac_debug: mac[%x]=%x\n", i, temp8);
+ i = REG_RXFF_PTR_V1;
+ temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "halmac_debug: mac[%x]=%x\n", i, temp8);
+ i = REG_RXFF_WTR_V1;
+ temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "halmac_debug: mac[%x]=%x\n", i, temp8);
+ } else {
+ /*Dump MAC Register*/
+ for (i = 0x0000; i < 0x17fc; i += 4) {
+ temp32 = HALMAC_REG_READ_32(halmac_adapter, i);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
+ DBG_DMESG, "halmac_debug: mac[%x]=%x\n",
+ i, temp32);
+ }
+
+ /*Check RX Fifo status*/
+ i = REG_RXFF_PTR_V1;
+ temp32 = HALMAC_REG_READ_32(halmac_adapter, i);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "halmac_debug: mac[%x]=%x\n", i, temp32);
+ i = REG_RXFF_WTR_V1;
+ temp32 = HALMAC_REG_READ_32(halmac_adapter, i);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "halmac_debug: mac[%x]=%x\n", i, temp32);
+ i = REG_RXFF_PTR_V1;
+ temp32 = HALMAC_REG_READ_32(halmac_adapter, i);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "halmac_debug: mac[%x]=%x\n", i, temp32);
+ i = REG_RXFF_WTR_V1;
+ temp32 = HALMAC_REG_READ_32(halmac_adapter, i);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "halmac_debug: mac[%x]=%x\n", i, temp32);
+ }
+
+ /* TODO: Add check register code, including MAC CLK, CPU CLK */
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_cfg_parameter_88xx() - config parameter by FW
+ * @halmac_adapter : the adapter of halmac
+ * @para_info : cmd id, content
+ * @full_fifo : parameter information
+ *
+ * If msk_en = true, the format of array is {reg_info, mask, value}.
+ * If msk_en =_FAUSE, the format of array is {reg_info, value}
+ * The format of reg_info is
+ * reg_info[31]=rf_reg, 0: MAC_BB reg, 1: RF reg
+ * reg_info[27:24]=rf_path, 0: path_A, 1: path_B
+ * if rf_reg=0(MAC_BB reg), rf_path is meaningless.
+ * ref_info[15:0]=offset
+ *
+ * Example: msk_en = false
+ * {0x8100000a, 0x00001122}
+ * =>Set RF register, path_B, offset 0xA to 0x00001122
+ * {0x00000824, 0x11224433}
+ * =>Set MAC_BB register, offset 0x800 to 0x11224433
+ *
+ * Note : full fifo mode only for init flow
+ *
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_cfg_parameter_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_phy_parameter_info *para_info,
+ u8 full_fifo)
+{
+ void *driver_adapter = NULL;
+ enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
+ enum halmac_cmd_process_status *process_status =
+ &halmac_adapter->halmac_state.cfg_para_state_set.process_status;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_NO_DLFW;
+
+ if (halmac_adapter->fw_version.h2c_version < 4)
+ return HALMAC_RET_FW_NO_SUPPORT;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_PARAMETER);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ if (halmac_adapter->halmac_state.dlfw_state == HALMAC_DLFW_NONE) {
+ pr_err("%s Fail due to DLFW NONE!!\n", __func__);
+ return HALMAC_RET_DLFW_FAIL;
+ }
+
+ if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Wait event(cfg para)...\n");
+ return HALMAC_RET_BUSY_STATE;
+ }
+
+ if (halmac_query_cfg_para_curr_state_88xx(halmac_adapter) !=
+ HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE &&
+ halmac_query_cfg_para_curr_state_88xx(halmac_adapter) !=
+ HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Not idle state(cfg para)...\n");
+ return HALMAC_RET_BUSY_STATE;
+ }
+
+ *process_status = HALMAC_CMD_PROCESS_IDLE;
+
+ ret_status = halmac_send_h2c_phy_parameter_88xx(halmac_adapter,
+ para_info, full_fifo);
+
+ if (ret_status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_send_h2c_phy_parameter_88xx Fail!! = %x\n",
+ ret_status);
+ return ret_status;
+ }
+
+ return ret_status;
+}
+
+/**
+ * halmac_update_packet_88xx() - send specific packet to FW
+ * @halmac_adapter : the adapter of halmac
+ * @pkt_id : packet id, to know the purpose of this packet
+ * @pkt : packet
+ * @pkt_size : packet size
+ *
+ * Note : TX_DESC is not included in the pkt
+ *
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_update_packet_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_packet_id pkt_id, u8 *pkt, u32 pkt_size)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+ enum halmac_cmd_process_status *process_status =
+ &halmac_adapter->halmac_state.update_packet_set.process_status;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_NO_DLFW;
+
+ if (halmac_adapter->fw_version.h2c_version < 4)
+ return HALMAC_RET_FW_NO_SUPPORT;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_UPDATE_PACKET);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Wait event(update_packet)...\n");
+ return HALMAC_RET_BUSY_STATE;
+ }
+
+ *process_status = HALMAC_CMD_PROCESS_SENDING;
+
+ status = halmac_send_h2c_update_packet_88xx(halmac_adapter, pkt_id, pkt,
+ pkt_size);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_send_h2c_update_packet_88xx packet = %x, fail = %x!!\n",
+ pkt_id, status);
+ return status;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_bcn_ie_filter_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_bcn_ie_info *bcn_ie_info)
+{
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_NO_DLFW;
+
+ if (halmac_adapter->fw_version.h2c_version < 4)
+ return HALMAC_RET_FW_NO_SUPPORT;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_BCN_IE_FILTER);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ status = halmac_send_h2c_update_bcn_parse_info_88xx(halmac_adapter,
+ bcn_ie_info);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_send_h2c_update_bcn_parse_info_88xx fail = %x\n",
+ status);
+ return status;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_update_datapack_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_data_type halmac_data_type,
+ struct halmac_phy_parameter_info *para_info)
+{
+ void *driver_adapter = NULL;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_NO_DLFW;
+
+ if (halmac_adapter->fw_version.h2c_version < 4)
+ return HALMAC_RET_FW_NO_SUPPORT;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "[TRACE]%s ==========>\n", __func__);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "[TRACE]%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_run_datapack_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_data_type halmac_data_type)
+{
+ void *driver_adapter = NULL;
+ enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_NO_DLFW;
+
+ if (halmac_adapter->fw_version.h2c_version < 4)
+ return HALMAC_RET_FW_NO_SUPPORT;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_RUN_DATAPACK);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ ret_status = halmac_send_h2c_run_datapack_88xx(halmac_adapter,
+ halmac_data_type);
+
+ if (ret_status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_send_h2c_run_datapack_88xx Fail, datatype = %x, status = %x!!\n",
+ halmac_data_type, ret_status);
+ return ret_status;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "halmac_update_datapack_88xx <==========\n");
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_cfg_drv_info_88xx() - config driver info
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_drv_info : driver information selection
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_cfg_drv_info_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_drv_info halmac_drv_info)
+{
+ u8 drv_info_size = 0;
+ u8 phy_status_en = 0;
+ u8 sniffer_en = 0;
+ u8 plcp_hdr_en = 0;
+ u32 value32;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_DRV_INFO);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "halmac_cfg_drv_info = %d\n", halmac_drv_info);
+
+ switch (halmac_drv_info) {
+ case HALMAC_DRV_INFO_NONE:
+ drv_info_size = 0;
+ phy_status_en = 0;
+ sniffer_en = 0;
+ plcp_hdr_en = 0;
+ break;
+ case HALMAC_DRV_INFO_PHY_STATUS:
+ drv_info_size = 4;
+ phy_status_en = 1;
+ sniffer_en = 0;
+ plcp_hdr_en = 0;
+ break;
+ case HALMAC_DRV_INFO_PHY_SNIFFER:
+ drv_info_size = 5; /* phy status 4byte, sniffer info 1byte */
+ phy_status_en = 1;
+ sniffer_en = 1;
+ plcp_hdr_en = 0;
+ break;
+ case HALMAC_DRV_INFO_PHY_PLCP:
+ drv_info_size = 6; /* phy status 4byte, plcp header 2byte */
+ phy_status_en = 1;
+ sniffer_en = 0;
+ plcp_hdr_en = 1;
+ break;
+ default:
+ status = HALMAC_RET_SW_CASE_NOT_SUPPORT;
+ pr_err("%s error = %x\n", __func__, status);
+ return status;
+ }
+
+ if (halmac_adapter->txff_allocation.rx_fifo_expanding_mode !=
+ HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE)
+ drv_info_size = 0xF;
+
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_RX_DRVINFO_SZ, drv_info_size);
+
+ halmac_adapter->drv_info_size = drv_info_size;
+
+ value32 = HALMAC_REG_READ_32(halmac_adapter, REG_RCR);
+ value32 = (value32 & (~BIT_APP_PHYSTS));
+ if (phy_status_en == 1)
+ value32 = value32 | BIT_APP_PHYSTS;
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_RCR, value32);
+
+ value32 = HALMAC_REG_READ_32(halmac_adapter,
+ REG_WMAC_OPTION_FUNCTION + 4);
+ value32 = (value32 & (~(BIT(8) | BIT(9))));
+ if (sniffer_en == 1)
+ value32 = value32 | BIT(9);
+ if (plcp_hdr_en == 1)
+ value32 = value32 | BIT(8);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_WMAC_OPTION_FUNCTION + 4,
+ value32);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_send_bt_coex_88xx(struct halmac_adapter *halmac_adapter, u8 *bt_buf,
+ u32 bt_size, u8 ack)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_NO_DLFW;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_SEND_BT_COEX);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ ret_status = halmac_send_bt_coex_cmd_88xx(halmac_adapter, bt_buf,
+ bt_size, ack);
+
+ if (ret_status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_send_bt_coex_cmd_88xx Fail = %x!!\n",
+ ret_status);
+ return ret_status;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * (debug API)halmac_verify_platform_api_88xx() - verify platform api
+ * @halmac_adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_verify_platform_api_88xx(struct halmac_adapter *halmac_adapter)
+{
+ void *driver_adapter = NULL;
+ enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter,
+ HALMAC_API_VERIFY_PLATFORM_API);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ ret_status = halmac_verify_io_88xx(halmac_adapter);
+
+ if (ret_status != HALMAC_RET_SUCCESS)
+ return ret_status;
+
+ if (halmac_adapter->txff_allocation.la_mode != HALMAC_LA_MODE_FULL)
+ ret_status = halmac_verify_send_rsvd_page_88xx(halmac_adapter);
+
+ if (ret_status != HALMAC_RET_SUCCESS)
+ return ret_status;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return ret_status;
+}
+
+enum halmac_ret_status
+halmac_send_original_h2c_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *original_h2c, u16 *seq, u8 ack)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_NO_DLFW;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_SEND_ORIGINAL_H2C);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ status = halmac_func_send_original_h2c_88xx(halmac_adapter,
+ original_h2c, seq, ack);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_send_original_h2c FAIL = %x!!\n", status);
+ return status;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_timer_2s_88xx(struct halmac_adapter *halmac_adapter)
+{
+ void *driver_adapter = NULL;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_fill_txdesc_check_sum_88xx() - fill in tx desc check sum
+ * @halmac_adapter : the adapter of halmac
+ * @cur_desc : tx desc packet
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_fill_txdesc_check_sum_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *cur_desc)
+{
+ u16 chk_result = 0;
+ u16 *data = (u16 *)NULL;
+ u32 i;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter,
+ HALMAC_API_FILL_TXDESC_CHECKSUM);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ if (!cur_desc) {
+ pr_err("%s NULL PTR", __func__);
+ return HALMAC_RET_NULL_POINTER;
+ }
+
+ SET_TX_DESC_TXDESC_CHECKSUM(cur_desc, 0x0000);
+
+ data = (u16 *)(cur_desc);
+
+ /* HW clculates only 32byte */
+ for (i = 0; i < 8; i++)
+ chk_result ^= (*(data + 2 * i) ^ *(data + (2 * i + 1)));
+
+ SET_TX_DESC_TXDESC_CHECKSUM(cur_desc, chk_result);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_dump_fifo_88xx() - dump fifo data
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_fifo_sel : FIFO selection
+ * @halmac_start_addr : start address of selected FIFO
+ * @halmac_fifo_dump_size : dump size of selected FIFO
+ * @fifo_map : FIFO data
+ *
+ * Note : before dump fifo, user need to call halmac_get_fifo_size to
+ * get fifo size. Then input this size to halmac_dump_fifo.
+ *
+ * Author : Ivan Lin/KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_dump_fifo_88xx(struct halmac_adapter *halmac_adapter,
+ enum hal_fifo_sel halmac_fifo_sel, u32 halmac_start_addr,
+ u32 halmac_fifo_dump_size, u8 *fifo_map)
+{
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DUMP_FIFO);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ if (halmac_fifo_sel == HAL_FIFO_SEL_TX &&
+ (halmac_start_addr + halmac_fifo_dump_size) >
+ halmac_adapter->hw_config_info.tx_fifo_size) {
+ pr_err("TX fifo dump size is too large\n");
+ return HALMAC_RET_DUMP_FIFOSIZE_INCORRECT;
+ }
+
+ if (halmac_fifo_sel == HAL_FIFO_SEL_RX &&
+ (halmac_start_addr + halmac_fifo_dump_size) >
+ halmac_adapter->hw_config_info.rx_fifo_size) {
+ pr_err("RX fifo dump size is too large\n");
+ return HALMAC_RET_DUMP_FIFOSIZE_INCORRECT;
+ }
+
+ if ((halmac_fifo_dump_size & (4 - 1)) != 0) {
+ pr_err("halmac_fifo_dump_size shall 4byte align\n");
+ return HALMAC_RET_DUMP_FIFOSIZE_INCORRECT;
+ }
+
+ if (!fifo_map) {
+ pr_err("fifo_map address is NULL\n");
+ return HALMAC_RET_NULL_POINTER;
+ }
+
+ status = halmac_buffer_read_88xx(halmac_adapter, halmac_start_addr,
+ halmac_fifo_dump_size, halmac_fifo_sel,
+ fifo_map);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_buffer_read_88xx error = %x\n", status);
+ return status;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_get_fifo_size_88xx() - get fifo size
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_fifo_sel : FIFO selection
+ * Author : Ivan Lin/KaiYuan Chang
+ * Return : u32
+ * More details of status code can be found in prototype document
+ */
+u32 halmac_get_fifo_size_88xx(struct halmac_adapter *halmac_adapter,
+ enum hal_fifo_sel halmac_fifo_sel)
+{
+ u32 fifo_size = 0;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_GET_FIFO_SIZE);
+
+ if (halmac_fifo_sel == HAL_FIFO_SEL_TX)
+ fifo_size = halmac_adapter->hw_config_info.tx_fifo_size;
+ else if (halmac_fifo_sel == HAL_FIFO_SEL_RX)
+ fifo_size = halmac_adapter->hw_config_info.rx_fifo_size;
+ else if (halmac_fifo_sel == HAL_FIFO_SEL_RSVD_PAGE)
+ fifo_size =
+ ((halmac_adapter->hw_config_info.tx_fifo_size >> 7) -
+ halmac_adapter->txff_allocation.rsvd_pg_bndy)
+ << 7;
+ else if (halmac_fifo_sel == HAL_FIFO_SEL_REPORT)
+ fifo_size = 65536;
+ else if (halmac_fifo_sel == HAL_FIFO_SEL_LLT)
+ fifo_size = 65536;
+
+ return fifo_size;
+}
+
+/**
+ * halmac_cfg_txbf_88xx() - enable/disable specific user's txbf
+ * @halmac_adapter : the adapter of halmac
+ * @userid : su bfee userid = 0 or 1 to apply TXBF
+ * @bw : the sounding bandwidth
+ * @txbf_en : 0: disable TXBF, 1: enable TXBF
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_cfg_txbf_88xx(struct halmac_adapter *halmac_adapter, u8 userid,
+ enum halmac_bw bw, u8 txbf_en)
+{
+ u16 temp42C = 0;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_TXBF);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ if (txbf_en) {
+ switch (bw) {
+ case HALMAC_BW_80:
+ temp42C |= BIT_R_TXBF0_80M;
+ case HALMAC_BW_40:
+ temp42C |= BIT_R_TXBF0_40M;
+ case HALMAC_BW_20:
+ temp42C |= BIT_R_TXBF0_20M;
+ break;
+ default:
+ pr_err("%s invalid TXBF BW setting 0x%x of userid %d\n",
+ __func__, bw, userid);
+ return HALMAC_RET_INVALID_SOUNDING_SETTING;
+ }
+ }
+
+ switch (userid) {
+ case 0:
+ temp42C |=
+ HALMAC_REG_READ_16(halmac_adapter, REG_TXBF_CTRL) &
+ ~(BIT_R_TXBF0_20M | BIT_R_TXBF0_40M | BIT_R_TXBF0_80M);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_TXBF_CTRL, temp42C);
+ break;
+ case 1:
+ temp42C |=
+ HALMAC_REG_READ_16(halmac_adapter, REG_TXBF_CTRL + 2) &
+ ~(BIT_R_TXBF0_20M | BIT_R_TXBF0_40M | BIT_R_TXBF0_80M);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_TXBF_CTRL + 2, temp42C);
+ break;
+ default:
+ pr_err("%s invalid userid %d\n", __func__, userid);
+ return HALMAC_RET_INVALID_SOUNDING_SETTING;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
+ "%s, txbf_en = %x <==========\n", __func__,
+ txbf_en);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_cfg_mumimo_88xx() -config mumimo
+ * @halmac_adapter : the adapter of halmac
+ * @cfgmu : parameters to configure MU PPDU Tx/Rx
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_cfg_mumimo_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_cfg_mumimo_para *cfgmu)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ u8 i, idx, id0, id1, gid, mu_tab_sel;
+ u8 mu_tab_valid = 0;
+ u32 gid_valid[6] = {0};
+ u8 temp14C0 = 0;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_MUMIMO);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ if (cfgmu->role == HAL_BFEE) {
+ /*config MU BFEE*/
+ temp14C0 = HALMAC_REG_READ_8(halmac_adapter, REG_MU_TX_CTL) &
+ ~BIT_MASK_R_MU_TABLE_VALID;
+ /*enable MU table 0 and 1, disable MU TX*/
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL,
+ (temp14C0 | BIT(0) | BIT(1)) & ~(BIT(7)));
+
+ /*config GID valid table and user position table*/
+ mu_tab_sel =
+ HALMAC_REG_READ_8(halmac_adapter, REG_MU_TX_CTL + 1) &
+ ~(BIT(0) | BIT(1) | BIT(2));
+ for (i = 0; i < 2; i++) {
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL + 1,
+ mu_tab_sel | i);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_MU_STA_GID_VLD,
+ cfgmu->given_gid_tab[i]);
+ HALMAC_REG_WRITE_32(halmac_adapter,
+ REG_MU_STA_USER_POS_INFO,
+ cfgmu->given_user_pos[i * 2]);
+ HALMAC_REG_WRITE_32(halmac_adapter,
+ REG_MU_STA_USER_POS_INFO + 4,
+ cfgmu->given_user_pos[i * 2 + 1]);
+ }
+ } else {
+ /*config MU BFER*/
+ if (!cfgmu->mu_tx_en) {
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL,
+ HALMAC_REG_READ_8(halmac_adapter,
+ REG_MU_TX_CTL) &
+ ~(BIT(7)));
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
+ "%s disable mu tx <==========\n", __func__);
+ return HALMAC_RET_SUCCESS;
+ }
+
+ /*Transform BB grouping bitmap[14:0] to MAC GID_valid table*/
+ for (idx = 0; idx < 15; idx++) {
+ if (idx < 5) {
+ /*group_bitmap bit0~4, MU_STA0 with MUSTA1~5*/
+ id0 = 0;
+ id1 = (u8)(idx + 1);
+ } else if (idx < 9) {
+ /*group_bitmap bit5~8, MU_STA1 with MUSTA2~5*/
+ id0 = 1;
+ id1 = (u8)(idx - 3);
+ } else if (idx < 12) {
+ /*group_bitmap bit9~11, MU_STA2 with MUSTA3~5*/
+ id0 = 2;
+ id1 = (u8)(idx - 6);
+ } else if (idx < 14) {
+ /*group_bitmap bit12~13, MU_STA3 with MUSTA4~5*/
+ id0 = 3;
+ id1 = (u8)(idx - 8);
+ } else {
+ /*group_bitmap bit14, MU_STA4 with MUSTA5*/
+ id0 = 4;
+ id1 = (u8)(idx - 9);
+ }
+ if (cfgmu->grouping_bitmap & BIT(idx)) {
+ /*Pair 1*/
+ gid = (idx << 1) + 1;
+ gid_valid[id0] |= (BIT(gid));
+ gid_valid[id1] |= (BIT(gid));
+ /*Pair 2*/
+ gid += 1;
+ gid_valid[id0] |= (BIT(gid));
+ gid_valid[id1] |= (BIT(gid));
+ } else {
+ /*Pair 1*/
+ gid = (idx << 1) + 1;
+ gid_valid[id0] &= ~(BIT(gid));
+ gid_valid[id1] &= ~(BIT(gid));
+ /*Pair 2*/
+ gid += 1;
+ gid_valid[id0] &= ~(BIT(gid));
+ gid_valid[id1] &= ~(BIT(gid));
+ }
+ }
+
+ /*set MU STA GID valid TABLE*/
+ mu_tab_sel =
+ HALMAC_REG_READ_8(halmac_adapter, REG_MU_TX_CTL + 1) &
+ ~(BIT(0) | BIT(1) | BIT(2));
+ for (idx = 0; idx < 6; idx++) {
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL + 1,
+ idx | mu_tab_sel);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_MU_STA_GID_VLD,
+ gid_valid[idx]);
+ }
+
+ /*To validate the sounding successful MU STA and enable MU TX*/
+ for (i = 0; i < 6; i++) {
+ if (cfgmu->sounding_sts[i])
+ mu_tab_valid |= BIT(i);
+ }
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL,
+ mu_tab_valid | BIT(7));
+ }
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
+ "%s <==========\n", __func__);
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_cfg_sounding_88xx() - configure general sounding
+ * @halmac_adapter : the adapter of halmac
+ * @role : driver's role, BFer or BFee
+ * @datarate : set ndpa tx rate if driver is BFer, or set csi response rate
+ * if driver is BFee
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_cfg_sounding_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_snd_role role,
+ enum halmac_data_rate datarate)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_SOUNDING);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ switch (role) {
+ case HAL_BFER:
+ HALMAC_REG_WRITE_32(
+ halmac_adapter, REG_TXBF_CTRL,
+ HALMAC_REG_READ_32(halmac_adapter, REG_TXBF_CTRL) |
+ BIT_R_ENABLE_NDPA | BIT_USE_NDPA_PARAMETER |
+ BIT_R_EN_NDPA_INT | BIT_DIS_NDP_BFEN);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_NDPA_RATE, datarate);
+ HALMAC_REG_WRITE_8(
+ halmac_adapter, REG_NDPA_OPT_CTRL,
+ HALMAC_REG_READ_8(halmac_adapter, REG_NDPA_OPT_CTRL) &
+ (~(BIT(0) | BIT(1))));
+ /*service file length 2 bytes; fix non-STA1 csi start offset */
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_SND_PTCL_CTRL + 1,
+ 0x2 | BIT(7));
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_SND_PTCL_CTRL + 2, 0x2);
+ break;
+ case HAL_BFEE:
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_SND_PTCL_CTRL, 0xDB);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_SND_PTCL_CTRL + 3, 0x50);
+ /*use ndpa rx rate to decide csi rate*/
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_BBPSF_CTRL + 3,
+ HALMAC_OFDM54 | BIT(6));
+ HALMAC_REG_WRITE_16(
+ halmac_adapter, REG_RRSR,
+ HALMAC_REG_READ_16(halmac_adapter, REG_RRSR) |
+ BIT(datarate));
+ /*RXFF do not accept BF Rpt Poll, avoid CSI crc error*/
+ HALMAC_REG_WRITE_8(
+ halmac_adapter, REG_RXFLTMAP1,
+ HALMAC_REG_READ_8(halmac_adapter, REG_RXFLTMAP1) &
+ (~(BIT(4))));
+ /*FWFF do not accept BF Rpt Poll, avoid CSI crc error*/
+ HALMAC_REG_WRITE_8(
+ halmac_adapter, REG_RXFLTMAP4,
+ HALMAC_REG_READ_8(halmac_adapter, REG_RXFLTMAP4) &
+ (~(BIT(4))));
+ break;
+ default:
+ pr_err("%s invalid role\n", __func__);
+ return HALMAC_RET_INVALID_SOUNDING_SETTING;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_del_sounding_88xx() - reset general sounding
+ * @halmac_adapter : the adapter of halmac
+ * @role : driver's role, BFer or BFee
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_del_sounding_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_snd_role role)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DEL_SOUNDING);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ switch (role) {
+ case HAL_BFER:
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_TXBF_CTRL + 3, 0);
+ break;
+ case HAL_BFEE:
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_SND_PTCL_CTRL, 0);
+ break;
+ default:
+ pr_err("%s invalid role\n", __func__);
+ return HALMAC_RET_INVALID_SOUNDING_SETTING;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_su_bfee_entry_init_88xx() - config SU beamformee's registers
+ * @halmac_adapter : the adapter of halmac
+ * @userid : SU bfee userid = 0 or 1 to be added
+ * @paid : partial AID of this bfee
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_su_bfee_entry_init_88xx(struct halmac_adapter *halmac_adapter, u8 userid,
+ u16 paid)
+{
+ u16 temp42C = 0;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter,
+ HALMAC_API_SU_BFEE_ENTRY_INIT);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ switch (userid) {
+ case 0:
+ temp42C = HALMAC_REG_READ_16(halmac_adapter, REG_TXBF_CTRL) &
+ ~(BIT_MASK_R_TXBF0_AID | BIT_R_TXBF0_20M |
+ BIT_R_TXBF0_40M | BIT_R_TXBF0_80M);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_TXBF_CTRL,
+ temp42C | paid);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_ASSOCIATED_BFMEE_SEL,
+ paid);
+ break;
+ case 1:
+ temp42C =
+ HALMAC_REG_READ_16(halmac_adapter, REG_TXBF_CTRL + 2) &
+ ~(BIT_MASK_R_TXBF1_AID | BIT_R_TXBF0_20M |
+ BIT_R_TXBF0_40M | BIT_R_TXBF0_80M);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_TXBF_CTRL + 2,
+ temp42C | paid);
+ HALMAC_REG_WRITE_16(halmac_adapter,
+ REG_ASSOCIATED_BFMEE_SEL + 2,
+ paid | BIT(9));
+ break;
+ default:
+ pr_err("%s invalid userid %d\n", __func__,
+ userid);
+ return HALMAC_RET_INVALID_SOUNDING_SETTING;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_su_bfee_entry_init_88xx() - config SU beamformer's registers
+ * @halmac_adapter : the adapter of halmac
+ * @su_bfer_init : parameters to configure SU BFER entry
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_su_bfer_entry_init_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_su_bfer_init_para *su_bfer_init)
+{
+ u16 mac_address_H;
+ u32 mac_address_L;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter,
+ HALMAC_API_SU_BFER_ENTRY_INIT);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ /* mac_address_L = bfer_address.address_l_h.address_low; */
+ /* mac_address_H = bfer_address.address_l_h.address_high; */
+
+ mac_address_L = le32_to_cpu(
+ su_bfer_init->bfer_address.address_l_h.le_address_low);
+ mac_address_H = le16_to_cpu(
+ su_bfer_init->bfer_address.address_l_h.le_address_high);
+
+ switch (su_bfer_init->userid) {
+ case 0:
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO,
+ mac_address_L);
+ HALMAC_REG_WRITE_16(halmac_adapter,
+ REG_ASSOCIATED_BFMER0_INFO + 4,
+ mac_address_H);
+ HALMAC_REG_WRITE_16(halmac_adapter,
+ REG_ASSOCIATED_BFMER0_INFO + 6,
+ su_bfer_init->paid);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_TX_CSI_RPT_PARAM_BW20,
+ su_bfer_init->csi_para);
+ break;
+ case 1:
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER1_INFO,
+ mac_address_L);
+ HALMAC_REG_WRITE_16(halmac_adapter,
+ REG_ASSOCIATED_BFMER1_INFO + 4,
+ mac_address_H);
+ HALMAC_REG_WRITE_16(halmac_adapter,
+ REG_ASSOCIATED_BFMER1_INFO + 6,
+ su_bfer_init->paid);
+ HALMAC_REG_WRITE_16(halmac_adapter,
+ REG_TX_CSI_RPT_PARAM_BW20 + 2,
+ su_bfer_init->csi_para);
+ break;
+ default:
+ pr_err("%s invalid userid %d\n", __func__,
+ su_bfer_init->userid);
+ return HALMAC_RET_INVALID_SOUNDING_SETTING;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_mu_bfee_entry_init_88xx() - config MU beamformee's registers
+ * @halmac_adapter : the adapter of halmac
+ * @mu_bfee_init : parameters to configure MU BFEE entry
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_mu_bfee_entry_init_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_mu_bfee_init_para *mu_bfee_init)
+{
+ u16 temp168X = 0, temp14C0;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter,
+ HALMAC_API_MU_BFEE_ENTRY_INIT);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ temp168X |= mu_bfee_init->paid | BIT(9);
+ HALMAC_REG_WRITE_16(halmac_adapter, (0x1680 + mu_bfee_init->userid * 2),
+ temp168X);
+
+ temp14C0 = HALMAC_REG_READ_16(halmac_adapter, REG_MU_TX_CTL) &
+ ~(BIT(8) | BIT(9) | BIT(10));
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_MU_TX_CTL,
+ temp14C0 | ((mu_bfee_init->userid - 2) << 8));
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_MU_STA_GID_VLD, 0);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_MU_STA_USER_POS_INFO,
+ mu_bfee_init->user_position_l);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_MU_STA_USER_POS_INFO + 4,
+ mu_bfee_init->user_position_h);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_mu_bfer_entry_init_88xx() - config MU beamformer's registers
+ * @halmac_adapter : the adapter of halmac
+ * @mu_bfer_init : parameters to configure MU BFER entry
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_mu_bfer_entry_init_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_mu_bfer_init_para *mu_bfer_init)
+{
+ u16 temp1680 = 0;
+ u16 mac_address_H;
+ u32 mac_address_L;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter,
+ HALMAC_API_MU_BFER_ENTRY_INIT);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ mac_address_L =
+ le32_to_cpu(mu_bfer_init->bfer_address.address_l_h.le_address_low);
+ mac_address_H =
+ le16_to_cpu(mu_bfer_init->bfer_address.address_l_h.le_address_high);
+
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO,
+ mac_address_L);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO + 4,
+ mac_address_H);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO + 6,
+ mu_bfer_init->paid);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_TX_CSI_RPT_PARAM_BW20,
+ mu_bfer_init->csi_para);
+
+ temp1680 = HALMAC_REG_READ_16(halmac_adapter, 0x1680) & 0xC000;
+ temp1680 |= mu_bfer_init->my_aid | (mu_bfer_init->csi_length_sel << 12);
+ HALMAC_REG_WRITE_16(halmac_adapter, 0x1680, temp1680);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_su_bfee_entry_del_88xx() - reset SU beamformee's registers
+ * @halmac_adapter : the adapter of halmac
+ * @userid : the SU BFee userid to be deleted
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_su_bfee_entry_del_88xx(struct halmac_adapter *halmac_adapter, u8 userid)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_SU_BFEE_ENTRY_DEL);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ switch (userid) {
+ case 0:
+ HALMAC_REG_WRITE_16(
+ halmac_adapter, REG_TXBF_CTRL,
+ HALMAC_REG_READ_16(halmac_adapter, REG_TXBF_CTRL) &
+ ~(BIT_MASK_R_TXBF0_AID | BIT_R_TXBF0_20M |
+ BIT_R_TXBF0_40M | BIT_R_TXBF0_80M));
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_ASSOCIATED_BFMEE_SEL,
+ 0);
+ break;
+ case 1:
+ HALMAC_REG_WRITE_16(
+ halmac_adapter, REG_TXBF_CTRL + 2,
+ HALMAC_REG_READ_16(halmac_adapter, REG_TXBF_CTRL + 2) &
+ ~(BIT_MASK_R_TXBF1_AID | BIT_R_TXBF0_20M |
+ BIT_R_TXBF0_40M | BIT_R_TXBF0_80M));
+ HALMAC_REG_WRITE_16(halmac_adapter,
+ REG_ASSOCIATED_BFMEE_SEL + 2, 0);
+ break;
+ default:
+ pr_err("%s invalid userid %d\n", __func__,
+ userid);
+ return HALMAC_RET_INVALID_SOUNDING_SETTING;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_su_bfee_entry_del_88xx() - reset SU beamformer's registers
+ * @halmac_adapter : the adapter of halmac
+ * @userid : the SU BFer userid to be deleted
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_su_bfer_entry_del_88xx(struct halmac_adapter *halmac_adapter, u8 userid)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_SU_BFER_ENTRY_DEL);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ switch (userid) {
+ case 0:
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO,
+ 0);
+ HALMAC_REG_WRITE_32(halmac_adapter,
+ REG_ASSOCIATED_BFMER0_INFO + 4, 0);
+ break;
+ case 1:
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER1_INFO,
+ 0);
+ HALMAC_REG_WRITE_32(halmac_adapter,
+ REG_ASSOCIATED_BFMER1_INFO + 4, 0);
+ break;
+ default:
+ pr_err("%s invalid userid %d\n", __func__,
+ userid);
+ return HALMAC_RET_INVALID_SOUNDING_SETTING;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_mu_bfee_entry_del_88xx() - reset MU beamformee's registers
+ * @halmac_adapter : the adapter of halmac
+ * @userid : the MU STA userid to be deleted
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_mu_bfee_entry_del_88xx(struct halmac_adapter *halmac_adapter, u8 userid)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_MU_BFEE_ENTRY_DEL);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_REG_WRITE_16(halmac_adapter, 0x1680 + userid * 2, 0);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL,
+ HALMAC_REG_READ_8(halmac_adapter, REG_MU_TX_CTL) &
+ ~(BIT(userid - 2)));
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_mu_bfer_entry_del_88xx() -reset MU beamformer's registers
+ * @halmac_adapter : the adapter of halmac
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_mu_bfer_entry_del_88xx(struct halmac_adapter *halmac_adapter)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_MU_BFER_ENTRY_DEL);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO, 0);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO + 4, 0);
+ HALMAC_REG_WRITE_16(halmac_adapter, 0x1680, 0);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL, 0);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_add_ch_info_88xx() -add channel information
+ * @halmac_adapter : the adapter of halmac
+ * @ch_info : channel information
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_add_ch_info_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_ch_info *ch_info)
+{
+ void *driver_adapter = NULL;
+ struct halmac_cs_info *ch_sw_info;
+ enum halmac_scan_cmd_construct_state state_scan;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ ch_sw_info = &halmac_adapter->ch_sw_info;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "[TRACE]%s ==========>\n", __func__);
+
+ if (halmac_adapter->halmac_state.dlfw_state != HALMAC_GEN_INFO_SENT) {
+ pr_err("[ERR]%s: gen_info is not send to FW!!!!\n", __func__);
+ return HALMAC_RET_GEN_INFO_NOT_SENT;
+ }
+
+ state_scan = halmac_query_scan_curr_state_88xx(halmac_adapter);
+ if (state_scan != HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED &&
+ state_scan != HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_WARNING,
+ "[WARN]Scan machine fail(add ch info)...\n");
+ return HALMAC_RET_ERROR_STATE;
+ }
+
+ if (!ch_sw_info->ch_info_buf) {
+ ch_sw_info->ch_info_buf =
+ kzalloc(HALMAC_EXTRA_INFO_BUFF_SIZE_88XX, GFP_KERNEL);
+ if (!ch_sw_info->ch_info_buf)
+ return HALMAC_RET_NULL_POINTER;
+ ch_sw_info->ch_info_buf_w = ch_sw_info->ch_info_buf;
+ ch_sw_info->buf_size = HALMAC_EXTRA_INFO_BUFF_SIZE_88XX;
+ ch_sw_info->avai_buf_size = HALMAC_EXTRA_INFO_BUFF_SIZE_88XX;
+ ch_sw_info->total_size = 0;
+ ch_sw_info->extra_info_en = 0;
+ ch_sw_info->ch_num = 0;
+ }
+
+ if (ch_sw_info->extra_info_en == 1) {
+ pr_err("[ERR]%s: construct sequence wrong!!\n", __func__);
+ return HALMAC_RET_CH_SW_SEQ_WRONG;
+ }
+
+ if (ch_sw_info->avai_buf_size < 4) {
+ pr_err("[ERR]%s: no available buffer!!\n", __func__);
+ return HALMAC_RET_CH_SW_NO_BUF;
+ }
+
+ if (halmac_transition_scan_state_88xx(
+ halmac_adapter, HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING) !=
+ HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ERROR_STATE;
+
+ CHANNEL_INFO_SET_CHANNEL(ch_sw_info->ch_info_buf_w, ch_info->channel);
+ CHANNEL_INFO_SET_PRI_CH_IDX(ch_sw_info->ch_info_buf_w,
+ ch_info->pri_ch_idx);
+ CHANNEL_INFO_SET_BANDWIDTH(ch_sw_info->ch_info_buf_w, ch_info->bw);
+ CHANNEL_INFO_SET_TIMEOUT(ch_sw_info->ch_info_buf_w, ch_info->timeout);
+ CHANNEL_INFO_SET_ACTION_ID(ch_sw_info->ch_info_buf_w,
+ ch_info->action_id);
+ CHANNEL_INFO_SET_CH_EXTRA_INFO(ch_sw_info->ch_info_buf_w,
+ ch_info->extra_info);
+
+ ch_sw_info->avai_buf_size = ch_sw_info->avai_buf_size - 4;
+ ch_sw_info->total_size = ch_sw_info->total_size + 4;
+ ch_sw_info->ch_num++;
+ ch_sw_info->extra_info_en = ch_info->extra_info;
+ ch_sw_info->ch_info_buf_w = ch_sw_info->ch_info_buf_w + 4;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "[TRACE]%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_add_extra_ch_info_88xx() -add extra channel information
+ * @halmac_adapter : the adapter of halmac
+ * @ch_extra_info : extra channel information
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_add_extra_ch_info_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_ch_extra_info *ch_extra_info)
+{
+ void *driver_adapter = NULL;
+ struct halmac_cs_info *ch_sw_info;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_ADD_EXTRA_CH_INFO);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ ch_sw_info = &halmac_adapter->ch_sw_info;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ if (!ch_sw_info->ch_info_buf) {
+ pr_err("%s: NULL==ch_sw_info->ch_info_buf!!\n", __func__);
+ return HALMAC_RET_CH_SW_SEQ_WRONG;
+ }
+
+ if (ch_sw_info->extra_info_en == 0) {
+ pr_err("%s: construct sequence wrong!!\n", __func__);
+ return HALMAC_RET_CH_SW_SEQ_WRONG;
+ }
+
+ if (ch_sw_info->avai_buf_size <
+ (u32)(ch_extra_info->extra_info_size + 2)) {
+ /* +2: ch_extra_info_id, ch_extra_info, ch_extra_info_size
+ * are totally 2Byte
+ */
+ pr_err("%s: no available buffer!!\n", __func__);
+ return HALMAC_RET_CH_SW_NO_BUF;
+ }
+
+ if (halmac_query_scan_curr_state_88xx(halmac_adapter) !=
+ HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Scan machine fail(add extra ch info)...\n");
+ return HALMAC_RET_ERROR_STATE;
+ }
+
+ if (halmac_transition_scan_state_88xx(
+ halmac_adapter, HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING) !=
+ HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ERROR_STATE;
+
+ CH_EXTRA_INFO_SET_CH_EXTRA_INFO_ID(ch_sw_info->ch_info_buf_w,
+ ch_extra_info->extra_action_id);
+ CH_EXTRA_INFO_SET_CH_EXTRA_INFO(ch_sw_info->ch_info_buf_w,
+ ch_extra_info->extra_info);
+ CH_EXTRA_INFO_SET_CH_EXTRA_INFO_SIZE(ch_sw_info->ch_info_buf_w,
+ ch_extra_info->extra_info_size);
+ memcpy(ch_sw_info->ch_info_buf_w + 2, ch_extra_info->extra_info_data,
+ ch_extra_info->extra_info_size);
+
+ ch_sw_info->avai_buf_size = ch_sw_info->avai_buf_size -
+ (2 + ch_extra_info->extra_info_size);
+ ch_sw_info->total_size =
+ ch_sw_info->total_size + (2 + ch_extra_info->extra_info_size);
+ ch_sw_info->extra_info_en = ch_extra_info->extra_info;
+ ch_sw_info->ch_info_buf_w = ch_sw_info->ch_info_buf_w +
+ (2 + ch_extra_info->extra_info_size);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_ctrl_ch_switch_88xx() -send channel switch cmd
+ * @halmac_adapter : the adapter of halmac
+ * @cs_option : channel switch config
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_ctrl_ch_switch_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_ch_switch_option *cs_option)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+ enum halmac_scan_cmd_construct_state state_scan;
+ enum halmac_cmd_process_status *process_status =
+ &halmac_adapter->halmac_state.scan_state_set.process_status;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_NO_DLFW;
+
+ if (halmac_adapter->fw_version.h2c_version < 4)
+ return HALMAC_RET_FW_NO_SUPPORT;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CTRL_CH_SWITCH);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s cs_option->switch_en = %d==========>\n", __func__,
+ cs_option->switch_en);
+
+ if (!cs_option->switch_en)
+ *process_status = HALMAC_CMD_PROCESS_IDLE;
+
+ if (*process_status == HALMAC_CMD_PROCESS_SENDING ||
+ *process_status == HALMAC_CMD_PROCESS_RCVD) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Wait event(ctrl ch switch)...\n");
+ return HALMAC_RET_BUSY_STATE;
+ }
+
+ state_scan = halmac_query_scan_curr_state_88xx(halmac_adapter);
+ if (cs_option->switch_en) {
+ if (state_scan != HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C,
+ DBG_DMESG,
+ "%s(on) invalid in state %x\n",
+ __func__, state_scan);
+ return HALMAC_RET_ERROR_STATE;
+ }
+ } else {
+ if (state_scan != HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED) {
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s(off) invalid in state %x\n", __func__,
+ state_scan);
+ return HALMAC_RET_ERROR_STATE;
+ }
+ }
+
+ status = halmac_func_ctrl_ch_switch_88xx(halmac_adapter, cs_option);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_ctrl_ch_switch FAIL = %x!!\n", status);
+ return status;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_clear_ch_info_88xx() -clear channel information
+ * @halmac_adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_clear_ch_info_88xx(struct halmac_adapter *halmac_adapter)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CLEAR_CH_INFO);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ if (halmac_query_scan_curr_state_88xx(halmac_adapter) ==
+ HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Scan machine fail(clear ch info)...\n");
+ return HALMAC_RET_ERROR_STATE;
+ }
+
+ if (halmac_transition_scan_state_88xx(
+ halmac_adapter, HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED) !=
+ HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ERROR_STATE;
+
+ kfree(halmac_adapter->ch_sw_info.ch_info_buf);
+ halmac_adapter->ch_sw_info.ch_info_buf = NULL;
+ halmac_adapter->ch_sw_info.ch_info_buf_w = NULL;
+ halmac_adapter->ch_sw_info.extra_info_en = 0;
+ halmac_adapter->ch_sw_info.buf_size = 0;
+ halmac_adapter->ch_sw_info.avai_buf_size = 0;
+ halmac_adapter->ch_sw_info.total_size = 0;
+ halmac_adapter->ch_sw_info.ch_num = 0;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status halmac_p2pps_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_p2pps *p2p_ps)
+{
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_NO_DLFW;
+
+ if (halmac_adapter->fw_version.h2c_version < 6)
+ return HALMAC_RET_FW_NO_SUPPORT;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ status = halmac_func_p2pps_88xx(halmac_adapter, p2p_ps);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("[ERR]halmac_p2pps FAIL = %x!!\n", status);
+ return status;
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_func_p2pps_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_p2pps *p2p_ps)
+{
+ u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
+ u16 h2c_seq_mum = 0;
+ void *driver_adapter = halmac_adapter->driver_adapter;
+ struct halmac_api *halmac_api;
+ struct halmac_h2c_header_info h2c_header_info;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "[TRACE]halmac_p2pps !!\n");
+
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ P2PPS_SET_OFFLOAD_EN(h2c_buff, p2p_ps->offload_en);
+ P2PPS_SET_ROLE(h2c_buff, p2p_ps->role);
+ P2PPS_SET_CTWINDOW_EN(h2c_buff, p2p_ps->ctwindow_en);
+ P2PPS_SET_NOA_EN(h2c_buff, p2p_ps->noa_en);
+ P2PPS_SET_NOA_SEL(h2c_buff, p2p_ps->noa_sel);
+ P2PPS_SET_ALLSTASLEEP(h2c_buff, p2p_ps->all_sta_sleep);
+ P2PPS_SET_DISCOVERY(h2c_buff, p2p_ps->discovery);
+ P2PPS_SET_P2P_PORT_ID(h2c_buff, p2p_ps->p2p_port_id);
+ P2PPS_SET_P2P_GROUP(h2c_buff, p2p_ps->p2p_group);
+ P2PPS_SET_P2P_MACID(h2c_buff, p2p_ps->p2p_macid);
+
+ P2PPS_SET_CTWINDOW_LENGTH(h2c_buff, p2p_ps->ctwindow_length);
+
+ P2PPS_SET_NOA_DURATION_PARA(h2c_buff, p2p_ps->noa_duration_para);
+ P2PPS_SET_NOA_INTERVAL_PARA(h2c_buff, p2p_ps->noa_interval_para);
+ P2PPS_SET_NOA_START_TIME_PARA(h2c_buff, p2p_ps->noa_start_time_para);
+ P2PPS_SET_NOA_COUNT_PARA(h2c_buff, p2p_ps->noa_count_para);
+
+ h2c_header_info.sub_cmd_id = SUB_CMD_ID_P2PPS;
+ h2c_header_info.content_size = 24;
+ h2c_header_info.ack = false;
+ halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
+ &h2c_header_info, &h2c_seq_mum);
+
+ status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
+ HALMAC_H2C_CMD_SIZE_88XX, false);
+
+ if (status != HALMAC_RET_SUCCESS)
+ pr_err("[ERR]halmac_send_h2c_p2pps_88xx Fail = %x!!\n", status);
+
+ return status;
+}
+
+/**
+ * halmac_send_general_info_88xx() -send general information to FW
+ * @halmac_adapter : the adapter of halmac
+ * @general_info : general information
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_send_general_info_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_general_info *general_info)
+{
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_NO_DLFW;
+
+ if (halmac_adapter->fw_version.h2c_version < 4)
+ return HALMAC_RET_FW_NO_SUPPORT;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_SEND_GENERAL_INFO);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ if (halmac_adapter->halmac_state.dlfw_state == HALMAC_DLFW_NONE) {
+ pr_err("%s Fail due to DLFW NONE!!\n", __func__);
+ return HALMAC_RET_DLFW_FAIL;
+ }
+
+ status = halmac_func_send_general_info_88xx(halmac_adapter,
+ general_info);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_send_general_info error = %x\n", status);
+ return status;
+ }
+
+ if (halmac_adapter->halmac_state.dlfw_state == HALMAC_DLFW_DONE)
+ halmac_adapter->halmac_state.dlfw_state = HALMAC_GEN_INFO_SENT;
+
+ halmac_adapter->gen_info_valid = true;
+ memcpy(&halmac_adapter->general_info, general_info,
+ sizeof(struct halmac_general_info));
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_start_iqk_88xx() -trigger FW IQK
+ * @halmac_adapter : the adapter of halmac
+ * @iqk_para : IQK parameter
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_start_iqk_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_iqk_para_ *iqk_para)
+{
+ u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
+ u16 h2c_seq_num = 0;
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+ struct halmac_h2c_header_info h2c_header_info;
+ enum halmac_cmd_process_status *process_status =
+ &halmac_adapter->halmac_state.iqk_set.process_status;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_NO_DLFW;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_START_IQK);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Wait event(iqk)...\n");
+ return HALMAC_RET_BUSY_STATE;
+ }
+
+ *process_status = HALMAC_CMD_PROCESS_SENDING;
+
+ IQK_SET_CLEAR(h2c_buff, iqk_para->clear);
+ IQK_SET_SEGMENT_IQK(h2c_buff, iqk_para->segment_iqk);
+
+ h2c_header_info.sub_cmd_id = SUB_CMD_ID_IQK;
+ h2c_header_info.content_size = 1;
+ h2c_header_info.ack = true;
+ halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
+ &h2c_header_info, &h2c_seq_num);
+
+ halmac_adapter->halmac_state.iqk_set.seq_num = h2c_seq_num;
+
+ status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
+ HALMAC_H2C_CMD_SIZE_88XX, true);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
+ return status;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_ctrl_pwr_tracking_88xx() -trigger FW power tracking
+ * @halmac_adapter : the adapter of halmac
+ * @pwr_tracking_opt : power tracking option
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status halmac_ctrl_pwr_tracking_88xx(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_pwr_tracking_option *pwr_tracking_opt)
+{
+ u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
+ u16 h2c_seq_mum = 0;
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+ struct halmac_h2c_header_info h2c_header_info;
+ enum halmac_cmd_process_status *process_status =
+ &halmac_adapter->halmac_state.power_tracking_set.process_status;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_NO_DLFW;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CTRL_PWR_TRACKING);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "halmac_start_iqk_88xx ==========>\n");
+
+ if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Wait event(pwr tracking)...\n");
+ return HALMAC_RET_BUSY_STATE;
+ }
+
+ *process_status = HALMAC_CMD_PROCESS_SENDING;
+
+ POWER_TRACKING_SET_TYPE(h2c_buff, pwr_tracking_opt->type);
+ POWER_TRACKING_SET_BBSWING_INDEX(h2c_buff,
+ pwr_tracking_opt->bbswing_index);
+ POWER_TRACKING_SET_ENABLE_A(
+ h2c_buff,
+ pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_A].enable);
+ POWER_TRACKING_SET_TX_PWR_INDEX_A(
+ h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_A]
+ .tx_pwr_index);
+ POWER_TRACKING_SET_PWR_TRACKING_OFFSET_VALUE_A(
+ h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_A]
+ .pwr_tracking_offset_value);
+ POWER_TRACKING_SET_TSSI_VALUE_A(
+ h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_A]
+ .tssi_value);
+ POWER_TRACKING_SET_ENABLE_B(
+ h2c_buff,
+ pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_B].enable);
+ POWER_TRACKING_SET_TX_PWR_INDEX_B(
+ h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_B]
+ .tx_pwr_index);
+ POWER_TRACKING_SET_PWR_TRACKING_OFFSET_VALUE_B(
+ h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_B]
+ .pwr_tracking_offset_value);
+ POWER_TRACKING_SET_TSSI_VALUE_B(
+ h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_B]
+ .tssi_value);
+ POWER_TRACKING_SET_ENABLE_C(
+ h2c_buff,
+ pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_C].enable);
+ POWER_TRACKING_SET_TX_PWR_INDEX_C(
+ h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_C]
+ .tx_pwr_index);
+ POWER_TRACKING_SET_PWR_TRACKING_OFFSET_VALUE_C(
+ h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_C]
+ .pwr_tracking_offset_value);
+ POWER_TRACKING_SET_TSSI_VALUE_C(
+ h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_C]
+ .tssi_value);
+ POWER_TRACKING_SET_ENABLE_D(
+ h2c_buff,
+ pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_D].enable);
+ POWER_TRACKING_SET_TX_PWR_INDEX_D(
+ h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_D]
+ .tx_pwr_index);
+ POWER_TRACKING_SET_PWR_TRACKING_OFFSET_VALUE_D(
+ h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_D]
+ .pwr_tracking_offset_value);
+ POWER_TRACKING_SET_TSSI_VALUE_D(
+ h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_D]
+ .tssi_value);
+
+ h2c_header_info.sub_cmd_id = SUB_CMD_ID_POWER_TRACKING;
+ h2c_header_info.content_size = 20;
+ h2c_header_info.ack = true;
+ halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
+ &h2c_header_info, &h2c_seq_mum);
+
+ halmac_adapter->halmac_state.power_tracking_set.seq_num = h2c_seq_mum;
+
+ status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
+ HALMAC_H2C_CMD_SIZE_88XX, true);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
+ return status;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "halmac_start_iqk_88xx <==========\n");
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_query_status_88xx() -query the offload feature status
+ * @halmac_adapter : the adapter of halmac
+ * @feature_id : feature_id
+ * @process_status : feature_status
+ * @data : data buffer
+ * @size : data size
+ *
+ * Note :
+ * If user wants to know the data size, use can allocate zero
+ * size buffer first. If this size less than the data size, halmac
+ * will return HALMAC_RET_BUFFER_TOO_SMALL. User need to
+ * re-allocate data buffer with correct data size.
+ *
+ * Author : Ivan Lin/KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_query_status_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_feature_id feature_id,
+ enum halmac_cmd_process_status *process_status,
+ u8 *data, u32 *size)
+{
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_QUERY_STATE);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ if (!process_status) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "null pointer!!\n");
+ return HALMAC_RET_NULL_POINTER;
+ }
+
+ switch (feature_id) {
+ case HALMAC_FEATURE_CFG_PARA:
+ status = halmac_query_cfg_para_status_88xx(
+ halmac_adapter, process_status, data, size);
+ break;
+ case HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE:
+ status = halmac_query_dump_physical_efuse_status_88xx(
+ halmac_adapter, process_status, data, size);
+ break;
+ case HALMAC_FEATURE_DUMP_LOGICAL_EFUSE:
+ status = halmac_query_dump_logical_efuse_status_88xx(
+ halmac_adapter, process_status, data, size);
+ break;
+ case HALMAC_FEATURE_CHANNEL_SWITCH:
+ status = halmac_query_channel_switch_status_88xx(
+ halmac_adapter, process_status, data, size);
+ break;
+ case HALMAC_FEATURE_UPDATE_PACKET:
+ status = halmac_query_update_packet_status_88xx(
+ halmac_adapter, process_status, data, size);
+ break;
+ case HALMAC_FEATURE_IQK:
+ status = halmac_query_iqk_status_88xx(
+ halmac_adapter, process_status, data, size);
+ break;
+ case HALMAC_FEATURE_POWER_TRACKING:
+ status = halmac_query_power_tracking_status_88xx(
+ halmac_adapter, process_status, data, size);
+ break;
+ case HALMAC_FEATURE_PSD:
+ status = halmac_query_psd_status_88xx(
+ halmac_adapter, process_status, data, size);
+ break;
+ default:
+ pr_err("%s invalid feature id %d\n", __func__,
+ feature_id);
+ return HALMAC_RET_INVALID_FEATURE_ID;
+ }
+
+ return status;
+}
+
+/**
+ * halmac_reset_feature_88xx() -reset async api cmd status
+ * @halmac_adapter : the adapter of halmac
+ * @feature_id : feature_id
+ * Author : Ivan Lin/KaiYuan Chang
+ * Return : enum halmac_ret_status.
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_reset_feature_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_feature_id feature_id)
+{
+ void *driver_adapter = NULL;
+ struct halmac_state *state = &halmac_adapter->halmac_state;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_RESET_FEATURE);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ switch (feature_id) {
+ case HALMAC_FEATURE_CFG_PARA:
+ state->cfg_para_state_set.process_status =
+ HALMAC_CMD_PROCESS_IDLE;
+ state->cfg_para_state_set.cfg_para_cmd_construct_state =
+ HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE;
+ break;
+ case HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE:
+ case HALMAC_FEATURE_DUMP_LOGICAL_EFUSE:
+ state->efuse_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
+ state->efuse_state_set.efuse_cmd_construct_state =
+ HALMAC_EFUSE_CMD_CONSTRUCT_IDLE;
+ break;
+ case HALMAC_FEATURE_CHANNEL_SWITCH:
+ state->scan_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
+ state->scan_state_set.scan_cmd_construct_state =
+ HALMAC_SCAN_CMD_CONSTRUCT_IDLE;
+ break;
+ case HALMAC_FEATURE_UPDATE_PACKET:
+ state->update_packet_set.process_status =
+ HALMAC_CMD_PROCESS_IDLE;
+ break;
+ case HALMAC_FEATURE_ALL:
+ state->cfg_para_state_set.process_status =
+ HALMAC_CMD_PROCESS_IDLE;
+ state->cfg_para_state_set.cfg_para_cmd_construct_state =
+ HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE;
+ state->efuse_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
+ state->efuse_state_set.efuse_cmd_construct_state =
+ HALMAC_EFUSE_CMD_CONSTRUCT_IDLE;
+ state->scan_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
+ state->scan_state_set.scan_cmd_construct_state =
+ HALMAC_SCAN_CMD_CONSTRUCT_IDLE;
+ state->update_packet_set.process_status =
+ HALMAC_CMD_PROCESS_IDLE;
+ break;
+ default:
+ pr_err("%s invalid feature id %d\n", __func__,
+ feature_id);
+ return HALMAC_RET_INVALID_FEATURE_ID;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_check_fw_status_88xx() -check fw status
+ * @halmac_adapter : the adapter of halmac
+ * @fw_status : fw status
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_check_fw_status_88xx(struct halmac_adapter *halmac_adapter,
+ bool *fw_status)
+{
+ u32 value32 = 0, value32_backup = 0, i = 0;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CHECK_FW_STATUS);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ value32 = PLATFORM_REG_READ_32(driver_adapter, REG_FW_DBG6);
+
+ if (value32 != 0) {
+ pr_err("halmac_check_fw_status REG_FW_DBG6 !=0\n");
+ *fw_status = false;
+ return status;
+ }
+
+ value32_backup = PLATFORM_REG_READ_32(driver_adapter, REG_FW_DBG7);
+
+ for (i = 0; i <= 10; i++) {
+ value32 = PLATFORM_REG_READ_32(driver_adapter, REG_FW_DBG7);
+ if (value32_backup != value32)
+ break;
+
+ if (i == 10) {
+ pr_err("halmac_check_fw_status Polling FW PC fail\n");
+ *fw_status = false;
+ return status;
+ }
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return status;
+}
+
+enum halmac_ret_status
+halmac_dump_fw_dmem_88xx(struct halmac_adapter *halmac_adapter, u8 *dmem,
+ u32 *size)
+{
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DUMP_FW_DMEM);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return status;
+}
+
+/**
+ * halmac_cfg_max_dl_size_88xx() - config max download FW size
+ * @halmac_adapter : the adapter of halmac
+ * @size : max download fw size
+ *
+ * Halmac uses this setting to set max packet size for
+ * download FW.
+ * If user has not called this API, halmac use default
+ * setting for download FW
+ * Note1 : size need multiple of 2
+ * Note2 : max size is 31K
+ *
+ * Author : Ivan Lin/KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_cfg_max_dl_size_88xx(struct halmac_adapter *halmac_adapter, u32 size)
+{
+ void *driver_adapter = NULL;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_MAX_DL_SIZE);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_FW, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ if (size > HALMAC_FW_CFG_MAX_DL_SIZE_MAX_88XX) {
+ pr_err("size > HALMAC_FW_CFG_MAX_DL_SIZE_MAX!\n");
+ return HALMAC_RET_CFG_DLFW_SIZE_FAIL;
+ }
+
+ if ((size & (2 - 1)) != 0) {
+ pr_err("size is not power of 2!\n");
+ return HALMAC_RET_CFG_DLFW_SIZE_FAIL;
+ }
+
+ halmac_adapter->max_download_size = size;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_FW, DBG_DMESG,
+ "Cfg max size is : %X\n", size);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_FW, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_psd_88xx() - trigger fw psd
+ * @halmac_adapter : the adapter of halmac
+ * @start_psd : start PSD
+ * @end_psd : end PSD
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status halmac_psd_88xx(struct halmac_adapter *halmac_adapter,
+ u16 start_psd, u16 end_psd)
+{
+ u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
+ u16 h2c_seq_mum = 0;
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+ struct halmac_h2c_header_info h2c_header_info;
+ enum halmac_cmd_process_status *process_status =
+ &halmac_adapter->halmac_state.psd_set.process_status;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_NO_DLFW;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_PSD);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Wait event(psd)...\n");
+ return HALMAC_RET_BUSY_STATE;
+ }
+
+ kfree(halmac_adapter->halmac_state.psd_set.data);
+ halmac_adapter->halmac_state.psd_set.data = (u8 *)NULL;
+
+ halmac_adapter->halmac_state.psd_set.data_size = 0;
+ halmac_adapter->halmac_state.psd_set.segment_size = 0;
+
+ *process_status = HALMAC_CMD_PROCESS_SENDING;
+
+ PSD_SET_START_PSD(h2c_buff, start_psd);
+ PSD_SET_END_PSD(h2c_buff, end_psd);
+
+ h2c_header_info.sub_cmd_id = SUB_CMD_ID_PSD;
+ h2c_header_info.content_size = 4;
+ h2c_header_info.ack = true;
+ halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
+ &h2c_header_info, &h2c_seq_mum);
+
+ status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
+ HALMAC_H2C_CMD_SIZE_88XX, true);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
+ return status;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_cfg_la_mode_88xx() - config la mode
+ * @halmac_adapter : the adapter of halmac
+ * @la_mode :
+ * disable : no TXFF space reserved for LA debug
+ * partial : partial TXFF space is reserved for LA debug
+ * full : all TXFF space is reserved for LA debug
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_cfg_la_mode_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_la_mode la_mode)
+{
+ void *driver_adapter = NULL;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_LA_MODE);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s ==========>la_mode = %d\n", __func__,
+ la_mode);
+
+ halmac_adapter->txff_allocation.la_mode = la_mode;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_cfg_rx_fifo_expanding_mode_88xx() - rx fifo expanding
+ * @halmac_adapter : the adapter of halmac
+ * @la_mode :
+ * disable : normal mode
+ * 1 block : Rx FIFO + 1 FIFO block; Tx fifo - 1 FIFO block
+ * 2 block : Rx FIFO + 2 FIFO block; Tx fifo - 2 FIFO block
+ * 3 block : Rx FIFO + 3 FIFO block; Tx fifo - 3 FIFO block
+ * Author : Soar
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status halmac_cfg_rx_fifo_expanding_mode_88xx(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_rx_fifo_expanding_mode rx_fifo_expanding_mode)
+{
+ void *driver_adapter = NULL;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter,
+ HALMAC_API_CFG_RX_FIFO_EXPANDING_MODE);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s ==========>rx_fifo_expanding_mode = %d\n", __func__,
+ rx_fifo_expanding_mode);
+
+ halmac_adapter->txff_allocation.rx_fifo_expanding_mode =
+ rx_fifo_expanding_mode;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_config_security_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_security_setting *sec_setting)
+{
+ struct halmac_api *halmac_api;
+ void *driver_adapter = NULL;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_CR,
+ (u16)(HALMAC_REG_READ_16(halmac_adapter, REG_CR) |
+ BIT_MAC_SEC_EN));
+
+ if (sec_setting->tx_encryption == 1)
+ HALMAC_REG_WRITE_8(
+ halmac_adapter, REG_SECCFG,
+ HALMAC_REG_READ_8(halmac_adapter, REG_SECCFG) | BIT(2));
+ else
+ HALMAC_REG_WRITE_8(
+ halmac_adapter, REG_SECCFG,
+ HALMAC_REG_READ_8(halmac_adapter, REG_SECCFG) &
+ ~(BIT(2)));
+
+ if (sec_setting->rx_decryption == 1)
+ HALMAC_REG_WRITE_8(
+ halmac_adapter, REG_SECCFG,
+ HALMAC_REG_READ_8(halmac_adapter, REG_SECCFG) | BIT(3));
+ else
+ HALMAC_REG_WRITE_8(
+ halmac_adapter, REG_SECCFG,
+ HALMAC_REG_READ_8(halmac_adapter, REG_SECCFG) &
+ ~(BIT(3)));
+
+ if (sec_setting->bip_enable == 1) {
+ if (halmac_adapter->chip_id == HALMAC_CHIP_ID_8822B)
+ return HALMAC_RET_BIP_NO_SUPPORT;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+u8 halmac_get_used_cam_entry_num_88xx(struct halmac_adapter *halmac_adapter,
+ enum hal_security_type sec_type)
+{
+ u8 entry_num;
+ void *driver_adapter = NULL;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ switch (sec_type) {
+ case HAL_SECURITY_TYPE_WEP40:
+ case HAL_SECURITY_TYPE_WEP104:
+ case HAL_SECURITY_TYPE_TKIP:
+ case HAL_SECURITY_TYPE_AES128:
+ case HAL_SECURITY_TYPE_GCMP128:
+ case HAL_SECURITY_TYPE_GCMSMS4:
+ case HAL_SECURITY_TYPE_BIP:
+ entry_num = 1;
+ break;
+ case HAL_SECURITY_TYPE_WAPI:
+ case HAL_SECURITY_TYPE_AES256:
+ case HAL_SECURITY_TYPE_GCMP256:
+ entry_num = 2;
+ break;
+ default:
+ entry_num = 0;
+ break;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return entry_num;
+}
+
+enum halmac_ret_status
+halmac_write_cam_88xx(struct halmac_adapter *halmac_adapter, u32 entry_index,
+ struct halmac_cam_entry_info *cam_entry_info)
+{
+ u32 i;
+ u32 command = 0x80010000;
+ struct halmac_api *halmac_api;
+ void *driver_adapter = NULL;
+ struct halmac_cam_entry_format *cam_entry_format = NULL;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
+ "[TRACE]%s ==========>\n", __func__);
+
+ if (entry_index >= halmac_adapter->hw_config_info.cam_entry_num)
+ return HALMAC_RET_ENTRY_INDEX_ERROR;
+
+ if (cam_entry_info->key_id > 3)
+ return HALMAC_RET_FAIL;
+
+ cam_entry_format = kzalloc(sizeof(*cam_entry_format), GFP_KERNEL);
+ if (!cam_entry_format)
+ return HALMAC_RET_NULL_POINTER;
+
+ cam_entry_format->key_id = cam_entry_info->key_id;
+ cam_entry_format->valid = cam_entry_info->valid;
+ memcpy(cam_entry_format->mac_address, cam_entry_info->mac_address, 6);
+ memcpy(cam_entry_format->key, cam_entry_info->key, 16);
+
+ switch (cam_entry_info->security_type) {
+ case HAL_SECURITY_TYPE_NONE:
+ cam_entry_format->type = 0;
+ break;
+ case HAL_SECURITY_TYPE_WEP40:
+ cam_entry_format->type = 1;
+ break;
+ case HAL_SECURITY_TYPE_WEP104:
+ cam_entry_format->type = 5;
+ break;
+ case HAL_SECURITY_TYPE_TKIP:
+ cam_entry_format->type = 2;
+ break;
+ case HAL_SECURITY_TYPE_AES128:
+ cam_entry_format->type = 4;
+ break;
+ case HAL_SECURITY_TYPE_WAPI:
+ cam_entry_format->type = 6;
+ break;
+ case HAL_SECURITY_TYPE_AES256:
+ cam_entry_format->type = 4;
+ cam_entry_format->ext_sectype = 1;
+ break;
+ case HAL_SECURITY_TYPE_GCMP128:
+ cam_entry_format->type = 7;
+ break;
+ case HAL_SECURITY_TYPE_GCMP256:
+ case HAL_SECURITY_TYPE_GCMSMS4:
+ cam_entry_format->type = 7;
+ cam_entry_format->ext_sectype = 1;
+ break;
+ case HAL_SECURITY_TYPE_BIP:
+ cam_entry_format->type = cam_entry_info->unicast == 1 ? 4 : 0;
+ cam_entry_format->mgnt = 1;
+ cam_entry_format->grp = cam_entry_info->unicast == 1 ? 0 : 1;
+ break;
+ default:
+ kfree(cam_entry_format);
+ return HALMAC_RET_FAIL;
+ }
+
+ for (i = 0; i < 8; i++) {
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_CAMWRITE,
+ *((u32 *)cam_entry_format + i));
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_CAMCMD,
+ command | ((entry_index << 3) + i));
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
+ "[TRACE]1 - CAM entry format : %X\n",
+ *((u32 *)cam_entry_format + i));
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
+ "[TRACE]1 - REG_CAMCMD : %X\n",
+ command | ((entry_index << 3) + i));
+ }
+
+ if (cam_entry_info->security_type == HAL_SECURITY_TYPE_WAPI ||
+ cam_entry_info->security_type == HAL_SECURITY_TYPE_AES256 ||
+ cam_entry_info->security_type == HAL_SECURITY_TYPE_GCMP256 ||
+ cam_entry_info->security_type == HAL_SECURITY_TYPE_GCMSMS4) {
+ cam_entry_format->mic = 1;
+ memcpy(cam_entry_format->key, cam_entry_info->key_ext, 16);
+
+ for (i = 0; i < 8; i++) {
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_CAMWRITE,
+ *((u32 *)cam_entry_format + i));
+ HALMAC_REG_WRITE_32(
+ halmac_adapter, REG_CAMCMD,
+ command | (((entry_index + 1) << 3) + i));
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON,
+ DBG_DMESG,
+ "[TRACE]2 - CAM entry format : %X\n",
+ *((u32 *)cam_entry_format + i));
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
+ "[TRACE]2 - REG_CAMCMD : %X\n",
+ command | (((entry_index + 1) << 3) + i));
+ }
+ }
+
+ kfree(cam_entry_format);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
+ "[TRACE]%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_read_cam_entry_88xx(struct halmac_adapter *halmac_adapter,
+ u32 entry_index,
+ struct halmac_cam_entry_format *content)
+{
+ u32 i;
+ u32 command = 0x80000000;
+ struct halmac_api *halmac_api;
+ void *driver_adapter = NULL;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ if (entry_index >= halmac_adapter->hw_config_info.cam_entry_num)
+ return HALMAC_RET_ENTRY_INDEX_ERROR;
+
+ for (i = 0; i < 8; i++) {
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_CAMCMD,
+ command | ((entry_index << 3) + i));
+ *((u32 *)content + i) =
+ HALMAC_REG_READ_32(halmac_adapter, REG_CAMREAD);
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_clear_cam_entry_88xx(struct halmac_adapter *halmac_adapter,
+ u32 entry_index)
+{
+ u32 i;
+ u32 command = 0x80010000;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ struct halmac_cam_entry_format *cam_entry_format;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "[TRACE]halmac_clear_security_cam_88xx ==========>\n");
+
+ if (entry_index >= halmac_adapter->hw_config_info.cam_entry_num)
+ return HALMAC_RET_ENTRY_INDEX_ERROR;
+
+ cam_entry_format = kzalloc(sizeof(*cam_entry_format), GFP_KERNEL);
+ if (!cam_entry_format)
+ return HALMAC_RET_NULL_POINTER;
+
+ for (i = 0; i < 8; i++) {
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_CAMWRITE,
+ *((u32 *)cam_entry_format + i));
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_CAMCMD,
+ command | ((entry_index << 3) + i));
+ }
+
+ kfree(cam_entry_format);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "[TRACE]halmac_clear_security_cam_88xx <==========\n");
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_get_hw_value_88xx() -get hw config value
+ * @halmac_adapter : the adapter of halmac
+ * @hw_id : hw id for driver to query
+ * @pvalue : hw value, reference table to get data type
+ * Author : KaiYuan Chang / Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_get_hw_value_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_hw_id hw_id, void *pvalue)
+{
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_GET_HW_VALUE);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ if (!pvalue) {
+ pr_err("%s (!pvalue)==========>\n", __func__);
+ return HALMAC_RET_NULL_POINTER;
+ }
+
+ switch (hw_id) {
+ case HALMAC_HW_RQPN_MAPPING:
+ ((struct halmac_rqpn_map *)pvalue)->dma_map_vo =
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VO];
+ ((struct halmac_rqpn_map *)pvalue)->dma_map_vi =
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VI];
+ ((struct halmac_rqpn_map *)pvalue)->dma_map_be =
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BE];
+ ((struct halmac_rqpn_map *)pvalue)->dma_map_bk =
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BK];
+ ((struct halmac_rqpn_map *)pvalue)->dma_map_mg =
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_MG];
+ ((struct halmac_rqpn_map *)pvalue)->dma_map_hi =
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_HI];
+ break;
+ case HALMAC_HW_EFUSE_SIZE:
+ *(u32 *)pvalue = halmac_adapter->hw_config_info.efuse_size;
+ break;
+ case HALMAC_HW_EEPROM_SIZE:
+ *(u32 *)pvalue = halmac_adapter->hw_config_info.eeprom_size;
+ break;
+ case HALMAC_HW_BT_BANK_EFUSE_SIZE:
+ *(u32 *)pvalue = halmac_adapter->hw_config_info.bt_efuse_size;
+ break;
+ case HALMAC_HW_BT_BANK1_EFUSE_SIZE:
+ case HALMAC_HW_BT_BANK2_EFUSE_SIZE:
+ *(u32 *)pvalue = 0;
+ break;
+ case HALMAC_HW_TXFIFO_SIZE:
+ *(u32 *)pvalue = halmac_adapter->hw_config_info.tx_fifo_size;
+ break;
+ case HALMAC_HW_RSVD_PG_BNDY:
+ *(u16 *)pvalue =
+ halmac_adapter->txff_allocation.rsvd_drv_pg_bndy;
+ break;
+ case HALMAC_HW_CAM_ENTRY_NUM:
+ *(u8 *)pvalue = halmac_adapter->hw_config_info.cam_entry_num;
+ break;
+ case HALMAC_HW_WLAN_EFUSE_AVAILABLE_SIZE: /*Remove later*/
+ status = halmac_dump_logical_efuse_map_88xx(halmac_adapter,
+ HALMAC_EFUSE_R_DRV);
+ if (status != HALMAC_RET_SUCCESS)
+ return status;
+ *(u32 *)pvalue = halmac_adapter->hw_config_info.efuse_size -
+ HALMAC_PROTECTED_EFUSE_SIZE_88XX -
+ halmac_adapter->efuse_end;
+ break;
+ case HALMAC_HW_IC_VERSION:
+ *(u8 *)pvalue = halmac_adapter->chip_version;
+ break;
+ case HALMAC_HW_PAGE_SIZE:
+ *(u32 *)pvalue = halmac_adapter->hw_config_info.page_size;
+ break;
+ case HALMAC_HW_TX_AGG_ALIGN_SIZE:
+ *(u16 *)pvalue = halmac_adapter->hw_config_info.tx_align_size;
+ break;
+ case HALMAC_HW_RX_AGG_ALIGN_SIZE:
+ *(u8 *)pvalue = 8;
+ break;
+ case HALMAC_HW_DRV_INFO_SIZE:
+ *(u8 *)pvalue = halmac_adapter->drv_info_size;
+ break;
+ case HALMAC_HW_TXFF_ALLOCATION:
+ memcpy(pvalue, &halmac_adapter->txff_allocation,
+ sizeof(struct halmac_txff_allocation));
+ break;
+ case HALMAC_HW_TX_DESC_SIZE:
+ *(u32 *)pvalue = halmac_adapter->hw_config_info.txdesc_size;
+ break;
+ case HALMAC_HW_RX_DESC_SIZE:
+ *(u32 *)pvalue = halmac_adapter->hw_config_info.rxdesc_size;
+ break;
+ default:
+ return HALMAC_RET_PARA_NOT_SUPPORT;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_set_hw_value_88xx() -set hw config value
+ * @halmac_adapter : the adapter of halmac
+ * @hw_id : hw id for driver to config
+ * @pvalue : hw value, reference table to get data type
+ * Author : KaiYuan Chang / Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_set_hw_value_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_hw_id hw_id, void *pvalue)
+{
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_GET_HW_VALUE);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ if (!pvalue) {
+ pr_err("%s (!pvalue)==========>\n", __func__);
+ return HALMAC_RET_NULL_POINTER;
+ }
+
+ switch (hw_id) {
+ case HALMAC_HW_USB_MODE:
+ status = halmac_set_usb_mode_88xx(
+ halmac_adapter, *(enum halmac_usb_mode *)pvalue);
+ if (status != HALMAC_RET_SUCCESS)
+ return status;
+ break;
+ case HALMAC_HW_SEQ_EN:
+ break;
+ case HALMAC_HW_BANDWIDTH:
+ halmac_cfg_bw_88xx(halmac_adapter, *(enum halmac_bw *)pvalue);
+ break;
+ case HALMAC_HW_CHANNEL:
+ halmac_cfg_ch_88xx(halmac_adapter, *(u8 *)pvalue);
+ break;
+ case HALMAC_HW_PRI_CHANNEL_IDX:
+ halmac_cfg_pri_ch_idx_88xx(halmac_adapter,
+ *(enum halmac_pri_ch_idx *)pvalue);
+ break;
+ case HALMAC_HW_EN_BB_RF:
+ halmac_enable_bb_rf_88xx(halmac_adapter, *(u8 *)pvalue);
+ break;
+ case HALMAC_HW_SDIO_TX_PAGE_THRESHOLD:
+ halmac_config_sdio_tx_page_threshold_88xx(
+ halmac_adapter,
+ (struct halmac_tx_page_threshold_info *)pvalue);
+ break;
+ case HALMAC_HW_AMPDU_CONFIG:
+ halmac_config_ampdu_88xx(halmac_adapter,
+ (struct halmac_ampdu_config *)pvalue);
+ break;
+ default:
+ return HALMAC_RET_PARA_NOT_SUPPORT;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_cfg_drv_rsvd_pg_num_88xx() -config reserved page number for driver
+ * @halmac_adapter : the adapter of halmac
+ * @pg_num : page number
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_cfg_drv_rsvd_pg_num_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_drv_rsvd_pg_num pg_num)
+{
+ void *driver_adapter = NULL;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter,
+ HALMAC_API_CFG_DRV_RSVD_PG_NUM);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s ==========>pg_num = %d\n", __func__,
+ pg_num);
+
+ switch (pg_num) {
+ case HALMAC_RSVD_PG_NUM16:
+ halmac_adapter->txff_allocation.rsvd_drv_pg_num = 16;
+ break;
+ case HALMAC_RSVD_PG_NUM24:
+ halmac_adapter->txff_allocation.rsvd_drv_pg_num = 24;
+ break;
+ case HALMAC_RSVD_PG_NUM32:
+ halmac_adapter->txff_allocation.rsvd_drv_pg_num = 32;
+ break;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_get_chip_version_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_ver *version)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s ==========>\n", __func__);
+ version->major_ver = (u8)HALMAC_MAJOR_VER_88XX;
+ version->prototype_ver = (u8)HALMAC_PROTOTYPE_VER_88XX;
+ version->minor_ver = (u8)HALMAC_MINOR_VER_88XX;
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_chk_txdesc_88xx() -check if the tx packet format is incorrect
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_buf : tx Packet buffer, tx desc is included
+ * @halmac_size : tx packet size
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_chk_txdesc_88xx(struct halmac_adapter *halmac_adapter, u8 *halmac_buf,
+ u32 halmac_size)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ if (GET_TX_DESC_BMC(halmac_buf))
+ if (GET_TX_DESC_AGG_EN(halmac_buf))
+ pr_err("TxDesc: Agg should not be set when BMC\n");
+
+ if (halmac_size < (GET_TX_DESC_TXPKTSIZE(halmac_buf) +
+ GET_TX_DESC_OFFSET(halmac_buf)))
+ pr_err("TxDesc: PktSize too small\n");
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_dl_drv_rsvd_page_88xx() - download packet to rsvd page
+ * @halmac_adapter : the adapter of halmac
+ * @pg_offset : page offset of driver's rsvd page
+ * @halmac_buf : data to be downloaded, tx_desc is not included
+ * @halmac_size : data size to be downloaded
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_dl_drv_rsvd_page_88xx(struct halmac_adapter *halmac_adapter,
+ u8 pg_offset, u8 *halmac_buf, u32 halmac_size)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ enum halmac_ret_status ret_status;
+ u16 drv_pg_bndy = 0;
+ u32 dl_pg_num = 0;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DL_DRV_RSVD_PG);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ /*check boundary and size valid*/
+ dl_pg_num = halmac_size / halmac_adapter->hw_config_info.page_size +
+ ((halmac_size &
+ (halmac_adapter->hw_config_info.page_size - 1)) ?
+ 1 :
+ 0);
+ if (pg_offset + dl_pg_num >
+ halmac_adapter->txff_allocation.rsvd_drv_pg_num) {
+ pr_err("[ERROR] driver download offset or size error ==========>\n");
+ return HALMAC_RET_DRV_DL_ERR;
+ }
+
+ /*update to target download boundary*/
+ drv_pg_bndy =
+ halmac_adapter->txff_allocation.rsvd_drv_pg_bndy + pg_offset;
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
+ (u16)(drv_pg_bndy & BIT_MASK_BCN_HEAD_1_V1));
+
+ ret_status = halmac_download_rsvd_page_88xx(halmac_adapter, halmac_buf,
+ halmac_size);
+
+ /*restore to original bundary*/
+ if (ret_status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_download_rsvd_page_88xx Fail = %x!!\n",
+ ret_status);
+ HALMAC_REG_WRITE_16(
+ halmac_adapter, REG_FIFOPAGE_CTRL_2,
+ (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
+ BIT_MASK_BCN_HEAD_1_V1));
+ return ret_status;
+ }
+
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
+ (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
+ BIT_MASK_BCN_HEAD_1_V1));
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s < ==========\n", __func__);
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_cfg_csi_rate_88xx() - config CSI frame Tx rate
+ * @halmac_adapter : the adapter of halmac
+ * @rssi : rssi in decimal value
+ * @current_rate : current CSI frame rate
+ * @fixrate_en : enable to fix CSI frame in VHT rate, otherwise legacy OFDM rate
+ * @new_rate : API returns the final CSI frame rate
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_cfg_csi_rate_88xx(struct halmac_adapter *halmac_adapter, u8 rssi,
+ u8 current_rate, u8 fixrate_en, u8 *new_rate)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ u32 temp_csi_setting;
+ u16 current_rrsr;
+ enum halmac_ret_status ret_status;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_CSI_RATE);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
+ "<%s ==========>\n", __func__);
+
+ temp_csi_setting = HALMAC_REG_READ_32(halmac_adapter, REG_BBPSF_CTRL) &
+ ~(BIT_MASK_WMAC_CSI_RATE << BIT_SHIFT_WMAC_CSI_RATE);
+
+ current_rrsr = HALMAC_REG_READ_16(halmac_adapter, REG_RRSR);
+
+ if (rssi >= 40) {
+ if (current_rate != HALMAC_OFDM54) {
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_RRSR,
+ current_rrsr | BIT(HALMAC_OFDM54));
+ HALMAC_REG_WRITE_32(
+ halmac_adapter, REG_BBPSF_CTRL,
+ temp_csi_setting |
+ BIT_WMAC_CSI_RATE(HALMAC_OFDM54));
+ }
+ *new_rate = HALMAC_OFDM54;
+ ret_status = HALMAC_RET_SUCCESS;
+ } else {
+ if (current_rate != HALMAC_OFDM24) {
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_RRSR,
+ current_rrsr &
+ ~(BIT(HALMAC_OFDM54)));
+ HALMAC_REG_WRITE_32(
+ halmac_adapter, REG_BBPSF_CTRL,
+ temp_csi_setting |
+ BIT_WMAC_CSI_RATE(HALMAC_OFDM24));
+ }
+ *new_rate = HALMAC_OFDM24;
+ ret_status = HALMAC_RET_SUCCESS;
+ }
+
+ return ret_status;
+}
+
+/**
+ * halmac_sdio_cmd53_4byte_88xx() - cmd53 only for 4byte len register IO
+ * @halmac_adapter : the adapter of halmac
+ * @enable : 1->CMD53 only use in 4byte reg, 0 : No limitation
+ * Author : Ivan Lin/KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_sdio_cmd53_4byte_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_sdio_cmd53_4byte_mode cmd53_4byte_mode)
+{
+ halmac_adapter->sdio_cmd53_4byte = cmd53_4byte_mode;
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_txfifo_is_empty_88xx() -check if txfifo is empty
+ * @halmac_adapter : the adapter of halmac
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_txfifo_is_empty_88xx(struct halmac_adapter *halmac_adapter, u32 chk_num)
+{
+ u32 counter;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ counter = (chk_num <= 10) ? 10 : chk_num;
+ do {
+ if (HALMAC_REG_READ_8(halmac_adapter, REG_TXPKT_EMPTY) != 0xFF)
+ return HALMAC_RET_TXFIFO_NO_EMPTY;
+
+ if ((HALMAC_REG_READ_8(halmac_adapter, REG_TXPKT_EMPTY + 1) &
+ 0x07) != 0x07)
+ return HALMAC_RET_TXFIFO_NO_EMPTY;
+ counter--;
+
+ } while (counter != 0);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx.h b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx.h
new file mode 100644
index 0000000..5debd1f
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx.h
@@ -0,0 +1,396 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HALMAC_API_88XX_H_
+#define _HALMAC_API_88XX_H_
+
+#include "../halmac_2_platform.h"
+#include "../halmac_type.h"
+
+void halmac_init_state_machine_88xx(struct halmac_adapter *halmac_adapter);
+
+void halmac_init_adapter_para_88xx(struct halmac_adapter *halmac_adapter);
+
+void halmac_init_adapter_dynamic_para_88xx(
+ struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_mount_api_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_download_firmware_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *hamacl_fw, u32 halmac_fw_size);
+
+enum halmac_ret_status
+halmac_free_download_firmware_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_dlfw_mem dlfw_mem, u8 *hamacl_fw,
+ u32 halmac_fw_size);
+
+enum halmac_ret_status
+halmac_get_fw_version_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_fw_version *fw_version);
+
+enum halmac_ret_status
+halmac_cfg_mac_addr_88xx(struct halmac_adapter *halmac_adapter, u8 halmac_port,
+ union halmac_wlan_addr *hal_address);
+
+enum halmac_ret_status
+halmac_cfg_bssid_88xx(struct halmac_adapter *halmac_adapter, u8 halmac_port,
+ union halmac_wlan_addr *hal_address);
+
+enum halmac_ret_status
+halmac_cfg_multicast_addr_88xx(struct halmac_adapter *halmac_adapter,
+ union halmac_wlan_addr *hal_address);
+
+enum halmac_ret_status
+halmac_pre_init_system_cfg_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_init_system_cfg_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_cfg_rx_aggregation_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_rxagg_cfg halmac_rxagg_cfg);
+
+enum halmac_ret_status
+halmac_init_edca_cfg_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_cfg_operation_mode_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_wireless_mode wireless_mode);
+
+enum halmac_ret_status
+halmac_cfg_ch_bw_88xx(struct halmac_adapter *halmac_adapter, u8 channel,
+ enum halmac_pri_ch_idx pri_ch_idx, enum halmac_bw bw);
+
+enum halmac_ret_status halmac_cfg_ch_88xx(struct halmac_adapter *halmac_adapter,
+ u8 channel);
+
+enum halmac_ret_status
+halmac_cfg_pri_ch_idx_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_pri_ch_idx pri_ch_idx);
+
+enum halmac_ret_status halmac_cfg_bw_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_bw bw);
+
+enum halmac_ret_status
+halmac_init_wmac_cfg_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_init_mac_cfg_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_trx_mode mode);
+
+enum halmac_ret_status
+halmac_dump_efuse_map_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_efuse_read_cfg cfg);
+
+enum halmac_ret_status
+halmac_dump_efuse_map_bt_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_efuse_bank halmac_efuse_bank,
+ u32 bt_efuse_map_size, u8 *bt_efuse_map);
+
+enum halmac_ret_status
+halmac_write_efuse_bt_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u8 halmac_value,
+ enum halmac_efuse_bank halmac_efuse_bank);
+
+enum halmac_ret_status
+halmac_pg_efuse_by_map_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_pg_efuse_info *pg_efuse_info,
+ enum halmac_efuse_read_cfg cfg);
+
+enum halmac_ret_status
+halmac_get_efuse_size_88xx(struct halmac_adapter *halmac_adapter,
+ u32 *halmac_size);
+
+enum halmac_ret_status
+halmac_get_efuse_available_size_88xx(struct halmac_adapter *halmac_adapter,
+ u32 *halmac_size);
+
+enum halmac_ret_status
+halmac_get_c2h_info_88xx(struct halmac_adapter *halmac_adapter, u8 *halmac_buf,
+ u32 halmac_size);
+
+enum halmac_ret_status
+halmac_get_logical_efuse_size_88xx(struct halmac_adapter *halmac_adapter,
+ u32 *halmac_size);
+
+enum halmac_ret_status
+halmac_dump_logical_efuse_map_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_efuse_read_cfg cfg);
+
+enum halmac_ret_status
+halmac_write_logical_efuse_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u8 halmac_value);
+
+enum halmac_ret_status
+halmac_read_logical_efuse_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u8 *value);
+
+enum halmac_ret_status
+halmac_cfg_fwlps_option_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_fwlps_option *lps_option);
+
+enum halmac_ret_status
+halmac_cfg_fwips_option_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_fwips_option *ips_option);
+
+enum halmac_ret_status
+halmac_enter_wowlan_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_wowlan_option *wowlan_option);
+
+enum halmac_ret_status
+halmac_leave_wowlan_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_enter_ps_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_ps_state ps_state);
+
+enum halmac_ret_status
+halmac_leave_ps_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_h2c_lb_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status halmac_debug_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_cfg_parameter_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_phy_parameter_info *para_info,
+ u8 full_fifo);
+
+enum halmac_ret_status
+halmac_update_packet_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_packet_id pkt_id, u8 *pkt, u32 pkt_size);
+
+enum halmac_ret_status
+halmac_bcn_ie_filter_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_bcn_ie_info *bcn_ie_info);
+
+enum halmac_ret_status
+halmac_send_original_h2c_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *original_h2c, u16 *seq, u8 ack);
+
+enum halmac_ret_status
+halmac_update_datapack_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_data_type halmac_data_type,
+ struct halmac_phy_parameter_info *para_info);
+
+enum halmac_ret_status
+halmac_run_datapack_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_data_type halmac_data_type);
+
+enum halmac_ret_status
+halmac_cfg_drv_info_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_drv_info halmac_drv_info);
+
+enum halmac_ret_status
+halmac_send_bt_coex_88xx(struct halmac_adapter *halmac_adapter, u8 *bt_buf,
+ u32 bt_size, u8 ack);
+
+enum halmac_ret_status
+halmac_verify_platform_api_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_timer_2s_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_fill_txdesc_check_sum_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *cur_desc);
+
+enum halmac_ret_status
+halmac_dump_fifo_88xx(struct halmac_adapter *halmac_adapter,
+ enum hal_fifo_sel halmac_fifo_sel, u32 halmac_start_addr,
+ u32 halmac_fifo_dump_size, u8 *fifo_map);
+
+u32 halmac_get_fifo_size_88xx(struct halmac_adapter *halmac_adapter,
+ enum hal_fifo_sel halmac_fifo_sel);
+
+enum halmac_ret_status
+halmac_cfg_txbf_88xx(struct halmac_adapter *halmac_adapter, u8 userid,
+ enum halmac_bw bw, u8 txbf_en);
+
+enum halmac_ret_status
+halmac_cfg_mumimo_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_cfg_mumimo_para *cfgmu);
+
+enum halmac_ret_status
+halmac_cfg_sounding_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_snd_role role,
+ enum halmac_data_rate datarate);
+
+enum halmac_ret_status
+halmac_del_sounding_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_snd_role role);
+
+enum halmac_ret_status
+halmac_su_bfee_entry_init_88xx(struct halmac_adapter *halmac_adapter, u8 userid,
+ u16 paid);
+
+enum halmac_ret_status
+halmac_su_bfer_entry_init_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_su_bfer_init_para *su_bfer_init);
+
+enum halmac_ret_status
+halmac_mu_bfee_entry_init_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_mu_bfee_init_para *mu_bfee_init);
+
+enum halmac_ret_status
+halmac_mu_bfer_entry_init_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_mu_bfer_init_para *mu_bfer_init);
+
+enum halmac_ret_status
+halmac_su_bfee_entry_del_88xx(struct halmac_adapter *halmac_adapter, u8 userid);
+
+enum halmac_ret_status
+halmac_su_bfer_entry_del_88xx(struct halmac_adapter *halmac_adapter, u8 userid);
+
+enum halmac_ret_status
+halmac_mu_bfee_entry_del_88xx(struct halmac_adapter *halmac_adapter, u8 userid);
+
+enum halmac_ret_status
+halmac_mu_bfer_entry_del_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_add_ch_info_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_ch_info *ch_info);
+
+enum halmac_ret_status
+halmac_add_extra_ch_info_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_ch_extra_info *ch_extra_info);
+
+enum halmac_ret_status
+halmac_ctrl_ch_switch_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_ch_switch_option *cs_option);
+
+enum halmac_ret_status halmac_p2pps_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_p2pps *p2p_ps);
+
+enum halmac_ret_status
+halmac_func_p2pps_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_p2pps *p2p_ps);
+
+enum halmac_ret_status
+halmac_clear_ch_info_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_send_general_info_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_general_info *general_info);
+
+enum halmac_ret_status
+halmac_start_iqk_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_iqk_para_ *iqk_para);
+
+enum halmac_ret_status halmac_ctrl_pwr_tracking_88xx(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_pwr_tracking_option *pwr_tracking_opt);
+
+enum halmac_ret_status
+halmac_query_status_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_feature_id feature_id,
+ enum halmac_cmd_process_status *process_status,
+ u8 *data, u32 *size);
+
+enum halmac_ret_status
+halmac_reset_feature_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_feature_id feature_id);
+
+enum halmac_ret_status
+halmac_check_fw_status_88xx(struct halmac_adapter *halmac_adapter,
+ bool *fw_status);
+
+enum halmac_ret_status
+halmac_dump_fw_dmem_88xx(struct halmac_adapter *halmac_adapter, u8 *dmem,
+ u32 *size);
+
+enum halmac_ret_status
+halmac_cfg_max_dl_size_88xx(struct halmac_adapter *halmac_adapter, u32 size);
+
+enum halmac_ret_status halmac_psd_88xx(struct halmac_adapter *halmac_adapter,
+ u16 start_psd, u16 end_psd);
+
+enum halmac_ret_status
+halmac_cfg_la_mode_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_la_mode la_mode);
+
+enum halmac_ret_status halmac_cfg_rx_fifo_expanding_mode_88xx(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_rx_fifo_expanding_mode rx_fifo_expanding_mode);
+
+enum halmac_ret_status
+halmac_config_security_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_security_setting *sec_setting);
+
+u8 halmac_get_used_cam_entry_num_88xx(struct halmac_adapter *halmac_adapter,
+ enum hal_security_type sec_type);
+
+enum halmac_ret_status
+halmac_write_cam_88xx(struct halmac_adapter *halmac_adapter, u32 entry_index,
+ struct halmac_cam_entry_info *cam_entry_info);
+
+enum halmac_ret_status
+halmac_read_cam_entry_88xx(struct halmac_adapter *halmac_adapter,
+ u32 entry_index,
+ struct halmac_cam_entry_format *content);
+
+enum halmac_ret_status
+halmac_clear_cam_entry_88xx(struct halmac_adapter *halmac_adapter,
+ u32 entry_index);
+
+enum halmac_ret_status
+halmac_get_hw_value_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_hw_id hw_id, void *pvalue);
+
+enum halmac_ret_status
+halmac_set_hw_value_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_hw_id hw_id, void *pvalue);
+
+enum halmac_ret_status
+halmac_cfg_drv_rsvd_pg_num_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_drv_rsvd_pg_num pg_num);
+
+enum halmac_ret_status
+halmac_get_chip_version_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_ver *version);
+
+enum halmac_ret_status
+halmac_chk_txdesc_88xx(struct halmac_adapter *halmac_adapter, u8 *halmac_buf,
+ u32 halmac_size);
+
+enum halmac_ret_status
+halmac_dl_drv_rsvd_page_88xx(struct halmac_adapter *halmac_adapter,
+ u8 pg_offset, u8 *halmac_buf, u32 halmac_size);
+
+enum halmac_ret_status
+halmac_cfg_csi_rate_88xx(struct halmac_adapter *halmac_adapter, u8 rssi,
+ u8 current_rate, u8 fixrate_en, u8 *new_rate);
+
+enum halmac_ret_status halmac_sdio_cmd53_4byte_88xx(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_sdio_cmd53_4byte_mode cmd53_4byte_mode);
+
+enum halmac_ret_status
+halmac_txfifo_is_empty_88xx(struct halmac_adapter *halmac_adapter, u32 chk_num);
+
+#endif /* _HALMAC_API_H_ */
diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx_pcie.c b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx_pcie.c
new file mode 100644
index 0000000..fa97cac
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx_pcie.c
@@ -0,0 +1,329 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#include "halmac_88xx_cfg.h"
+
+/**
+ * halmac_init_pcie_cfg_88xx() - init PCIe
+ * @halmac_adapter : the adapter of halmac
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_init_pcie_cfg_88xx(struct halmac_adapter *halmac_adapter)
+{
+ void *driver_adapter = NULL;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_PCIE_CFG);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_deinit_pcie_cfg_88xx() - deinit PCIE
+ * @halmac_adapter : the adapter of halmac
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_deinit_pcie_cfg_88xx(struct halmac_adapter *halmac_adapter)
+{
+ void *driver_adapter = NULL;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DEINIT_PCIE_CFG);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_cfg_rx_aggregation_88xx_pcie() - config rx aggregation
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_rx_agg_mode
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_cfg_rx_aggregation_88xx_pcie(struct halmac_adapter *halmac_adapter,
+ struct halmac_rxagg_cfg *phalmac_rxagg_cfg)
+{
+ void *driver_adapter = NULL;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter,
+ HALMAC_API_CFG_RX_AGGREGATION);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_reg_read_8_pcie_88xx() - read 1byte register
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_offset : register offset
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+u8 halmac_reg_read_8_pcie_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ return PLATFORM_REG_READ_8(driver_adapter, halmac_offset);
+}
+
+/**
+ * halmac_reg_write_8_pcie_88xx() - write 1byte register
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_offset : register offset
+ * @halmac_data : register value
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_reg_write_8_pcie_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u8 halmac_data)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ PLATFORM_REG_WRITE_8(driver_adapter, halmac_offset, halmac_data);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_reg_read_16_pcie_88xx() - read 2byte register
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_offset : register offset
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+u16 halmac_reg_read_16_pcie_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ return PLATFORM_REG_READ_16(driver_adapter, halmac_offset);
+}
+
+/**
+ * halmac_reg_write_16_pcie_88xx() - write 2byte register
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_offset : register offset
+ * @halmac_data : register value
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_reg_write_16_pcie_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u16 halmac_data)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ PLATFORM_REG_WRITE_16(driver_adapter, halmac_offset, halmac_data);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_reg_read_32_pcie_88xx() - read 4byte register
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_offset : register offset
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+u32 halmac_reg_read_32_pcie_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ return PLATFORM_REG_READ_32(driver_adapter, halmac_offset);
+}
+
+/**
+ * halmac_reg_write_32_pcie_88xx() - write 4byte register
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_offset : register offset
+ * @halmac_data : register value
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_reg_write_32_pcie_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u32 halmac_data)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ PLATFORM_REG_WRITE_32(driver_adapter, halmac_offset, halmac_data);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_cfg_tx_agg_align_pcie_88xx() -config sdio bus tx agg alignment
+ * @halmac_adapter : the adapter of halmac
+ * @enable : function enable(1)/disable(0)
+ * @align_size : sdio bus tx agg alignment size (2^n, n = 3~11)
+ * Author : Soar Tu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status halmac_cfg_tx_agg_align_pcie_not_support_88xx(
+ struct halmac_adapter *halmac_adapter, u8 enable, u16 align_size)
+{
+ struct halmac_api *halmac_api;
+ void *driver_adapter = NULL;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_TX_AGG_ALIGN);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s not support\n", __func__);
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx_pcie.h b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx_pcie.h
new file mode 100644
index 0000000..34969fc
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx_pcie.h
@@ -0,0 +1,71 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HALMAC_API_88XX_PCIE_H_
+#define _HALMAC_API_88XX_PCIE_H_
+
+#include "../halmac_2_platform.h"
+#include "../halmac_type.h"
+
+#define LINK_CTRL2_REG_OFFSET 0xA0
+#define GEN2_CTRL_OFFSET 0x80C
+#define LINK_STATUS_REG_OFFSET 0x82
+#define GEN1_SPEED 0x01
+#define GEN2_SPEED 0x02
+
+enum halmac_ret_status
+halmac_init_pcie_cfg_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_deinit_pcie_cfg_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_cfg_rx_aggregation_88xx_pcie(struct halmac_adapter *halmac_adapter,
+ struct halmac_rxagg_cfg *phalmac_rxagg_cfg);
+
+u8 halmac_reg_read_8_pcie_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset);
+
+enum halmac_ret_status
+halmac_reg_write_8_pcie_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u8 halmac_data);
+
+u16 halmac_reg_read_16_pcie_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset);
+
+enum halmac_ret_status
+halmac_reg_write_16_pcie_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u16 halmac_data);
+
+u32 halmac_reg_read_32_pcie_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset);
+
+enum halmac_ret_status
+halmac_reg_write_32_pcie_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u32 halmac_data);
+
+enum halmac_ret_status halmac_cfg_tx_agg_align_pcie_not_support_88xx(
+ struct halmac_adapter *halmac_adapter, u8 enable, u16 align_size);
+
+#endif /* _HALMAC_API_88XX_PCIE_H_ */
diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx_sdio.c b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx_sdio.c
new file mode 100644
index 0000000..69b26a5a
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx_sdio.c
@@ -0,0 +1,974 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#include "halmac_88xx_cfg.h"
+
+/**
+ * halmac_init_sdio_cfg_88xx() - init SDIO
+ * @halmac_adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_init_sdio_cfg_88xx(struct halmac_adapter *halmac_adapter)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_SDIO_CFG);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ HALMAC_REG_READ_32(halmac_adapter, REG_SDIO_FREE_TXPG);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_SDIO_TX_CTRL, 0x00000000);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_deinit_sdio_cfg_88xx() - deinit SDIO
+ * @halmac_adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_deinit_sdio_cfg_88xx(struct halmac_adapter *halmac_adapter)
+{
+ void *driver_adapter = NULL;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DEINIT_SDIO_CFG);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_cfg_rx_aggregation_88xx_sdio() - config rx aggregation
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_rx_agg_mode
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_cfg_rx_aggregation_88xx_sdio(struct halmac_adapter *halmac_adapter,
+ struct halmac_rxagg_cfg *phalmac_rxagg_cfg)
+{
+ u8 value8;
+ u8 size = 0, timeout = 0, agg_enable = 0;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter,
+ HALMAC_API_CFG_RX_AGGREGATION);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ agg_enable = HALMAC_REG_READ_8(halmac_adapter, REG_TXDMA_PQ_MAP);
+
+ switch (phalmac_rxagg_cfg->mode) {
+ case HALMAC_RX_AGG_MODE_NONE:
+ agg_enable &= ~(BIT_RXDMA_AGG_EN);
+ break;
+ case HALMAC_RX_AGG_MODE_DMA:
+ case HALMAC_RX_AGG_MODE_USB:
+ agg_enable |= BIT_RXDMA_AGG_EN;
+ break;
+ default:
+ pr_err("halmac_cfg_rx_aggregation_88xx_usb switch case not support\n");
+ agg_enable &= ~BIT_RXDMA_AGG_EN;
+ break;
+ }
+
+ if (!phalmac_rxagg_cfg->threshold.drv_define) {
+ size = 0xFF;
+ timeout = 0x01;
+ } else {
+ size = phalmac_rxagg_cfg->threshold.size;
+ timeout = phalmac_rxagg_cfg->threshold.timeout;
+ }
+
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_TXDMA_PQ_MAP, agg_enable);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_RXDMA_AGG_PG_TH,
+ (u16)(size | (timeout << BIT_SHIFT_DMA_AGG_TO)));
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RXDMA_MODE);
+ if ((agg_enable & BIT_RXDMA_AGG_EN) != 0)
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_RXDMA_MODE,
+ value8 | BIT_DMA_MODE);
+ else
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_RXDMA_MODE,
+ value8 & ~(BIT_DMA_MODE));
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_reg_read_8_sdio_88xx() - read 1byte register
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_offset : register offset
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+u8 halmac_reg_read_8_sdio_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset)
+{
+ u8 value8;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ if ((halmac_offset & 0xFFFF0000) == 0)
+ halmac_offset |= WLAN_IOREG_OFFSET;
+
+ status = halmac_convert_to_sdio_bus_offset_88xx(halmac_adapter,
+ &halmac_offset);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("%s error = %x\n", __func__, status);
+ return status;
+ }
+
+ value8 = PLATFORM_SDIO_CMD52_READ(driver_adapter, halmac_offset);
+
+ return value8;
+}
+
+/**
+ * halmac_reg_write_8_sdio_88xx() - write 1byte register
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_offset : register offset
+ * @halmac_data : register value
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_reg_write_8_sdio_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u8 halmac_data)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ if ((halmac_offset & 0xFFFF0000) == 0)
+ halmac_offset |= WLAN_IOREG_OFFSET;
+
+ status = halmac_convert_to_sdio_bus_offset_88xx(halmac_adapter,
+ &halmac_offset);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("%s error = %x\n", __func__, status);
+ return status;
+ }
+
+ PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset, halmac_data);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_reg_read_16_sdio_88xx() - read 2byte register
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_offset : register offset
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+u16 halmac_reg_read_16_sdio_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ union {
+ u16 word;
+ u8 byte[2];
+ __le16 le_word;
+ } value16 = {0x0000};
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ if ((halmac_offset & 0xFFFF0000) == 0)
+ halmac_offset |= WLAN_IOREG_OFFSET;
+
+ status = halmac_convert_to_sdio_bus_offset_88xx(halmac_adapter,
+ &halmac_offset);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("%s error = %x\n", __func__, status);
+ return status;
+ }
+
+ if (halmac_adapter->halmac_state.mac_power == HALMAC_MAC_POWER_OFF ||
+ (halmac_offset & (2 - 1)) != 0 ||
+ halmac_adapter->sdio_cmd53_4byte ==
+ HALMAC_SDIO_CMD53_4BYTE_MODE_RW ||
+ halmac_adapter->sdio_cmd53_4byte ==
+ HALMAC_SDIO_CMD53_4BYTE_MODE_R) {
+ value16.byte[0] =
+ PLATFORM_SDIO_CMD52_READ(driver_adapter, halmac_offset);
+ value16.byte[1] = PLATFORM_SDIO_CMD52_READ(driver_adapter,
+ halmac_offset + 1);
+ value16.word = le16_to_cpu(value16.le_word);
+ } else {
+#if (PLATFORM_SD_CLK > HALMAC_SD_CLK_THRESHOLD_88XX)
+ if ((halmac_offset & 0xffffef00) == 0x00000000) {
+ value16.byte[0] = PLATFORM_SDIO_CMD52_READ(
+ driver_adapter, halmac_offset);
+ value16.byte[1] = PLATFORM_SDIO_CMD52_READ(
+ driver_adapter, halmac_offset + 1);
+ value16.word = le16_to_cpu(value16.word);
+ } else {
+ value16.word = PLATFORM_SDIO_CMD53_READ_16(
+ driver_adapter, halmac_offset);
+ }
+#else
+ value16.word = PLATFORM_SDIO_CMD53_READ_16(driver_adapter,
+ halmac_offset);
+#endif
+ }
+
+ return value16.word;
+}
+
+/**
+ * halmac_reg_write_16_sdio_88xx() - write 2byte register
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_offset : register offset
+ * @halmac_data : register value
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_reg_write_16_sdio_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u16 halmac_data)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ if ((halmac_offset & 0xFFFF0000) == 0)
+ halmac_offset |= WLAN_IOREG_OFFSET;
+
+ status = halmac_convert_to_sdio_bus_offset_88xx(halmac_adapter,
+ &halmac_offset);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("%s error = %x\n", __func__, status);
+ return status;
+ }
+
+ if (halmac_adapter->halmac_state.mac_power == HALMAC_MAC_POWER_OFF ||
+ (halmac_offset & (2 - 1)) != 0 ||
+ halmac_adapter->sdio_cmd53_4byte ==
+ HALMAC_SDIO_CMD53_4BYTE_MODE_RW ||
+ halmac_adapter->sdio_cmd53_4byte ==
+ HALMAC_SDIO_CMD53_4BYTE_MODE_W) {
+ PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset,
+ (u8)(halmac_data & 0xFF));
+ PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset + 1,
+ (u8)((halmac_data & 0xFF00) >> 8));
+ } else {
+ PLATFORM_SDIO_CMD53_WRITE_16(driver_adapter, halmac_offset,
+ halmac_data);
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_reg_read_32_sdio_88xx() - read 4byte register
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_offset : register offset
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+u32 halmac_reg_read_32_sdio_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+ u32 halmac_offset_old = 0;
+
+ union {
+ u32 dword;
+ u8 byte[4];
+ __le32 le_dword;
+ } value32 = {0x00000000};
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ halmac_offset_old = halmac_offset;
+
+ if ((halmac_offset & 0xFFFF0000) == 0)
+ halmac_offset |= WLAN_IOREG_OFFSET;
+
+ status = halmac_convert_to_sdio_bus_offset_88xx(halmac_adapter,
+ &halmac_offset);
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("%s error = %x\n", __func__, status);
+ return status;
+ }
+
+ if (halmac_adapter->halmac_state.mac_power == HALMAC_MAC_POWER_OFF ||
+ (halmac_offset & (4 - 1)) != 0) {
+ value32.byte[0] =
+ PLATFORM_SDIO_CMD52_READ(driver_adapter, halmac_offset);
+ value32.byte[1] = PLATFORM_SDIO_CMD52_READ(driver_adapter,
+ halmac_offset + 1);
+ value32.byte[2] = PLATFORM_SDIO_CMD52_READ(driver_adapter,
+ halmac_offset + 2);
+ value32.byte[3] = PLATFORM_SDIO_CMD52_READ(driver_adapter,
+ halmac_offset + 3);
+ value32.dword = le32_to_cpu(value32.le_dword);
+ } else {
+#if (PLATFORM_SD_CLK > HALMAC_SD_CLK_THRESHOLD_88XX)
+ if ((halmac_offset_old & 0xffffef00) == 0x00000000) {
+ value32.byte[0] = PLATFORM_SDIO_CMD52_READ(
+ driver_adapter, halmac_offset);
+ value32.byte[1] = PLATFORM_SDIO_CMD52_READ(
+ driver_adapter, halmac_offset + 1);
+ value32.byte[2] = PLATFORM_SDIO_CMD52_READ(
+ driver_adapter, halmac_offset + 2);
+ value32.byte[3] = PLATFORM_SDIO_CMD52_READ(
+ driver_adapter, halmac_offset + 3);
+ value32.dword = le32_to_cpu(value32.dword);
+ } else {
+ value32.dword = PLATFORM_SDIO_CMD53_READ_32(
+ driver_adapter, halmac_offset);
+ }
+#else
+ value32.dword = PLATFORM_SDIO_CMD53_READ_32(driver_adapter,
+ halmac_offset);
+#endif
+ }
+
+ return value32.dword;
+}
+
+/**
+ * halmac_reg_write_32_sdio_88xx() - write 4byte register
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_offset : register offset
+ * @halmac_data : register value
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_reg_write_32_sdio_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u32 halmac_data)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ if ((halmac_offset & 0xFFFF0000) == 0)
+ halmac_offset |= WLAN_IOREG_OFFSET;
+
+ status = halmac_convert_to_sdio_bus_offset_88xx(halmac_adapter,
+ &halmac_offset);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("%s error = %x\n", __func__, status);
+ return status;
+ }
+
+ if (halmac_adapter->halmac_state.mac_power == HALMAC_MAC_POWER_OFF ||
+ (halmac_offset & (4 - 1)) != 0) {
+ PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset,
+ (u8)(halmac_data & 0xFF));
+ PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset + 1,
+ (u8)((halmac_data & 0xFF00) >> 8));
+ PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset + 2,
+ (u8)((halmac_data & 0xFF0000) >> 16));
+ PLATFORM_SDIO_CMD52_WRITE(
+ driver_adapter, halmac_offset + 3,
+ (u8)((halmac_data & 0xFF000000) >> 24));
+ } else {
+ PLATFORM_SDIO_CMD53_WRITE_32(driver_adapter, halmac_offset,
+ halmac_data);
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_reg_read_nbyte_sdio_88xx() - read n byte register
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_offset : register offset
+ * @halmac_size : register value size
+ * @halmac_data : register value
+ * Author : Soar
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+u8 halmac_reg_read_nbyte_sdio_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u32 halmac_size,
+ u8 *halmac_data)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ if ((halmac_offset & 0xFFFF0000) == 0) {
+ pr_err("halmac_offset error = 0x%x\n", halmac_offset);
+ return HALMAC_RET_FAIL;
+ }
+
+ status = halmac_convert_to_sdio_bus_offset_88xx(halmac_adapter,
+ &halmac_offset);
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("%s error = %x\n", __func__, status);
+ return status;
+ }
+
+ if (halmac_adapter->halmac_state.mac_power == HALMAC_MAC_POWER_OFF) {
+ pr_err("halmac_state error = 0x%x\n",
+ halmac_adapter->halmac_state.mac_power);
+ return HALMAC_RET_FAIL;
+ }
+
+ PLATFORM_SDIO_CMD53_READ_N(driver_adapter, halmac_offset, halmac_size,
+ halmac_data);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_get_sdio_tx_addr_sdio_88xx() - get CMD53 addr for the TX packet
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_buf : tx packet, include txdesc
+ * @halmac_size : tx packet size
+ * @pcmd53_addr : cmd53 addr value
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_get_sdio_tx_addr_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *halmac_buf, u32 halmac_size, u32 *pcmd53_addr)
+{
+ u32 four_byte_len;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ enum halmac_queue_select queue_sel;
+ enum halmac_dma_mapping dma_mapping;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_GET_SDIO_TX_ADDR);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ if (!halmac_buf) {
+ pr_err("halmac_buf is NULL!!\n");
+ return HALMAC_RET_DATA_BUF_NULL;
+ }
+
+ if (halmac_size == 0) {
+ pr_err("halmac_size is 0!!\n");
+ return HALMAC_RET_DATA_SIZE_INCORRECT;
+ }
+
+ queue_sel = (enum halmac_queue_select)GET_TX_DESC_QSEL(halmac_buf);
+
+ switch (queue_sel) {
+ case HALMAC_QUEUE_SELECT_VO:
+ case HALMAC_QUEUE_SELECT_VO_V2:
+ dma_mapping =
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VO];
+ break;
+ case HALMAC_QUEUE_SELECT_VI:
+ case HALMAC_QUEUE_SELECT_VI_V2:
+ dma_mapping =
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VI];
+ break;
+ case HALMAC_QUEUE_SELECT_BE:
+ case HALMAC_QUEUE_SELECT_BE_V2:
+ dma_mapping =
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BE];
+ break;
+ case HALMAC_QUEUE_SELECT_BK:
+ case HALMAC_QUEUE_SELECT_BK_V2:
+ dma_mapping =
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BK];
+ break;
+ case HALMAC_QUEUE_SELECT_MGNT:
+ dma_mapping =
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_MG];
+ break;
+ case HALMAC_QUEUE_SELECT_HIGH:
+ case HALMAC_QUEUE_SELECT_BCN:
+ case HALMAC_QUEUE_SELECT_CMD:
+ dma_mapping =
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_HI];
+ break;
+ default:
+ pr_err("Qsel is out of range\n");
+ return HALMAC_RET_QSEL_INCORRECT;
+ }
+
+ four_byte_len = (halmac_size >> 2) + ((halmac_size & (4 - 1)) ? 1 : 0);
+
+ switch (dma_mapping) {
+ case HALMAC_DMA_MAPPING_HIGH:
+ *pcmd53_addr = HALMAC_SDIO_CMD_ADDR_TXFF_HIGH;
+ break;
+ case HALMAC_DMA_MAPPING_NORMAL:
+ *pcmd53_addr = HALMAC_SDIO_CMD_ADDR_TXFF_NORMAL;
+ break;
+ case HALMAC_DMA_MAPPING_LOW:
+ *pcmd53_addr = HALMAC_SDIO_CMD_ADDR_TXFF_LOW;
+ break;
+ case HALMAC_DMA_MAPPING_EXTRA:
+ *pcmd53_addr = HALMAC_SDIO_CMD_ADDR_TXFF_EXTRA;
+ break;
+ default:
+ pr_err("DmaMapping is out of range\n");
+ return HALMAC_RET_DMA_MAP_INCORRECT;
+ }
+
+ *pcmd53_addr = (*pcmd53_addr << 13) |
+ (four_byte_len & HALMAC_SDIO_4BYTE_LEN_MASK);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_cfg_tx_agg_align_sdio_88xx() -config sdio bus tx agg alignment
+ * @halmac_adapter : the adapter of halmac
+ * @enable : function enable(1)/disable(0)
+ * @align_size : sdio bus tx agg alignment size (2^n, n = 3~11)
+ * Author : Soar Tu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_cfg_tx_agg_align_sdio_88xx(struct halmac_adapter *halmac_adapter,
+ u8 enable, u16 align_size)
+{
+ struct halmac_api *halmac_api;
+ void *driver_adapter = NULL;
+ u8 i, align_size_ok = 0;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_TX_AGG_ALIGN);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ if ((align_size & 0xF000) != 0) {
+ pr_err("Align size is out of range\n");
+ return HALMAC_RET_FAIL;
+ }
+
+ for (i = 3; i <= 11; i++) {
+ if (align_size == 1 << i) {
+ align_size_ok = 1;
+ break;
+ }
+ }
+ if (align_size_ok == 0) {
+ pr_err("Align size is not 2^3 ~ 2^11\n");
+ return HALMAC_RET_FAIL;
+ }
+
+ /*Keep sdio tx agg alignment size for driver query*/
+ halmac_adapter->hw_config_info.tx_align_size = align_size;
+
+ if (enable)
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_RQPN_CTRL_2,
+ 0x8000 | align_size);
+ else
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_RQPN_CTRL_2,
+ align_size);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status halmac_cfg_tx_agg_align_sdio_not_support_88xx(
+ struct halmac_adapter *halmac_adapter, u8 enable, u16 align_size)
+{
+ struct halmac_api *halmac_api;
+ void *driver_adapter = NULL;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_TX_AGG_ALIGN);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s not support\n", __func__);
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_tx_allowed_sdio_88xx() - check tx status
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_buf : tx packet, include txdesc
+ * @halmac_size : tx packet size, include txdesc
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_tx_allowed_sdio_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *halmac_buf, u32 halmac_size)
+{
+ u8 *curr_packet;
+ u16 *curr_free_space;
+ u32 i, counter;
+ u32 tx_agg_num, packet_size = 0;
+ u32 tx_required_page_num, total_required_page_num = 0;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+ void *driver_adapter = NULL;
+ enum halmac_dma_mapping dma_mapping;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_TX_ALLOWED_SDIO);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ tx_agg_num = GET_TX_DESC_DMA_TXAGG_NUM(halmac_buf);
+ curr_packet = halmac_buf;
+
+ tx_agg_num = tx_agg_num == 0 ? 1 : tx_agg_num;
+
+ switch ((enum halmac_queue_select)GET_TX_DESC_QSEL(curr_packet)) {
+ case HALMAC_QUEUE_SELECT_VO:
+ case HALMAC_QUEUE_SELECT_VO_V2:
+ dma_mapping =
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VO];
+ break;
+ case HALMAC_QUEUE_SELECT_VI:
+ case HALMAC_QUEUE_SELECT_VI_V2:
+ dma_mapping =
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VI];
+ break;
+ case HALMAC_QUEUE_SELECT_BE:
+ case HALMAC_QUEUE_SELECT_BE_V2:
+ dma_mapping =
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BE];
+ break;
+ case HALMAC_QUEUE_SELECT_BK:
+ case HALMAC_QUEUE_SELECT_BK_V2:
+ dma_mapping =
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BK];
+ break;
+ case HALMAC_QUEUE_SELECT_MGNT:
+ dma_mapping =
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_MG];
+ break;
+ case HALMAC_QUEUE_SELECT_HIGH:
+ dma_mapping =
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_HI];
+ break;
+ case HALMAC_QUEUE_SELECT_BCN:
+ case HALMAC_QUEUE_SELECT_CMD:
+ return HALMAC_RET_SUCCESS;
+ default:
+ pr_err("Qsel is out of range\n");
+ return HALMAC_RET_QSEL_INCORRECT;
+ }
+
+ switch (dma_mapping) {
+ case HALMAC_DMA_MAPPING_HIGH:
+ curr_free_space =
+ &halmac_adapter->sdio_free_space.high_queue_number;
+ break;
+ case HALMAC_DMA_MAPPING_NORMAL:
+ curr_free_space =
+ &halmac_adapter->sdio_free_space.normal_queue_number;
+ break;
+ case HALMAC_DMA_MAPPING_LOW:
+ curr_free_space =
+ &halmac_adapter->sdio_free_space.low_queue_number;
+ break;
+ case HALMAC_DMA_MAPPING_EXTRA:
+ curr_free_space =
+ &halmac_adapter->sdio_free_space.extra_queue_number;
+ break;
+ default:
+ pr_err("DmaMapping is out of range\n");
+ return HALMAC_RET_DMA_MAP_INCORRECT;
+ }
+
+ for (i = 0; i < tx_agg_num; i++) {
+ packet_size = GET_TX_DESC_TXPKTSIZE(curr_packet) +
+ GET_TX_DESC_OFFSET(curr_packet) +
+ (GET_TX_DESC_PKT_OFFSET(curr_packet) << 3);
+ tx_required_page_num =
+ (packet_size >>
+ halmac_adapter->hw_config_info.page_size_2_power) +
+ ((packet_size &
+ (halmac_adapter->hw_config_info.page_size - 1)) ?
+ 1 :
+ 0);
+ total_required_page_num += tx_required_page_num;
+
+ packet_size = HALMAC_ALIGN(packet_size, 8);
+
+ curr_packet += packet_size;
+ }
+
+ counter = 10;
+ do {
+ if ((u32)(*curr_free_space +
+ halmac_adapter->sdio_free_space.public_queue_number) >
+ total_required_page_num) {
+ if (*curr_free_space >= total_required_page_num) {
+ *curr_free_space -=
+ (u16)total_required_page_num;
+ } else {
+ halmac_adapter->sdio_free_space
+ .public_queue_number -=
+ (u16)(total_required_page_num -
+ *curr_free_space);
+ *curr_free_space = 0;
+ }
+
+ status = halmac_check_oqt_88xx(halmac_adapter,
+ tx_agg_num, halmac_buf);
+
+ if (status != HALMAC_RET_SUCCESS)
+ return status;
+
+ break;
+ }
+
+ halmac_update_sdio_free_page_88xx(halmac_adapter);
+
+ counter--;
+ if (counter == 0)
+ return HALMAC_RET_FREE_SPACE_NOT_ENOUGH;
+ } while (1);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_reg_read_indirect_32_sdio_88xx() - read MAC reg by SDIO reg
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_offset : register offset
+ * Author : Soar
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+u32 halmac_reg_read_indirect_32_sdio_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset)
+{
+ u8 rtemp;
+ u32 counter = 1000;
+ void *driver_adapter = NULL;
+
+ union {
+ u32 dword;
+ u8 byte[4];
+ } value32 = {0x00000000};
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ PLATFORM_SDIO_CMD53_WRITE_32(
+ driver_adapter,
+ (HALMAC_SDIO_CMD_ADDR_SDIO_REG << 13) |
+ (REG_SDIO_INDIRECT_REG_CFG & HALMAC_SDIO_LOCAL_MSK),
+ halmac_offset | BIT(19) | BIT(17));
+
+ do {
+ rtemp = PLATFORM_SDIO_CMD52_READ(
+ driver_adapter,
+ (HALMAC_SDIO_CMD_ADDR_SDIO_REG << 13) |
+ ((REG_SDIO_INDIRECT_REG_CFG + 2) &
+ HALMAC_SDIO_LOCAL_MSK));
+ counter--;
+ } while ((rtemp & BIT(4)) != 0 && counter > 0);
+
+ value32.dword = PLATFORM_SDIO_CMD53_READ_32(
+ driver_adapter,
+ (HALMAC_SDIO_CMD_ADDR_SDIO_REG << 13) |
+ (REG_SDIO_INDIRECT_REG_DATA & HALMAC_SDIO_LOCAL_MSK));
+
+ return value32.dword;
+}
diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx_sdio.h b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx_sdio.h
new file mode 100644
index 0000000..ee441ee
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx_sdio.h
@@ -0,0 +1,84 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HALMAC_API_88XX_SDIO_H_
+#define _HALMAC_API_88XX_SDIO_H_
+
+#include "../halmac_2_platform.h"
+#include "../halmac_type.h"
+
+enum halmac_ret_status
+halmac_init_sdio_cfg_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_deinit_sdio_cfg_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_cfg_rx_aggregation_88xx_sdio(struct halmac_adapter *halmac_adapter,
+ struct halmac_rxagg_cfg *phalmac_rxagg_cfg);
+
+u8 halmac_reg_read_8_sdio_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset);
+
+enum halmac_ret_status
+halmac_reg_write_8_sdio_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u8 halmac_data);
+
+u16 halmac_reg_read_16_sdio_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset);
+
+enum halmac_ret_status
+halmac_reg_write_16_sdio_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u16 halmac_data);
+
+u32 halmac_reg_read_32_sdio_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset);
+
+enum halmac_ret_status
+halmac_reg_write_32_sdio_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u32 halmac_data);
+
+enum halmac_ret_status
+halmac_get_sdio_tx_addr_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *halmac_buf, u32 halmac_size, u32 *pcmd53_addr);
+
+enum halmac_ret_status
+halmac_cfg_tx_agg_align_sdio_88xx(struct halmac_adapter *halmac_adapter,
+ u8 enable, u16 align_size);
+
+enum halmac_ret_status halmac_cfg_tx_agg_align_sdio_not_support_88xx(
+ struct halmac_adapter *halmac_adapter, u8 enable, u16 align_size);
+
+enum halmac_ret_status
+halmac_tx_allowed_sdio_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *halmac_buf, u32 halmac_size);
+
+u32 halmac_reg_read_indirect_32_sdio_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset);
+
+u8 halmac_reg_read_nbyte_sdio_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u32 halmac_size,
+ u8 *halmac_data);
+
+#endif /* _HALMAC_API_88XX_SDIO_H_ */
diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx_usb.c b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx_usb.c
new file mode 100644
index 0000000..17d7c3c
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx_usb.c
@@ -0,0 +1,554 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#include "halmac_88xx_cfg.h"
+
+/**
+ * halmac_init_usb_cfg_88xx() - init USB
+ * @halmac_adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_init_usb_cfg_88xx(struct halmac_adapter *halmac_adapter)
+{
+ void *driver_adapter = NULL;
+ u8 value8 = 0;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_USB_CFG);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ value8 |= (BIT_DMA_MODE |
+ (0x3 << BIT_SHIFT_BURST_CNT)); /* burst number = 4 */
+
+ if (PLATFORM_REG_READ_8(driver_adapter, REG_SYS_CFG2 + 3) ==
+ 0x20) { /* usb3.0 */
+ value8 |= (HALMAC_USB_BURST_SIZE_3_0 << BIT_SHIFT_BURST_SIZE);
+ } else {
+ if ((PLATFORM_REG_READ_8(driver_adapter, REG_USB_USBSTAT) &
+ 0x3) == 0x1) /* usb2.0 */
+ value8 |= HALMAC_USB_BURST_SIZE_2_0_HSPEED
+ << BIT_SHIFT_BURST_SIZE;
+ else /* usb1.1 */
+ value8 |= HALMAC_USB_BURST_SIZE_2_0_FSPEED
+ << BIT_SHIFT_BURST_SIZE;
+ }
+
+ PLATFORM_REG_WRITE_8(driver_adapter, REG_RXDMA_MODE, value8);
+ PLATFORM_REG_WRITE_16(
+ driver_adapter, REG_TXDMA_OFFSET_CHK,
+ PLATFORM_REG_READ_16(driver_adapter, REG_TXDMA_OFFSET_CHK) |
+ BIT_DROP_DATA_EN);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_deinit_usb_cfg_88xx() - deinit USB
+ * @halmac_adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_deinit_usb_cfg_88xx(struct halmac_adapter *halmac_adapter)
+{
+ void *driver_adapter = NULL;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DEINIT_USB_CFG);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_cfg_rx_aggregation_88xx_usb() - config rx aggregation
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_rx_agg_mode
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_cfg_rx_aggregation_88xx_usb(struct halmac_adapter *halmac_adapter,
+ struct halmac_rxagg_cfg *phalmac_rxagg_cfg)
+{
+ u8 dma_usb_agg;
+ u8 size = 0, timeout = 0, agg_enable = 0;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter,
+ HALMAC_API_CFG_RX_AGGREGATION);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ dma_usb_agg =
+ HALMAC_REG_READ_8(halmac_adapter, REG_RXDMA_AGG_PG_TH + 3);
+ agg_enable = HALMAC_REG_READ_8(halmac_adapter, REG_TXDMA_PQ_MAP);
+
+ switch (phalmac_rxagg_cfg->mode) {
+ case HALMAC_RX_AGG_MODE_NONE:
+ agg_enable &= ~BIT_RXDMA_AGG_EN;
+ break;
+ case HALMAC_RX_AGG_MODE_DMA:
+ agg_enable |= BIT_RXDMA_AGG_EN;
+ dma_usb_agg |= BIT(7);
+ break;
+
+ case HALMAC_RX_AGG_MODE_USB:
+ agg_enable |= BIT_RXDMA_AGG_EN;
+ dma_usb_agg &= ~BIT(7);
+ break;
+ default:
+ pr_err("%s switch case not support\n", __func__);
+ agg_enable &= ~BIT_RXDMA_AGG_EN;
+ break;
+ }
+
+ if (!phalmac_rxagg_cfg->threshold.drv_define) {
+ if (PLATFORM_REG_READ_8(driver_adapter, REG_SYS_CFG2 + 3) ==
+ 0x20) {
+ /* usb3.0 */
+ size = 0x5;
+ timeout = 0xA;
+ } else {
+ /* usb2.0 */
+ size = 0x5;
+ timeout = 0x20;
+ }
+ } else {
+ size = phalmac_rxagg_cfg->threshold.size;
+ timeout = phalmac_rxagg_cfg->threshold.timeout;
+ }
+
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_TXDMA_PQ_MAP, agg_enable);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_RXDMA_AGG_PG_TH + 3,
+ dma_usb_agg);
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_RXDMA_AGG_PG_TH,
+ (u16)(size | (timeout << BIT_SHIFT_DMA_AGG_TO)));
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_reg_read_8_usb_88xx() - read 1byte register
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_offset : register offset
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+u8 halmac_reg_read_8_usb_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset)
+{
+ u8 value8;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ value8 = PLATFORM_REG_READ_8(driver_adapter, halmac_offset);
+
+ return value8;
+}
+
+/**
+ * halmac_reg_write_8_usb_88xx() - write 1byte register
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_offset : register offset
+ * @halmac_data : register value
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_reg_write_8_usb_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u8 halmac_data)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ PLATFORM_REG_WRITE_8(driver_adapter, halmac_offset, halmac_data);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_reg_read_16_usb_88xx() - read 2byte register
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_offset : register offset
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+u16 halmac_reg_read_16_usb_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ union {
+ u16 word;
+ u8 byte[2];
+ } value16 = {0x0000};
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ value16.word = PLATFORM_REG_READ_16(driver_adapter, halmac_offset);
+
+ return value16.word;
+}
+
+/**
+ * halmac_reg_write_16_usb_88xx() - write 2byte register
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_offset : register offset
+ * @halmac_data : register value
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_reg_write_16_usb_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u16 halmac_data)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ PLATFORM_REG_WRITE_16(driver_adapter, halmac_offset, halmac_data);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_reg_read_32_usb_88xx() - read 4byte register
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_offset : register offset
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+u32 halmac_reg_read_32_usb_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ union {
+ u32 dword;
+ u8 byte[4];
+ } value32 = {0x00000000};
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ value32.dword = PLATFORM_REG_READ_32(driver_adapter, halmac_offset);
+
+ return value32.dword;
+}
+
+/**
+ * halmac_reg_write_32_usb_88xx() - write 4byte register
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_offset : register offset
+ * @halmac_data : register value
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_reg_write_32_usb_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u32 halmac_data)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ PLATFORM_REG_WRITE_32(driver_adapter, halmac_offset, halmac_data);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_set_bulkout_num_usb_88xx() - inform bulk-out num
+ * @halmac_adapter : the adapter of halmac
+ * @bulkout_num : usb bulk-out number
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_set_bulkout_num_88xx(struct halmac_adapter *halmac_adapter,
+ u8 bulkout_num)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_SET_BULKOUT_NUM);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ halmac_adapter->halmac_bulkout_num = bulkout_num;
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_get_usb_bulkout_id_usb_88xx() - get bulk out id for the TX packet
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_buf : tx packet, include txdesc
+ * @halmac_size : tx packet size
+ * @bulkout_id : usb bulk-out id
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_get_usb_bulkout_id_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *halmac_buf, u32 halmac_size, u8 *bulkout_id)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ enum halmac_queue_select queue_sel;
+ enum halmac_dma_mapping dma_mapping;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter,
+ HALMAC_API_GET_USB_BULKOUT_ID);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ if (!halmac_buf) {
+ pr_err("halmac_buf is NULL!!\n");
+ return HALMAC_RET_DATA_BUF_NULL;
+ }
+
+ if (halmac_size == 0) {
+ pr_err("halmac_size is 0!!\n");
+ return HALMAC_RET_DATA_SIZE_INCORRECT;
+ }
+
+ queue_sel = (enum halmac_queue_select)GET_TX_DESC_QSEL(halmac_buf);
+
+ switch (queue_sel) {
+ case HALMAC_QUEUE_SELECT_VO:
+ case HALMAC_QUEUE_SELECT_VO_V2:
+ dma_mapping =
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VO];
+ break;
+ case HALMAC_QUEUE_SELECT_VI:
+ case HALMAC_QUEUE_SELECT_VI_V2:
+ dma_mapping =
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VI];
+ break;
+ case HALMAC_QUEUE_SELECT_BE:
+ case HALMAC_QUEUE_SELECT_BE_V2:
+ dma_mapping =
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BE];
+ break;
+ case HALMAC_QUEUE_SELECT_BK:
+ case HALMAC_QUEUE_SELECT_BK_V2:
+ dma_mapping =
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BK];
+ break;
+ case HALMAC_QUEUE_SELECT_MGNT:
+ dma_mapping =
+ halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_MG];
+ break;
+ case HALMAC_QUEUE_SELECT_HIGH:
+ case HALMAC_QUEUE_SELECT_BCN:
+ case HALMAC_QUEUE_SELECT_CMD:
+ dma_mapping = HALMAC_DMA_MAPPING_HIGH;
+ break;
+ default:
+ pr_err("Qsel is out of range\n");
+ return HALMAC_RET_QSEL_INCORRECT;
+ }
+
+ switch (dma_mapping) {
+ case HALMAC_DMA_MAPPING_HIGH:
+ *bulkout_id = 0;
+ break;
+ case HALMAC_DMA_MAPPING_NORMAL:
+ *bulkout_id = 1;
+ break;
+ case HALMAC_DMA_MAPPING_LOW:
+ *bulkout_id = 2;
+ break;
+ case HALMAC_DMA_MAPPING_EXTRA:
+ *bulkout_id = 3;
+ break;
+ default:
+ pr_err("DmaMapping is out of range\n");
+ return HALMAC_RET_DMA_MAP_INCORRECT;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_cfg_tx_agg_align_usb_88xx() -config sdio bus tx agg alignment
+ * @halmac_adapter : the adapter of halmac
+ * @enable : function enable(1)/disable(0)
+ * @align_size : sdio bus tx agg alignment size (2^n, n = 3~11)
+ * Author : Soar Tu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status halmac_cfg_tx_agg_align_usb_not_support_88xx(
+ struct halmac_adapter *halmac_adapter, u8 enable, u16 align_size)
+{
+ struct halmac_api *halmac_api;
+ void *driver_adapter = NULL;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_API_INVALID;
+
+ halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_TX_AGG_ALIGN);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s not support\n", __func__);
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx_usb.h b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx_usb.h
new file mode 100644
index 0000000..a3d2a6a
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx_usb.h
@@ -0,0 +1,73 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HALMAC_API_88XX_USB_H_
+#define _HALMAC_API_88XX_USB_H_
+
+#include "../halmac_2_platform.h"
+#include "../halmac_type.h"
+
+enum halmac_ret_status
+halmac_init_usb_cfg_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_deinit_usb_cfg_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_cfg_rx_aggregation_88xx_usb(struct halmac_adapter *halmac_adapter,
+ struct halmac_rxagg_cfg *phalmac_rxagg_cfg);
+
+u8 halmac_reg_read_8_usb_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset);
+
+enum halmac_ret_status
+halmac_reg_write_8_usb_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u8 halmac_data);
+
+u16 halmac_reg_read_16_usb_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset);
+
+enum halmac_ret_status
+halmac_reg_write_16_usb_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u16 halmac_data);
+
+u32 halmac_reg_read_32_usb_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset);
+
+enum halmac_ret_status
+halmac_reg_write_32_usb_88xx(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset, u32 halmac_data);
+
+enum halmac_ret_status
+halmac_set_bulkout_num_88xx(struct halmac_adapter *halmac_adapter,
+ u8 bulkout_num);
+
+enum halmac_ret_status
+halmac_get_usb_bulkout_id_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *halmac_buf, u32 halmac_size, u8 *bulkout_id);
+
+enum halmac_ret_status halmac_cfg_tx_agg_align_usb_not_support_88xx(
+ struct halmac_adapter *halmac_adapter, u8 enable, u16 align_size);
+
+#endif /* _HALMAC_API_88XX_USB_H_ */
diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_func_88xx.c b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_func_88xx.c
new file mode 100644
index 0000000..f33024e
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_func_88xx.c
@@ -0,0 +1,4494 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#include "halmac_88xx_cfg.h"
+
+static enum halmac_ret_status
+halmac_dump_efuse_fw_88xx(struct halmac_adapter *halmac_adapter);
+
+static enum halmac_ret_status
+halmac_dump_efuse_drv_88xx(struct halmac_adapter *halmac_adapter);
+
+static enum halmac_ret_status
+halmac_update_eeprom_mask_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_pg_efuse_info *pg_efuse_info,
+ u8 *eeprom_mask_updated);
+
+static enum halmac_ret_status
+halmac_check_efuse_enough_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_pg_efuse_info *pg_efuse_info,
+ u8 *eeprom_mask_updated);
+
+static enum halmac_ret_status
+halmac_program_efuse_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_pg_efuse_info *pg_efuse_info,
+ u8 *eeprom_mask_updated);
+
+static enum halmac_ret_status
+halmac_pwr_sub_seq_parer_88xx(struct halmac_adapter *halmac_adapter, u8 cut,
+ u8 fab, u8 intf,
+ struct halmac_wl_pwr_cfg_ *pwr_sub_seq_cfg);
+
+static enum halmac_ret_status
+halmac_parse_c2h_debug_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
+ u32 c2h_size);
+
+static enum halmac_ret_status
+halmac_parse_scan_status_rpt_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *c2h_buf, u32 c2h_size);
+
+static enum halmac_ret_status
+halmac_parse_psd_data_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
+ u32 c2h_size);
+
+static enum halmac_ret_status
+halmac_parse_efuse_data_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
+ u32 c2h_size);
+
+static enum halmac_ret_status
+halmac_parse_h2c_ack_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
+ u32 c2h_size);
+
+static enum halmac_ret_status
+halmac_enqueue_para_buff_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_phy_parameter_info *para_info,
+ u8 *curr_buff_wptr, bool *end_cmd);
+
+static enum halmac_ret_status
+halmac_parse_h2c_ack_phy_efuse_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *c2h_buf, u32 c2h_size);
+
+static enum halmac_ret_status
+halmac_parse_h2c_ack_cfg_para_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *c2h_buf, u32 c2h_size);
+
+static enum halmac_ret_status
+halmac_gen_cfg_para_h2c_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *h2c_buff);
+
+static enum halmac_ret_status
+halmac_parse_h2c_ack_update_packet_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *c2h_buf, u32 c2h_size);
+
+static enum halmac_ret_status
+halmac_parse_h2c_ack_update_datapack_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *c2h_buf, u32 c2h_size);
+
+static enum halmac_ret_status
+halmac_parse_h2c_ack_run_datapack_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *c2h_buf, u32 c2h_size);
+
+static enum halmac_ret_status
+halmac_parse_h2c_ack_channel_switch_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *c2h_buf, u32 c2h_size);
+
+static enum halmac_ret_status
+halmac_parse_h2c_ack_iqk_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *c2h_buf, u32 c2h_size);
+
+static enum halmac_ret_status
+halmac_parse_h2c_ack_power_tracking_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *c2h_buf, u32 c2h_size);
+
+void halmac_init_offload_feature_state_machine_88xx(
+ struct halmac_adapter *halmac_adapter)
+{
+ struct halmac_state *state = &halmac_adapter->halmac_state;
+
+ state->efuse_state_set.efuse_cmd_construct_state =
+ HALMAC_EFUSE_CMD_CONSTRUCT_IDLE;
+ state->efuse_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
+ state->efuse_state_set.seq_num = halmac_adapter->h2c_packet_seq;
+
+ state->cfg_para_state_set.cfg_para_cmd_construct_state =
+ HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE;
+ state->cfg_para_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
+ state->cfg_para_state_set.seq_num = halmac_adapter->h2c_packet_seq;
+
+ state->scan_state_set.scan_cmd_construct_state =
+ HALMAC_SCAN_CMD_CONSTRUCT_IDLE;
+ state->scan_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
+ state->scan_state_set.seq_num = halmac_adapter->h2c_packet_seq;
+
+ state->update_packet_set.process_status = HALMAC_CMD_PROCESS_IDLE;
+ state->update_packet_set.seq_num = halmac_adapter->h2c_packet_seq;
+
+ state->iqk_set.process_status = HALMAC_CMD_PROCESS_IDLE;
+ state->iqk_set.seq_num = halmac_adapter->h2c_packet_seq;
+
+ state->power_tracking_set.process_status = HALMAC_CMD_PROCESS_IDLE;
+ state->power_tracking_set.seq_num = halmac_adapter->h2c_packet_seq;
+
+ state->psd_set.process_status = HALMAC_CMD_PROCESS_IDLE;
+ state->psd_set.seq_num = halmac_adapter->h2c_packet_seq;
+ state->psd_set.data_size = 0;
+ state->psd_set.segment_size = 0;
+ state->psd_set.data = NULL;
+}
+
+enum halmac_ret_status
+halmac_dump_efuse_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_efuse_read_cfg cfg)
+{
+ u32 chk_h2c_init;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api =
+ (struct halmac_api *)halmac_adapter->halmac_api;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+ enum halmac_cmd_process_status *process_status =
+ &halmac_adapter->halmac_state.efuse_state_set.process_status;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ *process_status = HALMAC_CMD_PROCESS_SENDING;
+
+ if (halmac_transition_efuse_state_88xx(
+ halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_H2C_SENT) !=
+ HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ERROR_STATE;
+
+ if (cfg == HALMAC_EFUSE_R_AUTO) {
+ chk_h2c_init = HALMAC_REG_READ_32(halmac_adapter,
+ REG_H2C_PKT_READADDR);
+ if (halmac_adapter->halmac_state.dlfw_state ==
+ HALMAC_DLFW_NONE ||
+ chk_h2c_init == 0)
+ status = halmac_dump_efuse_drv_88xx(halmac_adapter);
+ else
+ status = halmac_dump_efuse_fw_88xx(halmac_adapter);
+ } else if (cfg == HALMAC_EFUSE_R_FW) {
+ status = halmac_dump_efuse_fw_88xx(halmac_adapter);
+ } else {
+ status = halmac_dump_efuse_drv_88xx(halmac_adapter);
+ }
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_read_efuse error = %x\n", status);
+ return status;
+ }
+
+ return status;
+}
+
+enum halmac_ret_status
+halmac_func_read_efuse_88xx(struct halmac_adapter *halmac_adapter, u32 offset,
+ u32 size, u8 *efuse_map)
+{
+ void *driver_adapter = NULL;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ if (!efuse_map) {
+ pr_err("Malloc for dump efuse map error\n");
+ return HALMAC_RET_NULL_POINTER;
+ }
+
+ if (halmac_adapter->hal_efuse_map_valid)
+ memcpy(efuse_map, halmac_adapter->hal_efuse_map + offset, size);
+ else if (halmac_read_hw_efuse_88xx(halmac_adapter, offset, size,
+ efuse_map) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_EFUSE_R_FAIL;
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_read_hw_efuse_88xx(struct halmac_adapter *halmac_adapter, u32 offset,
+ u32 size, u8 *efuse_map)
+{
+ u8 value8;
+ u32 value32;
+ u32 address;
+ u32 tmp32, counter;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ /* Read efuse no need 2.5V LDO */
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 3);
+ if (value8 & BIT(7))
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 3,
+ (u8)(value8 & ~(BIT(7))));
+
+ value32 = HALMAC_REG_READ_32(halmac_adapter, REG_EFUSE_CTRL);
+
+ for (address = offset; address < offset + size; address++) {
+ value32 = value32 &
+ ~((BIT_MASK_EF_DATA) |
+ (BIT_MASK_EF_ADDR << BIT_SHIFT_EF_ADDR));
+ value32 = value32 |
+ ((address & BIT_MASK_EF_ADDR) << BIT_SHIFT_EF_ADDR);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_EFUSE_CTRL,
+ value32 & (~BIT_EF_FLAG));
+
+ counter = 1000000;
+ do {
+ udelay(1);
+ tmp32 = HALMAC_REG_READ_32(halmac_adapter,
+ REG_EFUSE_CTRL);
+ counter--;
+ if (counter == 0) {
+ pr_err("HALMAC_RET_EFUSE_R_FAIL\n");
+ return HALMAC_RET_EFUSE_R_FAIL;
+ }
+ } while ((tmp32 & BIT_EF_FLAG) == 0);
+
+ *(efuse_map + address - offset) =
+ (u8)(tmp32 & BIT_MASK_EF_DATA);
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+halmac_dump_efuse_drv_88xx(struct halmac_adapter *halmac_adapter)
+{
+ u8 *efuse_map = NULL;
+ u32 efuse_size;
+ void *driver_adapter = NULL;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ efuse_size = halmac_adapter->hw_config_info.efuse_size;
+
+ if (!halmac_adapter->hal_efuse_map) {
+ halmac_adapter->hal_efuse_map = kzalloc(efuse_size, GFP_KERNEL);
+ if (!halmac_adapter->hal_efuse_map) {
+ pr_err("[ERR]halmac allocate efuse map Fail!!\n");
+ return HALMAC_RET_MALLOC_FAIL;
+ }
+ }
+
+ efuse_map = kzalloc(efuse_size, GFP_KERNEL);
+ if (!efuse_map) {
+ /* out of memory */
+ return HALMAC_RET_MALLOC_FAIL;
+ }
+
+ if (halmac_read_hw_efuse_88xx(halmac_adapter, 0, efuse_size,
+ efuse_map) != HALMAC_RET_SUCCESS) {
+ kfree(efuse_map);
+ return HALMAC_RET_EFUSE_R_FAIL;
+ }
+
+ spin_lock(&halmac_adapter->efuse_lock);
+ memcpy(halmac_adapter->hal_efuse_map, efuse_map, efuse_size);
+ halmac_adapter->hal_efuse_map_valid = true;
+ spin_unlock(&halmac_adapter->efuse_lock);
+
+ kfree(efuse_map);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+halmac_dump_efuse_fw_88xx(struct halmac_adapter *halmac_adapter)
+{
+ u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
+ u16 h2c_seq_mum = 0;
+ void *driver_adapter = NULL;
+ struct halmac_h2c_header_info h2c_header_info;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ h2c_header_info.sub_cmd_id = SUB_CMD_ID_DUMP_PHYSICAL_EFUSE;
+ h2c_header_info.content_size = 0;
+ h2c_header_info.ack = true;
+ halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
+ &h2c_header_info, &h2c_seq_mum);
+ halmac_adapter->halmac_state.efuse_state_set.seq_num = h2c_seq_mum;
+
+ if (!halmac_adapter->hal_efuse_map) {
+ halmac_adapter->hal_efuse_map = kzalloc(
+ halmac_adapter->hw_config_info.efuse_size, GFP_KERNEL);
+ if (!halmac_adapter->hal_efuse_map) {
+ /* out of memory */
+ return HALMAC_RET_MALLOC_FAIL;
+ }
+ }
+
+ if (!halmac_adapter->hal_efuse_map_valid) {
+ status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
+ HALMAC_H2C_CMD_SIZE_88XX,
+ true);
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_read_efuse_fw Fail = %x!!\n", status);
+ return status;
+ }
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_func_write_efuse_88xx(struct halmac_adapter *halmac_adapter, u32 offset,
+ u8 value)
+{
+ const u8 wite_protect_code = 0x69;
+ u32 value32, tmp32, counter;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ spin_lock(&halmac_adapter->efuse_lock);
+ halmac_adapter->hal_efuse_map_valid = false;
+ spin_unlock(&halmac_adapter->efuse_lock);
+
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_PMC_DBG_CTRL2 + 3,
+ wite_protect_code);
+
+ /* Enable 2.5V LDO */
+ HALMAC_REG_WRITE_8(
+ halmac_adapter, REG_LDO_EFUSE_CTRL + 3,
+ (u8)(HALMAC_REG_READ_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 3) |
+ BIT(7)));
+
+ value32 = HALMAC_REG_READ_32(halmac_adapter, REG_EFUSE_CTRL);
+ value32 =
+ value32 &
+ ~((BIT_MASK_EF_DATA) | (BIT_MASK_EF_ADDR << BIT_SHIFT_EF_ADDR));
+ value32 = value32 | ((offset & BIT_MASK_EF_ADDR) << BIT_SHIFT_EF_ADDR) |
+ (value & BIT_MASK_EF_DATA);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_EFUSE_CTRL,
+ value32 | BIT_EF_FLAG);
+
+ counter = 1000000;
+ do {
+ udelay(1);
+ tmp32 = HALMAC_REG_READ_32(halmac_adapter, REG_EFUSE_CTRL);
+ counter--;
+ if (counter == 0) {
+ pr_err("halmac_write_efuse Fail !!\n");
+ return HALMAC_RET_EFUSE_W_FAIL;
+ }
+ } while ((tmp32 & BIT_EF_FLAG) == BIT_EF_FLAG);
+
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_PMC_DBG_CTRL2 + 3, 0x00);
+
+ /* Disable 2.5V LDO */
+ HALMAC_REG_WRITE_8(
+ halmac_adapter, REG_LDO_EFUSE_CTRL + 3,
+ (u8)(HALMAC_REG_READ_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 3) &
+ ~(BIT(7))));
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_func_switch_efuse_bank_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_efuse_bank efuse_bank)
+{
+ u8 reg_value;
+ struct halmac_api *halmac_api;
+
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ if (halmac_transition_efuse_state_88xx(
+ halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_BUSY) !=
+ HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ERROR_STATE;
+
+ reg_value = HALMAC_REG_READ_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 1);
+
+ if (efuse_bank == (reg_value & (BIT(0) | BIT(1))))
+ return HALMAC_RET_SUCCESS;
+
+ reg_value &= ~(BIT(0) | BIT(1));
+ reg_value |= efuse_bank;
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 1, reg_value);
+
+ if ((HALMAC_REG_READ_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 1) &
+ (BIT(0) | BIT(1))) != efuse_bank)
+ return HALMAC_RET_SWITCH_EFUSE_BANK_FAIL;
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_eeprom_parser_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *physical_efuse_map, u8 *logical_efuse_map)
+{
+ u8 j;
+ u8 value8;
+ u8 block_index;
+ u8 valid_word_enable, word_enable;
+ u8 efuse_read_header, efuse_read_header2 = 0;
+ u32 eeprom_index;
+ u32 efuse_index = 0;
+ u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
+ void *driver_adapter = NULL;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ memset(logical_efuse_map, 0xFF, eeprom_size);
+
+ do {
+ value8 = *(physical_efuse_map + efuse_index);
+ efuse_read_header = value8;
+
+ if ((efuse_read_header & 0x1f) == 0x0f) {
+ efuse_index++;
+ value8 = *(physical_efuse_map + efuse_index);
+ efuse_read_header2 = value8;
+ block_index = ((efuse_read_header2 & 0xF0) >> 1) |
+ ((efuse_read_header >> 5) & 0x07);
+ word_enable = efuse_read_header2 & 0x0F;
+ } else {
+ block_index = (efuse_read_header & 0xF0) >> 4;
+ word_enable = efuse_read_header & 0x0F;
+ }
+
+ if (efuse_read_header == 0xff)
+ break;
+
+ efuse_index++;
+
+ if (efuse_index >= halmac_adapter->hw_config_info.efuse_size -
+ HALMAC_PROTECTED_EFUSE_SIZE_88XX - 1)
+ return HALMAC_RET_EEPROM_PARSING_FAIL;
+
+ for (j = 0; j < 4; j++) {
+ valid_word_enable =
+ (u8)((~(word_enable >> j)) & BIT(0));
+ if (valid_word_enable != 1)
+ continue;
+
+ eeprom_index = (block_index << 3) + (j << 1);
+
+ if ((eeprom_index + 1) > eeprom_size) {
+ pr_err("Error: EEPROM addr exceeds eeprom_size:0x%X, at eFuse 0x%X\n",
+ eeprom_size, efuse_index - 1);
+ if ((efuse_read_header & 0x1f) == 0x0f)
+ pr_err("Error: EEPROM header: 0x%X, 0x%X,\n",
+ efuse_read_header,
+ efuse_read_header2);
+ else
+ pr_err("Error: EEPROM header: 0x%X,\n",
+ efuse_read_header);
+
+ return HALMAC_RET_EEPROM_PARSING_FAIL;
+ }
+
+ value8 = *(physical_efuse_map + efuse_index);
+ *(logical_efuse_map + eeprom_index) = value8;
+
+ eeprom_index++;
+ efuse_index++;
+
+ if (efuse_index >
+ halmac_adapter->hw_config_info.efuse_size -
+ HALMAC_PROTECTED_EFUSE_SIZE_88XX - 1)
+ return HALMAC_RET_EEPROM_PARSING_FAIL;
+
+ value8 = *(physical_efuse_map + efuse_index);
+ *(logical_efuse_map + eeprom_index) = value8;
+
+ efuse_index++;
+
+ if (efuse_index >
+ halmac_adapter->hw_config_info.efuse_size -
+ HALMAC_PROTECTED_EFUSE_SIZE_88XX)
+ return HALMAC_RET_EEPROM_PARSING_FAIL;
+ }
+ } while (1);
+
+ halmac_adapter->efuse_end = efuse_index;
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_read_logical_efuse_map_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *map)
+{
+ u8 *efuse_map = NULL;
+ u32 efuse_size;
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ efuse_size = halmac_adapter->hw_config_info.efuse_size;
+
+ if (!halmac_adapter->hal_efuse_map_valid) {
+ efuse_map = kzalloc(efuse_size, GFP_KERNEL);
+ if (!efuse_map) {
+ pr_err("[ERR]halmac allocate local efuse map Fail!!\n");
+ return HALMAC_RET_MALLOC_FAIL;
+ }
+
+ status = halmac_func_read_efuse_88xx(halmac_adapter, 0,
+ efuse_size, efuse_map);
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("[ERR]halmac_read_efuse error = %x\n", status);
+ kfree(efuse_map);
+ return status;
+ }
+
+ if (!halmac_adapter->hal_efuse_map) {
+ halmac_adapter->hal_efuse_map =
+ kzalloc(efuse_size, GFP_KERNEL);
+ if (!halmac_adapter->hal_efuse_map) {
+ pr_err("[ERR]halmac allocate efuse map Fail!!\n");
+ kfree(efuse_map);
+ return HALMAC_RET_MALLOC_FAIL;
+ }
+ }
+
+ spin_lock(&halmac_adapter->efuse_lock);
+ memcpy(halmac_adapter->hal_efuse_map, efuse_map, efuse_size);
+ halmac_adapter->hal_efuse_map_valid = true;
+ spin_unlock(&halmac_adapter->efuse_lock);
+
+ kfree(efuse_map);
+ }
+
+ if (halmac_eeprom_parser_88xx(halmac_adapter,
+ halmac_adapter->hal_efuse_map,
+ map) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_EEPROM_PARSING_FAIL;
+
+ return status;
+}
+
+enum halmac_ret_status
+halmac_func_write_logical_efuse_88xx(struct halmac_adapter *halmac_adapter,
+ u32 offset, u8 value)
+{
+ u8 pg_efuse_byte1, pg_efuse_byte2;
+ u8 pg_block, pg_block_index;
+ u8 pg_efuse_header, pg_efuse_header2;
+ u8 *eeprom_map = NULL;
+ u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
+ u32 efuse_end, pg_efuse_num;
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
+ if (!eeprom_map) {
+ /* out of memory */
+ return HALMAC_RET_MALLOC_FAIL;
+ }
+ memset(eeprom_map, 0xFF, eeprom_size);
+
+ status = halmac_read_logical_efuse_map_88xx(halmac_adapter, eeprom_map);
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("[ERR]halmac_read_logical_efuse_map_88xx error = %x\n",
+ status);
+ kfree(eeprom_map);
+ return status;
+ }
+
+ if (*(eeprom_map + offset) != value) {
+ efuse_end = halmac_adapter->efuse_end;
+ pg_block = (u8)(offset >> 3);
+ pg_block_index = (u8)((offset & (8 - 1)) >> 1);
+
+ if (offset > 0x7f) {
+ pg_efuse_header =
+ (((pg_block & 0x07) << 5) & 0xE0) | 0x0F;
+ pg_efuse_header2 =
+ (u8)(((pg_block & 0x78) << 1) +
+ ((0x1 << pg_block_index) ^ 0x0F));
+ } else {
+ pg_efuse_header =
+ (u8)((pg_block << 4) +
+ ((0x01 << pg_block_index) ^ 0x0F));
+ }
+
+ if ((offset & 1) == 0) {
+ pg_efuse_byte1 = value;
+ pg_efuse_byte2 = *(eeprom_map + offset + 1);
+ } else {
+ pg_efuse_byte1 = *(eeprom_map + offset - 1);
+ pg_efuse_byte2 = value;
+ }
+
+ if (offset > 0x7f) {
+ pg_efuse_num = 4;
+ if (halmac_adapter->hw_config_info.efuse_size <=
+ (pg_efuse_num + HALMAC_PROTECTED_EFUSE_SIZE_88XX +
+ halmac_adapter->efuse_end)) {
+ kfree(eeprom_map);
+ return HALMAC_RET_EFUSE_NOT_ENOUGH;
+ }
+ halmac_func_write_efuse_88xx(halmac_adapter, efuse_end,
+ pg_efuse_header);
+ halmac_func_write_efuse_88xx(halmac_adapter,
+ efuse_end + 1,
+ pg_efuse_header2);
+ halmac_func_write_efuse_88xx(
+ halmac_adapter, efuse_end + 2, pg_efuse_byte1);
+ status = halmac_func_write_efuse_88xx(
+ halmac_adapter, efuse_end + 3, pg_efuse_byte2);
+ } else {
+ pg_efuse_num = 3;
+ if (halmac_adapter->hw_config_info.efuse_size <=
+ (pg_efuse_num + HALMAC_PROTECTED_EFUSE_SIZE_88XX +
+ halmac_adapter->efuse_end)) {
+ kfree(eeprom_map);
+ return HALMAC_RET_EFUSE_NOT_ENOUGH;
+ }
+ halmac_func_write_efuse_88xx(halmac_adapter, efuse_end,
+ pg_efuse_header);
+ halmac_func_write_efuse_88xx(
+ halmac_adapter, efuse_end + 1, pg_efuse_byte1);
+ status = halmac_func_write_efuse_88xx(
+ halmac_adapter, efuse_end + 2, pg_efuse_byte2);
+ }
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("[ERR]halmac_write_logical_efuse error = %x\n",
+ status);
+ kfree(eeprom_map);
+ return status;
+ }
+ }
+
+ kfree(eeprom_map);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_func_pg_efuse_by_map_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_pg_efuse_info *pg_efuse_info,
+ enum halmac_efuse_read_cfg cfg)
+{
+ u8 *eeprom_mask_updated = NULL;
+ u32 eeprom_mask_size = halmac_adapter->hw_config_info.eeprom_size >> 4;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ eeprom_mask_updated = kzalloc(eeprom_mask_size, GFP_KERNEL);
+ if (!eeprom_mask_updated) {
+ /* out of memory */
+ return HALMAC_RET_MALLOC_FAIL;
+ }
+
+ status = halmac_update_eeprom_mask_88xx(halmac_adapter, pg_efuse_info,
+ eeprom_mask_updated);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("[ERR]halmac_update_eeprom_mask_88xx error = %x\n",
+ status);
+ kfree(eeprom_mask_updated);
+ return status;
+ }
+
+ status = halmac_check_efuse_enough_88xx(halmac_adapter, pg_efuse_info,
+ eeprom_mask_updated);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("[ERR]halmac_check_efuse_enough_88xx error = %x\n",
+ status);
+ kfree(eeprom_mask_updated);
+ return status;
+ }
+
+ status = halmac_program_efuse_88xx(halmac_adapter, pg_efuse_info,
+ eeprom_mask_updated);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("[ERR]halmac_program_efuse_88xx error = %x\n", status);
+ kfree(eeprom_mask_updated);
+ return status;
+ }
+
+ kfree(eeprom_mask_updated);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+halmac_update_eeprom_mask_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_pg_efuse_info *pg_efuse_info,
+ u8 *eeprom_mask_updated)
+{
+ u8 *eeprom_map = NULL;
+ u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
+ u8 *eeprom_map_pg, *eeprom_mask;
+ u16 i, j;
+ u16 map_byte_offset, mask_byte_offset;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ void *driver_adapter = NULL;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
+ if (!eeprom_map) {
+ /* out of memory */
+ return HALMAC_RET_MALLOC_FAIL;
+ }
+ memset(eeprom_map, 0xFF, eeprom_size);
+
+ memset(eeprom_mask_updated, 0x00, pg_efuse_info->efuse_mask_size);
+
+ status = halmac_read_logical_efuse_map_88xx(halmac_adapter, eeprom_map);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ kfree(eeprom_map);
+ return status;
+ }
+
+ eeprom_map_pg = pg_efuse_info->efuse_map;
+ eeprom_mask = pg_efuse_info->efuse_mask;
+
+ for (i = 0; i < pg_efuse_info->efuse_mask_size; i++)
+ *(eeprom_mask_updated + i) = *(eeprom_mask + i);
+
+ for (i = 0; i < pg_efuse_info->efuse_map_size; i = i + 16) {
+ for (j = 0; j < 16; j = j + 2) {
+ map_byte_offset = i + j;
+ mask_byte_offset = i >> 4;
+ if (*(eeprom_map_pg + map_byte_offset) ==
+ *(eeprom_map + map_byte_offset)) {
+ if (*(eeprom_map_pg + map_byte_offset + 1) ==
+ *(eeprom_map + map_byte_offset + 1)) {
+ switch (j) {
+ case 0:
+ *(eeprom_mask_updated +
+ mask_byte_offset) =
+ *(eeprom_mask_updated +
+ mask_byte_offset) &
+ (BIT(4) ^ 0xFF);
+ break;
+ case 2:
+ *(eeprom_mask_updated +
+ mask_byte_offset) =
+ *(eeprom_mask_updated +
+ mask_byte_offset) &
+ (BIT(5) ^ 0xFF);
+ break;
+ case 4:
+ *(eeprom_mask_updated +
+ mask_byte_offset) =
+ *(eeprom_mask_updated +
+ mask_byte_offset) &
+ (BIT(6) ^ 0xFF);
+ break;
+ case 6:
+ *(eeprom_mask_updated +
+ mask_byte_offset) =
+ *(eeprom_mask_updated +
+ mask_byte_offset) &
+ (BIT(7) ^ 0xFF);
+ break;
+ case 8:
+ *(eeprom_mask_updated +
+ mask_byte_offset) =
+ *(eeprom_mask_updated +
+ mask_byte_offset) &
+ (BIT(0) ^ 0xFF);
+ break;
+ case 10:
+ *(eeprom_mask_updated +
+ mask_byte_offset) =
+ *(eeprom_mask_updated +
+ mask_byte_offset) &
+ (BIT(1) ^ 0xFF);
+ break;
+ case 12:
+ *(eeprom_mask_updated +
+ mask_byte_offset) =
+ *(eeprom_mask_updated +
+ mask_byte_offset) &
+ (BIT(2) ^ 0xFF);
+ break;
+ case 14:
+ *(eeprom_mask_updated +
+ mask_byte_offset) =
+ *(eeprom_mask_updated +
+ mask_byte_offset) &
+ (BIT(3) ^ 0xFF);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ kfree(eeprom_map);
+
+ return status;
+}
+
+static enum halmac_ret_status
+halmac_check_efuse_enough_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_pg_efuse_info *pg_efuse_info,
+ u8 *eeprom_mask_updated)
+{
+ u8 pre_word_enb, word_enb;
+ u8 pg_efuse_header, pg_efuse_header2;
+ u8 pg_block;
+ u16 i, j;
+ u32 efuse_end;
+ u32 tmp_eeprom_offset, pg_efuse_num = 0;
+
+ efuse_end = halmac_adapter->efuse_end;
+
+ for (i = 0; i < pg_efuse_info->efuse_map_size; i = i + 8) {
+ tmp_eeprom_offset = i;
+
+ if ((tmp_eeprom_offset & 7) > 0) {
+ pre_word_enb =
+ (*(eeprom_mask_updated + (i >> 4)) & 0x0F);
+ word_enb = pre_word_enb ^ 0x0F;
+ } else {
+ pre_word_enb = (*(eeprom_mask_updated + (i >> 4)) >> 4);
+ word_enb = pre_word_enb ^ 0x0F;
+ }
+
+ pg_block = (u8)(tmp_eeprom_offset >> 3);
+
+ if (pre_word_enb > 0) {
+ if (tmp_eeprom_offset > 0x7f) {
+ pg_efuse_header =
+ (((pg_block & 0x07) << 5) & 0xE0) |
+ 0x0F;
+ pg_efuse_header2 = (u8)(
+ ((pg_block & 0x78) << 1) + word_enb);
+ } else {
+ pg_efuse_header =
+ (u8)((pg_block << 4) + word_enb);
+ }
+
+ if (tmp_eeprom_offset > 0x7f) {
+ pg_efuse_num++;
+ pg_efuse_num++;
+ efuse_end = efuse_end + 2;
+ for (j = 0; j < 4; j++) {
+ if (((pre_word_enb >> j) & 0x1) > 0) {
+ pg_efuse_num++;
+ pg_efuse_num++;
+ efuse_end = efuse_end + 2;
+ }
+ }
+ } else {
+ pg_efuse_num++;
+ efuse_end = efuse_end + 1;
+ for (j = 0; j < 4; j++) {
+ if (((pre_word_enb >> j) & 0x1) > 0) {
+ pg_efuse_num++;
+ pg_efuse_num++;
+ efuse_end = efuse_end + 2;
+ }
+ }
+ }
+ }
+ }
+
+ if (halmac_adapter->hw_config_info.efuse_size <=
+ (pg_efuse_num + HALMAC_PROTECTED_EFUSE_SIZE_88XX +
+ halmac_adapter->efuse_end))
+ return HALMAC_RET_EFUSE_NOT_ENOUGH;
+
+ return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+halmac_program_efuse_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_pg_efuse_info *pg_efuse_info,
+ u8 *eeprom_mask_updated)
+{
+ u8 pre_word_enb, word_enb;
+ u8 pg_efuse_header, pg_efuse_header2;
+ u8 pg_block;
+ u16 i, j;
+ u32 efuse_end;
+ u32 tmp_eeprom_offset;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ efuse_end = halmac_adapter->efuse_end;
+
+ for (i = 0; i < pg_efuse_info->efuse_map_size; i = i + 8) {
+ tmp_eeprom_offset = i;
+
+ if (((tmp_eeprom_offset >> 3) & 1) > 0) {
+ pre_word_enb =
+ (*(eeprom_mask_updated + (i >> 4)) & 0x0F);
+ word_enb = pre_word_enb ^ 0x0F;
+ } else {
+ pre_word_enb = (*(eeprom_mask_updated + (i >> 4)) >> 4);
+ word_enb = pre_word_enb ^ 0x0F;
+ }
+
+ pg_block = (u8)(tmp_eeprom_offset >> 3);
+
+ if (pre_word_enb <= 0)
+ continue;
+
+ if (tmp_eeprom_offset > 0x7f) {
+ pg_efuse_header =
+ (((pg_block & 0x07) << 5) & 0xE0) | 0x0F;
+ pg_efuse_header2 =
+ (u8)(((pg_block & 0x78) << 1) + word_enb);
+ } else {
+ pg_efuse_header = (u8)((pg_block << 4) + word_enb);
+ }
+
+ if (tmp_eeprom_offset > 0x7f) {
+ halmac_func_write_efuse_88xx(halmac_adapter, efuse_end,
+ pg_efuse_header);
+ status = halmac_func_write_efuse_88xx(halmac_adapter,
+ efuse_end + 1,
+ pg_efuse_header2);
+ efuse_end = efuse_end + 2;
+ for (j = 0; j < 4; j++) {
+ if (((pre_word_enb >> j) & 0x1) > 0) {
+ halmac_func_write_efuse_88xx(
+ halmac_adapter, efuse_end,
+ *(pg_efuse_info->efuse_map +
+ tmp_eeprom_offset +
+ (j << 1)));
+ status = halmac_func_write_efuse_88xx(
+ halmac_adapter, efuse_end + 1,
+ *(pg_efuse_info->efuse_map +
+ tmp_eeprom_offset + (j << 1) +
+ 1));
+ efuse_end = efuse_end + 2;
+ }
+ }
+ } else {
+ status = halmac_func_write_efuse_88xx(
+ halmac_adapter, efuse_end, pg_efuse_header);
+ efuse_end = efuse_end + 1;
+ for (j = 0; j < 4; j++) {
+ if (((pre_word_enb >> j) & 0x1) > 0) {
+ halmac_func_write_efuse_88xx(
+ halmac_adapter, efuse_end,
+ *(pg_efuse_info->efuse_map +
+ tmp_eeprom_offset +
+ (j << 1)));
+ status = halmac_func_write_efuse_88xx(
+ halmac_adapter, efuse_end + 1,
+ *(pg_efuse_info->efuse_map +
+ tmp_eeprom_offset + (j << 1) +
+ 1));
+ efuse_end = efuse_end + 2;
+ }
+ }
+ }
+ }
+
+ return status;
+}
+
+enum halmac_ret_status
+halmac_dlfw_to_mem_88xx(struct halmac_adapter *halmac_adapter, u8 *ram_code,
+ u32 dest, u32 code_size)
+{
+ u8 *code_ptr;
+ u8 first_part;
+ u32 mem_offset;
+ u32 pkt_size_tmp, send_pkt_size;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ code_ptr = ram_code;
+ mem_offset = 0;
+ first_part = 1;
+ pkt_size_tmp = code_size;
+
+ HALMAC_REG_WRITE_32(
+ halmac_adapter, REG_DDMA_CH0CTRL,
+ HALMAC_REG_READ_32(halmac_adapter, REG_DDMA_CH0CTRL) |
+ BIT_DDMACH0_RESET_CHKSUM_STS);
+
+ while (pkt_size_tmp != 0) {
+ if (pkt_size_tmp >= halmac_adapter->max_download_size)
+ send_pkt_size = halmac_adapter->max_download_size;
+ else
+ send_pkt_size = pkt_size_tmp;
+
+ if (halmac_send_fwpkt_88xx(
+ halmac_adapter, code_ptr + mem_offset,
+ send_pkt_size) != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_send_fwpkt_88xx fail!!");
+ return HALMAC_RET_DLFW_FAIL;
+ }
+
+ if (halmac_iddma_dlfw_88xx(
+ halmac_adapter,
+ HALMAC_OCPBASE_TXBUF_88XX +
+ halmac_adapter->hw_config_info.txdesc_size,
+ dest + mem_offset, send_pkt_size,
+ first_part) != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_iddma_dlfw_88xx fail!!");
+ return HALMAC_RET_DLFW_FAIL;
+ }
+
+ first_part = 0;
+ mem_offset += send_pkt_size;
+ pkt_size_tmp -= send_pkt_size;
+ }
+
+ if (halmac_check_fw_chksum_88xx(halmac_adapter, dest) !=
+ HALMAC_RET_SUCCESS) {
+ pr_err("halmac_check_fw_chksum_88xx fail!!");
+ return HALMAC_RET_DLFW_FAIL;
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_send_fwpkt_88xx(struct halmac_adapter *halmac_adapter, u8 *ram_code,
+ u32 code_size)
+{
+ if (halmac_download_rsvd_page_88xx(halmac_adapter, ram_code,
+ code_size) != HALMAC_RET_SUCCESS) {
+ pr_err("PLATFORM_SEND_RSVD_PAGE 0 error!!\n");
+ return HALMAC_RET_DL_RSVD_PAGE_FAIL;
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_iddma_dlfw_88xx(struct halmac_adapter *halmac_adapter, u32 source,
+ u32 dest, u32 length, u8 first)
+{
+ u32 counter;
+ u32 ch0_control = (u32)(BIT_DDMACH0_CHKSUM_EN | BIT_DDMACH0_OWN);
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ counter = HALMC_DDMA_POLLING_COUNT;
+ while (HALMAC_REG_READ_32(halmac_adapter, REG_DDMA_CH0CTRL) &
+ BIT_DDMACH0_OWN) {
+ counter--;
+ if (counter == 0) {
+ pr_err("%s error-1!!\n", __func__);
+ return HALMAC_RET_DDMA_FAIL;
+ }
+ }
+
+ ch0_control |= (length & BIT_MASK_DDMACH0_DLEN);
+ if (first == 0)
+ ch0_control |= BIT_DDMACH0_CHKSUM_CONT;
+
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_DDMA_CH0SA, source);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_DDMA_CH0DA, dest);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_DDMA_CH0CTRL, ch0_control);
+
+ counter = HALMC_DDMA_POLLING_COUNT;
+ while (HALMAC_REG_READ_32(halmac_adapter, REG_DDMA_CH0CTRL) &
+ BIT_DDMACH0_OWN) {
+ counter--;
+ if (counter == 0) {
+ pr_err("%s error-2!!\n", __func__);
+ return HALMAC_RET_DDMA_FAIL;
+ }
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_check_fw_chksum_88xx(struct halmac_adapter *halmac_adapter,
+ u32 memory_address)
+{
+ u8 mcu_fw_ctrl;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ enum halmac_ret_status status;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ mcu_fw_ctrl = HALMAC_REG_READ_8(halmac_adapter, REG_MCUFW_CTRL);
+
+ if (HALMAC_REG_READ_32(halmac_adapter, REG_DDMA_CH0CTRL) &
+ BIT_DDMACH0_CHKSUM_STS) {
+ if (memory_address < HALMAC_OCPBASE_DMEM_88XX) {
+ mcu_fw_ctrl |= BIT_IMEM_DW_OK;
+ HALMAC_REG_WRITE_8(
+ halmac_adapter, REG_MCUFW_CTRL,
+ (u8)(mcu_fw_ctrl & ~(BIT_IMEM_CHKSUM_OK)));
+ } else {
+ mcu_fw_ctrl |= BIT_DMEM_DW_OK;
+ HALMAC_REG_WRITE_8(
+ halmac_adapter, REG_MCUFW_CTRL,
+ (u8)(mcu_fw_ctrl & ~(BIT_DMEM_CHKSUM_OK)));
+ }
+
+ pr_err("%s error!!\n", __func__);
+
+ status = HALMAC_RET_FW_CHECKSUM_FAIL;
+ } else {
+ if (memory_address < HALMAC_OCPBASE_DMEM_88XX) {
+ mcu_fw_ctrl |= BIT_IMEM_DW_OK;
+ HALMAC_REG_WRITE_8(
+ halmac_adapter, REG_MCUFW_CTRL,
+ (u8)(mcu_fw_ctrl | BIT_IMEM_CHKSUM_OK));
+ } else {
+ mcu_fw_ctrl |= BIT_DMEM_DW_OK;
+ HALMAC_REG_WRITE_8(
+ halmac_adapter, REG_MCUFW_CTRL,
+ (u8)(mcu_fw_ctrl | BIT_DMEM_CHKSUM_OK));
+ }
+
+ status = HALMAC_RET_SUCCESS;
+ }
+
+ return status;
+}
+
+enum halmac_ret_status
+halmac_dlfw_end_flow_88xx(struct halmac_adapter *halmac_adapter)
+{
+ u8 value8;
+ u32 counter;
+ void *driver_adapter = halmac_adapter->driver_adapter;
+ struct halmac_api *halmac_api =
+ (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_TXDMA_STATUS, BIT(2));
+
+ /* Check IMEM & DMEM checksum is OK or not */
+ if ((HALMAC_REG_READ_8(halmac_adapter, REG_MCUFW_CTRL) & 0x50) == 0x50)
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_MCUFW_CTRL,
+ (u16)(HALMAC_REG_READ_16(halmac_adapter,
+ REG_MCUFW_CTRL) |
+ BIT_FW_DW_RDY));
+ else
+ return HALMAC_RET_DLFW_FAIL;
+
+ HALMAC_REG_WRITE_8(
+ halmac_adapter, REG_MCUFW_CTRL,
+ (u8)(HALMAC_REG_READ_8(halmac_adapter, REG_MCUFW_CTRL) &
+ ~(BIT(0))));
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RSV_CTRL + 1);
+ value8 = (u8)(value8 | BIT(0));
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_RSV_CTRL + 1, value8);
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_SYS_FUNC_EN + 1);
+ value8 = (u8)(value8 | BIT(2));
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_SYS_FUNC_EN + 1,
+ value8); /* Release MCU reset */
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Download Finish, Reset CPU\n");
+
+ counter = 10000;
+ while (HALMAC_REG_READ_16(halmac_adapter, REG_MCUFW_CTRL) != 0xC078) {
+ if (counter == 0) {
+ pr_err("Check 0x80 = 0xC078 fail\n");
+ if ((HALMAC_REG_READ_32(halmac_adapter, REG_FW_DBG7) &
+ 0xFFFFFF00) == 0xFAAAAA00)
+ pr_err("Key fail\n");
+ return HALMAC_RET_DLFW_FAIL;
+ }
+ counter--;
+ usleep_range(50, 60);
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Check 0x80 = 0xC078 counter = %d\n", counter);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_free_dl_fw_end_flow_88xx(struct halmac_adapter *halmac_adapter)
+{
+ u32 counter;
+ struct halmac_api *halmac_api =
+ (struct halmac_api *)halmac_adapter->halmac_api;
+
+ counter = 100;
+ while (HALMAC_REG_READ_8(halmac_adapter, REG_HMETFR + 3) != 0) {
+ counter--;
+ if (counter == 0) {
+ pr_err("[ERR]0x1CF != 0\n");
+ return HALMAC_RET_DLFW_FAIL;
+ }
+ usleep_range(50, 60);
+ }
+
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_HMETFR + 3,
+ ID_INFORM_DLEMEM_RDY);
+
+ counter = 10000;
+ while (HALMAC_REG_READ_8(halmac_adapter, REG_C2HEVT_3 + 3) !=
+ ID_INFORM_DLEMEM_RDY) {
+ counter--;
+ if (counter == 0) {
+ pr_err("[ERR]0x1AF != 0x80\n");
+ return HALMAC_RET_DLFW_FAIL;
+ }
+ usleep_range(50, 60);
+ }
+
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_C2HEVT_3 + 3, 0);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_pwr_seq_parser_88xx(struct halmac_adapter *halmac_adapter, u8 cut,
+ u8 fab, u8 intf,
+ struct halmac_wl_pwr_cfg_ **pp_pwr_seq_cfg)
+{
+ u32 seq_idx = 0;
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+ struct halmac_wl_pwr_cfg_ *seq_cmd;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ do {
+ seq_cmd = pp_pwr_seq_cfg[seq_idx];
+
+ if (!seq_cmd)
+ break;
+
+ status = halmac_pwr_sub_seq_parer_88xx(halmac_adapter, cut, fab,
+ intf, seq_cmd);
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("[Err]pwr sub seq parser fail, status = 0x%X!\n",
+ status);
+ return status;
+ }
+
+ seq_idx++;
+ } while (1);
+
+ return status;
+}
+
+static enum halmac_ret_status
+halmac_pwr_sub_seq_parer_do_cmd_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_wl_pwr_cfg_ *sub_seq_cmd,
+ bool *reti)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ u8 value, flag;
+ u8 polling_bit;
+ u32 polling_count;
+ static u32 poll_to_static;
+ u32 offset;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+ *reti = true;
+
+ switch (sub_seq_cmd->cmd) {
+ case HALMAC_PWR_CMD_WRITE:
+ if (sub_seq_cmd->base == HALMAC_PWR_BASEADDR_SDIO)
+ offset = sub_seq_cmd->offset | SDIO_LOCAL_OFFSET;
+ else
+ offset = sub_seq_cmd->offset;
+
+ value = HALMAC_REG_READ_8(halmac_adapter, offset);
+ value = (u8)(value & (u8)(~(sub_seq_cmd->msk)));
+ value = (u8)(value |
+ (u8)(sub_seq_cmd->value & sub_seq_cmd->msk));
+
+ HALMAC_REG_WRITE_8(halmac_adapter, offset, value);
+ break;
+ case HALMAC_PWR_CMD_POLLING:
+ polling_bit = 0;
+ polling_count = HALMAC_POLLING_READY_TIMEOUT_COUNT;
+ flag = 0;
+
+ if (sub_seq_cmd->base == HALMAC_PWR_BASEADDR_SDIO)
+ offset = sub_seq_cmd->offset | SDIO_LOCAL_OFFSET;
+ else
+ offset = sub_seq_cmd->offset;
+
+ do {
+ polling_count--;
+ value = HALMAC_REG_READ_8(halmac_adapter, offset);
+ value = (u8)(value & sub_seq_cmd->msk);
+
+ if (value == (sub_seq_cmd->value & sub_seq_cmd->msk)) {
+ polling_bit = 1;
+ continue;
+ }
+
+ if (polling_count != 0) {
+ usleep_range(50, 60);
+ continue;
+ }
+
+ if (halmac_adapter->halmac_interface ==
+ HALMAC_INTERFACE_PCIE &&
+ flag == 0) {
+ /* For PCIE + USB package poll power bit
+ * timeout issue
+ */
+ poll_to_static++;
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_PWR,
+ DBG_WARNING,
+ "[WARN]PCIE polling timeout : %d!!\n",
+ poll_to_static);
+ HALMAC_REG_WRITE_8(
+ halmac_adapter, REG_SYS_PW_CTRL,
+ HALMAC_REG_READ_8(halmac_adapter,
+ REG_SYS_PW_CTRL) |
+ BIT(3));
+ HALMAC_REG_WRITE_8(
+ halmac_adapter, REG_SYS_PW_CTRL,
+ HALMAC_REG_READ_8(halmac_adapter,
+ REG_SYS_PW_CTRL) &
+ ~BIT(3));
+ polling_bit = 0;
+ polling_count =
+ HALMAC_POLLING_READY_TIMEOUT_COUNT;
+ flag = 1;
+ } else {
+ pr_err("[ERR]Pwr cmd polling timeout!!\n");
+ pr_err("[ERR]Pwr cmd offset : %X!!\n",
+ sub_seq_cmd->offset);
+ pr_err("[ERR]Pwr cmd value : %X!!\n",
+ sub_seq_cmd->value);
+ pr_err("[ERR]Pwr cmd msk : %X!!\n",
+ sub_seq_cmd->msk);
+ pr_err("[ERR]Read offset = %X value = %X!!\n",
+ offset, value);
+ return HALMAC_RET_PWRSEQ_POLLING_FAIL;
+ }
+ } while (!polling_bit);
+ break;
+ case HALMAC_PWR_CMD_DELAY:
+ if (sub_seq_cmd->value == HALMAC_PWRSEQ_DELAY_US)
+ udelay(sub_seq_cmd->offset);
+ else
+ usleep_range(1000 * sub_seq_cmd->offset,
+ 1000 * sub_seq_cmd->offset + 100);
+
+ break;
+ case HALMAC_PWR_CMD_READ:
+ break;
+ case HALMAC_PWR_CMD_END:
+ return HALMAC_RET_SUCCESS;
+ default:
+ return HALMAC_RET_PWRSEQ_CMD_INCORRECT;
+ }
+
+ *reti = false;
+
+ return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+halmac_pwr_sub_seq_parer_88xx(struct halmac_adapter *halmac_adapter, u8 cut,
+ u8 fab, u8 intf,
+ struct halmac_wl_pwr_cfg_ *pwr_sub_seq_cfg)
+{
+ struct halmac_wl_pwr_cfg_ *sub_seq_cmd;
+ bool reti;
+ enum halmac_ret_status status;
+
+ for (sub_seq_cmd = pwr_sub_seq_cfg;; sub_seq_cmd++) {
+ if ((sub_seq_cmd->interface_msk & intf) &&
+ (sub_seq_cmd->fab_msk & fab) &&
+ (sub_seq_cmd->cut_msk & cut)) {
+ status = halmac_pwr_sub_seq_parer_do_cmd_88xx(
+ halmac_adapter, sub_seq_cmd, &reti);
+
+ if (reti)
+ return status;
+ }
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_get_h2c_buff_free_space_88xx(struct halmac_adapter *halmac_adapter)
+{
+ u32 hw_wptr, fw_rptr;
+ struct halmac_api *halmac_api =
+ (struct halmac_api *)halmac_adapter->halmac_api;
+
+ hw_wptr = HALMAC_REG_READ_32(halmac_adapter, REG_H2C_PKT_WRITEADDR) &
+ BIT_MASK_H2C_WR_ADDR;
+ fw_rptr = HALMAC_REG_READ_32(halmac_adapter, REG_H2C_PKT_READADDR) &
+ BIT_MASK_H2C_READ_ADDR;
+
+ if (hw_wptr >= fw_rptr)
+ halmac_adapter->h2c_buf_free_space =
+ halmac_adapter->h2c_buff_size - (hw_wptr - fw_rptr);
+ else
+ halmac_adapter->h2c_buf_free_space = fw_rptr - hw_wptr;
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_send_h2c_pkt_88xx(struct halmac_adapter *halmac_adapter, u8 *hal_h2c_cmd,
+ u32 size, bool ack)
+{
+ u32 counter = 100;
+ void *driver_adapter = halmac_adapter->driver_adapter;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ while (halmac_adapter->h2c_buf_free_space <=
+ HALMAC_H2C_CMD_SIZE_UNIT_88XX) {
+ halmac_get_h2c_buff_free_space_88xx(halmac_adapter);
+ counter--;
+ if (counter == 0) {
+ pr_err("h2c free space is not enough!!\n");
+ return HALMAC_RET_H2C_SPACE_FULL;
+ }
+ }
+
+ /* Send TxDesc + H2C_CMD */
+ if (!PLATFORM_SEND_H2C_PKT(driver_adapter, hal_h2c_cmd, size)) {
+ pr_err("Send H2C_CMD pkt error!!\n");
+ return HALMAC_RET_SEND_H2C_FAIL;
+ }
+
+ halmac_adapter->h2c_buf_free_space -= HALMAC_H2C_CMD_SIZE_UNIT_88XX;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "H2C free space : %d\n",
+ halmac_adapter->h2c_buf_free_space);
+
+ return status;
+}
+
+enum halmac_ret_status
+halmac_download_rsvd_page_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *hal_buf, u32 size)
+{
+ u8 restore[3];
+ u8 value8;
+ u32 counter;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ if (size == 0) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "Rsvd page packet size is zero!!\n");
+ return HALMAC_RET_ZERO_LEN_RSVD_PACKET;
+ }
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_FIFOPAGE_CTRL_2 + 1);
+ value8 = (u8)(value8 | BIT(7));
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_FIFOPAGE_CTRL_2 + 1, value8);
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_CR + 1);
+ restore[0] = value8;
+ value8 = (u8)(value8 | BIT(0));
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_CR + 1, value8);
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_BCN_CTRL);
+ restore[1] = value8;
+ value8 = (u8)((value8 & ~(BIT(3))) | BIT(4));
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_BCN_CTRL, value8);
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_FWHW_TXQ_CTRL + 2);
+ restore[2] = value8;
+ value8 = (u8)(value8 & ~(BIT(6)));
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_FWHW_TXQ_CTRL + 2, value8);
+
+ if (!PLATFORM_SEND_RSVD_PAGE(driver_adapter, hal_buf, size)) {
+ pr_err("PLATFORM_SEND_RSVD_PAGE 1 error!!\n");
+ status = HALMAC_RET_DL_RSVD_PAGE_FAIL;
+ }
+
+ /* Check Bcn_Valid_Bit */
+ counter = 1000;
+ while (!(HALMAC_REG_READ_8(halmac_adapter, REG_FIFOPAGE_CTRL_2 + 1) &
+ BIT(7))) {
+ udelay(10);
+ counter--;
+ if (counter == 0) {
+ pr_err("Polling Bcn_Valid_Fail error!!\n");
+ status = HALMAC_RET_POLLING_BCN_VALID_FAIL;
+ break;
+ }
+ }
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_FIFOPAGE_CTRL_2 + 1);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_FIFOPAGE_CTRL_2 + 1,
+ (value8 | BIT(7)));
+
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_FWHW_TXQ_CTRL + 2, restore[2]);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_BCN_CTRL, restore[1]);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_CR + 1, restore[0]);
+
+ return status;
+}
+
+enum halmac_ret_status
+halmac_set_h2c_header_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *hal_h2c_hdr, u16 *seq, bool ack)
+{
+ void *driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s!!\n", __func__);
+
+ H2C_CMD_HEADER_SET_CATEGORY(hal_h2c_hdr, 0x00);
+ H2C_CMD_HEADER_SET_TOTAL_LEN(hal_h2c_hdr, 16);
+
+ spin_lock(&halmac_adapter->h2c_seq_lock);
+ H2C_CMD_HEADER_SET_SEQ_NUM(hal_h2c_hdr, halmac_adapter->h2c_packet_seq);
+ *seq = halmac_adapter->h2c_packet_seq;
+ halmac_adapter->h2c_packet_seq++;
+ spin_unlock(&halmac_adapter->h2c_seq_lock);
+
+ if (ack)
+ H2C_CMD_HEADER_SET_ACK(hal_h2c_hdr, 1);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status halmac_set_fw_offload_h2c_header_88xx(
+ struct halmac_adapter *halmac_adapter, u8 *hal_h2c_hdr,
+ struct halmac_h2c_header_info *h2c_header_info, u16 *seq_num)
+{
+ void *driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s!!\n", __func__);
+
+ FW_OFFLOAD_H2C_SET_TOTAL_LEN(hal_h2c_hdr,
+ 8 + h2c_header_info->content_size);
+ FW_OFFLOAD_H2C_SET_SUB_CMD_ID(hal_h2c_hdr, h2c_header_info->sub_cmd_id);
+
+ FW_OFFLOAD_H2C_SET_CATEGORY(hal_h2c_hdr, 0x01);
+ FW_OFFLOAD_H2C_SET_CMD_ID(hal_h2c_hdr, 0xFF);
+
+ spin_lock(&halmac_adapter->h2c_seq_lock);
+ FW_OFFLOAD_H2C_SET_SEQ_NUM(hal_h2c_hdr, halmac_adapter->h2c_packet_seq);
+ *seq_num = halmac_adapter->h2c_packet_seq;
+ halmac_adapter->h2c_packet_seq++;
+ spin_unlock(&halmac_adapter->h2c_seq_lock);
+
+ if (h2c_header_info->ack)
+ FW_OFFLOAD_H2C_SET_ACK(hal_h2c_hdr, 1);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_send_h2c_set_pwr_mode_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_fwlps_option *hal_fw_lps_opt)
+{
+ u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX];
+ u8 *h2c_header, *h2c_cmd;
+ u16 seq = 0;
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s!!\n", __func__);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ h2c_header = h2c_buff;
+ h2c_cmd = h2c_header + HALMAC_H2C_CMD_HDR_SIZE_88XX;
+
+ memset(h2c_buff, 0x00, HALMAC_H2C_CMD_SIZE_88XX);
+
+ SET_PWR_MODE_SET_CMD_ID(h2c_cmd, CMD_ID_SET_PWR_MODE);
+ SET_PWR_MODE_SET_CLASS(h2c_cmd, CLASS_SET_PWR_MODE);
+ SET_PWR_MODE_SET_MODE(h2c_cmd, hal_fw_lps_opt->mode);
+ SET_PWR_MODE_SET_CLK_REQUEST(h2c_cmd, hal_fw_lps_opt->clk_request);
+ SET_PWR_MODE_SET_RLBM(h2c_cmd, hal_fw_lps_opt->rlbm);
+ SET_PWR_MODE_SET_SMART_PS(h2c_cmd, hal_fw_lps_opt->smart_ps);
+ SET_PWR_MODE_SET_AWAKE_INTERVAL(h2c_cmd,
+ hal_fw_lps_opt->awake_interval);
+ SET_PWR_MODE_SET_B_ALL_QUEUE_UAPSD(h2c_cmd,
+ hal_fw_lps_opt->all_queue_uapsd);
+ SET_PWR_MODE_SET_PWR_STATE(h2c_cmd, hal_fw_lps_opt->pwr_state);
+ SET_PWR_MODE_SET_ANT_AUTO_SWITCH(h2c_cmd,
+ hal_fw_lps_opt->ant_auto_switch);
+ SET_PWR_MODE_SET_PS_ALLOW_BT_HIGH_PRIORITY(
+ h2c_cmd, hal_fw_lps_opt->ps_allow_bt_high_priority);
+ SET_PWR_MODE_SET_PROTECT_BCN(h2c_cmd, hal_fw_lps_opt->protect_bcn);
+ SET_PWR_MODE_SET_SILENCE_PERIOD(h2c_cmd,
+ hal_fw_lps_opt->silence_period);
+ SET_PWR_MODE_SET_FAST_BT_CONNECT(h2c_cmd,
+ hal_fw_lps_opt->fast_bt_connect);
+ SET_PWR_MODE_SET_TWO_ANTENNA_EN(h2c_cmd,
+ hal_fw_lps_opt->two_antenna_en);
+ SET_PWR_MODE_SET_ADOPT_USER_SETTING(h2c_cmd,
+ hal_fw_lps_opt->adopt_user_setting);
+ SET_PWR_MODE_SET_DRV_BCN_EARLY_SHIFT(
+ h2c_cmd, hal_fw_lps_opt->drv_bcn_early_shift);
+
+ halmac_set_h2c_header_88xx(halmac_adapter, h2c_header, &seq, true);
+
+ status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
+ HALMAC_H2C_CMD_SIZE_88XX, true);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("%s Fail = %x!!\n", __func__, status);
+ return status;
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_func_send_original_h2c_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *original_h2c, u16 *seq, u8 ack)
+{
+ u8 H2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
+ u8 *h2c_header, *h2c_cmd;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "halmac_send_original_h2c ==========>\n");
+
+ h2c_header = H2c_buff;
+ h2c_cmd = h2c_header + HALMAC_H2C_CMD_HDR_SIZE_88XX;
+ memcpy(h2c_cmd, original_h2c, 8); /* Original H2C 8 byte */
+
+ halmac_set_h2c_header_88xx(halmac_adapter, h2c_header, seq, ack);
+
+ status = halmac_send_h2c_pkt_88xx(halmac_adapter, H2c_buff,
+ HALMAC_H2C_CMD_SIZE_88XX, ack);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_send_original_h2c Fail = %x!!\n", status);
+ return status;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "halmac_send_original_h2c <==========\n");
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_media_status_rpt_88xx(struct halmac_adapter *halmac_adapter, u8 op_mode,
+ u8 mac_id_ind, u8 mac_id, u8 mac_id_end)
+{
+ u8 H2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
+ u8 *h2c_header, *h2c_cmd;
+ u16 seq = 0;
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "halmac_send_h2c_set_pwr_mode_88xx!!\n");
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ h2c_header = H2c_buff;
+ h2c_cmd = h2c_header + HALMAC_H2C_CMD_HDR_SIZE_88XX;
+
+ memset(H2c_buff, 0x00, HALMAC_H2C_CMD_SIZE_88XX);
+
+ MEDIA_STATUS_RPT_SET_CMD_ID(h2c_cmd, CMD_ID_MEDIA_STATUS_RPT);
+ MEDIA_STATUS_RPT_SET_CLASS(h2c_cmd, CLASS_MEDIA_STATUS_RPT);
+ MEDIA_STATUS_RPT_SET_OP_MODE(h2c_cmd, op_mode);
+ MEDIA_STATUS_RPT_SET_MACID_IN(h2c_cmd, mac_id_ind);
+ MEDIA_STATUS_RPT_SET_MACID(h2c_cmd, mac_id);
+ MEDIA_STATUS_RPT_SET_MACID_END(h2c_cmd, mac_id_end);
+
+ halmac_set_h2c_header_88xx(halmac_adapter, h2c_header, &seq, true);
+
+ status = halmac_send_h2c_pkt_88xx(halmac_adapter, H2c_buff,
+ HALMAC_H2C_CMD_SIZE_88XX, true);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("%s Fail = %x!!\n", __func__, status);
+ return status;
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_send_h2c_update_packet_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_packet_id pkt_id, u8 *pkt,
+ u32 pkt_size)
+{
+ u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
+ u16 h2c_seq_mum = 0;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ struct halmac_h2c_header_info h2c_header_info;
+ enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
+ (u16)(halmac_adapter->txff_allocation
+ .rsvd_h2c_extra_info_pg_bndy &
+ BIT_MASK_BCN_HEAD_1_V1));
+
+ ret_status =
+ halmac_download_rsvd_page_88xx(halmac_adapter, pkt, pkt_size);
+
+ if (ret_status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_download_rsvd_page_88xx Fail = %x!!\n",
+ ret_status);
+ HALMAC_REG_WRITE_16(
+ halmac_adapter, REG_FIFOPAGE_CTRL_2,
+ (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
+ BIT_MASK_BCN_HEAD_1_V1));
+ return ret_status;
+ }
+
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
+ (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
+ BIT_MASK_BCN_HEAD_1_V1));
+
+ UPDATE_PACKET_SET_SIZE(
+ h2c_buff,
+ pkt_size + halmac_adapter->hw_config_info.txdesc_size);
+ UPDATE_PACKET_SET_PACKET_ID(h2c_buff, pkt_id);
+ UPDATE_PACKET_SET_PACKET_LOC(
+ h2c_buff,
+ halmac_adapter->txff_allocation.rsvd_h2c_extra_info_pg_bndy -
+ halmac_adapter->txff_allocation.rsvd_pg_bndy);
+
+ h2c_header_info.sub_cmd_id = SUB_CMD_ID_UPDATE_PACKET;
+ h2c_header_info.content_size = 8;
+ h2c_header_info.ack = true;
+ halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
+ &h2c_header_info, &h2c_seq_mum);
+ halmac_adapter->halmac_state.update_packet_set.seq_num = h2c_seq_mum;
+
+ ret_status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
+ HALMAC_H2C_CMD_SIZE_88XX, true);
+
+ if (ret_status != HALMAC_RET_SUCCESS) {
+ pr_err("%s Fail = %x!!\n", __func__, ret_status);
+ return ret_status;
+ }
+
+ return ret_status;
+}
+
+enum halmac_ret_status
+halmac_send_h2c_phy_parameter_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_phy_parameter_info *para_info,
+ bool full_fifo)
+{
+ bool drv_trigger_send = false;
+ u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
+ u16 h2c_seq_mum = 0;
+ u32 info_size = 0;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ struct halmac_h2c_header_info h2c_header_info;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+ struct halmac_config_para_info *config_para_info;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+ config_para_info = &halmac_adapter->config_para_info;
+
+ if (!config_para_info->cfg_para_buf) {
+ if (full_fifo)
+ config_para_info->para_buf_size =
+ HALMAC_EXTRA_INFO_BUFF_SIZE_FULL_FIFO_88XX;
+ else
+ config_para_info->para_buf_size =
+ HALMAC_EXTRA_INFO_BUFF_SIZE_88XX;
+
+ config_para_info->cfg_para_buf =
+ kzalloc(config_para_info->para_buf_size, GFP_KERNEL);
+
+ if (config_para_info->cfg_para_buf) {
+ memset(config_para_info->cfg_para_buf, 0x00,
+ config_para_info->para_buf_size);
+ config_para_info->full_fifo_mode = full_fifo;
+ config_para_info->para_buf_w =
+ config_para_info->cfg_para_buf;
+ config_para_info->para_num = 0;
+ config_para_info->avai_para_buf_size =
+ config_para_info->para_buf_size;
+ config_para_info->value_accumulation = 0;
+ config_para_info->offset_accumulation = 0;
+ } else {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C,
+ DBG_DMESG,
+ "Allocate cfg_para_buf fail!!\n");
+ return HALMAC_RET_MALLOC_FAIL;
+ }
+ }
+
+ if (halmac_transition_cfg_para_state_88xx(
+ halmac_adapter,
+ HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING) !=
+ HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ERROR_STATE;
+
+ halmac_enqueue_para_buff_88xx(halmac_adapter, para_info,
+ config_para_info->para_buf_w,
+ &drv_trigger_send);
+
+ if (para_info->cmd_id != HALMAC_PARAMETER_CMD_END) {
+ config_para_info->para_num++;
+ config_para_info->para_buf_w += HALMAC_FW_OFFLOAD_CMD_SIZE_88XX;
+ config_para_info->avai_para_buf_size =
+ config_para_info->avai_para_buf_size -
+ HALMAC_FW_OFFLOAD_CMD_SIZE_88XX;
+ }
+
+ if ((config_para_info->avai_para_buf_size -
+ halmac_adapter->hw_config_info.txdesc_size) >
+ HALMAC_FW_OFFLOAD_CMD_SIZE_88XX &&
+ !drv_trigger_send)
+ return HALMAC_RET_SUCCESS;
+
+ if (config_para_info->para_num == 0) {
+ kfree(config_para_info->cfg_para_buf);
+ config_para_info->cfg_para_buf = NULL;
+ config_para_info->para_buf_w = NULL;
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_WARNING,
+ "no cfg parameter element!!\n");
+
+ if (halmac_transition_cfg_para_state_88xx(
+ halmac_adapter,
+ HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE) !=
+ HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ERROR_STATE;
+
+ return HALMAC_RET_SUCCESS;
+ }
+
+ if (halmac_transition_cfg_para_state_88xx(
+ halmac_adapter, HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT) !=
+ HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ERROR_STATE;
+
+ halmac_adapter->halmac_state.cfg_para_state_set.process_status =
+ HALMAC_CMD_PROCESS_SENDING;
+
+ if (config_para_info->full_fifo_mode)
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2, 0);
+ else
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
+ (u16)(halmac_adapter->txff_allocation
+ .rsvd_h2c_extra_info_pg_bndy &
+ BIT_MASK_BCN_HEAD_1_V1));
+
+ info_size =
+ config_para_info->para_num * HALMAC_FW_OFFLOAD_CMD_SIZE_88XX;
+
+ status = halmac_download_rsvd_page_88xx(
+ halmac_adapter, (u8 *)config_para_info->cfg_para_buf,
+ info_size);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_download_rsvd_page_88xx Fail!!\n");
+ } else {
+ halmac_gen_cfg_para_h2c_88xx(halmac_adapter, h2c_buff);
+
+ h2c_header_info.sub_cmd_id = SUB_CMD_ID_CFG_PARAMETER;
+ h2c_header_info.content_size = 4;
+ h2c_header_info.ack = true;
+ halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
+ &h2c_header_info,
+ &h2c_seq_mum);
+
+ halmac_adapter->halmac_state.cfg_para_state_set.seq_num =
+ h2c_seq_mum;
+
+ status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
+ HALMAC_H2C_CMD_SIZE_88XX,
+ true);
+
+ if (status != HALMAC_RET_SUCCESS)
+ pr_err("halmac_send_h2c_pkt_88xx Fail!!\n");
+
+ HALMAC_RT_TRACE(
+ driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "config parameter time = %d\n",
+ HALMAC_REG_READ_32(halmac_adapter, REG_FW_DBG6));
+ }
+
+ kfree(config_para_info->cfg_para_buf);
+ config_para_info->cfg_para_buf = NULL;
+ config_para_info->para_buf_w = NULL;
+
+ /* Restore bcn head */
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
+ (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
+ BIT_MASK_BCN_HEAD_1_V1));
+
+ if (halmac_transition_cfg_para_state_88xx(
+ halmac_adapter, HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE) !=
+ HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ERROR_STATE;
+
+ if (!drv_trigger_send) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "Buffer full trigger sending H2C!!\n");
+ return HALMAC_RET_PARA_SENDING;
+ }
+
+ return status;
+}
+
+static enum halmac_ret_status
+halmac_enqueue_para_buff_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_phy_parameter_info *para_info,
+ u8 *curr_buff_wptr, bool *end_cmd)
+{
+ struct halmac_config_para_info *config_para_info =
+ &halmac_adapter->config_para_info;
+
+ *end_cmd = false;
+
+ PHY_PARAMETER_INFO_SET_LENGTH(curr_buff_wptr,
+ HALMAC_FW_OFFLOAD_CMD_SIZE_88XX);
+ PHY_PARAMETER_INFO_SET_IO_CMD(curr_buff_wptr, para_info->cmd_id);
+
+ switch (para_info->cmd_id) {
+ case HALMAC_PARAMETER_CMD_BB_W8:
+ case HALMAC_PARAMETER_CMD_BB_W16:
+ case HALMAC_PARAMETER_CMD_BB_W32:
+ case HALMAC_PARAMETER_CMD_MAC_W8:
+ case HALMAC_PARAMETER_CMD_MAC_W16:
+ case HALMAC_PARAMETER_CMD_MAC_W32:
+ PHY_PARAMETER_INFO_SET_IO_ADDR(
+ curr_buff_wptr, para_info->content.MAC_REG_W.offset);
+ PHY_PARAMETER_INFO_SET_DATA(curr_buff_wptr,
+ para_info->content.MAC_REG_W.value);
+ PHY_PARAMETER_INFO_SET_MASK(curr_buff_wptr,
+ para_info->content.MAC_REG_W.msk);
+ PHY_PARAMETER_INFO_SET_MSK_EN(
+ curr_buff_wptr, para_info->content.MAC_REG_W.msk_en);
+ config_para_info->value_accumulation +=
+ para_info->content.MAC_REG_W.value;
+ config_para_info->offset_accumulation +=
+ para_info->content.MAC_REG_W.offset;
+ break;
+ case HALMAC_PARAMETER_CMD_RF_W:
+ /*In rf register, the address is only 1 byte*/
+ PHY_PARAMETER_INFO_SET_RF_ADDR(
+ curr_buff_wptr, para_info->content.RF_REG_W.offset);
+ PHY_PARAMETER_INFO_SET_RF_PATH(
+ curr_buff_wptr, para_info->content.RF_REG_W.rf_path);
+ PHY_PARAMETER_INFO_SET_DATA(curr_buff_wptr,
+ para_info->content.RF_REG_W.value);
+ PHY_PARAMETER_INFO_SET_MASK(curr_buff_wptr,
+ para_info->content.RF_REG_W.msk);
+ PHY_PARAMETER_INFO_SET_MSK_EN(
+ curr_buff_wptr, para_info->content.RF_REG_W.msk_en);
+ config_para_info->value_accumulation +=
+ para_info->content.RF_REG_W.value;
+ config_para_info->offset_accumulation +=
+ (para_info->content.RF_REG_W.offset +
+ (para_info->content.RF_REG_W.rf_path << 8));
+ break;
+ case HALMAC_PARAMETER_CMD_DELAY_US:
+ case HALMAC_PARAMETER_CMD_DELAY_MS:
+ PHY_PARAMETER_INFO_SET_DELAY_VALUE(
+ curr_buff_wptr,
+ para_info->content.DELAY_TIME.delay_time);
+ break;
+ case HALMAC_PARAMETER_CMD_END:
+ *end_cmd = true;
+ break;
+ default:
+ pr_err(" halmac_send_h2c_phy_parameter_88xx illegal cmd_id!!\n");
+ break;
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+halmac_gen_cfg_para_h2c_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *h2c_buff)
+{
+ struct halmac_config_para_info *config_para_info =
+ &halmac_adapter->config_para_info;
+
+ CFG_PARAMETER_SET_NUM(h2c_buff, config_para_info->para_num);
+
+ if (config_para_info->full_fifo_mode) {
+ CFG_PARAMETER_SET_INIT_CASE(h2c_buff, 0x1);
+ CFG_PARAMETER_SET_PHY_PARAMETER_LOC(h2c_buff, 0);
+ } else {
+ CFG_PARAMETER_SET_INIT_CASE(h2c_buff, 0x0);
+ CFG_PARAMETER_SET_PHY_PARAMETER_LOC(
+ h2c_buff,
+ halmac_adapter->txff_allocation
+ .rsvd_h2c_extra_info_pg_bndy -
+ halmac_adapter->txff_allocation.rsvd_pg_bndy);
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_send_h2c_run_datapack_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_data_type halmac_data_type)
+{
+ u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
+ u16 h2c_seq_mum = 0;
+ void *driver_adapter = NULL;
+ struct halmac_h2c_header_info h2c_header_info;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s!!\n", __func__);
+
+ RUN_DATAPACK_SET_DATAPACK_ID(h2c_buff, halmac_data_type);
+
+ h2c_header_info.sub_cmd_id = SUB_CMD_ID_RUN_DATAPACK;
+ h2c_header_info.content_size = 4;
+ h2c_header_info.ack = true;
+ halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
+ &h2c_header_info, &h2c_seq_mum);
+
+ status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
+ HALMAC_H2C_CMD_SIZE_88XX, true);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
+ return status;
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_send_bt_coex_cmd_88xx(struct halmac_adapter *halmac_adapter, u8 *bt_buf,
+ u32 bt_size, u8 ack)
+{
+ u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
+ u16 h2c_seq_mum = 0;
+ void *driver_adapter = NULL;
+ struct halmac_h2c_header_info h2c_header_info;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s!!\n", __func__);
+
+ memcpy(h2c_buff + 8, bt_buf, bt_size);
+
+ h2c_header_info.sub_cmd_id = SUB_CMD_ID_BT_COEX;
+ h2c_header_info.content_size = (u16)bt_size;
+ h2c_header_info.ack = ack;
+ halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
+ &h2c_header_info, &h2c_seq_mum);
+
+ status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
+ HALMAC_H2C_CMD_SIZE_88XX, ack);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
+ return status;
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_func_ctrl_ch_switch_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_ch_switch_option *cs_option)
+{
+ u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
+ u16 h2c_seq_mum = 0;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ struct halmac_h2c_header_info h2c_header_info;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+ enum halmac_cmd_process_status *process_status =
+ &halmac_adapter->halmac_state.scan_state_set.process_status;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "halmac_ctrl_ch_switch!!\n");
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ if (halmac_transition_scan_state_88xx(
+ halmac_adapter, HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT) !=
+ HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ERROR_STATE;
+
+ *process_status = HALMAC_CMD_PROCESS_SENDING;
+
+ if (cs_option->switch_en != 0) {
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
+ (u16)(halmac_adapter->txff_allocation
+ .rsvd_h2c_extra_info_pg_bndy &
+ BIT_MASK_BCN_HEAD_1_V1));
+
+ status = halmac_download_rsvd_page_88xx(
+ halmac_adapter, halmac_adapter->ch_sw_info.ch_info_buf,
+ halmac_adapter->ch_sw_info.total_size);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_download_rsvd_page_88xx Fail = %x!!\n",
+ status);
+ HALMAC_REG_WRITE_16(
+ halmac_adapter, REG_FIFOPAGE_CTRL_2,
+ (u16)(halmac_adapter->txff_allocation
+ .rsvd_pg_bndy &
+ BIT_MASK_BCN_HEAD_1_V1));
+ return status;
+ }
+
+ HALMAC_REG_WRITE_16(
+ halmac_adapter, REG_FIFOPAGE_CTRL_2,
+ (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
+ BIT_MASK_BCN_HEAD_1_V1));
+ }
+
+ CHANNEL_SWITCH_SET_SWITCH_START(h2c_buff, cs_option->switch_en);
+ CHANNEL_SWITCH_SET_CHANNEL_NUM(h2c_buff,
+ halmac_adapter->ch_sw_info.ch_num);
+ CHANNEL_SWITCH_SET_CHANNEL_INFO_LOC(
+ h2c_buff,
+ halmac_adapter->txff_allocation.rsvd_h2c_extra_info_pg_bndy -
+ halmac_adapter->txff_allocation.rsvd_pg_bndy);
+ CHANNEL_SWITCH_SET_DEST_CH_EN(h2c_buff, cs_option->dest_ch_en);
+ CHANNEL_SWITCH_SET_DEST_CH(h2c_buff, cs_option->dest_ch);
+ CHANNEL_SWITCH_SET_PRI_CH_IDX(h2c_buff, cs_option->dest_pri_ch_idx);
+ CHANNEL_SWITCH_SET_ABSOLUTE_TIME(h2c_buff, cs_option->absolute_time_en);
+ CHANNEL_SWITCH_SET_TSF_LOW(h2c_buff, cs_option->tsf_low);
+ CHANNEL_SWITCH_SET_PERIODIC_OPTION(h2c_buff,
+ cs_option->periodic_option);
+ CHANNEL_SWITCH_SET_NORMAL_CYCLE(h2c_buff, cs_option->normal_cycle);
+ CHANNEL_SWITCH_SET_NORMAL_PERIOD(h2c_buff, cs_option->normal_period);
+ CHANNEL_SWITCH_SET_SLOW_PERIOD(h2c_buff, cs_option->phase_2_period);
+ CHANNEL_SWITCH_SET_CHANNEL_INFO_SIZE(
+ h2c_buff, halmac_adapter->ch_sw_info.total_size);
+
+ h2c_header_info.sub_cmd_id = SUB_CMD_ID_CHANNEL_SWITCH;
+ h2c_header_info.content_size = 20;
+ h2c_header_info.ack = true;
+ halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
+ &h2c_header_info, &h2c_seq_mum);
+ halmac_adapter->halmac_state.scan_state_set.seq_num = h2c_seq_mum;
+
+ status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
+ HALMAC_H2C_CMD_SIZE_88XX, true);
+
+ if (status != HALMAC_RET_SUCCESS)
+ pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
+
+ kfree(halmac_adapter->ch_sw_info.ch_info_buf);
+ halmac_adapter->ch_sw_info.ch_info_buf = NULL;
+ halmac_adapter->ch_sw_info.ch_info_buf_w = NULL;
+ halmac_adapter->ch_sw_info.extra_info_en = 0;
+ halmac_adapter->ch_sw_info.buf_size = 0;
+ halmac_adapter->ch_sw_info.avai_buf_size = 0;
+ halmac_adapter->ch_sw_info.total_size = 0;
+ halmac_adapter->ch_sw_info.ch_num = 0;
+
+ if (halmac_transition_scan_state_88xx(halmac_adapter,
+ HALMAC_SCAN_CMD_CONSTRUCT_IDLE) !=
+ HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ERROR_STATE;
+
+ return status;
+}
+
+enum halmac_ret_status
+halmac_func_send_general_info_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_general_info *general_info)
+{
+ u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
+ u16 h2c_seq_mum = 0;
+ void *driver_adapter = NULL;
+ struct halmac_h2c_header_info h2c_header_info;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "halmac_send_general_info!!\n");
+
+ GENERAL_INFO_SET_REF_TYPE(h2c_buff, general_info->rfe_type);
+ GENERAL_INFO_SET_RF_TYPE(h2c_buff, general_info->rf_type);
+ GENERAL_INFO_SET_FW_TX_BOUNDARY(
+ h2c_buff,
+ halmac_adapter->txff_allocation.rsvd_fw_txbuff_pg_bndy -
+ halmac_adapter->txff_allocation.rsvd_pg_bndy);
+
+ h2c_header_info.sub_cmd_id = SUB_CMD_ID_GENERAL_INFO;
+ h2c_header_info.content_size = 4;
+ h2c_header_info.ack = false;
+ halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
+ &h2c_header_info, &h2c_seq_mum);
+
+ status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
+ HALMAC_H2C_CMD_SIZE_88XX, true);
+
+ if (status != HALMAC_RET_SUCCESS)
+ pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
+
+ return status;
+}
+
+enum halmac_ret_status halmac_send_h2c_update_bcn_parse_info_88xx(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_bcn_ie_info *bcn_ie_info)
+{
+ u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
+ u16 h2c_seq_mum = 0;
+ void *driver_adapter = NULL;
+ struct halmac_h2c_header_info h2c_header_info;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s!!\n", __func__);
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ UPDATE_BEACON_PARSING_INFO_SET_FUNC_EN(h2c_buff, bcn_ie_info->func_en);
+ UPDATE_BEACON_PARSING_INFO_SET_SIZE_TH(h2c_buff, bcn_ie_info->size_th);
+ UPDATE_BEACON_PARSING_INFO_SET_TIMEOUT(h2c_buff, bcn_ie_info->timeout);
+
+ UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_0(
+ h2c_buff, (u32)(bcn_ie_info->ie_bmp[0]));
+ UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_1(
+ h2c_buff, (u32)(bcn_ie_info->ie_bmp[1]));
+ UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_2(
+ h2c_buff, (u32)(bcn_ie_info->ie_bmp[2]));
+ UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_3(
+ h2c_buff, (u32)(bcn_ie_info->ie_bmp[3]));
+ UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_4(
+ h2c_buff, (u32)(bcn_ie_info->ie_bmp[4]));
+
+ h2c_header_info.sub_cmd_id = SUB_CMD_ID_UPDATE_BEACON_PARSING_INFO;
+ h2c_header_info.content_size = 24;
+ h2c_header_info.ack = true;
+ halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
+ &h2c_header_info, &h2c_seq_mum);
+
+ status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
+ HALMAC_H2C_CMD_SIZE_88XX, true);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_send_h2c_pkt_88xx Fail =%x !!\n", status);
+ return status;
+ }
+
+ return status;
+}
+
+enum halmac_ret_status
+halmac_send_h2c_ps_tuning_para_88xx(struct halmac_adapter *halmac_adapter)
+{
+ u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
+ u8 *h2c_header, *h2c_cmd;
+ u16 seq = 0;
+ void *driver_adapter = NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "%s!!\n", __func__);
+
+ h2c_header = h2c_buff;
+ h2c_cmd = h2c_header + HALMAC_H2C_CMD_HDR_SIZE_88XX;
+
+ halmac_set_h2c_header_88xx(halmac_adapter, h2c_header, &seq, false);
+
+ status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
+ HALMAC_H2C_CMD_SIZE_88XX, false);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
+ return status;
+ }
+
+ return status;
+}
+
+enum halmac_ret_status
+halmac_parse_c2h_packet_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *halmac_buf, u32 halmac_size)
+{
+ u8 c2h_cmd, c2h_sub_cmd_id;
+ u8 *c2h_buf = halmac_buf + halmac_adapter->hw_config_info.rxdesc_size;
+ u32 c2h_size = halmac_size - halmac_adapter->hw_config_info.rxdesc_size;
+ void *driver_adapter = halmac_adapter->driver_adapter;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ c2h_cmd = (u8)C2H_HDR_GET_CMD_ID(c2h_buf);
+
+ /* FW offload C2H cmd is 0xFF */
+ if (c2h_cmd != 0xFF) {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "C2H_PKT not for FwOffloadC2HFormat!!\n");
+ return HALMAC_RET_C2H_NOT_HANDLED;
+ }
+
+ /* Get C2H sub cmd ID */
+ c2h_sub_cmd_id = (u8)C2H_HDR_GET_C2H_SUB_CMD_ID(c2h_buf);
+
+ switch (c2h_sub_cmd_id) {
+ case C2H_SUB_CMD_ID_C2H_DBG:
+ status = halmac_parse_c2h_debug_88xx(halmac_adapter, c2h_buf,
+ c2h_size);
+ break;
+ case C2H_SUB_CMD_ID_H2C_ACK_HDR:
+ status = halmac_parse_h2c_ack_88xx(halmac_adapter, c2h_buf,
+ c2h_size);
+ break;
+ case C2H_SUB_CMD_ID_BT_COEX_INFO:
+ status = HALMAC_RET_C2H_NOT_HANDLED;
+ break;
+ case C2H_SUB_CMD_ID_SCAN_STATUS_RPT:
+ status = halmac_parse_scan_status_rpt_88xx(halmac_adapter,
+ c2h_buf, c2h_size);
+ break;
+ case C2H_SUB_CMD_ID_PSD_DATA:
+ status = halmac_parse_psd_data_88xx(halmac_adapter, c2h_buf,
+ c2h_size);
+ break;
+
+ case C2H_SUB_CMD_ID_EFUSE_DATA:
+ status = halmac_parse_efuse_data_88xx(halmac_adapter, c2h_buf,
+ c2h_size);
+ break;
+ default:
+ pr_err("c2h_sub_cmd_id switch case out of boundary!!\n");
+ pr_err("[ERR]c2h pkt : %.8X %.8X!!\n", *(u32 *)c2h_buf,
+ *(u32 *)(c2h_buf + 4));
+ status = HALMAC_RET_C2H_NOT_HANDLED;
+ break;
+ }
+
+ return status;
+}
+
+static enum halmac_ret_status
+halmac_parse_c2h_debug_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
+ u32 c2h_size)
+{
+ void *driver_adapter = NULL;
+ u8 *c2h_buf_local = (u8 *)NULL;
+ u32 c2h_size_local = 0;
+ u8 dbg_content_length = 0;
+ u8 dbg_seq_num = 0;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ c2h_buf_local = c2h_buf;
+ c2h_size_local = c2h_size;
+
+ dbg_content_length = (u8)C2H_HDR_GET_LEN((u8 *)c2h_buf_local);
+
+ if (dbg_content_length > C2H_DBG_CONTENT_MAX_LENGTH)
+ return HALMAC_RET_SUCCESS;
+
+ *(c2h_buf_local + C2H_DBG_HEADER_LENGTH + dbg_content_length - 2) =
+ '\n';
+ dbg_seq_num = (u8)(*(c2h_buf_local + C2H_DBG_HEADER_LENGTH));
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "[RTKFW, SEQ=%d]: %s", dbg_seq_num,
+ (char *)(c2h_buf_local + C2H_DBG_HEADER_LENGTH + 1));
+
+ return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+halmac_parse_scan_status_rpt_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *c2h_buf, u32 c2h_size)
+{
+ u8 h2c_return_code;
+ void *driver_adapter = halmac_adapter->driver_adapter;
+ enum halmac_cmd_process_status process_status;
+
+ h2c_return_code = (u8)SCAN_STATUS_RPT_GET_H2C_RETURN_CODE(c2h_buf);
+ process_status = (enum halmac_h2c_return_code)h2c_return_code ==
+ HALMAC_H2C_RETURN_SUCCESS ?
+ HALMAC_CMD_PROCESS_DONE :
+ HALMAC_CMD_PROCESS_ERROR;
+
+ PLATFORM_EVENT_INDICATION(driver_adapter, HALMAC_FEATURE_CHANNEL_SWITCH,
+ process_status, NULL, 0);
+
+ halmac_adapter->halmac_state.scan_state_set.process_status =
+ process_status;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "[TRACE]scan status : %X\n", process_status);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+halmac_parse_psd_data_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
+ u32 c2h_size)
+{
+ u8 segment_id = 0, segment_size = 0, h2c_seq = 0;
+ u16 total_size;
+ void *driver_adapter = halmac_adapter->driver_adapter;
+ enum halmac_cmd_process_status process_status;
+ struct halmac_psd_state_set *psd_set =
+ &halmac_adapter->halmac_state.psd_set;
+
+ h2c_seq = (u8)PSD_DATA_GET_H2C_SEQ(c2h_buf);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
+ psd_set->seq_num, h2c_seq);
+ if (h2c_seq != psd_set->seq_num) {
+ pr_err("[ERR]Seq num mismatch : h2c -> %d c2h -> %d\n",
+ psd_set->seq_num, h2c_seq);
+ return HALMAC_RET_SUCCESS;
+ }
+
+ if (psd_set->process_status != HALMAC_CMD_PROCESS_SENDING) {
+ pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
+ return HALMAC_RET_SUCCESS;
+ }
+
+ total_size = (u16)PSD_DATA_GET_TOTAL_SIZE(c2h_buf);
+ segment_id = (u8)PSD_DATA_GET_SEGMENT_ID(c2h_buf);
+ segment_size = (u8)PSD_DATA_GET_SEGMENT_SIZE(c2h_buf);
+ psd_set->data_size = total_size;
+
+ if (!psd_set->data)
+ psd_set->data = kzalloc(psd_set->data_size, GFP_KERNEL);
+
+ if (segment_id == 0)
+ psd_set->segment_size = segment_size;
+
+ memcpy(psd_set->data + segment_id * psd_set->segment_size,
+ c2h_buf + HALMAC_C2H_DATA_OFFSET_88XX, segment_size);
+
+ if (!PSD_DATA_GET_END_SEGMENT(c2h_buf))
+ return HALMAC_RET_SUCCESS;
+
+ process_status = HALMAC_CMD_PROCESS_DONE;
+ psd_set->process_status = process_status;
+
+ PLATFORM_EVENT_INDICATION(driver_adapter, HALMAC_FEATURE_PSD,
+ process_status, psd_set->data,
+ psd_set->data_size);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+halmac_parse_efuse_data_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
+ u32 c2h_size)
+{
+ u8 segment_id = 0, segment_size = 0, h2c_seq = 0;
+ u8 *eeprom_map = NULL;
+ u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
+ u8 h2c_return_code = 0;
+ void *driver_adapter = halmac_adapter->driver_adapter;
+ enum halmac_cmd_process_status process_status;
+
+ h2c_seq = (u8)EFUSE_DATA_GET_H2C_SEQ(c2h_buf);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
+ halmac_adapter->halmac_state.efuse_state_set.seq_num,
+ h2c_seq);
+ if (h2c_seq != halmac_adapter->halmac_state.efuse_state_set.seq_num) {
+ pr_err("[ERR]Seq num mismatch : h2c -> %d c2h -> %d\n",
+ halmac_adapter->halmac_state.efuse_state_set.seq_num,
+ h2c_seq);
+ return HALMAC_RET_SUCCESS;
+ }
+
+ if (halmac_adapter->halmac_state.efuse_state_set.process_status !=
+ HALMAC_CMD_PROCESS_SENDING) {
+ pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
+ return HALMAC_RET_SUCCESS;
+ }
+
+ segment_id = (u8)EFUSE_DATA_GET_SEGMENT_ID(c2h_buf);
+ segment_size = (u8)EFUSE_DATA_GET_SEGMENT_SIZE(c2h_buf);
+ if (segment_id == 0)
+ halmac_adapter->efuse_segment_size = segment_size;
+
+ eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
+ if (!eeprom_map) {
+ /* out of memory */
+ return HALMAC_RET_MALLOC_FAIL;
+ }
+ memset(eeprom_map, 0xFF, eeprom_size);
+
+ spin_lock(&halmac_adapter->efuse_lock);
+ memcpy(halmac_adapter->hal_efuse_map +
+ segment_id * halmac_adapter->efuse_segment_size,
+ c2h_buf + HALMAC_C2H_DATA_OFFSET_88XX, segment_size);
+ spin_unlock(&halmac_adapter->efuse_lock);
+
+ if (!EFUSE_DATA_GET_END_SEGMENT(c2h_buf)) {
+ kfree(eeprom_map);
+ return HALMAC_RET_SUCCESS;
+ }
+
+ h2c_return_code =
+ halmac_adapter->halmac_state.efuse_state_set.fw_return_code;
+
+ if ((enum halmac_h2c_return_code)h2c_return_code ==
+ HALMAC_H2C_RETURN_SUCCESS) {
+ process_status = HALMAC_CMD_PROCESS_DONE;
+ halmac_adapter->halmac_state.efuse_state_set.process_status =
+ process_status;
+
+ spin_lock(&halmac_adapter->efuse_lock);
+ halmac_adapter->hal_efuse_map_valid = true;
+ spin_unlock(&halmac_adapter->efuse_lock);
+
+ if (halmac_adapter->event_trigger.physical_efuse_map == 1) {
+ PLATFORM_EVENT_INDICATION(
+ driver_adapter,
+ HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE,
+ process_status, halmac_adapter->hal_efuse_map,
+ halmac_adapter->hw_config_info.efuse_size);
+ halmac_adapter->event_trigger.physical_efuse_map = 0;
+ }
+
+ if (halmac_adapter->event_trigger.logical_efuse_map == 1) {
+ if (halmac_eeprom_parser_88xx(
+ halmac_adapter,
+ halmac_adapter->hal_efuse_map,
+ eeprom_map) != HALMAC_RET_SUCCESS) {
+ kfree(eeprom_map);
+ return HALMAC_RET_EEPROM_PARSING_FAIL;
+ }
+ PLATFORM_EVENT_INDICATION(
+ driver_adapter,
+ HALMAC_FEATURE_DUMP_LOGICAL_EFUSE,
+ process_status, eeprom_map, eeprom_size);
+ halmac_adapter->event_trigger.logical_efuse_map = 0;
+ }
+ } else {
+ process_status = HALMAC_CMD_PROCESS_ERROR;
+ halmac_adapter->halmac_state.efuse_state_set.process_status =
+ process_status;
+
+ if (halmac_adapter->event_trigger.physical_efuse_map == 1) {
+ PLATFORM_EVENT_INDICATION(
+ driver_adapter,
+ HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE,
+ process_status,
+ &halmac_adapter->halmac_state.efuse_state_set
+ .fw_return_code,
+ 1);
+ halmac_adapter->event_trigger.physical_efuse_map = 0;
+ }
+
+ if (halmac_adapter->event_trigger.logical_efuse_map == 1) {
+ if (halmac_eeprom_parser_88xx(
+ halmac_adapter,
+ halmac_adapter->hal_efuse_map,
+ eeprom_map) != HALMAC_RET_SUCCESS) {
+ kfree(eeprom_map);
+ return HALMAC_RET_EEPROM_PARSING_FAIL;
+ }
+ PLATFORM_EVENT_INDICATION(
+ driver_adapter,
+ HALMAC_FEATURE_DUMP_LOGICAL_EFUSE,
+ process_status,
+ &halmac_adapter->halmac_state.efuse_state_set
+ .fw_return_code,
+ 1);
+ halmac_adapter->event_trigger.logical_efuse_map = 0;
+ }
+ }
+
+ kfree(eeprom_map);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+halmac_parse_h2c_ack_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
+ u32 c2h_size)
+{
+ u8 h2c_cmd_id, h2c_sub_cmd_id;
+ u8 h2c_return_code;
+ void *driver_adapter = halmac_adapter->driver_adapter;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "Ack for C2H!!\n");
+
+ h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
+ if ((enum halmac_h2c_return_code)h2c_return_code !=
+ HALMAC_H2C_RETURN_SUCCESS)
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "C2H_PKT Status Error!! Status = %d\n",
+ h2c_return_code);
+
+ h2c_cmd_id = (u8)H2C_ACK_HDR_GET_H2C_CMD_ID(c2h_buf);
+
+ if (h2c_cmd_id != 0xFF) {
+ pr_err("original h2c ack is not handled!!\n");
+ status = HALMAC_RET_C2H_NOT_HANDLED;
+ } else {
+ h2c_sub_cmd_id = (u8)H2C_ACK_HDR_GET_H2C_SUB_CMD_ID(c2h_buf);
+
+ switch (h2c_sub_cmd_id) {
+ case H2C_SUB_CMD_ID_DUMP_PHYSICAL_EFUSE_ACK:
+ status = halmac_parse_h2c_ack_phy_efuse_88xx(
+ halmac_adapter, c2h_buf, c2h_size);
+ break;
+ case H2C_SUB_CMD_ID_CFG_PARAMETER_ACK:
+ status = halmac_parse_h2c_ack_cfg_para_88xx(
+ halmac_adapter, c2h_buf, c2h_size);
+ break;
+ case H2C_SUB_CMD_ID_UPDATE_PACKET_ACK:
+ status = halmac_parse_h2c_ack_update_packet_88xx(
+ halmac_adapter, c2h_buf, c2h_size);
+ break;
+ case H2C_SUB_CMD_ID_UPDATE_DATAPACK_ACK:
+ status = halmac_parse_h2c_ack_update_datapack_88xx(
+ halmac_adapter, c2h_buf, c2h_size);
+ break;
+ case H2C_SUB_CMD_ID_RUN_DATAPACK_ACK:
+ status = halmac_parse_h2c_ack_run_datapack_88xx(
+ halmac_adapter, c2h_buf, c2h_size);
+ break;
+ case H2C_SUB_CMD_ID_CHANNEL_SWITCH_ACK:
+ status = halmac_parse_h2c_ack_channel_switch_88xx(
+ halmac_adapter, c2h_buf, c2h_size);
+ break;
+ case H2C_SUB_CMD_ID_IQK_ACK:
+ status = halmac_parse_h2c_ack_iqk_88xx(
+ halmac_adapter, c2h_buf, c2h_size);
+ break;
+ case H2C_SUB_CMD_ID_POWER_TRACKING_ACK:
+ status = halmac_parse_h2c_ack_power_tracking_88xx(
+ halmac_adapter, c2h_buf, c2h_size);
+ break;
+ case H2C_SUB_CMD_ID_PSD_ACK:
+ break;
+ default:
+ pr_err("h2c_sub_cmd_id switch case out of boundary!!\n");
+ status = HALMAC_RET_C2H_NOT_HANDLED;
+ break;
+ }
+ }
+
+ return status;
+}
+
+static enum halmac_ret_status
+halmac_parse_h2c_ack_phy_efuse_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *c2h_buf, u32 c2h_size)
+{
+ u8 h2c_seq = 0;
+ u8 h2c_return_code;
+ void *driver_adapter = halmac_adapter->driver_adapter;
+
+ h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
+ halmac_adapter->halmac_state.efuse_state_set.seq_num,
+ h2c_seq);
+ if (h2c_seq != halmac_adapter->halmac_state.efuse_state_set.seq_num) {
+ pr_err("[ERR]Seq num mismatch : h2c -> %d c2h -> %d\n",
+ halmac_adapter->halmac_state.efuse_state_set.seq_num,
+ h2c_seq);
+ return HALMAC_RET_SUCCESS;
+ }
+
+ if (halmac_adapter->halmac_state.efuse_state_set.process_status !=
+ HALMAC_CMD_PROCESS_SENDING) {
+ pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
+ return HALMAC_RET_SUCCESS;
+ }
+
+ h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
+ halmac_adapter->halmac_state.efuse_state_set.fw_return_code =
+ h2c_return_code;
+
+ return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+halmac_parse_h2c_ack_cfg_para_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *c2h_buf, u32 c2h_size)
+{
+ u8 h2c_seq = 0;
+ u8 h2c_return_code;
+ u32 offset_accu = 0, value_accu = 0;
+ void *driver_adapter = halmac_adapter->driver_adapter;
+ enum halmac_cmd_process_status process_status =
+ HALMAC_CMD_PROCESS_UNDEFINE;
+
+ h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "Seq num : h2c -> %d c2h -> %d\n",
+ halmac_adapter->halmac_state.cfg_para_state_set.seq_num,
+ h2c_seq);
+ if (h2c_seq !=
+ halmac_adapter->halmac_state.cfg_para_state_set.seq_num) {
+ pr_err("Seq num mismatch : h2c -> %d c2h -> %d\n",
+ halmac_adapter->halmac_state.cfg_para_state_set.seq_num,
+ h2c_seq);
+ return HALMAC_RET_SUCCESS;
+ }
+
+ if (halmac_adapter->halmac_state.cfg_para_state_set.process_status !=
+ HALMAC_CMD_PROCESS_SENDING) {
+ pr_err("Not in HALMAC_CMD_PROCESS_SENDING\n");
+ return HALMAC_RET_SUCCESS;
+ }
+
+ h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
+ halmac_adapter->halmac_state.cfg_para_state_set.fw_return_code =
+ h2c_return_code;
+ offset_accu = CFG_PARAMETER_ACK_GET_OFFSET_ACCUMULATION(c2h_buf);
+ value_accu = CFG_PARAMETER_ACK_GET_VALUE_ACCUMULATION(c2h_buf);
+
+ if ((offset_accu !=
+ halmac_adapter->config_para_info.offset_accumulation) ||
+ (value_accu !=
+ halmac_adapter->config_para_info.value_accumulation)) {
+ pr_err("[C2H]offset_accu : %x, value_accu : %x!!\n",
+ offset_accu, value_accu);
+ pr_err("[Adapter]offset_accu : %x, value_accu : %x!!\n",
+ halmac_adapter->config_para_info.offset_accumulation,
+ halmac_adapter->config_para_info.value_accumulation);
+ process_status = HALMAC_CMD_PROCESS_ERROR;
+ }
+
+ if ((enum halmac_h2c_return_code)h2c_return_code ==
+ HALMAC_H2C_RETURN_SUCCESS &&
+ process_status != HALMAC_CMD_PROCESS_ERROR) {
+ process_status = HALMAC_CMD_PROCESS_DONE;
+ halmac_adapter->halmac_state.cfg_para_state_set.process_status =
+ process_status;
+ PLATFORM_EVENT_INDICATION(driver_adapter,
+ HALMAC_FEATURE_CFG_PARA,
+ process_status, NULL, 0);
+ } else {
+ process_status = HALMAC_CMD_PROCESS_ERROR;
+ halmac_adapter->halmac_state.cfg_para_state_set.process_status =
+ process_status;
+ PLATFORM_EVENT_INDICATION(
+ driver_adapter, HALMAC_FEATURE_CFG_PARA, process_status,
+ &halmac_adapter->halmac_state.cfg_para_state_set
+ .fw_return_code,
+ 1);
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+halmac_parse_h2c_ack_update_packet_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *c2h_buf, u32 c2h_size)
+{
+ u8 h2c_seq = 0;
+ u8 h2c_return_code;
+ void *driver_adapter = halmac_adapter->driver_adapter;
+ enum halmac_cmd_process_status process_status;
+
+ h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
+ halmac_adapter->halmac_state.update_packet_set.seq_num,
+ h2c_seq);
+ if (h2c_seq != halmac_adapter->halmac_state.update_packet_set.seq_num) {
+ pr_err("[ERR]Seq num mismatch : h2c -> %d c2h -> %d\n",
+ halmac_adapter->halmac_state.update_packet_set.seq_num,
+ h2c_seq);
+ return HALMAC_RET_SUCCESS;
+ }
+
+ if (halmac_adapter->halmac_state.update_packet_set.process_status !=
+ HALMAC_CMD_PROCESS_SENDING) {
+ pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
+ return HALMAC_RET_SUCCESS;
+ }
+
+ h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
+ halmac_adapter->halmac_state.update_packet_set.fw_return_code =
+ h2c_return_code;
+
+ if ((enum halmac_h2c_return_code)h2c_return_code ==
+ HALMAC_H2C_RETURN_SUCCESS) {
+ process_status = HALMAC_CMD_PROCESS_DONE;
+ halmac_adapter->halmac_state.update_packet_set.process_status =
+ process_status;
+ PLATFORM_EVENT_INDICATION(driver_adapter,
+ HALMAC_FEATURE_UPDATE_PACKET,
+ process_status, NULL, 0);
+ } else {
+ process_status = HALMAC_CMD_PROCESS_ERROR;
+ halmac_adapter->halmac_state.update_packet_set.process_status =
+ process_status;
+ PLATFORM_EVENT_INDICATION(
+ driver_adapter, HALMAC_FEATURE_UPDATE_PACKET,
+ process_status,
+ &halmac_adapter->halmac_state.update_packet_set
+ .fw_return_code,
+ 1);
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+halmac_parse_h2c_ack_update_datapack_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *c2h_buf, u32 c2h_size)
+{
+ void *driver_adapter = halmac_adapter->driver_adapter;
+ enum halmac_cmd_process_status process_status =
+ HALMAC_CMD_PROCESS_UNDEFINE;
+
+ PLATFORM_EVENT_INDICATION(driver_adapter,
+ HALMAC_FEATURE_UPDATE_DATAPACK,
+ process_status, NULL, 0);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+halmac_parse_h2c_ack_run_datapack_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *c2h_buf, u32 c2h_size)
+{
+ void *driver_adapter = halmac_adapter->driver_adapter;
+ enum halmac_cmd_process_status process_status =
+ HALMAC_CMD_PROCESS_UNDEFINE;
+
+ PLATFORM_EVENT_INDICATION(driver_adapter, HALMAC_FEATURE_RUN_DATAPACK,
+ process_status, NULL, 0);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+halmac_parse_h2c_ack_channel_switch_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *c2h_buf, u32 c2h_size)
+{
+ u8 h2c_seq = 0;
+ u8 h2c_return_code;
+ void *driver_adapter = halmac_adapter->driver_adapter;
+ enum halmac_cmd_process_status process_status;
+
+ h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
+ halmac_adapter->halmac_state.scan_state_set.seq_num,
+ h2c_seq);
+ if (h2c_seq != halmac_adapter->halmac_state.scan_state_set.seq_num) {
+ pr_err("[ERR]Seq num misactch : h2c -> %d c2h -> %d\n",
+ halmac_adapter->halmac_state.scan_state_set.seq_num,
+ h2c_seq);
+ return HALMAC_RET_SUCCESS;
+ }
+
+ if (halmac_adapter->halmac_state.scan_state_set.process_status !=
+ HALMAC_CMD_PROCESS_SENDING) {
+ pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
+ return HALMAC_RET_SUCCESS;
+ }
+
+ h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
+ halmac_adapter->halmac_state.scan_state_set.fw_return_code =
+ h2c_return_code;
+
+ if ((enum halmac_h2c_return_code)h2c_return_code ==
+ HALMAC_H2C_RETURN_SUCCESS) {
+ process_status = HALMAC_CMD_PROCESS_RCVD;
+ halmac_adapter->halmac_state.scan_state_set.process_status =
+ process_status;
+ PLATFORM_EVENT_INDICATION(driver_adapter,
+ HALMAC_FEATURE_CHANNEL_SWITCH,
+ process_status, NULL, 0);
+ } else {
+ process_status = HALMAC_CMD_PROCESS_ERROR;
+ halmac_adapter->halmac_state.scan_state_set.process_status =
+ process_status;
+ PLATFORM_EVENT_INDICATION(
+ driver_adapter, HALMAC_FEATURE_CHANNEL_SWITCH,
+ process_status, &halmac_adapter->halmac_state
+ .scan_state_set.fw_return_code,
+ 1);
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+halmac_parse_h2c_ack_iqk_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *c2h_buf, u32 c2h_size)
+{
+ u8 h2c_seq = 0;
+ u8 h2c_return_code;
+ void *driver_adapter = halmac_adapter->driver_adapter;
+ enum halmac_cmd_process_status process_status;
+
+ h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
+ halmac_adapter->halmac_state.iqk_set.seq_num, h2c_seq);
+ if (h2c_seq != halmac_adapter->halmac_state.iqk_set.seq_num) {
+ pr_err("[ERR]Seq num misactch : h2c -> %d c2h -> %d\n",
+ halmac_adapter->halmac_state.iqk_set.seq_num, h2c_seq);
+ return HALMAC_RET_SUCCESS;
+ }
+
+ if (halmac_adapter->halmac_state.iqk_set.process_status !=
+ HALMAC_CMD_PROCESS_SENDING) {
+ pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
+ return HALMAC_RET_SUCCESS;
+ }
+
+ h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
+ halmac_adapter->halmac_state.iqk_set.fw_return_code = h2c_return_code;
+
+ if ((enum halmac_h2c_return_code)h2c_return_code ==
+ HALMAC_H2C_RETURN_SUCCESS) {
+ process_status = HALMAC_CMD_PROCESS_DONE;
+ halmac_adapter->halmac_state.iqk_set.process_status =
+ process_status;
+ PLATFORM_EVENT_INDICATION(driver_adapter, HALMAC_FEATURE_IQK,
+ process_status, NULL, 0);
+ } else {
+ process_status = HALMAC_CMD_PROCESS_ERROR;
+ halmac_adapter->halmac_state.iqk_set.process_status =
+ process_status;
+ PLATFORM_EVENT_INDICATION(
+ driver_adapter, HALMAC_FEATURE_IQK, process_status,
+ &halmac_adapter->halmac_state.iqk_set.fw_return_code,
+ 1);
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+halmac_parse_h2c_ack_power_tracking_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *c2h_buf, u32 c2h_size)
+{
+ u8 h2c_seq = 0;
+ u8 h2c_return_code;
+ void *driver_adapter = halmac_adapter->driver_adapter;
+ enum halmac_cmd_process_status process_status;
+
+ h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
+ "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
+ halmac_adapter->halmac_state.power_tracking_set.seq_num,
+ h2c_seq);
+ if (h2c_seq !=
+ halmac_adapter->halmac_state.power_tracking_set.seq_num) {
+ pr_err("[ERR]Seq num mismatch : h2c -> %d c2h -> %d\n",
+ halmac_adapter->halmac_state.power_tracking_set.seq_num,
+ h2c_seq);
+ return HALMAC_RET_SUCCESS;
+ }
+
+ if (halmac_adapter->halmac_state.power_tracking_set.process_status !=
+ HALMAC_CMD_PROCESS_SENDING) {
+ pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
+ return HALMAC_RET_SUCCESS;
+ }
+
+ h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
+ halmac_adapter->halmac_state.power_tracking_set.fw_return_code =
+ h2c_return_code;
+
+ if ((enum halmac_h2c_return_code)h2c_return_code ==
+ HALMAC_H2C_RETURN_SUCCESS) {
+ process_status = HALMAC_CMD_PROCESS_DONE;
+ halmac_adapter->halmac_state.power_tracking_set.process_status =
+ process_status;
+ PLATFORM_EVENT_INDICATION(driver_adapter,
+ HALMAC_FEATURE_POWER_TRACKING,
+ process_status, NULL, 0);
+ } else {
+ process_status = HALMAC_CMD_PROCESS_ERROR;
+ halmac_adapter->halmac_state.power_tracking_set.process_status =
+ process_status;
+ PLATFORM_EVENT_INDICATION(
+ driver_adapter, HALMAC_FEATURE_POWER_TRACKING,
+ process_status,
+ &halmac_adapter->halmac_state.power_tracking_set
+ .fw_return_code,
+ 1);
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_convert_to_sdio_bus_offset_88xx(struct halmac_adapter *halmac_adapter,
+ u32 *halmac_offset)
+{
+ void *driver_adapter = NULL;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ switch ((*halmac_offset) & 0xFFFF0000) {
+ case WLAN_IOREG_OFFSET:
+ *halmac_offset = (HALMAC_SDIO_CMD_ADDR_MAC_REG << 13) |
+ (*halmac_offset & HALMAC_WLAN_MAC_REG_MSK);
+ break;
+ case SDIO_LOCAL_OFFSET:
+ *halmac_offset = (HALMAC_SDIO_CMD_ADDR_SDIO_REG << 13) |
+ (*halmac_offset & HALMAC_SDIO_LOCAL_MSK);
+ break;
+ default:
+ *halmac_offset = 0xFFFFFFFF;
+ pr_err("Unknown base address!!\n");
+ return HALMAC_RET_CONVERT_SDIO_OFFSET_FAIL;
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_update_sdio_free_page_88xx(struct halmac_adapter *halmac_adapter)
+{
+ u32 free_page = 0, free_page2 = 0, free_page3 = 0;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ struct halmac_sdio_free_space *sdio_free_space;
+ u8 data[12] = {0};
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ sdio_free_space = &halmac_adapter->sdio_free_space;
+ /*need to use HALMAC_REG_READ_N, 20160316, Soar*/
+ HALMAC_REG_SDIO_CMD53_READ_N(halmac_adapter, REG_SDIO_FREE_TXPG, 12,
+ data);
+ free_page =
+ data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
+ free_page2 =
+ data[4] | (data[5] << 8) | (data[6] << 16) | (data[7] << 24);
+ free_page3 =
+ data[8] | (data[9] << 8) | (data[10] << 16) | (data[11] << 24);
+
+ sdio_free_space->high_queue_number =
+ (u16)BIT_GET_HIQ_FREEPG_V1(free_page);
+ sdio_free_space->normal_queue_number =
+ (u16)BIT_GET_MID_FREEPG_V1(free_page);
+ sdio_free_space->low_queue_number =
+ (u16)BIT_GET_LOW_FREEPG_V1(free_page2);
+ sdio_free_space->public_queue_number =
+ (u16)BIT_GET_PUB_FREEPG_V1(free_page2);
+ sdio_free_space->extra_queue_number =
+ (u16)BIT_GET_EXQ_FREEPG_V1(free_page3);
+ sdio_free_space->ac_oqt_number = (u8)((free_page3 >> 16) & 0xFF);
+ sdio_free_space->non_ac_oqt_number = (u8)((free_page3 >> 24) & 0xFF);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_update_oqt_free_space_88xx(struct halmac_adapter *halmac_adapter)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ struct halmac_sdio_free_space *sdio_free_space;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ sdio_free_space = &halmac_adapter->sdio_free_space;
+
+ sdio_free_space->ac_oqt_number = HALMAC_REG_READ_8(
+ halmac_adapter, REG_SDIO_OQT_FREE_TXPG_V1 + 2);
+ sdio_free_space->ac_empty =
+ HALMAC_REG_READ_8(halmac_adapter, REG_TXPKT_EMPTY);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s <==========\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_efuse_cmd_construct_state
+halmac_query_efuse_curr_state_88xx(struct halmac_adapter *halmac_adapter)
+{
+ return halmac_adapter->halmac_state.efuse_state_set
+ .efuse_cmd_construct_state;
+}
+
+enum halmac_ret_status halmac_transition_efuse_state_88xx(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_efuse_cmd_construct_state dest_state)
+{
+ struct halmac_efuse_state_set *efuse_state =
+ &halmac_adapter->halmac_state.efuse_state_set;
+
+ if (efuse_state->efuse_cmd_construct_state !=
+ HALMAC_EFUSE_CMD_CONSTRUCT_IDLE &&
+ efuse_state->efuse_cmd_construct_state !=
+ HALMAC_EFUSE_CMD_CONSTRUCT_BUSY &&
+ efuse_state->efuse_cmd_construct_state !=
+ HALMAC_EFUSE_CMD_CONSTRUCT_H2C_SENT)
+ return HALMAC_RET_ERROR_STATE;
+
+ if (efuse_state->efuse_cmd_construct_state == dest_state)
+ return HALMAC_RET_ERROR_STATE;
+
+ if (dest_state == HALMAC_EFUSE_CMD_CONSTRUCT_BUSY) {
+ if (efuse_state->efuse_cmd_construct_state ==
+ HALMAC_EFUSE_CMD_CONSTRUCT_H2C_SENT)
+ return HALMAC_RET_ERROR_STATE;
+ } else if (dest_state == HALMAC_EFUSE_CMD_CONSTRUCT_H2C_SENT) {
+ if (efuse_state->efuse_cmd_construct_state ==
+ HALMAC_EFUSE_CMD_CONSTRUCT_IDLE)
+ return HALMAC_RET_ERROR_STATE;
+ }
+
+ efuse_state->efuse_cmd_construct_state = dest_state;
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_cfg_para_cmd_construct_state
+halmac_query_cfg_para_curr_state_88xx(struct halmac_adapter *halmac_adapter)
+{
+ return halmac_adapter->halmac_state.cfg_para_state_set
+ .cfg_para_cmd_construct_state;
+}
+
+enum halmac_ret_status halmac_transition_cfg_para_state_88xx(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_cfg_para_cmd_construct_state dest_state)
+{
+ struct halmac_cfg_para_state_set *cfg_para =
+ &halmac_adapter->halmac_state.cfg_para_state_set;
+
+ if (cfg_para->cfg_para_cmd_construct_state !=
+ HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE &&
+ cfg_para->cfg_para_cmd_construct_state !=
+ HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING &&
+ cfg_para->cfg_para_cmd_construct_state !=
+ HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT)
+ return HALMAC_RET_ERROR_STATE;
+
+ if (dest_state == HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE) {
+ if (cfg_para->cfg_para_cmd_construct_state ==
+ HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING)
+ return HALMAC_RET_ERROR_STATE;
+ } else if (dest_state == HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING) {
+ if (cfg_para->cfg_para_cmd_construct_state ==
+ HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT)
+ return HALMAC_RET_ERROR_STATE;
+ } else if (dest_state == HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT) {
+ if (cfg_para->cfg_para_cmd_construct_state ==
+ HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE ||
+ cfg_para->cfg_para_cmd_construct_state ==
+ HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT)
+ return HALMAC_RET_ERROR_STATE;
+ }
+
+ cfg_para->cfg_para_cmd_construct_state = dest_state;
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_scan_cmd_construct_state
+halmac_query_scan_curr_state_88xx(struct halmac_adapter *halmac_adapter)
+{
+ return halmac_adapter->halmac_state.scan_state_set
+ .scan_cmd_construct_state;
+}
+
+enum halmac_ret_status halmac_transition_scan_state_88xx(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_scan_cmd_construct_state dest_state)
+{
+ struct halmac_scan_state_set *scan =
+ &halmac_adapter->halmac_state.scan_state_set;
+
+ if (scan->scan_cmd_construct_state > HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT)
+ return HALMAC_RET_ERROR_STATE;
+
+ if (dest_state == HALMAC_SCAN_CMD_CONSTRUCT_IDLE) {
+ if (scan->scan_cmd_construct_state ==
+ HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED ||
+ scan->scan_cmd_construct_state ==
+ HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING)
+ return HALMAC_RET_ERROR_STATE;
+ } else if (dest_state == HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED) {
+ if (scan->scan_cmd_construct_state ==
+ HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT)
+ return HALMAC_RET_ERROR_STATE;
+ } else if (dest_state == HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING) {
+ if (scan->scan_cmd_construct_state ==
+ HALMAC_SCAN_CMD_CONSTRUCT_IDLE ||
+ scan->scan_cmd_construct_state ==
+ HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT)
+ return HALMAC_RET_ERROR_STATE;
+ } else if (dest_state == HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT) {
+ if (scan->scan_cmd_construct_state !=
+ HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING &&
+ scan->scan_cmd_construct_state !=
+ HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED)
+ return HALMAC_RET_ERROR_STATE;
+ }
+
+ scan->scan_cmd_construct_state = dest_state;
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status halmac_query_cfg_para_status_88xx(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
+{
+ struct halmac_cfg_para_state_set *cfg_para_state_set =
+ &halmac_adapter->halmac_state.cfg_para_state_set;
+
+ *process_status = cfg_para_state_set->process_status;
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status halmac_query_dump_physical_efuse_status_88xx(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
+{
+ void *driver_adapter = NULL;
+ struct halmac_efuse_state_set *efuse_state_set =
+ &halmac_adapter->halmac_state.efuse_state_set;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ *process_status = efuse_state_set->process_status;
+
+ if (!data)
+ return HALMAC_RET_NULL_POINTER;
+
+ if (!size)
+ return HALMAC_RET_NULL_POINTER;
+
+ if (*process_status == HALMAC_CMD_PROCESS_DONE) {
+ if (*size < halmac_adapter->hw_config_info.efuse_size) {
+ *size = halmac_adapter->hw_config_info.efuse_size;
+ return HALMAC_RET_BUFFER_TOO_SMALL;
+ }
+
+ *size = halmac_adapter->hw_config_info.efuse_size;
+ memcpy(data, halmac_adapter->hal_efuse_map, *size);
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status halmac_query_dump_logical_efuse_status_88xx(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
+{
+ u8 *eeprom_map = NULL;
+ u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
+ void *driver_adapter = NULL;
+ struct halmac_efuse_state_set *efuse_state_set =
+ &halmac_adapter->halmac_state.efuse_state_set;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ *process_status = efuse_state_set->process_status;
+
+ if (!data)
+ return HALMAC_RET_NULL_POINTER;
+
+ if (!size)
+ return HALMAC_RET_NULL_POINTER;
+
+ if (*process_status == HALMAC_CMD_PROCESS_DONE) {
+ if (*size < eeprom_size) {
+ *size = eeprom_size;
+ return HALMAC_RET_BUFFER_TOO_SMALL;
+ }
+
+ *size = eeprom_size;
+
+ eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
+ if (!eeprom_map) {
+ /* out of memory */
+ return HALMAC_RET_MALLOC_FAIL;
+ }
+ memset(eeprom_map, 0xFF, eeprom_size);
+
+ if (halmac_eeprom_parser_88xx(
+ halmac_adapter, halmac_adapter->hal_efuse_map,
+ eeprom_map) != HALMAC_RET_SUCCESS) {
+ kfree(eeprom_map);
+ return HALMAC_RET_EEPROM_PARSING_FAIL;
+ }
+
+ memcpy(data, eeprom_map, *size);
+
+ kfree(eeprom_map);
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status halmac_query_channel_switch_status_88xx(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
+{
+ struct halmac_scan_state_set *scan_state_set =
+ &halmac_adapter->halmac_state.scan_state_set;
+
+ *process_status = scan_state_set->process_status;
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status halmac_query_update_packet_status_88xx(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
+{
+ struct halmac_update_packet_state_set *update_packet_set =
+ &halmac_adapter->halmac_state.update_packet_set;
+
+ *process_status = update_packet_set->process_status;
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_query_iqk_status_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_cmd_process_status *process_status,
+ u8 *data, u32 *size)
+{
+ struct halmac_iqk_state_set *iqk_set =
+ &halmac_adapter->halmac_state.iqk_set;
+
+ *process_status = iqk_set->process_status;
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status halmac_query_power_tracking_status_88xx(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
+{
+ struct halmac_power_tracking_state_set *power_tracking_state_set =
+ &halmac_adapter->halmac_state.power_tracking_set;
+ ;
+
+ *process_status = power_tracking_state_set->process_status;
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_query_psd_status_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_cmd_process_status *process_status,
+ u8 *data, u32 *size)
+{
+ void *driver_adapter = NULL;
+ struct halmac_psd_state_set *psd_set =
+ &halmac_adapter->halmac_state.psd_set;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ *process_status = psd_set->process_status;
+
+ if (!data)
+ return HALMAC_RET_NULL_POINTER;
+
+ if (!size)
+ return HALMAC_RET_NULL_POINTER;
+
+ if (*process_status == HALMAC_CMD_PROCESS_DONE) {
+ if (*size < psd_set->data_size) {
+ *size = psd_set->data_size;
+ return HALMAC_RET_BUFFER_TOO_SMALL;
+ }
+
+ *size = psd_set->data_size;
+ memcpy(data, psd_set->data, *size);
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_verify_io_88xx(struct halmac_adapter *halmac_adapter)
+{
+ u8 value8, wvalue8;
+ u32 value32, value32_2, wvalue32;
+ u32 halmac_offset;
+ void *driver_adapter = NULL;
+ enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
+ halmac_offset = REG_PAGE5_DUMMY;
+ if ((halmac_offset & 0xFFFF0000) == 0)
+ halmac_offset |= WLAN_IOREG_OFFSET;
+
+ ret_status = halmac_convert_to_sdio_bus_offset_88xx(
+ halmac_adapter, &halmac_offset);
+
+ /* Verify CMD52 R/W */
+ wvalue8 = 0xab;
+ PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset,
+ wvalue8);
+
+ value8 =
+ PLATFORM_SDIO_CMD52_READ(driver_adapter, halmac_offset);
+
+ if (value8 != wvalue8) {
+ pr_err("cmd52 r/w fail write = %X read = %X\n", wvalue8,
+ value8);
+ ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
+ } else {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
+ DBG_DMESG, "cmd52 r/w ok\n");
+ }
+
+ /* Verify CMD53 R/W */
+ PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset, 0xaa);
+ PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset + 1,
+ 0xbb);
+ PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset + 2,
+ 0xcc);
+ PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset + 3,
+ 0xdd);
+
+ value32 = PLATFORM_SDIO_CMD53_READ_32(driver_adapter,
+ halmac_offset);
+
+ if (value32 != 0xddccbbaa) {
+ pr_err("cmd53 r fail : read = %X\n", value32);
+ ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
+ } else {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
+ DBG_DMESG, "cmd53 r ok\n");
+ }
+
+ wvalue32 = 0x11223344;
+ PLATFORM_SDIO_CMD53_WRITE_32(driver_adapter, halmac_offset,
+ wvalue32);
+
+ value32 = PLATFORM_SDIO_CMD53_READ_32(driver_adapter,
+ halmac_offset);
+
+ if (value32 != wvalue32) {
+ pr_err("cmd53 w fail\n");
+ ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
+ } else {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
+ DBG_DMESG, "cmd53 w ok\n");
+ }
+
+ value32 = PLATFORM_SDIO_CMD53_READ_32(
+ driver_adapter,
+ halmac_offset + 2); /* value32 should be 0x33441122 */
+
+ wvalue32 = 0x11225566;
+ PLATFORM_SDIO_CMD53_WRITE_32(driver_adapter, halmac_offset,
+ wvalue32);
+
+ value32_2 = PLATFORM_SDIO_CMD53_READ_32(
+ driver_adapter,
+ halmac_offset + 2); /* value32 should be 0x55661122 */
+ if (value32_2 == value32) {
+ pr_err("cmd52 is used for HAL_SDIO_CMD53_READ_32\n");
+ ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
+ } else {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
+ DBG_DMESG, "cmd53 is correctly used\n");
+ }
+ } else {
+ wvalue32 = 0x77665511;
+ PLATFORM_REG_WRITE_32(driver_adapter, REG_PAGE5_DUMMY,
+ wvalue32);
+
+ value32 = PLATFORM_REG_READ_32(driver_adapter, REG_PAGE5_DUMMY);
+ if (value32 != wvalue32) {
+ pr_err("reg rw\n");
+ ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
+ } else {
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
+ DBG_DMESG, "reg rw ok\n");
+ }
+ }
+
+ return ret_status;
+}
+
+enum halmac_ret_status
+halmac_verify_send_rsvd_page_88xx(struct halmac_adapter *halmac_adapter)
+{
+ u8 *rsvd_buf = NULL;
+ u8 *rsvd_page = NULL;
+ u32 i;
+ u32 h2c_pkt_verify_size = 64, h2c_pkt_verify_payload = 0xab;
+ void *driver_adapter = NULL;
+ enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ rsvd_buf = kzalloc(h2c_pkt_verify_size, GFP_KERNEL);
+
+ if (!rsvd_buf) {
+ /*pr_err("[ERR]rsvd buffer malloc fail!!\n");*/
+ return HALMAC_RET_MALLOC_FAIL;
+ }
+
+ memset(rsvd_buf, (u8)h2c_pkt_verify_payload, h2c_pkt_verify_size);
+
+ ret_status = halmac_download_rsvd_page_88xx(halmac_adapter, rsvd_buf,
+ h2c_pkt_verify_size);
+
+ if (ret_status != HALMAC_RET_SUCCESS) {
+ kfree(rsvd_buf);
+ return ret_status;
+ }
+
+ rsvd_page = kzalloc(h2c_pkt_verify_size +
+ halmac_adapter->hw_config_info.txdesc_size,
+ GFP_KERNEL);
+
+ if (!rsvd_page) {
+ pr_err("[ERR]rsvd page malloc fail!!\n");
+ kfree(rsvd_buf);
+ return HALMAC_RET_MALLOC_FAIL;
+ }
+
+ ret_status = halmac_dump_fifo_88xx(
+ halmac_adapter, HAL_FIFO_SEL_RSVD_PAGE, 0,
+ h2c_pkt_verify_size +
+ halmac_adapter->hw_config_info.txdesc_size,
+ rsvd_page);
+
+ if (ret_status != HALMAC_RET_SUCCESS) {
+ kfree(rsvd_buf);
+ kfree(rsvd_page);
+ return ret_status;
+ }
+
+ for (i = 0; i < h2c_pkt_verify_size; i++) {
+ if (*(rsvd_buf + i) !=
+ *(rsvd_page +
+ (i + halmac_adapter->hw_config_info.txdesc_size))) {
+ pr_err("[ERR]Compare RSVD page Fail\n");
+ ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
+ }
+ }
+
+ kfree(rsvd_buf);
+ kfree(rsvd_page);
+
+ return ret_status;
+}
+
+void halmac_power_save_cb_88xx(void *cb_data)
+{
+ void *driver_adapter = NULL;
+ struct halmac_adapter *halmac_adapter = (struct halmac_adapter *)NULL;
+
+ halmac_adapter = (struct halmac_adapter *)cb_data;
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
+ "%s\n", __func__);
+}
+
+enum halmac_ret_status
+halmac_buffer_read_88xx(struct halmac_adapter *halmac_adapter, u32 offset,
+ u32 size, enum hal_fifo_sel halmac_fifo_sel,
+ u8 *fifo_map)
+{
+ u32 start_page, value_read;
+ u32 i, counter = 0, residue;
+ struct halmac_api *halmac_api;
+
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ if (halmac_fifo_sel == HAL_FIFO_SEL_RSVD_PAGE)
+ offset = offset +
+ (halmac_adapter->txff_allocation.rsvd_pg_bndy << 7);
+
+ start_page = offset >> 12;
+ residue = offset & (4096 - 1);
+
+ if (halmac_fifo_sel == HAL_FIFO_SEL_TX ||
+ halmac_fifo_sel == HAL_FIFO_SEL_RSVD_PAGE)
+ start_page += 0x780;
+ else if (halmac_fifo_sel == HAL_FIFO_SEL_RX)
+ start_page += 0x700;
+ else if (halmac_fifo_sel == HAL_FIFO_SEL_REPORT)
+ start_page += 0x660;
+ else if (halmac_fifo_sel == HAL_FIFO_SEL_LLT)
+ start_page += 0x650;
+ else
+ return HALMAC_RET_NOT_SUPPORT;
+
+ value_read = HALMAC_REG_READ_16(halmac_adapter, REG_PKTBUF_DBG_CTRL);
+
+ do {
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_PKTBUF_DBG_CTRL,
+ (u16)(start_page | (value_read & 0xF000)));
+
+ for (i = 0x8000 + residue; i <= 0x8FFF; i += 4) {
+ *(u32 *)(fifo_map + counter) =
+ HALMAC_REG_READ_32(halmac_adapter, i);
+ *(u32 *)(fifo_map + counter) =
+ le32_to_cpu(*(__le32 *)(fifo_map + counter));
+ counter += 4;
+ if (size == counter)
+ goto HALMAC_BUF_READ_OK;
+ }
+
+ residue = 0;
+ start_page++;
+ } while (1);
+
+HALMAC_BUF_READ_OK:
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_PKTBUF_DBG_CTRL,
+ (u16)value_read);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+void halmac_restore_mac_register_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_restore_info *restore_info,
+ u32 restore_num)
+{
+ u8 value_length;
+ u32 i;
+ u32 mac_register;
+ u32 mac_value;
+ struct halmac_api *halmac_api;
+ struct halmac_restore_info *curr_restore_info = restore_info;
+
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ for (i = 0; i < restore_num; i++) {
+ mac_register = curr_restore_info->mac_register;
+ mac_value = curr_restore_info->value;
+ value_length = curr_restore_info->length;
+
+ if (value_length == 1)
+ HALMAC_REG_WRITE_8(halmac_adapter, mac_register,
+ (u8)mac_value);
+ else if (value_length == 2)
+ HALMAC_REG_WRITE_16(halmac_adapter, mac_register,
+ (u16)mac_value);
+ else if (value_length == 4)
+ HALMAC_REG_WRITE_32(halmac_adapter, mac_register,
+ mac_value);
+
+ curr_restore_info++;
+ }
+}
+
+void halmac_api_record_id_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_api_id api_id)
+{
+}
+
+enum halmac_ret_status
+halmac_set_usb_mode_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_usb_mode usb_mode)
+{
+ u32 usb_temp;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ enum halmac_usb_mode current_usb_mode;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ current_usb_mode =
+ HALMAC_REG_READ_8(halmac_adapter, REG_SYS_CFG2 + 3) == 0x20 ?
+ HALMAC_USB_MODE_U3 :
+ HALMAC_USB_MODE_U2;
+
+ /*check if HW supports usb2_usb3 swtich*/
+ usb_temp = HALMAC_REG_READ_32(halmac_adapter, REG_PAD_CTRL2);
+ if (!BIT_GET_USB23_SW_MODE_V1(usb_temp) &&
+ !(usb_temp & BIT_USB3_USB2_TRANSITION)) {
+ pr_err("HALMAC_HW_USB_MODE usb mode HW unsupport\n");
+ return HALMAC_RET_USB2_3_SWITCH_UNSUPPORT;
+ }
+
+ if (usb_mode == current_usb_mode) {
+ pr_err("HALMAC_HW_USB_MODE usb mode unchange\n");
+ return HALMAC_RET_USB_MODE_UNCHANGE;
+ }
+
+ usb_temp &= ~(BIT_USB23_SW_MODE_V1(0x3));
+
+ if (usb_mode == HALMAC_USB_MODE_U2) {
+ /* usb3 to usb2 */
+ HALMAC_REG_WRITE_32(
+ halmac_adapter, REG_PAD_CTRL2,
+ usb_temp | BIT_USB23_SW_MODE_V1(HALMAC_USB_MODE_U2) |
+ BIT_RSM_EN_V1);
+ } else {
+ /* usb2 to usb3 */
+ HALMAC_REG_WRITE_32(
+ halmac_adapter, REG_PAD_CTRL2,
+ usb_temp | BIT_USB23_SW_MODE_V1(HALMAC_USB_MODE_U3) |
+ BIT_RSM_EN_V1);
+ }
+
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_PAD_CTRL2 + 1,
+ 4); /* set counter down timer 4x64 ms */
+ HALMAC_REG_WRITE_16(
+ halmac_adapter, REG_SYS_PW_CTRL,
+ HALMAC_REG_READ_16(halmac_adapter, REG_SYS_PW_CTRL) |
+ BIT_APFM_OFFMAC);
+ usleep_range(1000, 1100);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_PAD_CTRL2,
+ HALMAC_REG_READ_32(halmac_adapter, REG_PAD_CTRL2) |
+ BIT_NO_PDN_CHIPOFF_V1);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+void halmac_enable_bb_rf_88xx(struct halmac_adapter *halmac_adapter, u8 enable)
+{
+ u8 value8;
+ u32 value32;
+ struct halmac_api *halmac_api;
+
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ if (enable == 1) {
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_SYS_FUNC_EN);
+ value8 = value8 | BIT(0) | BIT(1);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_SYS_FUNC_EN, value8);
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RF_CTRL);
+ value8 = value8 | BIT(0) | BIT(1) | BIT(2);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_RF_CTRL, value8);
+
+ value32 = HALMAC_REG_READ_32(halmac_adapter, REG_WLRF1);
+ value32 = value32 | BIT(24) | BIT(25) | BIT(26);
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_WLRF1, value32);
+ } else {
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_SYS_FUNC_EN);
+ value8 = value8 & (~(BIT(0) | BIT(1)));
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_SYS_FUNC_EN, value8);
+
+ value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RF_CTRL);
+ value8 = value8 & (~(BIT(0) | BIT(1) | BIT(2)));
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_RF_CTRL, value8);
+
+ value32 = HALMAC_REG_READ_32(halmac_adapter, REG_WLRF1);
+ value32 = value32 & (~(BIT(24) | BIT(25) | BIT(26)));
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_WLRF1, value32);
+ }
+}
+
+void halmac_config_sdio_tx_page_threshold_88xx(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_tx_page_threshold_info *threshold_info)
+{
+ struct halmac_api *halmac_api;
+
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ switch (threshold_info->dma_queue_sel) {
+ case HALMAC_MAP2_HQ:
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_TQPNT1,
+ threshold_info->threshold);
+ break;
+ case HALMAC_MAP2_NQ:
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_TQPNT2,
+ threshold_info->threshold);
+ break;
+ case HALMAC_MAP2_LQ:
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_TQPNT3,
+ threshold_info->threshold);
+ break;
+ case HALMAC_MAP2_EXQ:
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_TQPNT4,
+ threshold_info->threshold);
+ break;
+ default:
+ break;
+ }
+}
+
+void halmac_config_ampdu_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_ampdu_config *ampdu_config)
+{
+ struct halmac_api *halmac_api;
+
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_PROT_MODE_CTRL + 2,
+ ampdu_config->max_agg_num);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_PROT_MODE_CTRL + 3,
+ ampdu_config->max_agg_num);
+};
+
+enum halmac_ret_status
+halmac_check_oqt_88xx(struct halmac_adapter *halmac_adapter, u32 tx_agg_num,
+ u8 *halmac_buf)
+{
+ u32 counter = 10;
+
+ /*S0, S1 are not allowed to use, 0x4E4[0] should be 0. Soar 20160323*/
+ /*no need to check non_ac_oqt_number. HI and MGQ blocked will cause
+ *protocal issue before H_OQT being full
+ */
+ switch ((enum halmac_queue_select)GET_TX_DESC_QSEL(halmac_buf)) {
+ case HALMAC_QUEUE_SELECT_VO:
+ case HALMAC_QUEUE_SELECT_VO_V2:
+ case HALMAC_QUEUE_SELECT_VI:
+ case HALMAC_QUEUE_SELECT_VI_V2:
+ case HALMAC_QUEUE_SELECT_BE:
+ case HALMAC_QUEUE_SELECT_BE_V2:
+ case HALMAC_QUEUE_SELECT_BK:
+ case HALMAC_QUEUE_SELECT_BK_V2:
+ counter = 10;
+ do {
+ if (halmac_adapter->sdio_free_space.ac_empty > 0) {
+ halmac_adapter->sdio_free_space.ac_empty -= 1;
+ break;
+ }
+
+ if (halmac_adapter->sdio_free_space.ac_oqt_number >=
+ tx_agg_num) {
+ halmac_adapter->sdio_free_space.ac_oqt_number -=
+ (u8)tx_agg_num;
+ break;
+ }
+
+ halmac_update_oqt_free_space_88xx(halmac_adapter);
+
+ counter--;
+ if (counter == 0)
+ return HALMAC_RET_OQT_NOT_ENOUGH;
+ } while (1);
+ break;
+ default:
+ break;
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_rqpn_parser_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_trx_mode halmac_trx_mode,
+ struct halmac_rqpn_ *rqpn_table)
+{
+ u8 search_flag;
+ u32 i;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ search_flag = 0;
+ for (i = 0; i < HALMAC_TRX_MODE_MAX; i++) {
+ if (halmac_trx_mode == rqpn_table[i].mode) {
+ halmac_adapter
+ ->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VO] =
+ rqpn_table[i].dma_map_vo;
+ halmac_adapter
+ ->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VI] =
+ rqpn_table[i].dma_map_vi;
+ halmac_adapter
+ ->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BE] =
+ rqpn_table[i].dma_map_be;
+ halmac_adapter
+ ->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BK] =
+ rqpn_table[i].dma_map_bk;
+ halmac_adapter
+ ->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_MG] =
+ rqpn_table[i].dma_map_mg;
+ halmac_adapter
+ ->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_HI] =
+ rqpn_table[i].dma_map_hi;
+ search_flag = 1;
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
+ DBG_DMESG, "%s done\n", __func__);
+ break;
+ }
+ }
+
+ if (search_flag == 0) {
+ pr_err("HALMAC_RET_TRX_MODE_NOT_SUPPORT 1 switch case not support\n");
+ return HALMAC_RET_TRX_MODE_NOT_SUPPORT;
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_pg_num_parser_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_trx_mode halmac_trx_mode,
+ struct halmac_pg_num_ *pg_num_table)
+{
+ u8 search_flag;
+ u16 HPQ_num = 0, lpq_nnum = 0, NPQ_num = 0, GAPQ_num = 0;
+ u16 EXPQ_num = 0, PUBQ_num = 0;
+ u32 i = 0;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ search_flag = 0;
+ for (i = 0; i < HALMAC_TRX_MODE_MAX; i++) {
+ if (halmac_trx_mode == pg_num_table[i].mode) {
+ HPQ_num = pg_num_table[i].hq_num;
+ lpq_nnum = pg_num_table[i].lq_num;
+ NPQ_num = pg_num_table[i].nq_num;
+ EXPQ_num = pg_num_table[i].exq_num;
+ GAPQ_num = pg_num_table[i].gap_num;
+ PUBQ_num = halmac_adapter->txff_allocation.ac_q_pg_num -
+ HPQ_num - lpq_nnum - NPQ_num - EXPQ_num -
+ GAPQ_num;
+ search_flag = 1;
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
+ DBG_DMESG, "%s done\n", __func__);
+ break;
+ }
+ }
+
+ if (search_flag == 0) {
+ pr_err("HALMAC_RET_TRX_MODE_NOT_SUPPORT 1 switch case not support\n");
+ return HALMAC_RET_TRX_MODE_NOT_SUPPORT;
+ }
+
+ if (halmac_adapter->txff_allocation.ac_q_pg_num <
+ HPQ_num + lpq_nnum + NPQ_num + EXPQ_num + GAPQ_num)
+ return HALMAC_RET_CFG_TXFIFO_PAGE_FAIL;
+
+ halmac_adapter->txff_allocation.high_queue_pg_num = HPQ_num;
+ halmac_adapter->txff_allocation.low_queue_pg_num = lpq_nnum;
+ halmac_adapter->txff_allocation.normal_queue_pg_num = NPQ_num;
+ halmac_adapter->txff_allocation.extra_queue_pg_num = EXPQ_num;
+ halmac_adapter->txff_allocation.pub_queue_pg_num = PUBQ_num;
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_parse_intf_phy_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_intf_phy_para_ *intf_phy_para,
+ enum halmac_intf_phy_platform platform,
+ enum hal_intf_phy intf_phy)
+{
+ u16 value;
+ u16 curr_cut;
+ u16 offset;
+ u16 ip_sel;
+ struct halmac_intf_phy_para_ *curr_phy_para;
+ struct halmac_api *halmac_api;
+ void *driver_adapter = NULL;
+ u8 result = HALMAC_RET_SUCCESS;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ switch (halmac_adapter->chip_version) {
+ case HALMAC_CHIP_VER_A_CUT:
+ curr_cut = (u16)HALMAC_INTF_PHY_CUT_A;
+ break;
+ case HALMAC_CHIP_VER_B_CUT:
+ curr_cut = (u16)HALMAC_INTF_PHY_CUT_B;
+ break;
+ case HALMAC_CHIP_VER_C_CUT:
+ curr_cut = (u16)HALMAC_INTF_PHY_CUT_C;
+ break;
+ case HALMAC_CHIP_VER_D_CUT:
+ curr_cut = (u16)HALMAC_INTF_PHY_CUT_D;
+ break;
+ case HALMAC_CHIP_VER_E_CUT:
+ curr_cut = (u16)HALMAC_INTF_PHY_CUT_E;
+ break;
+ case HALMAC_CHIP_VER_F_CUT:
+ curr_cut = (u16)HALMAC_INTF_PHY_CUT_F;
+ break;
+ case HALMAC_CHIP_VER_TEST:
+ curr_cut = (u16)HALMAC_INTF_PHY_CUT_TESTCHIP;
+ break;
+ default:
+ return HALMAC_RET_FAIL;
+ }
+
+ for (curr_phy_para = intf_phy_para;; curr_phy_para++) {
+ if (!(curr_phy_para->cut & curr_cut) ||
+ !(curr_phy_para->plaform & (u16)platform))
+ continue;
+
+ offset = curr_phy_para->offset;
+ value = curr_phy_para->value;
+ ip_sel = curr_phy_para->ip_sel;
+
+ if (offset == 0xFFFF)
+ break;
+
+ if (ip_sel == HALMAC_IP_SEL_MAC) {
+ HALMAC_REG_WRITE_8(halmac_adapter, (u32)offset,
+ (u8)value);
+ } else if (intf_phy == HAL_INTF_PHY_USB2) {
+ result = halmac_usbphy_write_88xx(halmac_adapter,
+ (u8)offset, value,
+ HAL_INTF_PHY_USB2);
+
+ if (result != HALMAC_RET_SUCCESS)
+ pr_err("[ERR]Write USB2PHY fail!\n");
+
+ } else if (intf_phy == HAL_INTF_PHY_USB3) {
+ result = halmac_usbphy_write_88xx(halmac_adapter,
+ (u8)offset, value,
+ HAL_INTF_PHY_USB3);
+
+ if (result != HALMAC_RET_SUCCESS)
+ pr_err("[ERR]Write USB3PHY fail!\n");
+
+ } else if (intf_phy == HAL_INTF_PHY_PCIE_GEN1) {
+ if (ip_sel == HALMAC_IP_SEL_INTF_PHY)
+ result = halmac_mdio_write_88xx(
+ halmac_adapter, (u8)offset, value,
+ HAL_INTF_PHY_PCIE_GEN1);
+ else
+ result = halmac_dbi_write8_88xx(
+ halmac_adapter, offset, (u8)value);
+
+ if (result != HALMAC_RET_SUCCESS)
+ pr_err("[ERR]MDIO write GEN1 fail!\n");
+
+ } else if (intf_phy == HAL_INTF_PHY_PCIE_GEN2) {
+ if (ip_sel == HALMAC_IP_SEL_INTF_PHY)
+ result = halmac_mdio_write_88xx(
+ halmac_adapter, (u8)offset, value,
+ HAL_INTF_PHY_PCIE_GEN2);
+ else
+ result = halmac_dbi_write8_88xx(
+ halmac_adapter, offset, (u8)value);
+
+ if (result != HALMAC_RET_SUCCESS)
+ pr_err("[ERR]MDIO write GEN2 fail!\n");
+ } else {
+ pr_err("[ERR]Parse intf phy cfg error!\n");
+ }
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+halmac_dbi_write32_88xx(struct halmac_adapter *halmac_adapter, u16 addr,
+ u32 data)
+{
+ u8 tmp_u1b = 0;
+ u32 count = 0;
+ u16 write_addr = 0;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_REG_WRITE_32(halmac_adapter, REG_DBI_WDATA_V1, data);
+
+ write_addr = ((addr & 0x0ffc) | (0x000F << 12));
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_DBI_FLAG_V1, write_addr);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_DBI, DBG_DMESG,
+ "WriteAddr = %x\n", write_addr);
+
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_DBI_FLAG_V1 + 2, 0x01);
+ tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
+
+ count = 20;
+ while (tmp_u1b && count != 0) {
+ udelay(10);
+ tmp_u1b =
+ HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
+ count--;
+ }
+
+ if (tmp_u1b) {
+ pr_err("DBI write fail!\n");
+ return HALMAC_RET_FAIL;
+ } else {
+ return HALMAC_RET_SUCCESS;
+ }
+}
+
+u32 halmac_dbi_read32_88xx(struct halmac_adapter *halmac_adapter, u16 addr)
+{
+ u16 read_addr = addr & 0x0ffc;
+ u8 tmp_u1b = 0;
+ u32 count = 0;
+ u32 ret = 0;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_DBI_FLAG_V1, read_addr);
+
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_DBI_FLAG_V1 + 2, 0x2);
+ tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
+
+ count = 20;
+ while (tmp_u1b && count != 0) {
+ udelay(10);
+ tmp_u1b =
+ HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
+ count--;
+ }
+
+ if (tmp_u1b) {
+ ret = 0xFFFF;
+ pr_err("DBI read fail!\n");
+ } else {
+ ret = HALMAC_REG_READ_32(halmac_adapter, REG_DBI_RDATA_V1);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_DBI, DBG_DMESG,
+ "Read Value = %x\n", ret);
+ }
+
+ return ret;
+}
+
+enum halmac_ret_status
+halmac_dbi_write8_88xx(struct halmac_adapter *halmac_adapter, u16 addr, u8 data)
+{
+ u8 tmp_u1b = 0;
+ u32 count = 0;
+ u16 write_addr = 0;
+ u16 remainder = addr & (4 - 1);
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_DBI_WDATA_V1 + remainder, data);
+
+ write_addr = ((addr & 0x0ffc) | (BIT(0) << (remainder + 12)));
+
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_DBI_FLAG_V1, write_addr);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_DBI, DBG_DMESG,
+ "WriteAddr = %x\n", write_addr);
+
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_DBI_FLAG_V1 + 2, 0x01);
+
+ tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
+
+ count = 20;
+ while (tmp_u1b && count != 0) {
+ udelay(10);
+ tmp_u1b =
+ HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
+ count--;
+ }
+
+ if (tmp_u1b) {
+ pr_err("DBI write fail!\n");
+ return HALMAC_RET_FAIL;
+ } else {
+ return HALMAC_RET_SUCCESS;
+ }
+}
+
+u8 halmac_dbi_read8_88xx(struct halmac_adapter *halmac_adapter, u16 addr)
+{
+ u16 read_addr = addr & 0x0ffc;
+ u8 tmp_u1b = 0;
+ u32 count = 0;
+ u8 ret = 0;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_DBI_FLAG_V1, read_addr);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_DBI_FLAG_V1 + 2, 0x2);
+
+ tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
+
+ count = 20;
+ while (tmp_u1b && count != 0) {
+ udelay(10);
+ tmp_u1b =
+ HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
+ count--;
+ }
+
+ if (tmp_u1b) {
+ ret = 0xFF;
+ pr_err("DBI read fail!\n");
+ } else {
+ ret = HALMAC_REG_READ_8(halmac_adapter,
+ REG_DBI_RDATA_V1 + (addr & (4 - 1)));
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_DBI, DBG_DMESG,
+ "Read Value = %x\n", ret);
+ }
+
+ return ret;
+}
+
+enum halmac_ret_status
+halmac_mdio_write_88xx(struct halmac_adapter *halmac_adapter, u8 addr, u16 data,
+ u8 speed)
+{
+ u8 tmp_u1b = 0;
+ u32 count = 0;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ u8 real_addr = 0;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_REG_WRITE_16(halmac_adapter, REG_MDIO_V1, data);
+
+ /* address : 5bit */
+ real_addr = (addr & 0x1F);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG, real_addr);
+
+ if (speed == HAL_INTF_PHY_PCIE_GEN1) {
+ /* GEN1 page 0 */
+ if (addr < 0x20) {
+ /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b00 */
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
+ 0x00);
+
+ /* GEN1 page 1 */
+ } else {
+ /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b01 */
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
+ 0x01);
+ }
+
+ } else if (speed == HAL_INTF_PHY_PCIE_GEN2) {
+ /* GEN2 page 0 */
+ if (addr < 0x20) {
+ /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b10 */
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
+ 0x02);
+
+ /* GEN2 page 1 */
+ } else {
+ /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b11 */
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
+ 0x03);
+ }
+ } else {
+ pr_err("Error Speed !\n");
+ }
+
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG,
+ HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) |
+ BIT_MDIO_WFLAG_V1);
+
+ tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) &
+ BIT_MDIO_WFLAG_V1;
+ count = 20;
+
+ while (tmp_u1b && count != 0) {
+ udelay(10);
+ tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) &
+ BIT_MDIO_WFLAG_V1;
+ count--;
+ }
+
+ if (tmp_u1b) {
+ pr_err("MDIO write fail!\n");
+ return HALMAC_RET_FAIL;
+ } else {
+ return HALMAC_RET_SUCCESS;
+ }
+}
+
+u16 halmac_mdio_read_88xx(struct halmac_adapter *halmac_adapter, u8 addr,
+ u8 speed
+
+ )
+{
+ u16 ret = 0;
+ u8 tmp_u1b = 0;
+ u32 count = 0;
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ u8 real_addr = 0;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ /* address : 5bit */
+ real_addr = (addr & 0x1F);
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG, real_addr);
+
+ if (speed == HAL_INTF_PHY_PCIE_GEN1) {
+ /* GEN1 page 0 */
+ if (addr < 0x20) {
+ /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b00 */
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
+ 0x00);
+
+ /* GEN1 page 1 */
+ } else {
+ /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b01 */
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
+ 0x01);
+ }
+
+ } else if (speed == HAL_INTF_PHY_PCIE_GEN2) {
+ /* GEN2 page 0 */
+ if (addr < 0x20) {
+ /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b10 */
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
+ 0x02);
+
+ /* GEN2 page 1 */
+ } else {
+ /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b11 */
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
+ 0x03);
+ }
+ } else {
+ pr_err("Error Speed !\n");
+ }
+
+ HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG,
+ HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) |
+ BIT_MDIO_RFLAG_V1);
+
+ tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) &
+ BIT_MDIO_RFLAG_V1;
+ count = 20;
+
+ while (tmp_u1b && count != 0) {
+ udelay(10);
+ tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) &
+ BIT_MDIO_RFLAG_V1;
+ count--;
+ }
+
+ if (tmp_u1b) {
+ ret = 0xFFFF;
+ pr_err("MDIO read fail!\n");
+
+ } else {
+ ret = HALMAC_REG_READ_16(halmac_adapter, REG_MDIO_V1 + 2);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_MDIO, DBG_DMESG,
+ "Read Value = %x\n", ret);
+ }
+
+ return ret;
+}
+
+enum halmac_ret_status
+halmac_usbphy_write_88xx(struct halmac_adapter *halmac_adapter, u8 addr,
+ u16 data, u8 speed)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ if (speed == HAL_INTF_PHY_USB3) {
+ HALMAC_REG_WRITE_8(halmac_adapter, 0xff0d, (u8)data);
+ HALMAC_REG_WRITE_8(halmac_adapter, 0xff0e, (u8)(data >> 8));
+ HALMAC_REG_WRITE_8(halmac_adapter, 0xff0c, addr | BIT(7));
+ } else if (speed == HAL_INTF_PHY_USB2) {
+ HALMAC_REG_WRITE_8(halmac_adapter, 0xfe41, (u8)data);
+ HALMAC_REG_WRITE_8(halmac_adapter, 0xfe40, addr);
+ HALMAC_REG_WRITE_8(halmac_adapter, 0xfe42, 0x81);
+ } else {
+ pr_err("[ERR]Error USB Speed !\n");
+ return HALMAC_RET_NOT_SUPPORT;
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+u16 halmac_usbphy_read_88xx(struct halmac_adapter *halmac_adapter, u8 addr,
+ u8 speed)
+{
+ void *driver_adapter = NULL;
+ struct halmac_api *halmac_api;
+ u16 value = 0;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ if (speed == HAL_INTF_PHY_USB3) {
+ HALMAC_REG_WRITE_8(halmac_adapter, 0xff0c, addr | BIT(6));
+ value = (u16)(HALMAC_REG_READ_32(halmac_adapter, 0xff0c) >> 8);
+ } else if (speed == HAL_INTF_PHY_USB2) {
+ if ((addr >= 0xE0) /*&& (addr <= 0xFF)*/)
+ addr -= 0x20;
+ if ((addr >= 0xC0) && (addr <= 0xDF)) {
+ HALMAC_REG_WRITE_8(halmac_adapter, 0xfe40, addr);
+ HALMAC_REG_WRITE_8(halmac_adapter, 0xfe42, 0x81);
+ value = HALMAC_REG_READ_8(halmac_adapter, 0xfe43);
+ } else {
+ pr_err("[ERR]Error USB2PHY offset!\n");
+ return HALMAC_RET_NOT_SUPPORT;
+ }
+ } else {
+ pr_err("[ERR]Error USB Speed !\n");
+ return HALMAC_RET_NOT_SUPPORT;
+ }
+
+ return value;
+}
diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_func_88xx.h b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_func_88xx.h
new file mode 100644
index 0000000..1b59301
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_func_88xx.h
@@ -0,0 +1,321 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HALMAC_FUNC_88XX_H_
+#define _HALMAC_FUNC_88XX_H_
+
+#include "../halmac_type.h"
+
+void halmac_init_offload_feature_state_machine_88xx(
+ struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_send_h2c_pkt_88xx(struct halmac_adapter *halmac_adapter, u8 *hal_buff,
+ u32 size, bool ack);
+
+enum halmac_ret_status
+halmac_download_rsvd_page_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *hal_buf, u32 size);
+
+enum halmac_ret_status
+halmac_set_h2c_header_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *hal_h2c_hdr, u16 *seq, bool ack);
+
+enum halmac_ret_status halmac_set_fw_offload_h2c_header_88xx(
+ struct halmac_adapter *halmac_adapter, u8 *hal_h2c_hdr,
+ struct halmac_h2c_header_info *h2c_header_info, u16 *seq_num);
+
+enum halmac_ret_status
+halmac_dump_efuse_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_efuse_read_cfg cfg);
+
+enum halmac_ret_status
+halmac_func_read_efuse_88xx(struct halmac_adapter *halmac_adapter, u32 offset,
+ u32 size, u8 *efuse_map);
+
+enum halmac_ret_status
+halmac_func_write_efuse_88xx(struct halmac_adapter *halmac_adapter, u32 offset,
+ u8 value);
+
+enum halmac_ret_status
+halmac_func_switch_efuse_bank_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_efuse_bank efuse_bank);
+
+enum halmac_ret_status
+halmac_read_logical_efuse_map_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *map);
+
+enum halmac_ret_status
+halmac_func_write_logical_efuse_88xx(struct halmac_adapter *halmac_adapter,
+ u32 offset, u8 value);
+
+enum halmac_ret_status
+halmac_func_pg_efuse_by_map_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_pg_efuse_info *pg_efuse_info,
+ enum halmac_efuse_read_cfg cfg);
+
+enum halmac_ret_status
+halmac_eeprom_parser_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *physical_efuse_map, u8 *logical_efuse_map);
+
+enum halmac_ret_status
+halmac_read_hw_efuse_88xx(struct halmac_adapter *halmac_adapter, u32 offset,
+ u32 size, u8 *efuse_map);
+
+enum halmac_ret_status
+halmac_dlfw_to_mem_88xx(struct halmac_adapter *halmac_adapter, u8 *ram_code,
+ u32 dest, u32 code_size);
+
+enum halmac_ret_status
+halmac_send_fwpkt_88xx(struct halmac_adapter *halmac_adapter, u8 *ram_code,
+ u32 code_size);
+
+enum halmac_ret_status
+halmac_iddma_dlfw_88xx(struct halmac_adapter *halmac_adapter, u32 source,
+ u32 dest, u32 length, u8 first);
+
+enum halmac_ret_status
+halmac_check_fw_chksum_88xx(struct halmac_adapter *halmac_adapter,
+ u32 memory_address);
+
+enum halmac_ret_status
+halmac_dlfw_end_flow_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_free_dl_fw_end_flow_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_pwr_seq_parser_88xx(struct halmac_adapter *halmac_adapter, u8 cut,
+ u8 fab, u8 intf,
+ struct halmac_wl_pwr_cfg_ **pp_pwr_seq_cfg
+
+ );
+
+enum halmac_ret_status
+halmac_get_h2c_buff_free_space_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_send_h2c_set_pwr_mode_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_fwlps_option *hal_fw_lps_opt);
+
+enum halmac_ret_status
+halmac_func_send_original_h2c_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *original_h2c, u16 *seq, u8 ack);
+
+enum halmac_ret_status
+halmac_media_status_rpt_88xx(struct halmac_adapter *halmac_adapter, u8 op_mode,
+ u8 mac_id_ind, u8 mac_id, u8 mac_id_end);
+
+enum halmac_ret_status halmac_send_h2c_update_datapack_88xx(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_data_type halmac_data_type,
+ struct halmac_phy_parameter_info *para_info);
+
+enum halmac_ret_status
+halmac_send_h2c_run_datapack_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_data_type halmac_data_type);
+
+enum halmac_ret_status
+halmac_send_bt_coex_cmd_88xx(struct halmac_adapter *halmac_adapter, u8 *bt_buf,
+ u32 bt_size, u8 ack);
+
+enum halmac_ret_status
+halmac_func_ctrl_ch_switch_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_ch_switch_option *cs_option);
+
+enum halmac_ret_status
+halmac_func_send_general_info_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_general_info *general_info);
+
+enum halmac_ret_status
+halmac_send_h2c_ps_tuning_para_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_parse_c2h_packet_88xx(struct halmac_adapter *halmac_adapter,
+ u8 *halmac_buf, u32 halmac_size);
+
+enum halmac_ret_status
+halmac_send_h2c_update_packet_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_packet_id pkt_id, u8 *pkt,
+ u32 pkt_size);
+
+enum halmac_ret_status
+halmac_send_h2c_phy_parameter_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_phy_parameter_info *para_info,
+ bool full_fifo);
+
+enum halmac_ret_status
+halmac_dump_physical_efuse_fw_88xx(struct halmac_adapter *halmac_adapter,
+ u32 offset, u32 size, u8 *efuse_map);
+
+enum halmac_ret_status halmac_send_h2c_update_bcn_parse_info_88xx(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_bcn_ie_info *bcn_ie_info);
+
+enum halmac_ret_status
+halmac_convert_to_sdio_bus_offset_88xx(struct halmac_adapter *halmac_adapter,
+ u32 *halmac_offset);
+
+enum halmac_ret_status
+halmac_update_sdio_free_page_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_update_oqt_free_space_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_efuse_cmd_construct_state
+halmac_query_efuse_curr_state_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status halmac_transition_efuse_state_88xx(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_efuse_cmd_construct_state dest_state);
+
+enum halmac_cfg_para_cmd_construct_state
+halmac_query_cfg_para_curr_state_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status halmac_transition_cfg_para_state_88xx(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_cfg_para_cmd_construct_state dest_state);
+
+enum halmac_scan_cmd_construct_state
+halmac_query_scan_curr_state_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status halmac_transition_scan_state_88xx(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_scan_cmd_construct_state dest_state);
+
+enum halmac_ret_status halmac_query_cfg_para_status_88xx(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_cmd_process_status *process_status, u8 *data, u32 *size);
+
+enum halmac_ret_status halmac_query_dump_physical_efuse_status_88xx(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_cmd_process_status *process_status, u8 *data, u32 *size);
+
+enum halmac_ret_status halmac_query_dump_logical_efuse_status_88xx(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_cmd_process_status *process_status, u8 *data, u32 *size);
+
+enum halmac_ret_status halmac_query_channel_switch_status_88xx(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_cmd_process_status *process_status, u8 *data, u32 *size);
+
+enum halmac_ret_status halmac_query_update_packet_status_88xx(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_cmd_process_status *process_status, u8 *data, u32 *size);
+
+enum halmac_ret_status
+halmac_query_iqk_status_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_cmd_process_status *process_status,
+ u8 *data, u32 *size);
+
+enum halmac_ret_status halmac_query_power_tracking_status_88xx(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_cmd_process_status *process_status, u8 *data, u32 *size);
+
+enum halmac_ret_status
+halmac_query_psd_status_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_cmd_process_status *process_status,
+ u8 *data, u32 *size);
+
+enum halmac_ret_status
+halmac_verify_io_88xx(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status
+halmac_verify_send_rsvd_page_88xx(struct halmac_adapter *halmac_adapter);
+
+void halmac_power_save_cb_88xx(void *cb_data);
+
+enum halmac_ret_status
+halmac_buffer_read_88xx(struct halmac_adapter *halmac_adapter, u32 offset,
+ u32 size, enum hal_fifo_sel halmac_fifo_sel,
+ u8 *fifo_map);
+
+void halmac_restore_mac_register_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_restore_info *restore_info,
+ u32 restore_num);
+
+void halmac_api_record_id_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_api_id api_id);
+
+enum halmac_ret_status
+halmac_set_usb_mode_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_usb_mode usb_mode);
+
+void halmac_enable_bb_rf_88xx(struct halmac_adapter *halmac_adapter, u8 enable);
+
+void halmac_config_sdio_tx_page_threshold_88xx(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_tx_page_threshold_info *threshold_info);
+
+enum halmac_ret_status
+halmac_rqpn_parser_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_trx_mode halmac_trx_mode,
+ struct halmac_rqpn_ *pwr_seq_cfg);
+
+enum halmac_ret_status
+halmac_check_oqt_88xx(struct halmac_adapter *halmac_adapter, u32 tx_agg_num,
+ u8 *halmac_buf);
+
+enum halmac_ret_status
+halmac_pg_num_parser_88xx(struct halmac_adapter *halmac_adapter,
+ enum halmac_trx_mode halmac_trx_mode,
+ struct halmac_pg_num_ *pg_num_table);
+
+enum halmac_ret_status
+halmac_parse_intf_phy_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_intf_phy_para_ *intf_phy_para,
+ enum halmac_intf_phy_platform platform,
+ enum hal_intf_phy intf_phy);
+
+enum halmac_ret_status
+halmac_dbi_write32_88xx(struct halmac_adapter *halmac_adapter, u16 addr,
+ u32 data);
+
+u32 halmac_dbi_read32_88xx(struct halmac_adapter *halmac_adapter, u16 addr);
+
+enum halmac_ret_status
+halmac_dbi_write8_88xx(struct halmac_adapter *halmac_adapter, u16 addr,
+ u8 data);
+
+u8 halmac_dbi_read8_88xx(struct halmac_adapter *halmac_adapter, u16 addr);
+
+u16 halmac_mdio_read_88xx(struct halmac_adapter *halmac_adapter, u8 addr,
+ u8 speed
+
+ );
+
+enum halmac_ret_status
+halmac_mdio_write_88xx(struct halmac_adapter *halmac_adapter, u8 addr, u16 data,
+ u8 speed);
+
+void halmac_config_ampdu_88xx(struct halmac_adapter *halmac_adapter,
+ struct halmac_ampdu_config *ampdu_config);
+
+enum halmac_ret_status
+halmac_usbphy_write_88xx(struct halmac_adapter *halmac_adapter, u8 addr,
+ u16 data, u8 speed);
+
+u16 halmac_usbphy_read_88xx(struct halmac_adapter *halmac_adapter, u8 addr,
+ u8 speed);
+#endif /* _HALMAC_FUNC_88XX_H_ */
diff --git a/drivers/staging/rtlwifi/halmac/halmac_api.c b/drivers/staging/rtlwifi/halmac/halmac_api.c
new file mode 100644
index 0000000..0886a46
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_api.c
@@ -0,0 +1,426 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#include "halmac_2_platform.h"
+#include "halmac_type.h"
+#include "halmac_88xx/halmac_api_88xx.h"
+#include "halmac_88xx/halmac_88xx_cfg.h"
+
+#include "halmac_88xx/halmac_8822b/halmac_8822b_cfg.h"
+
+static enum halmac_ret_status
+halmac_check_platform_api(void *driver_adapter,
+ enum halmac_interface halmac_interface,
+ struct halmac_platform_api *halmac_platform_api)
+{
+ void *adapter_local = NULL;
+
+ adapter_local = driver_adapter;
+
+ if (!halmac_platform_api)
+ return HALMAC_RET_PLATFORM_API_NULL;
+
+ if (halmac_interface == HALMAC_INTERFACE_SDIO) {
+ if (!halmac_platform_api->SDIO_CMD52_READ) {
+ pr_err("(!halmac_platform_api->SDIO_CMD52_READ)\n");
+ return HALMAC_RET_PLATFORM_API_NULL;
+ }
+ if (!halmac_platform_api->SDIO_CMD53_READ_8) {
+ pr_err("(!halmac_platform_api->SDIO_CMD53_READ_8)\n");
+ return HALMAC_RET_PLATFORM_API_NULL;
+ }
+ if (!halmac_platform_api->SDIO_CMD53_READ_16) {
+ pr_err("(!halmac_platform_api->SDIO_CMD53_READ_16)\n");
+ return HALMAC_RET_PLATFORM_API_NULL;
+ }
+ if (!halmac_platform_api->SDIO_CMD53_READ_32) {
+ pr_err("(!halmac_platform_api->SDIO_CMD53_READ_32)\n");
+ return HALMAC_RET_PLATFORM_API_NULL;
+ }
+ if (!halmac_platform_api->SDIO_CMD53_READ_N) {
+ pr_err("(!halmac_platform_api->SDIO_CMD53_READ_N)\n");
+ return HALMAC_RET_PLATFORM_API_NULL;
+ }
+ if (!halmac_platform_api->SDIO_CMD52_WRITE) {
+ pr_err("(!halmac_platform_api->SDIO_CMD52_WRITE)\n");
+ return HALMAC_RET_PLATFORM_API_NULL;
+ }
+ if (!halmac_platform_api->SDIO_CMD53_WRITE_8) {
+ pr_err("(!halmac_platform_api->SDIO_CMD53_WRITE_8)\n");
+ return HALMAC_RET_PLATFORM_API_NULL;
+ }
+ if (!halmac_platform_api->SDIO_CMD53_WRITE_16) {
+ pr_err("(!halmac_platform_api->SDIO_CMD53_WRITE_16)\n");
+ return HALMAC_RET_PLATFORM_API_NULL;
+ }
+ if (!halmac_platform_api->SDIO_CMD53_WRITE_32) {
+ pr_err("(!halmac_platform_api->SDIO_CMD53_WRITE_32)\n");
+ return HALMAC_RET_PLATFORM_API_NULL;
+ }
+ }
+
+ if (halmac_interface == HALMAC_INTERFACE_USB ||
+ halmac_interface == HALMAC_INTERFACE_PCIE) {
+ if (!halmac_platform_api->REG_READ_8) {
+ pr_err("(!halmac_platform_api->REG_READ_8)\n");
+ return HALMAC_RET_PLATFORM_API_NULL;
+ }
+ if (!halmac_platform_api->REG_READ_16) {
+ pr_err("(!halmac_platform_api->REG_READ_16)\n");
+ return HALMAC_RET_PLATFORM_API_NULL;
+ }
+ if (!halmac_platform_api->REG_READ_32) {
+ pr_err("(!halmac_platform_api->REG_READ_32)\n");
+ return HALMAC_RET_PLATFORM_API_NULL;
+ }
+ if (!halmac_platform_api->REG_WRITE_8) {
+ pr_err("(!halmac_platform_api->REG_WRITE_8)\n");
+ return HALMAC_RET_PLATFORM_API_NULL;
+ }
+ if (!halmac_platform_api->REG_WRITE_16) {
+ pr_err("(!halmac_platform_api->REG_WRITE_16)\n");
+ return HALMAC_RET_PLATFORM_API_NULL;
+ }
+ if (!halmac_platform_api->REG_WRITE_32) {
+ pr_err("(!halmac_platform_api->REG_WRITE_32)\n");
+ return HALMAC_RET_PLATFORM_API_NULL;
+ }
+ }
+
+ if (!halmac_platform_api->EVENT_INDICATION) {
+ pr_err("(!halmac_platform_api->EVENT_INDICATION)\n");
+ return HALMAC_RET_PLATFORM_API_NULL;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+halmac_convert_to_sdio_bus_offset(u32 *halmac_offset)
+{
+ switch ((*halmac_offset) & 0xFFFF0000) {
+ case WLAN_IOREG_OFFSET:
+ *halmac_offset = (HALMAC_SDIO_CMD_ADDR_MAC_REG << 13) |
+ (*halmac_offset & HALMAC_WLAN_MAC_REG_MSK);
+ break;
+ case SDIO_LOCAL_OFFSET:
+ *halmac_offset = (HALMAC_SDIO_CMD_ADDR_SDIO_REG << 13) |
+ (*halmac_offset & HALMAC_SDIO_LOCAL_MSK);
+ break;
+ default:
+ *halmac_offset = 0xFFFFFFFF;
+ return HALMAC_RET_CONVERT_SDIO_OFFSET_FAIL;
+ }
+
+ return HALMAC_RET_SUCCESS;
+}
+
+static u8
+platform_reg_read_8_sdio(void *driver_adapter,
+ struct halmac_platform_api *halmac_platform_api,
+ u32 offset)
+{
+ u8 value8;
+ u32 halmac_offset = offset;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ if ((halmac_offset & 0xFFFF0000) == 0)
+ halmac_offset |= WLAN_IOREG_OFFSET;
+
+ status = halmac_convert_to_sdio_bus_offset(&halmac_offset);
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("%s error = %x\n", __func__, status);
+ return status;
+ }
+
+ value8 = halmac_platform_api->SDIO_CMD52_READ(driver_adapter,
+ halmac_offset);
+
+ return value8;
+}
+
+static enum halmac_ret_status
+platform_reg_write_8_sdio(void *driver_adapter,
+ struct halmac_platform_api *halmac_platform_api,
+ u32 offset, u8 data)
+{
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+ u32 halmac_offset = offset;
+
+ if ((halmac_offset & 0xFFFF0000) == 0)
+ halmac_offset |= WLAN_IOREG_OFFSET;
+
+ status = halmac_convert_to_sdio_bus_offset(&halmac_offset);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ pr_err("halmac_reg_write_8_sdio_88xx error = %x\n", status);
+ return status;
+ }
+ halmac_platform_api->SDIO_CMD52_WRITE(driver_adapter, halmac_offset,
+ data);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+halmac_get_chip_info(void *driver_adapter,
+ struct halmac_platform_api *halmac_platform_api,
+ enum halmac_interface halmac_interface,
+ struct halmac_adapter *halmac_adapter)
+{
+ struct halmac_api *halmac_api = (struct halmac_api *)NULL;
+ u8 chip_id, chip_version;
+ u32 polling_count;
+
+ halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ /* Get Chip_id and Chip_version */
+ if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
+ platform_reg_write_8_sdio(
+ driver_adapter, halmac_platform_api, REG_SDIO_HSUS_CTRL,
+ platform_reg_read_8_sdio(driver_adapter,
+ halmac_platform_api,
+ REG_SDIO_HSUS_CTRL) &
+ ~(BIT(0)));
+
+ polling_count = 10000;
+ while (!(platform_reg_read_8_sdio(driver_adapter,
+ halmac_platform_api,
+ REG_SDIO_HSUS_CTRL) &
+ 0x02)) {
+ polling_count--;
+ if (polling_count == 0)
+ return HALMAC_RET_SDIO_LEAVE_SUSPEND_FAIL;
+ }
+
+ chip_id = platform_reg_read_8_sdio(
+ driver_adapter, halmac_platform_api, REG_SYS_CFG2);
+ chip_version = platform_reg_read_8_sdio(driver_adapter,
+ halmac_platform_api,
+ REG_SYS_CFG1 + 1) >>
+ 4;
+ } else {
+ chip_id = halmac_platform_api->REG_READ_8(driver_adapter,
+ REG_SYS_CFG2);
+ chip_version = halmac_platform_api->REG_READ_8(
+ driver_adapter, REG_SYS_CFG1 + 1) >>
+ 4;
+ }
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "[TRACE]Chip id : 0x%X\n", chip_id);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "[TRACE]Chip version : 0x%X\n", chip_version);
+
+ halmac_adapter->chip_version = (enum halmac_chip_ver)chip_version;
+
+ if (chip_id == HALMAC_CHIP_ID_HW_DEF_8822B)
+ halmac_adapter->chip_id = HALMAC_CHIP_ID_8822B;
+ else if (chip_id == HALMAC_CHIP_ID_HW_DEF_8821C)
+ halmac_adapter->chip_id = HALMAC_CHIP_ID_8821C;
+ else if (chip_id == HALMAC_CHIP_ID_HW_DEF_8814B)
+ halmac_adapter->chip_id = HALMAC_CHIP_ID_8814B;
+ else if (chip_id == HALMAC_CHIP_ID_HW_DEF_8197F)
+ halmac_adapter->chip_id = HALMAC_CHIP_ID_8197F;
+ else
+ halmac_adapter->chip_id = HALMAC_CHIP_ID_UNDEFINE;
+
+ if (halmac_adapter->chip_id == HALMAC_CHIP_ID_UNDEFINE)
+ return HALMAC_RET_CHIP_NOT_SUPPORT;
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_init_adapter() - init halmac_adapter
+ * @driver_adapter : the adapter of caller
+ * @halmac_platform_api : the platform APIs which is used in halmac APIs
+ * @halmac_interface : bus interface
+ * @pp_halmac_adapter : the adapter of halmac
+ * @pp_halmac_api : the function pointer of APIs, caller shall call APIs by
+ * function pointer
+ * Author : KaiYuan Chang / Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_init_adapter(void *driver_adapter,
+ struct halmac_platform_api *halmac_platform_api,
+ enum halmac_interface halmac_interface,
+ struct halmac_adapter **pp_halmac_adapter,
+ struct halmac_api **pp_halmac_api)
+{
+ struct halmac_adapter *halmac_adapter = (struct halmac_adapter *)NULL;
+ enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+ union {
+ u32 i;
+ u8 x[4];
+ } ENDIAN_CHECK = {0x01000000};
+
+ status = halmac_check_platform_api(driver_adapter, halmac_interface,
+ halmac_platform_api);
+ if (status != HALMAC_RET_SUCCESS)
+ return status;
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ HALMAC_SVN_VER "\n");
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "HALMAC_MAJOR_VER = %x\n", HALMAC_MAJOR_VER);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "HALMAC_PROTOTYPE_VER = %x\n", HALMAC_PROTOTYPE_VER);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "HALMAC_MINOR_VER = %x\n", HALMAC_MINOR_VER);
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "HALMAC_PATCH_VER = %x\n", HALMAC_PATCH_VER);
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "halmac_init_adapter_88xx ==========>\n");
+
+ /* Check endian setting - Little endian : 1, Big endian : 0*/
+ if (ENDIAN_CHECK.x[0] == HALMAC_SYSTEM_ENDIAN) {
+ pr_err("Endian setting Err!!\n");
+ return HALMAC_RET_ENDIAN_ERR;
+ }
+
+ halmac_adapter = kzalloc(sizeof(*halmac_adapter), GFP_KERNEL);
+ if (!halmac_adapter) {
+ /* out of memory */
+ return HALMAC_RET_MALLOC_FAIL;
+ }
+
+ /* return halmac adapter address to caller */
+ *pp_halmac_adapter = halmac_adapter;
+
+ /* Record caller info */
+ halmac_adapter->halmac_platform_api = halmac_platform_api;
+ halmac_adapter->driver_adapter = driver_adapter;
+ halmac_interface = halmac_interface == HALMAC_INTERFACE_AXI ?
+ HALMAC_INTERFACE_PCIE :
+ halmac_interface;
+ halmac_adapter->halmac_interface = halmac_interface;
+
+ spin_lock_init(&halmac_adapter->efuse_lock);
+ spin_lock_init(&halmac_adapter->h2c_seq_lock);
+
+ /*Get Chip*/
+ if (halmac_get_chip_info(driver_adapter, halmac_platform_api,
+ halmac_interface,
+ halmac_adapter) != HALMAC_RET_SUCCESS) {
+ pr_err("HALMAC_RET_CHIP_NOT_SUPPORT\n");
+ return HALMAC_RET_CHIP_NOT_SUPPORT;
+ }
+
+ /* Assign function pointer to halmac API */
+ halmac_init_adapter_para_88xx(halmac_adapter);
+ status = halmac_mount_api_88xx(halmac_adapter);
+
+ /* Return halmac API function pointer */
+ *pp_halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "halmac_init_adapter_88xx <==========\n");
+
+ return status;
+}
+
+/**
+ * halmac_halt_api() - stop halmac_api action
+ * @halmac_adapter : the adapter of halmac
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status halmac_halt_api(struct halmac_adapter *halmac_adapter)
+{
+ void *driver_adapter = NULL;
+ struct halmac_platform_api *halmac_platform_api =
+ (struct halmac_platform_api *)NULL;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+ halmac_platform_api = halmac_adapter->halmac_platform_api;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+ halmac_adapter->halmac_state.api_state = HALMAC_API_STATE_HALT;
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "%s ==========>\n", __func__);
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_deinit_adapter() - deinit halmac adapter
+ * @halmac_adapter : the adapter of halmac
+ * Author : KaiYuan Chang / Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_deinit_adapter(struct halmac_adapter *halmac_adapter)
+{
+ void *driver_adapter = NULL;
+
+ if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ driver_adapter = halmac_adapter->driver_adapter;
+
+ HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
+ "[TRACE]halmac_deinit_adapter_88xx ==========>\n");
+
+ kfree(halmac_adapter->hal_efuse_map);
+ halmac_adapter->hal_efuse_map = (u8 *)NULL;
+
+ kfree(halmac_adapter->halmac_state.psd_set.data);
+ halmac_adapter->halmac_state.psd_set.data = (u8 *)NULL;
+
+ kfree(halmac_adapter->halmac_api);
+ halmac_adapter->halmac_api = NULL;
+
+ halmac_adapter->hal_adapter_backup = NULL;
+ kfree(halmac_adapter);
+
+ return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_get_version() - get HALMAC version
+ * @version : return version of major, prototype and minor information
+ * Author : KaiYuan Chang / Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status halmac_get_version(struct halmac_ver *version)
+{
+ version->major_ver = (u8)HALMAC_MAJOR_VER;
+ version->prototype_ver = (u8)HALMAC_PROTOTYPE_VER;
+ version->minor_ver = (u8)HALMAC_MINOR_VER;
+
+ return HALMAC_RET_SUCCESS;
+}
diff --git a/drivers/staging/rtlwifi/halmac/halmac_api.h b/drivers/staging/rtlwifi/halmac/halmac_api.h
new file mode 100644
index 0000000..917a646
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_api.h
@@ -0,0 +1,82 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HALMAC_API_H_
+#define _HALMAC_API_H_
+
+#define HALMAC_SVN_VER "13348M"
+
+#define HALMAC_MAJOR_VER 0x0001 /* major version, ver_1 for async_api */
+/* For halmac_api num change or prototype change, increment prototype version.
+ * Otherwise, increase minor version
+ */
+#define HALMAC_PROTOTYPE_VER 0x0003 /* prototype version */
+#define HALMAC_MINOR_VER 0x0005 /* minor version */
+#define HALMAC_PATCH_VER 0x0000 /* patch version */
+
+#include "halmac_2_platform.h"
+#include "halmac_type.h"
+
+#include "halmac_usb_reg.h"
+#include "halmac_sdio_reg.h"
+#include "halmac_pcie_reg.h"
+
+#include "halmac_bit2.h"
+#include "halmac_reg2.h"
+
+#include "halmac_tx_desc_nic.h"
+#include "halmac_rx_desc_nic.h"
+#include "halmac_tx_bd_nic.h"
+#include "halmac_rx_bd_nic.h"
+#include "halmac_fw_offload_c2h_nic.h"
+#include "halmac_fw_offload_h2c_nic.h"
+#include "halmac_h2c_extra_info_nic.h"
+#include "halmac_original_c2h_nic.h"
+#include "halmac_original_h2c_nic.h"
+
+#include "halmac_tx_desc_chip.h"
+#include "halmac_rx_desc_chip.h"
+#include "halmac_tx_bd_chip.h"
+#include "halmac_rx_bd_chip.h"
+#include "halmac_88xx/halmac_88xx_cfg.h"
+
+#include "halmac_88xx/halmac_8822b/halmac_8822b_cfg.h"
+#include "halmac_reg_8822b.h"
+#include "halmac_bit_8822b.h"
+
+enum halmac_ret_status
+halmac_init_adapter(void *driver_adapter,
+ struct halmac_platform_api *halmac_platform_api,
+ enum halmac_interface halmac_interface,
+ struct halmac_adapter **pp_halmac_adapter,
+ struct halmac_api **pp_halmac_api);
+
+enum halmac_ret_status
+halmac_deinit_adapter(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status halmac_halt_api(struct halmac_adapter *halmac_adapter);
+
+enum halmac_ret_status halmac_get_version(struct halmac_ver *version);
+
+#endif
diff --git a/drivers/staging/rtlwifi/halmac/halmac_bit2.h b/drivers/staging/rtlwifi/halmac/halmac_bit2.h
new file mode 100644
index 0000000..1c7fe5d
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_bit2.h
@@ -0,0 +1,13407 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __RTL_WLAN_BITDEF_H__
+#define __RTL_WLAN_BITDEF_H__
+
+/*-------------------------Modification Log-----------------------------------
+ * Base on MAC_Register.doc SVN391
+ *-------------------------Modification Log-----------------------------------
+ */
+
+/*--------------------------Include File--------------------------------------*/
+/*--------------------------Include File--------------------------------------*/
+
+/* 3 ============Programming guide Start===================== */
+/*
+ * 1. For all bit define, it should be prefixed by "BIT_"
+ * 2. For all bit mask, it should be prefixed by "BIT_MASK_"
+ * 3. For all bit shift, it should be prefixed by "BIT_SHIFT_"
+ * 4. For other case, prefix is not needed
+ *
+ * Example:
+ * #define BIT_SHIFT_MAX_TXDMA 16
+ * #define BIT_MASK_MAX_TXDMA 0x7
+ * #define BIT_MAX_TXDMA(x) \
+ * (((x) & BIT_MASK_MAX_TXDMA) << BIT_SHIFT_MAX_TXDMA)
+ * #define BIT_GET_MAX_TXDMA(x) \
+ * (((x) >> BIT_SHIFT_MAX_TXDMA) & BIT_MASK_MAX_TXDMA)
+ *
+ */
+/* 3 ============Programming guide End===================== */
+
+#define CPU_OPT_WIDTH 0x1F
+
+#define BIT_SHIFT_WATCH_DOG_RECORD_V1 10
+#define BIT_MASK_WATCH_DOG_RECORD_V1 0x3fff
+#define BIT_WATCH_DOG_RECORD_V1(x) \
+ (((x) & BIT_MASK_WATCH_DOG_RECORD_V1) << BIT_SHIFT_WATCH_DOG_RECORD_V1)
+#define BIT_GET_WATCH_DOG_RECORD_V1(x) \
+ (((x) >> BIT_SHIFT_WATCH_DOG_RECORD_V1) & BIT_MASK_WATCH_DOG_RECORD_V1)
+
+#define BIT_R_IO_TIMEOUT_FLAG_V1 BIT(9)
+
+#define BIT_ISO_MD2PP BIT(0)
+
+#define BIT_SHIFT_R_WMAC_IPV6_MYIPAD 0
+#define BIT_MASK_R_WMAC_IPV6_MYIPAD 0xffffffffffffffffffffffffffffffffL
+#define BIT_R_WMAC_IPV6_MYIPAD(x) \
+ (((x) & BIT_MASK_R_WMAC_IPV6_MYIPAD) << BIT_SHIFT_R_WMAC_IPV6_MYIPAD)
+#define BIT_GET_R_WMAC_IPV6_MYIPAD(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_IPV6_MYIPAD) & BIT_MASK_R_WMAC_IPV6_MYIPAD)
+
+/* 2 REG_SDIO_TX_CTRL (Offset 0x10250000) */
+
+#define BIT_SHIFT_SDIO_INT_TIMEOUT 16
+#define BIT_MASK_SDIO_INT_TIMEOUT 0xffff
+#define BIT_SDIO_INT_TIMEOUT(x) \
+ (((x) & BIT_MASK_SDIO_INT_TIMEOUT) << BIT_SHIFT_SDIO_INT_TIMEOUT)
+#define BIT_GET_SDIO_INT_TIMEOUT(x) \
+ (((x) >> BIT_SHIFT_SDIO_INT_TIMEOUT) & BIT_MASK_SDIO_INT_TIMEOUT)
+
+/* 2 REG_SYS_ISO_CTRL (Offset 0x0000) */
+
+#define BIT_PWC_EV12V BIT(15)
+
+/* 2 REG_SDIO_TX_CTRL (Offset 0x10250000) */
+
+#define BIT_IO_ERR_STATUS BIT(15)
+
+/* 2 REG_SYS_ISO_CTRL (Offset 0x0000) */
+
+#define BIT_PWC_EV25V BIT(14)
+
+/* 2 REG_SYS_ISO_CTRL (Offset 0x0000) */
+
+#define BIT_PA33V_EN BIT(13)
+#define BIT_PA12V_EN BIT(12)
+
+/* 2 REG_SYS_ISO_CTRL (Offset 0x0000) */
+
+#define BIT_UA33V_EN BIT(11)
+#define BIT_UA12V_EN BIT(10)
+
+/* 2 REG_SYS_ISO_CTRL (Offset 0x0000) */
+
+#define BIT_ISO_RFDIO BIT(9)
+
+/* 2 REG_SDIO_TX_CTRL (Offset 0x10250000) */
+
+#define BIT_REPLY_ERRCRC_IN_DATA BIT(9)
+
+/* 2 REG_SYS_ISO_CTRL (Offset 0x0000) */
+
+#define BIT_ISO_EB2CORE BIT(8)
+
+/* 2 REG_SDIO_TX_CTRL (Offset 0x10250000) */
+
+#define BIT_EN_CMD53_OVERLAP BIT(8)
+
+/* 2 REG_SYS_ISO_CTRL (Offset 0x0000) */
+
+#define BIT_ISO_DIOE BIT(7)
+
+/* 2 REG_SDIO_TX_CTRL (Offset 0x10250000) */
+
+#define BIT_REPLY_ERR_IN_R5 BIT(7)
+
+/* 2 REG_SYS_ISO_CTRL (Offset 0x0000) */
+
+#define BIT_ISO_WLPON2PP BIT(6)
+
+/* 2 REG_SDIO_TX_CTRL (Offset 0x10250000) */
+
+#define BIT_R18A_EN BIT(6)
+
+/* 2 REG_SYS_ISO_CTRL (Offset 0x0000) */
+
+#define BIT_ISO_IP2MAC_WA2PP BIT(5)
+
+/* 2 REG_SDIO_TX_CTRL (Offset 0x10250000) */
+
+#define BIT_INIT_CMD_EN BIT(5)
+
+/* 2 REG_SYS_ISO_CTRL (Offset 0x0000) */
+
+#define BIT_ISO_PD2CORE BIT(4)
+
+/* 2 REG_SYS_ISO_CTRL (Offset 0x0000) */
+
+#define BIT_ISO_PA2PCIE BIT(3)
+
+/* 2 REG_SYS_ISO_CTRL (Offset 0x0000) */
+
+#define BIT_ISO_UD2CORE BIT(2)
+
+/* 2 REG_SDIO_TX_CTRL (Offset 0x10250000) */
+
+#define BIT_EN_RXDMA_MASK_INT BIT(2)
+
+/* 2 REG_SYS_ISO_CTRL (Offset 0x0000) */
+
+#define BIT_ISO_UA2USB BIT(1)
+
+/* 2 REG_SDIO_TX_CTRL (Offset 0x10250000) */
+
+#define BIT_EN_MASK_TIMER BIT(1)
+
+/* 2 REG_SYS_ISO_CTRL (Offset 0x0000) */
+
+#define BIT_ISO_WD2PP BIT(0)
+
+/* 2 REG_SDIO_TX_CTRL (Offset 0x10250000) */
+
+#define BIT_CMD_ERR_STOP_INT_EN BIT(0)
+
+/* 2 REG_SYS_FUNC_EN (Offset 0x0002) */
+
+#define BIT_FEN_MREGEN BIT(15)
+#define BIT_FEN_HWPDN BIT(14)
+
+/* 2 REG_SYS_FUNC_EN (Offset 0x0002) */
+
+#define BIT_EN_25_1 BIT(13)
+
+/* 2 REG_SYS_FUNC_EN (Offset 0x0002) */
+
+#define BIT_FEN_ELDR BIT(12)
+#define BIT_FEN_DCORE BIT(11)
+#define BIT_FEN_CPUEN BIT(10)
+#define BIT_FEN_DIOE BIT(9)
+#define BIT_FEN_PCIED BIT(8)
+#define BIT_FEN_PPLL BIT(7)
+#define BIT_FEN_PCIEA BIT(6)
+#define BIT_FEN_DIO_PCIE BIT(5)
+#define BIT_FEN_USBD BIT(4)
+#define BIT_FEN_UPLL BIT(3)
+#define BIT_FEN_USBA BIT(2)
+
+/* 2 REG_SYS_FUNC_EN (Offset 0x0002) */
+
+#define BIT_FEN_BB_GLB_RSTN BIT(1)
+#define BIT_FEN_BBRSTB BIT(0)
+
+/* 2 REG_SYS_PW_CTRL (Offset 0x0004) */
+
+#define BIT_SOP_EABM BIT(31)
+
+/* 2 REG_SYS_PW_CTRL (Offset 0x0004) */
+
+#define BIT_SOP_ACKF BIT(30)
+#define BIT_SOP_ERCK BIT(29)
+
+/* 2 REG_SYS_PW_CTRL (Offset 0x0004) */
+
+#define BIT_SOP_ESWR BIT(28)
+
+/* 2 REG_SYS_PW_CTRL (Offset 0x0004) */
+
+#define BIT_SOP_PWMM BIT(27)
+
+/* 2 REG_SYS_PW_CTRL (Offset 0x0004) */
+
+#define BIT_SOP_EECK BIT(26)
+
+/* 2 REG_SYS_PW_CTRL (Offset 0x0004) */
+
+#define BIT_SOP_EXTL BIT(24)
+
+/* 2 REG_SYS_PW_CTRL (Offset 0x0004) */
+
+#define BIT_SYM_OP_RING_12M BIT(22)
+
+/* 2 REG_SYS_PW_CTRL (Offset 0x0004) */
+
+#define BIT_ROP_SWPR BIT(21)
+
+/* 2 REG_SYS_PW_CTRL (Offset 0x0004) */
+
+#define BIT_DIS_HW_LPLDM BIT(20)
+
+/* 2 REG_SYS_PW_CTRL (Offset 0x0004) */
+
+#define BIT_OPT_SWRST_WLMCU BIT(19)
+#define BIT_RDY_SYSPWR BIT(17)
+
+/* 2 REG_SYS_PW_CTRL (Offset 0x0004) */
+
+#define BIT_EN_WLON BIT(16)
+
+/* 2 REG_SYS_PW_CTRL (Offset 0x0004) */
+
+#define BIT_APDM_HPDN BIT(15)
+
+/* 2 REG_SYS_PW_CTRL (Offset 0x0004) */
+
+#define BIT_AFSM_PCIE_SUS_EN BIT(12)
+
+/* 2 REG_SYS_PW_CTRL (Offset 0x0004) */
+
+#define BIT_AFSM_WLSUS_EN BIT(11)
+
+/* 2 REG_SYS_PW_CTRL (Offset 0x0004) */
+
+#define BIT_APFM_SWLPS BIT(10)
+
+/* 2 REG_SYS_PW_CTRL (Offset 0x0004) */
+
+#define BIT_APFM_OFFMAC BIT(9)
+#define BIT_APFN_ONMAC BIT(8)
+
+/* 2 REG_SYS_PW_CTRL (Offset 0x0004) */
+
+#define BIT_CHIP_PDN_EN BIT(7)
+
+/* 2 REG_SYS_PW_CTRL (Offset 0x0004) */
+
+#define BIT_RDY_MACDIS BIT(6)
+
+/* 2 REG_SYS_PW_CTRL (Offset 0x0004) */
+
+#define BIT_RING_CLK_12M_EN BIT(4)
+
+/* 2 REG_SYS_PW_CTRL (Offset 0x0004) */
+
+#define BIT_PFM_WOWL BIT(3)
+
+/* 2 REG_SYS_PW_CTRL (Offset 0x0004) */
+
+#define BIT_PFM_LDKP BIT(2)
+
+/* 2 REG_SYS_PW_CTRL (Offset 0x0004) */
+
+#define BIT_WL_HCI_ALD BIT(1)
+
+/* 2 REG_SYS_PW_CTRL (Offset 0x0004) */
+
+#define BIT_PFM_LDALL BIT(0)
+
+/* 2 REG_SYS_CLK_CTRL (Offset 0x0008) */
+
+#define BIT_LDO_DUMMY BIT(15)
+
+/* 2 REG_SYS_CLK_CTRL (Offset 0x0008) */
+
+#define BIT_CPU_CLK_EN BIT(14)
+
+/* 2 REG_SYS_CLK_CTRL (Offset 0x0008) */
+
+#define BIT_SYMREG_CLK_EN BIT(13)
+
+/* 2 REG_SYS_CLK_CTRL (Offset 0x0008) */
+
+#define BIT_HCI_CLK_EN BIT(12)
+
+/* 2 REG_SYS_CLK_CTRL (Offset 0x0008) */
+
+#define BIT_MAC_CLK_EN BIT(11)
+#define BIT_SEC_CLK_EN BIT(10)
+
+/* 2 REG_SYS_CLK_CTRL (Offset 0x0008) */
+
+#define BIT_PHY_SSC_RSTB BIT(9)
+#define BIT_EXT_32K_EN BIT(8)
+
+/* 2 REG_SYS_CLK_CTRL (Offset 0x0008) */
+
+#define BIT_WL_CLK_TEST BIT(7)
+#define BIT_OP_SPS_PWM_EN BIT(6)
+
+/* 2 REG_SYS_CLK_CTRL (Offset 0x0008) */
+
+#define BIT_LOADER_CLK_EN BIT(5)
+#define BIT_MACSLP BIT(4)
+#define BIT_WAKEPAD_EN BIT(3)
+#define BIT_ROMD16V_EN BIT(2)
+
+/* 2 REG_SYS_CLK_CTRL (Offset 0x0008) */
+
+#define BIT_CKANA12M_EN BIT(1)
+
+/* 2 REG_SYS_CLK_CTRL (Offset 0x0008) */
+
+#define BIT_CNTD16V_EN BIT(0)
+
+/* 2 REG_SYS_EEPROM_CTRL (Offset 0x000A) */
+
+#define BIT_SHIFT_VPDIDX 8
+#define BIT_MASK_VPDIDX 0xff
+#define BIT_VPDIDX(x) (((x) & BIT_MASK_VPDIDX) << BIT_SHIFT_VPDIDX)
+#define BIT_GET_VPDIDX(x) (((x) >> BIT_SHIFT_VPDIDX) & BIT_MASK_VPDIDX)
+
+#define BIT_SHIFT_EEM1_0 6
+#define BIT_MASK_EEM1_0 0x3
+#define BIT_EEM1_0(x) (((x) & BIT_MASK_EEM1_0) << BIT_SHIFT_EEM1_0)
+#define BIT_GET_EEM1_0(x) (((x) >> BIT_SHIFT_EEM1_0) & BIT_MASK_EEM1_0)
+
+#define BIT_AUTOLOAD_SUS BIT(5)
+
+/* 2 REG_SYS_EEPROM_CTRL (Offset 0x000A) */
+
+#define BIT_EERPOMSEL BIT(4)
+
+/* 2 REG_SYS_EEPROM_CTRL (Offset 0x000A) */
+
+#define BIT_EECS_V1 BIT(3)
+#define BIT_EESK_V1 BIT(2)
+#define BIT_EEDI_V1 BIT(1)
+#define BIT_EEDO_V1 BIT(0)
+
+/* 2 REG_EE_VPD (Offset 0x000C) */
+
+#define BIT_SHIFT_VPD_DATA 0
+#define BIT_MASK_VPD_DATA 0xffffffffL
+#define BIT_VPD_DATA(x) (((x) & BIT_MASK_VPD_DATA) << BIT_SHIFT_VPD_DATA)
+#define BIT_GET_VPD_DATA(x) (((x) >> BIT_SHIFT_VPD_DATA) & BIT_MASK_VPD_DATA)
+
+/* 2 REG_SYS_SWR_CTRL1 (Offset 0x0010) */
+
+#define BIT_C2_L_BIT0 BIT(31)
+
+/* 2 REG_SYS_SWR_CTRL1 (Offset 0x0010) */
+
+#define BIT_SHIFT_C1_L 29
+#define BIT_MASK_C1_L 0x3
+#define BIT_C1_L(x) (((x) & BIT_MASK_C1_L) << BIT_SHIFT_C1_L)
+#define BIT_GET_C1_L(x) (((x) >> BIT_SHIFT_C1_L) & BIT_MASK_C1_L)
+
+/* 2 REG_SYS_SWR_CTRL1 (Offset 0x0010) */
+
+#define BIT_SHIFT_REG_FREQ_L 25
+#define BIT_MASK_REG_FREQ_L 0x7
+#define BIT_REG_FREQ_L(x) (((x) & BIT_MASK_REG_FREQ_L) << BIT_SHIFT_REG_FREQ_L)
+#define BIT_GET_REG_FREQ_L(x) \
+ (((x) >> BIT_SHIFT_REG_FREQ_L) & BIT_MASK_REG_FREQ_L)
+
+#define BIT_REG_EN_DUTY BIT(24)
+
+/* 2 REG_SYS_SWR_CTRL1 (Offset 0x0010) */
+
+#define BIT_SHIFT_REG_MODE 22
+#define BIT_MASK_REG_MODE 0x3
+#define BIT_REG_MODE(x) (((x) & BIT_MASK_REG_MODE) << BIT_SHIFT_REG_MODE)
+#define BIT_GET_REG_MODE(x) (((x) >> BIT_SHIFT_REG_MODE) & BIT_MASK_REG_MODE)
+
+/* 2 REG_SYS_SWR_CTRL1 (Offset 0x0010) */
+
+#define BIT_REG_EN_SP BIT(21)
+#define BIT_REG_AUTO_L BIT(20)
+
+/* 2 REG_SYS_SWR_CTRL1 (Offset 0x0010) */
+
+#define BIT_SW18_SELD_BIT0 BIT(19)
+
+/* 2 REG_SYS_SWR_CTRL1 (Offset 0x0010) */
+
+#define BIT_SW18_POWOCP BIT(18)
+
+/* 2 REG_SYS_SWR_CTRL1 (Offset 0x0010) */
+
+#define BIT_SHIFT_OCP_L1 15
+#define BIT_MASK_OCP_L1 0x7
+#define BIT_OCP_L1(x) (((x) & BIT_MASK_OCP_L1) << BIT_SHIFT_OCP_L1)
+#define BIT_GET_OCP_L1(x) (((x) >> BIT_SHIFT_OCP_L1) & BIT_MASK_OCP_L1)
+
+/* 2 REG_SYS_SWR_CTRL1 (Offset 0x0010) */
+
+#define BIT_SHIFT_CF_L 13
+#define BIT_MASK_CF_L 0x3
+#define BIT_CF_L(x) (((x) & BIT_MASK_CF_L) << BIT_SHIFT_CF_L)
+#define BIT_GET_CF_L(x) (((x) >> BIT_SHIFT_CF_L) & BIT_MASK_CF_L)
+
+/* 2 REG_SYS_SWR_CTRL1 (Offset 0x0010) */
+
+#define BIT_SW18_FPWM BIT(11)
+
+/* 2 REG_SYS_SWR_CTRL1 (Offset 0x0010) */
+
+#define BIT_SW18_SWEN BIT(9)
+#define BIT_SW18_LDEN BIT(8)
+#define BIT_MAC_ID_EN BIT(7)
+
+/* 2 REG_SYS_SWR_CTRL1 (Offset 0x0010) */
+
+#define BIT_AFE_BGEN BIT(0)
+
+/* 2 REG_SYS_SWR_CTRL2 (Offset 0x0014) */
+
+#define BIT_POW_ZCD_L BIT(31)
+
+/* 2 REG_SDIO_HIMR (Offset 0x10250014) */
+
+#define BIT_SDIO_CRCERR_MSK BIT(31)
+
+/* 2 REG_SYS_SWR_CTRL2 (Offset 0x0014) */
+
+#define BIT_AUTOZCD_L BIT(30)
+#define BIT_SDIO_HSISR3_IND_MSK BIT(30)
+#define BIT_SDIO_HSISR2_IND_MSK BIT(29)
+
+/* 2 REG_SYS_SWR_CTRL2 (Offset 0x0014) */
+
+#define BIT_SHIFT_REG_DELAY 28
+#define BIT_MASK_REG_DELAY 0x3
+#define BIT_REG_DELAY(x) (((x) & BIT_MASK_REG_DELAY) << BIT_SHIFT_REG_DELAY)
+#define BIT_GET_REG_DELAY(x) (((x) >> BIT_SHIFT_REG_DELAY) & BIT_MASK_REG_DELAY)
+
+/* 2 REG_SDIO_HIMR (Offset 0x10250014) */
+
+#define BIT_SDIO_HEISR_IND_MSK BIT(28)
+
+/* 2 REG_SDIO_HIMR (Offset 0x10250014) */
+
+#define BIT_SDIO_CTWEND_MSK BIT(27)
+#define BIT_SDIO_ATIMEND_E_MSK BIT(26)
+
+/* 2 REG_SDIO_HIMR (Offset 0x10250014) */
+
+#define BIT_SDIIO_ATIMEND_MSK BIT(25)
+
+/* 2 REG_SDIO_HIMR (Offset 0x10250014) */
+
+#define BIT_SDIO_OCPINT_MSK BIT(24)
+
+/* 2 REG_SYS_SWR_CTRL2 (Offset 0x0014) */
+
+#define BIT_SHIFT_V15ADJ_L1_V1 24
+#define BIT_MASK_V15ADJ_L1_V1 0x7
+#define BIT_V15ADJ_L1_V1(x) \
+ (((x) & BIT_MASK_V15ADJ_L1_V1) << BIT_SHIFT_V15ADJ_L1_V1)
+#define BIT_GET_V15ADJ_L1_V1(x) \
+ (((x) >> BIT_SHIFT_V15ADJ_L1_V1) & BIT_MASK_V15ADJ_L1_V1)
+
+/* 2 REG_SDIO_HIMR (Offset 0x10250014) */
+
+#define BIT_SDIO_PSTIMEOUT_MSK BIT(23)
+
+/* 2 REG_SDIO_HIMR (Offset 0x10250014) */
+
+#define BIT_SDIO_GTINT4_MSK BIT(22)
+
+/* 2 REG_SDIO_HIMR (Offset 0x10250014) */
+
+#define BIT_SDIO_GTINT3_MSK BIT(21)
+
+/* 2 REG_SDIO_HIMR (Offset 0x10250014) */
+
+#define BIT_SDIO_HSISR_IND_MSK BIT(20)
+
+/* 2 REG_SYS_SWR_CTRL2 (Offset 0x0014) */
+
+#define BIT_SHIFT_VOL_L1_V1 20
+#define BIT_MASK_VOL_L1_V1 0xf
+#define BIT_VOL_L1_V1(x) (((x) & BIT_MASK_VOL_L1_V1) << BIT_SHIFT_VOL_L1_V1)
+#define BIT_GET_VOL_L1_V1(x) (((x) >> BIT_SHIFT_VOL_L1_V1) & BIT_MASK_VOL_L1_V1)
+
+/* 2 REG_SDIO_HIMR (Offset 0x10250014) */
+
+#define BIT_SDIO_CPWM2_MSK BIT(19)
+
+/* 2 REG_SDIO_HIMR (Offset 0x10250014) */
+
+#define BIT_SDIO_CPWM1_MSK BIT(18)
+
+/* 2 REG_SDIO_HIMR (Offset 0x10250014) */
+
+#define BIT_SDIO_C2HCMD_INT_MSK BIT(17)
+
+/* 2 REG_SYS_SWR_CTRL2 (Offset 0x0014) */
+
+#define BIT_SHIFT_IN_L1_V1 17
+#define BIT_MASK_IN_L1_V1 0x7
+#define BIT_IN_L1_V1(x) (((x) & BIT_MASK_IN_L1_V1) << BIT_SHIFT_IN_L1_V1)
+#define BIT_GET_IN_L1_V1(x) (((x) >> BIT_SHIFT_IN_L1_V1) & BIT_MASK_IN_L1_V1)
+
+/* 2 REG_SDIO_HIMR (Offset 0x10250014) */
+
+#define BIT_SDIO_BCNERLY_INT_MSK BIT(16)
+
+/* 2 REG_SYS_SWR_CTRL2 (Offset 0x0014) */
+
+#define BIT_SHIFT_TBOX_L1 15
+#define BIT_MASK_TBOX_L1 0x3
+#define BIT_TBOX_L1(x) (((x) & BIT_MASK_TBOX_L1) << BIT_SHIFT_TBOX_L1)
+#define BIT_GET_TBOX_L1(x) (((x) >> BIT_SHIFT_TBOX_L1) & BIT_MASK_TBOX_L1)
+
+/* 2 REG_SYS_SWR_CTRL2 (Offset 0x0014) */
+
+#define BIT_SW18_SEL BIT(13)
+
+/* 2 REG_SYS_SWR_CTRL2 (Offset 0x0014) */
+
+#define BIT_SW18_SD BIT(10)
+
+/* 2 REG_SDIO_HIMR (Offset 0x10250014) */
+
+#define BIT_SDIO_TXBCNERR_MSK BIT(7)
+
+/* 2 REG_SYS_SWR_CTRL2 (Offset 0x0014) */
+
+#define BIT_SHIFT_R3_L 7
+#define BIT_MASK_R3_L 0x3
+#define BIT_R3_L(x) (((x) & BIT_MASK_R3_L) << BIT_SHIFT_R3_L)
+#define BIT_GET_R3_L(x) (((x) >> BIT_SHIFT_R3_L) & BIT_MASK_R3_L)
+
+/* 2 REG_SDIO_HIMR (Offset 0x10250014) */
+
+#define BIT_SDIO_TXBCNOK_MSK BIT(6)
+
+/* 2 REG_SYS_SWR_CTRL2 (Offset 0x0014) */
+
+#define BIT_SHIFT_SW18_R2 5
+#define BIT_MASK_SW18_R2 0x3
+#define BIT_SW18_R2(x) (((x) & BIT_MASK_SW18_R2) << BIT_SHIFT_SW18_R2)
+#define BIT_GET_SW18_R2(x) (((x) >> BIT_SHIFT_SW18_R2) & BIT_MASK_SW18_R2)
+
+/* 2 REG_SDIO_HIMR (Offset 0x10250014) */
+
+#define BIT_SDIO_RXFOVW_MSK BIT(5)
+#define BIT_SDIO_TXFOVW_MSK BIT(4)
+
+/* 2 REG_SYS_SWR_CTRL2 (Offset 0x0014) */
+
+#define BIT_SHIFT_SW18_R1 3
+#define BIT_MASK_SW18_R1 0x3
+#define BIT_SW18_R1(x) (((x) & BIT_MASK_SW18_R1) << BIT_SHIFT_SW18_R1)
+#define BIT_GET_SW18_R1(x) (((x) >> BIT_SHIFT_SW18_R1) & BIT_MASK_SW18_R1)
+
+/* 2 REG_SDIO_HIMR (Offset 0x10250014) */
+
+#define BIT_SDIO_RXERR_MSK BIT(3)
+#define BIT_SDIO_TXERR_MSK BIT(2)
+
+/* 2 REG_SDIO_HIMR (Offset 0x10250014) */
+
+#define BIT_SDIO_AVAL_MSK BIT(1)
+
+/* 2 REG_SYS_SWR_CTRL2 (Offset 0x0014) */
+
+#define BIT_SHIFT_C3_L_C3 1
+#define BIT_MASK_C3_L_C3 0x3
+#define BIT_C3_L_C3(x) (((x) & BIT_MASK_C3_L_C3) << BIT_SHIFT_C3_L_C3)
+#define BIT_GET_C3_L_C3(x) (((x) >> BIT_SHIFT_C3_L_C3) & BIT_MASK_C3_L_C3)
+
+/* 2 REG_SDIO_HIMR (Offset 0x10250014) */
+
+#define BIT_RX_REQUEST_MSK BIT(0)
+
+/* 2 REG_SYS_SWR_CTRL2 (Offset 0x0014) */
+
+#define BIT_C2_L_BIT1 BIT(0)
+
+/* 2 REG_SYS_SWR_CTRL3 (Offset 0x0018) */
+
+#define BIT_SPS18_OCP_DIS BIT(31)
+
+/* 2 REG_SDIO_HISR (Offset 0x10250018) */
+
+#define BIT_SDIO_CRCERR BIT(31)
+
+/* 2 REG_SDIO_HISR (Offset 0x10250018) */
+
+#define BIT_SDIO_HSISR3_IND BIT(30)
+#define BIT_SDIO_HSISR2_IND BIT(29)
+#define BIT_SDIO_HEISR_IND BIT(28)
+
+/* 2 REG_SDIO_HISR (Offset 0x10250018) */
+
+#define BIT_SDIO_CTWEND BIT(27)
+#define BIT_SDIO_ATIMEND_E BIT(26)
+#define BIT_SDIO_ATIMEND BIT(25)
+#define BIT_SDIO_OCPINT BIT(24)
+#define BIT_SDIO_PSTIMEOUT BIT(23)
+#define BIT_SDIO_GTINT4 BIT(22)
+#define BIT_SDIO_GTINT3 BIT(21)
+#define BIT_SDIO_HSISR_IND BIT(20)
+#define BIT_SDIO_CPWM2 BIT(19)
+#define BIT_SDIO_CPWM1 BIT(18)
+#define BIT_SDIO_C2HCMD_INT BIT(17)
+
+/* 2 REG_SYS_SWR_CTRL3 (Offset 0x0018) */
+
+#define BIT_SHIFT_SPS18_OCP_TH 16
+#define BIT_MASK_SPS18_OCP_TH 0x7fff
+#define BIT_SPS18_OCP_TH(x) \
+ (((x) & BIT_MASK_SPS18_OCP_TH) << BIT_SHIFT_SPS18_OCP_TH)
+#define BIT_GET_SPS18_OCP_TH(x) \
+ (((x) >> BIT_SHIFT_SPS18_OCP_TH) & BIT_MASK_SPS18_OCP_TH)
+
+/* 2 REG_SDIO_HISR (Offset 0x10250018) */
+
+#define BIT_SDIO_BCNERLY_INT BIT(16)
+#define BIT_SDIO_TXBCNERR BIT(7)
+#define BIT_SDIO_TXBCNOK BIT(6)
+#define BIT_SDIO_RXFOVW BIT(5)
+#define BIT_SDIO_TXFOVW BIT(4)
+#define BIT_SDIO_RXERR BIT(3)
+#define BIT_SDIO_TXERR BIT(2)
+#define BIT_SDIO_AVAL BIT(1)
+
+/* 2 REG_SYS_SWR_CTRL3 (Offset 0x0018) */
+
+#define BIT_SHIFT_OCP_WINDOW 0
+#define BIT_MASK_OCP_WINDOW 0xffff
+#define BIT_OCP_WINDOW(x) (((x) & BIT_MASK_OCP_WINDOW) << BIT_SHIFT_OCP_WINDOW)
+#define BIT_GET_OCP_WINDOW(x) \
+ (((x) >> BIT_SHIFT_OCP_WINDOW) & BIT_MASK_OCP_WINDOW)
+
+/* 2 REG_SDIO_HISR (Offset 0x10250018) */
+
+#define BIT_RX_REQUEST BIT(0)
+
+/* 2 REG_RSV_CTRL (Offset 0x001C) */
+
+#define BIT_HREG_DBG BIT(23)
+
+/* 2 REG_RSV_CTRL (Offset 0x001C) */
+
+#define BIT_WLMCUIOIF BIT(8)
+
+/* 2 REG_RSV_CTRL (Offset 0x001C) */
+
+#define BIT_LOCK_ALL_EN BIT(7)
+
+/* 2 REG_RSV_CTRL (Offset 0x001C) */
+
+#define BIT_R_DIS_PRST BIT(6)
+
+/* 2 REG_RSV_CTRL (Offset 0x001C) */
+
+#define BIT_WLOCK_1C_B6 BIT(5)
+
+/* 2 REG_RSV_CTRL (Offset 0x001C) */
+
+#define BIT_WLOCK_40 BIT(4)
+#define BIT_WLOCK_08 BIT(3)
+#define BIT_WLOCK_04 BIT(2)
+#define BIT_WLOCK_00 BIT(1)
+#define BIT_WLOCK_ALL BIT(0)
+
+/* 2 REG_SDIO_RX_REQ_LEN (Offset 0x1025001C) */
+
+#define BIT_SHIFT_RX_REQ_LEN_V1 0
+#define BIT_MASK_RX_REQ_LEN_V1 0x3ffff
+#define BIT_RX_REQ_LEN_V1(x) \
+ (((x) & BIT_MASK_RX_REQ_LEN_V1) << BIT_SHIFT_RX_REQ_LEN_V1)
+#define BIT_GET_RX_REQ_LEN_V1(x) \
+ (((x) >> BIT_SHIFT_RX_REQ_LEN_V1) & BIT_MASK_RX_REQ_LEN_V1)
+
+/* 2 REG_RF_CTRL (Offset 0x001F) */
+
+#define BIT_RF_SDMRSTB BIT(2)
+
+/* 2 REG_RF_CTRL (Offset 0x001F) */
+
+#define BIT_RF_RSTB BIT(1)
+
+/* 2 REG_RF_CTRL (Offset 0x001F) */
+
+#define BIT_RF_EN BIT(0)
+
+/* 2 REG_SDIO_FREE_TXPG_SEQ_V1 (Offset 0x1025001F) */
+
+#define BIT_SHIFT_FREE_TXPG_SEQ 0
+#define BIT_MASK_FREE_TXPG_SEQ 0xff
+#define BIT_FREE_TXPG_SEQ(x) \
+ (((x) & BIT_MASK_FREE_TXPG_SEQ) << BIT_SHIFT_FREE_TXPG_SEQ)
+#define BIT_GET_FREE_TXPG_SEQ(x) \
+ (((x) >> BIT_SHIFT_FREE_TXPG_SEQ) & BIT_MASK_FREE_TXPG_SEQ)
+
+/* 2 REG_AFE_LDO_CTRL (Offset 0x0020) */
+
+#define BIT_SHIFT_LPLDH12_RSV 29
+#define BIT_MASK_LPLDH12_RSV 0x7
+#define BIT_LPLDH12_RSV(x) \
+ (((x) & BIT_MASK_LPLDH12_RSV) << BIT_SHIFT_LPLDH12_RSV)
+#define BIT_GET_LPLDH12_RSV(x) \
+ (((x) >> BIT_SHIFT_LPLDH12_RSV) & BIT_MASK_LPLDH12_RSV)
+
+/* 2 REG_AFE_LDO_CTRL (Offset 0x0020) */
+
+#define BIT_LPLDH12_SLP BIT(28)
+
+#define BIT_SHIFT_LPLDH12_VADJ 24
+#define BIT_MASK_LPLDH12_VADJ 0xf
+#define BIT_LPLDH12_VADJ(x) \
+ (((x) & BIT_MASK_LPLDH12_VADJ) << BIT_SHIFT_LPLDH12_VADJ)
+#define BIT_GET_LPLDH12_VADJ(x) \
+ (((x) >> BIT_SHIFT_LPLDH12_VADJ) & BIT_MASK_LPLDH12_VADJ)
+
+/* 2 REG_AFE_LDO_CTRL (Offset 0x0020) */
+
+#define BIT_LDH12_EN BIT(16)
+
+/* 2 REG_SDIO_FREE_TXPG (Offset 0x10250020) */
+
+#define BIT_SHIFT_MID_FREEPG_V1 16
+#define BIT_MASK_MID_FREEPG_V1 0xfff
+#define BIT_MID_FREEPG_V1(x) \
+ (((x) & BIT_MASK_MID_FREEPG_V1) << BIT_SHIFT_MID_FREEPG_V1)
+#define BIT_GET_MID_FREEPG_V1(x) \
+ (((x) >> BIT_SHIFT_MID_FREEPG_V1) & BIT_MASK_MID_FREEPG_V1)
+
+/* 2 REG_AFE_LDO_CTRL (Offset 0x0020) */
+
+#define BIT_WLBBOFF_BIG_PWC_EN BIT(14)
+#define BIT_WLBBOFF_SMALL_PWC_EN BIT(13)
+#define BIT_WLMACOFF_BIG_PWC_EN BIT(12)
+#define BIT_WLPON_PWC_EN BIT(11)
+
+/* 2 REG_AFE_LDO_CTRL (Offset 0x0020) */
+
+#define BIT_POW_REGU_P1 BIT(10)
+
+/* 2 REG_AFE_LDO_CTRL (Offset 0x0020) */
+
+#define BIT_LDOV12W_EN BIT(8)
+
+/* 2 REG_AFE_LDO_CTRL (Offset 0x0020) */
+
+#define BIT_EX_XTAL_DRV_DIGI BIT(7)
+#define BIT_EX_XTAL_DRV_USB BIT(6)
+#define BIT_EX_XTAL_DRV_AFE BIT(5)
+
+/* 2 REG_AFE_LDO_CTRL (Offset 0x0020) */
+
+#define BIT_EX_XTAL_DRV_RF2 BIT(4)
+
+/* 2 REG_AFE_LDO_CTRL (Offset 0x0020) */
+
+#define BIT_EX_XTAL_DRV_RF1 BIT(3)
+#define BIT_POW_REGU_P0 BIT(2)
+
+/* 2 REG_AFE_LDO_CTRL (Offset 0x0020) */
+
+#define BIT_POW_PLL_LDO BIT(0)
+
+/* 2 REG_SDIO_FREE_TXPG (Offset 0x10250020) */
+
+#define BIT_SHIFT_HIQ_FREEPG_V1 0
+#define BIT_MASK_HIQ_FREEPG_V1 0xfff
+#define BIT_HIQ_FREEPG_V1(x) \
+ (((x) & BIT_MASK_HIQ_FREEPG_V1) << BIT_SHIFT_HIQ_FREEPG_V1)
+#define BIT_GET_HIQ_FREEPG_V1(x) \
+ (((x) >> BIT_SHIFT_HIQ_FREEPG_V1) & BIT_MASK_HIQ_FREEPG_V1)
+
+/* 2 REG_AFE_CTRL1 (Offset 0x0024) */
+
+#define BIT_AGPIO_GPE BIT(31)
+
+/* 2 REG_AFE_CTRL1 (Offset 0x0024) */
+
+#define BIT_SHIFT_XTAL_CAP_XI 25
+#define BIT_MASK_XTAL_CAP_XI 0x3f
+#define BIT_XTAL_CAP_XI(x) \
+ (((x) & BIT_MASK_XTAL_CAP_XI) << BIT_SHIFT_XTAL_CAP_XI)
+#define BIT_GET_XTAL_CAP_XI(x) \
+ (((x) >> BIT_SHIFT_XTAL_CAP_XI) & BIT_MASK_XTAL_CAP_XI)
+
+/* 2 REG_AFE_CTRL1 (Offset 0x0024) */
+
+#define BIT_SHIFT_XTAL_DRV_DIGI 23
+#define BIT_MASK_XTAL_DRV_DIGI 0x3
+#define BIT_XTAL_DRV_DIGI(x) \
+ (((x) & BIT_MASK_XTAL_DRV_DIGI) << BIT_SHIFT_XTAL_DRV_DIGI)
+#define BIT_GET_XTAL_DRV_DIGI(x) \
+ (((x) >> BIT_SHIFT_XTAL_DRV_DIGI) & BIT_MASK_XTAL_DRV_DIGI)
+
+#define BIT_XTAL_DRV_USB_BIT1 BIT(22)
+
+/* 2 REG_AFE_CTRL1 (Offset 0x0024) */
+
+#define BIT_SHIFT_MAC_CLK_SEL 20
+#define BIT_MASK_MAC_CLK_SEL 0x3
+#define BIT_MAC_CLK_SEL(x) \
+ (((x) & BIT_MASK_MAC_CLK_SEL) << BIT_SHIFT_MAC_CLK_SEL)
+#define BIT_GET_MAC_CLK_SEL(x) \
+ (((x) >> BIT_SHIFT_MAC_CLK_SEL) & BIT_MASK_MAC_CLK_SEL)
+
+/* 2 REG_AFE_CTRL1 (Offset 0x0024) */
+
+#define BIT_XTAL_DRV_USB_BIT0 BIT(19)
+
+/* 2 REG_AFE_CTRL1 (Offset 0x0024) */
+
+#define BIT_SHIFT_XTAL_DRV_AFE 17
+#define BIT_MASK_XTAL_DRV_AFE 0x3
+#define BIT_XTAL_DRV_AFE(x) \
+ (((x) & BIT_MASK_XTAL_DRV_AFE) << BIT_SHIFT_XTAL_DRV_AFE)
+#define BIT_GET_XTAL_DRV_AFE(x) \
+ (((x) >> BIT_SHIFT_XTAL_DRV_AFE) & BIT_MASK_XTAL_DRV_AFE)
+
+/* 2 REG_SDIO_FREE_TXPG2 (Offset 0x10250024) */
+
+#define BIT_SHIFT_PUB_FREEPG_V1 16
+#define BIT_MASK_PUB_FREEPG_V1 0xfff
+#define BIT_PUB_FREEPG_V1(x) \
+ (((x) & BIT_MASK_PUB_FREEPG_V1) << BIT_SHIFT_PUB_FREEPG_V1)
+#define BIT_GET_PUB_FREEPG_V1(x) \
+ (((x) >> BIT_SHIFT_PUB_FREEPG_V1) & BIT_MASK_PUB_FREEPG_V1)
+
+/* 2 REG_AFE_CTRL1 (Offset 0x0024) */
+
+#define BIT_SHIFT_XTAL_DRV_RF2 15
+#define BIT_MASK_XTAL_DRV_RF2 0x3
+#define BIT_XTAL_DRV_RF2(x) \
+ (((x) & BIT_MASK_XTAL_DRV_RF2) << BIT_SHIFT_XTAL_DRV_RF2)
+#define BIT_GET_XTAL_DRV_RF2(x) \
+ (((x) >> BIT_SHIFT_XTAL_DRV_RF2) & BIT_MASK_XTAL_DRV_RF2)
+
+/* 2 REG_AFE_CTRL1 (Offset 0x0024) */
+
+#define BIT_SHIFT_XTAL_DRV_RF1 13
+#define BIT_MASK_XTAL_DRV_RF1 0x3
+#define BIT_XTAL_DRV_RF1(x) \
+ (((x) & BIT_MASK_XTAL_DRV_RF1) << BIT_SHIFT_XTAL_DRV_RF1)
+#define BIT_GET_XTAL_DRV_RF1(x) \
+ (((x) >> BIT_SHIFT_XTAL_DRV_RF1) & BIT_MASK_XTAL_DRV_RF1)
+
+/* 2 REG_AFE_CTRL1 (Offset 0x0024) */
+
+#define BIT_XTAL_DELAY_DIGI BIT(12)
+
+/* 2 REG_AFE_CTRL1 (Offset 0x0024) */
+
+#define BIT_XTAL_DELAY_USB BIT(11)
+#define BIT_XTAL_DELAY_AFE BIT(10)
+
+/* 2 REG_AFE_CTRL1 (Offset 0x0024) */
+
+#define BIT_SHIFT_XTAL_LDO_VREF 7
+#define BIT_MASK_XTAL_LDO_VREF 0x7
+#define BIT_XTAL_LDO_VREF(x) \
+ (((x) & BIT_MASK_XTAL_LDO_VREF) << BIT_SHIFT_XTAL_LDO_VREF)
+#define BIT_GET_XTAL_LDO_VREF(x) \
+ (((x) >> BIT_SHIFT_XTAL_LDO_VREF) & BIT_MASK_XTAL_LDO_VREF)
+
+/* 2 REG_AFE_CTRL1 (Offset 0x0024) */
+
+#define BIT_XTAL_XQSEL_RF BIT(6)
+#define BIT_XTAL_XQSEL BIT(5)
+
+/* 2 REG_AFE_CTRL1 (Offset 0x0024) */
+
+#define BIT_SHIFT_XTAL_GMN_V2 3
+#define BIT_MASK_XTAL_GMN_V2 0x3
+#define BIT_XTAL_GMN_V2(x) \
+ (((x) & BIT_MASK_XTAL_GMN_V2) << BIT_SHIFT_XTAL_GMN_V2)
+#define BIT_GET_XTAL_GMN_V2(x) \
+ (((x) >> BIT_SHIFT_XTAL_GMN_V2) & BIT_MASK_XTAL_GMN_V2)
+
+/* 2 REG_AFE_CTRL1 (Offset 0x0024) */
+
+#define BIT_SHIFT_XTAL_GMP_V2 1
+#define BIT_MASK_XTAL_GMP_V2 0x3
+#define BIT_XTAL_GMP_V2(x) \
+ (((x) & BIT_MASK_XTAL_GMP_V2) << BIT_SHIFT_XTAL_GMP_V2)
+#define BIT_GET_XTAL_GMP_V2(x) \
+ (((x) >> BIT_SHIFT_XTAL_GMP_V2) & BIT_MASK_XTAL_GMP_V2)
+
+/* 2 REG_AFE_CTRL1 (Offset 0x0024) */
+
+#define BIT_XTAL_EN BIT(0)
+
+/* 2 REG_SDIO_FREE_TXPG2 (Offset 0x10250024) */
+
+#define BIT_SHIFT_LOW_FREEPG_V1 0
+#define BIT_MASK_LOW_FREEPG_V1 0xfff
+#define BIT_LOW_FREEPG_V1(x) \
+ (((x) & BIT_MASK_LOW_FREEPG_V1) << BIT_SHIFT_LOW_FREEPG_V1)
+#define BIT_GET_LOW_FREEPG_V1(x) \
+ (((x) >> BIT_SHIFT_LOW_FREEPG_V1) & BIT_MASK_LOW_FREEPG_V1)
+
+/* 2 REG_AFE_CTRL2 (Offset 0x0028) */
+
+#define BIT_SHIFT_REG_C3_V4 30
+#define BIT_MASK_REG_C3_V4 0x3
+#define BIT_REG_C3_V4(x) (((x) & BIT_MASK_REG_C3_V4) << BIT_SHIFT_REG_C3_V4)
+#define BIT_GET_REG_C3_V4(x) (((x) >> BIT_SHIFT_REG_C3_V4) & BIT_MASK_REG_C3_V4)
+
+#define BIT_REG_CP_BIT1 BIT(29)
+
+/* 2 REG_AFE_CTRL2 (Offset 0x0028) */
+
+#define BIT_SHIFT_REG_RS_V4 26
+#define BIT_MASK_REG_RS_V4 0x7
+#define BIT_REG_RS_V4(x) (((x) & BIT_MASK_REG_RS_V4) << BIT_SHIFT_REG_RS_V4)
+#define BIT_GET_REG_RS_V4(x) (((x) >> BIT_SHIFT_REG_RS_V4) & BIT_MASK_REG_RS_V4)
+
+/* 2 REG_SDIO_OQT_FREE_TXPG_V1 (Offset 0x10250028) */
+
+#define BIT_SHIFT_NOAC_OQT_FREEPG_V1 24
+#define BIT_MASK_NOAC_OQT_FREEPG_V1 0xff
+#define BIT_NOAC_OQT_FREEPG_V1(x) \
+ (((x) & BIT_MASK_NOAC_OQT_FREEPG_V1) << BIT_SHIFT_NOAC_OQT_FREEPG_V1)
+#define BIT_GET_NOAC_OQT_FREEPG_V1(x) \
+ (((x) >> BIT_SHIFT_NOAC_OQT_FREEPG_V1) & BIT_MASK_NOAC_OQT_FREEPG_V1)
+
+/* 2 REG_AFE_CTRL2 (Offset 0x0028) */
+
+#define BIT_SHIFT_REG__CS 24
+#define BIT_MASK_REG__CS 0x3
+#define BIT_REG__CS(x) (((x) & BIT_MASK_REG__CS) << BIT_SHIFT_REG__CS)
+#define BIT_GET_REG__CS(x) (((x) >> BIT_SHIFT_REG__CS) & BIT_MASK_REG__CS)
+
+/* 2 REG_AFE_CTRL2 (Offset 0x0028) */
+
+#define BIT_SHIFT_REG_CP_OFFSET 21
+#define BIT_MASK_REG_CP_OFFSET 0x7
+#define BIT_REG_CP_OFFSET(x) \
+ (((x) & BIT_MASK_REG_CP_OFFSET) << BIT_SHIFT_REG_CP_OFFSET)
+#define BIT_GET_REG_CP_OFFSET(x) \
+ (((x) >> BIT_SHIFT_REG_CP_OFFSET) & BIT_MASK_REG_CP_OFFSET)
+
+/* 2 REG_AFE_CTRL2 (Offset 0x0028) */
+
+#define BIT_SHIFT_CP_BIAS 18
+#define BIT_MASK_CP_BIAS 0x7
+#define BIT_CP_BIAS(x) (((x) & BIT_MASK_CP_BIAS) << BIT_SHIFT_CP_BIAS)
+#define BIT_GET_CP_BIAS(x) (((x) >> BIT_SHIFT_CP_BIAS) & BIT_MASK_CP_BIAS)
+
+/* 2 REG_AFE_CTRL2 (Offset 0x0028) */
+
+#define BIT_REG_IDOUBLE_V2 BIT(17)
+
+/* 2 REG_AFE_CTRL2 (Offset 0x0028) */
+
+#define BIT_EN_SYN BIT(16)
+
+#define BIT_SHIFT_AC_OQT_FREEPG_V1 16
+#define BIT_MASK_AC_OQT_FREEPG_V1 0xff
+#define BIT_AC_OQT_FREEPG_V1(x) \
+ (((x) & BIT_MASK_AC_OQT_FREEPG_V1) << BIT_SHIFT_AC_OQT_FREEPG_V1)
+#define BIT_GET_AC_OQT_FREEPG_V1(x) \
+ (((x) >> BIT_SHIFT_AC_OQT_FREEPG_V1) & BIT_MASK_AC_OQT_FREEPG_V1)
+
+/* 2 REG_AFE_CTRL2 (Offset 0x0028) */
+
+#define BIT_SHIFT_MCCO 14
+#define BIT_MASK_MCCO 0x3
+#define BIT_MCCO(x) (((x) & BIT_MASK_MCCO) << BIT_SHIFT_MCCO)
+#define BIT_GET_MCCO(x) (((x) >> BIT_SHIFT_MCCO) & BIT_MASK_MCCO)
+
+/* 2 REG_AFE_CTRL2 (Offset 0x0028) */
+
+#define BIT_SHIFT_REG_LDO_SEL 12
+#define BIT_MASK_REG_LDO_SEL 0x3
+#define BIT_REG_LDO_SEL(x) \
+ (((x) & BIT_MASK_REG_LDO_SEL) << BIT_SHIFT_REG_LDO_SEL)
+#define BIT_GET_REG_LDO_SEL(x) \
+ (((x) >> BIT_SHIFT_REG_LDO_SEL) & BIT_MASK_REG_LDO_SEL)
+
+#define BIT_REG_KVCO_V2 BIT(10)
+
+/* 2 REG_AFE_CTRL2 (Offset 0x0028) */
+
+#define BIT_AGPIO_GPO BIT(9)
+
+/* 2 REG_AFE_CTRL2 (Offset 0x0028) */
+
+#define BIT_SHIFT_AGPIO_DRV 7
+#define BIT_MASK_AGPIO_DRV 0x3
+#define BIT_AGPIO_DRV(x) (((x) & BIT_MASK_AGPIO_DRV) << BIT_SHIFT_AGPIO_DRV)
+#define BIT_GET_AGPIO_DRV(x) (((x) >> BIT_SHIFT_AGPIO_DRV) & BIT_MASK_AGPIO_DRV)
+
+/* 2 REG_AFE_CTRL2 (Offset 0x0028) */
+
+#define BIT_SHIFT_XTAL_CAP_XO 1
+#define BIT_MASK_XTAL_CAP_XO 0x3f
+#define BIT_XTAL_CAP_XO(x) \
+ (((x) & BIT_MASK_XTAL_CAP_XO) << BIT_SHIFT_XTAL_CAP_XO)
+#define BIT_GET_XTAL_CAP_XO(x) \
+ (((x) >> BIT_SHIFT_XTAL_CAP_XO) & BIT_MASK_XTAL_CAP_XO)
+
+/* 2 REG_AFE_CTRL2 (Offset 0x0028) */
+
+#define BIT_POW_PLL BIT(0)
+
+/* 2 REG_SDIO_OQT_FREE_TXPG_V1 (Offset 0x10250028) */
+
+#define BIT_SHIFT_EXQ_FREEPG_V1 0
+#define BIT_MASK_EXQ_FREEPG_V1 0xfff
+#define BIT_EXQ_FREEPG_V1(x) \
+ (((x) & BIT_MASK_EXQ_FREEPG_V1) << BIT_SHIFT_EXQ_FREEPG_V1)
+#define BIT_GET_EXQ_FREEPG_V1(x) \
+ (((x) >> BIT_SHIFT_EXQ_FREEPG_V1) & BIT_MASK_EXQ_FREEPG_V1)
+
+/* 2 REG_AFE_CTRL3 (Offset 0x002C) */
+
+#define BIT_SHIFT_PS 7
+#define BIT_MASK_PS 0x7
+#define BIT_PS(x) (((x) & BIT_MASK_PS) << BIT_SHIFT_PS)
+#define BIT_GET_PS(x) (((x) >> BIT_SHIFT_PS) & BIT_MASK_PS)
+
+/* 2 REG_AFE_CTRL3 (Offset 0x002C) */
+
+#define BIT_PSEN BIT(6)
+#define BIT_DOGENB BIT(5)
+
+/* 2 REG_AFE_CTRL3 (Offset 0x002C) */
+
+#define BIT_REG_MBIAS BIT(4)
+
+/* 2 REG_AFE_CTRL3 (Offset 0x002C) */
+
+#define BIT_SHIFT_REG_R3_V4 1
+#define BIT_MASK_REG_R3_V4 0x7
+#define BIT_REG_R3_V4(x) (((x) & BIT_MASK_REG_R3_V4) << BIT_SHIFT_REG_R3_V4)
+#define BIT_GET_REG_R3_V4(x) (((x) >> BIT_SHIFT_REG_R3_V4) & BIT_MASK_REG_R3_V4)
+
+/* 2 REG_AFE_CTRL3 (Offset 0x002C) */
+
+#define BIT_REG_CP_BIT0 BIT(0)
+
+/* 2 REG_EFUSE_CTRL (Offset 0x0030) */
+
+#define BIT_EF_FLAG BIT(31)
+
+#define BIT_SHIFT_EF_PGPD 28
+#define BIT_MASK_EF_PGPD 0x7
+#define BIT_EF_PGPD(x) (((x) & BIT_MASK_EF_PGPD) << BIT_SHIFT_EF_PGPD)
+#define BIT_GET_EF_PGPD(x) (((x) >> BIT_SHIFT_EF_PGPD) & BIT_MASK_EF_PGPD)
+
+#define BIT_SHIFT_EF_RDT 24
+#define BIT_MASK_EF_RDT 0xf
+#define BIT_EF_RDT(x) (((x) & BIT_MASK_EF_RDT) << BIT_SHIFT_EF_RDT)
+#define BIT_GET_EF_RDT(x) (((x) >> BIT_SHIFT_EF_RDT) & BIT_MASK_EF_RDT)
+
+#define BIT_SHIFT_EF_PGTS 20
+#define BIT_MASK_EF_PGTS 0xf
+#define BIT_EF_PGTS(x) (((x) & BIT_MASK_EF_PGTS) << BIT_SHIFT_EF_PGTS)
+#define BIT_GET_EF_PGTS(x) (((x) >> BIT_SHIFT_EF_PGTS) & BIT_MASK_EF_PGTS)
+
+/* 2 REG_EFUSE_CTRL (Offset 0x0030) */
+
+#define BIT_EF_PDWN BIT(19)
+
+/* 2 REG_EFUSE_CTRL (Offset 0x0030) */
+
+#define BIT_EF_ALDEN BIT(18)
+
+/* 2 REG_SDIO_HTSFR_INFO (Offset 0x10250030) */
+
+#define BIT_SHIFT_HTSFR1 16
+#define BIT_MASK_HTSFR1 0xffff
+#define BIT_HTSFR1(x) (((x) & BIT_MASK_HTSFR1) << BIT_SHIFT_HTSFR1)
+#define BIT_GET_HTSFR1(x) (((x) >> BIT_SHIFT_HTSFR1) & BIT_MASK_HTSFR1)
+
+/* 2 REG_EFUSE_CTRL (Offset 0x0030) */
+
+#define BIT_SHIFT_EF_ADDR 8
+#define BIT_MASK_EF_ADDR 0x3ff
+#define BIT_EF_ADDR(x) (((x) & BIT_MASK_EF_ADDR) << BIT_SHIFT_EF_ADDR)
+#define BIT_GET_EF_ADDR(x) (((x) >> BIT_SHIFT_EF_ADDR) & BIT_MASK_EF_ADDR)
+
+#define BIT_SHIFT_EF_DATA 0
+#define BIT_MASK_EF_DATA 0xff
+#define BIT_EF_DATA(x) (((x) & BIT_MASK_EF_DATA) << BIT_SHIFT_EF_DATA)
+#define BIT_GET_EF_DATA(x) (((x) >> BIT_SHIFT_EF_DATA) & BIT_MASK_EF_DATA)
+
+/* 2 REG_SDIO_HTSFR_INFO (Offset 0x10250030) */
+
+#define BIT_SHIFT_HTSFR0 0
+#define BIT_MASK_HTSFR0 0xffff
+#define BIT_HTSFR0(x) (((x) & BIT_MASK_HTSFR0) << BIT_SHIFT_HTSFR0)
+#define BIT_GET_HTSFR0(x) (((x) >> BIT_SHIFT_HTSFR0) & BIT_MASK_HTSFR0)
+
+/* 2 REG_LDO_EFUSE_CTRL (Offset 0x0034) */
+
+#define BIT_LDOE25_EN BIT(31)
+
+/* 2 REG_LDO_EFUSE_CTRL (Offset 0x0034) */
+
+#define BIT_SHIFT_LDOE25_V12ADJ_L 27
+#define BIT_MASK_LDOE25_V12ADJ_L 0xf
+#define BIT_LDOE25_V12ADJ_L(x) \
+ (((x) & BIT_MASK_LDOE25_V12ADJ_L) << BIT_SHIFT_LDOE25_V12ADJ_L)
+#define BIT_GET_LDOE25_V12ADJ_L(x) \
+ (((x) >> BIT_SHIFT_LDOE25_V12ADJ_L) & BIT_MASK_LDOE25_V12ADJ_L)
+
+/* 2 REG_LDO_EFUSE_CTRL (Offset 0x0034) */
+
+#define BIT_EF_CRES_SEL BIT(26)
+
+/* 2 REG_LDO_EFUSE_CTRL (Offset 0x0034) */
+
+#define BIT_SHIFT_EF_SCAN_START_V1 16
+#define BIT_MASK_EF_SCAN_START_V1 0x3ff
+#define BIT_EF_SCAN_START_V1(x) \
+ (((x) & BIT_MASK_EF_SCAN_START_V1) << BIT_SHIFT_EF_SCAN_START_V1)
+#define BIT_GET_EF_SCAN_START_V1(x) \
+ (((x) >> BIT_SHIFT_EF_SCAN_START_V1) & BIT_MASK_EF_SCAN_START_V1)
+
+/* 2 REG_LDO_EFUSE_CTRL (Offset 0x0034) */
+
+#define BIT_SHIFT_EF_SCAN_END 12
+#define BIT_MASK_EF_SCAN_END 0xf
+#define BIT_EF_SCAN_END(x) \
+ (((x) & BIT_MASK_EF_SCAN_END) << BIT_SHIFT_EF_SCAN_END)
+#define BIT_GET_EF_SCAN_END(x) \
+ (((x) >> BIT_SHIFT_EF_SCAN_END) & BIT_MASK_EF_SCAN_END)
+
+/* 2 REG_LDO_EFUSE_CTRL (Offset 0x0034) */
+
+#define BIT_EF_PD_DIS BIT(11)
+
+/* 2 REG_LDO_EFUSE_CTRL (Offset 0x0034) */
+
+#define BIT_SHIFT_EF_CELL_SEL 8
+#define BIT_MASK_EF_CELL_SEL 0x3
+#define BIT_EF_CELL_SEL(x) \
+ (((x) & BIT_MASK_EF_CELL_SEL) << BIT_SHIFT_EF_CELL_SEL)
+#define BIT_GET_EF_CELL_SEL(x) \
+ (((x) >> BIT_SHIFT_EF_CELL_SEL) & BIT_MASK_EF_CELL_SEL)
+
+/* 2 REG_LDO_EFUSE_CTRL (Offset 0x0034) */
+
+#define BIT_EF_TRPT BIT(7)
+
+#define BIT_SHIFT_EF_TTHD 0
+#define BIT_MASK_EF_TTHD 0x7f
+#define BIT_EF_TTHD(x) (((x) & BIT_MASK_EF_TTHD) << BIT_SHIFT_EF_TTHD)
+#define BIT_GET_EF_TTHD(x) (((x) >> BIT_SHIFT_EF_TTHD) & BIT_MASK_EF_TTHD)
+
+/* 2 REG_PWR_OPTION_CTRL (Offset 0x0038) */
+
+#define BIT_SHIFT_DBG_SEL_V1 16
+#define BIT_MASK_DBG_SEL_V1 0xff
+#define BIT_DBG_SEL_V1(x) (((x) & BIT_MASK_DBG_SEL_V1) << BIT_SHIFT_DBG_SEL_V1)
+#define BIT_GET_DBG_SEL_V1(x) \
+ (((x) >> BIT_SHIFT_DBG_SEL_V1) & BIT_MASK_DBG_SEL_V1)
+
+/* 2 REG_PWR_OPTION_CTRL (Offset 0x0038) */
+
+#define BIT_SHIFT_DBG_SEL_BYTE 14
+#define BIT_MASK_DBG_SEL_BYTE 0x3
+#define BIT_DBG_SEL_BYTE(x) \
+ (((x) & BIT_MASK_DBG_SEL_BYTE) << BIT_SHIFT_DBG_SEL_BYTE)
+#define BIT_GET_DBG_SEL_BYTE(x) \
+ (((x) >> BIT_SHIFT_DBG_SEL_BYTE) & BIT_MASK_DBG_SEL_BYTE)
+
+/* 2 REG_PWR_OPTION_CTRL (Offset 0x0038) */
+
+#define BIT_SHIFT_STD_L1_V1 12
+#define BIT_MASK_STD_L1_V1 0x3
+#define BIT_STD_L1_V1(x) (((x) & BIT_MASK_STD_L1_V1) << BIT_SHIFT_STD_L1_V1)
+#define BIT_GET_STD_L1_V1(x) (((x) >> BIT_SHIFT_STD_L1_V1) & BIT_MASK_STD_L1_V1)
+
+/* 2 REG_PWR_OPTION_CTRL (Offset 0x0038) */
+
+#define BIT_SYSON_DBG_PAD_E2 BIT(11)
+
+/* 2 REG_PWR_OPTION_CTRL (Offset 0x0038) */
+
+#define BIT_SYSON_LED_PAD_E2 BIT(10)
+
+/* 2 REG_PWR_OPTION_CTRL (Offset 0x0038) */
+
+#define BIT_SYSON_GPEE_PAD_E2 BIT(9)
+
+/* 2 REG_PWR_OPTION_CTRL (Offset 0x0038) */
+
+#define BIT_SYSON_PCI_PAD_E2 BIT(8)
+
+#define BIT_SHIFT_MATCH_CNT 8
+#define BIT_MASK_MATCH_CNT 0xff
+#define BIT_MATCH_CNT(x) (((x) & BIT_MASK_MATCH_CNT) << BIT_SHIFT_MATCH_CNT)
+#define BIT_GET_MATCH_CNT(x) (((x) >> BIT_SHIFT_MATCH_CNT) & BIT_MASK_MATCH_CNT)
+
+/* 2 REG_PWR_OPTION_CTRL (Offset 0x0038) */
+
+#define BIT_AUTO_SW_LDO_VOL_EN BIT(7)
+
+/* 2 REG_PWR_OPTION_CTRL (Offset 0x0038) */
+
+#define BIT_SHIFT_SYSON_SPS0WWV_WT 4
+#define BIT_MASK_SYSON_SPS0WWV_WT 0x3
+#define BIT_SYSON_SPS0WWV_WT(x) \
+ (((x) & BIT_MASK_SYSON_SPS0WWV_WT) << BIT_SHIFT_SYSON_SPS0WWV_WT)
+#define BIT_GET_SYSON_SPS0WWV_WT(x) \
+ (((x) >> BIT_SHIFT_SYSON_SPS0WWV_WT) & BIT_MASK_SYSON_SPS0WWV_WT)
+
+/* 2 REG_PWR_OPTION_CTRL (Offset 0x0038) */
+
+#define BIT_SHIFT_SYSON_SPS0LDO_WT 2
+#define BIT_MASK_SYSON_SPS0LDO_WT 0x3
+#define BIT_SYSON_SPS0LDO_WT(x) \
+ (((x) & BIT_MASK_SYSON_SPS0LDO_WT) << BIT_SHIFT_SYSON_SPS0LDO_WT)
+#define BIT_GET_SYSON_SPS0LDO_WT(x) \
+ (((x) >> BIT_SHIFT_SYSON_SPS0LDO_WT) & BIT_MASK_SYSON_SPS0LDO_WT)
+
+/* 2 REG_PWR_OPTION_CTRL (Offset 0x0038) */
+
+#define BIT_SHIFT_SYSON_RCLK_SCALE 0
+#define BIT_MASK_SYSON_RCLK_SCALE 0x3
+#define BIT_SYSON_RCLK_SCALE(x) \
+ (((x) & BIT_MASK_SYSON_RCLK_SCALE) << BIT_SHIFT_SYSON_RCLK_SCALE)
+#define BIT_GET_SYSON_RCLK_SCALE(x) \
+ (((x) >> BIT_SHIFT_SYSON_RCLK_SCALE) & BIT_MASK_SYSON_RCLK_SCALE)
+
+/* 2 REG_SDIO_HCPWM1_V2 (Offset 0x10250038) */
+
+#define BIT_SYS_CLK BIT(0)
+
+/* 2 REG_CAL_TIMER (Offset 0x003C) */
+
+#define BIT_SHIFT_CAL_SCAL 0
+#define BIT_MASK_CAL_SCAL 0xff
+#define BIT_CAL_SCAL(x) (((x) & BIT_MASK_CAL_SCAL) << BIT_SHIFT_CAL_SCAL)
+#define BIT_GET_CAL_SCAL(x) (((x) >> BIT_SHIFT_CAL_SCAL) & BIT_MASK_CAL_SCAL)
+
+/* 2 REG_ACLK_MON (Offset 0x003E) */
+
+#define BIT_SHIFT_RCLK_MON 5
+#define BIT_MASK_RCLK_MON 0x7ff
+#define BIT_RCLK_MON(x) (((x) & BIT_MASK_RCLK_MON) << BIT_SHIFT_RCLK_MON)
+#define BIT_GET_RCLK_MON(x) (((x) >> BIT_SHIFT_RCLK_MON) & BIT_MASK_RCLK_MON)
+
+#define BIT_CAL_EN BIT(4)
+
+#define BIT_SHIFT_DPSTU 2
+#define BIT_MASK_DPSTU 0x3
+#define BIT_DPSTU(x) (((x) & BIT_MASK_DPSTU) << BIT_SHIFT_DPSTU)
+#define BIT_GET_DPSTU(x) (((x) >> BIT_SHIFT_DPSTU) & BIT_MASK_DPSTU)
+
+#define BIT_SUS_16X BIT(1)
+
+/* 2 REG_SDIO_INDIRECT_REG_CFG (Offset 0x10250040) */
+
+#define BIT_INDIRECT_REG_RDY BIT(20)
+
+/* 2 REG_GPIO_MUXCFG (Offset 0x0040) */
+
+#define BIT_FSPI_EN BIT(19)
+
+/* 2 REG_SDIO_INDIRECT_REG_CFG (Offset 0x10250040) */
+
+#define BIT_INDIRECT_REG_R BIT(19)
+
+/* 2 REG_GPIO_MUXCFG (Offset 0x0040) */
+
+#define BIT_WL_RTS_EXT_32K_SEL BIT(18)
+
+/* 2 REG_SDIO_INDIRECT_REG_CFG (Offset 0x10250040) */
+
+#define BIT_INDIRECT_REG_W BIT(18)
+
+/* 2 REG_GPIO_MUXCFG (Offset 0x0040) */
+
+#define BIT_WLGP_SPI_EN BIT(16)
+
+/* 2 REG_SDIO_INDIRECT_REG_CFG (Offset 0x10250040) */
+
+#define BIT_SHIFT_INDIRECT_REG_SIZE 16
+#define BIT_MASK_INDIRECT_REG_SIZE 0x3
+#define BIT_INDIRECT_REG_SIZE(x) \
+ (((x) & BIT_MASK_INDIRECT_REG_SIZE) << BIT_SHIFT_INDIRECT_REG_SIZE)
+#define BIT_GET_INDIRECT_REG_SIZE(x) \
+ (((x) >> BIT_SHIFT_INDIRECT_REG_SIZE) & BIT_MASK_INDIRECT_REG_SIZE)
+
+/* 2 REG_GPIO_MUXCFG (Offset 0x0040) */
+
+#define BIT_SIC_LBK BIT(15)
+#define BIT_ENHTP BIT(14)
+
+/* 2 REG_GPIO_MUXCFG (Offset 0x0040) */
+
+#define BIT_ENSIC BIT(12)
+#define BIT_SIC_SWRST BIT(11)
+
+/* 2 REG_GPIO_MUXCFG (Offset 0x0040) */
+
+#define BIT_PO_WIFI_PTA_PINS BIT(10)
+
+/* 2 REG_GPIO_MUXCFG (Offset 0x0040) */
+
+#define BIT_PO_BT_PTA_PINS BIT(9)
+
+/* 2 REG_GPIO_MUXCFG (Offset 0x0040) */
+
+#define BIT_ENUART BIT(8)
+
+#define BIT_SHIFT_BTMODE 6
+#define BIT_MASK_BTMODE 0x3
+#define BIT_BTMODE(x) (((x) & BIT_MASK_BTMODE) << BIT_SHIFT_BTMODE)
+#define BIT_GET_BTMODE(x) (((x) >> BIT_SHIFT_BTMODE) & BIT_MASK_BTMODE)
+
+#define BIT_ENBT BIT(5)
+#define BIT_EROM_EN BIT(4)
+
+/* 2 REG_GPIO_MUXCFG (Offset 0x0040) */
+
+#define BIT_WLRFE_6_7_EN BIT(3)
+
+/* 2 REG_GPIO_MUXCFG (Offset 0x0040) */
+
+#define BIT_WLRFE_4_5_EN BIT(2)
+
+/* 2 REG_GPIO_MUXCFG (Offset 0x0040) */
+
+#define BIT_SHIFT_GPIOSEL 0
+#define BIT_MASK_GPIOSEL 0x3
+#define BIT_GPIOSEL(x) (((x) & BIT_MASK_GPIOSEL) << BIT_SHIFT_GPIOSEL)
+#define BIT_GET_GPIOSEL(x) (((x) >> BIT_SHIFT_GPIOSEL) & BIT_MASK_GPIOSEL)
+
+/* 2 REG_SDIO_INDIRECT_REG_CFG (Offset 0x10250040) */
+
+#define BIT_SHIFT_INDIRECT_REG_ADDR 0
+#define BIT_MASK_INDIRECT_REG_ADDR 0xffff
+#define BIT_INDIRECT_REG_ADDR(x) \
+ (((x) & BIT_MASK_INDIRECT_REG_ADDR) << BIT_SHIFT_INDIRECT_REG_ADDR)
+#define BIT_GET_INDIRECT_REG_ADDR(x) \
+ (((x) >> BIT_SHIFT_INDIRECT_REG_ADDR) & BIT_MASK_INDIRECT_REG_ADDR)
+
+/* 2 REG_GPIO_PIN_CTRL (Offset 0x0044) */
+
+#define BIT_SHIFT_GPIO_MOD_7_TO_0 24
+#define BIT_MASK_GPIO_MOD_7_TO_0 0xff
+#define BIT_GPIO_MOD_7_TO_0(x) \
+ (((x) & BIT_MASK_GPIO_MOD_7_TO_0) << BIT_SHIFT_GPIO_MOD_7_TO_0)
+#define BIT_GET_GPIO_MOD_7_TO_0(x) \
+ (((x) >> BIT_SHIFT_GPIO_MOD_7_TO_0) & BIT_MASK_GPIO_MOD_7_TO_0)
+
+#define BIT_SHIFT_GPIO_IO_SEL_7_TO_0 16
+#define BIT_MASK_GPIO_IO_SEL_7_TO_0 0xff
+#define BIT_GPIO_IO_SEL_7_TO_0(x) \
+ (((x) & BIT_MASK_GPIO_IO_SEL_7_TO_0) << BIT_SHIFT_GPIO_IO_SEL_7_TO_0)
+#define BIT_GET_GPIO_IO_SEL_7_TO_0(x) \
+ (((x) >> BIT_SHIFT_GPIO_IO_SEL_7_TO_0) & BIT_MASK_GPIO_IO_SEL_7_TO_0)
+
+#define BIT_SHIFT_GPIO_OUT_7_TO_0 8
+#define BIT_MASK_GPIO_OUT_7_TO_0 0xff
+#define BIT_GPIO_OUT_7_TO_0(x) \
+ (((x) & BIT_MASK_GPIO_OUT_7_TO_0) << BIT_SHIFT_GPIO_OUT_7_TO_0)
+#define BIT_GET_GPIO_OUT_7_TO_0(x) \
+ (((x) >> BIT_SHIFT_GPIO_OUT_7_TO_0) & BIT_MASK_GPIO_OUT_7_TO_0)
+
+#define BIT_SHIFT_GPIO_IN_7_TO_0 0
+#define BIT_MASK_GPIO_IN_7_TO_0 0xff
+#define BIT_GPIO_IN_7_TO_0(x) \
+ (((x) & BIT_MASK_GPIO_IN_7_TO_0) << BIT_SHIFT_GPIO_IN_7_TO_0)
+#define BIT_GET_GPIO_IN_7_TO_0(x) \
+ (((x) >> BIT_SHIFT_GPIO_IN_7_TO_0) & BIT_MASK_GPIO_IN_7_TO_0)
+
+/* 2 REG_SDIO_INDIRECT_REG_DATA (Offset 0x10250044) */
+
+#define BIT_SHIFT_INDIRECT_REG_DATA 0
+#define BIT_MASK_INDIRECT_REG_DATA 0xffffffffL
+#define BIT_INDIRECT_REG_DATA(x) \
+ (((x) & BIT_MASK_INDIRECT_REG_DATA) << BIT_SHIFT_INDIRECT_REG_DATA)
+#define BIT_GET_INDIRECT_REG_DATA(x) \
+ (((x) >> BIT_SHIFT_INDIRECT_REG_DATA) & BIT_MASK_INDIRECT_REG_DATA)
+
+/* 2 REG_GPIO_INTM (Offset 0x0048) */
+
+#define BIT_SHIFT_MUXDBG_SEL 30
+#define BIT_MASK_MUXDBG_SEL 0x3
+#define BIT_MUXDBG_SEL(x) (((x) & BIT_MASK_MUXDBG_SEL) << BIT_SHIFT_MUXDBG_SEL)
+#define BIT_GET_MUXDBG_SEL(x) \
+ (((x) >> BIT_SHIFT_MUXDBG_SEL) & BIT_MASK_MUXDBG_SEL)
+
+/* 2 REG_GPIO_INTM (Offset 0x0048) */
+
+#define BIT_EXTWOL_SEL BIT(17)
+
+/* 2 REG_GPIO_INTM (Offset 0x0048) */
+
+#define BIT_EXTWOL_EN BIT(16)
+
+/* 2 REG_GPIO_INTM (Offset 0x0048) */
+
+#define BIT_GPIOF_INT_MD BIT(15)
+#define BIT_GPIOE_INT_MD BIT(14)
+#define BIT_GPIOD_INT_MD BIT(13)
+#define BIT_GPIOC_INT_MD BIT(12)
+#define BIT_GPIOB_INT_MD BIT(11)
+#define BIT_GPIOA_INT_MD BIT(10)
+#define BIT_GPIO9_INT_MD BIT(9)
+#define BIT_GPIO8_INT_MD BIT(8)
+#define BIT_GPIO7_INT_MD BIT(7)
+#define BIT_GPIO6_INT_MD BIT(6)
+#define BIT_GPIO5_INT_MD BIT(5)
+#define BIT_GPIO4_INT_MD BIT(4)
+#define BIT_GPIO3_INT_MD BIT(3)
+#define BIT_GPIO2_INT_MD BIT(2)
+#define BIT_GPIO1_INT_MD BIT(1)
+#define BIT_GPIO0_INT_MD BIT(0)
+
+/* 2 REG_LED_CFG (Offset 0x004C) */
+
+#define BIT_GPIO3_WL_CTRL_EN BIT(27)
+
+/* 2 REG_LED_CFG (Offset 0x004C) */
+
+#define BIT_LNAON_SEL_EN BIT(26)
+
+/* 2 REG_LED_CFG (Offset 0x004C) */
+
+#define BIT_PAPE_SEL_EN BIT(25)
+
+/* 2 REG_LED_CFG (Offset 0x004C) */
+
+#define BIT_DPDT_WLBT_SEL BIT(24)
+
+/* 2 REG_LED_CFG (Offset 0x004C) */
+
+#define BIT_DPDT_SEL_EN BIT(23)
+
+/* 2 REG_LED_CFG (Offset 0x004C) */
+
+#define BIT_GPIO13_14_WL_CTRL_EN BIT(22)
+
+/* 2 REG_LED_CFG (Offset 0x004C) */
+
+#define BIT_LED2DIS BIT(21)
+
+/* 2 REG_LED_CFG (Offset 0x004C) */
+
+#define BIT_LED2PL BIT(20)
+#define BIT_LED2SV BIT(19)
+
+#define BIT_SHIFT_LED2CM 16
+#define BIT_MASK_LED2CM 0x7
+#define BIT_LED2CM(x) (((x) & BIT_MASK_LED2CM) << BIT_SHIFT_LED2CM)
+#define BIT_GET_LED2CM(x) (((x) >> BIT_SHIFT_LED2CM) & BIT_MASK_LED2CM)
+
+#define BIT_LED1DIS BIT(15)
+#define BIT_LED1PL BIT(12)
+#define BIT_LED1SV BIT(11)
+
+#define BIT_SHIFT_LED1CM 8
+#define BIT_MASK_LED1CM 0x7
+#define BIT_LED1CM(x) (((x) & BIT_MASK_LED1CM) << BIT_SHIFT_LED1CM)
+#define BIT_GET_LED1CM(x) (((x) >> BIT_SHIFT_LED1CM) & BIT_MASK_LED1CM)
+
+#define BIT_LED0DIS BIT(7)
+
+/* 2 REG_LED_CFG (Offset 0x004C) */
+
+#define BIT_SHIFT_AFE_LDO_SWR_CHECK 5
+#define BIT_MASK_AFE_LDO_SWR_CHECK 0x3
+#define BIT_AFE_LDO_SWR_CHECK(x) \
+ (((x) & BIT_MASK_AFE_LDO_SWR_CHECK) << BIT_SHIFT_AFE_LDO_SWR_CHECK)
+#define BIT_GET_AFE_LDO_SWR_CHECK(x) \
+ (((x) >> BIT_SHIFT_AFE_LDO_SWR_CHECK) & BIT_MASK_AFE_LDO_SWR_CHECK)
+
+/* 2 REG_LED_CFG (Offset 0x004C) */
+
+#define BIT_LED0PL BIT(4)
+#define BIT_LED0SV BIT(3)
+
+#define BIT_SHIFT_LED0CM 0
+#define BIT_MASK_LED0CM 0x7
+#define BIT_LED0CM(x) (((x) & BIT_MASK_LED0CM) << BIT_SHIFT_LED0CM)
+#define BIT_GET_LED0CM(x) (((x) >> BIT_SHIFT_LED0CM) & BIT_MASK_LED0CM)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_FS_PDNINT_EN BIT(31)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_NFC_INT_PAD_EN BIT(30)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_FS_SPS_OCP_INT_EN BIT(29)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_FS_PWMERR_INT_EN BIT(28)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_FS_GPIOF_INT_EN BIT(27)
+#define BIT_FS_GPIOE_INT_EN BIT(26)
+#define BIT_FS_GPIOD_INT_EN BIT(25)
+#define BIT_FS_GPIOC_INT_EN BIT(24)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_FS_GPIOB_INT_EN BIT(23)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_FS_GPIOA_INT_EN BIT(22)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_FS_GPIO9_INT_EN BIT(21)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_FS_GPIO8_INT_EN BIT(20)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_FS_GPIO7_INT_EN BIT(19)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_FS_GPIO6_INT_EN BIT(18)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_FS_GPIO5_INT_EN BIT(17)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_FS_GPIO4_INT_EN BIT(16)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_FS_GPIO3_INT_EN BIT(15)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_FS_GPIO2_INT_EN BIT(14)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_FS_GPIO1_INT_EN BIT(13)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_FS_GPIO0_INT_EN BIT(12)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_FS_HCI_SUS_EN BIT(11)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_FS_HCI_RES_EN BIT(10)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_FS_HCI_RESET_EN BIT(9)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_FS_BTON_STS_UPDATE_MSK_EN BIT(7)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_ACT2RECOVERY_INT_EN_V1 BIT(6)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_GEN1GEN2_SWITCH BIT(5)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_HCI_TXDMA_REQ_HIMR BIT(4)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_FS_32K_LEAVE_SETTING_MAK BIT(3)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_FS_32K_ENTER_SETTING_MAK BIT(2)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_FS_USB_LPMRSM_MSK BIT(1)
+
+/* 2 REG_FSIMR (Offset 0x0050) */
+
+#define BIT_FS_USB_LPMINT_MSK BIT(0)
+
+/* 2 REG_FSISR (Offset 0x0054) */
+
+#define BIT_FS_PDNINT BIT(31)
+
+/* 2 REG_FSISR (Offset 0x0054) */
+
+#define BIT_FS_SPS_OCP_INT BIT(29)
+
+/* 2 REG_FSISR (Offset 0x0054) */
+
+#define BIT_FS_PWMERR_INT BIT(28)
+
+/* 2 REG_FSISR (Offset 0x0054) */
+
+#define BIT_FS_GPIOF_INT BIT(27)
+#define BIT_FS_GPIOE_INT BIT(26)
+#define BIT_FS_GPIOD_INT BIT(25)
+#define BIT_FS_GPIOC_INT BIT(24)
+
+/* 2 REG_FSISR (Offset 0x0054) */
+
+#define BIT_FS_GPIOB_INT BIT(23)
+
+/* 2 REG_FSISR (Offset 0x0054) */
+
+#define BIT_FS_GPIOA_INT BIT(22)
+
+/* 2 REG_FSISR (Offset 0x0054) */
+
+#define BIT_FS_GPIO9_INT BIT(21)
+
+/* 2 REG_FSISR (Offset 0x0054) */
+
+#define BIT_FS_GPIO8_INT BIT(20)
+
+/* 2 REG_FSISR (Offset 0x0054) */
+
+#define BIT_FS_GPIO7_INT BIT(19)
+
+/* 2 REG_FSISR (Offset 0x0054) */
+
+#define BIT_FS_GPIO6_INT BIT(18)
+
+/* 2 REG_FSISR (Offset 0x0054) */
+
+#define BIT_FS_GPIO5_INT BIT(17)
+
+/* 2 REG_FSISR (Offset 0x0054) */
+
+#define BIT_FS_GPIO4_INT BIT(16)
+
+/* 2 REG_FSISR (Offset 0x0054) */
+
+#define BIT_FS_GPIO3_INT BIT(15)
+
+/* 2 REG_FSISR (Offset 0x0054) */
+
+#define BIT_FS_GPIO2_INT BIT(14)
+
+/* 2 REG_FSISR (Offset 0x0054) */
+
+#define BIT_FS_GPIO1_INT BIT(13)
+
+/* 2 REG_FSISR (Offset 0x0054) */
+
+#define BIT_FS_GPIO0_INT BIT(12)
+
+/* 2 REG_FSISR (Offset 0x0054) */
+
+#define BIT_FS_HCI_SUS_INT BIT(11)
+
+/* 2 REG_FSISR (Offset 0x0054) */
+
+#define BIT_FS_HCI_RES_INT BIT(10)
+
+/* 2 REG_FSISR (Offset 0x0054) */
+
+#define BIT_FS_HCI_RESET_INT BIT(9)
+
+/* 2 REG_FSISR (Offset 0x0054) */
+
+#define BIT_ACT2RECOVERY BIT(6)
+
+/* 2 REG_FSISR (Offset 0x0054) */
+
+#define BIT_HCI_TXDMA_REQ_HISR BIT(4)
+
+/* 2 REG_FSISR (Offset 0x0054) */
+
+#define BIT_FS_32K_LEAVE_SETTING_INT BIT(3)
+
+/* 2 REG_FSISR (Offset 0x0054) */
+
+#define BIT_FS_32K_ENTER_SETTING_INT BIT(2)
+
+/* 2 REG_FSISR (Offset 0x0054) */
+
+#define BIT_FS_USB_LPMRSM_INT BIT(1)
+
+/* 2 REG_FSISR (Offset 0x0054) */
+
+#define BIT_FS_USB_LPMINT_INT BIT(0)
+
+/* 2 REG_HSIMR (Offset 0x0058) */
+
+#define BIT_GPIOF_INT_EN BIT(31)
+#define BIT_GPIOE_INT_EN BIT(30)
+#define BIT_GPIOD_INT_EN BIT(29)
+#define BIT_GPIOC_INT_EN BIT(28)
+#define BIT_GPIOB_INT_EN BIT(27)
+#define BIT_GPIOA_INT_EN BIT(26)
+#define BIT_GPIO9_INT_EN BIT(25)
+#define BIT_GPIO8_INT_EN BIT(24)
+#define BIT_GPIO7_INT_EN BIT(23)
+#define BIT_GPIO6_INT_EN BIT(22)
+#define BIT_GPIO5_INT_EN BIT(21)
+#define BIT_GPIO4_INT_EN BIT(20)
+#define BIT_GPIO3_INT_EN BIT(19)
+
+/* 2 REG_HSIMR (Offset 0x0058) */
+
+#define BIT_GPIO1_INT_EN BIT(17)
+#define BIT_GPIO0_INT_EN BIT(16)
+
+/* 2 REG_HSIMR (Offset 0x0058) */
+
+#define BIT_GPIO2_INT_EN_V1 BIT(16)
+
+/* 2 REG_HSIMR (Offset 0x0058) */
+
+#define BIT_PDNINT_EN BIT(7)
+
+/* 2 REG_HSIMR (Offset 0x0058) */
+
+#define BIT_RON_INT_EN BIT(6)
+
+/* 2 REG_HSIMR (Offset 0x0058) */
+
+#define BIT_SPS_OCP_INT_EN BIT(5)
+
+/* 2 REG_HSIMR (Offset 0x0058) */
+
+#define BIT_GPIO15_0_INT_EN BIT(0)
+
+/* 2 REG_HSISR (Offset 0x005C) */
+
+#define BIT_GPIOF_INT BIT(31)
+#define BIT_GPIOE_INT BIT(30)
+#define BIT_GPIOD_INT BIT(29)
+#define BIT_GPIOC_INT BIT(28)
+#define BIT_GPIOB_INT BIT(27)
+#define BIT_GPIOA_INT BIT(26)
+#define BIT_GPIO9_INT BIT(25)
+#define BIT_GPIO8_INT BIT(24)
+#define BIT_GPIO7_INT BIT(23)
+
+/* 2 REG_HSISR (Offset 0x005C) */
+
+#define BIT_GPIO6_INT BIT(22)
+#define BIT_GPIO5_INT BIT(21)
+#define BIT_GPIO4_INT BIT(20)
+#define BIT_GPIO3_INT BIT(19)
+
+/* 2 REG_HSISR (Offset 0x005C) */
+
+#define BIT_GPIO1_INT BIT(17)
+#define BIT_GPIO0_INT BIT(16)
+
+/* 2 REG_HSISR (Offset 0x005C) */
+
+#define BIT_GPIO2_INT_V1 BIT(16)
+
+/* 2 REG_HSISR (Offset 0x005C) */
+
+#define BIT_PDNINT BIT(7)
+
+/* 2 REG_HSISR (Offset 0x005C) */
+
+#define BIT_RON_INT BIT(6)
+
+/* 2 REG_HSISR (Offset 0x005C) */
+
+#define BIT_SPS_OCP_INT BIT(5)
+
+/* 2 REG_HSISR (Offset 0x005C) */
+
+#define BIT_GPIO15_0_INT BIT(0)
+#define BIT_MCUFWDL_EN BIT(0)
+
+/* 2 REG_GPIO_EXT_CTRL (Offset 0x0060) */
+
+#define BIT_SHIFT_GPIO_MOD_15_TO_8 24
+#define BIT_MASK_GPIO_MOD_15_TO_8 0xff
+#define BIT_GPIO_MOD_15_TO_8(x) \
+ (((x) & BIT_MASK_GPIO_MOD_15_TO_8) << BIT_SHIFT_GPIO_MOD_15_TO_8)
+#define BIT_GET_GPIO_MOD_15_TO_8(x) \
+ (((x) >> BIT_SHIFT_GPIO_MOD_15_TO_8) & BIT_MASK_GPIO_MOD_15_TO_8)
+
+#define BIT_SHIFT_GPIO_IO_SEL_15_TO_8 16
+#define BIT_MASK_GPIO_IO_SEL_15_TO_8 0xff
+#define BIT_GPIO_IO_SEL_15_TO_8(x) \
+ (((x) & BIT_MASK_GPIO_IO_SEL_15_TO_8) << BIT_SHIFT_GPIO_IO_SEL_15_TO_8)
+#define BIT_GET_GPIO_IO_SEL_15_TO_8(x) \
+ (((x) >> BIT_SHIFT_GPIO_IO_SEL_15_TO_8) & BIT_MASK_GPIO_IO_SEL_15_TO_8)
+
+#define BIT_SHIFT_GPIO_OUT_15_TO_8 8
+#define BIT_MASK_GPIO_OUT_15_TO_8 0xff
+#define BIT_GPIO_OUT_15_TO_8(x) \
+ (((x) & BIT_MASK_GPIO_OUT_15_TO_8) << BIT_SHIFT_GPIO_OUT_15_TO_8)
+#define BIT_GET_GPIO_OUT_15_TO_8(x) \
+ (((x) >> BIT_SHIFT_GPIO_OUT_15_TO_8) & BIT_MASK_GPIO_OUT_15_TO_8)
+
+#define BIT_SHIFT_GPIO_IN_15_TO_8 0
+#define BIT_MASK_GPIO_IN_15_TO_8 0xff
+#define BIT_GPIO_IN_15_TO_8(x) \
+ (((x) & BIT_MASK_GPIO_IN_15_TO_8) << BIT_SHIFT_GPIO_IN_15_TO_8)
+#define BIT_GET_GPIO_IN_15_TO_8(x) \
+ (((x) >> BIT_SHIFT_GPIO_IN_15_TO_8) & BIT_MASK_GPIO_IN_15_TO_8)
+
+/* 2 REG_SDIO_H2C (Offset 0x10250060) */
+
+#define BIT_SHIFT_SDIO_H2C_MSG 0
+#define BIT_MASK_SDIO_H2C_MSG 0xffffffffL
+#define BIT_SDIO_H2C_MSG(x) \
+ (((x) & BIT_MASK_SDIO_H2C_MSG) << BIT_SHIFT_SDIO_H2C_MSG)
+#define BIT_GET_SDIO_H2C_MSG(x) \
+ (((x) >> BIT_SHIFT_SDIO_H2C_MSG) & BIT_MASK_SDIO_H2C_MSG)
+
+/* 2 REG_PAD_CTRL1 (Offset 0x0064) */
+
+#define BIT_PAPE_WLBT_SEL BIT(29)
+#define BIT_LNAON_WLBT_SEL BIT(28)
+
+/* 2 REG_PAD_CTRL1 (Offset 0x0064) */
+
+#define BIT_BTGP_GPG3_FEN BIT(26)
+#define BIT_BTGP_GPG2_FEN BIT(25)
+
+/* 2 REG_PAD_CTRL1 (Offset 0x0064) */
+
+#define BIT_BTGP_JTAG_EN BIT(24)
+
+/* 2 REG_PAD_CTRL1 (Offset 0x0064) */
+
+#define BIT_XTAL_CLK_EXTARNAL_EN BIT(23)
+
+/* 2 REG_PAD_CTRL1 (Offset 0x0064) */
+
+#define BIT_BTGP_UART0_EN BIT(22)
+
+/* 2 REG_PAD_CTRL1 (Offset 0x0064) */
+
+#define BIT_BTGP_UART1_EN BIT(21)
+
+/* 2 REG_PAD_CTRL1 (Offset 0x0064) */
+
+#define BIT_BTGP_SPI_EN BIT(20)
+
+/* 2 REG_PAD_CTRL1 (Offset 0x0064) */
+
+#define BIT_BTGP_GPIO_E2 BIT(19)
+
+/* 2 REG_PAD_CTRL1 (Offset 0x0064) */
+
+#define BIT_BTGP_GPIO_EN BIT(18)
+
+/* 2 REG_PAD_CTRL1 (Offset 0x0064) */
+
+#define BIT_SHIFT_BTGP_GPIO_SL 16
+#define BIT_MASK_BTGP_GPIO_SL 0x3
+#define BIT_BTGP_GPIO_SL(x) \
+ (((x) & BIT_MASK_BTGP_GPIO_SL) << BIT_SHIFT_BTGP_GPIO_SL)
+#define BIT_GET_BTGP_GPIO_SL(x) \
+ (((x) >> BIT_SHIFT_BTGP_GPIO_SL) & BIT_MASK_BTGP_GPIO_SL)
+
+/* 2 REG_PAD_CTRL1 (Offset 0x0064) */
+
+#define BIT_PAD_SDIO_SR BIT(14)
+
+/* 2 REG_PAD_CTRL1 (Offset 0x0064) */
+
+#define BIT_GPIO14_OUTPUT_PL BIT(13)
+
+/* 2 REG_PAD_CTRL1 (Offset 0x0064) */
+
+#define BIT_HOST_WAKE_PAD_PULL_EN BIT(12)
+
+/* 2 REG_PAD_CTRL1 (Offset 0x0064) */
+
+#define BIT_HOST_WAKE_PAD_SL BIT(11)
+
+/* 2 REG_PAD_CTRL1 (Offset 0x0064) */
+
+#define BIT_PAD_LNAON_SR BIT(10)
+
+/* 2 REG_PAD_CTRL1 (Offset 0x0064) */
+
+#define BIT_PAD_LNAON_E2 BIT(9)
+
+/* 2 REG_PAD_CTRL1 (Offset 0x0064) */
+
+#define BIT_SW_LNAON_G_SEL_DATA BIT(8)
+
+/* 2 REG_PAD_CTRL1 (Offset 0x0064) */
+
+#define BIT_SW_LNAON_A_SEL_DATA BIT(7)
+
+/* 2 REG_PAD_CTRL1 (Offset 0x0064) */
+
+#define BIT_PAD_PAPE_SR BIT(6)
+
+/* 2 REG_PAD_CTRL1 (Offset 0x0064) */
+
+#define BIT_PAD_PAPE_E2 BIT(5)
+
+/* 2 REG_PAD_CTRL1 (Offset 0x0064) */
+
+#define BIT_SW_PAPE_G_SEL_DATA BIT(4)
+
+/* 2 REG_PAD_CTRL1 (Offset 0x0064) */
+
+#define BIT_SW_PAPE_A_SEL_DATA BIT(3)
+
+/* 2 REG_PAD_CTRL1 (Offset 0x0064) */
+
+#define BIT_PAD_DPDT_SR BIT(2)
+
+/* 2 REG_PAD_CTRL1 (Offset 0x0064) */
+
+#define BIT_PAD_DPDT_PAD_E2 BIT(1)
+
+/* 2 REG_PAD_CTRL1 (Offset 0x0064) */
+
+#define BIT_SW_DPDT_SEL_DATA BIT(0)
+
+/* 2 REG_SDIO_C2H (Offset 0x10250064) */
+
+#define BIT_SHIFT_SDIO_C2H_MSG 0
+#define BIT_MASK_SDIO_C2H_MSG 0xffffffffL
+#define BIT_SDIO_C2H_MSG(x) \
+ (((x) & BIT_MASK_SDIO_C2H_MSG) << BIT_SHIFT_SDIO_C2H_MSG)
+#define BIT_GET_SDIO_C2H_MSG(x) \
+ (((x) >> BIT_SHIFT_SDIO_C2H_MSG) & BIT_MASK_SDIO_C2H_MSG)
+
+/* 2 REG_WL_BT_PWR_CTRL (Offset 0x0068) */
+
+#define BIT_ISO_BD2PP BIT(31)
+#define BIT_LDOV12B_EN BIT(30)
+#define BIT_CKEN_BTGPS BIT(29)
+#define BIT_FEN_BTGPS BIT(28)
+
+/* 2 REG_WL_BT_PWR_CTRL (Offset 0x0068) */
+
+#define BIT_MULRW BIT(27)
+
+/* 2 REG_WL_BT_PWR_CTRL (Offset 0x0068) */
+
+#define BIT_BTCPU_BOOTSEL BIT(27)
+#define BIT_SPI_SPEEDUP BIT(26)
+
+/* 2 REG_WL_BT_PWR_CTRL (Offset 0x0068) */
+
+#define BIT_DEVWAKE_PAD_TYPE_SEL BIT(24)
+#define BIT_CLKREQ_PAD_TYPE_SEL BIT(23)
+
+/* 2 REG_WL_BT_PWR_CTRL (Offset 0x0068) */
+
+#define BIT_EN_CPL_TIMEOUT_PS BIT(22)
+
+/* 2 REG_WL_BT_PWR_CTRL (Offset 0x0068) */
+
+#define BIT_ISO_BTPON2PP BIT(22)
+
+/* 2 REG_WL_BT_PWR_CTRL (Offset 0x0068) */
+
+#define BIT_REG_TXDMA_FAIL_PS BIT(21)
+
+/* 2 REG_WL_BT_PWR_CTRL (Offset 0x0068) */
+
+#define BIT_EN_HWENTR_L1 BIT(19)
+
+/* 2 REG_WL_BT_PWR_CTRL (Offset 0x0068) */
+
+#define BIT_BT_HWROF_EN BIT(19)
+
+/* 2 REG_WL_BT_PWR_CTRL (Offset 0x0068) */
+
+#define BIT_EN_ADV_CLKGATE BIT(18)
+
+/* 2 REG_WL_BT_PWR_CTRL (Offset 0x0068) */
+
+#define BIT_BT_FUNC_EN BIT(18)
+
+/* 2 REG_WL_BT_PWR_CTRL (Offset 0x0068) */
+
+#define BIT_BT_HWPDN_SL BIT(17)
+
+/* 2 REG_WL_BT_PWR_CTRL (Offset 0x0068) */
+
+#define BIT_BT_DISN_EN BIT(16)
+
+/* 2 REG_WL_BT_PWR_CTRL (Offset 0x0068) */
+
+#define BIT_BT_PDN_PULL_EN BIT(15)
+
+/* 2 REG_WL_BT_PWR_CTRL (Offset 0x0068) */
+
+#define BIT_WL_PDN_PULL_EN BIT(14)
+#define BIT_EXTERNAL_REQUEST_PL BIT(13)
+
+/* 2 REG_WL_BT_PWR_CTRL (Offset 0x0068) */
+
+#define BIT_GPIO0_2_3_PULL_LOW_EN BIT(12)
+
+/* 2 REG_WL_BT_PWR_CTRL (Offset 0x0068) */
+
+#define BIT_ISO_BA2PP BIT(11)
+#define BIT_BT_AFE_LDO_EN BIT(10)
+
+/* 2 REG_WL_BT_PWR_CTRL (Offset 0x0068) */
+
+#define BIT_BT_AFE_PLL_EN BIT(9)
+
+/* 2 REG_WL_BT_PWR_CTRL (Offset 0x0068) */
+
+#define BIT_BT_DIG_CLK_EN BIT(8)
+
+/* 2 REG_WL_BT_PWR_CTRL (Offset 0x0068) */
+
+#define BIT_WL_DRV_EXIST_IDX BIT(5)
+
+/* 2 REG_WL_BT_PWR_CTRL (Offset 0x0068) */
+
+#define BIT_DOP_EHPAD BIT(4)
+
+/* 2 REG_WL_BT_PWR_CTRL (Offset 0x0068) */
+
+#define BIT_WL_HWROF_EN BIT(3)
+
+/* 2 REG_WL_BT_PWR_CTRL (Offset 0x0068) */
+
+#define BIT_WL_FUNC_EN BIT(2)
+
+/* 2 REG_WL_BT_PWR_CTRL (Offset 0x0068) */
+
+#define BIT_WL_HWPDN_SL BIT(1)
+#define BIT_WL_HWPDN_EN BIT(0)
+
+/* 2 REG_SDM_DEBUG (Offset 0x006C) */
+
+#define BIT_SHIFT_WLCLK_PHASE 0
+#define BIT_MASK_WLCLK_PHASE 0x1f
+#define BIT_WLCLK_PHASE(x) \
+ (((x) & BIT_MASK_WLCLK_PHASE) << BIT_SHIFT_WLCLK_PHASE)
+#define BIT_GET_WLCLK_PHASE(x) \
+ (((x) >> BIT_SHIFT_WLCLK_PHASE) & BIT_MASK_WLCLK_PHASE)
+
+/* 2 REG_SYS_SDIO_CTRL (Offset 0x0070) */
+
+#define BIT_DBG_GNT_WL_BT BIT(27)
+
+/* 2 REG_SYS_SDIO_CTRL (Offset 0x0070) */
+
+#define BIT_LTE_MUX_CTRL_PATH BIT(26)
+
+/* 2 REG_SYS_SDIO_CTRL (Offset 0x0070) */
+
+#define BIT_LTE_COEX_UART BIT(25)
+
+/* 2 REG_SYS_SDIO_CTRL (Offset 0x0070) */
+
+#define BIT_3W_LTE_WL_GPIO BIT(24)
+
+/* 2 REG_SYS_SDIO_CTRL (Offset 0x0070) */
+
+#define BIT_SDIO_INT_POLARITY BIT(19)
+#define BIT_SDIO_INT BIT(18)
+
+/* 2 REG_SYS_SDIO_CTRL (Offset 0x0070) */
+
+#define BIT_SDIO_OFF_EN BIT(17)
+
+/* 2 REG_SYS_SDIO_CTRL (Offset 0x0070) */
+
+#define BIT_SDIO_ON_EN BIT(16)
+
+/* 2 REG_SYS_SDIO_CTRL (Offset 0x0070) */
+
+#define BIT_PCIE_WAIT_TIMEOUT_EVENT BIT(10)
+#define BIT_PCIE_WAIT_TIME BIT(9)
+
+/* 2 REG_SYS_SDIO_CTRL (Offset 0x0070) */
+
+#define BIT_MPCIE_REFCLK_XTAL_SEL BIT(8)
+
+/* 2 REG_HCI_OPT_CTRL (Offset 0x0074) */
+
+#define BIT_SHIFT_TSFT_SEL 29
+#define BIT_MASK_TSFT_SEL 0x7
+#define BIT_TSFT_SEL(x) (((x) & BIT_MASK_TSFT_SEL) << BIT_SHIFT_TSFT_SEL)
+#define BIT_GET_TSFT_SEL(x) (((x) >> BIT_SHIFT_TSFT_SEL) & BIT_MASK_TSFT_SEL)
+
+/* 2 REG_HCI_OPT_CTRL (Offset 0x0074) */
+
+#define BIT_SHIFT_RPWM 24
+#define BIT_MASK_RPWM 0xff
+#define BIT_RPWM(x) (((x) & BIT_MASK_RPWM) << BIT_SHIFT_RPWM)
+#define BIT_GET_RPWM(x) (((x) >> BIT_SHIFT_RPWM) & BIT_MASK_RPWM)
+
+#define BIT_ROM_DLEN BIT(19)
+
+#define BIT_SHIFT_ROM_PGE 16
+#define BIT_MASK_ROM_PGE 0x7
+#define BIT_ROM_PGE(x) (((x) & BIT_MASK_ROM_PGE) << BIT_SHIFT_ROM_PGE)
+#define BIT_GET_ROM_PGE(x) (((x) >> BIT_SHIFT_ROM_PGE) & BIT_MASK_ROM_PGE)
+
+/* 2 REG_HCI_OPT_CTRL (Offset 0x0074) */
+
+#define BIT_USB_HOST_PWR_OFF_EN BIT(12)
+
+/* 2 REG_HCI_OPT_CTRL (Offset 0x0074) */
+
+#define BIT_SYM_LPS_BLOCK_EN BIT(11)
+
+/* 2 REG_HCI_OPT_CTRL (Offset 0x0074) */
+
+#define BIT_USB_LPM_ACT_EN BIT(10)
+
+/* 2 REG_HCI_OPT_CTRL (Offset 0x0074) */
+
+#define BIT_USB_LPM_NY BIT(9)
+
+/* 2 REG_HCI_OPT_CTRL (Offset 0x0074) */
+
+#define BIT_USB_SUS_DIS BIT(8)
+
+/* 2 REG_HCI_OPT_CTRL (Offset 0x0074) */
+
+#define BIT_SHIFT_SDIO_PAD_E 5
+#define BIT_MASK_SDIO_PAD_E 0x7
+#define BIT_SDIO_PAD_E(x) (((x) & BIT_MASK_SDIO_PAD_E) << BIT_SHIFT_SDIO_PAD_E)
+#define BIT_GET_SDIO_PAD_E(x) \
+ (((x) >> BIT_SHIFT_SDIO_PAD_E) & BIT_MASK_SDIO_PAD_E)
+
+/* 2 REG_HCI_OPT_CTRL (Offset 0x0074) */
+
+#define BIT_USB_LPPLL_EN BIT(4)
+
+/* 2 REG_HCI_OPT_CTRL (Offset 0x0074) */
+
+#define BIT_ROP_SW15 BIT(2)
+
+/* 2 REG_HCI_OPT_CTRL (Offset 0x0074) */
+
+#define BIT_PCI_CKRDY_OPT BIT(1)
+
+/* 2 REG_HCI_OPT_CTRL (Offset 0x0074) */
+
+#define BIT_PCI_VAUX_EN BIT(0)
+
+/* 2 REG_LDO_SWR_CTRL (Offset 0x007C) */
+
+#define BIT_ZCD_HW_AUTO_EN BIT(27)
+#define BIT_ZCD_REGSEL BIT(26)
+
+/* 2 REG_LDO_SWR_CTRL (Offset 0x007C) */
+
+#define BIT_SHIFT_AUTO_ZCD_IN_CODE 21
+#define BIT_MASK_AUTO_ZCD_IN_CODE 0x1f
+#define BIT_AUTO_ZCD_IN_CODE(x) \
+ (((x) & BIT_MASK_AUTO_ZCD_IN_CODE) << BIT_SHIFT_AUTO_ZCD_IN_CODE)
+#define BIT_GET_AUTO_ZCD_IN_CODE(x) \
+ (((x) >> BIT_SHIFT_AUTO_ZCD_IN_CODE) & BIT_MASK_AUTO_ZCD_IN_CODE)
+
+/* 2 REG_LDO_SWR_CTRL (Offset 0x007C) */
+
+#define BIT_SHIFT_ZCD_CODE_IN_L 16
+#define BIT_MASK_ZCD_CODE_IN_L 0x1f
+#define BIT_ZCD_CODE_IN_L(x) \
+ (((x) & BIT_MASK_ZCD_CODE_IN_L) << BIT_SHIFT_ZCD_CODE_IN_L)
+#define BIT_GET_ZCD_CODE_IN_L(x) \
+ (((x) >> BIT_SHIFT_ZCD_CODE_IN_L) & BIT_MASK_ZCD_CODE_IN_L)
+
+/* 2 REG_LDO_SWR_CTRL (Offset 0x007C) */
+
+#define BIT_SHIFT_LDO_HV5_DUMMY 14
+#define BIT_MASK_LDO_HV5_DUMMY 0x3
+#define BIT_LDO_HV5_DUMMY(x) \
+ (((x) & BIT_MASK_LDO_HV5_DUMMY) << BIT_SHIFT_LDO_HV5_DUMMY)
+#define BIT_GET_LDO_HV5_DUMMY(x) \
+ (((x) >> BIT_SHIFT_LDO_HV5_DUMMY) & BIT_MASK_LDO_HV5_DUMMY)
+
+/* 2 REG_LDO_SWR_CTRL (Offset 0x007C) */
+
+#define BIT_SHIFT_REG_VTUNE33_BIT0_TO_BIT1 12
+#define BIT_MASK_REG_VTUNE33_BIT0_TO_BIT1 0x3
+#define BIT_REG_VTUNE33_BIT0_TO_BIT1(x) \
+ (((x) & BIT_MASK_REG_VTUNE33_BIT0_TO_BIT1) \
+ << BIT_SHIFT_REG_VTUNE33_BIT0_TO_BIT1)
+#define BIT_GET_REG_VTUNE33_BIT0_TO_BIT1(x) \
+ (((x) >> BIT_SHIFT_REG_VTUNE33_BIT0_TO_BIT1) & \
+ BIT_MASK_REG_VTUNE33_BIT0_TO_BIT1)
+
+/* 2 REG_LDO_SWR_CTRL (Offset 0x007C) */
+
+#define BIT_SHIFT_REG_STANDBY33_BIT0_TO_BIT1 10
+#define BIT_MASK_REG_STANDBY33_BIT0_TO_BIT1 0x3
+#define BIT_REG_STANDBY33_BIT0_TO_BIT1(x) \
+ (((x) & BIT_MASK_REG_STANDBY33_BIT0_TO_BIT1) \
+ << BIT_SHIFT_REG_STANDBY33_BIT0_TO_BIT1)
+#define BIT_GET_REG_STANDBY33_BIT0_TO_BIT1(x) \
+ (((x) >> BIT_SHIFT_REG_STANDBY33_BIT0_TO_BIT1) & \
+ BIT_MASK_REG_STANDBY33_BIT0_TO_BIT1)
+
+/* 2 REG_LDO_SWR_CTRL (Offset 0x007C) */
+
+#define BIT_SHIFT_REG_LOAD33_BIT0_TO_BIT1 8
+#define BIT_MASK_REG_LOAD33_BIT0_TO_BIT1 0x3
+#define BIT_REG_LOAD33_BIT0_TO_BIT1(x) \
+ (((x) & BIT_MASK_REG_LOAD33_BIT0_TO_BIT1) \
+ << BIT_SHIFT_REG_LOAD33_BIT0_TO_BIT1)
+#define BIT_GET_REG_LOAD33_BIT0_TO_BIT1(x) \
+ (((x) >> BIT_SHIFT_REG_LOAD33_BIT0_TO_BIT1) & \
+ BIT_MASK_REG_LOAD33_BIT0_TO_BIT1)
+
+/* 2 REG_LDO_SWR_CTRL (Offset 0x007C) */
+
+#define BIT_REG_BYPASS_L BIT(7)
+
+/* 2 REG_LDO_SWR_CTRL (Offset 0x007C) */
+
+#define BIT_REG_LDOF_L BIT(6)
+
+/* 2 REG_LDO_SWR_CTRL (Offset 0x007C) */
+
+#define BIT_REG_TYPE_L_V1 BIT(5)
+
+/* 2 REG_LDO_SWR_CTRL (Offset 0x007C) */
+
+#define BIT_ARENB_L BIT(3)
+
+/* 2 REG_LDO_SWR_CTRL (Offset 0x007C) */
+
+#define BIT_SHIFT_CFC_L 1
+#define BIT_MASK_CFC_L 0x3
+#define BIT_CFC_L(x) (((x) & BIT_MASK_CFC_L) << BIT_SHIFT_CFC_L)
+#define BIT_GET_CFC_L(x) (((x) >> BIT_SHIFT_CFC_L) & BIT_MASK_CFC_L)
+
+/* 2 REG_LDO_SWR_CTRL (Offset 0x007C) */
+
+#define BIT_REG_OCPS_L_V1 BIT(0)
+
+/* 2 REG_MCUFW_CTRL (Offset 0x0080) */
+
+#define BIT_ANA_PORT_EN BIT(22)
+#define BIT_MAC_PORT_EN BIT(21)
+#define BIT_BOOT_FSPI_EN BIT(20)
+#define BIT_FW_INIT_RDY BIT(15)
+#define BIT_FW_DW_RDY BIT(14)
+
+/* 2 REG_MCUFW_CTRL (Offset 0x0080) */
+
+#define BIT_SHIFT_CPU_CLK_SEL 12
+#define BIT_MASK_CPU_CLK_SEL 0x3
+#define BIT_CPU_CLK_SEL(x) \
+ (((x) & BIT_MASK_CPU_CLK_SEL) << BIT_SHIFT_CPU_CLK_SEL)
+#define BIT_GET_CPU_CLK_SEL(x) \
+ (((x) >> BIT_SHIFT_CPU_CLK_SEL) & BIT_MASK_CPU_CLK_SEL)
+
+/* 2 REG_MCUFW_CTRL (Offset 0x0080) */
+
+#define BIT_CCLK_CHG_MASK BIT(11)
+
+/* 2 REG_MCUFW_CTRL (Offset 0x0080) */
+
+#define BIT_EMEM__TXBUF_CHKSUM_OK BIT(10)
+
+/* 2 REG_MCUFW_CTRL (Offset 0x0080) */
+
+#define BIT_EMEM_TXBUF_DW_RDY BIT(9)
+
+/* 2 REG_MCUFW_CTRL (Offset 0x0080) */
+
+#define BIT_EMEM_CHKSUM_OK BIT(8)
+#define BIT_EMEM_DW_OK BIT(7)
+#define BIT_TOGGLING BIT(7)
+#define BIT_DMEM_CHKSUM_OK BIT(6)
+#define BIT_ACK BIT(6)
+
+/* 2 REG_MCUFW_CTRL (Offset 0x0080) */
+
+#define BIT_DMEM_DW_OK BIT(5)
+
+/* 2 REG_MCUFW_CTRL (Offset 0x0080) */
+
+#define BIT_IMEM_CHKSUM_OK BIT(4)
+
+/* 2 REG_MCUFW_CTRL (Offset 0x0080) */
+
+#define BIT_IMEM_DW_OK BIT(3)
+
+/* 2 REG_MCUFW_CTRL (Offset 0x0080) */
+
+#define BIT_IMEM_BOOT_LOAD_CHKSUM_OK BIT(2)
+
+/* 2 REG_MCUFW_CTRL (Offset 0x0080) */
+
+#define BIT_IMEM_BOOT_LOAD_DW_OK BIT(1)
+
+/* 2 REG_SDIO_HRPWM1 (Offset 0x10250080) */
+
+#define BIT_32K_PERMISSION BIT(0)
+
+/* 2 REG_MCU_TST_CFG (Offset 0x0084) */
+
+#define BIT_SHIFT_LBKTST 0
+#define BIT_MASK_LBKTST 0xffff
+#define BIT_LBKTST(x) (((x) & BIT_MASK_LBKTST) << BIT_SHIFT_LBKTST)
+#define BIT_GET_LBKTST(x) (((x) >> BIT_SHIFT_LBKTST) & BIT_MASK_LBKTST)
+
+/* 2 REG_SDIO_BUS_CTRL (Offset 0x10250085) */
+
+#define BIT_PAD_CLK_XHGE_EN BIT(3)
+#define BIT_INTER_CLK_EN BIT(2)
+#define BIT_EN_RPT_TXCRC BIT(1)
+#define BIT_DIS_RXDMA_STS BIT(0)
+
+/* 2 REG_SDIO_HSUS_CTRL (Offset 0x10250086) */
+
+#define BIT_INTR_CTRL BIT(4)
+#define BIT_SDIO_VOLTAGE BIT(3)
+#define BIT_BYPASS_INIT BIT(2)
+
+/* 2 REG_SDIO_HSUS_CTRL (Offset 0x10250086) */
+
+#define BIT_HCI_RESUME_RDY BIT(1)
+#define BIT_HCI_SUS_REQ BIT(0)
+
+/* 2 REG_HMEBOX_E0_E1 (Offset 0x0088) */
+
+#define BIT_SHIFT_HOST_MSG_E1 16
+#define BIT_MASK_HOST_MSG_E1 0xffff
+#define BIT_HOST_MSG_E1(x) \
+ (((x) & BIT_MASK_HOST_MSG_E1) << BIT_SHIFT_HOST_MSG_E1)
+#define BIT_GET_HOST_MSG_E1(x) \
+ (((x) >> BIT_SHIFT_HOST_MSG_E1) & BIT_MASK_HOST_MSG_E1)
+
+#define BIT_SHIFT_HOST_MSG_E0 0
+#define BIT_MASK_HOST_MSG_E0 0xffff
+#define BIT_HOST_MSG_E0(x) \
+ (((x) & BIT_MASK_HOST_MSG_E0) << BIT_SHIFT_HOST_MSG_E0)
+#define BIT_GET_HOST_MSG_E0(x) \
+ (((x) >> BIT_SHIFT_HOST_MSG_E0) & BIT_MASK_HOST_MSG_E0)
+
+/* 2 REG_SDIO_RESPONSE_TIMER (Offset 0x10250088) */
+
+#define BIT_SHIFT_CMDIN_2RESP_TIMER 0
+#define BIT_MASK_CMDIN_2RESP_TIMER 0xffff
+#define BIT_CMDIN_2RESP_TIMER(x) \
+ (((x) & BIT_MASK_CMDIN_2RESP_TIMER) << BIT_SHIFT_CMDIN_2RESP_TIMER)
+#define BIT_GET_CMDIN_2RESP_TIMER(x) \
+ (((x) >> BIT_SHIFT_CMDIN_2RESP_TIMER) & BIT_MASK_CMDIN_2RESP_TIMER)
+
+/* 2 REG_SDIO_CMD_CRC (Offset 0x1025008A) */
+
+#define BIT_SHIFT_SDIO_CMD_CRC_V1 0
+#define BIT_MASK_SDIO_CMD_CRC_V1 0xff
+#define BIT_SDIO_CMD_CRC_V1(x) \
+ (((x) & BIT_MASK_SDIO_CMD_CRC_V1) << BIT_SHIFT_SDIO_CMD_CRC_V1)
+#define BIT_GET_SDIO_CMD_CRC_V1(x) \
+ (((x) >> BIT_SHIFT_SDIO_CMD_CRC_V1) & BIT_MASK_SDIO_CMD_CRC_V1)
+
+/* 2 REG_HMEBOX_E2_E3 (Offset 0x008C) */
+
+#define BIT_SHIFT_HOST_MSG_E3 16
+#define BIT_MASK_HOST_MSG_E3 0xffff
+#define BIT_HOST_MSG_E3(x) \
+ (((x) & BIT_MASK_HOST_MSG_E3) << BIT_SHIFT_HOST_MSG_E3)
+#define BIT_GET_HOST_MSG_E3(x) \
+ (((x) >> BIT_SHIFT_HOST_MSG_E3) & BIT_MASK_HOST_MSG_E3)
+
+#define BIT_SHIFT_HOST_MSG_E2 0
+#define BIT_MASK_HOST_MSG_E2 0xffff
+#define BIT_HOST_MSG_E2(x) \
+ (((x) & BIT_MASK_HOST_MSG_E2) << BIT_SHIFT_HOST_MSG_E2)
+#define BIT_GET_HOST_MSG_E2(x) \
+ (((x) >> BIT_SHIFT_HOST_MSG_E2) & BIT_MASK_HOST_MSG_E2)
+
+/* 2 REG_WLLPS_CTRL (Offset 0x0090) */
+
+#define BIT_WLLPSOP_EABM BIT(31)
+
+/* 2 REG_WLLPS_CTRL (Offset 0x0090) */
+
+#define BIT_WLLPSOP_ACKF BIT(30)
+
+/* 2 REG_WLLPS_CTRL (Offset 0x0090) */
+
+#define BIT_WLLPSOP_DLDM BIT(29)
+
+/* 2 REG_WLLPS_CTRL (Offset 0x0090) */
+
+#define BIT_WLLPSOP_ESWR BIT(28)
+
+/* 2 REG_WLLPS_CTRL (Offset 0x0090) */
+
+#define BIT_WLLPSOP_PWMM BIT(27)
+#define BIT_WLLPSOP_EECK BIT(26)
+
+/* 2 REG_WLLPS_CTRL (Offset 0x0090) */
+
+#define BIT_WLLPSOP_WLMACOFF BIT(25)
+
+/* 2 REG_WLLPS_CTRL (Offset 0x0090) */
+
+#define BIT_WLLPSOP_EXTAL BIT(24)
+
+/* 2 REG_WLLPS_CTRL (Offset 0x0090) */
+
+#define BIT_WL_SYNPON_VOLTSPDN BIT(23)
+
+/* 2 REG_WLLPS_CTRL (Offset 0x0090) */
+
+#define BIT_WLLPSOP_WLBBOFF BIT(22)
+
+/* 2 REG_WLLPS_CTRL (Offset 0x0090) */
+
+#define BIT_WLLPSOP_WLMEM_DS BIT(21)
+
+/* 2 REG_WLLPS_CTRL (Offset 0x0090) */
+
+#define BIT_SHIFT_LPLDH12_VADJ_STEP_DN 12
+#define BIT_MASK_LPLDH12_VADJ_STEP_DN 0xf
+#define BIT_LPLDH12_VADJ_STEP_DN(x) \
+ (((x) & BIT_MASK_LPLDH12_VADJ_STEP_DN) \
+ << BIT_SHIFT_LPLDH12_VADJ_STEP_DN)
+#define BIT_GET_LPLDH12_VADJ_STEP_DN(x) \
+ (((x) >> BIT_SHIFT_LPLDH12_VADJ_STEP_DN) & \
+ BIT_MASK_LPLDH12_VADJ_STEP_DN)
+
+/* 2 REG_WLLPS_CTRL (Offset 0x0090) */
+
+#define BIT_SHIFT_V15ADJ_L1_STEP_DN 8
+#define BIT_MASK_V15ADJ_L1_STEP_DN 0x7
+#define BIT_V15ADJ_L1_STEP_DN(x) \
+ (((x) & BIT_MASK_V15ADJ_L1_STEP_DN) << BIT_SHIFT_V15ADJ_L1_STEP_DN)
+#define BIT_GET_V15ADJ_L1_STEP_DN(x) \
+ (((x) >> BIT_SHIFT_V15ADJ_L1_STEP_DN) & BIT_MASK_V15ADJ_L1_STEP_DN)
+
+#define BIT_REGU_32K_CLK_EN BIT(1)
+#define BIT_DRV_WLAN_INT_CLR BIT(1)
+
+/* 2 REG_WLLPS_CTRL (Offset 0x0090) */
+
+#define BIT_WL_LPS_EN BIT(0)
+
+/* 2 REG_SDIO_HSISR (Offset 0x10250090) */
+
+#define BIT_DRV_WLAN_INT BIT(0)
+
+/* 2 REG_SDIO_HSIMR (Offset 0x10250091) */
+
+#define BIT_HISR_MASK BIT(0)
+
+/* 2 REG_AFE_CTRL5 (Offset 0x0094) */
+
+#define BIT_BB_DBG_SEL_AFE_SDM_BIT0 BIT(31)
+
+/* 2 REG_AFE_CTRL5 (Offset 0x0094) */
+
+#define BIT_ORDER_SDM BIT(30)
+#define BIT_RFE_SEL_SDM BIT(29)
+
+#define BIT_SHIFT_REF_SEL 25
+#define BIT_MASK_REF_SEL 0xf
+#define BIT_REF_SEL(x) (((x) & BIT_MASK_REF_SEL) << BIT_SHIFT_REF_SEL)
+#define BIT_GET_REF_SEL(x) (((x) >> BIT_SHIFT_REF_SEL) & BIT_MASK_REF_SEL)
+
+/* 2 REG_AFE_CTRL5 (Offset 0x0094) */
+
+#define BIT_SHIFT_F0F_SDM 12
+#define BIT_MASK_F0F_SDM 0x1fff
+#define BIT_F0F_SDM(x) (((x) & BIT_MASK_F0F_SDM) << BIT_SHIFT_F0F_SDM)
+#define BIT_GET_F0F_SDM(x) (((x) >> BIT_SHIFT_F0F_SDM) & BIT_MASK_F0F_SDM)
+
+/* 2 REG_AFE_CTRL5 (Offset 0x0094) */
+
+#define BIT_SHIFT_F0N_SDM 9
+#define BIT_MASK_F0N_SDM 0x7
+#define BIT_F0N_SDM(x) (((x) & BIT_MASK_F0N_SDM) << BIT_SHIFT_F0N_SDM)
+#define BIT_GET_F0N_SDM(x) (((x) >> BIT_SHIFT_F0N_SDM) & BIT_MASK_F0N_SDM)
+
+/* 2 REG_AFE_CTRL5 (Offset 0x0094) */
+
+#define BIT_SHIFT_DIVN_SDM 3
+#define BIT_MASK_DIVN_SDM 0x3f
+#define BIT_DIVN_SDM(x) (((x) & BIT_MASK_DIVN_SDM) << BIT_SHIFT_DIVN_SDM)
+#define BIT_GET_DIVN_SDM(x) (((x) >> BIT_SHIFT_DIVN_SDM) & BIT_MASK_DIVN_SDM)
+
+/* 2 REG_GPIO_DEBOUNCE_CTRL (Offset 0x0098) */
+
+#define BIT_WLGP_DBC1EN BIT(15)
+
+#define BIT_SHIFT_WLGP_DBC1 8
+#define BIT_MASK_WLGP_DBC1 0xf
+#define BIT_WLGP_DBC1(x) (((x) & BIT_MASK_WLGP_DBC1) << BIT_SHIFT_WLGP_DBC1)
+#define BIT_GET_WLGP_DBC1(x) (((x) >> BIT_SHIFT_WLGP_DBC1) & BIT_MASK_WLGP_DBC1)
+
+#define BIT_WLGP_DBC0EN BIT(7)
+
+#define BIT_SHIFT_WLGP_DBC0 0
+#define BIT_MASK_WLGP_DBC0 0xf
+#define BIT_WLGP_DBC0(x) (((x) & BIT_MASK_WLGP_DBC0) << BIT_SHIFT_WLGP_DBC0)
+#define BIT_GET_WLGP_DBC0(x) (((x) >> BIT_SHIFT_WLGP_DBC0) & BIT_MASK_WLGP_DBC0)
+
+/* 2 REG_RPWM2 (Offset 0x009C) */
+
+#define BIT_SHIFT_RPWM2 16
+#define BIT_MASK_RPWM2 0xffff
+#define BIT_RPWM2(x) (((x) & BIT_MASK_RPWM2) << BIT_SHIFT_RPWM2)
+#define BIT_GET_RPWM2(x) (((x) >> BIT_SHIFT_RPWM2) & BIT_MASK_RPWM2)
+
+/* 2 REG_SYSON_FSM_MON (Offset 0x00A0) */
+
+#define BIT_SHIFT_FSM_MON_SEL 24
+#define BIT_MASK_FSM_MON_SEL 0x7
+#define BIT_FSM_MON_SEL(x) \
+ (((x) & BIT_MASK_FSM_MON_SEL) << BIT_SHIFT_FSM_MON_SEL)
+#define BIT_GET_FSM_MON_SEL(x) \
+ (((x) >> BIT_SHIFT_FSM_MON_SEL) & BIT_MASK_FSM_MON_SEL)
+
+#define BIT_DOP_ELDO BIT(23)
+#define BIT_FSM_MON_UPD BIT(15)
+
+#define BIT_SHIFT_FSM_PAR 0
+#define BIT_MASK_FSM_PAR 0x7fff
+#define BIT_FSM_PAR(x) (((x) & BIT_MASK_FSM_PAR) << BIT_SHIFT_FSM_PAR)
+#define BIT_GET_FSM_PAR(x) (((x) >> BIT_SHIFT_FSM_PAR) & BIT_MASK_FSM_PAR)
+
+/* 2 REG_AFE_CTRL6 (Offset 0x00A4) */
+
+#define BIT_SHIFT_BB_DBG_SEL_AFE_SDM_BIT3_1 0
+#define BIT_MASK_BB_DBG_SEL_AFE_SDM_BIT3_1 0x7
+#define BIT_BB_DBG_SEL_AFE_SDM_BIT3_1(x) \
+ (((x) & BIT_MASK_BB_DBG_SEL_AFE_SDM_BIT3_1) \
+ << BIT_SHIFT_BB_DBG_SEL_AFE_SDM_BIT3_1)
+#define BIT_GET_BB_DBG_SEL_AFE_SDM_BIT3_1(x) \
+ (((x) >> BIT_SHIFT_BB_DBG_SEL_AFE_SDM_BIT3_1) & \
+ BIT_MASK_BB_DBG_SEL_AFE_SDM_BIT3_1)
+
+/* 2 REG_PMC_DBG_CTRL1 (Offset 0x00A8) */
+
+#define BIT_BT_INT_EN BIT(31)
+
+#define BIT_SHIFT_RD_WR_WIFI_BT_INFO 16
+#define BIT_MASK_RD_WR_WIFI_BT_INFO 0x7fff
+#define BIT_RD_WR_WIFI_BT_INFO(x) \
+ (((x) & BIT_MASK_RD_WR_WIFI_BT_INFO) << BIT_SHIFT_RD_WR_WIFI_BT_INFO)
+#define BIT_GET_RD_WR_WIFI_BT_INFO(x) \
+ (((x) >> BIT_SHIFT_RD_WR_WIFI_BT_INFO) & BIT_MASK_RD_WR_WIFI_BT_INFO)
+
+/* 2 REG_PMC_DBG_CTRL1 (Offset 0x00A8) */
+
+#define BIT_PMC_WR_OVF BIT(8)
+
+#define BIT_SHIFT_WLPMC_ERRINT 0
+#define BIT_MASK_WLPMC_ERRINT 0xff
+#define BIT_WLPMC_ERRINT(x) \
+ (((x) & BIT_MASK_WLPMC_ERRINT) << BIT_SHIFT_WLPMC_ERRINT)
+#define BIT_GET_WLPMC_ERRINT(x) \
+ (((x) >> BIT_SHIFT_WLPMC_ERRINT) & BIT_MASK_WLPMC_ERRINT)
+
+/* 2 REG_AFE_CTRL7 (Offset 0x00AC) */
+
+#define BIT_SHIFT_SEL_V 30
+#define BIT_MASK_SEL_V 0x3
+#define BIT_SEL_V(x) (((x) & BIT_MASK_SEL_V) << BIT_SHIFT_SEL_V)
+#define BIT_GET_SEL_V(x) (((x) >> BIT_SHIFT_SEL_V) & BIT_MASK_SEL_V)
+
+/* 2 REG_AFE_CTRL7 (Offset 0x00AC) */
+
+#define BIT_TXFIFO_TH_INT BIT(30)
+
+/* 2 REG_AFE_CTRL7 (Offset 0x00AC) */
+
+#define BIT_SEL_LDO_PC BIT(29)
+
+/* 2 REG_AFE_CTRL7 (Offset 0x00AC) */
+
+#define BIT_SHIFT_CK_MON_SEL 26
+#define BIT_MASK_CK_MON_SEL 0x7
+#define BIT_CK_MON_SEL(x) (((x) & BIT_MASK_CK_MON_SEL) << BIT_SHIFT_CK_MON_SEL)
+#define BIT_GET_CK_MON_SEL(x) \
+ (((x) >> BIT_SHIFT_CK_MON_SEL) & BIT_MASK_CK_MON_SEL)
+
+/* 2 REG_AFE_CTRL7 (Offset 0x00AC) */
+
+#define BIT_CK_MON_EN BIT(25)
+#define BIT_FREF_EDGE BIT(24)
+#define BIT_CK320M_EN BIT(23)
+#define BIT_CK_5M_EN BIT(22)
+#define BIT_TESTEN BIT(21)
+
+/* 2 REG_HIMR0 (Offset 0x00B0) */
+
+#define BIT_TIMEOUT_INTERRUPT2_MASK BIT(31)
+#define BIT_TIMEOUT_INTERRUTP1_MASK BIT(30)
+#define BIT_PSTIMEOUT_MSK BIT(29)
+#define BIT_GTINT4_MSK BIT(28)
+#define BIT_GTINT3_MSK BIT(27)
+#define BIT_TXBCN0ERR_MSK BIT(26)
+#define BIT_TXBCN0OK_MSK BIT(25)
+#define BIT_TSF_BIT32_TOGGLE_MSK BIT(24)
+#define BIT_BCNDMAINT0_MSK BIT(20)
+#define BIT_BCNDERR0_MSK BIT(16)
+#define BIT_HSISR_IND_ON_INT_MSK BIT(15)
+
+/* 2 REG_HIMR0 (Offset 0x00B0) */
+
+#define BIT_BCNDMAINT_E_MSK BIT(14)
+
+/* 2 REG_HIMR0 (Offset 0x00B0) */
+
+#define BIT_CTWEND_MSK BIT(12)
+#define BIT_HISR1_IND_MSK BIT(11)
+
+/* 2 REG_HIMR0 (Offset 0x00B0) */
+
+#define BIT_C2HCMD_MSK BIT(10)
+#define BIT_CPWM2_MSK BIT(9)
+#define BIT_CPWM_MSK BIT(8)
+#define BIT_HIGHDOK_MSK BIT(7)
+#define BIT_MGTDOK_MSK BIT(6)
+#define BIT_BKDOK_MSK BIT(5)
+#define BIT_BEDOK_MSK BIT(4)
+#define BIT_VIDOK_MSK BIT(3)
+#define BIT_VODOK_MSK BIT(2)
+#define BIT_RDU_MSK BIT(1)
+#define BIT_RXOK_MSK BIT(0)
+
+/* 2 REG_HISR0 (Offset 0x00B4) */
+
+#define BIT_TIMEOUT_INTERRUPT2 BIT(31)
+
+/* 2 REG_HISR0 (Offset 0x00B4) */
+
+#define BIT_TIMEOUT_INTERRUTP1 BIT(30)
+
+/* 2 REG_HISR0 (Offset 0x00B4) */
+
+#define BIT_PSTIMEOUT BIT(29)
+#define BIT_GTINT4 BIT(28)
+#define BIT_GTINT3 BIT(27)
+#define BIT_TXBCN0ERR BIT(26)
+#define BIT_TXBCN0OK BIT(25)
+#define BIT_TSF_BIT32_TOGGLE BIT(24)
+#define BIT_BCNDMAINT0 BIT(20)
+#define BIT_BCNDERR0 BIT(16)
+#define BIT_HSISR_IND_ON_INT BIT(15)
+
+/* 2 REG_HISR0 (Offset 0x00B4) */
+
+#define BIT_BCNDMAINT_E BIT(14)
+
+/* 2 REG_HISR0 (Offset 0x00B4) */
+
+#define BIT_CTWEND BIT(12)
+
+/* 2 REG_HISR0 (Offset 0x00B4) */
+
+#define BIT_HISR1_IND_INT BIT(11)
+#define BIT_C2HCMD BIT(10)
+#define BIT_CPWM2 BIT(9)
+#define BIT_CPWM BIT(8)
+#define BIT_HIGHDOK BIT(7)
+#define BIT_MGTDOK BIT(6)
+#define BIT_BKDOK BIT(5)
+#define BIT_BEDOK BIT(4)
+#define BIT_VIDOK BIT(3)
+#define BIT_VODOK BIT(2)
+#define BIT_RDU BIT(1)
+#define BIT_RXOK BIT(0)
+
+/* 2 REG_HIMR1 (Offset 0x00B8) */
+
+#define BIT_BTON_STS_UPDATE_MASK BIT(29)
+
+/* 2 REG_HIMR1 (Offset 0x00B8) */
+
+#define BIT_MCU_ERR_MASK BIT(28)
+
+/* 2 REG_HIMR1 (Offset 0x00B8) */
+
+#define BIT_BCNDMAINT7__MSK BIT(27)
+
+/* 2 REG_HIMR1 (Offset 0x00B8) */
+
+#define BIT_BCNDMAINT6__MSK BIT(26)
+
+/* 2 REG_HIMR1 (Offset 0x00B8) */
+
+#define BIT_BCNDMAINT5__MSK BIT(25)
+
+/* 2 REG_HIMR1 (Offset 0x00B8) */
+
+#define BIT_BCNDMAINT4__MSK BIT(24)
+
+/* 2 REG_HIMR1 (Offset 0x00B8) */
+
+#define BIT_BCNDMAINT3_MSK BIT(23)
+#define BIT_BCNDMAINT2_MSK BIT(22)
+#define BIT_BCNDMAINT1_MSK BIT(21)
+#define BIT_BCNDERR7_MSK BIT(20)
+#define BIT_BCNDERR6_MSK BIT(19)
+#define BIT_BCNDERR5_MSK BIT(18)
+#define BIT_BCNDERR4_MSK BIT(17)
+#define BIT_BCNDERR3_MSK BIT(16)
+#define BIT_BCNDERR2_MSK BIT(15)
+#define BIT_BCNDERR1_MSK BIT(14)
+
+/* 2 REG_HIMR1 (Offset 0x00B8) */
+
+#define BIT_ATIMEND_E_MSK BIT(13)
+
+/* 2 REG_HIMR1 (Offset 0x00B8) */
+
+#define BIT_ATIMEND__MSK BIT(12)
+
+/* 2 REG_HIMR1 (Offset 0x00B8) */
+
+#define BIT_TXERR_MSK BIT(11)
+#define BIT_RXERR_MSK BIT(10)
+#define BIT_TXFOVW_MSK BIT(9)
+#define BIT_FOVW_MSK BIT(8)
+
+/* 2 REG_HIMR1 (Offset 0x00B8) */
+
+#define BIT_CPU_MGQ_TXDONE_MSK BIT(5)
+#define BIT_PS_TIMER_C_MSK BIT(4)
+#define BIT_PS_TIMER_B_MSK BIT(3)
+#define BIT_PS_TIMER_A_MSK BIT(2)
+#define BIT_CPUMGQ_TX_TIMER_MSK BIT(1)
+
+/* 2 REG_HISR1 (Offset 0x00BC) */
+
+#define BIT_BTON_STS_UPDATE_INT BIT(29)
+
+/* 2 REG_HISR1 (Offset 0x00BC) */
+
+#define BIT_MCU_ERR BIT(28)
+
+/* 2 REG_HISR1 (Offset 0x00BC) */
+
+#define BIT_BCNDMAINT7 BIT(27)
+#define BIT_BCNDMAINT6 BIT(26)
+#define BIT_BCNDMAINT5 BIT(25)
+#define BIT_BCNDMAINT4 BIT(24)
+#define BIT_BCNDMAINT3 BIT(23)
+#define BIT_BCNDMAINT2 BIT(22)
+#define BIT_BCNDMAINT1 BIT(21)
+#define BIT_BCNDERR7 BIT(20)
+#define BIT_BCNDERR6 BIT(19)
+#define BIT_BCNDERR5 BIT(18)
+#define BIT_BCNDERR4 BIT(17)
+#define BIT_BCNDERR3 BIT(16)
+#define BIT_BCNDERR2 BIT(15)
+#define BIT_BCNDERR1 BIT(14)
+
+/* 2 REG_HISR1 (Offset 0x00BC) */
+
+#define BIT_ATIMEND_E BIT(13)
+
+/* 2 REG_HISR1 (Offset 0x00BC) */
+
+#define BIT_ATIMEND BIT(12)
+#define BIT_TXERR_INT BIT(11)
+#define BIT_RXERR_INT BIT(10)
+#define BIT_TXFOVW BIT(9)
+#define BIT_FOVW BIT(8)
+
+/* 2 REG_HISR1 (Offset 0x00BC) */
+
+#define BIT_CPU_MGQ_TXDONE BIT(5)
+#define BIT_PS_TIMER_C BIT(4)
+#define BIT_PS_TIMER_B BIT(3)
+#define BIT_PS_TIMER_A BIT(2)
+#define BIT_CPUMGQ_TX_TIMER BIT(1)
+
+/* 2 REG_SDIO_ERR_RPT (Offset 0x102500C0) */
+
+#define BIT_HR_FF_OVF BIT(6)
+#define BIT_HR_FF_UDN BIT(5)
+#define BIT_TXDMA_BUSY_ERR BIT(4)
+#define BIT_TXDMA_VLD_ERR BIT(3)
+#define BIT_QSEL_UNKNOWN_ERR BIT(2)
+#define BIT_QSEL_MIS_ERR BIT(1)
+
+/* 2 REG_DBG_PORT_SEL (Offset 0x00C0) */
+
+#define BIT_SHIFT_DEBUG_ST 0
+#define BIT_MASK_DEBUG_ST 0xffffffffL
+#define BIT_DEBUG_ST(x) (((x) & BIT_MASK_DEBUG_ST) << BIT_SHIFT_DEBUG_ST)
+#define BIT_GET_DEBUG_ST(x) (((x) >> BIT_SHIFT_DEBUG_ST) & BIT_MASK_DEBUG_ST)
+
+/* 2 REG_SDIO_ERR_RPT (Offset 0x102500C0) */
+
+#define BIT_SDIO_OVERRD_ERR BIT(0)
+
+/* 2 REG_SDIO_CMD_ERRCNT (Offset 0x102500C1) */
+
+#define BIT_SHIFT_CMD_CRC_ERR_CNT 0
+#define BIT_MASK_CMD_CRC_ERR_CNT 0xff
+#define BIT_CMD_CRC_ERR_CNT(x) \
+ (((x) & BIT_MASK_CMD_CRC_ERR_CNT) << BIT_SHIFT_CMD_CRC_ERR_CNT)
+#define BIT_GET_CMD_CRC_ERR_CNT(x) \
+ (((x) >> BIT_SHIFT_CMD_CRC_ERR_CNT) & BIT_MASK_CMD_CRC_ERR_CNT)
+
+/* 2 REG_SDIO_DATA_ERRCNT (Offset 0x102500C2) */
+
+#define BIT_SHIFT_DATA_CRC_ERR_CNT 0
+#define BIT_MASK_DATA_CRC_ERR_CNT 0xff
+#define BIT_DATA_CRC_ERR_CNT(x) \
+ (((x) & BIT_MASK_DATA_CRC_ERR_CNT) << BIT_SHIFT_DATA_CRC_ERR_CNT)
+#define BIT_GET_DATA_CRC_ERR_CNT(x) \
+ (((x) >> BIT_SHIFT_DATA_CRC_ERR_CNT) & BIT_MASK_DATA_CRC_ERR_CNT)
+
+/* 2 REG_PAD_CTRL2 (Offset 0x00C4) */
+
+#define BIT_USB3_USB2_TRANSITION BIT(20)
+
+/* 2 REG_PAD_CTRL2 (Offset 0x00C4) */
+
+#define BIT_SHIFT_USB23_SW_MODE_V1 18
+#define BIT_MASK_USB23_SW_MODE_V1 0x3
+#define BIT_USB23_SW_MODE_V1(x) \
+ (((x) & BIT_MASK_USB23_SW_MODE_V1) << BIT_SHIFT_USB23_SW_MODE_V1)
+#define BIT_GET_USB23_SW_MODE_V1(x) \
+ (((x) >> BIT_SHIFT_USB23_SW_MODE_V1) & BIT_MASK_USB23_SW_MODE_V1)
+
+/* 2 REG_PAD_CTRL2 (Offset 0x00C4) */
+
+#define BIT_NO_PDN_CHIPOFF_V1 BIT(17)
+
+/* 2 REG_PAD_CTRL2 (Offset 0x00C4) */
+
+#define BIT_RSM_EN_V1 BIT(16)
+
+/* 2 REG_PAD_CTRL2 (Offset 0x00C4) */
+
+#define BIT_LD_B12V_EN BIT(7)
+
+/* 2 REG_PAD_CTRL2 (Offset 0x00C4) */
+
+#define BIT_EECS_IOSEL_V1 BIT(6)
+
+/* 2 REG_PAD_CTRL2 (Offset 0x00C4) */
+
+#define BIT_EECS_DATA_O_V1 BIT(5)
+
+/* 2 REG_PAD_CTRL2 (Offset 0x00C4) */
+
+#define BIT_EECS_DATA_I_V1 BIT(4)
+
+/* 2 REG_PAD_CTRL2 (Offset 0x00C4) */
+
+#define BIT_EESK_IOSEL_V1 BIT(2)
+
+/* 2 REG_PAD_CTRL2 (Offset 0x00C4) */
+
+#define BIT_EESK_DATA_O_V1 BIT(1)
+
+/* 2 REG_PAD_CTRL2 (Offset 0x00C4) */
+
+#define BIT_EESK_DATA_I_V1 BIT(0)
+
+/* 2 REG_SDIO_CMD_ERR_CONTENT (Offset 0x102500C4) */
+
+#define BIT_SHIFT_SDIO_CMD_ERR_CONTENT 0
+#define BIT_MASK_SDIO_CMD_ERR_CONTENT 0xffffffffffL
+#define BIT_SDIO_CMD_ERR_CONTENT(x) \
+ (((x) & BIT_MASK_SDIO_CMD_ERR_CONTENT) \
+ << BIT_SHIFT_SDIO_CMD_ERR_CONTENT)
+#define BIT_GET_SDIO_CMD_ERR_CONTENT(x) \
+ (((x) >> BIT_SHIFT_SDIO_CMD_ERR_CONTENT) & \
+ BIT_MASK_SDIO_CMD_ERR_CONTENT)
+
+/* 2 REG_SDIO_CRC_ERR_IDX (Offset 0x102500C9) */
+
+#define BIT_D3_CRC_ERR BIT(4)
+#define BIT_D2_CRC_ERR BIT(3)
+#define BIT_D1_CRC_ERR BIT(2)
+#define BIT_D0_CRC_ERR BIT(1)
+#define BIT_CMD_CRC_ERR BIT(0)
+
+/* 2 REG_SDIO_DATA_CRC (Offset 0x102500CA) */
+
+#define BIT_SHIFT_SDIO_DATA_CRC 0
+#define BIT_MASK_SDIO_DATA_CRC 0xff
+#define BIT_SDIO_DATA_CRC(x) \
+ (((x) & BIT_MASK_SDIO_DATA_CRC) << BIT_SHIFT_SDIO_DATA_CRC)
+#define BIT_GET_SDIO_DATA_CRC(x) \
+ (((x) >> BIT_SHIFT_SDIO_DATA_CRC) & BIT_MASK_SDIO_DATA_CRC)
+
+/* 2 REG_SDIO_DATA_REPLY_TIME (Offset 0x102500CB) */
+
+#define BIT_SHIFT_SDIO_DATA_REPLY_TIME 0
+#define BIT_MASK_SDIO_DATA_REPLY_TIME 0x7
+#define BIT_SDIO_DATA_REPLY_TIME(x) \
+ (((x) & BIT_MASK_SDIO_DATA_REPLY_TIME) \
+ << BIT_SHIFT_SDIO_DATA_REPLY_TIME)
+#define BIT_GET_SDIO_DATA_REPLY_TIME(x) \
+ (((x) >> BIT_SHIFT_SDIO_DATA_REPLY_TIME) & \
+ BIT_MASK_SDIO_DATA_REPLY_TIME)
+
+/* 2 REG_PMC_DBG_CTRL2 (Offset 0x00CC) */
+
+#define BIT_SHIFT_EFUSE_BURN_GNT 24
+#define BIT_MASK_EFUSE_BURN_GNT 0xff
+#define BIT_EFUSE_BURN_GNT(x) \
+ (((x) & BIT_MASK_EFUSE_BURN_GNT) << BIT_SHIFT_EFUSE_BURN_GNT)
+#define BIT_GET_EFUSE_BURN_GNT(x) \
+ (((x) >> BIT_SHIFT_EFUSE_BURN_GNT) & BIT_MASK_EFUSE_BURN_GNT)
+
+/* 2 REG_PMC_DBG_CTRL2 (Offset 0x00CC) */
+
+#define BIT_STOP_WL_PMC BIT(9)
+#define BIT_STOP_SYM_PMC BIT(8)
+
+/* 2 REG_PMC_DBG_CTRL2 (Offset 0x00CC) */
+
+#define BIT_REG_RST_WLPMC BIT(5)
+#define BIT_REG_RST_PD12N BIT(4)
+#define BIT_SYSON_DIS_WLREG_WRMSK BIT(3)
+#define BIT_SYSON_DIS_PMCREG_WRMSK BIT(2)
+
+#define BIT_SHIFT_SYSON_REG_ARB 0
+#define BIT_MASK_SYSON_REG_ARB 0x3
+#define BIT_SYSON_REG_ARB(x) \
+ (((x) & BIT_MASK_SYSON_REG_ARB) << BIT_SHIFT_SYSON_REG_ARB)
+#define BIT_GET_SYSON_REG_ARB(x) \
+ (((x) >> BIT_SHIFT_SYSON_REG_ARB) & BIT_MASK_SYSON_REG_ARB)
+
+/* 2 REG_BIST_CTRL (Offset 0x00D0) */
+
+#define BIT_BIST_USB_DIS BIT(27)
+
+/* 2 REG_BIST_CTRL (Offset 0x00D0) */
+
+#define BIT_BIST_PCI_DIS BIT(26)
+
+/* 2 REG_BIST_CTRL (Offset 0x00D0) */
+
+#define BIT_BIST_BT_DIS BIT(25)
+
+/* 2 REG_BIST_CTRL (Offset 0x00D0) */
+
+#define BIT_BIST_WL_DIS BIT(24)
+
+/* 2 REG_BIST_CTRL (Offset 0x00D0) */
+
+#define BIT_SHIFT_BIST_RPT_SEL 16
+#define BIT_MASK_BIST_RPT_SEL 0xf
+#define BIT_BIST_RPT_SEL(x) \
+ (((x) & BIT_MASK_BIST_RPT_SEL) << BIT_SHIFT_BIST_RPT_SEL)
+#define BIT_GET_BIST_RPT_SEL(x) \
+ (((x) >> BIT_SHIFT_BIST_RPT_SEL) & BIT_MASK_BIST_RPT_SEL)
+
+/* 2 REG_BIST_CTRL (Offset 0x00D0) */
+
+#define BIT_BIST_RESUME_PS BIT(4)
+
+/* 2 REG_BIST_CTRL (Offset 0x00D0) */
+
+#define BIT_BIST_RESUME BIT(3)
+#define BIT_BIST_NORMAL BIT(2)
+
+/* 2 REG_BIST_CTRL (Offset 0x00D0) */
+
+#define BIT_BIST_RSTN BIT(1)
+#define BIT_BIST_CLK_EN BIT(0)
+
+/* 2 REG_BIST_RPT (Offset 0x00D4) */
+
+#define BIT_SHIFT_MBIST_REPORT 0
+#define BIT_MASK_MBIST_REPORT 0xffffffffL
+#define BIT_MBIST_REPORT(x) \
+ (((x) & BIT_MASK_MBIST_REPORT) << BIT_SHIFT_MBIST_REPORT)
+#define BIT_GET_MBIST_REPORT(x) \
+ (((x) >> BIT_SHIFT_MBIST_REPORT) & BIT_MASK_MBIST_REPORT)
+
+/* 2 REG_MEM_CTRL (Offset 0x00D8) */
+
+#define BIT_UMEM_RME BIT(31)
+
+/* 2 REG_MEM_CTRL (Offset 0x00D8) */
+
+#define BIT_SHIFT_BT_SPRAM 28
+#define BIT_MASK_BT_SPRAM 0x3
+#define BIT_BT_SPRAM(x) (((x) & BIT_MASK_BT_SPRAM) << BIT_SHIFT_BT_SPRAM)
+#define BIT_GET_BT_SPRAM(x) (((x) >> BIT_SHIFT_BT_SPRAM) & BIT_MASK_BT_SPRAM)
+
+/* 2 REG_MEM_CTRL (Offset 0x00D8) */
+
+#define BIT_SHIFT_BT_ROM 24
+#define BIT_MASK_BT_ROM 0xf
+#define BIT_BT_ROM(x) (((x) & BIT_MASK_BT_ROM) << BIT_SHIFT_BT_ROM)
+#define BIT_GET_BT_ROM(x) (((x) >> BIT_SHIFT_BT_ROM) & BIT_MASK_BT_ROM)
+
+#define BIT_SHIFT_PCI_DPRAM 10
+#define BIT_MASK_PCI_DPRAM 0x3
+#define BIT_PCI_DPRAM(x) (((x) & BIT_MASK_PCI_DPRAM) << BIT_SHIFT_PCI_DPRAM)
+#define BIT_GET_PCI_DPRAM(x) (((x) >> BIT_SHIFT_PCI_DPRAM) & BIT_MASK_PCI_DPRAM)
+
+/* 2 REG_MEM_CTRL (Offset 0x00D8) */
+
+#define BIT_SHIFT_PCI_SPRAM 8
+#define BIT_MASK_PCI_SPRAM 0x3
+#define BIT_PCI_SPRAM(x) (((x) & BIT_MASK_PCI_SPRAM) << BIT_SHIFT_PCI_SPRAM)
+#define BIT_GET_PCI_SPRAM(x) (((x) >> BIT_SHIFT_PCI_SPRAM) & BIT_MASK_PCI_SPRAM)
+
+#define BIT_SHIFT_USB_SPRAM 6
+#define BIT_MASK_USB_SPRAM 0x3
+#define BIT_USB_SPRAM(x) (((x) & BIT_MASK_USB_SPRAM) << BIT_SHIFT_USB_SPRAM)
+#define BIT_GET_USB_SPRAM(x) (((x) >> BIT_SHIFT_USB_SPRAM) & BIT_MASK_USB_SPRAM)
+
+/* 2 REG_MEM_CTRL (Offset 0x00D8) */
+
+#define BIT_SHIFT_USB_SPRF 4
+#define BIT_MASK_USB_SPRF 0x3
+#define BIT_USB_SPRF(x) (((x) & BIT_MASK_USB_SPRF) << BIT_SHIFT_USB_SPRF)
+#define BIT_GET_USB_SPRF(x) (((x) >> BIT_SHIFT_USB_SPRF) & BIT_MASK_USB_SPRF)
+
+/* 2 REG_MEM_CTRL (Offset 0x00D8) */
+
+#define BIT_SHIFT_MCU_ROM 0
+#define BIT_MASK_MCU_ROM 0xf
+#define BIT_MCU_ROM(x) (((x) & BIT_MASK_MCU_ROM) << BIT_SHIFT_MCU_ROM)
+#define BIT_GET_MCU_ROM(x) (((x) >> BIT_SHIFT_MCU_ROM) & BIT_MASK_MCU_ROM)
+
+/* 2 REG_AFE_CTRL8 (Offset 0x00DC) */
+
+#define BIT_SYN_AGPIO BIT(20)
+
+/* 2 REG_AFE_CTRL8 (Offset 0x00DC) */
+
+#define BIT_XTAL_LP BIT(4)
+#define BIT_XTAL_GM_SEP BIT(3)
+
+/* 2 REG_AFE_CTRL8 (Offset 0x00DC) */
+
+#define BIT_SHIFT_XTAL_SEL_TOK 0
+#define BIT_MASK_XTAL_SEL_TOK 0x7
+#define BIT_XTAL_SEL_TOK(x) \
+ (((x) & BIT_MASK_XTAL_SEL_TOK) << BIT_SHIFT_XTAL_SEL_TOK)
+#define BIT_GET_XTAL_SEL_TOK(x) \
+ (((x) >> BIT_SHIFT_XTAL_SEL_TOK) & BIT_MASK_XTAL_SEL_TOK)
+
+/* 2 REG_USB_SIE_INTF (Offset 0x00E0) */
+
+#define BIT_RD_SEL BIT(31)
+
+/* 2 REG_USB_SIE_INTF (Offset 0x00E0) */
+
+#define BIT_USB_SIE_INTF_WE_V1 BIT(30)
+#define BIT_USB_SIE_INTF_BYIOREG_V1 BIT(29)
+#define BIT_USB_SIE_SELECT BIT(28)
+
+/* 2 REG_USB_SIE_INTF (Offset 0x00E0) */
+
+#define BIT_SHIFT_USB_SIE_INTF_ADDR_V1 16
+#define BIT_MASK_USB_SIE_INTF_ADDR_V1 0x1ff
+#define BIT_USB_SIE_INTF_ADDR_V1(x) \
+ (((x) & BIT_MASK_USB_SIE_INTF_ADDR_V1) \
+ << BIT_SHIFT_USB_SIE_INTF_ADDR_V1)
+#define BIT_GET_USB_SIE_INTF_ADDR_V1(x) \
+ (((x) >> BIT_SHIFT_USB_SIE_INTF_ADDR_V1) & \
+ BIT_MASK_USB_SIE_INTF_ADDR_V1)
+
+/* 2 REG_USB_SIE_INTF (Offset 0x00E0) */
+
+#define BIT_SHIFT_USB_SIE_INTF_RD 8
+#define BIT_MASK_USB_SIE_INTF_RD 0xff
+#define BIT_USB_SIE_INTF_RD(x) \
+ (((x) & BIT_MASK_USB_SIE_INTF_RD) << BIT_SHIFT_USB_SIE_INTF_RD)
+#define BIT_GET_USB_SIE_INTF_RD(x) \
+ (((x) >> BIT_SHIFT_USB_SIE_INTF_RD) & BIT_MASK_USB_SIE_INTF_RD)
+
+#define BIT_SHIFT_USB_SIE_INTF_WD 0
+#define BIT_MASK_USB_SIE_INTF_WD 0xff
+#define BIT_USB_SIE_INTF_WD(x) \
+ (((x) & BIT_MASK_USB_SIE_INTF_WD) << BIT_SHIFT_USB_SIE_INTF_WD)
+#define BIT_GET_USB_SIE_INTF_WD(x) \
+ (((x) >> BIT_SHIFT_USB_SIE_INTF_WD) & BIT_MASK_USB_SIE_INTF_WD)
+
+/* 2 REG_PCIE_MIO_INTF (Offset 0x00E4) */
+
+#define BIT_PCIE_MIO_BYIOREG BIT(13)
+#define BIT_PCIE_MIO_RE BIT(12)
+
+#define BIT_SHIFT_PCIE_MIO_WE 8
+#define BIT_MASK_PCIE_MIO_WE 0xf
+#define BIT_PCIE_MIO_WE(x) \
+ (((x) & BIT_MASK_PCIE_MIO_WE) << BIT_SHIFT_PCIE_MIO_WE)
+#define BIT_GET_PCIE_MIO_WE(x) \
+ (((x) >> BIT_SHIFT_PCIE_MIO_WE) & BIT_MASK_PCIE_MIO_WE)
+
+#define BIT_SHIFT_PCIE_MIO_ADDR 0
+#define BIT_MASK_PCIE_MIO_ADDR 0xff
+#define BIT_PCIE_MIO_ADDR(x) \
+ (((x) & BIT_MASK_PCIE_MIO_ADDR) << BIT_SHIFT_PCIE_MIO_ADDR)
+#define BIT_GET_PCIE_MIO_ADDR(x) \
+ (((x) >> BIT_SHIFT_PCIE_MIO_ADDR) & BIT_MASK_PCIE_MIO_ADDR)
+
+/* 2 REG_PCIE_MIO_INTD (Offset 0x00E8) */
+
+#define BIT_SHIFT_PCIE_MIO_DATA 0
+#define BIT_MASK_PCIE_MIO_DATA 0xffffffffL
+#define BIT_PCIE_MIO_DATA(x) \
+ (((x) & BIT_MASK_PCIE_MIO_DATA) << BIT_SHIFT_PCIE_MIO_DATA)
+#define BIT_GET_PCIE_MIO_DATA(x) \
+ (((x) >> BIT_SHIFT_PCIE_MIO_DATA) & BIT_MASK_PCIE_MIO_DATA)
+
+/* 2 REG_WLRF1 (Offset 0x00EC) */
+
+#define BIT_SHIFT_WLRF1_CTRL 24
+#define BIT_MASK_WLRF1_CTRL 0xff
+#define BIT_WLRF1_CTRL(x) (((x) & BIT_MASK_WLRF1_CTRL) << BIT_SHIFT_WLRF1_CTRL)
+#define BIT_GET_WLRF1_CTRL(x) \
+ (((x) >> BIT_SHIFT_WLRF1_CTRL) & BIT_MASK_WLRF1_CTRL)
+
+/* 2 REG_SYS_CFG1 (Offset 0x00F0) */
+
+#define BIT_SHIFT_TRP_ICFG 28
+#define BIT_MASK_TRP_ICFG 0xf
+#define BIT_TRP_ICFG(x) (((x) & BIT_MASK_TRP_ICFG) << BIT_SHIFT_TRP_ICFG)
+#define BIT_GET_TRP_ICFG(x) (((x) >> BIT_SHIFT_TRP_ICFG) & BIT_MASK_TRP_ICFG)
+
+/* 2 REG_SYS_CFG1 (Offset 0x00F0) */
+
+#define BIT_RF_TYPE_ID BIT(27)
+#define BIT_BD_HCI_SEL BIT(26)
+
+/* 2 REG_SYS_CFG1 (Offset 0x00F0) */
+
+#define BIT_BD_PKG_SEL BIT(25)
+
+/* 2 REG_SYS_CFG1 (Offset 0x00F0) */
+
+#define BIT_SPSLDO_SEL BIT(24)
+
+/* 2 REG_SYS_CFG1 (Offset 0x00F0) */
+
+#define BIT_RTL_ID BIT(23)
+#define BIT_PAD_HWPD_IDN BIT(22)
+
+/* 2 REG_SYS_CFG1 (Offset 0x00F0) */
+
+#define BIT_TESTMODE BIT(20)
+
+/* 2 REG_SYS_CFG1 (Offset 0x00F0) */
+
+#define BIT_SHIFT_VENDOR_ID 16
+#define BIT_MASK_VENDOR_ID 0xf
+#define BIT_VENDOR_ID(x) (((x) & BIT_MASK_VENDOR_ID) << BIT_SHIFT_VENDOR_ID)
+#define BIT_GET_VENDOR_ID(x) (((x) >> BIT_SHIFT_VENDOR_ID) & BIT_MASK_VENDOR_ID)
+
+/* 2 REG_SYS_CFG1 (Offset 0x00F0) */
+
+#define BIT_SHIFT_CHIP_VER 12
+#define BIT_MASK_CHIP_VER 0xf
+#define BIT_CHIP_VER(x) (((x) & BIT_MASK_CHIP_VER) << BIT_SHIFT_CHIP_VER)
+#define BIT_GET_CHIP_VER(x) (((x) >> BIT_SHIFT_CHIP_VER) & BIT_MASK_CHIP_VER)
+
+/* 2 REG_SYS_CFG1 (Offset 0x00F0) */
+
+#define BIT_BD_MAC3 BIT(11)
+
+/* 2 REG_SYS_CFG1 (Offset 0x00F0) */
+
+#define BIT_BD_MAC1 BIT(10)
+#define BIT_BD_MAC2 BIT(9)
+#define BIT_SIC_IDLE BIT(8)
+#define BIT_SW_OFFLOAD_EN BIT(7)
+
+/* 2 REG_SYS_CFG1 (Offset 0x00F0) */
+
+#define BIT_OCP_SHUTDN BIT(6)
+
+/* 2 REG_SYS_CFG1 (Offset 0x00F0) */
+
+#define BIT_V15_VLD BIT(5)
+
+/* 2 REG_SYS_CFG1 (Offset 0x00F0) */
+
+#define BIT_PCIRSTB BIT(4)
+
+/* 2 REG_SYS_CFG1 (Offset 0x00F0) */
+
+#define BIT_PCLK_VLD BIT(3)
+
+/* 2 REG_SYS_CFG1 (Offset 0x00F0) */
+
+#define BIT_UCLK_VLD BIT(2)
+
+/* 2 REG_SYS_CFG1 (Offset 0x00F0) */
+
+#define BIT_ACLK_VLD BIT(1)
+
+/* 2 REG_SYS_CFG1 (Offset 0x00F0) */
+
+#define BIT_XCLK_VLD BIT(0)
+
+/* 2 REG_SYS_STATUS1 (Offset 0x00F4) */
+
+#define BIT_SHIFT_RF_RL_ID 28
+#define BIT_MASK_RF_RL_ID 0xf
+#define BIT_RF_RL_ID(x) (((x) & BIT_MASK_RF_RL_ID) << BIT_SHIFT_RF_RL_ID)
+#define BIT_GET_RF_RL_ID(x) (((x) >> BIT_SHIFT_RF_RL_ID) & BIT_MASK_RF_RL_ID)
+
+/* 2 REG_SYS_STATUS1 (Offset 0x00F4) */
+
+#define BIT_HPHY_ICFG BIT(19)
+
+/* 2 REG_SYS_STATUS1 (Offset 0x00F4) */
+
+#define BIT_SHIFT_SEL_0XC0 16
+#define BIT_MASK_SEL_0XC0 0x3
+#define BIT_SEL_0XC0(x) (((x) & BIT_MASK_SEL_0XC0) << BIT_SHIFT_SEL_0XC0)
+#define BIT_GET_SEL_0XC0(x) (((x) >> BIT_SHIFT_SEL_0XC0) & BIT_MASK_SEL_0XC0)
+
+/* 2 REG_SYS_STATUS1 (Offset 0x00F4) */
+
+#define BIT_SHIFT_HCI_SEL_V3 12
+#define BIT_MASK_HCI_SEL_V3 0x7
+#define BIT_HCI_SEL_V3(x) (((x) & BIT_MASK_HCI_SEL_V3) << BIT_SHIFT_HCI_SEL_V3)
+#define BIT_GET_HCI_SEL_V3(x) \
+ (((x) >> BIT_SHIFT_HCI_SEL_V3) & BIT_MASK_HCI_SEL_V3)
+
+/* 2 REG_SYS_STATUS1 (Offset 0x00F4) */
+
+#define BIT_USB_OPERATION_MODE BIT(10)
+#define BIT_BT_PDN BIT(9)
+#define BIT_AUTO_WLPON BIT(8)
+
+/* 2 REG_SYS_STATUS1 (Offset 0x00F4) */
+
+#define BIT_WL_MODE BIT(7)
+
+/* 2 REG_SYS_STATUS1 (Offset 0x00F4) */
+
+#define BIT_PKG_SEL_HCI BIT(6)
+
+/* 2 REG_SYS_STATUS1 (Offset 0x00F4) */
+
+#define BIT_SHIFT_PAD_HCI_SEL_V1 3
+#define BIT_MASK_PAD_HCI_SEL_V1 0x7
+#define BIT_PAD_HCI_SEL_V1(x) \
+ (((x) & BIT_MASK_PAD_HCI_SEL_V1) << BIT_SHIFT_PAD_HCI_SEL_V1)
+#define BIT_GET_PAD_HCI_SEL_V1(x) \
+ (((x) >> BIT_SHIFT_PAD_HCI_SEL_V1) & BIT_MASK_PAD_HCI_SEL_V1)
+
+/* 2 REG_SYS_STATUS1 (Offset 0x00F4) */
+
+#define BIT_SHIFT_EFS_HCI_SEL_V1 0
+#define BIT_MASK_EFS_HCI_SEL_V1 0x7
+#define BIT_EFS_HCI_SEL_V1(x) \
+ (((x) & BIT_MASK_EFS_HCI_SEL_V1) << BIT_SHIFT_EFS_HCI_SEL_V1)
+#define BIT_GET_EFS_HCI_SEL_V1(x) \
+ (((x) >> BIT_SHIFT_EFS_HCI_SEL_V1) & BIT_MASK_EFS_HCI_SEL_V1)
+
+/* 2 REG_SYS_STATUS2 (Offset 0x00F8) */
+
+#define BIT_SIO_ALDN BIT(19)
+#define BIT_USB_ALDN BIT(18)
+#define BIT_PCI_ALDN BIT(17)
+#define BIT_SYS_ALDN BIT(16)
+
+#define BIT_SHIFT_EPVID1 8
+#define BIT_MASK_EPVID1 0xff
+#define BIT_EPVID1(x) (((x) & BIT_MASK_EPVID1) << BIT_SHIFT_EPVID1)
+#define BIT_GET_EPVID1(x) (((x) >> BIT_SHIFT_EPVID1) & BIT_MASK_EPVID1)
+
+#define BIT_SHIFT_EPVID0 0
+#define BIT_MASK_EPVID0 0xff
+#define BIT_EPVID0(x) (((x) & BIT_MASK_EPVID0) << BIT_SHIFT_EPVID0)
+#define BIT_GET_EPVID0(x) (((x) >> BIT_SHIFT_EPVID0) & BIT_MASK_EPVID0)
+
+/* 2 REG_SYS_CFG2 (Offset 0x00FC) */
+
+#define BIT_HCI_SEL_EMBEDDED BIT(8)
+
+/* 2 REG_SYS_CFG2 (Offset 0x00FC) */
+
+#define BIT_SHIFT_HW_ID 0
+#define BIT_MASK_HW_ID 0xff
+#define BIT_HW_ID(x) (((x) & BIT_MASK_HW_ID) << BIT_SHIFT_HW_ID)
+#define BIT_GET_HW_ID(x) (((x) >> BIT_SHIFT_HW_ID) & BIT_MASK_HW_ID)
+
+/* 2 REG_CR (Offset 0x0100) */
+
+#define BIT_SHIFT_LBMODE 24
+#define BIT_MASK_LBMODE 0x1f
+#define BIT_LBMODE(x) (((x) & BIT_MASK_LBMODE) << BIT_SHIFT_LBMODE)
+#define BIT_GET_LBMODE(x) (((x) >> BIT_SHIFT_LBMODE) & BIT_MASK_LBMODE)
+
+#define BIT_SHIFT_NETYPE1 18
+#define BIT_MASK_NETYPE1 0x3
+#define BIT_NETYPE1(x) (((x) & BIT_MASK_NETYPE1) << BIT_SHIFT_NETYPE1)
+#define BIT_GET_NETYPE1(x) (((x) >> BIT_SHIFT_NETYPE1) & BIT_MASK_NETYPE1)
+
+#define BIT_SHIFT_NETYPE0 16
+#define BIT_MASK_NETYPE0 0x3
+#define BIT_NETYPE0(x) (((x) & BIT_MASK_NETYPE0) << BIT_SHIFT_NETYPE0)
+#define BIT_GET_NETYPE0(x) (((x) >> BIT_SHIFT_NETYPE0) & BIT_MASK_NETYPE0)
+
+/* 2 REG_CR (Offset 0x0100) */
+
+#define BIT_I2C_MAILBOX_EN BIT(12)
+#define BIT_SHCUT_EN BIT(11)
+
+/* 2 REG_CR (Offset 0x0100) */
+
+#define BIT_32K_CAL_TMR_EN BIT(10)
+#define BIT_MAC_SEC_EN BIT(9)
+#define BIT_ENSWBCN BIT(8)
+#define BIT_MACRXEN BIT(7)
+#define BIT_MACTXEN BIT(6)
+#define BIT_SCHEDULE_EN BIT(5)
+#define BIT_PROTOCOL_EN BIT(4)
+#define BIT_RXDMA_EN BIT(3)
+#define BIT_TXDMA_EN BIT(2)
+#define BIT_HCI_RXDMA_EN BIT(1)
+#define BIT_HCI_TXDMA_EN BIT(0)
+
+/* 2 REG_PKT_BUFF_ACCESS_CTRL (Offset 0x0106) */
+
+#define BIT_SHIFT_PKT_BUFF_ACCESS_CTRL 0
+#define BIT_MASK_PKT_BUFF_ACCESS_CTRL 0xff
+#define BIT_PKT_BUFF_ACCESS_CTRL(x) \
+ (((x) & BIT_MASK_PKT_BUFF_ACCESS_CTRL) \
+ << BIT_SHIFT_PKT_BUFF_ACCESS_CTRL)
+#define BIT_GET_PKT_BUFF_ACCESS_CTRL(x) \
+ (((x) >> BIT_SHIFT_PKT_BUFF_ACCESS_CTRL) & \
+ BIT_MASK_PKT_BUFF_ACCESS_CTRL)
+
+/* 2 REG_TSF_CLK_STATE (Offset 0x0108) */
+
+#define BIT_TSF_CLK_STABLE BIT(15)
+
+#define BIT_SHIFT_I2C_M_BUS_GNT_FW 4
+#define BIT_MASK_I2C_M_BUS_GNT_FW 0x7
+#define BIT_I2C_M_BUS_GNT_FW(x) \
+ (((x) & BIT_MASK_I2C_M_BUS_GNT_FW) << BIT_SHIFT_I2C_M_BUS_GNT_FW)
+#define BIT_GET_I2C_M_BUS_GNT_FW(x) \
+ (((x) >> BIT_SHIFT_I2C_M_BUS_GNT_FW) & BIT_MASK_I2C_M_BUS_GNT_FW)
+
+#define BIT_I2C_M_GNT_FW BIT(3)
+
+#define BIT_SHIFT_I2C_M_SPEED 1
+#define BIT_MASK_I2C_M_SPEED 0x3
+#define BIT_I2C_M_SPEED(x) \
+ (((x) & BIT_MASK_I2C_M_SPEED) << BIT_SHIFT_I2C_M_SPEED)
+#define BIT_GET_I2C_M_SPEED(x) \
+ (((x) >> BIT_SHIFT_I2C_M_SPEED) & BIT_MASK_I2C_M_SPEED)
+
+#define BIT_I2C_M_UNLOCK BIT(0)
+
+/* 2 REG_TXDMA_PQ_MAP (Offset 0x010C) */
+
+#define BIT_SHIFT_TXDMA_HIQ_MAP 14
+#define BIT_MASK_TXDMA_HIQ_MAP 0x3
+#define BIT_TXDMA_HIQ_MAP(x) \
+ (((x) & BIT_MASK_TXDMA_HIQ_MAP) << BIT_SHIFT_TXDMA_HIQ_MAP)
+#define BIT_GET_TXDMA_HIQ_MAP(x) \
+ (((x) >> BIT_SHIFT_TXDMA_HIQ_MAP) & BIT_MASK_TXDMA_HIQ_MAP)
+
+#define BIT_SHIFT_TXDMA_MGQ_MAP 12
+#define BIT_MASK_TXDMA_MGQ_MAP 0x3
+#define BIT_TXDMA_MGQ_MAP(x) \
+ (((x) & BIT_MASK_TXDMA_MGQ_MAP) << BIT_SHIFT_TXDMA_MGQ_MAP)
+#define BIT_GET_TXDMA_MGQ_MAP(x) \
+ (((x) >> BIT_SHIFT_TXDMA_MGQ_MAP) & BIT_MASK_TXDMA_MGQ_MAP)
+
+#define BIT_SHIFT_TXDMA_BKQ_MAP 10
+#define BIT_MASK_TXDMA_BKQ_MAP 0x3
+#define BIT_TXDMA_BKQ_MAP(x) \
+ (((x) & BIT_MASK_TXDMA_BKQ_MAP) << BIT_SHIFT_TXDMA_BKQ_MAP)
+#define BIT_GET_TXDMA_BKQ_MAP(x) \
+ (((x) >> BIT_SHIFT_TXDMA_BKQ_MAP) & BIT_MASK_TXDMA_BKQ_MAP)
+
+#define BIT_SHIFT_TXDMA_BEQ_MAP 8
+#define BIT_MASK_TXDMA_BEQ_MAP 0x3
+#define BIT_TXDMA_BEQ_MAP(x) \
+ (((x) & BIT_MASK_TXDMA_BEQ_MAP) << BIT_SHIFT_TXDMA_BEQ_MAP)
+#define BIT_GET_TXDMA_BEQ_MAP(x) \
+ (((x) >> BIT_SHIFT_TXDMA_BEQ_MAP) & BIT_MASK_TXDMA_BEQ_MAP)
+
+#define BIT_SHIFT_TXDMA_VIQ_MAP 6
+#define BIT_MASK_TXDMA_VIQ_MAP 0x3
+#define BIT_TXDMA_VIQ_MAP(x) \
+ (((x) & BIT_MASK_TXDMA_VIQ_MAP) << BIT_SHIFT_TXDMA_VIQ_MAP)
+#define BIT_GET_TXDMA_VIQ_MAP(x) \
+ (((x) >> BIT_SHIFT_TXDMA_VIQ_MAP) & BIT_MASK_TXDMA_VIQ_MAP)
+
+#define BIT_SHIFT_TXDMA_VOQ_MAP 4
+#define BIT_MASK_TXDMA_VOQ_MAP 0x3
+#define BIT_TXDMA_VOQ_MAP(x) \
+ (((x) & BIT_MASK_TXDMA_VOQ_MAP) << BIT_SHIFT_TXDMA_VOQ_MAP)
+#define BIT_GET_TXDMA_VOQ_MAP(x) \
+ (((x) >> BIT_SHIFT_TXDMA_VOQ_MAP) & BIT_MASK_TXDMA_VOQ_MAP)
+
+#define BIT_RXDMA_AGG_EN BIT(2)
+#define BIT_RXSHFT_EN BIT(1)
+#define BIT_RXDMA_ARBBW_EN BIT(0)
+
+/* 2 REG_TRXFF_BNDY (Offset 0x0114) */
+
+#define BIT_SHIFT_RXFFOVFL_RSV_V2 8
+#define BIT_MASK_RXFFOVFL_RSV_V2 0xf
+#define BIT_RXFFOVFL_RSV_V2(x) \
+ (((x) & BIT_MASK_RXFFOVFL_RSV_V2) << BIT_SHIFT_RXFFOVFL_RSV_V2)
+#define BIT_GET_RXFFOVFL_RSV_V2(x) \
+ (((x) >> BIT_SHIFT_RXFFOVFL_RSV_V2) & BIT_MASK_RXFFOVFL_RSV_V2)
+
+/* 2 REG_TRXFF_BNDY (Offset 0x0114) */
+
+#define BIT_SHIFT_TXPKTBUF_PGBNDY 0
+#define BIT_MASK_TXPKTBUF_PGBNDY 0xff
+#define BIT_TXPKTBUF_PGBNDY(x) \
+ (((x) & BIT_MASK_TXPKTBUF_PGBNDY) << BIT_SHIFT_TXPKTBUF_PGBNDY)
+#define BIT_GET_TXPKTBUF_PGBNDY(x) \
+ (((x) >> BIT_SHIFT_TXPKTBUF_PGBNDY) & BIT_MASK_TXPKTBUF_PGBNDY)
+
+/* 2 REG_TRXFF_BNDY (Offset 0x0114) */
+
+#define BIT_SHIFT_RXFF0_BNDY_V2 0
+#define BIT_MASK_RXFF0_BNDY_V2 0x3ffff
+#define BIT_RXFF0_BNDY_V2(x) \
+ (((x) & BIT_MASK_RXFF0_BNDY_V2) << BIT_SHIFT_RXFF0_BNDY_V2)
+#define BIT_GET_RXFF0_BNDY_V2(x) \
+ (((x) >> BIT_SHIFT_RXFF0_BNDY_V2) & BIT_MASK_RXFF0_BNDY_V2)
+
+#define BIT_SHIFT_RXFF0_RDPTR_V2 0
+#define BIT_MASK_RXFF0_RDPTR_V2 0x3ffff
+#define BIT_RXFF0_RDPTR_V2(x) \
+ (((x) & BIT_MASK_RXFF0_RDPTR_V2) << BIT_SHIFT_RXFF0_RDPTR_V2)
+#define BIT_GET_RXFF0_RDPTR_V2(x) \
+ (((x) >> BIT_SHIFT_RXFF0_RDPTR_V2) & BIT_MASK_RXFF0_RDPTR_V2)
+
+#define BIT_SHIFT_RXFF0_WTPTR_V2 0
+#define BIT_MASK_RXFF0_WTPTR_V2 0x3ffff
+#define BIT_RXFF0_WTPTR_V2(x) \
+ (((x) & BIT_MASK_RXFF0_WTPTR_V2) << BIT_SHIFT_RXFF0_WTPTR_V2)
+#define BIT_GET_RXFF0_WTPTR_V2(x) \
+ (((x) >> BIT_SHIFT_RXFF0_WTPTR_V2) & BIT_MASK_RXFF0_WTPTR_V2)
+
+/* 2 REG_PTA_I2C_MBOX (Offset 0x0118) */
+
+#define BIT_SHIFT_I2C_M_STATUS 8
+#define BIT_MASK_I2C_M_STATUS 0xf
+#define BIT_I2C_M_STATUS(x) \
+ (((x) & BIT_MASK_I2C_M_STATUS) << BIT_SHIFT_I2C_M_STATUS)
+#define BIT_GET_I2C_M_STATUS(x) \
+ (((x) >> BIT_SHIFT_I2C_M_STATUS) & BIT_MASK_I2C_M_STATUS)
+
+/* 2 REG_FE1IMR (Offset 0x0120) */
+
+#define BIT_FS_RXDMA2_DONE_INT_EN BIT(28)
+#define BIT_FS_RXDONE3_INT_EN BIT(27)
+#define BIT_FS_RXDONE2_INT_EN BIT(26)
+#define BIT_FS_RX_BCN_P4_INT_EN BIT(25)
+#define BIT_FS_RX_BCN_P3_INT_EN BIT(24)
+#define BIT_FS_RX_BCN_P2_INT_EN BIT(23)
+#define BIT_FS_RX_BCN_P1_INT_EN BIT(22)
+#define BIT_FS_RX_BCN_P0_INT_EN BIT(21)
+#define BIT_FS_RX_UMD0_INT_EN BIT(20)
+#define BIT_FS_RX_UMD1_INT_EN BIT(19)
+#define BIT_FS_RX_BMD0_INT_EN BIT(18)
+#define BIT_FS_RX_BMD1_INT_EN BIT(17)
+#define BIT_FS_RXDONE_INT_EN BIT(16)
+#define BIT_FS_WWLAN_INT_EN BIT(15)
+#define BIT_FS_SOUND_DONE_INT_EN BIT(14)
+#define BIT_FS_LP_STBY_INT_EN BIT(13)
+#define BIT_FS_TRL_MTR_INT_EN BIT(12)
+#define BIT_FS_BF1_PRETO_INT_EN BIT(11)
+#define BIT_FS_BF0_PRETO_INT_EN BIT(10)
+#define BIT_FS_PTCL_RELEASE_MACID_INT_EN BIT(9)
+
+/* 2 REG_FE1IMR (Offset 0x0120) */
+
+#define BIT_FS_LTE_COEX_EN BIT(6)
+
+/* 2 REG_FE1IMR (Offset 0x0120) */
+
+#define BIT_FS_WLACTOFF_INT_EN BIT(5)
+#define BIT_FS_WLACTON_INT_EN BIT(4)
+#define BIT_FS_BTCMD_INT_EN BIT(3)
+
+/* 2 REG_FE1IMR (Offset 0x0120) */
+
+#define BIT_FS_REG_MAILBOX_TO_I2C_INT_EN BIT(2)
+
+/* 2 REG_FE1IMR (Offset 0x0120) */
+
+#define BIT_FS_TRPC_TO_INT_EN_V1 BIT(1)
+
+/* 2 REG_FE1IMR (Offset 0x0120) */
+
+#define BIT_FS_RPC_O_T_INT_EN_V1 BIT(0)
+
+/* 2 REG_FE1ISR (Offset 0x0124) */
+
+#define BIT_FS_RXDMA2_DONE_INT BIT(28)
+#define BIT_FS_RXDONE3_INT BIT(27)
+#define BIT_FS_RXDONE2_INT BIT(26)
+#define BIT_FS_RX_BCN_P4_INT BIT(25)
+#define BIT_FS_RX_BCN_P3_INT BIT(24)
+#define BIT_FS_RX_BCN_P2_INT BIT(23)
+#define BIT_FS_RX_BCN_P1_INT BIT(22)
+#define BIT_FS_RX_BCN_P0_INT BIT(21)
+#define BIT_FS_RX_UMD0_INT BIT(20)
+#define BIT_FS_RX_UMD1_INT BIT(19)
+#define BIT_FS_RX_BMD0_INT BIT(18)
+#define BIT_FS_RX_BMD1_INT BIT(17)
+#define BIT_FS_RXDONE_INT BIT(16)
+#define BIT_FS_WWLAN_INT BIT(15)
+#define BIT_FS_SOUND_DONE_INT BIT(14)
+#define BIT_FS_LP_STBY_INT BIT(13)
+#define BIT_FS_TRL_MTR_INT BIT(12)
+#define BIT_FS_BF1_PRETO_INT BIT(11)
+#define BIT_FS_BF0_PRETO_INT BIT(10)
+#define BIT_FS_PTCL_RELEASE_MACID_INT BIT(9)
+
+/* 2 REG_FE1ISR (Offset 0x0124) */
+
+#define BIT_FS_LTE_COEX_INT BIT(6)
+
+/* 2 REG_FE1ISR (Offset 0x0124) */
+
+#define BIT_FS_WLACTOFF_INT BIT(5)
+#define BIT_FS_WLACTON_INT BIT(4)
+#define BIT_FS_BCN_RX_INT_INT BIT(3)
+
+/* 2 REG_FE1ISR (Offset 0x0124) */
+
+#define BIT_FS_MAILBOX_TO_I2C_INT BIT(2)
+
+/* 2 REG_FE1ISR (Offset 0x0124) */
+
+#define BIT_FS_TRPC_TO_INT BIT(1)
+
+/* 2 REG_FE1ISR (Offset 0x0124) */
+
+#define BIT_FS_RPC_O_T_INT BIT(0)
+
+/* 2 REG_CPWM (Offset 0x012C) */
+
+#define BIT_CPWM_TOGGLING BIT(31)
+
+#define BIT_SHIFT_CPWM_MOD 24
+#define BIT_MASK_CPWM_MOD 0x7f
+#define BIT_CPWM_MOD(x) (((x) & BIT_MASK_CPWM_MOD) << BIT_SHIFT_CPWM_MOD)
+#define BIT_GET_CPWM_MOD(x) (((x) >> BIT_SHIFT_CPWM_MOD) & BIT_MASK_CPWM_MOD)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_TXBCNOK_MB7_INT_EN BIT(31)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_TXBCNOK_MB6_INT_EN BIT(30)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_TXBCNOK_MB5_INT_EN BIT(29)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_TXBCNOK_MB4_INT_EN BIT(28)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_TXBCNOK_MB3_INT_EN BIT(27)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_TXBCNOK_MB2_INT_EN BIT(26)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_TXBCNOK_MB1_INT_EN BIT(25)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_TXBCNOK_MB0_INT_EN BIT(24)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_TXBCNERR_MB7_INT_EN BIT(23)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_TXBCNERR_MB6_INT_EN BIT(22)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_TXBCNERR_MB5_INT_EN BIT(21)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_TXBCNERR_MB4_INT_EN BIT(20)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_TXBCNERR_MB3_INT_EN BIT(19)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_TXBCNERR_MB2_INT_EN BIT(18)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_TXBCNERR_MB1_INT_EN BIT(17)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_TXBCNERR_MB0_INT_EN BIT(16)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_CPU_MGQ_TXDONE_INT_EN BIT(15)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_SIFS_OVERSPEC_INT_EN BIT(14)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_MGNTQ_RPTR_RELEASE_INT_EN BIT(13)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_MGNTQFF_TO_INT_EN BIT(12)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_DDMA1_LP_INT_EN BIT(11)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_DDMA1_HP_INT_EN BIT(10)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_DDMA0_LP_INT_EN BIT(9)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_DDMA0_HP_INT_EN BIT(8)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_TRXRPT_INT_EN BIT(7)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_C2H_W_READY_INT_EN BIT(6)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_HRCV_INT_EN BIT(5)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_H2CCMD_INT_EN BIT(4)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_TXPKTIN_INT_EN BIT(3)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_ERRORHDL_INT_EN BIT(2)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_TXCCX_INT_EN BIT(1)
+
+/* 2 REG_FWIMR (Offset 0x0130) */
+
+#define BIT_FS_TXCLOSE_INT_EN BIT(0)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_TXBCNOK_MB7_INT BIT(31)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_TXBCNOK_MB6_INT BIT(30)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_TXBCNOK_MB5_INT BIT(29)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_TXBCNOK_MB4_INT BIT(28)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_TXBCNOK_MB3_INT BIT(27)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_TXBCNOK_MB2_INT BIT(26)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_TXBCNOK_MB1_INT BIT(25)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_TXBCNOK_MB0_INT BIT(24)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_TXBCNERR_MB7_INT BIT(23)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_TXBCNERR_MB6_INT BIT(22)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_TXBCNERR_MB5_INT BIT(21)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_TXBCNERR_MB4_INT BIT(20)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_TXBCNERR_MB3_INT BIT(19)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_TXBCNERR_MB2_INT BIT(18)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_TXBCNERR_MB1_INT BIT(17)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_TXBCNERR_MB0_INT BIT(16)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_CPU_MGQ_TXDONE_INT BIT(15)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_SIFS_OVERSPEC_INT BIT(14)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_MGNTQ_RPTR_RELEASE_INT BIT(13)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_MGNTQFF_TO_INT BIT(12)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_DDMA1_LP_INT BIT(11)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_DDMA1_HP_INT BIT(10)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_DDMA0_LP_INT BIT(9)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_DDMA0_HP_INT BIT(8)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_TRXRPT_INT BIT(7)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_C2H_W_READY_INT BIT(6)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_HRCV_INT BIT(5)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_H2CCMD_INT BIT(4)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_TXPKTIN_INT BIT(3)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_ERRORHDL_INT BIT(2)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_TXCCX_INT BIT(1)
+
+/* 2 REG_FWISR (Offset 0x0134) */
+
+#define BIT_FS_TXCLOSE_INT BIT(0)
+
+/* 2 REG_FTIMR (Offset 0x0138) */
+
+#define BIT_PS_TIMER_C_EARLY_INT_EN BIT(23)
+
+/* 2 REG_FTIMR (Offset 0x0138) */
+
+#define BIT_PS_TIMER_B_EARLY_INT_EN BIT(22)
+
+/* 2 REG_FTIMR (Offset 0x0138) */
+
+#define BIT_PS_TIMER_A_EARLY_INT_EN BIT(21)
+
+/* 2 REG_FTIMR (Offset 0x0138) */
+
+#define BIT_CPUMGQ_TX_TIMER_EARLY_INT_EN BIT(20)
+
+/* 2 REG_FTIMR (Offset 0x0138) */
+
+#define BIT_PS_TIMER_C_INT_EN BIT(19)
+
+/* 2 REG_FTIMR (Offset 0x0138) */
+
+#define BIT_PS_TIMER_B_INT_EN BIT(18)
+
+/* 2 REG_FTIMR (Offset 0x0138) */
+
+#define BIT_PS_TIMER_A_INT_EN BIT(17)
+
+/* 2 REG_FTIMR (Offset 0x0138) */
+
+#define BIT_CPUMGQ_TX_TIMER_INT_EN BIT(16)
+
+/* 2 REG_FTIMR (Offset 0x0138) */
+
+#define BIT_FS_PS_TIMEOUT2_EN BIT(15)
+
+/* 2 REG_FTIMR (Offset 0x0138) */
+
+#define BIT_FS_PS_TIMEOUT1_EN BIT(14)
+
+/* 2 REG_FTIMR (Offset 0x0138) */
+
+#define BIT_FS_PS_TIMEOUT0_EN BIT(13)
+
+/* 2 REG_FTIMR (Offset 0x0138) */
+
+#define BIT_FS_GTINT8_EN BIT(8)
+
+/* 2 REG_FTIMR (Offset 0x0138) */
+
+#define BIT_FS_GTINT7_EN BIT(7)
+
+/* 2 REG_FTIMR (Offset 0x0138) */
+
+#define BIT_FS_GTINT6_EN BIT(6)
+
+/* 2 REG_FTIMR (Offset 0x0138) */
+
+#define BIT_FS_GTINT5_EN BIT(5)
+
+/* 2 REG_FTIMR (Offset 0x0138) */
+
+#define BIT_FS_GTINT4_EN BIT(4)
+
+/* 2 REG_FTIMR (Offset 0x0138) */
+
+#define BIT_FS_GTINT3_EN BIT(3)
+
+/* 2 REG_FTIMR (Offset 0x0138) */
+
+#define BIT_FS_GTINT2_EN BIT(2)
+
+/* 2 REG_FTIMR (Offset 0x0138) */
+
+#define BIT_FS_GTINT1_EN BIT(1)
+
+/* 2 REG_FTIMR (Offset 0x0138) */
+
+#define BIT_FS_GTINT0_EN BIT(0)
+
+/* 2 REG_FTISR (Offset 0x013C) */
+
+#define BIT_PS_TIMER_C_EARLY__INT BIT(23)
+
+/* 2 REG_FTISR (Offset 0x013C) */
+
+#define BIT_PS_TIMER_B_EARLY__INT BIT(22)
+
+/* 2 REG_FTISR (Offset 0x013C) */
+
+#define BIT_PS_TIMER_A_EARLY__INT BIT(21)
+
+/* 2 REG_FTISR (Offset 0x013C) */
+
+#define BIT_CPUMGQ_TX_TIMER_EARLY_INT BIT(20)
+
+/* 2 REG_FTISR (Offset 0x013C) */
+
+#define BIT_PS_TIMER_C_INT BIT(19)
+
+/* 2 REG_FTISR (Offset 0x013C) */
+
+#define BIT_PS_TIMER_B_INT BIT(18)
+
+/* 2 REG_FTISR (Offset 0x013C) */
+
+#define BIT_PS_TIMER_A_INT BIT(17)
+
+/* 2 REG_FTISR (Offset 0x013C) */
+
+#define BIT_CPUMGQ_TX_TIMER_INT BIT(16)
+
+/* 2 REG_FTISR (Offset 0x013C) */
+
+#define BIT_FS_PS_TIMEOUT2_INT BIT(15)
+
+/* 2 REG_FTISR (Offset 0x013C) */
+
+#define BIT_FS_PS_TIMEOUT1_INT BIT(14)
+
+/* 2 REG_FTISR (Offset 0x013C) */
+
+#define BIT_FS_PS_TIMEOUT0_INT BIT(13)
+
+/* 2 REG_FTISR (Offset 0x013C) */
+
+#define BIT_FS_GTINT8_INT BIT(8)
+
+/* 2 REG_FTISR (Offset 0x013C) */
+
+#define BIT_FS_GTINT7_INT BIT(7)
+
+/* 2 REG_FTISR (Offset 0x013C) */
+
+#define BIT_FS_GTINT6_INT BIT(6)
+
+/* 2 REG_FTISR (Offset 0x013C) */
+
+#define BIT_FS_GTINT5_INT BIT(5)
+
+/* 2 REG_FTISR (Offset 0x013C) */
+
+#define BIT_FS_GTINT4_INT BIT(4)
+
+/* 2 REG_FTISR (Offset 0x013C) */
+
+#define BIT_FS_GTINT3_INT BIT(3)
+
+/* 2 REG_FTISR (Offset 0x013C) */
+
+#define BIT_FS_GTINT2_INT BIT(2)
+
+/* 2 REG_FTISR (Offset 0x013C) */
+
+#define BIT_FS_GTINT1_INT BIT(1)
+
+/* 2 REG_FTISR (Offset 0x013C) */
+
+#define BIT_FS_GTINT0_INT BIT(0)
+
+/* 2 REG_PKTBUF_DBG_CTRL (Offset 0x0140) */
+
+#define BIT_SHIFT_PKTBUF_WRITE_EN 24
+#define BIT_MASK_PKTBUF_WRITE_EN 0xff
+#define BIT_PKTBUF_WRITE_EN(x) \
+ (((x) & BIT_MASK_PKTBUF_WRITE_EN) << BIT_SHIFT_PKTBUF_WRITE_EN)
+#define BIT_GET_PKTBUF_WRITE_EN(x) \
+ (((x) >> BIT_SHIFT_PKTBUF_WRITE_EN) & BIT_MASK_PKTBUF_WRITE_EN)
+
+/* 2 REG_PKTBUF_DBG_CTRL (Offset 0x0140) */
+
+#define BIT_TXRPTBUF_DBG BIT(23)
+
+/* 2 REG_PKTBUF_DBG_CTRL (Offset 0x0140) */
+
+#define BIT_TXPKTBUF_DBG_V2 BIT(20)
+
+/* 2 REG_PKTBUF_DBG_CTRL (Offset 0x0140) */
+
+#define BIT_RXPKTBUF_DBG BIT(16)
+
+/* 2 REG_PKTBUF_DBG_CTRL (Offset 0x0140) */
+
+#define BIT_SHIFT_PKTBUF_DBG_ADDR 0
+#define BIT_MASK_PKTBUF_DBG_ADDR 0x1fff
+#define BIT_PKTBUF_DBG_ADDR(x) \
+ (((x) & BIT_MASK_PKTBUF_DBG_ADDR) << BIT_SHIFT_PKTBUF_DBG_ADDR)
+#define BIT_GET_PKTBUF_DBG_ADDR(x) \
+ (((x) >> BIT_SHIFT_PKTBUF_DBG_ADDR) & BIT_MASK_PKTBUF_DBG_ADDR)
+
+/* 2 REG_PKTBUF_DBG_DATA_L (Offset 0x0144) */
+
+#define BIT_SHIFT_PKTBUF_DBG_DATA_L 0
+#define BIT_MASK_PKTBUF_DBG_DATA_L 0xffffffffL
+#define BIT_PKTBUF_DBG_DATA_L(x) \
+ (((x) & BIT_MASK_PKTBUF_DBG_DATA_L) << BIT_SHIFT_PKTBUF_DBG_DATA_L)
+#define BIT_GET_PKTBUF_DBG_DATA_L(x) \
+ (((x) >> BIT_SHIFT_PKTBUF_DBG_DATA_L) & BIT_MASK_PKTBUF_DBG_DATA_L)
+
+/* 2 REG_PKTBUF_DBG_DATA_H (Offset 0x0148) */
+
+#define BIT_SHIFT_PKTBUF_DBG_DATA_H 0
+#define BIT_MASK_PKTBUF_DBG_DATA_H 0xffffffffL
+#define BIT_PKTBUF_DBG_DATA_H(x) \
+ (((x) & BIT_MASK_PKTBUF_DBG_DATA_H) << BIT_SHIFT_PKTBUF_DBG_DATA_H)
+#define BIT_GET_PKTBUF_DBG_DATA_H(x) \
+ (((x) >> BIT_SHIFT_PKTBUF_DBG_DATA_H) & BIT_MASK_PKTBUF_DBG_DATA_H)
+
+/* 2 REG_CPWM2 (Offset 0x014C) */
+
+#define BIT_SHIFT_L0S_TO_RCVY_NUM 16
+#define BIT_MASK_L0S_TO_RCVY_NUM 0xff
+#define BIT_L0S_TO_RCVY_NUM(x) \
+ (((x) & BIT_MASK_L0S_TO_RCVY_NUM) << BIT_SHIFT_L0S_TO_RCVY_NUM)
+#define BIT_GET_L0S_TO_RCVY_NUM(x) \
+ (((x) >> BIT_SHIFT_L0S_TO_RCVY_NUM) & BIT_MASK_L0S_TO_RCVY_NUM)
+
+#define BIT_CPWM2_TOGGLING BIT(15)
+
+#define BIT_SHIFT_CPWM2_MOD 0
+#define BIT_MASK_CPWM2_MOD 0x7fff
+#define BIT_CPWM2_MOD(x) (((x) & BIT_MASK_CPWM2_MOD) << BIT_SHIFT_CPWM2_MOD)
+#define BIT_GET_CPWM2_MOD(x) (((x) >> BIT_SHIFT_CPWM2_MOD) & BIT_MASK_CPWM2_MOD)
+
+/* 2 REG_TC0_CTRL (Offset 0x0150) */
+
+#define BIT_TC0INT_EN BIT(26)
+#define BIT_TC0MODE BIT(25)
+#define BIT_TC0EN BIT(24)
+
+#define BIT_SHIFT_TC0DATA 0
+#define BIT_MASK_TC0DATA 0xffffff
+#define BIT_TC0DATA(x) (((x) & BIT_MASK_TC0DATA) << BIT_SHIFT_TC0DATA)
+#define BIT_GET_TC0DATA(x) (((x) >> BIT_SHIFT_TC0DATA) & BIT_MASK_TC0DATA)
+
+/* 2 REG_TC1_CTRL (Offset 0x0154) */
+
+#define BIT_TC1INT_EN BIT(26)
+#define BIT_TC1MODE BIT(25)
+#define BIT_TC1EN BIT(24)
+
+#define BIT_SHIFT_TC1DATA 0
+#define BIT_MASK_TC1DATA 0xffffff
+#define BIT_TC1DATA(x) (((x) & BIT_MASK_TC1DATA) << BIT_SHIFT_TC1DATA)
+#define BIT_GET_TC1DATA(x) (((x) >> BIT_SHIFT_TC1DATA) & BIT_MASK_TC1DATA)
+
+/* 2 REG_TC2_CTRL (Offset 0x0158) */
+
+#define BIT_TC2INT_EN BIT(26)
+#define BIT_TC2MODE BIT(25)
+#define BIT_TC2EN BIT(24)
+
+#define BIT_SHIFT_TC2DATA 0
+#define BIT_MASK_TC2DATA 0xffffff
+#define BIT_TC2DATA(x) (((x) & BIT_MASK_TC2DATA) << BIT_SHIFT_TC2DATA)
+#define BIT_GET_TC2DATA(x) (((x) >> BIT_SHIFT_TC2DATA) & BIT_MASK_TC2DATA)
+
+/* 2 REG_TC3_CTRL (Offset 0x015C) */
+
+#define BIT_TC3INT_EN BIT(26)
+#define BIT_TC3MODE BIT(25)
+#define BIT_TC3EN BIT(24)
+
+#define BIT_SHIFT_TC3DATA 0
+#define BIT_MASK_TC3DATA 0xffffff
+#define BIT_TC3DATA(x) (((x) & BIT_MASK_TC3DATA) << BIT_SHIFT_TC3DATA)
+#define BIT_GET_TC3DATA(x) (((x) >> BIT_SHIFT_TC3DATA) & BIT_MASK_TC3DATA)
+
+/* 2 REG_TC4_CTRL (Offset 0x0160) */
+
+#define BIT_TC4INT_EN BIT(26)
+#define BIT_TC4MODE BIT(25)
+#define BIT_TC4EN BIT(24)
+
+#define BIT_SHIFT_TC4DATA 0
+#define BIT_MASK_TC4DATA 0xffffff
+#define BIT_TC4DATA(x) (((x) & BIT_MASK_TC4DATA) << BIT_SHIFT_TC4DATA)
+#define BIT_GET_TC4DATA(x) (((x) >> BIT_SHIFT_TC4DATA) & BIT_MASK_TC4DATA)
+
+/* 2 REG_TCUNIT_BASE (Offset 0x0164) */
+
+#define BIT_SHIFT_TCUNIT_BASE 0
+#define BIT_MASK_TCUNIT_BASE 0x3fff
+#define BIT_TCUNIT_BASE(x) \
+ (((x) & BIT_MASK_TCUNIT_BASE) << BIT_SHIFT_TCUNIT_BASE)
+#define BIT_GET_TCUNIT_BASE(x) \
+ (((x) >> BIT_SHIFT_TCUNIT_BASE) & BIT_MASK_TCUNIT_BASE)
+
+/* 2 REG_TC5_CTRL (Offset 0x0168) */
+
+#define BIT_TC5INT_EN BIT(26)
+
+/* 2 REG_TC5_CTRL (Offset 0x0168) */
+
+#define BIT_TC5MODE BIT(25)
+#define BIT_TC5EN BIT(24)
+
+#define BIT_SHIFT_TC5DATA 0
+#define BIT_MASK_TC5DATA 0xffffff
+#define BIT_TC5DATA(x) (((x) & BIT_MASK_TC5DATA) << BIT_SHIFT_TC5DATA)
+#define BIT_GET_TC5DATA(x) (((x) >> BIT_SHIFT_TC5DATA) & BIT_MASK_TC5DATA)
+
+/* 2 REG_TC6_CTRL (Offset 0x016C) */
+
+#define BIT_TC6INT_EN BIT(26)
+
+/* 2 REG_TC6_CTRL (Offset 0x016C) */
+
+#define BIT_TC6MODE BIT(25)
+#define BIT_TC6EN BIT(24)
+
+#define BIT_SHIFT_TC6DATA 0
+#define BIT_MASK_TC6DATA 0xffffff
+#define BIT_TC6DATA(x) (((x) & BIT_MASK_TC6DATA) << BIT_SHIFT_TC6DATA)
+#define BIT_GET_TC6DATA(x) (((x) >> BIT_SHIFT_TC6DATA) & BIT_MASK_TC6DATA)
+
+/* 2 REG_MBIST_FAIL (Offset 0x0170) */
+
+#define BIT_SHIFT_8051_MBIST_FAIL 26
+#define BIT_MASK_8051_MBIST_FAIL 0x7
+#define BIT_8051_MBIST_FAIL(x) \
+ (((x) & BIT_MASK_8051_MBIST_FAIL) << BIT_SHIFT_8051_MBIST_FAIL)
+#define BIT_GET_8051_MBIST_FAIL(x) \
+ (((x) >> BIT_SHIFT_8051_MBIST_FAIL) & BIT_MASK_8051_MBIST_FAIL)
+
+#define BIT_SHIFT_USB_MBIST_FAIL 24
+#define BIT_MASK_USB_MBIST_FAIL 0x3
+#define BIT_USB_MBIST_FAIL(x) \
+ (((x) & BIT_MASK_USB_MBIST_FAIL) << BIT_SHIFT_USB_MBIST_FAIL)
+#define BIT_GET_USB_MBIST_FAIL(x) \
+ (((x) >> BIT_SHIFT_USB_MBIST_FAIL) & BIT_MASK_USB_MBIST_FAIL)
+
+#define BIT_SHIFT_PCIE_MBIST_FAIL 16
+#define BIT_MASK_PCIE_MBIST_FAIL 0x3f
+#define BIT_PCIE_MBIST_FAIL(x) \
+ (((x) & BIT_MASK_PCIE_MBIST_FAIL) << BIT_SHIFT_PCIE_MBIST_FAIL)
+#define BIT_GET_PCIE_MBIST_FAIL(x) \
+ (((x) >> BIT_SHIFT_PCIE_MBIST_FAIL) & BIT_MASK_PCIE_MBIST_FAIL)
+
+/* 2 REG_MBIST_FAIL (Offset 0x0170) */
+
+#define BIT_SHIFT_MAC_MBIST_FAIL 0
+#define BIT_MASK_MAC_MBIST_FAIL 0xfff
+#define BIT_MAC_MBIST_FAIL(x) \
+ (((x) & BIT_MASK_MAC_MBIST_FAIL) << BIT_SHIFT_MAC_MBIST_FAIL)
+#define BIT_GET_MAC_MBIST_FAIL(x) \
+ (((x) >> BIT_SHIFT_MAC_MBIST_FAIL) & BIT_MASK_MAC_MBIST_FAIL)
+
+/* 2 REG_MBIST_START_PAUSE (Offset 0x0174) */
+
+#define BIT_SHIFT_8051_MBIST_START_PAUSE 26
+#define BIT_MASK_8051_MBIST_START_PAUSE 0x7
+#define BIT_8051_MBIST_START_PAUSE(x) \
+ (((x) & BIT_MASK_8051_MBIST_START_PAUSE) \
+ << BIT_SHIFT_8051_MBIST_START_PAUSE)
+#define BIT_GET_8051_MBIST_START_PAUSE(x) \
+ (((x) >> BIT_SHIFT_8051_MBIST_START_PAUSE) & \
+ BIT_MASK_8051_MBIST_START_PAUSE)
+
+#define BIT_SHIFT_USB_MBIST_START_PAUSE 24
+#define BIT_MASK_USB_MBIST_START_PAUSE 0x3
+#define BIT_USB_MBIST_START_PAUSE(x) \
+ (((x) & BIT_MASK_USB_MBIST_START_PAUSE) \
+ << BIT_SHIFT_USB_MBIST_START_PAUSE)
+#define BIT_GET_USB_MBIST_START_PAUSE(x) \
+ (((x) >> BIT_SHIFT_USB_MBIST_START_PAUSE) & \
+ BIT_MASK_USB_MBIST_START_PAUSE)
+
+#define BIT_SHIFT_PCIE_MBIST_START_PAUSE 16
+#define BIT_MASK_PCIE_MBIST_START_PAUSE 0x3f
+#define BIT_PCIE_MBIST_START_PAUSE(x) \
+ (((x) & BIT_MASK_PCIE_MBIST_START_PAUSE) \
+ << BIT_SHIFT_PCIE_MBIST_START_PAUSE)
+#define BIT_GET_PCIE_MBIST_START_PAUSE(x) \
+ (((x) >> BIT_SHIFT_PCIE_MBIST_START_PAUSE) & \
+ BIT_MASK_PCIE_MBIST_START_PAUSE)
+
+/* 2 REG_MBIST_START_PAUSE (Offset 0x0174) */
+
+#define BIT_SHIFT_MAC_MBIST_START_PAUSE 0
+#define BIT_MASK_MAC_MBIST_START_PAUSE 0xfff
+#define BIT_MAC_MBIST_START_PAUSE(x) \
+ (((x) & BIT_MASK_MAC_MBIST_START_PAUSE) \
+ << BIT_SHIFT_MAC_MBIST_START_PAUSE)
+#define BIT_GET_MAC_MBIST_START_PAUSE(x) \
+ (((x) >> BIT_SHIFT_MAC_MBIST_START_PAUSE) & \
+ BIT_MASK_MAC_MBIST_START_PAUSE)
+
+/* 2 REG_MBIST_DONE (Offset 0x0178) */
+
+#define BIT_SHIFT_8051_MBIST_DONE 26
+#define BIT_MASK_8051_MBIST_DONE 0x7
+#define BIT_8051_MBIST_DONE(x) \
+ (((x) & BIT_MASK_8051_MBIST_DONE) << BIT_SHIFT_8051_MBIST_DONE)
+#define BIT_GET_8051_MBIST_DONE(x) \
+ (((x) >> BIT_SHIFT_8051_MBIST_DONE) & BIT_MASK_8051_MBIST_DONE)
+
+#define BIT_SHIFT_USB_MBIST_DONE 24
+#define BIT_MASK_USB_MBIST_DONE 0x3
+#define BIT_USB_MBIST_DONE(x) \
+ (((x) & BIT_MASK_USB_MBIST_DONE) << BIT_SHIFT_USB_MBIST_DONE)
+#define BIT_GET_USB_MBIST_DONE(x) \
+ (((x) >> BIT_SHIFT_USB_MBIST_DONE) & BIT_MASK_USB_MBIST_DONE)
+
+#define BIT_SHIFT_PCIE_MBIST_DONE 16
+#define BIT_MASK_PCIE_MBIST_DONE 0x3f
+#define BIT_PCIE_MBIST_DONE(x) \
+ (((x) & BIT_MASK_PCIE_MBIST_DONE) << BIT_SHIFT_PCIE_MBIST_DONE)
+#define BIT_GET_PCIE_MBIST_DONE(x) \
+ (((x) >> BIT_SHIFT_PCIE_MBIST_DONE) & BIT_MASK_PCIE_MBIST_DONE)
+
+/* 2 REG_MBIST_DONE (Offset 0x0178) */
+
+#define BIT_SHIFT_MAC_MBIST_DONE 0
+#define BIT_MASK_MAC_MBIST_DONE 0xfff
+#define BIT_MAC_MBIST_DONE(x) \
+ (((x) & BIT_MASK_MAC_MBIST_DONE) << BIT_SHIFT_MAC_MBIST_DONE)
+#define BIT_GET_MAC_MBIST_DONE(x) \
+ (((x) >> BIT_SHIFT_MAC_MBIST_DONE) & BIT_MASK_MAC_MBIST_DONE)
+
+/* 2 REG_MBIST_FAIL_NRML (Offset 0x017C) */
+
+#define BIT_SHIFT_MBIST_FAIL_NRML 0
+#define BIT_MASK_MBIST_FAIL_NRML 0xffffffffL
+#define BIT_MBIST_FAIL_NRML(x) \
+ (((x) & BIT_MASK_MBIST_FAIL_NRML) << BIT_SHIFT_MBIST_FAIL_NRML)
+#define BIT_GET_MBIST_FAIL_NRML(x) \
+ (((x) >> BIT_SHIFT_MBIST_FAIL_NRML) & BIT_MASK_MBIST_FAIL_NRML)
+
+/* 2 REG_AES_DECRPT_DATA (Offset 0x0180) */
+
+#define BIT_SHIFT_IPS_CFG_ADDR 0
+#define BIT_MASK_IPS_CFG_ADDR 0xff
+#define BIT_IPS_CFG_ADDR(x) \
+ (((x) & BIT_MASK_IPS_CFG_ADDR) << BIT_SHIFT_IPS_CFG_ADDR)
+#define BIT_GET_IPS_CFG_ADDR(x) \
+ (((x) >> BIT_SHIFT_IPS_CFG_ADDR) & BIT_MASK_IPS_CFG_ADDR)
+
+/* 2 REG_AES_DECRPT_CFG (Offset 0x0184) */
+
+#define BIT_SHIFT_IPS_CFG_DATA 0
+#define BIT_MASK_IPS_CFG_DATA 0xffffffffL
+#define BIT_IPS_CFG_DATA(x) \
+ (((x) & BIT_MASK_IPS_CFG_DATA) << BIT_SHIFT_IPS_CFG_DATA)
+#define BIT_GET_IPS_CFG_DATA(x) \
+ (((x) >> BIT_SHIFT_IPS_CFG_DATA) & BIT_MASK_IPS_CFG_DATA)
+
+/* 2 REG_TMETER (Offset 0x0190) */
+
+#define BIT_TEMP_VALID BIT(31)
+
+#define BIT_SHIFT_TEMP_VALUE 24
+#define BIT_MASK_TEMP_VALUE 0x3f
+#define BIT_TEMP_VALUE(x) (((x) & BIT_MASK_TEMP_VALUE) << BIT_SHIFT_TEMP_VALUE)
+#define BIT_GET_TEMP_VALUE(x) \
+ (((x) >> BIT_SHIFT_TEMP_VALUE) & BIT_MASK_TEMP_VALUE)
+
+#define BIT_SHIFT_REG_TMETER_TIMER 8
+#define BIT_MASK_REG_TMETER_TIMER 0xfff
+#define BIT_REG_TMETER_TIMER(x) \
+ (((x) & BIT_MASK_REG_TMETER_TIMER) << BIT_SHIFT_REG_TMETER_TIMER)
+#define BIT_GET_REG_TMETER_TIMER(x) \
+ (((x) >> BIT_SHIFT_REG_TMETER_TIMER) & BIT_MASK_REG_TMETER_TIMER)
+
+#define BIT_SHIFT_REG_TEMP_DELTA 2
+#define BIT_MASK_REG_TEMP_DELTA 0x3f
+#define BIT_REG_TEMP_DELTA(x) \
+ (((x) & BIT_MASK_REG_TEMP_DELTA) << BIT_SHIFT_REG_TEMP_DELTA)
+#define BIT_GET_REG_TEMP_DELTA(x) \
+ (((x) >> BIT_SHIFT_REG_TEMP_DELTA) & BIT_MASK_REG_TEMP_DELTA)
+
+#define BIT_REG_TMETER_EN BIT(0)
+
+/* 2 REG_OSC_32K_CTRL (Offset 0x0194) */
+
+#define BIT_SHIFT_OSC_32K_CLKGEN_0 16
+#define BIT_MASK_OSC_32K_CLKGEN_0 0xffff
+#define BIT_OSC_32K_CLKGEN_0(x) \
+ (((x) & BIT_MASK_OSC_32K_CLKGEN_0) << BIT_SHIFT_OSC_32K_CLKGEN_0)
+#define BIT_GET_OSC_32K_CLKGEN_0(x) \
+ (((x) >> BIT_SHIFT_OSC_32K_CLKGEN_0) & BIT_MASK_OSC_32K_CLKGEN_0)
+
+/* 2 REG_OSC_32K_CTRL (Offset 0x0194) */
+
+#define BIT_SHIFT_OSC_32K_RES_COMP 4
+#define BIT_MASK_OSC_32K_RES_COMP 0x3
+#define BIT_OSC_32K_RES_COMP(x) \
+ (((x) & BIT_MASK_OSC_32K_RES_COMP) << BIT_SHIFT_OSC_32K_RES_COMP)
+#define BIT_GET_OSC_32K_RES_COMP(x) \
+ (((x) >> BIT_SHIFT_OSC_32K_RES_COMP) & BIT_MASK_OSC_32K_RES_COMP)
+
+#define BIT_OSC_32K_OUT_SEL BIT(3)
+
+/* 2 REG_OSC_32K_CTRL (Offset 0x0194) */
+
+#define BIT_ISO_WL_2_OSC_32K BIT(1)
+
+/* 2 REG_OSC_32K_CTRL (Offset 0x0194) */
+
+#define BIT_POW_CKGEN BIT(0)
+
+/* 2 REG_32K_CAL_REG1 (Offset 0x0198) */
+
+#define BIT_CAL_32K_REG_WR BIT(31)
+#define BIT_CAL_32K_DBG_SEL BIT(22)
+
+#define BIT_SHIFT_CAL_32K_REG_ADDR 16
+#define BIT_MASK_CAL_32K_REG_ADDR 0x3f
+#define BIT_CAL_32K_REG_ADDR(x) \
+ (((x) & BIT_MASK_CAL_32K_REG_ADDR) << BIT_SHIFT_CAL_32K_REG_ADDR)
+#define BIT_GET_CAL_32K_REG_ADDR(x) \
+ (((x) >> BIT_SHIFT_CAL_32K_REG_ADDR) & BIT_MASK_CAL_32K_REG_ADDR)
+
+/* 2 REG_32K_CAL_REG1 (Offset 0x0198) */
+
+#define BIT_SHIFT_CAL_32K_REG_DATA 0
+#define BIT_MASK_CAL_32K_REG_DATA 0xffff
+#define BIT_CAL_32K_REG_DATA(x) \
+ (((x) & BIT_MASK_CAL_32K_REG_DATA) << BIT_SHIFT_CAL_32K_REG_DATA)
+#define BIT_GET_CAL_32K_REG_DATA(x) \
+ (((x) >> BIT_SHIFT_CAL_32K_REG_DATA) & BIT_MASK_CAL_32K_REG_DATA)
+
+/* 2 REG_C2HEVT (Offset 0x01A0) */
+
+#define BIT_SHIFT_C2HEVT_MSG 0
+#define BIT_MASK_C2HEVT_MSG 0xffffffffffffffffffffffffffffffffL
+#define BIT_C2HEVT_MSG(x) (((x) & BIT_MASK_C2HEVT_MSG) << BIT_SHIFT_C2HEVT_MSG)
+#define BIT_GET_C2HEVT_MSG(x) \
+ (((x) >> BIT_SHIFT_C2HEVT_MSG) & BIT_MASK_C2HEVT_MSG)
+
+/* 2 REG_SW_DEFINED_PAGE1 (Offset 0x01B8) */
+
+#define BIT_SHIFT_SW_DEFINED_PAGE1 0
+#define BIT_MASK_SW_DEFINED_PAGE1 0xffffffffffffffffL
+#define BIT_SW_DEFINED_PAGE1(x) \
+ (((x) & BIT_MASK_SW_DEFINED_PAGE1) << BIT_SHIFT_SW_DEFINED_PAGE1)
+#define BIT_GET_SW_DEFINED_PAGE1(x) \
+ (((x) >> BIT_SHIFT_SW_DEFINED_PAGE1) & BIT_MASK_SW_DEFINED_PAGE1)
+
+/* 2 REG_MCUTST_I (Offset 0x01C0) */
+
+#define BIT_SHIFT_MCUDMSG_I 0
+#define BIT_MASK_MCUDMSG_I 0xffffffffL
+#define BIT_MCUDMSG_I(x) (((x) & BIT_MASK_MCUDMSG_I) << BIT_SHIFT_MCUDMSG_I)
+#define BIT_GET_MCUDMSG_I(x) (((x) >> BIT_SHIFT_MCUDMSG_I) & BIT_MASK_MCUDMSG_I)
+
+/* 2 REG_MCUTST_II (Offset 0x01C4) */
+
+#define BIT_SHIFT_MCUDMSG_II 0
+#define BIT_MASK_MCUDMSG_II 0xffffffffL
+#define BIT_MCUDMSG_II(x) (((x) & BIT_MASK_MCUDMSG_II) << BIT_SHIFT_MCUDMSG_II)
+#define BIT_GET_MCUDMSG_II(x) \
+ (((x) >> BIT_SHIFT_MCUDMSG_II) & BIT_MASK_MCUDMSG_II)
+
+/* 2 REG_FMETHR (Offset 0x01C8) */
+
+#define BIT_FMSG_INT BIT(31)
+
+#define BIT_SHIFT_FW_MSG 0
+#define BIT_MASK_FW_MSG 0xffffffffL
+#define BIT_FW_MSG(x) (((x) & BIT_MASK_FW_MSG) << BIT_SHIFT_FW_MSG)
+#define BIT_GET_FW_MSG(x) (((x) >> BIT_SHIFT_FW_MSG) & BIT_MASK_FW_MSG)
+
+/* 2 REG_HMETFR (Offset 0x01CC) */
+
+#define BIT_SHIFT_HRCV_MSG 24
+#define BIT_MASK_HRCV_MSG 0xff
+#define BIT_HRCV_MSG(x) (((x) & BIT_MASK_HRCV_MSG) << BIT_SHIFT_HRCV_MSG)
+#define BIT_GET_HRCV_MSG(x) (((x) >> BIT_SHIFT_HRCV_MSG) & BIT_MASK_HRCV_MSG)
+
+#define BIT_INT_BOX3 BIT(3)
+#define BIT_INT_BOX2 BIT(2)
+#define BIT_INT_BOX1 BIT(1)
+#define BIT_INT_BOX0 BIT(0)
+
+/* 2 REG_HMEBOX0 (Offset 0x01D0) */
+
+#define BIT_SHIFT_HOST_MSG_0 0
+#define BIT_MASK_HOST_MSG_0 0xffffffffL
+#define BIT_HOST_MSG_0(x) (((x) & BIT_MASK_HOST_MSG_0) << BIT_SHIFT_HOST_MSG_0)
+#define BIT_GET_HOST_MSG_0(x) \
+ (((x) >> BIT_SHIFT_HOST_MSG_0) & BIT_MASK_HOST_MSG_0)
+
+/* 2 REG_HMEBOX1 (Offset 0x01D4) */
+
+#define BIT_SHIFT_HOST_MSG_1 0
+#define BIT_MASK_HOST_MSG_1 0xffffffffL
+#define BIT_HOST_MSG_1(x) (((x) & BIT_MASK_HOST_MSG_1) << BIT_SHIFT_HOST_MSG_1)
+#define BIT_GET_HOST_MSG_1(x) \
+ (((x) >> BIT_SHIFT_HOST_MSG_1) & BIT_MASK_HOST_MSG_1)
+
+/* 2 REG_HMEBOX2 (Offset 0x01D8) */
+
+#define BIT_SHIFT_HOST_MSG_2 0
+#define BIT_MASK_HOST_MSG_2 0xffffffffL
+#define BIT_HOST_MSG_2(x) (((x) & BIT_MASK_HOST_MSG_2) << BIT_SHIFT_HOST_MSG_2)
+#define BIT_GET_HOST_MSG_2(x) \
+ (((x) >> BIT_SHIFT_HOST_MSG_2) & BIT_MASK_HOST_MSG_2)
+
+/* 2 REG_HMEBOX3 (Offset 0x01DC) */
+
+#define BIT_SHIFT_HOST_MSG_3 0
+#define BIT_MASK_HOST_MSG_3 0xffffffffL
+#define BIT_HOST_MSG_3(x) (((x) & BIT_MASK_HOST_MSG_3) << BIT_SHIFT_HOST_MSG_3)
+#define BIT_GET_HOST_MSG_3(x) \
+ (((x) >> BIT_SHIFT_HOST_MSG_3) & BIT_MASK_HOST_MSG_3)
+
+/* 2 REG_LLT_INIT (Offset 0x01E0) */
+
+#define BIT_SHIFT_LLTE_RWM 30
+#define BIT_MASK_LLTE_RWM 0x3
+#define BIT_LLTE_RWM(x) (((x) & BIT_MASK_LLTE_RWM) << BIT_SHIFT_LLTE_RWM)
+#define BIT_GET_LLTE_RWM(x) (((x) >> BIT_SHIFT_LLTE_RWM) & BIT_MASK_LLTE_RWM)
+
+/* 2 REG_LLT_INIT (Offset 0x01E0) */
+
+#define BIT_SHIFT_LLTINI_PDATA_V1 16
+#define BIT_MASK_LLTINI_PDATA_V1 0xfff
+#define BIT_LLTINI_PDATA_V1(x) \
+ (((x) & BIT_MASK_LLTINI_PDATA_V1) << BIT_SHIFT_LLTINI_PDATA_V1)
+#define BIT_GET_LLTINI_PDATA_V1(x) \
+ (((x) >> BIT_SHIFT_LLTINI_PDATA_V1) & BIT_MASK_LLTINI_PDATA_V1)
+
+/* 2 REG_LLT_INIT (Offset 0x01E0) */
+
+#define BIT_SHIFT_LLTINI_HDATA_V1 0
+#define BIT_MASK_LLTINI_HDATA_V1 0xfff
+#define BIT_LLTINI_HDATA_V1(x) \
+ (((x) & BIT_MASK_LLTINI_HDATA_V1) << BIT_SHIFT_LLTINI_HDATA_V1)
+#define BIT_GET_LLTINI_HDATA_V1(x) \
+ (((x) >> BIT_SHIFT_LLTINI_HDATA_V1) & BIT_MASK_LLTINI_HDATA_V1)
+
+/* 2 REG_LLT_INIT_ADDR (Offset 0x01E4) */
+
+#define BIT_SHIFT_LLTINI_ADDR_V1 0
+#define BIT_MASK_LLTINI_ADDR_V1 0xfff
+#define BIT_LLTINI_ADDR_V1(x) \
+ (((x) & BIT_MASK_LLTINI_ADDR_V1) << BIT_SHIFT_LLTINI_ADDR_V1)
+#define BIT_GET_LLTINI_ADDR_V1(x) \
+ (((x) >> BIT_SHIFT_LLTINI_ADDR_V1) & BIT_MASK_LLTINI_ADDR_V1)
+
+/* 2 REG_BB_ACCESS_CTRL (Offset 0x01E8) */
+
+#define BIT_SHIFT_BB_WRITE_READ 30
+#define BIT_MASK_BB_WRITE_READ 0x3
+#define BIT_BB_WRITE_READ(x) \
+ (((x) & BIT_MASK_BB_WRITE_READ) << BIT_SHIFT_BB_WRITE_READ)
+#define BIT_GET_BB_WRITE_READ(x) \
+ (((x) >> BIT_SHIFT_BB_WRITE_READ) & BIT_MASK_BB_WRITE_READ)
+
+/* 2 REG_BB_ACCESS_CTRL (Offset 0x01E8) */
+
+#define BIT_SHIFT_BB_WRITE_EN 12
+#define BIT_MASK_BB_WRITE_EN 0xf
+#define BIT_BB_WRITE_EN(x) \
+ (((x) & BIT_MASK_BB_WRITE_EN) << BIT_SHIFT_BB_WRITE_EN)
+#define BIT_GET_BB_WRITE_EN(x) \
+ (((x) >> BIT_SHIFT_BB_WRITE_EN) & BIT_MASK_BB_WRITE_EN)
+
+#define BIT_SHIFT_BB_ADDR 2
+#define BIT_MASK_BB_ADDR 0x1ff
+#define BIT_BB_ADDR(x) (((x) & BIT_MASK_BB_ADDR) << BIT_SHIFT_BB_ADDR)
+#define BIT_GET_BB_ADDR(x) (((x) >> BIT_SHIFT_BB_ADDR) & BIT_MASK_BB_ADDR)
+
+/* 2 REG_BB_ACCESS_CTRL (Offset 0x01E8) */
+
+#define BIT_BB_ERRACC BIT(0)
+
+/* 2 REG_BB_ACCESS_DATA (Offset 0x01EC) */
+
+#define BIT_SHIFT_BB_DATA 0
+#define BIT_MASK_BB_DATA 0xffffffffL
+#define BIT_BB_DATA(x) (((x) & BIT_MASK_BB_DATA) << BIT_SHIFT_BB_DATA)
+#define BIT_GET_BB_DATA(x) (((x) >> BIT_SHIFT_BB_DATA) & BIT_MASK_BB_DATA)
+
+/* 2 REG_HMEBOX_E0 (Offset 0x01F0) */
+
+#define BIT_SHIFT_HMEBOX_E0 0
+#define BIT_MASK_HMEBOX_E0 0xffffffffL
+#define BIT_HMEBOX_E0(x) (((x) & BIT_MASK_HMEBOX_E0) << BIT_SHIFT_HMEBOX_E0)
+#define BIT_GET_HMEBOX_E0(x) (((x) >> BIT_SHIFT_HMEBOX_E0) & BIT_MASK_HMEBOX_E0)
+
+/* 2 REG_HMEBOX_E1 (Offset 0x01F4) */
+
+#define BIT_SHIFT_HMEBOX_E1 0
+#define BIT_MASK_HMEBOX_E1 0xffffffffL
+#define BIT_HMEBOX_E1(x) (((x) & BIT_MASK_HMEBOX_E1) << BIT_SHIFT_HMEBOX_E1)
+#define BIT_GET_HMEBOX_E1(x) (((x) >> BIT_SHIFT_HMEBOX_E1) & BIT_MASK_HMEBOX_E1)
+
+/* 2 REG_HMEBOX_E2 (Offset 0x01F8) */
+
+#define BIT_SHIFT_HMEBOX_E2 0
+#define BIT_MASK_HMEBOX_E2 0xffffffffL
+#define BIT_HMEBOX_E2(x) (((x) & BIT_MASK_HMEBOX_E2) << BIT_SHIFT_HMEBOX_E2)
+#define BIT_GET_HMEBOX_E2(x) (((x) >> BIT_SHIFT_HMEBOX_E2) & BIT_MASK_HMEBOX_E2)
+
+/* 2 REG_HMEBOX_E3 (Offset 0x01FC) */
+
+#define BIT_LD_RQPN BIT(31)
+
+#define BIT_SHIFT_HMEBOX_E3 0
+#define BIT_MASK_HMEBOX_E3 0xffffffffL
+#define BIT_HMEBOX_E3(x) (((x) & BIT_MASK_HMEBOX_E3) << BIT_SHIFT_HMEBOX_E3)
+#define BIT_GET_HMEBOX_E3(x) (((x) >> BIT_SHIFT_HMEBOX_E3) & BIT_MASK_HMEBOX_E3)
+
+/* 2 REG_FIFOPAGE_CTRL_1 (Offset 0x0200) */
+
+#define BIT_SHIFT_TX_OQT_HE_FREE_SPACE_V1 16
+#define BIT_MASK_TX_OQT_HE_FREE_SPACE_V1 0xff
+#define BIT_TX_OQT_HE_FREE_SPACE_V1(x) \
+ (((x) & BIT_MASK_TX_OQT_HE_FREE_SPACE_V1) \
+ << BIT_SHIFT_TX_OQT_HE_FREE_SPACE_V1)
+#define BIT_GET_TX_OQT_HE_FREE_SPACE_V1(x) \
+ (((x) >> BIT_SHIFT_TX_OQT_HE_FREE_SPACE_V1) & \
+ BIT_MASK_TX_OQT_HE_FREE_SPACE_V1)
+
+/* 2 REG_FIFOPAGE_CTRL_1 (Offset 0x0200) */
+
+#define BIT_SHIFT_TX_OQT_NL_FREE_SPACE_V1 0
+#define BIT_MASK_TX_OQT_NL_FREE_SPACE_V1 0xff
+#define BIT_TX_OQT_NL_FREE_SPACE_V1(x) \
+ (((x) & BIT_MASK_TX_OQT_NL_FREE_SPACE_V1) \
+ << BIT_SHIFT_TX_OQT_NL_FREE_SPACE_V1)
+#define BIT_GET_TX_OQT_NL_FREE_SPACE_V1(x) \
+ (((x) >> BIT_SHIFT_TX_OQT_NL_FREE_SPACE_V1) & \
+ BIT_MASK_TX_OQT_NL_FREE_SPACE_V1)
+
+/* 2 REG_FIFOPAGE_CTRL_2 (Offset 0x0204) */
+
+#define BIT_BCN_VALID_1_V1 BIT(31)
+
+/* 2 REG_FIFOPAGE_CTRL_2 (Offset 0x0204) */
+
+#define BIT_SHIFT_BCN_HEAD_1_V1 16
+#define BIT_MASK_BCN_HEAD_1_V1 0xfff
+#define BIT_BCN_HEAD_1_V1(x) \
+ (((x) & BIT_MASK_BCN_HEAD_1_V1) << BIT_SHIFT_BCN_HEAD_1_V1)
+#define BIT_GET_BCN_HEAD_1_V1(x) \
+ (((x) >> BIT_SHIFT_BCN_HEAD_1_V1) & BIT_MASK_BCN_HEAD_1_V1)
+
+#define BIT_BCN_VALID_V1 BIT(15)
+
+/* 2 REG_FIFOPAGE_CTRL_2 (Offset 0x0204) */
+
+#define BIT_SHIFT_BCN_HEAD_V1 0
+#define BIT_MASK_BCN_HEAD_V1 0xfff
+#define BIT_BCN_HEAD_V1(x) \
+ (((x) & BIT_MASK_BCN_HEAD_V1) << BIT_SHIFT_BCN_HEAD_V1)
+#define BIT_GET_BCN_HEAD_V1(x) \
+ (((x) >> BIT_SHIFT_BCN_HEAD_V1) & BIT_MASK_BCN_HEAD_V1)
+
+/* 2 REG_AUTO_LLT_V1 (Offset 0x0208) */
+
+#define BIT_SHIFT_MAX_TX_PKT_FOR_USB_AND_SDIO_V1 24
+#define BIT_MASK_MAX_TX_PKT_FOR_USB_AND_SDIO_V1 0xff
+#define BIT_MAX_TX_PKT_FOR_USB_AND_SDIO_V1(x) \
+ (((x) & BIT_MASK_MAX_TX_PKT_FOR_USB_AND_SDIO_V1) \
+ << BIT_SHIFT_MAX_TX_PKT_FOR_USB_AND_SDIO_V1)
+#define BIT_GET_MAX_TX_PKT_FOR_USB_AND_SDIO_V1(x) \
+ (((x) >> BIT_SHIFT_MAX_TX_PKT_FOR_USB_AND_SDIO_V1) & \
+ BIT_MASK_MAX_TX_PKT_FOR_USB_AND_SDIO_V1)
+
+/* 2 REG_AUTO_LLT_V1 (Offset 0x0208) */
+
+#define BIT_SHIFT_LLT_FREE_PAGE_V1 8
+#define BIT_MASK_LLT_FREE_PAGE_V1 0xffff
+#define BIT_LLT_FREE_PAGE_V1(x) \
+ (((x) & BIT_MASK_LLT_FREE_PAGE_V1) << BIT_SHIFT_LLT_FREE_PAGE_V1)
+#define BIT_GET_LLT_FREE_PAGE_V1(x) \
+ (((x) >> BIT_SHIFT_LLT_FREE_PAGE_V1) & BIT_MASK_LLT_FREE_PAGE_V1)
+
+/* 2 REG_DWBCN0_CTRL (Offset 0x0208) */
+
+#define BIT_SHIFT_BLK_DESC_NUM 4
+#define BIT_MASK_BLK_DESC_NUM 0xf
+#define BIT_BLK_DESC_NUM(x) \
+ (((x) & BIT_MASK_BLK_DESC_NUM) << BIT_SHIFT_BLK_DESC_NUM)
+#define BIT_GET_BLK_DESC_NUM(x) \
+ (((x) >> BIT_SHIFT_BLK_DESC_NUM) & BIT_MASK_BLK_DESC_NUM)
+
+/* 2 REG_AUTO_LLT_V1 (Offset 0x0208) */
+
+#define BIT_R_BCN_HEAD_SEL BIT(3)
+#define BIT_R_EN_BCN_SW_HEAD_SEL BIT(2)
+#define BIT_LLT_DBG_SEL BIT(1)
+#define BIT_AUTO_INIT_LLT_V1 BIT(0)
+
+/* 2 REG_TXDMA_OFFSET_CHK (Offset 0x020C) */
+
+#define BIT_EM_CHKSUM_FIN BIT(31)
+#define BIT_EMN_PCIE_DMA_MOD BIT(30)
+
+/* 2 REG_TXDMA_OFFSET_CHK (Offset 0x020C) */
+
+#define BIT_EN_TXQUE_CLR BIT(29)
+#define BIT_EN_PCIE_FIFO_MODE BIT(28)
+
+/* 2 REG_TXDMA_OFFSET_CHK (Offset 0x020C) */
+
+#define BIT_SHIFT_PG_UNDER_TH_V1 16
+#define BIT_MASK_PG_UNDER_TH_V1 0xfff
+#define BIT_PG_UNDER_TH_V1(x) \
+ (((x) & BIT_MASK_PG_UNDER_TH_V1) << BIT_SHIFT_PG_UNDER_TH_V1)
+#define BIT_GET_PG_UNDER_TH_V1(x) \
+ (((x) >> BIT_SHIFT_PG_UNDER_TH_V1) & BIT_MASK_PG_UNDER_TH_V1)
+
+/* 2 REG_TXDMA_OFFSET_CHK (Offset 0x020C) */
+
+#define BIT_RESTORE_H2C_ADDRESS BIT(15)
+
+/* 2 REG_TXDMA_OFFSET_CHK (Offset 0x020C) */
+
+#define BIT_SDIO_TXDESC_CHKSUM_EN BIT(13)
+#define BIT_RST_RDPTR BIT(12)
+#define BIT_RST_WRPTR BIT(11)
+#define BIT_CHK_PG_TH_EN BIT(10)
+#define BIT_DROP_DATA_EN BIT(9)
+#define BIT_CHECK_OFFSET_EN BIT(8)
+
+#define BIT_SHIFT_CHECK_OFFSET 0
+#define BIT_MASK_CHECK_OFFSET 0xff
+#define BIT_CHECK_OFFSET(x) \
+ (((x) & BIT_MASK_CHECK_OFFSET) << BIT_SHIFT_CHECK_OFFSET)
+#define BIT_GET_CHECK_OFFSET(x) \
+ (((x) >> BIT_SHIFT_CHECK_OFFSET) & BIT_MASK_CHECK_OFFSET)
+
+/* 2 REG_TXDMA_STATUS (Offset 0x0210) */
+
+#define BIT_HI_OQT_UDN BIT(17)
+#define BIT_HI_OQT_OVF BIT(16)
+#define BIT_PAYLOAD_CHKSUM_ERR BIT(15)
+#define BIT_PAYLOAD_UDN BIT(14)
+#define BIT_PAYLOAD_OVF BIT(13)
+#define BIT_DSC_CHKSUM_FAIL BIT(12)
+#define BIT_UNKNOWN_QSEL BIT(11)
+#define BIT_EP_QSEL_DIFF BIT(10)
+#define BIT_TX_OFFS_UNMATCH BIT(9)
+#define BIT_TXOQT_UDN BIT(8)
+#define BIT_TXOQT_OVF BIT(7)
+#define BIT_TXDMA_SFF_UDN BIT(6)
+#define BIT_TXDMA_SFF_OVF BIT(5)
+#define BIT_LLT_NULL_PG BIT(4)
+#define BIT_PAGE_UDN BIT(3)
+#define BIT_PAGE_OVF BIT(2)
+#define BIT_TXFF_PG_UDN BIT(1)
+#define BIT_TXFF_PG_OVF BIT(0)
+
+/* 2 REG_TQPNT1 (Offset 0x0218) */
+
+#define BIT_SHIFT_HPQ_HIGH_TH_V1 16
+#define BIT_MASK_HPQ_HIGH_TH_V1 0xfff
+#define BIT_HPQ_HIGH_TH_V1(x) \
+ (((x) & BIT_MASK_HPQ_HIGH_TH_V1) << BIT_SHIFT_HPQ_HIGH_TH_V1)
+#define BIT_GET_HPQ_HIGH_TH_V1(x) \
+ (((x) >> BIT_SHIFT_HPQ_HIGH_TH_V1) & BIT_MASK_HPQ_HIGH_TH_V1)
+
+/* 2 REG_TQPNT1 (Offset 0x0218) */
+
+#define BIT_SHIFT_HPQ_LOW_TH_V1 0
+#define BIT_MASK_HPQ_LOW_TH_V1 0xfff
+#define BIT_HPQ_LOW_TH_V1(x) \
+ (((x) & BIT_MASK_HPQ_LOW_TH_V1) << BIT_SHIFT_HPQ_LOW_TH_V1)
+#define BIT_GET_HPQ_LOW_TH_V1(x) \
+ (((x) >> BIT_SHIFT_HPQ_LOW_TH_V1) & BIT_MASK_HPQ_LOW_TH_V1)
+
+/* 2 REG_TQPNT2 (Offset 0x021C) */
+
+#define BIT_SHIFT_NPQ_HIGH_TH_V1 16
+#define BIT_MASK_NPQ_HIGH_TH_V1 0xfff
+#define BIT_NPQ_HIGH_TH_V1(x) \
+ (((x) & BIT_MASK_NPQ_HIGH_TH_V1) << BIT_SHIFT_NPQ_HIGH_TH_V1)
+#define BIT_GET_NPQ_HIGH_TH_V1(x) \
+ (((x) >> BIT_SHIFT_NPQ_HIGH_TH_V1) & BIT_MASK_NPQ_HIGH_TH_V1)
+
+/* 2 REG_TQPNT2 (Offset 0x021C) */
+
+#define BIT_SHIFT_NPQ_LOW_TH_V1 0
+#define BIT_MASK_NPQ_LOW_TH_V1 0xfff
+#define BIT_NPQ_LOW_TH_V1(x) \
+ (((x) & BIT_MASK_NPQ_LOW_TH_V1) << BIT_SHIFT_NPQ_LOW_TH_V1)
+#define BIT_GET_NPQ_LOW_TH_V1(x) \
+ (((x) >> BIT_SHIFT_NPQ_LOW_TH_V1) & BIT_MASK_NPQ_LOW_TH_V1)
+
+/* 2 REG_TQPNT3 (Offset 0x0220) */
+
+#define BIT_SHIFT_LPQ_HIGH_TH_V1 16
+#define BIT_MASK_LPQ_HIGH_TH_V1 0xfff
+#define BIT_LPQ_HIGH_TH_V1(x) \
+ (((x) & BIT_MASK_LPQ_HIGH_TH_V1) << BIT_SHIFT_LPQ_HIGH_TH_V1)
+#define BIT_GET_LPQ_HIGH_TH_V1(x) \
+ (((x) >> BIT_SHIFT_LPQ_HIGH_TH_V1) & BIT_MASK_LPQ_HIGH_TH_V1)
+
+/* 2 REG_TQPNT3 (Offset 0x0220) */
+
+#define BIT_SHIFT_LPQ_LOW_TH_V1 0
+#define BIT_MASK_LPQ_LOW_TH_V1 0xfff
+#define BIT_LPQ_LOW_TH_V1(x) \
+ (((x) & BIT_MASK_LPQ_LOW_TH_V1) << BIT_SHIFT_LPQ_LOW_TH_V1)
+#define BIT_GET_LPQ_LOW_TH_V1(x) \
+ (((x) >> BIT_SHIFT_LPQ_LOW_TH_V1) & BIT_MASK_LPQ_LOW_TH_V1)
+
+/* 2 REG_TQPNT4 (Offset 0x0224) */
+
+#define BIT_SHIFT_EXQ_HIGH_TH_V1 16
+#define BIT_MASK_EXQ_HIGH_TH_V1 0xfff
+#define BIT_EXQ_HIGH_TH_V1(x) \
+ (((x) & BIT_MASK_EXQ_HIGH_TH_V1) << BIT_SHIFT_EXQ_HIGH_TH_V1)
+#define BIT_GET_EXQ_HIGH_TH_V1(x) \
+ (((x) >> BIT_SHIFT_EXQ_HIGH_TH_V1) & BIT_MASK_EXQ_HIGH_TH_V1)
+
+/* 2 REG_TQPNT4 (Offset 0x0224) */
+
+#define BIT_SHIFT_EXQ_LOW_TH_V1 0
+#define BIT_MASK_EXQ_LOW_TH_V1 0xfff
+#define BIT_EXQ_LOW_TH_V1(x) \
+ (((x) & BIT_MASK_EXQ_LOW_TH_V1) << BIT_SHIFT_EXQ_LOW_TH_V1)
+#define BIT_GET_EXQ_LOW_TH_V1(x) \
+ (((x) >> BIT_SHIFT_EXQ_LOW_TH_V1) & BIT_MASK_EXQ_LOW_TH_V1)
+
+/* 2 REG_RQPN_CTRL_1 (Offset 0x0228) */
+
+#define BIT_SHIFT_TXPKTNUM_H 16
+#define BIT_MASK_TXPKTNUM_H 0xffff
+#define BIT_TXPKTNUM_H(x) (((x) & BIT_MASK_TXPKTNUM_H) << BIT_SHIFT_TXPKTNUM_H)
+#define BIT_GET_TXPKTNUM_H(x) \
+ (((x) >> BIT_SHIFT_TXPKTNUM_H) & BIT_MASK_TXPKTNUM_H)
+
+/* 2 REG_RQPN_CTRL_1 (Offset 0x0228) */
+
+#define BIT_SHIFT_TXPKTNUM_V2 0
+#define BIT_MASK_TXPKTNUM_V2 0xffff
+#define BIT_TXPKTNUM_V2(x) \
+ (((x) & BIT_MASK_TXPKTNUM_V2) << BIT_SHIFT_TXPKTNUM_V2)
+#define BIT_GET_TXPKTNUM_V2(x) \
+ (((x) >> BIT_SHIFT_TXPKTNUM_V2) & BIT_MASK_TXPKTNUM_V2)
+
+/* 2 REG_RQPN_CTRL_2 (Offset 0x022C) */
+
+#define BIT_EXQ_PUBLIC_DIS_V1 BIT(19)
+#define BIT_NPQ_PUBLIC_DIS_V1 BIT(18)
+#define BIT_LPQ_PUBLIC_DIS_V1 BIT(17)
+#define BIT_HPQ_PUBLIC_DIS_V1 BIT(16)
+
+/* 2 REG_FIFOPAGE_INFO_1 (Offset 0x0230) */
+
+#define BIT_SHIFT_HPQ_AVAL_PG_V1 16
+#define BIT_MASK_HPQ_AVAL_PG_V1 0xfff
+#define BIT_HPQ_AVAL_PG_V1(x) \
+ (((x) & BIT_MASK_HPQ_AVAL_PG_V1) << BIT_SHIFT_HPQ_AVAL_PG_V1)
+#define BIT_GET_HPQ_AVAL_PG_V1(x) \
+ (((x) >> BIT_SHIFT_HPQ_AVAL_PG_V1) & BIT_MASK_HPQ_AVAL_PG_V1)
+
+#define BIT_SHIFT_HPQ_V1 0
+#define BIT_MASK_HPQ_V1 0xfff
+#define BIT_HPQ_V1(x) (((x) & BIT_MASK_HPQ_V1) << BIT_SHIFT_HPQ_V1)
+#define BIT_GET_HPQ_V1(x) (((x) >> BIT_SHIFT_HPQ_V1) & BIT_MASK_HPQ_V1)
+
+/* 2 REG_FIFOPAGE_INFO_2 (Offset 0x0234) */
+
+#define BIT_SHIFT_LPQ_AVAL_PG_V1 16
+#define BIT_MASK_LPQ_AVAL_PG_V1 0xfff
+#define BIT_LPQ_AVAL_PG_V1(x) \
+ (((x) & BIT_MASK_LPQ_AVAL_PG_V1) << BIT_SHIFT_LPQ_AVAL_PG_V1)
+#define BIT_GET_LPQ_AVAL_PG_V1(x) \
+ (((x) >> BIT_SHIFT_LPQ_AVAL_PG_V1) & BIT_MASK_LPQ_AVAL_PG_V1)
+
+#define BIT_SHIFT_LPQ_V1 0
+#define BIT_MASK_LPQ_V1 0xfff
+#define BIT_LPQ_V1(x) (((x) & BIT_MASK_LPQ_V1) << BIT_SHIFT_LPQ_V1)
+#define BIT_GET_LPQ_V1(x) (((x) >> BIT_SHIFT_LPQ_V1) & BIT_MASK_LPQ_V1)
+
+/* 2 REG_FIFOPAGE_INFO_3 (Offset 0x0238) */
+
+#define BIT_SHIFT_NPQ_AVAL_PG_V1 16
+#define BIT_MASK_NPQ_AVAL_PG_V1 0xfff
+#define BIT_NPQ_AVAL_PG_V1(x) \
+ (((x) & BIT_MASK_NPQ_AVAL_PG_V1) << BIT_SHIFT_NPQ_AVAL_PG_V1)
+#define BIT_GET_NPQ_AVAL_PG_V1(x) \
+ (((x) >> BIT_SHIFT_NPQ_AVAL_PG_V1) & BIT_MASK_NPQ_AVAL_PG_V1)
+
+/* 2 REG_FIFOPAGE_INFO_3 (Offset 0x0238) */
+
+#define BIT_SHIFT_NPQ_V1 0
+#define BIT_MASK_NPQ_V1 0xfff
+#define BIT_NPQ_V1(x) (((x) & BIT_MASK_NPQ_V1) << BIT_SHIFT_NPQ_V1)
+#define BIT_GET_NPQ_V1(x) (((x) >> BIT_SHIFT_NPQ_V1) & BIT_MASK_NPQ_V1)
+
+/* 2 REG_FIFOPAGE_INFO_4 (Offset 0x023C) */
+
+#define BIT_SHIFT_EXQ_AVAL_PG_V1 16
+#define BIT_MASK_EXQ_AVAL_PG_V1 0xfff
+#define BIT_EXQ_AVAL_PG_V1(x) \
+ (((x) & BIT_MASK_EXQ_AVAL_PG_V1) << BIT_SHIFT_EXQ_AVAL_PG_V1)
+#define BIT_GET_EXQ_AVAL_PG_V1(x) \
+ (((x) >> BIT_SHIFT_EXQ_AVAL_PG_V1) & BIT_MASK_EXQ_AVAL_PG_V1)
+
+#define BIT_SHIFT_EXQ_V1 0
+#define BIT_MASK_EXQ_V1 0xfff
+#define BIT_EXQ_V1(x) (((x) & BIT_MASK_EXQ_V1) << BIT_SHIFT_EXQ_V1)
+#define BIT_GET_EXQ_V1(x) (((x) >> BIT_SHIFT_EXQ_V1) & BIT_MASK_EXQ_V1)
+
+/* 2 REG_FIFOPAGE_INFO_5 (Offset 0x0240) */
+
+#define BIT_SHIFT_PUBQ_AVAL_PG_V1 16
+#define BIT_MASK_PUBQ_AVAL_PG_V1 0xfff
+#define BIT_PUBQ_AVAL_PG_V1(x) \
+ (((x) & BIT_MASK_PUBQ_AVAL_PG_V1) << BIT_SHIFT_PUBQ_AVAL_PG_V1)
+#define BIT_GET_PUBQ_AVAL_PG_V1(x) \
+ (((x) >> BIT_SHIFT_PUBQ_AVAL_PG_V1) & BIT_MASK_PUBQ_AVAL_PG_V1)
+
+#define BIT_SHIFT_PUBQ_V1 0
+#define BIT_MASK_PUBQ_V1 0xfff
+#define BIT_PUBQ_V1(x) (((x) & BIT_MASK_PUBQ_V1) << BIT_SHIFT_PUBQ_V1)
+#define BIT_GET_PUBQ_V1(x) (((x) >> BIT_SHIFT_PUBQ_V1) & BIT_MASK_PUBQ_V1)
+
+/* 2 REG_H2C_HEAD (Offset 0x0244) */
+
+#define BIT_SHIFT_H2C_HEAD 0
+#define BIT_MASK_H2C_HEAD 0x3ffff
+#define BIT_H2C_HEAD(x) (((x) & BIT_MASK_H2C_HEAD) << BIT_SHIFT_H2C_HEAD)
+#define BIT_GET_H2C_HEAD(x) (((x) >> BIT_SHIFT_H2C_HEAD) & BIT_MASK_H2C_HEAD)
+
+/* 2 REG_H2C_TAIL (Offset 0x0248) */
+
+#define BIT_SHIFT_H2C_TAIL 0
+#define BIT_MASK_H2C_TAIL 0x3ffff
+#define BIT_H2C_TAIL(x) (((x) & BIT_MASK_H2C_TAIL) << BIT_SHIFT_H2C_TAIL)
+#define BIT_GET_H2C_TAIL(x) (((x) >> BIT_SHIFT_H2C_TAIL) & BIT_MASK_H2C_TAIL)
+
+/* 2 REG_H2C_READ_ADDR (Offset 0x024C) */
+
+#define BIT_SHIFT_H2C_READ_ADDR 0
+#define BIT_MASK_H2C_READ_ADDR 0x3ffff
+#define BIT_H2C_READ_ADDR(x) \
+ (((x) & BIT_MASK_H2C_READ_ADDR) << BIT_SHIFT_H2C_READ_ADDR)
+#define BIT_GET_H2C_READ_ADDR(x) \
+ (((x) >> BIT_SHIFT_H2C_READ_ADDR) & BIT_MASK_H2C_READ_ADDR)
+
+/* 2 REG_H2C_WR_ADDR (Offset 0x0250) */
+
+#define BIT_SHIFT_H2C_WR_ADDR 0
+#define BIT_MASK_H2C_WR_ADDR 0x3ffff
+#define BIT_H2C_WR_ADDR(x) \
+ (((x) & BIT_MASK_H2C_WR_ADDR) << BIT_SHIFT_H2C_WR_ADDR)
+#define BIT_GET_H2C_WR_ADDR(x) \
+ (((x) >> BIT_SHIFT_H2C_WR_ADDR) & BIT_MASK_H2C_WR_ADDR)
+
+/* 2 REG_H2C_INFO (Offset 0x0254) */
+
+#define BIT_H2C_SPACE_VLD BIT(3)
+#define BIT_H2C_WR_ADDR_RST BIT(2)
+
+#define BIT_SHIFT_H2C_LEN_SEL 0
+#define BIT_MASK_H2C_LEN_SEL 0x3
+#define BIT_H2C_LEN_SEL(x) \
+ (((x) & BIT_MASK_H2C_LEN_SEL) << BIT_SHIFT_H2C_LEN_SEL)
+#define BIT_GET_H2C_LEN_SEL(x) \
+ (((x) >> BIT_SHIFT_H2C_LEN_SEL) & BIT_MASK_H2C_LEN_SEL)
+
+/* 2 REG_RXDMA_AGG_PG_TH (Offset 0x0280) */
+
+#define BIT_SHIFT_RXDMA_AGG_OLD_MOD 24
+#define BIT_MASK_RXDMA_AGG_OLD_MOD 0xff
+#define BIT_RXDMA_AGG_OLD_MOD(x) \
+ (((x) & BIT_MASK_RXDMA_AGG_OLD_MOD) << BIT_SHIFT_RXDMA_AGG_OLD_MOD)
+#define BIT_GET_RXDMA_AGG_OLD_MOD(x) \
+ (((x) >> BIT_SHIFT_RXDMA_AGG_OLD_MOD) & BIT_MASK_RXDMA_AGG_OLD_MOD)
+
+/* 2 REG_RXDMA_AGG_PG_TH (Offset 0x0280) */
+
+#define BIT_SHIFT_PKT_NUM_WOL 16
+#define BIT_MASK_PKT_NUM_WOL 0xff
+#define BIT_PKT_NUM_WOL(x) \
+ (((x) & BIT_MASK_PKT_NUM_WOL) << BIT_SHIFT_PKT_NUM_WOL)
+#define BIT_GET_PKT_NUM_WOL(x) \
+ (((x) >> BIT_SHIFT_PKT_NUM_WOL) & BIT_MASK_PKT_NUM_WOL)
+
+/* 2 REG_RXDMA_AGG_PG_TH (Offset 0x0280) */
+
+#define BIT_SHIFT_DMA_AGG_TO 8
+#define BIT_MASK_DMA_AGG_TO 0xf
+#define BIT_DMA_AGG_TO(x) (((x) & BIT_MASK_DMA_AGG_TO) << BIT_SHIFT_DMA_AGG_TO)
+#define BIT_GET_DMA_AGG_TO(x) \
+ (((x) >> BIT_SHIFT_DMA_AGG_TO) & BIT_MASK_DMA_AGG_TO)
+
+/* 2 REG_RXDMA_AGG_PG_TH (Offset 0x0280) */
+
+#define BIT_SHIFT_RXDMA_AGG_PG_TH_V1 0
+#define BIT_MASK_RXDMA_AGG_PG_TH_V1 0xf
+#define BIT_RXDMA_AGG_PG_TH_V1(x) \
+ (((x) & BIT_MASK_RXDMA_AGG_PG_TH_V1) << BIT_SHIFT_RXDMA_AGG_PG_TH_V1)
+#define BIT_GET_RXDMA_AGG_PG_TH_V1(x) \
+ (((x) >> BIT_SHIFT_RXDMA_AGG_PG_TH_V1) & BIT_MASK_RXDMA_AGG_PG_TH_V1)
+
+/* 2 REG_RXPKT_NUM (Offset 0x0284) */
+
+#define BIT_SHIFT_RXPKT_NUM 24
+#define BIT_MASK_RXPKT_NUM 0xff
+#define BIT_RXPKT_NUM(x) (((x) & BIT_MASK_RXPKT_NUM) << BIT_SHIFT_RXPKT_NUM)
+#define BIT_GET_RXPKT_NUM(x) (((x) >> BIT_SHIFT_RXPKT_NUM) & BIT_MASK_RXPKT_NUM)
+
+/* 2 REG_RXPKT_NUM (Offset 0x0284) */
+
+#define BIT_SHIFT_FW_UPD_RDPTR19_TO_16 20
+#define BIT_MASK_FW_UPD_RDPTR19_TO_16 0xf
+#define BIT_FW_UPD_RDPTR19_TO_16(x) \
+ (((x) & BIT_MASK_FW_UPD_RDPTR19_TO_16) \
+ << BIT_SHIFT_FW_UPD_RDPTR19_TO_16)
+#define BIT_GET_FW_UPD_RDPTR19_TO_16(x) \
+ (((x) >> BIT_SHIFT_FW_UPD_RDPTR19_TO_16) & \
+ BIT_MASK_FW_UPD_RDPTR19_TO_16)
+
+/* 2 REG_RXPKT_NUM (Offset 0x0284) */
+
+#define BIT_RXDMA_REQ BIT(19)
+#define BIT_RW_RELEASE_EN BIT(18)
+#define BIT_RXDMA_IDLE BIT(17)
+#define BIT_RXPKT_RELEASE_POLL BIT(16)
+
+#define BIT_SHIFT_FW_UPD_RDPTR 0
+#define BIT_MASK_FW_UPD_RDPTR 0xffff
+#define BIT_FW_UPD_RDPTR(x) \
+ (((x) & BIT_MASK_FW_UPD_RDPTR) << BIT_SHIFT_FW_UPD_RDPTR)
+#define BIT_GET_FW_UPD_RDPTR(x) \
+ (((x) >> BIT_SHIFT_FW_UPD_RDPTR) & BIT_MASK_FW_UPD_RDPTR)
+
+/* 2 REG_RXDMA_STATUS (Offset 0x0288) */
+
+#define BIT_C2H_PKT_OVF BIT(7)
+
+/* 2 REG_RXDMA_STATUS (Offset 0x0288) */
+
+#define BIT_AGG_CONFGI_ISSUE BIT(6)
+
+/* 2 REG_RXDMA_STATUS (Offset 0x0288) */
+
+#define BIT_FW_POLL_ISSUE BIT(5)
+#define BIT_RX_DATA_UDN BIT(4)
+#define BIT_RX_SFF_UDN BIT(3)
+#define BIT_RX_SFF_OVF BIT(2)
+
+/* 2 REG_RXDMA_STATUS (Offset 0x0288) */
+
+#define BIT_RXPKT_OVF BIT(0)
+
+/* 2 REG_RXDMA_DPR (Offset 0x028C) */
+
+#define BIT_SHIFT_RDE_DEBUG 0
+#define BIT_MASK_RDE_DEBUG 0xffffffffL
+#define BIT_RDE_DEBUG(x) (((x) & BIT_MASK_RDE_DEBUG) << BIT_SHIFT_RDE_DEBUG)
+#define BIT_GET_RDE_DEBUG(x) (((x) >> BIT_SHIFT_RDE_DEBUG) & BIT_MASK_RDE_DEBUG)
+
+/* 2 REG_RXDMA_MODE (Offset 0x0290) */
+
+#define BIT_SHIFT_PKTNUM_TH_V2 24
+#define BIT_MASK_PKTNUM_TH_V2 0x1f
+#define BIT_PKTNUM_TH_V2(x) \
+ (((x) & BIT_MASK_PKTNUM_TH_V2) << BIT_SHIFT_PKTNUM_TH_V2)
+#define BIT_GET_PKTNUM_TH_V2(x) \
+ (((x) >> BIT_SHIFT_PKTNUM_TH_V2) & BIT_MASK_PKTNUM_TH_V2)
+
+#define BIT_TXBA_BREAK_USBAGG BIT(23)
+
+#define BIT_SHIFT_PKTLEN_PARA 16
+#define BIT_MASK_PKTLEN_PARA 0x7
+#define BIT_PKTLEN_PARA(x) \
+ (((x) & BIT_MASK_PKTLEN_PARA) << BIT_SHIFT_PKTLEN_PARA)
+#define BIT_GET_PKTLEN_PARA(x) \
+ (((x) >> BIT_SHIFT_PKTLEN_PARA) & BIT_MASK_PKTLEN_PARA)
+
+/* 2 REG_RXDMA_MODE (Offset 0x0290) */
+
+#define BIT_SHIFT_BURST_SIZE 4
+#define BIT_MASK_BURST_SIZE 0x3
+#define BIT_BURST_SIZE(x) (((x) & BIT_MASK_BURST_SIZE) << BIT_SHIFT_BURST_SIZE)
+#define BIT_GET_BURST_SIZE(x) \
+ (((x) >> BIT_SHIFT_BURST_SIZE) & BIT_MASK_BURST_SIZE)
+
+#define BIT_SHIFT_BURST_CNT 2
+#define BIT_MASK_BURST_CNT 0x3
+#define BIT_BURST_CNT(x) (((x) & BIT_MASK_BURST_CNT) << BIT_SHIFT_BURST_CNT)
+#define BIT_GET_BURST_CNT(x) (((x) >> BIT_SHIFT_BURST_CNT) & BIT_MASK_BURST_CNT)
+
+/* 2 REG_RXDMA_MODE (Offset 0x0290) */
+
+#define BIT_DMA_MODE BIT(1)
+
+/* 2 REG_C2H_PKT (Offset 0x0294) */
+
+#define BIT_SHIFT_R_C2H_STR_ADDR_16_TO_19 24
+#define BIT_MASK_R_C2H_STR_ADDR_16_TO_19 0xf
+#define BIT_R_C2H_STR_ADDR_16_TO_19(x) \
+ (((x) & BIT_MASK_R_C2H_STR_ADDR_16_TO_19) \
+ << BIT_SHIFT_R_C2H_STR_ADDR_16_TO_19)
+#define BIT_GET_R_C2H_STR_ADDR_16_TO_19(x) \
+ (((x) >> BIT_SHIFT_R_C2H_STR_ADDR_16_TO_19) & \
+ BIT_MASK_R_C2H_STR_ADDR_16_TO_19)
+
+#define BIT_SHIFT_MDIO_PHY_ADDR 24
+#define BIT_MASK_MDIO_PHY_ADDR 0x1f
+#define BIT_MDIO_PHY_ADDR(x) \
+ (((x) & BIT_MASK_MDIO_PHY_ADDR) << BIT_SHIFT_MDIO_PHY_ADDR)
+#define BIT_GET_MDIO_PHY_ADDR(x) \
+ (((x) >> BIT_SHIFT_MDIO_PHY_ADDR) & BIT_MASK_MDIO_PHY_ADDR)
+
+/* 2 REG_C2H_PKT (Offset 0x0294) */
+
+#define BIT_R_C2H_PKT_REQ BIT(16)
+#define BIT_RX_CLOSE_EN BIT(15)
+#define BIT_STOP_BCNQ BIT(14)
+#define BIT_STOP_MGQ BIT(13)
+#define BIT_STOP_VOQ BIT(12)
+#define BIT_STOP_VIQ BIT(11)
+#define BIT_STOP_BEQ BIT(10)
+#define BIT_STOP_BKQ BIT(9)
+#define BIT_STOP_RXQ BIT(8)
+#define BIT_STOP_HI7Q BIT(7)
+#define BIT_STOP_HI6Q BIT(6)
+#define BIT_STOP_HI5Q BIT(5)
+#define BIT_STOP_HI4Q BIT(4)
+#define BIT_STOP_HI3Q BIT(3)
+#define BIT_STOP_HI2Q BIT(2)
+#define BIT_STOP_HI1Q BIT(1)
+
+#define BIT_SHIFT_R_C2H_STR_ADDR 0
+#define BIT_MASK_R_C2H_STR_ADDR 0xffff
+#define BIT_R_C2H_STR_ADDR(x) \
+ (((x) & BIT_MASK_R_C2H_STR_ADDR) << BIT_SHIFT_R_C2H_STR_ADDR)
+#define BIT_GET_R_C2H_STR_ADDR(x) \
+ (((x) >> BIT_SHIFT_R_C2H_STR_ADDR) & BIT_MASK_R_C2H_STR_ADDR)
+
+#define BIT_STOP_HI0Q BIT(0)
+
+/* 2 REG_FWFF_C2H (Offset 0x0298) */
+
+#define BIT_SHIFT_C2H_DMA_ADDR 0
+#define BIT_MASK_C2H_DMA_ADDR 0x3ffff
+#define BIT_C2H_DMA_ADDR(x) \
+ (((x) & BIT_MASK_C2H_DMA_ADDR) << BIT_SHIFT_C2H_DMA_ADDR)
+#define BIT_GET_C2H_DMA_ADDR(x) \
+ (((x) >> BIT_SHIFT_C2H_DMA_ADDR) & BIT_MASK_C2H_DMA_ADDR)
+
+/* 2 REG_FWFF_CTRL (Offset 0x029C) */
+
+#define BIT_FWFF_DMAPKT_REQ BIT(31)
+
+#define BIT_SHIFT_FWFF_DMA_PKT_NUM 16
+#define BIT_MASK_FWFF_DMA_PKT_NUM 0xff
+#define BIT_FWFF_DMA_PKT_NUM(x) \
+ (((x) & BIT_MASK_FWFF_DMA_PKT_NUM) << BIT_SHIFT_FWFF_DMA_PKT_NUM)
+#define BIT_GET_FWFF_DMA_PKT_NUM(x) \
+ (((x) >> BIT_SHIFT_FWFF_DMA_PKT_NUM) & BIT_MASK_FWFF_DMA_PKT_NUM)
+
+#define BIT_SHIFT_FWFF_STR_ADDR 0
+#define BIT_MASK_FWFF_STR_ADDR 0xffff
+#define BIT_FWFF_STR_ADDR(x) \
+ (((x) & BIT_MASK_FWFF_STR_ADDR) << BIT_SHIFT_FWFF_STR_ADDR)
+#define BIT_GET_FWFF_STR_ADDR(x) \
+ (((x) >> BIT_SHIFT_FWFF_STR_ADDR) & BIT_MASK_FWFF_STR_ADDR)
+
+/* 2 REG_FWFF_PKT_INFO (Offset 0x02A0) */
+
+#define BIT_SHIFT_FWFF_PKT_QUEUED 16
+#define BIT_MASK_FWFF_PKT_QUEUED 0xff
+#define BIT_FWFF_PKT_QUEUED(x) \
+ (((x) & BIT_MASK_FWFF_PKT_QUEUED) << BIT_SHIFT_FWFF_PKT_QUEUED)
+#define BIT_GET_FWFF_PKT_QUEUED(x) \
+ (((x) >> BIT_SHIFT_FWFF_PKT_QUEUED) & BIT_MASK_FWFF_PKT_QUEUED)
+
+/* 2 REG_FWFF_PKT_INFO (Offset 0x02A0) */
+
+#define BIT_SHIFT_FWFF_PKT_STR_ADDR 0
+#define BIT_MASK_FWFF_PKT_STR_ADDR 0xffff
+#define BIT_FWFF_PKT_STR_ADDR(x) \
+ (((x) & BIT_MASK_FWFF_PKT_STR_ADDR) << BIT_SHIFT_FWFF_PKT_STR_ADDR)
+#define BIT_GET_FWFF_PKT_STR_ADDR(x) \
+ (((x) >> BIT_SHIFT_FWFF_PKT_STR_ADDR) & BIT_MASK_FWFF_PKT_STR_ADDR)
+
+/* 2 REG_PCIE_CTRL (Offset 0x0300) */
+
+#define BIT_PCIEIO_PERSTB_SEL BIT(31)
+
+/* 2 REG_PCIE_CTRL (Offset 0x0300) */
+
+#define BIT_SHIFT_PCIE_MAX_RXDMA 28
+#define BIT_MASK_PCIE_MAX_RXDMA 0x7
+#define BIT_PCIE_MAX_RXDMA(x) \
+ (((x) & BIT_MASK_PCIE_MAX_RXDMA) << BIT_SHIFT_PCIE_MAX_RXDMA)
+#define BIT_GET_PCIE_MAX_RXDMA(x) \
+ (((x) >> BIT_SHIFT_PCIE_MAX_RXDMA) & BIT_MASK_PCIE_MAX_RXDMA)
+
+/* 2 REG_PCIE_CTRL (Offset 0x0300) */
+
+#define BIT_SHIFT_PCIE_MAX_TXDMA 24
+#define BIT_MASK_PCIE_MAX_TXDMA 0x7
+#define BIT_PCIE_MAX_TXDMA(x) \
+ (((x) & BIT_MASK_PCIE_MAX_TXDMA) << BIT_SHIFT_PCIE_MAX_TXDMA)
+#define BIT_GET_PCIE_MAX_TXDMA(x) \
+ (((x) >> BIT_SHIFT_PCIE_MAX_TXDMA) & BIT_MASK_PCIE_MAX_TXDMA)
+
+/* 2 REG_PCIE_CTRL (Offset 0x0300) */
+
+#define BIT_PCIE_RST_TRXDMA_INTF BIT(20)
+
+/* 2 REG_PCIE_CTRL (Offset 0x0300) */
+
+#define BIT_PCIE_EN_SWENT_L23 BIT(17)
+
+/* 2 REG_PCIE_CTRL (Offset 0x0300) */
+
+#define BIT_PCIE_EN_HWEXT_L1 BIT(16)
+
+/* 2 REG_INT_MIG (Offset 0x0304) */
+
+#define BIT_SHIFT_TXTTIMER_MATCH_NUM 28
+#define BIT_MASK_TXTTIMER_MATCH_NUM 0xf
+#define BIT_TXTTIMER_MATCH_NUM(x) \
+ (((x) & BIT_MASK_TXTTIMER_MATCH_NUM) << BIT_SHIFT_TXTTIMER_MATCH_NUM)
+#define BIT_GET_TXTTIMER_MATCH_NUM(x) \
+ (((x) >> BIT_SHIFT_TXTTIMER_MATCH_NUM) & BIT_MASK_TXTTIMER_MATCH_NUM)
+
+#define BIT_SHIFT_TXPKT_NUM_MATCH 24
+#define BIT_MASK_TXPKT_NUM_MATCH 0xf
+#define BIT_TXPKT_NUM_MATCH(x) \
+ (((x) & BIT_MASK_TXPKT_NUM_MATCH) << BIT_SHIFT_TXPKT_NUM_MATCH)
+#define BIT_GET_TXPKT_NUM_MATCH(x) \
+ (((x) >> BIT_SHIFT_TXPKT_NUM_MATCH) & BIT_MASK_TXPKT_NUM_MATCH)
+
+#define BIT_SHIFT_RXTTIMER_MATCH_NUM 20
+#define BIT_MASK_RXTTIMER_MATCH_NUM 0xf
+#define BIT_RXTTIMER_MATCH_NUM(x) \
+ (((x) & BIT_MASK_RXTTIMER_MATCH_NUM) << BIT_SHIFT_RXTTIMER_MATCH_NUM)
+#define BIT_GET_RXTTIMER_MATCH_NUM(x) \
+ (((x) >> BIT_SHIFT_RXTTIMER_MATCH_NUM) & BIT_MASK_RXTTIMER_MATCH_NUM)
+
+#define BIT_SHIFT_RXPKT_NUM_MATCH 16
+#define BIT_MASK_RXPKT_NUM_MATCH 0xf
+#define BIT_RXPKT_NUM_MATCH(x) \
+ (((x) & BIT_MASK_RXPKT_NUM_MATCH) << BIT_SHIFT_RXPKT_NUM_MATCH)
+#define BIT_GET_RXPKT_NUM_MATCH(x) \
+ (((x) >> BIT_SHIFT_RXPKT_NUM_MATCH) & BIT_MASK_RXPKT_NUM_MATCH)
+
+#define BIT_SHIFT_MIGRATE_TIMER 0
+#define BIT_MASK_MIGRATE_TIMER 0xffff
+#define BIT_MIGRATE_TIMER(x) \
+ (((x) & BIT_MASK_MIGRATE_TIMER) << BIT_SHIFT_MIGRATE_TIMER)
+#define BIT_GET_MIGRATE_TIMER(x) \
+ (((x) >> BIT_SHIFT_MIGRATE_TIMER) & BIT_MASK_MIGRATE_TIMER)
+
+/* 2 REG_BCNQ_TXBD_DESA (Offset 0x0308) */
+
+#define BIT_SHIFT_BCNQ_TXBD_DESA 0
+#define BIT_MASK_BCNQ_TXBD_DESA 0xffffffffffffffffL
+#define BIT_BCNQ_TXBD_DESA(x) \
+ (((x) & BIT_MASK_BCNQ_TXBD_DESA) << BIT_SHIFT_BCNQ_TXBD_DESA)
+#define BIT_GET_BCNQ_TXBD_DESA(x) \
+ (((x) >> BIT_SHIFT_BCNQ_TXBD_DESA) & BIT_MASK_BCNQ_TXBD_DESA)
+
+/* 2 REG_MGQ_TXBD_DESA (Offset 0x0310) */
+
+#define BIT_SHIFT_MGQ_TXBD_DESA 0
+#define BIT_MASK_MGQ_TXBD_DESA 0xffffffffffffffffL
+#define BIT_MGQ_TXBD_DESA(x) \
+ (((x) & BIT_MASK_MGQ_TXBD_DESA) << BIT_SHIFT_MGQ_TXBD_DESA)
+#define BIT_GET_MGQ_TXBD_DESA(x) \
+ (((x) >> BIT_SHIFT_MGQ_TXBD_DESA) & BIT_MASK_MGQ_TXBD_DESA)
+
+/* 2 REG_VOQ_TXBD_DESA (Offset 0x0318) */
+
+#define BIT_SHIFT_VOQ_TXBD_DESA 0
+#define BIT_MASK_VOQ_TXBD_DESA 0xffffffffffffffffL
+#define BIT_VOQ_TXBD_DESA(x) \
+ (((x) & BIT_MASK_VOQ_TXBD_DESA) << BIT_SHIFT_VOQ_TXBD_DESA)
+#define BIT_GET_VOQ_TXBD_DESA(x) \
+ (((x) >> BIT_SHIFT_VOQ_TXBD_DESA) & BIT_MASK_VOQ_TXBD_DESA)
+
+/* 2 REG_VIQ_TXBD_DESA (Offset 0x0320) */
+
+#define BIT_SHIFT_VIQ_TXBD_DESA 0
+#define BIT_MASK_VIQ_TXBD_DESA 0xffffffffffffffffL
+#define BIT_VIQ_TXBD_DESA(x) \
+ (((x) & BIT_MASK_VIQ_TXBD_DESA) << BIT_SHIFT_VIQ_TXBD_DESA)
+#define BIT_GET_VIQ_TXBD_DESA(x) \
+ (((x) >> BIT_SHIFT_VIQ_TXBD_DESA) & BIT_MASK_VIQ_TXBD_DESA)
+
+/* 2 REG_BEQ_TXBD_DESA (Offset 0x0328) */
+
+#define BIT_SHIFT_BEQ_TXBD_DESA 0
+#define BIT_MASK_BEQ_TXBD_DESA 0xffffffffffffffffL
+#define BIT_BEQ_TXBD_DESA(x) \
+ (((x) & BIT_MASK_BEQ_TXBD_DESA) << BIT_SHIFT_BEQ_TXBD_DESA)
+#define BIT_GET_BEQ_TXBD_DESA(x) \
+ (((x) >> BIT_SHIFT_BEQ_TXBD_DESA) & BIT_MASK_BEQ_TXBD_DESA)
+
+/* 2 REG_BKQ_TXBD_DESA (Offset 0x0330) */
+
+#define BIT_SHIFT_BKQ_TXBD_DESA 0
+#define BIT_MASK_BKQ_TXBD_DESA 0xffffffffffffffffL
+#define BIT_BKQ_TXBD_DESA(x) \
+ (((x) & BIT_MASK_BKQ_TXBD_DESA) << BIT_SHIFT_BKQ_TXBD_DESA)
+#define BIT_GET_BKQ_TXBD_DESA(x) \
+ (((x) >> BIT_SHIFT_BKQ_TXBD_DESA) & BIT_MASK_BKQ_TXBD_DESA)
+
+/* 2 REG_RXQ_RXBD_DESA (Offset 0x0338) */
+
+#define BIT_SHIFT_RXQ_RXBD_DESA 0
+#define BIT_MASK_RXQ_RXBD_DESA 0xffffffffffffffffL
+#define BIT_RXQ_RXBD_DESA(x) \
+ (((x) & BIT_MASK_RXQ_RXBD_DESA) << BIT_SHIFT_RXQ_RXBD_DESA)
+#define BIT_GET_RXQ_RXBD_DESA(x) \
+ (((x) >> BIT_SHIFT_RXQ_RXBD_DESA) & BIT_MASK_RXQ_RXBD_DESA)
+
+/* 2 REG_HI0Q_TXBD_DESA (Offset 0x0340) */
+
+#define BIT_SHIFT_HI0Q_TXBD_DESA 0
+#define BIT_MASK_HI0Q_TXBD_DESA 0xffffffffffffffffL
+#define BIT_HI0Q_TXBD_DESA(x) \
+ (((x) & BIT_MASK_HI0Q_TXBD_DESA) << BIT_SHIFT_HI0Q_TXBD_DESA)
+#define BIT_GET_HI0Q_TXBD_DESA(x) \
+ (((x) >> BIT_SHIFT_HI0Q_TXBD_DESA) & BIT_MASK_HI0Q_TXBD_DESA)
+
+/* 2 REG_HI1Q_TXBD_DESA (Offset 0x0348) */
+
+#define BIT_SHIFT_HI1Q_TXBD_DESA 0
+#define BIT_MASK_HI1Q_TXBD_DESA 0xffffffffffffffffL
+#define BIT_HI1Q_TXBD_DESA(x) \
+ (((x) & BIT_MASK_HI1Q_TXBD_DESA) << BIT_SHIFT_HI1Q_TXBD_DESA)
+#define BIT_GET_HI1Q_TXBD_DESA(x) \
+ (((x) >> BIT_SHIFT_HI1Q_TXBD_DESA) & BIT_MASK_HI1Q_TXBD_DESA)
+
+/* 2 REG_HI2Q_TXBD_DESA (Offset 0x0350) */
+
+#define BIT_SHIFT_HI2Q_TXBD_DESA 0
+#define BIT_MASK_HI2Q_TXBD_DESA 0xffffffffffffffffL
+#define BIT_HI2Q_TXBD_DESA(x) \
+ (((x) & BIT_MASK_HI2Q_TXBD_DESA) << BIT_SHIFT_HI2Q_TXBD_DESA)
+#define BIT_GET_HI2Q_TXBD_DESA(x) \
+ (((x) >> BIT_SHIFT_HI2Q_TXBD_DESA) & BIT_MASK_HI2Q_TXBD_DESA)
+
+/* 2 REG_HI3Q_TXBD_DESA (Offset 0x0358) */
+
+#define BIT_SHIFT_HI3Q_TXBD_DESA 0
+#define BIT_MASK_HI3Q_TXBD_DESA 0xffffffffffffffffL
+#define BIT_HI3Q_TXBD_DESA(x) \
+ (((x) & BIT_MASK_HI3Q_TXBD_DESA) << BIT_SHIFT_HI3Q_TXBD_DESA)
+#define BIT_GET_HI3Q_TXBD_DESA(x) \
+ (((x) >> BIT_SHIFT_HI3Q_TXBD_DESA) & BIT_MASK_HI3Q_TXBD_DESA)
+
+/* 2 REG_HI4Q_TXBD_DESA (Offset 0x0360) */
+
+#define BIT_SHIFT_HI4Q_TXBD_DESA 0
+#define BIT_MASK_HI4Q_TXBD_DESA 0xffffffffffffffffL
+#define BIT_HI4Q_TXBD_DESA(x) \
+ (((x) & BIT_MASK_HI4Q_TXBD_DESA) << BIT_SHIFT_HI4Q_TXBD_DESA)
+#define BIT_GET_HI4Q_TXBD_DESA(x) \
+ (((x) >> BIT_SHIFT_HI4Q_TXBD_DESA) & BIT_MASK_HI4Q_TXBD_DESA)
+
+/* 2 REG_HI5Q_TXBD_DESA (Offset 0x0368) */
+
+#define BIT_SHIFT_HI5Q_TXBD_DESA 0
+#define BIT_MASK_HI5Q_TXBD_DESA 0xffffffffffffffffL
+#define BIT_HI5Q_TXBD_DESA(x) \
+ (((x) & BIT_MASK_HI5Q_TXBD_DESA) << BIT_SHIFT_HI5Q_TXBD_DESA)
+#define BIT_GET_HI5Q_TXBD_DESA(x) \
+ (((x) >> BIT_SHIFT_HI5Q_TXBD_DESA) & BIT_MASK_HI5Q_TXBD_DESA)
+
+/* 2 REG_HI6Q_TXBD_DESA (Offset 0x0370) */
+
+#define BIT_SHIFT_HI6Q_TXBD_DESA 0
+#define BIT_MASK_HI6Q_TXBD_DESA 0xffffffffffffffffL
+#define BIT_HI6Q_TXBD_DESA(x) \
+ (((x) & BIT_MASK_HI6Q_TXBD_DESA) << BIT_SHIFT_HI6Q_TXBD_DESA)
+#define BIT_GET_HI6Q_TXBD_DESA(x) \
+ (((x) >> BIT_SHIFT_HI6Q_TXBD_DESA) & BIT_MASK_HI6Q_TXBD_DESA)
+
+/* 2 REG_HI7Q_TXBD_DESA (Offset 0x0378) */
+
+#define BIT_SHIFT_HI7Q_TXBD_DESA 0
+#define BIT_MASK_HI7Q_TXBD_DESA 0xffffffffffffffffL
+#define BIT_HI7Q_TXBD_DESA(x) \
+ (((x) & BIT_MASK_HI7Q_TXBD_DESA) << BIT_SHIFT_HI7Q_TXBD_DESA)
+#define BIT_GET_HI7Q_TXBD_DESA(x) \
+ (((x) >> BIT_SHIFT_HI7Q_TXBD_DESA) & BIT_MASK_HI7Q_TXBD_DESA)
+
+/* 2 REG_MGQ_TXBD_NUM (Offset 0x0380) */
+
+#define BIT_PCIE_MGQ_FLAG BIT(14)
+
+/* 2 REG_MGQ_TXBD_NUM (Offset 0x0380) */
+
+#define BIT_SHIFT_MGQ_DESC_MODE 12
+#define BIT_MASK_MGQ_DESC_MODE 0x3
+#define BIT_MGQ_DESC_MODE(x) \
+ (((x) & BIT_MASK_MGQ_DESC_MODE) << BIT_SHIFT_MGQ_DESC_MODE)
+#define BIT_GET_MGQ_DESC_MODE(x) \
+ (((x) >> BIT_SHIFT_MGQ_DESC_MODE) & BIT_MASK_MGQ_DESC_MODE)
+
+#define BIT_SHIFT_MGQ_DESC_NUM 0
+#define BIT_MASK_MGQ_DESC_NUM 0xfff
+#define BIT_MGQ_DESC_NUM(x) \
+ (((x) & BIT_MASK_MGQ_DESC_NUM) << BIT_SHIFT_MGQ_DESC_NUM)
+#define BIT_GET_MGQ_DESC_NUM(x) \
+ (((x) >> BIT_SHIFT_MGQ_DESC_NUM) & BIT_MASK_MGQ_DESC_NUM)
+
+/* 2 REG_RX_RXBD_NUM (Offset 0x0382) */
+
+#define BIT_SYS_32_64 BIT(15)
+
+#define BIT_SHIFT_BCNQ_DESC_MODE 13
+#define BIT_MASK_BCNQ_DESC_MODE 0x3
+#define BIT_BCNQ_DESC_MODE(x) \
+ (((x) & BIT_MASK_BCNQ_DESC_MODE) << BIT_SHIFT_BCNQ_DESC_MODE)
+#define BIT_GET_BCNQ_DESC_MODE(x) \
+ (((x) >> BIT_SHIFT_BCNQ_DESC_MODE) & BIT_MASK_BCNQ_DESC_MODE)
+
+/* 2 REG_RX_RXBD_NUM (Offset 0x0382) */
+
+#define BIT_PCIE_BCNQ_FLAG BIT(12)
+
+/* 2 REG_RX_RXBD_NUM (Offset 0x0382) */
+
+#define BIT_SHIFT_RXQ_DESC_NUM 0
+#define BIT_MASK_RXQ_DESC_NUM 0xfff
+#define BIT_RXQ_DESC_NUM(x) \
+ (((x) & BIT_MASK_RXQ_DESC_NUM) << BIT_SHIFT_RXQ_DESC_NUM)
+#define BIT_GET_RXQ_DESC_NUM(x) \
+ (((x) >> BIT_SHIFT_RXQ_DESC_NUM) & BIT_MASK_RXQ_DESC_NUM)
+
+/* 2 REG_VOQ_TXBD_NUM (Offset 0x0384) */
+
+#define BIT_PCIE_VOQ_FLAG BIT(14)
+
+/* 2 REG_VOQ_TXBD_NUM (Offset 0x0384) */
+
+#define BIT_SHIFT_VOQ_DESC_MODE 12
+#define BIT_MASK_VOQ_DESC_MODE 0x3
+#define BIT_VOQ_DESC_MODE(x) \
+ (((x) & BIT_MASK_VOQ_DESC_MODE) << BIT_SHIFT_VOQ_DESC_MODE)
+#define BIT_GET_VOQ_DESC_MODE(x) \
+ (((x) >> BIT_SHIFT_VOQ_DESC_MODE) & BIT_MASK_VOQ_DESC_MODE)
+
+#define BIT_SHIFT_VOQ_DESC_NUM 0
+#define BIT_MASK_VOQ_DESC_NUM 0xfff
+#define BIT_VOQ_DESC_NUM(x) \
+ (((x) & BIT_MASK_VOQ_DESC_NUM) << BIT_SHIFT_VOQ_DESC_NUM)
+#define BIT_GET_VOQ_DESC_NUM(x) \
+ (((x) >> BIT_SHIFT_VOQ_DESC_NUM) & BIT_MASK_VOQ_DESC_NUM)
+
+/* 2 REG_VIQ_TXBD_NUM (Offset 0x0386) */
+
+#define BIT_PCIE_VIQ_FLAG BIT(14)
+
+/* 2 REG_VIQ_TXBD_NUM (Offset 0x0386) */
+
+#define BIT_SHIFT_VIQ_DESC_MODE 12
+#define BIT_MASK_VIQ_DESC_MODE 0x3
+#define BIT_VIQ_DESC_MODE(x) \
+ (((x) & BIT_MASK_VIQ_DESC_MODE) << BIT_SHIFT_VIQ_DESC_MODE)
+#define BIT_GET_VIQ_DESC_MODE(x) \
+ (((x) >> BIT_SHIFT_VIQ_DESC_MODE) & BIT_MASK_VIQ_DESC_MODE)
+
+#define BIT_SHIFT_VIQ_DESC_NUM 0
+#define BIT_MASK_VIQ_DESC_NUM 0xfff
+#define BIT_VIQ_DESC_NUM(x) \
+ (((x) & BIT_MASK_VIQ_DESC_NUM) << BIT_SHIFT_VIQ_DESC_NUM)
+#define BIT_GET_VIQ_DESC_NUM(x) \
+ (((x) >> BIT_SHIFT_VIQ_DESC_NUM) & BIT_MASK_VIQ_DESC_NUM)
+
+/* 2 REG_BEQ_TXBD_NUM (Offset 0x0388) */
+
+#define BIT_PCIE_BEQ_FLAG BIT(14)
+
+/* 2 REG_BEQ_TXBD_NUM (Offset 0x0388) */
+
+#define BIT_SHIFT_BEQ_DESC_MODE 12
+#define BIT_MASK_BEQ_DESC_MODE 0x3
+#define BIT_BEQ_DESC_MODE(x) \
+ (((x) & BIT_MASK_BEQ_DESC_MODE) << BIT_SHIFT_BEQ_DESC_MODE)
+#define BIT_GET_BEQ_DESC_MODE(x) \
+ (((x) >> BIT_SHIFT_BEQ_DESC_MODE) & BIT_MASK_BEQ_DESC_MODE)
+
+#define BIT_SHIFT_BEQ_DESC_NUM 0
+#define BIT_MASK_BEQ_DESC_NUM 0xfff
+#define BIT_BEQ_DESC_NUM(x) \
+ (((x) & BIT_MASK_BEQ_DESC_NUM) << BIT_SHIFT_BEQ_DESC_NUM)
+#define BIT_GET_BEQ_DESC_NUM(x) \
+ (((x) >> BIT_SHIFT_BEQ_DESC_NUM) & BIT_MASK_BEQ_DESC_NUM)
+
+/* 2 REG_BKQ_TXBD_NUM (Offset 0x038A) */
+
+#define BIT_PCIE_BKQ_FLAG BIT(14)
+
+/* 2 REG_BKQ_TXBD_NUM (Offset 0x038A) */
+
+#define BIT_SHIFT_BKQ_DESC_MODE 12
+#define BIT_MASK_BKQ_DESC_MODE 0x3
+#define BIT_BKQ_DESC_MODE(x) \
+ (((x) & BIT_MASK_BKQ_DESC_MODE) << BIT_SHIFT_BKQ_DESC_MODE)
+#define BIT_GET_BKQ_DESC_MODE(x) \
+ (((x) >> BIT_SHIFT_BKQ_DESC_MODE) & BIT_MASK_BKQ_DESC_MODE)
+
+#define BIT_SHIFT_BKQ_DESC_NUM 0
+#define BIT_MASK_BKQ_DESC_NUM 0xfff
+#define BIT_BKQ_DESC_NUM(x) \
+ (((x) & BIT_MASK_BKQ_DESC_NUM) << BIT_SHIFT_BKQ_DESC_NUM)
+#define BIT_GET_BKQ_DESC_NUM(x) \
+ (((x) >> BIT_SHIFT_BKQ_DESC_NUM) & BIT_MASK_BKQ_DESC_NUM)
+
+/* 2 REG_HI0Q_TXBD_NUM (Offset 0x038C) */
+
+#define BIT_HI0Q_FLAG BIT(14)
+
+#define BIT_SHIFT_HI0Q_DESC_MODE 12
+#define BIT_MASK_HI0Q_DESC_MODE 0x3
+#define BIT_HI0Q_DESC_MODE(x) \
+ (((x) & BIT_MASK_HI0Q_DESC_MODE) << BIT_SHIFT_HI0Q_DESC_MODE)
+#define BIT_GET_HI0Q_DESC_MODE(x) \
+ (((x) >> BIT_SHIFT_HI0Q_DESC_MODE) & BIT_MASK_HI0Q_DESC_MODE)
+
+#define BIT_SHIFT_HI0Q_DESC_NUM 0
+#define BIT_MASK_HI0Q_DESC_NUM 0xfff
+#define BIT_HI0Q_DESC_NUM(x) \
+ (((x) & BIT_MASK_HI0Q_DESC_NUM) << BIT_SHIFT_HI0Q_DESC_NUM)
+#define BIT_GET_HI0Q_DESC_NUM(x) \
+ (((x) >> BIT_SHIFT_HI0Q_DESC_NUM) & BIT_MASK_HI0Q_DESC_NUM)
+
+/* 2 REG_HI1Q_TXBD_NUM (Offset 0x038E) */
+
+#define BIT_HI1Q_FLAG BIT(14)
+
+#define BIT_SHIFT_HI1Q_DESC_MODE 12
+#define BIT_MASK_HI1Q_DESC_MODE 0x3
+#define BIT_HI1Q_DESC_MODE(x) \
+ (((x) & BIT_MASK_HI1Q_DESC_MODE) << BIT_SHIFT_HI1Q_DESC_MODE)
+#define BIT_GET_HI1Q_DESC_MODE(x) \
+ (((x) >> BIT_SHIFT_HI1Q_DESC_MODE) & BIT_MASK_HI1Q_DESC_MODE)
+
+#define BIT_SHIFT_HI1Q_DESC_NUM 0
+#define BIT_MASK_HI1Q_DESC_NUM 0xfff
+#define BIT_HI1Q_DESC_NUM(x) \
+ (((x) & BIT_MASK_HI1Q_DESC_NUM) << BIT_SHIFT_HI1Q_DESC_NUM)
+#define BIT_GET_HI1Q_DESC_NUM(x) \
+ (((x) >> BIT_SHIFT_HI1Q_DESC_NUM) & BIT_MASK_HI1Q_DESC_NUM)
+
+/* 2 REG_HI2Q_TXBD_NUM (Offset 0x0390) */
+
+#define BIT_HI2Q_FLAG BIT(14)
+
+#define BIT_SHIFT_HI2Q_DESC_MODE 12
+#define BIT_MASK_HI2Q_DESC_MODE 0x3
+#define BIT_HI2Q_DESC_MODE(x) \
+ (((x) & BIT_MASK_HI2Q_DESC_MODE) << BIT_SHIFT_HI2Q_DESC_MODE)
+#define BIT_GET_HI2Q_DESC_MODE(x) \
+ (((x) >> BIT_SHIFT_HI2Q_DESC_MODE) & BIT_MASK_HI2Q_DESC_MODE)
+
+#define BIT_SHIFT_HI2Q_DESC_NUM 0
+#define BIT_MASK_HI2Q_DESC_NUM 0xfff
+#define BIT_HI2Q_DESC_NUM(x) \
+ (((x) & BIT_MASK_HI2Q_DESC_NUM) << BIT_SHIFT_HI2Q_DESC_NUM)
+#define BIT_GET_HI2Q_DESC_NUM(x) \
+ (((x) >> BIT_SHIFT_HI2Q_DESC_NUM) & BIT_MASK_HI2Q_DESC_NUM)
+
+/* 2 REG_HI3Q_TXBD_NUM (Offset 0x0392) */
+
+#define BIT_HI3Q_FLAG BIT(14)
+
+#define BIT_SHIFT_HI3Q_DESC_MODE 12
+#define BIT_MASK_HI3Q_DESC_MODE 0x3
+#define BIT_HI3Q_DESC_MODE(x) \
+ (((x) & BIT_MASK_HI3Q_DESC_MODE) << BIT_SHIFT_HI3Q_DESC_MODE)
+#define BIT_GET_HI3Q_DESC_MODE(x) \
+ (((x) >> BIT_SHIFT_HI3Q_DESC_MODE) & BIT_MASK_HI3Q_DESC_MODE)
+
+#define BIT_SHIFT_HI3Q_DESC_NUM 0
+#define BIT_MASK_HI3Q_DESC_NUM 0xfff
+#define BIT_HI3Q_DESC_NUM(x) \
+ (((x) & BIT_MASK_HI3Q_DESC_NUM) << BIT_SHIFT_HI3Q_DESC_NUM)
+#define BIT_GET_HI3Q_DESC_NUM(x) \
+ (((x) >> BIT_SHIFT_HI3Q_DESC_NUM) & BIT_MASK_HI3Q_DESC_NUM)
+
+/* 2 REG_HI4Q_TXBD_NUM (Offset 0x0394) */
+
+#define BIT_HI4Q_FLAG BIT(14)
+
+#define BIT_SHIFT_HI4Q_DESC_MODE 12
+#define BIT_MASK_HI4Q_DESC_MODE 0x3
+#define BIT_HI4Q_DESC_MODE(x) \
+ (((x) & BIT_MASK_HI4Q_DESC_MODE) << BIT_SHIFT_HI4Q_DESC_MODE)
+#define BIT_GET_HI4Q_DESC_MODE(x) \
+ (((x) >> BIT_SHIFT_HI4Q_DESC_MODE) & BIT_MASK_HI4Q_DESC_MODE)
+
+#define BIT_SHIFT_HI4Q_DESC_NUM 0
+#define BIT_MASK_HI4Q_DESC_NUM 0xfff
+#define BIT_HI4Q_DESC_NUM(x) \
+ (((x) & BIT_MASK_HI4Q_DESC_NUM) << BIT_SHIFT_HI4Q_DESC_NUM)
+#define BIT_GET_HI4Q_DESC_NUM(x) \
+ (((x) >> BIT_SHIFT_HI4Q_DESC_NUM) & BIT_MASK_HI4Q_DESC_NUM)
+
+/* 2 REG_HI5Q_TXBD_NUM (Offset 0x0396) */
+
+#define BIT_HI5Q_FLAG BIT(14)
+
+#define BIT_SHIFT_HI5Q_DESC_MODE 12
+#define BIT_MASK_HI5Q_DESC_MODE 0x3
+#define BIT_HI5Q_DESC_MODE(x) \
+ (((x) & BIT_MASK_HI5Q_DESC_MODE) << BIT_SHIFT_HI5Q_DESC_MODE)
+#define BIT_GET_HI5Q_DESC_MODE(x) \
+ (((x) >> BIT_SHIFT_HI5Q_DESC_MODE) & BIT_MASK_HI5Q_DESC_MODE)
+
+#define BIT_SHIFT_HI5Q_DESC_NUM 0
+#define BIT_MASK_HI5Q_DESC_NUM 0xfff
+#define BIT_HI5Q_DESC_NUM(x) \
+ (((x) & BIT_MASK_HI5Q_DESC_NUM) << BIT_SHIFT_HI5Q_DESC_NUM)
+#define BIT_GET_HI5Q_DESC_NUM(x) \
+ (((x) >> BIT_SHIFT_HI5Q_DESC_NUM) & BIT_MASK_HI5Q_DESC_NUM)
+
+/* 2 REG_HI6Q_TXBD_NUM (Offset 0x0398) */
+
+#define BIT_HI6Q_FLAG BIT(14)
+
+#define BIT_SHIFT_HI6Q_DESC_MODE 12
+#define BIT_MASK_HI6Q_DESC_MODE 0x3
+#define BIT_HI6Q_DESC_MODE(x) \
+ (((x) & BIT_MASK_HI6Q_DESC_MODE) << BIT_SHIFT_HI6Q_DESC_MODE)
+#define BIT_GET_HI6Q_DESC_MODE(x) \
+ (((x) >> BIT_SHIFT_HI6Q_DESC_MODE) & BIT_MASK_HI6Q_DESC_MODE)
+
+#define BIT_SHIFT_HI6Q_DESC_NUM 0
+#define BIT_MASK_HI6Q_DESC_NUM 0xfff
+#define BIT_HI6Q_DESC_NUM(x) \
+ (((x) & BIT_MASK_HI6Q_DESC_NUM) << BIT_SHIFT_HI6Q_DESC_NUM)
+#define BIT_GET_HI6Q_DESC_NUM(x) \
+ (((x) >> BIT_SHIFT_HI6Q_DESC_NUM) & BIT_MASK_HI6Q_DESC_NUM)
+
+/* 2 REG_HI7Q_TXBD_NUM (Offset 0x039A) */
+
+#define BIT_HI7Q_FLAG BIT(14)
+
+#define BIT_SHIFT_HI7Q_DESC_MODE 12
+#define BIT_MASK_HI7Q_DESC_MODE 0x3
+#define BIT_HI7Q_DESC_MODE(x) \
+ (((x) & BIT_MASK_HI7Q_DESC_MODE) << BIT_SHIFT_HI7Q_DESC_MODE)
+#define BIT_GET_HI7Q_DESC_MODE(x) \
+ (((x) >> BIT_SHIFT_HI7Q_DESC_MODE) & BIT_MASK_HI7Q_DESC_MODE)
+
+#define BIT_SHIFT_HI7Q_DESC_NUM 0
+#define BIT_MASK_HI7Q_DESC_NUM 0xfff
+#define BIT_HI7Q_DESC_NUM(x) \
+ (((x) & BIT_MASK_HI7Q_DESC_NUM) << BIT_SHIFT_HI7Q_DESC_NUM)
+#define BIT_GET_HI7Q_DESC_NUM(x) \
+ (((x) >> BIT_SHIFT_HI7Q_DESC_NUM) & BIT_MASK_HI7Q_DESC_NUM)
+
+/* 2 REG_BD_RWPTR_CLR (Offset 0x039C) */
+
+#define BIT_CLR_HI7Q_HW_IDX BIT(29)
+#define BIT_CLR_HI6Q_HW_IDX BIT(28)
+#define BIT_CLR_HI5Q_HW_IDX BIT(27)
+#define BIT_CLR_HI4Q_HW_IDX BIT(26)
+#define BIT_CLR_HI3Q_HW_IDX BIT(25)
+#define BIT_CLR_HI2Q_HW_IDX BIT(24)
+#define BIT_CLR_HI1Q_HW_IDX BIT(23)
+
+/* 2 REG_BD_RWPTR_CLR (Offset 0x039C) */
+
+#define BIT_CLR_HI0Q_HW_IDX BIT(22)
+
+/* 2 REG_BD_RWPTR_CLR (Offset 0x039C) */
+
+#define BIT_CLR_BKQ_HW_IDX BIT(21)
+
+/* 2 REG_BD_RWPTR_CLR (Offset 0x039C) */
+
+#define BIT_CLR_BEQ_HW_IDX BIT(20)
+
+/* 2 REG_BD_RWPTR_CLR (Offset 0x039C) */
+
+#define BIT_CLR_VIQ_HW_IDX BIT(19)
+
+/* 2 REG_BD_RWPTR_CLR (Offset 0x039C) */
+
+#define BIT_CLR_VOQ_HW_IDX BIT(18)
+
+/* 2 REG_BD_RWPTR_CLR (Offset 0x039C) */
+
+#define BIT_CLR_MGQ_HW_IDX BIT(17)
+
+/* 2 REG_TSFTIMER_HCI (Offset 0x039C) */
+
+#define BIT_SHIFT_TSFT2_HCI 16
+#define BIT_MASK_TSFT2_HCI 0xffff
+#define BIT_TSFT2_HCI(x) (((x) & BIT_MASK_TSFT2_HCI) << BIT_SHIFT_TSFT2_HCI)
+#define BIT_GET_TSFT2_HCI(x) (((x) >> BIT_SHIFT_TSFT2_HCI) & BIT_MASK_TSFT2_HCI)
+
+#define BIT_CLR_RXQ_HW_IDX BIT(16)
+
+/* 2 REG_BD_RWPTR_CLR (Offset 0x039C) */
+
+#define BIT_CLR_HI7Q_HOST_IDX BIT(13)
+
+/* 2 REG_BD_RWPTR_CLR (Offset 0x039C) */
+
+#define BIT_CLR_HI6Q_HOST_IDX BIT(12)
+
+/* 2 REG_BD_RWPTR_CLR (Offset 0x039C) */
+
+#define BIT_CLR_HI5Q_HOST_IDX BIT(11)
+
+/* 2 REG_BD_RWPTR_CLR (Offset 0x039C) */
+
+#define BIT_CLR_HI4Q_HOST_IDX BIT(10)
+
+/* 2 REG_BD_RWPTR_CLR (Offset 0x039C) */
+
+#define BIT_CLR_HI3Q_HOST_IDX BIT(9)
+
+/* 2 REG_BD_RWPTR_CLR (Offset 0x039C) */
+
+#define BIT_CLR_HI2Q_HOST_IDX BIT(8)
+
+/* 2 REG_BD_RWPTR_CLR (Offset 0x039C) */
+
+#define BIT_CLR_HI1Q_HOST_IDX BIT(7)
+#define BIT_CLR_HI0Q_HOST_IDX BIT(6)
+
+/* 2 REG_BD_RWPTR_CLR (Offset 0x039C) */
+
+#define BIT_CLR_BKQ_HOST_IDX BIT(5)
+
+/* 2 REG_BD_RWPTR_CLR (Offset 0x039C) */
+
+#define BIT_CLR_BEQ_HOST_IDX BIT(4)
+
+/* 2 REG_BD_RWPTR_CLR (Offset 0x039C) */
+
+#define BIT_CLR_VIQ_HOST_IDX BIT(3)
+
+/* 2 REG_BD_RWPTR_CLR (Offset 0x039C) */
+
+#define BIT_CLR_VOQ_HOST_IDX BIT(2)
+
+/* 2 REG_BD_RWPTR_CLR (Offset 0x039C) */
+
+#define BIT_CLR_MGQ_HOST_IDX BIT(1)
+
+/* 2 REG_TSFTIMER_HCI (Offset 0x039C) */
+
+#define BIT_SHIFT_TSFT1_HCI 0
+#define BIT_MASK_TSFT1_HCI 0xffff
+#define BIT_TSFT1_HCI(x) (((x) & BIT_MASK_TSFT1_HCI) << BIT_SHIFT_TSFT1_HCI)
+#define BIT_GET_TSFT1_HCI(x) (((x) >> BIT_SHIFT_TSFT1_HCI) & BIT_MASK_TSFT1_HCI)
+
+#define BIT_CLR_RXQ_HOST_IDX BIT(0)
+
+/* 2 REG_VOQ_TXBD_IDX (Offset 0x03A0) */
+
+#define BIT_SHIFT_VOQ_HW_IDX 16
+#define BIT_MASK_VOQ_HW_IDX 0xfff
+#define BIT_VOQ_HW_IDX(x) (((x) & BIT_MASK_VOQ_HW_IDX) << BIT_SHIFT_VOQ_HW_IDX)
+#define BIT_GET_VOQ_HW_IDX(x) \
+ (((x) >> BIT_SHIFT_VOQ_HW_IDX) & BIT_MASK_VOQ_HW_IDX)
+
+#define BIT_SHIFT_VOQ_HOST_IDX 0
+#define BIT_MASK_VOQ_HOST_IDX 0xfff
+#define BIT_VOQ_HOST_IDX(x) \
+ (((x) & BIT_MASK_VOQ_HOST_IDX) << BIT_SHIFT_VOQ_HOST_IDX)
+#define BIT_GET_VOQ_HOST_IDX(x) \
+ (((x) >> BIT_SHIFT_VOQ_HOST_IDX) & BIT_MASK_VOQ_HOST_IDX)
+
+/* 2 REG_VIQ_TXBD_IDX (Offset 0x03A4) */
+
+#define BIT_SHIFT_VIQ_HW_IDX 16
+#define BIT_MASK_VIQ_HW_IDX 0xfff
+#define BIT_VIQ_HW_IDX(x) (((x) & BIT_MASK_VIQ_HW_IDX) << BIT_SHIFT_VIQ_HW_IDX)
+#define BIT_GET_VIQ_HW_IDX(x) \
+ (((x) >> BIT_SHIFT_VIQ_HW_IDX) & BIT_MASK_VIQ_HW_IDX)
+
+#define BIT_SHIFT_VIQ_HOST_IDX 0
+#define BIT_MASK_VIQ_HOST_IDX 0xfff
+#define BIT_VIQ_HOST_IDX(x) \
+ (((x) & BIT_MASK_VIQ_HOST_IDX) << BIT_SHIFT_VIQ_HOST_IDX)
+#define BIT_GET_VIQ_HOST_IDX(x) \
+ (((x) >> BIT_SHIFT_VIQ_HOST_IDX) & BIT_MASK_VIQ_HOST_IDX)
+
+/* 2 REG_BEQ_TXBD_IDX (Offset 0x03A8) */
+
+#define BIT_SHIFT_BEQ_HW_IDX 16
+#define BIT_MASK_BEQ_HW_IDX 0xfff
+#define BIT_BEQ_HW_IDX(x) (((x) & BIT_MASK_BEQ_HW_IDX) << BIT_SHIFT_BEQ_HW_IDX)
+#define BIT_GET_BEQ_HW_IDX(x) \
+ (((x) >> BIT_SHIFT_BEQ_HW_IDX) & BIT_MASK_BEQ_HW_IDX)
+
+#define BIT_SHIFT_BEQ_HOST_IDX 0
+#define BIT_MASK_BEQ_HOST_IDX 0xfff
+#define BIT_BEQ_HOST_IDX(x) \
+ (((x) & BIT_MASK_BEQ_HOST_IDX) << BIT_SHIFT_BEQ_HOST_IDX)
+#define BIT_GET_BEQ_HOST_IDX(x) \
+ (((x) >> BIT_SHIFT_BEQ_HOST_IDX) & BIT_MASK_BEQ_HOST_IDX)
+
+/* 2 REG_BKQ_TXBD_IDX (Offset 0x03AC) */
+
+#define BIT_SHIFT_BKQ_HW_IDX 16
+#define BIT_MASK_BKQ_HW_IDX 0xfff
+#define BIT_BKQ_HW_IDX(x) (((x) & BIT_MASK_BKQ_HW_IDX) << BIT_SHIFT_BKQ_HW_IDX)
+#define BIT_GET_BKQ_HW_IDX(x) \
+ (((x) >> BIT_SHIFT_BKQ_HW_IDX) & BIT_MASK_BKQ_HW_IDX)
+
+#define BIT_SHIFT_BKQ_HOST_IDX 0
+#define BIT_MASK_BKQ_HOST_IDX 0xfff
+#define BIT_BKQ_HOST_IDX(x) \
+ (((x) & BIT_MASK_BKQ_HOST_IDX) << BIT_SHIFT_BKQ_HOST_IDX)
+#define BIT_GET_BKQ_HOST_IDX(x) \
+ (((x) >> BIT_SHIFT_BKQ_HOST_IDX) & BIT_MASK_BKQ_HOST_IDX)
+
+/* 2 REG_MGQ_TXBD_IDX (Offset 0x03B0) */
+
+#define BIT_SHIFT_MGQ_HW_IDX 16
+#define BIT_MASK_MGQ_HW_IDX 0xfff
+#define BIT_MGQ_HW_IDX(x) (((x) & BIT_MASK_MGQ_HW_IDX) << BIT_SHIFT_MGQ_HW_IDX)
+#define BIT_GET_MGQ_HW_IDX(x) \
+ (((x) >> BIT_SHIFT_MGQ_HW_IDX) & BIT_MASK_MGQ_HW_IDX)
+
+#define BIT_SHIFT_MGQ_HOST_IDX 0
+#define BIT_MASK_MGQ_HOST_IDX 0xfff
+#define BIT_MGQ_HOST_IDX(x) \
+ (((x) & BIT_MASK_MGQ_HOST_IDX) << BIT_SHIFT_MGQ_HOST_IDX)
+#define BIT_GET_MGQ_HOST_IDX(x) \
+ (((x) >> BIT_SHIFT_MGQ_HOST_IDX) & BIT_MASK_MGQ_HOST_IDX)
+
+/* 2 REG_RXQ_RXBD_IDX (Offset 0x03B4) */
+
+#define BIT_SHIFT_RXQ_HW_IDX 16
+#define BIT_MASK_RXQ_HW_IDX 0xfff
+#define BIT_RXQ_HW_IDX(x) (((x) & BIT_MASK_RXQ_HW_IDX) << BIT_SHIFT_RXQ_HW_IDX)
+#define BIT_GET_RXQ_HW_IDX(x) \
+ (((x) >> BIT_SHIFT_RXQ_HW_IDX) & BIT_MASK_RXQ_HW_IDX)
+
+#define BIT_SHIFT_RXQ_HOST_IDX 0
+#define BIT_MASK_RXQ_HOST_IDX 0xfff
+#define BIT_RXQ_HOST_IDX(x) \
+ (((x) & BIT_MASK_RXQ_HOST_IDX) << BIT_SHIFT_RXQ_HOST_IDX)
+#define BIT_GET_RXQ_HOST_IDX(x) \
+ (((x) >> BIT_SHIFT_RXQ_HOST_IDX) & BIT_MASK_RXQ_HOST_IDX)
+
+/* 2 REG_HI0Q_TXBD_IDX (Offset 0x03B8) */
+
+#define BIT_SHIFT_HI0Q_HW_IDX 16
+#define BIT_MASK_HI0Q_HW_IDX 0xfff
+#define BIT_HI0Q_HW_IDX(x) \
+ (((x) & BIT_MASK_HI0Q_HW_IDX) << BIT_SHIFT_HI0Q_HW_IDX)
+#define BIT_GET_HI0Q_HW_IDX(x) \
+ (((x) >> BIT_SHIFT_HI0Q_HW_IDX) & BIT_MASK_HI0Q_HW_IDX)
+
+#define BIT_SHIFT_HI0Q_HOST_IDX 0
+#define BIT_MASK_HI0Q_HOST_IDX 0xfff
+#define BIT_HI0Q_HOST_IDX(x) \
+ (((x) & BIT_MASK_HI0Q_HOST_IDX) << BIT_SHIFT_HI0Q_HOST_IDX)
+#define BIT_GET_HI0Q_HOST_IDX(x) \
+ (((x) >> BIT_SHIFT_HI0Q_HOST_IDX) & BIT_MASK_HI0Q_HOST_IDX)
+
+/* 2 REG_HI1Q_TXBD_IDX (Offset 0x03BC) */
+
+#define BIT_SHIFT_HI1Q_HW_IDX 16
+#define BIT_MASK_HI1Q_HW_IDX 0xfff
+#define BIT_HI1Q_HW_IDX(x) \
+ (((x) & BIT_MASK_HI1Q_HW_IDX) << BIT_SHIFT_HI1Q_HW_IDX)
+#define BIT_GET_HI1Q_HW_IDX(x) \
+ (((x) >> BIT_SHIFT_HI1Q_HW_IDX) & BIT_MASK_HI1Q_HW_IDX)
+
+#define BIT_SHIFT_HI1Q_HOST_IDX 0
+#define BIT_MASK_HI1Q_HOST_IDX 0xfff
+#define BIT_HI1Q_HOST_IDX(x) \
+ (((x) & BIT_MASK_HI1Q_HOST_IDX) << BIT_SHIFT_HI1Q_HOST_IDX)
+#define BIT_GET_HI1Q_HOST_IDX(x) \
+ (((x) >> BIT_SHIFT_HI1Q_HOST_IDX) & BIT_MASK_HI1Q_HOST_IDX)
+
+/* 2 REG_HI2Q_TXBD_IDX (Offset 0x03C0) */
+
+#define BIT_SHIFT_HI2Q_HW_IDX 16
+#define BIT_MASK_HI2Q_HW_IDX 0xfff
+#define BIT_HI2Q_HW_IDX(x) \
+ (((x) & BIT_MASK_HI2Q_HW_IDX) << BIT_SHIFT_HI2Q_HW_IDX)
+#define BIT_GET_HI2Q_HW_IDX(x) \
+ (((x) >> BIT_SHIFT_HI2Q_HW_IDX) & BIT_MASK_HI2Q_HW_IDX)
+
+#define BIT_SHIFT_HI2Q_HOST_IDX 0
+#define BIT_MASK_HI2Q_HOST_IDX 0xfff
+#define BIT_HI2Q_HOST_IDX(x) \
+ (((x) & BIT_MASK_HI2Q_HOST_IDX) << BIT_SHIFT_HI2Q_HOST_IDX)
+#define BIT_GET_HI2Q_HOST_IDX(x) \
+ (((x) >> BIT_SHIFT_HI2Q_HOST_IDX) & BIT_MASK_HI2Q_HOST_IDX)
+
+/* 2 REG_HI3Q_TXBD_IDX (Offset 0x03C4) */
+
+#define BIT_SHIFT_HI3Q_HW_IDX 16
+#define BIT_MASK_HI3Q_HW_IDX 0xfff
+#define BIT_HI3Q_HW_IDX(x) \
+ (((x) & BIT_MASK_HI3Q_HW_IDX) << BIT_SHIFT_HI3Q_HW_IDX)
+#define BIT_GET_HI3Q_HW_IDX(x) \
+ (((x) >> BIT_SHIFT_HI3Q_HW_IDX) & BIT_MASK_HI3Q_HW_IDX)
+
+#define BIT_SHIFT_HI3Q_HOST_IDX 0
+#define BIT_MASK_HI3Q_HOST_IDX 0xfff
+#define BIT_HI3Q_HOST_IDX(x) \
+ (((x) & BIT_MASK_HI3Q_HOST_IDX) << BIT_SHIFT_HI3Q_HOST_IDX)
+#define BIT_GET_HI3Q_HOST_IDX(x) \
+ (((x) >> BIT_SHIFT_HI3Q_HOST_IDX) & BIT_MASK_HI3Q_HOST_IDX)
+
+/* 2 REG_HI4Q_TXBD_IDX (Offset 0x03C8) */
+
+#define BIT_SHIFT_HI4Q_HW_IDX 16
+#define BIT_MASK_HI4Q_HW_IDX 0xfff
+#define BIT_HI4Q_HW_IDX(x) \
+ (((x) & BIT_MASK_HI4Q_HW_IDX) << BIT_SHIFT_HI4Q_HW_IDX)
+#define BIT_GET_HI4Q_HW_IDX(x) \
+ (((x) >> BIT_SHIFT_HI4Q_HW_IDX) & BIT_MASK_HI4Q_HW_IDX)
+
+#define BIT_SHIFT_HI4Q_HOST_IDX 0
+#define BIT_MASK_HI4Q_HOST_IDX 0xfff
+#define BIT_HI4Q_HOST_IDX(x) \
+ (((x) & BIT_MASK_HI4Q_HOST_IDX) << BIT_SHIFT_HI4Q_HOST_IDX)
+#define BIT_GET_HI4Q_HOST_IDX(x) \
+ (((x) >> BIT_SHIFT_HI4Q_HOST_IDX) & BIT_MASK_HI4Q_HOST_IDX)
+
+/* 2 REG_HI5Q_TXBD_IDX (Offset 0x03CC) */
+
+#define BIT_SHIFT_HI5Q_HW_IDX 16
+#define BIT_MASK_HI5Q_HW_IDX 0xfff
+#define BIT_HI5Q_HW_IDX(x) \
+ (((x) & BIT_MASK_HI5Q_HW_IDX) << BIT_SHIFT_HI5Q_HW_IDX)
+#define BIT_GET_HI5Q_HW_IDX(x) \
+ (((x) >> BIT_SHIFT_HI5Q_HW_IDX) & BIT_MASK_HI5Q_HW_IDX)
+
+#define BIT_SHIFT_HI5Q_HOST_IDX 0
+#define BIT_MASK_HI5Q_HOST_IDX 0xfff
+#define BIT_HI5Q_HOST_IDX(x) \
+ (((x) & BIT_MASK_HI5Q_HOST_IDX) << BIT_SHIFT_HI5Q_HOST_IDX)
+#define BIT_GET_HI5Q_HOST_IDX(x) \
+ (((x) >> BIT_SHIFT_HI5Q_HOST_IDX) & BIT_MASK_HI5Q_HOST_IDX)
+
+/* 2 REG_HI6Q_TXBD_IDX (Offset 0x03D0) */
+
+#define BIT_SHIFT_HI6Q_HW_IDX 16
+#define BIT_MASK_HI6Q_HW_IDX 0xfff
+#define BIT_HI6Q_HW_IDX(x) \
+ (((x) & BIT_MASK_HI6Q_HW_IDX) << BIT_SHIFT_HI6Q_HW_IDX)
+#define BIT_GET_HI6Q_HW_IDX(x) \
+ (((x) >> BIT_SHIFT_HI6Q_HW_IDX) & BIT_MASK_HI6Q_HW_IDX)
+
+#define BIT_SHIFT_HI6Q_HOST_IDX 0
+#define BIT_MASK_HI6Q_HOST_IDX 0xfff
+#define BIT_HI6Q_HOST_IDX(x) \
+ (((x) & BIT_MASK_HI6Q_HOST_IDX) << BIT_SHIFT_HI6Q_HOST_IDX)
+#define BIT_GET_HI6Q_HOST_IDX(x) \
+ (((x) >> BIT_SHIFT_HI6Q_HOST_IDX) & BIT_MASK_HI6Q_HOST_IDX)
+
+/* 2 REG_HI7Q_TXBD_IDX (Offset 0x03D4) */
+
+#define BIT_SHIFT_HI7Q_HW_IDX 16
+#define BIT_MASK_HI7Q_HW_IDX 0xfff
+#define BIT_HI7Q_HW_IDX(x) \
+ (((x) & BIT_MASK_HI7Q_HW_IDX) << BIT_SHIFT_HI7Q_HW_IDX)
+#define BIT_GET_HI7Q_HW_IDX(x) \
+ (((x) >> BIT_SHIFT_HI7Q_HW_IDX) & BIT_MASK_HI7Q_HW_IDX)
+
+#define BIT_SHIFT_HI7Q_HOST_IDX 0
+#define BIT_MASK_HI7Q_HOST_IDX 0xfff
+#define BIT_HI7Q_HOST_IDX(x) \
+ (((x) & BIT_MASK_HI7Q_HOST_IDX) << BIT_SHIFT_HI7Q_HOST_IDX)
+#define BIT_GET_HI7Q_HOST_IDX(x) \
+ (((x) >> BIT_SHIFT_HI7Q_HOST_IDX) & BIT_MASK_HI7Q_HOST_IDX)
+
+/* 2 REG_DBG_SEL_V1 (Offset 0x03D8) */
+
+#define BIT_DIS_TXDMA_PRE BIT(7)
+#define BIT_DIS_RXDMA_PRE BIT(6)
+#define BIT_TXFLAG_EXIT_L1_EN BIT(2)
+
+#define BIT_SHIFT_DBG_SEL 0
+#define BIT_MASK_DBG_SEL 0xff
+#define BIT_DBG_SEL(x) (((x) & BIT_MASK_DBG_SEL) << BIT_SHIFT_DBG_SEL)
+#define BIT_GET_DBG_SEL(x) (((x) >> BIT_SHIFT_DBG_SEL) & BIT_MASK_DBG_SEL)
+
+/* 2 REG_PCIE_HRPWM1_V1 (Offset 0x03D9) */
+
+#define BIT_SHIFT_PCIE_HRPWM 0
+#define BIT_MASK_PCIE_HRPWM 0xff
+#define BIT_PCIE_HRPWM(x) (((x) & BIT_MASK_PCIE_HRPWM) << BIT_SHIFT_PCIE_HRPWM)
+#define BIT_GET_PCIE_HRPWM(x) \
+ (((x) >> BIT_SHIFT_PCIE_HRPWM) & BIT_MASK_PCIE_HRPWM)
+
+/* 2 REG_PCIE_HCPWM1_V1 (Offset 0x03DA) */
+
+#define BIT_SHIFT_PCIE_HCPWM 0
+#define BIT_MASK_PCIE_HCPWM 0xff
+#define BIT_PCIE_HCPWM(x) (((x) & BIT_MASK_PCIE_HCPWM) << BIT_SHIFT_PCIE_HCPWM)
+#define BIT_GET_PCIE_HCPWM(x) \
+ (((x) >> BIT_SHIFT_PCIE_HCPWM) & BIT_MASK_PCIE_HCPWM)
+
+/* 2 REG_PCIE_CTRL2 (Offset 0x03DB) */
+
+#define BIT_SHIFT_HPS_CLKR_PCIE 4
+#define BIT_MASK_HPS_CLKR_PCIE 0x3
+#define BIT_HPS_CLKR_PCIE(x) \
+ (((x) & BIT_MASK_HPS_CLKR_PCIE) << BIT_SHIFT_HPS_CLKR_PCIE)
+#define BIT_GET_HPS_CLKR_PCIE(x) \
+ (((x) >> BIT_SHIFT_HPS_CLKR_PCIE) & BIT_MASK_HPS_CLKR_PCIE)
+
+/* 2 REG_PCIE_CTRL2 (Offset 0x03DB) */
+
+#define BIT_PCIE_INT BIT(3)
+
+/* 2 REG_PCIE_CTRL2 (Offset 0x03DB) */
+
+#define BIT_EN_RXDMA_ALIGN BIT(1)
+#define BIT_EN_TXDMA_ALIGN BIT(0)
+
+/* 2 REG_PCIE_HRPWM2_V1 (Offset 0x03DC) */
+
+#define BIT_SHIFT_PCIE_HRPWM2 0
+#define BIT_MASK_PCIE_HRPWM2 0xffff
+#define BIT_PCIE_HRPWM2(x) \
+ (((x) & BIT_MASK_PCIE_HRPWM2) << BIT_SHIFT_PCIE_HRPWM2)
+#define BIT_GET_PCIE_HRPWM2(x) \
+ (((x) >> BIT_SHIFT_PCIE_HRPWM2) & BIT_MASK_PCIE_HRPWM2)
+
+/* 2 REG_PCIE_HCPWM2_V1 (Offset 0x03DE) */
+
+#define BIT_SHIFT_PCIE_HCPWM2 0
+#define BIT_MASK_PCIE_HCPWM2 0xffff
+#define BIT_PCIE_HCPWM2(x) \
+ (((x) & BIT_MASK_PCIE_HCPWM2) << BIT_SHIFT_PCIE_HCPWM2)
+#define BIT_GET_PCIE_HCPWM2(x) \
+ (((x) >> BIT_SHIFT_PCIE_HCPWM2) & BIT_MASK_PCIE_HCPWM2)
+
+/* 2 REG_PCIE_H2C_MSG_V1 (Offset 0x03E0) */
+
+#define BIT_SHIFT_DRV2FW_INFO 0
+#define BIT_MASK_DRV2FW_INFO 0xffffffffL
+#define BIT_DRV2FW_INFO(x) \
+ (((x) & BIT_MASK_DRV2FW_INFO) << BIT_SHIFT_DRV2FW_INFO)
+#define BIT_GET_DRV2FW_INFO(x) \
+ (((x) >> BIT_SHIFT_DRV2FW_INFO) & BIT_MASK_DRV2FW_INFO)
+
+/* 2 REG_PCIE_C2H_MSG_V1 (Offset 0x03E4) */
+
+#define BIT_SHIFT_HCI_PCIE_C2H_MSG 0
+#define BIT_MASK_HCI_PCIE_C2H_MSG 0xffffffffL
+#define BIT_HCI_PCIE_C2H_MSG(x) \
+ (((x) & BIT_MASK_HCI_PCIE_C2H_MSG) << BIT_SHIFT_HCI_PCIE_C2H_MSG)
+#define BIT_GET_HCI_PCIE_C2H_MSG(x) \
+ (((x) >> BIT_SHIFT_HCI_PCIE_C2H_MSG) & BIT_MASK_HCI_PCIE_C2H_MSG)
+
+/* 2 REG_DBI_WDATA_V1 (Offset 0x03E8) */
+
+#define BIT_SHIFT_DBI_WDATA 0
+#define BIT_MASK_DBI_WDATA 0xffffffffL
+#define BIT_DBI_WDATA(x) (((x) & BIT_MASK_DBI_WDATA) << BIT_SHIFT_DBI_WDATA)
+#define BIT_GET_DBI_WDATA(x) (((x) >> BIT_SHIFT_DBI_WDATA) & BIT_MASK_DBI_WDATA)
+
+/* 2 REG_DBI_RDATA_V1 (Offset 0x03EC) */
+
+#define BIT_SHIFT_DBI_RDATA 0
+#define BIT_MASK_DBI_RDATA 0xffffffffL
+#define BIT_DBI_RDATA(x) (((x) & BIT_MASK_DBI_RDATA) << BIT_SHIFT_DBI_RDATA)
+#define BIT_GET_DBI_RDATA(x) (((x) >> BIT_SHIFT_DBI_RDATA) & BIT_MASK_DBI_RDATA)
+
+/* 2 REG_DBI_FLAG_V1 (Offset 0x03F0) */
+
+#define BIT_EN_STUCK_DBG BIT(26)
+#define BIT_RX_STUCK BIT(25)
+#define BIT_TX_STUCK BIT(24)
+#define BIT_DBI_RFLAG BIT(17)
+#define BIT_DBI_WFLAG BIT(16)
+
+#define BIT_SHIFT_DBI_WREN 12
+#define BIT_MASK_DBI_WREN 0xf
+#define BIT_DBI_WREN(x) (((x) & BIT_MASK_DBI_WREN) << BIT_SHIFT_DBI_WREN)
+#define BIT_GET_DBI_WREN(x) (((x) >> BIT_SHIFT_DBI_WREN) & BIT_MASK_DBI_WREN)
+
+#define BIT_SHIFT_DBI_ADDR 0
+#define BIT_MASK_DBI_ADDR 0xfff
+#define BIT_DBI_ADDR(x) (((x) & BIT_MASK_DBI_ADDR) << BIT_SHIFT_DBI_ADDR)
+#define BIT_GET_DBI_ADDR(x) (((x) >> BIT_SHIFT_DBI_ADDR) & BIT_MASK_DBI_ADDR)
+
+/* 2 REG_MDIO_V1 (Offset 0x03F4) */
+
+#define BIT_SHIFT_MDIO_RDATA 16
+#define BIT_MASK_MDIO_RDATA 0xffff
+#define BIT_MDIO_RDATA(x) (((x) & BIT_MASK_MDIO_RDATA) << BIT_SHIFT_MDIO_RDATA)
+#define BIT_GET_MDIO_RDATA(x) \
+ (((x) >> BIT_SHIFT_MDIO_RDATA) & BIT_MASK_MDIO_RDATA)
+
+#define BIT_SHIFT_MDIO_WDATA 0
+#define BIT_MASK_MDIO_WDATA 0xffff
+#define BIT_MDIO_WDATA(x) (((x) & BIT_MASK_MDIO_WDATA) << BIT_SHIFT_MDIO_WDATA)
+#define BIT_GET_MDIO_WDATA(x) \
+ (((x) >> BIT_SHIFT_MDIO_WDATA) & BIT_MASK_MDIO_WDATA)
+
+/* 2 REG_PCIE_MIX_CFG (Offset 0x03F8) */
+
+#define BIT_EN_WATCH_DOG BIT(8)
+
+/* 2 REG_PCIE_MIX_CFG (Offset 0x03F8) */
+
+#define BIT_SHIFT_MDIO_REG_ADDR_V1 0
+#define BIT_MASK_MDIO_REG_ADDR_V1 0x1f
+#define BIT_MDIO_REG_ADDR_V1(x) \
+ (((x) & BIT_MASK_MDIO_REG_ADDR_V1) << BIT_SHIFT_MDIO_REG_ADDR_V1)
+#define BIT_GET_MDIO_REG_ADDR_V1(x) \
+ (((x) >> BIT_SHIFT_MDIO_REG_ADDR_V1) & BIT_MASK_MDIO_REG_ADDR_V1)
+
+/* 2 REG_HCI_MIX_CFG (Offset 0x03FC) */
+
+#define BIT_HOST_GEN2_SUPPORT BIT(20)
+
+#define BIT_SHIFT_TXDMA_ERR_FLAG 16
+#define BIT_MASK_TXDMA_ERR_FLAG 0xf
+#define BIT_TXDMA_ERR_FLAG(x) \
+ (((x) & BIT_MASK_TXDMA_ERR_FLAG) << BIT_SHIFT_TXDMA_ERR_FLAG)
+#define BIT_GET_TXDMA_ERR_FLAG(x) \
+ (((x) >> BIT_SHIFT_TXDMA_ERR_FLAG) & BIT_MASK_TXDMA_ERR_FLAG)
+
+#define BIT_SHIFT_EARLY_MODE_SEL 12
+#define BIT_MASK_EARLY_MODE_SEL 0xf
+#define BIT_EARLY_MODE_SEL(x) \
+ (((x) & BIT_MASK_EARLY_MODE_SEL) << BIT_SHIFT_EARLY_MODE_SEL)
+#define BIT_GET_EARLY_MODE_SEL(x) \
+ (((x) >> BIT_SHIFT_EARLY_MODE_SEL) & BIT_MASK_EARLY_MODE_SEL)
+
+#define BIT_EPHY_RX50_EN BIT(11)
+
+#define BIT_SHIFT_MSI_TIMEOUT_ID_V1 8
+#define BIT_MASK_MSI_TIMEOUT_ID_V1 0x7
+#define BIT_MSI_TIMEOUT_ID_V1(x) \
+ (((x) & BIT_MASK_MSI_TIMEOUT_ID_V1) << BIT_SHIFT_MSI_TIMEOUT_ID_V1)
+#define BIT_GET_MSI_TIMEOUT_ID_V1(x) \
+ (((x) >> BIT_SHIFT_MSI_TIMEOUT_ID_V1) & BIT_MASK_MSI_TIMEOUT_ID_V1)
+
+#define BIT_RADDR_RD BIT(7)
+#define BIT_EN_MUL_TAG BIT(6)
+#define BIT_EN_EARLY_MODE BIT(5)
+#define BIT_L0S_LINK_OFF BIT(4)
+#define BIT_ACT_LINK_OFF BIT(3)
+
+/* 2 REG_HCI_MIX_CFG (Offset 0x03FC) */
+
+#define BIT_EN_SLOW_MAC_TX BIT(2)
+#define BIT_EN_SLOW_MAC_RX BIT(1)
+
+/* 2 REG_Q0_INFO (Offset 0x0400) */
+
+#define BIT_SHIFT_QUEUEMACID_Q0_V1 25
+#define BIT_MASK_QUEUEMACID_Q0_V1 0x7f
+#define BIT_QUEUEMACID_Q0_V1(x) \
+ (((x) & BIT_MASK_QUEUEMACID_Q0_V1) << BIT_SHIFT_QUEUEMACID_Q0_V1)
+#define BIT_GET_QUEUEMACID_Q0_V1(x) \
+ (((x) >> BIT_SHIFT_QUEUEMACID_Q0_V1) & BIT_MASK_QUEUEMACID_Q0_V1)
+
+#define BIT_SHIFT_QUEUEAC_Q0_V1 23
+#define BIT_MASK_QUEUEAC_Q0_V1 0x3
+#define BIT_QUEUEAC_Q0_V1(x) \
+ (((x) & BIT_MASK_QUEUEAC_Q0_V1) << BIT_SHIFT_QUEUEAC_Q0_V1)
+#define BIT_GET_QUEUEAC_Q0_V1(x) \
+ (((x) >> BIT_SHIFT_QUEUEAC_Q0_V1) & BIT_MASK_QUEUEAC_Q0_V1)
+
+/* 2 REG_Q0_INFO (Offset 0x0400) */
+
+#define BIT_TIDEMPTY_Q0_V1 BIT(22)
+
+/* 2 REG_Q0_INFO (Offset 0x0400) */
+
+#define BIT_SHIFT_TAIL_PKT_Q0_V2 11
+#define BIT_MASK_TAIL_PKT_Q0_V2 0x7ff
+#define BIT_TAIL_PKT_Q0_V2(x) \
+ (((x) & BIT_MASK_TAIL_PKT_Q0_V2) << BIT_SHIFT_TAIL_PKT_Q0_V2)
+#define BIT_GET_TAIL_PKT_Q0_V2(x) \
+ (((x) >> BIT_SHIFT_TAIL_PKT_Q0_V2) & BIT_MASK_TAIL_PKT_Q0_V2)
+
+/* 2 REG_Q0_INFO (Offset 0x0400) */
+
+#define BIT_SHIFT_HEAD_PKT_Q0_V1 0
+#define BIT_MASK_HEAD_PKT_Q0_V1 0x7ff
+#define BIT_HEAD_PKT_Q0_V1(x) \
+ (((x) & BIT_MASK_HEAD_PKT_Q0_V1) << BIT_SHIFT_HEAD_PKT_Q0_V1)
+#define BIT_GET_HEAD_PKT_Q0_V1(x) \
+ (((x) >> BIT_SHIFT_HEAD_PKT_Q0_V1) & BIT_MASK_HEAD_PKT_Q0_V1)
+
+/* 2 REG_Q1_INFO (Offset 0x0404) */
+
+#define BIT_SHIFT_QUEUEMACID_Q1_V1 25
+#define BIT_MASK_QUEUEMACID_Q1_V1 0x7f
+#define BIT_QUEUEMACID_Q1_V1(x) \
+ (((x) & BIT_MASK_QUEUEMACID_Q1_V1) << BIT_SHIFT_QUEUEMACID_Q1_V1)
+#define BIT_GET_QUEUEMACID_Q1_V1(x) \
+ (((x) >> BIT_SHIFT_QUEUEMACID_Q1_V1) & BIT_MASK_QUEUEMACID_Q1_V1)
+
+#define BIT_SHIFT_QUEUEAC_Q1_V1 23
+#define BIT_MASK_QUEUEAC_Q1_V1 0x3
+#define BIT_QUEUEAC_Q1_V1(x) \
+ (((x) & BIT_MASK_QUEUEAC_Q1_V1) << BIT_SHIFT_QUEUEAC_Q1_V1)
+#define BIT_GET_QUEUEAC_Q1_V1(x) \
+ (((x) >> BIT_SHIFT_QUEUEAC_Q1_V1) & BIT_MASK_QUEUEAC_Q1_V1)
+
+/* 2 REG_Q1_INFO (Offset 0x0404) */
+
+#define BIT_TIDEMPTY_Q1_V1 BIT(22)
+
+/* 2 REG_Q1_INFO (Offset 0x0404) */
+
+#define BIT_SHIFT_TAIL_PKT_Q1_V2 11
+#define BIT_MASK_TAIL_PKT_Q1_V2 0x7ff
+#define BIT_TAIL_PKT_Q1_V2(x) \
+ (((x) & BIT_MASK_TAIL_PKT_Q1_V2) << BIT_SHIFT_TAIL_PKT_Q1_V2)
+#define BIT_GET_TAIL_PKT_Q1_V2(x) \
+ (((x) >> BIT_SHIFT_TAIL_PKT_Q1_V2) & BIT_MASK_TAIL_PKT_Q1_V2)
+
+/* 2 REG_Q1_INFO (Offset 0x0404) */
+
+#define BIT_SHIFT_HEAD_PKT_Q1_V1 0
+#define BIT_MASK_HEAD_PKT_Q1_V1 0x7ff
+#define BIT_HEAD_PKT_Q1_V1(x) \
+ (((x) & BIT_MASK_HEAD_PKT_Q1_V1) << BIT_SHIFT_HEAD_PKT_Q1_V1)
+#define BIT_GET_HEAD_PKT_Q1_V1(x) \
+ (((x) >> BIT_SHIFT_HEAD_PKT_Q1_V1) & BIT_MASK_HEAD_PKT_Q1_V1)
+
+/* 2 REG_Q2_INFO (Offset 0x0408) */
+
+#define BIT_SHIFT_QUEUEMACID_Q2_V1 25
+#define BIT_MASK_QUEUEMACID_Q2_V1 0x7f
+#define BIT_QUEUEMACID_Q2_V1(x) \
+ (((x) & BIT_MASK_QUEUEMACID_Q2_V1) << BIT_SHIFT_QUEUEMACID_Q2_V1)
+#define BIT_GET_QUEUEMACID_Q2_V1(x) \
+ (((x) >> BIT_SHIFT_QUEUEMACID_Q2_V1) & BIT_MASK_QUEUEMACID_Q2_V1)
+
+#define BIT_SHIFT_QUEUEAC_Q2_V1 23
+#define BIT_MASK_QUEUEAC_Q2_V1 0x3
+#define BIT_QUEUEAC_Q2_V1(x) \
+ (((x) & BIT_MASK_QUEUEAC_Q2_V1) << BIT_SHIFT_QUEUEAC_Q2_V1)
+#define BIT_GET_QUEUEAC_Q2_V1(x) \
+ (((x) >> BIT_SHIFT_QUEUEAC_Q2_V1) & BIT_MASK_QUEUEAC_Q2_V1)
+
+/* 2 REG_Q2_INFO (Offset 0x0408) */
+
+#define BIT_TIDEMPTY_Q2_V1 BIT(22)
+
+/* 2 REG_Q2_INFO (Offset 0x0408) */
+
+#define BIT_SHIFT_TAIL_PKT_Q2_V2 11
+#define BIT_MASK_TAIL_PKT_Q2_V2 0x7ff
+#define BIT_TAIL_PKT_Q2_V2(x) \
+ (((x) & BIT_MASK_TAIL_PKT_Q2_V2) << BIT_SHIFT_TAIL_PKT_Q2_V2)
+#define BIT_GET_TAIL_PKT_Q2_V2(x) \
+ (((x) >> BIT_SHIFT_TAIL_PKT_Q2_V2) & BIT_MASK_TAIL_PKT_Q2_V2)
+
+/* 2 REG_Q2_INFO (Offset 0x0408) */
+
+#define BIT_SHIFT_HEAD_PKT_Q2_V1 0
+#define BIT_MASK_HEAD_PKT_Q2_V1 0x7ff
+#define BIT_HEAD_PKT_Q2_V1(x) \
+ (((x) & BIT_MASK_HEAD_PKT_Q2_V1) << BIT_SHIFT_HEAD_PKT_Q2_V1)
+#define BIT_GET_HEAD_PKT_Q2_V1(x) \
+ (((x) >> BIT_SHIFT_HEAD_PKT_Q2_V1) & BIT_MASK_HEAD_PKT_Q2_V1)
+
+/* 2 REG_Q3_INFO (Offset 0x040C) */
+
+#define BIT_SHIFT_QUEUEMACID_Q3_V1 25
+#define BIT_MASK_QUEUEMACID_Q3_V1 0x7f
+#define BIT_QUEUEMACID_Q3_V1(x) \
+ (((x) & BIT_MASK_QUEUEMACID_Q3_V1) << BIT_SHIFT_QUEUEMACID_Q3_V1)
+#define BIT_GET_QUEUEMACID_Q3_V1(x) \
+ (((x) >> BIT_SHIFT_QUEUEMACID_Q3_V1) & BIT_MASK_QUEUEMACID_Q3_V1)
+
+#define BIT_SHIFT_QUEUEAC_Q3_V1 23
+#define BIT_MASK_QUEUEAC_Q3_V1 0x3
+#define BIT_QUEUEAC_Q3_V1(x) \
+ (((x) & BIT_MASK_QUEUEAC_Q3_V1) << BIT_SHIFT_QUEUEAC_Q3_V1)
+#define BIT_GET_QUEUEAC_Q3_V1(x) \
+ (((x) >> BIT_SHIFT_QUEUEAC_Q3_V1) & BIT_MASK_QUEUEAC_Q3_V1)
+
+/* 2 REG_Q3_INFO (Offset 0x040C) */
+
+#define BIT_TIDEMPTY_Q3_V1 BIT(22)
+
+/* 2 REG_Q3_INFO (Offset 0x040C) */
+
+#define BIT_SHIFT_TAIL_PKT_Q3_V2 11
+#define BIT_MASK_TAIL_PKT_Q3_V2 0x7ff
+#define BIT_TAIL_PKT_Q3_V2(x) \
+ (((x) & BIT_MASK_TAIL_PKT_Q3_V2) << BIT_SHIFT_TAIL_PKT_Q3_V2)
+#define BIT_GET_TAIL_PKT_Q3_V2(x) \
+ (((x) >> BIT_SHIFT_TAIL_PKT_Q3_V2) & BIT_MASK_TAIL_PKT_Q3_V2)
+
+/* 2 REG_Q3_INFO (Offset 0x040C) */
+
+#define BIT_SHIFT_HEAD_PKT_Q3_V1 0
+#define BIT_MASK_HEAD_PKT_Q3_V1 0x7ff
+#define BIT_HEAD_PKT_Q3_V1(x) \
+ (((x) & BIT_MASK_HEAD_PKT_Q3_V1) << BIT_SHIFT_HEAD_PKT_Q3_V1)
+#define BIT_GET_HEAD_PKT_Q3_V1(x) \
+ (((x) >> BIT_SHIFT_HEAD_PKT_Q3_V1) & BIT_MASK_HEAD_PKT_Q3_V1)
+
+/* 2 REG_MGQ_INFO (Offset 0x0410) */
+
+#define BIT_SHIFT_QUEUEMACID_MGQ_V1 25
+#define BIT_MASK_QUEUEMACID_MGQ_V1 0x7f
+#define BIT_QUEUEMACID_MGQ_V1(x) \
+ (((x) & BIT_MASK_QUEUEMACID_MGQ_V1) << BIT_SHIFT_QUEUEMACID_MGQ_V1)
+#define BIT_GET_QUEUEMACID_MGQ_V1(x) \
+ (((x) >> BIT_SHIFT_QUEUEMACID_MGQ_V1) & BIT_MASK_QUEUEMACID_MGQ_V1)
+
+#define BIT_SHIFT_QUEUEAC_MGQ_V1 23
+#define BIT_MASK_QUEUEAC_MGQ_V1 0x3
+#define BIT_QUEUEAC_MGQ_V1(x) \
+ (((x) & BIT_MASK_QUEUEAC_MGQ_V1) << BIT_SHIFT_QUEUEAC_MGQ_V1)
+#define BIT_GET_QUEUEAC_MGQ_V1(x) \
+ (((x) >> BIT_SHIFT_QUEUEAC_MGQ_V1) & BIT_MASK_QUEUEAC_MGQ_V1)
+
+/* 2 REG_MGQ_INFO (Offset 0x0410) */
+
+#define BIT_TIDEMPTY_MGQ_V1 BIT(22)
+
+/* 2 REG_MGQ_INFO (Offset 0x0410) */
+
+#define BIT_SHIFT_TAIL_PKT_MGQ_V2 11
+#define BIT_MASK_TAIL_PKT_MGQ_V2 0x7ff
+#define BIT_TAIL_PKT_MGQ_V2(x) \
+ (((x) & BIT_MASK_TAIL_PKT_MGQ_V2) << BIT_SHIFT_TAIL_PKT_MGQ_V2)
+#define BIT_GET_TAIL_PKT_MGQ_V2(x) \
+ (((x) >> BIT_SHIFT_TAIL_PKT_MGQ_V2) & BIT_MASK_TAIL_PKT_MGQ_V2)
+
+/* 2 REG_MGQ_INFO (Offset 0x0410) */
+
+#define BIT_SHIFT_HEAD_PKT_MGQ_V1 0
+#define BIT_MASK_HEAD_PKT_MGQ_V1 0x7ff
+#define BIT_HEAD_PKT_MGQ_V1(x) \
+ (((x) & BIT_MASK_HEAD_PKT_MGQ_V1) << BIT_SHIFT_HEAD_PKT_MGQ_V1)
+#define BIT_GET_HEAD_PKT_MGQ_V1(x) \
+ (((x) >> BIT_SHIFT_HEAD_PKT_MGQ_V1) & BIT_MASK_HEAD_PKT_MGQ_V1)
+
+/* 2 REG_HIQ_INFO (Offset 0x0414) */
+
+#define BIT_SHIFT_QUEUEMACID_HIQ_V1 25
+#define BIT_MASK_QUEUEMACID_HIQ_V1 0x7f
+#define BIT_QUEUEMACID_HIQ_V1(x) \
+ (((x) & BIT_MASK_QUEUEMACID_HIQ_V1) << BIT_SHIFT_QUEUEMACID_HIQ_V1)
+#define BIT_GET_QUEUEMACID_HIQ_V1(x) \
+ (((x) >> BIT_SHIFT_QUEUEMACID_HIQ_V1) & BIT_MASK_QUEUEMACID_HIQ_V1)
+
+#define BIT_SHIFT_QUEUEAC_HIQ_V1 23
+#define BIT_MASK_QUEUEAC_HIQ_V1 0x3
+#define BIT_QUEUEAC_HIQ_V1(x) \
+ (((x) & BIT_MASK_QUEUEAC_HIQ_V1) << BIT_SHIFT_QUEUEAC_HIQ_V1)
+#define BIT_GET_QUEUEAC_HIQ_V1(x) \
+ (((x) >> BIT_SHIFT_QUEUEAC_HIQ_V1) & BIT_MASK_QUEUEAC_HIQ_V1)
+
+/* 2 REG_HIQ_INFO (Offset 0x0414) */
+
+#define BIT_TIDEMPTY_HIQ_V1 BIT(22)
+
+/* 2 REG_HIQ_INFO (Offset 0x0414) */
+
+#define BIT_SHIFT_TAIL_PKT_HIQ_V2 11
+#define BIT_MASK_TAIL_PKT_HIQ_V2 0x7ff
+#define BIT_TAIL_PKT_HIQ_V2(x) \
+ (((x) & BIT_MASK_TAIL_PKT_HIQ_V2) << BIT_SHIFT_TAIL_PKT_HIQ_V2)
+#define BIT_GET_TAIL_PKT_HIQ_V2(x) \
+ (((x) >> BIT_SHIFT_TAIL_PKT_HIQ_V2) & BIT_MASK_TAIL_PKT_HIQ_V2)
+
+/* 2 REG_HIQ_INFO (Offset 0x0414) */
+
+#define BIT_SHIFT_HEAD_PKT_HIQ_V1 0
+#define BIT_MASK_HEAD_PKT_HIQ_V1 0x7ff
+#define BIT_HEAD_PKT_HIQ_V1(x) \
+ (((x) & BIT_MASK_HEAD_PKT_HIQ_V1) << BIT_SHIFT_HEAD_PKT_HIQ_V1)
+#define BIT_GET_HEAD_PKT_HIQ_V1(x) \
+ (((x) >> BIT_SHIFT_HEAD_PKT_HIQ_V1) & BIT_MASK_HEAD_PKT_HIQ_V1)
+
+/* 2 REG_BCNQ_INFO (Offset 0x0418) */
+
+#define BIT_SHIFT_BCNQ_HEAD_PG_V1 0
+#define BIT_MASK_BCNQ_HEAD_PG_V1 0xfff
+#define BIT_BCNQ_HEAD_PG_V1(x) \
+ (((x) & BIT_MASK_BCNQ_HEAD_PG_V1) << BIT_SHIFT_BCNQ_HEAD_PG_V1)
+#define BIT_GET_BCNQ_HEAD_PG_V1(x) \
+ (((x) >> BIT_SHIFT_BCNQ_HEAD_PG_V1) & BIT_MASK_BCNQ_HEAD_PG_V1)
+
+/* 2 REG_TXPKT_EMPTY (Offset 0x041A) */
+
+#define BIT_BCNQ_EMPTY BIT(11)
+#define BIT_HQQ_EMPTY BIT(10)
+#define BIT_MQQ_EMPTY BIT(9)
+#define BIT_MGQ_CPU_EMPTY BIT(8)
+#define BIT_AC7Q_EMPTY BIT(7)
+#define BIT_AC6Q_EMPTY BIT(6)
+#define BIT_AC5Q_EMPTY BIT(5)
+#define BIT_AC4Q_EMPTY BIT(4)
+#define BIT_AC3Q_EMPTY BIT(3)
+#define BIT_AC2Q_EMPTY BIT(2)
+#define BIT_AC1Q_EMPTY BIT(1)
+#define BIT_AC0Q_EMPTY BIT(0)
+
+/* 2 REG_CPU_MGQ_INFO (Offset 0x041C) */
+
+#define BIT_BCN1_POLL BIT(30)
+
+/* 2 REG_CPU_MGQ_INFO (Offset 0x041C) */
+
+#define BIT_CPUMGT_POLL BIT(29)
+#define BIT_BCN_POLL BIT(28)
+
+/* 2 REG_CPU_MGQ_INFO (Offset 0x041C) */
+
+#define BIT_CPUMGQ_FW_NUM_V1 BIT(12)
+
+/* 2 REG_CPU_MGQ_INFO (Offset 0x041C) */
+
+#define BIT_SHIFT_FW_FREE_TAIL_V1 0
+#define BIT_MASK_FW_FREE_TAIL_V1 0xfff
+#define BIT_FW_FREE_TAIL_V1(x) \
+ (((x) & BIT_MASK_FW_FREE_TAIL_V1) << BIT_SHIFT_FW_FREE_TAIL_V1)
+#define BIT_GET_FW_FREE_TAIL_V1(x) \
+ (((x) >> BIT_SHIFT_FW_FREE_TAIL_V1) & BIT_MASK_FW_FREE_TAIL_V1)
+
+/* 2 REG_FWHW_TXQ_CTRL (Offset 0x0420) */
+
+#define BIT_RTS_LIMIT_IN_OFDM BIT(23)
+#define BIT_EN_BCNQ_DL BIT(22)
+#define BIT_EN_RD_RESP_NAV_BK BIT(21)
+#define BIT_EN_WR_FREE_TAIL BIT(20)
+
+#define BIT_SHIFT_EN_QUEUE_RPT 8
+#define BIT_MASK_EN_QUEUE_RPT 0xff
+#define BIT_EN_QUEUE_RPT(x) \
+ (((x) & BIT_MASK_EN_QUEUE_RPT) << BIT_SHIFT_EN_QUEUE_RPT)
+#define BIT_GET_EN_QUEUE_RPT(x) \
+ (((x) >> BIT_SHIFT_EN_QUEUE_RPT) & BIT_MASK_EN_QUEUE_RPT)
+
+#define BIT_EN_RTY_BK BIT(7)
+#define BIT_EN_USE_INI_RAT BIT(6)
+#define BIT_EN_RTS_NAV_BK BIT(5)
+#define BIT_DIS_SSN_CHECK BIT(4)
+#define BIT_MACID_MATCH_RTS BIT(3)
+
+/* 2 REG_FWHW_TXQ_CTRL (Offset 0x0420) */
+
+#define BIT_EN_BCN_TRXRPT_V1 BIT(2)
+
+/* 2 REG_FWHW_TXQ_CTRL (Offset 0x0420) */
+
+#define BIT_EN_FTMACKRPT BIT(1)
+
+/* 2 REG_FWHW_TXQ_CTRL (Offset 0x0420) */
+
+#define BIT_EN_FTMRPT BIT(0)
+
+/* 2 REG_DATAFB_SEL (Offset 0x0423) */
+
+#define BIT__R_EN_RTY_BK_COD BIT(2)
+
+/* 2 REG_DATAFB_SEL (Offset 0x0423) */
+
+#define BIT_SHIFT__R_DATA_FALLBACK_SEL 0
+#define BIT_MASK__R_DATA_FALLBACK_SEL 0x3
+#define BIT__R_DATA_FALLBACK_SEL(x) \
+ (((x) & BIT_MASK__R_DATA_FALLBACK_SEL) \
+ << BIT_SHIFT__R_DATA_FALLBACK_SEL)
+#define BIT_GET__R_DATA_FALLBACK_SEL(x) \
+ (((x) >> BIT_SHIFT__R_DATA_FALLBACK_SEL) & \
+ BIT_MASK__R_DATA_FALLBACK_SEL)
+
+/* 2 REG_BCNQ_BDNY_V1 (Offset 0x0424) */
+
+#define BIT_SHIFT_BCNQ_PGBNDY_V1 0
+#define BIT_MASK_BCNQ_PGBNDY_V1 0xfff
+#define BIT_BCNQ_PGBNDY_V1(x) \
+ (((x) & BIT_MASK_BCNQ_PGBNDY_V1) << BIT_SHIFT_BCNQ_PGBNDY_V1)
+#define BIT_GET_BCNQ_PGBNDY_V1(x) \
+ (((x) >> BIT_SHIFT_BCNQ_PGBNDY_V1) & BIT_MASK_BCNQ_PGBNDY_V1)
+
+/* 2 REG_LIFETIME_EN (Offset 0x0426) */
+
+#define BIT_BT_INT_CPU BIT(7)
+#define BIT_BT_INT_PTA BIT(6)
+
+/* 2 REG_LIFETIME_EN (Offset 0x0426) */
+
+#define BIT_EN_CTRL_RTYBIT BIT(4)
+
+/* 2 REG_LIFETIME_EN (Offset 0x0426) */
+
+#define BIT_LIFETIME_BK_EN BIT(3)
+#define BIT_LIFETIME_BE_EN BIT(2)
+#define BIT_LIFETIME_VI_EN BIT(1)
+#define BIT_LIFETIME_VO_EN BIT(0)
+
+/* 2 REG_SPEC_SIFS (Offset 0x0428) */
+
+#define BIT_SHIFT_SPEC_SIFS_OFDM_PTCL 8
+#define BIT_MASK_SPEC_SIFS_OFDM_PTCL 0xff
+#define BIT_SPEC_SIFS_OFDM_PTCL(x) \
+ (((x) & BIT_MASK_SPEC_SIFS_OFDM_PTCL) << BIT_SHIFT_SPEC_SIFS_OFDM_PTCL)
+#define BIT_GET_SPEC_SIFS_OFDM_PTCL(x) \
+ (((x) >> BIT_SHIFT_SPEC_SIFS_OFDM_PTCL) & BIT_MASK_SPEC_SIFS_OFDM_PTCL)
+
+#define BIT_SHIFT_SPEC_SIFS_CCK_PTCL 0
+#define BIT_MASK_SPEC_SIFS_CCK_PTCL 0xff
+#define BIT_SPEC_SIFS_CCK_PTCL(x) \
+ (((x) & BIT_MASK_SPEC_SIFS_CCK_PTCL) << BIT_SHIFT_SPEC_SIFS_CCK_PTCL)
+#define BIT_GET_SPEC_SIFS_CCK_PTCL(x) \
+ (((x) >> BIT_SHIFT_SPEC_SIFS_CCK_PTCL) & BIT_MASK_SPEC_SIFS_CCK_PTCL)
+
+/* 2 REG_RETRY_LIMIT (Offset 0x042A) */
+
+#define BIT_SHIFT_SRL 8
+#define BIT_MASK_SRL 0x3f
+#define BIT_SRL(x) (((x) & BIT_MASK_SRL) << BIT_SHIFT_SRL)
+#define BIT_GET_SRL(x) (((x) >> BIT_SHIFT_SRL) & BIT_MASK_SRL)
+
+#define BIT_SHIFT_LRL 0
+#define BIT_MASK_LRL 0x3f
+#define BIT_LRL(x) (((x) & BIT_MASK_LRL) << BIT_SHIFT_LRL)
+#define BIT_GET_LRL(x) (((x) >> BIT_SHIFT_LRL) & BIT_MASK_LRL)
+
+/* 2 REG_TXBF_CTRL (Offset 0x042C) */
+
+#define BIT_R_ENABLE_NDPA BIT(31)
+#define BIT_USE_NDPA_PARAMETER BIT(30)
+#define BIT_R_PROP_TXBF BIT(29)
+#define BIT_R_EN_NDPA_INT BIT(28)
+#define BIT_R_TXBF1_80M BIT(27)
+#define BIT_R_TXBF1_40M BIT(26)
+#define BIT_R_TXBF1_20M BIT(25)
+
+#define BIT_SHIFT_R_TXBF1_AID 16
+#define BIT_MASK_R_TXBF1_AID 0x1ff
+#define BIT_R_TXBF1_AID(x) \
+ (((x) & BIT_MASK_R_TXBF1_AID) << BIT_SHIFT_R_TXBF1_AID)
+#define BIT_GET_R_TXBF1_AID(x) \
+ (((x) >> BIT_SHIFT_R_TXBF1_AID) & BIT_MASK_R_TXBF1_AID)
+
+/* 2 REG_TXBF_CTRL (Offset 0x042C) */
+
+#define BIT_DIS_NDP_BFEN BIT(15)
+
+/* 2 REG_TXBF_CTRL (Offset 0x042C) */
+
+#define BIT_R_TXBCN_NOBLOCK_NDP BIT(14)
+
+/* 2 REG_TXBF_CTRL (Offset 0x042C) */
+
+#define BIT_R_TXBF0_80M BIT(11)
+#define BIT_R_TXBF0_40M BIT(10)
+#define BIT_R_TXBF0_20M BIT(9)
+
+#define BIT_SHIFT_R_TXBF0_AID 0
+#define BIT_MASK_R_TXBF0_AID 0x1ff
+#define BIT_R_TXBF0_AID(x) \
+ (((x) & BIT_MASK_R_TXBF0_AID) << BIT_SHIFT_R_TXBF0_AID)
+#define BIT_GET_R_TXBF0_AID(x) \
+ (((x) >> BIT_SHIFT_R_TXBF0_AID) & BIT_MASK_R_TXBF0_AID)
+
+/* 2 REG_DARFRC (Offset 0x0430) */
+
+#define BIT_SHIFT_DARF_RC8 (56 & CPU_OPT_WIDTH)
+#define BIT_MASK_DARF_RC8 0x1f
+#define BIT_DARF_RC8(x) (((x) & BIT_MASK_DARF_RC8) << BIT_SHIFT_DARF_RC8)
+#define BIT_GET_DARF_RC8(x) (((x) >> BIT_SHIFT_DARF_RC8) & BIT_MASK_DARF_RC8)
+
+#define BIT_SHIFT_DARF_RC7 (48 & CPU_OPT_WIDTH)
+#define BIT_MASK_DARF_RC7 0x1f
+#define BIT_DARF_RC7(x) (((x) & BIT_MASK_DARF_RC7) << BIT_SHIFT_DARF_RC7)
+#define BIT_GET_DARF_RC7(x) (((x) >> BIT_SHIFT_DARF_RC7) & BIT_MASK_DARF_RC7)
+
+#define BIT_SHIFT_DARF_RC6 (40 & CPU_OPT_WIDTH)
+#define BIT_MASK_DARF_RC6 0x1f
+#define BIT_DARF_RC6(x) (((x) & BIT_MASK_DARF_RC6) << BIT_SHIFT_DARF_RC6)
+#define BIT_GET_DARF_RC6(x) (((x) >> BIT_SHIFT_DARF_RC6) & BIT_MASK_DARF_RC6)
+
+#define BIT_SHIFT_DARF_RC5 (32 & CPU_OPT_WIDTH)
+#define BIT_MASK_DARF_RC5 0x1f
+#define BIT_DARF_RC5(x) (((x) & BIT_MASK_DARF_RC5) << BIT_SHIFT_DARF_RC5)
+#define BIT_GET_DARF_RC5(x) (((x) >> BIT_SHIFT_DARF_RC5) & BIT_MASK_DARF_RC5)
+
+#define BIT_SHIFT_DARF_RC4 24
+#define BIT_MASK_DARF_RC4 0x1f
+#define BIT_DARF_RC4(x) (((x) & BIT_MASK_DARF_RC4) << BIT_SHIFT_DARF_RC4)
+#define BIT_GET_DARF_RC4(x) (((x) >> BIT_SHIFT_DARF_RC4) & BIT_MASK_DARF_RC4)
+
+#define BIT_SHIFT_DARF_RC3 16
+#define BIT_MASK_DARF_RC3 0x1f
+#define BIT_DARF_RC3(x) (((x) & BIT_MASK_DARF_RC3) << BIT_SHIFT_DARF_RC3)
+#define BIT_GET_DARF_RC3(x) (((x) >> BIT_SHIFT_DARF_RC3) & BIT_MASK_DARF_RC3)
+
+#define BIT_SHIFT_DARF_RC2 8
+#define BIT_MASK_DARF_RC2 0x1f
+#define BIT_DARF_RC2(x) (((x) & BIT_MASK_DARF_RC2) << BIT_SHIFT_DARF_RC2)
+#define BIT_GET_DARF_RC2(x) (((x) >> BIT_SHIFT_DARF_RC2) & BIT_MASK_DARF_RC2)
+
+#define BIT_SHIFT_DARF_RC1 0
+#define BIT_MASK_DARF_RC1 0x1f
+#define BIT_DARF_RC1(x) (((x) & BIT_MASK_DARF_RC1) << BIT_SHIFT_DARF_RC1)
+#define BIT_GET_DARF_RC1(x) (((x) >> BIT_SHIFT_DARF_RC1) & BIT_MASK_DARF_RC1)
+
+/* 2 REG_RARFRC (Offset 0x0438) */
+
+#define BIT_SHIFT_RARF_RC8 (56 & CPU_OPT_WIDTH)
+#define BIT_MASK_RARF_RC8 0x1f
+#define BIT_RARF_RC8(x) (((x) & BIT_MASK_RARF_RC8) << BIT_SHIFT_RARF_RC8)
+#define BIT_GET_RARF_RC8(x) (((x) >> BIT_SHIFT_RARF_RC8) & BIT_MASK_RARF_RC8)
+
+#define BIT_SHIFT_RARF_RC7 (48 & CPU_OPT_WIDTH)
+#define BIT_MASK_RARF_RC7 0x1f
+#define BIT_RARF_RC7(x) (((x) & BIT_MASK_RARF_RC7) << BIT_SHIFT_RARF_RC7)
+#define BIT_GET_RARF_RC7(x) (((x) >> BIT_SHIFT_RARF_RC7) & BIT_MASK_RARF_RC7)
+
+#define BIT_SHIFT_RARF_RC6 (40 & CPU_OPT_WIDTH)
+#define BIT_MASK_RARF_RC6 0x1f
+#define BIT_RARF_RC6(x) (((x) & BIT_MASK_RARF_RC6) << BIT_SHIFT_RARF_RC6)
+#define BIT_GET_RARF_RC6(x) (((x) >> BIT_SHIFT_RARF_RC6) & BIT_MASK_RARF_RC6)
+
+#define BIT_SHIFT_RARF_RC5 (32 & CPU_OPT_WIDTH)
+#define BIT_MASK_RARF_RC5 0x1f
+#define BIT_RARF_RC5(x) (((x) & BIT_MASK_RARF_RC5) << BIT_SHIFT_RARF_RC5)
+#define BIT_GET_RARF_RC5(x) (((x) >> BIT_SHIFT_RARF_RC5) & BIT_MASK_RARF_RC5)
+
+#define BIT_SHIFT_RARF_RC4 24
+#define BIT_MASK_RARF_RC4 0x1f
+#define BIT_RARF_RC4(x) (((x) & BIT_MASK_RARF_RC4) << BIT_SHIFT_RARF_RC4)
+#define BIT_GET_RARF_RC4(x) (((x) >> BIT_SHIFT_RARF_RC4) & BIT_MASK_RARF_RC4)
+
+#define BIT_SHIFT_RARF_RC3 16
+#define BIT_MASK_RARF_RC3 0x1f
+#define BIT_RARF_RC3(x) (((x) & BIT_MASK_RARF_RC3) << BIT_SHIFT_RARF_RC3)
+#define BIT_GET_RARF_RC3(x) (((x) >> BIT_SHIFT_RARF_RC3) & BIT_MASK_RARF_RC3)
+
+#define BIT_SHIFT_RARF_RC2 8
+#define BIT_MASK_RARF_RC2 0x1f
+#define BIT_RARF_RC2(x) (((x) & BIT_MASK_RARF_RC2) << BIT_SHIFT_RARF_RC2)
+#define BIT_GET_RARF_RC2(x) (((x) >> BIT_SHIFT_RARF_RC2) & BIT_MASK_RARF_RC2)
+
+#define BIT_SHIFT_RARF_RC1 0
+#define BIT_MASK_RARF_RC1 0x1f
+#define BIT_RARF_RC1(x) (((x) & BIT_MASK_RARF_RC1) << BIT_SHIFT_RARF_RC1)
+#define BIT_GET_RARF_RC1(x) (((x) >> BIT_SHIFT_RARF_RC1) & BIT_MASK_RARF_RC1)
+
+/* 2 REG_RRSR (Offset 0x0440) */
+
+#define BIT_SHIFT_RRSR_RSC 21
+#define BIT_MASK_RRSR_RSC 0x3
+#define BIT_RRSR_RSC(x) (((x) & BIT_MASK_RRSR_RSC) << BIT_SHIFT_RRSR_RSC)
+#define BIT_GET_RRSR_RSC(x) (((x) >> BIT_SHIFT_RRSR_RSC) & BIT_MASK_RRSR_RSC)
+
+#define BIT_RRSR_BW BIT(20)
+
+#define BIT_SHIFT_RRSC_BITMAP 0
+#define BIT_MASK_RRSC_BITMAP 0xfffff
+#define BIT_RRSC_BITMAP(x) \
+ (((x) & BIT_MASK_RRSC_BITMAP) << BIT_SHIFT_RRSC_BITMAP)
+#define BIT_GET_RRSC_BITMAP(x) \
+ (((x) >> BIT_SHIFT_RRSC_BITMAP) & BIT_MASK_RRSC_BITMAP)
+
+/* 2 REG_ARFR0 (Offset 0x0444) */
+
+#define BIT_SHIFT_ARFR0_V1 0
+#define BIT_MASK_ARFR0_V1 0xffffffffffffffffL
+#define BIT_ARFR0_V1(x) (((x) & BIT_MASK_ARFR0_V1) << BIT_SHIFT_ARFR0_V1)
+#define BIT_GET_ARFR0_V1(x) (((x) >> BIT_SHIFT_ARFR0_V1) & BIT_MASK_ARFR0_V1)
+
+/* 2 REG_ARFR1_V1 (Offset 0x044C) */
+
+#define BIT_SHIFT_ARFR1_V1 0
+#define BIT_MASK_ARFR1_V1 0xffffffffffffffffL
+#define BIT_ARFR1_V1(x) (((x) & BIT_MASK_ARFR1_V1) << BIT_SHIFT_ARFR1_V1)
+#define BIT_GET_ARFR1_V1(x) (((x) >> BIT_SHIFT_ARFR1_V1) & BIT_MASK_ARFR1_V1)
+
+/* 2 REG_CCK_CHECK (Offset 0x0454) */
+
+#define BIT_CHECK_CCK_EN BIT(7)
+#define BIT_EN_BCN_PKT_REL BIT(6)
+#define BIT_BCN_PORT_SEL BIT(5)
+#define BIT_MOREDATA_BYPASS BIT(4)
+#define BIT_EN_CLR_CMD_REL_BCN_PKT BIT(3)
+
+/* 2 REG_CCK_CHECK (Offset 0x0454) */
+
+#define BIT_R_EN_SET_MOREDATA BIT(2)
+#define BIT__R_DIS_CLEAR_MACID_RELEASE BIT(1)
+#define BIT__R_MACID_RELEASE_EN BIT(0)
+
+/* 2 REG_AMPDU_MAX_TIME (Offset 0x0456) */
+
+#define BIT_SHIFT_AMPDU_MAX_TIME 0
+#define BIT_MASK_AMPDU_MAX_TIME 0xff
+#define BIT_AMPDU_MAX_TIME(x) \
+ (((x) & BIT_MASK_AMPDU_MAX_TIME) << BIT_SHIFT_AMPDU_MAX_TIME)
+#define BIT_GET_AMPDU_MAX_TIME(x) \
+ (((x) >> BIT_SHIFT_AMPDU_MAX_TIME) & BIT_MASK_AMPDU_MAX_TIME)
+
+/* 2 REG_BCNQ1_BDNY_V1 (Offset 0x0456) */
+
+#define BIT_SHIFT_BCNQ1_PGBNDY_V1 0
+#define BIT_MASK_BCNQ1_PGBNDY_V1 0xfff
+#define BIT_BCNQ1_PGBNDY_V1(x) \
+ (((x) & BIT_MASK_BCNQ1_PGBNDY_V1) << BIT_SHIFT_BCNQ1_PGBNDY_V1)
+#define BIT_GET_BCNQ1_PGBNDY_V1(x) \
+ (((x) >> BIT_SHIFT_BCNQ1_PGBNDY_V1) & BIT_MASK_BCNQ1_PGBNDY_V1)
+
+/* 2 REG_AMPDU_MAX_LENGTH (Offset 0x0458) */
+
+#define BIT_SHIFT_AMPDU_MAX_LENGTH 0
+#define BIT_MASK_AMPDU_MAX_LENGTH 0xffffffffL
+#define BIT_AMPDU_MAX_LENGTH(x) \
+ (((x) & BIT_MASK_AMPDU_MAX_LENGTH) << BIT_SHIFT_AMPDU_MAX_LENGTH)
+#define BIT_GET_AMPDU_MAX_LENGTH(x) \
+ (((x) >> BIT_SHIFT_AMPDU_MAX_LENGTH) & BIT_MASK_AMPDU_MAX_LENGTH)
+
+/* 2 REG_ACQ_STOP (Offset 0x045C) */
+
+#define BIT_AC7Q_STOP BIT(7)
+#define BIT_AC6Q_STOP BIT(6)
+#define BIT_AC5Q_STOP BIT(5)
+#define BIT_AC4Q_STOP BIT(4)
+#define BIT_AC3Q_STOP BIT(3)
+#define BIT_AC2Q_STOP BIT(2)
+#define BIT_AC1Q_STOP BIT(1)
+#define BIT_AC0Q_STOP BIT(0)
+
+/* 2 REG_NDPA_RATE (Offset 0x045D) */
+
+#define BIT_SHIFT_R_NDPA_RATE_V1 0
+#define BIT_MASK_R_NDPA_RATE_V1 0xff
+#define BIT_R_NDPA_RATE_V1(x) \
+ (((x) & BIT_MASK_R_NDPA_RATE_V1) << BIT_SHIFT_R_NDPA_RATE_V1)
+#define BIT_GET_R_NDPA_RATE_V1(x) \
+ (((x) >> BIT_SHIFT_R_NDPA_RATE_V1) & BIT_MASK_R_NDPA_RATE_V1)
+
+/* 2 REG_TX_HANG_CTRL (Offset 0x045E) */
+
+#define BIT_R_EN_GNT_BT_AWAKE BIT(3)
+
+/* 2 REG_TX_HANG_CTRL (Offset 0x045E) */
+
+#define BIT_EN_EOF_V1 BIT(2)
+
+/* 2 REG_TX_HANG_CTRL (Offset 0x045E) */
+
+#define BIT_DIS_OQT_BLOCK BIT(1)
+#define BIT_SEARCH_QUEUE_EN BIT(0)
+
+/* 2 REG_NDPA_OPT_CTRL (Offset 0x045F) */
+
+#define BIT_R_DIS_MACID_RELEASE_RTY BIT(5)
+
+/* 2 REG_NDPA_OPT_CTRL (Offset 0x045F) */
+
+#define BIT_SHIFT_BW_SIGTA 3
+#define BIT_MASK_BW_SIGTA 0x3
+#define BIT_BW_SIGTA(x) (((x) & BIT_MASK_BW_SIGTA) << BIT_SHIFT_BW_SIGTA)
+#define BIT_GET_BW_SIGTA(x) (((x) >> BIT_SHIFT_BW_SIGTA) & BIT_MASK_BW_SIGTA)
+
+/* 2 REG_NDPA_OPT_CTRL (Offset 0x045F) */
+
+#define BIT_EN_BAR_SIGTA BIT(2)
+
+/* 2 REG_NDPA_OPT_CTRL (Offset 0x045F) */
+
+#define BIT_SHIFT_R_NDPA_BW 0
+#define BIT_MASK_R_NDPA_BW 0x3
+#define BIT_R_NDPA_BW(x) (((x) & BIT_MASK_R_NDPA_BW) << BIT_SHIFT_R_NDPA_BW)
+#define BIT_GET_R_NDPA_BW(x) (((x) >> BIT_SHIFT_R_NDPA_BW) & BIT_MASK_R_NDPA_BW)
+
+/* 2 REG_RD_RESP_PKT_TH (Offset 0x0463) */
+
+#define BIT_SHIFT_RD_RESP_PKT_TH_V1 0
+#define BIT_MASK_RD_RESP_PKT_TH_V1 0x3f
+#define BIT_RD_RESP_PKT_TH_V1(x) \
+ (((x) & BIT_MASK_RD_RESP_PKT_TH_V1) << BIT_SHIFT_RD_RESP_PKT_TH_V1)
+#define BIT_GET_RD_RESP_PKT_TH_V1(x) \
+ (((x) >> BIT_SHIFT_RD_RESP_PKT_TH_V1) & BIT_MASK_RD_RESP_PKT_TH_V1)
+
+/* 2 REG_CMDQ_INFO (Offset 0x0464) */
+
+#define BIT_SHIFT_QUEUEMACID_CMDQ_V1 25
+#define BIT_MASK_QUEUEMACID_CMDQ_V1 0x7f
+#define BIT_QUEUEMACID_CMDQ_V1(x) \
+ (((x) & BIT_MASK_QUEUEMACID_CMDQ_V1) << BIT_SHIFT_QUEUEMACID_CMDQ_V1)
+#define BIT_GET_QUEUEMACID_CMDQ_V1(x) \
+ (((x) >> BIT_SHIFT_QUEUEMACID_CMDQ_V1) & BIT_MASK_QUEUEMACID_CMDQ_V1)
+
+/* 2 REG_CMDQ_INFO (Offset 0x0464) */
+
+#define BIT_SHIFT_QUEUEAC_CMDQ_V1 23
+#define BIT_MASK_QUEUEAC_CMDQ_V1 0x3
+#define BIT_QUEUEAC_CMDQ_V1(x) \
+ (((x) & BIT_MASK_QUEUEAC_CMDQ_V1) << BIT_SHIFT_QUEUEAC_CMDQ_V1)
+#define BIT_GET_QUEUEAC_CMDQ_V1(x) \
+ (((x) >> BIT_SHIFT_QUEUEAC_CMDQ_V1) & BIT_MASK_QUEUEAC_CMDQ_V1)
+
+/* 2 REG_CMDQ_INFO (Offset 0x0464) */
+
+#define BIT_TIDEMPTY_CMDQ_V1 BIT(22)
+
+/* 2 REG_CMDQ_INFO (Offset 0x0464) */
+
+#define BIT_SHIFT_TAIL_PKT_CMDQ_V2 11
+#define BIT_MASK_TAIL_PKT_CMDQ_V2 0x7ff
+#define BIT_TAIL_PKT_CMDQ_V2(x) \
+ (((x) & BIT_MASK_TAIL_PKT_CMDQ_V2) << BIT_SHIFT_TAIL_PKT_CMDQ_V2)
+#define BIT_GET_TAIL_PKT_CMDQ_V2(x) \
+ (((x) >> BIT_SHIFT_TAIL_PKT_CMDQ_V2) & BIT_MASK_TAIL_PKT_CMDQ_V2)
+
+/* 2 REG_CMDQ_INFO (Offset 0x0464) */
+
+#define BIT_SHIFT_HEAD_PKT_CMDQ_V1 0
+#define BIT_MASK_HEAD_PKT_CMDQ_V1 0x7ff
+#define BIT_HEAD_PKT_CMDQ_V1(x) \
+ (((x) & BIT_MASK_HEAD_PKT_CMDQ_V1) << BIT_SHIFT_HEAD_PKT_CMDQ_V1)
+#define BIT_GET_HEAD_PKT_CMDQ_V1(x) \
+ (((x) >> BIT_SHIFT_HEAD_PKT_CMDQ_V1) & BIT_MASK_HEAD_PKT_CMDQ_V1)
+
+/* 2 REG_Q4_INFO (Offset 0x0468) */
+
+#define BIT_SHIFT_QUEUEMACID_Q4_V1 25
+#define BIT_MASK_QUEUEMACID_Q4_V1 0x7f
+#define BIT_QUEUEMACID_Q4_V1(x) \
+ (((x) & BIT_MASK_QUEUEMACID_Q4_V1) << BIT_SHIFT_QUEUEMACID_Q4_V1)
+#define BIT_GET_QUEUEMACID_Q4_V1(x) \
+ (((x) >> BIT_SHIFT_QUEUEMACID_Q4_V1) & BIT_MASK_QUEUEMACID_Q4_V1)
+
+#define BIT_SHIFT_QUEUEAC_Q4_V1 23
+#define BIT_MASK_QUEUEAC_Q4_V1 0x3
+#define BIT_QUEUEAC_Q4_V1(x) \
+ (((x) & BIT_MASK_QUEUEAC_Q4_V1) << BIT_SHIFT_QUEUEAC_Q4_V1)
+#define BIT_GET_QUEUEAC_Q4_V1(x) \
+ (((x) >> BIT_SHIFT_QUEUEAC_Q4_V1) & BIT_MASK_QUEUEAC_Q4_V1)
+
+/* 2 REG_Q4_INFO (Offset 0x0468) */
+
+#define BIT_TIDEMPTY_Q4_V1 BIT(22)
+
+/* 2 REG_Q4_INFO (Offset 0x0468) */
+
+#define BIT_SHIFT_TAIL_PKT_Q4_V2 11
+#define BIT_MASK_TAIL_PKT_Q4_V2 0x7ff
+#define BIT_TAIL_PKT_Q4_V2(x) \
+ (((x) & BIT_MASK_TAIL_PKT_Q4_V2) << BIT_SHIFT_TAIL_PKT_Q4_V2)
+#define BIT_GET_TAIL_PKT_Q4_V2(x) \
+ (((x) >> BIT_SHIFT_TAIL_PKT_Q4_V2) & BIT_MASK_TAIL_PKT_Q4_V2)
+
+/* 2 REG_Q4_INFO (Offset 0x0468) */
+
+#define BIT_SHIFT_HEAD_PKT_Q4_V1 0
+#define BIT_MASK_HEAD_PKT_Q4_V1 0x7ff
+#define BIT_HEAD_PKT_Q4_V1(x) \
+ (((x) & BIT_MASK_HEAD_PKT_Q4_V1) << BIT_SHIFT_HEAD_PKT_Q4_V1)
+#define BIT_GET_HEAD_PKT_Q4_V1(x) \
+ (((x) >> BIT_SHIFT_HEAD_PKT_Q4_V1) & BIT_MASK_HEAD_PKT_Q4_V1)
+
+/* 2 REG_Q5_INFO (Offset 0x046C) */
+
+#define BIT_SHIFT_QUEUEMACID_Q5_V1 25
+#define BIT_MASK_QUEUEMACID_Q5_V1 0x7f
+#define BIT_QUEUEMACID_Q5_V1(x) \
+ (((x) & BIT_MASK_QUEUEMACID_Q5_V1) << BIT_SHIFT_QUEUEMACID_Q5_V1)
+#define BIT_GET_QUEUEMACID_Q5_V1(x) \
+ (((x) >> BIT_SHIFT_QUEUEMACID_Q5_V1) & BIT_MASK_QUEUEMACID_Q5_V1)
+
+#define BIT_SHIFT_QUEUEAC_Q5_V1 23
+#define BIT_MASK_QUEUEAC_Q5_V1 0x3
+#define BIT_QUEUEAC_Q5_V1(x) \
+ (((x) & BIT_MASK_QUEUEAC_Q5_V1) << BIT_SHIFT_QUEUEAC_Q5_V1)
+#define BIT_GET_QUEUEAC_Q5_V1(x) \
+ (((x) >> BIT_SHIFT_QUEUEAC_Q5_V1) & BIT_MASK_QUEUEAC_Q5_V1)
+
+/* 2 REG_Q5_INFO (Offset 0x046C) */
+
+#define BIT_TIDEMPTY_Q5_V1 BIT(22)
+
+/* 2 REG_Q5_INFO (Offset 0x046C) */
+
+#define BIT_SHIFT_TAIL_PKT_Q5_V2 11
+#define BIT_MASK_TAIL_PKT_Q5_V2 0x7ff
+#define BIT_TAIL_PKT_Q5_V2(x) \
+ (((x) & BIT_MASK_TAIL_PKT_Q5_V2) << BIT_SHIFT_TAIL_PKT_Q5_V2)
+#define BIT_GET_TAIL_PKT_Q5_V2(x) \
+ (((x) >> BIT_SHIFT_TAIL_PKT_Q5_V2) & BIT_MASK_TAIL_PKT_Q5_V2)
+
+/* 2 REG_Q5_INFO (Offset 0x046C) */
+
+#define BIT_SHIFT_HEAD_PKT_Q5_V1 0
+#define BIT_MASK_HEAD_PKT_Q5_V1 0x7ff
+#define BIT_HEAD_PKT_Q5_V1(x) \
+ (((x) & BIT_MASK_HEAD_PKT_Q5_V1) << BIT_SHIFT_HEAD_PKT_Q5_V1)
+#define BIT_GET_HEAD_PKT_Q5_V1(x) \
+ (((x) >> BIT_SHIFT_HEAD_PKT_Q5_V1) & BIT_MASK_HEAD_PKT_Q5_V1)
+
+/* 2 REG_Q6_INFO (Offset 0x0470) */
+
+#define BIT_SHIFT_QUEUEMACID_Q6_V1 25
+#define BIT_MASK_QUEUEMACID_Q6_V1 0x7f
+#define BIT_QUEUEMACID_Q6_V1(x) \
+ (((x) & BIT_MASK_QUEUEMACID_Q6_V1) << BIT_SHIFT_QUEUEMACID_Q6_V1)
+#define BIT_GET_QUEUEMACID_Q6_V1(x) \
+ (((x) >> BIT_SHIFT_QUEUEMACID_Q6_V1) & BIT_MASK_QUEUEMACID_Q6_V1)
+
+#define BIT_SHIFT_QUEUEAC_Q6_V1 23
+#define BIT_MASK_QUEUEAC_Q6_V1 0x3
+#define BIT_QUEUEAC_Q6_V1(x) \
+ (((x) & BIT_MASK_QUEUEAC_Q6_V1) << BIT_SHIFT_QUEUEAC_Q6_V1)
+#define BIT_GET_QUEUEAC_Q6_V1(x) \
+ (((x) >> BIT_SHIFT_QUEUEAC_Q6_V1) & BIT_MASK_QUEUEAC_Q6_V1)
+
+/* 2 REG_Q6_INFO (Offset 0x0470) */
+
+#define BIT_TIDEMPTY_Q6_V1 BIT(22)
+
+/* 2 REG_Q6_INFO (Offset 0x0470) */
+
+#define BIT_SHIFT_TAIL_PKT_Q6_V2 11
+#define BIT_MASK_TAIL_PKT_Q6_V2 0x7ff
+#define BIT_TAIL_PKT_Q6_V2(x) \
+ (((x) & BIT_MASK_TAIL_PKT_Q6_V2) << BIT_SHIFT_TAIL_PKT_Q6_V2)
+#define BIT_GET_TAIL_PKT_Q6_V2(x) \
+ (((x) >> BIT_SHIFT_TAIL_PKT_Q6_V2) & BIT_MASK_TAIL_PKT_Q6_V2)
+
+/* 2 REG_Q6_INFO (Offset 0x0470) */
+
+#define BIT_SHIFT_HEAD_PKT_Q6_V1 0
+#define BIT_MASK_HEAD_PKT_Q6_V1 0x7ff
+#define BIT_HEAD_PKT_Q6_V1(x) \
+ (((x) & BIT_MASK_HEAD_PKT_Q6_V1) << BIT_SHIFT_HEAD_PKT_Q6_V1)
+#define BIT_GET_HEAD_PKT_Q6_V1(x) \
+ (((x) >> BIT_SHIFT_HEAD_PKT_Q6_V1) & BIT_MASK_HEAD_PKT_Q6_V1)
+
+/* 2 REG_Q7_INFO (Offset 0x0474) */
+
+#define BIT_SHIFT_QUEUEMACID_Q7_V1 25
+#define BIT_MASK_QUEUEMACID_Q7_V1 0x7f
+#define BIT_QUEUEMACID_Q7_V1(x) \
+ (((x) & BIT_MASK_QUEUEMACID_Q7_V1) << BIT_SHIFT_QUEUEMACID_Q7_V1)
+#define BIT_GET_QUEUEMACID_Q7_V1(x) \
+ (((x) >> BIT_SHIFT_QUEUEMACID_Q7_V1) & BIT_MASK_QUEUEMACID_Q7_V1)
+
+#define BIT_SHIFT_QUEUEAC_Q7_V1 23
+#define BIT_MASK_QUEUEAC_Q7_V1 0x3
+#define BIT_QUEUEAC_Q7_V1(x) \
+ (((x) & BIT_MASK_QUEUEAC_Q7_V1) << BIT_SHIFT_QUEUEAC_Q7_V1)
+#define BIT_GET_QUEUEAC_Q7_V1(x) \
+ (((x) >> BIT_SHIFT_QUEUEAC_Q7_V1) & BIT_MASK_QUEUEAC_Q7_V1)
+
+/* 2 REG_Q7_INFO (Offset 0x0474) */
+
+#define BIT_TIDEMPTY_Q7_V1 BIT(22)
+
+/* 2 REG_Q7_INFO (Offset 0x0474) */
+
+#define BIT_SHIFT_TAIL_PKT_Q7_V2 11
+#define BIT_MASK_TAIL_PKT_Q7_V2 0x7ff
+#define BIT_TAIL_PKT_Q7_V2(x) \
+ (((x) & BIT_MASK_TAIL_PKT_Q7_V2) << BIT_SHIFT_TAIL_PKT_Q7_V2)
+#define BIT_GET_TAIL_PKT_Q7_V2(x) \
+ (((x) >> BIT_SHIFT_TAIL_PKT_Q7_V2) & BIT_MASK_TAIL_PKT_Q7_V2)
+
+/* 2 REG_Q7_INFO (Offset 0x0474) */
+
+#define BIT_SHIFT_HEAD_PKT_Q7_V1 0
+#define BIT_MASK_HEAD_PKT_Q7_V1 0x7ff
+#define BIT_HEAD_PKT_Q7_V1(x) \
+ (((x) & BIT_MASK_HEAD_PKT_Q7_V1) << BIT_SHIFT_HEAD_PKT_Q7_V1)
+#define BIT_GET_HEAD_PKT_Q7_V1(x) \
+ (((x) >> BIT_SHIFT_HEAD_PKT_Q7_V1) & BIT_MASK_HEAD_PKT_Q7_V1)
+
+/* 2 REG_WMAC_LBK_BUF_HD_V1 (Offset 0x0478) */
+
+#define BIT_SHIFT_WMAC_LBK_BUF_HEAD_V1 0
+#define BIT_MASK_WMAC_LBK_BUF_HEAD_V1 0xfff
+#define BIT_WMAC_LBK_BUF_HEAD_V1(x) \
+ (((x) & BIT_MASK_WMAC_LBK_BUF_HEAD_V1) \
+ << BIT_SHIFT_WMAC_LBK_BUF_HEAD_V1)
+#define BIT_GET_WMAC_LBK_BUF_HEAD_V1(x) \
+ (((x) >> BIT_SHIFT_WMAC_LBK_BUF_HEAD_V1) & \
+ BIT_MASK_WMAC_LBK_BUF_HEAD_V1)
+
+/* 2 REG_MGQ_BDNY_V1 (Offset 0x047A) */
+
+#define BIT_SHIFT_MGQ_PGBNDY_V1 0
+#define BIT_MASK_MGQ_PGBNDY_V1 0xfff
+#define BIT_MGQ_PGBNDY_V1(x) \
+ (((x) & BIT_MASK_MGQ_PGBNDY_V1) << BIT_SHIFT_MGQ_PGBNDY_V1)
+#define BIT_GET_MGQ_PGBNDY_V1(x) \
+ (((x) >> BIT_SHIFT_MGQ_PGBNDY_V1) & BIT_MASK_MGQ_PGBNDY_V1)
+
+/* 2 REG_TXRPT_CTRL (Offset 0x047C) */
+
+#define BIT_SHIFT_TRXRPT_TIMER_TH 24
+#define BIT_MASK_TRXRPT_TIMER_TH 0xff
+#define BIT_TRXRPT_TIMER_TH(x) \
+ (((x) & BIT_MASK_TRXRPT_TIMER_TH) << BIT_SHIFT_TRXRPT_TIMER_TH)
+#define BIT_GET_TRXRPT_TIMER_TH(x) \
+ (((x) >> BIT_SHIFT_TRXRPT_TIMER_TH) & BIT_MASK_TRXRPT_TIMER_TH)
+
+/* 2 REG_TXRPT_CTRL (Offset 0x047C) */
+
+#define BIT_SHIFT_TRXRPT_LEN_TH 16
+#define BIT_MASK_TRXRPT_LEN_TH 0xff
+#define BIT_TRXRPT_LEN_TH(x) \
+ (((x) & BIT_MASK_TRXRPT_LEN_TH) << BIT_SHIFT_TRXRPT_LEN_TH)
+#define BIT_GET_TRXRPT_LEN_TH(x) \
+ (((x) >> BIT_SHIFT_TRXRPT_LEN_TH) & BIT_MASK_TRXRPT_LEN_TH)
+
+/* 2 REG_TXRPT_CTRL (Offset 0x047C) */
+
+#define BIT_SHIFT_TRXRPT_READ_PTR 8
+#define BIT_MASK_TRXRPT_READ_PTR 0xff
+#define BIT_TRXRPT_READ_PTR(x) \
+ (((x) & BIT_MASK_TRXRPT_READ_PTR) << BIT_SHIFT_TRXRPT_READ_PTR)
+#define BIT_GET_TRXRPT_READ_PTR(x) \
+ (((x) >> BIT_SHIFT_TRXRPT_READ_PTR) & BIT_MASK_TRXRPT_READ_PTR)
+
+/* 2 REG_TXRPT_CTRL (Offset 0x047C) */
+
+#define BIT_SHIFT_TRXRPT_WRITE_PTR 0
+#define BIT_MASK_TRXRPT_WRITE_PTR 0xff
+#define BIT_TRXRPT_WRITE_PTR(x) \
+ (((x) & BIT_MASK_TRXRPT_WRITE_PTR) << BIT_SHIFT_TRXRPT_WRITE_PTR)
+#define BIT_GET_TRXRPT_WRITE_PTR(x) \
+ (((x) >> BIT_SHIFT_TRXRPT_WRITE_PTR) & BIT_MASK_TRXRPT_WRITE_PTR)
+
+/* 2 REG_INIRTS_RATE_SEL (Offset 0x0480) */
+
+#define BIT_LEAG_RTS_BW_DUP BIT(5)
+
+/* 2 REG_BASIC_CFEND_RATE (Offset 0x0481) */
+
+#define BIT_SHIFT_BASIC_CFEND_RATE 0
+#define BIT_MASK_BASIC_CFEND_RATE 0x1f
+#define BIT_BASIC_CFEND_RATE(x) \
+ (((x) & BIT_MASK_BASIC_CFEND_RATE) << BIT_SHIFT_BASIC_CFEND_RATE)
+#define BIT_GET_BASIC_CFEND_RATE(x) \
+ (((x) >> BIT_SHIFT_BASIC_CFEND_RATE) & BIT_MASK_BASIC_CFEND_RATE)
+
+/* 2 REG_STBC_CFEND_RATE (Offset 0x0482) */
+
+#define BIT_SHIFT_STBC_CFEND_RATE 0
+#define BIT_MASK_STBC_CFEND_RATE 0x1f
+#define BIT_STBC_CFEND_RATE(x) \
+ (((x) & BIT_MASK_STBC_CFEND_RATE) << BIT_SHIFT_STBC_CFEND_RATE)
+#define BIT_GET_STBC_CFEND_RATE(x) \
+ (((x) >> BIT_SHIFT_STBC_CFEND_RATE) & BIT_MASK_STBC_CFEND_RATE)
+
+/* 2 REG_DATA_SC (Offset 0x0483) */
+
+#define BIT_SHIFT_TXSC_40M 4
+#define BIT_MASK_TXSC_40M 0xf
+#define BIT_TXSC_40M(x) (((x) & BIT_MASK_TXSC_40M) << BIT_SHIFT_TXSC_40M)
+#define BIT_GET_TXSC_40M(x) (((x) >> BIT_SHIFT_TXSC_40M) & BIT_MASK_TXSC_40M)
+
+#define BIT_SHIFT_TXSC_20M 0
+#define BIT_MASK_TXSC_20M 0xf
+#define BIT_TXSC_20M(x) (((x) & BIT_MASK_TXSC_20M) << BIT_SHIFT_TXSC_20M)
+#define BIT_GET_TXSC_20M(x) (((x) >> BIT_SHIFT_TXSC_20M) & BIT_MASK_TXSC_20M)
+
+/* 2 REG_MACID_SLEEP3 (Offset 0x0484) */
+
+#define BIT_SHIFT_MACID127_96_PKTSLEEP 0
+#define BIT_MASK_MACID127_96_PKTSLEEP 0xffffffffL
+#define BIT_MACID127_96_PKTSLEEP(x) \
+ (((x) & BIT_MASK_MACID127_96_PKTSLEEP) \
+ << BIT_SHIFT_MACID127_96_PKTSLEEP)
+#define BIT_GET_MACID127_96_PKTSLEEP(x) \
+ (((x) >> BIT_SHIFT_MACID127_96_PKTSLEEP) & \
+ BIT_MASK_MACID127_96_PKTSLEEP)
+
+/* 2 REG_MACID_SLEEP1 (Offset 0x0488) */
+
+#define BIT_SHIFT_MACID63_32_PKTSLEEP 0
+#define BIT_MASK_MACID63_32_PKTSLEEP 0xffffffffL
+#define BIT_MACID63_32_PKTSLEEP(x) \
+ (((x) & BIT_MASK_MACID63_32_PKTSLEEP) << BIT_SHIFT_MACID63_32_PKTSLEEP)
+#define BIT_GET_MACID63_32_PKTSLEEP(x) \
+ (((x) >> BIT_SHIFT_MACID63_32_PKTSLEEP) & BIT_MASK_MACID63_32_PKTSLEEP)
+
+/* 2 REG_ARFR2_V1 (Offset 0x048C) */
+
+#define BIT_SHIFT_ARFR2_V1 0
+#define BIT_MASK_ARFR2_V1 0xffffffffffffffffL
+#define BIT_ARFR2_V1(x) (((x) & BIT_MASK_ARFR2_V1) << BIT_SHIFT_ARFR2_V1)
+#define BIT_GET_ARFR2_V1(x) (((x) >> BIT_SHIFT_ARFR2_V1) & BIT_MASK_ARFR2_V1)
+
+/* 2 REG_ARFR3_V1 (Offset 0x0494) */
+
+#define BIT_SHIFT_ARFR3_V1 0
+#define BIT_MASK_ARFR3_V1 0xffffffffffffffffL
+#define BIT_ARFR3_V1(x) (((x) & BIT_MASK_ARFR3_V1) << BIT_SHIFT_ARFR3_V1)
+#define BIT_GET_ARFR3_V1(x) (((x) >> BIT_SHIFT_ARFR3_V1) & BIT_MASK_ARFR3_V1)
+
+/* 2 REG_ARFR4 (Offset 0x049C) */
+
+#define BIT_SHIFT_ARFR4 0
+#define BIT_MASK_ARFR4 0xffffffffffffffffL
+#define BIT_ARFR4(x) (((x) & BIT_MASK_ARFR4) << BIT_SHIFT_ARFR4)
+#define BIT_GET_ARFR4(x) (((x) >> BIT_SHIFT_ARFR4) & BIT_MASK_ARFR4)
+
+/* 2 REG_ARFR5 (Offset 0x04A4) */
+
+#define BIT_SHIFT_ARFR5 0
+#define BIT_MASK_ARFR5 0xffffffffffffffffL
+#define BIT_ARFR5(x) (((x) & BIT_MASK_ARFR5) << BIT_SHIFT_ARFR5)
+#define BIT_GET_ARFR5(x) (((x) >> BIT_SHIFT_ARFR5) & BIT_MASK_ARFR5)
+
+/* 2 REG_TXRPT_START_OFFSET (Offset 0x04AC) */
+
+#define BIT_SHIFT_MACID_MURATE_OFFSET 24
+#define BIT_MASK_MACID_MURATE_OFFSET 0xff
+#define BIT_MACID_MURATE_OFFSET(x) \
+ (((x) & BIT_MASK_MACID_MURATE_OFFSET) << BIT_SHIFT_MACID_MURATE_OFFSET)
+#define BIT_GET_MACID_MURATE_OFFSET(x) \
+ (((x) >> BIT_SHIFT_MACID_MURATE_OFFSET) & BIT_MASK_MACID_MURATE_OFFSET)
+
+/* 2 REG_TXRPT_START_OFFSET (Offset 0x04AC) */
+
+#define BIT_RPTFIFO_SIZE_OPT BIT(16)
+
+/* 2 REG_TXRPT_START_OFFSET (Offset 0x04AC) */
+
+#define BIT_SHIFT_MACID_CTRL_OFFSET 8
+#define BIT_MASK_MACID_CTRL_OFFSET 0xff
+#define BIT_MACID_CTRL_OFFSET(x) \
+ (((x) & BIT_MASK_MACID_CTRL_OFFSET) << BIT_SHIFT_MACID_CTRL_OFFSET)
+#define BIT_GET_MACID_CTRL_OFFSET(x) \
+ (((x) >> BIT_SHIFT_MACID_CTRL_OFFSET) & BIT_MASK_MACID_CTRL_OFFSET)
+
+/* 2 REG_TXRPT_START_OFFSET (Offset 0x04AC) */
+
+#define BIT_SHIFT_AMPDU_TXRPT_OFFSET 0
+#define BIT_MASK_AMPDU_TXRPT_OFFSET 0xff
+#define BIT_AMPDU_TXRPT_OFFSET(x) \
+ (((x) & BIT_MASK_AMPDU_TXRPT_OFFSET) << BIT_SHIFT_AMPDU_TXRPT_OFFSET)
+#define BIT_GET_AMPDU_TXRPT_OFFSET(x) \
+ (((x) >> BIT_SHIFT_AMPDU_TXRPT_OFFSET) & BIT_MASK_AMPDU_TXRPT_OFFSET)
+
+/* 2 REG_POWER_STAGE1 (Offset 0x04B4) */
+
+#define BIT_PTA_WL_PRI_MASK_CPU_MGQ BIT(31)
+#define BIT_PTA_WL_PRI_MASK_BCNQ BIT(30)
+#define BIT_PTA_WL_PRI_MASK_HIQ BIT(29)
+#define BIT_PTA_WL_PRI_MASK_MGQ BIT(28)
+#define BIT_PTA_WL_PRI_MASK_BK BIT(27)
+#define BIT_PTA_WL_PRI_MASK_BE BIT(26)
+#define BIT_PTA_WL_PRI_MASK_VI BIT(25)
+#define BIT_PTA_WL_PRI_MASK_VO BIT(24)
+
+/* 2 REG_POWER_STAGE1 (Offset 0x04B4) */
+
+#define BIT_SHIFT_POWER_STAGE1 0
+#define BIT_MASK_POWER_STAGE1 0xffffff
+#define BIT_POWER_STAGE1(x) \
+ (((x) & BIT_MASK_POWER_STAGE1) << BIT_SHIFT_POWER_STAGE1)
+#define BIT_GET_POWER_STAGE1(x) \
+ (((x) >> BIT_SHIFT_POWER_STAGE1) & BIT_MASK_POWER_STAGE1)
+
+/* 2 REG_POWER_STAGE2 (Offset 0x04B8) */
+
+#define BIT__R_CTRL_PKT_POW_ADJ BIT(24)
+
+/* 2 REG_POWER_STAGE2 (Offset 0x04B8) */
+
+#define BIT_SHIFT_POWER_STAGE2 0
+#define BIT_MASK_POWER_STAGE2 0xffffff
+#define BIT_POWER_STAGE2(x) \
+ (((x) & BIT_MASK_POWER_STAGE2) << BIT_SHIFT_POWER_STAGE2)
+#define BIT_GET_POWER_STAGE2(x) \
+ (((x) >> BIT_SHIFT_POWER_STAGE2) & BIT_MASK_POWER_STAGE2)
+
+/* 2 REG_SW_AMPDU_BURST_MODE_CTRL (Offset 0x04BC) */
+
+#define BIT_SHIFT_PAD_NUM_THRES 24
+#define BIT_MASK_PAD_NUM_THRES 0x3f
+#define BIT_PAD_NUM_THRES(x) \
+ (((x) & BIT_MASK_PAD_NUM_THRES) << BIT_SHIFT_PAD_NUM_THRES)
+#define BIT_GET_PAD_NUM_THRES(x) \
+ (((x) >> BIT_SHIFT_PAD_NUM_THRES) & BIT_MASK_PAD_NUM_THRES)
+
+/* 2 REG_SW_AMPDU_BURST_MODE_CTRL (Offset 0x04BC) */
+
+#define BIT_R_DMA_THIS_QUEUE_BK BIT(23)
+#define BIT_R_DMA_THIS_QUEUE_BE BIT(22)
+#define BIT_R_DMA_THIS_QUEUE_VI BIT(21)
+#define BIT_R_DMA_THIS_QUEUE_VO BIT(20)
+
+#define BIT_SHIFT_R_TOTAL_LEN_TH 8
+#define BIT_MASK_R_TOTAL_LEN_TH 0xfff
+#define BIT_R_TOTAL_LEN_TH(x) \
+ (((x) & BIT_MASK_R_TOTAL_LEN_TH) << BIT_SHIFT_R_TOTAL_LEN_TH)
+#define BIT_GET_R_TOTAL_LEN_TH(x) \
+ (((x) >> BIT_SHIFT_R_TOTAL_LEN_TH) & BIT_MASK_R_TOTAL_LEN_TH)
+
+/* 2 REG_SW_AMPDU_BURST_MODE_CTRL (Offset 0x04BC) */
+
+#define BIT_EN_NEW_EARLY BIT(7)
+
+/* 2 REG_SW_AMPDU_BURST_MODE_CTRL (Offset 0x04BC) */
+
+#define BIT_PRE_TX_CMD BIT(6)
+
+#define BIT_SHIFT_NUM_SCL_EN 4
+#define BIT_MASK_NUM_SCL_EN 0x3
+#define BIT_NUM_SCL_EN(x) (((x) & BIT_MASK_NUM_SCL_EN) << BIT_SHIFT_NUM_SCL_EN)
+#define BIT_GET_NUM_SCL_EN(x) \
+ (((x) >> BIT_SHIFT_NUM_SCL_EN) & BIT_MASK_NUM_SCL_EN)
+
+#define BIT_BK_EN BIT(3)
+#define BIT_BE_EN BIT(2)
+#define BIT_VI_EN BIT(1)
+#define BIT_VO_EN BIT(0)
+
+/* 2 REG_PKT_LIFE_TIME (Offset 0x04C0) */
+
+#define BIT_SHIFT_PKT_LIFTIME_BEBK 16
+#define BIT_MASK_PKT_LIFTIME_BEBK 0xffff
+#define BIT_PKT_LIFTIME_BEBK(x) \
+ (((x) & BIT_MASK_PKT_LIFTIME_BEBK) << BIT_SHIFT_PKT_LIFTIME_BEBK)
+#define BIT_GET_PKT_LIFTIME_BEBK(x) \
+ (((x) >> BIT_SHIFT_PKT_LIFTIME_BEBK) & BIT_MASK_PKT_LIFTIME_BEBK)
+
+#define BIT_SHIFT_PKT_LIFTIME_VOVI 0
+#define BIT_MASK_PKT_LIFTIME_VOVI 0xffff
+#define BIT_PKT_LIFTIME_VOVI(x) \
+ (((x) & BIT_MASK_PKT_LIFTIME_VOVI) << BIT_SHIFT_PKT_LIFTIME_VOVI)
+#define BIT_GET_PKT_LIFTIME_VOVI(x) \
+ (((x) >> BIT_SHIFT_PKT_LIFTIME_VOVI) & BIT_MASK_PKT_LIFTIME_VOVI)
+
+/* 2 REG_STBC_SETTING (Offset 0x04C4) */
+
+#define BIT_SHIFT_CDEND_TXTIME_L 4
+#define BIT_MASK_CDEND_TXTIME_L 0xf
+#define BIT_CDEND_TXTIME_L(x) \
+ (((x) & BIT_MASK_CDEND_TXTIME_L) << BIT_SHIFT_CDEND_TXTIME_L)
+#define BIT_GET_CDEND_TXTIME_L(x) \
+ (((x) >> BIT_SHIFT_CDEND_TXTIME_L) & BIT_MASK_CDEND_TXTIME_L)
+
+#define BIT_SHIFT_NESS 2
+#define BIT_MASK_NESS 0x3
+#define BIT_NESS(x) (((x) & BIT_MASK_NESS) << BIT_SHIFT_NESS)
+#define BIT_GET_NESS(x) (((x) >> BIT_SHIFT_NESS) & BIT_MASK_NESS)
+
+#define BIT_SHIFT_STBC_CFEND 0
+#define BIT_MASK_STBC_CFEND 0x3
+#define BIT_STBC_CFEND(x) (((x) & BIT_MASK_STBC_CFEND) << BIT_SHIFT_STBC_CFEND)
+#define BIT_GET_STBC_CFEND(x) \
+ (((x) >> BIT_SHIFT_STBC_CFEND) & BIT_MASK_STBC_CFEND)
+
+/* 2 REG_STBC_SETTING2 (Offset 0x04C5) */
+
+#define BIT_SHIFT_CDEND_TXTIME_H 0
+#define BIT_MASK_CDEND_TXTIME_H 0x1f
+#define BIT_CDEND_TXTIME_H(x) \
+ (((x) & BIT_MASK_CDEND_TXTIME_H) << BIT_SHIFT_CDEND_TXTIME_H)
+#define BIT_GET_CDEND_TXTIME_H(x) \
+ (((x) >> BIT_SHIFT_CDEND_TXTIME_H) & BIT_MASK_CDEND_TXTIME_H)
+
+/* 2 REG_QUEUE_CTRL (Offset 0x04C6) */
+
+#define BIT_PTA_EDCCA_EN BIT(5)
+#define BIT_PTA_WL_TX_EN BIT(4)
+
+/* 2 REG_QUEUE_CTRL (Offset 0x04C6) */
+
+#define BIT_R_USE_DATA_BW BIT(3)
+#define BIT_TRI_PKT_INT_MODE1 BIT(2)
+#define BIT_TRI_PKT_INT_MODE0 BIT(1)
+#define BIT_ACQ_MODE_SEL BIT(0)
+
+/* 2 REG_SINGLE_AMPDU_CTRL (Offset 0x04C7) */
+
+#define BIT_EN_SINGLE_APMDU BIT(7)
+
+/* 2 REG_PROT_MODE_CTRL (Offset 0x04C8) */
+
+#define BIT_SHIFT_RTS_MAX_AGG_NUM 24
+#define BIT_MASK_RTS_MAX_AGG_NUM 0x3f
+#define BIT_RTS_MAX_AGG_NUM(x) \
+ (((x) & BIT_MASK_RTS_MAX_AGG_NUM) << BIT_SHIFT_RTS_MAX_AGG_NUM)
+#define BIT_GET_RTS_MAX_AGG_NUM(x) \
+ (((x) >> BIT_SHIFT_RTS_MAX_AGG_NUM) & BIT_MASK_RTS_MAX_AGG_NUM)
+
+#define BIT_SHIFT_MAX_AGG_NUM 16
+#define BIT_MASK_MAX_AGG_NUM 0x3f
+#define BIT_MAX_AGG_NUM(x) \
+ (((x) & BIT_MASK_MAX_AGG_NUM) << BIT_SHIFT_MAX_AGG_NUM)
+#define BIT_GET_MAX_AGG_NUM(x) \
+ (((x) >> BIT_SHIFT_MAX_AGG_NUM) & BIT_MASK_MAX_AGG_NUM)
+
+#define BIT_SHIFT_RTS_TXTIME_TH 8
+#define BIT_MASK_RTS_TXTIME_TH 0xff
+#define BIT_RTS_TXTIME_TH(x) \
+ (((x) & BIT_MASK_RTS_TXTIME_TH) << BIT_SHIFT_RTS_TXTIME_TH)
+#define BIT_GET_RTS_TXTIME_TH(x) \
+ (((x) >> BIT_SHIFT_RTS_TXTIME_TH) & BIT_MASK_RTS_TXTIME_TH)
+
+#define BIT_SHIFT_RTS_LEN_TH 0
+#define BIT_MASK_RTS_LEN_TH 0xff
+#define BIT_RTS_LEN_TH(x) (((x) & BIT_MASK_RTS_LEN_TH) << BIT_SHIFT_RTS_LEN_TH)
+#define BIT_GET_RTS_LEN_TH(x) \
+ (((x) >> BIT_SHIFT_RTS_LEN_TH) & BIT_MASK_RTS_LEN_TH)
+
+/* 2 REG_BAR_MODE_CTRL (Offset 0x04CC) */
+
+#define BIT_SHIFT_BAR_RTY_LMT 16
+#define BIT_MASK_BAR_RTY_LMT 0x3
+#define BIT_BAR_RTY_LMT(x) \
+ (((x) & BIT_MASK_BAR_RTY_LMT) << BIT_SHIFT_BAR_RTY_LMT)
+#define BIT_GET_BAR_RTY_LMT(x) \
+ (((x) >> BIT_SHIFT_BAR_RTY_LMT) & BIT_MASK_BAR_RTY_LMT)
+
+#define BIT_SHIFT_BAR_PKT_TXTIME_TH 8
+#define BIT_MASK_BAR_PKT_TXTIME_TH 0xff
+#define BIT_BAR_PKT_TXTIME_TH(x) \
+ (((x) & BIT_MASK_BAR_PKT_TXTIME_TH) << BIT_SHIFT_BAR_PKT_TXTIME_TH)
+#define BIT_GET_BAR_PKT_TXTIME_TH(x) \
+ (((x) >> BIT_SHIFT_BAR_PKT_TXTIME_TH) & BIT_MASK_BAR_PKT_TXTIME_TH)
+
+#define BIT_BAR_EN_V1 BIT(6)
+
+#define BIT_SHIFT_BAR_PKTNUM_TH_V1 0
+#define BIT_MASK_BAR_PKTNUM_TH_V1 0x3f
+#define BIT_BAR_PKTNUM_TH_V1(x) \
+ (((x) & BIT_MASK_BAR_PKTNUM_TH_V1) << BIT_SHIFT_BAR_PKTNUM_TH_V1)
+#define BIT_GET_BAR_PKTNUM_TH_V1(x) \
+ (((x) >> BIT_SHIFT_BAR_PKTNUM_TH_V1) & BIT_MASK_BAR_PKTNUM_TH_V1)
+
+/* 2 REG_RA_TRY_RATE_AGG_LMT (Offset 0x04CF) */
+
+#define BIT_SHIFT_RA_TRY_RATE_AGG_LMT_V1 0
+#define BIT_MASK_RA_TRY_RATE_AGG_LMT_V1 0x3f
+#define BIT_RA_TRY_RATE_AGG_LMT_V1(x) \
+ (((x) & BIT_MASK_RA_TRY_RATE_AGG_LMT_V1) \
+ << BIT_SHIFT_RA_TRY_RATE_AGG_LMT_V1)
+#define BIT_GET_RA_TRY_RATE_AGG_LMT_V1(x) \
+ (((x) >> BIT_SHIFT_RA_TRY_RATE_AGG_LMT_V1) & \
+ BIT_MASK_RA_TRY_RATE_AGG_LMT_V1)
+
+/* 2 REG_MACID_SLEEP2 (Offset 0x04D0) */
+
+#define BIT_SHIFT_MACID95_64PKTSLEEP 0
+#define BIT_MASK_MACID95_64PKTSLEEP 0xffffffffL
+#define BIT_MACID95_64PKTSLEEP(x) \
+ (((x) & BIT_MASK_MACID95_64PKTSLEEP) << BIT_SHIFT_MACID95_64PKTSLEEP)
+#define BIT_GET_MACID95_64PKTSLEEP(x) \
+ (((x) >> BIT_SHIFT_MACID95_64PKTSLEEP) & BIT_MASK_MACID95_64PKTSLEEP)
+
+/* 2 REG_MACID_SLEEP (Offset 0x04D4) */
+
+#define BIT_SHIFT_MACID31_0_PKTSLEEP 0
+#define BIT_MASK_MACID31_0_PKTSLEEP 0xffffffffL
+#define BIT_MACID31_0_PKTSLEEP(x) \
+ (((x) & BIT_MASK_MACID31_0_PKTSLEEP) << BIT_SHIFT_MACID31_0_PKTSLEEP)
+#define BIT_GET_MACID31_0_PKTSLEEP(x) \
+ (((x) >> BIT_SHIFT_MACID31_0_PKTSLEEP) & BIT_MASK_MACID31_0_PKTSLEEP)
+
+/* 2 REG_HW_SEQ0 (Offset 0x04D8) */
+
+#define BIT_SHIFT_HW_SSN_SEQ0 0
+#define BIT_MASK_HW_SSN_SEQ0 0xfff
+#define BIT_HW_SSN_SEQ0(x) \
+ (((x) & BIT_MASK_HW_SSN_SEQ0) << BIT_SHIFT_HW_SSN_SEQ0)
+#define BIT_GET_HW_SSN_SEQ0(x) \
+ (((x) >> BIT_SHIFT_HW_SSN_SEQ0) & BIT_MASK_HW_SSN_SEQ0)
+
+/* 2 REG_HW_SEQ1 (Offset 0x04DA) */
+
+#define BIT_SHIFT_HW_SSN_SEQ1 0
+#define BIT_MASK_HW_SSN_SEQ1 0xfff
+#define BIT_HW_SSN_SEQ1(x) \
+ (((x) & BIT_MASK_HW_SSN_SEQ1) << BIT_SHIFT_HW_SSN_SEQ1)
+#define BIT_GET_HW_SSN_SEQ1(x) \
+ (((x) >> BIT_SHIFT_HW_SSN_SEQ1) & BIT_MASK_HW_SSN_SEQ1)
+
+/* 2 REG_HW_SEQ2 (Offset 0x04DC) */
+
+#define BIT_SHIFT_HW_SSN_SEQ2 0
+#define BIT_MASK_HW_SSN_SEQ2 0xfff
+#define BIT_HW_SSN_SEQ2(x) \
+ (((x) & BIT_MASK_HW_SSN_SEQ2) << BIT_SHIFT_HW_SSN_SEQ2)
+#define BIT_GET_HW_SSN_SEQ2(x) \
+ (((x) >> BIT_SHIFT_HW_SSN_SEQ2) & BIT_MASK_HW_SSN_SEQ2)
+
+/* 2 REG_HW_SEQ3 (Offset 0x04DE) */
+
+#define BIT_SHIFT_HW_SSN_SEQ3 0
+#define BIT_MASK_HW_SSN_SEQ3 0xfff
+#define BIT_HW_SSN_SEQ3(x) \
+ (((x) & BIT_MASK_HW_SSN_SEQ3) << BIT_SHIFT_HW_SSN_SEQ3)
+#define BIT_GET_HW_SSN_SEQ3(x) \
+ (((x) >> BIT_SHIFT_HW_SSN_SEQ3) & BIT_MASK_HW_SSN_SEQ3)
+
+/* 2 REG_NULL_PKT_STATUS_V1 (Offset 0x04E0) */
+
+#define BIT_SHIFT_PTCL_TOTAL_PG_V2 2
+#define BIT_MASK_PTCL_TOTAL_PG_V2 0x3fff
+#define BIT_PTCL_TOTAL_PG_V2(x) \
+ (((x) & BIT_MASK_PTCL_TOTAL_PG_V2) << BIT_SHIFT_PTCL_TOTAL_PG_V2)
+#define BIT_GET_PTCL_TOTAL_PG_V2(x) \
+ (((x) >> BIT_SHIFT_PTCL_TOTAL_PG_V2) & BIT_MASK_PTCL_TOTAL_PG_V2)
+
+/* 2 REG_NULL_PKT_STATUS (Offset 0x04E0) */
+
+#define BIT_TX_NULL_1 BIT(1)
+#define BIT_TX_NULL_0 BIT(0)
+
+/* 2 REG_PTCL_ERR_STATUS (Offset 0x04E2) */
+
+#define BIT_PTCL_RATE_TABLE_INVALID BIT(7)
+#define BIT_FTM_T2R_ERROR BIT(6)
+
+/* 2 REG_PTCL_ERR_STATUS (Offset 0x04E2) */
+
+#define BIT_PTCL_ERR0 BIT(5)
+#define BIT_PTCL_ERR1 BIT(4)
+#define BIT_PTCL_ERR2 BIT(3)
+#define BIT_PTCL_ERR3 BIT(2)
+#define BIT_PTCL_ERR4 BIT(1)
+#define BIT_PTCL_ERR5 BIT(0)
+
+/* 2 REG_NULL_PKT_STATUS_EXTEND (Offset 0x04E3) */
+
+#define BIT_CLI3_TX_NULL_1 BIT(7)
+#define BIT_CLI3_TX_NULL_0 BIT(6)
+#define BIT_CLI2_TX_NULL_1 BIT(5)
+#define BIT_CLI2_TX_NULL_0 BIT(4)
+#define BIT_CLI1_TX_NULL_1 BIT(3)
+#define BIT_CLI1_TX_NULL_0 BIT(2)
+#define BIT_CLI0_TX_NULL_1 BIT(1)
+
+/* 2 REG_NULL_PKT_STATUS_EXTEND (Offset 0x04E3) */
+
+#define BIT_CLI0_TX_NULL_0 BIT(0)
+
+/* 2 REG_VIDEO_ENHANCEMENT_FUN (Offset 0x04E4) */
+
+#define BIT_VIDEO_JUST_DROP BIT(1)
+#define BIT_VIDEO_ENHANCEMENT_FUN_EN BIT(0)
+
+/* 2 REG_BT_POLLUTE_PKT_CNT (Offset 0x04E8) */
+
+#define BIT_SHIFT_BT_POLLUTE_PKT_CNT 0
+#define BIT_MASK_BT_POLLUTE_PKT_CNT 0xffff
+#define BIT_BT_POLLUTE_PKT_CNT(x) \
+ (((x) & BIT_MASK_BT_POLLUTE_PKT_CNT) << BIT_SHIFT_BT_POLLUTE_PKT_CNT)
+#define BIT_GET_BT_POLLUTE_PKT_CNT(x) \
+ (((x) >> BIT_SHIFT_BT_POLLUTE_PKT_CNT) & BIT_MASK_BT_POLLUTE_PKT_CNT)
+
+/* 2 REG_PTCL_DBG (Offset 0x04EC) */
+
+#define BIT_SHIFT_PTCL_DBG 0
+#define BIT_MASK_PTCL_DBG 0xffffffffL
+#define BIT_PTCL_DBG(x) (((x) & BIT_MASK_PTCL_DBG) << BIT_SHIFT_PTCL_DBG)
+#define BIT_GET_PTCL_DBG(x) (((x) >> BIT_SHIFT_PTCL_DBG) & BIT_MASK_PTCL_DBG)
+
+/* 2 REG_CPUMGQ_TIMER_CTRL2 (Offset 0x04F4) */
+
+#define BIT_QUEUE_MACID_AC_NOT_THE_SAME BIT(31)
+
+#define BIT_SHIFT_GTAB_ID 28
+#define BIT_MASK_GTAB_ID 0x7
+#define BIT_GTAB_ID(x) (((x) & BIT_MASK_GTAB_ID) << BIT_SHIFT_GTAB_ID)
+#define BIT_GET_GTAB_ID(x) (((x) >> BIT_SHIFT_GTAB_ID) & BIT_MASK_GTAB_ID)
+
+#define BIT_SHIFT_TRI_HEAD_ADDR 16
+#define BIT_MASK_TRI_HEAD_ADDR 0xfff
+#define BIT_TRI_HEAD_ADDR(x) \
+ (((x) & BIT_MASK_TRI_HEAD_ADDR) << BIT_SHIFT_TRI_HEAD_ADDR)
+#define BIT_GET_TRI_HEAD_ADDR(x) \
+ (((x) >> BIT_SHIFT_TRI_HEAD_ADDR) & BIT_MASK_TRI_HEAD_ADDR)
+
+#define BIT_QUEUE_MACID_AC_NOT_THE_SAME_V1 BIT(15)
+
+#define BIT_SHIFT_GTAB_ID_V1 12
+#define BIT_MASK_GTAB_ID_V1 0x7
+#define BIT_GTAB_ID_V1(x) (((x) & BIT_MASK_GTAB_ID_V1) << BIT_SHIFT_GTAB_ID_V1)
+#define BIT_GET_GTAB_ID_V1(x) \
+ (((x) >> BIT_SHIFT_GTAB_ID_V1) & BIT_MASK_GTAB_ID_V1)
+
+#define BIT_DROP_TH_EN BIT(8)
+
+#define BIT_SHIFT_DROP_TH 0
+#define BIT_MASK_DROP_TH 0xff
+#define BIT_DROP_TH(x) (((x) & BIT_MASK_DROP_TH) << BIT_SHIFT_DROP_TH)
+#define BIT_GET_DROP_TH(x) (((x) >> BIT_SHIFT_DROP_TH) & BIT_MASK_DROP_TH)
+
+/* 2 REG_DUMMY_PAGE4_V1 (Offset 0x04FC) */
+
+#define BIT_BCN_EN_EXTHWSEQ BIT(1)
+#define BIT_BCN_EN_HWSEQ BIT(0)
+
+/* 2 REG_MOREDATA (Offset 0x04FE) */
+
+#define BIT_MOREDATA_CTRL2_EN_V1 BIT(3)
+#define BIT_MOREDATA_CTRL1_EN_V1 BIT(2)
+#define BIT_PKTIN_MOREDATA_REPLACE_ENABLE_V1 BIT(0)
+
+/* 2 REG_EDCA_VO_PARAM (Offset 0x0500) */
+
+#define BIT_SHIFT_TXOPLIMIT 16
+#define BIT_MASK_TXOPLIMIT 0x7ff
+#define BIT_TXOPLIMIT(x) (((x) & BIT_MASK_TXOPLIMIT) << BIT_SHIFT_TXOPLIMIT)
+#define BIT_GET_TXOPLIMIT(x) (((x) >> BIT_SHIFT_TXOPLIMIT) & BIT_MASK_TXOPLIMIT)
+
+#define BIT_SHIFT_CW 8
+#define BIT_MASK_CW 0xff
+#define BIT_CW(x) (((x) & BIT_MASK_CW) << BIT_SHIFT_CW)
+#define BIT_GET_CW(x) (((x) >> BIT_SHIFT_CW) & BIT_MASK_CW)
+
+#define BIT_SHIFT_AIFS 0
+#define BIT_MASK_AIFS 0xff
+#define BIT_AIFS(x) (((x) & BIT_MASK_AIFS) << BIT_SHIFT_AIFS)
+#define BIT_GET_AIFS(x) (((x) >> BIT_SHIFT_AIFS) & BIT_MASK_AIFS)
+
+/* 2 REG_BCNTCFG (Offset 0x0510) */
+
+#define BIT_SHIFT_BCNCW_MAX 12
+#define BIT_MASK_BCNCW_MAX 0xf
+#define BIT_BCNCW_MAX(x) (((x) & BIT_MASK_BCNCW_MAX) << BIT_SHIFT_BCNCW_MAX)
+#define BIT_GET_BCNCW_MAX(x) (((x) >> BIT_SHIFT_BCNCW_MAX) & BIT_MASK_BCNCW_MAX)
+
+#define BIT_SHIFT_BCNCW_MIN 8
+#define BIT_MASK_BCNCW_MIN 0xf
+#define BIT_BCNCW_MIN(x) (((x) & BIT_MASK_BCNCW_MIN) << BIT_SHIFT_BCNCW_MIN)
+#define BIT_GET_BCNCW_MIN(x) (((x) >> BIT_SHIFT_BCNCW_MIN) & BIT_MASK_BCNCW_MIN)
+
+#define BIT_SHIFT_BCNIFS 0
+#define BIT_MASK_BCNIFS 0xff
+#define BIT_BCNIFS(x) (((x) & BIT_MASK_BCNIFS) << BIT_SHIFT_BCNIFS)
+#define BIT_GET_BCNIFS(x) (((x) >> BIT_SHIFT_BCNIFS) & BIT_MASK_BCNIFS)
+
+/* 2 REG_PIFS (Offset 0x0512) */
+
+#define BIT_SHIFT_PIFS 0
+#define BIT_MASK_PIFS 0xff
+#define BIT_PIFS(x) (((x) & BIT_MASK_PIFS) << BIT_SHIFT_PIFS)
+#define BIT_GET_PIFS(x) (((x) >> BIT_SHIFT_PIFS) & BIT_MASK_PIFS)
+
+/* 2 REG_RDG_PIFS (Offset 0x0513) */
+
+#define BIT_SHIFT_RDG_PIFS 0
+#define BIT_MASK_RDG_PIFS 0xff
+#define BIT_RDG_PIFS(x) (((x) & BIT_MASK_RDG_PIFS) << BIT_SHIFT_RDG_PIFS)
+#define BIT_GET_RDG_PIFS(x) (((x) >> BIT_SHIFT_RDG_PIFS) & BIT_MASK_RDG_PIFS)
+
+/* 2 REG_SIFS (Offset 0x0514) */
+
+#define BIT_SHIFT_SIFS_OFDM_TRX 24
+#define BIT_MASK_SIFS_OFDM_TRX 0xff
+#define BIT_SIFS_OFDM_TRX(x) \
+ (((x) & BIT_MASK_SIFS_OFDM_TRX) << BIT_SHIFT_SIFS_OFDM_TRX)
+#define BIT_GET_SIFS_OFDM_TRX(x) \
+ (((x) >> BIT_SHIFT_SIFS_OFDM_TRX) & BIT_MASK_SIFS_OFDM_TRX)
+
+#define BIT_SHIFT_SIFS_CCK_TRX 16
+#define BIT_MASK_SIFS_CCK_TRX 0xff
+#define BIT_SIFS_CCK_TRX(x) \
+ (((x) & BIT_MASK_SIFS_CCK_TRX) << BIT_SHIFT_SIFS_CCK_TRX)
+#define BIT_GET_SIFS_CCK_TRX(x) \
+ (((x) >> BIT_SHIFT_SIFS_CCK_TRX) & BIT_MASK_SIFS_CCK_TRX)
+
+#define BIT_SHIFT_SIFS_OFDM_CTX 8
+#define BIT_MASK_SIFS_OFDM_CTX 0xff
+#define BIT_SIFS_OFDM_CTX(x) \
+ (((x) & BIT_MASK_SIFS_OFDM_CTX) << BIT_SHIFT_SIFS_OFDM_CTX)
+#define BIT_GET_SIFS_OFDM_CTX(x) \
+ (((x) >> BIT_SHIFT_SIFS_OFDM_CTX) & BIT_MASK_SIFS_OFDM_CTX)
+
+#define BIT_SHIFT_SIFS_CCK_CTX 0
+#define BIT_MASK_SIFS_CCK_CTX 0xff
+#define BIT_SIFS_CCK_CTX(x) \
+ (((x) & BIT_MASK_SIFS_CCK_CTX) << BIT_SHIFT_SIFS_CCK_CTX)
+#define BIT_GET_SIFS_CCK_CTX(x) \
+ (((x) >> BIT_SHIFT_SIFS_CCK_CTX) & BIT_MASK_SIFS_CCK_CTX)
+
+/* 2 REG_TSFTR_SYN_OFFSET (Offset 0x0518) */
+
+#define BIT_SHIFT_TSFTR_SNC_OFFSET 0
+#define BIT_MASK_TSFTR_SNC_OFFSET 0xffff
+#define BIT_TSFTR_SNC_OFFSET(x) \
+ (((x) & BIT_MASK_TSFTR_SNC_OFFSET) << BIT_SHIFT_TSFTR_SNC_OFFSET)
+#define BIT_GET_TSFTR_SNC_OFFSET(x) \
+ (((x) >> BIT_SHIFT_TSFTR_SNC_OFFSET) & BIT_MASK_TSFTR_SNC_OFFSET)
+
+/* 2 REG_AGGR_BREAK_TIME (Offset 0x051A) */
+
+#define BIT_SHIFT_AGGR_BK_TIME 0
+#define BIT_MASK_AGGR_BK_TIME 0xff
+#define BIT_AGGR_BK_TIME(x) \
+ (((x) & BIT_MASK_AGGR_BK_TIME) << BIT_SHIFT_AGGR_BK_TIME)
+#define BIT_GET_AGGR_BK_TIME(x) \
+ (((x) >> BIT_SHIFT_AGGR_BK_TIME) & BIT_MASK_AGGR_BK_TIME)
+
+/* 2 REG_SLOT (Offset 0x051B) */
+
+#define BIT_SHIFT_SLOT 0
+#define BIT_MASK_SLOT 0xff
+#define BIT_SLOT(x) (((x) & BIT_MASK_SLOT) << BIT_SHIFT_SLOT)
+#define BIT_GET_SLOT(x) (((x) >> BIT_SHIFT_SLOT) & BIT_MASK_SLOT)
+
+/* 2 REG_TX_PTCL_CTRL (Offset 0x0520) */
+
+#define BIT_DIS_EDCCA BIT(15)
+#define BIT_DIS_CCA BIT(14)
+#define BIT_LSIG_TXOP_TXCMD_NAV BIT(13)
+#define BIT_SIFS_BK_EN BIT(12)
+
+#define BIT_SHIFT_TXQ_NAV_MSK 8
+#define BIT_MASK_TXQ_NAV_MSK 0xf
+#define BIT_TXQ_NAV_MSK(x) \
+ (((x) & BIT_MASK_TXQ_NAV_MSK) << BIT_SHIFT_TXQ_NAV_MSK)
+#define BIT_GET_TXQ_NAV_MSK(x) \
+ (((x) >> BIT_SHIFT_TXQ_NAV_MSK) & BIT_MASK_TXQ_NAV_MSK)
+
+#define BIT_DIS_CW BIT(7)
+#define BIT_NAV_END_TXOP BIT(6)
+#define BIT_RDG_END_TXOP BIT(5)
+#define BIT_AC_INBCN_HOLD BIT(4)
+#define BIT_MGTQ_TXOP_EN BIT(3)
+#define BIT_MGTQ_RTSMF_EN BIT(2)
+#define BIT_HIQ_RTSMF_EN BIT(1)
+#define BIT_BCN_RTSMF_EN BIT(0)
+
+/* 2 REG_TXPAUSE (Offset 0x0522) */
+
+#define BIT_STOP_BCN_HI_MGT BIT(7)
+#define BIT_MAC_STOPBCNQ BIT(6)
+#define BIT_MAC_STOPHIQ BIT(5)
+#define BIT_MAC_STOPMGQ BIT(4)
+#define BIT_MAC_STOPBK BIT(3)
+#define BIT_MAC_STOPBE BIT(2)
+#define BIT_MAC_STOPVI BIT(1)
+#define BIT_MAC_STOPVO BIT(0)
+
+/* 2 REG_DIS_TXREQ_CLR (Offset 0x0523) */
+
+#define BIT_DIS_BT_CCA BIT(7)
+
+/* 2 REG_DIS_TXREQ_CLR (Offset 0x0523) */
+
+#define BIT_DIS_TXREQ_CLR_HI BIT(5)
+#define BIT_DIS_TXREQ_CLR_MGQ BIT(4)
+#define BIT_DIS_TXREQ_CLR_VO BIT(3)
+#define BIT_DIS_TXREQ_CLR_VI BIT(2)
+#define BIT_DIS_TXREQ_CLR_BE BIT(1)
+#define BIT_DIS_TXREQ_CLR_BK BIT(0)
+
+/* 2 REG_RD_CTRL (Offset 0x0524) */
+
+#define BIT_EN_CLR_TXREQ_INCCA BIT(15)
+#define BIT_DIS_TX_OVER_BCNQ BIT(14)
+
+/* 2 REG_RD_CTRL (Offset 0x0524) */
+
+#define BIT_EN_BCNERR_INCCCA BIT(13)
+
+/* 2 REG_RD_CTRL (Offset 0x0524) */
+
+#define BIT_EDCCA_MSK_CNTDOWN_EN BIT(11)
+#define BIT_DIS_TXOP_CFE BIT(10)
+#define BIT_DIS_LSIG_CFE BIT(9)
+#define BIT_DIS_STBC_CFE BIT(8)
+#define BIT_BKQ_RD_INIT_EN BIT(7)
+#define BIT_BEQ_RD_INIT_EN BIT(6)
+#define BIT_VIQ_RD_INIT_EN BIT(5)
+#define BIT_VOQ_RD_INIT_EN BIT(4)
+#define BIT_BKQ_RD_RESP_EN BIT(3)
+#define BIT_BEQ_RD_RESP_EN BIT(2)
+#define BIT_VIQ_RD_RESP_EN BIT(1)
+#define BIT_VOQ_RD_RESP_EN BIT(0)
+
+/* 2 REG_MBSSID_CTRL (Offset 0x0526) */
+
+#define BIT_MBID_BCNQ7_EN BIT(7)
+#define BIT_MBID_BCNQ6_EN BIT(6)
+#define BIT_MBID_BCNQ5_EN BIT(5)
+#define BIT_MBID_BCNQ4_EN BIT(4)
+#define BIT_MBID_BCNQ3_EN BIT(3)
+#define BIT_MBID_BCNQ2_EN BIT(2)
+#define BIT_MBID_BCNQ1_EN BIT(1)
+#define BIT_MBID_BCNQ0_EN BIT(0)
+
+/* 2 REG_P2PPS_CTRL (Offset 0x0527) */
+
+#define BIT_P2P_CTW_ALLSTASLEEP BIT(7)
+#define BIT_P2P_OFF_DISTX_EN BIT(6)
+#define BIT_PWR_MGT_EN BIT(5)
+
+/* 2 REG_P2PPS_CTRL (Offset 0x0527) */
+
+#define BIT_P2P_NOA1_EN BIT(2)
+#define BIT_P2P_NOA0_EN BIT(1)
+
+/* 2 REG_PKT_LIFETIME_CTRL (Offset 0x0528) */
+
+#define BIT_EN_P2P_CTWND1 BIT(23)
+
+/* 2 REG_PKT_LIFETIME_CTRL (Offset 0x0528) */
+
+#define BIT_EN_BKF_CLR_TXREQ BIT(22)
+#define BIT_EN_TSFBIT32_RST_P2P BIT(21)
+#define BIT_EN_BCN_TX_BTCCA BIT(20)
+#define BIT_DIS_PKT_TX_ATIM BIT(19)
+#define BIT_DIS_BCN_DIS_CTN BIT(18)
+#define BIT_EN_NAVEND_RST_TXOP BIT(17)
+#define BIT_EN_FILTER_CCA BIT(16)
+
+#define BIT_SHIFT_CCA_FILTER_THRS 8
+#define BIT_MASK_CCA_FILTER_THRS 0xff
+#define BIT_CCA_FILTER_THRS(x) \
+ (((x) & BIT_MASK_CCA_FILTER_THRS) << BIT_SHIFT_CCA_FILTER_THRS)
+#define BIT_GET_CCA_FILTER_THRS(x) \
+ (((x) >> BIT_SHIFT_CCA_FILTER_THRS) & BIT_MASK_CCA_FILTER_THRS)
+
+#define BIT_SHIFT_EDCCA_THRS 0
+#define BIT_MASK_EDCCA_THRS 0xff
+#define BIT_EDCCA_THRS(x) (((x) & BIT_MASK_EDCCA_THRS) << BIT_SHIFT_EDCCA_THRS)
+#define BIT_GET_EDCCA_THRS(x) \
+ (((x) >> BIT_SHIFT_EDCCA_THRS) & BIT_MASK_EDCCA_THRS)
+
+/* 2 REG_P2PPS_SPEC_STATE (Offset 0x052B) */
+
+#define BIT_SPEC_POWER_STATE BIT(7)
+#define BIT_SPEC_CTWINDOW_ON BIT(6)
+#define BIT_SPEC_BEACON_AREA_ON BIT(5)
+#define BIT_SPEC_CTWIN_EARLY_DISTX BIT(4)
+#define BIT_SPEC_NOA1_OFF_PERIOD BIT(3)
+#define BIT_SPEC_FORCE_DOZE1 BIT(2)
+#define BIT_SPEC_NOA0_OFF_PERIOD BIT(1)
+#define BIT_SPEC_FORCE_DOZE0 BIT(0)
+
+/* 2 REG_QUEUE_INCOL_THR (Offset 0x0538) */
+
+#define BIT_SHIFT_BK_QUEUE_THR 24
+#define BIT_MASK_BK_QUEUE_THR 0xff
+#define BIT_BK_QUEUE_THR(x) \
+ (((x) & BIT_MASK_BK_QUEUE_THR) << BIT_SHIFT_BK_QUEUE_THR)
+#define BIT_GET_BK_QUEUE_THR(x) \
+ (((x) >> BIT_SHIFT_BK_QUEUE_THR) & BIT_MASK_BK_QUEUE_THR)
+
+#define BIT_SHIFT_BE_QUEUE_THR 16
+#define BIT_MASK_BE_QUEUE_THR 0xff
+#define BIT_BE_QUEUE_THR(x) \
+ (((x) & BIT_MASK_BE_QUEUE_THR) << BIT_SHIFT_BE_QUEUE_THR)
+#define BIT_GET_BE_QUEUE_THR(x) \
+ (((x) >> BIT_SHIFT_BE_QUEUE_THR) & BIT_MASK_BE_QUEUE_THR)
+
+#define BIT_SHIFT_VI_QUEUE_THR 8
+#define BIT_MASK_VI_QUEUE_THR 0xff
+#define BIT_VI_QUEUE_THR(x) \
+ (((x) & BIT_MASK_VI_QUEUE_THR) << BIT_SHIFT_VI_QUEUE_THR)
+#define BIT_GET_VI_QUEUE_THR(x) \
+ (((x) >> BIT_SHIFT_VI_QUEUE_THR) & BIT_MASK_VI_QUEUE_THR)
+
+#define BIT_SHIFT_VO_QUEUE_THR 0
+#define BIT_MASK_VO_QUEUE_THR 0xff
+#define BIT_VO_QUEUE_THR(x) \
+ (((x) & BIT_MASK_VO_QUEUE_THR) << BIT_SHIFT_VO_QUEUE_THR)
+#define BIT_GET_VO_QUEUE_THR(x) \
+ (((x) >> BIT_SHIFT_VO_QUEUE_THR) & BIT_MASK_VO_QUEUE_THR)
+
+/* 2 REG_QUEUE_INCOL_EN (Offset 0x053C) */
+
+#define BIT_QUEUE_INCOL_EN BIT(16)
+
+/* 2 REG_QUEUE_INCOL_EN (Offset 0x053C) */
+
+#define BIT_SHIFT_BE_TRIGGER_NUM 12
+#define BIT_MASK_BE_TRIGGER_NUM 0xf
+#define BIT_BE_TRIGGER_NUM(x) \
+ (((x) & BIT_MASK_BE_TRIGGER_NUM) << BIT_SHIFT_BE_TRIGGER_NUM)
+#define BIT_GET_BE_TRIGGER_NUM(x) \
+ (((x) >> BIT_SHIFT_BE_TRIGGER_NUM) & BIT_MASK_BE_TRIGGER_NUM)
+
+/* 2 REG_QUEUE_INCOL_EN (Offset 0x053C) */
+
+#define BIT_SHIFT_BK_TRIGGER_NUM 8
+#define BIT_MASK_BK_TRIGGER_NUM 0xf
+#define BIT_BK_TRIGGER_NUM(x) \
+ (((x) & BIT_MASK_BK_TRIGGER_NUM) << BIT_SHIFT_BK_TRIGGER_NUM)
+#define BIT_GET_BK_TRIGGER_NUM(x) \
+ (((x) >> BIT_SHIFT_BK_TRIGGER_NUM) & BIT_MASK_BK_TRIGGER_NUM)
+
+/* 2 REG_QUEUE_INCOL_EN (Offset 0x053C) */
+
+#define BIT_SHIFT_VI_TRIGGER_NUM 4
+#define BIT_MASK_VI_TRIGGER_NUM 0xf
+#define BIT_VI_TRIGGER_NUM(x) \
+ (((x) & BIT_MASK_VI_TRIGGER_NUM) << BIT_SHIFT_VI_TRIGGER_NUM)
+#define BIT_GET_VI_TRIGGER_NUM(x) \
+ (((x) >> BIT_SHIFT_VI_TRIGGER_NUM) & BIT_MASK_VI_TRIGGER_NUM)
+
+#define BIT_SHIFT_VO_TRIGGER_NUM 0
+#define BIT_MASK_VO_TRIGGER_NUM 0xf
+#define BIT_VO_TRIGGER_NUM(x) \
+ (((x) & BIT_MASK_VO_TRIGGER_NUM) << BIT_SHIFT_VO_TRIGGER_NUM)
+#define BIT_GET_VO_TRIGGER_NUM(x) \
+ (((x) >> BIT_SHIFT_VO_TRIGGER_NUM) & BIT_MASK_VO_TRIGGER_NUM)
+
+/* 2 REG_TBTT_PROHIBIT (Offset 0x0540) */
+
+#define BIT_SHIFT_TBTT_HOLD_TIME_AP 8
+#define BIT_MASK_TBTT_HOLD_TIME_AP 0xfff
+#define BIT_TBTT_HOLD_TIME_AP(x) \
+ (((x) & BIT_MASK_TBTT_HOLD_TIME_AP) << BIT_SHIFT_TBTT_HOLD_TIME_AP)
+#define BIT_GET_TBTT_HOLD_TIME_AP(x) \
+ (((x) >> BIT_SHIFT_TBTT_HOLD_TIME_AP) & BIT_MASK_TBTT_HOLD_TIME_AP)
+
+/* 2 REG_TBTT_PROHIBIT (Offset 0x0540) */
+
+#define BIT_SHIFT_TBTT_PROHIBIT_SETUP 0
+#define BIT_MASK_TBTT_PROHIBIT_SETUP 0xf
+#define BIT_TBTT_PROHIBIT_SETUP(x) \
+ (((x) & BIT_MASK_TBTT_PROHIBIT_SETUP) << BIT_SHIFT_TBTT_PROHIBIT_SETUP)
+#define BIT_GET_TBTT_PROHIBIT_SETUP(x) \
+ (((x) >> BIT_SHIFT_TBTT_PROHIBIT_SETUP) & BIT_MASK_TBTT_PROHIBIT_SETUP)
+
+/* 2 REG_P2PPS_STATE (Offset 0x0543) */
+
+#define BIT_POWER_STATE BIT(7)
+#define BIT_CTWINDOW_ON BIT(6)
+#define BIT_BEACON_AREA_ON BIT(5)
+#define BIT_CTWIN_EARLY_DISTX BIT(4)
+#define BIT_NOA1_OFF_PERIOD BIT(3)
+#define BIT_FORCE_DOZE1 BIT(2)
+#define BIT_NOA0_OFF_PERIOD BIT(1)
+#define BIT_FORCE_DOZE0 BIT(0)
+
+/* 2 REG_RD_NAV_NXT (Offset 0x0544) */
+
+#define BIT_SHIFT_RD_NAV_PROT_NXT 0
+#define BIT_MASK_RD_NAV_PROT_NXT 0xffff
+#define BIT_RD_NAV_PROT_NXT(x) \
+ (((x) & BIT_MASK_RD_NAV_PROT_NXT) << BIT_SHIFT_RD_NAV_PROT_NXT)
+#define BIT_GET_RD_NAV_PROT_NXT(x) \
+ (((x) >> BIT_SHIFT_RD_NAV_PROT_NXT) & BIT_MASK_RD_NAV_PROT_NXT)
+
+/* 2 REG_NAV_PROT_LEN (Offset 0x0546) */
+
+#define BIT_SHIFT_NAV_PROT_LEN 0
+#define BIT_MASK_NAV_PROT_LEN 0xffff
+#define BIT_NAV_PROT_LEN(x) \
+ (((x) & BIT_MASK_NAV_PROT_LEN) << BIT_SHIFT_NAV_PROT_LEN)
+#define BIT_GET_NAV_PROT_LEN(x) \
+ (((x) >> BIT_SHIFT_NAV_PROT_LEN) & BIT_MASK_NAV_PROT_LEN)
+
+/* 2 REG_BCN_CTRL (Offset 0x0550) */
+
+#define BIT_DIS_RX_BSSID_FIT BIT(6)
+
+/* 2 REG_BCN_CTRL (Offset 0x0550) */
+
+#define BIT_P0_EN_TXBCN_RPT BIT(5)
+
+/* 2 REG_BCN_CTRL (Offset 0x0550) */
+
+#define BIT_DIS_TSF_UDT BIT(4)
+#define BIT_EN_BCN_FUNCTION BIT(3)
+
+/* 2 REG_BCN_CTRL (Offset 0x0550) */
+
+#define BIT_P0_EN_RXBCN_RPT BIT(2)
+
+/* 2 REG_BCN_CTRL (Offset 0x0550) */
+
+#define BIT_EN_P2P_CTWINDOW BIT(1)
+#define BIT_EN_P2P_BCNQ_AREA BIT(0)
+
+/* 2 REG_BCN_CTRL_CLINT0 (Offset 0x0551) */
+
+#define BIT_CLI0_DIS_RX_BSSID_FIT BIT(6)
+
+/* 2 REG_BCN_CTRL_CLINT0 (Offset 0x0551) */
+
+#define BIT_CLI0_DIS_TSF_UDT BIT(4)
+
+/* 2 REG_BCN_CTRL_CLINT0 (Offset 0x0551) */
+
+#define BIT_CLI0_EN_BCN_FUNCTION BIT(3)
+
+/* 2 REG_BCN_CTRL_CLINT0 (Offset 0x0551) */
+
+#define BIT_CLI0_EN_RXBCN_RPT BIT(2)
+
+/* 2 REG_BCN_CTRL_CLINT0 (Offset 0x0551) */
+
+#define BIT_CLI0_ENP2P_CTWINDOW BIT(1)
+#define BIT_CLI0_ENP2P_BCNQ_AREA BIT(0)
+
+/* 2 REG_MBID_NUM (Offset 0x0552) */
+
+#define BIT_EN_PRE_DL_BEACON BIT(3)
+
+#define BIT_SHIFT_MBID_BCN_NUM 0
+#define BIT_MASK_MBID_BCN_NUM 0x7
+#define BIT_MBID_BCN_NUM(x) \
+ (((x) & BIT_MASK_MBID_BCN_NUM) << BIT_SHIFT_MBID_BCN_NUM)
+#define BIT_GET_MBID_BCN_NUM(x) \
+ (((x) >> BIT_SHIFT_MBID_BCN_NUM) & BIT_MASK_MBID_BCN_NUM)
+
+/* 2 REG_DUAL_TSF_RST (Offset 0x0553) */
+
+#define BIT_FREECNT_RST BIT(5)
+
+/* 2 REG_DUAL_TSF_RST (Offset 0x0553) */
+
+#define BIT_TSFTR_CLI3_RST BIT(4)
+
+/* 2 REG_DUAL_TSF_RST (Offset 0x0553) */
+
+#define BIT_TSFTR_CLI2_RST BIT(3)
+
+/* 2 REG_DUAL_TSF_RST (Offset 0x0553) */
+
+#define BIT_TSFTR_CLI1_RST BIT(2)
+
+/* 2 REG_DUAL_TSF_RST (Offset 0x0553) */
+
+#define BIT_TSFTR_CLI0_RST BIT(1)
+
+/* 2 REG_DUAL_TSF_RST (Offset 0x0553) */
+
+#define BIT_TSFTR_RST BIT(0)
+
+/* 2 REG_MBSSID_BCN_SPACE (Offset 0x0554) */
+
+#define BIT_SHIFT_BCN_TIMER_SEL_FWRD 28
+#define BIT_MASK_BCN_TIMER_SEL_FWRD 0x7
+#define BIT_BCN_TIMER_SEL_FWRD(x) \
+ (((x) & BIT_MASK_BCN_TIMER_SEL_FWRD) << BIT_SHIFT_BCN_TIMER_SEL_FWRD)
+#define BIT_GET_BCN_TIMER_SEL_FWRD(x) \
+ (((x) >> BIT_SHIFT_BCN_TIMER_SEL_FWRD) & BIT_MASK_BCN_TIMER_SEL_FWRD)
+
+/* 2 REG_MBSSID_BCN_SPACE (Offset 0x0554) */
+
+#define BIT_SHIFT_BCN_SPACE_CLINT0 16
+#define BIT_MASK_BCN_SPACE_CLINT0 0xfff
+#define BIT_BCN_SPACE_CLINT0(x) \
+ (((x) & BIT_MASK_BCN_SPACE_CLINT0) << BIT_SHIFT_BCN_SPACE_CLINT0)
+#define BIT_GET_BCN_SPACE_CLINT0(x) \
+ (((x) >> BIT_SHIFT_BCN_SPACE_CLINT0) & BIT_MASK_BCN_SPACE_CLINT0)
+
+/* 2 REG_MBSSID_BCN_SPACE (Offset 0x0554) */
+
+#define BIT_SHIFT_BCN_SPACE0 0
+#define BIT_MASK_BCN_SPACE0 0xffff
+#define BIT_BCN_SPACE0(x) (((x) & BIT_MASK_BCN_SPACE0) << BIT_SHIFT_BCN_SPACE0)
+#define BIT_GET_BCN_SPACE0(x) \
+ (((x) >> BIT_SHIFT_BCN_SPACE0) & BIT_MASK_BCN_SPACE0)
+
+/* 2 REG_DRVERLYINT (Offset 0x0558) */
+
+#define BIT_SHIFT_DRVERLYITV 0
+#define BIT_MASK_DRVERLYITV 0xff
+#define BIT_DRVERLYITV(x) (((x) & BIT_MASK_DRVERLYITV) << BIT_SHIFT_DRVERLYITV)
+#define BIT_GET_DRVERLYITV(x) \
+ (((x) >> BIT_SHIFT_DRVERLYITV) & BIT_MASK_DRVERLYITV)
+
+/* 2 REG_BCNDMATIM (Offset 0x0559) */
+
+#define BIT_SHIFT_BCNDMATIM 0
+#define BIT_MASK_BCNDMATIM 0xff
+#define BIT_BCNDMATIM(x) (((x) & BIT_MASK_BCNDMATIM) << BIT_SHIFT_BCNDMATIM)
+#define BIT_GET_BCNDMATIM(x) (((x) >> BIT_SHIFT_BCNDMATIM) & BIT_MASK_BCNDMATIM)
+
+/* 2 REG_ATIMWND (Offset 0x055A) */
+
+#define BIT_SHIFT_ATIMWND0 0
+#define BIT_MASK_ATIMWND0 0xffff
+#define BIT_ATIMWND0(x) (((x) & BIT_MASK_ATIMWND0) << BIT_SHIFT_ATIMWND0)
+#define BIT_GET_ATIMWND0(x) (((x) >> BIT_SHIFT_ATIMWND0) & BIT_MASK_ATIMWND0)
+
+/* 2 REG_USTIME_TSF (Offset 0x055C) */
+
+#define BIT_SHIFT_USTIME_TSF_V1 0
+#define BIT_MASK_USTIME_TSF_V1 0xff
+#define BIT_USTIME_TSF_V1(x) \
+ (((x) & BIT_MASK_USTIME_TSF_V1) << BIT_SHIFT_USTIME_TSF_V1)
+#define BIT_GET_USTIME_TSF_V1(x) \
+ (((x) >> BIT_SHIFT_USTIME_TSF_V1) & BIT_MASK_USTIME_TSF_V1)
+
+/* 2 REG_BCN_MAX_ERR (Offset 0x055D) */
+
+#define BIT_SHIFT_BCN_MAX_ERR 0
+#define BIT_MASK_BCN_MAX_ERR 0xff
+#define BIT_BCN_MAX_ERR(x) \
+ (((x) & BIT_MASK_BCN_MAX_ERR) << BIT_SHIFT_BCN_MAX_ERR)
+#define BIT_GET_BCN_MAX_ERR(x) \
+ (((x) >> BIT_SHIFT_BCN_MAX_ERR) & BIT_MASK_BCN_MAX_ERR)
+
+/* 2 REG_RXTSF_OFFSET_CCK (Offset 0x055E) */
+
+#define BIT_SHIFT_CCK_RXTSF_OFFSET 0
+#define BIT_MASK_CCK_RXTSF_OFFSET 0xff
+#define BIT_CCK_RXTSF_OFFSET(x) \
+ (((x) & BIT_MASK_CCK_RXTSF_OFFSET) << BIT_SHIFT_CCK_RXTSF_OFFSET)
+#define BIT_GET_CCK_RXTSF_OFFSET(x) \
+ (((x) >> BIT_SHIFT_CCK_RXTSF_OFFSET) & BIT_MASK_CCK_RXTSF_OFFSET)
+
+/* 2 REG_RXTSF_OFFSET_OFDM (Offset 0x055F) */
+
+#define BIT_SHIFT_OFDM_RXTSF_OFFSET 0
+#define BIT_MASK_OFDM_RXTSF_OFFSET 0xff
+#define BIT_OFDM_RXTSF_OFFSET(x) \
+ (((x) & BIT_MASK_OFDM_RXTSF_OFFSET) << BIT_SHIFT_OFDM_RXTSF_OFFSET)
+#define BIT_GET_OFDM_RXTSF_OFFSET(x) \
+ (((x) >> BIT_SHIFT_OFDM_RXTSF_OFFSET) & BIT_MASK_OFDM_RXTSF_OFFSET)
+
+/* 2 REG_TSFTR (Offset 0x0560) */
+
+#define BIT_SHIFT_TSF_TIMER 0
+#define BIT_MASK_TSF_TIMER 0xffffffffffffffffL
+#define BIT_TSF_TIMER(x) (((x) & BIT_MASK_TSF_TIMER) << BIT_SHIFT_TSF_TIMER)
+#define BIT_GET_TSF_TIMER(x) (((x) >> BIT_SHIFT_TSF_TIMER) & BIT_MASK_TSF_TIMER)
+
+/* 2 REG_FREERUN_CNT (Offset 0x0568) */
+
+#define BIT_SHIFT_FREERUN_CNT 0
+#define BIT_MASK_FREERUN_CNT 0xffffffffffffffffL
+#define BIT_FREERUN_CNT(x) \
+ (((x) & BIT_MASK_FREERUN_CNT) << BIT_SHIFT_FREERUN_CNT)
+#define BIT_GET_FREERUN_CNT(x) \
+ (((x) >> BIT_SHIFT_FREERUN_CNT) & BIT_MASK_FREERUN_CNT)
+
+/* 2 REG_ATIMWND1_V1 (Offset 0x0570) */
+
+#define BIT_SHIFT_ATIMWND1_V1 0
+#define BIT_MASK_ATIMWND1_V1 0xff
+#define BIT_ATIMWND1_V1(x) \
+ (((x) & BIT_MASK_ATIMWND1_V1) << BIT_SHIFT_ATIMWND1_V1)
+#define BIT_GET_ATIMWND1_V1(x) \
+ (((x) >> BIT_SHIFT_ATIMWND1_V1) & BIT_MASK_ATIMWND1_V1)
+
+/* 2 REG_TBTT_PROHIBIT_INFRA (Offset 0x0571) */
+
+#define BIT_SHIFT_TBTT_PROHIBIT_INFRA 0
+#define BIT_MASK_TBTT_PROHIBIT_INFRA 0xff
+#define BIT_TBTT_PROHIBIT_INFRA(x) \
+ (((x) & BIT_MASK_TBTT_PROHIBIT_INFRA) << BIT_SHIFT_TBTT_PROHIBIT_INFRA)
+#define BIT_GET_TBTT_PROHIBIT_INFRA(x) \
+ (((x) >> BIT_SHIFT_TBTT_PROHIBIT_INFRA) & BIT_MASK_TBTT_PROHIBIT_INFRA)
+
+/* 2 REG_CTWND (Offset 0x0572) */
+
+#define BIT_SHIFT_CTWND 0
+#define BIT_MASK_CTWND 0xff
+#define BIT_CTWND(x) (((x) & BIT_MASK_CTWND) << BIT_SHIFT_CTWND)
+#define BIT_GET_CTWND(x) (((x) >> BIT_SHIFT_CTWND) & BIT_MASK_CTWND)
+
+/* 2 REG_BCNIVLCUNT (Offset 0x0573) */
+
+#define BIT_SHIFT_BCNIVLCUNT 0
+#define BIT_MASK_BCNIVLCUNT 0x7f
+#define BIT_BCNIVLCUNT(x) (((x) & BIT_MASK_BCNIVLCUNT) << BIT_SHIFT_BCNIVLCUNT)
+#define BIT_GET_BCNIVLCUNT(x) \
+ (((x) >> BIT_SHIFT_BCNIVLCUNT) & BIT_MASK_BCNIVLCUNT)
+
+/* 2 REG_BCNDROPCTRL (Offset 0x0574) */
+
+#define BIT_BEACON_DROP_EN BIT(7)
+
+#define BIT_SHIFT_BEACON_DROP_IVL 0
+#define BIT_MASK_BEACON_DROP_IVL 0x7f
+#define BIT_BEACON_DROP_IVL(x) \
+ (((x) & BIT_MASK_BEACON_DROP_IVL) << BIT_SHIFT_BEACON_DROP_IVL)
+#define BIT_GET_BEACON_DROP_IVL(x) \
+ (((x) >> BIT_SHIFT_BEACON_DROP_IVL) & BIT_MASK_BEACON_DROP_IVL)
+
+/* 2 REG_HGQ_TIMEOUT_PERIOD (Offset 0x0575) */
+
+#define BIT_SHIFT_HGQ_TIMEOUT_PERIOD 0
+#define BIT_MASK_HGQ_TIMEOUT_PERIOD 0xff
+#define BIT_HGQ_TIMEOUT_PERIOD(x) \
+ (((x) & BIT_MASK_HGQ_TIMEOUT_PERIOD) << BIT_SHIFT_HGQ_TIMEOUT_PERIOD)
+#define BIT_GET_HGQ_TIMEOUT_PERIOD(x) \
+ (((x) >> BIT_SHIFT_HGQ_TIMEOUT_PERIOD) & BIT_MASK_HGQ_TIMEOUT_PERIOD)
+
+/* 2 REG_TXCMD_TIMEOUT_PERIOD (Offset 0x0576) */
+
+#define BIT_SHIFT_TXCMD_TIMEOUT_PERIOD 0
+#define BIT_MASK_TXCMD_TIMEOUT_PERIOD 0xff
+#define BIT_TXCMD_TIMEOUT_PERIOD(x) \
+ (((x) & BIT_MASK_TXCMD_TIMEOUT_PERIOD) \
+ << BIT_SHIFT_TXCMD_TIMEOUT_PERIOD)
+#define BIT_GET_TXCMD_TIMEOUT_PERIOD(x) \
+ (((x) >> BIT_SHIFT_TXCMD_TIMEOUT_PERIOD) & \
+ BIT_MASK_TXCMD_TIMEOUT_PERIOD)
+
+/* 2 REG_MISC_CTRL (Offset 0x0577) */
+
+#define BIT_DIS_TRX_CAL_BCN BIT(5)
+#define BIT_DIS_TX_CAL_TBTT BIT(4)
+#define BIT_EN_FREECNT BIT(3)
+#define BIT_BCN_AGGRESSION BIT(2)
+
+#define BIT_SHIFT_DIS_SECONDARY_CCA 0
+#define BIT_MASK_DIS_SECONDARY_CCA 0x3
+#define BIT_DIS_SECONDARY_CCA(x) \
+ (((x) & BIT_MASK_DIS_SECONDARY_CCA) << BIT_SHIFT_DIS_SECONDARY_CCA)
+#define BIT_GET_DIS_SECONDARY_CCA(x) \
+ (((x) >> BIT_SHIFT_DIS_SECONDARY_CCA) & BIT_MASK_DIS_SECONDARY_CCA)
+
+/* 2 REG_BCN_CTRL_CLINT1 (Offset 0x0578) */
+
+#define BIT_CLI1_DIS_RX_BSSID_FIT BIT(6)
+#define BIT_CLI1_DIS_TSF_UDT BIT(4)
+#define BIT_CLI1_EN_BCN_FUNCTION BIT(3)
+
+/* 2 REG_BCN_CTRL_CLINT1 (Offset 0x0578) */
+
+#define BIT_CLI1_EN_RXBCN_RPT BIT(2)
+
+/* 2 REG_BCN_CTRL_CLINT1 (Offset 0x0578) */
+
+#define BIT_CLI1_ENP2P_CTWINDOW BIT(1)
+#define BIT_CLI1_ENP2P_BCNQ_AREA BIT(0)
+
+/* 2 REG_BCN_CTRL_CLINT2 (Offset 0x0579) */
+
+#define BIT_CLI2_DIS_RX_BSSID_FIT BIT(6)
+#define BIT_CLI2_DIS_TSF_UDT BIT(4)
+#define BIT_CLI2_EN_BCN_FUNCTION BIT(3)
+
+/* 2 REG_BCN_CTRL_CLINT2 (Offset 0x0579) */
+
+#define BIT_CLI2_EN_RXBCN_RPT BIT(2)
+
+/* 2 REG_BCN_CTRL_CLINT2 (Offset 0x0579) */
+
+#define BIT_CLI2_ENP2P_CTWINDOW BIT(1)
+#define BIT_CLI2_ENP2P_BCNQ_AREA BIT(0)
+
+/* 2 REG_BCN_CTRL_CLINT3 (Offset 0x057A) */
+
+#define BIT_CLI3_DIS_RX_BSSID_FIT BIT(6)
+#define BIT_CLI3_DIS_TSF_UDT BIT(4)
+#define BIT_CLI3_EN_BCN_FUNCTION BIT(3)
+
+/* 2 REG_BCN_CTRL_CLINT3 (Offset 0x057A) */
+
+#define BIT_CLI3_EN_RXBCN_RPT BIT(2)
+
+/* 2 REG_BCN_CTRL_CLINT3 (Offset 0x057A) */
+
+#define BIT_CLI3_ENP2P_CTWINDOW BIT(1)
+#define BIT_CLI3_ENP2P_BCNQ_AREA BIT(0)
+
+/* 2 REG_EXTEND_CTRL (Offset 0x057B) */
+
+#define BIT_EN_TSFBIT32_RST_P2P2 BIT(5)
+#define BIT_EN_TSFBIT32_RST_P2P1 BIT(4)
+
+#define BIT_SHIFT_PORT_SEL 0
+#define BIT_MASK_PORT_SEL 0x7
+#define BIT_PORT_SEL(x) (((x) & BIT_MASK_PORT_SEL) << BIT_SHIFT_PORT_SEL)
+#define BIT_GET_PORT_SEL(x) (((x) >> BIT_SHIFT_PORT_SEL) & BIT_MASK_PORT_SEL)
+
+/* 2 REG_P2PPS1_SPEC_STATE (Offset 0x057C) */
+
+#define BIT_P2P1_SPEC_POWER_STATE BIT(7)
+#define BIT_P2P1_SPEC_CTWINDOW_ON BIT(6)
+#define BIT_P2P1_SPEC_BCN_AREA_ON BIT(5)
+#define BIT_P2P1_SPEC_CTWIN_EARLY_DISTX BIT(4)
+#define BIT_P2P1_SPEC_NOA1_OFF_PERIOD BIT(3)
+#define BIT_P2P1_SPEC_FORCE_DOZE1 BIT(2)
+#define BIT_P2P1_SPEC_NOA0_OFF_PERIOD BIT(1)
+#define BIT_P2P1_SPEC_FORCE_DOZE0 BIT(0)
+
+/* 2 REG_P2PPS1_STATE (Offset 0x057D) */
+
+#define BIT_P2P1_POWER_STATE BIT(7)
+#define BIT_P2P1_CTWINDOW_ON BIT(6)
+#define BIT_P2P1_BEACON_AREA_ON BIT(5)
+#define BIT_P2P1_CTWIN_EARLY_DISTX BIT(4)
+#define BIT_P2P1_NOA1_OFF_PERIOD BIT(3)
+#define BIT_P2P1_FORCE_DOZE1 BIT(2)
+#define BIT_P2P1_NOA0_OFF_PERIOD BIT(1)
+#define BIT_P2P1_FORCE_DOZE0 BIT(0)
+
+/* 2 REG_P2PPS2_SPEC_STATE (Offset 0x057E) */
+
+#define BIT_P2P2_SPEC_POWER_STATE BIT(7)
+#define BIT_P2P2_SPEC_CTWINDOW_ON BIT(6)
+#define BIT_P2P2_SPEC_BCN_AREA_ON BIT(5)
+#define BIT_P2P2_SPEC_CTWIN_EARLY_DISTX BIT(4)
+#define BIT_P2P2_SPEC_NOA1_OFF_PERIOD BIT(3)
+#define BIT_P2P2_SPEC_FORCE_DOZE1 BIT(2)
+#define BIT_P2P2_SPEC_NOA0_OFF_PERIOD BIT(1)
+#define BIT_P2P2_SPEC_FORCE_DOZE0 BIT(0)
+
+/* 2 REG_P2PPS2_STATE (Offset 0x057F) */
+
+#define BIT_P2P2_POWER_STATE BIT(7)
+#define BIT_P2P2_CTWINDOW_ON BIT(6)
+#define BIT_P2P2_BEACON_AREA_ON BIT(5)
+#define BIT_P2P2_CTWIN_EARLY_DISTX BIT(4)
+#define BIT_P2P2_NOA1_OFF_PERIOD BIT(3)
+#define BIT_P2P2_FORCE_DOZE1 BIT(2)
+#define BIT_P2P2_NOA0_OFF_PERIOD BIT(1)
+#define BIT_P2P2_FORCE_DOZE0 BIT(0)
+
+/* 2 REG_PS_TIMER0 (Offset 0x0580) */
+
+#define BIT_SHIFT_PSTIMER0_INT 5
+#define BIT_MASK_PSTIMER0_INT 0x7ffffff
+#define BIT_PSTIMER0_INT(x) \
+ (((x) & BIT_MASK_PSTIMER0_INT) << BIT_SHIFT_PSTIMER0_INT)
+#define BIT_GET_PSTIMER0_INT(x) \
+ (((x) >> BIT_SHIFT_PSTIMER0_INT) & BIT_MASK_PSTIMER0_INT)
+
+/* 2 REG_PS_TIMER1 (Offset 0x0584) */
+
+#define BIT_SHIFT_PSTIMER1_INT 5
+#define BIT_MASK_PSTIMER1_INT 0x7ffffff
+#define BIT_PSTIMER1_INT(x) \
+ (((x) & BIT_MASK_PSTIMER1_INT) << BIT_SHIFT_PSTIMER1_INT)
+#define BIT_GET_PSTIMER1_INT(x) \
+ (((x) >> BIT_SHIFT_PSTIMER1_INT) & BIT_MASK_PSTIMER1_INT)
+
+/* 2 REG_PS_TIMER2 (Offset 0x0588) */
+
+#define BIT_SHIFT_PSTIMER2_INT 5
+#define BIT_MASK_PSTIMER2_INT 0x7ffffff
+#define BIT_PSTIMER2_INT(x) \
+ (((x) & BIT_MASK_PSTIMER2_INT) << BIT_SHIFT_PSTIMER2_INT)
+#define BIT_GET_PSTIMER2_INT(x) \
+ (((x) >> BIT_SHIFT_PSTIMER2_INT) & BIT_MASK_PSTIMER2_INT)
+
+/* 2 REG_TBTT_CTN_AREA (Offset 0x058C) */
+
+#define BIT_SHIFT_TBTT_CTN_AREA 0
+#define BIT_MASK_TBTT_CTN_AREA 0xff
+#define BIT_TBTT_CTN_AREA(x) \
+ (((x) & BIT_MASK_TBTT_CTN_AREA) << BIT_SHIFT_TBTT_CTN_AREA)
+#define BIT_GET_TBTT_CTN_AREA(x) \
+ (((x) >> BIT_SHIFT_TBTT_CTN_AREA) & BIT_MASK_TBTT_CTN_AREA)
+
+/* 2 REG_FORCE_BCN_IFS (Offset 0x058E) */
+
+#define BIT_SHIFT_FORCE_BCN_IFS 0
+#define BIT_MASK_FORCE_BCN_IFS 0xff
+#define BIT_FORCE_BCN_IFS(x) \
+ (((x) & BIT_MASK_FORCE_BCN_IFS) << BIT_SHIFT_FORCE_BCN_IFS)
+#define BIT_GET_FORCE_BCN_IFS(x) \
+ (((x) >> BIT_SHIFT_FORCE_BCN_IFS) & BIT_MASK_FORCE_BCN_IFS)
+
+/* 2 REG_TXOP_MIN (Offset 0x0590) */
+
+#define BIT_SHIFT_TXOP_MIN 0
+#define BIT_MASK_TXOP_MIN 0x3fff
+#define BIT_TXOP_MIN(x) (((x) & BIT_MASK_TXOP_MIN) << BIT_SHIFT_TXOP_MIN)
+#define BIT_GET_TXOP_MIN(x) (((x) >> BIT_SHIFT_TXOP_MIN) & BIT_MASK_TXOP_MIN)
+
+/* 2 REG_PRE_BKF_TIME (Offset 0x0592) */
+
+#define BIT_SHIFT_PRE_BKF_TIME 0
+#define BIT_MASK_PRE_BKF_TIME 0xff
+#define BIT_PRE_BKF_TIME(x) \
+ (((x) & BIT_MASK_PRE_BKF_TIME) << BIT_SHIFT_PRE_BKF_TIME)
+#define BIT_GET_PRE_BKF_TIME(x) \
+ (((x) >> BIT_SHIFT_PRE_BKF_TIME) & BIT_MASK_PRE_BKF_TIME)
+
+/* 2 REG_CROSS_TXOP_CTRL (Offset 0x0593) */
+
+#define BIT_DTIM_BYPASS BIT(2)
+#define BIT_RTS_NAV_TXOP BIT(1)
+#define BIT_NOT_CROSS_TXOP BIT(0)
+
+/* 2 REG_ATIMWND2 (Offset 0x05A0) */
+
+#define BIT_SHIFT_ATIMWND2 0
+#define BIT_MASK_ATIMWND2 0xff
+#define BIT_ATIMWND2(x) (((x) & BIT_MASK_ATIMWND2) << BIT_SHIFT_ATIMWND2)
+#define BIT_GET_ATIMWND2(x) (((x) >> BIT_SHIFT_ATIMWND2) & BIT_MASK_ATIMWND2)
+
+/* 2 REG_ATIMWND3 (Offset 0x05A1) */
+
+#define BIT_SHIFT_ATIMWND3 0
+#define BIT_MASK_ATIMWND3 0xff
+#define BIT_ATIMWND3(x) (((x) & BIT_MASK_ATIMWND3) << BIT_SHIFT_ATIMWND3)
+#define BIT_GET_ATIMWND3(x) (((x) >> BIT_SHIFT_ATIMWND3) & BIT_MASK_ATIMWND3)
+
+/* 2 REG_ATIMWND4 (Offset 0x05A2) */
+
+#define BIT_SHIFT_ATIMWND4 0
+#define BIT_MASK_ATIMWND4 0xff
+#define BIT_ATIMWND4(x) (((x) & BIT_MASK_ATIMWND4) << BIT_SHIFT_ATIMWND4)
+#define BIT_GET_ATIMWND4(x) (((x) >> BIT_SHIFT_ATIMWND4) & BIT_MASK_ATIMWND4)
+
+/* 2 REG_ATIMWND5 (Offset 0x05A3) */
+
+#define BIT_SHIFT_ATIMWND5 0
+#define BIT_MASK_ATIMWND5 0xff
+#define BIT_ATIMWND5(x) (((x) & BIT_MASK_ATIMWND5) << BIT_SHIFT_ATIMWND5)
+#define BIT_GET_ATIMWND5(x) (((x) >> BIT_SHIFT_ATIMWND5) & BIT_MASK_ATIMWND5)
+
+/* 2 REG_ATIMWND6 (Offset 0x05A4) */
+
+#define BIT_SHIFT_ATIMWND6 0
+#define BIT_MASK_ATIMWND6 0xff
+#define BIT_ATIMWND6(x) (((x) & BIT_MASK_ATIMWND6) << BIT_SHIFT_ATIMWND6)
+#define BIT_GET_ATIMWND6(x) (((x) >> BIT_SHIFT_ATIMWND6) & BIT_MASK_ATIMWND6)
+
+/* 2 REG_ATIMWND7 (Offset 0x05A5) */
+
+#define BIT_SHIFT_ATIMWND7 0
+#define BIT_MASK_ATIMWND7 0xff
+#define BIT_ATIMWND7(x) (((x) & BIT_MASK_ATIMWND7) << BIT_SHIFT_ATIMWND7)
+#define BIT_GET_ATIMWND7(x) (((x) >> BIT_SHIFT_ATIMWND7) & BIT_MASK_ATIMWND7)
+
+/* 2 REG_ATIMUGT (Offset 0x05A6) */
+
+#define BIT_SHIFT_ATIM_URGENT 0
+#define BIT_MASK_ATIM_URGENT 0xff
+#define BIT_ATIM_URGENT(x) \
+ (((x) & BIT_MASK_ATIM_URGENT) << BIT_SHIFT_ATIM_URGENT)
+#define BIT_GET_ATIM_URGENT(x) \
+ (((x) >> BIT_SHIFT_ATIM_URGENT) & BIT_MASK_ATIM_URGENT)
+
+/* 2 REG_HIQ_NO_LMT_EN (Offset 0x05A7) */
+
+#define BIT_HIQ_NO_LMT_EN_VAP7 BIT(7)
+#define BIT_HIQ_NO_LMT_EN_VAP6 BIT(6)
+#define BIT_HIQ_NO_LMT_EN_VAP5 BIT(5)
+#define BIT_HIQ_NO_LMT_EN_VAP4 BIT(4)
+#define BIT_HIQ_NO_LMT_EN_VAP3 BIT(3)
+#define BIT_HIQ_NO_LMT_EN_VAP2 BIT(2)
+#define BIT_HIQ_NO_LMT_EN_VAP1 BIT(1)
+#define BIT_HIQ_NO_LMT_EN_ROOT BIT(0)
+
+/* 2 REG_DTIM_COUNTER_ROOT (Offset 0x05A8) */
+
+#define BIT_SHIFT_DTIM_COUNT_ROOT 0
+#define BIT_MASK_DTIM_COUNT_ROOT 0xff
+#define BIT_DTIM_COUNT_ROOT(x) \
+ (((x) & BIT_MASK_DTIM_COUNT_ROOT) << BIT_SHIFT_DTIM_COUNT_ROOT)
+#define BIT_GET_DTIM_COUNT_ROOT(x) \
+ (((x) >> BIT_SHIFT_DTIM_COUNT_ROOT) & BIT_MASK_DTIM_COUNT_ROOT)
+
+/* 2 REG_DTIM_COUNTER_VAP1 (Offset 0x05A9) */
+
+#define BIT_SHIFT_DTIM_COUNT_VAP1 0
+#define BIT_MASK_DTIM_COUNT_VAP1 0xff
+#define BIT_DTIM_COUNT_VAP1(x) \
+ (((x) & BIT_MASK_DTIM_COUNT_VAP1) << BIT_SHIFT_DTIM_COUNT_VAP1)
+#define BIT_GET_DTIM_COUNT_VAP1(x) \
+ (((x) >> BIT_SHIFT_DTIM_COUNT_VAP1) & BIT_MASK_DTIM_COUNT_VAP1)
+
+/* 2 REG_DTIM_COUNTER_VAP2 (Offset 0x05AA) */
+
+#define BIT_SHIFT_DTIM_COUNT_VAP2 0
+#define BIT_MASK_DTIM_COUNT_VAP2 0xff
+#define BIT_DTIM_COUNT_VAP2(x) \
+ (((x) & BIT_MASK_DTIM_COUNT_VAP2) << BIT_SHIFT_DTIM_COUNT_VAP2)
+#define BIT_GET_DTIM_COUNT_VAP2(x) \
+ (((x) >> BIT_SHIFT_DTIM_COUNT_VAP2) & BIT_MASK_DTIM_COUNT_VAP2)
+
+/* 2 REG_DTIM_COUNTER_VAP3 (Offset 0x05AB) */
+
+#define BIT_SHIFT_DTIM_COUNT_VAP3 0
+#define BIT_MASK_DTIM_COUNT_VAP3 0xff
+#define BIT_DTIM_COUNT_VAP3(x) \
+ (((x) & BIT_MASK_DTIM_COUNT_VAP3) << BIT_SHIFT_DTIM_COUNT_VAP3)
+#define BIT_GET_DTIM_COUNT_VAP3(x) \
+ (((x) >> BIT_SHIFT_DTIM_COUNT_VAP3) & BIT_MASK_DTIM_COUNT_VAP3)
+
+/* 2 REG_DTIM_COUNTER_VAP4 (Offset 0x05AC) */
+
+#define BIT_SHIFT_DTIM_COUNT_VAP4 0
+#define BIT_MASK_DTIM_COUNT_VAP4 0xff
+#define BIT_DTIM_COUNT_VAP4(x) \
+ (((x) & BIT_MASK_DTIM_COUNT_VAP4) << BIT_SHIFT_DTIM_COUNT_VAP4)
+#define BIT_GET_DTIM_COUNT_VAP4(x) \
+ (((x) >> BIT_SHIFT_DTIM_COUNT_VAP4) & BIT_MASK_DTIM_COUNT_VAP4)
+
+/* 2 REG_DTIM_COUNTER_VAP5 (Offset 0x05AD) */
+
+#define BIT_SHIFT_DTIM_COUNT_VAP5 0
+#define BIT_MASK_DTIM_COUNT_VAP5 0xff
+#define BIT_DTIM_COUNT_VAP5(x) \
+ (((x) & BIT_MASK_DTIM_COUNT_VAP5) << BIT_SHIFT_DTIM_COUNT_VAP5)
+#define BIT_GET_DTIM_COUNT_VAP5(x) \
+ (((x) >> BIT_SHIFT_DTIM_COUNT_VAP5) & BIT_MASK_DTIM_COUNT_VAP5)
+
+/* 2 REG_DTIM_COUNTER_VAP6 (Offset 0x05AE) */
+
+#define BIT_SHIFT_DTIM_COUNT_VAP6 0
+#define BIT_MASK_DTIM_COUNT_VAP6 0xff
+#define BIT_DTIM_COUNT_VAP6(x) \
+ (((x) & BIT_MASK_DTIM_COUNT_VAP6) << BIT_SHIFT_DTIM_COUNT_VAP6)
+#define BIT_GET_DTIM_COUNT_VAP6(x) \
+ (((x) >> BIT_SHIFT_DTIM_COUNT_VAP6) & BIT_MASK_DTIM_COUNT_VAP6)
+
+/* 2 REG_DTIM_COUNTER_VAP7 (Offset 0x05AF) */
+
+#define BIT_SHIFT_DTIM_COUNT_VAP7 0
+#define BIT_MASK_DTIM_COUNT_VAP7 0xff
+#define BIT_DTIM_COUNT_VAP7(x) \
+ (((x) & BIT_MASK_DTIM_COUNT_VAP7) << BIT_SHIFT_DTIM_COUNT_VAP7)
+#define BIT_GET_DTIM_COUNT_VAP7(x) \
+ (((x) >> BIT_SHIFT_DTIM_COUNT_VAP7) & BIT_MASK_DTIM_COUNT_VAP7)
+
+/* 2 REG_DIS_ATIM (Offset 0x05B0) */
+
+#define BIT_DIS_ATIM_VAP7 BIT(7)
+#define BIT_DIS_ATIM_VAP6 BIT(6)
+#define BIT_DIS_ATIM_VAP5 BIT(5)
+#define BIT_DIS_ATIM_VAP4 BIT(4)
+#define BIT_DIS_ATIM_VAP3 BIT(3)
+#define BIT_DIS_ATIM_VAP2 BIT(2)
+#define BIT_DIS_ATIM_VAP1 BIT(1)
+#define BIT_DIS_ATIM_ROOT BIT(0)
+
+/* 2 REG_EARLY_128US (Offset 0x05B1) */
+
+#define BIT_SHIFT_TSFT_SEL_TIMER1 3
+#define BIT_MASK_TSFT_SEL_TIMER1 0x7
+#define BIT_TSFT_SEL_TIMER1(x) \
+ (((x) & BIT_MASK_TSFT_SEL_TIMER1) << BIT_SHIFT_TSFT_SEL_TIMER1)
+#define BIT_GET_TSFT_SEL_TIMER1(x) \
+ (((x) >> BIT_SHIFT_TSFT_SEL_TIMER1) & BIT_MASK_TSFT_SEL_TIMER1)
+
+#define BIT_SHIFT_EARLY_128US 0
+#define BIT_MASK_EARLY_128US 0x7
+#define BIT_EARLY_128US(x) \
+ (((x) & BIT_MASK_EARLY_128US) << BIT_SHIFT_EARLY_128US)
+#define BIT_GET_EARLY_128US(x) \
+ (((x) >> BIT_SHIFT_EARLY_128US) & BIT_MASK_EARLY_128US)
+
+/* 2 REG_P2PPS1_CTRL (Offset 0x05B2) */
+
+#define BIT_P2P1_CTW_ALLSTASLEEP BIT(7)
+#define BIT_P2P1_OFF_DISTX_EN BIT(6)
+#define BIT_P2P1_PWR_MGT_EN BIT(5)
+#define BIT_P2P1_NOA1_EN BIT(2)
+#define BIT_P2P1_NOA0_EN BIT(1)
+
+/* 2 REG_P2PPS2_CTRL (Offset 0x05B3) */
+
+#define BIT_P2P2_CTW_ALLSTASLEEP BIT(7)
+#define BIT_P2P2_OFF_DISTX_EN BIT(6)
+#define BIT_P2P2_PWR_MGT_EN BIT(5)
+#define BIT_P2P2_NOA1_EN BIT(2)
+#define BIT_P2P2_NOA0_EN BIT(1)
+
+/* 2 REG_TIMER0_SRC_SEL (Offset 0x05B4) */
+
+#define BIT_SHIFT_SYNC_CLI_SEL 4
+#define BIT_MASK_SYNC_CLI_SEL 0x7
+#define BIT_SYNC_CLI_SEL(x) \
+ (((x) & BIT_MASK_SYNC_CLI_SEL) << BIT_SHIFT_SYNC_CLI_SEL)
+#define BIT_GET_SYNC_CLI_SEL(x) \
+ (((x) >> BIT_SHIFT_SYNC_CLI_SEL) & BIT_MASK_SYNC_CLI_SEL)
+
+#define BIT_SHIFT_TSFT_SEL_TIMER0 0
+#define BIT_MASK_TSFT_SEL_TIMER0 0x7
+#define BIT_TSFT_SEL_TIMER0(x) \
+ (((x) & BIT_MASK_TSFT_SEL_TIMER0) << BIT_SHIFT_TSFT_SEL_TIMER0)
+#define BIT_GET_TSFT_SEL_TIMER0(x) \
+ (((x) >> BIT_SHIFT_TSFT_SEL_TIMER0) & BIT_MASK_TSFT_SEL_TIMER0)
+
+/* 2 REG_NOA_UNIT_SEL (Offset 0x05B5) */
+
+#define BIT_SHIFT_NOA_UNIT2_SEL 8
+#define BIT_MASK_NOA_UNIT2_SEL 0x7
+#define BIT_NOA_UNIT2_SEL(x) \
+ (((x) & BIT_MASK_NOA_UNIT2_SEL) << BIT_SHIFT_NOA_UNIT2_SEL)
+#define BIT_GET_NOA_UNIT2_SEL(x) \
+ (((x) >> BIT_SHIFT_NOA_UNIT2_SEL) & BIT_MASK_NOA_UNIT2_SEL)
+
+#define BIT_SHIFT_NOA_UNIT1_SEL 4
+#define BIT_MASK_NOA_UNIT1_SEL 0x7
+#define BIT_NOA_UNIT1_SEL(x) \
+ (((x) & BIT_MASK_NOA_UNIT1_SEL) << BIT_SHIFT_NOA_UNIT1_SEL)
+#define BIT_GET_NOA_UNIT1_SEL(x) \
+ (((x) >> BIT_SHIFT_NOA_UNIT1_SEL) & BIT_MASK_NOA_UNIT1_SEL)
+
+#define BIT_SHIFT_NOA_UNIT0_SEL 0
+#define BIT_MASK_NOA_UNIT0_SEL 0x7
+#define BIT_NOA_UNIT0_SEL(x) \
+ (((x) & BIT_MASK_NOA_UNIT0_SEL) << BIT_SHIFT_NOA_UNIT0_SEL)
+#define BIT_GET_NOA_UNIT0_SEL(x) \
+ (((x) >> BIT_SHIFT_NOA_UNIT0_SEL) & BIT_MASK_NOA_UNIT0_SEL)
+
+/* 2 REG_P2POFF_DIS_TXTIME (Offset 0x05B7) */
+
+#define BIT_SHIFT_P2POFF_DIS_TXTIME 0
+#define BIT_MASK_P2POFF_DIS_TXTIME 0xff
+#define BIT_P2POFF_DIS_TXTIME(x) \
+ (((x) & BIT_MASK_P2POFF_DIS_TXTIME) << BIT_SHIFT_P2POFF_DIS_TXTIME)
+#define BIT_GET_P2POFF_DIS_TXTIME(x) \
+ (((x) >> BIT_SHIFT_P2POFF_DIS_TXTIME) & BIT_MASK_P2POFF_DIS_TXTIME)
+
+/* 2 REG_MBSSID_BCN_SPACE2 (Offset 0x05B8) */
+
+#define BIT_SHIFT_BCN_SPACE_CLINT2 16
+#define BIT_MASK_BCN_SPACE_CLINT2 0xfff
+#define BIT_BCN_SPACE_CLINT2(x) \
+ (((x) & BIT_MASK_BCN_SPACE_CLINT2) << BIT_SHIFT_BCN_SPACE_CLINT2)
+#define BIT_GET_BCN_SPACE_CLINT2(x) \
+ (((x) >> BIT_SHIFT_BCN_SPACE_CLINT2) & BIT_MASK_BCN_SPACE_CLINT2)
+
+#define BIT_SHIFT_BCN_SPACE_CLINT1 0
+#define BIT_MASK_BCN_SPACE_CLINT1 0xfff
+#define BIT_BCN_SPACE_CLINT1(x) \
+ (((x) & BIT_MASK_BCN_SPACE_CLINT1) << BIT_SHIFT_BCN_SPACE_CLINT1)
+#define BIT_GET_BCN_SPACE_CLINT1(x) \
+ (((x) >> BIT_SHIFT_BCN_SPACE_CLINT1) & BIT_MASK_BCN_SPACE_CLINT1)
+
+/* 2 REG_MBSSID_BCN_SPACE3 (Offset 0x05BC) */
+
+#define BIT_SHIFT_SUB_BCN_SPACE 16
+#define BIT_MASK_SUB_BCN_SPACE 0xff
+#define BIT_SUB_BCN_SPACE(x) \
+ (((x) & BIT_MASK_SUB_BCN_SPACE) << BIT_SHIFT_SUB_BCN_SPACE)
+#define BIT_GET_SUB_BCN_SPACE(x) \
+ (((x) >> BIT_SHIFT_SUB_BCN_SPACE) & BIT_MASK_SUB_BCN_SPACE)
+
+/* 2 REG_MBSSID_BCN_SPACE3 (Offset 0x05BC) */
+
+#define BIT_SHIFT_BCN_SPACE_CLINT3 0
+#define BIT_MASK_BCN_SPACE_CLINT3 0xfff
+#define BIT_BCN_SPACE_CLINT3(x) \
+ (((x) & BIT_MASK_BCN_SPACE_CLINT3) << BIT_SHIFT_BCN_SPACE_CLINT3)
+#define BIT_GET_BCN_SPACE_CLINT3(x) \
+ (((x) >> BIT_SHIFT_BCN_SPACE_CLINT3) & BIT_MASK_BCN_SPACE_CLINT3)
+
+/* 2 REG_ACMHWCTRL (Offset 0x05C0) */
+
+#define BIT_BEQ_ACM_STATUS BIT(7)
+#define BIT_VIQ_ACM_STATUS BIT(6)
+#define BIT_VOQ_ACM_STATUS BIT(5)
+#define BIT_BEQ_ACM_EN BIT(3)
+#define BIT_VIQ_ACM_EN BIT(2)
+#define BIT_VOQ_ACM_EN BIT(1)
+#define BIT_ACMHWEN BIT(0)
+
+/* 2 REG_ACMRSTCTRL (Offset 0x05C1) */
+
+#define BIT_BE_ACM_RESET_USED_TIME BIT(2)
+#define BIT_VI_ACM_RESET_USED_TIME BIT(1)
+#define BIT_VO_ACM_RESET_USED_TIME BIT(0)
+
+/* 2 REG_ACMAVG (Offset 0x05C2) */
+
+#define BIT_SHIFT_AVGPERIOD 0
+#define BIT_MASK_AVGPERIOD 0xffff
+#define BIT_AVGPERIOD(x) (((x) & BIT_MASK_AVGPERIOD) << BIT_SHIFT_AVGPERIOD)
+#define BIT_GET_AVGPERIOD(x) (((x) >> BIT_SHIFT_AVGPERIOD) & BIT_MASK_AVGPERIOD)
+
+/* 2 REG_VO_ADMTIME (Offset 0x05C4) */
+
+#define BIT_SHIFT_VO_ADMITTED_TIME 0
+#define BIT_MASK_VO_ADMITTED_TIME 0xffff
+#define BIT_VO_ADMITTED_TIME(x) \
+ (((x) & BIT_MASK_VO_ADMITTED_TIME) << BIT_SHIFT_VO_ADMITTED_TIME)
+#define BIT_GET_VO_ADMITTED_TIME(x) \
+ (((x) >> BIT_SHIFT_VO_ADMITTED_TIME) & BIT_MASK_VO_ADMITTED_TIME)
+
+/* 2 REG_VI_ADMTIME (Offset 0x05C6) */
+
+#define BIT_SHIFT_VI_ADMITTED_TIME 0
+#define BIT_MASK_VI_ADMITTED_TIME 0xffff
+#define BIT_VI_ADMITTED_TIME(x) \
+ (((x) & BIT_MASK_VI_ADMITTED_TIME) << BIT_SHIFT_VI_ADMITTED_TIME)
+#define BIT_GET_VI_ADMITTED_TIME(x) \
+ (((x) >> BIT_SHIFT_VI_ADMITTED_TIME) & BIT_MASK_VI_ADMITTED_TIME)
+
+/* 2 REG_BE_ADMTIME (Offset 0x05C8) */
+
+#define BIT_SHIFT_BE_ADMITTED_TIME 0
+#define BIT_MASK_BE_ADMITTED_TIME 0xffff
+#define BIT_BE_ADMITTED_TIME(x) \
+ (((x) & BIT_MASK_BE_ADMITTED_TIME) << BIT_SHIFT_BE_ADMITTED_TIME)
+#define BIT_GET_BE_ADMITTED_TIME(x) \
+ (((x) >> BIT_SHIFT_BE_ADMITTED_TIME) & BIT_MASK_BE_ADMITTED_TIME)
+
+/* 2 REG_EDCA_RANDOM_GEN (Offset 0x05CC) */
+
+#define BIT_SHIFT_RANDOM_GEN 0
+#define BIT_MASK_RANDOM_GEN 0xffffff
+#define BIT_RANDOM_GEN(x) (((x) & BIT_MASK_RANDOM_GEN) << BIT_SHIFT_RANDOM_GEN)
+#define BIT_GET_RANDOM_GEN(x) \
+ (((x) >> BIT_SHIFT_RANDOM_GEN) & BIT_MASK_RANDOM_GEN)
+
+/* 2 REG_TXCMD_NOA_SEL (Offset 0x05CF) */
+
+#define BIT_SHIFT_NOA_SEL 4
+#define BIT_MASK_NOA_SEL 0x7
+#define BIT_NOA_SEL(x) (((x) & BIT_MASK_NOA_SEL) << BIT_SHIFT_NOA_SEL)
+#define BIT_GET_NOA_SEL(x) (((x) >> BIT_SHIFT_NOA_SEL) & BIT_MASK_NOA_SEL)
+
+/* 2 REG_TXCMD_NOA_SEL (Offset 0x05CF) */
+
+#define BIT_SHIFT_TXCMD_SEG_SEL 0
+#define BIT_MASK_TXCMD_SEG_SEL 0xf
+#define BIT_TXCMD_SEG_SEL(x) \
+ (((x) & BIT_MASK_TXCMD_SEG_SEL) << BIT_SHIFT_TXCMD_SEG_SEL)
+#define BIT_GET_TXCMD_SEG_SEL(x) \
+ (((x) >> BIT_SHIFT_TXCMD_SEG_SEL) & BIT_MASK_TXCMD_SEG_SEL)
+
+/* 2 REG_NOA_PARAM (Offset 0x05E0) */
+
+#define BIT_SHIFT_NOA_COUNT (96 & CPU_OPT_WIDTH)
+#define BIT_MASK_NOA_COUNT 0xff
+#define BIT_NOA_COUNT(x) (((x) & BIT_MASK_NOA_COUNT) << BIT_SHIFT_NOA_COUNT)
+#define BIT_GET_NOA_COUNT(x) (((x) >> BIT_SHIFT_NOA_COUNT) & BIT_MASK_NOA_COUNT)
+
+#define BIT_SHIFT_NOA_START_TIME (64 & CPU_OPT_WIDTH)
+#define BIT_MASK_NOA_START_TIME 0xffffffffL
+#define BIT_NOA_START_TIME(x) \
+ (((x) & BIT_MASK_NOA_START_TIME) << BIT_SHIFT_NOA_START_TIME)
+#define BIT_GET_NOA_START_TIME(x) \
+ (((x) >> BIT_SHIFT_NOA_START_TIME) & BIT_MASK_NOA_START_TIME)
+
+#define BIT_SHIFT_NOA_INTERVAL (32 & CPU_OPT_WIDTH)
+#define BIT_MASK_NOA_INTERVAL 0xffffffffL
+#define BIT_NOA_INTERVAL(x) \
+ (((x) & BIT_MASK_NOA_INTERVAL) << BIT_SHIFT_NOA_INTERVAL)
+#define BIT_GET_NOA_INTERVAL(x) \
+ (((x) >> BIT_SHIFT_NOA_INTERVAL) & BIT_MASK_NOA_INTERVAL)
+
+#define BIT_SHIFT_NOA_DURATION 0
+#define BIT_MASK_NOA_DURATION 0xffffffffL
+#define BIT_NOA_DURATION(x) \
+ (((x) & BIT_MASK_NOA_DURATION) << BIT_SHIFT_NOA_DURATION)
+#define BIT_GET_NOA_DURATION(x) \
+ (((x) >> BIT_SHIFT_NOA_DURATION) & BIT_MASK_NOA_DURATION)
+
+/* 2 REG_P2P_RST (Offset 0x05F0) */
+
+#define BIT_P2P2_PWR_RST1 BIT(5)
+#define BIT_P2P2_PWR_RST0 BIT(4)
+#define BIT_P2P1_PWR_RST1 BIT(3)
+#define BIT_P2P1_PWR_RST0 BIT(2)
+#define BIT_P2P_PWR_RST1_V1 BIT(1)
+#define BIT_P2P_PWR_RST0_V1 BIT(0)
+
+/* 2 REG_SCHEDULER_RST (Offset 0x05F1) */
+
+#define BIT_SYNC_CLI BIT(1)
+#define BIT_SCHEDULER_RST_V1 BIT(0)
+
+/* 2 REG_SCH_TXCMD (Offset 0x05F8) */
+
+#define BIT_SHIFT_SCH_TXCMD 0
+#define BIT_MASK_SCH_TXCMD 0xffffffffL
+#define BIT_SCH_TXCMD(x) (((x) & BIT_MASK_SCH_TXCMD) << BIT_SHIFT_SCH_TXCMD)
+#define BIT_GET_SCH_TXCMD(x) (((x) >> BIT_SHIFT_SCH_TXCMD) & BIT_MASK_SCH_TXCMD)
+
+/* 2 REG_WMAC_CR (Offset 0x0600) */
+
+#define BIT_IC_MACPHY_M BIT(0)
+
+/* 2 REG_WMAC_FWPKT_CR (Offset 0x0601) */
+
+#define BIT_FWEN BIT(7)
+
+/* 2 REG_WMAC_FWPKT_CR (Offset 0x0601) */
+
+#define BIT_PHYSTS_PKT_CTRL BIT(6)
+
+/* 2 REG_WMAC_FWPKT_CR (Offset 0x0601) */
+
+#define BIT_APPHDR_MIDSRCH_FAIL BIT(4)
+#define BIT_FWPARSING_EN BIT(3)
+
+#define BIT_SHIFT_APPEND_MHDR_LEN 0
+#define BIT_MASK_APPEND_MHDR_LEN 0x7
+#define BIT_APPEND_MHDR_LEN(x) \
+ (((x) & BIT_MASK_APPEND_MHDR_LEN) << BIT_SHIFT_APPEND_MHDR_LEN)
+#define BIT_GET_APPEND_MHDR_LEN(x) \
+ (((x) >> BIT_SHIFT_APPEND_MHDR_LEN) & BIT_MASK_APPEND_MHDR_LEN)
+
+/* 2 REG_TCR (Offset 0x0604) */
+
+#define BIT_WMAC_EN_RTS_ADDR BIT(31)
+#define BIT_WMAC_DISABLE_CCK BIT(30)
+#define BIT_WMAC_RAW_LEN BIT(29)
+#define BIT_WMAC_NOTX_IN_RXNDP BIT(28)
+#define BIT_WMAC_EN_EOF BIT(27)
+#define BIT_WMAC_BF_SEL BIT(26)
+#define BIT_WMAC_ANTMODE_SEL BIT(25)
+
+/* 2 REG_TCR (Offset 0x0604) */
+
+#define BIT_WMAC_TCRPWRMGT_HWCTL BIT(24)
+
+/* 2 REG_TCR (Offset 0x0604) */
+
+#define BIT_WMAC_SMOOTH_VAL BIT(23)
+
+/* 2 REG_TCR (Offset 0x0604) */
+
+#define BIT_FETCH_MPDU_AFTER_WSEC_RDY BIT(20)
+
+/* 2 REG_TCR (Offset 0x0604) */
+
+#define BIT_WMAC_TCR_EN_20MST BIT(19)
+#define BIT_WMAC_DIS_SIGTA BIT(18)
+#define BIT_WMAC_DIS_A2B0 BIT(17)
+#define BIT_WMAC_MSK_SIGBCRC BIT(16)
+
+/* 2 REG_TCR (Offset 0x0604) */
+
+#define BIT_WMAC_TCR_ERRSTEN_3 BIT(15)
+#define BIT_WMAC_TCR_ERRSTEN_2 BIT(14)
+#define BIT_WMAC_TCR_ERRSTEN_1 BIT(13)
+#define BIT_WMAC_TCR_ERRSTEN_0 BIT(12)
+#define BIT_WMAC_TCR_TXSK_PERPKT BIT(11)
+#define BIT_ICV BIT(10)
+#define BIT_CFEND_FORMAT BIT(9)
+#define BIT_CRC BIT(8)
+#define BIT_PWRBIT_OW_EN BIT(7)
+#define BIT_PWR_ST BIT(6)
+#define BIT_WMAC_TCR_UPD_TIMIE BIT(5)
+#define BIT_WMAC_TCR_UPD_HGQMD BIT(4)
+
+/* 2 REG_TCR (Offset 0x0604) */
+
+#define BIT_VHTSIGA1_TXPS BIT(3)
+
+/* 2 REG_TCR (Offset 0x0604) */
+
+#define BIT_PAD_SEL BIT(2)
+#define BIT_DIS_GCLK BIT(1)
+
+/* 2 REG_RCR (Offset 0x0608) */
+
+#define BIT_APP_FCS BIT(31)
+#define BIT_APP_MIC BIT(30)
+#define BIT_APP_ICV BIT(29)
+#define BIT_APP_PHYSTS BIT(28)
+#define BIT_APP_BASSN BIT(27)
+
+/* 2 REG_RCR (Offset 0x0608) */
+
+#define BIT_VHT_DACK BIT(26)
+
+/* 2 REG_RCR (Offset 0x0608) */
+
+#define BIT_TCPOFLD_EN BIT(25)
+#define BIT_ENMBID BIT(24)
+#define BIT_LSIGEN BIT(23)
+#define BIT_MFBEN BIT(22)
+#define BIT_DISCHKPPDLLEN BIT(21)
+#define BIT_PKTCTL_DLEN BIT(20)
+#define BIT_TIM_PARSER_EN BIT(18)
+#define BIT_BC_MD_EN BIT(17)
+#define BIT_UC_MD_EN BIT(16)
+#define BIT_RXSK_PERPKT BIT(15)
+#define BIT_HTC_LOC_CTRL BIT(14)
+
+/* 2 REG_RCR (Offset 0x0608) */
+
+#define BIT_RPFM_CAM_ENABLE BIT(12)
+
+/* 2 REG_RCR (Offset 0x0608) */
+
+#define BIT_TA_BCN BIT(11)
+
+/* 2 REG_RCR (Offset 0x0608) */
+
+#define BIT_DISDECMYPKT BIT(10)
+#define BIT_AICV BIT(9)
+#define BIT_ACRC32 BIT(8)
+#define BIT_CBSSID_BCN BIT(7)
+#define BIT_CBSSID_DATA BIT(6)
+#define BIT_APWRMGT BIT(5)
+#define BIT_ADD3 BIT(4)
+#define BIT_AB BIT(3)
+#define BIT_AM BIT(2)
+#define BIT_APM BIT(1)
+#define BIT_AAP BIT(0)
+
+/* 2 REG_RX_PKT_LIMIT (Offset 0x060C) */
+
+#define BIT_SHIFT_RXPKTLMT 0
+#define BIT_MASK_RXPKTLMT 0x3f
+#define BIT_RXPKTLMT(x) (((x) & BIT_MASK_RXPKTLMT) << BIT_SHIFT_RXPKTLMT)
+#define BIT_GET_RXPKTLMT(x) (((x) >> BIT_SHIFT_RXPKTLMT) & BIT_MASK_RXPKTLMT)
+
+/* 2 REG_RX_DLK_TIME (Offset 0x060D) */
+
+#define BIT_SHIFT_RX_DLK_TIME 0
+#define BIT_MASK_RX_DLK_TIME 0xff
+#define BIT_RX_DLK_TIME(x) \
+ (((x) & BIT_MASK_RX_DLK_TIME) << BIT_SHIFT_RX_DLK_TIME)
+#define BIT_GET_RX_DLK_TIME(x) \
+ (((x) >> BIT_SHIFT_RX_DLK_TIME) & BIT_MASK_RX_DLK_TIME)
+
+/* 2 REG_RX_DRVINFO_SZ (Offset 0x060F) */
+
+#define BIT_DATA_RPFM15EN BIT(15)
+#define BIT_DATA_RPFM14EN BIT(14)
+#define BIT_DATA_RPFM13EN BIT(13)
+#define BIT_DATA_RPFM12EN BIT(12)
+#define BIT_DATA_RPFM11EN BIT(11)
+#define BIT_DATA_RPFM10EN BIT(10)
+#define BIT_DATA_RPFM9EN BIT(9)
+#define BIT_DATA_RPFM8EN BIT(8)
+
+/* 2 REG_RX_DRVINFO_SZ (Offset 0x060F) */
+
+#define BIT_PHYSTS_PER_PKT_MODE BIT(7)
+#define BIT_DATA_RPFM7EN BIT(7)
+
+/* 2 REG_RX_DRVINFO_SZ (Offset 0x060F) */
+
+#define BIT_DATA_RPFM6EN BIT(6)
+
+/* 2 REG_RX_DRVINFO_SZ (Offset 0x060F) */
+
+#define BIT_DATA_RPFM5EN BIT(5)
+#define BIT_DATA_RPFM4EN BIT(4)
+#define BIT_DATA_RPFM3EN BIT(3)
+#define BIT_DATA_RPFM2EN BIT(2)
+#define BIT_DATA_RPFM1EN BIT(1)
+
+/* 2 REG_RX_DRVINFO_SZ (Offset 0x060F) */
+
+#define BIT_SHIFT_DRVINFO_SZ_V1 0
+#define BIT_MASK_DRVINFO_SZ_V1 0xf
+#define BIT_DRVINFO_SZ_V1(x) \
+ (((x) & BIT_MASK_DRVINFO_SZ_V1) << BIT_SHIFT_DRVINFO_SZ_V1)
+#define BIT_GET_DRVINFO_SZ_V1(x) \
+ (((x) >> BIT_SHIFT_DRVINFO_SZ_V1) & BIT_MASK_DRVINFO_SZ_V1)
+
+/* 2 REG_RX_DRVINFO_SZ (Offset 0x060F) */
+
+#define BIT_DATA_RPFM0EN BIT(0)
+
+/* 2 REG_MACID (Offset 0x0610) */
+
+#define BIT_SHIFT_MACID 0
+#define BIT_MASK_MACID 0xffffffffffffL
+#define BIT_MACID(x) (((x) & BIT_MASK_MACID) << BIT_SHIFT_MACID)
+#define BIT_GET_MACID(x) (((x) >> BIT_SHIFT_MACID) & BIT_MASK_MACID)
+
+/* 2 REG_BSSID (Offset 0x0618) */
+
+#define BIT_SHIFT_BSSID 0
+#define BIT_MASK_BSSID 0xffffffffffffL
+#define BIT_BSSID(x) (((x) & BIT_MASK_BSSID) << BIT_SHIFT_BSSID)
+#define BIT_GET_BSSID(x) (((x) >> BIT_SHIFT_BSSID) & BIT_MASK_BSSID)
+
+/* 2 REG_MAR (Offset 0x0620) */
+
+#define BIT_SHIFT_MAR 0
+#define BIT_MASK_MAR 0xffffffffffffffffL
+#define BIT_MAR(x) (((x) & BIT_MASK_MAR) << BIT_SHIFT_MAR)
+#define BIT_GET_MAR(x) (((x) >> BIT_SHIFT_MAR) & BIT_MASK_MAR)
+
+/* 2 REG_MBIDCAMCFG_1 (Offset 0x0628) */
+
+#define BIT_SHIFT_MBIDCAM_RWDATA_L 0
+#define BIT_MASK_MBIDCAM_RWDATA_L 0xffffffffL
+#define BIT_MBIDCAM_RWDATA_L(x) \
+ (((x) & BIT_MASK_MBIDCAM_RWDATA_L) << BIT_SHIFT_MBIDCAM_RWDATA_L)
+#define BIT_GET_MBIDCAM_RWDATA_L(x) \
+ (((x) >> BIT_SHIFT_MBIDCAM_RWDATA_L) & BIT_MASK_MBIDCAM_RWDATA_L)
+
+/* 2 REG_MBIDCAMCFG_2 (Offset 0x062C) */
+
+#define BIT_MBIDCAM_POLL BIT(31)
+#define BIT_MBIDCAM_WT_EN BIT(30)
+
+#define BIT_SHIFT_MBIDCAM_ADDR 24
+#define BIT_MASK_MBIDCAM_ADDR 0x1f
+#define BIT_MBIDCAM_ADDR(x) \
+ (((x) & BIT_MASK_MBIDCAM_ADDR) << BIT_SHIFT_MBIDCAM_ADDR)
+#define BIT_GET_MBIDCAM_ADDR(x) \
+ (((x) >> BIT_SHIFT_MBIDCAM_ADDR) & BIT_MASK_MBIDCAM_ADDR)
+
+#define BIT_MBIDCAM_VALID BIT(23)
+#define BIT_LSIC_TXOP_EN BIT(17)
+
+/* 2 REG_MBIDCAMCFG_2 (Offset 0x062C) */
+
+#define BIT_CTS_EN BIT(16)
+
+/* 2 REG_MBIDCAMCFG_2 (Offset 0x062C) */
+
+#define BIT_SHIFT_MBIDCAM_RWDATA_H 0
+#define BIT_MASK_MBIDCAM_RWDATA_H 0xffff
+#define BIT_MBIDCAM_RWDATA_H(x) \
+ (((x) & BIT_MASK_MBIDCAM_RWDATA_H) << BIT_SHIFT_MBIDCAM_RWDATA_H)
+#define BIT_GET_MBIDCAM_RWDATA_H(x) \
+ (((x) >> BIT_SHIFT_MBIDCAM_RWDATA_H) & BIT_MASK_MBIDCAM_RWDATA_H)
+
+/* 2 REG_WMAC_TCR_TSFT_OFS (Offset 0x0630) */
+
+#define BIT_SHIFT_WMAC_TCR_TSFT_OFS 0
+#define BIT_MASK_WMAC_TCR_TSFT_OFS 0xffff
+#define BIT_WMAC_TCR_TSFT_OFS(x) \
+ (((x) & BIT_MASK_WMAC_TCR_TSFT_OFS) << BIT_SHIFT_WMAC_TCR_TSFT_OFS)
+#define BIT_GET_WMAC_TCR_TSFT_OFS(x) \
+ (((x) >> BIT_SHIFT_WMAC_TCR_TSFT_OFS) & BIT_MASK_WMAC_TCR_TSFT_OFS)
+
+/* 2 REG_UDF_THSD (Offset 0x0632) */
+
+#define BIT_SHIFT_UDF_THSD 0
+#define BIT_MASK_UDF_THSD 0xff
+#define BIT_UDF_THSD(x) (((x) & BIT_MASK_UDF_THSD) << BIT_SHIFT_UDF_THSD)
+#define BIT_GET_UDF_THSD(x) (((x) >> BIT_SHIFT_UDF_THSD) & BIT_MASK_UDF_THSD)
+
+/* 2 REG_ZLD_NUM (Offset 0x0633) */
+
+#define BIT_SHIFT_ZLD_NUM 0
+#define BIT_MASK_ZLD_NUM 0xff
+#define BIT_ZLD_NUM(x) (((x) & BIT_MASK_ZLD_NUM) << BIT_SHIFT_ZLD_NUM)
+#define BIT_GET_ZLD_NUM(x) (((x) >> BIT_SHIFT_ZLD_NUM) & BIT_MASK_ZLD_NUM)
+
+/* 2 REG_STMP_THSD (Offset 0x0634) */
+
+#define BIT_SHIFT_STMP_THSD 0
+#define BIT_MASK_STMP_THSD 0xff
+#define BIT_STMP_THSD(x) (((x) & BIT_MASK_STMP_THSD) << BIT_SHIFT_STMP_THSD)
+#define BIT_GET_STMP_THSD(x) (((x) >> BIT_SHIFT_STMP_THSD) & BIT_MASK_STMP_THSD)
+
+/* 2 REG_WMAC_TXTIMEOUT (Offset 0x0635) */
+
+#define BIT_SHIFT_WMAC_TXTIMEOUT 0
+#define BIT_MASK_WMAC_TXTIMEOUT 0xff
+#define BIT_WMAC_TXTIMEOUT(x) \
+ (((x) & BIT_MASK_WMAC_TXTIMEOUT) << BIT_SHIFT_WMAC_TXTIMEOUT)
+#define BIT_GET_WMAC_TXTIMEOUT(x) \
+ (((x) >> BIT_SHIFT_WMAC_TXTIMEOUT) & BIT_MASK_WMAC_TXTIMEOUT)
+
+/* 2 REG_MCU_TEST_2_V1 (Offset 0x0636) */
+
+#define BIT_SHIFT_MCU_RSVD_2_V1 0
+#define BIT_MASK_MCU_RSVD_2_V1 0xffff
+#define BIT_MCU_RSVD_2_V1(x) \
+ (((x) & BIT_MASK_MCU_RSVD_2_V1) << BIT_SHIFT_MCU_RSVD_2_V1)
+#define BIT_GET_MCU_RSVD_2_V1(x) \
+ (((x) >> BIT_SHIFT_MCU_RSVD_2_V1) & BIT_MASK_MCU_RSVD_2_V1)
+
+/* 2 REG_USTIME_EDCA (Offset 0x0638) */
+
+#define BIT_SHIFT_USTIME_EDCA_V1 0
+#define BIT_MASK_USTIME_EDCA_V1 0x1ff
+#define BIT_USTIME_EDCA_V1(x) \
+ (((x) & BIT_MASK_USTIME_EDCA_V1) << BIT_SHIFT_USTIME_EDCA_V1)
+#define BIT_GET_USTIME_EDCA_V1(x) \
+ (((x) >> BIT_SHIFT_USTIME_EDCA_V1) & BIT_MASK_USTIME_EDCA_V1)
+
+/* 2 REG_MAC_SPEC_SIFS (Offset 0x063A) */
+
+#define BIT_SHIFT_SPEC_SIFS_OFDM 8
+#define BIT_MASK_SPEC_SIFS_OFDM 0xff
+#define BIT_SPEC_SIFS_OFDM(x) \
+ (((x) & BIT_MASK_SPEC_SIFS_OFDM) << BIT_SHIFT_SPEC_SIFS_OFDM)
+#define BIT_GET_SPEC_SIFS_OFDM(x) \
+ (((x) >> BIT_SHIFT_SPEC_SIFS_OFDM) & BIT_MASK_SPEC_SIFS_OFDM)
+
+#define BIT_SHIFT_SPEC_SIFS_CCK 0
+#define BIT_MASK_SPEC_SIFS_CCK 0xff
+#define BIT_SPEC_SIFS_CCK(x) \
+ (((x) & BIT_MASK_SPEC_SIFS_CCK) << BIT_SHIFT_SPEC_SIFS_CCK)
+#define BIT_GET_SPEC_SIFS_CCK(x) \
+ (((x) >> BIT_SHIFT_SPEC_SIFS_CCK) & BIT_MASK_SPEC_SIFS_CCK)
+
+/* 2 REG_RESP_SIFS_CCK (Offset 0x063C) */
+
+#define BIT_SHIFT_SIFS_R2T_CCK 8
+#define BIT_MASK_SIFS_R2T_CCK 0xff
+#define BIT_SIFS_R2T_CCK(x) \
+ (((x) & BIT_MASK_SIFS_R2T_CCK) << BIT_SHIFT_SIFS_R2T_CCK)
+#define BIT_GET_SIFS_R2T_CCK(x) \
+ (((x) >> BIT_SHIFT_SIFS_R2T_CCK) & BIT_MASK_SIFS_R2T_CCK)
+
+#define BIT_SHIFT_SIFS_T2T_CCK 0
+#define BIT_MASK_SIFS_T2T_CCK 0xff
+#define BIT_SIFS_T2T_CCK(x) \
+ (((x) & BIT_MASK_SIFS_T2T_CCK) << BIT_SHIFT_SIFS_T2T_CCK)
+#define BIT_GET_SIFS_T2T_CCK(x) \
+ (((x) >> BIT_SHIFT_SIFS_T2T_CCK) & BIT_MASK_SIFS_T2T_CCK)
+
+/* 2 REG_RESP_SIFS_OFDM (Offset 0x063E) */
+
+#define BIT_SHIFT_SIFS_R2T_OFDM 8
+#define BIT_MASK_SIFS_R2T_OFDM 0xff
+#define BIT_SIFS_R2T_OFDM(x) \
+ (((x) & BIT_MASK_SIFS_R2T_OFDM) << BIT_SHIFT_SIFS_R2T_OFDM)
+#define BIT_GET_SIFS_R2T_OFDM(x) \
+ (((x) >> BIT_SHIFT_SIFS_R2T_OFDM) & BIT_MASK_SIFS_R2T_OFDM)
+
+#define BIT_SHIFT_SIFS_T2T_OFDM 0
+#define BIT_MASK_SIFS_T2T_OFDM 0xff
+#define BIT_SIFS_T2T_OFDM(x) \
+ (((x) & BIT_MASK_SIFS_T2T_OFDM) << BIT_SHIFT_SIFS_T2T_OFDM)
+#define BIT_GET_SIFS_T2T_OFDM(x) \
+ (((x) >> BIT_SHIFT_SIFS_T2T_OFDM) & BIT_MASK_SIFS_T2T_OFDM)
+
+/* 2 REG_ACKTO (Offset 0x0640) */
+
+#define BIT_SHIFT_ACKTO 0
+#define BIT_MASK_ACKTO 0xff
+#define BIT_ACKTO(x) (((x) & BIT_MASK_ACKTO) << BIT_SHIFT_ACKTO)
+#define BIT_GET_ACKTO(x) (((x) >> BIT_SHIFT_ACKTO) & BIT_MASK_ACKTO)
+
+/* 2 REG_CTS2TO (Offset 0x0641) */
+
+#define BIT_SHIFT_CTS2TO 0
+#define BIT_MASK_CTS2TO 0xff
+#define BIT_CTS2TO(x) (((x) & BIT_MASK_CTS2TO) << BIT_SHIFT_CTS2TO)
+#define BIT_GET_CTS2TO(x) (((x) >> BIT_SHIFT_CTS2TO) & BIT_MASK_CTS2TO)
+
+/* 2 REG_EIFS (Offset 0x0642) */
+
+#define BIT_SHIFT_EIFS 0
+#define BIT_MASK_EIFS 0xffff
+#define BIT_EIFS(x) (((x) & BIT_MASK_EIFS) << BIT_SHIFT_EIFS)
+#define BIT_GET_EIFS(x) (((x) >> BIT_SHIFT_EIFS) & BIT_MASK_EIFS)
+
+/* 2 REG_NAV_CTRL (Offset 0x0650) */
+
+#define BIT_SHIFT_NAV_UPPER 16
+#define BIT_MASK_NAV_UPPER 0xff
+#define BIT_NAV_UPPER(x) (((x) & BIT_MASK_NAV_UPPER) << BIT_SHIFT_NAV_UPPER)
+#define BIT_GET_NAV_UPPER(x) (((x) >> BIT_SHIFT_NAV_UPPER) & BIT_MASK_NAV_UPPER)
+
+#define BIT_SHIFT_RXMYRTS_NAV 8
+#define BIT_MASK_RXMYRTS_NAV 0xf
+#define BIT_RXMYRTS_NAV(x) \
+ (((x) & BIT_MASK_RXMYRTS_NAV) << BIT_SHIFT_RXMYRTS_NAV)
+#define BIT_GET_RXMYRTS_NAV(x) \
+ (((x) >> BIT_SHIFT_RXMYRTS_NAV) & BIT_MASK_RXMYRTS_NAV)
+
+#define BIT_SHIFT_RTSRST 0
+#define BIT_MASK_RTSRST 0xff
+#define BIT_RTSRST(x) (((x) & BIT_MASK_RTSRST) << BIT_SHIFT_RTSRST)
+#define BIT_GET_RTSRST(x) (((x) >> BIT_SHIFT_RTSRST) & BIT_MASK_RTSRST)
+
+/* 2 REG_BACAMCMD (Offset 0x0654) */
+
+#define BIT_BACAM_POLL BIT(31)
+#define BIT_BACAM_RST BIT(17)
+#define BIT_BACAM_RW BIT(16)
+
+#define BIT_SHIFT_TXSBM 14
+#define BIT_MASK_TXSBM 0x3
+#define BIT_TXSBM(x) (((x) & BIT_MASK_TXSBM) << BIT_SHIFT_TXSBM)
+#define BIT_GET_TXSBM(x) (((x) >> BIT_SHIFT_TXSBM) & BIT_MASK_TXSBM)
+
+#define BIT_SHIFT_BACAM_ADDR 0
+#define BIT_MASK_BACAM_ADDR 0x3f
+#define BIT_BACAM_ADDR(x) (((x) & BIT_MASK_BACAM_ADDR) << BIT_SHIFT_BACAM_ADDR)
+#define BIT_GET_BACAM_ADDR(x) \
+ (((x) >> BIT_SHIFT_BACAM_ADDR) & BIT_MASK_BACAM_ADDR)
+
+/* 2 REG_BACAMCONTENT (Offset 0x0658) */
+
+#define BIT_SHIFT_BA_CONTENT_H (32 & CPU_OPT_WIDTH)
+#define BIT_MASK_BA_CONTENT_H 0xffffffffL
+#define BIT_BA_CONTENT_H(x) \
+ (((x) & BIT_MASK_BA_CONTENT_H) << BIT_SHIFT_BA_CONTENT_H)
+#define BIT_GET_BA_CONTENT_H(x) \
+ (((x) >> BIT_SHIFT_BA_CONTENT_H) & BIT_MASK_BA_CONTENT_H)
+
+#define BIT_SHIFT_BA_CONTENT_L 0
+#define BIT_MASK_BA_CONTENT_L 0xffffffffL
+#define BIT_BA_CONTENT_L(x) \
+ (((x) & BIT_MASK_BA_CONTENT_L) << BIT_SHIFT_BA_CONTENT_L)
+#define BIT_GET_BA_CONTENT_L(x) \
+ (((x) >> BIT_SHIFT_BA_CONTENT_L) & BIT_MASK_BA_CONTENT_L)
+
+/* 2 REG_LBDLY (Offset 0x0660) */
+
+#define BIT_SHIFT_LBDLY 0
+#define BIT_MASK_LBDLY 0x1f
+#define BIT_LBDLY(x) (((x) & BIT_MASK_LBDLY) << BIT_SHIFT_LBDLY)
+#define BIT_GET_LBDLY(x) (((x) >> BIT_SHIFT_LBDLY) & BIT_MASK_LBDLY)
+
+/* 2 REG_WMAC_BACAM_RPMEN (Offset 0x0661) */
+
+#define BIT_SHIFT_BITMAP_SSNBK_COUNTER 2
+#define BIT_MASK_BITMAP_SSNBK_COUNTER 0x3f
+#define BIT_BITMAP_SSNBK_COUNTER(x) \
+ (((x) & BIT_MASK_BITMAP_SSNBK_COUNTER) \
+ << BIT_SHIFT_BITMAP_SSNBK_COUNTER)
+#define BIT_GET_BITMAP_SSNBK_COUNTER(x) \
+ (((x) >> BIT_SHIFT_BITMAP_SSNBK_COUNTER) & \
+ BIT_MASK_BITMAP_SSNBK_COUNTER)
+
+#define BIT_BITMAP_EN BIT(1)
+
+/* 2 REG_WMAC_BACAM_RPMEN (Offset 0x0661) */
+
+#define BIT_WMAC_BACAM_RPMEN BIT(0)
+
+/* 2 REG_TX_RX (Offset 0x0662) */
+
+#define BIT_SHIFT_RXPKT_TYPE 2
+#define BIT_MASK_RXPKT_TYPE 0x3f
+#define BIT_RXPKT_TYPE(x) (((x) & BIT_MASK_RXPKT_TYPE) << BIT_SHIFT_RXPKT_TYPE)
+#define BIT_GET_RXPKT_TYPE(x) \
+ (((x) >> BIT_SHIFT_RXPKT_TYPE) & BIT_MASK_RXPKT_TYPE)
+
+#define BIT_TXACT_IND BIT(1)
+#define BIT_RXACT_IND BIT(0)
+
+/* 2 REG_WMAC_BITMAP_CTL (Offset 0x0663) */
+
+#define BIT_BITMAP_VO BIT(7)
+#define BIT_BITMAP_VI BIT(6)
+#define BIT_BITMAP_BE BIT(5)
+#define BIT_BITMAP_BK BIT(4)
+
+#define BIT_SHIFT_BITMAP_CONDITION 2
+#define BIT_MASK_BITMAP_CONDITION 0x3
+#define BIT_BITMAP_CONDITION(x) \
+ (((x) & BIT_MASK_BITMAP_CONDITION) << BIT_SHIFT_BITMAP_CONDITION)
+#define BIT_GET_BITMAP_CONDITION(x) \
+ (((x) >> BIT_SHIFT_BITMAP_CONDITION) & BIT_MASK_BITMAP_CONDITION)
+
+#define BIT_BITMAP_SSNBK_COUNTER_CLR BIT(1)
+#define BIT_BITMAP_FORCE BIT(0)
+
+/* 2 REG_RXERR_RPT (Offset 0x0664) */
+
+#define BIT_SHIFT_RXERR_RPT_SEL_V1_3_0 28
+#define BIT_MASK_RXERR_RPT_SEL_V1_3_0 0xf
+#define BIT_RXERR_RPT_SEL_V1_3_0(x) \
+ (((x) & BIT_MASK_RXERR_RPT_SEL_V1_3_0) \
+ << BIT_SHIFT_RXERR_RPT_SEL_V1_3_0)
+#define BIT_GET_RXERR_RPT_SEL_V1_3_0(x) \
+ (((x) >> BIT_SHIFT_RXERR_RPT_SEL_V1_3_0) & \
+ BIT_MASK_RXERR_RPT_SEL_V1_3_0)
+
+/* 2 REG_RXERR_RPT (Offset 0x0664) */
+
+#define BIT_RXERR_RPT_RST BIT(27)
+
+/* 2 REG_RXERR_RPT (Offset 0x0664) */
+
+#define BIT_RXERR_RPT_SEL_V1_4 BIT(26)
+
+/* 2 REG_RXERR_RPT (Offset 0x0664) */
+
+#define BIT_W1S BIT(23)
+
+/* 2 REG_RXERR_RPT (Offset 0x0664) */
+
+#define BIT_UD_SELECT_BSSID BIT(22)
+
+/* 2 REG_RXERR_RPT (Offset 0x0664) */
+
+#define BIT_SHIFT_UD_SUB_TYPE 18
+#define BIT_MASK_UD_SUB_TYPE 0xf
+#define BIT_UD_SUB_TYPE(x) \
+ (((x) & BIT_MASK_UD_SUB_TYPE) << BIT_SHIFT_UD_SUB_TYPE)
+#define BIT_GET_UD_SUB_TYPE(x) \
+ (((x) >> BIT_SHIFT_UD_SUB_TYPE) & BIT_MASK_UD_SUB_TYPE)
+
+#define BIT_SHIFT_UD_TYPE 16
+#define BIT_MASK_UD_TYPE 0x3
+#define BIT_UD_TYPE(x) (((x) & BIT_MASK_UD_TYPE) << BIT_SHIFT_UD_TYPE)
+#define BIT_GET_UD_TYPE(x) (((x) >> BIT_SHIFT_UD_TYPE) & BIT_MASK_UD_TYPE)
+
+#define BIT_SHIFT_RPT_COUNTER 0
+#define BIT_MASK_RPT_COUNTER 0xffff
+#define BIT_RPT_COUNTER(x) \
+ (((x) & BIT_MASK_RPT_COUNTER) << BIT_SHIFT_RPT_COUNTER)
+#define BIT_GET_RPT_COUNTER(x) \
+ (((x) >> BIT_SHIFT_RPT_COUNTER) & BIT_MASK_RPT_COUNTER)
+
+/* 2 REG_WMAC_TRXPTCL_CTL (Offset 0x0668) */
+
+#define BIT_SHIFT_ACKBA_TYPSEL (60 & CPU_OPT_WIDTH)
+#define BIT_MASK_ACKBA_TYPSEL 0xf
+#define BIT_ACKBA_TYPSEL(x) \
+ (((x) & BIT_MASK_ACKBA_TYPSEL) << BIT_SHIFT_ACKBA_TYPSEL)
+#define BIT_GET_ACKBA_TYPSEL(x) \
+ (((x) >> BIT_SHIFT_ACKBA_TYPSEL) & BIT_MASK_ACKBA_TYPSEL)
+
+#define BIT_SHIFT_ACKBA_ACKPCHK (56 & CPU_OPT_WIDTH)
+#define BIT_MASK_ACKBA_ACKPCHK 0xf
+#define BIT_ACKBA_ACKPCHK(x) \
+ (((x) & BIT_MASK_ACKBA_ACKPCHK) << BIT_SHIFT_ACKBA_ACKPCHK)
+#define BIT_GET_ACKBA_ACKPCHK(x) \
+ (((x) >> BIT_SHIFT_ACKBA_ACKPCHK) & BIT_MASK_ACKBA_ACKPCHK)
+
+#define BIT_SHIFT_ACKBAR_TYPESEL (48 & CPU_OPT_WIDTH)
+#define BIT_MASK_ACKBAR_TYPESEL 0xff
+#define BIT_ACKBAR_TYPESEL(x) \
+ (((x) & BIT_MASK_ACKBAR_TYPESEL) << BIT_SHIFT_ACKBAR_TYPESEL)
+#define BIT_GET_ACKBAR_TYPESEL(x) \
+ (((x) >> BIT_SHIFT_ACKBAR_TYPESEL) & BIT_MASK_ACKBAR_TYPESEL)
+
+#define BIT_SHIFT_ACKBAR_ACKPCHK (44 & CPU_OPT_WIDTH)
+#define BIT_MASK_ACKBAR_ACKPCHK 0xf
+#define BIT_ACKBAR_ACKPCHK(x) \
+ (((x) & BIT_MASK_ACKBAR_ACKPCHK) << BIT_SHIFT_ACKBAR_ACKPCHK)
+#define BIT_GET_ACKBAR_ACKPCHK(x) \
+ (((x) >> BIT_SHIFT_ACKBAR_ACKPCHK) & BIT_MASK_ACKBAR_ACKPCHK)
+
+/* 2 REG_WMAC_TRXPTCL_CTL (Offset 0x0668) */
+
+#define BIT_RXBA_IGNOREA2 BIT(42)
+#define BIT_EN_SAVE_ALL_TXOPADDR BIT(41)
+#define BIT_EN_TXCTS_TO_TXOPOWNER_INRXNAV BIT(40)
+
+/* 2 REG_WMAC_TRXPTCL_CTL (Offset 0x0668) */
+
+#define BIT_DIS_TXBA_AMPDUFCSERR BIT(39)
+#define BIT_DIS_TXBA_RXBARINFULL BIT(38)
+#define BIT_DIS_TXCFE_INFULL BIT(37)
+#define BIT_DIS_TXCTS_INFULL BIT(36)
+#define BIT_EN_TXACKBA_IN_TX_RDG BIT(35)
+#define BIT_EN_TXACKBA_IN_TXOP BIT(34)
+#define BIT_EN_TXCTS_IN_RXNAV BIT(33)
+#define BIT_EN_TXCTS_INTXOP BIT(32)
+#define BIT_BLK_EDCA_BBSLP BIT(31)
+#define BIT_BLK_EDCA_BBSBY BIT(30)
+#define BIT_ACKTO_BLOCK_SCH_EN BIT(27)
+#define BIT_EIFS_BLOCK_SCH_EN BIT(26)
+#define BIT_PLCPCHK_RST_EIFS BIT(25)
+#define BIT_CCA_RST_EIFS BIT(24)
+#define BIT_DIS_UPD_MYRXPKTNAV BIT(23)
+#define BIT_EARLY_TXBA BIT(22)
+
+#define BIT_SHIFT_RESP_CHNBUSY 20
+#define BIT_MASK_RESP_CHNBUSY 0x3
+#define BIT_RESP_CHNBUSY(x) \
+ (((x) & BIT_MASK_RESP_CHNBUSY) << BIT_SHIFT_RESP_CHNBUSY)
+#define BIT_GET_RESP_CHNBUSY(x) \
+ (((x) >> BIT_SHIFT_RESP_CHNBUSY) & BIT_MASK_RESP_CHNBUSY)
+
+#define BIT_RESP_DCTS_EN BIT(19)
+#define BIT_RESP_DCFE_EN BIT(18)
+#define BIT_RESP_SPLCPEN BIT(17)
+#define BIT_RESP_SGIEN BIT(16)
+
+/* 2 REG_WMAC_TRXPTCL_CTL (Offset 0x0668) */
+
+#define BIT_RESP_LDPC_EN BIT(15)
+#define BIT_DIS_RESP_ACKINCCA BIT(14)
+#define BIT_DIS_RESP_CTSINCCA BIT(13)
+
+/* 2 REG_WMAC_TRXPTCL_CTL (Offset 0x0668) */
+
+#define BIT_SHIFT_R_WMAC_SECOND_CCA_TIMER 10
+#define BIT_MASK_R_WMAC_SECOND_CCA_TIMER 0x7
+#define BIT_R_WMAC_SECOND_CCA_TIMER(x) \
+ (((x) & BIT_MASK_R_WMAC_SECOND_CCA_TIMER) \
+ << BIT_SHIFT_R_WMAC_SECOND_CCA_TIMER)
+#define BIT_GET_R_WMAC_SECOND_CCA_TIMER(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_SECOND_CCA_TIMER) & \
+ BIT_MASK_R_WMAC_SECOND_CCA_TIMER)
+
+/* 2 REG_WMAC_TRXPTCL_CTL (Offset 0x0668) */
+
+#define BIT_SHIFT_RFMOD 7
+#define BIT_MASK_RFMOD 0x3
+#define BIT_RFMOD(x) (((x) & BIT_MASK_RFMOD) << BIT_SHIFT_RFMOD)
+#define BIT_GET_RFMOD(x) (((x) >> BIT_SHIFT_RFMOD) & BIT_MASK_RFMOD)
+
+/* 2 REG_WMAC_TRXPTCL_CTL (Offset 0x0668) */
+
+#define BIT_SHIFT_RESP_CTS_DYNBW_SEL 5
+#define BIT_MASK_RESP_CTS_DYNBW_SEL 0x3
+#define BIT_RESP_CTS_DYNBW_SEL(x) \
+ (((x) & BIT_MASK_RESP_CTS_DYNBW_SEL) << BIT_SHIFT_RESP_CTS_DYNBW_SEL)
+#define BIT_GET_RESP_CTS_DYNBW_SEL(x) \
+ (((x) >> BIT_SHIFT_RESP_CTS_DYNBW_SEL) & BIT_MASK_RESP_CTS_DYNBW_SEL)
+
+/* 2 REG_WMAC_TRXPTCL_CTL (Offset 0x0668) */
+
+#define BIT_DLY_TX_WAIT_RXANTSEL BIT(4)
+
+/* 2 REG_WMAC_TRXPTCL_CTL (Offset 0x0668) */
+
+#define BIT_TXRESP_BY_RXANTSEL BIT(3)
+
+/* 2 REG_WMAC_TRXPTCL_CTL (Offset 0x0668) */
+
+#define BIT_SHIFT_ORIG_DCTS_CHK 0
+#define BIT_MASK_ORIG_DCTS_CHK 0x3
+#define BIT_ORIG_DCTS_CHK(x) \
+ (((x) & BIT_MASK_ORIG_DCTS_CHK) << BIT_SHIFT_ORIG_DCTS_CHK)
+#define BIT_GET_ORIG_DCTS_CHK(x) \
+ (((x) >> BIT_SHIFT_ORIG_DCTS_CHK) & BIT_MASK_ORIG_DCTS_CHK)
+
+/* 2 REG_CAMCMD (Offset 0x0670) */
+
+#define BIT_SECCAM_POLLING BIT(31)
+#define BIT_SECCAM_CLR BIT(30)
+#define BIT_MFBCAM_CLR BIT(29)
+
+/* 2 REG_CAMCMD (Offset 0x0670) */
+
+#define BIT_SECCAM_WE BIT(16)
+
+/* 2 REG_CAMCMD (Offset 0x0670) */
+
+#define BIT_SHIFT_SECCAM_ADDR_V2 0
+#define BIT_MASK_SECCAM_ADDR_V2 0x3ff
+#define BIT_SECCAM_ADDR_V2(x) \
+ (((x) & BIT_MASK_SECCAM_ADDR_V2) << BIT_SHIFT_SECCAM_ADDR_V2)
+#define BIT_GET_SECCAM_ADDR_V2(x) \
+ (((x) >> BIT_SHIFT_SECCAM_ADDR_V2) & BIT_MASK_SECCAM_ADDR_V2)
+
+/* 2 REG_CAMWRITE (Offset 0x0674) */
+
+#define BIT_SHIFT_CAMW_DATA 0
+#define BIT_MASK_CAMW_DATA 0xffffffffL
+#define BIT_CAMW_DATA(x) (((x) & BIT_MASK_CAMW_DATA) << BIT_SHIFT_CAMW_DATA)
+#define BIT_GET_CAMW_DATA(x) (((x) >> BIT_SHIFT_CAMW_DATA) & BIT_MASK_CAMW_DATA)
+
+/* 2 REG_CAMREAD (Offset 0x0678) */
+
+#define BIT_SHIFT_CAMR_DATA 0
+#define BIT_MASK_CAMR_DATA 0xffffffffL
+#define BIT_CAMR_DATA(x) (((x) & BIT_MASK_CAMR_DATA) << BIT_SHIFT_CAMR_DATA)
+#define BIT_GET_CAMR_DATA(x) (((x) >> BIT_SHIFT_CAMR_DATA) & BIT_MASK_CAMR_DATA)
+
+/* 2 REG_CAMDBG (Offset 0x067C) */
+
+#define BIT_SECCAM_INFO BIT(31)
+#define BIT_SEC_KEYFOUND BIT(15)
+
+#define BIT_SHIFT_CAMDBG_SEC_TYPE 12
+#define BIT_MASK_CAMDBG_SEC_TYPE 0x7
+#define BIT_CAMDBG_SEC_TYPE(x) \
+ (((x) & BIT_MASK_CAMDBG_SEC_TYPE) << BIT_SHIFT_CAMDBG_SEC_TYPE)
+#define BIT_GET_CAMDBG_SEC_TYPE(x) \
+ (((x) >> BIT_SHIFT_CAMDBG_SEC_TYPE) & BIT_MASK_CAMDBG_SEC_TYPE)
+
+/* 2 REG_CAMDBG (Offset 0x067C) */
+
+#define BIT_CAMDBG_EXT_SECTYPE BIT(11)
+
+/* 2 REG_CAMDBG (Offset 0x067C) */
+
+#define BIT_SHIFT_CAMDBG_MIC_KEY_IDX 5
+#define BIT_MASK_CAMDBG_MIC_KEY_IDX 0x1f
+#define BIT_CAMDBG_MIC_KEY_IDX(x) \
+ (((x) & BIT_MASK_CAMDBG_MIC_KEY_IDX) << BIT_SHIFT_CAMDBG_MIC_KEY_IDX)
+#define BIT_GET_CAMDBG_MIC_KEY_IDX(x) \
+ (((x) >> BIT_SHIFT_CAMDBG_MIC_KEY_IDX) & BIT_MASK_CAMDBG_MIC_KEY_IDX)
+
+#define BIT_SHIFT_CAMDBG_SEC_KEY_IDX 0
+#define BIT_MASK_CAMDBG_SEC_KEY_IDX 0x1f
+#define BIT_CAMDBG_SEC_KEY_IDX(x) \
+ (((x) & BIT_MASK_CAMDBG_SEC_KEY_IDX) << BIT_SHIFT_CAMDBG_SEC_KEY_IDX)
+#define BIT_GET_CAMDBG_SEC_KEY_IDX(x) \
+ (((x) >> BIT_SHIFT_CAMDBG_SEC_KEY_IDX) & BIT_MASK_CAMDBG_SEC_KEY_IDX)
+
+/* 2 REG_SECCFG (Offset 0x0680) */
+
+#define BIT_DIS_GCLK_WAPI BIT(15)
+#define BIT_DIS_GCLK_AES BIT(14)
+#define BIT_DIS_GCLK_TKIP BIT(13)
+
+/* 2 REG_SECCFG (Offset 0x0680) */
+
+#define BIT_AES_SEL_QC_1 BIT(12)
+#define BIT_AES_SEL_QC_0 BIT(11)
+
+/* 2 REG_SECCFG (Offset 0x0680) */
+
+#define BIT_CHK_BMC BIT(9)
+
+/* 2 REG_SECCFG (Offset 0x0680) */
+
+#define BIT_CHK_KEYID BIT(8)
+#define BIT_RXBCUSEDK BIT(7)
+#define BIT_TXBCUSEDK BIT(6)
+#define BIT_NOSKMC BIT(5)
+#define BIT_SKBYA2 BIT(4)
+#define BIT_RXDEC BIT(3)
+#define BIT_TXENC BIT(2)
+#define BIT_RXUHUSEDK BIT(1)
+#define BIT_TXUHUSEDK BIT(0)
+
+/* 2 REG_RXFILTER_CATEGORY_1 (Offset 0x0682) */
+
+#define BIT_SHIFT_RXFILTER_CATEGORY_1 0
+#define BIT_MASK_RXFILTER_CATEGORY_1 0xff
+#define BIT_RXFILTER_CATEGORY_1(x) \
+ (((x) & BIT_MASK_RXFILTER_CATEGORY_1) << BIT_SHIFT_RXFILTER_CATEGORY_1)
+#define BIT_GET_RXFILTER_CATEGORY_1(x) \
+ (((x) >> BIT_SHIFT_RXFILTER_CATEGORY_1) & BIT_MASK_RXFILTER_CATEGORY_1)
+
+/* 2 REG_RXFILTER_ACTION_1 (Offset 0x0683) */
+
+#define BIT_SHIFT_RXFILTER_ACTION_1 0
+#define BIT_MASK_RXFILTER_ACTION_1 0xff
+#define BIT_RXFILTER_ACTION_1(x) \
+ (((x) & BIT_MASK_RXFILTER_ACTION_1) << BIT_SHIFT_RXFILTER_ACTION_1)
+#define BIT_GET_RXFILTER_ACTION_1(x) \
+ (((x) >> BIT_SHIFT_RXFILTER_ACTION_1) & BIT_MASK_RXFILTER_ACTION_1)
+
+/* 2 REG_RXFILTER_CATEGORY_2 (Offset 0x0684) */
+
+#define BIT_SHIFT_RXFILTER_CATEGORY_2 0
+#define BIT_MASK_RXFILTER_CATEGORY_2 0xff
+#define BIT_RXFILTER_CATEGORY_2(x) \
+ (((x) & BIT_MASK_RXFILTER_CATEGORY_2) << BIT_SHIFT_RXFILTER_CATEGORY_2)
+#define BIT_GET_RXFILTER_CATEGORY_2(x) \
+ (((x) >> BIT_SHIFT_RXFILTER_CATEGORY_2) & BIT_MASK_RXFILTER_CATEGORY_2)
+
+/* 2 REG_RXFILTER_ACTION_2 (Offset 0x0685) */
+
+#define BIT_SHIFT_RXFILTER_ACTION_2 0
+#define BIT_MASK_RXFILTER_ACTION_2 0xff
+#define BIT_RXFILTER_ACTION_2(x) \
+ (((x) & BIT_MASK_RXFILTER_ACTION_2) << BIT_SHIFT_RXFILTER_ACTION_2)
+#define BIT_GET_RXFILTER_ACTION_2(x) \
+ (((x) >> BIT_SHIFT_RXFILTER_ACTION_2) & BIT_MASK_RXFILTER_ACTION_2)
+
+/* 2 REG_RXFILTER_CATEGORY_3 (Offset 0x0686) */
+
+#define BIT_SHIFT_RXFILTER_CATEGORY_3 0
+#define BIT_MASK_RXFILTER_CATEGORY_3 0xff
+#define BIT_RXFILTER_CATEGORY_3(x) \
+ (((x) & BIT_MASK_RXFILTER_CATEGORY_3) << BIT_SHIFT_RXFILTER_CATEGORY_3)
+#define BIT_GET_RXFILTER_CATEGORY_3(x) \
+ (((x) >> BIT_SHIFT_RXFILTER_CATEGORY_3) & BIT_MASK_RXFILTER_CATEGORY_3)
+
+/* 2 REG_RXFILTER_ACTION_3 (Offset 0x0687) */
+
+#define BIT_SHIFT_RXFILTER_ACTION_3 0
+#define BIT_MASK_RXFILTER_ACTION_3 0xff
+#define BIT_RXFILTER_ACTION_3(x) \
+ (((x) & BIT_MASK_RXFILTER_ACTION_3) << BIT_SHIFT_RXFILTER_ACTION_3)
+#define BIT_GET_RXFILTER_ACTION_3(x) \
+ (((x) >> BIT_SHIFT_RXFILTER_ACTION_3) & BIT_MASK_RXFILTER_ACTION_3)
+
+/* 2 REG_RXFLTMAP3 (Offset 0x0688) */
+
+#define BIT_MGTFLT15EN_FW BIT(15)
+#define BIT_MGTFLT14EN_FW BIT(14)
+#define BIT_MGTFLT13EN_FW BIT(13)
+#define BIT_MGTFLT12EN_FW BIT(12)
+#define BIT_MGTFLT11EN_FW BIT(11)
+#define BIT_MGTFLT10EN_FW BIT(10)
+#define BIT_MGTFLT9EN_FW BIT(9)
+#define BIT_MGTFLT8EN_FW BIT(8)
+#define BIT_MGTFLT7EN_FW BIT(7)
+#define BIT_MGTFLT6EN_FW BIT(6)
+#define BIT_MGTFLT5EN_FW BIT(5)
+#define BIT_MGTFLT4EN_FW BIT(4)
+#define BIT_MGTFLT3EN_FW BIT(3)
+#define BIT_MGTFLT2EN_FW BIT(2)
+#define BIT_MGTFLT1EN_FW BIT(1)
+#define BIT_MGTFLT0EN_FW BIT(0)
+
+/* 2 REG_RXFLTMAP4 (Offset 0x068A) */
+
+#define BIT_CTRLFLT15EN_FW BIT(15)
+#define BIT_CTRLFLT14EN_FW BIT(14)
+#define BIT_CTRLFLT13EN_FW BIT(13)
+#define BIT_CTRLFLT12EN_FW BIT(12)
+#define BIT_CTRLFLT11EN_FW BIT(11)
+#define BIT_CTRLFLT10EN_FW BIT(10)
+#define BIT_CTRLFLT9EN_FW BIT(9)
+#define BIT_CTRLFLT8EN_FW BIT(8)
+#define BIT_CTRLFLT7EN_FW BIT(7)
+#define BIT_CTRLFLT6EN_FW BIT(6)
+#define BIT_CTRLFLT5EN_FW BIT(5)
+#define BIT_CTRLFLT4EN_FW BIT(4)
+#define BIT_CTRLFLT3EN_FW BIT(3)
+#define BIT_CTRLFLT2EN_FW BIT(2)
+#define BIT_CTRLFLT1EN_FW BIT(1)
+#define BIT_CTRLFLT0EN_FW BIT(0)
+
+/* 2 REG_RXFLTMAP5 (Offset 0x068C) */
+
+#define BIT_DATAFLT15EN_FW BIT(15)
+#define BIT_DATAFLT14EN_FW BIT(14)
+#define BIT_DATAFLT13EN_FW BIT(13)
+#define BIT_DATAFLT12EN_FW BIT(12)
+#define BIT_DATAFLT11EN_FW BIT(11)
+#define BIT_DATAFLT10EN_FW BIT(10)
+#define BIT_DATAFLT9EN_FW BIT(9)
+#define BIT_DATAFLT8EN_FW BIT(8)
+#define BIT_DATAFLT7EN_FW BIT(7)
+#define BIT_DATAFLT6EN_FW BIT(6)
+#define BIT_DATAFLT5EN_FW BIT(5)
+#define BIT_DATAFLT4EN_FW BIT(4)
+#define BIT_DATAFLT3EN_FW BIT(3)
+#define BIT_DATAFLT2EN_FW BIT(2)
+#define BIT_DATAFLT1EN_FW BIT(1)
+#define BIT_DATAFLT0EN_FW BIT(0)
+
+/* 2 REG_RXFLTMAP6 (Offset 0x068E) */
+
+#define BIT_ACTIONFLT15EN_FW BIT(15)
+#define BIT_ACTIONFLT14EN_FW BIT(14)
+#define BIT_ACTIONFLT13EN_FW BIT(13)
+#define BIT_ACTIONFLT12EN_FW BIT(12)
+#define BIT_ACTIONFLT11EN_FW BIT(11)
+#define BIT_ACTIONFLT10EN_FW BIT(10)
+#define BIT_ACTIONFLT9EN_FW BIT(9)
+#define BIT_ACTIONFLT8EN_FW BIT(8)
+#define BIT_ACTIONFLT7EN_FW BIT(7)
+#define BIT_ACTIONFLT6EN_FW BIT(6)
+#define BIT_ACTIONFLT5EN_FW BIT(5)
+#define BIT_ACTIONFLT4EN_FW BIT(4)
+#define BIT_ACTIONFLT3EN_FW BIT(3)
+#define BIT_ACTIONFLT2EN_FW BIT(2)
+#define BIT_ACTIONFLT1EN_FW BIT(1)
+#define BIT_ACTIONFLT0EN_FW BIT(0)
+
+/* 2 REG_WOW_CTRL (Offset 0x0690) */
+
+#define BIT_SHIFT_PSF_BSSIDSEL_B2B1 6
+#define BIT_MASK_PSF_BSSIDSEL_B2B1 0x3
+#define BIT_PSF_BSSIDSEL_B2B1(x) \
+ (((x) & BIT_MASK_PSF_BSSIDSEL_B2B1) << BIT_SHIFT_PSF_BSSIDSEL_B2B1)
+#define BIT_GET_PSF_BSSIDSEL_B2B1(x) \
+ (((x) >> BIT_SHIFT_PSF_BSSIDSEL_B2B1) & BIT_MASK_PSF_BSSIDSEL_B2B1)
+
+/* 2 REG_WOW_CTRL (Offset 0x0690) */
+
+#define BIT_WOWHCI BIT(5)
+
+/* 2 REG_WOW_CTRL (Offset 0x0690) */
+
+#define BIT_PSF_BSSIDSEL_B0 BIT(4)
+
+/* 2 REG_WOW_CTRL (Offset 0x0690) */
+
+#define BIT_UWF BIT(3)
+#define BIT_MAGIC BIT(2)
+#define BIT_WOWEN BIT(1)
+#define BIT_FORCE_WAKEUP BIT(0)
+
+/* 2 REG_NAN_RX_TSF_FILTER (Offset 0x0691) */
+
+#define BIT_CHK_TSF_TA BIT(2)
+#define BIT_CHK_TSF_CBSSID BIT(1)
+#define BIT_CHK_TSF_EN BIT(0)
+
+/* 2 REG_PS_RX_INFO (Offset 0x0692) */
+
+#define BIT_SHIFT_PORTSEL__PS_RX_INFO 5
+#define BIT_MASK_PORTSEL__PS_RX_INFO 0x7
+#define BIT_PORTSEL__PS_RX_INFO(x) \
+ (((x) & BIT_MASK_PORTSEL__PS_RX_INFO) << BIT_SHIFT_PORTSEL__PS_RX_INFO)
+#define BIT_GET_PORTSEL__PS_RX_INFO(x) \
+ (((x) >> BIT_SHIFT_PORTSEL__PS_RX_INFO) & BIT_MASK_PORTSEL__PS_RX_INFO)
+
+/* 2 REG_PS_RX_INFO (Offset 0x0692) */
+
+#define BIT_RXCTRLIN0 BIT(4)
+#define BIT_RXMGTIN0 BIT(3)
+#define BIT_RXDATAIN2 BIT(2)
+#define BIT_RXDATAIN1 BIT(1)
+#define BIT_RXDATAIN0 BIT(0)
+
+/* 2 REG_WMMPS_UAPSD_TID (Offset 0x0693) */
+
+#define BIT_WMMPS_UAPSD_TID7 BIT(7)
+#define BIT_WMMPS_UAPSD_TID6 BIT(6)
+#define BIT_WMMPS_UAPSD_TID5 BIT(5)
+#define BIT_WMMPS_UAPSD_TID4 BIT(4)
+#define BIT_WMMPS_UAPSD_TID3 BIT(3)
+#define BIT_WMMPS_UAPSD_TID2 BIT(2)
+#define BIT_WMMPS_UAPSD_TID1 BIT(1)
+#define BIT_WMMPS_UAPSD_TID0 BIT(0)
+
+/* 2 REG_LPNAV_CTRL (Offset 0x0694) */
+
+#define BIT_LPNAV_EN BIT(31)
+
+#define BIT_SHIFT_LPNAV_EARLY 16
+#define BIT_MASK_LPNAV_EARLY 0x7fff
+#define BIT_LPNAV_EARLY(x) \
+ (((x) & BIT_MASK_LPNAV_EARLY) << BIT_SHIFT_LPNAV_EARLY)
+#define BIT_GET_LPNAV_EARLY(x) \
+ (((x) >> BIT_SHIFT_LPNAV_EARLY) & BIT_MASK_LPNAV_EARLY)
+
+#define BIT_SHIFT_LPNAV_TH 0
+#define BIT_MASK_LPNAV_TH 0xffff
+#define BIT_LPNAV_TH(x) (((x) & BIT_MASK_LPNAV_TH) << BIT_SHIFT_LPNAV_TH)
+#define BIT_GET_LPNAV_TH(x) (((x) >> BIT_SHIFT_LPNAV_TH) & BIT_MASK_LPNAV_TH)
+
+/* 2 REG_WKFMCAM_CMD (Offset 0x0698) */
+
+#define BIT_WKFCAM_POLLING_V1 BIT(31)
+#define BIT_WKFCAM_CLR_V1 BIT(30)
+
+/* 2 REG_WKFMCAM_CMD (Offset 0x0698) */
+
+#define BIT_WKFCAM_WE BIT(16)
+
+/* 2 REG_WKFMCAM_CMD (Offset 0x0698) */
+
+#define BIT_SHIFT_WKFCAM_ADDR_V2 8
+#define BIT_MASK_WKFCAM_ADDR_V2 0xff
+#define BIT_WKFCAM_ADDR_V2(x) \
+ (((x) & BIT_MASK_WKFCAM_ADDR_V2) << BIT_SHIFT_WKFCAM_ADDR_V2)
+#define BIT_GET_WKFCAM_ADDR_V2(x) \
+ (((x) >> BIT_SHIFT_WKFCAM_ADDR_V2) & BIT_MASK_WKFCAM_ADDR_V2)
+
+#define BIT_SHIFT_WKFCAM_CAM_NUM_V1 0
+#define BIT_MASK_WKFCAM_CAM_NUM_V1 0xff
+#define BIT_WKFCAM_CAM_NUM_V1(x) \
+ (((x) & BIT_MASK_WKFCAM_CAM_NUM_V1) << BIT_SHIFT_WKFCAM_CAM_NUM_V1)
+#define BIT_GET_WKFCAM_CAM_NUM_V1(x) \
+ (((x) >> BIT_SHIFT_WKFCAM_CAM_NUM_V1) & BIT_MASK_WKFCAM_CAM_NUM_V1)
+
+/* 2 REG_WKFMCAM_RWD (Offset 0x069C) */
+
+#define BIT_SHIFT_WKFMCAM_RWD 0
+#define BIT_MASK_WKFMCAM_RWD 0xffffffffL
+#define BIT_WKFMCAM_RWD(x) \
+ (((x) & BIT_MASK_WKFMCAM_RWD) << BIT_SHIFT_WKFMCAM_RWD)
+#define BIT_GET_WKFMCAM_RWD(x) \
+ (((x) >> BIT_SHIFT_WKFMCAM_RWD) & BIT_MASK_WKFMCAM_RWD)
+
+/* 2 REG_RXFLTMAP0 (Offset 0x06A0) */
+
+#define BIT_MGTFLT15EN BIT(15)
+#define BIT_MGTFLT14EN BIT(14)
+
+/* 2 REG_RXFLTMAP0 (Offset 0x06A0) */
+
+#define BIT_MGTFLT13EN BIT(13)
+#define BIT_MGTFLT12EN BIT(12)
+#define BIT_MGTFLT11EN BIT(11)
+#define BIT_MGTFLT10EN BIT(10)
+#define BIT_MGTFLT9EN BIT(9)
+#define BIT_MGTFLT8EN BIT(8)
+
+/* 2 REG_RXFLTMAP0 (Offset 0x06A0) */
+
+#define BIT_MGTFLT7EN BIT(7)
+#define BIT_MGTFLT6EN BIT(6)
+
+/* 2 REG_RXFLTMAP0 (Offset 0x06A0) */
+
+#define BIT_MGTFLT5EN BIT(5)
+#define BIT_MGTFLT4EN BIT(4)
+#define BIT_MGTFLT3EN BIT(3)
+#define BIT_MGTFLT2EN BIT(2)
+#define BIT_MGTFLT1EN BIT(1)
+#define BIT_MGTFLT0EN BIT(0)
+
+/* 2 REG_RXFLTMAP1 (Offset 0x06A2) */
+
+#define BIT_CTRLFLT15EN BIT(15)
+#define BIT_CTRLFLT14EN BIT(14)
+#define BIT_CTRLFLT13EN BIT(13)
+#define BIT_CTRLFLT12EN BIT(12)
+#define BIT_CTRLFLT11EN BIT(11)
+#define BIT_CTRLFLT10EN BIT(10)
+#define BIT_CTRLFLT9EN BIT(9)
+#define BIT_CTRLFLT8EN BIT(8)
+#define BIT_CTRLFLT7EN BIT(7)
+#define BIT_CTRLFLT6EN BIT(6)
+
+/* 2 REG_RXFLTMAP1 (Offset 0x06A2) */
+
+#define BIT_CTRLFLT5EN BIT(5)
+#define BIT_CTRLFLT4EN BIT(4)
+#define BIT_CTRLFLT3EN BIT(3)
+#define BIT_CTRLFLT2EN BIT(2)
+#define BIT_CTRLFLT1EN BIT(1)
+#define BIT_CTRLFLT0EN BIT(0)
+
+/* 2 REG_RXFLTMAP (Offset 0x06A4) */
+
+#define BIT_DATAFLT15EN BIT(15)
+#define BIT_DATAFLT14EN BIT(14)
+#define BIT_DATAFLT13EN BIT(13)
+#define BIT_DATAFLT12EN BIT(12)
+#define BIT_DATAFLT11EN BIT(11)
+#define BIT_DATAFLT10EN BIT(10)
+#define BIT_DATAFLT9EN BIT(9)
+#define BIT_DATAFLT8EN BIT(8)
+#define BIT_DATAFLT7EN BIT(7)
+#define BIT_DATAFLT6EN BIT(6)
+#define BIT_DATAFLT5EN BIT(5)
+#define BIT_DATAFLT4EN BIT(4)
+#define BIT_DATAFLT3EN BIT(3)
+#define BIT_DATAFLT2EN BIT(2)
+#define BIT_DATAFLT1EN BIT(1)
+#define BIT_DATAFLT0EN BIT(0)
+
+/* 2 REG_BCN_PSR_RPT (Offset 0x06A8) */
+
+#define BIT_SHIFT_DTIM_CNT 24
+#define BIT_MASK_DTIM_CNT 0xff
+#define BIT_DTIM_CNT(x) (((x) & BIT_MASK_DTIM_CNT) << BIT_SHIFT_DTIM_CNT)
+#define BIT_GET_DTIM_CNT(x) (((x) >> BIT_SHIFT_DTIM_CNT) & BIT_MASK_DTIM_CNT)
+
+#define BIT_SHIFT_DTIM_PERIOD 16
+#define BIT_MASK_DTIM_PERIOD 0xff
+#define BIT_DTIM_PERIOD(x) \
+ (((x) & BIT_MASK_DTIM_PERIOD) << BIT_SHIFT_DTIM_PERIOD)
+#define BIT_GET_DTIM_PERIOD(x) \
+ (((x) >> BIT_SHIFT_DTIM_PERIOD) & BIT_MASK_DTIM_PERIOD)
+
+#define BIT_DTIM BIT(15)
+#define BIT_TIM BIT(14)
+
+#define BIT_SHIFT_PS_AID_0 0
+#define BIT_MASK_PS_AID_0 0x7ff
+#define BIT_PS_AID_0(x) (((x) & BIT_MASK_PS_AID_0) << BIT_SHIFT_PS_AID_0)
+#define BIT_GET_PS_AID_0(x) (((x) >> BIT_SHIFT_PS_AID_0) & BIT_MASK_PS_AID_0)
+
+/* 2 REG_FLC_RPC (Offset 0x06AC) */
+
+#define BIT_SHIFT_FLC_RPC 0
+#define BIT_MASK_FLC_RPC 0xff
+#define BIT_FLC_RPC(x) (((x) & BIT_MASK_FLC_RPC) << BIT_SHIFT_FLC_RPC)
+#define BIT_GET_FLC_RPC(x) (((x) >> BIT_SHIFT_FLC_RPC) & BIT_MASK_FLC_RPC)
+
+/* 2 REG_FLC_RPCT (Offset 0x06AD) */
+
+#define BIT_SHIFT_FLC_RPCT 0
+#define BIT_MASK_FLC_RPCT 0xff
+#define BIT_FLC_RPCT(x) (((x) & BIT_MASK_FLC_RPCT) << BIT_SHIFT_FLC_RPCT)
+#define BIT_GET_FLC_RPCT(x) (((x) >> BIT_SHIFT_FLC_RPCT) & BIT_MASK_FLC_RPCT)
+
+/* 2 REG_FLC_PTS (Offset 0x06AE) */
+
+#define BIT_CMF BIT(2)
+#define BIT_CCF BIT(1)
+#define BIT_CDF BIT(0)
+
+/* 2 REG_FLC_TRPC (Offset 0x06AF) */
+
+#define BIT_FLC_RPCT_V1 BIT(7)
+#define BIT_MODE BIT(6)
+
+#define BIT_SHIFT_TRPCD 0
+#define BIT_MASK_TRPCD 0x3f
+#define BIT_TRPCD(x) (((x) & BIT_MASK_TRPCD) << BIT_SHIFT_TRPCD)
+#define BIT_GET_TRPCD(x) (((x) >> BIT_SHIFT_TRPCD) & BIT_MASK_TRPCD)
+
+/* 2 REG_RXPKTMON_CTRL (Offset 0x06B0) */
+
+#define BIT_SHIFT_RXBKQPKT_SEQ 20
+#define BIT_MASK_RXBKQPKT_SEQ 0xf
+#define BIT_RXBKQPKT_SEQ(x) \
+ (((x) & BIT_MASK_RXBKQPKT_SEQ) << BIT_SHIFT_RXBKQPKT_SEQ)
+#define BIT_GET_RXBKQPKT_SEQ(x) \
+ (((x) >> BIT_SHIFT_RXBKQPKT_SEQ) & BIT_MASK_RXBKQPKT_SEQ)
+
+#define BIT_SHIFT_RXBEQPKT_SEQ 16
+#define BIT_MASK_RXBEQPKT_SEQ 0xf
+#define BIT_RXBEQPKT_SEQ(x) \
+ (((x) & BIT_MASK_RXBEQPKT_SEQ) << BIT_SHIFT_RXBEQPKT_SEQ)
+#define BIT_GET_RXBEQPKT_SEQ(x) \
+ (((x) >> BIT_SHIFT_RXBEQPKT_SEQ) & BIT_MASK_RXBEQPKT_SEQ)
+
+#define BIT_SHIFT_RXVIQPKT_SEQ 12
+#define BIT_MASK_RXVIQPKT_SEQ 0xf
+#define BIT_RXVIQPKT_SEQ(x) \
+ (((x) & BIT_MASK_RXVIQPKT_SEQ) << BIT_SHIFT_RXVIQPKT_SEQ)
+#define BIT_GET_RXVIQPKT_SEQ(x) \
+ (((x) >> BIT_SHIFT_RXVIQPKT_SEQ) & BIT_MASK_RXVIQPKT_SEQ)
+
+#define BIT_SHIFT_RXVOQPKT_SEQ 8
+#define BIT_MASK_RXVOQPKT_SEQ 0xf
+#define BIT_RXVOQPKT_SEQ(x) \
+ (((x) & BIT_MASK_RXVOQPKT_SEQ) << BIT_SHIFT_RXVOQPKT_SEQ)
+#define BIT_GET_RXVOQPKT_SEQ(x) \
+ (((x) >> BIT_SHIFT_RXVOQPKT_SEQ) & BIT_MASK_RXVOQPKT_SEQ)
+
+#define BIT_RXBKQPKT_ERR BIT(7)
+#define BIT_RXBEQPKT_ERR BIT(6)
+#define BIT_RXVIQPKT_ERR BIT(5)
+#define BIT_RXVOQPKT_ERR BIT(4)
+#define BIT_RXDMA_MON_EN BIT(2)
+#define BIT_RXPKT_MON_RST BIT(1)
+#define BIT_RXPKT_MON_EN BIT(0)
+
+/* 2 REG_STATE_MON (Offset 0x06B4) */
+
+#define BIT_SHIFT_STATE_SEL 24
+#define BIT_MASK_STATE_SEL 0x1f
+#define BIT_STATE_SEL(x) (((x) & BIT_MASK_STATE_SEL) << BIT_SHIFT_STATE_SEL)
+#define BIT_GET_STATE_SEL(x) (((x) >> BIT_SHIFT_STATE_SEL) & BIT_MASK_STATE_SEL)
+
+#define BIT_SHIFT_STATE_INFO 8
+#define BIT_MASK_STATE_INFO 0xff
+#define BIT_STATE_INFO(x) (((x) & BIT_MASK_STATE_INFO) << BIT_SHIFT_STATE_INFO)
+#define BIT_GET_STATE_INFO(x) \
+ (((x) >> BIT_SHIFT_STATE_INFO) & BIT_MASK_STATE_INFO)
+
+#define BIT_UPD_NXT_STATE BIT(7)
+
+/* 2 REG_STATE_MON (Offset 0x06B4) */
+
+#define BIT_SHIFT_CUR_STATE 0
+#define BIT_MASK_CUR_STATE 0x7f
+#define BIT_CUR_STATE(x) (((x) & BIT_MASK_CUR_STATE) << BIT_SHIFT_CUR_STATE)
+#define BIT_GET_CUR_STATE(x) (((x) >> BIT_SHIFT_CUR_STATE) & BIT_MASK_CUR_STATE)
+
+/* 2 REG_ERROR_MON (Offset 0x06B8) */
+
+#define BIT_MACRX_ERR_1 BIT(17)
+#define BIT_MACRX_ERR_0 BIT(16)
+#define BIT_MACTX_ERR_3 BIT(3)
+#define BIT_MACTX_ERR_2 BIT(2)
+#define BIT_MACTX_ERR_1 BIT(1)
+#define BIT_MACTX_ERR_0 BIT(0)
+
+/* 2 REG_SEARCH_MACID (Offset 0x06BC) */
+
+#define BIT_EN_TXRPTBUF_CLK BIT(31)
+
+#define BIT_SHIFT_INFO_INDEX_OFFSET 16
+#define BIT_MASK_INFO_INDEX_OFFSET 0x1fff
+#define BIT_INFO_INDEX_OFFSET(x) \
+ (((x) & BIT_MASK_INFO_INDEX_OFFSET) << BIT_SHIFT_INFO_INDEX_OFFSET)
+#define BIT_GET_INFO_INDEX_OFFSET(x) \
+ (((x) >> BIT_SHIFT_INFO_INDEX_OFFSET) & BIT_MASK_INFO_INDEX_OFFSET)
+
+/* 2 REG_SEARCH_MACID (Offset 0x06BC) */
+
+#define BIT_WMAC_SRCH_FIFOFULL BIT(15)
+
+/* 2 REG_SEARCH_MACID (Offset 0x06BC) */
+
+#define BIT_DIS_INFOSRCH BIT(14)
+#define BIT_DISABLE_B0 BIT(13)
+
+#define BIT_SHIFT_INFO_ADDR_OFFSET 0
+#define BIT_MASK_INFO_ADDR_OFFSET 0x1fff
+#define BIT_INFO_ADDR_OFFSET(x) \
+ (((x) & BIT_MASK_INFO_ADDR_OFFSET) << BIT_SHIFT_INFO_ADDR_OFFSET)
+#define BIT_GET_INFO_ADDR_OFFSET(x) \
+ (((x) >> BIT_SHIFT_INFO_ADDR_OFFSET) & BIT_MASK_INFO_ADDR_OFFSET)
+
+/* 2 REG_BT_COEX_TABLE (Offset 0x06C0) */
+
+#define BIT_PRI_MASK_RX_RESP BIT(126)
+#define BIT_PRI_MASK_RXOFDM BIT(125)
+#define BIT_PRI_MASK_RXCCK BIT(124)
+
+#define BIT_SHIFT_PRI_MASK_TXAC (117 & CPU_OPT_WIDTH)
+#define BIT_MASK_PRI_MASK_TXAC 0x7f
+#define BIT_PRI_MASK_TXAC(x) \
+ (((x) & BIT_MASK_PRI_MASK_TXAC) << BIT_SHIFT_PRI_MASK_TXAC)
+#define BIT_GET_PRI_MASK_TXAC(x) \
+ (((x) >> BIT_SHIFT_PRI_MASK_TXAC) & BIT_MASK_PRI_MASK_TXAC)
+
+#define BIT_SHIFT_PRI_MASK_NAV (109 & CPU_OPT_WIDTH)
+#define BIT_MASK_PRI_MASK_NAV 0xff
+#define BIT_PRI_MASK_NAV(x) \
+ (((x) & BIT_MASK_PRI_MASK_NAV) << BIT_SHIFT_PRI_MASK_NAV)
+#define BIT_GET_PRI_MASK_NAV(x) \
+ (((x) >> BIT_SHIFT_PRI_MASK_NAV) & BIT_MASK_PRI_MASK_NAV)
+
+#define BIT_PRI_MASK_CCK BIT(108)
+#define BIT_PRI_MASK_OFDM BIT(107)
+#define BIT_PRI_MASK_RTY BIT(106)
+
+#define BIT_SHIFT_PRI_MASK_NUM (102 & CPU_OPT_WIDTH)
+#define BIT_MASK_PRI_MASK_NUM 0xf
+#define BIT_PRI_MASK_NUM(x) \
+ (((x) & BIT_MASK_PRI_MASK_NUM) << BIT_SHIFT_PRI_MASK_NUM)
+#define BIT_GET_PRI_MASK_NUM(x) \
+ (((x) >> BIT_SHIFT_PRI_MASK_NUM) & BIT_MASK_PRI_MASK_NUM)
+
+#define BIT_SHIFT_PRI_MASK_TYPE (98 & CPU_OPT_WIDTH)
+#define BIT_MASK_PRI_MASK_TYPE 0xf
+#define BIT_PRI_MASK_TYPE(x) \
+ (((x) & BIT_MASK_PRI_MASK_TYPE) << BIT_SHIFT_PRI_MASK_TYPE)
+#define BIT_GET_PRI_MASK_TYPE(x) \
+ (((x) >> BIT_SHIFT_PRI_MASK_TYPE) & BIT_MASK_PRI_MASK_TYPE)
+
+#define BIT_OOB BIT(97)
+#define BIT_ANT_SEL BIT(96)
+
+#define BIT_SHIFT_BREAK_TABLE_2 (80 & CPU_OPT_WIDTH)
+#define BIT_MASK_BREAK_TABLE_2 0xffff
+#define BIT_BREAK_TABLE_2(x) \
+ (((x) & BIT_MASK_BREAK_TABLE_2) << BIT_SHIFT_BREAK_TABLE_2)
+#define BIT_GET_BREAK_TABLE_2(x) \
+ (((x) >> BIT_SHIFT_BREAK_TABLE_2) & BIT_MASK_BREAK_TABLE_2)
+
+#define BIT_SHIFT_BREAK_TABLE_1 (64 & CPU_OPT_WIDTH)
+#define BIT_MASK_BREAK_TABLE_1 0xffff
+#define BIT_BREAK_TABLE_1(x) \
+ (((x) & BIT_MASK_BREAK_TABLE_1) << BIT_SHIFT_BREAK_TABLE_1)
+#define BIT_GET_BREAK_TABLE_1(x) \
+ (((x) >> BIT_SHIFT_BREAK_TABLE_1) & BIT_MASK_BREAK_TABLE_1)
+
+#define BIT_SHIFT_COEX_TABLE_2 (32 & CPU_OPT_WIDTH)
+#define BIT_MASK_COEX_TABLE_2 0xffffffffL
+#define BIT_COEX_TABLE_2(x) \
+ (((x) & BIT_MASK_COEX_TABLE_2) << BIT_SHIFT_COEX_TABLE_2)
+#define BIT_GET_COEX_TABLE_2(x) \
+ (((x) >> BIT_SHIFT_COEX_TABLE_2) & BIT_MASK_COEX_TABLE_2)
+
+#define BIT_SHIFT_COEX_TABLE_1 0
+#define BIT_MASK_COEX_TABLE_1 0xffffffffL
+#define BIT_COEX_TABLE_1(x) \
+ (((x) & BIT_MASK_COEX_TABLE_1) << BIT_SHIFT_COEX_TABLE_1)
+#define BIT_GET_COEX_TABLE_1(x) \
+ (((x) >> BIT_SHIFT_COEX_TABLE_1) & BIT_MASK_COEX_TABLE_1)
+
+/* 2 REG_RXCMD_0 (Offset 0x06D0) */
+
+#define BIT_RXCMD_EN BIT(31)
+
+#define BIT_SHIFT_RXCMD_INFO 0
+#define BIT_MASK_RXCMD_INFO 0x7fffffffL
+#define BIT_RXCMD_INFO(x) (((x) & BIT_MASK_RXCMD_INFO) << BIT_SHIFT_RXCMD_INFO)
+#define BIT_GET_RXCMD_INFO(x) \
+ (((x) >> BIT_SHIFT_RXCMD_INFO) & BIT_MASK_RXCMD_INFO)
+
+/* 2 REG_RXCMD_1 (Offset 0x06D4) */
+
+#define BIT_SHIFT_RXCMD_PRD 0
+#define BIT_MASK_RXCMD_PRD 0xffff
+#define BIT_RXCMD_PRD(x) (((x) & BIT_MASK_RXCMD_PRD) << BIT_SHIFT_RXCMD_PRD)
+#define BIT_GET_RXCMD_PRD(x) (((x) >> BIT_SHIFT_RXCMD_PRD) & BIT_MASK_RXCMD_PRD)
+
+/* 2 REG_WMAC_RESP_TXINFO (Offset 0x06D8) */
+
+#define BIT_SHIFT_WMAC_RESP_MFB 25
+#define BIT_MASK_WMAC_RESP_MFB 0x7f
+#define BIT_WMAC_RESP_MFB(x) \
+ (((x) & BIT_MASK_WMAC_RESP_MFB) << BIT_SHIFT_WMAC_RESP_MFB)
+#define BIT_GET_WMAC_RESP_MFB(x) \
+ (((x) >> BIT_SHIFT_WMAC_RESP_MFB) & BIT_MASK_WMAC_RESP_MFB)
+
+#define BIT_SHIFT_WMAC_ANTINF_SEL 23
+#define BIT_MASK_WMAC_ANTINF_SEL 0x3
+#define BIT_WMAC_ANTINF_SEL(x) \
+ (((x) & BIT_MASK_WMAC_ANTINF_SEL) << BIT_SHIFT_WMAC_ANTINF_SEL)
+#define BIT_GET_WMAC_ANTINF_SEL(x) \
+ (((x) >> BIT_SHIFT_WMAC_ANTINF_SEL) & BIT_MASK_WMAC_ANTINF_SEL)
+
+#define BIT_SHIFT_WMAC_ANTSEL_SEL 21
+#define BIT_MASK_WMAC_ANTSEL_SEL 0x3
+#define BIT_WMAC_ANTSEL_SEL(x) \
+ (((x) & BIT_MASK_WMAC_ANTSEL_SEL) << BIT_SHIFT_WMAC_ANTSEL_SEL)
+#define BIT_GET_WMAC_ANTSEL_SEL(x) \
+ (((x) >> BIT_SHIFT_WMAC_ANTSEL_SEL) & BIT_MASK_WMAC_ANTSEL_SEL)
+
+/* 2 REG_WMAC_RESP_TXINFO (Offset 0x06D8) */
+
+#define BIT_SHIFT_R_WMAC_RESP_TXPOWER 18
+#define BIT_MASK_R_WMAC_RESP_TXPOWER 0x7
+#define BIT_R_WMAC_RESP_TXPOWER(x) \
+ (((x) & BIT_MASK_R_WMAC_RESP_TXPOWER) << BIT_SHIFT_R_WMAC_RESP_TXPOWER)
+#define BIT_GET_R_WMAC_RESP_TXPOWER(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_RESP_TXPOWER) & BIT_MASK_R_WMAC_RESP_TXPOWER)
+
+/* 2 REG_WMAC_RESP_TXINFO (Offset 0x06D8) */
+
+#define BIT_SHIFT_WMAC_RESP_TXANT 0
+#define BIT_MASK_WMAC_RESP_TXANT 0x3ffff
+#define BIT_WMAC_RESP_TXANT(x) \
+ (((x) & BIT_MASK_WMAC_RESP_TXANT) << BIT_SHIFT_WMAC_RESP_TXANT)
+#define BIT_GET_WMAC_RESP_TXANT(x) \
+ (((x) >> BIT_SHIFT_WMAC_RESP_TXANT) & BIT_MASK_WMAC_RESP_TXANT)
+
+/* 2 REG_BBPSF_CTRL (Offset 0x06DC) */
+
+#define BIT_CTL_IDLE_CLR_CSI_RPT BIT(31)
+
+/* 2 REG_BBPSF_CTRL (Offset 0x06DC) */
+
+#define BIT_WMAC_USE_NDPARATE BIT(30)
+
+#define BIT_SHIFT_WMAC_CSI_RATE 24
+#define BIT_MASK_WMAC_CSI_RATE 0x3f
+#define BIT_WMAC_CSI_RATE(x) \
+ (((x) & BIT_MASK_WMAC_CSI_RATE) << BIT_SHIFT_WMAC_CSI_RATE)
+#define BIT_GET_WMAC_CSI_RATE(x) \
+ (((x) >> BIT_SHIFT_WMAC_CSI_RATE) & BIT_MASK_WMAC_CSI_RATE)
+
+#define BIT_SHIFT_WMAC_RESP_TXRATE 16
+#define BIT_MASK_WMAC_RESP_TXRATE 0xff
+#define BIT_WMAC_RESP_TXRATE(x) \
+ (((x) & BIT_MASK_WMAC_RESP_TXRATE) << BIT_SHIFT_WMAC_RESP_TXRATE)
+#define BIT_GET_WMAC_RESP_TXRATE(x) \
+ (((x) >> BIT_SHIFT_WMAC_RESP_TXRATE) & BIT_MASK_WMAC_RESP_TXRATE)
+
+/* 2 REG_BBPSF_CTRL (Offset 0x06DC) */
+
+#define BIT_BBPSF_MPDUCHKEN BIT(5)
+
+/* 2 REG_BBPSF_CTRL (Offset 0x06DC) */
+
+#define BIT_BBPSF_MHCHKEN BIT(4)
+#define BIT_BBPSF_ERRCHKEN BIT(3)
+
+#define BIT_SHIFT_BBPSF_ERRTHR 0
+#define BIT_MASK_BBPSF_ERRTHR 0x7
+#define BIT_BBPSF_ERRTHR(x) \
+ (((x) & BIT_MASK_BBPSF_ERRTHR) << BIT_SHIFT_BBPSF_ERRTHR)
+#define BIT_GET_BBPSF_ERRTHR(x) \
+ (((x) >> BIT_SHIFT_BBPSF_ERRTHR) & BIT_MASK_BBPSF_ERRTHR)
+
+/* 2 REG_P2P_RX_BCN_NOA (Offset 0x06E0) */
+
+#define BIT_NOA_PARSER_EN BIT(15)
+
+/* 2 REG_P2P_RX_BCN_NOA (Offset 0x06E0) */
+
+#define BIT_BSSID_SEL BIT(14)
+
+/* 2 REG_P2P_RX_BCN_NOA (Offset 0x06E0) */
+
+#define BIT_SHIFT_P2P_OUI_TYPE 0
+#define BIT_MASK_P2P_OUI_TYPE 0xff
+#define BIT_P2P_OUI_TYPE(x) \
+ (((x) & BIT_MASK_P2P_OUI_TYPE) << BIT_SHIFT_P2P_OUI_TYPE)
+#define BIT_GET_P2P_OUI_TYPE(x) \
+ (((x) >> BIT_SHIFT_P2P_OUI_TYPE) & BIT_MASK_P2P_OUI_TYPE)
+
+/* 2 REG_ASSOCIATED_BFMER0_INFO (Offset 0x06E4) */
+
+#define BIT_SHIFT_R_WMAC_TXCSI_AID0 (48 & CPU_OPT_WIDTH)
+#define BIT_MASK_R_WMAC_TXCSI_AID0 0x1ff
+#define BIT_R_WMAC_TXCSI_AID0(x) \
+ (((x) & BIT_MASK_R_WMAC_TXCSI_AID0) << BIT_SHIFT_R_WMAC_TXCSI_AID0)
+#define BIT_GET_R_WMAC_TXCSI_AID0(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_TXCSI_AID0) & BIT_MASK_R_WMAC_TXCSI_AID0)
+
+#define BIT_SHIFT_R_WMAC_SOUNDING_RXADD_R0 0
+#define BIT_MASK_R_WMAC_SOUNDING_RXADD_R0 0xffffffffffffL
+#define BIT_R_WMAC_SOUNDING_RXADD_R0(x) \
+ (((x) & BIT_MASK_R_WMAC_SOUNDING_RXADD_R0) \
+ << BIT_SHIFT_R_WMAC_SOUNDING_RXADD_R0)
+#define BIT_GET_R_WMAC_SOUNDING_RXADD_R0(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_SOUNDING_RXADD_R0) & \
+ BIT_MASK_R_WMAC_SOUNDING_RXADD_R0)
+
+/* 2 REG_ASSOCIATED_BFMER1_INFO (Offset 0x06EC) */
+
+#define BIT_SHIFT_R_WMAC_TXCSI_AID1 (48 & CPU_OPT_WIDTH)
+#define BIT_MASK_R_WMAC_TXCSI_AID1 0x1ff
+#define BIT_R_WMAC_TXCSI_AID1(x) \
+ (((x) & BIT_MASK_R_WMAC_TXCSI_AID1) << BIT_SHIFT_R_WMAC_TXCSI_AID1)
+#define BIT_GET_R_WMAC_TXCSI_AID1(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_TXCSI_AID1) & BIT_MASK_R_WMAC_TXCSI_AID1)
+
+#define BIT_SHIFT_R_WMAC_SOUNDING_RXADD_R1 0
+#define BIT_MASK_R_WMAC_SOUNDING_RXADD_R1 0xffffffffffffL
+#define BIT_R_WMAC_SOUNDING_RXADD_R1(x) \
+ (((x) & BIT_MASK_R_WMAC_SOUNDING_RXADD_R1) \
+ << BIT_SHIFT_R_WMAC_SOUNDING_RXADD_R1)
+#define BIT_GET_R_WMAC_SOUNDING_RXADD_R1(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_SOUNDING_RXADD_R1) & \
+ BIT_MASK_R_WMAC_SOUNDING_RXADD_R1)
+
+/* 2 REG_TX_CSI_RPT_PARAM_BW20 (Offset 0x06F4) */
+
+#define BIT_SHIFT_R_WMAC_BFINFO_20M_1 16
+#define BIT_MASK_R_WMAC_BFINFO_20M_1 0xfff
+#define BIT_R_WMAC_BFINFO_20M_1(x) \
+ (((x) & BIT_MASK_R_WMAC_BFINFO_20M_1) << BIT_SHIFT_R_WMAC_BFINFO_20M_1)
+#define BIT_GET_R_WMAC_BFINFO_20M_1(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_BFINFO_20M_1) & BIT_MASK_R_WMAC_BFINFO_20M_1)
+
+#define BIT_SHIFT_R_WMAC_BFINFO_20M_0 0
+#define BIT_MASK_R_WMAC_BFINFO_20M_0 0xfff
+#define BIT_R_WMAC_BFINFO_20M_0(x) \
+ (((x) & BIT_MASK_R_WMAC_BFINFO_20M_0) << BIT_SHIFT_R_WMAC_BFINFO_20M_0)
+#define BIT_GET_R_WMAC_BFINFO_20M_0(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_BFINFO_20M_0) & BIT_MASK_R_WMAC_BFINFO_20M_0)
+
+/* 2 REG_TX_CSI_RPT_PARAM_BW40 (Offset 0x06F8) */
+
+#define BIT_SHIFT_WMAC_RESP_ANTCD 0
+#define BIT_MASK_WMAC_RESP_ANTCD 0xf
+#define BIT_WMAC_RESP_ANTCD(x) \
+ (((x) & BIT_MASK_WMAC_RESP_ANTCD) << BIT_SHIFT_WMAC_RESP_ANTCD)
+#define BIT_GET_WMAC_RESP_ANTCD(x) \
+ (((x) >> BIT_SHIFT_WMAC_RESP_ANTCD) & BIT_MASK_WMAC_RESP_ANTCD)
+
+/* 2 REG_MACID1 (Offset 0x0700) */
+
+#define BIT_SHIFT_MACID1 0
+#define BIT_MASK_MACID1 0xffffffffffffL
+#define BIT_MACID1(x) (((x) & BIT_MASK_MACID1) << BIT_SHIFT_MACID1)
+#define BIT_GET_MACID1(x) (((x) >> BIT_SHIFT_MACID1) & BIT_MASK_MACID1)
+
+/* 2 REG_BSSID1 (Offset 0x0708) */
+
+#define BIT_SHIFT_BSSID1 0
+#define BIT_MASK_BSSID1 0xffffffffffffL
+#define BIT_BSSID1(x) (((x) & BIT_MASK_BSSID1) << BIT_SHIFT_BSSID1)
+#define BIT_GET_BSSID1(x) (((x) >> BIT_SHIFT_BSSID1) & BIT_MASK_BSSID1)
+
+/* 2 REG_BCN_PSR_RPT1 (Offset 0x0710) */
+
+#define BIT_SHIFT_DTIM_CNT1 24
+#define BIT_MASK_DTIM_CNT1 0xff
+#define BIT_DTIM_CNT1(x) (((x) & BIT_MASK_DTIM_CNT1) << BIT_SHIFT_DTIM_CNT1)
+#define BIT_GET_DTIM_CNT1(x) (((x) >> BIT_SHIFT_DTIM_CNT1) & BIT_MASK_DTIM_CNT1)
+
+#define BIT_SHIFT_DTIM_PERIOD1 16
+#define BIT_MASK_DTIM_PERIOD1 0xff
+#define BIT_DTIM_PERIOD1(x) \
+ (((x) & BIT_MASK_DTIM_PERIOD1) << BIT_SHIFT_DTIM_PERIOD1)
+#define BIT_GET_DTIM_PERIOD1(x) \
+ (((x) >> BIT_SHIFT_DTIM_PERIOD1) & BIT_MASK_DTIM_PERIOD1)
+
+#define BIT_DTIM1 BIT(15)
+#define BIT_TIM1 BIT(14)
+
+#define BIT_SHIFT_PS_AID_1 0
+#define BIT_MASK_PS_AID_1 0x7ff
+#define BIT_PS_AID_1(x) (((x) & BIT_MASK_PS_AID_1) << BIT_SHIFT_PS_AID_1)
+#define BIT_GET_PS_AID_1(x) (((x) >> BIT_SHIFT_PS_AID_1) & BIT_MASK_PS_AID_1)
+
+/* 2 REG_ASSOCIATED_BFMEE_SEL (Offset 0x0714) */
+
+#define BIT_TXUSER_ID1 BIT(25)
+
+#define BIT_SHIFT_AID1 16
+#define BIT_MASK_AID1 0x1ff
+#define BIT_AID1(x) (((x) & BIT_MASK_AID1) << BIT_SHIFT_AID1)
+#define BIT_GET_AID1(x) (((x) >> BIT_SHIFT_AID1) & BIT_MASK_AID1)
+
+#define BIT_TXUSER_ID0 BIT(9)
+
+#define BIT_SHIFT_AID0 0
+#define BIT_MASK_AID0 0x1ff
+#define BIT_AID0(x) (((x) & BIT_MASK_AID0) << BIT_SHIFT_AID0)
+#define BIT_GET_AID0(x) (((x) >> BIT_SHIFT_AID0) & BIT_MASK_AID0)
+
+/* 2 REG_SND_PTCL_CTRL (Offset 0x0718) */
+
+#define BIT_SHIFT_NDP_RX_STANDBY_TIMER 24
+#define BIT_MASK_NDP_RX_STANDBY_TIMER 0xff
+#define BIT_NDP_RX_STANDBY_TIMER(x) \
+ (((x) & BIT_MASK_NDP_RX_STANDBY_TIMER) \
+ << BIT_SHIFT_NDP_RX_STANDBY_TIMER)
+#define BIT_GET_NDP_RX_STANDBY_TIMER(x) \
+ (((x) >> BIT_SHIFT_NDP_RX_STANDBY_TIMER) & \
+ BIT_MASK_NDP_RX_STANDBY_TIMER)
+
+#define BIT_SHIFT_CSI_RPT_OFFSET_HT 16
+#define BIT_MASK_CSI_RPT_OFFSET_HT 0xff
+#define BIT_CSI_RPT_OFFSET_HT(x) \
+ (((x) & BIT_MASK_CSI_RPT_OFFSET_HT) << BIT_SHIFT_CSI_RPT_OFFSET_HT)
+#define BIT_GET_CSI_RPT_OFFSET_HT(x) \
+ (((x) >> BIT_SHIFT_CSI_RPT_OFFSET_HT) & BIT_MASK_CSI_RPT_OFFSET_HT)
+
+/* 2 REG_SND_PTCL_CTRL (Offset 0x0718) */
+
+#define BIT_SHIFT_R_WMAC_VHT_CATEGORY 8
+#define BIT_MASK_R_WMAC_VHT_CATEGORY 0xff
+#define BIT_R_WMAC_VHT_CATEGORY(x) \
+ (((x) & BIT_MASK_R_WMAC_VHT_CATEGORY) << BIT_SHIFT_R_WMAC_VHT_CATEGORY)
+#define BIT_GET_R_WMAC_VHT_CATEGORY(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_VHT_CATEGORY) & BIT_MASK_R_WMAC_VHT_CATEGORY)
+
+/* 2 REG_SND_PTCL_CTRL (Offset 0x0718) */
+
+#define BIT_R_WMAC_USE_NSTS BIT(7)
+#define BIT_R_DISABLE_CHECK_VHTSIGB_CRC BIT(6)
+#define BIT_R_DISABLE_CHECK_VHTSIGA_CRC BIT(5)
+#define BIT_R_WMAC_BFPARAM_SEL BIT(4)
+#define BIT_R_WMAC_CSISEQ_SEL BIT(3)
+#define BIT_R_WMAC_CSI_WITHHTC_EN BIT(2)
+#define BIT_R_WMAC_HT_NDPA_EN BIT(1)
+#define BIT_R_WMAC_VHT_NDPA_EN BIT(0)
+
+/* 2 REG_NS_ARP_CTRL (Offset 0x0720) */
+
+#define BIT_R_WMAC_NSARP_RSPEN BIT(15)
+#define BIT_R_WMAC_NSARP_RARP BIT(9)
+#define BIT_R_WMAC_NSARP_RIPV6 BIT(8)
+
+#define BIT_SHIFT_R_WMAC_NSARP_MODEN 6
+#define BIT_MASK_R_WMAC_NSARP_MODEN 0x3
+#define BIT_R_WMAC_NSARP_MODEN(x) \
+ (((x) & BIT_MASK_R_WMAC_NSARP_MODEN) << BIT_SHIFT_R_WMAC_NSARP_MODEN)
+#define BIT_GET_R_WMAC_NSARP_MODEN(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_NSARP_MODEN) & BIT_MASK_R_WMAC_NSARP_MODEN)
+
+#define BIT_SHIFT_R_WMAC_NSARP_RSPFTP 4
+#define BIT_MASK_R_WMAC_NSARP_RSPFTP 0x3
+#define BIT_R_WMAC_NSARP_RSPFTP(x) \
+ (((x) & BIT_MASK_R_WMAC_NSARP_RSPFTP) << BIT_SHIFT_R_WMAC_NSARP_RSPFTP)
+#define BIT_GET_R_WMAC_NSARP_RSPFTP(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_NSARP_RSPFTP) & BIT_MASK_R_WMAC_NSARP_RSPFTP)
+
+#define BIT_SHIFT_R_WMAC_NSARP_RSPSEC 0
+#define BIT_MASK_R_WMAC_NSARP_RSPSEC 0xf
+#define BIT_R_WMAC_NSARP_RSPSEC(x) \
+ (((x) & BIT_MASK_R_WMAC_NSARP_RSPSEC) << BIT_SHIFT_R_WMAC_NSARP_RSPSEC)
+#define BIT_GET_R_WMAC_NSARP_RSPSEC(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_NSARP_RSPSEC) & BIT_MASK_R_WMAC_NSARP_RSPSEC)
+
+/* 2 REG_NS_ARP_INFO (Offset 0x0724) */
+
+#define BIT_REQ_IS_MCNS BIT(23)
+#define BIT_REQ_IS_UCNS BIT(22)
+#define BIT_REQ_IS_USNS BIT(21)
+#define BIT_REQ_IS_ARP BIT(20)
+#define BIT_EXPRSP_MH_WITHQC BIT(19)
+
+#define BIT_SHIFT_EXPRSP_SECTYPE 16
+#define BIT_MASK_EXPRSP_SECTYPE 0x7
+#define BIT_EXPRSP_SECTYPE(x) \
+ (((x) & BIT_MASK_EXPRSP_SECTYPE) << BIT_SHIFT_EXPRSP_SECTYPE)
+#define BIT_GET_EXPRSP_SECTYPE(x) \
+ (((x) >> BIT_SHIFT_EXPRSP_SECTYPE) & BIT_MASK_EXPRSP_SECTYPE)
+
+#define BIT_SHIFT_EXPRSP_CHKSM_7_TO_0 8
+#define BIT_MASK_EXPRSP_CHKSM_7_TO_0 0xff
+#define BIT_EXPRSP_CHKSM_7_TO_0(x) \
+ (((x) & BIT_MASK_EXPRSP_CHKSM_7_TO_0) << BIT_SHIFT_EXPRSP_CHKSM_7_TO_0)
+#define BIT_GET_EXPRSP_CHKSM_7_TO_0(x) \
+ (((x) >> BIT_SHIFT_EXPRSP_CHKSM_7_TO_0) & BIT_MASK_EXPRSP_CHKSM_7_TO_0)
+
+#define BIT_SHIFT_EXPRSP_CHKSM_15_TO_8 0
+#define BIT_MASK_EXPRSP_CHKSM_15_TO_8 0xff
+#define BIT_EXPRSP_CHKSM_15_TO_8(x) \
+ (((x) & BIT_MASK_EXPRSP_CHKSM_15_TO_8) \
+ << BIT_SHIFT_EXPRSP_CHKSM_15_TO_8)
+#define BIT_GET_EXPRSP_CHKSM_15_TO_8(x) \
+ (((x) >> BIT_SHIFT_EXPRSP_CHKSM_15_TO_8) & \
+ BIT_MASK_EXPRSP_CHKSM_15_TO_8)
+
+/* 2 REG_BEAMFORMING_INFO_NSARP_V1 (Offset 0x0728) */
+
+#define BIT_SHIFT_WMAC_ARPIP 0
+#define BIT_MASK_WMAC_ARPIP 0xffffffffL
+#define BIT_WMAC_ARPIP(x) (((x) & BIT_MASK_WMAC_ARPIP) << BIT_SHIFT_WMAC_ARPIP)
+#define BIT_GET_WMAC_ARPIP(x) \
+ (((x) >> BIT_SHIFT_WMAC_ARPIP) & BIT_MASK_WMAC_ARPIP)
+
+/* 2 REG_BEAMFORMING_INFO_NSARP (Offset 0x072C) */
+
+#define BIT_SHIFT_BEAMFORMING_INFO 0
+#define BIT_MASK_BEAMFORMING_INFO 0xffffffffL
+#define BIT_BEAMFORMING_INFO(x) \
+ (((x) & BIT_MASK_BEAMFORMING_INFO) << BIT_SHIFT_BEAMFORMING_INFO)
+#define BIT_GET_BEAMFORMING_INFO(x) \
+ (((x) >> BIT_SHIFT_BEAMFORMING_INFO) & BIT_MASK_BEAMFORMING_INFO)
+
+/* 2 REG_WMAC_RTX_CTX_SUBTYPE_CFG (Offset 0x0750) */
+
+#define BIT_SHIFT_R_WMAC_CTX_SUBTYPE 4
+#define BIT_MASK_R_WMAC_CTX_SUBTYPE 0xf
+#define BIT_R_WMAC_CTX_SUBTYPE(x) \
+ (((x) & BIT_MASK_R_WMAC_CTX_SUBTYPE) << BIT_SHIFT_R_WMAC_CTX_SUBTYPE)
+#define BIT_GET_R_WMAC_CTX_SUBTYPE(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_CTX_SUBTYPE) & BIT_MASK_R_WMAC_CTX_SUBTYPE)
+
+#define BIT_SHIFT_R_WMAC_RTX_SUBTYPE 0
+#define BIT_MASK_R_WMAC_RTX_SUBTYPE 0xf
+#define BIT_R_WMAC_RTX_SUBTYPE(x) \
+ (((x) & BIT_MASK_R_WMAC_RTX_SUBTYPE) << BIT_SHIFT_R_WMAC_RTX_SUBTYPE)
+#define BIT_GET_R_WMAC_RTX_SUBTYPE(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_RTX_SUBTYPE) & BIT_MASK_R_WMAC_RTX_SUBTYPE)
+
+/* 2 REG_BT_COEX_V2 (Offset 0x0762) */
+
+#define BIT_GNT_BT_POLARITY BIT(12)
+#define BIT_GNT_BT_BYPASS_PRIORITY BIT(8)
+
+#define BIT_SHIFT_TIMER 0
+#define BIT_MASK_TIMER 0xff
+#define BIT_TIMER(x) (((x) & BIT_MASK_TIMER) << BIT_SHIFT_TIMER)
+#define BIT_GET_TIMER(x) (((x) >> BIT_SHIFT_TIMER) & BIT_MASK_TIMER)
+
+/* 2 REG_BT_COEX (Offset 0x0764) */
+
+#define BIT_R_GNT_BT_RFC_SW BIT(12)
+#define BIT_R_GNT_BT_RFC_SW_EN BIT(11)
+#define BIT_R_GNT_BT_BB_SW BIT(10)
+#define BIT_R_GNT_BT_BB_SW_EN BIT(9)
+#define BIT_R_BT_CNT_THREN BIT(8)
+
+#define BIT_SHIFT_R_BT_CNT_THR 0
+#define BIT_MASK_R_BT_CNT_THR 0xff
+#define BIT_R_BT_CNT_THR(x) \
+ (((x) & BIT_MASK_R_BT_CNT_THR) << BIT_SHIFT_R_BT_CNT_THR)
+#define BIT_GET_R_BT_CNT_THR(x) \
+ (((x) >> BIT_SHIFT_R_BT_CNT_THR) & BIT_MASK_R_BT_CNT_THR)
+
+/* 2 REG_WLAN_ACT_MASK_CTRL (Offset 0x0768) */
+
+#define BIT_WLRX_TER_BY_CTL BIT(43)
+#define BIT_WLRX_TER_BY_AD BIT(42)
+#define BIT_ANT_DIVERSITY_SEL BIT(41)
+#define BIT_ANTSEL_FOR_BT_CTRL_EN BIT(40)
+#define BIT_WLACT_LOW_GNTWL_EN BIT(34)
+#define BIT_WLACT_HIGH_GNTBT_EN BIT(33)
+
+/* 2 REG_WLAN_ACT_MASK_CTRL (Offset 0x0768) */
+
+#define BIT_NAV_UPPER_V1 BIT(32)
+
+/* 2 REG_WLAN_ACT_MASK_CTRL (Offset 0x0768) */
+
+#define BIT_SHIFT_RXMYRTS_NAV_V1 8
+#define BIT_MASK_RXMYRTS_NAV_V1 0xff
+#define BIT_RXMYRTS_NAV_V1(x) \
+ (((x) & BIT_MASK_RXMYRTS_NAV_V1) << BIT_SHIFT_RXMYRTS_NAV_V1)
+#define BIT_GET_RXMYRTS_NAV_V1(x) \
+ (((x) >> BIT_SHIFT_RXMYRTS_NAV_V1) & BIT_MASK_RXMYRTS_NAV_V1)
+
+#define BIT_SHIFT_RTSRST_V1 0
+#define BIT_MASK_RTSRST_V1 0xff
+#define BIT_RTSRST_V1(x) (((x) & BIT_MASK_RTSRST_V1) << BIT_SHIFT_RTSRST_V1)
+#define BIT_GET_RTSRST_V1(x) (((x) >> BIT_SHIFT_RTSRST_V1) & BIT_MASK_RTSRST_V1)
+
+/* 2 REG_BT_COEX_ENHANCED_INTR_CTRL (Offset 0x076E) */
+
+#define BIT_SHIFT_BT_STAT_DELAY 12
+#define BIT_MASK_BT_STAT_DELAY 0xf
+#define BIT_BT_STAT_DELAY(x) \
+ (((x) & BIT_MASK_BT_STAT_DELAY) << BIT_SHIFT_BT_STAT_DELAY)
+#define BIT_GET_BT_STAT_DELAY(x) \
+ (((x) >> BIT_SHIFT_BT_STAT_DELAY) & BIT_MASK_BT_STAT_DELAY)
+
+#define BIT_SHIFT_BT_TRX_INIT_DETECT 8
+#define BIT_MASK_BT_TRX_INIT_DETECT 0xf
+#define BIT_BT_TRX_INIT_DETECT(x) \
+ (((x) & BIT_MASK_BT_TRX_INIT_DETECT) << BIT_SHIFT_BT_TRX_INIT_DETECT)
+#define BIT_GET_BT_TRX_INIT_DETECT(x) \
+ (((x) >> BIT_SHIFT_BT_TRX_INIT_DETECT) & BIT_MASK_BT_TRX_INIT_DETECT)
+
+#define BIT_SHIFT_BT_PRI_DETECT_TO 4
+#define BIT_MASK_BT_PRI_DETECT_TO 0xf
+#define BIT_BT_PRI_DETECT_TO(x) \
+ (((x) & BIT_MASK_BT_PRI_DETECT_TO) << BIT_SHIFT_BT_PRI_DETECT_TO)
+#define BIT_GET_BT_PRI_DETECT_TO(x) \
+ (((x) >> BIT_SHIFT_BT_PRI_DETECT_TO) & BIT_MASK_BT_PRI_DETECT_TO)
+
+#define BIT_R_GRANTALL_WLMASK BIT(3)
+#define BIT_STATIS_BT_EN BIT(2)
+#define BIT_WL_ACT_MASK_ENABLE BIT(1)
+#define BIT_ENHANCED_BT BIT(0)
+
+/* 2 REG_BT_ACT_STATISTICS (Offset 0x0770) */
+
+#define BIT_SHIFT_STATIS_BT_LO_RX (48 & CPU_OPT_WIDTH)
+#define BIT_MASK_STATIS_BT_LO_RX 0xffff
+#define BIT_STATIS_BT_LO_RX(x) \
+ (((x) & BIT_MASK_STATIS_BT_LO_RX) << BIT_SHIFT_STATIS_BT_LO_RX)
+#define BIT_GET_STATIS_BT_LO_RX(x) \
+ (((x) >> BIT_SHIFT_STATIS_BT_LO_RX) & BIT_MASK_STATIS_BT_LO_RX)
+
+#define BIT_SHIFT_STATIS_BT_LO_TX (32 & CPU_OPT_WIDTH)
+#define BIT_MASK_STATIS_BT_LO_TX 0xffff
+#define BIT_STATIS_BT_LO_TX(x) \
+ (((x) & BIT_MASK_STATIS_BT_LO_TX) << BIT_SHIFT_STATIS_BT_LO_TX)
+#define BIT_GET_STATIS_BT_LO_TX(x) \
+ (((x) >> BIT_SHIFT_STATIS_BT_LO_TX) & BIT_MASK_STATIS_BT_LO_TX)
+
+/* 2 REG_BT_ACT_STATISTICS (Offset 0x0770) */
+
+#define BIT_SHIFT_STATIS_BT_HI_RX 16
+#define BIT_MASK_STATIS_BT_HI_RX 0xffff
+#define BIT_STATIS_BT_HI_RX(x) \
+ (((x) & BIT_MASK_STATIS_BT_HI_RX) << BIT_SHIFT_STATIS_BT_HI_RX)
+#define BIT_GET_STATIS_BT_HI_RX(x) \
+ (((x) >> BIT_SHIFT_STATIS_BT_HI_RX) & BIT_MASK_STATIS_BT_HI_RX)
+
+#define BIT_SHIFT_STATIS_BT_HI_TX 0
+#define BIT_MASK_STATIS_BT_HI_TX 0xffff
+#define BIT_STATIS_BT_HI_TX(x) \
+ (((x) & BIT_MASK_STATIS_BT_HI_TX) << BIT_SHIFT_STATIS_BT_HI_TX)
+#define BIT_GET_STATIS_BT_HI_TX(x) \
+ (((x) >> BIT_SHIFT_STATIS_BT_HI_TX) & BIT_MASK_STATIS_BT_HI_TX)
+
+/* 2 REG_BT_STATISTICS_CONTROL_REGISTER (Offset 0x0778) */
+
+#define BIT_SHIFT_R_BT_CMD_RPT 16
+#define BIT_MASK_R_BT_CMD_RPT 0xffff
+#define BIT_R_BT_CMD_RPT(x) \
+ (((x) & BIT_MASK_R_BT_CMD_RPT) << BIT_SHIFT_R_BT_CMD_RPT)
+#define BIT_GET_R_BT_CMD_RPT(x) \
+ (((x) >> BIT_SHIFT_R_BT_CMD_RPT) & BIT_MASK_R_BT_CMD_RPT)
+
+#define BIT_SHIFT_R_RPT_FROM_BT 8
+#define BIT_MASK_R_RPT_FROM_BT 0xff
+#define BIT_R_RPT_FROM_BT(x) \
+ (((x) & BIT_MASK_R_RPT_FROM_BT) << BIT_SHIFT_R_RPT_FROM_BT)
+#define BIT_GET_R_RPT_FROM_BT(x) \
+ (((x) >> BIT_SHIFT_R_RPT_FROM_BT) & BIT_MASK_R_RPT_FROM_BT)
+
+#define BIT_SHIFT_BT_HID_ISR_SET 6
+#define BIT_MASK_BT_HID_ISR_SET 0x3
+#define BIT_BT_HID_ISR_SET(x) \
+ (((x) & BIT_MASK_BT_HID_ISR_SET) << BIT_SHIFT_BT_HID_ISR_SET)
+#define BIT_GET_BT_HID_ISR_SET(x) \
+ (((x) >> BIT_SHIFT_BT_HID_ISR_SET) & BIT_MASK_BT_HID_ISR_SET)
+
+#define BIT_TDMA_BT_START_NOTIFY BIT(5)
+#define BIT_ENABLE_TDMA_FW_MODE BIT(4)
+#define BIT_ENABLE_PTA_TDMA_MODE BIT(3)
+#define BIT_ENABLE_COEXIST_TAB_IN_TDMA BIT(2)
+#define BIT_GPIO2_GPIO3_EXANGE_OR_NO_BT_CCA BIT(1)
+#define BIT_RTK_BT_ENABLE BIT(0)
+
+/* 2 REG_BT_STATUS_REPORT_REGISTER (Offset 0x077C) */
+
+#define BIT_SHIFT_BT_PROFILE 24
+#define BIT_MASK_BT_PROFILE 0xff
+#define BIT_BT_PROFILE(x) (((x) & BIT_MASK_BT_PROFILE) << BIT_SHIFT_BT_PROFILE)
+#define BIT_GET_BT_PROFILE(x) \
+ (((x) >> BIT_SHIFT_BT_PROFILE) & BIT_MASK_BT_PROFILE)
+
+#define BIT_SHIFT_BT_POWER 16
+#define BIT_MASK_BT_POWER 0xff
+#define BIT_BT_POWER(x) (((x) & BIT_MASK_BT_POWER) << BIT_SHIFT_BT_POWER)
+#define BIT_GET_BT_POWER(x) (((x) >> BIT_SHIFT_BT_POWER) & BIT_MASK_BT_POWER)
+
+#define BIT_SHIFT_BT_PREDECT_STATUS 8
+#define BIT_MASK_BT_PREDECT_STATUS 0xff
+#define BIT_BT_PREDECT_STATUS(x) \
+ (((x) & BIT_MASK_BT_PREDECT_STATUS) << BIT_SHIFT_BT_PREDECT_STATUS)
+#define BIT_GET_BT_PREDECT_STATUS(x) \
+ (((x) >> BIT_SHIFT_BT_PREDECT_STATUS) & BIT_MASK_BT_PREDECT_STATUS)
+
+#define BIT_SHIFT_BT_CMD_INFO 0
+#define BIT_MASK_BT_CMD_INFO 0xff
+#define BIT_BT_CMD_INFO(x) \
+ (((x) & BIT_MASK_BT_CMD_INFO) << BIT_SHIFT_BT_CMD_INFO)
+#define BIT_GET_BT_CMD_INFO(x) \
+ (((x) >> BIT_SHIFT_BT_CMD_INFO) & BIT_MASK_BT_CMD_INFO)
+
+/* 2 REG_BT_INTERRUPT_CONTROL_REGISTER (Offset 0x0780) */
+
+#define BIT_EN_MAC_NULL_PKT_NOTIFY BIT(31)
+#define BIT_EN_WLAN_RPT_AND_BT_QUERY BIT(30)
+#define BIT_EN_BT_STSTUS_RPT BIT(29)
+#define BIT_EN_BT_POWER BIT(28)
+#define BIT_EN_BT_CHANNEL BIT(27)
+#define BIT_EN_BT_SLOT_CHANGE BIT(26)
+#define BIT_EN_BT_PROFILE_OR_HID BIT(25)
+#define BIT_WLAN_RPT_NOTIFY BIT(24)
+
+#define BIT_SHIFT_WLAN_RPT_DATA 16
+#define BIT_MASK_WLAN_RPT_DATA 0xff
+#define BIT_WLAN_RPT_DATA(x) \
+ (((x) & BIT_MASK_WLAN_RPT_DATA) << BIT_SHIFT_WLAN_RPT_DATA)
+#define BIT_GET_WLAN_RPT_DATA(x) \
+ (((x) >> BIT_SHIFT_WLAN_RPT_DATA) & BIT_MASK_WLAN_RPT_DATA)
+
+#define BIT_SHIFT_CMD_ID 8
+#define BIT_MASK_CMD_ID 0xff
+#define BIT_CMD_ID(x) (((x) & BIT_MASK_CMD_ID) << BIT_SHIFT_CMD_ID)
+#define BIT_GET_CMD_ID(x) (((x) >> BIT_SHIFT_CMD_ID) & BIT_MASK_CMD_ID)
+
+#define BIT_SHIFT_BT_DATA 0
+#define BIT_MASK_BT_DATA 0xff
+#define BIT_BT_DATA(x) (((x) & BIT_MASK_BT_DATA) << BIT_SHIFT_BT_DATA)
+#define BIT_GET_BT_DATA(x) (((x) >> BIT_SHIFT_BT_DATA) & BIT_MASK_BT_DATA)
+
+/* 2 REG_WLAN_REPORT_TIME_OUT_CONTROL_REGISTER (Offset 0x0784) */
+
+#define BIT_SHIFT_WLAN_RPT_TO 0
+#define BIT_MASK_WLAN_RPT_TO 0xff
+#define BIT_WLAN_RPT_TO(x) \
+ (((x) & BIT_MASK_WLAN_RPT_TO) << BIT_SHIFT_WLAN_RPT_TO)
+#define BIT_GET_WLAN_RPT_TO(x) \
+ (((x) >> BIT_SHIFT_WLAN_RPT_TO) & BIT_MASK_WLAN_RPT_TO)
+
+/* 2 REG_BT_ISOLATION_TABLE_REGISTER_REGISTER (Offset 0x0785) */
+
+#define BIT_SHIFT_ISOLATION_CHK 1
+#define BIT_MASK_ISOLATION_CHK 0x7fffffffffffffffffffL
+#define BIT_ISOLATION_CHK(x) \
+ (((x) & BIT_MASK_ISOLATION_CHK) << BIT_SHIFT_ISOLATION_CHK)
+#define BIT_GET_ISOLATION_CHK(x) \
+ (((x) >> BIT_SHIFT_ISOLATION_CHK) & BIT_MASK_ISOLATION_CHK)
+
+/* 2 REG_BT_ISOLATION_TABLE_REGISTER_REGISTER (Offset 0x0785) */
+
+#define BIT_ISOLATION_EN BIT(0)
+
+/* 2 REG_BT_INTERRUPT_STATUS_REGISTER (Offset 0x078F) */
+
+#define BIT_BT_HID_ISR BIT(7)
+#define BIT_BT_QUERY_ISR BIT(6)
+#define BIT_MAC_NULL_PKT_NOTIFY_ISR BIT(5)
+#define BIT_WLAN_RPT_ISR BIT(4)
+#define BIT_BT_POWER_ISR BIT(3)
+#define BIT_BT_CHANNEL_ISR BIT(2)
+#define BIT_BT_SLOT_CHANGE_ISR BIT(1)
+#define BIT_BT_PROFILE_ISR BIT(0)
+
+/* 2 REG_BT_TDMA_TIME_REGISTER (Offset 0x0790) */
+
+#define BIT_SHIFT_BT_TIME 6
+#define BIT_MASK_BT_TIME 0x3ffffff
+#define BIT_BT_TIME(x) (((x) & BIT_MASK_BT_TIME) << BIT_SHIFT_BT_TIME)
+#define BIT_GET_BT_TIME(x) (((x) >> BIT_SHIFT_BT_TIME) & BIT_MASK_BT_TIME)
+
+#define BIT_SHIFT_BT_RPT_SAMPLE_RATE 0
+#define BIT_MASK_BT_RPT_SAMPLE_RATE 0x3f
+#define BIT_BT_RPT_SAMPLE_RATE(x) \
+ (((x) & BIT_MASK_BT_RPT_SAMPLE_RATE) << BIT_SHIFT_BT_RPT_SAMPLE_RATE)
+#define BIT_GET_BT_RPT_SAMPLE_RATE(x) \
+ (((x) >> BIT_SHIFT_BT_RPT_SAMPLE_RATE) & BIT_MASK_BT_RPT_SAMPLE_RATE)
+
+/* 2 REG_BT_ACT_REGISTER (Offset 0x0794) */
+
+#define BIT_SHIFT_BT_EISR_EN 16
+#define BIT_MASK_BT_EISR_EN 0xff
+#define BIT_BT_EISR_EN(x) (((x) & BIT_MASK_BT_EISR_EN) << BIT_SHIFT_BT_EISR_EN)
+#define BIT_GET_BT_EISR_EN(x) \
+ (((x) >> BIT_SHIFT_BT_EISR_EN) & BIT_MASK_BT_EISR_EN)
+
+#define BIT_BT_ACT_FALLING_ISR BIT(10)
+#define BIT_BT_ACT_RISING_ISR BIT(9)
+#define BIT_TDMA_TO_ISR BIT(8)
+
+#define BIT_SHIFT_BT_CH 0
+#define BIT_MASK_BT_CH 0xff
+#define BIT_BT_CH(x) (((x) & BIT_MASK_BT_CH) << BIT_SHIFT_BT_CH)
+#define BIT_GET_BT_CH(x) (((x) >> BIT_SHIFT_BT_CH) & BIT_MASK_BT_CH)
+
+/* 2 REG_OBFF_CTRL_BASIC (Offset 0x0798) */
+
+#define BIT_OBFF_EN_V1 BIT(31)
+
+#define BIT_SHIFT_OBFF_STATE_V1 28
+#define BIT_MASK_OBFF_STATE_V1 0x3
+#define BIT_OBFF_STATE_V1(x) \
+ (((x) & BIT_MASK_OBFF_STATE_V1) << BIT_SHIFT_OBFF_STATE_V1)
+#define BIT_GET_OBFF_STATE_V1(x) \
+ (((x) >> BIT_SHIFT_OBFF_STATE_V1) & BIT_MASK_OBFF_STATE_V1)
+
+#define BIT_OBFF_ACT_RXDMA_EN BIT(27)
+#define BIT_OBFF_BLOCK_INT_EN BIT(26)
+#define BIT_OBFF_AUTOACT_EN BIT(25)
+#define BIT_OBFF_AUTOIDLE_EN BIT(24)
+
+#define BIT_SHIFT_WAKE_MAX_PLS 20
+#define BIT_MASK_WAKE_MAX_PLS 0x7
+#define BIT_WAKE_MAX_PLS(x) \
+ (((x) & BIT_MASK_WAKE_MAX_PLS) << BIT_SHIFT_WAKE_MAX_PLS)
+#define BIT_GET_WAKE_MAX_PLS(x) \
+ (((x) >> BIT_SHIFT_WAKE_MAX_PLS) & BIT_MASK_WAKE_MAX_PLS)
+
+#define BIT_SHIFT_WAKE_MIN_PLS 16
+#define BIT_MASK_WAKE_MIN_PLS 0x7
+#define BIT_WAKE_MIN_PLS(x) \
+ (((x) & BIT_MASK_WAKE_MIN_PLS) << BIT_SHIFT_WAKE_MIN_PLS)
+#define BIT_GET_WAKE_MIN_PLS(x) \
+ (((x) >> BIT_SHIFT_WAKE_MIN_PLS) & BIT_MASK_WAKE_MIN_PLS)
+
+#define BIT_SHIFT_WAKE_MAX_F2F 12
+#define BIT_MASK_WAKE_MAX_F2F 0x7
+#define BIT_WAKE_MAX_F2F(x) \
+ (((x) & BIT_MASK_WAKE_MAX_F2F) << BIT_SHIFT_WAKE_MAX_F2F)
+#define BIT_GET_WAKE_MAX_F2F(x) \
+ (((x) >> BIT_SHIFT_WAKE_MAX_F2F) & BIT_MASK_WAKE_MAX_F2F)
+
+#define BIT_SHIFT_WAKE_MIN_F2F 8
+#define BIT_MASK_WAKE_MIN_F2F 0x7
+#define BIT_WAKE_MIN_F2F(x) \
+ (((x) & BIT_MASK_WAKE_MIN_F2F) << BIT_SHIFT_WAKE_MIN_F2F)
+#define BIT_GET_WAKE_MIN_F2F(x) \
+ (((x) >> BIT_SHIFT_WAKE_MIN_F2F) & BIT_MASK_WAKE_MIN_F2F)
+
+#define BIT_APP_CPU_ACT_V1 BIT(3)
+#define BIT_APP_OBFF_V1 BIT(2)
+#define BIT_APP_IDLE_V1 BIT(1)
+#define BIT_APP_INIT_V1 BIT(0)
+
+/* 2 REG_OBFF_CTRL2_TIMER (Offset 0x079C) */
+
+#define BIT_SHIFT_RX_HIGH_TIMER_IDX 24
+#define BIT_MASK_RX_HIGH_TIMER_IDX 0x7
+#define BIT_RX_HIGH_TIMER_IDX(x) \
+ (((x) & BIT_MASK_RX_HIGH_TIMER_IDX) << BIT_SHIFT_RX_HIGH_TIMER_IDX)
+#define BIT_GET_RX_HIGH_TIMER_IDX(x) \
+ (((x) >> BIT_SHIFT_RX_HIGH_TIMER_IDX) & BIT_MASK_RX_HIGH_TIMER_IDX)
+
+#define BIT_SHIFT_RX_MED_TIMER_IDX 16
+#define BIT_MASK_RX_MED_TIMER_IDX 0x7
+#define BIT_RX_MED_TIMER_IDX(x) \
+ (((x) & BIT_MASK_RX_MED_TIMER_IDX) << BIT_SHIFT_RX_MED_TIMER_IDX)
+#define BIT_GET_RX_MED_TIMER_IDX(x) \
+ (((x) >> BIT_SHIFT_RX_MED_TIMER_IDX) & BIT_MASK_RX_MED_TIMER_IDX)
+
+#define BIT_SHIFT_RX_LOW_TIMER_IDX 8
+#define BIT_MASK_RX_LOW_TIMER_IDX 0x7
+#define BIT_RX_LOW_TIMER_IDX(x) \
+ (((x) & BIT_MASK_RX_LOW_TIMER_IDX) << BIT_SHIFT_RX_LOW_TIMER_IDX)
+#define BIT_GET_RX_LOW_TIMER_IDX(x) \
+ (((x) >> BIT_SHIFT_RX_LOW_TIMER_IDX) & BIT_MASK_RX_LOW_TIMER_IDX)
+
+#define BIT_SHIFT_OBFF_INT_TIMER_IDX 0
+#define BIT_MASK_OBFF_INT_TIMER_IDX 0x7
+#define BIT_OBFF_INT_TIMER_IDX(x) \
+ (((x) & BIT_MASK_OBFF_INT_TIMER_IDX) << BIT_SHIFT_OBFF_INT_TIMER_IDX)
+#define BIT_GET_OBFF_INT_TIMER_IDX(x) \
+ (((x) >> BIT_SHIFT_OBFF_INT_TIMER_IDX) & BIT_MASK_OBFF_INT_TIMER_IDX)
+
+/* 2 REG_LTR_CTRL_BASIC (Offset 0x07A0) */
+
+#define BIT_LTR_EN_V1 BIT(31)
+#define BIT_LTR_HW_EN_V1 BIT(30)
+#define BIT_LRT_ACT_CTS_EN BIT(29)
+#define BIT_LTR_ACT_RXPKT_EN BIT(28)
+#define BIT_LTR_ACT_RXDMA_EN BIT(27)
+#define BIT_LTR_IDLE_NO_SNOOP BIT(26)
+#define BIT_SPDUP_MGTPKT BIT(25)
+#define BIT_RX_AGG_EN BIT(24)
+#define BIT_APP_LTR_ACT BIT(23)
+#define BIT_APP_LTR_IDLE BIT(22)
+
+#define BIT_SHIFT_HIGH_RATE_TRIG_SEL 20
+#define BIT_MASK_HIGH_RATE_TRIG_SEL 0x3
+#define BIT_HIGH_RATE_TRIG_SEL(x) \
+ (((x) & BIT_MASK_HIGH_RATE_TRIG_SEL) << BIT_SHIFT_HIGH_RATE_TRIG_SEL)
+#define BIT_GET_HIGH_RATE_TRIG_SEL(x) \
+ (((x) >> BIT_SHIFT_HIGH_RATE_TRIG_SEL) & BIT_MASK_HIGH_RATE_TRIG_SEL)
+
+#define BIT_SHIFT_MED_RATE_TRIG_SEL 18
+#define BIT_MASK_MED_RATE_TRIG_SEL 0x3
+#define BIT_MED_RATE_TRIG_SEL(x) \
+ (((x) & BIT_MASK_MED_RATE_TRIG_SEL) << BIT_SHIFT_MED_RATE_TRIG_SEL)
+#define BIT_GET_MED_RATE_TRIG_SEL(x) \
+ (((x) >> BIT_SHIFT_MED_RATE_TRIG_SEL) & BIT_MASK_MED_RATE_TRIG_SEL)
+
+#define BIT_SHIFT_LOW_RATE_TRIG_SEL 16
+#define BIT_MASK_LOW_RATE_TRIG_SEL 0x3
+#define BIT_LOW_RATE_TRIG_SEL(x) \
+ (((x) & BIT_MASK_LOW_RATE_TRIG_SEL) << BIT_SHIFT_LOW_RATE_TRIG_SEL)
+#define BIT_GET_LOW_RATE_TRIG_SEL(x) \
+ (((x) >> BIT_SHIFT_LOW_RATE_TRIG_SEL) & BIT_MASK_LOW_RATE_TRIG_SEL)
+
+#define BIT_SHIFT_HIGH_RATE_BD_IDX 8
+#define BIT_MASK_HIGH_RATE_BD_IDX 0x7f
+#define BIT_HIGH_RATE_BD_IDX(x) \
+ (((x) & BIT_MASK_HIGH_RATE_BD_IDX) << BIT_SHIFT_HIGH_RATE_BD_IDX)
+#define BIT_GET_HIGH_RATE_BD_IDX(x) \
+ (((x) >> BIT_SHIFT_HIGH_RATE_BD_IDX) & BIT_MASK_HIGH_RATE_BD_IDX)
+
+#define BIT_SHIFT_LOW_RATE_BD_IDX 0
+#define BIT_MASK_LOW_RATE_BD_IDX 0x7f
+#define BIT_LOW_RATE_BD_IDX(x) \
+ (((x) & BIT_MASK_LOW_RATE_BD_IDX) << BIT_SHIFT_LOW_RATE_BD_IDX)
+#define BIT_GET_LOW_RATE_BD_IDX(x) \
+ (((x) >> BIT_SHIFT_LOW_RATE_BD_IDX) & BIT_MASK_LOW_RATE_BD_IDX)
+
+/* 2 REG_LTR_CTRL2_TIMER_THRESHOLD (Offset 0x07A4) */
+
+#define BIT_SHIFT_RX_EMPTY_TIMER_IDX 24
+#define BIT_MASK_RX_EMPTY_TIMER_IDX 0x7
+#define BIT_RX_EMPTY_TIMER_IDX(x) \
+ (((x) & BIT_MASK_RX_EMPTY_TIMER_IDX) << BIT_SHIFT_RX_EMPTY_TIMER_IDX)
+#define BIT_GET_RX_EMPTY_TIMER_IDX(x) \
+ (((x) >> BIT_SHIFT_RX_EMPTY_TIMER_IDX) & BIT_MASK_RX_EMPTY_TIMER_IDX)
+
+#define BIT_SHIFT_RX_AFULL_TH_IDX 20
+#define BIT_MASK_RX_AFULL_TH_IDX 0x7
+#define BIT_RX_AFULL_TH_IDX(x) \
+ (((x) & BIT_MASK_RX_AFULL_TH_IDX) << BIT_SHIFT_RX_AFULL_TH_IDX)
+#define BIT_GET_RX_AFULL_TH_IDX(x) \
+ (((x) >> BIT_SHIFT_RX_AFULL_TH_IDX) & BIT_MASK_RX_AFULL_TH_IDX)
+
+#define BIT_SHIFT_RX_HIGH_TH_IDX 16
+#define BIT_MASK_RX_HIGH_TH_IDX 0x7
+#define BIT_RX_HIGH_TH_IDX(x) \
+ (((x) & BIT_MASK_RX_HIGH_TH_IDX) << BIT_SHIFT_RX_HIGH_TH_IDX)
+#define BIT_GET_RX_HIGH_TH_IDX(x) \
+ (((x) >> BIT_SHIFT_RX_HIGH_TH_IDX) & BIT_MASK_RX_HIGH_TH_IDX)
+
+#define BIT_SHIFT_RX_MED_TH_IDX 12
+#define BIT_MASK_RX_MED_TH_IDX 0x7
+#define BIT_RX_MED_TH_IDX(x) \
+ (((x) & BIT_MASK_RX_MED_TH_IDX) << BIT_SHIFT_RX_MED_TH_IDX)
+#define BIT_GET_RX_MED_TH_IDX(x) \
+ (((x) >> BIT_SHIFT_RX_MED_TH_IDX) & BIT_MASK_RX_MED_TH_IDX)
+
+#define BIT_SHIFT_RX_LOW_TH_IDX 8
+#define BIT_MASK_RX_LOW_TH_IDX 0x7
+#define BIT_RX_LOW_TH_IDX(x) \
+ (((x) & BIT_MASK_RX_LOW_TH_IDX) << BIT_SHIFT_RX_LOW_TH_IDX)
+#define BIT_GET_RX_LOW_TH_IDX(x) \
+ (((x) >> BIT_SHIFT_RX_LOW_TH_IDX) & BIT_MASK_RX_LOW_TH_IDX)
+
+#define BIT_SHIFT_LTR_SPACE_IDX 4
+#define BIT_MASK_LTR_SPACE_IDX 0x3
+#define BIT_LTR_SPACE_IDX(x) \
+ (((x) & BIT_MASK_LTR_SPACE_IDX) << BIT_SHIFT_LTR_SPACE_IDX)
+#define BIT_GET_LTR_SPACE_IDX(x) \
+ (((x) >> BIT_SHIFT_LTR_SPACE_IDX) & BIT_MASK_LTR_SPACE_IDX)
+
+#define BIT_SHIFT_LTR_IDLE_TIMER_IDX 0
+#define BIT_MASK_LTR_IDLE_TIMER_IDX 0x7
+#define BIT_LTR_IDLE_TIMER_IDX(x) \
+ (((x) & BIT_MASK_LTR_IDLE_TIMER_IDX) << BIT_SHIFT_LTR_IDLE_TIMER_IDX)
+#define BIT_GET_LTR_IDLE_TIMER_IDX(x) \
+ (((x) >> BIT_SHIFT_LTR_IDLE_TIMER_IDX) & BIT_MASK_LTR_IDLE_TIMER_IDX)
+
+/* 2 REG_LTR_IDLE_LATENCY_V1 (Offset 0x07A8) */
+
+#define BIT_SHIFT_LTR_IDLE_L 0
+#define BIT_MASK_LTR_IDLE_L 0xffffffffL
+#define BIT_LTR_IDLE_L(x) (((x) & BIT_MASK_LTR_IDLE_L) << BIT_SHIFT_LTR_IDLE_L)
+#define BIT_GET_LTR_IDLE_L(x) \
+ (((x) >> BIT_SHIFT_LTR_IDLE_L) & BIT_MASK_LTR_IDLE_L)
+
+/* 2 REG_LTR_ACTIVE_LATENCY_V1 (Offset 0x07AC) */
+
+#define BIT_SHIFT_LTR_ACT_L 0
+#define BIT_MASK_LTR_ACT_L 0xffffffffL
+#define BIT_LTR_ACT_L(x) (((x) & BIT_MASK_LTR_ACT_L) << BIT_SHIFT_LTR_ACT_L)
+#define BIT_GET_LTR_ACT_L(x) (((x) >> BIT_SHIFT_LTR_ACT_L) & BIT_MASK_LTR_ACT_L)
+
+/* 2 REG_ANTENNA_TRAINING_CONTROL_REGISTER (Offset 0x07B0) */
+
+#define BIT_APPEND_MACID_IN_RESP_EN BIT(50)
+#define BIT_ADDR2_MATCH_EN BIT(49)
+#define BIT_ANTTRN_EN BIT(48)
+
+#define BIT_SHIFT_TRAIN_STA_ADDR 0
+#define BIT_MASK_TRAIN_STA_ADDR 0xffffffffffffL
+#define BIT_TRAIN_STA_ADDR(x) \
+ (((x) & BIT_MASK_TRAIN_STA_ADDR) << BIT_SHIFT_TRAIN_STA_ADDR)
+#define BIT_GET_TRAIN_STA_ADDR(x) \
+ (((x) >> BIT_SHIFT_TRAIN_STA_ADDR) & BIT_MASK_TRAIN_STA_ADDR)
+
+/* 2 REG_WMAC_PKTCNT_RWD (Offset 0x07B8) */
+
+#define BIT_SHIFT_PKTCNT_BSSIDMAP 4
+#define BIT_MASK_PKTCNT_BSSIDMAP 0xf
+#define BIT_PKTCNT_BSSIDMAP(x) \
+ (((x) & BIT_MASK_PKTCNT_BSSIDMAP) << BIT_SHIFT_PKTCNT_BSSIDMAP)
+#define BIT_GET_PKTCNT_BSSIDMAP(x) \
+ (((x) >> BIT_SHIFT_PKTCNT_BSSIDMAP) & BIT_MASK_PKTCNT_BSSIDMAP)
+
+#define BIT_PKTCNT_CNTRST BIT(1)
+#define BIT_PKTCNT_CNTEN BIT(0)
+
+/* 2 REG_WMAC_PKTCNT_CTRL (Offset 0x07BC) */
+
+#define BIT_WMAC_PKTCNT_TRST BIT(9)
+#define BIT_WMAC_PKTCNT_FEN BIT(8)
+
+#define BIT_SHIFT_WMAC_PKTCNT_CFGAD 0
+#define BIT_MASK_WMAC_PKTCNT_CFGAD 0xff
+#define BIT_WMAC_PKTCNT_CFGAD(x) \
+ (((x) & BIT_MASK_WMAC_PKTCNT_CFGAD) << BIT_SHIFT_WMAC_PKTCNT_CFGAD)
+#define BIT_GET_WMAC_PKTCNT_CFGAD(x) \
+ (((x) >> BIT_SHIFT_WMAC_PKTCNT_CFGAD) & BIT_MASK_WMAC_PKTCNT_CFGAD)
+
+/* 2 REG_IQ_DUMP (Offset 0x07C0) */
+
+#define BIT_SHIFT_R_WMAC_MATCH_REF_MAC (64 & CPU_OPT_WIDTH)
+#define BIT_MASK_R_WMAC_MATCH_REF_MAC 0xffffffffL
+#define BIT_R_WMAC_MATCH_REF_MAC(x) \
+ (((x) & BIT_MASK_R_WMAC_MATCH_REF_MAC) \
+ << BIT_SHIFT_R_WMAC_MATCH_REF_MAC)
+#define BIT_GET_R_WMAC_MATCH_REF_MAC(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_MATCH_REF_MAC) & \
+ BIT_MASK_R_WMAC_MATCH_REF_MAC)
+
+#define BIT_SHIFT_R_WMAC_RX_FIL_LEN (64 & CPU_OPT_WIDTH)
+#define BIT_MASK_R_WMAC_RX_FIL_LEN 0xffff
+#define BIT_R_WMAC_RX_FIL_LEN(x) \
+ (((x) & BIT_MASK_R_WMAC_RX_FIL_LEN) << BIT_SHIFT_R_WMAC_RX_FIL_LEN)
+#define BIT_GET_R_WMAC_RX_FIL_LEN(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_RX_FIL_LEN) & BIT_MASK_R_WMAC_RX_FIL_LEN)
+
+#define BIT_SHIFT_R_WMAC_RXFIFO_FULL_TH (56 & CPU_OPT_WIDTH)
+#define BIT_MASK_R_WMAC_RXFIFO_FULL_TH 0xff
+#define BIT_R_WMAC_RXFIFO_FULL_TH(x) \
+ (((x) & BIT_MASK_R_WMAC_RXFIFO_FULL_TH) \
+ << BIT_SHIFT_R_WMAC_RXFIFO_FULL_TH)
+#define BIT_GET_R_WMAC_RXFIFO_FULL_TH(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_RXFIFO_FULL_TH) & \
+ BIT_MASK_R_WMAC_RXFIFO_FULL_TH)
+
+#define BIT_R_WMAC_SRCH_TXRPT_TYPE BIT(51)
+#define BIT_R_WMAC_NDP_RST BIT(50)
+#define BIT_R_WMAC_POWINT_EN BIT(49)
+#define BIT_R_WMAC_SRCH_TXRPT_PERPKT BIT(48)
+#define BIT_R_WMAC_SRCH_TXRPT_MID BIT(47)
+#define BIT_R_WMAC_PFIN_TOEN BIT(46)
+#define BIT_R_WMAC_FIL_SECERR BIT(45)
+#define BIT_R_WMAC_FIL_CTLPKTLEN BIT(44)
+#define BIT_R_WMAC_FIL_FCTYPE BIT(43)
+#define BIT_R_WMAC_FIL_FCPROVER BIT(42)
+#define BIT_R_WMAC_PHYSTS_SNIF BIT(41)
+#define BIT_R_WMAC_PHYSTS_PLCP BIT(40)
+#define BIT_R_MAC_TCR_VBONF_RD BIT(39)
+#define BIT_R_WMAC_TCR_MPAR_NDP BIT(38)
+#define BIT_R_WMAC_NDP_FILTER BIT(37)
+#define BIT_R_WMAC_RXLEN_SEL BIT(36)
+#define BIT_R_WMAC_RXLEN_SEL1 BIT(35)
+#define BIT_R_OFDM_FILTER BIT(34)
+#define BIT_R_WMAC_CHK_OFDM_LEN BIT(33)
+
+#define BIT_SHIFT_R_WMAC_MASK_LA_MAC (32 & CPU_OPT_WIDTH)
+#define BIT_MASK_R_WMAC_MASK_LA_MAC 0xffffffffL
+#define BIT_R_WMAC_MASK_LA_MAC(x) \
+ (((x) & BIT_MASK_R_WMAC_MASK_LA_MAC) << BIT_SHIFT_R_WMAC_MASK_LA_MAC)
+#define BIT_GET_R_WMAC_MASK_LA_MAC(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_MASK_LA_MAC) & BIT_MASK_R_WMAC_MASK_LA_MAC)
+
+#define BIT_R_WMAC_CHK_CCK_LEN BIT(32)
+
+/* 2 REG_IQ_DUMP (Offset 0x07C0) */
+
+#define BIT_SHIFT_R_OFDM_LEN 26
+#define BIT_MASK_R_OFDM_LEN 0x3f
+#define BIT_R_OFDM_LEN(x) (((x) & BIT_MASK_R_OFDM_LEN) << BIT_SHIFT_R_OFDM_LEN)
+#define BIT_GET_R_OFDM_LEN(x) \
+ (((x) >> BIT_SHIFT_R_OFDM_LEN) & BIT_MASK_R_OFDM_LEN)
+
+#define BIT_SHIFT_DUMP_OK_ADDR 15
+#define BIT_MASK_DUMP_OK_ADDR 0x1ffff
+#define BIT_DUMP_OK_ADDR(x) \
+ (((x) & BIT_MASK_DUMP_OK_ADDR) << BIT_SHIFT_DUMP_OK_ADDR)
+#define BIT_GET_DUMP_OK_ADDR(x) \
+ (((x) >> BIT_SHIFT_DUMP_OK_ADDR) & BIT_MASK_DUMP_OK_ADDR)
+
+#define BIT_SHIFT_R_TRIG_TIME_SEL 8
+#define BIT_MASK_R_TRIG_TIME_SEL 0x7f
+#define BIT_R_TRIG_TIME_SEL(x) \
+ (((x) & BIT_MASK_R_TRIG_TIME_SEL) << BIT_SHIFT_R_TRIG_TIME_SEL)
+#define BIT_GET_R_TRIG_TIME_SEL(x) \
+ (((x) >> BIT_SHIFT_R_TRIG_TIME_SEL) & BIT_MASK_R_TRIG_TIME_SEL)
+
+#define BIT_SHIFT_R_MAC_TRIG_SEL 6
+#define BIT_MASK_R_MAC_TRIG_SEL 0x3
+#define BIT_R_MAC_TRIG_SEL(x) \
+ (((x) & BIT_MASK_R_MAC_TRIG_SEL) << BIT_SHIFT_R_MAC_TRIG_SEL)
+#define BIT_GET_R_MAC_TRIG_SEL(x) \
+ (((x) >> BIT_SHIFT_R_MAC_TRIG_SEL) & BIT_MASK_R_MAC_TRIG_SEL)
+
+#define BIT_MAC_TRIG_REG BIT(5)
+
+#define BIT_SHIFT_R_LEVEL_PULSE_SEL 3
+#define BIT_MASK_R_LEVEL_PULSE_SEL 0x3
+#define BIT_R_LEVEL_PULSE_SEL(x) \
+ (((x) & BIT_MASK_R_LEVEL_PULSE_SEL) << BIT_SHIFT_R_LEVEL_PULSE_SEL)
+#define BIT_GET_R_LEVEL_PULSE_SEL(x) \
+ (((x) >> BIT_SHIFT_R_LEVEL_PULSE_SEL) & BIT_MASK_R_LEVEL_PULSE_SEL)
+
+#define BIT_EN_LA_MAC BIT(2)
+#define BIT_R_EN_IQDUMP BIT(1)
+#define BIT_R_IQDATA_DUMP BIT(0)
+
+#define BIT_SHIFT_R_CCK_LEN 0
+#define BIT_MASK_R_CCK_LEN 0xffff
+#define BIT_R_CCK_LEN(x) (((x) & BIT_MASK_R_CCK_LEN) << BIT_SHIFT_R_CCK_LEN)
+#define BIT_GET_R_CCK_LEN(x) (((x) >> BIT_SHIFT_R_CCK_LEN) & BIT_MASK_R_CCK_LEN)
+
+/* 2 REG_WMAC_FTM_CTL (Offset 0x07CC) */
+
+#define BIT_RXFTM_TXACK_SC BIT(6)
+#define BIT_RXFTM_TXACK_BW BIT(5)
+#define BIT_RXFTM_EN BIT(3)
+#define BIT_RXFTMREQ_BYDRV BIT(2)
+#define BIT_RXFTMREQ_EN BIT(1)
+#define BIT_FTM_EN BIT(0)
+
+/* 2 REG_RX_FILTER_FUNCTION (Offset 0x07DA) */
+
+#define BIT_R_WMAC_MHRDDY_LATCH BIT(14)
+
+/* 2 REG_RX_FILTER_FUNCTION (Offset 0x07DA) */
+
+#define BIT_R_WMAC_MHRDDY_CLR BIT(13)
+
+/* 2 REG_RX_FILTER_FUNCTION (Offset 0x07DA) */
+
+#define BIT_R_RXPKTCTL_FSM_BASED_MPDURDY1 BIT(12)
+
+/* 2 REG_RX_FILTER_FUNCTION (Offset 0x07DA) */
+
+#define BIT_WMAC_DIS_VHT_PLCP_CHK_MU BIT(11)
+
+/* 2 REG_RX_FILTER_FUNCTION (Offset 0x07DA) */
+
+#define BIT_R_CHK_DELIMIT_LEN BIT(10)
+#define BIT_R_REAPTER_ADDR_MATCH BIT(9)
+#define BIT_R_RXPKTCTL_FSM_BASED_MPDURDY BIT(8)
+#define BIT_R_LATCH_MACHRDY BIT(7)
+#define BIT_R_WMAC_RXFIL_REND BIT(6)
+#define BIT_R_WMAC_MPDURDY_CLR BIT(5)
+#define BIT_R_WMAC_CLRRXSEC BIT(4)
+#define BIT_R_WMAC_RXFIL_RDEL BIT(3)
+#define BIT_R_WMAC_RXFIL_FCSE BIT(2)
+#define BIT_R_WMAC_RXFIL_MESH_DEL BIT(1)
+#define BIT_R_WMAC_RXFIL_MASKM BIT(0)
+
+/* 2 REG_NDP_SIG (Offset 0x07E0) */
+
+#define BIT_SHIFT_R_WMAC_TXNDP_SIGB 0
+#define BIT_MASK_R_WMAC_TXNDP_SIGB 0x1fffff
+#define BIT_R_WMAC_TXNDP_SIGB(x) \
+ (((x) & BIT_MASK_R_WMAC_TXNDP_SIGB) << BIT_SHIFT_R_WMAC_TXNDP_SIGB)
+#define BIT_GET_R_WMAC_TXNDP_SIGB(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_TXNDP_SIGB) & BIT_MASK_R_WMAC_TXNDP_SIGB)
+
+/* 2 REG_TXCMD_INFO_FOR_RSP_PKT (Offset 0x07E4) */
+
+#define BIT_SHIFT_R_MAC_DEBUG (32 & CPU_OPT_WIDTH)
+#define BIT_MASK_R_MAC_DEBUG 0xffffffffL
+#define BIT_R_MAC_DEBUG(x) \
+ (((x) & BIT_MASK_R_MAC_DEBUG) << BIT_SHIFT_R_MAC_DEBUG)
+#define BIT_GET_R_MAC_DEBUG(x) \
+ (((x) >> BIT_SHIFT_R_MAC_DEBUG) & BIT_MASK_R_MAC_DEBUG)
+
+/* 2 REG_TXCMD_INFO_FOR_RSP_PKT (Offset 0x07E4) */
+
+#define BIT_SHIFT_R_MAC_DBG_SHIFT 8
+#define BIT_MASK_R_MAC_DBG_SHIFT 0x7
+#define BIT_R_MAC_DBG_SHIFT(x) \
+ (((x) & BIT_MASK_R_MAC_DBG_SHIFT) << BIT_SHIFT_R_MAC_DBG_SHIFT)
+#define BIT_GET_R_MAC_DBG_SHIFT(x) \
+ (((x) >> BIT_SHIFT_R_MAC_DBG_SHIFT) & BIT_MASK_R_MAC_DBG_SHIFT)
+
+#define BIT_SHIFT_R_MAC_DBG_SEL 0
+#define BIT_MASK_R_MAC_DBG_SEL 0x3
+#define BIT_R_MAC_DBG_SEL(x) \
+ (((x) & BIT_MASK_R_MAC_DBG_SEL) << BIT_SHIFT_R_MAC_DBG_SEL)
+#define BIT_GET_R_MAC_DBG_SEL(x) \
+ (((x) >> BIT_SHIFT_R_MAC_DBG_SEL) & BIT_MASK_R_MAC_DBG_SEL)
+
+/* 2 REG_SYS_CFG3 (Offset 0x1000) */
+
+#define BIT_PWC_MA33V BIT(15)
+
+/* 2 REG_SYS_CFG3 (Offset 0x1000) */
+
+#define BIT_PWC_MA12V BIT(14)
+#define BIT_PWC_MD12V BIT(13)
+#define BIT_PWC_PD12V BIT(12)
+#define BIT_PWC_UD12V BIT(11)
+#define BIT_ISO_MA2MD BIT(1)
+
+/* 2 REG_SYS_CFG5 (Offset 0x1070) */
+
+#define BIT_LPS_STATUS BIT(3)
+#define BIT_HCI_TXDMA_BUSY BIT(2)
+#define BIT_HCI_TXDMA_ALLOW BIT(1)
+#define BIT_FW_CTRL_HCI_TXDMA_EN BIT(0)
+
+/* 2 REG_CPU_DMEM_CON (Offset 0x1080) */
+
+#define BIT_WDT_OPT_IOWRAPPER BIT(19)
+
+/* 2 REG_CPU_DMEM_CON (Offset 0x1080) */
+
+#define BIT_ANA_PORT_IDLE BIT(18)
+#define BIT_MAC_PORT_IDLE BIT(17)
+#define BIT_WL_PLATFORM_RST BIT(16)
+#define BIT_WL_SECURITY_CLK BIT(15)
+
+/* 2 REG_CPU_DMEM_CON (Offset 0x1080) */
+
+#define BIT_SHIFT_CPU_DMEM_CON 0
+#define BIT_MASK_CPU_DMEM_CON 0xff
+#define BIT_CPU_DMEM_CON(x) \
+ (((x) & BIT_MASK_CPU_DMEM_CON) << BIT_SHIFT_CPU_DMEM_CON)
+#define BIT_GET_CPU_DMEM_CON(x) \
+ (((x) >> BIT_SHIFT_CPU_DMEM_CON) & BIT_MASK_CPU_DMEM_CON)
+
+/* 2 REG_BOOT_REASON (Offset 0x1088) */
+
+#define BIT_SHIFT_BOOT_REASON 0
+#define BIT_MASK_BOOT_REASON 0x7
+#define BIT_BOOT_REASON(x) \
+ (((x) & BIT_MASK_BOOT_REASON) << BIT_SHIFT_BOOT_REASON)
+#define BIT_GET_BOOT_REASON(x) \
+ (((x) >> BIT_SHIFT_BOOT_REASON) & BIT_MASK_BOOT_REASON)
+
+/* 2 REG_NFCPAD_CTRL (Offset 0x10A8) */
+
+#define BIT_PAD_SHUTDW BIT(18)
+#define BIT_SYSON_NFC_PAD BIT(17)
+#define BIT_NFC_INT_PAD_CTRL BIT(16)
+#define BIT_NFC_RFDIS_PAD_CTRL BIT(15)
+#define BIT_NFC_CLK_PAD_CTRL BIT(14)
+#define BIT_NFC_DATA_PAD_CTRL BIT(13)
+#define BIT_NFC_PAD_PULL_CTRL BIT(12)
+
+#define BIT_SHIFT_NFCPAD_IO_SEL 8
+#define BIT_MASK_NFCPAD_IO_SEL 0xf
+#define BIT_NFCPAD_IO_SEL(x) \
+ (((x) & BIT_MASK_NFCPAD_IO_SEL) << BIT_SHIFT_NFCPAD_IO_SEL)
+#define BIT_GET_NFCPAD_IO_SEL(x) \
+ (((x) >> BIT_SHIFT_NFCPAD_IO_SEL) & BIT_MASK_NFCPAD_IO_SEL)
+
+#define BIT_SHIFT_NFCPAD_OUT 4
+#define BIT_MASK_NFCPAD_OUT 0xf
+#define BIT_NFCPAD_OUT(x) (((x) & BIT_MASK_NFCPAD_OUT) << BIT_SHIFT_NFCPAD_OUT)
+#define BIT_GET_NFCPAD_OUT(x) \
+ (((x) >> BIT_SHIFT_NFCPAD_OUT) & BIT_MASK_NFCPAD_OUT)
+
+#define BIT_SHIFT_NFCPAD_IN 0
+#define BIT_MASK_NFCPAD_IN 0xf
+#define BIT_NFCPAD_IN(x) (((x) & BIT_MASK_NFCPAD_IN) << BIT_SHIFT_NFCPAD_IN)
+#define BIT_GET_NFCPAD_IN(x) (((x) >> BIT_SHIFT_NFCPAD_IN) & BIT_MASK_NFCPAD_IN)
+
+/* 2 REG_HIMR2 (Offset 0x10B0) */
+
+#define BIT_BCNDMAINT_P4_MSK BIT(31)
+#define BIT_BCNDMAINT_P3_MSK BIT(30)
+#define BIT_BCNDMAINT_P2_MSK BIT(29)
+#define BIT_BCNDMAINT_P1_MSK BIT(28)
+#define BIT_ATIMEND7_MSK BIT(22)
+#define BIT_ATIMEND6_MSK BIT(21)
+#define BIT_ATIMEND5_MSK BIT(20)
+#define BIT_ATIMEND4_MSK BIT(19)
+#define BIT_ATIMEND3_MSK BIT(18)
+#define BIT_ATIMEND2_MSK BIT(17)
+#define BIT_ATIMEND1_MSK BIT(16)
+#define BIT_TXBCN7OK_MSK BIT(14)
+#define BIT_TXBCN6OK_MSK BIT(13)
+#define BIT_TXBCN5OK_MSK BIT(12)
+#define BIT_TXBCN4OK_MSK BIT(11)
+#define BIT_TXBCN3OK_MSK BIT(10)
+#define BIT_TXBCN2OK_MSK BIT(9)
+#define BIT_TXBCN1OK_MSK_V1 BIT(8)
+#define BIT_TXBCN7ERR_MSK BIT(6)
+#define BIT_TXBCN6ERR_MSK BIT(5)
+#define BIT_TXBCN5ERR_MSK BIT(4)
+#define BIT_TXBCN4ERR_MSK BIT(3)
+#define BIT_TXBCN3ERR_MSK BIT(2)
+#define BIT_TXBCN2ERR_MSK BIT(1)
+#define BIT_TXBCN1ERR_MSK_V1 BIT(0)
+
+/* 2 REG_HISR2 (Offset 0x10B4) */
+
+#define BIT_BCNDMAINT_P4 BIT(31)
+#define BIT_BCNDMAINT_P3 BIT(30)
+#define BIT_BCNDMAINT_P2 BIT(29)
+#define BIT_BCNDMAINT_P1 BIT(28)
+#define BIT_ATIMEND7 BIT(22)
+#define BIT_ATIMEND6 BIT(21)
+#define BIT_ATIMEND5 BIT(20)
+#define BIT_ATIMEND4 BIT(19)
+#define BIT_ATIMEND3 BIT(18)
+#define BIT_ATIMEND2 BIT(17)
+#define BIT_ATIMEND1 BIT(16)
+#define BIT_TXBCN7OK BIT(14)
+#define BIT_TXBCN6OK BIT(13)
+#define BIT_TXBCN5OK BIT(12)
+#define BIT_TXBCN4OK BIT(11)
+#define BIT_TXBCN3OK BIT(10)
+#define BIT_TXBCN2OK BIT(9)
+#define BIT_TXBCN1OK BIT(8)
+#define BIT_TXBCN7ERR BIT(6)
+#define BIT_TXBCN6ERR BIT(5)
+#define BIT_TXBCN5ERR BIT(4)
+#define BIT_TXBCN4ERR BIT(3)
+#define BIT_TXBCN3ERR BIT(2)
+#define BIT_TXBCN2ERR BIT(1)
+#define BIT_TXBCN1ERR BIT(0)
+
+/* 2 REG_HIMR3 (Offset 0x10B8) */
+
+#define BIT_WDT_PLATFORM_INT_MSK BIT(18)
+#define BIT_WDT_CPU_INT_MSK BIT(17)
+
+/* 2 REG_HIMR3 (Offset 0x10B8) */
+
+#define BIT_SETH2CDOK_MASK BIT(16)
+#define BIT_H2C_CMD_FULL_MASK BIT(15)
+#define BIT_PWR_INT_127_MASK BIT(14)
+#define BIT_TXSHORTCUT_TXDESUPDATEOK_MASK BIT(13)
+#define BIT_TXSHORTCUT_BKUPDATEOK_MASK BIT(12)
+#define BIT_TXSHORTCUT_BEUPDATEOK_MASK BIT(11)
+#define BIT_TXSHORTCUT_VIUPDATEOK_MAS BIT(10)
+#define BIT_TXSHORTCUT_VOUPDATEOK_MASK BIT(9)
+#define BIT_PWR_INT_127_MASK_V1 BIT(8)
+#define BIT_PWR_INT_126TO96_MASK BIT(7)
+#define BIT_PWR_INT_95TO64_MASK BIT(6)
+#define BIT_PWR_INT_63TO32_MASK BIT(5)
+#define BIT_PWR_INT_31TO0_MASK BIT(4)
+#define BIT_DDMA0_LP_INT_MSK BIT(1)
+#define BIT_DDMA0_HP_INT_MSK BIT(0)
+
+/* 2 REG_HISR3 (Offset 0x10BC) */
+
+#define BIT_WDT_PLATFORM_INT BIT(18)
+#define BIT_WDT_CPU_INT BIT(17)
+
+/* 2 REG_HISR3 (Offset 0x10BC) */
+
+#define BIT_SETH2CDOK BIT(16)
+#define BIT_H2C_CMD_FULL BIT(15)
+#define BIT_PWR_INT_127 BIT(14)
+#define BIT_TXSHORTCUT_TXDESUPDATEOK BIT(13)
+#define BIT_TXSHORTCUT_BKUPDATEOK BIT(12)
+#define BIT_TXSHORTCUT_BEUPDATEOK BIT(11)
+#define BIT_TXSHORTCUT_VIUPDATEOK BIT(10)
+#define BIT_TXSHORTCUT_VOUPDATEOK BIT(9)
+#define BIT_PWR_INT_127_V1 BIT(8)
+#define BIT_PWR_INT_126TO96 BIT(7)
+#define BIT_PWR_INT_95TO64 BIT(6)
+#define BIT_PWR_INT_63TO32 BIT(5)
+#define BIT_PWR_INT_31TO0 BIT(4)
+#define BIT_DDMA0_LP_INT BIT(1)
+#define BIT_DDMA0_HP_INT BIT(0)
+
+/* 2 REG_SW_MDIO (Offset 0x10C0) */
+
+#define BIT_DIS_TIMEOUT_IO BIT(24)
+
+/* 2 REG_SW_FLUSH (Offset 0x10C4) */
+
+#define BIT_FLUSH_HOLDN_EN BIT(25)
+#define BIT_FLUSH_WR_EN BIT(24)
+#define BIT_SW_FLASH_CONTROL BIT(23)
+#define BIT_SW_FLASH_WEN_E BIT(19)
+#define BIT_SW_FLASH_HOLDN_E BIT(18)
+#define BIT_SW_FLASH_SO_E BIT(17)
+#define BIT_SW_FLASH_SI_E BIT(16)
+#define BIT_SW_FLASH_SK_O BIT(13)
+#define BIT_SW_FLASH_CEN_O BIT(12)
+#define BIT_SW_FLASH_WEN_O BIT(11)
+#define BIT_SW_FLASH_HOLDN_O BIT(10)
+#define BIT_SW_FLASH_SO_O BIT(9)
+#define BIT_SW_FLASH_SI_O BIT(8)
+#define BIT_SW_FLASH_WEN_I BIT(3)
+#define BIT_SW_FLASH_HOLDN_I BIT(2)
+#define BIT_SW_FLASH_SO_I BIT(1)
+#define BIT_SW_FLASH_SI_I BIT(0)
+
+/* 2 REG_H2C_PKT_READADDR (Offset 0x10D0) */
+
+#define BIT_SHIFT_H2C_PKT_READADDR 0
+#define BIT_MASK_H2C_PKT_READADDR 0x3ffff
+#define BIT_H2C_PKT_READADDR(x) \
+ (((x) & BIT_MASK_H2C_PKT_READADDR) << BIT_SHIFT_H2C_PKT_READADDR)
+#define BIT_GET_H2C_PKT_READADDR(x) \
+ (((x) >> BIT_SHIFT_H2C_PKT_READADDR) & BIT_MASK_H2C_PKT_READADDR)
+
+/* 2 REG_H2C_PKT_WRITEADDR (Offset 0x10D4) */
+
+#define BIT_SHIFT_H2C_PKT_WRITEADDR 0
+#define BIT_MASK_H2C_PKT_WRITEADDR 0x3ffff
+#define BIT_H2C_PKT_WRITEADDR(x) \
+ (((x) & BIT_MASK_H2C_PKT_WRITEADDR) << BIT_SHIFT_H2C_PKT_WRITEADDR)
+#define BIT_GET_H2C_PKT_WRITEADDR(x) \
+ (((x) >> BIT_SHIFT_H2C_PKT_WRITEADDR) & BIT_MASK_H2C_PKT_WRITEADDR)
+
+/* 2 REG_MEM_PWR_CRTL (Offset 0x10D8) */
+
+#define BIT_MEM_BB_SD BIT(17)
+#define BIT_MEM_BB_DS BIT(16)
+#define BIT_MEM_BT_DS BIT(10)
+#define BIT_MEM_SDIO_LS BIT(9)
+#define BIT_MEM_SDIO_DS BIT(8)
+#define BIT_MEM_USB_LS BIT(7)
+#define BIT_MEM_USB_DS BIT(6)
+#define BIT_MEM_PCI_LS BIT(5)
+#define BIT_MEM_PCI_DS BIT(4)
+#define BIT_MEM_WLMAC_LS BIT(3)
+#define BIT_MEM_WLMAC_DS BIT(2)
+#define BIT_MEM_WLMCU_LS BIT(1)
+
+/* 2 REG_MEM_PWR_CRTL (Offset 0x10D8) */
+
+#define BIT_MEM_WLMCU_DS BIT(0)
+
+/* 2 REG_FW_DBG0 (Offset 0x10E0) */
+
+#define BIT_SHIFT_FW_DBG0 0
+#define BIT_MASK_FW_DBG0 0xffffffffL
+#define BIT_FW_DBG0(x) (((x) & BIT_MASK_FW_DBG0) << BIT_SHIFT_FW_DBG0)
+#define BIT_GET_FW_DBG0(x) (((x) >> BIT_SHIFT_FW_DBG0) & BIT_MASK_FW_DBG0)
+
+/* 2 REG_FW_DBG1 (Offset 0x10E4) */
+
+#define BIT_SHIFT_FW_DBG1 0
+#define BIT_MASK_FW_DBG1 0xffffffffL
+#define BIT_FW_DBG1(x) (((x) & BIT_MASK_FW_DBG1) << BIT_SHIFT_FW_DBG1)
+#define BIT_GET_FW_DBG1(x) (((x) >> BIT_SHIFT_FW_DBG1) & BIT_MASK_FW_DBG1)
+
+/* 2 REG_FW_DBG2 (Offset 0x10E8) */
+
+#define BIT_SHIFT_FW_DBG2 0
+#define BIT_MASK_FW_DBG2 0xffffffffL
+#define BIT_FW_DBG2(x) (((x) & BIT_MASK_FW_DBG2) << BIT_SHIFT_FW_DBG2)
+#define BIT_GET_FW_DBG2(x) (((x) >> BIT_SHIFT_FW_DBG2) & BIT_MASK_FW_DBG2)
+
+/* 2 REG_FW_DBG3 (Offset 0x10EC) */
+
+#define BIT_SHIFT_FW_DBG3 0
+#define BIT_MASK_FW_DBG3 0xffffffffL
+#define BIT_FW_DBG3(x) (((x) & BIT_MASK_FW_DBG3) << BIT_SHIFT_FW_DBG3)
+#define BIT_GET_FW_DBG3(x) (((x) >> BIT_SHIFT_FW_DBG3) & BIT_MASK_FW_DBG3)
+
+/* 2 REG_FW_DBG4 (Offset 0x10F0) */
+
+#define BIT_SHIFT_FW_DBG4 0
+#define BIT_MASK_FW_DBG4 0xffffffffL
+#define BIT_FW_DBG4(x) (((x) & BIT_MASK_FW_DBG4) << BIT_SHIFT_FW_DBG4)
+#define BIT_GET_FW_DBG4(x) (((x) >> BIT_SHIFT_FW_DBG4) & BIT_MASK_FW_DBG4)
+
+/* 2 REG_FW_DBG5 (Offset 0x10F4) */
+
+#define BIT_SHIFT_FW_DBG5 0
+#define BIT_MASK_FW_DBG5 0xffffffffL
+#define BIT_FW_DBG5(x) (((x) & BIT_MASK_FW_DBG5) << BIT_SHIFT_FW_DBG5)
+#define BIT_GET_FW_DBG5(x) (((x) >> BIT_SHIFT_FW_DBG5) & BIT_MASK_FW_DBG5)
+
+/* 2 REG_FW_DBG6 (Offset 0x10F8) */
+
+#define BIT_SHIFT_FW_DBG6 0
+#define BIT_MASK_FW_DBG6 0xffffffffL
+#define BIT_FW_DBG6(x) (((x) & BIT_MASK_FW_DBG6) << BIT_SHIFT_FW_DBG6)
+#define BIT_GET_FW_DBG6(x) (((x) >> BIT_SHIFT_FW_DBG6) & BIT_MASK_FW_DBG6)
+
+/* 2 REG_FW_DBG7 (Offset 0x10FC) */
+
+#define BIT_SHIFT_FW_DBG7 0
+#define BIT_MASK_FW_DBG7 0xffffffffL
+#define BIT_FW_DBG7(x) (((x) & BIT_MASK_FW_DBG7) << BIT_SHIFT_FW_DBG7)
+#define BIT_GET_FW_DBG7(x) (((x) >> BIT_SHIFT_FW_DBG7) & BIT_MASK_FW_DBG7)
+
+/* 2 REG_CR_EXT (Offset 0x1100) */
+
+#define BIT_SHIFT_PHY_REQ_DELAY 24
+#define BIT_MASK_PHY_REQ_DELAY 0xf
+#define BIT_PHY_REQ_DELAY(x) \
+ (((x) & BIT_MASK_PHY_REQ_DELAY) << BIT_SHIFT_PHY_REQ_DELAY)
+#define BIT_GET_PHY_REQ_DELAY(x) \
+ (((x) >> BIT_SHIFT_PHY_REQ_DELAY) & BIT_MASK_PHY_REQ_DELAY)
+
+#define BIT_SPD_DOWN BIT(16)
+
+#define BIT_SHIFT_NETYPE4 4
+#define BIT_MASK_NETYPE4 0x3
+#define BIT_NETYPE4(x) (((x) & BIT_MASK_NETYPE4) << BIT_SHIFT_NETYPE4)
+#define BIT_GET_NETYPE4(x) (((x) >> BIT_SHIFT_NETYPE4) & BIT_MASK_NETYPE4)
+
+#define BIT_SHIFT_NETYPE3 2
+#define BIT_MASK_NETYPE3 0x3
+#define BIT_NETYPE3(x) (((x) & BIT_MASK_NETYPE3) << BIT_SHIFT_NETYPE3)
+#define BIT_GET_NETYPE3(x) (((x) >> BIT_SHIFT_NETYPE3) & BIT_MASK_NETYPE3)
+
+#define BIT_SHIFT_NETYPE2 0
+#define BIT_MASK_NETYPE2 0x3
+#define BIT_NETYPE2(x) (((x) & BIT_MASK_NETYPE2) << BIT_SHIFT_NETYPE2)
+#define BIT_GET_NETYPE2(x) (((x) >> BIT_SHIFT_NETYPE2) & BIT_MASK_NETYPE2)
+
+/* 2 REG_FWFF (Offset 0x1114) */
+
+#define BIT_SHIFT_PKTNUM_TH_V1 24
+#define BIT_MASK_PKTNUM_TH_V1 0xff
+#define BIT_PKTNUM_TH_V1(x) \
+ (((x) & BIT_MASK_PKTNUM_TH_V1) << BIT_SHIFT_PKTNUM_TH_V1)
+#define BIT_GET_PKTNUM_TH_V1(x) \
+ (((x) >> BIT_SHIFT_PKTNUM_TH_V1) & BIT_MASK_PKTNUM_TH_V1)
+
+/* 2 REG_FWFF (Offset 0x1114) */
+
+#define BIT_SHIFT_TIMER_TH 16
+#define BIT_MASK_TIMER_TH 0xff
+#define BIT_TIMER_TH(x) (((x) & BIT_MASK_TIMER_TH) << BIT_SHIFT_TIMER_TH)
+#define BIT_GET_TIMER_TH(x) (((x) >> BIT_SHIFT_TIMER_TH) & BIT_MASK_TIMER_TH)
+
+/* 2 REG_FWFF (Offset 0x1114) */
+
+#define BIT_SHIFT_RXPKT1ENADDR 0
+#define BIT_MASK_RXPKT1ENADDR 0xffff
+#define BIT_RXPKT1ENADDR(x) \
+ (((x) & BIT_MASK_RXPKT1ENADDR) << BIT_SHIFT_RXPKT1ENADDR)
+#define BIT_GET_RXPKT1ENADDR(x) \
+ (((x) >> BIT_SHIFT_RXPKT1ENADDR) & BIT_MASK_RXPKT1ENADDR)
+
+/* 2 REG_FE2IMR (Offset 0x1120) */
+
+#define BIT__FE4ISR__IND_MSK BIT(29)
+
+/* 2 REG_FE2IMR (Offset 0x1120) */
+
+#define BIT_FS_TXSC_DESC_DONE_INT_EN BIT(28)
+#define BIT_FS_TXSC_BKDONE_INT_EN BIT(27)
+#define BIT_FS_TXSC_BEDONE_INT_EN BIT(26)
+#define BIT_FS_TXSC_VIDONE_INT_EN BIT(25)
+#define BIT_FS_TXSC_VODONE_INT_EN BIT(24)
+
+/* 2 REG_FE2IMR (Offset 0x1120) */
+
+#define BIT_FS_ATIM_MB7_INT_EN BIT(23)
+#define BIT_FS_ATIM_MB6_INT_EN BIT(22)
+#define BIT_FS_ATIM_MB5_INT_EN BIT(21)
+#define BIT_FS_ATIM_MB4_INT_EN BIT(20)
+#define BIT_FS_ATIM_MB3_INT_EN BIT(19)
+#define BIT_FS_ATIM_MB2_INT_EN BIT(18)
+#define BIT_FS_ATIM_MB1_INT_EN BIT(17)
+#define BIT_FS_ATIM_MB0_INT_EN BIT(16)
+#define BIT_FS_TBTT4INT_EN BIT(11)
+#define BIT_FS_TBTT3INT_EN BIT(10)
+#define BIT_FS_TBTT2INT_EN BIT(9)
+#define BIT_FS_TBTT1INT_EN BIT(8)
+#define BIT_FS_TBTT0_MB7INT_EN BIT(7)
+#define BIT_FS_TBTT0_MB6INT_EN BIT(6)
+#define BIT_FS_TBTT0_MB5INT_EN BIT(5)
+#define BIT_FS_TBTT0_MB4INT_EN BIT(4)
+#define BIT_FS_TBTT0_MB3INT_EN BIT(3)
+#define BIT_FS_TBTT0_MB2INT_EN BIT(2)
+#define BIT_FS_TBTT0_MB1INT_EN BIT(1)
+#define BIT_FS_TBTT0_INT_EN BIT(0)
+
+/* 2 REG_FE2ISR (Offset 0x1124) */
+
+#define BIT__FE4ISR__IND_INT BIT(29)
+
+/* 2 REG_FE2ISR (Offset 0x1124) */
+
+#define BIT_FS_TXSC_DESC_DONE_INT BIT(28)
+#define BIT_FS_TXSC_BKDONE_INT BIT(27)
+#define BIT_FS_TXSC_BEDONE_INT BIT(26)
+#define BIT_FS_TXSC_VIDONE_INT BIT(25)
+#define BIT_FS_TXSC_VODONE_INT BIT(24)
+
+/* 2 REG_FE2ISR (Offset 0x1124) */
+
+#define BIT_FS_ATIM_MB7_INT BIT(23)
+#define BIT_FS_ATIM_MB6_INT BIT(22)
+#define BIT_FS_ATIM_MB5_INT BIT(21)
+#define BIT_FS_ATIM_MB4_INT BIT(20)
+#define BIT_FS_ATIM_MB3_INT BIT(19)
+#define BIT_FS_ATIM_MB2_INT BIT(18)
+#define BIT_FS_ATIM_MB1_INT BIT(17)
+#define BIT_FS_ATIM_MB0_INT BIT(16)
+#define BIT_FS_TBTT4INT BIT(11)
+#define BIT_FS_TBTT3INT BIT(10)
+#define BIT_FS_TBTT2INT BIT(9)
+#define BIT_FS_TBTT1INT BIT(8)
+#define BIT_FS_TBTT0_MB7INT BIT(7)
+#define BIT_FS_TBTT0_MB6INT BIT(6)
+#define BIT_FS_TBTT0_MB5INT BIT(5)
+#define BIT_FS_TBTT0_MB4INT BIT(4)
+#define BIT_FS_TBTT0_MB3INT BIT(3)
+#define BIT_FS_TBTT0_MB2INT BIT(2)
+#define BIT_FS_TBTT0_MB1INT BIT(1)
+#define BIT_FS_TBTT0_INT BIT(0)
+
+/* 2 REG_FE3IMR (Offset 0x1128) */
+
+#define BIT_FS_CLI3_MTI_BCNIVLEAR_INT__EN BIT(31)
+
+/* 2 REG_FE3IMR (Offset 0x1128) */
+
+#define BIT_FS_CLI2_MTI_BCNIVLEAR_INT__EN BIT(30)
+
+/* 2 REG_FE3IMR (Offset 0x1128) */
+
+#define BIT_FS_CLI1_MTI_BCNIVLEAR_INT__EN BIT(29)
+
+/* 2 REG_FE3IMR (Offset 0x1128) */
+
+#define BIT_FS_CLI0_MTI_BCNIVLEAR_INT__EN BIT(28)
+
+/* 2 REG_FE3IMR (Offset 0x1128) */
+
+#define BIT_FS_BCNDMA4_INT_EN BIT(27)
+#define BIT_FS_BCNDMA3_INT_EN BIT(26)
+#define BIT_FS_BCNDMA2_INT_EN BIT(25)
+#define BIT_FS_BCNDMA1_INT_EN BIT(24)
+#define BIT_FS_BCNDMA0_MB7_INT_EN BIT(23)
+#define BIT_FS_BCNDMA0_MB6_INT_EN BIT(22)
+#define BIT_FS_BCNDMA0_MB5_INT_EN BIT(21)
+#define BIT_FS_BCNDMA0_MB4_INT_EN BIT(20)
+#define BIT_FS_BCNDMA0_MB3_INT_EN BIT(19)
+#define BIT_FS_BCNDMA0_MB2_INT_EN BIT(18)
+#define BIT_FS_BCNDMA0_MB1_INT_EN BIT(17)
+#define BIT_FS_BCNDMA0_INT_EN BIT(16)
+#define BIT_FS_MTI_BCNIVLEAR_INT__EN BIT(15)
+#define BIT_FS_BCNERLY4_INT_EN BIT(11)
+#define BIT_FS_BCNERLY3_INT_EN BIT(10)
+#define BIT_FS_BCNERLY2_INT_EN BIT(9)
+#define BIT_FS_BCNERLY1_INT_EN BIT(8)
+#define BIT_FS_BCNERLY0_MB7INT_EN BIT(7)
+#define BIT_FS_BCNERLY0_MB6INT_EN BIT(6)
+#define BIT_FS_BCNERLY0_MB5INT_EN BIT(5)
+#define BIT_FS_BCNERLY0_MB4INT_EN BIT(4)
+#define BIT_FS_BCNERLY0_MB3INT_EN BIT(3)
+#define BIT_FS_BCNERLY0_MB2INT_EN BIT(2)
+#define BIT_FS_BCNERLY0_MB1INT_EN BIT(1)
+#define BIT_FS_BCNERLY0_INT_EN BIT(0)
+
+/* 2 REG_FE3ISR (Offset 0x112C) */
+
+#define BIT_FS_CLI3_MTI_BCNIVLEAR_INT BIT(31)
+
+/* 2 REG_FE3ISR (Offset 0x112C) */
+
+#define BIT_FS_CLI2_MTI_BCNIVLEAR_INT BIT(30)
+
+/* 2 REG_FE3ISR (Offset 0x112C) */
+
+#define BIT_FS_CLI1_MTI_BCNIVLEAR_INT BIT(29)
+
+/* 2 REG_FE3ISR (Offset 0x112C) */
+
+#define BIT_FS_CLI0_MTI_BCNIVLEAR_INT BIT(28)
+
+/* 2 REG_FE3ISR (Offset 0x112C) */
+
+#define BIT_FS_BCNDMA4_INT BIT(27)
+#define BIT_FS_BCNDMA3_INT BIT(26)
+#define BIT_FS_BCNDMA2_INT BIT(25)
+#define BIT_FS_BCNDMA1_INT BIT(24)
+#define BIT_FS_BCNDMA0_MB7_INT BIT(23)
+#define BIT_FS_BCNDMA0_MB6_INT BIT(22)
+#define BIT_FS_BCNDMA0_MB5_INT BIT(21)
+#define BIT_FS_BCNDMA0_MB4_INT BIT(20)
+#define BIT_FS_BCNDMA0_MB3_INT BIT(19)
+#define BIT_FS_BCNDMA0_MB2_INT BIT(18)
+#define BIT_FS_BCNDMA0_MB1_INT BIT(17)
+#define BIT_FS_BCNDMA0_INT BIT(16)
+#define BIT_FS_MTI_BCNIVLEAR_INT BIT(15)
+#define BIT_FS_BCNERLY4_INT BIT(11)
+#define BIT_FS_BCNERLY3_INT BIT(10)
+#define BIT_FS_BCNERLY2_INT BIT(9)
+#define BIT_FS_BCNERLY1_INT BIT(8)
+#define BIT_FS_BCNERLY0_MB7INT BIT(7)
+#define BIT_FS_BCNERLY0_MB6INT BIT(6)
+#define BIT_FS_BCNERLY0_MB5INT BIT(5)
+#define BIT_FS_BCNERLY0_MB4INT BIT(4)
+#define BIT_FS_BCNERLY0_MB3INT BIT(3)
+#define BIT_FS_BCNERLY0_MB2INT BIT(2)
+#define BIT_FS_BCNERLY0_MB1INT BIT(1)
+#define BIT_FS_BCNERLY0_INT BIT(0)
+
+/* 2 REG_FE4IMR (Offset 0x1130) */
+
+#define BIT_FS_CLI3_TXPKTIN_INT_EN BIT(19)
+
+/* 2 REG_FE4IMR (Offset 0x1130) */
+
+#define BIT_FS_CLI2_TXPKTIN_INT_EN BIT(18)
+
+/* 2 REG_FE4IMR (Offset 0x1130) */
+
+#define BIT_FS_CLI1_TXPKTIN_INT_EN BIT(17)
+
+/* 2 REG_FE4IMR (Offset 0x1130) */
+
+#define BIT_FS_CLI0_TXPKTIN_INT_EN BIT(16)
+
+/* 2 REG_FE4IMR (Offset 0x1130) */
+
+#define BIT_FS_CLI3_RX_UMD0_INT_EN BIT(15)
+
+/* 2 REG_FE4IMR (Offset 0x1130) */
+
+#define BIT_FS_CLI3_RX_UMD1_INT_EN BIT(14)
+
+/* 2 REG_FE4IMR (Offset 0x1130) */
+
+#define BIT_FS_CLI3_RX_BMD0_INT_EN BIT(13)
+
+/* 2 REG_FE4IMR (Offset 0x1130) */
+
+#define BIT_FS_CLI3_RX_BMD1_INT_EN BIT(12)
+
+/* 2 REG_FE4IMR (Offset 0x1130) */
+
+#define BIT_FS_CLI2_RX_UMD0_INT_EN BIT(11)
+
+/* 2 REG_FE4IMR (Offset 0x1130) */
+
+#define BIT_FS_CLI2_RX_UMD1_INT_EN BIT(10)
+
+/* 2 REG_FE4IMR (Offset 0x1130) */
+
+#define BIT_FS_CLI2_RX_BMD0_INT_EN BIT(9)
+
+/* 2 REG_FE4IMR (Offset 0x1130) */
+
+#define BIT_FS_CLI2_RX_BMD1_INT_EN BIT(8)
+
+/* 2 REG_FE4IMR (Offset 0x1130) */
+
+#define BIT_FS_CLI1_RX_UMD0_INT_EN BIT(7)
+
+/* 2 REG_FE4IMR (Offset 0x1130) */
+
+#define BIT_FS_CLI1_RX_UMD1_INT_EN BIT(6)
+
+/* 2 REG_FE4IMR (Offset 0x1130) */
+
+#define BIT_FS_CLI1_RX_BMD0_INT_EN BIT(5)
+
+/* 2 REG_FE4IMR (Offset 0x1130) */
+
+#define BIT_FS_CLI1_RX_BMD1_INT_EN BIT(4)
+
+/* 2 REG_FE4IMR (Offset 0x1130) */
+
+#define BIT_FS_CLI0_RX_UMD0_INT_EN BIT(3)
+
+/* 2 REG_FE4IMR (Offset 0x1130) */
+
+#define BIT_FS_CLI0_RX_UMD1_INT_EN BIT(2)
+
+/* 2 REG_FE4IMR (Offset 0x1130) */
+
+#define BIT_FS_CLI0_RX_BMD0_INT_EN BIT(1)
+
+/* 2 REG_FE4IMR (Offset 0x1130) */
+
+#define BIT_FS_CLI0_RX_BMD1_INT_EN BIT(0)
+
+/* 2 REG_FE4ISR (Offset 0x1134) */
+
+#define BIT_FS_CLI3_TXPKTIN_INT BIT(19)
+
+/* 2 REG_FE4ISR (Offset 0x1134) */
+
+#define BIT_FS_CLI2_TXPKTIN_INT BIT(18)
+
+/* 2 REG_FE4ISR (Offset 0x1134) */
+
+#define BIT_FS_CLI1_TXPKTIN_INT BIT(17)
+
+/* 2 REG_FE4ISR (Offset 0x1134) */
+
+#define BIT_FS_CLI0_TXPKTIN_INT BIT(16)
+
+/* 2 REG_FE4ISR (Offset 0x1134) */
+
+#define BIT_FS_CLI3_RX_UMD0_INT BIT(15)
+
+/* 2 REG_FE4ISR (Offset 0x1134) */
+
+#define BIT_FS_CLI3_RX_UMD1_INT BIT(14)
+
+/* 2 REG_FE4ISR (Offset 0x1134) */
+
+#define BIT_FS_CLI3_RX_BMD0_INT BIT(13)
+
+/* 2 REG_FE4ISR (Offset 0x1134) */
+
+#define BIT_FS_CLI3_RX_BMD1_INT BIT(12)
+
+/* 2 REG_FE4ISR (Offset 0x1134) */
+
+#define BIT_FS_CLI2_RX_UMD0_INT BIT(11)
+
+/* 2 REG_FE4ISR (Offset 0x1134) */
+
+#define BIT_FS_CLI2_RX_UMD1_INT BIT(10)
+
+/* 2 REG_FE4ISR (Offset 0x1134) */
+
+#define BIT_FS_CLI2_RX_BMD0_INT BIT(9)
+
+/* 2 REG_FE4ISR (Offset 0x1134) */
+
+#define BIT_FS_CLI2_RX_BMD1_INT BIT(8)
+
+/* 2 REG_FE4ISR (Offset 0x1134) */
+
+#define BIT_FS_CLI1_RX_UMD0_INT BIT(7)
+
+/* 2 REG_FE4ISR (Offset 0x1134) */
+
+#define BIT_FS_CLI1_RX_UMD1_INT BIT(6)
+
+/* 2 REG_FE4ISR (Offset 0x1134) */
+
+#define BIT_FS_CLI1_RX_BMD0_INT BIT(5)
+
+/* 2 REG_FE4ISR (Offset 0x1134) */
+
+#define BIT_FS_CLI1_RX_BMD1_INT BIT(4)
+
+/* 2 REG_FE4ISR (Offset 0x1134) */
+
+#define BIT_FS_CLI0_RX_UMD0_INT BIT(3)
+
+/* 2 REG_FE4ISR (Offset 0x1134) */
+
+#define BIT_FS_CLI0_RX_UMD1_INT BIT(2)
+
+/* 2 REG_FE4ISR (Offset 0x1134) */
+
+#define BIT_FS_CLI0_RX_BMD0_INT BIT(1)
+
+/* 2 REG_FE4ISR (Offset 0x1134) */
+
+#define BIT_FS_CLI0_RX_BMD1_INT BIT(0)
+
+/* 2 REG_FT1IMR (Offset 0x1138) */
+
+#define BIT__FT2ISR__IND_MSK BIT(30)
+#define BIT_FTM_PTT_INT_EN BIT(29)
+#define BIT_RXFTMREQ_INT_EN BIT(28)
+#define BIT_RXFTM_INT_EN BIT(27)
+#define BIT_TXFTM_INT_EN BIT(26)
+
+/* 2 REG_FT1IMR (Offset 0x1138) */
+
+#define BIT_FS_H2C_CMD_OK_INT_EN BIT(25)
+#define BIT_FS_H2C_CMD_FULL_INT_EN BIT(24)
+
+/* 2 REG_FT1IMR (Offset 0x1138) */
+
+#define BIT_FS_MACID_PWRCHANGE5_INT_EN BIT(23)
+#define BIT_FS_MACID_PWRCHANGE4_INT_EN BIT(22)
+#define BIT_FS_MACID_PWRCHANGE3_INT_EN BIT(21)
+#define BIT_FS_MACID_PWRCHANGE2_INT_EN BIT(20)
+#define BIT_FS_MACID_PWRCHANGE1_INT_EN BIT(19)
+#define BIT_FS_MACID_PWRCHANGE0_INT_EN BIT(18)
+#define BIT_FS_CTWEND2_INT_EN BIT(17)
+#define BIT_FS_CTWEND1_INT_EN BIT(16)
+#define BIT_FS_CTWEND0_INT_EN BIT(15)
+#define BIT_FS_TX_NULL1_INT_EN BIT(14)
+#define BIT_FS_TX_NULL0_INT_EN BIT(13)
+#define BIT_FS_TSF_BIT32_TOGGLE_EN BIT(12)
+#define BIT_FS_P2P_RFON2_INT_EN BIT(11)
+#define BIT_FS_P2P_RFOFF2_INT_EN BIT(10)
+#define BIT_FS_P2P_RFON1_INT_EN BIT(9)
+#define BIT_FS_P2P_RFOFF1_INT_EN BIT(8)
+#define BIT_FS_P2P_RFON0_INT_EN BIT(7)
+#define BIT_FS_P2P_RFOFF0_INT_EN BIT(6)
+#define BIT_FS_RX_UAPSDMD1_EN BIT(5)
+#define BIT_FS_RX_UAPSDMD0_EN BIT(4)
+#define BIT_FS_TRIGGER_PKT_EN BIT(3)
+#define BIT_FS_EOSP_INT_EN BIT(2)
+#define BIT_FS_RPWM2_INT_EN BIT(1)
+#define BIT_FS_RPWM_INT_EN BIT(0)
+
+/* 2 REG_FT1ISR (Offset 0x113C) */
+
+#define BIT__FT2ISR__IND_INT BIT(30)
+#define BIT_FTM_PTT_INT BIT(29)
+#define BIT_RXFTMREQ_INT BIT(28)
+#define BIT_RXFTM_INT BIT(27)
+#define BIT_TXFTM_INT BIT(26)
+
+/* 2 REG_FT1ISR (Offset 0x113C) */
+
+#define BIT_FS_H2C_CMD_OK_INT BIT(25)
+#define BIT_FS_H2C_CMD_FULL_INT BIT(24)
+
+/* 2 REG_FT1ISR (Offset 0x113C) */
+
+#define BIT_FS_MACID_PWRCHANGE5_INT BIT(23)
+#define BIT_FS_MACID_PWRCHANGE4_INT BIT(22)
+#define BIT_FS_MACID_PWRCHANGE3_INT BIT(21)
+#define BIT_FS_MACID_PWRCHANGE2_INT BIT(20)
+#define BIT_FS_MACID_PWRCHANGE1_INT BIT(19)
+#define BIT_FS_MACID_PWRCHANGE0_INT BIT(18)
+#define BIT_FS_CTWEND2_INT BIT(17)
+#define BIT_FS_CTWEND1_INT BIT(16)
+#define BIT_FS_CTWEND0_INT BIT(15)
+#define BIT_FS_TX_NULL1_INT BIT(14)
+#define BIT_FS_TX_NULL0_INT BIT(13)
+#define BIT_FS_TSF_BIT32_TOGGLE_INT BIT(12)
+#define BIT_FS_P2P_RFON2_INT BIT(11)
+#define BIT_FS_P2P_RFOFF2_INT BIT(10)
+#define BIT_FS_P2P_RFON1_INT BIT(9)
+#define BIT_FS_P2P_RFOFF1_INT BIT(8)
+#define BIT_FS_P2P_RFON0_INT BIT(7)
+#define BIT_FS_P2P_RFOFF0_INT BIT(6)
+#define BIT_FS_RX_UAPSDMD1_INT BIT(5)
+#define BIT_FS_RX_UAPSDMD0_INT BIT(4)
+#define BIT_FS_TRIGGER_PKT_INT BIT(3)
+#define BIT_FS_EOSP_INT BIT(2)
+#define BIT_FS_RPWM2_INT BIT(1)
+#define BIT_FS_RPWM_INT BIT(0)
+
+/* 2 REG_SPWR0 (Offset 0x1140) */
+
+#define BIT_SHIFT_MID_31TO0 0
+#define BIT_MASK_MID_31TO0 0xffffffffL
+#define BIT_MID_31TO0(x) (((x) & BIT_MASK_MID_31TO0) << BIT_SHIFT_MID_31TO0)
+#define BIT_GET_MID_31TO0(x) (((x) >> BIT_SHIFT_MID_31TO0) & BIT_MASK_MID_31TO0)
+
+/* 2 REG_SPWR1 (Offset 0x1144) */
+
+#define BIT_SHIFT_MID_63TO32 0
+#define BIT_MASK_MID_63TO32 0xffffffffL
+#define BIT_MID_63TO32(x) (((x) & BIT_MASK_MID_63TO32) << BIT_SHIFT_MID_63TO32)
+#define BIT_GET_MID_63TO32(x) \
+ (((x) >> BIT_SHIFT_MID_63TO32) & BIT_MASK_MID_63TO32)
+
+/* 2 REG_SPWR2 (Offset 0x1148) */
+
+#define BIT_SHIFT_MID_95O64 0
+#define BIT_MASK_MID_95O64 0xffffffffL
+#define BIT_MID_95O64(x) (((x) & BIT_MASK_MID_95O64) << BIT_SHIFT_MID_95O64)
+#define BIT_GET_MID_95O64(x) (((x) >> BIT_SHIFT_MID_95O64) & BIT_MASK_MID_95O64)
+
+/* 2 REG_SPWR3 (Offset 0x114C) */
+
+#define BIT_SHIFT_MID_127TO96 0
+#define BIT_MASK_MID_127TO96 0xffffffffL
+#define BIT_MID_127TO96(x) \
+ (((x) & BIT_MASK_MID_127TO96) << BIT_SHIFT_MID_127TO96)
+#define BIT_GET_MID_127TO96(x) \
+ (((x) >> BIT_SHIFT_MID_127TO96) & BIT_MASK_MID_127TO96)
+
+/* 2 REG_POWSEQ (Offset 0x1150) */
+
+#define BIT_SHIFT_SEQNUM_MID 16
+#define BIT_MASK_SEQNUM_MID 0xffff
+#define BIT_SEQNUM_MID(x) (((x) & BIT_MASK_SEQNUM_MID) << BIT_SHIFT_SEQNUM_MID)
+#define BIT_GET_SEQNUM_MID(x) \
+ (((x) >> BIT_SHIFT_SEQNUM_MID) & BIT_MASK_SEQNUM_MID)
+
+#define BIT_SHIFT_REF_MID 0
+#define BIT_MASK_REF_MID 0x7f
+#define BIT_REF_MID(x) (((x) & BIT_MASK_REF_MID) << BIT_SHIFT_REF_MID)
+#define BIT_GET_REF_MID(x) (((x) >> BIT_SHIFT_REF_MID) & BIT_MASK_REF_MID)
+
+/* 2 REG_TC7_CTRL_V1 (Offset 0x1158) */
+
+#define BIT_TC7INT_EN BIT(26)
+#define BIT_TC7MODE BIT(25)
+#define BIT_TC7EN BIT(24)
+
+#define BIT_SHIFT_TC7DATA 0
+#define BIT_MASK_TC7DATA 0xffffff
+#define BIT_TC7DATA(x) (((x) & BIT_MASK_TC7DATA) << BIT_SHIFT_TC7DATA)
+#define BIT_GET_TC7DATA(x) (((x) >> BIT_SHIFT_TC7DATA) & BIT_MASK_TC7DATA)
+
+/* 2 REG_TC8_CTRL_V1 (Offset 0x115C) */
+
+#define BIT_TC8INT_EN BIT(26)
+#define BIT_TC8MODE BIT(25)
+#define BIT_TC8EN BIT(24)
+
+#define BIT_SHIFT_TC8DATA 0
+#define BIT_MASK_TC8DATA 0xffffff
+#define BIT_TC8DATA(x) (((x) & BIT_MASK_TC8DATA) << BIT_SHIFT_TC8DATA)
+#define BIT_GET_TC8DATA(x) (((x) >> BIT_SHIFT_TC8DATA) & BIT_MASK_TC8DATA)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_CLI3_RX_UAPSDMD1_EN BIT(31)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_CLI3_RX_UAPSDMD0_EN BIT(30)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_CLI3_TRIGGER_PKT_EN BIT(29)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_CLI3_EOSP_INT_EN BIT(28)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_CLI2_RX_UAPSDMD1_EN BIT(27)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_CLI2_RX_UAPSDMD0_EN BIT(26)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_CLI2_TRIGGER_PKT_EN BIT(25)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_CLI2_EOSP_INT_EN BIT(24)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_CLI1_RX_UAPSDMD1_EN BIT(23)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_CLI1_RX_UAPSDMD0_EN BIT(22)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_CLI1_TRIGGER_PKT_EN BIT(21)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_CLI1_EOSP_INT_EN BIT(20)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_CLI0_RX_UAPSDMD1_EN BIT(19)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_CLI0_RX_UAPSDMD0_EN BIT(18)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_CLI0_TRIGGER_PKT_EN BIT(17)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_CLI0_EOSP_INT_EN BIT(16)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_TSF_BIT32_TOGGLE_P2P2_EN BIT(9)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_TSF_BIT32_TOGGLE_P2P1_EN BIT(8)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_CLI3_TX_NULL1_INT_EN BIT(7)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_CLI3_TX_NULL0_INT_EN BIT(6)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_CLI2_TX_NULL1_INT_EN BIT(5)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_CLI2_TX_NULL0_INT_EN BIT(4)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_CLI1_TX_NULL1_INT_EN BIT(3)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_CLI1_TX_NULL0_INT_EN BIT(2)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_CLI0_TX_NULL1_INT_EN BIT(1)
+
+/* 2 REG_FT2IMR (Offset 0x11E0) */
+
+#define BIT_FS_CLI0_TX_NULL0_INT_EN BIT(0)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_CLI3_RX_UAPSDMD1_INT BIT(31)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_CLI3_RX_UAPSDMD0_INT BIT(30)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_CLI3_TRIGGER_PKT_INT BIT(29)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_CLI3_EOSP_INT BIT(28)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_CLI2_RX_UAPSDMD1_INT BIT(27)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_CLI2_RX_UAPSDMD0_INT BIT(26)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_CLI2_TRIGGER_PKT_INT BIT(25)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_CLI2_EOSP_INT BIT(24)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_CLI1_RX_UAPSDMD1_INT BIT(23)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_CLI1_RX_UAPSDMD0_INT BIT(22)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_CLI1_TRIGGER_PKT_INT BIT(21)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_CLI1_EOSP_INT BIT(20)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_CLI0_RX_UAPSDMD1_INT BIT(19)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_CLI0_RX_UAPSDMD0_INT BIT(18)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_CLI0_TRIGGER_PKT_INT BIT(17)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_CLI0_EOSP_INT BIT(16)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_TSF_BIT32_TOGGLE_P2P2_INT BIT(9)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_TSF_BIT32_TOGGLE_P2P1_INT BIT(8)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_CLI3_TX_NULL1_INT BIT(7)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_CLI3_TX_NULL0_INT BIT(6)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_CLI2_TX_NULL1_INT BIT(5)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_CLI2_TX_NULL0_INT BIT(4)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_CLI1_TX_NULL1_INT BIT(3)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_CLI1_TX_NULL0_INT BIT(2)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_CLI0_TX_NULL1_INT BIT(1)
+
+/* 2 REG_FT2ISR (Offset 0x11E4) */
+
+#define BIT_FS_CLI0_TX_NULL0_INT BIT(0)
+
+/* 2 REG_MSG2 (Offset 0x11F0) */
+
+#define BIT_SHIFT_FW_MSG2 0
+#define BIT_MASK_FW_MSG2 0xffffffffL
+#define BIT_FW_MSG2(x) (((x) & BIT_MASK_FW_MSG2) << BIT_SHIFT_FW_MSG2)
+#define BIT_GET_FW_MSG2(x) (((x) >> BIT_SHIFT_FW_MSG2) & BIT_MASK_FW_MSG2)
+
+/* 2 REG_MSG3 (Offset 0x11F4) */
+
+#define BIT_SHIFT_FW_MSG3 0
+#define BIT_MASK_FW_MSG3 0xffffffffL
+#define BIT_FW_MSG3(x) (((x) & BIT_MASK_FW_MSG3) << BIT_SHIFT_FW_MSG3)
+#define BIT_GET_FW_MSG3(x) (((x) >> BIT_SHIFT_FW_MSG3) & BIT_MASK_FW_MSG3)
+
+/* 2 REG_MSG4 (Offset 0x11F8) */
+
+#define BIT_SHIFT_FW_MSG4 0
+#define BIT_MASK_FW_MSG4 0xffffffffL
+#define BIT_FW_MSG4(x) (((x) & BIT_MASK_FW_MSG4) << BIT_SHIFT_FW_MSG4)
+#define BIT_GET_FW_MSG4(x) (((x) >> BIT_SHIFT_FW_MSG4) & BIT_MASK_FW_MSG4)
+
+/* 2 REG_MSG5 (Offset 0x11FC) */
+
+#define BIT_SHIFT_FW_MSG5 0
+#define BIT_MASK_FW_MSG5 0xffffffffL
+#define BIT_FW_MSG5(x) (((x) & BIT_MASK_FW_MSG5) << BIT_SHIFT_FW_MSG5)
+#define BIT_GET_FW_MSG5(x) (((x) >> BIT_SHIFT_FW_MSG5) & BIT_MASK_FW_MSG5)
+
+/* 2 REG_DDMA_CH0SA (Offset 0x1200) */
+
+#define BIT_SHIFT_DDMACH0_SA 0
+#define BIT_MASK_DDMACH0_SA 0xffffffffL
+#define BIT_DDMACH0_SA(x) (((x) & BIT_MASK_DDMACH0_SA) << BIT_SHIFT_DDMACH0_SA)
+#define BIT_GET_DDMACH0_SA(x) \
+ (((x) >> BIT_SHIFT_DDMACH0_SA) & BIT_MASK_DDMACH0_SA)
+
+/* 2 REG_DDMA_CH0DA (Offset 0x1204) */
+
+#define BIT_SHIFT_DDMACH0_DA 0
+#define BIT_MASK_DDMACH0_DA 0xffffffffL
+#define BIT_DDMACH0_DA(x) (((x) & BIT_MASK_DDMACH0_DA) << BIT_SHIFT_DDMACH0_DA)
+#define BIT_GET_DDMACH0_DA(x) \
+ (((x) >> BIT_SHIFT_DDMACH0_DA) & BIT_MASK_DDMACH0_DA)
+
+/* 2 REG_DDMA_CH0CTRL (Offset 0x1208) */
+
+#define BIT_DDMACH0_OWN BIT(31)
+#define BIT_DDMACH0_CHKSUM_EN BIT(29)
+#define BIT_DDMACH0_DA_W_DISABLE BIT(28)
+#define BIT_DDMACH0_CHKSUM_STS BIT(27)
+#define BIT_DDMACH0_DDMA_MODE BIT(26)
+#define BIT_DDMACH0_RESET_CHKSUM_STS BIT(25)
+#define BIT_DDMACH0_CHKSUM_CONT BIT(24)
+
+#define BIT_SHIFT_DDMACH0_DLEN 0
+#define BIT_MASK_DDMACH0_DLEN 0x3ffff
+#define BIT_DDMACH0_DLEN(x) \
+ (((x) & BIT_MASK_DDMACH0_DLEN) << BIT_SHIFT_DDMACH0_DLEN)
+#define BIT_GET_DDMACH0_DLEN(x) \
+ (((x) >> BIT_SHIFT_DDMACH0_DLEN) & BIT_MASK_DDMACH0_DLEN)
+
+/* 2 REG_DDMA_CH1SA (Offset 0x1210) */
+
+#define BIT_SHIFT_DDMACH1_SA 0
+#define BIT_MASK_DDMACH1_SA 0xffffffffL
+#define BIT_DDMACH1_SA(x) (((x) & BIT_MASK_DDMACH1_SA) << BIT_SHIFT_DDMACH1_SA)
+#define BIT_GET_DDMACH1_SA(x) \
+ (((x) >> BIT_SHIFT_DDMACH1_SA) & BIT_MASK_DDMACH1_SA)
+
+/* 2 REG_DDMA_CH1DA (Offset 0x1214) */
+
+#define BIT_SHIFT_DDMACH1_DA 0
+#define BIT_MASK_DDMACH1_DA 0xffffffffL
+#define BIT_DDMACH1_DA(x) (((x) & BIT_MASK_DDMACH1_DA) << BIT_SHIFT_DDMACH1_DA)
+#define BIT_GET_DDMACH1_DA(x) \
+ (((x) >> BIT_SHIFT_DDMACH1_DA) & BIT_MASK_DDMACH1_DA)
+
+/* 2 REG_DDMA_CH1CTRL (Offset 0x1218) */
+
+#define BIT_DDMACH1_OWN BIT(31)
+#define BIT_DDMACH1_CHKSUM_EN BIT(29)
+#define BIT_DDMACH1_DA_W_DISABLE BIT(28)
+#define BIT_DDMACH1_CHKSUM_STS BIT(27)
+#define BIT_DDMACH1_DDMA_MODE BIT(26)
+#define BIT_DDMACH1_RESET_CHKSUM_STS BIT(25)
+#define BIT_DDMACH1_CHKSUM_CONT BIT(24)
+
+#define BIT_SHIFT_DDMACH1_DLEN 0
+#define BIT_MASK_DDMACH1_DLEN 0x3ffff
+#define BIT_DDMACH1_DLEN(x) \
+ (((x) & BIT_MASK_DDMACH1_DLEN) << BIT_SHIFT_DDMACH1_DLEN)
+#define BIT_GET_DDMACH1_DLEN(x) \
+ (((x) >> BIT_SHIFT_DDMACH1_DLEN) & BIT_MASK_DDMACH1_DLEN)
+
+/* 2 REG_DDMA_CH2SA (Offset 0x1220) */
+
+#define BIT_SHIFT_DDMACH2_SA 0
+#define BIT_MASK_DDMACH2_SA 0xffffffffL
+#define BIT_DDMACH2_SA(x) (((x) & BIT_MASK_DDMACH2_SA) << BIT_SHIFT_DDMACH2_SA)
+#define BIT_GET_DDMACH2_SA(x) \
+ (((x) >> BIT_SHIFT_DDMACH2_SA) & BIT_MASK_DDMACH2_SA)
+
+/* 2 REG_DDMA_CH2DA (Offset 0x1224) */
+
+#define BIT_SHIFT_DDMACH2_DA 0
+#define BIT_MASK_DDMACH2_DA 0xffffffffL
+#define BIT_DDMACH2_DA(x) (((x) & BIT_MASK_DDMACH2_DA) << BIT_SHIFT_DDMACH2_DA)
+#define BIT_GET_DDMACH2_DA(x) \
+ (((x) >> BIT_SHIFT_DDMACH2_DA) & BIT_MASK_DDMACH2_DA)
+
+/* 2 REG_DDMA_CH2CTRL (Offset 0x1228) */
+
+#define BIT_DDMACH2_OWN BIT(31)
+#define BIT_DDMACH2_CHKSUM_EN BIT(29)
+#define BIT_DDMACH2_DA_W_DISABLE BIT(28)
+#define BIT_DDMACH2_CHKSUM_STS BIT(27)
+#define BIT_DDMACH2_DDMA_MODE BIT(26)
+#define BIT_DDMACH2_RESET_CHKSUM_STS BIT(25)
+#define BIT_DDMACH2_CHKSUM_CONT BIT(24)
+
+#define BIT_SHIFT_DDMACH2_DLEN 0
+#define BIT_MASK_DDMACH2_DLEN 0x3ffff
+#define BIT_DDMACH2_DLEN(x) \
+ (((x) & BIT_MASK_DDMACH2_DLEN) << BIT_SHIFT_DDMACH2_DLEN)
+#define BIT_GET_DDMACH2_DLEN(x) \
+ (((x) >> BIT_SHIFT_DDMACH2_DLEN) & BIT_MASK_DDMACH2_DLEN)
+
+/* 2 REG_DDMA_CH3SA (Offset 0x1230) */
+
+#define BIT_SHIFT_DDMACH3_SA 0
+#define BIT_MASK_DDMACH3_SA 0xffffffffL
+#define BIT_DDMACH3_SA(x) (((x) & BIT_MASK_DDMACH3_SA) << BIT_SHIFT_DDMACH3_SA)
+#define BIT_GET_DDMACH3_SA(x) \
+ (((x) >> BIT_SHIFT_DDMACH3_SA) & BIT_MASK_DDMACH3_SA)
+
+/* 2 REG_DDMA_CH3DA (Offset 0x1234) */
+
+#define BIT_SHIFT_DDMACH3_DA 0
+#define BIT_MASK_DDMACH3_DA 0xffffffffL
+#define BIT_DDMACH3_DA(x) (((x) & BIT_MASK_DDMACH3_DA) << BIT_SHIFT_DDMACH3_DA)
+#define BIT_GET_DDMACH3_DA(x) \
+ (((x) >> BIT_SHIFT_DDMACH3_DA) & BIT_MASK_DDMACH3_DA)
+
+/* 2 REG_DDMA_CH3CTRL (Offset 0x1238) */
+
+#define BIT_DDMACH3_OWN BIT(31)
+#define BIT_DDMACH3_CHKSUM_EN BIT(29)
+#define BIT_DDMACH3_DA_W_DISABLE BIT(28)
+#define BIT_DDMACH3_CHKSUM_STS BIT(27)
+#define BIT_DDMACH3_DDMA_MODE BIT(26)
+#define BIT_DDMACH3_RESET_CHKSUM_STS BIT(25)
+#define BIT_DDMACH3_CHKSUM_CONT BIT(24)
+
+#define BIT_SHIFT_DDMACH3_DLEN 0
+#define BIT_MASK_DDMACH3_DLEN 0x3ffff
+#define BIT_DDMACH3_DLEN(x) \
+ (((x) & BIT_MASK_DDMACH3_DLEN) << BIT_SHIFT_DDMACH3_DLEN)
+#define BIT_GET_DDMACH3_DLEN(x) \
+ (((x) >> BIT_SHIFT_DDMACH3_DLEN) & BIT_MASK_DDMACH3_DLEN)
+
+/* 2 REG_DDMA_CH4SA (Offset 0x1240) */
+
+#define BIT_SHIFT_DDMACH4_SA 0
+#define BIT_MASK_DDMACH4_SA 0xffffffffL
+#define BIT_DDMACH4_SA(x) (((x) & BIT_MASK_DDMACH4_SA) << BIT_SHIFT_DDMACH4_SA)
+#define BIT_GET_DDMACH4_SA(x) \
+ (((x) >> BIT_SHIFT_DDMACH4_SA) & BIT_MASK_DDMACH4_SA)
+
+/* 2 REG_DDMA_CH4DA (Offset 0x1244) */
+
+#define BIT_SHIFT_DDMACH4_DA 0
+#define BIT_MASK_DDMACH4_DA 0xffffffffL
+#define BIT_DDMACH4_DA(x) (((x) & BIT_MASK_DDMACH4_DA) << BIT_SHIFT_DDMACH4_DA)
+#define BIT_GET_DDMACH4_DA(x) \
+ (((x) >> BIT_SHIFT_DDMACH4_DA) & BIT_MASK_DDMACH4_DA)
+
+/* 2 REG_DDMA_CH4CTRL (Offset 0x1248) */
+
+#define BIT_DDMACH4_OWN BIT(31)
+#define BIT_DDMACH4_CHKSUM_EN BIT(29)
+#define BIT_DDMACH4_DA_W_DISABLE BIT(28)
+#define BIT_DDMACH4_CHKSUM_STS BIT(27)
+#define BIT_DDMACH4_DDMA_MODE BIT(26)
+#define BIT_DDMACH4_RESET_CHKSUM_STS BIT(25)
+#define BIT_DDMACH4_CHKSUM_CONT BIT(24)
+
+#define BIT_SHIFT_DDMACH4_DLEN 0
+#define BIT_MASK_DDMACH4_DLEN 0x3ffff
+#define BIT_DDMACH4_DLEN(x) \
+ (((x) & BIT_MASK_DDMACH4_DLEN) << BIT_SHIFT_DDMACH4_DLEN)
+#define BIT_GET_DDMACH4_DLEN(x) \
+ (((x) >> BIT_SHIFT_DDMACH4_DLEN) & BIT_MASK_DDMACH4_DLEN)
+
+/* 2 REG_DDMA_CH5SA (Offset 0x1250) */
+
+#define BIT_SHIFT_DDMACH5_SA 0
+#define BIT_MASK_DDMACH5_SA 0xffffffffL
+#define BIT_DDMACH5_SA(x) (((x) & BIT_MASK_DDMACH5_SA) << BIT_SHIFT_DDMACH5_SA)
+#define BIT_GET_DDMACH5_SA(x) \
+ (((x) >> BIT_SHIFT_DDMACH5_SA) & BIT_MASK_DDMACH5_SA)
+
+/* 2 REG_DDMA_CH5DA (Offset 0x1254) */
+
+#define BIT_DDMACH5_OWN BIT(31)
+#define BIT_DDMACH5_CHKSUM_EN BIT(29)
+#define BIT_DDMACH5_DA_W_DISABLE BIT(28)
+#define BIT_DDMACH5_CHKSUM_STS BIT(27)
+#define BIT_DDMACH5_DDMA_MODE BIT(26)
+#define BIT_DDMACH5_RESET_CHKSUM_STS BIT(25)
+#define BIT_DDMACH5_CHKSUM_CONT BIT(24)
+
+#define BIT_SHIFT_DDMACH5_DA 0
+#define BIT_MASK_DDMACH5_DA 0xffffffffL
+#define BIT_DDMACH5_DA(x) (((x) & BIT_MASK_DDMACH5_DA) << BIT_SHIFT_DDMACH5_DA)
+#define BIT_GET_DDMACH5_DA(x) \
+ (((x) >> BIT_SHIFT_DDMACH5_DA) & BIT_MASK_DDMACH5_DA)
+
+#define BIT_SHIFT_DDMACH5_DLEN 0
+#define BIT_MASK_DDMACH5_DLEN 0x3ffff
+#define BIT_DDMACH5_DLEN(x) \
+ (((x) & BIT_MASK_DDMACH5_DLEN) << BIT_SHIFT_DDMACH5_DLEN)
+#define BIT_GET_DDMACH5_DLEN(x) \
+ (((x) >> BIT_SHIFT_DDMACH5_DLEN) & BIT_MASK_DDMACH5_DLEN)
+
+/* 2 REG_DDMA_INT_MSK (Offset 0x12E0) */
+
+#define BIT_DDMACH5_MSK BIT(5)
+#define BIT_DDMACH4_MSK BIT(4)
+#define BIT_DDMACH3_MSK BIT(3)
+#define BIT_DDMACH2_MSK BIT(2)
+#define BIT_DDMACH1_MSK BIT(1)
+#define BIT_DDMACH0_MSK BIT(0)
+
+/* 2 REG_DDMA_CHSTATUS (Offset 0x12E8) */
+
+#define BIT_DDMACH5_BUSY BIT(5)
+#define BIT_DDMACH4_BUSY BIT(4)
+#define BIT_DDMACH3_BUSY BIT(3)
+#define BIT_DDMACH2_BUSY BIT(2)
+#define BIT_DDMACH1_BUSY BIT(1)
+#define BIT_DDMACH0_BUSY BIT(0)
+
+/* 2 REG_DDMA_CHKSUM (Offset 0x12F0) */
+
+#define BIT_SHIFT_IDDMA0_CHKSUM 0
+#define BIT_MASK_IDDMA0_CHKSUM 0xffff
+#define BIT_IDDMA0_CHKSUM(x) \
+ (((x) & BIT_MASK_IDDMA0_CHKSUM) << BIT_SHIFT_IDDMA0_CHKSUM)
+#define BIT_GET_IDDMA0_CHKSUM(x) \
+ (((x) >> BIT_SHIFT_IDDMA0_CHKSUM) & BIT_MASK_IDDMA0_CHKSUM)
+
+/* 2 REG_DDMA_MONITOR (Offset 0x12FC) */
+
+#define BIT_IDDMA0_PERMU_UNDERFLOW BIT(14)
+#define BIT_IDDMA0_FIFO_UNDERFLOW BIT(13)
+#define BIT_IDDMA0_FIFO_OVERFLOW BIT(12)
+#define BIT_ECRC_EN_V1 BIT(7)
+#define BIT_MDIO_RFLAG_V1 BIT(6)
+#define BIT_CH5_ERR BIT(5)
+#define BIT_MDIO_WFLAG_V1 BIT(5)
+#define BIT_CH4_ERR BIT(4)
+#define BIT_CH3_ERR BIT(3)
+#define BIT_CH2_ERR BIT(2)
+#define BIT_CH1_ERR BIT(1)
+#define BIT_CH0_ERR BIT(0)
+
+/* 2 REG_STC_INT_CS (Offset 0x1300) */
+
+#define BIT_STC_INT_EN BIT(31)
+
+#define BIT_SHIFT_STC_INT_FLAG 16
+#define BIT_MASK_STC_INT_FLAG 0xff
+#define BIT_STC_INT_FLAG(x) \
+ (((x) & BIT_MASK_STC_INT_FLAG) << BIT_SHIFT_STC_INT_FLAG)
+#define BIT_GET_STC_INT_FLAG(x) \
+ (((x) >> BIT_SHIFT_STC_INT_FLAG) & BIT_MASK_STC_INT_FLAG)
+
+#define BIT_SHIFT_STC_INT_IDX 8
+#define BIT_MASK_STC_INT_IDX 0x7
+#define BIT_STC_INT_IDX(x) \
+ (((x) & BIT_MASK_STC_INT_IDX) << BIT_SHIFT_STC_INT_IDX)
+#define BIT_GET_STC_INT_IDX(x) \
+ (((x) >> BIT_SHIFT_STC_INT_IDX) & BIT_MASK_STC_INT_IDX)
+
+#define BIT_SHIFT_STC_INT_REALTIME_CS 0
+#define BIT_MASK_STC_INT_REALTIME_CS 0x3f
+#define BIT_STC_INT_REALTIME_CS(x) \
+ (((x) & BIT_MASK_STC_INT_REALTIME_CS) << BIT_SHIFT_STC_INT_REALTIME_CS)
+#define BIT_GET_STC_INT_REALTIME_CS(x) \
+ (((x) >> BIT_SHIFT_STC_INT_REALTIME_CS) & BIT_MASK_STC_INT_REALTIME_CS)
+
+/* 2 REG_ST_INT_CFG (Offset 0x1304) */
+
+#define BIT_STC_INT_GRP_EN BIT(31)
+
+#define BIT_SHIFT_STC_INT_EXPECT_LS 8
+#define BIT_MASK_STC_INT_EXPECT_LS 0x3f
+#define BIT_STC_INT_EXPECT_LS(x) \
+ (((x) & BIT_MASK_STC_INT_EXPECT_LS) << BIT_SHIFT_STC_INT_EXPECT_LS)
+#define BIT_GET_STC_INT_EXPECT_LS(x) \
+ (((x) >> BIT_SHIFT_STC_INT_EXPECT_LS) & BIT_MASK_STC_INT_EXPECT_LS)
+
+#define BIT_SHIFT_STC_INT_EXPECT_CS 0
+#define BIT_MASK_STC_INT_EXPECT_CS 0x3f
+#define BIT_STC_INT_EXPECT_CS(x) \
+ (((x) & BIT_MASK_STC_INT_EXPECT_CS) << BIT_SHIFT_STC_INT_EXPECT_CS)
+#define BIT_GET_STC_INT_EXPECT_CS(x) \
+ (((x) >> BIT_SHIFT_STC_INT_EXPECT_CS) & BIT_MASK_STC_INT_EXPECT_CS)
+
+/* 2 REG_CMU_DLY_CTRL (Offset 0x1310) */
+
+#define BIT_CMU_DLY_EN BIT(31)
+#define BIT_CMU_DLY_MODE BIT(30)
+
+#define BIT_SHIFT_CMU_DLY_PRE_DIV 0
+#define BIT_MASK_CMU_DLY_PRE_DIV 0xff
+#define BIT_CMU_DLY_PRE_DIV(x) \
+ (((x) & BIT_MASK_CMU_DLY_PRE_DIV) << BIT_SHIFT_CMU_DLY_PRE_DIV)
+#define BIT_GET_CMU_DLY_PRE_DIV(x) \
+ (((x) >> BIT_SHIFT_CMU_DLY_PRE_DIV) & BIT_MASK_CMU_DLY_PRE_DIV)
+
+/* 2 REG_CMU_DLY_CFG (Offset 0x1314) */
+
+#define BIT_SHIFT_CMU_DLY_LTR_A2I 24
+#define BIT_MASK_CMU_DLY_LTR_A2I 0xff
+#define BIT_CMU_DLY_LTR_A2I(x) \
+ (((x) & BIT_MASK_CMU_DLY_LTR_A2I) << BIT_SHIFT_CMU_DLY_LTR_A2I)
+#define BIT_GET_CMU_DLY_LTR_A2I(x) \
+ (((x) >> BIT_SHIFT_CMU_DLY_LTR_A2I) & BIT_MASK_CMU_DLY_LTR_A2I)
+
+#define BIT_SHIFT_CMU_DLY_LTR_I2A 16
+#define BIT_MASK_CMU_DLY_LTR_I2A 0xff
+#define BIT_CMU_DLY_LTR_I2A(x) \
+ (((x) & BIT_MASK_CMU_DLY_LTR_I2A) << BIT_SHIFT_CMU_DLY_LTR_I2A)
+#define BIT_GET_CMU_DLY_LTR_I2A(x) \
+ (((x) >> BIT_SHIFT_CMU_DLY_LTR_I2A) & BIT_MASK_CMU_DLY_LTR_I2A)
+
+#define BIT_SHIFT_CMU_DLY_LTR_IDLE 8
+#define BIT_MASK_CMU_DLY_LTR_IDLE 0xff
+#define BIT_CMU_DLY_LTR_IDLE(x) \
+ (((x) & BIT_MASK_CMU_DLY_LTR_IDLE) << BIT_SHIFT_CMU_DLY_LTR_IDLE)
+#define BIT_GET_CMU_DLY_LTR_IDLE(x) \
+ (((x) >> BIT_SHIFT_CMU_DLY_LTR_IDLE) & BIT_MASK_CMU_DLY_LTR_IDLE)
+
+#define BIT_SHIFT_CMU_DLY_LTR_ACT 0
+#define BIT_MASK_CMU_DLY_LTR_ACT 0xff
+#define BIT_CMU_DLY_LTR_ACT(x) \
+ (((x) & BIT_MASK_CMU_DLY_LTR_ACT) << BIT_SHIFT_CMU_DLY_LTR_ACT)
+#define BIT_GET_CMU_DLY_LTR_ACT(x) \
+ (((x) >> BIT_SHIFT_CMU_DLY_LTR_ACT) & BIT_MASK_CMU_DLY_LTR_ACT)
+
+/* 2 REG_H2CQ_TXBD_DESA (Offset 0x1320) */
+
+#define BIT_SHIFT_H2CQ_TXBD_DESA 0
+#define BIT_MASK_H2CQ_TXBD_DESA 0xffffffffffffffffL
+#define BIT_H2CQ_TXBD_DESA(x) \
+ (((x) & BIT_MASK_H2CQ_TXBD_DESA) << BIT_SHIFT_H2CQ_TXBD_DESA)
+#define BIT_GET_H2CQ_TXBD_DESA(x) \
+ (((x) >> BIT_SHIFT_H2CQ_TXBD_DESA) & BIT_MASK_H2CQ_TXBD_DESA)
+
+/* 2 REG_H2CQ_TXBD_NUM (Offset 0x1328) */
+
+#define BIT_PCIE_H2CQ_FLAG BIT(14)
+
+/* 2 REG_H2CQ_TXBD_NUM (Offset 0x1328) */
+
+#define BIT_SHIFT_H2CQ_DESC_MODE 12
+#define BIT_MASK_H2CQ_DESC_MODE 0x3
+#define BIT_H2CQ_DESC_MODE(x) \
+ (((x) & BIT_MASK_H2CQ_DESC_MODE) << BIT_SHIFT_H2CQ_DESC_MODE)
+#define BIT_GET_H2CQ_DESC_MODE(x) \
+ (((x) >> BIT_SHIFT_H2CQ_DESC_MODE) & BIT_MASK_H2CQ_DESC_MODE)
+
+#define BIT_SHIFT_H2CQ_DESC_NUM 0
+#define BIT_MASK_H2CQ_DESC_NUM 0xfff
+#define BIT_H2CQ_DESC_NUM(x) \
+ (((x) & BIT_MASK_H2CQ_DESC_NUM) << BIT_SHIFT_H2CQ_DESC_NUM)
+#define BIT_GET_H2CQ_DESC_NUM(x) \
+ (((x) >> BIT_SHIFT_H2CQ_DESC_NUM) & BIT_MASK_H2CQ_DESC_NUM)
+
+/* 2 REG_H2CQ_TXBD_IDX (Offset 0x132C) */
+
+#define BIT_SHIFT_H2CQ_HW_IDX 16
+#define BIT_MASK_H2CQ_HW_IDX 0xfff
+#define BIT_H2CQ_HW_IDX(x) \
+ (((x) & BIT_MASK_H2CQ_HW_IDX) << BIT_SHIFT_H2CQ_HW_IDX)
+#define BIT_GET_H2CQ_HW_IDX(x) \
+ (((x) >> BIT_SHIFT_H2CQ_HW_IDX) & BIT_MASK_H2CQ_HW_IDX)
+
+#define BIT_SHIFT_H2CQ_HOST_IDX 0
+#define BIT_MASK_H2CQ_HOST_IDX 0xfff
+#define BIT_H2CQ_HOST_IDX(x) \
+ (((x) & BIT_MASK_H2CQ_HOST_IDX) << BIT_SHIFT_H2CQ_HOST_IDX)
+#define BIT_GET_H2CQ_HOST_IDX(x) \
+ (((x) >> BIT_SHIFT_H2CQ_HOST_IDX) & BIT_MASK_H2CQ_HOST_IDX)
+
+/* 2 REG_H2CQ_CSR (Offset 0x1330) */
+
+#define BIT_H2CQ_FULL BIT(31)
+#define BIT_CLR_H2CQ_HOST_IDX BIT(16)
+#define BIT_CLR_H2CQ_HW_IDX BIT(8)
+
+/* 2 REG_CHANGE_PCIE_SPEED (Offset 0x1350) */
+
+#define BIT_CHANGE_PCIE_SPEED BIT(18)
+
+/* 2 REG_CHANGE_PCIE_SPEED (Offset 0x1350) */
+
+#define BIT_SHIFT_GEN1_GEN2 16
+#define BIT_MASK_GEN1_GEN2 0x3
+#define BIT_GEN1_GEN2(x) (((x) & BIT_MASK_GEN1_GEN2) << BIT_SHIFT_GEN1_GEN2)
+#define BIT_GET_GEN1_GEN2(x) (((x) >> BIT_SHIFT_GEN1_GEN2) & BIT_MASK_GEN1_GEN2)
+
+/* 2 REG_CHANGE_PCIE_SPEED (Offset 0x1350) */
+
+#define BIT_SHIFT_AUTO_HANG_RELEASE 0
+#define BIT_MASK_AUTO_HANG_RELEASE 0x7
+#define BIT_AUTO_HANG_RELEASE(x) \
+ (((x) & BIT_MASK_AUTO_HANG_RELEASE) << BIT_SHIFT_AUTO_HANG_RELEASE)
+#define BIT_GET_AUTO_HANG_RELEASE(x) \
+ (((x) >> BIT_SHIFT_AUTO_HANG_RELEASE) & BIT_MASK_AUTO_HANG_RELEASE)
+
+/* 2 REG_OLD_DEHANG (Offset 0x13F4) */
+
+#define BIT_OLD_DEHANG BIT(1)
+
+/* 2 REG_Q0_Q1_INFO (Offset 0x1400) */
+
+#define BIT_SHIFT_AC1_PKT_INFO 16
+#define BIT_MASK_AC1_PKT_INFO 0xfff
+#define BIT_AC1_PKT_INFO(x) \
+ (((x) & BIT_MASK_AC1_PKT_INFO) << BIT_SHIFT_AC1_PKT_INFO)
+#define BIT_GET_AC1_PKT_INFO(x) \
+ (((x) >> BIT_SHIFT_AC1_PKT_INFO) & BIT_MASK_AC1_PKT_INFO)
+
+#define BIT_SHIFT_AC0_PKT_INFO 0
+#define BIT_MASK_AC0_PKT_INFO 0xfff
+#define BIT_AC0_PKT_INFO(x) \
+ (((x) & BIT_MASK_AC0_PKT_INFO) << BIT_SHIFT_AC0_PKT_INFO)
+#define BIT_GET_AC0_PKT_INFO(x) \
+ (((x) >> BIT_SHIFT_AC0_PKT_INFO) & BIT_MASK_AC0_PKT_INFO)
+
+/* 2 REG_Q2_Q3_INFO (Offset 0x1404) */
+
+#define BIT_SHIFT_AC3_PKT_INFO 16
+#define BIT_MASK_AC3_PKT_INFO 0xfff
+#define BIT_AC3_PKT_INFO(x) \
+ (((x) & BIT_MASK_AC3_PKT_INFO) << BIT_SHIFT_AC3_PKT_INFO)
+#define BIT_GET_AC3_PKT_INFO(x) \
+ (((x) >> BIT_SHIFT_AC3_PKT_INFO) & BIT_MASK_AC3_PKT_INFO)
+
+#define BIT_SHIFT_AC2_PKT_INFO 0
+#define BIT_MASK_AC2_PKT_INFO 0xfff
+#define BIT_AC2_PKT_INFO(x) \
+ (((x) & BIT_MASK_AC2_PKT_INFO) << BIT_SHIFT_AC2_PKT_INFO)
+#define BIT_GET_AC2_PKT_INFO(x) \
+ (((x) >> BIT_SHIFT_AC2_PKT_INFO) & BIT_MASK_AC2_PKT_INFO)
+
+/* 2 REG_Q4_Q5_INFO (Offset 0x1408) */
+
+#define BIT_SHIFT_AC5_PKT_INFO 16
+#define BIT_MASK_AC5_PKT_INFO 0xfff
+#define BIT_AC5_PKT_INFO(x) \
+ (((x) & BIT_MASK_AC5_PKT_INFO) << BIT_SHIFT_AC5_PKT_INFO)
+#define BIT_GET_AC5_PKT_INFO(x) \
+ (((x) >> BIT_SHIFT_AC5_PKT_INFO) & BIT_MASK_AC5_PKT_INFO)
+
+#define BIT_SHIFT_AC4_PKT_INFO 0
+#define BIT_MASK_AC4_PKT_INFO 0xfff
+#define BIT_AC4_PKT_INFO(x) \
+ (((x) & BIT_MASK_AC4_PKT_INFO) << BIT_SHIFT_AC4_PKT_INFO)
+#define BIT_GET_AC4_PKT_INFO(x) \
+ (((x) >> BIT_SHIFT_AC4_PKT_INFO) & BIT_MASK_AC4_PKT_INFO)
+
+/* 2 REG_Q6_Q7_INFO (Offset 0x140C) */
+
+#define BIT_SHIFT_AC7_PKT_INFO 16
+#define BIT_MASK_AC7_PKT_INFO 0xfff
+#define BIT_AC7_PKT_INFO(x) \
+ (((x) & BIT_MASK_AC7_PKT_INFO) << BIT_SHIFT_AC7_PKT_INFO)
+#define BIT_GET_AC7_PKT_INFO(x) \
+ (((x) >> BIT_SHIFT_AC7_PKT_INFO) & BIT_MASK_AC7_PKT_INFO)
+
+#define BIT_SHIFT_AC6_PKT_INFO 0
+#define BIT_MASK_AC6_PKT_INFO 0xfff
+#define BIT_AC6_PKT_INFO(x) \
+ (((x) & BIT_MASK_AC6_PKT_INFO) << BIT_SHIFT_AC6_PKT_INFO)
+#define BIT_GET_AC6_PKT_INFO(x) \
+ (((x) >> BIT_SHIFT_AC6_PKT_INFO) & BIT_MASK_AC6_PKT_INFO)
+
+/* 2 REG_MGQ_HIQ_INFO (Offset 0x1410) */
+
+#define BIT_SHIFT_HIQ_PKT_INFO 16
+#define BIT_MASK_HIQ_PKT_INFO 0xfff
+#define BIT_HIQ_PKT_INFO(x) \
+ (((x) & BIT_MASK_HIQ_PKT_INFO) << BIT_SHIFT_HIQ_PKT_INFO)
+#define BIT_GET_HIQ_PKT_INFO(x) \
+ (((x) >> BIT_SHIFT_HIQ_PKT_INFO) & BIT_MASK_HIQ_PKT_INFO)
+
+#define BIT_SHIFT_MGQ_PKT_INFO 0
+#define BIT_MASK_MGQ_PKT_INFO 0xfff
+#define BIT_MGQ_PKT_INFO(x) \
+ (((x) & BIT_MASK_MGQ_PKT_INFO) << BIT_SHIFT_MGQ_PKT_INFO)
+#define BIT_GET_MGQ_PKT_INFO(x) \
+ (((x) >> BIT_SHIFT_MGQ_PKT_INFO) & BIT_MASK_MGQ_PKT_INFO)
+
+/* 2 REG_CMDQ_BCNQ_INFO (Offset 0x1414) */
+
+#define BIT_SHIFT_CMDQ_PKT_INFO 16
+#define BIT_MASK_CMDQ_PKT_INFO 0xfff
+#define BIT_CMDQ_PKT_INFO(x) \
+ (((x) & BIT_MASK_CMDQ_PKT_INFO) << BIT_SHIFT_CMDQ_PKT_INFO)
+#define BIT_GET_CMDQ_PKT_INFO(x) \
+ (((x) >> BIT_SHIFT_CMDQ_PKT_INFO) & BIT_MASK_CMDQ_PKT_INFO)
+
+/* 2 REG_CMDQ_BCNQ_INFO (Offset 0x1414) */
+
+#define BIT_SHIFT_BCNQ_PKT_INFO 0
+#define BIT_MASK_BCNQ_PKT_INFO 0xfff
+#define BIT_BCNQ_PKT_INFO(x) \
+ (((x) & BIT_MASK_BCNQ_PKT_INFO) << BIT_SHIFT_BCNQ_PKT_INFO)
+#define BIT_GET_BCNQ_PKT_INFO(x) \
+ (((x) >> BIT_SHIFT_BCNQ_PKT_INFO) & BIT_MASK_BCNQ_PKT_INFO)
+
+/* 2 REG_USEREG_SETTING (Offset 0x1420) */
+
+#define BIT_NDPA_USEREG BIT(21)
+
+#define BIT_SHIFT_RETRY_USEREG 19
+#define BIT_MASK_RETRY_USEREG 0x3
+#define BIT_RETRY_USEREG(x) \
+ (((x) & BIT_MASK_RETRY_USEREG) << BIT_SHIFT_RETRY_USEREG)
+#define BIT_GET_RETRY_USEREG(x) \
+ (((x) >> BIT_SHIFT_RETRY_USEREG) & BIT_MASK_RETRY_USEREG)
+
+#define BIT_SHIFT_TRYPKT_USEREG 17
+#define BIT_MASK_TRYPKT_USEREG 0x3
+#define BIT_TRYPKT_USEREG(x) \
+ (((x) & BIT_MASK_TRYPKT_USEREG) << BIT_SHIFT_TRYPKT_USEREG)
+#define BIT_GET_TRYPKT_USEREG(x) \
+ (((x) >> BIT_SHIFT_TRYPKT_USEREG) & BIT_MASK_TRYPKT_USEREG)
+
+#define BIT_CTLPKT_USEREG BIT(16)
+
+/* 2 REG_AESIV_SETTING (Offset 0x1424) */
+
+#define BIT_SHIFT_AESIV_OFFSET 0
+#define BIT_MASK_AESIV_OFFSET 0xfff
+#define BIT_AESIV_OFFSET(x) \
+ (((x) & BIT_MASK_AESIV_OFFSET) << BIT_SHIFT_AESIV_OFFSET)
+#define BIT_GET_AESIV_OFFSET(x) \
+ (((x) >> BIT_SHIFT_AESIV_OFFSET) & BIT_MASK_AESIV_OFFSET)
+
+/* 2 REG_BF0_TIME_SETTING (Offset 0x1428) */
+
+#define BIT_BF0_TIMER_SET BIT(31)
+#define BIT_BF0_TIMER_CLR BIT(30)
+#define BIT_BF0_UPDATE_EN BIT(29)
+#define BIT_BF0_TIMER_EN BIT(28)
+
+#define BIT_SHIFT_BF0_PRETIME_OVER 16
+#define BIT_MASK_BF0_PRETIME_OVER 0xfff
+#define BIT_BF0_PRETIME_OVER(x) \
+ (((x) & BIT_MASK_BF0_PRETIME_OVER) << BIT_SHIFT_BF0_PRETIME_OVER)
+#define BIT_GET_BF0_PRETIME_OVER(x) \
+ (((x) >> BIT_SHIFT_BF0_PRETIME_OVER) & BIT_MASK_BF0_PRETIME_OVER)
+
+#define BIT_SHIFT_BF0_LIFETIME 0
+#define BIT_MASK_BF0_LIFETIME 0xffff
+#define BIT_BF0_LIFETIME(x) \
+ (((x) & BIT_MASK_BF0_LIFETIME) << BIT_SHIFT_BF0_LIFETIME)
+#define BIT_GET_BF0_LIFETIME(x) \
+ (((x) >> BIT_SHIFT_BF0_LIFETIME) & BIT_MASK_BF0_LIFETIME)
+
+/* 2 REG_BF1_TIME_SETTING (Offset 0x142C) */
+
+#define BIT_BF1_TIMER_SET BIT(31)
+#define BIT_BF1_TIMER_CLR BIT(30)
+#define BIT_BF1_UPDATE_EN BIT(29)
+#define BIT_BF1_TIMER_EN BIT(28)
+
+#define BIT_SHIFT_BF1_PRETIME_OVER 16
+#define BIT_MASK_BF1_PRETIME_OVER 0xfff
+#define BIT_BF1_PRETIME_OVER(x) \
+ (((x) & BIT_MASK_BF1_PRETIME_OVER) << BIT_SHIFT_BF1_PRETIME_OVER)
+#define BIT_GET_BF1_PRETIME_OVER(x) \
+ (((x) >> BIT_SHIFT_BF1_PRETIME_OVER) & BIT_MASK_BF1_PRETIME_OVER)
+
+#define BIT_SHIFT_BF1_LIFETIME 0
+#define BIT_MASK_BF1_LIFETIME 0xffff
+#define BIT_BF1_LIFETIME(x) \
+ (((x) & BIT_MASK_BF1_LIFETIME) << BIT_SHIFT_BF1_LIFETIME)
+#define BIT_GET_BF1_LIFETIME(x) \
+ (((x) >> BIT_SHIFT_BF1_LIFETIME) & BIT_MASK_BF1_LIFETIME)
+
+/* 2 REG_BF_TIMEOUT_EN (Offset 0x1430) */
+
+#define BIT_EN_VHT_LDPC BIT(9)
+#define BIT_EN_HT_LDPC BIT(8)
+#define BIT_BF1_TIMEOUT_EN BIT(1)
+#define BIT_BF0_TIMEOUT_EN BIT(0)
+
+/* 2 REG_MACID_RELEASE0 (Offset 0x1434) */
+
+#define BIT_SHIFT_MACID31_0_RELEASE 0
+#define BIT_MASK_MACID31_0_RELEASE 0xffffffffL
+#define BIT_MACID31_0_RELEASE(x) \
+ (((x) & BIT_MASK_MACID31_0_RELEASE) << BIT_SHIFT_MACID31_0_RELEASE)
+#define BIT_GET_MACID31_0_RELEASE(x) \
+ (((x) >> BIT_SHIFT_MACID31_0_RELEASE) & BIT_MASK_MACID31_0_RELEASE)
+
+/* 2 REG_MACID_RELEASE1 (Offset 0x1438) */
+
+#define BIT_SHIFT_MACID63_32_RELEASE 0
+#define BIT_MASK_MACID63_32_RELEASE 0xffffffffL
+#define BIT_MACID63_32_RELEASE(x) \
+ (((x) & BIT_MASK_MACID63_32_RELEASE) << BIT_SHIFT_MACID63_32_RELEASE)
+#define BIT_GET_MACID63_32_RELEASE(x) \
+ (((x) >> BIT_SHIFT_MACID63_32_RELEASE) & BIT_MASK_MACID63_32_RELEASE)
+
+/* 2 REG_MACID_RELEASE2 (Offset 0x143C) */
+
+#define BIT_SHIFT_MACID95_64_RELEASE 0
+#define BIT_MASK_MACID95_64_RELEASE 0xffffffffL
+#define BIT_MACID95_64_RELEASE(x) \
+ (((x) & BIT_MASK_MACID95_64_RELEASE) << BIT_SHIFT_MACID95_64_RELEASE)
+#define BIT_GET_MACID95_64_RELEASE(x) \
+ (((x) >> BIT_SHIFT_MACID95_64_RELEASE) & BIT_MASK_MACID95_64_RELEASE)
+
+/* 2 REG_MACID_RELEASE3 (Offset 0x1440) */
+
+#define BIT_SHIFT_MACID127_96_RELEASE 0
+#define BIT_MASK_MACID127_96_RELEASE 0xffffffffL
+#define BIT_MACID127_96_RELEASE(x) \
+ (((x) & BIT_MASK_MACID127_96_RELEASE) << BIT_SHIFT_MACID127_96_RELEASE)
+#define BIT_GET_MACID127_96_RELEASE(x) \
+ (((x) >> BIT_SHIFT_MACID127_96_RELEASE) & BIT_MASK_MACID127_96_RELEASE)
+
+/* 2 REG_MACID_RELEASE_SETTING (Offset 0x1444) */
+
+#define BIT_MACID_VALUE BIT(7)
+
+#define BIT_SHIFT_MACID_OFFSET 0
+#define BIT_MASK_MACID_OFFSET 0x7f
+#define BIT_MACID_OFFSET(x) \
+ (((x) & BIT_MASK_MACID_OFFSET) << BIT_SHIFT_MACID_OFFSET)
+#define BIT_GET_MACID_OFFSET(x) \
+ (((x) >> BIT_SHIFT_MACID_OFFSET) & BIT_MASK_MACID_OFFSET)
+
+/* 2 REG_FAST_EDCA_VOVI_SETTING (Offset 0x1448) */
+
+#define BIT_SHIFT_VI_FAST_EDCA_TO 24
+#define BIT_MASK_VI_FAST_EDCA_TO 0xff
+#define BIT_VI_FAST_EDCA_TO(x) \
+ (((x) & BIT_MASK_VI_FAST_EDCA_TO) << BIT_SHIFT_VI_FAST_EDCA_TO)
+#define BIT_GET_VI_FAST_EDCA_TO(x) \
+ (((x) >> BIT_SHIFT_VI_FAST_EDCA_TO) & BIT_MASK_VI_FAST_EDCA_TO)
+
+#define BIT_VI_THRESHOLD_SEL BIT(23)
+
+#define BIT_SHIFT_VI_FAST_EDCA_PKT_TH 16
+#define BIT_MASK_VI_FAST_EDCA_PKT_TH 0x7f
+#define BIT_VI_FAST_EDCA_PKT_TH(x) \
+ (((x) & BIT_MASK_VI_FAST_EDCA_PKT_TH) << BIT_SHIFT_VI_FAST_EDCA_PKT_TH)
+#define BIT_GET_VI_FAST_EDCA_PKT_TH(x) \
+ (((x) >> BIT_SHIFT_VI_FAST_EDCA_PKT_TH) & BIT_MASK_VI_FAST_EDCA_PKT_TH)
+
+#define BIT_SHIFT_VO_FAST_EDCA_TO 8
+#define BIT_MASK_VO_FAST_EDCA_TO 0xff
+#define BIT_VO_FAST_EDCA_TO(x) \
+ (((x) & BIT_MASK_VO_FAST_EDCA_TO) << BIT_SHIFT_VO_FAST_EDCA_TO)
+#define BIT_GET_VO_FAST_EDCA_TO(x) \
+ (((x) >> BIT_SHIFT_VO_FAST_EDCA_TO) & BIT_MASK_VO_FAST_EDCA_TO)
+
+#define BIT_VO_THRESHOLD_SEL BIT(7)
+
+#define BIT_SHIFT_VO_FAST_EDCA_PKT_TH 0
+#define BIT_MASK_VO_FAST_EDCA_PKT_TH 0x7f
+#define BIT_VO_FAST_EDCA_PKT_TH(x) \
+ (((x) & BIT_MASK_VO_FAST_EDCA_PKT_TH) << BIT_SHIFT_VO_FAST_EDCA_PKT_TH)
+#define BIT_GET_VO_FAST_EDCA_PKT_TH(x) \
+ (((x) >> BIT_SHIFT_VO_FAST_EDCA_PKT_TH) & BIT_MASK_VO_FAST_EDCA_PKT_TH)
+
+/* 2 REG_FAST_EDCA_BEBK_SETTING (Offset 0x144C) */
+
+#define BIT_SHIFT_BK_FAST_EDCA_TO 24
+#define BIT_MASK_BK_FAST_EDCA_TO 0xff
+#define BIT_BK_FAST_EDCA_TO(x) \
+ (((x) & BIT_MASK_BK_FAST_EDCA_TO) << BIT_SHIFT_BK_FAST_EDCA_TO)
+#define BIT_GET_BK_FAST_EDCA_TO(x) \
+ (((x) >> BIT_SHIFT_BK_FAST_EDCA_TO) & BIT_MASK_BK_FAST_EDCA_TO)
+
+#define BIT_BK_THRESHOLD_SEL BIT(23)
+
+#define BIT_SHIFT_BK_FAST_EDCA_PKT_TH 16
+#define BIT_MASK_BK_FAST_EDCA_PKT_TH 0x7f
+#define BIT_BK_FAST_EDCA_PKT_TH(x) \
+ (((x) & BIT_MASK_BK_FAST_EDCA_PKT_TH) << BIT_SHIFT_BK_FAST_EDCA_PKT_TH)
+#define BIT_GET_BK_FAST_EDCA_PKT_TH(x) \
+ (((x) >> BIT_SHIFT_BK_FAST_EDCA_PKT_TH) & BIT_MASK_BK_FAST_EDCA_PKT_TH)
+
+#define BIT_SHIFT_BE_FAST_EDCA_TO 8
+#define BIT_MASK_BE_FAST_EDCA_TO 0xff
+#define BIT_BE_FAST_EDCA_TO(x) \
+ (((x) & BIT_MASK_BE_FAST_EDCA_TO) << BIT_SHIFT_BE_FAST_EDCA_TO)
+#define BIT_GET_BE_FAST_EDCA_TO(x) \
+ (((x) >> BIT_SHIFT_BE_FAST_EDCA_TO) & BIT_MASK_BE_FAST_EDCA_TO)
+
+#define BIT_BE_THRESHOLD_SEL BIT(7)
+
+#define BIT_SHIFT_BE_FAST_EDCA_PKT_TH 0
+#define BIT_MASK_BE_FAST_EDCA_PKT_TH 0x7f
+#define BIT_BE_FAST_EDCA_PKT_TH(x) \
+ (((x) & BIT_MASK_BE_FAST_EDCA_PKT_TH) << BIT_SHIFT_BE_FAST_EDCA_PKT_TH)
+#define BIT_GET_BE_FAST_EDCA_PKT_TH(x) \
+ (((x) >> BIT_SHIFT_BE_FAST_EDCA_PKT_TH) & BIT_MASK_BE_FAST_EDCA_PKT_TH)
+
+/* 2 REG_MACID_DROP0 (Offset 0x1450) */
+
+#define BIT_SHIFT_MACID31_0_DROP 0
+#define BIT_MASK_MACID31_0_DROP 0xffffffffL
+#define BIT_MACID31_0_DROP(x) \
+ (((x) & BIT_MASK_MACID31_0_DROP) << BIT_SHIFT_MACID31_0_DROP)
+#define BIT_GET_MACID31_0_DROP(x) \
+ (((x) >> BIT_SHIFT_MACID31_0_DROP) & BIT_MASK_MACID31_0_DROP)
+
+/* 2 REG_MACID_DROP1 (Offset 0x1454) */
+
+#define BIT_SHIFT_MACID63_32_DROP 0
+#define BIT_MASK_MACID63_32_DROP 0xffffffffL
+#define BIT_MACID63_32_DROP(x) \
+ (((x) & BIT_MASK_MACID63_32_DROP) << BIT_SHIFT_MACID63_32_DROP)
+#define BIT_GET_MACID63_32_DROP(x) \
+ (((x) >> BIT_SHIFT_MACID63_32_DROP) & BIT_MASK_MACID63_32_DROP)
+
+/* 2 REG_MACID_DROP2 (Offset 0x1458) */
+
+#define BIT_SHIFT_MACID95_64_DROP 0
+#define BIT_MASK_MACID95_64_DROP 0xffffffffL
+#define BIT_MACID95_64_DROP(x) \
+ (((x) & BIT_MASK_MACID95_64_DROP) << BIT_SHIFT_MACID95_64_DROP)
+#define BIT_GET_MACID95_64_DROP(x) \
+ (((x) >> BIT_SHIFT_MACID95_64_DROP) & BIT_MASK_MACID95_64_DROP)
+
+/* 2 REG_MACID_DROP3 (Offset 0x145C) */
+
+#define BIT_SHIFT_MACID127_96_DROP 0
+#define BIT_MASK_MACID127_96_DROP 0xffffffffL
+#define BIT_MACID127_96_DROP(x) \
+ (((x) & BIT_MASK_MACID127_96_DROP) << BIT_SHIFT_MACID127_96_DROP)
+#define BIT_GET_MACID127_96_DROP(x) \
+ (((x) >> BIT_SHIFT_MACID127_96_DROP) & BIT_MASK_MACID127_96_DROP)
+
+/* 2 REG_R_MACID_RELEASE_SUCCESS_0 (Offset 0x1460) */
+
+#define BIT_SHIFT_R_MACID_RELEASE_SUCCESS_0 0
+#define BIT_MASK_R_MACID_RELEASE_SUCCESS_0 0xffffffffL
+#define BIT_R_MACID_RELEASE_SUCCESS_0(x) \
+ (((x) & BIT_MASK_R_MACID_RELEASE_SUCCESS_0) \
+ << BIT_SHIFT_R_MACID_RELEASE_SUCCESS_0)
+#define BIT_GET_R_MACID_RELEASE_SUCCESS_0(x) \
+ (((x) >> BIT_SHIFT_R_MACID_RELEASE_SUCCESS_0) & \
+ BIT_MASK_R_MACID_RELEASE_SUCCESS_0)
+
+/* 2 REG_R_MACID_RELEASE_SUCCESS_1 (Offset 0x1464) */
+
+#define BIT_SHIFT_R_MACID_RELEASE_SUCCESS_1 0
+#define BIT_MASK_R_MACID_RELEASE_SUCCESS_1 0xffffffffL
+#define BIT_R_MACID_RELEASE_SUCCESS_1(x) \
+ (((x) & BIT_MASK_R_MACID_RELEASE_SUCCESS_1) \
+ << BIT_SHIFT_R_MACID_RELEASE_SUCCESS_1)
+#define BIT_GET_R_MACID_RELEASE_SUCCESS_1(x) \
+ (((x) >> BIT_SHIFT_R_MACID_RELEASE_SUCCESS_1) & \
+ BIT_MASK_R_MACID_RELEASE_SUCCESS_1)
+
+/* 2 REG_R_MACID_RELEASE_SUCCESS_2 (Offset 0x1468) */
+
+#define BIT_SHIFT_R_MACID_RELEASE_SUCCESS_2 0
+#define BIT_MASK_R_MACID_RELEASE_SUCCESS_2 0xffffffffL
+#define BIT_R_MACID_RELEASE_SUCCESS_2(x) \
+ (((x) & BIT_MASK_R_MACID_RELEASE_SUCCESS_2) \
+ << BIT_SHIFT_R_MACID_RELEASE_SUCCESS_2)
+#define BIT_GET_R_MACID_RELEASE_SUCCESS_2(x) \
+ (((x) >> BIT_SHIFT_R_MACID_RELEASE_SUCCESS_2) & \
+ BIT_MASK_R_MACID_RELEASE_SUCCESS_2)
+
+/* 2 REG_R_MACID_RELEASE_SUCCESS_3 (Offset 0x146C) */
+
+#define BIT_SHIFT_R_MACID_RELEASE_SUCCESS_3 0
+#define BIT_MASK_R_MACID_RELEASE_SUCCESS_3 0xffffffffL
+#define BIT_R_MACID_RELEASE_SUCCESS_3(x) \
+ (((x) & BIT_MASK_R_MACID_RELEASE_SUCCESS_3) \
+ << BIT_SHIFT_R_MACID_RELEASE_SUCCESS_3)
+#define BIT_GET_R_MACID_RELEASE_SUCCESS_3(x) \
+ (((x) >> BIT_SHIFT_R_MACID_RELEASE_SUCCESS_3) & \
+ BIT_MASK_R_MACID_RELEASE_SUCCESS_3)
+
+/* 2 REG_MGG_FIFO_CRTL (Offset 0x1470) */
+
+#define BIT_R_MGG_FIFO_EN BIT(31)
+
+#define BIT_SHIFT_R_MGG_FIFO_PG_SIZE 28
+#define BIT_MASK_R_MGG_FIFO_PG_SIZE 0x7
+#define BIT_R_MGG_FIFO_PG_SIZE(x) \
+ (((x) & BIT_MASK_R_MGG_FIFO_PG_SIZE) << BIT_SHIFT_R_MGG_FIFO_PG_SIZE)
+#define BIT_GET_R_MGG_FIFO_PG_SIZE(x) \
+ (((x) >> BIT_SHIFT_R_MGG_FIFO_PG_SIZE) & BIT_MASK_R_MGG_FIFO_PG_SIZE)
+
+#define BIT_SHIFT_R_MGG_FIFO_START_PG 16
+#define BIT_MASK_R_MGG_FIFO_START_PG 0xfff
+#define BIT_R_MGG_FIFO_START_PG(x) \
+ (((x) & BIT_MASK_R_MGG_FIFO_START_PG) << BIT_SHIFT_R_MGG_FIFO_START_PG)
+#define BIT_GET_R_MGG_FIFO_START_PG(x) \
+ (((x) >> BIT_SHIFT_R_MGG_FIFO_START_PG) & BIT_MASK_R_MGG_FIFO_START_PG)
+
+#define BIT_SHIFT_R_MGG_FIFO_SIZE 14
+#define BIT_MASK_R_MGG_FIFO_SIZE 0x3
+#define BIT_R_MGG_FIFO_SIZE(x) \
+ (((x) & BIT_MASK_R_MGG_FIFO_SIZE) << BIT_SHIFT_R_MGG_FIFO_SIZE)
+#define BIT_GET_R_MGG_FIFO_SIZE(x) \
+ (((x) >> BIT_SHIFT_R_MGG_FIFO_SIZE) & BIT_MASK_R_MGG_FIFO_SIZE)
+
+#define BIT_R_MGG_FIFO_PAUSE BIT(13)
+
+#define BIT_SHIFT_R_MGG_FIFO_RPTR 8
+#define BIT_MASK_R_MGG_FIFO_RPTR 0x1f
+#define BIT_R_MGG_FIFO_RPTR(x) \
+ (((x) & BIT_MASK_R_MGG_FIFO_RPTR) << BIT_SHIFT_R_MGG_FIFO_RPTR)
+#define BIT_GET_R_MGG_FIFO_RPTR(x) \
+ (((x) >> BIT_SHIFT_R_MGG_FIFO_RPTR) & BIT_MASK_R_MGG_FIFO_RPTR)
+
+#define BIT_R_MGG_FIFO_OV BIT(7)
+#define BIT_R_MGG_FIFO_WPTR_ERROR BIT(6)
+#define BIT_R_EN_CPU_LIFETIME BIT(5)
+
+#define BIT_SHIFT_R_MGG_FIFO_WPTR 0
+#define BIT_MASK_R_MGG_FIFO_WPTR 0x1f
+#define BIT_R_MGG_FIFO_WPTR(x) \
+ (((x) & BIT_MASK_R_MGG_FIFO_WPTR) << BIT_SHIFT_R_MGG_FIFO_WPTR)
+#define BIT_GET_R_MGG_FIFO_WPTR(x) \
+ (((x) >> BIT_SHIFT_R_MGG_FIFO_WPTR) & BIT_MASK_R_MGG_FIFO_WPTR)
+
+/* 2 REG_MGG_FIFO_INT (Offset 0x1474) */
+
+#define BIT_SHIFT_R_MGG_FIFO_INT_FLAG 16
+#define BIT_MASK_R_MGG_FIFO_INT_FLAG 0xffff
+#define BIT_R_MGG_FIFO_INT_FLAG(x) \
+ (((x) & BIT_MASK_R_MGG_FIFO_INT_FLAG) << BIT_SHIFT_R_MGG_FIFO_INT_FLAG)
+#define BIT_GET_R_MGG_FIFO_INT_FLAG(x) \
+ (((x) >> BIT_SHIFT_R_MGG_FIFO_INT_FLAG) & BIT_MASK_R_MGG_FIFO_INT_FLAG)
+
+#define BIT_SHIFT_R_MGG_FIFO_INT_MASK 0
+#define BIT_MASK_R_MGG_FIFO_INT_MASK 0xffff
+#define BIT_R_MGG_FIFO_INT_MASK(x) \
+ (((x) & BIT_MASK_R_MGG_FIFO_INT_MASK) << BIT_SHIFT_R_MGG_FIFO_INT_MASK)
+#define BIT_GET_R_MGG_FIFO_INT_MASK(x) \
+ (((x) >> BIT_SHIFT_R_MGG_FIFO_INT_MASK) & BIT_MASK_R_MGG_FIFO_INT_MASK)
+
+/* 2 REG_MGG_FIFO_LIFETIME (Offset 0x1478) */
+
+#define BIT_SHIFT_R_MGG_FIFO_LIFETIME 16
+#define BIT_MASK_R_MGG_FIFO_LIFETIME 0xffff
+#define BIT_R_MGG_FIFO_LIFETIME(x) \
+ (((x) & BIT_MASK_R_MGG_FIFO_LIFETIME) << BIT_SHIFT_R_MGG_FIFO_LIFETIME)
+#define BIT_GET_R_MGG_FIFO_LIFETIME(x) \
+ (((x) >> BIT_SHIFT_R_MGG_FIFO_LIFETIME) & BIT_MASK_R_MGG_FIFO_LIFETIME)
+
+#define BIT_SHIFT_R_MGG_FIFO_VALID_MAP 0
+#define BIT_MASK_R_MGG_FIFO_VALID_MAP 0xffff
+#define BIT_R_MGG_FIFO_VALID_MAP(x) \
+ (((x) & BIT_MASK_R_MGG_FIFO_VALID_MAP) \
+ << BIT_SHIFT_R_MGG_FIFO_VALID_MAP)
+#define BIT_GET_R_MGG_FIFO_VALID_MAP(x) \
+ (((x) >> BIT_SHIFT_R_MGG_FIFO_VALID_MAP) & \
+ BIT_MASK_R_MGG_FIFO_VALID_MAP)
+
+/* 2 REG_R_MACID_RELEASE_SUCCESS_CLEAR_OFFSET (Offset 0x147C) */
+
+#define BIT_SHIFT_R_MACID_RELEASE_SUCCESS_CLEAR_OFFSET 0
+#define BIT_MASK_R_MACID_RELEASE_SUCCESS_CLEAR_OFFSET 0x7f
+#define BIT_R_MACID_RELEASE_SUCCESS_CLEAR_OFFSET(x) \
+ (((x) & BIT_MASK_R_MACID_RELEASE_SUCCESS_CLEAR_OFFSET) \
+ << BIT_SHIFT_R_MACID_RELEASE_SUCCESS_CLEAR_OFFSET)
+#define BIT_GET_R_MACID_RELEASE_SUCCESS_CLEAR_OFFSET(x) \
+ (((x) >> BIT_SHIFT_R_MACID_RELEASE_SUCCESS_CLEAR_OFFSET) & \
+ BIT_MASK_R_MACID_RELEASE_SUCCESS_CLEAR_OFFSET)
+
+#define BIT_SHIFT_P2PON_DIS_TXTIME 0
+#define BIT_MASK_P2PON_DIS_TXTIME 0xff
+#define BIT_P2PON_DIS_TXTIME(x) \
+ (((x) & BIT_MASK_P2PON_DIS_TXTIME) << BIT_SHIFT_P2PON_DIS_TXTIME)
+#define BIT_GET_P2PON_DIS_TXTIME(x) \
+ (((x) >> BIT_SHIFT_P2PON_DIS_TXTIME) & BIT_MASK_P2PON_DIS_TXTIME)
+
+/* 2 REG_MACID_SHCUT_OFFSET (Offset 0x1480) */
+
+#define BIT_SHIFT_MACID_SHCUT_OFFSET_V1 0
+#define BIT_MASK_MACID_SHCUT_OFFSET_V1 0xff
+#define BIT_MACID_SHCUT_OFFSET_V1(x) \
+ (((x) & BIT_MASK_MACID_SHCUT_OFFSET_V1) \
+ << BIT_SHIFT_MACID_SHCUT_OFFSET_V1)
+#define BIT_GET_MACID_SHCUT_OFFSET_V1(x) \
+ (((x) >> BIT_SHIFT_MACID_SHCUT_OFFSET_V1) & \
+ BIT_MASK_MACID_SHCUT_OFFSET_V1)
+
+/* 2 REG_MU_TX_CTL (Offset 0x14C0) */
+
+#define BIT_R_EN_REVERS_GTAB BIT(6)
+
+#define BIT_SHIFT_R_MU_TABLE_VALID 0
+#define BIT_MASK_R_MU_TABLE_VALID 0x3f
+#define BIT_R_MU_TABLE_VALID(x) \
+ (((x) & BIT_MASK_R_MU_TABLE_VALID) << BIT_SHIFT_R_MU_TABLE_VALID)
+#define BIT_GET_R_MU_TABLE_VALID(x) \
+ (((x) >> BIT_SHIFT_R_MU_TABLE_VALID) & BIT_MASK_R_MU_TABLE_VALID)
+
+#define BIT_SHIFT_R_MU_STA_GTAB_VALID 0
+#define BIT_MASK_R_MU_STA_GTAB_VALID 0xffffffffL
+#define BIT_R_MU_STA_GTAB_VALID(x) \
+ (((x) & BIT_MASK_R_MU_STA_GTAB_VALID) << BIT_SHIFT_R_MU_STA_GTAB_VALID)
+#define BIT_GET_R_MU_STA_GTAB_VALID(x) \
+ (((x) >> BIT_SHIFT_R_MU_STA_GTAB_VALID) & BIT_MASK_R_MU_STA_GTAB_VALID)
+
+#define BIT_SHIFT_R_MU_STA_GTAB_POSITION 0
+#define BIT_MASK_R_MU_STA_GTAB_POSITION 0xffffffffffffffffL
+#define BIT_R_MU_STA_GTAB_POSITION(x) \
+ (((x) & BIT_MASK_R_MU_STA_GTAB_POSITION) \
+ << BIT_SHIFT_R_MU_STA_GTAB_POSITION)
+#define BIT_GET_R_MU_STA_GTAB_POSITION(x) \
+ (((x) >> BIT_SHIFT_R_MU_STA_GTAB_POSITION) & \
+ BIT_MASK_R_MU_STA_GTAB_POSITION)
+
+/* 2 REG_MU_TRX_DBG_CNT (Offset 0x14D0) */
+
+#define BIT_MU_DNGCNT_RST BIT(20)
+
+#define BIT_SHIFT_MU_DBGCNT_SEL 16
+#define BIT_MASK_MU_DBGCNT_SEL 0xf
+#define BIT_MU_DBGCNT_SEL(x) \
+ (((x) & BIT_MASK_MU_DBGCNT_SEL) << BIT_SHIFT_MU_DBGCNT_SEL)
+#define BIT_GET_MU_DBGCNT_SEL(x) \
+ (((x) >> BIT_SHIFT_MU_DBGCNT_SEL) & BIT_MASK_MU_DBGCNT_SEL)
+
+#define BIT_SHIFT_MU_DNGCNT 0
+#define BIT_MASK_MU_DNGCNT 0xffff
+#define BIT_MU_DNGCNT(x) (((x) & BIT_MASK_MU_DNGCNT) << BIT_SHIFT_MU_DNGCNT)
+#define BIT_GET_MU_DNGCNT(x) (((x) >> BIT_SHIFT_MU_DNGCNT) & BIT_MASK_MU_DNGCNT)
+
+/* 2 REG_CPUMGQ_TX_TIMER (Offset 0x1500) */
+
+#define BIT_SHIFT_CPUMGQ_TX_TIMER_V1 0
+#define BIT_MASK_CPUMGQ_TX_TIMER_V1 0xffffffffL
+#define BIT_CPUMGQ_TX_TIMER_V1(x) \
+ (((x) & BIT_MASK_CPUMGQ_TX_TIMER_V1) << BIT_SHIFT_CPUMGQ_TX_TIMER_V1)
+#define BIT_GET_CPUMGQ_TX_TIMER_V1(x) \
+ (((x) >> BIT_SHIFT_CPUMGQ_TX_TIMER_V1) & BIT_MASK_CPUMGQ_TX_TIMER_V1)
+
+/* 2 REG_PS_TIMER_A (Offset 0x1504) */
+
+#define BIT_SHIFT_PS_TIMER_A_V1 0
+#define BIT_MASK_PS_TIMER_A_V1 0xffffffffL
+#define BIT_PS_TIMER_A_V1(x) \
+ (((x) & BIT_MASK_PS_TIMER_A_V1) << BIT_SHIFT_PS_TIMER_A_V1)
+#define BIT_GET_PS_TIMER_A_V1(x) \
+ (((x) >> BIT_SHIFT_PS_TIMER_A_V1) & BIT_MASK_PS_TIMER_A_V1)
+
+/* 2 REG_PS_TIMER_B (Offset 0x1508) */
+
+#define BIT_SHIFT_PS_TIMER_B_V1 0
+#define BIT_MASK_PS_TIMER_B_V1 0xffffffffL
+#define BIT_PS_TIMER_B_V1(x) \
+ (((x) & BIT_MASK_PS_TIMER_B_V1) << BIT_SHIFT_PS_TIMER_B_V1)
+#define BIT_GET_PS_TIMER_B_V1(x) \
+ (((x) >> BIT_SHIFT_PS_TIMER_B_V1) & BIT_MASK_PS_TIMER_B_V1)
+
+/* 2 REG_PS_TIMER_C (Offset 0x150C) */
+
+#define BIT_SHIFT_PS_TIMER_C_V1 0
+#define BIT_MASK_PS_TIMER_C_V1 0xffffffffL
+#define BIT_PS_TIMER_C_V1(x) \
+ (((x) & BIT_MASK_PS_TIMER_C_V1) << BIT_SHIFT_PS_TIMER_C_V1)
+#define BIT_GET_PS_TIMER_C_V1(x) \
+ (((x) >> BIT_SHIFT_PS_TIMER_C_V1) & BIT_MASK_PS_TIMER_C_V1)
+
+/* 2 REG_PS_TIMER_ABC_CPUMGQ_TIMER_CRTL (Offset 0x1510) */
+
+#define BIT_CPUMGQ_TIMER_EN BIT(31)
+#define BIT_CPUMGQ_TX_EN BIT(28)
+
+#define BIT_SHIFT_CPUMGQ_TIMER_TSF_SEL 24
+#define BIT_MASK_CPUMGQ_TIMER_TSF_SEL 0x7
+#define BIT_CPUMGQ_TIMER_TSF_SEL(x) \
+ (((x) & BIT_MASK_CPUMGQ_TIMER_TSF_SEL) \
+ << BIT_SHIFT_CPUMGQ_TIMER_TSF_SEL)
+#define BIT_GET_CPUMGQ_TIMER_TSF_SEL(x) \
+ (((x) >> BIT_SHIFT_CPUMGQ_TIMER_TSF_SEL) & \
+ BIT_MASK_CPUMGQ_TIMER_TSF_SEL)
+
+#define BIT_PS_TIMER_C_EN BIT(23)
+
+#define BIT_SHIFT_PS_TIMER_C_TSF_SEL 16
+#define BIT_MASK_PS_TIMER_C_TSF_SEL 0x7
+#define BIT_PS_TIMER_C_TSF_SEL(x) \
+ (((x) & BIT_MASK_PS_TIMER_C_TSF_SEL) << BIT_SHIFT_PS_TIMER_C_TSF_SEL)
+#define BIT_GET_PS_TIMER_C_TSF_SEL(x) \
+ (((x) >> BIT_SHIFT_PS_TIMER_C_TSF_SEL) & BIT_MASK_PS_TIMER_C_TSF_SEL)
+
+#define BIT_PS_TIMER_B_EN BIT(15)
+
+#define BIT_SHIFT_PS_TIMER_B_TSF_SEL 8
+#define BIT_MASK_PS_TIMER_B_TSF_SEL 0x7
+#define BIT_PS_TIMER_B_TSF_SEL(x) \
+ (((x) & BIT_MASK_PS_TIMER_B_TSF_SEL) << BIT_SHIFT_PS_TIMER_B_TSF_SEL)
+#define BIT_GET_PS_TIMER_B_TSF_SEL(x) \
+ (((x) >> BIT_SHIFT_PS_TIMER_B_TSF_SEL) & BIT_MASK_PS_TIMER_B_TSF_SEL)
+
+#define BIT_PS_TIMER_A_EN BIT(7)
+
+#define BIT_SHIFT_PS_TIMER_A_TSF_SEL 0
+#define BIT_MASK_PS_TIMER_A_TSF_SEL 0x7
+#define BIT_PS_TIMER_A_TSF_SEL(x) \
+ (((x) & BIT_MASK_PS_TIMER_A_TSF_SEL) << BIT_SHIFT_PS_TIMER_A_TSF_SEL)
+#define BIT_GET_PS_TIMER_A_TSF_SEL(x) \
+ (((x) >> BIT_SHIFT_PS_TIMER_A_TSF_SEL) & BIT_MASK_PS_TIMER_A_TSF_SEL)
+
+/* 2 REG_CPUMGQ_TX_TIMER_EARLY (Offset 0x1514) */
+
+#define BIT_SHIFT_CPUMGQ_TX_TIMER_EARLY 0
+#define BIT_MASK_CPUMGQ_TX_TIMER_EARLY 0xff
+#define BIT_CPUMGQ_TX_TIMER_EARLY(x) \
+ (((x) & BIT_MASK_CPUMGQ_TX_TIMER_EARLY) \
+ << BIT_SHIFT_CPUMGQ_TX_TIMER_EARLY)
+#define BIT_GET_CPUMGQ_TX_TIMER_EARLY(x) \
+ (((x) >> BIT_SHIFT_CPUMGQ_TX_TIMER_EARLY) & \
+ BIT_MASK_CPUMGQ_TX_TIMER_EARLY)
+
+/* 2 REG_PS_TIMER_A_EARLY (Offset 0x1515) */
+
+#define BIT_SHIFT_PS_TIMER_A_EARLY 0
+#define BIT_MASK_PS_TIMER_A_EARLY 0xff
+#define BIT_PS_TIMER_A_EARLY(x) \
+ (((x) & BIT_MASK_PS_TIMER_A_EARLY) << BIT_SHIFT_PS_TIMER_A_EARLY)
+#define BIT_GET_PS_TIMER_A_EARLY(x) \
+ (((x) >> BIT_SHIFT_PS_TIMER_A_EARLY) & BIT_MASK_PS_TIMER_A_EARLY)
+
+/* 2 REG_PS_TIMER_B_EARLY (Offset 0x1516) */
+
+#define BIT_SHIFT_PS_TIMER_B_EARLY 0
+#define BIT_MASK_PS_TIMER_B_EARLY 0xff
+#define BIT_PS_TIMER_B_EARLY(x) \
+ (((x) & BIT_MASK_PS_TIMER_B_EARLY) << BIT_SHIFT_PS_TIMER_B_EARLY)
+#define BIT_GET_PS_TIMER_B_EARLY(x) \
+ (((x) >> BIT_SHIFT_PS_TIMER_B_EARLY) & BIT_MASK_PS_TIMER_B_EARLY)
+
+/* 2 REG_PS_TIMER_C_EARLY (Offset 0x1517) */
+
+#define BIT_SHIFT_PS_TIMER_C_EARLY 0
+#define BIT_MASK_PS_TIMER_C_EARLY 0xff
+#define BIT_PS_TIMER_C_EARLY(x) \
+ (((x) & BIT_MASK_PS_TIMER_C_EARLY) << BIT_SHIFT_PS_TIMER_C_EARLY)
+#define BIT_GET_PS_TIMER_C_EARLY(x) \
+ (((x) >> BIT_SHIFT_PS_TIMER_C_EARLY) & BIT_MASK_PS_TIMER_C_EARLY)
+
+/* 2 REG_BCN_PSR_RPT2 (Offset 0x1600) */
+
+#define BIT_SHIFT_DTIM_CNT2 24
+#define BIT_MASK_DTIM_CNT2 0xff
+#define BIT_DTIM_CNT2(x) (((x) & BIT_MASK_DTIM_CNT2) << BIT_SHIFT_DTIM_CNT2)
+#define BIT_GET_DTIM_CNT2(x) (((x) >> BIT_SHIFT_DTIM_CNT2) & BIT_MASK_DTIM_CNT2)
+
+#define BIT_SHIFT_DTIM_PERIOD2 16
+#define BIT_MASK_DTIM_PERIOD2 0xff
+#define BIT_DTIM_PERIOD2(x) \
+ (((x) & BIT_MASK_DTIM_PERIOD2) << BIT_SHIFT_DTIM_PERIOD2)
+#define BIT_GET_DTIM_PERIOD2(x) \
+ (((x) >> BIT_SHIFT_DTIM_PERIOD2) & BIT_MASK_DTIM_PERIOD2)
+
+#define BIT_DTIM2 BIT(15)
+#define BIT_TIM2 BIT(14)
+
+#define BIT_SHIFT_PS_AID_2 0
+#define BIT_MASK_PS_AID_2 0x7ff
+#define BIT_PS_AID_2(x) (((x) & BIT_MASK_PS_AID_2) << BIT_SHIFT_PS_AID_2)
+#define BIT_GET_PS_AID_2(x) (((x) >> BIT_SHIFT_PS_AID_2) & BIT_MASK_PS_AID_2)
+
+/* 2 REG_BCN_PSR_RPT3 (Offset 0x1604) */
+
+#define BIT_SHIFT_DTIM_CNT3 24
+#define BIT_MASK_DTIM_CNT3 0xff
+#define BIT_DTIM_CNT3(x) (((x) & BIT_MASK_DTIM_CNT3) << BIT_SHIFT_DTIM_CNT3)
+#define BIT_GET_DTIM_CNT3(x) (((x) >> BIT_SHIFT_DTIM_CNT3) & BIT_MASK_DTIM_CNT3)
+
+#define BIT_SHIFT_DTIM_PERIOD3 16
+#define BIT_MASK_DTIM_PERIOD3 0xff
+#define BIT_DTIM_PERIOD3(x) \
+ (((x) & BIT_MASK_DTIM_PERIOD3) << BIT_SHIFT_DTIM_PERIOD3)
+#define BIT_GET_DTIM_PERIOD3(x) \
+ (((x) >> BIT_SHIFT_DTIM_PERIOD3) & BIT_MASK_DTIM_PERIOD3)
+
+#define BIT_DTIM3 BIT(15)
+#define BIT_TIM3 BIT(14)
+
+#define BIT_SHIFT_PS_AID_3 0
+#define BIT_MASK_PS_AID_3 0x7ff
+#define BIT_PS_AID_3(x) (((x) & BIT_MASK_PS_AID_3) << BIT_SHIFT_PS_AID_3)
+#define BIT_GET_PS_AID_3(x) (((x) >> BIT_SHIFT_PS_AID_3) & BIT_MASK_PS_AID_3)
+
+/* 2 REG_BCN_PSR_RPT4 (Offset 0x1608) */
+
+#define BIT_SHIFT_DTIM_CNT4 24
+#define BIT_MASK_DTIM_CNT4 0xff
+#define BIT_DTIM_CNT4(x) (((x) & BIT_MASK_DTIM_CNT4) << BIT_SHIFT_DTIM_CNT4)
+#define BIT_GET_DTIM_CNT4(x) (((x) >> BIT_SHIFT_DTIM_CNT4) & BIT_MASK_DTIM_CNT4)
+
+#define BIT_SHIFT_DTIM_PERIOD4 16
+#define BIT_MASK_DTIM_PERIOD4 0xff
+#define BIT_DTIM_PERIOD4(x) \
+ (((x) & BIT_MASK_DTIM_PERIOD4) << BIT_SHIFT_DTIM_PERIOD4)
+#define BIT_GET_DTIM_PERIOD4(x) \
+ (((x) >> BIT_SHIFT_DTIM_PERIOD4) & BIT_MASK_DTIM_PERIOD4)
+
+#define BIT_DTIM4 BIT(15)
+#define BIT_TIM4 BIT(14)
+
+#define BIT_SHIFT_PS_AID_4 0
+#define BIT_MASK_PS_AID_4 0x7ff
+#define BIT_PS_AID_4(x) (((x) & BIT_MASK_PS_AID_4) << BIT_SHIFT_PS_AID_4)
+#define BIT_GET_PS_AID_4(x) (((x) >> BIT_SHIFT_PS_AID_4) & BIT_MASK_PS_AID_4)
+
+/* 2 REG_A1_ADDR_MASK (Offset 0x160C) */
+
+#define BIT_SHIFT_A1_ADDR_MASK 0
+#define BIT_MASK_A1_ADDR_MASK 0xffffffffL
+#define BIT_A1_ADDR_MASK(x) \
+ (((x) & BIT_MASK_A1_ADDR_MASK) << BIT_SHIFT_A1_ADDR_MASK)
+#define BIT_GET_A1_ADDR_MASK(x) \
+ (((x) >> BIT_SHIFT_A1_ADDR_MASK) & BIT_MASK_A1_ADDR_MASK)
+
+/* 2 REG_MACID2 (Offset 0x1620) */
+
+#define BIT_SHIFT_MACID2 0
+#define BIT_MASK_MACID2 0xffffffffffffL
+#define BIT_MACID2(x) (((x) & BIT_MASK_MACID2) << BIT_SHIFT_MACID2)
+#define BIT_GET_MACID2(x) (((x) >> BIT_SHIFT_MACID2) & BIT_MASK_MACID2)
+
+/* 2 REG_BSSID2 (Offset 0x1628) */
+
+#define BIT_SHIFT_BSSID2 0
+#define BIT_MASK_BSSID2 0xffffffffffffL
+#define BIT_BSSID2(x) (((x) & BIT_MASK_BSSID2) << BIT_SHIFT_BSSID2)
+#define BIT_GET_BSSID2(x) (((x) >> BIT_SHIFT_BSSID2) & BIT_MASK_BSSID2)
+
+/* 2 REG_MACID3 (Offset 0x1630) */
+
+#define BIT_SHIFT_MACID3 0
+#define BIT_MASK_MACID3 0xffffffffffffL
+#define BIT_MACID3(x) (((x) & BIT_MASK_MACID3) << BIT_SHIFT_MACID3)
+#define BIT_GET_MACID3(x) (((x) >> BIT_SHIFT_MACID3) & BIT_MASK_MACID3)
+
+/* 2 REG_BSSID3 (Offset 0x1638) */
+
+#define BIT_SHIFT_BSSID3 0
+#define BIT_MASK_BSSID3 0xffffffffffffL
+#define BIT_BSSID3(x) (((x) & BIT_MASK_BSSID3) << BIT_SHIFT_BSSID3)
+#define BIT_GET_BSSID3(x) (((x) >> BIT_SHIFT_BSSID3) & BIT_MASK_BSSID3)
+
+/* 2 REG_MACID4 (Offset 0x1640) */
+
+#define BIT_SHIFT_MACID4 0
+#define BIT_MASK_MACID4 0xffffffffffffL
+#define BIT_MACID4(x) (((x) & BIT_MASK_MACID4) << BIT_SHIFT_MACID4)
+#define BIT_GET_MACID4(x) (((x) >> BIT_SHIFT_MACID4) & BIT_MASK_MACID4)
+
+/* 2 REG_BSSID4 (Offset 0x1648) */
+
+#define BIT_SHIFT_BSSID4 0
+#define BIT_MASK_BSSID4 0xffffffffffffL
+#define BIT_BSSID4(x) (((x) & BIT_MASK_BSSID4) << BIT_SHIFT_BSSID4)
+#define BIT_GET_BSSID4(x) (((x) >> BIT_SHIFT_BSSID4) & BIT_MASK_BSSID4)
+
+/* 2 REG_PWRBIT_SETTING (Offset 0x1660) */
+
+#define BIT_CLI3_PWRBIT_OW_EN BIT(7)
+#define BIT_CLI3_PWR_ST BIT(6)
+#define BIT_CLI2_PWRBIT_OW_EN BIT(5)
+#define BIT_CLI2_PWR_ST BIT(4)
+#define BIT_CLI1_PWRBIT_OW_EN BIT(3)
+#define BIT_CLI1_PWR_ST BIT(2)
+#define BIT_CLI0_PWRBIT_OW_EN BIT(1)
+#define BIT_CLI0_PWR_ST BIT(0)
+
+/* 2 REG_WMAC_MU_BF_OPTION (Offset 0x167C) */
+
+#define BIT_WMAC_RESP_NONSTA1_DIS BIT(7)
+
+/* 2 REG_WMAC_MU_BF_OPTION (Offset 0x167C) */
+
+#define BIT_BIT_WMAC_TXMU_ACKPOLICY_EN BIT(6)
+
+/* 2 REG_WMAC_MU_BF_OPTION (Offset 0x167C) */
+
+#define BIT_SHIFT_WMAC_TXMU_ACKPOLICY 4
+#define BIT_MASK_WMAC_TXMU_ACKPOLICY 0x3
+#define BIT_WMAC_TXMU_ACKPOLICY(x) \
+ (((x) & BIT_MASK_WMAC_TXMU_ACKPOLICY) << BIT_SHIFT_WMAC_TXMU_ACKPOLICY)
+#define BIT_GET_WMAC_TXMU_ACKPOLICY(x) \
+ (((x) >> BIT_SHIFT_WMAC_TXMU_ACKPOLICY) & BIT_MASK_WMAC_TXMU_ACKPOLICY)
+
+#define BIT_SHIFT_WMAC_MU_BFEE_PORT_SEL 1
+#define BIT_MASK_WMAC_MU_BFEE_PORT_SEL 0x7
+#define BIT_WMAC_MU_BFEE_PORT_SEL(x) \
+ (((x) & BIT_MASK_WMAC_MU_BFEE_PORT_SEL) \
+ << BIT_SHIFT_WMAC_MU_BFEE_PORT_SEL)
+#define BIT_GET_WMAC_MU_BFEE_PORT_SEL(x) \
+ (((x) >> BIT_SHIFT_WMAC_MU_BFEE_PORT_SEL) & \
+ BIT_MASK_WMAC_MU_BFEE_PORT_SEL)
+
+#define BIT_WMAC_MU_BFEE_DIS BIT(0)
+
+/* 2 REG_WMAC_PAUSE_BB_CLR_TH (Offset 0x167D) */
+
+#define BIT_SHIFT_WMAC_PAUSE_BB_CLR_TH 0
+#define BIT_MASK_WMAC_PAUSE_BB_CLR_TH 0xff
+#define BIT_WMAC_PAUSE_BB_CLR_TH(x) \
+ (((x) & BIT_MASK_WMAC_PAUSE_BB_CLR_TH) \
+ << BIT_SHIFT_WMAC_PAUSE_BB_CLR_TH)
+#define BIT_GET_WMAC_PAUSE_BB_CLR_TH(x) \
+ (((x) >> BIT_SHIFT_WMAC_PAUSE_BB_CLR_TH) & \
+ BIT_MASK_WMAC_PAUSE_BB_CLR_TH)
+
+/* 2 REG_WMAC_MU_ARB (Offset 0x167E) */
+
+#define BIT_WMAC_ARB_HW_ADAPT_EN BIT(7)
+#define BIT_WMAC_ARB_SW_EN BIT(6)
+
+#define BIT_SHIFT_WMAC_ARB_SW_STATE 0
+#define BIT_MASK_WMAC_ARB_SW_STATE 0x3f
+#define BIT_WMAC_ARB_SW_STATE(x) \
+ (((x) & BIT_MASK_WMAC_ARB_SW_STATE) << BIT_SHIFT_WMAC_ARB_SW_STATE)
+#define BIT_GET_WMAC_ARB_SW_STATE(x) \
+ (((x) >> BIT_SHIFT_WMAC_ARB_SW_STATE) & BIT_MASK_WMAC_ARB_SW_STATE)
+
+/* 2 REG_WMAC_MU_OPTION (Offset 0x167F) */
+
+#define BIT_SHIFT_WMAC_MU_DBGSEL 5
+#define BIT_MASK_WMAC_MU_DBGSEL 0x3
+#define BIT_WMAC_MU_DBGSEL(x) \
+ (((x) & BIT_MASK_WMAC_MU_DBGSEL) << BIT_SHIFT_WMAC_MU_DBGSEL)
+#define BIT_GET_WMAC_MU_DBGSEL(x) \
+ (((x) >> BIT_SHIFT_WMAC_MU_DBGSEL) & BIT_MASK_WMAC_MU_DBGSEL)
+
+#define BIT_SHIFT_WMAC_MU_CPRD_TIMEOUT 0
+#define BIT_MASK_WMAC_MU_CPRD_TIMEOUT 0x1f
+#define BIT_WMAC_MU_CPRD_TIMEOUT(x) \
+ (((x) & BIT_MASK_WMAC_MU_CPRD_TIMEOUT) \
+ << BIT_SHIFT_WMAC_MU_CPRD_TIMEOUT)
+#define BIT_GET_WMAC_MU_CPRD_TIMEOUT(x) \
+ (((x) >> BIT_SHIFT_WMAC_MU_CPRD_TIMEOUT) & \
+ BIT_MASK_WMAC_MU_CPRD_TIMEOUT)
+
+/* 2 REG_WMAC_MU_BF_CTL (Offset 0x1680) */
+
+#define BIT_WMAC_INVLD_BFPRT_CHK BIT(15)
+#define BIT_WMAC_RETXBFRPTSEQ_UPD BIT(14)
+
+#define BIT_SHIFT_WMAC_MU_BFRPTSEG_SEL 12
+#define BIT_MASK_WMAC_MU_BFRPTSEG_SEL 0x3
+#define BIT_WMAC_MU_BFRPTSEG_SEL(x) \
+ (((x) & BIT_MASK_WMAC_MU_BFRPTSEG_SEL) \
+ << BIT_SHIFT_WMAC_MU_BFRPTSEG_SEL)
+#define BIT_GET_WMAC_MU_BFRPTSEG_SEL(x) \
+ (((x) >> BIT_SHIFT_WMAC_MU_BFRPTSEG_SEL) & \
+ BIT_MASK_WMAC_MU_BFRPTSEG_SEL)
+
+#define BIT_SHIFT_WMAC_MU_BF_MYAID 0
+#define BIT_MASK_WMAC_MU_BF_MYAID 0xfff
+#define BIT_WMAC_MU_BF_MYAID(x) \
+ (((x) & BIT_MASK_WMAC_MU_BF_MYAID) << BIT_SHIFT_WMAC_MU_BF_MYAID)
+#define BIT_GET_WMAC_MU_BF_MYAID(x) \
+ (((x) >> BIT_SHIFT_WMAC_MU_BF_MYAID) & BIT_MASK_WMAC_MU_BF_MYAID)
+
+#define BIT_SHIFT_BFRPT_PARA 0
+#define BIT_MASK_BFRPT_PARA 0xfff
+#define BIT_BFRPT_PARA(x) (((x) & BIT_MASK_BFRPT_PARA) << BIT_SHIFT_BFRPT_PARA)
+#define BIT_GET_BFRPT_PARA(x) \
+ (((x) >> BIT_SHIFT_BFRPT_PARA) & BIT_MASK_BFRPT_PARA)
+
+/* 2 REG_WMAC_MU_BFRPT_PARA (Offset 0x1682) */
+
+#define BIT_SHIFT_BIT_BFRPT_PARA_USERID_SEL 12
+#define BIT_MASK_BIT_BFRPT_PARA_USERID_SEL 0x7
+#define BIT_BIT_BFRPT_PARA_USERID_SEL(x) \
+ (((x) & BIT_MASK_BIT_BFRPT_PARA_USERID_SEL) \
+ << BIT_SHIFT_BIT_BFRPT_PARA_USERID_SEL)
+#define BIT_GET_BIT_BFRPT_PARA_USERID_SEL(x) \
+ (((x) >> BIT_SHIFT_BIT_BFRPT_PARA_USERID_SEL) & \
+ BIT_MASK_BIT_BFRPT_PARA_USERID_SEL)
+
+/* 2 REG_WMAC_ASSOCIATED_MU_BFMEE2 (Offset 0x1684) */
+
+#define BIT_STATUS_BFEE2 BIT(10)
+#define BIT_WMAC_MU_BFEE2_EN BIT(9)
+
+#define BIT_SHIFT_WMAC_MU_BFEE2_AID 0
+#define BIT_MASK_WMAC_MU_BFEE2_AID 0x1ff
+#define BIT_WMAC_MU_BFEE2_AID(x) \
+ (((x) & BIT_MASK_WMAC_MU_BFEE2_AID) << BIT_SHIFT_WMAC_MU_BFEE2_AID)
+#define BIT_GET_WMAC_MU_BFEE2_AID(x) \
+ (((x) >> BIT_SHIFT_WMAC_MU_BFEE2_AID) & BIT_MASK_WMAC_MU_BFEE2_AID)
+
+/* 2 REG_WMAC_ASSOCIATED_MU_BFMEE3 (Offset 0x1686) */
+
+#define BIT_STATUS_BFEE3 BIT(10)
+#define BIT_WMAC_MU_BFEE3_EN BIT(9)
+
+#define BIT_SHIFT_WMAC_MU_BFEE3_AID 0
+#define BIT_MASK_WMAC_MU_BFEE3_AID 0x1ff
+#define BIT_WMAC_MU_BFEE3_AID(x) \
+ (((x) & BIT_MASK_WMAC_MU_BFEE3_AID) << BIT_SHIFT_WMAC_MU_BFEE3_AID)
+#define BIT_GET_WMAC_MU_BFEE3_AID(x) \
+ (((x) >> BIT_SHIFT_WMAC_MU_BFEE3_AID) & BIT_MASK_WMAC_MU_BFEE3_AID)
+
+/* 2 REG_WMAC_ASSOCIATED_MU_BFMEE4 (Offset 0x1688) */
+
+#define BIT_STATUS_BFEE4 BIT(10)
+#define BIT_WMAC_MU_BFEE4_EN BIT(9)
+
+#define BIT_SHIFT_WMAC_MU_BFEE4_AID 0
+#define BIT_MASK_WMAC_MU_BFEE4_AID 0x1ff
+#define BIT_WMAC_MU_BFEE4_AID(x) \
+ (((x) & BIT_MASK_WMAC_MU_BFEE4_AID) << BIT_SHIFT_WMAC_MU_BFEE4_AID)
+#define BIT_GET_WMAC_MU_BFEE4_AID(x) \
+ (((x) >> BIT_SHIFT_WMAC_MU_BFEE4_AID) & BIT_MASK_WMAC_MU_BFEE4_AID)
+
+/* 2 REG_WMAC_ASSOCIATED_MU_BFMEE5 (Offset 0x168A) */
+
+#define BIT_R_WMAC_RX_SYNCFIFO_SYNC BIT(55)
+#define BIT_R_WMAC_RXRST_DLY BIT(54)
+#define BIT_R_WMAC_SRCH_TXRPT_REF_DROP BIT(53)
+#define BIT_R_WMAC_SRCH_TXRPT_UA1 BIT(52)
+#define BIT_STATUS_BFEE5 BIT(10)
+
+/* 2 REG_WMAC_ASSOCIATED_MU_BFMEE5 (Offset 0x168A) */
+
+#define BIT_WMAC_MU_BFEE5_EN BIT(9)
+
+#define BIT_SHIFT_WMAC_MU_BFEE5_AID 0
+#define BIT_MASK_WMAC_MU_BFEE5_AID 0x1ff
+#define BIT_WMAC_MU_BFEE5_AID(x) \
+ (((x) & BIT_MASK_WMAC_MU_BFEE5_AID) << BIT_SHIFT_WMAC_MU_BFEE5_AID)
+#define BIT_GET_WMAC_MU_BFEE5_AID(x) \
+ (((x) >> BIT_SHIFT_WMAC_MU_BFEE5_AID) & BIT_MASK_WMAC_MU_BFEE5_AID)
+
+/* 2 REG_WMAC_ASSOCIATED_MU_BFMEE6 (Offset 0x168C) */
+
+#define BIT_STATUS_BFEE6 BIT(10)
+#define BIT_WMAC_MU_BFEE6_EN BIT(9)
+
+#define BIT_SHIFT_WMAC_MU_BFEE6_AID 0
+#define BIT_MASK_WMAC_MU_BFEE6_AID 0x1ff
+#define BIT_WMAC_MU_BFEE6_AID(x) \
+ (((x) & BIT_MASK_WMAC_MU_BFEE6_AID) << BIT_SHIFT_WMAC_MU_BFEE6_AID)
+#define BIT_GET_WMAC_MU_BFEE6_AID(x) \
+ (((x) >> BIT_SHIFT_WMAC_MU_BFEE6_AID) & BIT_MASK_WMAC_MU_BFEE6_AID)
+
+/* 2 REG_WMAC_ASSOCIATED_MU_BFMEE7 (Offset 0x168E) */
+
+#define BIT_BIT_STATUS_BFEE4 BIT(10)
+#define BIT_WMAC_MU_BFEE7_EN BIT(9)
+
+#define BIT_SHIFT_WMAC_MU_BFEE7_AID 0
+#define BIT_MASK_WMAC_MU_BFEE7_AID 0x1ff
+#define BIT_WMAC_MU_BFEE7_AID(x) \
+ (((x) & BIT_MASK_WMAC_MU_BFEE7_AID) << BIT_SHIFT_WMAC_MU_BFEE7_AID)
+#define BIT_GET_WMAC_MU_BFEE7_AID(x) \
+ (((x) >> BIT_SHIFT_WMAC_MU_BFEE7_AID) & BIT_MASK_WMAC_MU_BFEE7_AID)
+
+/* 2 REG_WMAC_BB_STOP_RX_COUNTER (Offset 0x1690) */
+
+#define BIT_RST_ALL_COUNTER BIT(31)
+
+#define BIT_SHIFT_ABORT_RX_VBON_COUNTER 16
+#define BIT_MASK_ABORT_RX_VBON_COUNTER 0xff
+#define BIT_ABORT_RX_VBON_COUNTER(x) \
+ (((x) & BIT_MASK_ABORT_RX_VBON_COUNTER) \
+ << BIT_SHIFT_ABORT_RX_VBON_COUNTER)
+#define BIT_GET_ABORT_RX_VBON_COUNTER(x) \
+ (((x) >> BIT_SHIFT_ABORT_RX_VBON_COUNTER) & \
+ BIT_MASK_ABORT_RX_VBON_COUNTER)
+
+#define BIT_SHIFT_ABORT_RX_RDRDY_COUNTER 8
+#define BIT_MASK_ABORT_RX_RDRDY_COUNTER 0xff
+#define BIT_ABORT_RX_RDRDY_COUNTER(x) \
+ (((x) & BIT_MASK_ABORT_RX_RDRDY_COUNTER) \
+ << BIT_SHIFT_ABORT_RX_RDRDY_COUNTER)
+#define BIT_GET_ABORT_RX_RDRDY_COUNTER(x) \
+ (((x) >> BIT_SHIFT_ABORT_RX_RDRDY_COUNTER) & \
+ BIT_MASK_ABORT_RX_RDRDY_COUNTER)
+
+#define BIT_SHIFT_VBON_EARLY_FALLING_COUNTER 0
+#define BIT_MASK_VBON_EARLY_FALLING_COUNTER 0xff
+#define BIT_VBON_EARLY_FALLING_COUNTER(x) \
+ (((x) & BIT_MASK_VBON_EARLY_FALLING_COUNTER) \
+ << BIT_SHIFT_VBON_EARLY_FALLING_COUNTER)
+#define BIT_GET_VBON_EARLY_FALLING_COUNTER(x) \
+ (((x) >> BIT_SHIFT_VBON_EARLY_FALLING_COUNTER) & \
+ BIT_MASK_VBON_EARLY_FALLING_COUNTER)
+
+/* 2 REG_WMAC_PLCP_MONITOR (Offset 0x1694) */
+
+#define BIT_WMAC_PLCP_TRX_SEL BIT(31)
+
+#define BIT_SHIFT_WMAC_PLCP_RDSIG_SEL 28
+#define BIT_MASK_WMAC_PLCP_RDSIG_SEL 0x7
+#define BIT_WMAC_PLCP_RDSIG_SEL(x) \
+ (((x) & BIT_MASK_WMAC_PLCP_RDSIG_SEL) << BIT_SHIFT_WMAC_PLCP_RDSIG_SEL)
+#define BIT_GET_WMAC_PLCP_RDSIG_SEL(x) \
+ (((x) >> BIT_SHIFT_WMAC_PLCP_RDSIG_SEL) & BIT_MASK_WMAC_PLCP_RDSIG_SEL)
+
+#define BIT_SHIFT_WMAC_RATE_IDX 24
+#define BIT_MASK_WMAC_RATE_IDX 0xf
+#define BIT_WMAC_RATE_IDX(x) \
+ (((x) & BIT_MASK_WMAC_RATE_IDX) << BIT_SHIFT_WMAC_RATE_IDX)
+#define BIT_GET_WMAC_RATE_IDX(x) \
+ (((x) >> BIT_SHIFT_WMAC_RATE_IDX) & BIT_MASK_WMAC_RATE_IDX)
+
+#define BIT_SHIFT_WMAC_PLCP_RDSIG 0
+#define BIT_MASK_WMAC_PLCP_RDSIG 0xffffff
+#define BIT_WMAC_PLCP_RDSIG(x) \
+ (((x) & BIT_MASK_WMAC_PLCP_RDSIG) << BIT_SHIFT_WMAC_PLCP_RDSIG)
+#define BIT_GET_WMAC_PLCP_RDSIG(x) \
+ (((x) >> BIT_SHIFT_WMAC_PLCP_RDSIG) & BIT_MASK_WMAC_PLCP_RDSIG)
+
+/* 2 REG_WMAC_PLCP_MONITOR_MUTX (Offset 0x1698) */
+
+#define BIT_WMAC_MUTX_IDX BIT(24)
+
+/* 2 REG_TRANSMIT_ADDRSS_0 (Offset 0x16A0) */
+
+#define BIT_SHIFT_TA0 0
+#define BIT_MASK_TA0 0xffffffffffffL
+#define BIT_TA0(x) (((x) & BIT_MASK_TA0) << BIT_SHIFT_TA0)
+#define BIT_GET_TA0(x) (((x) >> BIT_SHIFT_TA0) & BIT_MASK_TA0)
+
+/* 2 REG_TRANSMIT_ADDRSS_1 (Offset 0x16A8) */
+
+#define BIT_SHIFT_TA1 0
+#define BIT_MASK_TA1 0xffffffffffffL
+#define BIT_TA1(x) (((x) & BIT_MASK_TA1) << BIT_SHIFT_TA1)
+#define BIT_GET_TA1(x) (((x) >> BIT_SHIFT_TA1) & BIT_MASK_TA1)
+
+/* 2 REG_TRANSMIT_ADDRSS_2 (Offset 0x16B0) */
+
+#define BIT_SHIFT_TA2 0
+#define BIT_MASK_TA2 0xffffffffffffL
+#define BIT_TA2(x) (((x) & BIT_MASK_TA2) << BIT_SHIFT_TA2)
+#define BIT_GET_TA2(x) (((x) >> BIT_SHIFT_TA2) & BIT_MASK_TA2)
+
+/* 2 REG_TRANSMIT_ADDRSS_3 (Offset 0x16B8) */
+
+#define BIT_SHIFT_TA3 0
+#define BIT_MASK_TA3 0xffffffffffffL
+#define BIT_TA3(x) (((x) & BIT_MASK_TA3) << BIT_SHIFT_TA3)
+#define BIT_GET_TA3(x) (((x) >> BIT_SHIFT_TA3) & BIT_MASK_TA3)
+
+/* 2 REG_TRANSMIT_ADDRSS_4 (Offset 0x16C0) */
+
+#define BIT_SHIFT_TA4 0
+#define BIT_MASK_TA4 0xffffffffffffL
+#define BIT_TA4(x) (((x) & BIT_MASK_TA4) << BIT_SHIFT_TA4)
+#define BIT_GET_TA4(x) (((x) >> BIT_SHIFT_TA4) & BIT_MASK_TA4)
+
+/* 2 REG_WL2LTECOEX_INDIRECT_ACCESS_CTRL_V1 (Offset 0x1700) */
+
+#define BIT_LTECOEX_ACCESS_START_V1 BIT(31)
+#define BIT_LTECOEX_WRITE_MODE_V1 BIT(30)
+#define BIT_LTECOEX_READY_BIT_V1 BIT(29)
+
+#define BIT_SHIFT_WRITE_BYTE_EN_V1 16
+#define BIT_MASK_WRITE_BYTE_EN_V1 0xf
+#define BIT_WRITE_BYTE_EN_V1(x) \
+ (((x) & BIT_MASK_WRITE_BYTE_EN_V1) << BIT_SHIFT_WRITE_BYTE_EN_V1)
+#define BIT_GET_WRITE_BYTE_EN_V1(x) \
+ (((x) >> BIT_SHIFT_WRITE_BYTE_EN_V1) & BIT_MASK_WRITE_BYTE_EN_V1)
+
+#define BIT_SHIFT_LTECOEX_REG_ADDR_V1 0
+#define BIT_MASK_LTECOEX_REG_ADDR_V1 0xffff
+#define BIT_LTECOEX_REG_ADDR_V1(x) \
+ (((x) & BIT_MASK_LTECOEX_REG_ADDR_V1) << BIT_SHIFT_LTECOEX_REG_ADDR_V1)
+#define BIT_GET_LTECOEX_REG_ADDR_V1(x) \
+ (((x) >> BIT_SHIFT_LTECOEX_REG_ADDR_V1) & BIT_MASK_LTECOEX_REG_ADDR_V1)
+
+/* 2 REG_WL2LTECOEX_INDIRECT_ACCESS_WRITE_DATA_V1 (Offset 0x1704) */
+
+#define BIT_SHIFT_LTECOEX_W_DATA_V1 0
+#define BIT_MASK_LTECOEX_W_DATA_V1 0xffffffffL
+#define BIT_LTECOEX_W_DATA_V1(x) \
+ (((x) & BIT_MASK_LTECOEX_W_DATA_V1) << BIT_SHIFT_LTECOEX_W_DATA_V1)
+#define BIT_GET_LTECOEX_W_DATA_V1(x) \
+ (((x) >> BIT_SHIFT_LTECOEX_W_DATA_V1) & BIT_MASK_LTECOEX_W_DATA_V1)
+
+/* 2 REG_WL2LTECOEX_INDIRECT_ACCESS_READ_DATA_V1 (Offset 0x1708) */
+
+#define BIT_SHIFT_LTECOEX_R_DATA_V1 0
+#define BIT_MASK_LTECOEX_R_DATA_V1 0xffffffffL
+#define BIT_LTECOEX_R_DATA_V1(x) \
+ (((x) & BIT_MASK_LTECOEX_R_DATA_V1) << BIT_SHIFT_LTECOEX_R_DATA_V1)
+#define BIT_GET_LTECOEX_R_DATA_V1(x) \
+ (((x) >> BIT_SHIFT_LTECOEX_R_DATA_V1) & BIT_MASK_LTECOEX_R_DATA_V1)
+
+#endif /* __RTL_WLAN_BITDEF_H__ */
diff --git a/drivers/staging/rtlwifi/halmac/halmac_bit_8822b.h b/drivers/staging/rtlwifi/halmac/halmac_bit_8822b.h
new file mode 100644
index 0000000..7d02553
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_bit_8822b.h
@@ -0,0 +1,12103 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __INC_HALMAC_BIT_8822B_H
+#define __INC_HALMAC_BIT_8822B_H
+
+#define CPU_OPT_WIDTH 0x1F
+
+/* 2 REG_NOT_VALID_8822B */
+
+/* 2 REG_SYS_ISO_CTRL_8822B */
+#define BIT_PWC_EV12V_8822B BIT(15)
+#define BIT_PWC_EV25V_8822B BIT(14)
+#define BIT_PA33V_EN_8822B BIT(13)
+#define BIT_PA12V_EN_8822B BIT(12)
+#define BIT_UA33V_EN_8822B BIT(11)
+#define BIT_UA12V_EN_8822B BIT(10)
+#define BIT_ISO_RFDIO_8822B BIT(9)
+#define BIT_ISO_EB2CORE_8822B BIT(8)
+#define BIT_ISO_DIOE_8822B BIT(7)
+#define BIT_ISO_WLPON2PP_8822B BIT(6)
+#define BIT_ISO_IP2MAC_WA2PP_8822B BIT(5)
+#define BIT_ISO_PD2CORE_8822B BIT(4)
+#define BIT_ISO_PA2PCIE_8822B BIT(3)
+#define BIT_ISO_UD2CORE_8822B BIT(2)
+#define BIT_ISO_UA2USB_8822B BIT(1)
+#define BIT_ISO_WD2PP_8822B BIT(0)
+
+/* 2 REG_SYS_FUNC_EN_8822B */
+#define BIT_FEN_MREGEN_8822B BIT(15)
+#define BIT_FEN_HWPDN_8822B BIT(14)
+#define BIT_EN_25_1_8822B BIT(13)
+#define BIT_FEN_ELDR_8822B BIT(12)
+#define BIT_FEN_DCORE_8822B BIT(11)
+#define BIT_FEN_CPUEN_8822B BIT(10)
+#define BIT_FEN_DIOE_8822B BIT(9)
+#define BIT_FEN_PCIED_8822B BIT(8)
+#define BIT_FEN_PPLL_8822B BIT(7)
+#define BIT_FEN_PCIEA_8822B BIT(6)
+#define BIT_FEN_DIO_PCIE_8822B BIT(5)
+#define BIT_FEN_USBD_8822B BIT(4)
+#define BIT_FEN_UPLL_8822B BIT(3)
+#define BIT_FEN_USBA_8822B BIT(2)
+#define BIT_FEN_BB_GLB_RSTN_8822B BIT(1)
+#define BIT_FEN_BBRSTB_8822B BIT(0)
+
+/* 2 REG_SYS_PW_CTRL_8822B */
+#define BIT_SOP_EABM_8822B BIT(31)
+#define BIT_SOP_ACKF_8822B BIT(30)
+#define BIT_SOP_ERCK_8822B BIT(29)
+#define BIT_SOP_ESWR_8822B BIT(28)
+#define BIT_SOP_PWMM_8822B BIT(27)
+#define BIT_SOP_EECK_8822B BIT(26)
+#define BIT_SOP_EXTL_8822B BIT(24)
+#define BIT_SYM_OP_RING_12M_8822B BIT(22)
+#define BIT_ROP_SWPR_8822B BIT(21)
+#define BIT_DIS_HW_LPLDM_8822B BIT(20)
+#define BIT_OPT_SWRST_WLMCU_8822B BIT(19)
+#define BIT_RDY_SYSPWR_8822B BIT(17)
+#define BIT_EN_WLON_8822B BIT(16)
+#define BIT_APDM_HPDN_8822B BIT(15)
+#define BIT_AFSM_PCIE_SUS_EN_8822B BIT(12)
+#define BIT_AFSM_WLSUS_EN_8822B BIT(11)
+#define BIT_APFM_SWLPS_8822B BIT(10)
+#define BIT_APFM_OFFMAC_8822B BIT(9)
+#define BIT_APFN_ONMAC_8822B BIT(8)
+#define BIT_CHIP_PDN_EN_8822B BIT(7)
+#define BIT_RDY_MACDIS_8822B BIT(6)
+#define BIT_RING_CLK_12M_EN_8822B BIT(4)
+#define BIT_PFM_WOWL_8822B BIT(3)
+#define BIT_PFM_LDKP_8822B BIT(2)
+#define BIT_WL_HCI_ALD_8822B BIT(1)
+#define BIT_PFM_LDALL_8822B BIT(0)
+
+/* 2 REG_SYS_CLK_CTRL_8822B */
+#define BIT_LDO_DUMMY_8822B BIT(15)
+#define BIT_CPU_CLK_EN_8822B BIT(14)
+#define BIT_SYMREG_CLK_EN_8822B BIT(13)
+#define BIT_HCI_CLK_EN_8822B BIT(12)
+#define BIT_MAC_CLK_EN_8822B BIT(11)
+#define BIT_SEC_CLK_EN_8822B BIT(10)
+#define BIT_PHY_SSC_RSTB_8822B BIT(9)
+#define BIT_EXT_32K_EN_8822B BIT(8)
+#define BIT_WL_CLK_TEST_8822B BIT(7)
+#define BIT_OP_SPS_PWM_EN_8822B BIT(6)
+#define BIT_LOADER_CLK_EN_8822B BIT(5)
+#define BIT_MACSLP_8822B BIT(4)
+#define BIT_WAKEPAD_EN_8822B BIT(3)
+#define BIT_ROMD16V_EN_8822B BIT(2)
+#define BIT_CKANA12M_EN_8822B BIT(1)
+#define BIT_CNTD16V_EN_8822B BIT(0)
+
+/* 2 REG_SYS_EEPROM_CTRL_8822B */
+
+#define BIT_SHIFT_VPDIDX_8822B 8
+#define BIT_MASK_VPDIDX_8822B 0xff
+#define BIT_VPDIDX_8822B(x) \
+ (((x) & BIT_MASK_VPDIDX_8822B) << BIT_SHIFT_VPDIDX_8822B)
+#define BIT_GET_VPDIDX_8822B(x) \
+ (((x) >> BIT_SHIFT_VPDIDX_8822B) & BIT_MASK_VPDIDX_8822B)
+
+#define BIT_SHIFT_EEM1_0_8822B 6
+#define BIT_MASK_EEM1_0_8822B 0x3
+#define BIT_EEM1_0_8822B(x) \
+ (((x) & BIT_MASK_EEM1_0_8822B) << BIT_SHIFT_EEM1_0_8822B)
+#define BIT_GET_EEM1_0_8822B(x) \
+ (((x) >> BIT_SHIFT_EEM1_0_8822B) & BIT_MASK_EEM1_0_8822B)
+
+#define BIT_AUTOLOAD_SUS_8822B BIT(5)
+#define BIT_EERPOMSEL_8822B BIT(4)
+#define BIT_EECS_V1_8822B BIT(3)
+#define BIT_EESK_V1_8822B BIT(2)
+#define BIT_EEDI_V1_8822B BIT(1)
+#define BIT_EEDO_V1_8822B BIT(0)
+
+/* 2 REG_EE_VPD_8822B */
+
+#define BIT_SHIFT_VPD_DATA_8822B 0
+#define BIT_MASK_VPD_DATA_8822B 0xffffffffL
+#define BIT_VPD_DATA_8822B(x) \
+ (((x) & BIT_MASK_VPD_DATA_8822B) << BIT_SHIFT_VPD_DATA_8822B)
+#define BIT_GET_VPD_DATA_8822B(x) \
+ (((x) >> BIT_SHIFT_VPD_DATA_8822B) & BIT_MASK_VPD_DATA_8822B)
+
+/* 2 REG_SYS_SWR_CTRL1_8822B */
+#define BIT_C2_L_BIT0_8822B BIT(31)
+
+#define BIT_SHIFT_C1_L_8822B 29
+#define BIT_MASK_C1_L_8822B 0x3
+#define BIT_C1_L_8822B(x) (((x) & BIT_MASK_C1_L_8822B) << BIT_SHIFT_C1_L_8822B)
+#define BIT_GET_C1_L_8822B(x) \
+ (((x) >> BIT_SHIFT_C1_L_8822B) & BIT_MASK_C1_L_8822B)
+
+#define BIT_SHIFT_REG_FREQ_L_8822B 25
+#define BIT_MASK_REG_FREQ_L_8822B 0x7
+#define BIT_REG_FREQ_L_8822B(x) \
+ (((x) & BIT_MASK_REG_FREQ_L_8822B) << BIT_SHIFT_REG_FREQ_L_8822B)
+#define BIT_GET_REG_FREQ_L_8822B(x) \
+ (((x) >> BIT_SHIFT_REG_FREQ_L_8822B) & BIT_MASK_REG_FREQ_L_8822B)
+
+#define BIT_REG_EN_DUTY_8822B BIT(24)
+
+#define BIT_SHIFT_REG_MODE_8822B 22
+#define BIT_MASK_REG_MODE_8822B 0x3
+#define BIT_REG_MODE_8822B(x) \
+ (((x) & BIT_MASK_REG_MODE_8822B) << BIT_SHIFT_REG_MODE_8822B)
+#define BIT_GET_REG_MODE_8822B(x) \
+ (((x) >> BIT_SHIFT_REG_MODE_8822B) & BIT_MASK_REG_MODE_8822B)
+
+#define BIT_REG_EN_SP_8822B BIT(21)
+#define BIT_REG_AUTO_L_8822B BIT(20)
+#define BIT_SW18_SELD_BIT0_8822B BIT(19)
+#define BIT_SW18_POWOCP_8822B BIT(18)
+
+#define BIT_SHIFT_OCP_L1_8822B 15
+#define BIT_MASK_OCP_L1_8822B 0x7
+#define BIT_OCP_L1_8822B(x) \
+ (((x) & BIT_MASK_OCP_L1_8822B) << BIT_SHIFT_OCP_L1_8822B)
+#define BIT_GET_OCP_L1_8822B(x) \
+ (((x) >> BIT_SHIFT_OCP_L1_8822B) & BIT_MASK_OCP_L1_8822B)
+
+#define BIT_SHIFT_CF_L_8822B 13
+#define BIT_MASK_CF_L_8822B 0x3
+#define BIT_CF_L_8822B(x) (((x) & BIT_MASK_CF_L_8822B) << BIT_SHIFT_CF_L_8822B)
+#define BIT_GET_CF_L_8822B(x) \
+ (((x) >> BIT_SHIFT_CF_L_8822B) & BIT_MASK_CF_L_8822B)
+
+#define BIT_SW18_FPWM_8822B BIT(11)
+#define BIT_SW18_SWEN_8822B BIT(9)
+#define BIT_SW18_LDEN_8822B BIT(8)
+#define BIT_MAC_ID_EN_8822B BIT(7)
+#define BIT_AFE_BGEN_8822B BIT(0)
+
+/* 2 REG_SYS_SWR_CTRL2_8822B */
+#define BIT_POW_ZCD_L_8822B BIT(31)
+#define BIT_AUTOZCD_L_8822B BIT(30)
+
+#define BIT_SHIFT_REG_DELAY_8822B 28
+#define BIT_MASK_REG_DELAY_8822B 0x3
+#define BIT_REG_DELAY_8822B(x) \
+ (((x) & BIT_MASK_REG_DELAY_8822B) << BIT_SHIFT_REG_DELAY_8822B)
+#define BIT_GET_REG_DELAY_8822B(x) \
+ (((x) >> BIT_SHIFT_REG_DELAY_8822B) & BIT_MASK_REG_DELAY_8822B)
+
+#define BIT_SHIFT_V15ADJ_L1_V1_8822B 24
+#define BIT_MASK_V15ADJ_L1_V1_8822B 0x7
+#define BIT_V15ADJ_L1_V1_8822B(x) \
+ (((x) & BIT_MASK_V15ADJ_L1_V1_8822B) << BIT_SHIFT_V15ADJ_L1_V1_8822B)
+#define BIT_GET_V15ADJ_L1_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_V15ADJ_L1_V1_8822B) & BIT_MASK_V15ADJ_L1_V1_8822B)
+
+#define BIT_SHIFT_VOL_L1_V1_8822B 20
+#define BIT_MASK_VOL_L1_V1_8822B 0xf
+#define BIT_VOL_L1_V1_8822B(x) \
+ (((x) & BIT_MASK_VOL_L1_V1_8822B) << BIT_SHIFT_VOL_L1_V1_8822B)
+#define BIT_GET_VOL_L1_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_VOL_L1_V1_8822B) & BIT_MASK_VOL_L1_V1_8822B)
+
+#define BIT_SHIFT_IN_L1_V1_8822B 17
+#define BIT_MASK_IN_L1_V1_8822B 0x7
+#define BIT_IN_L1_V1_8822B(x) \
+ (((x) & BIT_MASK_IN_L1_V1_8822B) << BIT_SHIFT_IN_L1_V1_8822B)
+#define BIT_GET_IN_L1_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_IN_L1_V1_8822B) & BIT_MASK_IN_L1_V1_8822B)
+
+#define BIT_SHIFT_TBOX_L1_8822B 15
+#define BIT_MASK_TBOX_L1_8822B 0x3
+#define BIT_TBOX_L1_8822B(x) \
+ (((x) & BIT_MASK_TBOX_L1_8822B) << BIT_SHIFT_TBOX_L1_8822B)
+#define BIT_GET_TBOX_L1_8822B(x) \
+ (((x) >> BIT_SHIFT_TBOX_L1_8822B) & BIT_MASK_TBOX_L1_8822B)
+
+#define BIT_SW18_SEL_8822B BIT(13)
+
+/* 2 REG_NOT_VALID_8822B */
+#define BIT_SW18_SD_8822B BIT(10)
+
+#define BIT_SHIFT_R3_L_8822B 7
+#define BIT_MASK_R3_L_8822B 0x3
+#define BIT_R3_L_8822B(x) (((x) & BIT_MASK_R3_L_8822B) << BIT_SHIFT_R3_L_8822B)
+#define BIT_GET_R3_L_8822B(x) \
+ (((x) >> BIT_SHIFT_R3_L_8822B) & BIT_MASK_R3_L_8822B)
+
+#define BIT_SHIFT_SW18_R2_8822B 5
+#define BIT_MASK_SW18_R2_8822B 0x3
+#define BIT_SW18_R2_8822B(x) \
+ (((x) & BIT_MASK_SW18_R2_8822B) << BIT_SHIFT_SW18_R2_8822B)
+#define BIT_GET_SW18_R2_8822B(x) \
+ (((x) >> BIT_SHIFT_SW18_R2_8822B) & BIT_MASK_SW18_R2_8822B)
+
+#define BIT_SHIFT_SW18_R1_8822B 3
+#define BIT_MASK_SW18_R1_8822B 0x3
+#define BIT_SW18_R1_8822B(x) \
+ (((x) & BIT_MASK_SW18_R1_8822B) << BIT_SHIFT_SW18_R1_8822B)
+#define BIT_GET_SW18_R1_8822B(x) \
+ (((x) >> BIT_SHIFT_SW18_R1_8822B) & BIT_MASK_SW18_R1_8822B)
+
+#define BIT_SHIFT_C3_L_C3_8822B 1
+#define BIT_MASK_C3_L_C3_8822B 0x3
+#define BIT_C3_L_C3_8822B(x) \
+ (((x) & BIT_MASK_C3_L_C3_8822B) << BIT_SHIFT_C3_L_C3_8822B)
+#define BIT_GET_C3_L_C3_8822B(x) \
+ (((x) >> BIT_SHIFT_C3_L_C3_8822B) & BIT_MASK_C3_L_C3_8822B)
+
+#define BIT_C2_L_BIT1_8822B BIT(0)
+
+/* 2 REG_SYS_SWR_CTRL3_8822B */
+#define BIT_SPS18_OCP_DIS_8822B BIT(31)
+
+#define BIT_SHIFT_SPS18_OCP_TH_8822B 16
+#define BIT_MASK_SPS18_OCP_TH_8822B 0x7fff
+#define BIT_SPS18_OCP_TH_8822B(x) \
+ (((x) & BIT_MASK_SPS18_OCP_TH_8822B) << BIT_SHIFT_SPS18_OCP_TH_8822B)
+#define BIT_GET_SPS18_OCP_TH_8822B(x) \
+ (((x) >> BIT_SHIFT_SPS18_OCP_TH_8822B) & BIT_MASK_SPS18_OCP_TH_8822B)
+
+#define BIT_SHIFT_OCP_WINDOW_8822B 0
+#define BIT_MASK_OCP_WINDOW_8822B 0xffff
+#define BIT_OCP_WINDOW_8822B(x) \
+ (((x) & BIT_MASK_OCP_WINDOW_8822B) << BIT_SHIFT_OCP_WINDOW_8822B)
+#define BIT_GET_OCP_WINDOW_8822B(x) \
+ (((x) >> BIT_SHIFT_OCP_WINDOW_8822B) & BIT_MASK_OCP_WINDOW_8822B)
+
+/* 2 REG_RSV_CTRL_8822B */
+#define BIT_HREG_DBG_8822B BIT(23)
+#define BIT_WLMCUIOIF_8822B BIT(8)
+#define BIT_LOCK_ALL_EN_8822B BIT(7)
+#define BIT_R_DIS_PRST_8822B BIT(6)
+#define BIT_WLOCK_1C_B6_8822B BIT(5)
+#define BIT_WLOCK_40_8822B BIT(4)
+#define BIT_WLOCK_08_8822B BIT(3)
+#define BIT_WLOCK_04_8822B BIT(2)
+#define BIT_WLOCK_00_8822B BIT(1)
+#define BIT_WLOCK_ALL_8822B BIT(0)
+
+/* 2 REG_RF_CTRL_8822B */
+#define BIT_RF_SDMRSTB_8822B BIT(2)
+#define BIT_RF_RSTB_8822B BIT(1)
+#define BIT_RF_EN_8822B BIT(0)
+
+/* 2 REG_AFE_LDO_CTRL_8822B */
+
+#define BIT_SHIFT_LPLDH12_RSV_8822B 29
+#define BIT_MASK_LPLDH12_RSV_8822B 0x7
+#define BIT_LPLDH12_RSV_8822B(x) \
+ (((x) & BIT_MASK_LPLDH12_RSV_8822B) << BIT_SHIFT_LPLDH12_RSV_8822B)
+#define BIT_GET_LPLDH12_RSV_8822B(x) \
+ (((x) >> BIT_SHIFT_LPLDH12_RSV_8822B) & BIT_MASK_LPLDH12_RSV_8822B)
+
+#define BIT_LPLDH12_SLP_8822B BIT(28)
+
+#define BIT_SHIFT_LPLDH12_VADJ_8822B 24
+#define BIT_MASK_LPLDH12_VADJ_8822B 0xf
+#define BIT_LPLDH12_VADJ_8822B(x) \
+ (((x) & BIT_MASK_LPLDH12_VADJ_8822B) << BIT_SHIFT_LPLDH12_VADJ_8822B)
+#define BIT_GET_LPLDH12_VADJ_8822B(x) \
+ (((x) >> BIT_SHIFT_LPLDH12_VADJ_8822B) & BIT_MASK_LPLDH12_VADJ_8822B)
+
+#define BIT_LDH12_EN_8822B BIT(16)
+#define BIT_WLBBOFF_BIG_PWC_EN_8822B BIT(14)
+#define BIT_WLBBOFF_SMALL_PWC_EN_8822B BIT(13)
+#define BIT_WLMACOFF_BIG_PWC_EN_8822B BIT(12)
+#define BIT_WLPON_PWC_EN_8822B BIT(11)
+#define BIT_POW_REGU_P1_8822B BIT(10)
+#define BIT_LDOV12W_EN_8822B BIT(8)
+#define BIT_EX_XTAL_DRV_DIGI_8822B BIT(7)
+#define BIT_EX_XTAL_DRV_USB_8822B BIT(6)
+#define BIT_EX_XTAL_DRV_AFE_8822B BIT(5)
+#define BIT_EX_XTAL_DRV_RF2_8822B BIT(4)
+#define BIT_EX_XTAL_DRV_RF1_8822B BIT(3)
+#define BIT_POW_REGU_P0_8822B BIT(2)
+
+/* 2 REG_NOT_VALID_8822B */
+#define BIT_POW_PLL_LDO_8822B BIT(0)
+
+/* 2 REG_AFE_CTRL1_8822B */
+#define BIT_AGPIO_GPE_8822B BIT(31)
+
+#define BIT_SHIFT_XTAL_CAP_XI_8822B 25
+#define BIT_MASK_XTAL_CAP_XI_8822B 0x3f
+#define BIT_XTAL_CAP_XI_8822B(x) \
+ (((x) & BIT_MASK_XTAL_CAP_XI_8822B) << BIT_SHIFT_XTAL_CAP_XI_8822B)
+#define BIT_GET_XTAL_CAP_XI_8822B(x) \
+ (((x) >> BIT_SHIFT_XTAL_CAP_XI_8822B) & BIT_MASK_XTAL_CAP_XI_8822B)
+
+#define BIT_SHIFT_XTAL_DRV_DIGI_8822B 23
+#define BIT_MASK_XTAL_DRV_DIGI_8822B 0x3
+#define BIT_XTAL_DRV_DIGI_8822B(x) \
+ (((x) & BIT_MASK_XTAL_DRV_DIGI_8822B) << BIT_SHIFT_XTAL_DRV_DIGI_8822B)
+#define BIT_GET_XTAL_DRV_DIGI_8822B(x) \
+ (((x) >> BIT_SHIFT_XTAL_DRV_DIGI_8822B) & BIT_MASK_XTAL_DRV_DIGI_8822B)
+
+#define BIT_XTAL_DRV_USB_BIT1_8822B BIT(22)
+
+#define BIT_SHIFT_MAC_CLK_SEL_8822B 20
+#define BIT_MASK_MAC_CLK_SEL_8822B 0x3
+#define BIT_MAC_CLK_SEL_8822B(x) \
+ (((x) & BIT_MASK_MAC_CLK_SEL_8822B) << BIT_SHIFT_MAC_CLK_SEL_8822B)
+#define BIT_GET_MAC_CLK_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_MAC_CLK_SEL_8822B) & BIT_MASK_MAC_CLK_SEL_8822B)
+
+#define BIT_XTAL_DRV_USB_BIT0_8822B BIT(19)
+
+#define BIT_SHIFT_XTAL_DRV_AFE_8822B 17
+#define BIT_MASK_XTAL_DRV_AFE_8822B 0x3
+#define BIT_XTAL_DRV_AFE_8822B(x) \
+ (((x) & BIT_MASK_XTAL_DRV_AFE_8822B) << BIT_SHIFT_XTAL_DRV_AFE_8822B)
+#define BIT_GET_XTAL_DRV_AFE_8822B(x) \
+ (((x) >> BIT_SHIFT_XTAL_DRV_AFE_8822B) & BIT_MASK_XTAL_DRV_AFE_8822B)
+
+#define BIT_SHIFT_XTAL_DRV_RF2_8822B 15
+#define BIT_MASK_XTAL_DRV_RF2_8822B 0x3
+#define BIT_XTAL_DRV_RF2_8822B(x) \
+ (((x) & BIT_MASK_XTAL_DRV_RF2_8822B) << BIT_SHIFT_XTAL_DRV_RF2_8822B)
+#define BIT_GET_XTAL_DRV_RF2_8822B(x) \
+ (((x) >> BIT_SHIFT_XTAL_DRV_RF2_8822B) & BIT_MASK_XTAL_DRV_RF2_8822B)
+
+#define BIT_SHIFT_XTAL_DRV_RF1_8822B 13
+#define BIT_MASK_XTAL_DRV_RF1_8822B 0x3
+#define BIT_XTAL_DRV_RF1_8822B(x) \
+ (((x) & BIT_MASK_XTAL_DRV_RF1_8822B) << BIT_SHIFT_XTAL_DRV_RF1_8822B)
+#define BIT_GET_XTAL_DRV_RF1_8822B(x) \
+ (((x) >> BIT_SHIFT_XTAL_DRV_RF1_8822B) & BIT_MASK_XTAL_DRV_RF1_8822B)
+
+#define BIT_XTAL_DELAY_DIGI_8822B BIT(12)
+#define BIT_XTAL_DELAY_USB_8822B BIT(11)
+#define BIT_XTAL_DELAY_AFE_8822B BIT(10)
+
+#define BIT_SHIFT_XTAL_LDO_VREF_8822B 7
+#define BIT_MASK_XTAL_LDO_VREF_8822B 0x7
+#define BIT_XTAL_LDO_VREF_8822B(x) \
+ (((x) & BIT_MASK_XTAL_LDO_VREF_8822B) << BIT_SHIFT_XTAL_LDO_VREF_8822B)
+#define BIT_GET_XTAL_LDO_VREF_8822B(x) \
+ (((x) >> BIT_SHIFT_XTAL_LDO_VREF_8822B) & BIT_MASK_XTAL_LDO_VREF_8822B)
+
+#define BIT_XTAL_XQSEL_RF_8822B BIT(6)
+#define BIT_XTAL_XQSEL_8822B BIT(5)
+
+#define BIT_SHIFT_XTAL_GMN_V2_8822B 3
+#define BIT_MASK_XTAL_GMN_V2_8822B 0x3
+#define BIT_XTAL_GMN_V2_8822B(x) \
+ (((x) & BIT_MASK_XTAL_GMN_V2_8822B) << BIT_SHIFT_XTAL_GMN_V2_8822B)
+#define BIT_GET_XTAL_GMN_V2_8822B(x) \
+ (((x) >> BIT_SHIFT_XTAL_GMN_V2_8822B) & BIT_MASK_XTAL_GMN_V2_8822B)
+
+#define BIT_SHIFT_XTAL_GMP_V2_8822B 1
+#define BIT_MASK_XTAL_GMP_V2_8822B 0x3
+#define BIT_XTAL_GMP_V2_8822B(x) \
+ (((x) & BIT_MASK_XTAL_GMP_V2_8822B) << BIT_SHIFT_XTAL_GMP_V2_8822B)
+#define BIT_GET_XTAL_GMP_V2_8822B(x) \
+ (((x) >> BIT_SHIFT_XTAL_GMP_V2_8822B) & BIT_MASK_XTAL_GMP_V2_8822B)
+
+#define BIT_XTAL_EN_8822B BIT(0)
+
+/* 2 REG_AFE_CTRL2_8822B */
+
+#define BIT_SHIFT_REG_C3_V4_8822B 30
+#define BIT_MASK_REG_C3_V4_8822B 0x3
+#define BIT_REG_C3_V4_8822B(x) \
+ (((x) & BIT_MASK_REG_C3_V4_8822B) << BIT_SHIFT_REG_C3_V4_8822B)
+#define BIT_GET_REG_C3_V4_8822B(x) \
+ (((x) >> BIT_SHIFT_REG_C3_V4_8822B) & BIT_MASK_REG_C3_V4_8822B)
+
+#define BIT_REG_CP_BIT1_8822B BIT(29)
+
+#define BIT_SHIFT_REG_RS_V4_8822B 26
+#define BIT_MASK_REG_RS_V4_8822B 0x7
+#define BIT_REG_RS_V4_8822B(x) \
+ (((x) & BIT_MASK_REG_RS_V4_8822B) << BIT_SHIFT_REG_RS_V4_8822B)
+#define BIT_GET_REG_RS_V4_8822B(x) \
+ (((x) >> BIT_SHIFT_REG_RS_V4_8822B) & BIT_MASK_REG_RS_V4_8822B)
+
+#define BIT_SHIFT_REG__CS_8822B 24
+#define BIT_MASK_REG__CS_8822B 0x3
+#define BIT_REG__CS_8822B(x) \
+ (((x) & BIT_MASK_REG__CS_8822B) << BIT_SHIFT_REG__CS_8822B)
+#define BIT_GET_REG__CS_8822B(x) \
+ (((x) >> BIT_SHIFT_REG__CS_8822B) & BIT_MASK_REG__CS_8822B)
+
+#define BIT_SHIFT_REG_CP_OFFSET_8822B 21
+#define BIT_MASK_REG_CP_OFFSET_8822B 0x7
+#define BIT_REG_CP_OFFSET_8822B(x) \
+ (((x) & BIT_MASK_REG_CP_OFFSET_8822B) << BIT_SHIFT_REG_CP_OFFSET_8822B)
+#define BIT_GET_REG_CP_OFFSET_8822B(x) \
+ (((x) >> BIT_SHIFT_REG_CP_OFFSET_8822B) & BIT_MASK_REG_CP_OFFSET_8822B)
+
+#define BIT_SHIFT_CP_BIAS_8822B 18
+#define BIT_MASK_CP_BIAS_8822B 0x7
+#define BIT_CP_BIAS_8822B(x) \
+ (((x) & BIT_MASK_CP_BIAS_8822B) << BIT_SHIFT_CP_BIAS_8822B)
+#define BIT_GET_CP_BIAS_8822B(x) \
+ (((x) >> BIT_SHIFT_CP_BIAS_8822B) & BIT_MASK_CP_BIAS_8822B)
+
+#define BIT_REG_IDOUBLE_V2_8822B BIT(17)
+#define BIT_EN_SYN_8822B BIT(16)
+
+#define BIT_SHIFT_MCCO_8822B 14
+#define BIT_MASK_MCCO_8822B 0x3
+#define BIT_MCCO_8822B(x) (((x) & BIT_MASK_MCCO_8822B) << BIT_SHIFT_MCCO_8822B)
+#define BIT_GET_MCCO_8822B(x) \
+ (((x) >> BIT_SHIFT_MCCO_8822B) & BIT_MASK_MCCO_8822B)
+
+#define BIT_SHIFT_REG_LDO_SEL_8822B 12
+#define BIT_MASK_REG_LDO_SEL_8822B 0x3
+#define BIT_REG_LDO_SEL_8822B(x) \
+ (((x) & BIT_MASK_REG_LDO_SEL_8822B) << BIT_SHIFT_REG_LDO_SEL_8822B)
+#define BIT_GET_REG_LDO_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_REG_LDO_SEL_8822B) & BIT_MASK_REG_LDO_SEL_8822B)
+
+#define BIT_REG_KVCO_V2_8822B BIT(10)
+#define BIT_AGPIO_GPO_8822B BIT(9)
+
+#define BIT_SHIFT_AGPIO_DRV_8822B 7
+#define BIT_MASK_AGPIO_DRV_8822B 0x3
+#define BIT_AGPIO_DRV_8822B(x) \
+ (((x) & BIT_MASK_AGPIO_DRV_8822B) << BIT_SHIFT_AGPIO_DRV_8822B)
+#define BIT_GET_AGPIO_DRV_8822B(x) \
+ (((x) >> BIT_SHIFT_AGPIO_DRV_8822B) & BIT_MASK_AGPIO_DRV_8822B)
+
+#define BIT_SHIFT_XTAL_CAP_XO_8822B 1
+#define BIT_MASK_XTAL_CAP_XO_8822B 0x3f
+#define BIT_XTAL_CAP_XO_8822B(x) \
+ (((x) & BIT_MASK_XTAL_CAP_XO_8822B) << BIT_SHIFT_XTAL_CAP_XO_8822B)
+#define BIT_GET_XTAL_CAP_XO_8822B(x) \
+ (((x) >> BIT_SHIFT_XTAL_CAP_XO_8822B) & BIT_MASK_XTAL_CAP_XO_8822B)
+
+#define BIT_POW_PLL_8822B BIT(0)
+
+/* 2 REG_AFE_CTRL3_8822B */
+
+#define BIT_SHIFT_PS_8822B 7
+#define BIT_MASK_PS_8822B 0x7
+#define BIT_PS_8822B(x) (((x) & BIT_MASK_PS_8822B) << BIT_SHIFT_PS_8822B)
+#define BIT_GET_PS_8822B(x) (((x) >> BIT_SHIFT_PS_8822B) & BIT_MASK_PS_8822B)
+
+#define BIT_PSEN_8822B BIT(6)
+#define BIT_DOGENB_8822B BIT(5)
+#define BIT_REG_MBIAS_8822B BIT(4)
+
+#define BIT_SHIFT_REG_R3_V4_8822B 1
+#define BIT_MASK_REG_R3_V4_8822B 0x7
+#define BIT_REG_R3_V4_8822B(x) \
+ (((x) & BIT_MASK_REG_R3_V4_8822B) << BIT_SHIFT_REG_R3_V4_8822B)
+#define BIT_GET_REG_R3_V4_8822B(x) \
+ (((x) >> BIT_SHIFT_REG_R3_V4_8822B) & BIT_MASK_REG_R3_V4_8822B)
+
+#define BIT_REG_CP_BIT0_8822B BIT(0)
+
+/* 2 REG_EFUSE_CTRL_8822B */
+#define BIT_EF_FLAG_8822B BIT(31)
+
+#define BIT_SHIFT_EF_PGPD_8822B 28
+#define BIT_MASK_EF_PGPD_8822B 0x7
+#define BIT_EF_PGPD_8822B(x) \
+ (((x) & BIT_MASK_EF_PGPD_8822B) << BIT_SHIFT_EF_PGPD_8822B)
+#define BIT_GET_EF_PGPD_8822B(x) \
+ (((x) >> BIT_SHIFT_EF_PGPD_8822B) & BIT_MASK_EF_PGPD_8822B)
+
+#define BIT_SHIFT_EF_RDT_8822B 24
+#define BIT_MASK_EF_RDT_8822B 0xf
+#define BIT_EF_RDT_8822B(x) \
+ (((x) & BIT_MASK_EF_RDT_8822B) << BIT_SHIFT_EF_RDT_8822B)
+#define BIT_GET_EF_RDT_8822B(x) \
+ (((x) >> BIT_SHIFT_EF_RDT_8822B) & BIT_MASK_EF_RDT_8822B)
+
+#define BIT_SHIFT_EF_PGTS_8822B 20
+#define BIT_MASK_EF_PGTS_8822B 0xf
+#define BIT_EF_PGTS_8822B(x) \
+ (((x) & BIT_MASK_EF_PGTS_8822B) << BIT_SHIFT_EF_PGTS_8822B)
+#define BIT_GET_EF_PGTS_8822B(x) \
+ (((x) >> BIT_SHIFT_EF_PGTS_8822B) & BIT_MASK_EF_PGTS_8822B)
+
+#define BIT_EF_PDWN_8822B BIT(19)
+#define BIT_EF_ALDEN_8822B BIT(18)
+
+#define BIT_SHIFT_EF_ADDR_8822B 8
+#define BIT_MASK_EF_ADDR_8822B 0x3ff
+#define BIT_EF_ADDR_8822B(x) \
+ (((x) & BIT_MASK_EF_ADDR_8822B) << BIT_SHIFT_EF_ADDR_8822B)
+#define BIT_GET_EF_ADDR_8822B(x) \
+ (((x) >> BIT_SHIFT_EF_ADDR_8822B) & BIT_MASK_EF_ADDR_8822B)
+
+#define BIT_SHIFT_EF_DATA_8822B 0
+#define BIT_MASK_EF_DATA_8822B 0xff
+#define BIT_EF_DATA_8822B(x) \
+ (((x) & BIT_MASK_EF_DATA_8822B) << BIT_SHIFT_EF_DATA_8822B)
+#define BIT_GET_EF_DATA_8822B(x) \
+ (((x) >> BIT_SHIFT_EF_DATA_8822B) & BIT_MASK_EF_DATA_8822B)
+
+/* 2 REG_LDO_EFUSE_CTRL_8822B */
+#define BIT_LDOE25_EN_8822B BIT(31)
+
+#define BIT_SHIFT_LDOE25_V12ADJ_L_8822B 27
+#define BIT_MASK_LDOE25_V12ADJ_L_8822B 0xf
+#define BIT_LDOE25_V12ADJ_L_8822B(x) \
+ (((x) & BIT_MASK_LDOE25_V12ADJ_L_8822B) \
+ << BIT_SHIFT_LDOE25_V12ADJ_L_8822B)
+#define BIT_GET_LDOE25_V12ADJ_L_8822B(x) \
+ (((x) >> BIT_SHIFT_LDOE25_V12ADJ_L_8822B) & \
+ BIT_MASK_LDOE25_V12ADJ_L_8822B)
+
+#define BIT_EF_CRES_SEL_8822B BIT(26)
+
+#define BIT_SHIFT_EF_SCAN_START_V1_8822B 16
+#define BIT_MASK_EF_SCAN_START_V1_8822B 0x3ff
+#define BIT_EF_SCAN_START_V1_8822B(x) \
+ (((x) & BIT_MASK_EF_SCAN_START_V1_8822B) \
+ << BIT_SHIFT_EF_SCAN_START_V1_8822B)
+#define BIT_GET_EF_SCAN_START_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_EF_SCAN_START_V1_8822B) & \
+ BIT_MASK_EF_SCAN_START_V1_8822B)
+
+#define BIT_SHIFT_EF_SCAN_END_8822B 12
+#define BIT_MASK_EF_SCAN_END_8822B 0xf
+#define BIT_EF_SCAN_END_8822B(x) \
+ (((x) & BIT_MASK_EF_SCAN_END_8822B) << BIT_SHIFT_EF_SCAN_END_8822B)
+#define BIT_GET_EF_SCAN_END_8822B(x) \
+ (((x) >> BIT_SHIFT_EF_SCAN_END_8822B) & BIT_MASK_EF_SCAN_END_8822B)
+
+#define BIT_EF_PD_DIS_8822B BIT(11)
+
+#define BIT_SHIFT_EF_CELL_SEL_8822B 8
+#define BIT_MASK_EF_CELL_SEL_8822B 0x3
+#define BIT_EF_CELL_SEL_8822B(x) \
+ (((x) & BIT_MASK_EF_CELL_SEL_8822B) << BIT_SHIFT_EF_CELL_SEL_8822B)
+#define BIT_GET_EF_CELL_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_EF_CELL_SEL_8822B) & BIT_MASK_EF_CELL_SEL_8822B)
+
+#define BIT_EF_TRPT_8822B BIT(7)
+
+#define BIT_SHIFT_EF_TTHD_8822B 0
+#define BIT_MASK_EF_TTHD_8822B 0x7f
+#define BIT_EF_TTHD_8822B(x) \
+ (((x) & BIT_MASK_EF_TTHD_8822B) << BIT_SHIFT_EF_TTHD_8822B)
+#define BIT_GET_EF_TTHD_8822B(x) \
+ (((x) >> BIT_SHIFT_EF_TTHD_8822B) & BIT_MASK_EF_TTHD_8822B)
+
+/* 2 REG_PWR_OPTION_CTRL_8822B */
+
+#define BIT_SHIFT_DBG_SEL_V1_8822B 16
+#define BIT_MASK_DBG_SEL_V1_8822B 0xff
+#define BIT_DBG_SEL_V1_8822B(x) \
+ (((x) & BIT_MASK_DBG_SEL_V1_8822B) << BIT_SHIFT_DBG_SEL_V1_8822B)
+#define BIT_GET_DBG_SEL_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_DBG_SEL_V1_8822B) & BIT_MASK_DBG_SEL_V1_8822B)
+
+#define BIT_SHIFT_DBG_SEL_BYTE_8822B 14
+#define BIT_MASK_DBG_SEL_BYTE_8822B 0x3
+#define BIT_DBG_SEL_BYTE_8822B(x) \
+ (((x) & BIT_MASK_DBG_SEL_BYTE_8822B) << BIT_SHIFT_DBG_SEL_BYTE_8822B)
+#define BIT_GET_DBG_SEL_BYTE_8822B(x) \
+ (((x) >> BIT_SHIFT_DBG_SEL_BYTE_8822B) & BIT_MASK_DBG_SEL_BYTE_8822B)
+
+#define BIT_SHIFT_STD_L1_V1_8822B 12
+#define BIT_MASK_STD_L1_V1_8822B 0x3
+#define BIT_STD_L1_V1_8822B(x) \
+ (((x) & BIT_MASK_STD_L1_V1_8822B) << BIT_SHIFT_STD_L1_V1_8822B)
+#define BIT_GET_STD_L1_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_STD_L1_V1_8822B) & BIT_MASK_STD_L1_V1_8822B)
+
+#define BIT_SYSON_DBG_PAD_E2_8822B BIT(11)
+#define BIT_SYSON_LED_PAD_E2_8822B BIT(10)
+#define BIT_SYSON_GPEE_PAD_E2_8822B BIT(9)
+#define BIT_SYSON_PCI_PAD_E2_8822B BIT(8)
+#define BIT_AUTO_SW_LDO_VOL_EN_8822B BIT(7)
+
+#define BIT_SHIFT_SYSON_SPS0WWV_WT_8822B 4
+#define BIT_MASK_SYSON_SPS0WWV_WT_8822B 0x3
+#define BIT_SYSON_SPS0WWV_WT_8822B(x) \
+ (((x) & BIT_MASK_SYSON_SPS0WWV_WT_8822B) \
+ << BIT_SHIFT_SYSON_SPS0WWV_WT_8822B)
+#define BIT_GET_SYSON_SPS0WWV_WT_8822B(x) \
+ (((x) >> BIT_SHIFT_SYSON_SPS0WWV_WT_8822B) & \
+ BIT_MASK_SYSON_SPS0WWV_WT_8822B)
+
+#define BIT_SHIFT_SYSON_SPS0LDO_WT_8822B 2
+#define BIT_MASK_SYSON_SPS0LDO_WT_8822B 0x3
+#define BIT_SYSON_SPS0LDO_WT_8822B(x) \
+ (((x) & BIT_MASK_SYSON_SPS0LDO_WT_8822B) \
+ << BIT_SHIFT_SYSON_SPS0LDO_WT_8822B)
+#define BIT_GET_SYSON_SPS0LDO_WT_8822B(x) \
+ (((x) >> BIT_SHIFT_SYSON_SPS0LDO_WT_8822B) & \
+ BIT_MASK_SYSON_SPS0LDO_WT_8822B)
+
+#define BIT_SHIFT_SYSON_RCLK_SCALE_8822B 0
+#define BIT_MASK_SYSON_RCLK_SCALE_8822B 0x3
+#define BIT_SYSON_RCLK_SCALE_8822B(x) \
+ (((x) & BIT_MASK_SYSON_RCLK_SCALE_8822B) \
+ << BIT_SHIFT_SYSON_RCLK_SCALE_8822B)
+#define BIT_GET_SYSON_RCLK_SCALE_8822B(x) \
+ (((x) >> BIT_SHIFT_SYSON_RCLK_SCALE_8822B) & \
+ BIT_MASK_SYSON_RCLK_SCALE_8822B)
+
+/* 2 REG_CAL_TIMER_8822B */
+
+#define BIT_SHIFT_MATCH_CNT_8822B 8
+#define BIT_MASK_MATCH_CNT_8822B 0xff
+#define BIT_MATCH_CNT_8822B(x) \
+ (((x) & BIT_MASK_MATCH_CNT_8822B) << BIT_SHIFT_MATCH_CNT_8822B)
+#define BIT_GET_MATCH_CNT_8822B(x) \
+ (((x) >> BIT_SHIFT_MATCH_CNT_8822B) & BIT_MASK_MATCH_CNT_8822B)
+
+#define BIT_SHIFT_CAL_SCAL_8822B 0
+#define BIT_MASK_CAL_SCAL_8822B 0xff
+#define BIT_CAL_SCAL_8822B(x) \
+ (((x) & BIT_MASK_CAL_SCAL_8822B) << BIT_SHIFT_CAL_SCAL_8822B)
+#define BIT_GET_CAL_SCAL_8822B(x) \
+ (((x) >> BIT_SHIFT_CAL_SCAL_8822B) & BIT_MASK_CAL_SCAL_8822B)
+
+/* 2 REG_ACLK_MON_8822B */
+
+#define BIT_SHIFT_RCLK_MON_8822B 5
+#define BIT_MASK_RCLK_MON_8822B 0x7ff
+#define BIT_RCLK_MON_8822B(x) \
+ (((x) & BIT_MASK_RCLK_MON_8822B) << BIT_SHIFT_RCLK_MON_8822B)
+#define BIT_GET_RCLK_MON_8822B(x) \
+ (((x) >> BIT_SHIFT_RCLK_MON_8822B) & BIT_MASK_RCLK_MON_8822B)
+
+#define BIT_CAL_EN_8822B BIT(4)
+
+#define BIT_SHIFT_DPSTU_8822B 2
+#define BIT_MASK_DPSTU_8822B 0x3
+#define BIT_DPSTU_8822B(x) \
+ (((x) & BIT_MASK_DPSTU_8822B) << BIT_SHIFT_DPSTU_8822B)
+#define BIT_GET_DPSTU_8822B(x) \
+ (((x) >> BIT_SHIFT_DPSTU_8822B) & BIT_MASK_DPSTU_8822B)
+
+#define BIT_SUS_16X_8822B BIT(1)
+
+/* 2 REG_GPIO_MUXCFG_8822B */
+#define BIT_FSPI_EN_8822B BIT(19)
+#define BIT_WL_RTS_EXT_32K_SEL_8822B BIT(18)
+#define BIT_WLGP_SPI_EN_8822B BIT(16)
+#define BIT_SIC_LBK_8822B BIT(15)
+#define BIT_ENHTP_8822B BIT(14)
+#define BIT_ENSIC_8822B BIT(12)
+#define BIT_SIC_SWRST_8822B BIT(11)
+#define BIT_PO_WIFI_PTA_PINS_8822B BIT(10)
+#define BIT_PO_BT_PTA_PINS_8822B BIT(9)
+#define BIT_ENUART_8822B BIT(8)
+
+#define BIT_SHIFT_BTMODE_8822B 6
+#define BIT_MASK_BTMODE_8822B 0x3
+#define BIT_BTMODE_8822B(x) \
+ (((x) & BIT_MASK_BTMODE_8822B) << BIT_SHIFT_BTMODE_8822B)
+#define BIT_GET_BTMODE_8822B(x) \
+ (((x) >> BIT_SHIFT_BTMODE_8822B) & BIT_MASK_BTMODE_8822B)
+
+#define BIT_ENBT_8822B BIT(5)
+#define BIT_EROM_EN_8822B BIT(4)
+#define BIT_WLRFE_6_7_EN_8822B BIT(3)
+#define BIT_WLRFE_4_5_EN_8822B BIT(2)
+
+#define BIT_SHIFT_GPIOSEL_8822B 0
+#define BIT_MASK_GPIOSEL_8822B 0x3
+#define BIT_GPIOSEL_8822B(x) \
+ (((x) & BIT_MASK_GPIOSEL_8822B) << BIT_SHIFT_GPIOSEL_8822B)
+#define BIT_GET_GPIOSEL_8822B(x) \
+ (((x) >> BIT_SHIFT_GPIOSEL_8822B) & BIT_MASK_GPIOSEL_8822B)
+
+/* 2 REG_GPIO_PIN_CTRL_8822B */
+
+#define BIT_SHIFT_GPIO_MOD_7_TO_0_8822B 24
+#define BIT_MASK_GPIO_MOD_7_TO_0_8822B 0xff
+#define BIT_GPIO_MOD_7_TO_0_8822B(x) \
+ (((x) & BIT_MASK_GPIO_MOD_7_TO_0_8822B) \
+ << BIT_SHIFT_GPIO_MOD_7_TO_0_8822B)
+#define BIT_GET_GPIO_MOD_7_TO_0_8822B(x) \
+ (((x) >> BIT_SHIFT_GPIO_MOD_7_TO_0_8822B) & \
+ BIT_MASK_GPIO_MOD_7_TO_0_8822B)
+
+#define BIT_SHIFT_GPIO_IO_SEL_7_TO_0_8822B 16
+#define BIT_MASK_GPIO_IO_SEL_7_TO_0_8822B 0xff
+#define BIT_GPIO_IO_SEL_7_TO_0_8822B(x) \
+ (((x) & BIT_MASK_GPIO_IO_SEL_7_TO_0_8822B) \
+ << BIT_SHIFT_GPIO_IO_SEL_7_TO_0_8822B)
+#define BIT_GET_GPIO_IO_SEL_7_TO_0_8822B(x) \
+ (((x) >> BIT_SHIFT_GPIO_IO_SEL_7_TO_0_8822B) & \
+ BIT_MASK_GPIO_IO_SEL_7_TO_0_8822B)
+
+#define BIT_SHIFT_GPIO_OUT_7_TO_0_8822B 8
+#define BIT_MASK_GPIO_OUT_7_TO_0_8822B 0xff
+#define BIT_GPIO_OUT_7_TO_0_8822B(x) \
+ (((x) & BIT_MASK_GPIO_OUT_7_TO_0_8822B) \
+ << BIT_SHIFT_GPIO_OUT_7_TO_0_8822B)
+#define BIT_GET_GPIO_OUT_7_TO_0_8822B(x) \
+ (((x) >> BIT_SHIFT_GPIO_OUT_7_TO_0_8822B) & \
+ BIT_MASK_GPIO_OUT_7_TO_0_8822B)
+
+#define BIT_SHIFT_GPIO_IN_7_TO_0_8822B 0
+#define BIT_MASK_GPIO_IN_7_TO_0_8822B 0xff
+#define BIT_GPIO_IN_7_TO_0_8822B(x) \
+ (((x) & BIT_MASK_GPIO_IN_7_TO_0_8822B) \
+ << BIT_SHIFT_GPIO_IN_7_TO_0_8822B)
+#define BIT_GET_GPIO_IN_7_TO_0_8822B(x) \
+ (((x) >> BIT_SHIFT_GPIO_IN_7_TO_0_8822B) & \
+ BIT_MASK_GPIO_IN_7_TO_0_8822B)
+
+/* 2 REG_GPIO_INTM_8822B */
+
+#define BIT_SHIFT_MUXDBG_SEL_8822B 30
+#define BIT_MASK_MUXDBG_SEL_8822B 0x3
+#define BIT_MUXDBG_SEL_8822B(x) \
+ (((x) & BIT_MASK_MUXDBG_SEL_8822B) << BIT_SHIFT_MUXDBG_SEL_8822B)
+#define BIT_GET_MUXDBG_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_MUXDBG_SEL_8822B) & BIT_MASK_MUXDBG_SEL_8822B)
+
+#define BIT_EXTWOL_SEL_8822B BIT(17)
+#define BIT_EXTWOL_EN_8822B BIT(16)
+#define BIT_GPIOF_INT_MD_8822B BIT(15)
+#define BIT_GPIOE_INT_MD_8822B BIT(14)
+#define BIT_GPIOD_INT_MD_8822B BIT(13)
+#define BIT_GPIOF_INT_MD_8822B BIT(15)
+#define BIT_GPIOE_INT_MD_8822B BIT(14)
+#define BIT_GPIOD_INT_MD_8822B BIT(13)
+#define BIT_GPIOC_INT_MD_8822B BIT(12)
+#define BIT_GPIOB_INT_MD_8822B BIT(11)
+#define BIT_GPIOA_INT_MD_8822B BIT(10)
+#define BIT_GPIO9_INT_MD_8822B BIT(9)
+#define BIT_GPIO8_INT_MD_8822B BIT(8)
+#define BIT_GPIO7_INT_MD_8822B BIT(7)
+#define BIT_GPIO6_INT_MD_8822B BIT(6)
+#define BIT_GPIO5_INT_MD_8822B BIT(5)
+#define BIT_GPIO4_INT_MD_8822B BIT(4)
+#define BIT_GPIO3_INT_MD_8822B BIT(3)
+#define BIT_GPIO2_INT_MD_8822B BIT(2)
+#define BIT_GPIO1_INT_MD_8822B BIT(1)
+#define BIT_GPIO0_INT_MD_8822B BIT(0)
+
+/* 2 REG_LED_CFG_8822B */
+#define BIT_GPIO3_WL_CTRL_EN_8822B BIT(27)
+#define BIT_LNAON_SEL_EN_8822B BIT(26)
+#define BIT_PAPE_SEL_EN_8822B BIT(25)
+#define BIT_DPDT_WLBT_SEL_8822B BIT(24)
+#define BIT_DPDT_SEL_EN_8822B BIT(23)
+#define BIT_GPIO13_14_WL_CTRL_EN_8822B BIT(22)
+#define BIT_GPIO13_14_WL_CTRL_EN_8822B BIT(22)
+#define BIT_LED2DIS_8822B BIT(21)
+#define BIT_LED2PL_8822B BIT(20)
+#define BIT_LED2SV_8822B BIT(19)
+
+#define BIT_SHIFT_LED2CM_8822B 16
+#define BIT_MASK_LED2CM_8822B 0x7
+#define BIT_LED2CM_8822B(x) \
+ (((x) & BIT_MASK_LED2CM_8822B) << BIT_SHIFT_LED2CM_8822B)
+#define BIT_GET_LED2CM_8822B(x) \
+ (((x) >> BIT_SHIFT_LED2CM_8822B) & BIT_MASK_LED2CM_8822B)
+
+#define BIT_LED1DIS_8822B BIT(15)
+#define BIT_LED1PL_8822B BIT(12)
+#define BIT_LED1SV_8822B BIT(11)
+
+#define BIT_SHIFT_LED1CM_8822B 8
+#define BIT_MASK_LED1CM_8822B 0x7
+#define BIT_LED1CM_8822B(x) \
+ (((x) & BIT_MASK_LED1CM_8822B) << BIT_SHIFT_LED1CM_8822B)
+#define BIT_GET_LED1CM_8822B(x) \
+ (((x) >> BIT_SHIFT_LED1CM_8822B) & BIT_MASK_LED1CM_8822B)
+
+#define BIT_LED0DIS_8822B BIT(7)
+
+#define BIT_SHIFT_AFE_LDO_SWR_CHECK_8822B 5
+#define BIT_MASK_AFE_LDO_SWR_CHECK_8822B 0x3
+#define BIT_AFE_LDO_SWR_CHECK_8822B(x) \
+ (((x) & BIT_MASK_AFE_LDO_SWR_CHECK_8822B) \
+ << BIT_SHIFT_AFE_LDO_SWR_CHECK_8822B)
+#define BIT_GET_AFE_LDO_SWR_CHECK_8822B(x) \
+ (((x) >> BIT_SHIFT_AFE_LDO_SWR_CHECK_8822B) & \
+ BIT_MASK_AFE_LDO_SWR_CHECK_8822B)
+
+#define BIT_LED0PL_8822B BIT(4)
+#define BIT_LED0SV_8822B BIT(3)
+
+#define BIT_SHIFT_LED0CM_8822B 0
+#define BIT_MASK_LED0CM_8822B 0x7
+#define BIT_LED0CM_8822B(x) \
+ (((x) & BIT_MASK_LED0CM_8822B) << BIT_SHIFT_LED0CM_8822B)
+#define BIT_GET_LED0CM_8822B(x) \
+ (((x) >> BIT_SHIFT_LED0CM_8822B) & BIT_MASK_LED0CM_8822B)
+
+/* 2 REG_FSIMR_8822B */
+#define BIT_FS_PDNINT_EN_8822B BIT(31)
+#define BIT_NFC_INT_PAD_EN_8822B BIT(30)
+#define BIT_FS_SPS_OCP_INT_EN_8822B BIT(29)
+#define BIT_FS_PWMERR_INT_EN_8822B BIT(28)
+#define BIT_FS_GPIOF_INT_EN_8822B BIT(27)
+#define BIT_FS_GPIOE_INT_EN_8822B BIT(26)
+#define BIT_FS_GPIOD_INT_EN_8822B BIT(25)
+#define BIT_FS_GPIOC_INT_EN_8822B BIT(24)
+#define BIT_FS_GPIOB_INT_EN_8822B BIT(23)
+#define BIT_FS_GPIOA_INT_EN_8822B BIT(22)
+#define BIT_FS_GPIO9_INT_EN_8822B BIT(21)
+#define BIT_FS_GPIO8_INT_EN_8822B BIT(20)
+#define BIT_FS_GPIO7_INT_EN_8822B BIT(19)
+#define BIT_FS_GPIO6_INT_EN_8822B BIT(18)
+#define BIT_FS_GPIO5_INT_EN_8822B BIT(17)
+#define BIT_FS_GPIO4_INT_EN_8822B BIT(16)
+#define BIT_FS_GPIO3_INT_EN_8822B BIT(15)
+#define BIT_FS_GPIO2_INT_EN_8822B BIT(14)
+#define BIT_FS_GPIO1_INT_EN_8822B BIT(13)
+#define BIT_FS_GPIO0_INT_EN_8822B BIT(12)
+#define BIT_FS_HCI_SUS_EN_8822B BIT(11)
+#define BIT_FS_HCI_RES_EN_8822B BIT(10)
+#define BIT_FS_HCI_RESET_EN_8822B BIT(9)
+#define BIT_FS_BTON_STS_UPDATE_MSK_EN_8822B BIT(7)
+#define BIT_ACT2RECOVERY_INT_EN_V1_8822B BIT(6)
+#define BIT_GEN1GEN2_SWITCH_8822B BIT(5)
+#define BIT_HCI_TXDMA_REQ_HIMR_8822B BIT(4)
+#define BIT_FS_32K_LEAVE_SETTING_MAK_8822B BIT(3)
+#define BIT_FS_32K_ENTER_SETTING_MAK_8822B BIT(2)
+#define BIT_FS_USB_LPMRSM_MSK_8822B BIT(1)
+#define BIT_FS_USB_LPMINT_MSK_8822B BIT(0)
+
+/* 2 REG_FSISR_8822B */
+#define BIT_FS_PDNINT_8822B BIT(31)
+#define BIT_FS_SPS_OCP_INT_8822B BIT(29)
+#define BIT_FS_PWMERR_INT_8822B BIT(28)
+#define BIT_FS_GPIOF_INT_8822B BIT(27)
+#define BIT_FS_GPIOE_INT_8822B BIT(26)
+#define BIT_FS_GPIOD_INT_8822B BIT(25)
+#define BIT_FS_GPIOC_INT_8822B BIT(24)
+#define BIT_FS_GPIOB_INT_8822B BIT(23)
+#define BIT_FS_GPIOA_INT_8822B BIT(22)
+#define BIT_FS_GPIO9_INT_8822B BIT(21)
+#define BIT_FS_GPIO8_INT_8822B BIT(20)
+#define BIT_FS_GPIO7_INT_8822B BIT(19)
+#define BIT_FS_GPIO6_INT_8822B BIT(18)
+#define BIT_FS_GPIO5_INT_8822B BIT(17)
+#define BIT_FS_GPIO4_INT_8822B BIT(16)
+#define BIT_FS_GPIO3_INT_8822B BIT(15)
+#define BIT_FS_GPIO2_INT_8822B BIT(14)
+#define BIT_FS_GPIO1_INT_8822B BIT(13)
+#define BIT_FS_GPIO0_INT_8822B BIT(12)
+#define BIT_FS_HCI_SUS_INT_8822B BIT(11)
+#define BIT_FS_HCI_RES_INT_8822B BIT(10)
+#define BIT_FS_HCI_RESET_INT_8822B BIT(9)
+#define BIT_ACT2RECOVERY_8822B BIT(6)
+#define BIT_GEN1GEN2_SWITCH_8822B BIT(5)
+#define BIT_HCI_TXDMA_REQ_HISR_8822B BIT(4)
+#define BIT_FS_32K_LEAVE_SETTING_INT_8822B BIT(3)
+#define BIT_FS_32K_ENTER_SETTING_INT_8822B BIT(2)
+#define BIT_FS_USB_LPMRSM_INT_8822B BIT(1)
+#define BIT_FS_USB_LPMINT_INT_8822B BIT(0)
+
+/* 2 REG_HSIMR_8822B */
+#define BIT_GPIOF_INT_EN_8822B BIT(31)
+#define BIT_GPIOE_INT_EN_8822B BIT(30)
+#define BIT_GPIOD_INT_EN_8822B BIT(29)
+#define BIT_GPIOC_INT_EN_8822B BIT(28)
+#define BIT_GPIOB_INT_EN_8822B BIT(27)
+#define BIT_GPIOA_INT_EN_8822B BIT(26)
+#define BIT_GPIO9_INT_EN_8822B BIT(25)
+#define BIT_GPIO8_INT_EN_8822B BIT(24)
+#define BIT_GPIO7_INT_EN_8822B BIT(23)
+#define BIT_GPIO6_INT_EN_8822B BIT(22)
+#define BIT_GPIO5_INT_EN_8822B BIT(21)
+#define BIT_GPIO4_INT_EN_8822B BIT(20)
+#define BIT_GPIO3_INT_EN_8822B BIT(19)
+#define BIT_GPIO2_INT_EN_V1_8822B BIT(16)
+#define BIT_GPIO1_INT_EN_8822B BIT(17)
+#define BIT_GPIO0_INT_EN_8822B BIT(16)
+#define BIT_PDNINT_EN_8822B BIT(7)
+#define BIT_RON_INT_EN_8822B BIT(6)
+#define BIT_SPS_OCP_INT_EN_8822B BIT(5)
+#define BIT_GPIO15_0_INT_EN_8822B BIT(0)
+
+/* 2 REG_HSISR_8822B */
+#define BIT_GPIOF_INT_8822B BIT(31)
+#define BIT_GPIOE_INT_8822B BIT(30)
+#define BIT_GPIOD_INT_8822B BIT(29)
+#define BIT_GPIOC_INT_8822B BIT(28)
+#define BIT_GPIOB_INT_8822B BIT(27)
+#define BIT_GPIOA_INT_8822B BIT(26)
+#define BIT_GPIO9_INT_8822B BIT(25)
+#define BIT_GPIO8_INT_8822B BIT(24)
+#define BIT_GPIO7_INT_8822B BIT(23)
+#define BIT_GPIO6_INT_8822B BIT(22)
+#define BIT_GPIO5_INT_8822B BIT(21)
+#define BIT_GPIO4_INT_8822B BIT(20)
+#define BIT_GPIO3_INT_8822B BIT(19)
+#define BIT_GPIO2_INT_V1_8822B BIT(16)
+#define BIT_GPIO1_INT_8822B BIT(17)
+#define BIT_GPIO0_INT_8822B BIT(16)
+#define BIT_PDNINT_8822B BIT(7)
+#define BIT_RON_INT_8822B BIT(6)
+#define BIT_SPS_OCP_INT_8822B BIT(5)
+#define BIT_GPIO15_0_INT_8822B BIT(0)
+
+/* 2 REG_GPIO_EXT_CTRL_8822B */
+
+#define BIT_SHIFT_GPIO_MOD_15_TO_8_8822B 24
+#define BIT_MASK_GPIO_MOD_15_TO_8_8822B 0xff
+#define BIT_GPIO_MOD_15_TO_8_8822B(x) \
+ (((x) & BIT_MASK_GPIO_MOD_15_TO_8_8822B) \
+ << BIT_SHIFT_GPIO_MOD_15_TO_8_8822B)
+#define BIT_GET_GPIO_MOD_15_TO_8_8822B(x) \
+ (((x) >> BIT_SHIFT_GPIO_MOD_15_TO_8_8822B) & \
+ BIT_MASK_GPIO_MOD_15_TO_8_8822B)
+
+#define BIT_SHIFT_GPIO_IO_SEL_15_TO_8_8822B 16
+#define BIT_MASK_GPIO_IO_SEL_15_TO_8_8822B 0xff
+#define BIT_GPIO_IO_SEL_15_TO_8_8822B(x) \
+ (((x) & BIT_MASK_GPIO_IO_SEL_15_TO_8_8822B) \
+ << BIT_SHIFT_GPIO_IO_SEL_15_TO_8_8822B)
+#define BIT_GET_GPIO_IO_SEL_15_TO_8_8822B(x) \
+ (((x) >> BIT_SHIFT_GPIO_IO_SEL_15_TO_8_8822B) & \
+ BIT_MASK_GPIO_IO_SEL_15_TO_8_8822B)
+
+#define BIT_SHIFT_GPIO_OUT_15_TO_8_8822B 8
+#define BIT_MASK_GPIO_OUT_15_TO_8_8822B 0xff
+#define BIT_GPIO_OUT_15_TO_8_8822B(x) \
+ (((x) & BIT_MASK_GPIO_OUT_15_TO_8_8822B) \
+ << BIT_SHIFT_GPIO_OUT_15_TO_8_8822B)
+#define BIT_GET_GPIO_OUT_15_TO_8_8822B(x) \
+ (((x) >> BIT_SHIFT_GPIO_OUT_15_TO_8_8822B) & \
+ BIT_MASK_GPIO_OUT_15_TO_8_8822B)
+
+#define BIT_SHIFT_GPIO_IN_15_TO_8_8822B 0
+#define BIT_MASK_GPIO_IN_15_TO_8_8822B 0xff
+#define BIT_GPIO_IN_15_TO_8_8822B(x) \
+ (((x) & BIT_MASK_GPIO_IN_15_TO_8_8822B) \
+ << BIT_SHIFT_GPIO_IN_15_TO_8_8822B)
+#define BIT_GET_GPIO_IN_15_TO_8_8822B(x) \
+ (((x) >> BIT_SHIFT_GPIO_IN_15_TO_8_8822B) & \
+ BIT_MASK_GPIO_IN_15_TO_8_8822B)
+
+/* 2 REG_PAD_CTRL1_8822B */
+#define BIT_PAPE_WLBT_SEL_8822B BIT(29)
+#define BIT_LNAON_WLBT_SEL_8822B BIT(28)
+#define BIT_BTGP_GPG3_FEN_8822B BIT(26)
+#define BIT_BTGP_GPG2_FEN_8822B BIT(25)
+#define BIT_BTGP_JTAG_EN_8822B BIT(24)
+#define BIT_XTAL_CLK_EXTARNAL_EN_8822B BIT(23)
+#define BIT_BTGP_UART0_EN_8822B BIT(22)
+#define BIT_BTGP_UART1_EN_8822B BIT(21)
+#define BIT_BTGP_SPI_EN_8822B BIT(20)
+#define BIT_BTGP_GPIO_E2_8822B BIT(19)
+#define BIT_BTGP_GPIO_EN_8822B BIT(18)
+
+#define BIT_SHIFT_BTGP_GPIO_SL_8822B 16
+#define BIT_MASK_BTGP_GPIO_SL_8822B 0x3
+#define BIT_BTGP_GPIO_SL_8822B(x) \
+ (((x) & BIT_MASK_BTGP_GPIO_SL_8822B) << BIT_SHIFT_BTGP_GPIO_SL_8822B)
+#define BIT_GET_BTGP_GPIO_SL_8822B(x) \
+ (((x) >> BIT_SHIFT_BTGP_GPIO_SL_8822B) & BIT_MASK_BTGP_GPIO_SL_8822B)
+
+#define BIT_PAD_SDIO_SR_8822B BIT(14)
+#define BIT_GPIO14_OUTPUT_PL_8822B BIT(13)
+#define BIT_HOST_WAKE_PAD_PULL_EN_8822B BIT(12)
+#define BIT_HOST_WAKE_PAD_SL_8822B BIT(11)
+#define BIT_PAD_LNAON_SR_8822B BIT(10)
+#define BIT_PAD_LNAON_E2_8822B BIT(9)
+#define BIT_SW_LNAON_G_SEL_DATA_8822B BIT(8)
+#define BIT_SW_LNAON_A_SEL_DATA_8822B BIT(7)
+#define BIT_PAD_PAPE_SR_8822B BIT(6)
+#define BIT_PAD_PAPE_E2_8822B BIT(5)
+#define BIT_SW_PAPE_G_SEL_DATA_8822B BIT(4)
+#define BIT_SW_PAPE_A_SEL_DATA_8822B BIT(3)
+#define BIT_PAD_DPDT_SR_8822B BIT(2)
+#define BIT_PAD_DPDT_PAD_E2_8822B BIT(1)
+#define BIT_SW_DPDT_SEL_DATA_8822B BIT(0)
+
+/* 2 REG_WL_BT_PWR_CTRL_8822B */
+#define BIT_ISO_BD2PP_8822B BIT(31)
+#define BIT_LDOV12B_EN_8822B BIT(30)
+#define BIT_CKEN_BTGPS_8822B BIT(29)
+#define BIT_FEN_BTGPS_8822B BIT(28)
+#define BIT_BTCPU_BOOTSEL_8822B BIT(27)
+#define BIT_SPI_SPEEDUP_8822B BIT(26)
+#define BIT_DEVWAKE_PAD_TYPE_SEL_8822B BIT(24)
+#define BIT_CLKREQ_PAD_TYPE_SEL_8822B BIT(23)
+#define BIT_ISO_BTPON2PP_8822B BIT(22)
+#define BIT_BT_HWROF_EN_8822B BIT(19)
+#define BIT_BT_FUNC_EN_8822B BIT(18)
+#define BIT_BT_HWPDN_SL_8822B BIT(17)
+#define BIT_BT_DISN_EN_8822B BIT(16)
+#define BIT_BT_PDN_PULL_EN_8822B BIT(15)
+#define BIT_WL_PDN_PULL_EN_8822B BIT(14)
+#define BIT_EXTERNAL_REQUEST_PL_8822B BIT(13)
+#define BIT_GPIO0_2_3_PULL_LOW_EN_8822B BIT(12)
+#define BIT_ISO_BA2PP_8822B BIT(11)
+#define BIT_BT_AFE_LDO_EN_8822B BIT(10)
+#define BIT_BT_AFE_PLL_EN_8822B BIT(9)
+#define BIT_BT_DIG_CLK_EN_8822B BIT(8)
+#define BIT_WL_DRV_EXIST_IDX_8822B BIT(5)
+#define BIT_DOP_EHPAD_8822B BIT(4)
+#define BIT_WL_HWROF_EN_8822B BIT(3)
+#define BIT_WL_FUNC_EN_8822B BIT(2)
+#define BIT_WL_HWPDN_SL_8822B BIT(1)
+#define BIT_WL_HWPDN_EN_8822B BIT(0)
+
+/* 2 REG_SDM_DEBUG_8822B */
+
+#define BIT_SHIFT_WLCLK_PHASE_8822B 0
+#define BIT_MASK_WLCLK_PHASE_8822B 0x1f
+#define BIT_WLCLK_PHASE_8822B(x) \
+ (((x) & BIT_MASK_WLCLK_PHASE_8822B) << BIT_SHIFT_WLCLK_PHASE_8822B)
+#define BIT_GET_WLCLK_PHASE_8822B(x) \
+ (((x) >> BIT_SHIFT_WLCLK_PHASE_8822B) & BIT_MASK_WLCLK_PHASE_8822B)
+
+/* 2 REG_SYS_SDIO_CTRL_8822B */
+#define BIT_DBG_GNT_WL_BT_8822B BIT(27)
+#define BIT_LTE_MUX_CTRL_PATH_8822B BIT(26)
+#define BIT_LTE_COEX_UART_8822B BIT(25)
+#define BIT_3W_LTE_WL_GPIO_8822B BIT(24)
+#define BIT_SDIO_INT_POLARITY_8822B BIT(19)
+#define BIT_SDIO_INT_8822B BIT(18)
+#define BIT_SDIO_OFF_EN_8822B BIT(17)
+#define BIT_SDIO_ON_EN_8822B BIT(16)
+#define BIT_PCIE_WAIT_TIMEOUT_EVENT_8822B BIT(10)
+#define BIT_PCIE_WAIT_TIME_8822B BIT(9)
+#define BIT_MPCIE_REFCLK_XTAL_SEL_8822B BIT(8)
+
+/* 2 REG_HCI_OPT_CTRL_8822B */
+
+#define BIT_SHIFT_TSFT_SEL_8822B 29
+#define BIT_MASK_TSFT_SEL_8822B 0x7
+#define BIT_TSFT_SEL_8822B(x) \
+ (((x) & BIT_MASK_TSFT_SEL_8822B) << BIT_SHIFT_TSFT_SEL_8822B)
+#define BIT_GET_TSFT_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_TSFT_SEL_8822B) & BIT_MASK_TSFT_SEL_8822B)
+
+#define BIT_USB_HOST_PWR_OFF_EN_8822B BIT(12)
+#define BIT_SYM_LPS_BLOCK_EN_8822B BIT(11)
+#define BIT_USB_LPM_ACT_EN_8822B BIT(10)
+#define BIT_USB_LPM_NY_8822B BIT(9)
+#define BIT_USB_SUS_DIS_8822B BIT(8)
+
+#define BIT_SHIFT_SDIO_PAD_E_8822B 5
+#define BIT_MASK_SDIO_PAD_E_8822B 0x7
+#define BIT_SDIO_PAD_E_8822B(x) \
+ (((x) & BIT_MASK_SDIO_PAD_E_8822B) << BIT_SHIFT_SDIO_PAD_E_8822B)
+#define BIT_GET_SDIO_PAD_E_8822B(x) \
+ (((x) >> BIT_SHIFT_SDIO_PAD_E_8822B) & BIT_MASK_SDIO_PAD_E_8822B)
+
+#define BIT_USB_LPPLL_EN_8822B BIT(4)
+#define BIT_ROP_SW15_8822B BIT(2)
+#define BIT_PCI_CKRDY_OPT_8822B BIT(1)
+#define BIT_PCI_VAUX_EN_8822B BIT(0)
+
+/* 2 REG_AFE_CTRL4_8822B */
+
+/* 2 REG_LDO_SWR_CTRL_8822B */
+#define BIT_ZCD_HW_AUTO_EN_8822B BIT(27)
+#define BIT_ZCD_REGSEL_8822B BIT(26)
+
+#define BIT_SHIFT_AUTO_ZCD_IN_CODE_8822B 21
+#define BIT_MASK_AUTO_ZCD_IN_CODE_8822B 0x1f
+#define BIT_AUTO_ZCD_IN_CODE_8822B(x) \
+ (((x) & BIT_MASK_AUTO_ZCD_IN_CODE_8822B) \
+ << BIT_SHIFT_AUTO_ZCD_IN_CODE_8822B)
+#define BIT_GET_AUTO_ZCD_IN_CODE_8822B(x) \
+ (((x) >> BIT_SHIFT_AUTO_ZCD_IN_CODE_8822B) & \
+ BIT_MASK_AUTO_ZCD_IN_CODE_8822B)
+
+#define BIT_SHIFT_ZCD_CODE_IN_L_8822B 16
+#define BIT_MASK_ZCD_CODE_IN_L_8822B 0x1f
+#define BIT_ZCD_CODE_IN_L_8822B(x) \
+ (((x) & BIT_MASK_ZCD_CODE_IN_L_8822B) << BIT_SHIFT_ZCD_CODE_IN_L_8822B)
+#define BIT_GET_ZCD_CODE_IN_L_8822B(x) \
+ (((x) >> BIT_SHIFT_ZCD_CODE_IN_L_8822B) & BIT_MASK_ZCD_CODE_IN_L_8822B)
+
+#define BIT_SHIFT_LDO_HV5_DUMMY_8822B 14
+#define BIT_MASK_LDO_HV5_DUMMY_8822B 0x3
+#define BIT_LDO_HV5_DUMMY_8822B(x) \
+ (((x) & BIT_MASK_LDO_HV5_DUMMY_8822B) << BIT_SHIFT_LDO_HV5_DUMMY_8822B)
+#define BIT_GET_LDO_HV5_DUMMY_8822B(x) \
+ (((x) >> BIT_SHIFT_LDO_HV5_DUMMY_8822B) & BIT_MASK_LDO_HV5_DUMMY_8822B)
+
+#define BIT_SHIFT_REG_VTUNE33_BIT0_TO_BIT1_8822B 12
+#define BIT_MASK_REG_VTUNE33_BIT0_TO_BIT1_8822B 0x3
+#define BIT_REG_VTUNE33_BIT0_TO_BIT1_8822B(x) \
+ (((x) & BIT_MASK_REG_VTUNE33_BIT0_TO_BIT1_8822B) \
+ << BIT_SHIFT_REG_VTUNE33_BIT0_TO_BIT1_8822B)
+#define BIT_GET_REG_VTUNE33_BIT0_TO_BIT1_8822B(x) \
+ (((x) >> BIT_SHIFT_REG_VTUNE33_BIT0_TO_BIT1_8822B) & \
+ BIT_MASK_REG_VTUNE33_BIT0_TO_BIT1_8822B)
+
+#define BIT_SHIFT_REG_STANDBY33_BIT0_TO_BIT1_8822B 10
+#define BIT_MASK_REG_STANDBY33_BIT0_TO_BIT1_8822B 0x3
+#define BIT_REG_STANDBY33_BIT0_TO_BIT1_8822B(x) \
+ (((x) & BIT_MASK_REG_STANDBY33_BIT0_TO_BIT1_8822B) \
+ << BIT_SHIFT_REG_STANDBY33_BIT0_TO_BIT1_8822B)
+#define BIT_GET_REG_STANDBY33_BIT0_TO_BIT1_8822B(x) \
+ (((x) >> BIT_SHIFT_REG_STANDBY33_BIT0_TO_BIT1_8822B) & \
+ BIT_MASK_REG_STANDBY33_BIT0_TO_BIT1_8822B)
+
+#define BIT_SHIFT_REG_LOAD33_BIT0_TO_BIT1_8822B 8
+#define BIT_MASK_REG_LOAD33_BIT0_TO_BIT1_8822B 0x3
+#define BIT_REG_LOAD33_BIT0_TO_BIT1_8822B(x) \
+ (((x) & BIT_MASK_REG_LOAD33_BIT0_TO_BIT1_8822B) \
+ << BIT_SHIFT_REG_LOAD33_BIT0_TO_BIT1_8822B)
+#define BIT_GET_REG_LOAD33_BIT0_TO_BIT1_8822B(x) \
+ (((x) >> BIT_SHIFT_REG_LOAD33_BIT0_TO_BIT1_8822B) & \
+ BIT_MASK_REG_LOAD33_BIT0_TO_BIT1_8822B)
+
+#define BIT_REG_BYPASS_L_8822B BIT(7)
+#define BIT_REG_LDOF_L_8822B BIT(6)
+#define BIT_REG_TYPE_L_V1_8822B BIT(5)
+#define BIT_ARENB_L_8822B BIT(3)
+
+#define BIT_SHIFT_CFC_L_8822B 1
+#define BIT_MASK_CFC_L_8822B 0x3
+#define BIT_CFC_L_8822B(x) \
+ (((x) & BIT_MASK_CFC_L_8822B) << BIT_SHIFT_CFC_L_8822B)
+#define BIT_GET_CFC_L_8822B(x) \
+ (((x) >> BIT_SHIFT_CFC_L_8822B) & BIT_MASK_CFC_L_8822B)
+
+#define BIT_REG_OCPS_L_V1_8822B BIT(0)
+
+/* 2 REG_MCUFW_CTRL_8822B */
+
+#define BIT_SHIFT_RPWM_8822B 24
+#define BIT_MASK_RPWM_8822B 0xff
+#define BIT_RPWM_8822B(x) (((x) & BIT_MASK_RPWM_8822B) << BIT_SHIFT_RPWM_8822B)
+#define BIT_GET_RPWM_8822B(x) \
+ (((x) >> BIT_SHIFT_RPWM_8822B) & BIT_MASK_RPWM_8822B)
+
+#define BIT_ANA_PORT_EN_8822B BIT(22)
+#define BIT_MAC_PORT_EN_8822B BIT(21)
+#define BIT_BOOT_FSPI_EN_8822B BIT(20)
+#define BIT_ROM_DLEN_8822B BIT(19)
+
+#define BIT_SHIFT_ROM_PGE_8822B 16
+#define BIT_MASK_ROM_PGE_8822B 0x7
+#define BIT_ROM_PGE_8822B(x) \
+ (((x) & BIT_MASK_ROM_PGE_8822B) << BIT_SHIFT_ROM_PGE_8822B)
+#define BIT_GET_ROM_PGE_8822B(x) \
+ (((x) >> BIT_SHIFT_ROM_PGE_8822B) & BIT_MASK_ROM_PGE_8822B)
+
+#define BIT_FW_INIT_RDY_8822B BIT(15)
+#define BIT_FW_DW_RDY_8822B BIT(14)
+
+#define BIT_SHIFT_CPU_CLK_SEL_8822B 12
+#define BIT_MASK_CPU_CLK_SEL_8822B 0x3
+#define BIT_CPU_CLK_SEL_8822B(x) \
+ (((x) & BIT_MASK_CPU_CLK_SEL_8822B) << BIT_SHIFT_CPU_CLK_SEL_8822B)
+#define BIT_GET_CPU_CLK_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_CPU_CLK_SEL_8822B) & BIT_MASK_CPU_CLK_SEL_8822B)
+
+#define BIT_CCLK_CHG_MASK_8822B BIT(11)
+#define BIT_EMEM__TXBUF_CHKSUM_OK_8822B BIT(10)
+#define BIT_EMEM_TXBUF_DW_RDY_8822B BIT(9)
+#define BIT_EMEM_CHKSUM_OK_8822B BIT(8)
+#define BIT_EMEM_DW_OK_8822B BIT(7)
+#define BIT_DMEM_CHKSUM_OK_8822B BIT(6)
+#define BIT_DMEM_DW_OK_8822B BIT(5)
+#define BIT_IMEM_CHKSUM_OK_8822B BIT(4)
+#define BIT_IMEM_DW_OK_8822B BIT(3)
+#define BIT_IMEM_BOOT_LOAD_CHKSUM_OK_8822B BIT(2)
+#define BIT_IMEM_BOOT_LOAD_DW_OK_8822B BIT(1)
+#define BIT_MCUFWDL_EN_8822B BIT(0)
+
+/* 2 REG_MCU_TST_CFG_8822B */
+
+#define BIT_SHIFT_LBKTST_8822B 0
+#define BIT_MASK_LBKTST_8822B 0xffff
+#define BIT_LBKTST_8822B(x) \
+ (((x) & BIT_MASK_LBKTST_8822B) << BIT_SHIFT_LBKTST_8822B)
+#define BIT_GET_LBKTST_8822B(x) \
+ (((x) >> BIT_SHIFT_LBKTST_8822B) & BIT_MASK_LBKTST_8822B)
+
+/* 2 REG_HMEBOX_E0_E1_8822B */
+
+#define BIT_SHIFT_HOST_MSG_E1_8822B 16
+#define BIT_MASK_HOST_MSG_E1_8822B 0xffff
+#define BIT_HOST_MSG_E1_8822B(x) \
+ (((x) & BIT_MASK_HOST_MSG_E1_8822B) << BIT_SHIFT_HOST_MSG_E1_8822B)
+#define BIT_GET_HOST_MSG_E1_8822B(x) \
+ (((x) >> BIT_SHIFT_HOST_MSG_E1_8822B) & BIT_MASK_HOST_MSG_E1_8822B)
+
+#define BIT_SHIFT_HOST_MSG_E0_8822B 0
+#define BIT_MASK_HOST_MSG_E0_8822B 0xffff
+#define BIT_HOST_MSG_E0_8822B(x) \
+ (((x) & BIT_MASK_HOST_MSG_E0_8822B) << BIT_SHIFT_HOST_MSG_E0_8822B)
+#define BIT_GET_HOST_MSG_E0_8822B(x) \
+ (((x) >> BIT_SHIFT_HOST_MSG_E0_8822B) & BIT_MASK_HOST_MSG_E0_8822B)
+
+/* 2 REG_HMEBOX_E2_E3_8822B */
+
+#define BIT_SHIFT_HOST_MSG_E3_8822B 16
+#define BIT_MASK_HOST_MSG_E3_8822B 0xffff
+#define BIT_HOST_MSG_E3_8822B(x) \
+ (((x) & BIT_MASK_HOST_MSG_E3_8822B) << BIT_SHIFT_HOST_MSG_E3_8822B)
+#define BIT_GET_HOST_MSG_E3_8822B(x) \
+ (((x) >> BIT_SHIFT_HOST_MSG_E3_8822B) & BIT_MASK_HOST_MSG_E3_8822B)
+
+#define BIT_SHIFT_HOST_MSG_E2_8822B 0
+#define BIT_MASK_HOST_MSG_E2_8822B 0xffff
+#define BIT_HOST_MSG_E2_8822B(x) \
+ (((x) & BIT_MASK_HOST_MSG_E2_8822B) << BIT_SHIFT_HOST_MSG_E2_8822B)
+#define BIT_GET_HOST_MSG_E2_8822B(x) \
+ (((x) >> BIT_SHIFT_HOST_MSG_E2_8822B) & BIT_MASK_HOST_MSG_E2_8822B)
+
+/* 2 REG_WLLPS_CTRL_8822B */
+#define BIT_WLLPSOP_EABM_8822B BIT(31)
+#define BIT_WLLPSOP_ACKF_8822B BIT(30)
+#define BIT_WLLPSOP_DLDM_8822B BIT(29)
+#define BIT_WLLPSOP_ESWR_8822B BIT(28)
+#define BIT_WLLPSOP_PWMM_8822B BIT(27)
+#define BIT_WLLPSOP_EECK_8822B BIT(26)
+#define BIT_WLLPSOP_WLMACOFF_8822B BIT(25)
+#define BIT_WLLPSOP_EXTAL_8822B BIT(24)
+#define BIT_WL_SYNPON_VOLTSPDN_8822B BIT(23)
+#define BIT_WLLPSOP_WLBBOFF_8822B BIT(22)
+#define BIT_WLLPSOP_WLMEM_DS_8822B BIT(21)
+
+#define BIT_SHIFT_LPLDH12_VADJ_STEP_DN_8822B 12
+#define BIT_MASK_LPLDH12_VADJ_STEP_DN_8822B 0xf
+#define BIT_LPLDH12_VADJ_STEP_DN_8822B(x) \
+ (((x) & BIT_MASK_LPLDH12_VADJ_STEP_DN_8822B) \
+ << BIT_SHIFT_LPLDH12_VADJ_STEP_DN_8822B)
+#define BIT_GET_LPLDH12_VADJ_STEP_DN_8822B(x) \
+ (((x) >> BIT_SHIFT_LPLDH12_VADJ_STEP_DN_8822B) & \
+ BIT_MASK_LPLDH12_VADJ_STEP_DN_8822B)
+
+#define BIT_SHIFT_V15ADJ_L1_STEP_DN_8822B 8
+#define BIT_MASK_V15ADJ_L1_STEP_DN_8822B 0x7
+#define BIT_V15ADJ_L1_STEP_DN_8822B(x) \
+ (((x) & BIT_MASK_V15ADJ_L1_STEP_DN_8822B) \
+ << BIT_SHIFT_V15ADJ_L1_STEP_DN_8822B)
+#define BIT_GET_V15ADJ_L1_STEP_DN_8822B(x) \
+ (((x) >> BIT_SHIFT_V15ADJ_L1_STEP_DN_8822B) & \
+ BIT_MASK_V15ADJ_L1_STEP_DN_8822B)
+
+#define BIT_REGU_32K_CLK_EN_8822B BIT(1)
+#define BIT_WL_LPS_EN_8822B BIT(0)
+
+/* 2 REG_AFE_CTRL5_8822B */
+#define BIT_BB_DBG_SEL_AFE_SDM_BIT0_8822B BIT(31)
+#define BIT_ORDER_SDM_8822B BIT(30)
+#define BIT_RFE_SEL_SDM_8822B BIT(29)
+
+#define BIT_SHIFT_REF_SEL_8822B 25
+#define BIT_MASK_REF_SEL_8822B 0xf
+#define BIT_REF_SEL_8822B(x) \
+ (((x) & BIT_MASK_REF_SEL_8822B) << BIT_SHIFT_REF_SEL_8822B)
+#define BIT_GET_REF_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_REF_SEL_8822B) & BIT_MASK_REF_SEL_8822B)
+
+#define BIT_SHIFT_F0F_SDM_8822B 12
+#define BIT_MASK_F0F_SDM_8822B 0x1fff
+#define BIT_F0F_SDM_8822B(x) \
+ (((x) & BIT_MASK_F0F_SDM_8822B) << BIT_SHIFT_F0F_SDM_8822B)
+#define BIT_GET_F0F_SDM_8822B(x) \
+ (((x) >> BIT_SHIFT_F0F_SDM_8822B) & BIT_MASK_F0F_SDM_8822B)
+
+#define BIT_SHIFT_F0N_SDM_8822B 9
+#define BIT_MASK_F0N_SDM_8822B 0x7
+#define BIT_F0N_SDM_8822B(x) \
+ (((x) & BIT_MASK_F0N_SDM_8822B) << BIT_SHIFT_F0N_SDM_8822B)
+#define BIT_GET_F0N_SDM_8822B(x) \
+ (((x) >> BIT_SHIFT_F0N_SDM_8822B) & BIT_MASK_F0N_SDM_8822B)
+
+#define BIT_SHIFT_DIVN_SDM_8822B 3
+#define BIT_MASK_DIVN_SDM_8822B 0x3f
+#define BIT_DIVN_SDM_8822B(x) \
+ (((x) & BIT_MASK_DIVN_SDM_8822B) << BIT_SHIFT_DIVN_SDM_8822B)
+#define BIT_GET_DIVN_SDM_8822B(x) \
+ (((x) >> BIT_SHIFT_DIVN_SDM_8822B) & BIT_MASK_DIVN_SDM_8822B)
+
+/* 2 REG_GPIO_DEBOUNCE_CTRL_8822B */
+#define BIT_WLGP_DBC1EN_8822B BIT(15)
+
+#define BIT_SHIFT_WLGP_DBC1_8822B 8
+#define BIT_MASK_WLGP_DBC1_8822B 0xf
+#define BIT_WLGP_DBC1_8822B(x) \
+ (((x) & BIT_MASK_WLGP_DBC1_8822B) << BIT_SHIFT_WLGP_DBC1_8822B)
+#define BIT_GET_WLGP_DBC1_8822B(x) \
+ (((x) >> BIT_SHIFT_WLGP_DBC1_8822B) & BIT_MASK_WLGP_DBC1_8822B)
+
+#define BIT_WLGP_DBC0EN_8822B BIT(7)
+
+#define BIT_SHIFT_WLGP_DBC0_8822B 0
+#define BIT_MASK_WLGP_DBC0_8822B 0xf
+#define BIT_WLGP_DBC0_8822B(x) \
+ (((x) & BIT_MASK_WLGP_DBC0_8822B) << BIT_SHIFT_WLGP_DBC0_8822B)
+#define BIT_GET_WLGP_DBC0_8822B(x) \
+ (((x) >> BIT_SHIFT_WLGP_DBC0_8822B) & BIT_MASK_WLGP_DBC0_8822B)
+
+/* 2 REG_RPWM2_8822B */
+
+#define BIT_SHIFT_RPWM2_8822B 16
+#define BIT_MASK_RPWM2_8822B 0xffff
+#define BIT_RPWM2_8822B(x) \
+ (((x) & BIT_MASK_RPWM2_8822B) << BIT_SHIFT_RPWM2_8822B)
+#define BIT_GET_RPWM2_8822B(x) \
+ (((x) >> BIT_SHIFT_RPWM2_8822B) & BIT_MASK_RPWM2_8822B)
+
+/* 2 REG_SYSON_FSM_MON_8822B */
+
+#define BIT_SHIFT_FSM_MON_SEL_8822B 24
+#define BIT_MASK_FSM_MON_SEL_8822B 0x7
+#define BIT_FSM_MON_SEL_8822B(x) \
+ (((x) & BIT_MASK_FSM_MON_SEL_8822B) << BIT_SHIFT_FSM_MON_SEL_8822B)
+#define BIT_GET_FSM_MON_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_FSM_MON_SEL_8822B) & BIT_MASK_FSM_MON_SEL_8822B)
+
+#define BIT_DOP_ELDO_8822B BIT(23)
+#define BIT_FSM_MON_UPD_8822B BIT(15)
+
+#define BIT_SHIFT_FSM_PAR_8822B 0
+#define BIT_MASK_FSM_PAR_8822B 0x7fff
+#define BIT_FSM_PAR_8822B(x) \
+ (((x) & BIT_MASK_FSM_PAR_8822B) << BIT_SHIFT_FSM_PAR_8822B)
+#define BIT_GET_FSM_PAR_8822B(x) \
+ (((x) >> BIT_SHIFT_FSM_PAR_8822B) & BIT_MASK_FSM_PAR_8822B)
+
+/* 2 REG_AFE_CTRL6_8822B */
+
+#define BIT_SHIFT_BB_DBG_SEL_AFE_SDM_BIT3_1_8822B 0
+#define BIT_MASK_BB_DBG_SEL_AFE_SDM_BIT3_1_8822B 0x7
+#define BIT_BB_DBG_SEL_AFE_SDM_BIT3_1_8822B(x) \
+ (((x) & BIT_MASK_BB_DBG_SEL_AFE_SDM_BIT3_1_8822B) \
+ << BIT_SHIFT_BB_DBG_SEL_AFE_SDM_BIT3_1_8822B)
+#define BIT_GET_BB_DBG_SEL_AFE_SDM_BIT3_1_8822B(x) \
+ (((x) >> BIT_SHIFT_BB_DBG_SEL_AFE_SDM_BIT3_1_8822B) & \
+ BIT_MASK_BB_DBG_SEL_AFE_SDM_BIT3_1_8822B)
+
+/* 2 REG_PMC_DBG_CTRL1_8822B */
+#define BIT_BT_INT_EN_8822B BIT(31)
+
+#define BIT_SHIFT_RD_WR_WIFI_BT_INFO_8822B 16
+#define BIT_MASK_RD_WR_WIFI_BT_INFO_8822B 0x7fff
+#define BIT_RD_WR_WIFI_BT_INFO_8822B(x) \
+ (((x) & BIT_MASK_RD_WR_WIFI_BT_INFO_8822B) \
+ << BIT_SHIFT_RD_WR_WIFI_BT_INFO_8822B)
+#define BIT_GET_RD_WR_WIFI_BT_INFO_8822B(x) \
+ (((x) >> BIT_SHIFT_RD_WR_WIFI_BT_INFO_8822B) & \
+ BIT_MASK_RD_WR_WIFI_BT_INFO_8822B)
+
+#define BIT_PMC_WR_OVF_8822B BIT(8)
+
+#define BIT_SHIFT_WLPMC_ERRINT_8822B 0
+#define BIT_MASK_WLPMC_ERRINT_8822B 0xff
+#define BIT_WLPMC_ERRINT_8822B(x) \
+ (((x) & BIT_MASK_WLPMC_ERRINT_8822B) << BIT_SHIFT_WLPMC_ERRINT_8822B)
+#define BIT_GET_WLPMC_ERRINT_8822B(x) \
+ (((x) >> BIT_SHIFT_WLPMC_ERRINT_8822B) & BIT_MASK_WLPMC_ERRINT_8822B)
+
+/* 2 REG_AFE_CTRL7_8822B */
+
+#define BIT_SHIFT_SEL_V_8822B 30
+#define BIT_MASK_SEL_V_8822B 0x3
+#define BIT_SEL_V_8822B(x) \
+ (((x) & BIT_MASK_SEL_V_8822B) << BIT_SHIFT_SEL_V_8822B)
+#define BIT_GET_SEL_V_8822B(x) \
+ (((x) >> BIT_SHIFT_SEL_V_8822B) & BIT_MASK_SEL_V_8822B)
+
+#define BIT_SEL_LDO_PC_8822B BIT(29)
+
+#define BIT_SHIFT_CK_MON_SEL_8822B 26
+#define BIT_MASK_CK_MON_SEL_8822B 0x7
+#define BIT_CK_MON_SEL_8822B(x) \
+ (((x) & BIT_MASK_CK_MON_SEL_8822B) << BIT_SHIFT_CK_MON_SEL_8822B)
+#define BIT_GET_CK_MON_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_CK_MON_SEL_8822B) & BIT_MASK_CK_MON_SEL_8822B)
+
+#define BIT_CK_MON_EN_8822B BIT(25)
+#define BIT_FREF_EDGE_8822B BIT(24)
+#define BIT_CK320M_EN_8822B BIT(23)
+#define BIT_CK_5M_EN_8822B BIT(22)
+#define BIT_TESTEN_8822B BIT(21)
+
+/* 2 REG_HIMR0_8822B */
+#define BIT_TIMEOUT_INTERRUPT2_MASK_8822B BIT(31)
+#define BIT_TIMEOUT_INTERRUTP1_MASK_8822B BIT(30)
+#define BIT_PSTIMEOUT_MSK_8822B BIT(29)
+#define BIT_GTINT4_MSK_8822B BIT(28)
+#define BIT_GTINT3_MSK_8822B BIT(27)
+#define BIT_TXBCN0ERR_MSK_8822B BIT(26)
+#define BIT_TXBCN0OK_MSK_8822B BIT(25)
+#define BIT_TSF_BIT32_TOGGLE_MSK_8822B BIT(24)
+#define BIT_BCNDMAINT0_MSK_8822B BIT(20)
+#define BIT_BCNDERR0_MSK_8822B BIT(16)
+#define BIT_HSISR_IND_ON_INT_MSK_8822B BIT(15)
+#define BIT_BCNDMAINT_E_MSK_8822B BIT(14)
+#define BIT_CTWEND_MSK_8822B BIT(12)
+#define BIT_HISR1_IND_MSK_8822B BIT(11)
+#define BIT_C2HCMD_MSK_8822B BIT(10)
+#define BIT_CPWM2_MSK_8822B BIT(9)
+#define BIT_CPWM_MSK_8822B BIT(8)
+#define BIT_HIGHDOK_MSK_8822B BIT(7)
+#define BIT_MGTDOK_MSK_8822B BIT(6)
+#define BIT_BKDOK_MSK_8822B BIT(5)
+#define BIT_BEDOK_MSK_8822B BIT(4)
+#define BIT_VIDOK_MSK_8822B BIT(3)
+#define BIT_VODOK_MSK_8822B BIT(2)
+#define BIT_RDU_MSK_8822B BIT(1)
+#define BIT_RXOK_MSK_8822B BIT(0)
+
+/* 2 REG_HISR0_8822B */
+#define BIT_TIMEOUT_INTERRUPT2_8822B BIT(31)
+#define BIT_TIMEOUT_INTERRUTP1_8822B BIT(30)
+#define BIT_PSTIMEOUT_8822B BIT(29)
+#define BIT_GTINT4_8822B BIT(28)
+#define BIT_GTINT3_8822B BIT(27)
+#define BIT_TXBCN0ERR_8822B BIT(26)
+#define BIT_TXBCN0OK_8822B BIT(25)
+#define BIT_TSF_BIT32_TOGGLE_8822B BIT(24)
+#define BIT_BCNDMAINT0_8822B BIT(20)
+#define BIT_BCNDERR0_8822B BIT(16)
+#define BIT_HSISR_IND_ON_INT_8822B BIT(15)
+#define BIT_BCNDMAINT_E_8822B BIT(14)
+#define BIT_CTWEND_8822B BIT(12)
+#define BIT_HISR1_IND_INT_8822B BIT(11)
+#define BIT_C2HCMD_8822B BIT(10)
+#define BIT_CPWM2_8822B BIT(9)
+#define BIT_CPWM_8822B BIT(8)
+#define BIT_HIGHDOK_8822B BIT(7)
+#define BIT_MGTDOK_8822B BIT(6)
+#define BIT_BKDOK_8822B BIT(5)
+#define BIT_BEDOK_8822B BIT(4)
+#define BIT_VIDOK_8822B BIT(3)
+#define BIT_VODOK_8822B BIT(2)
+#define BIT_RDU_8822B BIT(1)
+#define BIT_RXOK_8822B BIT(0)
+
+/* 2 REG_HIMR1_8822B */
+#define BIT_TXFIFO_TH_INT_8822B BIT(30)
+#define BIT_BTON_STS_UPDATE_MASK_8822B BIT(29)
+#define BIT_MCU_ERR_MASK_8822B BIT(28)
+#define BIT_BCNDMAINT7__MSK_8822B BIT(27)
+#define BIT_BCNDMAINT6__MSK_8822B BIT(26)
+#define BIT_BCNDMAINT5__MSK_8822B BIT(25)
+#define BIT_BCNDMAINT4__MSK_8822B BIT(24)
+#define BIT_BCNDMAINT3_MSK_8822B BIT(23)
+#define BIT_BCNDMAINT2_MSK_8822B BIT(22)
+#define BIT_BCNDMAINT1_MSK_8822B BIT(21)
+#define BIT_BCNDERR7_MSK_8822B BIT(20)
+#define BIT_BCNDERR6_MSK_8822B BIT(19)
+#define BIT_BCNDERR5_MSK_8822B BIT(18)
+#define BIT_BCNDERR4_MSK_8822B BIT(17)
+#define BIT_BCNDERR3_MSK_8822B BIT(16)
+#define BIT_BCNDERR2_MSK_8822B BIT(15)
+#define BIT_BCNDERR1_MSK_8822B BIT(14)
+#define BIT_ATIMEND_E_MSK_8822B BIT(13)
+#define BIT_ATIMEND__MSK_8822B BIT(12)
+#define BIT_TXERR_MSK_8822B BIT(11)
+#define BIT_RXERR_MSK_8822B BIT(10)
+#define BIT_TXFOVW_MSK_8822B BIT(9)
+#define BIT_FOVW_MSK_8822B BIT(8)
+#define BIT_CPU_MGQ_TXDONE_MSK_8822B BIT(5)
+#define BIT_PS_TIMER_C_MSK_8822B BIT(4)
+#define BIT_PS_TIMER_B_MSK_8822B BIT(3)
+#define BIT_PS_TIMER_A_MSK_8822B BIT(2)
+#define BIT_CPUMGQ_TX_TIMER_MSK_8822B BIT(1)
+
+/* 2 REG_HISR1_8822B */
+#define BIT_TXFIFO_TH_INT_8822B BIT(30)
+#define BIT_BTON_STS_UPDATE_INT_8822B BIT(29)
+#define BIT_MCU_ERR_8822B BIT(28)
+#define BIT_BCNDMAINT7_8822B BIT(27)
+#define BIT_BCNDMAINT6_8822B BIT(26)
+#define BIT_BCNDMAINT5_8822B BIT(25)
+#define BIT_BCNDMAINT4_8822B BIT(24)
+#define BIT_BCNDMAINT3_8822B BIT(23)
+#define BIT_BCNDMAINT2_8822B BIT(22)
+#define BIT_BCNDMAINT1_8822B BIT(21)
+#define BIT_BCNDERR7_8822B BIT(20)
+#define BIT_BCNDERR6_8822B BIT(19)
+#define BIT_BCNDERR5_8822B BIT(18)
+#define BIT_BCNDERR4_8822B BIT(17)
+#define BIT_BCNDERR3_8822B BIT(16)
+#define BIT_BCNDERR2_8822B BIT(15)
+#define BIT_BCNDERR1_8822B BIT(14)
+#define BIT_ATIMEND_E_8822B BIT(13)
+#define BIT_ATIMEND_8822B BIT(12)
+#define BIT_TXERR_INT_8822B BIT(11)
+#define BIT_RXERR_INT_8822B BIT(10)
+#define BIT_TXFOVW_8822B BIT(9)
+#define BIT_FOVW_8822B BIT(8)
+#define BIT_CPU_MGQ_TXDONE_8822B BIT(5)
+#define BIT_PS_TIMER_C_8822B BIT(4)
+#define BIT_PS_TIMER_B_8822B BIT(3)
+#define BIT_PS_TIMER_A_8822B BIT(2)
+#define BIT_CPUMGQ_TX_TIMER_8822B BIT(1)
+
+/* 2 REG_DBG_PORT_SEL_8822B */
+
+#define BIT_SHIFT_DEBUG_ST_8822B 0
+#define BIT_MASK_DEBUG_ST_8822B 0xffffffffL
+#define BIT_DEBUG_ST_8822B(x) \
+ (((x) & BIT_MASK_DEBUG_ST_8822B) << BIT_SHIFT_DEBUG_ST_8822B)
+#define BIT_GET_DEBUG_ST_8822B(x) \
+ (((x) >> BIT_SHIFT_DEBUG_ST_8822B) & BIT_MASK_DEBUG_ST_8822B)
+
+/* 2 REG_PAD_CTRL2_8822B */
+#define BIT_USB3_USB2_TRANSITION_8822B BIT(20)
+
+#define BIT_SHIFT_USB23_SW_MODE_V1_8822B 18
+#define BIT_MASK_USB23_SW_MODE_V1_8822B 0x3
+#define BIT_USB23_SW_MODE_V1_8822B(x) \
+ (((x) & BIT_MASK_USB23_SW_MODE_V1_8822B) \
+ << BIT_SHIFT_USB23_SW_MODE_V1_8822B)
+#define BIT_GET_USB23_SW_MODE_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_USB23_SW_MODE_V1_8822B) & \
+ BIT_MASK_USB23_SW_MODE_V1_8822B)
+
+#define BIT_NO_PDN_CHIPOFF_V1_8822B BIT(17)
+#define BIT_RSM_EN_V1_8822B BIT(16)
+
+#define BIT_SHIFT_MATCH_CNT_8822B 8
+#define BIT_MASK_MATCH_CNT_8822B 0xff
+#define BIT_MATCH_CNT_8822B(x) \
+ (((x) & BIT_MASK_MATCH_CNT_8822B) << BIT_SHIFT_MATCH_CNT_8822B)
+#define BIT_GET_MATCH_CNT_8822B(x) \
+ (((x) >> BIT_SHIFT_MATCH_CNT_8822B) & BIT_MASK_MATCH_CNT_8822B)
+
+#define BIT_LD_B12V_EN_8822B BIT(7)
+#define BIT_EECS_IOSEL_V1_8822B BIT(6)
+#define BIT_EECS_DATA_O_V1_8822B BIT(5)
+#define BIT_EECS_DATA_I_V1_8822B BIT(4)
+#define BIT_EESK_IOSEL_V1_8822B BIT(2)
+#define BIT_EESK_DATA_O_V1_8822B BIT(1)
+#define BIT_EESK_DATA_I_V1_8822B BIT(0)
+
+/* 2 REG_NOT_VALID_8822B */
+
+/* 2 REG_PMC_DBG_CTRL2_8822B */
+
+#define BIT_SHIFT_EFUSE_BURN_GNT_8822B 24
+#define BIT_MASK_EFUSE_BURN_GNT_8822B 0xff
+#define BIT_EFUSE_BURN_GNT_8822B(x) \
+ (((x) & BIT_MASK_EFUSE_BURN_GNT_8822B) \
+ << BIT_SHIFT_EFUSE_BURN_GNT_8822B)
+#define BIT_GET_EFUSE_BURN_GNT_8822B(x) \
+ (((x) >> BIT_SHIFT_EFUSE_BURN_GNT_8822B) & \
+ BIT_MASK_EFUSE_BURN_GNT_8822B)
+
+#define BIT_STOP_WL_PMC_8822B BIT(9)
+#define BIT_STOP_SYM_PMC_8822B BIT(8)
+#define BIT_REG_RST_WLPMC_8822B BIT(5)
+#define BIT_REG_RST_PD12N_8822B BIT(4)
+#define BIT_SYSON_DIS_WLREG_WRMSK_8822B BIT(3)
+#define BIT_SYSON_DIS_PMCREG_WRMSK_8822B BIT(2)
+
+#define BIT_SHIFT_SYSON_REG_ARB_8822B 0
+#define BIT_MASK_SYSON_REG_ARB_8822B 0x3
+#define BIT_SYSON_REG_ARB_8822B(x) \
+ (((x) & BIT_MASK_SYSON_REG_ARB_8822B) << BIT_SHIFT_SYSON_REG_ARB_8822B)
+#define BIT_GET_SYSON_REG_ARB_8822B(x) \
+ (((x) >> BIT_SHIFT_SYSON_REG_ARB_8822B) & BIT_MASK_SYSON_REG_ARB_8822B)
+
+/* 2 REG_BIST_CTRL_8822B */
+#define BIT_BIST_USB_DIS_8822B BIT(27)
+#define BIT_BIST_PCI_DIS_8822B BIT(26)
+#define BIT_BIST_BT_DIS_8822B BIT(25)
+#define BIT_BIST_WL_DIS_8822B BIT(24)
+
+#define BIT_SHIFT_BIST_RPT_SEL_8822B 16
+#define BIT_MASK_BIST_RPT_SEL_8822B 0xf
+#define BIT_BIST_RPT_SEL_8822B(x) \
+ (((x) & BIT_MASK_BIST_RPT_SEL_8822B) << BIT_SHIFT_BIST_RPT_SEL_8822B)
+#define BIT_GET_BIST_RPT_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_BIST_RPT_SEL_8822B) & BIT_MASK_BIST_RPT_SEL_8822B)
+
+#define BIT_BIST_RESUME_PS_8822B BIT(4)
+#define BIT_BIST_RESUME_8822B BIT(3)
+#define BIT_BIST_NORMAL_8822B BIT(2)
+#define BIT_BIST_RSTN_8822B BIT(1)
+#define BIT_BIST_CLK_EN_8822B BIT(0)
+
+/* 2 REG_BIST_RPT_8822B */
+
+#define BIT_SHIFT_MBIST_REPORT_8822B 0
+#define BIT_MASK_MBIST_REPORT_8822B 0xffffffffL
+#define BIT_MBIST_REPORT_8822B(x) \
+ (((x) & BIT_MASK_MBIST_REPORT_8822B) << BIT_SHIFT_MBIST_REPORT_8822B)
+#define BIT_GET_MBIST_REPORT_8822B(x) \
+ (((x) >> BIT_SHIFT_MBIST_REPORT_8822B) & BIT_MASK_MBIST_REPORT_8822B)
+
+/* 2 REG_MEM_CTRL_8822B */
+#define BIT_UMEM_RME_8822B BIT(31)
+
+#define BIT_SHIFT_BT_SPRAM_8822B 28
+#define BIT_MASK_BT_SPRAM_8822B 0x3
+#define BIT_BT_SPRAM_8822B(x) \
+ (((x) & BIT_MASK_BT_SPRAM_8822B) << BIT_SHIFT_BT_SPRAM_8822B)
+#define BIT_GET_BT_SPRAM_8822B(x) \
+ (((x) >> BIT_SHIFT_BT_SPRAM_8822B) & BIT_MASK_BT_SPRAM_8822B)
+
+#define BIT_SHIFT_BT_ROM_8822B 24
+#define BIT_MASK_BT_ROM_8822B 0xf
+#define BIT_BT_ROM_8822B(x) \
+ (((x) & BIT_MASK_BT_ROM_8822B) << BIT_SHIFT_BT_ROM_8822B)
+#define BIT_GET_BT_ROM_8822B(x) \
+ (((x) >> BIT_SHIFT_BT_ROM_8822B) & BIT_MASK_BT_ROM_8822B)
+
+#define BIT_SHIFT_PCI_DPRAM_8822B 10
+#define BIT_MASK_PCI_DPRAM_8822B 0x3
+#define BIT_PCI_DPRAM_8822B(x) \
+ (((x) & BIT_MASK_PCI_DPRAM_8822B) << BIT_SHIFT_PCI_DPRAM_8822B)
+#define BIT_GET_PCI_DPRAM_8822B(x) \
+ (((x) >> BIT_SHIFT_PCI_DPRAM_8822B) & BIT_MASK_PCI_DPRAM_8822B)
+
+#define BIT_SHIFT_PCI_SPRAM_8822B 8
+#define BIT_MASK_PCI_SPRAM_8822B 0x3
+#define BIT_PCI_SPRAM_8822B(x) \
+ (((x) & BIT_MASK_PCI_SPRAM_8822B) << BIT_SHIFT_PCI_SPRAM_8822B)
+#define BIT_GET_PCI_SPRAM_8822B(x) \
+ (((x) >> BIT_SHIFT_PCI_SPRAM_8822B) & BIT_MASK_PCI_SPRAM_8822B)
+
+#define BIT_SHIFT_USB_SPRAM_8822B 6
+#define BIT_MASK_USB_SPRAM_8822B 0x3
+#define BIT_USB_SPRAM_8822B(x) \
+ (((x) & BIT_MASK_USB_SPRAM_8822B) << BIT_SHIFT_USB_SPRAM_8822B)
+#define BIT_GET_USB_SPRAM_8822B(x) \
+ (((x) >> BIT_SHIFT_USB_SPRAM_8822B) & BIT_MASK_USB_SPRAM_8822B)
+
+#define BIT_SHIFT_USB_SPRF_8822B 4
+#define BIT_MASK_USB_SPRF_8822B 0x3
+#define BIT_USB_SPRF_8822B(x) \
+ (((x) & BIT_MASK_USB_SPRF_8822B) << BIT_SHIFT_USB_SPRF_8822B)
+#define BIT_GET_USB_SPRF_8822B(x) \
+ (((x) >> BIT_SHIFT_USB_SPRF_8822B) & BIT_MASK_USB_SPRF_8822B)
+
+#define BIT_SHIFT_MCU_ROM_8822B 0
+#define BIT_MASK_MCU_ROM_8822B 0xf
+#define BIT_MCU_ROM_8822B(x) \
+ (((x) & BIT_MASK_MCU_ROM_8822B) << BIT_SHIFT_MCU_ROM_8822B)
+#define BIT_GET_MCU_ROM_8822B(x) \
+ (((x) >> BIT_SHIFT_MCU_ROM_8822B) & BIT_MASK_MCU_ROM_8822B)
+
+/* 2 REG_AFE_CTRL8_8822B */
+#define BIT_SYN_AGPIO_8822B BIT(20)
+#define BIT_XTAL_LP_8822B BIT(4)
+#define BIT_XTAL_GM_SEP_8822B BIT(3)
+
+#define BIT_SHIFT_XTAL_SEL_TOK_8822B 0
+#define BIT_MASK_XTAL_SEL_TOK_8822B 0x7
+#define BIT_XTAL_SEL_TOK_8822B(x) \
+ (((x) & BIT_MASK_XTAL_SEL_TOK_8822B) << BIT_SHIFT_XTAL_SEL_TOK_8822B)
+#define BIT_GET_XTAL_SEL_TOK_8822B(x) \
+ (((x) >> BIT_SHIFT_XTAL_SEL_TOK_8822B) & BIT_MASK_XTAL_SEL_TOK_8822B)
+
+/* 2 REG_USB_SIE_INTF_8822B */
+#define BIT_RD_SEL_8822B BIT(31)
+#define BIT_USB_SIE_INTF_WE_V1_8822B BIT(30)
+#define BIT_USB_SIE_INTF_BYIOREG_V1_8822B BIT(29)
+#define BIT_USB_SIE_SELECT_8822B BIT(28)
+
+#define BIT_SHIFT_USB_SIE_INTF_ADDR_V1_8822B 16
+#define BIT_MASK_USB_SIE_INTF_ADDR_V1_8822B 0x1ff
+#define BIT_USB_SIE_INTF_ADDR_V1_8822B(x) \
+ (((x) & BIT_MASK_USB_SIE_INTF_ADDR_V1_8822B) \
+ << BIT_SHIFT_USB_SIE_INTF_ADDR_V1_8822B)
+#define BIT_GET_USB_SIE_INTF_ADDR_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_USB_SIE_INTF_ADDR_V1_8822B) & \
+ BIT_MASK_USB_SIE_INTF_ADDR_V1_8822B)
+
+#define BIT_SHIFT_USB_SIE_INTF_RD_8822B 8
+#define BIT_MASK_USB_SIE_INTF_RD_8822B 0xff
+#define BIT_USB_SIE_INTF_RD_8822B(x) \
+ (((x) & BIT_MASK_USB_SIE_INTF_RD_8822B) \
+ << BIT_SHIFT_USB_SIE_INTF_RD_8822B)
+#define BIT_GET_USB_SIE_INTF_RD_8822B(x) \
+ (((x) >> BIT_SHIFT_USB_SIE_INTF_RD_8822B) & \
+ BIT_MASK_USB_SIE_INTF_RD_8822B)
+
+#define BIT_SHIFT_USB_SIE_INTF_WD_8822B 0
+#define BIT_MASK_USB_SIE_INTF_WD_8822B 0xff
+#define BIT_USB_SIE_INTF_WD_8822B(x) \
+ (((x) & BIT_MASK_USB_SIE_INTF_WD_8822B) \
+ << BIT_SHIFT_USB_SIE_INTF_WD_8822B)
+#define BIT_GET_USB_SIE_INTF_WD_8822B(x) \
+ (((x) >> BIT_SHIFT_USB_SIE_INTF_WD_8822B) & \
+ BIT_MASK_USB_SIE_INTF_WD_8822B)
+
+/* 2 REG_PCIE_MIO_INTF_8822B */
+#define BIT_PCIE_MIO_BYIOREG_8822B BIT(13)
+#define BIT_PCIE_MIO_RE_8822B BIT(12)
+
+#define BIT_SHIFT_PCIE_MIO_WE_8822B 8
+#define BIT_MASK_PCIE_MIO_WE_8822B 0xf
+#define BIT_PCIE_MIO_WE_8822B(x) \
+ (((x) & BIT_MASK_PCIE_MIO_WE_8822B) << BIT_SHIFT_PCIE_MIO_WE_8822B)
+#define BIT_GET_PCIE_MIO_WE_8822B(x) \
+ (((x) >> BIT_SHIFT_PCIE_MIO_WE_8822B) & BIT_MASK_PCIE_MIO_WE_8822B)
+
+#define BIT_SHIFT_PCIE_MIO_ADDR_8822B 0
+#define BIT_MASK_PCIE_MIO_ADDR_8822B 0xff
+#define BIT_PCIE_MIO_ADDR_8822B(x) \
+ (((x) & BIT_MASK_PCIE_MIO_ADDR_8822B) << BIT_SHIFT_PCIE_MIO_ADDR_8822B)
+#define BIT_GET_PCIE_MIO_ADDR_8822B(x) \
+ (((x) >> BIT_SHIFT_PCIE_MIO_ADDR_8822B) & BIT_MASK_PCIE_MIO_ADDR_8822B)
+
+/* 2 REG_PCIE_MIO_INTD_8822B */
+
+#define BIT_SHIFT_PCIE_MIO_DATA_8822B 0
+#define BIT_MASK_PCIE_MIO_DATA_8822B 0xffffffffL
+#define BIT_PCIE_MIO_DATA_8822B(x) \
+ (((x) & BIT_MASK_PCIE_MIO_DATA_8822B) << BIT_SHIFT_PCIE_MIO_DATA_8822B)
+#define BIT_GET_PCIE_MIO_DATA_8822B(x) \
+ (((x) >> BIT_SHIFT_PCIE_MIO_DATA_8822B) & BIT_MASK_PCIE_MIO_DATA_8822B)
+
+/* 2 REG_WLRF1_8822B */
+
+#define BIT_SHIFT_WLRF1_CTRL_8822B 24
+#define BIT_MASK_WLRF1_CTRL_8822B 0xff
+#define BIT_WLRF1_CTRL_8822B(x) \
+ (((x) & BIT_MASK_WLRF1_CTRL_8822B) << BIT_SHIFT_WLRF1_CTRL_8822B)
+#define BIT_GET_WLRF1_CTRL_8822B(x) \
+ (((x) >> BIT_SHIFT_WLRF1_CTRL_8822B) & BIT_MASK_WLRF1_CTRL_8822B)
+
+/* 2 REG_SYS_CFG1_8822B */
+
+#define BIT_SHIFT_TRP_ICFG_8822B 28
+#define BIT_MASK_TRP_ICFG_8822B 0xf
+#define BIT_TRP_ICFG_8822B(x) \
+ (((x) & BIT_MASK_TRP_ICFG_8822B) << BIT_SHIFT_TRP_ICFG_8822B)
+#define BIT_GET_TRP_ICFG_8822B(x) \
+ (((x) >> BIT_SHIFT_TRP_ICFG_8822B) & BIT_MASK_TRP_ICFG_8822B)
+
+#define BIT_RF_TYPE_ID_8822B BIT(27)
+#define BIT_BD_HCI_SEL_8822B BIT(26)
+#define BIT_BD_PKG_SEL_8822B BIT(25)
+#define BIT_SPSLDO_SEL_8822B BIT(24)
+#define BIT_RTL_ID_8822B BIT(23)
+#define BIT_PAD_HWPD_IDN_8822B BIT(22)
+#define BIT_TESTMODE_8822B BIT(20)
+
+#define BIT_SHIFT_VENDOR_ID_8822B 16
+#define BIT_MASK_VENDOR_ID_8822B 0xf
+#define BIT_VENDOR_ID_8822B(x) \
+ (((x) & BIT_MASK_VENDOR_ID_8822B) << BIT_SHIFT_VENDOR_ID_8822B)
+#define BIT_GET_VENDOR_ID_8822B(x) \
+ (((x) >> BIT_SHIFT_VENDOR_ID_8822B) & BIT_MASK_VENDOR_ID_8822B)
+
+#define BIT_SHIFT_CHIP_VER_8822B 12
+#define BIT_MASK_CHIP_VER_8822B 0xf
+#define BIT_CHIP_VER_8822B(x) \
+ (((x) & BIT_MASK_CHIP_VER_8822B) << BIT_SHIFT_CHIP_VER_8822B)
+#define BIT_GET_CHIP_VER_8822B(x) \
+ (((x) >> BIT_SHIFT_CHIP_VER_8822B) & BIT_MASK_CHIP_VER_8822B)
+
+#define BIT_BD_MAC3_8822B BIT(11)
+#define BIT_BD_MAC1_8822B BIT(10)
+#define BIT_BD_MAC2_8822B BIT(9)
+#define BIT_SIC_IDLE_8822B BIT(8)
+#define BIT_SW_OFFLOAD_EN_8822B BIT(7)
+#define BIT_OCP_SHUTDN_8822B BIT(6)
+#define BIT_V15_VLD_8822B BIT(5)
+#define BIT_PCIRSTB_8822B BIT(4)
+#define BIT_PCLK_VLD_8822B BIT(3)
+#define BIT_UCLK_VLD_8822B BIT(2)
+#define BIT_ACLK_VLD_8822B BIT(1)
+#define BIT_XCLK_VLD_8822B BIT(0)
+
+/* 2 REG_SYS_STATUS1_8822B */
+
+#define BIT_SHIFT_RF_RL_ID_8822B 28
+#define BIT_MASK_RF_RL_ID_8822B 0xf
+#define BIT_RF_RL_ID_8822B(x) \
+ (((x) & BIT_MASK_RF_RL_ID_8822B) << BIT_SHIFT_RF_RL_ID_8822B)
+#define BIT_GET_RF_RL_ID_8822B(x) \
+ (((x) >> BIT_SHIFT_RF_RL_ID_8822B) & BIT_MASK_RF_RL_ID_8822B)
+
+#define BIT_HPHY_ICFG_8822B BIT(19)
+
+#define BIT_SHIFT_SEL_0XC0_8822B 16
+#define BIT_MASK_SEL_0XC0_8822B 0x3
+#define BIT_SEL_0XC0_8822B(x) \
+ (((x) & BIT_MASK_SEL_0XC0_8822B) << BIT_SHIFT_SEL_0XC0_8822B)
+#define BIT_GET_SEL_0XC0_8822B(x) \
+ (((x) >> BIT_SHIFT_SEL_0XC0_8822B) & BIT_MASK_SEL_0XC0_8822B)
+
+#define BIT_SHIFT_HCI_SEL_V3_8822B 12
+#define BIT_MASK_HCI_SEL_V3_8822B 0x7
+#define BIT_HCI_SEL_V3_8822B(x) \
+ (((x) & BIT_MASK_HCI_SEL_V3_8822B) << BIT_SHIFT_HCI_SEL_V3_8822B)
+#define BIT_GET_HCI_SEL_V3_8822B(x) \
+ (((x) >> BIT_SHIFT_HCI_SEL_V3_8822B) & BIT_MASK_HCI_SEL_V3_8822B)
+
+#define BIT_USB_OPERATION_MODE_8822B BIT(10)
+#define BIT_BT_PDN_8822B BIT(9)
+#define BIT_AUTO_WLPON_8822B BIT(8)
+#define BIT_WL_MODE_8822B BIT(7)
+#define BIT_PKG_SEL_HCI_8822B BIT(6)
+
+#define BIT_SHIFT_PAD_HCI_SEL_V1_8822B 3
+#define BIT_MASK_PAD_HCI_SEL_V1_8822B 0x7
+#define BIT_PAD_HCI_SEL_V1_8822B(x) \
+ (((x) & BIT_MASK_PAD_HCI_SEL_V1_8822B) \
+ << BIT_SHIFT_PAD_HCI_SEL_V1_8822B)
+#define BIT_GET_PAD_HCI_SEL_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_PAD_HCI_SEL_V1_8822B) & \
+ BIT_MASK_PAD_HCI_SEL_V1_8822B)
+
+#define BIT_SHIFT_EFS_HCI_SEL_V1_8822B 0
+#define BIT_MASK_EFS_HCI_SEL_V1_8822B 0x7
+#define BIT_EFS_HCI_SEL_V1_8822B(x) \
+ (((x) & BIT_MASK_EFS_HCI_SEL_V1_8822B) \
+ << BIT_SHIFT_EFS_HCI_SEL_V1_8822B)
+#define BIT_GET_EFS_HCI_SEL_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_EFS_HCI_SEL_V1_8822B) & \
+ BIT_MASK_EFS_HCI_SEL_V1_8822B)
+
+/* 2 REG_SYS_STATUS2_8822B */
+#define BIT_SIO_ALDN_8822B BIT(19)
+#define BIT_USB_ALDN_8822B BIT(18)
+#define BIT_PCI_ALDN_8822B BIT(17)
+#define BIT_SYS_ALDN_8822B BIT(16)
+
+#define BIT_SHIFT_EPVID1_8822B 8
+#define BIT_MASK_EPVID1_8822B 0xff
+#define BIT_EPVID1_8822B(x) \
+ (((x) & BIT_MASK_EPVID1_8822B) << BIT_SHIFT_EPVID1_8822B)
+#define BIT_GET_EPVID1_8822B(x) \
+ (((x) >> BIT_SHIFT_EPVID1_8822B) & BIT_MASK_EPVID1_8822B)
+
+#define BIT_SHIFT_EPVID0_8822B 0
+#define BIT_MASK_EPVID0_8822B 0xff
+#define BIT_EPVID0_8822B(x) \
+ (((x) & BIT_MASK_EPVID0_8822B) << BIT_SHIFT_EPVID0_8822B)
+#define BIT_GET_EPVID0_8822B(x) \
+ (((x) >> BIT_SHIFT_EPVID0_8822B) & BIT_MASK_EPVID0_8822B)
+
+/* 2 REG_SYS_CFG2_8822B */
+#define BIT_HCI_SEL_EMBEDDED_8822B BIT(8)
+
+#define BIT_SHIFT_HW_ID_8822B 0
+#define BIT_MASK_HW_ID_8822B 0xff
+#define BIT_HW_ID_8822B(x) \
+ (((x) & BIT_MASK_HW_ID_8822B) << BIT_SHIFT_HW_ID_8822B)
+#define BIT_GET_HW_ID_8822B(x) \
+ (((x) >> BIT_SHIFT_HW_ID_8822B) & BIT_MASK_HW_ID_8822B)
+
+/* 2 REG_SYS_CFG3_8822B */
+#define BIT_PWC_MA33V_8822B BIT(15)
+#define BIT_PWC_MA12V_8822B BIT(14)
+#define BIT_PWC_MD12V_8822B BIT(13)
+#define BIT_PWC_PD12V_8822B BIT(12)
+#define BIT_PWC_UD12V_8822B BIT(11)
+#define BIT_ISO_MA2MD_8822B BIT(1)
+#define BIT_ISO_MD2PP_8822B BIT(0)
+
+/* 2 REG_SYS_CFG4_8822B */
+
+/* 2 REG_SYS_CFG5_8822B */
+#define BIT_LPS_STATUS_8822B BIT(3)
+#define BIT_HCI_TXDMA_BUSY_8822B BIT(2)
+#define BIT_HCI_TXDMA_ALLOW_8822B BIT(1)
+#define BIT_FW_CTRL_HCI_TXDMA_EN_8822B BIT(0)
+
+/* 2 REG_CPU_DMEM_CON_8822B */
+#define BIT_WDT_OPT_IOWRAPPER_8822B BIT(19)
+#define BIT_ANA_PORT_IDLE_8822B BIT(18)
+#define BIT_MAC_PORT_IDLE_8822B BIT(17)
+#define BIT_WL_PLATFORM_RST_8822B BIT(16)
+#define BIT_WL_SECURITY_CLK_8822B BIT(15)
+
+#define BIT_SHIFT_CPU_DMEM_CON_8822B 0
+#define BIT_MASK_CPU_DMEM_CON_8822B 0xff
+#define BIT_CPU_DMEM_CON_8822B(x) \
+ (((x) & BIT_MASK_CPU_DMEM_CON_8822B) << BIT_SHIFT_CPU_DMEM_CON_8822B)
+#define BIT_GET_CPU_DMEM_CON_8822B(x) \
+ (((x) >> BIT_SHIFT_CPU_DMEM_CON_8822B) & BIT_MASK_CPU_DMEM_CON_8822B)
+
+/* 2 REG_BOOT_REASON_8822B */
+
+#define BIT_SHIFT_BOOT_REASON_8822B 0
+#define BIT_MASK_BOOT_REASON_8822B 0x7
+#define BIT_BOOT_REASON_8822B(x) \
+ (((x) & BIT_MASK_BOOT_REASON_8822B) << BIT_SHIFT_BOOT_REASON_8822B)
+#define BIT_GET_BOOT_REASON_8822B(x) \
+ (((x) >> BIT_SHIFT_BOOT_REASON_8822B) & BIT_MASK_BOOT_REASON_8822B)
+
+/* 2 REG_NFCPAD_CTRL_8822B */
+#define BIT_PAD_SHUTDW_8822B BIT(18)
+#define BIT_SYSON_NFC_PAD_8822B BIT(17)
+#define BIT_NFC_INT_PAD_CTRL_8822B BIT(16)
+#define BIT_NFC_RFDIS_PAD_CTRL_8822B BIT(15)
+#define BIT_NFC_CLK_PAD_CTRL_8822B BIT(14)
+#define BIT_NFC_DATA_PAD_CTRL_8822B BIT(13)
+#define BIT_NFC_PAD_PULL_CTRL_8822B BIT(12)
+
+#define BIT_SHIFT_NFCPAD_IO_SEL_8822B 8
+#define BIT_MASK_NFCPAD_IO_SEL_8822B 0xf
+#define BIT_NFCPAD_IO_SEL_8822B(x) \
+ (((x) & BIT_MASK_NFCPAD_IO_SEL_8822B) << BIT_SHIFT_NFCPAD_IO_SEL_8822B)
+#define BIT_GET_NFCPAD_IO_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_NFCPAD_IO_SEL_8822B) & BIT_MASK_NFCPAD_IO_SEL_8822B)
+
+#define BIT_SHIFT_NFCPAD_OUT_8822B 4
+#define BIT_MASK_NFCPAD_OUT_8822B 0xf
+#define BIT_NFCPAD_OUT_8822B(x) \
+ (((x) & BIT_MASK_NFCPAD_OUT_8822B) << BIT_SHIFT_NFCPAD_OUT_8822B)
+#define BIT_GET_NFCPAD_OUT_8822B(x) \
+ (((x) >> BIT_SHIFT_NFCPAD_OUT_8822B) & BIT_MASK_NFCPAD_OUT_8822B)
+
+#define BIT_SHIFT_NFCPAD_IN_8822B 0
+#define BIT_MASK_NFCPAD_IN_8822B 0xf
+#define BIT_NFCPAD_IN_8822B(x) \
+ (((x) & BIT_MASK_NFCPAD_IN_8822B) << BIT_SHIFT_NFCPAD_IN_8822B)
+#define BIT_GET_NFCPAD_IN_8822B(x) \
+ (((x) >> BIT_SHIFT_NFCPAD_IN_8822B) & BIT_MASK_NFCPAD_IN_8822B)
+
+/* 2 REG_HIMR2_8822B */
+#define BIT_BCNDMAINT_P4_MSK_8822B BIT(31)
+#define BIT_BCNDMAINT_P3_MSK_8822B BIT(30)
+#define BIT_BCNDMAINT_P2_MSK_8822B BIT(29)
+#define BIT_BCNDMAINT_P1_MSK_8822B BIT(28)
+#define BIT_ATIMEND7_MSK_8822B BIT(22)
+#define BIT_ATIMEND6_MSK_8822B BIT(21)
+#define BIT_ATIMEND5_MSK_8822B BIT(20)
+#define BIT_ATIMEND4_MSK_8822B BIT(19)
+#define BIT_ATIMEND3_MSK_8822B BIT(18)
+#define BIT_ATIMEND2_MSK_8822B BIT(17)
+#define BIT_ATIMEND1_MSK_8822B BIT(16)
+#define BIT_TXBCN7OK_MSK_8822B BIT(14)
+#define BIT_TXBCN6OK_MSK_8822B BIT(13)
+#define BIT_TXBCN5OK_MSK_8822B BIT(12)
+#define BIT_TXBCN4OK_MSK_8822B BIT(11)
+#define BIT_TXBCN3OK_MSK_8822B BIT(10)
+#define BIT_TXBCN2OK_MSK_8822B BIT(9)
+#define BIT_TXBCN1OK_MSK_V1_8822B BIT(8)
+#define BIT_TXBCN7ERR_MSK_8822B BIT(6)
+#define BIT_TXBCN6ERR_MSK_8822B BIT(5)
+#define BIT_TXBCN5ERR_MSK_8822B BIT(4)
+#define BIT_TXBCN4ERR_MSK_8822B BIT(3)
+#define BIT_TXBCN3ERR_MSK_8822B BIT(2)
+#define BIT_TXBCN2ERR_MSK_8822B BIT(1)
+#define BIT_TXBCN1ERR_MSK_V1_8822B BIT(0)
+
+/* 2 REG_HISR2_8822B */
+#define BIT_BCNDMAINT_P4_8822B BIT(31)
+#define BIT_BCNDMAINT_P3_8822B BIT(30)
+#define BIT_BCNDMAINT_P2_8822B BIT(29)
+#define BIT_BCNDMAINT_P1_8822B BIT(28)
+#define BIT_ATIMEND7_8822B BIT(22)
+#define BIT_ATIMEND6_8822B BIT(21)
+#define BIT_ATIMEND5_8822B BIT(20)
+#define BIT_ATIMEND4_8822B BIT(19)
+#define BIT_ATIMEND3_8822B BIT(18)
+#define BIT_ATIMEND2_8822B BIT(17)
+#define BIT_ATIMEND1_8822B BIT(16)
+#define BIT_TXBCN7OK_8822B BIT(14)
+#define BIT_TXBCN6OK_8822B BIT(13)
+#define BIT_TXBCN5OK_8822B BIT(12)
+#define BIT_TXBCN4OK_8822B BIT(11)
+#define BIT_TXBCN3OK_8822B BIT(10)
+#define BIT_TXBCN2OK_8822B BIT(9)
+#define BIT_TXBCN1OK_8822B BIT(8)
+#define BIT_TXBCN7ERR_8822B BIT(6)
+#define BIT_TXBCN6ERR_8822B BIT(5)
+#define BIT_TXBCN5ERR_8822B BIT(4)
+#define BIT_TXBCN4ERR_8822B BIT(3)
+#define BIT_TXBCN3ERR_8822B BIT(2)
+#define BIT_TXBCN2ERR_8822B BIT(1)
+#define BIT_TXBCN1ERR_8822B BIT(0)
+
+/* 2 REG_HIMR3_8822B */
+#define BIT_WDT_PLATFORM_INT_MSK_8822B BIT(18)
+#define BIT_WDT_CPU_INT_MSK_8822B BIT(17)
+#define BIT_SETH2CDOK_MASK_8822B BIT(16)
+#define BIT_H2C_CMD_FULL_MASK_8822B BIT(15)
+#define BIT_PWR_INT_127_MASK_8822B BIT(14)
+#define BIT_TXSHORTCUT_TXDESUPDATEOK_MASK_8822B BIT(13)
+#define BIT_TXSHORTCUT_BKUPDATEOK_MASK_8822B BIT(12)
+#define BIT_TXSHORTCUT_BEUPDATEOK_MASK_8822B BIT(11)
+#define BIT_TXSHORTCUT_VIUPDATEOK_MAS_8822B BIT(10)
+#define BIT_TXSHORTCUT_VOUPDATEOK_MASK_8822B BIT(9)
+#define BIT_PWR_INT_127_MASK_V1_8822B BIT(8)
+#define BIT_PWR_INT_126TO96_MASK_8822B BIT(7)
+#define BIT_PWR_INT_95TO64_MASK_8822B BIT(6)
+#define BIT_PWR_INT_63TO32_MASK_8822B BIT(5)
+#define BIT_PWR_INT_31TO0_MASK_8822B BIT(4)
+#define BIT_DDMA0_LP_INT_MSK_8822B BIT(1)
+#define BIT_DDMA0_HP_INT_MSK_8822B BIT(0)
+
+/* 2 REG_HISR3_8822B */
+#define BIT_WDT_PLATFORM_INT_8822B BIT(18)
+#define BIT_WDT_CPU_INT_8822B BIT(17)
+#define BIT_SETH2CDOK_8822B BIT(16)
+#define BIT_H2C_CMD_FULL_8822B BIT(15)
+#define BIT_PWR_INT_127_8822B BIT(14)
+#define BIT_TXSHORTCUT_TXDESUPDATEOK_8822B BIT(13)
+#define BIT_TXSHORTCUT_BKUPDATEOK_8822B BIT(12)
+#define BIT_TXSHORTCUT_BEUPDATEOK_8822B BIT(11)
+#define BIT_TXSHORTCUT_VIUPDATEOK_8822B BIT(10)
+#define BIT_TXSHORTCUT_VOUPDATEOK_8822B BIT(9)
+#define BIT_PWR_INT_127_V1_8822B BIT(8)
+#define BIT_PWR_INT_126TO96_8822B BIT(7)
+#define BIT_PWR_INT_95TO64_8822B BIT(6)
+#define BIT_PWR_INT_63TO32_8822B BIT(5)
+#define BIT_PWR_INT_31TO0_8822B BIT(4)
+#define BIT_DDMA0_LP_INT_8822B BIT(1)
+#define BIT_DDMA0_HP_INT_8822B BIT(0)
+
+/* 2 REG_SW_MDIO_8822B */
+#define BIT_DIS_TIMEOUT_IO_8822B BIT(24)
+
+/* 2 REG_SW_FLUSH_8822B */
+#define BIT_FLUSH_HOLDN_EN_8822B BIT(25)
+#define BIT_FLUSH_WR_EN_8822B BIT(24)
+#define BIT_SW_FLASH_CONTROL_8822B BIT(23)
+#define BIT_SW_FLASH_WEN_E_8822B BIT(19)
+#define BIT_SW_FLASH_HOLDN_E_8822B BIT(18)
+#define BIT_SW_FLASH_SO_E_8822B BIT(17)
+#define BIT_SW_FLASH_SI_E_8822B BIT(16)
+#define BIT_SW_FLASH_SK_O_8822B BIT(13)
+#define BIT_SW_FLASH_CEN_O_8822B BIT(12)
+#define BIT_SW_FLASH_WEN_O_8822B BIT(11)
+#define BIT_SW_FLASH_HOLDN_O_8822B BIT(10)
+#define BIT_SW_FLASH_SO_O_8822B BIT(9)
+#define BIT_SW_FLASH_SI_O_8822B BIT(8)
+#define BIT_SW_FLASH_WEN_I_8822B BIT(3)
+#define BIT_SW_FLASH_HOLDN_I_8822B BIT(2)
+#define BIT_SW_FLASH_SO_I_8822B BIT(1)
+#define BIT_SW_FLASH_SI_I_8822B BIT(0)
+
+/* 2 REG_H2C_PKT_READADDR_8822B */
+
+#define BIT_SHIFT_H2C_PKT_READADDR_8822B 0
+#define BIT_MASK_H2C_PKT_READADDR_8822B 0x3ffff
+#define BIT_H2C_PKT_READADDR_8822B(x) \
+ (((x) & BIT_MASK_H2C_PKT_READADDR_8822B) \
+ << BIT_SHIFT_H2C_PKT_READADDR_8822B)
+#define BIT_GET_H2C_PKT_READADDR_8822B(x) \
+ (((x) >> BIT_SHIFT_H2C_PKT_READADDR_8822B) & \
+ BIT_MASK_H2C_PKT_READADDR_8822B)
+
+/* 2 REG_H2C_PKT_WRITEADDR_8822B */
+
+#define BIT_SHIFT_H2C_PKT_WRITEADDR_8822B 0
+#define BIT_MASK_H2C_PKT_WRITEADDR_8822B 0x3ffff
+#define BIT_H2C_PKT_WRITEADDR_8822B(x) \
+ (((x) & BIT_MASK_H2C_PKT_WRITEADDR_8822B) \
+ << BIT_SHIFT_H2C_PKT_WRITEADDR_8822B)
+#define BIT_GET_H2C_PKT_WRITEADDR_8822B(x) \
+ (((x) >> BIT_SHIFT_H2C_PKT_WRITEADDR_8822B) & \
+ BIT_MASK_H2C_PKT_WRITEADDR_8822B)
+
+/* 2 REG_MEM_PWR_CRTL_8822B */
+#define BIT_MEM_BB_SD_8822B BIT(17)
+#define BIT_MEM_BB_DS_8822B BIT(16)
+#define BIT_MEM_BT_DS_8822B BIT(10)
+#define BIT_MEM_SDIO_LS_8822B BIT(9)
+#define BIT_MEM_SDIO_DS_8822B BIT(8)
+#define BIT_MEM_USB_LS_8822B BIT(7)
+#define BIT_MEM_USB_DS_8822B BIT(6)
+#define BIT_MEM_PCI_LS_8822B BIT(5)
+#define BIT_MEM_PCI_DS_8822B BIT(4)
+#define BIT_MEM_WLMAC_LS_8822B BIT(3)
+#define BIT_MEM_WLMAC_DS_8822B BIT(2)
+#define BIT_MEM_WLMCU_LS_8822B BIT(1)
+#define BIT_MEM_WLMCU_DS_8822B BIT(0)
+
+/* 2 REG_FW_DBG0_8822B */
+
+#define BIT_SHIFT_FW_DBG0_8822B 0
+#define BIT_MASK_FW_DBG0_8822B 0xffffffffL
+#define BIT_FW_DBG0_8822B(x) \
+ (((x) & BIT_MASK_FW_DBG0_8822B) << BIT_SHIFT_FW_DBG0_8822B)
+#define BIT_GET_FW_DBG0_8822B(x) \
+ (((x) >> BIT_SHIFT_FW_DBG0_8822B) & BIT_MASK_FW_DBG0_8822B)
+
+/* 2 REG_FW_DBG1_8822B */
+
+#define BIT_SHIFT_FW_DBG1_8822B 0
+#define BIT_MASK_FW_DBG1_8822B 0xffffffffL
+#define BIT_FW_DBG1_8822B(x) \
+ (((x) & BIT_MASK_FW_DBG1_8822B) << BIT_SHIFT_FW_DBG1_8822B)
+#define BIT_GET_FW_DBG1_8822B(x) \
+ (((x) >> BIT_SHIFT_FW_DBG1_8822B) & BIT_MASK_FW_DBG1_8822B)
+
+/* 2 REG_FW_DBG2_8822B */
+
+#define BIT_SHIFT_FW_DBG2_8822B 0
+#define BIT_MASK_FW_DBG2_8822B 0xffffffffL
+#define BIT_FW_DBG2_8822B(x) \
+ (((x) & BIT_MASK_FW_DBG2_8822B) << BIT_SHIFT_FW_DBG2_8822B)
+#define BIT_GET_FW_DBG2_8822B(x) \
+ (((x) >> BIT_SHIFT_FW_DBG2_8822B) & BIT_MASK_FW_DBG2_8822B)
+
+/* 2 REG_FW_DBG3_8822B */
+
+#define BIT_SHIFT_FW_DBG3_8822B 0
+#define BIT_MASK_FW_DBG3_8822B 0xffffffffL
+#define BIT_FW_DBG3_8822B(x) \
+ (((x) & BIT_MASK_FW_DBG3_8822B) << BIT_SHIFT_FW_DBG3_8822B)
+#define BIT_GET_FW_DBG3_8822B(x) \
+ (((x) >> BIT_SHIFT_FW_DBG3_8822B) & BIT_MASK_FW_DBG3_8822B)
+
+/* 2 REG_FW_DBG4_8822B */
+
+#define BIT_SHIFT_FW_DBG4_8822B 0
+#define BIT_MASK_FW_DBG4_8822B 0xffffffffL
+#define BIT_FW_DBG4_8822B(x) \
+ (((x) & BIT_MASK_FW_DBG4_8822B) << BIT_SHIFT_FW_DBG4_8822B)
+#define BIT_GET_FW_DBG4_8822B(x) \
+ (((x) >> BIT_SHIFT_FW_DBG4_8822B) & BIT_MASK_FW_DBG4_8822B)
+
+/* 2 REG_FW_DBG5_8822B */
+
+#define BIT_SHIFT_FW_DBG5_8822B 0
+#define BIT_MASK_FW_DBG5_8822B 0xffffffffL
+#define BIT_FW_DBG5_8822B(x) \
+ (((x) & BIT_MASK_FW_DBG5_8822B) << BIT_SHIFT_FW_DBG5_8822B)
+#define BIT_GET_FW_DBG5_8822B(x) \
+ (((x) >> BIT_SHIFT_FW_DBG5_8822B) & BIT_MASK_FW_DBG5_8822B)
+
+/* 2 REG_FW_DBG6_8822B */
+
+#define BIT_SHIFT_FW_DBG6_8822B 0
+#define BIT_MASK_FW_DBG6_8822B 0xffffffffL
+#define BIT_FW_DBG6_8822B(x) \
+ (((x) & BIT_MASK_FW_DBG6_8822B) << BIT_SHIFT_FW_DBG6_8822B)
+#define BIT_GET_FW_DBG6_8822B(x) \
+ (((x) >> BIT_SHIFT_FW_DBG6_8822B) & BIT_MASK_FW_DBG6_8822B)
+
+/* 2 REG_FW_DBG7_8822B */
+
+#define BIT_SHIFT_FW_DBG7_8822B 0
+#define BIT_MASK_FW_DBG7_8822B 0xffffffffL
+#define BIT_FW_DBG7_8822B(x) \
+ (((x) & BIT_MASK_FW_DBG7_8822B) << BIT_SHIFT_FW_DBG7_8822B)
+#define BIT_GET_FW_DBG7_8822B(x) \
+ (((x) >> BIT_SHIFT_FW_DBG7_8822B) & BIT_MASK_FW_DBG7_8822B)
+
+/* 2 REG_NOT_VALID_8822B */
+
+/* 2 REG_CR_8822B */
+
+#define BIT_SHIFT_LBMODE_8822B 24
+#define BIT_MASK_LBMODE_8822B 0x1f
+#define BIT_LBMODE_8822B(x) \
+ (((x) & BIT_MASK_LBMODE_8822B) << BIT_SHIFT_LBMODE_8822B)
+#define BIT_GET_LBMODE_8822B(x) \
+ (((x) >> BIT_SHIFT_LBMODE_8822B) & BIT_MASK_LBMODE_8822B)
+
+#define BIT_SHIFT_NETYPE1_8822B 18
+#define BIT_MASK_NETYPE1_8822B 0x3
+#define BIT_NETYPE1_8822B(x) \
+ (((x) & BIT_MASK_NETYPE1_8822B) << BIT_SHIFT_NETYPE1_8822B)
+#define BIT_GET_NETYPE1_8822B(x) \
+ (((x) >> BIT_SHIFT_NETYPE1_8822B) & BIT_MASK_NETYPE1_8822B)
+
+#define BIT_SHIFT_NETYPE0_8822B 16
+#define BIT_MASK_NETYPE0_8822B 0x3
+#define BIT_NETYPE0_8822B(x) \
+ (((x) & BIT_MASK_NETYPE0_8822B) << BIT_SHIFT_NETYPE0_8822B)
+#define BIT_GET_NETYPE0_8822B(x) \
+ (((x) >> BIT_SHIFT_NETYPE0_8822B) & BIT_MASK_NETYPE0_8822B)
+
+#define BIT_I2C_MAILBOX_EN_8822B BIT(12)
+#define BIT_SHCUT_EN_8822B BIT(11)
+#define BIT_32K_CAL_TMR_EN_8822B BIT(10)
+#define BIT_MAC_SEC_EN_8822B BIT(9)
+#define BIT_ENSWBCN_8822B BIT(8)
+#define BIT_MACRXEN_8822B BIT(7)
+#define BIT_MACTXEN_8822B BIT(6)
+#define BIT_SCHEDULE_EN_8822B BIT(5)
+#define BIT_PROTOCOL_EN_8822B BIT(4)
+#define BIT_RXDMA_EN_8822B BIT(3)
+#define BIT_TXDMA_EN_8822B BIT(2)
+#define BIT_HCI_RXDMA_EN_8822B BIT(1)
+#define BIT_HCI_TXDMA_EN_8822B BIT(0)
+
+/* 2 REG_PKT_BUFF_ACCESS_CTRL_8822B */
+
+#define BIT_SHIFT_PKT_BUFF_ACCESS_CTRL_8822B 0
+#define BIT_MASK_PKT_BUFF_ACCESS_CTRL_8822B 0xff
+#define BIT_PKT_BUFF_ACCESS_CTRL_8822B(x) \
+ (((x) & BIT_MASK_PKT_BUFF_ACCESS_CTRL_8822B) \
+ << BIT_SHIFT_PKT_BUFF_ACCESS_CTRL_8822B)
+#define BIT_GET_PKT_BUFF_ACCESS_CTRL_8822B(x) \
+ (((x) >> BIT_SHIFT_PKT_BUFF_ACCESS_CTRL_8822B) & \
+ BIT_MASK_PKT_BUFF_ACCESS_CTRL_8822B)
+
+/* 2 REG_TSF_CLK_STATE_8822B */
+#define BIT_TSF_CLK_STABLE_8822B BIT(15)
+
+/* 2 REG_TXDMA_PQ_MAP_8822B */
+
+#define BIT_SHIFT_TXDMA_HIQ_MAP_8822B 14
+#define BIT_MASK_TXDMA_HIQ_MAP_8822B 0x3
+#define BIT_TXDMA_HIQ_MAP_8822B(x) \
+ (((x) & BIT_MASK_TXDMA_HIQ_MAP_8822B) << BIT_SHIFT_TXDMA_HIQ_MAP_8822B)
+#define BIT_GET_TXDMA_HIQ_MAP_8822B(x) \
+ (((x) >> BIT_SHIFT_TXDMA_HIQ_MAP_8822B) & BIT_MASK_TXDMA_HIQ_MAP_8822B)
+
+#define BIT_SHIFT_TXDMA_MGQ_MAP_8822B 12
+#define BIT_MASK_TXDMA_MGQ_MAP_8822B 0x3
+#define BIT_TXDMA_MGQ_MAP_8822B(x) \
+ (((x) & BIT_MASK_TXDMA_MGQ_MAP_8822B) << BIT_SHIFT_TXDMA_MGQ_MAP_8822B)
+#define BIT_GET_TXDMA_MGQ_MAP_8822B(x) \
+ (((x) >> BIT_SHIFT_TXDMA_MGQ_MAP_8822B) & BIT_MASK_TXDMA_MGQ_MAP_8822B)
+
+#define BIT_SHIFT_TXDMA_BKQ_MAP_8822B 10
+#define BIT_MASK_TXDMA_BKQ_MAP_8822B 0x3
+#define BIT_TXDMA_BKQ_MAP_8822B(x) \
+ (((x) & BIT_MASK_TXDMA_BKQ_MAP_8822B) << BIT_SHIFT_TXDMA_BKQ_MAP_8822B)
+#define BIT_GET_TXDMA_BKQ_MAP_8822B(x) \
+ (((x) >> BIT_SHIFT_TXDMA_BKQ_MAP_8822B) & BIT_MASK_TXDMA_BKQ_MAP_8822B)
+
+#define BIT_SHIFT_TXDMA_BEQ_MAP_8822B 8
+#define BIT_MASK_TXDMA_BEQ_MAP_8822B 0x3
+#define BIT_TXDMA_BEQ_MAP_8822B(x) \
+ (((x) & BIT_MASK_TXDMA_BEQ_MAP_8822B) << BIT_SHIFT_TXDMA_BEQ_MAP_8822B)
+#define BIT_GET_TXDMA_BEQ_MAP_8822B(x) \
+ (((x) >> BIT_SHIFT_TXDMA_BEQ_MAP_8822B) & BIT_MASK_TXDMA_BEQ_MAP_8822B)
+
+#define BIT_SHIFT_TXDMA_VIQ_MAP_8822B 6
+#define BIT_MASK_TXDMA_VIQ_MAP_8822B 0x3
+#define BIT_TXDMA_VIQ_MAP_8822B(x) \
+ (((x) & BIT_MASK_TXDMA_VIQ_MAP_8822B) << BIT_SHIFT_TXDMA_VIQ_MAP_8822B)
+#define BIT_GET_TXDMA_VIQ_MAP_8822B(x) \
+ (((x) >> BIT_SHIFT_TXDMA_VIQ_MAP_8822B) & BIT_MASK_TXDMA_VIQ_MAP_8822B)
+
+#define BIT_SHIFT_TXDMA_VOQ_MAP_8822B 4
+#define BIT_MASK_TXDMA_VOQ_MAP_8822B 0x3
+#define BIT_TXDMA_VOQ_MAP_8822B(x) \
+ (((x) & BIT_MASK_TXDMA_VOQ_MAP_8822B) << BIT_SHIFT_TXDMA_VOQ_MAP_8822B)
+#define BIT_GET_TXDMA_VOQ_MAP_8822B(x) \
+ (((x) >> BIT_SHIFT_TXDMA_VOQ_MAP_8822B) & BIT_MASK_TXDMA_VOQ_MAP_8822B)
+
+#define BIT_RXDMA_AGG_EN_8822B BIT(2)
+#define BIT_RXSHFT_EN_8822B BIT(1)
+#define BIT_RXDMA_ARBBW_EN_8822B BIT(0)
+
+/* 2 REG_TRXFF_BNDY_8822B */
+
+#define BIT_SHIFT_RXFFOVFL_RSV_V2_8822B 8
+#define BIT_MASK_RXFFOVFL_RSV_V2_8822B 0xf
+#define BIT_RXFFOVFL_RSV_V2_8822B(x) \
+ (((x) & BIT_MASK_RXFFOVFL_RSV_V2_8822B) \
+ << BIT_SHIFT_RXFFOVFL_RSV_V2_8822B)
+#define BIT_GET_RXFFOVFL_RSV_V2_8822B(x) \
+ (((x) >> BIT_SHIFT_RXFFOVFL_RSV_V2_8822B) & \
+ BIT_MASK_RXFFOVFL_RSV_V2_8822B)
+
+#define BIT_SHIFT_TXPKTBUF_PGBNDY_8822B 0
+#define BIT_MASK_TXPKTBUF_PGBNDY_8822B 0xff
+#define BIT_TXPKTBUF_PGBNDY_8822B(x) \
+ (((x) & BIT_MASK_TXPKTBUF_PGBNDY_8822B) \
+ << BIT_SHIFT_TXPKTBUF_PGBNDY_8822B)
+#define BIT_GET_TXPKTBUF_PGBNDY_8822B(x) \
+ (((x) >> BIT_SHIFT_TXPKTBUF_PGBNDY_8822B) & \
+ BIT_MASK_TXPKTBUF_PGBNDY_8822B)
+
+/* 2 REG_PTA_I2C_MBOX_8822B */
+
+/* 2 REG_NOT_VALID_8822B */
+
+#define BIT_SHIFT_I2C_M_STATUS_8822B 8
+#define BIT_MASK_I2C_M_STATUS_8822B 0xf
+#define BIT_I2C_M_STATUS_8822B(x) \
+ (((x) & BIT_MASK_I2C_M_STATUS_8822B) << BIT_SHIFT_I2C_M_STATUS_8822B)
+#define BIT_GET_I2C_M_STATUS_8822B(x) \
+ (((x) >> BIT_SHIFT_I2C_M_STATUS_8822B) & BIT_MASK_I2C_M_STATUS_8822B)
+
+#define BIT_SHIFT_I2C_M_BUS_GNT_FW_8822B 4
+#define BIT_MASK_I2C_M_BUS_GNT_FW_8822B 0x7
+#define BIT_I2C_M_BUS_GNT_FW_8822B(x) \
+ (((x) & BIT_MASK_I2C_M_BUS_GNT_FW_8822B) \
+ << BIT_SHIFT_I2C_M_BUS_GNT_FW_8822B)
+#define BIT_GET_I2C_M_BUS_GNT_FW_8822B(x) \
+ (((x) >> BIT_SHIFT_I2C_M_BUS_GNT_FW_8822B) & \
+ BIT_MASK_I2C_M_BUS_GNT_FW_8822B)
+
+#define BIT_I2C_M_GNT_FW_8822B BIT(3)
+
+#define BIT_SHIFT_I2C_M_SPEED_8822B 1
+#define BIT_MASK_I2C_M_SPEED_8822B 0x3
+#define BIT_I2C_M_SPEED_8822B(x) \
+ (((x) & BIT_MASK_I2C_M_SPEED_8822B) << BIT_SHIFT_I2C_M_SPEED_8822B)
+#define BIT_GET_I2C_M_SPEED_8822B(x) \
+ (((x) >> BIT_SHIFT_I2C_M_SPEED_8822B) & BIT_MASK_I2C_M_SPEED_8822B)
+
+#define BIT_I2C_M_UNLOCK_8822B BIT(0)
+
+/* 2 REG_RXFF_BNDY_8822B */
+
+/* 2 REG_NOT_VALID_8822B */
+
+#define BIT_SHIFT_RXFF0_BNDY_V2_8822B 0
+#define BIT_MASK_RXFF0_BNDY_V2_8822B 0x3ffff
+#define BIT_RXFF0_BNDY_V2_8822B(x) \
+ (((x) & BIT_MASK_RXFF0_BNDY_V2_8822B) << BIT_SHIFT_RXFF0_BNDY_V2_8822B)
+#define BIT_GET_RXFF0_BNDY_V2_8822B(x) \
+ (((x) >> BIT_SHIFT_RXFF0_BNDY_V2_8822B) & BIT_MASK_RXFF0_BNDY_V2_8822B)
+
+/* 2 REG_FE1IMR_8822B */
+#define BIT_FS_RXDMA2_DONE_INT_EN_8822B BIT(28)
+#define BIT_FS_RXDONE3_INT_EN_8822B BIT(27)
+#define BIT_FS_RXDONE2_INT_EN_8822B BIT(26)
+#define BIT_FS_RX_BCN_P4_INT_EN_8822B BIT(25)
+#define BIT_FS_RX_BCN_P3_INT_EN_8822B BIT(24)
+#define BIT_FS_RX_BCN_P2_INT_EN_8822B BIT(23)
+#define BIT_FS_RX_BCN_P1_INT_EN_8822B BIT(22)
+#define BIT_FS_RX_BCN_P0_INT_EN_8822B BIT(21)
+#define BIT_FS_RX_UMD0_INT_EN_8822B BIT(20)
+#define BIT_FS_RX_UMD1_INT_EN_8822B BIT(19)
+#define BIT_FS_RX_BMD0_INT_EN_8822B BIT(18)
+#define BIT_FS_RX_BMD1_INT_EN_8822B BIT(17)
+#define BIT_FS_RXDONE_INT_EN_8822B BIT(16)
+#define BIT_FS_WWLAN_INT_EN_8822B BIT(15)
+#define BIT_FS_SOUND_DONE_INT_EN_8822B BIT(14)
+#define BIT_FS_LP_STBY_INT_EN_8822B BIT(13)
+#define BIT_FS_TRL_MTR_INT_EN_8822B BIT(12)
+#define BIT_FS_BF1_PRETO_INT_EN_8822B BIT(11)
+#define BIT_FS_BF0_PRETO_INT_EN_8822B BIT(10)
+#define BIT_FS_PTCL_RELEASE_MACID_INT_EN_8822B BIT(9)
+#define BIT_FS_LTE_COEX_EN_8822B BIT(6)
+#define BIT_FS_WLACTOFF_INT_EN_8822B BIT(5)
+#define BIT_FS_WLACTON_INT_EN_8822B BIT(4)
+#define BIT_FS_BTCMD_INT_EN_8822B BIT(3)
+#define BIT_FS_REG_MAILBOX_TO_I2C_INT_EN_8822B BIT(2)
+#define BIT_FS_TRPC_TO_INT_EN_V1_8822B BIT(1)
+#define BIT_FS_RPC_O_T_INT_EN_V1_8822B BIT(0)
+
+/* 2 REG_FE1ISR_8822B */
+#define BIT_FS_RXDMA2_DONE_INT_8822B BIT(28)
+#define BIT_FS_RXDONE3_INT_8822B BIT(27)
+#define BIT_FS_RXDONE2_INT_8822B BIT(26)
+#define BIT_FS_RX_BCN_P4_INT_8822B BIT(25)
+#define BIT_FS_RX_BCN_P3_INT_8822B BIT(24)
+#define BIT_FS_RX_BCN_P2_INT_8822B BIT(23)
+#define BIT_FS_RX_BCN_P1_INT_8822B BIT(22)
+#define BIT_FS_RX_BCN_P0_INT_8822B BIT(21)
+#define BIT_FS_RX_UMD0_INT_8822B BIT(20)
+#define BIT_FS_RX_UMD1_INT_8822B BIT(19)
+#define BIT_FS_RX_BMD0_INT_8822B BIT(18)
+#define BIT_FS_RX_BMD1_INT_8822B BIT(17)
+#define BIT_FS_RXDONE_INT_8822B BIT(16)
+#define BIT_FS_WWLAN_INT_8822B BIT(15)
+#define BIT_FS_SOUND_DONE_INT_8822B BIT(14)
+#define BIT_FS_LP_STBY_INT_8822B BIT(13)
+#define BIT_FS_TRL_MTR_INT_8822B BIT(12)
+#define BIT_FS_BF1_PRETO_INT_8822B BIT(11)
+#define BIT_FS_BF0_PRETO_INT_8822B BIT(10)
+#define BIT_FS_PTCL_RELEASE_MACID_INT_8822B BIT(9)
+#define BIT_FS_LTE_COEX_INT_8822B BIT(6)
+#define BIT_FS_WLACTOFF_INT_8822B BIT(5)
+#define BIT_FS_WLACTON_INT_8822B BIT(4)
+#define BIT_FS_BCN_RX_INT_INT_8822B BIT(3)
+#define BIT_FS_MAILBOX_TO_I2C_INT_8822B BIT(2)
+#define BIT_FS_TRPC_TO_INT_8822B BIT(1)
+#define BIT_FS_RPC_O_T_INT_8822B BIT(0)
+
+/* 2 REG_NOT_VALID_8822B */
+
+/* 2 REG_CPWM_8822B */
+#define BIT_CPWM_TOGGLING_8822B BIT(31)
+
+#define BIT_SHIFT_CPWM_MOD_8822B 24
+#define BIT_MASK_CPWM_MOD_8822B 0x7f
+#define BIT_CPWM_MOD_8822B(x) \
+ (((x) & BIT_MASK_CPWM_MOD_8822B) << BIT_SHIFT_CPWM_MOD_8822B)
+#define BIT_GET_CPWM_MOD_8822B(x) \
+ (((x) >> BIT_SHIFT_CPWM_MOD_8822B) & BIT_MASK_CPWM_MOD_8822B)
+
+/* 2 REG_FWIMR_8822B */
+#define BIT_FS_TXBCNOK_MB7_INT_EN_8822B BIT(31)
+#define BIT_FS_TXBCNOK_MB6_INT_EN_8822B BIT(30)
+#define BIT_FS_TXBCNOK_MB5_INT_EN_8822B BIT(29)
+#define BIT_FS_TXBCNOK_MB4_INT_EN_8822B BIT(28)
+#define BIT_FS_TXBCNOK_MB3_INT_EN_8822B BIT(27)
+#define BIT_FS_TXBCNOK_MB2_INT_EN_8822B BIT(26)
+#define BIT_FS_TXBCNOK_MB1_INT_EN_8822B BIT(25)
+#define BIT_FS_TXBCNOK_MB0_INT_EN_8822B BIT(24)
+#define BIT_FS_TXBCNERR_MB7_INT_EN_8822B BIT(23)
+#define BIT_FS_TXBCNERR_MB6_INT_EN_8822B BIT(22)
+#define BIT_FS_TXBCNERR_MB5_INT_EN_8822B BIT(21)
+#define BIT_FS_TXBCNERR_MB4_INT_EN_8822B BIT(20)
+#define BIT_FS_TXBCNERR_MB3_INT_EN_8822B BIT(19)
+#define BIT_FS_TXBCNERR_MB2_INT_EN_8822B BIT(18)
+#define BIT_FS_TXBCNERR_MB1_INT_EN_8822B BIT(17)
+#define BIT_FS_TXBCNERR_MB0_INT_EN_8822B BIT(16)
+#define BIT_CPU_MGQ_TXDONE_INT_EN_8822B BIT(15)
+#define BIT_SIFS_OVERSPEC_INT_EN_8822B BIT(14)
+#define BIT_FS_MGNTQ_RPTR_RELEASE_INT_EN_8822B BIT(13)
+#define BIT_FS_MGNTQFF_TO_INT_EN_8822B BIT(12)
+#define BIT_FS_DDMA1_LP_INT_EN_8822B BIT(11)
+#define BIT_FS_DDMA1_HP_INT_EN_8822B BIT(10)
+#define BIT_FS_DDMA0_LP_INT_EN_8822B BIT(9)
+#define BIT_FS_DDMA0_HP_INT_EN_8822B BIT(8)
+#define BIT_FS_TRXRPT_INT_EN_8822B BIT(7)
+#define BIT_FS_C2H_W_READY_INT_EN_8822B BIT(6)
+#define BIT_FS_HRCV_INT_EN_8822B BIT(5)
+#define BIT_FS_H2CCMD_INT_EN_8822B BIT(4)
+#define BIT_FS_TXPKTIN_INT_EN_8822B BIT(3)
+#define BIT_FS_ERRORHDL_INT_EN_8822B BIT(2)
+#define BIT_FS_TXCCX_INT_EN_8822B BIT(1)
+#define BIT_FS_TXCLOSE_INT_EN_8822B BIT(0)
+
+/* 2 REG_FWISR_8822B */
+#define BIT_FS_TXBCNOK_MB7_INT_8822B BIT(31)
+#define BIT_FS_TXBCNOK_MB6_INT_8822B BIT(30)
+#define BIT_FS_TXBCNOK_MB5_INT_8822B BIT(29)
+#define BIT_FS_TXBCNOK_MB4_INT_8822B BIT(28)
+#define BIT_FS_TXBCNOK_MB3_INT_8822B BIT(27)
+#define BIT_FS_TXBCNOK_MB2_INT_8822B BIT(26)
+#define BIT_FS_TXBCNOK_MB1_INT_8822B BIT(25)
+#define BIT_FS_TXBCNOK_MB0_INT_8822B BIT(24)
+#define BIT_FS_TXBCNERR_MB7_INT_8822B BIT(23)
+#define BIT_FS_TXBCNERR_MB6_INT_8822B BIT(22)
+#define BIT_FS_TXBCNERR_MB5_INT_8822B BIT(21)
+#define BIT_FS_TXBCNERR_MB4_INT_8822B BIT(20)
+#define BIT_FS_TXBCNERR_MB3_INT_8822B BIT(19)
+#define BIT_FS_TXBCNERR_MB2_INT_8822B BIT(18)
+#define BIT_FS_TXBCNERR_MB1_INT_8822B BIT(17)
+#define BIT_FS_TXBCNERR_MB0_INT_8822B BIT(16)
+#define BIT_CPU_MGQ_TXDONE_INT_8822B BIT(15)
+#define BIT_SIFS_OVERSPEC_INT_8822B BIT(14)
+#define BIT_FS_MGNTQ_RPTR_RELEASE_INT_8822B BIT(13)
+#define BIT_FS_MGNTQFF_TO_INT_8822B BIT(12)
+#define BIT_FS_DDMA1_LP_INT_8822B BIT(11)
+#define BIT_FS_DDMA1_HP_INT_8822B BIT(10)
+#define BIT_FS_DDMA0_LP_INT_8822B BIT(9)
+#define BIT_FS_DDMA0_HP_INT_8822B BIT(8)
+#define BIT_FS_TRXRPT_INT_8822B BIT(7)
+#define BIT_FS_C2H_W_READY_INT_8822B BIT(6)
+#define BIT_FS_HRCV_INT_8822B BIT(5)
+#define BIT_FS_H2CCMD_INT_8822B BIT(4)
+#define BIT_FS_TXPKTIN_INT_8822B BIT(3)
+#define BIT_FS_ERRORHDL_INT_8822B BIT(2)
+#define BIT_FS_TXCCX_INT_8822B BIT(1)
+#define BIT_FS_TXCLOSE_INT_8822B BIT(0)
+
+/* 2 REG_FTIMR_8822B */
+#define BIT_PS_TIMER_C_EARLY_INT_EN_8822B BIT(23)
+#define BIT_PS_TIMER_B_EARLY_INT_EN_8822B BIT(22)
+#define BIT_PS_TIMER_A_EARLY_INT_EN_8822B BIT(21)
+#define BIT_CPUMGQ_TX_TIMER_EARLY_INT_EN_8822B BIT(20)
+#define BIT_PS_TIMER_C_INT_EN_8822B BIT(19)
+#define BIT_PS_TIMER_B_INT_EN_8822B BIT(18)
+#define BIT_PS_TIMER_A_INT_EN_8822B BIT(17)
+#define BIT_CPUMGQ_TX_TIMER_INT_EN_8822B BIT(16)
+#define BIT_FS_PS_TIMEOUT2_EN_8822B BIT(15)
+#define BIT_FS_PS_TIMEOUT1_EN_8822B BIT(14)
+#define BIT_FS_PS_TIMEOUT0_EN_8822B BIT(13)
+#define BIT_FS_GTINT8_EN_8822B BIT(8)
+#define BIT_FS_GTINT7_EN_8822B BIT(7)
+#define BIT_FS_GTINT6_EN_8822B BIT(6)
+#define BIT_FS_GTINT5_EN_8822B BIT(5)
+#define BIT_FS_GTINT4_EN_8822B BIT(4)
+#define BIT_FS_GTINT3_EN_8822B BIT(3)
+#define BIT_FS_GTINT2_EN_8822B BIT(2)
+#define BIT_FS_GTINT1_EN_8822B BIT(1)
+#define BIT_FS_GTINT0_EN_8822B BIT(0)
+
+/* 2 REG_FTISR_8822B */
+#define BIT_PS_TIMER_C_EARLY__INT_8822B BIT(23)
+#define BIT_PS_TIMER_B_EARLY__INT_8822B BIT(22)
+#define BIT_PS_TIMER_A_EARLY__INT_8822B BIT(21)
+#define BIT_CPUMGQ_TX_TIMER_EARLY_INT_8822B BIT(20)
+#define BIT_PS_TIMER_C_INT_8822B BIT(19)
+#define BIT_PS_TIMER_B_INT_8822B BIT(18)
+#define BIT_PS_TIMER_A_INT_8822B BIT(17)
+#define BIT_CPUMGQ_TX_TIMER_INT_8822B BIT(16)
+#define BIT_FS_PS_TIMEOUT2_INT_8822B BIT(15)
+#define BIT_FS_PS_TIMEOUT1_INT_8822B BIT(14)
+#define BIT_FS_PS_TIMEOUT0_INT_8822B BIT(13)
+#define BIT_FS_GTINT8_INT_8822B BIT(8)
+#define BIT_FS_GTINT7_INT_8822B BIT(7)
+#define BIT_FS_GTINT6_INT_8822B BIT(6)
+#define BIT_FS_GTINT5_INT_8822B BIT(5)
+#define BIT_FS_GTINT4_INT_8822B BIT(4)
+#define BIT_FS_GTINT3_INT_8822B BIT(3)
+#define BIT_FS_GTINT2_INT_8822B BIT(2)
+#define BIT_FS_GTINT1_INT_8822B BIT(1)
+#define BIT_FS_GTINT0_INT_8822B BIT(0)
+
+/* 2 REG_PKTBUF_DBG_CTRL_8822B */
+
+#define BIT_SHIFT_PKTBUF_WRITE_EN_8822B 24
+#define BIT_MASK_PKTBUF_WRITE_EN_8822B 0xff
+#define BIT_PKTBUF_WRITE_EN_8822B(x) \
+ (((x) & BIT_MASK_PKTBUF_WRITE_EN_8822B) \
+ << BIT_SHIFT_PKTBUF_WRITE_EN_8822B)
+#define BIT_GET_PKTBUF_WRITE_EN_8822B(x) \
+ (((x) >> BIT_SHIFT_PKTBUF_WRITE_EN_8822B) & \
+ BIT_MASK_PKTBUF_WRITE_EN_8822B)
+
+#define BIT_TXRPTBUF_DBG_8822B BIT(23)
+
+/* 2 REG_NOT_VALID_8822B */
+#define BIT_TXPKTBUF_DBG_V2_8822B BIT(20)
+#define BIT_RXPKTBUF_DBG_8822B BIT(16)
+
+#define BIT_SHIFT_PKTBUF_DBG_ADDR_8822B 0
+#define BIT_MASK_PKTBUF_DBG_ADDR_8822B 0x1fff
+#define BIT_PKTBUF_DBG_ADDR_8822B(x) \
+ (((x) & BIT_MASK_PKTBUF_DBG_ADDR_8822B) \
+ << BIT_SHIFT_PKTBUF_DBG_ADDR_8822B)
+#define BIT_GET_PKTBUF_DBG_ADDR_8822B(x) \
+ (((x) >> BIT_SHIFT_PKTBUF_DBG_ADDR_8822B) & \
+ BIT_MASK_PKTBUF_DBG_ADDR_8822B)
+
+/* 2 REG_PKTBUF_DBG_DATA_L_8822B */
+
+#define BIT_SHIFT_PKTBUF_DBG_DATA_L_8822B 0
+#define BIT_MASK_PKTBUF_DBG_DATA_L_8822B 0xffffffffL
+#define BIT_PKTBUF_DBG_DATA_L_8822B(x) \
+ (((x) & BIT_MASK_PKTBUF_DBG_DATA_L_8822B) \
+ << BIT_SHIFT_PKTBUF_DBG_DATA_L_8822B)
+#define BIT_GET_PKTBUF_DBG_DATA_L_8822B(x) \
+ (((x) >> BIT_SHIFT_PKTBUF_DBG_DATA_L_8822B) & \
+ BIT_MASK_PKTBUF_DBG_DATA_L_8822B)
+
+/* 2 REG_PKTBUF_DBG_DATA_H_8822B */
+
+#define BIT_SHIFT_PKTBUF_DBG_DATA_H_8822B 0
+#define BIT_MASK_PKTBUF_DBG_DATA_H_8822B 0xffffffffL
+#define BIT_PKTBUF_DBG_DATA_H_8822B(x) \
+ (((x) & BIT_MASK_PKTBUF_DBG_DATA_H_8822B) \
+ << BIT_SHIFT_PKTBUF_DBG_DATA_H_8822B)
+#define BIT_GET_PKTBUF_DBG_DATA_H_8822B(x) \
+ (((x) >> BIT_SHIFT_PKTBUF_DBG_DATA_H_8822B) & \
+ BIT_MASK_PKTBUF_DBG_DATA_H_8822B)
+
+/* 2 REG_CPWM2_8822B */
+
+#define BIT_SHIFT_L0S_TO_RCVY_NUM_8822B 16
+#define BIT_MASK_L0S_TO_RCVY_NUM_8822B 0xff
+#define BIT_L0S_TO_RCVY_NUM_8822B(x) \
+ (((x) & BIT_MASK_L0S_TO_RCVY_NUM_8822B) \
+ << BIT_SHIFT_L0S_TO_RCVY_NUM_8822B)
+#define BIT_GET_L0S_TO_RCVY_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_L0S_TO_RCVY_NUM_8822B) & \
+ BIT_MASK_L0S_TO_RCVY_NUM_8822B)
+
+#define BIT_CPWM2_TOGGLING_8822B BIT(15)
+
+#define BIT_SHIFT_CPWM2_MOD_8822B 0
+#define BIT_MASK_CPWM2_MOD_8822B 0x7fff
+#define BIT_CPWM2_MOD_8822B(x) \
+ (((x) & BIT_MASK_CPWM2_MOD_8822B) << BIT_SHIFT_CPWM2_MOD_8822B)
+#define BIT_GET_CPWM2_MOD_8822B(x) \
+ (((x) >> BIT_SHIFT_CPWM2_MOD_8822B) & BIT_MASK_CPWM2_MOD_8822B)
+
+/* 2 REG_NOT_VALID_8822B */
+
+/* 2 REG_TC0_CTRL_8822B */
+#define BIT_TC0INT_EN_8822B BIT(26)
+#define BIT_TC0MODE_8822B BIT(25)
+#define BIT_TC0EN_8822B BIT(24)
+
+#define BIT_SHIFT_TC0DATA_8822B 0
+#define BIT_MASK_TC0DATA_8822B 0xffffff
+#define BIT_TC0DATA_8822B(x) \
+ (((x) & BIT_MASK_TC0DATA_8822B) << BIT_SHIFT_TC0DATA_8822B)
+#define BIT_GET_TC0DATA_8822B(x) \
+ (((x) >> BIT_SHIFT_TC0DATA_8822B) & BIT_MASK_TC0DATA_8822B)
+
+/* 2 REG_TC1_CTRL_8822B */
+#define BIT_TC1INT_EN_8822B BIT(26)
+#define BIT_TC1MODE_8822B BIT(25)
+#define BIT_TC1EN_8822B BIT(24)
+
+#define BIT_SHIFT_TC1DATA_8822B 0
+#define BIT_MASK_TC1DATA_8822B 0xffffff
+#define BIT_TC1DATA_8822B(x) \
+ (((x) & BIT_MASK_TC1DATA_8822B) << BIT_SHIFT_TC1DATA_8822B)
+#define BIT_GET_TC1DATA_8822B(x) \
+ (((x) >> BIT_SHIFT_TC1DATA_8822B) & BIT_MASK_TC1DATA_8822B)
+
+/* 2 REG_TC2_CTRL_8822B */
+#define BIT_TC2INT_EN_8822B BIT(26)
+#define BIT_TC2MODE_8822B BIT(25)
+#define BIT_TC2EN_8822B BIT(24)
+
+#define BIT_SHIFT_TC2DATA_8822B 0
+#define BIT_MASK_TC2DATA_8822B 0xffffff
+#define BIT_TC2DATA_8822B(x) \
+ (((x) & BIT_MASK_TC2DATA_8822B) << BIT_SHIFT_TC2DATA_8822B)
+#define BIT_GET_TC2DATA_8822B(x) \
+ (((x) >> BIT_SHIFT_TC2DATA_8822B) & BIT_MASK_TC2DATA_8822B)
+
+/* 2 REG_TC3_CTRL_8822B */
+#define BIT_TC3INT_EN_8822B BIT(26)
+#define BIT_TC3MODE_8822B BIT(25)
+#define BIT_TC3EN_8822B BIT(24)
+
+#define BIT_SHIFT_TC3DATA_8822B 0
+#define BIT_MASK_TC3DATA_8822B 0xffffff
+#define BIT_TC3DATA_8822B(x) \
+ (((x) & BIT_MASK_TC3DATA_8822B) << BIT_SHIFT_TC3DATA_8822B)
+#define BIT_GET_TC3DATA_8822B(x) \
+ (((x) >> BIT_SHIFT_TC3DATA_8822B) & BIT_MASK_TC3DATA_8822B)
+
+/* 2 REG_TC4_CTRL_8822B */
+#define BIT_TC4INT_EN_8822B BIT(26)
+#define BIT_TC4MODE_8822B BIT(25)
+#define BIT_TC4EN_8822B BIT(24)
+
+#define BIT_SHIFT_TC4DATA_8822B 0
+#define BIT_MASK_TC4DATA_8822B 0xffffff
+#define BIT_TC4DATA_8822B(x) \
+ (((x) & BIT_MASK_TC4DATA_8822B) << BIT_SHIFT_TC4DATA_8822B)
+#define BIT_GET_TC4DATA_8822B(x) \
+ (((x) >> BIT_SHIFT_TC4DATA_8822B) & BIT_MASK_TC4DATA_8822B)
+
+/* 2 REG_TCUNIT_BASE_8822B */
+
+#define BIT_SHIFT_TCUNIT_BASE_8822B 0
+#define BIT_MASK_TCUNIT_BASE_8822B 0x3fff
+#define BIT_TCUNIT_BASE_8822B(x) \
+ (((x) & BIT_MASK_TCUNIT_BASE_8822B) << BIT_SHIFT_TCUNIT_BASE_8822B)
+#define BIT_GET_TCUNIT_BASE_8822B(x) \
+ (((x) >> BIT_SHIFT_TCUNIT_BASE_8822B) & BIT_MASK_TCUNIT_BASE_8822B)
+
+/* 2 REG_TC5_CTRL_8822B */
+#define BIT_TC5INT_EN_8822B BIT(26)
+#define BIT_TC5MODE_8822B BIT(25)
+#define BIT_TC5EN_8822B BIT(24)
+
+#define BIT_SHIFT_TC5DATA_8822B 0
+#define BIT_MASK_TC5DATA_8822B 0xffffff
+#define BIT_TC5DATA_8822B(x) \
+ (((x) & BIT_MASK_TC5DATA_8822B) << BIT_SHIFT_TC5DATA_8822B)
+#define BIT_GET_TC5DATA_8822B(x) \
+ (((x) >> BIT_SHIFT_TC5DATA_8822B) & BIT_MASK_TC5DATA_8822B)
+
+/* 2 REG_TC6_CTRL_8822B */
+#define BIT_TC6INT_EN_8822B BIT(26)
+#define BIT_TC6MODE_8822B BIT(25)
+#define BIT_TC6EN_8822B BIT(24)
+
+#define BIT_SHIFT_TC6DATA_8822B 0
+#define BIT_MASK_TC6DATA_8822B 0xffffff
+#define BIT_TC6DATA_8822B(x) \
+ (((x) & BIT_MASK_TC6DATA_8822B) << BIT_SHIFT_TC6DATA_8822B)
+#define BIT_GET_TC6DATA_8822B(x) \
+ (((x) >> BIT_SHIFT_TC6DATA_8822B) & BIT_MASK_TC6DATA_8822B)
+
+/* 2 REG_MBIST_FAIL_8822B */
+
+#define BIT_SHIFT_8051_MBIST_FAIL_8822B 26
+#define BIT_MASK_8051_MBIST_FAIL_8822B 0x7
+#define BIT_8051_MBIST_FAIL_8822B(x) \
+ (((x) & BIT_MASK_8051_MBIST_FAIL_8822B) \
+ << BIT_SHIFT_8051_MBIST_FAIL_8822B)
+#define BIT_GET_8051_MBIST_FAIL_8822B(x) \
+ (((x) >> BIT_SHIFT_8051_MBIST_FAIL_8822B) & \
+ BIT_MASK_8051_MBIST_FAIL_8822B)
+
+#define BIT_SHIFT_USB_MBIST_FAIL_8822B 24
+#define BIT_MASK_USB_MBIST_FAIL_8822B 0x3
+#define BIT_USB_MBIST_FAIL_8822B(x) \
+ (((x) & BIT_MASK_USB_MBIST_FAIL_8822B) \
+ << BIT_SHIFT_USB_MBIST_FAIL_8822B)
+#define BIT_GET_USB_MBIST_FAIL_8822B(x) \
+ (((x) >> BIT_SHIFT_USB_MBIST_FAIL_8822B) & \
+ BIT_MASK_USB_MBIST_FAIL_8822B)
+
+#define BIT_SHIFT_PCIE_MBIST_FAIL_8822B 16
+#define BIT_MASK_PCIE_MBIST_FAIL_8822B 0x3f
+#define BIT_PCIE_MBIST_FAIL_8822B(x) \
+ (((x) & BIT_MASK_PCIE_MBIST_FAIL_8822B) \
+ << BIT_SHIFT_PCIE_MBIST_FAIL_8822B)
+#define BIT_GET_PCIE_MBIST_FAIL_8822B(x) \
+ (((x) >> BIT_SHIFT_PCIE_MBIST_FAIL_8822B) & \
+ BIT_MASK_PCIE_MBIST_FAIL_8822B)
+
+#define BIT_SHIFT_MAC_MBIST_FAIL_8822B 0
+#define BIT_MASK_MAC_MBIST_FAIL_8822B 0xfff
+#define BIT_MAC_MBIST_FAIL_8822B(x) \
+ (((x) & BIT_MASK_MAC_MBIST_FAIL_8822B) \
+ << BIT_SHIFT_MAC_MBIST_FAIL_8822B)
+#define BIT_GET_MAC_MBIST_FAIL_8822B(x) \
+ (((x) >> BIT_SHIFT_MAC_MBIST_FAIL_8822B) & \
+ BIT_MASK_MAC_MBIST_FAIL_8822B)
+
+/* 2 REG_MBIST_START_PAUSE_8822B */
+
+#define BIT_SHIFT_8051_MBIST_START_PAUSE_8822B 26
+#define BIT_MASK_8051_MBIST_START_PAUSE_8822B 0x7
+#define BIT_8051_MBIST_START_PAUSE_8822B(x) \
+ (((x) & BIT_MASK_8051_MBIST_START_PAUSE_8822B) \
+ << BIT_SHIFT_8051_MBIST_START_PAUSE_8822B)
+#define BIT_GET_8051_MBIST_START_PAUSE_8822B(x) \
+ (((x) >> BIT_SHIFT_8051_MBIST_START_PAUSE_8822B) & \
+ BIT_MASK_8051_MBIST_START_PAUSE_8822B)
+
+#define BIT_SHIFT_USB_MBIST_START_PAUSE_8822B 24
+#define BIT_MASK_USB_MBIST_START_PAUSE_8822B 0x3
+#define BIT_USB_MBIST_START_PAUSE_8822B(x) \
+ (((x) & BIT_MASK_USB_MBIST_START_PAUSE_8822B) \
+ << BIT_SHIFT_USB_MBIST_START_PAUSE_8822B)
+#define BIT_GET_USB_MBIST_START_PAUSE_8822B(x) \
+ (((x) >> BIT_SHIFT_USB_MBIST_START_PAUSE_8822B) & \
+ BIT_MASK_USB_MBIST_START_PAUSE_8822B)
+
+#define BIT_SHIFT_PCIE_MBIST_START_PAUSE_8822B 16
+#define BIT_MASK_PCIE_MBIST_START_PAUSE_8822B 0x3f
+#define BIT_PCIE_MBIST_START_PAUSE_8822B(x) \
+ (((x) & BIT_MASK_PCIE_MBIST_START_PAUSE_8822B) \
+ << BIT_SHIFT_PCIE_MBIST_START_PAUSE_8822B)
+#define BIT_GET_PCIE_MBIST_START_PAUSE_8822B(x) \
+ (((x) >> BIT_SHIFT_PCIE_MBIST_START_PAUSE_8822B) & \
+ BIT_MASK_PCIE_MBIST_START_PAUSE_8822B)
+
+#define BIT_SHIFT_MAC_MBIST_START_PAUSE_8822B 0
+#define BIT_MASK_MAC_MBIST_START_PAUSE_8822B 0xfff
+#define BIT_MAC_MBIST_START_PAUSE_8822B(x) \
+ (((x) & BIT_MASK_MAC_MBIST_START_PAUSE_8822B) \
+ << BIT_SHIFT_MAC_MBIST_START_PAUSE_8822B)
+#define BIT_GET_MAC_MBIST_START_PAUSE_8822B(x) \
+ (((x) >> BIT_SHIFT_MAC_MBIST_START_PAUSE_8822B) & \
+ BIT_MASK_MAC_MBIST_START_PAUSE_8822B)
+
+/* 2 REG_MBIST_DONE_8822B */
+
+#define BIT_SHIFT_8051_MBIST_DONE_8822B 26
+#define BIT_MASK_8051_MBIST_DONE_8822B 0x7
+#define BIT_8051_MBIST_DONE_8822B(x) \
+ (((x) & BIT_MASK_8051_MBIST_DONE_8822B) \
+ << BIT_SHIFT_8051_MBIST_DONE_8822B)
+#define BIT_GET_8051_MBIST_DONE_8822B(x) \
+ (((x) >> BIT_SHIFT_8051_MBIST_DONE_8822B) & \
+ BIT_MASK_8051_MBIST_DONE_8822B)
+
+#define BIT_SHIFT_USB_MBIST_DONE_8822B 24
+#define BIT_MASK_USB_MBIST_DONE_8822B 0x3
+#define BIT_USB_MBIST_DONE_8822B(x) \
+ (((x) & BIT_MASK_USB_MBIST_DONE_8822B) \
+ << BIT_SHIFT_USB_MBIST_DONE_8822B)
+#define BIT_GET_USB_MBIST_DONE_8822B(x) \
+ (((x) >> BIT_SHIFT_USB_MBIST_DONE_8822B) & \
+ BIT_MASK_USB_MBIST_DONE_8822B)
+
+#define BIT_SHIFT_PCIE_MBIST_DONE_8822B 16
+#define BIT_MASK_PCIE_MBIST_DONE_8822B 0x3f
+#define BIT_PCIE_MBIST_DONE_8822B(x) \
+ (((x) & BIT_MASK_PCIE_MBIST_DONE_8822B) \
+ << BIT_SHIFT_PCIE_MBIST_DONE_8822B)
+#define BIT_GET_PCIE_MBIST_DONE_8822B(x) \
+ (((x) >> BIT_SHIFT_PCIE_MBIST_DONE_8822B) & \
+ BIT_MASK_PCIE_MBIST_DONE_8822B)
+
+#define BIT_SHIFT_MAC_MBIST_DONE_8822B 0
+#define BIT_MASK_MAC_MBIST_DONE_8822B 0xfff
+#define BIT_MAC_MBIST_DONE_8822B(x) \
+ (((x) & BIT_MASK_MAC_MBIST_DONE_8822B) \
+ << BIT_SHIFT_MAC_MBIST_DONE_8822B)
+#define BIT_GET_MAC_MBIST_DONE_8822B(x) \
+ (((x) >> BIT_SHIFT_MAC_MBIST_DONE_8822B) & \
+ BIT_MASK_MAC_MBIST_DONE_8822B)
+
+/* 2 REG_MBIST_FAIL_NRML_8822B */
+
+#define BIT_SHIFT_MBIST_FAIL_NRML_8822B 0
+#define BIT_MASK_MBIST_FAIL_NRML_8822B 0xffffffffL
+#define BIT_MBIST_FAIL_NRML_8822B(x) \
+ (((x) & BIT_MASK_MBIST_FAIL_NRML_8822B) \
+ << BIT_SHIFT_MBIST_FAIL_NRML_8822B)
+#define BIT_GET_MBIST_FAIL_NRML_8822B(x) \
+ (((x) >> BIT_SHIFT_MBIST_FAIL_NRML_8822B) & \
+ BIT_MASK_MBIST_FAIL_NRML_8822B)
+
+/* 2 REG_AES_DECRPT_DATA_8822B */
+
+#define BIT_SHIFT_IPS_CFG_ADDR_8822B 0
+#define BIT_MASK_IPS_CFG_ADDR_8822B 0xff
+#define BIT_IPS_CFG_ADDR_8822B(x) \
+ (((x) & BIT_MASK_IPS_CFG_ADDR_8822B) << BIT_SHIFT_IPS_CFG_ADDR_8822B)
+#define BIT_GET_IPS_CFG_ADDR_8822B(x) \
+ (((x) >> BIT_SHIFT_IPS_CFG_ADDR_8822B) & BIT_MASK_IPS_CFG_ADDR_8822B)
+
+/* 2 REG_AES_DECRPT_CFG_8822B */
+
+#define BIT_SHIFT_IPS_CFG_DATA_8822B 0
+#define BIT_MASK_IPS_CFG_DATA_8822B 0xffffffffL
+#define BIT_IPS_CFG_DATA_8822B(x) \
+ (((x) & BIT_MASK_IPS_CFG_DATA_8822B) << BIT_SHIFT_IPS_CFG_DATA_8822B)
+#define BIT_GET_IPS_CFG_DATA_8822B(x) \
+ (((x) >> BIT_SHIFT_IPS_CFG_DATA_8822B) & BIT_MASK_IPS_CFG_DATA_8822B)
+
+/* 2 REG_NOT_VALID_8822B */
+
+/* 2 REG_NOT_VALID_8822B */
+
+/* 2 REG_TMETER_8822B */
+#define BIT_TEMP_VALID_8822B BIT(31)
+
+#define BIT_SHIFT_TEMP_VALUE_8822B 24
+#define BIT_MASK_TEMP_VALUE_8822B 0x3f
+#define BIT_TEMP_VALUE_8822B(x) \
+ (((x) & BIT_MASK_TEMP_VALUE_8822B) << BIT_SHIFT_TEMP_VALUE_8822B)
+#define BIT_GET_TEMP_VALUE_8822B(x) \
+ (((x) >> BIT_SHIFT_TEMP_VALUE_8822B) & BIT_MASK_TEMP_VALUE_8822B)
+
+#define BIT_SHIFT_REG_TMETER_TIMER_8822B 8
+#define BIT_MASK_REG_TMETER_TIMER_8822B 0xfff
+#define BIT_REG_TMETER_TIMER_8822B(x) \
+ (((x) & BIT_MASK_REG_TMETER_TIMER_8822B) \
+ << BIT_SHIFT_REG_TMETER_TIMER_8822B)
+#define BIT_GET_REG_TMETER_TIMER_8822B(x) \
+ (((x) >> BIT_SHIFT_REG_TMETER_TIMER_8822B) & \
+ BIT_MASK_REG_TMETER_TIMER_8822B)
+
+#define BIT_SHIFT_REG_TEMP_DELTA_8822B 2
+#define BIT_MASK_REG_TEMP_DELTA_8822B 0x3f
+#define BIT_REG_TEMP_DELTA_8822B(x) \
+ (((x) & BIT_MASK_REG_TEMP_DELTA_8822B) \
+ << BIT_SHIFT_REG_TEMP_DELTA_8822B)
+#define BIT_GET_REG_TEMP_DELTA_8822B(x) \
+ (((x) >> BIT_SHIFT_REG_TEMP_DELTA_8822B) & \
+ BIT_MASK_REG_TEMP_DELTA_8822B)
+
+#define BIT_REG_TMETER_EN_8822B BIT(0)
+
+/* 2 REG_OSC_32K_CTRL_8822B */
+
+#define BIT_SHIFT_OSC_32K_CLKGEN_0_8822B 16
+#define BIT_MASK_OSC_32K_CLKGEN_0_8822B 0xffff
+#define BIT_OSC_32K_CLKGEN_0_8822B(x) \
+ (((x) & BIT_MASK_OSC_32K_CLKGEN_0_8822B) \
+ << BIT_SHIFT_OSC_32K_CLKGEN_0_8822B)
+#define BIT_GET_OSC_32K_CLKGEN_0_8822B(x) \
+ (((x) >> BIT_SHIFT_OSC_32K_CLKGEN_0_8822B) & \
+ BIT_MASK_OSC_32K_CLKGEN_0_8822B)
+
+#define BIT_SHIFT_OSC_32K_RES_COMP_8822B 4
+#define BIT_MASK_OSC_32K_RES_COMP_8822B 0x3
+#define BIT_OSC_32K_RES_COMP_8822B(x) \
+ (((x) & BIT_MASK_OSC_32K_RES_COMP_8822B) \
+ << BIT_SHIFT_OSC_32K_RES_COMP_8822B)
+#define BIT_GET_OSC_32K_RES_COMP_8822B(x) \
+ (((x) >> BIT_SHIFT_OSC_32K_RES_COMP_8822B) & \
+ BIT_MASK_OSC_32K_RES_COMP_8822B)
+
+#define BIT_OSC_32K_OUT_SEL_8822B BIT(3)
+#define BIT_ISO_WL_2_OSC_32K_8822B BIT(1)
+#define BIT_POW_CKGEN_8822B BIT(0)
+
+/* 2 REG_32K_CAL_REG1_8822B */
+#define BIT_CAL_32K_REG_WR_8822B BIT(31)
+#define BIT_CAL_32K_DBG_SEL_8822B BIT(22)
+
+#define BIT_SHIFT_CAL_32K_REG_ADDR_8822B 16
+#define BIT_MASK_CAL_32K_REG_ADDR_8822B 0x3f
+#define BIT_CAL_32K_REG_ADDR_8822B(x) \
+ (((x) & BIT_MASK_CAL_32K_REG_ADDR_8822B) \
+ << BIT_SHIFT_CAL_32K_REG_ADDR_8822B)
+#define BIT_GET_CAL_32K_REG_ADDR_8822B(x) \
+ (((x) >> BIT_SHIFT_CAL_32K_REG_ADDR_8822B) & \
+ BIT_MASK_CAL_32K_REG_ADDR_8822B)
+
+#define BIT_SHIFT_CAL_32K_REG_DATA_8822B 0
+#define BIT_MASK_CAL_32K_REG_DATA_8822B 0xffff
+#define BIT_CAL_32K_REG_DATA_8822B(x) \
+ (((x) & BIT_MASK_CAL_32K_REG_DATA_8822B) \
+ << BIT_SHIFT_CAL_32K_REG_DATA_8822B)
+#define BIT_GET_CAL_32K_REG_DATA_8822B(x) \
+ (((x) >> BIT_SHIFT_CAL_32K_REG_DATA_8822B) & \
+ BIT_MASK_CAL_32K_REG_DATA_8822B)
+
+/* 2 REG_NOT_VALID_8822B */
+
+/* 2 REG_C2HEVT_8822B */
+
+#define BIT_SHIFT_C2HEVT_MSG_8822B 0
+#define BIT_MASK_C2HEVT_MSG_8822B 0xffffffffffffffffffffffffffffffffL
+#define BIT_C2HEVT_MSG_8822B(x) \
+ (((x) & BIT_MASK_C2HEVT_MSG_8822B) << BIT_SHIFT_C2HEVT_MSG_8822B)
+#define BIT_GET_C2HEVT_MSG_8822B(x) \
+ (((x) >> BIT_SHIFT_C2HEVT_MSG_8822B) & BIT_MASK_C2HEVT_MSG_8822B)
+
+/* 2 REG_SW_DEFINED_PAGE1_8822B */
+
+#define BIT_SHIFT_SW_DEFINED_PAGE1_8822B 0
+#define BIT_MASK_SW_DEFINED_PAGE1_8822B 0xffffffffffffffffL
+#define BIT_SW_DEFINED_PAGE1_8822B(x) \
+ (((x) & BIT_MASK_SW_DEFINED_PAGE1_8822B) \
+ << BIT_SHIFT_SW_DEFINED_PAGE1_8822B)
+#define BIT_GET_SW_DEFINED_PAGE1_8822B(x) \
+ (((x) >> BIT_SHIFT_SW_DEFINED_PAGE1_8822B) & \
+ BIT_MASK_SW_DEFINED_PAGE1_8822B)
+
+/* 2 REG_MCUTST_I_8822B */
+
+#define BIT_SHIFT_MCUDMSG_I_8822B 0
+#define BIT_MASK_MCUDMSG_I_8822B 0xffffffffL
+#define BIT_MCUDMSG_I_8822B(x) \
+ (((x) & BIT_MASK_MCUDMSG_I_8822B) << BIT_SHIFT_MCUDMSG_I_8822B)
+#define BIT_GET_MCUDMSG_I_8822B(x) \
+ (((x) >> BIT_SHIFT_MCUDMSG_I_8822B) & BIT_MASK_MCUDMSG_I_8822B)
+
+/* 2 REG_MCUTST_II_8822B */
+
+#define BIT_SHIFT_MCUDMSG_II_8822B 0
+#define BIT_MASK_MCUDMSG_II_8822B 0xffffffffL
+#define BIT_MCUDMSG_II_8822B(x) \
+ (((x) & BIT_MASK_MCUDMSG_II_8822B) << BIT_SHIFT_MCUDMSG_II_8822B)
+#define BIT_GET_MCUDMSG_II_8822B(x) \
+ (((x) >> BIT_SHIFT_MCUDMSG_II_8822B) & BIT_MASK_MCUDMSG_II_8822B)
+
+/* 2 REG_FMETHR_8822B */
+#define BIT_FMSG_INT_8822B BIT(31)
+
+#define BIT_SHIFT_FW_MSG_8822B 0
+#define BIT_MASK_FW_MSG_8822B 0xffffffffL
+#define BIT_FW_MSG_8822B(x) \
+ (((x) & BIT_MASK_FW_MSG_8822B) << BIT_SHIFT_FW_MSG_8822B)
+#define BIT_GET_FW_MSG_8822B(x) \
+ (((x) >> BIT_SHIFT_FW_MSG_8822B) & BIT_MASK_FW_MSG_8822B)
+
+/* 2 REG_HMETFR_8822B */
+
+#define BIT_SHIFT_HRCV_MSG_8822B 24
+#define BIT_MASK_HRCV_MSG_8822B 0xff
+#define BIT_HRCV_MSG_8822B(x) \
+ (((x) & BIT_MASK_HRCV_MSG_8822B) << BIT_SHIFT_HRCV_MSG_8822B)
+#define BIT_GET_HRCV_MSG_8822B(x) \
+ (((x) >> BIT_SHIFT_HRCV_MSG_8822B) & BIT_MASK_HRCV_MSG_8822B)
+
+#define BIT_INT_BOX3_8822B BIT(3)
+#define BIT_INT_BOX2_8822B BIT(2)
+#define BIT_INT_BOX1_8822B BIT(1)
+#define BIT_INT_BOX0_8822B BIT(0)
+
+/* 2 REG_HMEBOX0_8822B */
+
+#define BIT_SHIFT_HOST_MSG_0_8822B 0
+#define BIT_MASK_HOST_MSG_0_8822B 0xffffffffL
+#define BIT_HOST_MSG_0_8822B(x) \
+ (((x) & BIT_MASK_HOST_MSG_0_8822B) << BIT_SHIFT_HOST_MSG_0_8822B)
+#define BIT_GET_HOST_MSG_0_8822B(x) \
+ (((x) >> BIT_SHIFT_HOST_MSG_0_8822B) & BIT_MASK_HOST_MSG_0_8822B)
+
+/* 2 REG_HMEBOX1_8822B */
+
+#define BIT_SHIFT_HOST_MSG_1_8822B 0
+#define BIT_MASK_HOST_MSG_1_8822B 0xffffffffL
+#define BIT_HOST_MSG_1_8822B(x) \
+ (((x) & BIT_MASK_HOST_MSG_1_8822B) << BIT_SHIFT_HOST_MSG_1_8822B)
+#define BIT_GET_HOST_MSG_1_8822B(x) \
+ (((x) >> BIT_SHIFT_HOST_MSG_1_8822B) & BIT_MASK_HOST_MSG_1_8822B)
+
+/* 2 REG_HMEBOX2_8822B */
+
+#define BIT_SHIFT_HOST_MSG_2_8822B 0
+#define BIT_MASK_HOST_MSG_2_8822B 0xffffffffL
+#define BIT_HOST_MSG_2_8822B(x) \
+ (((x) & BIT_MASK_HOST_MSG_2_8822B) << BIT_SHIFT_HOST_MSG_2_8822B)
+#define BIT_GET_HOST_MSG_2_8822B(x) \
+ (((x) >> BIT_SHIFT_HOST_MSG_2_8822B) & BIT_MASK_HOST_MSG_2_8822B)
+
+/* 2 REG_HMEBOX3_8822B */
+
+#define BIT_SHIFT_HOST_MSG_3_8822B 0
+#define BIT_MASK_HOST_MSG_3_8822B 0xffffffffL
+#define BIT_HOST_MSG_3_8822B(x) \
+ (((x) & BIT_MASK_HOST_MSG_3_8822B) << BIT_SHIFT_HOST_MSG_3_8822B)
+#define BIT_GET_HOST_MSG_3_8822B(x) \
+ (((x) >> BIT_SHIFT_HOST_MSG_3_8822B) & BIT_MASK_HOST_MSG_3_8822B)
+
+/* 2 REG_LLT_INIT_8822B */
+
+#define BIT_SHIFT_LLTE_RWM_8822B 30
+#define BIT_MASK_LLTE_RWM_8822B 0x3
+#define BIT_LLTE_RWM_8822B(x) \
+ (((x) & BIT_MASK_LLTE_RWM_8822B) << BIT_SHIFT_LLTE_RWM_8822B)
+#define BIT_GET_LLTE_RWM_8822B(x) \
+ (((x) >> BIT_SHIFT_LLTE_RWM_8822B) & BIT_MASK_LLTE_RWM_8822B)
+
+#define BIT_SHIFT_LLTINI_PDATA_V1_8822B 16
+#define BIT_MASK_LLTINI_PDATA_V1_8822B 0xfff
+#define BIT_LLTINI_PDATA_V1_8822B(x) \
+ (((x) & BIT_MASK_LLTINI_PDATA_V1_8822B) \
+ << BIT_SHIFT_LLTINI_PDATA_V1_8822B)
+#define BIT_GET_LLTINI_PDATA_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_LLTINI_PDATA_V1_8822B) & \
+ BIT_MASK_LLTINI_PDATA_V1_8822B)
+
+#define BIT_SHIFT_LLTINI_HDATA_V1_8822B 0
+#define BIT_MASK_LLTINI_HDATA_V1_8822B 0xfff
+#define BIT_LLTINI_HDATA_V1_8822B(x) \
+ (((x) & BIT_MASK_LLTINI_HDATA_V1_8822B) \
+ << BIT_SHIFT_LLTINI_HDATA_V1_8822B)
+#define BIT_GET_LLTINI_HDATA_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_LLTINI_HDATA_V1_8822B) & \
+ BIT_MASK_LLTINI_HDATA_V1_8822B)
+
+/* 2 REG_LLT_INIT_ADDR_8822B */
+
+#define BIT_SHIFT_LLTINI_ADDR_V1_8822B 0
+#define BIT_MASK_LLTINI_ADDR_V1_8822B 0xfff
+#define BIT_LLTINI_ADDR_V1_8822B(x) \
+ (((x) & BIT_MASK_LLTINI_ADDR_V1_8822B) \
+ << BIT_SHIFT_LLTINI_ADDR_V1_8822B)
+#define BIT_GET_LLTINI_ADDR_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_LLTINI_ADDR_V1_8822B) & \
+ BIT_MASK_LLTINI_ADDR_V1_8822B)
+
+/* 2 REG_BB_ACCESS_CTRL_8822B */
+
+#define BIT_SHIFT_BB_WRITE_READ_8822B 30
+#define BIT_MASK_BB_WRITE_READ_8822B 0x3
+#define BIT_BB_WRITE_READ_8822B(x) \
+ (((x) & BIT_MASK_BB_WRITE_READ_8822B) << BIT_SHIFT_BB_WRITE_READ_8822B)
+#define BIT_GET_BB_WRITE_READ_8822B(x) \
+ (((x) >> BIT_SHIFT_BB_WRITE_READ_8822B) & BIT_MASK_BB_WRITE_READ_8822B)
+
+#define BIT_SHIFT_BB_WRITE_EN_8822B 12
+#define BIT_MASK_BB_WRITE_EN_8822B 0xf
+#define BIT_BB_WRITE_EN_8822B(x) \
+ (((x) & BIT_MASK_BB_WRITE_EN_8822B) << BIT_SHIFT_BB_WRITE_EN_8822B)
+#define BIT_GET_BB_WRITE_EN_8822B(x) \
+ (((x) >> BIT_SHIFT_BB_WRITE_EN_8822B) & BIT_MASK_BB_WRITE_EN_8822B)
+
+#define BIT_SHIFT_BB_ADDR_8822B 2
+#define BIT_MASK_BB_ADDR_8822B 0x1ff
+#define BIT_BB_ADDR_8822B(x) \
+ (((x) & BIT_MASK_BB_ADDR_8822B) << BIT_SHIFT_BB_ADDR_8822B)
+#define BIT_GET_BB_ADDR_8822B(x) \
+ (((x) >> BIT_SHIFT_BB_ADDR_8822B) & BIT_MASK_BB_ADDR_8822B)
+
+#define BIT_BB_ERRACC_8822B BIT(0)
+
+/* 2 REG_BB_ACCESS_DATA_8822B */
+
+#define BIT_SHIFT_BB_DATA_8822B 0
+#define BIT_MASK_BB_DATA_8822B 0xffffffffL
+#define BIT_BB_DATA_8822B(x) \
+ (((x) & BIT_MASK_BB_DATA_8822B) << BIT_SHIFT_BB_DATA_8822B)
+#define BIT_GET_BB_DATA_8822B(x) \
+ (((x) >> BIT_SHIFT_BB_DATA_8822B) & BIT_MASK_BB_DATA_8822B)
+
+/* 2 REG_HMEBOX_E0_8822B */
+
+#define BIT_SHIFT_HMEBOX_E0_8822B 0
+#define BIT_MASK_HMEBOX_E0_8822B 0xffffffffL
+#define BIT_HMEBOX_E0_8822B(x) \
+ (((x) & BIT_MASK_HMEBOX_E0_8822B) << BIT_SHIFT_HMEBOX_E0_8822B)
+#define BIT_GET_HMEBOX_E0_8822B(x) \
+ (((x) >> BIT_SHIFT_HMEBOX_E0_8822B) & BIT_MASK_HMEBOX_E0_8822B)
+
+/* 2 REG_HMEBOX_E1_8822B */
+
+#define BIT_SHIFT_HMEBOX_E1_8822B 0
+#define BIT_MASK_HMEBOX_E1_8822B 0xffffffffL
+#define BIT_HMEBOX_E1_8822B(x) \
+ (((x) & BIT_MASK_HMEBOX_E1_8822B) << BIT_SHIFT_HMEBOX_E1_8822B)
+#define BIT_GET_HMEBOX_E1_8822B(x) \
+ (((x) >> BIT_SHIFT_HMEBOX_E1_8822B) & BIT_MASK_HMEBOX_E1_8822B)
+
+/* 2 REG_HMEBOX_E2_8822B */
+
+#define BIT_SHIFT_HMEBOX_E2_8822B 0
+#define BIT_MASK_HMEBOX_E2_8822B 0xffffffffL
+#define BIT_HMEBOX_E2_8822B(x) \
+ (((x) & BIT_MASK_HMEBOX_E2_8822B) << BIT_SHIFT_HMEBOX_E2_8822B)
+#define BIT_GET_HMEBOX_E2_8822B(x) \
+ (((x) >> BIT_SHIFT_HMEBOX_E2_8822B) & BIT_MASK_HMEBOX_E2_8822B)
+
+/* 2 REG_HMEBOX_E3_8822B */
+
+#define BIT_SHIFT_HMEBOX_E3_8822B 0
+#define BIT_MASK_HMEBOX_E3_8822B 0xffffffffL
+#define BIT_HMEBOX_E3_8822B(x) \
+ (((x) & BIT_MASK_HMEBOX_E3_8822B) << BIT_SHIFT_HMEBOX_E3_8822B)
+#define BIT_GET_HMEBOX_E3_8822B(x) \
+ (((x) >> BIT_SHIFT_HMEBOX_E3_8822B) & BIT_MASK_HMEBOX_E3_8822B)
+
+/* 2 REG_NOT_VALID_8822B */
+
+/* 2 REG_CR_EXT_8822B */
+
+#define BIT_SHIFT_PHY_REQ_DELAY_8822B 24
+#define BIT_MASK_PHY_REQ_DELAY_8822B 0xf
+#define BIT_PHY_REQ_DELAY_8822B(x) \
+ (((x) & BIT_MASK_PHY_REQ_DELAY_8822B) << BIT_SHIFT_PHY_REQ_DELAY_8822B)
+#define BIT_GET_PHY_REQ_DELAY_8822B(x) \
+ (((x) >> BIT_SHIFT_PHY_REQ_DELAY_8822B) & BIT_MASK_PHY_REQ_DELAY_8822B)
+
+#define BIT_SPD_DOWN_8822B BIT(16)
+
+#define BIT_SHIFT_NETYPE4_8822B 4
+#define BIT_MASK_NETYPE4_8822B 0x3
+#define BIT_NETYPE4_8822B(x) \
+ (((x) & BIT_MASK_NETYPE4_8822B) << BIT_SHIFT_NETYPE4_8822B)
+#define BIT_GET_NETYPE4_8822B(x) \
+ (((x) >> BIT_SHIFT_NETYPE4_8822B) & BIT_MASK_NETYPE4_8822B)
+
+#define BIT_SHIFT_NETYPE3_8822B 2
+#define BIT_MASK_NETYPE3_8822B 0x3
+#define BIT_NETYPE3_8822B(x) \
+ (((x) & BIT_MASK_NETYPE3_8822B) << BIT_SHIFT_NETYPE3_8822B)
+#define BIT_GET_NETYPE3_8822B(x) \
+ (((x) >> BIT_SHIFT_NETYPE3_8822B) & BIT_MASK_NETYPE3_8822B)
+
+#define BIT_SHIFT_NETYPE2_8822B 0
+#define BIT_MASK_NETYPE2_8822B 0x3
+#define BIT_NETYPE2_8822B(x) \
+ (((x) & BIT_MASK_NETYPE2_8822B) << BIT_SHIFT_NETYPE2_8822B)
+#define BIT_GET_NETYPE2_8822B(x) \
+ (((x) >> BIT_SHIFT_NETYPE2_8822B) & BIT_MASK_NETYPE2_8822B)
+
+/* 2 REG_FWFF_8822B */
+
+#define BIT_SHIFT_PKTNUM_TH_V1_8822B 24
+#define BIT_MASK_PKTNUM_TH_V1_8822B 0xff
+#define BIT_PKTNUM_TH_V1_8822B(x) \
+ (((x) & BIT_MASK_PKTNUM_TH_V1_8822B) << BIT_SHIFT_PKTNUM_TH_V1_8822B)
+#define BIT_GET_PKTNUM_TH_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_PKTNUM_TH_V1_8822B) & BIT_MASK_PKTNUM_TH_V1_8822B)
+
+#define BIT_SHIFT_TIMER_TH_8822B 16
+#define BIT_MASK_TIMER_TH_8822B 0xff
+#define BIT_TIMER_TH_8822B(x) \
+ (((x) & BIT_MASK_TIMER_TH_8822B) << BIT_SHIFT_TIMER_TH_8822B)
+#define BIT_GET_TIMER_TH_8822B(x) \
+ (((x) >> BIT_SHIFT_TIMER_TH_8822B) & BIT_MASK_TIMER_TH_8822B)
+
+#define BIT_SHIFT_RXPKT1ENADDR_8822B 0
+#define BIT_MASK_RXPKT1ENADDR_8822B 0xffff
+#define BIT_RXPKT1ENADDR_8822B(x) \
+ (((x) & BIT_MASK_RXPKT1ENADDR_8822B) << BIT_SHIFT_RXPKT1ENADDR_8822B)
+#define BIT_GET_RXPKT1ENADDR_8822B(x) \
+ (((x) >> BIT_SHIFT_RXPKT1ENADDR_8822B) & BIT_MASK_RXPKT1ENADDR_8822B)
+
+/* 2 REG_RXFF_PTR_V1_8822B */
+
+/* 2 REG_NOT_VALID_8822B */
+
+#define BIT_SHIFT_RXFF0_RDPTR_V2_8822B 0
+#define BIT_MASK_RXFF0_RDPTR_V2_8822B 0x3ffff
+#define BIT_RXFF0_RDPTR_V2_8822B(x) \
+ (((x) & BIT_MASK_RXFF0_RDPTR_V2_8822B) \
+ << BIT_SHIFT_RXFF0_RDPTR_V2_8822B)
+#define BIT_GET_RXFF0_RDPTR_V2_8822B(x) \
+ (((x) >> BIT_SHIFT_RXFF0_RDPTR_V2_8822B) & \
+ BIT_MASK_RXFF0_RDPTR_V2_8822B)
+
+/* 2 REG_RXFF_WTR_V1_8822B */
+
+/* 2 REG_NOT_VALID_8822B */
+
+#define BIT_SHIFT_RXFF0_WTPTR_V2_8822B 0
+#define BIT_MASK_RXFF0_WTPTR_V2_8822B 0x3ffff
+#define BIT_RXFF0_WTPTR_V2_8822B(x) \
+ (((x) & BIT_MASK_RXFF0_WTPTR_V2_8822B) \
+ << BIT_SHIFT_RXFF0_WTPTR_V2_8822B)
+#define BIT_GET_RXFF0_WTPTR_V2_8822B(x) \
+ (((x) >> BIT_SHIFT_RXFF0_WTPTR_V2_8822B) & \
+ BIT_MASK_RXFF0_WTPTR_V2_8822B)
+
+/* 2 REG_FE2IMR_8822B */
+#define BIT__FE4ISR__IND_MSK_8822B BIT(29)
+#define BIT_FS_TXSC_DESC_DONE_INT_EN_8822B BIT(28)
+#define BIT_FS_TXSC_BKDONE_INT_EN_8822B BIT(27)
+#define BIT_FS_TXSC_BEDONE_INT_EN_8822B BIT(26)
+#define BIT_FS_TXSC_VIDONE_INT_EN_8822B BIT(25)
+#define BIT_FS_TXSC_VODONE_INT_EN_8822B BIT(24)
+#define BIT_FS_ATIM_MB7_INT_EN_8822B BIT(23)
+#define BIT_FS_ATIM_MB6_INT_EN_8822B BIT(22)
+#define BIT_FS_ATIM_MB5_INT_EN_8822B BIT(21)
+#define BIT_FS_ATIM_MB4_INT_EN_8822B BIT(20)
+#define BIT_FS_ATIM_MB3_INT_EN_8822B BIT(19)
+#define BIT_FS_ATIM_MB2_INT_EN_8822B BIT(18)
+#define BIT_FS_ATIM_MB1_INT_EN_8822B BIT(17)
+#define BIT_FS_ATIM_MB0_INT_EN_8822B BIT(16)
+#define BIT_FS_TBTT4INT_EN_8822B BIT(11)
+#define BIT_FS_TBTT3INT_EN_8822B BIT(10)
+#define BIT_FS_TBTT2INT_EN_8822B BIT(9)
+#define BIT_FS_TBTT1INT_EN_8822B BIT(8)
+#define BIT_FS_TBTT0_MB7INT_EN_8822B BIT(7)
+#define BIT_FS_TBTT0_MB6INT_EN_8822B BIT(6)
+#define BIT_FS_TBTT0_MB5INT_EN_8822B BIT(5)
+#define BIT_FS_TBTT0_MB4INT_EN_8822B BIT(4)
+#define BIT_FS_TBTT0_MB3INT_EN_8822B BIT(3)
+#define BIT_FS_TBTT0_MB2INT_EN_8822B BIT(2)
+#define BIT_FS_TBTT0_MB1INT_EN_8822B BIT(1)
+#define BIT_FS_TBTT0_INT_EN_8822B BIT(0)
+
+/* 2 REG_FE2ISR_8822B */
+#define BIT__FE4ISR__IND_INT_8822B BIT(29)
+#define BIT_FS_TXSC_DESC_DONE_INT_8822B BIT(28)
+#define BIT_FS_TXSC_BKDONE_INT_8822B BIT(27)
+#define BIT_FS_TXSC_BEDONE_INT_8822B BIT(26)
+#define BIT_FS_TXSC_VIDONE_INT_8822B BIT(25)
+#define BIT_FS_TXSC_VODONE_INT_8822B BIT(24)
+#define BIT_FS_ATIM_MB7_INT_8822B BIT(23)
+#define BIT_FS_ATIM_MB6_INT_8822B BIT(22)
+#define BIT_FS_ATIM_MB5_INT_8822B BIT(21)
+#define BIT_FS_ATIM_MB4_INT_8822B BIT(20)
+#define BIT_FS_ATIM_MB3_INT_8822B BIT(19)
+#define BIT_FS_ATIM_MB2_INT_8822B BIT(18)
+#define BIT_FS_ATIM_MB1_INT_8822B BIT(17)
+#define BIT_FS_ATIM_MB0_INT_8822B BIT(16)
+#define BIT_FS_TBTT4INT_8822B BIT(11)
+#define BIT_FS_TBTT3INT_8822B BIT(10)
+#define BIT_FS_TBTT2INT_8822B BIT(9)
+#define BIT_FS_TBTT1INT_8822B BIT(8)
+#define BIT_FS_TBTT0_MB7INT_8822B BIT(7)
+#define BIT_FS_TBTT0_MB6INT_8822B BIT(6)
+#define BIT_FS_TBTT0_MB5INT_8822B BIT(5)
+#define BIT_FS_TBTT0_MB4INT_8822B BIT(4)
+#define BIT_FS_TBTT0_MB3INT_8822B BIT(3)
+#define BIT_FS_TBTT0_MB2INT_8822B BIT(2)
+#define BIT_FS_TBTT0_MB1INT_8822B BIT(1)
+#define BIT_FS_TBTT0_INT_8822B BIT(0)
+
+/* 2 REG_FE3IMR_8822B */
+#define BIT_FS_CLI3_MTI_BCNIVLEAR_INT__EN_8822B BIT(31)
+#define BIT_FS_CLI2_MTI_BCNIVLEAR_INT__EN_8822B BIT(30)
+#define BIT_FS_CLI1_MTI_BCNIVLEAR_INT__EN_8822B BIT(29)
+#define BIT_FS_CLI0_MTI_BCNIVLEAR_INT__EN_8822B BIT(28)
+#define BIT_FS_BCNDMA4_INT_EN_8822B BIT(27)
+#define BIT_FS_BCNDMA3_INT_EN_8822B BIT(26)
+#define BIT_FS_BCNDMA2_INT_EN_8822B BIT(25)
+#define BIT_FS_BCNDMA1_INT_EN_8822B BIT(24)
+#define BIT_FS_BCNDMA0_MB7_INT_EN_8822B BIT(23)
+#define BIT_FS_BCNDMA0_MB6_INT_EN_8822B BIT(22)
+#define BIT_FS_BCNDMA0_MB5_INT_EN_8822B BIT(21)
+#define BIT_FS_BCNDMA0_MB4_INT_EN_8822B BIT(20)
+#define BIT_FS_BCNDMA0_MB3_INT_EN_8822B BIT(19)
+#define BIT_FS_BCNDMA0_MB2_INT_EN_8822B BIT(18)
+#define BIT_FS_BCNDMA0_MB1_INT_EN_8822B BIT(17)
+#define BIT_FS_BCNDMA0_INT_EN_8822B BIT(16)
+#define BIT_FS_MTI_BCNIVLEAR_INT__EN_8822B BIT(15)
+#define BIT_FS_BCNERLY4_INT_EN_8822B BIT(11)
+#define BIT_FS_BCNERLY3_INT_EN_8822B BIT(10)
+#define BIT_FS_BCNERLY2_INT_EN_8822B BIT(9)
+#define BIT_FS_BCNERLY1_INT_EN_8822B BIT(8)
+#define BIT_FS_BCNERLY0_MB7INT_EN_8822B BIT(7)
+#define BIT_FS_BCNERLY0_MB6INT_EN_8822B BIT(6)
+#define BIT_FS_BCNERLY0_MB5INT_EN_8822B BIT(5)
+#define BIT_FS_BCNERLY0_MB4INT_EN_8822B BIT(4)
+#define BIT_FS_BCNERLY0_MB3INT_EN_8822B BIT(3)
+#define BIT_FS_BCNERLY0_MB2INT_EN_8822B BIT(2)
+#define BIT_FS_BCNERLY0_MB1INT_EN_8822B BIT(1)
+#define BIT_FS_BCNERLY0_INT_EN_8822B BIT(0)
+
+/* 2 REG_FE3ISR_8822B */
+#define BIT_FS_CLI3_MTI_BCNIVLEAR_INT_8822B BIT(31)
+#define BIT_FS_CLI2_MTI_BCNIVLEAR_INT_8822B BIT(30)
+#define BIT_FS_CLI1_MTI_BCNIVLEAR_INT_8822B BIT(29)
+#define BIT_FS_CLI0_MTI_BCNIVLEAR_INT_8822B BIT(28)
+#define BIT_FS_BCNDMA4_INT_8822B BIT(27)
+#define BIT_FS_BCNDMA3_INT_8822B BIT(26)
+#define BIT_FS_BCNDMA2_INT_8822B BIT(25)
+#define BIT_FS_BCNDMA1_INT_8822B BIT(24)
+#define BIT_FS_BCNDMA0_MB7_INT_8822B BIT(23)
+#define BIT_FS_BCNDMA0_MB6_INT_8822B BIT(22)
+#define BIT_FS_BCNDMA0_MB5_INT_8822B BIT(21)
+#define BIT_FS_BCNDMA0_MB4_INT_8822B BIT(20)
+#define BIT_FS_BCNDMA0_MB3_INT_8822B BIT(19)
+#define BIT_FS_BCNDMA0_MB2_INT_8822B BIT(18)
+#define BIT_FS_BCNDMA0_MB1_INT_8822B BIT(17)
+#define BIT_FS_BCNDMA0_INT_8822B BIT(16)
+#define BIT_FS_MTI_BCNIVLEAR_INT_8822B BIT(15)
+#define BIT_FS_BCNERLY4_INT_8822B BIT(11)
+#define BIT_FS_BCNERLY3_INT_8822B BIT(10)
+#define BIT_FS_BCNERLY2_INT_8822B BIT(9)
+#define BIT_FS_BCNERLY1_INT_8822B BIT(8)
+#define BIT_FS_BCNERLY0_MB7INT_8822B BIT(7)
+#define BIT_FS_BCNERLY0_MB6INT_8822B BIT(6)
+#define BIT_FS_BCNERLY0_MB5INT_8822B BIT(5)
+#define BIT_FS_BCNERLY0_MB4INT_8822B BIT(4)
+#define BIT_FS_BCNERLY0_MB3INT_8822B BIT(3)
+#define BIT_FS_BCNERLY0_MB2INT_8822B BIT(2)
+#define BIT_FS_BCNERLY0_MB1INT_8822B BIT(1)
+#define BIT_FS_BCNERLY0_INT_8822B BIT(0)
+
+/* 2 REG_FE4IMR_8822B */
+#define BIT_FS_CLI3_TXPKTIN_INT_EN_8822B BIT(19)
+#define BIT_FS_CLI2_TXPKTIN_INT_EN_8822B BIT(18)
+#define BIT_FS_CLI1_TXPKTIN_INT_EN_8822B BIT(17)
+#define BIT_FS_CLI0_TXPKTIN_INT_EN_8822B BIT(16)
+#define BIT_FS_CLI3_RX_UMD0_INT_EN_8822B BIT(15)
+#define BIT_FS_CLI3_RX_UMD1_INT_EN_8822B BIT(14)
+#define BIT_FS_CLI3_RX_BMD0_INT_EN_8822B BIT(13)
+#define BIT_FS_CLI3_RX_BMD1_INT_EN_8822B BIT(12)
+#define BIT_FS_CLI2_RX_UMD0_INT_EN_8822B BIT(11)
+#define BIT_FS_CLI2_RX_UMD1_INT_EN_8822B BIT(10)
+#define BIT_FS_CLI2_RX_BMD0_INT_EN_8822B BIT(9)
+#define BIT_FS_CLI2_RX_BMD1_INT_EN_8822B BIT(8)
+#define BIT_FS_CLI1_RX_UMD0_INT_EN_8822B BIT(7)
+#define BIT_FS_CLI1_RX_UMD1_INT_EN_8822B BIT(6)
+#define BIT_FS_CLI1_RX_BMD0_INT_EN_8822B BIT(5)
+#define BIT_FS_CLI1_RX_BMD1_INT_EN_8822B BIT(4)
+#define BIT_FS_CLI0_RX_UMD0_INT_EN_8822B BIT(3)
+#define BIT_FS_CLI0_RX_UMD1_INT_EN_8822B BIT(2)
+#define BIT_FS_CLI0_RX_BMD0_INT_EN_8822B BIT(1)
+#define BIT_FS_CLI0_RX_BMD1_INT_EN_8822B BIT(0)
+
+/* 2 REG_FE4ISR_8822B */
+#define BIT_FS_CLI3_TXPKTIN_INT_8822B BIT(19)
+#define BIT_FS_CLI2_TXPKTIN_INT_8822B BIT(18)
+#define BIT_FS_CLI1_TXPKTIN_INT_8822B BIT(17)
+#define BIT_FS_CLI0_TXPKTIN_INT_8822B BIT(16)
+#define BIT_FS_CLI3_RX_UMD0_INT_8822B BIT(15)
+#define BIT_FS_CLI3_RX_UMD1_INT_8822B BIT(14)
+#define BIT_FS_CLI3_RX_BMD0_INT_8822B BIT(13)
+#define BIT_FS_CLI3_RX_BMD1_INT_8822B BIT(12)
+#define BIT_FS_CLI2_RX_UMD0_INT_8822B BIT(11)
+#define BIT_FS_CLI2_RX_UMD1_INT_8822B BIT(10)
+#define BIT_FS_CLI2_RX_BMD0_INT_8822B BIT(9)
+#define BIT_FS_CLI2_RX_BMD1_INT_8822B BIT(8)
+#define BIT_FS_CLI1_RX_UMD0_INT_8822B BIT(7)
+#define BIT_FS_CLI1_RX_UMD1_INT_8822B BIT(6)
+#define BIT_FS_CLI1_RX_BMD0_INT_8822B BIT(5)
+#define BIT_FS_CLI1_RX_BMD1_INT_8822B BIT(4)
+#define BIT_FS_CLI0_RX_UMD0_INT_8822B BIT(3)
+#define BIT_FS_CLI0_RX_UMD1_INT_8822B BIT(2)
+#define BIT_FS_CLI0_RX_BMD0_INT_8822B BIT(1)
+#define BIT_FS_CLI0_RX_BMD1_INT_8822B BIT(0)
+
+/* 2 REG_FT1IMR_8822B */
+#define BIT__FT2ISR__IND_MSK_8822B BIT(30)
+#define BIT_FTM_PTT_INT_EN_8822B BIT(29)
+#define BIT_RXFTMREQ_INT_EN_8822B BIT(28)
+#define BIT_RXFTM_INT_EN_8822B BIT(27)
+#define BIT_TXFTM_INT_EN_8822B BIT(26)
+#define BIT_FS_H2C_CMD_OK_INT_EN_8822B BIT(25)
+#define BIT_FS_H2C_CMD_FULL_INT_EN_8822B BIT(24)
+#define BIT_FS_MACID_PWRCHANGE5_INT_EN_8822B BIT(23)
+#define BIT_FS_MACID_PWRCHANGE4_INT_EN_8822B BIT(22)
+#define BIT_FS_MACID_PWRCHANGE3_INT_EN_8822B BIT(21)
+#define BIT_FS_MACID_PWRCHANGE2_INT_EN_8822B BIT(20)
+#define BIT_FS_MACID_PWRCHANGE1_INT_EN_8822B BIT(19)
+#define BIT_FS_MACID_PWRCHANGE0_INT_EN_8822B BIT(18)
+#define BIT_FS_CTWEND2_INT_EN_8822B BIT(17)
+#define BIT_FS_CTWEND1_INT_EN_8822B BIT(16)
+#define BIT_FS_CTWEND0_INT_EN_8822B BIT(15)
+#define BIT_FS_TX_NULL1_INT_EN_8822B BIT(14)
+#define BIT_FS_TX_NULL0_INT_EN_8822B BIT(13)
+#define BIT_FS_TSF_BIT32_TOGGLE_EN_8822B BIT(12)
+#define BIT_FS_P2P_RFON2_INT_EN_8822B BIT(11)
+#define BIT_FS_P2P_RFOFF2_INT_EN_8822B BIT(10)
+#define BIT_FS_P2P_RFON1_INT_EN_8822B BIT(9)
+#define BIT_FS_P2P_RFOFF1_INT_EN_8822B BIT(8)
+#define BIT_FS_P2P_RFON0_INT_EN_8822B BIT(7)
+#define BIT_FS_P2P_RFOFF0_INT_EN_8822B BIT(6)
+#define BIT_FS_RX_UAPSDMD1_EN_8822B BIT(5)
+#define BIT_FS_RX_UAPSDMD0_EN_8822B BIT(4)
+#define BIT_FS_TRIGGER_PKT_EN_8822B BIT(3)
+#define BIT_FS_EOSP_INT_EN_8822B BIT(2)
+#define BIT_FS_RPWM2_INT_EN_8822B BIT(1)
+#define BIT_FS_RPWM_INT_EN_8822B BIT(0)
+
+/* 2 REG_FT1ISR_8822B */
+#define BIT__FT2ISR__IND_INT_8822B BIT(30)
+#define BIT_FTM_PTT_INT_8822B BIT(29)
+#define BIT_RXFTMREQ_INT_8822B BIT(28)
+#define BIT_RXFTM_INT_8822B BIT(27)
+#define BIT_TXFTM_INT_8822B BIT(26)
+#define BIT_FS_H2C_CMD_OK_INT_8822B BIT(25)
+#define BIT_FS_H2C_CMD_FULL_INT_8822B BIT(24)
+#define BIT_FS_MACID_PWRCHANGE5_INT_8822B BIT(23)
+#define BIT_FS_MACID_PWRCHANGE4_INT_8822B BIT(22)
+#define BIT_FS_MACID_PWRCHANGE3_INT_8822B BIT(21)
+#define BIT_FS_MACID_PWRCHANGE2_INT_8822B BIT(20)
+#define BIT_FS_MACID_PWRCHANGE1_INT_8822B BIT(19)
+#define BIT_FS_MACID_PWRCHANGE0_INT_8822B BIT(18)
+#define BIT_FS_CTWEND2_INT_8822B BIT(17)
+#define BIT_FS_CTWEND1_INT_8822B BIT(16)
+#define BIT_FS_CTWEND0_INT_8822B BIT(15)
+#define BIT_FS_TX_NULL1_INT_8822B BIT(14)
+#define BIT_FS_TX_NULL0_INT_8822B BIT(13)
+#define BIT_FS_TSF_BIT32_TOGGLE_INT_8822B BIT(12)
+#define BIT_FS_P2P_RFON2_INT_8822B BIT(11)
+#define BIT_FS_P2P_RFOFF2_INT_8822B BIT(10)
+#define BIT_FS_P2P_RFON1_INT_8822B BIT(9)
+#define BIT_FS_P2P_RFOFF1_INT_8822B BIT(8)
+#define BIT_FS_P2P_RFON0_INT_8822B BIT(7)
+#define BIT_FS_P2P_RFOFF0_INT_8822B BIT(6)
+#define BIT_FS_RX_UAPSDMD1_INT_8822B BIT(5)
+#define BIT_FS_RX_UAPSDMD0_INT_8822B BIT(4)
+#define BIT_FS_TRIGGER_PKT_INT_8822B BIT(3)
+#define BIT_FS_EOSP_INT_8822B BIT(2)
+#define BIT_FS_RPWM2_INT_8822B BIT(1)
+#define BIT_FS_RPWM_INT_8822B BIT(0)
+
+/* 2 REG_SPWR0_8822B */
+
+#define BIT_SHIFT_MID_31TO0_8822B 0
+#define BIT_MASK_MID_31TO0_8822B 0xffffffffL
+#define BIT_MID_31TO0_8822B(x) \
+ (((x) & BIT_MASK_MID_31TO0_8822B) << BIT_SHIFT_MID_31TO0_8822B)
+#define BIT_GET_MID_31TO0_8822B(x) \
+ (((x) >> BIT_SHIFT_MID_31TO0_8822B) & BIT_MASK_MID_31TO0_8822B)
+
+/* 2 REG_SPWR1_8822B */
+
+#define BIT_SHIFT_MID_63TO32_8822B 0
+#define BIT_MASK_MID_63TO32_8822B 0xffffffffL
+#define BIT_MID_63TO32_8822B(x) \
+ (((x) & BIT_MASK_MID_63TO32_8822B) << BIT_SHIFT_MID_63TO32_8822B)
+#define BIT_GET_MID_63TO32_8822B(x) \
+ (((x) >> BIT_SHIFT_MID_63TO32_8822B) & BIT_MASK_MID_63TO32_8822B)
+
+/* 2 REG_SPWR2_8822B */
+
+#define BIT_SHIFT_MID_95O64_8822B 0
+#define BIT_MASK_MID_95O64_8822B 0xffffffffL
+#define BIT_MID_95O64_8822B(x) \
+ (((x) & BIT_MASK_MID_95O64_8822B) << BIT_SHIFT_MID_95O64_8822B)
+#define BIT_GET_MID_95O64_8822B(x) \
+ (((x) >> BIT_SHIFT_MID_95O64_8822B) & BIT_MASK_MID_95O64_8822B)
+
+/* 2 REG_SPWR3_8822B */
+
+#define BIT_SHIFT_MID_127TO96_8822B 0
+#define BIT_MASK_MID_127TO96_8822B 0xffffffffL
+#define BIT_MID_127TO96_8822B(x) \
+ (((x) & BIT_MASK_MID_127TO96_8822B) << BIT_SHIFT_MID_127TO96_8822B)
+#define BIT_GET_MID_127TO96_8822B(x) \
+ (((x) >> BIT_SHIFT_MID_127TO96_8822B) & BIT_MASK_MID_127TO96_8822B)
+
+/* 2 REG_POWSEQ_8822B */
+
+#define BIT_SHIFT_SEQNUM_MID_8822B 16
+#define BIT_MASK_SEQNUM_MID_8822B 0xffff
+#define BIT_SEQNUM_MID_8822B(x) \
+ (((x) & BIT_MASK_SEQNUM_MID_8822B) << BIT_SHIFT_SEQNUM_MID_8822B)
+#define BIT_GET_SEQNUM_MID_8822B(x) \
+ (((x) >> BIT_SHIFT_SEQNUM_MID_8822B) & BIT_MASK_SEQNUM_MID_8822B)
+
+#define BIT_SHIFT_REF_MID_8822B 0
+#define BIT_MASK_REF_MID_8822B 0x7f
+#define BIT_REF_MID_8822B(x) \
+ (((x) & BIT_MASK_REF_MID_8822B) << BIT_SHIFT_REF_MID_8822B)
+#define BIT_GET_REF_MID_8822B(x) \
+ (((x) >> BIT_SHIFT_REF_MID_8822B) & BIT_MASK_REF_MID_8822B)
+
+/* 2 REG_TC7_CTRL_V1_8822B */
+#define BIT_TC7INT_EN_8822B BIT(26)
+#define BIT_TC7MODE_8822B BIT(25)
+#define BIT_TC7EN_8822B BIT(24)
+
+#define BIT_SHIFT_TC7DATA_8822B 0
+#define BIT_MASK_TC7DATA_8822B 0xffffff
+#define BIT_TC7DATA_8822B(x) \
+ (((x) & BIT_MASK_TC7DATA_8822B) << BIT_SHIFT_TC7DATA_8822B)
+#define BIT_GET_TC7DATA_8822B(x) \
+ (((x) >> BIT_SHIFT_TC7DATA_8822B) & BIT_MASK_TC7DATA_8822B)
+
+/* 2 REG_TC8_CTRL_V1_8822B */
+#define BIT_TC8INT_EN_8822B BIT(26)
+#define BIT_TC8MODE_8822B BIT(25)
+#define BIT_TC8EN_8822B BIT(24)
+
+#define BIT_SHIFT_TC8DATA_8822B 0
+#define BIT_MASK_TC8DATA_8822B 0xffffff
+#define BIT_TC8DATA_8822B(x) \
+ (((x) & BIT_MASK_TC8DATA_8822B) << BIT_SHIFT_TC8DATA_8822B)
+#define BIT_GET_TC8DATA_8822B(x) \
+ (((x) >> BIT_SHIFT_TC8DATA_8822B) & BIT_MASK_TC8DATA_8822B)
+
+/* 2 REG_FT2IMR_8822B */
+#define BIT_FS_CLI3_RX_UAPSDMD1_EN_8822B BIT(31)
+#define BIT_FS_CLI3_RX_UAPSDMD0_EN_8822B BIT(30)
+#define BIT_FS_CLI3_TRIGGER_PKT_EN_8822B BIT(29)
+#define BIT_FS_CLI3_EOSP_INT_EN_8822B BIT(28)
+#define BIT_FS_CLI2_RX_UAPSDMD1_EN_8822B BIT(27)
+#define BIT_FS_CLI2_RX_UAPSDMD0_EN_8822B BIT(26)
+#define BIT_FS_CLI2_TRIGGER_PKT_EN_8822B BIT(25)
+#define BIT_FS_CLI2_EOSP_INT_EN_8822B BIT(24)
+#define BIT_FS_CLI1_RX_UAPSDMD1_EN_8822B BIT(23)
+#define BIT_FS_CLI1_RX_UAPSDMD0_EN_8822B BIT(22)
+#define BIT_FS_CLI1_TRIGGER_PKT_EN_8822B BIT(21)
+#define BIT_FS_CLI1_EOSP_INT_EN_8822B BIT(20)
+#define BIT_FS_CLI0_RX_UAPSDMD1_EN_8822B BIT(19)
+#define BIT_FS_CLI0_RX_UAPSDMD0_EN_8822B BIT(18)
+#define BIT_FS_CLI0_TRIGGER_PKT_EN_8822B BIT(17)
+#define BIT_FS_CLI0_EOSP_INT_EN_8822B BIT(16)
+#define BIT_FS_TSF_BIT32_TOGGLE_P2P2_EN_8822B BIT(9)
+#define BIT_FS_TSF_BIT32_TOGGLE_P2P1_EN_8822B BIT(8)
+#define BIT_FS_CLI3_TX_NULL1_INT_EN_8822B BIT(7)
+#define BIT_FS_CLI3_TX_NULL0_INT_EN_8822B BIT(6)
+#define BIT_FS_CLI2_TX_NULL1_INT_EN_8822B BIT(5)
+#define BIT_FS_CLI2_TX_NULL0_INT_EN_8822B BIT(4)
+#define BIT_FS_CLI1_TX_NULL1_INT_EN_8822B BIT(3)
+#define BIT_FS_CLI1_TX_NULL0_INT_EN_8822B BIT(2)
+#define BIT_FS_CLI0_TX_NULL1_INT_EN_8822B BIT(1)
+#define BIT_FS_CLI0_TX_NULL0_INT_EN_8822B BIT(0)
+
+/* 2 REG_FT2ISR_8822B */
+#define BIT_FS_CLI3_RX_UAPSDMD1_INT_8822B BIT(31)
+#define BIT_FS_CLI3_RX_UAPSDMD0_INT_8822B BIT(30)
+#define BIT_FS_CLI3_TRIGGER_PKT_INT_8822B BIT(29)
+#define BIT_FS_CLI3_EOSP_INT_8822B BIT(28)
+#define BIT_FS_CLI2_RX_UAPSDMD1_INT_8822B BIT(27)
+#define BIT_FS_CLI2_RX_UAPSDMD0_INT_8822B BIT(26)
+#define BIT_FS_CLI2_TRIGGER_PKT_INT_8822B BIT(25)
+#define BIT_FS_CLI2_EOSP_INT_8822B BIT(24)
+#define BIT_FS_CLI1_RX_UAPSDMD1_INT_8822B BIT(23)
+#define BIT_FS_CLI1_RX_UAPSDMD0_INT_8822B BIT(22)
+#define BIT_FS_CLI1_TRIGGER_PKT_INT_8822B BIT(21)
+#define BIT_FS_CLI1_EOSP_INT_8822B BIT(20)
+#define BIT_FS_CLI0_RX_UAPSDMD1_INT_8822B BIT(19)
+#define BIT_FS_CLI0_RX_UAPSDMD0_INT_8822B BIT(18)
+#define BIT_FS_CLI0_TRIGGER_PKT_INT_8822B BIT(17)
+#define BIT_FS_CLI0_EOSP_INT_8822B BIT(16)
+#define BIT_FS_TSF_BIT32_TOGGLE_P2P2_INT_8822B BIT(9)
+#define BIT_FS_TSF_BIT32_TOGGLE_P2P1_INT_8822B BIT(8)
+#define BIT_FS_CLI3_TX_NULL1_INT_8822B BIT(7)
+#define BIT_FS_CLI3_TX_NULL0_INT_8822B BIT(6)
+#define BIT_FS_CLI2_TX_NULL1_INT_8822B BIT(5)
+#define BIT_FS_CLI2_TX_NULL0_INT_8822B BIT(4)
+#define BIT_FS_CLI1_TX_NULL1_INT_8822B BIT(3)
+#define BIT_FS_CLI1_TX_NULL0_INT_8822B BIT(2)
+#define BIT_FS_CLI0_TX_NULL1_INT_8822B BIT(1)
+#define BIT_FS_CLI0_TX_NULL0_INT_8822B BIT(0)
+
+/* 2 REG_MSG2_8822B */
+
+#define BIT_SHIFT_FW_MSG2_8822B 0
+#define BIT_MASK_FW_MSG2_8822B 0xffffffffL
+#define BIT_FW_MSG2_8822B(x) \
+ (((x) & BIT_MASK_FW_MSG2_8822B) << BIT_SHIFT_FW_MSG2_8822B)
+#define BIT_GET_FW_MSG2_8822B(x) \
+ (((x) >> BIT_SHIFT_FW_MSG2_8822B) & BIT_MASK_FW_MSG2_8822B)
+
+/* 2 REG_MSG3_8822B */
+
+#define BIT_SHIFT_FW_MSG3_8822B 0
+#define BIT_MASK_FW_MSG3_8822B 0xffffffffL
+#define BIT_FW_MSG3_8822B(x) \
+ (((x) & BIT_MASK_FW_MSG3_8822B) << BIT_SHIFT_FW_MSG3_8822B)
+#define BIT_GET_FW_MSG3_8822B(x) \
+ (((x) >> BIT_SHIFT_FW_MSG3_8822B) & BIT_MASK_FW_MSG3_8822B)
+
+/* 2 REG_MSG4_8822B */
+
+#define BIT_SHIFT_FW_MSG4_8822B 0
+#define BIT_MASK_FW_MSG4_8822B 0xffffffffL
+#define BIT_FW_MSG4_8822B(x) \
+ (((x) & BIT_MASK_FW_MSG4_8822B) << BIT_SHIFT_FW_MSG4_8822B)
+#define BIT_GET_FW_MSG4_8822B(x) \
+ (((x) >> BIT_SHIFT_FW_MSG4_8822B) & BIT_MASK_FW_MSG4_8822B)
+
+/* 2 REG_MSG5_8822B */
+
+#define BIT_SHIFT_FW_MSG5_8822B 0
+#define BIT_MASK_FW_MSG5_8822B 0xffffffffL
+#define BIT_FW_MSG5_8822B(x) \
+ (((x) & BIT_MASK_FW_MSG5_8822B) << BIT_SHIFT_FW_MSG5_8822B)
+#define BIT_GET_FW_MSG5_8822B(x) \
+ (((x) >> BIT_SHIFT_FW_MSG5_8822B) & BIT_MASK_FW_MSG5_8822B)
+
+/* 2 REG_NOT_VALID_8822B */
+
+/* 2 REG_FIFOPAGE_CTRL_1_8822B */
+
+#define BIT_SHIFT_TX_OQT_HE_FREE_SPACE_V1_8822B 16
+#define BIT_MASK_TX_OQT_HE_FREE_SPACE_V1_8822B 0xff
+#define BIT_TX_OQT_HE_FREE_SPACE_V1_8822B(x) \
+ (((x) & BIT_MASK_TX_OQT_HE_FREE_SPACE_V1_8822B) \
+ << BIT_SHIFT_TX_OQT_HE_FREE_SPACE_V1_8822B)
+#define BIT_GET_TX_OQT_HE_FREE_SPACE_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_TX_OQT_HE_FREE_SPACE_V1_8822B) & \
+ BIT_MASK_TX_OQT_HE_FREE_SPACE_V1_8822B)
+
+#define BIT_SHIFT_TX_OQT_NL_FREE_SPACE_V1_8822B 0
+#define BIT_MASK_TX_OQT_NL_FREE_SPACE_V1_8822B 0xff
+#define BIT_TX_OQT_NL_FREE_SPACE_V1_8822B(x) \
+ (((x) & BIT_MASK_TX_OQT_NL_FREE_SPACE_V1_8822B) \
+ << BIT_SHIFT_TX_OQT_NL_FREE_SPACE_V1_8822B)
+#define BIT_GET_TX_OQT_NL_FREE_SPACE_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_TX_OQT_NL_FREE_SPACE_V1_8822B) & \
+ BIT_MASK_TX_OQT_NL_FREE_SPACE_V1_8822B)
+
+/* 2 REG_FIFOPAGE_CTRL_2_8822B */
+#define BIT_BCN_VALID_1_V1_8822B BIT(31)
+
+#define BIT_SHIFT_BCN_HEAD_1_V1_8822B 16
+#define BIT_MASK_BCN_HEAD_1_V1_8822B 0xfff
+#define BIT_BCN_HEAD_1_V1_8822B(x) \
+ (((x) & BIT_MASK_BCN_HEAD_1_V1_8822B) << BIT_SHIFT_BCN_HEAD_1_V1_8822B)
+#define BIT_GET_BCN_HEAD_1_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_BCN_HEAD_1_V1_8822B) & BIT_MASK_BCN_HEAD_1_V1_8822B)
+
+#define BIT_BCN_VALID_V1_8822B BIT(15)
+
+#define BIT_SHIFT_BCN_HEAD_V1_8822B 0
+#define BIT_MASK_BCN_HEAD_V1_8822B 0xfff
+#define BIT_BCN_HEAD_V1_8822B(x) \
+ (((x) & BIT_MASK_BCN_HEAD_V1_8822B) << BIT_SHIFT_BCN_HEAD_V1_8822B)
+#define BIT_GET_BCN_HEAD_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_BCN_HEAD_V1_8822B) & BIT_MASK_BCN_HEAD_V1_8822B)
+
+/* 2 REG_AUTO_LLT_V1_8822B */
+
+#define BIT_SHIFT_MAX_TX_PKT_FOR_USB_AND_SDIO_V1_8822B 24
+#define BIT_MASK_MAX_TX_PKT_FOR_USB_AND_SDIO_V1_8822B 0xff
+#define BIT_MAX_TX_PKT_FOR_USB_AND_SDIO_V1_8822B(x) \
+ (((x) & BIT_MASK_MAX_TX_PKT_FOR_USB_AND_SDIO_V1_8822B) \
+ << BIT_SHIFT_MAX_TX_PKT_FOR_USB_AND_SDIO_V1_8822B)
+#define BIT_GET_MAX_TX_PKT_FOR_USB_AND_SDIO_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_MAX_TX_PKT_FOR_USB_AND_SDIO_V1_8822B) & \
+ BIT_MASK_MAX_TX_PKT_FOR_USB_AND_SDIO_V1_8822B)
+
+#define BIT_SHIFT_LLT_FREE_PAGE_V1_8822B 8
+#define BIT_MASK_LLT_FREE_PAGE_V1_8822B 0xffff
+#define BIT_LLT_FREE_PAGE_V1_8822B(x) \
+ (((x) & BIT_MASK_LLT_FREE_PAGE_V1_8822B) \
+ << BIT_SHIFT_LLT_FREE_PAGE_V1_8822B)
+#define BIT_GET_LLT_FREE_PAGE_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_LLT_FREE_PAGE_V1_8822B) & \
+ BIT_MASK_LLT_FREE_PAGE_V1_8822B)
+
+#define BIT_SHIFT_BLK_DESC_NUM_8822B 4
+#define BIT_MASK_BLK_DESC_NUM_8822B 0xf
+#define BIT_BLK_DESC_NUM_8822B(x) \
+ (((x) & BIT_MASK_BLK_DESC_NUM_8822B) << BIT_SHIFT_BLK_DESC_NUM_8822B)
+#define BIT_GET_BLK_DESC_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_BLK_DESC_NUM_8822B) & BIT_MASK_BLK_DESC_NUM_8822B)
+
+#define BIT_R_BCN_HEAD_SEL_8822B BIT(3)
+#define BIT_R_EN_BCN_SW_HEAD_SEL_8822B BIT(2)
+#define BIT_LLT_DBG_SEL_8822B BIT(1)
+#define BIT_AUTO_INIT_LLT_V1_8822B BIT(0)
+
+/* 2 REG_TXDMA_OFFSET_CHK_8822B */
+#define BIT_EM_CHKSUM_FIN_8822B BIT(31)
+#define BIT_EMN_PCIE_DMA_MOD_8822B BIT(30)
+#define BIT_EN_TXQUE_CLR_8822B BIT(29)
+#define BIT_EN_PCIE_FIFO_MODE_8822B BIT(28)
+
+#define BIT_SHIFT_PG_UNDER_TH_V1_8822B 16
+#define BIT_MASK_PG_UNDER_TH_V1_8822B 0xfff
+#define BIT_PG_UNDER_TH_V1_8822B(x) \
+ (((x) & BIT_MASK_PG_UNDER_TH_V1_8822B) \
+ << BIT_SHIFT_PG_UNDER_TH_V1_8822B)
+#define BIT_GET_PG_UNDER_TH_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_PG_UNDER_TH_V1_8822B) & \
+ BIT_MASK_PG_UNDER_TH_V1_8822B)
+
+#define BIT_RESTORE_H2C_ADDRESS_8822B BIT(15)
+#define BIT_SDIO_TXDESC_CHKSUM_EN_8822B BIT(13)
+#define BIT_RST_RDPTR_8822B BIT(12)
+#define BIT_RST_WRPTR_8822B BIT(11)
+#define BIT_CHK_PG_TH_EN_8822B BIT(10)
+#define BIT_DROP_DATA_EN_8822B BIT(9)
+#define BIT_CHECK_OFFSET_EN_8822B BIT(8)
+
+#define BIT_SHIFT_CHECK_OFFSET_8822B 0
+#define BIT_MASK_CHECK_OFFSET_8822B 0xff
+#define BIT_CHECK_OFFSET_8822B(x) \
+ (((x) & BIT_MASK_CHECK_OFFSET_8822B) << BIT_SHIFT_CHECK_OFFSET_8822B)
+#define BIT_GET_CHECK_OFFSET_8822B(x) \
+ (((x) >> BIT_SHIFT_CHECK_OFFSET_8822B) & BIT_MASK_CHECK_OFFSET_8822B)
+
+/* 2 REG_TXDMA_STATUS_8822B */
+#define BIT_HI_OQT_UDN_8822B BIT(17)
+#define BIT_HI_OQT_OVF_8822B BIT(16)
+#define BIT_PAYLOAD_CHKSUM_ERR_8822B BIT(15)
+#define BIT_PAYLOAD_UDN_8822B BIT(14)
+#define BIT_PAYLOAD_OVF_8822B BIT(13)
+#define BIT_DSC_CHKSUM_FAIL_8822B BIT(12)
+#define BIT_UNKNOWN_QSEL_8822B BIT(11)
+#define BIT_EP_QSEL_DIFF_8822B BIT(10)
+#define BIT_TX_OFFS_UNMATCH_8822B BIT(9)
+#define BIT_TXOQT_UDN_8822B BIT(8)
+#define BIT_TXOQT_OVF_8822B BIT(7)
+#define BIT_TXDMA_SFF_UDN_8822B BIT(6)
+#define BIT_TXDMA_SFF_OVF_8822B BIT(5)
+#define BIT_LLT_NULL_PG_8822B BIT(4)
+#define BIT_PAGE_UDN_8822B BIT(3)
+#define BIT_PAGE_OVF_8822B BIT(2)
+#define BIT_TXFF_PG_UDN_8822B BIT(1)
+#define BIT_TXFF_PG_OVF_8822B BIT(0)
+
+/* 2 REG_TX_DMA_DBG_8822B */
+
+/* 2 REG_TQPNT1_8822B */
+
+#define BIT_SHIFT_HPQ_HIGH_TH_V1_8822B 16
+#define BIT_MASK_HPQ_HIGH_TH_V1_8822B 0xfff
+#define BIT_HPQ_HIGH_TH_V1_8822B(x) \
+ (((x) & BIT_MASK_HPQ_HIGH_TH_V1_8822B) \
+ << BIT_SHIFT_HPQ_HIGH_TH_V1_8822B)
+#define BIT_GET_HPQ_HIGH_TH_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_HPQ_HIGH_TH_V1_8822B) & \
+ BIT_MASK_HPQ_HIGH_TH_V1_8822B)
+
+#define BIT_SHIFT_HPQ_LOW_TH_V1_8822B 0
+#define BIT_MASK_HPQ_LOW_TH_V1_8822B 0xfff
+#define BIT_HPQ_LOW_TH_V1_8822B(x) \
+ (((x) & BIT_MASK_HPQ_LOW_TH_V1_8822B) << BIT_SHIFT_HPQ_LOW_TH_V1_8822B)
+#define BIT_GET_HPQ_LOW_TH_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_HPQ_LOW_TH_V1_8822B) & BIT_MASK_HPQ_LOW_TH_V1_8822B)
+
+/* 2 REG_TQPNT2_8822B */
+
+#define BIT_SHIFT_NPQ_HIGH_TH_V1_8822B 16
+#define BIT_MASK_NPQ_HIGH_TH_V1_8822B 0xfff
+#define BIT_NPQ_HIGH_TH_V1_8822B(x) \
+ (((x) & BIT_MASK_NPQ_HIGH_TH_V1_8822B) \
+ << BIT_SHIFT_NPQ_HIGH_TH_V1_8822B)
+#define BIT_GET_NPQ_HIGH_TH_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_NPQ_HIGH_TH_V1_8822B) & \
+ BIT_MASK_NPQ_HIGH_TH_V1_8822B)
+
+#define BIT_SHIFT_NPQ_LOW_TH_V1_8822B 0
+#define BIT_MASK_NPQ_LOW_TH_V1_8822B 0xfff
+#define BIT_NPQ_LOW_TH_V1_8822B(x) \
+ (((x) & BIT_MASK_NPQ_LOW_TH_V1_8822B) << BIT_SHIFT_NPQ_LOW_TH_V1_8822B)
+#define BIT_GET_NPQ_LOW_TH_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_NPQ_LOW_TH_V1_8822B) & BIT_MASK_NPQ_LOW_TH_V1_8822B)
+
+/* 2 REG_TQPNT3_8822B */
+
+#define BIT_SHIFT_LPQ_HIGH_TH_V1_8822B 16
+#define BIT_MASK_LPQ_HIGH_TH_V1_8822B 0xfff
+#define BIT_LPQ_HIGH_TH_V1_8822B(x) \
+ (((x) & BIT_MASK_LPQ_HIGH_TH_V1_8822B) \
+ << BIT_SHIFT_LPQ_HIGH_TH_V1_8822B)
+#define BIT_GET_LPQ_HIGH_TH_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_LPQ_HIGH_TH_V1_8822B) & \
+ BIT_MASK_LPQ_HIGH_TH_V1_8822B)
+
+#define BIT_SHIFT_LPQ_LOW_TH_V1_8822B 0
+#define BIT_MASK_LPQ_LOW_TH_V1_8822B 0xfff
+#define BIT_LPQ_LOW_TH_V1_8822B(x) \
+ (((x) & BIT_MASK_LPQ_LOW_TH_V1_8822B) << BIT_SHIFT_LPQ_LOW_TH_V1_8822B)
+#define BIT_GET_LPQ_LOW_TH_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_LPQ_LOW_TH_V1_8822B) & BIT_MASK_LPQ_LOW_TH_V1_8822B)
+
+/* 2 REG_TQPNT4_8822B */
+
+#define BIT_SHIFT_EXQ_HIGH_TH_V1_8822B 16
+#define BIT_MASK_EXQ_HIGH_TH_V1_8822B 0xfff
+#define BIT_EXQ_HIGH_TH_V1_8822B(x) \
+ (((x) & BIT_MASK_EXQ_HIGH_TH_V1_8822B) \
+ << BIT_SHIFT_EXQ_HIGH_TH_V1_8822B)
+#define BIT_GET_EXQ_HIGH_TH_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_EXQ_HIGH_TH_V1_8822B) & \
+ BIT_MASK_EXQ_HIGH_TH_V1_8822B)
+
+#define BIT_SHIFT_EXQ_LOW_TH_V1_8822B 0
+#define BIT_MASK_EXQ_LOW_TH_V1_8822B 0xfff
+#define BIT_EXQ_LOW_TH_V1_8822B(x) \
+ (((x) & BIT_MASK_EXQ_LOW_TH_V1_8822B) << BIT_SHIFT_EXQ_LOW_TH_V1_8822B)
+#define BIT_GET_EXQ_LOW_TH_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_EXQ_LOW_TH_V1_8822B) & BIT_MASK_EXQ_LOW_TH_V1_8822B)
+
+/* 2 REG_RQPN_CTRL_1_8822B */
+
+#define BIT_SHIFT_TXPKTNUM_H_8822B 16
+#define BIT_MASK_TXPKTNUM_H_8822B 0xffff
+#define BIT_TXPKTNUM_H_8822B(x) \
+ (((x) & BIT_MASK_TXPKTNUM_H_8822B) << BIT_SHIFT_TXPKTNUM_H_8822B)
+#define BIT_GET_TXPKTNUM_H_8822B(x) \
+ (((x) >> BIT_SHIFT_TXPKTNUM_H_8822B) & BIT_MASK_TXPKTNUM_H_8822B)
+
+#define BIT_SHIFT_TXPKTNUM_V2_8822B 0
+#define BIT_MASK_TXPKTNUM_V2_8822B 0xffff
+#define BIT_TXPKTNUM_V2_8822B(x) \
+ (((x) & BIT_MASK_TXPKTNUM_V2_8822B) << BIT_SHIFT_TXPKTNUM_V2_8822B)
+#define BIT_GET_TXPKTNUM_V2_8822B(x) \
+ (((x) >> BIT_SHIFT_TXPKTNUM_V2_8822B) & BIT_MASK_TXPKTNUM_V2_8822B)
+
+/* 2 REG_RQPN_CTRL_2_8822B */
+#define BIT_LD_RQPN_8822B BIT(31)
+#define BIT_EXQ_PUBLIC_DIS_V1_8822B BIT(19)
+#define BIT_NPQ_PUBLIC_DIS_V1_8822B BIT(18)
+#define BIT_LPQ_PUBLIC_DIS_V1_8822B BIT(17)
+#define BIT_HPQ_PUBLIC_DIS_V1_8822B BIT(16)
+
+/* 2 REG_FIFOPAGE_INFO_1_8822B */
+
+#define BIT_SHIFT_HPQ_AVAL_PG_V1_8822B 16
+#define BIT_MASK_HPQ_AVAL_PG_V1_8822B 0xfff
+#define BIT_HPQ_AVAL_PG_V1_8822B(x) \
+ (((x) & BIT_MASK_HPQ_AVAL_PG_V1_8822B) \
+ << BIT_SHIFT_HPQ_AVAL_PG_V1_8822B)
+#define BIT_GET_HPQ_AVAL_PG_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_HPQ_AVAL_PG_V1_8822B) & \
+ BIT_MASK_HPQ_AVAL_PG_V1_8822B)
+
+#define BIT_SHIFT_HPQ_V1_8822B 0
+#define BIT_MASK_HPQ_V1_8822B 0xfff
+#define BIT_HPQ_V1_8822B(x) \
+ (((x) & BIT_MASK_HPQ_V1_8822B) << BIT_SHIFT_HPQ_V1_8822B)
+#define BIT_GET_HPQ_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_HPQ_V1_8822B) & BIT_MASK_HPQ_V1_8822B)
+
+/* 2 REG_FIFOPAGE_INFO_2_8822B */
+
+#define BIT_SHIFT_LPQ_AVAL_PG_V1_8822B 16
+#define BIT_MASK_LPQ_AVAL_PG_V1_8822B 0xfff
+#define BIT_LPQ_AVAL_PG_V1_8822B(x) \
+ (((x) & BIT_MASK_LPQ_AVAL_PG_V1_8822B) \
+ << BIT_SHIFT_LPQ_AVAL_PG_V1_8822B)
+#define BIT_GET_LPQ_AVAL_PG_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_LPQ_AVAL_PG_V1_8822B) & \
+ BIT_MASK_LPQ_AVAL_PG_V1_8822B)
+
+#define BIT_SHIFT_LPQ_V1_8822B 0
+#define BIT_MASK_LPQ_V1_8822B 0xfff
+#define BIT_LPQ_V1_8822B(x) \
+ (((x) & BIT_MASK_LPQ_V1_8822B) << BIT_SHIFT_LPQ_V1_8822B)
+#define BIT_GET_LPQ_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_LPQ_V1_8822B) & BIT_MASK_LPQ_V1_8822B)
+
+/* 2 REG_FIFOPAGE_INFO_3_8822B */
+
+#define BIT_SHIFT_NPQ_AVAL_PG_V1_8822B 16
+#define BIT_MASK_NPQ_AVAL_PG_V1_8822B 0xfff
+#define BIT_NPQ_AVAL_PG_V1_8822B(x) \
+ (((x) & BIT_MASK_NPQ_AVAL_PG_V1_8822B) \
+ << BIT_SHIFT_NPQ_AVAL_PG_V1_8822B)
+#define BIT_GET_NPQ_AVAL_PG_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_NPQ_AVAL_PG_V1_8822B) & \
+ BIT_MASK_NPQ_AVAL_PG_V1_8822B)
+
+#define BIT_SHIFT_NPQ_V1_8822B 0
+#define BIT_MASK_NPQ_V1_8822B 0xfff
+#define BIT_NPQ_V1_8822B(x) \
+ (((x) & BIT_MASK_NPQ_V1_8822B) << BIT_SHIFT_NPQ_V1_8822B)
+#define BIT_GET_NPQ_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_NPQ_V1_8822B) & BIT_MASK_NPQ_V1_8822B)
+
+/* 2 REG_FIFOPAGE_INFO_4_8822B */
+
+#define BIT_SHIFT_EXQ_AVAL_PG_V1_8822B 16
+#define BIT_MASK_EXQ_AVAL_PG_V1_8822B 0xfff
+#define BIT_EXQ_AVAL_PG_V1_8822B(x) \
+ (((x) & BIT_MASK_EXQ_AVAL_PG_V1_8822B) \
+ << BIT_SHIFT_EXQ_AVAL_PG_V1_8822B)
+#define BIT_GET_EXQ_AVAL_PG_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_EXQ_AVAL_PG_V1_8822B) & \
+ BIT_MASK_EXQ_AVAL_PG_V1_8822B)
+
+#define BIT_SHIFT_EXQ_V1_8822B 0
+#define BIT_MASK_EXQ_V1_8822B 0xfff
+#define BIT_EXQ_V1_8822B(x) \
+ (((x) & BIT_MASK_EXQ_V1_8822B) << BIT_SHIFT_EXQ_V1_8822B)
+#define BIT_GET_EXQ_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_EXQ_V1_8822B) & BIT_MASK_EXQ_V1_8822B)
+
+/* 2 REG_FIFOPAGE_INFO_5_8822B */
+
+#define BIT_SHIFT_PUBQ_AVAL_PG_V1_8822B 16
+#define BIT_MASK_PUBQ_AVAL_PG_V1_8822B 0xfff
+#define BIT_PUBQ_AVAL_PG_V1_8822B(x) \
+ (((x) & BIT_MASK_PUBQ_AVAL_PG_V1_8822B) \
+ << BIT_SHIFT_PUBQ_AVAL_PG_V1_8822B)
+#define BIT_GET_PUBQ_AVAL_PG_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_PUBQ_AVAL_PG_V1_8822B) & \
+ BIT_MASK_PUBQ_AVAL_PG_V1_8822B)
+
+#define BIT_SHIFT_PUBQ_V1_8822B 0
+#define BIT_MASK_PUBQ_V1_8822B 0xfff
+#define BIT_PUBQ_V1_8822B(x) \
+ (((x) & BIT_MASK_PUBQ_V1_8822B) << BIT_SHIFT_PUBQ_V1_8822B)
+#define BIT_GET_PUBQ_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_PUBQ_V1_8822B) & BIT_MASK_PUBQ_V1_8822B)
+
+/* 2 REG_H2C_HEAD_8822B */
+
+#define BIT_SHIFT_H2C_HEAD_8822B 0
+#define BIT_MASK_H2C_HEAD_8822B 0x3ffff
+#define BIT_H2C_HEAD_8822B(x) \
+ (((x) & BIT_MASK_H2C_HEAD_8822B) << BIT_SHIFT_H2C_HEAD_8822B)
+#define BIT_GET_H2C_HEAD_8822B(x) \
+ (((x) >> BIT_SHIFT_H2C_HEAD_8822B) & BIT_MASK_H2C_HEAD_8822B)
+
+/* 2 REG_H2C_TAIL_8822B */
+
+#define BIT_SHIFT_H2C_TAIL_8822B 0
+#define BIT_MASK_H2C_TAIL_8822B 0x3ffff
+#define BIT_H2C_TAIL_8822B(x) \
+ (((x) & BIT_MASK_H2C_TAIL_8822B) << BIT_SHIFT_H2C_TAIL_8822B)
+#define BIT_GET_H2C_TAIL_8822B(x) \
+ (((x) >> BIT_SHIFT_H2C_TAIL_8822B) & BIT_MASK_H2C_TAIL_8822B)
+
+/* 2 REG_H2C_READ_ADDR_8822B */
+
+#define BIT_SHIFT_H2C_READ_ADDR_8822B 0
+#define BIT_MASK_H2C_READ_ADDR_8822B 0x3ffff
+#define BIT_H2C_READ_ADDR_8822B(x) \
+ (((x) & BIT_MASK_H2C_READ_ADDR_8822B) << BIT_SHIFT_H2C_READ_ADDR_8822B)
+#define BIT_GET_H2C_READ_ADDR_8822B(x) \
+ (((x) >> BIT_SHIFT_H2C_READ_ADDR_8822B) & BIT_MASK_H2C_READ_ADDR_8822B)
+
+/* 2 REG_H2C_WR_ADDR_8822B */
+
+#define BIT_SHIFT_H2C_WR_ADDR_8822B 0
+#define BIT_MASK_H2C_WR_ADDR_8822B 0x3ffff
+#define BIT_H2C_WR_ADDR_8822B(x) \
+ (((x) & BIT_MASK_H2C_WR_ADDR_8822B) << BIT_SHIFT_H2C_WR_ADDR_8822B)
+#define BIT_GET_H2C_WR_ADDR_8822B(x) \
+ (((x) >> BIT_SHIFT_H2C_WR_ADDR_8822B) & BIT_MASK_H2C_WR_ADDR_8822B)
+
+/* 2 REG_H2C_INFO_8822B */
+#define BIT_H2C_SPACE_VLD_8822B BIT(3)
+#define BIT_H2C_WR_ADDR_RST_8822B BIT(2)
+
+#define BIT_SHIFT_H2C_LEN_SEL_8822B 0
+#define BIT_MASK_H2C_LEN_SEL_8822B 0x3
+#define BIT_H2C_LEN_SEL_8822B(x) \
+ (((x) & BIT_MASK_H2C_LEN_SEL_8822B) << BIT_SHIFT_H2C_LEN_SEL_8822B)
+#define BIT_GET_H2C_LEN_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_H2C_LEN_SEL_8822B) & BIT_MASK_H2C_LEN_SEL_8822B)
+
+/* 2 REG_RXDMA_AGG_PG_TH_8822B */
+
+#define BIT_SHIFT_RXDMA_AGG_OLD_MOD_8822B 24
+#define BIT_MASK_RXDMA_AGG_OLD_MOD_8822B 0xff
+#define BIT_RXDMA_AGG_OLD_MOD_8822B(x) \
+ (((x) & BIT_MASK_RXDMA_AGG_OLD_MOD_8822B) \
+ << BIT_SHIFT_RXDMA_AGG_OLD_MOD_8822B)
+#define BIT_GET_RXDMA_AGG_OLD_MOD_8822B(x) \
+ (((x) >> BIT_SHIFT_RXDMA_AGG_OLD_MOD_8822B) & \
+ BIT_MASK_RXDMA_AGG_OLD_MOD_8822B)
+
+#define BIT_SHIFT_PKT_NUM_WOL_8822B 16
+#define BIT_MASK_PKT_NUM_WOL_8822B 0xff
+#define BIT_PKT_NUM_WOL_8822B(x) \
+ (((x) & BIT_MASK_PKT_NUM_WOL_8822B) << BIT_SHIFT_PKT_NUM_WOL_8822B)
+#define BIT_GET_PKT_NUM_WOL_8822B(x) \
+ (((x) >> BIT_SHIFT_PKT_NUM_WOL_8822B) & BIT_MASK_PKT_NUM_WOL_8822B)
+
+#define BIT_SHIFT_DMA_AGG_TO_8822B 8
+#define BIT_MASK_DMA_AGG_TO_8822B 0xf
+#define BIT_DMA_AGG_TO_8822B(x) \
+ (((x) & BIT_MASK_DMA_AGG_TO_8822B) << BIT_SHIFT_DMA_AGG_TO_8822B)
+#define BIT_GET_DMA_AGG_TO_8822B(x) \
+ (((x) >> BIT_SHIFT_DMA_AGG_TO_8822B) & BIT_MASK_DMA_AGG_TO_8822B)
+
+#define BIT_SHIFT_RXDMA_AGG_PG_TH_V1_8822B 0
+#define BIT_MASK_RXDMA_AGG_PG_TH_V1_8822B 0xf
+#define BIT_RXDMA_AGG_PG_TH_V1_8822B(x) \
+ (((x) & BIT_MASK_RXDMA_AGG_PG_TH_V1_8822B) \
+ << BIT_SHIFT_RXDMA_AGG_PG_TH_V1_8822B)
+#define BIT_GET_RXDMA_AGG_PG_TH_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_RXDMA_AGG_PG_TH_V1_8822B) & \
+ BIT_MASK_RXDMA_AGG_PG_TH_V1_8822B)
+
+/* 2 REG_RXPKT_NUM_8822B */
+
+#define BIT_SHIFT_RXPKT_NUM_8822B 24
+#define BIT_MASK_RXPKT_NUM_8822B 0xff
+#define BIT_RXPKT_NUM_8822B(x) \
+ (((x) & BIT_MASK_RXPKT_NUM_8822B) << BIT_SHIFT_RXPKT_NUM_8822B)
+#define BIT_GET_RXPKT_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_RXPKT_NUM_8822B) & BIT_MASK_RXPKT_NUM_8822B)
+
+#define BIT_SHIFT_FW_UPD_RDPTR19_TO_16_8822B 20
+#define BIT_MASK_FW_UPD_RDPTR19_TO_16_8822B 0xf
+#define BIT_FW_UPD_RDPTR19_TO_16_8822B(x) \
+ (((x) & BIT_MASK_FW_UPD_RDPTR19_TO_16_8822B) \
+ << BIT_SHIFT_FW_UPD_RDPTR19_TO_16_8822B)
+#define BIT_GET_FW_UPD_RDPTR19_TO_16_8822B(x) \
+ (((x) >> BIT_SHIFT_FW_UPD_RDPTR19_TO_16_8822B) & \
+ BIT_MASK_FW_UPD_RDPTR19_TO_16_8822B)
+
+#define BIT_RXDMA_REQ_8822B BIT(19)
+#define BIT_RW_RELEASE_EN_8822B BIT(18)
+#define BIT_RXDMA_IDLE_8822B BIT(17)
+#define BIT_RXPKT_RELEASE_POLL_8822B BIT(16)
+
+#define BIT_SHIFT_FW_UPD_RDPTR_8822B 0
+#define BIT_MASK_FW_UPD_RDPTR_8822B 0xffff
+#define BIT_FW_UPD_RDPTR_8822B(x) \
+ (((x) & BIT_MASK_FW_UPD_RDPTR_8822B) << BIT_SHIFT_FW_UPD_RDPTR_8822B)
+#define BIT_GET_FW_UPD_RDPTR_8822B(x) \
+ (((x) >> BIT_SHIFT_FW_UPD_RDPTR_8822B) & BIT_MASK_FW_UPD_RDPTR_8822B)
+
+/* 2 REG_RXDMA_STATUS_8822B */
+#define BIT_C2H_PKT_OVF_8822B BIT(7)
+#define BIT_AGG_CONFGI_ISSUE_8822B BIT(6)
+#define BIT_FW_POLL_ISSUE_8822B BIT(5)
+#define BIT_RX_DATA_UDN_8822B BIT(4)
+#define BIT_RX_SFF_UDN_8822B BIT(3)
+#define BIT_RX_SFF_OVF_8822B BIT(2)
+#define BIT_RXPKT_OVF_8822B BIT(0)
+
+/* 2 REG_RXDMA_DPR_8822B */
+
+#define BIT_SHIFT_RDE_DEBUG_8822B 0
+#define BIT_MASK_RDE_DEBUG_8822B 0xffffffffL
+#define BIT_RDE_DEBUG_8822B(x) \
+ (((x) & BIT_MASK_RDE_DEBUG_8822B) << BIT_SHIFT_RDE_DEBUG_8822B)
+#define BIT_GET_RDE_DEBUG_8822B(x) \
+ (((x) >> BIT_SHIFT_RDE_DEBUG_8822B) & BIT_MASK_RDE_DEBUG_8822B)
+
+/* 2 REG_RXDMA_MODE_8822B */
+
+#define BIT_SHIFT_PKTNUM_TH_V2_8822B 24
+#define BIT_MASK_PKTNUM_TH_V2_8822B 0x1f
+#define BIT_PKTNUM_TH_V2_8822B(x) \
+ (((x) & BIT_MASK_PKTNUM_TH_V2_8822B) << BIT_SHIFT_PKTNUM_TH_V2_8822B)
+#define BIT_GET_PKTNUM_TH_V2_8822B(x) \
+ (((x) >> BIT_SHIFT_PKTNUM_TH_V2_8822B) & BIT_MASK_PKTNUM_TH_V2_8822B)
+
+#define BIT_TXBA_BREAK_USBAGG_8822B BIT(23)
+
+#define BIT_SHIFT_PKTLEN_PARA_8822B 16
+#define BIT_MASK_PKTLEN_PARA_8822B 0x7
+#define BIT_PKTLEN_PARA_8822B(x) \
+ (((x) & BIT_MASK_PKTLEN_PARA_8822B) << BIT_SHIFT_PKTLEN_PARA_8822B)
+#define BIT_GET_PKTLEN_PARA_8822B(x) \
+ (((x) >> BIT_SHIFT_PKTLEN_PARA_8822B) & BIT_MASK_PKTLEN_PARA_8822B)
+
+/* 2 REG_NOT_VALID_8822B */
+
+/* 2 REG_NOT_VALID_8822B */
+
+/* 2 REG_NOT_VALID_8822B */
+
+#define BIT_SHIFT_BURST_SIZE_8822B 4
+#define BIT_MASK_BURST_SIZE_8822B 0x3
+#define BIT_BURST_SIZE_8822B(x) \
+ (((x) & BIT_MASK_BURST_SIZE_8822B) << BIT_SHIFT_BURST_SIZE_8822B)
+#define BIT_GET_BURST_SIZE_8822B(x) \
+ (((x) >> BIT_SHIFT_BURST_SIZE_8822B) & BIT_MASK_BURST_SIZE_8822B)
+
+#define BIT_SHIFT_BURST_CNT_8822B 2
+#define BIT_MASK_BURST_CNT_8822B 0x3
+#define BIT_BURST_CNT_8822B(x) \
+ (((x) & BIT_MASK_BURST_CNT_8822B) << BIT_SHIFT_BURST_CNT_8822B)
+#define BIT_GET_BURST_CNT_8822B(x) \
+ (((x) >> BIT_SHIFT_BURST_CNT_8822B) & BIT_MASK_BURST_CNT_8822B)
+
+#define BIT_DMA_MODE_8822B BIT(1)
+
+/* 2 REG_C2H_PKT_8822B */
+
+#define BIT_SHIFT_R_C2H_STR_ADDR_16_TO_19_8822B 24
+#define BIT_MASK_R_C2H_STR_ADDR_16_TO_19_8822B 0xf
+#define BIT_R_C2H_STR_ADDR_16_TO_19_8822B(x) \
+ (((x) & BIT_MASK_R_C2H_STR_ADDR_16_TO_19_8822B) \
+ << BIT_SHIFT_R_C2H_STR_ADDR_16_TO_19_8822B)
+#define BIT_GET_R_C2H_STR_ADDR_16_TO_19_8822B(x) \
+ (((x) >> BIT_SHIFT_R_C2H_STR_ADDR_16_TO_19_8822B) & \
+ BIT_MASK_R_C2H_STR_ADDR_16_TO_19_8822B)
+
+#define BIT_R_C2H_PKT_REQ_8822B BIT(16)
+
+#define BIT_SHIFT_R_C2H_STR_ADDR_8822B 0
+#define BIT_MASK_R_C2H_STR_ADDR_8822B 0xffff
+#define BIT_R_C2H_STR_ADDR_8822B(x) \
+ (((x) & BIT_MASK_R_C2H_STR_ADDR_8822B) \
+ << BIT_SHIFT_R_C2H_STR_ADDR_8822B)
+#define BIT_GET_R_C2H_STR_ADDR_8822B(x) \
+ (((x) >> BIT_SHIFT_R_C2H_STR_ADDR_8822B) & \
+ BIT_MASK_R_C2H_STR_ADDR_8822B)
+
+/* 2 REG_FWFF_C2H_8822B */
+
+#define BIT_SHIFT_C2H_DMA_ADDR_8822B 0
+#define BIT_MASK_C2H_DMA_ADDR_8822B 0x3ffff
+#define BIT_C2H_DMA_ADDR_8822B(x) \
+ (((x) & BIT_MASK_C2H_DMA_ADDR_8822B) << BIT_SHIFT_C2H_DMA_ADDR_8822B)
+#define BIT_GET_C2H_DMA_ADDR_8822B(x) \
+ (((x) >> BIT_SHIFT_C2H_DMA_ADDR_8822B) & BIT_MASK_C2H_DMA_ADDR_8822B)
+
+/* 2 REG_FWFF_CTRL_8822B */
+#define BIT_FWFF_DMAPKT_REQ_8822B BIT(31)
+
+#define BIT_SHIFT_FWFF_DMA_PKT_NUM_8822B 16
+#define BIT_MASK_FWFF_DMA_PKT_NUM_8822B 0xff
+#define BIT_FWFF_DMA_PKT_NUM_8822B(x) \
+ (((x) & BIT_MASK_FWFF_DMA_PKT_NUM_8822B) \
+ << BIT_SHIFT_FWFF_DMA_PKT_NUM_8822B)
+#define BIT_GET_FWFF_DMA_PKT_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_FWFF_DMA_PKT_NUM_8822B) & \
+ BIT_MASK_FWFF_DMA_PKT_NUM_8822B)
+
+#define BIT_SHIFT_FWFF_STR_ADDR_8822B 0
+#define BIT_MASK_FWFF_STR_ADDR_8822B 0xffff
+#define BIT_FWFF_STR_ADDR_8822B(x) \
+ (((x) & BIT_MASK_FWFF_STR_ADDR_8822B) << BIT_SHIFT_FWFF_STR_ADDR_8822B)
+#define BIT_GET_FWFF_STR_ADDR_8822B(x) \
+ (((x) >> BIT_SHIFT_FWFF_STR_ADDR_8822B) & BIT_MASK_FWFF_STR_ADDR_8822B)
+
+/* 2 REG_FWFF_PKT_INFO_8822B */
+
+#define BIT_SHIFT_FWFF_PKT_QUEUED_8822B 16
+#define BIT_MASK_FWFF_PKT_QUEUED_8822B 0xff
+#define BIT_FWFF_PKT_QUEUED_8822B(x) \
+ (((x) & BIT_MASK_FWFF_PKT_QUEUED_8822B) \
+ << BIT_SHIFT_FWFF_PKT_QUEUED_8822B)
+#define BIT_GET_FWFF_PKT_QUEUED_8822B(x) \
+ (((x) >> BIT_SHIFT_FWFF_PKT_QUEUED_8822B) & \
+ BIT_MASK_FWFF_PKT_QUEUED_8822B)
+
+#define BIT_SHIFT_FWFF_PKT_STR_ADDR_8822B 0
+#define BIT_MASK_FWFF_PKT_STR_ADDR_8822B 0xffff
+#define BIT_FWFF_PKT_STR_ADDR_8822B(x) \
+ (((x) & BIT_MASK_FWFF_PKT_STR_ADDR_8822B) \
+ << BIT_SHIFT_FWFF_PKT_STR_ADDR_8822B)
+#define BIT_GET_FWFF_PKT_STR_ADDR_8822B(x) \
+ (((x) >> BIT_SHIFT_FWFF_PKT_STR_ADDR_8822B) & \
+ BIT_MASK_FWFF_PKT_STR_ADDR_8822B)
+
+/* 2 REG_NOT_VALID_8822B */
+
+/* 2 REG_DDMA_CH0SA_8822B */
+
+#define BIT_SHIFT_DDMACH0_SA_8822B 0
+#define BIT_MASK_DDMACH0_SA_8822B 0xffffffffL
+#define BIT_DDMACH0_SA_8822B(x) \
+ (((x) & BIT_MASK_DDMACH0_SA_8822B) << BIT_SHIFT_DDMACH0_SA_8822B)
+#define BIT_GET_DDMACH0_SA_8822B(x) \
+ (((x) >> BIT_SHIFT_DDMACH0_SA_8822B) & BIT_MASK_DDMACH0_SA_8822B)
+
+/* 2 REG_DDMA_CH0DA_8822B */
+
+#define BIT_SHIFT_DDMACH0_DA_8822B 0
+#define BIT_MASK_DDMACH0_DA_8822B 0xffffffffL
+#define BIT_DDMACH0_DA_8822B(x) \
+ (((x) & BIT_MASK_DDMACH0_DA_8822B) << BIT_SHIFT_DDMACH0_DA_8822B)
+#define BIT_GET_DDMACH0_DA_8822B(x) \
+ (((x) >> BIT_SHIFT_DDMACH0_DA_8822B) & BIT_MASK_DDMACH0_DA_8822B)
+
+/* 2 REG_DDMA_CH0CTRL_8822B */
+#define BIT_DDMACH0_OWN_8822B BIT(31)
+#define BIT_DDMACH0_CHKSUM_EN_8822B BIT(29)
+#define BIT_DDMACH0_DA_W_DISABLE_8822B BIT(28)
+#define BIT_DDMACH0_CHKSUM_STS_8822B BIT(27)
+#define BIT_DDMACH0_DDMA_MODE_8822B BIT(26)
+#define BIT_DDMACH0_RESET_CHKSUM_STS_8822B BIT(25)
+#define BIT_DDMACH0_CHKSUM_CONT_8822B BIT(24)
+
+#define BIT_SHIFT_DDMACH0_DLEN_8822B 0
+#define BIT_MASK_DDMACH0_DLEN_8822B 0x3ffff
+#define BIT_DDMACH0_DLEN_8822B(x) \
+ (((x) & BIT_MASK_DDMACH0_DLEN_8822B) << BIT_SHIFT_DDMACH0_DLEN_8822B)
+#define BIT_GET_DDMACH0_DLEN_8822B(x) \
+ (((x) >> BIT_SHIFT_DDMACH0_DLEN_8822B) & BIT_MASK_DDMACH0_DLEN_8822B)
+
+/* 2 REG_DDMA_CH1SA_8822B */
+
+#define BIT_SHIFT_DDMACH1_SA_8822B 0
+#define BIT_MASK_DDMACH1_SA_8822B 0xffffffffL
+#define BIT_DDMACH1_SA_8822B(x) \
+ (((x) & BIT_MASK_DDMACH1_SA_8822B) << BIT_SHIFT_DDMACH1_SA_8822B)
+#define BIT_GET_DDMACH1_SA_8822B(x) \
+ (((x) >> BIT_SHIFT_DDMACH1_SA_8822B) & BIT_MASK_DDMACH1_SA_8822B)
+
+/* 2 REG_DDMA_CH1DA_8822B */
+
+#define BIT_SHIFT_DDMACH1_DA_8822B 0
+#define BIT_MASK_DDMACH1_DA_8822B 0xffffffffL
+#define BIT_DDMACH1_DA_8822B(x) \
+ (((x) & BIT_MASK_DDMACH1_DA_8822B) << BIT_SHIFT_DDMACH1_DA_8822B)
+#define BIT_GET_DDMACH1_DA_8822B(x) \
+ (((x) >> BIT_SHIFT_DDMACH1_DA_8822B) & BIT_MASK_DDMACH1_DA_8822B)
+
+/* 2 REG_DDMA_CH1CTRL_8822B */
+#define BIT_DDMACH1_OWN_8822B BIT(31)
+#define BIT_DDMACH1_CHKSUM_EN_8822B BIT(29)
+#define BIT_DDMACH1_DA_W_DISABLE_8822B BIT(28)
+#define BIT_DDMACH1_CHKSUM_STS_8822B BIT(27)
+#define BIT_DDMACH1_DDMA_MODE_8822B BIT(26)
+#define BIT_DDMACH1_RESET_CHKSUM_STS_8822B BIT(25)
+#define BIT_DDMACH1_CHKSUM_CONT_8822B BIT(24)
+
+#define BIT_SHIFT_DDMACH1_DLEN_8822B 0
+#define BIT_MASK_DDMACH1_DLEN_8822B 0x3ffff
+#define BIT_DDMACH1_DLEN_8822B(x) \
+ (((x) & BIT_MASK_DDMACH1_DLEN_8822B) << BIT_SHIFT_DDMACH1_DLEN_8822B)
+#define BIT_GET_DDMACH1_DLEN_8822B(x) \
+ (((x) >> BIT_SHIFT_DDMACH1_DLEN_8822B) & BIT_MASK_DDMACH1_DLEN_8822B)
+
+/* 2 REG_DDMA_CH2SA_8822B */
+
+#define BIT_SHIFT_DDMACH2_SA_8822B 0
+#define BIT_MASK_DDMACH2_SA_8822B 0xffffffffL
+#define BIT_DDMACH2_SA_8822B(x) \
+ (((x) & BIT_MASK_DDMACH2_SA_8822B) << BIT_SHIFT_DDMACH2_SA_8822B)
+#define BIT_GET_DDMACH2_SA_8822B(x) \
+ (((x) >> BIT_SHIFT_DDMACH2_SA_8822B) & BIT_MASK_DDMACH2_SA_8822B)
+
+/* 2 REG_DDMA_CH2DA_8822B */
+
+#define BIT_SHIFT_DDMACH2_DA_8822B 0
+#define BIT_MASK_DDMACH2_DA_8822B 0xffffffffL
+#define BIT_DDMACH2_DA_8822B(x) \
+ (((x) & BIT_MASK_DDMACH2_DA_8822B) << BIT_SHIFT_DDMACH2_DA_8822B)
+#define BIT_GET_DDMACH2_DA_8822B(x) \
+ (((x) >> BIT_SHIFT_DDMACH2_DA_8822B) & BIT_MASK_DDMACH2_DA_8822B)
+
+/* 2 REG_DDMA_CH2CTRL_8822B */
+#define BIT_DDMACH2_OWN_8822B BIT(31)
+#define BIT_DDMACH2_CHKSUM_EN_8822B BIT(29)
+#define BIT_DDMACH2_DA_W_DISABLE_8822B BIT(28)
+#define BIT_DDMACH2_CHKSUM_STS_8822B BIT(27)
+#define BIT_DDMACH2_DDMA_MODE_8822B BIT(26)
+#define BIT_DDMACH2_RESET_CHKSUM_STS_8822B BIT(25)
+#define BIT_DDMACH2_CHKSUM_CONT_8822B BIT(24)
+
+#define BIT_SHIFT_DDMACH2_DLEN_8822B 0
+#define BIT_MASK_DDMACH2_DLEN_8822B 0x3ffff
+#define BIT_DDMACH2_DLEN_8822B(x) \
+ (((x) & BIT_MASK_DDMACH2_DLEN_8822B) << BIT_SHIFT_DDMACH2_DLEN_8822B)
+#define BIT_GET_DDMACH2_DLEN_8822B(x) \
+ (((x) >> BIT_SHIFT_DDMACH2_DLEN_8822B) & BIT_MASK_DDMACH2_DLEN_8822B)
+
+/* 2 REG_DDMA_CH3SA_8822B */
+
+#define BIT_SHIFT_DDMACH3_SA_8822B 0
+#define BIT_MASK_DDMACH3_SA_8822B 0xffffffffL
+#define BIT_DDMACH3_SA_8822B(x) \
+ (((x) & BIT_MASK_DDMACH3_SA_8822B) << BIT_SHIFT_DDMACH3_SA_8822B)
+#define BIT_GET_DDMACH3_SA_8822B(x) \
+ (((x) >> BIT_SHIFT_DDMACH3_SA_8822B) & BIT_MASK_DDMACH3_SA_8822B)
+
+/* 2 REG_DDMA_CH3DA_8822B */
+
+#define BIT_SHIFT_DDMACH3_DA_8822B 0
+#define BIT_MASK_DDMACH3_DA_8822B 0xffffffffL
+#define BIT_DDMACH3_DA_8822B(x) \
+ (((x) & BIT_MASK_DDMACH3_DA_8822B) << BIT_SHIFT_DDMACH3_DA_8822B)
+#define BIT_GET_DDMACH3_DA_8822B(x) \
+ (((x) >> BIT_SHIFT_DDMACH3_DA_8822B) & BIT_MASK_DDMACH3_DA_8822B)
+
+/* 2 REG_DDMA_CH3CTRL_8822B */
+#define BIT_DDMACH3_OWN_8822B BIT(31)
+#define BIT_DDMACH3_CHKSUM_EN_8822B BIT(29)
+#define BIT_DDMACH3_DA_W_DISABLE_8822B BIT(28)
+#define BIT_DDMACH3_CHKSUM_STS_8822B BIT(27)
+#define BIT_DDMACH3_DDMA_MODE_8822B BIT(26)
+#define BIT_DDMACH3_RESET_CHKSUM_STS_8822B BIT(25)
+#define BIT_DDMACH3_CHKSUM_CONT_8822B BIT(24)
+
+#define BIT_SHIFT_DDMACH3_DLEN_8822B 0
+#define BIT_MASK_DDMACH3_DLEN_8822B 0x3ffff
+#define BIT_DDMACH3_DLEN_8822B(x) \
+ (((x) & BIT_MASK_DDMACH3_DLEN_8822B) << BIT_SHIFT_DDMACH3_DLEN_8822B)
+#define BIT_GET_DDMACH3_DLEN_8822B(x) \
+ (((x) >> BIT_SHIFT_DDMACH3_DLEN_8822B) & BIT_MASK_DDMACH3_DLEN_8822B)
+
+/* 2 REG_DDMA_CH4SA_8822B */
+
+#define BIT_SHIFT_DDMACH4_SA_8822B 0
+#define BIT_MASK_DDMACH4_SA_8822B 0xffffffffL
+#define BIT_DDMACH4_SA_8822B(x) \
+ (((x) & BIT_MASK_DDMACH4_SA_8822B) << BIT_SHIFT_DDMACH4_SA_8822B)
+#define BIT_GET_DDMACH4_SA_8822B(x) \
+ (((x) >> BIT_SHIFT_DDMACH4_SA_8822B) & BIT_MASK_DDMACH4_SA_8822B)
+
+/* 2 REG_DDMA_CH4DA_8822B */
+
+#define BIT_SHIFT_DDMACH4_DA_8822B 0
+#define BIT_MASK_DDMACH4_DA_8822B 0xffffffffL
+#define BIT_DDMACH4_DA_8822B(x) \
+ (((x) & BIT_MASK_DDMACH4_DA_8822B) << BIT_SHIFT_DDMACH4_DA_8822B)
+#define BIT_GET_DDMACH4_DA_8822B(x) \
+ (((x) >> BIT_SHIFT_DDMACH4_DA_8822B) & BIT_MASK_DDMACH4_DA_8822B)
+
+/* 2 REG_DDMA_CH4CTRL_8822B */
+#define BIT_DDMACH4_OWN_8822B BIT(31)
+#define BIT_DDMACH4_CHKSUM_EN_8822B BIT(29)
+#define BIT_DDMACH4_DA_W_DISABLE_8822B BIT(28)
+#define BIT_DDMACH4_CHKSUM_STS_8822B BIT(27)
+#define BIT_DDMACH4_DDMA_MODE_8822B BIT(26)
+#define BIT_DDMACH4_RESET_CHKSUM_STS_8822B BIT(25)
+#define BIT_DDMACH4_CHKSUM_CONT_8822B BIT(24)
+
+#define BIT_SHIFT_DDMACH4_DLEN_8822B 0
+#define BIT_MASK_DDMACH4_DLEN_8822B 0x3ffff
+#define BIT_DDMACH4_DLEN_8822B(x) \
+ (((x) & BIT_MASK_DDMACH4_DLEN_8822B) << BIT_SHIFT_DDMACH4_DLEN_8822B)
+#define BIT_GET_DDMACH4_DLEN_8822B(x) \
+ (((x) >> BIT_SHIFT_DDMACH4_DLEN_8822B) & BIT_MASK_DDMACH4_DLEN_8822B)
+
+/* 2 REG_DDMA_CH5SA_8822B */
+
+#define BIT_SHIFT_DDMACH5_SA_8822B 0
+#define BIT_MASK_DDMACH5_SA_8822B 0xffffffffL
+#define BIT_DDMACH5_SA_8822B(x) \
+ (((x) & BIT_MASK_DDMACH5_SA_8822B) << BIT_SHIFT_DDMACH5_SA_8822B)
+#define BIT_GET_DDMACH5_SA_8822B(x) \
+ (((x) >> BIT_SHIFT_DDMACH5_SA_8822B) & BIT_MASK_DDMACH5_SA_8822B)
+
+/* 2 REG_DDMA_CH5DA_8822B */
+
+#define BIT_SHIFT_DDMACH5_DA_8822B 0
+#define BIT_MASK_DDMACH5_DA_8822B 0xffffffffL
+#define BIT_DDMACH5_DA_8822B(x) \
+ (((x) & BIT_MASK_DDMACH5_DA_8822B) << BIT_SHIFT_DDMACH5_DA_8822B)
+#define BIT_GET_DDMACH5_DA_8822B(x) \
+ (((x) >> BIT_SHIFT_DDMACH5_DA_8822B) & BIT_MASK_DDMACH5_DA_8822B)
+
+/* 2 REG_REG_DDMA_CH5CTRL_8822B */
+#define BIT_DDMACH5_OWN_8822B BIT(31)
+#define BIT_DDMACH5_CHKSUM_EN_8822B BIT(29)
+#define BIT_DDMACH5_DA_W_DISABLE_8822B BIT(28)
+#define BIT_DDMACH5_CHKSUM_STS_8822B BIT(27)
+#define BIT_DDMACH5_DDMA_MODE_8822B BIT(26)
+#define BIT_DDMACH5_RESET_CHKSUM_STS_8822B BIT(25)
+#define BIT_DDMACH5_CHKSUM_CONT_8822B BIT(24)
+
+#define BIT_SHIFT_DDMACH5_DLEN_8822B 0
+#define BIT_MASK_DDMACH5_DLEN_8822B 0x3ffff
+#define BIT_DDMACH5_DLEN_8822B(x) \
+ (((x) & BIT_MASK_DDMACH5_DLEN_8822B) << BIT_SHIFT_DDMACH5_DLEN_8822B)
+#define BIT_GET_DDMACH5_DLEN_8822B(x) \
+ (((x) >> BIT_SHIFT_DDMACH5_DLEN_8822B) & BIT_MASK_DDMACH5_DLEN_8822B)
+
+/* 2 REG_DDMA_INT_MSK_8822B */
+#define BIT_DDMACH5_MSK_8822B BIT(5)
+#define BIT_DDMACH4_MSK_8822B BIT(4)
+#define BIT_DDMACH3_MSK_8822B BIT(3)
+#define BIT_DDMACH2_MSK_8822B BIT(2)
+#define BIT_DDMACH1_MSK_8822B BIT(1)
+#define BIT_DDMACH0_MSK_8822B BIT(0)
+
+/* 2 REG_DDMA_CHSTATUS_8822B */
+#define BIT_DDMACH5_BUSY_8822B BIT(5)
+#define BIT_DDMACH4_BUSY_8822B BIT(4)
+#define BIT_DDMACH3_BUSY_8822B BIT(3)
+#define BIT_DDMACH2_BUSY_8822B BIT(2)
+#define BIT_DDMACH1_BUSY_8822B BIT(1)
+#define BIT_DDMACH0_BUSY_8822B BIT(0)
+
+/* 2 REG_DDMA_CHKSUM_8822B */
+
+#define BIT_SHIFT_IDDMA0_CHKSUM_8822B 0
+#define BIT_MASK_IDDMA0_CHKSUM_8822B 0xffff
+#define BIT_IDDMA0_CHKSUM_8822B(x) \
+ (((x) & BIT_MASK_IDDMA0_CHKSUM_8822B) << BIT_SHIFT_IDDMA0_CHKSUM_8822B)
+#define BIT_GET_IDDMA0_CHKSUM_8822B(x) \
+ (((x) >> BIT_SHIFT_IDDMA0_CHKSUM_8822B) & BIT_MASK_IDDMA0_CHKSUM_8822B)
+
+/* 2 REG_DDMA_MONITOR_8822B */
+#define BIT_IDDMA0_PERMU_UNDERFLOW_8822B BIT(14)
+#define BIT_IDDMA0_FIFO_UNDERFLOW_8822B BIT(13)
+#define BIT_IDDMA0_FIFO_OVERFLOW_8822B BIT(12)
+#define BIT_CH5_ERR_8822B BIT(5)
+#define BIT_CH4_ERR_8822B BIT(4)
+#define BIT_CH3_ERR_8822B BIT(3)
+#define BIT_CH2_ERR_8822B BIT(2)
+#define BIT_CH1_ERR_8822B BIT(1)
+#define BIT_CH0_ERR_8822B BIT(0)
+
+/* 2 REG_NOT_VALID_8822B */
+
+/* 2 REG_PCIE_CTRL_8822B */
+#define BIT_PCIEIO_PERSTB_SEL_8822B BIT(31)
+
+#define BIT_SHIFT_PCIE_MAX_RXDMA_8822B 28
+#define BIT_MASK_PCIE_MAX_RXDMA_8822B 0x7
+#define BIT_PCIE_MAX_RXDMA_8822B(x) \
+ (((x) & BIT_MASK_PCIE_MAX_RXDMA_8822B) \
+ << BIT_SHIFT_PCIE_MAX_RXDMA_8822B)
+#define BIT_GET_PCIE_MAX_RXDMA_8822B(x) \
+ (((x) >> BIT_SHIFT_PCIE_MAX_RXDMA_8822B) & \
+ BIT_MASK_PCIE_MAX_RXDMA_8822B)
+
+#define BIT_MULRW_8822B BIT(27)
+
+#define BIT_SHIFT_PCIE_MAX_TXDMA_8822B 24
+#define BIT_MASK_PCIE_MAX_TXDMA_8822B 0x7
+#define BIT_PCIE_MAX_TXDMA_8822B(x) \
+ (((x) & BIT_MASK_PCIE_MAX_TXDMA_8822B) \
+ << BIT_SHIFT_PCIE_MAX_TXDMA_8822B)
+#define BIT_GET_PCIE_MAX_TXDMA_8822B(x) \
+ (((x) >> BIT_SHIFT_PCIE_MAX_TXDMA_8822B) & \
+ BIT_MASK_PCIE_MAX_TXDMA_8822B)
+
+#define BIT_EN_CPL_TIMEOUT_PS_8822B BIT(22)
+#define BIT_REG_TXDMA_FAIL_PS_8822B BIT(21)
+#define BIT_PCIE_RST_TRXDMA_INTF_8822B BIT(20)
+#define BIT_EN_HWENTR_L1_8822B BIT(19)
+#define BIT_EN_ADV_CLKGATE_8822B BIT(18)
+#define BIT_PCIE_EN_SWENT_L23_8822B BIT(17)
+#define BIT_PCIE_EN_HWEXT_L1_8822B BIT(16)
+#define BIT_RX_CLOSE_EN_8822B BIT(15)
+#define BIT_STOP_BCNQ_8822B BIT(14)
+#define BIT_STOP_MGQ_8822B BIT(13)
+#define BIT_STOP_VOQ_8822B BIT(12)
+#define BIT_STOP_VIQ_8822B BIT(11)
+#define BIT_STOP_BEQ_8822B BIT(10)
+#define BIT_STOP_BKQ_8822B BIT(9)
+#define BIT_STOP_RXQ_8822B BIT(8)
+#define BIT_STOP_HI7Q_8822B BIT(7)
+#define BIT_STOP_HI6Q_8822B BIT(6)
+#define BIT_STOP_HI5Q_8822B BIT(5)
+#define BIT_STOP_HI4Q_8822B BIT(4)
+#define BIT_STOP_HI3Q_8822B BIT(3)
+#define BIT_STOP_HI2Q_8822B BIT(2)
+#define BIT_STOP_HI1Q_8822B BIT(1)
+#define BIT_STOP_HI0Q_8822B BIT(0)
+
+/* 2 REG_INT_MIG_8822B */
+
+#define BIT_SHIFT_TXTTIMER_MATCH_NUM_8822B 28
+#define BIT_MASK_TXTTIMER_MATCH_NUM_8822B 0xf
+#define BIT_TXTTIMER_MATCH_NUM_8822B(x) \
+ (((x) & BIT_MASK_TXTTIMER_MATCH_NUM_8822B) \
+ << BIT_SHIFT_TXTTIMER_MATCH_NUM_8822B)
+#define BIT_GET_TXTTIMER_MATCH_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_TXTTIMER_MATCH_NUM_8822B) & \
+ BIT_MASK_TXTTIMER_MATCH_NUM_8822B)
+
+#define BIT_SHIFT_TXPKT_NUM_MATCH_8822B 24
+#define BIT_MASK_TXPKT_NUM_MATCH_8822B 0xf
+#define BIT_TXPKT_NUM_MATCH_8822B(x) \
+ (((x) & BIT_MASK_TXPKT_NUM_MATCH_8822B) \
+ << BIT_SHIFT_TXPKT_NUM_MATCH_8822B)
+#define BIT_GET_TXPKT_NUM_MATCH_8822B(x) \
+ (((x) >> BIT_SHIFT_TXPKT_NUM_MATCH_8822B) & \
+ BIT_MASK_TXPKT_NUM_MATCH_8822B)
+
+#define BIT_SHIFT_RXTTIMER_MATCH_NUM_8822B 20
+#define BIT_MASK_RXTTIMER_MATCH_NUM_8822B 0xf
+#define BIT_RXTTIMER_MATCH_NUM_8822B(x) \
+ (((x) & BIT_MASK_RXTTIMER_MATCH_NUM_8822B) \
+ << BIT_SHIFT_RXTTIMER_MATCH_NUM_8822B)
+#define BIT_GET_RXTTIMER_MATCH_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_RXTTIMER_MATCH_NUM_8822B) & \
+ BIT_MASK_RXTTIMER_MATCH_NUM_8822B)
+
+#define BIT_SHIFT_RXPKT_NUM_MATCH_8822B 16
+#define BIT_MASK_RXPKT_NUM_MATCH_8822B 0xf
+#define BIT_RXPKT_NUM_MATCH_8822B(x) \
+ (((x) & BIT_MASK_RXPKT_NUM_MATCH_8822B) \
+ << BIT_SHIFT_RXPKT_NUM_MATCH_8822B)
+#define BIT_GET_RXPKT_NUM_MATCH_8822B(x) \
+ (((x) >> BIT_SHIFT_RXPKT_NUM_MATCH_8822B) & \
+ BIT_MASK_RXPKT_NUM_MATCH_8822B)
+
+#define BIT_SHIFT_MIGRATE_TIMER_8822B 0
+#define BIT_MASK_MIGRATE_TIMER_8822B 0xffff
+#define BIT_MIGRATE_TIMER_8822B(x) \
+ (((x) & BIT_MASK_MIGRATE_TIMER_8822B) << BIT_SHIFT_MIGRATE_TIMER_8822B)
+#define BIT_GET_MIGRATE_TIMER_8822B(x) \
+ (((x) >> BIT_SHIFT_MIGRATE_TIMER_8822B) & BIT_MASK_MIGRATE_TIMER_8822B)
+
+/* 2 REG_BCNQ_TXBD_DESA_8822B */
+
+#define BIT_SHIFT_BCNQ_TXBD_DESA_8822B 0
+#define BIT_MASK_BCNQ_TXBD_DESA_8822B 0xffffffffffffffffL
+#define BIT_BCNQ_TXBD_DESA_8822B(x) \
+ (((x) & BIT_MASK_BCNQ_TXBD_DESA_8822B) \
+ << BIT_SHIFT_BCNQ_TXBD_DESA_8822B)
+#define BIT_GET_BCNQ_TXBD_DESA_8822B(x) \
+ (((x) >> BIT_SHIFT_BCNQ_TXBD_DESA_8822B) & \
+ BIT_MASK_BCNQ_TXBD_DESA_8822B)
+
+/* 2 REG_MGQ_TXBD_DESA_8822B */
+
+#define BIT_SHIFT_MGQ_TXBD_DESA_8822B 0
+#define BIT_MASK_MGQ_TXBD_DESA_8822B 0xffffffffffffffffL
+#define BIT_MGQ_TXBD_DESA_8822B(x) \
+ (((x) & BIT_MASK_MGQ_TXBD_DESA_8822B) << BIT_SHIFT_MGQ_TXBD_DESA_8822B)
+#define BIT_GET_MGQ_TXBD_DESA_8822B(x) \
+ (((x) >> BIT_SHIFT_MGQ_TXBD_DESA_8822B) & BIT_MASK_MGQ_TXBD_DESA_8822B)
+
+/* 2 REG_VOQ_TXBD_DESA_8822B */
+
+#define BIT_SHIFT_VOQ_TXBD_DESA_8822B 0
+#define BIT_MASK_VOQ_TXBD_DESA_8822B 0xffffffffffffffffL
+#define BIT_VOQ_TXBD_DESA_8822B(x) \
+ (((x) & BIT_MASK_VOQ_TXBD_DESA_8822B) << BIT_SHIFT_VOQ_TXBD_DESA_8822B)
+#define BIT_GET_VOQ_TXBD_DESA_8822B(x) \
+ (((x) >> BIT_SHIFT_VOQ_TXBD_DESA_8822B) & BIT_MASK_VOQ_TXBD_DESA_8822B)
+
+/* 2 REG_VIQ_TXBD_DESA_8822B */
+
+#define BIT_SHIFT_VIQ_TXBD_DESA_8822B 0
+#define BIT_MASK_VIQ_TXBD_DESA_8822B 0xffffffffffffffffL
+#define BIT_VIQ_TXBD_DESA_8822B(x) \
+ (((x) & BIT_MASK_VIQ_TXBD_DESA_8822B) << BIT_SHIFT_VIQ_TXBD_DESA_8822B)
+#define BIT_GET_VIQ_TXBD_DESA_8822B(x) \
+ (((x) >> BIT_SHIFT_VIQ_TXBD_DESA_8822B) & BIT_MASK_VIQ_TXBD_DESA_8822B)
+
+/* 2 REG_BEQ_TXBD_DESA_8822B */
+
+#define BIT_SHIFT_BEQ_TXBD_DESA_8822B 0
+#define BIT_MASK_BEQ_TXBD_DESA_8822B 0xffffffffffffffffL
+#define BIT_BEQ_TXBD_DESA_8822B(x) \
+ (((x) & BIT_MASK_BEQ_TXBD_DESA_8822B) << BIT_SHIFT_BEQ_TXBD_DESA_8822B)
+#define BIT_GET_BEQ_TXBD_DESA_8822B(x) \
+ (((x) >> BIT_SHIFT_BEQ_TXBD_DESA_8822B) & BIT_MASK_BEQ_TXBD_DESA_8822B)
+
+/* 2 REG_BKQ_TXBD_DESA_8822B */
+
+#define BIT_SHIFT_BKQ_TXBD_DESA_8822B 0
+#define BIT_MASK_BKQ_TXBD_DESA_8822B 0xffffffffffffffffL
+#define BIT_BKQ_TXBD_DESA_8822B(x) \
+ (((x) & BIT_MASK_BKQ_TXBD_DESA_8822B) << BIT_SHIFT_BKQ_TXBD_DESA_8822B)
+#define BIT_GET_BKQ_TXBD_DESA_8822B(x) \
+ (((x) >> BIT_SHIFT_BKQ_TXBD_DESA_8822B) & BIT_MASK_BKQ_TXBD_DESA_8822B)
+
+/* 2 REG_RXQ_RXBD_DESA_8822B */
+
+#define BIT_SHIFT_RXQ_RXBD_DESA_8822B 0
+#define BIT_MASK_RXQ_RXBD_DESA_8822B 0xffffffffffffffffL
+#define BIT_RXQ_RXBD_DESA_8822B(x) \
+ (((x) & BIT_MASK_RXQ_RXBD_DESA_8822B) << BIT_SHIFT_RXQ_RXBD_DESA_8822B)
+#define BIT_GET_RXQ_RXBD_DESA_8822B(x) \
+ (((x) >> BIT_SHIFT_RXQ_RXBD_DESA_8822B) & BIT_MASK_RXQ_RXBD_DESA_8822B)
+
+/* 2 REG_HI0Q_TXBD_DESA_8822B */
+
+#define BIT_SHIFT_HI0Q_TXBD_DESA_8822B 0
+#define BIT_MASK_HI0Q_TXBD_DESA_8822B 0xffffffffffffffffL
+#define BIT_HI0Q_TXBD_DESA_8822B(x) \
+ (((x) & BIT_MASK_HI0Q_TXBD_DESA_8822B) \
+ << BIT_SHIFT_HI0Q_TXBD_DESA_8822B)
+#define BIT_GET_HI0Q_TXBD_DESA_8822B(x) \
+ (((x) >> BIT_SHIFT_HI0Q_TXBD_DESA_8822B) & \
+ BIT_MASK_HI0Q_TXBD_DESA_8822B)
+
+/* 2 REG_HI1Q_TXBD_DESA_8822B */
+
+#define BIT_SHIFT_HI1Q_TXBD_DESA_8822B 0
+#define BIT_MASK_HI1Q_TXBD_DESA_8822B 0xffffffffffffffffL
+#define BIT_HI1Q_TXBD_DESA_8822B(x) \
+ (((x) & BIT_MASK_HI1Q_TXBD_DESA_8822B) \
+ << BIT_SHIFT_HI1Q_TXBD_DESA_8822B)
+#define BIT_GET_HI1Q_TXBD_DESA_8822B(x) \
+ (((x) >> BIT_SHIFT_HI1Q_TXBD_DESA_8822B) & \
+ BIT_MASK_HI1Q_TXBD_DESA_8822B)
+
+/* 2 REG_HI2Q_TXBD_DESA_8822B */
+
+#define BIT_SHIFT_HI2Q_TXBD_DESA_8822B 0
+#define BIT_MASK_HI2Q_TXBD_DESA_8822B 0xffffffffffffffffL
+#define BIT_HI2Q_TXBD_DESA_8822B(x) \
+ (((x) & BIT_MASK_HI2Q_TXBD_DESA_8822B) \
+ << BIT_SHIFT_HI2Q_TXBD_DESA_8822B)
+#define BIT_GET_HI2Q_TXBD_DESA_8822B(x) \
+ (((x) >> BIT_SHIFT_HI2Q_TXBD_DESA_8822B) & \
+ BIT_MASK_HI2Q_TXBD_DESA_8822B)
+
+/* 2 REG_HI3Q_TXBD_DESA_8822B */
+
+#define BIT_SHIFT_HI3Q_TXBD_DESA_8822B 0
+#define BIT_MASK_HI3Q_TXBD_DESA_8822B 0xffffffffffffffffL
+#define BIT_HI3Q_TXBD_DESA_8822B(x) \
+ (((x) & BIT_MASK_HI3Q_TXBD_DESA_8822B) \
+ << BIT_SHIFT_HI3Q_TXBD_DESA_8822B)
+#define BIT_GET_HI3Q_TXBD_DESA_8822B(x) \
+ (((x) >> BIT_SHIFT_HI3Q_TXBD_DESA_8822B) & \
+ BIT_MASK_HI3Q_TXBD_DESA_8822B)
+
+/* 2 REG_HI4Q_TXBD_DESA_8822B */
+
+#define BIT_SHIFT_HI4Q_TXBD_DESA_8822B 0
+#define BIT_MASK_HI4Q_TXBD_DESA_8822B 0xffffffffffffffffL
+#define BIT_HI4Q_TXBD_DESA_8822B(x) \
+ (((x) & BIT_MASK_HI4Q_TXBD_DESA_8822B) \
+ << BIT_SHIFT_HI4Q_TXBD_DESA_8822B)
+#define BIT_GET_HI4Q_TXBD_DESA_8822B(x) \
+ (((x) >> BIT_SHIFT_HI4Q_TXBD_DESA_8822B) & \
+ BIT_MASK_HI4Q_TXBD_DESA_8822B)
+
+/* 2 REG_HI5Q_TXBD_DESA_8822B */
+
+#define BIT_SHIFT_HI5Q_TXBD_DESA_8822B 0
+#define BIT_MASK_HI5Q_TXBD_DESA_8822B 0xffffffffffffffffL
+#define BIT_HI5Q_TXBD_DESA_8822B(x) \
+ (((x) & BIT_MASK_HI5Q_TXBD_DESA_8822B) \
+ << BIT_SHIFT_HI5Q_TXBD_DESA_8822B)
+#define BIT_GET_HI5Q_TXBD_DESA_8822B(x) \
+ (((x) >> BIT_SHIFT_HI5Q_TXBD_DESA_8822B) & \
+ BIT_MASK_HI5Q_TXBD_DESA_8822B)
+
+/* 2 REG_HI6Q_TXBD_DESA_8822B */
+
+#define BIT_SHIFT_HI6Q_TXBD_DESA_8822B 0
+#define BIT_MASK_HI6Q_TXBD_DESA_8822B 0xffffffffffffffffL
+#define BIT_HI6Q_TXBD_DESA_8822B(x) \
+ (((x) & BIT_MASK_HI6Q_TXBD_DESA_8822B) \
+ << BIT_SHIFT_HI6Q_TXBD_DESA_8822B)
+#define BIT_GET_HI6Q_TXBD_DESA_8822B(x) \
+ (((x) >> BIT_SHIFT_HI6Q_TXBD_DESA_8822B) & \
+ BIT_MASK_HI6Q_TXBD_DESA_8822B)
+
+/* 2 REG_HI7Q_TXBD_DESA_8822B */
+
+#define BIT_SHIFT_HI7Q_TXBD_DESA_8822B 0
+#define BIT_MASK_HI7Q_TXBD_DESA_8822B 0xffffffffffffffffL
+#define BIT_HI7Q_TXBD_DESA_8822B(x) \
+ (((x) & BIT_MASK_HI7Q_TXBD_DESA_8822B) \
+ << BIT_SHIFT_HI7Q_TXBD_DESA_8822B)
+#define BIT_GET_HI7Q_TXBD_DESA_8822B(x) \
+ (((x) >> BIT_SHIFT_HI7Q_TXBD_DESA_8822B) & \
+ BIT_MASK_HI7Q_TXBD_DESA_8822B)
+
+/* 2 REG_MGQ_TXBD_NUM_8822B */
+#define BIT_PCIE_MGQ_FLAG_8822B BIT(14)
+
+#define BIT_SHIFT_MGQ_DESC_MODE_8822B 12
+#define BIT_MASK_MGQ_DESC_MODE_8822B 0x3
+#define BIT_MGQ_DESC_MODE_8822B(x) \
+ (((x) & BIT_MASK_MGQ_DESC_MODE_8822B) << BIT_SHIFT_MGQ_DESC_MODE_8822B)
+#define BIT_GET_MGQ_DESC_MODE_8822B(x) \
+ (((x) >> BIT_SHIFT_MGQ_DESC_MODE_8822B) & BIT_MASK_MGQ_DESC_MODE_8822B)
+
+#define BIT_SHIFT_MGQ_DESC_NUM_8822B 0
+#define BIT_MASK_MGQ_DESC_NUM_8822B 0xfff
+#define BIT_MGQ_DESC_NUM_8822B(x) \
+ (((x) & BIT_MASK_MGQ_DESC_NUM_8822B) << BIT_SHIFT_MGQ_DESC_NUM_8822B)
+#define BIT_GET_MGQ_DESC_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_MGQ_DESC_NUM_8822B) & BIT_MASK_MGQ_DESC_NUM_8822B)
+
+/* 2 REG_RX_RXBD_NUM_8822B */
+#define BIT_SYS_32_64_8822B BIT(15)
+
+#define BIT_SHIFT_BCNQ_DESC_MODE_8822B 13
+#define BIT_MASK_BCNQ_DESC_MODE_8822B 0x3
+#define BIT_BCNQ_DESC_MODE_8822B(x) \
+ (((x) & BIT_MASK_BCNQ_DESC_MODE_8822B) \
+ << BIT_SHIFT_BCNQ_DESC_MODE_8822B)
+#define BIT_GET_BCNQ_DESC_MODE_8822B(x) \
+ (((x) >> BIT_SHIFT_BCNQ_DESC_MODE_8822B) & \
+ BIT_MASK_BCNQ_DESC_MODE_8822B)
+
+#define BIT_PCIE_BCNQ_FLAG_8822B BIT(12)
+
+#define BIT_SHIFT_RXQ_DESC_NUM_8822B 0
+#define BIT_MASK_RXQ_DESC_NUM_8822B 0xfff
+#define BIT_RXQ_DESC_NUM_8822B(x) \
+ (((x) & BIT_MASK_RXQ_DESC_NUM_8822B) << BIT_SHIFT_RXQ_DESC_NUM_8822B)
+#define BIT_GET_RXQ_DESC_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_RXQ_DESC_NUM_8822B) & BIT_MASK_RXQ_DESC_NUM_8822B)
+
+/* 2 REG_VOQ_TXBD_NUM_8822B */
+#define BIT_PCIE_VOQ_FLAG_8822B BIT(14)
+
+#define BIT_SHIFT_VOQ_DESC_MODE_8822B 12
+#define BIT_MASK_VOQ_DESC_MODE_8822B 0x3
+#define BIT_VOQ_DESC_MODE_8822B(x) \
+ (((x) & BIT_MASK_VOQ_DESC_MODE_8822B) << BIT_SHIFT_VOQ_DESC_MODE_8822B)
+#define BIT_GET_VOQ_DESC_MODE_8822B(x) \
+ (((x) >> BIT_SHIFT_VOQ_DESC_MODE_8822B) & BIT_MASK_VOQ_DESC_MODE_8822B)
+
+#define BIT_SHIFT_VOQ_DESC_NUM_8822B 0
+#define BIT_MASK_VOQ_DESC_NUM_8822B 0xfff
+#define BIT_VOQ_DESC_NUM_8822B(x) \
+ (((x) & BIT_MASK_VOQ_DESC_NUM_8822B) << BIT_SHIFT_VOQ_DESC_NUM_8822B)
+#define BIT_GET_VOQ_DESC_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_VOQ_DESC_NUM_8822B) & BIT_MASK_VOQ_DESC_NUM_8822B)
+
+/* 2 REG_VIQ_TXBD_NUM_8822B */
+#define BIT_PCIE_VIQ_FLAG_8822B BIT(14)
+
+#define BIT_SHIFT_VIQ_DESC_MODE_8822B 12
+#define BIT_MASK_VIQ_DESC_MODE_8822B 0x3
+#define BIT_VIQ_DESC_MODE_8822B(x) \
+ (((x) & BIT_MASK_VIQ_DESC_MODE_8822B) << BIT_SHIFT_VIQ_DESC_MODE_8822B)
+#define BIT_GET_VIQ_DESC_MODE_8822B(x) \
+ (((x) >> BIT_SHIFT_VIQ_DESC_MODE_8822B) & BIT_MASK_VIQ_DESC_MODE_8822B)
+
+#define BIT_SHIFT_VIQ_DESC_NUM_8822B 0
+#define BIT_MASK_VIQ_DESC_NUM_8822B 0xfff
+#define BIT_VIQ_DESC_NUM_8822B(x) \
+ (((x) & BIT_MASK_VIQ_DESC_NUM_8822B) << BIT_SHIFT_VIQ_DESC_NUM_8822B)
+#define BIT_GET_VIQ_DESC_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_VIQ_DESC_NUM_8822B) & BIT_MASK_VIQ_DESC_NUM_8822B)
+
+/* 2 REG_BEQ_TXBD_NUM_8822B */
+#define BIT_PCIE_BEQ_FLAG_8822B BIT(14)
+
+#define BIT_SHIFT_BEQ_DESC_MODE_8822B 12
+#define BIT_MASK_BEQ_DESC_MODE_8822B 0x3
+#define BIT_BEQ_DESC_MODE_8822B(x) \
+ (((x) & BIT_MASK_BEQ_DESC_MODE_8822B) << BIT_SHIFT_BEQ_DESC_MODE_8822B)
+#define BIT_GET_BEQ_DESC_MODE_8822B(x) \
+ (((x) >> BIT_SHIFT_BEQ_DESC_MODE_8822B) & BIT_MASK_BEQ_DESC_MODE_8822B)
+
+#define BIT_SHIFT_BEQ_DESC_NUM_8822B 0
+#define BIT_MASK_BEQ_DESC_NUM_8822B 0xfff
+#define BIT_BEQ_DESC_NUM_8822B(x) \
+ (((x) & BIT_MASK_BEQ_DESC_NUM_8822B) << BIT_SHIFT_BEQ_DESC_NUM_8822B)
+#define BIT_GET_BEQ_DESC_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_BEQ_DESC_NUM_8822B) & BIT_MASK_BEQ_DESC_NUM_8822B)
+
+/* 2 REG_BKQ_TXBD_NUM_8822B */
+#define BIT_PCIE_BKQ_FLAG_8822B BIT(14)
+
+#define BIT_SHIFT_BKQ_DESC_MODE_8822B 12
+#define BIT_MASK_BKQ_DESC_MODE_8822B 0x3
+#define BIT_BKQ_DESC_MODE_8822B(x) \
+ (((x) & BIT_MASK_BKQ_DESC_MODE_8822B) << BIT_SHIFT_BKQ_DESC_MODE_8822B)
+#define BIT_GET_BKQ_DESC_MODE_8822B(x) \
+ (((x) >> BIT_SHIFT_BKQ_DESC_MODE_8822B) & BIT_MASK_BKQ_DESC_MODE_8822B)
+
+#define BIT_SHIFT_BKQ_DESC_NUM_8822B 0
+#define BIT_MASK_BKQ_DESC_NUM_8822B 0xfff
+#define BIT_BKQ_DESC_NUM_8822B(x) \
+ (((x) & BIT_MASK_BKQ_DESC_NUM_8822B) << BIT_SHIFT_BKQ_DESC_NUM_8822B)
+#define BIT_GET_BKQ_DESC_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_BKQ_DESC_NUM_8822B) & BIT_MASK_BKQ_DESC_NUM_8822B)
+
+/* 2 REG_HI0Q_TXBD_NUM_8822B */
+#define BIT_HI0Q_FLAG_8822B BIT(14)
+
+#define BIT_SHIFT_HI0Q_DESC_MODE_8822B 12
+#define BIT_MASK_HI0Q_DESC_MODE_8822B 0x3
+#define BIT_HI0Q_DESC_MODE_8822B(x) \
+ (((x) & BIT_MASK_HI0Q_DESC_MODE_8822B) \
+ << BIT_SHIFT_HI0Q_DESC_MODE_8822B)
+#define BIT_GET_HI0Q_DESC_MODE_8822B(x) \
+ (((x) >> BIT_SHIFT_HI0Q_DESC_MODE_8822B) & \
+ BIT_MASK_HI0Q_DESC_MODE_8822B)
+
+#define BIT_SHIFT_HI0Q_DESC_NUM_8822B 0
+#define BIT_MASK_HI0Q_DESC_NUM_8822B 0xfff
+#define BIT_HI0Q_DESC_NUM_8822B(x) \
+ (((x) & BIT_MASK_HI0Q_DESC_NUM_8822B) << BIT_SHIFT_HI0Q_DESC_NUM_8822B)
+#define BIT_GET_HI0Q_DESC_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_HI0Q_DESC_NUM_8822B) & BIT_MASK_HI0Q_DESC_NUM_8822B)
+
+/* 2 REG_HI1Q_TXBD_NUM_8822B */
+#define BIT_HI1Q_FLAG_8822B BIT(14)
+
+#define BIT_SHIFT_HI1Q_DESC_MODE_8822B 12
+#define BIT_MASK_HI1Q_DESC_MODE_8822B 0x3
+#define BIT_HI1Q_DESC_MODE_8822B(x) \
+ (((x) & BIT_MASK_HI1Q_DESC_MODE_8822B) \
+ << BIT_SHIFT_HI1Q_DESC_MODE_8822B)
+#define BIT_GET_HI1Q_DESC_MODE_8822B(x) \
+ (((x) >> BIT_SHIFT_HI1Q_DESC_MODE_8822B) & \
+ BIT_MASK_HI1Q_DESC_MODE_8822B)
+
+#define BIT_SHIFT_HI1Q_DESC_NUM_8822B 0
+#define BIT_MASK_HI1Q_DESC_NUM_8822B 0xfff
+#define BIT_HI1Q_DESC_NUM_8822B(x) \
+ (((x) & BIT_MASK_HI1Q_DESC_NUM_8822B) << BIT_SHIFT_HI1Q_DESC_NUM_8822B)
+#define BIT_GET_HI1Q_DESC_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_HI1Q_DESC_NUM_8822B) & BIT_MASK_HI1Q_DESC_NUM_8822B)
+
+/* 2 REG_HI2Q_TXBD_NUM_8822B */
+#define BIT_HI2Q_FLAG_8822B BIT(14)
+
+#define BIT_SHIFT_HI2Q_DESC_MODE_8822B 12
+#define BIT_MASK_HI2Q_DESC_MODE_8822B 0x3
+#define BIT_HI2Q_DESC_MODE_8822B(x) \
+ (((x) & BIT_MASK_HI2Q_DESC_MODE_8822B) \
+ << BIT_SHIFT_HI2Q_DESC_MODE_8822B)
+#define BIT_GET_HI2Q_DESC_MODE_8822B(x) \
+ (((x) >> BIT_SHIFT_HI2Q_DESC_MODE_8822B) & \
+ BIT_MASK_HI2Q_DESC_MODE_8822B)
+
+#define BIT_SHIFT_HI2Q_DESC_NUM_8822B 0
+#define BIT_MASK_HI2Q_DESC_NUM_8822B 0xfff
+#define BIT_HI2Q_DESC_NUM_8822B(x) \
+ (((x) & BIT_MASK_HI2Q_DESC_NUM_8822B) << BIT_SHIFT_HI2Q_DESC_NUM_8822B)
+#define BIT_GET_HI2Q_DESC_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_HI2Q_DESC_NUM_8822B) & BIT_MASK_HI2Q_DESC_NUM_8822B)
+
+/* 2 REG_HI3Q_TXBD_NUM_8822B */
+#define BIT_HI3Q_FLAG_8822B BIT(14)
+
+#define BIT_SHIFT_HI3Q_DESC_MODE_8822B 12
+#define BIT_MASK_HI3Q_DESC_MODE_8822B 0x3
+#define BIT_HI3Q_DESC_MODE_8822B(x) \
+ (((x) & BIT_MASK_HI3Q_DESC_MODE_8822B) \
+ << BIT_SHIFT_HI3Q_DESC_MODE_8822B)
+#define BIT_GET_HI3Q_DESC_MODE_8822B(x) \
+ (((x) >> BIT_SHIFT_HI3Q_DESC_MODE_8822B) & \
+ BIT_MASK_HI3Q_DESC_MODE_8822B)
+
+#define BIT_SHIFT_HI3Q_DESC_NUM_8822B 0
+#define BIT_MASK_HI3Q_DESC_NUM_8822B 0xfff
+#define BIT_HI3Q_DESC_NUM_8822B(x) \
+ (((x) & BIT_MASK_HI3Q_DESC_NUM_8822B) << BIT_SHIFT_HI3Q_DESC_NUM_8822B)
+#define BIT_GET_HI3Q_DESC_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_HI3Q_DESC_NUM_8822B) & BIT_MASK_HI3Q_DESC_NUM_8822B)
+
+/* 2 REG_HI4Q_TXBD_NUM_8822B */
+#define BIT_HI4Q_FLAG_8822B BIT(14)
+
+#define BIT_SHIFT_HI4Q_DESC_MODE_8822B 12
+#define BIT_MASK_HI4Q_DESC_MODE_8822B 0x3
+#define BIT_HI4Q_DESC_MODE_8822B(x) \
+ (((x) & BIT_MASK_HI4Q_DESC_MODE_8822B) \
+ << BIT_SHIFT_HI4Q_DESC_MODE_8822B)
+#define BIT_GET_HI4Q_DESC_MODE_8822B(x) \
+ (((x) >> BIT_SHIFT_HI4Q_DESC_MODE_8822B) & \
+ BIT_MASK_HI4Q_DESC_MODE_8822B)
+
+#define BIT_SHIFT_HI4Q_DESC_NUM_8822B 0
+#define BIT_MASK_HI4Q_DESC_NUM_8822B 0xfff
+#define BIT_HI4Q_DESC_NUM_8822B(x) \
+ (((x) & BIT_MASK_HI4Q_DESC_NUM_8822B) << BIT_SHIFT_HI4Q_DESC_NUM_8822B)
+#define BIT_GET_HI4Q_DESC_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_HI4Q_DESC_NUM_8822B) & BIT_MASK_HI4Q_DESC_NUM_8822B)
+
+/* 2 REG_HI5Q_TXBD_NUM_8822B */
+#define BIT_HI5Q_FLAG_8822B BIT(14)
+
+#define BIT_SHIFT_HI5Q_DESC_MODE_8822B 12
+#define BIT_MASK_HI5Q_DESC_MODE_8822B 0x3
+#define BIT_HI5Q_DESC_MODE_8822B(x) \
+ (((x) & BIT_MASK_HI5Q_DESC_MODE_8822B) \
+ << BIT_SHIFT_HI5Q_DESC_MODE_8822B)
+#define BIT_GET_HI5Q_DESC_MODE_8822B(x) \
+ (((x) >> BIT_SHIFT_HI5Q_DESC_MODE_8822B) & \
+ BIT_MASK_HI5Q_DESC_MODE_8822B)
+
+#define BIT_SHIFT_HI5Q_DESC_NUM_8822B 0
+#define BIT_MASK_HI5Q_DESC_NUM_8822B 0xfff
+#define BIT_HI5Q_DESC_NUM_8822B(x) \
+ (((x) & BIT_MASK_HI5Q_DESC_NUM_8822B) << BIT_SHIFT_HI5Q_DESC_NUM_8822B)
+#define BIT_GET_HI5Q_DESC_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_HI5Q_DESC_NUM_8822B) & BIT_MASK_HI5Q_DESC_NUM_8822B)
+
+/* 2 REG_HI6Q_TXBD_NUM_8822B */
+#define BIT_HI6Q_FLAG_8822B BIT(14)
+
+#define BIT_SHIFT_HI6Q_DESC_MODE_8822B 12
+#define BIT_MASK_HI6Q_DESC_MODE_8822B 0x3
+#define BIT_HI6Q_DESC_MODE_8822B(x) \
+ (((x) & BIT_MASK_HI6Q_DESC_MODE_8822B) \
+ << BIT_SHIFT_HI6Q_DESC_MODE_8822B)
+#define BIT_GET_HI6Q_DESC_MODE_8822B(x) \
+ (((x) >> BIT_SHIFT_HI6Q_DESC_MODE_8822B) & \
+ BIT_MASK_HI6Q_DESC_MODE_8822B)
+
+#define BIT_SHIFT_HI6Q_DESC_NUM_8822B 0
+#define BIT_MASK_HI6Q_DESC_NUM_8822B 0xfff
+#define BIT_HI6Q_DESC_NUM_8822B(x) \
+ (((x) & BIT_MASK_HI6Q_DESC_NUM_8822B) << BIT_SHIFT_HI6Q_DESC_NUM_8822B)
+#define BIT_GET_HI6Q_DESC_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_HI6Q_DESC_NUM_8822B) & BIT_MASK_HI6Q_DESC_NUM_8822B)
+
+/* 2 REG_HI7Q_TXBD_NUM_8822B */
+#define BIT_HI7Q_FLAG_8822B BIT(14)
+
+#define BIT_SHIFT_HI7Q_DESC_MODE_8822B 12
+#define BIT_MASK_HI7Q_DESC_MODE_8822B 0x3
+#define BIT_HI7Q_DESC_MODE_8822B(x) \
+ (((x) & BIT_MASK_HI7Q_DESC_MODE_8822B) \
+ << BIT_SHIFT_HI7Q_DESC_MODE_8822B)
+#define BIT_GET_HI7Q_DESC_MODE_8822B(x) \
+ (((x) >> BIT_SHIFT_HI7Q_DESC_MODE_8822B) & \
+ BIT_MASK_HI7Q_DESC_MODE_8822B)
+
+#define BIT_SHIFT_HI7Q_DESC_NUM_8822B 0
+#define BIT_MASK_HI7Q_DESC_NUM_8822B 0xfff
+#define BIT_HI7Q_DESC_NUM_8822B(x) \
+ (((x) & BIT_MASK_HI7Q_DESC_NUM_8822B) << BIT_SHIFT_HI7Q_DESC_NUM_8822B)
+#define BIT_GET_HI7Q_DESC_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_HI7Q_DESC_NUM_8822B) & BIT_MASK_HI7Q_DESC_NUM_8822B)
+
+/* 2 REG_TSFTIMER_HCI_8822B */
+
+#define BIT_SHIFT_TSFT2_HCI_8822B 16
+#define BIT_MASK_TSFT2_HCI_8822B 0xffff
+#define BIT_TSFT2_HCI_8822B(x) \
+ (((x) & BIT_MASK_TSFT2_HCI_8822B) << BIT_SHIFT_TSFT2_HCI_8822B)
+#define BIT_GET_TSFT2_HCI_8822B(x) \
+ (((x) >> BIT_SHIFT_TSFT2_HCI_8822B) & BIT_MASK_TSFT2_HCI_8822B)
+
+#define BIT_SHIFT_TSFT1_HCI_8822B 0
+#define BIT_MASK_TSFT1_HCI_8822B 0xffff
+#define BIT_TSFT1_HCI_8822B(x) \
+ (((x) & BIT_MASK_TSFT1_HCI_8822B) << BIT_SHIFT_TSFT1_HCI_8822B)
+#define BIT_GET_TSFT1_HCI_8822B(x) \
+ (((x) >> BIT_SHIFT_TSFT1_HCI_8822B) & BIT_MASK_TSFT1_HCI_8822B)
+
+/* 2 REG_BD_RWPTR_CLR_8822B */
+#define BIT_CLR_HI7Q_HW_IDX_8822B BIT(29)
+#define BIT_CLR_HI6Q_HW_IDX_8822B BIT(28)
+#define BIT_CLR_HI5Q_HW_IDX_8822B BIT(27)
+#define BIT_CLR_HI4Q_HW_IDX_8822B BIT(26)
+#define BIT_CLR_HI3Q_HW_IDX_8822B BIT(25)
+#define BIT_CLR_HI2Q_HW_IDX_8822B BIT(24)
+#define BIT_CLR_HI1Q_HW_IDX_8822B BIT(23)
+#define BIT_CLR_HI0Q_HW_IDX_8822B BIT(22)
+#define BIT_CLR_BKQ_HW_IDX_8822B BIT(21)
+#define BIT_CLR_BEQ_HW_IDX_8822B BIT(20)
+#define BIT_CLR_VIQ_HW_IDX_8822B BIT(19)
+#define BIT_CLR_VOQ_HW_IDX_8822B BIT(18)
+#define BIT_CLR_MGQ_HW_IDX_8822B BIT(17)
+#define BIT_CLR_RXQ_HW_IDX_8822B BIT(16)
+#define BIT_CLR_HI7Q_HOST_IDX_8822B BIT(13)
+#define BIT_CLR_HI6Q_HOST_IDX_8822B BIT(12)
+#define BIT_CLR_HI5Q_HOST_IDX_8822B BIT(11)
+#define BIT_CLR_HI4Q_HOST_IDX_8822B BIT(10)
+#define BIT_CLR_HI3Q_HOST_IDX_8822B BIT(9)
+#define BIT_CLR_HI2Q_HOST_IDX_8822B BIT(8)
+#define BIT_CLR_HI1Q_HOST_IDX_8822B BIT(7)
+#define BIT_CLR_HI0Q_HOST_IDX_8822B BIT(6)
+#define BIT_CLR_BKQ_HOST_IDX_8822B BIT(5)
+#define BIT_CLR_BEQ_HOST_IDX_8822B BIT(4)
+#define BIT_CLR_VIQ_HOST_IDX_8822B BIT(3)
+#define BIT_CLR_VOQ_HOST_IDX_8822B BIT(2)
+#define BIT_CLR_MGQ_HOST_IDX_8822B BIT(1)
+#define BIT_CLR_RXQ_HOST_IDX_8822B BIT(0)
+
+/* 2 REG_VOQ_TXBD_IDX_8822B */
+
+#define BIT_SHIFT_VOQ_HW_IDX_8822B 16
+#define BIT_MASK_VOQ_HW_IDX_8822B 0xfff
+#define BIT_VOQ_HW_IDX_8822B(x) \
+ (((x) & BIT_MASK_VOQ_HW_IDX_8822B) << BIT_SHIFT_VOQ_HW_IDX_8822B)
+#define BIT_GET_VOQ_HW_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_VOQ_HW_IDX_8822B) & BIT_MASK_VOQ_HW_IDX_8822B)
+
+#define BIT_SHIFT_VOQ_HOST_IDX_8822B 0
+#define BIT_MASK_VOQ_HOST_IDX_8822B 0xfff
+#define BIT_VOQ_HOST_IDX_8822B(x) \
+ (((x) & BIT_MASK_VOQ_HOST_IDX_8822B) << BIT_SHIFT_VOQ_HOST_IDX_8822B)
+#define BIT_GET_VOQ_HOST_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_VOQ_HOST_IDX_8822B) & BIT_MASK_VOQ_HOST_IDX_8822B)
+
+/* 2 REG_VIQ_TXBD_IDX_8822B */
+
+#define BIT_SHIFT_VIQ_HW_IDX_8822B 16
+#define BIT_MASK_VIQ_HW_IDX_8822B 0xfff
+#define BIT_VIQ_HW_IDX_8822B(x) \
+ (((x) & BIT_MASK_VIQ_HW_IDX_8822B) << BIT_SHIFT_VIQ_HW_IDX_8822B)
+#define BIT_GET_VIQ_HW_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_VIQ_HW_IDX_8822B) & BIT_MASK_VIQ_HW_IDX_8822B)
+
+#define BIT_SHIFT_VIQ_HOST_IDX_8822B 0
+#define BIT_MASK_VIQ_HOST_IDX_8822B 0xfff
+#define BIT_VIQ_HOST_IDX_8822B(x) \
+ (((x) & BIT_MASK_VIQ_HOST_IDX_8822B) << BIT_SHIFT_VIQ_HOST_IDX_8822B)
+#define BIT_GET_VIQ_HOST_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_VIQ_HOST_IDX_8822B) & BIT_MASK_VIQ_HOST_IDX_8822B)
+
+/* 2 REG_BEQ_TXBD_IDX_8822B */
+
+#define BIT_SHIFT_BEQ_HW_IDX_8822B 16
+#define BIT_MASK_BEQ_HW_IDX_8822B 0xfff
+#define BIT_BEQ_HW_IDX_8822B(x) \
+ (((x) & BIT_MASK_BEQ_HW_IDX_8822B) << BIT_SHIFT_BEQ_HW_IDX_8822B)
+#define BIT_GET_BEQ_HW_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_BEQ_HW_IDX_8822B) & BIT_MASK_BEQ_HW_IDX_8822B)
+
+#define BIT_SHIFT_BEQ_HOST_IDX_8822B 0
+#define BIT_MASK_BEQ_HOST_IDX_8822B 0xfff
+#define BIT_BEQ_HOST_IDX_8822B(x) \
+ (((x) & BIT_MASK_BEQ_HOST_IDX_8822B) << BIT_SHIFT_BEQ_HOST_IDX_8822B)
+#define BIT_GET_BEQ_HOST_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_BEQ_HOST_IDX_8822B) & BIT_MASK_BEQ_HOST_IDX_8822B)
+
+/* 2 REG_BKQ_TXBD_IDX_8822B */
+
+#define BIT_SHIFT_BKQ_HW_IDX_8822B 16
+#define BIT_MASK_BKQ_HW_IDX_8822B 0xfff
+#define BIT_BKQ_HW_IDX_8822B(x) \
+ (((x) & BIT_MASK_BKQ_HW_IDX_8822B) << BIT_SHIFT_BKQ_HW_IDX_8822B)
+#define BIT_GET_BKQ_HW_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_BKQ_HW_IDX_8822B) & BIT_MASK_BKQ_HW_IDX_8822B)
+
+#define BIT_SHIFT_BKQ_HOST_IDX_8822B 0
+#define BIT_MASK_BKQ_HOST_IDX_8822B 0xfff
+#define BIT_BKQ_HOST_IDX_8822B(x) \
+ (((x) & BIT_MASK_BKQ_HOST_IDX_8822B) << BIT_SHIFT_BKQ_HOST_IDX_8822B)
+#define BIT_GET_BKQ_HOST_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_BKQ_HOST_IDX_8822B) & BIT_MASK_BKQ_HOST_IDX_8822B)
+
+/* 2 REG_MGQ_TXBD_IDX_8822B */
+
+#define BIT_SHIFT_MGQ_HW_IDX_8822B 16
+#define BIT_MASK_MGQ_HW_IDX_8822B 0xfff
+#define BIT_MGQ_HW_IDX_8822B(x) \
+ (((x) & BIT_MASK_MGQ_HW_IDX_8822B) << BIT_SHIFT_MGQ_HW_IDX_8822B)
+#define BIT_GET_MGQ_HW_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_MGQ_HW_IDX_8822B) & BIT_MASK_MGQ_HW_IDX_8822B)
+
+#define BIT_SHIFT_MGQ_HOST_IDX_8822B 0
+#define BIT_MASK_MGQ_HOST_IDX_8822B 0xfff
+#define BIT_MGQ_HOST_IDX_8822B(x) \
+ (((x) & BIT_MASK_MGQ_HOST_IDX_8822B) << BIT_SHIFT_MGQ_HOST_IDX_8822B)
+#define BIT_GET_MGQ_HOST_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_MGQ_HOST_IDX_8822B) & BIT_MASK_MGQ_HOST_IDX_8822B)
+
+/* 2 REG_RXQ_RXBD_IDX_8822B */
+
+#define BIT_SHIFT_RXQ_HW_IDX_8822B 16
+#define BIT_MASK_RXQ_HW_IDX_8822B 0xfff
+#define BIT_RXQ_HW_IDX_8822B(x) \
+ (((x) & BIT_MASK_RXQ_HW_IDX_8822B) << BIT_SHIFT_RXQ_HW_IDX_8822B)
+#define BIT_GET_RXQ_HW_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_RXQ_HW_IDX_8822B) & BIT_MASK_RXQ_HW_IDX_8822B)
+
+#define BIT_SHIFT_RXQ_HOST_IDX_8822B 0
+#define BIT_MASK_RXQ_HOST_IDX_8822B 0xfff
+#define BIT_RXQ_HOST_IDX_8822B(x) \
+ (((x) & BIT_MASK_RXQ_HOST_IDX_8822B) << BIT_SHIFT_RXQ_HOST_IDX_8822B)
+#define BIT_GET_RXQ_HOST_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_RXQ_HOST_IDX_8822B) & BIT_MASK_RXQ_HOST_IDX_8822B)
+
+/* 2 REG_HI0Q_TXBD_IDX_8822B */
+
+#define BIT_SHIFT_HI0Q_HW_IDX_8822B 16
+#define BIT_MASK_HI0Q_HW_IDX_8822B 0xfff
+#define BIT_HI0Q_HW_IDX_8822B(x) \
+ (((x) & BIT_MASK_HI0Q_HW_IDX_8822B) << BIT_SHIFT_HI0Q_HW_IDX_8822B)
+#define BIT_GET_HI0Q_HW_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_HI0Q_HW_IDX_8822B) & BIT_MASK_HI0Q_HW_IDX_8822B)
+
+#define BIT_SHIFT_HI0Q_HOST_IDX_8822B 0
+#define BIT_MASK_HI0Q_HOST_IDX_8822B 0xfff
+#define BIT_HI0Q_HOST_IDX_8822B(x) \
+ (((x) & BIT_MASK_HI0Q_HOST_IDX_8822B) << BIT_SHIFT_HI0Q_HOST_IDX_8822B)
+#define BIT_GET_HI0Q_HOST_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_HI0Q_HOST_IDX_8822B) & BIT_MASK_HI0Q_HOST_IDX_8822B)
+
+/* 2 REG_HI1Q_TXBD_IDX_8822B */
+
+#define BIT_SHIFT_HI1Q_HW_IDX_8822B 16
+#define BIT_MASK_HI1Q_HW_IDX_8822B 0xfff
+#define BIT_HI1Q_HW_IDX_8822B(x) \
+ (((x) & BIT_MASK_HI1Q_HW_IDX_8822B) << BIT_SHIFT_HI1Q_HW_IDX_8822B)
+#define BIT_GET_HI1Q_HW_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_HI1Q_HW_IDX_8822B) & BIT_MASK_HI1Q_HW_IDX_8822B)
+
+#define BIT_SHIFT_HI1Q_HOST_IDX_8822B 0
+#define BIT_MASK_HI1Q_HOST_IDX_8822B 0xfff
+#define BIT_HI1Q_HOST_IDX_8822B(x) \
+ (((x) & BIT_MASK_HI1Q_HOST_IDX_8822B) << BIT_SHIFT_HI1Q_HOST_IDX_8822B)
+#define BIT_GET_HI1Q_HOST_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_HI1Q_HOST_IDX_8822B) & BIT_MASK_HI1Q_HOST_IDX_8822B)
+
+/* 2 REG_HI2Q_TXBD_IDX_8822B */
+
+#define BIT_SHIFT_HI2Q_HW_IDX_8822B 16
+#define BIT_MASK_HI2Q_HW_IDX_8822B 0xfff
+#define BIT_HI2Q_HW_IDX_8822B(x) \
+ (((x) & BIT_MASK_HI2Q_HW_IDX_8822B) << BIT_SHIFT_HI2Q_HW_IDX_8822B)
+#define BIT_GET_HI2Q_HW_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_HI2Q_HW_IDX_8822B) & BIT_MASK_HI2Q_HW_IDX_8822B)
+
+#define BIT_SHIFT_HI2Q_HOST_IDX_8822B 0
+#define BIT_MASK_HI2Q_HOST_IDX_8822B 0xfff
+#define BIT_HI2Q_HOST_IDX_8822B(x) \
+ (((x) & BIT_MASK_HI2Q_HOST_IDX_8822B) << BIT_SHIFT_HI2Q_HOST_IDX_8822B)
+#define BIT_GET_HI2Q_HOST_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_HI2Q_HOST_IDX_8822B) & BIT_MASK_HI2Q_HOST_IDX_8822B)
+
+/* 2 REG_HI3Q_TXBD_IDX_8822B */
+
+#define BIT_SHIFT_HI3Q_HW_IDX_8822B 16
+#define BIT_MASK_HI3Q_HW_IDX_8822B 0xfff
+#define BIT_HI3Q_HW_IDX_8822B(x) \
+ (((x) & BIT_MASK_HI3Q_HW_IDX_8822B) << BIT_SHIFT_HI3Q_HW_IDX_8822B)
+#define BIT_GET_HI3Q_HW_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_HI3Q_HW_IDX_8822B) & BIT_MASK_HI3Q_HW_IDX_8822B)
+
+#define BIT_SHIFT_HI3Q_HOST_IDX_8822B 0
+#define BIT_MASK_HI3Q_HOST_IDX_8822B 0xfff
+#define BIT_HI3Q_HOST_IDX_8822B(x) \
+ (((x) & BIT_MASK_HI3Q_HOST_IDX_8822B) << BIT_SHIFT_HI3Q_HOST_IDX_8822B)
+#define BIT_GET_HI3Q_HOST_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_HI3Q_HOST_IDX_8822B) & BIT_MASK_HI3Q_HOST_IDX_8822B)
+
+/* 2 REG_HI4Q_TXBD_IDX_8822B */
+
+#define BIT_SHIFT_HI4Q_HW_IDX_8822B 16
+#define BIT_MASK_HI4Q_HW_IDX_8822B 0xfff
+#define BIT_HI4Q_HW_IDX_8822B(x) \
+ (((x) & BIT_MASK_HI4Q_HW_IDX_8822B) << BIT_SHIFT_HI4Q_HW_IDX_8822B)
+#define BIT_GET_HI4Q_HW_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_HI4Q_HW_IDX_8822B) & BIT_MASK_HI4Q_HW_IDX_8822B)
+
+#define BIT_SHIFT_HI4Q_HOST_IDX_8822B 0
+#define BIT_MASK_HI4Q_HOST_IDX_8822B 0xfff
+#define BIT_HI4Q_HOST_IDX_8822B(x) \
+ (((x) & BIT_MASK_HI4Q_HOST_IDX_8822B) << BIT_SHIFT_HI4Q_HOST_IDX_8822B)
+#define BIT_GET_HI4Q_HOST_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_HI4Q_HOST_IDX_8822B) & BIT_MASK_HI4Q_HOST_IDX_8822B)
+
+/* 2 REG_HI5Q_TXBD_IDX_8822B */
+
+#define BIT_SHIFT_HI5Q_HW_IDX_8822B 16
+#define BIT_MASK_HI5Q_HW_IDX_8822B 0xfff
+#define BIT_HI5Q_HW_IDX_8822B(x) \
+ (((x) & BIT_MASK_HI5Q_HW_IDX_8822B) << BIT_SHIFT_HI5Q_HW_IDX_8822B)
+#define BIT_GET_HI5Q_HW_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_HI5Q_HW_IDX_8822B) & BIT_MASK_HI5Q_HW_IDX_8822B)
+
+#define BIT_SHIFT_HI5Q_HOST_IDX_8822B 0
+#define BIT_MASK_HI5Q_HOST_IDX_8822B 0xfff
+#define BIT_HI5Q_HOST_IDX_8822B(x) \
+ (((x) & BIT_MASK_HI5Q_HOST_IDX_8822B) << BIT_SHIFT_HI5Q_HOST_IDX_8822B)
+#define BIT_GET_HI5Q_HOST_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_HI5Q_HOST_IDX_8822B) & BIT_MASK_HI5Q_HOST_IDX_8822B)
+
+/* 2 REG_HI6Q_TXBD_IDX_8822B */
+
+#define BIT_SHIFT_HI6Q_HW_IDX_8822B 16
+#define BIT_MASK_HI6Q_HW_IDX_8822B 0xfff
+#define BIT_HI6Q_HW_IDX_8822B(x) \
+ (((x) & BIT_MASK_HI6Q_HW_IDX_8822B) << BIT_SHIFT_HI6Q_HW_IDX_8822B)
+#define BIT_GET_HI6Q_HW_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_HI6Q_HW_IDX_8822B) & BIT_MASK_HI6Q_HW_IDX_8822B)
+
+#define BIT_SHIFT_HI6Q_HOST_IDX_8822B 0
+#define BIT_MASK_HI6Q_HOST_IDX_8822B 0xfff
+#define BIT_HI6Q_HOST_IDX_8822B(x) \
+ (((x) & BIT_MASK_HI6Q_HOST_IDX_8822B) << BIT_SHIFT_HI6Q_HOST_IDX_8822B)
+#define BIT_GET_HI6Q_HOST_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_HI6Q_HOST_IDX_8822B) & BIT_MASK_HI6Q_HOST_IDX_8822B)
+
+/* 2 REG_HI7Q_TXBD_IDX_8822B */
+
+#define BIT_SHIFT_HI7Q_HW_IDX_8822B 16
+#define BIT_MASK_HI7Q_HW_IDX_8822B 0xfff
+#define BIT_HI7Q_HW_IDX_8822B(x) \
+ (((x) & BIT_MASK_HI7Q_HW_IDX_8822B) << BIT_SHIFT_HI7Q_HW_IDX_8822B)
+#define BIT_GET_HI7Q_HW_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_HI7Q_HW_IDX_8822B) & BIT_MASK_HI7Q_HW_IDX_8822B)
+
+#define BIT_SHIFT_HI7Q_HOST_IDX_8822B 0
+#define BIT_MASK_HI7Q_HOST_IDX_8822B 0xfff
+#define BIT_HI7Q_HOST_IDX_8822B(x) \
+ (((x) & BIT_MASK_HI7Q_HOST_IDX_8822B) << BIT_SHIFT_HI7Q_HOST_IDX_8822B)
+#define BIT_GET_HI7Q_HOST_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_HI7Q_HOST_IDX_8822B) & BIT_MASK_HI7Q_HOST_IDX_8822B)
+
+/* 2 REG_DBG_SEL_V1_8822B */
+
+#define BIT_SHIFT_DBG_SEL_8822B 0
+#define BIT_MASK_DBG_SEL_8822B 0xff
+#define BIT_DBG_SEL_8822B(x) \
+ (((x) & BIT_MASK_DBG_SEL_8822B) << BIT_SHIFT_DBG_SEL_8822B)
+#define BIT_GET_DBG_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_DBG_SEL_8822B) & BIT_MASK_DBG_SEL_8822B)
+
+/* 2 REG_PCIE_HRPWM1_V1_8822B */
+
+#define BIT_SHIFT_PCIE_HRPWM_8822B 0
+#define BIT_MASK_PCIE_HRPWM_8822B 0xff
+#define BIT_PCIE_HRPWM_8822B(x) \
+ (((x) & BIT_MASK_PCIE_HRPWM_8822B) << BIT_SHIFT_PCIE_HRPWM_8822B)
+#define BIT_GET_PCIE_HRPWM_8822B(x) \
+ (((x) >> BIT_SHIFT_PCIE_HRPWM_8822B) & BIT_MASK_PCIE_HRPWM_8822B)
+
+/* 2 REG_PCIE_HCPWM1_V1_8822B */
+
+#define BIT_SHIFT_PCIE_HCPWM_8822B 0
+#define BIT_MASK_PCIE_HCPWM_8822B 0xff
+#define BIT_PCIE_HCPWM_8822B(x) \
+ (((x) & BIT_MASK_PCIE_HCPWM_8822B) << BIT_SHIFT_PCIE_HCPWM_8822B)
+#define BIT_GET_PCIE_HCPWM_8822B(x) \
+ (((x) >> BIT_SHIFT_PCIE_HCPWM_8822B) & BIT_MASK_PCIE_HCPWM_8822B)
+
+/* 2 REG_PCIE_CTRL2_8822B */
+#define BIT_DIS_TXDMA_PRE_8822B BIT(7)
+#define BIT_DIS_RXDMA_PRE_8822B BIT(6)
+
+#define BIT_SHIFT_HPS_CLKR_PCIE_8822B 4
+#define BIT_MASK_HPS_CLKR_PCIE_8822B 0x3
+#define BIT_HPS_CLKR_PCIE_8822B(x) \
+ (((x) & BIT_MASK_HPS_CLKR_PCIE_8822B) << BIT_SHIFT_HPS_CLKR_PCIE_8822B)
+#define BIT_GET_HPS_CLKR_PCIE_8822B(x) \
+ (((x) >> BIT_SHIFT_HPS_CLKR_PCIE_8822B) & BIT_MASK_HPS_CLKR_PCIE_8822B)
+
+#define BIT_PCIE_INT_8822B BIT(3)
+#define BIT_TXFLAG_EXIT_L1_EN_8822B BIT(2)
+#define BIT_EN_RXDMA_ALIGN_8822B BIT(1)
+#define BIT_EN_TXDMA_ALIGN_8822B BIT(0)
+
+/* 2 REG_PCIE_HRPWM2_V1_8822B */
+
+#define BIT_SHIFT_PCIE_HRPWM2_8822B 0
+#define BIT_MASK_PCIE_HRPWM2_8822B 0xffff
+#define BIT_PCIE_HRPWM2_8822B(x) \
+ (((x) & BIT_MASK_PCIE_HRPWM2_8822B) << BIT_SHIFT_PCIE_HRPWM2_8822B)
+#define BIT_GET_PCIE_HRPWM2_8822B(x) \
+ (((x) >> BIT_SHIFT_PCIE_HRPWM2_8822B) & BIT_MASK_PCIE_HRPWM2_8822B)
+
+/* 2 REG_PCIE_HCPWM2_V1_8822B */
+
+#define BIT_SHIFT_PCIE_HCPWM2_8822B 0
+#define BIT_MASK_PCIE_HCPWM2_8822B 0xffff
+#define BIT_PCIE_HCPWM2_8822B(x) \
+ (((x) & BIT_MASK_PCIE_HCPWM2_8822B) << BIT_SHIFT_PCIE_HCPWM2_8822B)
+#define BIT_GET_PCIE_HCPWM2_8822B(x) \
+ (((x) >> BIT_SHIFT_PCIE_HCPWM2_8822B) & BIT_MASK_PCIE_HCPWM2_8822B)
+
+/* 2 REG_PCIE_H2C_MSG_V1_8822B */
+
+#define BIT_SHIFT_DRV2FW_INFO_8822B 0
+#define BIT_MASK_DRV2FW_INFO_8822B 0xffffffffL
+#define BIT_DRV2FW_INFO_8822B(x) \
+ (((x) & BIT_MASK_DRV2FW_INFO_8822B) << BIT_SHIFT_DRV2FW_INFO_8822B)
+#define BIT_GET_DRV2FW_INFO_8822B(x) \
+ (((x) >> BIT_SHIFT_DRV2FW_INFO_8822B) & BIT_MASK_DRV2FW_INFO_8822B)
+
+/* 2 REG_PCIE_C2H_MSG_V1_8822B */
+
+#define BIT_SHIFT_HCI_PCIE_C2H_MSG_8822B 0
+#define BIT_MASK_HCI_PCIE_C2H_MSG_8822B 0xffffffffL
+#define BIT_HCI_PCIE_C2H_MSG_8822B(x) \
+ (((x) & BIT_MASK_HCI_PCIE_C2H_MSG_8822B) \
+ << BIT_SHIFT_HCI_PCIE_C2H_MSG_8822B)
+#define BIT_GET_HCI_PCIE_C2H_MSG_8822B(x) \
+ (((x) >> BIT_SHIFT_HCI_PCIE_C2H_MSG_8822B) & \
+ BIT_MASK_HCI_PCIE_C2H_MSG_8822B)
+
+/* 2 REG_DBI_WDATA_V1_8822B */
+
+#define BIT_SHIFT_DBI_WDATA_8822B 0
+#define BIT_MASK_DBI_WDATA_8822B 0xffffffffL
+#define BIT_DBI_WDATA_8822B(x) \
+ (((x) & BIT_MASK_DBI_WDATA_8822B) << BIT_SHIFT_DBI_WDATA_8822B)
+#define BIT_GET_DBI_WDATA_8822B(x) \
+ (((x) >> BIT_SHIFT_DBI_WDATA_8822B) & BIT_MASK_DBI_WDATA_8822B)
+
+/* 2 REG_DBI_RDATA_V1_8822B */
+
+#define BIT_SHIFT_DBI_RDATA_8822B 0
+#define BIT_MASK_DBI_RDATA_8822B 0xffffffffL
+#define BIT_DBI_RDATA_8822B(x) \
+ (((x) & BIT_MASK_DBI_RDATA_8822B) << BIT_SHIFT_DBI_RDATA_8822B)
+#define BIT_GET_DBI_RDATA_8822B(x) \
+ (((x) >> BIT_SHIFT_DBI_RDATA_8822B) & BIT_MASK_DBI_RDATA_8822B)
+
+/* 2 REG_DBI_FLAG_V1_8822B */
+#define BIT_EN_STUCK_DBG_8822B BIT(26)
+#define BIT_RX_STUCK_8822B BIT(25)
+#define BIT_TX_STUCK_8822B BIT(24)
+#define BIT_DBI_RFLAG_8822B BIT(17)
+#define BIT_DBI_WFLAG_8822B BIT(16)
+
+#define BIT_SHIFT_DBI_WREN_8822B 12
+#define BIT_MASK_DBI_WREN_8822B 0xf
+#define BIT_DBI_WREN_8822B(x) \
+ (((x) & BIT_MASK_DBI_WREN_8822B) << BIT_SHIFT_DBI_WREN_8822B)
+#define BIT_GET_DBI_WREN_8822B(x) \
+ (((x) >> BIT_SHIFT_DBI_WREN_8822B) & BIT_MASK_DBI_WREN_8822B)
+
+#define BIT_SHIFT_DBI_ADDR_8822B 0
+#define BIT_MASK_DBI_ADDR_8822B 0xfff
+#define BIT_DBI_ADDR_8822B(x) \
+ (((x) & BIT_MASK_DBI_ADDR_8822B) << BIT_SHIFT_DBI_ADDR_8822B)
+#define BIT_GET_DBI_ADDR_8822B(x) \
+ (((x) >> BIT_SHIFT_DBI_ADDR_8822B) & BIT_MASK_DBI_ADDR_8822B)
+
+/* 2 REG_MDIO_V1_8822B */
+
+#define BIT_SHIFT_MDIO_RDATA_8822B 16
+#define BIT_MASK_MDIO_RDATA_8822B 0xffff
+#define BIT_MDIO_RDATA_8822B(x) \
+ (((x) & BIT_MASK_MDIO_RDATA_8822B) << BIT_SHIFT_MDIO_RDATA_8822B)
+#define BIT_GET_MDIO_RDATA_8822B(x) \
+ (((x) >> BIT_SHIFT_MDIO_RDATA_8822B) & BIT_MASK_MDIO_RDATA_8822B)
+
+#define BIT_SHIFT_MDIO_WDATA_8822B 0
+#define BIT_MASK_MDIO_WDATA_8822B 0xffff
+#define BIT_MDIO_WDATA_8822B(x) \
+ (((x) & BIT_MASK_MDIO_WDATA_8822B) << BIT_SHIFT_MDIO_WDATA_8822B)
+#define BIT_GET_MDIO_WDATA_8822B(x) \
+ (((x) >> BIT_SHIFT_MDIO_WDATA_8822B) & BIT_MASK_MDIO_WDATA_8822B)
+
+/* 2 REG_PCIE_MIX_CFG_8822B */
+
+#define BIT_SHIFT_MDIO_PHY_ADDR_8822B 24
+#define BIT_MASK_MDIO_PHY_ADDR_8822B 0x1f
+#define BIT_MDIO_PHY_ADDR_8822B(x) \
+ (((x) & BIT_MASK_MDIO_PHY_ADDR_8822B) << BIT_SHIFT_MDIO_PHY_ADDR_8822B)
+#define BIT_GET_MDIO_PHY_ADDR_8822B(x) \
+ (((x) >> BIT_SHIFT_MDIO_PHY_ADDR_8822B) & BIT_MASK_MDIO_PHY_ADDR_8822B)
+
+#define BIT_SHIFT_WATCH_DOG_RECORD_V1_8822B 10
+#define BIT_MASK_WATCH_DOG_RECORD_V1_8822B 0x3fff
+#define BIT_WATCH_DOG_RECORD_V1_8822B(x) \
+ (((x) & BIT_MASK_WATCH_DOG_RECORD_V1_8822B) \
+ << BIT_SHIFT_WATCH_DOG_RECORD_V1_8822B)
+#define BIT_GET_WATCH_DOG_RECORD_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_WATCH_DOG_RECORD_V1_8822B) & \
+ BIT_MASK_WATCH_DOG_RECORD_V1_8822B)
+
+#define BIT_R_IO_TIMEOUT_FLAG_V1_8822B BIT(9)
+#define BIT_EN_WATCH_DOG_8822B BIT(8)
+#define BIT_ECRC_EN_V1_8822B BIT(7)
+#define BIT_MDIO_RFLAG_V1_8822B BIT(6)
+#define BIT_MDIO_WFLAG_V1_8822B BIT(5)
+
+#define BIT_SHIFT_MDIO_REG_ADDR_V1_8822B 0
+#define BIT_MASK_MDIO_REG_ADDR_V1_8822B 0x1f
+#define BIT_MDIO_REG_ADDR_V1_8822B(x) \
+ (((x) & BIT_MASK_MDIO_REG_ADDR_V1_8822B) \
+ << BIT_SHIFT_MDIO_REG_ADDR_V1_8822B)
+#define BIT_GET_MDIO_REG_ADDR_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_MDIO_REG_ADDR_V1_8822B) & \
+ BIT_MASK_MDIO_REG_ADDR_V1_8822B)
+
+/* 2 REG_HCI_MIX_CFG_8822B */
+#define BIT_HOST_GEN2_SUPPORT_8822B BIT(20)
+
+#define BIT_SHIFT_TXDMA_ERR_FLAG_8822B 16
+#define BIT_MASK_TXDMA_ERR_FLAG_8822B 0xf
+#define BIT_TXDMA_ERR_FLAG_8822B(x) \
+ (((x) & BIT_MASK_TXDMA_ERR_FLAG_8822B) \
+ << BIT_SHIFT_TXDMA_ERR_FLAG_8822B)
+#define BIT_GET_TXDMA_ERR_FLAG_8822B(x) \
+ (((x) >> BIT_SHIFT_TXDMA_ERR_FLAG_8822B) & \
+ BIT_MASK_TXDMA_ERR_FLAG_8822B)
+
+#define BIT_SHIFT_EARLY_MODE_SEL_8822B 12
+#define BIT_MASK_EARLY_MODE_SEL_8822B 0xf
+#define BIT_EARLY_MODE_SEL_8822B(x) \
+ (((x) & BIT_MASK_EARLY_MODE_SEL_8822B) \
+ << BIT_SHIFT_EARLY_MODE_SEL_8822B)
+#define BIT_GET_EARLY_MODE_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_EARLY_MODE_SEL_8822B) & \
+ BIT_MASK_EARLY_MODE_SEL_8822B)
+
+#define BIT_EPHY_RX50_EN_8822B BIT(11)
+
+#define BIT_SHIFT_MSI_TIMEOUT_ID_V1_8822B 8
+#define BIT_MASK_MSI_TIMEOUT_ID_V1_8822B 0x7
+#define BIT_MSI_TIMEOUT_ID_V1_8822B(x) \
+ (((x) & BIT_MASK_MSI_TIMEOUT_ID_V1_8822B) \
+ << BIT_SHIFT_MSI_TIMEOUT_ID_V1_8822B)
+#define BIT_GET_MSI_TIMEOUT_ID_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_MSI_TIMEOUT_ID_V1_8822B) & \
+ BIT_MASK_MSI_TIMEOUT_ID_V1_8822B)
+
+#define BIT_RADDR_RD_8822B BIT(7)
+#define BIT_EN_MUL_TAG_8822B BIT(6)
+#define BIT_EN_EARLY_MODE_8822B BIT(5)
+#define BIT_L0S_LINK_OFF_8822B BIT(4)
+#define BIT_ACT_LINK_OFF_8822B BIT(3)
+#define BIT_EN_SLOW_MAC_TX_8822B BIT(2)
+#define BIT_EN_SLOW_MAC_RX_8822B BIT(1)
+
+/* 2 REG_STC_INT_CS_8822B(PCIE STATE CHANGE INTERRUPT CONTROL AND STATUS) */
+#define BIT_STC_INT_EN_8822B BIT(31)
+
+#define BIT_SHIFT_STC_INT_FLAG_8822B 16
+#define BIT_MASK_STC_INT_FLAG_8822B 0xff
+#define BIT_STC_INT_FLAG_8822B(x) \
+ (((x) & BIT_MASK_STC_INT_FLAG_8822B) << BIT_SHIFT_STC_INT_FLAG_8822B)
+#define BIT_GET_STC_INT_FLAG_8822B(x) \
+ (((x) >> BIT_SHIFT_STC_INT_FLAG_8822B) & BIT_MASK_STC_INT_FLAG_8822B)
+
+#define BIT_SHIFT_STC_INT_IDX_8822B 8
+#define BIT_MASK_STC_INT_IDX_8822B 0x7
+#define BIT_STC_INT_IDX_8822B(x) \
+ (((x) & BIT_MASK_STC_INT_IDX_8822B) << BIT_SHIFT_STC_INT_IDX_8822B)
+#define BIT_GET_STC_INT_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_STC_INT_IDX_8822B) & BIT_MASK_STC_INT_IDX_8822B)
+
+#define BIT_SHIFT_STC_INT_REALTIME_CS_8822B 0
+#define BIT_MASK_STC_INT_REALTIME_CS_8822B 0x3f
+#define BIT_STC_INT_REALTIME_CS_8822B(x) \
+ (((x) & BIT_MASK_STC_INT_REALTIME_CS_8822B) \
+ << BIT_SHIFT_STC_INT_REALTIME_CS_8822B)
+#define BIT_GET_STC_INT_REALTIME_CS_8822B(x) \
+ (((x) >> BIT_SHIFT_STC_INT_REALTIME_CS_8822B) & \
+ BIT_MASK_STC_INT_REALTIME_CS_8822B)
+
+/* 2 REG_ST_INT_CFG_8822B(PCIE STATE CHANGE INTERRUPT CONFIGURATION) */
+#define BIT_STC_INT_GRP_EN_8822B BIT(31)
+
+#define BIT_SHIFT_STC_INT_EXPECT_LS_8822B 8
+#define BIT_MASK_STC_INT_EXPECT_LS_8822B 0x3f
+#define BIT_STC_INT_EXPECT_LS_8822B(x) \
+ (((x) & BIT_MASK_STC_INT_EXPECT_LS_8822B) \
+ << BIT_SHIFT_STC_INT_EXPECT_LS_8822B)
+#define BIT_GET_STC_INT_EXPECT_LS_8822B(x) \
+ (((x) >> BIT_SHIFT_STC_INT_EXPECT_LS_8822B) & \
+ BIT_MASK_STC_INT_EXPECT_LS_8822B)
+
+#define BIT_SHIFT_STC_INT_EXPECT_CS_8822B 0
+#define BIT_MASK_STC_INT_EXPECT_CS_8822B 0x3f
+#define BIT_STC_INT_EXPECT_CS_8822B(x) \
+ (((x) & BIT_MASK_STC_INT_EXPECT_CS_8822B) \
+ << BIT_SHIFT_STC_INT_EXPECT_CS_8822B)
+#define BIT_GET_STC_INT_EXPECT_CS_8822B(x) \
+ (((x) >> BIT_SHIFT_STC_INT_EXPECT_CS_8822B) & \
+ BIT_MASK_STC_INT_EXPECT_CS_8822B)
+
+/* 2 REG_CMU_DLY_CTRL_8822B(PCIE PHY CLOCK MGT UNIT DELAY CONTROL ) */
+#define BIT_CMU_DLY_EN_8822B BIT(31)
+#define BIT_CMU_DLY_MODE_8822B BIT(30)
+
+#define BIT_SHIFT_CMU_DLY_PRE_DIV_8822B 0
+#define BIT_MASK_CMU_DLY_PRE_DIV_8822B 0xff
+#define BIT_CMU_DLY_PRE_DIV_8822B(x) \
+ (((x) & BIT_MASK_CMU_DLY_PRE_DIV_8822B) \
+ << BIT_SHIFT_CMU_DLY_PRE_DIV_8822B)
+#define BIT_GET_CMU_DLY_PRE_DIV_8822B(x) \
+ (((x) >> BIT_SHIFT_CMU_DLY_PRE_DIV_8822B) & \
+ BIT_MASK_CMU_DLY_PRE_DIV_8822B)
+
+/* 2 REG_CMU_DLY_CFG_8822B(PCIE PHY CLOCK MGT UNIT DELAY CONFIGURATION ) */
+
+#define BIT_SHIFT_CMU_DLY_LTR_A2I_8822B 24
+#define BIT_MASK_CMU_DLY_LTR_A2I_8822B 0xff
+#define BIT_CMU_DLY_LTR_A2I_8822B(x) \
+ (((x) & BIT_MASK_CMU_DLY_LTR_A2I_8822B) \
+ << BIT_SHIFT_CMU_DLY_LTR_A2I_8822B)
+#define BIT_GET_CMU_DLY_LTR_A2I_8822B(x) \
+ (((x) >> BIT_SHIFT_CMU_DLY_LTR_A2I_8822B) & \
+ BIT_MASK_CMU_DLY_LTR_A2I_8822B)
+
+#define BIT_SHIFT_CMU_DLY_LTR_I2A_8822B 16
+#define BIT_MASK_CMU_DLY_LTR_I2A_8822B 0xff
+#define BIT_CMU_DLY_LTR_I2A_8822B(x) \
+ (((x) & BIT_MASK_CMU_DLY_LTR_I2A_8822B) \
+ << BIT_SHIFT_CMU_DLY_LTR_I2A_8822B)
+#define BIT_GET_CMU_DLY_LTR_I2A_8822B(x) \
+ (((x) >> BIT_SHIFT_CMU_DLY_LTR_I2A_8822B) & \
+ BIT_MASK_CMU_DLY_LTR_I2A_8822B)
+
+#define BIT_SHIFT_CMU_DLY_LTR_IDLE_8822B 8
+#define BIT_MASK_CMU_DLY_LTR_IDLE_8822B 0xff
+#define BIT_CMU_DLY_LTR_IDLE_8822B(x) \
+ (((x) & BIT_MASK_CMU_DLY_LTR_IDLE_8822B) \
+ << BIT_SHIFT_CMU_DLY_LTR_IDLE_8822B)
+#define BIT_GET_CMU_DLY_LTR_IDLE_8822B(x) \
+ (((x) >> BIT_SHIFT_CMU_DLY_LTR_IDLE_8822B) & \
+ BIT_MASK_CMU_DLY_LTR_IDLE_8822B)
+
+#define BIT_SHIFT_CMU_DLY_LTR_ACT_8822B 0
+#define BIT_MASK_CMU_DLY_LTR_ACT_8822B 0xff
+#define BIT_CMU_DLY_LTR_ACT_8822B(x) \
+ (((x) & BIT_MASK_CMU_DLY_LTR_ACT_8822B) \
+ << BIT_SHIFT_CMU_DLY_LTR_ACT_8822B)
+#define BIT_GET_CMU_DLY_LTR_ACT_8822B(x) \
+ (((x) >> BIT_SHIFT_CMU_DLY_LTR_ACT_8822B) & \
+ BIT_MASK_CMU_DLY_LTR_ACT_8822B)
+
+/* 2 REG_H2CQ_TXBD_DESA_8822B */
+
+#define BIT_SHIFT_H2CQ_TXBD_DESA_8822B 0
+#define BIT_MASK_H2CQ_TXBD_DESA_8822B 0xffffffffffffffffL
+#define BIT_H2CQ_TXBD_DESA_8822B(x) \
+ (((x) & BIT_MASK_H2CQ_TXBD_DESA_8822B) \
+ << BIT_SHIFT_H2CQ_TXBD_DESA_8822B)
+#define BIT_GET_H2CQ_TXBD_DESA_8822B(x) \
+ (((x) >> BIT_SHIFT_H2CQ_TXBD_DESA_8822B) & \
+ BIT_MASK_H2CQ_TXBD_DESA_8822B)
+
+/* 2 REG_H2CQ_TXBD_NUM_8822B */
+#define BIT_PCIE_H2CQ_FLAG_8822B BIT(14)
+
+#define BIT_SHIFT_H2CQ_DESC_MODE_8822B 12
+#define BIT_MASK_H2CQ_DESC_MODE_8822B 0x3
+#define BIT_H2CQ_DESC_MODE_8822B(x) \
+ (((x) & BIT_MASK_H2CQ_DESC_MODE_8822B) \
+ << BIT_SHIFT_H2CQ_DESC_MODE_8822B)
+#define BIT_GET_H2CQ_DESC_MODE_8822B(x) \
+ (((x) >> BIT_SHIFT_H2CQ_DESC_MODE_8822B) & \
+ BIT_MASK_H2CQ_DESC_MODE_8822B)
+
+#define BIT_SHIFT_H2CQ_DESC_NUM_8822B 0
+#define BIT_MASK_H2CQ_DESC_NUM_8822B 0xfff
+#define BIT_H2CQ_DESC_NUM_8822B(x) \
+ (((x) & BIT_MASK_H2CQ_DESC_NUM_8822B) << BIT_SHIFT_H2CQ_DESC_NUM_8822B)
+#define BIT_GET_H2CQ_DESC_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_H2CQ_DESC_NUM_8822B) & BIT_MASK_H2CQ_DESC_NUM_8822B)
+
+/* 2 REG_H2CQ_TXBD_IDX_8822B */
+
+#define BIT_SHIFT_H2CQ_HW_IDX_8822B 16
+#define BIT_MASK_H2CQ_HW_IDX_8822B 0xfff
+#define BIT_H2CQ_HW_IDX_8822B(x) \
+ (((x) & BIT_MASK_H2CQ_HW_IDX_8822B) << BIT_SHIFT_H2CQ_HW_IDX_8822B)
+#define BIT_GET_H2CQ_HW_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_H2CQ_HW_IDX_8822B) & BIT_MASK_H2CQ_HW_IDX_8822B)
+
+#define BIT_SHIFT_H2CQ_HOST_IDX_8822B 0
+#define BIT_MASK_H2CQ_HOST_IDX_8822B 0xfff
+#define BIT_H2CQ_HOST_IDX_8822B(x) \
+ (((x) & BIT_MASK_H2CQ_HOST_IDX_8822B) << BIT_SHIFT_H2CQ_HOST_IDX_8822B)
+#define BIT_GET_H2CQ_HOST_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_H2CQ_HOST_IDX_8822B) & BIT_MASK_H2CQ_HOST_IDX_8822B)
+
+/* 2 REG_H2CQ_CSR_8822B[31:0] (H2CQ CONTROL AND STATUS) */
+#define BIT_H2CQ_FULL_8822B BIT(31)
+#define BIT_CLR_H2CQ_HOST_IDX_8822B BIT(16)
+#define BIT_CLR_H2CQ_HW_IDX_8822B BIT(8)
+
+/* 2 REG_CHANGE_PCIE_SPEED_8822B */
+#define BIT_CHANGE_PCIE_SPEED_8822B BIT(18)
+
+#define BIT_SHIFT_GEN1_GEN2_8822B 16
+#define BIT_MASK_GEN1_GEN2_8822B 0x3
+#define BIT_GEN1_GEN2_8822B(x) \
+ (((x) & BIT_MASK_GEN1_GEN2_8822B) << BIT_SHIFT_GEN1_GEN2_8822B)
+#define BIT_GET_GEN1_GEN2_8822B(x) \
+ (((x) >> BIT_SHIFT_GEN1_GEN2_8822B) & BIT_MASK_GEN1_GEN2_8822B)
+
+#define BIT_SHIFT_AUTO_HANG_RELEASE_8822B 0
+#define BIT_MASK_AUTO_HANG_RELEASE_8822B 0x7
+#define BIT_AUTO_HANG_RELEASE_8822B(x) \
+ (((x) & BIT_MASK_AUTO_HANG_RELEASE_8822B) \
+ << BIT_SHIFT_AUTO_HANG_RELEASE_8822B)
+#define BIT_GET_AUTO_HANG_RELEASE_8822B(x) \
+ (((x) >> BIT_SHIFT_AUTO_HANG_RELEASE_8822B) & \
+ BIT_MASK_AUTO_HANG_RELEASE_8822B)
+
+/* 2 REG_OLD_DEHANG_8822B */
+#define BIT_OLD_DEHANG_8822B BIT(1)
+
+/* 2 REG_Q0_INFO_8822B */
+
+#define BIT_SHIFT_QUEUEMACID_Q0_V1_8822B 25
+#define BIT_MASK_QUEUEMACID_Q0_V1_8822B 0x7f
+#define BIT_QUEUEMACID_Q0_V1_8822B(x) \
+ (((x) & BIT_MASK_QUEUEMACID_Q0_V1_8822B) \
+ << BIT_SHIFT_QUEUEMACID_Q0_V1_8822B)
+#define BIT_GET_QUEUEMACID_Q0_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_QUEUEMACID_Q0_V1_8822B) & \
+ BIT_MASK_QUEUEMACID_Q0_V1_8822B)
+
+#define BIT_SHIFT_QUEUEAC_Q0_V1_8822B 23
+#define BIT_MASK_QUEUEAC_Q0_V1_8822B 0x3
+#define BIT_QUEUEAC_Q0_V1_8822B(x) \
+ (((x) & BIT_MASK_QUEUEAC_Q0_V1_8822B) << BIT_SHIFT_QUEUEAC_Q0_V1_8822B)
+#define BIT_GET_QUEUEAC_Q0_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_QUEUEAC_Q0_V1_8822B) & BIT_MASK_QUEUEAC_Q0_V1_8822B)
+
+#define BIT_TIDEMPTY_Q0_V1_8822B BIT(22)
+
+#define BIT_SHIFT_TAIL_PKT_Q0_V2_8822B 11
+#define BIT_MASK_TAIL_PKT_Q0_V2_8822B 0x7ff
+#define BIT_TAIL_PKT_Q0_V2_8822B(x) \
+ (((x) & BIT_MASK_TAIL_PKT_Q0_V2_8822B) \
+ << BIT_SHIFT_TAIL_PKT_Q0_V2_8822B)
+#define BIT_GET_TAIL_PKT_Q0_V2_8822B(x) \
+ (((x) >> BIT_SHIFT_TAIL_PKT_Q0_V2_8822B) & \
+ BIT_MASK_TAIL_PKT_Q0_V2_8822B)
+
+#define BIT_SHIFT_HEAD_PKT_Q0_V1_8822B 0
+#define BIT_MASK_HEAD_PKT_Q0_V1_8822B 0x7ff
+#define BIT_HEAD_PKT_Q0_V1_8822B(x) \
+ (((x) & BIT_MASK_HEAD_PKT_Q0_V1_8822B) \
+ << BIT_SHIFT_HEAD_PKT_Q0_V1_8822B)
+#define BIT_GET_HEAD_PKT_Q0_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_HEAD_PKT_Q0_V1_8822B) & \
+ BIT_MASK_HEAD_PKT_Q0_V1_8822B)
+
+/* 2 REG_Q1_INFO_8822B */
+
+#define BIT_SHIFT_QUEUEMACID_Q1_V1_8822B 25
+#define BIT_MASK_QUEUEMACID_Q1_V1_8822B 0x7f
+#define BIT_QUEUEMACID_Q1_V1_8822B(x) \
+ (((x) & BIT_MASK_QUEUEMACID_Q1_V1_8822B) \
+ << BIT_SHIFT_QUEUEMACID_Q1_V1_8822B)
+#define BIT_GET_QUEUEMACID_Q1_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_QUEUEMACID_Q1_V1_8822B) & \
+ BIT_MASK_QUEUEMACID_Q1_V1_8822B)
+
+#define BIT_SHIFT_QUEUEAC_Q1_V1_8822B 23
+#define BIT_MASK_QUEUEAC_Q1_V1_8822B 0x3
+#define BIT_QUEUEAC_Q1_V1_8822B(x) \
+ (((x) & BIT_MASK_QUEUEAC_Q1_V1_8822B) << BIT_SHIFT_QUEUEAC_Q1_V1_8822B)
+#define BIT_GET_QUEUEAC_Q1_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_QUEUEAC_Q1_V1_8822B) & BIT_MASK_QUEUEAC_Q1_V1_8822B)
+
+#define BIT_TIDEMPTY_Q1_V1_8822B BIT(22)
+
+#define BIT_SHIFT_TAIL_PKT_Q1_V2_8822B 11
+#define BIT_MASK_TAIL_PKT_Q1_V2_8822B 0x7ff
+#define BIT_TAIL_PKT_Q1_V2_8822B(x) \
+ (((x) & BIT_MASK_TAIL_PKT_Q1_V2_8822B) \
+ << BIT_SHIFT_TAIL_PKT_Q1_V2_8822B)
+#define BIT_GET_TAIL_PKT_Q1_V2_8822B(x) \
+ (((x) >> BIT_SHIFT_TAIL_PKT_Q1_V2_8822B) & \
+ BIT_MASK_TAIL_PKT_Q1_V2_8822B)
+
+#define BIT_SHIFT_HEAD_PKT_Q1_V1_8822B 0
+#define BIT_MASK_HEAD_PKT_Q1_V1_8822B 0x7ff
+#define BIT_HEAD_PKT_Q1_V1_8822B(x) \
+ (((x) & BIT_MASK_HEAD_PKT_Q1_V1_8822B) \
+ << BIT_SHIFT_HEAD_PKT_Q1_V1_8822B)
+#define BIT_GET_HEAD_PKT_Q1_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_HEAD_PKT_Q1_V1_8822B) & \
+ BIT_MASK_HEAD_PKT_Q1_V1_8822B)
+
+/* 2 REG_Q2_INFO_8822B */
+
+#define BIT_SHIFT_QUEUEMACID_Q2_V1_8822B 25
+#define BIT_MASK_QUEUEMACID_Q2_V1_8822B 0x7f
+#define BIT_QUEUEMACID_Q2_V1_8822B(x) \
+ (((x) & BIT_MASK_QUEUEMACID_Q2_V1_8822B) \
+ << BIT_SHIFT_QUEUEMACID_Q2_V1_8822B)
+#define BIT_GET_QUEUEMACID_Q2_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_QUEUEMACID_Q2_V1_8822B) & \
+ BIT_MASK_QUEUEMACID_Q2_V1_8822B)
+
+#define BIT_SHIFT_QUEUEAC_Q2_V1_8822B 23
+#define BIT_MASK_QUEUEAC_Q2_V1_8822B 0x3
+#define BIT_QUEUEAC_Q2_V1_8822B(x) \
+ (((x) & BIT_MASK_QUEUEAC_Q2_V1_8822B) << BIT_SHIFT_QUEUEAC_Q2_V1_8822B)
+#define BIT_GET_QUEUEAC_Q2_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_QUEUEAC_Q2_V1_8822B) & BIT_MASK_QUEUEAC_Q2_V1_8822B)
+
+#define BIT_TIDEMPTY_Q2_V1_8822B BIT(22)
+
+#define BIT_SHIFT_TAIL_PKT_Q2_V2_8822B 11
+#define BIT_MASK_TAIL_PKT_Q2_V2_8822B 0x7ff
+#define BIT_TAIL_PKT_Q2_V2_8822B(x) \
+ (((x) & BIT_MASK_TAIL_PKT_Q2_V2_8822B) \
+ << BIT_SHIFT_TAIL_PKT_Q2_V2_8822B)
+#define BIT_GET_TAIL_PKT_Q2_V2_8822B(x) \
+ (((x) >> BIT_SHIFT_TAIL_PKT_Q2_V2_8822B) & \
+ BIT_MASK_TAIL_PKT_Q2_V2_8822B)
+
+#define BIT_SHIFT_HEAD_PKT_Q2_V1_8822B 0
+#define BIT_MASK_HEAD_PKT_Q2_V1_8822B 0x7ff
+#define BIT_HEAD_PKT_Q2_V1_8822B(x) \
+ (((x) & BIT_MASK_HEAD_PKT_Q2_V1_8822B) \
+ << BIT_SHIFT_HEAD_PKT_Q2_V1_8822B)
+#define BIT_GET_HEAD_PKT_Q2_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_HEAD_PKT_Q2_V1_8822B) & \
+ BIT_MASK_HEAD_PKT_Q2_V1_8822B)
+
+/* 2 REG_Q3_INFO_8822B */
+
+#define BIT_SHIFT_QUEUEMACID_Q3_V1_8822B 25
+#define BIT_MASK_QUEUEMACID_Q3_V1_8822B 0x7f
+#define BIT_QUEUEMACID_Q3_V1_8822B(x) \
+ (((x) & BIT_MASK_QUEUEMACID_Q3_V1_8822B) \
+ << BIT_SHIFT_QUEUEMACID_Q3_V1_8822B)
+#define BIT_GET_QUEUEMACID_Q3_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_QUEUEMACID_Q3_V1_8822B) & \
+ BIT_MASK_QUEUEMACID_Q3_V1_8822B)
+
+#define BIT_SHIFT_QUEUEAC_Q3_V1_8822B 23
+#define BIT_MASK_QUEUEAC_Q3_V1_8822B 0x3
+#define BIT_QUEUEAC_Q3_V1_8822B(x) \
+ (((x) & BIT_MASK_QUEUEAC_Q3_V1_8822B) << BIT_SHIFT_QUEUEAC_Q3_V1_8822B)
+#define BIT_GET_QUEUEAC_Q3_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_QUEUEAC_Q3_V1_8822B) & BIT_MASK_QUEUEAC_Q3_V1_8822B)
+
+#define BIT_TIDEMPTY_Q3_V1_8822B BIT(22)
+
+#define BIT_SHIFT_TAIL_PKT_Q3_V2_8822B 11
+#define BIT_MASK_TAIL_PKT_Q3_V2_8822B 0x7ff
+#define BIT_TAIL_PKT_Q3_V2_8822B(x) \
+ (((x) & BIT_MASK_TAIL_PKT_Q3_V2_8822B) \
+ << BIT_SHIFT_TAIL_PKT_Q3_V2_8822B)
+#define BIT_GET_TAIL_PKT_Q3_V2_8822B(x) \
+ (((x) >> BIT_SHIFT_TAIL_PKT_Q3_V2_8822B) & \
+ BIT_MASK_TAIL_PKT_Q3_V2_8822B)
+
+#define BIT_SHIFT_HEAD_PKT_Q3_V1_8822B 0
+#define BIT_MASK_HEAD_PKT_Q3_V1_8822B 0x7ff
+#define BIT_HEAD_PKT_Q3_V1_8822B(x) \
+ (((x) & BIT_MASK_HEAD_PKT_Q3_V1_8822B) \
+ << BIT_SHIFT_HEAD_PKT_Q3_V1_8822B)
+#define BIT_GET_HEAD_PKT_Q3_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_HEAD_PKT_Q3_V1_8822B) & \
+ BIT_MASK_HEAD_PKT_Q3_V1_8822B)
+
+/* 2 REG_MGQ_INFO_8822B */
+
+#define BIT_SHIFT_QUEUEMACID_MGQ_V1_8822B 25
+#define BIT_MASK_QUEUEMACID_MGQ_V1_8822B 0x7f
+#define BIT_QUEUEMACID_MGQ_V1_8822B(x) \
+ (((x) & BIT_MASK_QUEUEMACID_MGQ_V1_8822B) \
+ << BIT_SHIFT_QUEUEMACID_MGQ_V1_8822B)
+#define BIT_GET_QUEUEMACID_MGQ_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_QUEUEMACID_MGQ_V1_8822B) & \
+ BIT_MASK_QUEUEMACID_MGQ_V1_8822B)
+
+#define BIT_SHIFT_QUEUEAC_MGQ_V1_8822B 23
+#define BIT_MASK_QUEUEAC_MGQ_V1_8822B 0x3
+#define BIT_QUEUEAC_MGQ_V1_8822B(x) \
+ (((x) & BIT_MASK_QUEUEAC_MGQ_V1_8822B) \
+ << BIT_SHIFT_QUEUEAC_MGQ_V1_8822B)
+#define BIT_GET_QUEUEAC_MGQ_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_QUEUEAC_MGQ_V1_8822B) & \
+ BIT_MASK_QUEUEAC_MGQ_V1_8822B)
+
+#define BIT_TIDEMPTY_MGQ_V1_8822B BIT(22)
+
+#define BIT_SHIFT_TAIL_PKT_MGQ_V2_8822B 11
+#define BIT_MASK_TAIL_PKT_MGQ_V2_8822B 0x7ff
+#define BIT_TAIL_PKT_MGQ_V2_8822B(x) \
+ (((x) & BIT_MASK_TAIL_PKT_MGQ_V2_8822B) \
+ << BIT_SHIFT_TAIL_PKT_MGQ_V2_8822B)
+#define BIT_GET_TAIL_PKT_MGQ_V2_8822B(x) \
+ (((x) >> BIT_SHIFT_TAIL_PKT_MGQ_V2_8822B) & \
+ BIT_MASK_TAIL_PKT_MGQ_V2_8822B)
+
+#define BIT_SHIFT_HEAD_PKT_MGQ_V1_8822B 0
+#define BIT_MASK_HEAD_PKT_MGQ_V1_8822B 0x7ff
+#define BIT_HEAD_PKT_MGQ_V1_8822B(x) \
+ (((x) & BIT_MASK_HEAD_PKT_MGQ_V1_8822B) \
+ << BIT_SHIFT_HEAD_PKT_MGQ_V1_8822B)
+#define BIT_GET_HEAD_PKT_MGQ_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_HEAD_PKT_MGQ_V1_8822B) & \
+ BIT_MASK_HEAD_PKT_MGQ_V1_8822B)
+
+/* 2 REG_HIQ_INFO_8822B */
+
+#define BIT_SHIFT_QUEUEMACID_HIQ_V1_8822B 25
+#define BIT_MASK_QUEUEMACID_HIQ_V1_8822B 0x7f
+#define BIT_QUEUEMACID_HIQ_V1_8822B(x) \
+ (((x) & BIT_MASK_QUEUEMACID_HIQ_V1_8822B) \
+ << BIT_SHIFT_QUEUEMACID_HIQ_V1_8822B)
+#define BIT_GET_QUEUEMACID_HIQ_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_QUEUEMACID_HIQ_V1_8822B) & \
+ BIT_MASK_QUEUEMACID_HIQ_V1_8822B)
+
+#define BIT_SHIFT_QUEUEAC_HIQ_V1_8822B 23
+#define BIT_MASK_QUEUEAC_HIQ_V1_8822B 0x3
+#define BIT_QUEUEAC_HIQ_V1_8822B(x) \
+ (((x) & BIT_MASK_QUEUEAC_HIQ_V1_8822B) \
+ << BIT_SHIFT_QUEUEAC_HIQ_V1_8822B)
+#define BIT_GET_QUEUEAC_HIQ_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_QUEUEAC_HIQ_V1_8822B) & \
+ BIT_MASK_QUEUEAC_HIQ_V1_8822B)
+
+#define BIT_TIDEMPTY_HIQ_V1_8822B BIT(22)
+
+#define BIT_SHIFT_TAIL_PKT_HIQ_V2_8822B 11
+#define BIT_MASK_TAIL_PKT_HIQ_V2_8822B 0x7ff
+#define BIT_TAIL_PKT_HIQ_V2_8822B(x) \
+ (((x) & BIT_MASK_TAIL_PKT_HIQ_V2_8822B) \
+ << BIT_SHIFT_TAIL_PKT_HIQ_V2_8822B)
+#define BIT_GET_TAIL_PKT_HIQ_V2_8822B(x) \
+ (((x) >> BIT_SHIFT_TAIL_PKT_HIQ_V2_8822B) & \
+ BIT_MASK_TAIL_PKT_HIQ_V2_8822B)
+
+#define BIT_SHIFT_HEAD_PKT_HIQ_V1_8822B 0
+#define BIT_MASK_HEAD_PKT_HIQ_V1_8822B 0x7ff
+#define BIT_HEAD_PKT_HIQ_V1_8822B(x) \
+ (((x) & BIT_MASK_HEAD_PKT_HIQ_V1_8822B) \
+ << BIT_SHIFT_HEAD_PKT_HIQ_V1_8822B)
+#define BIT_GET_HEAD_PKT_HIQ_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_HEAD_PKT_HIQ_V1_8822B) & \
+ BIT_MASK_HEAD_PKT_HIQ_V1_8822B)
+
+/* 2 REG_BCNQ_INFO_8822B */
+
+#define BIT_SHIFT_BCNQ_HEAD_PG_V1_8822B 0
+#define BIT_MASK_BCNQ_HEAD_PG_V1_8822B 0xfff
+#define BIT_BCNQ_HEAD_PG_V1_8822B(x) \
+ (((x) & BIT_MASK_BCNQ_HEAD_PG_V1_8822B) \
+ << BIT_SHIFT_BCNQ_HEAD_PG_V1_8822B)
+#define BIT_GET_BCNQ_HEAD_PG_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_BCNQ_HEAD_PG_V1_8822B) & \
+ BIT_MASK_BCNQ_HEAD_PG_V1_8822B)
+
+/* 2 REG_TXPKT_EMPTY_8822B */
+#define BIT_BCNQ_EMPTY_8822B BIT(11)
+#define BIT_HQQ_EMPTY_8822B BIT(10)
+#define BIT_MQQ_EMPTY_8822B BIT(9)
+#define BIT_MGQ_CPU_EMPTY_8822B BIT(8)
+#define BIT_AC7Q_EMPTY_8822B BIT(7)
+#define BIT_AC6Q_EMPTY_8822B BIT(6)
+#define BIT_AC5Q_EMPTY_8822B BIT(5)
+#define BIT_AC4Q_EMPTY_8822B BIT(4)
+#define BIT_AC3Q_EMPTY_8822B BIT(3)
+#define BIT_AC2Q_EMPTY_8822B BIT(2)
+#define BIT_AC1Q_EMPTY_8822B BIT(1)
+#define BIT_AC0Q_EMPTY_8822B BIT(0)
+
+/* 2 REG_CPU_MGQ_INFO_8822B */
+#define BIT_BCN1_POLL_8822B BIT(30)
+#define BIT_CPUMGT_POLL_8822B BIT(29)
+#define BIT_BCN_POLL_8822B BIT(28)
+#define BIT_CPUMGQ_FW_NUM_V1_8822B BIT(12)
+
+#define BIT_SHIFT_FW_FREE_TAIL_V1_8822B 0
+#define BIT_MASK_FW_FREE_TAIL_V1_8822B 0xfff
+#define BIT_FW_FREE_TAIL_V1_8822B(x) \
+ (((x) & BIT_MASK_FW_FREE_TAIL_V1_8822B) \
+ << BIT_SHIFT_FW_FREE_TAIL_V1_8822B)
+#define BIT_GET_FW_FREE_TAIL_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_FW_FREE_TAIL_V1_8822B) & \
+ BIT_MASK_FW_FREE_TAIL_V1_8822B)
+
+/* 2 REG_FWHW_TXQ_CTRL_8822B */
+#define BIT_RTS_LIMIT_IN_OFDM_8822B BIT(23)
+#define BIT_EN_BCNQ_DL_8822B BIT(22)
+#define BIT_EN_RD_RESP_NAV_BK_8822B BIT(21)
+#define BIT_EN_WR_FREE_TAIL_8822B BIT(20)
+
+#define BIT_SHIFT_EN_QUEUE_RPT_8822B 8
+#define BIT_MASK_EN_QUEUE_RPT_8822B 0xff
+#define BIT_EN_QUEUE_RPT_8822B(x) \
+ (((x) & BIT_MASK_EN_QUEUE_RPT_8822B) << BIT_SHIFT_EN_QUEUE_RPT_8822B)
+#define BIT_GET_EN_QUEUE_RPT_8822B(x) \
+ (((x) >> BIT_SHIFT_EN_QUEUE_RPT_8822B) & BIT_MASK_EN_QUEUE_RPT_8822B)
+
+#define BIT_EN_RTY_BK_8822B BIT(7)
+#define BIT_EN_USE_INI_RAT_8822B BIT(6)
+#define BIT_EN_RTS_NAV_BK_8822B BIT(5)
+#define BIT_DIS_SSN_CHECK_8822B BIT(4)
+#define BIT_MACID_MATCH_RTS_8822B BIT(3)
+#define BIT_EN_BCN_TRXRPT_V1_8822B BIT(2)
+#define BIT_EN_FTMACKRPT_8822B BIT(1)
+#define BIT_EN_FTMRPT_8822B BIT(0)
+
+/* 2 REG_DATAFB_SEL_8822B */
+#define BIT__R_EN_RTY_BK_COD_8822B BIT(2)
+
+#define BIT_SHIFT__R_DATA_FALLBACK_SEL_8822B 0
+#define BIT_MASK__R_DATA_FALLBACK_SEL_8822B 0x3
+#define BIT__R_DATA_FALLBACK_SEL_8822B(x) \
+ (((x) & BIT_MASK__R_DATA_FALLBACK_SEL_8822B) \
+ << BIT_SHIFT__R_DATA_FALLBACK_SEL_8822B)
+#define BIT_GET__R_DATA_FALLBACK_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT__R_DATA_FALLBACK_SEL_8822B) & \
+ BIT_MASK__R_DATA_FALLBACK_SEL_8822B)
+
+/* 2 REG_BCNQ_BDNY_V1_8822B */
+
+#define BIT_SHIFT_BCNQ_PGBNDY_V1_8822B 0
+#define BIT_MASK_BCNQ_PGBNDY_V1_8822B 0xfff
+#define BIT_BCNQ_PGBNDY_V1_8822B(x) \
+ (((x) & BIT_MASK_BCNQ_PGBNDY_V1_8822B) \
+ << BIT_SHIFT_BCNQ_PGBNDY_V1_8822B)
+#define BIT_GET_BCNQ_PGBNDY_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_BCNQ_PGBNDY_V1_8822B) & \
+ BIT_MASK_BCNQ_PGBNDY_V1_8822B)
+
+/* 2 REG_LIFETIME_EN_8822B */
+#define BIT_BT_INT_CPU_8822B BIT(7)
+#define BIT_BT_INT_PTA_8822B BIT(6)
+#define BIT_EN_CTRL_RTYBIT_8822B BIT(4)
+#define BIT_LIFETIME_BK_EN_8822B BIT(3)
+#define BIT_LIFETIME_BE_EN_8822B BIT(2)
+#define BIT_LIFETIME_VI_EN_8822B BIT(1)
+#define BIT_LIFETIME_VO_EN_8822B BIT(0)
+
+/* 2 REG_SPEC_SIFS_8822B */
+
+#define BIT_SHIFT_SPEC_SIFS_OFDM_PTCL_8822B 8
+#define BIT_MASK_SPEC_SIFS_OFDM_PTCL_8822B 0xff
+#define BIT_SPEC_SIFS_OFDM_PTCL_8822B(x) \
+ (((x) & BIT_MASK_SPEC_SIFS_OFDM_PTCL_8822B) \
+ << BIT_SHIFT_SPEC_SIFS_OFDM_PTCL_8822B)
+#define BIT_GET_SPEC_SIFS_OFDM_PTCL_8822B(x) \
+ (((x) >> BIT_SHIFT_SPEC_SIFS_OFDM_PTCL_8822B) & \
+ BIT_MASK_SPEC_SIFS_OFDM_PTCL_8822B)
+
+#define BIT_SHIFT_SPEC_SIFS_CCK_PTCL_8822B 0
+#define BIT_MASK_SPEC_SIFS_CCK_PTCL_8822B 0xff
+#define BIT_SPEC_SIFS_CCK_PTCL_8822B(x) \
+ (((x) & BIT_MASK_SPEC_SIFS_CCK_PTCL_8822B) \
+ << BIT_SHIFT_SPEC_SIFS_CCK_PTCL_8822B)
+#define BIT_GET_SPEC_SIFS_CCK_PTCL_8822B(x) \
+ (((x) >> BIT_SHIFT_SPEC_SIFS_CCK_PTCL_8822B) & \
+ BIT_MASK_SPEC_SIFS_CCK_PTCL_8822B)
+
+/* 2 REG_RETRY_LIMIT_8822B */
+
+#define BIT_SHIFT_SRL_8822B 8
+#define BIT_MASK_SRL_8822B 0x3f
+#define BIT_SRL_8822B(x) (((x) & BIT_MASK_SRL_8822B) << BIT_SHIFT_SRL_8822B)
+#define BIT_GET_SRL_8822B(x) (((x) >> BIT_SHIFT_SRL_8822B) & BIT_MASK_SRL_8822B)
+
+#define BIT_SHIFT_LRL_8822B 0
+#define BIT_MASK_LRL_8822B 0x3f
+#define BIT_LRL_8822B(x) (((x) & BIT_MASK_LRL_8822B) << BIT_SHIFT_LRL_8822B)
+#define BIT_GET_LRL_8822B(x) (((x) >> BIT_SHIFT_LRL_8822B) & BIT_MASK_LRL_8822B)
+
+/* 2 REG_TXBF_CTRL_8822B */
+#define BIT_R_ENABLE_NDPA_8822B BIT(31)
+#define BIT_USE_NDPA_PARAMETER_8822B BIT(30)
+#define BIT_R_PROP_TXBF_8822B BIT(29)
+#define BIT_R_EN_NDPA_INT_8822B BIT(28)
+#define BIT_R_TXBF1_80M_8822B BIT(27)
+#define BIT_R_TXBF1_40M_8822B BIT(26)
+#define BIT_R_TXBF1_20M_8822B BIT(25)
+
+#define BIT_SHIFT_R_TXBF1_AID_8822B 16
+#define BIT_MASK_R_TXBF1_AID_8822B 0x1ff
+#define BIT_R_TXBF1_AID_8822B(x) \
+ (((x) & BIT_MASK_R_TXBF1_AID_8822B) << BIT_SHIFT_R_TXBF1_AID_8822B)
+#define BIT_GET_R_TXBF1_AID_8822B(x) \
+ (((x) >> BIT_SHIFT_R_TXBF1_AID_8822B) & BIT_MASK_R_TXBF1_AID_8822B)
+
+#define BIT_DIS_NDP_BFEN_8822B BIT(15)
+#define BIT_R_TXBCN_NOBLOCK_NDP_8822B BIT(14)
+#define BIT_R_TXBF0_80M_8822B BIT(11)
+#define BIT_R_TXBF0_40M_8822B BIT(10)
+#define BIT_R_TXBF0_20M_8822B BIT(9)
+
+#define BIT_SHIFT_R_TXBF0_AID_8822B 0
+#define BIT_MASK_R_TXBF0_AID_8822B 0x1ff
+#define BIT_R_TXBF0_AID_8822B(x) \
+ (((x) & BIT_MASK_R_TXBF0_AID_8822B) << BIT_SHIFT_R_TXBF0_AID_8822B)
+#define BIT_GET_R_TXBF0_AID_8822B(x) \
+ (((x) >> BIT_SHIFT_R_TXBF0_AID_8822B) & BIT_MASK_R_TXBF0_AID_8822B)
+
+/* 2 REG_DARFRC_8822B */
+
+#define BIT_SHIFT_DARF_RC8_8822B (56 & CPU_OPT_WIDTH)
+#define BIT_MASK_DARF_RC8_8822B 0x1f
+#define BIT_DARF_RC8_8822B(x) \
+ (((x) & BIT_MASK_DARF_RC8_8822B) << BIT_SHIFT_DARF_RC8_8822B)
+#define BIT_GET_DARF_RC8_8822B(x) \
+ (((x) >> BIT_SHIFT_DARF_RC8_8822B) & BIT_MASK_DARF_RC8_8822B)
+
+#define BIT_SHIFT_DARF_RC7_8822B (48 & CPU_OPT_WIDTH)
+#define BIT_MASK_DARF_RC7_8822B 0x1f
+#define BIT_DARF_RC7_8822B(x) \
+ (((x) & BIT_MASK_DARF_RC7_8822B) << BIT_SHIFT_DARF_RC7_8822B)
+#define BIT_GET_DARF_RC7_8822B(x) \
+ (((x) >> BIT_SHIFT_DARF_RC7_8822B) & BIT_MASK_DARF_RC7_8822B)
+
+#define BIT_SHIFT_DARF_RC6_8822B (40 & CPU_OPT_WIDTH)
+#define BIT_MASK_DARF_RC6_8822B 0x1f
+#define BIT_DARF_RC6_8822B(x) \
+ (((x) & BIT_MASK_DARF_RC6_8822B) << BIT_SHIFT_DARF_RC6_8822B)
+#define BIT_GET_DARF_RC6_8822B(x) \
+ (((x) >> BIT_SHIFT_DARF_RC6_8822B) & BIT_MASK_DARF_RC6_8822B)
+
+#define BIT_SHIFT_DARF_RC5_8822B (32 & CPU_OPT_WIDTH)
+#define BIT_MASK_DARF_RC5_8822B 0x1f
+#define BIT_DARF_RC5_8822B(x) \
+ (((x) & BIT_MASK_DARF_RC5_8822B) << BIT_SHIFT_DARF_RC5_8822B)
+#define BIT_GET_DARF_RC5_8822B(x) \
+ (((x) >> BIT_SHIFT_DARF_RC5_8822B) & BIT_MASK_DARF_RC5_8822B)
+
+#define BIT_SHIFT_DARF_RC4_8822B 24
+#define BIT_MASK_DARF_RC4_8822B 0x1f
+#define BIT_DARF_RC4_8822B(x) \
+ (((x) & BIT_MASK_DARF_RC4_8822B) << BIT_SHIFT_DARF_RC4_8822B)
+#define BIT_GET_DARF_RC4_8822B(x) \
+ (((x) >> BIT_SHIFT_DARF_RC4_8822B) & BIT_MASK_DARF_RC4_8822B)
+
+#define BIT_SHIFT_DARF_RC3_8822B 16
+#define BIT_MASK_DARF_RC3_8822B 0x1f
+#define BIT_DARF_RC3_8822B(x) \
+ (((x) & BIT_MASK_DARF_RC3_8822B) << BIT_SHIFT_DARF_RC3_8822B)
+#define BIT_GET_DARF_RC3_8822B(x) \
+ (((x) >> BIT_SHIFT_DARF_RC3_8822B) & BIT_MASK_DARF_RC3_8822B)
+
+#define BIT_SHIFT_DARF_RC2_8822B 8
+#define BIT_MASK_DARF_RC2_8822B 0x1f
+#define BIT_DARF_RC2_8822B(x) \
+ (((x) & BIT_MASK_DARF_RC2_8822B) << BIT_SHIFT_DARF_RC2_8822B)
+#define BIT_GET_DARF_RC2_8822B(x) \
+ (((x) >> BIT_SHIFT_DARF_RC2_8822B) & BIT_MASK_DARF_RC2_8822B)
+
+#define BIT_SHIFT_DARF_RC1_8822B 0
+#define BIT_MASK_DARF_RC1_8822B 0x1f
+#define BIT_DARF_RC1_8822B(x) \
+ (((x) & BIT_MASK_DARF_RC1_8822B) << BIT_SHIFT_DARF_RC1_8822B)
+#define BIT_GET_DARF_RC1_8822B(x) \
+ (((x) >> BIT_SHIFT_DARF_RC1_8822B) & BIT_MASK_DARF_RC1_8822B)
+
+/* 2 REG_RARFRC_8822B */
+
+#define BIT_SHIFT_RARF_RC8_8822B (56 & CPU_OPT_WIDTH)
+#define BIT_MASK_RARF_RC8_8822B 0x1f
+#define BIT_RARF_RC8_8822B(x) \
+ (((x) & BIT_MASK_RARF_RC8_8822B) << BIT_SHIFT_RARF_RC8_8822B)
+#define BIT_GET_RARF_RC8_8822B(x) \
+ (((x) >> BIT_SHIFT_RARF_RC8_8822B) & BIT_MASK_RARF_RC8_8822B)
+
+#define BIT_SHIFT_RARF_RC7_8822B (48 & CPU_OPT_WIDTH)
+#define BIT_MASK_RARF_RC7_8822B 0x1f
+#define BIT_RARF_RC7_8822B(x) \
+ (((x) & BIT_MASK_RARF_RC7_8822B) << BIT_SHIFT_RARF_RC7_8822B)
+#define BIT_GET_RARF_RC7_8822B(x) \
+ (((x) >> BIT_SHIFT_RARF_RC7_8822B) & BIT_MASK_RARF_RC7_8822B)
+
+#define BIT_SHIFT_RARF_RC6_8822B (40 & CPU_OPT_WIDTH)
+#define BIT_MASK_RARF_RC6_8822B 0x1f
+#define BIT_RARF_RC6_8822B(x) \
+ (((x) & BIT_MASK_RARF_RC6_8822B) << BIT_SHIFT_RARF_RC6_8822B)
+#define BIT_GET_RARF_RC6_8822B(x) \
+ (((x) >> BIT_SHIFT_RARF_RC6_8822B) & BIT_MASK_RARF_RC6_8822B)
+
+#define BIT_SHIFT_RARF_RC5_8822B (32 & CPU_OPT_WIDTH)
+#define BIT_MASK_RARF_RC5_8822B 0x1f
+#define BIT_RARF_RC5_8822B(x) \
+ (((x) & BIT_MASK_RARF_RC5_8822B) << BIT_SHIFT_RARF_RC5_8822B)
+#define BIT_GET_RARF_RC5_8822B(x) \
+ (((x) >> BIT_SHIFT_RARF_RC5_8822B) & BIT_MASK_RARF_RC5_8822B)
+
+#define BIT_SHIFT_RARF_RC4_8822B 24
+#define BIT_MASK_RARF_RC4_8822B 0x1f
+#define BIT_RARF_RC4_8822B(x) \
+ (((x) & BIT_MASK_RARF_RC4_8822B) << BIT_SHIFT_RARF_RC4_8822B)
+#define BIT_GET_RARF_RC4_8822B(x) \
+ (((x) >> BIT_SHIFT_RARF_RC4_8822B) & BIT_MASK_RARF_RC4_8822B)
+
+#define BIT_SHIFT_RARF_RC3_8822B 16
+#define BIT_MASK_RARF_RC3_8822B 0x1f
+#define BIT_RARF_RC3_8822B(x) \
+ (((x) & BIT_MASK_RARF_RC3_8822B) << BIT_SHIFT_RARF_RC3_8822B)
+#define BIT_GET_RARF_RC3_8822B(x) \
+ (((x) >> BIT_SHIFT_RARF_RC3_8822B) & BIT_MASK_RARF_RC3_8822B)
+
+#define BIT_SHIFT_RARF_RC2_8822B 8
+#define BIT_MASK_RARF_RC2_8822B 0x1f
+#define BIT_RARF_RC2_8822B(x) \
+ (((x) & BIT_MASK_RARF_RC2_8822B) << BIT_SHIFT_RARF_RC2_8822B)
+#define BIT_GET_RARF_RC2_8822B(x) \
+ (((x) >> BIT_SHIFT_RARF_RC2_8822B) & BIT_MASK_RARF_RC2_8822B)
+
+#define BIT_SHIFT_RARF_RC1_8822B 0
+#define BIT_MASK_RARF_RC1_8822B 0x1f
+#define BIT_RARF_RC1_8822B(x) \
+ (((x) & BIT_MASK_RARF_RC1_8822B) << BIT_SHIFT_RARF_RC1_8822B)
+#define BIT_GET_RARF_RC1_8822B(x) \
+ (((x) >> BIT_SHIFT_RARF_RC1_8822B) & BIT_MASK_RARF_RC1_8822B)
+
+/* 2 REG_RRSR_8822B */
+
+#define BIT_SHIFT_RRSR_RSC_8822B 21
+#define BIT_MASK_RRSR_RSC_8822B 0x3
+#define BIT_RRSR_RSC_8822B(x) \
+ (((x) & BIT_MASK_RRSR_RSC_8822B) << BIT_SHIFT_RRSR_RSC_8822B)
+#define BIT_GET_RRSR_RSC_8822B(x) \
+ (((x) >> BIT_SHIFT_RRSR_RSC_8822B) & BIT_MASK_RRSR_RSC_8822B)
+
+#define BIT_RRSR_BW_8822B BIT(20)
+
+#define BIT_SHIFT_RRSC_BITMAP_8822B 0
+#define BIT_MASK_RRSC_BITMAP_8822B 0xfffff
+#define BIT_RRSC_BITMAP_8822B(x) \
+ (((x) & BIT_MASK_RRSC_BITMAP_8822B) << BIT_SHIFT_RRSC_BITMAP_8822B)
+#define BIT_GET_RRSC_BITMAP_8822B(x) \
+ (((x) >> BIT_SHIFT_RRSC_BITMAP_8822B) & BIT_MASK_RRSC_BITMAP_8822B)
+
+/* 2 REG_ARFR0_8822B */
+
+#define BIT_SHIFT_ARFR0_V1_8822B 0
+#define BIT_MASK_ARFR0_V1_8822B 0xffffffffffffffffL
+#define BIT_ARFR0_V1_8822B(x) \
+ (((x) & BIT_MASK_ARFR0_V1_8822B) << BIT_SHIFT_ARFR0_V1_8822B)
+#define BIT_GET_ARFR0_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_ARFR0_V1_8822B) & BIT_MASK_ARFR0_V1_8822B)
+
+/* 2 REG_ARFR1_V1_8822B */
+
+#define BIT_SHIFT_ARFR1_V1_8822B 0
+#define BIT_MASK_ARFR1_V1_8822B 0xffffffffffffffffL
+#define BIT_ARFR1_V1_8822B(x) \
+ (((x) & BIT_MASK_ARFR1_V1_8822B) << BIT_SHIFT_ARFR1_V1_8822B)
+#define BIT_GET_ARFR1_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_ARFR1_V1_8822B) & BIT_MASK_ARFR1_V1_8822B)
+
+/* 2 REG_CCK_CHECK_8822B */
+#define BIT_CHECK_CCK_EN_8822B BIT(7)
+#define BIT_EN_BCN_PKT_REL_8822B BIT(6)
+#define BIT_BCN_PORT_SEL_8822B BIT(5)
+#define BIT_MOREDATA_BYPASS_8822B BIT(4)
+#define BIT_EN_CLR_CMD_REL_BCN_PKT_8822B BIT(3)
+#define BIT_R_EN_SET_MOREDATA_8822B BIT(2)
+#define BIT__R_DIS_CLEAR_MACID_RELEASE_8822B BIT(1)
+#define BIT__R_MACID_RELEASE_EN_8822B BIT(0)
+
+/* 2 REG_AMPDU_MAX_TIME_V1_8822B */
+
+#define BIT_SHIFT_AMPDU_MAX_TIME_8822B 0
+#define BIT_MASK_AMPDU_MAX_TIME_8822B 0xff
+#define BIT_AMPDU_MAX_TIME_8822B(x) \
+ (((x) & BIT_MASK_AMPDU_MAX_TIME_8822B) \
+ << BIT_SHIFT_AMPDU_MAX_TIME_8822B)
+#define BIT_GET_AMPDU_MAX_TIME_8822B(x) \
+ (((x) >> BIT_SHIFT_AMPDU_MAX_TIME_8822B) & \
+ BIT_MASK_AMPDU_MAX_TIME_8822B)
+
+/* 2 REG_BCNQ1_BDNY_V1_8822B */
+
+#define BIT_SHIFT_BCNQ1_PGBNDY_V1_8822B 0
+#define BIT_MASK_BCNQ1_PGBNDY_V1_8822B 0xfff
+#define BIT_BCNQ1_PGBNDY_V1_8822B(x) \
+ (((x) & BIT_MASK_BCNQ1_PGBNDY_V1_8822B) \
+ << BIT_SHIFT_BCNQ1_PGBNDY_V1_8822B)
+#define BIT_GET_BCNQ1_PGBNDY_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_BCNQ1_PGBNDY_V1_8822B) & \
+ BIT_MASK_BCNQ1_PGBNDY_V1_8822B)
+
+/* 2 REG_AMPDU_MAX_LENGTH_8822B */
+
+#define BIT_SHIFT_AMPDU_MAX_LENGTH_8822B 0
+#define BIT_MASK_AMPDU_MAX_LENGTH_8822B 0xffffffffL
+#define BIT_AMPDU_MAX_LENGTH_8822B(x) \
+ (((x) & BIT_MASK_AMPDU_MAX_LENGTH_8822B) \
+ << BIT_SHIFT_AMPDU_MAX_LENGTH_8822B)
+#define BIT_GET_AMPDU_MAX_LENGTH_8822B(x) \
+ (((x) >> BIT_SHIFT_AMPDU_MAX_LENGTH_8822B) & \
+ BIT_MASK_AMPDU_MAX_LENGTH_8822B)
+
+/* 2 REG_ACQ_STOP_8822B */
+#define BIT_AC7Q_STOP_8822B BIT(7)
+#define BIT_AC6Q_STOP_8822B BIT(6)
+#define BIT_AC5Q_STOP_8822B BIT(5)
+#define BIT_AC4Q_STOP_8822B BIT(4)
+#define BIT_AC3Q_STOP_8822B BIT(3)
+#define BIT_AC2Q_STOP_8822B BIT(2)
+#define BIT_AC1Q_STOP_8822B BIT(1)
+#define BIT_AC0Q_STOP_8822B BIT(0)
+
+/* 2 REG_NDPA_RATE_8822B */
+
+#define BIT_SHIFT_R_NDPA_RATE_V1_8822B 0
+#define BIT_MASK_R_NDPA_RATE_V1_8822B 0xff
+#define BIT_R_NDPA_RATE_V1_8822B(x) \
+ (((x) & BIT_MASK_R_NDPA_RATE_V1_8822B) \
+ << BIT_SHIFT_R_NDPA_RATE_V1_8822B)
+#define BIT_GET_R_NDPA_RATE_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_R_NDPA_RATE_V1_8822B) & \
+ BIT_MASK_R_NDPA_RATE_V1_8822B)
+
+/* 2 REG_TX_HANG_CTRL_8822B */
+#define BIT_R_EN_GNT_BT_AWAKE_8822B BIT(3)
+#define BIT_EN_EOF_V1_8822B BIT(2)
+#define BIT_DIS_OQT_BLOCK_8822B BIT(1)
+#define BIT_SEARCH_QUEUE_EN_8822B BIT(0)
+
+/* 2 REG_NDPA_OPT_CTRL_8822B */
+#define BIT_R_DIS_MACID_RELEASE_RTY_8822B BIT(5)
+
+#define BIT_SHIFT_BW_SIGTA_8822B 3
+#define BIT_MASK_BW_SIGTA_8822B 0x3
+#define BIT_BW_SIGTA_8822B(x) \
+ (((x) & BIT_MASK_BW_SIGTA_8822B) << BIT_SHIFT_BW_SIGTA_8822B)
+#define BIT_GET_BW_SIGTA_8822B(x) \
+ (((x) >> BIT_SHIFT_BW_SIGTA_8822B) & BIT_MASK_BW_SIGTA_8822B)
+
+#define BIT_EN_BAR_SIGTA_8822B BIT(2)
+
+#define BIT_SHIFT_R_NDPA_BW_8822B 0
+#define BIT_MASK_R_NDPA_BW_8822B 0x3
+#define BIT_R_NDPA_BW_8822B(x) \
+ (((x) & BIT_MASK_R_NDPA_BW_8822B) << BIT_SHIFT_R_NDPA_BW_8822B)
+#define BIT_GET_R_NDPA_BW_8822B(x) \
+ (((x) >> BIT_SHIFT_R_NDPA_BW_8822B) & BIT_MASK_R_NDPA_BW_8822B)
+
+/* 2 REG_RD_RESP_PKT_TH_8822B */
+
+#define BIT_SHIFT_RD_RESP_PKT_TH_V1_8822B 0
+#define BIT_MASK_RD_RESP_PKT_TH_V1_8822B 0x3f
+#define BIT_RD_RESP_PKT_TH_V1_8822B(x) \
+ (((x) & BIT_MASK_RD_RESP_PKT_TH_V1_8822B) \
+ << BIT_SHIFT_RD_RESP_PKT_TH_V1_8822B)
+#define BIT_GET_RD_RESP_PKT_TH_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_RD_RESP_PKT_TH_V1_8822B) & \
+ BIT_MASK_RD_RESP_PKT_TH_V1_8822B)
+
+/* 2 REG_CMDQ_INFO_8822B */
+
+#define BIT_SHIFT_QUEUEMACID_CMDQ_V1_8822B 25
+#define BIT_MASK_QUEUEMACID_CMDQ_V1_8822B 0x7f
+#define BIT_QUEUEMACID_CMDQ_V1_8822B(x) \
+ (((x) & BIT_MASK_QUEUEMACID_CMDQ_V1_8822B) \
+ << BIT_SHIFT_QUEUEMACID_CMDQ_V1_8822B)
+#define BIT_GET_QUEUEMACID_CMDQ_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_QUEUEMACID_CMDQ_V1_8822B) & \
+ BIT_MASK_QUEUEMACID_CMDQ_V1_8822B)
+
+#define BIT_SHIFT_QUEUEAC_CMDQ_V1_8822B 23
+#define BIT_MASK_QUEUEAC_CMDQ_V1_8822B 0x3
+#define BIT_QUEUEAC_CMDQ_V1_8822B(x) \
+ (((x) & BIT_MASK_QUEUEAC_CMDQ_V1_8822B) \
+ << BIT_SHIFT_QUEUEAC_CMDQ_V1_8822B)
+#define BIT_GET_QUEUEAC_CMDQ_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_QUEUEAC_CMDQ_V1_8822B) & \
+ BIT_MASK_QUEUEAC_CMDQ_V1_8822B)
+
+#define BIT_TIDEMPTY_CMDQ_V1_8822B BIT(22)
+
+#define BIT_SHIFT_TAIL_PKT_CMDQ_V2_8822B 11
+#define BIT_MASK_TAIL_PKT_CMDQ_V2_8822B 0x7ff
+#define BIT_TAIL_PKT_CMDQ_V2_8822B(x) \
+ (((x) & BIT_MASK_TAIL_PKT_CMDQ_V2_8822B) \
+ << BIT_SHIFT_TAIL_PKT_CMDQ_V2_8822B)
+#define BIT_GET_TAIL_PKT_CMDQ_V2_8822B(x) \
+ (((x) >> BIT_SHIFT_TAIL_PKT_CMDQ_V2_8822B) & \
+ BIT_MASK_TAIL_PKT_CMDQ_V2_8822B)
+
+#define BIT_SHIFT_HEAD_PKT_CMDQ_V1_8822B 0
+#define BIT_MASK_HEAD_PKT_CMDQ_V1_8822B 0x7ff
+#define BIT_HEAD_PKT_CMDQ_V1_8822B(x) \
+ (((x) & BIT_MASK_HEAD_PKT_CMDQ_V1_8822B) \
+ << BIT_SHIFT_HEAD_PKT_CMDQ_V1_8822B)
+#define BIT_GET_HEAD_PKT_CMDQ_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_HEAD_PKT_CMDQ_V1_8822B) & \
+ BIT_MASK_HEAD_PKT_CMDQ_V1_8822B)
+
+/* 2 REG_Q4_INFO_8822B */
+
+#define BIT_SHIFT_QUEUEMACID_Q4_V1_8822B 25
+#define BIT_MASK_QUEUEMACID_Q4_V1_8822B 0x7f
+#define BIT_QUEUEMACID_Q4_V1_8822B(x) \
+ (((x) & BIT_MASK_QUEUEMACID_Q4_V1_8822B) \
+ << BIT_SHIFT_QUEUEMACID_Q4_V1_8822B)
+#define BIT_GET_QUEUEMACID_Q4_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_QUEUEMACID_Q4_V1_8822B) & \
+ BIT_MASK_QUEUEMACID_Q4_V1_8822B)
+
+#define BIT_SHIFT_QUEUEAC_Q4_V1_8822B 23
+#define BIT_MASK_QUEUEAC_Q4_V1_8822B 0x3
+#define BIT_QUEUEAC_Q4_V1_8822B(x) \
+ (((x) & BIT_MASK_QUEUEAC_Q4_V1_8822B) << BIT_SHIFT_QUEUEAC_Q4_V1_8822B)
+#define BIT_GET_QUEUEAC_Q4_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_QUEUEAC_Q4_V1_8822B) & BIT_MASK_QUEUEAC_Q4_V1_8822B)
+
+#define BIT_TIDEMPTY_Q4_V1_8822B BIT(22)
+
+#define BIT_SHIFT_TAIL_PKT_Q4_V2_8822B 11
+#define BIT_MASK_TAIL_PKT_Q4_V2_8822B 0x7ff
+#define BIT_TAIL_PKT_Q4_V2_8822B(x) \
+ (((x) & BIT_MASK_TAIL_PKT_Q4_V2_8822B) \
+ << BIT_SHIFT_TAIL_PKT_Q4_V2_8822B)
+#define BIT_GET_TAIL_PKT_Q4_V2_8822B(x) \
+ (((x) >> BIT_SHIFT_TAIL_PKT_Q4_V2_8822B) & \
+ BIT_MASK_TAIL_PKT_Q4_V2_8822B)
+
+#define BIT_SHIFT_HEAD_PKT_Q4_V1_8822B 0
+#define BIT_MASK_HEAD_PKT_Q4_V1_8822B 0x7ff
+#define BIT_HEAD_PKT_Q4_V1_8822B(x) \
+ (((x) & BIT_MASK_HEAD_PKT_Q4_V1_8822B) \
+ << BIT_SHIFT_HEAD_PKT_Q4_V1_8822B)
+#define BIT_GET_HEAD_PKT_Q4_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_HEAD_PKT_Q4_V1_8822B) & \
+ BIT_MASK_HEAD_PKT_Q4_V1_8822B)
+
+/* 2 REG_Q5_INFO_8822B */
+
+#define BIT_SHIFT_QUEUEMACID_Q5_V1_8822B 25
+#define BIT_MASK_QUEUEMACID_Q5_V1_8822B 0x7f
+#define BIT_QUEUEMACID_Q5_V1_8822B(x) \
+ (((x) & BIT_MASK_QUEUEMACID_Q5_V1_8822B) \
+ << BIT_SHIFT_QUEUEMACID_Q5_V1_8822B)
+#define BIT_GET_QUEUEMACID_Q5_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_QUEUEMACID_Q5_V1_8822B) & \
+ BIT_MASK_QUEUEMACID_Q5_V1_8822B)
+
+#define BIT_SHIFT_QUEUEAC_Q5_V1_8822B 23
+#define BIT_MASK_QUEUEAC_Q5_V1_8822B 0x3
+#define BIT_QUEUEAC_Q5_V1_8822B(x) \
+ (((x) & BIT_MASK_QUEUEAC_Q5_V1_8822B) << BIT_SHIFT_QUEUEAC_Q5_V1_8822B)
+#define BIT_GET_QUEUEAC_Q5_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_QUEUEAC_Q5_V1_8822B) & BIT_MASK_QUEUEAC_Q5_V1_8822B)
+
+#define BIT_TIDEMPTY_Q5_V1_8822B BIT(22)
+
+#define BIT_SHIFT_TAIL_PKT_Q5_V2_8822B 11
+#define BIT_MASK_TAIL_PKT_Q5_V2_8822B 0x7ff
+#define BIT_TAIL_PKT_Q5_V2_8822B(x) \
+ (((x) & BIT_MASK_TAIL_PKT_Q5_V2_8822B) \
+ << BIT_SHIFT_TAIL_PKT_Q5_V2_8822B)
+#define BIT_GET_TAIL_PKT_Q5_V2_8822B(x) \
+ (((x) >> BIT_SHIFT_TAIL_PKT_Q5_V2_8822B) & \
+ BIT_MASK_TAIL_PKT_Q5_V2_8822B)
+
+#define BIT_SHIFT_HEAD_PKT_Q5_V1_8822B 0
+#define BIT_MASK_HEAD_PKT_Q5_V1_8822B 0x7ff
+#define BIT_HEAD_PKT_Q5_V1_8822B(x) \
+ (((x) & BIT_MASK_HEAD_PKT_Q5_V1_8822B) \
+ << BIT_SHIFT_HEAD_PKT_Q5_V1_8822B)
+#define BIT_GET_HEAD_PKT_Q5_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_HEAD_PKT_Q5_V1_8822B) & \
+ BIT_MASK_HEAD_PKT_Q5_V1_8822B)
+
+/* 2 REG_Q6_INFO_8822B */
+
+#define BIT_SHIFT_QUEUEMACID_Q6_V1_8822B 25
+#define BIT_MASK_QUEUEMACID_Q6_V1_8822B 0x7f
+#define BIT_QUEUEMACID_Q6_V1_8822B(x) \
+ (((x) & BIT_MASK_QUEUEMACID_Q6_V1_8822B) \
+ << BIT_SHIFT_QUEUEMACID_Q6_V1_8822B)
+#define BIT_GET_QUEUEMACID_Q6_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_QUEUEMACID_Q6_V1_8822B) & \
+ BIT_MASK_QUEUEMACID_Q6_V1_8822B)
+
+#define BIT_SHIFT_QUEUEAC_Q6_V1_8822B 23
+#define BIT_MASK_QUEUEAC_Q6_V1_8822B 0x3
+#define BIT_QUEUEAC_Q6_V1_8822B(x) \
+ (((x) & BIT_MASK_QUEUEAC_Q6_V1_8822B) << BIT_SHIFT_QUEUEAC_Q6_V1_8822B)
+#define BIT_GET_QUEUEAC_Q6_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_QUEUEAC_Q6_V1_8822B) & BIT_MASK_QUEUEAC_Q6_V1_8822B)
+
+#define BIT_TIDEMPTY_Q6_V1_8822B BIT(22)
+
+#define BIT_SHIFT_TAIL_PKT_Q6_V2_8822B 11
+#define BIT_MASK_TAIL_PKT_Q6_V2_8822B 0x7ff
+#define BIT_TAIL_PKT_Q6_V2_8822B(x) \
+ (((x) & BIT_MASK_TAIL_PKT_Q6_V2_8822B) \
+ << BIT_SHIFT_TAIL_PKT_Q6_V2_8822B)
+#define BIT_GET_TAIL_PKT_Q6_V2_8822B(x) \
+ (((x) >> BIT_SHIFT_TAIL_PKT_Q6_V2_8822B) & \
+ BIT_MASK_TAIL_PKT_Q6_V2_8822B)
+
+#define BIT_SHIFT_HEAD_PKT_Q6_V1_8822B 0
+#define BIT_MASK_HEAD_PKT_Q6_V1_8822B 0x7ff
+#define BIT_HEAD_PKT_Q6_V1_8822B(x) \
+ (((x) & BIT_MASK_HEAD_PKT_Q6_V1_8822B) \
+ << BIT_SHIFT_HEAD_PKT_Q6_V1_8822B)
+#define BIT_GET_HEAD_PKT_Q6_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_HEAD_PKT_Q6_V1_8822B) & \
+ BIT_MASK_HEAD_PKT_Q6_V1_8822B)
+
+/* 2 REG_Q7_INFO_8822B */
+
+#define BIT_SHIFT_QUEUEMACID_Q7_V1_8822B 25
+#define BIT_MASK_QUEUEMACID_Q7_V1_8822B 0x7f
+#define BIT_QUEUEMACID_Q7_V1_8822B(x) \
+ (((x) & BIT_MASK_QUEUEMACID_Q7_V1_8822B) \
+ << BIT_SHIFT_QUEUEMACID_Q7_V1_8822B)
+#define BIT_GET_QUEUEMACID_Q7_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_QUEUEMACID_Q7_V1_8822B) & \
+ BIT_MASK_QUEUEMACID_Q7_V1_8822B)
+
+#define BIT_SHIFT_QUEUEAC_Q7_V1_8822B 23
+#define BIT_MASK_QUEUEAC_Q7_V1_8822B 0x3
+#define BIT_QUEUEAC_Q7_V1_8822B(x) \
+ (((x) & BIT_MASK_QUEUEAC_Q7_V1_8822B) << BIT_SHIFT_QUEUEAC_Q7_V1_8822B)
+#define BIT_GET_QUEUEAC_Q7_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_QUEUEAC_Q7_V1_8822B) & BIT_MASK_QUEUEAC_Q7_V1_8822B)
+
+#define BIT_TIDEMPTY_Q7_V1_8822B BIT(22)
+
+#define BIT_SHIFT_TAIL_PKT_Q7_V2_8822B 11
+#define BIT_MASK_TAIL_PKT_Q7_V2_8822B 0x7ff
+#define BIT_TAIL_PKT_Q7_V2_8822B(x) \
+ (((x) & BIT_MASK_TAIL_PKT_Q7_V2_8822B) \
+ << BIT_SHIFT_TAIL_PKT_Q7_V2_8822B)
+#define BIT_GET_TAIL_PKT_Q7_V2_8822B(x) \
+ (((x) >> BIT_SHIFT_TAIL_PKT_Q7_V2_8822B) & \
+ BIT_MASK_TAIL_PKT_Q7_V2_8822B)
+
+#define BIT_SHIFT_HEAD_PKT_Q7_V1_8822B 0
+#define BIT_MASK_HEAD_PKT_Q7_V1_8822B 0x7ff
+#define BIT_HEAD_PKT_Q7_V1_8822B(x) \
+ (((x) & BIT_MASK_HEAD_PKT_Q7_V1_8822B) \
+ << BIT_SHIFT_HEAD_PKT_Q7_V1_8822B)
+#define BIT_GET_HEAD_PKT_Q7_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_HEAD_PKT_Q7_V1_8822B) & \
+ BIT_MASK_HEAD_PKT_Q7_V1_8822B)
+
+/* 2 REG_WMAC_LBK_BUF_HD_V1_8822B */
+
+#define BIT_SHIFT_WMAC_LBK_BUF_HEAD_V1_8822B 0
+#define BIT_MASK_WMAC_LBK_BUF_HEAD_V1_8822B 0xfff
+#define BIT_WMAC_LBK_BUF_HEAD_V1_8822B(x) \
+ (((x) & BIT_MASK_WMAC_LBK_BUF_HEAD_V1_8822B) \
+ << BIT_SHIFT_WMAC_LBK_BUF_HEAD_V1_8822B)
+#define BIT_GET_WMAC_LBK_BUF_HEAD_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_LBK_BUF_HEAD_V1_8822B) & \
+ BIT_MASK_WMAC_LBK_BUF_HEAD_V1_8822B)
+
+/* 2 REG_MGQ_BDNY_V1_8822B */
+
+#define BIT_SHIFT_MGQ_PGBNDY_V1_8822B 0
+#define BIT_MASK_MGQ_PGBNDY_V1_8822B 0xfff
+#define BIT_MGQ_PGBNDY_V1_8822B(x) \
+ (((x) & BIT_MASK_MGQ_PGBNDY_V1_8822B) << BIT_SHIFT_MGQ_PGBNDY_V1_8822B)
+#define BIT_GET_MGQ_PGBNDY_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_MGQ_PGBNDY_V1_8822B) & BIT_MASK_MGQ_PGBNDY_V1_8822B)
+
+/* 2 REG_TXRPT_CTRL_8822B */
+
+#define BIT_SHIFT_TRXRPT_TIMER_TH_8822B 24
+#define BIT_MASK_TRXRPT_TIMER_TH_8822B 0xff
+#define BIT_TRXRPT_TIMER_TH_8822B(x) \
+ (((x) & BIT_MASK_TRXRPT_TIMER_TH_8822B) \
+ << BIT_SHIFT_TRXRPT_TIMER_TH_8822B)
+#define BIT_GET_TRXRPT_TIMER_TH_8822B(x) \
+ (((x) >> BIT_SHIFT_TRXRPT_TIMER_TH_8822B) & \
+ BIT_MASK_TRXRPT_TIMER_TH_8822B)
+
+#define BIT_SHIFT_TRXRPT_LEN_TH_8822B 16
+#define BIT_MASK_TRXRPT_LEN_TH_8822B 0xff
+#define BIT_TRXRPT_LEN_TH_8822B(x) \
+ (((x) & BIT_MASK_TRXRPT_LEN_TH_8822B) << BIT_SHIFT_TRXRPT_LEN_TH_8822B)
+#define BIT_GET_TRXRPT_LEN_TH_8822B(x) \
+ (((x) >> BIT_SHIFT_TRXRPT_LEN_TH_8822B) & BIT_MASK_TRXRPT_LEN_TH_8822B)
+
+#define BIT_SHIFT_TRXRPT_READ_PTR_8822B 8
+#define BIT_MASK_TRXRPT_READ_PTR_8822B 0xff
+#define BIT_TRXRPT_READ_PTR_8822B(x) \
+ (((x) & BIT_MASK_TRXRPT_READ_PTR_8822B) \
+ << BIT_SHIFT_TRXRPT_READ_PTR_8822B)
+#define BIT_GET_TRXRPT_READ_PTR_8822B(x) \
+ (((x) >> BIT_SHIFT_TRXRPT_READ_PTR_8822B) & \
+ BIT_MASK_TRXRPT_READ_PTR_8822B)
+
+#define BIT_SHIFT_TRXRPT_WRITE_PTR_8822B 0
+#define BIT_MASK_TRXRPT_WRITE_PTR_8822B 0xff
+#define BIT_TRXRPT_WRITE_PTR_8822B(x) \
+ (((x) & BIT_MASK_TRXRPT_WRITE_PTR_8822B) \
+ << BIT_SHIFT_TRXRPT_WRITE_PTR_8822B)
+#define BIT_GET_TRXRPT_WRITE_PTR_8822B(x) \
+ (((x) >> BIT_SHIFT_TRXRPT_WRITE_PTR_8822B) & \
+ BIT_MASK_TRXRPT_WRITE_PTR_8822B)
+
+/* 2 REG_INIRTS_RATE_SEL_8822B */
+#define BIT_LEAG_RTS_BW_DUP_8822B BIT(5)
+
+/* 2 REG_BASIC_CFEND_RATE_8822B */
+
+#define BIT_SHIFT_BASIC_CFEND_RATE_8822B 0
+#define BIT_MASK_BASIC_CFEND_RATE_8822B 0x1f
+#define BIT_BASIC_CFEND_RATE_8822B(x) \
+ (((x) & BIT_MASK_BASIC_CFEND_RATE_8822B) \
+ << BIT_SHIFT_BASIC_CFEND_RATE_8822B)
+#define BIT_GET_BASIC_CFEND_RATE_8822B(x) \
+ (((x) >> BIT_SHIFT_BASIC_CFEND_RATE_8822B) & \
+ BIT_MASK_BASIC_CFEND_RATE_8822B)
+
+/* 2 REG_STBC_CFEND_RATE_8822B */
+
+#define BIT_SHIFT_STBC_CFEND_RATE_8822B 0
+#define BIT_MASK_STBC_CFEND_RATE_8822B 0x1f
+#define BIT_STBC_CFEND_RATE_8822B(x) \
+ (((x) & BIT_MASK_STBC_CFEND_RATE_8822B) \
+ << BIT_SHIFT_STBC_CFEND_RATE_8822B)
+#define BIT_GET_STBC_CFEND_RATE_8822B(x) \
+ (((x) >> BIT_SHIFT_STBC_CFEND_RATE_8822B) & \
+ BIT_MASK_STBC_CFEND_RATE_8822B)
+
+/* 2 REG_DATA_SC_8822B */
+
+#define BIT_SHIFT_TXSC_40M_8822B 4
+#define BIT_MASK_TXSC_40M_8822B 0xf
+#define BIT_TXSC_40M_8822B(x) \
+ (((x) & BIT_MASK_TXSC_40M_8822B) << BIT_SHIFT_TXSC_40M_8822B)
+#define BIT_GET_TXSC_40M_8822B(x) \
+ (((x) >> BIT_SHIFT_TXSC_40M_8822B) & BIT_MASK_TXSC_40M_8822B)
+
+#define BIT_SHIFT_TXSC_20M_8822B 0
+#define BIT_MASK_TXSC_20M_8822B 0xf
+#define BIT_TXSC_20M_8822B(x) \
+ (((x) & BIT_MASK_TXSC_20M_8822B) << BIT_SHIFT_TXSC_20M_8822B)
+#define BIT_GET_TXSC_20M_8822B(x) \
+ (((x) >> BIT_SHIFT_TXSC_20M_8822B) & BIT_MASK_TXSC_20M_8822B)
+
+/* 2 REG_MACID_SLEEP3_8822B */
+
+#define BIT_SHIFT_MACID127_96_PKTSLEEP_8822B 0
+#define BIT_MASK_MACID127_96_PKTSLEEP_8822B 0xffffffffL
+#define BIT_MACID127_96_PKTSLEEP_8822B(x) \
+ (((x) & BIT_MASK_MACID127_96_PKTSLEEP_8822B) \
+ << BIT_SHIFT_MACID127_96_PKTSLEEP_8822B)
+#define BIT_GET_MACID127_96_PKTSLEEP_8822B(x) \
+ (((x) >> BIT_SHIFT_MACID127_96_PKTSLEEP_8822B) & \
+ BIT_MASK_MACID127_96_PKTSLEEP_8822B)
+
+/* 2 REG_MACID_SLEEP1_8822B */
+
+#define BIT_SHIFT_MACID63_32_PKTSLEEP_8822B 0
+#define BIT_MASK_MACID63_32_PKTSLEEP_8822B 0xffffffffL
+#define BIT_MACID63_32_PKTSLEEP_8822B(x) \
+ (((x) & BIT_MASK_MACID63_32_PKTSLEEP_8822B) \
+ << BIT_SHIFT_MACID63_32_PKTSLEEP_8822B)
+#define BIT_GET_MACID63_32_PKTSLEEP_8822B(x) \
+ (((x) >> BIT_SHIFT_MACID63_32_PKTSLEEP_8822B) & \
+ BIT_MASK_MACID63_32_PKTSLEEP_8822B)
+
+/* 2 REG_ARFR2_V1_8822B */
+
+#define BIT_SHIFT_ARFR2_V1_8822B 0
+#define BIT_MASK_ARFR2_V1_8822B 0xffffffffffffffffL
+#define BIT_ARFR2_V1_8822B(x) \
+ (((x) & BIT_MASK_ARFR2_V1_8822B) << BIT_SHIFT_ARFR2_V1_8822B)
+#define BIT_GET_ARFR2_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_ARFR2_V1_8822B) & BIT_MASK_ARFR2_V1_8822B)
+
+/* 2 REG_ARFR3_V1_8822B */
+
+#define BIT_SHIFT_ARFR3_V1_8822B 0
+#define BIT_MASK_ARFR3_V1_8822B 0xffffffffffffffffL
+#define BIT_ARFR3_V1_8822B(x) \
+ (((x) & BIT_MASK_ARFR3_V1_8822B) << BIT_SHIFT_ARFR3_V1_8822B)
+#define BIT_GET_ARFR3_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_ARFR3_V1_8822B) & BIT_MASK_ARFR3_V1_8822B)
+
+/* 2 REG_ARFR4_8822B */
+
+#define BIT_SHIFT_ARFR4_8822B 0
+#define BIT_MASK_ARFR4_8822B 0xffffffffffffffffL
+#define BIT_ARFR4_8822B(x) \
+ (((x) & BIT_MASK_ARFR4_8822B) << BIT_SHIFT_ARFR4_8822B)
+#define BIT_GET_ARFR4_8822B(x) \
+ (((x) >> BIT_SHIFT_ARFR4_8822B) & BIT_MASK_ARFR4_8822B)
+
+/* 2 REG_ARFR5_8822B */
+
+#define BIT_SHIFT_ARFR5_8822B 0
+#define BIT_MASK_ARFR5_8822B 0xffffffffffffffffL
+#define BIT_ARFR5_8822B(x) \
+ (((x) & BIT_MASK_ARFR5_8822B) << BIT_SHIFT_ARFR5_8822B)
+#define BIT_GET_ARFR5_8822B(x) \
+ (((x) >> BIT_SHIFT_ARFR5_8822B) & BIT_MASK_ARFR5_8822B)
+
+/* 2 REG_TXRPT_START_OFFSET_8822B */
+
+#define BIT_SHIFT_MACID_MURATE_OFFSET_8822B 24
+#define BIT_MASK_MACID_MURATE_OFFSET_8822B 0xff
+#define BIT_MACID_MURATE_OFFSET_8822B(x) \
+ (((x) & BIT_MASK_MACID_MURATE_OFFSET_8822B) \
+ << BIT_SHIFT_MACID_MURATE_OFFSET_8822B)
+#define BIT_GET_MACID_MURATE_OFFSET_8822B(x) \
+ (((x) >> BIT_SHIFT_MACID_MURATE_OFFSET_8822B) & \
+ BIT_MASK_MACID_MURATE_OFFSET_8822B)
+
+#define BIT_RPTFIFO_SIZE_OPT_8822B BIT(16)
+
+#define BIT_SHIFT_MACID_CTRL_OFFSET_8822B 8
+#define BIT_MASK_MACID_CTRL_OFFSET_8822B 0xff
+#define BIT_MACID_CTRL_OFFSET_8822B(x) \
+ (((x) & BIT_MASK_MACID_CTRL_OFFSET_8822B) \
+ << BIT_SHIFT_MACID_CTRL_OFFSET_8822B)
+#define BIT_GET_MACID_CTRL_OFFSET_8822B(x) \
+ (((x) >> BIT_SHIFT_MACID_CTRL_OFFSET_8822B) & \
+ BIT_MASK_MACID_CTRL_OFFSET_8822B)
+
+#define BIT_SHIFT_AMPDU_TXRPT_OFFSET_8822B 0
+#define BIT_MASK_AMPDU_TXRPT_OFFSET_8822B 0xff
+#define BIT_AMPDU_TXRPT_OFFSET_8822B(x) \
+ (((x) & BIT_MASK_AMPDU_TXRPT_OFFSET_8822B) \
+ << BIT_SHIFT_AMPDU_TXRPT_OFFSET_8822B)
+#define BIT_GET_AMPDU_TXRPT_OFFSET_8822B(x) \
+ (((x) >> BIT_SHIFT_AMPDU_TXRPT_OFFSET_8822B) & \
+ BIT_MASK_AMPDU_TXRPT_OFFSET_8822B)
+
+/* 2 REG_POWER_STAGE1_8822B */
+#define BIT_PTA_WL_PRI_MASK_CPU_MGQ_8822B BIT(31)
+#define BIT_PTA_WL_PRI_MASK_BCNQ_8822B BIT(30)
+#define BIT_PTA_WL_PRI_MASK_HIQ_8822B BIT(29)
+#define BIT_PTA_WL_PRI_MASK_MGQ_8822B BIT(28)
+#define BIT_PTA_WL_PRI_MASK_BK_8822B BIT(27)
+#define BIT_PTA_WL_PRI_MASK_BE_8822B BIT(26)
+#define BIT_PTA_WL_PRI_MASK_VI_8822B BIT(25)
+#define BIT_PTA_WL_PRI_MASK_VO_8822B BIT(24)
+
+#define BIT_SHIFT_POWER_STAGE1_8822B 0
+#define BIT_MASK_POWER_STAGE1_8822B 0xffffff
+#define BIT_POWER_STAGE1_8822B(x) \
+ (((x) & BIT_MASK_POWER_STAGE1_8822B) << BIT_SHIFT_POWER_STAGE1_8822B)
+#define BIT_GET_POWER_STAGE1_8822B(x) \
+ (((x) >> BIT_SHIFT_POWER_STAGE1_8822B) & BIT_MASK_POWER_STAGE1_8822B)
+
+/* 2 REG_POWER_STAGE2_8822B */
+#define BIT__R_CTRL_PKT_POW_ADJ_8822B BIT(24)
+
+#define BIT_SHIFT_POWER_STAGE2_8822B 0
+#define BIT_MASK_POWER_STAGE2_8822B 0xffffff
+#define BIT_POWER_STAGE2_8822B(x) \
+ (((x) & BIT_MASK_POWER_STAGE2_8822B) << BIT_SHIFT_POWER_STAGE2_8822B)
+#define BIT_GET_POWER_STAGE2_8822B(x) \
+ (((x) >> BIT_SHIFT_POWER_STAGE2_8822B) & BIT_MASK_POWER_STAGE2_8822B)
+
+/* 2 REG_SW_AMPDU_BURST_MODE_CTRL_8822B */
+
+#define BIT_SHIFT_PAD_NUM_THRES_8822B 24
+#define BIT_MASK_PAD_NUM_THRES_8822B 0x3f
+#define BIT_PAD_NUM_THRES_8822B(x) \
+ (((x) & BIT_MASK_PAD_NUM_THRES_8822B) << BIT_SHIFT_PAD_NUM_THRES_8822B)
+#define BIT_GET_PAD_NUM_THRES_8822B(x) \
+ (((x) >> BIT_SHIFT_PAD_NUM_THRES_8822B) & BIT_MASK_PAD_NUM_THRES_8822B)
+
+#define BIT_R_DMA_THIS_QUEUE_BK_8822B BIT(23)
+#define BIT_R_DMA_THIS_QUEUE_BE_8822B BIT(22)
+#define BIT_R_DMA_THIS_QUEUE_VI_8822B BIT(21)
+#define BIT_R_DMA_THIS_QUEUE_VO_8822B BIT(20)
+
+#define BIT_SHIFT_R_TOTAL_LEN_TH_8822B 8
+#define BIT_MASK_R_TOTAL_LEN_TH_8822B 0xfff
+#define BIT_R_TOTAL_LEN_TH_8822B(x) \
+ (((x) & BIT_MASK_R_TOTAL_LEN_TH_8822B) \
+ << BIT_SHIFT_R_TOTAL_LEN_TH_8822B)
+#define BIT_GET_R_TOTAL_LEN_TH_8822B(x) \
+ (((x) >> BIT_SHIFT_R_TOTAL_LEN_TH_8822B) & \
+ BIT_MASK_R_TOTAL_LEN_TH_8822B)
+
+#define BIT_EN_NEW_EARLY_8822B BIT(7)
+#define BIT_PRE_TX_CMD_8822B BIT(6)
+
+#define BIT_SHIFT_NUM_SCL_EN_8822B 4
+#define BIT_MASK_NUM_SCL_EN_8822B 0x3
+#define BIT_NUM_SCL_EN_8822B(x) \
+ (((x) & BIT_MASK_NUM_SCL_EN_8822B) << BIT_SHIFT_NUM_SCL_EN_8822B)
+#define BIT_GET_NUM_SCL_EN_8822B(x) \
+ (((x) >> BIT_SHIFT_NUM_SCL_EN_8822B) & BIT_MASK_NUM_SCL_EN_8822B)
+
+#define BIT_BK_EN_8822B BIT(3)
+#define BIT_BE_EN_8822B BIT(2)
+#define BIT_VI_EN_8822B BIT(1)
+#define BIT_VO_EN_8822B BIT(0)
+
+/* 2 REG_PKT_LIFE_TIME_8822B */
+
+#define BIT_SHIFT_PKT_LIFTIME_BEBK_8822B 16
+#define BIT_MASK_PKT_LIFTIME_BEBK_8822B 0xffff
+#define BIT_PKT_LIFTIME_BEBK_8822B(x) \
+ (((x) & BIT_MASK_PKT_LIFTIME_BEBK_8822B) \
+ << BIT_SHIFT_PKT_LIFTIME_BEBK_8822B)
+#define BIT_GET_PKT_LIFTIME_BEBK_8822B(x) \
+ (((x) >> BIT_SHIFT_PKT_LIFTIME_BEBK_8822B) & \
+ BIT_MASK_PKT_LIFTIME_BEBK_8822B)
+
+#define BIT_SHIFT_PKT_LIFTIME_VOVI_8822B 0
+#define BIT_MASK_PKT_LIFTIME_VOVI_8822B 0xffff
+#define BIT_PKT_LIFTIME_VOVI_8822B(x) \
+ (((x) & BIT_MASK_PKT_LIFTIME_VOVI_8822B) \
+ << BIT_SHIFT_PKT_LIFTIME_VOVI_8822B)
+#define BIT_GET_PKT_LIFTIME_VOVI_8822B(x) \
+ (((x) >> BIT_SHIFT_PKT_LIFTIME_VOVI_8822B) & \
+ BIT_MASK_PKT_LIFTIME_VOVI_8822B)
+
+/* 2 REG_STBC_SETTING_8822B */
+
+#define BIT_SHIFT_CDEND_TXTIME_L_8822B 4
+#define BIT_MASK_CDEND_TXTIME_L_8822B 0xf
+#define BIT_CDEND_TXTIME_L_8822B(x) \
+ (((x) & BIT_MASK_CDEND_TXTIME_L_8822B) \
+ << BIT_SHIFT_CDEND_TXTIME_L_8822B)
+#define BIT_GET_CDEND_TXTIME_L_8822B(x) \
+ (((x) >> BIT_SHIFT_CDEND_TXTIME_L_8822B) & \
+ BIT_MASK_CDEND_TXTIME_L_8822B)
+
+#define BIT_SHIFT_NESS_8822B 2
+#define BIT_MASK_NESS_8822B 0x3
+#define BIT_NESS_8822B(x) (((x) & BIT_MASK_NESS_8822B) << BIT_SHIFT_NESS_8822B)
+#define BIT_GET_NESS_8822B(x) \
+ (((x) >> BIT_SHIFT_NESS_8822B) & BIT_MASK_NESS_8822B)
+
+#define BIT_SHIFT_STBC_CFEND_8822B 0
+#define BIT_MASK_STBC_CFEND_8822B 0x3
+#define BIT_STBC_CFEND_8822B(x) \
+ (((x) & BIT_MASK_STBC_CFEND_8822B) << BIT_SHIFT_STBC_CFEND_8822B)
+#define BIT_GET_STBC_CFEND_8822B(x) \
+ (((x) >> BIT_SHIFT_STBC_CFEND_8822B) & BIT_MASK_STBC_CFEND_8822B)
+
+/* 2 REG_STBC_SETTING2_8822B */
+
+#define BIT_SHIFT_CDEND_TXTIME_H_8822B 0
+#define BIT_MASK_CDEND_TXTIME_H_8822B 0x1f
+#define BIT_CDEND_TXTIME_H_8822B(x) \
+ (((x) & BIT_MASK_CDEND_TXTIME_H_8822B) \
+ << BIT_SHIFT_CDEND_TXTIME_H_8822B)
+#define BIT_GET_CDEND_TXTIME_H_8822B(x) \
+ (((x) >> BIT_SHIFT_CDEND_TXTIME_H_8822B) & \
+ BIT_MASK_CDEND_TXTIME_H_8822B)
+
+/* 2 REG_QUEUE_CTRL_8822B */
+#define BIT_PTA_EDCCA_EN_8822B BIT(5)
+#define BIT_PTA_WL_TX_EN_8822B BIT(4)
+#define BIT_R_USE_DATA_BW_8822B BIT(3)
+#define BIT_TRI_PKT_INT_MODE1_8822B BIT(2)
+#define BIT_TRI_PKT_INT_MODE0_8822B BIT(1)
+#define BIT_ACQ_MODE_SEL_8822B BIT(0)
+
+/* 2 REG_SINGLE_AMPDU_CTRL_8822B */
+#define BIT_EN_SINGLE_APMDU_8822B BIT(7)
+
+/* 2 REG_PROT_MODE_CTRL_8822B */
+
+#define BIT_SHIFT_RTS_MAX_AGG_NUM_8822B 24
+#define BIT_MASK_RTS_MAX_AGG_NUM_8822B 0x3f
+#define BIT_RTS_MAX_AGG_NUM_8822B(x) \
+ (((x) & BIT_MASK_RTS_MAX_AGG_NUM_8822B) \
+ << BIT_SHIFT_RTS_MAX_AGG_NUM_8822B)
+#define BIT_GET_RTS_MAX_AGG_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_RTS_MAX_AGG_NUM_8822B) & \
+ BIT_MASK_RTS_MAX_AGG_NUM_8822B)
+
+#define BIT_SHIFT_MAX_AGG_NUM_8822B 16
+#define BIT_MASK_MAX_AGG_NUM_8822B 0x3f
+#define BIT_MAX_AGG_NUM_8822B(x) \
+ (((x) & BIT_MASK_MAX_AGG_NUM_8822B) << BIT_SHIFT_MAX_AGG_NUM_8822B)
+#define BIT_GET_MAX_AGG_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_MAX_AGG_NUM_8822B) & BIT_MASK_MAX_AGG_NUM_8822B)
+
+#define BIT_SHIFT_RTS_TXTIME_TH_8822B 8
+#define BIT_MASK_RTS_TXTIME_TH_8822B 0xff
+#define BIT_RTS_TXTIME_TH_8822B(x) \
+ (((x) & BIT_MASK_RTS_TXTIME_TH_8822B) << BIT_SHIFT_RTS_TXTIME_TH_8822B)
+#define BIT_GET_RTS_TXTIME_TH_8822B(x) \
+ (((x) >> BIT_SHIFT_RTS_TXTIME_TH_8822B) & BIT_MASK_RTS_TXTIME_TH_8822B)
+
+#define BIT_SHIFT_RTS_LEN_TH_8822B 0
+#define BIT_MASK_RTS_LEN_TH_8822B 0xff
+#define BIT_RTS_LEN_TH_8822B(x) \
+ (((x) & BIT_MASK_RTS_LEN_TH_8822B) << BIT_SHIFT_RTS_LEN_TH_8822B)
+#define BIT_GET_RTS_LEN_TH_8822B(x) \
+ (((x) >> BIT_SHIFT_RTS_LEN_TH_8822B) & BIT_MASK_RTS_LEN_TH_8822B)
+
+/* 2 REG_BAR_MODE_CTRL_8822B */
+
+#define BIT_SHIFT_BAR_RTY_LMT_8822B 16
+#define BIT_MASK_BAR_RTY_LMT_8822B 0x3
+#define BIT_BAR_RTY_LMT_8822B(x) \
+ (((x) & BIT_MASK_BAR_RTY_LMT_8822B) << BIT_SHIFT_BAR_RTY_LMT_8822B)
+#define BIT_GET_BAR_RTY_LMT_8822B(x) \
+ (((x) >> BIT_SHIFT_BAR_RTY_LMT_8822B) & BIT_MASK_BAR_RTY_LMT_8822B)
+
+#define BIT_SHIFT_BAR_PKT_TXTIME_TH_8822B 8
+#define BIT_MASK_BAR_PKT_TXTIME_TH_8822B 0xff
+#define BIT_BAR_PKT_TXTIME_TH_8822B(x) \
+ (((x) & BIT_MASK_BAR_PKT_TXTIME_TH_8822B) \
+ << BIT_SHIFT_BAR_PKT_TXTIME_TH_8822B)
+#define BIT_GET_BAR_PKT_TXTIME_TH_8822B(x) \
+ (((x) >> BIT_SHIFT_BAR_PKT_TXTIME_TH_8822B) & \
+ BIT_MASK_BAR_PKT_TXTIME_TH_8822B)
+
+#define BIT_BAR_EN_V1_8822B BIT(6)
+
+#define BIT_SHIFT_BAR_PKTNUM_TH_V1_8822B 0
+#define BIT_MASK_BAR_PKTNUM_TH_V1_8822B 0x3f
+#define BIT_BAR_PKTNUM_TH_V1_8822B(x) \
+ (((x) & BIT_MASK_BAR_PKTNUM_TH_V1_8822B) \
+ << BIT_SHIFT_BAR_PKTNUM_TH_V1_8822B)
+#define BIT_GET_BAR_PKTNUM_TH_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_BAR_PKTNUM_TH_V1_8822B) & \
+ BIT_MASK_BAR_PKTNUM_TH_V1_8822B)
+
+/* 2 REG_RA_TRY_RATE_AGG_LMT_8822B */
+
+#define BIT_SHIFT_RA_TRY_RATE_AGG_LMT_V1_8822B 0
+#define BIT_MASK_RA_TRY_RATE_AGG_LMT_V1_8822B 0x3f
+#define BIT_RA_TRY_RATE_AGG_LMT_V1_8822B(x) \
+ (((x) & BIT_MASK_RA_TRY_RATE_AGG_LMT_V1_8822B) \
+ << BIT_SHIFT_RA_TRY_RATE_AGG_LMT_V1_8822B)
+#define BIT_GET_RA_TRY_RATE_AGG_LMT_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_RA_TRY_RATE_AGG_LMT_V1_8822B) & \
+ BIT_MASK_RA_TRY_RATE_AGG_LMT_V1_8822B)
+
+/* 2 REG_MACID_SLEEP2_8822B */
+
+#define BIT_SHIFT_MACID95_64PKTSLEEP_8822B 0
+#define BIT_MASK_MACID95_64PKTSLEEP_8822B 0xffffffffL
+#define BIT_MACID95_64PKTSLEEP_8822B(x) \
+ (((x) & BIT_MASK_MACID95_64PKTSLEEP_8822B) \
+ << BIT_SHIFT_MACID95_64PKTSLEEP_8822B)
+#define BIT_GET_MACID95_64PKTSLEEP_8822B(x) \
+ (((x) >> BIT_SHIFT_MACID95_64PKTSLEEP_8822B) & \
+ BIT_MASK_MACID95_64PKTSLEEP_8822B)
+
+/* 2 REG_MACID_SLEEP_8822B */
+
+#define BIT_SHIFT_MACID31_0_PKTSLEEP_8822B 0
+#define BIT_MASK_MACID31_0_PKTSLEEP_8822B 0xffffffffL
+#define BIT_MACID31_0_PKTSLEEP_8822B(x) \
+ (((x) & BIT_MASK_MACID31_0_PKTSLEEP_8822B) \
+ << BIT_SHIFT_MACID31_0_PKTSLEEP_8822B)
+#define BIT_GET_MACID31_0_PKTSLEEP_8822B(x) \
+ (((x) >> BIT_SHIFT_MACID31_0_PKTSLEEP_8822B) & \
+ BIT_MASK_MACID31_0_PKTSLEEP_8822B)
+
+/* 2 REG_HW_SEQ0_8822B */
+
+#define BIT_SHIFT_HW_SSN_SEQ0_8822B 0
+#define BIT_MASK_HW_SSN_SEQ0_8822B 0xfff
+#define BIT_HW_SSN_SEQ0_8822B(x) \
+ (((x) & BIT_MASK_HW_SSN_SEQ0_8822B) << BIT_SHIFT_HW_SSN_SEQ0_8822B)
+#define BIT_GET_HW_SSN_SEQ0_8822B(x) \
+ (((x) >> BIT_SHIFT_HW_SSN_SEQ0_8822B) & BIT_MASK_HW_SSN_SEQ0_8822B)
+
+/* 2 REG_HW_SEQ1_8822B */
+
+#define BIT_SHIFT_HW_SSN_SEQ1_8822B 0
+#define BIT_MASK_HW_SSN_SEQ1_8822B 0xfff
+#define BIT_HW_SSN_SEQ1_8822B(x) \
+ (((x) & BIT_MASK_HW_SSN_SEQ1_8822B) << BIT_SHIFT_HW_SSN_SEQ1_8822B)
+#define BIT_GET_HW_SSN_SEQ1_8822B(x) \
+ (((x) >> BIT_SHIFT_HW_SSN_SEQ1_8822B) & BIT_MASK_HW_SSN_SEQ1_8822B)
+
+/* 2 REG_HW_SEQ2_8822B */
+
+#define BIT_SHIFT_HW_SSN_SEQ2_8822B 0
+#define BIT_MASK_HW_SSN_SEQ2_8822B 0xfff
+#define BIT_HW_SSN_SEQ2_8822B(x) \
+ (((x) & BIT_MASK_HW_SSN_SEQ2_8822B) << BIT_SHIFT_HW_SSN_SEQ2_8822B)
+#define BIT_GET_HW_SSN_SEQ2_8822B(x) \
+ (((x) >> BIT_SHIFT_HW_SSN_SEQ2_8822B) & BIT_MASK_HW_SSN_SEQ2_8822B)
+
+/* 2 REG_HW_SEQ3_8822B */
+
+#define BIT_SHIFT_HW_SSN_SEQ3_8822B 0
+#define BIT_MASK_HW_SSN_SEQ3_8822B 0xfff
+#define BIT_HW_SSN_SEQ3_8822B(x) \
+ (((x) & BIT_MASK_HW_SSN_SEQ3_8822B) << BIT_SHIFT_HW_SSN_SEQ3_8822B)
+#define BIT_GET_HW_SSN_SEQ3_8822B(x) \
+ (((x) >> BIT_SHIFT_HW_SSN_SEQ3_8822B) & BIT_MASK_HW_SSN_SEQ3_8822B)
+
+/* 2 REG_NULL_PKT_STATUS_V1_8822B */
+
+#define BIT_SHIFT_PTCL_TOTAL_PG_V2_8822B 2
+#define BIT_MASK_PTCL_TOTAL_PG_V2_8822B 0x3fff
+#define BIT_PTCL_TOTAL_PG_V2_8822B(x) \
+ (((x) & BIT_MASK_PTCL_TOTAL_PG_V2_8822B) \
+ << BIT_SHIFT_PTCL_TOTAL_PG_V2_8822B)
+#define BIT_GET_PTCL_TOTAL_PG_V2_8822B(x) \
+ (((x) >> BIT_SHIFT_PTCL_TOTAL_PG_V2_8822B) & \
+ BIT_MASK_PTCL_TOTAL_PG_V2_8822B)
+
+#define BIT_TX_NULL_1_8822B BIT(1)
+#define BIT_TX_NULL_0_8822B BIT(0)
+
+/* 2 REG_PTCL_ERR_STATUS_8822B */
+#define BIT_PTCL_RATE_TABLE_INVALID_8822B BIT(7)
+#define BIT_FTM_T2R_ERROR_8822B BIT(6)
+#define BIT_PTCL_ERR0_8822B BIT(5)
+#define BIT_PTCL_ERR1_8822B BIT(4)
+#define BIT_PTCL_ERR2_8822B BIT(3)
+#define BIT_PTCL_ERR3_8822B BIT(2)
+#define BIT_PTCL_ERR4_8822B BIT(1)
+#define BIT_PTCL_ERR5_8822B BIT(0)
+
+/* 2 REG_NULL_PKT_STATUS_EXTEND_8822B */
+#define BIT_CLI3_TX_NULL_1_8822B BIT(7)
+#define BIT_CLI3_TX_NULL_0_8822B BIT(6)
+#define BIT_CLI2_TX_NULL_1_8822B BIT(5)
+#define BIT_CLI2_TX_NULL_0_8822B BIT(4)
+#define BIT_CLI1_TX_NULL_1_8822B BIT(3)
+#define BIT_CLI1_TX_NULL_0_8822B BIT(2)
+#define BIT_CLI0_TX_NULL_1_8822B BIT(1)
+#define BIT_CLI0_TX_NULL_0_8822B BIT(0)
+
+/* 2 REG_VIDEO_ENHANCEMENT_FUN_8822B */
+#define BIT_VIDEO_JUST_DROP_8822B BIT(1)
+#define BIT_VIDEO_ENHANCEMENT_FUN_EN_8822B BIT(0)
+
+/* 2 REG_BT_POLLUTE_PKT_CNT_8822B */
+
+#define BIT_SHIFT_BT_POLLUTE_PKT_CNT_8822B 0
+#define BIT_MASK_BT_POLLUTE_PKT_CNT_8822B 0xffff
+#define BIT_BT_POLLUTE_PKT_CNT_8822B(x) \
+ (((x) & BIT_MASK_BT_POLLUTE_PKT_CNT_8822B) \
+ << BIT_SHIFT_BT_POLLUTE_PKT_CNT_8822B)
+#define BIT_GET_BT_POLLUTE_PKT_CNT_8822B(x) \
+ (((x) >> BIT_SHIFT_BT_POLLUTE_PKT_CNT_8822B) & \
+ BIT_MASK_BT_POLLUTE_PKT_CNT_8822B)
+
+/* 2 REG_NOT_VALID_8822B */
+
+/* 2 REG_PTCL_DBG_8822B */
+
+#define BIT_SHIFT_PTCL_DBG_8822B 0
+#define BIT_MASK_PTCL_DBG_8822B 0xffffffffL
+#define BIT_PTCL_DBG_8822B(x) \
+ (((x) & BIT_MASK_PTCL_DBG_8822B) << BIT_SHIFT_PTCL_DBG_8822B)
+#define BIT_GET_PTCL_DBG_8822B(x) \
+ (((x) >> BIT_SHIFT_PTCL_DBG_8822B) & BIT_MASK_PTCL_DBG_8822B)
+
+/* 2 REG_NOT_VALID_8822B */
+
+/* 2 REG_CPUMGQ_TIMER_CTRL2_8822B */
+
+#define BIT_SHIFT_TRI_HEAD_ADDR_8822B 16
+#define BIT_MASK_TRI_HEAD_ADDR_8822B 0xfff
+#define BIT_TRI_HEAD_ADDR_8822B(x) \
+ (((x) & BIT_MASK_TRI_HEAD_ADDR_8822B) << BIT_SHIFT_TRI_HEAD_ADDR_8822B)
+#define BIT_GET_TRI_HEAD_ADDR_8822B(x) \
+ (((x) >> BIT_SHIFT_TRI_HEAD_ADDR_8822B) & BIT_MASK_TRI_HEAD_ADDR_8822B)
+
+#define BIT_DROP_TH_EN_8822B BIT(8)
+
+#define BIT_SHIFT_DROP_TH_8822B 0
+#define BIT_MASK_DROP_TH_8822B 0xff
+#define BIT_DROP_TH_8822B(x) \
+ (((x) & BIT_MASK_DROP_TH_8822B) << BIT_SHIFT_DROP_TH_8822B)
+#define BIT_GET_DROP_TH_8822B(x) \
+ (((x) >> BIT_SHIFT_DROP_TH_8822B) & BIT_MASK_DROP_TH_8822B)
+
+/* 2 REG_NOT_VALID_8822B */
+
+/* 2 REG_DUMMY_PAGE4_V1_8822B */
+#define BIT_BCN_EN_EXTHWSEQ_8822B BIT(1)
+#define BIT_BCN_EN_HWSEQ_8822B BIT(0)
+
+/* 2 REG_MOREDATA_8822B */
+#define BIT_MOREDATA_CTRL2_EN_V1_8822B BIT(3)
+#define BIT_MOREDATA_CTRL1_EN_V1_8822B BIT(2)
+#define BIT_PKTIN_MOREDATA_REPLACE_ENABLE_V1_8822B BIT(0)
+
+/* 2 REG_NOT_VALID_8822B */
+
+/* 2 REG_Q0_Q1_INFO_8822B */
+#define BIT_QUEUE_MACID_AC_NOT_THE_SAME_8822B BIT(31)
+
+#define BIT_SHIFT_GTAB_ID_8822B 28
+#define BIT_MASK_GTAB_ID_8822B 0x7
+#define BIT_GTAB_ID_8822B(x) \
+ (((x) & BIT_MASK_GTAB_ID_8822B) << BIT_SHIFT_GTAB_ID_8822B)
+#define BIT_GET_GTAB_ID_8822B(x) \
+ (((x) >> BIT_SHIFT_GTAB_ID_8822B) & BIT_MASK_GTAB_ID_8822B)
+
+#define BIT_SHIFT_AC1_PKT_INFO_8822B 16
+#define BIT_MASK_AC1_PKT_INFO_8822B 0xfff
+#define BIT_AC1_PKT_INFO_8822B(x) \
+ (((x) & BIT_MASK_AC1_PKT_INFO_8822B) << BIT_SHIFT_AC1_PKT_INFO_8822B)
+#define BIT_GET_AC1_PKT_INFO_8822B(x) \
+ (((x) >> BIT_SHIFT_AC1_PKT_INFO_8822B) & BIT_MASK_AC1_PKT_INFO_8822B)
+
+#define BIT_QUEUE_MACID_AC_NOT_THE_SAME_V1_8822B BIT(15)
+
+#define BIT_SHIFT_GTAB_ID_V1_8822B 12
+#define BIT_MASK_GTAB_ID_V1_8822B 0x7
+#define BIT_GTAB_ID_V1_8822B(x) \
+ (((x) & BIT_MASK_GTAB_ID_V1_8822B) << BIT_SHIFT_GTAB_ID_V1_8822B)
+#define BIT_GET_GTAB_ID_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_GTAB_ID_V1_8822B) & BIT_MASK_GTAB_ID_V1_8822B)
+
+#define BIT_SHIFT_AC0_PKT_INFO_8822B 0
+#define BIT_MASK_AC0_PKT_INFO_8822B 0xfff
+#define BIT_AC0_PKT_INFO_8822B(x) \
+ (((x) & BIT_MASK_AC0_PKT_INFO_8822B) << BIT_SHIFT_AC0_PKT_INFO_8822B)
+#define BIT_GET_AC0_PKT_INFO_8822B(x) \
+ (((x) >> BIT_SHIFT_AC0_PKT_INFO_8822B) & BIT_MASK_AC0_PKT_INFO_8822B)
+
+/* 2 REG_Q2_Q3_INFO_8822B */
+#define BIT_QUEUE_MACID_AC_NOT_THE_SAME_8822B BIT(31)
+
+#define BIT_SHIFT_GTAB_ID_8822B 28
+#define BIT_MASK_GTAB_ID_8822B 0x7
+#define BIT_GTAB_ID_8822B(x) \
+ (((x) & BIT_MASK_GTAB_ID_8822B) << BIT_SHIFT_GTAB_ID_8822B)
+#define BIT_GET_GTAB_ID_8822B(x) \
+ (((x) >> BIT_SHIFT_GTAB_ID_8822B) & BIT_MASK_GTAB_ID_8822B)
+
+#define BIT_SHIFT_AC3_PKT_INFO_8822B 16
+#define BIT_MASK_AC3_PKT_INFO_8822B 0xfff
+#define BIT_AC3_PKT_INFO_8822B(x) \
+ (((x) & BIT_MASK_AC3_PKT_INFO_8822B) << BIT_SHIFT_AC3_PKT_INFO_8822B)
+#define BIT_GET_AC3_PKT_INFO_8822B(x) \
+ (((x) >> BIT_SHIFT_AC3_PKT_INFO_8822B) & BIT_MASK_AC3_PKT_INFO_8822B)
+
+#define BIT_QUEUE_MACID_AC_NOT_THE_SAME_V1_8822B BIT(15)
+
+#define BIT_SHIFT_GTAB_ID_V1_8822B 12
+#define BIT_MASK_GTAB_ID_V1_8822B 0x7
+#define BIT_GTAB_ID_V1_8822B(x) \
+ (((x) & BIT_MASK_GTAB_ID_V1_8822B) << BIT_SHIFT_GTAB_ID_V1_8822B)
+#define BIT_GET_GTAB_ID_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_GTAB_ID_V1_8822B) & BIT_MASK_GTAB_ID_V1_8822B)
+
+#define BIT_SHIFT_AC2_PKT_INFO_8822B 0
+#define BIT_MASK_AC2_PKT_INFO_8822B 0xfff
+#define BIT_AC2_PKT_INFO_8822B(x) \
+ (((x) & BIT_MASK_AC2_PKT_INFO_8822B) << BIT_SHIFT_AC2_PKT_INFO_8822B)
+#define BIT_GET_AC2_PKT_INFO_8822B(x) \
+ (((x) >> BIT_SHIFT_AC2_PKT_INFO_8822B) & BIT_MASK_AC2_PKT_INFO_8822B)
+
+/* 2 REG_Q4_Q5_INFO_8822B */
+#define BIT_QUEUE_MACID_AC_NOT_THE_SAME_8822B BIT(31)
+
+#define BIT_SHIFT_GTAB_ID_8822B 28
+#define BIT_MASK_GTAB_ID_8822B 0x7
+#define BIT_GTAB_ID_8822B(x) \
+ (((x) & BIT_MASK_GTAB_ID_8822B) << BIT_SHIFT_GTAB_ID_8822B)
+#define BIT_GET_GTAB_ID_8822B(x) \
+ (((x) >> BIT_SHIFT_GTAB_ID_8822B) & BIT_MASK_GTAB_ID_8822B)
+
+#define BIT_SHIFT_AC5_PKT_INFO_8822B 16
+#define BIT_MASK_AC5_PKT_INFO_8822B 0xfff
+#define BIT_AC5_PKT_INFO_8822B(x) \
+ (((x) & BIT_MASK_AC5_PKT_INFO_8822B) << BIT_SHIFT_AC5_PKT_INFO_8822B)
+#define BIT_GET_AC5_PKT_INFO_8822B(x) \
+ (((x) >> BIT_SHIFT_AC5_PKT_INFO_8822B) & BIT_MASK_AC5_PKT_INFO_8822B)
+
+#define BIT_QUEUE_MACID_AC_NOT_THE_SAME_V1_8822B BIT(15)
+
+#define BIT_SHIFT_GTAB_ID_V1_8822B 12
+#define BIT_MASK_GTAB_ID_V1_8822B 0x7
+#define BIT_GTAB_ID_V1_8822B(x) \
+ (((x) & BIT_MASK_GTAB_ID_V1_8822B) << BIT_SHIFT_GTAB_ID_V1_8822B)
+#define BIT_GET_GTAB_ID_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_GTAB_ID_V1_8822B) & BIT_MASK_GTAB_ID_V1_8822B)
+
+#define BIT_SHIFT_AC4_PKT_INFO_8822B 0
+#define BIT_MASK_AC4_PKT_INFO_8822B 0xfff
+#define BIT_AC4_PKT_INFO_8822B(x) \
+ (((x) & BIT_MASK_AC4_PKT_INFO_8822B) << BIT_SHIFT_AC4_PKT_INFO_8822B)
+#define BIT_GET_AC4_PKT_INFO_8822B(x) \
+ (((x) >> BIT_SHIFT_AC4_PKT_INFO_8822B) & BIT_MASK_AC4_PKT_INFO_8822B)
+
+/* 2 REG_Q6_Q7_INFO_8822B */
+#define BIT_QUEUE_MACID_AC_NOT_THE_SAME_8822B BIT(31)
+
+#define BIT_SHIFT_GTAB_ID_8822B 28
+#define BIT_MASK_GTAB_ID_8822B 0x7
+#define BIT_GTAB_ID_8822B(x) \
+ (((x) & BIT_MASK_GTAB_ID_8822B) << BIT_SHIFT_GTAB_ID_8822B)
+#define BIT_GET_GTAB_ID_8822B(x) \
+ (((x) >> BIT_SHIFT_GTAB_ID_8822B) & BIT_MASK_GTAB_ID_8822B)
+
+#define BIT_SHIFT_AC7_PKT_INFO_8822B 16
+#define BIT_MASK_AC7_PKT_INFO_8822B 0xfff
+#define BIT_AC7_PKT_INFO_8822B(x) \
+ (((x) & BIT_MASK_AC7_PKT_INFO_8822B) << BIT_SHIFT_AC7_PKT_INFO_8822B)
+#define BIT_GET_AC7_PKT_INFO_8822B(x) \
+ (((x) >> BIT_SHIFT_AC7_PKT_INFO_8822B) & BIT_MASK_AC7_PKT_INFO_8822B)
+
+#define BIT_QUEUE_MACID_AC_NOT_THE_SAME_V1_8822B BIT(15)
+
+#define BIT_SHIFT_GTAB_ID_V1_8822B 12
+#define BIT_MASK_GTAB_ID_V1_8822B 0x7
+#define BIT_GTAB_ID_V1_8822B(x) \
+ (((x) & BIT_MASK_GTAB_ID_V1_8822B) << BIT_SHIFT_GTAB_ID_V1_8822B)
+#define BIT_GET_GTAB_ID_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_GTAB_ID_V1_8822B) & BIT_MASK_GTAB_ID_V1_8822B)
+
+#define BIT_SHIFT_AC6_PKT_INFO_8822B 0
+#define BIT_MASK_AC6_PKT_INFO_8822B 0xfff
+#define BIT_AC6_PKT_INFO_8822B(x) \
+ (((x) & BIT_MASK_AC6_PKT_INFO_8822B) << BIT_SHIFT_AC6_PKT_INFO_8822B)
+#define BIT_GET_AC6_PKT_INFO_8822B(x) \
+ (((x) >> BIT_SHIFT_AC6_PKT_INFO_8822B) & BIT_MASK_AC6_PKT_INFO_8822B)
+
+/* 2 REG_MGQ_HIQ_INFO_8822B */
+
+#define BIT_SHIFT_HIQ_PKT_INFO_8822B 16
+#define BIT_MASK_HIQ_PKT_INFO_8822B 0xfff
+#define BIT_HIQ_PKT_INFO_8822B(x) \
+ (((x) & BIT_MASK_HIQ_PKT_INFO_8822B) << BIT_SHIFT_HIQ_PKT_INFO_8822B)
+#define BIT_GET_HIQ_PKT_INFO_8822B(x) \
+ (((x) >> BIT_SHIFT_HIQ_PKT_INFO_8822B) & BIT_MASK_HIQ_PKT_INFO_8822B)
+
+#define BIT_SHIFT_MGQ_PKT_INFO_8822B 0
+#define BIT_MASK_MGQ_PKT_INFO_8822B 0xfff
+#define BIT_MGQ_PKT_INFO_8822B(x) \
+ (((x) & BIT_MASK_MGQ_PKT_INFO_8822B) << BIT_SHIFT_MGQ_PKT_INFO_8822B)
+#define BIT_GET_MGQ_PKT_INFO_8822B(x) \
+ (((x) >> BIT_SHIFT_MGQ_PKT_INFO_8822B) & BIT_MASK_MGQ_PKT_INFO_8822B)
+
+/* 2 REG_CMDQ_BCNQ_INFO_8822B */
+
+#define BIT_SHIFT_CMDQ_PKT_INFO_8822B 16
+#define BIT_MASK_CMDQ_PKT_INFO_8822B 0xfff
+#define BIT_CMDQ_PKT_INFO_8822B(x) \
+ (((x) & BIT_MASK_CMDQ_PKT_INFO_8822B) << BIT_SHIFT_CMDQ_PKT_INFO_8822B)
+#define BIT_GET_CMDQ_PKT_INFO_8822B(x) \
+ (((x) >> BIT_SHIFT_CMDQ_PKT_INFO_8822B) & BIT_MASK_CMDQ_PKT_INFO_8822B)
+
+#define BIT_SHIFT_BCNQ_PKT_INFO_8822B 0
+#define BIT_MASK_BCNQ_PKT_INFO_8822B 0xfff
+#define BIT_BCNQ_PKT_INFO_8822B(x) \
+ (((x) & BIT_MASK_BCNQ_PKT_INFO_8822B) << BIT_SHIFT_BCNQ_PKT_INFO_8822B)
+#define BIT_GET_BCNQ_PKT_INFO_8822B(x) \
+ (((x) >> BIT_SHIFT_BCNQ_PKT_INFO_8822B) & BIT_MASK_BCNQ_PKT_INFO_8822B)
+
+/* 2 REG_USEREG_SETTING_8822B */
+#define BIT_NDPA_USEREG_8822B BIT(21)
+
+#define BIT_SHIFT_RETRY_USEREG_8822B 19
+#define BIT_MASK_RETRY_USEREG_8822B 0x3
+#define BIT_RETRY_USEREG_8822B(x) \
+ (((x) & BIT_MASK_RETRY_USEREG_8822B) << BIT_SHIFT_RETRY_USEREG_8822B)
+#define BIT_GET_RETRY_USEREG_8822B(x) \
+ (((x) >> BIT_SHIFT_RETRY_USEREG_8822B) & BIT_MASK_RETRY_USEREG_8822B)
+
+#define BIT_SHIFT_TRYPKT_USEREG_8822B 17
+#define BIT_MASK_TRYPKT_USEREG_8822B 0x3
+#define BIT_TRYPKT_USEREG_8822B(x) \
+ (((x) & BIT_MASK_TRYPKT_USEREG_8822B) << BIT_SHIFT_TRYPKT_USEREG_8822B)
+#define BIT_GET_TRYPKT_USEREG_8822B(x) \
+ (((x) >> BIT_SHIFT_TRYPKT_USEREG_8822B) & BIT_MASK_TRYPKT_USEREG_8822B)
+
+#define BIT_CTLPKT_USEREG_8822B BIT(16)
+
+/* 2 REG_AESIV_SETTING_8822B */
+
+#define BIT_SHIFT_AESIV_OFFSET_8822B 0
+#define BIT_MASK_AESIV_OFFSET_8822B 0xfff
+#define BIT_AESIV_OFFSET_8822B(x) \
+ (((x) & BIT_MASK_AESIV_OFFSET_8822B) << BIT_SHIFT_AESIV_OFFSET_8822B)
+#define BIT_GET_AESIV_OFFSET_8822B(x) \
+ (((x) >> BIT_SHIFT_AESIV_OFFSET_8822B) & BIT_MASK_AESIV_OFFSET_8822B)
+
+/* 2 REG_BF0_TIME_SETTING_8822B */
+#define BIT_BF0_TIMER_SET_8822B BIT(31)
+#define BIT_BF0_TIMER_CLR_8822B BIT(30)
+#define BIT_BF0_UPDATE_EN_8822B BIT(29)
+#define BIT_BF0_TIMER_EN_8822B BIT(28)
+
+#define BIT_SHIFT_BF0_PRETIME_OVER_8822B 16
+#define BIT_MASK_BF0_PRETIME_OVER_8822B 0xfff
+#define BIT_BF0_PRETIME_OVER_8822B(x) \
+ (((x) & BIT_MASK_BF0_PRETIME_OVER_8822B) \
+ << BIT_SHIFT_BF0_PRETIME_OVER_8822B)
+#define BIT_GET_BF0_PRETIME_OVER_8822B(x) \
+ (((x) >> BIT_SHIFT_BF0_PRETIME_OVER_8822B) & \
+ BIT_MASK_BF0_PRETIME_OVER_8822B)
+
+#define BIT_SHIFT_BF0_LIFETIME_8822B 0
+#define BIT_MASK_BF0_LIFETIME_8822B 0xffff
+#define BIT_BF0_LIFETIME_8822B(x) \
+ (((x) & BIT_MASK_BF0_LIFETIME_8822B) << BIT_SHIFT_BF0_LIFETIME_8822B)
+#define BIT_GET_BF0_LIFETIME_8822B(x) \
+ (((x) >> BIT_SHIFT_BF0_LIFETIME_8822B) & BIT_MASK_BF0_LIFETIME_8822B)
+
+/* 2 REG_BF1_TIME_SETTING_8822B */
+#define BIT_BF1_TIMER_SET_8822B BIT(31)
+#define BIT_BF1_TIMER_CLR_8822B BIT(30)
+#define BIT_BF1_UPDATE_EN_8822B BIT(29)
+#define BIT_BF1_TIMER_EN_8822B BIT(28)
+
+#define BIT_SHIFT_BF1_PRETIME_OVER_8822B 16
+#define BIT_MASK_BF1_PRETIME_OVER_8822B 0xfff
+#define BIT_BF1_PRETIME_OVER_8822B(x) \
+ (((x) & BIT_MASK_BF1_PRETIME_OVER_8822B) \
+ << BIT_SHIFT_BF1_PRETIME_OVER_8822B)
+#define BIT_GET_BF1_PRETIME_OVER_8822B(x) \
+ (((x) >> BIT_SHIFT_BF1_PRETIME_OVER_8822B) & \
+ BIT_MASK_BF1_PRETIME_OVER_8822B)
+
+#define BIT_SHIFT_BF1_LIFETIME_8822B 0
+#define BIT_MASK_BF1_LIFETIME_8822B 0xffff
+#define BIT_BF1_LIFETIME_8822B(x) \
+ (((x) & BIT_MASK_BF1_LIFETIME_8822B) << BIT_SHIFT_BF1_LIFETIME_8822B)
+#define BIT_GET_BF1_LIFETIME_8822B(x) \
+ (((x) >> BIT_SHIFT_BF1_LIFETIME_8822B) & BIT_MASK_BF1_LIFETIME_8822B)
+
+/* 2 REG_BF_TIMEOUT_EN_8822B */
+#define BIT_EN_VHT_LDPC_8822B BIT(9)
+#define BIT_EN_HT_LDPC_8822B BIT(8)
+#define BIT_BF1_TIMEOUT_EN_8822B BIT(1)
+#define BIT_BF0_TIMEOUT_EN_8822B BIT(0)
+
+/* 2 REG_MACID_RELEASE0_8822B */
+
+#define BIT_SHIFT_MACID31_0_RELEASE_8822B 0
+#define BIT_MASK_MACID31_0_RELEASE_8822B 0xffffffffL
+#define BIT_MACID31_0_RELEASE_8822B(x) \
+ (((x) & BIT_MASK_MACID31_0_RELEASE_8822B) \
+ << BIT_SHIFT_MACID31_0_RELEASE_8822B)
+#define BIT_GET_MACID31_0_RELEASE_8822B(x) \
+ (((x) >> BIT_SHIFT_MACID31_0_RELEASE_8822B) & \
+ BIT_MASK_MACID31_0_RELEASE_8822B)
+
+/* 2 REG_MACID_RELEASE1_8822B */
+
+#define BIT_SHIFT_MACID63_32_RELEASE_8822B 0
+#define BIT_MASK_MACID63_32_RELEASE_8822B 0xffffffffL
+#define BIT_MACID63_32_RELEASE_8822B(x) \
+ (((x) & BIT_MASK_MACID63_32_RELEASE_8822B) \
+ << BIT_SHIFT_MACID63_32_RELEASE_8822B)
+#define BIT_GET_MACID63_32_RELEASE_8822B(x) \
+ (((x) >> BIT_SHIFT_MACID63_32_RELEASE_8822B) & \
+ BIT_MASK_MACID63_32_RELEASE_8822B)
+
+/* 2 REG_MACID_RELEASE2_8822B */
+
+#define BIT_SHIFT_MACID95_64_RELEASE_8822B 0
+#define BIT_MASK_MACID95_64_RELEASE_8822B 0xffffffffL
+#define BIT_MACID95_64_RELEASE_8822B(x) \
+ (((x) & BIT_MASK_MACID95_64_RELEASE_8822B) \
+ << BIT_SHIFT_MACID95_64_RELEASE_8822B)
+#define BIT_GET_MACID95_64_RELEASE_8822B(x) \
+ (((x) >> BIT_SHIFT_MACID95_64_RELEASE_8822B) & \
+ BIT_MASK_MACID95_64_RELEASE_8822B)
+
+/* 2 REG_MACID_RELEASE3_8822B */
+
+#define BIT_SHIFT_MACID127_96_RELEASE_8822B 0
+#define BIT_MASK_MACID127_96_RELEASE_8822B 0xffffffffL
+#define BIT_MACID127_96_RELEASE_8822B(x) \
+ (((x) & BIT_MASK_MACID127_96_RELEASE_8822B) \
+ << BIT_SHIFT_MACID127_96_RELEASE_8822B)
+#define BIT_GET_MACID127_96_RELEASE_8822B(x) \
+ (((x) >> BIT_SHIFT_MACID127_96_RELEASE_8822B) & \
+ BIT_MASK_MACID127_96_RELEASE_8822B)
+
+/* 2 REG_MACID_RELEASE_SETTING_8822B */
+#define BIT_MACID_VALUE_8822B BIT(7)
+
+#define BIT_SHIFT_MACID_OFFSET_8822B 0
+#define BIT_MASK_MACID_OFFSET_8822B 0x7f
+#define BIT_MACID_OFFSET_8822B(x) \
+ (((x) & BIT_MASK_MACID_OFFSET_8822B) << BIT_SHIFT_MACID_OFFSET_8822B)
+#define BIT_GET_MACID_OFFSET_8822B(x) \
+ (((x) >> BIT_SHIFT_MACID_OFFSET_8822B) & BIT_MASK_MACID_OFFSET_8822B)
+
+/* 2 REG_FAST_EDCA_VOVI_SETTING_8822B */
+
+#define BIT_SHIFT_VI_FAST_EDCA_TO_8822B 24
+#define BIT_MASK_VI_FAST_EDCA_TO_8822B 0xff
+#define BIT_VI_FAST_EDCA_TO_8822B(x) \
+ (((x) & BIT_MASK_VI_FAST_EDCA_TO_8822B) \
+ << BIT_SHIFT_VI_FAST_EDCA_TO_8822B)
+#define BIT_GET_VI_FAST_EDCA_TO_8822B(x) \
+ (((x) >> BIT_SHIFT_VI_FAST_EDCA_TO_8822B) & \
+ BIT_MASK_VI_FAST_EDCA_TO_8822B)
+
+#define BIT_VI_THRESHOLD_SEL_8822B BIT(23)
+
+#define BIT_SHIFT_VI_FAST_EDCA_PKT_TH_8822B 16
+#define BIT_MASK_VI_FAST_EDCA_PKT_TH_8822B 0x7f
+#define BIT_VI_FAST_EDCA_PKT_TH_8822B(x) \
+ (((x) & BIT_MASK_VI_FAST_EDCA_PKT_TH_8822B) \
+ << BIT_SHIFT_VI_FAST_EDCA_PKT_TH_8822B)
+#define BIT_GET_VI_FAST_EDCA_PKT_TH_8822B(x) \
+ (((x) >> BIT_SHIFT_VI_FAST_EDCA_PKT_TH_8822B) & \
+ BIT_MASK_VI_FAST_EDCA_PKT_TH_8822B)
+
+#define BIT_SHIFT_VO_FAST_EDCA_TO_8822B 8
+#define BIT_MASK_VO_FAST_EDCA_TO_8822B 0xff
+#define BIT_VO_FAST_EDCA_TO_8822B(x) \
+ (((x) & BIT_MASK_VO_FAST_EDCA_TO_8822B) \
+ << BIT_SHIFT_VO_FAST_EDCA_TO_8822B)
+#define BIT_GET_VO_FAST_EDCA_TO_8822B(x) \
+ (((x) >> BIT_SHIFT_VO_FAST_EDCA_TO_8822B) & \
+ BIT_MASK_VO_FAST_EDCA_TO_8822B)
+
+#define BIT_VO_THRESHOLD_SEL_8822B BIT(7)
+
+#define BIT_SHIFT_VO_FAST_EDCA_PKT_TH_8822B 0
+#define BIT_MASK_VO_FAST_EDCA_PKT_TH_8822B 0x7f
+#define BIT_VO_FAST_EDCA_PKT_TH_8822B(x) \
+ (((x) & BIT_MASK_VO_FAST_EDCA_PKT_TH_8822B) \
+ << BIT_SHIFT_VO_FAST_EDCA_PKT_TH_8822B)
+#define BIT_GET_VO_FAST_EDCA_PKT_TH_8822B(x) \
+ (((x) >> BIT_SHIFT_VO_FAST_EDCA_PKT_TH_8822B) & \
+ BIT_MASK_VO_FAST_EDCA_PKT_TH_8822B)
+
+/* 2 REG_FAST_EDCA_BEBK_SETTING_8822B */
+
+#define BIT_SHIFT_BK_FAST_EDCA_TO_8822B 24
+#define BIT_MASK_BK_FAST_EDCA_TO_8822B 0xff
+#define BIT_BK_FAST_EDCA_TO_8822B(x) \
+ (((x) & BIT_MASK_BK_FAST_EDCA_TO_8822B) \
+ << BIT_SHIFT_BK_FAST_EDCA_TO_8822B)
+#define BIT_GET_BK_FAST_EDCA_TO_8822B(x) \
+ (((x) >> BIT_SHIFT_BK_FAST_EDCA_TO_8822B) & \
+ BIT_MASK_BK_FAST_EDCA_TO_8822B)
+
+#define BIT_BK_THRESHOLD_SEL_8822B BIT(23)
+
+#define BIT_SHIFT_BK_FAST_EDCA_PKT_TH_8822B 16
+#define BIT_MASK_BK_FAST_EDCA_PKT_TH_8822B 0x7f
+#define BIT_BK_FAST_EDCA_PKT_TH_8822B(x) \
+ (((x) & BIT_MASK_BK_FAST_EDCA_PKT_TH_8822B) \
+ << BIT_SHIFT_BK_FAST_EDCA_PKT_TH_8822B)
+#define BIT_GET_BK_FAST_EDCA_PKT_TH_8822B(x) \
+ (((x) >> BIT_SHIFT_BK_FAST_EDCA_PKT_TH_8822B) & \
+ BIT_MASK_BK_FAST_EDCA_PKT_TH_8822B)
+
+#define BIT_SHIFT_BE_FAST_EDCA_TO_8822B 8
+#define BIT_MASK_BE_FAST_EDCA_TO_8822B 0xff
+#define BIT_BE_FAST_EDCA_TO_8822B(x) \
+ (((x) & BIT_MASK_BE_FAST_EDCA_TO_8822B) \
+ << BIT_SHIFT_BE_FAST_EDCA_TO_8822B)
+#define BIT_GET_BE_FAST_EDCA_TO_8822B(x) \
+ (((x) >> BIT_SHIFT_BE_FAST_EDCA_TO_8822B) & \
+ BIT_MASK_BE_FAST_EDCA_TO_8822B)
+
+#define BIT_BE_THRESHOLD_SEL_8822B BIT(7)
+
+#define BIT_SHIFT_BE_FAST_EDCA_PKT_TH_8822B 0
+#define BIT_MASK_BE_FAST_EDCA_PKT_TH_8822B 0x7f
+#define BIT_BE_FAST_EDCA_PKT_TH_8822B(x) \
+ (((x) & BIT_MASK_BE_FAST_EDCA_PKT_TH_8822B) \
+ << BIT_SHIFT_BE_FAST_EDCA_PKT_TH_8822B)
+#define BIT_GET_BE_FAST_EDCA_PKT_TH_8822B(x) \
+ (((x) >> BIT_SHIFT_BE_FAST_EDCA_PKT_TH_8822B) & \
+ BIT_MASK_BE_FAST_EDCA_PKT_TH_8822B)
+
+/* 2 REG_MACID_DROP0_8822B */
+
+#define BIT_SHIFT_MACID31_0_DROP_8822B 0
+#define BIT_MASK_MACID31_0_DROP_8822B 0xffffffffL
+#define BIT_MACID31_0_DROP_8822B(x) \
+ (((x) & BIT_MASK_MACID31_0_DROP_8822B) \
+ << BIT_SHIFT_MACID31_0_DROP_8822B)
+#define BIT_GET_MACID31_0_DROP_8822B(x) \
+ (((x) >> BIT_SHIFT_MACID31_0_DROP_8822B) & \
+ BIT_MASK_MACID31_0_DROP_8822B)
+
+/* 2 REG_MACID_DROP1_8822B */
+
+#define BIT_SHIFT_MACID63_32_DROP_8822B 0
+#define BIT_MASK_MACID63_32_DROP_8822B 0xffffffffL
+#define BIT_MACID63_32_DROP_8822B(x) \
+ (((x) & BIT_MASK_MACID63_32_DROP_8822B) \
+ << BIT_SHIFT_MACID63_32_DROP_8822B)
+#define BIT_GET_MACID63_32_DROP_8822B(x) \
+ (((x) >> BIT_SHIFT_MACID63_32_DROP_8822B) & \
+ BIT_MASK_MACID63_32_DROP_8822B)
+
+/* 2 REG_MACID_DROP2_8822B */
+
+#define BIT_SHIFT_MACID95_64_DROP_8822B 0
+#define BIT_MASK_MACID95_64_DROP_8822B 0xffffffffL
+#define BIT_MACID95_64_DROP_8822B(x) \
+ (((x) & BIT_MASK_MACID95_64_DROP_8822B) \
+ << BIT_SHIFT_MACID95_64_DROP_8822B)
+#define BIT_GET_MACID95_64_DROP_8822B(x) \
+ (((x) >> BIT_SHIFT_MACID95_64_DROP_8822B) & \
+ BIT_MASK_MACID95_64_DROP_8822B)
+
+/* 2 REG_MACID_DROP3_8822B */
+
+#define BIT_SHIFT_MACID127_96_DROP_8822B 0
+#define BIT_MASK_MACID127_96_DROP_8822B 0xffffffffL
+#define BIT_MACID127_96_DROP_8822B(x) \
+ (((x) & BIT_MASK_MACID127_96_DROP_8822B) \
+ << BIT_SHIFT_MACID127_96_DROP_8822B)
+#define BIT_GET_MACID127_96_DROP_8822B(x) \
+ (((x) >> BIT_SHIFT_MACID127_96_DROP_8822B) & \
+ BIT_MASK_MACID127_96_DROP_8822B)
+
+/* 2 REG_R_MACID_RELEASE_SUCCESS_0_8822B */
+
+#define BIT_SHIFT_R_MACID_RELEASE_SUCCESS_0_8822B 0
+#define BIT_MASK_R_MACID_RELEASE_SUCCESS_0_8822B 0xffffffffL
+#define BIT_R_MACID_RELEASE_SUCCESS_0_8822B(x) \
+ (((x) & BIT_MASK_R_MACID_RELEASE_SUCCESS_0_8822B) \
+ << BIT_SHIFT_R_MACID_RELEASE_SUCCESS_0_8822B)
+#define BIT_GET_R_MACID_RELEASE_SUCCESS_0_8822B(x) \
+ (((x) >> BIT_SHIFT_R_MACID_RELEASE_SUCCESS_0_8822B) & \
+ BIT_MASK_R_MACID_RELEASE_SUCCESS_0_8822B)
+
+/* 2 REG_R_MACID_RELEASE_SUCCESS_1_8822B */
+
+#define BIT_SHIFT_R_MACID_RELEASE_SUCCESS_1_8822B 0
+#define BIT_MASK_R_MACID_RELEASE_SUCCESS_1_8822B 0xffffffffL
+#define BIT_R_MACID_RELEASE_SUCCESS_1_8822B(x) \
+ (((x) & BIT_MASK_R_MACID_RELEASE_SUCCESS_1_8822B) \
+ << BIT_SHIFT_R_MACID_RELEASE_SUCCESS_1_8822B)
+#define BIT_GET_R_MACID_RELEASE_SUCCESS_1_8822B(x) \
+ (((x) >> BIT_SHIFT_R_MACID_RELEASE_SUCCESS_1_8822B) & \
+ BIT_MASK_R_MACID_RELEASE_SUCCESS_1_8822B)
+
+/* 2 REG_R_MACID_RELEASE_SUCCESS_2_8822B */
+
+#define BIT_SHIFT_R_MACID_RELEASE_SUCCESS_2_8822B 0
+#define BIT_MASK_R_MACID_RELEASE_SUCCESS_2_8822B 0xffffffffL
+#define BIT_R_MACID_RELEASE_SUCCESS_2_8822B(x) \
+ (((x) & BIT_MASK_R_MACID_RELEASE_SUCCESS_2_8822B) \
+ << BIT_SHIFT_R_MACID_RELEASE_SUCCESS_2_8822B)
+#define BIT_GET_R_MACID_RELEASE_SUCCESS_2_8822B(x) \
+ (((x) >> BIT_SHIFT_R_MACID_RELEASE_SUCCESS_2_8822B) & \
+ BIT_MASK_R_MACID_RELEASE_SUCCESS_2_8822B)
+
+/* 2 REG_R_MACID_RELEASE_SUCCESS_3_8822B */
+
+#define BIT_SHIFT_R_MACID_RELEASE_SUCCESS_3_8822B 0
+#define BIT_MASK_R_MACID_RELEASE_SUCCESS_3_8822B 0xffffffffL
+#define BIT_R_MACID_RELEASE_SUCCESS_3_8822B(x) \
+ (((x) & BIT_MASK_R_MACID_RELEASE_SUCCESS_3_8822B) \
+ << BIT_SHIFT_R_MACID_RELEASE_SUCCESS_3_8822B)
+#define BIT_GET_R_MACID_RELEASE_SUCCESS_3_8822B(x) \
+ (((x) >> BIT_SHIFT_R_MACID_RELEASE_SUCCESS_3_8822B) & \
+ BIT_MASK_R_MACID_RELEASE_SUCCESS_3_8822B)
+
+/* 2 REG_MGG_FIFO_CRTL_8822B */
+#define BIT_R_MGG_FIFO_EN_8822B BIT(31)
+
+#define BIT_SHIFT_R_MGG_FIFO_PG_SIZE_8822B 28
+#define BIT_MASK_R_MGG_FIFO_PG_SIZE_8822B 0x7
+#define BIT_R_MGG_FIFO_PG_SIZE_8822B(x) \
+ (((x) & BIT_MASK_R_MGG_FIFO_PG_SIZE_8822B) \
+ << BIT_SHIFT_R_MGG_FIFO_PG_SIZE_8822B)
+#define BIT_GET_R_MGG_FIFO_PG_SIZE_8822B(x) \
+ (((x) >> BIT_SHIFT_R_MGG_FIFO_PG_SIZE_8822B) & \
+ BIT_MASK_R_MGG_FIFO_PG_SIZE_8822B)
+
+#define BIT_SHIFT_R_MGG_FIFO_START_PG_8822B 16
+#define BIT_MASK_R_MGG_FIFO_START_PG_8822B 0xfff
+#define BIT_R_MGG_FIFO_START_PG_8822B(x) \
+ (((x) & BIT_MASK_R_MGG_FIFO_START_PG_8822B) \
+ << BIT_SHIFT_R_MGG_FIFO_START_PG_8822B)
+#define BIT_GET_R_MGG_FIFO_START_PG_8822B(x) \
+ (((x) >> BIT_SHIFT_R_MGG_FIFO_START_PG_8822B) & \
+ BIT_MASK_R_MGG_FIFO_START_PG_8822B)
+
+#define BIT_SHIFT_R_MGG_FIFO_SIZE_8822B 14
+#define BIT_MASK_R_MGG_FIFO_SIZE_8822B 0x3
+#define BIT_R_MGG_FIFO_SIZE_8822B(x) \
+ (((x) & BIT_MASK_R_MGG_FIFO_SIZE_8822B) \
+ << BIT_SHIFT_R_MGG_FIFO_SIZE_8822B)
+#define BIT_GET_R_MGG_FIFO_SIZE_8822B(x) \
+ (((x) >> BIT_SHIFT_R_MGG_FIFO_SIZE_8822B) & \
+ BIT_MASK_R_MGG_FIFO_SIZE_8822B)
+
+#define BIT_R_MGG_FIFO_PAUSE_8822B BIT(13)
+
+#define BIT_SHIFT_R_MGG_FIFO_RPTR_8822B 8
+#define BIT_MASK_R_MGG_FIFO_RPTR_8822B 0x1f
+#define BIT_R_MGG_FIFO_RPTR_8822B(x) \
+ (((x) & BIT_MASK_R_MGG_FIFO_RPTR_8822B) \
+ << BIT_SHIFT_R_MGG_FIFO_RPTR_8822B)
+#define BIT_GET_R_MGG_FIFO_RPTR_8822B(x) \
+ (((x) >> BIT_SHIFT_R_MGG_FIFO_RPTR_8822B) & \
+ BIT_MASK_R_MGG_FIFO_RPTR_8822B)
+
+#define BIT_R_MGG_FIFO_OV_8822B BIT(7)
+#define BIT_R_MGG_FIFO_WPTR_ERROR_8822B BIT(6)
+#define BIT_R_EN_CPU_LIFETIME_8822B BIT(5)
+
+#define BIT_SHIFT_R_MGG_FIFO_WPTR_8822B 0
+#define BIT_MASK_R_MGG_FIFO_WPTR_8822B 0x1f
+#define BIT_R_MGG_FIFO_WPTR_8822B(x) \
+ (((x) & BIT_MASK_R_MGG_FIFO_WPTR_8822B) \
+ << BIT_SHIFT_R_MGG_FIFO_WPTR_8822B)
+#define BIT_GET_R_MGG_FIFO_WPTR_8822B(x) \
+ (((x) >> BIT_SHIFT_R_MGG_FIFO_WPTR_8822B) & \
+ BIT_MASK_R_MGG_FIFO_WPTR_8822B)
+
+/* 2 REG_MGG_FIFO_INT_8822B */
+
+#define BIT_SHIFT_R_MGG_FIFO_INT_FLAG_8822B 16
+#define BIT_MASK_R_MGG_FIFO_INT_FLAG_8822B 0xffff
+#define BIT_R_MGG_FIFO_INT_FLAG_8822B(x) \
+ (((x) & BIT_MASK_R_MGG_FIFO_INT_FLAG_8822B) \
+ << BIT_SHIFT_R_MGG_FIFO_INT_FLAG_8822B)
+#define BIT_GET_R_MGG_FIFO_INT_FLAG_8822B(x) \
+ (((x) >> BIT_SHIFT_R_MGG_FIFO_INT_FLAG_8822B) & \
+ BIT_MASK_R_MGG_FIFO_INT_FLAG_8822B)
+
+#define BIT_SHIFT_R_MGG_FIFO_INT_MASK_8822B 0
+#define BIT_MASK_R_MGG_FIFO_INT_MASK_8822B 0xffff
+#define BIT_R_MGG_FIFO_INT_MASK_8822B(x) \
+ (((x) & BIT_MASK_R_MGG_FIFO_INT_MASK_8822B) \
+ << BIT_SHIFT_R_MGG_FIFO_INT_MASK_8822B)
+#define BIT_GET_R_MGG_FIFO_INT_MASK_8822B(x) \
+ (((x) >> BIT_SHIFT_R_MGG_FIFO_INT_MASK_8822B) & \
+ BIT_MASK_R_MGG_FIFO_INT_MASK_8822B)
+
+/* 2 REG_MGG_FIFO_LIFETIME_8822B */
+
+#define BIT_SHIFT_R_MGG_FIFO_LIFETIME_8822B 16
+#define BIT_MASK_R_MGG_FIFO_LIFETIME_8822B 0xffff
+#define BIT_R_MGG_FIFO_LIFETIME_8822B(x) \
+ (((x) & BIT_MASK_R_MGG_FIFO_LIFETIME_8822B) \
+ << BIT_SHIFT_R_MGG_FIFO_LIFETIME_8822B)
+#define BIT_GET_R_MGG_FIFO_LIFETIME_8822B(x) \
+ (((x) >> BIT_SHIFT_R_MGG_FIFO_LIFETIME_8822B) & \
+ BIT_MASK_R_MGG_FIFO_LIFETIME_8822B)
+
+#define BIT_SHIFT_R_MGG_FIFO_VALID_MAP_8822B 0
+#define BIT_MASK_R_MGG_FIFO_VALID_MAP_8822B 0xffff
+#define BIT_R_MGG_FIFO_VALID_MAP_8822B(x) \
+ (((x) & BIT_MASK_R_MGG_FIFO_VALID_MAP_8822B) \
+ << BIT_SHIFT_R_MGG_FIFO_VALID_MAP_8822B)
+#define BIT_GET_R_MGG_FIFO_VALID_MAP_8822B(x) \
+ (((x) >> BIT_SHIFT_R_MGG_FIFO_VALID_MAP_8822B) & \
+ BIT_MASK_R_MGG_FIFO_VALID_MAP_8822B)
+
+/* 2 REG_R_MACID_RELEASE_SUCCESS_CLEAR_OFFSET_8822B */
+
+#define BIT_SHIFT_R_MACID_RELEASE_SUCCESS_CLEAR_OFFSET_8822B 0
+#define BIT_MASK_R_MACID_RELEASE_SUCCESS_CLEAR_OFFSET_8822B 0x7f
+#define BIT_R_MACID_RELEASE_SUCCESS_CLEAR_OFFSET_8822B(x) \
+ (((x) & BIT_MASK_R_MACID_RELEASE_SUCCESS_CLEAR_OFFSET_8822B) \
+ << BIT_SHIFT_R_MACID_RELEASE_SUCCESS_CLEAR_OFFSET_8822B)
+#define BIT_GET_R_MACID_RELEASE_SUCCESS_CLEAR_OFFSET_8822B(x) \
+ (((x) >> BIT_SHIFT_R_MACID_RELEASE_SUCCESS_CLEAR_OFFSET_8822B) & \
+ BIT_MASK_R_MACID_RELEASE_SUCCESS_CLEAR_OFFSET_8822B)
+
+/* 2 REG_MACID_SHCUT_OFFSET_8822B */
+
+#define BIT_SHIFT_MACID_SHCUT_OFFSET_V1_8822B 0
+#define BIT_MASK_MACID_SHCUT_OFFSET_V1_8822B 0xff
+#define BIT_MACID_SHCUT_OFFSET_V1_8822B(x) \
+ (((x) & BIT_MASK_MACID_SHCUT_OFFSET_V1_8822B) \
+ << BIT_SHIFT_MACID_SHCUT_OFFSET_V1_8822B)
+#define BIT_GET_MACID_SHCUT_OFFSET_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_MACID_SHCUT_OFFSET_V1_8822B) & \
+ BIT_MASK_MACID_SHCUT_OFFSET_V1_8822B)
+
+/* 2 REG_MU_TX_CTL_8822B */
+#define BIT_R_EN_REVERS_GTAB_8822B BIT(6)
+
+#define BIT_SHIFT_R_MU_TABLE_VALID_8822B 0
+#define BIT_MASK_R_MU_TABLE_VALID_8822B 0x3f
+#define BIT_R_MU_TABLE_VALID_8822B(x) \
+ (((x) & BIT_MASK_R_MU_TABLE_VALID_8822B) \
+ << BIT_SHIFT_R_MU_TABLE_VALID_8822B)
+#define BIT_GET_R_MU_TABLE_VALID_8822B(x) \
+ (((x) >> BIT_SHIFT_R_MU_TABLE_VALID_8822B) & \
+ BIT_MASK_R_MU_TABLE_VALID_8822B)
+
+/* 2 REG_MU_STA_GID_VLD_8822B */
+
+/* 2 REG_NOT_VALID_8822B */
+
+#define BIT_SHIFT_R_MU_STA_GTAB_VALID_8822B 0
+#define BIT_MASK_R_MU_STA_GTAB_VALID_8822B 0xffffffffL
+#define BIT_R_MU_STA_GTAB_VALID_8822B(x) \
+ (((x) & BIT_MASK_R_MU_STA_GTAB_VALID_8822B) \
+ << BIT_SHIFT_R_MU_STA_GTAB_VALID_8822B)
+#define BIT_GET_R_MU_STA_GTAB_VALID_8822B(x) \
+ (((x) >> BIT_SHIFT_R_MU_STA_GTAB_VALID_8822B) & \
+ BIT_MASK_R_MU_STA_GTAB_VALID_8822B)
+
+#define BIT_SHIFT_R_MU_STA_GTAB_VALID_8822B 0
+#define BIT_MASK_R_MU_STA_GTAB_VALID_8822B 0xffffffffL
+#define BIT_R_MU_STA_GTAB_VALID_8822B(x) \
+ (((x) & BIT_MASK_R_MU_STA_GTAB_VALID_8822B) \
+ << BIT_SHIFT_R_MU_STA_GTAB_VALID_8822B)
+#define BIT_GET_R_MU_STA_GTAB_VALID_8822B(x) \
+ (((x) >> BIT_SHIFT_R_MU_STA_GTAB_VALID_8822B) & \
+ BIT_MASK_R_MU_STA_GTAB_VALID_8822B)
+
+/* 2 REG_MU_STA_USER_POS_INFO_8822B */
+
+/* 2 REG_NOT_VALID_8822B */
+
+#define BIT_SHIFT_R_MU_STA_GTAB_POSITION_8822B 0
+#define BIT_MASK_R_MU_STA_GTAB_POSITION_8822B 0xffffffffffffffffL
+#define BIT_R_MU_STA_GTAB_POSITION_8822B(x) \
+ (((x) & BIT_MASK_R_MU_STA_GTAB_POSITION_8822B) \
+ << BIT_SHIFT_R_MU_STA_GTAB_POSITION_8822B)
+#define BIT_GET_R_MU_STA_GTAB_POSITION_8822B(x) \
+ (((x) >> BIT_SHIFT_R_MU_STA_GTAB_POSITION_8822B) & \
+ BIT_MASK_R_MU_STA_GTAB_POSITION_8822B)
+
+#define BIT_SHIFT_R_MU_STA_GTAB_POSITION_8822B 0
+#define BIT_MASK_R_MU_STA_GTAB_POSITION_8822B 0xffffffffffffffffL
+#define BIT_R_MU_STA_GTAB_POSITION_8822B(x) \
+ (((x) & BIT_MASK_R_MU_STA_GTAB_POSITION_8822B) \
+ << BIT_SHIFT_R_MU_STA_GTAB_POSITION_8822B)
+#define BIT_GET_R_MU_STA_GTAB_POSITION_8822B(x) \
+ (((x) >> BIT_SHIFT_R_MU_STA_GTAB_POSITION_8822B) & \
+ BIT_MASK_R_MU_STA_GTAB_POSITION_8822B)
+
+/* 2 REG_MU_TRX_DBG_CNT_8822B */
+#define BIT_MU_DNGCNT_RST_8822B BIT(20)
+
+#define BIT_SHIFT_MU_DBGCNT_SEL_8822B 16
+#define BIT_MASK_MU_DBGCNT_SEL_8822B 0xf
+#define BIT_MU_DBGCNT_SEL_8822B(x) \
+ (((x) & BIT_MASK_MU_DBGCNT_SEL_8822B) << BIT_SHIFT_MU_DBGCNT_SEL_8822B)
+#define BIT_GET_MU_DBGCNT_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_MU_DBGCNT_SEL_8822B) & BIT_MASK_MU_DBGCNT_SEL_8822B)
+
+#define BIT_SHIFT_MU_DNGCNT_8822B 0
+#define BIT_MASK_MU_DNGCNT_8822B 0xffff
+#define BIT_MU_DNGCNT_8822B(x) \
+ (((x) & BIT_MASK_MU_DNGCNT_8822B) << BIT_SHIFT_MU_DNGCNT_8822B)
+#define BIT_GET_MU_DNGCNT_8822B(x) \
+ (((x) >> BIT_SHIFT_MU_DNGCNT_8822B) & BIT_MASK_MU_DNGCNT_8822B)
+
+/* 2 REG_NOT_VALID_8822B */
+
+/* 2 REG_EDCA_VO_PARAM_8822B */
+
+#define BIT_SHIFT_TXOPLIMIT_8822B 16
+#define BIT_MASK_TXOPLIMIT_8822B 0x7ff
+#define BIT_TXOPLIMIT_8822B(x) \
+ (((x) & BIT_MASK_TXOPLIMIT_8822B) << BIT_SHIFT_TXOPLIMIT_8822B)
+#define BIT_GET_TXOPLIMIT_8822B(x) \
+ (((x) >> BIT_SHIFT_TXOPLIMIT_8822B) & BIT_MASK_TXOPLIMIT_8822B)
+
+#define BIT_SHIFT_CW_8822B 8
+#define BIT_MASK_CW_8822B 0xff
+#define BIT_CW_8822B(x) (((x) & BIT_MASK_CW_8822B) << BIT_SHIFT_CW_8822B)
+#define BIT_GET_CW_8822B(x) (((x) >> BIT_SHIFT_CW_8822B) & BIT_MASK_CW_8822B)
+
+#define BIT_SHIFT_AIFS_8822B 0
+#define BIT_MASK_AIFS_8822B 0xff
+#define BIT_AIFS_8822B(x) (((x) & BIT_MASK_AIFS_8822B) << BIT_SHIFT_AIFS_8822B)
+#define BIT_GET_AIFS_8822B(x) \
+ (((x) >> BIT_SHIFT_AIFS_8822B) & BIT_MASK_AIFS_8822B)
+
+/* 2 REG_EDCA_VI_PARAM_8822B */
+
+/* 2 REG_NOT_VALID_8822B */
+
+#define BIT_SHIFT_TXOPLIMIT_8822B 16
+#define BIT_MASK_TXOPLIMIT_8822B 0x7ff
+#define BIT_TXOPLIMIT_8822B(x) \
+ (((x) & BIT_MASK_TXOPLIMIT_8822B) << BIT_SHIFT_TXOPLIMIT_8822B)
+#define BIT_GET_TXOPLIMIT_8822B(x) \
+ (((x) >> BIT_SHIFT_TXOPLIMIT_8822B) & BIT_MASK_TXOPLIMIT_8822B)
+
+#define BIT_SHIFT_CW_8822B 8
+#define BIT_MASK_CW_8822B 0xff
+#define BIT_CW_8822B(x) (((x) & BIT_MASK_CW_8822B) << BIT_SHIFT_CW_8822B)
+#define BIT_GET_CW_8822B(x) (((x) >> BIT_SHIFT_CW_8822B) & BIT_MASK_CW_8822B)
+
+#define BIT_SHIFT_AIFS_8822B 0
+#define BIT_MASK_AIFS_8822B 0xff
+#define BIT_AIFS_8822B(x) (((x) & BIT_MASK_AIFS_8822B) << BIT_SHIFT_AIFS_8822B)
+#define BIT_GET_AIFS_8822B(x) \
+ (((x) >> BIT_SHIFT_AIFS_8822B) & BIT_MASK_AIFS_8822B)
+
+/* 2 REG_EDCA_BE_PARAM_8822B */
+
+/* 2 REG_NOT_VALID_8822B */
+
+#define BIT_SHIFT_TXOPLIMIT_8822B 16
+#define BIT_MASK_TXOPLIMIT_8822B 0x7ff
+#define BIT_TXOPLIMIT_8822B(x) \
+ (((x) & BIT_MASK_TXOPLIMIT_8822B) << BIT_SHIFT_TXOPLIMIT_8822B)
+#define BIT_GET_TXOPLIMIT_8822B(x) \
+ (((x) >> BIT_SHIFT_TXOPLIMIT_8822B) & BIT_MASK_TXOPLIMIT_8822B)
+
+#define BIT_SHIFT_CW_8822B 8
+#define BIT_MASK_CW_8822B 0xff
+#define BIT_CW_8822B(x) (((x) & BIT_MASK_CW_8822B) << BIT_SHIFT_CW_8822B)
+#define BIT_GET_CW_8822B(x) (((x) >> BIT_SHIFT_CW_8822B) & BIT_MASK_CW_8822B)
+
+#define BIT_SHIFT_AIFS_8822B 0
+#define BIT_MASK_AIFS_8822B 0xff
+#define BIT_AIFS_8822B(x) (((x) & BIT_MASK_AIFS_8822B) << BIT_SHIFT_AIFS_8822B)
+#define BIT_GET_AIFS_8822B(x) \
+ (((x) >> BIT_SHIFT_AIFS_8822B) & BIT_MASK_AIFS_8822B)
+
+/* 2 REG_EDCA_BK_PARAM_8822B */
+
+/* 2 REG_NOT_VALID_8822B */
+
+#define BIT_SHIFT_TXOPLIMIT_8822B 16
+#define BIT_MASK_TXOPLIMIT_8822B 0x7ff
+#define BIT_TXOPLIMIT_8822B(x) \
+ (((x) & BIT_MASK_TXOPLIMIT_8822B) << BIT_SHIFT_TXOPLIMIT_8822B)
+#define BIT_GET_TXOPLIMIT_8822B(x) \
+ (((x) >> BIT_SHIFT_TXOPLIMIT_8822B) & BIT_MASK_TXOPLIMIT_8822B)
+
+#define BIT_SHIFT_CW_8822B 8
+#define BIT_MASK_CW_8822B 0xff
+#define BIT_CW_8822B(x) (((x) & BIT_MASK_CW_8822B) << BIT_SHIFT_CW_8822B)
+#define BIT_GET_CW_8822B(x) (((x) >> BIT_SHIFT_CW_8822B) & BIT_MASK_CW_8822B)
+
+#define BIT_SHIFT_AIFS_8822B 0
+#define BIT_MASK_AIFS_8822B 0xff
+#define BIT_AIFS_8822B(x) (((x) & BIT_MASK_AIFS_8822B) << BIT_SHIFT_AIFS_8822B)
+#define BIT_GET_AIFS_8822B(x) \
+ (((x) >> BIT_SHIFT_AIFS_8822B) & BIT_MASK_AIFS_8822B)
+
+/* 2 REG_BCNTCFG_8822B */
+
+#define BIT_SHIFT_BCNCW_MAX_8822B 12
+#define BIT_MASK_BCNCW_MAX_8822B 0xf
+#define BIT_BCNCW_MAX_8822B(x) \
+ (((x) & BIT_MASK_BCNCW_MAX_8822B) << BIT_SHIFT_BCNCW_MAX_8822B)
+#define BIT_GET_BCNCW_MAX_8822B(x) \
+ (((x) >> BIT_SHIFT_BCNCW_MAX_8822B) & BIT_MASK_BCNCW_MAX_8822B)
+
+#define BIT_SHIFT_BCNCW_MIN_8822B 8
+#define BIT_MASK_BCNCW_MIN_8822B 0xf
+#define BIT_BCNCW_MIN_8822B(x) \
+ (((x) & BIT_MASK_BCNCW_MIN_8822B) << BIT_SHIFT_BCNCW_MIN_8822B)
+#define BIT_GET_BCNCW_MIN_8822B(x) \
+ (((x) >> BIT_SHIFT_BCNCW_MIN_8822B) & BIT_MASK_BCNCW_MIN_8822B)
+
+#define BIT_SHIFT_BCNIFS_8822B 0
+#define BIT_MASK_BCNIFS_8822B 0xff
+#define BIT_BCNIFS_8822B(x) \
+ (((x) & BIT_MASK_BCNIFS_8822B) << BIT_SHIFT_BCNIFS_8822B)
+#define BIT_GET_BCNIFS_8822B(x) \
+ (((x) >> BIT_SHIFT_BCNIFS_8822B) & BIT_MASK_BCNIFS_8822B)
+
+/* 2 REG_PIFS_8822B */
+
+#define BIT_SHIFT_PIFS_8822B 0
+#define BIT_MASK_PIFS_8822B 0xff
+#define BIT_PIFS_8822B(x) (((x) & BIT_MASK_PIFS_8822B) << BIT_SHIFT_PIFS_8822B)
+#define BIT_GET_PIFS_8822B(x) \
+ (((x) >> BIT_SHIFT_PIFS_8822B) & BIT_MASK_PIFS_8822B)
+
+/* 2 REG_RDG_PIFS_8822B */
+
+#define BIT_SHIFT_RDG_PIFS_8822B 0
+#define BIT_MASK_RDG_PIFS_8822B 0xff
+#define BIT_RDG_PIFS_8822B(x) \
+ (((x) & BIT_MASK_RDG_PIFS_8822B) << BIT_SHIFT_RDG_PIFS_8822B)
+#define BIT_GET_RDG_PIFS_8822B(x) \
+ (((x) >> BIT_SHIFT_RDG_PIFS_8822B) & BIT_MASK_RDG_PIFS_8822B)
+
+/* 2 REG_SIFS_8822B */
+
+#define BIT_SHIFT_SIFS_OFDM_TRX_8822B 24
+#define BIT_MASK_SIFS_OFDM_TRX_8822B 0xff
+#define BIT_SIFS_OFDM_TRX_8822B(x) \
+ (((x) & BIT_MASK_SIFS_OFDM_TRX_8822B) << BIT_SHIFT_SIFS_OFDM_TRX_8822B)
+#define BIT_GET_SIFS_OFDM_TRX_8822B(x) \
+ (((x) >> BIT_SHIFT_SIFS_OFDM_TRX_8822B) & BIT_MASK_SIFS_OFDM_TRX_8822B)
+
+#define BIT_SHIFT_SIFS_CCK_TRX_8822B 16
+#define BIT_MASK_SIFS_CCK_TRX_8822B 0xff
+#define BIT_SIFS_CCK_TRX_8822B(x) \
+ (((x) & BIT_MASK_SIFS_CCK_TRX_8822B) << BIT_SHIFT_SIFS_CCK_TRX_8822B)
+#define BIT_GET_SIFS_CCK_TRX_8822B(x) \
+ (((x) >> BIT_SHIFT_SIFS_CCK_TRX_8822B) & BIT_MASK_SIFS_CCK_TRX_8822B)
+
+#define BIT_SHIFT_SIFS_OFDM_CTX_8822B 8
+#define BIT_MASK_SIFS_OFDM_CTX_8822B 0xff
+#define BIT_SIFS_OFDM_CTX_8822B(x) \
+ (((x) & BIT_MASK_SIFS_OFDM_CTX_8822B) << BIT_SHIFT_SIFS_OFDM_CTX_8822B)
+#define BIT_GET_SIFS_OFDM_CTX_8822B(x) \
+ (((x) >> BIT_SHIFT_SIFS_OFDM_CTX_8822B) & BIT_MASK_SIFS_OFDM_CTX_8822B)
+
+#define BIT_SHIFT_SIFS_CCK_CTX_8822B 0
+#define BIT_MASK_SIFS_CCK_CTX_8822B 0xff
+#define BIT_SIFS_CCK_CTX_8822B(x) \
+ (((x) & BIT_MASK_SIFS_CCK_CTX_8822B) << BIT_SHIFT_SIFS_CCK_CTX_8822B)
+#define BIT_GET_SIFS_CCK_CTX_8822B(x) \
+ (((x) >> BIT_SHIFT_SIFS_CCK_CTX_8822B) & BIT_MASK_SIFS_CCK_CTX_8822B)
+
+/* 2 REG_TSFTR_SYN_OFFSET_8822B */
+
+#define BIT_SHIFT_TSFTR_SNC_OFFSET_8822B 0
+#define BIT_MASK_TSFTR_SNC_OFFSET_8822B 0xffff
+#define BIT_TSFTR_SNC_OFFSET_8822B(x) \
+ (((x) & BIT_MASK_TSFTR_SNC_OFFSET_8822B) \
+ << BIT_SHIFT_TSFTR_SNC_OFFSET_8822B)
+#define BIT_GET_TSFTR_SNC_OFFSET_8822B(x) \
+ (((x) >> BIT_SHIFT_TSFTR_SNC_OFFSET_8822B) & \
+ BIT_MASK_TSFTR_SNC_OFFSET_8822B)
+
+/* 2 REG_AGGR_BREAK_TIME_8822B */
+
+#define BIT_SHIFT_AGGR_BK_TIME_8822B 0
+#define BIT_MASK_AGGR_BK_TIME_8822B 0xff
+#define BIT_AGGR_BK_TIME_8822B(x) \
+ (((x) & BIT_MASK_AGGR_BK_TIME_8822B) << BIT_SHIFT_AGGR_BK_TIME_8822B)
+#define BIT_GET_AGGR_BK_TIME_8822B(x) \
+ (((x) >> BIT_SHIFT_AGGR_BK_TIME_8822B) & BIT_MASK_AGGR_BK_TIME_8822B)
+
+/* 2 REG_SLOT_8822B */
+
+#define BIT_SHIFT_SLOT_8822B 0
+#define BIT_MASK_SLOT_8822B 0xff
+#define BIT_SLOT_8822B(x) (((x) & BIT_MASK_SLOT_8822B) << BIT_SHIFT_SLOT_8822B)
+#define BIT_GET_SLOT_8822B(x) \
+ (((x) >> BIT_SHIFT_SLOT_8822B) & BIT_MASK_SLOT_8822B)
+
+/* 2 REG_TX_PTCL_CTRL_8822B */
+#define BIT_DIS_EDCCA_8822B BIT(15)
+#define BIT_DIS_CCA_8822B BIT(14)
+#define BIT_LSIG_TXOP_TXCMD_NAV_8822B BIT(13)
+#define BIT_SIFS_BK_EN_8822B BIT(12)
+
+#define BIT_SHIFT_TXQ_NAV_MSK_8822B 8
+#define BIT_MASK_TXQ_NAV_MSK_8822B 0xf
+#define BIT_TXQ_NAV_MSK_8822B(x) \
+ (((x) & BIT_MASK_TXQ_NAV_MSK_8822B) << BIT_SHIFT_TXQ_NAV_MSK_8822B)
+#define BIT_GET_TXQ_NAV_MSK_8822B(x) \
+ (((x) >> BIT_SHIFT_TXQ_NAV_MSK_8822B) & BIT_MASK_TXQ_NAV_MSK_8822B)
+
+#define BIT_DIS_CW_8822B BIT(7)
+#define BIT_NAV_END_TXOP_8822B BIT(6)
+#define BIT_RDG_END_TXOP_8822B BIT(5)
+#define BIT_AC_INBCN_HOLD_8822B BIT(4)
+#define BIT_MGTQ_TXOP_EN_8822B BIT(3)
+#define BIT_MGTQ_RTSMF_EN_8822B BIT(2)
+#define BIT_HIQ_RTSMF_EN_8822B BIT(1)
+#define BIT_BCN_RTSMF_EN_8822B BIT(0)
+
+/* 2 REG_TXPAUSE_8822B */
+#define BIT_STOP_BCN_HI_MGT_8822B BIT(7)
+#define BIT_MAC_STOPBCNQ_8822B BIT(6)
+#define BIT_MAC_STOPHIQ_8822B BIT(5)
+#define BIT_MAC_STOPMGQ_8822B BIT(4)
+#define BIT_MAC_STOPBK_8822B BIT(3)
+#define BIT_MAC_STOPBE_8822B BIT(2)
+#define BIT_MAC_STOPVI_8822B BIT(1)
+#define BIT_MAC_STOPVO_8822B BIT(0)
+
+/* 2 REG_DIS_TXREQ_CLR_8822B */
+#define BIT_DIS_BT_CCA_8822B BIT(7)
+#define BIT_DIS_TXREQ_CLR_HI_8822B BIT(5)
+#define BIT_DIS_TXREQ_CLR_MGQ_8822B BIT(4)
+#define BIT_DIS_TXREQ_CLR_VO_8822B BIT(3)
+#define BIT_DIS_TXREQ_CLR_VI_8822B BIT(2)
+#define BIT_DIS_TXREQ_CLR_BE_8822B BIT(1)
+#define BIT_DIS_TXREQ_CLR_BK_8822B BIT(0)
+
+/* 2 REG_RD_CTRL_8822B */
+#define BIT_EN_CLR_TXREQ_INCCA_8822B BIT(15)
+#define BIT_DIS_TX_OVER_BCNQ_8822B BIT(14)
+#define BIT_EN_BCNERR_INCCCA_8822B BIT(13)
+#define BIT_EDCCA_MSK_CNTDOWN_EN_8822B BIT(11)
+#define BIT_DIS_TXOP_CFE_8822B BIT(10)
+#define BIT_DIS_LSIG_CFE_8822B BIT(9)
+#define BIT_DIS_STBC_CFE_8822B BIT(8)
+#define BIT_BKQ_RD_INIT_EN_8822B BIT(7)
+#define BIT_BEQ_RD_INIT_EN_8822B BIT(6)
+#define BIT_VIQ_RD_INIT_EN_8822B BIT(5)
+#define BIT_VOQ_RD_INIT_EN_8822B BIT(4)
+#define BIT_BKQ_RD_RESP_EN_8822B BIT(3)
+#define BIT_BEQ_RD_RESP_EN_8822B BIT(2)
+#define BIT_VIQ_RD_RESP_EN_8822B BIT(1)
+#define BIT_VOQ_RD_RESP_EN_8822B BIT(0)
+
+/* 2 REG_MBSSID_CTRL_8822B */
+#define BIT_MBID_BCNQ7_EN_8822B BIT(7)
+#define BIT_MBID_BCNQ6_EN_8822B BIT(6)
+#define BIT_MBID_BCNQ5_EN_8822B BIT(5)
+#define BIT_MBID_BCNQ4_EN_8822B BIT(4)
+#define BIT_MBID_BCNQ3_EN_8822B BIT(3)
+#define BIT_MBID_BCNQ2_EN_8822B BIT(2)
+#define BIT_MBID_BCNQ1_EN_8822B BIT(1)
+#define BIT_MBID_BCNQ0_EN_8822B BIT(0)
+
+/* 2 REG_P2PPS_CTRL_8822B */
+#define BIT_P2P_CTW_ALLSTASLEEP_8822B BIT(7)
+#define BIT_P2P_OFF_DISTX_EN_8822B BIT(6)
+#define BIT_PWR_MGT_EN_8822B BIT(5)
+#define BIT_P2P_NOA1_EN_8822B BIT(2)
+#define BIT_P2P_NOA0_EN_8822B BIT(1)
+
+/* 2 REG_PKT_LIFETIME_CTRL_8822B */
+#define BIT_EN_P2P_CTWND1_8822B BIT(23)
+#define BIT_EN_BKF_CLR_TXREQ_8822B BIT(22)
+#define BIT_EN_TSFBIT32_RST_P2P_8822B BIT(21)
+#define BIT_EN_BCN_TX_BTCCA_8822B BIT(20)
+#define BIT_DIS_PKT_TX_ATIM_8822B BIT(19)
+#define BIT_DIS_BCN_DIS_CTN_8822B BIT(18)
+#define BIT_EN_NAVEND_RST_TXOP_8822B BIT(17)
+#define BIT_EN_FILTER_CCA_8822B BIT(16)
+
+#define BIT_SHIFT_CCA_FILTER_THRS_8822B 8
+#define BIT_MASK_CCA_FILTER_THRS_8822B 0xff
+#define BIT_CCA_FILTER_THRS_8822B(x) \
+ (((x) & BIT_MASK_CCA_FILTER_THRS_8822B) \
+ << BIT_SHIFT_CCA_FILTER_THRS_8822B)
+#define BIT_GET_CCA_FILTER_THRS_8822B(x) \
+ (((x) >> BIT_SHIFT_CCA_FILTER_THRS_8822B) & \
+ BIT_MASK_CCA_FILTER_THRS_8822B)
+
+#define BIT_SHIFT_EDCCA_THRS_8822B 0
+#define BIT_MASK_EDCCA_THRS_8822B 0xff
+#define BIT_EDCCA_THRS_8822B(x) \
+ (((x) & BIT_MASK_EDCCA_THRS_8822B) << BIT_SHIFT_EDCCA_THRS_8822B)
+#define BIT_GET_EDCCA_THRS_8822B(x) \
+ (((x) >> BIT_SHIFT_EDCCA_THRS_8822B) & BIT_MASK_EDCCA_THRS_8822B)
+
+/* 2 REG_P2PPS_SPEC_STATE_8822B */
+#define BIT_SPEC_POWER_STATE_8822B BIT(7)
+#define BIT_SPEC_CTWINDOW_ON_8822B BIT(6)
+#define BIT_SPEC_BEACON_AREA_ON_8822B BIT(5)
+#define BIT_SPEC_CTWIN_EARLY_DISTX_8822B BIT(4)
+#define BIT_SPEC_NOA1_OFF_PERIOD_8822B BIT(3)
+#define BIT_SPEC_FORCE_DOZE1_8822B BIT(2)
+#define BIT_SPEC_NOA0_OFF_PERIOD_8822B BIT(1)
+#define BIT_SPEC_FORCE_DOZE0_8822B BIT(0)
+
+/* 2 REG_BAR_TX_CTRL_8822B */
+
+/* 2 REG_NOT_VALID_8822B */
+
+#define BIT_SHIFT_P2PON_DIS_TXTIME_8822B 0
+#define BIT_MASK_P2PON_DIS_TXTIME_8822B 0xff
+#define BIT_P2PON_DIS_TXTIME_8822B(x) \
+ (((x) & BIT_MASK_P2PON_DIS_TXTIME_8822B) \
+ << BIT_SHIFT_P2PON_DIS_TXTIME_8822B)
+#define BIT_GET_P2PON_DIS_TXTIME_8822B(x) \
+ (((x) >> BIT_SHIFT_P2PON_DIS_TXTIME_8822B) & \
+ BIT_MASK_P2PON_DIS_TXTIME_8822B)
+
+/* 2 REG_QUEUE_INCOL_THR_8822B */
+
+#define BIT_SHIFT_BK_QUEUE_THR_8822B 24
+#define BIT_MASK_BK_QUEUE_THR_8822B 0xff
+#define BIT_BK_QUEUE_THR_8822B(x) \
+ (((x) & BIT_MASK_BK_QUEUE_THR_8822B) << BIT_SHIFT_BK_QUEUE_THR_8822B)
+#define BIT_GET_BK_QUEUE_THR_8822B(x) \
+ (((x) >> BIT_SHIFT_BK_QUEUE_THR_8822B) & BIT_MASK_BK_QUEUE_THR_8822B)
+
+#define BIT_SHIFT_BE_QUEUE_THR_8822B 16
+#define BIT_MASK_BE_QUEUE_THR_8822B 0xff
+#define BIT_BE_QUEUE_THR_8822B(x) \
+ (((x) & BIT_MASK_BE_QUEUE_THR_8822B) << BIT_SHIFT_BE_QUEUE_THR_8822B)
+#define BIT_GET_BE_QUEUE_THR_8822B(x) \
+ (((x) >> BIT_SHIFT_BE_QUEUE_THR_8822B) & BIT_MASK_BE_QUEUE_THR_8822B)
+
+#define BIT_SHIFT_VI_QUEUE_THR_8822B 8
+#define BIT_MASK_VI_QUEUE_THR_8822B 0xff
+#define BIT_VI_QUEUE_THR_8822B(x) \
+ (((x) & BIT_MASK_VI_QUEUE_THR_8822B) << BIT_SHIFT_VI_QUEUE_THR_8822B)
+#define BIT_GET_VI_QUEUE_THR_8822B(x) \
+ (((x) >> BIT_SHIFT_VI_QUEUE_THR_8822B) & BIT_MASK_VI_QUEUE_THR_8822B)
+
+#define BIT_SHIFT_VO_QUEUE_THR_8822B 0
+#define BIT_MASK_VO_QUEUE_THR_8822B 0xff
+#define BIT_VO_QUEUE_THR_8822B(x) \
+ (((x) & BIT_MASK_VO_QUEUE_THR_8822B) << BIT_SHIFT_VO_QUEUE_THR_8822B)
+#define BIT_GET_VO_QUEUE_THR_8822B(x) \
+ (((x) >> BIT_SHIFT_VO_QUEUE_THR_8822B) & BIT_MASK_VO_QUEUE_THR_8822B)
+
+/* 2 REG_QUEUE_INCOL_EN_8822B */
+#define BIT_QUEUE_INCOL_EN_8822B BIT(16)
+
+#define BIT_SHIFT_BE_TRIGGER_NUM_8822B 12
+#define BIT_MASK_BE_TRIGGER_NUM_8822B 0xf
+#define BIT_BE_TRIGGER_NUM_8822B(x) \
+ (((x) & BIT_MASK_BE_TRIGGER_NUM_8822B) \
+ << BIT_SHIFT_BE_TRIGGER_NUM_8822B)
+#define BIT_GET_BE_TRIGGER_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_BE_TRIGGER_NUM_8822B) & \
+ BIT_MASK_BE_TRIGGER_NUM_8822B)
+
+#define BIT_SHIFT_BK_TRIGGER_NUM_8822B 8
+#define BIT_MASK_BK_TRIGGER_NUM_8822B 0xf
+#define BIT_BK_TRIGGER_NUM_8822B(x) \
+ (((x) & BIT_MASK_BK_TRIGGER_NUM_8822B) \
+ << BIT_SHIFT_BK_TRIGGER_NUM_8822B)
+#define BIT_GET_BK_TRIGGER_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_BK_TRIGGER_NUM_8822B) & \
+ BIT_MASK_BK_TRIGGER_NUM_8822B)
+
+#define BIT_SHIFT_VI_TRIGGER_NUM_8822B 4
+#define BIT_MASK_VI_TRIGGER_NUM_8822B 0xf
+#define BIT_VI_TRIGGER_NUM_8822B(x) \
+ (((x) & BIT_MASK_VI_TRIGGER_NUM_8822B) \
+ << BIT_SHIFT_VI_TRIGGER_NUM_8822B)
+#define BIT_GET_VI_TRIGGER_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_VI_TRIGGER_NUM_8822B) & \
+ BIT_MASK_VI_TRIGGER_NUM_8822B)
+
+#define BIT_SHIFT_VO_TRIGGER_NUM_8822B 0
+#define BIT_MASK_VO_TRIGGER_NUM_8822B 0xf
+#define BIT_VO_TRIGGER_NUM_8822B(x) \
+ (((x) & BIT_MASK_VO_TRIGGER_NUM_8822B) \
+ << BIT_SHIFT_VO_TRIGGER_NUM_8822B)
+#define BIT_GET_VO_TRIGGER_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_VO_TRIGGER_NUM_8822B) & \
+ BIT_MASK_VO_TRIGGER_NUM_8822B)
+
+/* 2 REG_TBTT_PROHIBIT_8822B */
+
+#define BIT_SHIFT_TBTT_HOLD_TIME_AP_8822B 8
+#define BIT_MASK_TBTT_HOLD_TIME_AP_8822B 0xfff
+#define BIT_TBTT_HOLD_TIME_AP_8822B(x) \
+ (((x) & BIT_MASK_TBTT_HOLD_TIME_AP_8822B) \
+ << BIT_SHIFT_TBTT_HOLD_TIME_AP_8822B)
+#define BIT_GET_TBTT_HOLD_TIME_AP_8822B(x) \
+ (((x) >> BIT_SHIFT_TBTT_HOLD_TIME_AP_8822B) & \
+ BIT_MASK_TBTT_HOLD_TIME_AP_8822B)
+
+#define BIT_SHIFT_TBTT_PROHIBIT_SETUP_8822B 0
+#define BIT_MASK_TBTT_PROHIBIT_SETUP_8822B 0xf
+#define BIT_TBTT_PROHIBIT_SETUP_8822B(x) \
+ (((x) & BIT_MASK_TBTT_PROHIBIT_SETUP_8822B) \
+ << BIT_SHIFT_TBTT_PROHIBIT_SETUP_8822B)
+#define BIT_GET_TBTT_PROHIBIT_SETUP_8822B(x) \
+ (((x) >> BIT_SHIFT_TBTT_PROHIBIT_SETUP_8822B) & \
+ BIT_MASK_TBTT_PROHIBIT_SETUP_8822B)
+
+/* 2 REG_P2PPS_STATE_8822B */
+#define BIT_POWER_STATE_8822B BIT(7)
+#define BIT_CTWINDOW_ON_8822B BIT(6)
+#define BIT_BEACON_AREA_ON_8822B BIT(5)
+#define BIT_CTWIN_EARLY_DISTX_8822B BIT(4)
+#define BIT_NOA1_OFF_PERIOD_8822B BIT(3)
+#define BIT_FORCE_DOZE1_8822B BIT(2)
+#define BIT_NOA0_OFF_PERIOD_8822B BIT(1)
+#define BIT_FORCE_DOZE0_8822B BIT(0)
+
+/* 2 REG_RD_NAV_NXT_8822B */
+
+#define BIT_SHIFT_RD_NAV_PROT_NXT_8822B 0
+#define BIT_MASK_RD_NAV_PROT_NXT_8822B 0xffff
+#define BIT_RD_NAV_PROT_NXT_8822B(x) \
+ (((x) & BIT_MASK_RD_NAV_PROT_NXT_8822B) \
+ << BIT_SHIFT_RD_NAV_PROT_NXT_8822B)
+#define BIT_GET_RD_NAV_PROT_NXT_8822B(x) \
+ (((x) >> BIT_SHIFT_RD_NAV_PROT_NXT_8822B) & \
+ BIT_MASK_RD_NAV_PROT_NXT_8822B)
+
+/* 2 REG_NAV_PROT_LEN_8822B */
+
+#define BIT_SHIFT_NAV_PROT_LEN_8822B 0
+#define BIT_MASK_NAV_PROT_LEN_8822B 0xffff
+#define BIT_NAV_PROT_LEN_8822B(x) \
+ (((x) & BIT_MASK_NAV_PROT_LEN_8822B) << BIT_SHIFT_NAV_PROT_LEN_8822B)
+#define BIT_GET_NAV_PROT_LEN_8822B(x) \
+ (((x) >> BIT_SHIFT_NAV_PROT_LEN_8822B) & BIT_MASK_NAV_PROT_LEN_8822B)
+
+/* 2 REG_BCN_CTRL_8822B */
+#define BIT_DIS_RX_BSSID_FIT_8822B BIT(6)
+#define BIT_P0_EN_TXBCN_RPT_8822B BIT(5)
+#define BIT_DIS_TSF_UDT_8822B BIT(4)
+#define BIT_EN_BCN_FUNCTION_8822B BIT(3)
+#define BIT_P0_EN_RXBCN_RPT_8822B BIT(2)
+#define BIT_EN_P2P_CTWINDOW_8822B BIT(1)
+#define BIT_EN_P2P_BCNQ_AREA_8822B BIT(0)
+
+/* 2 REG_BCN_CTRL_CLINT0_8822B */
+#define BIT_CLI0_DIS_RX_BSSID_FIT_8822B BIT(6)
+#define BIT_CLI0_DIS_TSF_UDT_8822B BIT(4)
+#define BIT_CLI0_EN_BCN_FUNCTION_8822B BIT(3)
+#define BIT_CLI0_EN_RXBCN_RPT_8822B BIT(2)
+#define BIT_CLI0_ENP2P_CTWINDOW_8822B BIT(1)
+#define BIT_CLI0_ENP2P_BCNQ_AREA_8822B BIT(0)
+
+/* 2 REG_MBID_NUM_8822B */
+#define BIT_EN_PRE_DL_BEACON_8822B BIT(3)
+
+#define BIT_SHIFT_MBID_BCN_NUM_8822B 0
+#define BIT_MASK_MBID_BCN_NUM_8822B 0x7
+#define BIT_MBID_BCN_NUM_8822B(x) \
+ (((x) & BIT_MASK_MBID_BCN_NUM_8822B) << BIT_SHIFT_MBID_BCN_NUM_8822B)
+#define BIT_GET_MBID_BCN_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_MBID_BCN_NUM_8822B) & BIT_MASK_MBID_BCN_NUM_8822B)
+
+/* 2 REG_DUAL_TSF_RST_8822B */
+#define BIT_FREECNT_RST_8822B BIT(5)
+#define BIT_TSFTR_CLI3_RST_8822B BIT(4)
+#define BIT_TSFTR_CLI2_RST_8822B BIT(3)
+#define BIT_TSFTR_CLI1_RST_8822B BIT(2)
+#define BIT_TSFTR_CLI0_RST_8822B BIT(1)
+#define BIT_TSFTR_RST_8822B BIT(0)
+
+/* 2 REG_MBSSID_BCN_SPACE_8822B */
+
+#define BIT_SHIFT_BCN_TIMER_SEL_FWRD_8822B 28
+#define BIT_MASK_BCN_TIMER_SEL_FWRD_8822B 0x7
+#define BIT_BCN_TIMER_SEL_FWRD_8822B(x) \
+ (((x) & BIT_MASK_BCN_TIMER_SEL_FWRD_8822B) \
+ << BIT_SHIFT_BCN_TIMER_SEL_FWRD_8822B)
+#define BIT_GET_BCN_TIMER_SEL_FWRD_8822B(x) \
+ (((x) >> BIT_SHIFT_BCN_TIMER_SEL_FWRD_8822B) & \
+ BIT_MASK_BCN_TIMER_SEL_FWRD_8822B)
+
+#define BIT_SHIFT_BCN_SPACE_CLINT0_8822B 16
+#define BIT_MASK_BCN_SPACE_CLINT0_8822B 0xfff
+#define BIT_BCN_SPACE_CLINT0_8822B(x) \
+ (((x) & BIT_MASK_BCN_SPACE_CLINT0_8822B) \
+ << BIT_SHIFT_BCN_SPACE_CLINT0_8822B)
+#define BIT_GET_BCN_SPACE_CLINT0_8822B(x) \
+ (((x) >> BIT_SHIFT_BCN_SPACE_CLINT0_8822B) & \
+ BIT_MASK_BCN_SPACE_CLINT0_8822B)
+
+#define BIT_SHIFT_BCN_SPACE0_8822B 0
+#define BIT_MASK_BCN_SPACE0_8822B 0xffff
+#define BIT_BCN_SPACE0_8822B(x) \
+ (((x) & BIT_MASK_BCN_SPACE0_8822B) << BIT_SHIFT_BCN_SPACE0_8822B)
+#define BIT_GET_BCN_SPACE0_8822B(x) \
+ (((x) >> BIT_SHIFT_BCN_SPACE0_8822B) & BIT_MASK_BCN_SPACE0_8822B)
+
+/* 2 REG_DRVERLYINT_8822B */
+
+#define BIT_SHIFT_DRVERLYITV_8822B 0
+#define BIT_MASK_DRVERLYITV_8822B 0xff
+#define BIT_DRVERLYITV_8822B(x) \
+ (((x) & BIT_MASK_DRVERLYITV_8822B) << BIT_SHIFT_DRVERLYITV_8822B)
+#define BIT_GET_DRVERLYITV_8822B(x) \
+ (((x) >> BIT_SHIFT_DRVERLYITV_8822B) & BIT_MASK_DRVERLYITV_8822B)
+
+/* 2 REG_BCNDMATIM_8822B */
+
+#define BIT_SHIFT_BCNDMATIM_8822B 0
+#define BIT_MASK_BCNDMATIM_8822B 0xff
+#define BIT_BCNDMATIM_8822B(x) \
+ (((x) & BIT_MASK_BCNDMATIM_8822B) << BIT_SHIFT_BCNDMATIM_8822B)
+#define BIT_GET_BCNDMATIM_8822B(x) \
+ (((x) >> BIT_SHIFT_BCNDMATIM_8822B) & BIT_MASK_BCNDMATIM_8822B)
+
+/* 2 REG_ATIMWND_8822B */
+
+#define BIT_SHIFT_ATIMWND0_8822B 0
+#define BIT_MASK_ATIMWND0_8822B 0xffff
+#define BIT_ATIMWND0_8822B(x) \
+ (((x) & BIT_MASK_ATIMWND0_8822B) << BIT_SHIFT_ATIMWND0_8822B)
+#define BIT_GET_ATIMWND0_8822B(x) \
+ (((x) >> BIT_SHIFT_ATIMWND0_8822B) & BIT_MASK_ATIMWND0_8822B)
+
+/* 2 REG_USTIME_TSF_8822B */
+
+#define BIT_SHIFT_USTIME_TSF_V1_8822B 0
+#define BIT_MASK_USTIME_TSF_V1_8822B 0xff
+#define BIT_USTIME_TSF_V1_8822B(x) \
+ (((x) & BIT_MASK_USTIME_TSF_V1_8822B) << BIT_SHIFT_USTIME_TSF_V1_8822B)
+#define BIT_GET_USTIME_TSF_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_USTIME_TSF_V1_8822B) & BIT_MASK_USTIME_TSF_V1_8822B)
+
+/* 2 REG_BCN_MAX_ERR_8822B */
+
+#define BIT_SHIFT_BCN_MAX_ERR_8822B 0
+#define BIT_MASK_BCN_MAX_ERR_8822B 0xff
+#define BIT_BCN_MAX_ERR_8822B(x) \
+ (((x) & BIT_MASK_BCN_MAX_ERR_8822B) << BIT_SHIFT_BCN_MAX_ERR_8822B)
+#define BIT_GET_BCN_MAX_ERR_8822B(x) \
+ (((x) >> BIT_SHIFT_BCN_MAX_ERR_8822B) & BIT_MASK_BCN_MAX_ERR_8822B)
+
+/* 2 REG_RXTSF_OFFSET_CCK_8822B */
+
+#define BIT_SHIFT_CCK_RXTSF_OFFSET_8822B 0
+#define BIT_MASK_CCK_RXTSF_OFFSET_8822B 0xff
+#define BIT_CCK_RXTSF_OFFSET_8822B(x) \
+ (((x) & BIT_MASK_CCK_RXTSF_OFFSET_8822B) \
+ << BIT_SHIFT_CCK_RXTSF_OFFSET_8822B)
+#define BIT_GET_CCK_RXTSF_OFFSET_8822B(x) \
+ (((x) >> BIT_SHIFT_CCK_RXTSF_OFFSET_8822B) & \
+ BIT_MASK_CCK_RXTSF_OFFSET_8822B)
+
+/* 2 REG_RXTSF_OFFSET_OFDM_8822B */
+
+#define BIT_SHIFT_OFDM_RXTSF_OFFSET_8822B 0
+#define BIT_MASK_OFDM_RXTSF_OFFSET_8822B 0xff
+#define BIT_OFDM_RXTSF_OFFSET_8822B(x) \
+ (((x) & BIT_MASK_OFDM_RXTSF_OFFSET_8822B) \
+ << BIT_SHIFT_OFDM_RXTSF_OFFSET_8822B)
+#define BIT_GET_OFDM_RXTSF_OFFSET_8822B(x) \
+ (((x) >> BIT_SHIFT_OFDM_RXTSF_OFFSET_8822B) & \
+ BIT_MASK_OFDM_RXTSF_OFFSET_8822B)
+
+/* 2 REG_TSFTR_8822B */
+
+#define BIT_SHIFT_TSF_TIMER_8822B 0
+#define BIT_MASK_TSF_TIMER_8822B 0xffffffffffffffffL
+#define BIT_TSF_TIMER_8822B(x) \
+ (((x) & BIT_MASK_TSF_TIMER_8822B) << BIT_SHIFT_TSF_TIMER_8822B)
+#define BIT_GET_TSF_TIMER_8822B(x) \
+ (((x) >> BIT_SHIFT_TSF_TIMER_8822B) & BIT_MASK_TSF_TIMER_8822B)
+
+/* 2 REG_FREERUN_CNT_8822B */
+
+#define BIT_SHIFT_FREERUN_CNT_8822B 0
+#define BIT_MASK_FREERUN_CNT_8822B 0xffffffffffffffffL
+#define BIT_FREERUN_CNT_8822B(x) \
+ (((x) & BIT_MASK_FREERUN_CNT_8822B) << BIT_SHIFT_FREERUN_CNT_8822B)
+#define BIT_GET_FREERUN_CNT_8822B(x) \
+ (((x) >> BIT_SHIFT_FREERUN_CNT_8822B) & BIT_MASK_FREERUN_CNT_8822B)
+
+/* 2 REG_ATIMWND1_V1_8822B */
+
+#define BIT_SHIFT_ATIMWND1_V1_8822B 0
+#define BIT_MASK_ATIMWND1_V1_8822B 0xff
+#define BIT_ATIMWND1_V1_8822B(x) \
+ (((x) & BIT_MASK_ATIMWND1_V1_8822B) << BIT_SHIFT_ATIMWND1_V1_8822B)
+#define BIT_GET_ATIMWND1_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_ATIMWND1_V1_8822B) & BIT_MASK_ATIMWND1_V1_8822B)
+
+/* 2 REG_TBTT_PROHIBIT_INFRA_8822B */
+
+#define BIT_SHIFT_TBTT_PROHIBIT_INFRA_8822B 0
+#define BIT_MASK_TBTT_PROHIBIT_INFRA_8822B 0xff
+#define BIT_TBTT_PROHIBIT_INFRA_8822B(x) \
+ (((x) & BIT_MASK_TBTT_PROHIBIT_INFRA_8822B) \
+ << BIT_SHIFT_TBTT_PROHIBIT_INFRA_8822B)
+#define BIT_GET_TBTT_PROHIBIT_INFRA_8822B(x) \
+ (((x) >> BIT_SHIFT_TBTT_PROHIBIT_INFRA_8822B) & \
+ BIT_MASK_TBTT_PROHIBIT_INFRA_8822B)
+
+/* 2 REG_CTWND_8822B */
+
+#define BIT_SHIFT_CTWND_8822B 0
+#define BIT_MASK_CTWND_8822B 0xff
+#define BIT_CTWND_8822B(x) \
+ (((x) & BIT_MASK_CTWND_8822B) << BIT_SHIFT_CTWND_8822B)
+#define BIT_GET_CTWND_8822B(x) \
+ (((x) >> BIT_SHIFT_CTWND_8822B) & BIT_MASK_CTWND_8822B)
+
+/* 2 REG_BCNIVLCUNT_8822B */
+
+#define BIT_SHIFT_BCNIVLCUNT_8822B 0
+#define BIT_MASK_BCNIVLCUNT_8822B 0x7f
+#define BIT_BCNIVLCUNT_8822B(x) \
+ (((x) & BIT_MASK_BCNIVLCUNT_8822B) << BIT_SHIFT_BCNIVLCUNT_8822B)
+#define BIT_GET_BCNIVLCUNT_8822B(x) \
+ (((x) >> BIT_SHIFT_BCNIVLCUNT_8822B) & BIT_MASK_BCNIVLCUNT_8822B)
+
+/* 2 REG_BCNDROPCTRL_8822B */
+#define BIT_BEACON_DROP_EN_8822B BIT(7)
+
+#define BIT_SHIFT_BEACON_DROP_IVL_8822B 0
+#define BIT_MASK_BEACON_DROP_IVL_8822B 0x7f
+#define BIT_BEACON_DROP_IVL_8822B(x) \
+ (((x) & BIT_MASK_BEACON_DROP_IVL_8822B) \
+ << BIT_SHIFT_BEACON_DROP_IVL_8822B)
+#define BIT_GET_BEACON_DROP_IVL_8822B(x) \
+ (((x) >> BIT_SHIFT_BEACON_DROP_IVL_8822B) & \
+ BIT_MASK_BEACON_DROP_IVL_8822B)
+
+/* 2 REG_HGQ_TIMEOUT_PERIOD_8822B */
+
+#define BIT_SHIFT_HGQ_TIMEOUT_PERIOD_8822B 0
+#define BIT_MASK_HGQ_TIMEOUT_PERIOD_8822B 0xff
+#define BIT_HGQ_TIMEOUT_PERIOD_8822B(x) \
+ (((x) & BIT_MASK_HGQ_TIMEOUT_PERIOD_8822B) \
+ << BIT_SHIFT_HGQ_TIMEOUT_PERIOD_8822B)
+#define BIT_GET_HGQ_TIMEOUT_PERIOD_8822B(x) \
+ (((x) >> BIT_SHIFT_HGQ_TIMEOUT_PERIOD_8822B) & \
+ BIT_MASK_HGQ_TIMEOUT_PERIOD_8822B)
+
+/* 2 REG_TXCMD_TIMEOUT_PERIOD_8822B */
+
+#define BIT_SHIFT_TXCMD_TIMEOUT_PERIOD_8822B 0
+#define BIT_MASK_TXCMD_TIMEOUT_PERIOD_8822B 0xff
+#define BIT_TXCMD_TIMEOUT_PERIOD_8822B(x) \
+ (((x) & BIT_MASK_TXCMD_TIMEOUT_PERIOD_8822B) \
+ << BIT_SHIFT_TXCMD_TIMEOUT_PERIOD_8822B)
+#define BIT_GET_TXCMD_TIMEOUT_PERIOD_8822B(x) \
+ (((x) >> BIT_SHIFT_TXCMD_TIMEOUT_PERIOD_8822B) & \
+ BIT_MASK_TXCMD_TIMEOUT_PERIOD_8822B)
+
+/* 2 REG_MISC_CTRL_8822B */
+#define BIT_DIS_TRX_CAL_BCN_8822B BIT(5)
+#define BIT_DIS_TX_CAL_TBTT_8822B BIT(4)
+#define BIT_EN_FREECNT_8822B BIT(3)
+#define BIT_BCN_AGGRESSION_8822B BIT(2)
+
+#define BIT_SHIFT_DIS_SECONDARY_CCA_8822B 0
+#define BIT_MASK_DIS_SECONDARY_CCA_8822B 0x3
+#define BIT_DIS_SECONDARY_CCA_8822B(x) \
+ (((x) & BIT_MASK_DIS_SECONDARY_CCA_8822B) \
+ << BIT_SHIFT_DIS_SECONDARY_CCA_8822B)
+#define BIT_GET_DIS_SECONDARY_CCA_8822B(x) \
+ (((x) >> BIT_SHIFT_DIS_SECONDARY_CCA_8822B) & \
+ BIT_MASK_DIS_SECONDARY_CCA_8822B)
+
+/* 2 REG_BCN_CTRL_CLINT1_8822B */
+#define BIT_CLI1_DIS_RX_BSSID_FIT_8822B BIT(6)
+#define BIT_CLI1_DIS_TSF_UDT_8822B BIT(4)
+#define BIT_CLI1_EN_BCN_FUNCTION_8822B BIT(3)
+#define BIT_CLI1_EN_RXBCN_RPT_8822B BIT(2)
+#define BIT_CLI1_ENP2P_CTWINDOW_8822B BIT(1)
+#define BIT_CLI1_ENP2P_BCNQ_AREA_8822B BIT(0)
+
+/* 2 REG_BCN_CTRL_CLINT2_8822B */
+#define BIT_CLI2_DIS_RX_BSSID_FIT_8822B BIT(6)
+#define BIT_CLI2_DIS_TSF_UDT_8822B BIT(4)
+#define BIT_CLI2_EN_BCN_FUNCTION_8822B BIT(3)
+#define BIT_CLI2_EN_RXBCN_RPT_8822B BIT(2)
+#define BIT_CLI2_ENP2P_CTWINDOW_8822B BIT(1)
+#define BIT_CLI2_ENP2P_BCNQ_AREA_8822B BIT(0)
+
+/* 2 REG_BCN_CTRL_CLINT3_8822B */
+#define BIT_CLI3_DIS_RX_BSSID_FIT_8822B BIT(6)
+#define BIT_CLI3_DIS_TSF_UDT_8822B BIT(4)
+#define BIT_CLI3_EN_BCN_FUNCTION_8822B BIT(3)
+#define BIT_CLI3_EN_RXBCN_RPT_8822B BIT(2)
+#define BIT_CLI3_ENP2P_CTWINDOW_8822B BIT(1)
+#define BIT_CLI3_ENP2P_BCNQ_AREA_8822B BIT(0)
+
+/* 2 REG_EXTEND_CTRL_8822B */
+#define BIT_EN_TSFBIT32_RST_P2P2_8822B BIT(5)
+#define BIT_EN_TSFBIT32_RST_P2P1_8822B BIT(4)
+
+#define BIT_SHIFT_PORT_SEL_8822B 0
+#define BIT_MASK_PORT_SEL_8822B 0x7
+#define BIT_PORT_SEL_8822B(x) \
+ (((x) & BIT_MASK_PORT_SEL_8822B) << BIT_SHIFT_PORT_SEL_8822B)
+#define BIT_GET_PORT_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_PORT_SEL_8822B) & BIT_MASK_PORT_SEL_8822B)
+
+/* 2 REG_P2PPS1_SPEC_STATE_8822B */
+#define BIT_P2P1_SPEC_POWER_STATE_8822B BIT(7)
+#define BIT_P2P1_SPEC_CTWINDOW_ON_8822B BIT(6)
+#define BIT_P2P1_SPEC_BCN_AREA_ON_8822B BIT(5)
+#define BIT_P2P1_SPEC_CTWIN_EARLY_DISTX_8822B BIT(4)
+#define BIT_P2P1_SPEC_NOA1_OFF_PERIOD_8822B BIT(3)
+#define BIT_P2P1_SPEC_FORCE_DOZE1_8822B BIT(2)
+#define BIT_P2P1_SPEC_NOA0_OFF_PERIOD_8822B BIT(1)
+#define BIT_P2P1_SPEC_FORCE_DOZE0_8822B BIT(0)
+
+/* 2 REG_P2PPS1_STATE_8822B */
+#define BIT_P2P1_POWER_STATE_8822B BIT(7)
+#define BIT_P2P1_CTWINDOW_ON_8822B BIT(6)
+#define BIT_P2P1_BEACON_AREA_ON_8822B BIT(5)
+#define BIT_P2P1_CTWIN_EARLY_DISTX_8822B BIT(4)
+#define BIT_P2P1_NOA1_OFF_PERIOD_8822B BIT(3)
+#define BIT_P2P1_FORCE_DOZE1_8822B BIT(2)
+#define BIT_P2P1_NOA0_OFF_PERIOD_8822B BIT(1)
+#define BIT_P2P1_FORCE_DOZE0_8822B BIT(0)
+
+/* 2 REG_P2PPS2_SPEC_STATE_8822B */
+#define BIT_P2P2_SPEC_POWER_STATE_8822B BIT(7)
+#define BIT_P2P2_SPEC_CTWINDOW_ON_8822B BIT(6)
+#define BIT_P2P2_SPEC_BCN_AREA_ON_8822B BIT(5)
+#define BIT_P2P2_SPEC_CTWIN_EARLY_DISTX_8822B BIT(4)
+#define BIT_P2P2_SPEC_NOA1_OFF_PERIOD_8822B BIT(3)
+#define BIT_P2P2_SPEC_FORCE_DOZE1_8822B BIT(2)
+#define BIT_P2P2_SPEC_NOA0_OFF_PERIOD_8822B BIT(1)
+#define BIT_P2P2_SPEC_FORCE_DOZE0_8822B BIT(0)
+
+/* 2 REG_P2PPS2_STATE_8822B */
+#define BIT_P2P2_POWER_STATE_8822B BIT(7)
+#define BIT_P2P2_CTWINDOW_ON_8822B BIT(6)
+#define BIT_P2P2_BEACON_AREA_ON_8822B BIT(5)
+#define BIT_P2P2_CTWIN_EARLY_DISTX_8822B BIT(4)
+#define BIT_P2P2_NOA1_OFF_PERIOD_8822B BIT(3)
+#define BIT_P2P2_FORCE_DOZE1_8822B BIT(2)
+#define BIT_P2P2_NOA0_OFF_PERIOD_8822B BIT(1)
+#define BIT_P2P2_FORCE_DOZE0_8822B BIT(0)
+
+/* 2 REG_PS_TIMER0_8822B */
+
+#define BIT_SHIFT_PSTIMER0_INT_8822B 5
+#define BIT_MASK_PSTIMER0_INT_8822B 0x7ffffff
+#define BIT_PSTIMER0_INT_8822B(x) \
+ (((x) & BIT_MASK_PSTIMER0_INT_8822B) << BIT_SHIFT_PSTIMER0_INT_8822B)
+#define BIT_GET_PSTIMER0_INT_8822B(x) \
+ (((x) >> BIT_SHIFT_PSTIMER0_INT_8822B) & BIT_MASK_PSTIMER0_INT_8822B)
+
+/* 2 REG_PS_TIMER1_8822B */
+
+#define BIT_SHIFT_PSTIMER1_INT_8822B 5
+#define BIT_MASK_PSTIMER1_INT_8822B 0x7ffffff
+#define BIT_PSTIMER1_INT_8822B(x) \
+ (((x) & BIT_MASK_PSTIMER1_INT_8822B) << BIT_SHIFT_PSTIMER1_INT_8822B)
+#define BIT_GET_PSTIMER1_INT_8822B(x) \
+ (((x) >> BIT_SHIFT_PSTIMER1_INT_8822B) & BIT_MASK_PSTIMER1_INT_8822B)
+
+/* 2 REG_PS_TIMER2_8822B */
+
+#define BIT_SHIFT_PSTIMER2_INT_8822B 5
+#define BIT_MASK_PSTIMER2_INT_8822B 0x7ffffff
+#define BIT_PSTIMER2_INT_8822B(x) \
+ (((x) & BIT_MASK_PSTIMER2_INT_8822B) << BIT_SHIFT_PSTIMER2_INT_8822B)
+#define BIT_GET_PSTIMER2_INT_8822B(x) \
+ (((x) >> BIT_SHIFT_PSTIMER2_INT_8822B) & BIT_MASK_PSTIMER2_INT_8822B)
+
+/* 2 REG_TBTT_CTN_AREA_8822B */
+
+#define BIT_SHIFT_TBTT_CTN_AREA_8822B 0
+#define BIT_MASK_TBTT_CTN_AREA_8822B 0xff
+#define BIT_TBTT_CTN_AREA_8822B(x) \
+ (((x) & BIT_MASK_TBTT_CTN_AREA_8822B) << BIT_SHIFT_TBTT_CTN_AREA_8822B)
+#define BIT_GET_TBTT_CTN_AREA_8822B(x) \
+ (((x) >> BIT_SHIFT_TBTT_CTN_AREA_8822B) & BIT_MASK_TBTT_CTN_AREA_8822B)
+
+/* 2 REG_FORCE_BCN_IFS_8822B */
+
+#define BIT_SHIFT_FORCE_BCN_IFS_8822B 0
+#define BIT_MASK_FORCE_BCN_IFS_8822B 0xff
+#define BIT_FORCE_BCN_IFS_8822B(x) \
+ (((x) & BIT_MASK_FORCE_BCN_IFS_8822B) << BIT_SHIFT_FORCE_BCN_IFS_8822B)
+#define BIT_GET_FORCE_BCN_IFS_8822B(x) \
+ (((x) >> BIT_SHIFT_FORCE_BCN_IFS_8822B) & BIT_MASK_FORCE_BCN_IFS_8822B)
+
+/* 2 REG_TXOP_MIN_8822B */
+
+#define BIT_SHIFT_TXOP_MIN_8822B 0
+#define BIT_MASK_TXOP_MIN_8822B 0x3fff
+#define BIT_TXOP_MIN_8822B(x) \
+ (((x) & BIT_MASK_TXOP_MIN_8822B) << BIT_SHIFT_TXOP_MIN_8822B)
+#define BIT_GET_TXOP_MIN_8822B(x) \
+ (((x) >> BIT_SHIFT_TXOP_MIN_8822B) & BIT_MASK_TXOP_MIN_8822B)
+
+/* 2 REG_PRE_BKF_TIME_8822B */
+
+#define BIT_SHIFT_PRE_BKF_TIME_8822B 0
+#define BIT_MASK_PRE_BKF_TIME_8822B 0xff
+#define BIT_PRE_BKF_TIME_8822B(x) \
+ (((x) & BIT_MASK_PRE_BKF_TIME_8822B) << BIT_SHIFT_PRE_BKF_TIME_8822B)
+#define BIT_GET_PRE_BKF_TIME_8822B(x) \
+ (((x) >> BIT_SHIFT_PRE_BKF_TIME_8822B) & BIT_MASK_PRE_BKF_TIME_8822B)
+
+/* 2 REG_CROSS_TXOP_CTRL_8822B */
+#define BIT_DTIM_BYPASS_8822B BIT(2)
+#define BIT_RTS_NAV_TXOP_8822B BIT(1)
+#define BIT_NOT_CROSS_TXOP_8822B BIT(0)
+
+/* 2 REG_ATIMWND2_8822B */
+
+#define BIT_SHIFT_ATIMWND2_8822B 0
+#define BIT_MASK_ATIMWND2_8822B 0xff
+#define BIT_ATIMWND2_8822B(x) \
+ (((x) & BIT_MASK_ATIMWND2_8822B) << BIT_SHIFT_ATIMWND2_8822B)
+#define BIT_GET_ATIMWND2_8822B(x) \
+ (((x) >> BIT_SHIFT_ATIMWND2_8822B) & BIT_MASK_ATIMWND2_8822B)
+
+/* 2 REG_ATIMWND3_8822B */
+
+#define BIT_SHIFT_ATIMWND3_8822B 0
+#define BIT_MASK_ATIMWND3_8822B 0xff
+#define BIT_ATIMWND3_8822B(x) \
+ (((x) & BIT_MASK_ATIMWND3_8822B) << BIT_SHIFT_ATIMWND3_8822B)
+#define BIT_GET_ATIMWND3_8822B(x) \
+ (((x) >> BIT_SHIFT_ATIMWND3_8822B) & BIT_MASK_ATIMWND3_8822B)
+
+/* 2 REG_ATIMWND4_8822B */
+
+#define BIT_SHIFT_ATIMWND4_8822B 0
+#define BIT_MASK_ATIMWND4_8822B 0xff
+#define BIT_ATIMWND4_8822B(x) \
+ (((x) & BIT_MASK_ATIMWND4_8822B) << BIT_SHIFT_ATIMWND4_8822B)
+#define BIT_GET_ATIMWND4_8822B(x) \
+ (((x) >> BIT_SHIFT_ATIMWND4_8822B) & BIT_MASK_ATIMWND4_8822B)
+
+/* 2 REG_ATIMWND5_8822B */
+
+#define BIT_SHIFT_ATIMWND5_8822B 0
+#define BIT_MASK_ATIMWND5_8822B 0xff
+#define BIT_ATIMWND5_8822B(x) \
+ (((x) & BIT_MASK_ATIMWND5_8822B) << BIT_SHIFT_ATIMWND5_8822B)
+#define BIT_GET_ATIMWND5_8822B(x) \
+ (((x) >> BIT_SHIFT_ATIMWND5_8822B) & BIT_MASK_ATIMWND5_8822B)
+
+/* 2 REG_ATIMWND6_8822B */
+
+#define BIT_SHIFT_ATIMWND6_8822B 0
+#define BIT_MASK_ATIMWND6_8822B 0xff
+#define BIT_ATIMWND6_8822B(x) \
+ (((x) & BIT_MASK_ATIMWND6_8822B) << BIT_SHIFT_ATIMWND6_8822B)
+#define BIT_GET_ATIMWND6_8822B(x) \
+ (((x) >> BIT_SHIFT_ATIMWND6_8822B) & BIT_MASK_ATIMWND6_8822B)
+
+/* 2 REG_ATIMWND7_8822B */
+
+#define BIT_SHIFT_ATIMWND7_8822B 0
+#define BIT_MASK_ATIMWND7_8822B 0xff
+#define BIT_ATIMWND7_8822B(x) \
+ (((x) & BIT_MASK_ATIMWND7_8822B) << BIT_SHIFT_ATIMWND7_8822B)
+#define BIT_GET_ATIMWND7_8822B(x) \
+ (((x) >> BIT_SHIFT_ATIMWND7_8822B) & BIT_MASK_ATIMWND7_8822B)
+
+/* 2 REG_ATIMUGT_8822B */
+
+#define BIT_SHIFT_ATIM_URGENT_8822B 0
+#define BIT_MASK_ATIM_URGENT_8822B 0xff
+#define BIT_ATIM_URGENT_8822B(x) \
+ (((x) & BIT_MASK_ATIM_URGENT_8822B) << BIT_SHIFT_ATIM_URGENT_8822B)
+#define BIT_GET_ATIM_URGENT_8822B(x) \
+ (((x) >> BIT_SHIFT_ATIM_URGENT_8822B) & BIT_MASK_ATIM_URGENT_8822B)
+
+/* 2 REG_HIQ_NO_LMT_EN_8822B */
+#define BIT_HIQ_NO_LMT_EN_VAP7_8822B BIT(7)
+#define BIT_HIQ_NO_LMT_EN_VAP6_8822B BIT(6)
+#define BIT_HIQ_NO_LMT_EN_VAP5_8822B BIT(5)
+#define BIT_HIQ_NO_LMT_EN_VAP4_8822B BIT(4)
+#define BIT_HIQ_NO_LMT_EN_VAP3_8822B BIT(3)
+#define BIT_HIQ_NO_LMT_EN_VAP2_8822B BIT(2)
+#define BIT_HIQ_NO_LMT_EN_VAP1_8822B BIT(1)
+#define BIT_HIQ_NO_LMT_EN_ROOT_8822B BIT(0)
+
+/* 2 REG_DTIM_COUNTER_ROOT_8822B */
+
+#define BIT_SHIFT_DTIM_COUNT_ROOT_8822B 0
+#define BIT_MASK_DTIM_COUNT_ROOT_8822B 0xff
+#define BIT_DTIM_COUNT_ROOT_8822B(x) \
+ (((x) & BIT_MASK_DTIM_COUNT_ROOT_8822B) \
+ << BIT_SHIFT_DTIM_COUNT_ROOT_8822B)
+#define BIT_GET_DTIM_COUNT_ROOT_8822B(x) \
+ (((x) >> BIT_SHIFT_DTIM_COUNT_ROOT_8822B) & \
+ BIT_MASK_DTIM_COUNT_ROOT_8822B)
+
+/* 2 REG_DTIM_COUNTER_VAP1_8822B */
+
+#define BIT_SHIFT_DTIM_COUNT_VAP1_8822B 0
+#define BIT_MASK_DTIM_COUNT_VAP1_8822B 0xff
+#define BIT_DTIM_COUNT_VAP1_8822B(x) \
+ (((x) & BIT_MASK_DTIM_COUNT_VAP1_8822B) \
+ << BIT_SHIFT_DTIM_COUNT_VAP1_8822B)
+#define BIT_GET_DTIM_COUNT_VAP1_8822B(x) \
+ (((x) >> BIT_SHIFT_DTIM_COUNT_VAP1_8822B) & \
+ BIT_MASK_DTIM_COUNT_VAP1_8822B)
+
+/* 2 REG_DTIM_COUNTER_VAP2_8822B */
+
+#define BIT_SHIFT_DTIM_COUNT_VAP2_8822B 0
+#define BIT_MASK_DTIM_COUNT_VAP2_8822B 0xff
+#define BIT_DTIM_COUNT_VAP2_8822B(x) \
+ (((x) & BIT_MASK_DTIM_COUNT_VAP2_8822B) \
+ << BIT_SHIFT_DTIM_COUNT_VAP2_8822B)
+#define BIT_GET_DTIM_COUNT_VAP2_8822B(x) \
+ (((x) >> BIT_SHIFT_DTIM_COUNT_VAP2_8822B) & \
+ BIT_MASK_DTIM_COUNT_VAP2_8822B)
+
+/* 2 REG_DTIM_COUNTER_VAP3_8822B */
+
+#define BIT_SHIFT_DTIM_COUNT_VAP3_8822B 0
+#define BIT_MASK_DTIM_COUNT_VAP3_8822B 0xff
+#define BIT_DTIM_COUNT_VAP3_8822B(x) \
+ (((x) & BIT_MASK_DTIM_COUNT_VAP3_8822B) \
+ << BIT_SHIFT_DTIM_COUNT_VAP3_8822B)
+#define BIT_GET_DTIM_COUNT_VAP3_8822B(x) \
+ (((x) >> BIT_SHIFT_DTIM_COUNT_VAP3_8822B) & \
+ BIT_MASK_DTIM_COUNT_VAP3_8822B)
+
+/* 2 REG_DTIM_COUNTER_VAP4_8822B */
+
+#define BIT_SHIFT_DTIM_COUNT_VAP4_8822B 0
+#define BIT_MASK_DTIM_COUNT_VAP4_8822B 0xff
+#define BIT_DTIM_COUNT_VAP4_8822B(x) \
+ (((x) & BIT_MASK_DTIM_COUNT_VAP4_8822B) \
+ << BIT_SHIFT_DTIM_COUNT_VAP4_8822B)
+#define BIT_GET_DTIM_COUNT_VAP4_8822B(x) \
+ (((x) >> BIT_SHIFT_DTIM_COUNT_VAP4_8822B) & \
+ BIT_MASK_DTIM_COUNT_VAP4_8822B)
+
+/* 2 REG_DTIM_COUNTER_VAP5_8822B */
+
+#define BIT_SHIFT_DTIM_COUNT_VAP5_8822B 0
+#define BIT_MASK_DTIM_COUNT_VAP5_8822B 0xff
+#define BIT_DTIM_COUNT_VAP5_8822B(x) \
+ (((x) & BIT_MASK_DTIM_COUNT_VAP5_8822B) \
+ << BIT_SHIFT_DTIM_COUNT_VAP5_8822B)
+#define BIT_GET_DTIM_COUNT_VAP5_8822B(x) \
+ (((x) >> BIT_SHIFT_DTIM_COUNT_VAP5_8822B) & \
+ BIT_MASK_DTIM_COUNT_VAP5_8822B)
+
+/* 2 REG_DTIM_COUNTER_VAP6_8822B */
+
+#define BIT_SHIFT_DTIM_COUNT_VAP6_8822B 0
+#define BIT_MASK_DTIM_COUNT_VAP6_8822B 0xff
+#define BIT_DTIM_COUNT_VAP6_8822B(x) \
+ (((x) & BIT_MASK_DTIM_COUNT_VAP6_8822B) \
+ << BIT_SHIFT_DTIM_COUNT_VAP6_8822B)
+#define BIT_GET_DTIM_COUNT_VAP6_8822B(x) \
+ (((x) >> BIT_SHIFT_DTIM_COUNT_VAP6_8822B) & \
+ BIT_MASK_DTIM_COUNT_VAP6_8822B)
+
+/* 2 REG_DTIM_COUNTER_VAP7_8822B */
+
+#define BIT_SHIFT_DTIM_COUNT_VAP7_8822B 0
+#define BIT_MASK_DTIM_COUNT_VAP7_8822B 0xff
+#define BIT_DTIM_COUNT_VAP7_8822B(x) \
+ (((x) & BIT_MASK_DTIM_COUNT_VAP7_8822B) \
+ << BIT_SHIFT_DTIM_COUNT_VAP7_8822B)
+#define BIT_GET_DTIM_COUNT_VAP7_8822B(x) \
+ (((x) >> BIT_SHIFT_DTIM_COUNT_VAP7_8822B) & \
+ BIT_MASK_DTIM_COUNT_VAP7_8822B)
+
+/* 2 REG_DIS_ATIM_8822B */
+#define BIT_DIS_ATIM_VAP7_8822B BIT(7)
+#define BIT_DIS_ATIM_VAP6_8822B BIT(6)
+#define BIT_DIS_ATIM_VAP5_8822B BIT(5)
+#define BIT_DIS_ATIM_VAP4_8822B BIT(4)
+#define BIT_DIS_ATIM_VAP3_8822B BIT(3)
+#define BIT_DIS_ATIM_VAP2_8822B BIT(2)
+#define BIT_DIS_ATIM_VAP1_8822B BIT(1)
+#define BIT_DIS_ATIM_ROOT_8822B BIT(0)
+
+/* 2 REG_EARLY_128US_8822B */
+
+#define BIT_SHIFT_TSFT_SEL_TIMER1_8822B 3
+#define BIT_MASK_TSFT_SEL_TIMER1_8822B 0x7
+#define BIT_TSFT_SEL_TIMER1_8822B(x) \
+ (((x) & BIT_MASK_TSFT_SEL_TIMER1_8822B) \
+ << BIT_SHIFT_TSFT_SEL_TIMER1_8822B)
+#define BIT_GET_TSFT_SEL_TIMER1_8822B(x) \
+ (((x) >> BIT_SHIFT_TSFT_SEL_TIMER1_8822B) & \
+ BIT_MASK_TSFT_SEL_TIMER1_8822B)
+
+#define BIT_SHIFT_EARLY_128US_8822B 0
+#define BIT_MASK_EARLY_128US_8822B 0x7
+#define BIT_EARLY_128US_8822B(x) \
+ (((x) & BIT_MASK_EARLY_128US_8822B) << BIT_SHIFT_EARLY_128US_8822B)
+#define BIT_GET_EARLY_128US_8822B(x) \
+ (((x) >> BIT_SHIFT_EARLY_128US_8822B) & BIT_MASK_EARLY_128US_8822B)
+
+/* 2 REG_P2PPS1_CTRL_8822B */
+#define BIT_P2P1_CTW_ALLSTASLEEP_8822B BIT(7)
+#define BIT_P2P1_OFF_DISTX_EN_8822B BIT(6)
+#define BIT_P2P1_PWR_MGT_EN_8822B BIT(5)
+#define BIT_P2P1_NOA1_EN_8822B BIT(2)
+#define BIT_P2P1_NOA0_EN_8822B BIT(1)
+
+/* 2 REG_P2PPS2_CTRL_8822B */
+#define BIT_P2P2_CTW_ALLSTASLEEP_8822B BIT(7)
+#define BIT_P2P2_OFF_DISTX_EN_8822B BIT(6)
+#define BIT_P2P2_PWR_MGT_EN_8822B BIT(5)
+#define BIT_P2P2_NOA1_EN_8822B BIT(2)
+#define BIT_P2P2_NOA0_EN_8822B BIT(1)
+
+/* 2 REG_TIMER0_SRC_SEL_8822B */
+
+#define BIT_SHIFT_SYNC_CLI_SEL_8822B 4
+#define BIT_MASK_SYNC_CLI_SEL_8822B 0x7
+#define BIT_SYNC_CLI_SEL_8822B(x) \
+ (((x) & BIT_MASK_SYNC_CLI_SEL_8822B) << BIT_SHIFT_SYNC_CLI_SEL_8822B)
+#define BIT_GET_SYNC_CLI_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_SYNC_CLI_SEL_8822B) & BIT_MASK_SYNC_CLI_SEL_8822B)
+
+#define BIT_SHIFT_TSFT_SEL_TIMER0_8822B 0
+#define BIT_MASK_TSFT_SEL_TIMER0_8822B 0x7
+#define BIT_TSFT_SEL_TIMER0_8822B(x) \
+ (((x) & BIT_MASK_TSFT_SEL_TIMER0_8822B) \
+ << BIT_SHIFT_TSFT_SEL_TIMER0_8822B)
+#define BIT_GET_TSFT_SEL_TIMER0_8822B(x) \
+ (((x) >> BIT_SHIFT_TSFT_SEL_TIMER0_8822B) & \
+ BIT_MASK_TSFT_SEL_TIMER0_8822B)
+
+/* 2 REG_NOA_UNIT_SEL_8822B */
+
+#define BIT_SHIFT_NOA_UNIT2_SEL_8822B 8
+#define BIT_MASK_NOA_UNIT2_SEL_8822B 0x7
+#define BIT_NOA_UNIT2_SEL_8822B(x) \
+ (((x) & BIT_MASK_NOA_UNIT2_SEL_8822B) << BIT_SHIFT_NOA_UNIT2_SEL_8822B)
+#define BIT_GET_NOA_UNIT2_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_NOA_UNIT2_SEL_8822B) & BIT_MASK_NOA_UNIT2_SEL_8822B)
+
+#define BIT_SHIFT_NOA_UNIT1_SEL_8822B 4
+#define BIT_MASK_NOA_UNIT1_SEL_8822B 0x7
+#define BIT_NOA_UNIT1_SEL_8822B(x) \
+ (((x) & BIT_MASK_NOA_UNIT1_SEL_8822B) << BIT_SHIFT_NOA_UNIT1_SEL_8822B)
+#define BIT_GET_NOA_UNIT1_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_NOA_UNIT1_SEL_8822B) & BIT_MASK_NOA_UNIT1_SEL_8822B)
+
+#define BIT_SHIFT_NOA_UNIT0_SEL_8822B 0
+#define BIT_MASK_NOA_UNIT0_SEL_8822B 0x7
+#define BIT_NOA_UNIT0_SEL_8822B(x) \
+ (((x) & BIT_MASK_NOA_UNIT0_SEL_8822B) << BIT_SHIFT_NOA_UNIT0_SEL_8822B)
+#define BIT_GET_NOA_UNIT0_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_NOA_UNIT0_SEL_8822B) & BIT_MASK_NOA_UNIT0_SEL_8822B)
+
+/* 2 REG_P2POFF_DIS_TXTIME_8822B */
+
+#define BIT_SHIFT_P2POFF_DIS_TXTIME_8822B 0
+#define BIT_MASK_P2POFF_DIS_TXTIME_8822B 0xff
+#define BIT_P2POFF_DIS_TXTIME_8822B(x) \
+ (((x) & BIT_MASK_P2POFF_DIS_TXTIME_8822B) \
+ << BIT_SHIFT_P2POFF_DIS_TXTIME_8822B)
+#define BIT_GET_P2POFF_DIS_TXTIME_8822B(x) \
+ (((x) >> BIT_SHIFT_P2POFF_DIS_TXTIME_8822B) & \
+ BIT_MASK_P2POFF_DIS_TXTIME_8822B)
+
+/* 2 REG_MBSSID_BCN_SPACE2_8822B */
+
+#define BIT_SHIFT_BCN_SPACE_CLINT2_8822B 16
+#define BIT_MASK_BCN_SPACE_CLINT2_8822B 0xfff
+#define BIT_BCN_SPACE_CLINT2_8822B(x) \
+ (((x) & BIT_MASK_BCN_SPACE_CLINT2_8822B) \
+ << BIT_SHIFT_BCN_SPACE_CLINT2_8822B)
+#define BIT_GET_BCN_SPACE_CLINT2_8822B(x) \
+ (((x) >> BIT_SHIFT_BCN_SPACE_CLINT2_8822B) & \
+ BIT_MASK_BCN_SPACE_CLINT2_8822B)
+
+#define BIT_SHIFT_BCN_SPACE_CLINT1_8822B 0
+#define BIT_MASK_BCN_SPACE_CLINT1_8822B 0xfff
+#define BIT_BCN_SPACE_CLINT1_8822B(x) \
+ (((x) & BIT_MASK_BCN_SPACE_CLINT1_8822B) \
+ << BIT_SHIFT_BCN_SPACE_CLINT1_8822B)
+#define BIT_GET_BCN_SPACE_CLINT1_8822B(x) \
+ (((x) >> BIT_SHIFT_BCN_SPACE_CLINT1_8822B) & \
+ BIT_MASK_BCN_SPACE_CLINT1_8822B)
+
+/* 2 REG_MBSSID_BCN_SPACE3_8822B */
+
+#define BIT_SHIFT_SUB_BCN_SPACE_8822B 16
+#define BIT_MASK_SUB_BCN_SPACE_8822B 0xff
+#define BIT_SUB_BCN_SPACE_8822B(x) \
+ (((x) & BIT_MASK_SUB_BCN_SPACE_8822B) << BIT_SHIFT_SUB_BCN_SPACE_8822B)
+#define BIT_GET_SUB_BCN_SPACE_8822B(x) \
+ (((x) >> BIT_SHIFT_SUB_BCN_SPACE_8822B) & BIT_MASK_SUB_BCN_SPACE_8822B)
+
+#define BIT_SHIFT_BCN_SPACE_CLINT3_8822B 0
+#define BIT_MASK_BCN_SPACE_CLINT3_8822B 0xfff
+#define BIT_BCN_SPACE_CLINT3_8822B(x) \
+ (((x) & BIT_MASK_BCN_SPACE_CLINT3_8822B) \
+ << BIT_SHIFT_BCN_SPACE_CLINT3_8822B)
+#define BIT_GET_BCN_SPACE_CLINT3_8822B(x) \
+ (((x) >> BIT_SHIFT_BCN_SPACE_CLINT3_8822B) & \
+ BIT_MASK_BCN_SPACE_CLINT3_8822B)
+
+/* 2 REG_ACMHWCTRL_8822B */
+#define BIT_BEQ_ACM_STATUS_8822B BIT(7)
+#define BIT_VIQ_ACM_STATUS_8822B BIT(6)
+#define BIT_VOQ_ACM_STATUS_8822B BIT(5)
+#define BIT_BEQ_ACM_EN_8822B BIT(3)
+#define BIT_VIQ_ACM_EN_8822B BIT(2)
+#define BIT_VOQ_ACM_EN_8822B BIT(1)
+#define BIT_ACMHWEN_8822B BIT(0)
+
+/* 2 REG_ACMRSTCTRL_8822B */
+#define BIT_BE_ACM_RESET_USED_TIME_8822B BIT(2)
+#define BIT_VI_ACM_RESET_USED_TIME_8822B BIT(1)
+#define BIT_VO_ACM_RESET_USED_TIME_8822B BIT(0)
+
+/* 2 REG_ACMAVG_8822B */
+
+#define BIT_SHIFT_AVGPERIOD_8822B 0
+#define BIT_MASK_AVGPERIOD_8822B 0xffff
+#define BIT_AVGPERIOD_8822B(x) \
+ (((x) & BIT_MASK_AVGPERIOD_8822B) << BIT_SHIFT_AVGPERIOD_8822B)
+#define BIT_GET_AVGPERIOD_8822B(x) \
+ (((x) >> BIT_SHIFT_AVGPERIOD_8822B) & BIT_MASK_AVGPERIOD_8822B)
+
+/* 2 REG_VO_ADMTIME_8822B */
+
+#define BIT_SHIFT_VO_ADMITTED_TIME_8822B 0
+#define BIT_MASK_VO_ADMITTED_TIME_8822B 0xffff
+#define BIT_VO_ADMITTED_TIME_8822B(x) \
+ (((x) & BIT_MASK_VO_ADMITTED_TIME_8822B) \
+ << BIT_SHIFT_VO_ADMITTED_TIME_8822B)
+#define BIT_GET_VO_ADMITTED_TIME_8822B(x) \
+ (((x) >> BIT_SHIFT_VO_ADMITTED_TIME_8822B) & \
+ BIT_MASK_VO_ADMITTED_TIME_8822B)
+
+/* 2 REG_VI_ADMTIME_8822B */
+
+#define BIT_SHIFT_VI_ADMITTED_TIME_8822B 0
+#define BIT_MASK_VI_ADMITTED_TIME_8822B 0xffff
+#define BIT_VI_ADMITTED_TIME_8822B(x) \
+ (((x) & BIT_MASK_VI_ADMITTED_TIME_8822B) \
+ << BIT_SHIFT_VI_ADMITTED_TIME_8822B)
+#define BIT_GET_VI_ADMITTED_TIME_8822B(x) \
+ (((x) >> BIT_SHIFT_VI_ADMITTED_TIME_8822B) & \
+ BIT_MASK_VI_ADMITTED_TIME_8822B)
+
+/* 2 REG_BE_ADMTIME_8822B */
+
+#define BIT_SHIFT_BE_ADMITTED_TIME_8822B 0
+#define BIT_MASK_BE_ADMITTED_TIME_8822B 0xffff
+#define BIT_BE_ADMITTED_TIME_8822B(x) \
+ (((x) & BIT_MASK_BE_ADMITTED_TIME_8822B) \
+ << BIT_SHIFT_BE_ADMITTED_TIME_8822B)
+#define BIT_GET_BE_ADMITTED_TIME_8822B(x) \
+ (((x) >> BIT_SHIFT_BE_ADMITTED_TIME_8822B) & \
+ BIT_MASK_BE_ADMITTED_TIME_8822B)
+
+/* 2 REG_EDCA_RANDOM_GEN_8822B */
+
+#define BIT_SHIFT_RANDOM_GEN_8822B 0
+#define BIT_MASK_RANDOM_GEN_8822B 0xffffff
+#define BIT_RANDOM_GEN_8822B(x) \
+ (((x) & BIT_MASK_RANDOM_GEN_8822B) << BIT_SHIFT_RANDOM_GEN_8822B)
+#define BIT_GET_RANDOM_GEN_8822B(x) \
+ (((x) >> BIT_SHIFT_RANDOM_GEN_8822B) & BIT_MASK_RANDOM_GEN_8822B)
+
+/* 2 REG_TXCMD_NOA_SEL_8822B */
+
+#define BIT_SHIFT_NOA_SEL_8822B 4
+#define BIT_MASK_NOA_SEL_8822B 0x7
+#define BIT_NOA_SEL_8822B(x) \
+ (((x) & BIT_MASK_NOA_SEL_8822B) << BIT_SHIFT_NOA_SEL_8822B)
+#define BIT_GET_NOA_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_NOA_SEL_8822B) & BIT_MASK_NOA_SEL_8822B)
+
+#define BIT_SHIFT_TXCMD_SEG_SEL_8822B 0
+#define BIT_MASK_TXCMD_SEG_SEL_8822B 0xf
+#define BIT_TXCMD_SEG_SEL_8822B(x) \
+ (((x) & BIT_MASK_TXCMD_SEG_SEL_8822B) << BIT_SHIFT_TXCMD_SEG_SEL_8822B)
+#define BIT_GET_TXCMD_SEG_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_TXCMD_SEG_SEL_8822B) & BIT_MASK_TXCMD_SEG_SEL_8822B)
+
+/* 2 REG_NOA_PARAM_8822B */
+
+#define BIT_SHIFT_NOA_COUNT_8822B (96 & CPU_OPT_WIDTH)
+#define BIT_MASK_NOA_COUNT_8822B 0xff
+#define BIT_NOA_COUNT_8822B(x) \
+ (((x) & BIT_MASK_NOA_COUNT_8822B) << BIT_SHIFT_NOA_COUNT_8822B)
+#define BIT_GET_NOA_COUNT_8822B(x) \
+ (((x) >> BIT_SHIFT_NOA_COUNT_8822B) & BIT_MASK_NOA_COUNT_8822B)
+
+#define BIT_SHIFT_NOA_START_TIME_8822B (64 & CPU_OPT_WIDTH)
+#define BIT_MASK_NOA_START_TIME_8822B 0xffffffffL
+#define BIT_NOA_START_TIME_8822B(x) \
+ (((x) & BIT_MASK_NOA_START_TIME_8822B) \
+ << BIT_SHIFT_NOA_START_TIME_8822B)
+#define BIT_GET_NOA_START_TIME_8822B(x) \
+ (((x) >> BIT_SHIFT_NOA_START_TIME_8822B) & \
+ BIT_MASK_NOA_START_TIME_8822B)
+
+#define BIT_SHIFT_NOA_INTERVAL_8822B (32 & CPU_OPT_WIDTH)
+#define BIT_MASK_NOA_INTERVAL_8822B 0xffffffffL
+#define BIT_NOA_INTERVAL_8822B(x) \
+ (((x) & BIT_MASK_NOA_INTERVAL_8822B) << BIT_SHIFT_NOA_INTERVAL_8822B)
+#define BIT_GET_NOA_INTERVAL_8822B(x) \
+ (((x) >> BIT_SHIFT_NOA_INTERVAL_8822B) & BIT_MASK_NOA_INTERVAL_8822B)
+
+#define BIT_SHIFT_NOA_DURATION_8822B 0
+#define BIT_MASK_NOA_DURATION_8822B 0xffffffffL
+#define BIT_NOA_DURATION_8822B(x) \
+ (((x) & BIT_MASK_NOA_DURATION_8822B) << BIT_SHIFT_NOA_DURATION_8822B)
+#define BIT_GET_NOA_DURATION_8822B(x) \
+ (((x) >> BIT_SHIFT_NOA_DURATION_8822B) & BIT_MASK_NOA_DURATION_8822B)
+
+/* 2 REG_P2P_RST_8822B */
+#define BIT_P2P2_PWR_RST1_8822B BIT(5)
+#define BIT_P2P2_PWR_RST0_8822B BIT(4)
+#define BIT_P2P1_PWR_RST1_8822B BIT(3)
+#define BIT_P2P1_PWR_RST0_8822B BIT(2)
+#define BIT_P2P_PWR_RST1_V1_8822B BIT(1)
+#define BIT_P2P_PWR_RST0_V1_8822B BIT(0)
+
+/* 2 REG_SCHEDULER_RST_8822B */
+#define BIT_SYNC_CLI_8822B BIT(1)
+#define BIT_SCHEDULER_RST_V1_8822B BIT(0)
+
+/* 2 REG_SCH_TXCMD_8822B */
+
+#define BIT_SHIFT_SCH_TXCMD_8822B 0
+#define BIT_MASK_SCH_TXCMD_8822B 0xffffffffL
+#define BIT_SCH_TXCMD_8822B(x) \
+ (((x) & BIT_MASK_SCH_TXCMD_8822B) << BIT_SHIFT_SCH_TXCMD_8822B)
+#define BIT_GET_SCH_TXCMD_8822B(x) \
+ (((x) >> BIT_SHIFT_SCH_TXCMD_8822B) & BIT_MASK_SCH_TXCMD_8822B)
+
+/* 2 REG_PAGE5_DUMMY_8822B */
+
+/* 2 REG_CPUMGQ_TX_TIMER_8822B */
+
+#define BIT_SHIFT_CPUMGQ_TX_TIMER_V1_8822B 0
+#define BIT_MASK_CPUMGQ_TX_TIMER_V1_8822B 0xffffffffL
+#define BIT_CPUMGQ_TX_TIMER_V1_8822B(x) \
+ (((x) & BIT_MASK_CPUMGQ_TX_TIMER_V1_8822B) \
+ << BIT_SHIFT_CPUMGQ_TX_TIMER_V1_8822B)
+#define BIT_GET_CPUMGQ_TX_TIMER_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_CPUMGQ_TX_TIMER_V1_8822B) & \
+ BIT_MASK_CPUMGQ_TX_TIMER_V1_8822B)
+
+/* 2 REG_PS_TIMER_A_8822B */
+
+#define BIT_SHIFT_PS_TIMER_A_V1_8822B 0
+#define BIT_MASK_PS_TIMER_A_V1_8822B 0xffffffffL
+#define BIT_PS_TIMER_A_V1_8822B(x) \
+ (((x) & BIT_MASK_PS_TIMER_A_V1_8822B) << BIT_SHIFT_PS_TIMER_A_V1_8822B)
+#define BIT_GET_PS_TIMER_A_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_PS_TIMER_A_V1_8822B) & BIT_MASK_PS_TIMER_A_V1_8822B)
+
+/* 2 REG_PS_TIMER_B_8822B */
+
+#define BIT_SHIFT_PS_TIMER_B_V1_8822B 0
+#define BIT_MASK_PS_TIMER_B_V1_8822B 0xffffffffL
+#define BIT_PS_TIMER_B_V1_8822B(x) \
+ (((x) & BIT_MASK_PS_TIMER_B_V1_8822B) << BIT_SHIFT_PS_TIMER_B_V1_8822B)
+#define BIT_GET_PS_TIMER_B_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_PS_TIMER_B_V1_8822B) & BIT_MASK_PS_TIMER_B_V1_8822B)
+
+/* 2 REG_PS_TIMER_C_8822B */
+
+#define BIT_SHIFT_PS_TIMER_C_V1_8822B 0
+#define BIT_MASK_PS_TIMER_C_V1_8822B 0xffffffffL
+#define BIT_PS_TIMER_C_V1_8822B(x) \
+ (((x) & BIT_MASK_PS_TIMER_C_V1_8822B) << BIT_SHIFT_PS_TIMER_C_V1_8822B)
+#define BIT_GET_PS_TIMER_C_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_PS_TIMER_C_V1_8822B) & BIT_MASK_PS_TIMER_C_V1_8822B)
+
+/* 2 REG_PS_TIMER_ABC_CPUMGQ_TIMER_CRTL_8822B */
+#define BIT_CPUMGQ_TIMER_EN_8822B BIT(31)
+#define BIT_CPUMGQ_TX_EN_8822B BIT(28)
+
+#define BIT_SHIFT_CPUMGQ_TIMER_TSF_SEL_8822B 24
+#define BIT_MASK_CPUMGQ_TIMER_TSF_SEL_8822B 0x7
+#define BIT_CPUMGQ_TIMER_TSF_SEL_8822B(x) \
+ (((x) & BIT_MASK_CPUMGQ_TIMER_TSF_SEL_8822B) \
+ << BIT_SHIFT_CPUMGQ_TIMER_TSF_SEL_8822B)
+#define BIT_GET_CPUMGQ_TIMER_TSF_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_CPUMGQ_TIMER_TSF_SEL_8822B) & \
+ BIT_MASK_CPUMGQ_TIMER_TSF_SEL_8822B)
+
+#define BIT_PS_TIMER_C_EN_8822B BIT(23)
+
+#define BIT_SHIFT_PS_TIMER_C_TSF_SEL_8822B 16
+#define BIT_MASK_PS_TIMER_C_TSF_SEL_8822B 0x7
+#define BIT_PS_TIMER_C_TSF_SEL_8822B(x) \
+ (((x) & BIT_MASK_PS_TIMER_C_TSF_SEL_8822B) \
+ << BIT_SHIFT_PS_TIMER_C_TSF_SEL_8822B)
+#define BIT_GET_PS_TIMER_C_TSF_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_PS_TIMER_C_TSF_SEL_8822B) & \
+ BIT_MASK_PS_TIMER_C_TSF_SEL_8822B)
+
+#define BIT_PS_TIMER_B_EN_8822B BIT(15)
+
+#define BIT_SHIFT_PS_TIMER_B_TSF_SEL_8822B 8
+#define BIT_MASK_PS_TIMER_B_TSF_SEL_8822B 0x7
+#define BIT_PS_TIMER_B_TSF_SEL_8822B(x) \
+ (((x) & BIT_MASK_PS_TIMER_B_TSF_SEL_8822B) \
+ << BIT_SHIFT_PS_TIMER_B_TSF_SEL_8822B)
+#define BIT_GET_PS_TIMER_B_TSF_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_PS_TIMER_B_TSF_SEL_8822B) & \
+ BIT_MASK_PS_TIMER_B_TSF_SEL_8822B)
+
+#define BIT_PS_TIMER_A_EN_8822B BIT(7)
+
+#define BIT_SHIFT_PS_TIMER_A_TSF_SEL_8822B 0
+#define BIT_MASK_PS_TIMER_A_TSF_SEL_8822B 0x7
+#define BIT_PS_TIMER_A_TSF_SEL_8822B(x) \
+ (((x) & BIT_MASK_PS_TIMER_A_TSF_SEL_8822B) \
+ << BIT_SHIFT_PS_TIMER_A_TSF_SEL_8822B)
+#define BIT_GET_PS_TIMER_A_TSF_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_PS_TIMER_A_TSF_SEL_8822B) & \
+ BIT_MASK_PS_TIMER_A_TSF_SEL_8822B)
+
+/* 2 REG_CPUMGQ_TX_TIMER_EARLY_8822B */
+
+#define BIT_SHIFT_CPUMGQ_TX_TIMER_EARLY_8822B 0
+#define BIT_MASK_CPUMGQ_TX_TIMER_EARLY_8822B 0xff
+#define BIT_CPUMGQ_TX_TIMER_EARLY_8822B(x) \
+ (((x) & BIT_MASK_CPUMGQ_TX_TIMER_EARLY_8822B) \
+ << BIT_SHIFT_CPUMGQ_TX_TIMER_EARLY_8822B)
+#define BIT_GET_CPUMGQ_TX_TIMER_EARLY_8822B(x) \
+ (((x) >> BIT_SHIFT_CPUMGQ_TX_TIMER_EARLY_8822B) & \
+ BIT_MASK_CPUMGQ_TX_TIMER_EARLY_8822B)
+
+/* 2 REG_PS_TIMER_A_EARLY_8822B */
+
+#define BIT_SHIFT_PS_TIMER_A_EARLY_8822B 0
+#define BIT_MASK_PS_TIMER_A_EARLY_8822B 0xff
+#define BIT_PS_TIMER_A_EARLY_8822B(x) \
+ (((x) & BIT_MASK_PS_TIMER_A_EARLY_8822B) \
+ << BIT_SHIFT_PS_TIMER_A_EARLY_8822B)
+#define BIT_GET_PS_TIMER_A_EARLY_8822B(x) \
+ (((x) >> BIT_SHIFT_PS_TIMER_A_EARLY_8822B) & \
+ BIT_MASK_PS_TIMER_A_EARLY_8822B)
+
+/* 2 REG_PS_TIMER_B_EARLY_8822B */
+
+#define BIT_SHIFT_PS_TIMER_B_EARLY_8822B 0
+#define BIT_MASK_PS_TIMER_B_EARLY_8822B 0xff
+#define BIT_PS_TIMER_B_EARLY_8822B(x) \
+ (((x) & BIT_MASK_PS_TIMER_B_EARLY_8822B) \
+ << BIT_SHIFT_PS_TIMER_B_EARLY_8822B)
+#define BIT_GET_PS_TIMER_B_EARLY_8822B(x) \
+ (((x) >> BIT_SHIFT_PS_TIMER_B_EARLY_8822B) & \
+ BIT_MASK_PS_TIMER_B_EARLY_8822B)
+
+/* 2 REG_PS_TIMER_C_EARLY_8822B */
+
+#define BIT_SHIFT_PS_TIMER_C_EARLY_8822B 0
+#define BIT_MASK_PS_TIMER_C_EARLY_8822B 0xff
+#define BIT_PS_TIMER_C_EARLY_8822B(x) \
+ (((x) & BIT_MASK_PS_TIMER_C_EARLY_8822B) \
+ << BIT_SHIFT_PS_TIMER_C_EARLY_8822B)
+#define BIT_GET_PS_TIMER_C_EARLY_8822B(x) \
+ (((x) >> BIT_SHIFT_PS_TIMER_C_EARLY_8822B) & \
+ BIT_MASK_PS_TIMER_C_EARLY_8822B)
+
+/* 2 REG_NOT_VALID_8822B */
+
+/* 2 REG_BWOPMODE_8822B (BW OPERATION MODE REGISTER) */
+
+/* 2 REG_WMAC_FWPKT_CR_8822B */
+#define BIT_FWEN_8822B BIT(7)
+#define BIT_PHYSTS_PKT_CTRL_8822B BIT(6)
+#define BIT_APPHDR_MIDSRCH_FAIL_8822B BIT(4)
+#define BIT_FWPARSING_EN_8822B BIT(3)
+
+#define BIT_SHIFT_APPEND_MHDR_LEN_8822B 0
+#define BIT_MASK_APPEND_MHDR_LEN_8822B 0x7
+#define BIT_APPEND_MHDR_LEN_8822B(x) \
+ (((x) & BIT_MASK_APPEND_MHDR_LEN_8822B) \
+ << BIT_SHIFT_APPEND_MHDR_LEN_8822B)
+#define BIT_GET_APPEND_MHDR_LEN_8822B(x) \
+ (((x) >> BIT_SHIFT_APPEND_MHDR_LEN_8822B) & \
+ BIT_MASK_APPEND_MHDR_LEN_8822B)
+
+/* 2 REG_WMAC_CR_8822B (WMAC CR AND APSD CONTROL REGISTER) */
+#define BIT_IC_MACPHY_M_8822B BIT(0)
+
+/* 2 REG_TCR_8822B (TRANSMISSION CONFIGURATION REGISTER) */
+#define BIT_WMAC_EN_RTS_ADDR_8822B BIT(31)
+#define BIT_WMAC_DISABLE_CCK_8822B BIT(30)
+#define BIT_WMAC_RAW_LEN_8822B BIT(29)
+#define BIT_WMAC_NOTX_IN_RXNDP_8822B BIT(28)
+#define BIT_WMAC_EN_EOF_8822B BIT(27)
+#define BIT_WMAC_BF_SEL_8822B BIT(26)
+#define BIT_WMAC_ANTMODE_SEL_8822B BIT(25)
+#define BIT_WMAC_TCRPWRMGT_HWCTL_8822B BIT(24)
+#define BIT_WMAC_SMOOTH_VAL_8822B BIT(23)
+#define BIT_FETCH_MPDU_AFTER_WSEC_RDY_8822B BIT(20)
+#define BIT_WMAC_TCR_EN_20MST_8822B BIT(19)
+#define BIT_WMAC_DIS_SIGTA_8822B BIT(18)
+#define BIT_WMAC_DIS_A2B0_8822B BIT(17)
+#define BIT_WMAC_MSK_SIGBCRC_8822B BIT(16)
+#define BIT_WMAC_TCR_ERRSTEN_3_8822B BIT(15)
+#define BIT_WMAC_TCR_ERRSTEN_2_8822B BIT(14)
+#define BIT_WMAC_TCR_ERRSTEN_1_8822B BIT(13)
+#define BIT_WMAC_TCR_ERRSTEN_0_8822B BIT(12)
+#define BIT_WMAC_TCR_TXSK_PERPKT_8822B BIT(11)
+#define BIT_ICV_8822B BIT(10)
+#define BIT_CFEND_FORMAT_8822B BIT(9)
+#define BIT_CRC_8822B BIT(8)
+#define BIT_PWRBIT_OW_EN_8822B BIT(7)
+#define BIT_PWR_ST_8822B BIT(6)
+#define BIT_WMAC_TCR_UPD_TIMIE_8822B BIT(5)
+#define BIT_WMAC_TCR_UPD_HGQMD_8822B BIT(4)
+#define BIT_VHTSIGA1_TXPS_8822B BIT(3)
+#define BIT_PAD_SEL_8822B BIT(2)
+#define BIT_DIS_GCLK_8822B BIT(1)
+
+/* 2 REG_RCR_8822B (RECEIVE CONFIGURATION REGISTER) */
+#define BIT_APP_FCS_8822B BIT(31)
+#define BIT_APP_MIC_8822B BIT(30)
+#define BIT_APP_ICV_8822B BIT(29)
+#define BIT_APP_PHYSTS_8822B BIT(28)
+#define BIT_APP_BASSN_8822B BIT(27)
+#define BIT_VHT_DACK_8822B BIT(26)
+#define BIT_TCPOFLD_EN_8822B BIT(25)
+#define BIT_ENMBID_8822B BIT(24)
+#define BIT_LSIGEN_8822B BIT(23)
+#define BIT_MFBEN_8822B BIT(22)
+#define BIT_DISCHKPPDLLEN_8822B BIT(21)
+#define BIT_PKTCTL_DLEN_8822B BIT(20)
+#define BIT_TIM_PARSER_EN_8822B BIT(18)
+#define BIT_BC_MD_EN_8822B BIT(17)
+#define BIT_UC_MD_EN_8822B BIT(16)
+#define BIT_RXSK_PERPKT_8822B BIT(15)
+#define BIT_HTC_LOC_CTRL_8822B BIT(14)
+#define BIT_RPFM_CAM_ENABLE_8822B BIT(12)
+#define BIT_TA_BCN_8822B BIT(11)
+#define BIT_DISDECMYPKT_8822B BIT(10)
+#define BIT_AICV_8822B BIT(9)
+#define BIT_ACRC32_8822B BIT(8)
+#define BIT_CBSSID_BCN_8822B BIT(7)
+#define BIT_CBSSID_DATA_8822B BIT(6)
+#define BIT_APWRMGT_8822B BIT(5)
+#define BIT_ADD3_8822B BIT(4)
+#define BIT_AB_8822B BIT(3)
+#define BIT_AM_8822B BIT(2)
+#define BIT_APM_8822B BIT(1)
+#define BIT_AAP_8822B BIT(0)
+
+/* 2 REG_RX_DRVINFO_SZ_8822B (RX DRIVER INFO SIZE REGISTER) */
+#define BIT_PHYSTS_PER_PKT_MODE_8822B BIT(7)
+
+#define BIT_SHIFT_DRVINFO_SZ_V1_8822B 0
+#define BIT_MASK_DRVINFO_SZ_V1_8822B 0xf
+#define BIT_DRVINFO_SZ_V1_8822B(x) \
+ (((x) & BIT_MASK_DRVINFO_SZ_V1_8822B) << BIT_SHIFT_DRVINFO_SZ_V1_8822B)
+#define BIT_GET_DRVINFO_SZ_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_DRVINFO_SZ_V1_8822B) & BIT_MASK_DRVINFO_SZ_V1_8822B)
+
+/* 2 REG_RX_DLK_TIME_8822B (RX DEADLOCK TIME REGISTER) */
+
+#define BIT_SHIFT_RX_DLK_TIME_8822B 0
+#define BIT_MASK_RX_DLK_TIME_8822B 0xff
+#define BIT_RX_DLK_TIME_8822B(x) \
+ (((x) & BIT_MASK_RX_DLK_TIME_8822B) << BIT_SHIFT_RX_DLK_TIME_8822B)
+#define BIT_GET_RX_DLK_TIME_8822B(x) \
+ (((x) >> BIT_SHIFT_RX_DLK_TIME_8822B) & BIT_MASK_RX_DLK_TIME_8822B)
+
+/* 2 REG_RX_PKT_LIMIT_8822B (RX PACKET LENGTH LIMIT REGISTER) */
+
+#define BIT_SHIFT_RXPKTLMT_8822B 0
+#define BIT_MASK_RXPKTLMT_8822B 0x3f
+#define BIT_RXPKTLMT_8822B(x) \
+ (((x) & BIT_MASK_RXPKTLMT_8822B) << BIT_SHIFT_RXPKTLMT_8822B)
+#define BIT_GET_RXPKTLMT_8822B(x) \
+ (((x) >> BIT_SHIFT_RXPKTLMT_8822B) & BIT_MASK_RXPKTLMT_8822B)
+
+/* 2 REG_MACID_8822B (MAC ID REGISTER) */
+
+#define BIT_SHIFT_MACID_8822B 0
+#define BIT_MASK_MACID_8822B 0xffffffffffffL
+#define BIT_MACID_8822B(x) \
+ (((x) & BIT_MASK_MACID_8822B) << BIT_SHIFT_MACID_8822B)
+#define BIT_GET_MACID_8822B(x) \
+ (((x) >> BIT_SHIFT_MACID_8822B) & BIT_MASK_MACID_8822B)
+
+/* 2 REG_BSSID_8822B (BSSID REGISTER) */
+
+#define BIT_SHIFT_BSSID_8822B 0
+#define BIT_MASK_BSSID_8822B 0xffffffffffffL
+#define BIT_BSSID_8822B(x) \
+ (((x) & BIT_MASK_BSSID_8822B) << BIT_SHIFT_BSSID_8822B)
+#define BIT_GET_BSSID_8822B(x) \
+ (((x) >> BIT_SHIFT_BSSID_8822B) & BIT_MASK_BSSID_8822B)
+
+/* 2 REG_MAR_8822B (MULTICAST ADDRESS REGISTER) */
+
+#define BIT_SHIFT_MAR_8822B 0
+#define BIT_MASK_MAR_8822B 0xffffffffffffffffL
+#define BIT_MAR_8822B(x) (((x) & BIT_MASK_MAR_8822B) << BIT_SHIFT_MAR_8822B)
+#define BIT_GET_MAR_8822B(x) (((x) >> BIT_SHIFT_MAR_8822B) & BIT_MASK_MAR_8822B)
+
+/* 2 REG_MBIDCAMCFG_1_8822B (MBSSID CAM CONFIGURATION REGISTER) */
+
+#define BIT_SHIFT_MBIDCAM_RWDATA_L_8822B 0
+#define BIT_MASK_MBIDCAM_RWDATA_L_8822B 0xffffffffL
+#define BIT_MBIDCAM_RWDATA_L_8822B(x) \
+ (((x) & BIT_MASK_MBIDCAM_RWDATA_L_8822B) \
+ << BIT_SHIFT_MBIDCAM_RWDATA_L_8822B)
+#define BIT_GET_MBIDCAM_RWDATA_L_8822B(x) \
+ (((x) >> BIT_SHIFT_MBIDCAM_RWDATA_L_8822B) & \
+ BIT_MASK_MBIDCAM_RWDATA_L_8822B)
+
+/* 2 REG_MBIDCAMCFG_2_8822B (MBSSID CAM CONFIGURATION REGISTER) */
+#define BIT_MBIDCAM_POLL_8822B BIT(31)
+#define BIT_MBIDCAM_WT_EN_8822B BIT(30)
+
+#define BIT_SHIFT_MBIDCAM_ADDR_8822B 24
+#define BIT_MASK_MBIDCAM_ADDR_8822B 0x1f
+#define BIT_MBIDCAM_ADDR_8822B(x) \
+ (((x) & BIT_MASK_MBIDCAM_ADDR_8822B) << BIT_SHIFT_MBIDCAM_ADDR_8822B)
+#define BIT_GET_MBIDCAM_ADDR_8822B(x) \
+ (((x) >> BIT_SHIFT_MBIDCAM_ADDR_8822B) & BIT_MASK_MBIDCAM_ADDR_8822B)
+
+#define BIT_MBIDCAM_VALID_8822B BIT(23)
+#define BIT_LSIC_TXOP_EN_8822B BIT(17)
+#define BIT_CTS_EN_8822B BIT(16)
+
+#define BIT_SHIFT_MBIDCAM_RWDATA_H_8822B 0
+#define BIT_MASK_MBIDCAM_RWDATA_H_8822B 0xffff
+#define BIT_MBIDCAM_RWDATA_H_8822B(x) \
+ (((x) & BIT_MASK_MBIDCAM_RWDATA_H_8822B) \
+ << BIT_SHIFT_MBIDCAM_RWDATA_H_8822B)
+#define BIT_GET_MBIDCAM_RWDATA_H_8822B(x) \
+ (((x) >> BIT_SHIFT_MBIDCAM_RWDATA_H_8822B) & \
+ BIT_MASK_MBIDCAM_RWDATA_H_8822B)
+
+/* 2 REG_ZLD_NUM_8822B */
+
+#define BIT_SHIFT_ZLD_NUM_8822B 0
+#define BIT_MASK_ZLD_NUM_8822B 0xff
+#define BIT_ZLD_NUM_8822B(x) \
+ (((x) & BIT_MASK_ZLD_NUM_8822B) << BIT_SHIFT_ZLD_NUM_8822B)
+#define BIT_GET_ZLD_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_ZLD_NUM_8822B) & BIT_MASK_ZLD_NUM_8822B)
+
+/* 2 REG_UDF_THSD_8822B */
+
+#define BIT_SHIFT_UDF_THSD_8822B 0
+#define BIT_MASK_UDF_THSD_8822B 0xff
+#define BIT_UDF_THSD_8822B(x) \
+ (((x) & BIT_MASK_UDF_THSD_8822B) << BIT_SHIFT_UDF_THSD_8822B)
+#define BIT_GET_UDF_THSD_8822B(x) \
+ (((x) >> BIT_SHIFT_UDF_THSD_8822B) & BIT_MASK_UDF_THSD_8822B)
+
+/* 2 REG_WMAC_TCR_TSFT_OFS_8822B */
+
+#define BIT_SHIFT_WMAC_TCR_TSFT_OFS_8822B 0
+#define BIT_MASK_WMAC_TCR_TSFT_OFS_8822B 0xffff
+#define BIT_WMAC_TCR_TSFT_OFS_8822B(x) \
+ (((x) & BIT_MASK_WMAC_TCR_TSFT_OFS_8822B) \
+ << BIT_SHIFT_WMAC_TCR_TSFT_OFS_8822B)
+#define BIT_GET_WMAC_TCR_TSFT_OFS_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_TCR_TSFT_OFS_8822B) & \
+ BIT_MASK_WMAC_TCR_TSFT_OFS_8822B)
+
+/* 2 REG_MCU_TEST_2_V1_8822B */
+
+#define BIT_SHIFT_MCU_RSVD_2_V1_8822B 0
+#define BIT_MASK_MCU_RSVD_2_V1_8822B 0xffff
+#define BIT_MCU_RSVD_2_V1_8822B(x) \
+ (((x) & BIT_MASK_MCU_RSVD_2_V1_8822B) << BIT_SHIFT_MCU_RSVD_2_V1_8822B)
+#define BIT_GET_MCU_RSVD_2_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_MCU_RSVD_2_V1_8822B) & BIT_MASK_MCU_RSVD_2_V1_8822B)
+
+/* 2 REG_WMAC_TXTIMEOUT_8822B */
+
+#define BIT_SHIFT_WMAC_TXTIMEOUT_8822B 0
+#define BIT_MASK_WMAC_TXTIMEOUT_8822B 0xff
+#define BIT_WMAC_TXTIMEOUT_8822B(x) \
+ (((x) & BIT_MASK_WMAC_TXTIMEOUT_8822B) \
+ << BIT_SHIFT_WMAC_TXTIMEOUT_8822B)
+#define BIT_GET_WMAC_TXTIMEOUT_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_TXTIMEOUT_8822B) & \
+ BIT_MASK_WMAC_TXTIMEOUT_8822B)
+
+/* 2 REG_STMP_THSD_8822B */
+
+#define BIT_SHIFT_STMP_THSD_8822B 0
+#define BIT_MASK_STMP_THSD_8822B 0xff
+#define BIT_STMP_THSD_8822B(x) \
+ (((x) & BIT_MASK_STMP_THSD_8822B) << BIT_SHIFT_STMP_THSD_8822B)
+#define BIT_GET_STMP_THSD_8822B(x) \
+ (((x) >> BIT_SHIFT_STMP_THSD_8822B) & BIT_MASK_STMP_THSD_8822B)
+
+/* 2 REG_MAC_SPEC_SIFS_8822B (SPECIFICATION SIFS REGISTER) */
+
+#define BIT_SHIFT_SPEC_SIFS_OFDM_8822B 8
+#define BIT_MASK_SPEC_SIFS_OFDM_8822B 0xff
+#define BIT_SPEC_SIFS_OFDM_8822B(x) \
+ (((x) & BIT_MASK_SPEC_SIFS_OFDM_8822B) \
+ << BIT_SHIFT_SPEC_SIFS_OFDM_8822B)
+#define BIT_GET_SPEC_SIFS_OFDM_8822B(x) \
+ (((x) >> BIT_SHIFT_SPEC_SIFS_OFDM_8822B) & \
+ BIT_MASK_SPEC_SIFS_OFDM_8822B)
+
+#define BIT_SHIFT_SPEC_SIFS_CCK_8822B 0
+#define BIT_MASK_SPEC_SIFS_CCK_8822B 0xff
+#define BIT_SPEC_SIFS_CCK_8822B(x) \
+ (((x) & BIT_MASK_SPEC_SIFS_CCK_8822B) << BIT_SHIFT_SPEC_SIFS_CCK_8822B)
+#define BIT_GET_SPEC_SIFS_CCK_8822B(x) \
+ (((x) >> BIT_SHIFT_SPEC_SIFS_CCK_8822B) & BIT_MASK_SPEC_SIFS_CCK_8822B)
+
+/* 2 REG_USTIME_EDCA_8822B (US TIME TUNING FOR EDCA REGISTER) */
+
+#define BIT_SHIFT_USTIME_EDCA_V1_8822B 0
+#define BIT_MASK_USTIME_EDCA_V1_8822B 0x1ff
+#define BIT_USTIME_EDCA_V1_8822B(x) \
+ (((x) & BIT_MASK_USTIME_EDCA_V1_8822B) \
+ << BIT_SHIFT_USTIME_EDCA_V1_8822B)
+#define BIT_GET_USTIME_EDCA_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_USTIME_EDCA_V1_8822B) & \
+ BIT_MASK_USTIME_EDCA_V1_8822B)
+
+/* 2 REG_RESP_SIFS_OFDM_8822B (RESPONSE SIFS FOR OFDM REGISTER) */
+
+#define BIT_SHIFT_SIFS_R2T_OFDM_8822B 8
+#define BIT_MASK_SIFS_R2T_OFDM_8822B 0xff
+#define BIT_SIFS_R2T_OFDM_8822B(x) \
+ (((x) & BIT_MASK_SIFS_R2T_OFDM_8822B) << BIT_SHIFT_SIFS_R2T_OFDM_8822B)
+#define BIT_GET_SIFS_R2T_OFDM_8822B(x) \
+ (((x) >> BIT_SHIFT_SIFS_R2T_OFDM_8822B) & BIT_MASK_SIFS_R2T_OFDM_8822B)
+
+#define BIT_SHIFT_SIFS_T2T_OFDM_8822B 0
+#define BIT_MASK_SIFS_T2T_OFDM_8822B 0xff
+#define BIT_SIFS_T2T_OFDM_8822B(x) \
+ (((x) & BIT_MASK_SIFS_T2T_OFDM_8822B) << BIT_SHIFT_SIFS_T2T_OFDM_8822B)
+#define BIT_GET_SIFS_T2T_OFDM_8822B(x) \
+ (((x) >> BIT_SHIFT_SIFS_T2T_OFDM_8822B) & BIT_MASK_SIFS_T2T_OFDM_8822B)
+
+/* 2 REG_RESP_SIFS_CCK_8822B (RESPONSE SIFS FOR CCK REGISTER) */
+
+#define BIT_SHIFT_SIFS_R2T_CCK_8822B 8
+#define BIT_MASK_SIFS_R2T_CCK_8822B 0xff
+#define BIT_SIFS_R2T_CCK_8822B(x) \
+ (((x) & BIT_MASK_SIFS_R2T_CCK_8822B) << BIT_SHIFT_SIFS_R2T_CCK_8822B)
+#define BIT_GET_SIFS_R2T_CCK_8822B(x) \
+ (((x) >> BIT_SHIFT_SIFS_R2T_CCK_8822B) & BIT_MASK_SIFS_R2T_CCK_8822B)
+
+#define BIT_SHIFT_SIFS_T2T_CCK_8822B 0
+#define BIT_MASK_SIFS_T2T_CCK_8822B 0xff
+#define BIT_SIFS_T2T_CCK_8822B(x) \
+ (((x) & BIT_MASK_SIFS_T2T_CCK_8822B) << BIT_SHIFT_SIFS_T2T_CCK_8822B)
+#define BIT_GET_SIFS_T2T_CCK_8822B(x) \
+ (((x) >> BIT_SHIFT_SIFS_T2T_CCK_8822B) & BIT_MASK_SIFS_T2T_CCK_8822B)
+
+/* 2 REG_EIFS_8822B (EIFS REGISTER) */
+
+#define BIT_SHIFT_EIFS_8822B 0
+#define BIT_MASK_EIFS_8822B 0xffff
+#define BIT_EIFS_8822B(x) (((x) & BIT_MASK_EIFS_8822B) << BIT_SHIFT_EIFS_8822B)
+#define BIT_GET_EIFS_8822B(x) \
+ (((x) >> BIT_SHIFT_EIFS_8822B) & BIT_MASK_EIFS_8822B)
+
+/* 2 REG_CTS2TO_8822B (CTS2 TIMEOUT REGISTER) */
+
+#define BIT_SHIFT_CTS2TO_8822B 0
+#define BIT_MASK_CTS2TO_8822B 0xff
+#define BIT_CTS2TO_8822B(x) \
+ (((x) & BIT_MASK_CTS2TO_8822B) << BIT_SHIFT_CTS2TO_8822B)
+#define BIT_GET_CTS2TO_8822B(x) \
+ (((x) >> BIT_SHIFT_CTS2TO_8822B) & BIT_MASK_CTS2TO_8822B)
+
+/* 2 REG_ACKTO_8822B (ACK TIMEOUT REGISTER) */
+
+#define BIT_SHIFT_ACKTO_8822B 0
+#define BIT_MASK_ACKTO_8822B 0xff
+#define BIT_ACKTO_8822B(x) \
+ (((x) & BIT_MASK_ACKTO_8822B) << BIT_SHIFT_ACKTO_8822B)
+#define BIT_GET_ACKTO_8822B(x) \
+ (((x) >> BIT_SHIFT_ACKTO_8822B) & BIT_MASK_ACKTO_8822B)
+
+/* 2 REG_NAV_CTRL_8822B (NAV CONTROL REGISTER) */
+
+#define BIT_SHIFT_NAV_UPPER_8822B 16
+#define BIT_MASK_NAV_UPPER_8822B 0xff
+#define BIT_NAV_UPPER_8822B(x) \
+ (((x) & BIT_MASK_NAV_UPPER_8822B) << BIT_SHIFT_NAV_UPPER_8822B)
+#define BIT_GET_NAV_UPPER_8822B(x) \
+ (((x) >> BIT_SHIFT_NAV_UPPER_8822B) & BIT_MASK_NAV_UPPER_8822B)
+
+#define BIT_SHIFT_RXMYRTS_NAV_8822B 8
+#define BIT_MASK_RXMYRTS_NAV_8822B 0xf
+#define BIT_RXMYRTS_NAV_8822B(x) \
+ (((x) & BIT_MASK_RXMYRTS_NAV_8822B) << BIT_SHIFT_RXMYRTS_NAV_8822B)
+#define BIT_GET_RXMYRTS_NAV_8822B(x) \
+ (((x) >> BIT_SHIFT_RXMYRTS_NAV_8822B) & BIT_MASK_RXMYRTS_NAV_8822B)
+
+#define BIT_SHIFT_RTSRST_8822B 0
+#define BIT_MASK_RTSRST_8822B 0xff
+#define BIT_RTSRST_8822B(x) \
+ (((x) & BIT_MASK_RTSRST_8822B) << BIT_SHIFT_RTSRST_8822B)
+#define BIT_GET_RTSRST_8822B(x) \
+ (((x) >> BIT_SHIFT_RTSRST_8822B) & BIT_MASK_RTSRST_8822B)
+
+/* 2 REG_BACAMCMD_8822B (BLOCK ACK CAM COMMAND REGISTER) */
+#define BIT_BACAM_POLL_8822B BIT(31)
+#define BIT_BACAM_RST_8822B BIT(17)
+#define BIT_BACAM_RW_8822B BIT(16)
+
+#define BIT_SHIFT_TXSBM_8822B 14
+#define BIT_MASK_TXSBM_8822B 0x3
+#define BIT_TXSBM_8822B(x) \
+ (((x) & BIT_MASK_TXSBM_8822B) << BIT_SHIFT_TXSBM_8822B)
+#define BIT_GET_TXSBM_8822B(x) \
+ (((x) >> BIT_SHIFT_TXSBM_8822B) & BIT_MASK_TXSBM_8822B)
+
+#define BIT_SHIFT_BACAM_ADDR_8822B 0
+#define BIT_MASK_BACAM_ADDR_8822B 0x3f
+#define BIT_BACAM_ADDR_8822B(x) \
+ (((x) & BIT_MASK_BACAM_ADDR_8822B) << BIT_SHIFT_BACAM_ADDR_8822B)
+#define BIT_GET_BACAM_ADDR_8822B(x) \
+ (((x) >> BIT_SHIFT_BACAM_ADDR_8822B) & BIT_MASK_BACAM_ADDR_8822B)
+
+/* 2 REG_BACAMCONTENT_8822B (BLOCK ACK CAM CONTENT REGISTER) */
+
+#define BIT_SHIFT_BA_CONTENT_H_8822B (32 & CPU_OPT_WIDTH)
+#define BIT_MASK_BA_CONTENT_H_8822B 0xffffffffL
+#define BIT_BA_CONTENT_H_8822B(x) \
+ (((x) & BIT_MASK_BA_CONTENT_H_8822B) << BIT_SHIFT_BA_CONTENT_H_8822B)
+#define BIT_GET_BA_CONTENT_H_8822B(x) \
+ (((x) >> BIT_SHIFT_BA_CONTENT_H_8822B) & BIT_MASK_BA_CONTENT_H_8822B)
+
+#define BIT_SHIFT_BA_CONTENT_L_8822B 0
+#define BIT_MASK_BA_CONTENT_L_8822B 0xffffffffL
+#define BIT_BA_CONTENT_L_8822B(x) \
+ (((x) & BIT_MASK_BA_CONTENT_L_8822B) << BIT_SHIFT_BA_CONTENT_L_8822B)
+#define BIT_GET_BA_CONTENT_L_8822B(x) \
+ (((x) >> BIT_SHIFT_BA_CONTENT_L_8822B) & BIT_MASK_BA_CONTENT_L_8822B)
+
+/* 2 REG_WMAC_BITMAP_CTL_8822B */
+#define BIT_BITMAP_VO_8822B BIT(7)
+#define BIT_BITMAP_VI_8822B BIT(6)
+#define BIT_BITMAP_BE_8822B BIT(5)
+#define BIT_BITMAP_BK_8822B BIT(4)
+
+#define BIT_SHIFT_BITMAP_CONDITION_8822B 2
+#define BIT_MASK_BITMAP_CONDITION_8822B 0x3
+#define BIT_BITMAP_CONDITION_8822B(x) \
+ (((x) & BIT_MASK_BITMAP_CONDITION_8822B) \
+ << BIT_SHIFT_BITMAP_CONDITION_8822B)
+#define BIT_GET_BITMAP_CONDITION_8822B(x) \
+ (((x) >> BIT_SHIFT_BITMAP_CONDITION_8822B) & \
+ BIT_MASK_BITMAP_CONDITION_8822B)
+
+#define BIT_BITMAP_SSNBK_COUNTER_CLR_8822B BIT(1)
+#define BIT_BITMAP_FORCE_8822B BIT(0)
+
+/* 2 REG_TX_RX_8822B STATUS */
+
+#define BIT_SHIFT_RXPKT_TYPE_8822B 2
+#define BIT_MASK_RXPKT_TYPE_8822B 0x3f
+#define BIT_RXPKT_TYPE_8822B(x) \
+ (((x) & BIT_MASK_RXPKT_TYPE_8822B) << BIT_SHIFT_RXPKT_TYPE_8822B)
+#define BIT_GET_RXPKT_TYPE_8822B(x) \
+ (((x) >> BIT_SHIFT_RXPKT_TYPE_8822B) & BIT_MASK_RXPKT_TYPE_8822B)
+
+#define BIT_TXACT_IND_8822B BIT(1)
+#define BIT_RXACT_IND_8822B BIT(0)
+
+/* 2 REG_WMAC_BACAM_RPMEN_8822B */
+
+#define BIT_SHIFT_BITMAP_SSNBK_COUNTER_8822B 2
+#define BIT_MASK_BITMAP_SSNBK_COUNTER_8822B 0x3f
+#define BIT_BITMAP_SSNBK_COUNTER_8822B(x) \
+ (((x) & BIT_MASK_BITMAP_SSNBK_COUNTER_8822B) \
+ << BIT_SHIFT_BITMAP_SSNBK_COUNTER_8822B)
+#define BIT_GET_BITMAP_SSNBK_COUNTER_8822B(x) \
+ (((x) >> BIT_SHIFT_BITMAP_SSNBK_COUNTER_8822B) & \
+ BIT_MASK_BITMAP_SSNBK_COUNTER_8822B)
+
+#define BIT_BITMAP_EN_8822B BIT(1)
+#define BIT_WMAC_BACAM_RPMEN_8822B BIT(0)
+
+/* 2 REG_LBDLY_8822B (LOOPBACK DELAY REGISTER) */
+
+#define BIT_SHIFT_LBDLY_8822B 0
+#define BIT_MASK_LBDLY_8822B 0x1f
+#define BIT_LBDLY_8822B(x) \
+ (((x) & BIT_MASK_LBDLY_8822B) << BIT_SHIFT_LBDLY_8822B)
+#define BIT_GET_LBDLY_8822B(x) \
+ (((x) >> BIT_SHIFT_LBDLY_8822B) & BIT_MASK_LBDLY_8822B)
+
+/* 2 REG_RXERR_RPT_8822B (RX ERROR REPORT REGISTER) */
+
+#define BIT_SHIFT_RXERR_RPT_SEL_V1_3_0_8822B 28
+#define BIT_MASK_RXERR_RPT_SEL_V1_3_0_8822B 0xf
+#define BIT_RXERR_RPT_SEL_V1_3_0_8822B(x) \
+ (((x) & BIT_MASK_RXERR_RPT_SEL_V1_3_0_8822B) \
+ << BIT_SHIFT_RXERR_RPT_SEL_V1_3_0_8822B)
+#define BIT_GET_RXERR_RPT_SEL_V1_3_0_8822B(x) \
+ (((x) >> BIT_SHIFT_RXERR_RPT_SEL_V1_3_0_8822B) & \
+ BIT_MASK_RXERR_RPT_SEL_V1_3_0_8822B)
+
+#define BIT_RXERR_RPT_RST_8822B BIT(27)
+#define BIT_RXERR_RPT_SEL_V1_4_8822B BIT(26)
+#define BIT_W1S_8822B BIT(23)
+#define BIT_UD_SELECT_BSSID_8822B BIT(22)
+
+#define BIT_SHIFT_UD_SUB_TYPE_8822B 18
+#define BIT_MASK_UD_SUB_TYPE_8822B 0xf
+#define BIT_UD_SUB_TYPE_8822B(x) \
+ (((x) & BIT_MASK_UD_SUB_TYPE_8822B) << BIT_SHIFT_UD_SUB_TYPE_8822B)
+#define BIT_GET_UD_SUB_TYPE_8822B(x) \
+ (((x) >> BIT_SHIFT_UD_SUB_TYPE_8822B) & BIT_MASK_UD_SUB_TYPE_8822B)
+
+#define BIT_SHIFT_UD_TYPE_8822B 16
+#define BIT_MASK_UD_TYPE_8822B 0x3
+#define BIT_UD_TYPE_8822B(x) \
+ (((x) & BIT_MASK_UD_TYPE_8822B) << BIT_SHIFT_UD_TYPE_8822B)
+#define BIT_GET_UD_TYPE_8822B(x) \
+ (((x) >> BIT_SHIFT_UD_TYPE_8822B) & BIT_MASK_UD_TYPE_8822B)
+
+#define BIT_SHIFT_RPT_COUNTER_8822B 0
+#define BIT_MASK_RPT_COUNTER_8822B 0xffff
+#define BIT_RPT_COUNTER_8822B(x) \
+ (((x) & BIT_MASK_RPT_COUNTER_8822B) << BIT_SHIFT_RPT_COUNTER_8822B)
+#define BIT_GET_RPT_COUNTER_8822B(x) \
+ (((x) >> BIT_SHIFT_RPT_COUNTER_8822B) & BIT_MASK_RPT_COUNTER_8822B)
+
+/* 2 REG_WMAC_TRXPTCL_CTL_8822B (WMAC TX/RX PROTOCOL CONTROL REGISTER) */
+
+#define BIT_SHIFT_ACKBA_TYPSEL_8822B (60 & CPU_OPT_WIDTH)
+#define BIT_MASK_ACKBA_TYPSEL_8822B 0xf
+#define BIT_ACKBA_TYPSEL_8822B(x) \
+ (((x) & BIT_MASK_ACKBA_TYPSEL_8822B) << BIT_SHIFT_ACKBA_TYPSEL_8822B)
+#define BIT_GET_ACKBA_TYPSEL_8822B(x) \
+ (((x) >> BIT_SHIFT_ACKBA_TYPSEL_8822B) & BIT_MASK_ACKBA_TYPSEL_8822B)
+
+#define BIT_SHIFT_ACKBA_ACKPCHK_8822B (56 & CPU_OPT_WIDTH)
+#define BIT_MASK_ACKBA_ACKPCHK_8822B 0xf
+#define BIT_ACKBA_ACKPCHK_8822B(x) \
+ (((x) & BIT_MASK_ACKBA_ACKPCHK_8822B) << BIT_SHIFT_ACKBA_ACKPCHK_8822B)
+#define BIT_GET_ACKBA_ACKPCHK_8822B(x) \
+ (((x) >> BIT_SHIFT_ACKBA_ACKPCHK_8822B) & BIT_MASK_ACKBA_ACKPCHK_8822B)
+
+#define BIT_SHIFT_ACKBAR_TYPESEL_8822B (48 & CPU_OPT_WIDTH)
+#define BIT_MASK_ACKBAR_TYPESEL_8822B 0xff
+#define BIT_ACKBAR_TYPESEL_8822B(x) \
+ (((x) & BIT_MASK_ACKBAR_TYPESEL_8822B) \
+ << BIT_SHIFT_ACKBAR_TYPESEL_8822B)
+#define BIT_GET_ACKBAR_TYPESEL_8822B(x) \
+ (((x) >> BIT_SHIFT_ACKBAR_TYPESEL_8822B) & \
+ BIT_MASK_ACKBAR_TYPESEL_8822B)
+
+#define BIT_SHIFT_ACKBAR_ACKPCHK_8822B (44 & CPU_OPT_WIDTH)
+#define BIT_MASK_ACKBAR_ACKPCHK_8822B 0xf
+#define BIT_ACKBAR_ACKPCHK_8822B(x) \
+ (((x) & BIT_MASK_ACKBAR_ACKPCHK_8822B) \
+ << BIT_SHIFT_ACKBAR_ACKPCHK_8822B)
+#define BIT_GET_ACKBAR_ACKPCHK_8822B(x) \
+ (((x) >> BIT_SHIFT_ACKBAR_ACKPCHK_8822B) & \
+ BIT_MASK_ACKBAR_ACKPCHK_8822B)
+
+#define BIT_RXBA_IGNOREA2_8822B BIT(42)
+#define BIT_EN_SAVE_ALL_TXOPADDR_8822B BIT(41)
+#define BIT_EN_TXCTS_TO_TXOPOWNER_INRXNAV_8822B BIT(40)
+#define BIT_DIS_TXBA_AMPDUFCSERR_8822B BIT(39)
+#define BIT_DIS_TXBA_RXBARINFULL_8822B BIT(38)
+#define BIT_DIS_TXCFE_INFULL_8822B BIT(37)
+#define BIT_DIS_TXCTS_INFULL_8822B BIT(36)
+#define BIT_EN_TXACKBA_IN_TX_RDG_8822B BIT(35)
+#define BIT_EN_TXACKBA_IN_TXOP_8822B BIT(34)
+#define BIT_EN_TXCTS_IN_RXNAV_8822B BIT(33)
+#define BIT_EN_TXCTS_INTXOP_8822B BIT(32)
+#define BIT_BLK_EDCA_BBSLP_8822B BIT(31)
+#define BIT_BLK_EDCA_BBSBY_8822B BIT(30)
+#define BIT_ACKTO_BLOCK_SCH_EN_8822B BIT(27)
+#define BIT_EIFS_BLOCK_SCH_EN_8822B BIT(26)
+#define BIT_PLCPCHK_RST_EIFS_8822B BIT(25)
+#define BIT_CCA_RST_EIFS_8822B BIT(24)
+#define BIT_DIS_UPD_MYRXPKTNAV_8822B BIT(23)
+#define BIT_EARLY_TXBA_8822B BIT(22)
+
+#define BIT_SHIFT_RESP_CHNBUSY_8822B 20
+#define BIT_MASK_RESP_CHNBUSY_8822B 0x3
+#define BIT_RESP_CHNBUSY_8822B(x) \
+ (((x) & BIT_MASK_RESP_CHNBUSY_8822B) << BIT_SHIFT_RESP_CHNBUSY_8822B)
+#define BIT_GET_RESP_CHNBUSY_8822B(x) \
+ (((x) >> BIT_SHIFT_RESP_CHNBUSY_8822B) & BIT_MASK_RESP_CHNBUSY_8822B)
+
+#define BIT_RESP_DCTS_EN_8822B BIT(19)
+#define BIT_RESP_DCFE_EN_8822B BIT(18)
+#define BIT_RESP_SPLCPEN_8822B BIT(17)
+#define BIT_RESP_SGIEN_8822B BIT(16)
+#define BIT_RESP_LDPC_EN_8822B BIT(15)
+#define BIT_DIS_RESP_ACKINCCA_8822B BIT(14)
+#define BIT_DIS_RESP_CTSINCCA_8822B BIT(13)
+
+#define BIT_SHIFT_R_WMAC_SECOND_CCA_TIMER_8822B 10
+#define BIT_MASK_R_WMAC_SECOND_CCA_TIMER_8822B 0x7
+#define BIT_R_WMAC_SECOND_CCA_TIMER_8822B(x) \
+ (((x) & BIT_MASK_R_WMAC_SECOND_CCA_TIMER_8822B) \
+ << BIT_SHIFT_R_WMAC_SECOND_CCA_TIMER_8822B)
+#define BIT_GET_R_WMAC_SECOND_CCA_TIMER_8822B(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_SECOND_CCA_TIMER_8822B) & \
+ BIT_MASK_R_WMAC_SECOND_CCA_TIMER_8822B)
+
+#define BIT_SHIFT_RFMOD_8822B 7
+#define BIT_MASK_RFMOD_8822B 0x3
+#define BIT_RFMOD_8822B(x) \
+ (((x) & BIT_MASK_RFMOD_8822B) << BIT_SHIFT_RFMOD_8822B)
+#define BIT_GET_RFMOD_8822B(x) \
+ (((x) >> BIT_SHIFT_RFMOD_8822B) & BIT_MASK_RFMOD_8822B)
+
+#define BIT_SHIFT_RESP_CTS_DYNBW_SEL_8822B 5
+#define BIT_MASK_RESP_CTS_DYNBW_SEL_8822B 0x3
+#define BIT_RESP_CTS_DYNBW_SEL_8822B(x) \
+ (((x) & BIT_MASK_RESP_CTS_DYNBW_SEL_8822B) \
+ << BIT_SHIFT_RESP_CTS_DYNBW_SEL_8822B)
+#define BIT_GET_RESP_CTS_DYNBW_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_RESP_CTS_DYNBW_SEL_8822B) & \
+ BIT_MASK_RESP_CTS_DYNBW_SEL_8822B)
+
+#define BIT_DLY_TX_WAIT_RXANTSEL_8822B BIT(4)
+#define BIT_TXRESP_BY_RXANTSEL_8822B BIT(3)
+
+#define BIT_SHIFT_ORIG_DCTS_CHK_8822B 0
+#define BIT_MASK_ORIG_DCTS_CHK_8822B 0x3
+#define BIT_ORIG_DCTS_CHK_8822B(x) \
+ (((x) & BIT_MASK_ORIG_DCTS_CHK_8822B) << BIT_SHIFT_ORIG_DCTS_CHK_8822B)
+#define BIT_GET_ORIG_DCTS_CHK_8822B(x) \
+ (((x) >> BIT_SHIFT_ORIG_DCTS_CHK_8822B) & BIT_MASK_ORIG_DCTS_CHK_8822B)
+
+/* 2 REG_CAMCMD_8822B (CAM COMMAND REGISTER) */
+#define BIT_SECCAM_POLLING_8822B BIT(31)
+#define BIT_SECCAM_CLR_8822B BIT(30)
+#define BIT_MFBCAM_CLR_8822B BIT(29)
+#define BIT_SECCAM_WE_8822B BIT(16)
+
+#define BIT_SHIFT_SECCAM_ADDR_V2_8822B 0
+#define BIT_MASK_SECCAM_ADDR_V2_8822B 0x3ff
+#define BIT_SECCAM_ADDR_V2_8822B(x) \
+ (((x) & BIT_MASK_SECCAM_ADDR_V2_8822B) \
+ << BIT_SHIFT_SECCAM_ADDR_V2_8822B)
+#define BIT_GET_SECCAM_ADDR_V2_8822B(x) \
+ (((x) >> BIT_SHIFT_SECCAM_ADDR_V2_8822B) & \
+ BIT_MASK_SECCAM_ADDR_V2_8822B)
+
+/* 2 REG_CAMWRITE_8822B (CAM WRITE REGISTER) */
+
+#define BIT_SHIFT_CAMW_DATA_8822B 0
+#define BIT_MASK_CAMW_DATA_8822B 0xffffffffL
+#define BIT_CAMW_DATA_8822B(x) \
+ (((x) & BIT_MASK_CAMW_DATA_8822B) << BIT_SHIFT_CAMW_DATA_8822B)
+#define BIT_GET_CAMW_DATA_8822B(x) \
+ (((x) >> BIT_SHIFT_CAMW_DATA_8822B) & BIT_MASK_CAMW_DATA_8822B)
+
+/* 2 REG_CAMREAD_8822B (CAM READ REGISTER) */
+
+#define BIT_SHIFT_CAMR_DATA_8822B 0
+#define BIT_MASK_CAMR_DATA_8822B 0xffffffffL
+#define BIT_CAMR_DATA_8822B(x) \
+ (((x) & BIT_MASK_CAMR_DATA_8822B) << BIT_SHIFT_CAMR_DATA_8822B)
+#define BIT_GET_CAMR_DATA_8822B(x) \
+ (((x) >> BIT_SHIFT_CAMR_DATA_8822B) & BIT_MASK_CAMR_DATA_8822B)
+
+/* 2 REG_CAMDBG_8822B (CAM DEBUG REGISTER) */
+#define BIT_SECCAM_INFO_8822B BIT(31)
+#define BIT_SEC_KEYFOUND_8822B BIT(15)
+
+#define BIT_SHIFT_CAMDBG_SEC_TYPE_8822B 12
+#define BIT_MASK_CAMDBG_SEC_TYPE_8822B 0x7
+#define BIT_CAMDBG_SEC_TYPE_8822B(x) \
+ (((x) & BIT_MASK_CAMDBG_SEC_TYPE_8822B) \
+ << BIT_SHIFT_CAMDBG_SEC_TYPE_8822B)
+#define BIT_GET_CAMDBG_SEC_TYPE_8822B(x) \
+ (((x) >> BIT_SHIFT_CAMDBG_SEC_TYPE_8822B) & \
+ BIT_MASK_CAMDBG_SEC_TYPE_8822B)
+
+#define BIT_CAMDBG_EXT_SECTYPE_8822B BIT(11)
+
+#define BIT_SHIFT_CAMDBG_MIC_KEY_IDX_8822B 5
+#define BIT_MASK_CAMDBG_MIC_KEY_IDX_8822B 0x1f
+#define BIT_CAMDBG_MIC_KEY_IDX_8822B(x) \
+ (((x) & BIT_MASK_CAMDBG_MIC_KEY_IDX_8822B) \
+ << BIT_SHIFT_CAMDBG_MIC_KEY_IDX_8822B)
+#define BIT_GET_CAMDBG_MIC_KEY_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_CAMDBG_MIC_KEY_IDX_8822B) & \
+ BIT_MASK_CAMDBG_MIC_KEY_IDX_8822B)
+
+#define BIT_SHIFT_CAMDBG_SEC_KEY_IDX_8822B 0
+#define BIT_MASK_CAMDBG_SEC_KEY_IDX_8822B 0x1f
+#define BIT_CAMDBG_SEC_KEY_IDX_8822B(x) \
+ (((x) & BIT_MASK_CAMDBG_SEC_KEY_IDX_8822B) \
+ << BIT_SHIFT_CAMDBG_SEC_KEY_IDX_8822B)
+#define BIT_GET_CAMDBG_SEC_KEY_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_CAMDBG_SEC_KEY_IDX_8822B) & \
+ BIT_MASK_CAMDBG_SEC_KEY_IDX_8822B)
+
+/* 2 REG_RXFILTER_ACTION_1_8822B */
+
+#define BIT_SHIFT_RXFILTER_ACTION_1_8822B 0
+#define BIT_MASK_RXFILTER_ACTION_1_8822B 0xff
+#define BIT_RXFILTER_ACTION_1_8822B(x) \
+ (((x) & BIT_MASK_RXFILTER_ACTION_1_8822B) \
+ << BIT_SHIFT_RXFILTER_ACTION_1_8822B)
+#define BIT_GET_RXFILTER_ACTION_1_8822B(x) \
+ (((x) >> BIT_SHIFT_RXFILTER_ACTION_1_8822B) & \
+ BIT_MASK_RXFILTER_ACTION_1_8822B)
+
+/* 2 REG_RXFILTER_CATEGORY_1_8822B */
+
+#define BIT_SHIFT_RXFILTER_CATEGORY_1_8822B 0
+#define BIT_MASK_RXFILTER_CATEGORY_1_8822B 0xff
+#define BIT_RXFILTER_CATEGORY_1_8822B(x) \
+ (((x) & BIT_MASK_RXFILTER_CATEGORY_1_8822B) \
+ << BIT_SHIFT_RXFILTER_CATEGORY_1_8822B)
+#define BIT_GET_RXFILTER_CATEGORY_1_8822B(x) \
+ (((x) >> BIT_SHIFT_RXFILTER_CATEGORY_1_8822B) & \
+ BIT_MASK_RXFILTER_CATEGORY_1_8822B)
+
+/* 2 REG_SECCFG_8822B (SECURITY CONFIGURATION REGISTER) */
+#define BIT_DIS_GCLK_WAPI_8822B BIT(15)
+#define BIT_DIS_GCLK_AES_8822B BIT(14)
+#define BIT_DIS_GCLK_TKIP_8822B BIT(13)
+#define BIT_AES_SEL_QC_1_8822B BIT(12)
+#define BIT_AES_SEL_QC_0_8822B BIT(11)
+#define BIT_CHK_BMC_8822B BIT(9)
+#define BIT_CHK_KEYID_8822B BIT(8)
+#define BIT_RXBCUSEDK_8822B BIT(7)
+#define BIT_TXBCUSEDK_8822B BIT(6)
+#define BIT_NOSKMC_8822B BIT(5)
+#define BIT_SKBYA2_8822B BIT(4)
+#define BIT_RXDEC_8822B BIT(3)
+#define BIT_TXENC_8822B BIT(2)
+#define BIT_RXUHUSEDK_8822B BIT(1)
+#define BIT_TXUHUSEDK_8822B BIT(0)
+
+/* 2 REG_RXFILTER_ACTION_3_8822B */
+
+#define BIT_SHIFT_RXFILTER_ACTION_3_8822B 0
+#define BIT_MASK_RXFILTER_ACTION_3_8822B 0xff
+#define BIT_RXFILTER_ACTION_3_8822B(x) \
+ (((x) & BIT_MASK_RXFILTER_ACTION_3_8822B) \
+ << BIT_SHIFT_RXFILTER_ACTION_3_8822B)
+#define BIT_GET_RXFILTER_ACTION_3_8822B(x) \
+ (((x) >> BIT_SHIFT_RXFILTER_ACTION_3_8822B) & \
+ BIT_MASK_RXFILTER_ACTION_3_8822B)
+
+/* 2 REG_RXFILTER_CATEGORY_3_8822B */
+
+#define BIT_SHIFT_RXFILTER_CATEGORY_3_8822B 0
+#define BIT_MASK_RXFILTER_CATEGORY_3_8822B 0xff
+#define BIT_RXFILTER_CATEGORY_3_8822B(x) \
+ (((x) & BIT_MASK_RXFILTER_CATEGORY_3_8822B) \
+ << BIT_SHIFT_RXFILTER_CATEGORY_3_8822B)
+#define BIT_GET_RXFILTER_CATEGORY_3_8822B(x) \
+ (((x) >> BIT_SHIFT_RXFILTER_CATEGORY_3_8822B) & \
+ BIT_MASK_RXFILTER_CATEGORY_3_8822B)
+
+/* 2 REG_RXFILTER_ACTION_2_8822B */
+
+#define BIT_SHIFT_RXFILTER_ACTION_2_8822B 0
+#define BIT_MASK_RXFILTER_ACTION_2_8822B 0xff
+#define BIT_RXFILTER_ACTION_2_8822B(x) \
+ (((x) & BIT_MASK_RXFILTER_ACTION_2_8822B) \
+ << BIT_SHIFT_RXFILTER_ACTION_2_8822B)
+#define BIT_GET_RXFILTER_ACTION_2_8822B(x) \
+ (((x) >> BIT_SHIFT_RXFILTER_ACTION_2_8822B) & \
+ BIT_MASK_RXFILTER_ACTION_2_8822B)
+
+/* 2 REG_RXFILTER_CATEGORY_2_8822B */
+
+#define BIT_SHIFT_RXFILTER_CATEGORY_2_8822B 0
+#define BIT_MASK_RXFILTER_CATEGORY_2_8822B 0xff
+#define BIT_RXFILTER_CATEGORY_2_8822B(x) \
+ (((x) & BIT_MASK_RXFILTER_CATEGORY_2_8822B) \
+ << BIT_SHIFT_RXFILTER_CATEGORY_2_8822B)
+#define BIT_GET_RXFILTER_CATEGORY_2_8822B(x) \
+ (((x) >> BIT_SHIFT_RXFILTER_CATEGORY_2_8822B) & \
+ BIT_MASK_RXFILTER_CATEGORY_2_8822B)
+
+/* 2 REG_RXFLTMAP4_8822B (RX FILTER MAP GROUP 4) */
+#define BIT_CTRLFLT15EN_FW_8822B BIT(15)
+#define BIT_CTRLFLT14EN_FW_8822B BIT(14)
+#define BIT_CTRLFLT13EN_FW_8822B BIT(13)
+#define BIT_CTRLFLT12EN_FW_8822B BIT(12)
+#define BIT_CTRLFLT11EN_FW_8822B BIT(11)
+#define BIT_CTRLFLT10EN_FW_8822B BIT(10)
+#define BIT_CTRLFLT9EN_FW_8822B BIT(9)
+#define BIT_CTRLFLT8EN_FW_8822B BIT(8)
+#define BIT_CTRLFLT7EN_FW_8822B BIT(7)
+#define BIT_CTRLFLT6EN_FW_8822B BIT(6)
+#define BIT_CTRLFLT5EN_FW_8822B BIT(5)
+#define BIT_CTRLFLT4EN_FW_8822B BIT(4)
+#define BIT_CTRLFLT3EN_FW_8822B BIT(3)
+#define BIT_CTRLFLT2EN_FW_8822B BIT(2)
+#define BIT_CTRLFLT1EN_FW_8822B BIT(1)
+#define BIT_CTRLFLT0EN_FW_8822B BIT(0)
+
+/* 2 REG_RXFLTMAP3_8822B (RX FILTER MAP GROUP 3) */
+#define BIT_MGTFLT15EN_FW_8822B BIT(15)
+#define BIT_MGTFLT14EN_FW_8822B BIT(14)
+#define BIT_MGTFLT13EN_FW_8822B BIT(13)
+#define BIT_MGTFLT12EN_FW_8822B BIT(12)
+#define BIT_MGTFLT11EN_FW_8822B BIT(11)
+#define BIT_MGTFLT10EN_FW_8822B BIT(10)
+#define BIT_MGTFLT9EN_FW_8822B BIT(9)
+#define BIT_MGTFLT8EN_FW_8822B BIT(8)
+#define BIT_MGTFLT7EN_FW_8822B BIT(7)
+#define BIT_MGTFLT6EN_FW_8822B BIT(6)
+#define BIT_MGTFLT5EN_FW_8822B BIT(5)
+#define BIT_MGTFLT4EN_FW_8822B BIT(4)
+#define BIT_MGTFLT3EN_FW_8822B BIT(3)
+#define BIT_MGTFLT2EN_FW_8822B BIT(2)
+#define BIT_MGTFLT1EN_FW_8822B BIT(1)
+#define BIT_MGTFLT0EN_FW_8822B BIT(0)
+
+/* 2 REG_RXFLTMAP6_8822B (RX FILTER MAP GROUP 3) */
+#define BIT_ACTIONFLT15EN_FW_8822B BIT(15)
+#define BIT_ACTIONFLT14EN_FW_8822B BIT(14)
+#define BIT_ACTIONFLT13EN_FW_8822B BIT(13)
+#define BIT_ACTIONFLT12EN_FW_8822B BIT(12)
+#define BIT_ACTIONFLT11EN_FW_8822B BIT(11)
+#define BIT_ACTIONFLT10EN_FW_8822B BIT(10)
+#define BIT_ACTIONFLT9EN_FW_8822B BIT(9)
+#define BIT_ACTIONFLT8EN_FW_8822B BIT(8)
+#define BIT_ACTIONFLT7EN_FW_8822B BIT(7)
+#define BIT_ACTIONFLT6EN_FW_8822B BIT(6)
+#define BIT_ACTIONFLT5EN_FW_8822B BIT(5)
+#define BIT_ACTIONFLT4EN_FW_8822B BIT(4)
+#define BIT_ACTIONFLT3EN_FW_8822B BIT(3)
+#define BIT_ACTIONFLT2EN_FW_8822B BIT(2)
+#define BIT_ACTIONFLT1EN_FW_8822B BIT(1)
+#define BIT_ACTIONFLT0EN_FW_8822B BIT(0)
+
+/* 2 REG_RXFLTMAP5_8822B (RX FILTER MAP GROUP 3) */
+#define BIT_DATAFLT15EN_FW_8822B BIT(15)
+#define BIT_DATAFLT14EN_FW_8822B BIT(14)
+#define BIT_DATAFLT13EN_FW_8822B BIT(13)
+#define BIT_DATAFLT12EN_FW_8822B BIT(12)
+#define BIT_DATAFLT11EN_FW_8822B BIT(11)
+#define BIT_DATAFLT10EN_FW_8822B BIT(10)
+#define BIT_DATAFLT9EN_FW_8822B BIT(9)
+#define BIT_DATAFLT8EN_FW_8822B BIT(8)
+#define BIT_DATAFLT7EN_FW_8822B BIT(7)
+#define BIT_DATAFLT6EN_FW_8822B BIT(6)
+#define BIT_DATAFLT5EN_FW_8822B BIT(5)
+#define BIT_DATAFLT4EN_FW_8822B BIT(4)
+#define BIT_DATAFLT3EN_FW_8822B BIT(3)
+#define BIT_DATAFLT2EN_FW_8822B BIT(2)
+#define BIT_DATAFLT1EN_FW_8822B BIT(1)
+#define BIT_DATAFLT0EN_FW_8822B BIT(0)
+
+/* 2 REG_WMMPS_UAPSD_TID_8822B (WMM POWER SAVE UAPSD TID REGISTER) */
+#define BIT_WMMPS_UAPSD_TID7_8822B BIT(7)
+#define BIT_WMMPS_UAPSD_TID6_8822B BIT(6)
+#define BIT_WMMPS_UAPSD_TID5_8822B BIT(5)
+#define BIT_WMMPS_UAPSD_TID4_8822B BIT(4)
+#define BIT_WMMPS_UAPSD_TID3_8822B BIT(3)
+#define BIT_WMMPS_UAPSD_TID2_8822B BIT(2)
+#define BIT_WMMPS_UAPSD_TID1_8822B BIT(1)
+#define BIT_WMMPS_UAPSD_TID0_8822B BIT(0)
+
+/* 2 REG_PS_RX_INFO_8822B (POWER SAVE RX INFORMATION REGISTER) */
+
+#define BIT_SHIFT_PORTSEL__PS_RX_INFO_8822B 5
+#define BIT_MASK_PORTSEL__PS_RX_INFO_8822B 0x7
+#define BIT_PORTSEL__PS_RX_INFO_8822B(x) \
+ (((x) & BIT_MASK_PORTSEL__PS_RX_INFO_8822B) \
+ << BIT_SHIFT_PORTSEL__PS_RX_INFO_8822B)
+#define BIT_GET_PORTSEL__PS_RX_INFO_8822B(x) \
+ (((x) >> BIT_SHIFT_PORTSEL__PS_RX_INFO_8822B) & \
+ BIT_MASK_PORTSEL__PS_RX_INFO_8822B)
+
+#define BIT_RXCTRLIN0_8822B BIT(4)
+#define BIT_RXMGTIN0_8822B BIT(3)
+#define BIT_RXDATAIN2_8822B BIT(2)
+#define BIT_RXDATAIN1_8822B BIT(1)
+#define BIT_RXDATAIN0_8822B BIT(0)
+
+/* 2 REG_NAN_RX_TSF_FILTER_8822B(NAN_RX_TSF_ADDRESS_FILTER) */
+#define BIT_CHK_TSF_TA_8822B BIT(2)
+#define BIT_CHK_TSF_CBSSID_8822B BIT(1)
+#define BIT_CHK_TSF_EN_8822B BIT(0)
+
+/* 2 REG_WOW_CTRL_8822B (WAKE ON WLAN CONTROL REGISTER) */
+
+#define BIT_SHIFT_PSF_BSSIDSEL_B2B1_8822B 6
+#define BIT_MASK_PSF_BSSIDSEL_B2B1_8822B 0x3
+#define BIT_PSF_BSSIDSEL_B2B1_8822B(x) \
+ (((x) & BIT_MASK_PSF_BSSIDSEL_B2B1_8822B) \
+ << BIT_SHIFT_PSF_BSSIDSEL_B2B1_8822B)
+#define BIT_GET_PSF_BSSIDSEL_B2B1_8822B(x) \
+ (((x) >> BIT_SHIFT_PSF_BSSIDSEL_B2B1_8822B) & \
+ BIT_MASK_PSF_BSSIDSEL_B2B1_8822B)
+
+#define BIT_WOWHCI_8822B BIT(5)
+#define BIT_PSF_BSSIDSEL_B0_8822B BIT(4)
+#define BIT_UWF_8822B BIT(3)
+#define BIT_MAGIC_8822B BIT(2)
+#define BIT_WOWEN_8822B BIT(1)
+#define BIT_FORCE_WAKEUP_8822B BIT(0)
+
+/* 2 REG_LPNAV_CTRL_8822B (LOW POWER NAV CONTROL REGISTER) */
+#define BIT_LPNAV_EN_8822B BIT(31)
+
+#define BIT_SHIFT_LPNAV_EARLY_8822B 16
+#define BIT_MASK_LPNAV_EARLY_8822B 0x7fff
+#define BIT_LPNAV_EARLY_8822B(x) \
+ (((x) & BIT_MASK_LPNAV_EARLY_8822B) << BIT_SHIFT_LPNAV_EARLY_8822B)
+#define BIT_GET_LPNAV_EARLY_8822B(x) \
+ (((x) >> BIT_SHIFT_LPNAV_EARLY_8822B) & BIT_MASK_LPNAV_EARLY_8822B)
+
+#define BIT_SHIFT_LPNAV_TH_8822B 0
+#define BIT_MASK_LPNAV_TH_8822B 0xffff
+#define BIT_LPNAV_TH_8822B(x) \
+ (((x) & BIT_MASK_LPNAV_TH_8822B) << BIT_SHIFT_LPNAV_TH_8822B)
+#define BIT_GET_LPNAV_TH_8822B(x) \
+ (((x) >> BIT_SHIFT_LPNAV_TH_8822B) & BIT_MASK_LPNAV_TH_8822B)
+
+/* 2 REG_WKFMCAM_CMD_8822B (WAKEUP FRAME CAM COMMAND REGISTER) */
+#define BIT_WKFCAM_POLLING_V1_8822B BIT(31)
+#define BIT_WKFCAM_CLR_V1_8822B BIT(30)
+#define BIT_WKFCAM_WE_8822B BIT(16)
+
+#define BIT_SHIFT_WKFCAM_ADDR_V2_8822B 8
+#define BIT_MASK_WKFCAM_ADDR_V2_8822B 0xff
+#define BIT_WKFCAM_ADDR_V2_8822B(x) \
+ (((x) & BIT_MASK_WKFCAM_ADDR_V2_8822B) \
+ << BIT_SHIFT_WKFCAM_ADDR_V2_8822B)
+#define BIT_GET_WKFCAM_ADDR_V2_8822B(x) \
+ (((x) >> BIT_SHIFT_WKFCAM_ADDR_V2_8822B) & \
+ BIT_MASK_WKFCAM_ADDR_V2_8822B)
+
+#define BIT_SHIFT_WKFCAM_CAM_NUM_V1_8822B 0
+#define BIT_MASK_WKFCAM_CAM_NUM_V1_8822B 0xff
+#define BIT_WKFCAM_CAM_NUM_V1_8822B(x) \
+ (((x) & BIT_MASK_WKFCAM_CAM_NUM_V1_8822B) \
+ << BIT_SHIFT_WKFCAM_CAM_NUM_V1_8822B)
+#define BIT_GET_WKFCAM_CAM_NUM_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_WKFCAM_CAM_NUM_V1_8822B) & \
+ BIT_MASK_WKFCAM_CAM_NUM_V1_8822B)
+
+/* 2 REG_WKFMCAM_RWD_8822B (WAKEUP FRAME READ/WRITE DATA) */
+
+#define BIT_SHIFT_WKFMCAM_RWD_8822B 0
+#define BIT_MASK_WKFMCAM_RWD_8822B 0xffffffffL
+#define BIT_WKFMCAM_RWD_8822B(x) \
+ (((x) & BIT_MASK_WKFMCAM_RWD_8822B) << BIT_SHIFT_WKFMCAM_RWD_8822B)
+#define BIT_GET_WKFMCAM_RWD_8822B(x) \
+ (((x) >> BIT_SHIFT_WKFMCAM_RWD_8822B) & BIT_MASK_WKFMCAM_RWD_8822B)
+
+/* 2 REG_RXFLTMAP1_8822B (RX FILTER MAP GROUP 1) */
+#define BIT_CTRLFLT15EN_8822B BIT(15)
+#define BIT_CTRLFLT14EN_8822B BIT(14)
+#define BIT_CTRLFLT13EN_8822B BIT(13)
+#define BIT_CTRLFLT12EN_8822B BIT(12)
+#define BIT_CTRLFLT11EN_8822B BIT(11)
+#define BIT_CTRLFLT10EN_8822B BIT(10)
+#define BIT_CTRLFLT9EN_8822B BIT(9)
+#define BIT_CTRLFLT8EN_8822B BIT(8)
+#define BIT_CTRLFLT7EN_8822B BIT(7)
+#define BIT_CTRLFLT6EN_8822B BIT(6)
+#define BIT_CTRLFLT5EN_8822B BIT(5)
+#define BIT_CTRLFLT4EN_8822B BIT(4)
+#define BIT_CTRLFLT3EN_8822B BIT(3)
+#define BIT_CTRLFLT2EN_8822B BIT(2)
+#define BIT_CTRLFLT1EN_8822B BIT(1)
+#define BIT_CTRLFLT0EN_8822B BIT(0)
+
+/* 2 REG_RXFLTMAP0_8822B (RX FILTER MAP GROUP 0) */
+#define BIT_MGTFLT15EN_8822B BIT(15)
+#define BIT_MGTFLT14EN_8822B BIT(14)
+#define BIT_MGTFLT13EN_8822B BIT(13)
+#define BIT_MGTFLT12EN_8822B BIT(12)
+#define BIT_MGTFLT11EN_8822B BIT(11)
+#define BIT_MGTFLT10EN_8822B BIT(10)
+#define BIT_MGTFLT9EN_8822B BIT(9)
+#define BIT_MGTFLT8EN_8822B BIT(8)
+#define BIT_MGTFLT7EN_8822B BIT(7)
+#define BIT_MGTFLT6EN_8822B BIT(6)
+#define BIT_MGTFLT5EN_8822B BIT(5)
+#define BIT_MGTFLT4EN_8822B BIT(4)
+#define BIT_MGTFLT3EN_8822B BIT(3)
+#define BIT_MGTFLT2EN_8822B BIT(2)
+#define BIT_MGTFLT1EN_8822B BIT(1)
+#define BIT_MGTFLT0EN_8822B BIT(0)
+
+/* 2 REG_NOT_VALID_8822B */
+
+/* 2 REG_RXFLTMAP_8822B (RX FILTER MAP GROUP 2) */
+#define BIT_DATAFLT15EN_8822B BIT(15)
+#define BIT_DATAFLT14EN_8822B BIT(14)
+#define BIT_DATAFLT13EN_8822B BIT(13)
+#define BIT_DATAFLT12EN_8822B BIT(12)
+#define BIT_DATAFLT11EN_8822B BIT(11)
+#define BIT_DATAFLT10EN_8822B BIT(10)
+#define BIT_DATAFLT9EN_8822B BIT(9)
+#define BIT_DATAFLT8EN_8822B BIT(8)
+#define BIT_DATAFLT7EN_8822B BIT(7)
+#define BIT_DATAFLT6EN_8822B BIT(6)
+#define BIT_DATAFLT5EN_8822B BIT(5)
+#define BIT_DATAFLT4EN_8822B BIT(4)
+#define BIT_DATAFLT3EN_8822B BIT(3)
+#define BIT_DATAFLT2EN_8822B BIT(2)
+#define BIT_DATAFLT1EN_8822B BIT(1)
+#define BIT_DATAFLT0EN_8822B BIT(0)
+
+/* 2 REG_BCN_PSR_RPT_8822B (BEACON PARSER REPORT REGISTER) */
+
+#define BIT_SHIFT_DTIM_CNT_8822B 24
+#define BIT_MASK_DTIM_CNT_8822B 0xff
+#define BIT_DTIM_CNT_8822B(x) \
+ (((x) & BIT_MASK_DTIM_CNT_8822B) << BIT_SHIFT_DTIM_CNT_8822B)
+#define BIT_GET_DTIM_CNT_8822B(x) \
+ (((x) >> BIT_SHIFT_DTIM_CNT_8822B) & BIT_MASK_DTIM_CNT_8822B)
+
+#define BIT_SHIFT_DTIM_PERIOD_8822B 16
+#define BIT_MASK_DTIM_PERIOD_8822B 0xff
+#define BIT_DTIM_PERIOD_8822B(x) \
+ (((x) & BIT_MASK_DTIM_PERIOD_8822B) << BIT_SHIFT_DTIM_PERIOD_8822B)
+#define BIT_GET_DTIM_PERIOD_8822B(x) \
+ (((x) >> BIT_SHIFT_DTIM_PERIOD_8822B) & BIT_MASK_DTIM_PERIOD_8822B)
+
+#define BIT_DTIM_8822B BIT(15)
+#define BIT_TIM_8822B BIT(14)
+
+#define BIT_SHIFT_PS_AID_0_8822B 0
+#define BIT_MASK_PS_AID_0_8822B 0x7ff
+#define BIT_PS_AID_0_8822B(x) \
+ (((x) & BIT_MASK_PS_AID_0_8822B) << BIT_SHIFT_PS_AID_0_8822B)
+#define BIT_GET_PS_AID_0_8822B(x) \
+ (((x) >> BIT_SHIFT_PS_AID_0_8822B) & BIT_MASK_PS_AID_0_8822B)
+
+/* 2 REG_FLC_TRPC_8822B (TIMER OF FLC_RPC) */
+#define BIT_FLC_RPCT_V1_8822B BIT(7)
+#define BIT_MODE_8822B BIT(6)
+
+#define BIT_SHIFT_TRPCD_8822B 0
+#define BIT_MASK_TRPCD_8822B 0x3f
+#define BIT_TRPCD_8822B(x) \
+ (((x) & BIT_MASK_TRPCD_8822B) << BIT_SHIFT_TRPCD_8822B)
+#define BIT_GET_TRPCD_8822B(x) \
+ (((x) >> BIT_SHIFT_TRPCD_8822B) & BIT_MASK_TRPCD_8822B)
+
+/* 2 REG_FLC_PTS_8822B (PKT TYPE SELECTION OF FLC_RPC T) */
+#define BIT_CMF_8822B BIT(2)
+#define BIT_CCF_8822B BIT(1)
+#define BIT_CDF_8822B BIT(0)
+
+/* 2 REG_FLC_RPCT_8822B (FLC_RPC THRESHOLD) */
+
+#define BIT_SHIFT_FLC_RPCT_8822B 0
+#define BIT_MASK_FLC_RPCT_8822B 0xff
+#define BIT_FLC_RPCT_8822B(x) \
+ (((x) & BIT_MASK_FLC_RPCT_8822B) << BIT_SHIFT_FLC_RPCT_8822B)
+#define BIT_GET_FLC_RPCT_8822B(x) \
+ (((x) >> BIT_SHIFT_FLC_RPCT_8822B) & BIT_MASK_FLC_RPCT_8822B)
+
+/* 2 REG_FLC_RPC_8822B (FW LPS CONDITION -- RX PKT COUNTER) */
+
+#define BIT_SHIFT_FLC_RPC_8822B 0
+#define BIT_MASK_FLC_RPC_8822B 0xff
+#define BIT_FLC_RPC_8822B(x) \
+ (((x) & BIT_MASK_FLC_RPC_8822B) << BIT_SHIFT_FLC_RPC_8822B)
+#define BIT_GET_FLC_RPC_8822B(x) \
+ (((x) >> BIT_SHIFT_FLC_RPC_8822B) & BIT_MASK_FLC_RPC_8822B)
+
+/* 2 REG_RXPKTMON_CTRL_8822B */
+
+#define BIT_SHIFT_RXBKQPKT_SEQ_8822B 20
+#define BIT_MASK_RXBKQPKT_SEQ_8822B 0xf
+#define BIT_RXBKQPKT_SEQ_8822B(x) \
+ (((x) & BIT_MASK_RXBKQPKT_SEQ_8822B) << BIT_SHIFT_RXBKQPKT_SEQ_8822B)
+#define BIT_GET_RXBKQPKT_SEQ_8822B(x) \
+ (((x) >> BIT_SHIFT_RXBKQPKT_SEQ_8822B) & BIT_MASK_RXBKQPKT_SEQ_8822B)
+
+#define BIT_SHIFT_RXBEQPKT_SEQ_8822B 16
+#define BIT_MASK_RXBEQPKT_SEQ_8822B 0xf
+#define BIT_RXBEQPKT_SEQ_8822B(x) \
+ (((x) & BIT_MASK_RXBEQPKT_SEQ_8822B) << BIT_SHIFT_RXBEQPKT_SEQ_8822B)
+#define BIT_GET_RXBEQPKT_SEQ_8822B(x) \
+ (((x) >> BIT_SHIFT_RXBEQPKT_SEQ_8822B) & BIT_MASK_RXBEQPKT_SEQ_8822B)
+
+#define BIT_SHIFT_RXVIQPKT_SEQ_8822B 12
+#define BIT_MASK_RXVIQPKT_SEQ_8822B 0xf
+#define BIT_RXVIQPKT_SEQ_8822B(x) \
+ (((x) & BIT_MASK_RXVIQPKT_SEQ_8822B) << BIT_SHIFT_RXVIQPKT_SEQ_8822B)
+#define BIT_GET_RXVIQPKT_SEQ_8822B(x) \
+ (((x) >> BIT_SHIFT_RXVIQPKT_SEQ_8822B) & BIT_MASK_RXVIQPKT_SEQ_8822B)
+
+#define BIT_SHIFT_RXVOQPKT_SEQ_8822B 8
+#define BIT_MASK_RXVOQPKT_SEQ_8822B 0xf
+#define BIT_RXVOQPKT_SEQ_8822B(x) \
+ (((x) & BIT_MASK_RXVOQPKT_SEQ_8822B) << BIT_SHIFT_RXVOQPKT_SEQ_8822B)
+#define BIT_GET_RXVOQPKT_SEQ_8822B(x) \
+ (((x) >> BIT_SHIFT_RXVOQPKT_SEQ_8822B) & BIT_MASK_RXVOQPKT_SEQ_8822B)
+
+#define BIT_RXBKQPKT_ERR_8822B BIT(7)
+#define BIT_RXBEQPKT_ERR_8822B BIT(6)
+#define BIT_RXVIQPKT_ERR_8822B BIT(5)
+#define BIT_RXVOQPKT_ERR_8822B BIT(4)
+#define BIT_RXDMA_MON_EN_8822B BIT(2)
+#define BIT_RXPKT_MON_RST_8822B BIT(1)
+#define BIT_RXPKT_MON_EN_8822B BIT(0)
+
+/* 2 REG_STATE_MON_8822B */
+
+#define BIT_SHIFT_STATE_SEL_8822B 24
+#define BIT_MASK_STATE_SEL_8822B 0x1f
+#define BIT_STATE_SEL_8822B(x) \
+ (((x) & BIT_MASK_STATE_SEL_8822B) << BIT_SHIFT_STATE_SEL_8822B)
+#define BIT_GET_STATE_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_STATE_SEL_8822B) & BIT_MASK_STATE_SEL_8822B)
+
+#define BIT_SHIFT_STATE_INFO_8822B 8
+#define BIT_MASK_STATE_INFO_8822B 0xff
+#define BIT_STATE_INFO_8822B(x) \
+ (((x) & BIT_MASK_STATE_INFO_8822B) << BIT_SHIFT_STATE_INFO_8822B)
+#define BIT_GET_STATE_INFO_8822B(x) \
+ (((x) >> BIT_SHIFT_STATE_INFO_8822B) & BIT_MASK_STATE_INFO_8822B)
+
+#define BIT_UPD_NXT_STATE_8822B BIT(7)
+
+#define BIT_SHIFT_CUR_STATE_8822B 0
+#define BIT_MASK_CUR_STATE_8822B 0x7f
+#define BIT_CUR_STATE_8822B(x) \
+ (((x) & BIT_MASK_CUR_STATE_8822B) << BIT_SHIFT_CUR_STATE_8822B)
+#define BIT_GET_CUR_STATE_8822B(x) \
+ (((x) >> BIT_SHIFT_CUR_STATE_8822B) & BIT_MASK_CUR_STATE_8822B)
+
+/* 2 REG_ERROR_MON_8822B */
+#define BIT_MACRX_ERR_1_8822B BIT(17)
+#define BIT_MACRX_ERR_0_8822B BIT(16)
+#define BIT_MACTX_ERR_3_8822B BIT(3)
+#define BIT_MACTX_ERR_2_8822B BIT(2)
+#define BIT_MACTX_ERR_1_8822B BIT(1)
+#define BIT_MACTX_ERR_0_8822B BIT(0)
+
+/* 2 REG_SEARCH_MACID_8822B */
+#define BIT_EN_TXRPTBUF_CLK_8822B BIT(31)
+
+#define BIT_SHIFT_INFO_INDEX_OFFSET_8822B 16
+#define BIT_MASK_INFO_INDEX_OFFSET_8822B 0x1fff
+#define BIT_INFO_INDEX_OFFSET_8822B(x) \
+ (((x) & BIT_MASK_INFO_INDEX_OFFSET_8822B) \
+ << BIT_SHIFT_INFO_INDEX_OFFSET_8822B)
+#define BIT_GET_INFO_INDEX_OFFSET_8822B(x) \
+ (((x) >> BIT_SHIFT_INFO_INDEX_OFFSET_8822B) & \
+ BIT_MASK_INFO_INDEX_OFFSET_8822B)
+
+#define BIT_WMAC_SRCH_FIFOFULL_8822B BIT(15)
+#define BIT_DIS_INFOSRCH_8822B BIT(14)
+#define BIT_DISABLE_B0_8822B BIT(13)
+
+#define BIT_SHIFT_INFO_ADDR_OFFSET_8822B 0
+#define BIT_MASK_INFO_ADDR_OFFSET_8822B 0x1fff
+#define BIT_INFO_ADDR_OFFSET_8822B(x) \
+ (((x) & BIT_MASK_INFO_ADDR_OFFSET_8822B) \
+ << BIT_SHIFT_INFO_ADDR_OFFSET_8822B)
+#define BIT_GET_INFO_ADDR_OFFSET_8822B(x) \
+ (((x) >> BIT_SHIFT_INFO_ADDR_OFFSET_8822B) & \
+ BIT_MASK_INFO_ADDR_OFFSET_8822B)
+
+/* 2 REG_BT_COEX_TABLE_8822B (BT-COEXISTENCE CONTROL REGISTER) */
+#define BIT_PRI_MASK_RX_RESP_8822B BIT(126)
+#define BIT_PRI_MASK_RXOFDM_8822B BIT(125)
+#define BIT_PRI_MASK_RXCCK_8822B BIT(124)
+
+#define BIT_SHIFT_PRI_MASK_TXAC_8822B (117 & CPU_OPT_WIDTH)
+#define BIT_MASK_PRI_MASK_TXAC_8822B 0x7f
+#define BIT_PRI_MASK_TXAC_8822B(x) \
+ (((x) & BIT_MASK_PRI_MASK_TXAC_8822B) << BIT_SHIFT_PRI_MASK_TXAC_8822B)
+#define BIT_GET_PRI_MASK_TXAC_8822B(x) \
+ (((x) >> BIT_SHIFT_PRI_MASK_TXAC_8822B) & BIT_MASK_PRI_MASK_TXAC_8822B)
+
+#define BIT_SHIFT_PRI_MASK_NAV_8822B (109 & CPU_OPT_WIDTH)
+#define BIT_MASK_PRI_MASK_NAV_8822B 0xff
+#define BIT_PRI_MASK_NAV_8822B(x) \
+ (((x) & BIT_MASK_PRI_MASK_NAV_8822B) << BIT_SHIFT_PRI_MASK_NAV_8822B)
+#define BIT_GET_PRI_MASK_NAV_8822B(x) \
+ (((x) >> BIT_SHIFT_PRI_MASK_NAV_8822B) & BIT_MASK_PRI_MASK_NAV_8822B)
+
+#define BIT_PRI_MASK_CCK_8822B BIT(108)
+#define BIT_PRI_MASK_OFDM_8822B BIT(107)
+#define BIT_PRI_MASK_RTY_8822B BIT(106)
+
+#define BIT_SHIFT_PRI_MASK_NUM_8822B (102 & CPU_OPT_WIDTH)
+#define BIT_MASK_PRI_MASK_NUM_8822B 0xf
+#define BIT_PRI_MASK_NUM_8822B(x) \
+ (((x) & BIT_MASK_PRI_MASK_NUM_8822B) << BIT_SHIFT_PRI_MASK_NUM_8822B)
+#define BIT_GET_PRI_MASK_NUM_8822B(x) \
+ (((x) >> BIT_SHIFT_PRI_MASK_NUM_8822B) & BIT_MASK_PRI_MASK_NUM_8822B)
+
+#define BIT_SHIFT_PRI_MASK_TYPE_8822B (98 & CPU_OPT_WIDTH)
+#define BIT_MASK_PRI_MASK_TYPE_8822B 0xf
+#define BIT_PRI_MASK_TYPE_8822B(x) \
+ (((x) & BIT_MASK_PRI_MASK_TYPE_8822B) << BIT_SHIFT_PRI_MASK_TYPE_8822B)
+#define BIT_GET_PRI_MASK_TYPE_8822B(x) \
+ (((x) >> BIT_SHIFT_PRI_MASK_TYPE_8822B) & BIT_MASK_PRI_MASK_TYPE_8822B)
+
+#define BIT_OOB_8822B BIT(97)
+#define BIT_ANT_SEL_8822B BIT(96)
+
+#define BIT_SHIFT_BREAK_TABLE_2_8822B (80 & CPU_OPT_WIDTH)
+#define BIT_MASK_BREAK_TABLE_2_8822B 0xffff
+#define BIT_BREAK_TABLE_2_8822B(x) \
+ (((x) & BIT_MASK_BREAK_TABLE_2_8822B) << BIT_SHIFT_BREAK_TABLE_2_8822B)
+#define BIT_GET_BREAK_TABLE_2_8822B(x) \
+ (((x) >> BIT_SHIFT_BREAK_TABLE_2_8822B) & BIT_MASK_BREAK_TABLE_2_8822B)
+
+#define BIT_SHIFT_BREAK_TABLE_1_8822B (64 & CPU_OPT_WIDTH)
+#define BIT_MASK_BREAK_TABLE_1_8822B 0xffff
+#define BIT_BREAK_TABLE_1_8822B(x) \
+ (((x) & BIT_MASK_BREAK_TABLE_1_8822B) << BIT_SHIFT_BREAK_TABLE_1_8822B)
+#define BIT_GET_BREAK_TABLE_1_8822B(x) \
+ (((x) >> BIT_SHIFT_BREAK_TABLE_1_8822B) & BIT_MASK_BREAK_TABLE_1_8822B)
+
+#define BIT_SHIFT_COEX_TABLE_2_8822B (32 & CPU_OPT_WIDTH)
+#define BIT_MASK_COEX_TABLE_2_8822B 0xffffffffL
+#define BIT_COEX_TABLE_2_8822B(x) \
+ (((x) & BIT_MASK_COEX_TABLE_2_8822B) << BIT_SHIFT_COEX_TABLE_2_8822B)
+#define BIT_GET_COEX_TABLE_2_8822B(x) \
+ (((x) >> BIT_SHIFT_COEX_TABLE_2_8822B) & BIT_MASK_COEX_TABLE_2_8822B)
+
+#define BIT_SHIFT_COEX_TABLE_1_8822B 0
+#define BIT_MASK_COEX_TABLE_1_8822B 0xffffffffL
+#define BIT_COEX_TABLE_1_8822B(x) \
+ (((x) & BIT_MASK_COEX_TABLE_1_8822B) << BIT_SHIFT_COEX_TABLE_1_8822B)
+#define BIT_GET_COEX_TABLE_1_8822B(x) \
+ (((x) >> BIT_SHIFT_COEX_TABLE_1_8822B) & BIT_MASK_COEX_TABLE_1_8822B)
+
+/* 2 REG_RXCMD_0_8822B */
+#define BIT_RXCMD_EN_8822B BIT(31)
+
+#define BIT_SHIFT_RXCMD_INFO_8822B 0
+#define BIT_MASK_RXCMD_INFO_8822B 0x7fffffffL
+#define BIT_RXCMD_INFO_8822B(x) \
+ (((x) & BIT_MASK_RXCMD_INFO_8822B) << BIT_SHIFT_RXCMD_INFO_8822B)
+#define BIT_GET_RXCMD_INFO_8822B(x) \
+ (((x) >> BIT_SHIFT_RXCMD_INFO_8822B) & BIT_MASK_RXCMD_INFO_8822B)
+
+/* 2 REG_RXCMD_1_8822B */
+
+#define BIT_SHIFT_RXCMD_PRD_8822B 0
+#define BIT_MASK_RXCMD_PRD_8822B 0xffff
+#define BIT_RXCMD_PRD_8822B(x) \
+ (((x) & BIT_MASK_RXCMD_PRD_8822B) << BIT_SHIFT_RXCMD_PRD_8822B)
+#define BIT_GET_RXCMD_PRD_8822B(x) \
+ (((x) >> BIT_SHIFT_RXCMD_PRD_8822B) & BIT_MASK_RXCMD_PRD_8822B)
+
+/* 2 REG_NOT_VALID_8822B */
+
+/* 2 REG_WMAC_RESP_TXINFO_8822B (RESPONSE TXINFO REGISTER) */
+
+#define BIT_SHIFT_WMAC_RESP_MFB_8822B 25
+#define BIT_MASK_WMAC_RESP_MFB_8822B 0x7f
+#define BIT_WMAC_RESP_MFB_8822B(x) \
+ (((x) & BIT_MASK_WMAC_RESP_MFB_8822B) << BIT_SHIFT_WMAC_RESP_MFB_8822B)
+#define BIT_GET_WMAC_RESP_MFB_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_RESP_MFB_8822B) & BIT_MASK_WMAC_RESP_MFB_8822B)
+
+#define BIT_SHIFT_WMAC_ANTINF_SEL_8822B 23
+#define BIT_MASK_WMAC_ANTINF_SEL_8822B 0x3
+#define BIT_WMAC_ANTINF_SEL_8822B(x) \
+ (((x) & BIT_MASK_WMAC_ANTINF_SEL_8822B) \
+ << BIT_SHIFT_WMAC_ANTINF_SEL_8822B)
+#define BIT_GET_WMAC_ANTINF_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_ANTINF_SEL_8822B) & \
+ BIT_MASK_WMAC_ANTINF_SEL_8822B)
+
+#define BIT_SHIFT_WMAC_ANTSEL_SEL_8822B 21
+#define BIT_MASK_WMAC_ANTSEL_SEL_8822B 0x3
+#define BIT_WMAC_ANTSEL_SEL_8822B(x) \
+ (((x) & BIT_MASK_WMAC_ANTSEL_SEL_8822B) \
+ << BIT_SHIFT_WMAC_ANTSEL_SEL_8822B)
+#define BIT_GET_WMAC_ANTSEL_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_ANTSEL_SEL_8822B) & \
+ BIT_MASK_WMAC_ANTSEL_SEL_8822B)
+
+#define BIT_SHIFT_R_WMAC_RESP_TXPOWER_8822B 18
+#define BIT_MASK_R_WMAC_RESP_TXPOWER_8822B 0x7
+#define BIT_R_WMAC_RESP_TXPOWER_8822B(x) \
+ (((x) & BIT_MASK_R_WMAC_RESP_TXPOWER_8822B) \
+ << BIT_SHIFT_R_WMAC_RESP_TXPOWER_8822B)
+#define BIT_GET_R_WMAC_RESP_TXPOWER_8822B(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_RESP_TXPOWER_8822B) & \
+ BIT_MASK_R_WMAC_RESP_TXPOWER_8822B)
+
+#define BIT_SHIFT_WMAC_RESP_TXANT_8822B 0
+#define BIT_MASK_WMAC_RESP_TXANT_8822B 0x3ffff
+#define BIT_WMAC_RESP_TXANT_8822B(x) \
+ (((x) & BIT_MASK_WMAC_RESP_TXANT_8822B) \
+ << BIT_SHIFT_WMAC_RESP_TXANT_8822B)
+#define BIT_GET_WMAC_RESP_TXANT_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_RESP_TXANT_8822B) & \
+ BIT_MASK_WMAC_RESP_TXANT_8822B)
+
+/* 2 REG_BBPSF_CTRL_8822B */
+#define BIT_CTL_IDLE_CLR_CSI_RPT_8822B BIT(31)
+#define BIT_WMAC_USE_NDPARATE_8822B BIT(30)
+
+#define BIT_SHIFT_WMAC_CSI_RATE_8822B 24
+#define BIT_MASK_WMAC_CSI_RATE_8822B 0x3f
+#define BIT_WMAC_CSI_RATE_8822B(x) \
+ (((x) & BIT_MASK_WMAC_CSI_RATE_8822B) << BIT_SHIFT_WMAC_CSI_RATE_8822B)
+#define BIT_GET_WMAC_CSI_RATE_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_CSI_RATE_8822B) & BIT_MASK_WMAC_CSI_RATE_8822B)
+
+#define BIT_SHIFT_WMAC_RESP_TXRATE_8822B 16
+#define BIT_MASK_WMAC_RESP_TXRATE_8822B 0xff
+#define BIT_WMAC_RESP_TXRATE_8822B(x) \
+ (((x) & BIT_MASK_WMAC_RESP_TXRATE_8822B) \
+ << BIT_SHIFT_WMAC_RESP_TXRATE_8822B)
+#define BIT_GET_WMAC_RESP_TXRATE_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_RESP_TXRATE_8822B) & \
+ BIT_MASK_WMAC_RESP_TXRATE_8822B)
+
+#define BIT_BBPSF_MPDUCHKEN_8822B BIT(5)
+#define BIT_BBPSF_MHCHKEN_8822B BIT(4)
+#define BIT_BBPSF_ERRCHKEN_8822B BIT(3)
+
+#define BIT_SHIFT_BBPSF_ERRTHR_8822B 0
+#define BIT_MASK_BBPSF_ERRTHR_8822B 0x7
+#define BIT_BBPSF_ERRTHR_8822B(x) \
+ (((x) & BIT_MASK_BBPSF_ERRTHR_8822B) << BIT_SHIFT_BBPSF_ERRTHR_8822B)
+#define BIT_GET_BBPSF_ERRTHR_8822B(x) \
+ (((x) >> BIT_SHIFT_BBPSF_ERRTHR_8822B) & BIT_MASK_BBPSF_ERRTHR_8822B)
+
+/* 2 REG_NOT_VALID_8822B */
+
+/* 2 REG_P2P_RX_BCN_NOA_8822B (P2P RX BEACON NOA REGISTER) */
+#define BIT_NOA_PARSER_EN_8822B BIT(15)
+#define BIT_BSSID_SEL_8822B BIT(14)
+
+#define BIT_SHIFT_P2P_OUI_TYPE_8822B 0
+#define BIT_MASK_P2P_OUI_TYPE_8822B 0xff
+#define BIT_P2P_OUI_TYPE_8822B(x) \
+ (((x) & BIT_MASK_P2P_OUI_TYPE_8822B) << BIT_SHIFT_P2P_OUI_TYPE_8822B)
+#define BIT_GET_P2P_OUI_TYPE_8822B(x) \
+ (((x) >> BIT_SHIFT_P2P_OUI_TYPE_8822B) & BIT_MASK_P2P_OUI_TYPE_8822B)
+
+/* 2 REG_ASSOCIATED_BFMER0_INFO_8822B (ASSOCIATED BEAMFORMER0 INFO REGISTER) */
+
+#define BIT_SHIFT_R_WMAC_TXCSI_AID0_8822B (48 & CPU_OPT_WIDTH)
+#define BIT_MASK_R_WMAC_TXCSI_AID0_8822B 0x1ff
+#define BIT_R_WMAC_TXCSI_AID0_8822B(x) \
+ (((x) & BIT_MASK_R_WMAC_TXCSI_AID0_8822B) \
+ << BIT_SHIFT_R_WMAC_TXCSI_AID0_8822B)
+#define BIT_GET_R_WMAC_TXCSI_AID0_8822B(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_TXCSI_AID0_8822B) & \
+ BIT_MASK_R_WMAC_TXCSI_AID0_8822B)
+
+#define BIT_SHIFT_R_WMAC_SOUNDING_RXADD_R0_8822B 0
+#define BIT_MASK_R_WMAC_SOUNDING_RXADD_R0_8822B 0xffffffffffffL
+#define BIT_R_WMAC_SOUNDING_RXADD_R0_8822B(x) \
+ (((x) & BIT_MASK_R_WMAC_SOUNDING_RXADD_R0_8822B) \
+ << BIT_SHIFT_R_WMAC_SOUNDING_RXADD_R0_8822B)
+#define BIT_GET_R_WMAC_SOUNDING_RXADD_R0_8822B(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_SOUNDING_RXADD_R0_8822B) & \
+ BIT_MASK_R_WMAC_SOUNDING_RXADD_R0_8822B)
+
+/* 2 REG_ASSOCIATED_BFMER1_INFO_8822B (ASSOCIATED BEAMFORMER1 INFO REGISTER) */
+
+#define BIT_SHIFT_R_WMAC_TXCSI_AID1_8822B (48 & CPU_OPT_WIDTH)
+#define BIT_MASK_R_WMAC_TXCSI_AID1_8822B 0x1ff
+#define BIT_R_WMAC_TXCSI_AID1_8822B(x) \
+ (((x) & BIT_MASK_R_WMAC_TXCSI_AID1_8822B) \
+ << BIT_SHIFT_R_WMAC_TXCSI_AID1_8822B)
+#define BIT_GET_R_WMAC_TXCSI_AID1_8822B(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_TXCSI_AID1_8822B) & \
+ BIT_MASK_R_WMAC_TXCSI_AID1_8822B)
+
+#define BIT_SHIFT_R_WMAC_SOUNDING_RXADD_R1_8822B 0
+#define BIT_MASK_R_WMAC_SOUNDING_RXADD_R1_8822B 0xffffffffffffL
+#define BIT_R_WMAC_SOUNDING_RXADD_R1_8822B(x) \
+ (((x) & BIT_MASK_R_WMAC_SOUNDING_RXADD_R1_8822B) \
+ << BIT_SHIFT_R_WMAC_SOUNDING_RXADD_R1_8822B)
+#define BIT_GET_R_WMAC_SOUNDING_RXADD_R1_8822B(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_SOUNDING_RXADD_R1_8822B) & \
+ BIT_MASK_R_WMAC_SOUNDING_RXADD_R1_8822B)
+
+/* 2 REG_TX_CSI_RPT_PARAM_BW20_8822B (TX CSI REPORT PARAMETER REGISTER) */
+
+#define BIT_SHIFT_R_WMAC_BFINFO_20M_1_8822B 16
+#define BIT_MASK_R_WMAC_BFINFO_20M_1_8822B 0xfff
+#define BIT_R_WMAC_BFINFO_20M_1_8822B(x) \
+ (((x) & BIT_MASK_R_WMAC_BFINFO_20M_1_8822B) \
+ << BIT_SHIFT_R_WMAC_BFINFO_20M_1_8822B)
+#define BIT_GET_R_WMAC_BFINFO_20M_1_8822B(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_BFINFO_20M_1_8822B) & \
+ BIT_MASK_R_WMAC_BFINFO_20M_1_8822B)
+
+#define BIT_SHIFT_R_WMAC_BFINFO_20M_0_8822B 0
+#define BIT_MASK_R_WMAC_BFINFO_20M_0_8822B 0xfff
+#define BIT_R_WMAC_BFINFO_20M_0_8822B(x) \
+ (((x) & BIT_MASK_R_WMAC_BFINFO_20M_0_8822B) \
+ << BIT_SHIFT_R_WMAC_BFINFO_20M_0_8822B)
+#define BIT_GET_R_WMAC_BFINFO_20M_0_8822B(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_BFINFO_20M_0_8822B) & \
+ BIT_MASK_R_WMAC_BFINFO_20M_0_8822B)
+
+/* 2 REG_TX_CSI_RPT_PARAM_BW40_8822B (TX CSI REPORT PARAMETER_BW40 REGISTER) */
+
+#define BIT_SHIFT_WMAC_RESP_ANTCD_8822B 0
+#define BIT_MASK_WMAC_RESP_ANTCD_8822B 0xf
+#define BIT_WMAC_RESP_ANTCD_8822B(x) \
+ (((x) & BIT_MASK_WMAC_RESP_ANTCD_8822B) \
+ << BIT_SHIFT_WMAC_RESP_ANTCD_8822B)
+#define BIT_GET_WMAC_RESP_ANTCD_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_RESP_ANTCD_8822B) & \
+ BIT_MASK_WMAC_RESP_ANTCD_8822B)
+
+/* 2 REG_TX_CSI_RPT_PARAM_BW80_8822B (TX CSI REPORT PARAMETER_BW80 REGISTER) */
+
+/* 2 REG_BCN_PSR_RPT2_8822B (BEACON PARSER REPORT REGISTER2) */
+
+#define BIT_SHIFT_DTIM_CNT2_8822B 24
+#define BIT_MASK_DTIM_CNT2_8822B 0xff
+#define BIT_DTIM_CNT2_8822B(x) \
+ (((x) & BIT_MASK_DTIM_CNT2_8822B) << BIT_SHIFT_DTIM_CNT2_8822B)
+#define BIT_GET_DTIM_CNT2_8822B(x) \
+ (((x) >> BIT_SHIFT_DTIM_CNT2_8822B) & BIT_MASK_DTIM_CNT2_8822B)
+
+#define BIT_SHIFT_DTIM_PERIOD2_8822B 16
+#define BIT_MASK_DTIM_PERIOD2_8822B 0xff
+#define BIT_DTIM_PERIOD2_8822B(x) \
+ (((x) & BIT_MASK_DTIM_PERIOD2_8822B) << BIT_SHIFT_DTIM_PERIOD2_8822B)
+#define BIT_GET_DTIM_PERIOD2_8822B(x) \
+ (((x) >> BIT_SHIFT_DTIM_PERIOD2_8822B) & BIT_MASK_DTIM_PERIOD2_8822B)
+
+#define BIT_DTIM2_8822B BIT(15)
+#define BIT_TIM2_8822B BIT(14)
+
+#define BIT_SHIFT_PS_AID_2_8822B 0
+#define BIT_MASK_PS_AID_2_8822B 0x7ff
+#define BIT_PS_AID_2_8822B(x) \
+ (((x) & BIT_MASK_PS_AID_2_8822B) << BIT_SHIFT_PS_AID_2_8822B)
+#define BIT_GET_PS_AID_2_8822B(x) \
+ (((x) >> BIT_SHIFT_PS_AID_2_8822B) & BIT_MASK_PS_AID_2_8822B)
+
+/* 2 REG_BCN_PSR_RPT3_8822B (BEACON PARSER REPORT REGISTER3) */
+
+#define BIT_SHIFT_DTIM_CNT3_8822B 24
+#define BIT_MASK_DTIM_CNT3_8822B 0xff
+#define BIT_DTIM_CNT3_8822B(x) \
+ (((x) & BIT_MASK_DTIM_CNT3_8822B) << BIT_SHIFT_DTIM_CNT3_8822B)
+#define BIT_GET_DTIM_CNT3_8822B(x) \
+ (((x) >> BIT_SHIFT_DTIM_CNT3_8822B) & BIT_MASK_DTIM_CNT3_8822B)
+
+#define BIT_SHIFT_DTIM_PERIOD3_8822B 16
+#define BIT_MASK_DTIM_PERIOD3_8822B 0xff
+#define BIT_DTIM_PERIOD3_8822B(x) \
+ (((x) & BIT_MASK_DTIM_PERIOD3_8822B) << BIT_SHIFT_DTIM_PERIOD3_8822B)
+#define BIT_GET_DTIM_PERIOD3_8822B(x) \
+ (((x) >> BIT_SHIFT_DTIM_PERIOD3_8822B) & BIT_MASK_DTIM_PERIOD3_8822B)
+
+#define BIT_DTIM3_8822B BIT(15)
+#define BIT_TIM3_8822B BIT(14)
+
+#define BIT_SHIFT_PS_AID_3_8822B 0
+#define BIT_MASK_PS_AID_3_8822B 0x7ff
+#define BIT_PS_AID_3_8822B(x) \
+ (((x) & BIT_MASK_PS_AID_3_8822B) << BIT_SHIFT_PS_AID_3_8822B)
+#define BIT_GET_PS_AID_3_8822B(x) \
+ (((x) >> BIT_SHIFT_PS_AID_3_8822B) & BIT_MASK_PS_AID_3_8822B)
+
+/* 2 REG_BCN_PSR_RPT4_8822B (BEACON PARSER REPORT REGISTER4) */
+
+#define BIT_SHIFT_DTIM_CNT4_8822B 24
+#define BIT_MASK_DTIM_CNT4_8822B 0xff
+#define BIT_DTIM_CNT4_8822B(x) \
+ (((x) & BIT_MASK_DTIM_CNT4_8822B) << BIT_SHIFT_DTIM_CNT4_8822B)
+#define BIT_GET_DTIM_CNT4_8822B(x) \
+ (((x) >> BIT_SHIFT_DTIM_CNT4_8822B) & BIT_MASK_DTIM_CNT4_8822B)
+
+#define BIT_SHIFT_DTIM_PERIOD4_8822B 16
+#define BIT_MASK_DTIM_PERIOD4_8822B 0xff
+#define BIT_DTIM_PERIOD4_8822B(x) \
+ (((x) & BIT_MASK_DTIM_PERIOD4_8822B) << BIT_SHIFT_DTIM_PERIOD4_8822B)
+#define BIT_GET_DTIM_PERIOD4_8822B(x) \
+ (((x) >> BIT_SHIFT_DTIM_PERIOD4_8822B) & BIT_MASK_DTIM_PERIOD4_8822B)
+
+#define BIT_DTIM4_8822B BIT(15)
+#define BIT_TIM4_8822B BIT(14)
+
+#define BIT_SHIFT_PS_AID_4_8822B 0
+#define BIT_MASK_PS_AID_4_8822B 0x7ff
+#define BIT_PS_AID_4_8822B(x) \
+ (((x) & BIT_MASK_PS_AID_4_8822B) << BIT_SHIFT_PS_AID_4_8822B)
+#define BIT_GET_PS_AID_4_8822B(x) \
+ (((x) >> BIT_SHIFT_PS_AID_4_8822B) & BIT_MASK_PS_AID_4_8822B)
+
+/* 2 REG_A1_ADDR_MASK_8822B (A1 ADDR MASK REGISTER) */
+
+#define BIT_SHIFT_A1_ADDR_MASK_8822B 0
+#define BIT_MASK_A1_ADDR_MASK_8822B 0xffffffffL
+#define BIT_A1_ADDR_MASK_8822B(x) \
+ (((x) & BIT_MASK_A1_ADDR_MASK_8822B) << BIT_SHIFT_A1_ADDR_MASK_8822B)
+#define BIT_GET_A1_ADDR_MASK_8822B(x) \
+ (((x) >> BIT_SHIFT_A1_ADDR_MASK_8822B) & BIT_MASK_A1_ADDR_MASK_8822B)
+
+/* 2 REG_MACID2_8822B (MAC ID2 REGISTER) */
+
+#define BIT_SHIFT_MACID2_8822B 0
+#define BIT_MASK_MACID2_8822B 0xffffffffffffL
+#define BIT_MACID2_8822B(x) \
+ (((x) & BIT_MASK_MACID2_8822B) << BIT_SHIFT_MACID2_8822B)
+#define BIT_GET_MACID2_8822B(x) \
+ (((x) >> BIT_SHIFT_MACID2_8822B) & BIT_MASK_MACID2_8822B)
+
+/* 2 REG_BSSID2_8822B (BSSID2 REGISTER) */
+
+#define BIT_SHIFT_BSSID2_8822B 0
+#define BIT_MASK_BSSID2_8822B 0xffffffffffffL
+#define BIT_BSSID2_8822B(x) \
+ (((x) & BIT_MASK_BSSID2_8822B) << BIT_SHIFT_BSSID2_8822B)
+#define BIT_GET_BSSID2_8822B(x) \
+ (((x) >> BIT_SHIFT_BSSID2_8822B) & BIT_MASK_BSSID2_8822B)
+
+/* 2 REG_MACID3_8822B (MAC ID3 REGISTER) */
+
+#define BIT_SHIFT_MACID3_8822B 0
+#define BIT_MASK_MACID3_8822B 0xffffffffffffL
+#define BIT_MACID3_8822B(x) \
+ (((x) & BIT_MASK_MACID3_8822B) << BIT_SHIFT_MACID3_8822B)
+#define BIT_GET_MACID3_8822B(x) \
+ (((x) >> BIT_SHIFT_MACID3_8822B) & BIT_MASK_MACID3_8822B)
+
+/* 2 REG_BSSID3_8822B (BSSID3 REGISTER) */
+
+#define BIT_SHIFT_BSSID3_8822B 0
+#define BIT_MASK_BSSID3_8822B 0xffffffffffffL
+#define BIT_BSSID3_8822B(x) \
+ (((x) & BIT_MASK_BSSID3_8822B) << BIT_SHIFT_BSSID3_8822B)
+#define BIT_GET_BSSID3_8822B(x) \
+ (((x) >> BIT_SHIFT_BSSID3_8822B) & BIT_MASK_BSSID3_8822B)
+
+/* 2 REG_MACID4_8822B (MAC ID4 REGISTER) */
+
+#define BIT_SHIFT_MACID4_8822B 0
+#define BIT_MASK_MACID4_8822B 0xffffffffffffL
+#define BIT_MACID4_8822B(x) \
+ (((x) & BIT_MASK_MACID4_8822B) << BIT_SHIFT_MACID4_8822B)
+#define BIT_GET_MACID4_8822B(x) \
+ (((x) >> BIT_SHIFT_MACID4_8822B) & BIT_MASK_MACID4_8822B)
+
+/* 2 REG_BSSID4_8822B (BSSID4 REGISTER) */
+
+#define BIT_SHIFT_BSSID4_8822B 0
+#define BIT_MASK_BSSID4_8822B 0xffffffffffffL
+#define BIT_BSSID4_8822B(x) \
+ (((x) & BIT_MASK_BSSID4_8822B) << BIT_SHIFT_BSSID4_8822B)
+#define BIT_GET_BSSID4_8822B(x) \
+ (((x) >> BIT_SHIFT_BSSID4_8822B) & BIT_MASK_BSSID4_8822B)
+
+/* 2 REG_NOA_REPORT_8822B */
+
+/* 2 REG_PWRBIT_SETTING_8822B */
+#define BIT_CLI3_PWRBIT_OW_EN_8822B BIT(7)
+#define BIT_CLI3_PWR_ST_8822B BIT(6)
+#define BIT_CLI2_PWRBIT_OW_EN_8822B BIT(5)
+#define BIT_CLI2_PWR_ST_8822B BIT(4)
+#define BIT_CLI1_PWRBIT_OW_EN_8822B BIT(3)
+#define BIT_CLI1_PWR_ST_8822B BIT(2)
+#define BIT_CLI0_PWRBIT_OW_EN_8822B BIT(1)
+#define BIT_CLI0_PWR_ST_8822B BIT(0)
+
+/* 2 REG_WMAC_MU_BF_OPTION_8822B */
+#define BIT_WMAC_RESP_NONSTA1_DIS_8822B BIT(7)
+#define BIT_BIT_WMAC_TXMU_ACKPOLICY_EN_8822B BIT(6)
+
+#define BIT_SHIFT_WMAC_TXMU_ACKPOLICY_8822B 4
+#define BIT_MASK_WMAC_TXMU_ACKPOLICY_8822B 0x3
+#define BIT_WMAC_TXMU_ACKPOLICY_8822B(x) \
+ (((x) & BIT_MASK_WMAC_TXMU_ACKPOLICY_8822B) \
+ << BIT_SHIFT_WMAC_TXMU_ACKPOLICY_8822B)
+#define BIT_GET_WMAC_TXMU_ACKPOLICY_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_TXMU_ACKPOLICY_8822B) & \
+ BIT_MASK_WMAC_TXMU_ACKPOLICY_8822B)
+
+#define BIT_SHIFT_WMAC_MU_BFEE_PORT_SEL_8822B 1
+#define BIT_MASK_WMAC_MU_BFEE_PORT_SEL_8822B 0x7
+#define BIT_WMAC_MU_BFEE_PORT_SEL_8822B(x) \
+ (((x) & BIT_MASK_WMAC_MU_BFEE_PORT_SEL_8822B) \
+ << BIT_SHIFT_WMAC_MU_BFEE_PORT_SEL_8822B)
+#define BIT_GET_WMAC_MU_BFEE_PORT_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_MU_BFEE_PORT_SEL_8822B) & \
+ BIT_MASK_WMAC_MU_BFEE_PORT_SEL_8822B)
+
+#define BIT_WMAC_MU_BFEE_DIS_8822B BIT(0)
+
+/* 2 REG_NOT_VALID_8822B */
+
+#define BIT_SHIFT_WMAC_PAUSE_BB_CLR_TH_8822B 0
+#define BIT_MASK_WMAC_PAUSE_BB_CLR_TH_8822B 0xff
+#define BIT_WMAC_PAUSE_BB_CLR_TH_8822B(x) \
+ (((x) & BIT_MASK_WMAC_PAUSE_BB_CLR_TH_8822B) \
+ << BIT_SHIFT_WMAC_PAUSE_BB_CLR_TH_8822B)
+#define BIT_GET_WMAC_PAUSE_BB_CLR_TH_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_PAUSE_BB_CLR_TH_8822B) & \
+ BIT_MASK_WMAC_PAUSE_BB_CLR_TH_8822B)
+
+/* 2 REG_WMAC_MU_ARB_8822B */
+#define BIT_WMAC_ARB_HW_ADAPT_EN_8822B BIT(7)
+#define BIT_WMAC_ARB_SW_EN_8822B BIT(6)
+
+#define BIT_SHIFT_WMAC_ARB_SW_STATE_8822B 0
+#define BIT_MASK_WMAC_ARB_SW_STATE_8822B 0x3f
+#define BIT_WMAC_ARB_SW_STATE_8822B(x) \
+ (((x) & BIT_MASK_WMAC_ARB_SW_STATE_8822B) \
+ << BIT_SHIFT_WMAC_ARB_SW_STATE_8822B)
+#define BIT_GET_WMAC_ARB_SW_STATE_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_ARB_SW_STATE_8822B) & \
+ BIT_MASK_WMAC_ARB_SW_STATE_8822B)
+
+/* 2 REG_WMAC_MU_OPTION_8822B */
+
+#define BIT_SHIFT_WMAC_MU_DBGSEL_8822B 5
+#define BIT_MASK_WMAC_MU_DBGSEL_8822B 0x3
+#define BIT_WMAC_MU_DBGSEL_8822B(x) \
+ (((x) & BIT_MASK_WMAC_MU_DBGSEL_8822B) \
+ << BIT_SHIFT_WMAC_MU_DBGSEL_8822B)
+#define BIT_GET_WMAC_MU_DBGSEL_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_MU_DBGSEL_8822B) & \
+ BIT_MASK_WMAC_MU_DBGSEL_8822B)
+
+#define BIT_SHIFT_WMAC_MU_CPRD_TIMEOUT_8822B 0
+#define BIT_MASK_WMAC_MU_CPRD_TIMEOUT_8822B 0x1f
+#define BIT_WMAC_MU_CPRD_TIMEOUT_8822B(x) \
+ (((x) & BIT_MASK_WMAC_MU_CPRD_TIMEOUT_8822B) \
+ << BIT_SHIFT_WMAC_MU_CPRD_TIMEOUT_8822B)
+#define BIT_GET_WMAC_MU_CPRD_TIMEOUT_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_MU_CPRD_TIMEOUT_8822B) & \
+ BIT_MASK_WMAC_MU_CPRD_TIMEOUT_8822B)
+
+/* 2 REG_WMAC_MU_BF_CTL_8822B */
+#define BIT_WMAC_INVLD_BFPRT_CHK_8822B BIT(15)
+#define BIT_WMAC_RETXBFRPTSEQ_UPD_8822B BIT(14)
+
+#define BIT_SHIFT_WMAC_MU_BFRPTSEG_SEL_8822B 12
+#define BIT_MASK_WMAC_MU_BFRPTSEG_SEL_8822B 0x3
+#define BIT_WMAC_MU_BFRPTSEG_SEL_8822B(x) \
+ (((x) & BIT_MASK_WMAC_MU_BFRPTSEG_SEL_8822B) \
+ << BIT_SHIFT_WMAC_MU_BFRPTSEG_SEL_8822B)
+#define BIT_GET_WMAC_MU_BFRPTSEG_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_MU_BFRPTSEG_SEL_8822B) & \
+ BIT_MASK_WMAC_MU_BFRPTSEG_SEL_8822B)
+
+#define BIT_SHIFT_WMAC_MU_BF_MYAID_8822B 0
+#define BIT_MASK_WMAC_MU_BF_MYAID_8822B 0xfff
+#define BIT_WMAC_MU_BF_MYAID_8822B(x) \
+ (((x) & BIT_MASK_WMAC_MU_BF_MYAID_8822B) \
+ << BIT_SHIFT_WMAC_MU_BF_MYAID_8822B)
+#define BIT_GET_WMAC_MU_BF_MYAID_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_MU_BF_MYAID_8822B) & \
+ BIT_MASK_WMAC_MU_BF_MYAID_8822B)
+
+/* 2 REG_WMAC_MU_BFRPT_PARA_8822B */
+
+#define BIT_SHIFT_BIT_BFRPT_PARA_USERID_SEL_8822B 12
+#define BIT_MASK_BIT_BFRPT_PARA_USERID_SEL_8822B 0x7
+#define BIT_BIT_BFRPT_PARA_USERID_SEL_8822B(x) \
+ (((x) & BIT_MASK_BIT_BFRPT_PARA_USERID_SEL_8822B) \
+ << BIT_SHIFT_BIT_BFRPT_PARA_USERID_SEL_8822B)
+#define BIT_GET_BIT_BFRPT_PARA_USERID_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_BIT_BFRPT_PARA_USERID_SEL_8822B) & \
+ BIT_MASK_BIT_BFRPT_PARA_USERID_SEL_8822B)
+
+#define BIT_SHIFT_BFRPT_PARA_8822B 0
+#define BIT_MASK_BFRPT_PARA_8822B 0xfff
+#define BIT_BFRPT_PARA_8822B(x) \
+ (((x) & BIT_MASK_BFRPT_PARA_8822B) << BIT_SHIFT_BFRPT_PARA_8822B)
+#define BIT_GET_BFRPT_PARA_8822B(x) \
+ (((x) >> BIT_SHIFT_BFRPT_PARA_8822B) & BIT_MASK_BFRPT_PARA_8822B)
+
+/* 2 REG_WMAC_ASSOCIATED_MU_BFMEE2_8822B */
+#define BIT_STATUS_BFEE2_8822B BIT(10)
+#define BIT_WMAC_MU_BFEE2_EN_8822B BIT(9)
+
+#define BIT_SHIFT_WMAC_MU_BFEE2_AID_8822B 0
+#define BIT_MASK_WMAC_MU_BFEE2_AID_8822B 0x1ff
+#define BIT_WMAC_MU_BFEE2_AID_8822B(x) \
+ (((x) & BIT_MASK_WMAC_MU_BFEE2_AID_8822B) \
+ << BIT_SHIFT_WMAC_MU_BFEE2_AID_8822B)
+#define BIT_GET_WMAC_MU_BFEE2_AID_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_MU_BFEE2_AID_8822B) & \
+ BIT_MASK_WMAC_MU_BFEE2_AID_8822B)
+
+/* 2 REG_WMAC_ASSOCIATED_MU_BFMEE3_8822B */
+#define BIT_STATUS_BFEE3_8822B BIT(10)
+#define BIT_WMAC_MU_BFEE3_EN_8822B BIT(9)
+
+#define BIT_SHIFT_WMAC_MU_BFEE3_AID_8822B 0
+#define BIT_MASK_WMAC_MU_BFEE3_AID_8822B 0x1ff
+#define BIT_WMAC_MU_BFEE3_AID_8822B(x) \
+ (((x) & BIT_MASK_WMAC_MU_BFEE3_AID_8822B) \
+ << BIT_SHIFT_WMAC_MU_BFEE3_AID_8822B)
+#define BIT_GET_WMAC_MU_BFEE3_AID_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_MU_BFEE3_AID_8822B) & \
+ BIT_MASK_WMAC_MU_BFEE3_AID_8822B)
+
+/* 2 REG_WMAC_ASSOCIATED_MU_BFMEE4_8822B */
+#define BIT_STATUS_BFEE4_8822B BIT(10)
+#define BIT_WMAC_MU_BFEE4_EN_8822B BIT(9)
+
+#define BIT_SHIFT_WMAC_MU_BFEE4_AID_8822B 0
+#define BIT_MASK_WMAC_MU_BFEE4_AID_8822B 0x1ff
+#define BIT_WMAC_MU_BFEE4_AID_8822B(x) \
+ (((x) & BIT_MASK_WMAC_MU_BFEE4_AID_8822B) \
+ << BIT_SHIFT_WMAC_MU_BFEE4_AID_8822B)
+#define BIT_GET_WMAC_MU_BFEE4_AID_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_MU_BFEE4_AID_8822B) & \
+ BIT_MASK_WMAC_MU_BFEE4_AID_8822B)
+
+/* 2 REG_WMAC_ASSOCIATED_MU_BFMEE5_8822B */
+#define BIT_STATUS_BFEE5_8822B BIT(10)
+#define BIT_WMAC_MU_BFEE5_EN_8822B BIT(9)
+
+#define BIT_SHIFT_WMAC_MU_BFEE5_AID_8822B 0
+#define BIT_MASK_WMAC_MU_BFEE5_AID_8822B 0x1ff
+#define BIT_WMAC_MU_BFEE5_AID_8822B(x) \
+ (((x) & BIT_MASK_WMAC_MU_BFEE5_AID_8822B) \
+ << BIT_SHIFT_WMAC_MU_BFEE5_AID_8822B)
+#define BIT_GET_WMAC_MU_BFEE5_AID_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_MU_BFEE5_AID_8822B) & \
+ BIT_MASK_WMAC_MU_BFEE5_AID_8822B)
+
+/* 2 REG_WMAC_ASSOCIATED_MU_BFMEE6_8822B */
+#define BIT_STATUS_BFEE6_8822B BIT(10)
+#define BIT_WMAC_MU_BFEE6_EN_8822B BIT(9)
+
+#define BIT_SHIFT_WMAC_MU_BFEE6_AID_8822B 0
+#define BIT_MASK_WMAC_MU_BFEE6_AID_8822B 0x1ff
+#define BIT_WMAC_MU_BFEE6_AID_8822B(x) \
+ (((x) & BIT_MASK_WMAC_MU_BFEE6_AID_8822B) \
+ << BIT_SHIFT_WMAC_MU_BFEE6_AID_8822B)
+#define BIT_GET_WMAC_MU_BFEE6_AID_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_MU_BFEE6_AID_8822B) & \
+ BIT_MASK_WMAC_MU_BFEE6_AID_8822B)
+
+/* 2 REG_WMAC_ASSOCIATED_MU_BFMEE7_8822B */
+#define BIT_BIT_STATUS_BFEE4_8822B BIT(10)
+#define BIT_WMAC_MU_BFEE7_EN_8822B BIT(9)
+
+#define BIT_SHIFT_WMAC_MU_BFEE7_AID_8822B 0
+#define BIT_MASK_WMAC_MU_BFEE7_AID_8822B 0x1ff
+#define BIT_WMAC_MU_BFEE7_AID_8822B(x) \
+ (((x) & BIT_MASK_WMAC_MU_BFEE7_AID_8822B) \
+ << BIT_SHIFT_WMAC_MU_BFEE7_AID_8822B)
+#define BIT_GET_WMAC_MU_BFEE7_AID_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_MU_BFEE7_AID_8822B) & \
+ BIT_MASK_WMAC_MU_BFEE7_AID_8822B)
+
+/* 2 REG_NOT_VALID_8822B */
+#define BIT_RST_ALL_COUNTER_8822B BIT(31)
+
+#define BIT_SHIFT_ABORT_RX_VBON_COUNTER_8822B 16
+#define BIT_MASK_ABORT_RX_VBON_COUNTER_8822B 0xff
+#define BIT_ABORT_RX_VBON_COUNTER_8822B(x) \
+ (((x) & BIT_MASK_ABORT_RX_VBON_COUNTER_8822B) \
+ << BIT_SHIFT_ABORT_RX_VBON_COUNTER_8822B)
+#define BIT_GET_ABORT_RX_VBON_COUNTER_8822B(x) \
+ (((x) >> BIT_SHIFT_ABORT_RX_VBON_COUNTER_8822B) & \
+ BIT_MASK_ABORT_RX_VBON_COUNTER_8822B)
+
+#define BIT_SHIFT_ABORT_RX_RDRDY_COUNTER_8822B 8
+#define BIT_MASK_ABORT_RX_RDRDY_COUNTER_8822B 0xff
+#define BIT_ABORT_RX_RDRDY_COUNTER_8822B(x) \
+ (((x) & BIT_MASK_ABORT_RX_RDRDY_COUNTER_8822B) \
+ << BIT_SHIFT_ABORT_RX_RDRDY_COUNTER_8822B)
+#define BIT_GET_ABORT_RX_RDRDY_COUNTER_8822B(x) \
+ (((x) >> BIT_SHIFT_ABORT_RX_RDRDY_COUNTER_8822B) & \
+ BIT_MASK_ABORT_RX_RDRDY_COUNTER_8822B)
+
+#define BIT_SHIFT_VBON_EARLY_FALLING_COUNTER_8822B 0
+#define BIT_MASK_VBON_EARLY_FALLING_COUNTER_8822B 0xff
+#define BIT_VBON_EARLY_FALLING_COUNTER_8822B(x) \
+ (((x) & BIT_MASK_VBON_EARLY_FALLING_COUNTER_8822B) \
+ << BIT_SHIFT_VBON_EARLY_FALLING_COUNTER_8822B)
+#define BIT_GET_VBON_EARLY_FALLING_COUNTER_8822B(x) \
+ (((x) >> BIT_SHIFT_VBON_EARLY_FALLING_COUNTER_8822B) & \
+ BIT_MASK_VBON_EARLY_FALLING_COUNTER_8822B)
+
+/* 2 REG_NOT_VALID_8822B */
+#define BIT_WMAC_PLCP_TRX_SEL_8822B BIT(31)
+
+#define BIT_SHIFT_WMAC_PLCP_RDSIG_SEL_8822B 28
+#define BIT_MASK_WMAC_PLCP_RDSIG_SEL_8822B 0x7
+#define BIT_WMAC_PLCP_RDSIG_SEL_8822B(x) \
+ (((x) & BIT_MASK_WMAC_PLCP_RDSIG_SEL_8822B) \
+ << BIT_SHIFT_WMAC_PLCP_RDSIG_SEL_8822B)
+#define BIT_GET_WMAC_PLCP_RDSIG_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_PLCP_RDSIG_SEL_8822B) & \
+ BIT_MASK_WMAC_PLCP_RDSIG_SEL_8822B)
+
+#define BIT_SHIFT_WMAC_RATE_IDX_8822B 24
+#define BIT_MASK_WMAC_RATE_IDX_8822B 0xf
+#define BIT_WMAC_RATE_IDX_8822B(x) \
+ (((x) & BIT_MASK_WMAC_RATE_IDX_8822B) << BIT_SHIFT_WMAC_RATE_IDX_8822B)
+#define BIT_GET_WMAC_RATE_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_RATE_IDX_8822B) & BIT_MASK_WMAC_RATE_IDX_8822B)
+
+#define BIT_SHIFT_WMAC_PLCP_RDSIG_8822B 0
+#define BIT_MASK_WMAC_PLCP_RDSIG_8822B 0xffffff
+#define BIT_WMAC_PLCP_RDSIG_8822B(x) \
+ (((x) & BIT_MASK_WMAC_PLCP_RDSIG_8822B) \
+ << BIT_SHIFT_WMAC_PLCP_RDSIG_8822B)
+#define BIT_GET_WMAC_PLCP_RDSIG_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_PLCP_RDSIG_8822B) & \
+ BIT_MASK_WMAC_PLCP_RDSIG_8822B)
+
+/* 2 REG_NOT_VALID_8822B */
+#define BIT_WMAC_MUTX_IDX_8822B BIT(24)
+
+#define BIT_SHIFT_WMAC_PLCP_RDSIG_8822B 0
+#define BIT_MASK_WMAC_PLCP_RDSIG_8822B 0xffffff
+#define BIT_WMAC_PLCP_RDSIG_8822B(x) \
+ (((x) & BIT_MASK_WMAC_PLCP_RDSIG_8822B) \
+ << BIT_SHIFT_WMAC_PLCP_RDSIG_8822B)
+#define BIT_GET_WMAC_PLCP_RDSIG_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_PLCP_RDSIG_8822B) & \
+ BIT_MASK_WMAC_PLCP_RDSIG_8822B)
+
+/* 2 REG_TRANSMIT_ADDRSS_0_8822B (TA0 REGISTER) */
+
+#define BIT_SHIFT_TA0_8822B 0
+#define BIT_MASK_TA0_8822B 0xffffffffffffL
+#define BIT_TA0_8822B(x) (((x) & BIT_MASK_TA0_8822B) << BIT_SHIFT_TA0_8822B)
+#define BIT_GET_TA0_8822B(x) (((x) >> BIT_SHIFT_TA0_8822B) & BIT_MASK_TA0_8822B)
+
+/* 2 REG_TRANSMIT_ADDRSS_1_8822B (TA1 REGISTER) */
+
+#define BIT_SHIFT_TA1_8822B 0
+#define BIT_MASK_TA1_8822B 0xffffffffffffL
+#define BIT_TA1_8822B(x) (((x) & BIT_MASK_TA1_8822B) << BIT_SHIFT_TA1_8822B)
+#define BIT_GET_TA1_8822B(x) (((x) >> BIT_SHIFT_TA1_8822B) & BIT_MASK_TA1_8822B)
+
+/* 2 REG_TRANSMIT_ADDRSS_2_8822B (TA2 REGISTER) */
+
+#define BIT_SHIFT_TA2_8822B 0
+#define BIT_MASK_TA2_8822B 0xffffffffffffL
+#define BIT_TA2_8822B(x) (((x) & BIT_MASK_TA2_8822B) << BIT_SHIFT_TA2_8822B)
+#define BIT_GET_TA2_8822B(x) (((x) >> BIT_SHIFT_TA2_8822B) & BIT_MASK_TA2_8822B)
+
+/* 2 REG_TRANSMIT_ADDRSS_3_8822B (TA3 REGISTER) */
+
+#define BIT_SHIFT_TA3_8822B 0
+#define BIT_MASK_TA3_8822B 0xffffffffffffL
+#define BIT_TA3_8822B(x) (((x) & BIT_MASK_TA3_8822B) << BIT_SHIFT_TA3_8822B)
+#define BIT_GET_TA3_8822B(x) (((x) >> BIT_SHIFT_TA3_8822B) & BIT_MASK_TA3_8822B)
+
+/* 2 REG_TRANSMIT_ADDRSS_4_8822B (TA4 REGISTER) */
+
+#define BIT_SHIFT_TA4_8822B 0
+#define BIT_MASK_TA4_8822B 0xffffffffffffL
+#define BIT_TA4_8822B(x) (((x) & BIT_MASK_TA4_8822B) << BIT_SHIFT_TA4_8822B)
+#define BIT_GET_TA4_8822B(x) (((x) >> BIT_SHIFT_TA4_8822B) & BIT_MASK_TA4_8822B)
+
+/* 2 REG_NOT_VALID_8822B */
+
+/* 2 REG_MACID1_8822B */
+
+#define BIT_SHIFT_MACID1_8822B 0
+#define BIT_MASK_MACID1_8822B 0xffffffffffffL
+#define BIT_MACID1_8822B(x) \
+ (((x) & BIT_MASK_MACID1_8822B) << BIT_SHIFT_MACID1_8822B)
+#define BIT_GET_MACID1_8822B(x) \
+ (((x) >> BIT_SHIFT_MACID1_8822B) & BIT_MASK_MACID1_8822B)
+
+/* 2 REG_BSSID1_8822B */
+
+#define BIT_SHIFT_BSSID1_8822B 0
+#define BIT_MASK_BSSID1_8822B 0xffffffffffffL
+#define BIT_BSSID1_8822B(x) \
+ (((x) & BIT_MASK_BSSID1_8822B) << BIT_SHIFT_BSSID1_8822B)
+#define BIT_GET_BSSID1_8822B(x) \
+ (((x) >> BIT_SHIFT_BSSID1_8822B) & BIT_MASK_BSSID1_8822B)
+
+/* 2 REG_BCN_PSR_RPT1_8822B */
+
+#define BIT_SHIFT_DTIM_CNT1_8822B 24
+#define BIT_MASK_DTIM_CNT1_8822B 0xff
+#define BIT_DTIM_CNT1_8822B(x) \
+ (((x) & BIT_MASK_DTIM_CNT1_8822B) << BIT_SHIFT_DTIM_CNT1_8822B)
+#define BIT_GET_DTIM_CNT1_8822B(x) \
+ (((x) >> BIT_SHIFT_DTIM_CNT1_8822B) & BIT_MASK_DTIM_CNT1_8822B)
+
+#define BIT_SHIFT_DTIM_PERIOD1_8822B 16
+#define BIT_MASK_DTIM_PERIOD1_8822B 0xff
+#define BIT_DTIM_PERIOD1_8822B(x) \
+ (((x) & BIT_MASK_DTIM_PERIOD1_8822B) << BIT_SHIFT_DTIM_PERIOD1_8822B)
+#define BIT_GET_DTIM_PERIOD1_8822B(x) \
+ (((x) >> BIT_SHIFT_DTIM_PERIOD1_8822B) & BIT_MASK_DTIM_PERIOD1_8822B)
+
+#define BIT_DTIM1_8822B BIT(15)
+#define BIT_TIM1_8822B BIT(14)
+
+#define BIT_SHIFT_PS_AID_1_8822B 0
+#define BIT_MASK_PS_AID_1_8822B 0x7ff
+#define BIT_PS_AID_1_8822B(x) \
+ (((x) & BIT_MASK_PS_AID_1_8822B) << BIT_SHIFT_PS_AID_1_8822B)
+#define BIT_GET_PS_AID_1_8822B(x) \
+ (((x) >> BIT_SHIFT_PS_AID_1_8822B) & BIT_MASK_PS_AID_1_8822B)
+
+/* 2 REG_ASSOCIATED_BFMEE_SEL_8822B */
+#define BIT_TXUSER_ID1_8822B BIT(25)
+
+#define BIT_SHIFT_AID1_8822B 16
+#define BIT_MASK_AID1_8822B 0x1ff
+#define BIT_AID1_8822B(x) (((x) & BIT_MASK_AID1_8822B) << BIT_SHIFT_AID1_8822B)
+#define BIT_GET_AID1_8822B(x) \
+ (((x) >> BIT_SHIFT_AID1_8822B) & BIT_MASK_AID1_8822B)
+
+#define BIT_TXUSER_ID0_8822B BIT(9)
+
+#define BIT_SHIFT_AID0_8822B 0
+#define BIT_MASK_AID0_8822B 0x1ff
+#define BIT_AID0_8822B(x) (((x) & BIT_MASK_AID0_8822B) << BIT_SHIFT_AID0_8822B)
+#define BIT_GET_AID0_8822B(x) \
+ (((x) >> BIT_SHIFT_AID0_8822B) & BIT_MASK_AID0_8822B)
+
+/* 2 REG_SND_PTCL_CTRL_8822B */
+
+#define BIT_SHIFT_NDP_RX_STANDBY_TIMER_8822B 24
+#define BIT_MASK_NDP_RX_STANDBY_TIMER_8822B 0xff
+#define BIT_NDP_RX_STANDBY_TIMER_8822B(x) \
+ (((x) & BIT_MASK_NDP_RX_STANDBY_TIMER_8822B) \
+ << BIT_SHIFT_NDP_RX_STANDBY_TIMER_8822B)
+#define BIT_GET_NDP_RX_STANDBY_TIMER_8822B(x) \
+ (((x) >> BIT_SHIFT_NDP_RX_STANDBY_TIMER_8822B) & \
+ BIT_MASK_NDP_RX_STANDBY_TIMER_8822B)
+
+#define BIT_SHIFT_CSI_RPT_OFFSET_HT_8822B 16
+#define BIT_MASK_CSI_RPT_OFFSET_HT_8822B 0xff
+#define BIT_CSI_RPT_OFFSET_HT_8822B(x) \
+ (((x) & BIT_MASK_CSI_RPT_OFFSET_HT_8822B) \
+ << BIT_SHIFT_CSI_RPT_OFFSET_HT_8822B)
+#define BIT_GET_CSI_RPT_OFFSET_HT_8822B(x) \
+ (((x) >> BIT_SHIFT_CSI_RPT_OFFSET_HT_8822B) & \
+ BIT_MASK_CSI_RPT_OFFSET_HT_8822B)
+
+#define BIT_SHIFT_R_WMAC_VHT_CATEGORY_8822B 8
+#define BIT_MASK_R_WMAC_VHT_CATEGORY_8822B 0xff
+#define BIT_R_WMAC_VHT_CATEGORY_8822B(x) \
+ (((x) & BIT_MASK_R_WMAC_VHT_CATEGORY_8822B) \
+ << BIT_SHIFT_R_WMAC_VHT_CATEGORY_8822B)
+#define BIT_GET_R_WMAC_VHT_CATEGORY_8822B(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_VHT_CATEGORY_8822B) & \
+ BIT_MASK_R_WMAC_VHT_CATEGORY_8822B)
+
+#define BIT_R_WMAC_USE_NSTS_8822B BIT(7)
+#define BIT_R_DISABLE_CHECK_VHTSIGB_CRC_8822B BIT(6)
+#define BIT_R_DISABLE_CHECK_VHTSIGA_CRC_8822B BIT(5)
+#define BIT_R_WMAC_BFPARAM_SEL_8822B BIT(4)
+#define BIT_R_WMAC_CSISEQ_SEL_8822B BIT(3)
+#define BIT_R_WMAC_CSI_WITHHTC_EN_8822B BIT(2)
+#define BIT_R_WMAC_HT_NDPA_EN_8822B BIT(1)
+#define BIT_R_WMAC_VHT_NDPA_EN_8822B BIT(0)
+
+/* 2 REG_RX_CSI_RPT_INFO_8822B */
+
+/* 2 REG_NS_ARP_CTRL_8822B */
+#define BIT_R_WMAC_NSARP_RSPEN_8822B BIT(15)
+#define BIT_R_WMAC_NSARP_RARP_8822B BIT(9)
+#define BIT_R_WMAC_NSARP_RIPV6_8822B BIT(8)
+
+#define BIT_SHIFT_R_WMAC_NSARP_MODEN_8822B 6
+#define BIT_MASK_R_WMAC_NSARP_MODEN_8822B 0x3
+#define BIT_R_WMAC_NSARP_MODEN_8822B(x) \
+ (((x) & BIT_MASK_R_WMAC_NSARP_MODEN_8822B) \
+ << BIT_SHIFT_R_WMAC_NSARP_MODEN_8822B)
+#define BIT_GET_R_WMAC_NSARP_MODEN_8822B(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_NSARP_MODEN_8822B) & \
+ BIT_MASK_R_WMAC_NSARP_MODEN_8822B)
+
+#define BIT_SHIFT_R_WMAC_NSARP_RSPFTP_8822B 4
+#define BIT_MASK_R_WMAC_NSARP_RSPFTP_8822B 0x3
+#define BIT_R_WMAC_NSARP_RSPFTP_8822B(x) \
+ (((x) & BIT_MASK_R_WMAC_NSARP_RSPFTP_8822B) \
+ << BIT_SHIFT_R_WMAC_NSARP_RSPFTP_8822B)
+#define BIT_GET_R_WMAC_NSARP_RSPFTP_8822B(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_NSARP_RSPFTP_8822B) & \
+ BIT_MASK_R_WMAC_NSARP_RSPFTP_8822B)
+
+#define BIT_SHIFT_R_WMAC_NSARP_RSPSEC_8822B 0
+#define BIT_MASK_R_WMAC_NSARP_RSPSEC_8822B 0xf
+#define BIT_R_WMAC_NSARP_RSPSEC_8822B(x) \
+ (((x) & BIT_MASK_R_WMAC_NSARP_RSPSEC_8822B) \
+ << BIT_SHIFT_R_WMAC_NSARP_RSPSEC_8822B)
+#define BIT_GET_R_WMAC_NSARP_RSPSEC_8822B(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_NSARP_RSPSEC_8822B) & \
+ BIT_MASK_R_WMAC_NSARP_RSPSEC_8822B)
+
+/* 2 REG_NS_ARP_INFO_8822B */
+#define BIT_REQ_IS_MCNS_8822B BIT(23)
+#define BIT_REQ_IS_UCNS_8822B BIT(22)
+#define BIT_REQ_IS_USNS_8822B BIT(21)
+#define BIT_REQ_IS_ARP_8822B BIT(20)
+#define BIT_EXPRSP_MH_WITHQC_8822B BIT(19)
+
+#define BIT_SHIFT_EXPRSP_SECTYPE_8822B 16
+#define BIT_MASK_EXPRSP_SECTYPE_8822B 0x7
+#define BIT_EXPRSP_SECTYPE_8822B(x) \
+ (((x) & BIT_MASK_EXPRSP_SECTYPE_8822B) \
+ << BIT_SHIFT_EXPRSP_SECTYPE_8822B)
+#define BIT_GET_EXPRSP_SECTYPE_8822B(x) \
+ (((x) >> BIT_SHIFT_EXPRSP_SECTYPE_8822B) & \
+ BIT_MASK_EXPRSP_SECTYPE_8822B)
+
+#define BIT_SHIFT_EXPRSP_CHKSM_7_TO_0_8822B 8
+#define BIT_MASK_EXPRSP_CHKSM_7_TO_0_8822B 0xff
+#define BIT_EXPRSP_CHKSM_7_TO_0_8822B(x) \
+ (((x) & BIT_MASK_EXPRSP_CHKSM_7_TO_0_8822B) \
+ << BIT_SHIFT_EXPRSP_CHKSM_7_TO_0_8822B)
+#define BIT_GET_EXPRSP_CHKSM_7_TO_0_8822B(x) \
+ (((x) >> BIT_SHIFT_EXPRSP_CHKSM_7_TO_0_8822B) & \
+ BIT_MASK_EXPRSP_CHKSM_7_TO_0_8822B)
+
+#define BIT_SHIFT_EXPRSP_CHKSM_15_TO_8_8822B 0
+#define BIT_MASK_EXPRSP_CHKSM_15_TO_8_8822B 0xff
+#define BIT_EXPRSP_CHKSM_15_TO_8_8822B(x) \
+ (((x) & BIT_MASK_EXPRSP_CHKSM_15_TO_8_8822B) \
+ << BIT_SHIFT_EXPRSP_CHKSM_15_TO_8_8822B)
+#define BIT_GET_EXPRSP_CHKSM_15_TO_8_8822B(x) \
+ (((x) >> BIT_SHIFT_EXPRSP_CHKSM_15_TO_8_8822B) & \
+ BIT_MASK_EXPRSP_CHKSM_15_TO_8_8822B)
+
+/* 2 REG_BEAMFORMING_INFO_NSARP_V1_8822B */
+
+#define BIT_SHIFT_WMAC_ARPIP_8822B 0
+#define BIT_MASK_WMAC_ARPIP_8822B 0xffffffffL
+#define BIT_WMAC_ARPIP_8822B(x) \
+ (((x) & BIT_MASK_WMAC_ARPIP_8822B) << BIT_SHIFT_WMAC_ARPIP_8822B)
+#define BIT_GET_WMAC_ARPIP_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_ARPIP_8822B) & BIT_MASK_WMAC_ARPIP_8822B)
+
+/* 2 REG_BEAMFORMING_INFO_NSARP_8822B */
+
+#define BIT_SHIFT_BEAMFORMING_INFO_8822B 0
+#define BIT_MASK_BEAMFORMING_INFO_8822B 0xffffffffL
+#define BIT_BEAMFORMING_INFO_8822B(x) \
+ (((x) & BIT_MASK_BEAMFORMING_INFO_8822B) \
+ << BIT_SHIFT_BEAMFORMING_INFO_8822B)
+#define BIT_GET_BEAMFORMING_INFO_8822B(x) \
+ (((x) >> BIT_SHIFT_BEAMFORMING_INFO_8822B) & \
+ BIT_MASK_BEAMFORMING_INFO_8822B)
+
+/* 2 REG_NOT_VALID_8822B */
+
+#define BIT_SHIFT_R_WMAC_IPV6_MYIPAD_8822B 0
+#define BIT_MASK_R_WMAC_IPV6_MYIPAD_8822B 0xffffffffffffffffffffffffffffffffL
+#define BIT_R_WMAC_IPV6_MYIPAD_8822B(x) \
+ (((x) & BIT_MASK_R_WMAC_IPV6_MYIPAD_8822B) \
+ << BIT_SHIFT_R_WMAC_IPV6_MYIPAD_8822B)
+#define BIT_GET_R_WMAC_IPV6_MYIPAD_8822B(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_IPV6_MYIPAD_8822B) & \
+ BIT_MASK_R_WMAC_IPV6_MYIPAD_8822B)
+
+/* 2 REG_RSVD_0X740_8822B */
+
+/* 2 REG_WMAC_RTX_CTX_SUBTYPE_CFG_8822B */
+
+#define BIT_SHIFT_R_WMAC_CTX_SUBTYPE_8822B 4
+#define BIT_MASK_R_WMAC_CTX_SUBTYPE_8822B 0xf
+#define BIT_R_WMAC_CTX_SUBTYPE_8822B(x) \
+ (((x) & BIT_MASK_R_WMAC_CTX_SUBTYPE_8822B) \
+ << BIT_SHIFT_R_WMAC_CTX_SUBTYPE_8822B)
+#define BIT_GET_R_WMAC_CTX_SUBTYPE_8822B(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_CTX_SUBTYPE_8822B) & \
+ BIT_MASK_R_WMAC_CTX_SUBTYPE_8822B)
+
+#define BIT_SHIFT_R_WMAC_RTX_SUBTYPE_8822B 0
+#define BIT_MASK_R_WMAC_RTX_SUBTYPE_8822B 0xf
+#define BIT_R_WMAC_RTX_SUBTYPE_8822B(x) \
+ (((x) & BIT_MASK_R_WMAC_RTX_SUBTYPE_8822B) \
+ << BIT_SHIFT_R_WMAC_RTX_SUBTYPE_8822B)
+#define BIT_GET_R_WMAC_RTX_SUBTYPE_8822B(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_RTX_SUBTYPE_8822B) & \
+ BIT_MASK_R_WMAC_RTX_SUBTYPE_8822B)
+
+/* 2 REG_WMAC_SWAES_CFG_8822B */
+
+/* 2 REG_BT_COEX_V2_8822B */
+#define BIT_GNT_BT_POLARITY_8822B BIT(12)
+#define BIT_GNT_BT_BYPASS_PRIORITY_8822B BIT(8)
+
+#define BIT_SHIFT_TIMER_8822B 0
+#define BIT_MASK_TIMER_8822B 0xff
+#define BIT_TIMER_8822B(x) \
+ (((x) & BIT_MASK_TIMER_8822B) << BIT_SHIFT_TIMER_8822B)
+#define BIT_GET_TIMER_8822B(x) \
+ (((x) >> BIT_SHIFT_TIMER_8822B) & BIT_MASK_TIMER_8822B)
+
+/* 2 REG_BT_COEX_8822B */
+#define BIT_R_GNT_BT_RFC_SW_8822B BIT(12)
+#define BIT_R_GNT_BT_RFC_SW_EN_8822B BIT(11)
+#define BIT_R_GNT_BT_BB_SW_8822B BIT(10)
+#define BIT_R_GNT_BT_BB_SW_EN_8822B BIT(9)
+#define BIT_R_BT_CNT_THREN_8822B BIT(8)
+
+#define BIT_SHIFT_R_BT_CNT_THR_8822B 0
+#define BIT_MASK_R_BT_CNT_THR_8822B 0xff
+#define BIT_R_BT_CNT_THR_8822B(x) \
+ (((x) & BIT_MASK_R_BT_CNT_THR_8822B) << BIT_SHIFT_R_BT_CNT_THR_8822B)
+#define BIT_GET_R_BT_CNT_THR_8822B(x) \
+ (((x) >> BIT_SHIFT_R_BT_CNT_THR_8822B) & BIT_MASK_R_BT_CNT_THR_8822B)
+
+/* 2 REG_WLAN_ACT_MASK_CTRL_8822B */
+#define BIT_WLRX_TER_BY_CTL_8822B BIT(43)
+#define BIT_WLRX_TER_BY_AD_8822B BIT(42)
+#define BIT_ANT_DIVERSITY_SEL_8822B BIT(41)
+#define BIT_ANTSEL_FOR_BT_CTRL_EN_8822B BIT(40)
+#define BIT_WLACT_LOW_GNTWL_EN_8822B BIT(34)
+#define BIT_WLACT_HIGH_GNTBT_EN_8822B BIT(33)
+#define BIT_NAV_UPPER_V1_8822B BIT(32)
+
+#define BIT_SHIFT_RXMYRTS_NAV_V1_8822B 8
+#define BIT_MASK_RXMYRTS_NAV_V1_8822B 0xff
+#define BIT_RXMYRTS_NAV_V1_8822B(x) \
+ (((x) & BIT_MASK_RXMYRTS_NAV_V1_8822B) \
+ << BIT_SHIFT_RXMYRTS_NAV_V1_8822B)
+#define BIT_GET_RXMYRTS_NAV_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_RXMYRTS_NAV_V1_8822B) & \
+ BIT_MASK_RXMYRTS_NAV_V1_8822B)
+
+#define BIT_SHIFT_RTSRST_V1_8822B 0
+#define BIT_MASK_RTSRST_V1_8822B 0xff
+#define BIT_RTSRST_V1_8822B(x) \
+ (((x) & BIT_MASK_RTSRST_V1_8822B) << BIT_SHIFT_RTSRST_V1_8822B)
+#define BIT_GET_RTSRST_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_RTSRST_V1_8822B) & BIT_MASK_RTSRST_V1_8822B)
+
+/* 2 REG_BT_COEX_ENHANCED_INTR_CTRL_8822B */
+
+#define BIT_SHIFT_BT_STAT_DELAY_8822B 12
+#define BIT_MASK_BT_STAT_DELAY_8822B 0xf
+#define BIT_BT_STAT_DELAY_8822B(x) \
+ (((x) & BIT_MASK_BT_STAT_DELAY_8822B) << BIT_SHIFT_BT_STAT_DELAY_8822B)
+#define BIT_GET_BT_STAT_DELAY_8822B(x) \
+ (((x) >> BIT_SHIFT_BT_STAT_DELAY_8822B) & BIT_MASK_BT_STAT_DELAY_8822B)
+
+#define BIT_SHIFT_BT_TRX_INIT_DETECT_8822B 8
+#define BIT_MASK_BT_TRX_INIT_DETECT_8822B 0xf
+#define BIT_BT_TRX_INIT_DETECT_8822B(x) \
+ (((x) & BIT_MASK_BT_TRX_INIT_DETECT_8822B) \
+ << BIT_SHIFT_BT_TRX_INIT_DETECT_8822B)
+#define BIT_GET_BT_TRX_INIT_DETECT_8822B(x) \
+ (((x) >> BIT_SHIFT_BT_TRX_INIT_DETECT_8822B) & \
+ BIT_MASK_BT_TRX_INIT_DETECT_8822B)
+
+#define BIT_SHIFT_BT_PRI_DETECT_TO_8822B 4
+#define BIT_MASK_BT_PRI_DETECT_TO_8822B 0xf
+#define BIT_BT_PRI_DETECT_TO_8822B(x) \
+ (((x) & BIT_MASK_BT_PRI_DETECT_TO_8822B) \
+ << BIT_SHIFT_BT_PRI_DETECT_TO_8822B)
+#define BIT_GET_BT_PRI_DETECT_TO_8822B(x) \
+ (((x) >> BIT_SHIFT_BT_PRI_DETECT_TO_8822B) & \
+ BIT_MASK_BT_PRI_DETECT_TO_8822B)
+
+#define BIT_R_GRANTALL_WLMASK_8822B BIT(3)
+#define BIT_STATIS_BT_EN_8822B BIT(2)
+#define BIT_WL_ACT_MASK_ENABLE_8822B BIT(1)
+#define BIT_ENHANCED_BT_8822B BIT(0)
+
+/* 2 REG_BT_ACT_STATISTICS_8822B */
+
+#define BIT_SHIFT_STATIS_BT_LO_RX_8822B (48 & CPU_OPT_WIDTH)
+#define BIT_MASK_STATIS_BT_LO_RX_8822B 0xffff
+#define BIT_STATIS_BT_LO_RX_8822B(x) \
+ (((x) & BIT_MASK_STATIS_BT_LO_RX_8822B) \
+ << BIT_SHIFT_STATIS_BT_LO_RX_8822B)
+#define BIT_GET_STATIS_BT_LO_RX_8822B(x) \
+ (((x) >> BIT_SHIFT_STATIS_BT_LO_RX_8822B) & \
+ BIT_MASK_STATIS_BT_LO_RX_8822B)
+
+#define BIT_SHIFT_STATIS_BT_LO_TX_8822B (32 & CPU_OPT_WIDTH)
+#define BIT_MASK_STATIS_BT_LO_TX_8822B 0xffff
+#define BIT_STATIS_BT_LO_TX_8822B(x) \
+ (((x) & BIT_MASK_STATIS_BT_LO_TX_8822B) \
+ << BIT_SHIFT_STATIS_BT_LO_TX_8822B)
+#define BIT_GET_STATIS_BT_LO_TX_8822B(x) \
+ (((x) >> BIT_SHIFT_STATIS_BT_LO_TX_8822B) & \
+ BIT_MASK_STATIS_BT_LO_TX_8822B)
+
+#define BIT_SHIFT_STATIS_BT_HI_RX_8822B 16
+#define BIT_MASK_STATIS_BT_HI_RX_8822B 0xffff
+#define BIT_STATIS_BT_HI_RX_8822B(x) \
+ (((x) & BIT_MASK_STATIS_BT_HI_RX_8822B) \
+ << BIT_SHIFT_STATIS_BT_HI_RX_8822B)
+#define BIT_GET_STATIS_BT_HI_RX_8822B(x) \
+ (((x) >> BIT_SHIFT_STATIS_BT_HI_RX_8822B) & \
+ BIT_MASK_STATIS_BT_HI_RX_8822B)
+
+#define BIT_SHIFT_STATIS_BT_HI_TX_8822B 0
+#define BIT_MASK_STATIS_BT_HI_TX_8822B 0xffff
+#define BIT_STATIS_BT_HI_TX_8822B(x) \
+ (((x) & BIT_MASK_STATIS_BT_HI_TX_8822B) \
+ << BIT_SHIFT_STATIS_BT_HI_TX_8822B)
+#define BIT_GET_STATIS_BT_HI_TX_8822B(x) \
+ (((x) >> BIT_SHIFT_STATIS_BT_HI_TX_8822B) & \
+ BIT_MASK_STATIS_BT_HI_TX_8822B)
+
+/* 2 REG_BT_STATISTICS_CONTROL_REGISTER_8822B */
+
+#define BIT_SHIFT_R_BT_CMD_RPT_8822B 16
+#define BIT_MASK_R_BT_CMD_RPT_8822B 0xffff
+#define BIT_R_BT_CMD_RPT_8822B(x) \
+ (((x) & BIT_MASK_R_BT_CMD_RPT_8822B) << BIT_SHIFT_R_BT_CMD_RPT_8822B)
+#define BIT_GET_R_BT_CMD_RPT_8822B(x) \
+ (((x) >> BIT_SHIFT_R_BT_CMD_RPT_8822B) & BIT_MASK_R_BT_CMD_RPT_8822B)
+
+#define BIT_SHIFT_R_RPT_FROM_BT_8822B 8
+#define BIT_MASK_R_RPT_FROM_BT_8822B 0xff
+#define BIT_R_RPT_FROM_BT_8822B(x) \
+ (((x) & BIT_MASK_R_RPT_FROM_BT_8822B) << BIT_SHIFT_R_RPT_FROM_BT_8822B)
+#define BIT_GET_R_RPT_FROM_BT_8822B(x) \
+ (((x) >> BIT_SHIFT_R_RPT_FROM_BT_8822B) & BIT_MASK_R_RPT_FROM_BT_8822B)
+
+#define BIT_SHIFT_BT_HID_ISR_SET_8822B 6
+#define BIT_MASK_BT_HID_ISR_SET_8822B 0x3
+#define BIT_BT_HID_ISR_SET_8822B(x) \
+ (((x) & BIT_MASK_BT_HID_ISR_SET_8822B) \
+ << BIT_SHIFT_BT_HID_ISR_SET_8822B)
+#define BIT_GET_BT_HID_ISR_SET_8822B(x) \
+ (((x) >> BIT_SHIFT_BT_HID_ISR_SET_8822B) & \
+ BIT_MASK_BT_HID_ISR_SET_8822B)
+
+#define BIT_TDMA_BT_START_NOTIFY_8822B BIT(5)
+#define BIT_ENABLE_TDMA_FW_MODE_8822B BIT(4)
+#define BIT_ENABLE_PTA_TDMA_MODE_8822B BIT(3)
+#define BIT_ENABLE_COEXIST_TAB_IN_TDMA_8822B BIT(2)
+#define BIT_GPIO2_GPIO3_EXANGE_OR_NO_BT_CCA_8822B BIT(1)
+#define BIT_RTK_BT_ENABLE_8822B BIT(0)
+
+/* 2 REG_BT_STATUS_REPORT_REGISTER_8822B */
+
+#define BIT_SHIFT_BT_PROFILE_8822B 24
+#define BIT_MASK_BT_PROFILE_8822B 0xff
+#define BIT_BT_PROFILE_8822B(x) \
+ (((x) & BIT_MASK_BT_PROFILE_8822B) << BIT_SHIFT_BT_PROFILE_8822B)
+#define BIT_GET_BT_PROFILE_8822B(x) \
+ (((x) >> BIT_SHIFT_BT_PROFILE_8822B) & BIT_MASK_BT_PROFILE_8822B)
+
+#define BIT_SHIFT_BT_POWER_8822B 16
+#define BIT_MASK_BT_POWER_8822B 0xff
+#define BIT_BT_POWER_8822B(x) \
+ (((x) & BIT_MASK_BT_POWER_8822B) << BIT_SHIFT_BT_POWER_8822B)
+#define BIT_GET_BT_POWER_8822B(x) \
+ (((x) >> BIT_SHIFT_BT_POWER_8822B) & BIT_MASK_BT_POWER_8822B)
+
+#define BIT_SHIFT_BT_PREDECT_STATUS_8822B 8
+#define BIT_MASK_BT_PREDECT_STATUS_8822B 0xff
+#define BIT_BT_PREDECT_STATUS_8822B(x) \
+ (((x) & BIT_MASK_BT_PREDECT_STATUS_8822B) \
+ << BIT_SHIFT_BT_PREDECT_STATUS_8822B)
+#define BIT_GET_BT_PREDECT_STATUS_8822B(x) \
+ (((x) >> BIT_SHIFT_BT_PREDECT_STATUS_8822B) & \
+ BIT_MASK_BT_PREDECT_STATUS_8822B)
+
+#define BIT_SHIFT_BT_CMD_INFO_8822B 0
+#define BIT_MASK_BT_CMD_INFO_8822B 0xff
+#define BIT_BT_CMD_INFO_8822B(x) \
+ (((x) & BIT_MASK_BT_CMD_INFO_8822B) << BIT_SHIFT_BT_CMD_INFO_8822B)
+#define BIT_GET_BT_CMD_INFO_8822B(x) \
+ (((x) >> BIT_SHIFT_BT_CMD_INFO_8822B) & BIT_MASK_BT_CMD_INFO_8822B)
+
+/* 2 REG_BT_INTERRUPT_CONTROL_REGISTER_8822B */
+#define BIT_EN_MAC_NULL_PKT_NOTIFY_8822B BIT(31)
+#define BIT_EN_WLAN_RPT_AND_BT_QUERY_8822B BIT(30)
+#define BIT_EN_BT_STSTUS_RPT_8822B BIT(29)
+#define BIT_EN_BT_POWER_8822B BIT(28)
+#define BIT_EN_BT_CHANNEL_8822B BIT(27)
+#define BIT_EN_BT_SLOT_CHANGE_8822B BIT(26)
+#define BIT_EN_BT_PROFILE_OR_HID_8822B BIT(25)
+#define BIT_WLAN_RPT_NOTIFY_8822B BIT(24)
+
+#define BIT_SHIFT_WLAN_RPT_DATA_8822B 16
+#define BIT_MASK_WLAN_RPT_DATA_8822B 0xff
+#define BIT_WLAN_RPT_DATA_8822B(x) \
+ (((x) & BIT_MASK_WLAN_RPT_DATA_8822B) << BIT_SHIFT_WLAN_RPT_DATA_8822B)
+#define BIT_GET_WLAN_RPT_DATA_8822B(x) \
+ (((x) >> BIT_SHIFT_WLAN_RPT_DATA_8822B) & BIT_MASK_WLAN_RPT_DATA_8822B)
+
+#define BIT_SHIFT_CMD_ID_8822B 8
+#define BIT_MASK_CMD_ID_8822B 0xff
+#define BIT_CMD_ID_8822B(x) \
+ (((x) & BIT_MASK_CMD_ID_8822B) << BIT_SHIFT_CMD_ID_8822B)
+#define BIT_GET_CMD_ID_8822B(x) \
+ (((x) >> BIT_SHIFT_CMD_ID_8822B) & BIT_MASK_CMD_ID_8822B)
+
+#define BIT_SHIFT_BT_DATA_8822B 0
+#define BIT_MASK_BT_DATA_8822B 0xff
+#define BIT_BT_DATA_8822B(x) \
+ (((x) & BIT_MASK_BT_DATA_8822B) << BIT_SHIFT_BT_DATA_8822B)
+#define BIT_GET_BT_DATA_8822B(x) \
+ (((x) >> BIT_SHIFT_BT_DATA_8822B) & BIT_MASK_BT_DATA_8822B)
+
+/* 2 REG_WLAN_REPORT_TIME_OUT_CONTROL_REGISTER_8822B */
+
+#define BIT_SHIFT_WLAN_RPT_TO_8822B 0
+#define BIT_MASK_WLAN_RPT_TO_8822B 0xff
+#define BIT_WLAN_RPT_TO_8822B(x) \
+ (((x) & BIT_MASK_WLAN_RPT_TO_8822B) << BIT_SHIFT_WLAN_RPT_TO_8822B)
+#define BIT_GET_WLAN_RPT_TO_8822B(x) \
+ (((x) >> BIT_SHIFT_WLAN_RPT_TO_8822B) & BIT_MASK_WLAN_RPT_TO_8822B)
+
+/* 2 REG_BT_ISOLATION_TABLE_REGISTER_REGISTER_8822B */
+
+#define BIT_SHIFT_ISOLATION_CHK_8822B 1
+#define BIT_MASK_ISOLATION_CHK_8822B 0x7fffffffffffffffffffL
+#define BIT_ISOLATION_CHK_8822B(x) \
+ (((x) & BIT_MASK_ISOLATION_CHK_8822B) << BIT_SHIFT_ISOLATION_CHK_8822B)
+#define BIT_GET_ISOLATION_CHK_8822B(x) \
+ (((x) >> BIT_SHIFT_ISOLATION_CHK_8822B) & BIT_MASK_ISOLATION_CHK_8822B)
+
+#define BIT_ISOLATION_EN_8822B BIT(0)
+
+/* 2 REG_BT_INTERRUPT_STATUS_REGISTER_8822B */
+#define BIT_BT_HID_ISR_8822B BIT(7)
+#define BIT_BT_QUERY_ISR_8822B BIT(6)
+#define BIT_MAC_NULL_PKT_NOTIFY_ISR_8822B BIT(5)
+#define BIT_WLAN_RPT_ISR_8822B BIT(4)
+#define BIT_BT_POWER_ISR_8822B BIT(3)
+#define BIT_BT_CHANNEL_ISR_8822B BIT(2)
+#define BIT_BT_SLOT_CHANGE_ISR_8822B BIT(1)
+#define BIT_BT_PROFILE_ISR_8822B BIT(0)
+
+/* 2 REG_BT_TDMA_TIME_REGISTER_8822B */
+
+#define BIT_SHIFT_BT_TIME_8822B 6
+#define BIT_MASK_BT_TIME_8822B 0x3ffffff
+#define BIT_BT_TIME_8822B(x) \
+ (((x) & BIT_MASK_BT_TIME_8822B) << BIT_SHIFT_BT_TIME_8822B)
+#define BIT_GET_BT_TIME_8822B(x) \
+ (((x) >> BIT_SHIFT_BT_TIME_8822B) & BIT_MASK_BT_TIME_8822B)
+
+#define BIT_SHIFT_BT_RPT_SAMPLE_RATE_8822B 0
+#define BIT_MASK_BT_RPT_SAMPLE_RATE_8822B 0x3f
+#define BIT_BT_RPT_SAMPLE_RATE_8822B(x) \
+ (((x) & BIT_MASK_BT_RPT_SAMPLE_RATE_8822B) \
+ << BIT_SHIFT_BT_RPT_SAMPLE_RATE_8822B)
+#define BIT_GET_BT_RPT_SAMPLE_RATE_8822B(x) \
+ (((x) >> BIT_SHIFT_BT_RPT_SAMPLE_RATE_8822B) & \
+ BIT_MASK_BT_RPT_SAMPLE_RATE_8822B)
+
+/* 2 REG_BT_ACT_REGISTER_8822B */
+
+#define BIT_SHIFT_BT_EISR_EN_8822B 16
+#define BIT_MASK_BT_EISR_EN_8822B 0xff
+#define BIT_BT_EISR_EN_8822B(x) \
+ (((x) & BIT_MASK_BT_EISR_EN_8822B) << BIT_SHIFT_BT_EISR_EN_8822B)
+#define BIT_GET_BT_EISR_EN_8822B(x) \
+ (((x) >> BIT_SHIFT_BT_EISR_EN_8822B) & BIT_MASK_BT_EISR_EN_8822B)
+
+#define BIT_BT_ACT_FALLING_ISR_8822B BIT(10)
+#define BIT_BT_ACT_RISING_ISR_8822B BIT(9)
+#define BIT_TDMA_TO_ISR_8822B BIT(8)
+
+#define BIT_SHIFT_BT_CH_8822B 0
+#define BIT_MASK_BT_CH_8822B 0xff
+#define BIT_BT_CH_8822B(x) \
+ (((x) & BIT_MASK_BT_CH_8822B) << BIT_SHIFT_BT_CH_8822B)
+#define BIT_GET_BT_CH_8822B(x) \
+ (((x) >> BIT_SHIFT_BT_CH_8822B) & BIT_MASK_BT_CH_8822B)
+
+/* 2 REG_OBFF_CTRL_BASIC_8822B */
+#define BIT_OBFF_EN_V1_8822B BIT(31)
+
+#define BIT_SHIFT_OBFF_STATE_V1_8822B 28
+#define BIT_MASK_OBFF_STATE_V1_8822B 0x3
+#define BIT_OBFF_STATE_V1_8822B(x) \
+ (((x) & BIT_MASK_OBFF_STATE_V1_8822B) << BIT_SHIFT_OBFF_STATE_V1_8822B)
+#define BIT_GET_OBFF_STATE_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_OBFF_STATE_V1_8822B) & BIT_MASK_OBFF_STATE_V1_8822B)
+
+#define BIT_OBFF_ACT_RXDMA_EN_8822B BIT(27)
+#define BIT_OBFF_BLOCK_INT_EN_8822B BIT(26)
+#define BIT_OBFF_AUTOACT_EN_8822B BIT(25)
+#define BIT_OBFF_AUTOIDLE_EN_8822B BIT(24)
+
+#define BIT_SHIFT_WAKE_MAX_PLS_8822B 20
+#define BIT_MASK_WAKE_MAX_PLS_8822B 0x7
+#define BIT_WAKE_MAX_PLS_8822B(x) \
+ (((x) & BIT_MASK_WAKE_MAX_PLS_8822B) << BIT_SHIFT_WAKE_MAX_PLS_8822B)
+#define BIT_GET_WAKE_MAX_PLS_8822B(x) \
+ (((x) >> BIT_SHIFT_WAKE_MAX_PLS_8822B) & BIT_MASK_WAKE_MAX_PLS_8822B)
+
+#define BIT_SHIFT_WAKE_MIN_PLS_8822B 16
+#define BIT_MASK_WAKE_MIN_PLS_8822B 0x7
+#define BIT_WAKE_MIN_PLS_8822B(x) \
+ (((x) & BIT_MASK_WAKE_MIN_PLS_8822B) << BIT_SHIFT_WAKE_MIN_PLS_8822B)
+#define BIT_GET_WAKE_MIN_PLS_8822B(x) \
+ (((x) >> BIT_SHIFT_WAKE_MIN_PLS_8822B) & BIT_MASK_WAKE_MIN_PLS_8822B)
+
+#define BIT_SHIFT_WAKE_MAX_F2F_8822B 12
+#define BIT_MASK_WAKE_MAX_F2F_8822B 0x7
+#define BIT_WAKE_MAX_F2F_8822B(x) \
+ (((x) & BIT_MASK_WAKE_MAX_F2F_8822B) << BIT_SHIFT_WAKE_MAX_F2F_8822B)
+#define BIT_GET_WAKE_MAX_F2F_8822B(x) \
+ (((x) >> BIT_SHIFT_WAKE_MAX_F2F_8822B) & BIT_MASK_WAKE_MAX_F2F_8822B)
+
+#define BIT_SHIFT_WAKE_MIN_F2F_8822B 8
+#define BIT_MASK_WAKE_MIN_F2F_8822B 0x7
+#define BIT_WAKE_MIN_F2F_8822B(x) \
+ (((x) & BIT_MASK_WAKE_MIN_F2F_8822B) << BIT_SHIFT_WAKE_MIN_F2F_8822B)
+#define BIT_GET_WAKE_MIN_F2F_8822B(x) \
+ (((x) >> BIT_SHIFT_WAKE_MIN_F2F_8822B) & BIT_MASK_WAKE_MIN_F2F_8822B)
+
+#define BIT_APP_CPU_ACT_V1_8822B BIT(3)
+#define BIT_APP_OBFF_V1_8822B BIT(2)
+#define BIT_APP_IDLE_V1_8822B BIT(1)
+#define BIT_APP_INIT_V1_8822B BIT(0)
+
+/* 2 REG_OBFF_CTRL2_TIMER_8822B */
+
+#define BIT_SHIFT_RX_HIGH_TIMER_IDX_8822B 24
+#define BIT_MASK_RX_HIGH_TIMER_IDX_8822B 0x7
+#define BIT_RX_HIGH_TIMER_IDX_8822B(x) \
+ (((x) & BIT_MASK_RX_HIGH_TIMER_IDX_8822B) \
+ << BIT_SHIFT_RX_HIGH_TIMER_IDX_8822B)
+#define BIT_GET_RX_HIGH_TIMER_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_RX_HIGH_TIMER_IDX_8822B) & \
+ BIT_MASK_RX_HIGH_TIMER_IDX_8822B)
+
+#define BIT_SHIFT_RX_MED_TIMER_IDX_8822B 16
+#define BIT_MASK_RX_MED_TIMER_IDX_8822B 0x7
+#define BIT_RX_MED_TIMER_IDX_8822B(x) \
+ (((x) & BIT_MASK_RX_MED_TIMER_IDX_8822B) \
+ << BIT_SHIFT_RX_MED_TIMER_IDX_8822B)
+#define BIT_GET_RX_MED_TIMER_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_RX_MED_TIMER_IDX_8822B) & \
+ BIT_MASK_RX_MED_TIMER_IDX_8822B)
+
+#define BIT_SHIFT_RX_LOW_TIMER_IDX_8822B 8
+#define BIT_MASK_RX_LOW_TIMER_IDX_8822B 0x7
+#define BIT_RX_LOW_TIMER_IDX_8822B(x) \
+ (((x) & BIT_MASK_RX_LOW_TIMER_IDX_8822B) \
+ << BIT_SHIFT_RX_LOW_TIMER_IDX_8822B)
+#define BIT_GET_RX_LOW_TIMER_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_RX_LOW_TIMER_IDX_8822B) & \
+ BIT_MASK_RX_LOW_TIMER_IDX_8822B)
+
+#define BIT_SHIFT_OBFF_INT_TIMER_IDX_8822B 0
+#define BIT_MASK_OBFF_INT_TIMER_IDX_8822B 0x7
+#define BIT_OBFF_INT_TIMER_IDX_8822B(x) \
+ (((x) & BIT_MASK_OBFF_INT_TIMER_IDX_8822B) \
+ << BIT_SHIFT_OBFF_INT_TIMER_IDX_8822B)
+#define BIT_GET_OBFF_INT_TIMER_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_OBFF_INT_TIMER_IDX_8822B) & \
+ BIT_MASK_OBFF_INT_TIMER_IDX_8822B)
+
+/* 2 REG_LTR_CTRL_BASIC_8822B */
+#define BIT_LTR_EN_V1_8822B BIT(31)
+#define BIT_LTR_HW_EN_V1_8822B BIT(30)
+#define BIT_LRT_ACT_CTS_EN_8822B BIT(29)
+#define BIT_LTR_ACT_RXPKT_EN_8822B BIT(28)
+#define BIT_LTR_ACT_RXDMA_EN_8822B BIT(27)
+#define BIT_LTR_IDLE_NO_SNOOP_8822B BIT(26)
+#define BIT_SPDUP_MGTPKT_8822B BIT(25)
+#define BIT_RX_AGG_EN_8822B BIT(24)
+#define BIT_APP_LTR_ACT_8822B BIT(23)
+#define BIT_APP_LTR_IDLE_8822B BIT(22)
+
+#define BIT_SHIFT_HIGH_RATE_TRIG_SEL_8822B 20
+#define BIT_MASK_HIGH_RATE_TRIG_SEL_8822B 0x3
+#define BIT_HIGH_RATE_TRIG_SEL_8822B(x) \
+ (((x) & BIT_MASK_HIGH_RATE_TRIG_SEL_8822B) \
+ << BIT_SHIFT_HIGH_RATE_TRIG_SEL_8822B)
+#define BIT_GET_HIGH_RATE_TRIG_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_HIGH_RATE_TRIG_SEL_8822B) & \
+ BIT_MASK_HIGH_RATE_TRIG_SEL_8822B)
+
+#define BIT_SHIFT_MED_RATE_TRIG_SEL_8822B 18
+#define BIT_MASK_MED_RATE_TRIG_SEL_8822B 0x3
+#define BIT_MED_RATE_TRIG_SEL_8822B(x) \
+ (((x) & BIT_MASK_MED_RATE_TRIG_SEL_8822B) \
+ << BIT_SHIFT_MED_RATE_TRIG_SEL_8822B)
+#define BIT_GET_MED_RATE_TRIG_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_MED_RATE_TRIG_SEL_8822B) & \
+ BIT_MASK_MED_RATE_TRIG_SEL_8822B)
+
+#define BIT_SHIFT_LOW_RATE_TRIG_SEL_8822B 16
+#define BIT_MASK_LOW_RATE_TRIG_SEL_8822B 0x3
+#define BIT_LOW_RATE_TRIG_SEL_8822B(x) \
+ (((x) & BIT_MASK_LOW_RATE_TRIG_SEL_8822B) \
+ << BIT_SHIFT_LOW_RATE_TRIG_SEL_8822B)
+#define BIT_GET_LOW_RATE_TRIG_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_LOW_RATE_TRIG_SEL_8822B) & \
+ BIT_MASK_LOW_RATE_TRIG_SEL_8822B)
+
+#define BIT_SHIFT_HIGH_RATE_BD_IDX_8822B 8
+#define BIT_MASK_HIGH_RATE_BD_IDX_8822B 0x7f
+#define BIT_HIGH_RATE_BD_IDX_8822B(x) \
+ (((x) & BIT_MASK_HIGH_RATE_BD_IDX_8822B) \
+ << BIT_SHIFT_HIGH_RATE_BD_IDX_8822B)
+#define BIT_GET_HIGH_RATE_BD_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_HIGH_RATE_BD_IDX_8822B) & \
+ BIT_MASK_HIGH_RATE_BD_IDX_8822B)
+
+#define BIT_SHIFT_LOW_RATE_BD_IDX_8822B 0
+#define BIT_MASK_LOW_RATE_BD_IDX_8822B 0x7f
+#define BIT_LOW_RATE_BD_IDX_8822B(x) \
+ (((x) & BIT_MASK_LOW_RATE_BD_IDX_8822B) \
+ << BIT_SHIFT_LOW_RATE_BD_IDX_8822B)
+#define BIT_GET_LOW_RATE_BD_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_LOW_RATE_BD_IDX_8822B) & \
+ BIT_MASK_LOW_RATE_BD_IDX_8822B)
+
+/* 2 REG_LTR_CTRL2_TIMER_THRESHOLD_8822B */
+
+#define BIT_SHIFT_RX_EMPTY_TIMER_IDX_8822B 24
+#define BIT_MASK_RX_EMPTY_TIMER_IDX_8822B 0x7
+#define BIT_RX_EMPTY_TIMER_IDX_8822B(x) \
+ (((x) & BIT_MASK_RX_EMPTY_TIMER_IDX_8822B) \
+ << BIT_SHIFT_RX_EMPTY_TIMER_IDX_8822B)
+#define BIT_GET_RX_EMPTY_TIMER_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_RX_EMPTY_TIMER_IDX_8822B) & \
+ BIT_MASK_RX_EMPTY_TIMER_IDX_8822B)
+
+#define BIT_SHIFT_RX_AFULL_TH_IDX_8822B 20
+#define BIT_MASK_RX_AFULL_TH_IDX_8822B 0x7
+#define BIT_RX_AFULL_TH_IDX_8822B(x) \
+ (((x) & BIT_MASK_RX_AFULL_TH_IDX_8822B) \
+ << BIT_SHIFT_RX_AFULL_TH_IDX_8822B)
+#define BIT_GET_RX_AFULL_TH_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_RX_AFULL_TH_IDX_8822B) & \
+ BIT_MASK_RX_AFULL_TH_IDX_8822B)
+
+#define BIT_SHIFT_RX_HIGH_TH_IDX_8822B 16
+#define BIT_MASK_RX_HIGH_TH_IDX_8822B 0x7
+#define BIT_RX_HIGH_TH_IDX_8822B(x) \
+ (((x) & BIT_MASK_RX_HIGH_TH_IDX_8822B) \
+ << BIT_SHIFT_RX_HIGH_TH_IDX_8822B)
+#define BIT_GET_RX_HIGH_TH_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_RX_HIGH_TH_IDX_8822B) & \
+ BIT_MASK_RX_HIGH_TH_IDX_8822B)
+
+#define BIT_SHIFT_RX_MED_TH_IDX_8822B 12
+#define BIT_MASK_RX_MED_TH_IDX_8822B 0x7
+#define BIT_RX_MED_TH_IDX_8822B(x) \
+ (((x) & BIT_MASK_RX_MED_TH_IDX_8822B) << BIT_SHIFT_RX_MED_TH_IDX_8822B)
+#define BIT_GET_RX_MED_TH_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_RX_MED_TH_IDX_8822B) & BIT_MASK_RX_MED_TH_IDX_8822B)
+
+#define BIT_SHIFT_RX_LOW_TH_IDX_8822B 8
+#define BIT_MASK_RX_LOW_TH_IDX_8822B 0x7
+#define BIT_RX_LOW_TH_IDX_8822B(x) \
+ (((x) & BIT_MASK_RX_LOW_TH_IDX_8822B) << BIT_SHIFT_RX_LOW_TH_IDX_8822B)
+#define BIT_GET_RX_LOW_TH_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_RX_LOW_TH_IDX_8822B) & BIT_MASK_RX_LOW_TH_IDX_8822B)
+
+#define BIT_SHIFT_LTR_SPACE_IDX_8822B 4
+#define BIT_MASK_LTR_SPACE_IDX_8822B 0x3
+#define BIT_LTR_SPACE_IDX_8822B(x) \
+ (((x) & BIT_MASK_LTR_SPACE_IDX_8822B) << BIT_SHIFT_LTR_SPACE_IDX_8822B)
+#define BIT_GET_LTR_SPACE_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_LTR_SPACE_IDX_8822B) & BIT_MASK_LTR_SPACE_IDX_8822B)
+
+#define BIT_SHIFT_LTR_IDLE_TIMER_IDX_8822B 0
+#define BIT_MASK_LTR_IDLE_TIMER_IDX_8822B 0x7
+#define BIT_LTR_IDLE_TIMER_IDX_8822B(x) \
+ (((x) & BIT_MASK_LTR_IDLE_TIMER_IDX_8822B) \
+ << BIT_SHIFT_LTR_IDLE_TIMER_IDX_8822B)
+#define BIT_GET_LTR_IDLE_TIMER_IDX_8822B(x) \
+ (((x) >> BIT_SHIFT_LTR_IDLE_TIMER_IDX_8822B) & \
+ BIT_MASK_LTR_IDLE_TIMER_IDX_8822B)
+
+/* 2 REG_LTR_IDLE_LATENCY_V1_8822B */
+
+#define BIT_SHIFT_LTR_IDLE_L_8822B 0
+#define BIT_MASK_LTR_IDLE_L_8822B 0xffffffffL
+#define BIT_LTR_IDLE_L_8822B(x) \
+ (((x) & BIT_MASK_LTR_IDLE_L_8822B) << BIT_SHIFT_LTR_IDLE_L_8822B)
+#define BIT_GET_LTR_IDLE_L_8822B(x) \
+ (((x) >> BIT_SHIFT_LTR_IDLE_L_8822B) & BIT_MASK_LTR_IDLE_L_8822B)
+
+/* 2 REG_LTR_ACTIVE_LATENCY_V1_8822B */
+
+#define BIT_SHIFT_LTR_ACT_L_8822B 0
+#define BIT_MASK_LTR_ACT_L_8822B 0xffffffffL
+#define BIT_LTR_ACT_L_8822B(x) \
+ (((x) & BIT_MASK_LTR_ACT_L_8822B) << BIT_SHIFT_LTR_ACT_L_8822B)
+#define BIT_GET_LTR_ACT_L_8822B(x) \
+ (((x) >> BIT_SHIFT_LTR_ACT_L_8822B) & BIT_MASK_LTR_ACT_L_8822B)
+
+/* 2 REG_ANTENNA_TRAINING_CONTROL_REGISTER_8822B */
+#define BIT_APPEND_MACID_IN_RESP_EN_8822B BIT(50)
+#define BIT_ADDR2_MATCH_EN_8822B BIT(49)
+#define BIT_ANTTRN_EN_8822B BIT(48)
+
+#define BIT_SHIFT_TRAIN_STA_ADDR_8822B 0
+#define BIT_MASK_TRAIN_STA_ADDR_8822B 0xffffffffffffL
+#define BIT_TRAIN_STA_ADDR_8822B(x) \
+ (((x) & BIT_MASK_TRAIN_STA_ADDR_8822B) \
+ << BIT_SHIFT_TRAIN_STA_ADDR_8822B)
+#define BIT_GET_TRAIN_STA_ADDR_8822B(x) \
+ (((x) >> BIT_SHIFT_TRAIN_STA_ADDR_8822B) & \
+ BIT_MASK_TRAIN_STA_ADDR_8822B)
+
+/* 2 REG_RSVD_0X7B4_8822B */
+
+/* 2 REG_WMAC_PKTCNT_RWD_8822B */
+
+#define BIT_SHIFT_PKTCNT_BSSIDMAP_8822B 4
+#define BIT_MASK_PKTCNT_BSSIDMAP_8822B 0xf
+#define BIT_PKTCNT_BSSIDMAP_8822B(x) \
+ (((x) & BIT_MASK_PKTCNT_BSSIDMAP_8822B) \
+ << BIT_SHIFT_PKTCNT_BSSIDMAP_8822B)
+#define BIT_GET_PKTCNT_BSSIDMAP_8822B(x) \
+ (((x) >> BIT_SHIFT_PKTCNT_BSSIDMAP_8822B) & \
+ BIT_MASK_PKTCNT_BSSIDMAP_8822B)
+
+#define BIT_PKTCNT_CNTRST_8822B BIT(1)
+#define BIT_PKTCNT_CNTEN_8822B BIT(0)
+
+/* 2 REG_WMAC_PKTCNT_CTRL_8822B */
+#define BIT_WMAC_PKTCNT_TRST_8822B BIT(9)
+#define BIT_WMAC_PKTCNT_FEN_8822B BIT(8)
+
+#define BIT_SHIFT_WMAC_PKTCNT_CFGAD_8822B 0
+#define BIT_MASK_WMAC_PKTCNT_CFGAD_8822B 0xff
+#define BIT_WMAC_PKTCNT_CFGAD_8822B(x) \
+ (((x) & BIT_MASK_WMAC_PKTCNT_CFGAD_8822B) \
+ << BIT_SHIFT_WMAC_PKTCNT_CFGAD_8822B)
+#define BIT_GET_WMAC_PKTCNT_CFGAD_8822B(x) \
+ (((x) >> BIT_SHIFT_WMAC_PKTCNT_CFGAD_8822B) & \
+ BIT_MASK_WMAC_PKTCNT_CFGAD_8822B)
+
+/* 2 REG_IQ_DUMP_8822B */
+
+#define BIT_SHIFT_R_WMAC_MATCH_REF_MAC_8822B (64 & CPU_OPT_WIDTH)
+#define BIT_MASK_R_WMAC_MATCH_REF_MAC_8822B 0xffffffffL
+#define BIT_R_WMAC_MATCH_REF_MAC_8822B(x) \
+ (((x) & BIT_MASK_R_WMAC_MATCH_REF_MAC_8822B) \
+ << BIT_SHIFT_R_WMAC_MATCH_REF_MAC_8822B)
+#define BIT_GET_R_WMAC_MATCH_REF_MAC_8822B(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_MATCH_REF_MAC_8822B) & \
+ BIT_MASK_R_WMAC_MATCH_REF_MAC_8822B)
+
+#define BIT_SHIFT_R_WMAC_MASK_LA_MAC_8822B (32 & CPU_OPT_WIDTH)
+#define BIT_MASK_R_WMAC_MASK_LA_MAC_8822B 0xffffffffL
+#define BIT_R_WMAC_MASK_LA_MAC_8822B(x) \
+ (((x) & BIT_MASK_R_WMAC_MASK_LA_MAC_8822B) \
+ << BIT_SHIFT_R_WMAC_MASK_LA_MAC_8822B)
+#define BIT_GET_R_WMAC_MASK_LA_MAC_8822B(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_MASK_LA_MAC_8822B) & \
+ BIT_MASK_R_WMAC_MASK_LA_MAC_8822B)
+
+#define BIT_SHIFT_DUMP_OK_ADDR_8822B 15
+#define BIT_MASK_DUMP_OK_ADDR_8822B 0x1ffff
+#define BIT_DUMP_OK_ADDR_8822B(x) \
+ (((x) & BIT_MASK_DUMP_OK_ADDR_8822B) << BIT_SHIFT_DUMP_OK_ADDR_8822B)
+#define BIT_GET_DUMP_OK_ADDR_8822B(x) \
+ (((x) >> BIT_SHIFT_DUMP_OK_ADDR_8822B) & BIT_MASK_DUMP_OK_ADDR_8822B)
+
+#define BIT_SHIFT_R_TRIG_TIME_SEL_8822B 8
+#define BIT_MASK_R_TRIG_TIME_SEL_8822B 0x7f
+#define BIT_R_TRIG_TIME_SEL_8822B(x) \
+ (((x) & BIT_MASK_R_TRIG_TIME_SEL_8822B) \
+ << BIT_SHIFT_R_TRIG_TIME_SEL_8822B)
+#define BIT_GET_R_TRIG_TIME_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_R_TRIG_TIME_SEL_8822B) & \
+ BIT_MASK_R_TRIG_TIME_SEL_8822B)
+
+#define BIT_SHIFT_R_MAC_TRIG_SEL_8822B 6
+#define BIT_MASK_R_MAC_TRIG_SEL_8822B 0x3
+#define BIT_R_MAC_TRIG_SEL_8822B(x) \
+ (((x) & BIT_MASK_R_MAC_TRIG_SEL_8822B) \
+ << BIT_SHIFT_R_MAC_TRIG_SEL_8822B)
+#define BIT_GET_R_MAC_TRIG_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_R_MAC_TRIG_SEL_8822B) & \
+ BIT_MASK_R_MAC_TRIG_SEL_8822B)
+
+#define BIT_MAC_TRIG_REG_8822B BIT(5)
+
+#define BIT_SHIFT_R_LEVEL_PULSE_SEL_8822B 3
+#define BIT_MASK_R_LEVEL_PULSE_SEL_8822B 0x3
+#define BIT_R_LEVEL_PULSE_SEL_8822B(x) \
+ (((x) & BIT_MASK_R_LEVEL_PULSE_SEL_8822B) \
+ << BIT_SHIFT_R_LEVEL_PULSE_SEL_8822B)
+#define BIT_GET_R_LEVEL_PULSE_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_R_LEVEL_PULSE_SEL_8822B) & \
+ BIT_MASK_R_LEVEL_PULSE_SEL_8822B)
+
+#define BIT_EN_LA_MAC_8822B BIT(2)
+#define BIT_R_EN_IQDUMP_8822B BIT(1)
+#define BIT_R_IQDATA_DUMP_8822B BIT(0)
+
+/* 2 REG_WMAC_FTM_CTL_8822B */
+#define BIT_RXFTM_TXACK_SC_8822B BIT(6)
+#define BIT_RXFTM_TXACK_BW_8822B BIT(5)
+#define BIT_RXFTM_EN_8822B BIT(3)
+#define BIT_RXFTMREQ_BYDRV_8822B BIT(2)
+#define BIT_RXFTMREQ_EN_8822B BIT(1)
+#define BIT_FTM_EN_8822B BIT(0)
+
+/* 2 REG_WMAC_IQ_MDPK_FUNC_8822B */
+
+/* 2 REG_WMAC_OPTION_FUNCTION_8822B */
+
+#define BIT_SHIFT_R_WMAC_RX_FIL_LEN_8822B (64 & CPU_OPT_WIDTH)
+#define BIT_MASK_R_WMAC_RX_FIL_LEN_8822B 0xffff
+#define BIT_R_WMAC_RX_FIL_LEN_8822B(x) \
+ (((x) & BIT_MASK_R_WMAC_RX_FIL_LEN_8822B) \
+ << BIT_SHIFT_R_WMAC_RX_FIL_LEN_8822B)
+#define BIT_GET_R_WMAC_RX_FIL_LEN_8822B(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_RX_FIL_LEN_8822B) & \
+ BIT_MASK_R_WMAC_RX_FIL_LEN_8822B)
+
+#define BIT_SHIFT_R_WMAC_RXFIFO_FULL_TH_8822B (56 & CPU_OPT_WIDTH)
+#define BIT_MASK_R_WMAC_RXFIFO_FULL_TH_8822B 0xff
+#define BIT_R_WMAC_RXFIFO_FULL_TH_8822B(x) \
+ (((x) & BIT_MASK_R_WMAC_RXFIFO_FULL_TH_8822B) \
+ << BIT_SHIFT_R_WMAC_RXFIFO_FULL_TH_8822B)
+#define BIT_GET_R_WMAC_RXFIFO_FULL_TH_8822B(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_RXFIFO_FULL_TH_8822B) & \
+ BIT_MASK_R_WMAC_RXFIFO_FULL_TH_8822B)
+
+#define BIT_R_WMAC_RX_SYNCFIFO_SYNC_8822B BIT(55)
+#define BIT_R_WMAC_RXRST_DLY_8822B BIT(54)
+#define BIT_R_WMAC_SRCH_TXRPT_REF_DROP_8822B BIT(53)
+#define BIT_R_WMAC_SRCH_TXRPT_UA1_8822B BIT(52)
+#define BIT_R_WMAC_SRCH_TXRPT_TYPE_8822B BIT(51)
+#define BIT_R_WMAC_NDP_RST_8822B BIT(50)
+#define BIT_R_WMAC_POWINT_EN_8822B BIT(49)
+#define BIT_R_WMAC_SRCH_TXRPT_PERPKT_8822B BIT(48)
+#define BIT_R_WMAC_SRCH_TXRPT_MID_8822B BIT(47)
+#define BIT_R_WMAC_PFIN_TOEN_8822B BIT(46)
+#define BIT_R_WMAC_FIL_SECERR_8822B BIT(45)
+#define BIT_R_WMAC_FIL_CTLPKTLEN_8822B BIT(44)
+#define BIT_R_WMAC_FIL_FCTYPE_8822B BIT(43)
+#define BIT_R_WMAC_FIL_FCPROVER_8822B BIT(42)
+#define BIT_R_WMAC_PHYSTS_SNIF_8822B BIT(41)
+#define BIT_R_WMAC_PHYSTS_PLCP_8822B BIT(40)
+#define BIT_R_MAC_TCR_VBONF_RD_8822B BIT(39)
+#define BIT_R_WMAC_TCR_MPAR_NDP_8822B BIT(38)
+#define BIT_R_WMAC_NDP_FILTER_8822B BIT(37)
+#define BIT_R_WMAC_RXLEN_SEL_8822B BIT(36)
+#define BIT_R_WMAC_RXLEN_SEL1_8822B BIT(35)
+#define BIT_R_OFDM_FILTER_8822B BIT(34)
+#define BIT_R_WMAC_CHK_OFDM_LEN_8822B BIT(33)
+#define BIT_R_WMAC_CHK_CCK_LEN_8822B BIT(32)
+
+#define BIT_SHIFT_R_OFDM_LEN_8822B 26
+#define BIT_MASK_R_OFDM_LEN_8822B 0x3f
+#define BIT_R_OFDM_LEN_8822B(x) \
+ (((x) & BIT_MASK_R_OFDM_LEN_8822B) << BIT_SHIFT_R_OFDM_LEN_8822B)
+#define BIT_GET_R_OFDM_LEN_8822B(x) \
+ (((x) >> BIT_SHIFT_R_OFDM_LEN_8822B) & BIT_MASK_R_OFDM_LEN_8822B)
+
+#define BIT_SHIFT_R_CCK_LEN_8822B 0
+#define BIT_MASK_R_CCK_LEN_8822B 0xffff
+#define BIT_R_CCK_LEN_8822B(x) \
+ (((x) & BIT_MASK_R_CCK_LEN_8822B) << BIT_SHIFT_R_CCK_LEN_8822B)
+#define BIT_GET_R_CCK_LEN_8822B(x) \
+ (((x) >> BIT_SHIFT_R_CCK_LEN_8822B) & BIT_MASK_R_CCK_LEN_8822B)
+
+/* 2 REG_RX_FILTER_FUNCTION_8822B */
+#define BIT_R_WMAC_MHRDDY_LATCH_8822B BIT(14)
+#define BIT_R_WMAC_MHRDDY_CLR_8822B BIT(13)
+#define BIT_R_RXPKTCTL_FSM_BASED_MPDURDY1_8822B BIT(12)
+#define BIT_WMAC_DIS_VHT_PLCP_CHK_MU_8822B BIT(11)
+#define BIT_R_CHK_DELIMIT_LEN_8822B BIT(10)
+#define BIT_R_REAPTER_ADDR_MATCH_8822B BIT(9)
+#define BIT_R_RXPKTCTL_FSM_BASED_MPDURDY_8822B BIT(8)
+#define BIT_R_LATCH_MACHRDY_8822B BIT(7)
+#define BIT_R_WMAC_RXFIL_REND_8822B BIT(6)
+#define BIT_R_WMAC_MPDURDY_CLR_8822B BIT(5)
+#define BIT_R_WMAC_CLRRXSEC_8822B BIT(4)
+#define BIT_R_WMAC_RXFIL_RDEL_8822B BIT(3)
+#define BIT_R_WMAC_RXFIL_FCSE_8822B BIT(2)
+#define BIT_R_WMAC_RXFIL_MESH_DEL_8822B BIT(1)
+#define BIT_R_WMAC_RXFIL_MASKM_8822B BIT(0)
+
+/* 2 REG_NDP_SIG_8822B */
+
+#define BIT_SHIFT_R_WMAC_TXNDP_SIGB_8822B 0
+#define BIT_MASK_R_WMAC_TXNDP_SIGB_8822B 0x1fffff
+#define BIT_R_WMAC_TXNDP_SIGB_8822B(x) \
+ (((x) & BIT_MASK_R_WMAC_TXNDP_SIGB_8822B) \
+ << BIT_SHIFT_R_WMAC_TXNDP_SIGB_8822B)
+#define BIT_GET_R_WMAC_TXNDP_SIGB_8822B(x) \
+ (((x) >> BIT_SHIFT_R_WMAC_TXNDP_SIGB_8822B) & \
+ BIT_MASK_R_WMAC_TXNDP_SIGB_8822B)
+
+/* 2 REG_TXCMD_INFO_FOR_RSP_PKT_8822B */
+
+#define BIT_SHIFT_R_MAC_DEBUG_8822B (32 & CPU_OPT_WIDTH)
+#define BIT_MASK_R_MAC_DEBUG_8822B 0xffffffffL
+#define BIT_R_MAC_DEBUG_8822B(x) \
+ (((x) & BIT_MASK_R_MAC_DEBUG_8822B) << BIT_SHIFT_R_MAC_DEBUG_8822B)
+#define BIT_GET_R_MAC_DEBUG_8822B(x) \
+ (((x) >> BIT_SHIFT_R_MAC_DEBUG_8822B) & BIT_MASK_R_MAC_DEBUG_8822B)
+
+#define BIT_SHIFT_R_MAC_DBG_SHIFT_8822B 8
+#define BIT_MASK_R_MAC_DBG_SHIFT_8822B 0x7
+#define BIT_R_MAC_DBG_SHIFT_8822B(x) \
+ (((x) & BIT_MASK_R_MAC_DBG_SHIFT_8822B) \
+ << BIT_SHIFT_R_MAC_DBG_SHIFT_8822B)
+#define BIT_GET_R_MAC_DBG_SHIFT_8822B(x) \
+ (((x) >> BIT_SHIFT_R_MAC_DBG_SHIFT_8822B) & \
+ BIT_MASK_R_MAC_DBG_SHIFT_8822B)
+
+#define BIT_SHIFT_R_MAC_DBG_SEL_8822B 0
+#define BIT_MASK_R_MAC_DBG_SEL_8822B 0x3
+#define BIT_R_MAC_DBG_SEL_8822B(x) \
+ (((x) & BIT_MASK_R_MAC_DBG_SEL_8822B) << BIT_SHIFT_R_MAC_DBG_SEL_8822B)
+#define BIT_GET_R_MAC_DBG_SEL_8822B(x) \
+ (((x) >> BIT_SHIFT_R_MAC_DBG_SEL_8822B) & BIT_MASK_R_MAC_DBG_SEL_8822B)
+
+/* 2 REG_RTS_ADDRESS_0_8822B */
+
+/* 2 REG_RTS_ADDRESS_1_8822B */
+
+/* 2 REG__RPFM_MAP1_8822B
+ * (RX PAYLOAD FILTER MAP FRAME TYPE CONTROL REGISTER GROUP 1
+ */
+#define BIT_DATA_RPFM15EN_8822B BIT(15)
+#define BIT_DATA_RPFM14EN_8822B BIT(14)
+#define BIT_DATA_RPFM13EN_8822B BIT(13)
+#define BIT_DATA_RPFM12EN_8822B BIT(12)
+#define BIT_DATA_RPFM11EN_8822B BIT(11)
+#define BIT_DATA_RPFM10EN_8822B BIT(10)
+#define BIT_DATA_RPFM9EN_8822B BIT(9)
+#define BIT_DATA_RPFM8EN_8822B BIT(8)
+#define BIT_DATA_RPFM7EN_8822B BIT(7)
+#define BIT_DATA_RPFM6EN_8822B BIT(6)
+#define BIT_DATA_RPFM5EN_8822B BIT(5)
+#define BIT_DATA_RPFM4EN_8822B BIT(4)
+#define BIT_DATA_RPFM3EN_8822B BIT(3)
+#define BIT_DATA_RPFM2EN_8822B BIT(2)
+#define BIT_DATA_RPFM1EN_8822B BIT(1)
+#define BIT_DATA_RPFM0EN_8822B BIT(0)
+
+/* 2 REG_WL2LTECOEX_INDIRECT_ACCESS_CTRL_V1_8822B */
+#define BIT_LTECOEX_ACCESS_START_V1_8822B BIT(31)
+#define BIT_LTECOEX_WRITE_MODE_V1_8822B BIT(30)
+#define BIT_LTECOEX_READY_BIT_V1_8822B BIT(29)
+
+#define BIT_SHIFT_WRITE_BYTE_EN_V1_8822B 16
+#define BIT_MASK_WRITE_BYTE_EN_V1_8822B 0xf
+#define BIT_WRITE_BYTE_EN_V1_8822B(x) \
+ (((x) & BIT_MASK_WRITE_BYTE_EN_V1_8822B) \
+ << BIT_SHIFT_WRITE_BYTE_EN_V1_8822B)
+#define BIT_GET_WRITE_BYTE_EN_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_WRITE_BYTE_EN_V1_8822B) & \
+ BIT_MASK_WRITE_BYTE_EN_V1_8822B)
+
+#define BIT_SHIFT_LTECOEX_REG_ADDR_V1_8822B 0
+#define BIT_MASK_LTECOEX_REG_ADDR_V1_8822B 0xffff
+#define BIT_LTECOEX_REG_ADDR_V1_8822B(x) \
+ (((x) & BIT_MASK_LTECOEX_REG_ADDR_V1_8822B) \
+ << BIT_SHIFT_LTECOEX_REG_ADDR_V1_8822B)
+#define BIT_GET_LTECOEX_REG_ADDR_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_LTECOEX_REG_ADDR_V1_8822B) & \
+ BIT_MASK_LTECOEX_REG_ADDR_V1_8822B)
+
+/* 2 REG_WL2LTECOEX_INDIRECT_ACCESS_WRITE_DATA_V1_8822B */
+
+#define BIT_SHIFT_LTECOEX_W_DATA_V1_8822B 0
+#define BIT_MASK_LTECOEX_W_DATA_V1_8822B 0xffffffffL
+#define BIT_LTECOEX_W_DATA_V1_8822B(x) \
+ (((x) & BIT_MASK_LTECOEX_W_DATA_V1_8822B) \
+ << BIT_SHIFT_LTECOEX_W_DATA_V1_8822B)
+#define BIT_GET_LTECOEX_W_DATA_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_LTECOEX_W_DATA_V1_8822B) & \
+ BIT_MASK_LTECOEX_W_DATA_V1_8822B)
+
+/* 2 REG_WL2LTECOEX_INDIRECT_ACCESS_READ_DATA_V1_8822B */
+
+#define BIT_SHIFT_LTECOEX_R_DATA_V1_8822B 0
+#define BIT_MASK_LTECOEX_R_DATA_V1_8822B 0xffffffffL
+#define BIT_LTECOEX_R_DATA_V1_8822B(x) \
+ (((x) & BIT_MASK_LTECOEX_R_DATA_V1_8822B) \
+ << BIT_SHIFT_LTECOEX_R_DATA_V1_8822B)
+#define BIT_GET_LTECOEX_R_DATA_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_LTECOEX_R_DATA_V1_8822B) & \
+ BIT_MASK_LTECOEX_R_DATA_V1_8822B)
+
+/* 2 REG_NOT_VALID_8822B */
+
+/* 2 REG_SDIO_TX_CTRL_8822B */
+
+#define BIT_SHIFT_SDIO_INT_TIMEOUT_8822B 16
+#define BIT_MASK_SDIO_INT_TIMEOUT_8822B 0xffff
+#define BIT_SDIO_INT_TIMEOUT_8822B(x) \
+ (((x) & BIT_MASK_SDIO_INT_TIMEOUT_8822B) \
+ << BIT_SHIFT_SDIO_INT_TIMEOUT_8822B)
+#define BIT_GET_SDIO_INT_TIMEOUT_8822B(x) \
+ (((x) >> BIT_SHIFT_SDIO_INT_TIMEOUT_8822B) & \
+ BIT_MASK_SDIO_INT_TIMEOUT_8822B)
+
+#define BIT_IO_ERR_STATUS_8822B BIT(15)
+#define BIT_REPLY_ERRCRC_IN_DATA_8822B BIT(9)
+#define BIT_EN_CMD53_OVERLAP_8822B BIT(8)
+#define BIT_REPLY_ERR_IN_R5_8822B BIT(7)
+#define BIT_R18A_EN_8822B BIT(6)
+#define BIT_INIT_CMD_EN_8822B BIT(5)
+#define BIT_EN_RXDMA_MASK_INT_8822B BIT(2)
+#define BIT_EN_MASK_TIMER_8822B BIT(1)
+#define BIT_CMD_ERR_STOP_INT_EN_8822B BIT(0)
+
+/* 2 REG_SDIO_HIMR_8822B */
+#define BIT_SDIO_CRCERR_MSK_8822B BIT(31)
+#define BIT_SDIO_HSISR3_IND_MSK_8822B BIT(30)
+#define BIT_SDIO_HSISR2_IND_MSK_8822B BIT(29)
+#define BIT_SDIO_HEISR_IND_MSK_8822B BIT(28)
+#define BIT_SDIO_CTWEND_MSK_8822B BIT(27)
+#define BIT_SDIO_ATIMEND_E_MSK_8822B BIT(26)
+#define BIT_SDIIO_ATIMEND_MSK_8822B BIT(25)
+#define BIT_SDIO_OCPINT_MSK_8822B BIT(24)
+#define BIT_SDIO_PSTIMEOUT_MSK_8822B BIT(23)
+#define BIT_SDIO_GTINT4_MSK_8822B BIT(22)
+#define BIT_SDIO_GTINT3_MSK_8822B BIT(21)
+#define BIT_SDIO_HSISR_IND_MSK_8822B BIT(20)
+#define BIT_SDIO_CPWM2_MSK_8822B BIT(19)
+#define BIT_SDIO_CPWM1_MSK_8822B BIT(18)
+#define BIT_SDIO_C2HCMD_INT_MSK_8822B BIT(17)
+#define BIT_SDIO_BCNERLY_INT_MSK_8822B BIT(16)
+#define BIT_SDIO_TXBCNERR_MSK_8822B BIT(7)
+#define BIT_SDIO_TXBCNOK_MSK_8822B BIT(6)
+#define BIT_SDIO_RXFOVW_MSK_8822B BIT(5)
+#define BIT_SDIO_TXFOVW_MSK_8822B BIT(4)
+#define BIT_SDIO_RXERR_MSK_8822B BIT(3)
+#define BIT_SDIO_TXERR_MSK_8822B BIT(2)
+#define BIT_SDIO_AVAL_MSK_8822B BIT(1)
+#define BIT_RX_REQUEST_MSK_8822B BIT(0)
+
+/* 2 REG_SDIO_HISR_8822B */
+#define BIT_SDIO_CRCERR_8822B BIT(31)
+#define BIT_SDIO_HSISR3_IND_8822B BIT(30)
+#define BIT_SDIO_HSISR2_IND_8822B BIT(29)
+#define BIT_SDIO_HEISR_IND_8822B BIT(28)
+#define BIT_SDIO_CTWEND_8822B BIT(27)
+#define BIT_SDIO_ATIMEND_E_8822B BIT(26)
+#define BIT_SDIO_ATIMEND_8822B BIT(25)
+#define BIT_SDIO_OCPINT_8822B BIT(24)
+#define BIT_SDIO_PSTIMEOUT_8822B BIT(23)
+#define BIT_SDIO_GTINT4_8822B BIT(22)
+#define BIT_SDIO_GTINT3_8822B BIT(21)
+#define BIT_SDIO_HSISR_IND_8822B BIT(20)
+#define BIT_SDIO_CPWM2_8822B BIT(19)
+#define BIT_SDIO_CPWM1_8822B BIT(18)
+#define BIT_SDIO_C2HCMD_INT_8822B BIT(17)
+#define BIT_SDIO_BCNERLY_INT_8822B BIT(16)
+#define BIT_SDIO_TXBCNERR_8822B BIT(7)
+#define BIT_SDIO_TXBCNOK_8822B BIT(6)
+#define BIT_SDIO_RXFOVW_8822B BIT(5)
+#define BIT_SDIO_TXFOVW_8822B BIT(4)
+#define BIT_SDIO_RXERR_8822B BIT(3)
+#define BIT_SDIO_TXERR_8822B BIT(2)
+#define BIT_SDIO_AVAL_8822B BIT(1)
+#define BIT_RX_REQUEST_8822B BIT(0)
+
+/* 2 REG_SDIO_RX_REQ_LEN_8822B */
+
+#define BIT_SHIFT_RX_REQ_LEN_V1_8822B 0
+#define BIT_MASK_RX_REQ_LEN_V1_8822B 0x3ffff
+#define BIT_RX_REQ_LEN_V1_8822B(x) \
+ (((x) & BIT_MASK_RX_REQ_LEN_V1_8822B) << BIT_SHIFT_RX_REQ_LEN_V1_8822B)
+#define BIT_GET_RX_REQ_LEN_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_RX_REQ_LEN_V1_8822B) & BIT_MASK_RX_REQ_LEN_V1_8822B)
+
+/* 2 REG_SDIO_FREE_TXPG_SEQ_V1_8822B */
+
+#define BIT_SHIFT_FREE_TXPG_SEQ_8822B 0
+#define BIT_MASK_FREE_TXPG_SEQ_8822B 0xff
+#define BIT_FREE_TXPG_SEQ_8822B(x) \
+ (((x) & BIT_MASK_FREE_TXPG_SEQ_8822B) << BIT_SHIFT_FREE_TXPG_SEQ_8822B)
+#define BIT_GET_FREE_TXPG_SEQ_8822B(x) \
+ (((x) >> BIT_SHIFT_FREE_TXPG_SEQ_8822B) & BIT_MASK_FREE_TXPG_SEQ_8822B)
+
+/* 2 REG_SDIO_FREE_TXPG_8822B */
+
+#define BIT_SHIFT_MID_FREEPG_V1_8822B 16
+#define BIT_MASK_MID_FREEPG_V1_8822B 0xfff
+#define BIT_MID_FREEPG_V1_8822B(x) \
+ (((x) & BIT_MASK_MID_FREEPG_V1_8822B) << BIT_SHIFT_MID_FREEPG_V1_8822B)
+#define BIT_GET_MID_FREEPG_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_MID_FREEPG_V1_8822B) & BIT_MASK_MID_FREEPG_V1_8822B)
+
+#define BIT_SHIFT_HIQ_FREEPG_V1_8822B 0
+#define BIT_MASK_HIQ_FREEPG_V1_8822B 0xfff
+#define BIT_HIQ_FREEPG_V1_8822B(x) \
+ (((x) & BIT_MASK_HIQ_FREEPG_V1_8822B) << BIT_SHIFT_HIQ_FREEPG_V1_8822B)
+#define BIT_GET_HIQ_FREEPG_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_HIQ_FREEPG_V1_8822B) & BIT_MASK_HIQ_FREEPG_V1_8822B)
+
+/* 2 REG_SDIO_FREE_TXPG2_8822B */
+
+#define BIT_SHIFT_PUB_FREEPG_V1_8822B 16
+#define BIT_MASK_PUB_FREEPG_V1_8822B 0xfff
+#define BIT_PUB_FREEPG_V1_8822B(x) \
+ (((x) & BIT_MASK_PUB_FREEPG_V1_8822B) << BIT_SHIFT_PUB_FREEPG_V1_8822B)
+#define BIT_GET_PUB_FREEPG_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_PUB_FREEPG_V1_8822B) & BIT_MASK_PUB_FREEPG_V1_8822B)
+
+#define BIT_SHIFT_LOW_FREEPG_V1_8822B 0
+#define BIT_MASK_LOW_FREEPG_V1_8822B 0xfff
+#define BIT_LOW_FREEPG_V1_8822B(x) \
+ (((x) & BIT_MASK_LOW_FREEPG_V1_8822B) << BIT_SHIFT_LOW_FREEPG_V1_8822B)
+#define BIT_GET_LOW_FREEPG_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_LOW_FREEPG_V1_8822B) & BIT_MASK_LOW_FREEPG_V1_8822B)
+
+/* 2 REG_SDIO_OQT_FREE_TXPG_V1_8822B */
+
+#define BIT_SHIFT_NOAC_OQT_FREEPG_V1_8822B 24
+#define BIT_MASK_NOAC_OQT_FREEPG_V1_8822B 0xff
+#define BIT_NOAC_OQT_FREEPG_V1_8822B(x) \
+ (((x) & BIT_MASK_NOAC_OQT_FREEPG_V1_8822B) \
+ << BIT_SHIFT_NOAC_OQT_FREEPG_V1_8822B)
+#define BIT_GET_NOAC_OQT_FREEPG_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_NOAC_OQT_FREEPG_V1_8822B) & \
+ BIT_MASK_NOAC_OQT_FREEPG_V1_8822B)
+
+#define BIT_SHIFT_AC_OQT_FREEPG_V1_8822B 16
+#define BIT_MASK_AC_OQT_FREEPG_V1_8822B 0xff
+#define BIT_AC_OQT_FREEPG_V1_8822B(x) \
+ (((x) & BIT_MASK_AC_OQT_FREEPG_V1_8822B) \
+ << BIT_SHIFT_AC_OQT_FREEPG_V1_8822B)
+#define BIT_GET_AC_OQT_FREEPG_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_AC_OQT_FREEPG_V1_8822B) & \
+ BIT_MASK_AC_OQT_FREEPG_V1_8822B)
+
+#define BIT_SHIFT_EXQ_FREEPG_V1_8822B 0
+#define BIT_MASK_EXQ_FREEPG_V1_8822B 0xfff
+#define BIT_EXQ_FREEPG_V1_8822B(x) \
+ (((x) & BIT_MASK_EXQ_FREEPG_V1_8822B) << BIT_SHIFT_EXQ_FREEPG_V1_8822B)
+#define BIT_GET_EXQ_FREEPG_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_EXQ_FREEPG_V1_8822B) & BIT_MASK_EXQ_FREEPG_V1_8822B)
+
+/* 2 REG_SDIO_HTSFR_INFO_8822B */
+
+#define BIT_SHIFT_HTSFR1_8822B 16
+#define BIT_MASK_HTSFR1_8822B 0xffff
+#define BIT_HTSFR1_8822B(x) \
+ (((x) & BIT_MASK_HTSFR1_8822B) << BIT_SHIFT_HTSFR1_8822B)
+#define BIT_GET_HTSFR1_8822B(x) \
+ (((x) >> BIT_SHIFT_HTSFR1_8822B) & BIT_MASK_HTSFR1_8822B)
+
+#define BIT_SHIFT_HTSFR0_8822B 0
+#define BIT_MASK_HTSFR0_8822B 0xffff
+#define BIT_HTSFR0_8822B(x) \
+ (((x) & BIT_MASK_HTSFR0_8822B) << BIT_SHIFT_HTSFR0_8822B)
+#define BIT_GET_HTSFR0_8822B(x) \
+ (((x) >> BIT_SHIFT_HTSFR0_8822B) & BIT_MASK_HTSFR0_8822B)
+
+/* 2 REG_SDIO_HCPWM1_V2_8822B */
+#define BIT_TOGGLING_8822B BIT(7)
+#define BIT_ACK_8822B BIT(6)
+#define BIT_SYS_CLK_8822B BIT(0)
+
+/* 2 REG_SDIO_HCPWM2_V2_8822B */
+
+/* 2 REG_SDIO_INDIRECT_REG_CFG_8822B */
+#define BIT_INDIRECT_REG_RDY_8822B BIT(20)
+#define BIT_INDIRECT_REG_R_8822B BIT(19)
+#define BIT_INDIRECT_REG_W_8822B BIT(18)
+
+#define BIT_SHIFT_INDIRECT_REG_SIZE_8822B 16
+#define BIT_MASK_INDIRECT_REG_SIZE_8822B 0x3
+#define BIT_INDIRECT_REG_SIZE_8822B(x) \
+ (((x) & BIT_MASK_INDIRECT_REG_SIZE_8822B) \
+ << BIT_SHIFT_INDIRECT_REG_SIZE_8822B)
+#define BIT_GET_INDIRECT_REG_SIZE_8822B(x) \
+ (((x) >> BIT_SHIFT_INDIRECT_REG_SIZE_8822B) & \
+ BIT_MASK_INDIRECT_REG_SIZE_8822B)
+
+#define BIT_SHIFT_INDIRECT_REG_ADDR_8822B 0
+#define BIT_MASK_INDIRECT_REG_ADDR_8822B 0xffff
+#define BIT_INDIRECT_REG_ADDR_8822B(x) \
+ (((x) & BIT_MASK_INDIRECT_REG_ADDR_8822B) \
+ << BIT_SHIFT_INDIRECT_REG_ADDR_8822B)
+#define BIT_GET_INDIRECT_REG_ADDR_8822B(x) \
+ (((x) >> BIT_SHIFT_INDIRECT_REG_ADDR_8822B) & \
+ BIT_MASK_INDIRECT_REG_ADDR_8822B)
+
+/* 2 REG_SDIO_INDIRECT_REG_DATA_8822B */
+
+#define BIT_SHIFT_INDIRECT_REG_DATA_8822B 0
+#define BIT_MASK_INDIRECT_REG_DATA_8822B 0xffffffffL
+#define BIT_INDIRECT_REG_DATA_8822B(x) \
+ (((x) & BIT_MASK_INDIRECT_REG_DATA_8822B) \
+ << BIT_SHIFT_INDIRECT_REG_DATA_8822B)
+#define BIT_GET_INDIRECT_REG_DATA_8822B(x) \
+ (((x) >> BIT_SHIFT_INDIRECT_REG_DATA_8822B) & \
+ BIT_MASK_INDIRECT_REG_DATA_8822B)
+
+/* 2 REG_SDIO_H2C_8822B */
+
+#define BIT_SHIFT_SDIO_H2C_MSG_8822B 0
+#define BIT_MASK_SDIO_H2C_MSG_8822B 0xffffffffL
+#define BIT_SDIO_H2C_MSG_8822B(x) \
+ (((x) & BIT_MASK_SDIO_H2C_MSG_8822B) << BIT_SHIFT_SDIO_H2C_MSG_8822B)
+#define BIT_GET_SDIO_H2C_MSG_8822B(x) \
+ (((x) >> BIT_SHIFT_SDIO_H2C_MSG_8822B) & BIT_MASK_SDIO_H2C_MSG_8822B)
+
+/* 2 REG_SDIO_C2H_8822B */
+
+#define BIT_SHIFT_SDIO_C2H_MSG_8822B 0
+#define BIT_MASK_SDIO_C2H_MSG_8822B 0xffffffffL
+#define BIT_SDIO_C2H_MSG_8822B(x) \
+ (((x) & BIT_MASK_SDIO_C2H_MSG_8822B) << BIT_SHIFT_SDIO_C2H_MSG_8822B)
+#define BIT_GET_SDIO_C2H_MSG_8822B(x) \
+ (((x) >> BIT_SHIFT_SDIO_C2H_MSG_8822B) & BIT_MASK_SDIO_C2H_MSG_8822B)
+
+/* 2 REG_SDIO_HRPWM1_8822B */
+#define BIT_TOGGLING_8822B BIT(7)
+#define BIT_ACK_8822B BIT(6)
+#define BIT_32K_PERMISSION_8822B BIT(0)
+
+/* 2 REG_SDIO_HRPWM2_8822B */
+
+/* 2 REG_SDIO_HPS_CLKR_8822B */
+
+/* 2 REG_SDIO_BUS_CTRL_8822B */
+#define BIT_PAD_CLK_XHGE_EN_8822B BIT(3)
+#define BIT_INTER_CLK_EN_8822B BIT(2)
+#define BIT_EN_RPT_TXCRC_8822B BIT(1)
+#define BIT_DIS_RXDMA_STS_8822B BIT(0)
+
+/* 2 REG_SDIO_HSUS_CTRL_8822B */
+#define BIT_INTR_CTRL_8822B BIT(4)
+#define BIT_SDIO_VOLTAGE_8822B BIT(3)
+#define BIT_BYPASS_INIT_8822B BIT(2)
+#define BIT_HCI_RESUME_RDY_8822B BIT(1)
+#define BIT_HCI_SUS_REQ_8822B BIT(0)
+
+/* 2 REG_SDIO_RESPONSE_TIMER_8822B */
+
+#define BIT_SHIFT_CMDIN_2RESP_TIMER_8822B 0
+#define BIT_MASK_CMDIN_2RESP_TIMER_8822B 0xffff
+#define BIT_CMDIN_2RESP_TIMER_8822B(x) \
+ (((x) & BIT_MASK_CMDIN_2RESP_TIMER_8822B) \
+ << BIT_SHIFT_CMDIN_2RESP_TIMER_8822B)
+#define BIT_GET_CMDIN_2RESP_TIMER_8822B(x) \
+ (((x) >> BIT_SHIFT_CMDIN_2RESP_TIMER_8822B) & \
+ BIT_MASK_CMDIN_2RESP_TIMER_8822B)
+
+/* 2 REG_SDIO_CMD_CRC_8822B */
+
+#define BIT_SHIFT_SDIO_CMD_CRC_V1_8822B 0
+#define BIT_MASK_SDIO_CMD_CRC_V1_8822B 0xff
+#define BIT_SDIO_CMD_CRC_V1_8822B(x) \
+ (((x) & BIT_MASK_SDIO_CMD_CRC_V1_8822B) \
+ << BIT_SHIFT_SDIO_CMD_CRC_V1_8822B)
+#define BIT_GET_SDIO_CMD_CRC_V1_8822B(x) \
+ (((x) >> BIT_SHIFT_SDIO_CMD_CRC_V1_8822B) & \
+ BIT_MASK_SDIO_CMD_CRC_V1_8822B)
+
+/* 2 REG_SDIO_HSISR_8822B */
+#define BIT_DRV_WLAN_INT_CLR_8822B BIT(1)
+#define BIT_DRV_WLAN_INT_8822B BIT(0)
+
+/* 2 REG_SDIO_HSIMR_8822B */
+#define BIT_HISR_MASK_8822B BIT(0)
+
+/* 2 REG_SDIO_ERR_RPT_8822B */
+#define BIT_HR_FF_OVF_8822B BIT(6)
+#define BIT_HR_FF_UDN_8822B BIT(5)
+#define BIT_TXDMA_BUSY_ERR_8822B BIT(4)
+#define BIT_TXDMA_VLD_ERR_8822B BIT(3)
+#define BIT_QSEL_UNKNOWN_ERR_8822B BIT(2)
+#define BIT_QSEL_MIS_ERR_8822B BIT(1)
+#define BIT_SDIO_OVERRD_ERR_8822B BIT(0)
+
+/* 2 REG_SDIO_CMD_ERRCNT_8822B */
+
+#define BIT_SHIFT_CMD_CRC_ERR_CNT_8822B 0
+#define BIT_MASK_CMD_CRC_ERR_CNT_8822B 0xff
+#define BIT_CMD_CRC_ERR_CNT_8822B(x) \
+ (((x) & BIT_MASK_CMD_CRC_ERR_CNT_8822B) \
+ << BIT_SHIFT_CMD_CRC_ERR_CNT_8822B)
+#define BIT_GET_CMD_CRC_ERR_CNT_8822B(x) \
+ (((x) >> BIT_SHIFT_CMD_CRC_ERR_CNT_8822B) & \
+ BIT_MASK_CMD_CRC_ERR_CNT_8822B)
+
+/* 2 REG_SDIO_DATA_ERRCNT_8822B */
+
+#define BIT_SHIFT_DATA_CRC_ERR_CNT_8822B 0
+#define BIT_MASK_DATA_CRC_ERR_CNT_8822B 0xff
+#define BIT_DATA_CRC_ERR_CNT_8822B(x) \
+ (((x) & BIT_MASK_DATA_CRC_ERR_CNT_8822B) \
+ << BIT_SHIFT_DATA_CRC_ERR_CNT_8822B)
+#define BIT_GET_DATA_CRC_ERR_CNT_8822B(x) \
+ (((x) >> BIT_SHIFT_DATA_CRC_ERR_CNT_8822B) & \
+ BIT_MASK_DATA_CRC_ERR_CNT_8822B)
+
+/* 2 REG_SDIO_CMD_ERR_CONTENT_8822B */
+
+#define BIT_SHIFT_SDIO_CMD_ERR_CONTENT_8822B 0
+#define BIT_MASK_SDIO_CMD_ERR_CONTENT_8822B 0xffffffffffL
+#define BIT_SDIO_CMD_ERR_CONTENT_8822B(x) \
+ (((x) & BIT_MASK_SDIO_CMD_ERR_CONTENT_8822B) \
+ << BIT_SHIFT_SDIO_CMD_ERR_CONTENT_8822B)
+#define BIT_GET_SDIO_CMD_ERR_CONTENT_8822B(x) \
+ (((x) >> BIT_SHIFT_SDIO_CMD_ERR_CONTENT_8822B) & \
+ BIT_MASK_SDIO_CMD_ERR_CONTENT_8822B)
+
+/* 2 REG_SDIO_CRC_ERR_IDX_8822B */
+#define BIT_D3_CRC_ERR_8822B BIT(4)
+#define BIT_D2_CRC_ERR_8822B BIT(3)
+#define BIT_D1_CRC_ERR_8822B BIT(2)
+#define BIT_D0_CRC_ERR_8822B BIT(1)
+#define BIT_CMD_CRC_ERR_8822B BIT(0)
+
+/* 2 REG_SDIO_DATA_CRC_8822B */
+
+#define BIT_SHIFT_SDIO_DATA_CRC_8822B 0
+#define BIT_MASK_SDIO_DATA_CRC_8822B 0xff
+#define BIT_SDIO_DATA_CRC_8822B(x) \
+ (((x) & BIT_MASK_SDIO_DATA_CRC_8822B) << BIT_SHIFT_SDIO_DATA_CRC_8822B)
+#define BIT_GET_SDIO_DATA_CRC_8822B(x) \
+ (((x) >> BIT_SHIFT_SDIO_DATA_CRC_8822B) & BIT_MASK_SDIO_DATA_CRC_8822B)
+
+/* 2 REG_SDIO_DATA_REPLY_TIME_8822B */
+
+#define BIT_SHIFT_SDIO_DATA_REPLY_TIME_8822B 0
+#define BIT_MASK_SDIO_DATA_REPLY_TIME_8822B 0x7
+#define BIT_SDIO_DATA_REPLY_TIME_8822B(x) \
+ (((x) & BIT_MASK_SDIO_DATA_REPLY_TIME_8822B) \
+ << BIT_SHIFT_SDIO_DATA_REPLY_TIME_8822B)
+#define BIT_GET_SDIO_DATA_REPLY_TIME_8822B(x) \
+ (((x) >> BIT_SHIFT_SDIO_DATA_REPLY_TIME_8822B) & \
+ BIT_MASK_SDIO_DATA_REPLY_TIME_8822B)
+
+#endif
diff --git a/drivers/staging/rtlwifi/halmac/halmac_fw_info.h b/drivers/staging/rtlwifi/halmac/halmac_fw_info.h
new file mode 100644
index 0000000..dad8be3
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_fw_info.h
@@ -0,0 +1,122 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HALMAC_FW_INFO_H_
+#define _HALMAC_FW_INFO_H_
+
+#define H2C_FORMAT_VERSION 6
+
+#define H2C_ACK_HDR_CONTENT_LENGTH 8
+#define CFG_PARAMETER_ACK_CONTENT_LENGTH 16
+#define SCAN_STATUS_RPT_CONTENT_LENGTH 4
+#define C2H_DBG_HEADER_LENGTH 4
+#define C2H_DBG_CONTENT_MAX_LENGTH 228
+
+#define C2H_DBG_CONTENT_SEQ_OFFSET 1
+
+/* Rename from FW SysHalCom_Debug_RAM.h */
+#define FW_REG_H2CPKT_DONE_SEQ 0x1C8
+#define fw_reg_wow_reason 0x1C7
+
+enum halmac_data_type {
+ HALMAC_DATA_TYPE_MAC_REG = 0x00,
+ HALMAC_DATA_TYPE_BB_REG = 0x01,
+ HALMAC_DATA_TYPE_RADIO_A = 0x02,
+ HALMAC_DATA_TYPE_RADIO_B = 0x03,
+ HALMAC_DATA_TYPE_RADIO_C = 0x04,
+ HALMAC_DATA_TYPE_RADIO_D = 0x05,
+
+ HALMAC_DATA_TYPE_DRV_DEFINE_0 = 0x80,
+ HALMAC_DATA_TYPE_DRV_DEFINE_1 = 0x81,
+ HALMAC_DATA_TYPE_DRV_DEFINE_2 = 0x82,
+ HALMAC_DATA_TYPE_DRV_DEFINE_3 = 0x83,
+ HALMAC_DATA_TYPE_UNDEFINE = 0x7FFFFFFF,
+};
+
+enum halmac_packet_id {
+ HALMAC_PACKET_PROBE_REQ = 0x00,
+ HALMAC_PACKET_SYNC_BCN = 0x01,
+ HALMAC_PACKET_DISCOVERY_BCN = 0x02,
+
+ HALMAC_PACKET_UNDEFINE = 0x7FFFFFFF,
+};
+
+/* Channel Switch Action ID */
+enum halmac_cs_action_id {
+ HALMAC_CS_ACTION_NONE = 0x00,
+ HALMAC_CS_ACTIVE_SCAN = 0x01,
+ HALMAC_CS_NAN_NONMASTER_DW = 0x02,
+ HALMAC_CS_NAN_NONMASTER_NONDW = 0x03,
+ HALMAC_CS_NAN_MASTER_NONDW = 0x04,
+ HALMAC_CS_NAN_MASTER_DW = 0x05,
+
+ HALMAC_CS_ACTION_UNDEFINE = 0x7FFFFFFF,
+};
+
+/* Channel Switch Extra Action ID */
+enum halmac_cs_extra_action_id {
+ HALMAC_CS_EXTRA_ACTION_NONE = 0x00,
+ HALMAC_CS_EXTRA_UPDATE_PROBE = 0x01,
+ HALMAC_CS_EXTRA_UPDATE_BEACON = 0x02,
+
+ HALMAC_CS_EXTRA_ACTION_UNDEFINE = 0x7FFFFFFF,
+};
+
+enum halmac_h2c_return_code {
+ HALMAC_H2C_RETURN_SUCCESS = 0x00,
+ HALMAC_H2C_RETURN_CFG_ERR_LEN = 0x01,
+ HALMAC_H2C_RETURN_CFG_ERR_CMD = 0x02,
+
+ HALMAC_H2C_RETURN_EFUSE_ERR_DUMP = 0x03,
+
+ HALMAC_H2C_RETURN_DATAPACK_ERR_FULL = 0x04, /* DMEM buffer full */
+ HALMAC_H2C_RETURN_DATAPACK_ERR_ID = 0x05, /* Invalid pack id */
+
+ HALMAC_H2C_RETURN_RUN_ERR_EMPTY =
+ 0x06, /* No data in dedicated buffer */
+ HALMAC_H2C_RETURN_RUN_ERR_LEN = 0x07,
+ HALMAC_H2C_RETURN_RUN_ERR_CMD = 0x08,
+ HALMAC_H2C_RETURN_RUN_ERR_ID = 0x09, /* Invalid pack id */
+
+ HALMAC_H2C_RETURN_PACKET_ERR_FULL = 0x0A, /* DMEM buffer full */
+ HALMAC_H2C_RETURN_PACKET_ERR_ID = 0x0B, /* Invalid packet id */
+
+ HALMAC_H2C_RETURN_SCAN_ERR_FULL = 0x0C, /* DMEM buffer full */
+ HALMAC_H2C_RETURN_SCAN_ERR_PHYDM = 0x0D, /* PHYDM API return fail */
+
+ HALMAC_H2C_RETURN_ORIG_ERR_ID = 0x0E, /* Invalid original H2C cmd id */
+
+ HALMAC_H2C_RETURN_UNDEFINE = 0x7FFFFFFF,
+};
+
+enum halmac_scan_report_code {
+ HALMAC_SCAN_REPORT_DONE = 0x00,
+ HALMAC_SCAN_REPORT_ERR_PHYDM = 0x01, /* PHYDM API return fail */
+ HALMAC_SCAN_REPORT_ERR_ID = 0x02, /* Invalid ActionID */
+ HALMAC_SCAN_REPORT_ERR_TX = 0x03, /* Tx RsvdPage fail */
+
+ HALMAC_SCAN_REPORT_UNDEFINE = 0x7FFFFFFF,
+};
+
+#endif
diff --git a/drivers/staging/rtlwifi/halmac/halmac_fw_offload_c2h_nic.h b/drivers/staging/rtlwifi/halmac/halmac_fw_offload_c2h_nic.h
new file mode 100644
index 0000000..0e99967
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_fw_offload_c2h_nic.h
@@ -0,0 +1,184 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HAL_FWOFFLOADC2HFORMAT_H2C_C2H_NIC_H_
+#define _HAL_FWOFFLOADC2HFORMAT_H2C_C2H_NIC_H_
+#define C2H_SUB_CMD_ID_C2H_DBG 0X00
+#define C2H_SUB_CMD_ID_BT_COEX_INFO 0X02
+#define C2H_SUB_CMD_ID_SCAN_STATUS_RPT 0X03
+#define C2H_SUB_CMD_ID_H2C_ACK_HDR 0X01
+#define C2H_SUB_CMD_ID_CFG_PARAMETER_ACK 0X01
+#define C2H_SUB_CMD_ID_BT_COEX_ACK 0X01
+#define C2H_SUB_CMD_ID_DUMP_PHYSICAL_EFUSE_ACK 0X01
+#define C2H_SUB_CMD_ID_UPDATE_PACKET_ACK 0X01
+#define C2H_SUB_CMD_ID_UPDATE_DATAPACK_ACK 0X01
+#define C2H_SUB_CMD_ID_RUN_DATAPACK_ACK 0X01
+#define C2H_SUB_CMD_ID_CHANNEL_SWITCH_ACK 0X01
+#define C2H_SUB_CMD_ID_IQK_ACK 0X01
+#define C2H_SUB_CMD_ID_POWER_TRACKING_ACK 0X01
+#define C2H_SUB_CMD_ID_PSD_ACK 0X01
+#define C2H_SUB_CMD_ID_PSD_DATA 0X04
+#define C2H_SUB_CMD_ID_EFUSE_DATA 0X05
+#define C2H_SUB_CMD_ID_IQK_DATA 0X06
+#define C2H_SUB_CMD_ID_C2H_PKT_FTM_DBG 0X07
+#define C2H_SUB_CMD_ID_C2H_PKT_FTM_2_DBG 0X08
+#define C2H_SUB_CMD_ID_C2H_PKT_FTM_3_DBG 0X09
+#define C2H_SUB_CMD_ID_C2H_PKT_FTM_4_DBG 0X0A
+#define C2H_SUB_CMD_ID_FTMACKRPT_HDL_DBG 0X0B
+#define C2H_SUB_CMD_ID_FTMC2H_RPT 0X0C
+#define C2H_SUB_CMD_ID_DRVFTMC2H_RPT 0X0D
+#define C2H_SUB_CMD_ID_C2H_PKT_FTM_5_DBG 0X0E
+#define C2H_SUB_CMD_ID_CCX_RPT 0X0F
+#define C2H_SUB_CMD_ID_C2H_PKT_NAN_RPT 0X10
+#define H2C_SUB_CMD_ID_CFG_PARAMETER_ACK SUB_CMD_ID_CFG_PARAMETER
+#define H2C_SUB_CMD_ID_BT_COEX_ACK SUB_CMD_ID_BT_COEX
+#define H2C_SUB_CMD_ID_DUMP_PHYSICAL_EFUSE_ACK SUB_CMD_ID_DUMP_PHYSICAL_EFUSE
+#define H2C_SUB_CMD_ID_UPDATE_PACKET_ACK SUB_CMD_ID_UPDATE_PACKET
+#define H2C_SUB_CMD_ID_UPDATE_DATAPACK_ACK SUB_CMD_ID_UPDATE_DATAPACK
+#define H2C_SUB_CMD_ID_RUN_DATAPACK_ACK SUB_CMD_ID_RUN_DATAPACK
+#define H2C_SUB_CMD_ID_CHANNEL_SWITCH_ACK SUB_CMD_ID_CHANNEL_SWITCH
+#define H2C_SUB_CMD_ID_IQK_ACK SUB_CMD_ID_IQK
+#define H2C_SUB_CMD_ID_POWER_TRACKING_ACK SUB_CMD_ID_POWER_TRACKING
+#define H2C_SUB_CMD_ID_PSD_ACK SUB_CMD_ID_PSD
+#define H2C_SUB_CMD_ID_CCX_RPT SUB_CMD_ID_CCX_RPT
+#define H2C_CMD_ID_CFG_PARAMETER_ACK 0XFF
+#define H2C_CMD_ID_BT_COEX_ACK 0XFF
+#define H2C_CMD_ID_DUMP_PHYSICAL_EFUSE_ACK 0XFF
+#define H2C_CMD_ID_UPDATE_PACKET_ACK 0XFF
+#define H2C_CMD_ID_UPDATE_DATAPACK_ACK 0XFF
+#define H2C_CMD_ID_RUN_DATAPACK_ACK 0XFF
+#define H2C_CMD_ID_CHANNEL_SWITCH_ACK 0XFF
+#define H2C_CMD_ID_IQK_ACK 0XFF
+#define H2C_CMD_ID_POWER_TRACKING_ACK 0XFF
+#define H2C_CMD_ID_PSD_ACK 0XFF
+#define H2C_CMD_ID_CCX_RPT 0XFF
+#define C2H_HDR_GET_CMD_ID(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 0, 8)
+#define C2H_HDR_SET_CMD_ID(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 0, 8, __value)
+#define C2H_HDR_GET_SEQ(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 8, 8)
+#define C2H_HDR_SET_SEQ(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 8, 8, __value)
+#define C2H_HDR_GET_C2H_SUB_CMD_ID(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 16, 8)
+#define C2H_HDR_SET_C2H_SUB_CMD_ID(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 16, 8, __value)
+#define C2H_HDR_GET_LEN(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 24, 8)
+#define C2H_HDR_SET_LEN(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 24, 8, __value)
+#define C2H_DBG_GET_DBG_MSG(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X04, 0, 8)
+#define C2H_DBG_SET_DBG_MSG(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 0, 8, __value)
+#define BT_COEX_INFO_GET_DATA_START(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X04, 0, 8)
+#define BT_COEX_INFO_SET_DATA_START(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 0, 8, __value)
+#define SCAN_STATUS_RPT_GET_H2C_RETURN_CODE(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X04, 0, 8)
+#define SCAN_STATUS_RPT_SET_H2C_RETURN_CODE(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 0, 8, __value)
+#define SCAN_STATUS_RPT_GET_H2C_SEQ(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X04, 16, 16)
+#define SCAN_STATUS_RPT_SET_H2C_SEQ(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 16, 16, __value)
+#define H2C_ACK_HDR_GET_H2C_RETURN_CODE(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X04, 0, 8)
+#define H2C_ACK_HDR_SET_H2C_RETURN_CODE(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 0, 8, __value)
+#define H2C_ACK_HDR_GET_H2C_CMD_ID(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X04, 8, 8)
+#define H2C_ACK_HDR_SET_H2C_CMD_ID(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 8, 8, __value)
+#define H2C_ACK_HDR_GET_H2C_SUB_CMD_ID(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X04, 16, 16)
+#define H2C_ACK_HDR_SET_H2C_SUB_CMD_ID(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 16, 16, __value)
+#define H2C_ACK_HDR_GET_H2C_SEQ(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X08, 0, 16)
+#define H2C_ACK_HDR_SET_H2C_SEQ(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X08, 0, 16, __value)
+#define CFG_PARAMETER_ACK_GET_OFFSET_ACCUMULATION(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0XC, 0, 32)
+#define CFG_PARAMETER_ACK_SET_OFFSET_ACCUMULATION(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0XC, 0, 32, __value)
+#define CFG_PARAMETER_ACK_GET_VALUE_ACCUMULATION(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X10, 0, 32)
+#define CFG_PARAMETER_ACK_SET_VALUE_ACCUMULATION(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X10, 0, 32, __value)
+#define BT_COEX_ACK_GET_DATA_START(__c2h) LE_BITS_TO_4BYTE(__c2h + 0XC, 0, 8)
+#define BT_COEX_ACK_SET_DATA_START(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0XC, 0, 8, __value)
+#define PSD_DATA_GET_SEGMENT_ID(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X04, 0, 7)
+#define PSD_DATA_SET_SEGMENT_ID(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 0, 7, __value)
+#define PSD_DATA_GET_END_SEGMENT(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X04, 7, 1)
+#define PSD_DATA_SET_END_SEGMENT(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 7, 1, __value)
+#define PSD_DATA_GET_SEGMENT_SIZE(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X04, 8, 8)
+#define PSD_DATA_SET_SEGMENT_SIZE(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 8, 8, __value)
+#define PSD_DATA_GET_TOTAL_SIZE(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X04, 16, 16)
+#define PSD_DATA_SET_TOTAL_SIZE(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 16, 16, __value)
+#define PSD_DATA_GET_H2C_SEQ(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X8, 0, 16)
+#define PSD_DATA_SET_H2C_SEQ(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X8, 0, 16, __value)
+#define PSD_DATA_GET_DATA_START(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X8, 16, 8)
+#define PSD_DATA_SET_DATA_START(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X8, 16, 8, __value)
+#define EFUSE_DATA_GET_SEGMENT_ID(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X04, 0, 7)
+#define EFUSE_DATA_SET_SEGMENT_ID(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 0, 7, __value)
+#define EFUSE_DATA_GET_END_SEGMENT(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X04, 7, 1)
+#define EFUSE_DATA_SET_END_SEGMENT(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 7, 1, __value)
+#define EFUSE_DATA_GET_SEGMENT_SIZE(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X04, 8, 8)
+#define EFUSE_DATA_SET_SEGMENT_SIZE(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 8, 8, __value)
+#define EFUSE_DATA_GET_TOTAL_SIZE(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X04, 16, 16)
+#define EFUSE_DATA_SET_TOTAL_SIZE(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 16, 16, __value)
+#define EFUSE_DATA_GET_H2C_SEQ(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X8, 0, 16)
+#define EFUSE_DATA_SET_H2C_SEQ(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X8, 0, 16, __value)
+#define EFUSE_DATA_GET_DATA_START(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X8, 16, 8)
+#define EFUSE_DATA_SET_DATA_START(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X8, 16, 8, __value)
+#define IQK_DATA_GET_SEGMENT_ID(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X04, 0, 7)
+#define IQK_DATA_SET_SEGMENT_ID(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 0, 7, __value)
+#define IQK_DATA_GET_END_SEGMENT(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X04, 7, 1)
+#define IQK_DATA_SET_END_SEGMENT(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 7, 1, __value)
+#define IQK_DATA_GET_SEGMENT_SIZE(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X04, 8, 8)
+#define IQK_DATA_SET_SEGMENT_SIZE(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 8, 8, __value)
+#define IQK_DATA_GET_TOTAL_SIZE(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X04, 16, 16)
+#define IQK_DATA_SET_TOTAL_SIZE(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 16, 16, __value)
+#define IQK_DATA_GET_H2C_SEQ(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X8, 0, 16)
+#define IQK_DATA_SET_H2C_SEQ(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X8, 0, 16, __value)
+#define IQK_DATA_GET_DATA_START(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X8, 16, 8)
+#define IQK_DATA_SET_DATA_START(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X8, 16, 8, __value)
+#define CCX_RPT_GET_CCX_RPT(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X4, 0, 129)
+#define CCX_RPT_SET_CCX_RPT(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X4, 0, 129, __value)
+#endif
diff --git a/drivers/staging/rtlwifi/halmac/halmac_fw_offload_h2c_nic.h b/drivers/staging/rtlwifi/halmac/halmac_fw_offload_h2c_nic.h
new file mode 100644
index 0000000..7adc3cd
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_fw_offload_h2c_nic.h
@@ -0,0 +1,515 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HAL_FWOFFLOADH2CFORMAT_H2C_C2H_NIC_H_
+#define _HAL_FWOFFLOADH2CFORMAT_H2C_C2H_NIC_H_
+#define CMD_ID_FW_OFFLOAD_H2C 0XFF
+#define CMD_ID_CHANNEL_SWITCH 0XFF
+#define CMD_ID_DUMP_PHYSICAL_EFUSE 0XFF
+#define CMD_ID_UPDATE_BEACON_PARSING_INFO 0XFF
+#define CMD_ID_CFG_PARAMETER 0XFF
+#define CMD_ID_UPDATE_DATAPACK 0XFF
+#define CMD_ID_RUN_DATAPACK 0XFF
+#define CMD_ID_DOWNLOAD_FLASH 0XFF
+#define CMD_ID_UPDATE_PACKET 0XFF
+#define CMD_ID_GENERAL_INFO 0XFF
+#define CMD_ID_IQK 0XFF
+#define CMD_ID_POWER_TRACKING 0XFF
+#define CMD_ID_PSD 0XFF
+#define CMD_ID_P2PPS 0XFF
+#define CMD_ID_BT_COEX 0XFF
+#define CMD_ID_NAN_CTRL 0XFF
+#define CMD_ID_NAN_CHANNEL_PLAN_0 0XFF
+#define CMD_ID_NAN_CHANNEL_PLAN_1 0XFF
+#define CATEGORY_H2C_CMD_HEADER 0X00
+#define CATEGORY_FW_OFFLOAD_H2C 0X01
+#define CATEGORY_CHANNEL_SWITCH 0X01
+#define CATEGORY_DUMP_PHYSICAL_EFUSE 0X01
+#define CATEGORY_UPDATE_BEACON_PARSING_INFO 0X01
+#define CATEGORY_CFG_PARAMETER 0X01
+#define CATEGORY_UPDATE_DATAPACK 0X01
+#define CATEGORY_RUN_DATAPACK 0X01
+#define CATEGORY_DOWNLOAD_FLASH 0X01
+#define CATEGORY_UPDATE_PACKET 0X01
+#define CATEGORY_GENERAL_INFO 0X01
+#define CATEGORY_IQK 0X01
+#define CATEGORY_POWER_TRACKING 0X01
+#define CATEGORY_PSD 0X01
+#define CATEGORY_P2PPS 0X01
+#define CATEGORY_BT_COEX 0X01
+#define CATEGORY_NAN_CTRL 0X01
+#define CATEGORY_NAN_CHANNEL_PLAN_0 0X01
+#define CATEGORY_NAN_CHANNEL_PLAN_1 0X01
+#define SUB_CMD_ID_CHANNEL_SWITCH 0X02
+#define SUB_CMD_ID_DUMP_PHYSICAL_EFUSE 0X03
+#define SUB_CMD_ID_UPDATE_BEACON_PARSING_INFO 0X05
+#define SUB_CMD_ID_CFG_PARAMETER 0X08
+#define SUB_CMD_ID_UPDATE_DATAPACK 0X09
+#define SUB_CMD_ID_RUN_DATAPACK 0X0A
+#define SUB_CMD_ID_DOWNLOAD_FLASH 0X0B
+#define SUB_CMD_ID_UPDATE_PACKET 0X0C
+#define SUB_CMD_ID_GENERAL_INFO 0X0D
+#define SUB_CMD_ID_IQK 0X0E
+#define SUB_CMD_ID_POWER_TRACKING 0X0F
+#define SUB_CMD_ID_PSD 0X10
+#define SUB_CMD_ID_P2PPS 0X24
+#define SUB_CMD_ID_BT_COEX 0X60
+#define SUB_CMD_ID_NAN_CTRL 0XB2
+#define SUB_CMD_ID_NAN_CHANNEL_PLAN_0 0XB4
+#define SUB_CMD_ID_NAN_CHANNEL_PLAN_1 0XB5
+#define H2C_CMD_HEADER_GET_CATEGORY(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 7)
+#define H2C_CMD_HEADER_SET_CATEGORY(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 7, __value)
+#define H2C_CMD_HEADER_GET_ACK(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 7, 1)
+#define H2C_CMD_HEADER_SET_ACK(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 7, 1, __value)
+#define H2C_CMD_HEADER_GET_TOTAL_LEN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 0, 16)
+#define H2C_CMD_HEADER_SET_TOTAL_LEN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 0, 16, __value)
+#define H2C_CMD_HEADER_GET_SEQ_NUM(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X04, 16, 16)
+#define H2C_CMD_HEADER_SET_SEQ_NUM(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 16, 16, __value)
+#define FW_OFFLOAD_H2C_GET_CATEGORY(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 7)
+#define FW_OFFLOAD_H2C_SET_CATEGORY(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 7, __value)
+#define FW_OFFLOAD_H2C_GET_ACK(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 7, 1)
+#define FW_OFFLOAD_H2C_SET_ACK(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 7, 1, __value)
+#define FW_OFFLOAD_H2C_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 8)
+#define FW_OFFLOAD_H2C_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 8, __value)
+#define FW_OFFLOAD_H2C_GET_SUB_CMD_ID(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 16)
+#define FW_OFFLOAD_H2C_SET_SUB_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 16, __value)
+#define FW_OFFLOAD_H2C_GET_TOTAL_LEN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 0, 16)
+#define FW_OFFLOAD_H2C_SET_TOTAL_LEN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 0, 16, __value)
+#define FW_OFFLOAD_H2C_GET_SEQ_NUM(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X04, 16, 16)
+#define FW_OFFLOAD_H2C_SET_SEQ_NUM(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 16, 16, __value)
+#define CHANNEL_SWITCH_GET_SWITCH_START(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X08, 0, 1)
+#define CHANNEL_SWITCH_SET_SWITCH_START(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 0, 1, __value)
+#define CHANNEL_SWITCH_GET_DEST_CH_EN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X08, 1, 1)
+#define CHANNEL_SWITCH_SET_DEST_CH_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 1, 1, __value)
+#define CHANNEL_SWITCH_GET_ABSOLUTE_TIME(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X08, 2, 1)
+#define CHANNEL_SWITCH_SET_ABSOLUTE_TIME(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 2, 1, __value)
+#define CHANNEL_SWITCH_GET_PERIODIC_OPTION(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X08, 3, 2)
+#define CHANNEL_SWITCH_SET_PERIODIC_OPTION(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 3, 2, __value)
+#define CHANNEL_SWITCH_GET_CHANNEL_INFO_LOC(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X08, 8, 8)
+#define CHANNEL_SWITCH_SET_CHANNEL_INFO_LOC(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 8, 8, __value)
+#define CHANNEL_SWITCH_GET_CHANNEL_NUM(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X08, 16, 8)
+#define CHANNEL_SWITCH_SET_CHANNEL_NUM(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 16, 8, __value)
+#define CHANNEL_SWITCH_GET_PRI_CH_IDX(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X08, 24, 4)
+#define CHANNEL_SWITCH_SET_PRI_CH_IDX(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 24, 4, __value)
+#define CHANNEL_SWITCH_GET_DEST_BW(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 28, 4)
+#define CHANNEL_SWITCH_SET_DEST_BW(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 28, 4, __value)
+#define CHANNEL_SWITCH_GET_DEST_CH(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X0C, 0, 8)
+#define CHANNEL_SWITCH_SET_DEST_CH(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X0C, 0, 8, __value)
+#define CHANNEL_SWITCH_GET_NORMAL_PERIOD(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X0C, 8, 8)
+#define CHANNEL_SWITCH_SET_NORMAL_PERIOD(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X0C, 8, 8, __value)
+#define CHANNEL_SWITCH_GET_SLOW_PERIOD(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X0C, 16, 8)
+#define CHANNEL_SWITCH_SET_SLOW_PERIOD(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X0C, 16, 8, __value)
+#define CHANNEL_SWITCH_GET_NORMAL_CYCLE(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X0C, 24, 8)
+#define CHANNEL_SWITCH_SET_NORMAL_CYCLE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X0C, 24, 8, __value)
+#define CHANNEL_SWITCH_GET_TSF_HIGH(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X10, 0, 32)
+#define CHANNEL_SWITCH_SET_TSF_HIGH(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X10, 0, 32, __value)
+#define CHANNEL_SWITCH_GET_TSF_LOW(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X14, 0, 32)
+#define CHANNEL_SWITCH_SET_TSF_LOW(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X14, 0, 32, __value)
+#define CHANNEL_SWITCH_GET_CHANNEL_INFO_SIZE(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X18, 0, 16)
+#define CHANNEL_SWITCH_SET_CHANNEL_INFO_SIZE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X18, 0, 16, __value)
+#define UPDATE_BEACON_PARSING_INFO_GET_FUNC_EN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X08, 0, 1)
+#define UPDATE_BEACON_PARSING_INFO_SET_FUNC_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 0, 1, __value)
+#define UPDATE_BEACON_PARSING_INFO_GET_SIZE_TH(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X08, 8, 4)
+#define UPDATE_BEACON_PARSING_INFO_SET_SIZE_TH(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 8, 4, __value)
+#define UPDATE_BEACON_PARSING_INFO_GET_TIMEOUT(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X08, 12, 4)
+#define UPDATE_BEACON_PARSING_INFO_SET_TIMEOUT(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 12, 4, __value)
+#define UPDATE_BEACON_PARSING_INFO_GET_IE_ID_BMP_0(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X0C, 0, 32)
+#define UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_0(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X0C, 0, 32, __value)
+#define UPDATE_BEACON_PARSING_INFO_GET_IE_ID_BMP_1(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X10, 0, 32)
+#define UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_1(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X10, 0, 32, __value)
+#define UPDATE_BEACON_PARSING_INFO_GET_IE_ID_BMP_2(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X14, 0, 32)
+#define UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_2(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X14, 0, 32, __value)
+#define UPDATE_BEACON_PARSING_INFO_GET_IE_ID_BMP_3(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X18, 0, 32)
+#define UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_3(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X18, 0, 32, __value)
+#define UPDATE_BEACON_PARSING_INFO_GET_IE_ID_BMP_4(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X1C, 0, 32)
+#define UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_4(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X1C, 0, 32, __value)
+#define CFG_PARAMETER_GET_NUM(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 0, 16)
+#define CFG_PARAMETER_SET_NUM(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 0, 16, __value)
+#define CFG_PARAMETER_GET_INIT_CASE(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 16, 1)
+#define CFG_PARAMETER_SET_INIT_CASE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 16, 1, __value)
+#define CFG_PARAMETER_GET_PHY_PARAMETER_LOC(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X08, 24, 8)
+#define CFG_PARAMETER_SET_PHY_PARAMETER_LOC(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 24, 8, __value)
+#define UPDATE_DATAPACK_GET_SIZE(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 0, 16)
+#define UPDATE_DATAPACK_SET_SIZE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 0, 16, __value)
+#define UPDATE_DATAPACK_GET_DATAPACK_ID(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X08, 16, 8)
+#define UPDATE_DATAPACK_SET_DATAPACK_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 16, 8, __value)
+#define UPDATE_DATAPACK_GET_DATAPACK_LOC(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X08, 24, 8)
+#define UPDATE_DATAPACK_SET_DATAPACK_LOC(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 24, 8, __value)
+#define UPDATE_DATAPACK_GET_DATAPACK_SEGMENT(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X0C, 0, 8)
+#define UPDATE_DATAPACK_SET_DATAPACK_SEGMENT(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X0C, 0, 8, __value)
+#define UPDATE_DATAPACK_GET_END_SEGMENT(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X0C, 8, 1)
+#define UPDATE_DATAPACK_SET_END_SEGMENT(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X0C, 8, 1, __value)
+#define RUN_DATAPACK_GET_DATAPACK_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 0, 8)
+#define RUN_DATAPACK_SET_DATAPACK_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 0, 8, __value)
+#define DOWNLOAD_FLASH_GET_SPI_CMD(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 0, 8)
+#define DOWNLOAD_FLASH_SET_SPI_CMD(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 0, 8, __value)
+#define DOWNLOAD_FLASH_GET_LOCATION(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 8, 16)
+#define DOWNLOAD_FLASH_SET_LOCATION(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 8, 16, __value)
+#define DOWNLOAD_FLASH_GET_SIZE(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X0C, 0, 32)
+#define DOWNLOAD_FLASH_SET_SIZE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X0C, 0, 32, __value)
+#define DOWNLOAD_FLASH_GET_START_ADDR(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X10, 0, 32)
+#define DOWNLOAD_FLASH_SET_START_ADDR(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X10, 0, 32, __value)
+#define UPDATE_PACKET_GET_SIZE(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 0, 16)
+#define UPDATE_PACKET_SET_SIZE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 0, 16, __value)
+#define UPDATE_PACKET_GET_PACKET_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 16, 8)
+#define UPDATE_PACKET_SET_PACKET_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 16, 8, __value)
+#define UPDATE_PACKET_GET_PACKET_LOC(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X08, 24, 8)
+#define UPDATE_PACKET_SET_PACKET_LOC(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 24, 8, __value)
+#define GENERAL_INFO_GET_REF_TYPE(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 0, 8)
+#define GENERAL_INFO_SET_REF_TYPE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 0, 8, __value)
+#define GENERAL_INFO_GET_RF_TYPE(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 8, 9)
+#define GENERAL_INFO_SET_RF_TYPE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 8, 9, __value)
+#define GENERAL_INFO_GET_FW_TX_BOUNDARY(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X08, 16, 8)
+#define GENERAL_INFO_SET_FW_TX_BOUNDARY(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 16, 8, __value)
+#define IQK_GET_CLEAR(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 0, 1)
+#define IQK_SET_CLEAR(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 0, 1, __value)
+#define IQK_GET_SEGMENT_IQK(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 1, 1)
+#define IQK_SET_SEGMENT_IQK(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 1, 1, __value)
+#define POWER_TRACKING_GET_ENABLE_A(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 0, 1)
+#define POWER_TRACKING_SET_ENABLE_A(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 0, 1, __value)
+#define POWER_TRACKING_GET_ENABLE_B(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 1, 1)
+#define POWER_TRACKING_SET_ENABLE_B(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 1, 1, __value)
+#define POWER_TRACKING_GET_ENABLE_C(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 2, 1)
+#define POWER_TRACKING_SET_ENABLE_C(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 2, 1, __value)
+#define POWER_TRACKING_GET_ENABLE_D(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 3, 1)
+#define POWER_TRACKING_SET_ENABLE_D(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 3, 1, __value)
+#define POWER_TRACKING_GET_TYPE(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 4, 3)
+#define POWER_TRACKING_SET_TYPE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 4, 3, __value)
+#define POWER_TRACKING_GET_BBSWING_INDEX(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X08, 8, 8)
+#define POWER_TRACKING_SET_BBSWING_INDEX(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 8, 8, __value)
+#define POWER_TRACKING_GET_TX_PWR_INDEX_A(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X0C, 0, 8)
+#define POWER_TRACKING_SET_TX_PWR_INDEX_A(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X0C, 0, 8, __value)
+#define POWER_TRACKING_GET_PWR_TRACKING_OFFSET_VALUE_A(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X0C, 8, 8)
+#define POWER_TRACKING_SET_PWR_TRACKING_OFFSET_VALUE_A(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X0C, 8, 8, __value)
+#define POWER_TRACKING_GET_TSSI_VALUE_A(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X0C, 16, 8)
+#define POWER_TRACKING_SET_TSSI_VALUE_A(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X0C, 16, 8, __value)
+#define POWER_TRACKING_GET_TX_PWR_INDEX_B(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X10, 0, 8)
+#define POWER_TRACKING_SET_TX_PWR_INDEX_B(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X10, 0, 8, __value)
+#define POWER_TRACKING_GET_PWR_TRACKING_OFFSET_VALUE_B(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X10, 8, 8)
+#define POWER_TRACKING_SET_PWR_TRACKING_OFFSET_VALUE_B(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X10, 8, 8, __value)
+#define POWER_TRACKING_GET_TSSI_VALUE_B(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X10, 16, 8)
+#define POWER_TRACKING_SET_TSSI_VALUE_B(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X10, 16, 8, __value)
+#define POWER_TRACKING_GET_TX_PWR_INDEX_C(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X14, 0, 8)
+#define POWER_TRACKING_SET_TX_PWR_INDEX_C(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X14, 0, 8, __value)
+#define POWER_TRACKING_GET_PWR_TRACKING_OFFSET_VALUE_C(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X14, 8, 8)
+#define POWER_TRACKING_SET_PWR_TRACKING_OFFSET_VALUE_C(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X14, 8, 8, __value)
+#define POWER_TRACKING_GET_TSSI_VALUE_C(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X14, 16, 8)
+#define POWER_TRACKING_SET_TSSI_VALUE_C(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X14, 16, 8, __value)
+#define POWER_TRACKING_GET_TX_PWR_INDEX_D(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X18, 0, 8)
+#define POWER_TRACKING_SET_TX_PWR_INDEX_D(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X18, 0, 8, __value)
+#define POWER_TRACKING_GET_PWR_TRACKING_OFFSET_VALUE_D(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X18, 8, 8)
+#define POWER_TRACKING_SET_PWR_TRACKING_OFFSET_VALUE_D(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X18, 8, 8, __value)
+#define POWER_TRACKING_GET_TSSI_VALUE_D(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X18, 16, 8)
+#define POWER_TRACKING_SET_TSSI_VALUE_D(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X18, 16, 8, __value)
+#define PSD_GET_START_PSD(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 0, 16)
+#define PSD_SET_START_PSD(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 0, 16, __value)
+#define PSD_GET_END_PSD(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 16, 16)
+#define PSD_SET_END_PSD(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 16, 16, __value)
+#define P2PPS_GET_OFFLOAD_EN(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 0, 1)
+#define P2PPS_SET_OFFLOAD_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 0, 1, __value)
+#define P2PPS_GET_ROLE(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 1, 1)
+#define P2PPS_SET_ROLE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 1, 1, __value)
+#define P2PPS_GET_CTWINDOW_EN(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 2, 1)
+#define P2PPS_SET_CTWINDOW_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 2, 1, __value)
+#define P2PPS_GET_NOA_EN(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 3, 1)
+#define P2PPS_SET_NOA_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 3, 1, __value)
+#define P2PPS_GET_NOA_SEL(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 4, 1)
+#define P2PPS_SET_NOA_SEL(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 4, 1, __value)
+#define P2PPS_GET_ALLSTASLEEP(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 5, 1)
+#define P2PPS_SET_ALLSTASLEEP(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 5, 1, __value)
+#define P2PPS_GET_DISCOVERY(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 6, 1)
+#define P2PPS_SET_DISCOVERY(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 6, 1, __value)
+#define P2PPS_GET_P2P_PORT_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 8, 8)
+#define P2PPS_SET_P2P_PORT_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 8, 8, __value)
+#define P2PPS_GET_P2P_GROUP(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 16, 8)
+#define P2PPS_SET_P2P_GROUP(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 16, 8, __value)
+#define P2PPS_GET_P2P_MACID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 24, 8)
+#define P2PPS_SET_P2P_MACID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 24, 8, __value)
+#define P2PPS_GET_CTWINDOW_LENGTH(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X0C, 0, 8)
+#define P2PPS_SET_CTWINDOW_LENGTH(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X0C, 0, 8, __value)
+#define P2PPS_GET_NOA_DURATION_PARA(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X10, 0, 32)
+#define P2PPS_SET_NOA_DURATION_PARA(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X10, 0, 32, __value)
+#define P2PPS_GET_NOA_INTERVAL_PARA(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X14, 0, 32)
+#define P2PPS_SET_NOA_INTERVAL_PARA(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X14, 0, 32, __value)
+#define P2PPS_GET_NOA_START_TIME_PARA(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X18, 0, 32)
+#define P2PPS_SET_NOA_START_TIME_PARA(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X18, 0, 32, __value)
+#define P2PPS_GET_NOA_COUNT_PARA(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X1C, 0, 32)
+#define P2PPS_SET_NOA_COUNT_PARA(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X1C, 0, 32, __value)
+#define BT_COEX_GET_DATA_START(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 0, 8)
+#define BT_COEX_SET_DATA_START(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 0, 8, __value)
+#define NAN_CTRL_GET_NAN_EN(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 0, 2)
+#define NAN_CTRL_SET_NAN_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 0, 2, __value)
+#define NAN_CTRL_GET_SUPPORT_BAND(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 8, 2)
+#define NAN_CTRL_SET_SUPPORT_BAND(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 8, 2, __value)
+#define NAN_CTRL_GET_DISABLE_2G_DISC_BCN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X08, 10, 1)
+#define NAN_CTRL_SET_DISABLE_2G_DISC_BCN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 10, 1, __value)
+#define NAN_CTRL_GET_DISABLE_5G_DISC_BCN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X08, 11, 1)
+#define NAN_CTRL_SET_DISABLE_5G_DISC_BCN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 11, 1, __value)
+#define NAN_CTRL_GET_BCN_RSVD_PAGE_OFFSET(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X08, 16, 8)
+#define NAN_CTRL_SET_BCN_RSVD_PAGE_OFFSET(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 16, 8, __value)
+#define NAN_CTRL_GET_CHANNEL_2G(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X08, 24, 8)
+#define NAN_CTRL_SET_CHANNEL_2G(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 24, 8, __value)
+#define NAN_CTRL_GET_CHANNEL_5G(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X0C, 0, 8)
+#define NAN_CTRL_SET_CHANNEL_5G(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X0C, 0, 8, __value)
+#define NAN_CHANNEL_PLAN_0_GET_CHANNEL_NUMBER_0(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X08, 0, 8)
+#define NAN_CHANNEL_PLAN_0_SET_CHANNEL_NUMBER_0(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 0, 8, __value)
+#define NAN_CHANNEL_PLAN_0_GET_UNPAUSE_MACID_0(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X08, 8, 8)
+#define NAN_CHANNEL_PLAN_0_SET_UNPAUSE_MACID_0(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 8, 8, __value)
+#define NAN_CHANNEL_PLAN_0_GET_START_TIME_SLOT_0(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X0C, 0, 16)
+#define NAN_CHANNEL_PLAN_0_SET_START_TIME_SLOT_0(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X0C, 0, 16, __value)
+#define NAN_CHANNEL_PLAN_0_GET_DURATION_0(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X0C, 16, 16)
+#define NAN_CHANNEL_PLAN_0_SET_DURATION_0(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X0C, 16, 16, __value)
+#define NAN_CHANNEL_PLAN_0_GET_CHANNEL_NUMBER_1(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X10, 0, 8)
+#define NAN_CHANNEL_PLAN_0_SET_CHANNEL_NUMBER_1(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X10, 0, 8, __value)
+#define NAN_CHANNEL_PLAN_0_GET_UNPAUSE_MACID_1(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X10, 8, 8)
+#define NAN_CHANNEL_PLAN_0_SET_UNPAUSE_MACID_1(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X10, 8, 8, __value)
+#define NAN_CHANNEL_PLAN_0_GET_START_TIME_SLOT_1(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X14, 0, 16)
+#define NAN_CHANNEL_PLAN_0_SET_START_TIME_SLOT_1(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X14, 0, 16, __value)
+#define NAN_CHANNEL_PLAN_0_GET_DURATION_1(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X14, 16, 16)
+#define NAN_CHANNEL_PLAN_0_SET_DURATION_1(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X14, 16, 16, __value)
+#define NAN_CHANNEL_PLAN_0_GET_CHANNEL_NUMBER_2(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X18, 0, 8)
+#define NAN_CHANNEL_PLAN_0_SET_CHANNEL_NUMBER_2(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X18, 0, 8, __value)
+#define NAN_CHANNEL_PLAN_0_GET_UNPAUSE_MACID_2(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X18, 8, 8)
+#define NAN_CHANNEL_PLAN_0_SET_UNPAUSE_MACID_2(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X18, 8, 8, __value)
+#define NAN_CHANNEL_PLAN_0_GET_START_TIME_SLOT_2(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X1C, 0, 16)
+#define NAN_CHANNEL_PLAN_0_SET_START_TIME_SLOT_2(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X1C, 0, 16, __value)
+#define NAN_CHANNEL_PLAN_0_GET_DURATION_2(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X1C, 16, 16)
+#define NAN_CHANNEL_PLAN_0_SET_DURATION_2(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X1C, 16, 16, __value)
+#define NAN_CHANNEL_PLAN_1_GET_CHANNEL_NUMBER_3(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X08, 0, 8)
+#define NAN_CHANNEL_PLAN_1_SET_CHANNEL_NUMBER_3(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 0, 8, __value)
+#define NAN_CHANNEL_PLAN_1_GET_UNPAUSE_MACID_3(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X08, 8, 8)
+#define NAN_CHANNEL_PLAN_1_SET_UNPAUSE_MACID_3(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X08, 8, 8, __value)
+#define NAN_CHANNEL_PLAN_1_GET_START_TIME_SLOT_3(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X0C, 0, 16)
+#define NAN_CHANNEL_PLAN_1_SET_START_TIME_SLOT_3(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X0C, 0, 16, __value)
+#define NAN_CHANNEL_PLAN_1_GET_DURATION_3(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X0C, 16, 16)
+#define NAN_CHANNEL_PLAN_1_SET_DURATION_3(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X0C, 16, 16, __value)
+#define NAN_CHANNEL_PLAN_1_GET_CHANNEL_NUMBER_4(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X10, 0, 8)
+#define NAN_CHANNEL_PLAN_1_SET_CHANNEL_NUMBER_4(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X10, 0, 8, __value)
+#define NAN_CHANNEL_PLAN_1_GET_UNPAUSE_MACID_4(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X10, 8, 8)
+#define NAN_CHANNEL_PLAN_1_SET_UNPAUSE_MACID_4(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X10, 8, 8, __value)
+#define NAN_CHANNEL_PLAN_1_GET_START_TIME_SLOT_4(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X14, 0, 16)
+#define NAN_CHANNEL_PLAN_1_SET_START_TIME_SLOT_4(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X14, 0, 16, __value)
+#define NAN_CHANNEL_PLAN_1_GET_DURATION_4(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X14, 16, 16)
+#define NAN_CHANNEL_PLAN_1_SET_DURATION_4(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X14, 16, 16, __value)
+#define NAN_CHANNEL_PLAN_1_GET_CHANNEL_NUMBER_5(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X18, 0, 8)
+#define NAN_CHANNEL_PLAN_1_SET_CHANNEL_NUMBER_5(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X18, 0, 8, __value)
+#define NAN_CHANNEL_PLAN_1_GET_UNPAUSE_MACID_5(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X18, 8, 8)
+#define NAN_CHANNEL_PLAN_1_SET_UNPAUSE_MACID_5(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X18, 8, 8, __value)
+#define NAN_CHANNEL_PLAN_1_GET_START_TIME_SLOT_5(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X1C, 0, 16)
+#define NAN_CHANNEL_PLAN_1_SET_START_TIME_SLOT_5(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X1C, 0, 16, __value)
+#define NAN_CHANNEL_PLAN_1_GET_DURATION_5(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X1C, 16, 16)
+#define NAN_CHANNEL_PLAN_1_SET_DURATION_5(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X1C, 16, 16, __value)
+#endif
diff --git a/drivers/staging/rtlwifi/halmac/halmac_h2c_extra_info_nic.h b/drivers/staging/rtlwifi/halmac/halmac_h2c_extra_info_nic.h
new file mode 100644
index 0000000..5f23cba
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_h2c_extra_info_nic.h
@@ -0,0 +1,115 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HAL_H2CEXTRAINFO_H2C_C2H_NIC_H_
+#define _HAL_H2CEXTRAINFO_H2C_C2H_NIC_H_
+#define PHY_PARAMETER_INFO_GET_LENGTH(__extra_info) \
+ LE_BITS_TO_4BYTE(__extra_info + 0X00, 0, 8)
+#define PHY_PARAMETER_INFO_SET_LENGTH(__extra_info, __value) \
+ SET_BITS_TO_LE_4BYTE(__extra_info + 0X00, 0, 8, __value)
+#define PHY_PARAMETER_INFO_GET_IO_CMD(__extra_info) \
+ LE_BITS_TO_4BYTE(__extra_info + 0X00, 8, 7)
+#define PHY_PARAMETER_INFO_SET_IO_CMD(__extra_info, __value) \
+ SET_BITS_TO_LE_4BYTE(__extra_info + 0X00, 8, 7, __value)
+#define PHY_PARAMETER_INFO_GET_MSK_EN(__extra_info) \
+ LE_BITS_TO_4BYTE(__extra_info + 0X00, 15, 1)
+#define PHY_PARAMETER_INFO_SET_MSK_EN(__extra_info, __value) \
+ SET_BITS_TO_LE_4BYTE(__extra_info + 0X00, 15, 1, __value)
+#define PHY_PARAMETER_INFO_GET_LLT_PG_BNDY(__extra_info) \
+ LE_BITS_TO_4BYTE(__extra_info + 0X00, 16, 8)
+#define PHY_PARAMETER_INFO_SET_LLT_PG_BNDY(__extra_info, __value) \
+ SET_BITS_TO_LE_4BYTE(__extra_info + 0X00, 16, 8, __value)
+#define PHY_PARAMETER_INFO_GET_EFUSE_RSVDPAGE_LOC(__extra_info) \
+ LE_BITS_TO_4BYTE(__extra_info + 0X00, 16, 8)
+#define PHY_PARAMETER_INFO_SET_EFUSE_RSVDPAGE_LOC(__extra_info, __value) \
+ SET_BITS_TO_LE_4BYTE(__extra_info + 0X00, 16, 8, __value)
+#define PHY_PARAMETER_INFO_GET_EFUSE_PATCH_EN(__extra_info) \
+ LE_BITS_TO_4BYTE(__extra_info + 0X00, 16, 8)
+#define PHY_PARAMETER_INFO_SET_EFUSE_PATCH_EN(__extra_info, __value) \
+ SET_BITS_TO_LE_4BYTE(__extra_info + 0X00, 16, 8, __value)
+#define PHY_PARAMETER_INFO_GET_RF_ADDR(__extra_info) \
+ LE_BITS_TO_4BYTE(__extra_info + 0X00, 16, 8)
+#define PHY_PARAMETER_INFO_SET_RF_ADDR(__extra_info, __value) \
+ SET_BITS_TO_LE_4BYTE(__extra_info + 0X00, 16, 8, __value)
+#define PHY_PARAMETER_INFO_GET_IO_ADDR(__extra_info) \
+ LE_BITS_TO_4BYTE(__extra_info + 0X00, 16, 16)
+#define PHY_PARAMETER_INFO_SET_IO_ADDR(__extra_info, __value) \
+ SET_BITS_TO_LE_4BYTE(__extra_info + 0X00, 16, 16, __value)
+#define PHY_PARAMETER_INFO_GET_DELAY_VALUE(__extra_info) \
+ LE_BITS_TO_4BYTE(__extra_info + 0X00, 16, 16)
+#define PHY_PARAMETER_INFO_SET_DELAY_VALUE(__extra_info, __value) \
+ SET_BITS_TO_LE_4BYTE(__extra_info + 0X00, 16, 16, __value)
+#define PHY_PARAMETER_INFO_GET_RF_PATH(__extra_info) \
+ LE_BITS_TO_4BYTE(__extra_info + 0X00, 24, 8)
+#define PHY_PARAMETER_INFO_SET_RF_PATH(__extra_info, __value) \
+ SET_BITS_TO_LE_4BYTE(__extra_info + 0X00, 24, 8, __value)
+#define PHY_PARAMETER_INFO_GET_DATA(__extra_info) \
+ LE_BITS_TO_4BYTE(__extra_info + 0X04, 0, 32)
+#define PHY_PARAMETER_INFO_SET_DATA(__extra_info, __value) \
+ SET_BITS_TO_LE_4BYTE(__extra_info + 0X04, 0, 32, __value)
+#define PHY_PARAMETER_INFO_GET_MASK(__extra_info) \
+ LE_BITS_TO_4BYTE(__extra_info + 0X08, 0, 32)
+#define PHY_PARAMETER_INFO_SET_MASK(__extra_info, __value) \
+ SET_BITS_TO_LE_4BYTE(__extra_info + 0X08, 0, 32, __value)
+#define CHANNEL_INFO_GET_CHANNEL(__extra_info) \
+ LE_BITS_TO_4BYTE(__extra_info + 0X00, 0, 8)
+#define CHANNEL_INFO_SET_CHANNEL(__extra_info, __value) \
+ SET_BITS_TO_LE_4BYTE(__extra_info + 0X00, 0, 8, __value)
+#define CHANNEL_INFO_GET_PRI_CH_IDX(__extra_info) \
+ LE_BITS_TO_4BYTE(__extra_info + 0X00, 8, 4)
+#define CHANNEL_INFO_SET_PRI_CH_IDX(__extra_info, __value) \
+ SET_BITS_TO_LE_4BYTE(__extra_info + 0X00, 8, 4, __value)
+#define CHANNEL_INFO_GET_BANDWIDTH(__extra_info) \
+ LE_BITS_TO_4BYTE(__extra_info + 0X00, 12, 4)
+#define CHANNEL_INFO_SET_BANDWIDTH(__extra_info, __value) \
+ SET_BITS_TO_LE_4BYTE(__extra_info + 0X00, 12, 4, __value)
+#define CHANNEL_INFO_GET_TIMEOUT(__extra_info) \
+ LE_BITS_TO_4BYTE(__extra_info + 0X00, 16, 8)
+#define CHANNEL_INFO_SET_TIMEOUT(__extra_info, __value) \
+ SET_BITS_TO_LE_4BYTE(__extra_info + 0X00, 16, 8, __value)
+#define CHANNEL_INFO_GET_ACTION_ID(__extra_info) \
+ LE_BITS_TO_4BYTE(__extra_info + 0X00, 24, 7)
+#define CHANNEL_INFO_SET_ACTION_ID(__extra_info, __value) \
+ SET_BITS_TO_LE_4BYTE(__extra_info + 0X00, 24, 7, __value)
+#define CHANNEL_INFO_GET_CH_EXTRA_INFO(__extra_info) \
+ LE_BITS_TO_4BYTE(__extra_info + 0X00, 31, 1)
+#define CHANNEL_INFO_SET_CH_EXTRA_INFO(__extra_info, __value) \
+ SET_BITS_TO_LE_4BYTE(__extra_info + 0X00, 31, 1, __value)
+#define CH_EXTRA_INFO_GET_CH_EXTRA_INFO_ID(__extra_info) \
+ LE_BITS_TO_4BYTE(__extra_info + 0X00, 0, 7)
+#define CH_EXTRA_INFO_SET_CH_EXTRA_INFO_ID(__extra_info, __value) \
+ SET_BITS_TO_LE_4BYTE(__extra_info + 0X00, 0, 7, __value)
+#define CH_EXTRA_INFO_GET_CH_EXTRA_INFO(__extra_info) \
+ LE_BITS_TO_4BYTE(__extra_info + 0X00, 7, 1)
+#define CH_EXTRA_INFO_SET_CH_EXTRA_INFO(__extra_info, __value) \
+ SET_BITS_TO_LE_4BYTE(__extra_info + 0X00, 7, 1, __value)
+#define CH_EXTRA_INFO_GET_CH_EXTRA_INFO_SIZE(__extra_info) \
+ LE_BITS_TO_4BYTE(__extra_info + 0X00, 8, 8)
+#define CH_EXTRA_INFO_SET_CH_EXTRA_INFO_SIZE(__extra_info, __value) \
+ SET_BITS_TO_LE_4BYTE(__extra_info + 0X00, 8, 8, __value)
+#define CH_EXTRA_INFO_GET_CH_EXTRA_INFO_DATA(__extra_info) \
+ LE_BITS_TO_4BYTE(__extra_info + 0X00, 16, 1)
+#define CH_EXTRA_INFO_SET_CH_EXTRA_INFO_DATA(__extra_info, __value) \
+ SET_BITS_TO_LE_4BYTE(__extra_info + 0X00, 16, 1, __value)
+#endif
diff --git a/drivers/staging/rtlwifi/halmac/halmac_intf_phy_cmd.h b/drivers/staging/rtlwifi/halmac/halmac_intf_phy_cmd.h
new file mode 100644
index 0000000..273d4c0
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_intf_phy_cmd.h
@@ -0,0 +1,54 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef HALMAC_INTF_PHY_CMD
+#define HALMAC_INTF_PHY_CMD
+
+/* Cut mask */
+enum halmac_intf_phy_cut {
+ HALMAC_INTF_PHY_CUT_TESTCHIP = BIT(0),
+ HALMAC_INTF_PHY_CUT_A = BIT(1),
+ HALMAC_INTF_PHY_CUT_B = BIT(2),
+ HALMAC_INTF_PHY_CUT_C = BIT(3),
+ HALMAC_INTF_PHY_CUT_D = BIT(4),
+ HALMAC_INTF_PHY_CUT_E = BIT(5),
+ HALMAC_INTF_PHY_CUT_F = BIT(6),
+ HALMAC_INTF_PHY_CUT_G = BIT(7),
+ HALMAC_INTF_PHY_CUT_ALL = 0x7FFF,
+};
+
+/* IP selection */
+enum halmac_ip_sel {
+ HALMAC_IP_SEL_INTF_PHY = 0,
+ HALMAC_IP_SEL_MAC = 1,
+ HALMAC_IP_SEL_PCIE_DBI = 2,
+ HALMAC_IP_SEL_UNDEFINE = 0x7FFF,
+};
+
+/* Platform mask */
+enum halmac_intf_phy_platform {
+ HALMAC_INTF_PHY_PLATFORM_ALL = 0x7FFF,
+};
+
+#endif
diff --git a/drivers/staging/rtlwifi/halmac/halmac_original_c2h_nic.h b/drivers/staging/rtlwifi/halmac/halmac_original_c2h_nic.h
new file mode 100644
index 0000000..4331e2a
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_original_c2h_nic.h
@@ -0,0 +1,403 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HAL_ORIGINALC2HFORMAT_H2C_C2H_NIC_H_
+#define _HAL_ORIGINALC2HFORMAT_H2C_C2H_NIC_H_
+#define CMD_ID_C2H 0X00
+#define CMD_ID_DBG 0X00
+#define CMD_ID_C2H_LB 0X01
+#define CMD_ID_C2H_SND_TXBF 0X02
+#define CMD_ID_C2H_CCX_RPT 0X03
+#define CMD_ID_C2H_AP_REQ_TXRPT 0X04
+#define CMD_ID_C2H_INITIAL_RATE_COLLECTION 0X05
+#define CMD_ID_C2H_RA_RPT 0X0C
+#define CMD_ID_C2H_SPECIAL_STATISTICS 0X0D
+#define CMD_ID_C2H_RA_PARA_RPT 0X0E
+#define CMD_ID_C2H_CUR_CHANNEL 0X10
+#define CMD_ID_C2H_GPIO_WAKEUP 0X14
+#define C2H_GET_CMD_ID(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 0, 8)
+#define C2H_SET_CMD_ID(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 0, 8, __value)
+#define C2H_GET_SEQ(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 8, 8)
+#define C2H_SET_SEQ(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 8, 8, __value)
+#define DBG_GET_CMD_ID(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 0, 8)
+#define DBG_SET_CMD_ID(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 0, 8, __value)
+#define DBG_GET_SEQ(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 8, 8)
+#define DBG_SET_SEQ(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 8, 8, __value)
+#define DBG_GET_DBG_STR1(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 16, 8)
+#define DBG_SET_DBG_STR1(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 16, 8, __value)
+#define DBG_GET_DBG_STR2(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 24, 8)
+#define DBG_SET_DBG_STR2(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 24, 8, __value)
+#define DBG_GET_DBG_STR3(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X04, 0, 8)
+#define DBG_SET_DBG_STR3(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 0, 8, __value)
+#define DBG_GET_DBG_STR4(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X04, 8, 8)
+#define DBG_SET_DBG_STR4(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 8, 8, __value)
+#define DBG_GET_DBG_STR5(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X04, 16, 8)
+#define DBG_SET_DBG_STR5(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 16, 8, __value)
+#define DBG_GET_DBG_STR6(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X04, 24, 8)
+#define DBG_SET_DBG_STR6(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 24, 8, __value)
+#define DBG_GET_DBG_STR7(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X08, 0, 8)
+#define DBG_SET_DBG_STR7(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X08, 0, 8, __value)
+#define DBG_GET_DBG_STR8(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X08, 8, 8)
+#define DBG_SET_DBG_STR8(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X08, 8, 8, __value)
+#define DBG_GET_DBG_STR9(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X08, 16, 8)
+#define DBG_SET_DBG_STR9(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X08, 16, 8, __value)
+#define DBG_GET_DBG_STR10(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X08, 24, 8)
+#define DBG_SET_DBG_STR10(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X08, 24, 8, __value)
+#define DBG_GET_DBG_STR11(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X0C, 0, 8)
+#define DBG_SET_DBG_STR11(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 0, 8, __value)
+#define DBG_GET_DBG_STR12(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X0C, 8, 8)
+#define DBG_SET_DBG_STR12(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 8, 8, __value)
+#define DBG_GET_LEN(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X0C, 16, 8)
+#define DBG_SET_LEN(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 16, 8, __value)
+#define DBG_GET_TRIGGER(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X0C, 24, 8)
+#define DBG_SET_TRIGGER(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 24, 8, __value)
+#define C2H_LB_GET_CMD_ID(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 0, 8)
+#define C2H_LB_SET_CMD_ID(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 0, 8, __value)
+#define C2H_LB_GET_SEQ(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 8, 8)
+#define C2H_LB_SET_SEQ(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 8, 8, __value)
+#define C2H_LB_GET_PAYLOAD1(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 16, 16)
+#define C2H_LB_SET_PAYLOAD1(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 16, 16, __value)
+#define C2H_LB_GET_PAYLOAD2(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X04, 0, 32)
+#define C2H_LB_SET_PAYLOAD2(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 0, 32, __value)
+#define C2H_LB_GET_LEN(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X0C, 16, 8)
+#define C2H_LB_SET_LEN(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 16, 8, __value)
+#define C2H_LB_GET_TRIGGER(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X0C, 24, 8)
+#define C2H_LB_SET_TRIGGER(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 24, 8, __value)
+#define C2H_SND_TXBF_GET_CMD_ID(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 0, 8)
+#define C2H_SND_TXBF_SET_CMD_ID(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 0, 8, __value)
+#define C2H_SND_TXBF_GET_SEQ(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 8, 8)
+#define C2H_SND_TXBF_SET_SEQ(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 8, 8, __value)
+#define C2H_SND_TXBF_GET_SND_RESULT(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 16, 1)
+#define C2H_SND_TXBF_SET_SND_RESULT(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 16, 1, __value)
+#define C2H_SND_TXBF_GET_LEN(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X0C, 16, 8)
+#define C2H_SND_TXBF_SET_LEN(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 16, 8, __value)
+#define C2H_SND_TXBF_GET_TRIGGER(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X0C, 24, 8)
+#define C2H_SND_TXBF_SET_TRIGGER(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 24, 8, __value)
+#define C2H_CCX_RPT_GET_CMD_ID(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 0, 8)
+#define C2H_CCX_RPT_SET_CMD_ID(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 0, 8, __value)
+#define C2H_CCX_RPT_GET_SEQ(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 8, 8)
+#define C2H_CCX_RPT_SET_SEQ(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 8, 8, __value)
+#define C2H_CCX_RPT_GET_QSEL(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 16, 5)
+#define C2H_CCX_RPT_SET_QSEL(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 16, 5, __value)
+#define C2H_CCX_RPT_GET_BMC(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 21, 1)
+#define C2H_CCX_RPT_SET_BMC(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 21, 1, __value)
+#define C2H_CCX_RPT_GET_LIFE_TIME_OVER(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X00, 22, 1)
+#define C2H_CCX_RPT_SET_LIFE_TIME_OVER(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 22, 1, __value)
+#define C2H_CCX_RPT_GET_RETRY_OVER(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 23, 1)
+#define C2H_CCX_RPT_SET_RETRY_OVER(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 23, 1, __value)
+#define C2H_CCX_RPT_GET_MACID(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 24, 8)
+#define C2H_CCX_RPT_SET_MACID(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 24, 8, __value)
+#define C2H_CCX_RPT_GET_DATA_RETRY_CNT(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X04, 0, 6)
+#define C2H_CCX_RPT_SET_DATA_RETRY_CNT(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 0, 6, __value)
+#define C2H_CCX_RPT_GET_QUEUE7_0(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X04, 8, 8)
+#define C2H_CCX_RPT_SET_QUEUE7_0(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 8, 8, __value)
+#define C2H_CCX_RPT_GET_QUEUE15_8(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X04, 16, 8)
+#define C2H_CCX_RPT_SET_QUEUE15_8(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 16, 8, __value)
+#define C2H_CCX_RPT_GET_FINAL_DATA_RATE(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X04, 24, 8)
+#define C2H_CCX_RPT_SET_FINAL_DATA_RATE(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 24, 8, __value)
+#define C2H_CCX_RPT_GET_SW_DEFINE_0(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X08, 0, 8)
+#define C2H_CCX_RPT_SET_SW_DEFINE_0(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X08, 0, 8, __value)
+#define C2H_CCX_RPT_GET_SW_DEFINE_1(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X08, 8, 4)
+#define C2H_CCX_RPT_SET_SW_DEFINE_1(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X08, 8, 4, __value)
+#define C2H_CCX_RPT_GET_LEN(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X0C, 16, 8)
+#define C2H_CCX_RPT_SET_LEN(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 16, 8, __value)
+#define C2H_CCX_RPT_GET_TRIGGER(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X0C, 24, 8)
+#define C2H_CCX_RPT_SET_TRIGGER(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 24, 8, __value)
+#define C2H_AP_REQ_TXRPT_GET_CMD_ID(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 0, 8)
+#define C2H_AP_REQ_TXRPT_SET_CMD_ID(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 0, 8, __value)
+#define C2H_AP_REQ_TXRPT_GET_SEQ(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 8, 8)
+#define C2H_AP_REQ_TXRPT_SET_SEQ(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 8, 8, __value)
+#define C2H_AP_REQ_TXRPT_GET_STA1_MACID(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X00, 16, 8)
+#define C2H_AP_REQ_TXRPT_SET_STA1_MACID(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 16, 8, __value)
+#define C2H_AP_REQ_TXRPT_GET_TX_OK1_0(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X00, 24, 8)
+#define C2H_AP_REQ_TXRPT_SET_TX_OK1_0(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 24, 8, __value)
+#define C2H_AP_REQ_TXRPT_GET_TX_OK1_1(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X04, 0, 8)
+#define C2H_AP_REQ_TXRPT_SET_TX_OK1_1(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 0, 8, __value)
+#define C2H_AP_REQ_TXRPT_GET_TX_FAIL1_0(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X04, 8, 8)
+#define C2H_AP_REQ_TXRPT_SET_TX_FAIL1_0(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 8, 8, __value)
+#define C2H_AP_REQ_TXRPT_GET_TX_FAIL1_1(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X04, 16, 8)
+#define C2H_AP_REQ_TXRPT_SET_TX_FAIL1_1(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 16, 8, __value)
+#define C2H_AP_REQ_TXRPT_GET_INITIAL_RATE1(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X04, 24, 8)
+#define C2H_AP_REQ_TXRPT_SET_INITIAL_RATE1(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 24, 8, __value)
+#define C2H_AP_REQ_TXRPT_GET_STA2_MACID(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X08, 0, 8)
+#define C2H_AP_REQ_TXRPT_SET_STA2_MACID(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X08, 0, 8, __value)
+#define C2H_AP_REQ_TXRPT_GET_TX_OK2_0(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X08, 8, 8)
+#define C2H_AP_REQ_TXRPT_SET_TX_OK2_0(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X08, 8, 8, __value)
+#define C2H_AP_REQ_TXRPT_GET_TX_OK2_1(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X08, 16, 8)
+#define C2H_AP_REQ_TXRPT_SET_TX_OK2_1(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X08, 16, 8, __value)
+#define C2H_AP_REQ_TXRPT_GET_TX_FAIL2_0(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X08, 24, 8)
+#define C2H_AP_REQ_TXRPT_SET_TX_FAIL2_0(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X08, 24, 8, __value)
+#define C2H_AP_REQ_TXRPT_GET_TX_FAIL2_1(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X0C, 0, 8)
+#define C2H_AP_REQ_TXRPT_SET_TX_FAIL2_1(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 0, 8, __value)
+#define C2H_AP_REQ_TXRPT_GET_INITIAL_RATE2(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X0C, 8, 8)
+#define C2H_AP_REQ_TXRPT_SET_INITIAL_RATE2(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 8, 8, __value)
+#define C2H_AP_REQ_TXRPT_GET_LEN(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X0C, 16, 8)
+#define C2H_AP_REQ_TXRPT_SET_LEN(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 16, 8, __value)
+#define C2H_AP_REQ_TXRPT_GET_TRIGGER(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X0C, 24, 8)
+#define C2H_AP_REQ_TXRPT_SET_TRIGGER(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 24, 8, __value)
+#define C2H_INITIAL_RATE_COLLECTION_GET_CMD_ID(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X00, 0, 8)
+#define C2H_INITIAL_RATE_COLLECTION_SET_CMD_ID(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 0, 8, __value)
+#define C2H_INITIAL_RATE_COLLECTION_GET_SEQ(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X00, 8, 8)
+#define C2H_INITIAL_RATE_COLLECTION_SET_SEQ(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 8, 8, __value)
+#define C2H_INITIAL_RATE_COLLECTION_GET_TRYING_BITMAP(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X00, 16, 7)
+#define C2H_INITIAL_RATE_COLLECTION_SET_TRYING_BITMAP(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 16, 7, __value)
+#define C2H_INITIAL_RATE_COLLECTION_GET_INITIAL_RATE1(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X00, 24, 8)
+#define C2H_INITIAL_RATE_COLLECTION_SET_INITIAL_RATE1(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 24, 8, __value)
+#define C2H_INITIAL_RATE_COLLECTION_GET_INITIAL_RATE2(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X04, 0, 8)
+#define C2H_INITIAL_RATE_COLLECTION_SET_INITIAL_RATE2(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 0, 8, __value)
+#define C2H_INITIAL_RATE_COLLECTION_GET_INITIAL_RATE3(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X04, 8, 8)
+#define C2H_INITIAL_RATE_COLLECTION_SET_INITIAL_RATE3(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 8, 8, __value)
+#define C2H_INITIAL_RATE_COLLECTION_GET_INITIAL_RATE4(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X04, 16, 8)
+#define C2H_INITIAL_RATE_COLLECTION_SET_INITIAL_RATE4(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 16, 8, __value)
+#define C2H_INITIAL_RATE_COLLECTION_GET_INITIAL_RATE5(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X04, 24, 8)
+#define C2H_INITIAL_RATE_COLLECTION_SET_INITIAL_RATE5(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 24, 8, __value)
+#define C2H_INITIAL_RATE_COLLECTION_GET_INITIAL_RATE6(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X08, 0, 8)
+#define C2H_INITIAL_RATE_COLLECTION_SET_INITIAL_RATE6(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X08, 0, 8, __value)
+#define C2H_INITIAL_RATE_COLLECTION_GET_INITIAL_RATE7(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X08, 8, 8)
+#define C2H_INITIAL_RATE_COLLECTION_SET_INITIAL_RATE7(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X08, 8, 8, __value)
+#define C2H_INITIAL_RATE_COLLECTION_GET_LEN(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X0C, 16, 8)
+#define C2H_INITIAL_RATE_COLLECTION_SET_LEN(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 16, 8, __value)
+#define C2H_INITIAL_RATE_COLLECTION_GET_TRIGGER(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X0C, 24, 8)
+#define C2H_INITIAL_RATE_COLLECTION_SET_TRIGGER(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 24, 8, __value)
+#define C2H_RA_RPT_GET_CMD_ID(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 0, 8)
+#define C2H_RA_RPT_SET_CMD_ID(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 0, 8, __value)
+#define C2H_RA_RPT_GET_SEQ(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 8, 8)
+#define C2H_RA_RPT_SET_SEQ(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 8, 8, __value)
+#define C2H_RA_RPT_GET_RATE(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 16, 8)
+#define C2H_RA_RPT_SET_RATE(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 16, 8, __value)
+#define C2H_RA_RPT_GET_MACID(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 24, 8)
+#define C2H_RA_RPT_SET_MACID(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 24, 8, __value)
+#define C2H_RA_RPT_GET_USE_LDPC(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X04, 0, 1)
+#define C2H_RA_RPT_SET_USE_LDPC(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 0, 1, __value)
+#define C2H_RA_RPT_GET_USE_TXBF(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X04, 1, 1)
+#define C2H_RA_RPT_SET_USE_TXBF(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 1, 1, __value)
+#define C2H_RA_RPT_GET_COLLISION_STATE(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X04, 8, 8)
+#define C2H_RA_RPT_SET_COLLISION_STATE(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 8, 8, __value)
+#define C2H_RA_RPT_GET_LEN(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X0C, 16, 8)
+#define C2H_RA_RPT_SET_LEN(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 16, 8, __value)
+#define C2H_RA_RPT_GET_TRIGGER(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X0C, 24, 8)
+#define C2H_RA_RPT_SET_TRIGGER(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 24, 8, __value)
+#define C2H_SPECIAL_STATISTICS_GET_CMD_ID(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X00, 0, 8)
+#define C2H_SPECIAL_STATISTICS_SET_CMD_ID(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 0, 8, __value)
+#define C2H_SPECIAL_STATISTICS_GET_SEQ(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X00, 8, 8)
+#define C2H_SPECIAL_STATISTICS_SET_SEQ(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 8, 8, __value)
+#define C2H_SPECIAL_STATISTICS_GET_STATISTICS_IDX(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X00, 16, 8)
+#define C2H_SPECIAL_STATISTICS_SET_STATISTICS_IDX(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 16, 8, __value)
+#define C2H_SPECIAL_STATISTICS_GET_DATA0(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X00, 24, 8)
+#define C2H_SPECIAL_STATISTICS_SET_DATA0(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 24, 8, __value)
+#define C2H_SPECIAL_STATISTICS_GET_DATA1(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X04, 0, 8)
+#define C2H_SPECIAL_STATISTICS_SET_DATA1(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 0, 8, __value)
+#define C2H_SPECIAL_STATISTICS_GET_DATA2(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X04, 8, 8)
+#define C2H_SPECIAL_STATISTICS_SET_DATA2(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 8, 8, __value)
+#define C2H_SPECIAL_STATISTICS_GET_DATA3(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X04, 16, 8)
+#define C2H_SPECIAL_STATISTICS_SET_DATA3(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 16, 8, __value)
+#define C2H_SPECIAL_STATISTICS_GET_DATA4(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X04, 24, 8)
+#define C2H_SPECIAL_STATISTICS_SET_DATA4(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X04, 24, 8, __value)
+#define C2H_SPECIAL_STATISTICS_GET_DATA5(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X08, 0, 8)
+#define C2H_SPECIAL_STATISTICS_SET_DATA5(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X08, 0, 8, __value)
+#define C2H_SPECIAL_STATISTICS_GET_DATA6(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X08, 8, 8)
+#define C2H_SPECIAL_STATISTICS_SET_DATA6(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X08, 8, 8, __value)
+#define C2H_SPECIAL_STATISTICS_GET_DATA7(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X08, 16, 8)
+#define C2H_SPECIAL_STATISTICS_SET_DATA7(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X08, 16, 8, __value)
+#define C2H_SPECIAL_STATISTICS_GET_LEN(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X0C, 16, 8)
+#define C2H_SPECIAL_STATISTICS_SET_LEN(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 16, 8, __value)
+#define C2H_SPECIAL_STATISTICS_GET_TRIGGER(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X0C, 24, 8)
+#define C2H_SPECIAL_STATISTICS_SET_TRIGGER(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 24, 8, __value)
+#define C2H_RA_PARA_RPT_GET_CMD_ID(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 0, 8)
+#define C2H_RA_PARA_RPT_SET_CMD_ID(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 0, 8, __value)
+#define C2H_RA_PARA_RPT_GET_SEQ(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 8, 8)
+#define C2H_RA_PARA_RPT_SET_SEQ(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 8, 8, __value)
+#define C2H_RA_PARA_RPT_GET_LEN(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X0C, 16, 8)
+#define C2H_RA_PARA_RPT_SET_LEN(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 16, 8, __value)
+#define C2H_RA_PARA_RPT_GET_TRIGGER(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X0C, 24, 8)
+#define C2H_RA_PARA_RPT_SET_TRIGGER(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 24, 8, __value)
+#define C2H_CUR_CHANNEL_GET_CMD_ID(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 0, 8)
+#define C2H_CUR_CHANNEL_SET_CMD_ID(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 0, 8, __value)
+#define C2H_CUR_CHANNEL_GET_SEQ(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 8, 8)
+#define C2H_CUR_CHANNEL_SET_SEQ(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 8, 8, __value)
+#define C2H_CUR_CHANNEL_GET_CHANNEL_NUM(__c2h) \
+ LE_BITS_TO_4BYTE(__c2h + 0X00, 16, 8)
+#define C2H_CUR_CHANNEL_SET_CHANNEL_NUM(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 16, 8, __value)
+#define C2H_CUR_CHANNEL_GET_LEN(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X0C, 16, 8)
+#define C2H_CUR_CHANNEL_SET_LEN(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 16, 8, __value)
+#define C2H_CUR_CHANNEL_GET_TRIGGER(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X0C, 24, 8)
+#define C2H_CUR_CHANNEL_SET_TRIGGER(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 24, 8, __value)
+#define C2H_GPIO_WAKEUP_GET_CMD_ID(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 0, 8)
+#define C2H_GPIO_WAKEUP_SET_CMD_ID(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 0, 8, __value)
+#define C2H_GPIO_WAKEUP_GET_SEQ(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X00, 8, 8)
+#define C2H_GPIO_WAKEUP_SET_SEQ(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X00, 8, 8, __value)
+#define C2H_GPIO_WAKEUP_GET_LEN(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X0C, 16, 8)
+#define C2H_GPIO_WAKEUP_SET_LEN(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 16, 8, __value)
+#define C2H_GPIO_WAKEUP_GET_TRIGGER(__c2h) LE_BITS_TO_4BYTE(__c2h + 0X0C, 24, 8)
+#define C2H_GPIO_WAKEUP_SET_TRIGGER(__c2h, __value) \
+ SET_BITS_TO_LE_4BYTE(__c2h + 0X0C, 24, 8, __value)
+#endif
diff --git a/drivers/staging/rtlwifi/halmac/halmac_original_h2c_nic.h b/drivers/staging/rtlwifi/halmac/halmac_original_h2c_nic.h
new file mode 100644
index 0000000..db7aac4
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_original_h2c_nic.h
@@ -0,0 +1,1011 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HAL_ORIGINALH2CFORMAT_H2C_C2H_NIC_H_
+#define _HAL_ORIGINALH2CFORMAT_H2C_C2H_NIC_H_
+#define CMD_ID_ORIGINAL_H2C 0X00
+#define CMD_ID_H2C2H_LB 0X0
+#define CMD_ID_D0_SCAN_OFFLOAD_CTRL 0X06
+#define CMD_ID_RSVD_PAGE 0X0
+#define CMD_ID_MEDIA_STATUS_RPT 0X01
+#define CMD_ID_KEEP_ALIVE 0X03
+#define CMD_ID_DISCONNECT_DECISION 0X04
+#define CMD_ID_AP_OFFLOAD 0X08
+#define CMD_ID_BCN_RSVDPAGE 0X09
+#define CMD_ID_PROBE_RSP_RSVDPAGE 0X0A
+#define CMD_ID_SET_PWR_MODE 0X00
+#define CMD_ID_PS_TUNING_PARA 0X01
+#define CMD_ID_PS_TUNING_PARA_II 0X02
+#define CMD_ID_PS_LPS_PARA 0X03
+#define CMD_ID_P2P_PS_OFFLOAD 0X04
+#define CMD_ID_PS_SCAN_EN 0X05
+#define CMD_ID_SAP_PS 0X06
+#define CMD_ID_INACTIVE_PS 0X07
+#define CMD_ID_MACID_CFG 0X00
+#define CMD_ID_TXBF 0X01
+#define CMD_ID_RSSI_SETTING 0X02
+#define CMD_ID_AP_REQ_TXRPT 0X03
+#define CMD_ID_INIT_RATE_COLLECTION 0X04
+#define CMD_ID_IQK_OFFLOAD 0X05
+#define CMD_ID_MACID_CFG_3SS 0X06
+#define CMD_ID_RA_PARA_ADJUST 0X07
+#define CMD_ID_WWLAN 0X00
+#define CMD_ID_REMOTE_WAKE_CTRL 0X01
+#define CMD_ID_AOAC_GLOBAL_INFO 0X02
+#define CMD_ID_AOAC_RSVD_PAGE 0X03
+#define CMD_ID_AOAC_RSVD_PAGE2 0X04
+#define CMD_ID_D0_SCAN_OFFLOAD_INFO 0X05
+#define CMD_ID_CHANNEL_SWITCH_OFFLOAD 0X07
+#define CMD_ID_AOAC_RSVD_PAGE3 0X08
+#define CLASS_ORIGINAL_H2C 0X00
+#define CLASS_H2C2H_LB 0X07
+#define CLASS_D0_SCAN_OFFLOAD_CTRL 0X04
+#define CLASS_RSVD_PAGE 0X0
+#define CLASS_MEDIA_STATUS_RPT 0X0
+#define CLASS_KEEP_ALIVE 0X0
+#define CLASS_DISCONNECT_DECISION 0X0
+#define CLASS_AP_OFFLOAD 0X0
+#define CLASS_BCN_RSVDPAGE 0X0
+#define CLASS_PROBE_RSP_RSVDPAGE 0X0
+#define CLASS_SET_PWR_MODE 0X01
+#define CLASS_PS_TUNING_PARA 0X01
+#define CLASS_PS_TUNING_PARA_II 0X01
+#define CLASS_PS_LPS_PARA 0X01
+#define CLASS_P2P_PS_OFFLOAD 0X01
+#define CLASS_PS_SCAN_EN 0X1
+#define CLASS_SAP_PS 0X1
+#define CLASS_INACTIVE_PS 0X1
+#define CLASS_MACID_CFG 0X2
+#define CLASS_TXBF 0X2
+#define CLASS_RSSI_SETTING 0X2
+#define CLASS_AP_REQ_TXRPT 0X2
+#define CLASS_INIT_RATE_COLLECTION 0X2
+#define CLASS_IQK_OFFLOAD 0X2
+#define CLASS_MACID_CFG_3SS 0X2
+#define CLASS_RA_PARA_ADJUST 0X02
+#define CLASS_WWLAN 0X4
+#define CLASS_REMOTE_WAKE_CTRL 0X4
+#define CLASS_AOAC_GLOBAL_INFO 0X04
+#define CLASS_AOAC_RSVD_PAGE 0X04
+#define CLASS_AOAC_RSVD_PAGE2 0X04
+#define CLASS_D0_SCAN_OFFLOAD_INFO 0X04
+#define CLASS_CHANNEL_SWITCH_OFFLOAD 0X04
+#define CLASS_AOAC_RSVD_PAGE3 0X04
+#define ORIGINAL_H2C_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define ORIGINAL_H2C_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define ORIGINAL_H2C_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define ORIGINAL_H2C_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define H2C2H_LB_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define H2C2H_LB_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define H2C2H_LB_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define H2C2H_LB_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define H2C2H_LB_GET_SEQ(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 8)
+#define H2C2H_LB_SET_SEQ(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 8, __value)
+#define H2C2H_LB_GET_PAYLOAD1(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 16)
+#define H2C2H_LB_SET_PAYLOAD1(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 16, __value)
+#define H2C2H_LB_GET_PAYLOAD2(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X04, 0, 32)
+#define H2C2H_LB_SET_PAYLOAD2(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 0, 32, __value)
+#define D0_SCAN_OFFLOAD_CTRL_GET_CMD_ID(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define D0_SCAN_OFFLOAD_CTRL_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define D0_SCAN_OFFLOAD_CTRL_GET_CLASS(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define D0_SCAN_OFFLOAD_CTRL_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define D0_SCAN_OFFLOAD_CTRL_GET_D0_SCAN_FUN_EN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 1)
+#define D0_SCAN_OFFLOAD_CTRL_SET_D0_SCAN_FUN_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 1, __value)
+#define D0_SCAN_OFFLOAD_CTRL_GET_RTD3FUN_EN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 9, 1)
+#define D0_SCAN_OFFLOAD_CTRL_SET_RTD3FUN_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 9, 1, __value)
+#define D0_SCAN_OFFLOAD_CTRL_GET_U3_SCAN_FUN_EN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 10, 1)
+#define D0_SCAN_OFFLOAD_CTRL_SET_U3_SCAN_FUN_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 10, 1, __value)
+#define D0_SCAN_OFFLOAD_CTRL_GET_NLO_FUN_EN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 11, 1)
+#define D0_SCAN_OFFLOAD_CTRL_SET_NLO_FUN_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 11, 1, __value)
+#define D0_SCAN_OFFLOAD_CTRL_GET_IPS_DEPENDENT(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 12, 1)
+#define D0_SCAN_OFFLOAD_CTRL_SET_IPS_DEPENDENT(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 12, 1, __value)
+#define D0_SCAN_OFFLOAD_CTRL_GET_LOC_PROBE_PACKET(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 17)
+#define D0_SCAN_OFFLOAD_CTRL_SET_LOC_PROBE_PACKET(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 17, __value)
+#define D0_SCAN_OFFLOAD_CTRL_GET_LOC_SCAN_INFO(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 24, 8)
+#define D0_SCAN_OFFLOAD_CTRL_SET_LOC_SCAN_INFO(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 24, 8, __value)
+#define D0_SCAN_OFFLOAD_CTRL_GET_LOC_SSID_INFO(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 0, 8)
+#define D0_SCAN_OFFLOAD_CTRL_SET_LOC_SSID_INFO(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 0, 8, __value)
+#define RSVD_PAGE_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define RSVD_PAGE_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define RSVD_PAGE_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define RSVD_PAGE_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define RSVD_PAGE_GET_LOC_PROBE_RSP(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 8)
+#define RSVD_PAGE_SET_LOC_PROBE_RSP(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 8, __value)
+#define RSVD_PAGE_GET_LOC_PS_POLL(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 8)
+#define RSVD_PAGE_SET_LOC_PS_POLL(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 8, __value)
+#define RSVD_PAGE_GET_LOC_NULL_DATA(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 24, 8)
+#define RSVD_PAGE_SET_LOC_NULL_DATA(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 24, 8, __value)
+#define RSVD_PAGE_GET_LOC_QOS_NULL(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X04, 0, 8)
+#define RSVD_PAGE_SET_LOC_QOS_NULL(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 0, 8, __value)
+#define RSVD_PAGE_GET_LOC_BT_QOS_NULL(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 8, 8)
+#define RSVD_PAGE_SET_LOC_BT_QOS_NULL(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 8, 8, __value)
+#define RSVD_PAGE_GET_LOC_CTS2SELF(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X04, 16, 8)
+#define RSVD_PAGE_SET_LOC_CTS2SELF(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 16, 8, __value)
+#define RSVD_PAGE_GET_LOC_LTECOEX_QOSNULL(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 24, 8)
+#define RSVD_PAGE_SET_LOC_LTECOEX_QOSNULL(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 24, 8, __value)
+#define MEDIA_STATUS_RPT_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define MEDIA_STATUS_RPT_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define MEDIA_STATUS_RPT_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define MEDIA_STATUS_RPT_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define MEDIA_STATUS_RPT_GET_OP_MODE(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 1)
+#define MEDIA_STATUS_RPT_SET_OP_MODE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 1, __value)
+#define MEDIA_STATUS_RPT_GET_MACID_IN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 9, 1)
+#define MEDIA_STATUS_RPT_SET_MACID_IN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 9, 1, __value)
+#define MEDIA_STATUS_RPT_GET_MACID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 8)
+#define MEDIA_STATUS_RPT_SET_MACID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 8, __value)
+#define MEDIA_STATUS_RPT_GET_MACID_END(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 24, 8)
+#define MEDIA_STATUS_RPT_SET_MACID_END(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 24, 8, __value)
+#define KEEP_ALIVE_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define KEEP_ALIVE_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define KEEP_ALIVE_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define KEEP_ALIVE_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define KEEP_ALIVE_GET_ENABLE(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 1)
+#define KEEP_ALIVE_SET_ENABLE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 1, __value)
+#define KEEP_ALIVE_GET_ADOPT_USER_SETTING(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 9, 1)
+#define KEEP_ALIVE_SET_ADOPT_USER_SETTING(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 9, 1, __value)
+#define KEEP_ALIVE_GET_PKT_TYPE(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 10, 1)
+#define KEEP_ALIVE_SET_PKT_TYPE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 10, 1, __value)
+#define KEEP_ALIVE_GET_KEEP_ALIVE_CHECK_PERIOD(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 8)
+#define KEEP_ALIVE_SET_KEEP_ALIVE_CHECK_PERIOD(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 8, __value)
+#define DISCONNECT_DECISION_GET_CMD_ID(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define DISCONNECT_DECISION_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define DISCONNECT_DECISION_GET_CLASS(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define DISCONNECT_DECISION_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define DISCONNECT_DECISION_GET_ENABLE(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 1)
+#define DISCONNECT_DECISION_SET_ENABLE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 1, __value)
+#define DISCONNECT_DECISION_GET_ADOPT_USER_SETTING(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 9, 1)
+#define DISCONNECT_DECISION_SET_ADOPT_USER_SETTING(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 9, 1, __value)
+#define DISCONNECT_DECISION_GET_TRY_OK_BCN_FAIL_COUNT_EN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 10, 1)
+#define DISCONNECT_DECISION_SET_TRY_OK_BCN_FAIL_COUNT_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 10, 1, __value)
+#define DISCONNECT_DECISION_GET_DISCONNECT_EN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 11, 1)
+#define DISCONNECT_DECISION_SET_DISCONNECT_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 11, 1, __value)
+#define DISCONNECT_DECISION_GET_DISCON_DECISION_CHECK_PERIOD(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 8)
+#define DISCONNECT_DECISION_SET_DISCON_DECISION_CHECK_PERIOD(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 8, __value)
+#define DISCONNECT_DECISION_GET_TRY_PKT_NUM(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 24, 8)
+#define DISCONNECT_DECISION_SET_TRY_PKT_NUM(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 24, 8, __value)
+#define DISCONNECT_DECISION_GET_TRY_OK_BCN_FAIL_COUNT_LIMIT(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 0, 8)
+#define DISCONNECT_DECISION_SET_TRY_OK_BCN_FAIL_COUNT_LIMIT(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 0, 8, __value)
+#define AP_OFFLOAD_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define AP_OFFLOAD_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define AP_OFFLOAD_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define AP_OFFLOAD_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define AP_OFFLOAD_GET_ON(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 1)
+#define AP_OFFLOAD_SET_ON(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 1, __value)
+#define AP_OFFLOAD_GET_CFG_MIFI_PLATFORM(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 9, 1)
+#define AP_OFFLOAD_SET_CFG_MIFI_PLATFORM(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 9, 1, __value)
+#define AP_OFFLOAD_GET_LINKED(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 10, 1)
+#define AP_OFFLOAD_SET_LINKED(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 10, 1, __value)
+#define AP_OFFLOAD_GET_EN_AUTO_WAKE(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 11, 1)
+#define AP_OFFLOAD_SET_EN_AUTO_WAKE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 11, 1, __value)
+#define AP_OFFLOAD_GET_WAKE_FLAG(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 12, 1)
+#define AP_OFFLOAD_SET_WAKE_FLAG(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 12, 1, __value)
+#define AP_OFFLOAD_GET_HIDDEN_ROOT(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 1)
+#define AP_OFFLOAD_SET_HIDDEN_ROOT(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 1, __value)
+#define AP_OFFLOAD_GET_HIDDEN_VAP1(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 17, 1)
+#define AP_OFFLOAD_SET_HIDDEN_VAP1(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 17, 1, __value)
+#define AP_OFFLOAD_GET_HIDDEN_VAP2(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 18, 1)
+#define AP_OFFLOAD_SET_HIDDEN_VAP2(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 18, 1, __value)
+#define AP_OFFLOAD_GET_HIDDEN_VAP3(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 19, 1)
+#define AP_OFFLOAD_SET_HIDDEN_VAP3(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 19, 1, __value)
+#define AP_OFFLOAD_GET_HIDDEN_VAP4(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 20, 1)
+#define AP_OFFLOAD_SET_HIDDEN_VAP4(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 20, 1, __value)
+#define AP_OFFLOAD_GET_DENYANY_ROOT(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 24, 1)
+#define AP_OFFLOAD_SET_DENYANY_ROOT(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 24, 1, __value)
+#define AP_OFFLOAD_GET_DENYANY_VAP1(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 25, 1)
+#define AP_OFFLOAD_SET_DENYANY_VAP1(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 25, 1, __value)
+#define AP_OFFLOAD_GET_DENYANY_VAP2(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 26, 1)
+#define AP_OFFLOAD_SET_DENYANY_VAP2(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 26, 1, __value)
+#define AP_OFFLOAD_GET_DENYANY_VAP3(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 27, 1)
+#define AP_OFFLOAD_SET_DENYANY_VAP3(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 27, 1, __value)
+#define AP_OFFLOAD_GET_DENYANY_VAP4(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 28, 1)
+#define AP_OFFLOAD_SET_DENYANY_VAP4(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 28, 1, __value)
+#define AP_OFFLOAD_GET_WAIT_TBTT_CNT(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X04, 0, 8)
+#define AP_OFFLOAD_SET_WAIT_TBTT_CNT(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 0, 8, __value)
+#define AP_OFFLOAD_GET_WAKE_TIMEOUT(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X04, 8, 8)
+#define AP_OFFLOAD_SET_WAKE_TIMEOUT(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 8, 8, __value)
+#define AP_OFFLOAD_GET_LEN_IV_PAIR(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X04, 16, 8)
+#define AP_OFFLOAD_SET_LEN_IV_PAIR(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 16, 8, __value)
+#define AP_OFFLOAD_GET_LEN_IV_GRP(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X04, 24, 8)
+#define AP_OFFLOAD_SET_LEN_IV_GRP(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 24, 8, __value)
+#define BCN_RSVDPAGE_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define BCN_RSVDPAGE_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define BCN_RSVDPAGE_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define BCN_RSVDPAGE_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define BCN_RSVDPAGE_GET_LOC_ROOT(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 8)
+#define BCN_RSVDPAGE_SET_LOC_ROOT(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 8, __value)
+#define BCN_RSVDPAGE_GET_LOC_VAP1(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 8)
+#define BCN_RSVDPAGE_SET_LOC_VAP1(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 8, __value)
+#define BCN_RSVDPAGE_GET_LOC_VAP2(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 24, 8)
+#define BCN_RSVDPAGE_SET_LOC_VAP2(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 24, 8, __value)
+#define BCN_RSVDPAGE_GET_LOC_VAP3(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X04, 0, 8)
+#define BCN_RSVDPAGE_SET_LOC_VAP3(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 0, 8, __value)
+#define BCN_RSVDPAGE_GET_LOC_VAP4(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X04, 8, 8)
+#define BCN_RSVDPAGE_SET_LOC_VAP4(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 8, 8, __value)
+#define PROBE_RSP_RSVDPAGE_GET_CMD_ID(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define PROBE_RSP_RSVDPAGE_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define PROBE_RSP_RSVDPAGE_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define PROBE_RSP_RSVDPAGE_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define PROBE_RSP_RSVDPAGE_GET_LOC_ROOT(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 8)
+#define PROBE_RSP_RSVDPAGE_SET_LOC_ROOT(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 8, __value)
+#define PROBE_RSP_RSVDPAGE_GET_LOC_VAP1(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 8)
+#define PROBE_RSP_RSVDPAGE_SET_LOC_VAP1(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 8, __value)
+#define PROBE_RSP_RSVDPAGE_GET_LOC_VAP2(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 24, 8)
+#define PROBE_RSP_RSVDPAGE_SET_LOC_VAP2(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 24, 8, __value)
+#define PROBE_RSP_RSVDPAGE_GET_LOC_VAP3(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 0, 8)
+#define PROBE_RSP_RSVDPAGE_SET_LOC_VAP3(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 0, 8, __value)
+#define PROBE_RSP_RSVDPAGE_GET_LOC_VAP4(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 8, 8)
+#define PROBE_RSP_RSVDPAGE_SET_LOC_VAP4(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 8, 8, __value)
+#define SET_PWR_MODE_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define SET_PWR_MODE_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define SET_PWR_MODE_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define SET_PWR_MODE_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define SET_PWR_MODE_GET_MODE(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 7)
+#define SET_PWR_MODE_SET_MODE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 7, __value)
+#define SET_PWR_MODE_GET_CLK_REQUEST(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 15, 1)
+#define SET_PWR_MODE_SET_CLK_REQUEST(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 15, 1, __value)
+#define SET_PWR_MODE_GET_RLBM(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 4)
+#define SET_PWR_MODE_SET_RLBM(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 4, __value)
+#define SET_PWR_MODE_GET_SMART_PS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 20, 4)
+#define SET_PWR_MODE_SET_SMART_PS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 20, 4, __value)
+#define SET_PWR_MODE_GET_AWAKE_INTERVAL(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 24, 8)
+#define SET_PWR_MODE_SET_AWAKE_INTERVAL(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 24, 8, __value)
+#define SET_PWR_MODE_GET_B_ALL_QUEUE_UAPSD(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 0, 1)
+#define SET_PWR_MODE_SET_B_ALL_QUEUE_UAPSD(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 0, 1, __value)
+#define SET_PWR_MODE_GET_BCN_EARLY_RPT(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 2, 1)
+#define SET_PWR_MODE_SET_BCN_EARLY_RPT(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 2, 1, __value)
+#define SET_PWR_MODE_GET_PORT_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X04, 5, 3)
+#define SET_PWR_MODE_SET_PORT_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 5, 3, __value)
+#define SET_PWR_MODE_GET_PWR_STATE(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X04, 8, 8)
+#define SET_PWR_MODE_SET_PWR_STATE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 8, 8, __value)
+#define SET_PWR_MODE_GET_LOW_POWER_RX_BCN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 16, 1)
+#define SET_PWR_MODE_SET_LOW_POWER_RX_BCN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 16, 1, __value)
+#define SET_PWR_MODE_GET_ANT_AUTO_SWITCH(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 17, 1)
+#define SET_PWR_MODE_SET_ANT_AUTO_SWITCH(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 17, 1, __value)
+#define SET_PWR_MODE_GET_PS_ALLOW_BT_HIGH_PRIORITY(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 18, 1)
+#define SET_PWR_MODE_SET_PS_ALLOW_BT_HIGH_PRIORITY(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 18, 1, __value)
+#define SET_PWR_MODE_GET_PROTECT_BCN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 19, 1)
+#define SET_PWR_MODE_SET_PROTECT_BCN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 19, 1, __value)
+#define SET_PWR_MODE_GET_SILENCE_PERIOD(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 20, 1)
+#define SET_PWR_MODE_SET_SILENCE_PERIOD(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 20, 1, __value)
+#define SET_PWR_MODE_GET_FAST_BT_CONNECT(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 21, 1)
+#define SET_PWR_MODE_SET_FAST_BT_CONNECT(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 21, 1, __value)
+#define SET_PWR_MODE_GET_TWO_ANTENNA_EN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 22, 1)
+#define SET_PWR_MODE_SET_TWO_ANTENNA_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 22, 1, __value)
+#define SET_PWR_MODE_GET_ADOPT_USER_SETTING(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 24, 1)
+#define SET_PWR_MODE_SET_ADOPT_USER_SETTING(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 24, 1, __value)
+#define SET_PWR_MODE_GET_DRV_BCN_EARLY_SHIFT(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 25, 3)
+#define SET_PWR_MODE_SET_DRV_BCN_EARLY_SHIFT(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 25, 3, __value)
+#define SET_PWR_MODE_GET_DRV_BCN_EARLY_SHIFT2(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 28, 4)
+#define SET_PWR_MODE_SET_DRV_BCN_EARLY_SHIFT2(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 28, 4, __value)
+#define PS_TUNING_PARA_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define PS_TUNING_PARA_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define PS_TUNING_PARA_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define PS_TUNING_PARA_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define PS_TUNING_PARA_GET_BCN_TO_LIMIT(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 7)
+#define PS_TUNING_PARA_SET_BCN_TO_LIMIT(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 7, __value)
+#define PS_TUNING_PARA_GET_DTIM_TIME_OUT(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 15, 1)
+#define PS_TUNING_PARA_SET_DTIM_TIME_OUT(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 15, 1, __value)
+#define PS_TUNING_PARA_GET_PS_TIME_OUT(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 4)
+#define PS_TUNING_PARA_SET_PS_TIME_OUT(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 4, __value)
+#define PS_TUNING_PARA_GET_ADOPT(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 24, 8)
+#define PS_TUNING_PARA_SET_ADOPT(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 24, 8, __value)
+#define PS_TUNING_PARA_II_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define PS_TUNING_PARA_II_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define PS_TUNING_PARA_II_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define PS_TUNING_PARA_II_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define PS_TUNING_PARA_II_GET_BCN_TO_PERIOD(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 7)
+#define PS_TUNING_PARA_II_SET_BCN_TO_PERIOD(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 7, __value)
+#define PS_TUNING_PARA_II_GET_ADOPT(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 15, 1)
+#define PS_TUNING_PARA_II_SET_ADOPT(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 15, 1, __value)
+#define PS_TUNING_PARA_II_GET_DRV_EARLY_IVL(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 8)
+#define PS_TUNING_PARA_II_SET_DRV_EARLY_IVL(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 8, __value)
+#define PS_LPS_PARA_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define PS_LPS_PARA_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define PS_LPS_PARA_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define PS_LPS_PARA_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define PS_LPS_PARA_GET_LPS_CONTROL(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 8)
+#define PS_LPS_PARA_SET_LPS_CONTROL(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 8, __value)
+#define P2P_PS_OFFLOAD_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define P2P_PS_OFFLOAD_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define P2P_PS_OFFLOAD_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define P2P_PS_OFFLOAD_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define P2P_PS_OFFLOAD_GET_OFFLOAD_EN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 1)
+#define P2P_PS_OFFLOAD_SET_OFFLOAD_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 1, __value)
+#define P2P_PS_OFFLOAD_GET_ROLE(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 9, 1)
+#define P2P_PS_OFFLOAD_SET_ROLE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 9, 1, __value)
+#define P2P_PS_OFFLOAD_GET_CTWINDOW_EN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 10, 1)
+#define P2P_PS_OFFLOAD_SET_CTWINDOW_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 10, 1, __value)
+#define P2P_PS_OFFLOAD_GET_NOA0_EN(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 11, 1)
+#define P2P_PS_OFFLOAD_SET_NOA0_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 11, 1, __value)
+#define P2P_PS_OFFLOAD_GET_NOA1_EN(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 12, 1)
+#define P2P_PS_OFFLOAD_SET_NOA1_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 12, 1, __value)
+#define P2P_PS_OFFLOAD_GET_ALL_STA_SLEEP(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 13, 1)
+#define P2P_PS_OFFLOAD_SET_ALL_STA_SLEEP(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 13, 1, __value)
+#define P2P_PS_OFFLOAD_GET_DISCOVERY(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 14, 1)
+#define P2P_PS_OFFLOAD_SET_DISCOVERY(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 14, 1, __value)
+#define PS_SCAN_EN_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define PS_SCAN_EN_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define PS_SCAN_EN_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define PS_SCAN_EN_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define PS_SCAN_EN_GET_ENABLE(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 1)
+#define PS_SCAN_EN_SET_ENABLE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 1, __value)
+#define SAP_PS_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define SAP_PS_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define SAP_PS_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define SAP_PS_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define SAP_PS_GET_ENABLE(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 1)
+#define SAP_PS_SET_ENABLE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 1, __value)
+#define SAP_PS_GET_EN_PS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 9, 1)
+#define SAP_PS_SET_EN_PS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 9, 1, __value)
+#define SAP_PS_GET_EN_LP_RX(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 10, 1)
+#define SAP_PS_SET_EN_LP_RX(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 10, 1, __value)
+#define SAP_PS_GET_MANUAL_32K(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 11, 1)
+#define SAP_PS_SET_MANUAL_32K(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 11, 1, __value)
+#define SAP_PS_GET_DURATION(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 8)
+#define SAP_PS_SET_DURATION(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 8, __value)
+#define INACTIVE_PS_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define INACTIVE_PS_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define INACTIVE_PS_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define INACTIVE_PS_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define INACTIVE_PS_GET_ENABLE(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 1)
+#define INACTIVE_PS_SET_ENABLE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 1, __value)
+#define INACTIVE_PS_GET_IGNORE_PS_CONDITION(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 9, 1)
+#define INACTIVE_PS_SET_IGNORE_PS_CONDITION(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 9, 1, __value)
+#define INACTIVE_PS_GET_FREQUENCY(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 8)
+#define INACTIVE_PS_SET_FREQUENCY(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 8, __value)
+#define INACTIVE_PS_GET_DURATION(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 24, 8)
+#define INACTIVE_PS_SET_DURATION(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 24, 8, __value)
+#define MACID_CFG_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define MACID_CFG_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define MACID_CFG_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define MACID_CFG_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define MACID_CFG_GET_MAC_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 8)
+#define MACID_CFG_SET_MAC_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 8, __value)
+#define MACID_CFG_GET_RATE_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 5)
+#define MACID_CFG_SET_RATE_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 5, __value)
+#define MACID_CFG_GET_SGI(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 23, 1)
+#define MACID_CFG_SET_SGI(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 23, 1, __value)
+#define MACID_CFG_GET_BW(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 24, 2)
+#define MACID_CFG_SET_BW(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 24, 2, __value)
+#define MACID_CFG_GET_LDPC_CAP(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 26, 1)
+#define MACID_CFG_SET_LDPC_CAP(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 26, 1, __value)
+#define MACID_CFG_GET_NO_UPDATE(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 27, 1)
+#define MACID_CFG_SET_NO_UPDATE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 27, 1, __value)
+#define MACID_CFG_GET_WHT_EN(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 28, 2)
+#define MACID_CFG_SET_WHT_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 28, 2, __value)
+#define MACID_CFG_GET_DISPT(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 30, 1)
+#define MACID_CFG_SET_DISPT(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 30, 1, __value)
+#define MACID_CFG_GET_DISRA(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 31, 1)
+#define MACID_CFG_SET_DISRA(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 31, 1, __value)
+#define MACID_CFG_GET_RATE_MASK7_0(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X04, 0, 8)
+#define MACID_CFG_SET_RATE_MASK7_0(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 0, 8, __value)
+#define MACID_CFG_GET_RATE_MASK15_8(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X04, 8, 8)
+#define MACID_CFG_SET_RATE_MASK15_8(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 8, 8, __value)
+#define MACID_CFG_GET_RATE_MASK23_16(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 16, 8)
+#define MACID_CFG_SET_RATE_MASK23_16(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 16, 8, __value)
+#define MACID_CFG_GET_RATE_MASK31_24(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 24, 8)
+#define MACID_CFG_SET_RATE_MASK31_24(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 24, 8, __value)
+#define TXBF_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define TXBF_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define TXBF_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define TXBF_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define TXBF_GET_NDPA0_HEAD_PAGE(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 8)
+#define TXBF_SET_NDPA0_HEAD_PAGE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 8, __value)
+#define TXBF_GET_NDPA1_HEAD_PAGE(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 8)
+#define TXBF_SET_NDPA1_HEAD_PAGE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 8, __value)
+#define TXBF_GET_PERIOD_0(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 24, 8)
+#define TXBF_SET_PERIOD_0(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 24, 8, __value)
+#define RSSI_SETTING_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define RSSI_SETTING_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define RSSI_SETTING_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define RSSI_SETTING_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define RSSI_SETTING_GET_MAC_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 8)
+#define RSSI_SETTING_SET_MAC_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 8, __value)
+#define RSSI_SETTING_GET_RSSI(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 24, 7)
+#define RSSI_SETTING_SET_RSSI(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 24, 7, __value)
+#define RSSI_SETTING_GET_RA_INFO(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X04, 0, 8)
+#define RSSI_SETTING_SET_RA_INFO(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 0, 8, __value)
+#define AP_REQ_TXRPT_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define AP_REQ_TXRPT_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define AP_REQ_TXRPT_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define AP_REQ_TXRPT_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define AP_REQ_TXRPT_GET_STA1_MACID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 8)
+#define AP_REQ_TXRPT_SET_STA1_MACID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 8, __value)
+#define AP_REQ_TXRPT_GET_STA2_MACID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 8)
+#define AP_REQ_TXRPT_SET_STA2_MACID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 8, __value)
+#define AP_REQ_TXRPT_GET_RTY_OK_TOTAL(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 24, 1)
+#define AP_REQ_TXRPT_SET_RTY_OK_TOTAL(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 24, 1, __value)
+#define AP_REQ_TXRPT_GET_RTY_CNT_MACID(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 25, 1)
+#define AP_REQ_TXRPT_SET_RTY_CNT_MACID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 25, 1, __value)
+#define INIT_RATE_COLLECTION_GET_CMD_ID(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define INIT_RATE_COLLECTION_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define INIT_RATE_COLLECTION_GET_CLASS(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define INIT_RATE_COLLECTION_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define INIT_RATE_COLLECTION_GET_STA1_MACID(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 8)
+#define INIT_RATE_COLLECTION_SET_STA1_MACID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 8, __value)
+#define INIT_RATE_COLLECTION_GET_STA2_MACID(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 8)
+#define INIT_RATE_COLLECTION_SET_STA2_MACID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 8, __value)
+#define INIT_RATE_COLLECTION_GET_STA3_MACID(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 24, 8)
+#define INIT_RATE_COLLECTION_SET_STA3_MACID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 24, 8, __value)
+#define INIT_RATE_COLLECTION_GET_STA4_MACID(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 0, 8)
+#define INIT_RATE_COLLECTION_SET_STA4_MACID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 0, 8, __value)
+#define INIT_RATE_COLLECTION_GET_STA5_MACID(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 8, 8)
+#define INIT_RATE_COLLECTION_SET_STA5_MACID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 8, 8, __value)
+#define INIT_RATE_COLLECTION_GET_STA6_MACID(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 16, 8)
+#define INIT_RATE_COLLECTION_SET_STA6_MACID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 16, 8, __value)
+#define INIT_RATE_COLLECTION_GET_STA7_MACID(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 24, 8)
+#define INIT_RATE_COLLECTION_SET_STA7_MACID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 24, 8, __value)
+#define IQK_OFFLOAD_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define IQK_OFFLOAD_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define IQK_OFFLOAD_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define IQK_OFFLOAD_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define IQK_OFFLOAD_GET_CHANNEL(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 8)
+#define IQK_OFFLOAD_SET_CHANNEL(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 8, __value)
+#define IQK_OFFLOAD_GET_BWBAND(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 8)
+#define IQK_OFFLOAD_SET_BWBAND(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 8, __value)
+#define IQK_OFFLOAD_GET_EXTPALNA(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 24, 8)
+#define IQK_OFFLOAD_SET_EXTPALNA(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 24, 8, __value)
+#define MACID_CFG_3SS_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define MACID_CFG_3SS_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define MACID_CFG_3SS_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define MACID_CFG_3SS_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define MACID_CFG_3SS_GET_MACID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 8)
+#define MACID_CFG_3SS_SET_MACID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 8, __value)
+#define MACID_CFG_3SS_GET_RATE_MASK_39_32(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 0, 8)
+#define MACID_CFG_3SS_SET_RATE_MASK_39_32(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 0, 8, __value)
+#define MACID_CFG_3SS_GET_RATE_MASK_47_40(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 8, 8)
+#define MACID_CFG_3SS_SET_RATE_MASK_47_40(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 8, 8, __value)
+#define RA_PARA_ADJUST_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define RA_PARA_ADJUST_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define RA_PARA_ADJUST_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define RA_PARA_ADJUST_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define RA_PARA_ADJUST_GET_MAC_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 8)
+#define RA_PARA_ADJUST_SET_MAC_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 8, __value)
+#define RA_PARA_ADJUST_GET_PARAMETER_INDEX(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 8)
+#define RA_PARA_ADJUST_SET_PARAMETER_INDEX(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 8, __value)
+#define RA_PARA_ADJUST_GET_RATE_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 24, 8)
+#define RA_PARA_ADJUST_SET_RATE_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 24, 8, __value)
+#define RA_PARA_ADJUST_GET_VALUE_BYTE0(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 0, 8)
+#define RA_PARA_ADJUST_SET_VALUE_BYTE0(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 0, 8, __value)
+#define RA_PARA_ADJUST_GET_VALUE_BYTE1(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 8, 8)
+#define RA_PARA_ADJUST_SET_VALUE_BYTE1(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 8, 8, __value)
+#define RA_PARA_ADJUST_GET_ASK_FW_FOR_FW_PARA(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 16, 8)
+#define RA_PARA_ADJUST_SET_ASK_FW_FOR_FW_PARA(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 16, 8, __value)
+#define WWLAN_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define WWLAN_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define WWLAN_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define WWLAN_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define WWLAN_GET_FUNC_EN(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 1)
+#define WWLAN_SET_FUNC_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 1, __value)
+#define WWLAN_GET_PATTERM_MAT_EN(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 9, 1)
+#define WWLAN_SET_PATTERM_MAT_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 9, 1, __value)
+#define WWLAN_GET_MAGIC_PKT_EN(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 10, 1)
+#define WWLAN_SET_MAGIC_PKT_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 10, 1, __value)
+#define WWLAN_GET_UNICAST_WAKEUP_EN(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 11, 1)
+#define WWLAN_SET_UNICAST_WAKEUP_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 11, 1, __value)
+#define WWLAN_GET_ALL_PKT_DROP(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 12, 1)
+#define WWLAN_SET_ALL_PKT_DROP(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 12, 1, __value)
+#define WWLAN_GET_GPIO_ACTIVE(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 13, 1)
+#define WWLAN_SET_GPIO_ACTIVE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 13, 1, __value)
+#define WWLAN_GET_REKEY_WAKEUP_EN(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 14, 1)
+#define WWLAN_SET_REKEY_WAKEUP_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 14, 1, __value)
+#define WWLAN_GET_DEAUTH_WAKEUP_EN(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 15, 1)
+#define WWLAN_SET_DEAUTH_WAKEUP_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 15, 1, __value)
+#define WWLAN_GET_GPIO_NUM(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 7)
+#define WWLAN_SET_GPIO_NUM(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 7, __value)
+#define WWLAN_GET_DATAPIN_WAKEUP_EN(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 23, 1)
+#define WWLAN_SET_DATAPIN_WAKEUP_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 23, 1, __value)
+#define WWLAN_GET_GPIO_DURATION(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 24, 8)
+#define WWLAN_SET_GPIO_DURATION(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 24, 8, __value)
+#define WWLAN_GET_GPIO_PLUS_EN(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X04, 0, 1)
+#define WWLAN_SET_GPIO_PLUS_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 0, 1, __value)
+#define WWLAN_GET_GPIO_PULSE_COUNT(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X04, 1, 7)
+#define WWLAN_SET_GPIO_PULSE_COUNT(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 1, 7, __value)
+#define WWLAN_GET_DISABLE_UPHY(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X04, 8, 1)
+#define WWLAN_SET_DISABLE_UPHY(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 8, 1, __value)
+#define WWLAN_GET_HST2DEV_EN(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X04, 9, 1)
+#define WWLAN_SET_HST2DEV_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 9, 1, __value)
+#define WWLAN_GET_GPIO_DURATION_MS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X04, 10, 1)
+#define WWLAN_SET_GPIO_DURATION_MS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 10, 1, __value)
+#define REMOTE_WAKE_CTRL_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define REMOTE_WAKE_CTRL_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define REMOTE_WAKE_CTRL_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define REMOTE_WAKE_CTRL_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define REMOTE_WAKE_CTRL_GET_REMOTE_WAKE_CTRL_EN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 1)
+#define REMOTE_WAKE_CTRL_SET_REMOTE_WAKE_CTRL_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 1, __value)
+#define REMOTE_WAKE_CTRL_GET_ARP_EN(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 9, 1)
+#define REMOTE_WAKE_CTRL_SET_ARP_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 9, 1, __value)
+#define REMOTE_WAKE_CTRL_GET_NDP_EN(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 10, 1)
+#define REMOTE_WAKE_CTRL_SET_NDP_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 10, 1, __value)
+#define REMOTE_WAKE_CTRL_GET_GTK_EN(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 11, 1)
+#define REMOTE_WAKE_CTRL_SET_GTK_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 11, 1, __value)
+#define REMOTE_WAKE_CTRL_GET_NLO_OFFLOAD_EN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 12, 1)
+#define REMOTE_WAKE_CTRL_SET_NLO_OFFLOAD_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 12, 1, __value)
+#define REMOTE_WAKE_CTRL_GET_REAL_WOW_V1_EN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 13, 1)
+#define REMOTE_WAKE_CTRL_SET_REAL_WOW_V1_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 13, 1, __value)
+#define REMOTE_WAKE_CTRL_GET_REAL_WOW_V2_EN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 14, 1)
+#define REMOTE_WAKE_CTRL_SET_REAL_WOW_V2_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 14, 1, __value)
+#define REMOTE_WAKE_CTRL_GET_FW_UNICAST(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 15, 1)
+#define REMOTE_WAKE_CTRL_SET_FW_UNICAST(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 15, 1, __value)
+#define REMOTE_WAKE_CTRL_GET_P2P_OFFLOAD_EN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 1)
+#define REMOTE_WAKE_CTRL_SET_P2P_OFFLOAD_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 1, __value)
+#define REMOTE_WAKE_CTRL_GET_RUNTIME_PM_EN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 17, 1)
+#define REMOTE_WAKE_CTRL_SET_RUNTIME_PM_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 17, 1, __value)
+#define REMOTE_WAKE_CTRL_GET_NET_BIOS_DROP_EN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 18, 1)
+#define REMOTE_WAKE_CTRL_SET_NET_BIOS_DROP_EN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 18, 1, __value)
+#define REMOTE_WAKE_CTRL_GET_ARP_ACTION(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 24, 1)
+#define REMOTE_WAKE_CTRL_SET_ARP_ACTION(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 24, 1, __value)
+#define REMOTE_WAKE_CTRL_GET_FW_PARSING_UNTIL_WAKEUP(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 28, 1)
+#define REMOTE_WAKE_CTRL_SET_FW_PARSING_UNTIL_WAKEUP(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 28, 1, __value)
+#define REMOTE_WAKE_CTRL_GET_FW_PARSING_AFTER_WAKEUP(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 29, 1)
+#define REMOTE_WAKE_CTRL_SET_FW_PARSING_AFTER_WAKEUP(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 29, 1, __value)
+#define AOAC_GLOBAL_INFO_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define AOAC_GLOBAL_INFO_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define AOAC_GLOBAL_INFO_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define AOAC_GLOBAL_INFO_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define AOAC_GLOBAL_INFO_GET_PAIR_WISE_ENC_ALG(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 8)
+#define AOAC_GLOBAL_INFO_SET_PAIR_WISE_ENC_ALG(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 8, __value)
+#define AOAC_GLOBAL_INFO_GET_GROUP_ENC_ALG(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 8)
+#define AOAC_GLOBAL_INFO_SET_GROUP_ENC_ALG(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 8, __value)
+#define AOAC_RSVD_PAGE_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define AOAC_RSVD_PAGE_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define AOAC_RSVD_PAGE_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define AOAC_RSVD_PAGE_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define AOAC_RSVD_PAGE_GET_LOC_REMOTE_CTRL_INFO(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 8)
+#define AOAC_RSVD_PAGE_SET_LOC_REMOTE_CTRL_INFO(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 8, __value)
+#define AOAC_RSVD_PAGE_GET_LOC_ARP_RESPONSE(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 8)
+#define AOAC_RSVD_PAGE_SET_LOC_ARP_RESPONSE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 8, __value)
+#define AOAC_RSVD_PAGE_GET_LOC_NEIGHBOR_ADVERTISEMENT(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 24, 8)
+#define AOAC_RSVD_PAGE_SET_LOC_NEIGHBOR_ADVERTISEMENT(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 24, 8, __value)
+#define AOAC_RSVD_PAGE_GET_LOC_GTK_RSP(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 0, 8)
+#define AOAC_RSVD_PAGE_SET_LOC_GTK_RSP(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 0, 8, __value)
+#define AOAC_RSVD_PAGE_GET_LOC_GTK_INFO(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 8, 8)
+#define AOAC_RSVD_PAGE_SET_LOC_GTK_INFO(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 8, 8, __value)
+#define AOAC_RSVD_PAGE_GET_LOC_GTK_EXT_MEM(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 16, 8)
+#define AOAC_RSVD_PAGE_SET_LOC_GTK_EXT_MEM(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 16, 8, __value)
+#define AOAC_RSVD_PAGE_GET_LOC_NDP_INFO(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 24, 8)
+#define AOAC_RSVD_PAGE_SET_LOC_NDP_INFO(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 24, 8, __value)
+#define AOAC_RSVD_PAGE2_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define AOAC_RSVD_PAGE2_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define AOAC_RSVD_PAGE2_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define AOAC_RSVD_PAGE2_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define AOAC_RSVD_PAGE2_GET_LOC_ROUTER_SOLICATION(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 8)
+#define AOAC_RSVD_PAGE2_SET_LOC_ROUTER_SOLICATION(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 8, __value)
+#define AOAC_RSVD_PAGE2_GET_LOC_BUBBLE_PACKET(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 8)
+#define AOAC_RSVD_PAGE2_SET_LOC_BUBBLE_PACKET(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 8, __value)
+#define AOAC_RSVD_PAGE2_GET_LOC_TEREDO_INFO(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 24, 8)
+#define AOAC_RSVD_PAGE2_SET_LOC_TEREDO_INFO(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 24, 8, __value)
+#define AOAC_RSVD_PAGE2_GET_LOC_REALWOW_INFO(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 0, 8)
+#define AOAC_RSVD_PAGE2_SET_LOC_REALWOW_INFO(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 0, 8, __value)
+#define AOAC_RSVD_PAGE2_GET_LOC_KEEP_ALIVE_PKT(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 8, 8)
+#define AOAC_RSVD_PAGE2_SET_LOC_KEEP_ALIVE_PKT(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 8, 8, __value)
+#define AOAC_RSVD_PAGE2_GET_LOC_ACK_PATTERN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 16, 8)
+#define AOAC_RSVD_PAGE2_SET_LOC_ACK_PATTERN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 16, 8, __value)
+#define AOAC_RSVD_PAGE2_GET_LOC_WAKEUP_PATTERN(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X04, 24, 8)
+#define AOAC_RSVD_PAGE2_SET_LOC_WAKEUP_PATTERN(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X04, 24, 8, __value)
+#define D0_SCAN_OFFLOAD_INFO_GET_CMD_ID(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define D0_SCAN_OFFLOAD_INFO_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define D0_SCAN_OFFLOAD_INFO_GET_CLASS(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define D0_SCAN_OFFLOAD_INFO_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define D0_SCAN_OFFLOAD_INFO_GET_LOC_CHANNEL_INFO(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 8)
+#define D0_SCAN_OFFLOAD_INFO_SET_LOC_CHANNEL_INFO(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 8, __value)
+#define CHANNEL_SWITCH_OFFLOAD_GET_CMD_ID(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define CHANNEL_SWITCH_OFFLOAD_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define CHANNEL_SWITCH_OFFLOAD_GET_CLASS(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define CHANNEL_SWITCH_OFFLOAD_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define CHANNEL_SWITCH_OFFLOAD_GET_CHANNEL_NUM(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 8)
+#define CHANNEL_SWITCH_OFFLOAD_SET_CHANNEL_NUM(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 8, __value)
+#define CHANNEL_SWITCH_OFFLOAD_GET_EN_RFE(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 8)
+#define CHANNEL_SWITCH_OFFLOAD_SET_EN_RFE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 8, __value)
+#define CHANNEL_SWITCH_OFFLOAD_GET_RFE_TYPE(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 24, 8)
+#define CHANNEL_SWITCH_OFFLOAD_SET_RFE_TYPE(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 24, 8, __value)
+#define AOAC_RSVD_PAGE3_GET_CMD_ID(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 0, 5)
+#define AOAC_RSVD_PAGE3_SET_CMD_ID(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 0, 5, __value)
+#define AOAC_RSVD_PAGE3_GET_CLASS(__h2c) LE_BITS_TO_4BYTE(__h2c + 0X00, 5, 3)
+#define AOAC_RSVD_PAGE3_SET_CLASS(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 5, 3, __value)
+#define AOAC_RSVD_PAGE3_GET_LOC_NLO_INFO(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 8, 8)
+#define AOAC_RSVD_PAGE3_SET_LOC_NLO_INFO(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 8, 8, __value)
+#define AOAC_RSVD_PAGE3_GET_LOC_AOAC_REPORT(__h2c) \
+ LE_BITS_TO_4BYTE(__h2c + 0X00, 16, 8)
+#define AOAC_RSVD_PAGE3_SET_LOC_AOAC_REPORT(__h2c, __value) \
+ SET_BITS_TO_LE_4BYTE(__h2c + 0X00, 16, 8, __value)
+#endif
diff --git a/drivers/staging/rtlwifi/halmac/halmac_pcie_reg.h b/drivers/staging/rtlwifi/halmac/halmac_pcie_reg.h
new file mode 100644
index 0000000..4178067
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_pcie_reg.h
@@ -0,0 +1,28 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __HALMAC_PCIE_REG_H__
+#define __HALMAC_PCIE_REG_H__
+
+#endif /* __HALMAC_PCIE_REG_H__ */
diff --git a/drivers/staging/rtlwifi/halmac/halmac_pwr_seq_cmd.h b/drivers/staging/rtlwifi/halmac/halmac_pwr_seq_cmd.h
new file mode 100644
index 0000000..13a65a4
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_pwr_seq_cmd.h
@@ -0,0 +1,116 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef HALMAC_POWER_SEQUENCE_CMD
+#define HALMAC_POWER_SEQUENCE_CMD
+
+#include "halmac_2_platform.h"
+#include "halmac_type.h"
+
+#define HALMAC_POLLING_READY_TIMEOUT_COUNT 20000
+
+/* The value of cmd : 4 bits */
+
+/* offset : the read register offset
+ * msk : the mask of the read value
+ * value : N/A, left by 0
+ * Note : dirver shall implement this function by read & msk
+ */
+#define HALMAC_PWR_CMD_READ 0x00
+/*
+ * offset: the read register offset
+ * msk: the mask of the write bits
+ * value: write value
+ * Note: driver shall implement this cmd by read & msk after write
+ */
+#define HALMAC_PWR_CMD_WRITE 0x01
+/* offset: the read register offset
+ * msk: the mask of the polled value
+ * value: the value to be polled, masked by the msd field.
+ * Note: driver shall implement this cmd by
+ * do{
+ * if( (Read(offset) & msk) == (value & msk) )
+ * break;
+ * } while(not timeout);
+ */
+#define HALMAC_PWR_CMD_POLLING 0x02
+/* offset: the value to delay
+ * msk: N/A
+ * value: the unit of delay, 0: us, 1: ms
+ */
+#define HALMAC_PWR_CMD_DELAY 0x03
+/* offset: N/A
+ * msk: N/A
+ * value: N/A
+ */
+#define HALMAC_PWR_CMD_END 0x04
+
+/* The value of base : 4 bits */
+
+/* define the base address of each block */
+#define HALMAC_PWR_BASEADDR_MAC 0x00
+#define HALMAC_PWR_BASEADDR_USB 0x01
+#define HALMAC_PWR_BASEADDR_PCIE 0x02
+#define HALMAC_PWR_BASEADDR_SDIO 0x03
+
+/* The value of interface_msk : 4 bits */
+#define HALMAC_PWR_INTF_SDIO_MSK BIT(0)
+#define HALMAC_PWR_INTF_USB_MSK BIT(1)
+#define HALMAC_PWR_INTF_PCI_MSK BIT(2)
+#define HALMAC_PWR_INTF_ALL_MSK (BIT(0) | BIT(1) | BIT(2) | BIT(3))
+
+/* The value of fab_msk : 4 bits */
+#define HALMAC_PWR_FAB_TSMC_MSK BIT(0)
+#define HALMAC_PWR_FAB_UMC_MSK BIT(1)
+#define HALMAC_PWR_FAB_ALL_MSK (BIT(0) | BIT(1) | BIT(2) | BIT(3))
+
+/* The value of cut_msk : 8 bits */
+#define HALMAC_PWR_CUT_TESTCHIP_MSK BIT(0)
+#define HALMAC_PWR_CUT_A_MSK BIT(1)
+#define HALMAC_PWR_CUT_B_MSK BIT(2)
+#define HALMAC_PWR_CUT_C_MSK BIT(3)
+#define HALMAC_PWR_CUT_D_MSK BIT(4)
+#define HALMAC_PWR_CUT_E_MSK BIT(5)
+#define HALMAC_PWR_CUT_F_MSK BIT(6)
+#define HALMAC_PWR_CUT_G_MSK BIT(7)
+#define HALMAC_PWR_CUT_ALL_MSK 0xFF
+
+enum halmac_pwrseq_cmd_delay_unit_ {
+ HALMAC_PWRSEQ_DELAY_US,
+ HALMAC_PWRSEQ_DELAY_MS,
+};
+
+/*Don't care endian issue, because element of pwer seq vector is fixed address*/
+struct halmac_wl_pwr_cfg_ {
+ u16 offset;
+ u8 cut_msk;
+ u8 fab_msk : 4;
+ u8 interface_msk : 4;
+ u8 base : 4;
+ u8 cmd : 4;
+ u8 msk;
+ u8 value;
+};
+
+#endif
diff --git a/drivers/staging/rtlwifi/halmac/halmac_reg2.h b/drivers/staging/rtlwifi/halmac/halmac_reg2.h
new file mode 100644
index 0000000..bebf974
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_reg2.h
@@ -0,0 +1,1132 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __HALMAC_COM_REG_H__
+#define __HALMAC_COM_REG_H__
+/*-------------------------Modification Log-----------------------------------
+ * For Page0, it is based on Combo_And_WL_Only_Page0_Reg.xls SVN524
+ * The supported IC are 8723A, 8881A, 8723B, 8192E, 8881A
+ * 8812A and 8188E is not included in page0 register
+ *
+ * For other pages, it is based on MAC_Register.doc SVN502
+ * Most IC is the same with 8812A
+ *-------------------------Modification Log-----------------------------------
+ */
+
+/*--------------------------Include File--------------------------------------*/
+/*--------------------------Include File--------------------------------------*/
+
+#define REG_SYS_ISO_CTRL 0x0000
+
+#define REG_SDIO_TX_CTRL 0x10250000
+
+#define REG_SYS_FUNC_EN 0x0002
+#define REG_SYS_PW_CTRL 0x0004
+#define REG_SYS_CLK_CTRL 0x0008
+#define REG_SYS_EEPROM_CTRL 0x000A
+#define REG_EE_VPD 0x000C
+#define REG_SYS_SWR_CTRL1 0x0010
+#define REG_SYS_SWR_CTRL2 0x0014
+
+#define REG_SDIO_HIMR 0x10250014
+
+#define REG_SYS_SWR_CTRL3 0x0018
+
+#define REG_SDIO_HISR 0x10250018
+
+#define REG_RSV_CTRL 0x001C
+
+#define REG_SDIO_RX_REQ_LEN 0x1025001C
+
+#define REG_RF_CTRL 0x001F
+
+#define REG_SDIO_FREE_TXPG_SEQ_V1 0x1025001F
+
+#define REG_AFE_LDO_CTRL 0x0020
+
+#define REG_SDIO_FREE_TXPG 0x10250020
+
+#define REG_AFE_CTRL1 0x0024
+
+#define REG_SDIO_FREE_TXPG2 0x10250024
+
+#define REG_AFE_CTRL2 0x0028
+
+#define REG_SDIO_OQT_FREE_TXPG_V1 0x10250028
+
+#define REG_AFE_CTRL3 0x002C
+#define REG_EFUSE_CTRL 0x0030
+
+#define REG_SDIO_HTSFR_INFO 0x10250030
+
+#define REG_LDO_EFUSE_CTRL 0x0034
+#define REG_PWR_OPTION_CTRL 0x0038
+
+#define REG_SDIO_HCPWM1_V2 0x10250038
+#define REG_SDIO_HCPWM2_V2 0x1025003A
+
+#define REG_CAL_TIMER 0x003C
+#define REG_ACLK_MON 0x003E
+#define REG_GPIO_MUXCFG 0x0040
+
+#define REG_SDIO_INDIRECT_REG_CFG 0x10250040
+
+#define REG_GPIO_PIN_CTRL 0x0044
+
+#define REG_SDIO_INDIRECT_REG_DATA 0x10250044
+
+#define REG_GPIO_INTM 0x0048
+#define REG_LED_CFG 0x004C
+#define REG_FSIMR 0x0050
+#define REG_FSISR 0x0054
+#define REG_HSIMR 0x0058
+#define REG_HSISR 0x005C
+#define REG_GPIO_EXT_CTRL 0x0060
+
+#define REG_SDIO_H2C 0x10250060
+
+#define REG_PAD_CTRL1 0x0064
+
+#define REG_SDIO_C2H 0x10250064
+
+#define REG_WL_BT_PWR_CTRL 0x0068
+
+#define REG_SDM_DEBUG 0x006C
+
+#define REG_SYS_SDIO_CTRL 0x0070
+
+#define REG_HCI_OPT_CTRL 0x0074
+
+#define REG_AFE_CTRL4 0x0078
+
+#define REG_LDO_SWR_CTRL 0x007C
+
+#define REG_MCUFW_CTRL 0x0080
+
+#define REG_SDIO_HRPWM1 0x10250080
+#define REG_SDIO_HRPWM2 0x10250082
+
+#define REG_MCU_TST_CFG 0x0084
+
+#define REG_SDIO_HPS_CLKR 0x10250084
+#define REG_SDIO_BUS_CTRL 0x10250085
+
+#define REG_SDIO_HSUS_CTRL 0x10250086
+
+#define REG_HMEBOX_E0_E1 0x0088
+
+#define REG_SDIO_RESPONSE_TIMER 0x10250088
+
+#define REG_SDIO_CMD_CRC 0x1025008A
+
+#define REG_HMEBOX_E2_E3 0x008C
+#define REG_WLLPS_CTRL 0x0090
+
+#define REG_SDIO_HSISR 0x10250090
+#define REG_SDIO_HSIMR 0x10250091
+
+#define REG_AFE_CTRL5 0x0094
+
+#define REG_GPIO_DEBOUNCE_CTRL 0x0098
+#define REG_RPWM2 0x009C
+#define REG_SYSON_FSM_MON 0x00A0
+
+#define REG_AFE_CTRL6 0x00A4
+
+#define REG_PMC_DBG_CTRL1 0x00A8
+
+#define REG_AFE_CTRL7 0x00AC
+
+#define REG_HIMR0 0x00B0
+#define REG_HISR0 0x00B4
+#define REG_HIMR1 0x00B8
+#define REG_HISR1 0x00BC
+#define REG_DBG_PORT_SEL 0x00C0
+
+#define REG_SDIO_ERR_RPT 0x102500C0
+#define REG_SDIO_CMD_ERRCNT 0x102500C1
+#define REG_SDIO_DATA_ERRCNT 0x102500C2
+
+#define REG_PAD_CTRL2 0x00C4
+
+#define REG_SDIO_CMD_ERR_CONTENT 0x102500C4
+
+#define REG_SDIO_CRC_ERR_IDX 0x102500C9
+#define REG_SDIO_DATA_CRC 0x102500CA
+#define REG_SDIO_DATA_REPLY_TIME 0x102500CB
+
+#define REG_PMC_DBG_CTRL2 0x00CC
+#define REG_BIST_CTRL 0x00D0
+#define REG_BIST_RPT 0x00D4
+#define REG_MEM_CTRL 0x00D8
+
+#define REG_AFE_CTRL8 0x00DC
+
+#define REG_USB_SIE_INTF 0x00E0
+#define REG_PCIE_MIO_INTF 0x00E4
+#define REG_PCIE_MIO_INTD 0x00E8
+
+#define REG_WLRF1 0x00EC
+
+#define REG_SYS_CFG1 0x00F0
+#define REG_SYS_STATUS1 0x00F4
+#define REG_SYS_STATUS2 0x00F8
+#define REG_SYS_CFG2 0x00FC
+#define REG_CR 0x0100
+
+#define REG_PKT_BUFF_ACCESS_CTRL 0x0106
+
+#define REG_TSF_CLK_STATE 0x0108
+#define REG_TXDMA_PQ_MAP 0x010C
+#define REG_TRXFF_BNDY 0x0114
+
+#define REG_PTA_I2C_MBOX 0x0118
+
+#define REG_RXFF_BNDY 0x011C
+
+#define REG_FE1IMR 0x0120
+
+#define REG_FE1ISR 0x0124
+
+#define REG_CPWM 0x012C
+#define REG_FWIMR 0x0130
+#define REG_FWISR 0x0134
+#define REG_FTIMR 0x0138
+#define REG_FTISR 0x013C
+#define REG_PKTBUF_DBG_CTRL 0x0140
+#define REG_PKTBUF_DBG_DATA_L 0x0144
+#define REG_PKTBUF_DBG_DATA_H 0x0148
+#define REG_CPWM2 0x014C
+#define REG_TC0_CTRL 0x0150
+#define REG_TC1_CTRL 0x0154
+#define REG_TC2_CTRL 0x0158
+#define REG_TC3_CTRL 0x015C
+#define REG_TC4_CTRL 0x0160
+#define REG_TCUNIT_BASE 0x0164
+#define REG_TC5_CTRL 0x0168
+#define REG_TC6_CTRL 0x016C
+#define REG_MBIST_FAIL 0x0170
+#define REG_MBIST_START_PAUSE 0x0174
+#define REG_MBIST_DONE 0x0178
+
+#define REG_MBIST_FAIL_NRML 0x017C
+
+#define REG_AES_DECRPT_DATA 0x0180
+#define REG_AES_DECRPT_CFG 0x0184
+
+#define REG_TMETER 0x0190
+#define REG_OSC_32K_CTRL 0x0194
+#define REG_32K_CAL_REG1 0x0198
+#define REG_C2HEVT 0x01A0
+
+#define REG_C2HEVT_1 0x01A4
+#define REG_C2HEVT_2 0x01A8
+#define REG_C2HEVT_3 0x01AC
+
+#define REG_SW_DEFINED_PAGE1 0x01B8
+
+#define REG_MCUTST_I 0x01C0
+#define REG_MCUTST_II 0x01C4
+#define REG_FMETHR 0x01C8
+#define REG_HMETFR 0x01CC
+#define REG_HMEBOX0 0x01D0
+#define REG_HMEBOX1 0x01D4
+#define REG_HMEBOX2 0x01D8
+#define REG_HMEBOX3 0x01DC
+#define REG_LLT_INIT 0x01E0
+
+#define REG_LLT_INIT_ADDR 0x01E4
+
+#define REG_BB_ACCESS_CTRL 0x01E8
+#define REG_BB_ACCESS_DATA 0x01EC
+#define REG_HMEBOX_E0 0x01F0
+#define REG_HMEBOX_E1 0x01F4
+#define REG_HMEBOX_E2 0x01F8
+#define REG_HMEBOX_E3 0x01FC
+
+#define REG_FIFOPAGE_CTRL_1 0x0200
+
+#define REG_FIFOPAGE_CTRL_2 0x0204
+
+#define REG_AUTO_LLT_V1 0x0208
+
+#define REG_TXDMA_OFFSET_CHK 0x020C
+#define REG_TXDMA_STATUS 0x0210
+
+#define REG_TX_DMA_DBG 0x0214
+
+#define REG_TQPNT1 0x0218
+#define REG_TQPNT2 0x021C
+
+#define REG_TQPNT3 0x0220
+
+#define REG_TQPNT4 0x0224
+
+#define REG_RQPN_CTRL_1 0x0228
+#define REG_RQPN_CTRL_2 0x022C
+#define REG_FIFOPAGE_INFO_1 0x0230
+#define REG_FIFOPAGE_INFO_2 0x0234
+#define REG_FIFOPAGE_INFO_3 0x0238
+#define REG_FIFOPAGE_INFO_4 0x023C
+#define REG_FIFOPAGE_INFO_5 0x0240
+
+#define REG_H2C_HEAD 0x0244
+#define REG_H2C_TAIL 0x0248
+#define REG_H2C_READ_ADDR 0x024C
+#define REG_H2C_WR_ADDR 0x0250
+#define REG_H2C_INFO 0x0254
+
+#define REG_RXDMA_AGG_PG_TH 0x0280
+#define REG_RXPKT_NUM 0x0284
+#define REG_RXDMA_STATUS 0x0288
+#define REG_RXDMA_DPR 0x028C
+#define REG_RXDMA_MODE 0x0290
+#define REG_C2H_PKT 0x0294
+
+#define REG_FWFF_C2H 0x0298
+#define REG_FWFF_CTRL 0x029C
+#define REG_FWFF_PKT_INFO 0x02A0
+
+#define REG_PCIE_CTRL 0x0300
+
+#define REG_INT_MIG 0x0304
+#define REG_BCNQ_TXBD_DESA 0x0308
+#define REG_MGQ_TXBD_DESA 0x0310
+#define REG_VOQ_TXBD_DESA 0x0318
+#define REG_VIQ_TXBD_DESA 0x0320
+#define REG_BEQ_TXBD_DESA 0x0328
+#define REG_BKQ_TXBD_DESA 0x0330
+#define REG_RXQ_RXBD_DESA 0x0338
+#define REG_HI0Q_TXBD_DESA 0x0340
+#define REG_HI1Q_TXBD_DESA 0x0348
+#define REG_HI2Q_TXBD_DESA 0x0350
+#define REG_HI3Q_TXBD_DESA 0x0358
+#define REG_HI4Q_TXBD_DESA 0x0360
+#define REG_HI5Q_TXBD_DESA 0x0368
+#define REG_HI6Q_TXBD_DESA 0x0370
+#define REG_HI7Q_TXBD_DESA 0x0378
+#define REG_MGQ_TXBD_NUM 0x0380
+#define REG_RX_RXBD_NUM 0x0382
+#define REG_VOQ_TXBD_NUM 0x0384
+#define REG_VIQ_TXBD_NUM 0x0386
+#define REG_BEQ_TXBD_NUM 0x0388
+#define REG_BKQ_TXBD_NUM 0x038A
+#define REG_HI0Q_TXBD_NUM 0x038C
+#define REG_HI1Q_TXBD_NUM 0x038E
+#define REG_HI2Q_TXBD_NUM 0x0390
+#define REG_HI3Q_TXBD_NUM 0x0392
+#define REG_HI4Q_TXBD_NUM 0x0394
+#define REG_HI5Q_TXBD_NUM 0x0396
+#define REG_HI6Q_TXBD_NUM 0x0398
+#define REG_HI7Q_TXBD_NUM 0x039A
+#define REG_TSFTIMER_HCI 0x039C
+#define REG_BD_RWPTR_CLR 0x039C
+#define REG_VOQ_TXBD_IDX 0x03A0
+#define REG_VIQ_TXBD_IDX 0x03A4
+#define REG_BEQ_TXBD_IDX 0x03A8
+#define REG_BKQ_TXBD_IDX 0x03AC
+#define REG_MGQ_TXBD_IDX 0x03B0
+#define REG_RXQ_RXBD_IDX 0x03B4
+#define REG_HI0Q_TXBD_IDX 0x03B8
+#define REG_HI1Q_TXBD_IDX 0x03BC
+#define REG_HI2Q_TXBD_IDX 0x03C0
+#define REG_HI3Q_TXBD_IDX 0x03C4
+#define REG_HI4Q_TXBD_IDX 0x03C8
+#define REG_HI5Q_TXBD_IDX 0x03CC
+#define REG_HI6Q_TXBD_IDX 0x03D0
+#define REG_HI7Q_TXBD_IDX 0x03D4
+
+#define REG_DBG_SEL_V1 0x03D8
+
+#define REG_PCIE_HRPWM1_V1 0x03D9
+
+#define REG_PCIE_HCPWM1_V1 0x03DA
+
+#define REG_PCIE_CTRL2 0x03DB
+
+#define REG_PCIE_HRPWM2_V1 0x03DC
+
+#define REG_PCIE_HCPWM2_V1 0x03DE
+
+#define REG_PCIE_H2C_MSG_V1 0x03E0
+
+#define REG_PCIE_C2H_MSG_V1 0x03E4
+
+#define REG_DBI_WDATA_V1 0x03E8
+
+#define REG_DBI_RDATA_V1 0x03EC
+
+#define REG_DBI_FLAG_V1 0x03F0
+
+#define REG_MDIO_V1 0x03F4
+
+#define REG_PCIE_MIX_CFG 0x03F8
+
+#define REG_HCI_MIX_CFG 0x03FC
+
+#define REG_Q0_INFO 0x0400
+#define REG_Q1_INFO 0x0404
+#define REG_Q2_INFO 0x0408
+#define REG_Q3_INFO 0x040C
+#define REG_MGQ_INFO 0x0410
+#define REG_HIQ_INFO 0x0414
+#define REG_BCNQ_INFO 0x0418
+#define REG_TXPKT_EMPTY 0x041A
+#define REG_CPU_MGQ_INFO 0x041C
+#define REG_FWHW_TXQ_CTRL 0x0420
+
+#define REG_DATAFB_SEL 0x0423
+
+#define REG_BCNQ_BDNY_V1 0x0424
+
+#define REG_LIFETIME_EN 0x0426
+
+#define REG_SPEC_SIFS 0x0428
+#define REG_RETRY_LIMIT 0x042A
+#define REG_TXBF_CTRL 0x042C
+#define REG_DARFRC 0x0430
+#define REG_RARFRC 0x0438
+#define REG_RRSR 0x0440
+#define REG_ARFR0 0x0444
+#define REG_ARFR1_V1 0x044C
+#define REG_CCK_CHECK 0x0454
+
+#define REG_AMPDU_MAX_TIME_V1 0x0455
+
+#define REG_BCNQ1_BDNY_V1 0x0456
+
+#define REG_AMPDU_MAX_LENGTH 0x0458
+#define REG_ACQ_STOP 0x045C
+
+#define REG_NDPA_RATE 0x045D
+
+#define REG_TX_HANG_CTRL 0x045E
+#define REG_NDPA_OPT_CTRL 0x045F
+
+#define REG_RD_RESP_PKT_TH 0x0463
+#define REG_CMDQ_INFO 0x0464
+#define REG_Q4_INFO 0x0468
+#define REG_Q5_INFO 0x046C
+#define REG_Q6_INFO 0x0470
+#define REG_Q7_INFO 0x0474
+
+#define REG_WMAC_LBK_BUF_HD_V1 0x0478
+#define REG_MGQ_BDNY_V1 0x047A
+
+#define REG_TXRPT_CTRL 0x047C
+#define REG_INIRTS_RATE_SEL 0x0480
+#define REG_BASIC_CFEND_RATE 0x0481
+#define REG_STBC_CFEND_RATE 0x0482
+#define REG_DATA_SC 0x0483
+#define REG_MACID_SLEEP3 0x0484
+#define REG_MACID_SLEEP1 0x0488
+#define REG_ARFR2_V1 0x048C
+#define REG_ARFR3_V1 0x0494
+#define REG_ARFR4 0x049C
+#define REG_ARFR5 0x04A4
+#define REG_TXRPT_START_OFFSET 0x04AC
+
+#define REG_POWER_STAGE1 0x04B4
+
+#define REG_POWER_STAGE2 0x04B8
+
+#define REG_SW_AMPDU_BURST_MODE_CTRL 0x04BC
+#define REG_PKT_LIFE_TIME 0x04C0
+#define REG_STBC_SETTING 0x04C4
+#define REG_STBC_SETTING2 0x04C5
+#define REG_QUEUE_CTRL 0x04C6
+#define REG_SINGLE_AMPDU_CTRL 0x04C7
+#define REG_PROT_MODE_CTRL 0x04C8
+#define REG_BAR_MODE_CTRL 0x04CC
+#define REG_RA_TRY_RATE_AGG_LMT 0x04CF
+#define REG_MACID_SLEEP2 0x04D0
+#define REG_MACID_SLEEP 0x04D4
+
+#define REG_HW_SEQ0 0x04D8
+#define REG_HW_SEQ1 0x04DA
+#define REG_HW_SEQ2 0x04DC
+#define REG_HW_SEQ3 0x04DE
+
+#define REG_NULL_PKT_STATUS_V1 0x04E0
+
+#define REG_PTCL_ERR_STATUS 0x04E2
+
+#define REG_NULL_PKT_STATUS_EXTEND 0x04E3
+
+#define REG_VIDEO_ENHANCEMENT_FUN 0x04E4
+
+#define REG_BT_POLLUTE_PKT_CNT 0x04E8
+#define REG_PTCL_DBG 0x04EC
+
+#define REG_CPUMGQ_TIMER_CTRL2 0x04F4
+
+#define REG_DUMMY_PAGE4_V1 0x04FC
+#define REG_MOREDATA 0x04FE
+
+#define REG_EDCA_VO_PARAM 0x0500
+#define REG_EDCA_VI_PARAM 0x0504
+#define REG_EDCA_BE_PARAM 0x0508
+#define REG_EDCA_BK_PARAM 0x050C
+#define REG_BCNTCFG 0x0510
+#define REG_PIFS 0x0512
+#define REG_RDG_PIFS 0x0513
+#define REG_SIFS 0x0514
+#define REG_TSFTR_SYN_OFFSET 0x0518
+#define REG_AGGR_BREAK_TIME 0x051A
+#define REG_SLOT 0x051B
+#define REG_TX_PTCL_CTRL 0x0520
+#define REG_TXPAUSE 0x0522
+#define REG_DIS_TXREQ_CLR 0x0523
+#define REG_RD_CTRL 0x0524
+#define REG_MBSSID_CTRL 0x0526
+#define REG_P2PPS_CTRL 0x0527
+#define REG_PKT_LIFETIME_CTRL 0x0528
+#define REG_P2PPS_SPEC_STATE 0x052B
+
+#define REG_BAR_TX_CTRL 0x0530
+
+#define REG_QUEUE_INCOL_THR 0x0538
+#define REG_QUEUE_INCOL_EN 0x053C
+
+#define REG_TBTT_PROHIBIT 0x0540
+#define REG_P2PPS_STATE 0x0543
+#define REG_RD_NAV_NXT 0x0544
+#define REG_NAV_PROT_LEN 0x0546
+
+#define REG_BCN_CTRL 0x0550
+
+#define REG_BCN_CTRL_CLINT0 0x0551
+
+#define REG_MBID_NUM 0x0552
+#define REG_DUAL_TSF_RST 0x0553
+#define REG_MBSSID_BCN_SPACE 0x0554
+#define REG_DRVERLYINT 0x0558
+#define REG_BCNDMATIM 0x0559
+#define REG_ATIMWND 0x055A
+#define REG_USTIME_TSF 0x055C
+#define REG_BCN_MAX_ERR 0x055D
+#define REG_RXTSF_OFFSET_CCK 0x055E
+#define REG_RXTSF_OFFSET_OFDM 0x055F
+#define REG_TSFTR 0x0560
+
+#define REG_FREERUN_CNT 0x0568
+
+#define REG_ATIMWND1_V1 0x0570
+
+#define REG_TBTT_PROHIBIT_INFRA 0x0571
+
+#define REG_CTWND 0x0572
+#define REG_BCNIVLCUNT 0x0573
+#define REG_BCNDROPCTRL 0x0574
+#define REG_HGQ_TIMEOUT_PERIOD 0x0575
+
+#define REG_TXCMD_TIMEOUT_PERIOD 0x0576
+#define REG_MISC_CTRL 0x0577
+#define REG_BCN_CTRL_CLINT1 0x0578
+#define REG_BCN_CTRL_CLINT2 0x0579
+#define REG_BCN_CTRL_CLINT3 0x057A
+
+#define REG_EXTEND_CTRL 0x057B
+
+#define REG_P2PPS1_SPEC_STATE 0x057C
+#define REG_P2PPS1_STATE 0x057D
+#define REG_P2PPS2_SPEC_STATE 0x057E
+#define REG_P2PPS2_STATE 0x057F
+
+#define REG_PS_TIMER0 0x0580
+
+#define REG_PS_TIMER1 0x0584
+
+#define REG_PS_TIMER2 0x0588
+
+#define REG_TBTT_CTN_AREA 0x058C
+#define REG_FORCE_BCN_IFS 0x058E
+#define REG_TXOP_MIN 0x0590
+#define REG_PRE_BKF_TIME 0x0592
+#define REG_CROSS_TXOP_CTRL 0x0593
+
+#define REG_ATIMWND2 0x05A0
+#define REG_ATIMWND3 0x05A1
+#define REG_ATIMWND4 0x05A2
+#define REG_ATIMWND5 0x05A3
+#define REG_ATIMWND6 0x05A4
+#define REG_ATIMWND7 0x05A5
+#define REG_ATIMUGT 0x05A6
+#define REG_HIQ_NO_LMT_EN 0x05A7
+#define REG_DTIM_COUNTER_ROOT 0x05A8
+#define REG_DTIM_COUNTER_VAP1 0x05A9
+#define REG_DTIM_COUNTER_VAP2 0x05AA
+#define REG_DTIM_COUNTER_VAP3 0x05AB
+#define REG_DTIM_COUNTER_VAP4 0x05AC
+#define REG_DTIM_COUNTER_VAP5 0x05AD
+#define REG_DTIM_COUNTER_VAP6 0x05AE
+#define REG_DTIM_COUNTER_VAP7 0x05AF
+#define REG_DIS_ATIM 0x05B0
+
+#define REG_EARLY_128US 0x05B1
+#define REG_P2PPS1_CTRL 0x05B2
+#define REG_P2PPS2_CTRL 0x05B3
+#define REG_TIMER0_SRC_SEL 0x05B4
+#define REG_NOA_UNIT_SEL 0x05B5
+#define REG_P2POFF_DIS_TXTIME 0x05B7
+#define REG_MBSSID_BCN_SPACE2 0x05B8
+#define REG_MBSSID_BCN_SPACE3 0x05BC
+
+#define REG_ACMHWCTRL 0x05C0
+#define REG_ACMRSTCTRL 0x05C1
+#define REG_ACMAVG 0x05C2
+#define REG_VO_ADMTIME 0x05C4
+#define REG_VI_ADMTIME 0x05C6
+#define REG_BE_ADMTIME 0x05C8
+#define REG_EDCA_RANDOM_GEN 0x05CC
+#define REG_TXCMD_NOA_SEL 0x05CF
+#define REG_NOA_PARAM 0x05E0
+
+#define REG_P2P_RST 0x05F0
+#define REG_SCHEDULER_RST 0x05F1
+
+#define REG_SCH_TXCMD 0x05F8
+#define REG_PAGE5_DUMMY 0x05FC
+#define REG_WMAC_CR 0x0600
+
+#define REG_WMAC_FWPKT_CR 0x0601
+
+#define REG_BWOPMODE 0x0603
+
+#define REG_TCR 0x0604
+#define REG_RCR 0x0608
+#define REG_RX_PKT_LIMIT 0x060C
+#define REG_RX_DLK_TIME 0x060D
+#define REG_RX_DRVINFO_SZ 0x060F
+#define REG_MACID 0x0610
+#define REG_BSSID 0x0618
+#define REG_MAR 0x0620
+#define REG_MBIDCAMCFG_1 0x0628
+#define REG_MBIDCAMCFG_2 0x062C
+
+#define REG_WMAC_TCR_TSFT_OFS 0x0630
+#define REG_UDF_THSD 0x0632
+#define REG_ZLD_NUM 0x0633
+
+#define REG_STMP_THSD 0x0634
+#define REG_WMAC_TXTIMEOUT 0x0635
+#define REG_MCU_TEST_2_V1 0x0636
+
+#define REG_USTIME_EDCA 0x0638
+
+#define REG_MAC_SPEC_SIFS 0x063A
+#define REG_RESP_SIFS_CCK 0x063C
+#define REG_RESP_SIFS_OFDM 0x063E
+#define REG_ACKTO 0x0640
+#define REG_CTS2TO 0x0641
+#define REG_EIFS 0x0642
+
+#define REG_NAV_CTRL 0x0650
+#define REG_BACAMCMD 0x0654
+#define REG_BACAMCONTENT 0x0658
+#define REG_LBDLY 0x0660
+
+#define REG_WMAC_BACAM_RPMEN 0x0661
+
+#define REG_TX_RX 0x0662
+
+#define REG_WMAC_BITMAP_CTL 0x0663
+
+#define REG_RXERR_RPT 0x0664
+#define REG_WMAC_TRXPTCL_CTL 0x0668
+#define REG_CAMCMD 0x0670
+#define REG_CAMWRITE 0x0674
+#define REG_CAMREAD 0x0678
+#define REG_CAMDBG 0x067C
+#define REG_SECCFG 0x0680
+
+#define REG_RXFILTER_CATEGORY_1 0x0682
+#define REG_RXFILTER_ACTION_1 0x0683
+#define REG_RXFILTER_CATEGORY_2 0x0684
+#define REG_RXFILTER_ACTION_2 0x0685
+#define REG_RXFILTER_CATEGORY_3 0x0686
+#define REG_RXFILTER_ACTION_3 0x0687
+#define REG_RXFLTMAP3 0x0688
+#define REG_RXFLTMAP4 0x068A
+#define REG_RXFLTMAP5 0x068C
+#define REG_RXFLTMAP6 0x068E
+
+#define REG_WOW_CTRL 0x0690
+
+#define REG_NAN_RX_TSF_FILTER 0x0691
+
+#define REG_PS_RX_INFO 0x0692
+#define REG_WMMPS_UAPSD_TID 0x0693
+#define REG_LPNAV_CTRL 0x0694
+
+#define REG_WKFMCAM_CMD 0x0698
+#define REG_WKFMCAM_RWD 0x069C
+
+#define REG_RXFLTMAP0 0x06A0
+#define REG_RXFLTMAP1 0x06A2
+#define REG_RXFLTMAP 0x06A4
+#define REG_BCN_PSR_RPT 0x06A8
+
+#define REG_FLC_RPC 0x06AC
+#define REG_FLC_RPCT 0x06AD
+#define REG_FLC_PTS 0x06AE
+#define REG_FLC_TRPC 0x06AF
+
+#define REG_RXPKTMON_CTRL 0x06B0
+
+#define REG_STATE_MON 0x06B4
+
+#define REG_ERROR_MON 0x06B8
+#define REG_SEARCH_MACID 0x06BC
+
+#define REG_BT_COEX_TABLE 0x06C0
+
+#define REG_RXCMD_0 0x06D0
+#define REG_RXCMD_1 0x06D4
+
+#define REG_WMAC_RESP_TXINFO 0x06D8
+
+#define REG_BBPSF_CTRL 0x06DC
+
+#define REG_P2P_RX_BCN_NOA 0x06E0
+#define REG_ASSOCIATED_BFMER0_INFO 0x06E4
+#define REG_ASSOCIATED_BFMER1_INFO 0x06EC
+#define REG_TX_CSI_RPT_PARAM_BW20 0x06F4
+#define REG_TX_CSI_RPT_PARAM_BW40 0x06F8
+#define REG_TX_CSI_RPT_PARAM_BW80 0x06FC
+#define REG_MACID1 0x0700
+
+#define REG_BSSID1 0x0708
+
+#define REG_BCN_PSR_RPT1 0x0710
+#define REG_ASSOCIATED_BFMEE_SEL 0x0714
+#define REG_SND_PTCL_CTRL 0x0718
+#define REG_RX_CSI_RPT_INFO 0x071C
+#define REG_NS_ARP_CTRL 0x0720
+#define REG_NS_ARP_INFO 0x0724
+
+#define REG_BEAMFORMING_INFO_NSARP_V1 0x0728
+
+#define REG_BEAMFORMING_INFO_NSARP 0x072C
+
+#define REG_WMAC_RTX_CTX_SUBTYPE_CFG 0x0750
+
+#define REG_WMAC_SWAES_CFG 0x0760
+
+#define REG_BT_COEX_V2 0x0762
+
+#define REG_BT_COEX 0x0764
+
+#define REG_WLAN_ACT_MASK_CTRL 0x0768
+
+#define REG_BT_COEX_ENHANCED_INTR_CTRL 0x076E
+
+#define REG_BT_ACT_STATISTICS 0x0770
+
+#define REG_BT_STATISTICS_CONTROL_REGISTER 0x0778
+
+#define REG_BT_STATUS_REPORT_REGISTER 0x077C
+
+#define REG_BT_INTERRUPT_CONTROL_REGISTER 0x0780
+
+#define REG_WLAN_REPORT_TIME_OUT_CONTROL_REGISTER 0x0784
+
+#define REG_BT_ISOLATION_TABLE_REGISTER_REGISTER 0x0785
+
+#define REG_BT_INTERRUPT_STATUS_REGISTER 0x078F
+
+#define REG_BT_TDMA_TIME_REGISTER 0x0790
+
+#define REG_BT_ACT_REGISTER 0x0794
+
+#define REG_OBFF_CTRL_BASIC 0x0798
+
+#define REG_OBFF_CTRL2_TIMER 0x079C
+
+#define REG_LTR_CTRL_BASIC 0x07A0
+
+#define REG_LTR_CTRL2_TIMER_THRESHOLD 0x07A4
+
+#define REG_LTR_IDLE_LATENCY_V1 0x07A8
+#define REG_LTR_ACTIVE_LATENCY_V1 0x07AC
+
+#define REG_ANTENNA_TRAINING_CONTROL_REGISTER 0x07B0
+
+#define REG_WMAC_PKTCNT_RWD 0x07B8
+#define REG_WMAC_PKTCNT_CTRL 0x07BC
+
+#define REG_IQ_DUMP 0x07C0
+
+#define REG_WMAC_FTM_CTL 0x07CC
+
+#define REG_WMAC_IQ_MDPK_FUNC 0x07CE
+
+#define REG_WMAC_OPTION_FUNCTION 0x07D0
+
+#define REG_RX_FILTER_FUNCTION 0x07DA
+
+#define REG_NDP_SIG 0x07E0
+#define REG_TXCMD_INFO_FOR_RSP_PKT 0x07E4
+
+#define REG_RTS_ADDRESS_0 0x07F0
+
+#define REG_RTS_ADDRESS_1 0x07F8
+
+#define REG__RPFM_MAP1 0x07FE
+
+#define REG_SYS_CFG3 0x1000
+#define REG_SYS_CFG4 0x1034
+
+#define REG_SYS_CFG5 0x1070
+
+#define REG_CPU_DMEM_CON 0x1080
+
+#define REG_BOOT_REASON 0x1088
+#define REG_NFCPAD_CTRL 0x10A8
+
+#define REG_HIMR2 0x10B0
+#define REG_HISR2 0x10B4
+#define REG_HIMR3 0x10B8
+#define REG_HISR3 0x10BC
+#define REG_SW_MDIO 0x10C0
+#define REG_SW_FLUSH 0x10C4
+
+#define REG_H2C_PKT_READADDR 0x10D0
+#define REG_H2C_PKT_WRITEADDR 0x10D4
+
+#define REG_MEM_PWR_CRTL 0x10D8
+
+#define REG_FW_DBG0 0x10E0
+#define REG_FW_DBG1 0x10E4
+#define REG_FW_DBG2 0x10E8
+#define REG_FW_DBG3 0x10EC
+#define REG_FW_DBG4 0x10F0
+#define REG_FW_DBG5 0x10F4
+#define REG_FW_DBG6 0x10F8
+#define REG_FW_DBG7 0x10FC
+#define REG_CR_EXT 0x1100
+#define REG_FWFF 0x1114
+
+#define REG_RXFF_PTR_V1 0x1118
+#define REG_RXFF_WTR_V1 0x111C
+
+#define REG_FE2IMR 0x1120
+#define REG_FE2ISR 0x1124
+#define REG_FE3IMR 0x1128
+#define REG_FE3ISR 0x112C
+#define REG_FE4IMR 0x1130
+#define REG_FE4ISR 0x1134
+#define REG_FT1IMR 0x1138
+#define REG_FT1ISR 0x113C
+#define REG_SPWR0 0x1140
+#define REG_SPWR1 0x1144
+#define REG_SPWR2 0x1148
+#define REG_SPWR3 0x114C
+#define REG_POWSEQ 0x1150
+
+#define REG_TC7_CTRL_V1 0x1158
+#define REG_TC8_CTRL_V1 0x115C
+
+#define REG_FT2IMR 0x11E0
+#define REG_FT2ISR 0x11E4
+
+#define REG_MSG2 0x11F0
+#define REG_MSG3 0x11F4
+#define REG_MSG4 0x11F8
+#define REG_MSG5 0x11FC
+#define REG_DDMA_CH0SA 0x1200
+#define REG_DDMA_CH0DA 0x1204
+#define REG_DDMA_CH0CTRL 0x1208
+#define REG_DDMA_CH1SA 0x1210
+#define REG_DDMA_CH1DA 0x1214
+#define REG_DDMA_CH1CTRL 0x1218
+#define REG_DDMA_CH2SA 0x1220
+#define REG_DDMA_CH2DA 0x1224
+#define REG_DDMA_CH2CTRL 0x1228
+#define REG_DDMA_CH3SA 0x1230
+#define REG_DDMA_CH3DA 0x1234
+#define REG_DDMA_CH3CTRL 0x1238
+#define REG_DDMA_CH4SA 0x1240
+#define REG_DDMA_CH4DA 0x1244
+#define REG_DDMA_CH4CTRL 0x1248
+#define REG_DDMA_CH5SA 0x1250
+#define REG_DDMA_CH5DA 0x1254
+
+#define REG_REG_DDMA_CH5CTRL 0x1258
+
+#define REG_DDMA_INT_MSK 0x12E0
+#define REG_DDMA_CHSTATUS 0x12E8
+#define REG_DDMA_CHKSUM 0x12F0
+#define REG_DDMA_MONITOR 0x12FC
+
+#define REG_STC_INT_CS 0x1300
+#define REG_ST_INT_CFG 0x1304
+#define REG_CMU_DLY_CTRL 0x1310
+#define REG_CMU_DLY_CFG 0x1314
+#define REG_H2CQ_TXBD_DESA 0x1320
+#define REG_H2CQ_TXBD_NUM 0x1328
+#define REG_H2CQ_TXBD_IDX 0x132C
+#define REG_H2CQ_CSR 0x1330
+
+#define REG_CHANGE_PCIE_SPEED 0x1350
+
+#define REG_OLD_DEHANG 0x13F4
+
+#define REG_Q0_Q1_INFO 0x1400
+#define REG_Q2_Q3_INFO 0x1404
+#define REG_Q4_Q5_INFO 0x1408
+#define REG_Q6_Q7_INFO 0x140C
+#define REG_MGQ_HIQ_INFO 0x1410
+#define REG_CMDQ_BCNQ_INFO 0x1414
+#define REG_USEREG_SETTING 0x1420
+#define REG_AESIV_SETTING 0x1424
+#define REG_BF0_TIME_SETTING 0x1428
+#define REG_BF1_TIME_SETTING 0x142C
+#define REG_BF_TIMEOUT_EN 0x1430
+#define REG_MACID_RELEASE0 0x1434
+#define REG_MACID_RELEASE1 0x1438
+#define REG_MACID_RELEASE2 0x143C
+#define REG_MACID_RELEASE3 0x1440
+#define REG_MACID_RELEASE_SETTING 0x1444
+#define REG_FAST_EDCA_VOVI_SETTING 0x1448
+#define REG_FAST_EDCA_BEBK_SETTING 0x144C
+#define REG_MACID_DROP0 0x1450
+#define REG_MACID_DROP1 0x1454
+#define REG_MACID_DROP2 0x1458
+#define REG_MACID_DROP3 0x145C
+
+#define REG_R_MACID_RELEASE_SUCCESS_0 0x1460
+#define REG_R_MACID_RELEASE_SUCCESS_1 0x1464
+#define REG_R_MACID_RELEASE_SUCCESS_2 0x1468
+#define REG_R_MACID_RELEASE_SUCCESS_3 0x146C
+#define REG_MGG_FIFO_CRTL 0x1470
+#define REG_MGG_FIFO_INT 0x1474
+#define REG_MGG_FIFO_LIFETIME 0x1478
+#define REG_R_MACID_RELEASE_SUCCESS_CLEAR_OFFSET 0x147C
+
+#define REG_MACID_SHCUT_OFFSET 0x1480
+
+#define REG_MU_TX_CTL 0x14C0
+#define REG_MU_STA_GID_VLD 0x14C4
+#define REG_MU_STA_USER_POS_INFO 0x14C8
+#define REG_MU_TRX_DBG_CNT 0x14D0
+
+#define REG_CPUMGQ_TX_TIMER 0x1500
+#define REG_PS_TIMER_A 0x1504
+#define REG_PS_TIMER_B 0x1508
+#define REG_PS_TIMER_C 0x150C
+#define REG_PS_TIMER_ABC_CPUMGQ_TIMER_CRTL 0x1510
+#define REG_CPUMGQ_TX_TIMER_EARLY 0x1514
+#define REG_PS_TIMER_A_EARLY 0x1515
+#define REG_PS_TIMER_B_EARLY 0x1516
+#define REG_PS_TIMER_C_EARLY 0x1517
+
+#define REG_BCN_PSR_RPT2 0x1600
+#define REG_BCN_PSR_RPT3 0x1604
+#define REG_BCN_PSR_RPT4 0x1608
+#define REG_A1_ADDR_MASK 0x160C
+#define REG_MACID2 0x1620
+#define REG_BSSID2 0x1628
+#define REG_MACID3 0x1630
+#define REG_BSSID3 0x1638
+#define REG_MACID4 0x1640
+#define REG_BSSID4 0x1648
+
+#define REG_NOA_REPORT 0x1650
+#define REG_PWRBIT_SETTING 0x1660
+#define REG_WMAC_MU_BF_OPTION 0x167C
+
+#define REG_WMAC_MU_ARB 0x167E
+#define REG_WMAC_MU_OPTION 0x167F
+#define REG_WMAC_MU_BF_CTL 0x1680
+
+#define REG_WMAC_MU_BFRPT_PARA 0x1682
+
+#define REG_WMAC_ASSOCIATED_MU_BFMEE2 0x1684
+#define REG_WMAC_ASSOCIATED_MU_BFMEE3 0x1686
+#define REG_WMAC_ASSOCIATED_MU_BFMEE4 0x1688
+#define REG_WMAC_ASSOCIATED_MU_BFMEE5 0x168A
+#define REG_WMAC_ASSOCIATED_MU_BFMEE6 0x168C
+#define REG_WMAC_ASSOCIATED_MU_BFMEE7 0x168E
+
+#define REG_TRANSMIT_ADDRSS_0 0x16A0
+#define REG_TRANSMIT_ADDRSS_1 0x16A8
+#define REG_TRANSMIT_ADDRSS_2 0x16B0
+#define REG_TRANSMIT_ADDRSS_3 0x16B8
+#define REG_TRANSMIT_ADDRSS_4 0x16C0
+
+#define REG_WL2LTECOEX_INDIRECT_ACCESS_CTRL_V1 0x1700
+#define REG_WL2LTECOEX_INDIRECT_ACCESS_WRITE_DATA_V1 0x1704
+#define REG_WL2LTECOEX_INDIRECT_ACCESS_READ_DATA_V1 0x1708
+
+/* ----------------------------------------------------- */
+/* */
+/* 0xFB00h ~ 0xFCFFh TX/RX packet buffer affress */
+/* */
+/* ----------------------------------------------------- */
+#define REG_RXPKTBUF_STARTADDR 0xFB00
+#define REG_TXPKTBUF_STARTADDR 0xFC00
+
+/* ----------------------------------------------------- */
+/* */
+/* 0xFD00h ~ 0xFDFFh 8051 CPU Local REG */
+/* */
+/* ----------------------------------------------------- */
+#define REG_SYS_CTRL 0xFD00
+#define REG_PONSTS_RPT1 0xFD01
+#define REG_PONSTS_RPT2 0xFD02
+#define REG_PONSTS_RPT3 0xFD03
+#define REG_PONSTS_RPT4 0xFD04 /* 0x84 */
+#define REG_PONSTS_RPT5 0xFD05 /* 0x85 */
+#define REG_8051ERRFLAG 0xFD08
+#define REG_8051ERRFLAG_MASK 0xFD09
+#define REG_TXADDRH 0xFD10 /* Tx Packet High address */
+#define REG_RXADDRH 0xFD11 /* Rx Packet High address */
+#define REG_TXADDRH_EXT 0xFD12 /* 0xFD12[0] : for 8051 access txpktbuf
+ * high64k as external register
+ */
+
+#define REG_U3_STATE 0xFD48 /* (Read only)
+ * [7:4] : usb3 changed last state.
+ * [3:0] : usb3 state
+ */
+
+/* for MAILBOX */
+#define REG_OUTDATA0 0xFD50
+#define REG_OUTDATA1 0xFD54
+#define REG_OUTRDY 0xFD58 /* bit[0] : OutReady,
+ * bit[1] : OutEmptyIntEn
+ */
+
+#define REG_INDATA0 0xFD60
+#define REG_INDATA1 0xFD64
+#define REG_INRDY 0xFD68 /* bit[0] : InReady,
+ * bit[1] : InRdyIntEn
+ */
+
+/* MCU ERROR debug REG */
+#define REG_MCUERR_PCLSB 0xFD90 /* PC[7:0] */
+#define REG_MCUERR_PCMSB 0xFD91 /* PC[15:8] */
+#define REG_MCUERR_ACC 0xFD92
+#define REG_MCUERR_B 0xFD93
+#define REG_MCUERR_DPTRLSB 0xFD94 /* DPTR[7:0] */
+#define REG_MCUERR_DPTRMSB 0xFD95 /* DPTR[15:8] */
+#define REG_MCUERR_SP 0xFD96 /* SP[7:0] */
+#define REG_MCUERR_IE 0xFD97 /* IE[7:0] */
+#define REG_MCUERR_EIE 0xFD98 /* EIE[7:0] */
+#define REG_VERA_SIM 0xFD9F
+/* 0xFD99~0xFD9F are reserved.. */
+
+/* ----------------------------------------------------- */
+/* */
+/* 0xFE00h ~ 0xFEFFh USB Configuration */
+/* */
+/* ----------------------------------------------------- */
+
+/* RTS5101 USB Register Definition */
+#define REG_USB_SETUP_DEC_INT 0xFE00
+#define REG_USB_DMACTL 0xFE01
+#define REG_USB_IRQSTAT0 0xFE02
+#define REG_USB_IRQSTAT1 0xFE03
+#define REG_USB_IRQEN0 0xFE04
+#define REG_USB_IRQEN1 0xFE05
+#define REG_USB_AUTOPTRL 0xFE06
+#define REG_USB_AUTOPTRH 0xFE07
+#define REG_USB_AUTODAT 0xFE08
+
+#define REG_USB_SCRATCH0 0xFE09
+#define REG_USB_SCRATCH1 0xFE0A
+#define REG_USB_SEEPROM 0xFE0B
+#define REG_USB_GPIO0 0xFE0C
+#define REG_USB_GPIO0DIR 0xFE0D
+#define REG_USB_CLKSEL 0xFE0E
+#define REG_USB_BOOTCTL 0xFE0F
+
+#define REG_USB_USBCTL 0xFE10
+#define REG_USB_USBSTAT 0xFE11
+#define REG_USB_DEVADDR 0xFE12
+#define REG_USB_USBTEST 0xFE13
+#define REG_USB_FNUM0 0xFE14
+#define REG_USB_FNUM1 0xFE15
+
+#define REG_USB_EP_IDX 0xFE20
+#define REG_USB_EP_CFG 0xFE21
+#define REG_USB_EP_CTL 0xFE22
+#define REG_USB_EP_STAT 0xFE23
+#define REG_USB_EP_IRQ 0xFE24
+#define REG_USB_EP_IRQEN 0xFE25
+#define REG_USB_EP_MAXPKT0 0xFE26
+#define REG_USB_EP_MAXPKT1 0xFE27
+#define REG_USB_EP_DAT 0xFE28
+#define REG_USB_EP_BC0 0xFE29
+#define REG_USB_EP_BC1 0xFE2A
+#define REG_USB_EP_TC0 0xFE2B
+#define REG_USB_EP_TC1 0xFE2C
+#define REG_USB_EP_TC2 0xFE2D
+#define REG_USB_EP_CTL2 0xFE2E
+
+#define REG_USB_INFO 0xFE17
+#define REG_USB_SPECIAL_OPTION 0xFE55
+#define REG_USB_DMA_AGG_TO 0xFE5B
+#define REG_USB_AGG_TO 0xFE5C
+#define REG_USB_AGG_TH 0xFE5D
+
+#define REG_USB_VID 0xFE60
+#define REG_USB_PID 0xFE62
+#define REG_USB_OPT 0xFE64
+#define REG_USB_CONFIG 0xFE65 /* RX EP setting.
+ * 0xFE65 Bit[3:0] : RXQ,
+ * Bit[7:4] : INTQ
+ */
+ /* TX EP setting.
+ * 0xFE66 Bit[3:0] : TXQ0,
+ * Bit[7:4] : TXQ1,
+ * 0xFE67 Bit[3:0] : TXQ2
+ */
+#define REG_USB_PHY_PARA1 0xFE68 /* Bit[7:4]: XCVR_SEN (USB PHY 0xE2[7:4]),
+ * Bit[3:0]: XCVR_SH (USB PHY 0xE2[3:0])
+ */
+#define REG_USB_PHY_PARA2 0xFE69 /* Bit[7:5]: XCVR_BG (USB PHY 0xE3[5:3]),
+ * Bit[4:2]: XCVR_DR (USB PHY 0xE3[2:0]),
+ * Bit[1]: SE0_LVL (USB PHY 0xE5[7]),
+ * Bit[0]: FORCE_XTL_ON (USB PHY 0xE5[1])
+ */
+#define REG_USB_PHY_PARA3 0xFE6A /* Bit[7:5]: XCVR_SRC (USB PHY 0xE5[4:2]),
+ * Bit[4]: LATE_DLLEN (USB PHY 0xF0[4]),
+ * Bit[3]: HS_LP_MODE (USB PHY 0xF0[3]),
+ * Bit[2]: UTMI_POS_OUT (USB PHY 0xF1 [7]),
+ * Bit[1:0]: TX_DELAY (USB PHY 0xF1 [2:1])
+ */
+#define REG_USB_PHY_PARA4 0xFE6B /* (USB PHY 0xE7[7:0]) */
+#define REG_USB_OPT2 0xFE6C
+#define REG_USB_MAC_ADDR 0xFE70 /* 0xFE70~0xFE75 */
+#define REG_USB_MANUFACTURE_SETTING 0xFE80 /* 0xFE80~0xFE90 Max: 32 bytes*/
+#define REG_USB_PRODUCT_STRING 0xFEA0 /* 0xFEA0~0xFECF Max: 48 bytes*/
+#define REG_USB_SERIAL_NUMBER_STRING 0xFED0 /* 0xFED0~0xFEDF Max: 12 bytes*/
+
+#define REG_USB_ALTERNATE_SETTING 0xFE4F
+#define REG_USB_INT_BINTERVAL 0xFE6E
+#define REG_USB_GPS_EP_CONFIG 0xFE6D
+
+#endif /* __HALMAC_COM_REG_H__ */
diff --git a/drivers/staging/rtlwifi/halmac/halmac_reg_8822b.h b/drivers/staging/rtlwifi/halmac/halmac_reg_8822b.h
new file mode 100644
index 0000000..4bc59b1
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_reg_8822b.h
@@ -0,0 +1,728 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __INC_HALMAC_REG_8822B_H
+#define __INC_HALMAC_REG_8822B_H
+
+#define REG_SYS_ISO_CTRL_8822B 0x0000
+#define REG_SYS_FUNC_EN_8822B 0x0002
+#define REG_SYS_PW_CTRL_8822B 0x0004
+#define REG_SYS_CLK_CTRL_8822B 0x0008
+#define REG_SYS_EEPROM_CTRL_8822B 0x000A
+#define REG_EE_VPD_8822B 0x000C
+#define REG_SYS_SWR_CTRL1_8822B 0x0010
+#define REG_SYS_SWR_CTRL2_8822B 0x0014
+#define REG_SYS_SWR_CTRL3_8822B 0x0018
+#define REG_RSV_CTRL_8822B 0x001C
+#define REG_RF_CTRL_8822B 0x001F
+#define REG_AFE_LDO_CTRL_8822B 0x0020
+#define REG_AFE_CTRL1_8822B 0x0024
+#define REG_AFE_CTRL2_8822B 0x0028
+#define REG_AFE_CTRL3_8822B 0x002C
+#define REG_EFUSE_CTRL_8822B 0x0030
+#define REG_LDO_EFUSE_CTRL_8822B 0x0034
+#define REG_PWR_OPTION_CTRL_8822B 0x0038
+#define REG_CAL_TIMER_8822B 0x003C
+#define REG_ACLK_MON_8822B 0x003E
+#define REG_GPIO_MUXCFG_8822B 0x0040
+#define REG_GPIO_PIN_CTRL_8822B 0x0044
+#define REG_GPIO_INTM_8822B 0x0048
+#define REG_LED_CFG_8822B 0x004C
+#define REG_FSIMR_8822B 0x0050
+#define REG_FSISR_8822B 0x0054
+#define REG_HSIMR_8822B 0x0058
+#define REG_HSISR_8822B 0x005C
+#define REG_GPIO_EXT_CTRL_8822B 0x0060
+#define REG_PAD_CTRL1_8822B 0x0064
+#define REG_WL_BT_PWR_CTRL_8822B 0x0068
+#define REG_SDM_DEBUG_8822B 0x006C
+#define REG_SYS_SDIO_CTRL_8822B 0x0070
+#define REG_HCI_OPT_CTRL_8822B 0x0074
+#define REG_AFE_CTRL4_8822B 0x0078
+#define REG_LDO_SWR_CTRL_8822B 0x007C
+#define REG_MCUFW_CTRL_8822B 0x0080
+#define REG_MCU_TST_CFG_8822B 0x0084
+#define REG_HMEBOX_E0_E1_8822B 0x0088
+#define REG_HMEBOX_E2_E3_8822B 0x008C
+#define REG_WLLPS_CTRL_8822B 0x0090
+#define REG_AFE_CTRL5_8822B 0x0094
+#define REG_GPIO_DEBOUNCE_CTRL_8822B 0x0098
+#define REG_RPWM2_8822B 0x009C
+#define REG_SYSON_FSM_MON_8822B 0x00A0
+#define REG_AFE_CTRL6_8822B 0x00A4
+#define REG_PMC_DBG_CTRL1_8822B 0x00A8
+#define REG_AFE_CTRL7_8822B 0x00AC
+#define REG_HIMR0_8822B 0x00B0
+#define REG_HISR0_8822B 0x00B4
+#define REG_HIMR1_8822B 0x00B8
+#define REG_HISR1_8822B 0x00BC
+#define REG_DBG_PORT_SEL_8822B 0x00C0
+#define REG_PAD_CTRL2_8822B 0x00C4
+#define REG_PMC_DBG_CTRL2_8822B 0x00CC
+#define REG_BIST_CTRL_8822B 0x00D0
+#define REG_BIST_RPT_8822B 0x00D4
+#define REG_MEM_CTRL_8822B 0x00D8
+#define REG_AFE_CTRL8_8822B 0x00DC
+#define REG_USB_SIE_INTF_8822B 0x00E0
+#define REG_PCIE_MIO_INTF_8822B 0x00E4
+#define REG_PCIE_MIO_INTD_8822B 0x00E8
+#define REG_WLRF1_8822B 0x00EC
+#define REG_SYS_CFG1_8822B 0x00F0
+#define REG_SYS_STATUS1_8822B 0x00F4
+#define REG_SYS_STATUS2_8822B 0x00F8
+#define REG_SYS_CFG2_8822B 0x00FC
+#define REG_SYS_CFG3_8822B 0x1000
+#define REG_SYS_CFG4_8822B 0x1034
+#define REG_SYS_CFG5_8822B 0x1070
+#define REG_CPU_DMEM_CON_8822B 0x1080
+#define REG_BOOT_REASON_8822B 0x1088
+#define REG_NFCPAD_CTRL_8822B 0x10A8
+#define REG_HIMR2_8822B 0x10B0
+#define REG_HISR2_8822B 0x10B4
+#define REG_HIMR3_8822B 0x10B8
+#define REG_HISR3_8822B 0x10BC
+#define REG_SW_MDIO_8822B 0x10C0
+#define REG_SW_FLUSH_8822B 0x10C4
+#define REG_H2C_PKT_READADDR_8822B 0x10D0
+#define REG_H2C_PKT_WRITEADDR_8822B 0x10D4
+#define REG_MEM_PWR_CRTL_8822B 0x10D8
+#define REG_FW_DBG0_8822B 0x10E0
+#define REG_FW_DBG1_8822B 0x10E4
+#define REG_FW_DBG2_8822B 0x10E8
+#define REG_FW_DBG3_8822B 0x10EC
+#define REG_FW_DBG4_8822B 0x10F0
+#define REG_FW_DBG5_8822B 0x10F4
+#define REG_FW_DBG6_8822B 0x10F8
+#define REG_FW_DBG7_8822B 0x10FC
+#define REG_CR_8822B 0x0100
+#define REG_PKT_BUFF_ACCESS_CTRL_8822B 0x0106
+#define REG_TSF_CLK_STATE_8822B 0x0108
+#define REG_TXDMA_PQ_MAP_8822B 0x010C
+#define REG_TRXFF_BNDY_8822B 0x0114
+#define REG_PTA_I2C_MBOX_8822B 0x0118
+#define REG_RXFF_BNDY_8822B 0x011C
+#define REG_FE1IMR_8822B 0x0120
+#define REG_FE1ISR_8822B 0x0124
+#define REG_CPWM_8822B 0x012C
+#define REG_FWIMR_8822B 0x0130
+#define REG_FWISR_8822B 0x0134
+#define REG_FTIMR_8822B 0x0138
+#define REG_FTISR_8822B 0x013C
+#define REG_PKTBUF_DBG_CTRL_8822B 0x0140
+#define REG_PKTBUF_DBG_DATA_L_8822B 0x0144
+#define REG_PKTBUF_DBG_DATA_H_8822B 0x0148
+#define REG_CPWM2_8822B 0x014C
+#define REG_TC0_CTRL_8822B 0x0150
+#define REG_TC1_CTRL_8822B 0x0154
+#define REG_TC2_CTRL_8822B 0x0158
+#define REG_TC3_CTRL_8822B 0x015C
+#define REG_TC4_CTRL_8822B 0x0160
+#define REG_TCUNIT_BASE_8822B 0x0164
+#define REG_TC5_CTRL_8822B 0x0168
+#define REG_TC6_CTRL_8822B 0x016C
+#define REG_MBIST_FAIL_8822B 0x0170
+#define REG_MBIST_START_PAUSE_8822B 0x0174
+#define REG_MBIST_DONE_8822B 0x0178
+#define REG_MBIST_FAIL_NRML_8822B 0x017C
+#define REG_AES_DECRPT_DATA_8822B 0x0180
+#define REG_AES_DECRPT_CFG_8822B 0x0184
+#define REG_TMETER_8822B 0x0190
+#define REG_OSC_32K_CTRL_8822B 0x0194
+#define REG_32K_CAL_REG1_8822B 0x0198
+#define REG_C2HEVT_8822B 0x01A0
+#define REG_SW_DEFINED_PAGE1_8822B 0x01B8
+#define REG_MCUTST_I_8822B 0x01C0
+#define REG_MCUTST_II_8822B 0x01C4
+#define REG_FMETHR_8822B 0x01C8
+#define REG_HMETFR_8822B 0x01CC
+#define REG_HMEBOX0_8822B 0x01D0
+#define REG_HMEBOX1_8822B 0x01D4
+#define REG_HMEBOX2_8822B 0x01D8
+#define REG_HMEBOX3_8822B 0x01DC
+#define REG_LLT_INIT_8822B 0x01E0
+#define REG_LLT_INIT_ADDR_8822B 0x01E4
+#define REG_BB_ACCESS_CTRL_8822B 0x01E8
+#define REG_BB_ACCESS_DATA_8822B 0x01EC
+#define REG_HMEBOX_E0_8822B 0x01F0
+#define REG_HMEBOX_E1_8822B 0x01F4
+#define REG_HMEBOX_E2_8822B 0x01F8
+#define REG_HMEBOX_E3_8822B 0x01FC
+#define REG_CR_EXT_8822B 0x1100
+#define REG_FWFF_8822B 0x1114
+#define REG_RXFF_PTR_V1_8822B 0x1118
+#define REG_RXFF_WTR_V1_8822B 0x111C
+#define REG_FE2IMR_8822B 0x1120
+#define REG_FE2ISR_8822B 0x1124
+#define REG_FE3IMR_8822B 0x1128
+#define REG_FE3ISR_8822B 0x112C
+#define REG_FE4IMR_8822B 0x1130
+#define REG_FE4ISR_8822B 0x1134
+#define REG_FT1IMR_8822B 0x1138
+#define REG_FT1ISR_8822B 0x113C
+#define REG_SPWR0_8822B 0x1140
+#define REG_SPWR1_8822B 0x1144
+#define REG_SPWR2_8822B 0x1148
+#define REG_SPWR3_8822B 0x114C
+#define REG_POWSEQ_8822B 0x1150
+#define REG_TC7_CTRL_V1_8822B 0x1158
+#define REG_TC8_CTRL_V1_8822B 0x115C
+#define REG_FT2IMR_8822B 0x11E0
+#define REG_FT2ISR_8822B 0x11E4
+#define REG_MSG2_8822B 0x11F0
+#define REG_MSG3_8822B 0x11F4
+#define REG_MSG4_8822B 0x11F8
+#define REG_MSG5_8822B 0x11FC
+#define REG_FIFOPAGE_CTRL_1_8822B 0x0200
+#define REG_FIFOPAGE_CTRL_2_8822B 0x0204
+#define REG_AUTO_LLT_V1_8822B 0x0208
+#define REG_TXDMA_OFFSET_CHK_8822B 0x020C
+#define REG_TXDMA_STATUS_8822B 0x0210
+#define REG_TX_DMA_DBG_8822B 0x0214
+#define REG_TQPNT1_8822B 0x0218
+#define REG_TQPNT2_8822B 0x021C
+#define REG_TQPNT3_8822B 0x0220
+#define REG_TQPNT4_8822B 0x0224
+#define REG_RQPN_CTRL_1_8822B 0x0228
+#define REG_RQPN_CTRL_2_8822B 0x022C
+#define REG_FIFOPAGE_INFO_1_8822B 0x0230
+#define REG_FIFOPAGE_INFO_2_8822B 0x0234
+#define REG_FIFOPAGE_INFO_3_8822B 0x0238
+#define REG_FIFOPAGE_INFO_4_8822B 0x023C
+#define REG_FIFOPAGE_INFO_5_8822B 0x0240
+#define REG_H2C_HEAD_8822B 0x0244
+#define REG_H2C_TAIL_8822B 0x0248
+#define REG_H2C_READ_ADDR_8822B 0x024C
+#define REG_H2C_WR_ADDR_8822B 0x0250
+#define REG_H2C_INFO_8822B 0x0254
+#define REG_RXDMA_AGG_PG_TH_8822B 0x0280
+#define REG_RXPKT_NUM_8822B 0x0284
+#define REG_RXDMA_STATUS_8822B 0x0288
+#define REG_RXDMA_DPR_8822B 0x028C
+#define REG_RXDMA_MODE_8822B 0x0290
+#define REG_C2H_PKT_8822B 0x0294
+#define REG_FWFF_C2H_8822B 0x0298
+#define REG_FWFF_CTRL_8822B 0x029C
+#define REG_FWFF_PKT_INFO_8822B 0x02A0
+#define REG_DDMA_CH0SA_8822B 0x1200
+#define REG_DDMA_CH0DA_8822B 0x1204
+#define REG_DDMA_CH0CTRL_8822B 0x1208
+#define REG_DDMA_CH1SA_8822B 0x1210
+#define REG_DDMA_CH1DA_8822B 0x1214
+#define REG_DDMA_CH1CTRL_8822B 0x1218
+#define REG_DDMA_CH2SA_8822B 0x1220
+#define REG_DDMA_CH2DA_8822B 0x1224
+#define REG_DDMA_CH2CTRL_8822B 0x1228
+#define REG_DDMA_CH3SA_8822B 0x1230
+#define REG_DDMA_CH3DA_8822B 0x1234
+#define REG_DDMA_CH3CTRL_8822B 0x1238
+#define REG_DDMA_CH4SA_8822B 0x1240
+#define REG_DDMA_CH4DA_8822B 0x1244
+#define REG_DDMA_CH4CTRL_8822B 0x1248
+#define REG_DDMA_CH5SA_8822B 0x1250
+#define REG_DDMA_CH5DA_8822B 0x1254
+#define REG_REG_DDMA_CH5CTRL_8822B 0x1258
+#define REG_DDMA_INT_MSK_8822B 0x12E0
+#define REG_DDMA_CHSTATUS_8822B 0x12E8
+#define REG_DDMA_CHKSUM_8822B 0x12F0
+#define REG_DDMA_MONITOR_8822B 0x12FC
+#define REG_PCIE_CTRL_8822B 0x0300
+#define REG_INT_MIG_8822B 0x0304
+#define REG_BCNQ_TXBD_DESA_8822B 0x0308
+#define REG_MGQ_TXBD_DESA_8822B 0x0310
+#define REG_VOQ_TXBD_DESA_8822B 0x0318
+#define REG_VIQ_TXBD_DESA_8822B 0x0320
+#define REG_BEQ_TXBD_DESA_8822B 0x0328
+#define REG_BKQ_TXBD_DESA_8822B 0x0330
+#define REG_RXQ_RXBD_DESA_8822B 0x0338
+#define REG_HI0Q_TXBD_DESA_8822B 0x0340
+#define REG_HI1Q_TXBD_DESA_8822B 0x0348
+#define REG_HI2Q_TXBD_DESA_8822B 0x0350
+#define REG_HI3Q_TXBD_DESA_8822B 0x0358
+#define REG_HI4Q_TXBD_DESA_8822B 0x0360
+#define REG_HI5Q_TXBD_DESA_8822B 0x0368
+#define REG_HI6Q_TXBD_DESA_8822B 0x0370
+#define REG_HI7Q_TXBD_DESA_8822B 0x0378
+#define REG_MGQ_TXBD_NUM_8822B 0x0380
+#define REG_RX_RXBD_NUM_8822B 0x0382
+#define REG_VOQ_TXBD_NUM_8822B 0x0384
+#define REG_VIQ_TXBD_NUM_8822B 0x0386
+#define REG_BEQ_TXBD_NUM_8822B 0x0388
+#define REG_BKQ_TXBD_NUM_8822B 0x038A
+#define REG_HI0Q_TXBD_NUM_8822B 0x038C
+#define REG_HI1Q_TXBD_NUM_8822B 0x038E
+#define REG_HI2Q_TXBD_NUM_8822B 0x0390
+#define REG_HI3Q_TXBD_NUM_8822B 0x0392
+#define REG_HI4Q_TXBD_NUM_8822B 0x0394
+#define REG_HI5Q_TXBD_NUM_8822B 0x0396
+#define REG_HI6Q_TXBD_NUM_8822B 0x0398
+#define REG_HI7Q_TXBD_NUM_8822B 0x039A
+#define REG_TSFTIMER_HCI_8822B 0x039C
+#define REG_BD_RWPTR_CLR_8822B 0x039C
+#define REG_VOQ_TXBD_IDX_8822B 0x03A0
+#define REG_VIQ_TXBD_IDX_8822B 0x03A4
+#define REG_BEQ_TXBD_IDX_8822B 0x03A8
+#define REG_BKQ_TXBD_IDX_8822B 0x03AC
+#define REG_MGQ_TXBD_IDX_8822B 0x03B0
+#define REG_RXQ_RXBD_IDX_8822B 0x03B4
+#define REG_HI0Q_TXBD_IDX_8822B 0x03B8
+#define REG_HI1Q_TXBD_IDX_8822B 0x03BC
+#define REG_HI2Q_TXBD_IDX_8822B 0x03C0
+#define REG_HI3Q_TXBD_IDX_8822B 0x03C4
+#define REG_HI4Q_TXBD_IDX_8822B 0x03C8
+#define REG_HI5Q_TXBD_IDX_8822B 0x03CC
+#define REG_HI6Q_TXBD_IDX_8822B 0x03D0
+#define REG_HI7Q_TXBD_IDX_8822B 0x03D4
+#define REG_DBG_SEL_V1_8822B 0x03D8
+#define REG_PCIE_HRPWM1_V1_8822B 0x03D9
+#define REG_PCIE_HCPWM1_V1_8822B 0x03DA
+#define REG_PCIE_CTRL2_8822B 0x03DB
+#define REG_PCIE_HRPWM2_V1_8822B 0x03DC
+#define REG_PCIE_HCPWM2_V1_8822B 0x03DE
+#define REG_PCIE_H2C_MSG_V1_8822B 0x03E0
+#define REG_PCIE_C2H_MSG_V1_8822B 0x03E4
+#define REG_DBI_WDATA_V1_8822B 0x03E8
+#define REG_DBI_RDATA_V1_8822B 0x03EC
+#define REG_DBI_FLAG_V1_8822B 0x03F0
+#define REG_MDIO_V1_8822B 0x03F4
+#define REG_PCIE_MIX_CFG_8822B 0x03F8
+#define REG_HCI_MIX_CFG_8822B 0x03FC
+#define REG_STC_INT_CS_8822B 0x1300
+#define REG_ST_INT_CFG_8822B 0x1304
+#define REG_CMU_DLY_CTRL_8822B 0x1310
+#define REG_CMU_DLY_CFG_8822B 0x1314
+#define REG_H2CQ_TXBD_DESA_8822B 0x1320
+#define REG_H2CQ_TXBD_NUM_8822B 0x1328
+#define REG_H2CQ_TXBD_IDX_8822B 0x132C
+#define REG_H2CQ_CSR_8822B 0x1330
+#define REG_CHANGE_PCIE_SPEED_8822B 0x1350
+#define REG_OLD_DEHANG_8822B 0x13F4
+#define REG_Q0_INFO_8822B 0x0400
+#define REG_Q1_INFO_8822B 0x0404
+#define REG_Q2_INFO_8822B 0x0408
+#define REG_Q3_INFO_8822B 0x040C
+#define REG_MGQ_INFO_8822B 0x0410
+#define REG_HIQ_INFO_8822B 0x0414
+#define REG_BCNQ_INFO_8822B 0x0418
+#define REG_TXPKT_EMPTY_8822B 0x041A
+#define REG_CPU_MGQ_INFO_8822B 0x041C
+#define REG_FWHW_TXQ_CTRL_8822B 0x0420
+#define REG_DATAFB_SEL_8822B 0x0423
+#define REG_BCNQ_BDNY_V1_8822B 0x0424
+#define REG_LIFETIME_EN_8822B 0x0426
+#define REG_SPEC_SIFS_8822B 0x0428
+#define REG_RETRY_LIMIT_8822B 0x042A
+#define REG_TXBF_CTRL_8822B 0x042C
+#define REG_DARFRC_8822B 0x0430
+#define REG_RARFRC_8822B 0x0438
+#define REG_RRSR_8822B 0x0440
+#define REG_ARFR0_8822B 0x0444
+#define REG_ARFR1_V1_8822B 0x044C
+#define REG_CCK_CHECK_8822B 0x0454
+#define REG_AMPDU_MAX_TIME_V1_8822B 0x0455
+#define REG_BCNQ1_BDNY_V1_8822B 0x0456
+#define REG_AMPDU_MAX_LENGTH_8822B 0x0458
+#define REG_ACQ_STOP_8822B 0x045C
+#define REG_NDPA_RATE_8822B 0x045D
+#define REG_TX_HANG_CTRL_8822B 0x045E
+#define REG_NDPA_OPT_CTRL_8822B 0x045F
+#define REG_RD_RESP_PKT_TH_8822B 0x0463
+#define REG_CMDQ_INFO_8822B 0x0464
+#define REG_Q4_INFO_8822B 0x0468
+#define REG_Q5_INFO_8822B 0x046C
+#define REG_Q6_INFO_8822B 0x0470
+#define REG_Q7_INFO_8822B 0x0474
+#define REG_WMAC_LBK_BUF_HD_V1_8822B 0x0478
+#define REG_MGQ_BDNY_V1_8822B 0x047A
+#define REG_TXRPT_CTRL_8822B 0x047C
+#define REG_INIRTS_RATE_SEL_8822B 0x0480
+#define REG_BASIC_CFEND_RATE_8822B 0x0481
+#define REG_STBC_CFEND_RATE_8822B 0x0482
+#define REG_DATA_SC_8822B 0x0483
+#define REG_MACID_SLEEP3_8822B 0x0484
+#define REG_MACID_SLEEP1_8822B 0x0488
+#define REG_ARFR2_V1_8822B 0x048C
+#define REG_ARFR3_V1_8822B 0x0494
+#define REG_ARFR4_8822B 0x049C
+#define REG_ARFR5_8822B 0x04A4
+#define REG_TXRPT_START_OFFSET_8822B 0x04AC
+#define REG_POWER_STAGE1_8822B 0x04B4
+#define REG_POWER_STAGE2_8822B 0x04B8
+#define REG_SW_AMPDU_BURST_MODE_CTRL_8822B 0x04BC
+#define REG_PKT_LIFE_TIME_8822B 0x04C0
+#define REG_STBC_SETTING_8822B 0x04C4
+#define REG_STBC_SETTING2_8822B 0x04C5
+#define REG_QUEUE_CTRL_8822B 0x04C6
+#define REG_SINGLE_AMPDU_CTRL_8822B 0x04C7
+#define REG_PROT_MODE_CTRL_8822B 0x04C8
+#define REG_BAR_MODE_CTRL_8822B 0x04CC
+#define REG_RA_TRY_RATE_AGG_LMT_8822B 0x04CF
+#define REG_MACID_SLEEP2_8822B 0x04D0
+#define REG_MACID_SLEEP_8822B 0x04D4
+#define REG_HW_SEQ0_8822B 0x04D8
+#define REG_HW_SEQ1_8822B 0x04DA
+#define REG_HW_SEQ2_8822B 0x04DC
+#define REG_HW_SEQ3_8822B 0x04DE
+#define REG_NULL_PKT_STATUS_V1_8822B 0x04E0
+#define REG_PTCL_ERR_STATUS_8822B 0x04E2
+#define REG_NULL_PKT_STATUS_EXTEND_8822B 0x04E3
+#define REG_VIDEO_ENHANCEMENT_FUN_8822B 0x04E4
+#define REG_BT_POLLUTE_PKT_CNT_8822B 0x04E8
+#define REG_PTCL_DBG_8822B 0x04EC
+#define REG_CPUMGQ_TIMER_CTRL2_8822B 0x04F4
+#define REG_DUMMY_PAGE4_V1_8822B 0x04FC
+#define REG_MOREDATA_8822B 0x04FE
+#define REG_Q0_Q1_INFO_8822B 0x1400
+#define REG_Q2_Q3_INFO_8822B 0x1404
+#define REG_Q4_Q5_INFO_8822B 0x1408
+#define REG_Q6_Q7_INFO_8822B 0x140C
+#define REG_MGQ_HIQ_INFO_8822B 0x1410
+#define REG_CMDQ_BCNQ_INFO_8822B 0x1414
+#define REG_USEREG_SETTING_8822B 0x1420
+#define REG_AESIV_SETTING_8822B 0x1424
+#define REG_BF0_TIME_SETTING_8822B 0x1428
+#define REG_BF1_TIME_SETTING_8822B 0x142C
+#define REG_BF_TIMEOUT_EN_8822B 0x1430
+#define REG_MACID_RELEASE0_8822B 0x1434
+#define REG_MACID_RELEASE1_8822B 0x1438
+#define REG_MACID_RELEASE2_8822B 0x143C
+#define REG_MACID_RELEASE3_8822B 0x1440
+#define REG_MACID_RELEASE_SETTING_8822B 0x1444
+#define REG_FAST_EDCA_VOVI_SETTING_8822B 0x1448
+#define REG_FAST_EDCA_BEBK_SETTING_8822B 0x144C
+#define REG_MACID_DROP0_8822B 0x1450
+#define REG_MACID_DROP1_8822B 0x1454
+#define REG_MACID_DROP2_8822B 0x1458
+#define REG_MACID_DROP3_8822B 0x145C
+#define REG_R_MACID_RELEASE_SUCCESS_0_8822B 0x1460
+#define REG_R_MACID_RELEASE_SUCCESS_1_8822B 0x1464
+#define REG_R_MACID_RELEASE_SUCCESS_2_8822B 0x1468
+#define REG_R_MACID_RELEASE_SUCCESS_3_8822B 0x146C
+#define REG_MGG_FIFO_CRTL_8822B 0x1470
+#define REG_MGG_FIFO_INT_8822B 0x1474
+#define REG_MGG_FIFO_LIFETIME_8822B 0x1478
+#define REG_R_MACID_RELEASE_SUCCESS_CLEAR_OFFSET_8822B 0x147C
+#define REG_MACID_SHCUT_OFFSET_8822B 0x1480
+#define REG_MU_TX_CTL_8822B 0x14C0
+#define REG_MU_STA_GID_VLD_8822B 0x14C4
+#define REG_MU_STA_USER_POS_INFO_8822B 0x14C8
+#define REG_MU_TRX_DBG_CNT_8822B 0x14D0
+#define REG_EDCA_VO_PARAM_8822B 0x0500
+#define REG_EDCA_VI_PARAM_8822B 0x0504
+#define REG_EDCA_BE_PARAM_8822B 0x0508
+#define REG_EDCA_BK_PARAM_8822B 0x050C
+#define REG_BCNTCFG_8822B 0x0510
+#define REG_PIFS_8822B 0x0512
+#define REG_RDG_PIFS_8822B 0x0513
+#define REG_SIFS_8822B 0x0514
+#define REG_TSFTR_SYN_OFFSET_8822B 0x0518
+#define REG_AGGR_BREAK_TIME_8822B 0x051A
+#define REG_SLOT_8822B 0x051B
+#define REG_TX_PTCL_CTRL_8822B 0x0520
+#define REG_TXPAUSE_8822B 0x0522
+#define REG_DIS_TXREQ_CLR_8822B 0x0523
+#define REG_RD_CTRL_8822B 0x0524
+#define REG_MBSSID_CTRL_8822B 0x0526
+#define REG_P2PPS_CTRL_8822B 0x0527
+#define REG_PKT_LIFETIME_CTRL_8822B 0x0528
+#define REG_P2PPS_SPEC_STATE_8822B 0x052B
+#define REG_BAR_TX_CTRL_8822B 0x0530
+#define REG_QUEUE_INCOL_THR_8822B 0x0538
+#define REG_QUEUE_INCOL_EN_8822B 0x053C
+#define REG_TBTT_PROHIBIT_8822B 0x0540
+#define REG_P2PPS_STATE_8822B 0x0543
+#define REG_RD_NAV_NXT_8822B 0x0544
+#define REG_NAV_PROT_LEN_8822B 0x0546
+#define REG_BCN_CTRL_8822B 0x0550
+#define REG_BCN_CTRL_CLINT0_8822B 0x0551
+#define REG_MBID_NUM_8822B 0x0552
+#define REG_DUAL_TSF_RST_8822B 0x0553
+#define REG_MBSSID_BCN_SPACE_8822B 0x0554
+#define REG_DRVERLYINT_8822B 0x0558
+#define REG_BCNDMATIM_8822B 0x0559
+#define REG_ATIMWND_8822B 0x055A
+#define REG_USTIME_TSF_8822B 0x055C
+#define REG_BCN_MAX_ERR_8822B 0x055D
+#define REG_RXTSF_OFFSET_CCK_8822B 0x055E
+#define REG_RXTSF_OFFSET_OFDM_8822B 0x055F
+#define REG_TSFTR_8822B 0x0560
+#define REG_FREERUN_CNT_8822B 0x0568
+#define REG_ATIMWND1_V1_8822B 0x0570
+#define REG_TBTT_PROHIBIT_INFRA_8822B 0x0571
+#define REG_CTWND_8822B 0x0572
+#define REG_BCNIVLCUNT_8822B 0x0573
+#define REG_BCNDROPCTRL_8822B 0x0574
+#define REG_HGQ_TIMEOUT_PERIOD_8822B 0x0575
+#define REG_TXCMD_TIMEOUT_PERIOD_8822B 0x0576
+#define REG_MISC_CTRL_8822B 0x0577
+#define REG_BCN_CTRL_CLINT1_8822B 0x0578
+#define REG_BCN_CTRL_CLINT2_8822B 0x0579
+#define REG_BCN_CTRL_CLINT3_8822B 0x057A
+#define REG_EXTEND_CTRL_8822B 0x057B
+#define REG_P2PPS1_SPEC_STATE_8822B 0x057C
+#define REG_P2PPS1_STATE_8822B 0x057D
+#define REG_P2PPS2_SPEC_STATE_8822B 0x057E
+#define REG_P2PPS2_STATE_8822B 0x057F
+#define REG_PS_TIMER0_8822B 0x0580
+#define REG_PS_TIMER1_8822B 0x0584
+#define REG_PS_TIMER2_8822B 0x0588
+#define REG_TBTT_CTN_AREA_8822B 0x058C
+#define REG_FORCE_BCN_IFS_8822B 0x058E
+#define REG_TXOP_MIN_8822B 0x0590
+#define REG_PRE_BKF_TIME_8822B 0x0592
+#define REG_CROSS_TXOP_CTRL_8822B 0x0593
+#define REG_ATIMWND2_8822B 0x05A0
+#define REG_ATIMWND3_8822B 0x05A1
+#define REG_ATIMWND4_8822B 0x05A2
+#define REG_ATIMWND5_8822B 0x05A3
+#define REG_ATIMWND6_8822B 0x05A4
+#define REG_ATIMWND7_8822B 0x05A5
+#define REG_ATIMUGT_8822B 0x05A6
+#define REG_HIQ_NO_LMT_EN_8822B 0x05A7
+#define REG_DTIM_COUNTER_ROOT_8822B 0x05A8
+#define REG_DTIM_COUNTER_VAP1_8822B 0x05A9
+#define REG_DTIM_COUNTER_VAP2_8822B 0x05AA
+#define REG_DTIM_COUNTER_VAP3_8822B 0x05AB
+#define REG_DTIM_COUNTER_VAP4_8822B 0x05AC
+#define REG_DTIM_COUNTER_VAP5_8822B 0x05AD
+#define REG_DTIM_COUNTER_VAP6_8822B 0x05AE
+#define REG_DTIM_COUNTER_VAP7_8822B 0x05AF
+#define REG_DIS_ATIM_8822B 0x05B0
+#define REG_EARLY_128US_8822B 0x05B1
+#define REG_P2PPS1_CTRL_8822B 0x05B2
+#define REG_P2PPS2_CTRL_8822B 0x05B3
+#define REG_TIMER0_SRC_SEL_8822B 0x05B4
+#define REG_NOA_UNIT_SEL_8822B 0x05B5
+#define REG_P2POFF_DIS_TXTIME_8822B 0x05B7
+#define REG_MBSSID_BCN_SPACE2_8822B 0x05B8
+#define REG_MBSSID_BCN_SPACE3_8822B 0x05BC
+#define REG_ACMHWCTRL_8822B 0x05C0
+#define REG_ACMRSTCTRL_8822B 0x05C1
+#define REG_ACMAVG_8822B 0x05C2
+#define REG_VO_ADMTIME_8822B 0x05C4
+#define REG_VI_ADMTIME_8822B 0x05C6
+#define REG_BE_ADMTIME_8822B 0x05C8
+#define REG_EDCA_RANDOM_GEN_8822B 0x05CC
+#define REG_TXCMD_NOA_SEL_8822B 0x05CF
+#define REG_NOA_PARAM_8822B 0x05E0
+#define REG_P2P_RST_8822B 0x05F0
+#define REG_SCHEDULER_RST_8822B 0x05F1
+#define REG_SCH_TXCMD_8822B 0x05F8
+#define REG_PAGE5_DUMMY_8822B 0x05FC
+#define REG_CPUMGQ_TX_TIMER_8822B 0x1500
+#define REG_PS_TIMER_A_8822B 0x1504
+#define REG_PS_TIMER_B_8822B 0x1508
+#define REG_PS_TIMER_C_8822B 0x150C
+#define REG_PS_TIMER_ABC_CPUMGQ_TIMER_CRTL_8822B 0x1510
+#define REG_CPUMGQ_TX_TIMER_EARLY_8822B 0x1514
+#define REG_PS_TIMER_A_EARLY_8822B 0x1515
+#define REG_PS_TIMER_B_EARLY_8822B 0x1516
+#define REG_PS_TIMER_C_EARLY_8822B 0x1517
+#define REG_WMAC_CR_8822B 0x0600
+#define REG_WMAC_FWPKT_CR_8822B 0x0601
+#define REG_BWOPMODE_8822B 0x0603
+#define REG_TCR_8822B 0x0604
+#define REG_RCR_8822B 0x0608
+#define REG_RX_PKT_LIMIT_8822B 0x060C
+#define REG_RX_DLK_TIME_8822B 0x060D
+#define REG_RX_DRVINFO_SZ_8822B 0x060F
+#define REG_MACID_8822B 0x0610
+#define REG_BSSID_8822B 0x0618
+#define REG_MAR_8822B 0x0620
+#define REG_MBIDCAMCFG_1_8822B 0x0628
+#define REG_MBIDCAMCFG_2_8822B 0x062C
+#define REG_WMAC_TCR_TSFT_OFS_8822B 0x0630
+#define REG_UDF_THSD_8822B 0x0632
+#define REG_ZLD_NUM_8822B 0x0633
+#define REG_STMP_THSD_8822B 0x0634
+#define REG_WMAC_TXTIMEOUT_8822B 0x0635
+#define REG_MCU_TEST_2_V1_8822B 0x0636
+#define REG_USTIME_EDCA_8822B 0x0638
+#define REG_MAC_SPEC_SIFS_8822B 0x063A
+#define REG_RESP_SIFS_CCK_8822B 0x063C
+#define REG_RESP_SIFS_OFDM_8822B 0x063E
+#define REG_ACKTO_8822B 0x0640
+#define REG_CTS2TO_8822B 0x0641
+#define REG_EIFS_8822B 0x0642
+#define REG_NAV_CTRL_8822B 0x0650
+#define REG_BACAMCMD_8822B 0x0654
+#define REG_BACAMCONTENT_8822B 0x0658
+#define REG_LBDLY_8822B 0x0660
+#define REG_WMAC_BACAM_RPMEN_8822B 0x0661
+#define REG_TX_RX_8822B 0x0662
+#define REG_WMAC_BITMAP_CTL_8822B 0x0663
+#define REG_RXERR_RPT_8822B 0x0664
+#define REG_WMAC_TRXPTCL_CTL_8822B 0x0668
+#define REG_CAMCMD_8822B 0x0670
+#define REG_CAMWRITE_8822B 0x0674
+#define REG_CAMREAD_8822B 0x0678
+#define REG_CAMDBG_8822B 0x067C
+#define REG_SECCFG_8822B 0x0680
+#define REG_RXFILTER_CATEGORY_1_8822B 0x0682
+#define REG_RXFILTER_ACTION_1_8822B 0x0683
+#define REG_RXFILTER_CATEGORY_2_8822B 0x0684
+#define REG_RXFILTER_ACTION_2_8822B 0x0685
+#define REG_RXFILTER_CATEGORY_3_8822B 0x0686
+#define REG_RXFILTER_ACTION_3_8822B 0x0687
+#define REG_RXFLTMAP3_8822B 0x0688
+#define REG_RXFLTMAP4_8822B 0x068A
+#define REG_RXFLTMAP5_8822B 0x068C
+#define REG_RXFLTMAP6_8822B 0x068E
+#define REG_WOW_CTRL_8822B 0x0690
+#define REG_NAN_RX_TSF_FILTER_8822B 0x0691
+#define REG_PS_RX_INFO_8822B 0x0692
+#define REG_WMMPS_UAPSD_TID_8822B 0x0693
+#define REG_LPNAV_CTRL_8822B 0x0694
+#define REG_WKFMCAM_CMD_8822B 0x0698
+#define REG_WKFMCAM_RWD_8822B 0x069C
+#define REG_RXFLTMAP0_8822B 0x06A0
+#define REG_RXFLTMAP1_8822B 0x06A2
+#define REG_RXFLTMAP_8822B 0x06A4
+#define REG_BCN_PSR_RPT_8822B 0x06A8
+#define REG_FLC_RPC_8822B 0x06AC
+#define REG_FLC_RPCT_8822B 0x06AD
+#define REG_FLC_PTS_8822B 0x06AE
+#define REG_FLC_TRPC_8822B 0x06AF
+#define REG_RXPKTMON_CTRL_8822B 0x06B0
+#define REG_STATE_MON_8822B 0x06B4
+#define REG_ERROR_MON_8822B 0x06B8
+#define REG_SEARCH_MACID_8822B 0x06BC
+#define REG_BT_COEX_TABLE_8822B 0x06C0
+#define REG_RXCMD_0_8822B 0x06D0
+#define REG_RXCMD_1_8822B 0x06D4
+#define REG_WMAC_RESP_TXINFO_8822B 0x06D8
+#define REG_BBPSF_CTRL_8822B 0x06DC
+#define REG_P2P_RX_BCN_NOA_8822B 0x06E0
+#define REG_ASSOCIATED_BFMER0_INFO_8822B 0x06E4
+#define REG_ASSOCIATED_BFMER1_INFO_8822B 0x06EC
+#define REG_TX_CSI_RPT_PARAM_BW20_8822B 0x06F4
+#define REG_TX_CSI_RPT_PARAM_BW40_8822B 0x06F8
+#define REG_TX_CSI_RPT_PARAM_BW80_8822B 0x06FC
+#define REG_BCN_PSR_RPT2_8822B 0x1600
+#define REG_BCN_PSR_RPT3_8822B 0x1604
+#define REG_BCN_PSR_RPT4_8822B 0x1608
+#define REG_A1_ADDR_MASK_8822B 0x160C
+#define REG_MACID2_8822B 0x1620
+#define REG_BSSID2_8822B 0x1628
+#define REG_MACID3_8822B 0x1630
+#define REG_BSSID3_8822B 0x1638
+#define REG_MACID4_8822B 0x1640
+#define REG_BSSID4_8822B 0x1648
+#define REG_NOA_REPORT_8822B 0x1650
+#define REG_PWRBIT_SETTING_8822B 0x1660
+#define REG_WMAC_MU_BF_OPTION_8822B 0x167C
+#define REG_WMAC_MU_ARB_8822B 0x167E
+#define REG_WMAC_MU_OPTION_8822B 0x167F
+#define REG_WMAC_MU_BF_CTL_8822B 0x1680
+#define REG_WMAC_MU_BFRPT_PARA_8822B 0x1682
+#define REG_WMAC_ASSOCIATED_MU_BFMEE2_8822B 0x1684
+#define REG_WMAC_ASSOCIATED_MU_BFMEE3_8822B 0x1686
+#define REG_WMAC_ASSOCIATED_MU_BFMEE4_8822B 0x1688
+#define REG_WMAC_ASSOCIATED_MU_BFMEE5_8822B 0x168A
+#define REG_WMAC_ASSOCIATED_MU_BFMEE6_8822B 0x168C
+#define REG_WMAC_ASSOCIATED_MU_BFMEE7_8822B 0x168E
+#define REG_TRANSMIT_ADDRSS_0_8822B 0x16A0
+#define REG_TRANSMIT_ADDRSS_1_8822B 0x16A8
+#define REG_TRANSMIT_ADDRSS_2_8822B 0x16B0
+#define REG_TRANSMIT_ADDRSS_3_8822B 0x16B8
+#define REG_TRANSMIT_ADDRSS_4_8822B 0x16C0
+#define REG_MACID1_8822B 0x0700
+#define REG_BSSID1_8822B 0x0708
+#define REG_BCN_PSR_RPT1_8822B 0x0710
+#define REG_ASSOCIATED_BFMEE_SEL_8822B 0x0714
+#define REG_SND_PTCL_CTRL_8822B 0x0718
+#define REG_RX_CSI_RPT_INFO_8822B 0x071C
+#define REG_NS_ARP_CTRL_8822B 0x0720
+#define REG_NS_ARP_INFO_8822B 0x0724
+#define REG_BEAMFORMING_INFO_NSARP_V1_8822B 0x0728
+#define REG_BEAMFORMING_INFO_NSARP_8822B 0x072C
+#define REG_WMAC_RTX_CTX_SUBTYPE_CFG_8822B 0x0750
+#define REG_WMAC_SWAES_CFG_8822B 0x0760
+#define REG_BT_COEX_V2_8822B 0x0762
+#define REG_BT_COEX_8822B 0x0764
+#define REG_WLAN_ACT_MASK_CTRL_8822B 0x0768
+#define REG_BT_COEX_ENHANCED_INTR_CTRL_8822B 0x076E
+#define REG_BT_ACT_STATISTICS_8822B 0x0770
+#define REG_BT_STATISTICS_CONTROL_REGISTER_8822B 0x0778
+#define REG_BT_STATUS_REPORT_REGISTER_8822B 0x077C
+#define REG_BT_INTERRUPT_CONTROL_REGISTER_8822B 0x0780
+#define REG_WLAN_REPORT_TIME_OUT_CONTROL_REGISTER_8822B 0x0784
+#define REG_BT_ISOLATION_TABLE_REGISTER_REGISTER_8822B 0x0785
+#define REG_BT_INTERRUPT_STATUS_REGISTER_8822B 0x078F
+#define REG_BT_TDMA_TIME_REGISTER_8822B 0x0790
+#define REG_BT_ACT_REGISTER_8822B 0x0794
+#define REG_OBFF_CTRL_BASIC_8822B 0x0798
+#define REG_OBFF_CTRL2_TIMER_8822B 0x079C
+#define REG_LTR_CTRL_BASIC_8822B 0x07A0
+#define REG_LTR_CTRL2_TIMER_THRESHOLD_8822B 0x07A4
+#define REG_LTR_IDLE_LATENCY_V1_8822B 0x07A8
+#define REG_LTR_ACTIVE_LATENCY_V1_8822B 0x07AC
+#define REG_ANTENNA_TRAINING_CONTROL_REGISTER_8822B 0x07B0
+#define REG_WMAC_PKTCNT_RWD_8822B 0x07B8
+#define REG_WMAC_PKTCNT_CTRL_8822B 0x07BC
+#define REG_IQ_DUMP_8822B 0x07C0
+#define REG_WMAC_FTM_CTL_8822B 0x07CC
+#define REG_WMAC_IQ_MDPK_FUNC_8822B 0x07CE
+#define REG_WMAC_OPTION_FUNCTION_8822B 0x07D0
+#define REG_RX_FILTER_FUNCTION_8822B 0x07DA
+#define REG_NDP_SIG_8822B 0x07E0
+#define REG_TXCMD_INFO_FOR_RSP_PKT_8822B 0x07E4
+#define REG_RTS_ADDRESS_0_8822B 0x07F0
+#define REG_RTS_ADDRESS_1_8822B 0x07F8
+#define REG__RPFM_MAP1_8822B 0x07FE
+#define REG_WL2LTECOEX_INDIRECT_ACCESS_CTRL_V1_8822B 0x1700
+#define REG_WL2LTECOEX_INDIRECT_ACCESS_WRITE_DATA_V1_8822B 0x1704
+#define REG_WL2LTECOEX_INDIRECT_ACCESS_READ_DATA_V1_8822B 0x1708
+#define REG_SDIO_TX_CTRL_8822B 0x10250000
+#define REG_SDIO_HIMR_8822B 0x10250014
+#define REG_SDIO_HISR_8822B 0x10250018
+#define REG_SDIO_RX_REQ_LEN_8822B 0x1025001C
+#define REG_SDIO_FREE_TXPG_SEQ_V1_8822B 0x1025001F
+#define REG_SDIO_FREE_TXPG_8822B 0x10250020
+#define REG_SDIO_FREE_TXPG2_8822B 0x10250024
+#define REG_SDIO_OQT_FREE_TXPG_V1_8822B 0x10250028
+#define REG_SDIO_HTSFR_INFO_8822B 0x10250030
+#define REG_SDIO_HCPWM1_V2_8822B 0x10250038
+#define REG_SDIO_HCPWM2_V2_8822B 0x1025003A
+#define REG_SDIO_INDIRECT_REG_CFG_8822B 0x10250040
+#define REG_SDIO_INDIRECT_REG_DATA_8822B 0x10250044
+#define REG_SDIO_H2C_8822B 0x10250060
+#define REG_SDIO_C2H_8822B 0x10250064
+#define REG_SDIO_HRPWM1_8822B 0x10250080
+#define REG_SDIO_HRPWM2_8822B 0x10250082
+#define REG_SDIO_HPS_CLKR_8822B 0x10250084
+#define REG_SDIO_BUS_CTRL_8822B 0x10250085
+#define REG_SDIO_HSUS_CTRL_8822B 0x10250086
+#define REG_SDIO_RESPONSE_TIMER_8822B 0x10250088
+#define REG_SDIO_CMD_CRC_8822B 0x1025008A
+#define REG_SDIO_HSISR_8822B 0x10250090
+#define REG_SDIO_HSIMR_8822B 0x10250091
+#define REG_SDIO_ERR_RPT_8822B 0x102500C0
+#define REG_SDIO_CMD_ERRCNT_8822B 0x102500C1
+#define REG_SDIO_DATA_ERRCNT_8822B 0x102500C2
+#define REG_SDIO_CMD_ERR_CONTENT_8822B 0x102500C4
+#define REG_SDIO_CRC_ERR_IDX_8822B 0x102500C9
+#define REG_SDIO_DATA_CRC_8822B 0x102500CA
+#define REG_SDIO_DATA_REPLY_TIME_8822B 0x102500CB
+
+#endif
diff --git a/drivers/staging/rtlwifi/halmac/halmac_rx_bd_chip.h b/drivers/staging/rtlwifi/halmac/halmac_rx_bd_chip.h
new file mode 100644
index 0000000..59ff1fec
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_rx_bd_chip.h
@@ -0,0 +1,48 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HALMAC_RX_BD_CHIP_H_
+#define _HALMAC_RX_BD_CHIP_H_
+
+/*TXBD_DW0*/
+
+#define GET_RX_BD_RXFAIL_8822B(__rx_bd) GET_RX_BD_RXFAIL(__rx_bd)
+#define GET_RX_BD_TOTALRXPKTSIZE_8822B(__rx_bd) \
+ GET_RX_BD_TOTALRXPKTSIZE(__rx_bd)
+#define GET_RX_BD_RXTAG_8822B(__rx_bd) GET_RX_BD_RXTAG(__rx_bd)
+#define GET_RX_BD_FS_8822B(__rx_bd) GET_RX_BD_FS(__rx_bd)
+#define GET_RX_BD_LS_8822B(__rx_bd) GET_RX_BD_LS(__rx_bd)
+#define GET_RX_BD_RXBUFFSIZE_8822B(__rx_bd) GET_RX_BD_RXBUFFSIZE(__rx_bd)
+
+/*TXBD_DW1*/
+
+#define GET_RX_BD_PHYSICAL_ADDR_LOW_8822B(__rx_bd) \
+ GET_RX_BD_PHYSICAL_ADDR_LOW(__rx_bd)
+
+/*TXBD_DW2*/
+
+#define GET_RX_BD_PHYSICAL_ADDR_HIGH_8822B(__rx_bd) \
+ GET_RX_BD_PHYSICAL_ADDR_HIGH(__rx_bd)
+
+#endif
diff --git a/drivers/staging/rtlwifi/halmac/halmac_rx_bd_nic.h b/drivers/staging/rtlwifi/halmac/halmac_rx_bd_nic.h
new file mode 100644
index 0000000..62817d8
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_rx_bd_nic.h
@@ -0,0 +1,48 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HALMAC_RX_BD_NIC_H_
+#define _HALMAC_RX_BD_NIC_H_
+
+/*TXBD_DW0*/
+
+#define GET_RX_BD_RXFAIL(__rx_bd) LE_BITS_TO_4BYTE(__rx_bd + 0x00, 31, 1)
+#define GET_RX_BD_TOTALRXPKTSIZE(__rx_bd) \
+ LE_BITS_TO_4BYTE(__rx_bd + 0x00, 16, 13)
+#define GET_RX_BD_RXTAG(__rx_bd) LE_BITS_TO_4BYTE(__rx_bd + 0x00, 16, 13)
+#define GET_RX_BD_FS(__rx_bd) LE_BITS_TO_4BYTE(__rx_bd + 0x00, 15, 1)
+#define GET_RX_BD_LS(__rx_bd) LE_BITS_TO_4BYTE(__rx_bd + 0x00, 14, 1)
+#define GET_RX_BD_RXBUFFSIZE(__rx_bd) LE_BITS_TO_4BYTE(__rx_bd + 0x00, 0, 14)
+
+/*TXBD_DW1*/
+
+#define GET_RX_BD_PHYSICAL_ADDR_LOW(__rx_bd) \
+ LE_BITS_TO_4BYTE(__rx_bd + 0x04, 0, 32)
+
+/*TXBD_DW2*/
+
+#define GET_RX_BD_PHYSICAL_ADDR_HIGH(__rx_bd) \
+ LE_BITS_TO_4BYTE(__rx_bd + 0x08, 0, 32)
+
+#endif
diff --git a/drivers/staging/rtlwifi/halmac/halmac_rx_desc_chip.h b/drivers/staging/rtlwifi/halmac/halmac_rx_desc_chip.h
new file mode 100644
index 0000000..442120a
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_rx_desc_chip.h
@@ -0,0 +1,118 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HALMAC_RX_DESC_CHIP_H_
+#define _HALMAC_RX_DESC_CHIP_H_
+
+/*RXDESC_WORD0*/
+
+#define GET_RX_DESC_EOR_8822B(__rx_desc) GET_RX_DESC_EOR(__rx_desc)
+#define GET_RX_DESC_PHYPKTIDC_8822B(__rx_desc) GET_RX_DESC_PHYPKTIDC(__rx_desc)
+#define GET_RX_DESC_SWDEC_8822B(__rx_desc) GET_RX_DESC_SWDEC(__rx_desc)
+#define GET_RX_DESC_PHYST_8822B(__rx_desc) GET_RX_DESC_PHYST(__rx_desc)
+#define GET_RX_DESC_SHIFT_8822B(__rx_desc) GET_RX_DESC_SHIFT(__rx_desc)
+#define GET_RX_DESC_QOS_8822B(__rx_desc) GET_RX_DESC_QOS(__rx_desc)
+#define GET_RX_DESC_SECURITY_8822B(__rx_desc) GET_RX_DESC_SECURITY(__rx_desc)
+#define GET_RX_DESC_DRV_INFO_SIZE_8822B(__rx_desc) \
+ GET_RX_DESC_DRV_INFO_SIZE(__rx_desc)
+#define GET_RX_DESC_ICV_ERR_8822B(__rx_desc) GET_RX_DESC_ICV_ERR(__rx_desc)
+#define GET_RX_DESC_CRC32_8822B(__rx_desc) GET_RX_DESC_CRC32(__rx_desc)
+#define GET_RX_DESC_PKT_LEN_8822B(__rx_desc) GET_RX_DESC_PKT_LEN(__rx_desc)
+
+/*RXDESC_WORD1*/
+
+#define GET_RX_DESC_BC_8822B(__rx_desc) GET_RX_DESC_BC(__rx_desc)
+#define GET_RX_DESC_MC_8822B(__rx_desc) GET_RX_DESC_MC(__rx_desc)
+#define GET_RX_DESC_TY_PE_8822B(__rx_desc) GET_RX_DESC_TY_PE(__rx_desc)
+#define GET_RX_DESC_MF_8822B(__rx_desc) GET_RX_DESC_MF(__rx_desc)
+#define GET_RX_DESC_MD_8822B(__rx_desc) GET_RX_DESC_MD(__rx_desc)
+#define GET_RX_DESC_PWR_8822B(__rx_desc) GET_RX_DESC_PWR(__rx_desc)
+#define GET_RX_DESC_PAM_8822B(__rx_desc) GET_RX_DESC_PAM(__rx_desc)
+#define GET_RX_DESC_CHK_VLD_8822B(__rx_desc) GET_RX_DESC_CHK_VLD(__rx_desc)
+#define GET_RX_DESC_RX_IS_TCP_UDP_8822B(__rx_desc) \
+ GET_RX_DESC_RX_IS_TCP_UDP(__rx_desc)
+#define GET_RX_DESC_RX_IPV_8822B(__rx_desc) GET_RX_DESC_RX_IPV(__rx_desc)
+#define GET_RX_DESC_CHKERR_8822B(__rx_desc) GET_RX_DESC_CHKERR(__rx_desc)
+#define GET_RX_DESC_PAGGR_8822B(__rx_desc) GET_RX_DESC_PAGGR(__rx_desc)
+#define GET_RX_DESC_RXID_MATCH_8822B(__rx_desc) \
+ GET_RX_DESC_RXID_MATCH(__rx_desc)
+#define GET_RX_DESC_AMSDU_8822B(__rx_desc) GET_RX_DESC_AMSDU(__rx_desc)
+#define GET_RX_DESC_MACID_VLD_8822B(__rx_desc) GET_RX_DESC_MACID_VLD(__rx_desc)
+#define GET_RX_DESC_TID_8822B(__rx_desc) GET_RX_DESC_TID(__rx_desc)
+#define GET_RX_DESC_EXT_SECTYPE_8822B(__rx_desc) \
+ GET_RX_DESC_EXT_SECTYPE(__rx_desc)
+#define GET_RX_DESC_MACID_8822B(__rx_desc) GET_RX_DESC_MACID(__rx_desc)
+
+/*RXDESC_WORD2*/
+
+#define GET_RX_DESC_FCS_OK_8822B(__rx_desc) GET_RX_DESC_FCS_OK(__rx_desc)
+#define GET_RX_DESC_PPDU_CNT_8822B(__rx_desc) GET_RX_DESC_PPDU_CNT(__rx_desc)
+#define GET_RX_DESC_C2H_8822B(__rx_desc) GET_RX_DESC_C2H(__rx_desc)
+#define GET_RX_DESC_HWRSVD_8822B(__rx_desc) GET_RX_DESC_HWRSVD(__rx_desc)
+#define GET_RX_DESC_WLANHD_IV_LEN_8822B(__rx_desc) \
+ GET_RX_DESC_WLANHD_IV_LEN(__rx_desc)
+#define GET_RX_DESC_RX_IS_QOS_8822B(__rx_desc) GET_RX_DESC_RX_IS_QOS(__rx_desc)
+#define GET_RX_DESC_FRAG_8822B(__rx_desc) GET_RX_DESC_FRAG(__rx_desc)
+#define GET_RX_DESC_SEQ_8822B(__rx_desc) GET_RX_DESC_SEQ(__rx_desc)
+
+/*RXDESC_WORD3*/
+
+#define GET_RX_DESC_MAGIC_WAKE_8822B(__rx_desc) \
+ GET_RX_DESC_MAGIC_WAKE(__rx_desc)
+#define GET_RX_DESC_UNICAST_WAKE_8822B(__rx_desc) \
+ GET_RX_DESC_UNICAST_WAKE(__rx_desc)
+#define GET_RX_DESC_PATTERN_MATCH_8822B(__rx_desc) \
+ GET_RX_DESC_PATTERN_MATCH(__rx_desc)
+#define GET_RX_DESC_RXPAYLOAD_MATCH_8822B(__rx_desc) \
+ GET_RX_DESC_RXPAYLOAD_MATCH(__rx_desc)
+#define GET_RX_DESC_RXPAYLOAD_ID_8822B(__rx_desc) \
+ GET_RX_DESC_RXPAYLOAD_ID(__rx_desc)
+#define GET_RX_DESC_DMA_AGG_NUM_8822B(__rx_desc) \
+ GET_RX_DESC_DMA_AGG_NUM(__rx_desc)
+#define GET_RX_DESC_BSSID_FIT_1_0_8822B(__rx_desc) \
+ GET_RX_DESC_BSSID_FIT_1_0(__rx_desc)
+#define GET_RX_DESC_EOSP_8822B(__rx_desc) GET_RX_DESC_EOSP(__rx_desc)
+#define GET_RX_DESC_HTC_8822B(__rx_desc) GET_RX_DESC_HTC(__rx_desc)
+#define GET_RX_DESC_BSSID_FIT_4_2_8822B(__rx_desc) \
+ GET_RX_DESC_BSSID_FIT_4_2(__rx_desc)
+#define GET_RX_DESC_RX_RATE_8822B(__rx_desc) GET_RX_DESC_RX_RATE(__rx_desc)
+
+/*RXDESC_WORD4*/
+
+#define GET_RX_DESC_A1_FIT_8822B(__rx_desc) GET_RX_DESC_A1_FIT(__rx_desc)
+#define GET_RX_DESC_MACID_RPT_BUFF_8822B(__rx_desc) \
+ GET_RX_DESC_MACID_RPT_BUFF(__rx_desc)
+#define GET_RX_DESC_RX_PRE_NDP_VLD_8822B(__rx_desc) \
+ GET_RX_DESC_RX_PRE_NDP_VLD(__rx_desc)
+#define GET_RX_DESC_RX_SCRAMBLER_8822B(__rx_desc) \
+ GET_RX_DESC_RX_SCRAMBLER(__rx_desc)
+#define GET_RX_DESC_RX_EOF_8822B(__rx_desc) GET_RX_DESC_RX_EOF(__rx_desc)
+#define GET_RX_DESC_PATTERN_IDX_8822B(__rx_desc) \
+ GET_RX_DESC_PATTERN_IDX(__rx_desc)
+
+/*RXDESC_WORD5*/
+
+#define GET_RX_DESC_TSFL_8822B(__rx_desc) GET_RX_DESC_TSFL(__rx_desc)
+
+#endif
diff --git a/drivers/staging/rtlwifi/halmac/halmac_rx_desc_nic.h b/drivers/staging/rtlwifi/halmac/halmac_rx_desc_nic.h
new file mode 100644
index 0000000..8256c36
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_rx_desc_nic.h
@@ -0,0 +1,133 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HALMAC_RX_DESC_NIC_H_
+#define _HALMAC_RX_DESC_NIC_H_
+
+/*RXDESC_WORD0*/
+
+#define GET_RX_DESC_EOR(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x00, 30, 1)
+#define GET_RX_DESC_PHYPKTIDC(__rx_desc) \
+ LE_BITS_TO_4BYTE(__rx_desc + 0x00, 28, 1)
+#define GET_RX_DESC_SWDEC(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x00, 27, 1)
+#define GET_RX_DESC_PHYST(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x00, 26, 1)
+#define GET_RX_DESC_SHIFT(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x00, 24, 2)
+#define GET_RX_DESC_QOS(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x00, 23, 1)
+#define GET_RX_DESC_SECURITY(__rx_desc) \
+ LE_BITS_TO_4BYTE(__rx_desc + 0x00, 20, 3)
+#define GET_RX_DESC_DRV_INFO_SIZE(__rx_desc) \
+ LE_BITS_TO_4BYTE(__rx_desc + 0x00, 16, 4)
+#define GET_RX_DESC_ICV_ERR(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x00, 15, 1)
+#define GET_RX_DESC_CRC32(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x00, 14, 1)
+#define GET_RX_DESC_PKT_LEN(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x00, 0, 14)
+
+/*RXDESC_WORD1*/
+
+#define GET_RX_DESC_BC(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x04, 31, 1)
+#define GET_RX_DESC_MC(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x04, 30, 1)
+#define GET_RX_DESC_TY_PE(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x04, 28, 2)
+#define GET_RX_DESC_MF(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x04, 27, 1)
+#define GET_RX_DESC_MD(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x04, 26, 1)
+#define GET_RX_DESC_PWR(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x04, 25, 1)
+#define GET_RX_DESC_PAM(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x04, 24, 1)
+#define GET_RX_DESC_CHK_VLD(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x04, 23, 1)
+#define GET_RX_DESC_RX_IS_TCP_UDP(__rx_desc) \
+ LE_BITS_TO_4BYTE(__rx_desc + 0x04, 22, 1)
+#define GET_RX_DESC_RX_IPV(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x04, 21, 1)
+#define GET_RX_DESC_CHKERR(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x04, 20, 1)
+#define GET_RX_DESC_PAGGR(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x04, 15, 1)
+#define GET_RX_DESC_RXID_MATCH(__rx_desc) \
+ LE_BITS_TO_4BYTE(__rx_desc + 0x04, 14, 1)
+#define GET_RX_DESC_AMSDU(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x04, 13, 1)
+#define GET_RX_DESC_MACID_VLD(__rx_desc) \
+ LE_BITS_TO_4BYTE(__rx_desc + 0x04, 12, 1)
+#define GET_RX_DESC_TID(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x04, 8, 4)
+
+#define GET_RX_DESC_EXT_SECTYPE(__rx_desc) \
+ LE_BITS_TO_4BYTE(__rx_desc + 0x04, 7, 1)
+
+#define GET_RX_DESC_MACID(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x04, 0, 7)
+
+/*RXDESC_WORD2*/
+
+#define GET_RX_DESC_FCS_OK(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x08, 31, 1)
+
+#define GET_RX_DESC_PPDU_CNT(__rx_desc) \
+ LE_BITS_TO_4BYTE(__rx_desc + 0x08, 29, 2)
+
+#define GET_RX_DESC_C2H(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x08, 28, 1)
+#define GET_RX_DESC_HWRSVD(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x08, 24, 4)
+#define GET_RX_DESC_WLANHD_IV_LEN(__rx_desc) \
+ LE_BITS_TO_4BYTE(__rx_desc + 0x08, 18, 6)
+#define GET_RX_DESC_RX_IS_QOS(__rx_desc) \
+ LE_BITS_TO_4BYTE(__rx_desc + 0x08, 16, 1)
+#define GET_RX_DESC_FRAG(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x08, 12, 4)
+#define GET_RX_DESC_SEQ(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x08, 0, 12)
+
+/*RXDESC_WORD3*/
+
+#define GET_RX_DESC_MAGIC_WAKE(__rx_desc) \
+ LE_BITS_TO_4BYTE(__rx_desc + 0x0C, 31, 1)
+#define GET_RX_DESC_UNICAST_WAKE(__rx_desc) \
+ LE_BITS_TO_4BYTE(__rx_desc + 0x0C, 30, 1)
+#define GET_RX_DESC_PATTERN_MATCH(__rx_desc) \
+ LE_BITS_TO_4BYTE(__rx_desc + 0x0C, 29, 1)
+
+#define GET_RX_DESC_RXPAYLOAD_MATCH(__rx_desc) \
+ LE_BITS_TO_4BYTE(__rx_desc + 0x0C, 28, 1)
+#define GET_RX_DESC_RXPAYLOAD_ID(__rx_desc) \
+ LE_BITS_TO_4BYTE(__rx_desc + 0x0C, 24, 4)
+
+#define GET_RX_DESC_DMA_AGG_NUM(__rx_desc) \
+ LE_BITS_TO_4BYTE(__rx_desc + 0x0C, 16, 8)
+#define GET_RX_DESC_BSSID_FIT_1_0(__rx_desc) \
+ LE_BITS_TO_4BYTE(__rx_desc + 0x0C, 12, 2)
+#define GET_RX_DESC_EOSP(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x0C, 11, 1)
+#define GET_RX_DESC_HTC(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x0C, 10, 1)
+
+#define GET_RX_DESC_BSSID_FIT_4_2(__rx_desc) \
+ LE_BITS_TO_4BYTE(__rx_desc + 0x0C, 7, 3)
+
+#define GET_RX_DESC_RX_RATE(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x0C, 0, 7)
+
+/*RXDESC_WORD4*/
+
+#define GET_RX_DESC_A1_FIT(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x10, 24, 5)
+
+#define GET_RX_DESC_MACID_RPT_BUFF(__rx_desc) \
+ LE_BITS_TO_4BYTE(__rx_desc + 0x10, 17, 7)
+#define GET_RX_DESC_RX_PRE_NDP_VLD(__rx_desc) \
+ LE_BITS_TO_4BYTE(__rx_desc + 0x10, 16, 1)
+#define GET_RX_DESC_RX_SCRAMBLER(__rx_desc) \
+ LE_BITS_TO_4BYTE(__rx_desc + 0x10, 9, 7)
+#define GET_RX_DESC_RX_EOF(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x10, 8, 1)
+
+#define GET_RX_DESC_PATTERN_IDX(__rx_desc) \
+ LE_BITS_TO_4BYTE(__rx_desc + 0x10, 0, 8)
+
+/*RXDESC_WORD5*/
+
+#define GET_RX_DESC_TSFL(__rx_desc) LE_BITS_TO_4BYTE(__rx_desc + 0x14, 0, 32)
+
+#endif
diff --git a/drivers/staging/rtlwifi/halmac/halmac_sdio_reg.h b/drivers/staging/rtlwifi/halmac/halmac_sdio_reg.h
new file mode 100644
index 0000000..8967699
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_sdio_reg.h
@@ -0,0 +1,62 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __HALMAC_SDIO_REG_H__
+#define __HALMAC_SDIO_REG_H__
+
+/* SDIO CMD address mapping */
+
+#define HALMAC_SDIO_4BYTE_LEN_MASK 0x1FFF
+#define HALMAC_SDIO_LOCAL_MSK 0x0FFF
+#define HALMAC_WLAN_MAC_REG_MSK 0xFFFF
+#define HALMAC_WLAN_IOREG_MSK 0xFFFF
+
+/* Sdio address for SDIO Local Reg, TRX FIFO, MAC Reg */
+enum halmac_sdio_cmd_addr {
+ HALMAC_SDIO_CMD_ADDR_SDIO_REG = 0,
+ HALMAC_SDIO_CMD_ADDR_MAC_REG = 8,
+ HALMAC_SDIO_CMD_ADDR_TXFF_HIGH = 4,
+ HALMAC_SDIO_CMD_ADDR_TXFF_LOW = 6,
+ HALMAC_SDIO_CMD_ADDR_TXFF_NORMAL = 5,
+ HALMAC_SDIO_CMD_ADDR_TXFF_EXTRA = 7,
+ HALMAC_SDIO_CMD_ADDR_RXFF = 7,
+};
+
+/* IO Bus domain address mapping */
+#define SDIO_LOCAL_OFFSET 0x10250000
+#define WLAN_IOREG_OFFSET 0x10260000
+#define FW_FIFO_OFFSET 0x10270000
+#define TX_HIQ_OFFSET 0x10310000
+#define TX_MIQ_OFFSET 0x10320000
+#define TX_LOQ_OFFSET 0x10330000
+#define TX_EXQ_OFFSET 0x10350000
+#define RX_RXOFF_OFFSET 0x10340000
+
+/* Get TX WLAN FIFO information in CMD53 addr */
+#define GET_WLAN_TXFF_DEVICE_ID(__cmd53_addr) \
+ LE_BITS_TO_4BYTE((u32 *)__cmd53_addr, 13, 4)
+#define GET_WLAN_TXFF_PKT_SIZE(__cmd53_addr) \
+ (LE_BITS_TO_4BYTE((u32 *)__cmd53_addr, 0, 13) << 2)
+
+#endif /* __HALMAC_SDIO_REG_H__ */
diff --git a/drivers/staging/rtlwifi/halmac/halmac_tx_bd_chip.h b/drivers/staging/rtlwifi/halmac/halmac_tx_bd_chip.h
new file mode 100644
index 0000000..d5c9da2
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_tx_bd_chip.h
@@ -0,0 +1,118 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HALMAC_TX_BD_CHIP_H_
+#define _HALMAC_TX_BD_CHIP_H_
+
+/*TXBD_DW0*/
+
+#define SET_TX_BD_OWN_8822B(__tx_bd, __value) SET_TX_BD_OWN(__tx_bd, __value)
+#define GET_TX_BD_OWN_8822B(__tx_bd) GET_TX_BD_OWN(__tx_bd)
+#define SET_TX_BD_PSB_8822B(__tx_bd, __value) SET_TX_BD_PSB(__tx_bd, __value)
+#define GET_TX_BD_PSB_8822B(__tx_bd) GET_TX_BD_PSB(__tx_bd)
+#define SET_TX_BD_TX_BUFF_SIZE0_8822B(__tx_bd, __value) \
+ SET_TX_BD_TX_BUFF_SIZE0(__tx_bd, __value)
+#define GET_TX_BD_TX_BUFF_SIZE0_8822B(__tx_bd) GET_TX_BD_TX_BUFF_SIZE0(__tx_bd)
+
+/*TXBD_DW1*/
+
+#define SET_TX_BD_PHYSICAL_ADDR0_LOW_8822B(__tx_bd, __value) \
+ SET_TX_BD_PHYSICAL_ADDR0_LOW(__tx_bd, __value)
+#define GET_TX_BD_PHYSICAL_ADDR0_LOW_8822B(__tx_bd) \
+ GET_TX_BD_PHYSICAL_ADDR0_LOW(__tx_bd)
+
+/*TXBD_DW2*/
+
+#define SET_TX_BD_PHYSICAL_ADDR0_HIGH_8822B(__tx_bd, __value) \
+ SET_TX_BD_PHYSICAL_ADDR0_HIGH(__tx_bd, __value)
+#define GET_TX_BD_PHYSICAL_ADDR0_HIGH_8822B(__tx_bd) \
+ GET_TX_BD_PHYSICAL_ADDR0_HIGH(__tx_bd)
+
+/*TXBD_DW4*/
+
+#define SET_TX_BD_A1_8822B(__tx_bd, __value) SET_TX_BD_A1(__tx_bd, __value)
+#define GET_TX_BD_A1_8822B(__tx_bd) GET_TX_BD_A1(__tx_bd)
+#define SET_TX_BD_TX_BUFF_SIZE1_8822B(__tx_bd, __value) \
+ SET_TX_BD_TX_BUFF_SIZE1(__tx_bd, __value)
+#define GET_TX_BD_TX_BUFF_SIZE1_8822B(__tx_bd) GET_TX_BD_TX_BUFF_SIZE1(__tx_bd)
+
+/*TXBD_DW5*/
+
+#define SET_TX_BD_PHYSICAL_ADDR1_LOW_8822B(__tx_bd, __value) \
+ SET_TX_BD_PHYSICAL_ADDR1_LOW(__tx_bd, __value)
+#define GET_TX_BD_PHYSICAL_ADDR1_LOW_8822B(__tx_bd) \
+ GET_TX_BD_PHYSICAL_ADDR1_LOW(__tx_bd)
+
+/*TXBD_DW6*/
+
+#define SET_TX_BD_PHYSICAL_ADDR1_HIGH_8822B(__tx_bd, __value) \
+ SET_TX_BD_PHYSICAL_ADDR1_HIGH(__tx_bd, __value)
+#define GET_TX_BD_PHYSICAL_ADDR1_HIGH_8822B(__tx_bd) \
+ GET_TX_BD_PHYSICAL_ADDR1_HIGH(__tx_bd)
+
+/*TXBD_DW8*/
+
+#define SET_TX_BD_A2_8822B(__tx_bd, __value) SET_TX_BD_A2(__tx_bd, __value)
+#define GET_TX_BD_A2_8822B(__tx_bd) GET_TX_BD_A2(__tx_bd)
+#define SET_TX_BD_TX_BUFF_SIZE2_8822B(__tx_bd, __value) \
+ SET_TX_BD_TX_BUFF_SIZE2(__tx_bd, __value)
+#define GET_TX_BD_TX_BUFF_SIZE2_8822B(__tx_bd) GET_TX_BD_TX_BUFF_SIZE2(__tx_bd)
+
+/*TXBD_DW9*/
+
+#define SET_TX_BD_PHYSICAL_ADDR2_LOW_8822B(__tx_bd, __value) \
+ SET_TX_BD_PHYSICAL_ADDR2_LOW(__tx_bd, __value)
+#define GET_TX_BD_PHYSICAL_ADDR2_LOW_8822B(__tx_bd) \
+ GET_TX_BD_PHYSICAL_ADDR2_LOW(__tx_bd)
+
+/*TXBD_DW10*/
+
+#define SET_TX_BD_PHYSICAL_ADDR2_HIGH_8822B(__tx_bd, __value) \
+ SET_TX_BD_PHYSICAL_ADDR2_HIGH(__tx_bd, __value)
+#define GET_TX_BD_PHYSICAL_ADDR2_HIGH_8822B(__tx_bd) \
+ GET_TX_BD_PHYSICAL_ADDR2_HIGH(__tx_bd)
+
+/*TXBD_DW12*/
+
+#define SET_TX_BD_A3_8822B(__tx_bd, __value) SET_TX_BD_A3(__tx_bd, __value)
+#define GET_TX_BD_A3_8822B(__tx_bd) GET_TX_BD_A3(__tx_bd)
+#define SET_TX_BD_TX_BUFF_SIZE3_8822B(__tx_bd, __value) \
+ SET_TX_BD_TX_BUFF_SIZE3(__tx_bd, __value)
+#define GET_TX_BD_TX_BUFF_SIZE3_8822B(__tx_bd) GET_TX_BD_TX_BUFF_SIZE3(__tx_bd)
+
+/*TXBD_DW13*/
+
+#define SET_TX_BD_PHYSICAL_ADDR3_LOW_8822B(__tx_bd, __value) \
+ SET_TX_BD_PHYSICAL_ADDR3_LOW(__tx_bd, __value)
+#define GET_TX_BD_PHYSICAL_ADDR3_LOW_8822B(__tx_bd) \
+ GET_TX_BD_PHYSICAL_ADDR3_LOW(__tx_bd)
+
+/*TXBD_DW14*/
+
+#define SET_TX_BD_PHYSICAL_ADDR3_HIGH_8822B(__tx_bd, __value) \
+ SET_TX_BD_PHYSICAL_ADDR3_HIGH(__tx_bd, __value)
+#define GET_TX_BD_PHYSICAL_ADDR3_HIGH_8822B(__tx_bd) \
+ GET_TX_BD_PHYSICAL_ADDR3_HIGH(__tx_bd)
+
+#endif
diff --git a/drivers/staging/rtlwifi/halmac/halmac_tx_bd_nic.h b/drivers/staging/rtlwifi/halmac/halmac_tx_bd_nic.h
new file mode 100644
index 0000000..43c2261
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_tx_bd_nic.h
@@ -0,0 +1,123 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HALMAC_TX_BD_NIC_H_
+#define _HALMAC_TX_BD_NIC_H_
+
+/*TXBD_DW0*/
+
+#define SET_TX_BD_OWN(__tx_bd, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_bd + 0x00, 31, 1, __value)
+#define GET_TX_BD_OWN(__tx_bd) LE_BITS_TO_4BYTE(__tx_bd + 0x00, 31, 1)
+#define SET_TX_BD_PSB(__tx_bd, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_bd + 0x00, 16, 8, __value)
+#define GET_TX_BD_PSB(__tx_bd) LE_BITS_TO_4BYTE(__tx_bd + 0x00, 16, 8)
+#define SET_TX_BD_TX_BUFF_SIZE0(__tx_bd, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_bd + 0x00, 0, 16, __value)
+#define GET_TX_BD_TX_BUFF_SIZE0(__tx_bd) LE_BITS_TO_4BYTE(__tx_bd + 0x00, 0, 16)
+
+/*TXBD_DW1*/
+
+#define SET_TX_BD_PHYSICAL_ADDR0_LOW(__tx_bd, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_bd + 0x04, 0, 32, __value)
+#define GET_TX_BD_PHYSICAL_ADDR0_LOW(__tx_bd) \
+ LE_BITS_TO_4BYTE(__tx_bd + 0x04, 0, 32)
+
+/*TXBD_DW2*/
+
+#define SET_TX_BD_PHYSICAL_ADDR0_HIGH(__tx_bd, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_bd + 0x08, 0, 32, __value)
+#define GET_TX_BD_PHYSICAL_ADDR0_HIGH(__tx_bd) \
+ LE_BITS_TO_4BYTE(__tx_bd + 0x08, 0, 32)
+
+/*TXBD_DW4*/
+
+#define SET_TX_BD_A1(__tx_bd, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_bd + 0x10, 31, 1, __value)
+#define GET_TX_BD_A1(__tx_bd) LE_BITS_TO_4BYTE(__tx_bd + 0x10, 31, 1)
+#define SET_TX_BD_TX_BUFF_SIZE1(__tx_bd, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_bd + 0x10, 0, 16, __value)
+#define GET_TX_BD_TX_BUFF_SIZE1(__tx_bd) LE_BITS_TO_4BYTE(__tx_bd + 0x10, 0, 16)
+
+/*TXBD_DW5*/
+
+#define SET_TX_BD_PHYSICAL_ADDR1_LOW(__tx_bd, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_bd + 0x14, 0, 32, __value)
+#define GET_TX_BD_PHYSICAL_ADDR1_LOW(__tx_bd) \
+ LE_BITS_TO_4BYTE(__tx_bd + 0x14, 0, 32)
+
+/*TXBD_DW6*/
+
+#define SET_TX_BD_PHYSICAL_ADDR1_HIGH(__tx_bd, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_bd + 0x18, 0, 32, __value)
+#define GET_TX_BD_PHYSICAL_ADDR1_HIGH(__tx_bd) \
+ LE_BITS_TO_4BYTE(__tx_bd + 0x18, 0, 32)
+
+/*TXBD_DW8*/
+
+#define SET_TX_BD_A2(__tx_bd, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_bd + 0x20, 31, 1, __value)
+#define GET_TX_BD_A2(__tx_bd) LE_BITS_TO_4BYTE(__tx_bd + 0x20, 31, 1)
+#define SET_TX_BD_TX_BUFF_SIZE2(__tx_bd, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_bd + 0x20, 0, 16, __value)
+#define GET_TX_BD_TX_BUFF_SIZE2(__tx_bd) LE_BITS_TO_4BYTE(__tx_bd + 0x20, 0, 16)
+
+/*TXBD_DW9*/
+
+#define SET_TX_BD_PHYSICAL_ADDR2_LOW(__tx_bd, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_bd + 0x24, 0, 32, __value)
+#define GET_TX_BD_PHYSICAL_ADDR2_LOW(__tx_bd) \
+ LE_BITS_TO_4BYTE(__tx_bd + 0x24, 0, 32)
+
+/*TXBD_DW10*/
+
+#define SET_TX_BD_PHYSICAL_ADDR2_HIGH(__tx_bd, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_bd + 0x28, 0, 32, __value)
+#define GET_TX_BD_PHYSICAL_ADDR2_HIGH(__tx_bd) \
+ LE_BITS_TO_4BYTE(__tx_bd + 0x28, 0, 32)
+
+/*TXBD_DW12*/
+
+#define SET_TX_BD_A3(__tx_bd, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_bd + 0x30, 31, 1, __value)
+#define GET_TX_BD_A3(__tx_bd) LE_BITS_TO_4BYTE(__tx_bd + 0x30, 31, 1)
+#define SET_TX_BD_TX_BUFF_SIZE3(__tx_bd, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_bd + 0x30, 0, 16, __value)
+#define GET_TX_BD_TX_BUFF_SIZE3(__tx_bd) LE_BITS_TO_4BYTE(__tx_bd + 0x30, 0, 16)
+
+/*TXBD_DW13*/
+
+#define SET_TX_BD_PHYSICAL_ADDR3_LOW(__tx_bd, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_bd + 0x34, 0, 32, __value)
+#define GET_TX_BD_PHYSICAL_ADDR3_LOW(__tx_bd) \
+ LE_BITS_TO_4BYTE(__tx_bd + 0x34, 0, 32)
+
+/*TXBD_DW14*/
+
+#define SET_TX_BD_PHYSICAL_ADDR3_HIGH(__tx_bd, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_bd + 0x38, 0, 32, __value)
+#define GET_TX_BD_PHYSICAL_ADDR3_HIGH(__tx_bd) \
+ LE_BITS_TO_4BYTE(__tx_bd + 0x38, 0, 32)
+
+#endif
diff --git a/drivers/staging/rtlwifi/halmac/halmac_tx_desc_chip.h b/drivers/staging/rtlwifi/halmac/halmac_tx_desc_chip.h
new file mode 100644
index 0000000..fd1aa39
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_tx_desc_chip.h
@@ -0,0 +1,444 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HALMAC_TX_DESC_CHIP_H_
+#define _HALMAC_TX_DESC_CHIP_H_
+
+/*TXDESC_WORD0*/
+
+#define SET_TX_DESC_DISQSELSEQ_8822B(__tx_desc, __value) \
+ SET_TX_DESC_DISQSELSEQ(__tx_desc, __value)
+#define GET_TX_DESC_DISQSELSEQ_8822B(__tx_desc) \
+ GET_TX_DESC_DISQSELSEQ(__tx_desc)
+#define SET_TX_DESC_GF_8822B(__tx_desc, __value) \
+ SET_TX_DESC_GF(__tx_desc, __value)
+#define GET_TX_DESC_GF_8822B(__tx_desc) GET_TX_DESC_GF(__tx_desc)
+#define SET_TX_DESC_NO_ACM_8822B(__tx_desc, __value) \
+ SET_TX_DESC_NO_ACM(__tx_desc, __value)
+#define GET_TX_DESC_NO_ACM_8822B(__tx_desc) GET_TX_DESC_NO_ACM(__tx_desc)
+#define SET_TX_DESC_BCNPKT_TSF_CTRL_8822B(__tx_desc, __value) \
+ SET_TX_DESC_BCNPKT_TSF_CTRL(__tx_desc, __value)
+#define GET_TX_DESC_BCNPKT_TSF_CTRL_8822B(__tx_desc) \
+ GET_TX_DESC_BCNPKT_TSF_CTRL(__tx_desc)
+#define SET_TX_DESC_AMSDU_PAD_EN_8822B(__tx_desc, __value) \
+ SET_TX_DESC_AMSDU_PAD_EN(__tx_desc, __value)
+#define GET_TX_DESC_AMSDU_PAD_EN_8822B(__tx_desc) \
+ GET_TX_DESC_AMSDU_PAD_EN(__tx_desc)
+#define SET_TX_DESC_LS_8822B(__tx_desc, __value) \
+ SET_TX_DESC_LS(__tx_desc, __value)
+#define GET_TX_DESC_LS_8822B(__tx_desc) GET_TX_DESC_LS(__tx_desc)
+#define SET_TX_DESC_HTC_8822B(__tx_desc, __value) \
+ SET_TX_DESC_HTC(__tx_desc, __value)
+#define GET_TX_DESC_HTC_8822B(__tx_desc) GET_TX_DESC_HTC(__tx_desc)
+#define SET_TX_DESC_BMC_8822B(__tx_desc, __value) \
+ SET_TX_DESC_BMC(__tx_desc, __value)
+#define GET_TX_DESC_BMC_8822B(__tx_desc) GET_TX_DESC_BMC(__tx_desc)
+#define SET_TX_DESC_OFFSET_8822B(__tx_desc, __value) \
+ SET_TX_DESC_OFFSET(__tx_desc, __value)
+#define GET_TX_DESC_OFFSET_8822B(__tx_desc) GET_TX_DESC_OFFSET(__tx_desc)
+#define SET_TX_DESC_TXPKTSIZE_8822B(__tx_desc, __value) \
+ SET_TX_DESC_TXPKTSIZE(__tx_desc, __value)
+#define GET_TX_DESC_TXPKTSIZE_8822B(__tx_desc) GET_TX_DESC_TXPKTSIZE(__tx_desc)
+
+/*TXDESC_WORD1*/
+
+#define SET_TX_DESC_MOREDATA_8822B(__tx_desc, __value) \
+ SET_TX_DESC_MOREDATA(__tx_desc, __value)
+#define GET_TX_DESC_MOREDATA_8822B(__tx_desc) GET_TX_DESC_MOREDATA(__tx_desc)
+#define SET_TX_DESC_PKT_OFFSET_8822B(__tx_desc, __value) \
+ SET_TX_DESC_PKT_OFFSET(__tx_desc, __value)
+#define GET_TX_DESC_PKT_OFFSET_8822B(__tx_desc) \
+ GET_TX_DESC_PKT_OFFSET(__tx_desc)
+#define SET_TX_DESC_SEC_TYPE_8822B(__tx_desc, __value) \
+ SET_TX_DESC_SEC_TYPE(__tx_desc, __value)
+#define GET_TX_DESC_SEC_TYPE_8822B(__tx_desc) GET_TX_DESC_SEC_TYPE(__tx_desc)
+#define SET_TX_DESC_EN_DESC_ID_8822B(__tx_desc, __value) \
+ SET_TX_DESC_EN_DESC_ID(__tx_desc, __value)
+#define GET_TX_DESC_EN_DESC_ID_8822B(__tx_desc) \
+ GET_TX_DESC_EN_DESC_ID(__tx_desc)
+#define SET_TX_DESC_RATE_ID_8822B(__tx_desc, __value) \
+ SET_TX_DESC_RATE_ID(__tx_desc, __value)
+#define GET_TX_DESC_RATE_ID_8822B(__tx_desc) GET_TX_DESC_RATE_ID(__tx_desc)
+#define SET_TX_DESC_PIFS_8822B(__tx_desc, __value) \
+ SET_TX_DESC_PIFS(__tx_desc, __value)
+#define GET_TX_DESC_PIFS_8822B(__tx_desc) GET_TX_DESC_PIFS(__tx_desc)
+#define SET_TX_DESC_LSIG_TXOP_EN_8822B(__tx_desc, __value) \
+ SET_TX_DESC_LSIG_TXOP_EN(__tx_desc, __value)
+#define GET_TX_DESC_LSIG_TXOP_EN_8822B(__tx_desc) \
+ GET_TX_DESC_LSIG_TXOP_EN(__tx_desc)
+#define SET_TX_DESC_RD_NAV_EXT_8822B(__tx_desc, __value) \
+ SET_TX_DESC_RD_NAV_EXT(__tx_desc, __value)
+#define GET_TX_DESC_RD_NAV_EXT_8822B(__tx_desc) \
+ GET_TX_DESC_RD_NAV_EXT(__tx_desc)
+#define SET_TX_DESC_QSEL_8822B(__tx_desc, __value) \
+ SET_TX_DESC_QSEL(__tx_desc, __value)
+#define GET_TX_DESC_QSEL_8822B(__tx_desc) GET_TX_DESC_QSEL(__tx_desc)
+#define SET_TX_DESC_MACID_8822B(__tx_desc, __value) \
+ SET_TX_DESC_MACID(__tx_desc, __value)
+#define GET_TX_DESC_MACID_8822B(__tx_desc) GET_TX_DESC_MACID(__tx_desc)
+
+/*TXDESC_WORD2*/
+
+#define SET_TX_DESC_HW_AES_IV_8822B(__tx_desc, __value) \
+ SET_TX_DESC_HW_AES_IV(__tx_desc, __value)
+#define GET_TX_DESC_HW_AES_IV_8822B(__tx_desc) GET_TX_DESC_HW_AES_IV(__tx_desc)
+#define SET_TX_DESC_FTM_EN_8822B(__tx_desc, __value) \
+ SET_TX_DESC_FTM_EN(__tx_desc, __value)
+#define GET_TX_DESC_FTM_EN_8822B(__tx_desc) GET_TX_DESC_FTM_EN(__tx_desc)
+#define SET_TX_DESC_G_ID_8822B(__tx_desc, __value) \
+ SET_TX_DESC_G_ID(__tx_desc, __value)
+#define GET_TX_DESC_G_ID_8822B(__tx_desc) GET_TX_DESC_G_ID(__tx_desc)
+#define SET_TX_DESC_BT_NULL_8822B(__tx_desc, __value) \
+ SET_TX_DESC_BT_NULL(__tx_desc, __value)
+#define GET_TX_DESC_BT_NULL_8822B(__tx_desc) GET_TX_DESC_BT_NULL(__tx_desc)
+#define SET_TX_DESC_AMPDU_DENSITY_8822B(__tx_desc, __value) \
+ SET_TX_DESC_AMPDU_DENSITY(__tx_desc, __value)
+#define GET_TX_DESC_AMPDU_DENSITY_8822B(__tx_desc) \
+ GET_TX_DESC_AMPDU_DENSITY(__tx_desc)
+#define SET_TX_DESC_SPE_RPT_8822B(__tx_desc, __value) \
+ SET_TX_DESC_SPE_RPT(__tx_desc, __value)
+#define GET_TX_DESC_SPE_RPT_8822B(__tx_desc) GET_TX_DESC_SPE_RPT(__tx_desc)
+#define SET_TX_DESC_RAW_8822B(__tx_desc, __value) \
+ SET_TX_DESC_RAW(__tx_desc, __value)
+#define GET_TX_DESC_RAW_8822B(__tx_desc) GET_TX_DESC_RAW(__tx_desc)
+#define SET_TX_DESC_MOREFRAG_8822B(__tx_desc, __value) \
+ SET_TX_DESC_MOREFRAG(__tx_desc, __value)
+#define GET_TX_DESC_MOREFRAG_8822B(__tx_desc) GET_TX_DESC_MOREFRAG(__tx_desc)
+#define SET_TX_DESC_BK_8822B(__tx_desc, __value) \
+ SET_TX_DESC_BK(__tx_desc, __value)
+#define GET_TX_DESC_BK_8822B(__tx_desc) GET_TX_DESC_BK(__tx_desc)
+#define SET_TX_DESC_NULL_1_8822B(__tx_desc, __value) \
+ SET_TX_DESC_NULL_1(__tx_desc, __value)
+#define GET_TX_DESC_NULL_1_8822B(__tx_desc) GET_TX_DESC_NULL_1(__tx_desc)
+#define SET_TX_DESC_NULL_0_8822B(__tx_desc, __value) \
+ SET_TX_DESC_NULL_0(__tx_desc, __value)
+#define GET_TX_DESC_NULL_0_8822B(__tx_desc) GET_TX_DESC_NULL_0(__tx_desc)
+#define SET_TX_DESC_RDG_EN_8822B(__tx_desc, __value) \
+ SET_TX_DESC_RDG_EN(__tx_desc, __value)
+#define GET_TX_DESC_RDG_EN_8822B(__tx_desc) GET_TX_DESC_RDG_EN(__tx_desc)
+#define SET_TX_DESC_AGG_EN_8822B(__tx_desc, __value) \
+ SET_TX_DESC_AGG_EN(__tx_desc, __value)
+#define GET_TX_DESC_AGG_EN_8822B(__tx_desc) GET_TX_DESC_AGG_EN(__tx_desc)
+#define SET_TX_DESC_CCA_RTS_8822B(__tx_desc, __value) \
+ SET_TX_DESC_CCA_RTS(__tx_desc, __value)
+#define GET_TX_DESC_CCA_RTS_8822B(__tx_desc) GET_TX_DESC_CCA_RTS(__tx_desc)
+#define SET_TX_DESC_TRI_FRAME_8822B(__tx_desc, __value) \
+ SET_TX_DESC_TRI_FRAME(__tx_desc, __value)
+#define GET_TX_DESC_TRI_FRAME_8822B(__tx_desc) GET_TX_DESC_TRI_FRAME(__tx_desc)
+#define SET_TX_DESC_P_AID_8822B(__tx_desc, __value) \
+ SET_TX_DESC_P_AID(__tx_desc, __value)
+#define GET_TX_DESC_P_AID_8822B(__tx_desc) GET_TX_DESC_P_AID(__tx_desc)
+
+/*TXDESC_WORD3*/
+
+#define SET_TX_DESC_AMPDU_MAX_TIME_8822B(__tx_desc, __value) \
+ SET_TX_DESC_AMPDU_MAX_TIME(__tx_desc, __value)
+#define GET_TX_DESC_AMPDU_MAX_TIME_8822B(__tx_desc) \
+ GET_TX_DESC_AMPDU_MAX_TIME(__tx_desc)
+#define SET_TX_DESC_NDPA_8822B(__tx_desc, __value) \
+ SET_TX_DESC_NDPA(__tx_desc, __value)
+#define GET_TX_DESC_NDPA_8822B(__tx_desc) GET_TX_DESC_NDPA(__tx_desc)
+#define SET_TX_DESC_MAX_AGG_NUM_8822B(__tx_desc, __value) \
+ SET_TX_DESC_MAX_AGG_NUM(__tx_desc, __value)
+#define GET_TX_DESC_MAX_AGG_NUM_8822B(__tx_desc) \
+ GET_TX_DESC_MAX_AGG_NUM(__tx_desc)
+#define SET_TX_DESC_USE_MAX_TIME_EN_8822B(__tx_desc, __value) \
+ SET_TX_DESC_USE_MAX_TIME_EN(__tx_desc, __value)
+#define GET_TX_DESC_USE_MAX_TIME_EN_8822B(__tx_desc) \
+ GET_TX_DESC_USE_MAX_TIME_EN(__tx_desc)
+#define SET_TX_DESC_NAVUSEHDR_8822B(__tx_desc, __value) \
+ SET_TX_DESC_NAVUSEHDR(__tx_desc, __value)
+#define GET_TX_DESC_NAVUSEHDR_8822B(__tx_desc) GET_TX_DESC_NAVUSEHDR(__tx_desc)
+#define SET_TX_DESC_CHK_EN_8822B(__tx_desc, __value) \
+ SET_TX_DESC_CHK_EN(__tx_desc, __value)
+#define GET_TX_DESC_CHK_EN_8822B(__tx_desc) GET_TX_DESC_CHK_EN(__tx_desc)
+#define SET_TX_DESC_HW_RTS_EN_8822B(__tx_desc, __value) \
+ SET_TX_DESC_HW_RTS_EN(__tx_desc, __value)
+#define GET_TX_DESC_HW_RTS_EN_8822B(__tx_desc) GET_TX_DESC_HW_RTS_EN(__tx_desc)
+#define SET_TX_DESC_RTSEN_8822B(__tx_desc, __value) \
+ SET_TX_DESC_RTSEN(__tx_desc, __value)
+#define GET_TX_DESC_RTSEN_8822B(__tx_desc) GET_TX_DESC_RTSEN(__tx_desc)
+#define SET_TX_DESC_CTS2SELF_8822B(__tx_desc, __value) \
+ SET_TX_DESC_CTS2SELF(__tx_desc, __value)
+#define GET_TX_DESC_CTS2SELF_8822B(__tx_desc) GET_TX_DESC_CTS2SELF(__tx_desc)
+#define SET_TX_DESC_DISDATAFB_8822B(__tx_desc, __value) \
+ SET_TX_DESC_DISDATAFB(__tx_desc, __value)
+#define GET_TX_DESC_DISDATAFB_8822B(__tx_desc) GET_TX_DESC_DISDATAFB(__tx_desc)
+#define SET_TX_DESC_DISRTSFB_8822B(__tx_desc, __value) \
+ SET_TX_DESC_DISRTSFB(__tx_desc, __value)
+#define GET_TX_DESC_DISRTSFB_8822B(__tx_desc) GET_TX_DESC_DISRTSFB(__tx_desc)
+#define SET_TX_DESC_USE_RATE_8822B(__tx_desc, __value) \
+ SET_TX_DESC_USE_RATE(__tx_desc, __value)
+#define GET_TX_DESC_USE_RATE_8822B(__tx_desc) GET_TX_DESC_USE_RATE(__tx_desc)
+#define SET_TX_DESC_HW_SSN_SEL_8822B(__tx_desc, __value) \
+ SET_TX_DESC_HW_SSN_SEL(__tx_desc, __value)
+#define GET_TX_DESC_HW_SSN_SEL_8822B(__tx_desc) \
+ GET_TX_DESC_HW_SSN_SEL(__tx_desc)
+#define SET_TX_DESC_WHEADER_LEN_8822B(__tx_desc, __value) \
+ SET_TX_DESC_WHEADER_LEN(__tx_desc, __value)
+#define GET_TX_DESC_WHEADER_LEN_8822B(__tx_desc) \
+ GET_TX_DESC_WHEADER_LEN(__tx_desc)
+
+/*TXDESC_WORD4*/
+
+#define SET_TX_DESC_PCTS_MASK_IDX_8822B(__tx_desc, __value) \
+ SET_TX_DESC_PCTS_MASK_IDX(__tx_desc, __value)
+#define GET_TX_DESC_PCTS_MASK_IDX_8822B(__tx_desc) \
+ GET_TX_DESC_PCTS_MASK_IDX(__tx_desc)
+#define SET_TX_DESC_PCTS_EN_8822B(__tx_desc, __value) \
+ SET_TX_DESC_PCTS_EN(__tx_desc, __value)
+#define GET_TX_DESC_PCTS_EN_8822B(__tx_desc) GET_TX_DESC_PCTS_EN(__tx_desc)
+#define SET_TX_DESC_RTSRATE_8822B(__tx_desc, __value) \
+ SET_TX_DESC_RTSRATE(__tx_desc, __value)
+#define GET_TX_DESC_RTSRATE_8822B(__tx_desc) GET_TX_DESC_RTSRATE(__tx_desc)
+#define SET_TX_DESC_RTS_DATA_RTY_LMT_8822B(__tx_desc, __value) \
+ SET_TX_DESC_RTS_DATA_RTY_LMT(__tx_desc, __value)
+#define GET_TX_DESC_RTS_DATA_RTY_LMT_8822B(__tx_desc) \
+ GET_TX_DESC_RTS_DATA_RTY_LMT(__tx_desc)
+#define SET_TX_DESC_RTY_LMT_EN_8822B(__tx_desc, __value) \
+ SET_TX_DESC_RTY_LMT_EN(__tx_desc, __value)
+#define GET_TX_DESC_RTY_LMT_EN_8822B(__tx_desc) \
+ GET_TX_DESC_RTY_LMT_EN(__tx_desc)
+#define SET_TX_DESC_RTS_RTY_LOWEST_RATE_8822B(__tx_desc, __value) \
+ SET_TX_DESC_RTS_RTY_LOWEST_RATE(__tx_desc, __value)
+#define GET_TX_DESC_RTS_RTY_LOWEST_RATE_8822B(__tx_desc) \
+ GET_TX_DESC_RTS_RTY_LOWEST_RATE(__tx_desc)
+#define SET_TX_DESC_DATA_RTY_LOWEST_RATE_8822B(__tx_desc, __value) \
+ SET_TX_DESC_DATA_RTY_LOWEST_RATE(__tx_desc, __value)
+#define GET_TX_DESC_DATA_RTY_LOWEST_RATE_8822B(__tx_desc) \
+ GET_TX_DESC_DATA_RTY_LOWEST_RATE(__tx_desc)
+#define SET_TX_DESC_TRY_RATE_8822B(__tx_desc, __value) \
+ SET_TX_DESC_TRY_RATE(__tx_desc, __value)
+#define GET_TX_DESC_TRY_RATE_8822B(__tx_desc) GET_TX_DESC_TRY_RATE(__tx_desc)
+#define SET_TX_DESC_DATARATE_8822B(__tx_desc, __value) \
+ SET_TX_DESC_DATARATE(__tx_desc, __value)
+#define GET_TX_DESC_DATARATE_8822B(__tx_desc) GET_TX_DESC_DATARATE(__tx_desc)
+
+/*TXDESC_WORD5*/
+
+#define SET_TX_DESC_POLLUTED_8822B(__tx_desc, __value) \
+ SET_TX_DESC_POLLUTED(__tx_desc, __value)
+#define GET_TX_DESC_POLLUTED_8822B(__tx_desc) GET_TX_DESC_POLLUTED(__tx_desc)
+#define SET_TX_DESC_TXPWR_OFSET_8822B(__tx_desc, __value) \
+ SET_TX_DESC_TXPWR_OFSET(__tx_desc, __value)
+#define GET_TX_DESC_TXPWR_OFSET_8822B(__tx_desc) \
+ GET_TX_DESC_TXPWR_OFSET(__tx_desc)
+#define SET_TX_DESC_TX_ANT_8822B(__tx_desc, __value) \
+ SET_TX_DESC_TX_ANT(__tx_desc, __value)
+#define GET_TX_DESC_TX_ANT_8822B(__tx_desc) GET_TX_DESC_TX_ANT(__tx_desc)
+#define SET_TX_DESC_PORT_ID_8822B(__tx_desc, __value) \
+ SET_TX_DESC_PORT_ID(__tx_desc, __value)
+#define GET_TX_DESC_PORT_ID_8822B(__tx_desc) GET_TX_DESC_PORT_ID(__tx_desc)
+#define SET_TX_DESC_MULTIPLE_PORT_8822B(__tx_desc, __value) \
+ SET_TX_DESC_MULTIPLE_PORT(__tx_desc, __value)
+#define GET_TX_DESC_MULTIPLE_PORT_8822B(__tx_desc) \
+ GET_TX_DESC_MULTIPLE_PORT(__tx_desc)
+#define SET_TX_DESC_SIGNALING_TAPKT_EN_8822B(__tx_desc, __value) \
+ SET_TX_DESC_SIGNALING_TAPKT_EN(__tx_desc, __value)
+#define GET_TX_DESC_SIGNALING_TAPKT_EN_8822B(__tx_desc) \
+ GET_TX_DESC_SIGNALING_TAPKT_EN(__tx_desc)
+#define SET_TX_DESC_RTS_SC_8822B(__tx_desc, __value) \
+ SET_TX_DESC_RTS_SC(__tx_desc, __value)
+#define GET_TX_DESC_RTS_SC_8822B(__tx_desc) GET_TX_DESC_RTS_SC(__tx_desc)
+#define SET_TX_DESC_RTS_SHORT_8822B(__tx_desc, __value) \
+ SET_TX_DESC_RTS_SHORT(__tx_desc, __value)
+#define GET_TX_DESC_RTS_SHORT_8822B(__tx_desc) GET_TX_DESC_RTS_SHORT(__tx_desc)
+#define SET_TX_DESC_VCS_STBC_8822B(__tx_desc, __value) \
+ SET_TX_DESC_VCS_STBC(__tx_desc, __value)
+#define GET_TX_DESC_VCS_STBC_8822B(__tx_desc) GET_TX_DESC_VCS_STBC(__tx_desc)
+#define SET_TX_DESC_DATA_STBC_8822B(__tx_desc, __value) \
+ SET_TX_DESC_DATA_STBC(__tx_desc, __value)
+#define GET_TX_DESC_DATA_STBC_8822B(__tx_desc) GET_TX_DESC_DATA_STBC(__tx_desc)
+#define SET_TX_DESC_DATA_LDPC_8822B(__tx_desc, __value) \
+ SET_TX_DESC_DATA_LDPC(__tx_desc, __value)
+#define GET_TX_DESC_DATA_LDPC_8822B(__tx_desc) GET_TX_DESC_DATA_LDPC(__tx_desc)
+#define SET_TX_DESC_DATA_BW_8822B(__tx_desc, __value) \
+ SET_TX_DESC_DATA_BW(__tx_desc, __value)
+#define GET_TX_DESC_DATA_BW_8822B(__tx_desc) GET_TX_DESC_DATA_BW(__tx_desc)
+#define SET_TX_DESC_DATA_SHORT_8822B(__tx_desc, __value) \
+ SET_TX_DESC_DATA_SHORT(__tx_desc, __value)
+#define GET_TX_DESC_DATA_SHORT_8822B(__tx_desc) \
+ GET_TX_DESC_DATA_SHORT(__tx_desc)
+#define SET_TX_DESC_DATA_SC_8822B(__tx_desc, __value) \
+ SET_TX_DESC_DATA_SC(__tx_desc, __value)
+#define GET_TX_DESC_DATA_SC_8822B(__tx_desc) GET_TX_DESC_DATA_SC(__tx_desc)
+
+/*TXDESC_WORD6*/
+
+#define SET_TX_DESC_ANTSEL_D_8822B(__tx_desc, __value) \
+ SET_TX_DESC_ANTSEL_D(__tx_desc, __value)
+#define GET_TX_DESC_ANTSEL_D_8822B(__tx_desc) GET_TX_DESC_ANTSEL_D(__tx_desc)
+#define SET_TX_DESC_ANT_MAPD_8822B(__tx_desc, __value) \
+ SET_TX_DESC_ANT_MAPD(__tx_desc, __value)
+#define GET_TX_DESC_ANT_MAPD_8822B(__tx_desc) GET_TX_DESC_ANT_MAPD(__tx_desc)
+#define SET_TX_DESC_ANT_MAPC_8822B(__tx_desc, __value) \
+ SET_TX_DESC_ANT_MAPC(__tx_desc, __value)
+#define GET_TX_DESC_ANT_MAPC_8822B(__tx_desc) GET_TX_DESC_ANT_MAPC(__tx_desc)
+#define SET_TX_DESC_ANT_MAPB_8822B(__tx_desc, __value) \
+ SET_TX_DESC_ANT_MAPB(__tx_desc, __value)
+#define GET_TX_DESC_ANT_MAPB_8822B(__tx_desc) GET_TX_DESC_ANT_MAPB(__tx_desc)
+#define SET_TX_DESC_ANT_MAPA_8822B(__tx_desc, __value) \
+ SET_TX_DESC_ANT_MAPA(__tx_desc, __value)
+#define GET_TX_DESC_ANT_MAPA_8822B(__tx_desc) GET_TX_DESC_ANT_MAPA(__tx_desc)
+#define SET_TX_DESC_ANTSEL_C_8822B(__tx_desc, __value) \
+ SET_TX_DESC_ANTSEL_C(__tx_desc, __value)
+#define GET_TX_DESC_ANTSEL_C_8822B(__tx_desc) GET_TX_DESC_ANTSEL_C(__tx_desc)
+#define SET_TX_DESC_ANTSEL_B_8822B(__tx_desc, __value) \
+ SET_TX_DESC_ANTSEL_B(__tx_desc, __value)
+#define GET_TX_DESC_ANTSEL_B_8822B(__tx_desc) GET_TX_DESC_ANTSEL_B(__tx_desc)
+#define SET_TX_DESC_ANTSEL_A_8822B(__tx_desc, __value) \
+ SET_TX_DESC_ANTSEL_A(__tx_desc, __value)
+#define GET_TX_DESC_ANTSEL_A_8822B(__tx_desc) GET_TX_DESC_ANTSEL_A(__tx_desc)
+#define SET_TX_DESC_MBSSID_8822B(__tx_desc, __value) \
+ SET_TX_DESC_MBSSID(__tx_desc, __value)
+#define GET_TX_DESC_MBSSID_8822B(__tx_desc) GET_TX_DESC_MBSSID(__tx_desc)
+#define SET_TX_DESC_SW_DEFINE_8822B(__tx_desc, __value) \
+ SET_TX_DESC_SW_DEFINE(__tx_desc, __value)
+#define GET_TX_DESC_SW_DEFINE_8822B(__tx_desc) GET_TX_DESC_SW_DEFINE(__tx_desc)
+
+/*TXDESC_WORD7*/
+
+#define SET_TX_DESC_DMA_TXAGG_NUM_8822B(__tx_desc, __value) \
+ SET_TX_DESC_DMA_TXAGG_NUM(__tx_desc, __value)
+#define GET_TX_DESC_DMA_TXAGG_NUM_8822B(__tx_desc) \
+ GET_TX_DESC_DMA_TXAGG_NUM(__tx_desc)
+#define SET_TX_DESC_FINAL_DATA_RATE_8822B(__tx_desc, __value) \
+ SET_TX_DESC_FINAL_DATA_RATE(__tx_desc, __value)
+#define GET_TX_DESC_FINAL_DATA_RATE_8822B(__tx_desc) \
+ GET_TX_DESC_FINAL_DATA_RATE(__tx_desc)
+#define SET_TX_DESC_NTX_MAP_8822B(__tx_desc, __value) \
+ SET_TX_DESC_NTX_MAP(__tx_desc, __value)
+#define GET_TX_DESC_NTX_MAP_8822B(__tx_desc) GET_TX_DESC_NTX_MAP(__tx_desc)
+#define SET_TX_DESC_TX_BUFF_SIZE_8822B(__tx_desc, __value) \
+ SET_TX_DESC_TX_BUFF_SIZE(__tx_desc, __value)
+#define GET_TX_DESC_TX_BUFF_SIZE_8822B(__tx_desc) \
+ GET_TX_DESC_TX_BUFF_SIZE(__tx_desc)
+#define SET_TX_DESC_TXDESC_CHECKSUM_8822B(__tx_desc, __value) \
+ SET_TX_DESC_TXDESC_CHECKSUM(__tx_desc, __value)
+#define GET_TX_DESC_TXDESC_CHECKSUM_8822B(__tx_desc) \
+ GET_TX_DESC_TXDESC_CHECKSUM(__tx_desc)
+#define SET_TX_DESC_TIMESTAMP_8822B(__tx_desc, __value) \
+ SET_TX_DESC_TIMESTAMP(__tx_desc, __value)
+#define GET_TX_DESC_TIMESTAMP_8822B(__tx_desc) GET_TX_DESC_TIMESTAMP(__tx_desc)
+
+/*TXDESC_WORD8*/
+
+#define SET_TX_DESC_TXWIFI_CP_8822B(__tx_desc, __value) \
+ SET_TX_DESC_TXWIFI_CP(__tx_desc, __value)
+#define GET_TX_DESC_TXWIFI_CP_8822B(__tx_desc) GET_TX_DESC_TXWIFI_CP(__tx_desc)
+#define SET_TX_DESC_MAC_CP_8822B(__tx_desc, __value) \
+ SET_TX_DESC_MAC_CP(__tx_desc, __value)
+#define GET_TX_DESC_MAC_CP_8822B(__tx_desc) GET_TX_DESC_MAC_CP(__tx_desc)
+#define SET_TX_DESC_STW_PKTRE_DIS_8822B(__tx_desc, __value) \
+ SET_TX_DESC_STW_PKTRE_DIS(__tx_desc, __value)
+#define GET_TX_DESC_STW_PKTRE_DIS_8822B(__tx_desc) \
+ GET_TX_DESC_STW_PKTRE_DIS(__tx_desc)
+#define SET_TX_DESC_STW_RB_DIS_8822B(__tx_desc, __value) \
+ SET_TX_DESC_STW_RB_DIS(__tx_desc, __value)
+#define GET_TX_DESC_STW_RB_DIS_8822B(__tx_desc) \
+ GET_TX_DESC_STW_RB_DIS(__tx_desc)
+#define SET_TX_DESC_STW_RATE_DIS_8822B(__tx_desc, __value) \
+ SET_TX_DESC_STW_RATE_DIS(__tx_desc, __value)
+#define GET_TX_DESC_STW_RATE_DIS_8822B(__tx_desc) \
+ GET_TX_DESC_STW_RATE_DIS(__tx_desc)
+#define SET_TX_DESC_STW_ANT_DIS_8822B(__tx_desc, __value) \
+ SET_TX_DESC_STW_ANT_DIS(__tx_desc, __value)
+#define GET_TX_DESC_STW_ANT_DIS_8822B(__tx_desc) \
+ GET_TX_DESC_STW_ANT_DIS(__tx_desc)
+#define SET_TX_DESC_STW_EN_8822B(__tx_desc, __value) \
+ SET_TX_DESC_STW_EN(__tx_desc, __value)
+#define GET_TX_DESC_STW_EN_8822B(__tx_desc) GET_TX_DESC_STW_EN(__tx_desc)
+#define SET_TX_DESC_SMH_EN_8822B(__tx_desc, __value) \
+ SET_TX_DESC_SMH_EN(__tx_desc, __value)
+#define GET_TX_DESC_SMH_EN_8822B(__tx_desc) GET_TX_DESC_SMH_EN(__tx_desc)
+#define SET_TX_DESC_TAILPAGE_L_8822B(__tx_desc, __value) \
+ SET_TX_DESC_TAILPAGE_L(__tx_desc, __value)
+#define GET_TX_DESC_TAILPAGE_L_8822B(__tx_desc) \
+ GET_TX_DESC_TAILPAGE_L(__tx_desc)
+#define SET_TX_DESC_SDIO_DMASEQ_8822B(__tx_desc, __value) \
+ SET_TX_DESC_SDIO_DMASEQ(__tx_desc, __value)
+#define GET_TX_DESC_SDIO_DMASEQ_8822B(__tx_desc) \
+ GET_TX_DESC_SDIO_DMASEQ(__tx_desc)
+#define SET_TX_DESC_NEXTHEADPAGE_L_8822B(__tx_desc, __value) \
+ SET_TX_DESC_NEXTHEADPAGE_L(__tx_desc, __value)
+#define GET_TX_DESC_NEXTHEADPAGE_L_8822B(__tx_desc) \
+ GET_TX_DESC_NEXTHEADPAGE_L(__tx_desc)
+#define SET_TX_DESC_EN_HWSEQ_8822B(__tx_desc, __value) \
+ SET_TX_DESC_EN_HWSEQ(__tx_desc, __value)
+#define GET_TX_DESC_EN_HWSEQ_8822B(__tx_desc) GET_TX_DESC_EN_HWSEQ(__tx_desc)
+#define SET_TX_DESC_EN_HWEXSEQ_8822B(__tx_desc, __value) \
+ SET_TX_DESC_EN_HWEXSEQ(__tx_desc, __value)
+#define GET_TX_DESC_EN_HWEXSEQ_8822B(__tx_desc) \
+ GET_TX_DESC_EN_HWEXSEQ(__tx_desc)
+#define SET_TX_DESC_DATA_RC_8822B(__tx_desc, __value) \
+ SET_TX_DESC_DATA_RC(__tx_desc, __value)
+#define GET_TX_DESC_DATA_RC_8822B(__tx_desc) GET_TX_DESC_DATA_RC(__tx_desc)
+#define SET_TX_DESC_BAR_RTY_TH_8822B(__tx_desc, __value) \
+ SET_TX_DESC_BAR_RTY_TH(__tx_desc, __value)
+#define GET_TX_DESC_BAR_RTY_TH_8822B(__tx_desc) \
+ GET_TX_DESC_BAR_RTY_TH(__tx_desc)
+#define SET_TX_DESC_RTS_RC_8822B(__tx_desc, __value) \
+ SET_TX_DESC_RTS_RC(__tx_desc, __value)
+#define GET_TX_DESC_RTS_RC_8822B(__tx_desc) GET_TX_DESC_RTS_RC(__tx_desc)
+
+/*TXDESC_WORD9*/
+
+#define SET_TX_DESC_TAILPAGE_H_8822B(__tx_desc, __value) \
+ SET_TX_DESC_TAILPAGE_H(__tx_desc, __value)
+#define GET_TX_DESC_TAILPAGE_H_8822B(__tx_desc) \
+ GET_TX_DESC_TAILPAGE_H(__tx_desc)
+#define SET_TX_DESC_NEXTHEADPAGE_H_8822B(__tx_desc, __value) \
+ SET_TX_DESC_NEXTHEADPAGE_H(__tx_desc, __value)
+#define GET_TX_DESC_NEXTHEADPAGE_H_8822B(__tx_desc) \
+ GET_TX_DESC_NEXTHEADPAGE_H(__tx_desc)
+#define SET_TX_DESC_SW_SEQ_8822B(__tx_desc, __value) \
+ SET_TX_DESC_SW_SEQ(__tx_desc, __value)
+#define GET_TX_DESC_SW_SEQ_8822B(__tx_desc) GET_TX_DESC_SW_SEQ(__tx_desc)
+#define SET_TX_DESC_TXBF_PATH_8822B(__tx_desc, __value) \
+ SET_TX_DESC_TXBF_PATH(__tx_desc, __value)
+#define GET_TX_DESC_TXBF_PATH_8822B(__tx_desc) GET_TX_DESC_TXBF_PATH(__tx_desc)
+#define SET_TX_DESC_PADDING_LEN_8822B(__tx_desc, __value) \
+ SET_TX_DESC_PADDING_LEN(__tx_desc, __value)
+#define GET_TX_DESC_PADDING_LEN_8822B(__tx_desc) \
+ GET_TX_DESC_PADDING_LEN(__tx_desc)
+#define SET_TX_DESC_GROUP_BIT_IE_OFFSET_8822B(__tx_desc, __value) \
+ SET_TX_DESC_GROUP_BIT_IE_OFFSET(__tx_desc, __value)
+#define GET_TX_DESC_GROUP_BIT_IE_OFFSET_8822B(__tx_desc) \
+ GET_TX_DESC_GROUP_BIT_IE_OFFSET(__tx_desc)
+
+/*WORD10*/
+
+#define SET_TX_DESC_MU_DATARATE_8822B(__tx_desc, __value) \
+ SET_TX_DESC_MU_DATARATE(__tx_desc, __value)
+#define GET_TX_DESC_MU_DATARATE_8822B(__tx_desc) \
+ GET_TX_DESC_MU_DATARATE(__tx_desc)
+#define SET_TX_DESC_MU_RC_8822B(__tx_desc, __value) \
+ SET_TX_DESC_MU_RC(__tx_desc, __value)
+#define GET_TX_DESC_MU_RC_8822B(__tx_desc) GET_TX_DESC_MU_RC(__tx_desc)
+#define SET_TX_DESC_SND_PKT_SEL_8822B(__tx_desc, __value) \
+ SET_TX_DESC_SND_PKT_SEL(__tx_desc, __value)
+#define GET_TX_DESC_SND_PKT_SEL_8822B(__tx_desc) \
+ GET_TX_DESC_SND_PKT_SEL(__tx_desc)
+
+#endif
diff --git a/drivers/staging/rtlwifi/halmac/halmac_tx_desc_nic.h b/drivers/staging/rtlwifi/halmac/halmac_tx_desc_nic.h
new file mode 100644
index 0000000..02177c5
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_tx_desc_nic.h
@@ -0,0 +1,506 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HALMAC_TX_DESC_NIC_H_
+#define _HALMAC_TX_DESC_NIC_H_
+
+/*TXDESC_WORD0*/
+
+#define SET_TX_DESC_DISQSELSEQ(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x00, 31, 1, __value)
+#define GET_TX_DESC_DISQSELSEQ(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x00, 31, 1)
+
+#define SET_TX_DESC_GF(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x00, 30, 1, __value)
+#define GET_TX_DESC_GF(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x00, 30, 1)
+#define SET_TX_DESC_NO_ACM(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x00, 29, 1, __value)
+#define GET_TX_DESC_NO_ACM(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x00, 29, 1)
+
+#define SET_TX_DESC_BCNPKT_TSF_CTRL(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x00, 28, 1, __value)
+#define GET_TX_DESC_BCNPKT_TSF_CTRL(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x00, 28, 1)
+
+#define SET_TX_DESC_AMSDU_PAD_EN(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x00, 27, 1, __value)
+#define GET_TX_DESC_AMSDU_PAD_EN(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x00, 27, 1)
+
+#define SET_TX_DESC_LS(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x00, 26, 1, __value)
+#define GET_TX_DESC_LS(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x00, 26, 1)
+#define SET_TX_DESC_HTC(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x00, 25, 1, __value)
+#define GET_TX_DESC_HTC(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x00, 25, 1)
+#define SET_TX_DESC_BMC(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x00, 24, 1, __value)
+#define GET_TX_DESC_BMC(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x00, 24, 1)
+#define SET_TX_DESC_OFFSET(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x00, 16, 8, __value)
+#define GET_TX_DESC_OFFSET(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x00, 16, 8)
+#define SET_TX_DESC_TXPKTSIZE(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x00, 0, 16, __value)
+#define GET_TX_DESC_TXPKTSIZE(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x00, 0, 16)
+
+/*TXDESC_WORD1*/
+
+#define SET_TX_DESC_MOREDATA(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x04, 29, 1, __value)
+#define GET_TX_DESC_MOREDATA(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x04, 29, 1)
+#define SET_TX_DESC_PKT_OFFSET(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x04, 24, 5, __value)
+#define GET_TX_DESC_PKT_OFFSET(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x04, 24, 5)
+#define SET_TX_DESC_SEC_TYPE(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x04, 22, 2, __value)
+#define GET_TX_DESC_SEC_TYPE(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x04, 22, 2)
+#define SET_TX_DESC_EN_DESC_ID(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x04, 21, 1, __value)
+#define GET_TX_DESC_EN_DESC_ID(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x04, 21, 1)
+#define SET_TX_DESC_RATE_ID(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x04, 16, 5, __value)
+#define GET_TX_DESC_RATE_ID(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x04, 16, 5)
+#define SET_TX_DESC_PIFS(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x04, 15, 1, __value)
+#define GET_TX_DESC_PIFS(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x04, 15, 1)
+#define SET_TX_DESC_LSIG_TXOP_EN(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x04, 14, 1, __value)
+#define GET_TX_DESC_LSIG_TXOP_EN(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x04, 14, 1)
+#define SET_TX_DESC_RD_NAV_EXT(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x04, 13, 1, __value)
+#define GET_TX_DESC_RD_NAV_EXT(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x04, 13, 1)
+#define SET_TX_DESC_QSEL(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x04, 8, 5, __value)
+#define GET_TX_DESC_QSEL(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x04, 8, 5)
+#define SET_TX_DESC_MACID(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x04, 0, 7, __value)
+#define GET_TX_DESC_MACID(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x04, 0, 7)
+
+/*TXDESC_WORD2*/
+
+#define SET_TX_DESC_HW_AES_IV(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x08, 31, 1, __value)
+#define GET_TX_DESC_HW_AES_IV(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x08, 31, 1)
+
+#define SET_TX_DESC_FTM_EN(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x08, 30, 1, __value)
+#define GET_TX_DESC_FTM_EN(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x08, 30, 1)
+
+#define SET_TX_DESC_G_ID(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x08, 24, 6, __value)
+#define GET_TX_DESC_G_ID(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x08, 24, 6)
+#define SET_TX_DESC_BT_NULL(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x08, 23, 1, __value)
+#define GET_TX_DESC_BT_NULL(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x08, 23, 1)
+#define SET_TX_DESC_AMPDU_DENSITY(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x08, 20, 3, __value)
+#define GET_TX_DESC_AMPDU_DENSITY(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x08, 20, 3)
+#ifdef SET_TX_DESC_SPE_RPT
+#undef SET_TX_DESC_SPE_RPT
+#endif
+#define SET_TX_DESC_SPE_RPT(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x08, 19, 1, __value)
+#define GET_TX_DESC_SPE_RPT(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x08, 19, 1)
+#define SET_TX_DESC_RAW(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x08, 18, 1, __value)
+#define GET_TX_DESC_RAW(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x08, 18, 1)
+#define SET_TX_DESC_MOREFRAG(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x08, 17, 1, __value)
+#define GET_TX_DESC_MOREFRAG(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x08, 17, 1)
+#define SET_TX_DESC_BK(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x08, 16, 1, __value)
+#define GET_TX_DESC_BK(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x08, 16, 1)
+#define SET_TX_DESC_NULL_1(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x08, 15, 1, __value)
+#define GET_TX_DESC_NULL_1(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x08, 15, 1)
+#define SET_TX_DESC_NULL_0(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x08, 14, 1, __value)
+#define GET_TX_DESC_NULL_0(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x08, 14, 1)
+#define SET_TX_DESC_RDG_EN(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x08, 13, 1, __value)
+#define GET_TX_DESC_RDG_EN(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x08, 13, 1)
+#define SET_TX_DESC_AGG_EN(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x08, 12, 1, __value)
+#define GET_TX_DESC_AGG_EN(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x08, 12, 1)
+#define SET_TX_DESC_CCA_RTS(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x08, 10, 2, __value)
+#define GET_TX_DESC_CCA_RTS(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x08, 10, 2)
+
+#define SET_TX_DESC_TRI_FRAME(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x08, 9, 1, __value)
+#define GET_TX_DESC_TRI_FRAME(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x08, 9, 1)
+
+#define SET_TX_DESC_P_AID(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x08, 0, 9, __value)
+#define GET_TX_DESC_P_AID(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x08, 0, 9)
+
+/*TXDESC_WORD3*/
+
+#define SET_TX_DESC_AMPDU_MAX_TIME(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x0C, 24, 8, __value)
+#define GET_TX_DESC_AMPDU_MAX_TIME(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x0C, 24, 8)
+#define SET_TX_DESC_NDPA(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x0C, 22, 2, __value)
+#define GET_TX_DESC_NDPA(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x0C, 22, 2)
+#define SET_TX_DESC_MAX_AGG_NUM(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x0C, 17, 5, __value)
+#define GET_TX_DESC_MAX_AGG_NUM(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x0C, 17, 5)
+#define SET_TX_DESC_USE_MAX_TIME_EN(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x0C, 16, 1, __value)
+#define GET_TX_DESC_USE_MAX_TIME_EN(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x0C, 16, 1)
+#define SET_TX_DESC_NAVUSEHDR(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x0C, 15, 1, __value)
+#define GET_TX_DESC_NAVUSEHDR(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x0C, 15, 1)
+
+#define SET_TX_DESC_CHK_EN(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x0C, 14, 1, __value)
+#define GET_TX_DESC_CHK_EN(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x0C, 14, 1)
+
+#define SET_TX_DESC_HW_RTS_EN(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x0C, 13, 1, __value)
+#define GET_TX_DESC_HW_RTS_EN(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x0C, 13, 1)
+#define SET_TX_DESC_RTSEN(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x0C, 12, 1, __value)
+#define GET_TX_DESC_RTSEN(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x0C, 12, 1)
+#define SET_TX_DESC_CTS2SELF(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x0C, 11, 1, __value)
+#define GET_TX_DESC_CTS2SELF(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x0C, 11, 1)
+#define SET_TX_DESC_DISDATAFB(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x0C, 10, 1, __value)
+#define GET_TX_DESC_DISDATAFB(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x0C, 10, 1)
+#define SET_TX_DESC_DISRTSFB(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x0C, 9, 1, __value)
+#define GET_TX_DESC_DISRTSFB(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x0C, 9, 1)
+#define SET_TX_DESC_USE_RATE(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x0C, 8, 1, __value)
+#define GET_TX_DESC_USE_RATE(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x0C, 8, 1)
+#define SET_TX_DESC_HW_SSN_SEL(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x0C, 6, 2, __value)
+#define GET_TX_DESC_HW_SSN_SEL(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x0C, 6, 2)
+
+#define SET_TX_DESC_WHEADER_LEN(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x0C, 0, 5, __value)
+#define GET_TX_DESC_WHEADER_LEN(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x0C, 0, 5)
+
+/*TXDESC_WORD4*/
+
+#define SET_TX_DESC_PCTS_MASK_IDX(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x10, 30, 2, __value)
+#define GET_TX_DESC_PCTS_MASK_IDX(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x10, 30, 2)
+#define SET_TX_DESC_PCTS_EN(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x10, 29, 1, __value)
+#define GET_TX_DESC_PCTS_EN(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x10, 29, 1)
+#define SET_TX_DESC_RTSRATE(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x10, 24, 5, __value)
+#define GET_TX_DESC_RTSRATE(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x10, 24, 5)
+#define SET_TX_DESC_RTS_DATA_RTY_LMT(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x10, 18, 6, __value)
+#define GET_TX_DESC_RTS_DATA_RTY_LMT(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x10, 18, 6)
+#define SET_TX_DESC_RTY_LMT_EN(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x10, 17, 1, __value)
+#define GET_TX_DESC_RTY_LMT_EN(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x10, 17, 1)
+#define SET_TX_DESC_RTS_RTY_LOWEST_RATE(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x10, 13, 4, __value)
+#define GET_TX_DESC_RTS_RTY_LOWEST_RATE(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x10, 13, 4)
+#define SET_TX_DESC_DATA_RTY_LOWEST_RATE(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x10, 8, 5, __value)
+#define GET_TX_DESC_DATA_RTY_LOWEST_RATE(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x10, 8, 5)
+#define SET_TX_DESC_TRY_RATE(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x10, 7, 1, __value)
+#define GET_TX_DESC_TRY_RATE(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x10, 7, 1)
+#define SET_TX_DESC_DATARATE(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x10, 0, 7, __value)
+#define GET_TX_DESC_DATARATE(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x10, 0, 7)
+
+/*TXDESC_WORD5*/
+
+#define SET_TX_DESC_POLLUTED(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x14, 31, 1, __value)
+#define GET_TX_DESC_POLLUTED(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x14, 31, 1)
+
+#define SET_TX_DESC_TXPWR_OFSET(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x14, 28, 3, __value)
+#define GET_TX_DESC_TXPWR_OFSET(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x14, 28, 3)
+#define SET_TX_DESC_TX_ANT(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x14, 24, 4, __value)
+#define GET_TX_DESC_TX_ANT(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x14, 24, 4)
+#define SET_TX_DESC_PORT_ID(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x14, 21, 3, __value)
+#define GET_TX_DESC_PORT_ID(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x14, 21, 3)
+
+#define SET_TX_DESC_MULTIPLE_PORT(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x14, 18, 3, __value)
+#define GET_TX_DESC_MULTIPLE_PORT(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x14, 18, 3)
+
+#define SET_TX_DESC_SIGNALING_TAPKT_EN(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x14, 17, 1, __value)
+#define GET_TX_DESC_SIGNALING_TAPKT_EN(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x14, 17, 1)
+
+#define SET_TX_DESC_RTS_SC(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x14, 13, 4, __value)
+#define GET_TX_DESC_RTS_SC(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x14, 13, 4)
+#define SET_TX_DESC_RTS_SHORT(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x14, 12, 1, __value)
+#define GET_TX_DESC_RTS_SHORT(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x14, 12, 1)
+
+#define SET_TX_DESC_VCS_STBC(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x14, 10, 2, __value)
+#define GET_TX_DESC_VCS_STBC(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x14, 10, 2)
+
+#define SET_TX_DESC_DATA_STBC(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x14, 8, 2, __value)
+#define GET_TX_DESC_DATA_STBC(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x14, 8, 2)
+
+#define SET_TX_DESC_DATA_LDPC(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x14, 7, 1, __value)
+#define GET_TX_DESC_DATA_LDPC(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x14, 7, 1)
+
+#define SET_TX_DESC_DATA_BW(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x14, 5, 2, __value)
+#define GET_TX_DESC_DATA_BW(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x14, 5, 2)
+#define SET_TX_DESC_DATA_SHORT(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x14, 4, 1, __value)
+#define GET_TX_DESC_DATA_SHORT(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x14, 4, 1)
+#define SET_TX_DESC_DATA_SC(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x14, 0, 4, __value)
+#define GET_TX_DESC_DATA_SC(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x14, 0, 4)
+
+/*TXDESC_WORD6*/
+
+#define SET_TX_DESC_ANTSEL_D(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x18, 30, 2, __value)
+#define GET_TX_DESC_ANTSEL_D(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x18, 30, 2)
+#define SET_TX_DESC_ANT_MAPD(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x18, 28, 2, __value)
+#define GET_TX_DESC_ANT_MAPD(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x18, 28, 2)
+#define SET_TX_DESC_ANT_MAPC(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x18, 26, 2, __value)
+#define GET_TX_DESC_ANT_MAPC(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x18, 26, 2)
+#define SET_TX_DESC_ANT_MAPB(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x18, 24, 2, __value)
+#define GET_TX_DESC_ANT_MAPB(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x18, 24, 2)
+#define SET_TX_DESC_ANT_MAPA(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x18, 22, 2, __value)
+#define GET_TX_DESC_ANT_MAPA(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x18, 22, 2)
+#define SET_TX_DESC_ANTSEL_C(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x18, 20, 2, __value)
+#define GET_TX_DESC_ANTSEL_C(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x18, 20, 2)
+#define SET_TX_DESC_ANTSEL_B(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x18, 18, 2, __value)
+#define GET_TX_DESC_ANTSEL_B(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x18, 18, 2)
+
+#define SET_TX_DESC_ANTSEL_A(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x18, 16, 2, __value)
+#define GET_TX_DESC_ANTSEL_A(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x18, 16, 2)
+#define SET_TX_DESC_MBSSID(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x18, 12, 4, __value)
+#define GET_TX_DESC_MBSSID(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x18, 12, 4)
+#ifdef SET_TX_DESC_SW_DEFINE
+#undef SET_TX_DESC_SW_DEFINE
+#endif
+#define SET_TX_DESC_SW_DEFINE(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x18, 0, 12, __value)
+#define GET_TX_DESC_SW_DEFINE(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x18, 0, 12)
+
+/*TXDESC_WORD7*/
+
+#define SET_TX_DESC_DMA_TXAGG_NUM(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x1C, 24, 8, __value)
+#define GET_TX_DESC_DMA_TXAGG_NUM(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x1C, 24, 8)
+
+#define SET_TX_DESC_FINAL_DATA_RATE(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x1C, 24, 8, __value)
+#define GET_TX_DESC_FINAL_DATA_RATE(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x1C, 24, 8)
+#define SET_TX_DESC_NTX_MAP(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x1C, 20, 4, __value)
+#define GET_TX_DESC_NTX_MAP(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x1C, 20, 4)
+
+#define SET_TX_DESC_TX_BUFF_SIZE(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x1C, 0, 16, __value)
+#define GET_TX_DESC_TX_BUFF_SIZE(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x1C, 0, 16)
+#define SET_TX_DESC_TXDESC_CHECKSUM(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x1C, 0, 16, __value)
+#define GET_TX_DESC_TXDESC_CHECKSUM(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x1C, 0, 16)
+#define SET_TX_DESC_TIMESTAMP(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x1C, 0, 16, __value)
+#define GET_TX_DESC_TIMESTAMP(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x1C, 0, 16)
+
+/*TXDESC_WORD8*/
+
+#define SET_TX_DESC_TXWIFI_CP(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x20, 31, 1, __value)
+#define GET_TX_DESC_TXWIFI_CP(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x20, 31, 1)
+#define SET_TX_DESC_MAC_CP(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x20, 30, 1, __value)
+#define GET_TX_DESC_MAC_CP(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x20, 30, 1)
+#define SET_TX_DESC_STW_PKTRE_DIS(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x20, 29, 1, __value)
+#define GET_TX_DESC_STW_PKTRE_DIS(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x20, 29, 1)
+#define SET_TX_DESC_STW_RB_DIS(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x20, 28, 1, __value)
+#define GET_TX_DESC_STW_RB_DIS(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x20, 28, 1)
+#define SET_TX_DESC_STW_RATE_DIS(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x20, 27, 1, __value)
+#define GET_TX_DESC_STW_RATE_DIS(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x20, 27, 1)
+#define SET_TX_DESC_STW_ANT_DIS(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x20, 26, 1, __value)
+#define GET_TX_DESC_STW_ANT_DIS(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x20, 26, 1)
+#define SET_TX_DESC_STW_EN(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x20, 25, 1, __value)
+#define GET_TX_DESC_STW_EN(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x20, 25, 1)
+#define SET_TX_DESC_SMH_EN(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x20, 24, 1, __value)
+#define GET_TX_DESC_SMH_EN(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x20, 24, 1)
+
+#define SET_TX_DESC_TAILPAGE_L(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x20, 24, 8, __value)
+#define GET_TX_DESC_TAILPAGE_L(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x20, 24, 8)
+
+#define SET_TX_DESC_SDIO_DMASEQ(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x20, 16, 8, __value)
+#define GET_TX_DESC_SDIO_DMASEQ(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x20, 16, 8)
+
+#define SET_TX_DESC_NEXTHEADPAGE_L(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x20, 16, 8, __value)
+#define GET_TX_DESC_NEXTHEADPAGE_L(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x20, 16, 8)
+#define SET_TX_DESC_EN_HWSEQ(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x20, 15, 1, __value)
+#define GET_TX_DESC_EN_HWSEQ(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x20, 15, 1)
+
+#define SET_TX_DESC_EN_HWEXSEQ(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x20, 14, 1, __value)
+#define GET_TX_DESC_EN_HWEXSEQ(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x20, 14, 1)
+
+#define SET_TX_DESC_DATA_RC(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x20, 8, 6, __value)
+#define GET_TX_DESC_DATA_RC(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x20, 8, 6)
+#define SET_TX_DESC_BAR_RTY_TH(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x20, 6, 2, __value)
+#define GET_TX_DESC_BAR_RTY_TH(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x20, 6, 2)
+#define SET_TX_DESC_RTS_RC(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x20, 0, 6, __value)
+#define GET_TX_DESC_RTS_RC(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x20, 0, 6)
+
+/*TXDESC_WORD9*/
+
+#define SET_TX_DESC_TAILPAGE_H(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x24, 28, 4, __value)
+#define GET_TX_DESC_TAILPAGE_H(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x24, 28, 4)
+#define SET_TX_DESC_NEXTHEADPAGE_H(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x24, 24, 4, __value)
+#define GET_TX_DESC_NEXTHEADPAGE_H(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x24, 24, 4)
+
+#define SET_TX_DESC_SW_SEQ(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x24, 12, 12, __value)
+#define GET_TX_DESC_SW_SEQ(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x24, 12, 12)
+#define SET_TX_DESC_TXBF_PATH(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x24, 11, 1, __value)
+#define GET_TX_DESC_TXBF_PATH(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x24, 11, 1)
+#define SET_TX_DESC_PADDING_LEN(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x24, 0, 11, __value)
+#define GET_TX_DESC_PADDING_LEN(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x24, 0, 11)
+#define SET_TX_DESC_GROUP_BIT_IE_OFFSET(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x24, 0, 8, __value)
+#define GET_TX_DESC_GROUP_BIT_IE_OFFSET(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x24, 0, 8)
+
+/*WORD10*/
+
+#define SET_TX_DESC_MU_DATARATE(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x28, 8, 8, __value)
+#define GET_TX_DESC_MU_DATARATE(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x28, 8, 8)
+#define SET_TX_DESC_MU_RC(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x28, 4, 4, __value)
+#define GET_TX_DESC_MU_RC(__tx_desc) LE_BITS_TO_4BYTE(__tx_desc + 0x28, 4, 4)
+#define SET_TX_DESC_SND_PKT_SEL(__tx_desc, __value) \
+ SET_BITS_TO_LE_4BYTE(__tx_desc + 0x28, 0, 2, __value)
+#define GET_TX_DESC_SND_PKT_SEL(__tx_desc) \
+ LE_BITS_TO_4BYTE(__tx_desc + 0x28, 0, 2)
+
+#endif
diff --git a/drivers/staging/rtlwifi/halmac/halmac_type.h b/drivers/staging/rtlwifi/halmac/halmac_type.h
new file mode 100644
index 0000000..0bf8424
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_type.h
@@ -0,0 +1,1934 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _HALMAC_TYPE_H_
+#define _HALMAC_TYPE_H_
+
+#include "halmac_2_platform.h"
+#include "halmac_fw_info.h"
+#include "halmac_intf_phy_cmd.h"
+
+#define HALMAC_SCAN_CH_NUM_MAX 28
+#define HALMAC_BCN_IE_BMP_SIZE 24 /* ID0~ID191, 192/8=24 */
+#define HALMAC_PHY_PARAMETER_SIZE 12
+#define HALMAC_PHY_PARAMETER_MAX_NUM 128
+#define HALMAC_MAX_SSID_LEN 32
+#define HALMAC_SUPPORT_NLO_NUM 16
+#define HALMAC_SUPPORT_PROBE_REQ_NUM 8
+#define HALMC_DDMA_POLLING_COUNT 1000
+#define API_ARRAY_SIZE 32
+
+/* platform api */
+#define PLATFORM_SDIO_CMD52_READ \
+ halmac_adapter->halmac_platform_api->SDIO_CMD52_READ
+#define PLATFORM_SDIO_CMD53_READ_8 \
+ halmac_adapter->halmac_platform_api->SDIO_CMD53_READ_8
+#define PLATFORM_SDIO_CMD53_READ_16 \
+ halmac_adapter->halmac_platform_api->SDIO_CMD53_READ_16
+#define PLATFORM_SDIO_CMD53_READ_32 \
+ halmac_adapter->halmac_platform_api->SDIO_CMD53_READ_32
+#define PLATFORM_SDIO_CMD53_READ_N \
+ halmac_adapter->halmac_platform_api->SDIO_CMD53_READ_N
+#define PLATFORM_SDIO_CMD52_WRITE \
+ halmac_adapter->halmac_platform_api->SDIO_CMD52_WRITE
+#define PLATFORM_SDIO_CMD53_WRITE_8 \
+ halmac_adapter->halmac_platform_api->SDIO_CMD53_WRITE_8
+#define PLATFORM_SDIO_CMD53_WRITE_16 \
+ halmac_adapter->halmac_platform_api->SDIO_CMD53_WRITE_16
+#define PLATFORM_SDIO_CMD53_WRITE_32 \
+ halmac_adapter->halmac_platform_api->SDIO_CMD53_WRITE_32
+
+#define PLATFORM_REG_READ_8 halmac_adapter->halmac_platform_api->REG_READ_8
+#define PLATFORM_REG_READ_16 halmac_adapter->halmac_platform_api->REG_READ_16
+#define PLATFORM_REG_READ_32 halmac_adapter->halmac_platform_api->REG_READ_32
+#define PLATFORM_REG_WRITE_8 halmac_adapter->halmac_platform_api->REG_WRITE_8
+#define PLATFORM_REG_WRITE_16 halmac_adapter->halmac_platform_api->REG_WRITE_16
+#define PLATFORM_REG_WRITE_32 halmac_adapter->halmac_platform_api->REG_WRITE_32
+
+#define PLATFORM_SEND_RSVD_PAGE \
+ halmac_adapter->halmac_platform_api->SEND_RSVD_PAGE
+#define PLATFORM_SEND_H2C_PKT halmac_adapter->halmac_platform_api->SEND_H2C_PKT
+
+#define PLATFORM_EVENT_INDICATION \
+ halmac_adapter->halmac_platform_api->EVENT_INDICATION
+
+#define HALMAC_RT_TRACE(drv_adapter, comp, level, fmt, ...) \
+ RT_TRACE(drv_adapter, COMP_HALMAC, level, fmt, ##__VA_ARGS__)
+
+#define HALMAC_REG_READ_8 halmac_api->halmac_reg_read_8
+#define HALMAC_REG_READ_16 halmac_api->halmac_reg_read_16
+#define HALMAC_REG_READ_32 halmac_api->halmac_reg_read_32
+#define HALMAC_REG_WRITE_8 halmac_api->halmac_reg_write_8
+#define HALMAC_REG_WRITE_16 halmac_api->halmac_reg_write_16
+#define HALMAC_REG_WRITE_32 halmac_api->halmac_reg_write_32
+#define HALMAC_REG_SDIO_CMD53_READ_N halmac_api->halmac_reg_sdio_cmd53_read_n
+
+/* Swap Little-endian <-> Big-endia*/
+
+/*1->Little endian 0->Big endian*/
+#if HALMAC_SYSTEM_ENDIAN
+#else
+#endif
+
+#define HALMAC_ALIGN(x, a) HALMAC_ALIGN_MASK(x, (a) - 1)
+#define HALMAC_ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))
+
+/* HALMAC API return status*/
+enum halmac_ret_status {
+ HALMAC_RET_SUCCESS = 0x00,
+ HALMAC_RET_SUCCESS_ENQUEUE = 0x01,
+ HALMAC_RET_PLATFORM_API_NULL = 0x02,
+ HALMAC_RET_EFUSE_SIZE_INCORRECT = 0x03,
+ HALMAC_RET_MALLOC_FAIL = 0x04,
+ HALMAC_RET_ADAPTER_INVALID = 0x05,
+ HALMAC_RET_ITF_INCORRECT = 0x06,
+ HALMAC_RET_DLFW_FAIL = 0x07,
+ HALMAC_RET_PORT_NOT_SUPPORT = 0x08,
+ HALMAC_RET_TRXMODE_NOT_SUPPORT = 0x09,
+ HALMAC_RET_INIT_LLT_FAIL = 0x0A,
+ HALMAC_RET_POWER_STATE_INVALID = 0x0B,
+ HALMAC_RET_H2C_ACK_NOT_RECEIVED = 0x0C,
+ HALMAC_RET_DL_RSVD_PAGE_FAIL = 0x0D,
+ HALMAC_RET_EFUSE_R_FAIL = 0x0E,
+ HALMAC_RET_EFUSE_W_FAIL = 0x0F,
+ HALMAC_RET_H2C_SW_RES_FAIL = 0x10,
+ HALMAC_RET_SEND_H2C_FAIL = 0x11,
+ HALMAC_RET_PARA_NOT_SUPPORT = 0x12,
+ HALMAC_RET_PLATFORM_API_INCORRECT = 0x13,
+ HALMAC_RET_ENDIAN_ERR = 0x14,
+ HALMAC_RET_FW_SIZE_ERR = 0x15,
+ HALMAC_RET_TRX_MODE_NOT_SUPPORT = 0x16,
+ HALMAC_RET_FAIL = 0x17,
+ HALMAC_RET_CHANGE_PS_FAIL = 0x18,
+ HALMAC_RET_CFG_PARA_FAIL = 0x19,
+ HALMAC_RET_UPDATE_PROBE_FAIL = 0x1A,
+ HALMAC_RET_SCAN_FAIL = 0x1B,
+ HALMAC_RET_STOP_SCAN_FAIL = 0x1C,
+ HALMAC_RET_BCN_PARSER_CMD_FAIL = 0x1D,
+ HALMAC_RET_POWER_ON_FAIL = 0x1E,
+ HALMAC_RET_POWER_OFF_FAIL = 0x1F,
+ HALMAC_RET_RX_AGG_MODE_FAIL = 0x20,
+ HALMAC_RET_DATA_BUF_NULL = 0x21,
+ HALMAC_RET_DATA_SIZE_INCORRECT = 0x22,
+ HALMAC_RET_QSEL_INCORRECT = 0x23,
+ HALMAC_RET_DMA_MAP_INCORRECT = 0x24,
+ HALMAC_RET_SEND_ORIGINAL_H2C_FAIL = 0x25,
+ HALMAC_RET_DDMA_FAIL = 0x26,
+ HALMAC_RET_FW_CHECKSUM_FAIL = 0x27,
+ HALMAC_RET_PWRSEQ_POLLING_FAIL = 0x28,
+ HALMAC_RET_PWRSEQ_CMD_INCORRECT = 0x29,
+ HALMAC_RET_WRITE_DATA_FAIL = 0x2A,
+ HALMAC_RET_DUMP_FIFOSIZE_INCORRECT = 0x2B,
+ HALMAC_RET_NULL_POINTER = 0x2C,
+ HALMAC_RET_PROBE_NOT_FOUND = 0x2D,
+ HALMAC_RET_FW_NO_MEMORY = 0x2E,
+ HALMAC_RET_H2C_STATUS_ERR = 0x2F,
+ HALMAC_RET_GET_H2C_SPACE_ERR = 0x30,
+ HALMAC_RET_H2C_SPACE_FULL = 0x31,
+ HALMAC_RET_DATAPACK_NO_FOUND = 0x32,
+ HALMAC_RET_CANNOT_FIND_H2C_RESOURCE = 0x33,
+ HALMAC_RET_TX_DMA_ERR = 0x34,
+ HALMAC_RET_RX_DMA_ERR = 0x35,
+ HALMAC_RET_CHIP_NOT_SUPPORT = 0x36,
+ HALMAC_RET_FREE_SPACE_NOT_ENOUGH = 0x37,
+ HALMAC_RET_CH_SW_SEQ_WRONG = 0x38,
+ HALMAC_RET_CH_SW_NO_BUF = 0x39,
+ HALMAC_RET_SW_CASE_NOT_SUPPORT = 0x3A,
+ HALMAC_RET_CONVERT_SDIO_OFFSET_FAIL = 0x3B,
+ HALMAC_RET_INVALID_SOUNDING_SETTING = 0x3C,
+ HALMAC_RET_GEN_INFO_NOT_SENT = 0x3D,
+ HALMAC_RET_STATE_INCORRECT = 0x3E,
+ HALMAC_RET_H2C_BUSY = 0x3F,
+ HALMAC_RET_INVALID_FEATURE_ID = 0x40,
+ HALMAC_RET_BUFFER_TOO_SMALL = 0x41,
+ HALMAC_RET_ZERO_LEN_RSVD_PACKET = 0x42,
+ HALMAC_RET_BUSY_STATE = 0x43,
+ HALMAC_RET_ERROR_STATE = 0x44,
+ HALMAC_RET_API_INVALID = 0x45,
+ HALMAC_RET_POLLING_BCN_VALID_FAIL = 0x46,
+ HALMAC_RET_SDIO_LEAVE_SUSPEND_FAIL = 0x47,
+ HALMAC_RET_EEPROM_PARSING_FAIL = 0x48,
+ HALMAC_RET_EFUSE_NOT_ENOUGH = 0x49,
+ HALMAC_RET_WRONG_ARGUMENT = 0x4A,
+ HALMAC_RET_NOT_SUPPORT = 0x4B,
+ HALMAC_RET_C2H_NOT_HANDLED = 0x4C,
+ HALMAC_RET_PARA_SENDING = 0x4D,
+ HALMAC_RET_CFG_DLFW_SIZE_FAIL = 0x4E,
+ HALMAC_RET_CFG_TXFIFO_PAGE_FAIL = 0x4F,
+ HALMAC_RET_SWITCH_CASE_ERROR = 0x50,
+ HALMAC_RET_EFUSE_BANK_INCORRECT = 0x51,
+ HALMAC_RET_SWITCH_EFUSE_BANK_FAIL = 0x52,
+ HALMAC_RET_USB_MODE_UNCHANGE = 0x53,
+ HALMAC_RET_NO_DLFW = 0x54,
+ HALMAC_RET_USB2_3_SWITCH_UNSUPPORT = 0x55,
+ HALMAC_RET_BIP_NO_SUPPORT = 0x56,
+ HALMAC_RET_ENTRY_INDEX_ERROR = 0x57,
+ HALMAC_RET_ENTRY_KEY_ID_ERROR = 0x58,
+ HALMAC_RET_DRV_DL_ERR = 0x59,
+ HALMAC_RET_OQT_NOT_ENOUGH = 0x5A,
+ HALMAC_RET_PWR_UNCHANGE = 0x5B,
+ HALMAC_RET_FW_NO_SUPPORT = 0x60,
+ HALMAC_RET_TXFIFO_NO_EMPTY = 0x61,
+};
+
+enum halmac_mac_clock_hw_def {
+ HALMAC_MAC_CLOCK_HW_DEF_80M = 0,
+ HALMAC_MAC_CLOCK_HW_DEF_40M = 1,
+ HALMAC_MAC_CLOCK_HW_DEF_20M = 2,
+};
+
+/* Rx aggregation parameters */
+enum halmac_normal_rxagg_th_to {
+ HALMAC_NORMAL_RXAGG_THRESHOLD = 0xFF,
+ HALMAC_NORMAL_RXAGG_TIMEOUT = 0x01,
+};
+
+enum halmac_loopback_rxagg_th_to {
+ HALMAC_LOOPBACK_RXAGG_THRESHOLD = 0xFF,
+ HALMAC_LOOPBACK_RXAGG_TIMEOUT = 0x01,
+};
+
+/* Chip ID*/
+enum halmac_chip_id {
+ HALMAC_CHIP_ID_8822B = 0,
+ HALMAC_CHIP_ID_8821C = 1,
+ HALMAC_CHIP_ID_8814B = 2,
+ HALMAC_CHIP_ID_8197F = 3,
+ HALMAC_CHIP_ID_UNDEFINE = 0x7F,
+};
+
+enum halmac_chip_id_hw_def {
+ HALMAC_CHIP_ID_HW_DEF_8723A = 0x01,
+ HALMAC_CHIP_ID_HW_DEF_8188E = 0x02,
+ HALMAC_CHIP_ID_HW_DEF_8881A = 0x03,
+ HALMAC_CHIP_ID_HW_DEF_8812A = 0x04,
+ HALMAC_CHIP_ID_HW_DEF_8821A = 0x05,
+ HALMAC_CHIP_ID_HW_DEF_8723B = 0x06,
+ HALMAC_CHIP_ID_HW_DEF_8192E = 0x07,
+ HALMAC_CHIP_ID_HW_DEF_8814A = 0x08,
+ HALMAC_CHIP_ID_HW_DEF_8821C = 0x09,
+ HALMAC_CHIP_ID_HW_DEF_8822B = 0x0A,
+ HALMAC_CHIP_ID_HW_DEF_8703B = 0x0B,
+ HALMAC_CHIP_ID_HW_DEF_8188F = 0x0C,
+ HALMAC_CHIP_ID_HW_DEF_8192F = 0x0D,
+ HALMAC_CHIP_ID_HW_DEF_8197F = 0x0E,
+ HALMAC_CHIP_ID_HW_DEF_8723D = 0x0F,
+ HALMAC_CHIP_ID_HW_DEF_8814B = 0x10,
+ HALMAC_CHIP_ID_HW_DEF_UNDEFINE = 0x7F,
+ HALMAC_CHIP_ID_HW_DEF_PS = 0xEA,
+};
+
+/* Chip Version*/
+enum halmac_chip_ver {
+ HALMAC_CHIP_VER_A_CUT = 0x00,
+ HALMAC_CHIP_VER_B_CUT = 0x01,
+ HALMAC_CHIP_VER_C_CUT = 0x02,
+ HALMAC_CHIP_VER_D_CUT = 0x03,
+ HALMAC_CHIP_VER_E_CUT = 0x04,
+ HALMAC_CHIP_VER_F_CUT = 0x05,
+ HALMAC_CHIP_VER_TEST = 0xFF,
+ HALMAC_CHIP_VER_UNDEFINE = 0x7FFF,
+};
+
+/* Network type select */
+enum halmac_network_type_select {
+ HALMAC_NETWORK_NO_LINK = 0,
+ HALMAC_NETWORK_ADHOC = 1,
+ HALMAC_NETWORK_INFRASTRUCTURE = 2,
+ HALMAC_NETWORK_AP = 3,
+ HALMAC_NETWORK_UNDEFINE = 0x7F,
+};
+
+/* Transfer mode select */
+enum halmac_trnsfer_mode_select {
+ HALMAC_TRNSFER_NORMAL = 0x0,
+ HALMAC_TRNSFER_LOOPBACK_DIRECT = 0xB,
+ HALMAC_TRNSFER_LOOPBACK_DELAY = 0x3,
+ HALMAC_TRNSFER_UNDEFINE = 0x7F,
+};
+
+/* Queue select */
+enum halmac_dma_mapping {
+ HALMAC_DMA_MAPPING_EXTRA = 0,
+ HALMAC_DMA_MAPPING_LOW = 1,
+ HALMAC_DMA_MAPPING_NORMAL = 2,
+ HALMAC_DMA_MAPPING_HIGH = 3,
+ HALMAC_DMA_MAPPING_UNDEFINE = 0x7F,
+};
+
+#define HALMAC_MAP2_HQ HALMAC_DMA_MAPPING_HIGH
+#define HALMAC_MAP2_NQ HALMAC_DMA_MAPPING_NORMAL
+#define HALMAC_MAP2_LQ HALMAC_DMA_MAPPING_LOW
+#define HALMAC_MAP2_EXQ HALMAC_DMA_MAPPING_EXTRA
+#define HALMAC_MAP2_UNDEF HALMAC_DMA_MAPPING_UNDEFINE
+
+/* TXDESC queue select TID */
+enum halmac_txdesc_queue_tid {
+ HALMAC_TXDESC_QSEL_TID0 = 0,
+ HALMAC_TXDESC_QSEL_TID1 = 1,
+ HALMAC_TXDESC_QSEL_TID2 = 2,
+ HALMAC_TXDESC_QSEL_TID3 = 3,
+ HALMAC_TXDESC_QSEL_TID4 = 4,
+ HALMAC_TXDESC_QSEL_TID5 = 5,
+ HALMAC_TXDESC_QSEL_TID6 = 6,
+ HALMAC_TXDESC_QSEL_TID7 = 7,
+ HALMAC_TXDESC_QSEL_TID8 = 8,
+ HALMAC_TXDESC_QSEL_TID9 = 9,
+ HALMAC_TXDESC_QSEL_TIDA = 10,
+ HALMAC_TXDESC_QSEL_TIDB = 11,
+ HALMAC_TXDESC_QSEL_TIDC = 12,
+ HALMAC_TXDESC_QSEL_TIDD = 13,
+ HALMAC_TXDESC_QSEL_TIDE = 14,
+ HALMAC_TXDESC_QSEL_TIDF = 15,
+
+ HALMAC_TXDESC_QSEL_BEACON = 0x10,
+ HALMAC_TXDESC_QSEL_HIGH = 0x11,
+ HALMAC_TXDESC_QSEL_MGT = 0x12,
+ HALMAC_TXDESC_QSEL_H2C_CMD = 0x13,
+
+ HALMAC_TXDESC_QSEL_UNDEFINE = 0x7F,
+};
+
+enum halmac_ptcl_queue {
+ HALMAC_PTCL_QUEUE_VO = 0x0,
+ HALMAC_PTCL_QUEUE_VI = 0x1,
+ HALMAC_PTCL_QUEUE_BE = 0x2,
+ HALMAC_PTCL_QUEUE_BK = 0x3,
+ HALMAC_PTCL_QUEUE_MG = 0x4,
+ HALMAC_PTCL_QUEUE_HI = 0x5,
+ HALMAC_PTCL_QUEUE_NUM = 0x6,
+ HALMAC_PTCL_QUEUE_UNDEFINE = 0x7F,
+};
+
+enum halmac_queue_select {
+ HALMAC_QUEUE_SELECT_VO = HALMAC_TXDESC_QSEL_TID6,
+ HALMAC_QUEUE_SELECT_VI = HALMAC_TXDESC_QSEL_TID4,
+ HALMAC_QUEUE_SELECT_BE = HALMAC_TXDESC_QSEL_TID0,
+ HALMAC_QUEUE_SELECT_BK = HALMAC_TXDESC_QSEL_TID1,
+ HALMAC_QUEUE_SELECT_VO_V2 = HALMAC_TXDESC_QSEL_TID7,
+ HALMAC_QUEUE_SELECT_VI_V2 = HALMAC_TXDESC_QSEL_TID5,
+ HALMAC_QUEUE_SELECT_BE_V2 = HALMAC_TXDESC_QSEL_TID3,
+ HALMAC_QUEUE_SELECT_BK_V2 = HALMAC_TXDESC_QSEL_TID2,
+ HALMAC_QUEUE_SELECT_BCN = HALMAC_TXDESC_QSEL_BEACON,
+ HALMAC_QUEUE_SELECT_HIGH = HALMAC_TXDESC_QSEL_HIGH,
+ HALMAC_QUEUE_SELECT_MGNT = HALMAC_TXDESC_QSEL_MGT,
+ HALMAC_QUEUE_SELECT_CMD = HALMAC_TXDESC_QSEL_H2C_CMD,
+ HALMAC_QUEUE_SELECT_UNDEFINE = 0x7F,
+};
+
+/* USB burst size */
+enum halmac_usb_burst_size {
+ HALMAC_USB_BURST_SIZE_3_0 = 0x0,
+ HALMAC_USB_BURST_SIZE_2_0_HSPEED = 0x1,
+ HALMAC_USB_BURST_SIZE_2_0_FSPEED = 0x2,
+ HALMAC_USB_BURST_SIZE_2_0_OTHERS = 0x3,
+ HALMAC_USB_BURST_SIZE_UNDEFINE = 0x7F,
+};
+
+/* HAL API function parameters*/
+enum halmac_interface {
+ HALMAC_INTERFACE_PCIE = 0x0,
+ HALMAC_INTERFACE_USB = 0x1,
+ HALMAC_INTERFACE_SDIO = 0x2,
+ HALMAC_INTERFACE_AXI = 0x3,
+ HALMAC_INTERFACE_UNDEFINE = 0x7F,
+};
+
+enum halmac_rx_agg_mode {
+ HALMAC_RX_AGG_MODE_NONE = 0x0,
+ HALMAC_RX_AGG_MODE_DMA = 0x1,
+ HALMAC_RX_AGG_MODE_USB = 0x2,
+ HALMAC_RX_AGG_MODE_UNDEFINE = 0x7F,
+};
+
+struct halmac_rxagg_th {
+ u8 drv_define;
+ u8 timeout;
+ u8 size;
+};
+
+struct halmac_rxagg_cfg {
+ enum halmac_rx_agg_mode mode;
+ struct halmac_rxagg_th threshold;
+};
+
+enum halmac_mac_power {
+ HALMAC_MAC_POWER_OFF = 0x0,
+ HALMAC_MAC_POWER_ON = 0x1,
+ HALMAC_MAC_POWER_UNDEFINE = 0x7F,
+};
+
+enum halmac_ps_state {
+ HALMAC_PS_STATE_ACT = 0x0,
+ HALMAC_PS_STATE_LPS = 0x1,
+ HALMAC_PS_STATE_IPS = 0x2,
+ HALMAC_PS_STATE_UNDEFINE = 0x7F,
+};
+
+enum halmac_trx_mode {
+ HALMAC_TRX_MODE_NORMAL = 0x0,
+ HALMAC_TRX_MODE_TRXSHARE = 0x1,
+ HALMAC_TRX_MODE_WMM = 0x2,
+ HALMAC_TRX_MODE_P2P = 0x3,
+ HALMAC_TRX_MODE_LOOPBACK = 0x4,
+ HALMAC_TRX_MODE_DELAY_LOOPBACK = 0x5,
+ HALMAC_TRX_MODE_MAX = 0x6,
+ HALMAC_TRX_MODE_WMM_LINUX = 0x7E,
+ HALMAC_TRX_MODE_UNDEFINE = 0x7F,
+};
+
+enum halmac_wireless_mode {
+ HALMAC_WIRELESS_MODE_B = 0x0,
+ HALMAC_WIRELESS_MODE_G = 0x1,
+ HALMAC_WIRELESS_MODE_N = 0x2,
+ HALMAC_WIRELESS_MODE_AC = 0x3,
+ HALMAC_WIRELESS_MODE_UNDEFINE = 0x7F,
+};
+
+enum halmac_bw {
+ HALMAC_BW_20 = 0x00,
+ HALMAC_BW_40 = 0x01,
+ HALMAC_BW_80 = 0x02,
+ HALMAC_BW_160 = 0x03,
+ HALMAC_BW_5 = 0x04,
+ HALMAC_BW_10 = 0x05,
+ HALMAC_BW_MAX = 0x06,
+ HALMAC_BW_UNDEFINE = 0x7F,
+};
+
+enum halmac_efuse_read_cfg {
+ HALMAC_EFUSE_R_AUTO = 0x00,
+ HALMAC_EFUSE_R_DRV = 0x01,
+ HALMAC_EFUSE_R_FW = 0x02,
+ HALMAC_EFUSE_R_UNDEFINE = 0x7F,
+};
+
+enum halmac_dlfw_mem {
+ HALMAC_DLFW_MEM_EMEM = 0x00,
+ HALMAC_DLFW_MEM_UNDEFINE = 0x7F,
+};
+
+struct halmac_tx_desc {
+ u32 dword0;
+ u32 dword1;
+ u32 dword2;
+ u32 dword3;
+ u32 dword4;
+ u32 dword5;
+ u32 dword6;
+ u32 dword7;
+ u32 dword8;
+ u32 dword9;
+ u32 dword10;
+ u32 dword11;
+};
+
+struct halmac_rx_desc {
+ u32 dword0;
+ u32 dword1;
+ u32 dword2;
+ u32 dword3;
+ u32 dword4;
+ u32 dword5;
+};
+
+struct halmac_fwlps_option {
+ u8 mode;
+ u8 clk_request;
+ u8 rlbm;
+ u8 smart_ps;
+ u8 awake_interval;
+ u8 all_queue_uapsd;
+ u8 pwr_state;
+ u8 low_pwr_rx_beacon;
+ u8 ant_auto_switch;
+ u8 ps_allow_bt_high_priority;
+ u8 protect_bcn;
+ u8 silence_period;
+ u8 fast_bt_connect;
+ u8 two_antenna_en;
+ u8 adopt_user_setting;
+ u8 drv_bcn_early_shift;
+ bool enter_32K;
+};
+
+struct halmac_fwips_option {
+ u8 adopt_user_setting;
+};
+
+struct halmac_wowlan_option {
+ u8 adopt_user_setting;
+};
+
+struct halmac_bcn_ie_info {
+ u8 func_en;
+ u8 size_th;
+ u8 timeout;
+ u8 ie_bmp[HALMAC_BCN_IE_BMP_SIZE];
+};
+
+enum halmac_reg_type {
+ HALMAC_REG_TYPE_MAC = 0x0,
+ HALMAC_REG_TYPE_BB = 0x1,
+ HALMAC_REG_TYPE_RF = 0x2,
+ HALMAC_REG_TYPE_UNDEFINE = 0x7F,
+};
+
+enum halmac_parameter_cmd {
+ /* HALMAC_PARAMETER_CMD_LLT = 0x1, */
+ /* HALMAC_PARAMETER_CMD_R_EFUSE = 0x2, */
+ /* HALMAC_PARAMETER_CMD_EFUSE_PATCH = 0x3, */
+ HALMAC_PARAMETER_CMD_MAC_W8 = 0x4,
+ HALMAC_PARAMETER_CMD_MAC_W16 = 0x5,
+ HALMAC_PARAMETER_CMD_MAC_W32 = 0x6,
+ HALMAC_PARAMETER_CMD_RF_W = 0x7,
+ HALMAC_PARAMETER_CMD_BB_W8 = 0x8,
+ HALMAC_PARAMETER_CMD_BB_W16 = 0x9,
+ HALMAC_PARAMETER_CMD_BB_W32 = 0XA,
+ HALMAC_PARAMETER_CMD_DELAY_US = 0X10,
+ HALMAC_PARAMETER_CMD_DELAY_MS = 0X11,
+ HALMAC_PARAMETER_CMD_END = 0XFF,
+};
+
+union halmac_parameter_content {
+ struct _MAC_REG_W {
+ u32 value;
+ u32 msk;
+ u16 offset;
+ u8 msk_en;
+ } MAC_REG_W;
+ struct _BB_REG_W {
+ u32 value;
+ u32 msk;
+ u16 offset;
+ u8 msk_en;
+ } BB_REG_W;
+ struct _RF_REG_W {
+ u32 value;
+ u32 msk;
+ u8 offset;
+ u8 msk_en;
+ u8 rf_path;
+ } RF_REG_W;
+ struct _DELAY_TIME {
+ u32 rsvd1;
+ u32 rsvd2;
+ u16 delay_time;
+ u8 rsvd3;
+ } DELAY_TIME;
+};
+
+struct halmac_phy_parameter_info {
+ enum halmac_parameter_cmd cmd_id;
+ union halmac_parameter_content content;
+};
+
+struct halmac_h2c_info {
+ u16 h2c_seq_num; /* H2C sequence number */
+ u8 in_use; /* 0 : empty 1 : used */
+ enum halmac_h2c_return_code status;
+};
+
+struct halmac_pg_efuse_info {
+ u8 *efuse_map;
+ u32 efuse_map_size;
+ u8 *efuse_mask;
+ u32 efuse_mask_size;
+};
+
+struct halmac_txagg_buff_info {
+ u8 *tx_agg_buf;
+ u8 *curr_pkt_buf;
+ u32 avai_buf_size;
+ u32 total_pkt_size;
+ u8 agg_num;
+};
+
+struct halmac_config_para_info {
+ u32 para_buf_size; /* Parameter buffer size */
+ u8 *cfg_para_buf; /* Buffer for config parameter */
+ u8 *para_buf_w; /* Write pointer of the parameter buffer */
+ u32 para_num; /* Parameter numbers in parameter buffer */
+ u32 avai_para_buf_size; /* Free size of parameter buffer */
+ u32 offset_accumulation;
+ u32 value_accumulation;
+ enum halmac_data_type data_type; /*DataType which is passed to FW*/
+ u8 datapack_segment; /*DataPack Segment, from segment0...*/
+ bool full_fifo_mode; /* Used full tx fifo to save cfg parameter */
+};
+
+struct halmac_hw_config_info {
+ u32 efuse_size; /* Record efuse size */
+ u32 eeprom_size; /* Record eeprom size */
+ u32 bt_efuse_size; /* Record BT efuse size */
+ u32 tx_fifo_size; /* Record tx fifo size */
+ u32 rx_fifo_size; /* Record rx fifo size */
+ u8 txdesc_size; /* Record tx desc size */
+ u8 rxdesc_size; /* Record rx desc size */
+ u32 page_size; /* Record page size */
+ u16 tx_align_size;
+ u8 page_size_2_power;
+ u8 cam_entry_num; /* Record CAM entry number */
+};
+
+struct halmac_sdio_free_space {
+ u16 high_queue_number; /* Free space of HIQ */
+ u16 normal_queue_number; /* Free space of MIDQ */
+ u16 low_queue_number; /* Free space of LOWQ */
+ u16 public_queue_number; /* Free space of PUBQ */
+ u16 extra_queue_number; /* Free space of EXBQ */
+ u8 ac_oqt_number;
+ u8 non_ac_oqt_number;
+ u8 ac_empty;
+};
+
+enum hal_fifo_sel {
+ HAL_FIFO_SEL_TX,
+ HAL_FIFO_SEL_RX,
+ HAL_FIFO_SEL_RSVD_PAGE,
+ HAL_FIFO_SEL_REPORT,
+ HAL_FIFO_SEL_LLT,
+};
+
+enum halmac_drv_info {
+ HALMAC_DRV_INFO_NONE, /* No information is appended in rx_pkt */
+ HALMAC_DRV_INFO_PHY_STATUS, /* PHY status is appended after rx_desc */
+ HALMAC_DRV_INFO_PHY_SNIFFER, /* PHY status and sniffer info appended */
+ HALMAC_DRV_INFO_PHY_PLCP, /* PHY status and plcp header are appended */
+ HALMAC_DRV_INFO_UNDEFINE,
+};
+
+struct halmac_bt_coex_cmd {
+ u8 element_id;
+ u8 op_code;
+ u8 op_code_ver;
+ u8 req_num;
+ u8 data0;
+ u8 data1;
+ u8 data2;
+ u8 data3;
+ u8 data4;
+};
+
+enum halmac_pri_ch_idx {
+ HALMAC_CH_IDX_UNDEFINE = 0,
+ HALMAC_CH_IDX_1 = 1,
+ HALMAC_CH_IDX_2 = 2,
+ HALMAC_CH_IDX_3 = 3,
+ HALMAC_CH_IDX_4 = 4,
+ HALMAC_CH_IDX_MAX = 5,
+};
+
+struct halmac_ch_info {
+ enum halmac_cs_action_id action_id;
+ enum halmac_bw bw;
+ enum halmac_pri_ch_idx pri_ch_idx;
+ u8 channel;
+ u8 timeout;
+ u8 extra_info;
+};
+
+struct halmac_ch_extra_info {
+ u8 extra_info;
+ enum halmac_cs_extra_action_id extra_action_id;
+ u8 extra_info_size;
+ u8 *extra_info_data;
+};
+
+enum halmac_cs_periodic_option {
+ HALMAC_CS_PERIODIC_NONE,
+ HALMAC_CS_PERIODIC_NORMAL,
+ HALMAC_CS_PERIODIC_2_PHASE,
+ HALMAC_CS_PERIODIC_SEAMLESS,
+};
+
+struct halmac_ch_switch_option {
+ enum halmac_bw dest_bw;
+ enum halmac_cs_periodic_option periodic_option;
+ enum halmac_pri_ch_idx dest_pri_ch_idx;
+ /* u32 tsf_high; */
+ u32 tsf_low;
+ bool switch_en;
+ u8 dest_ch_en;
+ u8 absolute_time_en;
+ u8 dest_ch;
+ u8 normal_period;
+ u8 normal_cycle;
+ u8 phase_2_period;
+};
+
+struct halmac_fw_version {
+ u16 version;
+ u8 sub_version;
+ u8 sub_index;
+ u16 h2c_version;
+};
+
+enum halmac_rf_type {
+ HALMAC_RF_1T2R = 0,
+ HALMAC_RF_2T4R = 1,
+ HALMAC_RF_2T2R = 2,
+ HALMAC_RF_2T3R = 3,
+ HALMAC_RF_1T1R = 4,
+ HALMAC_RF_2T2R_GREEN = 5,
+ HALMAC_RF_3T3R = 6,
+ HALMAC_RF_3T4R = 7,
+ HALMAC_RF_4T4R = 8,
+ HALMAC_RF_MAX_TYPE = 0xF,
+};
+
+struct halmac_general_info {
+ u8 rfe_type;
+ enum halmac_rf_type rf_type;
+};
+
+struct halmac_pwr_tracking_para {
+ u8 enable;
+ u8 tx_pwr_index;
+ u8 pwr_tracking_offset_value;
+ u8 tssi_value;
+};
+
+struct halmac_pwr_tracking_option {
+ u8 type;
+ u8 bbswing_index;
+ struct halmac_pwr_tracking_para
+ pwr_tracking_para[4]; /* pathA, pathB, pathC, pathD */
+};
+
+struct halmac_nlo_cfg {
+ u8 num_of_ssid;
+ u8 num_of_hidden_ap;
+ u8 rsvd[2];
+ u32 pattern_check;
+ u32 rsvd1;
+ u32 rsvd2;
+ u8 ssid_len[HALMAC_SUPPORT_NLO_NUM];
+ u8 chiper_type[HALMAC_SUPPORT_NLO_NUM];
+ u8 rsvd3[HALMAC_SUPPORT_NLO_NUM];
+ u8 loc_probe_req[HALMAC_SUPPORT_PROBE_REQ_NUM];
+ u8 rsvd4[56];
+ u8 ssid[HALMAC_SUPPORT_NLO_NUM][HALMAC_MAX_SSID_LEN];
+};
+
+enum halmac_data_rate {
+ HALMAC_CCK1,
+ HALMAC_CCK2,
+ HALMAC_CCK5_5,
+ HALMAC_CCK11,
+ HALMAC_OFDM6,
+ HALMAC_OFDM9,
+ HALMAC_OFDM12,
+ HALMAC_OFDM18,
+ HALMAC_OFDM24,
+ HALMAC_OFDM36,
+ HALMAC_OFDM48,
+ HALMAC_OFDM54,
+ HALMAC_MCS0,
+ HALMAC_MCS1,
+ HALMAC_MCS2,
+ HALMAC_MCS3,
+ HALMAC_MCS4,
+ HALMAC_MCS5,
+ HALMAC_MCS6,
+ HALMAC_MCS7,
+ HALMAC_MCS8,
+ HALMAC_MCS9,
+ HALMAC_MCS10,
+ HALMAC_MCS11,
+ HALMAC_MCS12,
+ HALMAC_MCS13,
+ HALMAC_MCS14,
+ HALMAC_MCS15,
+ HALMAC_MCS16,
+ HALMAC_MCS17,
+ HALMAC_MCS18,
+ HALMAC_MCS19,
+ HALMAC_MCS20,
+ HALMAC_MCS21,
+ HALMAC_MCS22,
+ HALMAC_MCS23,
+ HALMAC_MCS24,
+ HALMAC_MCS25,
+ HALMAC_MCS26,
+ HALMAC_MCS27,
+ HALMAC_MCS28,
+ HALMAC_MCS29,
+ HALMAC_MCS30,
+ HALMAC_MCS31,
+ HALMAC_VHT_NSS1_MCS0,
+ HALMAC_VHT_NSS1_MCS1,
+ HALMAC_VHT_NSS1_MCS2,
+ HALMAC_VHT_NSS1_MCS3,
+ HALMAC_VHT_NSS1_MCS4,
+ HALMAC_VHT_NSS1_MCS5,
+ HALMAC_VHT_NSS1_MCS6,
+ HALMAC_VHT_NSS1_MCS7,
+ HALMAC_VHT_NSS1_MCS8,
+ HALMAC_VHT_NSS1_MCS9,
+ HALMAC_VHT_NSS2_MCS0,
+ HALMAC_VHT_NSS2_MCS1,
+ HALMAC_VHT_NSS2_MCS2,
+ HALMAC_VHT_NSS2_MCS3,
+ HALMAC_VHT_NSS2_MCS4,
+ HALMAC_VHT_NSS2_MCS5,
+ HALMAC_VHT_NSS2_MCS6,
+ HALMAC_VHT_NSS2_MCS7,
+ HALMAC_VHT_NSS2_MCS8,
+ HALMAC_VHT_NSS2_MCS9,
+ HALMAC_VHT_NSS3_MCS0,
+ HALMAC_VHT_NSS3_MCS1,
+ HALMAC_VHT_NSS3_MCS2,
+ HALMAC_VHT_NSS3_MCS3,
+ HALMAC_VHT_NSS3_MCS4,
+ HALMAC_VHT_NSS3_MCS5,
+ HALMAC_VHT_NSS3_MCS6,
+ HALMAC_VHT_NSS3_MCS7,
+ HALMAC_VHT_NSS3_MCS8,
+ HALMAC_VHT_NSS3_MCS9,
+ HALMAC_VHT_NSS4_MCS0,
+ HALMAC_VHT_NSS4_MCS1,
+ HALMAC_VHT_NSS4_MCS2,
+ HALMAC_VHT_NSS4_MCS3,
+ HALMAC_VHT_NSS4_MCS4,
+ HALMAC_VHT_NSS4_MCS5,
+ HALMAC_VHT_NSS4_MCS6,
+ HALMAC_VHT_NSS4_MCS7,
+ HALMAC_VHT_NSS4_MCS8,
+ HALMAC_VHT_NSS4_MCS9
+};
+
+enum halmac_rf_path {
+ HALMAC_RF_PATH_A,
+ HALMAC_RF_PATH_B,
+ HALMAC_RF_PATH_C,
+ HALMAC_RF_PATH_D
+};
+
+enum halmac_snd_pkt_sel {
+ HALMAC_UNI_NDPA,
+ HALMAC_BMC_NDPA,
+ HALMAC_NON_FINAL_BFRPRPOLL,
+ HALMAC_FINAL_BFRPTPOLL,
+};
+
+enum hal_security_type {
+ HAL_SECURITY_TYPE_NONE = 0,
+ HAL_SECURITY_TYPE_WEP40 = 1,
+ HAL_SECURITY_TYPE_WEP104 = 2,
+ HAL_SECURITY_TYPE_TKIP = 3,
+ HAL_SECURITY_TYPE_AES128 = 4,
+ HAL_SECURITY_TYPE_WAPI = 5,
+ HAL_SECURITY_TYPE_AES256 = 6,
+ HAL_SECURITY_TYPE_GCMP128 = 7,
+ HAL_SECURITY_TYPE_GCMP256 = 8,
+ HAL_SECURITY_TYPE_GCMSMS4 = 9,
+ HAL_SECURITY_TYPE_BIP = 10,
+ HAL_SECURITY_TYPE_UNDEFINE = 0x7F,
+};
+
+enum hal_intf_phy {
+ HAL_INTF_PHY_USB2 = 0,
+ HAL_INTF_PHY_USB3 = 1,
+ HAL_INTF_PHY_PCIE_GEN1 = 2,
+ HAL_INTF_PHY_PCIE_GEN2 = 3,
+ HAL_INTF_PHY_UNDEFINE = 0x7F,
+};
+
+enum halmac_dbg_msg_info {
+ HALMAC_DBG_ERR,
+ HALMAC_DBG_WARN,
+ HALMAC_DBG_TRACE,
+};
+
+enum halmac_dbg_msg_type {
+ HALMAC_MSG_INIT,
+ HALMAC_MSG_EFUSE,
+ HALMAC_MSG_FW,
+ HALMAC_MSG_H2C,
+ HALMAC_MSG_PWR,
+ HALMAC_MSG_SND,
+ HALMAC_MSG_COMMON,
+ HALMAC_MSG_DBI,
+ HALMAC_MSG_MDIO,
+ HALMAC_MSG_USB
+};
+
+enum halmac_cmd_process_status {
+ HALMAC_CMD_PROCESS_IDLE = 0x01, /* Init status */
+ HALMAC_CMD_PROCESS_SENDING = 0x02, /* Wait ack */
+ HALMAC_CMD_PROCESS_RCVD = 0x03, /* Rcvd ack */
+ HALMAC_CMD_PROCESS_DONE = 0x04, /* Event done */
+ HALMAC_CMD_PROCESS_ERROR = 0x05, /* Return code error */
+ HALMAC_CMD_PROCESS_UNDEFINE = 0x7F,
+};
+
+enum halmac_feature_id {
+ HALMAC_FEATURE_CFG_PARA, /* Support */
+ HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE, /* Support */
+ HALMAC_FEATURE_DUMP_LOGICAL_EFUSE, /* Support */
+ HALMAC_FEATURE_UPDATE_PACKET, /* Support */
+ HALMAC_FEATURE_UPDATE_DATAPACK,
+ HALMAC_FEATURE_RUN_DATAPACK,
+ HALMAC_FEATURE_CHANNEL_SWITCH, /* Support */
+ HALMAC_FEATURE_IQK, /* Support */
+ HALMAC_FEATURE_POWER_TRACKING, /* Support */
+ HALMAC_FEATURE_PSD, /* Support */
+ HALMAC_FEATURE_ALL, /* Support, only for reset */
+};
+
+enum halmac_drv_rsvd_pg_num {
+ HALMAC_RSVD_PG_NUM16, /* 2K */
+ HALMAC_RSVD_PG_NUM24, /* 3K */
+ HALMAC_RSVD_PG_NUM32, /* 4K */
+};
+
+enum halmac_pcie_cfg {
+ HALMAC_PCIE_GEN1,
+ HALMAC_PCIE_GEN2,
+ HALMAC_PCIE_CFG_UNDEFINE,
+};
+
+enum halmac_portid {
+ HALMAC_PORTID0 = 0,
+ HALMAC_PORTID1 = 1,
+ HALMAC_PORTID2 = 2,
+ HALMAC_PORTID3 = 3,
+ HALMAC_PORTID4 = 4,
+ HALMAC_PORTIDMAX
+};
+
+struct halmac_p2pps {
+ /*DW0*/
+ u8 offload_en : 1;
+ u8 role : 1;
+ u8 ctwindow_en : 1;
+ u8 noa_en : 1;
+ u8 noa_sel : 1;
+ u8 all_sta_sleep : 1;
+ u8 discovery : 1;
+ u8 rsvd2 : 1;
+ u8 p2p_port_id;
+ u8 p2p_group;
+ u8 p2p_macid;
+
+ /*DW1*/
+ u8 ctwindow_length;
+ u8 rsvd3;
+ u8 rsvd4;
+ u8 rsvd5;
+
+ /*DW2*/
+ u32 noa_duration_para;
+
+ /*DW3*/
+ u32 noa_interval_para;
+
+ /*DW4*/
+ u32 noa_start_time_para;
+
+ /*DW5*/
+ u32 noa_count_para;
+};
+
+/* Platform API setting */
+struct halmac_platform_api {
+ /* R/W register */
+ u8 (*SDIO_CMD52_READ)(void *driver_adapter, u32 offset);
+ u8 (*SDIO_CMD53_READ_8)(void *driver_adapter, u32 offset);
+ u16 (*SDIO_CMD53_READ_16)(void *driver_adapter, u32 offset);
+ u32 (*SDIO_CMD53_READ_32)(void *driver_adapter, u32 offset);
+ u8 (*SDIO_CMD53_READ_N)(void *driver_adapter, u32 offset, u32 size,
+ u8 *data);
+ void (*SDIO_CMD52_WRITE)(void *driver_adapter, u32 offset, u8 value);
+ void (*SDIO_CMD53_WRITE_8)(void *driver_adapter, u32 offset, u8 value);
+ void (*SDIO_CMD53_WRITE_16)(void *driver_adapter, u32 offset,
+ u16 value);
+ void (*SDIO_CMD53_WRITE_32)(void *driver_adapter, u32 offset,
+ u32 value);
+ u8 (*REG_READ_8)(void *driver_adapter, u32 offset);
+ u16 (*REG_READ_16)(void *driver_adapter, u32 offset);
+ u32 (*REG_READ_32)(void *driver_adapter, u32 offset);
+ void (*REG_WRITE_8)(void *driver_adapter, u32 offset, u8 value);
+ void (*REG_WRITE_16)(void *driver_adapter, u32 offset, u16 value);
+ void (*REG_WRITE_32)(void *driver_adapter, u32 offset, u32 value);
+
+ /* send buf to reserved page, the tx_desc is not included in buf,
+ * driver need to fill tx_desc with qsel = bcn
+ */
+ bool (*SEND_RSVD_PAGE)(void *driver_adapter, u8 *buf, u32 size);
+ /* send buf to h2c queue, the tx_desc is not included in buf,
+ * driver need to fill tx_desc with qsel = h2c
+ */
+ bool (*SEND_H2C_PKT)(void *driver_adapter, u8 *buf, u32 size);
+
+ bool (*EVENT_INDICATION)(void *driver_adapter,
+ enum halmac_feature_id feature_id,
+ enum halmac_cmd_process_status process_status,
+ u8 *buf, u32 size);
+};
+
+/*1->Little endian 0->Big endian*/
+#if HALMAC_SYSTEM_ENDIAN
+
+#else
+
+#endif
+
+/* User can not use members in address_l_h, use address[6] is mandatory */
+union halmac_wlan_addr {
+ u8 address[6]; /* WLAN address (MACID, BSSID, Brodcast ID).
+ * address[0] is lowest, address[5] is highest
+ */
+ struct {
+ union {
+ u32 address_low;
+ __le32 le_address_low;
+ u8 address_low_b[4];
+ };
+ union {
+ u16 address_high;
+ __le16 le_address_high;
+ u8 address_high_b[2];
+ };
+ } address_l_h;
+};
+
+enum halmac_snd_role {
+ HAL_BFER = 0,
+ HAL_BFEE = 1,
+};
+
+enum halmac_csi_seg_len {
+ HAL_CSI_SEG_4K = 0,
+ HAL_CSI_SEG_8K = 1,
+ HAL_CSI_SEG_11K = 2,
+};
+
+struct halmac_cfg_mumimo_para {
+ enum halmac_snd_role role;
+ bool sounding_sts[6];
+ u16 grouping_bitmap;
+ bool mu_tx_en;
+ u32 given_gid_tab[2];
+ u32 given_user_pos[4];
+};
+
+struct halmac_su_bfer_init_para {
+ u8 userid;
+ u16 paid;
+ u16 csi_para;
+ union halmac_wlan_addr bfer_address;
+};
+
+struct halmac_mu_bfee_init_para {
+ u8 userid;
+ u16 paid;
+ u32 user_position_l;
+ u32 user_position_h;
+};
+
+struct halmac_mu_bfer_init_para {
+ u16 paid;
+ u16 csi_para;
+ u16 my_aid;
+ enum halmac_csi_seg_len csi_length_sel;
+ union halmac_wlan_addr bfer_address;
+};
+
+struct halmac_snd_info {
+ u16 paid;
+ u8 userid;
+ enum halmac_data_rate ndpa_rate;
+ u16 csi_para;
+ u16 my_aid;
+ enum halmac_data_rate csi_rate;
+ enum halmac_csi_seg_len csi_length_sel;
+ enum halmac_snd_role role;
+ union halmac_wlan_addr bfer_address;
+ enum halmac_bw bw;
+ u8 txbf_en;
+ struct halmac_su_bfer_init_para *su_bfer_init;
+ struct halmac_mu_bfer_init_para *mu_bfer_init;
+ struct halmac_mu_bfee_init_para *mu_bfee_init;
+};
+
+struct halmac_cs_info {
+ u8 *ch_info_buf;
+ u8 *ch_info_buf_w;
+ u8 extra_info_en;
+ u32 buf_size; /* buffer size */
+ u32 avai_buf_size; /* buffer size */
+ u32 total_size;
+ u32 accu_timeout;
+ u32 ch_num;
+};
+
+struct halmac_restore_info {
+ u32 mac_register;
+ u32 value;
+ u8 length;
+};
+
+struct halmac_event_trigger {
+ u32 physical_efuse_map : 1;
+ u32 logical_efuse_map : 1;
+ u32 rsvd1 : 28;
+};
+
+struct halmac_h2c_header_info {
+ u16 sub_cmd_id;
+ u16 content_size;
+ bool ack;
+};
+
+enum halmac_dlfw_state {
+ HALMAC_DLFW_NONE = 0,
+ HALMAC_DLFW_DONE = 1,
+ HALMAC_GEN_INFO_SENT = 2,
+ HALMAC_DLFW_UNDEFINED = 0x7F,
+};
+
+enum halmac_efuse_cmd_construct_state {
+ HALMAC_EFUSE_CMD_CONSTRUCT_IDLE = 0,
+ HALMAC_EFUSE_CMD_CONSTRUCT_BUSY = 1,
+ HALMAC_EFUSE_CMD_CONSTRUCT_H2C_SENT = 2,
+ HALMAC_EFUSE_CMD_CONSTRUCT_STATE_NUM = 3,
+ HALMAC_EFUSE_CMD_CONSTRUCT_UNDEFINED = 0x7F,
+};
+
+enum halmac_cfg_para_cmd_construct_state {
+ HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE = 0,
+ HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING = 1,
+ HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT = 2,
+ HALMAC_CFG_PARA_CMD_CONSTRUCT_NUM = 3,
+ HALMAC_CFG_PARA_CMD_CONSTRUCT_UNDEFINED = 0x7F,
+};
+
+enum halmac_scan_cmd_construct_state {
+ HALMAC_SCAN_CMD_CONSTRUCT_IDLE = 0,
+ HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED = 1,
+ HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING = 2,
+ HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT = 3,
+ HALMAC_SCAN_CMD_CONSTRUCT_STATE_NUM = 4,
+ HALMAC_SCAN_CMD_CONSTRUCT_UNDEFINED = 0x7F,
+};
+
+enum halmac_api_state {
+ HALMAC_API_STATE_INIT = 0,
+ HALMAC_API_STATE_HALT = 1,
+ HALMAC_API_STATE_UNDEFINED = 0x7F,
+};
+
+struct halmac_efuse_state_set {
+ enum halmac_efuse_cmd_construct_state efuse_cmd_construct_state;
+ enum halmac_cmd_process_status process_status;
+ u8 fw_return_code;
+ u16 seq_num;
+};
+
+struct halmac_cfg_para_state_set {
+ enum halmac_cfg_para_cmd_construct_state cfg_para_cmd_construct_state;
+ enum halmac_cmd_process_status process_status;
+ u8 fw_return_code;
+ u16 seq_num;
+};
+
+struct halmac_scan_state_set {
+ enum halmac_scan_cmd_construct_state scan_cmd_construct_state;
+ enum halmac_cmd_process_status process_status;
+ u8 fw_return_code;
+ u16 seq_num;
+};
+
+struct halmac_update_packet_state_set {
+ enum halmac_cmd_process_status process_status;
+ u8 fw_return_code;
+ u16 seq_num;
+};
+
+struct halmac_iqk_state_set {
+ enum halmac_cmd_process_status process_status;
+ u8 fw_return_code;
+ u16 seq_num;
+};
+
+struct halmac_power_tracking_state_set {
+ enum halmac_cmd_process_status process_status;
+ u8 fw_return_code;
+ u16 seq_num;
+};
+
+struct halmac_psd_state_set {
+ enum halmac_cmd_process_status process_status;
+ u16 data_size;
+ u16 segment_size;
+ u8 *data;
+ u8 fw_return_code;
+ u16 seq_num;
+};
+
+struct halmac_state {
+ struct halmac_efuse_state_set
+ efuse_state_set; /* State machine + cmd process status */
+ struct halmac_cfg_para_state_set
+ cfg_para_state_set; /* State machine + cmd process status */
+ struct halmac_scan_state_set
+ scan_state_set; /* State machine + cmd process status */
+ struct halmac_update_packet_state_set
+ update_packet_set; /* cmd process status */
+ struct halmac_iqk_state_set iqk_set; /* cmd process status */
+ struct halmac_power_tracking_state_set
+ power_tracking_set; /* cmd process status */
+ struct halmac_psd_state_set psd_set; /* cmd process status */
+ enum halmac_api_state api_state; /* Halmac api state */
+ enum halmac_mac_power mac_power; /* 0 : power off, 1 : power on*/
+ enum halmac_ps_state ps_state; /* power saving state */
+ enum halmac_dlfw_state dlfw_state; /* download FW state */
+};
+
+struct halmac_ver {
+ u8 major_ver;
+ u8 prototype_ver;
+ u8 minor_ver;
+};
+
+enum halmac_api_id {
+ /*stuff, need to be the 1st*/
+ HALMAC_API_STUFF = 0x0,
+ /*stuff, need to be the 1st*/
+ HALMAC_API_MAC_POWER_SWITCH = 0x1,
+ HALMAC_API_DOWNLOAD_FIRMWARE = 0x2,
+ HALMAC_API_CFG_MAC_ADDR = 0x3,
+ HALMAC_API_CFG_BSSID = 0x4,
+ HALMAC_API_CFG_MULTICAST_ADDR = 0x5,
+ HALMAC_API_PRE_INIT_SYSTEM_CFG = 0x6,
+ HALMAC_API_INIT_SYSTEM_CFG = 0x7,
+ HALMAC_API_INIT_TRX_CFG = 0x8,
+ HALMAC_API_CFG_RX_AGGREGATION = 0x9,
+ HALMAC_API_INIT_PROTOCOL_CFG = 0xA,
+ HALMAC_API_INIT_EDCA_CFG = 0xB,
+ HALMAC_API_CFG_OPERATION_MODE = 0xC,
+ HALMAC_API_CFG_CH_BW = 0xD,
+ HALMAC_API_CFG_BW = 0xE,
+ HALMAC_API_INIT_WMAC_CFG = 0xF,
+ HALMAC_API_INIT_MAC_CFG = 0x10,
+ HALMAC_API_INIT_SDIO_CFG = 0x11,
+ HALMAC_API_INIT_USB_CFG = 0x12,
+ HALMAC_API_INIT_PCIE_CFG = 0x13,
+ HALMAC_API_INIT_INTERFACE_CFG = 0x14,
+ HALMAC_API_DEINIT_SDIO_CFG = 0x15,
+ HALMAC_API_DEINIT_USB_CFG = 0x16,
+ HALMAC_API_DEINIT_PCIE_CFG = 0x17,
+ HALMAC_API_DEINIT_INTERFACE_CFG = 0x18,
+ HALMAC_API_GET_EFUSE_SIZE = 0x19,
+ HALMAC_API_DUMP_EFUSE_MAP = 0x1A,
+ HALMAC_API_WRITE_EFUSE = 0x1B,
+ HALMAC_API_READ_EFUSE = 0x1C,
+ HALMAC_API_GET_LOGICAL_EFUSE_SIZE = 0x1D,
+ HALMAC_API_DUMP_LOGICAL_EFUSE_MAP = 0x1E,
+ HALMAC_API_WRITE_LOGICAL_EFUSE = 0x1F,
+ HALMAC_API_READ_LOGICAL_EFUSE = 0x20,
+ HALMAC_API_PG_EFUSE_BY_MAP = 0x21,
+ HALMAC_API_GET_C2H_INFO = 0x22,
+ HALMAC_API_CFG_FWLPS_OPTION = 0x23,
+ HALMAC_API_CFG_FWIPS_OPTION = 0x24,
+ HALMAC_API_ENTER_WOWLAN = 0x25,
+ HALMAC_API_LEAVE_WOWLAN = 0x26,
+ HALMAC_API_ENTER_PS = 0x27,
+ HALMAC_API_LEAVE_PS = 0x28,
+ HALMAC_API_H2C_LB = 0x29,
+ HALMAC_API_DEBUG = 0x2A,
+ HALMAC_API_CFG_PARAMETER = 0x2B,
+ HALMAC_API_UPDATE_PACKET = 0x2C,
+ HALMAC_API_BCN_IE_FILTER = 0x2D,
+ HALMAC_API_REG_READ_8 = 0x2E,
+ HALMAC_API_REG_WRITE_8 = 0x2F,
+ HALMAC_API_REG_READ_16 = 0x30,
+ HALMAC_API_REG_WRITE_16 = 0x31,
+ HALMAC_API_REG_READ_32 = 0x32,
+ HALMAC_API_REG_WRITE_32 = 0x33,
+ HALMAC_API_TX_ALLOWED_SDIO = 0x34,
+ HALMAC_API_SET_BULKOUT_NUM = 0x35,
+ HALMAC_API_GET_SDIO_TX_ADDR = 0x36,
+ HALMAC_API_GET_USB_BULKOUT_ID = 0x37,
+ HALMAC_API_TIMER_2S = 0x38,
+ HALMAC_API_FILL_TXDESC_CHECKSUM = 0x39,
+ HALMAC_API_SEND_ORIGINAL_H2C = 0x3A,
+ HALMAC_API_UPDATE_DATAPACK = 0x3B,
+ HALMAC_API_RUN_DATAPACK = 0x3C,
+ HALMAC_API_CFG_DRV_INFO = 0x3D,
+ HALMAC_API_SEND_BT_COEX = 0x3E,
+ HALMAC_API_VERIFY_PLATFORM_API = 0x3F,
+ HALMAC_API_GET_FIFO_SIZE = 0x40,
+ HALMAC_API_DUMP_FIFO = 0x41,
+ HALMAC_API_CFG_TXBF = 0x42,
+ HALMAC_API_CFG_MUMIMO = 0x43,
+ HALMAC_API_CFG_SOUNDING = 0x44,
+ HALMAC_API_DEL_SOUNDING = 0x45,
+ HALMAC_API_SU_BFER_ENTRY_INIT = 0x46,
+ HALMAC_API_SU_BFEE_ENTRY_INIT = 0x47,
+ HALMAC_API_MU_BFER_ENTRY_INIT = 0x48,
+ HALMAC_API_MU_BFEE_ENTRY_INIT = 0x49,
+ HALMAC_API_SU_BFER_ENTRY_DEL = 0x4A,
+ HALMAC_API_SU_BFEE_ENTRY_DEL = 0x4B,
+ HALMAC_API_MU_BFER_ENTRY_DEL = 0x4C,
+ HALMAC_API_MU_BFEE_ENTRY_DEL = 0x4D,
+
+ HALMAC_API_ADD_CH_INFO = 0x4E,
+ HALMAC_API_ADD_EXTRA_CH_INFO = 0x4F,
+ HALMAC_API_CTRL_CH_SWITCH = 0x50,
+ HALMAC_API_CLEAR_CH_INFO = 0x51,
+
+ HALMAC_API_SEND_GENERAL_INFO = 0x52,
+ HALMAC_API_START_IQK = 0x53,
+ HALMAC_API_CTRL_PWR_TRACKING = 0x54,
+ HALMAC_API_PSD = 0x55,
+ HALMAC_API_CFG_TX_AGG_ALIGN = 0x56,
+
+ HALMAC_API_QUERY_STATE = 0x57,
+ HALMAC_API_RESET_FEATURE = 0x58,
+ HALMAC_API_CHECK_FW_STATUS = 0x59,
+ HALMAC_API_DUMP_FW_DMEM = 0x5A,
+ HALMAC_API_CFG_MAX_DL_SIZE = 0x5B,
+
+ HALMAC_API_INIT_OBJ = 0x5C,
+ HALMAC_API_DEINIT_OBJ = 0x5D,
+ HALMAC_API_CFG_LA_MODE = 0x5E,
+ HALMAC_API_GET_HW_VALUE = 0x5F,
+ HALMAC_API_SET_HW_VALUE = 0x60,
+ HALMAC_API_CFG_DRV_RSVD_PG_NUM = 0x61,
+ HALMAC_API_SWITCH_EFUSE_BANK = 0x62,
+ HALMAC_API_WRITE_EFUSE_BT = 0x63,
+ HALMAC_API_DUMP_EFUSE_MAP_BT = 0x64,
+ HALMAC_API_DL_DRV_RSVD_PG = 0x65,
+ HALMAC_API_PCIE_SWITCH = 0x66,
+ HALMAC_API_PHY_CFG = 0x67,
+ HALMAC_API_CFG_RX_FIFO_EXPANDING_MODE = 0x68,
+ HALMAC_API_CFG_CSI_RATE = 0x69,
+ HALMAC_API_MAX
+};
+
+struct halmac_api_record {
+ enum halmac_api_id api_array[API_ARRAY_SIZE];
+ u8 array_wptr;
+};
+
+enum halmac_la_mode {
+ HALMAC_LA_MODE_DISABLE = 0,
+ HALMAC_LA_MODE_PARTIAL = 1,
+ HALMAC_LA_MODE_FULL = 2,
+ HALMAC_LA_MODE_UNDEFINE = 0x7F,
+};
+
+enum halmac_rx_fifo_expanding_mode {
+ HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE = 0,
+ HALMAC_RX_FIFO_EXPANDING_MODE_1_BLOCK = 1,
+ HALMAC_RX_FIFO_EXPANDING_MODE_2_BLOCK = 2,
+ HALMAC_RX_FIFO_EXPANDING_MODE_3_BLOCK = 3,
+ HALMAC_RX_FIFO_EXPANDING_MODE_UNDEFINE = 0x7F,
+};
+
+enum halmac_sdio_cmd53_4byte_mode {
+ HALMAC_SDIO_CMD53_4BYTE_MODE_DISABLE = 0,
+ HALMAC_SDIO_CMD53_4BYTE_MODE_RW = 1,
+ HALMAC_SDIO_CMD53_4BYTE_MODE_R = 2,
+ HALMAC_SDIO_CMD53_4BYTE_MODE_W = 3,
+ HALMAC_SDIO_CMD53_4BYTE_MODE_UNDEFINE = 0x7F,
+};
+
+enum halmac_usb_mode {
+ HALMAC_USB_MODE_U2 = 1,
+ HALMAC_USB_MODE_U3 = 2,
+};
+
+enum halmac_hw_id {
+ /* Get HW value */
+ HALMAC_HW_RQPN_MAPPING = 0x00,
+ HALMAC_HW_EFUSE_SIZE = 0x01,
+ HALMAC_HW_EEPROM_SIZE = 0x02,
+ HALMAC_HW_BT_BANK_EFUSE_SIZE = 0x03,
+ HALMAC_HW_BT_BANK1_EFUSE_SIZE = 0x04,
+ HALMAC_HW_BT_BANK2_EFUSE_SIZE = 0x05,
+ HALMAC_HW_TXFIFO_SIZE = 0x06,
+ HALMAC_HW_RSVD_PG_BNDY = 0x07,
+ HALMAC_HW_CAM_ENTRY_NUM = 0x08,
+ HALMAC_HW_IC_VERSION = 0x09,
+ HALMAC_HW_PAGE_SIZE = 0x0A,
+ HALMAC_HW_TX_AGG_ALIGN_SIZE = 0x0B,
+ HALMAC_HW_RX_AGG_ALIGN_SIZE = 0x0C,
+ HALMAC_HW_DRV_INFO_SIZE = 0x0D,
+ HALMAC_HW_TXFF_ALLOCATION = 0x0E,
+ HALMAC_HW_RSVD_EFUSE_SIZE = 0x0F,
+ HALMAC_HW_FW_HDR_SIZE = 0x10,
+ HALMAC_HW_TX_DESC_SIZE = 0x11,
+ HALMAC_HW_RX_DESC_SIZE = 0x12,
+ HALMAC_HW_WLAN_EFUSE_AVAILABLE_SIZE = 0x13,
+ /* Set HW value */
+ HALMAC_HW_USB_MODE = 0x60,
+ HALMAC_HW_SEQ_EN = 0x61,
+ HALMAC_HW_BANDWIDTH = 0x62,
+ HALMAC_HW_CHANNEL = 0x63,
+ HALMAC_HW_PRI_CHANNEL_IDX = 0x64,
+ HALMAC_HW_EN_BB_RF = 0x65,
+ HALMAC_HW_SDIO_TX_PAGE_THRESHOLD = 0x66,
+ HALMAC_HW_AMPDU_CONFIG = 0x67,
+
+ HALMAC_HW_ID_UNDEFINE = 0x7F,
+};
+
+enum halmac_efuse_bank {
+ HALMAC_EFUSE_BANK_WIFI = 0,
+ HALMAC_EFUSE_BANK_BT = 1,
+ HALMAC_EFUSE_BANK_BT_1 = 2,
+ HALMAC_EFUSE_BANK_BT_2 = 3,
+ HALMAC_EFUSE_BANK_MAX,
+ HALMAC_EFUSE_BANK_UNDEFINE = 0X7F,
+};
+
+struct halmac_txff_allocation {
+ u16 tx_fifo_pg_num;
+ u16 rsvd_pg_num;
+ u16 rsvd_drv_pg_num;
+ u16 ac_q_pg_num;
+ u16 high_queue_pg_num;
+ u16 low_queue_pg_num;
+ u16 normal_queue_pg_num;
+ u16 extra_queue_pg_num;
+ u16 pub_queue_pg_num;
+ u16 rsvd_pg_bndy;
+ u16 rsvd_drv_pg_bndy;
+ u16 rsvd_h2c_extra_info_pg_bndy;
+ u16 rsvd_h2c_queue_pg_bndy;
+ u16 rsvd_cpu_instr_pg_bndy;
+ u16 rsvd_fw_txbuff_pg_bndy;
+ enum halmac_la_mode la_mode;
+ enum halmac_rx_fifo_expanding_mode rx_fifo_expanding_mode;
+};
+
+struct halmac_rqpn_map {
+ enum halmac_dma_mapping dma_map_vo;
+ enum halmac_dma_mapping dma_map_vi;
+ enum halmac_dma_mapping dma_map_be;
+ enum halmac_dma_mapping dma_map_bk;
+ enum halmac_dma_mapping dma_map_mg;
+ enum halmac_dma_mapping dma_map_hi;
+};
+
+struct halmac_security_setting {
+ u8 tx_encryption;
+ u8 rx_decryption;
+ u8 bip_enable;
+};
+
+struct halmac_cam_entry_info {
+ enum hal_security_type security_type;
+ u32 key[4];
+ u32 key_ext[4];
+ u8 mac_address[6];
+ u8 unicast;
+ u8 key_id;
+ u8 valid;
+};
+
+struct halmac_cam_entry_format {
+ u16 key_id : 2;
+ u16 type : 3;
+ u16 mic : 1;
+ u16 grp : 1;
+ u16 spp_mode : 1;
+ u16 rpt_md : 1;
+ u16 ext_sectype : 1;
+ u16 mgnt : 1;
+ u16 rsvd1 : 4;
+ u16 valid : 1;
+ u8 mac_address[6];
+ u32 key[4];
+ u32 rsvd[2];
+};
+
+struct halmac_tx_page_threshold_info {
+ u32 threshold;
+ enum halmac_dma_mapping dma_queue_sel;
+};
+
+struct halmac_ampdu_config {
+ u8 max_agg_num;
+};
+
+struct halmac_port_cfg {
+ u8 port0_sync_tsf;
+ u8 port1_sync_tsf;
+};
+
+struct halmac_rqpn_ {
+ enum halmac_trx_mode mode;
+ enum halmac_dma_mapping dma_map_vo;
+ enum halmac_dma_mapping dma_map_vi;
+ enum halmac_dma_mapping dma_map_be;
+ enum halmac_dma_mapping dma_map_bk;
+ enum halmac_dma_mapping dma_map_mg;
+ enum halmac_dma_mapping dma_map_hi;
+};
+
+struct halmac_pg_num_ {
+ enum halmac_trx_mode mode;
+ u16 hq_num;
+ u16 nq_num;
+ u16 lq_num;
+ u16 exq_num;
+ u16 gap_num; /*used for loopback mode*/
+};
+
+struct halmac_intf_phy_para_ {
+ u16 offset;
+ u16 value;
+ u16 ip_sel;
+ u16 cut;
+ u16 plaform;
+};
+
+struct halmac_iqk_para_ {
+ u8 clear;
+ u8 segment_iqk;
+};
+
+/* Hal mac adapter */
+struct halmac_adapter {
+ /* Dma mapping of protocol queues */
+ enum halmac_dma_mapping halmac_ptcl_queue[HALMAC_PTCL_QUEUE_NUM];
+ /* low power state option */
+ struct halmac_fwlps_option fwlps_option;
+ /* mac address information, suppot 2 ports */
+ union halmac_wlan_addr hal_mac_addr[HALMAC_PORTIDMAX];
+ /* bss address information, suppot 2 ports */
+ union halmac_wlan_addr hal_bss_addr[HALMAC_PORTIDMAX];
+ /* Protect h2c_packet_seq packet*/
+ spinlock_t h2c_seq_lock;
+ /* Protect Efuse map memory of halmac_adapter */
+ spinlock_t efuse_lock;
+ struct halmac_config_para_info config_para_info;
+ struct halmac_cs_info ch_sw_info;
+ struct halmac_event_trigger event_trigger;
+ /* HW related information */
+ struct halmac_hw_config_info hw_config_info;
+ struct halmac_sdio_free_space sdio_free_space;
+ struct halmac_snd_info snd_info;
+ /* Backup HalAdapter address */
+ void *hal_adapter_backup;
+ /* Driver or FW adapter address. Do not write this memory*/
+ void *driver_adapter;
+ u8 *hal_efuse_map;
+ /* Record function pointer of halmac api */
+ void *halmac_api;
+ /* Record function pointer of platform api */
+ struct halmac_platform_api *halmac_platform_api;
+ /* Record efuse used memory */
+ u32 efuse_end;
+ u32 h2c_buf_free_space;
+ u32 h2c_buff_size;
+ u32 max_download_size;
+ /* Chip ID, 8822B, 8821C... */
+ enum halmac_chip_id chip_id;
+ /* A cut, B cut... */
+ enum halmac_chip_ver chip_version;
+ struct halmac_fw_version fw_version;
+ struct halmac_state halmac_state;
+ /* Interface information, get from driver */
+ enum halmac_interface halmac_interface;
+ /* Noraml, WMM, P2P, LoopBack... */
+ enum halmac_trx_mode trx_mode;
+ struct halmac_txff_allocation txff_allocation;
+ u8 h2c_packet_seq; /* current h2c packet sequence number */
+ u16 ack_h2c_packet_seq; /*the acked h2c packet sequence number */
+ bool hal_efuse_map_valid;
+ u8 efuse_segment_size;
+ u8 rpwm_record; /* record rpwm value */
+ bool low_clk; /*LPS 32K or IPS 32K*/
+ u8 halmac_bulkout_num; /* USB bulkout num */
+ struct halmac_api_record api_record; /* API record */
+ bool gen_info_valid;
+ struct halmac_general_info general_info;
+ u8 drv_info_size;
+ enum halmac_sdio_cmd53_4byte_mode sdio_cmd53_4byte;
+};
+
+/* Function pointer of Hal mac API */
+struct halmac_api {
+ enum halmac_ret_status (*halmac_mac_power_switch)(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_mac_power halmac_power);
+ enum halmac_ret_status (*halmac_download_firmware)(
+ struct halmac_adapter *halmac_adapter, u8 *hamacl_fw,
+ u32 halmac_fw_size);
+ enum halmac_ret_status (*halmac_free_download_firmware)(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_dlfw_mem dlfw_mem, u8 *hamacl_fw,
+ u32 halmac_fw_size);
+ enum halmac_ret_status (*halmac_get_fw_version)(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_fw_version *fw_version);
+ enum halmac_ret_status (*halmac_cfg_mac_addr)(
+ struct halmac_adapter *halmac_adapter, u8 halmac_port,
+ union halmac_wlan_addr *hal_address);
+ enum halmac_ret_status (*halmac_cfg_bssid)(
+ struct halmac_adapter *halmac_adapter, u8 halmac_port,
+ union halmac_wlan_addr *hal_address);
+ enum halmac_ret_status (*halmac_cfg_multicast_addr)(
+ struct halmac_adapter *halmac_adapter,
+ union halmac_wlan_addr *hal_address);
+ enum halmac_ret_status (*halmac_pre_init_system_cfg)(
+ struct halmac_adapter *halmac_adapter);
+ enum halmac_ret_status (*halmac_init_system_cfg)(
+ struct halmac_adapter *halmac_adapter);
+ enum halmac_ret_status (*halmac_init_trx_cfg)(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_trx_mode mode);
+ enum halmac_ret_status (*halmac_init_h2c)(
+ struct halmac_adapter *halmac_adapter);
+ enum halmac_ret_status (*halmac_cfg_rx_aggregation)(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_rxagg_cfg *phalmac_rxagg_cfg);
+ enum halmac_ret_status (*halmac_init_protocol_cfg)(
+ struct halmac_adapter *halmac_adapter);
+ enum halmac_ret_status (*halmac_init_edca_cfg)(
+ struct halmac_adapter *halmac_adapter);
+ enum halmac_ret_status (*halmac_cfg_operation_mode)(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_wireless_mode wireless_mode);
+ enum halmac_ret_status (*halmac_cfg_ch_bw)(
+ struct halmac_adapter *halmac_adapter, u8 channel,
+ enum halmac_pri_ch_idx pri_ch_idx, enum halmac_bw bw);
+ enum halmac_ret_status (*halmac_cfg_bw)(
+ struct halmac_adapter *halmac_adapter, enum halmac_bw bw);
+ enum halmac_ret_status (*halmac_init_wmac_cfg)(
+ struct halmac_adapter *halmac_adapter);
+ enum halmac_ret_status (*halmac_init_mac_cfg)(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_trx_mode mode);
+ enum halmac_ret_status (*halmac_init_sdio_cfg)(
+ struct halmac_adapter *halmac_adapter);
+ enum halmac_ret_status (*halmac_init_usb_cfg)(
+ struct halmac_adapter *halmac_adapter);
+ enum halmac_ret_status (*halmac_init_pcie_cfg)(
+ struct halmac_adapter *halmac_adapter);
+ enum halmac_ret_status (*halmac_init_interface_cfg)(
+ struct halmac_adapter *halmac_adapter);
+ enum halmac_ret_status (*halmac_deinit_sdio_cfg)(
+ struct halmac_adapter *halmac_adapter);
+ enum halmac_ret_status (*halmac_deinit_usb_cfg)(
+ struct halmac_adapter *halmac_adapter);
+ enum halmac_ret_status (*halmac_deinit_pcie_cfg)(
+ struct halmac_adapter *halmac_adapter);
+ enum halmac_ret_status (*halmac_deinit_interface_cfg)(
+ struct halmac_adapter *halmac_adapter);
+ enum halmac_ret_status (*halmac_get_efuse_size)(
+ struct halmac_adapter *halmac_adapter, u32 *halmac_size);
+ enum halmac_ret_status (*halmac_get_efuse_available_size)(
+ struct halmac_adapter *halmac_adapter, u32 *halmac_size);
+ enum halmac_ret_status (*halmac_dump_efuse_map)(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_efuse_read_cfg cfg);
+ enum halmac_ret_status (*halmac_dump_efuse_map_bt)(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_efuse_bank halmac_efues_bank, u32 bt_efuse_map_size,
+ u8 *bt_efuse_map);
+ enum halmac_ret_status (*halmac_write_efuse)(
+ struct halmac_adapter *halmac_adapter, u32 halmac_offset,
+ u8 halmac_value);
+ enum halmac_ret_status (*halmac_read_efuse)(
+ struct halmac_adapter *halmac_adapter, u32 halmac_offset,
+ u8 *value);
+ enum halmac_ret_status (*halmac_switch_efuse_bank)(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_efuse_bank halmac_efues_bank);
+ enum halmac_ret_status (*halmac_write_efuse_bt)(
+ struct halmac_adapter *halmac_adapter, u32 halmac_offset,
+ u8 halmac_value, enum halmac_efuse_bank halmac_efues_bank);
+ enum halmac_ret_status (*halmac_get_logical_efuse_size)(
+ struct halmac_adapter *halmac_adapter, u32 *halmac_size);
+ enum halmac_ret_status (*halmac_dump_logical_efuse_map)(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_efuse_read_cfg cfg);
+ enum halmac_ret_status (*halmac_write_logical_efuse)(
+ struct halmac_adapter *halmac_adapter, u32 halmac_offset,
+ u8 halmac_value);
+ enum halmac_ret_status (*halmac_read_logical_efuse)(
+ struct halmac_adapter *halmac_adapter, u32 halmac_offset,
+ u8 *value);
+ enum halmac_ret_status (*halmac_pg_efuse_by_map)(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_pg_efuse_info *pg_efuse_info,
+ enum halmac_efuse_read_cfg cfg);
+ enum halmac_ret_status (*halmac_get_c2h_info)(
+ struct halmac_adapter *halmac_adapter, u8 *halmac_buf,
+ u32 halmac_size);
+ enum halmac_ret_status (*halmac_cfg_fwlps_option)(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_fwlps_option *lps_option);
+ enum halmac_ret_status (*halmac_cfg_fwips_option)(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_fwips_option *ips_option);
+ enum halmac_ret_status (*halmac_enter_wowlan)(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_wowlan_option *wowlan_option);
+ enum halmac_ret_status (*halmac_leave_wowlan)(
+ struct halmac_adapter *halmac_adapter);
+ enum halmac_ret_status (*halmac_enter_ps)(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_ps_state ps_state);
+ enum halmac_ret_status (*halmac_leave_ps)(
+ struct halmac_adapter *halmac_adapter);
+ enum halmac_ret_status (*halmac_h2c_lb)(
+ struct halmac_adapter *halmac_adapter);
+ enum halmac_ret_status (*halmac_debug)(
+ struct halmac_adapter *halmac_adapter);
+ enum halmac_ret_status (*halmac_cfg_parameter)(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_phy_parameter_info *para_info, u8 full_fifo);
+ enum halmac_ret_status (*halmac_update_packet)(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_packet_id pkt_id, u8 *pkt, u32 pkt_size);
+ enum halmac_ret_status (*halmac_bcn_ie_filter)(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_bcn_ie_info *bcn_ie_info);
+ u8 (*halmac_reg_read_8)(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset);
+ enum halmac_ret_status (*halmac_reg_write_8)(
+ struct halmac_adapter *halmac_adapter, u32 halmac_offset,
+ u8 halmac_data);
+ u16 (*halmac_reg_read_16)(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset);
+ enum halmac_ret_status (*halmac_reg_write_16)(
+ struct halmac_adapter *halmac_adapter, u32 halmac_offset,
+ u16 halmac_data);
+ u32 (*halmac_reg_read_32)(struct halmac_adapter *halmac_adapter,
+ u32 halmac_offset);
+ u32 (*halmac_reg_read_indirect_32)(
+ struct halmac_adapter *halmac_adapter, u32 halmac_offset);
+ u8 (*halmac_reg_sdio_cmd53_read_n)(
+ struct halmac_adapter *halmac_adapter, u32 halmac_offset,
+ u32 halmac_size, u8 *halmac_data);
+ enum halmac_ret_status (*halmac_reg_write_32)(
+ struct halmac_adapter *halmac_adapter, u32 halmac_offset,
+ u32 halmac_data);
+ enum halmac_ret_status (*halmac_tx_allowed_sdio)(
+ struct halmac_adapter *halmac_adapter, u8 *halmac_buf,
+ u32 halmac_size);
+ enum halmac_ret_status (*halmac_set_bulkout_num)(
+ struct halmac_adapter *halmac_adapter, u8 bulkout_num);
+ enum halmac_ret_status (*halmac_get_sdio_tx_addr)(
+ struct halmac_adapter *halmac_adapter, u8 *halmac_buf,
+ u32 halmac_size, u32 *pcmd53_addr);
+ enum halmac_ret_status (*halmac_get_usb_bulkout_id)(
+ struct halmac_adapter *halmac_adapter, u8 *halmac_buf,
+ u32 halmac_size, u8 *bulkout_id);
+ enum halmac_ret_status (*halmac_timer_2s)(
+ struct halmac_adapter *halmac_adapter);
+ enum halmac_ret_status (*halmac_fill_txdesc_checksum)(
+ struct halmac_adapter *halmac_adapter, u8 *cur_desc);
+ enum halmac_ret_status (*halmac_update_datapack)(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_data_type halmac_data_type,
+ struct halmac_phy_parameter_info *para_info);
+ enum halmac_ret_status (*halmac_run_datapack)(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_data_type halmac_data_type);
+ enum halmac_ret_status (*halmac_cfg_drv_info)(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_drv_info halmac_drv_info);
+ enum halmac_ret_status (*halmac_send_bt_coex)(
+ struct halmac_adapter *halmac_adapter, u8 *bt_buf, u32 bt_size,
+ u8 ack);
+ enum halmac_ret_status (*halmac_verify_platform_api)(
+ struct halmac_adapter *halmac_adapte);
+ u32 (*halmac_get_fifo_size)(struct halmac_adapter *halmac_adapter,
+ enum hal_fifo_sel halmac_fifo_sel);
+ enum halmac_ret_status (*halmac_dump_fifo)(
+ struct halmac_adapter *halmac_adapter,
+ enum hal_fifo_sel halmac_fifo_sel, u32 halmac_start_addr,
+ u32 halmac_fifo_dump_size, u8 *fifo_map);
+ enum halmac_ret_status (*halmac_cfg_txbf)(
+ struct halmac_adapter *halmac_adapter, u8 userid,
+ enum halmac_bw bw, u8 txbf_en);
+ enum halmac_ret_status (*halmac_cfg_mumimo)(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_cfg_mumimo_para *cfgmu);
+ enum halmac_ret_status (*halmac_cfg_sounding)(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_snd_role role, enum halmac_data_rate datarate);
+ enum halmac_ret_status (*halmac_del_sounding)(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_snd_role role);
+ enum halmac_ret_status (*halmac_su_bfer_entry_init)(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_su_bfer_init_para *su_bfer_init);
+ enum halmac_ret_status (*halmac_su_bfee_entry_init)(
+ struct halmac_adapter *halmac_adapter, u8 userid, u16 paid);
+ enum halmac_ret_status (*halmac_mu_bfer_entry_init)(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_mu_bfer_init_para *mu_bfer_init);
+ enum halmac_ret_status (*halmac_mu_bfee_entry_init)(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_mu_bfee_init_para *mu_bfee_init);
+ enum halmac_ret_status (*halmac_su_bfer_entry_del)(
+ struct halmac_adapter *halmac_adapter, u8 userid);
+ enum halmac_ret_status (*halmac_su_bfee_entry_del)(
+ struct halmac_adapter *halmac_adapter, u8 userid);
+ enum halmac_ret_status (*halmac_mu_bfer_entry_del)(
+ struct halmac_adapter *halmac_adapter);
+ enum halmac_ret_status (*halmac_mu_bfee_entry_del)(
+ struct halmac_adapter *halmac_adapter, u8 userid);
+ enum halmac_ret_status (*halmac_add_ch_info)(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_ch_info *ch_info);
+ enum halmac_ret_status (*halmac_add_extra_ch_info)(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_ch_extra_info *ch_extra_info);
+ enum halmac_ret_status (*halmac_ctrl_ch_switch)(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_ch_switch_option *cs_option);
+ enum halmac_ret_status (*halmac_p2pps)(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_p2pps *p2p_ps);
+ enum halmac_ret_status (*halmac_clear_ch_info)(
+ struct halmac_adapter *halmac_adapter);
+ enum halmac_ret_status (*halmac_send_general_info)(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_general_info *pg_general_info);
+ enum halmac_ret_status (*halmac_start_iqk)(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_iqk_para_ *iqk_para);
+ enum halmac_ret_status (*halmac_ctrl_pwr_tracking)(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_pwr_tracking_option *pwr_tracking_opt);
+ enum halmac_ret_status (*halmac_psd)(
+ struct halmac_adapter *halmac_adapter, u16 start_psd,
+ u16 end_psd);
+ enum halmac_ret_status (*halmac_cfg_tx_agg_align)(
+ struct halmac_adapter *halmac_adapter, u8 enable,
+ u16 align_size);
+ enum halmac_ret_status (*halmac_query_status)(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_feature_id feature_id,
+ enum halmac_cmd_process_status *process_status, u8 *data,
+ u32 *size);
+ enum halmac_ret_status (*halmac_reset_feature)(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_feature_id feature_id);
+ enum halmac_ret_status (*halmac_check_fw_status)(
+ struct halmac_adapter *halmac_adapter, bool *fw_status);
+ enum halmac_ret_status (*halmac_dump_fw_dmem)(
+ struct halmac_adapter *halmac_adapter, u8 *dmem, u32 *size);
+ enum halmac_ret_status (*halmac_cfg_max_dl_size)(
+ struct halmac_adapter *halmac_adapter, u32 size);
+ enum halmac_ret_status (*halmac_cfg_la_mode)(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_la_mode la_mode);
+ enum halmac_ret_status (*halmac_cfg_rx_fifo_expanding_mode)(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_rx_fifo_expanding_mode rx_fifo_expanding_mode);
+ enum halmac_ret_status (*halmac_config_security)(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_security_setting *sec_setting);
+ u8 (*halmac_get_used_cam_entry_num)(
+ struct halmac_adapter *halmac_adapter,
+ enum hal_security_type sec_type);
+ enum halmac_ret_status (*halmac_write_cam)(
+ struct halmac_adapter *halmac_adapter, u32 entry_index,
+ struct halmac_cam_entry_info *cam_entry_info);
+ enum halmac_ret_status (*halmac_read_cam_entry)(
+ struct halmac_adapter *halmac_adapter, u32 entry_index,
+ struct halmac_cam_entry_format *content);
+ enum halmac_ret_status (*halmac_clear_cam_entry)(
+ struct halmac_adapter *halmac_adapter, u32 entry_index);
+ enum halmac_ret_status (*halmac_get_hw_value)(
+ struct halmac_adapter *halmac_adapter, enum halmac_hw_id hw_id,
+ void *pvalue);
+ enum halmac_ret_status (*halmac_set_hw_value)(
+ struct halmac_adapter *halmac_adapter, enum halmac_hw_id hw_id,
+ void *pvalue);
+ enum halmac_ret_status (*halmac_cfg_drv_rsvd_pg_num)(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_drv_rsvd_pg_num pg_num);
+ enum halmac_ret_status (*halmac_get_chip_version)(
+ struct halmac_adapter *halmac_adapter,
+ struct halmac_ver *version);
+ enum halmac_ret_status (*halmac_chk_txdesc)(
+ struct halmac_adapter *halmac_adapter, u8 *halmac_buf,
+ u32 halmac_size);
+ enum halmac_ret_status (*halmac_dl_drv_rsvd_page)(
+ struct halmac_adapter *halmac_adapter, u8 pg_offset,
+ u8 *hal_buf, u32 size);
+ enum halmac_ret_status (*halmac_pcie_switch)(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_pcie_cfg pcie_cfg);
+ enum halmac_ret_status (*halmac_phy_cfg)(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_intf_phy_platform platform);
+ enum halmac_ret_status (*halmac_cfg_csi_rate)(
+ struct halmac_adapter *halmac_adapter, u8 rssi, u8 current_rate,
+ u8 fixrate_en, u8 *new_rate);
+ enum halmac_ret_status (*halmac_sdio_cmd53_4byte)(
+ struct halmac_adapter *halmac_adapter,
+ enum halmac_sdio_cmd53_4byte_mode cmd53_4byte_mode);
+ enum halmac_ret_status (*halmac_interface_integration_tuning)(
+ struct halmac_adapter *halmac_adapter);
+ enum halmac_ret_status (*halmac_txfifo_is_empty)(
+ struct halmac_adapter *halmac_adapter, u32 chk_num);
+};
+
+#define HALMAC_GET_API(phalmac_adapter) \
+ ((struct halmac_api *)phalmac_adapter->halmac_api)
+
+static inline enum halmac_ret_status
+halmac_adapter_validate(struct halmac_adapter *halmac_adapter)
+{
+ if ((!halmac_adapter) ||
+ (halmac_adapter->hal_adapter_backup != halmac_adapter))
+ return HALMAC_RET_ADAPTER_INVALID;
+
+ return HALMAC_RET_SUCCESS;
+}
+
+static inline enum halmac_ret_status
+halmac_api_validate(struct halmac_adapter *halmac_adapter)
+{
+ if (halmac_adapter->halmac_state.api_state != HALMAC_API_STATE_INIT)
+ return HALMAC_RET_API_INVALID;
+
+ return HALMAC_RET_SUCCESS;
+}
+
+static inline enum halmac_ret_status
+halmac_fw_validate(struct halmac_adapter *halmac_adapter)
+{
+ if (halmac_adapter->halmac_state.dlfw_state != HALMAC_DLFW_DONE &&
+ halmac_adapter->halmac_state.dlfw_state != HALMAC_GEN_INFO_SENT)
+ return HALMAC_RET_NO_DLFW;
+
+ return HALMAC_RET_SUCCESS;
+}
+
+#endif
diff --git a/drivers/staging/rtlwifi/halmac/halmac_usb_reg.h b/drivers/staging/rtlwifi/halmac/halmac_usb_reg.h
new file mode 100644
index 0000000..d6e721e
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/halmac_usb_reg.h
@@ -0,0 +1,28 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __HALMAC_USB_REG_H__
+#define __HALMAC_USB_REG_H__
+
+#endif /* __HALMAC_USB_REG_H__ */
diff --git a/drivers/staging/rtlwifi/halmac/rtl_halmac.c b/drivers/staging/rtlwifi/halmac/rtl_halmac.c
new file mode 100644
index 0000000..6448a8b
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/rtl_halmac.c
@@ -0,0 +1,1384 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "halmac_api.h"
+#include "rtl_halmac.h"
+#include <linux/module.h>
+#include <linux/vmalloc.h>
+
+#define DEFAULT_INDICATOR_TIMELMT msecs_to_jiffies(1000) /* ms */
+#define FIRMWARE_MAX_SIZE HALMAC_FW_SIZE_MAX_88XX
+
+static struct rtl_halmac_ops rtl_halmac_operation = {
+ .halmac_init_adapter = rtl_halmac_init_adapter,
+ .halmac_deinit_adapter = rtl_halmac_deinit_adapter,
+ .halmac_init_hal = rtl_halmac_init_hal,
+ .halmac_deinit_hal = rtl_halmac_deinit_hal,
+ .halmac_poweron = rtl_halmac_poweron,
+ .halmac_poweroff = rtl_halmac_poweroff,
+
+ .halmac_phy_power_switch = rtl_halmac_phy_power_switch,
+ .halmac_set_mac_address = rtl_halmac_set_mac_address,
+ .halmac_set_bssid = rtl_halmac_set_bssid,
+
+ .halmac_get_physical_efuse_size = rtl_halmac_get_physical_efuse_size,
+ .halmac_read_physical_efuse_map = rtl_halmac_read_physical_efuse_map,
+ .halmac_get_logical_efuse_size = rtl_halmac_get_logical_efuse_size,
+ .halmac_read_logical_efuse_map = rtl_halmac_read_logical_efuse_map,
+
+ .halmac_set_bandwidth = rtl_halmac_set_bandwidth,
+
+ .halmac_c2h_handle = rtl_halmac_c2h_handle,
+
+ .halmac_chk_txdesc = rtl_halmac_chk_txdesc,
+};
+
+struct rtl_halmac_ops *rtl_halmac_get_ops_pointer(void)
+{
+ return &rtl_halmac_operation;
+}
+EXPORT_SYMBOL(rtl_halmac_get_ops_pointer);
+
+/*
+ * Driver API for HALMAC operations
+ */
+
+static u8 _halmac_reg_read_8(void *p, u32 offset)
+{
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)p;
+
+ return rtl_read_byte(rtlpriv, offset);
+}
+
+static u16 _halmac_reg_read_16(void *p, u32 offset)
+{
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)p;
+
+ return rtl_read_word(rtlpriv, offset);
+}
+
+static u32 _halmac_reg_read_32(void *p, u32 offset)
+{
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)p;
+
+ return rtl_read_dword(rtlpriv, offset);
+}
+
+static void _halmac_reg_write_8(void *p, u32 offset, u8 val)
+{
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)p;
+
+ rtl_write_byte(rtlpriv, offset, val);
+}
+
+static void _halmac_reg_write_16(void *p, u32 offset, u16 val)
+{
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)p;
+
+ rtl_write_word(rtlpriv, offset, val);
+}
+
+static void _halmac_reg_write_32(void *p, u32 offset, u32 val)
+{
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)p;
+
+ rtl_write_dword(rtlpriv, offset, val);
+}
+
+static bool _halmac_write_data_rsvd_page(void *p, u8 *buf, u32 size)
+{
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)p;
+
+ if (rtlpriv->cfg->ops->halmac_cb_write_data_rsvd_page &&
+ rtlpriv->cfg->ops->halmac_cb_write_data_rsvd_page(rtlpriv, buf,
+ size))
+ return true;
+
+ return false;
+}
+
+static bool _halmac_write_data_h2c(void *p, u8 *buf, u32 size)
+{
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)p;
+
+ if (rtlpriv->cfg->ops->halmac_cb_write_data_h2c &&
+ rtlpriv->cfg->ops->halmac_cb_write_data_h2c(rtlpriv, buf, size))
+ return true;
+
+ return false;
+}
+
+static const char *const RTL_HALMAC_FEATURE_NAME[] = {
+ "HALMAC_FEATURE_CFG_PARA",
+ "HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE",
+ "HALMAC_FEATURE_DUMP_LOGICAL_EFUSE",
+ "HALMAC_FEATURE_UPDATE_PACKET",
+ "HALMAC_FEATURE_UPDATE_DATAPACK",
+ "HALMAC_FEATURE_RUN_DATAPACK",
+ "HALMAC_FEATURE_CHANNEL_SWITCH",
+ "HALMAC_FEATURE_IQK",
+ "HALMAC_FEATURE_POWER_TRACKING",
+ "HALMAC_FEATURE_PSD",
+ "HALMAC_FEATURE_ALL"};
+
+static inline bool is_valid_id_status(struct rtl_priv *rtlpriv,
+ enum halmac_feature_id id,
+ enum halmac_cmd_process_status status)
+{
+ switch (id) {
+ case HALMAC_FEATURE_CFG_PARA:
+ RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
+ RTL_HALMAC_FEATURE_NAME[id]);
+ break;
+ case HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE:
+ RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
+ RTL_HALMAC_FEATURE_NAME[id]);
+ if (status != HALMAC_CMD_PROCESS_DONE) {
+ RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
+ "%s: <WARN> id(%d) unspecified status(%d)!\n",
+ __func__, id, status);
+ }
+ break;
+ case HALMAC_FEATURE_DUMP_LOGICAL_EFUSE:
+ RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
+ RTL_HALMAC_FEATURE_NAME[id]);
+ if (status != HALMAC_CMD_PROCESS_DONE) {
+ RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
+ "%s: <WARN> id(%d) unspecified status(%d)!\n",
+ __func__, id, status);
+ }
+ break;
+ case HALMAC_FEATURE_UPDATE_PACKET:
+ RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
+ RTL_HALMAC_FEATURE_NAME[id]);
+ break;
+ case HALMAC_FEATURE_UPDATE_DATAPACK:
+ RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
+ RTL_HALMAC_FEATURE_NAME[id]);
+ break;
+ case HALMAC_FEATURE_RUN_DATAPACK:
+ RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
+ RTL_HALMAC_FEATURE_NAME[id]);
+ break;
+ case HALMAC_FEATURE_CHANNEL_SWITCH:
+ RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
+ RTL_HALMAC_FEATURE_NAME[id]);
+ break;
+ case HALMAC_FEATURE_IQK:
+ RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
+ RTL_HALMAC_FEATURE_NAME[id]);
+ break;
+ case HALMAC_FEATURE_POWER_TRACKING:
+ RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
+ RTL_HALMAC_FEATURE_NAME[id]);
+ break;
+ case HALMAC_FEATURE_PSD:
+ RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
+ RTL_HALMAC_FEATURE_NAME[id]);
+ break;
+ case HALMAC_FEATURE_ALL:
+ RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
+ RTL_HALMAC_FEATURE_NAME[id]);
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
+ "%s: unknown feature id(%d)\n", __func__, id);
+ return false;
+ }
+
+ return true;
+}
+
+static int init_halmac_event_with_waittime(struct rtl_priv *rtlpriv,
+ enum halmac_feature_id id, u8 *buf,
+ u32 size, u32 time)
+{
+ struct completion *comp;
+
+ if (!rtlpriv->halmac.indicator[id].comp) {
+ comp = kzalloc(sizeof(*comp), GFP_KERNEL);
+ if (!comp)
+ return -1;
+ } else {
+ RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
+ "%s: <WARN> id(%d) sctx is not NULL!!\n", __func__,
+ id);
+ comp = rtlpriv->halmac.indicator[id].comp;
+ rtlpriv->halmac.indicator[id].comp = NULL;
+ }
+
+ init_completion(comp);
+ rtlpriv->halmac.indicator[id].wait_ms = time;
+
+ rtlpriv->halmac.indicator[id].buffer = buf;
+ rtlpriv->halmac.indicator[id].buf_size = size;
+ rtlpriv->halmac.indicator[id].ret_size = 0;
+ rtlpriv->halmac.indicator[id].status = 0;
+ /* fill sctx at least to sure other variables are all ready! */
+ rtlpriv->halmac.indicator[id].comp = comp;
+
+ return 0;
+}
+
+static inline int init_halmac_event(struct rtl_priv *rtlpriv,
+ enum halmac_feature_id id, u8 *buf,
+ u32 size)
+{
+ return init_halmac_event_with_waittime(rtlpriv, id, buf, size,
+ DEFAULT_INDICATOR_TIMELMT);
+}
+
+static void free_halmac_event(struct rtl_priv *rtlpriv,
+ enum halmac_feature_id id)
+{
+ struct completion *comp;
+
+ if (!rtlpriv->halmac.indicator[id].comp)
+ return;
+
+ comp = rtlpriv->halmac.indicator[id].comp;
+ rtlpriv->halmac.indicator[id].comp = NULL;
+ kfree(comp);
+}
+
+static int wait_halmac_event(struct rtl_priv *rtlpriv,
+ enum halmac_feature_id id)
+{
+ struct completion *comp;
+ int ret;
+
+ comp = rtlpriv->halmac.indicator[id].comp;
+ if (!comp)
+ return -1;
+
+ ret = wait_for_completion_timeout(
+ comp, rtlpriv->halmac.indicator[id].wait_ms);
+ free_halmac_event(rtlpriv, id);
+ if (ret > 0)
+ return 0;
+
+ return -1;
+}
+
+/*
+ * Return:
+ * Always return true, HALMAC don't care the return value.
+ */
+static bool
+_halmac_event_indication(void *p, enum halmac_feature_id feature_id,
+ enum halmac_cmd_process_status process_status, u8 *buf,
+ u32 size)
+{
+ struct rtl_priv *rtlpriv;
+ struct rtl_halmac_indicator *tbl, *indicator;
+ struct completion *comp;
+ u32 cpsz;
+ bool ret;
+
+ rtlpriv = (struct rtl_priv *)p;
+ tbl = rtlpriv->halmac.indicator;
+
+ ret = is_valid_id_status(rtlpriv, feature_id, process_status);
+ if (!ret)
+ goto exit;
+
+ indicator = &tbl[feature_id];
+ indicator->status = process_status;
+ indicator->ret_size = size;
+ if (!indicator->comp) {
+ RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
+ "%s: No feature id(%d) waiting!!\n", __func__,
+ feature_id);
+ goto exit;
+ }
+ comp = indicator->comp;
+
+ if (process_status == HALMAC_CMD_PROCESS_ERROR) {
+ RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
+ "%s: Something wrong id(%d)!!\n", __func__,
+ feature_id);
+ complete(comp); /* may provide error code */
+ goto exit;
+ }
+
+ if (size > indicator->buf_size) {
+ RT_TRACE(
+ rtlpriv, COMP_HALMAC, DBG_LOUD,
+ "%s: <WARN> id(%d) buffer is not enough(%d<%d), data will be truncated!\n",
+ __func__, feature_id, indicator->buf_size, size);
+ cpsz = indicator->buf_size;
+ } else {
+ cpsz = size;
+ }
+
+ if (cpsz && indicator->buffer)
+ memcpy(indicator->buffer, buf, cpsz);
+
+ complete(comp);
+
+exit:
+ return true;
+}
+
+static struct halmac_platform_api rtl_halmac_platform_api = {
+ /* R/W register */
+ .REG_READ_8 = _halmac_reg_read_8,
+ .REG_READ_16 = _halmac_reg_read_16,
+ .REG_READ_32 = _halmac_reg_read_32,
+ .REG_WRITE_8 = _halmac_reg_write_8,
+ .REG_WRITE_16 = _halmac_reg_write_16,
+ .REG_WRITE_32 = _halmac_reg_write_32,
+
+ /* Write data */
+ /* impletement in HAL-IC level */
+ .SEND_RSVD_PAGE = _halmac_write_data_rsvd_page,
+ .SEND_H2C_PKT = _halmac_write_data_h2c,
+
+ .EVENT_INDICATION = _halmac_event_indication,
+};
+
+static int init_priv(struct rtl_halmac *halmac)
+{
+ struct rtl_halmac_indicator *indicator;
+ u32 count, size;
+
+ halmac->send_general_info = 0;
+
+ count = HALMAC_FEATURE_ALL + 1;
+ size = sizeof(*indicator) * count;
+ indicator = kzalloc(size, GFP_KERNEL);
+ if (!indicator)
+ return -1;
+ halmac->indicator = indicator;
+
+ return 0;
+}
+
+static void deinit_priv(struct rtl_halmac *halmac)
+{
+ struct rtl_halmac_indicator *indicator;
+
+ indicator = halmac->indicator;
+ halmac->indicator = NULL;
+ kfree(indicator);
+}
+
+int rtl_halmac_init_adapter(struct rtl_priv *rtlpriv)
+{
+ struct halmac_adapter *halmac;
+ struct halmac_api *api;
+ enum halmac_interface intf;
+ enum halmac_ret_status status;
+ int err = 0;
+ struct halmac_platform_api *pf_api = &rtl_halmac_platform_api;
+
+ halmac = rtlpriv_to_halmac(rtlpriv);
+ if (halmac) {
+ err = 0;
+ goto out;
+ }
+
+ err = init_priv(&rtlpriv->halmac);
+ if (err)
+ goto out;
+
+ intf = HALMAC_INTERFACE_PCIE;
+ status = halmac_init_adapter(rtlpriv, pf_api, intf, &halmac, &api);
+ if (status != HALMAC_RET_SUCCESS) {
+ RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
+ "%s: halmac_init_adapter fail!(status=%d)\n", __func__,
+ status);
+ err = -1;
+ goto out;
+ }
+
+ rtlpriv->halmac.internal = halmac;
+
+out:
+ if (err)
+ rtl_halmac_deinit_adapter(rtlpriv);
+
+ return err;
+}
+
+int rtl_halmac_deinit_adapter(struct rtl_priv *rtlpriv)
+{
+ struct halmac_adapter *halmac;
+ enum halmac_ret_status status;
+ int err = 0;
+
+ halmac = rtlpriv_to_halmac(rtlpriv);
+ if (!halmac) {
+ err = 0;
+ goto out;
+ }
+
+ deinit_priv(&rtlpriv->halmac);
+
+ halmac_halt_api(halmac);
+
+ status = halmac_deinit_adapter(halmac);
+ rtlpriv->halmac.internal = NULL;
+ if (status != HALMAC_RET_SUCCESS) {
+ err = -1;
+ goto out;
+ }
+
+out:
+ return err;
+}
+
+int rtl_halmac_poweron(struct rtl_priv *rtlpriv)
+{
+ struct halmac_adapter *halmac;
+ struct halmac_api *api;
+ enum halmac_ret_status status;
+ int err = -1;
+
+ halmac = rtlpriv_to_halmac(rtlpriv);
+ if (!halmac)
+ goto out;
+
+ api = HALMAC_GET_API(halmac);
+
+ status = api->halmac_pre_init_system_cfg(halmac);
+ if (status != HALMAC_RET_SUCCESS)
+ goto out;
+
+ status = api->halmac_mac_power_switch(halmac, HALMAC_MAC_POWER_ON);
+ if (status != HALMAC_RET_SUCCESS)
+ goto out;
+
+ status = api->halmac_init_system_cfg(halmac);
+ if (status != HALMAC_RET_SUCCESS)
+ goto out;
+
+ err = 0;
+out:
+ return err;
+}
+
+int rtl_halmac_poweroff(struct rtl_priv *rtlpriv)
+{
+ struct halmac_adapter *halmac;
+ struct halmac_api *api;
+ enum halmac_ret_status status;
+ int err = -1;
+
+ halmac = rtlpriv_to_halmac(rtlpriv);
+ if (!halmac)
+ goto out;
+
+ api = HALMAC_GET_API(halmac);
+
+ status = api->halmac_mac_power_switch(halmac, HALMAC_MAC_POWER_OFF);
+ if (status != HALMAC_RET_SUCCESS)
+ goto out;
+
+ err = 0;
+out:
+ return err;
+}
+
+/*
+ * Note:
+ * When this function return, the register REG_RCR may be changed.
+ */
+int rtl_halmac_config_rx_info(struct rtl_priv *rtlpriv,
+ enum halmac_drv_info info)
+{
+ struct halmac_adapter *halmac;
+ struct halmac_api *api;
+ enum halmac_ret_status status;
+ int err = -1;
+
+ halmac = rtlpriv_to_halmac(rtlpriv);
+ api = HALMAC_GET_API(halmac);
+
+ status = api->halmac_cfg_drv_info(halmac, info);
+ if (status != HALMAC_RET_SUCCESS)
+ goto out;
+
+ err = 0;
+out:
+ return err;
+}
+
+static enum halmac_ret_status init_mac_flow(struct rtl_priv *rtlpriv)
+{
+ struct halmac_adapter *halmac;
+ struct halmac_api *api;
+ enum halmac_ret_status status;
+ u8 wifi_test = 0;
+ int err;
+
+ halmac = rtlpriv_to_halmac(rtlpriv);
+ api = HALMAC_GET_API(halmac);
+
+ if (wifi_test)
+ status = api->halmac_init_mac_cfg(halmac, HALMAC_TRX_MODE_WMM);
+ else
+ status = api->halmac_init_mac_cfg(halmac,
+ HALMAC_TRX_MODE_NORMAL);
+ if (status != HALMAC_RET_SUCCESS)
+ goto out;
+
+ err = rtl_halmac_rx_agg_switch(rtlpriv, true);
+ if (err)
+ goto out;
+
+ if (rtlpriv->cfg->maps[RTL_RC_VHT_RATE_1SS_MCS7])
+ status = api->halmac_cfg_operation_mode(
+ halmac, HALMAC_WIRELESS_MODE_AC);
+ else if (rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS7])
+ status = api->halmac_cfg_operation_mode(halmac,
+ HALMAC_WIRELESS_MODE_N);
+ else if (rtlpriv->cfg->maps[RTL_RC_OFDM_RATE6M])
+ status = api->halmac_cfg_operation_mode(halmac,
+ HALMAC_WIRELESS_MODE_G);
+ else
+ status = api->halmac_cfg_operation_mode(halmac,
+ HALMAC_WIRELESS_MODE_B);
+ if (status != HALMAC_RET_SUCCESS)
+ goto out;
+
+out:
+ return status;
+}
+
+static inline enum halmac_rf_type _rf_type_drv2halmac(enum rf_type rf_drv)
+{
+ enum halmac_rf_type rf_mac;
+
+ switch (rf_drv) {
+ case RF_1T2R:
+ rf_mac = HALMAC_RF_1T2R;
+ break;
+ case RF_2T2R:
+ rf_mac = HALMAC_RF_2T2R;
+ break;
+ case RF_1T1R:
+ rf_mac = HALMAC_RF_1T1R;
+ break;
+ case RF_2T2R_GREEN:
+ rf_mac = HALMAC_RF_2T2R_GREEN;
+ break;
+ default:
+ rf_mac = (enum halmac_rf_type)rf_drv;
+ break;
+ }
+
+ return rf_mac;
+}
+
+static int _send_general_info(struct rtl_priv *rtlpriv)
+{
+ struct halmac_adapter *halmac;
+ struct halmac_api *api;
+ struct halmac_general_info info;
+ enum halmac_ret_status status;
+
+ halmac = rtlpriv_to_halmac(rtlpriv);
+ if (!halmac)
+ return -1;
+ api = HALMAC_GET_API(halmac);
+
+ memset(&info, 0, sizeof(info));
+ info.rfe_type = rtlpriv->rtlhal.rfe_type;
+ info.rf_type = _rf_type_drv2halmac(rtlpriv->phy.rf_type);
+
+ status = api->halmac_send_general_info(halmac, &info);
+ switch (status) {
+ case HALMAC_RET_SUCCESS:
+ break;
+ case HALMAC_RET_NO_DLFW:
+ RT_TRACE(rtlpriv, COMP_HALMAC, DBG_WARNING,
+ "%s: halmac_send_general_info() fail because fw not dl!\n",
+ __func__);
+ /* fallthrough here */
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Notices:
+ * Make sure
+ * 1. rtl_hal_get_hwreg(HW_VAR_RF_TYPE)
+ * 2. HAL_DATA_TYPE.rfe_type
+ * already ready for use before calling this function.
+ */
+static int _halmac_init_hal(struct rtl_priv *rtlpriv, u8 *fw, u32 fwsize)
+{
+ struct halmac_adapter *halmac;
+ struct halmac_api *api;
+ enum halmac_ret_status status;
+ bool ok;
+ bool fw_ok = false;
+ int err, err_ret = -1;
+
+ halmac = rtlpriv_to_halmac(rtlpriv);
+ if (!halmac)
+ goto out;
+ api = HALMAC_GET_API(halmac);
+
+ /* StatePowerOff */
+
+ /* SKIP: halmac_init_adapter (Already done before) */
+
+ /* halmac_pre_Init_system_cfg */
+ /* halmac_mac_power_switch(on) */
+ /* halmac_Init_system_cfg */
+ err = rtl_halmac_poweron(rtlpriv);
+ if (err)
+ goto out;
+
+ /* StatePowerOn */
+
+ /* DownloadFW */
+ rtlpriv->halmac.send_general_info = 0;
+ if (fw && fwsize) {
+ err = rtl_halmac_dlfw(rtlpriv, fw, fwsize);
+ if (err)
+ goto out;
+ fw_ok = true;
+ }
+
+ /* InitMACFlow */
+ status = init_mac_flow(rtlpriv);
+ if (status != HALMAC_RET_SUCCESS)
+ goto out;
+
+ /* halmac_send_general_info */
+ if (fw_ok) {
+ rtlpriv->halmac.send_general_info = 0;
+ err = _send_general_info(rtlpriv);
+ if (err)
+ goto out;
+ } else {
+ rtlpriv->halmac.send_general_info = 1;
+ }
+
+ /* Init Phy parameter-MAC */
+ if (rtlpriv->cfg->ops->halmac_cb_init_mac_register)
+ ok = rtlpriv->cfg->ops->halmac_cb_init_mac_register(rtlpriv);
+ else
+ ok = false;
+
+ if (!ok)
+ goto out;
+
+ /* StateMacInitialized */
+
+ /* halmac_cfg_drv_info */
+ err = rtl_halmac_config_rx_info(rtlpriv, HALMAC_DRV_INFO_PHY_STATUS);
+ if (err)
+ goto out;
+
+ /* halmac_set_hw_value(HALMAC_HW_EN_BB_RF) */
+ /* Init BB, RF */
+ if (rtlpriv->cfg->ops->halmac_cb_init_bb_rf_register)
+ ok = rtlpriv->cfg->ops->halmac_cb_init_bb_rf_register(rtlpriv);
+ else
+ ok = false;
+
+ if (!ok)
+ goto out;
+
+ status = api->halmac_init_interface_cfg(halmac);
+ if (status != HALMAC_RET_SUCCESS)
+ goto out;
+
+ /* SKIP: halmac_verify_platform_api */
+ /* SKIP: halmac_h2c_lb */
+
+ /* StateRxIdle */
+
+ err_ret = 0;
+out:
+ return err_ret;
+}
+
+int rtl_halmac_init_hal(struct rtl_priv *rtlpriv)
+{
+ if (!rtlpriv->rtlhal.pfirmware || rtlpriv->rtlhal.fwsize == 0)
+ return -1;
+
+ return _halmac_init_hal(rtlpriv, rtlpriv->rtlhal.pfirmware,
+ rtlpriv->rtlhal.fwsize);
+}
+
+int rtl_halmac_deinit_hal(struct rtl_priv *rtlpriv)
+{
+ struct halmac_adapter *halmac;
+ struct halmac_api *api;
+ enum halmac_ret_status status;
+ int err = -1;
+
+ halmac = rtlpriv_to_halmac(rtlpriv);
+ if (!halmac)
+ goto out;
+ api = HALMAC_GET_API(halmac);
+
+ status = api->halmac_deinit_interface_cfg(halmac);
+ if (status != HALMAC_RET_SUCCESS)
+ goto out;
+
+ /* rtw_hal_power_off(adapter); */
+ status = api->halmac_mac_power_switch(halmac, HALMAC_MAC_POWER_OFF);
+ if (status != HALMAC_RET_SUCCESS)
+ goto out;
+
+ err = 0;
+out:
+ return err;
+}
+
+int rtl_halmac_self_verify(struct rtl_priv *rtlpriv)
+{
+ struct halmac_adapter *mac;
+ struct halmac_api *api;
+ enum halmac_ret_status status;
+ int err = -1;
+
+ mac = rtlpriv_to_halmac(rtlpriv);
+ api = HALMAC_GET_API(mac);
+
+ status = api->halmac_verify_platform_api(mac);
+ if (status != HALMAC_RET_SUCCESS)
+ goto out;
+
+ status = api->halmac_h2c_lb(mac);
+ if (status != HALMAC_RET_SUCCESS)
+ goto out;
+
+ err = 0;
+out:
+ return err;
+}
+
+int rtl_halmac_dlfw(struct rtl_priv *rtlpriv, u8 *fw, u32 fwsize)
+{
+ struct halmac_adapter *mac;
+ struct halmac_api *api;
+ enum halmac_ret_status status;
+ struct halmac_fw_version fw_version;
+ int err = 0;
+
+ mac = rtlpriv_to_halmac(rtlpriv);
+ api = HALMAC_GET_API(mac);
+
+ if ((!fw) || (!fwsize))
+ return -1;
+
+ /* 1. Driver Stop Tx */
+ /* ToDo */
+
+ /* 2. Driver Check Tx FIFO is empty */
+ /* ToDo */
+
+ /* 3. Config MAX download size */
+ api->halmac_cfg_max_dl_size(mac, 0x1000);
+
+ /* 4. Download Firmware */
+ mac->h2c_packet_seq = 0;
+ status = api->halmac_download_firmware(mac, fw, fwsize);
+ if (status != HALMAC_RET_SUCCESS)
+ return -1;
+
+ status = api->halmac_get_fw_version(mac, &fw_version);
+ if (status == HALMAC_RET_SUCCESS) {
+ rtlpriv->rtlhal.fw_version = fw_version.version;
+ rtlpriv->rtlhal.fw_subversion =
+ (fw_version.sub_version << 8) | (fw_version.sub_index);
+
+ RT_TRACE(
+ rtlpriv, COMP_HALMAC, DBG_DMESG,
+ "halmac report firmware version %04X.%04X\n",
+ rtlpriv->rtlhal.fw_version,
+ rtlpriv->rtlhal.fw_subversion);
+ }
+
+ if (rtlpriv->halmac.send_general_info) {
+ rtlpriv->halmac.send_general_info = 0;
+ err = _send_general_info(rtlpriv);
+ }
+
+ /* 5. Driver resume TX if needed */
+ /* ToDo */
+
+ /* 6. Reset driver variables if needed */
+ /*hal->LastHMEBoxNum = 0;*/
+
+ return err;
+}
+
+/*
+ * Description:
+ * Power on/off BB/RF domain.
+ *
+ * Parameters:
+ * enable true/false for power on/off
+ *
+ * Return:
+ * 0 Success
+ * others Fail
+ */
+int rtl_halmac_phy_power_switch(struct rtl_priv *rtlpriv, u8 enable)
+{
+ struct halmac_adapter *halmac;
+ struct halmac_api *api;
+ enum halmac_ret_status status;
+
+ halmac = rtlpriv_to_halmac(rtlpriv);
+ if (!halmac)
+ return -1;
+ api = HALMAC_GET_API(halmac);
+
+ status = api->halmac_set_hw_value(halmac, HALMAC_HW_EN_BB_RF, &enable);
+ if (status != HALMAC_RET_SUCCESS)
+ return -1;
+
+ return 0;
+}
+
+static bool _is_fw_read_cmd_down(struct rtl_priv *rtlpriv, u8 msgbox_num)
+{
+ bool read_down = false;
+ int retry_cnts = 100;
+ u8 valid;
+
+ RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
+ "%s, reg_1cc(%x), msg_box(%d)...\n", __func__,
+ rtl_read_byte(rtlpriv, REG_HMETFR), msgbox_num);
+
+ do {
+ valid = rtl_read_byte(rtlpriv, REG_HMETFR) & BIT(msgbox_num);
+ if (valid == 0)
+ read_down = true;
+ else
+ schedule();
+ } while ((!read_down) && (retry_cnts--));
+
+ return read_down;
+}
+
+int rtl_halmac_send_h2c(struct rtl_priv *rtlpriv, u8 *h2c)
+{
+ u8 h2c_box_num = 0;
+ u32 msgbox_addr = 0;
+ u32 msgbox_ex_addr = 0;
+ __le32 h2c_cmd = 0;
+ __le32 h2c_cmd_ex = 0;
+ s32 ret = -1;
+ unsigned long flag = 0;
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+
+ if (!h2c) {
+ RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: pbuf is NULL\n",
+ __func__);
+ return ret;
+ }
+
+ spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
+
+ /* pay attention to if race condition happened in H2C cmd setting */
+ h2c_box_num = rtlhal->last_hmeboxnum;
+
+ if (!_is_fw_read_cmd_down(rtlpriv, h2c_box_num)) {
+ RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
+ " fw read cmd failed...\n");
+ goto exit;
+ }
+
+ /* Write Ext command(byte 4 -7) */
+ msgbox_ex_addr = REG_HMEBOX_E0 + (h2c_box_num * EX_MESSAGE_BOX_SIZE);
+ memcpy((u8 *)(&h2c_cmd_ex), h2c + 4, EX_MESSAGE_BOX_SIZE);
+ rtl_write_dword(rtlpriv, msgbox_ex_addr, le32_to_cpu(h2c_cmd_ex));
+
+ /* Write command (byte 0 -3 ) */
+ msgbox_addr = REG_HMEBOX0 + (h2c_box_num * MESSAGE_BOX_SIZE);
+ memcpy((u8 *)(&h2c_cmd), h2c, 4);
+ rtl_write_dword(rtlpriv, msgbox_addr, le32_to_cpu(h2c_cmd));
+
+ /* update last msg box number */
+ rtlhal->last_hmeboxnum = (h2c_box_num + 1) % MAX_H2C_BOX_NUMS;
+ ret = 0;
+
+exit:
+ spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
+ return ret;
+}
+
+int rtl_halmac_c2h_handle(struct rtl_priv *rtlpriv, u8 *c2h, u32 size)
+{
+ struct halmac_adapter *mac;
+ struct halmac_api *api;
+ enum halmac_ret_status status;
+
+ mac = rtlpriv_to_halmac(rtlpriv);
+ api = HALMAC_GET_API(mac);
+
+ status = api->halmac_get_c2h_info(mac, c2h, size);
+ if (status != HALMAC_RET_SUCCESS)
+ return -1;
+
+ return 0;
+}
+
+int rtl_halmac_get_physical_efuse_size(struct rtl_priv *rtlpriv, u32 *size)
+{
+ struct halmac_adapter *mac;
+ struct halmac_api *api;
+ enum halmac_ret_status status;
+ u32 val;
+
+ mac = rtlpriv_to_halmac(rtlpriv);
+ api = HALMAC_GET_API(mac);
+
+ status = api->halmac_get_efuse_size(mac, &val);
+ if (status != HALMAC_RET_SUCCESS)
+ return -1;
+
+ *size = val;
+ return 0;
+}
+
+int rtl_halmac_read_physical_efuse_map(struct rtl_priv *rtlpriv, u8 *map,
+ u32 size)
+{
+ struct halmac_adapter *mac;
+ struct halmac_api *api;
+ enum halmac_ret_status status;
+ enum halmac_feature_id id;
+ int ret;
+
+ mac = rtlpriv_to_halmac(rtlpriv);
+ api = HALMAC_GET_API(mac);
+ id = HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE;
+
+ ret = init_halmac_event(rtlpriv, id, map, size);
+ if (ret)
+ return -1;
+
+ status = api->halmac_dump_efuse_map(mac, HALMAC_EFUSE_R_DRV);
+ if (status != HALMAC_RET_SUCCESS) {
+ free_halmac_event(rtlpriv, id);
+ return -1;
+ }
+
+ ret = wait_halmac_event(rtlpriv, id);
+ if (ret)
+ return -1;
+
+ return 0;
+}
+
+int rtl_halmac_read_physical_efuse(struct rtl_priv *rtlpriv, u32 offset,
+ u32 cnt, u8 *data)
+{
+ struct halmac_adapter *mac;
+ struct halmac_api *api;
+ enum halmac_ret_status status;
+ u8 v;
+ u32 i;
+
+ mac = rtlpriv_to_halmac(rtlpriv);
+ api = HALMAC_GET_API(mac);
+
+ for (i = 0; i < cnt; i++) {
+ status = api->halmac_read_efuse(mac, offset + i, &v);
+ if (status != HALMAC_RET_SUCCESS)
+ return -1;
+ data[i] = v;
+ }
+
+ return 0;
+}
+
+int rtl_halmac_write_physical_efuse(struct rtl_priv *rtlpriv, u32 offset,
+ u32 cnt, u8 *data)
+{
+ struct halmac_adapter *mac;
+ struct halmac_api *api;
+ enum halmac_ret_status status;
+ u32 i;
+
+ mac = rtlpriv_to_halmac(rtlpriv);
+ api = HALMAC_GET_API(mac);
+
+ for (i = 0; i < cnt; i++) {
+ status = api->halmac_write_efuse(mac, offset + i, data[i]);
+ if (status != HALMAC_RET_SUCCESS)
+ return -1;
+ }
+
+ return 0;
+}
+
+int rtl_halmac_get_logical_efuse_size(struct rtl_priv *rtlpriv, u32 *size)
+{
+ struct halmac_adapter *mac;
+ struct halmac_api *api;
+ enum halmac_ret_status status;
+ u32 val;
+
+ mac = rtlpriv_to_halmac(rtlpriv);
+ api = HALMAC_GET_API(mac);
+
+ status = api->halmac_get_logical_efuse_size(mac, &val);
+ if (status != HALMAC_RET_SUCCESS)
+ return -1;
+
+ *size = val;
+ return 0;
+}
+
+int rtl_halmac_read_logical_efuse_map(struct rtl_priv *rtlpriv, u8 *map,
+ u32 size)
+{
+ struct halmac_adapter *mac;
+ struct halmac_api *api;
+ enum halmac_ret_status status;
+ enum halmac_feature_id id;
+ int ret;
+
+ mac = rtlpriv_to_halmac(rtlpriv);
+ api = HALMAC_GET_API(mac);
+ id = HALMAC_FEATURE_DUMP_LOGICAL_EFUSE;
+
+ ret = init_halmac_event(rtlpriv, id, map, size);
+ if (ret)
+ return -1;
+
+ status = api->halmac_dump_logical_efuse_map(mac, HALMAC_EFUSE_R_AUTO);
+ if (status != HALMAC_RET_SUCCESS) {
+ free_halmac_event(rtlpriv, id);
+ return -1;
+ }
+
+ ret = wait_halmac_event(rtlpriv, id);
+ if (ret)
+ return -1;
+
+ return 0;
+}
+
+int rtl_halmac_write_logical_efuse_map(struct rtl_priv *rtlpriv, u8 *map,
+ u32 size, u8 *maskmap, u32 masksize)
+{
+ struct halmac_adapter *mac;
+ struct halmac_api *api;
+ struct halmac_pg_efuse_info pginfo;
+ enum halmac_ret_status status;
+
+ mac = rtlpriv_to_halmac(rtlpriv);
+ api = HALMAC_GET_API(mac);
+
+ pginfo.efuse_map = map;
+ pginfo.efuse_map_size = size;
+ pginfo.efuse_mask = maskmap;
+ pginfo.efuse_mask_size = masksize;
+
+ status = api->halmac_pg_efuse_by_map(mac, &pginfo, HALMAC_EFUSE_R_AUTO);
+ if (status != HALMAC_RET_SUCCESS)
+ return -1;
+
+ return 0;
+}
+
+int rtl_halmac_read_logical_efuse(struct rtl_priv *rtlpriv, u32 offset, u32 cnt,
+ u8 *data)
+{
+ struct halmac_adapter *mac;
+ struct halmac_api *api;
+ enum halmac_ret_status status;
+ u8 v;
+ u32 i;
+
+ mac = rtlpriv_to_halmac(rtlpriv);
+ api = HALMAC_GET_API(mac);
+
+ for (i = 0; i < cnt; i++) {
+ status = api->halmac_read_logical_efuse(mac, offset + i, &v);
+ if (status != HALMAC_RET_SUCCESS)
+ return -1;
+ data[i] = v;
+ }
+
+ return 0;
+}
+
+int rtl_halmac_write_logical_efuse(struct rtl_priv *rtlpriv, u32 offset,
+ u32 cnt, u8 *data)
+{
+ struct halmac_adapter *mac;
+ struct halmac_api *api;
+ enum halmac_ret_status status;
+ u32 i;
+
+ mac = rtlpriv_to_halmac(rtlpriv);
+ api = HALMAC_GET_API(mac);
+
+ for (i = 0; i < cnt; i++) {
+ status = api->halmac_write_logical_efuse(mac, offset + i,
+ data[i]);
+ if (status != HALMAC_RET_SUCCESS)
+ return -1;
+ }
+
+ return 0;
+}
+
+int rtl_halmac_set_mac_address(struct rtl_priv *rtlpriv, u8 hwport, u8 *addr)
+{
+ struct halmac_adapter *halmac;
+ struct halmac_api *api;
+ u8 port;
+ union halmac_wlan_addr hwa;
+ enum halmac_ret_status status;
+ int err = -1;
+
+ halmac = rtlpriv_to_halmac(rtlpriv);
+ api = HALMAC_GET_API(halmac);
+
+ port = hwport;
+ memset(&hwa, 0, sizeof(hwa));
+ memcpy(hwa.address, addr, 6);
+
+ status = api->halmac_cfg_mac_addr(halmac, port, &hwa);
+ if (status != HALMAC_RET_SUCCESS)
+ goto out;
+
+ err = 0;
+out:
+ return err;
+}
+
+int rtl_halmac_set_bssid(struct rtl_priv *rtlpriv, u8 hwport, u8 *addr)
+{
+ struct halmac_adapter *halmac;
+ struct halmac_api *api;
+ u8 port;
+ union halmac_wlan_addr hwa;
+ enum halmac_ret_status status;
+ int err = -1;
+
+ halmac = rtlpriv_to_halmac(rtlpriv);
+ api = HALMAC_GET_API(halmac);
+ port = hwport;
+
+ memset(&hwa, 0, sizeof(union halmac_wlan_addr));
+ memcpy(hwa.address, addr, 6);
+ status = api->halmac_cfg_bssid(halmac, port, &hwa);
+ if (status != HALMAC_RET_SUCCESS)
+ goto out;
+
+ err = 0;
+out:
+ return err;
+}
+
+int rtl_halmac_set_bandwidth(struct rtl_priv *rtlpriv, u8 channel,
+ u8 pri_ch_idx, u8 bw)
+{
+ struct halmac_adapter *mac;
+ struct halmac_api *api;
+ enum halmac_ret_status status;
+
+ mac = rtlpriv_to_halmac(rtlpriv);
+ api = HALMAC_GET_API(mac);
+
+ status = api->halmac_cfg_ch_bw(mac, channel, pri_ch_idx, bw);
+ if (status != HALMAC_RET_SUCCESS)
+ return -1;
+
+ return 0;
+}
+
+int rtl_halmac_get_hw_value(struct rtl_priv *rtlpriv, enum halmac_hw_id hw_id,
+ void *pvalue)
+{
+ struct halmac_adapter *mac;
+ struct halmac_api *api;
+ enum halmac_ret_status status;
+
+ mac = rtlpriv_to_halmac(rtlpriv);
+ api = HALMAC_GET_API(mac);
+
+ status = api->halmac_get_hw_value(mac, hw_id, pvalue);
+ if (status != HALMAC_RET_SUCCESS)
+ return -1;
+
+ return 0;
+}
+
+int rtl_halmac_dump_fifo(struct rtl_priv *rtlpriv,
+ enum hal_fifo_sel halmac_fifo_sel)
+{
+ struct halmac_adapter *mac;
+ struct halmac_api *api;
+ enum halmac_ret_status status;
+ u8 *pfifo_map = NULL;
+ u32 fifo_size = 0;
+ s8 ret = 0;
+
+ mac = rtlpriv_to_halmac(rtlpriv);
+ api = HALMAC_GET_API(mac);
+
+ fifo_size = api->halmac_get_fifo_size(mac, halmac_fifo_sel);
+ if (fifo_size)
+ pfifo_map = vmalloc(fifo_size);
+ if (!pfifo_map)
+ return -1;
+
+ status = api->halmac_dump_fifo(mac, halmac_fifo_sel, 0, fifo_size,
+ pfifo_map);
+
+ if (status != HALMAC_RET_SUCCESS) {
+ ret = -1;
+ goto _exit;
+ }
+
+_exit:
+ if (pfifo_map)
+ vfree(pfifo_map);
+ return ret;
+}
+
+int rtl_halmac_rx_agg_switch(struct rtl_priv *rtlpriv, bool enable)
+{
+ struct halmac_adapter *halmac;
+ struct halmac_api *api;
+ struct halmac_rxagg_cfg rxaggcfg;
+ enum halmac_ret_status status;
+ int err = -1;
+
+ halmac = rtlpriv_to_halmac(rtlpriv);
+ api = HALMAC_GET_API(halmac);
+ memset((void *)&rxaggcfg, 0, sizeof(rxaggcfg));
+
+ if (enable) {
+ /* enable RX agg. */
+ /* PCIE do nothing */
+ } else {
+ /* disable RX agg. */
+ rxaggcfg.mode = HALMAC_RX_AGG_MODE_NONE;
+ }
+
+ status = api->halmac_cfg_rx_aggregation(halmac, &rxaggcfg);
+ if (status != HALMAC_RET_SUCCESS)
+ goto out;
+
+ err = 0;
+out:
+ return err;
+}
+
+int rtl_halmac_get_wow_reason(struct rtl_priv *rtlpriv, u8 *reason)
+{
+ u8 val8;
+ int err = -1;
+
+ val8 = rtl_read_byte(rtlpriv, 0x1C7);
+ if (val8 == 0xEA)
+ goto out;
+
+ *reason = val8;
+ err = 0;
+out:
+ return err;
+}
+
+/*
+ * Description:
+ * Get RX driver info size. RX driver info is a small memory space between
+ * scriptor and RX payload.
+ *
+ * +-------------------------+
+ * | RX descriptor |
+ * | usually 24 bytes |
+ * +-------------------------+
+ * | RX driver info |
+ * | depends on driver cfg |
+ * +-------------------------+
+ * | RX paylad |
+ * | |
+ * +-------------------------+
+ *
+ * Parameter:
+ * d pointer to struct dvobj_priv of driver
+ * sz rx driver info size in bytes.
+ *
+ * Rteurn:
+ * 0 Success
+ * other Fail
+ */
+int rtl_halmac_get_drv_info_sz(struct rtl_priv *rtlpriv, u8 *sz)
+{
+ /* enum halmac_ret_status status; */
+ u8 dw = 6; /* max number */
+
+ *sz = dw * 8;
+ return 0;
+}
+
+int rtl_halmac_get_rsvd_drv_pg_bndy(struct rtl_priv *rtlpriv, u16 *drv_pg)
+{
+ enum halmac_ret_status status;
+ struct halmac_adapter *halmac = rtlpriv_to_halmac(rtlpriv);
+ struct halmac_api *api = HALMAC_GET_API(halmac);
+
+ status = api->halmac_get_hw_value(halmac, HALMAC_HW_RSVD_PG_BNDY,
+ drv_pg);
+ if (status != HALMAC_RET_SUCCESS)
+ return -1;
+
+ return 0;
+}
+
+int rtl_halmac_chk_txdesc(struct rtl_priv *rtlpriv, u8 *txdesc, u32 size)
+{
+ struct halmac_adapter *mac;
+ struct halmac_api *api;
+ enum halmac_ret_status status;
+
+ mac = rtlpriv_to_halmac(rtlpriv);
+ api = HALMAC_GET_API(mac);
+
+ status = api->halmac_chk_txdesc(mac, txdesc, size);
+
+ if (status != HALMAC_RET_SUCCESS)
+ return -1;
+
+ return 0;
+}
+
+MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
+MODULE_AUTHOR("Larry Finger <Larry.FInger@lwfinger.net>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core");
diff --git a/drivers/staging/rtlwifi/halmac/rtl_halmac.h b/drivers/staging/rtlwifi/halmac/rtl_halmac.h
new file mode 100644
index 0000000..51a3684
--- /dev/null
+++ b/drivers/staging/rtlwifi/halmac/rtl_halmac.h
@@ -0,0 +1,94 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef _RTL_HALMAC_H_
+#define _RTL_HALMAC_H_
+
+#include "halmac_api.h"
+
+#define rtlpriv_to_halmac(priv) \
+ ((struct halmac_adapter *)((priv)->halmac.internal))
+
+/* for H2C cmd */
+#define MAX_H2C_BOX_NUMS 4
+#define MESSAGE_BOX_SIZE 4
+#define EX_MESSAGE_BOX_SIZE 4
+
+/* HALMAC API for Driver(HAL) */
+int rtl_halmac_init_adapter(struct rtl_priv *rtlpriv);
+int rtl_halmac_deinit_adapter(struct rtl_priv *rtlpriv);
+int rtl_halmac_poweron(struct rtl_priv *rtlpriv);
+int rtl_halmac_poweroff(struct rtl_priv *rtlpriv);
+int rtl_halmac_init_hal(struct rtl_priv *rtlpriv);
+int rtl_halmac_init_hal_fw(struct rtl_priv *rtlpriv, u8 *fw, u32 fwsize);
+int rtl_halmac_init_hal_fw_file(struct rtl_priv *rtlpriv, u8 *fwpath);
+int rtl_halmac_deinit_hal(struct rtl_priv *rtlpriv);
+int rtl_halmac_self_verify(struct rtl_priv *rtlpriv);
+int rtl_halmac_dlfw(struct rtl_priv *rtlpriv, u8 *fw, u32 fwsize);
+int rtl_halmac_dlfw_from_file(struct rtl_priv *rtlpriv, u8 *fwpath);
+int rtl_halmac_phy_power_switch(struct rtl_priv *rtlpriv, u8 enable);
+int rtl_halmac_send_h2c(struct rtl_priv *rtlpriv, u8 *h2c);
+int rtl_halmac_c2h_handle(struct rtl_priv *rtlpriv, u8 *c2h, u32 size);
+
+int rtl_halmac_get_physical_efuse_size(struct rtl_priv *rtlpriv, u32 *size);
+int rtl_halmac_read_physical_efuse_map(struct rtl_priv *rtlpriv, u8 *map,
+ u32 size);
+int rtl_halmac_read_physical_efuse(struct rtl_priv *rtlpriv, u32 offset,
+ u32 cnt, u8 *data);
+int rtl_halmac_write_physical_efuse(struct rtl_priv *rtlpriv, u32 offset,
+ u32 cnt, u8 *data);
+int rtl_halmac_get_logical_efuse_size(struct rtl_priv *rtlpriv, u32 *size);
+int rtl_halmac_read_logical_efuse_map(struct rtl_priv *rtlpriv, u8 *map,
+ u32 size);
+int rtl_halmac_write_logical_efuse_map(struct rtl_priv *rtlpriv, u8 *map,
+ u32 size, u8 *maskmap, u32 masksize);
+int rtl_halmac_read_logical_efuse(struct rtl_priv *rtlpriv, u32 offset, u32 cnt,
+ u8 *data);
+int rtl_halmac_write_logical_efuse(struct rtl_priv *rtlpriv, u32 offset,
+ u32 cnt, u8 *data);
+
+int rtl_halmac_config_rx_info(struct rtl_priv *rtlpriv, enum halmac_drv_info);
+int rtl_halmac_set_mac_address(struct rtl_priv *rtlpriv, u8 hwport, u8 *addr);
+int rtl_halmac_set_bssid(struct rtl_priv *d, u8 hwport, u8 *addr);
+
+int rtl_halmac_set_bandwidth(struct rtl_priv *rtlpriv, u8 channel,
+ u8 pri_ch_idx, u8 bw);
+int rtl_halmac_rx_agg_switch(struct rtl_priv *rtlpriv, bool enable);
+int rtl_halmac_get_hw_value(struct rtl_priv *d, enum halmac_hw_id hw_id,
+ void *pvalue);
+int rtl_halmac_dump_fifo(struct rtl_priv *rtlpriv,
+ enum hal_fifo_sel halmac_fifo_sel);
+
+int rtl_halmac_get_wow_reason(struct rtl_priv *rtlpriv, u8 *reason);
+int rtl_halmac_get_drv_info_sz(struct rtl_priv *d, u8 *sz);
+
+int rtl_halmac_get_rsvd_drv_pg_bndy(struct rtl_priv *dvobj, u16 *drv_pg);
+int rtl_halmac_download_rsvd_page(struct rtl_priv *dvobj, u8 pg_offset,
+ u8 *pbuf, u32 size);
+
+int rtl_halmac_chk_txdesc(struct rtl_priv *rtlpriv, u8 *txdesc, u32 size);
+
+struct rtl_halmac_ops *rtl_halmac_get_ops_pointer(void);
+
+#endif /* _RTL_HALMAC_H_ */
diff --git a/drivers/staging/rtlwifi/pci.c b/drivers/staging/rtlwifi/pci.c
new file mode 100644
index 0000000..4035b88
--- /dev/null
+++ b/drivers/staging/rtlwifi/pci.c
@@ -0,0 +1,2508 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2012 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "wifi.h"
+#include "core.h"
+#include "pci.h"
+#include "base.h"
+#include "ps.h"
+#include "efuse.h"
+#include <linux/interrupt.h>
+#include <linux/export.h>
+#include <linux/kmemleak.h>
+#include <linux/module.h>
+
+MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>");
+MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
+MODULE_AUTHOR("Larry Finger <Larry.FInger@lwfinger.net>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("PCI basic driver for rtlwifi");
+
+static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = {
+ INTEL_VENDOR_ID,
+ ATI_VENDOR_ID,
+ AMD_VENDOR_ID,
+ SIS_VENDOR_ID
+};
+
+static const u8 ac_to_hwq[] = {
+ VO_QUEUE,
+ VI_QUEUE,
+ BE_QUEUE,
+ BK_QUEUE
+};
+
+static u8 _rtl_mac_to_hwqueue(struct ieee80211_hw *hw,
+ struct sk_buff *skb)
+{
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ __le16 fc = rtl_get_fc(skb);
+ u8 queue_index = skb_get_queue_mapping(skb);
+ struct ieee80211_hdr *hdr;
+
+ if (unlikely(ieee80211_is_beacon(fc)))
+ return BEACON_QUEUE;
+ if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))
+ return MGNT_QUEUE;
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE)
+ if (ieee80211_is_nullfunc(fc))
+ return HIGH_QUEUE;
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8822BE) {
+ hdr = rtl_get_hdr(skb);
+
+ if (is_multicast_ether_addr(hdr->addr1) ||
+ is_broadcast_ether_addr(hdr->addr1))
+ return HIGH_QUEUE;
+ }
+
+ return ac_to_hwq[queue_index];
+}
+
+/* Update PCI dependent default settings*/
+static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
+ u8 init_aspm;
+
+ ppsc->reg_rfps_level = 0;
+ ppsc->support_aspm = false;
+
+ /*Update PCI ASPM setting */
+ ppsc->const_amdpci_aspm = rtlpci->const_amdpci_aspm;
+ switch (rtlpci->const_pci_aspm) {
+ case 0:
+ /*No ASPM */
+ break;
+
+ case 1:
+ /*ASPM dynamically enabled/disable. */
+ ppsc->reg_rfps_level |= RT_RF_LPS_LEVEL_ASPM;
+ break;
+
+ case 2:
+ /*ASPM with Clock Req dynamically enabled/disable. */
+ ppsc->reg_rfps_level |= (RT_RF_LPS_LEVEL_ASPM |
+ RT_RF_OFF_LEVL_CLK_REQ);
+ break;
+
+ case 3:
+ /* Always enable ASPM and Clock Req
+ * from initialization to halt.
+ */
+ ppsc->reg_rfps_level &= ~(RT_RF_LPS_LEVEL_ASPM);
+ ppsc->reg_rfps_level |= (RT_RF_PS_LEVEL_ALWAYS_ASPM |
+ RT_RF_OFF_LEVL_CLK_REQ);
+ break;
+
+ case 4:
+ /* Always enable ASPM without Clock Req
+ * from initialization to halt.
+ */
+ ppsc->reg_rfps_level &= ~(RT_RF_LPS_LEVEL_ASPM |
+ RT_RF_OFF_LEVL_CLK_REQ);
+ ppsc->reg_rfps_level |= RT_RF_PS_LEVEL_ALWAYS_ASPM;
+ break;
+ }
+
+ ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_HALT_NIC;
+
+ /*Update Radio OFF setting */
+ switch (rtlpci->const_hwsw_rfoff_d3) {
+ case 1:
+ if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM)
+ ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_ASPM;
+ break;
+
+ case 2:
+ if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM)
+ ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_ASPM;
+ ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_HALT_NIC;
+ break;
+
+ case 3:
+ ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_PCI_D3;
+ break;
+ }
+
+ /*Set HW definition to determine if it supports ASPM. */
+ switch (rtlpci->const_support_pciaspm) {
+ case 0:{
+ /*Not support ASPM. */
+ bool support_aspm = false;
+
+ ppsc->support_aspm = support_aspm;
+ break;
+ }
+ case 1:{
+ /*Support ASPM. */
+ bool support_aspm = true;
+ bool support_backdoor = true;
+
+ ppsc->support_aspm = support_aspm;
+
+ /*if (priv->oem_id == RT_CID_TOSHIBA &&
+ * !priv->ndis_adapter.amd_l1_patch)
+ * support_backdoor = false;
+ */
+
+ ppsc->support_backdoor = support_backdoor;
+
+ break;
+ }
+ case 2:
+ /*ASPM value set by chipset. */
+ if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) {
+ bool support_aspm = true;
+
+ ppsc->support_aspm = support_aspm;
+ }
+ break;
+ default:
+ pr_err("switch case %#x not processed\n",
+ rtlpci->const_support_pciaspm);
+ break;
+ }
+
+ /* toshiba aspm issue, toshiba will set aspm selfly
+ * so we should not set aspm in driver
+ */
+ pci_read_config_byte(rtlpci->pdev, 0x80, &init_aspm);
+ if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8192SE &&
+ init_aspm == 0x43)
+ ppsc->support_aspm = false;
+}
+
+static bool _rtl_pci_platform_switch_device_pci_aspm(
+ struct ieee80211_hw *hw,
+ u8 value)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE)
+ value |= 0x40;
+
+ pci_write_config_byte(rtlpci->pdev, 0x80, value);
+
+ return false;
+}
+
+/*When we set 0x01 to enable clk request. Set 0x0 to disable clk req.*/
+static void _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ pci_write_config_byte(rtlpci->pdev, 0x81, value);
+
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE)
+ udelay(100);
+}
+
+/*Disable RTL8192SE ASPM & Disable Pci Bridge ASPM*/
+static void rtl_pci_disable_aspm(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
+ u8 num4bytes = pcipriv->ndis_adapter.num4bytes;
+ /*Retrieve original configuration settings. */
+ u8 linkctrl_reg = pcipriv->ndis_adapter.linkctrl_reg;
+ u16 pcibridge_linkctrlreg = pcipriv->ndis_adapter.pcibridge_linkctrlreg;
+ u16 aspmlevel = 0;
+ u8 tmp_u1b = 0;
+
+ if (!ppsc->support_aspm)
+ return;
+
+ if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
+ "PCI(Bridge) UNKNOWN\n");
+
+ return;
+ }
+
+ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_CLK_REQ) {
+ RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_CLK_REQ);
+ _rtl_pci_switch_clk_req(hw, 0x0);
+ }
+
+ /*for promising device will in L0 state after an I/O. */
+ pci_read_config_byte(rtlpci->pdev, 0x80, &tmp_u1b);
+
+ /*Set corresponding value. */
+ aspmlevel |= BIT(0) | BIT(1);
+ linkctrl_reg &= ~aspmlevel;
+ pcibridge_linkctrlreg &= ~(BIT(0) | BIT(1));
+
+ _rtl_pci_platform_switch_device_pci_aspm(hw, linkctrl_reg);
+ udelay(50);
+
+ /*4 Disable Pci Bridge ASPM */
+ pci_write_config_byte(rtlpci->pdev, (num4bytes << 2),
+ pcibridge_linkctrlreg);
+
+ udelay(50);
+}
+
+/*
+ *Enable RTL8192SE ASPM & Enable Pci Bridge ASPM for
+ *power saving We should follow the sequence to enable
+ *RTL8192SE first then enable Pci Bridge ASPM
+ *or the system will show bluescreen.
+ */
+static void rtl_pci_enable_aspm(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
+ u8 num4bytes = pcipriv->ndis_adapter.num4bytes;
+ u16 aspmlevel;
+ u8 u_pcibridge_aspmsetting;
+ u8 u_device_aspmsetting;
+
+ if (!ppsc->support_aspm)
+ return;
+
+ if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
+ "PCI(Bridge) UNKNOWN\n");
+ return;
+ }
+
+ /*4 Enable Pci Bridge ASPM */
+
+ u_pcibridge_aspmsetting =
+ pcipriv->ndis_adapter.pcibridge_linkctrlreg |
+ rtlpci->const_hostpci_aspm_setting;
+
+ if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL)
+ u_pcibridge_aspmsetting &= ~BIT(0);
+
+ pci_write_config_byte(rtlpci->pdev, (num4bytes << 2),
+ u_pcibridge_aspmsetting);
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "PlatformEnableASPM(): Write reg[%x] = %x\n",
+ (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10),
+ u_pcibridge_aspmsetting);
+
+ udelay(50);
+
+ /*Get ASPM level (with/without Clock Req) */
+ aspmlevel = rtlpci->const_devicepci_aspm_setting;
+ u_device_aspmsetting = pcipriv->ndis_adapter.linkctrl_reg;
+
+ /*_rtl_pci_platform_switch_device_pci_aspm(dev,*/
+ /*(priv->ndis_adapter.linkctrl_reg | ASPMLevel)); */
+
+ u_device_aspmsetting |= aspmlevel;
+
+ _rtl_pci_platform_switch_device_pci_aspm(hw, u_device_aspmsetting);
+
+ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_CLK_REQ) {
+ _rtl_pci_switch_clk_req(hw, (ppsc->reg_rfps_level &
+ RT_RF_OFF_LEVL_CLK_REQ) ? 1 : 0);
+ RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_CLK_REQ);
+ }
+ udelay(100);
+}
+
+static bool rtl_pci_get_amd_l1_patch(struct ieee80211_hw *hw)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ bool status = false;
+ u8 offset_e0;
+ unsigned int offset_e4;
+
+ pci_write_config_byte(rtlpci->pdev, 0xe0, 0xa0);
+
+ pci_read_config_byte(rtlpci->pdev, 0xe0, &offset_e0);
+
+ if (offset_e0 == 0xA0) {
+ pci_read_config_dword(rtlpci->pdev, 0xe4, &offset_e4);
+ if (offset_e4 & BIT(23))
+ status = true;
+ }
+
+ return status;
+}
+
+static bool rtl_pci_check_buddy_priv(struct ieee80211_hw *hw,
+ struct rtl_priv **buddy_priv)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ bool find_buddy_priv = false;
+ struct rtl_priv *tpriv;
+ struct rtl_pci_priv *tpcipriv = NULL;
+
+ if (!list_empty(&rtlpriv->glb_var->glb_priv_list)) {
+ list_for_each_entry(tpriv, &rtlpriv->glb_var->glb_priv_list,
+ list) {
+ tpcipriv = (struct rtl_pci_priv *)tpriv->priv;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "pcipriv->ndis_adapter.funcnumber %x\n",
+ pcipriv->ndis_adapter.funcnumber);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "tpcipriv->ndis_adapter.funcnumber %x\n",
+ tpcipriv->ndis_adapter.funcnumber);
+
+ if ((pcipriv->ndis_adapter.busnumber ==
+ tpcipriv->ndis_adapter.busnumber) &&
+ (pcipriv->ndis_adapter.devnumber ==
+ tpcipriv->ndis_adapter.devnumber) &&
+ (pcipriv->ndis_adapter.funcnumber !=
+ tpcipriv->ndis_adapter.funcnumber)) {
+ find_buddy_priv = true;
+ break;
+ }
+ }
+ }
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "find_buddy_priv %d\n", find_buddy_priv);
+
+ if (find_buddy_priv)
+ *buddy_priv = tpriv;
+
+ return find_buddy_priv;
+}
+
+static void rtl_pci_get_linkcontrol_field(struct ieee80211_hw *hw)
+{
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
+ u8 capabilityoffset = pcipriv->ndis_adapter.pcibridge_pciehdr_offset;
+ u8 linkctrl_reg;
+ u8 num4bbytes;
+
+ num4bbytes = (capabilityoffset + 0x10) / 4;
+
+ /*Read Link Control Register */
+ pci_read_config_byte(rtlpci->pdev, (num4bbytes << 2), &linkctrl_reg);
+
+ pcipriv->ndis_adapter.pcibridge_linkctrlreg = linkctrl_reg;
+}
+
+static void rtl_pci_parse_configuration(struct pci_dev *pdev,
+ struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+
+ u8 tmp;
+ u16 linkctrl_reg;
+
+ /*Link Control Register */
+ pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &linkctrl_reg);
+ pcipriv->ndis_adapter.linkctrl_reg = (u8)linkctrl_reg;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Link Control Register =%x\n",
+ pcipriv->ndis_adapter.linkctrl_reg);
+
+ pci_read_config_byte(pdev, 0x98, &tmp);
+ tmp |= BIT(4);
+ pci_write_config_byte(pdev, 0x98, tmp);
+
+ tmp = 0x17;
+ pci_write_config_byte(pdev, 0x70f, tmp);
+}
+
+static void rtl_pci_init_aspm(struct ieee80211_hw *hw)
+{
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+ _rtl_pci_update_default_setting(hw);
+
+ if (ppsc->reg_rfps_level & RT_RF_PS_LEVEL_ALWAYS_ASPM) {
+ /*Always enable ASPM & Clock Req. */
+ rtl_pci_enable_aspm(hw);
+ RT_SET_PS_LEVEL(ppsc, RT_RF_PS_LEVEL_ALWAYS_ASPM);
+ }
+}
+
+static void _rtl_pci_io_handler_init(struct device *dev,
+ struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtlpriv->io.dev = dev;
+
+ rtlpriv->io.write8_async = pci_write8_async;
+ rtlpriv->io.write16_async = pci_write16_async;
+ rtlpriv->io.write32_async = pci_write32_async;
+
+ rtlpriv->io.read8_sync = pci_read8_sync;
+ rtlpriv->io.read16_sync = pci_read16_sync;
+ rtlpriv->io.read32_sync = pci_read32_sync;
+}
+
+static bool _rtl_update_earlymode_info(struct ieee80211_hw *hw,
+ struct sk_buff *skb,
+ struct rtl_tcb_desc *tcb_desc, u8 tid)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct sk_buff *next_skb;
+ u8 additionlen = FCS_LEN;
+
+ /* here open is 4, wep/tkip is 8, aes is 12*/
+ if (info->control.hw_key)
+ additionlen += info->control.hw_key->icv_len;
+
+ /* The most skb num is 6 */
+ tcb_desc->empkt_num = 0;
+ spin_lock_bh(&rtlpriv->locks.waitq_lock);
+ skb_queue_walk(&rtlpriv->mac80211.skb_waitq[tid], next_skb) {
+ struct ieee80211_tx_info *next_info;
+
+ next_info = IEEE80211_SKB_CB(next_skb);
+ if (next_info->flags & IEEE80211_TX_CTL_AMPDU) {
+ tcb_desc->empkt_len[tcb_desc->empkt_num] =
+ next_skb->len + additionlen;
+ tcb_desc->empkt_num++;
+ } else {
+ break;
+ }
+
+ if (skb_queue_is_last(&rtlpriv->mac80211.skb_waitq[tid],
+ next_skb))
+ break;
+
+ if (tcb_desc->empkt_num >= rtlhal->max_earlymode_num)
+ break;
+ }
+ spin_unlock_bh(&rtlpriv->locks.waitq_lock);
+
+ return true;
+}
+
+/* just for early mode now */
+static void _rtl_pci_tx_chk_waitq(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct sk_buff *skb = NULL;
+ struct ieee80211_tx_info *info = NULL;
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ int tid;
+
+ if (!rtlpriv->rtlhal.earlymode_enable)
+ return;
+
+ if (rtlpriv->dm.supp_phymode_switch &&
+ (rtlpriv->easy_concurrent_ctl.switch_in_process ||
+ (rtlpriv->buddy_priv &&
+ rtlpriv->buddy_priv->easy_concurrent_ctl.switch_in_process)))
+ return;
+ /* we just use em for BE/BK/VI/VO */
+ for (tid = 7; tid >= 0; tid--) {
+ u8 hw_queue = ac_to_hwq[rtl_tid_to_ac(tid)];
+ struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue];
+
+ while (!mac->act_scanning &&
+ rtlpriv->psc.rfpwr_state == ERFON) {
+ struct rtl_tcb_desc tcb_desc;
+
+ memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
+ spin_lock_bh(&rtlpriv->locks.waitq_lock);
+ if (!skb_queue_empty(&mac->skb_waitq[tid]) &&
+ (ring->entries - skb_queue_len(&ring->queue) >
+ rtlhal->max_earlymode_num)) {
+ skb = skb_dequeue(&mac->skb_waitq[tid]);
+ } else {
+ spin_unlock_bh(&rtlpriv->locks.waitq_lock);
+ break;
+ }
+ spin_unlock_bh(&rtlpriv->locks.waitq_lock);
+
+ /* Some macaddr can't do early mode. like
+ * multicast/broadcast/no_qos data
+ */
+ info = IEEE80211_SKB_CB(skb);
+ if (info->flags & IEEE80211_TX_CTL_AMPDU)
+ _rtl_update_earlymode_info(hw, skb,
+ &tcb_desc, tid);
+
+ rtlpriv->intf_ops->adapter_tx(hw, NULL, skb, &tcb_desc);
+ }
+ }
+}
+
+static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[prio];
+
+ while (skb_queue_len(&ring->queue)) {
+ struct sk_buff *skb;
+ struct ieee80211_tx_info *info;
+ __le16 fc;
+ u8 tid;
+ u8 *entry;
+
+ if (rtlpriv->use_new_trx_flow)
+ entry = (u8 *)(&ring->buffer_desc[ring->idx]);
+ else
+ entry = (u8 *)(&ring->desc[ring->idx]);
+
+ if (!rtlpriv->cfg->ops->is_tx_desc_closed(hw, prio, ring->idx))
+ return;
+ ring->idx = (ring->idx + 1) % ring->entries;
+
+ skb = __skb_dequeue(&ring->queue);
+ pci_unmap_single(rtlpci->pdev,
+ rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry, true,
+ HW_DESC_TXBUFF_ADDR),
+ skb->len, PCI_DMA_TODEVICE);
+
+ /* remove early mode header */
+ if (rtlpriv->rtlhal.earlymode_enable)
+ skb_pull(skb, EM_HDR_LEN);
+
+ RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_TRACE,
+ "new ring->idx:%d, free: skb_queue_len:%d, free: seq:%x\n",
+ ring->idx,
+ skb_queue_len(&ring->queue),
+ *(u16 *)(skb->data + 22));
+
+ if (prio == TXCMD_QUEUE) {
+ dev_kfree_skb(skb);
+ goto tx_status_ok;
+ }
+
+ /* for sw LPS, just after NULL skb send out, we can
+ * sure AP knows we are sleeping, we should not let
+ * rf sleep
+ */
+ fc = rtl_get_fc(skb);
+ if (ieee80211_is_nullfunc(fc)) {
+ if (ieee80211_has_pm(fc)) {
+ rtlpriv->mac80211.offchan_delay = true;
+ rtlpriv->psc.state_inap = true;
+ } else {
+ rtlpriv->psc.state_inap = false;
+ }
+ }
+ if (ieee80211_is_action(fc)) {
+ struct ieee80211_mgmt *action_frame =
+ (struct ieee80211_mgmt *)skb->data;
+ if (action_frame->u.action.u.ht_smps.action ==
+ WLAN_HT_ACTION_SMPS) {
+ dev_kfree_skb(skb);
+ goto tx_status_ok;
+ }
+ }
+
+ /* update tid tx pkt num */
+ tid = rtl_get_tid(skb);
+ if (tid <= 7)
+ rtlpriv->link_info.tidtx_inperiod[tid]++;
+
+ info = IEEE80211_SKB_CB(skb);
+ ieee80211_tx_info_clear_status(info);
+
+ info->flags |= IEEE80211_TX_STAT_ACK;
+ /*info->status.rates[0].count = 1; */
+
+ ieee80211_tx_status_irqsafe(hw, skb);
+
+ if ((ring->entries - skb_queue_len(&ring->queue)) <= 4) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
+ "more desc left, wake skb_queue@%d, ring->idx = %d, skb_queue_len = 0x%x\n",
+ prio, ring->idx,
+ skb_queue_len(&ring->queue));
+
+ ieee80211_wake_queue(hw, skb_get_queue_mapping (skb));
+ }
+tx_status_ok:
+ skb = NULL;
+ }
+
+ if (((rtlpriv->link_info.num_rx_inperiod +
+ rtlpriv->link_info.num_tx_inperiod) > 8) ||
+ (rtlpriv->link_info.num_rx_inperiod > 2))
+ rtl_lps_leave(hw);
+}
+
+static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw,
+ struct sk_buff *new_skb, u8 *entry,
+ int rxring_idx, int desc_idx)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ u32 bufferaddress;
+ u8 tmp_one = 1;
+ struct sk_buff *skb;
+
+ if (likely(new_skb)) {
+ skb = new_skb;
+ goto remap;
+ }
+ skb = dev_alloc_skb(rtlpci->rxbuffersize);
+ if (!skb)
+ return 0;
+
+remap:
+ /* just set skb->cb to mapping addr for pci_unmap_single use */
+ *((dma_addr_t *)skb->cb) =
+ pci_map_single(rtlpci->pdev, skb_tail_pointer(skb),
+ rtlpci->rxbuffersize, PCI_DMA_FROMDEVICE);
+ bufferaddress = *((dma_addr_t *)skb->cb);
+ if (pci_dma_mapping_error(rtlpci->pdev, bufferaddress))
+ return 0;
+ rtlpci->rx_ring[rxring_idx].rx_buf[desc_idx] = skb;
+ if (rtlpriv->use_new_trx_flow) {
+ /* skb->cb may be 64 bit address */
+ rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false,
+ HW_DESC_RX_PREPARE,
+ (u8 *)(dma_addr_t *)skb->cb);
+ } else {
+ rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false,
+ HW_DESC_RXBUFF_ADDR,
+ (u8 *)&bufferaddress);
+ rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false,
+ HW_DESC_RXPKT_LEN,
+ (u8 *)&rtlpci->rxbuffersize);
+ rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false,
+ HW_DESC_RXOWN,
+ (u8 *)&tmp_one);
+ }
+ return 1;
+}
+
+/* inorder to receive 8K AMSDU we have set skb to
+ * 9100bytes in init rx ring, but if this packet is
+ * not a AMSDU, this large packet will be sent to
+ * TCP/IP directly, this cause big packet ping fail
+ * like: "ping -s 65507", so here we will realloc skb
+ * based on the true size of packet, Mac80211
+ * Probably will do it better, but does not yet.
+ *
+ * Some platform will fail when alloc skb sometimes.
+ * in this condition, we will send the old skb to
+ * mac80211 directly, this will not cause any other
+ * issues, but only this packet will be lost by TCP/IP
+ */
+static void _rtl_pci_rx_to_mac80211(struct ieee80211_hw *hw,
+ struct sk_buff *skb,
+ struct ieee80211_rx_status rx_status)
+{
+ if (unlikely(!rtl_action_proc(hw, skb, false))) {
+ dev_kfree_skb_any(skb);
+ } else {
+ struct sk_buff *uskb = NULL;
+
+ uskb = dev_alloc_skb(skb->len + 128);
+ if (likely(uskb)) {
+ memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status,
+ sizeof(rx_status));
+ skb_put_data(uskb, skb->data, skb->len);
+ dev_kfree_skb_any(skb);
+ ieee80211_rx_irqsafe(hw, uskb);
+ } else {
+ ieee80211_rx_irqsafe(hw, skb);
+ }
+ }
+}
+
+/*hsisr interrupt handler*/
+static void _rtl_pci_hs_interrupt(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[MAC_HSISR],
+ rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[MAC_HSISR]) |
+ rtlpci->sys_irq_mask);
+}
+
+static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ int rxring_idx = RTL_PCI_RX_MPDU_QUEUE;
+ struct ieee80211_rx_status rx_status = { 0 };
+ unsigned int count = rtlpci->rxringcount;
+ u8 own;
+ u8 tmp_one;
+ bool unicast = false;
+ u8 hw_queue = 0;
+ unsigned int rx_remained_cnt = 0;
+ struct rtl_stats stats = {
+ .signal = 0,
+ .rate = 0,
+ };
+
+ /*RX NORMAL PKT */
+ while (count--) {
+ struct ieee80211_hdr *hdr;
+ __le16 fc;
+ u16 len;
+ /*rx buffer descriptor */
+ struct rtl_rx_buffer_desc *buffer_desc = NULL;
+ /*if use new trx flow, it means wifi info */
+ struct rtl_rx_desc *pdesc = NULL;
+ /*rx pkt */
+ struct sk_buff *skb = rtlpci->rx_ring[rxring_idx].rx_buf[
+ rtlpci->rx_ring[rxring_idx].idx];
+ struct sk_buff *new_skb;
+
+ if (rtlpriv->use_new_trx_flow) {
+ if (rx_remained_cnt == 0)
+ rx_remained_cnt =
+ rtlpriv->cfg->ops->rx_desc_buff_remained_cnt(hw,
+ hw_queue);
+ if (rx_remained_cnt == 0)
+ return;
+ buffer_desc = &rtlpci->rx_ring[rxring_idx].buffer_desc[
+ rtlpci->rx_ring[rxring_idx].idx];
+ pdesc = (struct rtl_rx_desc *)skb->data;
+ } else { /* rx descriptor */
+ pdesc = &rtlpci->rx_ring[rxring_idx].desc[
+ rtlpci->rx_ring[rxring_idx].idx];
+
+ own = (u8)rtlpriv->cfg->ops->get_desc(hw, (u8 *)pdesc,
+ false,
+ HW_DESC_OWN);
+ if (own) /* wait data to be filled by hardware */
+ return;
+ }
+
+ /* Reaching this point means: data is filled already
+ * AAAAAAttention !!!
+ * We can NOT access 'skb' before 'pci_unmap_single'
+ */
+ pci_unmap_single(rtlpci->pdev, *((dma_addr_t *)skb->cb),
+ rtlpci->rxbuffersize, PCI_DMA_FROMDEVICE);
+
+ /* get a new skb - if fail, old one will be reused */
+ new_skb = dev_alloc_skb(rtlpci->rxbuffersize);
+ if (unlikely(!new_skb))
+ goto no_new;
+ memset(&rx_status, 0, sizeof(rx_status));
+ rtlpriv->cfg->ops->query_rx_desc(hw, &stats,
+ &rx_status, (u8 *)pdesc, skb);
+
+ if (rtlpriv->use_new_trx_flow)
+ rtlpriv->cfg->ops->rx_check_dma_ok(hw,
+ (u8 *)buffer_desc,
+ hw_queue);
+
+ len = rtlpriv->cfg->ops->get_desc(hw, (u8 *)pdesc, false,
+ HW_DESC_RXPKT_LEN);
+
+ if (skb->end - skb->tail > len) {
+ skb_put(skb, len);
+ if (rtlpriv->use_new_trx_flow)
+ skb_reserve(skb, stats.rx_drvinfo_size +
+ stats.rx_bufshift + 24);
+ else
+ skb_reserve(skb, stats.rx_drvinfo_size +
+ stats.rx_bufshift);
+ } else {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ "skb->end - skb->tail = %d, len is %d\n",
+ skb->end - skb->tail, len);
+ dev_kfree_skb_any(skb);
+ goto new_trx_end;
+ }
+ /* handle command packet here */
+ if (rtlpriv->cfg->ops->rx_command_packet &&
+ rtlpriv->cfg->ops->rx_command_packet(hw, &stats, skb)) {
+ dev_kfree_skb_any(skb);
+ goto new_trx_end;
+ }
+
+ /*
+ * NOTICE This can not be use for mac80211,
+ * this is done in mac80211 code,
+ * if done here sec DHCP will fail
+ * skb_trim(skb, skb->len - 4);
+ */
+
+ hdr = rtl_get_hdr(skb);
+ fc = rtl_get_fc(skb);
+
+ if (!stats.crc && !stats.hwerror) {
+ memcpy(IEEE80211_SKB_RXCB(skb), &rx_status,
+ sizeof(rx_status));
+
+ if (is_broadcast_ether_addr(hdr->addr1)) {
+ ;/*TODO*/
+ } else if (is_multicast_ether_addr(hdr->addr1)) {
+ ;/*TODO*/
+ } else {
+ unicast = true;
+ rtlpriv->stats.rxbytesunicast += skb->len;
+ }
+ rtl_is_special_data(hw, skb, false, true);
+
+ if (ieee80211_is_data(fc)) {
+ rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX);
+ if (unicast)
+ rtlpriv->link_info.num_rx_inperiod++;
+ }
+
+ rtl_collect_scan_list(hw, skb);
+
+ /* static bcn for roaming */
+ rtl_beacon_statistic(hw, skb);
+ rtl_p2p_info(hw, (void *)skb->data, skb->len);
+ /* for sw lps */
+ rtl_swlps_beacon(hw, (void *)skb->data, skb->len);
+ rtl_recognize_peer(hw, (void *)skb->data, skb->len);
+ if ((rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP) &&
+ (rtlpriv->rtlhal.current_bandtype ==
+ BAND_ON_2_4G) &&
+ (ieee80211_is_beacon(fc) ||
+ ieee80211_is_probe_resp(fc))) {
+ dev_kfree_skb_any(skb);
+ } else {
+ rtl_check_beacon_key(hw, (void *)skb->data,
+ skb->len);
+ _rtl_pci_rx_to_mac80211(hw, skb, rx_status);
+ }
+ } else {
+ dev_kfree_skb_any(skb);
+ }
+new_trx_end:
+ if (rtlpriv->use_new_trx_flow) {
+ rtlpci->rx_ring[hw_queue].next_rx_rp += 1;
+ rtlpci->rx_ring[hw_queue].next_rx_rp %=
+ RTL_PCI_MAX_RX_COUNT;
+
+ rx_remained_cnt--;
+ rtl_write_word(rtlpriv, 0x3B4,
+ rtlpci->rx_ring[hw_queue].next_rx_rp);
+ }
+ if (((rtlpriv->link_info.num_rx_inperiod +
+ rtlpriv->link_info.num_tx_inperiod) > 8) ||
+ (rtlpriv->link_info.num_rx_inperiod > 2))
+ rtl_lps_leave(hw);
+ skb = new_skb;
+no_new:
+ if (rtlpriv->use_new_trx_flow) {
+ _rtl_pci_init_one_rxdesc(hw, skb, (u8 *)buffer_desc,
+ rxring_idx,
+ rtlpci->rx_ring[rxring_idx].idx);
+ } else {
+ _rtl_pci_init_one_rxdesc(hw, skb, (u8 *)pdesc,
+ rxring_idx,
+ rtlpci->rx_ring[rxring_idx].idx);
+ if (rtlpci->rx_ring[rxring_idx].idx ==
+ rtlpci->rxringcount - 1)
+ rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc,
+ false,
+ HW_DESC_RXERO,
+ (u8 *)&tmp_one);
+ }
+ rtlpci->rx_ring[rxring_idx].idx =
+ (rtlpci->rx_ring[rxring_idx].idx + 1) %
+ rtlpci->rxringcount;
+ }
+}
+
+static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
+{
+ struct ieee80211_hw *hw = dev_id;
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ unsigned long flags;
+ u32 inta = 0;
+ u32 intb = 0;
+ u32 intc = 0;
+ u32 intd = 0;
+ irqreturn_t ret = IRQ_HANDLED;
+
+ if (rtlpci->irq_enabled == 0)
+ return ret;
+
+ spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
+ rtlpriv->cfg->ops->disable_interrupt(hw);
+
+ /*read ISR: 4/8bytes */
+ rtlpriv->cfg->ops->interrupt_recognized(hw, &inta, &intb, &intc, &intd);
+
+ /*Shared IRQ or HW disappeared */
+ if (!inta || inta == 0xffff)
+ goto done;
+
+ /*<1> beacon related */
+ if (inta & rtlpriv->cfg->maps[RTL_IMR_TBDOK]) {
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+ "beacon ok interrupt!\n");
+ }
+
+ if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_TBDER])) {
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+ "beacon err interrupt!\n");
+ }
+
+ if (inta & rtlpriv->cfg->maps[RTL_IMR_BDOK])
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "beacon interrupt!\n");
+
+ if (inta & rtlpriv->cfg->maps[RTL_IMR_BCNINT]) {
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+ "prepare beacon for interrupt!\n");
+ tasklet_schedule(&rtlpriv->works.irq_prepare_bcn_tasklet);
+ }
+
+ /*<2> Tx related */
+ if (unlikely(intb & rtlpriv->cfg->maps[RTL_IMR_TXFOVW]))
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "IMR_TXFOVW!\n");
+
+ if (inta & rtlpriv->cfg->maps[RTL_IMR_MGNTDOK]) {
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+ "Manage ok interrupt!\n");
+ _rtl_pci_tx_isr(hw, MGNT_QUEUE);
+ }
+
+ if (inta & rtlpriv->cfg->maps[RTL_IMR_HIGHDOK]) {
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+ "HIGH_QUEUE ok interrupt!\n");
+ _rtl_pci_tx_isr(hw, HIGH_QUEUE);
+ }
+
+ if (inta & rtlpriv->cfg->maps[RTL_IMR_BKDOK]) {
+ rtlpriv->link_info.num_tx_inperiod++;
+
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+ "BK Tx OK interrupt!\n");
+ _rtl_pci_tx_isr(hw, BK_QUEUE);
+ }
+
+ if (inta & rtlpriv->cfg->maps[RTL_IMR_BEDOK]) {
+ rtlpriv->link_info.num_tx_inperiod++;
+
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+ "BE TX OK interrupt!\n");
+ _rtl_pci_tx_isr(hw, BE_QUEUE);
+ }
+
+ if (inta & rtlpriv->cfg->maps[RTL_IMR_VIDOK]) {
+ rtlpriv->link_info.num_tx_inperiod++;
+
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+ "VI TX OK interrupt!\n");
+ _rtl_pci_tx_isr(hw, VI_QUEUE);
+ }
+
+ if (inta & rtlpriv->cfg->maps[RTL_IMR_VODOK]) {
+ rtlpriv->link_info.num_tx_inperiod++;
+
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+ "Vo TX OK interrupt!\n");
+ _rtl_pci_tx_isr(hw, VO_QUEUE);
+ }
+
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8822BE) {
+ if (intd & rtlpriv->cfg->maps[RTL_IMR_H2CDOK]) {
+ rtlpriv->link_info.num_tx_inperiod++;
+
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+ "H2C TX OK interrupt!\n");
+ _rtl_pci_tx_isr(hw, H2C_QUEUE);
+ }
+ }
+
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) {
+ if (inta & rtlpriv->cfg->maps[RTL_IMR_COMDOK]) {
+ rtlpriv->link_info.num_tx_inperiod++;
+
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+ "CMD TX OK interrupt!\n");
+ _rtl_pci_tx_isr(hw, TXCMD_QUEUE);
+ }
+ }
+
+ /*<3> Rx related */
+ if (inta & rtlpriv->cfg->maps[RTL_IMR_ROK]) {
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "Rx ok interrupt!\n");
+ _rtl_pci_rx_interrupt(hw);
+ }
+
+ if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RDU])) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ "rx descriptor unavailable!\n");
+ _rtl_pci_rx_interrupt(hw);
+ }
+
+ if (unlikely(intb & rtlpriv->cfg->maps[RTL_IMR_RXFOVW])) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "rx overflow !\n");
+ _rtl_pci_rx_interrupt(hw);
+ }
+
+ /*<4> fw related*/
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723AE) {
+ if (inta & rtlpriv->cfg->maps[RTL_IMR_C2HCMD]) {
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+ "firmware interrupt!\n");
+ queue_delayed_work(rtlpriv->works.rtl_wq,
+ &rtlpriv->works.fwevt_wq, 0);
+ }
+ }
+
+ /*<5> hsisr related*/
+ /* Only 8188EE & 8723BE Supported.
+ * If Other ICs Come in, System will corrupt,
+ * because maps[RTL_IMR_HSISR_IND] & maps[MAC_HSISR]
+ * are not initialized
+ */
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8188EE ||
+ rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) {
+ if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_HSISR_IND])) {
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+ "hsisr interrupt!\n");
+ _rtl_pci_hs_interrupt(hw);
+ }
+ }
+
+ if (rtlpriv->rtlhal.earlymode_enable)
+ tasklet_schedule(&rtlpriv->works.irq_tasklet);
+
+done:
+ rtlpriv->cfg->ops->enable_interrupt(hw);
+ spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+ return ret;
+}
+
+static void _rtl_pci_irq_tasklet(struct ieee80211_hw *hw)
+{
+ _rtl_pci_tx_chk_waitq(hw);
+}
+
+static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl8192_tx_ring *ring = NULL;
+ struct ieee80211_hdr *hdr = NULL;
+ struct ieee80211_tx_info *info = NULL;
+ struct sk_buff *pskb = NULL;
+ struct rtl_tx_desc *pdesc = NULL;
+ struct rtl_tcb_desc tcb_desc;
+ /*This is for new trx flow*/
+ struct rtl_tx_buffer_desc *pbuffer_desc = NULL;
+ u8 temp_one = 1;
+ u8 *entry;
+
+ memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
+ ring = &rtlpci->tx_ring[BEACON_QUEUE];
+ pskb = __skb_dequeue(&ring->queue);
+ if (rtlpriv->use_new_trx_flow)
+ entry = (u8 *)(&ring->buffer_desc[ring->idx]);
+ else
+ entry = (u8 *)(&ring->desc[ring->idx]);
+ if (pskb) {
+ pci_unmap_single(rtlpci->pdev,
+ rtlpriv->cfg->ops->get_desc(
+ hw, (u8 *)entry, true, HW_DESC_TXBUFF_ADDR),
+ pskb->len, PCI_DMA_TODEVICE);
+ kfree_skb(pskb);
+ }
+
+ /*NB: the beacon data buffer must be 32-bit aligned. */
+ pskb = ieee80211_beacon_get(hw, mac->vif);
+ if (!pskb)
+ return;
+ hdr = rtl_get_hdr(pskb);
+ info = IEEE80211_SKB_CB(pskb);
+ pdesc = &ring->desc[0];
+ if (rtlpriv->use_new_trx_flow)
+ pbuffer_desc = &ring->buffer_desc[0];
+
+ rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc,
+ (u8 *)pbuffer_desc, info, NULL, pskb,
+ BEACON_QUEUE, &tcb_desc);
+
+ __skb_queue_tail(&ring->queue, pskb);
+
+ if (rtlpriv->use_new_trx_flow) {
+ temp_one = 4;
+ rtlpriv->cfg->ops->set_desc(hw, (u8 *)pbuffer_desc, true,
+ HW_DESC_OWN, (u8 *)&temp_one);
+ } else {
+ rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true, HW_DESC_OWN,
+ &temp_one);
+ }
+}
+
+static void _rtl_pci_init_trx_var(struct ieee80211_hw *hw)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+ u8 i;
+ u16 desc_num;
+
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192EE)
+ desc_num = TX_DESC_NUM_92E;
+ else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8822BE)
+ desc_num = TX_DESC_NUM_8822B;
+ else
+ desc_num = RT_TXDESC_NUM;
+
+ for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++)
+ rtlpci->txringcount[i] = desc_num;
+
+ /*
+ *we just alloc 2 desc for beacon queue,
+ *because we just need first desc in hw beacon.
+ */
+ rtlpci->txringcount[BEACON_QUEUE] = 2;
+
+ /*BE queue need more descriptor for performance
+ *consideration or, No more tx desc will happen,
+ *and may cause mac80211 mem leakage.
+ */
+ if (!rtl_priv(hw)->use_new_trx_flow)
+ rtlpci->txringcount[BE_QUEUE] = RT_TXDESC_NUM_BE_QUEUE;
+
+ rtlpci->rxbuffersize = 9100; /*2048/1024; */
+ rtlpci->rxringcount = RTL_PCI_MAX_RX_COUNT; /*64; */
+}
+
+static void _rtl_pci_init_struct(struct ieee80211_hw *hw,
+ struct pci_dev *pdev)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ rtlpci->up_first_time = true;
+ rtlpci->being_init_adapter = false;
+
+ rtlhal->hw = hw;
+ rtlpci->pdev = pdev;
+
+ /*Tx/Rx related var */
+ _rtl_pci_init_trx_var(hw);
+
+ /*IBSS*/
+ mac->beacon_interval = 100;
+
+ /*AMPDU*/
+ mac->min_space_cfg = 0;
+ mac->max_mss_density = 0;
+ /*set sane AMPDU defaults */
+ mac->current_ampdu_density = 7;
+ mac->current_ampdu_factor = 3;
+
+ /*Retry Limit*/
+ mac->retry_short = 7;
+ mac->retry_long = 7;
+
+ /*QOS*/
+ rtlpci->acm_method = EACMWAY2_SW;
+
+ /*task */
+ tasklet_init(&rtlpriv->works.irq_tasklet,
+ (void (*)(unsigned long))_rtl_pci_irq_tasklet,
+ (unsigned long)hw);
+ tasklet_init(&rtlpriv->works.irq_prepare_bcn_tasklet,
+ (void (*)(unsigned long))_rtl_pci_prepare_bcn_tasklet,
+ (unsigned long)hw);
+ INIT_WORK(&rtlpriv->works.lps_change_work,
+ rtl_lps_change_work_callback);
+}
+
+static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw,
+ unsigned int prio, unsigned int entries)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_tx_buffer_desc *buffer_desc;
+ struct rtl_tx_desc *desc;
+ dma_addr_t buffer_desc_dma, desc_dma;
+ u32 nextdescaddress;
+ int i;
+
+ /* alloc tx buffer desc for new trx flow*/
+ if (rtlpriv->use_new_trx_flow) {
+ buffer_desc =
+ pci_zalloc_consistent(rtlpci->pdev,
+ sizeof(*buffer_desc) * entries,
+ &buffer_desc_dma);
+
+ if (!buffer_desc || (unsigned long)buffer_desc & 0xFF) {
+ pr_err("Cannot allocate TX ring (prio = %d)\n",
+ prio);
+ return -ENOMEM;
+ }
+
+ rtlpci->tx_ring[prio].buffer_desc = buffer_desc;
+ rtlpci->tx_ring[prio].buffer_desc_dma = buffer_desc_dma;
+
+ rtlpci->tx_ring[prio].cur_tx_rp = 0;
+ rtlpci->tx_ring[prio].cur_tx_wp = 0;
+ }
+
+ /* alloc dma for this ring */
+ desc = pci_zalloc_consistent(rtlpci->pdev,
+ sizeof(*desc) * entries, &desc_dma);
+
+ if (!desc || (unsigned long)desc & 0xFF) {
+ pr_err("Cannot allocate TX ring (prio = %d)\n", prio);
+ return -ENOMEM;
+ }
+
+ rtlpci->tx_ring[prio].desc = desc;
+ rtlpci->tx_ring[prio].dma = desc_dma;
+
+ rtlpci->tx_ring[prio].idx = 0;
+ rtlpci->tx_ring[prio].entries = entries;
+ skb_queue_head_init(&rtlpci->tx_ring[prio].queue);
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "queue:%d, ring_addr:%p\n",
+ prio, desc);
+
+ /* init every desc in this ring */
+ if (!rtlpriv->use_new_trx_flow) {
+ for (i = 0; i < entries; i++) {
+ nextdescaddress = (u32)desc_dma +
+ ((i + 1) % entries) *
+ sizeof(*desc);
+
+ rtlpriv->cfg->ops->set_desc(hw, (u8 *)&desc[i],
+ true,
+ HW_DESC_TX_NEXTDESC_ADDR,
+ (u8 *)&nextdescaddress);
+ }
+ }
+ return 0;
+}
+
+static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw, int rxring_idx)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ int i;
+
+ if (rtlpriv->use_new_trx_flow) {
+ struct rtl_rx_buffer_desc *entry = NULL;
+ /* alloc dma for this ring */
+ rtlpci->rx_ring[rxring_idx].buffer_desc =
+ pci_zalloc_consistent(rtlpci->pdev,
+ sizeof(*rtlpci->rx_ring[rxring_idx].buffer_desc) *
+ rtlpci->rxringcount,
+ &rtlpci->rx_ring[rxring_idx].dma);
+ if (!rtlpci->rx_ring[rxring_idx].buffer_desc ||
+ (ulong)rtlpci->rx_ring[rxring_idx].buffer_desc & 0xFF) {
+ pr_err("Cannot allocate RX ring\n");
+ return -ENOMEM;
+ }
+
+ /* init every desc in this ring */
+ rtlpci->rx_ring[rxring_idx].idx = 0;
+ for (i = 0; i < rtlpci->rxringcount; i++) {
+ entry = &rtlpci->rx_ring[rxring_idx].buffer_desc[i];
+ if (!_rtl_pci_init_one_rxdesc(hw, NULL, (u8 *)entry,
+ rxring_idx, i))
+ return -ENOMEM;
+ }
+ } else {
+ struct rtl_rx_desc *entry = NULL;
+ u8 tmp_one = 1;
+ /* alloc dma for this ring */
+ rtlpci->rx_ring[rxring_idx].desc =
+ pci_zalloc_consistent(rtlpci->pdev,
+ sizeof(*rtlpci->rx_ring[rxring_idx].desc) *
+ rtlpci->rxringcount,
+ &rtlpci->rx_ring[rxring_idx].dma);
+ if (!rtlpci->rx_ring[rxring_idx].desc ||
+ (unsigned long)rtlpci->rx_ring[rxring_idx].desc & 0xFF) {
+ pr_err("Cannot allocate RX ring\n");
+ return -ENOMEM;
+ }
+
+ /* init every desc in this ring */
+ rtlpci->rx_ring[rxring_idx].idx = 0;
+
+ for (i = 0; i < rtlpci->rxringcount; i++) {
+ entry = &rtlpci->rx_ring[rxring_idx].desc[i];
+ if (!_rtl_pci_init_one_rxdesc(hw, NULL, (u8 *)entry,
+ rxring_idx, i))
+ return -ENOMEM;
+ }
+
+ rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false,
+ HW_DESC_RXERO, &tmp_one);
+ }
+ return 0;
+}
+
+static void _rtl_pci_free_tx_ring(struct ieee80211_hw *hw,
+ unsigned int prio)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[prio];
+
+ /* free every desc in this ring */
+ while (skb_queue_len(&ring->queue)) {
+ u8 *entry;
+ struct sk_buff *skb = __skb_dequeue(&ring->queue);
+
+ if (rtlpriv->use_new_trx_flow)
+ entry = (u8 *)(&ring->buffer_desc[ring->idx]);
+ else
+ entry = (u8 *)(&ring->desc[ring->idx]);
+
+ pci_unmap_single(rtlpci->pdev,
+ rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry,
+ true,
+ HW_DESC_TXBUFF_ADDR),
+ skb->len, PCI_DMA_TODEVICE);
+ kfree_skb(skb);
+ ring->idx = (ring->idx + 1) % ring->entries;
+ }
+
+ /* free dma of this ring */
+ pci_free_consistent(rtlpci->pdev,
+ sizeof(*ring->desc) * ring->entries,
+ ring->desc, ring->dma);
+ ring->desc = NULL;
+ if (rtlpriv->use_new_trx_flow) {
+ pci_free_consistent(rtlpci->pdev,
+ sizeof(*ring->buffer_desc) * ring->entries,
+ ring->buffer_desc, ring->buffer_desc_dma);
+ ring->buffer_desc = NULL;
+ }
+}
+
+static void _rtl_pci_free_rx_ring(struct ieee80211_hw *hw, int rxring_idx)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ int i;
+
+ /* free every desc in this ring */
+ for (i = 0; i < rtlpci->rxringcount; i++) {
+ struct sk_buff *skb = rtlpci->rx_ring[rxring_idx].rx_buf[i];
+
+ if (!skb)
+ continue;
+ pci_unmap_single(rtlpci->pdev, *((dma_addr_t *)skb->cb),
+ rtlpci->rxbuffersize, PCI_DMA_FROMDEVICE);
+ kfree_skb(skb);
+ }
+
+ /* free dma of this ring */
+ if (rtlpriv->use_new_trx_flow) {
+ pci_free_consistent(rtlpci->pdev,
+ sizeof(*rtlpci->rx_ring[rxring_idx].buffer_desc) *
+ rtlpci->rxringcount,
+ rtlpci->rx_ring[rxring_idx].buffer_desc,
+ rtlpci->rx_ring[rxring_idx].dma);
+ rtlpci->rx_ring[rxring_idx].buffer_desc = NULL;
+ } else {
+ pci_free_consistent(rtlpci->pdev,
+ sizeof(*rtlpci->rx_ring[rxring_idx].desc) *
+ rtlpci->rxringcount,
+ rtlpci->rx_ring[rxring_idx].desc,
+ rtlpci->rx_ring[rxring_idx].dma);
+ rtlpci->rx_ring[rxring_idx].desc = NULL;
+ }
+}
+
+static int _rtl_pci_init_trx_ring(struct ieee80211_hw *hw)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ int ret;
+ int i, rxring_idx;
+
+ /* rxring_idx 0:RX_MPDU_QUEUE
+ * rxring_idx 1:RX_CMD_QUEUE
+ */
+ for (rxring_idx = 0; rxring_idx < RTL_PCI_MAX_RX_QUEUE; rxring_idx++) {
+ ret = _rtl_pci_init_rx_ring(hw, rxring_idx);
+ if (ret)
+ return ret;
+ }
+
+ for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++) {
+ ret = _rtl_pci_init_tx_ring(hw, i, rtlpci->txringcount[i]);
+ if (ret)
+ goto err_free_rings;
+ }
+
+ return 0;
+
+err_free_rings:
+ for (rxring_idx = 0; rxring_idx < RTL_PCI_MAX_RX_QUEUE; rxring_idx++)
+ _rtl_pci_free_rx_ring(hw, rxring_idx);
+
+ for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++)
+ if (rtlpci->tx_ring[i].desc ||
+ rtlpci->tx_ring[i].buffer_desc)
+ _rtl_pci_free_tx_ring(hw, i);
+
+ return 1;
+}
+
+static int _rtl_pci_deinit_trx_ring(struct ieee80211_hw *hw)
+{
+ u32 i, rxring_idx;
+
+ /*free rx rings */
+ for (rxring_idx = 0; rxring_idx < RTL_PCI_MAX_RX_QUEUE; rxring_idx++)
+ _rtl_pci_free_rx_ring(hw, rxring_idx);
+
+ /*free tx rings */
+ for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++)
+ _rtl_pci_free_tx_ring(hw, i);
+
+ return 0;
+}
+
+int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ int i, rxring_idx;
+ unsigned long flags;
+ u8 tmp_one = 1;
+ u32 bufferaddress;
+ /* rxring_idx 0:RX_MPDU_QUEUE */
+ /* rxring_idx 1:RX_CMD_QUEUE */
+ for (rxring_idx = 0; rxring_idx < RTL_PCI_MAX_RX_QUEUE; rxring_idx++) {
+ /* force the rx_ring[RX_MPDU_QUEUE/
+ * RX_CMD_QUEUE].idx to the first one
+ * new trx flow, do nothing
+ */
+ if (!rtlpriv->use_new_trx_flow &&
+ rtlpci->rx_ring[rxring_idx].desc) {
+ struct rtl_rx_desc *entry = NULL;
+
+ rtlpci->rx_ring[rxring_idx].idx = 0;
+ for (i = 0; i < rtlpci->rxringcount; i++) {
+ entry = &rtlpci->rx_ring[rxring_idx].desc[i];
+ bufferaddress =
+ rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry,
+ false, HW_DESC_RXBUFF_ADDR);
+ memset((u8 *)entry, 0,
+ sizeof(*rtlpci->rx_ring
+ [rxring_idx].desc));/*clear one entry*/
+ if (rtlpriv->use_new_trx_flow) {
+ /* This is deadcode */
+ rtlpriv->cfg->ops->set_desc(hw,
+ (u8 *)entry, false,
+ HW_DESC_RX_PREPARE,
+ (u8 *)&bufferaddress);
+ } else {
+ rtlpriv->cfg->ops->set_desc(hw,
+ (u8 *)entry, false,
+ HW_DESC_RXBUFF_ADDR,
+ (u8 *)&bufferaddress);
+ rtlpriv->cfg->ops->set_desc(hw,
+ (u8 *)entry, false,
+ HW_DESC_RXPKT_LEN,
+ (u8 *)&rtlpci->rxbuffersize);
+ rtlpriv->cfg->ops->set_desc(hw,
+ (u8 *)entry, false,
+ HW_DESC_RXOWN,
+ (u8 *)&tmp_one);
+ }
+ }
+ rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false,
+ HW_DESC_RXERO, (u8 *)&tmp_one);
+ }
+ rtlpci->rx_ring[rxring_idx].idx = 0;
+ }
+
+ /*
+ *after reset, release previous pending packet,
+ *and force the tx idx to the first one
+ */
+ spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
+ for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++) {
+ if (rtlpci->tx_ring[i].desc ||
+ rtlpci->tx_ring[i].buffer_desc) {
+ struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[i];
+
+ while (skb_queue_len(&ring->queue)) {
+ u8 *entry;
+ struct sk_buff *skb =
+ __skb_dequeue(&ring->queue);
+ if (rtlpriv->use_new_trx_flow)
+ entry = (u8 *)(&ring->buffer_desc
+ [ring->idx]);
+ else
+ entry = (u8 *)(&ring->desc[ring->idx]);
+
+ pci_unmap_single(rtlpci->pdev,
+ rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry,
+ true, HW_DESC_TXBUFF_ADDR),
+ skb->len, PCI_DMA_TODEVICE);
+ dev_kfree_skb_irq(skb);
+ ring->idx = (ring->idx + 1) % ring->entries;
+ }
+
+ if (rtlpriv->use_new_trx_flow) {
+ rtlpci->tx_ring[i].cur_tx_rp = 0;
+ rtlpci->tx_ring[i].cur_tx_wp = 0;
+ }
+
+ ring->idx = 0;
+ ring->entries = rtlpci->txringcount[i];
+ }
+ }
+ spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+
+ return 0;
+}
+
+static bool rtl_pci_tx_chk_waitq_insert(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
+ struct sk_buff *skb)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_sta_info *sta_entry = NULL;
+ u8 tid = rtl_get_tid(skb);
+ __le16 fc = rtl_get_fc(skb);
+
+ if (!sta)
+ return false;
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+
+ if (!rtlpriv->rtlhal.earlymode_enable)
+ return false;
+ if (ieee80211_is_nullfunc(fc))
+ return false;
+ if (ieee80211_is_qos_nullfunc(fc))
+ return false;
+ if (ieee80211_is_pspoll(fc))
+ return false;
+ if (sta_entry->tids[tid].agg.agg_state != RTL_AGG_OPERATIONAL)
+ return false;
+ if (_rtl_mac_to_hwqueue(hw, skb) > VO_QUEUE)
+ return false;
+ if (tid > 7)
+ return false;
+
+ /* maybe every tid should be checked */
+ if (!rtlpriv->link_info.higher_busytxtraffic[tid])
+ return false;
+
+ spin_lock_bh(&rtlpriv->locks.waitq_lock);
+ skb_queue_tail(&rtlpriv->mac80211.skb_waitq[tid], skb);
+ spin_unlock_bh(&rtlpriv->locks.waitq_lock);
+
+ return true;
+}
+
+static int rtl_pci_tx(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
+ struct sk_buff *skb,
+ struct rtl_tcb_desc *ptcb_desc)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_sta_info *sta_entry = NULL;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct rtl8192_tx_ring *ring;
+ struct rtl_tx_desc *pdesc;
+ struct rtl_tx_buffer_desc *ptx_bd_desc = NULL;
+ u16 idx;
+ u8 hw_queue = _rtl_mac_to_hwqueue(hw, skb);
+ unsigned long flags;
+ struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
+ __le16 fc = rtl_get_fc(skb);
+ u8 *pda_addr = hdr->addr1;
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ /*ssn */
+ u8 tid = 0;
+ u16 seq_number = 0;
+ u8 own;
+ u8 temp_one = 1;
+
+ if (ieee80211_is_mgmt(fc))
+ rtl_tx_mgmt_proc(hw, skb);
+
+ if (rtlpriv->psc.sw_ps_enabled) {
+ if (ieee80211_is_data(fc) && !ieee80211_is_nullfunc(fc) &&
+ !ieee80211_has_pm(fc))
+ hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
+ }
+
+ rtl_action_proc(hw, skb, true);
+
+ if (is_multicast_ether_addr(pda_addr))
+ rtlpriv->stats.txbytesmulticast += skb->len;
+ else if (is_broadcast_ether_addr(pda_addr))
+ rtlpriv->stats.txbytesbroadcast += skb->len;
+ else
+ rtlpriv->stats.txbytesunicast += skb->len;
+
+ spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
+ ring = &rtlpci->tx_ring[hw_queue];
+ if (hw_queue != BEACON_QUEUE) {
+ if (rtlpriv->use_new_trx_flow)
+ idx = ring->cur_tx_wp;
+ else
+ idx = (ring->idx + skb_queue_len(&ring->queue)) %
+ ring->entries;
+ } else {
+ idx = 0;
+ }
+
+ pdesc = &ring->desc[idx];
+ if (rtlpriv->use_new_trx_flow) {
+ ptx_bd_desc = &ring->buffer_desc[idx];
+ } else {
+ own = (u8)rtlpriv->cfg->ops->get_desc(hw, (u8 *)pdesc,
+ true, HW_DESC_OWN);
+
+ if ((own == 1) && (hw_queue != BEACON_QUEUE)) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ "No more TX desc@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%x\n",
+ hw_queue, ring->idx, idx,
+ skb_queue_len(&ring->queue));
+
+ spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock,
+ flags);
+ return skb->len;
+ }
+ }
+
+ if (rtlpriv->cfg->ops->get_available_desc &&
+ rtlpriv->cfg->ops->get_available_desc(hw, hw_queue) == 0) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ "get_available_desc fail\n");
+ spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+ return skb->len;
+ }
+
+ if (ieee80211_is_data_qos(fc)) {
+ tid = rtl_get_tid(skb);
+ if (sta) {
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+ seq_number = (le16_to_cpu(hdr->seq_ctrl) &
+ IEEE80211_SCTL_SEQ) >> 4;
+ seq_number += 1;
+
+ if (!ieee80211_has_morefrags(hdr->frame_control))
+ sta_entry->tids[tid].seq_number = seq_number;
+ }
+ }
+
+ if (ieee80211_is_data(fc))
+ rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX);
+
+ rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc,
+ (u8 *)ptx_bd_desc, info, sta, skb, hw_queue, ptcb_desc);
+
+ __skb_queue_tail(&ring->queue, skb);
+
+ if (rtlpriv->use_new_trx_flow) {
+ rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true,
+ HW_DESC_OWN, &hw_queue);
+ } else {
+ rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true,
+ HW_DESC_OWN, &temp_one);
+ }
+
+ if ((ring->entries - skb_queue_len(&ring->queue)) < 2 &&
+ hw_queue != BEACON_QUEUE) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
+ "less desc left, stop skb_queue@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%x\n",
+ hw_queue, ring->idx, idx,
+ skb_queue_len(&ring->queue));
+
+ ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
+ }
+
+ spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+
+ rtlpriv->cfg->ops->tx_polling(hw, hw_queue);
+
+ return 0;
+}
+
+static void rtl_pci_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ u16 i = 0;
+ int queue_id;
+ struct rtl8192_tx_ring *ring;
+
+ if (mac->skip_scan)
+ return;
+
+ for (queue_id = RTL_PCI_MAX_TX_QUEUE_COUNT - 1; queue_id >= 0;) {
+ u32 queue_len;
+
+ if (((queues >> queue_id) & 0x1) == 0) {
+ queue_id--;
+ continue;
+ }
+ ring = &pcipriv->dev.tx_ring[queue_id];
+ queue_len = skb_queue_len(&ring->queue);
+ if (queue_len == 0 || queue_id == BEACON_QUEUE ||
+ queue_id == TXCMD_QUEUE) {
+ queue_id--;
+ continue;
+ } else {
+ msleep(20);
+ i++;
+ }
+
+ /* we just wait 1s for all queues */
+ if (rtlpriv->psc.rfpwr_state == ERFOFF ||
+ is_hal_stop(rtlhal) || i >= 200)
+ return;
+ }
+}
+
+static void rtl_pci_deinit(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ _rtl_pci_deinit_trx_ring(hw);
+
+ synchronize_irq(rtlpci->pdev->irq);
+ tasklet_kill(&rtlpriv->works.irq_tasklet);
+ cancel_work_sync(&rtlpriv->works.lps_change_work);
+
+ flush_workqueue(rtlpriv->works.rtl_wq);
+ destroy_workqueue(rtlpriv->works.rtl_wq);
+}
+
+static int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev)
+{
+ int err;
+
+ _rtl_pci_init_struct(hw, pdev);
+
+ err = _rtl_pci_init_trx_ring(hw);
+ if (err) {
+ pr_err("tx ring initialization failed\n");
+ return err;
+ }
+
+ return 0;
+}
+
+static int rtl_pci_start(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
+
+ int err;
+
+ rtl_pci_reset_trx_ring(hw);
+
+ rtlpci->driver_is_goingto_unload = false;
+ if (rtlpriv->cfg->ops->get_btc_status &&
+ rtlpriv->cfg->ops->get_btc_status()) {
+ rtlpriv->btcoexist.btc_info.ap_num = 36;
+ rtlpriv->btcoexist.btc_ops->btc_init_variables(rtlpriv);
+ rtlpriv->btcoexist.btc_ops->btc_init_hal_vars(rtlpriv);
+ } else if (rtlpriv->btcoexist.btc_ops) {
+ rtlpriv->btcoexist.btc_ops->btc_init_variables_wifi_only(
+ rtlpriv);
+ }
+
+ err = rtlpriv->cfg->ops->hw_init(hw);
+ if (err) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ "Failed to config hardware!\n");
+ return err;
+ }
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,
+ &rtlmac->retry_long);
+
+ rtlpriv->cfg->ops->enable_interrupt(hw);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "enable_interrupt OK\n");
+
+ rtl_init_rx_config(hw);
+
+ /*should be after adapter start and interrupt enable. */
+ set_hal_start(rtlhal);
+
+ RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
+
+ rtlpci->up_first_time = false;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%s OK\n", __func__);
+ return 0;
+}
+
+static void rtl_pci_stop(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ unsigned long flags;
+ u8 rf_timeout = 0;
+
+ if (rtlpriv->cfg->ops->get_btc_status())
+ rtlpriv->btcoexist.btc_ops->btc_halt_notify(rtlpriv);
+
+ if (rtlpriv->btcoexist.btc_ops)
+ rtlpriv->btcoexist.btc_ops->btc_deinit_variables(rtlpriv);
+
+ /*
+ *should be before disable interrupt&adapter
+ *and will do it immediately.
+ */
+ set_hal_stop(rtlhal);
+
+ rtlpci->driver_is_goingto_unload = true;
+ rtlpriv->cfg->ops->disable_interrupt(hw);
+ cancel_work_sync(&rtlpriv->works.lps_change_work);
+
+ spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags);
+ while (ppsc->rfchange_inprogress) {
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flags);
+ if (rf_timeout > 100) {
+ spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags);
+ break;
+ }
+ mdelay(1);
+ rf_timeout++;
+ spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags);
+ }
+ ppsc->rfchange_inprogress = true;
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flags);
+
+ rtlpriv->cfg->ops->hw_disable(hw);
+ /* some things are not needed if firmware not available */
+ if (!rtlpriv->max_fw_size)
+ return;
+ rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
+
+ spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags);
+ ppsc->rfchange_inprogress = false;
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flags);
+
+ rtl_pci_enable_aspm(hw);
+}
+
+static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
+ struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct pci_dev *bridge_pdev = pdev->bus->self;
+ u16 venderid;
+ u16 deviceid;
+ u8 revisionid;
+ u16 irqline;
+ u8 tmp;
+
+ pcipriv->ndis_adapter.pcibridge_vendor = PCI_BRIDGE_VENDOR_UNKNOWN;
+ venderid = pdev->vendor;
+ deviceid = pdev->device;
+ pci_read_config_byte(pdev, 0x8, &revisionid);
+ pci_read_config_word(pdev, 0x3C, &irqline);
+
+ /* PCI ID 0x10ec:0x8192 occurs for both RTL8192E, which uses
+ * r8192e_pci, and RTL8192SE, which uses this driver. If the
+ * revision ID is RTL_PCI_REVISION_ID_8192PCIE (0x01), then
+ * the correct driver is r8192e_pci, thus this routine should
+ * return false.
+ */
+ if (deviceid == RTL_PCI_8192SE_DID &&
+ revisionid == RTL_PCI_REVISION_ID_8192PCIE)
+ return false;
+
+ if (deviceid == RTL_PCI_8192_DID ||
+ deviceid == RTL_PCI_0044_DID ||
+ deviceid == RTL_PCI_0047_DID ||
+ deviceid == RTL_PCI_8192SE_DID ||
+ deviceid == RTL_PCI_8174_DID ||
+ deviceid == RTL_PCI_8173_DID ||
+ deviceid == RTL_PCI_8172_DID ||
+ deviceid == RTL_PCI_8171_DID) {
+ switch (revisionid) {
+ case RTL_PCI_REVISION_ID_8192PCIE:
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ "8192 PCI-E is found - vid/did=%x/%x\n",
+ venderid, deviceid);
+ rtlhal->hw_type = HARDWARE_TYPE_RTL8192E;
+ return false;
+ case RTL_PCI_REVISION_ID_8192SE:
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ "8192SE is found - vid/did=%x/%x\n",
+ venderid, deviceid);
+ rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE;
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ "Err: Unknown device - vid/did=%x/%x\n",
+ venderid, deviceid);
+ rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE;
+ break;
+ }
+ } else if (deviceid == RTL_PCI_8723AE_DID) {
+ rtlhal->hw_type = HARDWARE_TYPE_RTL8723AE;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ "8723AE PCI-E is found - vid/did=%x/%x\n",
+ venderid, deviceid);
+ } else if (deviceid == RTL_PCI_8192CET_DID ||
+ deviceid == RTL_PCI_8192CE_DID ||
+ deviceid == RTL_PCI_8191CE_DID ||
+ deviceid == RTL_PCI_8188CE_DID) {
+ rtlhal->hw_type = HARDWARE_TYPE_RTL8192CE;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ "8192C PCI-E is found - vid/did=%x/%x\n",
+ venderid, deviceid);
+ } else if (deviceid == RTL_PCI_8192DE_DID ||
+ deviceid == RTL_PCI_8192DE_DID2) {
+ rtlhal->hw_type = HARDWARE_TYPE_RTL8192DE;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ "8192D PCI-E is found - vid/did=%x/%x\n",
+ venderid, deviceid);
+ } else if (deviceid == RTL_PCI_8188EE_DID) {
+ rtlhal->hw_type = HARDWARE_TYPE_RTL8188EE;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "Find adapter, Hardware type is 8188EE\n");
+ } else if (deviceid == RTL_PCI_8723BE_DID) {
+ rtlhal->hw_type = HARDWARE_TYPE_RTL8723BE;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "Find adapter, Hardware type is 8723BE\n");
+ } else if (deviceid == RTL_PCI_8192EE_DID) {
+ rtlhal->hw_type = HARDWARE_TYPE_RTL8192EE;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "Find adapter, Hardware type is 8192EE\n");
+ } else if (deviceid == RTL_PCI_8821AE_DID) {
+ rtlhal->hw_type = HARDWARE_TYPE_RTL8821AE;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "Find adapter, Hardware type is 8821AE\n");
+ } else if (deviceid == RTL_PCI_8812AE_DID) {
+ rtlhal->hw_type = HARDWARE_TYPE_RTL8812AE;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "Find adapter, Hardware type is 8812AE\n");
+ } else if (deviceid == RTL_PCI_8822BE_DID) {
+ rtlhal->hw_type = HARDWARE_TYPE_RTL8822BE;
+ rtlhal->bandset = BAND_ON_BOTH;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "Find adapter, Hardware type is 8822BE\n");
+ } else {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ "Err: Unknown device - vid/did=%x/%x\n",
+ venderid, deviceid);
+
+ rtlhal->hw_type = RTL_DEFAULT_HARDWARE_TYPE;
+ }
+
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE) {
+ if (revisionid == 0 || revisionid == 1) {
+ if (revisionid == 0) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "Find 92DE MAC0\n");
+ rtlhal->interfaceindex = 0;
+ } else if (revisionid == 1) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "Find 92DE MAC1\n");
+ rtlhal->interfaceindex = 1;
+ }
+ } else {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "Unknown device - VendorID/DeviceID=%x/%x, Revision=%x\n",
+ venderid, deviceid, revisionid);
+ rtlhal->interfaceindex = 0;
+ }
+ }
+
+ switch (rtlhal->hw_type) {
+ case HARDWARE_TYPE_RTL8192EE:
+ case HARDWARE_TYPE_RTL8822BE:
+ /* use new trx flow */
+ rtlpriv->use_new_trx_flow = true;
+ break;
+
+ default:
+ rtlpriv->use_new_trx_flow = false;
+ break;
+ }
+
+ /*find bus info */
+ pcipriv->ndis_adapter.busnumber = pdev->bus->number;
+ pcipriv->ndis_adapter.devnumber = PCI_SLOT(pdev->devfn);
+ pcipriv->ndis_adapter.funcnumber = PCI_FUNC(pdev->devfn);
+
+ /*find bridge info */
+ pcipriv->ndis_adapter.pcibridge_vendor = PCI_BRIDGE_VENDOR_UNKNOWN;
+ /* some ARM have no bridge_pdev and will crash here
+ * so we should check if bridge_pdev is NULL
+ */
+ if (bridge_pdev) {
+ /*find bridge info if available */
+ pcipriv->ndis_adapter.pcibridge_vendorid = bridge_pdev->vendor;
+ for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) {
+ if (bridge_pdev->vendor == pcibridge_vendors[tmp]) {
+ pcipriv->ndis_adapter.pcibridge_vendor = tmp;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ "Pci Bridge Vendor is found index: %d\n",
+ tmp);
+ break;
+ }
+ }
+ }
+
+ if (pcipriv->ndis_adapter.pcibridge_vendor !=
+ PCI_BRIDGE_VENDOR_UNKNOWN) {
+ pcipriv->ndis_adapter.pcibridge_busnum =
+ bridge_pdev->bus->number;
+ pcipriv->ndis_adapter.pcibridge_devnum =
+ PCI_SLOT(bridge_pdev->devfn);
+ pcipriv->ndis_adapter.pcibridge_funcnum =
+ PCI_FUNC(bridge_pdev->devfn);
+ pcipriv->ndis_adapter.pcibridge_pciehdr_offset =
+ pci_pcie_cap(bridge_pdev);
+ pcipriv->ndis_adapter.num4bytes =
+ (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10) / 4;
+
+ rtl_pci_get_linkcontrol_field(hw);
+
+ if (pcipriv->ndis_adapter.pcibridge_vendor ==
+ PCI_BRIDGE_VENDOR_AMD) {
+ pcipriv->ndis_adapter.amd_l1_patch =
+ rtl_pci_get_amd_l1_patch(hw);
+ }
+ }
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ "pcidev busnumber:devnumber:funcnumber:vendor:link_ctl %d:%d:%d:%x:%x\n",
+ pcipriv->ndis_adapter.busnumber,
+ pcipriv->ndis_adapter.devnumber,
+ pcipriv->ndis_adapter.funcnumber,
+ pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg);
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ "pci_bridge busnumber:devnumber:funcnumber:vendor:pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n",
+ pcipriv->ndis_adapter.pcibridge_busnum,
+ pcipriv->ndis_adapter.pcibridge_devnum,
+ pcipriv->ndis_adapter.pcibridge_funcnum,
+ pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor],
+ pcipriv->ndis_adapter.pcibridge_pciehdr_offset,
+ pcipriv->ndis_adapter.pcibridge_linkctrlreg,
+ pcipriv->ndis_adapter.amd_l1_patch);
+
+ rtl_pci_parse_configuration(pdev, hw);
+ list_add_tail(&rtlpriv->list, &rtlpriv->glb_var->glb_priv_list);
+
+ return true;
+}
+
+static int rtl_pci_intr_mode_msi(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
+ int ret;
+
+ ret = pci_enable_msi(rtlpci->pdev);
+ if (ret < 0)
+ return ret;
+
+ ret = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt,
+ IRQF_SHARED, KBUILD_MODNAME, hw);
+ if (ret < 0) {
+ pci_disable_msi(rtlpci->pdev);
+ return ret;
+ }
+
+ rtlpci->using_msi = true;
+
+ RT_TRACE(rtlpriv, COMP_INIT | COMP_INTR, DBG_DMESG,
+ "MSI Interrupt Mode!\n");
+ return 0;
+}
+
+static int rtl_pci_intr_mode_legacy(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
+ int ret;
+
+ ret = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt,
+ IRQF_SHARED, KBUILD_MODNAME, hw);
+ if (ret < 0)
+ return ret;
+
+ rtlpci->using_msi = false;
+ RT_TRACE(rtlpriv, COMP_INIT | COMP_INTR, DBG_DMESG,
+ "Pin-based Interrupt Mode!\n");
+ return 0;
+}
+
+static int rtl_pci_intr_mode_decide(struct ieee80211_hw *hw)
+{
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
+ int ret;
+
+ if (rtlpci->msi_support) {
+ ret = rtl_pci_intr_mode_msi(hw);
+ if (ret < 0)
+ ret = rtl_pci_intr_mode_legacy(hw);
+ } else {
+ ret = rtl_pci_intr_mode_legacy(hw);
+ }
+ return ret;
+}
+
+static void platform_enable_dma64(struct pci_dev *pdev, bool dma64)
+{
+ u8 value;
+
+ pci_read_config_byte(pdev, 0x719, &value);
+
+ /* 0x719 Bit5 is DMA64 bit fetch. */
+ if (dma64)
+ value |= BIT(5);
+ else
+ value &= ~BIT(5);
+
+ pci_write_config_byte(pdev, 0x719, value);
+}
+
+int rtl_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ struct ieee80211_hw *hw = NULL;
+
+ struct rtl_priv *rtlpriv = NULL;
+ struct rtl_pci_priv *pcipriv = NULL;
+ struct rtl_pci *rtlpci;
+ unsigned long pmem_start, pmem_len, pmem_flags;
+ int err;
+
+ err = rtl_core_module_init();
+ if (err)
+ return err;
+ err = pci_enable_device(pdev);
+ if (err) {
+ WARN_ONCE(true, "%s : Cannot enable new PCI device\n",
+ pci_name(pdev));
+ return err;
+ }
+
+ if (((struct rtl_hal_cfg *)(id->driver_data))->mod_params->dma64 &&
+ !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+ if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
+ WARN_ONCE(true,
+ "Unable to obtain 64bit DMA for consistent allocations\n");
+ err = -ENOMEM;
+ goto fail1;
+ }
+
+ platform_enable_dma64(pdev, true);
+ } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
+ if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
+ WARN_ONCE(true,
+ "rtlwifi: Unable to obtain 32bit DMA for consistent allocations\n");
+ err = -ENOMEM;
+ goto fail1;
+ }
+
+ platform_enable_dma64(pdev, false);
+ }
+
+ pci_set_master(pdev);
+
+ hw = ieee80211_alloc_hw(sizeof(struct rtl_pci_priv) +
+ sizeof(struct rtl_priv), &rtl_ops);
+ if (!hw) {
+ WARN_ONCE(true,
+ "%s : ieee80211 alloc failed\n", pci_name(pdev));
+ err = -ENOMEM;
+ goto fail1;
+ }
+
+ SET_IEEE80211_DEV(hw, &pdev->dev);
+ pci_set_drvdata(pdev, hw);
+
+ rtlpriv = hw->priv;
+ rtlpriv->hw = hw;
+ pcipriv = (void *)rtlpriv->priv;
+ pcipriv->dev.pdev = pdev;
+ init_completion(&rtlpriv->firmware_loading_complete);
+ /*proximity init here*/
+ rtlpriv->proximity.proxim_on = false;
+
+ pcipriv = (void *)rtlpriv->priv;
+ pcipriv->dev.pdev = pdev;
+
+ /* init cfg & intf_ops */
+ rtlpriv->rtlhal.interface = INTF_PCI;
+ rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data);
+ rtlpriv->intf_ops = &rtl_pci_ops;
+ rtlpriv->glb_var = &rtl_global_var;
+
+ /* MEM map */
+ err = pci_request_regions(pdev, KBUILD_MODNAME);
+ if (err) {
+ WARN_ONCE(true, "rtlwifi: Can't obtain PCI resources\n");
+ goto fail1;
+ }
+
+ pmem_start = pci_resource_start(pdev, rtlpriv->cfg->bar_id);
+ pmem_len = pci_resource_len(pdev, rtlpriv->cfg->bar_id);
+ pmem_flags = pci_resource_flags(pdev, rtlpriv->cfg->bar_id);
+
+ /*shared mem start */
+ rtlpriv->io.pci_mem_start =
+ (unsigned long)pci_iomap(pdev,
+ rtlpriv->cfg->bar_id, pmem_len);
+ if (rtlpriv->io.pci_mem_start == 0) {
+ WARN_ONCE(true, "rtlwifi: Can't map PCI mem\n");
+ err = -ENOMEM;
+ goto fail2;
+ }
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ "mem mapped space: start: 0x%08lx len:%08lx flags:%08lx, after map:0x%08lx\n",
+ pmem_start, pmem_len, pmem_flags,
+ rtlpriv->io.pci_mem_start);
+
+ /* Disable Clk Request */
+ pci_write_config_byte(pdev, 0x81, 0);
+ /* leave D3 mode */
+ pci_write_config_byte(pdev, 0x44, 0);
+ pci_write_config_byte(pdev, 0x04, 0x06);
+ pci_write_config_byte(pdev, 0x04, 0x07);
+
+ /* find adapter */
+ if (!_rtl_pci_find_adapter(pdev, hw)) {
+ err = -ENODEV;
+ goto fail2;
+ }
+
+ /* Init IO handler */
+ _rtl_pci_io_handler_init(&pdev->dev, hw);
+
+ /*like read eeprom and so on */
+ rtlpriv->cfg->ops->read_eeprom_info(hw);
+
+ if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
+ pr_err("Can't init_sw_vars\n");
+ err = -ENODEV;
+ goto fail3;
+ }
+ rtlpriv->cfg->ops->init_sw_leds(hw);
+
+ /*aspm */
+ rtl_pci_init_aspm(hw);
+
+ /* Init mac80211 sw */
+ err = rtl_init_core(hw);
+ if (err) {
+ pr_err("Can't allocate sw for mac80211\n");
+ goto fail3;
+ }
+
+ /* Init PCI sw */
+ err = rtl_pci_init(hw, pdev);
+ if (err) {
+ pr_err("Failed to init PCI\n");
+ goto fail3;
+ }
+
+ err = ieee80211_register_hw(hw);
+ if (err) {
+ pr_err("Can't register mac80211 hw.\n");
+ err = -ENODEV;
+ goto fail3;
+ }
+ rtlpriv->mac80211.mac80211_registered = 1;
+
+ /* add for debug */
+ rtl_debug_add_one(hw);
+
+ /*init rfkill */
+ rtl_init_rfkill(hw); /* Init PCI sw */
+
+ rtlpci = rtl_pcidev(pcipriv);
+ err = rtl_pci_intr_mode_decide(hw);
+ if (err) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ "%s: failed to register IRQ handler\n",
+ wiphy_name(hw->wiphy));
+ goto fail3;
+ }
+ rtlpci->irq_alloc = 1;
+
+ set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
+ return 0;
+
+fail3:
+ pci_set_drvdata(pdev, NULL);
+ rtl_deinit_core(hw);
+
+fail2:
+ if (rtlpriv->io.pci_mem_start != 0)
+ pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start);
+
+ pci_release_regions(pdev);
+ complete(&rtlpriv->firmware_loading_complete);
+
+fail1:
+ if (hw)
+ ieee80211_free_hw(hw);
+ pci_disable_device(pdev);
+
+ return err;
+}
+
+void rtl_pci_disconnect(struct pci_dev *pdev)
+{
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
+ struct rtl_mac *rtlmac = rtl_mac(rtlpriv);
+
+ /* just in case driver is removed before firmware callback */
+ wait_for_completion(&rtlpriv->firmware_loading_complete);
+ clear_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
+
+ /* remove form debug */
+ rtl_debug_remove_one(hw);
+
+ /*ieee80211_unregister_hw will call ops_stop */
+ if (rtlmac->mac80211_registered == 1) {
+ ieee80211_unregister_hw(hw);
+ rtlmac->mac80211_registered = 0;
+ } else {
+ rtl_deinit_deferred_work(hw);
+ rtlpriv->intf_ops->adapter_stop(hw);
+ }
+ rtlpriv->cfg->ops->disable_interrupt(hw);
+
+ /*deinit rfkill */
+ rtl_deinit_rfkill(hw);
+
+ rtl_pci_deinit(hw);
+ rtl_deinit_core(hw);
+ rtlpriv->cfg->ops->deinit_sw_vars(hw);
+
+ if (rtlpci->irq_alloc) {
+ free_irq(rtlpci->pdev->irq, hw);
+ rtlpci->irq_alloc = 0;
+ }
+
+ if (rtlpci->using_msi)
+ pci_disable_msi(rtlpci->pdev);
+
+ list_del(&rtlpriv->list);
+ if (rtlpriv->io.pci_mem_start != 0) {
+ pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start);
+ pci_release_regions(pdev);
+ }
+
+ pci_disable_device(pdev);
+
+ rtl_pci_disable_aspm(hw);
+
+ pci_set_drvdata(pdev, NULL);
+
+ ieee80211_free_hw(hw);
+ rtl_core_module_exit();
+}
+
+#ifdef CONFIG_PM_SLEEP
+/***************************************
+ * kernel pci power state define:
+ * PCI_D0 ((pci_power_t __force) 0)
+ * PCI_D1 ((pci_power_t __force) 1)
+ * PCI_D2 ((pci_power_t __force) 2)
+ * PCI_D3hot ((pci_power_t __force) 3)
+ * PCI_D3cold ((pci_power_t __force) 4)
+ * PCI_UNKNOWN ((pci_power_t __force) 5)
+
+ * This function is called when system
+ * goes into suspend state mac80211 will
+ * call rtl_mac_stop() from the mac80211
+ * suspend function first, So there is
+ * no need to call hw_disable here.
+ ****************************************/
+int rtl_pci_suspend(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtlpriv->cfg->ops->hw_suspend(hw);
+ rtl_deinit_rfkill(hw);
+
+ return 0;
+}
+
+int rtl_pci_resume(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtlpriv->cfg->ops->hw_resume(hw);
+ rtl_init_rfkill(hw);
+ return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+const struct rtl_intf_ops rtl_pci_ops = {
+ .read_efuse_byte = read_efuse_byte,
+ .adapter_start = rtl_pci_start,
+ .adapter_stop = rtl_pci_stop,
+ .check_buddy_priv = rtl_pci_check_buddy_priv,
+ .adapter_tx = rtl_pci_tx,
+ .flush = rtl_pci_flush,
+ .reset_trx_ring = rtl_pci_reset_trx_ring,
+ .waitq_insert = rtl_pci_tx_chk_waitq_insert,
+
+ .disable_aspm = rtl_pci_disable_aspm,
+ .enable_aspm = rtl_pci_enable_aspm,
+};
diff --git a/drivers/staging/rtlwifi/pci.h b/drivers/staging/rtlwifi/pci.h
new file mode 100644
index 0000000..3fb56c8
--- /dev/null
+++ b/drivers/staging/rtlwifi/pci.h
@@ -0,0 +1,329 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2012 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL_PCI_H__
+#define __RTL_PCI_H__
+
+#include <linux/pci.h>
+/* 1: MSDU packet queue,
+ * 2: Rx Command Queue
+ */
+#define RTL_PCI_RX_MPDU_QUEUE 0
+#define RTL_PCI_RX_CMD_QUEUE 1
+#define RTL_PCI_MAX_RX_QUEUE 2
+
+#define RTL_PCI_MAX_RX_COUNT 512/*64*/
+#define RTL_PCI_MAX_TX_QUEUE_COUNT 9
+
+#define RT_TXDESC_NUM 128
+#define TX_DESC_NUM_92E 512
+#define TX_DESC_NUM_8822B 512
+#define RT_TXDESC_NUM_BE_QUEUE 256
+
+#define BK_QUEUE 0
+#define BE_QUEUE 1
+#define VI_QUEUE 2
+#define VO_QUEUE 3
+#define BEACON_QUEUE 4
+#define TXCMD_QUEUE 5
+#define MGNT_QUEUE 6
+#define HIGH_QUEUE 7
+#define HCCA_QUEUE 8
+#define H2C_QUEUE TXCMD_QUEUE /* In 8822B */
+
+#define RTL_PCI_DEVICE(vend, dev, cfg) \
+ .vendor = (vend), \
+ .device = (dev), \
+ .subvendor = PCI_ANY_ID, \
+ .subdevice = PCI_ANY_ID,\
+ .driver_data = (kernel_ulong_t)&(cfg)
+
+#define INTEL_VENDOR_ID 0x8086
+#define SIS_VENDOR_ID 0x1039
+#define ATI_VENDOR_ID 0x1002
+#define ATI_DEVICE_ID 0x7914
+#define AMD_VENDOR_ID 0x1022
+
+#define PCI_MAX_BRIDGE_NUMBER 255
+#define PCI_MAX_DEVICES 32
+#define PCI_MAX_FUNCTION 8
+
+#define PCI_CONF_ADDRESS 0x0CF8 /*PCI Configuration Space Address */
+#define PCI_CONF_DATA 0x0CFC /*PCI Configuration Space Data */
+
+#define PCI_CLASS_BRIDGE_DEV 0x06
+#define PCI_SUBCLASS_BR_PCI_TO_PCI 0x04
+#define PCI_CAPABILITY_ID_PCI_EXPRESS 0x10
+#define PCI_CAP_ID_EXP 0x10
+
+#define U1DONTCARE 0xFF
+#define U2DONTCARE 0xFFFF
+#define U4DONTCARE 0xFFFFFFFF
+
+#define RTL_PCI_8192_DID 0x8192 /*8192 PCI-E */
+#define RTL_PCI_8192SE_DID 0x8192 /*8192 SE */
+#define RTL_PCI_8174_DID 0x8174 /*8192 SE */
+#define RTL_PCI_8173_DID 0x8173 /*8191 SE Crab */
+#define RTL_PCI_8172_DID 0x8172 /*8191 SE RE */
+#define RTL_PCI_8171_DID 0x8171 /*8191 SE Unicron */
+#define RTL_PCI_8723AE_DID 0x8723 /*8723AE */
+#define RTL_PCI_0045_DID 0x0045 /*8190 PCI for Ceraga */
+#define RTL_PCI_0046_DID 0x0046 /*8190 Cardbus for Ceraga */
+#define RTL_PCI_0044_DID 0x0044 /*8192e PCIE for Ceraga */
+#define RTL_PCI_0047_DID 0x0047 /*8192e Express Card for Ceraga */
+#define RTL_PCI_700F_DID 0x700F
+#define RTL_PCI_701F_DID 0x701F
+#define RTL_PCI_DLINK_DID 0x3304
+#define RTL_PCI_8723AE_DID 0x8723 /*8723e */
+#define RTL_PCI_8192CET_DID 0x8191 /*8192ce */
+#define RTL_PCI_8192CE_DID 0x8178 /*8192ce */
+#define RTL_PCI_8191CE_DID 0x8177 /*8192ce */
+#define RTL_PCI_8188CE_DID 0x8176 /*8192ce */
+#define RTL_PCI_8192CU_DID 0x8191 /*8192ce */
+#define RTL_PCI_8192DE_DID 0x8193 /*8192de */
+#define RTL_PCI_8192DE_DID2 0x002B /*92DE*/
+#define RTL_PCI_8188EE_DID 0x8179 /*8188ee*/
+#define RTL_PCI_8723BE_DID 0xB723 /*8723be*/
+#define RTL_PCI_8192EE_DID 0x818B /*8192ee*/
+#define RTL_PCI_8821AE_DID 0x8821 /*8821ae*/
+#define RTL_PCI_8812AE_DID 0x8812 /*8812ae*/
+#define RTL_PCI_8822BE_DID 0xB822 /*8822be*/
+
+/*8192 support 16 pages of IO registers*/
+#define RTL_MEM_MAPPED_IO_RANGE_8190PCI 0x1000
+#define RTL_MEM_MAPPED_IO_RANGE_8192PCIE 0x4000
+#define RTL_MEM_MAPPED_IO_RANGE_8192SE 0x4000
+#define RTL_MEM_MAPPED_IO_RANGE_8192CE 0x4000
+#define RTL_MEM_MAPPED_IO_RANGE_8192DE 0x4000
+
+#define RTL_PCI_REVISION_ID_8190PCI 0x00
+#define RTL_PCI_REVISION_ID_8192PCIE 0x01
+#define RTL_PCI_REVISION_ID_8192SE 0x10
+#define RTL_PCI_REVISION_ID_8192CE 0x1
+#define RTL_PCI_REVISION_ID_8192DE 0x0
+
+#define RTL_DEFAULT_HARDWARE_TYPE HARDWARE_TYPE_RTL8192CE
+
+enum pci_bridge_vendor {
+ PCI_BRIDGE_VENDOR_INTEL = 0x0, /*0b'0000,0001 */
+ PCI_BRIDGE_VENDOR_ATI, /*0b'0000,0010*/
+ PCI_BRIDGE_VENDOR_AMD, /*0b'0000,0100*/
+ PCI_BRIDGE_VENDOR_SIS, /*0b'0000,1000*/
+ PCI_BRIDGE_VENDOR_UNKNOWN, /*0b'0100,0000*/
+ PCI_BRIDGE_VENDOR_MAX,
+};
+
+struct rtl_pci_capabilities_header {
+ u8 capability_id;
+ u8 next;
+};
+
+/* In new TRX flow, Buffer_desc is new concept
+ * But TX wifi info == TX descriptor in old flow
+ * RX wifi info == RX descriptor in old flow
+ */
+struct rtl_tx_buffer_desc {
+ u32 dword[4 * (1 << (BUFDESC_SEG_NUM + 1))];
+} __packed;
+
+struct rtl_tx_desc {
+ u32 dword[16];
+} __packed;
+
+struct rtl_rx_buffer_desc { /*rx buffer desc*/
+ u32 dword[4];
+} __packed;
+
+struct rtl_rx_desc { /*old: rx desc new: rx wifi info*/
+ u32 dword[8];
+} __packed;
+
+struct rtl_tx_cmd_desc {
+ u32 dword[16];
+} __packed;
+
+struct rtl8192_tx_ring {
+ struct rtl_tx_desc *desc;
+ dma_addr_t dma;
+ unsigned int idx;
+ unsigned int entries;
+ struct sk_buff_head queue;
+ /*add for new trx flow*/
+ struct rtl_tx_buffer_desc *buffer_desc; /*tx buffer descriptor*/
+ dma_addr_t buffer_desc_dma; /*tx bufferd desc dma memory*/
+ u16 cur_tx_wp; /* current_tx_write_point */
+ u16 cur_tx_rp; /* current_tx_read_point */
+};
+
+struct rtl8192_rx_ring {
+ struct rtl_rx_desc *desc;
+ dma_addr_t dma;
+ unsigned int idx;
+ struct sk_buff *rx_buf[RTL_PCI_MAX_RX_COUNT];
+ /*add for new trx flow*/
+ struct rtl_rx_buffer_desc *buffer_desc; /*rx buffer descriptor*/
+ u16 next_rx_rp; /* next_rx_read_point */
+};
+
+struct rtl_pci {
+ struct pci_dev *pdev;
+ bool irq_enabled;
+
+ bool driver_is_goingto_unload;
+ bool up_first_time;
+ bool first_init;
+ bool being_init_adapter;
+ bool init_ready;
+
+ /*Tx */
+ struct rtl8192_tx_ring tx_ring[RTL_PCI_MAX_TX_QUEUE_COUNT];
+ int txringcount[RTL_PCI_MAX_TX_QUEUE_COUNT];
+ u32 transmit_config;
+
+ /*Rx */
+ struct rtl8192_rx_ring rx_ring[RTL_PCI_MAX_RX_QUEUE];
+ int rxringcount;
+ u16 rxbuffersize;
+ u32 receive_config;
+
+ /*irq */
+ u8 irq_alloc;
+ u32 irq_mask[4]; /* 0-1: normal, 2: unused, 3: h2c */
+ u32 sys_irq_mask;
+
+ /*Bcn control register setting */
+ u32 reg_bcn_ctrl_val;
+
+ /*ASPM*/ u8 const_pci_aspm;
+ u8 const_amdpci_aspm;
+ u8 const_hwsw_rfoff_d3;
+ u8 const_support_pciaspm;
+ /*pci-e bridge */
+ u8 const_hostpci_aspm_setting;
+ /*pci-e device */
+ u8 const_devicepci_aspm_setting;
+ /* If it supports ASPM, Offset[560h] = 0x40,
+ * otherwise Offset[560h] = 0x00.
+ */
+ bool support_aspm;
+ bool support_backdoor;
+
+ /*QOS & EDCA */
+ enum acm_method acm_method;
+
+ u16 shortretry_limit;
+ u16 longretry_limit;
+
+ /* MSI support */
+ bool msi_support;
+ bool using_msi;
+ /* interrupt clear before set */
+ bool int_clear;
+};
+
+struct mp_adapter {
+ u8 linkctrl_reg;
+
+ u8 busnumber;
+ u8 devnumber;
+ u8 funcnumber;
+
+ u8 pcibridge_busnum;
+ u8 pcibridge_devnum;
+ u8 pcibridge_funcnum;
+
+ u8 pcibridge_vendor;
+ u16 pcibridge_vendorid;
+ u16 pcibridge_deviceid;
+
+ u8 num4bytes;
+
+ u8 pcibridge_pciehdr_offset;
+ u8 pcibridge_linkctrlreg;
+
+ bool amd_l1_patch;
+};
+
+struct rtl_pci_priv {
+ struct bt_coexist_info bt_coexist;
+ struct rtl_led_ctl ledctl;
+ struct rtl_pci dev;
+ struct mp_adapter ndis_adapter;
+};
+
+#define rtl_pcipriv(hw) (((struct rtl_pci_priv *)(rtl_priv(hw))->priv))
+#define rtl_pcidev(pcipriv) (&((pcipriv)->dev))
+
+int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw);
+
+extern const struct rtl_intf_ops rtl_pci_ops;
+
+int rtl_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id);
+void rtl_pci_disconnect(struct pci_dev *pdev);
+#ifdef CONFIG_PM_SLEEP
+int rtl_pci_suspend(struct device *dev);
+int rtl_pci_resume(struct device *dev);
+#endif /* CONFIG_PM_SLEEP */
+static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr)
+{
+ return readb((u8 __iomem *)rtlpriv->io.pci_mem_start + addr);
+}
+
+static inline u16 pci_read16_sync(struct rtl_priv *rtlpriv, u32 addr)
+{
+ return readw((u8 __iomem *)rtlpriv->io.pci_mem_start + addr);
+}
+
+static inline u32 pci_read32_sync(struct rtl_priv *rtlpriv, u32 addr)
+{
+ return readl((u8 __iomem *)rtlpriv->io.pci_mem_start + addr);
+}
+
+static inline void pci_write8_async(struct rtl_priv *rtlpriv, u32 addr, u8 val)
+{
+ writeb(val, (u8 __iomem *)rtlpriv->io.pci_mem_start + addr);
+}
+
+static inline void pci_write16_async(struct rtl_priv *rtlpriv,
+ u32 addr, u16 val)
+{
+ writew(val, (u8 __iomem *)rtlpriv->io.pci_mem_start + addr);
+}
+
+static inline void pci_write32_async(struct rtl_priv *rtlpriv,
+ u32 addr, u32 val)
+{
+ writel(val, (u8 __iomem *)rtlpriv->io.pci_mem_start + addr);
+}
+
+static inline u16 calc_fifo_space(u16 rp, u16 wp, u16 size)
+{
+ if (rp <= wp)
+ return size - 1 + rp - wp;
+ return rp - wp - 1;
+}
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/halphyrf_ce.c b/drivers/staging/rtlwifi/phydm/halphyrf_ce.c
new file mode 100644
index 0000000..684e383
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/halphyrf_ce.c
@@ -0,0 +1,965 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+#define CALCULATE_SWINGTALBE_OFFSET(_offset, _direction, _size, \
+ _delta_thermal) \
+ do { \
+ for (_offset = 0; _offset < _size; _offset++) { \
+ if (_delta_thermal < \
+ thermal_threshold[_direction][_offset]) { \
+ if (_offset != 0) \
+ _offset--; \
+ break; \
+ } \
+ } \
+ if (_offset >= _size) \
+ _offset = _size - 1; \
+ } while (0)
+
+static inline void phydm_set_calibrate_info_up(
+ struct phy_dm_struct *dm, struct txpwrtrack_cfg *c, u8 delta,
+ struct dm_rf_calibration_struct *cali_info,
+ u8 *delta_swing_table_idx_tup_a, u8 *delta_swing_table_idx_tup_b,
+ u8 *delta_swing_table_idx_tup_c, u8 *delta_swing_table_idx_tup_d)
+{
+ u8 p = 0;
+
+ for (p = ODM_RF_PATH_A; p < c->rf_path_count; p++) {
+ cali_info->delta_power_index_last[p] =
+ cali_info->delta_power_index
+ [p]; /*recording poer index offset*/
+ switch (p) {
+ case ODM_RF_PATH_B:
+ ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
+ "delta_swing_table_idx_tup_b[%d] = %d\n",
+ delta, delta_swing_table_idx_tup_b[delta]);
+
+ cali_info->delta_power_index[p] =
+ delta_swing_table_idx_tup_b[delta];
+ /*Record delta swing for mix mode pwr tracking*/
+ cali_info->absolute_ofdm_swing_idx[p] =
+ delta_swing_table_idx_tup_b[delta];
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "******Temp is higher and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_B] = %d\n",
+ cali_info->absolute_ofdm_swing_idx[p]);
+ break;
+
+ case ODM_RF_PATH_C:
+ ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
+ "delta_swing_table_idx_tup_c[%d] = %d\n",
+ delta, delta_swing_table_idx_tup_c[delta]);
+
+ cali_info->delta_power_index[p] =
+ delta_swing_table_idx_tup_c[delta];
+ /*Record delta swing for mix mode pwr tracking*/
+ cali_info->absolute_ofdm_swing_idx[p] =
+ delta_swing_table_idx_tup_c[delta];
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "******Temp is higher and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_C] = %d\n",
+ cali_info->absolute_ofdm_swing_idx[p]);
+ break;
+
+ case ODM_RF_PATH_D:
+ ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
+ "delta_swing_table_idx_tup_d[%d] = %d\n",
+ delta, delta_swing_table_idx_tup_d[delta]);
+
+ cali_info->delta_power_index[p] =
+ delta_swing_table_idx_tup_d[delta];
+ /*Record delta swing for mix mode pwr tracking*/
+ cali_info->absolute_ofdm_swing_idx[p] =
+ delta_swing_table_idx_tup_d[delta];
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "******Temp is higher and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_D] = %d\n",
+ cali_info->absolute_ofdm_swing_idx[p]);
+ break;
+
+ default:
+ ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
+ "delta_swing_table_idx_tup_a[%d] = %d\n",
+ delta, delta_swing_table_idx_tup_a[delta]);
+
+ cali_info->delta_power_index[p] =
+ delta_swing_table_idx_tup_a[delta];
+ /*Record delta swing for mix mode pwr tracking*/
+ cali_info->absolute_ofdm_swing_idx[p] =
+ delta_swing_table_idx_tup_a[delta];
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "******Temp is higher and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_A] = %d\n",
+ cali_info->absolute_ofdm_swing_idx[p]);
+ break;
+ }
+ }
+}
+
+static inline void phydm_set_calibrate_info_down(
+ struct phy_dm_struct *dm, struct txpwrtrack_cfg *c, u8 delta,
+ struct dm_rf_calibration_struct *cali_info,
+ u8 *delta_swing_table_idx_tdown_a, u8 *delta_swing_table_idx_tdown_b,
+ u8 *delta_swing_table_idx_tdown_c, u8 *delta_swing_table_idx_tdown_d)
+{
+ u8 p = 0;
+
+ for (p = ODM_RF_PATH_A; p < c->rf_path_count; p++) {
+ cali_info->delta_power_index_last[p] =
+ cali_info->delta_power_index
+ [p]; /*recording poer index offset*/
+
+ switch (p) {
+ case ODM_RF_PATH_B:
+ ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
+ "delta_swing_table_idx_tdown_b[%d] = %d\n",
+ delta,
+ delta_swing_table_idx_tdown_b[delta]);
+ cali_info->delta_power_index[p] =
+ -1 * delta_swing_table_idx_tdown_b[delta];
+ /*Record delta swing for mix mode pwr tracking*/
+ cali_info->absolute_ofdm_swing_idx[p] =
+ -1 * delta_swing_table_idx_tdown_b[delta];
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "******Temp is lower and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_B] = %d\n",
+ cali_info->absolute_ofdm_swing_idx[p]);
+ break;
+
+ case ODM_RF_PATH_C:
+ ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
+ "delta_swing_table_idx_tdown_c[%d] = %d\n",
+ delta,
+ delta_swing_table_idx_tdown_c[delta]);
+ cali_info->delta_power_index[p] =
+ -1 * delta_swing_table_idx_tdown_c[delta];
+ /*Record delta swing for mix mode pwr tracking*/
+ cali_info->absolute_ofdm_swing_idx[p] =
+ -1 * delta_swing_table_idx_tdown_c[delta];
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "******Temp is lower and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_C] = %d\n",
+ cali_info->absolute_ofdm_swing_idx[p]);
+ break;
+
+ case ODM_RF_PATH_D:
+ ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
+ "delta_swing_table_idx_tdown_d[%d] = %d\n",
+ delta,
+ delta_swing_table_idx_tdown_d[delta]);
+ cali_info->delta_power_index[p] =
+ -1 * delta_swing_table_idx_tdown_d[delta];
+ /*Record delta swing for mix mode pwr tracking*/
+ cali_info->absolute_ofdm_swing_idx[p] =
+ -1 * delta_swing_table_idx_tdown_d[delta];
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "******Temp is lower and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_D] = %d\n",
+ cali_info->absolute_ofdm_swing_idx[p]);
+ break;
+
+ default:
+ ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
+ "delta_swing_table_idx_tdown_a[%d] = %d\n",
+ delta,
+ delta_swing_table_idx_tdown_a[delta]);
+ cali_info->delta_power_index[p] =
+ -1 * delta_swing_table_idx_tdown_a[delta];
+ /*Record delta swing for mix mode pwr tracking*/
+ cali_info->absolute_ofdm_swing_idx[p] =
+ -1 * delta_swing_table_idx_tdown_a[delta];
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "******Temp is lower and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_A] = %d\n",
+ cali_info->absolute_ofdm_swing_idx[p]);
+ break;
+ }
+ }
+}
+
+static inline void phydm_odm_tx_power_set(struct phy_dm_struct *dm,
+ struct txpwrtrack_cfg *c,
+ u8 indexforchannel, u8 flag)
+{
+ u8 p = 0;
+
+ if (dm->support_ic_type == ODM_RTL8188E ||
+ dm->support_ic_type == ODM_RTL8192E ||
+ dm->support_ic_type == ODM_RTL8821 ||
+ dm->support_ic_type == ODM_RTL8812 ||
+ dm->support_ic_type == ODM_RTL8723B ||
+ dm->support_ic_type == ODM_RTL8814A ||
+ dm->support_ic_type == ODM_RTL8703B ||
+ dm->support_ic_type == ODM_RTL8188F ||
+ dm->support_ic_type == ODM_RTL8822B ||
+ dm->support_ic_type == ODM_RTL8723D ||
+ dm->support_ic_type == ODM_RTL8821C ||
+ dm->support_ic_type == ODM_RTL8710B) { /* JJ ADD 20161014 */
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "**********Enter POWER Tracking MIX_MODE**********\n");
+ for (p = ODM_RF_PATH_A; p < c->rf_path_count; p++) {
+ if (flag == 0)
+ (*c->odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p,
+ 0);
+ else
+ (*c->odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p,
+ indexforchannel);
+ }
+ } else {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "**********Enter POWER Tracking BBSWING_MODE**********\n");
+ for (p = ODM_RF_PATH_A; p < c->rf_path_count; p++)
+ (*c->odm_tx_pwr_track_set_pwr)(dm, BBSWING, p,
+ indexforchannel);
+ }
+}
+
+void configure_txpower_track(void *dm_void, struct txpwrtrack_cfg *config)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ /* JJ ADD 20161014 */
+
+ if (dm->support_ic_type == ODM_RTL8822B)
+ configure_txpower_track_8822b(config);
+}
+
+/* **********************************************************************
+ * <20121113, Kordan> This function should be called when tx_agc changed.
+ * Otherwise the previous compensation is gone, because we record the
+ * delta of temperature between two TxPowerTracking watch dogs.
+ *
+ * NOTE: If Tx BB swing or Tx scaling is varified during run-time, still
+ * need to call this function.
+ * ***********************************************************************/
+void odm_clear_txpowertracking_state(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
+ struct rtl_efuse *rtlefu = rtl_efuse(rtlpriv);
+ u8 p = 0;
+ struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
+
+ cali_info->bb_swing_idx_cck_base = cali_info->default_cck_index;
+ cali_info->bb_swing_idx_cck = cali_info->default_cck_index;
+ dm->rf_calibrate_info.CCK_index = 0;
+
+ for (p = ODM_RF_PATH_A; p < MAX_RF_PATH; ++p) {
+ cali_info->bb_swing_idx_ofdm_base[p] =
+ cali_info->default_ofdm_index;
+ cali_info->bb_swing_idx_ofdm[p] = cali_info->default_ofdm_index;
+ cali_info->OFDM_index[p] = cali_info->default_ofdm_index;
+
+ cali_info->power_index_offset[p] = 0;
+ cali_info->delta_power_index[p] = 0;
+ cali_info->delta_power_index_last[p] = 0;
+
+ cali_info->absolute_ofdm_swing_idx[p] =
+ 0; /* Initial Mix mode power tracking*/
+ cali_info->remnant_ofdm_swing_idx[p] = 0;
+ cali_info->kfree_offset[p] = 0;
+ }
+
+ cali_info->modify_tx_agc_flag_path_a =
+ false; /*Initial at Modify Tx Scaling mode*/
+ cali_info->modify_tx_agc_flag_path_b =
+ false; /*Initial at Modify Tx Scaling mode*/
+ cali_info->modify_tx_agc_flag_path_c =
+ false; /*Initial at Modify Tx Scaling mode*/
+ cali_info->modify_tx_agc_flag_path_d =
+ false; /*Initial at Modify Tx Scaling mode*/
+ cali_info->remnant_cck_swing_idx = 0;
+ cali_info->thermal_value = rtlefu->eeprom_thermalmeter;
+
+ cali_info->modify_tx_agc_value_cck = 0; /* modify by Mingzhi.Guo */
+ cali_info->modify_tx_agc_value_ofdm = 0; /* modify by Mingzhi.Guo */
+}
+
+void odm_txpowertracking_callback_thermal_meter(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
+ struct rtl_efuse *rtlefu = rtl_efuse(rtlpriv);
+ void *adapter = dm->adapter;
+
+ struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
+
+ u8 thermal_value = 0, delta, delta_LCK, delta_IQK, p = 0, i = 0;
+ s8 diff_DPK[4]; /* use 'for..loop' to initialize */
+ u8 thermal_value_avg_count = 0;
+ u32 thermal_value_avg = 0, regc80, regcd0, regcd4, regab4;
+
+ /* OFDM BB Swing should be less than +3.0dB (required by Arthur) */
+ u8 OFDM_min_index = 0;
+ /* get_right_chnl_place_for_iqk(hal_data->current_channel) */
+ u8 indexforchannel = 0;
+ u8 power_tracking_type = 0; /* no specify type */
+ u8 xtal_offset_eanble = 0;
+
+ struct txpwrtrack_cfg c;
+
+ /* 4 1. The following TWO tables decide the final index of
+ * OFDM/CCK swing table.
+ */
+ u8 *delta_swing_table_idx_tup_a = NULL;
+ u8 *delta_swing_table_idx_tdown_a = NULL;
+ u8 *delta_swing_table_idx_tup_b = NULL;
+ u8 *delta_swing_table_idx_tdown_b = NULL;
+ /*for 8814 add by Yu Chen*/
+ u8 *delta_swing_table_idx_tup_c = NULL;
+ u8 *delta_swing_table_idx_tdown_c = NULL;
+ u8 *delta_swing_table_idx_tup_d = NULL;
+ u8 *delta_swing_table_idx_tdown_d = NULL;
+ /*for Xtal Offset by James.Tung*/
+ s8 *delta_swing_table_xtal_up = NULL;
+ s8 *delta_swing_table_xtal_down = NULL;
+
+ /* 4 2. Initialization ( 7 steps in total ) */
+
+ configure_txpower_track(dm, &c);
+
+ (*c.get_delta_swing_table)(dm, (u8 **)&delta_swing_table_idx_tup_a,
+ (u8 **)&delta_swing_table_idx_tdown_a,
+ (u8 **)&delta_swing_table_idx_tup_b,
+ (u8 **)&delta_swing_table_idx_tdown_b);
+
+ if (dm->support_ic_type & ODM_RTL8814A) /*for 8814 path C & D*/
+ (*c.get_delta_swing_table8814only)(
+ dm, (u8 **)&delta_swing_table_idx_tup_c,
+ (u8 **)&delta_swing_table_idx_tdown_c,
+ (u8 **)&delta_swing_table_idx_tup_d,
+ (u8 **)&delta_swing_table_idx_tdown_d);
+ /* JJ ADD 20161014 */
+ if (dm->support_ic_type &
+ (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B)) /*for Xtal Offset*/
+ (*c.get_delta_swing_xtal_table)(
+ dm, (s8 **)&delta_swing_table_xtal_up,
+ (s8 **)&delta_swing_table_xtal_down);
+
+ cali_info->txpowertracking_callback_cnt++; /*cosa add for debug*/
+ cali_info->is_txpowertracking_init = true;
+
+ /*cali_info->txpowertrack_control = hal_data->txpowertrack_control;
+ *<Kordan> We should keep updating ctrl variable according to HalData.
+ *<Kordan> rf_calibrate_info.rega24 will be initialized when
+ *ODM HW configuring, but MP configures with para files.
+ */
+ if (dm->mp_mode)
+ cali_info->rega24 = 0x090e1317;
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "===>%s\n cali_info->bb_swing_idx_cck_base: %d, cali_info->bb_swing_idx_ofdm_base[A]: %d, cali_info->default_ofdm_index: %d\n",
+ __func__, cali_info->bb_swing_idx_cck_base,
+ cali_info->bb_swing_idx_ofdm_base[ODM_RF_PATH_A],
+ cali_info->default_ofdm_index);
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "cali_info->txpowertrack_control=%d, rtlefu->eeprom_thermalmeter %d\n",
+ cali_info->txpowertrack_control, rtlefu->eeprom_thermalmeter);
+
+ thermal_value =
+ (u8)odm_get_rf_reg(dm, ODM_RF_PATH_A, c.thermal_reg_addr,
+ 0xfc00); /* 0x42: RF Reg[15:10] 88E */
+
+ /*add log by zhao he, check c80/c94/c14/ca0 value*/
+ if (dm->support_ic_type == ODM_RTL8723D) {
+ regc80 = odm_get_bb_reg(dm, 0xc80, MASKDWORD);
+ regcd0 = odm_get_bb_reg(dm, 0xcd0, MASKDWORD);
+ regcd4 = odm_get_bb_reg(dm, 0xcd4, MASKDWORD);
+ regab4 = odm_get_bb_reg(dm, 0xab4, 0x000007FF);
+ ODM_RT_TRACE(
+ dm, ODM_COMP_CALIBRATION,
+ "0xc80 = 0x%x 0xcd0 = 0x%x 0xcd4 = 0x%x 0xab4 = 0x%x\n",
+ regc80, regcd0, regcd4, regab4);
+ }
+ /* JJ ADD 20161014 */
+ if (dm->support_ic_type == ODM_RTL8710B) {
+ regc80 = odm_get_bb_reg(dm, 0xc80, MASKDWORD);
+ regcd0 = odm_get_bb_reg(dm, 0xcd0, MASKDWORD);
+ regcd4 = odm_get_bb_reg(dm, 0xcd4, MASKDWORD);
+ regab4 = odm_get_bb_reg(dm, 0xab4, 0x000007FF);
+ ODM_RT_TRACE(
+ dm, ODM_COMP_CALIBRATION,
+ "0xc80 = 0x%x 0xcd0 = 0x%x 0xcd4 = 0x%x 0xab4 = 0x%x\n",
+ regc80, regcd0, regcd4, regab4);
+ }
+
+ if (!cali_info->txpowertrack_control)
+ return;
+
+ /*4 3. Initialize ThermalValues of rf_calibrate_info*/
+
+ if (cali_info->is_reloadtxpowerindex)
+ ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
+ "reload ofdm index for band switch\n");
+
+ /*4 4. Calculate average thermal meter*/
+
+ cali_info->thermal_value_avg[cali_info->thermal_value_avg_index] =
+ thermal_value;
+ cali_info->thermal_value_avg_index++;
+ if (cali_info->thermal_value_avg_index ==
+ c.average_thermal_num) /*Average times = c.average_thermal_num*/
+ cali_info->thermal_value_avg_index = 0;
+
+ for (i = 0; i < c.average_thermal_num; i++) {
+ if (cali_info->thermal_value_avg[i]) {
+ thermal_value_avg += cali_info->thermal_value_avg[i];
+ thermal_value_avg_count++;
+ }
+ }
+
+ if (thermal_value_avg_count) {
+ /* Calculate Average thermal_value after average enough times */
+ thermal_value =
+ (u8)(thermal_value_avg / thermal_value_avg_count);
+ cali_info->thermal_value_delta =
+ thermal_value - rtlefu->eeprom_thermalmeter;
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "AVG Thermal Meter = 0x%X, EFUSE Thermal base = 0x%X\n",
+ thermal_value, rtlefu->eeprom_thermalmeter);
+ }
+
+ /* 4 5. Calculate delta, delta_LCK, delta_IQK. */
+
+ /* "delta" is used to determine whether thermal value changes or not*/
+ delta = (thermal_value > cali_info->thermal_value) ?
+ (thermal_value - cali_info->thermal_value) :
+ (cali_info->thermal_value - thermal_value);
+ delta_LCK = (thermal_value > cali_info->thermal_value_lck) ?
+ (thermal_value - cali_info->thermal_value_lck) :
+ (cali_info->thermal_value_lck - thermal_value);
+ delta_IQK = (thermal_value > cali_info->thermal_value_iqk) ?
+ (thermal_value - cali_info->thermal_value_iqk) :
+ (cali_info->thermal_value_iqk - thermal_value);
+
+ if (cali_info->thermal_value_iqk ==
+ 0xff) { /*no PG, use thermal value for IQK*/
+ cali_info->thermal_value_iqk = thermal_value;
+ delta_IQK =
+ (thermal_value > cali_info->thermal_value_iqk) ?
+ (thermal_value - cali_info->thermal_value_iqk) :
+ (cali_info->thermal_value_iqk - thermal_value);
+ ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
+ "no PG, use thermal_value for IQK\n");
+ }
+
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
+ diff_DPK[p] = (s8)thermal_value - (s8)cali_info->dpk_thermal[p];
+
+ /*4 6. If necessary, do LCK.*/
+
+ if (!(dm->support_ic_type &
+ ODM_RTL8821)) { /*no PG, do LCK at initial status*/
+ if (cali_info->thermal_value_lck == 0xff) {
+ ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
+ "no PG, do LCK\n");
+ cali_info->thermal_value_lck = thermal_value;
+
+ /*Use RTLCK, so close power tracking driver LCK*/
+ if (!(dm->support_ic_type & ODM_RTL8814A) &&
+ c.phy_lc_calibrate)
+ (*c.phy_lc_calibrate)(dm);
+
+ delta_LCK =
+ (thermal_value > cali_info->thermal_value_lck) ?
+ (thermal_value -
+ cali_info->thermal_value_lck) :
+ (cali_info->thermal_value_lck -
+ thermal_value);
+ }
+
+ ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
+ "(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n",
+ delta, delta_LCK, delta_IQK);
+
+ /*Delta temperature is equal to or larger than 20 centigrade.*/
+ if (delta_LCK >= c.threshold_iqk) {
+ ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
+ "delta_LCK(%d) >= threshold_iqk(%d)\n",
+ delta_LCK, c.threshold_iqk);
+ cali_info->thermal_value_lck = thermal_value;
+
+ /*Use RTLCK, so close power tracking driver LCK*/
+ if (!(dm->support_ic_type & ODM_RTL8814A) &&
+ c.phy_lc_calibrate)
+ (*c.phy_lc_calibrate)(dm);
+ }
+ }
+
+ /*3 7. If necessary, move the index of swing table to adjust Tx power.*/
+
+ if (delta > 0 && cali_info->txpowertrack_control) {
+ /* "delta" here is used to record the abs value of difference.*/
+ delta = thermal_value > rtlefu->eeprom_thermalmeter ?
+ (thermal_value - rtlefu->eeprom_thermalmeter) :
+ (rtlefu->eeprom_thermalmeter - thermal_value);
+ if (delta >= TXPWR_TRACK_TABLE_SIZE)
+ delta = TXPWR_TRACK_TABLE_SIZE - 1;
+
+ /*4 7.1 The Final Power index = BaseIndex + power_index_offset*/
+
+ if (thermal_value > rtlefu->eeprom_thermalmeter) {
+ phydm_set_calibrate_info_up(
+ dm, &c, delta, cali_info,
+ delta_swing_table_idx_tup_a,
+ delta_swing_table_idx_tup_b,
+ delta_swing_table_idx_tup_c,
+ delta_swing_table_idx_tup_d);
+ /* JJ ADD 20161014 */
+ if (dm->support_ic_type &
+ (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B)) {
+ /*Save xtal_offset from Xtal table*/
+
+ /*recording last Xtal offset*/
+ cali_info->xtal_offset_last =
+ cali_info->xtal_offset;
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "[Xtal] delta_swing_table_xtal_up[%d] = %d\n",
+ delta,
+ delta_swing_table_xtal_up[delta]);
+ cali_info->xtal_offset =
+ delta_swing_table_xtal_up[delta];
+ xtal_offset_eanble =
+ (cali_info->xtal_offset_last ==
+ cali_info->xtal_offset) ?
+ 0 :
+ 1;
+ }
+
+ } else {
+ phydm_set_calibrate_info_down(
+ dm, &c, delta, cali_info,
+ delta_swing_table_idx_tdown_a,
+ delta_swing_table_idx_tdown_b,
+ delta_swing_table_idx_tdown_c,
+ delta_swing_table_idx_tdown_d);
+ /* JJ ADD 20161014 */
+ if (dm->support_ic_type &
+ (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B)) {
+ /*Save xtal_offset from Xtal table*/
+
+ /*recording last Xtal offset*/
+ cali_info->xtal_offset_last =
+ cali_info->xtal_offset;
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "[Xtal] delta_swing_table_xtal_down[%d] = %d\n",
+ delta,
+ delta_swing_table_xtal_down[delta]);
+ cali_info->xtal_offset =
+ delta_swing_table_xtal_down[delta];
+ xtal_offset_eanble =
+ (cali_info->xtal_offset_last ==
+ cali_info->xtal_offset) ?
+ 0 :
+ 1;
+ }
+ }
+
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "\n\n=========================== [path-%d] Calculating power_index_offset===========================\n",
+ p);
+
+ if (cali_info->delta_power_index[p] ==
+ cali_info->delta_power_index_last[p]) {
+ /* If Thermal value changes but lookup table
+ * value still the same
+ */
+ cali_info->power_index_offset[p] = 0;
+ } else {
+ /*Power idx diff between 2 times Pwr Tracking*/
+ cali_info->power_index_offset[p] =
+ cali_info->delta_power_index[p] -
+ cali_info->delta_power_index_last[p];
+ }
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "[path-%d] power_index_offset(%d) = delta_power_index(%d) - delta_power_index_last(%d)\n",
+ p, cali_info->power_index_offset[p],
+ cali_info->delta_power_index[p],
+ cali_info->delta_power_index_last[p]);
+
+ cali_info->OFDM_index[p] =
+ cali_info->bb_swing_idx_ofdm_base[p] +
+ cali_info->power_index_offset[p];
+ cali_info->CCK_index =
+ cali_info->bb_swing_idx_cck_base +
+ cali_info->power_index_offset[p];
+
+ cali_info->bb_swing_idx_cck = cali_info->CCK_index;
+ cali_info->bb_swing_idx_ofdm[p] =
+ cali_info->OFDM_index[p];
+
+ /*******Print BB Swing base and index Offset**********/
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "The 'CCK' final index(%d) = BaseIndex(%d) + power_index_offset(%d)\n",
+ cali_info->bb_swing_idx_cck,
+ cali_info->bb_swing_idx_cck_base,
+ cali_info->power_index_offset[p]);
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "The 'OFDM' final index(%d) = BaseIndex[%d](%d) + power_index_offset(%d)\n",
+ cali_info->bb_swing_idx_ofdm[p], p,
+ cali_info->bb_swing_idx_ofdm_base[p],
+ cali_info->power_index_offset[p]);
+
+ /*4 7.1 Handle boundary conditions of index.*/
+
+ if (cali_info->OFDM_index[p] >
+ c.swing_table_size_ofdm - 1)
+ cali_info->OFDM_index[p] =
+ c.swing_table_size_ofdm - 1;
+ else if (cali_info->OFDM_index[p] <= OFDM_min_index)
+ cali_info->OFDM_index[p] = OFDM_min_index;
+ }
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "\n\n========================================================================================================\n");
+
+ if (cali_info->CCK_index > c.swing_table_size_cck - 1)
+ cali_info->CCK_index = c.swing_table_size_cck - 1;
+ else if (cali_info->CCK_index <= 0)
+ cali_info->CCK_index = 0;
+ } else {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "The thermal meter is unchanged or TxPowerTracking OFF(%d): thermal_value: %d, cali_info->thermal_value: %d\n",
+ cali_info->txpowertrack_control, thermal_value,
+ cali_info->thermal_value);
+
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
+ cali_info->power_index_offset[p] = 0;
+ }
+
+ /*Print Swing base & current*/
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "TxPowerTracking: [CCK] Swing Current index: %d, Swing base index: %d\n",
+ cali_info->CCK_index, cali_info->bb_swing_idx_cck_base);
+
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "TxPowerTracking: [OFDM] Swing Current index: %d, Swing base index[%d]: %d\n",
+ cali_info->OFDM_index[p], p,
+ cali_info->bb_swing_idx_ofdm_base[p]);
+
+ if ((dm->support_ic_type & ODM_RTL8814A)) {
+ ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
+ "power_tracking_type=%d\n", power_tracking_type);
+
+ if (power_tracking_type == 0) {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "**********Enter POWER Tracking MIX_MODE**********\n");
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
+ (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p,
+ 0);
+ } else if (power_tracking_type == 1) {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "**********Enter POWER Tracking MIX(2G) TSSI(5G) MODE**********\n");
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
+ (*c.odm_tx_pwr_track_set_pwr)(
+ dm, MIX_2G_TSSI_5G_MODE, p, 0);
+ } else if (power_tracking_type == 2) {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "**********Enter POWER Tracking MIX(5G) TSSI(2G)MODE**********\n");
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
+ (*c.odm_tx_pwr_track_set_pwr)(
+ dm, MIX_5G_TSSI_2G_MODE, p, 0);
+ } else if (power_tracking_type == 3) {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "**********Enter POWER Tracking TSSI MODE**********\n");
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
+ (*c.odm_tx_pwr_track_set_pwr)(dm, TSSI_MODE, p,
+ 0);
+ }
+ /*Record last Power Tracking Thermal value*/
+ cali_info->thermal_value = thermal_value;
+
+ } else if ((cali_info->power_index_offset[ODM_RF_PATH_A] != 0 ||
+ cali_info->power_index_offset[ODM_RF_PATH_B] != 0 ||
+ cali_info->power_index_offset[ODM_RF_PATH_C] != 0 ||
+ cali_info->power_index_offset[ODM_RF_PATH_D] != 0) &&
+ cali_info->txpowertrack_control &&
+ (rtlefu->eeprom_thermalmeter != 0xff)) {
+ /* 4 7.2 Configure the Swing Table to adjust Tx Power. */
+
+ /*Always true after Tx Power is adjusted by power tracking.*/
+ cali_info->is_tx_power_changed = true;
+ /* 2012/04/23 MH According to Luke's suggestion, we can not
+ * write BB digital to increase TX power. Otherwise, EVM will
+ * be bad.
+ */
+ /* 2012/04/25 MH Add for tx power tracking to set tx power in
+ * tx agc for 88E.
+ */
+ if (thermal_value > cali_info->thermal_value) {
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
+ /* print temperature increasing */
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "Temperature Increasing(%d): delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
+ p, cali_info->power_index_offset[p],
+ delta, thermal_value,
+ rtlefu->eeprom_thermalmeter,
+ cali_info->thermal_value);
+ }
+ } else if (thermal_value <
+ cali_info->thermal_value) { /*Low temperature*/
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
+ /* print temperature decreasing */
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "Temperature Decreasing(%d): delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
+ p, cali_info->power_index_offset[p],
+ delta, thermal_value,
+ rtlefu->eeprom_thermalmeter,
+ cali_info->thermal_value);
+ }
+ }
+
+ if (thermal_value > rtlefu->eeprom_thermalmeter) {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "Temperature(%d) higher than PG value(%d)\n",
+ thermal_value, rtlefu->eeprom_thermalmeter);
+
+ phydm_odm_tx_power_set(dm, &c, indexforchannel, 0);
+ } else {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "Temperature(%d) lower than PG value(%d)\n",
+ thermal_value, rtlefu->eeprom_thermalmeter);
+ phydm_odm_tx_power_set(dm, &c, indexforchannel, 1);
+ }
+
+ /*Record last time Power Tracking result as base.*/
+ cali_info->bb_swing_idx_cck_base = cali_info->bb_swing_idx_cck;
+
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
+ cali_info->bb_swing_idx_ofdm_base[p] =
+ cali_info->bb_swing_idx_ofdm[p];
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "cali_info->thermal_value = %d thermal_value= %d\n",
+ cali_info->thermal_value, thermal_value);
+
+ /*Record last Power Tracking Thermal value*/
+ cali_info->thermal_value = thermal_value;
+ }
+
+ if (dm->support_ic_type == ODM_RTL8703B ||
+ dm->support_ic_type == ODM_RTL8723D ||
+ dm->support_ic_type == ODM_RTL8710B) { /* JJ ADD 20161014 */
+
+ if (xtal_offset_eanble != 0 &&
+ cali_info->txpowertrack_control &&
+ (rtlefu->eeprom_thermalmeter != 0xff)) {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "**********Enter Xtal Tracking**********\n");
+
+ if (thermal_value > rtlefu->eeprom_thermalmeter) {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "Temperature(%d) higher than PG value(%d)\n",
+ thermal_value,
+ rtlefu->eeprom_thermalmeter);
+ (*c.odm_txxtaltrack_set_xtal)(dm);
+ } else {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "Temperature(%d) lower than PG value(%d)\n",
+ thermal_value,
+ rtlefu->eeprom_thermalmeter);
+ (*c.odm_txxtaltrack_set_xtal)(dm);
+ }
+ }
+ ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
+ "**********End Xtal Tracking**********\n");
+ }
+
+ if (!IS_HARDWARE_TYPE_8723B(adapter)) {
+ /* Delta temperature is equal to or larger than 20 centigrade
+ * (When threshold is 8).
+ */
+ if (delta_IQK >= c.threshold_iqk) {
+ ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
+ "delta_IQK(%d) >= threshold_iqk(%d)\n",
+ delta_IQK, c.threshold_iqk);
+ if (!cali_info->is_iqk_in_progress)
+ (*c.do_iqk)(dm, delta_IQK, thermal_value, 8);
+ }
+ }
+ if (cali_info->dpk_thermal[ODM_RF_PATH_A] != 0) {
+ if (diff_DPK[ODM_RF_PATH_A] >= c.threshold_dpk) {
+ odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
+ odm_set_bb_reg(
+ dm, 0xcc4,
+ BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10),
+ (diff_DPK[ODM_RF_PATH_A] / c.threshold_dpk));
+ odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
+ } else if ((diff_DPK[ODM_RF_PATH_A] <= -1 * c.threshold_dpk)) {
+ s32 value = 0x20 +
+ (diff_DPK[ODM_RF_PATH_A] / c.threshold_dpk);
+
+ odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
+ odm_set_bb_reg(dm, 0xcc4, BIT(14) | BIT(13) | BIT(12) |
+ BIT(11) | BIT(10),
+ value);
+ odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
+ } else {
+ odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
+ odm_set_bb_reg(dm, 0xcc4, BIT(14) | BIT(13) | BIT(12) |
+ BIT(11) | BIT(10),
+ 0);
+ odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
+ }
+ }
+ if (cali_info->dpk_thermal[ODM_RF_PATH_B] != 0) {
+ if (diff_DPK[ODM_RF_PATH_B] >= c.threshold_dpk) {
+ odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
+ odm_set_bb_reg(
+ dm, 0xec4,
+ BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10),
+ (diff_DPK[ODM_RF_PATH_B] / c.threshold_dpk));
+ odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
+ } else if ((diff_DPK[ODM_RF_PATH_B] <= -1 * c.threshold_dpk)) {
+ s32 value = 0x20 +
+ (diff_DPK[ODM_RF_PATH_B] / c.threshold_dpk);
+
+ odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
+ odm_set_bb_reg(dm, 0xec4, BIT(14) | BIT(13) | BIT(12) |
+ BIT(11) | BIT(10),
+ value);
+ odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
+ } else {
+ odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
+ odm_set_bb_reg(dm, 0xec4, BIT(14) | BIT(13) | BIT(12) |
+ BIT(11) | BIT(10),
+ 0);
+ odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
+ }
+ }
+
+ ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, "<===%s\n", __func__);
+
+ cali_info->tx_powercount = 0;
+}
+
+/* 3============================================================
+ * 3 IQ Calibration
+ * 3============================================================
+ */
+
+void odm_reset_iqk_result(void *dm_void) { return; }
+
+u8 odm_get_right_chnl_place_for_iqk(u8 chnl)
+{
+ u8 channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = {
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54,
+ 56, 58, 60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
+ 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136,
+ 138, 140, 149, 151, 153, 155, 157, 159, 161, 163, 165};
+ u8 place = chnl;
+
+ if (chnl > 14) {
+ for (place = 14; place < sizeof(channel_all); place++) {
+ if (channel_all[place] == chnl)
+ return place - 13;
+ }
+ }
+ return 0;
+}
+
+static void odm_iq_calibrate(struct phy_dm_struct *dm)
+{
+ void *adapter = dm->adapter;
+
+ if (IS_HARDWARE_TYPE_8812AU(adapter))
+ return;
+
+ if (dm->is_linked) {
+ if ((*dm->channel != dm->pre_channel) &&
+ (!*dm->is_scan_in_process)) {
+ dm->pre_channel = *dm->channel;
+ dm->linked_interval = 0;
+ }
+
+ if (dm->linked_interval < 3)
+ dm->linked_interval++;
+
+ if (dm->linked_interval == 2) {
+ if (IS_HARDWARE_TYPE_8814A(adapter))
+ ;
+
+ else if (IS_HARDWARE_TYPE_8822B(adapter))
+ phy_iq_calibrate_8822b(dm, false);
+ }
+ } else {
+ dm->linked_interval = 0;
+ }
+}
+
+void phydm_rf_init(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ odm_txpowertracking_init(dm);
+
+ odm_clear_txpowertracking_state(dm);
+}
+
+void phydm_rf_watchdog(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ odm_txpowertracking_check(dm);
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES)
+ odm_iq_calibrate(dm);
+}
diff --git a/drivers/staging/rtlwifi/phydm/halphyrf_ce.h b/drivers/staging/rtlwifi/phydm/halphyrf_ce.h
new file mode 100644
index 0000000..e5d6257
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/halphyrf_ce.h
@@ -0,0 +1,85 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __HAL_PHY_RF_H__
+#define __HAL_PHY_RF_H__
+
+#include "phydm_kfree.h"
+
+#include "rtl8822b/phydm_iqk_8822b.h"
+
+#include "phydm_powertracking_ce.h"
+
+enum spur_cal_method { PLL_RESET, AFE_PHASE_SEL };
+
+enum pwrtrack_method {
+ BBSWING,
+ TXAGC,
+ MIX_MODE,
+ TSSI_MODE,
+ MIX_2G_TSSI_5G_MODE,
+ MIX_5G_TSSI_2G_MODE
+};
+
+typedef void (*func_set_pwr)(void *, enum pwrtrack_method, u8, u8);
+typedef void (*func_iqk)(void *, u8, u8, u8);
+typedef void (*func_lck)(void *);
+typedef void (*func_swing)(void *, u8 **, u8 **, u8 **, u8 **);
+typedef void (*func_swing8814only)(void *, u8 **, u8 **, u8 **, u8 **);
+typedef void (*func_swing_xtal)(void *, s8 **, s8 **);
+typedef void (*func_set_xtal)(void *);
+
+struct txpwrtrack_cfg {
+ u8 swing_table_size_cck;
+ u8 swing_table_size_ofdm;
+ u8 threshold_iqk;
+ u8 threshold_dpk;
+ u8 average_thermal_num;
+ u8 rf_path_count;
+ u32 thermal_reg_addr;
+ func_set_pwr odm_tx_pwr_track_set_pwr;
+ func_iqk do_iqk;
+ func_lck phy_lc_calibrate;
+ func_swing get_delta_swing_table;
+ func_swing8814only get_delta_swing_table8814only;
+ func_swing_xtal get_delta_swing_xtal_table;
+ func_set_xtal odm_txxtaltrack_set_xtal;
+};
+
+void configure_txpower_track(void *dm_void, struct txpwrtrack_cfg *config);
+
+void odm_clear_txpowertracking_state(void *dm_void);
+
+void odm_txpowertracking_callback_thermal_meter(void *dm);
+
+#define ODM_TARGET_CHNL_NUM_2G_5G 59
+
+void odm_reset_iqk_result(void *dm_void);
+u8 odm_get_right_chnl_place_for_iqk(u8 chnl);
+
+void phydm_rf_init(void *dm_void);
+void phydm_rf_watchdog(void *dm_void);
+
+#endif /* #ifndef __HAL_PHY_RF_H__ */
diff --git a/drivers/staging/rtlwifi/phydm/mp_precomp.h b/drivers/staging/rtlwifi/phydm/mp_precomp.h
new file mode 100644
index 0000000..b313de5
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/mp_precomp.h
@@ -0,0 +1,24 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
diff --git a/drivers/staging/rtlwifi/phydm/phydm.c b/drivers/staging/rtlwifi/phydm/phydm.c
new file mode 100644
index 0000000..37888c30
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm.c
@@ -0,0 +1,1986 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+/* ************************************************************
+ * include files
+ * *************************************************************/
+
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+static const u16 db_invert_table[12][8] = {
+ {1, 1, 1, 2, 2, 2, 2, 3},
+ {3, 3, 4, 4, 4, 5, 6, 6},
+ {7, 8, 9, 10, 11, 13, 14, 16},
+ {18, 20, 22, 25, 28, 32, 35, 40},
+ {45, 50, 56, 63, 71, 79, 89, 100},
+ {112, 126, 141, 158, 178, 200, 224, 251},
+ {282, 316, 355, 398, 447, 501, 562, 631},
+ {708, 794, 891, 1000, 1122, 1259, 1413, 1585},
+ {1778, 1995, 2239, 2512, 2818, 3162, 3548, 3981},
+ {4467, 5012, 5623, 6310, 7079, 7943, 8913, 10000},
+ {11220, 12589, 14125, 15849, 17783, 19953, 22387, 25119},
+ {28184, 31623, 35481, 39811, 44668, 50119, 56234, 65535},
+};
+
+/* ************************************************************
+ * Local Function predefine.
+ * *************************************************************/
+
+/* START------------COMMON INFO RELATED--------------- */
+
+static void odm_update_power_training_state(struct phy_dm_struct *dm);
+
+/* ************************************************************
+ * 3 Export Interface
+ * *************************************************************/
+
+/*Y = 10*log(X)*/
+s32 odm_pwdb_conversion(s32 X, u32 total_bit, u32 decimal_bit)
+{
+ s32 Y, integer = 0, decimal = 0;
+ u32 i;
+
+ if (X == 0)
+ X = 1; /* log2(x), x can't be 0 */
+
+ for (i = (total_bit - 1); i > 0; i--) {
+ if (X & BIT(i)) {
+ integer = i;
+ if (i > 0) {
+ /* decimal is 0.5dB*3=1.5dB~=2dB */
+ decimal = (X & BIT(i - 1)) ? 2 : 0;
+ }
+ break;
+ }
+ }
+
+ Y = 3 * (integer - decimal_bit) + decimal; /* 10*log(x)=3*log2(x), */
+
+ return Y;
+}
+
+s32 odm_sign_conversion(s32 value, u32 total_bit)
+{
+ if (value & BIT(total_bit - 1))
+ value -= BIT(total_bit);
+ return value;
+}
+
+void phydm_seq_sorting(void *dm_void, u32 *value, u32 *rank_idx, u32 *idx_out,
+ u8 seq_length)
+{
+ u8 i = 0, j = 0;
+ u32 tmp_a, tmp_b;
+ u32 tmp_idx_a, tmp_idx_b;
+
+ for (i = 0; i < seq_length; i++) {
+ rank_idx[i] = i;
+ /**/
+ }
+
+ for (i = 0; i < (seq_length - 1); i++) {
+ for (j = 0; j < (seq_length - 1 - i); j++) {
+ tmp_a = value[j];
+ tmp_b = value[j + 1];
+
+ tmp_idx_a = rank_idx[j];
+ tmp_idx_b = rank_idx[j + 1];
+
+ if (tmp_a < tmp_b) {
+ value[j] = tmp_b;
+ value[j + 1] = tmp_a;
+
+ rank_idx[j] = tmp_idx_b;
+ rank_idx[j + 1] = tmp_idx_a;
+ }
+ }
+ }
+
+ for (i = 0; i < seq_length; i++) {
+ idx_out[rank_idx[i]] = i + 1;
+ /**/
+ }
+}
+
+void odm_init_mp_driver_status(struct phy_dm_struct *dm)
+{
+ dm->mp_mode = false;
+}
+
+static void odm_update_mp_driver_status(struct phy_dm_struct *dm)
+{
+ /* Do nothing. */
+}
+
+static void phydm_init_trx_antenna_setting(struct phy_dm_struct *dm)
+{
+ /*#if (RTL8814A_SUPPORT == 1)*/
+
+ if (dm->support_ic_type & (ODM_RTL8814A)) {
+ u8 rx_ant = 0, tx_ant = 0;
+
+ rx_ant = (u8)odm_get_bb_reg(dm, ODM_REG(BB_RX_PATH, dm),
+ ODM_BIT(BB_RX_PATH, dm));
+ tx_ant = (u8)odm_get_bb_reg(dm, ODM_REG(BB_TX_PATH, dm),
+ ODM_BIT(BB_TX_PATH, dm));
+ dm->tx_ant_status = (tx_ant & 0xf);
+ dm->rx_ant_status = (rx_ant & 0xf);
+ } else if (dm->support_ic_type & (ODM_RTL8723D | ODM_RTL8821C |
+ ODM_RTL8710B)) { /* JJ ADD 20161014 */
+ dm->tx_ant_status = 0x1;
+ dm->rx_ant_status = 0x1;
+ }
+ /*#endif*/
+}
+
+static void phydm_traffic_load_decision(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ /*---TP & Trafic-load calculation---*/
+
+ if (dm->last_tx_ok_cnt > *dm->num_tx_bytes_unicast)
+ dm->last_tx_ok_cnt = *dm->num_tx_bytes_unicast;
+
+ if (dm->last_rx_ok_cnt > *dm->num_rx_bytes_unicast)
+ dm->last_rx_ok_cnt = *dm->num_rx_bytes_unicast;
+
+ dm->cur_tx_ok_cnt = *dm->num_tx_bytes_unicast - dm->last_tx_ok_cnt;
+ dm->cur_rx_ok_cnt = *dm->num_rx_bytes_unicast - dm->last_rx_ok_cnt;
+ dm->last_tx_ok_cnt = *dm->num_tx_bytes_unicast;
+ dm->last_rx_ok_cnt = *dm->num_rx_bytes_unicast;
+
+ dm->tx_tp = ((dm->tx_tp) >> 1) +
+ (u32)(((dm->cur_tx_ok_cnt) >> 18) >>
+ 1); /* <<3(8bit), >>20(10^6,M), >>1(2sec)*/
+ dm->rx_tp = ((dm->rx_tp) >> 1) +
+ (u32)(((dm->cur_rx_ok_cnt) >> 18) >>
+ 1); /* <<3(8bit), >>20(10^6,M), >>1(2sec)*/
+ dm->total_tp = dm->tx_tp + dm->rx_tp;
+
+ dm->pre_traffic_load = dm->traffic_load;
+
+ if (dm->cur_tx_ok_cnt > 1875000 ||
+ dm->cur_rx_ok_cnt >
+ 1875000) { /* ( 1.875M * 8bit ) / 2sec= 7.5M bits /sec )*/
+
+ dm->traffic_load = TRAFFIC_HIGH;
+ /**/
+ } else if (
+ dm->cur_tx_ok_cnt > 500000 ||
+ dm->cur_rx_ok_cnt >
+ 500000) { /*( 0.5M * 8bit ) / 2sec = 2M bits /sec )*/
+
+ dm->traffic_load = TRAFFIC_MID;
+ /**/
+ } else if (
+ dm->cur_tx_ok_cnt > 100000 ||
+ dm->cur_rx_ok_cnt >
+ 100000) { /*( 0.1M * 8bit ) / 2sec = 0.4M bits /sec )*/
+
+ dm->traffic_load = TRAFFIC_LOW;
+ /**/
+ } else {
+ dm->traffic_load = TRAFFIC_ULTRA_LOW;
+ /**/
+ }
+}
+
+static void phydm_config_ofdm_tx_path(struct phy_dm_struct *dm, u32 path) {}
+
+void phydm_config_ofdm_rx_path(struct phy_dm_struct *dm, u32 path)
+{
+ u8 ofdm_rx_path = 0;
+
+ if (dm->support_ic_type & (ODM_RTL8192E)) {
+ } else if (dm->support_ic_type & (ODM_RTL8812 | ODM_RTL8822B)) {
+ if (path == PHYDM_A) {
+ ofdm_rx_path = 1;
+ /**/
+ } else if (path == PHYDM_B) {
+ ofdm_rx_path = 2;
+ /**/
+ } else if (path == PHYDM_AB) {
+ ofdm_rx_path = 3;
+ /**/
+ }
+
+ odm_set_bb_reg(dm, 0x808, MASKBYTE0,
+ ((ofdm_rx_path << 4) | ofdm_rx_path));
+ }
+}
+
+static void phydm_config_cck_rx_antenna_init(struct phy_dm_struct *dm) {}
+
+static void phydm_config_cck_rx_path(struct phy_dm_struct *dm, u8 path,
+ u8 path_div_en)
+{
+}
+
+void phydm_config_trx_path(void *dm_void, u32 *const dm_value, u32 *_used,
+ char *output, u32 *_out_len)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ /* CCK */
+ if (dm_value[0] == 0) {
+ if (dm_value[1] == 1) { /*TX*/
+ if (dm_value[2] == 1)
+ odm_set_bb_reg(dm, 0xa04, 0xf0000000, 0x8);
+ else if (dm_value[2] == 2)
+ odm_set_bb_reg(dm, 0xa04, 0xf0000000, 0x4);
+ else if (dm_value[2] == 3)
+ odm_set_bb_reg(dm, 0xa04, 0xf0000000, 0xc);
+ } else if (dm_value[1] == 2) { /*RX*/
+
+ phydm_config_cck_rx_antenna_init(dm);
+
+ if (dm_value[2] == 1)
+ phydm_config_cck_rx_path(dm, PHYDM_A,
+ CCA_PATHDIV_DISABLE);
+ else if (dm_value[2] == 2)
+ phydm_config_cck_rx_path(dm, PHYDM_B,
+ CCA_PATHDIV_DISABLE);
+ else if (dm_value[2] == 3 &&
+ dm_value[3] == 1) /*enable path diversity*/
+ phydm_config_cck_rx_path(dm, PHYDM_AB,
+ CCA_PATHDIV_ENABLE);
+ else if (dm_value[2] == 3 && dm_value[3] != 1)
+ phydm_config_cck_rx_path(dm, PHYDM_B,
+ CCA_PATHDIV_DISABLE);
+ }
+ }
+ /* OFDM */
+ else if (dm_value[0] == 1) {
+ if (dm_value[1] == 1) { /*TX*/
+ phydm_config_ofdm_tx_path(dm, dm_value[2]);
+ /**/
+ } else if (dm_value[1] == 2) { /*RX*/
+ phydm_config_ofdm_rx_path(dm, dm_value[2]);
+ /**/
+ }
+ }
+
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "PHYDM Set path [%s] [%s] = [%s%s%s%s]\n",
+ (dm_value[0] == 1) ? "OFDM" : "CCK",
+ (dm_value[1] == 1) ? "TX" : "RX",
+ (dm_value[2] & 0x1) ? "A" : "", (dm_value[2] & 0x2) ? "B" : "",
+ (dm_value[2] & 0x4) ? "C" : "", (dm_value[2] & 0x8) ? "D" : "");
+}
+
+static void phydm_init_cck_setting(struct phy_dm_struct *dm)
+{
+ dm->is_cck_high_power = (bool)odm_get_bb_reg(
+ dm, ODM_REG(CCK_RPT_FORMAT, dm), ODM_BIT(CCK_RPT_FORMAT, dm));
+
+ /* JJ ADD 20161014 */
+ /* JJ ADD 20161014 */
+ if (dm->support_ic_type & (ODM_RTL8723D | ODM_RTL8822B | ODM_RTL8197F |
+ ODM_RTL8821C | ODM_RTL8710B))
+ dm->cck_new_agc = odm_get_bb_reg(dm, 0xa9c, BIT(17)) ?
+ true :
+ false; /*1: new agc 0: old agc*/
+ else
+ dm->cck_new_agc = false;
+}
+
+static void phydm_init_soft_ml_setting(struct phy_dm_struct *dm)
+{
+ if (!dm->mp_mode) {
+ if (dm->support_ic_type & ODM_RTL8822B)
+ odm_set_bb_reg(dm, 0x19a8, MASKDWORD, 0xc10a0000);
+ }
+}
+
+static void phydm_init_hw_info_by_rfe(struct phy_dm_struct *dm)
+{
+ if (dm->support_ic_type & ODM_RTL8822B)
+ phydm_init_hw_info_by_rfe_type_8822b(dm);
+}
+
+static void odm_common_info_self_init(struct phy_dm_struct *dm)
+{
+ phydm_init_cck_setting(dm);
+ dm->rf_path_rx_enable = (u8)odm_get_bb_reg(dm, ODM_REG(BB_RX_PATH, dm),
+ ODM_BIT(BB_RX_PATH, dm));
+ odm_init_mp_driver_status(dm);
+ phydm_init_trx_antenna_setting(dm);
+ phydm_init_soft_ml_setting(dm);
+
+ dm->phydm_period = PHYDM_WATCH_DOG_PERIOD;
+ dm->phydm_sys_up_time = 0;
+
+ if (dm->support_ic_type & ODM_IC_1SS)
+ dm->num_rf_path = 1;
+ else if (dm->support_ic_type & ODM_IC_2SS)
+ dm->num_rf_path = 2;
+ else if (dm->support_ic_type & ODM_IC_3SS)
+ dm->num_rf_path = 3;
+ else if (dm->support_ic_type & ODM_IC_4SS)
+ dm->num_rf_path = 4;
+
+ dm->tx_rate = 0xFF;
+
+ dm->number_linked_client = 0;
+ dm->pre_number_linked_client = 0;
+ dm->number_active_client = 0;
+ dm->pre_number_active_client = 0;
+
+ dm->last_tx_ok_cnt = 0;
+ dm->last_rx_ok_cnt = 0;
+ dm->tx_tp = 0;
+ dm->rx_tp = 0;
+ dm->total_tp = 0;
+ dm->traffic_load = TRAFFIC_LOW;
+
+ dm->nbi_set_result = 0;
+ dm->is_init_hw_info_by_rfe = false;
+ dm->pre_dbg_priority = BB_DBGPORT_RELEASE;
+}
+
+static void odm_common_info_self_update(struct phy_dm_struct *dm)
+{
+ u8 entry_cnt = 0, num_active_client = 0;
+ u32 i, one_entry_macid = 0;
+ struct rtl_sta_info *entry;
+
+ /* THis variable cannot be used because it is wrong*/
+ if (*dm->band_width == ODM_BW40M) {
+ if (*dm->sec_ch_offset == 1)
+ dm->control_channel = *dm->channel - 2;
+ else if (*dm->sec_ch_offset == 2)
+ dm->control_channel = *dm->channel + 2;
+ } else {
+ dm->control_channel = *dm->channel;
+ }
+
+ for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
+ entry = dm->odm_sta_info[i];
+ if (IS_STA_VALID(entry)) {
+ entry_cnt++;
+ if (entry_cnt == 1)
+ one_entry_macid = i;
+ }
+ }
+
+ if (entry_cnt == 1) {
+ dm->is_one_entry_only = true;
+ dm->one_entry_macid = one_entry_macid;
+ } else {
+ dm->is_one_entry_only = false;
+ }
+
+ dm->pre_number_linked_client = dm->number_linked_client;
+ dm->pre_number_active_client = dm->number_active_client;
+
+ dm->number_linked_client = entry_cnt;
+ dm->number_active_client = num_active_client;
+
+ /* Update MP driver status*/
+ odm_update_mp_driver_status(dm);
+
+ /*Traffic load information update*/
+ phydm_traffic_load_decision(dm);
+
+ dm->phydm_sys_up_time += dm->phydm_period;
+}
+
+static void odm_common_info_self_reset(struct phy_dm_struct *dm)
+{
+ dm->phy_dbg_info.num_qry_beacon_pkt = 0;
+}
+
+void *phydm_get_structure(struct phy_dm_struct *dm, u8 structure_type)
+
+{
+ void *p_struct = NULL;
+
+ switch (structure_type) {
+ case PHYDM_FALSEALMCNT:
+ p_struct = &dm->false_alm_cnt;
+ break;
+
+ case PHYDM_CFOTRACK:
+ p_struct = &dm->dm_cfo_track;
+ break;
+
+ case PHYDM_ADAPTIVITY:
+ p_struct = &dm->adaptivity;
+ break;
+
+ default:
+ break;
+ }
+
+ return p_struct;
+}
+
+static void odm_hw_setting(struct phy_dm_struct *dm)
+{
+ if (dm->support_ic_type & ODM_RTL8822B)
+ phydm_hwsetting_8822b(dm);
+}
+
+static void phydm_supportability_init(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 support_ability = 0;
+
+ if (dm->support_ic_type != ODM_RTL8821C)
+ return;
+
+ switch (dm->support_ic_type) {
+ /*---------------AC Series-------------------*/
+
+ case ODM_RTL8822B:
+ support_ability |= ODM_BB_DIG | ODM_BB_FA_CNT | ODM_BB_CCK_PD |
+ ODM_BB_CFO_TRACKING | ODM_BB_RATE_ADAPTIVE |
+ ODM_BB_RSSI_MONITOR | ODM_BB_RA_MASK |
+ ODM_RF_TX_PWR_TRACK;
+ break;
+
+ default:
+ support_ability |= ODM_BB_DIG | ODM_BB_FA_CNT | ODM_BB_CCK_PD |
+ ODM_BB_CFO_TRACKING | ODM_BB_RATE_ADAPTIVE |
+ ODM_BB_RSSI_MONITOR | ODM_BB_RA_MASK |
+ ODM_RF_TX_PWR_TRACK;
+
+ ODM_RT_TRACE(dm, ODM_COMP_UNCOND,
+ "[Warning] Supportability Init Warning !!!\n");
+ break;
+ }
+
+ if (*dm->enable_antdiv)
+ support_ability |= ODM_BB_ANT_DIV;
+
+ if (*dm->enable_adaptivity) {
+ ODM_RT_TRACE(dm, ODM_COMP_INIT,
+ "ODM adaptivity is set to Enabled!!!\n");
+
+ support_ability |= ODM_BB_ADAPTIVITY;
+
+ } else {
+ ODM_RT_TRACE(dm, ODM_COMP_INIT,
+ "ODM adaptivity is set to disnabled!!!\n");
+ /**/
+ }
+
+ ODM_RT_TRACE(dm, ODM_COMP_INIT, "PHYDM support_ability = ((0x%x))\n",
+ support_ability);
+ odm_cmn_info_init(dm, ODM_CMNINFO_ABILITY, support_ability);
+}
+
+/*
+ * 2011/09/21 MH Add to describe different team necessary resource allocate??
+ */
+void odm_dm_init(struct phy_dm_struct *dm)
+{
+ phydm_supportability_init(dm);
+ odm_common_info_self_init(dm);
+ odm_dig_init(dm);
+ phydm_nhm_counter_statistics_init(dm);
+ phydm_adaptivity_init(dm);
+ phydm_ra_info_init(dm);
+ odm_rate_adaptive_mask_init(dm);
+ odm_cfo_tracking_init(dm);
+ odm_edca_turbo_init(dm);
+ odm_rssi_monitor_init(dm);
+ phydm_rf_init(dm);
+ odm_txpowertracking_init(dm);
+
+ if (dm->support_ic_type & ODM_RTL8822B)
+ phydm_txcurrentcalibration(dm);
+
+ odm_antenna_diversity_init(dm);
+ odm_auto_channel_select_init(dm);
+ odm_dynamic_tx_power_init(dm);
+ phydm_init_ra_info(dm);
+ adc_smp_init(dm);
+
+ phydm_beamforming_init(dm);
+
+ if (dm->support_ic_type & ODM_IC_11N_SERIES) {
+ /* 11n series */
+ odm_dynamic_bb_power_saving_init(dm);
+ }
+
+ phydm_psd_init(dm);
+}
+
+void odm_dm_reset(struct phy_dm_struct *dm)
+{
+ struct dig_thres *dig_tab = &dm->dm_dig_table;
+
+ odm_ant_div_reset(dm);
+ phydm_set_edcca_threshold_api(dm, dig_tab->cur_ig_value);
+}
+
+void phydm_support_ability_debug(void *dm_void, u32 *const dm_value, u32 *_used,
+ char *output, u32 *_out_len)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 pre_support_ability;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ pre_support_ability = dm->support_ability;
+ PHYDM_SNPRINTF(output + used, out_len - used, "\n%s\n",
+ "================================");
+ if (dm_value[0] == 100) {
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "[Supportability] PhyDM Selection\n");
+ PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
+ "================================");
+ PHYDM_SNPRINTF(
+ output + used, out_len - used, "00. (( %s ))DIG\n",
+ ((dm->support_ability & ODM_BB_DIG) ? ("V") : (".")));
+ PHYDM_SNPRINTF(
+ output + used, out_len - used, "01. (( %s ))RA_MASK\n",
+ ((dm->support_ability & ODM_BB_RA_MASK) ? ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "02. (( %s ))DYNAMIC_TXPWR\n",
+ ((dm->support_ability & ODM_BB_DYNAMIC_TXPWR) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "03. (( %s ))FA_CNT\n",
+ ((dm->support_ability & ODM_BB_FA_CNT) ? ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "04. (( %s ))RSSI_MONITOR\n",
+ ((dm->support_ability & ODM_BB_RSSI_MONITOR) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "05. (( %s ))CCK_PD\n",
+ ((dm->support_ability & ODM_BB_CCK_PD) ? ("V") :
+ (".")));
+ PHYDM_SNPRINTF(
+ output + used, out_len - used, "06. (( %s ))ANT_DIV\n",
+ ((dm->support_ability & ODM_BB_ANT_DIV) ? ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "08. (( %s ))PWR_TRAIN\n",
+ ((dm->support_ability & ODM_BB_PWR_TRAIN) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "09. (( %s ))RATE_ADAPTIVE\n",
+ ((dm->support_ability & ODM_BB_RATE_ADAPTIVE) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(
+ output + used, out_len - used, "10. (( %s ))PATH_DIV\n",
+ ((dm->support_ability & ODM_BB_PATH_DIV) ? ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "13. (( %s ))ADAPTIVITY\n",
+ ((dm->support_ability & ODM_BB_ADAPTIVITY) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "14. (( %s ))struct cfo_tracking\n",
+ ((dm->support_ability & ODM_BB_CFO_TRACKING) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(
+ output + used, out_len - used, "15. (( %s ))NHM_CNT\n",
+ ((dm->support_ability & ODM_BB_NHM_CNT) ? ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "16. (( %s ))PRIMARY_CCA\n",
+ ((dm->support_ability & ODM_BB_PRIMARY_CCA) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(
+ output + used, out_len - used, "17. (( %s ))TXBF\n",
+ ((dm->support_ability & ODM_BB_TXBF) ? ("V") : (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "18. (( %s ))DYNAMIC_ARFR\n",
+ ((dm->support_ability & ODM_BB_DYNAMIC_ARFR) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "20. (( %s ))EDCA_TURBO\n",
+ ((dm->support_ability & ODM_MAC_EDCA_TURBO) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "21. (( %s ))DYNAMIC_RX_PATH\n",
+ ((dm->support_ability & ODM_BB_DYNAMIC_RX_PATH) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "24. (( %s ))TX_PWR_TRACK\n",
+ ((dm->support_ability & ODM_RF_TX_PWR_TRACK) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "25. (( %s ))RX_GAIN_TRACK\n",
+ ((dm->support_ability & ODM_RF_RX_GAIN_TRACK) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "26. (( %s ))RF_CALIBRATION\n",
+ ((dm->support_ability & ODM_RF_CALIBRATION) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
+ "================================");
+ } else {
+ if (dm_value[1] == 1) { /* enable */
+ dm->support_ability |= BIT(dm_value[0]);
+ } else if (dm_value[1] == 2) /* disable */
+ dm->support_ability &= ~(BIT(dm_value[0]));
+ else {
+ PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
+ "[Warning!!!] 1:enable, 2:disable");
+ }
+ }
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "pre-support_ability = 0x%x\n", pre_support_ability);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "Curr-support_ability = 0x%x\n", dm->support_ability);
+ PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
+ "================================");
+}
+
+void phydm_watchdog_mp(struct phy_dm_struct *dm) {}
+/*
+ * 2011/09/20 MH This is the entry pointer for all team to execute HW outsrc DM.
+ * You can not add any dummy function here, be care, you can only use DM struct
+ * to perform any new ODM_DM.
+ */
+void odm_dm_watchdog(struct phy_dm_struct *dm)
+{
+ odm_common_info_self_update(dm);
+ phydm_basic_dbg_message(dm);
+ odm_hw_setting(dm);
+
+ odm_false_alarm_counter_statistics(dm);
+ phydm_noisy_detection(dm);
+
+ odm_rssi_monitor_check(dm);
+
+ if (*dm->is_power_saving) {
+ odm_dig_by_rssi_lps(dm);
+ phydm_adaptivity(dm);
+ odm_antenna_diversity(
+ dm); /*enable AntDiv in PS mode, request from SD4 Jeff*/
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON,
+ "DMWatchdog in power saving mode\n");
+ return;
+ }
+
+ phydm_check_adaptivity(dm);
+ odm_update_power_training_state(dm);
+ odm_DIG(dm);
+ phydm_adaptivity(dm);
+ odm_cck_packet_detection_thresh(dm);
+
+ phydm_ra_info_watchdog(dm);
+ odm_edca_turbo_check(dm);
+ odm_cfo_tracking(dm);
+ odm_dynamic_tx_power(dm);
+ odm_antenna_diversity(dm);
+
+ phydm_beamforming_watchdog(dm);
+
+ phydm_rf_watchdog(dm);
+
+ odm_dtc(dm);
+
+ odm_common_info_self_reset(dm);
+}
+
+/*
+ * Init /.. Fixed HW value. Only init time.
+ */
+void odm_cmn_info_init(struct phy_dm_struct *dm, enum odm_cmninfo cmn_info,
+ u32 value)
+{
+ /* This section is used for init value */
+ switch (cmn_info) {
+ /* Fixed ODM value. */
+ case ODM_CMNINFO_ABILITY:
+ dm->support_ability = (u32)value;
+ break;
+
+ case ODM_CMNINFO_RF_TYPE:
+ dm->rf_type = (u8)value;
+ break;
+
+ case ODM_CMNINFO_PLATFORM:
+ dm->support_platform = (u8)value;
+ break;
+
+ case ODM_CMNINFO_INTERFACE:
+ dm->support_interface = (u8)value;
+ break;
+
+ case ODM_CMNINFO_MP_TEST_CHIP:
+ dm->is_mp_chip = (u8)value;
+ break;
+
+ case ODM_CMNINFO_IC_TYPE:
+ dm->support_ic_type = value;
+ break;
+
+ case ODM_CMNINFO_CUT_VER:
+ dm->cut_version = (u8)value;
+ break;
+
+ case ODM_CMNINFO_FAB_VER:
+ dm->fab_version = (u8)value;
+ break;
+
+ case ODM_CMNINFO_RFE_TYPE:
+ dm->rfe_type = (u8)value;
+ phydm_init_hw_info_by_rfe(dm);
+ break;
+
+ case ODM_CMNINFO_RF_ANTENNA_TYPE:
+ dm->ant_div_type = (u8)value;
+ break;
+
+ case ODM_CMNINFO_WITH_EXT_ANTENNA_SWITCH:
+ dm->with_extenal_ant_switch = (u8)value;
+ break;
+
+ case ODM_CMNINFO_BE_FIX_TX_ANT:
+ dm->dm_fat_table.b_fix_tx_ant = (u8)value;
+ break;
+
+ case ODM_CMNINFO_BOARD_TYPE:
+ if (!dm->is_init_hw_info_by_rfe)
+ dm->board_type = (u8)value;
+ break;
+
+ case ODM_CMNINFO_PACKAGE_TYPE:
+ if (!dm->is_init_hw_info_by_rfe)
+ dm->package_type = (u8)value;
+ break;
+
+ case ODM_CMNINFO_EXT_LNA:
+ if (!dm->is_init_hw_info_by_rfe)
+ dm->ext_lna = (u8)value;
+ break;
+
+ case ODM_CMNINFO_5G_EXT_LNA:
+ if (!dm->is_init_hw_info_by_rfe)
+ dm->ext_lna_5g = (u8)value;
+ break;
+
+ case ODM_CMNINFO_EXT_PA:
+ if (!dm->is_init_hw_info_by_rfe)
+ dm->ext_pa = (u8)value;
+ break;
+
+ case ODM_CMNINFO_5G_EXT_PA:
+ if (!dm->is_init_hw_info_by_rfe)
+ dm->ext_pa_5g = (u8)value;
+ break;
+
+ case ODM_CMNINFO_GPA:
+ if (!dm->is_init_hw_info_by_rfe)
+ dm->type_gpa = (u16)value;
+ break;
+
+ case ODM_CMNINFO_APA:
+ if (!dm->is_init_hw_info_by_rfe)
+ dm->type_apa = (u16)value;
+ break;
+
+ case ODM_CMNINFO_GLNA:
+ if (!dm->is_init_hw_info_by_rfe)
+ dm->type_glna = (u16)value;
+ break;
+
+ case ODM_CMNINFO_ALNA:
+ if (!dm->is_init_hw_info_by_rfe)
+ dm->type_alna = (u16)value;
+ break;
+
+ case ODM_CMNINFO_EXT_TRSW:
+ if (!dm->is_init_hw_info_by_rfe)
+ dm->ext_trsw = (u8)value;
+ break;
+ case ODM_CMNINFO_EXT_LNA_GAIN:
+ dm->ext_lna_gain = (u8)value;
+ break;
+ case ODM_CMNINFO_PATCH_ID:
+ dm->patch_id = (u8)value;
+ break;
+ case ODM_CMNINFO_BINHCT_TEST:
+ dm->is_in_hct_test = (bool)value;
+ break;
+ case ODM_CMNINFO_BWIFI_TEST:
+ dm->wifi_test = (u8)value;
+ break;
+ case ODM_CMNINFO_SMART_CONCURRENT:
+ dm->is_dual_mac_smart_concurrent = (bool)value;
+ break;
+ case ODM_CMNINFO_DOMAIN_CODE_2G:
+ dm->odm_regulation_2_4g = (u8)value;
+ break;
+ case ODM_CMNINFO_DOMAIN_CODE_5G:
+ dm->odm_regulation_5g = (u8)value;
+ break;
+ case ODM_CMNINFO_CONFIG_BB_RF:
+ dm->config_bbrf = (bool)value;
+ break;
+ case ODM_CMNINFO_IQKFWOFFLOAD:
+ dm->iqk_fw_offload = (u8)value;
+ break;
+ case ODM_CMNINFO_IQKPAOFF:
+ dm->rf_calibrate_info.is_iqk_pa_off = (bool)value;
+ break;
+ case ODM_CMNINFO_REGRFKFREEENABLE:
+ dm->rf_calibrate_info.reg_rf_kfree_enable = (u8)value;
+ break;
+ case ODM_CMNINFO_RFKFREEENABLE:
+ dm->rf_calibrate_info.rf_kfree_enable = (u8)value;
+ break;
+ case ODM_CMNINFO_NORMAL_RX_PATH_CHANGE:
+ dm->normal_rx_path = (u8)value;
+ break;
+ case ODM_CMNINFO_EFUSE0X3D8:
+ dm->efuse0x3d8 = (u8)value;
+ break;
+ case ODM_CMNINFO_EFUSE0X3D7:
+ dm->efuse0x3d7 = (u8)value;
+ break;
+ /* To remove the compiler warning, must add an empty default statement
+ * to handle the other values.
+ */
+ default:
+ /* do nothing */
+ break;
+ }
+}
+
+void odm_cmn_info_hook(struct phy_dm_struct *dm, enum odm_cmninfo cmn_info,
+ void *value)
+{
+ /* */
+ /* Hook call by reference pointer. */
+ /* */
+ switch (cmn_info) {
+ /* */
+ /* Dynamic call by reference pointer. */
+ /* */
+ case ODM_CMNINFO_MAC_PHY_MODE:
+ dm->mac_phy_mode = (u8 *)value;
+ break;
+
+ case ODM_CMNINFO_TX_UNI:
+ dm->num_tx_bytes_unicast = (u64 *)value;
+ break;
+
+ case ODM_CMNINFO_RX_UNI:
+ dm->num_rx_bytes_unicast = (u64 *)value;
+ break;
+
+ case ODM_CMNINFO_WM_MODE:
+ dm->wireless_mode = (u8 *)value;
+ break;
+
+ case ODM_CMNINFO_BAND:
+ dm->band_type = (u8 *)value;
+ break;
+
+ case ODM_CMNINFO_SEC_CHNL_OFFSET:
+ dm->sec_ch_offset = (u8 *)value;
+ break;
+
+ case ODM_CMNINFO_SEC_MODE:
+ dm->security = (u8 *)value;
+ break;
+
+ case ODM_CMNINFO_BW:
+ dm->band_width = (u8 *)value;
+ break;
+
+ case ODM_CMNINFO_CHNL:
+ dm->channel = (u8 *)value;
+ break;
+
+ case ODM_CMNINFO_DMSP_GET_VALUE:
+ dm->is_get_value_from_other_mac = (bool *)value;
+ break;
+
+ case ODM_CMNINFO_BUDDY_ADAPTOR:
+ dm->buddy_adapter = (void **)value;
+ break;
+
+ case ODM_CMNINFO_DMSP_IS_MASTER:
+ dm->is_master_of_dmsp = (bool *)value;
+ break;
+
+ case ODM_CMNINFO_SCAN:
+ dm->is_scan_in_process = (bool *)value;
+ break;
+
+ case ODM_CMNINFO_POWER_SAVING:
+ dm->is_power_saving = (bool *)value;
+ break;
+
+ case ODM_CMNINFO_ONE_PATH_CCA:
+ dm->one_path_cca = (u8 *)value;
+ break;
+
+ case ODM_CMNINFO_DRV_STOP:
+ dm->is_driver_stopped = (bool *)value;
+ break;
+
+ case ODM_CMNINFO_PNP_IN:
+ dm->is_driver_is_going_to_pnp_set_power_sleep = (bool *)value;
+ break;
+
+ case ODM_CMNINFO_INIT_ON:
+ dm->pinit_adpt_in_progress = (bool *)value;
+ break;
+
+ case ODM_CMNINFO_ANT_TEST:
+ dm->antenna_test = (u8 *)value;
+ break;
+
+ case ODM_CMNINFO_NET_CLOSED:
+ dm->is_net_closed = (bool *)value;
+ break;
+
+ case ODM_CMNINFO_FORCED_RATE:
+ dm->forced_data_rate = (u16 *)value;
+ break;
+ case ODM_CMNINFO_ANT_DIV:
+ dm->enable_antdiv = (u8 *)value;
+ break;
+ case ODM_CMNINFO_ADAPTIVITY:
+ dm->enable_adaptivity = (u8 *)value;
+ break;
+ case ODM_CMNINFO_FORCED_IGI_LB:
+ dm->pu1_forced_igi_lb = (u8 *)value;
+ break;
+
+ case ODM_CMNINFO_P2P_LINK:
+ dm->dm_dig_table.is_p2p_in_process = (u8 *)value;
+ break;
+
+ case ODM_CMNINFO_IS1ANTENNA:
+ dm->is_1_antenna = (bool *)value;
+ break;
+
+ case ODM_CMNINFO_RFDEFAULTPATH:
+ dm->rf_default_path = (u8 *)value;
+ break;
+
+ case ODM_CMNINFO_FCS_MODE:
+ dm->is_fcs_mode_enable = (bool *)value;
+ break;
+ /*add by YuChen for beamforming PhyDM*/
+ case ODM_CMNINFO_HUBUSBMODE:
+ dm->hub_usb_mode = (u8 *)value;
+ break;
+ case ODM_CMNINFO_FWDWRSVDPAGEINPROGRESS:
+ dm->is_fw_dw_rsvd_page_in_progress = (bool *)value;
+ break;
+ case ODM_CMNINFO_TX_TP:
+ dm->current_tx_tp = (u32 *)value;
+ break;
+ case ODM_CMNINFO_RX_TP:
+ dm->current_rx_tp = (u32 *)value;
+ break;
+ case ODM_CMNINFO_SOUNDING_SEQ:
+ dm->sounding_seq = (u8 *)value;
+ break;
+ case ODM_CMNINFO_FORCE_TX_ANT_BY_TXDESC:
+ dm->dm_fat_table.p_force_tx_ant_by_desc = (u8 *)value;
+ break;
+ case ODM_CMNINFO_SET_S0S1_DEFAULT_ANTENNA:
+ dm->dm_fat_table.p_default_s0_s1 = (u8 *)value;
+ break;
+
+ default:
+ /*do nothing*/
+ break;
+ }
+}
+
+void odm_cmn_info_ptr_array_hook(struct phy_dm_struct *dm,
+ enum odm_cmninfo cmn_info, u16 index,
+ void *value)
+{
+ /*Hook call by reference pointer.*/
+ switch (cmn_info) {
+ /*Dynamic call by reference pointer. */
+ case ODM_CMNINFO_STA_STATUS:
+ dm->odm_sta_info[index] = (struct rtl_sta_info *)value;
+
+ if (IS_STA_VALID(dm->odm_sta_info[index]))
+ dm->platform2phydm_macid_table[index] = index;
+
+ break;
+ /* To remove the compiler warning, must add an empty default statement
+ * to handle the other values.
+ */
+ default:
+ /* do nothing */
+ break;
+ }
+}
+
+/*
+ * Update band/CHannel/.. The values are dynamic but non-per-packet.
+ */
+void odm_cmn_info_update(struct phy_dm_struct *dm, u32 cmn_info, u64 value)
+{
+ /* This init variable may be changed in run time. */
+ switch (cmn_info) {
+ case ODM_CMNINFO_LINK_IN_PROGRESS:
+ dm->is_link_in_process = (bool)value;
+ break;
+
+ case ODM_CMNINFO_ABILITY:
+ dm->support_ability = (u32)value;
+ break;
+
+ case ODM_CMNINFO_RF_TYPE:
+ dm->rf_type = (u8)value;
+ break;
+
+ case ODM_CMNINFO_WIFI_DIRECT:
+ dm->is_wifi_direct = (bool)value;
+ break;
+
+ case ODM_CMNINFO_WIFI_DISPLAY:
+ dm->is_wifi_display = (bool)value;
+ break;
+
+ case ODM_CMNINFO_LINK:
+ dm->is_linked = (bool)value;
+ break;
+
+ case ODM_CMNINFO_CMW500LINK:
+ dm->is_linkedcmw500 = (bool)value;
+ break;
+
+ case ODM_CMNINFO_LPSPG:
+ dm->is_in_lps_pg = (bool)value;
+ break;
+
+ case ODM_CMNINFO_STATION_STATE:
+ dm->bsta_state = (bool)value;
+ break;
+
+ case ODM_CMNINFO_RSSI_MIN:
+ dm->rssi_min = (u8)value;
+ break;
+
+ case ODM_CMNINFO_DBG_COMP:
+ dm->debug_components = (u32)value;
+ break;
+
+ case ODM_CMNINFO_DBG_LEVEL:
+ dm->debug_level = (u32)value;
+ break;
+ case ODM_CMNINFO_RA_THRESHOLD_HIGH:
+ dm->rate_adaptive.high_rssi_thresh = (u8)value;
+ break;
+
+ case ODM_CMNINFO_RA_THRESHOLD_LOW:
+ dm->rate_adaptive.low_rssi_thresh = (u8)value;
+ break;
+ /* The following is for BT HS mode and BT coexist mechanism. */
+ case ODM_CMNINFO_BT_ENABLED:
+ dm->is_bt_enabled = (bool)value;
+ break;
+
+ case ODM_CMNINFO_BT_HS_CONNECT_PROCESS:
+ dm->is_bt_connect_process = (bool)value;
+ break;
+
+ case ODM_CMNINFO_BT_HS_RSSI:
+ dm->bt_hs_rssi = (u8)value;
+ break;
+
+ case ODM_CMNINFO_BT_OPERATION:
+ dm->is_bt_hs_operation = (bool)value;
+ break;
+
+ case ODM_CMNINFO_BT_LIMITED_DIG:
+ dm->is_bt_limited_dig = (bool)value;
+ break;
+
+ case ODM_CMNINFO_BT_DIG:
+ dm->bt_hs_dig_val = (u8)value;
+ break;
+
+ case ODM_CMNINFO_BT_BUSY:
+ dm->is_bt_busy = (bool)value;
+ break;
+
+ case ODM_CMNINFO_BT_DISABLE_EDCA:
+ dm->is_bt_disable_edca_turbo = (bool)value;
+ break;
+
+ case ODM_CMNINFO_AP_TOTAL_NUM:
+ dm->ap_total_num = (u8)value;
+ break;
+
+ case ODM_CMNINFO_POWER_TRAINING:
+ dm->is_disable_power_training = (bool)value;
+ break;
+
+ default:
+ /* do nothing */
+ break;
+ }
+}
+
+u32 phydm_cmn_info_query(struct phy_dm_struct *dm,
+ enum phydm_info_query info_type)
+{
+ struct false_alarm_stat *false_alm_cnt =
+ (struct false_alarm_stat *)phydm_get_structure(
+ dm, PHYDM_FALSEALMCNT);
+
+ switch (info_type) {
+ case PHYDM_INFO_FA_OFDM:
+ return false_alm_cnt->cnt_ofdm_fail;
+
+ case PHYDM_INFO_FA_CCK:
+ return false_alm_cnt->cnt_cck_fail;
+
+ case PHYDM_INFO_FA_TOTAL:
+ return false_alm_cnt->cnt_all;
+
+ case PHYDM_INFO_CCA_OFDM:
+ return false_alm_cnt->cnt_ofdm_cca;
+
+ case PHYDM_INFO_CCA_CCK:
+ return false_alm_cnt->cnt_cck_cca;
+
+ case PHYDM_INFO_CCA_ALL:
+ return false_alm_cnt->cnt_cca_all;
+
+ case PHYDM_INFO_CRC32_OK_VHT:
+ return false_alm_cnt->cnt_vht_crc32_ok;
+
+ case PHYDM_INFO_CRC32_OK_HT:
+ return false_alm_cnt->cnt_ht_crc32_ok;
+
+ case PHYDM_INFO_CRC32_OK_LEGACY:
+ return false_alm_cnt->cnt_ofdm_crc32_ok;
+
+ case PHYDM_INFO_CRC32_OK_CCK:
+ return false_alm_cnt->cnt_cck_crc32_ok;
+
+ case PHYDM_INFO_CRC32_ERROR_VHT:
+ return false_alm_cnt->cnt_vht_crc32_error;
+
+ case PHYDM_INFO_CRC32_ERROR_HT:
+ return false_alm_cnt->cnt_ht_crc32_error;
+
+ case PHYDM_INFO_CRC32_ERROR_LEGACY:
+ return false_alm_cnt->cnt_ofdm_crc32_error;
+
+ case PHYDM_INFO_CRC32_ERROR_CCK:
+ return false_alm_cnt->cnt_cck_crc32_error;
+
+ case PHYDM_INFO_EDCCA_FLAG:
+ return false_alm_cnt->edcca_flag;
+
+ case PHYDM_INFO_OFDM_ENABLE:
+ return false_alm_cnt->ofdm_block_enable;
+
+ case PHYDM_INFO_CCK_ENABLE:
+ return false_alm_cnt->cck_block_enable;
+
+ case PHYDM_INFO_DBG_PORT_0:
+ return false_alm_cnt->dbg_port0;
+
+ default:
+ return 0xffffffff;
+ }
+}
+
+void odm_init_all_timers(struct phy_dm_struct *dm) {}
+
+void odm_cancel_all_timers(struct phy_dm_struct *dm) {}
+
+void odm_release_all_timers(struct phy_dm_struct *dm) {}
+
+/* 3============================================================
+ * 3 Tx Power Tracking
+ * 3============================================================
+ */
+
+/* need to ODM CE Platform
+ * move to here for ANT detection mechanism using
+ */
+
+u32 odm_convert_to_db(u32 value)
+{
+ u8 i;
+ u8 j;
+ u32 dB;
+
+ value = value & 0xFFFF;
+
+ for (i = 0; i < 12; i++) {
+ if (value <= db_invert_table[i][7])
+ break;
+ }
+
+ if (i >= 12)
+ return 96; /* maximum 96 dB */
+
+ for (j = 0; j < 8; j++) {
+ if (value <= db_invert_table[i][j])
+ break;
+ }
+
+ dB = (i << 3) + j + 1;
+
+ return dB;
+}
+
+u32 odm_convert_to_linear(u32 value)
+{
+ u8 i;
+ u8 j;
+ u32 linear;
+
+ /* 1dB~96dB */
+
+ value = value & 0xFF;
+
+ i = (u8)((value - 1) >> 3);
+ j = (u8)(value - 1) - (i << 3);
+
+ linear = db_invert_table[i][j];
+
+ return linear;
+}
+
+/*
+ * ODM multi-port consideration, added by Roger, 2013.10.01.
+ */
+void odm_asoc_entry_init(struct phy_dm_struct *dm) {}
+
+/* Justin: According to the current RRSI to adjust Response Frame TX power */
+void odm_dtc(struct phy_dm_struct *dm) {}
+
+static void odm_update_power_training_state(struct phy_dm_struct *dm)
+{
+ struct false_alarm_stat *false_alm_cnt =
+ (struct false_alarm_stat *)phydm_get_structure(
+ dm, PHYDM_FALSEALMCNT);
+ struct dig_thres *dig_tab = &dm->dm_dig_table;
+ u32 score = 0;
+
+ if (!(dm->support_ability & ODM_BB_PWR_TRAIN))
+ return;
+
+ ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, "%s()============>\n", __func__);
+ dm->is_change_state = false;
+
+ /* Debug command */
+ if (dm->force_power_training_state) {
+ if (dm->force_power_training_state == 1 &&
+ !dm->is_disable_power_training) {
+ dm->is_change_state = true;
+ dm->is_disable_power_training = true;
+ } else if (dm->force_power_training_state == 2 &&
+ dm->is_disable_power_training) {
+ dm->is_change_state = true;
+ dm->is_disable_power_training = false;
+ }
+
+ dm->PT_score = 0;
+ dm->phy_dbg_info.num_qry_phy_status_ofdm = 0;
+ dm->phy_dbg_info.num_qry_phy_status_cck = 0;
+ ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
+ "%s(): force_power_training_state = %d\n",
+ __func__, dm->force_power_training_state);
+ return;
+ }
+
+ if (!dm->is_linked)
+ return;
+
+ /* First connect */
+ if ((dm->is_linked) && !dig_tab->is_media_connect_0) {
+ dm->PT_score = 0;
+ dm->is_change_state = true;
+ dm->phy_dbg_info.num_qry_phy_status_ofdm = 0;
+ dm->phy_dbg_info.num_qry_phy_status_cck = 0;
+ ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, "%s(): First Connect\n",
+ __func__);
+ return;
+ }
+
+ /* Compute score */
+ if (dm->nhm_cnt_0 >= 215) {
+ score = 2;
+ } else if (dm->nhm_cnt_0 >= 190) {
+ score = 1; /* unknown state */
+ } else {
+ u32 rx_pkt_cnt;
+
+ rx_pkt_cnt = (u32)(dm->phy_dbg_info.num_qry_phy_status_ofdm) +
+ (u32)(dm->phy_dbg_info.num_qry_phy_status_cck);
+
+ if ((false_alm_cnt->cnt_cca_all > 31 && rx_pkt_cnt > 31) &&
+ (false_alm_cnt->cnt_cca_all >= rx_pkt_cnt)) {
+ if ((rx_pkt_cnt + (rx_pkt_cnt >> 1)) <=
+ false_alm_cnt->cnt_cca_all)
+ score = 0;
+ else if ((rx_pkt_cnt + (rx_pkt_cnt >> 2)) <=
+ false_alm_cnt->cnt_cca_all)
+ score = 1;
+ else
+ score = 2;
+ }
+ ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
+ "%s(): rx_pkt_cnt = %d, cnt_cca_all = %d\n",
+ __func__, rx_pkt_cnt, false_alm_cnt->cnt_cca_all);
+ }
+ ODM_RT_TRACE(
+ dm, ODM_COMP_RA_MASK,
+ "%s(): num_qry_phy_status_ofdm = %d, num_qry_phy_status_cck = %d\n",
+ __func__, (u32)(dm->phy_dbg_info.num_qry_phy_status_ofdm),
+ (u32)(dm->phy_dbg_info.num_qry_phy_status_cck));
+ ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, "%s(): nhm_cnt_0 = %d, score = %d\n",
+ __func__, dm->nhm_cnt_0, score);
+
+ /* smoothing */
+ dm->PT_score = (score << 4) + (dm->PT_score >> 1) + (dm->PT_score >> 2);
+ score = (dm->PT_score + 32) >> 6;
+ ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
+ "%s(): PT_score = %d, score after smoothing = %d\n",
+ __func__, dm->PT_score, score);
+
+ /* mode decision */
+ if (score == 2) {
+ if (dm->is_disable_power_training) {
+ dm->is_change_state = true;
+ dm->is_disable_power_training = false;
+ ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
+ "%s(): Change state\n", __func__);
+ }
+ ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
+ "%s(): Enable Power Training\n", __func__);
+ } else if (score == 0) {
+ if (!dm->is_disable_power_training) {
+ dm->is_change_state = true;
+ dm->is_disable_power_training = true;
+ ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
+ "%s(): Change state\n", __func__);
+ }
+ ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
+ "%s(): Disable Power Training\n", __func__);
+ }
+
+ dm->phy_dbg_info.num_qry_phy_status_ofdm = 0;
+ dm->phy_dbg_info.num_qry_phy_status_cck = 0;
+}
+
+/*===========================================================*/
+/* The following is for compile only*/
+/*===========================================================*/
+/*#define TARGET_CHNL_NUM_2G_5G 59*/
+/*===========================================================*/
+
+void phydm_noisy_detection(struct phy_dm_struct *dm)
+{
+ u32 total_fa_cnt, total_cca_cnt;
+ u32 score = 0, i, score_smooth;
+
+ total_cca_cnt = dm->false_alm_cnt.cnt_cca_all;
+ total_fa_cnt = dm->false_alm_cnt.cnt_all;
+
+ for (i = 0; i <= 16; i++) {
+ if (total_fa_cnt * 16 >= total_cca_cnt * (16 - i)) {
+ score = 16 - i;
+ break;
+ }
+ }
+
+ /* noisy_decision_smooth = noisy_decision_smooth>>1 + (score<<3)>>1; */
+ dm->noisy_decision_smooth =
+ (dm->noisy_decision_smooth >> 1) + (score << 2);
+
+ /* Round the noisy_decision_smooth: +"3" comes from (2^3)/2-1 */
+ score_smooth = (total_cca_cnt >= 300) ?
+ ((dm->noisy_decision_smooth + 3) >> 3) :
+ 0;
+
+ dm->noisy_decision = (score_smooth >= 3) ? 1 : 0;
+ ODM_RT_TRACE(
+ dm, ODM_COMP_NOISY_DETECT,
+ "[NoisyDetection] total_cca_cnt=%d, total_fa_cnt=%d, noisy_decision_smooth=%d, score=%d, score_smooth=%d, dm->noisy_decision=%d\n",
+ total_cca_cnt, total_fa_cnt, dm->noisy_decision_smooth, score,
+ score_smooth, dm->noisy_decision);
+}
+
+void phydm_set_ext_switch(void *dm_void, u32 *const dm_value, u32 *_used,
+ char *output, u32 *_out_len)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 ext_ant_switch = dm_value[0];
+
+ if (dm->support_ic_type & (ODM_RTL8821 | ODM_RTL8881A)) {
+ /*Output Pin Settings*/
+ odm_set_mac_reg(dm, 0x4C, BIT(23),
+ 0); /*select DPDT_P and DPDT_N as output pin*/
+ odm_set_mac_reg(dm, 0x4C, BIT(24), 1); /*by WLAN control*/
+
+ odm_set_bb_reg(dm, 0xCB4, 0xF, 7); /*DPDT_P = 1b'0*/
+ odm_set_bb_reg(dm, 0xCB4, 0xF0, 7); /*DPDT_N = 1b'0*/
+
+ if (ext_ant_switch == MAIN_ANT) {
+ odm_set_bb_reg(dm, 0xCB4, (BIT(29) | BIT(28)), 1);
+ ODM_RT_TRACE(
+ dm, ODM_COMP_API,
+ "***8821A set ant switch = 2b'01 (Main)\n");
+ } else if (ext_ant_switch == AUX_ANT) {
+ odm_set_bb_reg(dm, 0xCB4, BIT(29) | BIT(28), 2);
+ ODM_RT_TRACE(dm, ODM_COMP_API,
+ "***8821A set ant switch = 2b'10 (Aux)\n");
+ }
+ }
+}
+
+static void phydm_csi_mask_enable(void *dm_void, u32 enable)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 reg_value = 0;
+
+ reg_value = (enable == CSI_MASK_ENABLE) ? 1 : 0;
+
+ if (dm->support_ic_type & ODM_IC_11N_SERIES) {
+ odm_set_bb_reg(dm, 0xD2C, BIT(28), reg_value);
+ ODM_RT_TRACE(dm, ODM_COMP_API,
+ "Enable CSI Mask: Reg 0xD2C[28] = ((0x%x))\n",
+ reg_value);
+
+ } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ odm_set_bb_reg(dm, 0x874, BIT(0), reg_value);
+ ODM_RT_TRACE(dm, ODM_COMP_API,
+ "Enable CSI Mask: Reg 0x874[0] = ((0x%x))\n",
+ reg_value);
+ }
+}
+
+static void phydm_clean_all_csi_mask(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ if (dm->support_ic_type & ODM_IC_11N_SERIES) {
+ odm_set_bb_reg(dm, 0xD40, MASKDWORD, 0);
+ odm_set_bb_reg(dm, 0xD44, MASKDWORD, 0);
+ odm_set_bb_reg(dm, 0xD48, MASKDWORD, 0);
+ odm_set_bb_reg(dm, 0xD4c, MASKDWORD, 0);
+
+ } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ odm_set_bb_reg(dm, 0x880, MASKDWORD, 0);
+ odm_set_bb_reg(dm, 0x884, MASKDWORD, 0);
+ odm_set_bb_reg(dm, 0x888, MASKDWORD, 0);
+ odm_set_bb_reg(dm, 0x88c, MASKDWORD, 0);
+ odm_set_bb_reg(dm, 0x890, MASKDWORD, 0);
+ odm_set_bb_reg(dm, 0x894, MASKDWORD, 0);
+ odm_set_bb_reg(dm, 0x898, MASKDWORD, 0);
+ odm_set_bb_reg(dm, 0x89c, MASKDWORD, 0);
+ }
+}
+
+static void phydm_set_csi_mask_reg(void *dm_void, u32 tone_idx_tmp,
+ u8 tone_direction)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u8 byte_offset, bit_offset;
+ u32 target_reg;
+ u8 reg_tmp_value;
+ u32 tone_num = 64;
+ u32 tone_num_shift = 0;
+ u32 csi_mask_reg_p = 0, csi_mask_reg_n = 0;
+
+ /* calculate real tone idx*/
+ if ((tone_idx_tmp % 10) >= 5)
+ tone_idx_tmp += 10;
+
+ tone_idx_tmp = (tone_idx_tmp / 10);
+
+ if (dm->support_ic_type & ODM_IC_11N_SERIES) {
+ tone_num = 64;
+ csi_mask_reg_p = 0xD40;
+ csi_mask_reg_n = 0xD48;
+
+ } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ tone_num = 128;
+ csi_mask_reg_p = 0x880;
+ csi_mask_reg_n = 0x890;
+ }
+
+ if (tone_direction == FREQ_POSITIVE) {
+ if (tone_idx_tmp >= (tone_num - 1))
+ tone_idx_tmp = (tone_num - 1);
+
+ byte_offset = (u8)(tone_idx_tmp >> 3);
+ bit_offset = (u8)(tone_idx_tmp & 0x7);
+ target_reg = csi_mask_reg_p + byte_offset;
+
+ } else {
+ tone_num_shift = tone_num;
+
+ if (tone_idx_tmp >= tone_num)
+ tone_idx_tmp = tone_num;
+
+ tone_idx_tmp = tone_num - tone_idx_tmp;
+
+ byte_offset = (u8)(tone_idx_tmp >> 3);
+ bit_offset = (u8)(tone_idx_tmp & 0x7);
+ target_reg = csi_mask_reg_n + byte_offset;
+ }
+
+ reg_tmp_value = odm_read_1byte(dm, target_reg);
+ ODM_RT_TRACE(dm, ODM_COMP_API,
+ "Pre Mask tone idx[%d]: Reg0x%x = ((0x%x))\n",
+ (tone_idx_tmp + tone_num_shift), target_reg,
+ reg_tmp_value);
+ reg_tmp_value |= BIT(bit_offset);
+ odm_write_1byte(dm, target_reg, reg_tmp_value);
+ ODM_RT_TRACE(dm, ODM_COMP_API,
+ "New Mask tone idx[%d]: Reg0x%x = ((0x%x))\n",
+ (tone_idx_tmp + tone_num_shift), target_reg,
+ reg_tmp_value);
+}
+
+static void phydm_set_nbi_reg(void *dm_void, u32 tone_idx_tmp, u32 bw)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 nbi_table_128[NBI_TABLE_SIZE_128] = {
+ 25, 55, 85, 115, 135, 155, 185, 205, 225, 245,
+ /*1~10*/ /*tone_idx X 10*/
+ 265, 285, 305, 335, 355, 375, 395, 415, 435, 455, /*11~20*/
+ 485, 505, 525, 555, 585, 615, 635}; /*21~27*/
+
+ u32 nbi_table_256[NBI_TABLE_SIZE_256] = {
+ 25, 55, 85, 115, 135, 155, 175, 195, 225,
+ 245, /*1~10*/
+ 265, 285, 305, 325, 345, 365, 385, 405, 425,
+ 445, /*11~20*/
+ 465, 485, 505, 525, 545, 565, 585, 605, 625,
+ 645, /*21~30*/
+ 665, 695, 715, 735, 755, 775, 795, 815, 835,
+ 855, /*31~40*/
+ 875, 895, 915, 935, 955, 975, 995, 1015, 1035,
+ 1055, /*41~50*/
+ 1085, 1105, 1125, 1145, 1175, 1195, 1225, 1255, 1275}; /*51~59*/
+
+ u32 reg_idx = 0;
+ u32 i;
+ u8 nbi_table_idx = FFT_128_TYPE;
+
+ if (dm->support_ic_type & ODM_IC_11N_SERIES) {
+ nbi_table_idx = FFT_128_TYPE;
+ } else if (dm->support_ic_type & ODM_IC_11AC_1_SERIES) {
+ nbi_table_idx = FFT_256_TYPE;
+ } else if (dm->support_ic_type & ODM_IC_11AC_2_SERIES) {
+ if (bw == 80)
+ nbi_table_idx = FFT_256_TYPE;
+ else /*20M, 40M*/
+ nbi_table_idx = FFT_128_TYPE;
+ }
+
+ if (nbi_table_idx == FFT_128_TYPE) {
+ for (i = 0; i < NBI_TABLE_SIZE_128; i++) {
+ if (tone_idx_tmp < nbi_table_128[i]) {
+ reg_idx = i + 1;
+ break;
+ }
+ }
+
+ } else if (nbi_table_idx == FFT_256_TYPE) {
+ for (i = 0; i < NBI_TABLE_SIZE_256; i++) {
+ if (tone_idx_tmp < nbi_table_256[i]) {
+ reg_idx = i + 1;
+ break;
+ }
+ }
+ }
+
+ if (dm->support_ic_type & ODM_IC_11N_SERIES) {
+ odm_set_bb_reg(dm, 0xc40, 0x1f000000, reg_idx);
+ ODM_RT_TRACE(dm, ODM_COMP_API,
+ "Set tone idx: Reg0xC40[28:24] = ((0x%x))\n",
+ reg_idx);
+ /**/
+ } else {
+ odm_set_bb_reg(dm, 0x87c, 0xfc000, reg_idx);
+ ODM_RT_TRACE(dm, ODM_COMP_API,
+ "Set tone idx: Reg0x87C[19:14] = ((0x%x))\n",
+ reg_idx);
+ /**/
+ }
+}
+
+static void phydm_nbi_enable(void *dm_void, u32 enable)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 reg_value = 0;
+
+ reg_value = (enable == NBI_ENABLE) ? 1 : 0;
+
+ if (dm->support_ic_type & ODM_IC_11N_SERIES) {
+ odm_set_bb_reg(dm, 0xc40, BIT(9), reg_value);
+ ODM_RT_TRACE(dm, ODM_COMP_API,
+ "Enable NBI Reg0xC40[9] = ((0x%x))\n", reg_value);
+
+ } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ odm_set_bb_reg(dm, 0x87c, BIT(13), reg_value);
+ ODM_RT_TRACE(dm, ODM_COMP_API,
+ "Enable NBI Reg0x87C[13] = ((0x%x))\n", reg_value);
+ }
+}
+
+static u8 phydm_calculate_fc(void *dm_void, u32 channel, u32 bw, u32 second_ch,
+ u32 *fc_in)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 fc = *fc_in;
+ u32 start_ch_per_40m[NUM_START_CH_40M + 1] = {
+ 36, 44, 52, 60, 100, 108, 116, 124,
+ 132, 140, 149, 157, 165, 173, 173 + 8,
+ };
+ u32 start_ch_per_80m[NUM_START_CH_80M + 1] = {
+ 36, 52, 100, 116, 132, 149, 165, 165 + 16,
+ };
+ u32 *start_ch = &start_ch_per_40m[0];
+ u32 num_start_channel = NUM_START_CH_40M;
+ u32 channel_offset = 0;
+ u32 i;
+
+ /*2.4G*/
+ if (channel <= 14 && channel > 0) {
+ if (bw == 80)
+ return SET_ERROR;
+
+ fc = 2412 + (channel - 1) * 5;
+
+ if (bw == 40 && (second_ch == PHYDM_ABOVE)) {
+ if (channel >= 10) {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_API,
+ "CH = ((%d)), Scnd_CH = ((%d)) Error setting\n",
+ channel, second_ch);
+ return SET_ERROR;
+ }
+ fc += 10;
+ } else if (bw == 40 && (second_ch == PHYDM_BELOW)) {
+ if (channel <= 2) {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_API,
+ "CH = ((%d)), Scnd_CH = ((%d)) Error setting\n",
+ channel, second_ch);
+ return SET_ERROR;
+ }
+ fc -= 10;
+ }
+ }
+ /*5G*/
+ else if (channel >= 36 && channel <= 177) {
+ if (bw == 20) {
+ fc = 5180 + (channel - 36) * 5;
+ *fc_in = fc;
+ return SET_SUCCESS;
+ }
+
+ if (bw == 40) {
+ num_start_channel = NUM_START_CH_40M;
+ start_ch = &start_ch_per_40m[0];
+ channel_offset = CH_OFFSET_40M;
+ } else if (bw == 80) {
+ num_start_channel = NUM_START_CH_80M;
+ start_ch = &start_ch_per_80m[0];
+ channel_offset = CH_OFFSET_80M;
+ }
+
+ for (i = 0; i < num_start_channel; i++) {
+ if (channel < start_ch[i + 1]) {
+ channel = start_ch[i] + channel_offset;
+ break;
+ }
+ }
+
+ ODM_RT_TRACE(dm, ODM_COMP_API, "Mod_CH = ((%d))\n", channel);
+
+ fc = 5180 + (channel - 36) * 5;
+
+ } else {
+ ODM_RT_TRACE(dm, ODM_COMP_API, "CH = ((%d)) Error setting\n",
+ channel);
+ return SET_ERROR;
+ }
+
+ *fc_in = fc;
+
+ return SET_SUCCESS;
+}
+
+static u8 phydm_calculate_intf_distance(void *dm_void, u32 bw, u32 fc,
+ u32 f_interference,
+ u32 *tone_idx_tmp_in)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 bw_up, bw_low;
+ u32 int_distance;
+ u32 tone_idx_tmp;
+ u8 set_result = SET_NO_NEED;
+
+ bw_up = fc + bw / 2;
+ bw_low = fc - bw / 2;
+
+ ODM_RT_TRACE(dm, ODM_COMP_API,
+ "[f_l, fc, fh] = [ %d, %d, %d ], f_int = ((%d))\n", bw_low,
+ fc, bw_up, f_interference);
+
+ if ((f_interference >= bw_low) && (f_interference <= bw_up)) {
+ int_distance = (fc >= f_interference) ? (fc - f_interference) :
+ (f_interference - fc);
+ tone_idx_tmp =
+ (int_distance << 5); /* =10*(int_distance /0.3125) */
+ ODM_RT_TRACE(
+ dm, ODM_COMP_API,
+ "int_distance = ((%d MHz)) Mhz, tone_idx_tmp = ((%d.%d))\n",
+ int_distance, (tone_idx_tmp / 10), (tone_idx_tmp % 10));
+ *tone_idx_tmp_in = tone_idx_tmp;
+ set_result = SET_SUCCESS;
+ }
+
+ return set_result;
+}
+
+static u8 phydm_csi_mask_setting(void *dm_void, u32 enable, u32 channel, u32 bw,
+ u32 f_interference, u32 second_ch)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 fc;
+ u8 tone_direction;
+ u32 tone_idx_tmp;
+ u8 set_result = SET_SUCCESS;
+
+ if (enable == CSI_MASK_DISABLE) {
+ set_result = SET_SUCCESS;
+ phydm_clean_all_csi_mask(dm);
+
+ } else {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_API,
+ "[Set CSI MASK_] CH = ((%d)), BW = ((%d)), f_intf = ((%d)), Scnd_CH = ((%s))\n",
+ channel, bw, f_interference,
+ (((bw == 20) || (channel > 14)) ?
+ "Don't care" :
+ (second_ch == PHYDM_ABOVE) ? "H" : "L"));
+
+ /*calculate fc*/
+ if (phydm_calculate_fc(dm, channel, bw, second_ch, &fc) ==
+ SET_ERROR) {
+ set_result = SET_ERROR;
+ } else {
+ /*calculate interference distance*/
+ if (phydm_calculate_intf_distance(
+ dm, bw, fc, f_interference,
+ &tone_idx_tmp) == SET_SUCCESS) {
+ tone_direction = (f_interference >= fc) ?
+ FREQ_POSITIVE :
+ FREQ_NEGATIVE;
+ phydm_set_csi_mask_reg(dm, tone_idx_tmp,
+ tone_direction);
+ set_result = SET_SUCCESS;
+ } else {
+ set_result = SET_NO_NEED;
+ }
+ }
+ }
+
+ if (set_result == SET_SUCCESS)
+ phydm_csi_mask_enable(dm, enable);
+ else
+ phydm_csi_mask_enable(dm, CSI_MASK_DISABLE);
+
+ return set_result;
+}
+
+u8 phydm_nbi_setting(void *dm_void, u32 enable, u32 channel, u32 bw,
+ u32 f_interference, u32 second_ch)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 fc;
+ u32 tone_idx_tmp;
+ u8 set_result = SET_SUCCESS;
+
+ if (enable == NBI_DISABLE) {
+ set_result = SET_SUCCESS;
+ } else {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_API,
+ "[Set NBI] CH = ((%d)), BW = ((%d)), f_intf = ((%d)), Scnd_CH = ((%s))\n",
+ channel, bw, f_interference,
+ (((second_ch == PHYDM_DONT_CARE) || (bw == 20) ||
+ (channel > 14)) ?
+ "Don't care" :
+ (second_ch == PHYDM_ABOVE) ? "H" : "L"));
+
+ /*calculate fc*/
+ if (phydm_calculate_fc(dm, channel, bw, second_ch, &fc) ==
+ SET_ERROR) {
+ set_result = SET_ERROR;
+ } else {
+ /*calculate interference distance*/
+ if (phydm_calculate_intf_distance(
+ dm, bw, fc, f_interference,
+ &tone_idx_tmp) == SET_SUCCESS) {
+ phydm_set_nbi_reg(dm, tone_idx_tmp, bw);
+ set_result = SET_SUCCESS;
+ } else {
+ set_result = SET_NO_NEED;
+ }
+ }
+ }
+
+ if (set_result == SET_SUCCESS)
+ phydm_nbi_enable(dm, enable);
+ else
+ phydm_nbi_enable(dm, NBI_DISABLE);
+
+ return set_result;
+}
+
+void phydm_api_debug(void *dm_void, u32 function_map, u32 *const dm_value,
+ u32 *_used, char *output, u32 *_out_len)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+ u32 channel = dm_value[1];
+ u32 bw = dm_value[2];
+ u32 f_interference = dm_value[3];
+ u32 second_ch = dm_value[4];
+ u8 set_result = 0;
+
+ /*PHYDM_API_NBI*/
+ /*--------------------------------------------------------------------*/
+ if (function_map == PHYDM_API_NBI) {
+ if (dm_value[0] == 100) {
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "[HELP-NBI] EN(on=1, off=2) CH BW(20/40/80) f_intf(Mhz) Scnd_CH(L=1, H=2)\n");
+ return;
+
+ } else if (dm_value[0] == NBI_ENABLE) {
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "[Enable NBI] CH = ((%d)), BW = ((%d)), f_intf = ((%d)), Scnd_CH = ((%s))\n",
+ channel, bw, f_interference,
+ ((second_ch == PHYDM_DONT_CARE) || (bw == 20) ||
+ (channel > 14)) ?
+ "Don't care" :
+ ((second_ch == PHYDM_ABOVE) ? "H" :
+ "L"));
+ set_result =
+ phydm_nbi_setting(dm, NBI_ENABLE, channel, bw,
+ f_interference, second_ch);
+
+ } else if (dm_value[0] == NBI_DISABLE) {
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "[Disable NBI]\n");
+ set_result =
+ phydm_nbi_setting(dm, NBI_DISABLE, channel, bw,
+ f_interference, second_ch);
+
+ } else {
+ set_result = SET_ERROR;
+ }
+
+ PHYDM_SNPRINTF(
+ output + used, out_len - used, "[NBI set result: %s]\n",
+ (set_result == SET_SUCCESS) ?
+ "Success" :
+ ((set_result == SET_NO_NEED) ? "No need" :
+ "Error"));
+ }
+
+ /*PHYDM_CSI_MASK*/
+ /*--------------------------------------------------------------------*/
+ else if (function_map == PHYDM_API_CSI_MASK) {
+ if (dm_value[0] == 100) {
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "[HELP-CSI MASK] EN(on=1, off=2) CH BW(20/40/80) f_intf(Mhz) Scnd_CH(L=1, H=2)\n");
+ return;
+
+ } else if (dm_value[0] == CSI_MASK_ENABLE) {
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "[Enable CSI MASK] CH = ((%d)), BW = ((%d)), f_intf = ((%d)), Scnd_CH = ((%s))\n",
+ channel, bw, f_interference,
+ (channel > 14) ?
+ "Don't care" :
+ (((second_ch == PHYDM_DONT_CARE) ||
+ (bw == 20) || (channel > 14)) ?
+ "H" :
+ "L"));
+ set_result = phydm_csi_mask_setting(
+ dm, CSI_MASK_ENABLE, channel, bw,
+ f_interference, second_ch);
+
+ } else if (dm_value[0] == CSI_MASK_DISABLE) {
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "[Disable CSI MASK]\n");
+ set_result = phydm_csi_mask_setting(
+ dm, CSI_MASK_DISABLE, channel, bw,
+ f_interference, second_ch);
+
+ } else {
+ set_result = SET_ERROR;
+ }
+
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "[CSI MASK set result: %s]\n",
+ (set_result == SET_SUCCESS) ?
+ "Success" :
+ ((set_result == SET_NO_NEED) ?
+ "No need" :
+ "Error"));
+ }
+}
diff --git a/drivers/staging/rtlwifi/phydm/phydm.h b/drivers/staging/rtlwifi/phydm/phydm.h
new file mode 100644
index 0000000..5812ff4
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm.h
@@ -0,0 +1,946 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __HALDMOUTSRC_H__
+#define __HALDMOUTSRC_H__
+
+/*============================================================*/
+/*include files*/
+/*============================================================*/
+#include "phydm_pre_define.h"
+#include "phydm_dig.h"
+#include "phydm_edcaturbocheck.h"
+#include "phydm_antdiv.h"
+#include "phydm_dynamicbbpowersaving.h"
+#include "phydm_rainfo.h"
+#include "phydm_dynamictxpower.h"
+#include "phydm_cfotracking.h"
+#include "phydm_acs.h"
+#include "phydm_adaptivity.h"
+#include "phydm_iqk.h"
+#include "phydm_dfs.h"
+#include "phydm_ccx.h"
+#include "txbf/phydm_hal_txbf_api.h"
+
+#include "phydm_adc_sampling.h"
+#include "phydm_dynamic_rx_path.h"
+#include "phydm_psd.h"
+
+#include "phydm_beamforming.h"
+
+#include "phydm_noisemonitor.h"
+#include "halphyrf_ce.h"
+
+/*============================================================*/
+/*Definition */
+/*============================================================*/
+
+/* Traffic load decision */
+#define TRAFFIC_ULTRA_LOW 1
+#define TRAFFIC_LOW 2
+#define TRAFFIC_MID 3
+#define TRAFFIC_HIGH 4
+
+#define NONE 0
+
+/*NBI API------------------------------------*/
+#define NBI_ENABLE 1
+#define NBI_DISABLE 2
+
+#define NBI_TABLE_SIZE_128 27
+#define NBI_TABLE_SIZE_256 59
+
+#define NUM_START_CH_80M 7
+#define NUM_START_CH_40M 14
+
+#define CH_OFFSET_40M 2
+#define CH_OFFSET_80M 6
+
+/*CSI MASK API------------------------------------*/
+#define CSI_MASK_ENABLE 1
+#define CSI_MASK_DISABLE 2
+
+/*------------------------------------------------*/
+
+#define FFT_128_TYPE 1
+#define FFT_256_TYPE 2
+
+#define SET_SUCCESS 1
+#define SET_ERROR 2
+#define SET_NO_NEED 3
+
+#define FREQ_POSITIVE 1
+#define FREQ_NEGATIVE 2
+
+#define PHYDM_WATCH_DOG_PERIOD 2
+
+/*============================================================*/
+/*structure and define*/
+/*============================================================*/
+
+/*2011/09/20 MH Add for AP/ADSLpseudo DM structuer requirement.*/
+/*We need to remove to other position???*/
+
+struct rtl8192cd_priv {
+ u8 temp;
+};
+
+struct dyn_primary_cca {
+ u8 pri_cca_flag;
+ u8 intf_flag;
+ u8 intf_type;
+ u8 dup_rts_flag;
+ u8 monitor_flag;
+ u8 ch_offset;
+ u8 mf_state;
+};
+
+#define dm_type_by_fw 0
+#define dm_type_by_driver 1
+
+/*Declare for common info*/
+
+#define IQK_THRESHOLD 8
+#define DPK_THRESHOLD 4
+
+struct dm_phy_status_info {
+ /* */
+ /* Be care, if you want to add any element please insert between */
+ /* rx_pwdb_all & signal_strength. */
+ /* */
+ u8 rx_pwdb_all;
+ u8 signal_quality; /* in 0-100 index. */
+ s8 rx_mimo_signal_quality[4]; /* per-path's EVM translate to 0~100% */
+ u8 rx_mimo_evm_dbm[4]; /* per-path's original EVM (dbm) */
+ u8 rx_mimo_signal_strength[4]; /* in 0~100 index */
+ s16 cfo_short[4]; /* per-path's cfo_short */
+ s16 cfo_tail[4]; /* per-path's cfo_tail */
+ s8 rx_power; /* in dBm Translate from PWdB */
+ s8 recv_signal_power; /* Real power in dBm for this packet,
+ * no beautification and aggregation.
+ * Keep this raw info to be used for the other
+ * procedures.
+ */
+ u8 bt_rx_rssi_percentage;
+ u8 signal_strength; /* in 0-100 index. */
+ s8 rx_pwr[4]; /* per-path's pwdb */
+ s8 rx_snr[4]; /* per-path's SNR */
+ /* s8 BB_Backup[13]; backup reg. */
+ u8 rx_count : 2; /* RX path counter---*/
+ u8 band_width : 2;
+ u8 rxsc : 4; /* sub-channel---*/
+ u8 bt_coex_pwr_adjust;
+ u8 channel; /* channel number---*/
+ bool is_mu_packet; /* is MU packet or not---*/
+ bool is_beamformed; /* BF packet---*/
+};
+
+struct dm_per_pkt_info {
+ u8 data_rate;
+ u8 station_id;
+ bool is_packet_match_bssid;
+ bool is_packet_to_self;
+ bool is_packet_beacon;
+ bool is_to_self;
+ u8 ppdu_cnt;
+};
+
+struct odm_phy_dbg_info {
+ /*ODM Write,debug info*/
+ s8 rx_snr_db[4];
+ u32 num_qry_phy_status;
+ u32 num_qry_phy_status_cck;
+ u32 num_qry_phy_status_ofdm;
+ u32 num_qry_mu_pkt;
+ u32 num_qry_bf_pkt;
+ u32 num_qry_mu_vht_pkt[40];
+ u32 num_qry_vht_pkt[40];
+ bool is_ldpc_pkt;
+ bool is_stbc_pkt;
+ u8 num_of_ppdu[4];
+ u8 gid_num[4];
+ u8 num_qry_beacon_pkt;
+ /* Others */
+ s32 rx_evm[4];
+};
+
+/*2011/20/20 MH For MP driver RT_WLAN_STA = struct rtl_sta_info*/
+/*Please declare below ODM relative info in your STA info structure.*/
+
+struct odm_sta_info {
+ /*Driver Write*/
+ bool is_used; /*record the sta status link or not?*/
+ u8 iot_peer; /*Enum value. HT_IOT_PEER_E*/
+
+ /*ODM Write*/
+ /*PHY_STATUS_INFO*/
+ u8 rssi_path[4];
+ u8 rssi_ave;
+ u8 RXEVM[4];
+ u8 RXSNR[4];
+};
+
+enum odm_cmninfo {
+ /*Fixed value*/
+ /*-----------HOOK BEFORE REG INIT-----------*/
+ ODM_CMNINFO_PLATFORM = 0,
+ ODM_CMNINFO_ABILITY,
+ ODM_CMNINFO_INTERFACE,
+ ODM_CMNINFO_MP_TEST_CHIP,
+ ODM_CMNINFO_IC_TYPE,
+ ODM_CMNINFO_CUT_VER,
+ ODM_CMNINFO_FAB_VER,
+ ODM_CMNINFO_RF_TYPE,
+ ODM_CMNINFO_RFE_TYPE,
+ ODM_CMNINFO_BOARD_TYPE,
+ ODM_CMNINFO_PACKAGE_TYPE,
+ ODM_CMNINFO_EXT_LNA,
+ ODM_CMNINFO_5G_EXT_LNA,
+ ODM_CMNINFO_EXT_PA,
+ ODM_CMNINFO_5G_EXT_PA,
+ ODM_CMNINFO_GPA,
+ ODM_CMNINFO_APA,
+ ODM_CMNINFO_GLNA,
+ ODM_CMNINFO_ALNA,
+ ODM_CMNINFO_EXT_TRSW,
+ ODM_CMNINFO_DPK_EN,
+ ODM_CMNINFO_EXT_LNA_GAIN,
+ ODM_CMNINFO_PATCH_ID,
+ ODM_CMNINFO_BINHCT_TEST,
+ ODM_CMNINFO_BWIFI_TEST,
+ ODM_CMNINFO_SMART_CONCURRENT,
+ ODM_CMNINFO_CONFIG_BB_RF,
+ ODM_CMNINFO_DOMAIN_CODE_2G,
+ ODM_CMNINFO_DOMAIN_CODE_5G,
+ ODM_CMNINFO_IQKFWOFFLOAD,
+ ODM_CMNINFO_IQKPAOFF,
+ ODM_CMNINFO_HUBUSBMODE,
+ ODM_CMNINFO_FWDWRSVDPAGEINPROGRESS,
+ ODM_CMNINFO_TX_TP,
+ ODM_CMNINFO_RX_TP,
+ ODM_CMNINFO_SOUNDING_SEQ,
+ ODM_CMNINFO_REGRFKFREEENABLE,
+ ODM_CMNINFO_RFKFREEENABLE,
+ ODM_CMNINFO_NORMAL_RX_PATH_CHANGE,
+ ODM_CMNINFO_EFUSE0X3D8,
+ ODM_CMNINFO_EFUSE0X3D7,
+ /*-----------HOOK BEFORE REG INIT-----------*/
+
+ /*Dynamic value:*/
+
+ /*--------- POINTER REFERENCE-----------*/
+ ODM_CMNINFO_MAC_PHY_MODE,
+ ODM_CMNINFO_TX_UNI,
+ ODM_CMNINFO_RX_UNI,
+ ODM_CMNINFO_WM_MODE,
+ ODM_CMNINFO_BAND,
+ ODM_CMNINFO_SEC_CHNL_OFFSET,
+ ODM_CMNINFO_SEC_MODE,
+ ODM_CMNINFO_BW,
+ ODM_CMNINFO_CHNL,
+ ODM_CMNINFO_FORCED_RATE,
+ ODM_CMNINFO_ANT_DIV,
+ ODM_CMNINFO_ADAPTIVITY,
+ ODM_CMNINFO_DMSP_GET_VALUE,
+ ODM_CMNINFO_BUDDY_ADAPTOR,
+ ODM_CMNINFO_DMSP_IS_MASTER,
+ ODM_CMNINFO_SCAN,
+ ODM_CMNINFO_POWER_SAVING,
+ ODM_CMNINFO_ONE_PATH_CCA,
+ ODM_CMNINFO_DRV_STOP,
+ ODM_CMNINFO_PNP_IN,
+ ODM_CMNINFO_INIT_ON,
+ ODM_CMNINFO_ANT_TEST,
+ ODM_CMNINFO_NET_CLOSED,
+ ODM_CMNINFO_FORCED_IGI_LB,
+ ODM_CMNINFO_P2P_LINK,
+ ODM_CMNINFO_FCS_MODE,
+ ODM_CMNINFO_IS1ANTENNA,
+ ODM_CMNINFO_RFDEFAULTPATH,
+ ODM_CMNINFO_DFS_MASTER_ENABLE,
+ ODM_CMNINFO_FORCE_TX_ANT_BY_TXDESC,
+ ODM_CMNINFO_SET_S0S1_DEFAULT_ANTENNA,
+ /*--------- POINTER REFERENCE-----------*/
+
+ /*------------CALL BY VALUE-------------*/
+ ODM_CMNINFO_WIFI_DIRECT,
+ ODM_CMNINFO_WIFI_DISPLAY,
+ ODM_CMNINFO_LINK_IN_PROGRESS,
+ ODM_CMNINFO_LINK,
+ ODM_CMNINFO_CMW500LINK,
+ ODM_CMNINFO_LPSPG,
+ ODM_CMNINFO_STATION_STATE,
+ ODM_CMNINFO_RSSI_MIN,
+ ODM_CMNINFO_DBG_COMP,
+ ODM_CMNINFO_DBG_LEVEL,
+ ODM_CMNINFO_RA_THRESHOLD_HIGH,
+ ODM_CMNINFO_RA_THRESHOLD_LOW,
+ ODM_CMNINFO_RF_ANTENNA_TYPE,
+ ODM_CMNINFO_WITH_EXT_ANTENNA_SWITCH,
+ ODM_CMNINFO_BE_FIX_TX_ANT,
+ ODM_CMNINFO_BT_ENABLED,
+ ODM_CMNINFO_BT_HS_CONNECT_PROCESS,
+ ODM_CMNINFO_BT_HS_RSSI,
+ ODM_CMNINFO_BT_OPERATION,
+ ODM_CMNINFO_BT_LIMITED_DIG,
+ ODM_CMNINFO_BT_DIG,
+ ODM_CMNINFO_BT_BUSY,
+ ODM_CMNINFO_BT_DISABLE_EDCA,
+ ODM_CMNINFO_AP_TOTAL_NUM,
+ ODM_CMNINFO_POWER_TRAINING,
+ ODM_CMNINFO_DFS_REGION_DOMAIN,
+ /*------------CALL BY VALUE-------------*/
+
+ /*Dynamic ptr array hook itms.*/
+ ODM_CMNINFO_STA_STATUS,
+ ODM_CMNINFO_MAX,
+
+};
+
+enum phydm_info_query {
+ PHYDM_INFO_FA_OFDM,
+ PHYDM_INFO_FA_CCK,
+ PHYDM_INFO_FA_TOTAL,
+ PHYDM_INFO_CCA_OFDM,
+ PHYDM_INFO_CCA_CCK,
+ PHYDM_INFO_CCA_ALL,
+ PHYDM_INFO_CRC32_OK_VHT,
+ PHYDM_INFO_CRC32_OK_HT,
+ PHYDM_INFO_CRC32_OK_LEGACY,
+ PHYDM_INFO_CRC32_OK_CCK,
+ PHYDM_INFO_CRC32_ERROR_VHT,
+ PHYDM_INFO_CRC32_ERROR_HT,
+ PHYDM_INFO_CRC32_ERROR_LEGACY,
+ PHYDM_INFO_CRC32_ERROR_CCK,
+ PHYDM_INFO_EDCCA_FLAG,
+ PHYDM_INFO_OFDM_ENABLE,
+ PHYDM_INFO_CCK_ENABLE,
+ PHYDM_INFO_DBG_PORT_0
+};
+
+enum phydm_api {
+ PHYDM_API_NBI = 1,
+ PHYDM_API_CSI_MASK,
+
+};
+
+/*2011/10/20 MH Define ODM support ability. ODM_CMNINFO_ABILITY*/
+enum odm_ability {
+ /*BB ODM section BIT 0-19*/
+ ODM_BB_DIG = BIT(0),
+ ODM_BB_RA_MASK = BIT(1),
+ ODM_BB_DYNAMIC_TXPWR = BIT(2),
+ ODM_BB_FA_CNT = BIT(3),
+ ODM_BB_RSSI_MONITOR = BIT(4),
+ ODM_BB_CCK_PD = BIT(5),
+ ODM_BB_ANT_DIV = BIT(6),
+ ODM_BB_PWR_TRAIN = BIT(8),
+ ODM_BB_RATE_ADAPTIVE = BIT(9),
+ ODM_BB_PATH_DIV = BIT(10),
+ ODM_BB_ADAPTIVITY = BIT(13),
+ ODM_BB_CFO_TRACKING = BIT(14),
+ ODM_BB_NHM_CNT = BIT(15),
+ ODM_BB_PRIMARY_CCA = BIT(16),
+ ODM_BB_TXBF = BIT(17),
+ ODM_BB_DYNAMIC_ARFR = BIT(18),
+
+ ODM_MAC_EDCA_TURBO = BIT(20),
+ ODM_BB_DYNAMIC_RX_PATH = BIT(21),
+
+ /*RF ODM section BIT 24-31*/
+ ODM_RF_TX_PWR_TRACK = BIT(24),
+ ODM_RF_RX_GAIN_TRACK = BIT(25),
+ ODM_RF_CALIBRATION = BIT(26),
+
+};
+
+/*ODM_CMNINFO_ONE_PATH_CCA*/
+enum odm_cca_path {
+ ODM_CCA_2R = 0,
+ ODM_CCA_1R_A = 1,
+ ODM_CCA_1R_B = 2,
+};
+
+enum cca_pathdiv_en {
+ CCA_PATHDIV_DISABLE = 0,
+ CCA_PATHDIV_ENABLE = 1,
+
+};
+
+enum phy_reg_pg_type {
+ PHY_REG_PG_RELATIVE_VALUE = 0,
+ PHY_REG_PG_EXACT_VALUE = 1
+};
+
+/*2011/09/22 MH Copy from SD4 defined structure.
+ *We use to support PHY DM integration.
+ */
+
+struct phy_dm_struct {
+ /*Add for different team use temporarily*/
+ void *adapter; /*For CE/NIC team*/
+ struct rtl8192cd_priv *priv; /*For AP/ADSL team*/
+ /*When you use adapter or priv pointer,
+ *you must make sure the pointer is ready.
+ */
+ bool odm_ready;
+
+ struct rtl8192cd_priv fake_priv;
+
+ enum phy_reg_pg_type phy_reg_pg_value_type;
+ u8 phy_reg_pg_version;
+
+ u32 debug_components;
+ u32 fw_debug_components;
+ u32 debug_level;
+
+ u32 num_qry_phy_status_all; /*CCK + OFDM*/
+ u32 last_num_qry_phy_status_all;
+ u32 rx_pwdb_ave;
+ bool MPDIG_2G; /*off MPDIG*/
+ u8 times_2g;
+ bool is_init_hw_info_by_rfe;
+
+ /*------ ODM HANDLE, DRIVER NEEDS NOT TO HOOK------*/
+ bool is_cck_high_power;
+ u8 rf_path_rx_enable;
+ u8 control_channel;
+ /*------ ODM HANDLE, DRIVER NEEDS NOT TO HOOK------*/
+
+ /* 1 COMMON INFORMATION */
+
+ /*Init value*/
+ /*-----------HOOK BEFORE REG INIT-----------*/
+ /*ODM Platform info AP/ADSL/CE/MP = 1/2/3/4*/
+ u8 support_platform;
+ /* ODM Platform info WIN/AP/CE = 1/2/3 */
+ u8 normal_rx_path;
+ /*ODM Support Ability DIG/RATR/TX_PWR_TRACK/ ... = 1/2/3/...*/
+ u32 support_ability;
+ /*ODM PCIE/USB/SDIO = 1/2/3*/
+ u8 support_interface;
+ /*ODM composite or independent. Bit oriented/ 92C+92D+ .... or
+ *any other type = 1/2/3/...
+ */
+ u32 support_ic_type;
+ /*cut version TestChip/A-cut/B-cut... = 0/1/2/3/...*/
+ u8 cut_version;
+ /*Fab version TSMC/UMC = 0/1*/
+ u8 fab_version;
+ /*RF type 4T4R/3T3R/2T2R/1T2R/1T1R/...*/
+ u8 rf_type;
+ u8 rfe_type;
+ /*Board type Normal/HighPower/MiniCard/SLIM/Combo/... = 0/1/2/3/4/...*/
+ /*Enable Function DPK OFF/ON = 0/1*/
+ u8 dpk_en;
+ u8 board_type;
+ u8 package_type;
+ u16 type_glna;
+ u16 type_gpa;
+ u16 type_alna;
+ u16 type_apa;
+ /*with external LNA NO/Yes = 0/1*/
+ u8 ext_lna; /*2G*/
+ u8 ext_lna_5g; /*5G*/
+ /*with external PA NO/Yes = 0/1*/
+ u8 ext_pa; /*2G*/
+ u8 ext_pa_5g; /*5G*/
+ /*with Efuse number*/
+ u8 efuse0x3d7;
+ u8 efuse0x3d8;
+ /*with external TRSW NO/Yes = 0/1*/
+ u8 ext_trsw;
+ u8 ext_lna_gain; /*2G*/
+ u8 patch_id; /*Customer ID*/
+ bool is_in_hct_test;
+ u8 wifi_test;
+
+ bool is_dual_mac_smart_concurrent;
+ u32 bk_support_ability;
+ u8 ant_div_type;
+ u8 with_extenal_ant_switch;
+ bool config_bbrf;
+ u8 odm_regulation_2_4g;
+ u8 odm_regulation_5g;
+ u8 iqk_fw_offload;
+ bool cck_new_agc;
+ u8 phydm_period;
+ u32 phydm_sys_up_time;
+ u8 num_rf_path;
+ /*-----------HOOK BEFORE REG INIT-----------*/
+
+ /*Dynamic value*/
+
+ /*--------- POINTER REFERENCE-----------*/
+
+ u8 u1_byte_temp;
+ bool BOOLEAN_temp;
+ void *PADAPTER_temp;
+
+ /*MAC PHY mode SMSP/DMSP/DMDP = 0/1/2*/
+ u8 *mac_phy_mode;
+ /*TX Unicast byte count*/
+ u64 *num_tx_bytes_unicast;
+ /*RX Unicast byte count*/
+ u64 *num_rx_bytes_unicast;
+ /*Wireless mode B/G/A/N = BIT0/BIT1/BIT2/BIT3*/
+ u8 *wireless_mode;
+ /*Frequence band 2.4G/5G = 0/1*/
+ u8 *band_type;
+ /*Secondary channel offset don't_care/below/above = 0/1/2*/
+ u8 *sec_ch_offset;
+ /*security mode Open/WEP/AES/TKIP = 0/1/2/3*/
+ u8 *security;
+ /*BW info 20M/40M/80M = 0/1/2*/
+ u8 *band_width;
+ /*Central channel location Ch1/Ch2/....*/
+ u8 *channel; /*central channel number*/
+ bool dpk_done;
+ /*Common info for 92D DMSP*/
+
+ bool *is_get_value_from_other_mac;
+ void **buddy_adapter;
+ bool *is_master_of_dmsp; /* MAC0: master, MAC1: slave */
+ /*Common info for status*/
+ bool *is_scan_in_process;
+ bool *is_power_saving;
+ /*CCA path 2-path/path-A/path-B = 0/1/2; using enum odm_cca_path.*/
+ u8 *one_path_cca;
+ u8 *antenna_test;
+ bool *is_net_closed;
+ u8 *pu1_forced_igi_lb;
+ bool *is_fcs_mode_enable;
+ /*--------- For 8723B IQK-----------*/
+ bool *is_1_antenna;
+ u8 *rf_default_path;
+ /* 0:S1, 1:S0 */
+
+ /*--------- POINTER REFERENCE-----------*/
+ u16 *forced_data_rate;
+ u8 *enable_antdiv;
+ u8 *enable_adaptivity;
+ u8 *hub_usb_mode;
+ bool *is_fw_dw_rsvd_page_in_progress;
+ u32 *current_tx_tp;
+ u32 *current_rx_tp;
+ u8 *sounding_seq;
+ /*------------CALL BY VALUE-------------*/
+ bool is_link_in_process;
+ bool is_wifi_direct;
+ bool is_wifi_display;
+ bool is_linked;
+ bool is_linkedcmw500;
+ bool is_in_lps_pg;
+ bool bsta_state;
+ u8 rssi_min;
+ u8 interface_index; /*Add for 92D dual MAC: 0--Mac0 1--Mac1*/
+ bool is_mp_chip;
+ bool is_one_entry_only;
+ bool mp_mode;
+ u32 one_entry_macid;
+ u8 pre_number_linked_client;
+ u8 number_linked_client;
+ u8 pre_number_active_client;
+ u8 number_active_client;
+ /*Common info for BTDM*/
+ bool is_bt_enabled; /*BT is enabled*/
+ bool is_bt_connect_process; /*BT HS is under connection progress.*/
+ u8 bt_hs_rssi; /*BT HS mode wifi rssi value.*/
+ bool is_bt_hs_operation; /*BT HS mode is under progress*/
+ u8 bt_hs_dig_val; /*use BT rssi to decide the DIG value*/
+ bool is_bt_disable_edca_turbo; /*Under some condition, don't enable*/
+ bool is_bt_busy; /*BT is busy.*/
+ bool is_bt_limited_dig; /*BT is busy.*/
+ bool is_disable_phy_api;
+ /*------------CALL BY VALUE-------------*/
+ u8 rssi_a;
+ u8 rssi_b;
+ u8 rssi_c;
+ u8 rssi_d;
+ u64 rssi_trsw;
+ u64 rssi_trsw_h;
+ u64 rssi_trsw_l;
+ u64 rssi_trsw_iso;
+ u8 tx_ant_status;
+ u8 rx_ant_status;
+ u8 cck_lna_idx;
+ u8 cck_vga_idx;
+ u8 curr_station_id;
+ u8 ofdm_agc_idx[4];
+
+ u8 rx_rate;
+ bool is_noisy_state;
+ u8 tx_rate;
+ u8 linked_interval;
+ u8 pre_channel;
+ u32 txagc_offset_value_a;
+ bool is_txagc_offset_positive_a;
+ u32 txagc_offset_value_b;
+ bool is_txagc_offset_positive_b;
+ u32 tx_tp;
+ u32 rx_tp;
+ u32 total_tp;
+ u64 cur_tx_ok_cnt;
+ u64 cur_rx_ok_cnt;
+ u64 last_tx_ok_cnt;
+ u64 last_rx_ok_cnt;
+ u32 bb_swing_offset_a;
+ bool is_bb_swing_offset_positive_a;
+ u32 bb_swing_offset_b;
+ bool is_bb_swing_offset_positive_b;
+ u8 igi_lower_bound;
+ u8 igi_upper_bound;
+ u8 antdiv_rssi;
+ u8 fat_comb_a;
+ u8 fat_comb_b;
+ u8 antdiv_intvl;
+ u8 ant_type;
+ u8 pre_ant_type;
+ u8 antdiv_period;
+ u8 evm_antdiv_period;
+ u8 antdiv_select;
+ u8 path_select;
+ u8 antdiv_evm_en;
+ u8 bdc_holdstate;
+ u8 ndpa_period;
+ bool h2c_rarpt_connect;
+ bool cck_agc_report_type;
+
+ u8 dm_dig_max_TH;
+ u8 dm_dig_min_TH;
+ u8 print_agc;
+ u8 traffic_load;
+ u8 pre_traffic_load;
+ /*8821C Antenna BTG/WLG/WLA Select*/
+ u8 current_rf_set_8821c;
+ u8 default_rf_set_8821c;
+ /*For Adaptivtiy*/
+ u16 nhm_cnt_0;
+ u16 nhm_cnt_1;
+ s8 TH_L2H_default;
+ s8 th_edcca_hl_diff_default;
+ s8 th_l2h_ini;
+ s8 th_edcca_hl_diff;
+ s8 th_l2h_ini_mode2;
+ s8 th_edcca_hl_diff_mode2;
+ bool carrier_sense_enable;
+ u8 adaptivity_igi_upper;
+ bool adaptivity_flag;
+ u8 dc_backoff;
+ bool adaptivity_enable;
+ u8 ap_total_num;
+ bool edcca_enable;
+ u8 pre_dbg_priority;
+ struct adaptivity_statistics adaptivity;
+ /*For Adaptivtiy*/
+ u8 last_usb_hub;
+ u8 tx_bf_data_rate;
+
+ u8 nbi_set_result;
+
+ u8 c2h_cmd_start;
+ u8 fw_debug_trace[60];
+ u8 pre_c2h_seq;
+ bool fw_buff_is_enpty;
+ u32 data_frame_num;
+
+ /*for noise detection*/
+ bool noisy_decision; /*b_noisy*/
+ bool pre_b_noisy;
+ u32 noisy_decision_smooth;
+ bool is_disable_dym_ecs;
+
+ struct odm_noise_monitor noise_level;
+ /*Define STA info.*/
+ /*odm_sta_info*/
+ /*2012/01/12 MH For MP,
+ *we need to reduce one array pointer for default port.??
+ */
+ struct rtl_sta_info *odm_sta_info[ODM_ASSOCIATE_ENTRY_NUM];
+ u16 platform2phydm_macid_table[ODM_ASSOCIATE_ENTRY_NUM];
+ /* platform_macid_table[platform_macid] = phydm_macid */
+ s32 accumulate_pwdb[ODM_ASSOCIATE_ENTRY_NUM];
+
+ /*2012/02/14 MH Add to share 88E ra with other SW team.*/
+ /*We need to colelct all support abilit to a proper area.*/
+
+ bool ra_support88e;
+
+ struct odm_phy_dbg_info phy_dbg_info;
+
+ /*ODM Structure*/
+ struct fast_antenna_training dm_fat_table;
+ struct dig_thres dm_dig_table;
+ struct dyn_pwr_saving dm_ps_table;
+ struct dyn_primary_cca dm_pri_cca;
+ struct ra_table dm_ra_table;
+ struct false_alarm_stat false_alm_cnt;
+ struct false_alarm_stat flase_alm_cnt_buddy_adapter;
+ struct sw_antenna_switch dm_swat_table;
+ struct cfo_tracking dm_cfo_track;
+ struct acs_info dm_acs;
+ struct ccx_info dm_ccx_info;
+ struct psd_info dm_psd_table;
+
+ struct rt_adcsmp adcsmp;
+
+ struct dm_iqk_info IQK_info;
+
+ struct edca_turbo dm_edca_table;
+ u32 WMMEDCA_BE;
+
+ bool *is_driver_stopped;
+ bool *is_driver_is_going_to_pnp_set_power_sleep;
+ bool *pinit_adpt_in_progress;
+
+ /*PSD*/
+ bool is_user_assign_level;
+ u8 RSSI_BT; /*come from BT*/
+ bool is_psd_in_process;
+ bool is_psd_active;
+ bool is_dm_initial_gain_enable;
+
+ /*MPT DIG*/
+ struct timer_list mpt_dig_timer;
+
+ /*for rate adaptive, in fact, 88c/92c fw will handle this*/
+ u8 is_use_ra_mask;
+
+ /* for dynamic SoML control */
+ bool bsomlenabled;
+
+ struct odm_rate_adaptive rate_adaptive;
+ struct dm_rf_calibration_struct rf_calibrate_info;
+ u32 n_iqk_cnt;
+ u32 n_iqk_ok_cnt;
+ u32 n_iqk_fail_cnt;
+
+ /*Power Training*/
+ u8 force_power_training_state;
+ bool is_change_state;
+ u32 PT_score;
+ u64 ofdm_rx_cnt;
+ u64 cck_rx_cnt;
+ bool is_disable_power_training;
+ u8 dynamic_tx_high_power_lvl;
+ u8 last_dtp_lvl;
+ u32 tx_agc_ofdm_18_6;
+ u8 rx_pkt_type;
+
+ /*ODM relative time.*/
+ struct timer_list path_div_switch_timer;
+ /*2011.09.27 add for path Diversity*/
+ struct timer_list cck_path_diversity_timer;
+ struct timer_list fast_ant_training_timer;
+ struct timer_list sbdcnt_timer;
+
+ /*ODM relative workitem.*/
+};
+
+enum phydm_structure_type {
+ PHYDM_FALSEALMCNT,
+ PHYDM_CFOTRACK,
+ PHYDM_ADAPTIVITY,
+ PHYDM_ROMINFO,
+
+};
+
+enum odm_rf_content {
+ odm_radioa_txt = 0x1000,
+ odm_radiob_txt = 0x1001,
+ odm_radioc_txt = 0x1002,
+ odm_radiod_txt = 0x1003
+};
+
+enum odm_bb_config_type {
+ CONFIG_BB_PHY_REG,
+ CONFIG_BB_AGC_TAB,
+ CONFIG_BB_AGC_TAB_2G,
+ CONFIG_BB_AGC_TAB_5G,
+ CONFIG_BB_PHY_REG_PG,
+ CONFIG_BB_PHY_REG_MP,
+ CONFIG_BB_AGC_TAB_DIFF,
+};
+
+enum odm_rf_config_type {
+ CONFIG_RF_RADIO,
+ CONFIG_RF_TXPWR_LMT,
+};
+
+enum odm_fw_config_type {
+ CONFIG_FW_NIC,
+ CONFIG_FW_NIC_2,
+ CONFIG_FW_AP,
+ CONFIG_FW_AP_2,
+ CONFIG_FW_MP,
+ CONFIG_FW_WOWLAN,
+ CONFIG_FW_WOWLAN_2,
+ CONFIG_FW_AP_WOWLAN,
+ CONFIG_FW_BT,
+};
+
+/*status code*/
+enum rt_status {
+ RT_STATUS_SUCCESS,
+ RT_STATUS_FAILURE,
+ RT_STATUS_PENDING,
+ RT_STATUS_RESOURCE,
+ RT_STATUS_INVALID_CONTEXT,
+ RT_STATUS_INVALID_PARAMETER,
+ RT_STATUS_NOT_SUPPORT,
+ RT_STATUS_OS_API_FAILED,
+};
+
+/*===========================================================*/
+/*AGC RX High Power mode*/
+/*===========================================================*/
+#define lna_low_gain_1 0x64
+#define lna_low_gain_2 0x5A
+#define lna_low_gain_3 0x58
+
+#define FA_RXHP_TH1 5000
+#define FA_RXHP_TH2 1500
+#define FA_RXHP_TH3 800
+#define FA_RXHP_TH4 600
+#define FA_RXHP_TH5 500
+
+enum dm_1r_cca {
+ CCA_1R = 0,
+ CCA_2R = 1,
+ CCA_MAX = 2,
+};
+
+enum dm_rf {
+ rf_save = 0,
+ rf_normal = 1,
+ RF_MAX = 2,
+};
+
+/*check Sta pointer valid or not*/
+
+#define IS_STA_VALID(sta) (sta)
+
+u32 odm_convert_to_db(u32 value);
+
+u32 odm_convert_to_linear(u32 value);
+
+s32 odm_pwdb_conversion(s32 X, u32 total_bit, u32 decimal_bit);
+
+s32 odm_sign_conversion(s32 value, u32 total_bit);
+
+void odm_init_mp_driver_status(struct phy_dm_struct *dm);
+
+void phydm_txcurrentcalibration(struct phy_dm_struct *dm);
+
+void phydm_seq_sorting(void *dm_void, u32 *value, u32 *rank_idx, u32 *idx_out,
+ u8 seq_length);
+
+void odm_dm_init(struct phy_dm_struct *dm);
+
+void odm_dm_reset(struct phy_dm_struct *dm);
+
+void phydm_support_ability_debug(void *dm_void, u32 *const dm_value, u32 *_used,
+ char *output, u32 *_out_len);
+
+void phydm_config_ofdm_rx_path(struct phy_dm_struct *dm, u32 path);
+
+void phydm_config_trx_path(void *dm_void, u32 *const dm_value, u32 *_used,
+ char *output, u32 *_out_len);
+
+void odm_dm_watchdog(struct phy_dm_struct *dm);
+
+void phydm_watchdog_mp(struct phy_dm_struct *dm);
+
+void odm_cmn_info_init(struct phy_dm_struct *dm, enum odm_cmninfo cmn_info,
+ u32 value);
+
+void odm_cmn_info_hook(struct phy_dm_struct *dm, enum odm_cmninfo cmn_info,
+ void *value);
+
+void odm_cmn_info_ptr_array_hook(struct phy_dm_struct *dm,
+ enum odm_cmninfo cmn_info, u16 index,
+ void *value);
+
+void odm_cmn_info_update(struct phy_dm_struct *dm, u32 cmn_info, u64 value);
+
+u32 phydm_cmn_info_query(struct phy_dm_struct *dm,
+ enum phydm_info_query info_type);
+
+void odm_init_all_timers(struct phy_dm_struct *dm);
+
+void odm_cancel_all_timers(struct phy_dm_struct *dm);
+
+void odm_release_all_timers(struct phy_dm_struct *dm);
+
+void odm_asoc_entry_init(struct phy_dm_struct *dm);
+
+void *phydm_get_structure(struct phy_dm_struct *dm, u8 structure_type);
+
+/*===========================================================*/
+/* The following is for compile only*/
+/*===========================================================*/
+
+#define IS_HARDWARE_TYPE_8188E(_adapter) false
+#define IS_HARDWARE_TYPE_8188F(_adapter) false
+#define IS_HARDWARE_TYPE_8703B(_adapter) false
+#define IS_HARDWARE_TYPE_8723D(_adapter) false
+#define IS_HARDWARE_TYPE_8821C(_adapter) false
+#define IS_HARDWARE_TYPE_8812AU(_adapter) false
+#define IS_HARDWARE_TYPE_8814A(_adapter) false
+#define IS_HARDWARE_TYPE_8814AU(_adapter) false
+#define IS_HARDWARE_TYPE_8814AE(_adapter) false
+#define IS_HARDWARE_TYPE_8814AS(_adapter) false
+#define IS_HARDWARE_TYPE_8723BU(_adapter) false
+#define IS_HARDWARE_TYPE_8822BU(_adapter) false
+#define IS_HARDWARE_TYPE_8822BS(_adapter) false
+#define IS_HARDWARE_TYPE_JAGUAR(_adapter) \
+ (IS_HARDWARE_TYPE_8812(_adapter) || IS_HARDWARE_TYPE_8821(_adapter))
+#define IS_HARDWARE_TYPE_8723AE(_adapter) false
+#define IS_HARDWARE_TYPE_8192C(_adapter) false
+#define IS_HARDWARE_TYPE_8192D(_adapter) false
+#define RF_T_METER_92D 0x42
+
+#define GET_RX_STATUS_DESC_RX_MCS(__prx_status_desc) \
+ LE_BITS_TO_1BYTE(__prx_status_desc + 12, 0, 6)
+
+#define REG_CONFIG_RAM64X16 0xb2c
+
+#define TARGET_CHNL_NUM_2G_5G 59
+
+/* *********************************************************** */
+
+void odm_dtc(struct phy_dm_struct *dm);
+
+void phydm_noisy_detection(struct phy_dm_struct *dm);
+
+void phydm_set_ext_switch(void *dm_void, u32 *const dm_value, u32 *_used,
+ char *output, u32 *_out_len);
+
+void phydm_api_debug(void *dm_void, u32 function_map, u32 *const dm_value,
+ u32 *_used, char *output, u32 *_out_len);
+
+u8 phydm_nbi_setting(void *dm_void, u32 enable, u32 channel, u32 bw,
+ u32 f_interference, u32 second_ch);
+#endif /* __HALDMOUTSRC_H__ */
diff --git a/drivers/staging/rtlwifi/phydm/phydm_acs.c b/drivers/staging/rtlwifi/phydm/phydm_acs.c
new file mode 100644
index 0000000..eae5a0a
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_acs.c
@@ -0,0 +1,200 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+/* ************************************************************
+ * include files
+ * *************************************************************/
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+u8 odm_get_auto_channel_select_result(void *dm_void, u8 band)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct acs_info *acs = &dm->dm_acs;
+ u8 result;
+
+ if (band == ODM_BAND_2_4G) {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_ACS,
+ "[struct acs_info] %s(): clean_channel_2g(%d)\n",
+ __func__, acs->clean_channel_2g);
+ result = (u8)acs->clean_channel_2g;
+ } else {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_ACS,
+ "[struct acs_info] %s(): clean_channel_5g(%d)\n",
+ __func__, acs->clean_channel_5g);
+ result = (u8)acs->clean_channel_5g;
+ }
+
+ return result;
+}
+
+static void odm_auto_channel_select_setting(void *dm_void, bool is_enable)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u16 period = 0x2710; /* 40ms in default */
+ u16 nhm_type = 0x7;
+
+ ODM_RT_TRACE(dm, ODM_COMP_ACS, "%s()=========>\n", __func__);
+
+ if (is_enable) {
+ /* 20 ms */
+ period = 0x1388;
+ nhm_type = 0x1;
+ }
+
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ /* PHY parameters initialize for ac series */
+
+ /* 0x990[31:16]=0x2710
+ * Time duration for NHM unit: 4us, 0x2710=40ms
+ */
+ odm_write_2byte(dm, ODM_REG_CCX_PERIOD_11AC + 2, period);
+ } else if (dm->support_ic_type & ODM_IC_11N_SERIES) {
+ /* PHY parameters initialize for n series */
+
+ /* 0x894[31:16]=0x2710
+ * Time duration for NHM unit: 4us, 0x2710=40ms
+ */
+ odm_write_2byte(dm, ODM_REG_CCX_PERIOD_11N + 2, period);
+ }
+}
+
+void odm_auto_channel_select_init(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct acs_info *acs = &dm->dm_acs;
+ u8 i;
+
+ if (!(dm->support_ability & ODM_BB_NHM_CNT))
+ return;
+
+ if (acs->is_force_acs_result)
+ return;
+
+ ODM_RT_TRACE(dm, ODM_COMP_ACS, "%s()=========>\n", __func__);
+
+ acs->clean_channel_2g = 1;
+ acs->clean_channel_5g = 36;
+
+ for (i = 0; i < ODM_MAX_CHANNEL_2G; ++i) {
+ acs->channel_info_2g[0][i] = 0;
+ acs->channel_info_2g[1][i] = 0;
+ }
+
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ for (i = 0; i < ODM_MAX_CHANNEL_5G; ++i) {
+ acs->channel_info_5g[0][i] = 0;
+ acs->channel_info_5g[1][i] = 0;
+ }
+ }
+}
+
+void odm_auto_channel_select_reset(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct acs_info *acs = &dm->dm_acs;
+
+ if (!(dm->support_ability & ODM_BB_NHM_CNT))
+ return;
+
+ if (acs->is_force_acs_result)
+ return;
+
+ ODM_RT_TRACE(dm, ODM_COMP_ACS, "%s()=========>\n", __func__);
+
+ odm_auto_channel_select_setting(dm, true); /* for 20ms measurement */
+ phydm_nhm_counter_statistics_reset(dm);
+}
+
+void odm_auto_channel_select(void *dm_void, u8 channel)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct acs_info *acs = &dm->dm_acs;
+ u8 channel_idx = 0, search_idx = 0;
+ u16 max_score = 0;
+
+ if (!(dm->support_ability & ODM_BB_NHM_CNT)) {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "%s(): Return: support_ability ODM_BB_NHM_CNT is disabled\n",
+ __func__);
+ return;
+ }
+
+ if (acs->is_force_acs_result) {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "%s(): Force 2G clean channel = %d, 5G clean channel = %d\n",
+ __func__, acs->clean_channel_2g, acs->clean_channel_5g);
+ return;
+ }
+
+ ODM_RT_TRACE(dm, ODM_COMP_ACS, "%s(): channel = %d=========>\n",
+ __func__, channel);
+
+ phydm_get_nhm_counter_statistics(dm);
+ odm_auto_channel_select_setting(dm, false);
+
+ if (channel >= 1 && channel <= 14) {
+ channel_idx = channel - 1;
+ acs->channel_info_2g[1][channel_idx]++;
+
+ if (acs->channel_info_2g[1][channel_idx] >= 2)
+ acs->channel_info_2g[0][channel_idx] =
+ (acs->channel_info_2g[0][channel_idx] >> 1) +
+ (acs->channel_info_2g[0][channel_idx] >> 2) +
+ (dm->nhm_cnt_0 >> 2);
+ else
+ acs->channel_info_2g[0][channel_idx] = dm->nhm_cnt_0;
+
+ ODM_RT_TRACE(dm, ODM_COMP_ACS, "%s(): nhm_cnt_0 = %d\n",
+ __func__, dm->nhm_cnt_0);
+ ODM_RT_TRACE(
+ dm, ODM_COMP_ACS,
+ "%s(): Channel_Info[0][%d] = %d, Channel_Info[1][%d] = %d\n",
+ __func__, channel_idx,
+ acs->channel_info_2g[0][channel_idx], channel_idx,
+ acs->channel_info_2g[1][channel_idx]);
+
+ for (search_idx = 0; search_idx < ODM_MAX_CHANNEL_2G;
+ search_idx++) {
+ if (acs->channel_info_2g[1][search_idx] != 0 &&
+ acs->channel_info_2g[0][search_idx] >= max_score) {
+ max_score = acs->channel_info_2g[0][search_idx];
+ acs->clean_channel_2g = search_idx + 1;
+ }
+ }
+ ODM_RT_TRACE(
+ dm, ODM_COMP_ACS,
+ "(1)%s(): 2G: clean_channel_2g = %d, max_score = %d\n",
+ __func__, acs->clean_channel_2g, max_score);
+
+ } else if (channel >= 36) {
+ /* Need to do */
+ acs->clean_channel_5g = channel;
+ }
+}
diff --git a/drivers/staging/rtlwifi/phydm/phydm_acs.h b/drivers/staging/rtlwifi/phydm/phydm_acs.h
new file mode 100644
index 0000000..51d72b7
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_acs.h
@@ -0,0 +1,57 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __PHYDMACS_H__
+#define __PHYDMACS_H__
+
+#define ACS_VERSION "1.1" /*20150729 by YuChen*/
+#define CLM_VERSION "1.0"
+
+#define ODM_MAX_CHANNEL_2G 14
+#define ODM_MAX_CHANNEL_5G 24
+
+/* For phydm_auto_channel_select_setting_ap() */
+#define STORE_DEFAULT_NHM_SETTING 0
+#define RESTORE_DEFAULT_NHM_SETTING 1
+#define ACS_NHM_SETTING 2
+
+struct acs_info {
+ bool is_force_acs_result;
+ u8 clean_channel_2g;
+ u8 clean_channel_5g;
+ /* channel_info[1]: channel score, channel_info[2]:channel_scan_times */
+ u16 channel_info_2g[2][ODM_MAX_CHANNEL_2G];
+ u16 channel_info_5g[2][ODM_MAX_CHANNEL_5G];
+};
+
+void odm_auto_channel_select_init(void *dm_void);
+
+void odm_auto_channel_select_reset(void *dm_void);
+
+void odm_auto_channel_select(void *dm_void, u8 channel);
+
+u8 odm_get_auto_channel_select_result(void *dm_void, u8 band);
+
+#endif /* #ifndef __PHYDMACS_H__ */
diff --git a/drivers/staging/rtlwifi/phydm/phydm_adaptivity.c b/drivers/staging/rtlwifi/phydm/phydm_adaptivity.c
new file mode 100644
index 0000000..4f9e267
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_adaptivity.c
@@ -0,0 +1,941 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+/* ************************************************************
+ * include files
+ * *************************************************************/
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+void phydm_check_adaptivity(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct adaptivity_statistics *adaptivity =
+ (struct adaptivity_statistics *)phydm_get_structure(
+ dm, PHYDM_ADAPTIVITY);
+
+ if (dm->support_ability & ODM_BB_ADAPTIVITY) {
+ if (adaptivity->dynamic_link_adaptivity ||
+ adaptivity->acs_for_adaptivity) {
+ if (dm->is_linked && !adaptivity->is_check) {
+ phydm_nhm_counter_statistics(dm);
+ phydm_check_environment(dm);
+ } else if (!dm->is_linked) {
+ adaptivity->is_check = false;
+ }
+ } else {
+ dm->adaptivity_enable = true;
+
+ if (dm->support_ic_type & (ODM_IC_11AC_GAIN_IDX_EDCCA |
+ ODM_IC_11N_GAIN_IDX_EDCCA))
+ dm->adaptivity_flag = false;
+ else
+ dm->adaptivity_flag = true;
+ }
+ } else {
+ dm->adaptivity_enable = false;
+ dm->adaptivity_flag = false;
+ }
+}
+
+void phydm_nhm_counter_statistics_init(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ if (dm->support_ic_type & ODM_IC_11N_SERIES) {
+ /*PHY parameters initialize for n series*/
+
+ /*0x894[31:16]=0x0xC350
+ *Time duration for NHM unit: us, 0xc350=200ms
+ */
+ odm_write_2byte(dm, ODM_REG_CCX_PERIOD_11N + 2, 0xC350);
+ /*0x890[31:16]=0xffff th_9, th_10*/
+ odm_write_2byte(dm, ODM_REG_NHM_TH9_TH10_11N + 2, 0xffff);
+ /*0x898=0xffffff52 th_3, th_2, th_1, th_0*/
+ odm_write_4byte(dm, ODM_REG_NHM_TH3_TO_TH0_11N, 0xffffff50);
+ /*0x89c=0xffffffff th_7, th_6, th_5, th_4*/
+ odm_write_4byte(dm, ODM_REG_NHM_TH7_TO_TH4_11N, 0xffffffff);
+ /*0xe28[7:0]=0xff th_8*/
+ odm_set_bb_reg(dm, ODM_REG_FPGA0_IQK_11N, MASKBYTE0, 0xff);
+ /*0x890[10:8]=1 ignoreCCA ignore PHYTXON enable CCX*/
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11N,
+ BIT(10) | BIT(9) | BIT(8), 0x1);
+ /*0xc0c[7]=1 max power among all RX ants*/
+ odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTC_11N, BIT(7), 0x1);
+ } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ /*PHY parameters initialize for ac series*/
+
+ odm_write_2byte(dm, ODM_REG_CCX_PERIOD_11AC + 2, 0xC350);
+ /*0x994[31:16]=0xffff th_9, th_10*/
+ odm_write_2byte(dm, ODM_REG_NHM_TH9_TH10_11AC + 2, 0xffff);
+ /*0x998=0xffffff52 th_3, th_2, th_1, th_0*/
+ odm_write_4byte(dm, ODM_REG_NHM_TH3_TO_TH0_11AC, 0xffffff50);
+ /*0x99c=0xffffffff th_7, th_6, th_5, th_4*/
+ odm_write_4byte(dm, ODM_REG_NHM_TH7_TO_TH4_11AC, 0xffffffff);
+ /*0x9a0[7:0]=0xff th_8*/
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH8_11AC, MASKBYTE0, 0xff);
+ /*0x994[10:8]=1 ignoreCCA ignore PHYTXON enable CCX*/
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11AC,
+ BIT(8) | BIT(9) | BIT(10), 0x1);
+ /*0x9e8[7]=1 max power among all RX ants*/
+ odm_set_bb_reg(dm, ODM_REG_NHM_9E8_11AC, BIT(0), 0x1);
+ }
+}
+
+void phydm_nhm_counter_statistics(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ if (!(dm->support_ability & ODM_BB_NHM_CNT))
+ return;
+
+ /*Get NHM report*/
+ phydm_get_nhm_counter_statistics(dm);
+
+ /*Reset NHM counter*/
+ phydm_nhm_counter_statistics_reset(dm);
+}
+
+void phydm_get_nhm_counter_statistics(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 value32 = 0;
+
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES)
+ value32 = odm_get_bb_reg(dm, ODM_REG_NHM_CNT_11AC, MASKDWORD);
+ else if (dm->support_ic_type & ODM_IC_11N_SERIES)
+ value32 = odm_get_bb_reg(dm, ODM_REG_NHM_CNT_11N, MASKDWORD);
+
+ dm->nhm_cnt_0 = (u8)(value32 & MASKBYTE0);
+ dm->nhm_cnt_1 = (u8)((value32 & MASKBYTE1) >> 8);
+}
+
+void phydm_nhm_counter_statistics_reset(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ if (dm->support_ic_type & ODM_IC_11N_SERIES) {
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11N, BIT(1), 0);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11N, BIT(1), 1);
+ } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(1), 0);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(1), 1);
+ }
+}
+
+void phydm_set_edcca_threshold(void *dm_void, s8 H2L, s8 L2H)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ if (dm->support_ic_type & ODM_IC_11N_SERIES)
+ odm_set_bb_reg(dm, REG_OFDM_0_ECCA_THRESHOLD,
+ MASKBYTE2 | MASKBYTE0,
+ (u32)((u8)L2H | (u8)H2L << 16));
+ else if (dm->support_ic_type & ODM_IC_11AC_SERIES)
+ odm_set_bb_reg(dm, REG_FPGA0_XB_LSSI_READ_BACK, MASKLWORD,
+ (u16)((u8)L2H | (u8)H2L << 8));
+}
+
+static void phydm_set_lna(void *dm_void, enum phydm_set_lna type)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ if (dm->support_ic_type & (ODM_RTL8188E | ODM_RTL8192E)) {
+ if (type == phydm_disable_lna) {
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x30, 0xfffff,
+ 0x18000); /*select Rx mode*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x31, 0xfffff,
+ 0x0000f);
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x32, 0xfffff,
+ 0x37f82); /*disable LNA*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
+ if (dm->rf_type > ODM_1T1R) {
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, 0x80000,
+ 0x1);
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x30, 0xfffff,
+ 0x18000);
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x31, 0xfffff,
+ 0x0000f);
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x32, 0xfffff,
+ 0x37f82);
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, 0x80000,
+ 0x0);
+ }
+ } else if (type == phydm_enable_lna) {
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x30, 0xfffff,
+ 0x18000); /*select Rx mode*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x31, 0xfffff,
+ 0x0000f);
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x32, 0xfffff,
+ 0x77f82); /*back to normal*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
+ if (dm->rf_type > ODM_1T1R) {
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, 0x80000,
+ 0x1);
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x30, 0xfffff,
+ 0x18000);
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x31, 0xfffff,
+ 0x0000f);
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x32, 0xfffff,
+ 0x77f82);
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, 0x80000,
+ 0x0);
+ }
+ }
+ } else if (dm->support_ic_type & ODM_RTL8723B) {
+ if (type == phydm_disable_lna) {
+ /*S0*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x30, 0xfffff,
+ 0x18000); /*select Rx mode*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x31, 0xfffff,
+ 0x0001f);
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x32, 0xfffff,
+ 0xe6137); /*disable LNA*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
+ /*S1*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xed, 0x00020, 0x1);
+ odm_set_rf_reg(
+ dm, ODM_RF_PATH_A, 0x43, 0xfffff,
+ 0x3008d); /*select Rx mode and disable LNA*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xed, 0x00020, 0x0);
+ } else if (type == phydm_enable_lna) {
+ /*S0*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x30, 0xfffff,
+ 0x18000); /*select Rx mode*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x31, 0xfffff,
+ 0x0001f);
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x32, 0xfffff,
+ 0xe6177); /*disable LNA*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
+ /*S1*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xed, 0x00020, 0x1);
+ odm_set_rf_reg(
+ dm, ODM_RF_PATH_A, 0x43, 0xfffff,
+ 0x300bd); /*select Rx mode and disable LNA*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xed, 0x00020, 0x0);
+ }
+
+ } else if (dm->support_ic_type & ODM_RTL8812) {
+ if (type == phydm_disable_lna) {
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x30, 0xfffff,
+ 0x18000); /*select Rx mode*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x31, 0xfffff,
+ 0x3f7ff);
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x32, 0xfffff,
+ 0xc22bf); /*disable LNA*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
+ if (dm->rf_type > ODM_1T1R) {
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, 0x80000,
+ 0x1);
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x30, 0xfffff,
+ 0x18000); /*select Rx mode*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x31, 0xfffff,
+ 0x3f7ff);
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x32, 0xfffff,
+ 0xc22bf); /*disable LNA*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, 0x80000,
+ 0x0);
+ }
+ } else if (type == phydm_enable_lna) {
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x30, 0xfffff,
+ 0x18000); /*select Rx mode*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x31, 0xfffff,
+ 0x3f7ff);
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x32, 0xfffff,
+ 0xc26bf); /*disable LNA*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
+ if (dm->rf_type > ODM_1T1R) {
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, 0x80000,
+ 0x1);
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x30, 0xfffff,
+ 0x18000); /*select Rx mode*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x31, 0xfffff,
+ 0x3f7ff);
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x32, 0xfffff,
+ 0xc26bf); /*disable LNA*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, 0x80000,
+ 0x0);
+ }
+ }
+ } else if (dm->support_ic_type & (ODM_RTL8821 | ODM_RTL8881A)) {
+ if (type == phydm_disable_lna) {
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x30, 0xfffff,
+ 0x18000); /*select Rx mode*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x31, 0xfffff,
+ 0x0002f);
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x32, 0xfffff,
+ 0xfb09b); /*disable LNA*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
+ } else if (type == phydm_enable_lna) {
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x30, 0xfffff,
+ 0x18000); /*select Rx mode*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x31, 0xfffff,
+ 0x0002f);
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x32, 0xfffff,
+ 0xfb0bb); /*disable LNA*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
+ }
+ }
+}
+
+void phydm_set_trx_mux(void *dm_void, enum phydm_trx_mux_type tx_mode,
+ enum phydm_trx_mux_type rx_mode)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ if (dm->support_ic_type & ODM_IC_11N_SERIES) {
+ /*set TXmod to standby mode to remove outside noise affect*/
+ odm_set_bb_reg(dm, ODM_REG_CCK_RPT_FORMAT_11N,
+ BIT(3) | BIT(2) | BIT(1), tx_mode);
+ /*set RXmod to standby mode to remove outside noise affect*/
+ odm_set_bb_reg(dm, ODM_REG_CCK_RPT_FORMAT_11N,
+ BIT(22) | BIT(21) | BIT(20), rx_mode);
+ if (dm->rf_type > ODM_1T1R) {
+ /*set TXmod to standby mode to rm outside noise affect*/
+ odm_set_bb_reg(dm, ODM_REG_CCK_RPT_FORMAT_11N_B,
+ BIT(3) | BIT(2) | BIT(1), tx_mode);
+ /*set RXmod to standby mode to rm outside noise affect*/
+ odm_set_bb_reg(dm, ODM_REG_CCK_RPT_FORMAT_11N_B,
+ BIT(22) | BIT(21) | BIT(20), rx_mode);
+ }
+ } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ /*set TXmod to standby mode to remove outside noise affect*/
+ odm_set_bb_reg(dm, ODM_REG_TRMUX_11AC,
+ BIT(11) | BIT(10) | BIT(9) | BIT(8), tx_mode);
+ /*set RXmod to standby mode to remove outside noise affect*/
+ odm_set_bb_reg(dm, ODM_REG_TRMUX_11AC,
+ BIT(7) | BIT(6) | BIT(5) | BIT(4), rx_mode);
+ if (dm->rf_type > ODM_1T1R) {
+ /*set TXmod to standby mode to rm outside noise affect*/
+ odm_set_bb_reg(dm, ODM_REG_TRMUX_11AC_B,
+ BIT(11) | BIT(10) | BIT(9) | BIT(8),
+ tx_mode);
+ /*set RXmod to standby mode to rm outside noise affect*/
+ odm_set_bb_reg(dm, ODM_REG_TRMUX_11AC_B,
+ BIT(7) | BIT(6) | BIT(5) | BIT(4),
+ rx_mode);
+ }
+ }
+}
+
+void phydm_mac_edcca_state(void *dm_void, enum phydm_mac_edcca_type state)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ if (state == phydm_ignore_edcca) {
+ /*ignore EDCCA reg520[15]=1*/
+ odm_set_mac_reg(dm, REG_TX_PTCL_CTRL, BIT(15), 1);
+ } else { /*don't set MAC ignore EDCCA signal*/
+ /*don't ignore EDCCA reg520[15]=0*/
+ odm_set_mac_reg(dm, REG_TX_PTCL_CTRL, BIT(15), 0);
+ }
+ ODM_RT_TRACE(dm, PHYDM_COMP_ADAPTIVITY, "EDCCA enable state = %d\n",
+ state);
+}
+
+bool phydm_cal_nhm_cnt(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u16 base = 0;
+
+ base = dm->nhm_cnt_0 + dm->nhm_cnt_1;
+
+ if (base != 0) {
+ dm->nhm_cnt_0 = ((dm->nhm_cnt_0) << 8) / base;
+ dm->nhm_cnt_1 = ((dm->nhm_cnt_1) << 8) / base;
+ }
+ if ((dm->nhm_cnt_0 - dm->nhm_cnt_1) >= 100)
+ return true; /*clean environment*/
+ else
+ return false; /*noisy environment*/
+}
+
+void phydm_check_environment(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct adaptivity_statistics *adaptivity =
+ (struct adaptivity_statistics *)phydm_get_structure(
+ dm, PHYDM_ADAPTIVITY);
+ bool is_clean_environment = false;
+
+ if (adaptivity->is_first_link) {
+ if (dm->support_ic_type &
+ (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA))
+ dm->adaptivity_flag = false;
+ else
+ dm->adaptivity_flag = true;
+
+ adaptivity->is_first_link = false;
+ return;
+ }
+
+ if (adaptivity->nhm_wait < 3) { /*Start enter NHM after 4 nhm_wait*/
+ adaptivity->nhm_wait++;
+ phydm_nhm_counter_statistics(dm);
+ return;
+ }
+
+ phydm_nhm_counter_statistics(dm);
+ is_clean_environment = phydm_cal_nhm_cnt(dm);
+
+ if (is_clean_environment) {
+ dm->th_l2h_ini =
+ adaptivity->th_l2h_ini_backup; /*adaptivity mode*/
+ dm->th_edcca_hl_diff = adaptivity->th_edcca_hl_diff_backup;
+
+ dm->adaptivity_enable = true;
+
+ if (dm->support_ic_type &
+ (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA))
+ dm->adaptivity_flag = false;
+ else
+ dm->adaptivity_flag = true;
+ } else {
+ if (!adaptivity->acs_for_adaptivity) {
+ dm->th_l2h_ini = dm->th_l2h_ini_mode2; /*mode2*/
+ dm->th_edcca_hl_diff = dm->th_edcca_hl_diff_mode2;
+
+ dm->adaptivity_flag = false;
+ dm->adaptivity_enable = false;
+ }
+ }
+
+ adaptivity->nhm_wait = 0;
+ adaptivity->is_first_link = true;
+ adaptivity->is_check = true;
+}
+
+void phydm_search_pwdb_lower_bound(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct adaptivity_statistics *adaptivity =
+ (struct adaptivity_statistics *)phydm_get_structure(
+ dm, PHYDM_ADAPTIVITY);
+ u32 value32 = 0, reg_value32 = 0;
+ u8 cnt, try_count = 0;
+ u8 tx_edcca1 = 0, tx_edcca0 = 0;
+ bool is_adjust = true;
+ s8 th_l2h_dmc, th_h2l_dmc, igi_target = 0x32;
+ s8 diff;
+ u8 IGI = adaptivity->igi_base + 30 + (u8)dm->th_l2h_ini -
+ (u8)dm->th_edcca_hl_diff;
+
+ if (dm->support_ic_type & (ODM_RTL8723B | ODM_RTL8188E | ODM_RTL8192E |
+ ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8881A)) {
+ phydm_set_lna(dm, phydm_disable_lna);
+ } else {
+ phydm_set_trx_mux(dm, phydm_standby_mode, phydm_standby_mode);
+ odm_pause_dig(dm, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_0, 0x7e);
+ }
+
+ diff = igi_target - (s8)IGI;
+ th_l2h_dmc = dm->th_l2h_ini + diff;
+ if (th_l2h_dmc > 10)
+ th_l2h_dmc = 10;
+ th_h2l_dmc = th_l2h_dmc - dm->th_edcca_hl_diff;
+
+ phydm_set_edcca_threshold(dm, th_h2l_dmc, th_l2h_dmc);
+ ODM_delay_ms(30);
+
+ while (is_adjust) {
+ if (dm->support_ic_type & ODM_IC_11N_SERIES) {
+ odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11N, MASKDWORD, 0x0);
+ reg_value32 =
+ odm_get_bb_reg(dm, ODM_REG_RPT_11N, MASKDWORD);
+ } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD,
+ 0x0);
+ reg_value32 =
+ odm_get_bb_reg(dm, ODM_REG_RPT_11AC, MASKDWORD);
+ }
+ while (reg_value32 & BIT(3) && try_count < 3) {
+ ODM_delay_ms(3);
+ try_count = try_count + 1;
+ if (dm->support_ic_type & ODM_IC_11N_SERIES)
+ reg_value32 = odm_get_bb_reg(
+ dm, ODM_REG_RPT_11N, MASKDWORD);
+ else if (dm->support_ic_type & ODM_IC_11AC_SERIES)
+ reg_value32 = odm_get_bb_reg(
+ dm, ODM_REG_RPT_11AC, MASKDWORD);
+ }
+ try_count = 0;
+
+ for (cnt = 0; cnt < 20; cnt++) {
+ if (dm->support_ic_type & ODM_IC_11N_SERIES) {
+ odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11N,
+ MASKDWORD, 0x208);
+ value32 = odm_get_bb_reg(dm, ODM_REG_RPT_11N,
+ MASKDWORD);
+ } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11AC,
+ MASKDWORD, 0x209);
+ value32 = odm_get_bb_reg(dm, ODM_REG_RPT_11AC,
+ MASKDWORD);
+ }
+ if (value32 & BIT(30) &&
+ (dm->support_ic_type &
+ (ODM_RTL8723B | ODM_RTL8188E)))
+ tx_edcca1 = tx_edcca1 + 1;
+ else if (value32 & BIT(29))
+ tx_edcca1 = tx_edcca1 + 1;
+ else
+ tx_edcca0 = tx_edcca0 + 1;
+ }
+
+ if (tx_edcca1 > 1) {
+ IGI = IGI - 1;
+ th_l2h_dmc = th_l2h_dmc + 1;
+ if (th_l2h_dmc > 10)
+ th_l2h_dmc = 10;
+ th_h2l_dmc = th_l2h_dmc - dm->th_edcca_hl_diff;
+
+ phydm_set_edcca_threshold(dm, th_h2l_dmc, th_l2h_dmc);
+ if (th_l2h_dmc == 10) {
+ is_adjust = false;
+ adaptivity->h2l_lb = th_h2l_dmc;
+ adaptivity->l2h_lb = th_l2h_dmc;
+ dm->adaptivity_igi_upper = IGI;
+ }
+
+ tx_edcca1 = 0;
+ tx_edcca0 = 0;
+
+ } else {
+ is_adjust = false;
+ adaptivity->h2l_lb = th_h2l_dmc;
+ adaptivity->l2h_lb = th_l2h_dmc;
+ dm->adaptivity_igi_upper = IGI;
+ tx_edcca1 = 0;
+ tx_edcca0 = 0;
+ }
+ }
+
+ dm->adaptivity_igi_upper = dm->adaptivity_igi_upper - dm->dc_backoff;
+ adaptivity->h2l_lb = adaptivity->h2l_lb + dm->dc_backoff;
+ adaptivity->l2h_lb = adaptivity->l2h_lb + dm->dc_backoff;
+
+ if (dm->support_ic_type & (ODM_RTL8723B | ODM_RTL8188E | ODM_RTL8192E |
+ ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8881A)) {
+ phydm_set_lna(dm, phydm_enable_lna);
+ } else {
+ phydm_set_trx_mux(dm, phydm_tx_mode, phydm_rx_mode);
+ odm_pause_dig(dm, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_0, NONE);
+ }
+
+ phydm_set_edcca_threshold(dm, 0x7f, 0x7f); /*resume to no link state*/
+}
+
+static bool phydm_re_search_condition(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u8 adaptivity_igi_upper;
+ u8 count = 0;
+
+ adaptivity_igi_upper = dm->adaptivity_igi_upper + dm->dc_backoff;
+
+ if (adaptivity_igi_upper <= 0x26 && count < 3) {
+ count = count + 1;
+ return true;
+ }
+
+ return false;
+}
+
+void phydm_adaptivity_info_init(void *dm_void, enum phydm_adapinfo cmn_info,
+ u32 value)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct adaptivity_statistics *adaptivity =
+ (struct adaptivity_statistics *)phydm_get_structure(
+ dm, PHYDM_ADAPTIVITY);
+
+ switch (cmn_info) {
+ case PHYDM_ADAPINFO_CARRIER_SENSE_ENABLE:
+ dm->carrier_sense_enable = (bool)value;
+ break;
+
+ case PHYDM_ADAPINFO_DCBACKOFF:
+ dm->dc_backoff = (u8)value;
+ break;
+
+ case PHYDM_ADAPINFO_DYNAMICLINKADAPTIVITY:
+ adaptivity->dynamic_link_adaptivity = (bool)value;
+ break;
+
+ case PHYDM_ADAPINFO_TH_L2H_INI:
+ dm->th_l2h_ini = (s8)value;
+ break;
+
+ case PHYDM_ADAPINFO_TH_EDCCA_HL_DIFF:
+ dm->th_edcca_hl_diff = (s8)value;
+ break;
+
+ case PHYDM_ADAPINFO_AP_NUM_TH:
+ adaptivity->ap_num_th = (u8)value;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void phydm_adaptivity_init(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct adaptivity_statistics *adaptivity =
+ (struct adaptivity_statistics *)phydm_get_structure(
+ dm, PHYDM_ADAPTIVITY);
+ s8 igi_target = 0x32;
+
+ if (!dm->carrier_sense_enable) {
+ if (dm->th_l2h_ini == 0)
+ dm->th_l2h_ini = 0xf5;
+ } else {
+ dm->th_l2h_ini = 0xa;
+ }
+
+ if (dm->th_edcca_hl_diff == 0)
+ dm->th_edcca_hl_diff = 7;
+ if (dm->wifi_test || dm->mp_mode) {
+ /*even no adaptivity, we still enable EDCCA, AP use mib ctrl*/
+ dm->edcca_enable = false;
+ } else {
+ dm->edcca_enable = true;
+ }
+
+ dm->adaptivity_igi_upper = 0;
+ dm->adaptivity_enable =
+ false; /*use this flag to decide enable or disable*/
+
+ dm->th_l2h_ini_mode2 = 20;
+ dm->th_edcca_hl_diff_mode2 = 8;
+ adaptivity->th_l2h_ini_backup = dm->th_l2h_ini;
+ adaptivity->th_edcca_hl_diff_backup = dm->th_edcca_hl_diff;
+
+ adaptivity->igi_base = 0x32;
+ adaptivity->igi_target = 0x1c;
+ adaptivity->h2l_lb = 0;
+ adaptivity->l2h_lb = 0;
+ adaptivity->nhm_wait = 0;
+ adaptivity->is_check = false;
+ adaptivity->is_first_link = true;
+ adaptivity->adajust_igi_level = 0;
+ adaptivity->is_stop_edcca = false;
+ adaptivity->backup_h2l = 0;
+ adaptivity->backup_l2h = 0;
+
+ phydm_mac_edcca_state(dm, phydm_dont_ignore_edcca);
+
+ /*Search pwdB lower bound*/
+ if (dm->support_ic_type & ODM_IC_11N_SERIES)
+ odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11N, MASKDWORD, 0x208);
+ else if (dm->support_ic_type & ODM_IC_11AC_SERIES)
+ odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0x209);
+
+ if (dm->support_ic_type & ODM_IC_11N_GAIN_IDX_EDCCA) {
+ if (dm->support_ic_type & ODM_RTL8197F) {
+ /*set to page B1*/
+ odm_set_bb_reg(dm, ODM_REG_PAGE_B1_97F, BIT(30), 0x1);
+ /*0:rx_dfir, 1: dcnf_out, 2 :rx_iq, 3: rx_nbi_nf_out*/
+ odm_set_bb_reg(dm, ODM_REG_EDCCA_DCNF_97F,
+ BIT(27) | BIT(26), 0x1);
+ odm_set_bb_reg(dm, ODM_REG_PAGE_B1_97F, BIT(30), 0x0);
+ } else {
+ /*0:rx_dfir, 1: dcnf_out, 2 :rx_iq, 3: rx_nbi_nf_out*/
+ odm_set_bb_reg(dm, ODM_REG_EDCCA_DCNF_11N,
+ BIT(21) | BIT(20), 0x1);
+ }
+ }
+ /*8814a no need to find pwdB lower bound, maybe*/
+ if (dm->support_ic_type & ODM_IC_11AC_GAIN_IDX_EDCCA) {
+ /*0:rx_dfir, 1: dcnf_out, 2 :rx_iq, 3: rx_nbi_nf_out*/
+ odm_set_bb_reg(dm, ODM_REG_ACBB_EDCCA_ENHANCE,
+ BIT(29) | BIT(28), 0x1);
+ }
+
+ if (!(dm->support_ic_type &
+ (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA))) {
+ phydm_search_pwdb_lower_bound(dm);
+ if (phydm_re_search_condition(dm))
+ phydm_search_pwdb_lower_bound(dm);
+ }
+
+ /*we need to consider PwdB upper bound for 8814 later IC*/
+ adaptivity->adajust_igi_level =
+ (u8)((dm->th_l2h_ini + igi_target) - pwdb_upper_bound +
+ dfir_loss); /*IGI = L2H - PwdB - dfir_loss*/
+
+ ODM_RT_TRACE(
+ dm, PHYDM_COMP_ADAPTIVITY,
+ "th_l2h_ini = 0x%x, th_edcca_hl_diff = 0x%x, adaptivity->adajust_igi_level = 0x%x\n",
+ dm->th_l2h_ini, dm->th_edcca_hl_diff,
+ adaptivity->adajust_igi_level);
+
+ /*Check this later on Windows*/
+ /*phydm_set_edcca_threshold_api(dm, dig_tab->cur_ig_value);*/
+}
+
+void phydm_adaptivity(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct dig_thres *dig_tab = &dm->dm_dig_table;
+ u8 IGI = dig_tab->cur_ig_value;
+ s8 th_l2h_dmc, th_h2l_dmc;
+ s8 diff = 0, igi_target;
+ struct adaptivity_statistics *adaptivity =
+ (struct adaptivity_statistics *)phydm_get_structure(
+ dm, PHYDM_ADAPTIVITY);
+
+ if (!dm->edcca_enable || adaptivity->is_stop_edcca) {
+ ODM_RT_TRACE(dm, PHYDM_COMP_ADAPTIVITY, "Disable EDCCA!!!\n");
+ return;
+ }
+
+ if (!(dm->support_ability & ODM_BB_ADAPTIVITY)) {
+ ODM_RT_TRACE(dm, PHYDM_COMP_ADAPTIVITY,
+ "adaptivity disable, enable EDCCA mode!!!\n");
+ dm->th_l2h_ini = dm->th_l2h_ini_mode2;
+ dm->th_edcca_hl_diff = dm->th_edcca_hl_diff_mode2;
+ }
+
+ ODM_RT_TRACE(dm, PHYDM_COMP_ADAPTIVITY, "%s() =====>\n", __func__);
+ ODM_RT_TRACE(dm, PHYDM_COMP_ADAPTIVITY,
+ "igi_base=0x%x, th_l2h_ini = %d, th_edcca_hl_diff = %d\n",
+ adaptivity->igi_base, dm->th_l2h_ini,
+ dm->th_edcca_hl_diff);
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ /*fix AC series when enable EDCCA hang issue*/
+ odm_set_bb_reg(dm, 0x800, BIT(10), 1); /*ADC_mask disable*/
+ odm_set_bb_reg(dm, 0x800, BIT(10), 0); /*ADC_mask enable*/
+ }
+ if (*dm->band_width == ODM_BW20M) /*CHANNEL_WIDTH_20*/
+ igi_target = adaptivity->igi_base;
+ else if (*dm->band_width == ODM_BW40M)
+ igi_target = adaptivity->igi_base + 2;
+ else if (*dm->band_width == ODM_BW80M)
+ igi_target = adaptivity->igi_base + 2;
+ else
+ igi_target = adaptivity->igi_base;
+ adaptivity->igi_target = (u8)igi_target;
+
+ ODM_RT_TRACE(
+ dm, PHYDM_COMP_ADAPTIVITY,
+ "band_width=%s, igi_target=0x%x, dynamic_link_adaptivity = %d, acs_for_adaptivity = %d\n",
+ (*dm->band_width == ODM_BW80M) ?
+ "80M" :
+ ((*dm->band_width == ODM_BW40M) ? "40M" : "20M"),
+ igi_target, adaptivity->dynamic_link_adaptivity,
+ adaptivity->acs_for_adaptivity);
+ ODM_RT_TRACE(
+ dm, PHYDM_COMP_ADAPTIVITY,
+ "rssi_min = %d, adaptivity->adajust_igi_level= 0x%x, adaptivity_flag = %d, adaptivity_enable = %d\n",
+ dm->rssi_min, adaptivity->adajust_igi_level,
+ dm->adaptivity_flag, dm->adaptivity_enable);
+
+ if (adaptivity->dynamic_link_adaptivity && (!dm->is_linked) &&
+ !dm->adaptivity_enable) {
+ phydm_set_edcca_threshold(dm, 0x7f, 0x7f);
+ ODM_RT_TRACE(
+ dm, PHYDM_COMP_ADAPTIVITY,
+ "In DynamicLink mode(noisy) and No link, Turn off EDCCA!!\n");
+ return;
+ }
+
+ if (dm->support_ic_type &
+ (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA)) {
+ if ((adaptivity->adajust_igi_level > IGI) &&
+ dm->adaptivity_enable)
+ diff = adaptivity->adajust_igi_level - IGI;
+
+ th_l2h_dmc = dm->th_l2h_ini - diff + igi_target;
+ th_h2l_dmc = th_l2h_dmc - dm->th_edcca_hl_diff;
+ } else {
+ diff = igi_target - (s8)IGI;
+ th_l2h_dmc = dm->th_l2h_ini + diff;
+ if (th_l2h_dmc > 10 && dm->adaptivity_enable)
+ th_l2h_dmc = 10;
+
+ th_h2l_dmc = th_l2h_dmc - dm->th_edcca_hl_diff;
+
+ /*replace lower bound to prevent EDCCA always equal 1*/
+ if (th_h2l_dmc < adaptivity->h2l_lb)
+ th_h2l_dmc = adaptivity->h2l_lb;
+ if (th_l2h_dmc < adaptivity->l2h_lb)
+ th_l2h_dmc = adaptivity->l2h_lb;
+ }
+ ODM_RT_TRACE(dm, PHYDM_COMP_ADAPTIVITY,
+ "IGI=0x%x, th_l2h_dmc = %d, th_h2l_dmc = %d\n", IGI,
+ th_l2h_dmc, th_h2l_dmc);
+ ODM_RT_TRACE(
+ dm, PHYDM_COMP_ADAPTIVITY,
+ "adaptivity_igi_upper=0x%x, h2l_lb = 0x%x, l2h_lb = 0x%x\n",
+ dm->adaptivity_igi_upper, adaptivity->h2l_lb,
+ adaptivity->l2h_lb);
+
+ phydm_set_edcca_threshold(dm, th_h2l_dmc, th_l2h_dmc);
+
+ if (dm->adaptivity_enable)
+ odm_set_mac_reg(dm, REG_RD_CTRL, BIT(11), 1);
+}
+
+/*This is for solving USB can't Tx problem due to USB3.0 interference in 2.4G*/
+void phydm_pause_edcca(void *dm_void, bool is_pasue_edcca)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct adaptivity_statistics *adaptivity =
+ (struct adaptivity_statistics *)phydm_get_structure(
+ dm, PHYDM_ADAPTIVITY);
+ struct dig_thres *dig_tab = &dm->dm_dig_table;
+ u8 IGI = dig_tab->cur_ig_value;
+ s8 diff = 0;
+
+ if (is_pasue_edcca) {
+ adaptivity->is_stop_edcca = true;
+
+ if (dm->support_ic_type &
+ (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA)) {
+ if (adaptivity->adajust_igi_level > IGI)
+ diff = adaptivity->adajust_igi_level - IGI;
+
+ adaptivity->backup_l2h =
+ dm->th_l2h_ini - diff + adaptivity->igi_target;
+ adaptivity->backup_h2l =
+ adaptivity->backup_l2h - dm->th_edcca_hl_diff;
+ } else {
+ diff = adaptivity->igi_target - (s8)IGI;
+ adaptivity->backup_l2h = dm->th_l2h_ini + diff;
+ if (adaptivity->backup_l2h > 10)
+ adaptivity->backup_l2h = 10;
+
+ adaptivity->backup_h2l =
+ adaptivity->backup_l2h - dm->th_edcca_hl_diff;
+
+ /*replace lower bound to prevent EDCCA always equal 1*/
+ if (adaptivity->backup_h2l < adaptivity->h2l_lb)
+ adaptivity->backup_h2l = adaptivity->h2l_lb;
+ if (adaptivity->backup_l2h < adaptivity->l2h_lb)
+ adaptivity->backup_l2h = adaptivity->l2h_lb;
+ }
+ ODM_RT_TRACE(
+ dm, PHYDM_COMP_ADAPTIVITY,
+ "pauseEDCCA : L2Hbak = 0x%x, H2Lbak = 0x%x, IGI = 0x%x\n",
+ adaptivity->backup_l2h, adaptivity->backup_h2l, IGI);
+
+ /*Disable EDCCA*/
+ phydm_pause_edcca_work_item_callback(dm);
+
+ } else {
+ adaptivity->is_stop_edcca = false;
+ ODM_RT_TRACE(
+ dm, PHYDM_COMP_ADAPTIVITY,
+ "resumeEDCCA : L2Hbak = 0x%x, H2Lbak = 0x%x, IGI = 0x%x\n",
+ adaptivity->backup_l2h, adaptivity->backup_h2l, IGI);
+ /*Resume EDCCA*/
+ phydm_resume_edcca_work_item_callback(dm);
+ }
+}
+
+void phydm_pause_edcca_work_item_callback(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ if (dm->support_ic_type & ODM_IC_11N_SERIES)
+ odm_set_bb_reg(dm, REG_OFDM_0_ECCA_THRESHOLD,
+ MASKBYTE2 | MASKBYTE0, (u32)(0x7f | 0x7f << 16));
+ else if (dm->support_ic_type & ODM_IC_11AC_SERIES)
+ odm_set_bb_reg(dm, REG_FPGA0_XB_LSSI_READ_BACK, MASKLWORD,
+ (u16)(0x7f | 0x7f << 8));
+}
+
+void phydm_resume_edcca_work_item_callback(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct adaptivity_statistics *adaptivity =
+ (struct adaptivity_statistics *)phydm_get_structure(
+ dm, PHYDM_ADAPTIVITY);
+
+ if (dm->support_ic_type & ODM_IC_11N_SERIES)
+ odm_set_bb_reg(dm, REG_OFDM_0_ECCA_THRESHOLD,
+ MASKBYTE2 | MASKBYTE0,
+ (u32)((u8)adaptivity->backup_l2h |
+ (u8)adaptivity->backup_h2l << 16));
+ else if (dm->support_ic_type & ODM_IC_11AC_SERIES)
+ odm_set_bb_reg(dm, REG_FPGA0_XB_LSSI_READ_BACK, MASKLWORD,
+ (u16)((u8)adaptivity->backup_l2h |
+ (u8)adaptivity->backup_h2l << 8));
+}
+
+void phydm_set_edcca_threshold_api(void *dm_void, u8 IGI)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct adaptivity_statistics *adaptivity =
+ (struct adaptivity_statistics *)phydm_get_structure(
+ dm, PHYDM_ADAPTIVITY);
+ s8 th_l2h_dmc, th_h2l_dmc;
+ s8 diff = 0, igi_target = 0x32;
+
+ if (dm->support_ability & ODM_BB_ADAPTIVITY) {
+ if (dm->support_ic_type &
+ (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA)) {
+ if (adaptivity->adajust_igi_level > IGI)
+ diff = adaptivity->adajust_igi_level - IGI;
+
+ th_l2h_dmc = dm->th_l2h_ini - diff + igi_target;
+ th_h2l_dmc = th_l2h_dmc - dm->th_edcca_hl_diff;
+ } else {
+ diff = igi_target - (s8)IGI;
+ th_l2h_dmc = dm->th_l2h_ini + diff;
+ if (th_l2h_dmc > 10)
+ th_l2h_dmc = 10;
+
+ th_h2l_dmc = th_l2h_dmc - dm->th_edcca_hl_diff;
+
+ /*replace lower bound to prevent EDCCA always equal 1*/
+ if (th_h2l_dmc < adaptivity->h2l_lb)
+ th_h2l_dmc = adaptivity->h2l_lb;
+ if (th_l2h_dmc < adaptivity->l2h_lb)
+ th_l2h_dmc = adaptivity->l2h_lb;
+ }
+ ODM_RT_TRACE(
+ dm, PHYDM_COMP_ADAPTIVITY,
+ "API :IGI=0x%x, th_l2h_dmc = %d, th_h2l_dmc = %d\n",
+ IGI, th_l2h_dmc, th_h2l_dmc);
+ ODM_RT_TRACE(
+ dm, PHYDM_COMP_ADAPTIVITY,
+ "API :adaptivity_igi_upper=0x%x, h2l_lb = 0x%x, l2h_lb = 0x%x\n",
+ dm->adaptivity_igi_upper, adaptivity->h2l_lb,
+ adaptivity->l2h_lb);
+
+ phydm_set_edcca_threshold(dm, th_h2l_dmc, th_l2h_dmc);
+ }
+}
diff --git a/drivers/staging/rtlwifi/phydm/phydm_adaptivity.h b/drivers/staging/rtlwifi/phydm/phydm_adaptivity.h
new file mode 100644
index 0000000..fdb39b4
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_adaptivity.h
@@ -0,0 +1,119 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __PHYDMADAPTIVITY_H__
+#define __PHYDMADAPTIVITY_H__
+
+/*20160902 changed by Kevin, refine method for searching pwdb lower bound*/
+#define ADAPTIVITY_VERSION "9.3.5"
+
+#define pwdb_upper_bound 7
+#define dfir_loss 5
+
+enum phydm_adapinfo {
+ PHYDM_ADAPINFO_CARRIER_SENSE_ENABLE = 0,
+ PHYDM_ADAPINFO_DCBACKOFF,
+ PHYDM_ADAPINFO_DYNAMICLINKADAPTIVITY,
+ PHYDM_ADAPINFO_TH_L2H_INI,
+ PHYDM_ADAPINFO_TH_EDCCA_HL_DIFF,
+ PHYDM_ADAPINFO_AP_NUM_TH
+
+};
+
+enum phydm_set_lna {
+ phydm_disable_lna = 0,
+ phydm_enable_lna = 1,
+};
+
+enum phydm_trx_mux_type {
+ phydm_shutdown = 0,
+ phydm_standby_mode = 1,
+ phydm_tx_mode = 2,
+ phydm_rx_mode = 3
+};
+
+enum phydm_mac_edcca_type {
+ phydm_ignore_edcca = 0,
+ phydm_dont_ignore_edcca = 1
+};
+
+struct adaptivity_statistics {
+ s8 th_l2h_ini_backup;
+ s8 th_edcca_hl_diff_backup;
+ s8 igi_base;
+ u8 igi_target;
+ u8 nhm_wait;
+ s8 h2l_lb;
+ s8 l2h_lb;
+ bool is_first_link;
+ bool is_check;
+ bool dynamic_link_adaptivity;
+ u8 ap_num_th;
+ u8 adajust_igi_level;
+ bool acs_for_adaptivity;
+ s8 backup_l2h;
+ s8 backup_h2l;
+ bool is_stop_edcca;
+};
+
+void phydm_pause_edcca(void *dm_void, bool is_pasue_edcca);
+
+void phydm_check_adaptivity(void *dm_void);
+
+void phydm_check_environment(void *dm_void);
+
+void phydm_nhm_counter_statistics_init(void *dm_void);
+
+void phydm_nhm_counter_statistics(void *dm_void);
+
+void phydm_nhm_counter_statistics_reset(void *dm_void);
+
+void phydm_get_nhm_counter_statistics(void *dm_void);
+
+void phydm_mac_edcca_state(void *dm_void, enum phydm_mac_edcca_type state);
+
+void phydm_set_edcca_threshold(void *dm_void, s8 H2L, s8 L2H);
+
+void phydm_set_trx_mux(void *dm_void, enum phydm_trx_mux_type tx_mode,
+ enum phydm_trx_mux_type rx_mode);
+
+bool phydm_cal_nhm_cnt(void *dm_void);
+
+void phydm_search_pwdb_lower_bound(void *dm_void);
+
+void phydm_adaptivity_info_init(void *dm_void, enum phydm_adapinfo cmn_info,
+ u32 value);
+
+void phydm_adaptivity_init(void *dm_void);
+
+void phydm_adaptivity(void *dm_void);
+
+void phydm_set_edcca_threshold_api(void *dm_void, u8 IGI);
+
+void phydm_pause_edcca_work_item_callback(void *dm_void);
+
+void phydm_resume_edcca_work_item_callback(void *dm_void);
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/phydm_adc_sampling.c b/drivers/staging/rtlwifi/phydm/phydm_adc_sampling.c
new file mode 100644
index 0000000..158dd5d
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_adc_sampling.c
@@ -0,0 +1,628 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+static bool phydm_la_buffer_allocate(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct rt_adcsmp *adc_smp = &dm->adcsmp;
+ struct rt_adcsmp_string *adc_smp_buf = &adc_smp->adc_smp_buf;
+ bool ret = false;
+
+ ODM_RT_TRACE(dm, ODM_COMP_UNCOND, "[LA mode BufferAllocate]\n");
+
+ if (adc_smp_buf->length == 0) {
+ odm_allocate_memory(dm, (void **)&adc_smp_buf->octet,
+ adc_smp_buf->buffer_size);
+ if (!adc_smp_buf->octet) {
+ ret = false;
+ } else {
+ adc_smp_buf->length = adc_smp_buf->buffer_size;
+ ret = true;
+ }
+ }
+
+ return ret;
+}
+
+static void phydm_la_get_tx_pkt_buf(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct rt_adcsmp *adc_smp = &dm->adcsmp;
+ struct rt_adcsmp_string *adc_smp_buf = &adc_smp->adc_smp_buf;
+ u32 i = 0, value32, data_l = 0, data_h = 0;
+ u32 addr, finish_addr;
+ u32 end_addr = (adc_smp_buf->start_pos + adc_smp_buf->buffer_size) -
+ 1; /*end_addr = 0x3ffff;*/
+ bool is_round_up;
+ static u32 page = 0xFF;
+ u32 smp_cnt = 0, smp_number = 0, addr_8byte = 0;
+
+ odm_memory_set(dm, adc_smp_buf->octet, 0, adc_smp_buf->length);
+ odm_write_1byte(dm, 0x0106, 0x69);
+
+ ODM_RT_TRACE(dm, ODM_COMP_UNCOND, "GetTxPktBuf\n");
+
+ value32 = odm_read_4byte(dm, 0x7c0);
+ is_round_up = (bool)((value32 & BIT(31)) >> 31);
+ /*Reg7C0[30:16]: finish addr (unit: 8byte)*/
+ finish_addr = (value32 & 0x7FFF0000) >> 16;
+
+ if (is_round_up) {
+ addr = (finish_addr + 1) << 3;
+ ODM_RT_TRACE(
+ dm, ODM_COMP_UNCOND,
+ "is_round_up = ((%d)), finish_addr=((0x%x)), 0x7c0=((0x%x))\n",
+ is_round_up, finish_addr, value32);
+ /*Byte to 64Byte*/
+ smp_number = ((adc_smp_buf->buffer_size) >> 3);
+ } else {
+ addr = adc_smp_buf->start_pos;
+
+ addr_8byte = addr >> 3;
+ if (addr_8byte > finish_addr)
+ smp_number = addr_8byte - finish_addr;
+ else
+ smp_number = finish_addr - addr_8byte;
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_UNCOND,
+ "is_round_up = ((%d)), finish_addr=((0x%x * 8Byte)), Start_Addr = ((0x%x * 8Byte)), smp_number = ((%d))\n",
+ is_round_up, finish_addr, addr_8byte, smp_number);
+ }
+
+ if (dm->support_ic_type & ODM_RTL8197F) {
+ /*64K byte*/
+ for (addr = 0x0, i = 0; addr < end_addr; addr += 8, i += 2) {
+ if ((addr & 0xfff) == 0)
+ odm_set_bb_reg(dm, 0x0140, MASKLWORD,
+ 0x780 + (addr >> 12));
+ data_l = odm_get_bb_reg(dm, 0x8000 + (addr & 0xfff),
+ MASKDWORD);
+ data_h = odm_get_bb_reg(dm, 0x8000 + (addr & 0xfff) + 4,
+ MASKDWORD);
+
+ ODM_RT_TRACE(dm, ODM_COMP_UNCOND, "%08x%08x\n", data_h,
+ data_l);
+ }
+ } else {
+ while (addr != (finish_addr << 3)) {
+ if (page != (addr >> 12)) {
+ /*Reg140=0x780+(addr>>12),
+ *addr=0x30~0x3F, total 16 pages
+ */
+ page = (addr >> 12);
+ }
+ odm_set_bb_reg(dm, 0x0140, MASKLWORD, 0x780 + page);
+
+ /*pDataL = 0x8000+(addr&0xfff);*/
+ data_l = odm_get_bb_reg(dm, 0x8000 + (addr & 0xfff),
+ MASKDWORD);
+ data_h = odm_get_bb_reg(dm, 0x8000 + (addr & 0xfff) + 4,
+ MASKDWORD);
+
+ adc_smp_buf->octet[i] = data_h;
+ adc_smp_buf->octet[i + 1] = data_l;
+
+ ODM_RT_TRACE(dm, ODM_COMP_UNCOND, "%08x%08x\n", data_h,
+ data_l);
+
+ i = i + 2;
+
+ if ((addr + 8) >= end_addr)
+ addr = adc_smp_buf->start_pos;
+ else
+ addr = addr + 8;
+
+ smp_cnt++;
+ if (smp_cnt >= (smp_number - 1))
+ break;
+ }
+ ODM_RT_TRACE(dm, ODM_COMP_UNCOND, "smp_cnt = ((%d))\n",
+ smp_cnt);
+ }
+}
+
+static void phydm_la_mode_set_mac_iq_dump(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct rt_adcsmp *adc_smp = &dm->adcsmp;
+ u32 reg_value;
+
+ odm_write_1byte(dm, 0x7c0, 0); /*clear all 0x7c0*/
+ odm_set_mac_reg(dm, 0x7c0, BIT(0), 1); /*Enable LA mode HW block*/
+
+ if (adc_smp->la_trig_mode == PHYDM_MAC_TRIG) {
+ adc_smp->is_bb_trigger = 0;
+ odm_set_mac_reg(dm, 0x7c0, BIT(2),
+ 1); /*polling bit for MAC mode*/
+ odm_set_mac_reg(
+ dm, 0x7c0, BIT(4) | BIT(3),
+ adc_smp->la_trigger_edge); /*trigger mode for MAC*/
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_UNCOND,
+ "[MAC_trig] ref_mask = ((0x%x)), ref_value = ((0x%x)), dbg_port = ((0x%x))\n",
+ adc_smp->la_mac_ref_mask, adc_smp->la_trig_sig_sel,
+ adc_smp->la_dbg_port);
+ /*[Set MAC Debug Port]*/
+ odm_set_mac_reg(dm, 0xF4, BIT(16), 1);
+ odm_set_mac_reg(dm, 0x38, 0xff0000, adc_smp->la_dbg_port);
+ odm_set_mac_reg(dm, 0x7c4, MASKDWORD, adc_smp->la_mac_ref_mask);
+ odm_set_mac_reg(dm, 0x7c8, MASKDWORD, adc_smp->la_trig_sig_sel);
+
+ } else {
+ adc_smp->is_bb_trigger = 1;
+ odm_set_mac_reg(dm, 0x7c0, BIT(1),
+ 1); /*polling bit for BB ADC mode*/
+
+ if (adc_smp->la_trig_mode == PHYDM_ADC_MAC_TRIG) {
+ odm_set_mac_reg(
+ dm, 0x7c0, BIT(3),
+ 1); /*polling bit for MAC trigger event*/
+ odm_set_mac_reg(dm, 0x7c0, BIT(7) | BIT(6),
+ adc_smp->la_trig_sig_sel);
+
+ if (adc_smp->la_trig_sig_sel == ADCSMP_TRIG_REG)
+ odm_set_mac_reg(
+ dm, 0x7c0, BIT(5),
+ 1); /* manual trigger 0x7C0[5] = 0->1*/
+ }
+ }
+
+ reg_value = odm_get_bb_reg(dm, 0x7c0, 0xff);
+ ODM_RT_TRACE(dm, ODM_COMP_UNCOND,
+ "4. [Set MAC IQ dump] 0x7c0[7:0] = ((0x%x))\n", reg_value);
+}
+
+static void phydm_la_mode_set_dma_type(void *dm_void, u8 la_dma_type)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ ODM_RT_TRACE(dm, ODM_COMP_UNCOND,
+ "2. [LA mode DMA setting] Dma_type = ((%d))\n",
+ la_dma_type);
+
+ if (dm->support_ic_type & ODM_N_ANTDIV_SUPPORT)
+ odm_set_bb_reg(dm, 0x9a0, 0xf00, la_dma_type); /*0x9A0[11:8]*/
+ else
+ odm_set_bb_reg(dm, odm_adc_trigger_jaguar2, 0xf00,
+ la_dma_type); /*0x95C[11:8]*/
+}
+
+static void phydm_adc_smp_start(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct rt_adcsmp *adc_smp = &dm->adcsmp;
+ u8 tmp_u1b;
+ u8 while_cnt = 0;
+ u8 polling_ok = false, target_polling_bit;
+
+ phydm_la_mode_bb_setting(dm);
+ phydm_la_mode_set_dma_type(dm, adc_smp->la_dma_type);
+ phydm_la_mode_set_trigger_time(dm, adc_smp->la_trigger_time);
+
+ if (dm->support_ic_type & ODM_RTL8197F) {
+ odm_set_bb_reg(dm, 0xd00, BIT(26), 0x1);
+ } else { /*for 8814A and 8822B?*/
+ odm_write_1byte(dm, 0x198c, 0x7);
+ odm_write_1byte(dm, 0x8b4, 0x80);
+ /* odm_set_bb_reg(dm, 0x8b4, BIT(7), 1); */
+ }
+
+ phydm_la_mode_set_mac_iq_dump(dm);
+ /* return; */
+
+ target_polling_bit = (adc_smp->is_bb_trigger) ? BIT(1) : BIT(2);
+ do { /*Poll time always use 100ms, when it exceed 2s, break while loop*/
+ tmp_u1b = odm_read_1byte(dm, 0x7c0);
+
+ if (adc_smp->adc_smp_state != ADCSMP_STATE_SET) {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_UNCOND,
+ "[state Error] adc_smp_state != ADCSMP_STATE_SET\n");
+ break;
+
+ } else if (tmp_u1b & target_polling_bit) {
+ ODM_delay_ms(100);
+ while_cnt = while_cnt + 1;
+ continue;
+ } else {
+ ODM_RT_TRACE(dm, ODM_COMP_UNCOND,
+ "[LA Query OK] polling_bit=((0x%x))\n",
+ target_polling_bit);
+ polling_ok = true;
+ if (dm->support_ic_type & ODM_RTL8197F)
+ odm_set_bb_reg(dm, 0x7c0, BIT(0), 0x0);
+ break;
+ }
+ } while (while_cnt < 20);
+
+ if (adc_smp->adc_smp_state == ADCSMP_STATE_SET) {
+ if (polling_ok)
+ phydm_la_get_tx_pkt_buf(dm);
+ else
+ ODM_RT_TRACE(dm, ODM_COMP_UNCOND,
+ "[Polling timeout]\n");
+ }
+
+ if (adc_smp->adc_smp_state == ADCSMP_STATE_SET)
+ adc_smp->adc_smp_state = ADCSMP_STATE_QUERY;
+
+ ODM_RT_TRACE(dm, ODM_COMP_UNCOND,
+ "[LA mode] LA_pattern_count = ((%d))\n",
+ adc_smp->la_count);
+
+ adc_smp_stop(dm);
+
+ if (adc_smp->la_count == 0) {
+ ODM_RT_TRACE(dm, ODM_COMP_UNCOND,
+ "LA Dump finished ---------->\n\n\n");
+ /**/
+ } else {
+ adc_smp->la_count--;
+ ODM_RT_TRACE(dm, ODM_COMP_UNCOND,
+ "LA Dump more ---------->\n\n\n");
+ adc_smp_set(dm, adc_smp->la_trig_mode, adc_smp->la_trig_sig_sel,
+ adc_smp->la_dma_type, adc_smp->la_trigger_time, 0);
+ }
+}
+
+void adc_smp_set(void *dm_void, u8 trig_mode, u32 trig_sig_sel,
+ u8 dma_data_sig_sel, u32 trigger_time, u16 polling_time)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ bool is_set_success = true;
+ struct rt_adcsmp *adc_smp = &dm->adcsmp;
+
+ adc_smp->la_trig_mode = trig_mode;
+ adc_smp->la_trig_sig_sel = trig_sig_sel;
+ adc_smp->la_dma_type = dma_data_sig_sel;
+ adc_smp->la_trigger_time = trigger_time;
+
+ if (adc_smp->adc_smp_state != ADCSMP_STATE_IDLE)
+ is_set_success = false;
+ else if (adc_smp->adc_smp_buf.length == 0)
+ is_set_success = phydm_la_buffer_allocate(dm);
+
+ if (is_set_success) {
+ adc_smp->adc_smp_state = ADCSMP_STATE_SET;
+
+ ODM_RT_TRACE(dm, ODM_COMP_UNCOND,
+ "[LA Set Success] LA_State=((%d))\n",
+ adc_smp->adc_smp_state);
+
+ phydm_adc_smp_start(dm);
+ } else {
+ ODM_RT_TRACE(dm, ODM_COMP_UNCOND,
+ "[LA Set Fail] LA_State=((%d))\n",
+ adc_smp->adc_smp_state);
+ }
+}
+
+void adc_smp_query(void *dm_void, void *output, u32 out_len, u32 *pused)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct rt_adcsmp *adc_smp = &dm->adcsmp;
+ struct rt_adcsmp_string *adc_smp_buf = &adc_smp->adc_smp_buf;
+ u32 used = *pused;
+ u32 i;
+
+ ODM_RT_TRACE(dm, ODM_COMP_UNCOND, "%s adc_smp_state %d", __func__,
+ adc_smp->adc_smp_state);
+
+ for (i = 0; i < (adc_smp_buf->length >> 2) - 2; i += 2) {
+ PHYDM_SNPRINTF(output + used, out_len - used, "%08x%08x\n",
+ adc_smp_buf->octet[i],
+ adc_smp_buf->octet[i + 1]);
+ }
+
+ PHYDM_SNPRINTF(output + used, out_len - used, "\n");
+ *pused = used;
+}
+
+s32 adc_smp_get_sample_counts(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct rt_adcsmp *adc_smp = &dm->adcsmp;
+ struct rt_adcsmp_string *adc_smp_buf = &adc_smp->adc_smp_buf;
+
+ return (adc_smp_buf->length >> 2) - 2;
+}
+
+s32 adc_smp_query_single_data(void *dm_void, void *output, u32 out_len,
+ u32 index)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct rt_adcsmp *adc_smp = &dm->adcsmp;
+ struct rt_adcsmp_string *adc_smp_buf = &adc_smp->adc_smp_buf;
+ u32 used = 0;
+
+ if (adc_smp->adc_smp_state != ADCSMP_STATE_QUERY) {
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "Error: la data is not ready yet ...\n");
+ return -1;
+ }
+
+ if (index < ((adc_smp_buf->length >> 2) - 2)) {
+ PHYDM_SNPRINTF(output + used, out_len - used, "%08x%08x\n",
+ adc_smp_buf->octet[index],
+ adc_smp_buf->octet[index + 1]);
+ }
+ return 0;
+}
+
+void adc_smp_stop(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct rt_adcsmp *adc_smp = &dm->adcsmp;
+
+ adc_smp->adc_smp_state = ADCSMP_STATE_IDLE;
+ ODM_RT_TRACE(dm, ODM_COMP_UNCOND, "[LA_Stop] LA_state = ((%d))\n",
+ adc_smp->adc_smp_state);
+}
+
+void adc_smp_init(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct rt_adcsmp *adc_smp = &dm->adcsmp;
+ struct rt_adcsmp_string *adc_smp_buf = &adc_smp->adc_smp_buf;
+
+ adc_smp->adc_smp_state = ADCSMP_STATE_IDLE;
+
+ if (dm->support_ic_type & ODM_RTL8814A) {
+ adc_smp_buf->start_pos = 0x30000;
+ adc_smp_buf->buffer_size = 0x10000;
+ } else if (dm->support_ic_type & ODM_RTL8822B) {
+ adc_smp_buf->start_pos = 0x20000;
+ adc_smp_buf->buffer_size = 0x20000;
+ } else if (dm->support_ic_type & ODM_RTL8197F) {
+ adc_smp_buf->start_pos = 0x00000;
+ adc_smp_buf->buffer_size = 0x10000;
+ } else if (dm->support_ic_type & ODM_RTL8821C) {
+ adc_smp_buf->start_pos = 0x8000;
+ adc_smp_buf->buffer_size = 0x8000;
+ }
+}
+
+void adc_smp_de_init(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct rt_adcsmp *adc_smp = &dm->adcsmp;
+ struct rt_adcsmp_string *adc_smp_buf = &adc_smp->adc_smp_buf;
+
+ adc_smp_stop(dm);
+
+ if (adc_smp_buf->length != 0x0) {
+ odm_free_memory(dm, adc_smp_buf->octet, adc_smp_buf->length);
+ adc_smp_buf->length = 0x0;
+ }
+}
+
+void phydm_la_mode_bb_setting(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct rt_adcsmp *adc_smp = &dm->adcsmp;
+
+ u8 trig_mode = adc_smp->la_trig_mode;
+ u32 trig_sig_sel = adc_smp->la_trig_sig_sel;
+ u32 dbg_port = adc_smp->la_dbg_port;
+ u8 is_trigger_edge = adc_smp->la_trigger_edge;
+ u8 sampling_rate = adc_smp->la_smp_rate;
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_UNCOND,
+ "1. [LA mode bb_setting] trig_mode = ((%d)), dbg_port = ((0x%x)), Trig_Edge = ((%d)), smp_rate = ((%d)), Trig_Sel = ((0x%x))\n",
+ trig_mode, dbg_port, is_trigger_edge, sampling_rate,
+ trig_sig_sel);
+
+ if (trig_mode == PHYDM_MAC_TRIG)
+ trig_sig_sel = 0; /*ignore this setting*/
+
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ if (trig_mode == PHYDM_ADC_RF0_TRIG) {
+ /*DBGOUT_RFC_a[31:0]*/
+ odm_set_bb_reg(dm, 0x8f8,
+ BIT(25) | BIT(24) | BIT(23) | BIT(22),
+ 9);
+ } else if (trig_mode == PHYDM_ADC_RF1_TRIG) {
+ /*DBGOUT_RFC_b[31:0]*/
+ odm_set_bb_reg(dm, 0x8f8,
+ BIT(25) | BIT(24) | BIT(23) | BIT(22),
+ 8);
+ } else {
+ odm_set_bb_reg(dm, 0x8f8,
+ BIT(25) | BIT(24) | BIT(23) | BIT(22),
+ 0);
+ }
+ /*
+ * (0:) '{ofdm_dbg[31:0]}'
+ * (1:) '{cca,crc32_fail,dbg_ofdm[29:0]}'
+ * (2:) '{vbon,crc32_fail,dbg_ofdm[29:0]}'
+ * (3:) '{cca,crc32_ok,dbg_ofdm[29:0]}'
+ * (4:) '{vbon,crc32_ok,dbg_ofdm[29:0]}'
+ * (5:) '{dbg_iqk_anta}'
+ * (6:) '{cca,ofdm_crc_ok,dbg_dp_anta[29:0]}'
+ * (7:) '{dbg_iqk_antb}'
+ * (8:) '{DBGOUT_RFC_b[31:0]}'
+ * (9:) '{DBGOUT_RFC_a[31:0]}'
+ * (a:) '{dbg_ofdm}'
+ * (b:) '{dbg_cck}'
+ */
+
+ /*disable dbg clk gating*/
+ odm_set_bb_reg(dm, 0x198C, BIT(2) | BIT(1) | BIT(0), 7);
+
+ /*0x95C[4:0], BB debug port bit*/
+ odm_set_bb_reg(dm, 0x95C, 0x1f, trig_sig_sel);
+ odm_set_bb_reg(dm, 0x8FC, MASKDWORD, dbg_port);
+ /*0: posedge, 1: negedge*/
+ odm_set_bb_reg(dm, 0x95C, BIT(31), is_trigger_edge);
+ odm_set_bb_reg(dm, 0x95c, 0xe0, sampling_rate);
+ /* (0:) '80MHz'
+ * (1:) '40MHz'
+ * (2:) '20MHz'
+ * (3:) '10MHz'
+ * (4:) '5MHz'
+ * (5:) '2.5MHz'
+ * (6:) '1.25MHz'
+ * (7:) '160MHz (for BW160 ic)'
+ */
+ } else {
+ /*0x9A0[4:0], BB debug port bit*/
+ odm_set_bb_reg(dm, 0x9a0, 0x1f, trig_sig_sel);
+ odm_set_bb_reg(dm, 0x908, MASKDWORD, dbg_port);
+ /*0: posedge, 1: negedge*/
+ odm_set_bb_reg(dm, 0x9A0, BIT(31), is_trigger_edge);
+ odm_set_bb_reg(dm, 0x9A0, 0xe0, sampling_rate);
+ /* (0:) '80MHz'
+ * (1:) '40MHz'
+ * (2:) '20MHz'
+ * (3:) '10MHz'
+ * (4:) '5MHz'
+ * (5:) '2.5MHz'
+ * (6:) '1.25MHz'
+ * (7:) '160MHz (for BW160 ic)'
+ */
+ }
+}
+
+void phydm_la_mode_set_trigger_time(void *dm_void, u32 trigger_time_mu_sec)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u8 trigger_time_unit_num;
+ u32 time_unit = 0;
+
+ if (trigger_time_mu_sec < 128)
+ time_unit = 0; /*unit: 1mu sec*/
+ else if (trigger_time_mu_sec < 256)
+ time_unit = 1; /*unit: 2mu sec*/
+ else if (trigger_time_mu_sec < 512)
+ time_unit = 2; /*unit: 4mu sec*/
+ else if (trigger_time_mu_sec < 1024)
+ time_unit = 3; /*unit: 8mu sec*/
+ else if (trigger_time_mu_sec < 2048)
+ time_unit = 4; /*unit: 16mu sec*/
+ else if (trigger_time_mu_sec < 4096)
+ time_unit = 5; /*unit: 32mu sec*/
+ else if (trigger_time_mu_sec < 8192)
+ time_unit = 6; /*unit: 64mu sec*/
+
+ trigger_time_unit_num = (u8)(trigger_time_mu_sec >> time_unit);
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_UNCOND,
+ "3. [Set Trigger Time] Trig_Time = ((%d)) * unit = ((2^%d us))\n",
+ trigger_time_unit_num, time_unit);
+
+ odm_set_mac_reg(dm, 0x7cc, BIT(20) | BIT(19) | BIT(18), time_unit);
+ odm_set_mac_reg(dm, 0x7c0, 0x7f00, (trigger_time_unit_num & 0x7f));
+}
+
+void phydm_lamode_trigger_setting(void *dm_void, char input[][16], u32 *_used,
+ char *output, u32 *_out_len, u32 input_num)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct rt_adcsmp *adc_smp = &dm->adcsmp;
+ u8 trig_mode, dma_data_sig_sel;
+ u32 trig_sig_sel;
+ bool is_enable_la_mode;
+ u32 trigger_time_mu_sec;
+ char help[] = "-h";
+ u32 var1[10] = {0};
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ if (dm->support_ic_type & PHYDM_IC_SUPPORT_LA_MODE) {
+ PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);
+ is_enable_la_mode = (bool)var1[0];
+ /*dbg_print("echo cmd input_num = %d\n", input_num);*/
+
+ if ((strcmp(input[1], help) == 0)) {
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "{En} {0:BB,1:BB_MAC,2:RF0,3:RF1,4:MAC}\n {BB:dbg_port[bit],BB_MAC:0-ok/1-fail/2-cca,MAC:ref} {DMA type} {TrigTime}\n {polling_time/ref_mask} {dbg_port} {0:P_Edge, 1:N_Edge} {SpRate:0-80M,1-40M,2-20M} {Capture num}\n");
+ /**/
+ } else if ((is_enable_la_mode == 1)) {
+ PHYDM_SSCANF(input[2], DCMD_DECIMAL, &var1[1]);
+
+ trig_mode = (u8)var1[1];
+
+ if (trig_mode == PHYDM_MAC_TRIG)
+ PHYDM_SSCANF(input[3], DCMD_HEX, &var1[2]);
+ else
+ PHYDM_SSCANF(input[3], DCMD_DECIMAL, &var1[2]);
+ trig_sig_sel = var1[2];
+
+ PHYDM_SSCANF(input[4], DCMD_DECIMAL, &var1[3]);
+ PHYDM_SSCANF(input[5], DCMD_DECIMAL, &var1[4]);
+ PHYDM_SSCANF(input[6], DCMD_HEX, &var1[5]);
+ PHYDM_SSCANF(input[7], DCMD_HEX, &var1[6]);
+ PHYDM_SSCANF(input[8], DCMD_DECIMAL, &var1[7]);
+ PHYDM_SSCANF(input[9], DCMD_DECIMAL, &var1[8]);
+ PHYDM_SSCANF(input[10], DCMD_DECIMAL, &var1[9]);
+
+ dma_data_sig_sel = (u8)var1[3];
+ trigger_time_mu_sec = var1[4]; /*unit: us*/
+
+ adc_smp->la_mac_ref_mask = var1[5];
+ adc_smp->la_dbg_port = var1[6];
+ adc_smp->la_trigger_edge = (u8)var1[7];
+ adc_smp->la_smp_rate = (u8)(var1[8] & 0x7);
+ adc_smp->la_count = var1[9];
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_UNCOND,
+ "echo lamode %d %d %d %d %d %d %x %d %d %d\n",
+ var1[0], var1[1], var1[2], var1[3], var1[4],
+ var1[5], var1[6], var1[7], var1[8], var1[9]);
+
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "a.En= ((1)), b.mode = ((%d)), c.Trig_Sel = ((0x%x)), d.Dma_type = ((%d))\n",
+ trig_mode, trig_sig_sel, dma_data_sig_sel);
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "e.Trig_Time = ((%dus)), f.mac_ref_mask = ((0x%x)), g.dbg_port = ((0x%x))\n",
+ trigger_time_mu_sec, adc_smp->la_mac_ref_mask,
+ adc_smp->la_dbg_port);
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "h.Trig_edge = ((%d)), i.smp rate = ((%d MHz)), j.Cap_num = ((%d))\n",
+ adc_smp->la_trigger_edge,
+ (80 >> adc_smp->la_smp_rate),
+ adc_smp->la_count);
+
+ adc_smp_set(dm, trig_mode, trig_sig_sel,
+ dma_data_sig_sel, trigger_time_mu_sec, 0);
+
+ } else {
+ adc_smp_stop(dm);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "Disable LA mode\n");
+ }
+ }
+}
diff --git a/drivers/staging/rtlwifi/phydm/phydm_adc_sampling.h b/drivers/staging/rtlwifi/phydm/phydm_adc_sampling.h
new file mode 100644
index 0000000..4609314
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_adc_sampling.h
@@ -0,0 +1,96 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __INC_ADCSMP_H
+#define __INC_ADCSMP_H
+
+#define DYNAMIC_LA_MODE "1.0" /*2016.07.15 Dino */
+
+struct rt_adcsmp_string {
+ u32 *octet;
+ u32 length;
+ u32 buffer_size;
+ u32 start_pos;
+};
+
+enum rt_adcsmp_trig_sel {
+ PHYDM_ADC_BB_TRIG = 0,
+ PHYDM_ADC_MAC_TRIG = 1,
+ PHYDM_ADC_RF0_TRIG = 2,
+ PHYDM_ADC_RF1_TRIG = 3,
+ PHYDM_MAC_TRIG = 4
+};
+
+enum rt_adcsmp_trig_sig_sel {
+ ADCSMP_TRIG_CRCOK = 0,
+ ADCSMP_TRIG_CRCFAIL = 1,
+ ADCSMP_TRIG_CCA = 2,
+ ADCSMP_TRIG_REG = 3
+};
+
+enum rt_adcsmp_state {
+ ADCSMP_STATE_IDLE = 0,
+ ADCSMP_STATE_SET = 1,
+ ADCSMP_STATE_QUERY = 2
+};
+
+struct rt_adcsmp {
+ struct rt_adcsmp_string adc_smp_buf;
+ enum rt_adcsmp_state adc_smp_state;
+ u8 la_trig_mode;
+ u32 la_trig_sig_sel;
+ u8 la_dma_type;
+ u32 la_trigger_time;
+ u32 la_mac_ref_mask;
+ u32 la_dbg_port;
+ u8 la_trigger_edge;
+ u8 la_smp_rate;
+ u32 la_count;
+ u8 is_bb_trigger;
+ u8 la_work_item_index;
+};
+
+void adc_smp_set(void *dm_void, u8 trig_mode, u32 trig_sig_sel,
+ u8 dma_data_sig_sel, u32 trigger_time, u16 polling_time);
+
+void adc_smp_query(void *dm_void, void *output, u32 out_len, u32 *pused);
+
+s32 adc_smp_get_sample_counts(void *dm_void);
+
+s32 adc_smp_query_single_data(void *dm_void, void *output, u32 out_len,
+ u32 index);
+
+void adc_smp_stop(void *dm_void);
+
+void adc_smp_init(void *dm_void);
+
+void adc_smp_de_init(void *dm_void);
+
+void phydm_la_mode_bb_setting(void *dm_void);
+
+void phydm_la_mode_set_trigger_time(void *dm_void, u32 trigger_time_mu_sec);
+
+void phydm_lamode_trigger_setting(void *dm_void, char input[][16], u32 *_used,
+ char *output, u32 *_out_len, u32 input_num);
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/phydm_antdiv.c b/drivers/staging/rtlwifi/phydm/phydm_antdiv.c
new file mode 100644
index 0000000..39d3c69
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_antdiv.c
@@ -0,0 +1,83 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+/* ************************************************************
+ * include files
+ * *************************************************************/
+
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+/* ******************************************************
+ * when antenna test utility is on or some testing need to disable antenna
+ * diversity, call this function to disable all ODM related mechanisms which
+ * will switch antenna.
+ * *******************************************************/
+void odm_stop_antenna_switch_dm(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ /* disable ODM antenna diversity */
+ dm->support_ability &= ~ODM_BB_ANT_DIV;
+ ODM_RT_TRACE(dm, ODM_COMP_ANT_DIV, "STOP Antenna Diversity\n");
+}
+
+void phydm_enable_antenna_diversity(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ dm->support_ability |= ODM_BB_ANT_DIV;
+ ODM_RT_TRACE(dm, ODM_COMP_ANT_DIV,
+ "AntDiv is enabled & Re-Init AntDiv\n");
+ odm_antenna_diversity_init(dm);
+}
+
+void odm_set_ant_config(void *dm_void, u8 ant_setting /* 0=A, 1=B, 2=C, .... */
+ )
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ if (dm->support_ic_type == ODM_RTL8723B) {
+ if (ant_setting == 0) /* ant A*/
+ odm_set_bb_reg(dm, 0x948, MASKDWORD, 0x00000000);
+ else if (ant_setting == 1)
+ odm_set_bb_reg(dm, 0x948, MASKDWORD, 0x00000280);
+ } else if (dm->support_ic_type == ODM_RTL8723D) {
+ if (ant_setting == 0) /* ant A*/
+ odm_set_bb_reg(dm, 0x948, MASKLWORD, 0x0000);
+ else if (ant_setting == 1)
+ odm_set_bb_reg(dm, 0x948, MASKLWORD, 0x0280);
+ }
+}
+
+/* ****************************************************** */
+
+void odm_sw_ant_div_rest_after_link(void *dm_void) {}
+
+void odm_ant_div_reset(void *dm_void) {}
+
+void odm_antenna_diversity_init(void *dm_void) {}
+
+void odm_antenna_diversity(void *dm_void) {}
diff --git a/drivers/staging/rtlwifi/phydm/phydm_antdiv.h b/drivers/staging/rtlwifi/phydm/phydm_antdiv.h
new file mode 100644
index 0000000..ebbff2f
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_antdiv.h
@@ -0,0 +1,301 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __PHYDMANTDIV_H__
+#define __PHYDMANTDIV_H__
+
+/* 2.0 2014.11.04
+ * 2.1 2015.01.13 Dino
+ * 2.2 2015.01.16 Dino
+ * 3.1 2015.07.29 YuChen, remove 92c 92d 8723a
+ * 3.2 2015.08.11 Stanley, disable antenna diversity when BT is enable for 8723B
+ * 3.3 2015.08.12 Stanley. 8723B does not need to check the antenna is control
+ * by BT, because antenna diversity only works when BT is disable
+ * or radio off
+ * 3.4 2015.08.28 Dino 1.Add 8821A Smart Antenna 2. Add 8188F SW S0S1 Antenna
+ * Diversity
+ * 3.5 2015.10.07 Stanley Always check antenna detection result from BT-coex.
+ * for 8723B, not from PHYDM
+ * 3.6 2015.11.16 Stanley
+ * 3.7 2015.11.20 Dino Add SmartAnt FAT Patch
+ * 3.8 2015.12.21 Dino, Add SmartAnt dynamic training packet num
+ * 3.9 2016.01.05 Dino, Add SmartAnt cmd for converting single & two smtant, and
+ * add cmd for adjust truth table
+ */
+#define ANTDIV_VERSION "3.9"
+
+/* 1 ============================================================
+ * 1 Definition
+ * 1 ============================================================
+ */
+
+#define ANTDIV_INIT 0xff
+#define MAIN_ANT 1 /*ant A or ant Main or S1*/
+#define AUX_ANT 2 /*AntB or ant Aux or S0*/
+#define MAX_ANT 3 /* 3 for AP using*/
+
+#define ANT1_2G 0 /* = ANT2_5G for 8723D BTG S1 RX S0S1 diversity for 8723D,
+ * TX fixed at S1
+ */
+#define ANT2_2G 1 /* = ANT1_5G for 8723D BTG S0 RX S0S1 diversity for 8723D,
+ * TX fixed at S1
+ */
+/*smart antenna*/
+#define SUPPORT_RF_PATH_NUM 4
+#define SUPPORT_BEAM_PATTERN_NUM 4
+#define NUM_ANTENNA_8821A 2
+
+#define SUPPORT_BEAM_SET_PATTERN_NUM 8
+
+#define NO_FIX_TX_ANT 0
+#define FIX_TX_AT_MAIN 1
+#define FIX_AUX_AT_MAIN 2
+
+/* Antenna Diversty Control type */
+#define ODM_AUTO_ANT 0
+#define ODM_FIX_MAIN_ANT 1
+#define ODM_FIX_AUX_ANT 2
+
+#define ODM_N_ANTDIV_SUPPORT \
+ (ODM_RTL8188E | ODM_RTL8192E | ODM_RTL8723B | ODM_RTL8188F | \
+ ODM_RTL8723D | ODM_RTL8195A)
+#define ODM_AC_ANTDIV_SUPPORT \
+ (ODM_RTL8821 | ODM_RTL8881A | ODM_RTL8812 | ODM_RTL8821C | \
+ ODM_RTL8822B | ODM_RTL8814B)
+#define ODM_ANTDIV_SUPPORT (ODM_N_ANTDIV_SUPPORT | ODM_AC_ANTDIV_SUPPORT)
+#define ODM_SMART_ANT_SUPPORT (ODM_RTL8188E | ODM_RTL8192E)
+#define ODM_HL_SMART_ANT_TYPE1_SUPPORT (ODM_RTL8821 | ODM_RTL8822B)
+
+#define ODM_ANTDIV_2G_SUPPORT_IC \
+ (ODM_RTL8188E | ODM_RTL8192E | ODM_RTL8723B | ODM_RTL8881A | \
+ ODM_RTL8188F | ODM_RTL8723D)
+#define ODM_ANTDIV_5G_SUPPORT_IC \
+ (ODM_RTL8821 | ODM_RTL8881A | ODM_RTL8812 | ODM_RTL8821C)
+
+#define ODM_EVM_ENHANCE_ANTDIV_SUPPORT_IC (ODM_RTL8192E)
+
+#define ODM_ANTDIV_2G BIT(0)
+#define ODM_ANTDIV_5G BIT(1)
+
+#define ANTDIV_ON 1
+#define ANTDIV_OFF 0
+
+#define FAT_ON 1
+#define FAT_OFF 0
+
+#define TX_BY_DESC 1
+#define TX_BY_REG 0
+
+#define RSSI_METHOD 0
+#define EVM_METHOD 1
+#define CRC32_METHOD 2
+
+#define INIT_ANTDIV_TIMMER 0
+#define CANCEL_ANTDIV_TIMMER 1
+#define RELEASE_ANTDIV_TIMMER 2
+
+#define CRC32_FAIL 1
+#define CRC32_OK 0
+
+#define evm_rssi_th_high 25
+#define evm_rssi_th_low 20
+
+#define NORMAL_STATE_MIAN 1
+#define NORMAL_STATE_AUX 2
+#define TRAINING_STATE 3
+
+#define FORCE_RSSI_DIFF 10
+
+#define CSI_ON 1
+#define CSI_OFF 0
+
+#define DIVON_CSIOFF 1
+#define DIVOFF_CSION 2
+
+#define BDC_DIV_TRAIN_STATE 0
+#define bdc_bfer_train_state 1
+#define BDC_DECISION_STATE 2
+#define BDC_BF_HOLD_STATE 3
+#define BDC_DIV_HOLD_STATE 4
+
+#define BDC_MODE_1 1
+#define BDC_MODE_2 2
+#define BDC_MODE_3 3
+#define BDC_MODE_4 4
+#define BDC_MODE_NULL 0xff
+
+/*SW S0S1 antenna diversity*/
+#define SWAW_STEP_INIT 0xff
+#define SWAW_STEP_PEEK 0
+#define SWAW_STEP_DETERMINE 1
+
+#define RSSI_CHECK_RESET_PERIOD 10
+#define RSSI_CHECK_THRESHOLD 50
+
+/*Hong Lin Smart antenna*/
+#define HL_SMTANT_2WIRE_DATA_LEN 24
+
+/* 1 ============================================================
+ * 1 structure
+ * 1 ============================================================
+ */
+
+struct sw_antenna_switch {
+ u8 double_chk_flag; /*If current antenna RSSI > "RSSI_CHECK_THRESHOLD",
+ *than check this antenna again
+ */
+ u8 try_flag;
+ s32 pre_rssi;
+ u8 cur_antenna;
+ u8 pre_antenna;
+ u8 rssi_trying;
+ u8 reset_idx;
+ u8 train_time;
+ u8 train_time_flag; /*base on RSSI difference between two antennas*/
+ struct timer_list phydm_sw_antenna_switch_timer;
+ u32 pkt_cnt_sw_ant_div_by_ctrl_frame;
+ bool is_sw_ant_div_by_ctrl_frame;
+
+ /* AntDect (Before link Antenna Switch check) need to be moved*/
+ u16 single_ant_counter;
+ u16 dual_ant_counter;
+ u16 aux_fail_detec_counter;
+ u16 retry_counter;
+ u8 swas_no_link_state;
+ u32 swas_no_link_bk_reg948;
+ bool ANTA_ON; /*To indicate ant A is or not*/
+ bool ANTB_ON; /*To indicate ant B is on or not*/
+ bool pre_aux_fail_detec;
+ bool rssi_ant_dect_result;
+ u8 ant_5g;
+ u8 ant_2g;
+};
+
+struct fast_antenna_training {
+ u8 bssid[6];
+ u8 antsel_rx_keep_0;
+ u8 antsel_rx_keep_1;
+ u8 antsel_rx_keep_2;
+ u8 antsel_rx_keep_3;
+ u32 ant_sum_rssi[7];
+ u32 ant_rssi_cnt[7];
+ u32 ant_ave_rssi[7];
+ u8 fat_state;
+ u32 train_idx;
+ u8 antsel_a[ODM_ASSOCIATE_ENTRY_NUM];
+ u8 antsel_b[ODM_ASSOCIATE_ENTRY_NUM];
+ u8 antsel_c[ODM_ASSOCIATE_ENTRY_NUM];
+ u16 main_ant_sum[ODM_ASSOCIATE_ENTRY_NUM];
+ u16 aux_ant_sum[ODM_ASSOCIATE_ENTRY_NUM];
+ u16 main_ant_cnt[ODM_ASSOCIATE_ENTRY_NUM];
+ u16 aux_ant_cnt[ODM_ASSOCIATE_ENTRY_NUM];
+ u16 main_ant_sum_cck[ODM_ASSOCIATE_ENTRY_NUM];
+ u16 aux_ant_sum_cck[ODM_ASSOCIATE_ENTRY_NUM];
+ u16 main_ant_cnt_cck[ODM_ASSOCIATE_ENTRY_NUM];
+ u16 aux_ant_cnt_cck[ODM_ASSOCIATE_ENTRY_NUM];
+ u8 rx_idle_ant;
+ u8 ant_div_on_off;
+ bool is_become_linked;
+ u32 min_max_rssi;
+ u8 idx_ant_div_counter_2g;
+ u8 idx_ant_div_counter_5g;
+ u8 ant_div_2g_5g;
+
+ u32 cck_ctrl_frame_cnt_main;
+ u32 cck_ctrl_frame_cnt_aux;
+ u32 ofdm_ctrl_frame_cnt_main;
+ u32 ofdm_ctrl_frame_cnt_aux;
+ u32 main_ant_ctrl_frame_sum;
+ u32 aux_ant_ctrl_frame_sum;
+ u32 main_ant_ctrl_frame_cnt;
+ u32 aux_ant_ctrl_frame_cnt;
+ u8 b_fix_tx_ant;
+ bool fix_ant_bfee;
+ bool enable_ctrl_frame_antdiv;
+ bool use_ctrl_frame_antdiv;
+ u8 hw_antsw_occur;
+ u8 *p_force_tx_ant_by_desc;
+ u8 force_tx_ant_by_desc; /*A temp value, will hook to driver team's
+ *outer parameter later
+ */
+ u8 *p_default_s0_s1;
+ u8 default_s0_s1;
+};
+
+/* 1 ============================================================
+ * 1 enumeration
+ * 1 ============================================================
+ */
+
+/*Fast antenna training*/
+enum fat_state {
+ FAT_BEFORE_LINK_STATE = 0,
+ FAT_PREPARE_STATE = 1,
+ FAT_TRAINING_STATE = 2,
+ FAT_DECISION_STATE = 3
+};
+
+enum ant_div_type {
+ NO_ANTDIV = 0xFF,
+ CG_TRX_HW_ANTDIV = 0x01,
+ CGCS_RX_HW_ANTDIV = 0x02,
+ FIXED_HW_ANTDIV = 0x03,
+ CG_TRX_SMART_ANTDIV = 0x04,
+ CGCS_RX_SW_ANTDIV = 0x05,
+ /*8723B intrnal switch S0 S1*/
+ S0S1_SW_ANTDIV = 0x06,
+ /*TRX S0S1 diversity for 8723D*/
+ S0S1_TRX_HW_ANTDIV = 0x07,
+ /*Hong-Lin Smart antenna use for 8821AE which is a 2 ant. entitys, and
+ *each ant. is equipped with 4 antenna patterns
+ */
+ HL_SW_SMART_ANT_TYPE1 = 0x10,
+ /*Hong-Bo Smart antenna use for 8822B which is a 2 ant. entitys*/
+ HL_SW_SMART_ANT_TYPE2 = 0x11,
+};
+
+/* 1 ============================================================
+ * 1 function prototype
+ * 1 ============================================================
+ */
+
+void odm_stop_antenna_switch_dm(void *dm_void);
+
+void phydm_enable_antenna_diversity(void *dm_void);
+
+void odm_set_ant_config(void *dm_void, u8 ant_setting /* 0=A, 1=B, 2=C, .... */
+ );
+
+#define sw_ant_div_rest_after_link odm_sw_ant_div_rest_after_link
+
+void odm_sw_ant_div_rest_after_link(void *dm_void);
+
+void odm_ant_div_reset(void *dm_void);
+
+void odm_antenna_diversity_init(void *dm_void);
+
+void odm_antenna_diversity(void *dm_void);
+
+#endif /*#ifndef __ODMANTDIV_H__*/
diff --git a/drivers/staging/rtlwifi/phydm/phydm_beamforming.h b/drivers/staging/rtlwifi/phydm/phydm_beamforming.h
new file mode 100644
index 0000000..adc04ba
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_beamforming.h
@@ -0,0 +1,48 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __INC_PHYDM_BEAMFORMING_H
+#define __INC_PHYDM_BEAMFORMING_H
+
+/*Beamforming Related*/
+#include "txbf/halcomtxbf.h"
+#include "txbf/haltxbfjaguar.h"
+#include "txbf/haltxbf8822b.h"
+#include "txbf/haltxbfinterface.h"
+
+#define beamforming_gid_paid(adapter, tcb)
+#define phydm_acting_determine(dm, type) false
+#define beamforming_enter(dm, sta_idx)
+#define beamforming_leave(dm, RA)
+#define beamforming_end_fw(dm)
+#define beamforming_control_v1(dm, RA, AID, mode, BW, rate) true
+#define beamforming_control_v2(dm, idx, mode, BW, period) true
+#define phydm_beamforming_end_sw(dm, _status)
+#define beamforming_timer_callback(dm)
+#define phydm_beamforming_init(dm)
+#define phydm_beamforming_control_v2(dm, _idx, _mode, _BW, _period) false
+#define beamforming_watchdog(dm)
+#define phydm_beamforming_watchdog(dm)
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/phydm_ccx.c b/drivers/staging/rtlwifi/phydm/phydm_ccx.c
new file mode 100644
index 0000000..2e0dc68
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_ccx.c
@@ -0,0 +1,457 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+/*Set NHM period, threshold, disable ignore cca or not,
+ *disable ignore txon or not
+ */
+void phydm_nhm_setting(void *dm_void, u8 nhm_setting)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct ccx_info *ccx_info = &dm->dm_ccx_info;
+
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ if (nhm_setting == SET_NHM_SETTING) {
+ /*Set inexclude_cca, inexclude_txon*/
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(9),
+ ccx_info->nhm_inexclude_cca);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(10),
+ ccx_info->nhm_inexclude_txon);
+
+ /*Set NHM period*/
+ odm_set_bb_reg(dm, ODM_REG_CCX_PERIOD_11AC, MASKHWORD,
+ ccx_info->NHM_period);
+
+ /*Set NHM threshold*/
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH3_TO_TH0_11AC,
+ MASKBYTE0, ccx_info->NHM_th[0]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH3_TO_TH0_11AC,
+ MASKBYTE1, ccx_info->NHM_th[1]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH3_TO_TH0_11AC,
+ MASKBYTE2, ccx_info->NHM_th[2]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH3_TO_TH0_11AC,
+ MASKBYTE3, ccx_info->NHM_th[3]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH7_TO_TH4_11AC,
+ MASKBYTE0, ccx_info->NHM_th[4]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH7_TO_TH4_11AC,
+ MASKBYTE1, ccx_info->NHM_th[5]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH7_TO_TH4_11AC,
+ MASKBYTE2, ccx_info->NHM_th[6]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH7_TO_TH4_11AC,
+ MASKBYTE3, ccx_info->NHM_th[7]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH8_11AC, MASKBYTE0,
+ ccx_info->NHM_th[8]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE2,
+ ccx_info->NHM_th[9]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE3,
+ ccx_info->NHM_th[10]);
+
+ /*CCX EN*/
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(8),
+ CCX_EN);
+ } else if (nhm_setting == STORE_NHM_SETTING) {
+ /*Store prev. disable_ignore_cca, disable_ignore_txon*/
+ ccx_info->NHM_inexclude_cca_restore =
+ (enum nhm_inexclude_cca)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(9));
+ ccx_info->NHM_inexclude_txon_restore =
+ (enum nhm_inexclude_txon)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(10));
+
+ /*Store pervious NHM period*/
+ ccx_info->NHM_period_restore = (u16)odm_get_bb_reg(
+ dm, ODM_REG_CCX_PERIOD_11AC, MASKHWORD);
+
+ /*Store NHM threshold*/
+ ccx_info->NHM_th_restore[0] = (u8)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE0);
+ ccx_info->NHM_th_restore[1] = (u8)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE1);
+ ccx_info->NHM_th_restore[2] = (u8)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE2);
+ ccx_info->NHM_th_restore[3] = (u8)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE3);
+ ccx_info->NHM_th_restore[4] = (u8)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE0);
+ ccx_info->NHM_th_restore[5] = (u8)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE1);
+ ccx_info->NHM_th_restore[6] = (u8)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE2);
+ ccx_info->NHM_th_restore[7] = (u8)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE3);
+ ccx_info->NHM_th_restore[8] = (u8)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH8_11AC, MASKBYTE0);
+ ccx_info->NHM_th_restore[9] = (u8)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE2);
+ ccx_info->NHM_th_restore[10] = (u8)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE3);
+ } else if (nhm_setting == RESTORE_NHM_SETTING) {
+ /*Set disable_ignore_cca, disable_ignore_txon*/
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(9),
+ ccx_info->NHM_inexclude_cca_restore);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(10),
+ ccx_info->NHM_inexclude_txon_restore);
+
+ /*Set NHM period*/
+ odm_set_bb_reg(dm, ODM_REG_CCX_PERIOD_11AC, MASKHWORD,
+ ccx_info->NHM_period);
+
+ /*Set NHM threshold*/
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH3_TO_TH0_11AC,
+ MASKBYTE0, ccx_info->NHM_th_restore[0]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH3_TO_TH0_11AC,
+ MASKBYTE1, ccx_info->NHM_th_restore[1]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH3_TO_TH0_11AC,
+ MASKBYTE2, ccx_info->NHM_th_restore[2]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH3_TO_TH0_11AC,
+ MASKBYTE3, ccx_info->NHM_th_restore[3]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH7_TO_TH4_11AC,
+ MASKBYTE0, ccx_info->NHM_th_restore[4]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH7_TO_TH4_11AC,
+ MASKBYTE1, ccx_info->NHM_th_restore[5]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH7_TO_TH4_11AC,
+ MASKBYTE2, ccx_info->NHM_th_restore[6]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH7_TO_TH4_11AC,
+ MASKBYTE3, ccx_info->NHM_th_restore[7]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH8_11AC, MASKBYTE0,
+ ccx_info->NHM_th_restore[8]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE2,
+ ccx_info->NHM_th_restore[9]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE3,
+ ccx_info->NHM_th_restore[10]);
+ } else {
+ return;
+ }
+ }
+
+ else if (dm->support_ic_type & ODM_IC_11N_SERIES) {
+ if (nhm_setting == SET_NHM_SETTING) {
+ /*Set disable_ignore_cca, disable_ignore_txon*/
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11N, BIT(9),
+ ccx_info->nhm_inexclude_cca);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11N, BIT(10),
+ ccx_info->nhm_inexclude_txon);
+
+ /*Set NHM period*/
+ odm_set_bb_reg(dm, ODM_REG_CCX_PERIOD_11N, MASKHWORD,
+ ccx_info->NHM_period);
+
+ /*Set NHM threshold*/
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH3_TO_TH0_11N,
+ MASKBYTE0, ccx_info->NHM_th[0]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH3_TO_TH0_11N,
+ MASKBYTE1, ccx_info->NHM_th[1]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH3_TO_TH0_11N,
+ MASKBYTE2, ccx_info->NHM_th[2]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH3_TO_TH0_11N,
+ MASKBYTE3, ccx_info->NHM_th[3]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH7_TO_TH4_11N,
+ MASKBYTE0, ccx_info->NHM_th[4]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH7_TO_TH4_11N,
+ MASKBYTE1, ccx_info->NHM_th[5]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH7_TO_TH4_11N,
+ MASKBYTE2, ccx_info->NHM_th[6]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH7_TO_TH4_11N,
+ MASKBYTE3, ccx_info->NHM_th[7]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH8_11N, MASKBYTE0,
+ ccx_info->NHM_th[8]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE2,
+ ccx_info->NHM_th[9]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE3,
+ ccx_info->NHM_th[10]);
+
+ /*CCX EN*/
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11N, BIT(8),
+ CCX_EN);
+ } else if (nhm_setting == STORE_NHM_SETTING) {
+ /*Store prev. disable_ignore_cca, disable_ignore_txon*/
+ ccx_info->NHM_inexclude_cca_restore =
+ (enum nhm_inexclude_cca)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH9_TH10_11N, BIT(9));
+ ccx_info->NHM_inexclude_txon_restore =
+ (enum nhm_inexclude_txon)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH9_TH10_11N, BIT(10));
+
+ /*Store pervious NHM period*/
+ ccx_info->NHM_period_restore = (u16)odm_get_bb_reg(
+ dm, ODM_REG_CCX_PERIOD_11N, MASKHWORD);
+
+ /*Store NHM threshold*/
+ ccx_info->NHM_th_restore[0] = (u8)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE0);
+ ccx_info->NHM_th_restore[1] = (u8)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE1);
+ ccx_info->NHM_th_restore[2] = (u8)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE2);
+ ccx_info->NHM_th_restore[3] = (u8)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE3);
+ ccx_info->NHM_th_restore[4] = (u8)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE0);
+ ccx_info->NHM_th_restore[5] = (u8)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE1);
+ ccx_info->NHM_th_restore[6] = (u8)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE2);
+ ccx_info->NHM_th_restore[7] = (u8)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE3);
+ ccx_info->NHM_th_restore[8] = (u8)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH8_11N, MASKBYTE0);
+ ccx_info->NHM_th_restore[9] = (u8)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE2);
+ ccx_info->NHM_th_restore[10] = (u8)odm_get_bb_reg(
+ dm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE3);
+ } else if (nhm_setting == RESTORE_NHM_SETTING) {
+ /*Set disable_ignore_cca, disable_ignore_txon*/
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11N, BIT(9),
+ ccx_info->NHM_inexclude_cca_restore);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11N, BIT(10),
+ ccx_info->NHM_inexclude_txon_restore);
+
+ /*Set NHM period*/
+ odm_set_bb_reg(dm, ODM_REG_CCX_PERIOD_11N, MASKHWORD,
+ ccx_info->NHM_period_restore);
+
+ /*Set NHM threshold*/
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH3_TO_TH0_11N,
+ MASKBYTE0, ccx_info->NHM_th_restore[0]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH3_TO_TH0_11N,
+ MASKBYTE1, ccx_info->NHM_th_restore[1]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH3_TO_TH0_11N,
+ MASKBYTE2, ccx_info->NHM_th_restore[2]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH3_TO_TH0_11N,
+ MASKBYTE3, ccx_info->NHM_th_restore[3]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH7_TO_TH4_11N,
+ MASKBYTE0, ccx_info->NHM_th_restore[4]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH7_TO_TH4_11N,
+ MASKBYTE1, ccx_info->NHM_th_restore[5]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH7_TO_TH4_11N,
+ MASKBYTE2, ccx_info->NHM_th_restore[6]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH7_TO_TH4_11N,
+ MASKBYTE3, ccx_info->NHM_th_restore[7]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH8_11N, MASKBYTE0,
+ ccx_info->NHM_th_restore[8]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE2,
+ ccx_info->NHM_th_restore[9]);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE3,
+ ccx_info->NHM_th_restore[10]);
+ } else {
+ return;
+ }
+ }
+}
+
+void phydm_nhm_trigger(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ /*Trigger NHM*/
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(1), 0);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(1), 1);
+ } else if (dm->support_ic_type & ODM_IC_11N_SERIES) {
+ /*Trigger NHM*/
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11N, BIT(1), 0);
+ odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11N, BIT(1), 1);
+ }
+}
+
+void phydm_get_nhm_result(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 value32;
+ struct ccx_info *ccx_info = &dm->dm_ccx_info;
+
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ value32 = odm_read_4byte(dm, ODM_REG_NHM_CNT_11AC);
+ ccx_info->NHM_result[0] = (u8)(value32 & MASKBYTE0);
+ ccx_info->NHM_result[1] = (u8)((value32 & MASKBYTE1) >> 8);
+ ccx_info->NHM_result[2] = (u8)((value32 & MASKBYTE2) >> 16);
+ ccx_info->NHM_result[3] = (u8)((value32 & MASKBYTE3) >> 24);
+
+ value32 = odm_read_4byte(dm, ODM_REG_NHM_CNT7_TO_CNT4_11AC);
+ ccx_info->NHM_result[4] = (u8)(value32 & MASKBYTE0);
+ ccx_info->NHM_result[5] = (u8)((value32 & MASKBYTE1) >> 8);
+ ccx_info->NHM_result[6] = (u8)((value32 & MASKBYTE2) >> 16);
+ ccx_info->NHM_result[7] = (u8)((value32 & MASKBYTE3) >> 24);
+
+ value32 = odm_read_4byte(dm, ODM_REG_NHM_CNT11_TO_CNT8_11AC);
+ ccx_info->NHM_result[8] = (u8)(value32 & MASKBYTE0);
+ ccx_info->NHM_result[9] = (u8)((value32 & MASKBYTE1) >> 8);
+ ccx_info->NHM_result[10] = (u8)((value32 & MASKBYTE2) >> 16);
+ ccx_info->NHM_result[11] = (u8)((value32 & MASKBYTE3) >> 24);
+
+ /*Get NHM duration*/
+ value32 = odm_read_4byte(dm, ODM_REG_NHM_DUR_READY_11AC);
+ ccx_info->NHM_duration = (u16)(value32 & MASKLWORD);
+ }
+
+ else if (dm->support_ic_type & ODM_IC_11N_SERIES) {
+ value32 = odm_read_4byte(dm, ODM_REG_NHM_CNT_11N);
+ ccx_info->NHM_result[0] = (u8)(value32 & MASKBYTE0);
+ ccx_info->NHM_result[1] = (u8)((value32 & MASKBYTE1) >> 8);
+ ccx_info->NHM_result[2] = (u8)((value32 & MASKBYTE2) >> 16);
+ ccx_info->NHM_result[3] = (u8)((value32 & MASKBYTE3) >> 24);
+
+ value32 = odm_read_4byte(dm, ODM_REG_NHM_CNT7_TO_CNT4_11N);
+ ccx_info->NHM_result[4] = (u8)(value32 & MASKBYTE0);
+ ccx_info->NHM_result[5] = (u8)((value32 & MASKBYTE1) >> 8);
+ ccx_info->NHM_result[6] = (u8)((value32 & MASKBYTE2) >> 16);
+ ccx_info->NHM_result[7] = (u8)((value32 & MASKBYTE3) >> 24);
+
+ value32 = odm_read_4byte(dm, ODM_REG_NHM_CNT9_TO_CNT8_11N);
+ ccx_info->NHM_result[8] = (u8)((value32 & MASKBYTE2) >> 16);
+ ccx_info->NHM_result[9] = (u8)((value32 & MASKBYTE3) >> 24);
+
+ value32 = odm_read_4byte(dm, ODM_REG_NHM_CNT10_TO_CNT11_11N);
+ ccx_info->NHM_result[10] = (u8)((value32 & MASKBYTE2) >> 16);
+ ccx_info->NHM_result[11] = (u8)((value32 & MASKBYTE3) >> 24);
+
+ /*Get NHM duration*/
+ value32 = odm_read_4byte(dm, ODM_REG_NHM_CNT10_TO_CNT11_11N);
+ ccx_info->NHM_duration = (u16)(value32 & MASKLWORD);
+ }
+}
+
+bool phydm_check_nhm_ready(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 value32 = 0;
+ u8 i;
+ bool ret = false;
+
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ value32 =
+ odm_get_bb_reg(dm, ODM_REG_CLM_RESULT_11AC, MASKDWORD);
+
+ for (i = 0; i < 200; i++) {
+ ODM_delay_ms(1);
+ if (odm_get_bb_reg(dm, ODM_REG_NHM_DUR_READY_11AC,
+ BIT(17))) {
+ ret = 1;
+ break;
+ }
+ }
+ }
+
+ else if (dm->support_ic_type & ODM_IC_11N_SERIES) {
+ value32 = odm_get_bb_reg(dm, ODM_REG_CLM_READY_11N, MASKDWORD);
+
+ for (i = 0; i < 200; i++) {
+ ODM_delay_ms(1);
+ if (odm_get_bb_reg(dm, ODM_REG_NHM_DUR_READY_11AC,
+ BIT(17))) {
+ ret = 1;
+ break;
+ }
+ }
+ }
+ return ret;
+}
+
+void phydm_clm_setting(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct ccx_info *ccx_info = &dm->dm_ccx_info;
+
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ odm_set_bb_reg(dm, ODM_REG_CCX_PERIOD_11AC, MASKLWORD,
+ ccx_info->CLM_period); /*4us sample 1 time*/
+ odm_set_bb_reg(dm, ODM_REG_CLM_11AC, BIT(8),
+ 0x1); /*Enable CCX for CLM*/
+
+ } else if (dm->support_ic_type & ODM_IC_11N_SERIES) {
+ odm_set_bb_reg(dm, ODM_REG_CCX_PERIOD_11N, MASKLWORD,
+ ccx_info->CLM_period); /*4us sample 1 time*/
+ odm_set_bb_reg(dm, ODM_REG_CLM_11N, BIT(8),
+ 0x1); /*Enable CCX for CLM*/
+ }
+
+ ODM_RT_TRACE(dm, ODM_COMP_CCX, "[%s] : CLM period = %dus\n", __func__,
+ ccx_info->CLM_period * 4);
+}
+
+void phydm_clm_trigger(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ odm_set_bb_reg(dm, ODM_REG_CLM_11AC, BIT(0),
+ 0x0); /*Trigger CLM*/
+ odm_set_bb_reg(dm, ODM_REG_CLM_11AC, BIT(0), 0x1);
+ } else if (dm->support_ic_type & ODM_IC_11N_SERIES) {
+ odm_set_bb_reg(dm, ODM_REG_CLM_11N, BIT(0),
+ 0x0); /*Trigger CLM*/
+ odm_set_bb_reg(dm, ODM_REG_CLM_11N, BIT(0), 0x1);
+ }
+}
+
+bool phydm_check_cl_mready(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 value32 = 0;
+ bool ret = false;
+
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES)
+ value32 = odm_get_bb_reg(
+ dm, ODM_REG_CLM_RESULT_11AC,
+ MASKDWORD); /*make sure CLM calc is ready*/
+ else if (dm->support_ic_type & ODM_IC_11N_SERIES)
+ value32 = odm_get_bb_reg(
+ dm, ODM_REG_CLM_READY_11N,
+ MASKDWORD); /*make sure CLM calc is ready*/
+
+ if ((dm->support_ic_type & ODM_IC_11AC_SERIES) && (value32 & BIT(16)))
+ ret = true;
+ else if ((dm->support_ic_type & ODM_IC_11N_SERIES) &&
+ (value32 & BIT(16)))
+ ret = true;
+ else
+ ret = false;
+
+ ODM_RT_TRACE(dm, ODM_COMP_CCX, "[%s] : CLM ready = %d\n", __func__,
+ ret);
+
+ return ret;
+}
+
+void phydm_get_cl_mresult(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct ccx_info *ccx_info = &dm->dm_ccx_info;
+
+ u32 value32 = 0;
+
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES)
+ value32 = odm_get_bb_reg(dm, ODM_REG_CLM_RESULT_11AC,
+ MASKDWORD); /*read CLM calc result*/
+ else if (dm->support_ic_type & ODM_IC_11N_SERIES)
+ value32 = odm_get_bb_reg(dm, ODM_REG_CLM_RESULT_11N,
+ MASKDWORD); /*read CLM calc result*/
+
+ ccx_info->CLM_result = (u16)(value32 & MASKLWORD);
+
+ ODM_RT_TRACE(dm, ODM_COMP_CCX, "[%s] : CLM result = %dus\n", __func__,
+ ccx_info->CLM_result * 4);
+}
diff --git a/drivers/staging/rtlwifi/phydm/phydm_ccx.h b/drivers/staging/rtlwifi/phydm/phydm_ccx.h
new file mode 100644
index 0000000..a3517f4
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_ccx.h
@@ -0,0 +1,83 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __PHYDMCCX_H__
+#define __PHYDMCCX_H__
+
+#define CCX_EN 1
+
+#define SET_NHM_SETTING 0
+#define STORE_NHM_SETTING 1
+#define RESTORE_NHM_SETTING 2
+
+enum nhm_inexclude_cca { NHM_EXCLUDE_CCA, NHM_INCLUDE_CCA };
+
+enum nhm_inexclude_txon { NHM_EXCLUDE_TXON, NHM_INCLUDE_TXON };
+
+struct ccx_info {
+ /*Settings*/
+ u8 NHM_th[11];
+ u16 NHM_period; /* 4us per unit */
+ u16 CLM_period; /* 4us per unit */
+ enum nhm_inexclude_txon nhm_inexclude_txon;
+ enum nhm_inexclude_cca nhm_inexclude_cca;
+
+ /*Previous Settings*/
+ u8 NHM_th_restore[11];
+ u16 NHM_period_restore; /* 4us per unit */
+ u16 CLM_period_restore; /* 4us per unit */
+ enum nhm_inexclude_txon NHM_inexclude_txon_restore;
+ enum nhm_inexclude_cca NHM_inexclude_cca_restore;
+
+ /*Report*/
+ u8 NHM_result[12];
+ u16 NHM_duration;
+ u16 CLM_result;
+
+ bool echo_NHM_en;
+ bool echo_CLM_en;
+ u8 echo_IGI;
+};
+
+/*NHM*/
+
+void phydm_nhm_setting(void *dm_void, u8 nhm_setting);
+
+void phydm_nhm_trigger(void *dm_void);
+
+void phydm_get_nhm_result(void *dm_void);
+
+bool phydm_check_nhm_ready(void *dm_void);
+
+/*CLM*/
+
+void phydm_clm_setting(void *dm_void);
+
+void phydm_clm_trigger(void *dm_void);
+
+bool phydm_check_cl_mready(void *dm_void);
+
+void phydm_get_cl_mresult(void *dm_void);
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/phydm_cfotracking.c b/drivers/staging/rtlwifi/phydm/phydm_cfotracking.c
new file mode 100644
index 0000000..2ec8444
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_cfotracking.c
@@ -0,0 +1,343 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+static void odm_set_crystal_cap(void *dm_void, u8 crystal_cap)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct cfo_tracking *cfo_track =
+ (struct cfo_tracking *)phydm_get_structure(dm, PHYDM_CFOTRACK);
+
+ if (cfo_track->crystal_cap == crystal_cap)
+ return;
+
+ cfo_track->crystal_cap = crystal_cap;
+
+ if (dm->support_ic_type & (ODM_RTL8188E | ODM_RTL8188F)) {
+ /* write 0x24[22:17] = 0x24[16:11] = crystal_cap */
+ crystal_cap = crystal_cap & 0x3F;
+ odm_set_bb_reg(dm, REG_AFE_XTAL_CTRL, 0x007ff800,
+ (crystal_cap | (crystal_cap << 6)));
+ } else if (dm->support_ic_type & ODM_RTL8812) {
+ /* write 0x2C[30:25] = 0x2C[24:19] = crystal_cap */
+ crystal_cap = crystal_cap & 0x3F;
+ odm_set_bb_reg(dm, REG_MAC_PHY_CTRL, 0x7FF80000,
+ (crystal_cap | (crystal_cap << 6)));
+ } else if ((dm->support_ic_type & (ODM_RTL8703B | ODM_RTL8723B |
+ ODM_RTL8192E | ODM_RTL8821))) {
+ /* 0x2C[23:18] = 0x2C[17:12] = crystal_cap */
+ crystal_cap = crystal_cap & 0x3F;
+ odm_set_bb_reg(dm, REG_MAC_PHY_CTRL, 0x00FFF000,
+ (crystal_cap | (crystal_cap << 6)));
+ } else if (dm->support_ic_type & ODM_RTL8814A) {
+ /* write 0x2C[26:21] = 0x2C[20:15] = crystal_cap */
+ crystal_cap = crystal_cap & 0x3F;
+ odm_set_bb_reg(dm, REG_MAC_PHY_CTRL, 0x07FF8000,
+ (crystal_cap | (crystal_cap << 6)));
+ } else if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8821C)) {
+ /* write 0x24[30:25] = 0x28[6:1] = crystal_cap */
+ crystal_cap = crystal_cap & 0x3F;
+ odm_set_bb_reg(dm, REG_AFE_XTAL_CTRL, 0x7e000000, crystal_cap);
+ odm_set_bb_reg(dm, REG_AFE_PLL_CTRL, 0x7e, crystal_cap);
+ } else {
+ ODM_RT_TRACE(dm, ODM_COMP_CFO_TRACKING,
+ "%s(): Use default setting.\n", __func__);
+ odm_set_bb_reg(dm, REG_MAC_PHY_CTRL, 0xFFF000,
+ (crystal_cap | (crystal_cap << 6)));
+ }
+
+ ODM_RT_TRACE(dm, ODM_COMP_CFO_TRACKING, "%s(): crystal_cap = 0x%x\n",
+ __func__, crystal_cap);
+
+ /* JJ modified 20161115 */
+}
+
+static u8 odm_get_default_crytaltal_cap(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u8 crystal_cap = 0x20;
+
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
+
+ crystal_cap = rtlefuse->crystalcap;
+
+ crystal_cap = crystal_cap & 0x3f;
+
+ return crystal_cap;
+}
+
+static void odm_set_atc_status(void *dm_void, bool atc_status)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct cfo_tracking *cfo_track =
+ (struct cfo_tracking *)phydm_get_structure(dm, PHYDM_CFOTRACK);
+
+ if (cfo_track->is_atc_status == atc_status)
+ return;
+
+ odm_set_bb_reg(dm, ODM_REG(BB_ATC, dm), ODM_BIT(BB_ATC, dm),
+ atc_status);
+ cfo_track->is_atc_status = atc_status;
+}
+
+static bool odm_get_atc_status(void *dm_void)
+{
+ bool atc_status;
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ atc_status = (bool)odm_get_bb_reg(dm, ODM_REG(BB_ATC, dm),
+ ODM_BIT(BB_ATC, dm));
+ return atc_status;
+}
+
+void odm_cfo_tracking_reset(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct cfo_tracking *cfo_track =
+ (struct cfo_tracking *)phydm_get_structure(dm, PHYDM_CFOTRACK);
+
+ cfo_track->def_x_cap = odm_get_default_crytaltal_cap(dm);
+ cfo_track->is_adjust = true;
+
+ if (cfo_track->crystal_cap > cfo_track->def_x_cap) {
+ odm_set_crystal_cap(dm, cfo_track->crystal_cap - 1);
+ ODM_RT_TRACE(dm, ODM_COMP_CFO_TRACKING,
+ "%s(): approch default value (0x%x)\n", __func__,
+ cfo_track->crystal_cap);
+ } else if (cfo_track->crystal_cap < cfo_track->def_x_cap) {
+ odm_set_crystal_cap(dm, cfo_track->crystal_cap + 1);
+ ODM_RT_TRACE(dm, ODM_COMP_CFO_TRACKING,
+ "%s(): approch default value (0x%x)\n", __func__,
+ cfo_track->crystal_cap);
+ }
+
+ odm_set_atc_status(dm, true);
+}
+
+void odm_cfo_tracking_init(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct cfo_tracking *cfo_track =
+ (struct cfo_tracking *)phydm_get_structure(dm, PHYDM_CFOTRACK);
+
+ cfo_track->crystal_cap = odm_get_default_crytaltal_cap(dm);
+ cfo_track->def_x_cap = cfo_track->crystal_cap;
+ cfo_track->is_atc_status = odm_get_atc_status(dm);
+ cfo_track->is_adjust = true;
+ ODM_RT_TRACE(dm, ODM_COMP_CFO_TRACKING, "%s()=========>\n", __func__);
+ ODM_RT_TRACE(dm, ODM_COMP_CFO_TRACKING,
+ "%s(): is_atc_status = %d, crystal_cap = 0x%x\n", __func__,
+ cfo_track->is_atc_status, cfo_track->def_x_cap);
+
+ /* Crystal cap. control by WiFi */
+ if (dm->support_ic_type & ODM_RTL8822B)
+ odm_set_bb_reg(dm, 0x10, 0x40, 0x1);
+}
+
+void odm_cfo_tracking(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct cfo_tracking *cfo_track =
+ (struct cfo_tracking *)phydm_get_structure(dm, PHYDM_CFOTRACK);
+ s32 cfo_ave = 0;
+ u32 cfo_rpt_sum, cfo_khz_avg[4] = {0};
+ s32 cfo_ave_diff;
+ s8 crystal_cap = cfo_track->crystal_cap;
+ u8 adjust_xtal = 1, i, valid_path_cnt = 0;
+
+ /* 4 Support ability */
+ if (!(dm->support_ability & ODM_BB_CFO_TRACKING)) {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_CFO_TRACKING,
+ "%s(): Return: support_ability ODM_BB_CFO_TRACKING is disabled\n",
+ __func__);
+ return;
+ }
+
+ ODM_RT_TRACE(dm, ODM_COMP_CFO_TRACKING, "%s()=========>\n", __func__);
+
+ if (!dm->is_linked || !dm->is_one_entry_only) {
+ /* 4 No link or more than one entry */
+ odm_cfo_tracking_reset(dm);
+ ODM_RT_TRACE(
+ dm, ODM_COMP_CFO_TRACKING,
+ "%s(): Reset: is_linked = %d, is_one_entry_only = %d\n",
+ __func__, dm->is_linked, dm->is_one_entry_only);
+ } else {
+ /* 3 1. CFO Tracking */
+ /* 4 1.1 No new packet */
+ if (cfo_track->packet_count == cfo_track->packet_count_pre) {
+ ODM_RT_TRACE(dm, ODM_COMP_CFO_TRACKING,
+ "%s(): packet counter doesn't change\n",
+ __func__);
+ return;
+ }
+ cfo_track->packet_count_pre = cfo_track->packet_count;
+
+ /* 4 1.2 Calculate CFO */
+ for (i = 0; i < dm->num_rf_path; i++) {
+ if (cfo_track->CFO_cnt[i] == 0)
+ continue;
+
+ valid_path_cnt++;
+ cfo_rpt_sum =
+ (u32)((cfo_track->CFO_tail[i] < 0) ?
+ (0 - cfo_track->CFO_tail[i]) :
+ cfo_track->CFO_tail[i]);
+ cfo_khz_avg[i] = CFO_HW_RPT_2_MHZ(cfo_rpt_sum) /
+ cfo_track->CFO_cnt[i];
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_CFO_TRACKING,
+ "[path %d] cfo_rpt_sum = (( %d )), CFO_cnt = (( %d )) , CFO_avg= (( %s%d )) kHz\n",
+ i, cfo_rpt_sum, cfo_track->CFO_cnt[i],
+ ((cfo_track->CFO_tail[i] < 0) ? "-" : " "),
+ cfo_khz_avg[i]);
+ }
+
+ for (i = 0; i < valid_path_cnt; i++) {
+ if (cfo_track->CFO_tail[i] < 0) {
+ /* */
+ cfo_ave += (0 - (s32)cfo_khz_avg[i]);
+ } else {
+ cfo_ave += (s32)cfo_khz_avg[i];
+ }
+ }
+
+ if (valid_path_cnt >= 2)
+ cfo_ave = cfo_ave / valid_path_cnt;
+
+ ODM_RT_TRACE(dm, ODM_COMP_CFO_TRACKING,
+ "valid_path_cnt = ((%d)), cfo_ave = ((%d kHz))\n",
+ valid_path_cnt, cfo_ave);
+
+ /*reset counter*/
+ for (i = 0; i < dm->num_rf_path; i++) {
+ cfo_track->CFO_tail[i] = 0;
+ cfo_track->CFO_cnt[i] = 0;
+ }
+
+ /* 4 1.3 Avoid abnormal large CFO */
+ cfo_ave_diff = (cfo_track->CFO_ave_pre >= cfo_ave) ?
+ (cfo_track->CFO_ave_pre - cfo_ave) :
+ (cfo_ave - cfo_track->CFO_ave_pre);
+ if (cfo_ave_diff > 20 && cfo_track->large_cfo_hit == 0 &&
+ !cfo_track->is_adjust) {
+ ODM_RT_TRACE(dm, ODM_COMP_CFO_TRACKING,
+ "%s(): first large CFO hit\n", __func__);
+ cfo_track->large_cfo_hit = 1;
+ return;
+ }
+
+ cfo_track->large_cfo_hit = 0;
+ cfo_track->CFO_ave_pre = cfo_ave;
+
+ /* 4 1.4 Dynamic Xtal threshold */
+ if (!cfo_track->is_adjust) {
+ if (cfo_ave > CFO_TH_XTAL_HIGH ||
+ cfo_ave < (-CFO_TH_XTAL_HIGH))
+ cfo_track->is_adjust = true;
+ } else {
+ if (cfo_ave < CFO_TH_XTAL_LOW &&
+ cfo_ave > (-CFO_TH_XTAL_LOW))
+ cfo_track->is_adjust = false;
+ }
+
+ /* 4 1.5 BT case: Disable CFO tracking */
+ if (dm->is_bt_enabled) {
+ cfo_track->is_adjust = false;
+ odm_set_crystal_cap(dm, cfo_track->def_x_cap);
+ ODM_RT_TRACE(dm, ODM_COMP_CFO_TRACKING,
+ "%s(): Disable CFO tracking for BT!!\n",
+ __func__);
+ }
+
+ /* 4 1.7 Adjust Crystal Cap. */
+ if (cfo_track->is_adjust) {
+ if (cfo_ave > CFO_TH_XTAL_LOW)
+ crystal_cap = crystal_cap + adjust_xtal;
+ else if (cfo_ave < (-CFO_TH_XTAL_LOW))
+ crystal_cap = crystal_cap - adjust_xtal;
+
+ if (crystal_cap > 0x3f)
+ crystal_cap = 0x3f;
+ else if (crystal_cap < 0)
+ crystal_cap = 0;
+
+ odm_set_crystal_cap(dm, (u8)crystal_cap);
+ }
+ ODM_RT_TRACE(
+ dm, ODM_COMP_CFO_TRACKING,
+ "%s(): Crystal cap = 0x%x, Default Crystal cap = 0x%x\n",
+ __func__, cfo_track->crystal_cap, cfo_track->def_x_cap);
+
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES)
+ return;
+
+ /* 3 2. Dynamic ATC switch */
+ if (cfo_ave < CFO_TH_ATC && cfo_ave > -CFO_TH_ATC) {
+ odm_set_atc_status(dm, false);
+ ODM_RT_TRACE(dm, ODM_COMP_CFO_TRACKING,
+ "%s(): Disable ATC!!\n", __func__);
+ } else {
+ odm_set_atc_status(dm, true);
+ ODM_RT_TRACE(dm, ODM_COMP_CFO_TRACKING,
+ "%s(): Enable ATC!!\n", __func__);
+ }
+ }
+}
+
+void odm_parsing_cfo(void *dm_void, void *pktinfo_void, s8 *pcfotail, u8 num_ss)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct dm_per_pkt_info *pktinfo =
+ (struct dm_per_pkt_info *)pktinfo_void;
+ struct cfo_tracking *cfo_track =
+ (struct cfo_tracking *)phydm_get_structure(dm, PHYDM_CFOTRACK);
+ u8 i;
+
+ if (!(dm->support_ability & ODM_BB_CFO_TRACKING))
+ return;
+
+ if (pktinfo->is_packet_match_bssid) {
+ if (num_ss > dm->num_rf_path) /*For fool proof*/
+ num_ss = dm->num_rf_path;
+
+ /* 3 Update CFO report for path-A & path-B */
+ /* Only paht-A and path-B have CFO tail and short CFO */
+ for (i = 0; i < num_ss; i++) {
+ cfo_track->CFO_tail[i] += pcfotail[i];
+ cfo_track->CFO_cnt[i]++;
+ }
+
+ /* 3 Update packet counter */
+ if (cfo_track->packet_count == 0xffffffff)
+ cfo_track->packet_count = 0;
+ else
+ cfo_track->packet_count++;
+ }
+}
diff --git a/drivers/staging/rtlwifi/phydm/phydm_cfotracking.h b/drivers/staging/rtlwifi/phydm/phydm_cfotracking.h
new file mode 100644
index 0000000..e8436a3
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_cfotracking.h
@@ -0,0 +1,60 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __PHYDMCFOTRACK_H__
+#define __PHYDMCFOTRACK_H__
+
+#define CFO_TRACKING_VERSION "1.4" /*2015.10.01 Stanley, Modify for 8822B*/
+
+#define CFO_TH_XTAL_HIGH 20 /* kHz */
+#define CFO_TH_XTAL_LOW 10 /* kHz */
+#define CFO_TH_ATC 80 /* kHz */
+
+struct cfo_tracking {
+ bool is_atc_status;
+ bool large_cfo_hit;
+ bool is_adjust;
+ u8 crystal_cap;
+ u8 def_x_cap;
+ s32 CFO_tail[4];
+ u32 CFO_cnt[4];
+ s32 CFO_ave_pre;
+ u32 packet_count;
+ u32 packet_count_pre;
+
+ bool is_force_xtal_cap;
+ bool is_reset;
+};
+
+void odm_cfo_tracking_reset(void *dm_void);
+
+void odm_cfo_tracking_init(void *dm_void);
+
+void odm_cfo_tracking(void *dm_void);
+
+void odm_parsing_cfo(void *dm_void, void *pktinfo_void, s8 *pcfotail,
+ u8 num_ss);
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/phydm_debug.c b/drivers/staging/rtlwifi/phydm/phydm_debug.c
new file mode 100644
index 0000000..a5f90af
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_debug.c
@@ -0,0 +1,2910 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+/* ************************************************************
+ * include files
+ * *************************************************************/
+
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+bool phydm_api_set_txagc(struct phy_dm_struct *, u32, enum odm_rf_radio_path,
+ u8, bool);
+static inline void phydm_check_dmval_txagc(struct phy_dm_struct *dm, u32 used,
+ u32 out_len, u32 *const dm_value,
+ char *output)
+{
+ if ((u8)dm_value[2] != 0xff) {
+ if (phydm_api_set_txagc(dm, dm_value[3],
+ (enum odm_rf_radio_path)dm_value[1],
+ (u8)dm_value[2], true))
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ " %s%d %s%x%s%x\n", "Write path-",
+ dm_value[1], "rate index-0x",
+ dm_value[2], " = 0x", dm_value[3]);
+ else
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ " %s%d %s%x%s\n", "Write path-",
+ (dm_value[1] & 0x1), "rate index-0x",
+ (dm_value[2] & 0x7f), " fail");
+ } else {
+ u8 i;
+ u32 power_index;
+ bool status = true;
+
+ power_index = (dm_value[3] & 0x3f);
+
+ if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8821C)) {
+ power_index = (power_index << 24) |
+ (power_index << 16) | (power_index << 8) |
+ (power_index);
+ for (i = 0; i < ODM_RATEVHTSS2MCS9; i += 4)
+ status = (status &
+ phydm_api_set_txagc(
+ dm, power_index,
+ (enum odm_rf_radio_path)
+ dm_value[1],
+ i, false));
+ } else if (dm->support_ic_type & ODM_RTL8197F) {
+ for (i = 0; i <= ODM_RATEMCS15; i++)
+ status = (status &
+ phydm_api_set_txagc(
+ dm, power_index,
+ (enum odm_rf_radio_path)
+ dm_value[1],
+ i, false));
+ }
+
+ if (status)
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ " %s%d %s%x\n",
+ "Write all TXAGC of path-", dm_value[1],
+ " = 0x", dm_value[3]);
+ else
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ " %s%d %s\n",
+ "Write all TXAGC of path-", dm_value[1],
+ " fail");
+ }
+}
+
+static inline void phydm_print_nhm_trigger(char *output, u32 used, u32 out_len,
+ struct ccx_info *ccx_info)
+{
+ int i;
+
+ for (i = 0; i <= 10; i++) {
+ if (i == 5)
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "\r\n NHM_th[%d] = 0x%x, echo_IGI = 0x%x", i,
+ ccx_info->NHM_th[i], ccx_info->echo_IGI);
+ else if (i == 10)
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n NHM_th[%d] = 0x%x\n", i,
+ ccx_info->NHM_th[i]);
+ else
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n NHM_th[%d] = 0x%x", i,
+ ccx_info->NHM_th[i]);
+ }
+}
+
+static inline void phydm_print_nhm_result(char *output, u32 used, u32 out_len,
+ struct ccx_info *ccx_info)
+{
+ int i;
+
+ for (i = 0; i <= 11; i++) {
+ if (i == 5)
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "\r\n nhm_result[%d] = %d, echo_IGI = 0x%x", i,
+ ccx_info->NHM_result[i], ccx_info->echo_IGI);
+ else if (i == 11)
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n nhm_result[%d] = %d\n", i,
+ ccx_info->NHM_result[i]);
+ else
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n nhm_result[%d] = %d", i,
+ ccx_info->NHM_result[i]);
+ }
+}
+
+static inline void phydm_print_csi(struct phy_dm_struct *dm, u32 used,
+ u32 out_len, char *output)
+{
+ int index, ptr;
+ u32 dword_h, dword_l;
+
+ for (index = 0; index < 80; index++) {
+ ptr = index + 256;
+
+ if (ptr > 311)
+ ptr -= 312;
+
+ odm_set_bb_reg(dm, 0x1910, 0x03FF0000, ptr); /*Select Address*/
+ dword_h = odm_get_bb_reg(dm, 0xF74, MASKDWORD);
+ dword_l = odm_get_bb_reg(dm, 0xF5C, MASKDWORD);
+
+ if (index % 2 == 0)
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "%02x %02x %02x %02x %02x %02x %02x %02x\n",
+ dword_l & MASKBYTE0, (dword_l & MASKBYTE1) >> 8,
+ (dword_l & MASKBYTE2) >> 16,
+ (dword_l & MASKBYTE3) >> 24,
+ dword_h & MASKBYTE0, (dword_h & MASKBYTE1) >> 8,
+ (dword_h & MASKBYTE2) >> 16,
+ (dword_h & MASKBYTE3) >> 24);
+ else
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "%02x %02x %02x %02x %02x %02x %02x %02x\n",
+ dword_l & MASKBYTE0, (dword_l & MASKBYTE1) >> 8,
+ (dword_l & MASKBYTE2) >> 16,
+ (dword_l & MASKBYTE3) >> 24,
+ dword_h & MASKBYTE0, (dword_h & MASKBYTE1) >> 8,
+ (dword_h & MASKBYTE2) >> 16,
+ (dword_h & MASKBYTE3) >> 24);
+ }
+}
+
+void phydm_init_debug_setting(struct phy_dm_struct *dm)
+{
+ dm->debug_level = ODM_DBG_TRACE;
+
+ dm->fw_debug_components = 0;
+ dm->debug_components =
+
+ 0;
+
+ dm->fw_buff_is_enpty = true;
+ dm->pre_c2h_seq = 0;
+}
+
+u8 phydm_set_bb_dbg_port(void *dm_void, u8 curr_dbg_priority, u32 debug_port)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u8 dbg_port_result = false;
+
+ if (curr_dbg_priority > dm->pre_dbg_priority) {
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ odm_set_bb_reg(dm, 0x8fc, MASKDWORD, debug_port);
+ /**/
+ } else /*if (dm->support_ic_type & ODM_IC_11N_SERIES)*/ {
+ odm_set_bb_reg(dm, 0x908, MASKDWORD, debug_port);
+ /**/
+ }
+ ODM_RT_TRACE(
+ dm, ODM_COMP_API,
+ "DbgPort set success, Reg((0x%x)), Cur_priority=((%d)), Pre_priority=((%d))\n",
+ debug_port, curr_dbg_priority, dm->pre_dbg_priority);
+ dm->pre_dbg_priority = curr_dbg_priority;
+ dbg_port_result = true;
+ }
+
+ return dbg_port_result;
+}
+
+void phydm_release_bb_dbg_port(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ dm->pre_dbg_priority = BB_DBGPORT_RELEASE;
+ ODM_RT_TRACE(dm, ODM_COMP_API, "Release BB dbg_port\n");
+}
+
+u32 phydm_get_bb_dbg_port_value(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 dbg_port_value = 0;
+
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ dbg_port_value = odm_get_bb_reg(dm, 0xfa0, MASKDWORD);
+ /**/
+ } else /*if (dm->support_ic_type & ODM_IC_11N_SERIES)*/ {
+ dbg_port_value = odm_get_bb_reg(dm, 0xdf4, MASKDWORD);
+ /**/
+ }
+ ODM_RT_TRACE(dm, ODM_COMP_API, "dbg_port_value = 0x%x\n",
+ dbg_port_value);
+ return dbg_port_value;
+}
+
+static void phydm_bb_rx_hang_info(void *dm_void, u32 *_used, char *output,
+ u32 *_out_len)
+{
+ u32 value32 = 0;
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ if (dm->support_ic_type & ODM_IC_11N_SERIES)
+ return;
+
+ value32 = odm_get_bb_reg(dm, 0xF80, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = 0x%x",
+ "rptreg of sc/bw/ht/...", value32);
+
+ if (dm->support_ic_type & ODM_RTL8822B)
+ odm_set_bb_reg(dm, 0x198c, BIT(2) | BIT(1) | BIT(0), 7);
+
+ /* dbg_port = basic state machine */
+ {
+ odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0x000);
+ value32 = odm_get_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "0x8fc", value32);
+
+ value32 = odm_get_bb_reg(dm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "basic state machine",
+ value32);
+ }
+
+ /* dbg_port = state machine */
+ {
+ odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0x007);
+ value32 = odm_get_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "0x8fc", value32);
+
+ value32 = odm_get_bb_reg(dm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "state machine", value32);
+ }
+
+ /* dbg_port = CCA-related*/
+ {
+ odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0x204);
+ value32 = odm_get_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "0x8fc", value32);
+
+ value32 = odm_get_bb_reg(dm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "CCA-related", value32);
+ }
+
+ /* dbg_port = edcca/rxd*/
+ {
+ odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0x278);
+ value32 = odm_get_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "0x8fc", value32);
+
+ value32 = odm_get_bb_reg(dm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "edcca/rxd", value32);
+ }
+
+ /* dbg_port = rx_state/mux_state/ADC_MASK_OFDM*/
+ {
+ odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0x290);
+ value32 = odm_get_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "0x8fc", value32);
+
+ value32 = odm_get_bb_reg(dm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x",
+ "rx_state/mux_state/ADC_MASK_OFDM", value32);
+ }
+
+ /* dbg_port = bf-related*/
+ {
+ odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0x2B2);
+ value32 = odm_get_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "0x8fc", value32);
+
+ value32 = odm_get_bb_reg(dm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "bf-related", value32);
+ }
+
+ /* dbg_port = bf-related*/
+ {
+ odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0x2B8);
+ value32 = odm_get_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "0x8fc", value32);
+
+ value32 = odm_get_bb_reg(dm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "bf-related", value32);
+ }
+
+ /* dbg_port = txon/rxd*/
+ {
+ odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0xA03);
+ value32 = odm_get_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "0x8fc", value32);
+
+ value32 = odm_get_bb_reg(dm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "txon/rxd", value32);
+ }
+
+ /* dbg_port = l_rate/l_length*/
+ {
+ odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0xA0B);
+ value32 = odm_get_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "0x8fc", value32);
+
+ value32 = odm_get_bb_reg(dm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "l_rate/l_length", value32);
+ }
+
+ /* dbg_port = rxd/rxd_hit*/
+ {
+ odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0xA0D);
+ value32 = odm_get_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "0x8fc", value32);
+
+ value32 = odm_get_bb_reg(dm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "rxd/rxd_hit", value32);
+ }
+
+ /* dbg_port = dis_cca*/
+ {
+ odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0xAA0);
+ value32 = odm_get_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "0x8fc", value32);
+
+ value32 = odm_get_bb_reg(dm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "dis_cca", value32);
+ }
+
+ /* dbg_port = tx*/
+ {
+ odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0xAB0);
+ value32 = odm_get_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "0x8fc", value32);
+
+ value32 = odm_get_bb_reg(dm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "tx", value32);
+ }
+
+ /* dbg_port = rx plcp*/
+ {
+ odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0xAD0);
+ value32 = odm_get_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "0x8fc", value32);
+
+ value32 = odm_get_bb_reg(dm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "rx plcp", value32);
+
+ odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0xAD1);
+ value32 = odm_get_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "0x8fc", value32);
+
+ value32 = odm_get_bb_reg(dm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "rx plcp", value32);
+
+ odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0xAD2);
+ value32 = odm_get_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "0x8fc", value32);
+
+ value32 = odm_get_bb_reg(dm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "rx plcp", value32);
+
+ odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0xAD3);
+ value32 = odm_get_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "0x8fc", value32);
+
+ value32 = odm_get_bb_reg(dm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = 0x%x", "rx plcp", value32);
+ }
+}
+
+static void phydm_bb_debug_info_n_series(void *dm_void, u32 *_used,
+ char *output, u32 *_out_len)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ u32 value32 = 0, value32_1 = 0;
+ u8 rf_gain_a = 0, rf_gain_b = 0, rf_gain_c = 0, rf_gain_d = 0;
+ u8 rx_snr_a = 0, rx_snr_b = 0, rx_snr_c = 0, rx_snr_d = 0;
+
+ s8 rxevm_0 = 0, rxevm_1 = 0;
+ s32 short_cfo_a = 0, short_cfo_b = 0, long_cfo_a = 0, long_cfo_b = 0;
+ s32 scfo_a = 0, scfo_b = 0, avg_cfo_a = 0, avg_cfo_b = 0;
+ s32 cfo_end_a = 0, cfo_end_b = 0, acq_cfo_a = 0, acq_cfo_b = 0;
+
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s\n",
+ "BB Report Info");
+
+ /*AGC result*/
+ value32 = odm_get_bb_reg(dm, 0xdd0, MASKDWORD);
+ rf_gain_a = (u8)(value32 & 0x3f);
+ rf_gain_a = rf_gain_a << 1;
+
+ rf_gain_b = (u8)((value32 >> 8) & 0x3f);
+ rf_gain_b = rf_gain_b << 1;
+
+ rf_gain_c = (u8)((value32 >> 16) & 0x3f);
+ rf_gain_c = rf_gain_c << 1;
+
+ rf_gain_d = (u8)((value32 >> 24) & 0x3f);
+ rf_gain_d = rf_gain_d << 1;
+
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = %d / %d / %d / %d",
+ "OFDM RX RF Gain(A/B/C/D)", rf_gain_a, rf_gain_b,
+ rf_gain_c, rf_gain_d);
+
+ /*SNR report*/
+ value32 = odm_get_bb_reg(dm, 0xdd4, MASKDWORD);
+ rx_snr_a = (u8)(value32 & 0xff);
+ rx_snr_a = rx_snr_a >> 1;
+
+ rx_snr_b = (u8)((value32 >> 8) & 0xff);
+ rx_snr_b = rx_snr_b >> 1;
+
+ rx_snr_c = (u8)((value32 >> 16) & 0xff);
+ rx_snr_c = rx_snr_c >> 1;
+
+ rx_snr_d = (u8)((value32 >> 24) & 0xff);
+ rx_snr_d = rx_snr_d >> 1;
+
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = %d / %d / %d / %d", "RXSNR(A/B/C/D, dB)",
+ rx_snr_a, rx_snr_b, rx_snr_c, rx_snr_d);
+
+ /* PostFFT related info*/
+ value32 = odm_get_bb_reg(dm, 0xdd8, MASKDWORD);
+
+ rxevm_0 = (s8)((value32 & MASKBYTE2) >> 16);
+ rxevm_0 /= 2;
+ if (rxevm_0 < -63)
+ rxevm_0 = 0;
+
+ rxevm_1 = (s8)((value32 & MASKBYTE3) >> 24);
+ rxevm_1 /= 2;
+ if (rxevm_1 < -63)
+ rxevm_1 = 0;
+
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d",
+ "RXEVM (1ss/2ss)", rxevm_0, rxevm_1);
+
+ /*CFO Report Info*/
+ odm_set_bb_reg(dm, 0xd00, BIT(26), 1);
+
+ /*Short CFO*/
+ value32 = odm_get_bb_reg(dm, 0xdac, MASKDWORD);
+ value32_1 = odm_get_bb_reg(dm, 0xdb0, MASKDWORD);
+
+ short_cfo_b = (s32)(value32 & 0xfff); /*S(12,11)*/
+ short_cfo_a = (s32)((value32 & 0x0fff0000) >> 16);
+
+ long_cfo_b = (s32)(value32_1 & 0x1fff); /*S(13,12)*/
+ long_cfo_a = (s32)((value32_1 & 0x1fff0000) >> 16);
+
+ /*SFO 2's to dec*/
+ if (short_cfo_a > 2047)
+ short_cfo_a = short_cfo_a - 4096;
+ if (short_cfo_b > 2047)
+ short_cfo_b = short_cfo_b - 4096;
+
+ short_cfo_a = (short_cfo_a * 312500) / 2048;
+ short_cfo_b = (short_cfo_b * 312500) / 2048;
+
+ /*LFO 2's to dec*/
+
+ if (long_cfo_a > 4095)
+ long_cfo_a = long_cfo_a - 8192;
+
+ if (long_cfo_b > 4095)
+ long_cfo_b = long_cfo_b - 8192;
+
+ long_cfo_a = long_cfo_a * 312500 / 4096;
+ long_cfo_b = long_cfo_b * 312500 / 4096;
+
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s",
+ "CFO Report Info");
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d",
+ "Short CFO(Hz) <A/B>", short_cfo_a, short_cfo_b);
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d",
+ "Long CFO(Hz) <A/B>", long_cfo_a, long_cfo_b);
+
+ /*SCFO*/
+ value32 = odm_get_bb_reg(dm, 0xdb8, MASKDWORD);
+ value32_1 = odm_get_bb_reg(dm, 0xdb4, MASKDWORD);
+
+ scfo_b = (s32)(value32 & 0x7ff); /*S(11,10)*/
+ scfo_a = (s32)((value32 & 0x07ff0000) >> 16);
+
+ if (scfo_a > 1023)
+ scfo_a = scfo_a - 2048;
+
+ if (scfo_b > 1023)
+ scfo_b = scfo_b - 2048;
+
+ scfo_a = scfo_a * 312500 / 1024;
+ scfo_b = scfo_b * 312500 / 1024;
+
+ avg_cfo_b = (s32)(value32_1 & 0x1fff); /*S(13,12)*/
+ avg_cfo_a = (s32)((value32_1 & 0x1fff0000) >> 16);
+
+ if (avg_cfo_a > 4095)
+ avg_cfo_a = avg_cfo_a - 8192;
+
+ if (avg_cfo_b > 4095)
+ avg_cfo_b = avg_cfo_b - 8192;
+
+ avg_cfo_a = avg_cfo_a * 312500 / 4096;
+ avg_cfo_b = avg_cfo_b * 312500 / 4096;
+
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d",
+ "value SCFO(Hz) <A/B>", scfo_a, scfo_b);
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d",
+ "Avg CFO(Hz) <A/B>", avg_cfo_a, avg_cfo_b);
+
+ value32 = odm_get_bb_reg(dm, 0xdbc, MASKDWORD);
+ value32_1 = odm_get_bb_reg(dm, 0xde0, MASKDWORD);
+
+ cfo_end_b = (s32)(value32 & 0x1fff); /*S(13,12)*/
+ cfo_end_a = (s32)((value32 & 0x1fff0000) >> 16);
+
+ if (cfo_end_a > 4095)
+ cfo_end_a = cfo_end_a - 8192;
+
+ if (cfo_end_b > 4095)
+ cfo_end_b = cfo_end_b - 8192;
+
+ cfo_end_a = cfo_end_a * 312500 / 4096;
+ cfo_end_b = cfo_end_b * 312500 / 4096;
+
+ acq_cfo_b = (s32)(value32_1 & 0x1fff); /*S(13,12)*/
+ acq_cfo_a = (s32)((value32_1 & 0x1fff0000) >> 16);
+
+ if (acq_cfo_a > 4095)
+ acq_cfo_a = acq_cfo_a - 8192;
+
+ if (acq_cfo_b > 4095)
+ acq_cfo_b = acq_cfo_b - 8192;
+
+ acq_cfo_a = acq_cfo_a * 312500 / 4096;
+ acq_cfo_b = acq_cfo_b * 312500 / 4096;
+
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d",
+ "End CFO(Hz) <A/B>", cfo_end_a, cfo_end_b);
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d",
+ "ACQ CFO(Hz) <A/B>", acq_cfo_a, acq_cfo_b);
+}
+
+static void phydm_bb_debug_info(void *dm_void, u32 *_used, char *output,
+ u32 *_out_len)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ char *tmp_string = NULL;
+
+ u8 rx_ht_bw, rx_vht_bw, rxsc, rx_ht, rx_bw;
+ static u8 v_rx_bw;
+ u32 value32, value32_1, value32_2, value32_3;
+ s32 sfo_a, sfo_b, sfo_c, sfo_d;
+ s32 lfo_a, lfo_b, lfo_c, lfo_d;
+ static u8 MCSS, tail, parity, rsv, vrsv, idx, smooth, htsound, agg,
+ stbc, vstbc, fec, fecext, sgi, sgiext, htltf, vgid, v_nsts,
+ vtxops, vrsv2, vbrsv, bf, vbcrc;
+ static u16 h_length, htcrc8, length;
+ static u16 vpaid;
+ static u16 v_length, vhtcrc8, v_mcss, v_tail, vb_tail;
+ static u8 hmcss, hrx_bw;
+
+ u8 pwdb;
+ s8 rxevm_0, rxevm_1, rxevm_2;
+ u8 rf_gain_path_a, rf_gain_path_b, rf_gain_path_c, rf_gain_path_d;
+ u8 rx_snr_path_a, rx_snr_path_b, rx_snr_path_c, rx_snr_path_d;
+ s32 sig_power;
+
+ const char *L_rate[8] = {"6M", "9M", "12M", "18M",
+ "24M", "36M", "48M", "54M"};
+
+ if (dm->support_ic_type & ODM_IC_11N_SERIES) {
+ phydm_bb_debug_info_n_series(dm, &used, output, &out_len);
+ return;
+ }
+
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s\n",
+ "BB Report Info");
+
+ /*BW & mode Detection*/
+
+ value32 = odm_get_bb_reg(dm, 0xf80, MASKDWORD);
+ value32_2 = value32;
+ rx_ht_bw = (u8)(value32 & 0x1);
+ rx_vht_bw = (u8)((value32 >> 1) & 0x3);
+ rxsc = (u8)(value32 & 0x78);
+ value32_1 = (value32 & 0x180) >> 7;
+ rx_ht = (u8)(value32_1);
+
+ rx_bw = 0;
+
+ if (rx_ht == 2) {
+ if (rx_vht_bw == 0)
+ tmp_string = "20M";
+ else if (rx_vht_bw == 1)
+ tmp_string = "40M";
+ else
+ tmp_string = "80M";
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s %s %s", "mode", "VHT", tmp_string);
+ rx_bw = rx_vht_bw;
+ } else if (rx_ht == 1) {
+ if (rx_ht_bw == 0)
+ tmp_string = "20M";
+ else if (rx_ht_bw == 1)
+ tmp_string = "40M";
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s %s %s", "mode", "HT", tmp_string);
+ rx_bw = rx_ht_bw;
+ } else {
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s %s",
+ "mode", "Legacy");
+ }
+ if (rx_ht != 0) {
+ if (rxsc == 0)
+ tmp_string = "duplicate/full bw";
+ else if (rxsc == 1)
+ tmp_string = "usc20-1";
+ else if (rxsc == 2)
+ tmp_string = "lsc20-1";
+ else if (rxsc == 3)
+ tmp_string = "usc20-2";
+ else if (rxsc == 4)
+ tmp_string = "lsc20-2";
+ else if (rxsc == 9)
+ tmp_string = "usc40";
+ else if (rxsc == 10)
+ tmp_string = "lsc40";
+ PHYDM_SNPRINTF(output + used, out_len - used, " %-35s",
+ tmp_string);
+ }
+
+ /* RX signal power and AGC related info*/
+
+ value32 = odm_get_bb_reg(dm, 0xF90, MASKDWORD);
+ pwdb = (u8)((value32 & MASKBYTE1) >> 8);
+ pwdb = pwdb >> 1;
+ sig_power = -110 + pwdb;
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d",
+ "OFDM RX Signal Power(dB)", sig_power);
+
+ value32 = odm_get_bb_reg(dm, 0xd14, MASKDWORD);
+ rx_snr_path_a = (u8)(value32 & 0xFF) >> 1;
+ rf_gain_path_a = (s8)((value32 & MASKBYTE1) >> 8);
+ rf_gain_path_a *= 2;
+ value32 = odm_get_bb_reg(dm, 0xd54, MASKDWORD);
+ rx_snr_path_b = (u8)(value32 & 0xFF) >> 1;
+ rf_gain_path_b = (s8)((value32 & MASKBYTE1) >> 8);
+ rf_gain_path_b *= 2;
+ value32 = odm_get_bb_reg(dm, 0xd94, MASKDWORD);
+ rx_snr_path_c = (u8)(value32 & 0xFF) >> 1;
+ rf_gain_path_c = (s8)((value32 & MASKBYTE1) >> 8);
+ rf_gain_path_c *= 2;
+ value32 = odm_get_bb_reg(dm, 0xdd4, MASKDWORD);
+ rx_snr_path_d = (u8)(value32 & 0xFF) >> 1;
+ rf_gain_path_d = (s8)((value32 & MASKBYTE1) >> 8);
+ rf_gain_path_d *= 2;
+
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = %d / %d / %d / %d",
+ "OFDM RX RF Gain(A/B/C/D)", rf_gain_path_a,
+ rf_gain_path_b, rf_gain_path_c, rf_gain_path_d);
+
+ /* RX counter related info*/
+
+ value32 = odm_get_bb_reg(dm, 0xF08, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d",
+ "OFDM CCA counter", ((value32 & 0xFFFF0000) >> 16));
+
+ value32 = odm_get_bb_reg(dm, 0xFD0, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d",
+ "OFDM SBD Fail counter", value32 & 0xFFFF);
+
+ value32 = odm_get_bb_reg(dm, 0xFC4, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d",
+ "VHT SIGA/SIGB CRC8 Fail counter", value32 & 0xFFFF,
+ ((value32 & 0xFFFF0000) >> 16));
+
+ value32 = odm_get_bb_reg(dm, 0xFCC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d",
+ "CCK CCA counter", value32 & 0xFFFF);
+
+ value32 = odm_get_bb_reg(dm, 0xFBC, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d",
+ "LSIG (parity Fail/rate Illegal) counter",
+ value32 & 0xFFFF, ((value32 & 0xFFFF0000) >> 16));
+
+ value32_1 = odm_get_bb_reg(dm, 0xFC8, MASKDWORD);
+ value32_2 = odm_get_bb_reg(dm, 0xFC0, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d",
+ "HT/VHT MCS NOT SUPPORT counter",
+ ((value32_2 & 0xFFFF0000) >> 16), value32_1 & 0xFFFF);
+
+ /* PostFFT related info*/
+ value32 = odm_get_bb_reg(dm, 0xF8c, MASKDWORD);
+ rxevm_0 = (s8)((value32 & MASKBYTE2) >> 16);
+ rxevm_0 /= 2;
+ if (rxevm_0 < -63)
+ rxevm_0 = 0;
+
+ rxevm_1 = (s8)((value32 & MASKBYTE3) >> 24);
+ rxevm_1 /= 2;
+ value32 = odm_get_bb_reg(dm, 0xF88, MASKDWORD);
+ rxevm_2 = (s8)((value32 & MASKBYTE2) >> 16);
+ rxevm_2 /= 2;
+
+ if (rxevm_1 < -63)
+ rxevm_1 = 0;
+ if (rxevm_2 < -63)
+ rxevm_2 = 0;
+
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = %d / %d / %d", "RXEVM (1ss/2ss/3ss)",
+ rxevm_0, rxevm_1, rxevm_2);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = %d / %d / %d / %d", "RXSNR(A/B/C/D, dB)",
+ rx_snr_path_a, rx_snr_path_b, rx_snr_path_c,
+ rx_snr_path_d);
+
+ value32 = odm_get_bb_reg(dm, 0xF8C, MASKDWORD);
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d",
+ "CSI_1st /CSI_2nd", value32 & 0xFFFF,
+ ((value32 & 0xFFFF0000) >> 16));
+
+ /*BW & mode Detection*/
+
+ /*Reset Page F counter*/
+ odm_set_bb_reg(dm, 0xB58, BIT(0), 1);
+ odm_set_bb_reg(dm, 0xB58, BIT(0), 0);
+
+ /*CFO Report Info*/
+ /*Short CFO*/
+ value32 = odm_get_bb_reg(dm, 0xd0c, MASKDWORD);
+ value32_1 = odm_get_bb_reg(dm, 0xd4c, MASKDWORD);
+ value32_2 = odm_get_bb_reg(dm, 0xd8c, MASKDWORD);
+ value32_3 = odm_get_bb_reg(dm, 0xdcc, MASKDWORD);
+
+ sfo_a = (s32)(value32 & 0xfff);
+ sfo_b = (s32)(value32_1 & 0xfff);
+ sfo_c = (s32)(value32_2 & 0xfff);
+ sfo_d = (s32)(value32_3 & 0xfff);
+
+ lfo_a = (s32)(value32 >> 16);
+ lfo_b = (s32)(value32_1 >> 16);
+ lfo_c = (s32)(value32_2 >> 16);
+ lfo_d = (s32)(value32_3 >> 16);
+
+ /*SFO 2's to dec*/
+ if (sfo_a > 2047)
+ sfo_a = sfo_a - 4096;
+ sfo_a = (sfo_a * 312500) / 2048;
+ if (sfo_b > 2047)
+ sfo_b = sfo_b - 4096;
+ sfo_b = (sfo_b * 312500) / 2048;
+ if (sfo_c > 2047)
+ sfo_c = sfo_c - 4096;
+ sfo_c = (sfo_c * 312500) / 2048;
+ if (sfo_d > 2047)
+ sfo_d = sfo_d - 4096;
+ sfo_d = (sfo_d * 312500) / 2048;
+
+ /*LFO 2's to dec*/
+
+ if (lfo_a > 4095)
+ lfo_a = lfo_a - 8192;
+
+ if (lfo_b > 4095)
+ lfo_b = lfo_b - 8192;
+
+ if (lfo_c > 4095)
+ lfo_c = lfo_c - 8192;
+
+ if (lfo_d > 4095)
+ lfo_d = lfo_d - 8192;
+ lfo_a = lfo_a * 312500 / 4096;
+ lfo_b = lfo_b * 312500 / 4096;
+ lfo_c = lfo_c * 312500 / 4096;
+ lfo_d = lfo_d * 312500 / 4096;
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s",
+ "CFO Report Info");
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = %d / %d / %d /%d",
+ "Short CFO(Hz) <A/B/C/D>", sfo_a, sfo_b, sfo_c, sfo_d);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = %d / %d / %d /%d",
+ "Long CFO(Hz) <A/B/C/D>", lfo_a, lfo_b, lfo_c, lfo_d);
+
+ /*SCFO*/
+ value32 = odm_get_bb_reg(dm, 0xd10, MASKDWORD);
+ value32_1 = odm_get_bb_reg(dm, 0xd50, MASKDWORD);
+ value32_2 = odm_get_bb_reg(dm, 0xd90, MASKDWORD);
+ value32_3 = odm_get_bb_reg(dm, 0xdd0, MASKDWORD);
+
+ sfo_a = (s32)(value32 & 0x7ff);
+ sfo_b = (s32)(value32_1 & 0x7ff);
+ sfo_c = (s32)(value32_2 & 0x7ff);
+ sfo_d = (s32)(value32_3 & 0x7ff);
+
+ if (sfo_a > 1023)
+ sfo_a = sfo_a - 2048;
+
+ if (sfo_b > 2047)
+ sfo_b = sfo_b - 4096;
+
+ if (sfo_c > 2047)
+ sfo_c = sfo_c - 4096;
+
+ if (sfo_d > 2047)
+ sfo_d = sfo_d - 4096;
+
+ sfo_a = sfo_a * 312500 / 1024;
+ sfo_b = sfo_b * 312500 / 1024;
+ sfo_c = sfo_c * 312500 / 1024;
+ sfo_d = sfo_d * 312500 / 1024;
+
+ lfo_a = (s32)(value32 >> 16);
+ lfo_b = (s32)(value32_1 >> 16);
+ lfo_c = (s32)(value32_2 >> 16);
+ lfo_d = (s32)(value32_3 >> 16);
+
+ if (lfo_a > 4095)
+ lfo_a = lfo_a - 8192;
+
+ if (lfo_b > 4095)
+ lfo_b = lfo_b - 8192;
+
+ if (lfo_c > 4095)
+ lfo_c = lfo_c - 8192;
+
+ if (lfo_d > 4095)
+ lfo_d = lfo_d - 8192;
+ lfo_a = lfo_a * 312500 / 4096;
+ lfo_b = lfo_b * 312500 / 4096;
+ lfo_c = lfo_c * 312500 / 4096;
+ lfo_d = lfo_d * 312500 / 4096;
+
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = %d / %d / %d /%d",
+ "value SCFO(Hz) <A/B/C/D>", sfo_a, sfo_b, sfo_c, sfo_d);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = %d / %d / %d /%d", "ACQ CFO(Hz) <A/B/C/D>",
+ lfo_a, lfo_b, lfo_c, lfo_d);
+
+ value32 = odm_get_bb_reg(dm, 0xd14, MASKDWORD);
+ value32_1 = odm_get_bb_reg(dm, 0xd54, MASKDWORD);
+ value32_2 = odm_get_bb_reg(dm, 0xd94, MASKDWORD);
+ value32_3 = odm_get_bb_reg(dm, 0xdd4, MASKDWORD);
+
+ lfo_a = (s32)(value32 >> 16);
+ lfo_b = (s32)(value32_1 >> 16);
+ lfo_c = (s32)(value32_2 >> 16);
+ lfo_d = (s32)(value32_3 >> 16);
+
+ if (lfo_a > 4095)
+ lfo_a = lfo_a - 8192;
+
+ if (lfo_b > 4095)
+ lfo_b = lfo_b - 8192;
+
+ if (lfo_c > 4095)
+ lfo_c = lfo_c - 8192;
+
+ if (lfo_d > 4095)
+ lfo_d = lfo_d - 8192;
+
+ lfo_a = lfo_a * 312500 / 4096;
+ lfo_b = lfo_b * 312500 / 4096;
+ lfo_c = lfo_c * 312500 / 4096;
+ lfo_d = lfo_d * 312500 / 4096;
+
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = %d / %d / %d /%d", "End CFO(Hz) <A/B/C/D>",
+ lfo_a, lfo_b, lfo_c, lfo_d);
+
+ value32 = odm_get_bb_reg(dm, 0xf20, MASKDWORD); /*L SIG*/
+
+ tail = (u8)((value32 & 0xfc0000) >> 16);
+ parity = (u8)((value32 & 0x20000) >> 16);
+ length = (u16)((value32 & 0x1ffe00) >> 8);
+ rsv = (u8)(value32 & 0x10);
+ MCSS = (u8)(value32 & 0x0f);
+
+ switch (MCSS) {
+ case 0x0b:
+ idx = 0;
+ break;
+ case 0x0f:
+ idx = 1;
+ break;
+ case 0x0a:
+ idx = 2;
+ break;
+ case 0x0e:
+ idx = 3;
+ break;
+ case 0x09:
+ idx = 4;
+ break;
+ case 0x08:
+ idx = 5;
+ break;
+ case 0x0c:
+ idx = 6;
+ break;
+ default:
+ idx = 6;
+ break;
+ }
+
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s", "L-SIG");
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s : %s", "rate",
+ L_rate[idx]);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = %x / %x / %x", "Rsv/length/parity", rsv,
+ rx_bw, length);
+
+ value32 = odm_get_bb_reg(dm, 0xf2c, MASKDWORD); /*HT SIG*/
+ if (rx_ht == 1) {
+ hmcss = (u8)(value32 & 0x7F);
+ hrx_bw = (u8)(value32 & 0x80);
+ h_length = (u16)((value32 >> 8) & 0xffff);
+ }
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s", "HT-SIG1");
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = %x / %x / %x", "MCS/BW/length", hmcss,
+ hrx_bw, h_length);
+
+ value32 = odm_get_bb_reg(dm, 0xf30, MASKDWORD); /*HT SIG*/
+
+ if (rx_ht == 1) {
+ smooth = (u8)(value32 & 0x01);
+ htsound = (u8)(value32 & 0x02);
+ rsv = (u8)(value32 & 0x04);
+ agg = (u8)(value32 & 0x08);
+ stbc = (u8)(value32 & 0x30);
+ fec = (u8)(value32 & 0x40);
+ sgi = (u8)(value32 & 0x80);
+ htltf = (u8)((value32 & 0x300) >> 8);
+ htcrc8 = (u16)((value32 & 0x3fc00) >> 8);
+ tail = (u8)((value32 & 0xfc0000) >> 16);
+ }
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s", "HT-SIG2");
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = %x / %x / %x / %x / %x / %x",
+ "Smooth/NoSound/Rsv/Aggregate/STBC/LDPC", smooth,
+ htsound, rsv, agg, stbc, fec);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = %x / %x / %x / %x",
+ "SGI/E-HT-LTFs/CRC/tail", sgi, htltf, htcrc8, tail);
+
+ value32 = odm_get_bb_reg(dm, 0xf2c, MASKDWORD); /*VHT SIG A1*/
+ if (rx_ht == 2) {
+ /* value32 = odm_get_bb_reg(dm, 0xf2c,MASKDWORD);*/
+ v_rx_bw = (u8)(value32 & 0x03);
+ vrsv = (u8)(value32 & 0x04);
+ vstbc = (u8)(value32 & 0x08);
+ vgid = (u8)((value32 & 0x3f0) >> 4);
+ v_nsts = (u8)(((value32 & 0x1c00) >> 8) + 1);
+ vpaid = (u16)(value32 & 0x3fe);
+ vtxops = (u8)((value32 & 0x400000) >> 20);
+ vrsv2 = (u8)((value32 & 0x800000) >> 20);
+ }
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s",
+ "VHT-SIG-A1");
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = %x / %x / %x / %x / %x / %x / %x / %x",
+ "BW/Rsv1/STBC/GID/Nsts/PAID/TXOPPS/Rsv2", v_rx_bw, vrsv,
+ vstbc, vgid, v_nsts, vpaid, vtxops, vrsv2);
+
+ value32 = odm_get_bb_reg(dm, 0xf30, MASKDWORD); /*VHT SIG*/
+
+ if (rx_ht == 2) {
+ /*value32 = odm_get_bb_reg(dm, 0xf30,MASKDWORD); */ /*VHT SIG*/
+
+ /* sgi=(u8)(value32&0x01); */
+ sgiext = (u8)(value32 & 0x03);
+ /* fec = (u8)(value32&0x04); */
+ fecext = (u8)(value32 & 0x0C);
+
+ v_mcss = (u8)(value32 & 0xf0);
+ bf = (u8)((value32 & 0x100) >> 8);
+ vrsv = (u8)((value32 & 0x200) >> 8);
+ vhtcrc8 = (u16)((value32 & 0x3fc00) >> 8);
+ v_tail = (u8)((value32 & 0xfc0000) >> 16);
+ }
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s",
+ "VHT-SIG-A2");
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = %x / %x / %x / %x / %x / %x / %x",
+ "SGI/FEC/MCS/BF/Rsv/CRC/tail", sgiext, fecext, v_mcss,
+ bf, vrsv, vhtcrc8, v_tail);
+
+ value32 = odm_get_bb_reg(dm, 0xf34, MASKDWORD); /*VHT SIG*/
+ {
+ v_length = (u16)(value32 & 0x1fffff);
+ vbrsv = (u8)((value32 & 0x600000) >> 20);
+ vb_tail = (u16)((value32 & 0x1f800000) >> 20);
+ vbcrc = (u8)((value32 & 0x80000000) >> 28);
+ }
+ PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s",
+ "VHT-SIG-B");
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = %x / %x / %x / %x", "length/Rsv/tail/CRC",
+ v_length, vbrsv, vb_tail, vbcrc);
+
+ /*for Condition number*/
+ if (dm->support_ic_type & ODM_RTL8822B) {
+ s32 condition_num = 0;
+ char *factor = NULL;
+
+ /*enable report condition number*/
+ odm_set_bb_reg(dm, 0x1988, BIT(22), 0x1);
+
+ condition_num = odm_get_bb_reg(dm, 0xf84, MASKDWORD);
+ condition_num = (condition_num & 0x3ffff) >> 4;
+
+ if (*dm->band_width == ODM_BW80M) {
+ factor = "256/234";
+ } else if (*dm->band_width == ODM_BW40M) {
+ factor = "128/108";
+ } else if (*dm->band_width == ODM_BW20M) {
+ if (rx_ht == 2 || rx_ht == 1)
+ factor = "64/52"; /*HT or VHT*/
+ else
+ factor = "64/48"; /*legacy*/
+ }
+
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n %-35s = %d (factor = %s)",
+ "Condition number", condition_num, factor);
+ }
+}
+
+void phydm_basic_dbg_message(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct false_alarm_stat *false_alm_cnt =
+ (struct false_alarm_stat *)phydm_get_structure(
+ dm, PHYDM_FALSEALMCNT);
+ struct cfo_tracking *cfo_track =
+ (struct cfo_tracking *)phydm_get_structure(dm, PHYDM_CFOTRACK);
+ struct dig_thres *dig_tab = &dm->dm_dig_table;
+ struct ra_table *ra_tab = &dm->dm_ra_table;
+ u16 macid, phydm_macid, client_cnt = 0;
+ struct rtl_sta_info *entry;
+ s32 tmp_val = 0;
+ u8 tmp_val_u1 = 0;
+
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON,
+ "[PHYDM Common MSG] System up time: ((%d sec))----->\n",
+ dm->phydm_sys_up_time);
+
+ if (dm->is_linked) {
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON,
+ "ID=%d, BW=((%d)), CH=((%d))\n",
+ dm->curr_station_id, 20 << *dm->band_width,
+ *dm->channel);
+
+ /*Print RX rate*/
+ if (dm->rx_rate <= ODM_RATE11M)
+ ODM_RT_TRACE(
+ dm, ODM_COMP_COMMON,
+ "[CCK AGC Report] LNA_idx = 0x%x, VGA_idx = 0x%x\n",
+ dm->cck_lna_idx, dm->cck_vga_idx);
+ else
+ ODM_RT_TRACE(
+ dm, ODM_COMP_COMMON,
+ "[OFDM AGC Report] { 0x%x, 0x%x, 0x%x, 0x%x }\n",
+ dm->ofdm_agc_idx[0], dm->ofdm_agc_idx[1],
+ dm->ofdm_agc_idx[2], dm->ofdm_agc_idx[3]);
+
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON,
+ "RSSI: { %d, %d, %d, %d }, rx_rate:",
+ (dm->rssi_a == 0xff) ? 0 : dm->rssi_a,
+ (dm->rssi_b == 0xff) ? 0 : dm->rssi_b,
+ (dm->rssi_c == 0xff) ? 0 : dm->rssi_c,
+ (dm->rssi_d == 0xff) ? 0 : dm->rssi_d);
+
+ phydm_print_rate(dm, dm->rx_rate, ODM_COMP_COMMON);
+
+ /*Print TX rate*/
+ for (macid = 0; macid < ODM_ASSOCIATE_ENTRY_NUM; macid++) {
+ entry = dm->odm_sta_info[macid];
+ if (!IS_STA_VALID(entry))
+ continue;
+
+ phydm_macid = (dm->platform2phydm_macid_table[macid]);
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON, "TXRate [%d]:",
+ macid);
+ phydm_print_rate(dm, ra_tab->link_tx_rate[macid],
+ ODM_COMP_COMMON);
+
+ client_cnt++;
+
+ if (client_cnt == dm->number_linked_client)
+ break;
+ }
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_COMMON,
+ "TP { TX, RX, total} = {%d, %d, %d }Mbps, traffic_load = (%d))\n",
+ dm->tx_tp, dm->rx_tp, dm->total_tp, dm->traffic_load);
+
+ tmp_val_u1 =
+ (cfo_track->crystal_cap > cfo_track->def_x_cap) ?
+ (cfo_track->crystal_cap -
+ cfo_track->def_x_cap) :
+ (cfo_track->def_x_cap - cfo_track->crystal_cap);
+ ODM_RT_TRACE(
+ dm, ODM_COMP_COMMON,
+ "CFO_avg = ((%d kHz)) , CrystalCap_tracking = ((%s%d))\n",
+ cfo_track->CFO_ave_pre,
+ ((cfo_track->crystal_cap > cfo_track->def_x_cap) ? "+" :
+ "-"),
+ tmp_val_u1);
+
+ /* Condition number */
+ if (dm->support_ic_type == ODM_RTL8822B) {
+ tmp_val = phydm_get_condition_number_8822B(dm);
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON,
+ "Condition number = ((%d))\n", tmp_val);
+ }
+
+ /*STBC or LDPC pkt*/
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON, "LDPC = %s, STBC = %s\n",
+ (dm->phy_dbg_info.is_ldpc_pkt) ? "Y" : "N",
+ (dm->phy_dbg_info.is_stbc_pkt) ? "Y" : "N");
+ } else {
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON, "No Link !!!\n");
+ }
+
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON,
+ "[CCA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n",
+ false_alm_cnt->cnt_cck_cca, false_alm_cnt->cnt_ofdm_cca,
+ false_alm_cnt->cnt_cca_all);
+
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON,
+ "[FA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n",
+ false_alm_cnt->cnt_cck_fail, false_alm_cnt->cnt_ofdm_fail,
+ false_alm_cnt->cnt_all);
+
+ if (dm->support_ic_type & ODM_IC_11N_SERIES)
+ ODM_RT_TRACE(
+ dm, ODM_COMP_COMMON,
+ "[OFDM FA Detail] Parity_Fail = (( %d )), Rate_Illegal = (( %d )), CRC8_fail = (( %d )), Mcs_fail = (( %d )), Fast_Fsync = (( %d )), SB_Search_fail = (( %d ))\n",
+ false_alm_cnt->cnt_parity_fail,
+ false_alm_cnt->cnt_rate_illegal,
+ false_alm_cnt->cnt_crc8_fail,
+ false_alm_cnt->cnt_mcs_fail,
+ false_alm_cnt->cnt_fast_fsync,
+ false_alm_cnt->cnt_sb_search_fail);
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_COMMON,
+ "is_linked = %d, Num_client = %d, rssi_min = %d, current_igi = 0x%x, bNoisy=%d\n\n",
+ dm->is_linked, dm->number_linked_client, dm->rssi_min,
+ dig_tab->cur_ig_value, dm->noisy_decision);
+}
+
+void phydm_basic_profile(void *dm_void, u32 *_used, char *output, u32 *_out_len)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ char *cut = NULL;
+ char *ic_type = NULL;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+ u32 date = 0;
+ char *commit_by = NULL;
+ u32 release_ver = 0;
+
+ PHYDM_SNPRINTF(output + used, out_len - used, "%-35s\n",
+ "% Basic Profile %");
+
+ if (dm->support_ic_type == ODM_RTL8188E) {
+ } else if (dm->support_ic_type == ODM_RTL8822B) {
+ ic_type = "RTL8822B";
+ date = RELEASE_DATE_8822B;
+ commit_by = COMMIT_BY_8822B;
+ release_ver = RELEASE_VERSION_8822B;
+ }
+
+ /* JJ ADD 20161014 */
+
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ " %-35s: %s (MP Chip: %s)\n", "IC type", ic_type,
+ dm->is_mp_chip ? "Yes" : "No");
+
+ if (dm->cut_version == ODM_CUT_A)
+ cut = "A";
+ else if (dm->cut_version == ODM_CUT_B)
+ cut = "B";
+ else if (dm->cut_version == ODM_CUT_C)
+ cut = "C";
+ else if (dm->cut_version == ODM_CUT_D)
+ cut = "D";
+ else if (dm->cut_version == ODM_CUT_E)
+ cut = "E";
+ else if (dm->cut_version == ODM_CUT_F)
+ cut = "F";
+ else if (dm->cut_version == ODM_CUT_I)
+ cut = "I";
+ PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n",
+ "cut version", cut);
+ PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %d\n",
+ "PHY Parameter version", odm_get_hw_img_version(dm));
+ PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %d\n",
+ "PHY Parameter Commit date", date);
+ PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n",
+ "PHY Parameter Commit by", commit_by);
+ PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %d\n",
+ "PHY Parameter Release version", release_ver);
+
+ {
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ " %-35s: %d (Subversion: %d)\n", "FW version",
+ rtlhal->fw_version, rtlhal->fw_subversion);
+ }
+ /* 1 PHY DM version List */
+ PHYDM_SNPRINTF(output + used, out_len - used, "%-35s\n",
+ "% PHYDM version %");
+ PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n",
+ "Code base", PHYDM_CODE_BASE);
+ PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n",
+ "Release Date", PHYDM_RELEASE_DATE);
+ PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n",
+ "adaptivity", ADAPTIVITY_VERSION);
+ PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", "DIG",
+ DIG_VERSION);
+ PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n",
+ "Dynamic BB PowerSaving", DYNAMIC_BBPWRSAV_VERSION);
+ PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n",
+ "CFO Tracking", CFO_TRACKING_VERSION);
+ PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n",
+ "Antenna Diversity", ANTDIV_VERSION);
+ PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n",
+ "Power Tracking", POWRTRACKING_VERSION);
+ PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n",
+ "Dynamic TxPower", DYNAMIC_TXPWR_VERSION);
+ PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n",
+ "RA Info", RAINFO_VERSION);
+ PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n",
+ "Auto channel Selection", ACS_VERSION);
+ PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n",
+ "EDCA Turbo", EDCATURBO_VERSION);
+ PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n",
+ "LA mode", DYNAMIC_LA_MODE);
+ PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n",
+ "Dynamic RX path", DYNAMIC_RX_PATH_VERSION);
+
+ if (dm->support_ic_type & ODM_RTL8822B)
+ PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n",
+ "PHY config 8822B", PHY_CONFIG_VERSION_8822B);
+
+ *_used = used;
+ *_out_len = out_len;
+}
+
+void phydm_fw_trace_en_h2c(void *dm_void, bool enable, u32 fw_debug_component,
+ u32 monitor_mode, u32 macid)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u8 h2c_parameter[7] = {0};
+ u8 cmd_length;
+
+ if (dm->support_ic_type & PHYDM_IC_3081_SERIES) {
+ h2c_parameter[0] = enable;
+ h2c_parameter[1] = (u8)(fw_debug_component & MASKBYTE0);
+ h2c_parameter[2] = (u8)((fw_debug_component & MASKBYTE1) >> 8);
+ h2c_parameter[3] = (u8)((fw_debug_component & MASKBYTE2) >> 16);
+ h2c_parameter[4] = (u8)((fw_debug_component & MASKBYTE3) >> 24);
+ h2c_parameter[5] = (u8)monitor_mode;
+ h2c_parameter[6] = (u8)macid;
+ cmd_length = 7;
+
+ } else {
+ h2c_parameter[0] = enable;
+ h2c_parameter[1] = (u8)monitor_mode;
+ h2c_parameter[2] = (u8)macid;
+ cmd_length = 3;
+ }
+
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "---->\n");
+ if (monitor_mode == 0)
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE,
+ "[H2C] FW_debug_en: (( %d ))\n", enable);
+ else
+ ODM_RT_TRACE(
+ dm, ODM_FW_DEBUG_TRACE,
+ "[H2C] FW_debug_en: (( %d )), mode: (( %d )), macid: (( %d ))\n",
+ enable, monitor_mode, macid);
+ odm_fill_h2c_cmd(dm, PHYDM_H2C_FW_TRACE_EN, cmd_length, h2c_parameter);
+}
+
+bool phydm_api_set_txagc(struct phy_dm_struct *dm, u32 power_index,
+ enum odm_rf_radio_path path, u8 hw_rate,
+ bool is_single_rate)
+{
+ bool ret = false;
+
+ if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8821C)) {
+ if (is_single_rate) {
+ if (dm->support_ic_type == ODM_RTL8822B)
+ ret = phydm_write_txagc_1byte_8822b(
+ dm, power_index, path, hw_rate);
+
+ } else {
+ if (dm->support_ic_type == ODM_RTL8822B)
+ ret = config_phydm_write_txagc_8822b(
+ dm, power_index, path, hw_rate);
+ }
+ }
+
+ return ret;
+}
+
+static u8 phydm_api_get_txagc(struct phy_dm_struct *dm,
+ enum odm_rf_radio_path path, u8 hw_rate)
+{
+ u8 ret = 0;
+
+ if (dm->support_ic_type & ODM_RTL8822B)
+ ret = config_phydm_read_txagc_8822b(dm, path, hw_rate);
+
+ return ret;
+}
+
+static bool phydm_api_switch_bw_channel(struct phy_dm_struct *dm, u8 central_ch,
+ u8 primary_ch_idx,
+ enum odm_bw bandwidth)
+{
+ bool ret = false;
+
+ if (dm->support_ic_type & ODM_RTL8822B)
+ ret = config_phydm_switch_channel_bw_8822b(
+ dm, central_ch, primary_ch_idx, bandwidth);
+
+ return ret;
+}
+
+bool phydm_api_trx_mode(struct phy_dm_struct *dm, enum odm_rf_path tx_path,
+ enum odm_rf_path rx_path, bool is_tx2_path)
+{
+ bool ret = false;
+
+ if (dm->support_ic_type & ODM_RTL8822B)
+ ret = config_phydm_trx_mode_8822b(dm, tx_path, rx_path,
+ is_tx2_path);
+
+ return ret;
+}
+
+static void phydm_get_per_path_txagc(void *dm_void, u8 path, u32 *_used,
+ char *output, u32 *_out_len)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u8 rate_idx;
+ u8 txagc;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ if (((dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8197F)) &&
+ (path <= ODM_RF_PATH_B)) ||
+ ((dm->support_ic_type & (ODM_RTL8821C)) &&
+ (path <= ODM_RF_PATH_A))) {
+ for (rate_idx = 0; rate_idx <= 0x53; rate_idx++) {
+ if (rate_idx == ODM_RATE1M)
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ " %-35s\n", "CCK====>");
+ else if (rate_idx == ODM_RATE6M)
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\n %-35s\n", "OFDM====>");
+ else if (rate_idx == ODM_RATEMCS0)
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\n %-35s\n", "HT 1ss====>");
+ else if (rate_idx == ODM_RATEMCS8)
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\n %-35s\n", "HT 2ss====>");
+ else if (rate_idx == ODM_RATEMCS16)
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\n %-35s\n", "HT 3ss====>");
+ else if (rate_idx == ODM_RATEMCS24)
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\n %-35s\n", "HT 4ss====>");
+ else if (rate_idx == ODM_RATEVHTSS1MCS0)
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\n %-35s\n", "VHT 1ss====>");
+ else if (rate_idx == ODM_RATEVHTSS2MCS0)
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\n %-35s\n", "VHT 2ss====>");
+ else if (rate_idx == ODM_RATEVHTSS3MCS0)
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\n %-35s\n", "VHT 3ss====>");
+ else if (rate_idx == ODM_RATEVHTSS4MCS0)
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\n %-35s\n", "VHT 4ss====>");
+
+ txagc = phydm_api_get_txagc(
+ dm, (enum odm_rf_radio_path)path, rate_idx);
+ if (config_phydm_read_txagc_check(txagc))
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ " 0x%02x ", txagc);
+ else
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ " 0x%s ", "xx");
+ }
+ }
+}
+
+static void phydm_get_txagc(void *dm_void, u32 *_used, char *output,
+ u32 *_out_len)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ /* path-A */
+ PHYDM_SNPRINTF(output + used, out_len - used, "%-35s\n",
+ "path-A====================");
+ phydm_get_per_path_txagc(dm, ODM_RF_PATH_A, _used, output, _out_len);
+
+ /* path-B */
+ PHYDM_SNPRINTF(output + used, out_len - used, "\n%-35s\n",
+ "path-B====================");
+ phydm_get_per_path_txagc(dm, ODM_RF_PATH_B, _used, output, _out_len);
+
+ /* path-C */
+ PHYDM_SNPRINTF(output + used, out_len - used, "\n%-35s\n",
+ "path-C====================");
+ phydm_get_per_path_txagc(dm, ODM_RF_PATH_C, _used, output, _out_len);
+
+ /* path-D */
+ PHYDM_SNPRINTF(output + used, out_len - used, "\n%-35s\n",
+ "path-D====================");
+ phydm_get_per_path_txagc(dm, ODM_RF_PATH_D, _used, output, _out_len);
+}
+
+static void phydm_set_txagc(void *dm_void, u32 *const dm_value, u32 *_used,
+ char *output, u32 *_out_len)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ /*dm_value[1] = path*/
+ /*dm_value[2] = hw_rate*/
+ /*dm_value[3] = power_index*/
+
+ if (dm->support_ic_type &
+ (ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8821C)) {
+ if (dm_value[1] <= 1) {
+ phydm_check_dmval_txagc(dm, used, out_len, dm_value,
+ output);
+ } else {
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ " %s%d %s%x%s\n", "Write path-",
+ (dm_value[1] & 0x1), "rate index-0x",
+ (dm_value[2] & 0x7f), " fail");
+ }
+ }
+}
+
+static void phydm_debug_trace(void *dm_void, u32 *const dm_value, u32 *_used,
+ char *output, u32 *_out_len)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 pre_debug_components, one = 1;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ pre_debug_components = dm->debug_components;
+
+ PHYDM_SNPRINTF(output + used, out_len - used, "\n%s\n",
+ "================================");
+ if (dm_value[0] == 100) {
+ PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
+ "[Debug Message] PhyDM Selection");
+ PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
+ "================================");
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "00. (( %s ))DIG\n",
+ ((dm->debug_components & ODM_COMP_DIG) ? ("V") :
+ (".")));
+ PHYDM_SNPRINTF(
+ output + used, out_len - used, "01. (( %s ))RA_MASK\n",
+ ((dm->debug_components & ODM_COMP_RA_MASK) ? ("V") :
+ (".")));
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "02. (( %s ))DYNAMIC_TXPWR\n",
+ ((dm->debug_components & ODM_COMP_DYNAMIC_TXPWR) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(
+ output + used, out_len - used, "03. (( %s ))FA_CNT\n",
+ ((dm->debug_components & ODM_COMP_FA_CNT) ? ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "04. (( %s ))RSSI_MONITOR\n",
+ ((dm->debug_components & ODM_COMP_RSSI_MONITOR) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(
+ output + used, out_len - used, "05. (( %s ))SNIFFER\n",
+ ((dm->debug_components & ODM_COMP_SNIFFER) ? ("V") :
+ (".")));
+ PHYDM_SNPRINTF(
+ output + used, out_len - used, "06. (( %s ))ANT_DIV\n",
+ ((dm->debug_components & ODM_COMP_ANT_DIV) ? ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "07. (( %s ))DFS\n",
+ ((dm->debug_components & ODM_COMP_DFS) ? ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "08. (( %s ))NOISY_DETECT\n",
+ ((dm->debug_components & ODM_COMP_NOISY_DETECT) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "09. (( %s ))RATE_ADAPTIVE\n",
+ ((dm->debug_components & ODM_COMP_RATE_ADAPTIVE) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(
+ output + used, out_len - used, "10. (( %s ))PATH_DIV\n",
+ ((dm->debug_components & ODM_COMP_PATH_DIV) ? ("V") :
+ (".")));
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "12. (( %s ))DYNAMIC_PRICCA\n",
+ ((dm->debug_components & ODM_COMP_DYNAMIC_PRICCA) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(
+ output + used, out_len - used, "14. (( %s ))MP\n",
+ ((dm->debug_components & ODM_COMP_MP) ? ("V") : (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "15. (( %s ))struct cfo_tracking\n",
+ ((dm->debug_components & ODM_COMP_CFO_TRACKING) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "16. (( %s ))struct acs_info\n",
+ ((dm->debug_components & ODM_COMP_ACS) ? ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "17. (( %s ))ADAPTIVITY\n",
+ ((dm->debug_components & PHYDM_COMP_ADAPTIVITY) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(
+ output + used, out_len - used, "18. (( %s ))RA_DBG\n",
+ ((dm->debug_components & PHYDM_COMP_RA_DBG) ? ("V") :
+ (".")));
+ PHYDM_SNPRINTF(
+ output + used, out_len - used, "19. (( %s ))TXBF\n",
+ ((dm->debug_components & PHYDM_COMP_TXBF) ? ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "20. (( %s ))EDCA_TURBO\n",
+ ((dm->debug_components & ODM_COMP_EDCA_TURBO) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "22. (( %s ))FW_DEBUG_TRACE\n",
+ ((dm->debug_components & ODM_FW_DEBUG_TRACE) ?
+ ("V") :
+ (".")));
+
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "24. (( %s ))TX_PWR_TRACK\n",
+ ((dm->debug_components & ODM_COMP_TX_PWR_TRACK) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "26. (( %s ))CALIBRATION\n",
+ ((dm->debug_components & ODM_COMP_CALIBRATION) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "28. (( %s ))PHY_CONFIG\n",
+ ((dm->debug_components & ODM_PHY_CONFIG) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(
+ output + used, out_len - used, "29. (( %s ))INIT\n",
+ ((dm->debug_components & ODM_COMP_INIT) ? ("V") :
+ (".")));
+ PHYDM_SNPRINTF(
+ output + used, out_len - used, "30. (( %s ))COMMON\n",
+ ((dm->debug_components & ODM_COMP_COMMON) ? ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "31. (( %s ))API\n",
+ ((dm->debug_components & ODM_COMP_API) ? ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
+ "================================");
+
+ } else if (dm_value[0] == 101) {
+ dm->debug_components = 0;
+ PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
+ "Disable all debug components");
+ } else {
+ if (dm_value[1] == 1) /*enable*/
+ dm->debug_components |= (one << dm_value[0]);
+ else if (dm_value[1] == 2) /*disable*/
+ dm->debug_components &= ~(one << dm_value[0]);
+ else
+ PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
+ "[Warning!!!] 1:enable, 2:disable");
+ }
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "pre-DbgComponents = 0x%x\n", pre_debug_components);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "Curr-DbgComponents = 0x%x\n", dm->debug_components);
+ PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
+ "================================");
+}
+
+static void phydm_fw_debug_trace(void *dm_void, u32 *const dm_value, u32 *_used,
+ char *output, u32 *_out_len)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 pre_fw_debug_components, one = 1;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ pre_fw_debug_components = dm->fw_debug_components;
+
+ PHYDM_SNPRINTF(output + used, out_len - used, "\n%s\n",
+ "================================");
+ if (dm_value[0] == 100) {
+ PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
+ "[FW Debug Component]");
+ PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
+ "================================");
+ PHYDM_SNPRINTF(
+ output + used, out_len - used, "00. (( %s ))RA\n",
+ ((dm->fw_debug_components & PHYDM_FW_COMP_RA) ? ("V") :
+ (".")));
+
+ if (dm->support_ic_type & PHYDM_IC_3081_SERIES) {
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "01. (( %s ))MU\n",
+ ((dm->fw_debug_components & PHYDM_FW_COMP_MU) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "02. (( %s ))path Div\n",
+ ((dm->fw_debug_components &
+ PHYDM_FW_COMP_PHY_CONFIG) ?
+ ("V") :
+ (".")));
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "03. (( %s ))Phy Config\n",
+ ((dm->fw_debug_components &
+ PHYDM_FW_COMP_PHY_CONFIG) ?
+ ("V") :
+ (".")));
+ }
+ PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
+ "================================");
+
+ } else {
+ if (dm_value[0] == 101) {
+ dm->fw_debug_components = 0;
+ PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
+ "Clear all fw debug components");
+ } else {
+ if (dm_value[1] == 1) /*enable*/
+ dm->fw_debug_components |= (one << dm_value[0]);
+ else if (dm_value[1] == 2) /*disable*/
+ dm->fw_debug_components &=
+ ~(one << dm_value[0]);
+ else
+ PHYDM_SNPRINTF(
+ output + used, out_len - used, "%s\n",
+ "[Warning!!!] 1:enable, 2:disable");
+ }
+
+ if (dm->fw_debug_components == 0) {
+ dm->debug_components &= ~ODM_FW_DEBUG_TRACE;
+ phydm_fw_trace_en_h2c(
+ dm, false, dm->fw_debug_components, dm_value[2],
+ dm_value[3]); /*H2C to enable C2H Msg*/
+ } else {
+ dm->debug_components |= ODM_FW_DEBUG_TRACE;
+ phydm_fw_trace_en_h2c(
+ dm, true, dm->fw_debug_components, dm_value[2],
+ dm_value[3]); /*H2C to enable C2H Msg*/
+ }
+ }
+}
+
+static void phydm_dump_bb_reg(void *dm_void, u32 *_used, char *output,
+ u32 *_out_len)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 addr = 0;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ /* For Nseries IC we only need to dump page8 to pageF using 3 digits*/
+ for (addr = 0x800; addr < 0xfff; addr += 4) {
+ if (dm->support_ic_type & ODM_IC_11N_SERIES)
+ PHYDM_VAST_INFO_SNPRINTF(
+ output + used, out_len - used,
+ "0x%03x 0x%08x\n", addr,
+ odm_get_bb_reg(dm, addr, MASKDWORD));
+ else
+ PHYDM_VAST_INFO_SNPRINTF(
+ output + used, out_len - used,
+ "0x%04x 0x%08x\n", addr,
+ odm_get_bb_reg(dm, addr, MASKDWORD));
+ }
+
+ if (dm->support_ic_type &
+ (ODM_RTL8822B | ODM_RTL8814A | ODM_RTL8821C)) {
+ if (dm->rf_type > ODM_2T2R) {
+ for (addr = 0x1800; addr < 0x18ff; addr += 4)
+ PHYDM_VAST_INFO_SNPRINTF(
+ output + used, out_len - used,
+ "0x%04x 0x%08x\n", addr,
+ odm_get_bb_reg(dm, addr, MASKDWORD));
+ }
+
+ if (dm->rf_type > ODM_3T3R) {
+ for (addr = 0x1a00; addr < 0x1aff; addr += 4)
+ PHYDM_VAST_INFO_SNPRINTF(
+ output + used, out_len - used,
+ "0x%04x 0x%08x\n", addr,
+ odm_get_bb_reg(dm, addr, MASKDWORD));
+ }
+
+ for (addr = 0x1900; addr < 0x19ff; addr += 4)
+ PHYDM_VAST_INFO_SNPRINTF(
+ output + used, out_len - used,
+ "0x%04x 0x%08x\n", addr,
+ odm_get_bb_reg(dm, addr, MASKDWORD));
+
+ for (addr = 0x1c00; addr < 0x1cff; addr += 4)
+ PHYDM_VAST_INFO_SNPRINTF(
+ output + used, out_len - used,
+ "0x%04x 0x%08x\n", addr,
+ odm_get_bb_reg(dm, addr, MASKDWORD));
+
+ for (addr = 0x1f00; addr < 0x1fff; addr += 4)
+ PHYDM_VAST_INFO_SNPRINTF(
+ output + used, out_len - used,
+ "0x%04x 0x%08x\n", addr,
+ odm_get_bb_reg(dm, addr, MASKDWORD));
+ }
+}
+
+static void phydm_dump_all_reg(void *dm_void, u32 *_used, char *output,
+ u32 *_out_len)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 addr = 0;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ /* dump MAC register */
+ PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used,
+ "MAC==========\n");
+ for (addr = 0; addr < 0x7ff; addr += 4)
+ PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used,
+ "0x%04x 0x%08x\n", addr,
+ odm_get_bb_reg(dm, addr, MASKDWORD));
+
+ for (addr = 0x1000; addr < 0x17ff; addr += 4)
+ PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used,
+ "0x%04x 0x%08x\n", addr,
+ odm_get_bb_reg(dm, addr, MASKDWORD));
+
+ /* dump BB register */
+ PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used,
+ "BB==========\n");
+ phydm_dump_bb_reg(dm, &used, output, &out_len);
+
+ /* dump RF register */
+ PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used,
+ "RF-A==========\n");
+ for (addr = 0; addr < 0xFF; addr++)
+ PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used,
+ "0x%02x 0x%05x\n", addr,
+ odm_get_rf_reg(dm, ODM_RF_PATH_A, addr,
+ RFREGOFFSETMASK));
+
+ if (dm->rf_type > ODM_1T1R) {
+ PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used,
+ "RF-B==========\n");
+ for (addr = 0; addr < 0xFF; addr++)
+ PHYDM_VAST_INFO_SNPRINTF(
+ output + used, out_len - used,
+ "0x%02x 0x%05x\n", addr,
+ odm_get_rf_reg(dm, ODM_RF_PATH_B, addr,
+ RFREGOFFSETMASK));
+ }
+
+ if (dm->rf_type > ODM_2T2R) {
+ PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used,
+ "RF-C==========\n");
+ for (addr = 0; addr < 0xFF; addr++)
+ PHYDM_VAST_INFO_SNPRINTF(
+ output + used, out_len - used,
+ "0x%02x 0x%05x\n", addr,
+ odm_get_rf_reg(dm, ODM_RF_PATH_C, addr,
+ RFREGOFFSETMASK));
+ }
+
+ if (dm->rf_type > ODM_3T3R) {
+ PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used,
+ "RF-D==========\n");
+ for (addr = 0; addr < 0xFF; addr++)
+ PHYDM_VAST_INFO_SNPRINTF(
+ output + used, out_len - used,
+ "0x%02x 0x%05x\n", addr,
+ odm_get_rf_reg(dm, ODM_RF_PATH_D, addr,
+ RFREGOFFSETMASK));
+ }
+}
+
+static void phydm_enable_big_jump(struct phy_dm_struct *dm, bool state)
+{
+ struct dig_thres *dig_tab = &dm->dm_dig_table;
+
+ if (!state) {
+ dm->dm_dig_table.enable_adjust_big_jump = false;
+ odm_set_bb_reg(dm, 0x8c8, 0xfe,
+ ((dig_tab->big_jump_step3 << 5) |
+ (dig_tab->big_jump_step2 << 3) |
+ dig_tab->big_jump_step1));
+ } else {
+ dm->dm_dig_table.enable_adjust_big_jump = true;
+ }
+}
+
+static void phydm_show_rx_rate(struct phy_dm_struct *dm, u32 *_used,
+ char *output, u32 *_out_len)
+{
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "=====Rx SU rate Statistics=====\n");
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "1SS MCS0 = %d, 1SS MCS1 = %d, 1SS MCS2 = %d, 1SS MCS 3 = %d\n",
+ dm->phy_dbg_info.num_qry_vht_pkt[0],
+ dm->phy_dbg_info.num_qry_vht_pkt[1],
+ dm->phy_dbg_info.num_qry_vht_pkt[2],
+ dm->phy_dbg_info.num_qry_vht_pkt[3]);
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "1SS MCS4 = %d, 1SS MCS5 = %d, 1SS MCS6 = %d, 1SS MCS 7 = %d\n",
+ dm->phy_dbg_info.num_qry_vht_pkt[4],
+ dm->phy_dbg_info.num_qry_vht_pkt[5],
+ dm->phy_dbg_info.num_qry_vht_pkt[6],
+ dm->phy_dbg_info.num_qry_vht_pkt[7]);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "1SS MCS8 = %d, 1SS MCS9 = %d\n",
+ dm->phy_dbg_info.num_qry_vht_pkt[8],
+ dm->phy_dbg_info.num_qry_vht_pkt[9]);
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "2SS MCS0 = %d, 2SS MCS1 = %d, 2SS MCS2 = %d, 2SS MCS 3 = %d\n",
+ dm->phy_dbg_info.num_qry_vht_pkt[10],
+ dm->phy_dbg_info.num_qry_vht_pkt[11],
+ dm->phy_dbg_info.num_qry_vht_pkt[12],
+ dm->phy_dbg_info.num_qry_vht_pkt[13]);
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "2SS MCS4 = %d, 2SS MCS5 = %d, 2SS MCS6 = %d, 2SS MCS 7 = %d\n",
+ dm->phy_dbg_info.num_qry_vht_pkt[14],
+ dm->phy_dbg_info.num_qry_vht_pkt[15],
+ dm->phy_dbg_info.num_qry_vht_pkt[16],
+ dm->phy_dbg_info.num_qry_vht_pkt[17]);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "2SS MCS8 = %d, 2SS MCS9 = %d\n",
+ dm->phy_dbg_info.num_qry_vht_pkt[18],
+ dm->phy_dbg_info.num_qry_vht_pkt[19]);
+
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "=====Rx MU rate Statistics=====\n");
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "1SS MCS0 = %d, 1SS MCS1 = %d, 1SS MCS2 = %d, 1SS MCS 3 = %d\n",
+ dm->phy_dbg_info.num_qry_mu_vht_pkt[0],
+ dm->phy_dbg_info.num_qry_mu_vht_pkt[1],
+ dm->phy_dbg_info.num_qry_mu_vht_pkt[2],
+ dm->phy_dbg_info.num_qry_mu_vht_pkt[3]);
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "1SS MCS4 = %d, 1SS MCS5 = %d, 1SS MCS6 = %d, 1SS MCS 7 = %d\n",
+ dm->phy_dbg_info.num_qry_mu_vht_pkt[4],
+ dm->phy_dbg_info.num_qry_mu_vht_pkt[5],
+ dm->phy_dbg_info.num_qry_mu_vht_pkt[6],
+ dm->phy_dbg_info.num_qry_mu_vht_pkt[7]);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "1SS MCS8 = %d, 1SS MCS9 = %d\n",
+ dm->phy_dbg_info.num_qry_mu_vht_pkt[8],
+ dm->phy_dbg_info.num_qry_mu_vht_pkt[9]);
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "2SS MCS0 = %d, 2SS MCS1 = %d, 2SS MCS2 = %d, 2SS MCS 3 = %d\n",
+ dm->phy_dbg_info.num_qry_mu_vht_pkt[10],
+ dm->phy_dbg_info.num_qry_mu_vht_pkt[11],
+ dm->phy_dbg_info.num_qry_mu_vht_pkt[12],
+ dm->phy_dbg_info.num_qry_mu_vht_pkt[13]);
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "2SS MCS4 = %d, 2SS MCS5 = %d, 2SS MCS6 = %d, 2SS MCS 7 = %d\n",
+ dm->phy_dbg_info.num_qry_mu_vht_pkt[14],
+ dm->phy_dbg_info.num_qry_mu_vht_pkt[15],
+ dm->phy_dbg_info.num_qry_mu_vht_pkt[16],
+ dm->phy_dbg_info.num_qry_mu_vht_pkt[17]);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "2SS MCS8 = %d, 2SS MCS9 = %d\n",
+ dm->phy_dbg_info.num_qry_mu_vht_pkt[18],
+ dm->phy_dbg_info.num_qry_mu_vht_pkt[19]);
+}
+
+struct phydm_command {
+ char name[16];
+ u8 id;
+};
+
+enum PHYDM_CMD_ID {
+ PHYDM_HELP,
+ PHYDM_DEMO,
+ PHYDM_RA,
+ PHYDM_PROFILE,
+ PHYDM_ANTDIV,
+ PHYDM_PATHDIV,
+ PHYDM_DEBUG,
+ PHYDM_FW_DEBUG,
+ PHYDM_SUPPORT_ABILITY,
+ PHYDM_GET_TXAGC,
+ PHYDM_SET_TXAGC,
+ PHYDM_SMART_ANT,
+ PHYDM_API,
+ PHYDM_TRX_PATH,
+ PHYDM_LA_MODE,
+ PHYDM_DUMP_REG,
+ PHYDM_MU_MIMO,
+ PHYDM_HANG,
+ PHYDM_BIG_JUMP,
+ PHYDM_SHOW_RXRATE,
+ PHYDM_NBI_EN,
+ PHYDM_CSI_MASK_EN,
+ PHYDM_DFS,
+ PHYDM_IQK,
+ PHYDM_NHM,
+ PHYDM_CLM,
+ PHYDM_BB_INFO,
+ PHYDM_TXBF,
+ PHYDM_PAUSE_DIG_EN,
+ PHYDM_H2C,
+ PHYDM_ANT_SWITCH,
+ PHYDM_DYNAMIC_RA_PATH,
+ PHYDM_PSD,
+ PHYDM_DEBUG_PORT
+};
+
+static struct phydm_command phy_dm_ary[] = {
+ {"-h", PHYDM_HELP}, /*do not move this element to other position*/
+ {"demo", PHYDM_DEMO}, /*do not move this element to other position*/
+ {"ra", PHYDM_RA},
+ {"profile", PHYDM_PROFILE},
+ {"antdiv", PHYDM_ANTDIV},
+ {"pathdiv", PHYDM_PATHDIV},
+ {"dbg", PHYDM_DEBUG},
+ {"fw_dbg", PHYDM_FW_DEBUG},
+ {"ability", PHYDM_SUPPORT_ABILITY},
+ {"get_txagc", PHYDM_GET_TXAGC},
+ {"set_txagc", PHYDM_SET_TXAGC},
+ {"smtant", PHYDM_SMART_ANT},
+ {"api", PHYDM_API},
+ {"trxpath", PHYDM_TRX_PATH},
+ {"lamode", PHYDM_LA_MODE},
+ {"dumpreg", PHYDM_DUMP_REG},
+ {"mu", PHYDM_MU_MIMO},
+ {"hang", PHYDM_HANG},
+ {"bigjump", PHYDM_BIG_JUMP},
+ {"rxrate", PHYDM_SHOW_RXRATE},
+ {"nbi", PHYDM_NBI_EN},
+ {"csi_mask", PHYDM_CSI_MASK_EN},
+ {"dfs", PHYDM_DFS},
+ {"iqk", PHYDM_IQK},
+ {"nhm", PHYDM_NHM},
+ {"clm", PHYDM_CLM},
+ {"bbinfo", PHYDM_BB_INFO},
+ {"txbf", PHYDM_TXBF},
+ {"pause_dig", PHYDM_PAUSE_DIG_EN},
+ {"h2c", PHYDM_H2C},
+ {"ant_switch", PHYDM_ANT_SWITCH},
+ {"drp", PHYDM_DYNAMIC_RA_PATH},
+ {"psd", PHYDM_PSD},
+ {"dbgport", PHYDM_DEBUG_PORT},
+};
+
+void phydm_cmd_parser(struct phy_dm_struct *dm, char input[][MAX_ARGV],
+ u32 input_num, u8 flag, char *output, u32 out_len)
+{
+ u32 used = 0;
+ u8 id = 0;
+ int var1[10] = {0};
+ int i, input_idx = 0, phydm_ary_size;
+ char help[] = "-h";
+
+ bool is_enable_dbg_mode;
+ u8 central_ch, primary_ch_idx, bandwidth;
+
+ if (flag == 0) {
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "GET, nothing to print\n");
+ return;
+ }
+
+ PHYDM_SNPRINTF(output + used, out_len - used, "\n");
+
+ /* Parsing Cmd ID */
+ if (input_num) {
+ phydm_ary_size =
+ sizeof(phy_dm_ary) / sizeof(struct phydm_command);
+ for (i = 0; i < phydm_ary_size; i++) {
+ if (strcmp(phy_dm_ary[i].name, input[0]) == 0) {
+ id = phy_dm_ary[i].id;
+ break;
+ }
+ }
+ if (i == phydm_ary_size) {
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "SET, command not found!\n");
+ return;
+ }
+ }
+
+ switch (id) {
+ case PHYDM_HELP: {
+ PHYDM_SNPRINTF(output + used, out_len - used, "BB cmd ==>\n");
+ for (i = 0; i < phydm_ary_size - 2; i++) {
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ " %-5d: %s\n", i,
+ phy_dm_ary[i + 2].name);
+ /**/
+ }
+ } break;
+
+ case PHYDM_DEMO: { /*echo demo 10 0x3a z abcde >cmd*/
+ u32 directory = 0;
+
+ char char_temp;
+
+ PHYDM_SSCANF(input[1], DCMD_DECIMAL, &directory);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "Decimal value = %d\n", directory);
+ PHYDM_SSCANF(input[2], DCMD_HEX, &directory);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "Hex value = 0x%x\n", directory);
+ PHYDM_SSCANF(input[3], DCMD_CHAR, &char_temp);
+ PHYDM_SNPRINTF(output + used, out_len - used, "Char = %c\n",
+ char_temp);
+ PHYDM_SNPRINTF(output + used, out_len - used, "String = %s\n",
+ input[4]);
+ } break;
+
+ case PHYDM_RA:
+
+ for (i = 0; i < 5; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL,
+ &var1[i]);
+
+ input_idx++;
+ }
+ }
+
+ if (input_idx >= 1) {
+ phydm_RA_debug_PCR(dm, (u32 *)var1, &used, output,
+ &out_len);
+ }
+
+ break;
+
+ case PHYDM_ANTDIV:
+
+ for (i = 0; i < 5; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]);
+
+ input_idx++;
+ }
+ }
+
+ break;
+
+ case PHYDM_PATHDIV:
+
+ for (i = 0; i < 5; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]);
+
+ input_idx++;
+ }
+ }
+
+ break;
+
+ case PHYDM_DEBUG:
+
+ for (i = 0; i < 5; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL,
+ &var1[i]);
+
+ input_idx++;
+ }
+ }
+
+ if (input_idx >= 1) {
+ phydm_debug_trace(dm, (u32 *)var1, &used, output,
+ &out_len);
+ }
+
+ break;
+
+ case PHYDM_FW_DEBUG:
+
+ for (i = 0; i < 5; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL,
+ &var1[i]);
+ input_idx++;
+ }
+ }
+
+ if (input_idx >= 1)
+ phydm_fw_debug_trace(dm, (u32 *)var1, &used, output,
+ &out_len);
+
+ break;
+
+ case PHYDM_SUPPORT_ABILITY:
+
+ for (i = 0; i < 5; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL,
+ &var1[i]);
+
+ input_idx++;
+ }
+ }
+
+ if (input_idx >= 1) {
+ phydm_support_ability_debug(dm, (u32 *)var1, &used,
+ output, &out_len);
+ }
+
+ break;
+
+ case PHYDM_SMART_ANT:
+
+ for (i = 0; i < 5; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]);
+ input_idx++;
+ }
+ }
+
+ break;
+
+ case PHYDM_API:
+ if (!(dm->support_ic_type &
+ (ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8821C))) {
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "This IC doesn't support PHYDM API function\n");
+ }
+
+ for (i = 0; i < 4; i++) {
+ if (input[i + 1])
+ PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL,
+ &var1[i]);
+ }
+
+ is_enable_dbg_mode = (bool)var1[0];
+ central_ch = (u8)var1[1];
+ primary_ch_idx = (u8)var1[2];
+ bandwidth = (enum odm_bw)var1[3];
+
+ if (is_enable_dbg_mode) {
+ dm->is_disable_phy_api = false;
+ phydm_api_switch_bw_channel(dm, central_ch,
+ primary_ch_idx,
+ (enum odm_bw)bandwidth);
+ dm->is_disable_phy_api = true;
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "central_ch = %d, primary_ch_idx = %d, bandwidth = %d\n",
+ central_ch, primary_ch_idx, bandwidth);
+ } else {
+ dm->is_disable_phy_api = false;
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "Disable API debug mode\n");
+ }
+ break;
+
+ case PHYDM_PROFILE: /*echo profile, >cmd*/
+ phydm_basic_profile(dm, &used, output, &out_len);
+ break;
+
+ case PHYDM_GET_TXAGC:
+ phydm_get_txagc(dm, &used, output, &out_len);
+ break;
+
+ case PHYDM_SET_TXAGC: {
+ bool is_enable_dbg_mode;
+
+ for (i = 0; i < 5; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]);
+ input_idx++;
+ }
+ }
+
+ if ((strcmp(input[1], help) == 0)) {
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "{En} {pathA~D(0~3)} {rate_idx(Hex), All_rate:0xff} {txagc_idx (Hex)}\n");
+ /**/
+
+ } else {
+ is_enable_dbg_mode = (bool)var1[0];
+ if (is_enable_dbg_mode) {
+ dm->is_disable_phy_api = false;
+ phydm_set_txagc(dm, (u32 *)var1, &used, output,
+ &out_len);
+ dm->is_disable_phy_api = true;
+ } else {
+ dm->is_disable_phy_api = false;
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "Disable API debug mode\n");
+ }
+ }
+ } break;
+
+ case PHYDM_TRX_PATH:
+
+ for (i = 0; i < 4; i++) {
+ if (input[i + 1])
+ PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL,
+ &var1[i]);
+ }
+ if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8197F)) {
+ u8 tx_path, rx_path;
+ bool is_enable_dbg_mode, is_tx2_path;
+
+ is_enable_dbg_mode = (bool)var1[0];
+ tx_path = (u8)var1[1];
+ rx_path = (u8)var1[2];
+ is_tx2_path = (bool)var1[3];
+
+ if (is_enable_dbg_mode) {
+ dm->is_disable_phy_api = false;
+ phydm_api_trx_mode(
+ dm, (enum odm_rf_path)tx_path,
+ (enum odm_rf_path)rx_path, is_tx2_path);
+ dm->is_disable_phy_api = true;
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "tx_path = 0x%x, rx_path = 0x%x, is_tx2_path = %d\n",
+ tx_path, rx_path, is_tx2_path);
+ } else {
+ dm->is_disable_phy_api = false;
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "Disable API debug mode\n");
+ }
+ } else {
+ phydm_config_trx_path(dm, (u32 *)var1, &used, output,
+ &out_len);
+ }
+ break;
+
+ case PHYDM_LA_MODE:
+
+ dm->support_ability &= ~(ODM_BB_FA_CNT);
+ phydm_lamode_trigger_setting(dm, &input[0], &used, output,
+ &out_len, input_num);
+ dm->support_ability |= ODM_BB_FA_CNT;
+
+ break;
+
+ case PHYDM_DUMP_REG: {
+ u8 type = 0;
+
+ if (input[1]) {
+ PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);
+ type = (u8)var1[0];
+ }
+
+ if (type == 0)
+ phydm_dump_bb_reg(dm, &used, output, &out_len);
+ else if (type == 1)
+ phydm_dump_all_reg(dm, &used, output, &out_len);
+ } break;
+
+ case PHYDM_MU_MIMO:
+
+ if (input[1])
+ PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);
+ else
+ var1[0] = 0;
+
+ if (var1[0] == 1) {
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "Get MU BFee CSI\n");
+ odm_set_bb_reg(dm, 0x9e8, BIT(17) | BIT(16),
+ 2); /*Read BFee*/
+ odm_set_bb_reg(dm, 0x1910, BIT(15),
+ 1); /*Select BFee's CSI report*/
+ odm_set_bb_reg(dm, 0x19b8, BIT(6),
+ 1); /*set as CSI report*/
+ odm_set_bb_reg(dm, 0x19a8, 0xFFFF,
+ 0xFFFF); /*disable gated_clk*/
+ phydm_print_csi(dm, used, out_len, output);
+
+ } else if (var1[0] == 2) {
+ PHYDM_SSCANF(input[2], DCMD_DECIMAL, &var1[1]);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "Get MU BFer's STA%d CSI\n", var1[1]);
+ odm_set_bb_reg(dm, 0x9e8, BIT(24), 0); /*Read BFer*/
+ odm_set_bb_reg(dm, 0x9e8, BIT(25),
+ 1); /*enable Read/Write RAM*/
+ odm_set_bb_reg(dm, 0x9e8, BIT(30) | BIT(29) | BIT(28),
+ var1[1]); /*read which STA's CSI report*/
+ odm_set_bb_reg(dm, 0x1910, BIT(15),
+ 0); /*select BFer's CSI*/
+ odm_set_bb_reg(dm, 0x19e0, 0x00003FC0,
+ 0xFF); /*disable gated_clk*/
+ phydm_print_csi(dm, used, out_len, output);
+ }
+ break;
+
+ case PHYDM_BIG_JUMP: {
+ if (input[1]) {
+ PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);
+ phydm_enable_big_jump(dm, (bool)(var1[0]));
+ } else {
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "unknown command!\n");
+ }
+ break;
+ }
+
+ case PHYDM_HANG:
+ phydm_bb_rx_hang_info(dm, &used, output, &out_len);
+ break;
+
+ case PHYDM_SHOW_RXRATE: {
+ u8 rate_idx;
+
+ if (input[1])
+ PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);
+
+ if (var1[0] == 1) {
+ phydm_show_rx_rate(dm, &used, output, &out_len);
+ } else {
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "Reset Rx rate counter\n");
+
+ for (rate_idx = 0; rate_idx < 40; rate_idx++) {
+ dm->phy_dbg_info.num_qry_vht_pkt[rate_idx] = 0;
+ dm->phy_dbg_info.num_qry_mu_vht_pkt[rate_idx] =
+ 0;
+ }
+ }
+ } break;
+
+ case PHYDM_NBI_EN:
+
+ for (i = 0; i < 5; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL,
+ &var1[i]);
+ input_idx++;
+ }
+ }
+
+ if (input_idx >= 1) {
+ phydm_api_debug(dm, PHYDM_API_NBI, (u32 *)var1, &used,
+ output, &out_len);
+ /**/
+ }
+
+ break;
+
+ case PHYDM_CSI_MASK_EN:
+
+ for (i = 0; i < 5; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL,
+ &var1[i]);
+ input_idx++;
+ }
+ }
+
+ if (input_idx >= 1) {
+ phydm_api_debug(dm, PHYDM_API_CSI_MASK, (u32 *)var1,
+ &used, output, &out_len);
+ /**/
+ }
+
+ break;
+
+ case PHYDM_DFS:
+ break;
+
+ case PHYDM_IQK:
+ break;
+
+ case PHYDM_NHM: {
+ u8 target_rssi;
+ u16 nhm_period = 0xC350; /* 200ms */
+ u8 IGI;
+ struct ccx_info *ccx_info = &dm->dm_ccx_info;
+
+ PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);
+
+ if (input_num == 1) {
+ ccx_info->echo_NHM_en = false;
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n Trigger NHM: echo nhm 1\n");
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r (Exclude CCA)\n");
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r Trigger NHM: echo nhm 2\n");
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r (Include CCA)\n");
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r Get NHM results: echo nhm 3\n");
+
+ return;
+ }
+
+ /* NMH trigger */
+ if ((var1[0] <= 2) && (var1[0] != 0)) {
+ ccx_info->echo_NHM_en = true;
+ ccx_info->echo_IGI =
+ (u8)odm_get_bb_reg(dm, 0xC50, MASKBYTE0);
+
+ target_rssi = ccx_info->echo_IGI - 10;
+
+ ccx_info->NHM_th[0] = (target_rssi - 15 + 10) * 2;
+
+ for (i = 1; i <= 10; i++)
+ ccx_info->NHM_th[i] =
+ ccx_info->NHM_th[0] + 6 * i;
+
+ /* 4 1. store previous NHM setting */
+ phydm_nhm_setting(dm, STORE_NHM_SETTING);
+
+ /* 4 2. Set NHM period, 0x990[31:16]=0xC350,
+ * Time duration for NHM unit: 4us, 0xC350=200ms
+ */
+ ccx_info->NHM_period = nhm_period;
+
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n Monitor NHM for %d us",
+ nhm_period * 4);
+
+ /* 4 3. Set NHM inexclude_txon, inexclude_cca, ccx_en */
+
+ ccx_info->nhm_inexclude_cca = (var1[0] == 1) ?
+ NHM_EXCLUDE_CCA :
+ NHM_INCLUDE_CCA;
+ ccx_info->nhm_inexclude_txon = NHM_EXCLUDE_TXON;
+
+ phydm_nhm_setting(dm, SET_NHM_SETTING);
+ phydm_print_nhm_trigger(output, used, out_len,
+ ccx_info);
+
+ /* 4 4. Trigger NHM */
+ phydm_nhm_trigger(dm);
+ }
+
+ /*Get NHM results*/
+ else if (var1[0] == 3) {
+ IGI = (u8)odm_get_bb_reg(dm, 0xC50, MASKBYTE0);
+
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n Cur_IGI = 0x%x", IGI);
+
+ phydm_get_nhm_result(dm);
+
+ /* 4 Resotre NHM setting */
+ phydm_nhm_setting(dm, RESTORE_NHM_SETTING);
+ phydm_print_nhm_result(output, used, out_len, ccx_info);
+
+ ccx_info->echo_NHM_en = false;
+ } else {
+ ccx_info->echo_NHM_en = false;
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n Trigger NHM: echo nhm 1\n");
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r (Exclude CCA)\n");
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r Trigger NHM: echo nhm 2\n");
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r (Include CCA)\n");
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r Get NHM results: echo nhm 3\n");
+
+ return;
+ }
+ } break;
+
+ case PHYDM_CLM: {
+ struct ccx_info *ccx_info = &dm->dm_ccx_info;
+
+ PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);
+
+ if (input_num == 1) {
+ ccx_info->echo_CLM_en = false;
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n Trigger CLM: echo clm 1\n");
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r Get CLM results: echo clm 2\n");
+ return;
+ }
+
+ /* Set & trigger CLM */
+ if (var1[0] == 1) {
+ ccx_info->echo_CLM_en = true;
+ ccx_info->CLM_period = 0xC350; /*100ms*/
+ phydm_clm_setting(dm);
+ phydm_clm_trigger(dm);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n Monitor CLM for 200ms\n");
+ }
+
+ /* Get CLM results */
+ else if (var1[0] == 2) {
+ ccx_info->echo_CLM_en = false;
+ phydm_get_cl_mresult(dm);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n CLM_result = %d us\n",
+ ccx_info->CLM_result * 4);
+
+ } else {
+ ccx_info->echo_CLM_en = false;
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\n\r Error command !\n");
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r Trigger CLM: echo clm 1\n");
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r Get CLM results: echo clm 2\n");
+ }
+ } break;
+
+ case PHYDM_BB_INFO: {
+ s32 value32 = 0;
+
+ phydm_bb_debug_info(dm, &used, output, &out_len);
+
+ if (dm->support_ic_type & ODM_RTL8822B && input[1]) {
+ PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);
+ odm_set_bb_reg(dm, 0x1988, 0x003fff00, var1[0]);
+ value32 = odm_get_bb_reg(dm, 0xf84, MASKDWORD);
+ value32 = (value32 & 0xff000000) >> 24;
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "\r\n %-35s = condition num = %d, subcarriers = %d\n",
+ "Over condition num subcarrier", var1[0],
+ value32);
+ odm_set_bb_reg(dm, 0x1988, BIT(22),
+ 0x0); /*disable report condition number*/
+ }
+ } break;
+
+ case PHYDM_TXBF: {
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "\r\n no TxBF !!\n");
+ } break;
+
+ case PHYDM_PAUSE_DIG_EN:
+
+ for (i = 0; i < 5; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]);
+ input_idx++;
+ }
+ }
+
+ if (input_idx >= 1) {
+ if (var1[0] == 0) {
+ odm_pause_dig(dm, PHYDM_PAUSE,
+ PHYDM_PAUSE_LEVEL_7, (u8)var1[1]);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "Set IGI_value = ((%x))\n",
+ var1[1]);
+ } else if (var1[0] == 1) {
+ odm_pause_dig(dm, PHYDM_RESUME,
+ PHYDM_PAUSE_LEVEL_7, (u8)var1[1]);
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "Resume IGI_value\n");
+ } else {
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "echo (1:pause, 2resume) (IGI_value)\n");
+ }
+ }
+ break;
+ case PHYDM_H2C:
+
+ for (i = 0; i < 8; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]);
+ input_idx++;
+ }
+ }
+
+ if (input_idx >= 1)
+ phydm_h2C_debug(dm, (u32 *)var1, &used, output,
+ &out_len);
+
+ break;
+
+ case PHYDM_ANT_SWITCH:
+
+ for (i = 0; i < 8; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL,
+ &var1[i]);
+ input_idx++;
+ }
+ }
+
+ if (input_idx >= 1) {
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "Not Support IC");
+ }
+
+ break;
+
+ case PHYDM_DYNAMIC_RA_PATH:
+
+ PHYDM_SNPRINTF(output + used, out_len - used, "Not Support IC");
+
+ break;
+
+ case PHYDM_PSD:
+
+ phydm_psd_debug(dm, &input[0], &used, output, &out_len,
+ input_num);
+
+ break;
+
+ case PHYDM_DEBUG_PORT: {
+ u32 dbg_port_value;
+
+ PHYDM_SSCANF(input[1], DCMD_HEX, &var1[0]);
+
+ if (phydm_set_bb_dbg_port(dm, BB_DBGPORT_PRIORITY_3,
+ var1[0])) { /*set debug port to 0x0*/
+
+ dbg_port_value = phydm_get_bb_dbg_port_value(dm);
+ phydm_release_bb_dbg_port(dm);
+
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "Debug Port[0x%x] = ((0x%x))\n", var1[1],
+ dbg_port_value);
+ }
+ } break;
+
+ default:
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "SET, unknown command!\n");
+ break;
+ }
+}
+
+s32 phydm_cmd(struct phy_dm_struct *dm, char *input, u32 in_len, u8 flag,
+ char *output, u32 out_len)
+{
+ char *token;
+ u32 argc = 0;
+ char argv[MAX_ARGC][MAX_ARGV];
+
+ do {
+ token = strsep(&input, ", ");
+ if (token) {
+ strcpy(argv[argc], token);
+ argc++;
+ } else {
+ break;
+ }
+ } while (argc < MAX_ARGC);
+
+ if (argc == 1)
+ argv[0][strlen(argv[0]) - 1] = '\0';
+
+ phydm_cmd_parser(dm, argv, argc, flag, output, out_len);
+
+ return 0;
+}
+
+void phydm_fw_trace_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ /*u8 debug_trace_11byte[60];*/
+ u8 freg_num, c2h_seq, buf_0 = 0;
+
+ if (!(dm->support_ic_type & PHYDM_IC_3081_SERIES))
+ return;
+
+ if (cmd_len > 12)
+ return;
+
+ buf_0 = cmd_buf[0];
+ freg_num = (buf_0 & 0xf);
+ c2h_seq = (buf_0 & 0xf0) >> 4;
+
+ if ((c2h_seq != dm->pre_c2h_seq) && !dm->fw_buff_is_enpty) {
+ dm->fw_debug_trace[dm->c2h_cmd_start] = '\0';
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE,
+ "[FW Dbg Queue Overflow] %s\n",
+ dm->fw_debug_trace);
+ dm->c2h_cmd_start = 0;
+ }
+
+ if ((cmd_len - 1) > (60 - dm->c2h_cmd_start)) {
+ dm->fw_debug_trace[dm->c2h_cmd_start] = '\0';
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE,
+ "[FW Dbg Queue error: wrong C2H length] %s\n",
+ dm->fw_debug_trace);
+ dm->c2h_cmd_start = 0;
+ return;
+ }
+
+ strncpy((char *)&dm->fw_debug_trace[dm->c2h_cmd_start],
+ (char *)&cmd_buf[1], (cmd_len - 1));
+ dm->c2h_cmd_start += (cmd_len - 1);
+ dm->fw_buff_is_enpty = false;
+
+ if (freg_num == 0 || dm->c2h_cmd_start >= 60) {
+ if (dm->c2h_cmd_start < 60)
+ dm->fw_debug_trace[dm->c2h_cmd_start] = '\0';
+ else
+ dm->fw_debug_trace[59] = '\0';
+
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "[FW DBG Msg] %s\n",
+ dm->fw_debug_trace);
+ /*dbg_print("[FW DBG Msg] %s\n", dm->fw_debug_trace);*/
+ dm->c2h_cmd_start = 0;
+ dm->fw_buff_is_enpty = true;
+ }
+
+ dm->pre_c2h_seq = c2h_seq;
+}
+
+void phydm_fw_trace_handler_code(void *dm_void, u8 *buffer, u8 cmd_len)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u8 function = buffer[0];
+ u8 dbg_num = buffer[1];
+ u16 content_0 = (((u16)buffer[3]) << 8) | ((u16)buffer[2]);
+ u16 content_1 = (((u16)buffer[5]) << 8) | ((u16)buffer[4]);
+ u16 content_2 = (((u16)buffer[7]) << 8) | ((u16)buffer[6]);
+ u16 content_3 = (((u16)buffer[9]) << 8) | ((u16)buffer[8]);
+ u16 content_4 = (((u16)buffer[11]) << 8) | ((u16)buffer[10]);
+
+ if (cmd_len > 12)
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE,
+ "[FW Msg] Invalid cmd length (( %d )) >12\n",
+ cmd_len);
+
+ /*--------------------------------------------*/
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE,
+ "[FW][general][%d, %d, %d] = {%d, %d, %d, %d}\n", function,
+ dbg_num, content_0, content_1, content_2, content_3,
+ content_4);
+ /*--------------------------------------------*/
+}
+
+void phydm_fw_trace_handler_8051(void *dm_void, u8 *buffer, u8 cmd_len)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ int i = 0;
+ u8 extend_c2h_sub_id = 0, extend_c2h_dbg_len = 0,
+ extend_c2h_dbg_seq = 0;
+ u8 fw_debug_trace[128];
+ u8 *extend_c2h_dbg_content = NULL;
+
+ if (cmd_len > 127)
+ return;
+
+ extend_c2h_sub_id = buffer[0];
+ extend_c2h_dbg_len = buffer[1];
+ extend_c2h_dbg_content = buffer + 2; /*DbgSeq+DbgContent for show HEX*/
+
+go_backfor_aggre_dbg_pkt:
+ i = 0;
+ extend_c2h_dbg_seq = buffer[2];
+ extend_c2h_dbg_content = buffer + 3;
+
+ for (;; i++) {
+ fw_debug_trace[i] = extend_c2h_dbg_content[i];
+ if (extend_c2h_dbg_content[i + 1] == '\0') {
+ fw_debug_trace[i + 1] = '\0';
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "[FW DBG Msg] %s",
+ &fw_debug_trace[0]);
+ break;
+ } else if (extend_c2h_dbg_content[i] == '\n') {
+ fw_debug_trace[i + 1] = '\0';
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "[FW DBG Msg] %s",
+ &fw_debug_trace[0]);
+ buffer = extend_c2h_dbg_content + i + 3;
+ goto go_backfor_aggre_dbg_pkt;
+ }
+ }
+}
diff --git a/drivers/staging/rtlwifi/phydm/phydm_debug.h b/drivers/staging/rtlwifi/phydm/phydm_debug.h
new file mode 100644
index 0000000..f442f7c
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_debug.h
@@ -0,0 +1,175 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __ODM_DBG_H__
+#define __ODM_DBG_H__
+
+/*#define DEBUG_VERSION "1.1"*/ /*2015.07.29 YuChen*/
+/*#define DEBUG_VERSION "1.2"*/ /*2015.08.28 Dino*/
+#define DEBUG_VERSION "1.3" /*2016.04.28 YuChen*/
+#define ODM_DBG_TRACE 5
+
+/*FW DBG MSG*/
+#define RATE_DECISION BIT(0)
+#define INIT_RA_TABLE BIT(1)
+#define RATE_UP BIT(2)
+#define RATE_DOWN BIT(3)
+#define TRY_DONE BIT(4)
+#define RA_H2C BIT(5)
+#define F_RATE_AP_RPT BIT(7)
+
+/* -----------------------------------------------------------------------------
+ * Define the tracing components
+ *
+ * -----------------------------------------------------------------------------
+ */
+/*BB FW Functions*/
+#define PHYDM_FW_COMP_RA BIT(0)
+#define PHYDM_FW_COMP_MU BIT(1)
+#define PHYDM_FW_COMP_PATH_DIV BIT(2)
+#define PHYDM_FW_COMP_PHY_CONFIG BIT(3)
+
+/*BB Driver Functions*/
+#define ODM_COMP_DIG BIT(0)
+#define ODM_COMP_RA_MASK BIT(1)
+#define ODM_COMP_DYNAMIC_TXPWR BIT(2)
+#define ODM_COMP_FA_CNT BIT(3)
+#define ODM_COMP_RSSI_MONITOR BIT(4)
+#define ODM_COMP_SNIFFER BIT(5)
+#define ODM_COMP_ANT_DIV BIT(6)
+#define ODM_COMP_DFS BIT(7)
+#define ODM_COMP_NOISY_DETECT BIT(8)
+#define ODM_COMP_RATE_ADAPTIVE BIT(9)
+#define ODM_COMP_PATH_DIV BIT(10)
+#define ODM_COMP_CCX BIT(11)
+
+#define ODM_COMP_DYNAMIC_PRICCA BIT(12)
+/*BIT13 TBD*/
+#define ODM_COMP_MP BIT(14)
+#define ODM_COMP_CFO_TRACKING BIT(15)
+#define ODM_COMP_ACS BIT(16)
+#define PHYDM_COMP_ADAPTIVITY BIT(17)
+#define PHYDM_COMP_RA_DBG BIT(18)
+#define PHYDM_COMP_TXBF BIT(19)
+/* MAC Functions */
+#define ODM_COMP_EDCA_TURBO BIT(20)
+#define ODM_COMP_DYNAMIC_RX_PATH BIT(21)
+#define ODM_FW_DEBUG_TRACE BIT(22)
+/* RF Functions */
+/*BIT23 TBD*/
+#define ODM_COMP_TX_PWR_TRACK BIT(24)
+/*BIT25 TBD*/
+#define ODM_COMP_CALIBRATION BIT(26)
+/* Common Functions */
+/*BIT27 TBD*/
+#define ODM_PHY_CONFIG BIT(28)
+#define ODM_COMP_INIT BIT(29)
+#define ODM_COMP_COMMON BIT(30)
+#define ODM_COMP_API BIT(31)
+
+#define ODM_COMP_UNCOND 0xFFFFFFFF
+
+/*------------------------Export Marco Definition---------------------------*/
+
+#define config_phydm_read_txagc_check(data) (data != INVALID_TXAGC_DATA)
+
+#define ODM_RT_TRACE(dm, comp, fmt, ...) \
+ do { \
+ if (((comp) & dm->debug_components) || \
+ ((comp) == ODM_COMP_UNCOND)) \
+ RT_TRACE(dm->adapter, COMP_PHYDM, DBG_DMESG, fmt, \
+ ##__VA_ARGS__); \
+ } while (0)
+
+#define BB_DBGPORT_PRIORITY_3 3 /*Debug function (the highest priority)*/
+#define BB_DBGPORT_PRIORITY_2 2 /*Check hang function & Strong function*/
+#define BB_DBGPORT_PRIORITY_1 1 /*Watch dog function*/
+#define BB_DBGPORT_RELEASE 0 /*Init value (the lowest priority)*/
+
+void phydm_init_debug_setting(struct phy_dm_struct *dm);
+
+u8 phydm_set_bb_dbg_port(void *dm_void, u8 curr_dbg_priority, u32 debug_port);
+
+void phydm_release_bb_dbg_port(void *dm_void);
+
+u32 phydm_get_bb_dbg_port_value(void *dm_void);
+
+void phydm_basic_dbg_message(void *dm_void);
+
+#define PHYDM_DBGPRINT 0
+#define MAX_ARGC 20
+#define MAX_ARGV 16
+#define DCMD_DECIMAL "%d"
+#define DCMD_CHAR "%c"
+#define DCMD_HEX "%x"
+
+#define PHYDM_SSCANF(x, y, z) \
+ do { \
+ if (sscanf(x, y, z) != 1) \
+ ODM_RT_TRACE(dm, ODM_COMP_UNCOND, \
+ "%s:%d sscanf fail!", __func__, \
+ __LINE__); \
+ } while (0)
+
+#define PHYDM_VAST_INFO_SNPRINTF(msg, ...) \
+ do { \
+ snprintf(msg, ##__VA_ARGS__); \
+ ODM_RT_TRACE(dm, ODM_COMP_UNCOND, output); \
+ } while (0)
+
+#if (PHYDM_DBGPRINT == 1)
+#define PHYDM_SNPRINTF(msg, ...) \
+ do { \
+ snprintf(msg, ##__VA_ARGS__); \
+ ODM_RT_TRACE(dm, ODM_COMP_UNCOND, output); \
+ } while (0)
+#else
+#define PHYDM_SNPRINTF(msg, ...) \
+ do { \
+ if (out_len > used) \
+ used += snprintf(msg, ##__VA_ARGS__); \
+ } while (0)
+#endif
+
+void phydm_basic_profile(void *dm_void, u32 *_used, char *output,
+ u32 *_out_len);
+s32 phydm_cmd(struct phy_dm_struct *dm, char *input, u32 in_len, u8 flag,
+ char *output, u32 out_len);
+void phydm_cmd_parser(struct phy_dm_struct *dm, char input[][16], u32 input_num,
+ u8 flag, char *output, u32 out_len);
+
+bool phydm_api_trx_mode(struct phy_dm_struct *dm, enum odm_rf_path tx_path,
+ enum odm_rf_path rx_path, bool is_tx2_path);
+
+void phydm_fw_trace_en_h2c(void *dm_void, bool enable, u32 fw_debug_component,
+ u32 monitor_mode, u32 macid);
+
+void phydm_fw_trace_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len);
+
+void phydm_fw_trace_handler_code(void *dm_void, u8 *buffer, u8 cmd_len);
+
+void phydm_fw_trace_handler_8051(void *dm_void, u8 *cmd_buf, u8 cmd_len);
+
+#endif /* __ODM_DBG_H__ */
diff --git a/drivers/staging/rtlwifi/phydm/phydm_dfs.h b/drivers/staging/rtlwifi/phydm/phydm_dfs.h
new file mode 100644
index 0000000..59a1d08
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_dfs.h
@@ -0,0 +1,59 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __PHYDM_DFS_H__
+#define __PHYDM_DFS_H__
+
+#define DFS_VERSION "0.0"
+
+/* ============================================================
+ * Definition
+ * ============================================================
+ */
+
+/* ============================================================
+ * 1 structure
+ * ============================================================
+ */
+
+/* ============================================================
+ * enumeration
+ * ============================================================
+ */
+
+enum phydm_dfs_region_domain {
+ PHYDM_DFS_DOMAIN_UNKNOWN = 0,
+ PHYDM_DFS_DOMAIN_FCC = 1,
+ PHYDM_DFS_DOMAIN_MKK = 2,
+ PHYDM_DFS_DOMAIN_ETSI = 3,
+};
+
+/* ============================================================
+ * function prototype
+ * ============================================================
+ */
+#define phydm_dfs_master_enabled(dm) false
+
+#endif /*#ifndef __PHYDM_DFS_H__ */
diff --git a/drivers/staging/rtlwifi/phydm/phydm_dig.c b/drivers/staging/rtlwifi/phydm/phydm_dig.c
new file mode 100644
index 0000000..31a4f3f
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_dig.c
@@ -0,0 +1,1535 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+/* ************************************************************
+ * include files
+ * *************************************************************/
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+static int get_igi_for_diff(int);
+
+static inline void phydm_check_ap_write_dig(struct phy_dm_struct *dm,
+ u8 current_igi)
+{
+ switch (*dm->one_path_cca) {
+ case ODM_CCA_2R:
+ odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm),
+ current_igi);
+
+ if (dm->rf_type > ODM_1T1R)
+ odm_set_bb_reg(dm, ODM_REG(IGI_B, dm), ODM_BIT(IGI, dm),
+ current_igi);
+ break;
+ case ODM_CCA_1R_A:
+ odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm),
+ current_igi);
+ if (dm->rf_type != ODM_1T1R)
+ odm_set_bb_reg(dm, ODM_REG(IGI_B, dm), ODM_BIT(IGI, dm),
+ get_igi_for_diff(current_igi));
+ break;
+ case ODM_CCA_1R_B:
+ odm_set_bb_reg(dm, ODM_REG(IGI_B, dm), ODM_BIT(IGI, dm),
+ get_igi_for_diff(current_igi));
+ if (dm->rf_type != ODM_1T1R)
+ odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm),
+ current_igi);
+ break;
+ }
+}
+
+static inline u8 phydm_get_current_igi(u8 dig_max_of_min, u8 rssi_min,
+ u8 current_igi)
+{
+ if (rssi_min < dig_max_of_min) {
+ if (current_igi < rssi_min)
+ return rssi_min;
+ } else {
+ if (current_igi < dig_max_of_min)
+ return dig_max_of_min;
+ }
+ return current_igi;
+}
+
+void odm_change_dynamic_init_gain_thresh(void *dm_void, u32 dm_type,
+ u32 dm_value)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct dig_thres *dig_tab = &dm->dm_dig_table;
+
+ if (dm_type == DIG_TYPE_THRESH_HIGH) {
+ dig_tab->rssi_high_thresh = dm_value;
+ } else if (dm_type == DIG_TYPE_THRESH_LOW) {
+ dig_tab->rssi_low_thresh = dm_value;
+ } else if (dm_type == DIG_TYPE_ENABLE) {
+ dig_tab->dig_enable_flag = true;
+ } else if (dm_type == DIG_TYPE_DISABLE) {
+ dig_tab->dig_enable_flag = false;
+ } else if (dm_type == DIG_TYPE_BACKOFF) {
+ if (dm_value > 30)
+ dm_value = 30;
+ dig_tab->backoff_val = (u8)dm_value;
+ } else if (dm_type == DIG_TYPE_RX_GAIN_MIN) {
+ if (dm_value == 0)
+ dm_value = 0x1;
+ dig_tab->rx_gain_range_min = (u8)dm_value;
+ } else if (dm_type == DIG_TYPE_RX_GAIN_MAX) {
+ if (dm_value > 0x50)
+ dm_value = 0x50;
+ dig_tab->rx_gain_range_max = (u8)dm_value;
+ }
+} /* dm_change_dynamic_init_gain_thresh */
+
+static int get_igi_for_diff(int value_IGI)
+{
+#define ONERCCA_LOW_TH 0x30
+#define ONERCCA_LOW_DIFF 8
+
+ if (value_IGI < ONERCCA_LOW_TH) {
+ if ((ONERCCA_LOW_TH - value_IGI) < ONERCCA_LOW_DIFF)
+ return ONERCCA_LOW_TH;
+ else
+ return value_IGI + ONERCCA_LOW_DIFF;
+ }
+
+ return value_IGI;
+}
+
+static void odm_fa_threshold_check(void *dm_void, bool is_dfs_band,
+ bool is_performance, u32 rx_tp, u32 tx_tp,
+ u32 *dm_FA_thres)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ if (dm->is_linked && (is_performance || is_dfs_band)) {
+ /*For NIC*/
+ dm_FA_thres[0] = DM_DIG_FA_TH0;
+ dm_FA_thres[1] = DM_DIG_FA_TH1;
+ dm_FA_thres[2] = DM_DIG_FA_TH2;
+ } else {
+ if (is_dfs_band) {
+ /* For DFS band and no link */
+ dm_FA_thres[0] = 250;
+ dm_FA_thres[1] = 1000;
+ dm_FA_thres[2] = 2000;
+ } else {
+ dm_FA_thres[0] = 2000;
+ dm_FA_thres[1] = 4000;
+ dm_FA_thres[2] = 5000;
+ }
+ }
+}
+
+static u8 odm_forbidden_igi_check(void *dm_void, u8 dig_dynamic_min,
+ u8 current_igi)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct dig_thres *dig_tab = &dm->dm_dig_table;
+ struct false_alarm_stat *fa_cnt =
+ (struct false_alarm_stat *)phydm_get_structure(
+ dm, PHYDM_FALSEALMCNT);
+ u8 rx_gain_range_min = dig_tab->rx_gain_range_min;
+
+ if (dig_tab->large_fa_timeout) {
+ if (--dig_tab->large_fa_timeout == 0)
+ dig_tab->large_fa_hit = 0;
+ }
+
+ if (fa_cnt->cnt_all > 10000) {
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "%s(): Abnormally false alarm case.\n", __func__);
+
+ if (dig_tab->large_fa_hit != 3)
+ dig_tab->large_fa_hit++;
+
+ if (dig_tab->forbidden_igi < current_igi) {
+ dig_tab->forbidden_igi = current_igi;
+ dig_tab->large_fa_hit = 1;
+ dig_tab->large_fa_timeout = LARGE_FA_TIMEOUT;
+ }
+
+ if (dig_tab->large_fa_hit >= 3) {
+ if ((dig_tab->forbidden_igi + 2) >
+ dig_tab->rx_gain_range_max)
+ rx_gain_range_min = dig_tab->rx_gain_range_max;
+ else
+ rx_gain_range_min =
+ (dig_tab->forbidden_igi + 2);
+ dig_tab->recover_cnt = 1800;
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "%s(): Abnormally false alarm case: recover_cnt = %d\n",
+ __func__, dig_tab->recover_cnt);
+ }
+ }
+
+ else if (fa_cnt->cnt_all > 2000) {
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "Abnormally false alarm case.\n");
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "cnt_all=%d, cnt_all_pre=%d, current_igi=0x%x, pre_ig_value=0x%x\n",
+ fa_cnt->cnt_all, fa_cnt->cnt_all_pre, current_igi,
+ dig_tab->pre_ig_value);
+
+ /* fa_cnt->cnt_all = 1.1875*fa_cnt->cnt_all_pre */
+ if ((fa_cnt->cnt_all >
+ (fa_cnt->cnt_all_pre + (fa_cnt->cnt_all_pre >> 3) +
+ (fa_cnt->cnt_all_pre >> 4))) &&
+ (current_igi < dig_tab->pre_ig_value)) {
+ if (dig_tab->large_fa_hit != 3)
+ dig_tab->large_fa_hit++;
+
+ if (dig_tab->forbidden_igi < current_igi) {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "Updating forbidden_igi by current_igi, forbidden_igi=0x%x, current_igi=0x%x\n",
+ dig_tab->forbidden_igi, current_igi);
+
+ dig_tab->forbidden_igi = current_igi;
+ dig_tab->large_fa_hit = 1;
+ dig_tab->large_fa_timeout = LARGE_FA_TIMEOUT;
+ }
+ }
+
+ if (dig_tab->large_fa_hit >= 3) {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "FaHit is greater than 3, rx_gain_range_max=0x%x, rx_gain_range_min=0x%x, forbidden_igi=0x%x\n",
+ dig_tab->rx_gain_range_max, rx_gain_range_min,
+ dig_tab->forbidden_igi);
+
+ if ((dig_tab->forbidden_igi + 1) >
+ dig_tab->rx_gain_range_max)
+ rx_gain_range_min = dig_tab->rx_gain_range_max;
+ else
+ rx_gain_range_min =
+ (dig_tab->forbidden_igi + 1);
+
+ dig_tab->recover_cnt = 1200;
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "Abnormally false alarm case: recover_cnt = %d, rx_gain_range_min = 0x%x\n",
+ dig_tab->recover_cnt, rx_gain_range_min);
+ }
+ } else {
+ if (dig_tab->recover_cnt != 0) {
+ dig_tab->recover_cnt--;
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "%s(): Normal Case: recover_cnt = %d\n",
+ __func__, dig_tab->recover_cnt);
+ return rx_gain_range_min;
+ }
+
+ if (dig_tab->large_fa_hit >= 3) {
+ dig_tab->large_fa_hit = 0;
+ return rx_gain_range_min;
+ }
+
+ if ((dig_tab->forbidden_igi - 2) <
+ dig_dynamic_min) { /* DM_DIG_MIN) */
+ dig_tab->forbidden_igi =
+ dig_dynamic_min; /* DM_DIG_MIN; */
+ rx_gain_range_min = dig_dynamic_min; /* DM_DIG_MIN; */
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "%s(): Normal Case: At Lower Bound\n",
+ __func__);
+ } else {
+ if (dig_tab->large_fa_hit == 0) {
+ dig_tab->forbidden_igi -= 2;
+ rx_gain_range_min =
+ (dig_tab->forbidden_igi + 2);
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "%s(): Normal Case: Approach Lower Bound\n",
+ __func__);
+ }
+ }
+ }
+
+ return rx_gain_range_min;
+}
+
+static void phydm_set_big_jump_step(void *dm_void, u8 current_igi)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct dig_thres *dig_tab = &dm->dm_dig_table;
+ u8 step1[8] = {24, 30, 40, 50, 60, 70, 80, 90};
+ u8 i;
+
+ if (dig_tab->enable_adjust_big_jump == 0)
+ return;
+
+ for (i = 0; i <= dig_tab->big_jump_step1; i++) {
+ if ((current_igi + step1[i]) >
+ dig_tab->big_jump_lmt[dig_tab->agc_table_idx]) {
+ if (i != 0)
+ i = i - 1;
+ break;
+ } else if (i == dig_tab->big_jump_step1) {
+ break;
+ }
+ }
+ if (dm->support_ic_type & ODM_RTL8822B)
+ odm_set_bb_reg(dm, 0x8c8, 0xe, i);
+ else if (dm->support_ic_type & ODM_RTL8197F)
+ odm_set_bb_reg(dm, ODM_REG_BB_AGC_SET_2_11N, 0xe, i);
+
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "%s(): bigjump = %d (ori = 0x%x), LMT=0x%x\n", __func__, i,
+ dig_tab->big_jump_step1,
+ dig_tab->big_jump_lmt[dig_tab->agc_table_idx]);
+}
+
+void odm_write_dig(void *dm_void, u8 current_igi)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct dig_thres *dig_tab = &dm->dm_dig_table;
+
+ if (dig_tab->is_stop_dig) {
+ ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Stop Writing IGI\n",
+ __func__);
+ return;
+ }
+
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "%s(): ODM_REG(IGI_A,dm)=0x%x, ODM_BIT(IGI,dm)=0x%x\n",
+ __func__, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm));
+
+ /* 1 Check initial gain by upper bound */
+ if ((!dig_tab->is_psd_in_progress) && dm->is_linked) {
+ if (current_igi > dig_tab->rx_gain_range_max) {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "%s(): current_igi(0x%02x) is larger than upper bound !!\n",
+ __func__, current_igi);
+ current_igi = dig_tab->rx_gain_range_max;
+ }
+ if (dm->support_ability & ODM_BB_ADAPTIVITY &&
+ dm->adaptivity_flag) {
+ if (current_igi > dm->adaptivity_igi_upper)
+ current_igi = dm->adaptivity_igi_upper;
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "%s(): adaptivity case: Force upper bound to 0x%x !!!!!!\n",
+ __func__, current_igi);
+ }
+ }
+
+ if (dig_tab->cur_ig_value != current_igi) {
+ /* Modify big jump step for 8822B and 8197F */
+ if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8197F))
+ phydm_set_big_jump_step(dm, current_igi);
+
+ /* Set IGI value of CCK for new CCK AGC */
+ if (dm->cck_new_agc) {
+ if (dm->support_ic_type & ODM_IC_PHY_STATUE_NEW_TYPE)
+ odm_set_bb_reg(dm, 0xa0c, 0x00003f00,
+ (current_igi >> 1));
+ }
+
+ /*Add by YuChen for USB IO too slow issue*/
+ if ((dm->support_ability & ODM_BB_ADAPTIVITY) &&
+ (current_igi > dig_tab->cur_ig_value)) {
+ dig_tab->cur_ig_value = current_igi;
+ phydm_adaptivity(dm);
+ }
+
+ /* 1 Set IGI value */
+ if (dm->support_platform & (ODM_WIN | ODM_CE)) {
+ odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm),
+ current_igi);
+
+ if (dm->rf_type > ODM_1T1R)
+ odm_set_bb_reg(dm, ODM_REG(IGI_B, dm),
+ ODM_BIT(IGI, dm), current_igi);
+
+ } else if (dm->support_platform & (ODM_AP)) {
+ phydm_check_ap_write_dig(dm, current_igi);
+ }
+
+ dig_tab->cur_ig_value = current_igi;
+ }
+
+ ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): current_igi(0x%02x).\n", __func__,
+ current_igi);
+}
+
+void odm_pause_dig(void *dm_void, enum phydm_pause_type pause_type,
+ enum phydm_pause_level pause_level, u8 igi_value)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct dig_thres *dig_tab = &dm->dm_dig_table;
+ s8 max_level;
+
+ ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s()=========> level = %d\n", __func__,
+ pause_level);
+
+ if ((dig_tab->pause_dig_level == 0) &&
+ (!(dm->support_ability & ODM_BB_DIG) ||
+ !(dm->support_ability & ODM_BB_FA_CNT))) {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "%s(): Return: support_ability DIG or FA is disabled !!\n",
+ __func__);
+ return;
+ }
+
+ if (pause_level > DM_DIG_MAX_PAUSE_TYPE) {
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "%s(): Return: Wrong pause level !!\n", __func__);
+ return;
+ }
+
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "%s(): pause level = 0x%x, Current value = 0x%x\n",
+ __func__, dig_tab->pause_dig_level, igi_value);
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "%s(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ __func__, dig_tab->pause_dig_value[7],
+ dig_tab->pause_dig_value[6], dig_tab->pause_dig_value[5],
+ dig_tab->pause_dig_value[4], dig_tab->pause_dig_value[3],
+ dig_tab->pause_dig_value[2], dig_tab->pause_dig_value[1],
+ dig_tab->pause_dig_value[0]);
+
+ switch (pause_type) {
+ /* Pause DIG */
+ case PHYDM_PAUSE: {
+ /* Disable DIG */
+ odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY,
+ dm->support_ability & (~ODM_BB_DIG));
+ ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Pause DIG !!\n",
+ __func__);
+
+ /* Backup IGI value */
+ if (dig_tab->pause_dig_level == 0) {
+ dig_tab->igi_backup = dig_tab->cur_ig_value;
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "%s(): Backup IGI = 0x%x, new IGI = 0x%x\n",
+ __func__, dig_tab->igi_backup, igi_value);
+ }
+
+ /* Record IGI value */
+ dig_tab->pause_dig_value[pause_level] = igi_value;
+
+ /* Update pause level */
+ dig_tab->pause_dig_level =
+ (dig_tab->pause_dig_level | BIT(pause_level));
+
+ /* Write new IGI value */
+ if (BIT(pause_level + 1) > dig_tab->pause_dig_level) {
+ odm_write_dig(dm, igi_value);
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "%s(): IGI of higher level = 0x%x\n",
+ __func__, igi_value);
+ }
+ break;
+ }
+ /* Resume DIG */
+ case PHYDM_RESUME: {
+ /* check if the level is illegal or not */
+ if ((dig_tab->pause_dig_level & (BIT(pause_level))) != 0) {
+ dig_tab->pause_dig_level = dig_tab->pause_dig_level &
+ (~(BIT(pause_level)));
+ dig_tab->pause_dig_value[pause_level] = 0;
+ ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Resume DIG !!\n",
+ __func__);
+ } else {
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "%s(): Wrong resume level !!\n", __func__);
+ break;
+ }
+
+ /* Resume DIG */
+ if (dig_tab->pause_dig_level == 0) {
+ /* Write backup IGI value */
+ odm_write_dig(dm, dig_tab->igi_backup);
+ dig_tab->is_ignore_dig = true;
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "%s(): Write original IGI = 0x%x\n",
+ __func__, dig_tab->igi_backup);
+
+ /* Enable DIG */
+ odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY,
+ dm->support_ability | ODM_BB_DIG);
+ break;
+ }
+
+ if (BIT(pause_level) <= dig_tab->pause_dig_level)
+ break;
+
+ /* Calculate the maximum level now */
+ for (max_level = (pause_level - 1); max_level >= 0;
+ max_level--) {
+ if ((dig_tab->pause_dig_level & BIT(max_level)) > 0)
+ break;
+ }
+
+ /* write IGI of lower level */
+ odm_write_dig(dm, dig_tab->pause_dig_value[max_level]);
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "%s(): Write IGI (0x%x) of level (%d)\n", __func__,
+ dig_tab->pause_dig_value[max_level], max_level);
+ break;
+ }
+ default:
+ ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Wrong type !!\n",
+ __func__);
+ break;
+ }
+
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "%s(): pause level = 0x%x, Current value = 0x%x\n",
+ __func__, dig_tab->pause_dig_level, igi_value);
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "%s(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ __func__, dig_tab->pause_dig_value[7],
+ dig_tab->pause_dig_value[6], dig_tab->pause_dig_value[5],
+ dig_tab->pause_dig_value[4], dig_tab->pause_dig_value[3],
+ dig_tab->pause_dig_value[2], dig_tab->pause_dig_value[1],
+ dig_tab->pause_dig_value[0]);
+}
+
+static bool odm_dig_abort(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct dig_thres *dig_tab = &dm->dm_dig_table;
+
+ /* support_ability */
+ if (!(dm->support_ability & ODM_BB_FA_CNT)) {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "%s(): Return: support_ability ODM_BB_FA_CNT is disabled\n",
+ __func__);
+ return true;
+ }
+
+ /* support_ability */
+ if (!(dm->support_ability & ODM_BB_DIG)) {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "%s(): Return: support_ability ODM_BB_DIG is disabled\n",
+ __func__);
+ return true;
+ }
+
+ /* ScanInProcess */
+ if (*dm->is_scan_in_process) {
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "%s(): Return: In Scan Progress\n", __func__);
+ return true;
+ }
+
+ if (dig_tab->is_ignore_dig) {
+ dig_tab->is_ignore_dig = false;
+ ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Return: Ignore DIG\n",
+ __func__);
+ return true;
+ }
+
+ /* add by Neil Chen to avoid PSD is processing */
+ if (!dm->is_dm_initial_gain_enable) {
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "%s(): Return: PSD is Processing\n", __func__);
+ return true;
+ }
+
+ return false;
+}
+
+void odm_dig_init(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct dig_thres *dig_tab = &dm->dm_dig_table;
+ u32 ret_value;
+ u8 i;
+
+ dig_tab->is_stop_dig = false;
+ dig_tab->is_ignore_dig = false;
+ dig_tab->is_psd_in_progress = false;
+ dig_tab->cur_ig_value =
+ (u8)odm_get_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm));
+ dig_tab->pre_ig_value = 0;
+ dig_tab->rssi_low_thresh = DM_DIG_THRESH_LOW;
+ dig_tab->rssi_high_thresh = DM_DIG_THRESH_HIGH;
+ dig_tab->fa_low_thresh = DM_FALSEALARM_THRESH_LOW;
+ dig_tab->fa_high_thresh = DM_FALSEALARM_THRESH_HIGH;
+ dig_tab->backoff_val = DM_DIG_BACKOFF_DEFAULT;
+ dig_tab->backoff_val_range_max = DM_DIG_BACKOFF_MAX;
+ dig_tab->backoff_val_range_min = DM_DIG_BACKOFF_MIN;
+ dig_tab->pre_cck_cca_thres = 0xFF;
+ dig_tab->cur_cck_cca_thres = 0x83;
+ dig_tab->forbidden_igi = DM_DIG_MIN_NIC;
+ dig_tab->large_fa_hit = 0;
+ dig_tab->large_fa_timeout = 0;
+ dig_tab->recover_cnt = 0;
+ dig_tab->is_media_connect_0 = false;
+ dig_tab->is_media_connect_1 = false;
+
+ /*To initialize dm->is_dm_initial_gain_enable==false to avoid DIG err*/
+ dm->is_dm_initial_gain_enable = true;
+
+ dig_tab->dig_dynamic_min_0 = DM_DIG_MIN_NIC;
+ dig_tab->dig_dynamic_min_1 = DM_DIG_MIN_NIC;
+
+ /* To Initi BT30 IGI */
+ dig_tab->bt30_cur_igi = 0x32;
+
+ odm_memory_set(dm, dig_tab->pause_dig_value, 0,
+ (DM_DIG_MAX_PAUSE_TYPE + 1));
+ dig_tab->pause_dig_level = 0;
+ odm_memory_set(dm, dig_tab->pause_cckpd_value, 0,
+ (DM_DIG_MAX_PAUSE_TYPE + 1));
+ dig_tab->pause_cckpd_level = 0;
+
+ if (dm->board_type & (ODM_BOARD_EXT_PA | ODM_BOARD_EXT_LNA)) {
+ dig_tab->rx_gain_range_max = DM_DIG_MAX_NIC;
+ dig_tab->rx_gain_range_min = DM_DIG_MIN_NIC;
+ } else {
+ dig_tab->rx_gain_range_max = DM_DIG_MAX_NIC;
+ dig_tab->rx_gain_range_min = DM_DIG_MIN_NIC;
+ }
+
+ dig_tab->enable_adjust_big_jump = 1;
+ if (dm->support_ic_type & ODM_RTL8822B) {
+ ret_value = odm_get_bb_reg(dm, 0x8c8, MASKLWORD);
+ dig_tab->big_jump_step1 = (u8)(ret_value & 0xe) >> 1;
+ dig_tab->big_jump_step2 = (u8)(ret_value & 0x30) >> 4;
+ dig_tab->big_jump_step3 = (u8)(ret_value & 0xc0) >> 6;
+
+ } else if (dm->support_ic_type & ODM_RTL8197F) {
+ ret_value =
+ odm_get_bb_reg(dm, ODM_REG_BB_AGC_SET_2_11N, MASKLWORD);
+ dig_tab->big_jump_step1 = (u8)(ret_value & 0xe) >> 1;
+ dig_tab->big_jump_step2 = (u8)(ret_value & 0x30) >> 4;
+ dig_tab->big_jump_step3 = (u8)(ret_value & 0xc0) >> 6;
+ }
+ if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8197F)) {
+ for (i = 0; i < sizeof(dig_tab->big_jump_lmt); i++) {
+ if (dig_tab->big_jump_lmt[i] == 0)
+ dig_tab->big_jump_lmt[i] =
+ 0x64; /* Set -10dBm as default value */
+ }
+ }
+}
+
+void odm_DIG(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ /* Common parameters */
+ struct dig_thres *dig_tab = &dm->dm_dig_table;
+ struct false_alarm_stat *fa_cnt =
+ (struct false_alarm_stat *)phydm_get_structure(
+ dm, PHYDM_FALSEALMCNT);
+ bool first_connect, first_dis_connect;
+ u8 dig_max_of_min, dig_dynamic_min;
+ u8 dm_dig_max, dm_dig_min;
+ u8 current_igi = dig_tab->cur_ig_value;
+ u8 offset;
+ u32 dm_FA_thres[3];
+ u32 tx_tp = 0, rx_tp = 0;
+ bool is_dfs_band = false;
+ bool is_performance = true, is_first_tp_target = false,
+ is_first_coverage = false;
+
+ if (odm_dig_abort(dm))
+ return;
+
+ ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG Start===>\n");
+
+ /* 1 Update status */
+ {
+ dig_dynamic_min = dig_tab->dig_dynamic_min_0;
+ first_connect = (dm->is_linked) && !dig_tab->is_media_connect_0;
+ first_dis_connect =
+ (!dm->is_linked) && dig_tab->is_media_connect_0;
+ }
+
+ /* 1 Boundary Decision */
+ {
+ /* 2 For WIN\CE */
+ if (dm->support_ic_type >= ODM_RTL8188E)
+ dm_dig_max = 0x5A;
+ else
+ dm_dig_max = DM_DIG_MAX_NIC;
+
+ if (dm->support_ic_type != ODM_RTL8821)
+ dm_dig_min = DM_DIG_MIN_NIC;
+ else
+ dm_dig_min = 0x1C;
+
+ dig_max_of_min = DM_DIG_MAX_AP;
+
+ /* Modify lower bound for DFS band */
+ if ((((*dm->channel >= 52) && (*dm->channel <= 64)) ||
+ ((*dm->channel >= 100) && (*dm->channel <= 140))) &&
+ phydm_dfs_master_enabled(dm)) {
+ is_dfs_band = true;
+ if (*dm->band_width == ODM_BW20M)
+ dm_dig_min = DM_DIG_MIN_AP_DFS + 2;
+ else
+ dm_dig_min = DM_DIG_MIN_AP_DFS;
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "DIG: ====== In DFS band ======\n");
+ }
+ }
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "DIG: Absolutly upper bound = 0x%x, lower bound = 0x%x\n",
+ dm_dig_max, dm_dig_min);
+
+ if (dm->pu1_forced_igi_lb && (*dm->pu1_forced_igi_lb > 0)) {
+ ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG: Force IGI lb to: 0x%02x\n",
+ *dm->pu1_forced_igi_lb);
+ dm_dig_min = *dm->pu1_forced_igi_lb;
+ dm_dig_max = (dm_dig_min <= dm_dig_max) ? (dm_dig_max) :
+ (dm_dig_min + 1);
+ }
+
+ /* 1 Adjust boundary by RSSI */
+ if (dm->is_linked && is_performance) {
+ /* 2 Modify DIG upper bound */
+ /* 4 Modify DIG upper bound for 92E, 8723A\B, 8821 & 8812 BT */
+ if ((dm->support_ic_type & (ODM_RTL8192E | ODM_RTL8723B |
+ ODM_RTL8812 | ODM_RTL8821)) &&
+ (dm->is_bt_limited_dig == 1)) {
+ offset = 10;
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "DIG: Coex. case: Force upper bound to RSSI + %d\n",
+ offset);
+ } else {
+ offset = 15;
+ }
+
+ if ((dm->rssi_min + offset) > dm_dig_max)
+ dig_tab->rx_gain_range_max = dm_dig_max;
+ else if ((dm->rssi_min + offset) < dm_dig_min)
+ dig_tab->rx_gain_range_max = dm_dig_min;
+ else
+ dig_tab->rx_gain_range_max = dm->rssi_min + offset;
+
+ /* 2 Modify DIG lower bound */
+ /* if(dm->is_one_entry_only) */
+ {
+ if (dm->rssi_min < dm_dig_min)
+ dig_dynamic_min = dm_dig_min;
+ else if (dm->rssi_min > dig_max_of_min)
+ dig_dynamic_min = dig_max_of_min;
+ else
+ dig_dynamic_min = dm->rssi_min;
+
+ if (is_dfs_band) {
+ dig_dynamic_min = dm_dig_min;
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "DIG: DFS band: Force lower bound to 0x%x after link\n",
+ dm_dig_min);
+ }
+ }
+ } else {
+ if (is_performance && is_dfs_band) {
+ dig_tab->rx_gain_range_max = 0x28;
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "DIG: DFS band: Force upper bound to 0x%x before link\n",
+ dig_tab->rx_gain_range_max);
+ } else {
+ if (is_performance)
+ dig_tab->rx_gain_range_max = DM_DIG_MAX_OF_MIN;
+ else
+ dig_tab->rx_gain_range_max = dm_dig_max;
+ }
+ dig_dynamic_min = dm_dig_min;
+ }
+
+ /* 1 Force Lower Bound for AntDiv */
+ if (dm->is_linked && !dm->is_one_entry_only &&
+ (dm->support_ic_type & ODM_ANTDIV_SUPPORT) &&
+ (dm->support_ability & ODM_BB_ANT_DIV)) {
+ if (dm->ant_div_type == CG_TRX_HW_ANTDIV ||
+ dm->ant_div_type == CG_TRX_SMART_ANTDIV) {
+ if (dig_tab->ant_div_rssi_max > dig_max_of_min)
+ dig_dynamic_min = dig_max_of_min;
+ else
+ dig_dynamic_min = (u8)dig_tab->ant_div_rssi_max;
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "DIG: AntDiv case: Force lower bound to 0x%x\n",
+ dig_dynamic_min);
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "DIG: AntDiv case: rssi_max = 0x%x\n",
+ dig_tab->ant_div_rssi_max);
+ }
+ }
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "DIG: Adjust boundary by RSSI Upper bound = 0x%x, Lower bound = 0x%x\n",
+ dig_tab->rx_gain_range_max, dig_dynamic_min);
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "DIG: Link status: is_linked = %d, RSSI = %d, bFirstConnect = %d, bFirsrDisConnect = %d\n",
+ dm->is_linked, dm->rssi_min, first_connect, first_dis_connect);
+
+ /* 1 Modify DIG lower bound, deal with abnormal case */
+ /* 2 Abnormal false alarm case */
+ if (is_dfs_band) {
+ dig_tab->rx_gain_range_min = dig_dynamic_min;
+ } else {
+ if (!dm->is_linked) {
+ dig_tab->rx_gain_range_min = dig_dynamic_min;
+
+ if (first_dis_connect)
+ dig_tab->forbidden_igi = dig_dynamic_min;
+ } else {
+ dig_tab->rx_gain_range_min = odm_forbidden_igi_check(
+ dm, dig_dynamic_min, current_igi);
+ }
+ }
+
+ /* 2 Abnormal # beacon case */
+ if (dm->is_linked && !first_connect) {
+ ODM_RT_TRACE(dm, ODM_COMP_DIG, "Beacon Num (%d)\n",
+ dm->phy_dbg_info.num_qry_beacon_pkt);
+ if ((dm->phy_dbg_info.num_qry_beacon_pkt < 5) &&
+ (dm->bsta_state)) {
+ dig_tab->rx_gain_range_min = 0x1c;
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "DIG: Abnrormal #beacon (%d) case in STA mode: Force lower bound to 0x%x\n",
+ dm->phy_dbg_info.num_qry_beacon_pkt,
+ dig_tab->rx_gain_range_min);
+ }
+ }
+
+ /* 2 Abnormal lower bound case */
+ if (dig_tab->rx_gain_range_min > dig_tab->rx_gain_range_max) {
+ dig_tab->rx_gain_range_min = dig_tab->rx_gain_range_max;
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "DIG: Abnrormal lower bound case: Force lower bound to 0x%x\n",
+ dig_tab->rx_gain_range_min);
+ }
+
+ /* 1 False alarm threshold decision */
+ odm_fa_threshold_check(dm, is_dfs_band, is_performance, rx_tp, tx_tp,
+ dm_FA_thres);
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "DIG: False alarm threshold = %d, %d, %d\n",
+ dm_FA_thres[0], dm_FA_thres[1], dm_FA_thres[2]);
+
+ /* 1 Adjust initial gain by false alarm */
+ if (dm->is_linked && is_performance) {
+ /* 2 After link */
+ ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG: Adjust IGI after link\n");
+
+ if (is_first_tp_target || (first_connect && is_performance)) {
+ dig_tab->large_fa_hit = 0;
+
+ if (is_dfs_band) {
+ u8 rssi = dm->rssi_min;
+
+ current_igi =
+ (dm->rssi_min > 0x28) ? 0x28 : rssi;
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "DIG: DFS band: One-shot to 0x28 upmost\n");
+ } else {
+ current_igi = phydm_get_current_igi(
+ dig_max_of_min, dm->rssi_min,
+ current_igi);
+ }
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "DIG: First connect case: IGI does on-shot to 0x%x\n",
+ current_igi);
+
+ } else {
+ if (fa_cnt->cnt_all > dm_FA_thres[2])
+ current_igi = current_igi + 4;
+ else if (fa_cnt->cnt_all > dm_FA_thres[1])
+ current_igi = current_igi + 2;
+ else if (fa_cnt->cnt_all < dm_FA_thres[0])
+ current_igi = current_igi - 2;
+
+ /* 4 Abnormal # beacon case */
+ if ((dm->phy_dbg_info.num_qry_beacon_pkt < 5) &&
+ (fa_cnt->cnt_all < DM_DIG_FA_TH1) &&
+ (dm->bsta_state)) {
+ current_igi = dig_tab->rx_gain_range_min;
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "DIG: Abnormal #beacon (%d) case: IGI does one-shot to 0x%x\n",
+ dm->phy_dbg_info.num_qry_beacon_pkt,
+ current_igi);
+ }
+ }
+ } else {
+ /* 2 Before link */
+ ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG: Adjust IGI before link\n");
+
+ if (first_dis_connect || is_first_coverage) {
+ current_igi = dm_dig_min;
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "DIG: First disconnect case: IGI does on-shot to lower bound\n");
+ } else {
+ if (fa_cnt->cnt_all > dm_FA_thres[2])
+ current_igi = current_igi + 4;
+ else if (fa_cnt->cnt_all > dm_FA_thres[1])
+ current_igi = current_igi + 2;
+ else if (fa_cnt->cnt_all < dm_FA_thres[0])
+ current_igi = current_igi - 2;
+ }
+ }
+
+ /* 1 Check initial gain by upper/lower bound */
+ if (current_igi < dig_tab->rx_gain_range_min)
+ current_igi = dig_tab->rx_gain_range_min;
+
+ if (current_igi > dig_tab->rx_gain_range_max)
+ current_igi = dig_tab->rx_gain_range_max;
+
+ ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG: cur_ig_value=0x%x, TotalFA = %d\n",
+ current_igi, fa_cnt->cnt_all);
+
+ /* 1 Update status */
+ if (dm->is_bt_hs_operation) {
+ if (dm->is_linked) {
+ if (dig_tab->bt30_cur_igi > (current_igi))
+ odm_write_dig(dm, current_igi);
+ else
+ odm_write_dig(dm, dig_tab->bt30_cur_igi);
+
+ dig_tab->is_media_connect_0 = dm->is_linked;
+ dig_tab->dig_dynamic_min_0 = dig_dynamic_min;
+ } else {
+ if (dm->is_link_in_process)
+ odm_write_dig(dm, 0x1c);
+ else if (dm->is_bt_connect_process)
+ odm_write_dig(dm, 0x28);
+ else
+ odm_write_dig(dm, dig_tab->bt30_cur_igi);
+ }
+ } else { /* BT is not using */
+ odm_write_dig(dm, current_igi);
+ dig_tab->is_media_connect_0 = dm->is_linked;
+ dig_tab->dig_dynamic_min_0 = dig_dynamic_min;
+ }
+ ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG end\n");
+}
+
+void odm_dig_by_rssi_lps(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct false_alarm_stat *fa_cnt =
+ (struct false_alarm_stat *)phydm_get_structure(
+ dm, PHYDM_FALSEALMCNT);
+
+ u8 rssi_lower = DM_DIG_MIN_NIC; /* 0x1E or 0x1C */
+ u8 current_igi = dm->rssi_min;
+
+ if (odm_dig_abort(dm))
+ return;
+
+ current_igi = current_igi + RSSI_OFFSET_DIG;
+
+ ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s()==>\n", __func__);
+
+ /* Using FW PS mode to make IGI */
+ /* Adjust by FA in LPS MODE */
+ if (fa_cnt->cnt_all > DM_DIG_FA_TH2_LPS)
+ current_igi = current_igi + 4;
+ else if (fa_cnt->cnt_all > DM_DIG_FA_TH1_LPS)
+ current_igi = current_igi + 2;
+ else if (fa_cnt->cnt_all < DM_DIG_FA_TH0_LPS)
+ current_igi = current_igi - 2;
+
+ /* Lower bound checking */
+
+ /* RSSI Lower bound check */
+ if ((dm->rssi_min - 10) > DM_DIG_MIN_NIC)
+ rssi_lower = (dm->rssi_min - 10);
+ else
+ rssi_lower = DM_DIG_MIN_NIC;
+
+ /* Upper and Lower Bound checking */
+ if (current_igi > DM_DIG_MAX_NIC)
+ current_igi = DM_DIG_MAX_NIC;
+ else if (current_igi < rssi_lower)
+ current_igi = rssi_lower;
+
+ ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): fa_cnt->cnt_all = %d\n", __func__,
+ fa_cnt->cnt_all);
+ ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): dm->rssi_min = %d\n", __func__,
+ dm->rssi_min);
+ ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): current_igi = 0x%x\n", __func__,
+ current_igi);
+
+ odm_write_dig(
+ dm,
+ current_igi); /* odm_write_dig(dm, dig_tab->cur_ig_value); */
+}
+
+/* 3============================================================
+ * 3 FASLE ALARM CHECK
+ * 3============================================================
+ */
+
+void odm_false_alarm_counter_statistics(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct false_alarm_stat *false_alm_cnt =
+ (struct false_alarm_stat *)phydm_get_structure(
+ dm, PHYDM_FALSEALMCNT);
+ struct rt_adcsmp *adc_smp = &dm->adcsmp;
+ u32 ret_value;
+
+ if (!(dm->support_ability & ODM_BB_FA_CNT))
+ return;
+
+ ODM_RT_TRACE(dm, ODM_COMP_FA_CNT, "%s()======>\n", __func__);
+
+ if (dm->support_ic_type & ODM_IC_11N_SERIES) {
+ /* hold ofdm counter */
+ odm_set_bb_reg(dm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31),
+ 1); /* hold page C counter */
+ odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTD_11N, BIT(31),
+ 1); /* hold page D counter */
+
+ ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE1_11N,
+ MASKDWORD);
+ false_alm_cnt->cnt_fast_fsync = (ret_value & 0xffff);
+ false_alm_cnt->cnt_sb_search_fail =
+ ((ret_value & 0xffff0000) >> 16);
+
+ ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE2_11N,
+ MASKDWORD);
+ false_alm_cnt->cnt_ofdm_cca = (ret_value & 0xffff);
+ false_alm_cnt->cnt_parity_fail =
+ ((ret_value & 0xffff0000) >> 16);
+
+ ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE3_11N,
+ MASKDWORD);
+ false_alm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
+ false_alm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
+
+ ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE4_11N,
+ MASKDWORD);
+ false_alm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
+
+ false_alm_cnt->cnt_ofdm_fail =
+ false_alm_cnt->cnt_parity_fail +
+ false_alm_cnt->cnt_rate_illegal +
+ false_alm_cnt->cnt_crc8_fail +
+ false_alm_cnt->cnt_mcs_fail +
+ false_alm_cnt->cnt_fast_fsync +
+ false_alm_cnt->cnt_sb_search_fail;
+
+ /* read CCK CRC32 counter */
+ false_alm_cnt->cnt_cck_crc32_error = odm_get_bb_reg(
+ dm, ODM_REG_CCK_CRC32_ERROR_CNT_11N, MASKDWORD);
+ false_alm_cnt->cnt_cck_crc32_ok = odm_get_bb_reg(
+ dm, ODM_REG_CCK_CRC32_OK_CNT_11N, MASKDWORD);
+
+ /* read OFDM CRC32 counter */
+ ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_CRC32_CNT_11N,
+ MASKDWORD);
+ false_alm_cnt->cnt_ofdm_crc32_error =
+ (ret_value & 0xffff0000) >> 16;
+ false_alm_cnt->cnt_ofdm_crc32_ok = ret_value & 0xffff;
+
+ /* read HT CRC32 counter */
+ ret_value =
+ odm_get_bb_reg(dm, ODM_REG_HT_CRC32_CNT_11N, MASKDWORD);
+ false_alm_cnt->cnt_ht_crc32_error =
+ (ret_value & 0xffff0000) >> 16;
+ false_alm_cnt->cnt_ht_crc32_ok = ret_value & 0xffff;
+
+ /* read VHT CRC32 counter */
+ false_alm_cnt->cnt_vht_crc32_error = 0;
+ false_alm_cnt->cnt_vht_crc32_ok = 0;
+
+ {
+ /* hold cck counter */
+ odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N, BIT(12), 1);
+ odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N, BIT(14), 1);
+
+ ret_value = odm_get_bb_reg(dm, ODM_REG_CCK_FA_LSB_11N,
+ MASKBYTE0);
+ false_alm_cnt->cnt_cck_fail = ret_value;
+
+ ret_value = odm_get_bb_reg(dm, ODM_REG_CCK_FA_MSB_11N,
+ MASKBYTE3);
+ false_alm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
+
+ ret_value = odm_get_bb_reg(dm, ODM_REG_CCK_CCA_CNT_11N,
+ MASKDWORD);
+ false_alm_cnt->cnt_cck_cca =
+ ((ret_value & 0xFF) << 8) |
+ ((ret_value & 0xFF00) >> 8);
+ }
+
+ false_alm_cnt->cnt_all_pre = false_alm_cnt->cnt_all;
+
+ false_alm_cnt->cnt_all = (false_alm_cnt->cnt_fast_fsync +
+ false_alm_cnt->cnt_sb_search_fail +
+ false_alm_cnt->cnt_parity_fail +
+ false_alm_cnt->cnt_rate_illegal +
+ false_alm_cnt->cnt_crc8_fail +
+ false_alm_cnt->cnt_mcs_fail +
+ false_alm_cnt->cnt_cck_fail);
+
+ false_alm_cnt->cnt_cca_all = false_alm_cnt->cnt_ofdm_cca +
+ false_alm_cnt->cnt_cck_cca;
+
+ if (dm->support_ic_type >= ODM_RTL8188E) {
+ /*reset false alarm counter registers*/
+ odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTC_11N, BIT(31),
+ 1);
+ odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTC_11N, BIT(31),
+ 0);
+ odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTD_11N, BIT(27),
+ 1);
+ odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTD_11N, BIT(27),
+ 0);
+
+ /*update ofdm counter*/
+ odm_set_bb_reg(dm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31),
+ 0); /*update page C counter*/
+ odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTD_11N, BIT(31),
+ 0); /*update page D counter*/
+
+ /*reset CCK CCA counter*/
+ odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N,
+ BIT(13) | BIT(12), 0);
+ odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N,
+ BIT(13) | BIT(12), 2);
+
+ /*reset CCK FA counter*/
+ odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N,
+ BIT(15) | BIT(14), 0);
+ odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N,
+ BIT(15) | BIT(14), 2);
+
+ /*reset CRC32 counter*/
+ odm_set_bb_reg(dm, ODM_REG_PAGE_F_RST_11N, BIT(16), 1);
+ odm_set_bb_reg(dm, ODM_REG_PAGE_F_RST_11N, BIT(16), 0);
+ }
+
+ /* Get debug port 0 */
+ odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11N, MASKDWORD, 0x0);
+ false_alm_cnt->dbg_port0 =
+ odm_get_bb_reg(dm, ODM_REG_RPT_11N, MASKDWORD);
+
+ /* Get EDCCA flag */
+ odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11N, MASKDWORD, 0x208);
+ false_alm_cnt->edcca_flag =
+ (bool)odm_get_bb_reg(dm, ODM_REG_RPT_11N, BIT(30));
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_FA_CNT,
+ "[OFDM FA Detail] Parity_Fail = (( %d )), Rate_Illegal = (( %d )), CRC8_fail = (( %d )), Mcs_fail = (( %d )), Fast_Fsync = (( %d )), SB_Search_fail = (( %d ))\n",
+ false_alm_cnt->cnt_parity_fail,
+ false_alm_cnt->cnt_rate_illegal,
+ false_alm_cnt->cnt_crc8_fail,
+ false_alm_cnt->cnt_mcs_fail,
+ false_alm_cnt->cnt_fast_fsync,
+ false_alm_cnt->cnt_sb_search_fail);
+ }
+
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ u32 cck_enable;
+
+ /* read OFDM FA counter */
+ false_alm_cnt->cnt_ofdm_fail =
+ odm_get_bb_reg(dm, ODM_REG_OFDM_FA_11AC, MASKLWORD);
+
+ /* Read CCK FA counter */
+ false_alm_cnt->cnt_cck_fail =
+ odm_get_bb_reg(dm, ODM_REG_CCK_FA_11AC, MASKLWORD);
+
+ /* read CCK/OFDM CCA counter */
+ ret_value =
+ odm_get_bb_reg(dm, ODM_REG_CCK_CCA_CNT_11AC, MASKDWORD);
+ false_alm_cnt->cnt_ofdm_cca = (ret_value & 0xffff0000) >> 16;
+ false_alm_cnt->cnt_cck_cca = ret_value & 0xffff;
+
+ /* read CCK CRC32 counter */
+ ret_value = odm_get_bb_reg(dm, ODM_REG_CCK_CRC32_CNT_11AC,
+ MASKDWORD);
+ false_alm_cnt->cnt_cck_crc32_error =
+ (ret_value & 0xffff0000) >> 16;
+ false_alm_cnt->cnt_cck_crc32_ok = ret_value & 0xffff;
+
+ /* read OFDM CRC32 counter */
+ ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_CRC32_CNT_11AC,
+ MASKDWORD);
+ false_alm_cnt->cnt_ofdm_crc32_error =
+ (ret_value & 0xffff0000) >> 16;
+ false_alm_cnt->cnt_ofdm_crc32_ok = ret_value & 0xffff;
+
+ /* read HT CRC32 counter */
+ ret_value = odm_get_bb_reg(dm, ODM_REG_HT_CRC32_CNT_11AC,
+ MASKDWORD);
+ false_alm_cnt->cnt_ht_crc32_error =
+ (ret_value & 0xffff0000) >> 16;
+ false_alm_cnt->cnt_ht_crc32_ok = ret_value & 0xffff;
+
+ /* read VHT CRC32 counter */
+ ret_value = odm_get_bb_reg(dm, ODM_REG_VHT_CRC32_CNT_11AC,
+ MASKDWORD);
+ false_alm_cnt->cnt_vht_crc32_error =
+ (ret_value & 0xffff0000) >> 16;
+ false_alm_cnt->cnt_vht_crc32_ok = ret_value & 0xffff;
+
+ /* reset OFDM FA counter */
+ odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 1);
+ odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 0);
+
+ /* reset CCK FA counter */
+ odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11AC, BIT(15), 0);
+ odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11AC, BIT(15), 1);
+
+ /* reset CCA counter */
+ odm_set_bb_reg(dm, ODM_REG_RST_RPT_11AC, BIT(0), 1);
+ odm_set_bb_reg(dm, ODM_REG_RST_RPT_11AC, BIT(0), 0);
+
+ cck_enable =
+ odm_get_bb_reg(dm, ODM_REG_BB_RX_PATH_11AC, BIT(28));
+ if (cck_enable) { /* if(*dm->band_type == ODM_BAND_2_4G) */
+ false_alm_cnt->cnt_all = false_alm_cnt->cnt_ofdm_fail +
+ false_alm_cnt->cnt_cck_fail;
+ false_alm_cnt->cnt_cca_all =
+ false_alm_cnt->cnt_cck_cca +
+ false_alm_cnt->cnt_ofdm_cca;
+ } else {
+ false_alm_cnt->cnt_all = false_alm_cnt->cnt_ofdm_fail;
+ false_alm_cnt->cnt_cca_all =
+ false_alm_cnt->cnt_ofdm_cca;
+ }
+
+ if (adc_smp->adc_smp_state == ADCSMP_STATE_IDLE) {
+ if (phydm_set_bb_dbg_port(
+ dm, BB_DBGPORT_PRIORITY_1,
+ 0x0)) { /*set debug port to 0x0*/
+ false_alm_cnt->dbg_port0 =
+ phydm_get_bb_dbg_port_value(dm);
+ phydm_release_bb_dbg_port(dm);
+ }
+
+ if (phydm_set_bb_dbg_port(
+ dm, BB_DBGPORT_PRIORITY_1,
+ 0x209)) { /*set debug port to 0x0*/
+ false_alm_cnt->edcca_flag =
+ (bool)((phydm_get_bb_dbg_port_value(
+ dm) &
+ BIT(30)) >>
+ 30);
+ phydm_release_bb_dbg_port(dm);
+ }
+ }
+ }
+
+ false_alm_cnt->cnt_crc32_error_all =
+ false_alm_cnt->cnt_vht_crc32_error +
+ false_alm_cnt->cnt_ht_crc32_error +
+ false_alm_cnt->cnt_ofdm_crc32_error +
+ false_alm_cnt->cnt_cck_crc32_error;
+ false_alm_cnt->cnt_crc32_ok_all = false_alm_cnt->cnt_vht_crc32_ok +
+ false_alm_cnt->cnt_ht_crc32_ok +
+ false_alm_cnt->cnt_ofdm_crc32_ok +
+ false_alm_cnt->cnt_cck_crc32_ok;
+
+ ODM_RT_TRACE(dm, ODM_COMP_FA_CNT,
+ "[CCA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n",
+ false_alm_cnt->cnt_cck_cca, false_alm_cnt->cnt_ofdm_cca,
+ false_alm_cnt->cnt_cca_all);
+
+ ODM_RT_TRACE(dm, ODM_COMP_FA_CNT,
+ "[FA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n",
+ false_alm_cnt->cnt_cck_fail, false_alm_cnt->cnt_ofdm_fail,
+ false_alm_cnt->cnt_all);
+
+ ODM_RT_TRACE(dm, ODM_COMP_FA_CNT,
+ "[CCK] CRC32 {error, ok}= {%d, %d}\n",
+ false_alm_cnt->cnt_cck_crc32_error,
+ false_alm_cnt->cnt_cck_crc32_ok);
+ ODM_RT_TRACE(dm, ODM_COMP_FA_CNT, "[OFDM]CRC32 {error, ok}= {%d, %d}\n",
+ false_alm_cnt->cnt_ofdm_crc32_error,
+ false_alm_cnt->cnt_ofdm_crc32_ok);
+ ODM_RT_TRACE(dm, ODM_COMP_FA_CNT,
+ "[ HT ] CRC32 {error, ok}= {%d, %d}\n",
+ false_alm_cnt->cnt_ht_crc32_error,
+ false_alm_cnt->cnt_ht_crc32_ok);
+ ODM_RT_TRACE(dm, ODM_COMP_FA_CNT,
+ "[VHT] CRC32 {error, ok}= {%d, %d}\n",
+ false_alm_cnt->cnt_vht_crc32_error,
+ false_alm_cnt->cnt_vht_crc32_ok);
+ ODM_RT_TRACE(dm, ODM_COMP_FA_CNT,
+ "[VHT] CRC32 {error, ok}= {%d, %d}\n",
+ false_alm_cnt->cnt_crc32_error_all,
+ false_alm_cnt->cnt_crc32_ok_all);
+ ODM_RT_TRACE(dm, ODM_COMP_FA_CNT,
+ "FA_Cnt: Dbg port 0x0 = 0x%x, EDCCA = %d\n\n",
+ false_alm_cnt->dbg_port0, false_alm_cnt->edcca_flag);
+}
+
+/* 3============================================================
+ * 3 CCK Packet Detect threshold
+ * 3============================================================
+ */
+
+void odm_pause_cck_packet_detection(void *dm_void,
+ enum phydm_pause_type pause_type,
+ enum phydm_pause_level pause_level,
+ u8 cck_pd_threshold)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct dig_thres *dig_tab = &dm->dm_dig_table;
+ s8 max_level;
+
+ ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s()=========> level = %d\n", __func__,
+ pause_level);
+
+ if ((dig_tab->pause_cckpd_level == 0) &&
+ (!(dm->support_ability & ODM_BB_CCK_PD) ||
+ !(dm->support_ability & ODM_BB_FA_CNT))) {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "Return: support_ability ODM_BB_CCK_PD or ODM_BB_FA_CNT is disabled\n");
+ return;
+ }
+
+ if (pause_level > DM_DIG_MAX_PAUSE_TYPE) {
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "%s(): Return: Wrong pause level !!\n", __func__);
+ return;
+ }
+
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "%s(): pause level = 0x%x, Current value = 0x%x\n",
+ __func__, dig_tab->pause_cckpd_level, cck_pd_threshold);
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "%s(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ __func__, dig_tab->pause_cckpd_value[7],
+ dig_tab->pause_cckpd_value[6], dig_tab->pause_cckpd_value[5],
+ dig_tab->pause_cckpd_value[4], dig_tab->pause_cckpd_value[3],
+ dig_tab->pause_cckpd_value[2], dig_tab->pause_cckpd_value[1],
+ dig_tab->pause_cckpd_value[0]);
+
+ switch (pause_type) {
+ /* Pause CCK Packet Detection threshold */
+ case PHYDM_PAUSE: {
+ /* Disable CCK PD */
+ odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY,
+ dm->support_ability & (~ODM_BB_CCK_PD));
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "%s(): Pause CCK packet detection threshold !!\n",
+ __func__);
+
+ /*Backup original CCK PD threshold decided by CCK PD mechanism*/
+ if (dig_tab->pause_cckpd_level == 0) {
+ dig_tab->cck_pd_backup = dig_tab->cur_cck_cca_thres;
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "%s(): Backup CCKPD = 0x%x, new CCKPD = 0x%x\n",
+ __func__, dig_tab->cck_pd_backup,
+ cck_pd_threshold);
+ }
+
+ /* Update pause level */
+ dig_tab->pause_cckpd_level =
+ (dig_tab->pause_cckpd_level | BIT(pause_level));
+
+ /* Record CCK PD threshold */
+ dig_tab->pause_cckpd_value[pause_level] = cck_pd_threshold;
+
+ /* Write new CCK PD threshold */
+ if (BIT(pause_level + 1) > dig_tab->pause_cckpd_level) {
+ odm_write_cck_cca_thres(dm, cck_pd_threshold);
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "%s(): CCKPD of higher level = 0x%x\n",
+ __func__, cck_pd_threshold);
+ }
+ break;
+ }
+ /* Resume CCK Packet Detection threshold */
+ case PHYDM_RESUME: {
+ /* check if the level is illegal or not */
+ if ((dig_tab->pause_cckpd_level & (BIT(pause_level))) != 0) {
+ dig_tab->pause_cckpd_level =
+ dig_tab->pause_cckpd_level &
+ (~(BIT(pause_level)));
+ dig_tab->pause_cckpd_value[pause_level] = 0;
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "%s(): Resume CCK PD !!\n", __func__);
+ } else {
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "%s(): Wrong resume level !!\n", __func__);
+ break;
+ }
+
+ /* Resume DIG */
+ if (dig_tab->pause_cckpd_level == 0) {
+ /* Write backup IGI value */
+ odm_write_cck_cca_thres(dm, dig_tab->cck_pd_backup);
+ /* dig_tab->is_ignore_dig = true; */
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "%s(): Write original CCKPD = 0x%x\n",
+ __func__, dig_tab->cck_pd_backup);
+
+ /* Enable DIG */
+ odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY,
+ dm->support_ability |
+ ODM_BB_CCK_PD);
+ break;
+ }
+
+ if (BIT(pause_level) <= dig_tab->pause_cckpd_level)
+ break;
+
+ /* Calculate the maximum level now */
+ for (max_level = (pause_level - 1); max_level >= 0;
+ max_level--) {
+ if ((dig_tab->pause_cckpd_level & BIT(max_level)) > 0)
+ break;
+ }
+
+ /* write CCKPD of lower level */
+ odm_write_cck_cca_thres(dm,
+ dig_tab->pause_cckpd_value[max_level]);
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "%s(): Write CCKPD (0x%x) of level (%d)\n",
+ __func__, dig_tab->pause_cckpd_value[max_level],
+ max_level);
+ break;
+ }
+ default:
+ ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Wrong type !!\n",
+ __func__);
+ break;
+ }
+
+ ODM_RT_TRACE(dm, ODM_COMP_DIG,
+ "%s(): pause level = 0x%x, Current value = 0x%x\n",
+ __func__, dig_tab->pause_cckpd_level, cck_pd_threshold);
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "%s(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ __func__, dig_tab->pause_cckpd_value[7],
+ dig_tab->pause_cckpd_value[6], dig_tab->pause_cckpd_value[5],
+ dig_tab->pause_cckpd_value[4], dig_tab->pause_cckpd_value[3],
+ dig_tab->pause_cckpd_value[2], dig_tab->pause_cckpd_value[1],
+ dig_tab->pause_cckpd_value[0]);
+}
+
+void odm_cck_packet_detection_thresh(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct dig_thres *dig_tab = &dm->dm_dig_table;
+ struct false_alarm_stat *false_alm_cnt =
+ (struct false_alarm_stat *)phydm_get_structure(
+ dm, PHYDM_FALSEALMCNT);
+ u8 cur_cck_cca_thres = dig_tab->cur_cck_cca_thres, rssi_thd = 35;
+
+ if ((!(dm->support_ability & ODM_BB_CCK_PD)) ||
+ (!(dm->support_ability & ODM_BB_FA_CNT))) {
+ ODM_RT_TRACE(dm, ODM_COMP_DIG, "CCK_PD: return==========\n");
+ return;
+ }
+
+ if (dm->ext_lna)
+ return;
+
+ ODM_RT_TRACE(dm, ODM_COMP_DIG, "CCK_PD: ==========>\n");
+
+ if (dig_tab->cck_fa_ma == 0xffffffff)
+ dig_tab->cck_fa_ma = false_alm_cnt->cnt_cck_fail;
+ else
+ dig_tab->cck_fa_ma =
+ ((dig_tab->cck_fa_ma << 1) + dig_tab->cck_fa_ma +
+ false_alm_cnt->cnt_cck_fail) >>
+ 2;
+
+ ODM_RT_TRACE(dm, ODM_COMP_DIG, "CCK_PD: CCK FA moving average = %d\n",
+ dig_tab->cck_fa_ma);
+
+ if (dm->is_linked) {
+ if (dm->rssi_min > rssi_thd) {
+ cur_cck_cca_thres = 0xcd;
+ } else if (dm->rssi_min > 20) {
+ if (dig_tab->cck_fa_ma >
+ ((DM_DIG_FA_TH1 >> 1) + (DM_DIG_FA_TH1 >> 3)))
+ cur_cck_cca_thres = 0xcd;
+ else if (dig_tab->cck_fa_ma < (DM_DIG_FA_TH0 >> 1))
+ cur_cck_cca_thres = 0x83;
+ } else if (dm->rssi_min > 7) {
+ cur_cck_cca_thres = 0x83;
+ } else {
+ cur_cck_cca_thres = 0x40;
+ }
+
+ } else {
+ if (dig_tab->cck_fa_ma > 0x400)
+ cur_cck_cca_thres = 0x83;
+ else if (dig_tab->cck_fa_ma < 0x200)
+ cur_cck_cca_thres = 0x40;
+ }
+
+ {
+ odm_write_cck_cca_thres(dm, cur_cck_cca_thres);
+ }
+
+ ODM_RT_TRACE(dm, ODM_COMP_DIG, "CCK_PD: cck_cca_th=((0x%x))\n\n",
+ cur_cck_cca_thres);
+}
+
+void odm_write_cck_cca_thres(void *dm_void, u8 cur_cck_cca_thres)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct dig_thres *dig_tab = &dm->dm_dig_table;
+
+ if (dig_tab->cur_cck_cca_thres !=
+ cur_cck_cca_thres) { /* modify by Guo.Mingzhi 2012-01-03 */
+ odm_write_1byte(dm, ODM_REG(CCK_CCA, dm), cur_cck_cca_thres);
+ dig_tab->cck_fa_ma = 0xffffffff;
+ }
+ dig_tab->pre_cck_cca_thres = dig_tab->cur_cck_cca_thres;
+ dig_tab->cur_cck_cca_thres = cur_cck_cca_thres;
+}
+
+bool phydm_dig_go_up_check(void *dm_void)
+{
+ bool ret = true;
+
+ return ret;
+}
diff --git a/drivers/staging/rtlwifi/phydm/phydm_dig.h b/drivers/staging/rtlwifi/phydm/phydm_dig.h
new file mode 100644
index 0000000..af70aae
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_dig.h
@@ -0,0 +1,241 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __PHYDMDIG_H__
+#define __PHYDMDIG_H__
+
+#define DIG_VERSION "1.32" /* 2016.09.02 YuChen. add CCK PD for 8197F*/
+
+/* Pause DIG & CCKPD */
+#define DM_DIG_MAX_PAUSE_TYPE 0x7
+
+enum dig_goupcheck_level {
+ DIG_GOUPCHECK_LEVEL_0,
+ DIG_GOUPCHECK_LEVEL_1,
+ DIG_GOUPCHECK_LEVEL_2
+
+};
+
+struct dig_thres {
+ bool is_stop_dig; /* for debug */
+ bool is_ignore_dig;
+ bool is_psd_in_progress;
+
+ u8 dig_enable_flag;
+ u8 dig_ext_port_stage;
+
+ int rssi_low_thresh;
+ int rssi_high_thresh;
+
+ u32 fa_low_thresh;
+ u32 fa_high_thresh;
+
+ u8 cur_sta_connect_state;
+ u8 pre_sta_connect_state;
+ u8 cur_multi_sta_connect_state;
+
+ u8 pre_ig_value;
+ u8 cur_ig_value;
+ u8 backup_ig_value; /* MP DIG */
+ u8 bt30_cur_igi;
+ u8 igi_backup;
+
+ s8 backoff_val;
+ s8 backoff_val_range_max;
+ s8 backoff_val_range_min;
+ u8 rx_gain_range_max;
+ u8 rx_gain_range_min;
+ u8 rssi_val_min;
+
+ u8 pre_cck_cca_thres;
+ u8 cur_cck_cca_thres;
+ u8 pre_cck_pd_state;
+ u8 cur_cck_pd_state;
+ u8 cck_pd_backup;
+ u8 pause_cckpd_level;
+ u8 pause_cckpd_value[DM_DIG_MAX_PAUSE_TYPE + 1];
+
+ u8 large_fa_hit;
+ u8 large_fa_timeout; /*if (large_fa_hit), monitor "large_fa_timeout"
+ *sec, if timeout, large_fa_hit=0
+ */
+ u8 forbidden_igi;
+ u32 recover_cnt;
+
+ u8 dig_dynamic_min_0;
+ u8 dig_dynamic_min_1;
+ bool is_media_connect_0;
+ bool is_media_connect_1;
+
+ u32 ant_div_rssi_max;
+ u32 rssi_max;
+
+ u8 *is_p2p_in_process;
+
+ u8 pause_dig_level;
+ u8 pause_dig_value[DM_DIG_MAX_PAUSE_TYPE + 1];
+
+ u32 cck_fa_ma;
+ enum dig_goupcheck_level dig_go_up_check_level;
+ u8 aaa_default;
+
+ u8 rf_gain_idx;
+ u8 agc_table_idx;
+ u8 big_jump_lmt[16];
+ u8 enable_adjust_big_jump : 1;
+ u8 big_jump_step1 : 3;
+ u8 big_jump_step2 : 2;
+ u8 big_jump_step3 : 2;
+};
+
+struct false_alarm_stat {
+ u32 cnt_parity_fail;
+ u32 cnt_rate_illegal;
+ u32 cnt_crc8_fail;
+ u32 cnt_mcs_fail;
+ u32 cnt_ofdm_fail;
+ u32 cnt_ofdm_fail_pre; /* For RTL8881A */
+ u32 cnt_cck_fail;
+ u32 cnt_all;
+ u32 cnt_all_pre;
+ u32 cnt_fast_fsync;
+ u32 cnt_sb_search_fail;
+ u32 cnt_ofdm_cca;
+ u32 cnt_cck_cca;
+ u32 cnt_cca_all;
+ u32 cnt_bw_usc; /* Gary */
+ u32 cnt_bw_lsc; /* Gary */
+ u32 cnt_cck_crc32_error;
+ u32 cnt_cck_crc32_ok;
+ u32 cnt_ofdm_crc32_error;
+ u32 cnt_ofdm_crc32_ok;
+ u32 cnt_ht_crc32_error;
+ u32 cnt_ht_crc32_ok;
+ u32 cnt_vht_crc32_error;
+ u32 cnt_vht_crc32_ok;
+ u32 cnt_crc32_error_all;
+ u32 cnt_crc32_ok_all;
+ bool cck_block_enable;
+ bool ofdm_block_enable;
+ u32 dbg_port0;
+ bool edcca_flag;
+};
+
+enum dm_dig_op {
+ DIG_TYPE_THRESH_HIGH = 0,
+ DIG_TYPE_THRESH_LOW = 1,
+ DIG_TYPE_BACKOFF = 2,
+ DIG_TYPE_RX_GAIN_MIN = 3,
+ DIG_TYPE_RX_GAIN_MAX = 4,
+ DIG_TYPE_ENABLE = 5,
+ DIG_TYPE_DISABLE = 6,
+ DIG_OP_TYPE_MAX
+};
+
+enum phydm_pause_type { PHYDM_PAUSE = BIT(0), PHYDM_RESUME = BIT(1) };
+
+enum phydm_pause_level {
+ /* number of pause level can't exceed DM_DIG_MAX_PAUSE_TYPE */
+ PHYDM_PAUSE_LEVEL_0 = 0,
+ PHYDM_PAUSE_LEVEL_1 = 1,
+ PHYDM_PAUSE_LEVEL_2 = 2,
+ PHYDM_PAUSE_LEVEL_3 = 3,
+ PHYDM_PAUSE_LEVEL_4 = 4,
+ PHYDM_PAUSE_LEVEL_5 = 5,
+ PHYDM_PAUSE_LEVEL_6 = 6,
+ PHYDM_PAUSE_LEVEL_7 = DM_DIG_MAX_PAUSE_TYPE /* maximum level */
+};
+
+#define DM_DIG_THRESH_HIGH 40
+#define DM_DIG_THRESH_LOW 35
+
+#define DM_FALSEALARM_THRESH_LOW 400
+#define DM_FALSEALARM_THRESH_HIGH 1000
+
+#define DM_DIG_MAX_NIC 0x3e
+#define DM_DIG_MIN_NIC 0x20
+#define DM_DIG_MAX_OF_MIN_NIC 0x3e
+
+#define DM_DIG_MAX_AP 0x3e
+#define DM_DIG_MIN_AP 0x20
+#define DM_DIG_MAX_OF_MIN 0x2A /* 0x32 */
+#define DM_DIG_MIN_AP_DFS 0x20
+
+#define DM_DIG_MAX_NIC_HP 0x46
+#define DM_DIG_MIN_NIC_HP 0x2e
+
+#define DM_DIG_MAX_AP_HP 0x42
+#define DM_DIG_MIN_AP_HP 0x30
+
+/* vivi 92c&92d has different definition, 20110504
+ * this is for 92c
+ */
+#define DM_DIG_FA_TH0 0x200 /* 0x20 */
+
+#define DM_DIG_FA_TH1 0x300
+#define DM_DIG_FA_TH2 0x400
+/* this is for 92d */
+#define DM_DIG_FA_TH0_92D 0x100
+#define DM_DIG_FA_TH1_92D 0x400
+#define DM_DIG_FA_TH2_92D 0x600
+
+#define DM_DIG_BACKOFF_MAX 12
+#define DM_DIG_BACKOFF_MIN -4
+#define DM_DIG_BACKOFF_DEFAULT 10
+
+#define DM_DIG_FA_TH0_LPS 4 /* -> 4 in lps */
+#define DM_DIG_FA_TH1_LPS 15 /* -> 15 lps */
+#define DM_DIG_FA_TH2_LPS 30 /* -> 30 lps */
+#define RSSI_OFFSET_DIG 0x05
+#define LARGE_FA_TIMEOUT 60
+
+void odm_change_dynamic_init_gain_thresh(void *dm_void, u32 dm_type,
+ u32 dm_value);
+
+void odm_write_dig(void *dm_void, u8 current_igi);
+
+void odm_pause_dig(void *dm_void, enum phydm_pause_type pause_type,
+ enum phydm_pause_level pause_level, u8 igi_value);
+
+void odm_dig_init(void *dm_void);
+
+void odm_DIG(void *dm_void);
+
+void odm_dig_by_rssi_lps(void *dm_void);
+
+void odm_false_alarm_counter_statistics(void *dm_void);
+
+void odm_pause_cck_packet_detection(void *dm_void,
+ enum phydm_pause_type pause_type,
+ enum phydm_pause_level pause_level,
+ u8 cck_pd_threshold);
+
+void odm_cck_packet_detection_thresh(void *dm_void);
+
+void odm_write_cck_cca_thres(void *dm_void, u8 cur_cck_cca_thres);
+
+bool phydm_dig_go_up_check(void *dm_void);
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/phydm_dynamic_rx_path.h b/drivers/staging/rtlwifi/phydm/phydm_dynamic_rx_path.h
new file mode 100644
index 0000000..9f3cb24
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_dynamic_rx_path.h
@@ -0,0 +1,37 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __PHYDMDYMICRXPATH_H__
+#define __PHYDMDYMICRXPATH_H__
+
+#define DYNAMIC_RX_PATH_VERSION "1.0" /*2016.07.15 Dino */
+
+#define DRP_RSSI_TH 35
+
+#define INIT_DRP_TIMMER 0
+#define CANCEL_DRP_TIMMER 1
+#define RELEASE_DRP_TIMMER 2
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/phydm_dynamicbbpowersaving.c b/drivers/staging/rtlwifi/phydm/phydm_dynamicbbpowersaving.c
new file mode 100644
index 0000000..7661c49
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_dynamicbbpowersaving.c
@@ -0,0 +1,129 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+/* ************************************************************
+ * include files
+ * *************************************************************/
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+static inline void phydm_update_rf_state(struct phy_dm_struct *dm,
+ struct dyn_pwr_saving *dm_ps_table,
+ int _rssi_up_bound,
+ int _rssi_low_bound,
+ int _is_force_in_normal)
+{
+ if (_is_force_in_normal) {
+ dm_ps_table->cur_rf_state = rf_normal;
+ return;
+ }
+
+ if (dm->rssi_min == 0xFF) {
+ dm_ps_table->cur_rf_state = RF_MAX;
+ return;
+ }
+
+ if (dm_ps_table->pre_rf_state == rf_normal) {
+ if (dm->rssi_min >= _rssi_up_bound)
+ dm_ps_table->cur_rf_state = rf_save;
+ else
+ dm_ps_table->cur_rf_state = rf_normal;
+ } else {
+ if (dm->rssi_min <= _rssi_low_bound)
+ dm_ps_table->cur_rf_state = rf_normal;
+ else
+ dm_ps_table->cur_rf_state = rf_save;
+ }
+}
+
+void odm_dynamic_bb_power_saving_init(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct dyn_pwr_saving *dm_ps_table = &dm->dm_ps_table;
+
+ dm_ps_table->pre_cca_state = CCA_MAX;
+ dm_ps_table->cur_cca_state = CCA_MAX;
+ dm_ps_table->pre_rf_state = RF_MAX;
+ dm_ps_table->cur_rf_state = RF_MAX;
+ dm_ps_table->rssi_val_min = 0;
+ dm_ps_table->initialize = 0;
+}
+
+void odm_rf_saving(void *dm_void, u8 is_force_in_normal)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct dyn_pwr_saving *dm_ps_table = &dm->dm_ps_table;
+ u8 rssi_up_bound = 30;
+ u8 rssi_low_bound = 25;
+
+ if (dm->patch_id == 40) { /* RT_CID_819x_FUNAI_TV */
+ rssi_up_bound = 50;
+ rssi_low_bound = 45;
+ }
+ if (dm_ps_table->initialize == 0) {
+ dm_ps_table->reg874 =
+ (odm_get_bb_reg(dm, 0x874, MASKDWORD) & 0x1CC000) >> 14;
+ dm_ps_table->regc70 =
+ (odm_get_bb_reg(dm, 0xc70, MASKDWORD) & BIT(3)) >> 3;
+ dm_ps_table->reg85c =
+ (odm_get_bb_reg(dm, 0x85c, MASKDWORD) & 0xFF000000) >>
+ 24;
+ dm_ps_table->rega74 =
+ (odm_get_bb_reg(dm, 0xa74, MASKDWORD) & 0xF000) >> 12;
+ /* Reg818 = phy_query_bb_reg(adapter, 0x818, MASKDWORD); */
+ dm_ps_table->initialize = 1;
+ }
+
+ phydm_update_rf_state(dm, dm_ps_table, rssi_up_bound, rssi_low_bound,
+ is_force_in_normal);
+
+ if (dm_ps_table->pre_rf_state != dm_ps_table->cur_rf_state) {
+ if (dm_ps_table->cur_rf_state == rf_save) {
+ odm_set_bb_reg(dm, 0x874, 0x1C0000,
+ 0x2); /* reg874[20:18]=3'b010 */
+ odm_set_bb_reg(dm, 0xc70, BIT(3),
+ 0); /* regc70[3]=1'b0 */
+ odm_set_bb_reg(dm, 0x85c, 0xFF000000,
+ 0x63); /* reg85c[31:24]=0x63 */
+ odm_set_bb_reg(dm, 0x874, 0xC000,
+ 0x2); /* reg874[15:14]=2'b10 */
+ odm_set_bb_reg(dm, 0xa74, 0xF000,
+ 0x3); /* RegA75[7:4]=0x3 */
+ odm_set_bb_reg(dm, 0x818, BIT(28),
+ 0x0); /* Reg818[28]=1'b0 */
+ odm_set_bb_reg(dm, 0x818, BIT(28),
+ 0x1); /* Reg818[28]=1'b1 */
+ } else {
+ odm_set_bb_reg(dm, 0x874, 0x1CC000,
+ dm_ps_table->reg874);
+ odm_set_bb_reg(dm, 0xc70, BIT(3), dm_ps_table->regc70);
+ odm_set_bb_reg(dm, 0x85c, 0xFF000000,
+ dm_ps_table->reg85c);
+ odm_set_bb_reg(dm, 0xa74, 0xF000, dm_ps_table->rega74);
+ odm_set_bb_reg(dm, 0x818, BIT(28), 0x0);
+ }
+ dm_ps_table->pre_rf_state = dm_ps_table->cur_rf_state;
+ }
+}
diff --git a/drivers/staging/rtlwifi/phydm/phydm_dynamicbbpowersaving.h b/drivers/staging/rtlwifi/phydm/phydm_dynamicbbpowersaving.h
new file mode 100644
index 0000000..e7394c4
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_dynamicbbpowersaving.h
@@ -0,0 +1,50 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __PHYDMDYNAMICBBPOWERSAVING_H__
+#define __PHYDMDYNAMICBBPOWERSAVING_H__
+
+#define DYNAMIC_BBPWRSAV_VERSION "1.1"
+
+struct dyn_pwr_saving {
+ u8 pre_cca_state;
+ u8 cur_cca_state;
+
+ u8 pre_rf_state;
+ u8 cur_rf_state;
+
+ int rssi_val_min;
+
+ u8 initialize;
+ u32 reg874, regc70, reg85c, rega74;
+};
+
+#define dm_rf_saving odm_rf_saving
+
+void odm_rf_saving(void *dm_void, u8 is_force_in_normal);
+
+void odm_dynamic_bb_power_saving_init(void *dm_void);
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/phydm_dynamictxpower.c b/drivers/staging/rtlwifi/phydm/phydm_dynamictxpower.c
new file mode 100644
index 0000000..ebb4334
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_dynamictxpower.c
@@ -0,0 +1,102 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+/* ************************************************************
+ * include files
+ * *************************************************************/
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+void odm_dynamic_tx_power_init(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ dm->last_dtp_lvl = tx_high_pwr_level_normal;
+ dm->dynamic_tx_high_power_lvl = tx_high_pwr_level_normal;
+ dm->tx_agc_ofdm_18_6 =
+ odm_get_bb_reg(dm, 0xC24, MASKDWORD); /*TXAGC {18M 12M 9M 6M}*/
+}
+
+void odm_dynamic_tx_power_save_power_index(void *dm_void) {}
+
+void odm_dynamic_tx_power_restore_power_index(void *dm_void) {}
+
+void odm_dynamic_tx_power_write_power_index(void *dm_void, u8 value)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u8 index;
+ u32 power_index_reg[6] = {0xc90, 0xc91, 0xc92, 0xc98, 0xc99, 0xc9a};
+
+ for (index = 0; index < 6; index++)
+ odm_write_1byte(dm, power_index_reg[index], value);
+}
+
+static void odm_dynamic_tx_power_nic_ce(void *dm_void) {}
+
+void odm_dynamic_tx_power(void *dm_void)
+{
+ /* */
+ /* For AP/ADSL use struct rtl8192cd_priv* */
+ /* For CE/NIC use struct void* */
+ /* */
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ if (!(dm->support_ability & ODM_BB_DYNAMIC_TXPWR))
+ return;
+ /* 2011/09/29 MH In HW integration first stage, we provide 4 different
+ * handle to operate at the same time.
+ * In the stage2/3, we need to prive universal interface and merge all
+ * HW dynamic mechanism.
+ */
+ switch (dm->support_platform) {
+ case ODM_WIN:
+ odm_dynamic_tx_power_nic(dm);
+ break;
+ case ODM_CE:
+ odm_dynamic_tx_power_nic_ce(dm);
+ break;
+ case ODM_AP:
+ odm_dynamic_tx_power_ap(dm);
+ break;
+ default:
+ break;
+ }
+}
+
+void odm_dynamic_tx_power_nic(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ if (!(dm->support_ability & ODM_BB_DYNAMIC_TXPWR))
+ return;
+}
+
+void odm_dynamic_tx_power_ap(void *dm_void
+
+ )
+{
+}
+
+void odm_dynamic_tx_power_8821(void *dm_void, u8 *desc, u8 mac_id) {}
diff --git a/drivers/staging/rtlwifi/phydm/phydm_dynamictxpower.h b/drivers/staging/rtlwifi/phydm/phydm_dynamictxpower.h
new file mode 100644
index 0000000..10bad12
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_dynamictxpower.h
@@ -0,0 +1,64 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __PHYDMDYNAMICTXPOWER_H__
+#define __PHYDMDYNAMICTXPOWER_H__
+
+/*#define DYNAMIC_TXPWR_VERSION "1.0"*/
+/*#define DYNAMIC_TXPWR_VERSION "1.3" */ /*2015.08.26, Add 8814 Dynamic TX pwr*/
+#define DYNAMIC_TXPWR_VERSION "1.4" /*2015.11.06,Add CE 8821A Dynamic TX pwr*/
+
+#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74
+#define TX_POWER_NEAR_FIELD_THRESH_LVL1 60
+
+#define tx_high_pwr_level_normal 0
+#define tx_high_pwr_level_level1 1
+#define tx_high_pwr_level_level2 2
+
+#define tx_high_pwr_level_bt1 3
+#define tx_high_pwr_level_bt2 4
+#define tx_high_pwr_level_15 5
+#define tx_high_pwr_level_35 6
+#define tx_high_pwr_level_50 7
+#define tx_high_pwr_level_70 8
+#define tx_high_pwr_level_100 9
+
+void odm_dynamic_tx_power_init(void *dm_void);
+
+void odm_dynamic_tx_power_restore_power_index(void *dm_void);
+
+void odm_dynamic_tx_power_nic(void *dm_void);
+
+void odm_dynamic_tx_power_save_power_index(void *dm_void);
+
+void odm_dynamic_tx_power_write_power_index(void *dm_void, u8 value);
+
+void odm_dynamic_tx_power_8821(void *dm_void, u8 *desc, u8 mac_id);
+
+void odm_dynamic_tx_power(void *dm_void);
+
+void odm_dynamic_tx_power_ap(void *dm_void);
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/phydm_edcaturbocheck.c b/drivers/staging/rtlwifi/phydm/phydm_edcaturbocheck.c
new file mode 100644
index 0000000..753a9b98
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_edcaturbocheck.c
@@ -0,0 +1,139 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+/* ************************************************************
+ * include files
+ * *************************************************************/
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+void odm_edca_turbo_init(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ dm->dm_edca_table.is_current_turbo_edca = false;
+ dm->dm_edca_table.is_cur_rdl_state = false;
+
+ ODM_RT_TRACE(dm, ODM_COMP_EDCA_TURBO, "Orginial VO PARAM: 0x%x\n",
+ odm_read_4byte(dm, ODM_EDCA_VO_PARAM));
+ ODM_RT_TRACE(dm, ODM_COMP_EDCA_TURBO, "Orginial VI PARAM: 0x%x\n",
+ odm_read_4byte(dm, ODM_EDCA_VI_PARAM));
+ ODM_RT_TRACE(dm, ODM_COMP_EDCA_TURBO, "Orginial BE PARAM: 0x%x\n",
+ odm_read_4byte(dm, ODM_EDCA_BE_PARAM));
+ ODM_RT_TRACE(dm, ODM_COMP_EDCA_TURBO, "Orginial BK PARAM: 0x%x\n",
+ odm_read_4byte(dm, ODM_EDCA_BK_PARAM));
+
+} /* ODM_InitEdcaTurbo */
+
+void odm_edca_turbo_check(void *dm_void)
+{
+ /* For AP/ADSL use struct rtl8192cd_priv* */
+ /* For CE/NIC use struct void* */
+
+ /* 2011/09/29 MH In HW integration first stage, we provide 4 different
+ * handle to operate at the same time.
+ * In the stage2/3, we need to prive universal interface and merge all
+ * HW dynamic mechanism.
+ */
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ ODM_RT_TRACE(dm, ODM_COMP_EDCA_TURBO,
+ "%s========================>\n", __func__);
+
+ if (!(dm->support_ability & ODM_MAC_EDCA_TURBO))
+ return;
+
+ switch (dm->support_platform) {
+ case ODM_WIN:
+
+ break;
+
+ case ODM_CE:
+ odm_edca_turbo_check_ce(dm);
+ break;
+ }
+ ODM_RT_TRACE(dm, ODM_COMP_EDCA_TURBO,
+ "<========================%s\n", __func__);
+
+} /* odm_CheckEdcaTurbo */
+
+void odm_edca_turbo_check_ce(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
+ u64 cur_txok_cnt = 0;
+ u64 cur_rxok_cnt = 0;
+ u32 edca_be_ul = 0x5ea42b;
+ u32 edca_be_dl = 0x5ea42b;
+ u32 edca_be = 0x5ea42b;
+ bool is_cur_rdlstate;
+ bool edca_turbo_on = false;
+
+ if (dm->wifi_test)
+ return;
+
+ if (!dm->is_linked) {
+ rtlpriv->dm.is_any_nonbepkts = false;
+ return;
+ }
+
+ if (rtlpriv->dm.dbginfo.num_non_be_pkt > 0x100)
+ rtlpriv->dm.is_any_nonbepkts = true;
+ rtlpriv->dm.dbginfo.num_non_be_pkt = 0;
+
+ cur_txok_cnt = rtlpriv->stats.txbytesunicast_inperiod;
+ cur_rxok_cnt = rtlpriv->stats.rxbytesunicast_inperiod;
+
+ /*b_bias_on_rx = false;*/
+ edca_turbo_on = ((!rtlpriv->dm.is_any_nonbepkts) &&
+ (!rtlpriv->dm.disable_framebursting)) ?
+ true :
+ false;
+
+ if (rtlpriv->mac80211.mode == WIRELESS_MODE_B)
+ goto label_exit;
+
+ if (edca_turbo_on) {
+ is_cur_rdlstate =
+ (cur_rxok_cnt > cur_txok_cnt * 4) ? true : false;
+
+ edca_be = is_cur_rdlstate ? edca_be_dl : edca_be_ul;
+ rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM_8822B, edca_be);
+ rtlpriv->dm.is_cur_rdlstate = is_cur_rdlstate;
+ rtlpriv->dm.current_turbo_edca = true;
+ } else {
+ if (rtlpriv->dm.current_turbo_edca) {
+ u8 tmp = AC0_BE;
+
+ rtlpriv->cfg->ops->set_hw_reg(rtlpriv->hw,
+ HW_VAR_AC_PARAM,
+ (u8 *)(&tmp));
+ rtlpriv->dm.current_turbo_edca = false;
+ }
+ }
+
+label_exit:
+ rtlpriv->dm.is_any_nonbepkts = false;
+}
diff --git a/drivers/staging/rtlwifi/phydm/phydm_edcaturbocheck.h b/drivers/staging/rtlwifi/phydm/phydm_edcaturbocheck.h
new file mode 100644
index 0000000..5845b10
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_edcaturbocheck.h
@@ -0,0 +1,44 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __PHYDMEDCATURBOCHECK_H__
+#define __PHYDMEDCATURBOCHECK_H__
+
+/*#define EDCATURBO_VERSION "2.1"*/
+#define EDCATURBO_VERSION "2.3" /*2015.07.29 by YuChen*/
+
+struct edca_turbo {
+ bool is_current_turbo_edca;
+ bool is_cur_rdl_state;
+
+ u32 prv_traffic_idx; /* edca turbo */
+};
+
+void odm_edca_turbo_check(void *dm_void);
+void odm_edca_turbo_init(void *dm_void);
+
+void odm_edca_turbo_check_ce(void *dm_void);
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/phydm_features.h b/drivers/staging/rtlwifi/phydm/phydm_features.h
new file mode 100644
index 0000000..37f6f0c
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_features.h
@@ -0,0 +1,33 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __PHYDM_FEATURES_H__
+#define __PHYDM_FEATURES
+
+/*phydm debyg report & tools*/
+
+/*Antenna Diversity*/
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/phydm_hwconfig.c b/drivers/staging/rtlwifi/phydm/phydm_hwconfig.c
new file mode 100644
index 0000000..0a1f11a
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_hwconfig.c
@@ -0,0 +1,1928 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+/* ************************************************************
+ * include files
+ * *************************************************************/
+
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+#define READ_AND_CONFIG_MP(ic, txt) (odm_read_and_config_mp_##ic##txt(dm))
+#define READ_AND_CONFIG_TC(ic, txt) (odm_read_and_config_tc_##ic##txt(dm))
+
+#define READ_AND_CONFIG READ_AND_CONFIG_MP
+
+#define READ_FIRMWARE_MP(ic, txt) \
+ (odm_read_firmware_mp_##ic##txt(dm, p_firmware, size))
+#define READ_FIRMWARE_TC(ic, txt) \
+ (odm_read_firmware_tc_##ic##txt(dm, p_firmware, size))
+
+#define READ_FIRMWARE READ_FIRMWARE_MP
+
+#define GET_VERSION_MP(ic, txt) (odm_get_version_mp_##ic##txt())
+#define GET_VERSION_TC(ic, txt) (odm_get_version_tc_##ic##txt())
+
+#define GET_VERSION(ic, txt) GET_VERSION_MP(ic, txt)
+
+static u32 phydm_process_rssi_pwdb(struct phy_dm_struct *dm,
+ struct rtl_sta_info *entry,
+ struct dm_per_pkt_info *pktinfo,
+ u32 undecorated_smoothed_ofdm,
+ u32 undecorated_smoothed_cck)
+{
+ u32 weighting = 0, undecorated_smoothed_pwdb;
+ /* 2011.07.28 LukeLee: modified to prevent unstable CCK RSSI */
+
+ if (entry->rssi_stat.ofdm_pkt ==
+ 64) { /* speed up when all packets are OFDM*/
+ undecorated_smoothed_pwdb = undecorated_smoothed_ofdm;
+ ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
+ "PWDB_0[%d] = (( %d ))\n", pktinfo->station_id,
+ undecorated_smoothed_cck);
+ } else {
+ if (entry->rssi_stat.valid_bit < 64)
+ entry->rssi_stat.valid_bit++;
+
+ if (entry->rssi_stat.valid_bit == 64) {
+ weighting = ((entry->rssi_stat.ofdm_pkt) > 4) ?
+ 64 :
+ (entry->rssi_stat.ofdm_pkt << 4);
+ undecorated_smoothed_pwdb =
+ (weighting * undecorated_smoothed_ofdm +
+ (64 - weighting) * undecorated_smoothed_cck) >>
+ 6;
+ ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
+ "PWDB_1[%d] = (( %d )), W = (( %d ))\n",
+ pktinfo->station_id,
+ undecorated_smoothed_cck, weighting);
+ } else {
+ if (entry->rssi_stat.valid_bit != 0)
+ undecorated_smoothed_pwdb =
+ (entry->rssi_stat.ofdm_pkt *
+ undecorated_smoothed_ofdm +
+ (entry->rssi_stat.valid_bit -
+ entry->rssi_stat.ofdm_pkt) *
+ undecorated_smoothed_cck) /
+ entry->rssi_stat.valid_bit;
+ else
+ undecorated_smoothed_pwdb = 0;
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_RSSI_MONITOR,
+ "PWDB_2[%d] = (( %d )), ofdm_pkt = (( %d )), Valid_Bit = (( %d ))\n",
+ pktinfo->station_id, undecorated_smoothed_cck,
+ entry->rssi_stat.ofdm_pkt,
+ entry->rssi_stat.valid_bit);
+ }
+ }
+
+ return undecorated_smoothed_pwdb;
+}
+
+static u32 phydm_process_rssi_cck(struct phy_dm_struct *dm,
+ struct dm_phy_status_info *phy_info,
+ struct rtl_sta_info *entry,
+ u32 undecorated_smoothed_cck)
+{
+ u32 rssi_ave;
+ u8 i;
+
+ rssi_ave = phy_info->rx_pwdb_all;
+ dm->rssi_a = (u8)phy_info->rx_pwdb_all;
+ dm->rssi_b = 0xFF;
+ dm->rssi_c = 0xFF;
+ dm->rssi_d = 0xFF;
+
+ if (entry->rssi_stat.cck_pkt <= 63)
+ entry->rssi_stat.cck_pkt++;
+
+ /* 1 Process CCK RSSI */
+ if (undecorated_smoothed_cck <= 0) { /* initialize */
+ undecorated_smoothed_cck = phy_info->rx_pwdb_all;
+ entry->rssi_stat.cck_sum_power =
+ (u16)phy_info->rx_pwdb_all; /*reset*/
+ entry->rssi_stat.cck_pkt = 1; /*reset*/
+ ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, "CCK_INIT: (( %d ))\n",
+ undecorated_smoothed_cck);
+ } else if (entry->rssi_stat.cck_pkt <= CCK_RSSI_INIT_COUNT) {
+ entry->rssi_stat.cck_sum_power =
+ entry->rssi_stat.cck_sum_power +
+ (u16)phy_info->rx_pwdb_all;
+ undecorated_smoothed_cck = entry->rssi_stat.cck_sum_power /
+ entry->rssi_stat.cck_pkt;
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_RSSI_MONITOR,
+ "CCK_0: (( %d )), SumPow = (( %d )), cck_pkt = (( %d ))\n",
+ undecorated_smoothed_cck,
+ entry->rssi_stat.cck_sum_power,
+ entry->rssi_stat.cck_pkt);
+ } else {
+ if (phy_info->rx_pwdb_all > (u32)undecorated_smoothed_cck) {
+ undecorated_smoothed_cck =
+ (((undecorated_smoothed_cck) *
+ (RX_SMOOTH_FACTOR - 1)) +
+ (phy_info->rx_pwdb_all)) /
+ (RX_SMOOTH_FACTOR);
+ undecorated_smoothed_cck = undecorated_smoothed_cck + 1;
+ ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
+ "CCK_1: (( %d ))\n",
+ undecorated_smoothed_cck);
+ } else {
+ undecorated_smoothed_cck =
+ (((undecorated_smoothed_cck) *
+ (RX_SMOOTH_FACTOR - 1)) +
+ (phy_info->rx_pwdb_all)) /
+ (RX_SMOOTH_FACTOR);
+ ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
+ "CCK_2: (( %d ))\n",
+ undecorated_smoothed_cck);
+ }
+ }
+
+ i = 63;
+ entry->rssi_stat.ofdm_pkt -=
+ (u8)((entry->rssi_stat.packet_map >> i) & BIT(0));
+ entry->rssi_stat.packet_map = entry->rssi_stat.packet_map << 1;
+ return undecorated_smoothed_cck;
+}
+
+static u32 phydm_process_rssi_ofdm(struct phy_dm_struct *dm,
+ struct dm_phy_status_info *phy_info,
+ struct rtl_sta_info *entry,
+ u32 undecorated_smoothed_ofdm)
+{
+ u32 rssi_ave;
+ u8 rssi_max, rssi_min, i;
+
+ if (dm->support_ic_type & (ODM_RTL8814A | ODM_RTL8822B)) {
+ u8 rx_count = 0;
+ u32 rssi_linear = 0;
+
+ if (dm->rx_ant_status & ODM_RF_A) {
+ dm->rssi_a = phy_info->rx_mimo_signal_strength
+ [ODM_RF_PATH_A];
+ rx_count++;
+ rssi_linear += odm_convert_to_linear(
+ phy_info->rx_mimo_signal_strength
+ [ODM_RF_PATH_A]);
+ } else {
+ dm->rssi_a = 0;
+ }
+
+ if (dm->rx_ant_status & ODM_RF_B) {
+ dm->rssi_b = phy_info->rx_mimo_signal_strength
+ [ODM_RF_PATH_B];
+ rx_count++;
+ rssi_linear += odm_convert_to_linear(
+ phy_info->rx_mimo_signal_strength
+ [ODM_RF_PATH_B]);
+ } else {
+ dm->rssi_b = 0;
+ }
+
+ if (dm->rx_ant_status & ODM_RF_C) {
+ dm->rssi_c = phy_info->rx_mimo_signal_strength
+ [ODM_RF_PATH_C];
+ rx_count++;
+ rssi_linear += odm_convert_to_linear(
+ phy_info->rx_mimo_signal_strength
+ [ODM_RF_PATH_C]);
+ } else {
+ dm->rssi_c = 0;
+ }
+
+ if (dm->rx_ant_status & ODM_RF_D) {
+ dm->rssi_d = phy_info->rx_mimo_signal_strength
+ [ODM_RF_PATH_D];
+ rx_count++;
+ rssi_linear += odm_convert_to_linear(
+ phy_info->rx_mimo_signal_strength
+ [ODM_RF_PATH_D]);
+ } else {
+ dm->rssi_d = 0;
+ }
+
+ /* Calculate average RSSI */
+ switch (rx_count) {
+ case 2:
+ rssi_linear = (rssi_linear >> 1);
+ break;
+ case 3:
+ /* rssi_linear/3 ~ rssi_linear*11/32 */
+ rssi_linear = ((rssi_linear) + (rssi_linear << 1) +
+ (rssi_linear << 3)) >>
+ 5;
+ break;
+ case 4:
+ rssi_linear = (rssi_linear >> 2);
+ break;
+ }
+
+ rssi_ave = odm_convert_to_db(rssi_linear);
+ } else {
+ if (phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B] == 0) {
+ rssi_ave = phy_info->rx_mimo_signal_strength
+ [ODM_RF_PATH_A];
+ dm->rssi_a = phy_info->rx_mimo_signal_strength
+ [ODM_RF_PATH_A];
+ dm->rssi_b = 0;
+ } else {
+ dm->rssi_a = phy_info->rx_mimo_signal_strength
+ [ODM_RF_PATH_A];
+ dm->rssi_b = phy_info->rx_mimo_signal_strength
+ [ODM_RF_PATH_B];
+
+ if (phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A] >
+ phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]) {
+ rssi_max = phy_info->rx_mimo_signal_strength
+ [ODM_RF_PATH_A];
+ rssi_min = phy_info->rx_mimo_signal_strength
+ [ODM_RF_PATH_B];
+ } else {
+ rssi_max = phy_info->rx_mimo_signal_strength
+ [ODM_RF_PATH_B];
+ rssi_min = phy_info->rx_mimo_signal_strength
+ [ODM_RF_PATH_A];
+ }
+ if ((rssi_max - rssi_min) < 3)
+ rssi_ave = rssi_max;
+ else if ((rssi_max - rssi_min) < 6)
+ rssi_ave = rssi_max - 1;
+ else if ((rssi_max - rssi_min) < 10)
+ rssi_ave = rssi_max - 2;
+ else
+ rssi_ave = rssi_max - 3;
+ }
+ }
+
+ /* 1 Process OFDM RSSI */
+ if (undecorated_smoothed_ofdm <= 0) { /* initialize */
+ undecorated_smoothed_ofdm = phy_info->rx_pwdb_all;
+ ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, "OFDM_INIT: (( %d ))\n",
+ undecorated_smoothed_ofdm);
+ } else {
+ if (phy_info->rx_pwdb_all > (u32)undecorated_smoothed_ofdm) {
+ undecorated_smoothed_ofdm =
+ (((undecorated_smoothed_ofdm) *
+ (RX_SMOOTH_FACTOR - 1)) +
+ (rssi_ave)) /
+ (RX_SMOOTH_FACTOR);
+ undecorated_smoothed_ofdm =
+ undecorated_smoothed_ofdm + 1;
+ ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
+ "OFDM_1: (( %d ))\n",
+ undecorated_smoothed_ofdm);
+ } else {
+ undecorated_smoothed_ofdm =
+ (((undecorated_smoothed_ofdm) *
+ (RX_SMOOTH_FACTOR - 1)) +
+ (rssi_ave)) /
+ (RX_SMOOTH_FACTOR);
+ ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
+ "OFDM_2: (( %d ))\n",
+ undecorated_smoothed_ofdm);
+ }
+ }
+
+ if (entry->rssi_stat.ofdm_pkt != 64) {
+ i = 63;
+ entry->rssi_stat.ofdm_pkt -=
+ (u8)(((entry->rssi_stat.packet_map >> i) & BIT(0)) - 1);
+ }
+
+ entry->rssi_stat.packet_map =
+ (entry->rssi_stat.packet_map << 1) | BIT(0);
+ return undecorated_smoothed_ofdm;
+}
+
+static u8 odm_evm_db_to_percentage(s8);
+static u8 odm_evm_dbm_jaguar_series(s8);
+
+static inline u32 phydm_get_rssi_average(struct phy_dm_struct *dm,
+ struct dm_phy_status_info *phy_info)
+{
+ u8 rssi_max = 0, rssi_min = 0;
+
+ dm->rssi_a = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A];
+ dm->rssi_b = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B];
+
+ if (phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A] >
+ phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]) {
+ rssi_max = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A];
+ rssi_min = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B];
+ } else {
+ rssi_max = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B];
+ rssi_min = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A];
+ }
+ if ((rssi_max - rssi_min) < 3)
+ return rssi_max;
+ else if ((rssi_max - rssi_min) < 6)
+ return rssi_max - 1;
+ else if ((rssi_max - rssi_min) < 10)
+ return rssi_max - 2;
+ else
+ return rssi_max - 3;
+}
+
+static inline u8 phydm_get_evm_dbm(u8 i, u8 EVM,
+ struct phy_status_rpt_8812 *phy_sta_rpt,
+ struct dm_phy_status_info *phy_info)
+{
+ if (i < ODM_RF_PATH_C)
+ return odm_evm_dbm_jaguar_series(phy_sta_rpt->rxevm[i]);
+ else
+ return odm_evm_dbm_jaguar_series(phy_sta_rpt->rxevm_cd[i - 2]);
+ /*RT_DISP(FRX, RX_PHY_SQ, ("RXRATE=%x RXEVM=%x EVM=%s%d\n",*/
+ /*pktinfo->data_rate, phy_sta_rpt->rxevm[i], "%", EVM));*/
+}
+
+static inline u8 phydm_get_odm_evm(u8 i, struct dm_per_pkt_info *pktinfo,
+ struct phy_status_rpt_8812 *phy_sta_rpt)
+{
+ u8 evm = 0;
+
+ if (pktinfo->data_rate >= ODM_RATE6M &&
+ pktinfo->data_rate <= ODM_RATE54M) {
+ if (i == ODM_RF_PATH_A) {
+ evm = odm_evm_db_to_percentage(
+ (phy_sta_rpt->sigevm)); /*dbm*/
+ evm += 20;
+ if (evm > 100)
+ evm = 100;
+ }
+ } else {
+ if (i < ODM_RF_PATH_C) {
+ if (phy_sta_rpt->rxevm[i] == -128)
+ phy_sta_rpt->rxevm[i] = -25;
+ evm = odm_evm_db_to_percentage(
+ (phy_sta_rpt->rxevm[i])); /*dbm*/
+ } else {
+ if (phy_sta_rpt->rxevm_cd[i - 2] == -128)
+ phy_sta_rpt->rxevm_cd[i - 2] = -25;
+ evm = odm_evm_db_to_percentage(
+ (phy_sta_rpt->rxevm_cd[i - 2])); /*dbm*/
+ }
+ }
+
+ return evm;
+}
+
+static inline s8 phydm_get_rx_pwr(u8 LNA_idx, u8 VGA_idx, u8 cck_highpwr)
+{
+ switch (LNA_idx) {
+ case 7:
+ if (VGA_idx <= 27)
+ return -100 + 2 * (27 - VGA_idx); /*VGA_idx = 27~2*/
+ else
+ return -100;
+ break;
+ case 6:
+ return -48 + 2 * (2 - VGA_idx); /*VGA_idx = 2~0*/
+ case 5:
+ return -42 + 2 * (7 - VGA_idx); /*VGA_idx = 7~5*/
+ case 4:
+ return -36 + 2 * (7 - VGA_idx); /*VGA_idx = 7~4*/
+ case 3:
+ return -24 + 2 * (7 - VGA_idx); /*VGA_idx = 7~0*/
+ case 2:
+ if (cck_highpwr)
+ return -12 + 2 * (5 - VGA_idx); /*VGA_idx = 5~0*/
+ else
+ return -6 + 2 * (5 - VGA_idx);
+ break;
+ case 1:
+ return 8 - 2 * VGA_idx;
+ case 0:
+ return 14 - 2 * VGA_idx;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static inline u8 phydm_adjust_pwdb(u8 cck_highpwr, u8 pwdb_all)
+{
+ if (!cck_highpwr) {
+ if (pwdb_all >= 80)
+ return ((pwdb_all - 80) << 1) + ((pwdb_all - 80) >> 1) +
+ 80;
+ else if ((pwdb_all <= 78) && (pwdb_all >= 20))
+ return pwdb_all + 3;
+ if (pwdb_all > 100)
+ return 100;
+ }
+ return pwdb_all;
+}
+
+static inline u8
+phydm_get_signal_quality_8812(struct dm_phy_status_info *phy_info,
+ struct phy_dm_struct *dm,
+ struct phy_status_rpt_8812 *phy_sta_rpt)
+{
+ u8 sq_rpt;
+
+ if (phy_info->rx_pwdb_all > 40 && !dm->is_in_hct_test)
+ return 100;
+
+ sq_rpt = phy_sta_rpt->pwdb_all;
+
+ if (sq_rpt > 64)
+ return 0;
+ else if (sq_rpt < 20)
+ return 100;
+ else
+ return ((64 - sq_rpt) * 100) / 44;
+}
+
+static inline u8
+phydm_get_signal_quality_8192(struct dm_phy_status_info *phy_info,
+ struct phy_dm_struct *dm,
+ struct phy_status_rpt_8192cd *phy_sta_rpt)
+{
+ u8 sq_rpt;
+
+ if (phy_info->rx_pwdb_all > 40 && !dm->is_in_hct_test)
+ return 100;
+
+ sq_rpt = phy_sta_rpt->cck_sig_qual_ofdm_pwdb_all;
+
+ if (sq_rpt > 64)
+ return 0;
+ else if (sq_rpt < 20)
+ return 100;
+ else
+ return ((64 - sq_rpt) * 100) / 44;
+}
+
+static u8 odm_query_rx_pwr_percentage(s8 ant_power)
+{
+ if ((ant_power <= -100) || (ant_power >= 20))
+ return 0;
+ else if (ant_power >= 0)
+ return 100;
+ else
+ return 100 + ant_power;
+}
+
+/*
+ * 2012/01/12 MH MOve some signal strength smooth method to MP HAL layer.
+ * IF other SW team do not support the feature, remove this section.??
+ */
+
+s32 odm_signal_scale_mapping(struct phy_dm_struct *dm, s32 curr_sig)
+{
+ {
+ return curr_sig;
+ }
+}
+
+static u8 odm_sq_process_patch_rt_cid_819x_lenovo(struct phy_dm_struct *dm,
+ u8 is_cck_rate, u8 pwdb_all,
+ u8 path, u8 RSSI)
+{
+ u8 sq = 0;
+ return sq;
+}
+
+static u8 odm_evm_db_to_percentage(s8 value)
+{
+ /* -33dB~0dB to 0%~99% */
+ s8 ret_val;
+
+ ret_val = value;
+ ret_val /= 2;
+
+ if (ret_val >= 0)
+ ret_val = 0;
+
+ if (ret_val <= -33)
+ ret_val = -33;
+
+ ret_val = 0 - ret_val;
+ ret_val *= 3;
+
+ if (ret_val == 99)
+ ret_val = 100;
+
+ return (u8)ret_val;
+}
+
+static u8 odm_evm_dbm_jaguar_series(s8 value)
+{
+ s8 ret_val = value;
+
+ /* -33dB~0dB to 33dB ~ 0dB */
+ if (ret_val == -128)
+ ret_val = 127;
+ else if (ret_val < 0)
+ ret_val = 0 - ret_val;
+
+ ret_val = ret_val >> 1;
+ return (u8)ret_val;
+}
+
+static s16 odm_cfo(s8 value)
+{
+ s16 ret_val;
+
+ if (value < 0) {
+ ret_val = 0 - value;
+ ret_val = (ret_val << 1) + (ret_val >> 1); /* *2.5~=312.5/2^7 */
+ ret_val =
+ ret_val | BIT(12); /* set bit12 as 1 for negative cfo */
+ } else {
+ ret_val = value;
+ ret_val = (ret_val << 1) + (ret_val >> 1); /* *2.5~=312.5/2^7 */
+ }
+ return ret_val;
+}
+
+static u8 phydm_rate_to_num_ss(struct phy_dm_struct *dm, u8 data_rate)
+{
+ u8 num_ss = 1;
+
+ if (data_rate <= ODM_RATE54M)
+ num_ss = 1;
+ else if (data_rate <= ODM_RATEMCS31)
+ num_ss = ((data_rate - ODM_RATEMCS0) >> 3) + 1;
+ else if (data_rate <= ODM_RATEVHTSS1MCS9)
+ num_ss = 1;
+ else if (data_rate <= ODM_RATEVHTSS2MCS9)
+ num_ss = 2;
+ else if (data_rate <= ODM_RATEVHTSS3MCS9)
+ num_ss = 3;
+ else if (data_rate <= ODM_RATEVHTSS4MCS9)
+ num_ss = 4;
+
+ return num_ss;
+}
+
+static void odm_rx_phy_status92c_series_parsing(
+ struct phy_dm_struct *dm, struct dm_phy_status_info *phy_info,
+ u8 *phy_status, struct dm_per_pkt_info *pktinfo)
+{
+ u8 i, max_spatial_stream;
+ s8 rx_pwr[4], rx_pwr_all = 0;
+ u8 EVM, pwdb_all = 0, pwdb_all_bt;
+ u8 RSSI, total_rssi = 0;
+ bool is_cck_rate = false;
+ u8 rf_rx_num = 0;
+ u8 LNA_idx = 0;
+ u8 VGA_idx = 0;
+ u8 cck_agc_rpt;
+ u8 num_ss;
+ struct phy_status_rpt_8192cd *phy_sta_rpt =
+ (struct phy_status_rpt_8192cd *)phy_status;
+
+ is_cck_rate = (pktinfo->data_rate <= ODM_RATE11M) ? true : false;
+
+ if (pktinfo->is_to_self)
+ dm->curr_station_id = pktinfo->station_id;
+
+ phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = -1;
+ phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1;
+
+ if (is_cck_rate) {
+ dm->phy_dbg_info.num_qry_phy_status_cck++;
+ cck_agc_rpt = phy_sta_rpt->cck_agc_rpt_ofdm_cfosho_a;
+
+ if (dm->support_ic_type & (ODM_RTL8703B)) {
+ } else { /*3 bit LNA*/
+
+ LNA_idx = ((cck_agc_rpt & 0xE0) >> 5);
+ VGA_idx = (cck_agc_rpt & 0x1F);
+ }
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_RSSI_MONITOR,
+ "ext_lna_gain (( %d )), LNA_idx: (( 0x%x )), VGA_idx: (( 0x%x )), rx_pwr_all: (( %d ))\n",
+ dm->ext_lna_gain, LNA_idx, VGA_idx, rx_pwr_all);
+
+ if (dm->board_type & ODM_BOARD_EXT_LNA)
+ rx_pwr_all -= dm->ext_lna_gain;
+
+ pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
+
+ if (pktinfo->is_to_self) {
+ dm->cck_lna_idx = LNA_idx;
+ dm->cck_vga_idx = VGA_idx;
+ }
+ phy_info->rx_pwdb_all = pwdb_all;
+
+ phy_info->bt_rx_rssi_percentage = pwdb_all;
+ phy_info->recv_signal_power = rx_pwr_all;
+ /* (3) Get Signal Quality (EVM) */
+ {
+ u8 sq;
+
+ sq = phydm_get_signal_quality_8192(phy_info, dm,
+ phy_sta_rpt);
+ phy_info->signal_quality = sq;
+ phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = sq;
+ phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1;
+ }
+
+ for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX; i++) {
+ if (i == 0)
+ phy_info->rx_mimo_signal_strength[0] = pwdb_all;
+ else
+ phy_info->rx_mimo_signal_strength[1] = 0;
+ }
+ } else { /* 2 is OFDM rate */
+ dm->phy_dbg_info.num_qry_phy_status_ofdm++;
+
+ /* */
+ /* (1)Get RSSI for HT rate */
+ /* */
+
+ for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX; i++) {
+ /* 2008/01/30 MH we will judge RF RX path now. */
+ if (dm->rf_path_rx_enable & BIT(i))
+ rf_rx_num++;
+ /* else */
+ /* continue; */
+
+ rx_pwr[i] =
+ ((phy_sta_rpt->path_agc[i].gain & 0x3F) * 2) -
+ 110;
+
+ if (pktinfo->is_to_self) {
+ dm->ofdm_agc_idx[i] =
+ (phy_sta_rpt->path_agc[i].gain & 0x3F);
+ /**/
+ }
+
+ phy_info->rx_pwr[i] = rx_pwr[i];
+
+ /* Translate DBM to percentage. */
+ RSSI = odm_query_rx_pwr_percentage(rx_pwr[i]);
+ total_rssi += RSSI;
+
+ phy_info->rx_mimo_signal_strength[i] = (u8)RSSI;
+
+ /* Get Rx snr value in DB */
+ dm->phy_dbg_info.rx_snr_db[i] =
+ (s32)(phy_sta_rpt->path_rxsnr[i] / 2);
+ phy_info->rx_snr[i] = dm->phy_dbg_info.rx_snr_db[i];
+
+ /* Record Signal Strength for next packet */
+ /* if(pktinfo->is_packet_match_bssid) */
+ {
+ }
+ }
+
+ /* */
+ /* (2)PWDB, Average PWDB calcuated by hardware (for RA) */
+ /* */
+ rx_pwr_all = (((phy_sta_rpt->cck_sig_qual_ofdm_pwdb_all) >> 1) &
+ 0x7f) -
+ 110;
+
+ pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
+ pwdb_all_bt = pwdb_all;
+
+ phy_info->rx_pwdb_all = pwdb_all;
+ phy_info->bt_rx_rssi_percentage = pwdb_all_bt;
+ phy_info->rx_power = rx_pwr_all;
+ phy_info->recv_signal_power = rx_pwr_all;
+
+ if ((dm->support_platform == ODM_WIN) && (dm->patch_id == 19)) {
+ /* do nothing */
+ } else if ((dm->support_platform == ODM_WIN) &&
+ (dm->patch_id == 25)) {
+ /* do nothing */
+ } else { /* mgnt_info->customer_id != RT_CID_819X_LENOVO */
+ /* */
+ /* (3)EVM of HT rate */
+ /* */
+ if (pktinfo->data_rate >= ODM_RATEMCS8 &&
+ pktinfo->data_rate <= ODM_RATEMCS15) {
+ /* both spatial stream make sense */
+ max_spatial_stream = 2;
+ } else {
+ /* only spatial stream 1 makes sense */
+ max_spatial_stream = 1;
+ }
+
+ for (i = 0; i < max_spatial_stream; i++) {
+ /*Don't use shift operation like "rx_evmX >>= 1"
+ *because the compilor of free build environment
+ *fill most significant bit to "zero" when doing
+ *shifting operation which may change a negative
+ *value to positive one, then the dbm value
+ *(which is supposed to be negative) is not
+ *correct anymore.
+ */
+ EVM = odm_evm_db_to_percentage(
+ (phy_sta_rpt
+ ->stream_rxevm[i])); /* dbm */
+
+ /* Fill value in RFD, Get the first spatial
+ * stream only
+ */
+ if (i == ODM_RF_PATH_A)
+ phy_info->signal_quality =
+ (u8)(EVM & 0xff);
+ phy_info->rx_mimo_signal_quality[i] =
+ (u8)(EVM & 0xff);
+ }
+ }
+
+ num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate);
+ odm_parsing_cfo(dm, pktinfo, phy_sta_rpt->path_cfotail, num_ss);
+ }
+ /* UI BSS List signal strength(in percentage), make it good looking,
+ * from 0~100.
+ */
+ /* It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp(). */
+ if (is_cck_rate) {
+ phy_info->signal_strength = (u8)(
+ odm_signal_scale_mapping(dm, pwdb_all)); /*pwdb_all;*/
+ } else {
+ if (rf_rx_num != 0) {
+ phy_info->signal_strength =
+ (u8)(odm_signal_scale_mapping(dm, total_rssi /=
+ rf_rx_num));
+ }
+ }
+
+ /* For 92C/92D HW (Hybrid) Antenna Diversity */
+}
+
+static void
+odm_rx_phy_bw_jaguar_series_parsing(struct dm_phy_status_info *phy_info,
+ struct dm_per_pkt_info *pktinfo,
+ struct phy_status_rpt_8812 *phy_sta_rpt)
+{
+ if (pktinfo->data_rate <= ODM_RATE54M) {
+ switch (phy_sta_rpt->r_RFMOD) {
+ case 1:
+ if (phy_sta_rpt->sub_chnl == 0)
+ phy_info->band_width = 1;
+ else
+ phy_info->band_width = 0;
+ break;
+
+ case 2:
+ if (phy_sta_rpt->sub_chnl == 0)
+ phy_info->band_width = 2;
+ else if (phy_sta_rpt->sub_chnl == 9 ||
+ phy_sta_rpt->sub_chnl == 10)
+ phy_info->band_width = 1;
+ else
+ phy_info->band_width = 0;
+ break;
+
+ default:
+ case 0:
+ phy_info->band_width = 0;
+ break;
+ }
+ }
+}
+
+static void odm_rx_phy_status_jaguar_series_parsing(
+ struct phy_dm_struct *dm, struct dm_phy_status_info *phy_info,
+ u8 *phy_status, struct dm_per_pkt_info *pktinfo)
+{
+ u8 i, max_spatial_stream;
+ s8 rx_pwr[4], rx_pwr_all = 0;
+ u8 EVM = 0, evm_dbm, pwdb_all = 0, pwdb_all_bt;
+ u8 RSSI, avg_rssi = 0, best_rssi = 0, second_rssi = 0;
+ u8 is_cck_rate = 0;
+ u8 rf_rx_num = 0;
+ u8 cck_highpwr = 0;
+ u8 LNA_idx, VGA_idx;
+ struct phy_status_rpt_8812 *phy_sta_rpt =
+ (struct phy_status_rpt_8812 *)phy_status;
+ struct fast_antenna_training *fat_tab = &dm->dm_fat_table;
+ u8 num_ss;
+
+ odm_rx_phy_bw_jaguar_series_parsing(phy_info, pktinfo, phy_sta_rpt);
+
+ if (pktinfo->data_rate <= ODM_RATE11M)
+ is_cck_rate = true;
+ else
+ is_cck_rate = false;
+
+ if (pktinfo->is_to_self)
+ dm->curr_station_id = pktinfo->station_id;
+ else
+ dm->curr_station_id = 0xff;
+
+ phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = -1;
+ phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1;
+ phy_info->rx_mimo_signal_quality[ODM_RF_PATH_C] = -1;
+ phy_info->rx_mimo_signal_quality[ODM_RF_PATH_D] = -1;
+
+ if (is_cck_rate) {
+ u8 cck_agc_rpt;
+
+ dm->phy_dbg_info.num_qry_phy_status_cck++;
+
+ /*(1)Hardware does not provide RSSI for CCK*/
+ /*(2)PWDB, Average PWDB calculated by hardware (for RA)*/
+
+ cck_highpwr = dm->is_cck_high_power;
+
+ cck_agc_rpt = phy_sta_rpt->cfosho[0];
+ LNA_idx = ((cck_agc_rpt & 0xE0) >> 5);
+ VGA_idx = (cck_agc_rpt & 0x1F);
+
+ if (dm->support_ic_type == ODM_RTL8812) {
+ rx_pwr_all =
+ phydm_get_rx_pwr(LNA_idx, VGA_idx, cck_highpwr);
+ rx_pwr_all += 6;
+ pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
+ pwdb_all = phydm_adjust_pwdb(cck_highpwr, pwdb_all);
+
+ } else if (dm->support_ic_type & (ODM_RTL8821 | ODM_RTL8881A)) {
+ s8 pout = -6;
+
+ switch (LNA_idx) {
+ case 5:
+ rx_pwr_all = pout - 32 - (2 * VGA_idx);
+ break;
+ case 4:
+ rx_pwr_all = pout - 24 - (2 * VGA_idx);
+ break;
+ case 2:
+ rx_pwr_all = pout - 11 - (2 * VGA_idx);
+ break;
+ case 1:
+ rx_pwr_all = pout + 5 - (2 * VGA_idx);
+ break;
+ case 0:
+ rx_pwr_all = pout + 21 - (2 * VGA_idx);
+ break;
+ }
+ pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
+ } else if (dm->support_ic_type == ODM_RTL8814A ||
+ dm->support_ic_type == ODM_RTL8822B) {
+ s8 pout = -6;
+
+ switch (LNA_idx) {
+ /*CCK only use LNA: 2, 3, 5, 7*/
+ case 7:
+ rx_pwr_all = pout - 32 - (2 * VGA_idx);
+ break;
+ case 5:
+ rx_pwr_all = pout - 22 - (2 * VGA_idx);
+ break;
+ case 3:
+ rx_pwr_all = pout - 2 - (2 * VGA_idx);
+ break;
+ case 2:
+ rx_pwr_all = pout + 5 - (2 * VGA_idx);
+ break;
+ default:
+ break;
+ }
+ pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
+ }
+
+ dm->cck_lna_idx = LNA_idx;
+ dm->cck_vga_idx = VGA_idx;
+ phy_info->rx_pwdb_all = pwdb_all;
+ phy_info->bt_rx_rssi_percentage = pwdb_all;
+ phy_info->recv_signal_power = rx_pwr_all;
+ /*(3) Get Signal Quality (EVM)*/
+ {
+ u8 sq;
+
+ if ((dm->support_platform == ODM_WIN) &&
+ (dm->patch_id == RT_CID_819X_LENOVO))
+ sq = odm_sq_process_patch_rt_cid_819x_lenovo(
+ dm, is_cck_rate, pwdb_all, 0, 0);
+ else
+ sq = phydm_get_signal_quality_8812(phy_info, dm,
+ phy_sta_rpt);
+
+ phy_info->signal_quality = sq;
+ phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = sq;
+ }
+
+ for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
+ if (i == 0)
+ phy_info->rx_mimo_signal_strength[0] = pwdb_all;
+ else
+ phy_info->rx_mimo_signal_strength[i] = 0;
+ }
+ } else {
+ /*is OFDM rate*/
+ fat_tab->hw_antsw_occur = phy_sta_rpt->hw_antsw_occur;
+
+ dm->phy_dbg_info.num_qry_phy_status_ofdm++;
+
+ /*(1)Get RSSI for OFDM rate*/
+
+ for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
+ /*2008/01/30 MH we will judge RF RX path now.*/
+ if (dm->rf_path_rx_enable & BIT(i))
+ rf_rx_num++;
+ /*2012.05.25 LukeLee: Testchip AGC report is wrong,
+ *it should be restored back to old formula in MP chip
+ */
+ if (i < ODM_RF_PATH_C)
+ rx_pwr[i] = (phy_sta_rpt->gain_trsw[i] & 0x7F) -
+ 110;
+ else
+ rx_pwr[i] = (phy_sta_rpt->gain_trsw_cd[i - 2] &
+ 0x7F) -
+ 110;
+
+ phy_info->rx_pwr[i] = rx_pwr[i];
+
+ /* Translate DBM to percentage. */
+ RSSI = odm_query_rx_pwr_percentage(rx_pwr[i]);
+
+ /*total_rssi += RSSI;*/
+ /*Get the best two RSSI*/
+ if (RSSI > best_rssi && RSSI > second_rssi) {
+ second_rssi = best_rssi;
+ best_rssi = RSSI;
+ } else if (RSSI > second_rssi && RSSI <= best_rssi) {
+ second_rssi = RSSI;
+ }
+
+ phy_info->rx_mimo_signal_strength[i] = (u8)RSSI;
+
+ /*Get Rx snr value in DB*/
+ if (i < ODM_RF_PATH_C)
+ phy_info->rx_snr[i] =
+ dm->phy_dbg_info.rx_snr_db[i] =
+ phy_sta_rpt->rxsnr[i] / 2;
+ else if (dm->support_ic_type &
+ (ODM_RTL8814A | ODM_RTL8822B))
+ phy_info->rx_snr[i] = dm->phy_dbg_info
+ .rx_snr_db[i] =
+ phy_sta_rpt->csi_current[i - 2] / 2;
+
+ /*(2) CFO_short & CFO_tail*/
+ if (i < ODM_RF_PATH_C) {
+ phy_info->cfo_short[i] =
+ odm_cfo((phy_sta_rpt->cfosho[i]));
+ phy_info->cfo_tail[i] =
+ odm_cfo((phy_sta_rpt->cfotail[i]));
+ }
+ }
+
+ /*(3)PWDB, Average PWDB calculated by hardware (for RA)*/
+
+ /*2012.05.25 LukeLee: Testchip AGC report is wrong, it should be
+ *restored back to old formula in MP chip
+ */
+ if ((dm->support_ic_type &
+ (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8881A)) &&
+ (!dm->is_mp_chip))
+ rx_pwr_all = (phy_sta_rpt->pwdb_all & 0x7f) - 110;
+ else
+ rx_pwr_all = (((phy_sta_rpt->pwdb_all) >> 1) & 0x7f) -
+ 110; /*OLD FORMULA*/
+
+ pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
+ pwdb_all_bt = pwdb_all;
+
+ phy_info->rx_pwdb_all = pwdb_all;
+ phy_info->bt_rx_rssi_percentage = pwdb_all_bt;
+ phy_info->rx_power = rx_pwr_all;
+ phy_info->recv_signal_power = rx_pwr_all;
+
+ if ((dm->support_platform == ODM_WIN) && (dm->patch_id == 19)) {
+ /*do nothing*/
+ } else {
+ /*mgnt_info->customer_id != RT_CID_819X_LENOVO*/
+
+ /*(4)EVM of OFDM rate*/
+
+ if ((pktinfo->data_rate >= ODM_RATEMCS8) &&
+ (pktinfo->data_rate <= ODM_RATEMCS15))
+ max_spatial_stream = 2;
+ else if ((pktinfo->data_rate >= ODM_RATEVHTSS2MCS0) &&
+ (pktinfo->data_rate <= ODM_RATEVHTSS2MCS9))
+ max_spatial_stream = 2;
+ else if ((pktinfo->data_rate >= ODM_RATEMCS16) &&
+ (pktinfo->data_rate <= ODM_RATEMCS23))
+ max_spatial_stream = 3;
+ else if ((pktinfo->data_rate >= ODM_RATEVHTSS3MCS0) &&
+ (pktinfo->data_rate <= ODM_RATEVHTSS3MCS9))
+ max_spatial_stream = 3;
+ else
+ max_spatial_stream = 1;
+
+ for (i = 0; i < max_spatial_stream; i++) {
+ /*Don't use shift operation like "rx_evmX >>= 1"
+ *because the compilor of free build environment
+ *fill most significant bit to "zero" when doing
+ *shifting operation which may change a negative
+ *value to positive one, then the dbm value
+ *(which is supposed to be negative) is not
+ *correct anymore.
+ */
+
+ EVM = phydm_get_odm_evm(i, pktinfo,
+ phy_sta_rpt);
+ evm_dbm = phydm_get_evm_dbm(i, EVM, phy_sta_rpt,
+ phy_info);
+ phy_info->rx_mimo_signal_quality[i] = EVM;
+ phy_info->rx_mimo_evm_dbm[i] = evm_dbm;
+ }
+ }
+
+ num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate);
+ odm_parsing_cfo(dm, pktinfo, phy_sta_rpt->cfotail, num_ss);
+ }
+
+ /*UI BSS List signal strength(in percentage), make it good looking,
+ *from 0~100.
+ */
+ /*It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().*/
+ if (is_cck_rate) {
+ phy_info->signal_strength = (u8)(
+ odm_signal_scale_mapping(dm, pwdb_all)); /*pwdb_all;*/
+ } else {
+ if (rf_rx_num != 0) {
+ /* 2015/01 Sean, use the best two RSSI only,
+ * suggested by Ynlin and ChenYu.
+ */
+ if (rf_rx_num == 1)
+ avg_rssi = best_rssi;
+ else
+ avg_rssi = (best_rssi + second_rssi) / 2;
+ phy_info->signal_strength =
+ (u8)(odm_signal_scale_mapping(dm, avg_rssi));
+ }
+ }
+ dm->rx_pwdb_ave = dm->rx_pwdb_ave + phy_info->rx_pwdb_all;
+
+ dm->dm_fat_table.antsel_rx_keep_0 = phy_sta_rpt->antidx_anta;
+ dm->dm_fat_table.antsel_rx_keep_1 = phy_sta_rpt->antidx_antb;
+ dm->dm_fat_table.antsel_rx_keep_2 = phy_sta_rpt->antidx_antc;
+ dm->dm_fat_table.antsel_rx_keep_3 = phy_sta_rpt->antidx_antd;
+}
+
+void phydm_reset_rssi_for_dm(struct phy_dm_struct *dm, u8 station_id)
+{
+ struct rtl_sta_info *entry;
+
+ entry = dm->odm_sta_info[station_id];
+
+ if (!IS_STA_VALID(entry))
+ return;
+
+ ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
+ "Reset RSSI for macid = (( %d ))\n", station_id);
+
+ entry->rssi_stat.undecorated_smoothed_cck = -1;
+ entry->rssi_stat.undecorated_smoothed_ofdm = -1;
+ entry->rssi_stat.undecorated_smoothed_pwdb = -1;
+ entry->rssi_stat.ofdm_pkt = 0;
+ entry->rssi_stat.cck_pkt = 0;
+ entry->rssi_stat.cck_sum_power = 0;
+ entry->rssi_stat.is_send_rssi = RA_RSSI_STATE_INIT;
+ entry->rssi_stat.packet_map = 0;
+ entry->rssi_stat.valid_bit = 0;
+}
+
+void odm_init_rssi_for_dm(struct phy_dm_struct *dm) {}
+
+static void odm_process_rssi_for_dm(struct phy_dm_struct *dm,
+ struct dm_phy_status_info *phy_info,
+ struct dm_per_pkt_info *pktinfo)
+{
+ s32 undecorated_smoothed_pwdb, undecorated_smoothed_cck,
+ undecorated_smoothed_ofdm;
+ u8 is_cck_rate = 0;
+ u8 send_rssi_2_fw = 0;
+ struct rtl_sta_info *entry;
+
+ if (pktinfo->station_id >= ODM_ASSOCIATE_ENTRY_NUM)
+ return;
+
+ /* 2012/05/30 MH/Luke.Lee Add some description */
+ /* In windows driver: AP/IBSS mode STA */
+ entry = dm->odm_sta_info[pktinfo->station_id];
+
+ if (!IS_STA_VALID(entry))
+ return;
+
+ {
+ if ((!pktinfo->is_packet_match_bssid)) /*data frame only*/
+ return;
+ }
+
+ if (pktinfo->is_packet_beacon)
+ dm->phy_dbg_info.num_qry_beacon_pkt++;
+
+ is_cck_rate = (pktinfo->data_rate <= ODM_RATE11M) ? true : false;
+ dm->rx_rate = pktinfo->data_rate;
+
+ /* --------------Statistic for antenna/path diversity---------------- */
+
+ /* -----------------Smart Antenna Debug Message------------------ */
+
+ undecorated_smoothed_cck = entry->rssi_stat.undecorated_smoothed_cck;
+ undecorated_smoothed_ofdm = entry->rssi_stat.undecorated_smoothed_ofdm;
+ undecorated_smoothed_pwdb = entry->rssi_stat.undecorated_smoothed_pwdb;
+
+ if (pktinfo->is_packet_to_self || pktinfo->is_packet_beacon) {
+ if (!is_cck_rate) /* ofdm rate */
+ undecorated_smoothed_ofdm = phydm_process_rssi_ofdm(
+ dm, phy_info, entry, undecorated_smoothed_ofdm);
+ else
+ undecorated_smoothed_cck = phydm_process_rssi_cck(
+ dm, phy_info, entry, undecorated_smoothed_cck);
+
+ undecorated_smoothed_pwdb = phydm_process_rssi_pwdb(
+ dm, entry, pktinfo, undecorated_smoothed_ofdm,
+ undecorated_smoothed_cck);
+
+ if ((entry->rssi_stat.ofdm_pkt >= 1 ||
+ entry->rssi_stat.cck_pkt >= 5) &&
+ (entry->rssi_stat.is_send_rssi == RA_RSSI_STATE_INIT)) {
+ send_rssi_2_fw = 1;
+ entry->rssi_stat.is_send_rssi = RA_RSSI_STATE_SEND;
+ }
+
+ entry->rssi_stat.undecorated_smoothed_cck =
+ undecorated_smoothed_cck;
+ entry->rssi_stat.undecorated_smoothed_ofdm =
+ undecorated_smoothed_ofdm;
+ entry->rssi_stat.undecorated_smoothed_pwdb =
+ undecorated_smoothed_pwdb;
+
+ if (send_rssi_2_fw) { /* Trigger init rate by RSSI */
+
+ if (entry->rssi_stat.ofdm_pkt != 0)
+ entry->rssi_stat.undecorated_smoothed_pwdb =
+ undecorated_smoothed_ofdm;
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_RSSI_MONITOR,
+ "[Send to FW] PWDB = (( %d )), ofdm_pkt = (( %d )), cck_pkt = (( %d ))\n",
+ undecorated_smoothed_pwdb,
+ entry->rssi_stat.ofdm_pkt,
+ entry->rssi_stat.cck_pkt);
+ }
+ }
+}
+
+/*
+ * Endianness before calling this API
+ */
+static void odm_phy_status_query_92c_series(struct phy_dm_struct *dm,
+ struct dm_phy_status_info *phy_info,
+ u8 *phy_status,
+ struct dm_per_pkt_info *pktinfo)
+{
+ odm_rx_phy_status92c_series_parsing(dm, phy_info, phy_status, pktinfo);
+ odm_process_rssi_for_dm(dm, phy_info, pktinfo);
+}
+
+/*
+ * Endianness before calling this API
+ */
+
+static void odm_phy_status_query_jaguar_series(
+ struct phy_dm_struct *dm, struct dm_phy_status_info *phy_info,
+ u8 *phy_status, struct dm_per_pkt_info *pktinfo)
+{
+ odm_rx_phy_status_jaguar_series_parsing(dm, phy_info, phy_status,
+ pktinfo);
+ odm_process_rssi_for_dm(dm, phy_info, pktinfo);
+}
+
+void odm_phy_status_query(struct phy_dm_struct *dm,
+ struct dm_phy_status_info *phy_info, u8 *phy_status,
+ struct dm_per_pkt_info *pktinfo)
+{
+ if (dm->support_ic_type & ODM_IC_PHY_STATUE_NEW_TYPE) {
+ phydm_rx_phy_status_new_type(dm, phy_status, pktinfo, phy_info);
+ return;
+ }
+
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES)
+ odm_phy_status_query_jaguar_series(dm, phy_info, phy_status,
+ pktinfo);
+
+ if (dm->support_ic_type & ODM_IC_11N_SERIES)
+ odm_phy_status_query_92c_series(dm, phy_info, phy_status,
+ pktinfo);
+}
+
+/* For future use. */
+void odm_mac_status_query(struct phy_dm_struct *dm, u8 *mac_status, u8 mac_id,
+ bool is_packet_match_bssid, bool is_packet_to_self,
+ bool is_packet_beacon)
+{
+ /* 2011/10/19 Driver team will handle in the future. */
+}
+
+/*
+ * If you want to add a new IC, Please follow below template and generate
+ * a new one.
+ */
+
+enum hal_status
+odm_config_rf_with_header_file(struct phy_dm_struct *dm,
+ enum odm_rf_config_type config_type,
+ enum odm_rf_radio_path e_rf_path)
+{
+ ODM_RT_TRACE(dm, ODM_COMP_INIT,
+ "===>%s (%s)\n", __func__,
+ (dm->is_mp_chip) ? "MPChip" : "TestChip");
+ ODM_RT_TRACE(
+ dm, ODM_COMP_INIT,
+ "dm->support_platform: 0x%X, dm->support_interface: 0x%X, dm->board_type: 0x%X\n",
+ dm->support_platform, dm->support_interface, dm->board_type);
+
+ /* 1 AP doesn't use PHYDM power tracking table in these ICs */
+ /* JJ ADD 20161014 */
+
+ /* 1 All platforms support */
+ if (dm->support_ic_type == ODM_RTL8822B) {
+ if (config_type == CONFIG_RF_RADIO) {
+ if (e_rf_path == ODM_RF_PATH_A)
+ READ_AND_CONFIG_MP(8822b, _radioa);
+ else if (e_rf_path == ODM_RF_PATH_B)
+ READ_AND_CONFIG_MP(8822b, _radiob);
+ } else if (config_type == CONFIG_RF_TXPWR_LMT) {
+ if (dm->rfe_type == 5)
+ READ_AND_CONFIG_MP(8822b, _txpwr_lmt_type5);
+ else
+ READ_AND_CONFIG_MP(8822b, _txpwr_lmt);
+ }
+ }
+
+ return HAL_STATUS_SUCCESS;
+}
+
+enum hal_status
+odm_config_rf_with_tx_pwr_track_header_file(struct phy_dm_struct *dm)
+{
+ ODM_RT_TRACE(dm, ODM_COMP_INIT,
+ "===>%s (%s)\n", __func__,
+ (dm->is_mp_chip) ? "MPChip" : "TestChip");
+ ODM_RT_TRACE(
+ dm, ODM_COMP_INIT,
+ "dm->support_platform: 0x%X, dm->support_interface: 0x%X, dm->board_type: 0x%X\n",
+ dm->support_platform, dm->support_interface, dm->board_type);
+
+ /* 1 AP doesn't use PHYDM power tracking table in these ICs */
+ /* JJ ADD 20161014 */
+
+ /* 1 All platforms support */
+
+ if (dm->support_ic_type == ODM_RTL8822B) {
+ if (dm->rfe_type == 0)
+ READ_AND_CONFIG_MP(8822b, _txpowertrack_type0);
+ else if (dm->rfe_type == 1)
+ READ_AND_CONFIG_MP(8822b, _txpowertrack_type1);
+ else if (dm->rfe_type == 2)
+ READ_AND_CONFIG_MP(8822b, _txpowertrack_type2);
+ else if ((dm->rfe_type == 3) || (dm->rfe_type == 5))
+ READ_AND_CONFIG_MP(8822b, _txpowertrack_type3_type5);
+ else if (dm->rfe_type == 4)
+ READ_AND_CONFIG_MP(8822b, _txpowertrack_type4);
+ else if (dm->rfe_type == 6)
+ READ_AND_CONFIG_MP(8822b, _txpowertrack_type6);
+ else if (dm->rfe_type == 7)
+ READ_AND_CONFIG_MP(8822b, _txpowertrack_type7);
+ else if (dm->rfe_type == 8)
+ READ_AND_CONFIG_MP(8822b, _txpowertrack_type8);
+ else if (dm->rfe_type == 9)
+ READ_AND_CONFIG_MP(8822b, _txpowertrack_type9);
+ else
+ READ_AND_CONFIG_MP(8822b, _txpowertrack);
+ }
+
+ return HAL_STATUS_SUCCESS;
+}
+
+enum hal_status
+odm_config_bb_with_header_file(struct phy_dm_struct *dm,
+ enum odm_bb_config_type config_type)
+{
+ /* 1 AP doesn't use PHYDM initialization in these ICs */
+ /* JJ ADD 20161014 */
+
+ /* 1 All platforms support */
+ if (dm->support_ic_type == ODM_RTL8822B) {
+ if (config_type == CONFIG_BB_PHY_REG)
+ READ_AND_CONFIG_MP(8822b, _phy_reg);
+ else if (config_type == CONFIG_BB_AGC_TAB)
+ READ_AND_CONFIG_MP(8822b, _agc_tab);
+ else if (config_type == CONFIG_BB_PHY_REG_PG)
+ READ_AND_CONFIG_MP(8822b, _phy_reg_pg);
+ /*else if (config_type == CONFIG_BB_PHY_REG_MP)*/
+ /*READ_AND_CONFIG_MP(8822b, _phy_reg_mp);*/
+ }
+
+ return HAL_STATUS_SUCCESS;
+}
+
+enum hal_status odm_config_mac_with_header_file(struct phy_dm_struct *dm)
+{
+ ODM_RT_TRACE(dm, ODM_COMP_INIT,
+ "===>%s (%s)\n", __func__,
+ (dm->is_mp_chip) ? "MPChip" : "TestChip");
+ ODM_RT_TRACE(
+ dm, ODM_COMP_INIT,
+ "dm->support_platform: 0x%X, dm->support_interface: 0x%X, dm->board_type: 0x%X\n",
+ dm->support_platform, dm->support_interface, dm->board_type);
+
+ /* 1 AP doesn't use PHYDM initialization in these ICs */
+ /* JJ ADD 20161014 */
+
+ /* 1 All platforms support */
+ if (dm->support_ic_type == ODM_RTL8822B)
+ READ_AND_CONFIG_MP(8822b, _mac_reg);
+
+ return HAL_STATUS_SUCCESS;
+}
+
+enum hal_status
+odm_config_fw_with_header_file(struct phy_dm_struct *dm,
+ enum odm_fw_config_type config_type,
+ u8 *p_firmware, u32 *size)
+{
+ return HAL_STATUS_SUCCESS;
+}
+
+u32 odm_get_hw_img_version(struct phy_dm_struct *dm)
+{
+ u32 version = 0;
+
+ /* 1 AP doesn't use PHYDM initialization in these ICs */
+ /* JJ ADD 20161014 */
+
+ /*1 All platforms support*/
+ if (dm->support_ic_type == ODM_RTL8822B)
+ version = GET_VERSION_MP(8822b, _mac_reg);
+
+ return version;
+}
+
+/* For 8822B only!! need to move to FW finally */
+/*==============================================*/
+
+bool phydm_query_is_mu_api(struct phy_dm_struct *phydm, u8 ppdu_idx,
+ u8 *p_data_rate, u8 *p_gid)
+{
+ u8 data_rate = 0, gid = 0;
+ bool is_mu = false;
+
+ data_rate = phydm->phy_dbg_info.num_of_ppdu[ppdu_idx];
+ gid = phydm->phy_dbg_info.gid_num[ppdu_idx];
+
+ if (data_rate & BIT(7)) {
+ is_mu = true;
+ data_rate = data_rate & ~(BIT(7));
+ } else {
+ is_mu = false;
+ }
+
+ *p_data_rate = data_rate;
+ *p_gid = gid;
+
+ return is_mu;
+}
+
+static void phydm_rx_statistic_cal(struct phy_dm_struct *phydm, u8 *phy_status,
+ struct dm_per_pkt_info *pktinfo)
+{
+ struct phy_status_rpt_jaguar2_type1 *phy_sta_rpt =
+ (struct phy_status_rpt_jaguar2_type1 *)phy_status;
+ u8 date_rate = pktinfo->data_rate & ~(BIT(7));
+
+ if ((phy_sta_rpt->gid != 0) && (phy_sta_rpt->gid != 63)) {
+ if (date_rate >= ODM_RATEVHTSS1MCS0) {
+ phydm->phy_dbg_info
+ .num_qry_mu_vht_pkt[date_rate - 0x2C]++;
+ phydm->phy_dbg_info.num_of_ppdu[pktinfo->ppdu_cnt] =
+ date_rate | BIT(7);
+ phydm->phy_dbg_info.gid_num[pktinfo->ppdu_cnt] =
+ phy_sta_rpt->gid;
+ }
+
+ } else {
+ if (date_rate >= ODM_RATEVHTSS1MCS0) {
+ phydm->phy_dbg_info.num_qry_vht_pkt[date_rate - 0x2C]++;
+ phydm->phy_dbg_info.num_of_ppdu[pktinfo->ppdu_cnt] =
+ date_rate;
+ phydm->phy_dbg_info.gid_num[pktinfo->ppdu_cnt] =
+ phy_sta_rpt->gid;
+ }
+ }
+}
+
+static void phydm_reset_phy_info(struct phy_dm_struct *phydm,
+ struct dm_phy_status_info *phy_info)
+{
+ phy_info->rx_pwdb_all = 0;
+ phy_info->signal_quality = 0;
+ phy_info->band_width = 0;
+ phy_info->rx_count = 0;
+ odm_memory_set(phydm, phy_info->rx_mimo_signal_quality, 0, 4);
+ odm_memory_set(phydm, phy_info->rx_mimo_signal_strength, 0, 4);
+ odm_memory_set(phydm, phy_info->rx_snr, 0, 4);
+
+ phy_info->rx_power = -110;
+ phy_info->recv_signal_power = -110;
+ phy_info->bt_rx_rssi_percentage = 0;
+ phy_info->signal_strength = 0;
+ phy_info->bt_coex_pwr_adjust = 0;
+ phy_info->channel = 0;
+ phy_info->is_mu_packet = 0;
+ phy_info->is_beamformed = 0;
+ phy_info->rxsc = 0;
+ odm_memory_set(phydm, phy_info->rx_pwr, -110, 4);
+ odm_memory_set(phydm, phy_info->rx_mimo_evm_dbm, 0, 4);
+ odm_memory_set(phydm, phy_info->cfo_short, 0, 8);
+ odm_memory_set(phydm, phy_info->cfo_tail, 0, 8);
+}
+
+static void phydm_set_per_path_phy_info(u8 rx_path, s8 rx_pwr, s8 rx_evm,
+ s8 cfo_tail, s8 rx_snr,
+ struct dm_phy_status_info *phy_info)
+{
+ u8 evm_dbm = 0;
+ u8 evm_percentage = 0;
+
+ /* SNR is S(8,1), EVM is S(8,1), CFO is S(8,7) */
+
+ if (rx_evm < 0) {
+ /* Calculate EVM in dBm */
+ evm_dbm = ((u8)(0 - rx_evm) >> 1);
+
+ /* Calculate EVM in percentage */
+ if (evm_dbm >= 33)
+ evm_percentage = 100;
+ else
+ evm_percentage = (evm_dbm << 1) + (evm_dbm);
+ }
+
+ phy_info->rx_pwr[rx_path] = rx_pwr;
+ phy_info->rx_mimo_evm_dbm[rx_path] = evm_dbm;
+
+ /* CFO = CFO_tail * 312.5 / 2^7 ~= CFO tail * 39/512 (kHz)*/
+ phy_info->cfo_tail[rx_path] = cfo_tail;
+ phy_info->cfo_tail[rx_path] = ((phy_info->cfo_tail[rx_path] << 5) +
+ (phy_info->cfo_tail[rx_path] << 2) +
+ (phy_info->cfo_tail[rx_path] << 1) +
+ (phy_info->cfo_tail[rx_path])) >>
+ 9;
+
+ phy_info->rx_mimo_signal_strength[rx_path] =
+ odm_query_rx_pwr_percentage(rx_pwr);
+ phy_info->rx_mimo_signal_quality[rx_path] = evm_percentage;
+ phy_info->rx_snr[rx_path] = rx_snr >> 1;
+}
+
+static void phydm_set_common_phy_info(s8 rx_power, u8 channel,
+ bool is_beamformed, bool is_mu_packet,
+ u8 bandwidth, u8 signal_quality, u8 rxsc,
+ struct dm_phy_status_info *phy_info)
+{
+ phy_info->rx_power = rx_power; /* RSSI in dB */
+ phy_info->recv_signal_power = rx_power; /* RSSI in dB */
+ phy_info->channel = channel; /* channel number */
+ phy_info->is_beamformed = is_beamformed; /* apply BF */
+ phy_info->is_mu_packet = is_mu_packet; /* MU packet */
+ phy_info->rxsc = rxsc;
+ phy_info->rx_pwdb_all =
+ odm_query_rx_pwr_percentage(rx_power); /* RSSI in percentage */
+ phy_info->signal_quality = signal_quality; /* signal quality */
+ phy_info->band_width = bandwidth; /* bandwidth */
+}
+
+static void phydm_get_rx_phy_status_type0(struct phy_dm_struct *dm,
+ u8 *phy_status,
+ struct dm_per_pkt_info *pktinfo,
+ struct dm_phy_status_info *phy_info)
+{
+ /* type 0 is used for cck packet */
+
+ struct phy_status_rpt_jaguar2_type0 *phy_sta_rpt =
+ (struct phy_status_rpt_jaguar2_type0 *)phy_status;
+ u8 sq = 0;
+ s8 rx_power = phy_sta_rpt->pwdb - 110;
+
+ /* JJ ADD 20161014 */
+
+ /* Calculate Signal Quality*/
+ if (pktinfo->is_packet_match_bssid) {
+ if (phy_sta_rpt->signal_quality >= 64) {
+ sq = 0;
+ } else if (phy_sta_rpt->signal_quality <= 20) {
+ sq = 100;
+ } else {
+ /* mapping to 2~99% */
+ sq = 64 - phy_sta_rpt->signal_quality;
+ sq = ((sq << 3) + sq) >> 2;
+ }
+ }
+
+ /* Modify CCK PWDB if old AGC */
+ if (!dm->cck_new_agc) {
+ u8 lna_idx, vga_idx;
+
+ lna_idx = ((phy_sta_rpt->lna_h << 3) | phy_sta_rpt->lna_l);
+ vga_idx = phy_sta_rpt->vga;
+
+ /* JJ ADD 20161014 */
+
+ /* Need to do !! */
+ /*if (dm->support_ic_type & ODM_RTL8822B) */
+ /*rx_power = odm_CCKRSSI_8822B(LNA_idx, VGA_idx);*/
+ }
+
+ /* Update CCK packet counter */
+ dm->phy_dbg_info.num_qry_phy_status_cck++;
+
+ /*CCK no STBC and LDPC*/
+ dm->phy_dbg_info.is_ldpc_pkt = false;
+ dm->phy_dbg_info.is_stbc_pkt = false;
+
+ /* Update Common information */
+ phydm_set_common_phy_info(rx_power, phy_sta_rpt->channel, false, false,
+ ODM_BW20M, sq, phy_sta_rpt->rxsc, phy_info);
+
+ /* Update CCK pwdb */
+ /* Update per-path information */
+ phydm_set_per_path_phy_info(ODM_RF_PATH_A, rx_power, 0, 0, 0, phy_info);
+
+ dm->dm_fat_table.antsel_rx_keep_0 = phy_sta_rpt->antidx_a;
+ dm->dm_fat_table.antsel_rx_keep_1 = phy_sta_rpt->antidx_b;
+ dm->dm_fat_table.antsel_rx_keep_2 = phy_sta_rpt->antidx_c;
+ dm->dm_fat_table.antsel_rx_keep_3 = phy_sta_rpt->antidx_d;
+}
+
+static void phydm_get_rx_phy_status_type1(struct phy_dm_struct *dm,
+ u8 *phy_status,
+ struct dm_per_pkt_info *pktinfo,
+ struct dm_phy_status_info *phy_info)
+{
+ /* type 1 is used for ofdm packet */
+
+ struct phy_status_rpt_jaguar2_type1 *phy_sta_rpt =
+ (struct phy_status_rpt_jaguar2_type1 *)phy_status;
+ s8 rx_pwr_db = -120;
+ u8 i, rxsc, bw = ODM_BW20M, rx_count = 0;
+ bool is_mu;
+ u8 num_ss;
+
+ /* Update OFDM packet counter */
+ dm->phy_dbg_info.num_qry_phy_status_ofdm++;
+
+ /* Update per-path information */
+ for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
+ if (dm->rx_ant_status & BIT(i)) {
+ s8 rx_path_pwr_db;
+
+ /* RX path counter */
+ rx_count++;
+
+ /* Update per-path information
+ * (RSSI_dB RSSI_percentage EVM SNR CFO sq)
+ */
+ /* EVM report is reported by stream, not path */
+ rx_path_pwr_db = phy_sta_rpt->pwdb[i] -
+ 110; /* per-path pwdb in dB domain */
+ phydm_set_per_path_phy_info(
+ i, rx_path_pwr_db,
+ phy_sta_rpt->rxevm[rx_count - 1],
+ phy_sta_rpt->cfo_tail[i], phy_sta_rpt->rxsnr[i],
+ phy_info);
+
+ /* search maximum pwdb */
+ if (rx_path_pwr_db > rx_pwr_db)
+ rx_pwr_db = rx_path_pwr_db;
+ }
+ }
+
+ /* mapping RX counter from 1~4 to 0~3 */
+ if (rx_count > 0)
+ phy_info->rx_count = rx_count - 1;
+
+ /* Check if MU packet or not */
+ if ((phy_sta_rpt->gid != 0) && (phy_sta_rpt->gid != 63)) {
+ is_mu = true;
+ dm->phy_dbg_info.num_qry_mu_pkt++;
+ } else {
+ is_mu = false;
+ }
+
+ /* count BF packet */
+ dm->phy_dbg_info.num_qry_bf_pkt =
+ dm->phy_dbg_info.num_qry_bf_pkt + phy_sta_rpt->beamformed;
+
+ /*STBC or LDPC pkt*/
+ dm->phy_dbg_info.is_ldpc_pkt = phy_sta_rpt->ldpc;
+ dm->phy_dbg_info.is_stbc_pkt = phy_sta_rpt->stbc;
+
+ /* Check sub-channel */
+ if ((pktinfo->data_rate > ODM_RATE11M) &&
+ (pktinfo->data_rate < ODM_RATEMCS0))
+ rxsc = phy_sta_rpt->l_rxsc;
+ else
+ rxsc = phy_sta_rpt->ht_rxsc;
+
+ /* Check RX bandwidth */
+ if (dm->support_ic_type & ODM_RTL8822B) {
+ if ((rxsc >= 1) && (rxsc <= 8))
+ bw = ODM_BW20M;
+ else if ((rxsc >= 9) && (rxsc <= 12))
+ bw = ODM_BW40M;
+ else if (rxsc >= 13)
+ bw = ODM_BW80M;
+ else
+ bw = phy_sta_rpt->rf_mode;
+ } else if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8723D |
+ ODM_RTL8710B)) { /* JJ ADD 20161014 */
+ if (phy_sta_rpt->rf_mode == 0)
+ bw = ODM_BW20M;
+ else if ((rxsc == 1) || (rxsc == 2))
+ bw = ODM_BW20M;
+ else
+ bw = ODM_BW40M;
+ }
+
+ /* Update packet information */
+ phydm_set_common_phy_info(
+ rx_pwr_db, phy_sta_rpt->channel, (bool)phy_sta_rpt->beamformed,
+ is_mu, bw, odm_evm_db_to_percentage(phy_sta_rpt->rxevm[0]),
+ rxsc, phy_info);
+
+ num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate);
+
+ odm_parsing_cfo(dm, pktinfo, phy_sta_rpt->cfo_tail, num_ss);
+ dm->dm_fat_table.antsel_rx_keep_0 = phy_sta_rpt->antidx_a;
+ dm->dm_fat_table.antsel_rx_keep_1 = phy_sta_rpt->antidx_b;
+ dm->dm_fat_table.antsel_rx_keep_2 = phy_sta_rpt->antidx_c;
+ dm->dm_fat_table.antsel_rx_keep_3 = phy_sta_rpt->antidx_d;
+
+ if (pktinfo->is_packet_match_bssid) {
+ /* */
+ phydm_rx_statistic_cal(dm, phy_status, pktinfo);
+ }
+}
+
+static void phydm_get_rx_phy_status_type2(struct phy_dm_struct *dm,
+ u8 *phy_status,
+ struct dm_per_pkt_info *pktinfo,
+ struct dm_phy_status_info *phy_info)
+{
+ struct phy_status_rpt_jaguar2_type2 *phy_sta_rpt =
+ (struct phy_status_rpt_jaguar2_type2 *)phy_status;
+ s8 rx_pwr_db = -120;
+ u8 i, rxsc, bw = ODM_BW20M, rx_count = 0;
+
+ /* Update OFDM packet counter */
+ dm->phy_dbg_info.num_qry_phy_status_ofdm++;
+
+ /* Update per-path information */
+ for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
+ if (dm->rx_ant_status & BIT(i)) {
+ s8 rx_path_pwr_db;
+
+ /* RX path counter */
+ rx_count++;
+
+ /* Update per-path information
+ * (RSSI_dB RSSI_percentage EVM SNR CFO sq)
+ */
+ rx_path_pwr_db = phy_sta_rpt->pwdb[i] -
+ 110; /* per-path pwdb in dB domain */
+
+ phydm_set_per_path_phy_info(i, rx_path_pwr_db, 0, 0, 0,
+ phy_info);
+
+ /* search maximum pwdb */
+ if (rx_path_pwr_db > rx_pwr_db)
+ rx_pwr_db = rx_path_pwr_db;
+ }
+ }
+
+ /* mapping RX counter from 1~4 to 0~3 */
+ if (rx_count > 0)
+ phy_info->rx_count = rx_count - 1;
+
+ /* Check RX sub-channel */
+ if ((pktinfo->data_rate > ODM_RATE11M) &&
+ (pktinfo->data_rate < ODM_RATEMCS0))
+ rxsc = phy_sta_rpt->l_rxsc;
+ else
+ rxsc = phy_sta_rpt->ht_rxsc;
+
+ /*STBC or LDPC pkt*/
+ dm->phy_dbg_info.is_ldpc_pkt = phy_sta_rpt->ldpc;
+ dm->phy_dbg_info.is_stbc_pkt = phy_sta_rpt->stbc;
+
+ /* Check RX bandwidth */
+ /* the BW information of sc=0 is useless, because there is
+ * no information of RF mode
+ */
+
+ if (dm->support_ic_type & ODM_RTL8822B) {
+ if ((rxsc >= 1) && (rxsc <= 8))
+ bw = ODM_BW20M;
+ else if ((rxsc >= 9) && (rxsc <= 12))
+ bw = ODM_BW40M;
+ else if (rxsc >= 13)
+ bw = ODM_BW80M;
+ else
+ bw = ODM_BW20M;
+ } else if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8723D |
+ ODM_RTL8710B)) { /* JJ ADD 20161014 */
+ if (rxsc == 3)
+ bw = ODM_BW40M;
+ else if ((rxsc == 1) || (rxsc == 2))
+ bw = ODM_BW20M;
+ else
+ bw = ODM_BW20M;
+ }
+
+ /* Update packet information */
+ phydm_set_common_phy_info(rx_pwr_db, phy_sta_rpt->channel,
+ (bool)phy_sta_rpt->beamformed, false, bw, 0,
+ rxsc, phy_info);
+}
+
+static void
+phydm_process_rssi_for_dm_new_type(struct phy_dm_struct *dm,
+ struct dm_phy_status_info *phy_info,
+ struct dm_per_pkt_info *pktinfo)
+{
+ s32 undecorated_smoothed_pwdb, accumulate_pwdb;
+ u32 rssi_ave;
+ u8 i;
+ struct rtl_sta_info *entry;
+ u8 scaling_factor = 4;
+
+ if (pktinfo->station_id >= ODM_ASSOCIATE_ENTRY_NUM)
+ return;
+
+ entry = dm->odm_sta_info[pktinfo->station_id];
+
+ if (!IS_STA_VALID(entry))
+ return;
+
+ if ((!pktinfo->is_packet_match_bssid)) /*data frame only*/
+ return;
+
+ if (pktinfo->is_packet_beacon)
+ dm->phy_dbg_info.num_qry_beacon_pkt++;
+
+ if (pktinfo->is_packet_to_self || pktinfo->is_packet_beacon) {
+ u32 rssi_linear = 0;
+
+ dm->rx_rate = pktinfo->data_rate;
+ undecorated_smoothed_pwdb =
+ entry->rssi_stat.undecorated_smoothed_pwdb;
+ accumulate_pwdb = dm->accumulate_pwdb[pktinfo->station_id];
+ dm->rssi_a = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A];
+ dm->rssi_b = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B];
+ dm->rssi_c = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_C];
+ dm->rssi_d = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_D];
+
+ for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
+ if (phy_info->rx_mimo_signal_strength[i] != 0)
+ rssi_linear += odm_convert_to_linear(
+ phy_info->rx_mimo_signal_strength[i]);
+ }
+
+ switch (phy_info->rx_count + 1) {
+ case 2:
+ rssi_linear = (rssi_linear >> 1);
+ break;
+ case 3:
+ /* rssi_linear/3 ~ rssi_linear*11/32 */
+ rssi_linear = ((rssi_linear) + (rssi_linear << 1) +
+ (rssi_linear << 3)) >>
+ 5;
+ break;
+ case 4:
+ rssi_linear = (rssi_linear >> 2);
+ break;
+ }
+ rssi_ave = odm_convert_to_db(rssi_linear);
+
+ if (undecorated_smoothed_pwdb <= 0) {
+ accumulate_pwdb =
+ (phy_info->rx_pwdb_all << scaling_factor);
+ undecorated_smoothed_pwdb = phy_info->rx_pwdb_all;
+ } else {
+ accumulate_pwdb = accumulate_pwdb -
+ (accumulate_pwdb >> scaling_factor) +
+ rssi_ave;
+ undecorated_smoothed_pwdb =
+ (accumulate_pwdb +
+ (1 << (scaling_factor - 1))) >>
+ scaling_factor;
+ }
+
+ entry->rssi_stat.undecorated_smoothed_pwdb =
+ undecorated_smoothed_pwdb;
+ dm->accumulate_pwdb[pktinfo->station_id] = accumulate_pwdb;
+ }
+}
+
+void phydm_rx_phy_status_new_type(struct phy_dm_struct *phydm, u8 *phy_status,
+ struct dm_per_pkt_info *pktinfo,
+ struct dm_phy_status_info *phy_info)
+{
+ u8 phy_status_type = (*phy_status & 0xf);
+
+ /* Memory reset */
+ phydm_reset_phy_info(phydm, phy_info);
+
+ /* Phy status parsing */
+ switch (phy_status_type) {
+ case 0: {
+ phydm_get_rx_phy_status_type0(phydm, phy_status, pktinfo,
+ phy_info);
+ break;
+ }
+ case 1: {
+ phydm_get_rx_phy_status_type1(phydm, phy_status, pktinfo,
+ phy_info);
+ break;
+ }
+ case 2: {
+ phydm_get_rx_phy_status_type2(phydm, phy_status, pktinfo,
+ phy_info);
+ break;
+ }
+ default:
+ return;
+ }
+
+ /* Update signal strength to UI, and phy_info->rx_pwdb_all is the
+ * maximum RSSI of all path
+ */
+ phy_info->signal_strength =
+ (u8)(odm_signal_scale_mapping(phydm, phy_info->rx_pwdb_all));
+
+ /* Calculate average RSSI and smoothed RSSI */
+ phydm_process_rssi_for_dm_new_type(phydm, phy_info, pktinfo);
+}
+
+u32 query_phydm_trx_capability(struct phy_dm_struct *dm)
+{
+ u32 value32 = 0xFFFFFFFF;
+
+ return value32;
+}
+
+u32 query_phydm_stbc_capability(struct phy_dm_struct *dm)
+{
+ u32 value32 = 0xFFFFFFFF;
+
+ return value32;
+}
+
+u32 query_phydm_ldpc_capability(struct phy_dm_struct *dm)
+{
+ u32 value32 = 0xFFFFFFFF;
+
+ return value32;
+}
+
+u32 query_phydm_txbf_parameters(struct phy_dm_struct *dm)
+{
+ u32 value32 = 0xFFFFFFFF;
+
+ return value32;
+}
+
+u32 query_phydm_txbf_capability(struct phy_dm_struct *dm)
+{
+ u32 value32 = 0xFFFFFFFF;
+
+ return value32;
+}
diff --git a/drivers/staging/rtlwifi/phydm/phydm_hwconfig.h b/drivers/staging/rtlwifi/phydm/phydm_hwconfig.h
new file mode 100644
index 0000000..ec94c61
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_hwconfig.h
@@ -0,0 +1,510 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __HALHWOUTSRC_H__
+#define __HALHWOUTSRC_H__
+
+/*--------------------------Define -------------------------------------------*/
+#define CCK_RSSI_INIT_COUNT 5
+
+#define RA_RSSI_STATE_INIT 0
+#define RA_RSSI_STATE_SEND 1
+#define RA_RSSI_STATE_HOLD 2
+
+#define CFO_HW_RPT_2_MHZ(val) ((val << 1) + (val >> 1))
+/* ((X* 3125) / 10)>>7 = (X*10)>>2 = X*2.5 = X<<1 + X>>1 */
+
+#define AGC_DIFF_CONFIG_MP(ic, band) \
+ (odm_read_and_config_mp_##ic##_agc_tab_diff( \
+ dm, array_mp_##ic##_agc_tab_diff_##band, \
+ sizeof(array_mp_##ic##_agc_tab_diff_##band) / sizeof(u32)))
+#define AGC_DIFF_CONFIG_TC(ic, band) \
+ (odm_read_and_config_tc_##ic##_agc_tab_diff( \
+ dm, array_tc_##ic##_agc_tab_diff_##band, \
+ sizeof(array_tc_##ic##_agc_tab_diff_##band) / sizeof(u32)))
+
+#define AGC_DIFF_CONFIG(ic, band) \
+ do { \
+ if (dm->is_mp_chip) \
+ AGC_DIFF_CONFIG_MP(ic, band); \
+ else \
+ AGC_DIFF_CONFIG_TC(ic, band); \
+ } while (0)
+
+/* ************************************************************
+ * structure and define
+ * *************************************************************/
+
+struct phy_rx_agc_info {
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 gain : 7, trsw : 1;
+#else
+ u8 trsw : 1, gain : 7;
+#endif
+};
+
+struct phy_status_rpt_8192cd {
+ struct phy_rx_agc_info path_agc[2];
+ u8 ch_corr[2];
+ u8 cck_sig_qual_ofdm_pwdb_all;
+ u8 cck_agc_rpt_ofdm_cfosho_a;
+ u8 cck_rpt_b_ofdm_cfosho_b;
+ u8 rsvd_1; /*ch_corr_msb;*/
+ u8 noise_power_db_msb;
+ s8 path_cfotail[2];
+ u8 pcts_mask[2];
+ s8 stream_rxevm[2];
+ u8 path_rxsnr[2];
+ u8 noise_power_db_lsb;
+ u8 rsvd_2[3];
+ u8 stream_csi[2];
+ u8 stream_target_csi[2];
+ s8 sig_evm;
+ u8 rsvd_3;
+
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 antsel_rx_keep_2 : 1; /*ex_intf_flg:1;*/
+ u8 sgi_en : 1;
+ u8 rxsc : 2;
+ u8 idle_long : 1;
+ u8 r_ant_train_en : 1;
+ u8 ant_sel_b : 1;
+ u8 ant_sel : 1;
+#else /*_BIG_ENDIAN_ */
+ u8 ant_sel : 1;
+ u8 ant_sel_b : 1;
+ u8 r_ant_train_en : 1;
+ u8 idle_long : 1;
+ u8 rxsc : 2;
+ u8 sgi_en : 1;
+ u8 antsel_rx_keep_2 : 1; /*ex_intf_flg:1;*/
+#endif
+};
+
+struct phy_status_rpt_8812 {
+ /* DWORD 0*/
+ u8 gain_trsw[2]; /*path-A and path-B {TRSW, gain[6:0] }*/
+ u8 chl_num_LSB; /*channel number[7:0]*/
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 chl_num_MSB : 2; /*channel number[9:8]*/
+ u8 sub_chnl : 4; /*sub-channel location[3:0]*/
+ u8 r_RFMOD : 2; /*RF mode[1:0]*/
+#else /*_BIG_ENDIAN_ */
+ u8 r_RFMOD : 2;
+ u8 sub_chnl : 4;
+ u8 chl_num_MSB : 2;
+#endif
+
+ /* DWORD 1*/
+ u8 pwdb_all; /*CCK signal quality / OFDM pwdb all*/
+ s8 cfosho[2]; /*DW1 byte 1 DW1 byte2 */
+/*CCK AGC report and CCK_BB_Power / OFDM path-A and path-B short CFO*/
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ /*this should be checked again
+ *because the definition of 8812 and 8814 is different
+ */
+ u8 resvd_0 : 6;
+ u8 bt_RF_ch_MSB : 2; /*8812A:2'b0, 8814A: bt rf channel keep[7:6]*/
+#else /*_BIG_ENDIAN_*/
+ u8 bt_RF_ch_MSB : 2;
+ u8 resvd_0 : 6;
+#endif
+
+/* DWORD 2*/
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 ant_div_sw_a : 1; /*8812A: ant_div_sw_a, 8814A: 1'b0*/
+ u8 ant_div_sw_b : 1; /*8812A: ant_div_sw_b, 8814A: 1'b0*/
+ u8 bt_RF_ch_LSB : 6; /*8812A: 6'b0, 8814A: bt rf channel keep[5:0]*/
+#else /*_BIG_ENDIAN_ */
+ u8 bt_RF_ch_LSB : 6;
+ u8 ant_div_sw_b : 1;
+ u8 ant_div_sw_a : 1;
+#endif
+ s8 cfotail[2]; /*DW2 byte 1 DW2 byte 2 path-A and path-B CFO tail*/
+ u8 PCTS_MSK_RPT_0; /*PCTS mask report[7:0]*/
+ u8 PCTS_MSK_RPT_1; /*PCTS mask report[15:8]*/
+
+ /* DWORD 3*/
+ s8 rxevm[2]; /*DW3 byte 1 DW3 byte 2 stream 1 and stream 2 RX EVM*/
+ s8 rxsnr[2]; /*DW3 byte 3 DW4 byte 0 path-A and path-B RX SNR*/
+
+ /* DWORD 4*/
+ u8 PCTS_MSK_RPT_2; /*PCTS mask report[23:16]*/
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 PCTS_MSK_RPT_3 : 6; /*PCTS mask report[29:24]*/
+ u8 pcts_rpt_valid : 1; /*pcts_rpt_valid*/
+ u8 resvd_1 : 1; /*1'b0*/
+#else /*_BIG_ENDIAN_*/
+ u8 resvd_1 : 1;
+ u8 pcts_rpt_valid : 1;
+ u8 PCTS_MSK_RPT_3 : 6;
+#endif
+ s8 rxevm_cd[2]; /*DW 4 byte 3 DW5 byte 0 */
+ /* 8812A: 16'b0, 8814A: stream 3 and stream 4 RX EVM*/
+
+ /* DWORD 5*/
+ u8 csi_current[2]; /*DW5 byte 1 DW5 byte 2 */
+ /* 8812A: stream 1 and 2 CSI, 8814A: path-C and path-D RX SNR*/
+ u8 gain_trsw_cd[2]; /*DW5 byte 3 DW6 byte 0 */
+ /* path-C and path-D {TRSW, gain[6:0] }*/
+
+ /* DWORD 6*/
+ s8 sigevm; /*signal field EVM*/
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 antidx_antc : 3; /*8812A: 3'b0 8814A: antidx_antc[2:0]*/
+ u8 antidx_antd : 3; /*8812A: 3'b0 8814A: antidx_antd[2:0]*/
+ u8 dpdt_ctrl_keep : 1; /*8812A: 1'b0 8814A: dpdt_ctrl_keep*/
+ u8 GNT_BT_keep : 1; /*8812A: 1'b0 8814A: GNT_BT_keep*/
+#else /*_BIG_ENDIAN_*/
+ u8 GNT_BT_keep : 1;
+ u8 dpdt_ctrl_keep : 1;
+ u8 antidx_antd : 3;
+ u8 antidx_antc : 3;
+#endif
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 antidx_anta : 3; /*antidx_anta[2:0]*/
+ u8 antidx_antb : 3; /*antidx_antb[2:0]*/
+ u8 hw_antsw_occur : 2; /*1'b0*/
+#else /*_BIG_ENDIAN_*/
+ u8 hw_antsw_occur : 2;
+ u8 antidx_antb : 3;
+ u8 antidx_anta : 3;
+#endif
+};
+
+void phydm_reset_rssi_for_dm(struct phy_dm_struct *dm, u8 station_id);
+
+void odm_init_rssi_for_dm(struct phy_dm_struct *dm);
+
+void odm_phy_status_query(struct phy_dm_struct *dm,
+ struct dm_phy_status_info *phy_info, u8 *phy_status,
+ struct dm_per_pkt_info *pktinfo);
+
+void odm_mac_status_query(struct phy_dm_struct *dm, u8 *mac_status, u8 mac_id,
+ bool is_packet_match_bssid, bool is_packet_to_self,
+ bool is_packet_beacon);
+
+enum hal_status
+odm_config_rf_with_tx_pwr_track_header_file(struct phy_dm_struct *dm);
+
+enum hal_status
+odm_config_rf_with_header_file(struct phy_dm_struct *dm,
+ enum odm_rf_config_type config_type,
+ enum odm_rf_radio_path e_rf_path);
+
+enum hal_status
+odm_config_bb_with_header_file(struct phy_dm_struct *dm,
+ enum odm_bb_config_type config_type);
+
+enum hal_status odm_config_mac_with_header_file(struct phy_dm_struct *dm);
+
+enum hal_status
+odm_config_fw_with_header_file(struct phy_dm_struct *dm,
+ enum odm_fw_config_type config_type,
+ u8 *p_firmware, u32 *size);
+
+u32 odm_get_hw_img_version(struct phy_dm_struct *dm);
+
+s32 odm_signal_scale_mapping(struct phy_dm_struct *dm, s32 curr_sig);
+
+/*For 8822B only!! need to move to FW finally */
+/*==============================================*/
+void phydm_rx_phy_status_new_type(struct phy_dm_struct *phydm, u8 *phy_status,
+ struct dm_per_pkt_info *pktinfo,
+ struct dm_phy_status_info *phy_info);
+
+bool phydm_query_is_mu_api(struct phy_dm_struct *phydm, u8 ppdu_idx,
+ u8 *p_data_rate, u8 *p_gid);
+
+struct phy_status_rpt_jaguar2_type0 {
+ /* DW0 */
+ u8 page_num;
+ u8 pwdb;
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 gain : 6;
+ u8 rsvd_0 : 1;
+ u8 trsw : 1;
+#else
+ u8 trsw : 1;
+ u8 rsvd_0 : 1;
+ u8 gain : 6;
+#endif
+ u8 rsvd_1;
+
+ /* DW1 */
+ u8 rsvd_2;
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 rxsc : 4;
+ u8 agc_table : 4;
+#else
+ u8 agc_table : 4;
+ u8 rxsc : 4;
+#endif
+ u8 channel;
+ u8 band;
+
+ /* DW2 */
+ u16 length;
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 antidx_a : 3;
+ u8 antidx_b : 3;
+ u8 rsvd_3 : 2;
+ u8 antidx_c : 3;
+ u8 antidx_d : 3;
+ u8 rsvd_4 : 2;
+#else
+ u8 rsvd_3 : 2;
+ u8 antidx_b : 3;
+ u8 antidx_a : 3;
+ u8 rsvd_4 : 2;
+ u8 antidx_d : 3;
+ u8 antidx_c : 3;
+#endif
+
+ /* DW3 */
+ u8 signal_quality;
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 vga : 5;
+ u8 lna_l : 3;
+ u8 bb_power : 6;
+ u8 rsvd_9 : 1;
+ u8 lna_h : 1;
+#else
+ u8 lna_l : 3;
+ u8 vga : 5;
+ u8 lna_h : 1;
+ u8 rsvd_9 : 1;
+ u8 bb_power : 6;
+#endif
+ u8 rsvd_5;
+
+ /* DW4 */
+ u32 rsvd_6;
+
+ /* DW5 */
+ u32 rsvd_7;
+
+ /* DW6 */
+ u32 rsvd_8;
+};
+
+struct phy_status_rpt_jaguar2_type1 {
+ /* DW0 and DW1 */
+ u8 page_num;
+ u8 pwdb[4];
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 l_rxsc : 4;
+ u8 ht_rxsc : 4;
+#else
+ u8 ht_rxsc : 4;
+ u8 l_rxsc : 4;
+#endif
+ u8 channel;
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 band : 2;
+ u8 rsvd_0 : 1;
+ u8 hw_antsw_occu : 1;
+ u8 gnt_bt : 1;
+ u8 ldpc : 1;
+ u8 stbc : 1;
+ u8 beamformed : 1;
+#else
+ u8 beamformed : 1;
+ u8 stbc : 1;
+ u8 ldpc : 1;
+ u8 gnt_bt : 1;
+ u8 hw_antsw_occu : 1;
+ u8 rsvd_0 : 1;
+ u8 band : 2;
+#endif
+
+ /* DW2 */
+ u16 lsig_length;
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 antidx_a : 3;
+ u8 antidx_b : 3;
+ u8 rsvd_1 : 2;
+ u8 antidx_c : 3;
+ u8 antidx_d : 3;
+ u8 rsvd_2 : 2;
+#else
+ u8 rsvd_1 : 2;
+ u8 antidx_b : 3;
+ u8 antidx_a : 3;
+ u8 rsvd_2 : 2;
+ u8 antidx_d : 3;
+ u8 antidx_c : 3;
+#endif
+
+ /* DW3 */
+ u8 paid;
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 paid_msb : 1;
+ u8 gid : 6;
+ u8 rsvd_3 : 1;
+#else
+ u8 rsvd_3 : 1;
+ u8 gid : 6;
+ u8 paid_msb : 1;
+#endif
+ u8 intf_pos;
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 intf_pos_msb : 1;
+ u8 rsvd_4 : 2;
+ u8 nb_intf_flag : 1;
+ u8 rf_mode : 2;
+ u8 rsvd_5 : 2;
+#else
+ u8 rsvd_5 : 2;
+ u8 rf_mode : 2;
+ u8 nb_intf_flag : 1;
+ u8 rsvd_4 : 2;
+ u8 intf_pos_msb : 1;
+#endif
+
+ /* DW4 */
+ s8 rxevm[4]; /* s(8,1) */
+
+ /* DW5 */
+ s8 cfo_tail[4]; /* s(8,7) */
+
+ /* DW6 */
+ s8 rxsnr[4]; /* s(8,1) */
+};
+
+struct phy_status_rpt_jaguar2_type2 {
+ /* DW0 ane DW1 */
+ u8 page_num;
+ u8 pwdb[4];
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 l_rxsc : 4;
+ u8 ht_rxsc : 4;
+#else
+ u8 ht_rxsc : 4;
+ u8 l_rxsc : 4;
+#endif
+ u8 channel;
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 band : 2;
+ u8 rsvd_0 : 1;
+ u8 hw_antsw_occu : 1;
+ u8 gnt_bt : 1;
+ u8 ldpc : 1;
+ u8 stbc : 1;
+ u8 beamformed : 1;
+#else
+ u8 beamformed : 1;
+ u8 stbc : 1;
+ u8 ldpc : 1;
+ u8 gnt_bt : 1;
+ u8 hw_antsw_occu : 1;
+ u8 rsvd_0 : 1;
+ u8 band : 2;
+#endif
+
+/* DW2 */
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 shift_l_map : 6;
+ u8 rsvd_1 : 2;
+#else
+ u8 rsvd_1 : 2;
+ u8 shift_l_map : 6;
+#endif
+ u8 cnt_pw2cca;
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 agc_table_a : 4;
+ u8 agc_table_b : 4;
+ u8 agc_table_c : 4;
+ u8 agc_table_d : 4;
+#else
+ u8 agc_table_b : 4;
+ u8 agc_table_a : 4;
+ u8 agc_table_d : 4;
+ u8 agc_table_c : 4;
+#endif
+
+ /* DW3 ~ DW6*/
+ u8 cnt_cca2agc_rdy;
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 gain_a : 6;
+ u8 rsvd_2 : 1;
+ u8 trsw_a : 1;
+ u8 gain_b : 6;
+ u8 rsvd_3 : 1;
+ u8 trsw_b : 1;
+ u8 gain_c : 6;
+ u8 rsvd_4 : 1;
+ u8 trsw_c : 1;
+ u8 gain_d : 6;
+ u8 rsvd_5 : 1;
+ u8 trsw_d : 1;
+ u8 aagc_step_a : 2;
+ u8 aagc_step_b : 2;
+ u8 aagc_step_c : 2;
+ u8 aagc_step_d : 2;
+#else
+ u8 trsw_a : 1;
+ u8 rsvd_2 : 1;
+ u8 gain_a : 6;
+ u8 trsw_b : 1;
+ u8 rsvd_3 : 1;
+ u8 gain_b : 6;
+ u8 trsw_c : 1;
+ u8 rsvd_4 : 1;
+ u8 gain_c : 6;
+ u8 trsw_d : 1;
+ u8 rsvd_5 : 1;
+ u8 gain_d : 6;
+ u8 aagc_step_d : 2;
+ u8 aagc_step_c : 2;
+ u8 aagc_step_b : 2;
+ u8 aagc_step_a : 2;
+#endif
+ u8 ht_aagc_gain[4];
+ u8 dagc_gain[4];
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 counter : 6;
+ u8 rsvd_6 : 2;
+ u8 syn_count : 5;
+ u8 rsvd_7 : 3;
+#else
+ u8 rsvd_6 : 2;
+ u8 counter : 6;
+ u8 rsvd_7 : 3;
+ u8 syn_count : 5;
+#endif
+};
+
+u32 query_phydm_trx_capability(struct phy_dm_struct *dm);
+
+u32 query_phydm_stbc_capability(struct phy_dm_struct *dm);
+
+u32 query_phydm_ldpc_capability(struct phy_dm_struct *dm);
+
+u32 query_phydm_txbf_parameters(struct phy_dm_struct *dm);
+
+u32 query_phydm_txbf_capability(struct phy_dm_struct *dm);
+
+#endif /*#ifndef __HALHWOUTSRC_H__*/
diff --git a/drivers/staging/rtlwifi/phydm/phydm_interface.c b/drivers/staging/rtlwifi/phydm/phydm_interface.c
new file mode 100644
index 0000000..102576a
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_interface.c
@@ -0,0 +1,341 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+/* ************************************************************
+ * include files
+ * *************************************************************/
+
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+/*
+ * ODM IO Relative API.
+ */
+
+u8 odm_read_1byte(struct phy_dm_struct *dm, u32 reg_addr)
+{
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
+
+ return rtl_read_byte(rtlpriv, reg_addr);
+}
+
+u16 odm_read_2byte(struct phy_dm_struct *dm, u32 reg_addr)
+{
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
+
+ return rtl_read_word(rtlpriv, reg_addr);
+}
+
+u32 odm_read_4byte(struct phy_dm_struct *dm, u32 reg_addr)
+{
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
+
+ return rtl_read_dword(rtlpriv, reg_addr);
+}
+
+void odm_write_1byte(struct phy_dm_struct *dm, u32 reg_addr, u8 data)
+{
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
+
+ rtl_write_byte(rtlpriv, reg_addr, data);
+}
+
+void odm_write_2byte(struct phy_dm_struct *dm, u32 reg_addr, u16 data)
+{
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
+
+ rtl_write_word(rtlpriv, reg_addr, data);
+}
+
+void odm_write_4byte(struct phy_dm_struct *dm, u32 reg_addr, u32 data)
+{
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
+
+ rtl_write_dword(rtlpriv, reg_addr, data);
+}
+
+void odm_set_mac_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask,
+ u32 data)
+{
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
+
+ rtl_set_bbreg(rtlpriv->hw, reg_addr, bit_mask, data);
+}
+
+u32 odm_get_mac_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask)
+{
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
+
+ return rtl_get_bbreg(rtlpriv->hw, reg_addr, bit_mask);
+}
+
+void odm_set_bb_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask,
+ u32 data)
+{
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
+
+ rtl_set_bbreg(rtlpriv->hw, reg_addr, bit_mask, data);
+}
+
+u32 odm_get_bb_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask)
+{
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
+
+ return rtl_get_bbreg(rtlpriv->hw, reg_addr, bit_mask);
+}
+
+void odm_set_rf_reg(struct phy_dm_struct *dm, enum odm_rf_radio_path e_rf_path,
+ u32 reg_addr, u32 bit_mask, u32 data)
+{
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
+
+ rtl_set_rfreg(rtlpriv->hw, (enum radio_path)e_rf_path, reg_addr,
+ bit_mask, data);
+}
+
+u32 odm_get_rf_reg(struct phy_dm_struct *dm, enum odm_rf_radio_path e_rf_path,
+ u32 reg_addr, u32 bit_mask)
+{
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
+
+ return rtl_get_rfreg(rtlpriv->hw, (enum radio_path)e_rf_path, reg_addr,
+ bit_mask);
+}
+
+/*
+ * ODM Memory relative API.
+ */
+void odm_allocate_memory(struct phy_dm_struct *dm, void **ptr, u32 length)
+{
+ *ptr = kmalloc(length, GFP_ATOMIC);
+}
+
+/* length could be ignored, used to detect memory leakage. */
+void odm_free_memory(struct phy_dm_struct *dm, void *ptr, u32 length)
+{
+ kfree(ptr);
+}
+
+void odm_move_memory(struct phy_dm_struct *dm, void *p_dest, void *src,
+ u32 length)
+{
+ memcpy(p_dest, src, length);
+}
+
+void odm_memory_set(struct phy_dm_struct *dm, void *pbuf, s8 value, u32 length)
+{
+ memset(pbuf, value, length);
+}
+
+s32 odm_compare_memory(struct phy_dm_struct *dm, void *p_buf1, void *buf2,
+ u32 length)
+{
+ return memcmp(p_buf1, buf2, length);
+}
+
+/*
+ * ODM MISC relative API.
+ */
+void odm_acquire_spin_lock(struct phy_dm_struct *dm, enum rt_spinlock_type type)
+{
+}
+
+void odm_release_spin_lock(struct phy_dm_struct *dm, enum rt_spinlock_type type)
+{
+}
+
+/*
+ * ODM Timer relative API.
+ */
+void odm_stall_execution(u32 us_delay) { udelay(us_delay); }
+
+void ODM_delay_ms(u32 ms) { mdelay(ms); }
+
+void ODM_delay_us(u32 us) { udelay(us); }
+
+void ODM_sleep_ms(u32 ms) { msleep(ms); }
+
+void ODM_sleep_us(u32 us) { usleep_range(us, us + 1); }
+
+void odm_set_timer(struct phy_dm_struct *dm, struct timer_list *timer,
+ u32 ms_delay)
+{
+ mod_timer(timer, jiffies + msecs_to_jiffies(ms_delay));
+}
+
+void odm_initialize_timer(struct phy_dm_struct *dm, struct timer_list *timer,
+ void *call_back_func, void *context,
+ const char *sz_id)
+{
+ init_timer(timer);
+ timer->function = call_back_func;
+ timer->data = (unsigned long)dm;
+ /*mod_timer(timer, jiffies+RTL_MILISECONDS_TO_JIFFIES(10)); */
+}
+
+void odm_cancel_timer(struct phy_dm_struct *dm, struct timer_list *timer)
+{
+ del_timer(timer);
+}
+
+void odm_release_timer(struct phy_dm_struct *dm, struct timer_list *timer) {}
+
+static u8 phydm_trans_h2c_id(struct phy_dm_struct *dm, u8 phydm_h2c_id)
+{
+ u8 platform_h2c_id = phydm_h2c_id;
+
+ switch (phydm_h2c_id) {
+ /* 1 [0] */
+ case ODM_H2C_RSSI_REPORT:
+
+ break;
+
+ /* 1 [3] */
+ case ODM_H2C_WIFI_CALIBRATION:
+
+ break;
+
+ /* 1 [4] */
+ case ODM_H2C_IQ_CALIBRATION:
+
+ break;
+ /* 1 [5] */
+ case ODM_H2C_RA_PARA_ADJUST:
+
+ break;
+
+ /* 1 [6] */
+ case PHYDM_H2C_DYNAMIC_TX_PATH:
+
+ break;
+
+ /* [7]*/
+ case PHYDM_H2C_FW_TRACE_EN:
+
+ platform_h2c_id = 0x49;
+
+ break;
+
+ case PHYDM_H2C_TXBF:
+ break;
+
+ case PHYDM_H2C_MU:
+ platform_h2c_id = 0x4a; /*H2C_MU*/
+ break;
+
+ default:
+ platform_h2c_id = phydm_h2c_id;
+ break;
+ }
+
+ return platform_h2c_id;
+}
+
+/*ODM FW relative API.*/
+
+void odm_fill_h2c_cmd(struct phy_dm_struct *dm, u8 phydm_h2c_id, u32 cmd_len,
+ u8 *cmd_buffer)
+{
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
+ u8 platform_h2c_id;
+
+ platform_h2c_id = phydm_trans_h2c_id(dm, phydm_h2c_id);
+
+ ODM_RT_TRACE(dm, PHYDM_COMP_RA_DBG,
+ "[H2C] platform_h2c_id = ((0x%x))\n", platform_h2c_id);
+
+ rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->hw, platform_h2c_id, cmd_len,
+ cmd_buffer);
+}
+
+u8 phydm_c2H_content_parsing(void *dm_void, u8 c2h_cmd_id, u8 c2h_cmd_len,
+ u8 *tmp_buf)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u8 extend_c2h_sub_id = 0;
+ u8 find_c2h_cmd = true;
+
+ switch (c2h_cmd_id) {
+ case PHYDM_C2H_DBG:
+ phydm_fw_trace_handler(dm, tmp_buf, c2h_cmd_len);
+ break;
+
+ case PHYDM_C2H_RA_RPT:
+ phydm_c2h_ra_report_handler(dm, tmp_buf, c2h_cmd_len);
+ break;
+
+ case PHYDM_C2H_RA_PARA_RPT:
+ odm_c2h_ra_para_report_handler(dm, tmp_buf, c2h_cmd_len);
+ break;
+
+ case PHYDM_C2H_DYNAMIC_TX_PATH_RPT:
+ break;
+
+ case PHYDM_C2H_IQK_FINISH:
+ break;
+
+ case PHYDM_C2H_DBG_CODE:
+ phydm_fw_trace_handler_code(dm, tmp_buf, c2h_cmd_len);
+ break;
+
+ case PHYDM_C2H_EXTEND:
+ extend_c2h_sub_id = tmp_buf[0];
+ if (extend_c2h_sub_id == PHYDM_EXTEND_C2H_DBG_PRINT)
+ phydm_fw_trace_handler_8051(dm, tmp_buf, c2h_cmd_len);
+
+ break;
+
+ default:
+ find_c2h_cmd = false;
+ break;
+ }
+
+ return find_c2h_cmd;
+}
+
+u64 odm_get_current_time(struct phy_dm_struct *dm) { return jiffies; }
+
+u64 odm_get_progressing_time(struct phy_dm_struct *dm, u64 start_time)
+{
+ return jiffies_to_msecs(jiffies - (u32)start_time);
+}
+
+void odm_set_tx_power_index_by_rate_section(struct phy_dm_struct *dm,
+ u8 rf_path, u8 channel,
+ u8 rate_section)
+{
+ void *adapter = dm->adapter;
+
+ phy_set_tx_power_index_by_rs(adapter, channel, rf_path, rate_section);
+}
+
+u8 odm_get_tx_power_index(struct phy_dm_struct *dm, u8 rf_path, u8 tx_rate,
+ u8 band_width, u8 channel)
+{
+ void *adapter = dm->adapter;
+
+ return phy_get_tx_power_index(adapter, (enum odm_rf_radio_path)rf_path,
+ tx_rate, band_width, channel);
+}
diff --git a/drivers/staging/rtlwifi/phydm/phydm_interface.h b/drivers/staging/rtlwifi/phydm/phydm_interface.h
new file mode 100644
index 0000000..d315c79
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_interface.h
@@ -0,0 +1,205 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __ODM_INTERFACE_H__
+#define __ODM_INTERFACE_H__
+
+#define INTERFACE_VERSION "1.1" /*2015.07.29 YuChen*/
+
+/*
+ * =========== Constant/Structure/Enum/... Define
+ */
+
+/*
+ * =========== Macro Define
+ */
+
+#define _reg_all(_name) ODM_##_name
+#define _reg_ic(_name, _ic) ODM_##_name##_ic
+#define _bit_all(_name) BIT_##_name
+#define _bit_ic(_name, _ic) BIT_##_name##_ic
+
+/* _cat: implemented by Token-Pasting Operator. */
+
+/*===================================
+ *
+ * #define ODM_REG_DIG_11N 0xC50
+ * #define ODM_REG_DIG_11AC 0xDDD
+ *
+ * ODM_REG(DIG,_pdm_odm)
+ * ===================================
+ */
+
+#define _reg_11N(_name) ODM_REG_##_name##_11N
+#define _reg_11AC(_name) ODM_REG_##_name##_11AC
+#define _bit_11N(_name) ODM_BIT_##_name##_11N
+#define _bit_11AC(_name) ODM_BIT_##_name##_11AC
+
+#define _cat(_name, _ic_type, _func) \
+ (((_ic_type) & ODM_IC_11N_SERIES) ? _func##_11N(_name) : \
+ _func##_11AC(_name))
+
+/* _name: name of register or bit.
+ * Example: "ODM_REG(R_A_AGC_CORE1, dm)"
+ * gets "ODM_R_A_AGC_CORE1" or "ODM_R_A_AGC_CORE1_8192C",
+ * depends on support_ic_type.
+ */
+#define ODM_REG(_name, _pdm_odm) _cat(_name, _pdm_odm->support_ic_type, _reg)
+#define ODM_BIT(_name, _pdm_odm) _cat(_name, _pdm_odm->support_ic_type, _bit)
+enum phydm_h2c_cmd {
+ PHYDM_H2C_TXBF = 0x41,
+ ODM_H2C_RSSI_REPORT = 0x42,
+ ODM_H2C_IQ_CALIBRATION = 0x45,
+ ODM_H2C_RA_PARA_ADJUST = 0x47,
+ PHYDM_H2C_DYNAMIC_TX_PATH = 0x48,
+ PHYDM_H2C_FW_TRACE_EN = 0x49,
+ ODM_H2C_WIFI_CALIBRATION = 0x6d,
+ PHYDM_H2C_MU = 0x4a,
+ ODM_MAX_H2CCMD
+};
+
+enum phydm_c2h_evt {
+ PHYDM_C2H_DBG = 0,
+ PHYDM_C2H_LB = 1,
+ PHYDM_C2H_XBF = 2,
+ PHYDM_C2H_TX_REPORT = 3,
+ PHYDM_C2H_INFO = 9,
+ PHYDM_C2H_BT_MP = 11,
+ PHYDM_C2H_RA_RPT = 12,
+ PHYDM_C2H_RA_PARA_RPT = 14,
+ PHYDM_C2H_DYNAMIC_TX_PATH_RPT = 15,
+ PHYDM_C2H_IQK_FINISH = 17, /*0x11*/
+ PHYDM_C2H_DBG_CODE = 0xFE,
+ PHYDM_C2H_EXTEND = 0xFF,
+};
+
+enum phydm_extend_c2h_evt {
+ PHYDM_EXTEND_C2H_DBG_PRINT = 0
+
+};
+
+/*
+ * =========== Extern Variable ??? It should be forbidden.
+ */
+
+/*
+ * =========== EXtern Function Prototype
+ */
+
+u8 odm_read_1byte(struct phy_dm_struct *dm, u32 reg_addr);
+
+u16 odm_read_2byte(struct phy_dm_struct *dm, u32 reg_addr);
+
+u32 odm_read_4byte(struct phy_dm_struct *dm, u32 reg_addr);
+
+void odm_write_1byte(struct phy_dm_struct *dm, u32 reg_addr, u8 data);
+
+void odm_write_2byte(struct phy_dm_struct *dm, u32 reg_addr, u16 data);
+
+void odm_write_4byte(struct phy_dm_struct *dm, u32 reg_addr, u32 data);
+
+void odm_set_mac_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask,
+ u32 data);
+
+u32 odm_get_mac_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask);
+
+void odm_set_bb_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask,
+ u32 data);
+
+u32 odm_get_bb_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask);
+
+void odm_set_rf_reg(struct phy_dm_struct *dm, enum odm_rf_radio_path e_rf_path,
+ u32 reg_addr, u32 bit_mask, u32 data);
+
+u32 odm_get_rf_reg(struct phy_dm_struct *dm, enum odm_rf_radio_path e_rf_path,
+ u32 reg_addr, u32 bit_mask);
+
+/*
+ * Memory Relative Function.
+ */
+void odm_allocate_memory(struct phy_dm_struct *dm, void **ptr, u32 length);
+void odm_free_memory(struct phy_dm_struct *dm, void *ptr, u32 length);
+
+void odm_move_memory(struct phy_dm_struct *dm, void *p_dest, void *src,
+ u32 length);
+
+s32 odm_compare_memory(struct phy_dm_struct *dm, void *p_buf1, void *buf2,
+ u32 length);
+
+void odm_memory_set(struct phy_dm_struct *dm, void *pbuf, s8 value, u32 length);
+
+/*
+ * ODM MISC-spin lock relative API.
+ */
+void odm_acquire_spin_lock(struct phy_dm_struct *dm,
+ enum rt_spinlock_type type);
+
+void odm_release_spin_lock(struct phy_dm_struct *dm,
+ enum rt_spinlock_type type);
+
+/*
+ * ODM Timer relative API.
+ */
+void odm_stall_execution(u32 us_delay);
+
+void ODM_delay_ms(u32 ms);
+
+void ODM_delay_us(u32 us);
+
+void ODM_sleep_ms(u32 ms);
+
+void ODM_sleep_us(u32 us);
+
+void odm_set_timer(struct phy_dm_struct *dm, struct timer_list *timer,
+ u32 ms_delay);
+
+void odm_initialize_timer(struct phy_dm_struct *dm, struct timer_list *timer,
+ void *call_back_func, void *context,
+ const char *sz_id);
+
+void odm_cancel_timer(struct phy_dm_struct *dm, struct timer_list *timer);
+
+void odm_release_timer(struct phy_dm_struct *dm, struct timer_list *timer);
+
+/*
+ * ODM FW relative API.
+ */
+void odm_fill_h2c_cmd(struct phy_dm_struct *dm, u8 element_id, u32 cmd_len,
+ u8 *cmd_buffer);
+
+u8 phydm_c2H_content_parsing(void *dm_void, u8 c2h_cmd_id, u8 c2h_cmd_len,
+ u8 *tmp_buf);
+
+u64 odm_get_current_time(struct phy_dm_struct *dm);
+u64 odm_get_progressing_time(struct phy_dm_struct *dm, u64 start_time);
+
+void odm_set_tx_power_index_by_rate_section(struct phy_dm_struct *dm,
+ u8 rf_path, u8 channel,
+ u8 rate_section);
+
+u8 odm_get_tx_power_index(struct phy_dm_struct *dm, u8 rf_path, u8 tx_rate,
+ u8 band_width, u8 channel);
+
+#endif /* __ODM_INTERFACE_H__ */
diff --git a/drivers/staging/rtlwifi/phydm/phydm_iqk.h b/drivers/staging/rtlwifi/phydm/phydm_iqk.h
new file mode 100644
index 0000000..0d45bf0
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_iqk.h
@@ -0,0 +1,76 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __PHYDMIQK_H__
+#define __PHYDMIQK_H__
+
+/*--------------------------Define Parameters-------------------------------*/
+#define LOK_delay 1
+#define WBIQK_delay 10
+#define TX_IQK 0
+#define RX_IQK 1
+#define TXIQK 0
+#define RXIQK1 1
+#define RXIQK2 2
+#define GSRXK1 0
+#define GSRXK2 1
+#define kcount_limit_80m 2
+#define kcount_limit_others 4
+#define rxiqk_gs_limit 4
+
+#define NUM 4
+/*----------------------End Define Parameters-------------------------------*/
+
+struct dm_iqk_info {
+ bool lok_fail[NUM];
+ bool iqk_fail[2][NUM];
+ u32 iqc_matrix[2][NUM];
+ u8 iqk_times;
+ u32 rf_reg18;
+ u32 lna_idx;
+ u8 rxiqk_step;
+ u8 tmp1bcc;
+ u8 kcount;
+
+ u32 iqk_channel[2];
+ bool iqk_fail_report[2][4][2]; /*channel/path/TRX(TX:0, RX:1) */
+ u32 iqk_cfir_real[2][4][2]
+ [8]; /*channel / path / TRX(TX:0, RX:1) / CFIR_real*/
+ u32 iqk_cfir_imag[2][4][2]
+ [8]; /*channel / path / TRX(TX:0, RX:1) / CFIR_imag*/
+ u8 retry_count[2][4][3]; /* channel / path / (TXK:0, RXK1:1, RXK2:2) */
+ u8 gs_retry_count[2][4][2]; /* channel / path / (GSRXK1:0, GSRXK2:1) */
+ u8 rxiqk_fail_code[2][4]; /* channel / path
+ * 0:SRXK1 fail, 1:RXK1 fail 2:RXK2 fail
+ */
+ u32 lok_idac[2][4]; /*channel / path*/
+ u16 rxiqk_agc[2][4]; /*channel / path*/
+ u32 bypass_iqk[2][4]; /*channel / 0xc94/0xe94*/
+ u32 tmp_gntwl;
+ bool is_btg;
+ bool isbnd;
+};
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/phydm_kfree.c b/drivers/staging/rtlwifi/phydm/phydm_kfree.c
new file mode 100644
index 0000000..5f35823
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_kfree.c
@@ -0,0 +1,228 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+/*============================================================*/
+/*include files*/
+/*============================================================*/
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+/*<YuChen, 150720> Add for KFree Feature Requested by RF David.*/
+/*This is a phydm API*/
+
+static void phydm_set_kfree_to_rf_8814a(void *dm_void, u8 e_rf_path, u8 data)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
+ bool is_odd;
+
+ if ((data % 2) != 0) { /*odd->positive*/
+ data = data - 1;
+ odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(19),
+ 1);
+ is_odd = true;
+ } else { /*even->negative*/
+ odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(19),
+ 0);
+ is_odd = false;
+ }
+ ODM_RT_TRACE(dm, ODM_COMP_MP, "%s(): RF_0x55[19]= %d\n", __func__,
+ is_odd);
+ switch (data) {
+ case 0:
+ odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
+ 0);
+ odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
+ BIT(17) | BIT(16) | BIT(15), 0);
+ cali_info->kfree_offset[e_rf_path] = 0;
+ break;
+ case 2:
+ odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
+ 1);
+ odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
+ BIT(17) | BIT(16) | BIT(15), 0);
+ cali_info->kfree_offset[e_rf_path] = 0;
+ break;
+ case 4:
+ odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
+ 0);
+ odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
+ BIT(17) | BIT(16) | BIT(15), 1);
+ cali_info->kfree_offset[e_rf_path] = 1;
+ break;
+ case 6:
+ odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
+ 1);
+ odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
+ BIT(17) | BIT(16) | BIT(15), 1);
+ cali_info->kfree_offset[e_rf_path] = 1;
+ break;
+ case 8:
+ odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
+ 0);
+ odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
+ BIT(17) | BIT(16) | BIT(15), 2);
+ cali_info->kfree_offset[e_rf_path] = 2;
+ break;
+ case 10:
+ odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
+ 1);
+ odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
+ BIT(17) | BIT(16) | BIT(15), 2);
+ cali_info->kfree_offset[e_rf_path] = 2;
+ break;
+ case 12:
+ odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
+ 0);
+ odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
+ BIT(17) | BIT(16) | BIT(15), 3);
+ cali_info->kfree_offset[e_rf_path] = 3;
+ break;
+ case 14:
+ odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
+ 1);
+ odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
+ BIT(17) | BIT(16) | BIT(15), 3);
+ cali_info->kfree_offset[e_rf_path] = 3;
+ break;
+ case 16:
+ odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
+ 0);
+ odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
+ BIT(17) | BIT(16) | BIT(15), 4);
+ cali_info->kfree_offset[e_rf_path] = 4;
+ break;
+ case 18:
+ odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
+ 1);
+ odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
+ BIT(17) | BIT(16) | BIT(15), 4);
+ cali_info->kfree_offset[e_rf_path] = 4;
+ break;
+ case 20:
+ odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
+ 0);
+ odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
+ BIT(17) | BIT(16) | BIT(15), 5);
+ cali_info->kfree_offset[e_rf_path] = 5;
+ break;
+
+ default:
+ break;
+ }
+
+ if (!is_odd) {
+ /*that means Kfree offset is negative, we need to record it.*/
+ cali_info->kfree_offset[e_rf_path] =
+ (-1) * cali_info->kfree_offset[e_rf_path];
+ ODM_RT_TRACE(dm, ODM_COMP_MP, "%s(): kfree_offset = %d\n",
+ __func__, cali_info->kfree_offset[e_rf_path]);
+ } else {
+ ODM_RT_TRACE(dm, ODM_COMP_MP, "%s(): kfree_offset = %d\n",
+ __func__, cali_info->kfree_offset[e_rf_path]);
+ }
+}
+
+static void phydm_set_kfree_to_rf(void *dm_void, u8 e_rf_path, u8 data)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ if (dm->support_ic_type & ODM_RTL8814A)
+ phydm_set_kfree_to_rf_8814a(dm, e_rf_path, data);
+}
+
+void phydm_config_kfree(void *dm_void, u8 channel_to_sw, u8 *kfree_table)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
+ u8 rfpath = 0, max_rf_path = 0;
+ u8 channel_idx = 0;
+
+ if (dm->support_ic_type & ODM_RTL8814A)
+ max_rf_path = 4; /*0~3*/
+ else if (dm->support_ic_type &
+ (ODM_RTL8812 | ODM_RTL8192E | ODM_RTL8822B))
+ max_rf_path = 2; /*0~1*/
+ else
+ max_rf_path = 1;
+
+ ODM_RT_TRACE(dm, ODM_COMP_MP, "===>%s()\n", __func__);
+
+ if (cali_info->reg_rf_kfree_enable == 2) {
+ ODM_RT_TRACE(dm, ODM_COMP_MP,
+ "%s(): reg_rf_kfree_enable == 2, Disable\n",
+ __func__);
+ return;
+ }
+
+ if (cali_info->reg_rf_kfree_enable != 1 &&
+ cali_info->reg_rf_kfree_enable != 0) {
+ ODM_RT_TRACE(dm, ODM_COMP_MP, "<===%s()\n", __func__);
+ return;
+ }
+
+ ODM_RT_TRACE(dm, ODM_COMP_MP, "%s(): reg_rf_kfree_enable == true\n",
+ __func__);
+ /*Make sure the targetval is defined*/
+ if (((cali_info->reg_rf_kfree_enable == 1) &&
+ (kfree_table[0] != 0xFF)) ||
+ cali_info->rf_kfree_enable) {
+ /*if kfree_table[0] == 0xff, means no Kfree*/
+ if (*dm->band_type == ODM_BAND_2_4G) {
+ if (channel_to_sw <= 14 && channel_to_sw >= 1)
+ channel_idx = PHYDM_2G;
+ } else if (*dm->band_type == ODM_BAND_5G) {
+ if (channel_to_sw >= 36 && channel_to_sw <= 48)
+ channel_idx = PHYDM_5GLB1;
+ if (channel_to_sw >= 52 && channel_to_sw <= 64)
+ channel_idx = PHYDM_5GLB2;
+ if (channel_to_sw >= 100 && channel_to_sw <= 120)
+ channel_idx = PHYDM_5GMB1;
+ if (channel_to_sw >= 124 && channel_to_sw <= 144)
+ channel_idx = PHYDM_5GMB2;
+ if (channel_to_sw >= 149 && channel_to_sw <= 177)
+ channel_idx = PHYDM_5GHB;
+ }
+
+ for (rfpath = ODM_RF_PATH_A; rfpath < max_rf_path; rfpath++) {
+ ODM_RT_TRACE(dm, ODM_COMP_MP, "%s(): PATH_%d: %#x\n",
+ __func__, rfpath,
+ kfree_table[channel_idx * max_rf_path +
+ rfpath]);
+ phydm_set_kfree_to_rf(
+ dm, rfpath,
+ kfree_table[channel_idx * max_rf_path +
+ rfpath]);
+ }
+ } else {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_MP,
+ "%s(): targetval not defined, Don't execute KFree Process.\n",
+ __func__);
+ return;
+ }
+
+ ODM_RT_TRACE(dm, ODM_COMP_MP, "<===%s()\n", __func__);
+}
diff --git a/drivers/staging/rtlwifi/phydm/phydm_kfree.h b/drivers/staging/rtlwifi/phydm/phydm_kfree.h
new file mode 100644
index 0000000..1ee6005
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_kfree.h
@@ -0,0 +1,42 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __PHYDMKFREE_H__
+#define __PHYDKFREE_H__
+
+#define KFREE_VERSION "1.0"
+
+enum phydm_kfree_channeltosw {
+ PHYDM_2G = 0,
+ PHYDM_5GLB1 = 1,
+ PHYDM_5GLB2 = 2,
+ PHYDM_5GMB1 = 3,
+ PHYDM_5GMB2 = 4,
+ PHYDM_5GHB = 5,
+};
+
+void phydm_config_kfree(void *dm_void, u8 channel_to_sw, u8 *kfree_table);
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/phydm_noisemonitor.c b/drivers/staging/rtlwifi/phydm/phydm_noisemonitor.c
new file mode 100644
index 0000000..8d79a5a
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_noisemonitor.c
@@ -0,0 +1,330 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+/* ************************************************************
+ * include files
+ * *************************************************************/
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+#include "phydm_noisemonitor.h"
+
+/* *************************************************
+ * This function is for inband noise test utility only
+ * To obtain the inband noise level(dbm), do the following.
+ * 1. disable DIG and Power Saving
+ * 2. Set initial gain = 0x1a
+ * 3. Stop updating idle time pwer report (for driver read)
+ * - 0x80c[25]
+ *
+ * **************************************************/
+
+#define VALID_MIN -35
+#define VALID_MAX 10
+#define VALID_CNT 5
+
+static inline void phydm_set_noise_data_sum(struct noise_level *noise_data,
+ u8 max_rf_path)
+{
+ u8 rf_path;
+
+ for (rf_path = ODM_RF_PATH_A; rf_path < max_rf_path; rf_path++) {
+ if (noise_data->valid_cnt[rf_path])
+ noise_data->sum[rf_path] /=
+ noise_data->valid_cnt[rf_path];
+ else
+ noise_data->sum[rf_path] = 0;
+ }
+}
+
+static s16 odm_inband_noise_monitor_n_series(struct phy_dm_struct *dm,
+ u8 is_pause_dig, u8 igi_value,
+ u32 max_time)
+{
+ u32 tmp4b;
+ u8 max_rf_path = 0, rf_path;
+ u8 reg_c50, reg_c58, valid_done = 0;
+ struct noise_level noise_data;
+ u64 start = 0, func_start = 0, func_end = 0;
+
+ func_start = odm_get_current_time(dm);
+ dm->noise_level.noise_all = 0;
+
+ if ((dm->rf_type == ODM_1T2R) || (dm->rf_type == ODM_2T2R))
+ max_rf_path = 2;
+ else
+ max_rf_path = 1;
+
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON, "%s() ==>\n", __func__);
+
+ odm_memory_set(dm, &noise_data, 0, sizeof(struct noise_level));
+
+ /* */
+ /* step 1. Disable DIG && Set initial gain. */
+ /* */
+
+ if (is_pause_dig)
+ odm_pause_dig(dm, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_1, igi_value);
+ /* */
+ /* step 2. Disable all power save for read registers */
+ /* */
+ /* dcmd_DebugControlPowerSave(adapter, PSDisable); */
+
+ /* */
+ /* step 3. Get noise power level */
+ /* */
+ start = odm_get_current_time(dm);
+ while (1) {
+ /* Stop updating idle time pwer report (for driver read) */
+ odm_set_bb_reg(dm, REG_FPGA0_TX_GAIN_STAGE, BIT(25), 1);
+
+ /* Read Noise Floor Report */
+ tmp4b = odm_get_bb_reg(dm, 0x8f8, MASKDWORD);
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON,
+ "Noise Floor Report (0x8f8) = 0x%08x\n", tmp4b);
+
+ /* update idle time pwer report per 5us */
+ odm_set_bb_reg(dm, REG_FPGA0_TX_GAIN_STAGE, BIT(25), 0);
+
+ noise_data.value[ODM_RF_PATH_A] = (u8)(tmp4b & 0xff);
+ noise_data.value[ODM_RF_PATH_B] = (u8)((tmp4b & 0xff00) >> 8);
+
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON,
+ "value_a = 0x%x(%d), value_b = 0x%x(%d)\n",
+ noise_data.value[ODM_RF_PATH_A],
+ noise_data.value[ODM_RF_PATH_A],
+ noise_data.value[ODM_RF_PATH_B],
+ noise_data.value[ODM_RF_PATH_B]);
+
+ for (rf_path = ODM_RF_PATH_A; rf_path < max_rf_path;
+ rf_path++) {
+ noise_data.sval[rf_path] =
+ (s8)noise_data.value[rf_path];
+ noise_data.sval[rf_path] /= 2;
+ }
+
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON, "sval_a = %d, sval_b = %d\n",
+ noise_data.sval[ODM_RF_PATH_A],
+ noise_data.sval[ODM_RF_PATH_B]);
+
+ for (rf_path = ODM_RF_PATH_A; rf_path < max_rf_path;
+ rf_path++) {
+ if (!(noise_data.valid_cnt[rf_path] < VALID_CNT) ||
+ !(noise_data.sval[rf_path] < VALID_MAX &&
+ noise_data.sval[rf_path] >= VALID_MIN)) {
+ continue;
+ }
+
+ noise_data.valid_cnt[rf_path]++;
+ noise_data.sum[rf_path] += noise_data.sval[rf_path];
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON,
+ "rf_path:%d Valid sval = %d\n", rf_path,
+ noise_data.sval[rf_path]);
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON, "Sum of sval = %d,\n",
+ noise_data.sum[rf_path]);
+ if (noise_data.valid_cnt[rf_path] == VALID_CNT) {
+ valid_done++;
+ ODM_RT_TRACE(
+ dm, ODM_COMP_COMMON,
+ "After divided, rf_path:%d,sum = %d\n",
+ rf_path, noise_data.sum[rf_path]);
+ }
+ }
+
+ if ((valid_done == max_rf_path) ||
+ (odm_get_progressing_time(dm, start) > max_time)) {
+ phydm_set_noise_data_sum(&noise_data, max_rf_path);
+ break;
+ }
+ }
+ reg_c50 = (u8)odm_get_bb_reg(dm, REG_OFDM_0_XA_AGC_CORE1, MASKBYTE0);
+ reg_c50 &= ~BIT(7);
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON, "0x%x = 0x%02x(%d)\n",
+ REG_OFDM_0_XA_AGC_CORE1, reg_c50, reg_c50);
+ dm->noise_level.noise[ODM_RF_PATH_A] =
+ (u8)(-110 + reg_c50 + noise_data.sum[ODM_RF_PATH_A]);
+ dm->noise_level.noise_all += dm->noise_level.noise[ODM_RF_PATH_A];
+
+ if (max_rf_path == 2) {
+ reg_c58 = (u8)odm_get_bb_reg(dm, REG_OFDM_0_XB_AGC_CORE1,
+ MASKBYTE0);
+ reg_c58 &= ~BIT(7);
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON, "0x%x = 0x%02x(%d)\n",
+ REG_OFDM_0_XB_AGC_CORE1, reg_c58, reg_c58);
+ dm->noise_level.noise[ODM_RF_PATH_B] =
+ (u8)(-110 + reg_c58 + noise_data.sum[ODM_RF_PATH_B]);
+ dm->noise_level.noise_all +=
+ dm->noise_level.noise[ODM_RF_PATH_B];
+ }
+ dm->noise_level.noise_all /= max_rf_path;
+
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON, "noise_a = %d, noise_b = %d\n",
+ dm->noise_level.noise[ODM_RF_PATH_A],
+ dm->noise_level.noise[ODM_RF_PATH_B]);
+
+ /* */
+ /* step 4. Recover the Dig */
+ /* */
+ if (is_pause_dig)
+ odm_pause_dig(dm, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_1, igi_value);
+ func_end = odm_get_progressing_time(dm, func_start);
+
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON, "%s() <==\n", __func__);
+ return dm->noise_level.noise_all;
+}
+
+static s16 odm_inband_noise_monitor_ac_series(struct phy_dm_struct *dm,
+ u8 is_pause_dig, u8 igi_value,
+ u32 max_time)
+{
+ s32 rxi_buf_anta, rxq_buf_anta; /*rxi_buf_antb, rxq_buf_antb;*/
+ s32 value32, pwdb_A = 0, sval, noise, sum;
+ bool pd_flag;
+ u8 valid_cnt;
+ u64 start = 0, func_start = 0, func_end = 0;
+
+ if (!(dm->support_ic_type & (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8814A)))
+ return 0;
+
+ func_start = odm_get_current_time(dm);
+ dm->noise_level.noise_all = 0;
+
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON, "%s() ==>\n", __func__);
+
+ /* step 1. Disable DIG && Set initial gain. */
+ if (is_pause_dig)
+ odm_pause_dig(dm, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_1, igi_value);
+
+ /* step 2. Disable all power save for read registers */
+ /*dcmd_DebugControlPowerSave(adapter, PSDisable); */
+
+ /* step 3. Get noise power level */
+ start = odm_get_current_time(dm);
+
+ /* reset counters */
+ sum = 0;
+ valid_cnt = 0;
+
+ /* step 3. Get noise power level */
+ while (1) {
+ /*Set IGI=0x1C */
+ odm_write_dig(dm, 0x1C);
+ /*stop CK320&CK88 */
+ odm_set_bb_reg(dm, 0x8B4, BIT(6), 1);
+ /*Read path-A */
+ odm_set_bb_reg(dm, 0x8FC, MASKDWORD, 0x200); /*set debug port*/
+ value32 = odm_get_bb_reg(dm, 0xFA0,
+ MASKDWORD); /*read debug port*/
+
+ rxi_buf_anta = (value32 & 0xFFC00) >>
+ 10; /*rxi_buf_anta=RegFA0[19:10]*/
+ rxq_buf_anta = value32 & 0x3FF; /*rxq_buf_anta=RegFA0[19:10]*/
+
+ pd_flag = (bool)((value32 & BIT(31)) >> 31);
+
+ /*Not in packet detection period or Tx state */
+ if ((!pd_flag) || (rxi_buf_anta != 0x200)) {
+ /*sign conversion*/
+ rxi_buf_anta = odm_sign_conversion(rxi_buf_anta, 10);
+ rxq_buf_anta = odm_sign_conversion(rxq_buf_anta, 10);
+
+ pwdb_A = odm_pwdb_conversion(
+ rxi_buf_anta * rxi_buf_anta +
+ rxq_buf_anta * rxq_buf_anta,
+ 20, 18); /*S(10,9)*S(10,9)=S(20,18)*/
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_COMMON,
+ "pwdb_A= %d dB, rxi_buf_anta= 0x%x, rxq_buf_anta= 0x%x\n",
+ pwdb_A, rxi_buf_anta & 0x3FF,
+ rxq_buf_anta & 0x3FF);
+ }
+ /*Start CK320&CK88*/
+ odm_set_bb_reg(dm, 0x8B4, BIT(6), 0);
+ /*BB Reset*/
+ odm_write_1byte(dm, 0x02, odm_read_1byte(dm, 0x02) & (~BIT(0)));
+ odm_write_1byte(dm, 0x02, odm_read_1byte(dm, 0x02) | BIT(0));
+ /*PMAC Reset*/
+ odm_write_1byte(dm, 0xB03,
+ odm_read_1byte(dm, 0xB03) & (~BIT(0)));
+ odm_write_1byte(dm, 0xB03, odm_read_1byte(dm, 0xB03) | BIT(0));
+ /*CCK Reset*/
+ if (odm_read_1byte(dm, 0x80B) & BIT(4)) {
+ odm_write_1byte(dm, 0x80B,
+ odm_read_1byte(dm, 0x80B) & (~BIT(4)));
+ odm_write_1byte(dm, 0x80B,
+ odm_read_1byte(dm, 0x80B) | BIT(4));
+ }
+
+ sval = pwdb_A;
+
+ if ((sval < 0 && sval >= -27) && (valid_cnt < VALID_CNT)) {
+ valid_cnt++;
+ sum += sval;
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON, "Valid sval = %d\n",
+ sval);
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON, "Sum of sval = %d,\n",
+ sum);
+ if ((valid_cnt >= VALID_CNT) ||
+ (odm_get_progressing_time(dm, start) > max_time)) {
+ sum /= VALID_CNT;
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON,
+ "After divided, sum = %d\n", sum);
+ break;
+ }
+ }
+ }
+
+ /*ADC backoff is 12dB,*/
+ /*Ptarget=0x1C-110=-82dBm*/
+ noise = sum + 12 + 0x1C - 110;
+
+ /*Offset*/
+ noise = noise - 3;
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON, "noise = %d\n", noise);
+ dm->noise_level.noise_all = (s16)noise;
+
+ /* step 4. Recover the Dig*/
+ if (is_pause_dig)
+ odm_pause_dig(dm, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_1, igi_value);
+
+ func_end = odm_get_progressing_time(dm, func_start);
+
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON, "%s() <==\n", __func__);
+
+ return dm->noise_level.noise_all;
+}
+
+s16 odm_inband_noise_monitor(void *dm_void, u8 is_pause_dig, u8 igi_value,
+ u32 max_time)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES)
+ return odm_inband_noise_monitor_ac_series(dm, is_pause_dig,
+ igi_value, max_time);
+ else
+ return odm_inband_noise_monitor_n_series(dm, is_pause_dig,
+ igi_value, max_time);
+}
diff --git a/drivers/staging/rtlwifi/phydm/phydm_noisemonitor.h b/drivers/staging/rtlwifi/phydm/phydm_noisemonitor.h
new file mode 100644
index 0000000..a711b79
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_noisemonitor.h
@@ -0,0 +1,46 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __ODMNOISEMONITOR_H__
+#define __ODMNOISEMONITOR_H__
+
+#define ODM_MAX_CHANNEL_NUM 38 /* 14+24 */
+struct noise_level {
+ u8 value[MAX_RF_PATH];
+ s8 sval[MAX_RF_PATH];
+
+ s32 sum[MAX_RF_PATH];
+ u8 valid[MAX_RF_PATH];
+ u8 valid_cnt[MAX_RF_PATH];
+};
+
+struct odm_noise_monitor {
+ s8 noise[MAX_RF_PATH];
+ s16 noise_all;
+};
+
+s16 odm_inband_noise_monitor(void *dm_void, u8 is_pause_dig, u8 igi_value,
+ u32 max_time);
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/phydm_powertracking_ce.c b/drivers/staging/rtlwifi/phydm/phydm_powertracking_ce.c
new file mode 100644
index 0000000..48e73eb
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_powertracking_ce.c
@@ -0,0 +1,644 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+/*============================================================ */
+/* include files */
+/*============================================================ */
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+/* ************************************************************
+ * Global var
+ * *************************************************************/
+
+u32 ofdm_swing_table[OFDM_TABLE_SIZE] = {
+ 0x7f8001fe, /* 0, +6.0dB */
+ 0x788001e2, /* 1, +5.5dB */
+ 0x71c001c7, /* 2, +5.0dB*/
+ 0x6b8001ae, /* 3, +4.5dB*/
+ 0x65400195, /* 4, +4.0dB*/
+ 0x5fc0017f, /* 5, +3.5dB*/
+ 0x5a400169, /* 6, +3.0dB*/
+ 0x55400155, /* 7, +2.5dB*/
+ 0x50800142, /* 8, +2.0dB*/
+ 0x4c000130, /* 9, +1.5dB*/
+ 0x47c0011f, /* 10, +1.0dB*/
+ 0x43c0010f, /* 11, +0.5dB*/
+ 0x40000100, /* 12, +0dB*/
+ 0x3c8000f2, /* 13, -0.5dB*/
+ 0x390000e4, /* 14, -1.0dB*/
+ 0x35c000d7, /* 15, -1.5dB*/
+ 0x32c000cb, /* 16, -2.0dB*/
+ 0x300000c0, /* 17, -2.5dB*/
+ 0x2d4000b5, /* 18, -3.0dB*/
+ 0x2ac000ab, /* 19, -3.5dB*/
+ 0x288000a2, /* 20, -4.0dB*/
+ 0x26000098, /* 21, -4.5dB*/
+ 0x24000090, /* 22, -5.0dB*/
+ 0x22000088, /* 23, -5.5dB*/
+ 0x20000080, /* 24, -6.0dB*/
+ 0x1e400079, /* 25, -6.5dB*/
+ 0x1c800072, /* 26, -7.0dB*/
+ 0x1b00006c, /* 27. -7.5dB*/
+ 0x19800066, /* 28, -8.0dB*/
+ 0x18000060, /* 29, -8.5dB*/
+ 0x16c0005b, /* 30, -9.0dB*/
+ 0x15800056, /* 31, -9.5dB*/
+ 0x14400051, /* 32, -10.0dB*/
+ 0x1300004c, /* 33, -10.5dB*/
+ 0x12000048, /* 34, -11.0dB*/
+ 0x11000044, /* 35, -11.5dB*/
+ 0x10000040, /* 36, -12.0dB*/
+};
+
+u8 cck_swing_table_ch1_ch13[CCK_TABLE_SIZE][8] = {
+ {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /* 0, +0dB */
+ {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 1, -0.5dB */
+ {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 2, -1.0dB*/
+ {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 3, -1.5dB*/
+ {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 4, -2.0dB */
+ {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 5, -2.5dB*/
+ {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 6, -3.0dB*/
+ {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 7, -3.5dB*/
+ {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 8, -4.0dB */
+ {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 9, -4.5dB*/
+ {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 10, -5.0dB */
+ {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 11, -5.5dB*/
+ {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04,
+ 0x02}, /* 12, -6.0dB <== default */
+ {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 13, -6.5dB*/
+ {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 14, -7.0dB */
+ {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 15, -7.5dB*/
+ {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */
+ {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 17, -8.5dB*/
+ {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 18, -9.0dB */
+ {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 19, -9.5dB*/
+ {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 20, -10.0dB*/
+ {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 21, -10.5dB*/
+ {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 22, -11.0dB*/
+ {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 23, -11.5dB*/
+ {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 24, -12.0dB*/
+ {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 25, -12.5dB*/
+ {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 26, -13.0dB*/
+ {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 27, -13.5dB*/
+ {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 28, -14.0dB*/
+ {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 29, -14.5dB*/
+ {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 30, -15.0dB*/
+ {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 31, -15.5dB*/
+ {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} /* 32, -16.0dB*/
+};
+
+u8 cck_swing_table_ch14[CCK_TABLE_SIZE][8] = {
+ {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, /* 0, +0dB */
+ {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 1, -0.5dB */
+ {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 2, -1.0dB */
+ {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 3, -1.5dB*/
+ {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 4, -2.0dB */
+ {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 5, -2.5dB*/
+ {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 6, -3.0dB */
+ {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 7, -3.5dB */
+ {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 8, -4.0dB */
+ {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 9, -4.5dB*/
+ {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 10, -5.0dB */
+ {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 11, -5.5dB*/
+ {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00,
+ 0x00}, /* 12, -6.0dB <== default*/
+ {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 13, -6.5dB */
+ {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 14, -7.0dB */
+ {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 15, -7.5dB*/
+ {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */
+ {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 17, -8.5dB*/
+ {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 18, -9.0dB */
+ {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 19, -9.5dB*/
+ {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 20, -10.0dB*/
+ {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 21, -10.5dB*/
+ {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 22, -11.0dB*/
+ {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 23, -11.5dB*/
+ {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 24, -12.0dB*/
+ {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 25, -12.5dB*/
+ {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 26, -13.0dB*/
+ {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 27, -13.5dB*/
+ {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 28, -14.0dB*/
+ {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 29, -14.5dB*/
+ {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 30, -15.0dB*/
+ {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 31, -15.5dB*/
+ {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} /* 32, -16.0dB*/
+};
+
+u32 ofdm_swing_table_new[OFDM_TABLE_SIZE] = {
+ 0x0b40002d, /* 0, -15.0dB */
+ 0x0c000030, /* 1, -14.5dB*/
+ 0x0cc00033, /* 2, -14.0dB*/
+ 0x0d800036, /* 3, -13.5dB*/
+ 0x0e400039, /* 4, -13.0dB */
+ 0x0f00003c, /* 5, -12.5dB*/
+ 0x10000040, /* 6, -12.0dB*/
+ 0x11000044, /* 7, -11.5dB*/
+ 0x12000048, /* 8, -11.0dB*/
+ 0x1300004c, /* 9, -10.5dB*/
+ 0x14400051, /* 10, -10.0dB*/
+ 0x15800056, /* 11, -9.5dB*/
+ 0x16c0005b, /* 12, -9.0dB*/
+ 0x18000060, /* 13, -8.5dB*/
+ 0x19800066, /* 14, -8.0dB*/
+ 0x1b00006c, /* 15, -7.5dB*/
+ 0x1c800072, /* 16, -7.0dB*/
+ 0x1e400079, /* 17, -6.5dB*/
+ 0x20000080, /* 18, -6.0dB*/
+ 0x22000088, /* 19, -5.5dB*/
+ 0x24000090, /* 20, -5.0dB*/
+ 0x26000098, /* 21, -4.5dB*/
+ 0x288000a2, /* 22, -4.0dB*/
+ 0x2ac000ab, /* 23, -3.5dB*/
+ 0x2d4000b5, /* 24, -3.0dB*/
+ 0x300000c0, /* 25, -2.5dB*/
+ 0x32c000cb, /* 26, -2.0dB*/
+ 0x35c000d7, /* 27, -1.5dB*/
+ 0x390000e4, /* 28, -1.0dB*/
+ 0x3c8000f2, /* 29, -0.5dB*/
+ 0x40000100, /* 30, +0dB*/
+ 0x43c0010f, /* 31, +0.5dB*/
+ 0x47c0011f, /* 32, +1.0dB*/
+ 0x4c000130, /* 33, +1.5dB*/
+ 0x50800142, /* 34, +2.0dB*/
+ 0x55400155, /* 35, +2.5dB*/
+ 0x5a400169, /* 36, +3.0dB*/
+ 0x5fc0017f, /* 37, +3.5dB*/
+ 0x65400195, /* 38, +4.0dB*/
+ 0x6b8001ae, /* 39, +4.5dB*/
+ 0x71c001c7, /* 40, +5.0dB*/
+ 0x788001e2, /* 41, +5.5dB*/
+ 0x7f8001fe /* 42, +6.0dB*/
+};
+
+u8 cck_swing_table_ch1_ch14_88f[CCK_TABLE_SIZE_88F][16] = {
+ {0x44, 0x42, 0x3C, 0x33, 0x28, 0x1C, 0x13, 0x0B, 0x05, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-16dB*/
+ {0x48, 0x46, 0x3F, 0x36, 0x2A, 0x1E, 0x14, 0x0B, 0x05, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/
+ {0x4D, 0x4A, 0x43, 0x39, 0x2C, 0x20, 0x15, 0x0C, 0x06, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-15dB*/
+ {0x51, 0x4F, 0x47, 0x3C, 0x2F, 0x22, 0x16, 0x0D, 0x06, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-14.5dB*/
+ {0x56, 0x53, 0x4B, 0x40, 0x32, 0x24, 0x17, 0x0E, 0x06, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-14dB*/
+ {0x5B, 0x58, 0x50, 0x43, 0x35, 0x26, 0x19, 0x0E, 0x07, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-13.5dB*/
+ {0x60, 0x5D, 0x54, 0x47, 0x38, 0x28, 0x1A, 0x0F, 0x07, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-13dB*/
+ {0x66, 0x63, 0x59, 0x4C, 0x3B, 0x2B, 0x1C, 0x10, 0x08, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-12.5dB*/
+ {0x6C, 0x69, 0x5F, 0x50, 0x3F, 0x2D, 0x1E, 0x11, 0x08, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-12dB*/
+ {0x73, 0x6F, 0x64, 0x55, 0x42, 0x30, 0x1F, 0x12, 0x08, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-11.5dB*/
+ {0x79, 0x76, 0x6A, 0x5A, 0x46, 0x33, 0x21, 0x13, 0x09, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-11dB*/
+ {0x81, 0x7C, 0x71, 0x5F, 0x4A, 0x36, 0x23, 0x14, 0x0A, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-10.5dB*/
+ {0x88, 0x84, 0x77, 0x65, 0x4F, 0x39, 0x25, 0x15, 0x0A, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-10dB*/
+ {0x90, 0x8C, 0x7E, 0x6B, 0x54, 0x3C, 0x27, 0x17, 0x0B, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-9.5dB*/
+ {0x99, 0x94, 0x86, 0x71, 0x58, 0x40, 0x2A, 0x18, 0x0B, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-9dB*/
+ {0xA2, 0x9D, 0x8E, 0x78, 0x5E, 0x43, 0x2C, 0x19, 0x0C, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-8.5dB*/
+ {0xAC, 0xA6, 0x96, 0x7F, 0x63, 0x47, 0x2F, 0x1B, 0x0D, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-8dB*/
+ {0xB6, 0xB0, 0x9F, 0x87, 0x69, 0x4C, 0x32, 0x1D, 0x0D, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-7.5dB*/
+ {0xC1, 0xBA, 0xA8, 0x8F, 0x6F, 0x50, 0x35, 0x1E, 0x0E, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-7dB*/
+ {0xCC, 0xC5, 0xB2, 0x97, 0x76, 0x55, 0x38, 0x20, 0x0F, 0x05, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-6.5dB*/
+ {0xD8, 0xD1, 0xBD, 0xA0, 0x7D, 0x5A, 0x3B, 0x22, 0x10, 0x05, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00} /*-6dB*/
+};
+
+u8 cck_swing_table_ch1_ch13_88f[CCK_TABLE_SIZE_88F][16] = {
+ {0x44, 0x42, 0x3C, 0x33, 0x28, 0x1C, 0x13, 0x0B, 0x05, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-16dB*/
+ {0x48, 0x46, 0x3F, 0x36, 0x2A, 0x1E, 0x14, 0x0B, 0x05, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/
+ {0x4D, 0x4A, 0x43, 0x39, 0x2C, 0x20, 0x15, 0x0C, 0x06, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-15dB*/
+ {0x51, 0x4F, 0x47, 0x3C, 0x2F, 0x22, 0x16, 0x0D, 0x06, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-14.5dB*/
+ {0x56, 0x53, 0x4B, 0x40, 0x32, 0x24, 0x17, 0x0E, 0x06, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-14dB*/
+ {0x5B, 0x58, 0x50, 0x43, 0x35, 0x26, 0x19, 0x0E, 0x07, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-13.5dB*/
+ {0x60, 0x5D, 0x54, 0x47, 0x38, 0x28, 0x1A, 0x0F, 0x07, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-13dB*/
+ {0x66, 0x63, 0x59, 0x4C, 0x3B, 0x2B, 0x1C, 0x10, 0x08, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-12.5dB*/
+ {0x6C, 0x69, 0x5F, 0x50, 0x3F, 0x2D, 0x1E, 0x11, 0x08, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-12dB*/
+ {0x73, 0x6F, 0x64, 0x55, 0x42, 0x30, 0x1F, 0x12, 0x08, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-11.5dB*/
+ {0x79, 0x76, 0x6A, 0x5A, 0x46, 0x33, 0x21, 0x13, 0x09, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-11dB*/
+ {0x81, 0x7C, 0x71, 0x5F, 0x4A, 0x36, 0x23, 0x14, 0x0A, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-10.5dB*/
+ {0x88, 0x84, 0x77, 0x65, 0x4F, 0x39, 0x25, 0x15, 0x0A, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-10dB*/
+ {0x90, 0x8C, 0x7E, 0x6B, 0x54, 0x3C, 0x27, 0x17, 0x0B, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-9.5dB*/
+ {0x99, 0x94, 0x86, 0x71, 0x58, 0x40, 0x2A, 0x18, 0x0B, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-9dB*/
+ {0xA2, 0x9D, 0x8E, 0x78, 0x5E, 0x43, 0x2C, 0x19, 0x0C, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-8.5dB*/
+ {0xAC, 0xA6, 0x96, 0x7F, 0x63, 0x47, 0x2F, 0x1B, 0x0D, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-8dB*/
+ {0xB6, 0xB0, 0x9F, 0x87, 0x69, 0x4C, 0x32, 0x1D, 0x0D, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-7.5dB*/
+ {0xC1, 0xBA, 0xA8, 0x8F, 0x6F, 0x50, 0x35, 0x1E, 0x0E, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-7dB*/
+ {0xCC, 0xC5, 0xB2, 0x97, 0x76, 0x55, 0x38, 0x20, 0x0F, 0x05, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-6.5dB*/
+ {0xD8, 0xD1, 0xBD, 0xA0, 0x7D, 0x5A, 0x3B, 0x22, 0x10, 0x05, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00} /*-6dB*/
+};
+
+u8 cck_swing_table_ch14_88f[CCK_TABLE_SIZE_88F][16] = {
+ {0x44, 0x42, 0x3C, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-16dB*/
+ {0x48, 0x46, 0x3F, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/
+ {0x4D, 0x4A, 0x43, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-15dB*/
+ {0x51, 0x4F, 0x47, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-14.5dB*/
+ {0x56, 0x53, 0x4B, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-14dB*/
+ {0x5B, 0x58, 0x50, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-13.5dB*/
+ {0x60, 0x5D, 0x54, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-13dB*/
+ {0x66, 0x63, 0x59, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-12.5dB*/
+ {0x6C, 0x69, 0x5F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-12dB*/
+ {0x73, 0x6F, 0x64, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-11.5dB*/
+ {0x79, 0x76, 0x6A, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-11dB*/
+ {0x81, 0x7C, 0x71, 0x4A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-10.5dB*/
+ {0x88, 0x84, 0x77, 0x4F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-10dB*/
+ {0x90, 0x8C, 0x7E, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-9.5dB*/
+ {0x99, 0x94, 0x86, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-9dB*/
+ {0xA2, 0x9D, 0x8E, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-8.5dB*/
+ {0xAC, 0xA6, 0x96, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-8dB*/
+ {0xB6, 0xB0, 0x9F, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-7.5dB*/
+ {0xC1, 0xBA, 0xA8, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-7dB*/
+ {0xCC, 0xC5, 0xB2, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}, /*-6.5dB*/
+ {0xD8, 0xD1, 0xBD, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00} /*-6dB*/
+};
+
+u8 cck_swing_table_ch1_ch13_new[CCK_TABLE_SIZE][8] = {
+ {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}, /* 0, -16.0dB*/
+ {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 1, -15.5dB*/
+ {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 2, -15.0dB*/
+ {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 3, -14.5dB*/
+ {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 4, -14.0dB*/
+ {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 5, -13.5dB*/
+ {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 6, -13.0dB*/
+ {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 7, -12.5dB*/
+ {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 8, -12.0dB*/
+ {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 9, -11.5dB*/
+ {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 10, -11.0dB*/
+ {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 11, -10.5dB*/
+ {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 12, -10.0dB*/
+ {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 13, -9.5dB*/
+ {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 14, -9.0dB */
+ {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 15, -8.5dB*/
+ {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */
+ {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 17, -7.5dB*/
+ {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 18, -7.0dB */
+ {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 19, -6.5dB*/
+ {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /*20, -6.0dB */
+ {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 21, -5.5dB*/
+ {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 22, -5.0dB */
+ {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 23, -4.5dB*/
+ {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 24, -4.0dB */
+ {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 25, -3.5dB*/
+ {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 26, -3.0dB*/
+ {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 27, -2.5dB*/
+ {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 28, -2.0dB */
+ {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 29, -1.5dB*/
+ {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 30, -1.0dB*/
+ {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 31, -0.5dB*/
+ {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04} /* 32, +0dB*/
+};
+
+u8 cck_swing_table_ch14_new[CCK_TABLE_SIZE][8] = {
+ {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}, /* 0, -16.0dB*/
+ {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 1, -15.5dB*/
+ {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 2, -15.0dB*/
+ {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 3, -14.5dB*/
+ {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 4, -14.0dB*/
+ {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /*5, -13.5dB*/
+ {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 6, -13.0dB*/
+ {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 7, -12.5dB*/
+ {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 8, -12.0dB*/
+ {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 9, -11.5dB*/
+ {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 10, -11.0dB*/
+ {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /*11, -10.5dB*/
+ {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 12, -10.0dB*/
+ {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 13, -9.5dB*/
+ {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /*14, -9.0dB */
+ {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 15, -8.5dB*/
+ {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */
+ {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 17, -7.5dB*/
+ {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 18, -7.0dB */
+ {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 19, -6.5dB */
+ {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 20, -6.0dB */
+ {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 21, -5.5dB*/
+ {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 22, -5.0dB */
+ {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /*23, -4.5dB*/
+ {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 24, -4.0dB */
+ {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 25, -3.5dB */
+ {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 26, -3.0dB */
+ {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /*27, -2.5dB*/
+ {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 28, -2.0dB */
+ {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /*29, -1.5dB*/
+ {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 30, -1.0dB */
+ {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 31, -0.5dB */
+ {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00} /* 32, +0dB */
+};
+
+u32 cck_swing_table_ch1_ch14_8723d[CCK_TABLE_SIZE_8723D] = {
+ 0x0CD, /*0 , -20dB*/
+ 0x0D9, 0x0E6, 0x0F3, 0x102, 0x111, 0x121, 0x132, 0x144, 0x158, 0x16C,
+ 0x182, 0x198, 0x1B1, 0x1CA, 0x1E5, 0x202, 0x221, 0x241, 0x263, 0x287,
+ 0x2AE, 0x2D6, 0x301, 0x32F, 0x35F, 0x392, 0x3C9, 0x402, 0x43F, 0x47F,
+ 0x4C3, 0x50C, 0x558, 0x5A9, 0x5FF, 0x65A, 0x6BA, 0x720, 0x78C, 0x7FF,
+};
+
+/* JJ ADD 20161014 */
+u32 cck_swing_table_ch1_ch14_8710b[CCK_TABLE_SIZE_8710B] = {
+ 0x0CD, /*0 , -20dB*/
+ 0x0D9, 0x0E6, 0x0F3, 0x102, 0x111, 0x121, 0x132, 0x144, 0x158, 0x16C,
+ 0x182, 0x198, 0x1B1, 0x1CA, 0x1E5, 0x202, 0x221, 0x241, 0x263, 0x287,
+ 0x2AE, 0x2D6, 0x301, 0x32F, 0x35F, 0x392, 0x3C9, 0x402, 0x43F, 0x47F,
+ 0x4C3, 0x50C, 0x558, 0x5A9, 0x5FF, 0x65A, 0x6BA, 0x720, 0x78C, 0x7FF,
+};
+
+u32 tx_scaling_table_jaguar[TXSCALE_TABLE_SIZE] = {
+ 0x081, /* 0, -12.0dB*/
+ 0x088, /* 1, -11.5dB*/
+ 0x090, /* 2, -11.0dB*/
+ 0x099, /* 3, -10.5dB*/
+ 0x0A2, /* 4, -10.0dB*/
+ 0x0AC, /* 5, -9.5dB*/
+ 0x0B6, /* 6, -9.0dB*/
+ 0x0C0, /*7, -8.5dB*/
+ 0x0CC, /* 8, -8.0dB*/
+ 0x0D8, /* 9, -7.5dB*/
+ 0x0E5, /* 10, -7.0dB*/
+ 0x0F2, /* 11, -6.5dB*/
+ 0x101, /* 12, -6.0dB*/
+ 0x110, /* 13, -5.5dB*/
+ 0x120, /* 14, -5.0dB*/
+ 0x131, /* 15, -4.5dB*/
+ 0x143, /* 16, -4.0dB*/
+ 0x156, /* 17, -3.5dB*/
+ 0x16A, /* 18, -3.0dB*/
+ 0x180, /* 19, -2.5dB*/
+ 0x197, /* 20, -2.0dB*/
+ 0x1AF, /* 21, -1.5dB*/
+ 0x1C8, /* 22, -1.0dB*/
+ 0x1E3, /* 23, -0.5dB*/
+ 0x200, /* 24, +0 dB*/
+ 0x21E, /* 25, +0.5dB*/
+ 0x23E, /* 26, +1.0dB*/
+ 0x261, /* 27, +1.5dB*/
+ 0x285, /* 28, +2.0dB*/
+ 0x2AB, /* 29, +2.5dB*/
+ 0x2D3, /*30, +3.0dB*/
+ 0x2FE, /* 31, +3.5dB*/
+ 0x32B, /* 32, +4.0dB*/
+ 0x35C, /* 33, +4.5dB*/
+ 0x38E, /* 34, +5.0dB*/
+ 0x3C4, /* 35, +5.5dB*/
+ 0x3FE /* 36, +6.0dB */
+};
+
+void odm_txpowertracking_init(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ odm_txpowertracking_thermal_meter_init(dm);
+}
+
+static u8 get_swing_index(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u8 i = 0;
+ u32 bb_swing;
+ u32 swing_table_size;
+ u32 *swing_table;
+
+ if (dm->support_ic_type == ODM_RTL8188E ||
+ dm->support_ic_type == ODM_RTL8723B ||
+ dm->support_ic_type == ODM_RTL8192E ||
+ dm->support_ic_type == ODM_RTL8188F ||
+ dm->support_ic_type == ODM_RTL8703B) {
+ bb_swing = odm_get_bb_reg(dm, REG_OFDM_0_XA_TX_IQ_IMBALANCE,
+ 0xFFC00000);
+
+ swing_table = ofdm_swing_table_new;
+ swing_table_size = OFDM_TABLE_SIZE;
+ } else {
+ {
+ bb_swing = 0;
+ swing_table = ofdm_swing_table;
+ swing_table_size = OFDM_TABLE_SIZE;
+ }
+ }
+
+ for (i = 0; i < swing_table_size; ++i) {
+ u32 table_value = swing_table[i];
+
+ if (table_value >= 0x100000)
+ table_value >>= 22;
+ if (bb_swing == table_value)
+ break;
+ }
+ return i;
+}
+
+void odm_txpowertracking_thermal_meter_init(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u8 default_swing_index = get_swing_index(dm);
+ u8 p = 0;
+ struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
+ struct rtl_efuse *rtlefu = rtl_efuse(rtlpriv);
+
+ cali_info->is_txpowertracking = true;
+ cali_info->tx_powercount = 0;
+ cali_info->is_txpowertracking_init = false;
+
+ if (!dm->mp_mode)
+ cali_info->txpowertrack_control = true;
+ else
+ cali_info->txpowertrack_control = false;
+
+ if (!dm->mp_mode)
+ cali_info->txpowertrack_control = true;
+
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, "dm txpowertrack_control = %d\n",
+ cali_info->txpowertrack_control);
+
+ /* dm->rf_calibrate_info.txpowertrack_control = true; */
+ cali_info->thermal_value = rtlefu->eeprom_thermalmeter;
+ cali_info->thermal_value_iqk = rtlefu->eeprom_thermalmeter;
+ cali_info->thermal_value_lck = rtlefu->eeprom_thermalmeter;
+
+ if (!cali_info->default_bb_swing_index_flag) {
+ /*The index of "0 dB" in SwingTable.*/
+ if (dm->support_ic_type == ODM_RTL8188E ||
+ dm->support_ic_type == ODM_RTL8723B ||
+ dm->support_ic_type == ODM_RTL8192E ||
+ dm->support_ic_type == ODM_RTL8703B) {
+ cali_info->default_ofdm_index =
+ (default_swing_index >= OFDM_TABLE_SIZE) ?
+ 30 :
+ default_swing_index;
+ cali_info->default_cck_index = 20;
+ } else if (dm->support_ic_type ==
+ ODM_RTL8188F) { /*add by Mingzhi.Guo 2015-03-23*/
+ cali_info->default_ofdm_index = 28; /*OFDM: -1dB*/
+ cali_info->default_cck_index = 20; /*CCK:-6dB*/
+ } else if (dm->support_ic_type ==
+ ODM_RTL8723D) { /*add by zhaohe 2015-10-27*/
+ cali_info->default_ofdm_index = 28; /*OFDM: -1dB*/
+ cali_info->default_cck_index = 28; /*CCK: -6dB*/
+ } else if (dm->support_ic_type ==
+ ODM_RTL8710B) { /* JJ ADD 20161014 */
+ cali_info->default_ofdm_index = 28; /*OFDM: -1dB*/
+ cali_info->default_cck_index = 28; /*CCK: -6dB*/
+ } else {
+ cali_info->default_ofdm_index =
+ (default_swing_index >= TXSCALE_TABLE_SIZE) ?
+ 24 :
+ default_swing_index;
+ cali_info->default_cck_index = 24;
+ }
+ cali_info->default_bb_swing_index_flag = true;
+ }
+
+ cali_info->bb_swing_idx_cck_base = cali_info->default_cck_index;
+ cali_info->CCK_index = cali_info->default_cck_index;
+
+ for (p = ODM_RF_PATH_A; p < MAX_RF_PATH; ++p) {
+ cali_info->bb_swing_idx_ofdm_base[p] =
+ cali_info->default_ofdm_index;
+ cali_info->OFDM_index[p] = cali_info->default_ofdm_index;
+ cali_info->delta_power_index[p] = 0;
+ cali_info->delta_power_index_last[p] = 0;
+ cali_info->power_index_offset[p] = 0;
+ }
+ cali_info->modify_tx_agc_value_ofdm = 0;
+ cali_info->modify_tx_agc_value_cck = 0;
+}
+
+void odm_txpowertracking_check(void *dm_void)
+{
+ /* 2011/09/29 MH In HW integration first stage, we provide 4 different
+ * handle to operate at the same time.
+ * In the stage2/3, we need to prive universal interface and merge all
+ * HW dynamic mechanism.
+ */
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ switch (dm->support_platform) {
+ case ODM_WIN:
+ odm_txpowertracking_check_mp(dm);
+ break;
+
+ case ODM_CE:
+ odm_txpowertracking_check_ce(dm);
+ break;
+
+ case ODM_AP:
+ odm_txpowertracking_check_ap(dm);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void odm_txpowertracking_check_ce(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ void *adapter = dm->adapter;
+
+ if (!(dm->support_ability & ODM_RF_TX_PWR_TRACK))
+ return;
+
+ if (!dm->rf_calibrate_info.tm_trigger) {
+ if (IS_HARDWARE_TYPE_8188E(adapter) ||
+ IS_HARDWARE_TYPE_8188F(adapter) ||
+ IS_HARDWARE_TYPE_8192E(adapter) ||
+ IS_HARDWARE_TYPE_8723B(adapter) ||
+ IS_HARDWARE_TYPE_JAGUAR(adapter) ||
+ IS_HARDWARE_TYPE_8814A(adapter) ||
+ IS_HARDWARE_TYPE_8703B(adapter) ||
+ IS_HARDWARE_TYPE_8723D(adapter) ||
+ IS_HARDWARE_TYPE_8822B(adapter) ||
+ IS_HARDWARE_TYPE_8821C(adapter) ||
+ (dm->support_ic_type == ODM_RTL8710B)) /* JJ ADD 20161014 */
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, RF_T_METER_NEW,
+ (BIT(17) | BIT(16)), 0x03);
+ else
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, RF_T_METER_OLD,
+ RFREGOFFSETMASK, 0x60);
+
+ dm->rf_calibrate_info.tm_trigger = 1;
+ return;
+ }
+
+ odm_txpowertracking_callback_thermal_meter(dm);
+ dm->rf_calibrate_info.tm_trigger = 0;
+}
+
+void odm_txpowertracking_check_mp(void *dm_void) {}
+
+void odm_txpowertracking_check_ap(void *dm_void) {}
diff --git a/drivers/staging/rtlwifi/phydm/phydm_powertracking_ce.h b/drivers/staging/rtlwifi/phydm/phydm_powertracking_ce.h
new file mode 100644
index 0000000..757d772
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_powertracking_ce.h
@@ -0,0 +1,293 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __PHYDMPOWERTRACKING_H__
+#define __PHYDMPOWERTRACKING_H__
+
+#define POWRTRACKING_VERSION "1.1"
+
+#define DPK_DELTA_MAPPING_NUM 13
+#define index_mapping_HP_NUM 15
+#define OFDM_TABLE_SIZE 43
+#define CCK_TABLE_SIZE 33
+#define CCK_TABLE_SIZE_88F 21
+#define TXSCALE_TABLE_SIZE 37
+#define CCK_TABLE_SIZE_8723D 41
+/* JJ ADD 20161014 */
+#define CCK_TABLE_SIZE_8710B 41
+
+#define TXPWR_TRACK_TABLE_SIZE 30
+#define DELTA_SWINGIDX_SIZE 30
+#define DELTA_SWINTSSI_SIZE 61
+#define BAND_NUM 4
+
+#define AVG_THERMAL_NUM 8
+#define HP_THERMAL_NUM 8
+#define IQK_MAC_REG_NUM 4
+#define IQK_ADDA_REG_NUM 16
+#define IQK_BB_REG_NUM_MAX 10
+
+#define IQK_BB_REG_NUM 9
+
+#define iqk_matrix_reg_num 8
+
+extern u32 ofdm_swing_table[OFDM_TABLE_SIZE];
+extern u8 cck_swing_table_ch1_ch13[CCK_TABLE_SIZE][8];
+extern u8 cck_swing_table_ch14[CCK_TABLE_SIZE][8];
+
+extern u32 ofdm_swing_table_new[OFDM_TABLE_SIZE];
+extern u8 cck_swing_table_ch1_ch13_new[CCK_TABLE_SIZE][8];
+extern u8 cck_swing_table_ch14_new[CCK_TABLE_SIZE][8];
+extern u8 cck_swing_table_ch1_ch14_88f[CCK_TABLE_SIZE_88F][16];
+extern u8 cck_swing_table_ch1_ch13_88f[CCK_TABLE_SIZE_88F][16];
+extern u8 cck_swing_table_ch14_88f[CCK_TABLE_SIZE_88F][16];
+extern u32 cck_swing_table_ch1_ch14_8723d[CCK_TABLE_SIZE_8723D];
+/* JJ ADD 20161014 */
+extern u32 cck_swing_table_ch1_ch14_8710b[CCK_TABLE_SIZE_8710B];
+
+extern u32 tx_scaling_table_jaguar[TXSCALE_TABLE_SIZE];
+
+/* <20121018, Kordan> In case fail to read TxPowerTrack.txt,
+ * we use the table of 88E as the default table.
+ */
+
+#define dm_check_txpowertracking odm_txpowertracking_check
+
+struct iqk_matrix_regs_setting {
+ bool is_iqk_done;
+ s32 value[3][iqk_matrix_reg_num];
+ bool is_bw_iqk_result_saved[3];
+};
+
+struct dm_rf_calibration_struct {
+ /* for tx power tracking */
+
+ u32 rega24; /* for TempCCK */
+ s32 rege94;
+ s32 rege9c;
+ s32 regeb4;
+ s32 regebc;
+
+ u8 tx_powercount;
+ bool is_txpowertracking_init;
+ bool is_txpowertracking;
+ /* for mp mode, turn off txpwrtracking as default */
+ u8 txpowertrack_control;
+ u8 tm_trigger;
+ u8 internal_pa_5g[2]; /* pathA / pathB */
+
+ u8 thermal_meter
+ [2]; /* thermal_meter, index 0 for RFIC0, and 1 for RFIC1 */
+ u8 thermal_value;
+ u8 thermal_value_lck;
+ u8 thermal_value_iqk;
+ s8 thermal_value_delta; /* delta of thermal_value and efuse thermal */
+ u8 thermal_value_dpk;
+ u8 thermal_value_avg[AVG_THERMAL_NUM];
+ u8 thermal_value_avg_index;
+ u8 thermal_value_rx_gain;
+ u8 thermal_value_crystal;
+ u8 thermal_value_dpk_store;
+ u8 thermal_value_dpk_track;
+ bool txpowertracking_in_progress;
+
+ bool is_reloadtxpowerindex;
+ u8 is_rf_pi_enable;
+ u32 txpowertracking_callback_cnt; /* cosa add for debug */
+
+ /* ---------------------- Tx power Tracking ------------------------- */
+ u8 is_cck_in_ch14;
+ u8 CCK_index;
+ u8 OFDM_index[MAX_RF_PATH];
+ s8 power_index_offset[MAX_RF_PATH];
+ s8 delta_power_index[MAX_RF_PATH];
+ s8 delta_power_index_last[MAX_RF_PATH];
+ bool is_tx_power_changed;
+ s8 xtal_offset;
+ s8 xtal_offset_last;
+
+ u8 thermal_value_hp[HP_THERMAL_NUM];
+ u8 thermal_value_hp_index;
+ struct iqk_matrix_regs_setting
+ iqk_matrix_reg_setting[IQK_MATRIX_SETTINGS_NUM];
+ u8 delta_lck;
+ s8 bb_swing_diff_2g, bb_swing_diff_5g; /* Unit: dB */
+ u8 delta_swing_table_idx_2g_cck_a_p[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2g_cck_a_n[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2g_cck_b_p[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2g_cck_b_n[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2g_cck_c_p[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2g_cck_c_n[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2g_cck_d_p[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2g_cck_d_n[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2ga_p[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2ga_n[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2gb_p[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2gb_n[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2gc_p[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2gc_n[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2gd_p[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2gd_n[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_5ga_p[BAND_NUM][DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_5ga_n[BAND_NUM][DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_5gb_p[BAND_NUM][DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_5gb_n[BAND_NUM][DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_5gc_p[BAND_NUM][DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_5gc_n[BAND_NUM][DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_5gd_p[BAND_NUM][DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_5gd_n[BAND_NUM][DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_tssi_table_2g_cck_a[DELTA_SWINTSSI_SIZE];
+ u8 delta_swing_tssi_table_2g_cck_b[DELTA_SWINTSSI_SIZE];
+ u8 delta_swing_tssi_table_2g_cck_c[DELTA_SWINTSSI_SIZE];
+ u8 delta_swing_tssi_table_2g_cck_d[DELTA_SWINTSSI_SIZE];
+ u8 delta_swing_tssi_table_2ga[DELTA_SWINTSSI_SIZE];
+ u8 delta_swing_tssi_table_2gb[DELTA_SWINTSSI_SIZE];
+ u8 delta_swing_tssi_table_2gc[DELTA_SWINTSSI_SIZE];
+ u8 delta_swing_tssi_table_2gd[DELTA_SWINTSSI_SIZE];
+ u8 delta_swing_tssi_table_5ga[BAND_NUM][DELTA_SWINTSSI_SIZE];
+ u8 delta_swing_tssi_table_5gb[BAND_NUM][DELTA_SWINTSSI_SIZE];
+ u8 delta_swing_tssi_table_5gc[BAND_NUM][DELTA_SWINTSSI_SIZE];
+ u8 delta_swing_tssi_table_5gd[BAND_NUM][DELTA_SWINTSSI_SIZE];
+ s8 delta_swing_table_xtal_p[DELTA_SWINGIDX_SIZE];
+ s8 delta_swing_table_xtal_n[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2ga_p_8188e[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2ga_n_8188e[DELTA_SWINGIDX_SIZE];
+
+ u8 bb_swing_idx_ofdm[MAX_RF_PATH];
+ u8 bb_swing_idx_ofdm_current;
+ u8 bb_swing_idx_ofdm_base[MAX_RF_PATH];
+ bool default_bb_swing_index_flag;
+ bool bb_swing_flag_ofdm;
+ u8 bb_swing_idx_cck;
+ u8 bb_swing_idx_cck_current;
+ u8 bb_swing_idx_cck_base;
+ u8 default_ofdm_index;
+ u8 default_cck_index;
+ bool bb_swing_flag_cck;
+
+ s8 absolute_ofdm_swing_idx[MAX_RF_PATH];
+ s8 remnant_ofdm_swing_idx[MAX_RF_PATH];
+ s8 absolute_cck_swing_idx[MAX_RF_PATH];
+ s8 remnant_cck_swing_idx;
+ s8 modify_tx_agc_value; /*Remnat compensate value at tx_agc */
+ bool modify_tx_agc_flag_path_a;
+ bool modify_tx_agc_flag_path_b;
+ bool modify_tx_agc_flag_path_c;
+ bool modify_tx_agc_flag_path_d;
+ bool modify_tx_agc_flag_path_a_cck;
+
+ s8 kfree_offset[MAX_RF_PATH];
+
+ /* ------------------------------------------------------------------ */
+
+ /* for IQK */
+ u32 regc04;
+ u32 reg874;
+ u32 regc08;
+ u32 regb68;
+ u32 regb6c;
+ u32 reg870;
+ u32 reg860;
+ u32 reg864;
+
+ bool is_iqk_initialized;
+ bool is_lck_in_progress;
+ bool is_antenna_detected;
+ bool is_need_iqk;
+ bool is_iqk_in_progress;
+ bool is_iqk_pa_off;
+ u8 delta_iqk;
+ u32 ADDA_backup[IQK_ADDA_REG_NUM];
+ u32 IQK_MAC_backup[IQK_MAC_REG_NUM];
+ u32 IQK_BB_backup_recover[9];
+ /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}} */
+ u32 IQK_BB_backup[IQK_BB_REG_NUM];
+ u32 tx_iqc_8723b[2][3][2];
+ /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}} */
+ u32 rx_iqc_8723b[2][2][2];
+ /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}}*/
+ u32 tx_iqc_8703b[3][2];
+ /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}}*/
+ u32 rx_iqc_8703b[2][2];
+ /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}}*/
+ u32 tx_iqc_8723d[2][3][2];
+ /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}}*/
+ u32 rx_iqc_8723d[2][2][2];
+ /* JJ ADD 20161014 */
+ /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}}*/
+ u32 tx_iqc_8710b[2][3][2];
+ /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}}*/
+ u32 rx_iqc_8710b[2][2][2];
+
+ u8 iqk_step;
+ u8 kcount;
+ u8 retry_count[4][2]; /* [4]: path ABCD, [2] TXK, RXK */
+ bool is_mp_mode;
+
+ /* <James> IQK time measurement */
+ u64 iqk_start_time;
+ u64 iqk_progressing_time;
+ u64 iqk_total_progressing_time;
+
+ u32 lok_result;
+
+ /* for APK */
+ u32 ap_koutput[2][2]; /* path A/B; output1_1a/output1_2a */
+ u8 is_ap_kdone;
+ u8 is_apk_thermal_meter_ignore;
+
+ /* DPK */
+ bool is_dpk_fail;
+ u8 is_dp_done;
+ u8 is_dp_path_aok;
+ u8 is_dp_path_bok;
+
+ u32 tx_lok[2];
+ u32 dpk_tx_agc;
+ s32 dpk_gain;
+ u32 dpk_thermal[4];
+ s8 modify_tx_agc_value_ofdm;
+ s8 modify_tx_agc_value_cck;
+
+ /*Add by Yuchen for Kfree Phydm*/
+ u8 reg_rf_kfree_enable; /*for registry*/
+ u8 rf_kfree_enable; /*for efuse enable check*/
+};
+
+void odm_txpowertracking_check(void *dm_void);
+
+void odm_txpowertracking_init(void *dm_void);
+
+void odm_txpowertracking_check_ap(void *dm_void);
+
+void odm_txpowertracking_thermal_meter_init(void *dm_void);
+
+void odm_txpowertracking_init(void *dm_void);
+
+void odm_txpowertracking_check_mp(void *dm_void);
+
+void odm_txpowertracking_check_ce(void *dm_void);
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/phydm_pre_define.h b/drivers/staging/rtlwifi/phydm/phydm_pre_define.h
new file mode 100644
index 0000000..6c301fe
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_pre_define.h
@@ -0,0 +1,613 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __PHYDMPREDEFINE_H__
+#define __PHYDMPREDEFINE_H__
+
+/* 1 ============================================================
+ * 1 Definition
+ * 1 ============================================================
+ */
+
+#define PHYDM_CODE_BASE "PHYDM_TRUNK"
+#define PHYDM_RELEASE_DATE "00000000"
+
+/* Max path of IC */
+#define MAX_PATH_NUM_8188E 1
+#define MAX_PATH_NUM_8192E 2
+#define MAX_PATH_NUM_8723B 1
+#define MAX_PATH_NUM_8812A 2
+#define MAX_PATH_NUM_8821A 1
+#define MAX_PATH_NUM_8814A 4
+#define MAX_PATH_NUM_8822B 2
+#define MAX_PATH_NUM_8821B 2
+#define MAX_PATH_NUM_8703B 1
+#define MAX_PATH_NUM_8188F 1
+#define MAX_PATH_NUM_8723D 1
+#define MAX_PATH_NUM_8197F 2
+#define MAX_PATH_NUM_8821C 1
+/* JJ ADD 20161014 */
+#define MAX_PATH_NUM_8710B 1
+
+/* Max RF path */
+#define ODM_RF_PATH_MAX 2
+#define ODM_RF_PATH_MAX_JAGUAR 4
+
+/*Bit define path*/
+#define PHYDM_A BIT(0)
+#define PHYDM_B BIT(1)
+#define PHYDM_C BIT(2)
+#define PHYDM_D BIT(3)
+#define PHYDM_AB (BIT(0) | BIT(1))
+#define PHYDM_AC (BIT(0) | BIT(2))
+#define PHYDM_AD (BIT(0) | BIT(3))
+#define PHYDM_BC (BIT(1) | BIT(2))
+#define PHYDM_BD (BIT(1) | BIT(3))
+#define PHYDM_CD (BIT(2) | BIT(3))
+#define PHYDM_ABC (BIT(0) | BIT(1) | BIT(2))
+#define PHYDM_ABD (BIT(0) | BIT(1) | BIT(3))
+#define PHYDM_ACD (BIT(0) | BIT(2) | BIT(3))
+#define PHYDM_BCD (BIT(1) | BIT(2) | BIT(3))
+#define PHYDM_ABCD (BIT(0) | BIT(1) | BIT(2) | BIT(3))
+
+/* number of entry */
+/* defined in wifi.h (32+1) */
+#define ODM_ASSOCIATE_ENTRY_NUM ASSOCIATE_ENTRY_NUM
+
+#define RX_SMOOTH_FACTOR 20
+
+/* -----MGN rate--------------------------------- */
+
+enum ODM_MGN_RATE {
+ ODM_MGN_1M = 0x02,
+ ODM_MGN_2M = 0x04,
+ ODM_MGN_5_5M = 0x0B,
+ ODM_MGN_6M = 0x0C,
+ ODM_MGN_9M = 0x12,
+ ODM_MGN_11M = 0x16,
+ ODM_MGN_12M = 0x18,
+ ODM_MGN_18M = 0x24,
+ ODM_MGN_24M = 0x30,
+ ODM_MGN_36M = 0x48,
+ ODM_MGN_48M = 0x60,
+ ODM_MGN_54M = 0x6C,
+ ODM_MGN_MCS32 = 0x7F,
+ ODM_MGN_MCS0,
+ ODM_MGN_MCS1,
+ ODM_MGN_MCS2,
+ ODM_MGN_MCS3,
+ ODM_MGN_MCS4,
+ ODM_MGN_MCS5,
+ ODM_MGN_MCS6,
+ ODM_MGN_MCS7,
+ ODM_MGN_MCS8,
+ ODM_MGN_MCS9,
+ ODM_MGN_MCS10,
+ ODM_MGN_MCS11,
+ ODM_MGN_MCS12,
+ ODM_MGN_MCS13,
+ ODM_MGN_MCS14,
+ ODM_MGN_MCS15,
+ ODM_MGN_MCS16,
+ ODM_MGN_MCS17,
+ ODM_MGN_MCS18,
+ ODM_MGN_MCS19,
+ ODM_MGN_MCS20,
+ ODM_MGN_MCS21,
+ ODM_MGN_MCS22,
+ ODM_MGN_MCS23,
+ ODM_MGN_MCS24,
+ ODM_MGN_MCS25,
+ ODM_MGN_MCS26,
+ ODM_MGN_MCS27,
+ ODM_MGN_MCS28,
+ ODM_MGN_MCS29,
+ ODM_MGN_MCS30,
+ ODM_MGN_MCS31,
+ ODM_MGN_VHT1SS_MCS0,
+ ODM_MGN_VHT1SS_MCS1,
+ ODM_MGN_VHT1SS_MCS2,
+ ODM_MGN_VHT1SS_MCS3,
+ ODM_MGN_VHT1SS_MCS4,
+ ODM_MGN_VHT1SS_MCS5,
+ ODM_MGN_VHT1SS_MCS6,
+ ODM_MGN_VHT1SS_MCS7,
+ ODM_MGN_VHT1SS_MCS8,
+ ODM_MGN_VHT1SS_MCS9,
+ ODM_MGN_VHT2SS_MCS0,
+ ODM_MGN_VHT2SS_MCS1,
+ ODM_MGN_VHT2SS_MCS2,
+ ODM_MGN_VHT2SS_MCS3,
+ ODM_MGN_VHT2SS_MCS4,
+ ODM_MGN_VHT2SS_MCS5,
+ ODM_MGN_VHT2SS_MCS6,
+ ODM_MGN_VHT2SS_MCS7,
+ ODM_MGN_VHT2SS_MCS8,
+ ODM_MGN_VHT2SS_MCS9,
+ ODM_MGN_VHT3SS_MCS0,
+ ODM_MGN_VHT3SS_MCS1,
+ ODM_MGN_VHT3SS_MCS2,
+ ODM_MGN_VHT3SS_MCS3,
+ ODM_MGN_VHT3SS_MCS4,
+ ODM_MGN_VHT3SS_MCS5,
+ ODM_MGN_VHT3SS_MCS6,
+ ODM_MGN_VHT3SS_MCS7,
+ ODM_MGN_VHT3SS_MCS8,
+ ODM_MGN_VHT3SS_MCS9,
+ ODM_MGN_VHT4SS_MCS0,
+ ODM_MGN_VHT4SS_MCS1,
+ ODM_MGN_VHT4SS_MCS2,
+ ODM_MGN_VHT4SS_MCS3,
+ ODM_MGN_VHT4SS_MCS4,
+ ODM_MGN_VHT4SS_MCS5,
+ ODM_MGN_VHT4SS_MCS6,
+ ODM_MGN_VHT4SS_MCS7,
+ ODM_MGN_VHT4SS_MCS8,
+ ODM_MGN_VHT4SS_MCS9,
+ ODM_MGN_UNKNOWN
+};
+
+#define ODM_MGN_MCS0_SG 0xc0
+#define ODM_MGN_MCS1_SG 0xc1
+#define ODM_MGN_MCS2_SG 0xc2
+#define ODM_MGN_MCS3_SG 0xc3
+#define ODM_MGN_MCS4_SG 0xc4
+#define ODM_MGN_MCS5_SG 0xc5
+#define ODM_MGN_MCS6_SG 0xc6
+#define ODM_MGN_MCS7_SG 0xc7
+#define ODM_MGN_MCS8_SG 0xc8
+#define ODM_MGN_MCS9_SG 0xc9
+#define ODM_MGN_MCS10_SG 0xca
+#define ODM_MGN_MCS11_SG 0xcb
+#define ODM_MGN_MCS12_SG 0xcc
+#define ODM_MGN_MCS13_SG 0xcd
+#define ODM_MGN_MCS14_SG 0xce
+#define ODM_MGN_MCS15_SG 0xcf
+
+/* -----DESC rate--------------------------------- */
+
+#define ODM_RATEMCS15_SG 0x1c
+#define ODM_RATEMCS32 0x20
+
+/* CCK Rates, TxHT = 0 */
+#define ODM_RATE1M 0x00
+#define ODM_RATE2M 0x01
+#define ODM_RATE5_5M 0x02
+#define ODM_RATE11M 0x03
+/* OFDM Rates, TxHT = 0 */
+#define ODM_RATE6M 0x04
+#define ODM_RATE9M 0x05
+#define ODM_RATE12M 0x06
+#define ODM_RATE18M 0x07
+#define ODM_RATE24M 0x08
+#define ODM_RATE36M 0x09
+#define ODM_RATE48M 0x0A
+#define ODM_RATE54M 0x0B
+/* MCS Rates, TxHT = 1 */
+#define ODM_RATEMCS0 0x0C
+#define ODM_RATEMCS1 0x0D
+#define ODM_RATEMCS2 0x0E
+#define ODM_RATEMCS3 0x0F
+#define ODM_RATEMCS4 0x10
+#define ODM_RATEMCS5 0x11
+#define ODM_RATEMCS6 0x12
+#define ODM_RATEMCS7 0x13
+#define ODM_RATEMCS8 0x14
+#define ODM_RATEMCS9 0x15
+#define ODM_RATEMCS10 0x16
+#define ODM_RATEMCS11 0x17
+#define ODM_RATEMCS12 0x18
+#define ODM_RATEMCS13 0x19
+#define ODM_RATEMCS14 0x1A
+#define ODM_RATEMCS15 0x1B
+#define ODM_RATEMCS16 0x1C
+#define ODM_RATEMCS17 0x1D
+#define ODM_RATEMCS18 0x1E
+#define ODM_RATEMCS19 0x1F
+#define ODM_RATEMCS20 0x20
+#define ODM_RATEMCS21 0x21
+#define ODM_RATEMCS22 0x22
+#define ODM_RATEMCS23 0x23
+#define ODM_RATEMCS24 0x24
+#define ODM_RATEMCS25 0x25
+#define ODM_RATEMCS26 0x26
+#define ODM_RATEMCS27 0x27
+#define ODM_RATEMCS28 0x28
+#define ODM_RATEMCS29 0x29
+#define ODM_RATEMCS30 0x2A
+#define ODM_RATEMCS31 0x2B
+#define ODM_RATEVHTSS1MCS0 0x2C
+#define ODM_RATEVHTSS1MCS1 0x2D
+#define ODM_RATEVHTSS1MCS2 0x2E
+#define ODM_RATEVHTSS1MCS3 0x2F
+#define ODM_RATEVHTSS1MCS4 0x30
+#define ODM_RATEVHTSS1MCS5 0x31
+#define ODM_RATEVHTSS1MCS6 0x32
+#define ODM_RATEVHTSS1MCS7 0x33
+#define ODM_RATEVHTSS1MCS8 0x34
+#define ODM_RATEVHTSS1MCS9 0x35
+#define ODM_RATEVHTSS2MCS0 0x36
+#define ODM_RATEVHTSS2MCS1 0x37
+#define ODM_RATEVHTSS2MCS2 0x38
+#define ODM_RATEVHTSS2MCS3 0x39
+#define ODM_RATEVHTSS2MCS4 0x3A
+#define ODM_RATEVHTSS2MCS5 0x3B
+#define ODM_RATEVHTSS2MCS6 0x3C
+#define ODM_RATEVHTSS2MCS7 0x3D
+#define ODM_RATEVHTSS2MCS8 0x3E
+#define ODM_RATEVHTSS2MCS9 0x3F
+#define ODM_RATEVHTSS3MCS0 0x40
+#define ODM_RATEVHTSS3MCS1 0x41
+#define ODM_RATEVHTSS3MCS2 0x42
+#define ODM_RATEVHTSS3MCS3 0x43
+#define ODM_RATEVHTSS3MCS4 0x44
+#define ODM_RATEVHTSS3MCS5 0x45
+#define ODM_RATEVHTSS3MCS6 0x46
+#define ODM_RATEVHTSS3MCS7 0x47
+#define ODM_RATEVHTSS3MCS8 0x48
+#define ODM_RATEVHTSS3MCS9 0x49
+#define ODM_RATEVHTSS4MCS0 0x4A
+#define ODM_RATEVHTSS4MCS1 0x4B
+#define ODM_RATEVHTSS4MCS2 0x4C
+#define ODM_RATEVHTSS4MCS3 0x4D
+#define ODM_RATEVHTSS4MCS4 0x4E
+#define ODM_RATEVHTSS4MCS5 0x4F
+#define ODM_RATEVHTSS4MCS6 0x50
+#define ODM_RATEVHTSS4MCS7 0x51
+#define ODM_RATEVHTSS4MCS8 0x52
+#define ODM_RATEVHTSS4MCS9 0x53
+
+#define ODM_NUM_RATE_IDX (ODM_RATEVHTSS4MCS9 + 1)
+
+/* 1 ============================================================
+ * 1 enumeration
+ * 1 ============================================================
+ */
+
+/* ODM_CMNINFO_INTERFACE */
+enum odm_interface {
+ ODM_ITRF_PCIE = 0x1,
+ ODM_ITRF_USB = 0x2,
+ ODM_ITRF_SDIO = 0x4,
+ ODM_ITRF_ALL = 0x7,
+};
+
+/* ODM_CMNINFO_IC_TYPE */
+enum odm_ic_type {
+ ODM_RTL8188E = BIT(0),
+ ODM_RTL8812 = BIT(1),
+ ODM_RTL8821 = BIT(2),
+ ODM_RTL8192E = BIT(3),
+ ODM_RTL8723B = BIT(4),
+ ODM_RTL8814A = BIT(5),
+ ODM_RTL8881A = BIT(6),
+ ODM_RTL8822B = BIT(7),
+ ODM_RTL8703B = BIT(8),
+ ODM_RTL8195A = BIT(9),
+ ODM_RTL8188F = BIT(10),
+ ODM_RTL8723D = BIT(11),
+ ODM_RTL8197F = BIT(12),
+ ODM_RTL8821C = BIT(13),
+ ODM_RTL8814B = BIT(14),
+ ODM_RTL8198F = BIT(15),
+ /* JJ ADD 20161014 */
+ ODM_RTL8710B = BIT(16),
+};
+
+/* JJ ADD 20161014 */
+#define ODM_IC_1SS \
+ (ODM_RTL8188E | ODM_RTL8188F | ODM_RTL8723B | ODM_RTL8703B | \
+ ODM_RTL8723D | ODM_RTL8881A | ODM_RTL8821 | ODM_RTL8821C | \
+ ODM_RTL8195A | ODM_RTL8710B)
+#define ODM_IC_2SS (ODM_RTL8192E | ODM_RTL8197F | ODM_RTL8812 | ODM_RTL8822B)
+#define ODM_IC_3SS (ODM_RTL8814A)
+#define ODM_IC_4SS (ODM_RTL8814B | ODM_RTL8198F)
+
+/* JJ ADD 20161014 */
+#define ODM_IC_11N_SERIES \
+ (ODM_RTL8188E | ODM_RTL8192E | ODM_RTL8723B | ODM_RTL8703B | \
+ ODM_RTL8188F | ODM_RTL8723D | ODM_RTL8197F | ODM_RTL8710B)
+#define ODM_IC_11AC_SERIES \
+ (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8814A | ODM_RTL8881A | \
+ ODM_RTL8822B | ODM_RTL8821C)
+#define ODM_IC_11AC_1_SERIES (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8881A)
+#define ODM_IC_11AC_2_SERIES (ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8821C)
+#define ODM_IC_TXBF_SUPPORT \
+ (ODM_RTL8192E | ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8814A | \
+ ODM_RTL8881A | ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8821C)
+#define ODM_IC_11N_GAIN_IDX_EDCCA \
+ (ODM_RTL8195A | ODM_RTL8703B | ODM_RTL8188F | ODM_RTL8723D | \
+ ODM_RTL8197F | ODM_RTL8710B)
+#define ODM_IC_11AC_GAIN_IDX_EDCCA (ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8821C)
+#define ODM_IC_PHY_STATUE_NEW_TYPE \
+ (ODM_RTL8197F | ODM_RTL8822B | ODM_RTL8723D | ODM_RTL8821C | \
+ ODM_RTL8710B)
+
+#define PHYDM_IC_8051_SERIES \
+ (ODM_RTL8881A | ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8188E | \
+ ODM_RTL8192E | ODM_RTL8723B | ODM_RTL8703B | ODM_RTL8188F)
+#define PHYDM_IC_3081_SERIES \
+ (ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8821C)
+
+#define PHYDM_IC_SUPPORT_LA_MODE \
+ (ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8821C)
+
+/* JJ ADD 20161014 */
+
+/* ODM_CMNINFO_CUT_VER */
+enum odm_cut_version {
+ ODM_CUT_A = 0,
+ ODM_CUT_B = 1,
+ ODM_CUT_C = 2,
+ ODM_CUT_D = 3,
+ ODM_CUT_E = 4,
+ ODM_CUT_F = 5,
+
+ ODM_CUT_I = 8,
+ ODM_CUT_J = 9,
+ ODM_CUT_K = 10,
+ ODM_CUT_TEST = 15,
+};
+
+/* ODM_CMNINFO_FAB_VER */
+enum odm_fab {
+ ODM_TSMC = 0,
+ ODM_UMC = 1,
+};
+
+/* ODM_CMNINFO_RF_TYPE
+ *
+ * For example 1T2R (A+AB = BIT(0)|BIT(4)|BIT(5))
+ */
+enum odm_rf_path {
+ ODM_RF_A = BIT(0),
+ ODM_RF_B = BIT(1),
+ ODM_RF_C = BIT(2),
+ ODM_RF_D = BIT(3),
+};
+
+enum odm_rf_tx_num {
+ ODM_1T = 1,
+ ODM_2T = 2,
+ ODM_3T = 3,
+ ODM_4T = 4,
+};
+
+enum odm_rf_type {
+ ODM_1T1R,
+ ODM_1T2R,
+ ODM_2T2R,
+ ODM_2T2R_GREEN,
+ ODM_2T3R,
+ ODM_2T4R,
+ ODM_3T3R,
+ ODM_3T4R,
+ ODM_4T4R,
+ ODM_XTXR
+};
+
+enum odm_mac_phy_mode {
+ ODM_SMSP = 0,
+ ODM_DMSP = 1,
+ ODM_DMDP = 2,
+};
+
+enum odm_bt_coexist {
+ ODM_BT_BUSY = 1,
+ ODM_BT_ON = 2,
+ ODM_BT_OFF = 3,
+ ODM_BT_NONE = 4,
+};
+
+/* ODM_CMNINFO_OP_MODE */
+enum odm_operation_mode {
+ ODM_NO_LINK = BIT(0),
+ ODM_LINK = BIT(1),
+ ODM_SCAN = BIT(2),
+ ODM_POWERSAVE = BIT(3),
+ ODM_AP_MODE = BIT(4),
+ ODM_CLIENT_MODE = BIT(5),
+ ODM_AD_HOC = BIT(6),
+ ODM_WIFI_DIRECT = BIT(7),
+ ODM_WIFI_DISPLAY = BIT(8),
+};
+
+/* ODM_CMNINFO_WM_MODE */
+enum odm_wireless_mode {
+ ODM_WM_UNKNOWN = 0x0,
+ ODM_WM_B = BIT(0),
+ ODM_WM_G = BIT(1),
+ ODM_WM_A = BIT(2),
+ ODM_WM_N24G = BIT(3),
+ ODM_WM_N5G = BIT(4),
+ ODM_WM_AUTO = BIT(5),
+ ODM_WM_AC = BIT(6),
+};
+
+/* ODM_CMNINFO_BAND */
+enum odm_band_type {
+ ODM_BAND_2_4G = 0,
+ ODM_BAND_5G,
+ ODM_BAND_ON_BOTH,
+ ODM_BANDMAX
+};
+
+/* ODM_CMNINFO_SEC_CHNL_OFFSET */
+enum phydm_sec_chnl_offset {
+ PHYDM_DONT_CARE = 0,
+ PHYDM_BELOW = 1,
+ PHYDM_ABOVE = 2
+};
+
+/* ODM_CMNINFO_SEC_MODE */
+enum odm_security {
+ ODM_SEC_OPEN = 0,
+ ODM_SEC_WEP40 = 1,
+ ODM_SEC_TKIP = 2,
+ ODM_SEC_RESERVE = 3,
+ ODM_SEC_AESCCMP = 4,
+ ODM_SEC_WEP104 = 5,
+ ODM_WEP_WPA_MIXED = 6, /* WEP + WPA */
+ ODM_SEC_SMS4 = 7,
+};
+
+/* ODM_CMNINFO_BW */
+enum odm_bw {
+ ODM_BW20M = 0,
+ ODM_BW40M = 1,
+ ODM_BW80M = 2,
+ ODM_BW160M = 3,
+ ODM_BW5M = 4,
+ ODM_BW10M = 5,
+ ODM_BW_MAX = 6
+};
+
+/* ODM_CMNINFO_CHNL */
+
+/* ODM_CMNINFO_BOARD_TYPE */
+enum odm_board_type {
+ ODM_BOARD_DEFAULT = 0, /* The DEFAULT case. */
+ ODM_BOARD_MINICARD = BIT(0), /* 0 = non-mini card, 1= mini card. */
+ ODM_BOARD_SLIM = BIT(1), /* 0 = non-slim card, 1 = slim card */
+ ODM_BOARD_BT = BIT(2), /* 0 = without BT card, 1 = with BT */
+ ODM_BOARD_EXT_PA =
+ BIT(3), /* 0 = no 2G ext-PA, 1 = existing 2G ext-PA */
+ ODM_BOARD_EXT_LNA =
+ BIT(4), /* 0 = no 2G ext-LNA, 1 = existing 2G ext-LNA */
+ ODM_BOARD_EXT_TRSW =
+ BIT(5), /* 0 = no ext-TRSW, 1 = existing ext-TRSW */
+ ODM_BOARD_EXT_PA_5G =
+ BIT(6), /* 0 = no 5G ext-PA, 1 = existing 5G ext-PA */
+ ODM_BOARD_EXT_LNA_5G =
+ BIT(7), /* 0 = no 5G ext-LNA, 1 = existing 5G ext-LNA */
+};
+
+enum odm_package_type {
+ ODM_PACKAGE_DEFAULT = 0,
+ ODM_PACKAGE_QFN68 = BIT(0),
+ ODM_PACKAGE_TFBGA90 = BIT(1),
+ ODM_PACKAGE_TFBGA79 = BIT(2),
+};
+
+enum odm_type_gpa {
+ TYPE_GPA0 = 0x0000,
+ TYPE_GPA1 = 0x0055,
+ TYPE_GPA2 = 0x00AA,
+ TYPE_GPA3 = 0x00FF,
+ TYPE_GPA4 = 0x5500,
+ TYPE_GPA5 = 0x5555,
+ TYPE_GPA6 = 0x55AA,
+ TYPE_GPA7 = 0x55FF,
+ TYPE_GPA8 = 0xAA00,
+ TYPE_GPA9 = 0xAA55,
+ TYPE_GPA10 = 0xAAAA,
+ TYPE_GPA11 = 0xAAFF,
+ TYPE_GPA12 = 0xFF00,
+ TYPE_GPA13 = 0xFF55,
+ TYPE_GPA14 = 0xFFAA,
+ TYPE_GPA15 = 0xFFFF,
+};
+
+enum odm_type_apa {
+ TYPE_APA0 = 0x0000,
+ TYPE_APA1 = 0x0055,
+ TYPE_APA2 = 0x00AA,
+ TYPE_APA3 = 0x00FF,
+ TYPE_APA4 = 0x5500,
+ TYPE_APA5 = 0x5555,
+ TYPE_APA6 = 0x55AA,
+ TYPE_APA7 = 0x55FF,
+ TYPE_APA8 = 0xAA00,
+ TYPE_APA9 = 0xAA55,
+ TYPE_APA10 = 0xAAAA,
+ TYPE_APA11 = 0xAAFF,
+ TYPE_APA12 = 0xFF00,
+ TYPE_APA13 = 0xFF55,
+ TYPE_APA14 = 0xFFAA,
+ TYPE_APA15 = 0xFFFF,
+};
+
+enum odm_type_glna {
+ TYPE_GLNA0 = 0x0000,
+ TYPE_GLNA1 = 0x0055,
+ TYPE_GLNA2 = 0x00AA,
+ TYPE_GLNA3 = 0x00FF,
+ TYPE_GLNA4 = 0x5500,
+ TYPE_GLNA5 = 0x5555,
+ TYPE_GLNA6 = 0x55AA,
+ TYPE_GLNA7 = 0x55FF,
+ TYPE_GLNA8 = 0xAA00,
+ TYPE_GLNA9 = 0xAA55,
+ TYPE_GLNA10 = 0xAAAA,
+ TYPE_GLNA11 = 0xAAFF,
+ TYPE_GLNA12 = 0xFF00,
+ TYPE_GLNA13 = 0xFF55,
+ TYPE_GLNA14 = 0xFFAA,
+ TYPE_GLNA15 = 0xFFFF,
+};
+
+enum odm_type_alna {
+ TYPE_ALNA0 = 0x0000,
+ TYPE_ALNA1 = 0x0055,
+ TYPE_ALNA2 = 0x00AA,
+ TYPE_ALNA3 = 0x00FF,
+ TYPE_ALNA4 = 0x5500,
+ TYPE_ALNA5 = 0x5555,
+ TYPE_ALNA6 = 0x55AA,
+ TYPE_ALNA7 = 0x55FF,
+ TYPE_ALNA8 = 0xAA00,
+ TYPE_ALNA9 = 0xAA55,
+ TYPE_ALNA10 = 0xAAAA,
+ TYPE_ALNA11 = 0xAAFF,
+ TYPE_ALNA12 = 0xFF00,
+ TYPE_ALNA13 = 0xFF55,
+ TYPE_ALNA14 = 0xFFAA,
+ TYPE_ALNA15 = 0xFFFF,
+};
+
+enum odm_rf_radio_path {
+ ODM_RF_PATH_A = 0, /* Radio path A */
+ ODM_RF_PATH_B = 1, /* Radio path B */
+ ODM_RF_PATH_C = 2, /* Radio path C */
+ ODM_RF_PATH_D = 3, /* Radio path D */
+ ODM_RF_PATH_AB,
+ ODM_RF_PATH_AC,
+ ODM_RF_PATH_AD,
+ ODM_RF_PATH_BC,
+ ODM_RF_PATH_BD,
+ ODM_RF_PATH_CD,
+ ODM_RF_PATH_ABC,
+ ODM_RF_PATH_ACD,
+ ODM_RF_PATH_BCD,
+ ODM_RF_PATH_ABCD,
+ /* ODM_RF_PATH_MAX, */ /* Max RF number 90 support */
+};
+
+enum odm_parameter_init {
+ ODM_PRE_SETTING = 0,
+ ODM_POST_SETTING = 1,
+};
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/phydm_precomp.h b/drivers/staging/rtlwifi/phydm/phydm_precomp.h
new file mode 100644
index 0000000..bada15c
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_precomp.h
@@ -0,0 +1,85 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __ODM_PRECOMP_H__
+#define __ODM_PRECOMP_H__
+
+#include "phydm_types.h"
+
+/* 2 Config Flags and Structs - defined by each ODM type */
+
+#include "../wifi.h"
+#include "rtl_phydm.h"
+
+/* 2 OutSrc Header Files */
+
+#include "phydm.h"
+#include "phydm_hwconfig.h"
+#include "phydm_debug.h"
+#include "phydm_regdefine11ac.h"
+#include "phydm_regdefine11n.h"
+#include "phydm_interface.h"
+#include "phydm_reg.h"
+
+#include "phydm_adc_sampling.h"
+
+/* JJ ADD 20161014 */
+
+#include "../halmac/halmac_reg2.h"
+
+#define LDPC_HT_ENABLE_RX BIT(0)
+#define LDPC_HT_ENABLE_TX BIT(1)
+#define LDPC_HT_TEST_TX_ENABLE BIT(2)
+#define LDPC_HT_CAP_TX BIT(3)
+
+#define STBC_HT_ENABLE_RX BIT(0)
+#define STBC_HT_ENABLE_TX BIT(1)
+#define STBC_HT_TEST_TX_ENABLE BIT(2)
+#define STBC_HT_CAP_TX BIT(3)
+
+#define LDPC_VHT_ENABLE_RX BIT(0)
+#define LDPC_VHT_ENABLE_TX BIT(1)
+#define LDPC_VHT_TEST_TX_ENABLE BIT(2)
+#define LDPC_VHT_CAP_TX BIT(3)
+
+#define STBC_VHT_ENABLE_RX BIT(0)
+#define STBC_VHT_ENABLE_TX BIT(1)
+#define STBC_VHT_TEST_TX_ENABLE BIT(2)
+#define STBC_VHT_CAP_TX BIT(3)
+
+#include "rtl8822b/halhwimg8822b_mac.h"
+#include "rtl8822b/halhwimg8822b_rf.h"
+#include "rtl8822b/halhwimg8822b_bb.h"
+#include "rtl8822b/phydm_regconfig8822b.h"
+#include "rtl8822b/halphyrf_8822b.h"
+#include "rtl8822b/phydm_rtl8822b.h"
+#include "rtl8822b/phydm_hal_api8822b.h"
+#include "rtl8822b/version_rtl8822b.h"
+
+#include "../halmac/halmac_reg_8822b.h"
+
+/* JJ ADD 20161014 */
+
+#endif /* __ODM_PRECOMP_H__ */
diff --git a/drivers/staging/rtlwifi/phydm/phydm_psd.c b/drivers/staging/rtlwifi/phydm/phydm_psd.c
new file mode 100644
index 0000000..48f8776
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_psd.c
@@ -0,0 +1,422 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+/*============================================================
+ * include files
+ *============================================================
+ */
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+u32 phydm_get_psd_data(void *dm_void, u32 psd_tone_idx, u32 igi)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct psd_info *dm_psd_table = &dm->dm_psd_table;
+ u32 psd_report = 0;
+
+ odm_set_bb_reg(dm, dm_psd_table->psd_reg, 0x3ff, psd_tone_idx);
+
+ odm_set_bb_reg(dm, dm_psd_table->psd_reg, BIT(22),
+ 1); /*PSD trigger start*/
+ ODM_delay_us(10);
+ odm_set_bb_reg(dm, dm_psd_table->psd_reg, BIT(22),
+ 0); /*PSD trigger stop*/
+
+ psd_report = odm_get_bb_reg(dm, dm_psd_table->psd_report_reg, 0xffff);
+ psd_report = odm_convert_to_db(psd_report) + igi;
+
+ return psd_report;
+}
+
+static u8 phydm_psd_stop_trx(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u32 i;
+ u8 trx_idle_success = false;
+ u32 dbg_port_value = 0;
+
+ /*[Stop TRX]----------------------------------------------------------*/
+ if (!phydm_set_bb_dbg_port(dm, BB_DBGPORT_PRIORITY_3,
+ 0x0)) /*set debug port to 0x0*/
+ return STOP_TRX_FAIL;
+
+ for (i = 0; i < 10000; i++) {
+ dbg_port_value = phydm_get_bb_dbg_port_value(dm);
+ if ((dbg_port_value & (BIT(17) | BIT(3))) ==
+ 0) /* PHYTXON && CCA_all */ {
+ ODM_RT_TRACE(dm, ODM_COMP_API,
+ "PSD wait for ((%d)) times\n", i);
+
+ trx_idle_success = true;
+ break;
+ }
+ }
+
+ if (trx_idle_success) {
+ /*pause all TX queue*/
+ odm_set_bb_reg(dm, 0x520, 0xff0000, 0xff);
+
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ /*disable CCK block*/
+ odm_set_bb_reg(dm, 0x808, BIT(28), 0);
+ /*disable OFDM RX CCA*/
+ odm_set_bb_reg(dm, 0x838, BIT(1), 1);
+ } else {
+ /*TBD*/
+ /* disable whole CCK block */
+ odm_set_bb_reg(dm, 0x800, BIT(24), 0);
+ /*[ Set IQK Matrix = 0 ] equivalent to [ Turn off CCA]*/
+ odm_set_bb_reg(dm, 0xC14, MASKDWORD, 0x0);
+ }
+
+ } else {
+ return STOP_TRX_FAIL;
+ }
+
+ phydm_release_bb_dbg_port(dm);
+
+ return STOP_TRX_SUCCESS;
+}
+
+static u8 psd_result_cali_tone_8821[7] = {21, 28, 33, 93, 98, 105, 127};
+static u8 psd_result_cali_val_8821[7] = {67, 69, 71, 72, 71, 69, 67};
+
+void phydm_psd(void *dm_void, u32 igi, u16 start_point, u16 stop_point)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct psd_info *dm_psd_table = &dm->dm_psd_table;
+ u32 i = 0, mod_tone_idx;
+ u32 t = 0;
+ u16 fft_max_half_bw;
+ u32 psd_igi_a_reg;
+ u32 psd_igi_b_reg;
+ u16 psd_fc_channel = dm_psd_table->psd_fc_channel;
+ u8 ag_rf_mode_reg = 0;
+ u8 rf_reg18_9_8 = 0;
+ u32 psd_result_tmp = 0;
+ u8 psd_result = 0;
+ u8 psd_result_cali_tone[7] = {0};
+ u8 psd_result_cali_val[7] = {0};
+ u8 noise_table_idx = 0;
+
+ if (dm->support_ic_type == ODM_RTL8821) {
+ odm_move_memory(dm, psd_result_cali_tone,
+ psd_result_cali_tone_8821, 7);
+ odm_move_memory(dm, psd_result_cali_val,
+ psd_result_cali_val_8821, 7);
+ }
+
+ dm_psd_table->psd_in_progress = 1;
+
+ /*[Stop DIG]*/
+ dm->support_ability &= ~(ODM_BB_DIG);
+ dm->support_ability &= ~(ODM_BB_FA_CNT);
+
+ ODM_RT_TRACE(dm, ODM_COMP_API, "PSD Start =>\n");
+
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ psd_igi_a_reg = 0xc50;
+ psd_igi_b_reg = 0xe50;
+ } else {
+ psd_igi_a_reg = 0xc50;
+ psd_igi_b_reg = 0xc58;
+ }
+
+ /*[back up IGI]*/
+ dm_psd_table->initial_gain_backup =
+ odm_get_bb_reg(dm, psd_igi_a_reg, 0xff);
+ odm_set_bb_reg(dm, psd_igi_a_reg, 0xff,
+ 0x6e); /*IGI target at 0dBm & make it can't CCA*/
+ odm_set_bb_reg(dm, psd_igi_b_reg, 0xff,
+ 0x6e); /*IGI target at 0dBm & make it can't CCA*/
+ ODM_delay_us(10);
+
+ if (phydm_psd_stop_trx(dm) == STOP_TRX_FAIL) {
+ ODM_RT_TRACE(dm, ODM_COMP_API, "STOP_TRX_FAIL\n");
+ return;
+ }
+
+ /*[Set IGI]*/
+ odm_set_bb_reg(dm, psd_igi_a_reg, 0xff, igi);
+ odm_set_bb_reg(dm, psd_igi_b_reg, 0xff, igi);
+
+ /*[Backup RF Reg]*/
+ dm_psd_table->rf_0x18_bkp =
+ odm_get_rf_reg(dm, ODM_RF_PATH_A, 0x18, RFREGOFFSETMASK);
+
+ if (psd_fc_channel > 14) {
+ rf_reg18_9_8 = 1;
+
+ if (psd_fc_channel >= 36 && psd_fc_channel <= 64)
+ ag_rf_mode_reg = 0x1;
+ else if (psd_fc_channel >= 100 && psd_fc_channel <= 140)
+ ag_rf_mode_reg = 0x3;
+ else if (psd_fc_channel > 140)
+ ag_rf_mode_reg = 0x5;
+ }
+
+ /* Set RF fc*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x18, 0xff, psd_fc_channel);
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x18, 0x300, rf_reg18_9_8);
+ /*2b'11: 20MHz, 2b'10: 40MHz, 2b'01: 80MHz */
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x18, 0xc00,
+ dm_psd_table->psd_bw_rf_reg);
+ /* Set RF ag fc mode*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x18, 0xf0000, ag_rf_mode_reg);
+
+ ODM_RT_TRACE(dm, ODM_COMP_API, "0xc50=((0x%x))\n",
+ odm_get_bb_reg(dm, 0xc50, MASKDWORD));
+ ODM_RT_TRACE(dm, ODM_COMP_API, "RF0x18=((0x%x))\n",
+ odm_get_rf_reg(dm, ODM_RF_PATH_A, 0x18, RFREGOFFSETMASK));
+
+ /*[Stop 3-wires]*/
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ odm_set_bb_reg(dm, 0xc00, 0xf, 0x4); /* hardware 3-wire off */
+ odm_set_bb_reg(dm, 0xe00, 0xf, 0x4); /* hardware 3-wire off */
+ } else {
+ odm_set_bb_reg(dm, 0x88c, 0xf00000,
+ 0xf); /* 3 wire Disable 88c[23:20]=0xf */
+ }
+ ODM_delay_us(10);
+
+ if (stop_point > (dm_psd_table->fft_smp_point - 1))
+ stop_point = (dm_psd_table->fft_smp_point - 1);
+
+ if (start_point > (dm_psd_table->fft_smp_point - 1))
+ start_point = (dm_psd_table->fft_smp_point - 1);
+
+ if (start_point > stop_point)
+ stop_point = start_point;
+
+ if (stop_point > 127) /* limit of psd_result[128] */
+ stop_point = 127;
+
+ for (i = start_point; i <= stop_point; i++) {
+ fft_max_half_bw = (dm_psd_table->fft_smp_point) >> 1;
+
+ if (i < fft_max_half_bw)
+ mod_tone_idx = i + fft_max_half_bw;
+ else
+ mod_tone_idx = i - fft_max_half_bw;
+
+ psd_result_tmp = 0;
+ for (t = 0; t < dm_psd_table->sw_avg_time; t++)
+ psd_result_tmp +=
+ phydm_get_psd_data(dm, mod_tone_idx, igi);
+ psd_result =
+ (u8)((psd_result_tmp / dm_psd_table->sw_avg_time)) -
+ dm_psd_table->psd_pwr_common_offset;
+
+ if (dm_psd_table->fft_smp_point == 128 &&
+ (dm_psd_table->noise_k_en)) {
+ if (i > psd_result_cali_tone[noise_table_idx])
+ noise_table_idx++;
+
+ if (noise_table_idx > 6)
+ noise_table_idx = 6;
+
+ if (psd_result >= psd_result_cali_val[noise_table_idx])
+ psd_result =
+ psd_result -
+ psd_result_cali_val[noise_table_idx];
+ else
+ psd_result = 0;
+
+ dm_psd_table->psd_result[i] = psd_result;
+ }
+
+ ODM_RT_TRACE(dm, ODM_COMP_API, "[%d] N_cali = %d, PSD = %d\n",
+ mod_tone_idx, psd_result_cali_val[noise_table_idx],
+ psd_result);
+ }
+
+ /*[Start 3-wires]*/
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ odm_set_bb_reg(dm, 0xc00, 0xf, 0x7); /* hardware 3-wire on */
+ odm_set_bb_reg(dm, 0xe00, 0xf, 0x7); /* hardware 3-wire on */
+ } else {
+ odm_set_bb_reg(dm, 0x88c, 0xf00000,
+ 0x0); /* 3 wire enable 88c[23:20]=0x0 */
+ }
+ ODM_delay_us(10);
+
+ /*[Revert Reg]*/
+ odm_set_bb_reg(dm, 0x520, 0xff0000, 0x0); /*start all TX queue*/
+ odm_set_bb_reg(dm, 0x808, BIT(28), 1); /*enable CCK block*/
+ odm_set_bb_reg(dm, 0x838, BIT(1), 0); /*enable OFDM RX CCA*/
+
+ odm_set_bb_reg(dm, psd_igi_a_reg, 0xff,
+ dm_psd_table->initial_gain_backup);
+ odm_set_bb_reg(dm, psd_igi_b_reg, 0xff,
+ dm_psd_table->initial_gain_backup);
+
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x18, RFREGOFFSETMASK,
+ dm_psd_table->rf_0x18_bkp);
+
+ ODM_RT_TRACE(dm, ODM_COMP_API, "PSD finished\n\n");
+
+ dm->support_ability |= ODM_BB_DIG;
+ dm->support_ability |= ODM_BB_FA_CNT;
+ dm_psd_table->psd_in_progress = 0;
+}
+
+void phydm_psd_para_setting(void *dm_void, u8 sw_avg_time, u8 hw_avg_time,
+ u8 i_q_setting, u16 fft_smp_point, u8 ant_sel,
+ u8 psd_input, u8 channel, u8 noise_k_en)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct psd_info *dm_psd_table = &dm->dm_psd_table;
+ u8 fft_smp_point_idx = 0;
+
+ dm_psd_table->fft_smp_point = fft_smp_point;
+
+ if (sw_avg_time == 0)
+ sw_avg_time = 1;
+
+ dm_psd_table->sw_avg_time = sw_avg_time;
+ dm_psd_table->psd_fc_channel = channel;
+ dm_psd_table->noise_k_en = noise_k_en;
+
+ if (fft_smp_point == 128)
+ fft_smp_point_idx = 0;
+ else if (fft_smp_point == 256)
+ fft_smp_point_idx = 1;
+ else if (fft_smp_point == 512)
+ fft_smp_point_idx = 2;
+ else if (fft_smp_point == 1024)
+ fft_smp_point_idx = 3;
+
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ odm_set_bb_reg(dm, 0x910, BIT(11) | BIT(10), i_q_setting);
+ odm_set_bb_reg(dm, 0x910, BIT(13) | BIT(12), hw_avg_time);
+ odm_set_bb_reg(dm, 0x910, BIT(15) | BIT(14), fft_smp_point_idx);
+ odm_set_bb_reg(dm, 0x910, BIT(17) | BIT(16), ant_sel);
+ odm_set_bb_reg(dm, 0x910, BIT(23), psd_input);
+ }
+
+ /*bw = (*dm->band_width); //ODM_BW20M */
+ /*channel = *(dm->channel);*/
+}
+
+void phydm_psd_init(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct psd_info *dm_psd_table = &dm->dm_psd_table;
+
+ ODM_RT_TRACE(dm, ODM_COMP_API, "PSD para init\n");
+
+ dm_psd_table->psd_in_progress = false;
+
+ if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
+ dm_psd_table->psd_reg = 0x910;
+ dm_psd_table->psd_report_reg = 0xF44;
+
+ if (ODM_IC_11AC_2_SERIES)
+ dm_psd_table->psd_bw_rf_reg =
+ 1; /*2b'11: 20MHz, 2b'10: 40MHz, 2b'01: 80MHz */
+ else
+ dm_psd_table->psd_bw_rf_reg =
+ 2; /*2b'11: 20MHz, 2b'10: 40MHz, 2b'01: 80MHz */
+
+ } else {
+ dm_psd_table->psd_reg = 0x808;
+ dm_psd_table->psd_report_reg = 0x8B4;
+ dm_psd_table->psd_bw_rf_reg =
+ 2; /*2b'11: 20MHz, 2b'10: 40MHz, 2b'01: 80MHz */
+ }
+
+ if (dm->support_ic_type == ODM_RTL8812)
+ dm_psd_table->psd_pwr_common_offset = 0;
+ else if (dm->support_ic_type == ODM_RTL8821)
+ dm_psd_table->psd_pwr_common_offset = 0;
+ else
+ dm_psd_table->psd_pwr_common_offset = 0;
+
+ phydm_psd_para_setting(dm, 1, 2, 3, 128, 0, 0, 7, 0);
+ /*phydm_psd(dm, 0x3c, 0, 127);*/ /* target at -50dBm */
+}
+
+void phydm_psd_debug(void *dm_void, char input[][16], u32 *_used, char *output,
+ u32 *_out_len, u32 input_num)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ char help[] = "-h";
+ u32 var1[10] = {0};
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+ u8 i;
+
+ if ((strcmp(input[1], help) == 0)) {
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "{0} {sw_avg} {hw_avg 0:3} {1:I,2:Q,3:IQ} {fft_point: 128*(1:4)} {path_sel 0~3} {0:ADC, 1:RXIQC} {CH} {noise_k}\n");
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "{1} {IGI(hex)} {start_point} {stop_point}\n");
+ return;
+ }
+
+ PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);
+
+ if (var1[0] == 0) {
+ for (i = 1; i < 10; i++) {
+ if (input[i + 1])
+ PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL,
+ &var1[i]);
+ }
+
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "sw_avg_time=((%d)), hw_avg_time=((%d)), IQ=((%d)), fft=((%d)), path=((%d)), input =((%d)) ch=((%d)), noise_k=((%d))\n",
+ var1[1], var1[2], var1[3], var1[4], var1[5], var1[6],
+ (u8)var1[7], (u8)var1[8]);
+ phydm_psd_para_setting(dm, (u8)var1[1], (u8)var1[2],
+ (u8)var1[3], (u16)var1[4], (u8)var1[5],
+ (u8)var1[6], (u8)var1[7], (u8)var1[8]);
+
+ } else if (var1[0] == 1) {
+ PHYDM_SSCANF(input[2], DCMD_HEX, &var1[1]);
+ PHYDM_SSCANF(input[3], DCMD_DECIMAL, &var1[2]);
+ PHYDM_SSCANF(input[4], DCMD_DECIMAL, &var1[3]);
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "IGI=((0x%x)), start_point=((%d)), stop_point=((%d))\n",
+ var1[1], var1[2], var1[3]);
+ dm->debug_components |= ODM_COMP_API;
+ phydm_psd(dm, var1[1], (u16)var1[2], (u16)var1[3]);
+ dm->debug_components &= (~ODM_COMP_API);
+ }
+}
+
+u8 phydm_get_psd_result_table(void *dm_void, int index)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct psd_info *dm_psd_table = &dm->dm_psd_table;
+ u8 temp_result = 0;
+
+ if (index < 128)
+ temp_result = dm_psd_table->psd_result[index];
+
+ return temp_result;
+}
diff --git a/drivers/staging/rtlwifi/phydm/phydm_psd.h b/drivers/staging/rtlwifi/phydm/phydm_psd.h
new file mode 100644
index 0000000..aeb7075
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_psd.h
@@ -0,0 +1,67 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __PHYDMPSD_H__
+#define __PHYDMPSD_H__
+
+/*#define PSD_VERSION "1.0"*/ /*2016.09.22 Dino*/
+#define PSD_VERSION "1.1" /*2016.10.07 Dino, Add Option for PSD Tone index
+ *Selection
+ */
+
+#define STOP_TRX_SUCCESS 1
+#define STOP_TRX_FAIL 0
+
+struct psd_info {
+ u8 psd_in_progress;
+ u32 psd_reg;
+ u32 psd_report_reg;
+ u8 psd_pwr_common_offset;
+ u16 sw_avg_time;
+ u16 fft_smp_point;
+ u32 initial_gain_backup;
+ u32 rf_0x18_bkp;
+ u16 psd_fc_channel;
+ u32 psd_bw_rf_reg;
+ u8 psd_result[128];
+ u8 noise_k_en;
+};
+
+u32 phydm_get_psd_data(void *dm_void, u32 psd_tone_idx, u32 igi);
+
+void phydm_psd_debug(void *dm_void, char input[][16], u32 *_used, char *output,
+ u32 *_out_len, u32 input_num);
+
+void phydm_psd(void *dm_void, u32 igi, u16 start_point, u16 stop_point);
+
+void phydm_psd_para_setting(void *dm_void, u8 sw_avg_time, u8 hw_avg_time,
+ u8 i_q_setting, u16 fft_smp_point, u8 ant_sel,
+ u8 psd_input, u8 channel, u8 noise_k_en);
+
+void phydm_psd_init(void *dm_void);
+
+u8 phydm_get_psd_result_table(void *dm_void, int index);
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/phydm_rainfo.c b/drivers/staging/rtlwifi/phydm/phydm_rainfo.c
new file mode 100644
index 0000000..8c08c76
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_rainfo.c
@@ -0,0 +1,1208 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+/* ************************************************************
+ * include files
+ * *************************************************************/
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+void phydm_h2C_debug(void *dm_void, u32 *const dm_value, u32 *_used,
+ char *output, u32 *_out_len)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u8 h2c_parameter[H2C_MAX_LENGTH] = {0};
+ u8 phydm_h2c_id = (u8)dm_value[0];
+ u8 i;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "Phydm Send H2C_ID (( 0x%x))\n", phydm_h2c_id);
+ for (i = 0; i < H2C_MAX_LENGTH; i++) {
+ h2c_parameter[i] = (u8)dm_value[i + 1];
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "H2C: Byte[%d] = ((0x%x))\n", i,
+ h2c_parameter[i]);
+ }
+
+ odm_fill_h2c_cmd(dm, phydm_h2c_id, H2C_MAX_LENGTH, h2c_parameter);
+}
+
+void phydm_RA_debug_PCR(void *dm_void, u32 *const dm_value, u32 *_used,
+ char *output, u32 *_out_len)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct ra_table *ra_tab = &dm->dm_ra_table;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ if (dm_value[0] == 100) {
+ PHYDM_SNPRINTF(
+ output + used, out_len - used,
+ "[Get] PCR RA_threshold_offset = (( %s%d ))\n",
+ ((ra_tab->RA_threshold_offset == 0) ?
+ " " :
+ ((ra_tab->RA_offset_direction) ? "+" : "-")),
+ ra_tab->RA_threshold_offset);
+ /**/
+ } else if (dm_value[0] == 0) {
+ ra_tab->RA_offset_direction = 0;
+ ra_tab->RA_threshold_offset = (u8)dm_value[1];
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "[Set] PCR RA_threshold_offset = (( -%d ))\n",
+ ra_tab->RA_threshold_offset);
+ } else if (dm_value[0] == 1) {
+ ra_tab->RA_offset_direction = 1;
+ ra_tab->RA_threshold_offset = (u8)dm_value[1];
+ PHYDM_SNPRINTF(output + used, out_len - used,
+ "[Set] PCR RA_threshold_offset = (( +%d ))\n",
+ ra_tab->RA_threshold_offset);
+ } else {
+ PHYDM_SNPRINTF(output + used, out_len - used, "[Set] Error\n");
+ /**/
+ }
+}
+
+void odm_c2h_ra_para_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ u8 para_idx = cmd_buf[0]; /*Retry Penalty, NH, NL*/
+ u8 i;
+
+ ODM_RT_TRACE(dm, PHYDM_COMP_RA_DBG,
+ "[ From FW C2H RA Para ] cmd_buf[0]= (( %d ))\n",
+ cmd_buf[0]);
+
+ if (para_idx == RADBG_DEBUG_MONITOR1) {
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE,
+ "-------------------------------\n");
+ if (dm->support_ic_type & PHYDM_IC_3081_SERIES) {
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n",
+ "RSSI =", cmd_buf[1]);
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n",
+ "rate =", cmd_buf[2] & 0x7f);
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n",
+ "SGI =", (cmd_buf[2] & 0x80) >> 7);
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n",
+ "BW =", cmd_buf[3]);
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n",
+ "BW_max =", cmd_buf[4]);
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n",
+ "multi_rate0 =", cmd_buf[5]);
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n",
+ "multi_rate1 =", cmd_buf[6]);
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n",
+ "DISRA =", cmd_buf[7]);
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n",
+ "VHT_EN =", cmd_buf[8]);
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n",
+ "SGI_support =", cmd_buf[9]);
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n",
+ "try_ness =", cmd_buf[10]);
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n",
+ "pre_rate =", cmd_buf[11]);
+ } else {
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n",
+ "RSSI =", cmd_buf[1]);
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %x\n",
+ "BW =", cmd_buf[2]);
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n",
+ "DISRA =", cmd_buf[3]);
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n",
+ "VHT_EN =", cmd_buf[4]);
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n",
+ "Hightest rate =", cmd_buf[5]);
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n",
+ "Lowest rate =", cmd_buf[6]);
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n",
+ "SGI_support =", cmd_buf[7]);
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n",
+ "Rate_ID =", cmd_buf[8]);
+ ;
+ }
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE,
+ "-------------------------------\n");
+ } else if (para_idx == RADBG_DEBUG_MONITOR2) {
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE,
+ "-------------------------------\n");
+ if (dm->support_ic_type & PHYDM_IC_3081_SERIES) {
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n",
+ "rate_id =", cmd_buf[1]);
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n",
+ "highest_rate =", cmd_buf[2]);
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n",
+ "lowest_rate =", cmd_buf[3]);
+
+ for (i = 4; i <= 11; i++)
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE,
+ "RAMASK = 0x%x\n", cmd_buf[i]);
+ } else {
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE,
+ "%5s %x%x %x%x %x%x %x%x\n",
+ "RA Mask:", cmd_buf[8], cmd_buf[7],
+ cmd_buf[6], cmd_buf[5], cmd_buf[4],
+ cmd_buf[3], cmd_buf[2], cmd_buf[1]);
+ }
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE,
+ "-------------------------------\n");
+ } else if (para_idx == RADBG_DEBUG_MONITOR3) {
+ for (i = 0; i < (cmd_len - 1); i++)
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE,
+ "content[%d] = %d\n", i, cmd_buf[1 + i]);
+ } else if (para_idx == RADBG_DEBUG_MONITOR4) {
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s {%d.%d}\n",
+ "RA version =", cmd_buf[1], cmd_buf[2]);
+ } else if (para_idx == RADBG_DEBUG_MONITOR5) {
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n",
+ "Current rate =", cmd_buf[1]);
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n",
+ "Retry ratio =", cmd_buf[2]);
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n",
+ "rate down ratio =", cmd_buf[3]);
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n",
+ "highest rate =", cmd_buf[4]);
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s {0x%x 0x%x}\n",
+ "Muti-try =", cmd_buf[5], cmd_buf[6]);
+ ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x%x%x%x%x\n",
+ "RA mask =", cmd_buf[11], cmd_buf[10], cmd_buf[9],
+ cmd_buf[8], cmd_buf[7]);
+ }
+}
+
+void phydm_ra_dynamic_retry_count(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ if (!(dm->support_ability & ODM_BB_DYNAMIC_ARFR))
+ return;
+
+ if (dm->pre_b_noisy != dm->noisy_decision) {
+ if (dm->noisy_decision) {
+ ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE,
+ "->Noisy Env. RA fallback value\n");
+ odm_set_mac_reg(dm, 0x430, MASKDWORD, 0x0);
+ odm_set_mac_reg(dm, 0x434, MASKDWORD, 0x04030201);
+ } else {
+ ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE,
+ "->Clean Env. RA fallback value\n");
+ odm_set_mac_reg(dm, 0x430, MASKDWORD, 0x01000000);
+ odm_set_mac_reg(dm, 0x434, MASKDWORD, 0x06050402);
+ }
+ dm->pre_b_noisy = dm->noisy_decision;
+ }
+}
+
+void phydm_ra_dynamic_retry_limit(void *dm_void) {}
+
+void phydm_print_rate(void *dm_void, u8 rate, u32 dbg_component)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u8 legacy_table[12] = {1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54};
+ u8 rate_idx = rate & 0x7f; /*remove bit7 SGI*/
+ u8 vht_en = (rate_idx >= ODM_RATEVHTSS1MCS0) ? 1 : 0;
+ u8 b_sgi = (rate & 0x80) >> 7;
+
+ ODM_RT_TRACE(dm, dbg_component, "( %s%s%s%s%d%s%s)\n",
+ ((rate_idx >= ODM_RATEVHTSS1MCS0) &&
+ (rate_idx <= ODM_RATEVHTSS1MCS9)) ?
+ "VHT 1ss " :
+ "",
+ ((rate_idx >= ODM_RATEVHTSS2MCS0) &&
+ (rate_idx <= ODM_RATEVHTSS2MCS9)) ?
+ "VHT 2ss " :
+ "",
+ ((rate_idx >= ODM_RATEVHTSS3MCS0) &&
+ (rate_idx <= ODM_RATEVHTSS3MCS9)) ?
+ "VHT 3ss " :
+ "",
+ (rate_idx >= ODM_RATEMCS0) ? "MCS " : "",
+ (vht_en) ? ((rate_idx - ODM_RATEVHTSS1MCS0) % 10) :
+ ((rate_idx >= ODM_RATEMCS0) ?
+ (rate_idx - ODM_RATEMCS0) :
+ ((rate_idx <= ODM_RATE54M) ?
+ legacy_table[rate_idx] :
+ 0)),
+ (b_sgi) ? "-S" : " ",
+ (rate_idx >= ODM_RATEMCS0) ? "" : "M");
+}
+
+void phydm_c2h_ra_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct ra_table *ra_tab = &dm->dm_ra_table;
+ u8 macid = cmd_buf[1];
+ u8 rate = cmd_buf[0];
+ u8 rate_idx = rate & 0x7f; /*remove bit7 SGI*/
+ u8 rate_order;
+
+ if (cmd_len >= 4) {
+ if (cmd_buf[3] == 0) {
+ ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE,
+ "TX Init-rate Update[%d]:", macid);
+ /**/
+ } else if (cmd_buf[3] == 0xff) {
+ ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE,
+ "FW Level: Fix rate[%d]:", macid);
+ /**/
+ } else if (cmd_buf[3] == 1) {
+ ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE,
+ "Try Success[%d]:", macid);
+ /**/
+ } else if (cmd_buf[3] == 2) {
+ ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE,
+ "Try Fail & Try Again[%d]:", macid);
+ /**/
+ } else if (cmd_buf[3] == 3) {
+ ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE,
+ "rate Back[%d]:", macid);
+ /**/
+ } else if (cmd_buf[3] == 4) {
+ ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE,
+ "start rate by RSSI[%d]:", macid);
+ /**/
+ } else if (cmd_buf[3] == 5) {
+ ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE,
+ "Try rate[%d]:", macid);
+ /**/
+ }
+ } else {
+ ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE, "Tx rate Update[%d]:",
+ macid);
+ /**/
+ }
+
+ phydm_print_rate(dm, rate, ODM_COMP_RATE_ADAPTIVE);
+
+ ra_tab->link_tx_rate[macid] = rate;
+
+ /*trigger power training*/
+
+ rate_order = phydm_rate_order_compute(dm, rate_idx);
+
+ if ((dm->is_one_entry_only) ||
+ ((rate_order > ra_tab->highest_client_tx_order) &&
+ (ra_tab->power_tracking_flag == 1))) {
+ phydm_update_pwr_track(dm, rate_idx);
+ ra_tab->power_tracking_flag = 0;
+ }
+
+ /*trigger dynamic rate ID*/
+}
+
+void odm_rssi_monitor_init(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct ra_table *ra_tab = &dm->dm_ra_table;
+
+ ra_tab->firstconnect = false;
+}
+
+void odm_ra_post_action_on_assoc(void *dm_void) {}
+
+void phydm_init_ra_info(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ if (dm->support_ic_type == ODM_RTL8822B) {
+ u32 ret_value;
+
+ ret_value = odm_get_bb_reg(dm, 0x4c8, MASKBYTE2);
+ odm_set_bb_reg(dm, 0x4cc, MASKBYTE3, (ret_value - 1));
+ }
+}
+
+void phydm_modify_RA_PCR_threshold(void *dm_void, u8 RA_offset_direction,
+ u8 RA_threshold_offset
+
+ )
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct ra_table *ra_tab = &dm->dm_ra_table;
+
+ ra_tab->RA_offset_direction = RA_offset_direction;
+ ra_tab->RA_threshold_offset = RA_threshold_offset;
+ ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
+ "Set RA_threshold_offset = (( %s%d ))\n",
+ ((RA_threshold_offset == 0) ?
+ " " :
+ ((RA_offset_direction) ? "+" : "-")),
+ RA_threshold_offset);
+}
+
+static void odm_rssi_monitor_check_mp(void *dm_void) {}
+
+static void odm_rssi_monitor_check_ce(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct ra_table *ra_tab = &dm->dm_ra_table;
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
+ struct rtl_mac *mac = rtl_mac(rtlpriv);
+ struct rtl_sta_info *entry;
+ int i;
+ int tmp_entry_min_pwdb = 0xff;
+ unsigned long cur_tx_ok_cnt = 0, cur_rx_ok_cnt = 0;
+ u8 UL_DL_STATE = 0, STBC_TX = 0, tx_bf_en = 0;
+ u8 h2c_parameter[H2C_0X42_LENGTH] = {0};
+ u8 cmdlen = H2C_0X42_LENGTH;
+ u8 macid = 0;
+
+ if (!dm->is_linked)
+ return;
+
+ for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
+ entry = (struct rtl_sta_info *)dm->odm_sta_info[i];
+ if (!IS_STA_VALID(entry))
+ continue;
+
+ if (is_multicast_ether_addr(entry->mac_addr) ||
+ is_broadcast_ether_addr(entry->mac_addr))
+ continue;
+
+ if (entry->rssi_stat.undecorated_smoothed_pwdb == (-1))
+ continue;
+
+ /* calculate min_pwdb */
+ if (entry->rssi_stat.undecorated_smoothed_pwdb <
+ tmp_entry_min_pwdb)
+ tmp_entry_min_pwdb =
+ entry->rssi_stat.undecorated_smoothed_pwdb;
+
+ /* report RSSI */
+ cur_tx_ok_cnt = rtlpriv->stats.txbytesunicast_inperiod;
+ cur_rx_ok_cnt = rtlpriv->stats.rxbytesunicast_inperiod;
+
+ if (cur_rx_ok_cnt > (cur_tx_ok_cnt * 6))
+ UL_DL_STATE = 1;
+ else
+ UL_DL_STATE = 0;
+
+ if (mac->opmode == NL80211_IFTYPE_AP ||
+ mac->opmode == NL80211_IFTYPE_ADHOC) {
+ struct ieee80211_sta *sta = container_of(
+ (void *)entry, struct ieee80211_sta, drv_priv);
+ macid = sta->aid + 1;
+ }
+
+ h2c_parameter[0] = macid;
+ h2c_parameter[2] =
+ entry->rssi_stat.undecorated_smoothed_pwdb & 0x7F;
+
+ if (UL_DL_STATE)
+ h2c_parameter[3] |= RAINFO_BE_RX_STATE;
+
+ if (tx_bf_en)
+ h2c_parameter[3] |= RAINFO_BF_STATE;
+ if (STBC_TX)
+ h2c_parameter[3] |= RAINFO_STBC_STATE;
+ if (dm->noisy_decision)
+ h2c_parameter[3] |= RAINFO_NOISY_STATE;
+
+ if (entry->rssi_stat.is_send_rssi == RA_RSSI_STATE_SEND) {
+ h2c_parameter[3] |= RAINFO_INIT_RSSI_RATE_STATE;
+ entry->rssi_stat.is_send_rssi = RA_RSSI_STATE_HOLD;
+ }
+
+ h2c_parameter[4] = (ra_tab->RA_threshold_offset & 0x7f) |
+ (ra_tab->RA_offset_direction << 7);
+
+ odm_fill_h2c_cmd(dm, ODM_H2C_RSSI_REPORT, cmdlen,
+ h2c_parameter);
+ }
+
+ if (tmp_entry_min_pwdb != 0xff)
+ dm->rssi_min = tmp_entry_min_pwdb;
+}
+
+static void odm_rssi_monitor_check_ap(void *dm_void) {}
+
+void odm_rssi_monitor_check(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ if (!(dm->support_ability & ODM_BB_RSSI_MONITOR))
+ return;
+
+ switch (dm->support_platform) {
+ case ODM_WIN:
+ odm_rssi_monitor_check_mp(dm);
+ break;
+
+ case ODM_CE:
+ odm_rssi_monitor_check_ce(dm);
+ break;
+
+ case ODM_AP:
+ odm_rssi_monitor_check_ap(dm);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void odm_rate_adaptive_mask_init(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct odm_rate_adaptive *odm_ra = &dm->rate_adaptive;
+
+ odm_ra->type = dm_type_by_driver;
+ if (odm_ra->type == dm_type_by_driver)
+ dm->is_use_ra_mask = true;
+ else
+ dm->is_use_ra_mask = false;
+
+ odm_ra->ratr_state = DM_RATR_STA_INIT;
+
+ odm_ra->ldpc_thres = 35;
+ odm_ra->is_use_ldpc = false;
+
+ odm_ra->high_rssi_thresh = 50;
+ odm_ra->low_rssi_thresh = 20;
+}
+
+/*-----------------------------------------------------------------------------
+ * Function: odm_refresh_rate_adaptive_mask()
+ *
+ * Overview: Update rate table mask according to rssi
+ *
+ * Input: NONE
+ *
+ * Output: NONE
+ *
+ * Return: NONE
+ *
+ * Revised History:
+ * When Who Remark
+ * 05/27/2009 hpfan Create version 0.
+ *
+ *---------------------------------------------------------------------------
+ */
+void odm_refresh_rate_adaptive_mask(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct ra_table *ra_tab = &dm->dm_ra_table;
+
+ if (!dm->is_linked)
+ return;
+
+ if (!(dm->support_ability & ODM_BB_RA_MASK)) {
+ ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
+ "%s(): Return cos not supported\n", __func__);
+ return;
+ }
+
+ ra_tab->force_update_ra_mask_count++;
+ /* 2011/09/29 MH In HW integration first stage, we provide 4 different
+ * handle to operate at the same time.
+ * In the stage2/3, we need to prive universal interface and merge all
+ * HW dynamic mechanism.
+ */
+ switch (dm->support_platform) {
+ case ODM_WIN:
+ odm_refresh_rate_adaptive_mask_mp(dm);
+ break;
+
+ case ODM_CE:
+ odm_refresh_rate_adaptive_mask_ce(dm);
+ break;
+
+ case ODM_AP:
+ odm_refresh_rate_adaptive_mask_apadsl(dm);
+ break;
+ }
+}
+
+static u8 phydm_trans_platform_bw(void *dm_void, u8 BW)
+{
+ if (BW == HT_CHANNEL_WIDTH_20)
+ BW = PHYDM_BW_20;
+
+ else if (BW == HT_CHANNEL_WIDTH_20_40)
+ BW = PHYDM_BW_40;
+
+ else if (BW == HT_CHANNEL_WIDTH_80)
+ BW = PHYDM_BW_80;
+
+ return BW;
+}
+
+static u8 phydm_trans_platform_rf_type(void *dm_void, u8 rf_type)
+{
+ if (rf_type == RF_1T2R)
+ rf_type = PHYDM_RF_1T2R;
+
+ else if (rf_type == RF_2T4R)
+ rf_type = PHYDM_RF_2T4R;
+
+ else if (rf_type == RF_2T2R)
+ rf_type = PHYDM_RF_2T2R;
+
+ else if (rf_type == RF_1T1R)
+ rf_type = PHYDM_RF_1T1R;
+
+ else if (rf_type == RF_2T2R_GREEN)
+ rf_type = PHYDM_RF_2T2R_GREEN;
+
+ else if (rf_type == RF_3T3R)
+ rf_type = PHYDM_RF_3T3R;
+
+ else if (rf_type == RF_4T4R)
+ rf_type = PHYDM_RF_4T4R;
+
+ else if (rf_type == RF_2T3R)
+ rf_type = PHYDM_RF_1T2R;
+
+ else if (rf_type == RF_3T4R)
+ rf_type = PHYDM_RF_3T4R;
+
+ return rf_type;
+}
+
+static u32 phydm_trans_platform_wireless_mode(void *dm_void, u32 wireless_mode)
+{
+ return wireless_mode;
+}
+
+u8 phydm_vht_en_mapping(void *dm_void, u32 wireless_mode)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u8 vht_en_out = 0;
+
+ if ((wireless_mode == PHYDM_WIRELESS_MODE_AC_5G) ||
+ (wireless_mode == PHYDM_WIRELESS_MODE_AC_24G) ||
+ (wireless_mode == PHYDM_WIRELESS_MODE_AC_ONLY)) {
+ vht_en_out = 1;
+ /**/
+ }
+
+ ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
+ "wireless_mode= (( 0x%x )), VHT_EN= (( %d ))\n",
+ wireless_mode, vht_en_out);
+ return vht_en_out;
+}
+
+u8 phydm_rate_id_mapping(void *dm_void, u32 wireless_mode, u8 rf_type, u8 bw)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u8 rate_id_idx = 0;
+ u8 phydm_BW;
+ u8 phydm_rf_type;
+
+ phydm_BW = phydm_trans_platform_bw(dm, bw);
+ phydm_rf_type = phydm_trans_platform_rf_type(dm, rf_type);
+ wireless_mode = phydm_trans_platform_wireless_mode(dm, wireless_mode);
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_RA_MASK,
+ "wireless_mode= (( 0x%x )), rf_type = (( 0x%x )), BW = (( 0x%x ))\n",
+ wireless_mode, phydm_rf_type, phydm_BW);
+
+ switch (wireless_mode) {
+ case PHYDM_WIRELESS_MODE_N_24G: {
+ if (phydm_BW == PHYDM_BW_40) {
+ if (phydm_rf_type == PHYDM_RF_1T1R)
+ rate_id_idx = PHYDM_BGN_40M_1SS;
+ else if (phydm_rf_type == PHYDM_RF_2T2R)
+ rate_id_idx = PHYDM_BGN_40M_2SS;
+ else
+ rate_id_idx = PHYDM_ARFR5_N_3SS;
+
+ } else {
+ if (phydm_rf_type == PHYDM_RF_1T1R)
+ rate_id_idx = PHYDM_BGN_20M_1SS;
+ else if (phydm_rf_type == PHYDM_RF_2T2R)
+ rate_id_idx = PHYDM_BGN_20M_2SS;
+ else
+ rate_id_idx = PHYDM_ARFR5_N_3SS;
+ }
+ } break;
+
+ case PHYDM_WIRELESS_MODE_N_5G: {
+ if (phydm_rf_type == PHYDM_RF_1T1R)
+ rate_id_idx = PHYDM_GN_N1SS;
+ else if (phydm_rf_type == PHYDM_RF_2T2R)
+ rate_id_idx = PHYDM_GN_N2SS;
+ else
+ rate_id_idx = PHYDM_ARFR5_N_3SS;
+ }
+
+ break;
+
+ case PHYDM_WIRELESS_MODE_G:
+ rate_id_idx = PHYDM_BG;
+ break;
+
+ case PHYDM_WIRELESS_MODE_A:
+ rate_id_idx = PHYDM_G;
+ break;
+
+ case PHYDM_WIRELESS_MODE_B:
+ rate_id_idx = PHYDM_B_20M;
+ break;
+
+ case PHYDM_WIRELESS_MODE_AC_5G:
+ case PHYDM_WIRELESS_MODE_AC_ONLY: {
+ if (phydm_rf_type == PHYDM_RF_1T1R)
+ rate_id_idx = PHYDM_ARFR1_AC_1SS;
+ else if (phydm_rf_type == PHYDM_RF_2T2R)
+ rate_id_idx = PHYDM_ARFR0_AC_2SS;
+ else
+ rate_id_idx = PHYDM_ARFR4_AC_3SS;
+ } break;
+
+ case PHYDM_WIRELESS_MODE_AC_24G: {
+ /*Becareful to set "Lowest rate" while using PHYDM_ARFR4_AC_3SS
+ *in 2.4G/5G
+ */
+ if (phydm_BW >= PHYDM_BW_80) {
+ if (phydm_rf_type == PHYDM_RF_1T1R)
+ rate_id_idx = PHYDM_ARFR1_AC_1SS;
+ else if (phydm_rf_type == PHYDM_RF_2T2R)
+ rate_id_idx = PHYDM_ARFR0_AC_2SS;
+ else
+ rate_id_idx = PHYDM_ARFR4_AC_3SS;
+ } else {
+ if (phydm_rf_type == PHYDM_RF_1T1R)
+ rate_id_idx = PHYDM_ARFR2_AC_2G_1SS;
+ else if (phydm_rf_type == PHYDM_RF_2T2R)
+ rate_id_idx = PHYDM_ARFR3_AC_2G_2SS;
+ else
+ rate_id_idx = PHYDM_ARFR4_AC_3SS;
+ }
+ } break;
+
+ default:
+ rate_id_idx = 0;
+ break;
+ }
+
+ ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, "RA rate ID = (( 0x%x ))\n",
+ rate_id_idx);
+
+ return rate_id_idx;
+}
+
+void phydm_update_hal_ra_mask(void *dm_void, u32 wireless_mode, u8 rf_type,
+ u8 BW, u8 mimo_ps_enable, u8 disable_cck_rate,
+ u32 *ratr_bitmap_msb_in, u32 *ratr_bitmap_lsb_in,
+ u8 tx_rate_level)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u8 phydm_rf_type;
+ u8 phydm_BW;
+ u32 ratr_bitmap = *ratr_bitmap_lsb_in,
+ ratr_bitmap_msb = *ratr_bitmap_msb_in;
+
+ wireless_mode = phydm_trans_platform_wireless_mode(dm, wireless_mode);
+
+ phydm_rf_type = phydm_trans_platform_rf_type(dm, rf_type);
+ phydm_BW = phydm_trans_platform_bw(dm, BW);
+
+ ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
+ "Platfoem original RA Mask = (( 0x %x | %x ))\n",
+ ratr_bitmap_msb, ratr_bitmap);
+
+ switch (wireless_mode) {
+ case PHYDM_WIRELESS_MODE_B: {
+ ratr_bitmap &= 0x0000000f;
+ } break;
+
+ case PHYDM_WIRELESS_MODE_G: {
+ ratr_bitmap &= 0x00000ff5;
+ } break;
+
+ case PHYDM_WIRELESS_MODE_A: {
+ ratr_bitmap &= 0x00000ff0;
+ } break;
+
+ case PHYDM_WIRELESS_MODE_N_24G:
+ case PHYDM_WIRELESS_MODE_N_5G: {
+ if (mimo_ps_enable)
+ phydm_rf_type = PHYDM_RF_1T1R;
+
+ if (phydm_rf_type == PHYDM_RF_1T1R) {
+ if (phydm_BW == PHYDM_BW_40)
+ ratr_bitmap &= 0x000ff015;
+ else
+ ratr_bitmap &= 0x000ff005;
+ } else if (phydm_rf_type == PHYDM_RF_2T2R ||
+ phydm_rf_type == PHYDM_RF_2T4R ||
+ phydm_rf_type == PHYDM_RF_2T3R) {
+ if (phydm_BW == PHYDM_BW_40)
+ ratr_bitmap &= 0x0ffff015;
+ else
+ ratr_bitmap &= 0x0ffff005;
+ } else { /*3T*/
+
+ ratr_bitmap &= 0xfffff015;
+ ratr_bitmap_msb &= 0xf;
+ }
+ } break;
+
+ case PHYDM_WIRELESS_MODE_AC_24G: {
+ if (phydm_rf_type == PHYDM_RF_1T1R) {
+ ratr_bitmap &= 0x003ff015;
+ } else if (phydm_rf_type == PHYDM_RF_2T2R ||
+ phydm_rf_type == PHYDM_RF_2T4R ||
+ phydm_rf_type == PHYDM_RF_2T3R) {
+ ratr_bitmap &= 0xfffff015;
+ } else { /*3T*/
+
+ ratr_bitmap &= 0xfffff010;
+ ratr_bitmap_msb &= 0x3ff;
+ }
+
+ if (phydm_BW ==
+ PHYDM_BW_20) { /* AC 20MHz doesn't support MCS9 */
+ ratr_bitmap &= 0x7fdfffff;
+ ratr_bitmap_msb &= 0x1ff;
+ }
+ } break;
+
+ case PHYDM_WIRELESS_MODE_AC_5G: {
+ if (phydm_rf_type == PHYDM_RF_1T1R) {
+ ratr_bitmap &= 0x003ff010;
+ } else if (phydm_rf_type == PHYDM_RF_2T2R ||
+ phydm_rf_type == PHYDM_RF_2T4R ||
+ phydm_rf_type == PHYDM_RF_2T3R) {
+ ratr_bitmap &= 0xfffff010;
+ } else { /*3T*/
+
+ ratr_bitmap &= 0xfffff010;
+ ratr_bitmap_msb &= 0x3ff;
+ }
+
+ if (phydm_BW ==
+ PHYDM_BW_20) { /* AC 20MHz doesn't support MCS9 */
+ ratr_bitmap &= 0x7fdfffff;
+ ratr_bitmap_msb &= 0x1ff;
+ }
+ } break;
+
+ default:
+ break;
+ }
+
+ if (wireless_mode != PHYDM_WIRELESS_MODE_B) {
+ if (tx_rate_level == 0)
+ ratr_bitmap &= 0xffffffff;
+ else if (tx_rate_level == 1)
+ ratr_bitmap &= 0xfffffff0;
+ else if (tx_rate_level == 2)
+ ratr_bitmap &= 0xffffefe0;
+ else if (tx_rate_level == 3)
+ ratr_bitmap &= 0xffffcfc0;
+ else if (tx_rate_level == 4)
+ ratr_bitmap &= 0xffff8f80;
+ else if (tx_rate_level >= 5)
+ ratr_bitmap &= 0xffff0f00;
+ }
+
+ if (disable_cck_rate)
+ ratr_bitmap &= 0xfffffff0;
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_RA_MASK,
+ "wireless_mode= (( 0x%x )), rf_type = (( 0x%x )), BW = (( 0x%x )), MimoPs_en = (( %d )), tx_rate_level= (( 0x%x ))\n",
+ wireless_mode, phydm_rf_type, phydm_BW, mimo_ps_enable,
+ tx_rate_level);
+
+ *ratr_bitmap_lsb_in = ratr_bitmap;
+ *ratr_bitmap_msb_in = ratr_bitmap_msb;
+ ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
+ "Phydm modified RA Mask = (( 0x %x | %x ))\n",
+ *ratr_bitmap_msb_in, *ratr_bitmap_lsb_in);
+}
+
+u8 phydm_RA_level_decision(void *dm_void, u32 rssi, u8 ratr_state)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u8 ra_rate_floor_table[RA_FLOOR_TABLE_SIZE] = {
+ 20, 34, 38, 42,
+ 46, 50, 100}; /*MCS0 ~ MCS4 , VHT1SS MCS0 ~ MCS4 , G 6M~24M*/
+ u8 new_ratr_state = 0;
+ u8 i;
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_RA_MASK,
+ "curr RA level = ((%d)), Rate_floor_table ori [ %d , %d, %d , %d, %d, %d]\n",
+ ratr_state, ra_rate_floor_table[0], ra_rate_floor_table[1],
+ ra_rate_floor_table[2], ra_rate_floor_table[3],
+ ra_rate_floor_table[4], ra_rate_floor_table[5]);
+
+ for (i = 0; i < RA_FLOOR_TABLE_SIZE; i++) {
+ if (i >= (ratr_state))
+ ra_rate_floor_table[i] += RA_FLOOR_UP_GAP;
+ }
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_RA_MASK,
+ "RSSI = ((%d)), Rate_floor_table_mod [ %d , %d, %d , %d, %d, %d]\n",
+ rssi, ra_rate_floor_table[0], ra_rate_floor_table[1],
+ ra_rate_floor_table[2], ra_rate_floor_table[3],
+ ra_rate_floor_table[4], ra_rate_floor_table[5]);
+
+ for (i = 0; i < RA_FLOOR_TABLE_SIZE; i++) {
+ if (rssi < ra_rate_floor_table[i]) {
+ new_ratr_state = i;
+ break;
+ }
+ }
+
+ return new_ratr_state;
+}
+
+void odm_refresh_rate_adaptive_mask_mp(void *dm_void) {}
+
+void odm_refresh_rate_adaptive_mask_ce(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct ra_table *ra_tab = &dm->dm_ra_table;
+ void *adapter = dm->adapter;
+ u32 i;
+ struct rtl_sta_info *entry;
+ u8 ratr_state_new;
+
+ if (!dm->is_use_ra_mask) {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_RA_MASK,
+ "<---- %s(): driver does not control rate adaptive mask\n",
+ __func__);
+ return;
+ }
+
+ for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
+ entry = dm->odm_sta_info[i];
+
+ if (!IS_STA_VALID(entry))
+ continue;
+
+ if (is_multicast_ether_addr(entry->mac_addr))
+ continue;
+ else if (is_broadcast_ether_addr(entry->mac_addr))
+ continue;
+
+ ratr_state_new = phydm_RA_level_decision(
+ dm, entry->rssi_stat.undecorated_smoothed_pwdb,
+ entry->rssi_level);
+
+ if ((entry->rssi_level != ratr_state_new) ||
+ (ra_tab->force_update_ra_mask_count >=
+ FORCED_UPDATE_RAMASK_PERIOD)) {
+ ra_tab->force_update_ra_mask_count = 0;
+ ODM_RT_TRACE(
+ dm, ODM_COMP_RA_MASK,
+ "Update Tx RA Level: ((%x)) -> ((%x)), RSSI = ((%d))\n",
+ entry->rssi_level, ratr_state_new,
+ entry->rssi_stat.undecorated_smoothed_pwdb);
+
+ entry->rssi_level = ratr_state_new;
+ rtl_hal_update_ra_mask(adapter, entry,
+ entry->rssi_level);
+ } else {
+ ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
+ "Stay in RA level = (( %d ))\n\n",
+ ratr_state_new);
+ /**/
+ }
+ }
+}
+
+void odm_refresh_rate_adaptive_mask_apadsl(void *dm_void) {}
+
+void odm_refresh_basic_rate_mask(void *dm_void) {}
+
+u8 phydm_rate_order_compute(void *dm_void, u8 rate_idx)
+{
+ u8 rate_order = 0;
+
+ if (rate_idx >= ODM_RATEVHTSS4MCS0) {
+ rate_idx -= ODM_RATEVHTSS4MCS0;
+ /**/
+ } else if (rate_idx >= ODM_RATEVHTSS3MCS0) {
+ rate_idx -= ODM_RATEVHTSS3MCS0;
+ /**/
+ } else if (rate_idx >= ODM_RATEVHTSS2MCS0) {
+ rate_idx -= ODM_RATEVHTSS2MCS0;
+ /**/
+ } else if (rate_idx >= ODM_RATEVHTSS1MCS0) {
+ rate_idx -= ODM_RATEVHTSS1MCS0;
+ /**/
+ } else if (rate_idx >= ODM_RATEMCS24) {
+ rate_idx -= ODM_RATEMCS24;
+ /**/
+ } else if (rate_idx >= ODM_RATEMCS16) {
+ rate_idx -= ODM_RATEMCS16;
+ /**/
+ } else if (rate_idx >= ODM_RATEMCS8) {
+ rate_idx -= ODM_RATEMCS8;
+ /**/
+ }
+ rate_order = rate_idx;
+
+ return rate_order;
+}
+
+static void phydm_ra_common_info_update(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct ra_table *ra_tab = &dm->dm_ra_table;
+ u16 macid;
+ u8 rate_order_tmp;
+ u8 cnt = 0;
+
+ ra_tab->highest_client_tx_order = 0;
+ ra_tab->power_tracking_flag = 1;
+
+ if (dm->number_linked_client != 0) {
+ for (macid = 0; macid < ODM_ASSOCIATE_ENTRY_NUM; macid++) {
+ rate_order_tmp = phydm_rate_order_compute(
+ dm, ((ra_tab->link_tx_rate[macid]) & 0x7f));
+
+ if (rate_order_tmp >=
+ (ra_tab->highest_client_tx_order)) {
+ ra_tab->highest_client_tx_order =
+ rate_order_tmp;
+ ra_tab->highest_client_tx_rate_order = macid;
+ }
+
+ cnt++;
+
+ if (cnt == dm->number_linked_client)
+ break;
+ }
+ ODM_RT_TRACE(
+ dm, ODM_COMP_RATE_ADAPTIVE,
+ "MACID[%d], Highest Tx order Update for power traking: %d\n",
+ (ra_tab->highest_client_tx_rate_order),
+ (ra_tab->highest_client_tx_order));
+ }
+}
+
+void phydm_ra_info_watchdog(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ phydm_ra_common_info_update(dm);
+ phydm_ra_dynamic_retry_limit(dm);
+ phydm_ra_dynamic_retry_count(dm);
+ odm_refresh_rate_adaptive_mask(dm);
+ odm_refresh_basic_rate_mask(dm);
+}
+
+void phydm_ra_info_init(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct ra_table *ra_tab = &dm->dm_ra_table;
+
+ ra_tab->highest_client_tx_rate_order = 0;
+ ra_tab->highest_client_tx_order = 0;
+ ra_tab->RA_threshold_offset = 0;
+ ra_tab->RA_offset_direction = 0;
+}
+
+u8 odm_find_rts_rate(void *dm_void, u8 tx_rate, bool is_erp_protect)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ u8 rts_ini_rate = ODM_RATE6M;
+
+ if (is_erp_protect) { /* use CCK rate as RTS*/
+ rts_ini_rate = ODM_RATE1M;
+ } else {
+ switch (tx_rate) {
+ case ODM_RATEVHTSS3MCS9:
+ case ODM_RATEVHTSS3MCS8:
+ case ODM_RATEVHTSS3MCS7:
+ case ODM_RATEVHTSS3MCS6:
+ case ODM_RATEVHTSS3MCS5:
+ case ODM_RATEVHTSS3MCS4:
+ case ODM_RATEVHTSS3MCS3:
+ case ODM_RATEVHTSS2MCS9:
+ case ODM_RATEVHTSS2MCS8:
+ case ODM_RATEVHTSS2MCS7:
+ case ODM_RATEVHTSS2MCS6:
+ case ODM_RATEVHTSS2MCS5:
+ case ODM_RATEVHTSS2MCS4:
+ case ODM_RATEVHTSS2MCS3:
+ case ODM_RATEVHTSS1MCS9:
+ case ODM_RATEVHTSS1MCS8:
+ case ODM_RATEVHTSS1MCS7:
+ case ODM_RATEVHTSS1MCS6:
+ case ODM_RATEVHTSS1MCS5:
+ case ODM_RATEVHTSS1MCS4:
+ case ODM_RATEVHTSS1MCS3:
+ case ODM_RATEMCS15:
+ case ODM_RATEMCS14:
+ case ODM_RATEMCS13:
+ case ODM_RATEMCS12:
+ case ODM_RATEMCS11:
+ case ODM_RATEMCS7:
+ case ODM_RATEMCS6:
+ case ODM_RATEMCS5:
+ case ODM_RATEMCS4:
+ case ODM_RATEMCS3:
+ case ODM_RATE54M:
+ case ODM_RATE48M:
+ case ODM_RATE36M:
+ case ODM_RATE24M:
+ rts_ini_rate = ODM_RATE24M;
+ break;
+ case ODM_RATEVHTSS3MCS2:
+ case ODM_RATEVHTSS3MCS1:
+ case ODM_RATEVHTSS2MCS2:
+ case ODM_RATEVHTSS2MCS1:
+ case ODM_RATEVHTSS1MCS2:
+ case ODM_RATEVHTSS1MCS1:
+ case ODM_RATEMCS10:
+ case ODM_RATEMCS9:
+ case ODM_RATEMCS2:
+ case ODM_RATEMCS1:
+ case ODM_RATE18M:
+ case ODM_RATE12M:
+ rts_ini_rate = ODM_RATE12M;
+ break;
+ case ODM_RATEVHTSS3MCS0:
+ case ODM_RATEVHTSS2MCS0:
+ case ODM_RATEVHTSS1MCS0:
+ case ODM_RATEMCS8:
+ case ODM_RATEMCS0:
+ case ODM_RATE9M:
+ case ODM_RATE6M:
+ rts_ini_rate = ODM_RATE6M;
+ break;
+ case ODM_RATE11M:
+ case ODM_RATE5_5M:
+ case ODM_RATE2M:
+ case ODM_RATE1M:
+ rts_ini_rate = ODM_RATE1M;
+ break;
+ default:
+ rts_ini_rate = ODM_RATE6M;
+ break;
+ }
+ }
+
+ if (*dm->band_type == 1) {
+ if (rts_ini_rate < ODM_RATE6M)
+ rts_ini_rate = ODM_RATE6M;
+ }
+ return rts_ini_rate;
+}
+
+static void odm_set_ra_dm_arfb_by_noisy(struct phy_dm_struct *dm) {}
+
+void odm_update_noisy_state(void *dm_void, bool is_noisy_state_from_c2h)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ /* JJ ADD 20161014 */
+ if (dm->support_ic_type == ODM_RTL8821 ||
+ dm->support_ic_type == ODM_RTL8812 ||
+ dm->support_ic_type == ODM_RTL8723B ||
+ dm->support_ic_type == ODM_RTL8192E ||
+ dm->support_ic_type == ODM_RTL8188E ||
+ dm->support_ic_type == ODM_RTL8723D ||
+ dm->support_ic_type == ODM_RTL8710B)
+ dm->is_noisy_state = is_noisy_state_from_c2h;
+ odm_set_ra_dm_arfb_by_noisy(dm);
+};
+
+void phydm_update_pwr_track(void *dm_void, u8 rate)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, "Pwr Track Get rate=0x%x\n",
+ rate);
+
+ dm->tx_rate = rate;
+}
+
+/* RA_MASK_PHYDMLIZE, will delete it later*/
+
+bool odm_ra_state_check(void *dm_void, s32 rssi, bool is_force_update,
+ u8 *ra_tr_state)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct odm_rate_adaptive *ra = &dm->rate_adaptive;
+ const u8 go_up_gap = 5;
+ u8 high_rssi_thresh_for_ra = ra->high_rssi_thresh;
+ u8 low_rssi_thresh_for_ra = ra->low_rssi_thresh;
+ u8 ratr_state;
+
+ ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
+ "RSSI= (( %d )), Current_RSSI_level = (( %d ))\n", rssi,
+ *ra_tr_state);
+ ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
+ "[Ori RA RSSI Thresh] High= (( %d )), Low = (( %d ))\n",
+ high_rssi_thresh_for_ra, low_rssi_thresh_for_ra);
+ /* threshold Adjustment:
+ * when RSSI state trends to go up one or two levels, make sure RSSI is
+ * high enough. Here go_up_gap is added to solve the boundary's level
+ * alternation issue.
+ */
+
+ switch (*ra_tr_state) {
+ case DM_RATR_STA_INIT:
+ case DM_RATR_STA_HIGH:
+ break;
+
+ case DM_RATR_STA_MIDDLE:
+ high_rssi_thresh_for_ra += go_up_gap;
+ break;
+
+ case DM_RATR_STA_LOW:
+ high_rssi_thresh_for_ra += go_up_gap;
+ low_rssi_thresh_for_ra += go_up_gap;
+ break;
+
+ default:
+ WARN_ONCE(true, "wrong rssi level setting %d !", *ra_tr_state);
+ break;
+ }
+
+ /* Decide ratr_state by RSSI.*/
+ if (rssi > high_rssi_thresh_for_ra)
+ ratr_state = DM_RATR_STA_HIGH;
+ else if (rssi > low_rssi_thresh_for_ra)
+ ratr_state = DM_RATR_STA_MIDDLE;
+
+ else
+ ratr_state = DM_RATR_STA_LOW;
+ ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
+ "[Mod RA RSSI Thresh] High= (( %d )), Low = (( %d ))\n",
+ high_rssi_thresh_for_ra, low_rssi_thresh_for_ra);
+
+ if (*ra_tr_state != ratr_state || is_force_update) {
+ ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
+ "[RSSI Level Update] %d->%d\n", *ra_tr_state,
+ ratr_state);
+ *ra_tr_state = ratr_state;
+ return true;
+ }
+
+ return false;
+}
diff --git a/drivers/staging/rtlwifi/phydm/phydm_rainfo.h b/drivers/staging/rtlwifi/phydm/phydm_rainfo.h
new file mode 100644
index 0000000..c14ed9b
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_rainfo.h
@@ -0,0 +1,269 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __PHYDMRAINFO_H__
+#define __PHYDMRAINFO_H__
+
+/*#define RAINFO_VERSION "2.0"*/ /*2014.11.04*/
+/*#define RAINFO_VERSION "3.0"*/ /*2015.01.13 Dino*/
+/*#define RAINFO_VERSION "3.1"*/ /*2015.01.14 Dino*/
+/*#define RAINFO_VERSION "3.3"*/ /*2015.07.29 YuChen*/
+/*#define RAINFO_VERSION "3.4"*/ /*2015.12.15 Stanley*/
+/*#define RAINFO_VERSION "4.0"*/ /*2016.03.24 Dino, Add more RA mask
+ *state and Phydm-lize partial ra mask
+ *function
+ */
+/*#define RAINFO_VERSION "4.1"*/ /*2016.04.20 Dino, Add new function to
+ *adjust PCR RA threshold
+ */
+/*#define RAINFO_VERSION "4.2"*/ /*2016.05.17 Dino, Add H2C debug cmd */
+#define RAINFO_VERSION "4.3" /*2016.07.11 Dino, Fix RA hang in CCK 1M problem*/
+
+#define FORCED_UPDATE_RAMASK_PERIOD 5
+
+#define H2C_0X42_LENGTH 5
+#define H2C_MAX_LENGTH 7
+
+#define RA_FLOOR_UP_GAP 3
+#define RA_FLOOR_TABLE_SIZE 7
+
+#define ACTIVE_TP_THRESHOLD 150
+#define RA_RETRY_DESCEND_NUM 2
+#define RA_RETRY_LIMIT_LOW 4
+#define RA_RETRY_LIMIT_HIGH 32
+
+#define RAINFO_BE_RX_STATE BIT(0) /* 1:RX */ /* ULDL */
+#define RAINFO_STBC_STATE BIT(1)
+/* #define RAINFO_LDPC_STATE BIT2 */
+#define RAINFO_NOISY_STATE BIT(2) /* set by Noisy_Detection */
+#define RAINFO_SHURTCUT_STATE BIT(3)
+#define RAINFO_SHURTCUT_FLAG BIT(4)
+#define RAINFO_INIT_RSSI_RATE_STATE BIT(5)
+#define RAINFO_BF_STATE BIT(6)
+#define RAINFO_BE_TX_STATE BIT(7) /* 1:TX */
+
+#define RA_MASK_CCK 0xf
+#define RA_MASK_OFDM 0xff0
+#define RA_MASK_HT1SS 0xff000
+#define RA_MASK_HT2SS 0xff00000
+/*#define RA_MASK_MCS3SS */
+#define RA_MASK_HT4SS 0xff0
+#define RA_MASK_VHT1SS 0x3ff000
+#define RA_MASK_VHT2SS 0xffc00000
+
+#define RA_FIRST_MACID 0
+
+#define ap_init_rate_adaptive_state odm_rate_adaptive_state_ap_init
+
+#define DM_RATR_STA_INIT 0
+#define DM_RATR_STA_HIGH 1
+#define DM_RATR_STA_MIDDLE 2
+#define DM_RATR_STA_LOW 3
+#define DM_RATR_STA_ULTRA_LOW 4
+
+enum phydm_ra_arfr_num {
+ ARFR_0_RATE_ID = 0x9,
+ ARFR_1_RATE_ID = 0xa,
+ ARFR_2_RATE_ID = 0xb,
+ ARFR_3_RATE_ID = 0xc,
+ ARFR_4_RATE_ID = 0xd,
+ ARFR_5_RATE_ID = 0xe
+};
+
+enum phydm_ra_dbg_para {
+ RADBG_PCR_TH_OFFSET = 0,
+ RADBG_RTY_PENALTY = 1,
+ RADBG_N_HIGH = 2,
+ RADBG_N_LOW = 3,
+ RADBG_TRATE_UP_TABLE = 4,
+ RADBG_TRATE_DOWN_TABLE = 5,
+ RADBG_TRYING_NECESSARY = 6,
+ RADBG_TDROPING_NECESSARY = 7,
+ RADBG_RATE_UP_RTY_RATIO = 8,
+ RADBG_RATE_DOWN_RTY_RATIO = 9, /* u8 */
+
+ RADBG_DEBUG_MONITOR1 = 0xc,
+ RADBG_DEBUG_MONITOR2 = 0xd,
+ RADBG_DEBUG_MONITOR3 = 0xe,
+ RADBG_DEBUG_MONITOR4 = 0xf,
+ RADBG_DEBUG_MONITOR5 = 0x10,
+ NUM_RA_PARA
+};
+
+enum phydm_wireless_mode {
+ PHYDM_WIRELESS_MODE_UNKNOWN = 0x00,
+ PHYDM_WIRELESS_MODE_A = 0x01,
+ PHYDM_WIRELESS_MODE_B = 0x02,
+ PHYDM_WIRELESS_MODE_G = 0x04,
+ PHYDM_WIRELESS_MODE_AUTO = 0x08,
+ PHYDM_WIRELESS_MODE_N_24G = 0x10,
+ PHYDM_WIRELESS_MODE_N_5G = 0x20,
+ PHYDM_WIRELESS_MODE_AC_5G = 0x40,
+ PHYDM_WIRELESS_MODE_AC_24G = 0x80,
+ PHYDM_WIRELESS_MODE_AC_ONLY = 0x100,
+ PHYDM_WIRELESS_MODE_MAX = 0x800,
+ PHYDM_WIRELESS_MODE_ALL = 0xFFFF
+};
+
+enum phydm_rateid_idx {
+ PHYDM_BGN_40M_2SS = 0,
+ PHYDM_BGN_40M_1SS = 1,
+ PHYDM_BGN_20M_2SS = 2,
+ PHYDM_BGN_20M_1SS = 3,
+ PHYDM_GN_N2SS = 4,
+ PHYDM_GN_N1SS = 5,
+ PHYDM_BG = 6,
+ PHYDM_G = 7,
+ PHYDM_B_20M = 8,
+ PHYDM_ARFR0_AC_2SS = 9,
+ PHYDM_ARFR1_AC_1SS = 10,
+ PHYDM_ARFR2_AC_2G_1SS = 11,
+ PHYDM_ARFR3_AC_2G_2SS = 12,
+ PHYDM_ARFR4_AC_3SS = 13,
+ PHYDM_ARFR5_N_3SS = 14
+};
+
+enum phydm_rf_type_def {
+ PHYDM_RF_1T1R = 0,
+ PHYDM_RF_1T2R,
+ PHYDM_RF_2T2R,
+ PHYDM_RF_2T2R_GREEN,
+ PHYDM_RF_2T3R,
+ PHYDM_RF_2T4R,
+ PHYDM_RF_3T3R,
+ PHYDM_RF_3T4R,
+ PHYDM_RF_4T4R,
+ PHYDM_RF_MAX_TYPE
+};
+
+enum phydm_bw {
+ PHYDM_BW_20 = 0,
+ PHYDM_BW_40,
+ PHYDM_BW_80,
+ PHYDM_BW_80_80,
+ PHYDM_BW_160,
+ PHYDM_BW_10,
+ PHYDM_BW_5
+};
+
+struct ra_table {
+ u8 firstconnect;
+
+ u8 link_tx_rate[ODM_ASSOCIATE_ENTRY_NUM];
+ u8 highest_client_tx_order;
+ u16 highest_client_tx_rate_order;
+ u8 power_tracking_flag;
+ u8 RA_threshold_offset;
+ u8 RA_offset_direction;
+ u8 force_update_ra_mask_count;
+};
+
+struct odm_rate_adaptive {
+ /* dm_type_by_fw/dm_type_by_driver */
+ u8 type;
+ /* if RSSI > high_rssi_thresh => ratr_state is DM_RATR_STA_HIGH */
+ u8 high_rssi_thresh;
+ /* if RSSI <= low_rssi_thresh => ratr_state is DM_RATR_STA_LOW */
+ u8 low_rssi_thresh;
+ /* Cur RSSI level, DM_RATR_STA_HIGH/DM_RATR_STA_MIDDLE/DM_RATR_STA_LOW*/
+ u8 ratr_state;
+
+ /* if RSSI > ldpc_thres => switch from LPDC to BCC */
+ u8 ldpc_thres;
+ bool is_lower_rts_rate;
+
+ bool is_use_ldpc;
+};
+
+void phydm_h2C_debug(void *dm_void, u32 *const dm_value, u32 *_used,
+ char *output, u32 *_out_len);
+
+void phydm_RA_debug_PCR(void *dm_void, u32 *const dm_value, u32 *_used,
+ char *output, u32 *_out_len);
+
+void odm_c2h_ra_para_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len);
+
+void odm_ra_para_adjust(void *dm_void);
+
+void phydm_ra_dynamic_retry_count(void *dm_void);
+
+void phydm_ra_dynamic_retry_limit(void *dm_void);
+
+void phydm_ra_dynamic_rate_id_on_assoc(void *dm_void, u8 wireless_mode,
+ u8 init_rate_id);
+
+void phydm_print_rate(void *dm_void, u8 rate, u32 dbg_component);
+
+void phydm_c2h_ra_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len);
+
+u8 phydm_rate_order_compute(void *dm_void, u8 rate_idx);
+
+void phydm_ra_info_watchdog(void *dm_void);
+
+void phydm_ra_info_init(void *dm_void);
+
+void odm_rssi_monitor_init(void *dm_void);
+
+void phydm_modify_RA_PCR_threshold(void *dm_void, u8 RA_offset_direction,
+ u8 RA_threshold_offset);
+
+void odm_rssi_monitor_check(void *dm_void);
+
+void phydm_init_ra_info(void *dm_void);
+
+u8 phydm_vht_en_mapping(void *dm_void, u32 wireless_mode);
+
+u8 phydm_rate_id_mapping(void *dm_void, u32 wireless_mode, u8 rf_type, u8 bw);
+
+void phydm_update_hal_ra_mask(void *dm_void, u32 wireless_mode, u8 rf_type,
+ u8 BW, u8 mimo_ps_enable, u8 disable_cck_rate,
+ u32 *ratr_bitmap_msb_in, u32 *ratr_bitmap_in,
+ u8 tx_rate_level);
+
+void odm_rate_adaptive_mask_init(void *dm_void);
+
+void odm_refresh_rate_adaptive_mask(void *dm_void);
+
+void odm_refresh_rate_adaptive_mask_mp(void *dm_void);
+
+void odm_refresh_rate_adaptive_mask_ce(void *dm_void);
+
+void odm_refresh_rate_adaptive_mask_apadsl(void *dm_void);
+
+u8 phydm_RA_level_decision(void *dm_void, u32 rssi, u8 ratr_state);
+
+bool odm_ra_state_check(void *dm_void, s32 RSSI, bool is_force_update,
+ u8 *ra_tr_state);
+
+void odm_refresh_basic_rate_mask(void *dm_void);
+void odm_ra_post_action_on_assoc(void *dm);
+
+u8 odm_find_rts_rate(void *dm_void, u8 tx_rate, bool is_erp_protect);
+
+void odm_update_noisy_state(void *dm_void, bool is_noisy_state_from_c2h);
+
+void phydm_update_pwr_track(void *dm_void, u8 rate);
+
+#endif /*#ifndef __ODMRAINFO_H__*/
diff --git a/drivers/staging/rtlwifi/phydm/phydm_reg.h b/drivers/staging/rtlwifi/phydm/phydm_reg.h
new file mode 100644
index 0000000..d9d878e
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_reg.h
@@ -0,0 +1,151 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+/* ************************************************************
+ * File Name: odm_reg.h
+ *
+ * Description:
+ *
+ * This file is for general register definition.
+ *
+ *
+ * *************************************************************/
+#ifndef __HAL_ODM_REG_H__
+#define __HAL_ODM_REG_H__
+
+/*
+ * Register Definition
+ */
+
+/* MAC REG */
+#define ODM_BB_RESET 0x002
+#define ODM_DUMMY 0x4fe
+#define RF_T_METER_OLD 0x24
+#define RF_T_METER_NEW 0x42
+
+#define ODM_EDCA_VO_PARAM 0x500
+#define ODM_EDCA_VI_PARAM 0x504
+#define ODM_EDCA_BE_PARAM 0x508
+#define ODM_EDCA_BK_PARAM 0x50C
+#define ODM_TXPAUSE 0x522
+
+/* LTE_COEX */
+#define REG_LTECOEX_CTRL 0x07C0
+#define REG_LTECOEX_WRITE_DATA 0x07C4
+#define REG_LTECOEX_READ_DATA 0x07C8
+#define REG_LTECOEX_PATH_CONTROL 0x70
+
+/* BB REG */
+#define ODM_FPGA_PHY0_PAGE8 0x800
+#define ODM_PSD_SETTING 0x808
+#define ODM_AFE_SETTING 0x818
+#define ODM_TXAGC_B_6_18 0x830
+#define ODM_TXAGC_B_24_54 0x834
+#define ODM_TXAGC_B_MCS32_5 0x838
+#define ODM_TXAGC_B_MCS0_MCS3 0x83c
+#define ODM_TXAGC_B_MCS4_MCS7 0x848
+#define ODM_TXAGC_B_MCS8_MCS11 0x84c
+#define ODM_ANALOG_REGISTER 0x85c
+#define ODM_RF_INTERFACE_OUTPUT 0x860
+#define ODM_TXAGC_B_MCS12_MCS15 0x868
+#define ODM_TXAGC_B_11_A_2_11 0x86c
+#define ODM_AD_DA_LSB_MASK 0x874
+#define ODM_ENABLE_3_WIRE 0x88c
+#define ODM_PSD_REPORT 0x8b4
+#define ODM_R_ANT_SELECT 0x90c
+#define ODM_CCK_ANT_SELECT 0xa07
+#define ODM_CCK_PD_THRESH 0xa0a
+#define ODM_CCK_RF_REG1 0xa11
+#define ODM_CCK_MATCH_FILTER 0xa20
+#define ODM_CCK_RAKE_MAC 0xa2e
+#define ODM_CCK_CNT_RESET 0xa2d
+#define ODM_CCK_TX_DIVERSITY 0xa2f
+#define ODM_CCK_FA_CNT_MSB 0xa5b
+#define ODM_CCK_FA_CNT_LSB 0xa5c
+#define ODM_CCK_NEW_FUNCTION 0xa75
+#define ODM_OFDM_PHY0_PAGE_C 0xc00
+#define ODM_OFDM_RX_ANT 0xc04
+#define ODM_R_A_RXIQI 0xc14
+#define ODM_R_A_AGC_CORE1 0xc50
+#define ODM_R_A_AGC_CORE2 0xc54
+#define ODM_R_B_AGC_CORE1 0xc58
+#define ODM_R_AGC_PAR 0xc70
+#define ODM_R_HTSTF_AGC_PAR 0xc7c
+#define ODM_TX_PWR_TRAINING_A 0xc90
+#define ODM_TX_PWR_TRAINING_B 0xc98
+#define ODM_OFDM_FA_CNT1 0xcf0
+#define ODM_OFDM_PHY0_PAGE_D 0xd00
+#define ODM_OFDM_FA_CNT2 0xda0
+#define ODM_OFDM_FA_CNT3 0xda4
+#define ODM_OFDM_FA_CNT4 0xda8
+#define ODM_TXAGC_A_6_18 0xe00
+#define ODM_TXAGC_A_24_54 0xe04
+#define ODM_TXAGC_A_1_MCS32 0xe08
+#define ODM_TXAGC_A_MCS0_MCS3 0xe10
+#define ODM_TXAGC_A_MCS4_MCS7 0xe14
+#define ODM_TXAGC_A_MCS8_MCS11 0xe18
+#define ODM_TXAGC_A_MCS12_MCS15 0xe1c
+
+/* RF REG */
+#define ODM_GAIN_SETTING 0x00
+#define ODM_CHANNEL 0x18
+#define ODM_RF_T_METER 0x24
+#define ODM_RF_T_METER_92D 0x42
+#define ODM_RF_T_METER_88E 0x42
+#define ODM_RF_T_METER_92E 0x42
+#define ODM_RF_T_METER_8812 0x42
+#define REG_RF_TX_GAIN_OFFSET 0x55
+
+/* ant Detect Reg */
+#define ODM_DPDT 0x300
+
+/* PSD Init */
+#define ODM_PSDREG 0x808
+
+/* 92D path Div */
+#define PATHDIV_REG 0xB30
+#define PATHDIV_TRI 0xBA0
+
+/*
+ * Bitmap Definition
+ */
+
+#define BIT_FA_RESET BIT(0)
+
+#define REG_OFDM_0_XA_TX_IQ_IMBALANCE 0xC80
+#define REG_OFDM_0_ECCA_THRESHOLD 0xC4C
+#define REG_FPGA0_XB_LSSI_READ_BACK 0x8A4
+#define REG_FPGA0_TX_GAIN_STAGE 0x80C
+#define REG_OFDM_0_XA_AGC_CORE1 0xC50
+#define REG_OFDM_0_XB_AGC_CORE1 0xC58
+#define REG_A_TX_SCALE_JAGUAR 0xC1C
+#define REG_B_TX_SCALE_JAGUAR 0xE1C
+
+#define REG_AFE_XTAL_CTRL 0x0024
+#define REG_AFE_PLL_CTRL 0x0028
+#define REG_MAC_PHY_CTRL 0x002C
+
+#define RF_CHNLBW 0x18
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/phydm_regdefine11ac.h b/drivers/staging/rtlwifi/phydm/phydm_regdefine11ac.h
new file mode 100644
index 0000000..28d4841
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_regdefine11ac.h
@@ -0,0 +1,94 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __ODM_REGDEFINE11AC_H__
+#define __ODM_REGDEFINE11AC_H__
+
+/* 2 RF REG LIST */
+
+/* 2 BB REG LIST */
+/* PAGE 8 */
+#define ODM_REG_CCK_RPT_FORMAT_11AC 0x804
+#define ODM_REG_BB_RX_PATH_11AC 0x808
+#define ODM_REG_BB_TX_PATH_11AC 0x80c
+#define ODM_REG_BB_ATC_11AC 0x860
+#define ODM_REG_EDCCA_POWER_CAL 0x8dc
+#define ODM_REG_DBG_RPT_11AC 0x8fc
+/* PAGE 9 */
+#define ODM_REG_EDCCA_DOWN_OPT 0x900
+#define ODM_REG_ACBB_EDCCA_ENHANCE 0x944
+#define odm_adc_trigger_jaguar2 0x95C /*ADC sample mode*/
+#define ODM_REG_OFDM_FA_RST_11AC 0x9A4
+#define ODM_REG_CCX_PERIOD_11AC 0x990
+#define ODM_REG_NHM_TH9_TH10_11AC 0x994
+#define ODM_REG_CLM_11AC 0x994
+#define ODM_REG_NHM_TH3_TO_TH0_11AC 0x998
+#define ODM_REG_NHM_TH7_TO_TH4_11AC 0x99c
+#define ODM_REG_NHM_TH8_11AC 0x9a0
+#define ODM_REG_NHM_9E8_11AC 0x9e8
+#define ODM_REG_CSI_CONTENT_VALUE 0x9b4
+/* PAGE A */
+#define ODM_REG_CCK_CCA_11AC 0xA0A
+#define ODM_REG_CCK_FA_RST_11AC 0xA2C
+#define ODM_REG_CCK_FA_11AC 0xA5C
+/* PAGE B */
+#define ODM_REG_RST_RPT_11AC 0xB58
+/* PAGE C */
+#define ODM_REG_TRMUX_11AC 0xC08
+#define ODM_REG_IGI_A_11AC 0xC50
+/* PAGE E */
+#define ODM_REG_IGI_B_11AC 0xE50
+#define ODM_REG_TRMUX_11AC_B 0xE08
+/* PAGE F */
+#define ODM_REG_CCK_CRC32_CNT_11AC 0xF04
+#define ODM_REG_CCK_CCA_CNT_11AC 0xF08
+#define ODM_REG_VHT_CRC32_CNT_11AC 0xF0c
+#define ODM_REG_HT_CRC32_CNT_11AC 0xF10
+#define ODM_REG_OFDM_CRC32_CNT_11AC 0xF14
+#define ODM_REG_OFDM_FA_11AC 0xF48
+#define ODM_REG_RPT_11AC 0xfa0
+#define ODM_REG_CLM_RESULT_11AC 0xfa4
+#define ODM_REG_NHM_CNT_11AC 0xfa8
+#define ODM_REG_NHM_DUR_READY_11AC 0xfb4
+
+#define ODM_REG_NHM_CNT7_TO_CNT4_11AC 0xfac
+#define ODM_REG_NHM_CNT11_TO_CNT8_11AC 0xfb0
+#define ODM_REG_OFDM_FA_TYPE2_11AC 0xFD0
+/* PAGE 18 */
+#define ODM_REG_IGI_C_11AC 0x1850
+/* PAGE 1A */
+#define ODM_REG_IGI_D_11AC 0x1A50
+
+/* 2 MAC REG LIST */
+#define ODM_REG_RESP_TX_11AC 0x6D8
+
+/* DIG Related */
+#define ODM_BIT_IGI_11AC 0xFFFFFFFF
+#define ODM_BIT_CCK_RPT_FORMAT_11AC BIT(16)
+#define ODM_BIT_BB_RX_PATH_11AC 0xF
+#define ODM_BIT_BB_TX_PATH_11AC 0xF
+#define ODM_BIT_BB_ATC_11AC BIT(14)
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/phydm_regdefine11n.h b/drivers/staging/rtlwifi/phydm/phydm_regdefine11n.h
new file mode 100644
index 0000000..0b6581c
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_regdefine11n.h
@@ -0,0 +1,213 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __ODM_REGDEFINE11N_H__
+#define __ODM_REGDEFINE11N_H__
+
+/* 2 RF REG LIST */
+#define ODM_REG_RF_MODE_11N 0x00
+#define ODM_REG_RF_0B_11N 0x0B
+#define ODM_REG_CHNBW_11N 0x18
+#define ODM_REG_T_METER_11N 0x24
+#define ODM_REG_RF_25_11N 0x25
+#define ODM_REG_RF_26_11N 0x26
+#define ODM_REG_RF_27_11N 0x27
+#define ODM_REG_RF_2B_11N 0x2B
+#define ODM_REG_RF_2C_11N 0x2C
+#define ODM_REG_RXRF_A3_11N 0x3C
+#define ODM_REG_T_METER_92D_11N 0x42
+#define ODM_REG_T_METER_88E_11N 0x42
+
+/* 2 BB REG LIST */
+/* PAGE 8 */
+#define ODM_REG_BB_CTRL_11N 0x800
+#define ODM_REG_RF_PIN_11N 0x804
+#define ODM_REG_PSD_CTRL_11N 0x808
+#define ODM_REG_TX_ANT_CTRL_11N 0x80C
+#define ODM_REG_BB_PWR_SAV5_11N 0x818
+#define ODM_REG_CCK_RPT_FORMAT_11N 0x824
+#define ODM_REG_CCK_RPT_FORMAT_11N_B 0x82C
+#define ODM_REG_RX_DEFAULT_A_11N 0x858
+#define ODM_REG_RX_DEFAULT_B_11N 0x85A
+#define ODM_REG_BB_PWR_SAV3_11N 0x85C
+#define ODM_REG_ANTSEL_CTRL_11N 0x860
+#define ODM_REG_RX_ANT_CTRL_11N 0x864
+#define ODM_REG_PIN_CTRL_11N 0x870
+#define ODM_REG_BB_PWR_SAV1_11N 0x874
+#define ODM_REG_ANTSEL_PATH_11N 0x878
+#define ODM_REG_BB_3WIRE_11N 0x88C
+#define ODM_REG_SC_CNT_11N 0x8C4
+#define ODM_REG_PSD_DATA_11N 0x8B4
+#define ODM_REG_CCX_PERIOD_11N 0x894
+#define ODM_REG_NHM_TH9_TH10_11N 0x890
+#define ODM_REG_CLM_11N 0x890
+#define ODM_REG_NHM_TH3_TO_TH0_11N 0x898
+#define ODM_REG_NHM_TH7_TO_TH4_11N 0x89c
+#define ODM_REG_NHM_TH8_11N 0xe28
+#define ODM_REG_CLM_READY_11N 0x8b4
+#define ODM_REG_CLM_RESULT_11N 0x8d0
+#define ODM_REG_NHM_CNT_11N 0x8d8
+
+/* For struct acs_info, Jeffery, 2014-12-26 */
+#define ODM_REG_NHM_CNT7_TO_CNT4_11N 0x8dc
+#define ODM_REG_NHM_CNT9_TO_CNT8_11N 0x8d0
+#define ODM_REG_NHM_CNT10_TO_CNT11_11N 0x8d4
+
+/* PAGE 9 */
+#define ODM_REG_BB_CTRL_PAGE9_11N 0x900
+#define ODM_REG_DBG_RPT_11N 0x908
+#define ODM_REG_BB_TX_PATH_11N 0x90c
+#define ODM_REG_ANT_MAPPING1_11N 0x914
+#define ODM_REG_ANT_MAPPING2_11N 0x918
+#define ODM_REG_EDCCA_DOWN_OPT_11N 0x948
+#define ODM_REG_RX_DFIR_MOD_97F 0x948
+
+/* PAGE A */
+#define ODM_REG_CCK_ANTDIV_PARA1_11N 0xA00
+#define ODM_REG_CCK_ANT_SEL_11N 0xA04
+#define ODM_REG_CCK_CCA_11N 0xA0A
+#define ODM_REG_CCK_ANTDIV_PARA2_11N 0xA0C
+#define ODM_REG_CCK_ANTDIV_PARA3_11N 0xA10
+#define ODM_REG_CCK_ANTDIV_PARA4_11N 0xA14
+#define ODM_REG_CCK_FILTER_PARA1_11N 0xA22
+#define ODM_REG_CCK_FILTER_PARA2_11N 0xA23
+#define ODM_REG_CCK_FILTER_PARA3_11N 0xA24
+#define ODM_REG_CCK_FILTER_PARA4_11N 0xA25
+#define ODM_REG_CCK_FILTER_PARA5_11N 0xA26
+#define ODM_REG_CCK_FILTER_PARA6_11N 0xA27
+#define ODM_REG_CCK_FILTER_PARA7_11N 0xA28
+#define ODM_REG_CCK_FILTER_PARA8_11N 0xA29
+#define ODM_REG_CCK_FA_RST_11N 0xA2C
+#define ODM_REG_CCK_FA_MSB_11N 0xA58
+#define ODM_REG_CCK_FA_LSB_11N 0xA5C
+#define ODM_REG_CCK_CCA_CNT_11N 0xA60
+#define ODM_REG_BB_PWR_SAV4_11N 0xA74
+/* PAGE B */
+#define ODM_REG_LNA_SWITCH_11N 0xB2C
+#define ODM_REG_PATH_SWITCH_11N 0xB30
+#define ODM_REG_RSSI_CTRL_11N 0xB38
+#define ODM_REG_CONFIG_ANTA_11N 0xB68
+#define ODM_REG_RSSI_BT_11N 0xB9C
+#define ODM_REG_RXCK_RFMOD 0xBB0
+#define ODM_REG_EDCCA_DCNF_97F 0xBC0
+
+/* PAGE C */
+#define ODM_REG_OFDM_FA_HOLDC_11N 0xC00
+#define ODM_REG_BB_RX_PATH_11N 0xC04
+#define ODM_REG_TRMUX_11N 0xC08
+#define ODM_REG_OFDM_FA_RSTC_11N 0xC0C
+#define ODM_REG_DOWNSAM_FACTOR_11N 0xC10
+#define ODM_REG_RXIQI_MATRIX_11N 0xC14
+#define ODM_REG_TXIQK_MATRIX_LSB1_11N 0xC4C
+#define ODM_REG_IGI_A_11N 0xC50
+#define ODM_REG_ANTDIV_PARA2_11N 0xC54
+#define ODM_REG_IGI_B_11N 0xC58
+#define ODM_REG_ANTDIV_PARA3_11N 0xC5C
+#define ODM_REG_L1SBD_PD_CH_11N 0XC6C
+#define ODM_REG_BB_PWR_SAV2_11N 0xC70
+#define ODM_REG_BB_AGC_SET_2_11N 0xc74
+#define ODM_REG_RX_OFF_11N 0xC7C
+#define ODM_REG_TXIQK_MATRIXA_11N 0xC80
+#define ODM_REG_TXIQK_MATRIXB_11N 0xC88
+#define ODM_REG_TXIQK_MATRIXA_LSB2_11N 0xC94
+#define ODM_REG_TXIQK_MATRIXB_LSB2_11N 0xC9C
+#define ODM_REG_RXIQK_MATRIX_LSB_11N 0xCA0
+#define ODM_REG_ANTDIV_PARA1_11N 0xCA4
+#define ODM_REG_SMALL_BANDWIDTH_11N 0xCE4
+#define ODM_REG_OFDM_FA_TYPE1_11N 0xCF0
+/* PAGE D */
+#define ODM_REG_OFDM_FA_RSTD_11N 0xD00
+#define ODM_REG_BB_RX_ANT_11N 0xD04
+#define ODM_REG_BB_ATC_11N 0xD2C
+#define ODM_REG_OFDM_FA_TYPE2_11N 0xDA0
+#define ODM_REG_OFDM_FA_TYPE3_11N 0xDA4
+#define ODM_REG_OFDM_FA_TYPE4_11N 0xDA8
+#define ODM_REG_RPT_11N 0xDF4
+/* PAGE E */
+#define ODM_REG_TXAGC_A_6_18_11N 0xE00
+#define ODM_REG_TXAGC_A_24_54_11N 0xE04
+#define ODM_REG_TXAGC_A_1_MCS32_11N 0xE08
+#define ODM_REG_TXAGC_A_MCS0_3_11N 0xE10
+#define ODM_REG_TXAGC_A_MCS4_7_11N 0xE14
+#define ODM_REG_TXAGC_A_MCS8_11_11N 0xE18
+#define ODM_REG_TXAGC_A_MCS12_15_11N 0xE1C
+#define ODM_REG_EDCCA_DCNF_11N 0xE24
+#define ODM_REG_TAP_UPD_97F 0xE24
+#define ODM_REG_FPGA0_IQK_11N 0xE28
+#define ODM_REG_PAGE_B1_97F 0xE28
+#define ODM_REG_TXIQK_TONE_A_11N 0xE30
+#define ODM_REG_RXIQK_TONE_A_11N 0xE34
+#define ODM_REG_TXIQK_PI_A_11N 0xE38
+#define ODM_REG_RXIQK_PI_A_11N 0xE3C
+#define ODM_REG_TXIQK_11N 0xE40
+#define ODM_REG_RXIQK_11N 0xE44
+#define ODM_REG_IQK_AGC_PTS_11N 0xE48
+#define ODM_REG_IQK_AGC_RSP_11N 0xE4C
+#define ODM_REG_BLUETOOTH_11N 0xE6C
+#define ODM_REG_RX_WAIT_CCA_11N 0xE70
+#define ODM_REG_TX_CCK_RFON_11N 0xE74
+#define ODM_REG_TX_CCK_BBON_11N 0xE78
+#define ODM_REG_OFDM_RFON_11N 0xE7C
+#define ODM_REG_OFDM_BBON_11N 0xE80
+#define ODM_REG_TX2RX_11N 0xE84
+#define ODM_REG_TX2TX_11N 0xE88
+#define ODM_REG_RX_CCK_11N 0xE8C
+#define ODM_REG_RX_OFDM_11N 0xED0
+#define ODM_REG_RX_WAIT_RIFS_11N 0xED4
+#define ODM_REG_RX2RX_11N 0xED8
+#define ODM_REG_STANDBY_11N 0xEDC
+#define ODM_REG_SLEEP_11N 0xEE0
+#define ODM_REG_PMPD_ANAEN_11N 0xEEC
+/* PAGE F */
+#define ODM_REG_PAGE_F_RST_11N 0xF14
+#define ODM_REG_IGI_C_11N 0xF84
+#define ODM_REG_IGI_D_11N 0xF88
+#define ODM_REG_CCK_CRC32_ERROR_CNT_11N 0xF84
+#define ODM_REG_CCK_CRC32_OK_CNT_11N 0xF88
+#define ODM_REG_HT_CRC32_CNT_11N 0xF90
+#define ODM_REG_OFDM_CRC32_CNT_11N 0xF94
+
+/* 2 MAC REG LIST */
+#define ODM_REG_BB_RST_11N 0x02
+#define ODM_REG_ANTSEL_PIN_11N 0x4C
+#define ODM_REG_EARLY_MODE_11N 0x4D0
+#define ODM_REG_RSSI_MONITOR_11N 0x4FE
+#define ODM_REG_EDCA_VO_11N 0x500
+#define ODM_REG_EDCA_VI_11N 0x504
+#define ODM_REG_EDCA_BE_11N 0x508
+#define ODM_REG_EDCA_BK_11N 0x50C
+#define ODM_REG_TXPAUSE_11N 0x522
+#define ODM_REG_RESP_TX_11N 0x6D8
+#define ODM_REG_ANT_TRAIN_PARA1_11N 0x7b0
+#define ODM_REG_ANT_TRAIN_PARA2_11N 0x7b4
+
+/* DIG Related */
+#define ODM_BIT_IGI_11N 0x0000007F
+#define ODM_BIT_CCK_RPT_FORMAT_11N BIT(9)
+#define ODM_BIT_BB_RX_PATH_11N 0xF
+#define ODM_BIT_BB_TX_PATH_11N 0xF
+#define ODM_BIT_BB_ATC_11N BIT(11)
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/phydm_types.h b/drivers/staging/rtlwifi/phydm/phydm_types.h
new file mode 100644
index 0000000..a34ebe8
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/phydm_types.h
@@ -0,0 +1,130 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __ODM_TYPES_H__
+#define __ODM_TYPES_H__
+
+/*Define Different SW team support*/
+#define ODM_AP 0x01 /*BIT0*/
+#define ODM_CE 0x04 /*BIT2*/
+#define ODM_WIN 0x08 /*BIT3*/
+#define ODM_ADSL 0x10 /*BIT4*/
+#define ODM_IOT 0x20 /*BIT5*/
+
+/*Deifne HW endian support*/
+#define ODM_ENDIAN_BIG 0
+#define ODM_ENDIAN_LITTLE 1
+
+#define GET_PDM_ODM(__padapter) \
+ ((struct phy_dm_struct *)(&(GET_HAL_DATA(__padapter))->odmpriv))
+
+enum hal_status {
+ HAL_STATUS_SUCCESS,
+ HAL_STATUS_FAILURE,
+};
+
+/*
+ * Declare for ODM spin lock definition temporarily fro compile pass.
+ */
+enum rt_spinlock_type {
+ RT_TX_SPINLOCK = 1,
+ RT_RX_SPINLOCK = 2,
+ RT_RM_SPINLOCK = 3,
+ RT_CAM_SPINLOCK = 4,
+ RT_SCAN_SPINLOCK = 5,
+ RT_LOG_SPINLOCK = 7,
+ RT_BW_SPINLOCK = 8,
+ RT_CHNLOP_SPINLOCK = 9,
+ RT_RF_OPERATE_SPINLOCK = 10,
+ RT_INITIAL_SPINLOCK = 11,
+ RT_RF_STATE_SPINLOCK =
+ 12, /* For RF state. Added by Bruce, 2007-10-30. */
+ /* Shall we define Ndis 6.2 SpinLock Here ? */
+ RT_PORT_SPINLOCK = 16,
+ RT_VNIC_SPINLOCK = 17,
+ RT_HVL_SPINLOCK = 18,
+ RT_H2C_SPINLOCK = 20, /* For H2C cmd. Added by tynli. 2009.11.09. */
+
+ rt_bt_data_spinlock = 25,
+
+ RT_WAPI_OPTION_SPINLOCK = 26,
+ RT_WAPI_RX_SPINLOCK = 27,
+
+ /* add for 92D CCK control issue */
+ RT_CCK_PAGEA_SPINLOCK = 28,
+ RT_BUFFER_SPINLOCK = 29,
+ RT_CHANNEL_AND_BANDWIDTH_SPINLOCK = 30,
+ RT_GEN_TEMP_BUF_SPINLOCK = 31,
+ RT_AWB_SPINLOCK = 32,
+ RT_FW_PS_SPINLOCK = 33,
+ RT_HW_TIMER_SPIN_LOCK = 34,
+ RT_MPT_WI_SPINLOCK = 35,
+ RT_P2P_SPIN_LOCK = 36, /* Protect P2P context */
+ RT_DBG_SPIN_LOCK = 37,
+ RT_IQK_SPINLOCK = 38,
+ RT_PENDED_OID_SPINLOCK = 39,
+ RT_CHNLLIST_SPINLOCK = 40,
+ RT_INDIC_SPINLOCK = 41, /* protect indication */
+ RT_RFD_SPINLOCK = 42,
+ RT_SYNC_IO_CNT_SPINLOCK = 43,
+ RT_LAST_SPINLOCK,
+};
+
+#include <asm/byteorder.h>
+
+#if defined(__LITTLE_ENDIAN)
+#define ODM_ENDIAN_TYPE ODM_ENDIAN_LITTLE
+#elif defined(__BIG_ENDIAN)
+#define ODM_ENDIAN_TYPE ODM_ENDIAN_BIG
+#else
+#error
+#endif
+
+#define COND_ELSE 2
+#define COND_ENDIF 3
+
+#define MASKBYTE0 0xff
+#define MASKBYTE1 0xff00
+#define MASKBYTE2 0xff0000
+#define MASKBYTE3 0xff000000
+#define MASKHWORD 0xffff0000
+#define MASKLWORD 0x0000ffff
+#define MASKDWORD 0xffffffff
+#define MASK7BITS 0x7f
+#define MASK12BITS 0xfff
+#define MASKH4BITS 0xf0000000
+#define MASK20BITS 0xfffff
+#define MASKOFDM_D 0xffc00000
+#define MASKCCK 0x3f3f3f3f
+#define RFREGOFFSETMASK 0xfffff
+#define MASKH3BYTES 0xffffff00
+#define MASKL3BYTES 0x00ffffff
+#define MASKBYTE2HIGHNIBBLE 0x00f00000
+#define MASKBYTE3LOWNIBBLE 0x0f000000
+#define MASKL3BYTES 0x00ffffff
+#define RFREGOFFSETMASK 0xfffff
+
+#include "phydm_features.h"
+
+#endif /* __ODM_TYPES_H__ */
diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_bb.c b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_bb.c
new file mode 100644
index 0000000..4e79460
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_bb.c
@@ -0,0 +1,1969 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+/*Image2HeaderVersion: 3.2*/
+#include "../mp_precomp.h"
+#include "../phydm_precomp.h"
+
+static bool check_positive(struct phy_dm_struct *dm, const u32 condition1,
+ const u32 condition2, const u32 condition3,
+ const u32 condition4)
+{
+ u8 _board_type = ((dm->board_type & BIT(4)) >> 4) << 0 | /* _GLNA*/
+ ((dm->board_type & BIT(3)) >> 3) << 1 | /* _GPA*/
+ ((dm->board_type & BIT(7)) >> 7) << 2 | /* _ALNA*/
+ ((dm->board_type & BIT(6)) >> 6) << 3 | /* _APA */
+ ((dm->board_type & BIT(2)) >> 2) << 4; /* _BT*/
+
+ u32 cond1 = condition1, cond2 = condition2, cond3 = condition3,
+ cond4 = condition4;
+
+ u8 cut_version_for_para =
+ (dm->cut_version == ODM_CUT_A) ? 14 : dm->cut_version;
+ u8 pkg_type_for_para = (dm->package_type == 0) ? 14 : dm->package_type;
+
+ u32 driver1 = cut_version_for_para << 24 |
+ (dm->support_interface & 0xF0) << 16 |
+ dm->support_platform << 16 | pkg_type_for_para << 12 |
+ (dm->support_interface & 0x0F) << 8 | _board_type;
+
+ u32 driver2 = (dm->type_glna & 0xFF) << 0 | (dm->type_gpa & 0xFF) << 8 |
+ (dm->type_alna & 0xFF) << 16 |
+ (dm->type_apa & 0xFF) << 24;
+
+ u32 driver3 = 0;
+
+ u32 driver4 = (dm->type_glna & 0xFF00) >> 8 | (dm->type_gpa & 0xFF00) |
+ (dm->type_alna & 0xFF00) << 8 |
+ (dm->type_apa & 0xFF00) << 16;
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_INIT,
+ "===> %s (cond1, cond2, cond3, cond4) = (0x%X 0x%X 0x%X 0x%X)\n",
+ __func__, cond1, cond2, cond3, cond4);
+ ODM_RT_TRACE(
+ dm, ODM_COMP_INIT,
+ "===> %s (driver1, driver2, driver3, driver4) = (0x%X 0x%X 0x%X 0x%X)\n",
+ __func__, driver1, driver2, driver3, driver4);
+
+ ODM_RT_TRACE(dm, ODM_COMP_INIT,
+ " (Platform, Interface) = (0x%X, 0x%X)\n",
+ dm->support_platform, dm->support_interface);
+ ODM_RT_TRACE(dm, ODM_COMP_INIT,
+ " (Board, Package) = (0x%X, 0x%X)\n",
+ dm->board_type, dm->package_type);
+
+ /*============== value Defined Check ===============*/
+ /*QFN type [15:12] and cut version [27:24] need to do value check*/
+
+ if (((cond1 & 0x0000F000) != 0) &&
+ ((cond1 & 0x0000F000) != (driver1 & 0x0000F000)))
+ return false;
+ if (((cond1 & 0x0F000000) != 0) &&
+ ((cond1 & 0x0F000000) != (driver1 & 0x0F000000)))
+ return false;
+
+ /*=============== Bit Defined Check ================*/
+ /* We don't care [31:28] */
+
+ cond1 &= 0x00FF0FFF;
+ driver1 &= 0x00FF0FFF;
+
+ if ((cond1 & driver1) == cond1) {
+ u32 bit_mask = 0;
+
+ if ((cond1 & 0x0F) == 0) /* board_type is DONTCARE*/
+ return true;
+
+ if ((cond1 & BIT(0)) != 0) /*GLNA*/
+ bit_mask |= 0x000000FF;
+ if ((cond1 & BIT(1)) != 0) /*GPA*/
+ bit_mask |= 0x0000FF00;
+ if ((cond1 & BIT(2)) != 0) /*ALNA*/
+ bit_mask |= 0x00FF0000;
+ if ((cond1 & BIT(3)) != 0) /*APA*/
+ bit_mask |= 0xFF000000;
+
+ if (((cond2 & bit_mask) == (driver2 & bit_mask)) &&
+ ((cond4 & bit_mask) ==
+ (driver4 &
+ bit_mask))) /* board_type of each RF path is matched*/
+ return true;
+ else
+ return false;
+ } else {
+ return false;
+ }
+}
+
+/******************************************************************************
+ * agc_tab.TXT
+ ******************************************************************************/
+
+static u32 array_mp_8822b_agc_tab[] = {
+ 0x8000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x81C, 0xFF000003,
+ 0x81C, 0xF5000003, 0x81C, 0xF4020003, 0x81C, 0xF3040003,
+ 0x81C, 0xF2060003, 0x81C, 0xF1080003, 0x81C, 0xF00A0003,
+ 0x81C, 0xEF0C0003, 0x81C, 0xEE0E0003, 0x81C, 0xED100003,
+ 0x81C, 0xEC120003, 0x81C, 0xEB140003, 0x81C, 0xEA160003,
+ 0x81C, 0xE9180003, 0x81C, 0xE81A0003, 0x81C, 0xE71C0003,
+ 0x81C, 0xE61E0003, 0x81C, 0xE5200003, 0x81C, 0xE4220003,
+ 0x81C, 0xE3240003, 0x81C, 0xE2260003, 0x81C, 0xE1280003,
+ 0x81C, 0xE02A0003, 0x81C, 0xC32C0003, 0x81C, 0xC22E0003,
+ 0x81C, 0xC1300003, 0x81C, 0xC0320003, 0x81C, 0xA4340003,
+ 0x81C, 0xA3360003, 0x81C, 0xA2380003, 0x81C, 0xA13A0003,
+ 0x81C, 0xA03C0003, 0x81C, 0x823E0003, 0x81C, 0x81400003,
+ 0x81C, 0x80420003, 0x81C, 0x64440003, 0x81C, 0x63460003,
+ 0x81C, 0x62480003, 0x81C, 0x614A0003, 0x81C, 0x604C0003,
+ 0x81C, 0x454E0003, 0x81C, 0x44500003, 0x81C, 0x43520003,
+ 0x81C, 0x42540003, 0x81C, 0x41560003, 0x81C, 0x40580003,
+ 0x81C, 0x055A0003, 0x81C, 0x045C0003, 0x81C, 0x035E0003,
+ 0x81C, 0x02600003, 0x81C, 0x01620003, 0x81C, 0x00640003,
+ 0x81C, 0x00660003, 0x81C, 0x00680003, 0x81C, 0x006A0003,
+ 0x81C, 0x006C0003, 0x81C, 0x006E0003, 0x81C, 0x00700003,
+ 0x81C, 0x00720003, 0x81C, 0x00740003, 0x81C, 0x00760003,
+ 0x81C, 0x00780003, 0x81C, 0x007A0003, 0x81C, 0x007C0003,
+ 0x81C, 0x007E0003, 0x9000100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x81C, 0xFF000003, 0x81C, 0xF5000003, 0x81C, 0xF4020003,
+ 0x81C, 0xF3040003, 0x81C, 0xF2060003, 0x81C, 0xF1080003,
+ 0x81C, 0xF00A0003, 0x81C, 0xEF0C0003, 0x81C, 0xEE0E0003,
+ 0x81C, 0xED100003, 0x81C, 0xEC120003, 0x81C, 0xEB140003,
+ 0x81C, 0xEA160003, 0x81C, 0xE9180003, 0x81C, 0xE81A0003,
+ 0x81C, 0xE71C0003, 0x81C, 0xE61E0003, 0x81C, 0xE5200003,
+ 0x81C, 0xE4220003, 0x81C, 0xE3240003, 0x81C, 0xE2260003,
+ 0x81C, 0xE1280003, 0x81C, 0xE02A0003, 0x81C, 0xC32C0003,
+ 0x81C, 0xC22E0003, 0x81C, 0xC1300003, 0x81C, 0xC0320003,
+ 0x81C, 0xA4340003, 0x81C, 0xA3360003, 0x81C, 0xA2380003,
+ 0x81C, 0xA13A0003, 0x81C, 0xA03C0003, 0x81C, 0x823E0003,
+ 0x81C, 0x81400003, 0x81C, 0x80420003, 0x81C, 0x64440003,
+ 0x81C, 0x63460003, 0x81C, 0x62480003, 0x81C, 0x614A0003,
+ 0x81C, 0x604C0003, 0x81C, 0x454E0003, 0x81C, 0x44500003,
+ 0x81C, 0x43520003, 0x81C, 0x42540003, 0x81C, 0x41560003,
+ 0x81C, 0x40580003, 0x81C, 0x055A0003, 0x81C, 0x045C0003,
+ 0x81C, 0x035E0003, 0x81C, 0x02600003, 0x81C, 0x01620003,
+ 0x81C, 0x00640003, 0x81C, 0x00660003, 0x81C, 0x00680003,
+ 0x81C, 0x006A0003, 0x81C, 0x006C0003, 0x81C, 0x006E0003,
+ 0x81C, 0x00700003, 0x81C, 0x00720003, 0x81C, 0x00740003,
+ 0x81C, 0x00760003, 0x81C, 0x00780003, 0x81C, 0x007A0003,
+ 0x81C, 0x007C0003, 0x81C, 0x007E0003, 0x9000100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xFF000003, 0x81C, 0xF5000003,
+ 0x81C, 0xF4020003, 0x81C, 0xF3040003, 0x81C, 0xF2060003,
+ 0x81C, 0xF1080003, 0x81C, 0xF00A0003, 0x81C, 0xEF0C0003,
+ 0x81C, 0xEE0E0003, 0x81C, 0xED100003, 0x81C, 0xEC120003,
+ 0x81C, 0xEB140003, 0x81C, 0xEA160003, 0x81C, 0xE9180003,
+ 0x81C, 0xE81A0003, 0x81C, 0xE71C0003, 0x81C, 0xE61E0003,
+ 0x81C, 0xE5200003, 0x81C, 0xE4220003, 0x81C, 0xE3240003,
+ 0x81C, 0xE2260003, 0x81C, 0xE1280003, 0x81C, 0xE02A0003,
+ 0x81C, 0xC32C0003, 0x81C, 0xC22E0003, 0x81C, 0xC1300003,
+ 0x81C, 0xC0320003, 0x81C, 0xA4340003, 0x81C, 0xA3360003,
+ 0x81C, 0xA2380003, 0x81C, 0xA13A0003, 0x81C, 0xA03C0003,
+ 0x81C, 0x823E0003, 0x81C, 0x81400003, 0x81C, 0x80420003,
+ 0x81C, 0x64440003, 0x81C, 0x63460003, 0x81C, 0x62480003,
+ 0x81C, 0x614A0003, 0x81C, 0x604C0003, 0x81C, 0x454E0003,
+ 0x81C, 0x44500003, 0x81C, 0x43520003, 0x81C, 0x42540003,
+ 0x81C, 0x41560003, 0x81C, 0x40580003, 0x81C, 0x055A0003,
+ 0x81C, 0x045C0003, 0x81C, 0x035E0003, 0x81C, 0x02600003,
+ 0x81C, 0x01620003, 0x81C, 0x00640003, 0x81C, 0x00660003,
+ 0x81C, 0x00680003, 0x81C, 0x006A0003, 0x81C, 0x006C0003,
+ 0x81C, 0x006E0003, 0x81C, 0x00700003, 0x81C, 0x00720003,
+ 0x81C, 0x00740003, 0x81C, 0x00760003, 0x81C, 0x00780003,
+ 0x81C, 0x007A0003, 0x81C, 0x007C0003, 0x81C, 0x007E0003,
+ 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x81C, 0xFF000003,
+ 0x81C, 0xF5000003, 0x81C, 0xF4020003, 0x81C, 0xF3040003,
+ 0x81C, 0xF2060003, 0x81C, 0xF1080003, 0x81C, 0xF00A0003,
+ 0x81C, 0xEF0C0003, 0x81C, 0xEE0E0003, 0x81C, 0xED100003,
+ 0x81C, 0xEC120003, 0x81C, 0xEB140003, 0x81C, 0xEA160003,
+ 0x81C, 0xE9180003, 0x81C, 0xE81A0003, 0x81C, 0xE71C0003,
+ 0x81C, 0xE61E0003, 0x81C, 0xE5200003, 0x81C, 0xE4220003,
+ 0x81C, 0xE3240003, 0x81C, 0xE2260003, 0x81C, 0xE1280003,
+ 0x81C, 0xE02A0003, 0x81C, 0xC32C0003, 0x81C, 0xC22E0003,
+ 0x81C, 0xC1300003, 0x81C, 0xC0320003, 0x81C, 0xA4340003,
+ 0x81C, 0xA3360003, 0x81C, 0xA2380003, 0x81C, 0xA13A0003,
+ 0x81C, 0xA03C0003, 0x81C, 0x823E0003, 0x81C, 0x81400003,
+ 0x81C, 0x80420003, 0x81C, 0x64440003, 0x81C, 0x63460003,
+ 0x81C, 0x62480003, 0x81C, 0x614A0003, 0x81C, 0x604C0003,
+ 0x81C, 0x454E0003, 0x81C, 0x44500003, 0x81C, 0x43520003,
+ 0x81C, 0x42540003, 0x81C, 0x41560003, 0x81C, 0x40580003,
+ 0x81C, 0x055A0003, 0x81C, 0x045C0003, 0x81C, 0x035E0003,
+ 0x81C, 0x02600003, 0x81C, 0x01620003, 0x81C, 0x00640003,
+ 0x81C, 0x00660003, 0x81C, 0x00680003, 0x81C, 0x006A0003,
+ 0x81C, 0x006C0003, 0x81C, 0x006E0003, 0x81C, 0x00700003,
+ 0x81C, 0x00720003, 0x81C, 0x00740003, 0x81C, 0x00760003,
+ 0x81C, 0x00780003, 0x81C, 0x007A0003, 0x81C, 0x007C0003,
+ 0x81C, 0x007E0003, 0x9000200c, 0x00000000, 0x40000000, 0x00000000,
+ 0x81C, 0xFF000003, 0x81C, 0xFD000003, 0x81C, 0xFC020003,
+ 0x81C, 0xFB040003, 0x81C, 0xFA060003, 0x81C, 0xF9080003,
+ 0x81C, 0xF80A0003, 0x81C, 0xF70C0003, 0x81C, 0xF60E0003,
+ 0x81C, 0xF5100003, 0x81C, 0xF4120003, 0x81C, 0xF3140003,
+ 0x81C, 0xF2160003, 0x81C, 0xF1180003, 0x81C, 0xF01A0003,
+ 0x81C, 0xEF1C0003, 0x81C, 0xEE1E0003, 0x81C, 0xED200003,
+ 0x81C, 0xEC220003, 0x81C, 0xEB240003, 0x81C, 0xEA260003,
+ 0x81C, 0xE9280003, 0x81C, 0xE82A0003, 0x81C, 0xE72C0003,
+ 0x81C, 0xE62E0003, 0x81C, 0xE5300003, 0x81C, 0xC8320003,
+ 0x81C, 0xC7340003, 0x81C, 0xC6360003, 0x81C, 0xC5380003,
+ 0x81C, 0xC43A0003, 0x81C, 0xC33C0003, 0x81C, 0xC23E0003,
+ 0x81C, 0xC1400003, 0x81C, 0xC0420003, 0x81C, 0xA5440003,
+ 0x81C, 0xA4460003, 0x81C, 0xA3480003, 0x81C, 0xA24A0003,
+ 0x81C, 0xA14C0003, 0x81C, 0x834E0003, 0x81C, 0x82500003,
+ 0x81C, 0x81520003, 0x81C, 0x80540003, 0x81C, 0x65560003,
+ 0x81C, 0x64580003, 0x81C, 0x635A0003, 0x81C, 0x625C0003,
+ 0x81C, 0x435E0003, 0x81C, 0x42600003, 0x81C, 0x41620003,
+ 0x81C, 0x40640003, 0x81C, 0x06660003, 0x81C, 0x05680003,
+ 0x81C, 0x046A0003, 0x81C, 0x036C0003, 0x81C, 0x026E0003,
+ 0x81C, 0x01700003, 0x81C, 0x00720003, 0x81C, 0x00740003,
+ 0x81C, 0x00760003, 0x81C, 0x00780003, 0x81C, 0x007A0003,
+ 0x81C, 0x007C0003, 0x81C, 0x007E0003, 0x90012100, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xFF000003, 0x81C, 0xFE000003,
+ 0x81C, 0xFD020003, 0x81C, 0xFC040003, 0x81C, 0xFB060003,
+ 0x81C, 0xFA080003, 0x81C, 0xF90A0003, 0x81C, 0xF80C0003,
+ 0x81C, 0xF70E0003, 0x81C, 0xF6100003, 0x81C, 0xF5120003,
+ 0x81C, 0xF4140003, 0x81C, 0xF3160003, 0x81C, 0xF2180003,
+ 0x81C, 0xF11A0003, 0x81C, 0xF01C0003, 0x81C, 0xEF1E0003,
+ 0x81C, 0xEE200003, 0x81C, 0xED220003, 0x81C, 0xEC240003,
+ 0x81C, 0xEB260003, 0x81C, 0xEA280003, 0x81C, 0xE92A0003,
+ 0x81C, 0xE82C0003, 0x81C, 0xE72E0003, 0x81C, 0xE6300003,
+ 0x81C, 0xE5320003, 0x81C, 0xC8340003, 0x81C, 0xC7360003,
+ 0x81C, 0xC6380003, 0x81C, 0xC53A0003, 0x81C, 0xC43C0003,
+ 0x81C, 0xC33E0003, 0x81C, 0xC2400003, 0x81C, 0xC1420003,
+ 0x81C, 0xC0440003, 0x81C, 0xA3460003, 0x81C, 0xA2480003,
+ 0x81C, 0xA14A0003, 0x81C, 0xA04C0003, 0x81C, 0x824E0003,
+ 0x81C, 0x81500003, 0x81C, 0x80520003, 0x81C, 0x64540003,
+ 0x81C, 0x63560003, 0x81C, 0x62580003, 0x81C, 0x445A0003,
+ 0x81C, 0x435C0003, 0x81C, 0x425E0003, 0x81C, 0x41600003,
+ 0x81C, 0x40620003, 0x81C, 0x05640003, 0x81C, 0x04660003,
+ 0x81C, 0x03680003, 0x81C, 0x026A0003, 0x81C, 0x016C0003,
+ 0x81C, 0x006E0003, 0x81C, 0x00700003, 0x81C, 0x00720003,
+ 0x81C, 0x00740003, 0x81C, 0x00760003, 0x81C, 0x00780003,
+ 0x81C, 0x007A0003, 0x81C, 0x007C0003, 0x81C, 0x007E0003,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x81C, 0xFF000003,
+ 0x81C, 0xF5000003, 0x81C, 0xF4020003, 0x81C, 0xF3040003,
+ 0x81C, 0xF2060003, 0x81C, 0xF1080003, 0x81C, 0xF00A0003,
+ 0x81C, 0xEF0C0003, 0x81C, 0xEE0E0003, 0x81C, 0xED100003,
+ 0x81C, 0xEC120003, 0x81C, 0xEB140003, 0x81C, 0xEA160003,
+ 0x81C, 0xE9180003, 0x81C, 0xE81A0003, 0x81C, 0xE71C0003,
+ 0x81C, 0xE61E0003, 0x81C, 0xE5200003, 0x81C, 0xE4220003,
+ 0x81C, 0xE3240003, 0x81C, 0xE2260003, 0x81C, 0xE1280003,
+ 0x81C, 0xE02A0003, 0x81C, 0xC32C0003, 0x81C, 0xC22E0003,
+ 0x81C, 0xC1300003, 0x81C, 0xC0320003, 0x81C, 0xA4340003,
+ 0x81C, 0xA3360003, 0x81C, 0xA2380003, 0x81C, 0xA13A0003,
+ 0x81C, 0xA03C0003, 0x81C, 0x823E0003, 0x81C, 0x81400003,
+ 0x81C, 0x80420003, 0x81C, 0x64440003, 0x81C, 0x63460003,
+ 0x81C, 0x62480003, 0x81C, 0x614A0003, 0x81C, 0x604C0003,
+ 0x81C, 0x454E0003, 0x81C, 0x44500003, 0x81C, 0x43520003,
+ 0x81C, 0x42540003, 0x81C, 0x41560003, 0x81C, 0x40580003,
+ 0x81C, 0x055A0003, 0x81C, 0x045C0003, 0x81C, 0x035E0003,
+ 0x81C, 0x02600003, 0x81C, 0x01620003, 0x81C, 0x00640003,
+ 0x81C, 0x00660003, 0x81C, 0x00680003, 0x81C, 0x006A0003,
+ 0x81C, 0x006C0003, 0x81C, 0x006E0003, 0x81C, 0x00700003,
+ 0x81C, 0x00720003, 0x81C, 0x00740003, 0x81C, 0x00760003,
+ 0x81C, 0x00780003, 0x81C, 0x007A0003, 0x81C, 0x007C0003,
+ 0x81C, 0x007E0003, 0x90011000, 0x00000000, 0x40000000, 0x00000000,
+ 0x81C, 0xFF000003, 0x81C, 0xFE000003, 0x81C, 0xFD020003,
+ 0x81C, 0xFC040003, 0x81C, 0xFB060003, 0x81C, 0xFA080003,
+ 0x81C, 0xF90A0003, 0x81C, 0xF80C0003, 0x81C, 0xF70E0003,
+ 0x81C, 0xF6100003, 0x81C, 0xF5120003, 0x81C, 0xF4140003,
+ 0x81C, 0xF3160003, 0x81C, 0xF2180003, 0x81C, 0xF11A0003,
+ 0x81C, 0xF01C0003, 0x81C, 0xEF1E0003, 0x81C, 0xEE200003,
+ 0x81C, 0xED220003, 0x81C, 0xEC240003, 0x81C, 0xEB260003,
+ 0x81C, 0xEA280003, 0x81C, 0xE92A0003, 0x81C, 0xE82C0003,
+ 0x81C, 0xE72E0003, 0x81C, 0xE6300003, 0x81C, 0xE5320003,
+ 0x81C, 0xC8340003, 0x81C, 0xC7360003, 0x81C, 0xC6380003,
+ 0x81C, 0xC53A0003, 0x81C, 0xC43C0003, 0x81C, 0xC33E0003,
+ 0x81C, 0xC2400003, 0x81C, 0xC1420003, 0x81C, 0xC0440003,
+ 0x81C, 0xA3460003, 0x81C, 0xA2480003, 0x81C, 0xA14A0003,
+ 0x81C, 0xA04C0003, 0x81C, 0x824E0003, 0x81C, 0x81500003,
+ 0x81C, 0x80520003, 0x81C, 0x64540003, 0x81C, 0x63560003,
+ 0x81C, 0x62580003, 0x81C, 0x445A0003, 0x81C, 0x435C0003,
+ 0x81C, 0x425E0003, 0x81C, 0x41600003, 0x81C, 0x40620003,
+ 0x81C, 0x05640003, 0x81C, 0x04660003, 0x81C, 0x03680003,
+ 0x81C, 0x026A0003, 0x81C, 0x016C0003, 0x81C, 0x006E0003,
+ 0x81C, 0x00700003, 0x81C, 0x00720003, 0x81C, 0x00740003,
+ 0x81C, 0x00760003, 0x81C, 0x00780003, 0x81C, 0x007A0003,
+ 0x81C, 0x007C0003, 0x81C, 0x007E0003, 0x90002100, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xFF000003, 0x81C, 0xFD000003,
+ 0x81C, 0xFC020003, 0x81C, 0xFB040003, 0x81C, 0xFA060003,
+ 0x81C, 0xF9080003, 0x81C, 0xF80A0003, 0x81C, 0xF70C0003,
+ 0x81C, 0xF60E0003, 0x81C, 0xF5100003, 0x81C, 0xF4120003,
+ 0x81C, 0xF3140003, 0x81C, 0xF2160003, 0x81C, 0xF1180003,
+ 0x81C, 0xF01A0003, 0x81C, 0xEF1C0003, 0x81C, 0xEE1E0003,
+ 0x81C, 0xED200003, 0x81C, 0xEC220003, 0x81C, 0xEB240003,
+ 0x81C, 0xEA260003, 0x81C, 0xE9280003, 0x81C, 0xE82A0003,
+ 0x81C, 0xE72C0003, 0x81C, 0xE62E0003, 0x81C, 0xE5300003,
+ 0x81C, 0xC8320003, 0x81C, 0xC7340003, 0x81C, 0xC6360003,
+ 0x81C, 0xC5380003, 0x81C, 0xC43A0003, 0x81C, 0xC33C0003,
+ 0x81C, 0xC23E0003, 0x81C, 0xC1400003, 0x81C, 0xC0420003,
+ 0x81C, 0xA5440003, 0x81C, 0xA4460003, 0x81C, 0xA3480003,
+ 0x81C, 0xA24A0003, 0x81C, 0xA14C0003, 0x81C, 0x834E0003,
+ 0x81C, 0x82500003, 0x81C, 0x81520003, 0x81C, 0x80540003,
+ 0x81C, 0x65560003, 0x81C, 0x64580003, 0x81C, 0x635A0003,
+ 0x81C, 0x625C0003, 0x81C, 0x435E0003, 0x81C, 0x42600003,
+ 0x81C, 0x41620003, 0x81C, 0x40640003, 0x81C, 0x06660003,
+ 0x81C, 0x05680003, 0x81C, 0x046A0003, 0x81C, 0x036C0003,
+ 0x81C, 0x026E0003, 0x81C, 0x01700003, 0x81C, 0x00720003,
+ 0x81C, 0x00740003, 0x81C, 0x00760003, 0x81C, 0x00780003,
+ 0x81C, 0x007A0003, 0x81C, 0x007C0003, 0x81C, 0x007E0003,
+ 0x90002000, 0x00000000, 0x40000000, 0x00000000, 0x81C, 0xFF000003,
+ 0x81C, 0xFD000003, 0x81C, 0xFC020003, 0x81C, 0xFB040003,
+ 0x81C, 0xFA060003, 0x81C, 0xF9080003, 0x81C, 0xF80A0003,
+ 0x81C, 0xF70C0003, 0x81C, 0xF60E0003, 0x81C, 0xF5100003,
+ 0x81C, 0xF4120003, 0x81C, 0xF3140003, 0x81C, 0xF2160003,
+ 0x81C, 0xF1180003, 0x81C, 0xF01A0003, 0x81C, 0xEF1C0003,
+ 0x81C, 0xEE1E0003, 0x81C, 0xED200003, 0x81C, 0xEC220003,
+ 0x81C, 0xEB240003, 0x81C, 0xEA260003, 0x81C, 0xE9280003,
+ 0x81C, 0xE82A0003, 0x81C, 0xE72C0003, 0x81C, 0xE62E0003,
+ 0x81C, 0xE5300003, 0x81C, 0xC8320003, 0x81C, 0xC7340003,
+ 0x81C, 0xC6360003, 0x81C, 0xC5380003, 0x81C, 0xC43A0003,
+ 0x81C, 0xC33C0003, 0x81C, 0xC23E0003, 0x81C, 0xC1400003,
+ 0x81C, 0xC0420003, 0x81C, 0xA5440003, 0x81C, 0xA4460003,
+ 0x81C, 0xA3480003, 0x81C, 0xA24A0003, 0x81C, 0xA14C0003,
+ 0x81C, 0x834E0003, 0x81C, 0x82500003, 0x81C, 0x81520003,
+ 0x81C, 0x80540003, 0x81C, 0x65560003, 0x81C, 0x64580003,
+ 0x81C, 0x635A0003, 0x81C, 0x625C0003, 0x81C, 0x435E0003,
+ 0x81C, 0x42600003, 0x81C, 0x41620003, 0x81C, 0x40640003,
+ 0x81C, 0x06660003, 0x81C, 0x05680003, 0x81C, 0x046A0003,
+ 0x81C, 0x036C0003, 0x81C, 0x026E0003, 0x81C, 0x01700003,
+ 0x81C, 0x00720003, 0x81C, 0x00740003, 0x81C, 0x00760003,
+ 0x81C, 0x00780003, 0x81C, 0x007A0003, 0x81C, 0x007C0003,
+ 0x81C, 0x007E0003, 0xA0000000, 0x00000000, 0x81C, 0xFF000003,
+ 0x81C, 0xFE000003, 0x81C, 0xFD020003, 0x81C, 0xFC040003,
+ 0x81C, 0xFB060003, 0x81C, 0xFA080003, 0x81C, 0xF90A0003,
+ 0x81C, 0xF80C0003, 0x81C, 0xF70E0003, 0x81C, 0xF6100003,
+ 0x81C, 0xF5120003, 0x81C, 0xF4140003, 0x81C, 0xF3160003,
+ 0x81C, 0xF2180003, 0x81C, 0xF11A0003, 0x81C, 0xF01C0003,
+ 0x81C, 0xEF1E0003, 0x81C, 0xEE200003, 0x81C, 0xED220003,
+ 0x81C, 0xEC240003, 0x81C, 0xEB260003, 0x81C, 0xEA280003,
+ 0x81C, 0xE92A0003, 0x81C, 0xE82C0003, 0x81C, 0xE72E0003,
+ 0x81C, 0xE6300003, 0x81C, 0xE5320003, 0x81C, 0xC8340003,
+ 0x81C, 0xC7360003, 0x81C, 0xC6380003, 0x81C, 0xC53A0003,
+ 0x81C, 0xC43C0003, 0x81C, 0xC33E0003, 0x81C, 0xC2400003,
+ 0x81C, 0xC1420003, 0x81C, 0xC0440003, 0x81C, 0xA3460003,
+ 0x81C, 0xA2480003, 0x81C, 0xA14A0003, 0x81C, 0xA04C0003,
+ 0x81C, 0x824E0003, 0x81C, 0x81500003, 0x81C, 0x80520003,
+ 0x81C, 0x64540003, 0x81C, 0x63560003, 0x81C, 0x62580003,
+ 0x81C, 0x445A0003, 0x81C, 0x435C0003, 0x81C, 0x425E0003,
+ 0x81C, 0x41600003, 0x81C, 0x40620003, 0x81C, 0x05640003,
+ 0x81C, 0x04660003, 0x81C, 0x03680003, 0x81C, 0x026A0003,
+ 0x81C, 0x016C0003, 0x81C, 0x006E0003, 0x81C, 0x00700003,
+ 0x81C, 0x00720003, 0x81C, 0x00740003, 0x81C, 0x00760003,
+ 0x81C, 0x00780003, 0x81C, 0x007A0003, 0x81C, 0x007C0003,
+ 0x81C, 0x007E0003, 0xB0000000, 0x00000000, 0x8000100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x81C, 0xF8000103, 0x81C, 0xF7020103,
+ 0x81C, 0xF6040103, 0x81C, 0xF5060103, 0x81C, 0xF4080103,
+ 0x81C, 0xF30A0103, 0x81C, 0xF20C0103, 0x81C, 0xF10E0103,
+ 0x81C, 0xF0100103, 0x81C, 0xEF120103, 0x81C, 0xEE140103,
+ 0x81C, 0xED160103, 0x81C, 0xEC180103, 0x81C, 0xEB1A0103,
+ 0x81C, 0xEA1C0103, 0x81C, 0xE91E0103, 0x81C, 0xE8200103,
+ 0x81C, 0xE7220103, 0x81C, 0xE6240103, 0x81C, 0xE5260103,
+ 0x81C, 0xE4280103, 0x81C, 0xE32A0103, 0x81C, 0xE22C0103,
+ 0x81C, 0xC32E0103, 0x81C, 0xC2300103, 0x81C, 0xC1320103,
+ 0x81C, 0xA3340103, 0x81C, 0xA2360103, 0x81C, 0xA1380103,
+ 0x81C, 0xA03A0103, 0x81C, 0x823C0103, 0x81C, 0x813E0103,
+ 0x81C, 0x80400103, 0x81C, 0x64420103, 0x81C, 0x63440103,
+ 0x81C, 0x62460103, 0x81C, 0x61480103, 0x81C, 0x434A0103,
+ 0x81C, 0x424C0103, 0x81C, 0x414E0103, 0x81C, 0x40500103,
+ 0x81C, 0x22520103, 0x81C, 0x21540103, 0x81C, 0x20560103,
+ 0x81C, 0x04580103, 0x81C, 0x035A0103, 0x81C, 0x025C0103,
+ 0x81C, 0x015E0103, 0x81C, 0x00600103, 0x81C, 0x00620103,
+ 0x81C, 0x00640103, 0x81C, 0x00660103, 0x81C, 0x00680103,
+ 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103,
+ 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103,
+ 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103,
+ 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x9000100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x81C, 0xFA000103, 0x81C, 0xF9020103,
+ 0x81C, 0xF8040103, 0x81C, 0xF7060103, 0x81C, 0xF6080103,
+ 0x81C, 0xF50A0103, 0x81C, 0xF40C0103, 0x81C, 0xF30E0103,
+ 0x81C, 0xF2100103, 0x81C, 0xF1120103, 0x81C, 0xF0140103,
+ 0x81C, 0xEF160103, 0x81C, 0xEE180103, 0x81C, 0xED1A0103,
+ 0x81C, 0xEC1C0103, 0x81C, 0xEB1E0103, 0x81C, 0xEA200103,
+ 0x81C, 0xE9220103, 0x81C, 0xE8240103, 0x81C, 0xE7260103,
+ 0x81C, 0xE6280103, 0x81C, 0xE52A0103, 0x81C, 0xC42C0103,
+ 0x81C, 0xC32E0103, 0x81C, 0xC2300103, 0x81C, 0xC1320103,
+ 0x81C, 0xA4340103, 0x81C, 0xA3360103, 0x81C, 0xA2380103,
+ 0x81C, 0xA13A0103, 0x81C, 0x833C0103, 0x81C, 0x823E0103,
+ 0x81C, 0x81400103, 0x81C, 0x63420103, 0x81C, 0x62440103,
+ 0x81C, 0x61460103, 0x81C, 0x60480103, 0x81C, 0x424A0103,
+ 0x81C, 0x414C0103, 0x81C, 0x404E0103, 0x81C, 0x22500103,
+ 0x81C, 0x21520103, 0x81C, 0x20540103, 0x81C, 0x03560103,
+ 0x81C, 0x02580103, 0x81C, 0x015A0103, 0x81C, 0x005C0103,
+ 0x81C, 0x005E0103, 0x81C, 0x00600103, 0x81C, 0x00620103,
+ 0x81C, 0x00640103, 0x81C, 0x00660103, 0x81C, 0x00680103,
+ 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103,
+ 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103,
+ 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103,
+ 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x9000100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xF8000103, 0x81C, 0xF7020103,
+ 0x81C, 0xF6040103, 0x81C, 0xF5060103, 0x81C, 0xF4080103,
+ 0x81C, 0xF30A0103, 0x81C, 0xF20C0103, 0x81C, 0xF10E0103,
+ 0x81C, 0xF0100103, 0x81C, 0xEF120103, 0x81C, 0xEE140103,
+ 0x81C, 0xED160103, 0x81C, 0xEC180103, 0x81C, 0xEB1A0103,
+ 0x81C, 0xEA1C0103, 0x81C, 0xE91E0103, 0x81C, 0xE8200103,
+ 0x81C, 0xE7220103, 0x81C, 0xE6240103, 0x81C, 0xE5260103,
+ 0x81C, 0xE4280103, 0x81C, 0xE32A0103, 0x81C, 0xC32C0103,
+ 0x81C, 0xC22E0103, 0x81C, 0xC1300103, 0x81C, 0xC0320103,
+ 0x81C, 0xA3340103, 0x81C, 0xA2360103, 0x81C, 0xA1380103,
+ 0x81C, 0xA03A0103, 0x81C, 0x823C0103, 0x81C, 0x813E0103,
+ 0x81C, 0x80400103, 0x81C, 0x63420103, 0x81C, 0x62440103,
+ 0x81C, 0x61460103, 0x81C, 0x60480103, 0x81C, 0x424A0103,
+ 0x81C, 0x414C0103, 0x81C, 0x404E0103, 0x81C, 0x06500103,
+ 0x81C, 0x05520103, 0x81C, 0x04540103, 0x81C, 0x03560103,
+ 0x81C, 0x02580103, 0x81C, 0x015A0103, 0x81C, 0x005C0103,
+ 0x81C, 0x005E0103, 0x81C, 0x00600103, 0x81C, 0x00620103,
+ 0x81C, 0x00640103, 0x81C, 0x00660103, 0x81C, 0x00680103,
+ 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103,
+ 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103,
+ 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103,
+ 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x9000200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xF8000103, 0x81C, 0xF7020103,
+ 0x81C, 0xF6040103, 0x81C, 0xF5060103, 0x81C, 0xF4080103,
+ 0x81C, 0xF30A0103, 0x81C, 0xF20C0103, 0x81C, 0xF10E0103,
+ 0x81C, 0xF0100103, 0x81C, 0xEF120103, 0x81C, 0xEE140103,
+ 0x81C, 0xED160103, 0x81C, 0xEC180103, 0x81C, 0xEB1A0103,
+ 0x81C, 0xEA1C0103, 0x81C, 0xE91E0103, 0x81C, 0xE8200103,
+ 0x81C, 0xE7220103, 0x81C, 0xE6240103, 0x81C, 0xE5260103,
+ 0x81C, 0xE4280103, 0x81C, 0xE32A0103, 0x81C, 0xC32C0103,
+ 0x81C, 0xC22E0103, 0x81C, 0xC1300103, 0x81C, 0xC0320103,
+ 0x81C, 0xA3340103, 0x81C, 0xA2360103, 0x81C, 0xA1380103,
+ 0x81C, 0xA03A0103, 0x81C, 0x823C0103, 0x81C, 0x813E0103,
+ 0x81C, 0x80400103, 0x81C, 0x63420103, 0x81C, 0x62440103,
+ 0x81C, 0x61460103, 0x81C, 0x60480103, 0x81C, 0x424A0103,
+ 0x81C, 0x414C0103, 0x81C, 0x404E0103, 0x81C, 0x22500103,
+ 0x81C, 0x21520103, 0x81C, 0x20540103, 0x81C, 0x03560103,
+ 0x81C, 0x02580103, 0x81C, 0x015A0103, 0x81C, 0x005C0103,
+ 0x81C, 0x005E0103, 0x81C, 0x00600103, 0x81C, 0x00620103,
+ 0x81C, 0x00640103, 0x81C, 0x00660103, 0x81C, 0x00680103,
+ 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103,
+ 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103,
+ 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103,
+ 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x9000200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xF8000103, 0x81C, 0xF7020103,
+ 0x81C, 0xF6040103, 0x81C, 0xF5060103, 0x81C, 0xF4080103,
+ 0x81C, 0xF30A0103, 0x81C, 0xF20C0103, 0x81C, 0xF10E0103,
+ 0x81C, 0xF0100103, 0x81C, 0xEF120103, 0x81C, 0xEE140103,
+ 0x81C, 0xED160103, 0x81C, 0xEC180103, 0x81C, 0xEB1A0103,
+ 0x81C, 0xEA1C0103, 0x81C, 0xE91E0103, 0x81C, 0xE8200103,
+ 0x81C, 0xE7220103, 0x81C, 0xE6240103, 0x81C, 0xE5260103,
+ 0x81C, 0xE4280103, 0x81C, 0xE32A0103, 0x81C, 0xC32C0103,
+ 0x81C, 0xC22E0103, 0x81C, 0xC1300103, 0x81C, 0xC0320103,
+ 0x81C, 0xA3340103, 0x81C, 0xA2360103, 0x81C, 0xA1380103,
+ 0x81C, 0xA03A0103, 0x81C, 0x823C0103, 0x81C, 0x813E0103,
+ 0x81C, 0x80400103, 0x81C, 0x63420103, 0x81C, 0x62440103,
+ 0x81C, 0x61460103, 0x81C, 0x60480103, 0x81C, 0x424A0103,
+ 0x81C, 0x414C0103, 0x81C, 0x404E0103, 0x81C, 0x22500103,
+ 0x81C, 0x21520103, 0x81C, 0x20540103, 0x81C, 0x03560103,
+ 0x81C, 0x02580103, 0x81C, 0x015A0103, 0x81C, 0x005C0103,
+ 0x81C, 0x005E0103, 0x81C, 0x00600103, 0x81C, 0x00620103,
+ 0x81C, 0x00640103, 0x81C, 0x00660103, 0x81C, 0x00680103,
+ 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103,
+ 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103,
+ 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103,
+ 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x90012100, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xFD000103, 0x81C, 0xFC020103,
+ 0x81C, 0xFB040103, 0x81C, 0xFA060103, 0x81C, 0xF9080103,
+ 0x81C, 0xF80A0103, 0x81C, 0xF70C0103, 0x81C, 0xF60E0103,
+ 0x81C, 0xF5100103, 0x81C, 0xF4120103, 0x81C, 0xF3140103,
+ 0x81C, 0xF2160103, 0x81C, 0xF1180103, 0x81C, 0xF01A0103,
+ 0x81C, 0xEF1C0103, 0x81C, 0xEE1E0103, 0x81C, 0xED200103,
+ 0x81C, 0xEC220103, 0x81C, 0xEB240103, 0x81C, 0xEA260103,
+ 0x81C, 0xE9280103, 0x81C, 0xE82A0103, 0x81C, 0xE72C0103,
+ 0x81C, 0xE62E0103, 0x81C, 0xE5300103, 0x81C, 0xE4320103,
+ 0x81C, 0xE3340103, 0x81C, 0xC6360103, 0x81C, 0xC5380103,
+ 0x81C, 0xC43A0103, 0x81C, 0xC33C0103, 0x81C, 0xC23E0103,
+ 0x81C, 0xA5400103, 0x81C, 0xA4420103, 0x81C, 0xA3440103,
+ 0x81C, 0xA2460103, 0x81C, 0xA1480103, 0x81C, 0x834A0103,
+ 0x81C, 0x824C0103, 0x81C, 0x814E0103, 0x81C, 0x63500103,
+ 0x81C, 0x62520103, 0x81C, 0x61540103, 0x81C, 0x43560103,
+ 0x81C, 0x42580103, 0x81C, 0x245A0103, 0x81C, 0x235C0103,
+ 0x81C, 0x225E0103, 0x81C, 0x21600103, 0x81C, 0x04620103,
+ 0x81C, 0x03640103, 0x81C, 0x02660103, 0x81C, 0x01680103,
+ 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103,
+ 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103,
+ 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103,
+ 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x90001004, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xF8000103, 0x81C, 0xF7020103,
+ 0x81C, 0xF6040103, 0x81C, 0xF5060103, 0x81C, 0xF4080103,
+ 0x81C, 0xF30A0103, 0x81C, 0xF20C0103, 0x81C, 0xF10E0103,
+ 0x81C, 0xF0100103, 0x81C, 0xEF120103, 0x81C, 0xEE140103,
+ 0x81C, 0xED160103, 0x81C, 0xEC180103, 0x81C, 0xEB1A0103,
+ 0x81C, 0xEA1C0103, 0x81C, 0xE91E0103, 0x81C, 0xE8200103,
+ 0x81C, 0xE7220103, 0x81C, 0xE6240103, 0x81C, 0xE5260103,
+ 0x81C, 0xE4280103, 0x81C, 0xE32A0103, 0x81C, 0xE22C0103,
+ 0x81C, 0xC32E0103, 0x81C, 0xC2300103, 0x81C, 0xC1320103,
+ 0x81C, 0xA3340103, 0x81C, 0xA2360103, 0x81C, 0xA1380103,
+ 0x81C, 0xA03A0103, 0x81C, 0x823C0103, 0x81C, 0x813E0103,
+ 0x81C, 0x80400103, 0x81C, 0x64420103, 0x81C, 0x63440103,
+ 0x81C, 0x62460103, 0x81C, 0x61480103, 0x81C, 0x434A0103,
+ 0x81C, 0x424C0103, 0x81C, 0x414E0103, 0x81C, 0x40500103,
+ 0x81C, 0x22520103, 0x81C, 0x21540103, 0x81C, 0x20560103,
+ 0x81C, 0x04580103, 0x81C, 0x035A0103, 0x81C, 0x025C0103,
+ 0x81C, 0x015E0103, 0x81C, 0x00600103, 0x81C, 0x00620103,
+ 0x81C, 0x00640103, 0x81C, 0x00660103, 0x81C, 0x00680103,
+ 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103,
+ 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103,
+ 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103,
+ 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x90011000, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xFD000103, 0x81C, 0xFC020103,
+ 0x81C, 0xFB040103, 0x81C, 0xFA060103, 0x81C, 0xF9080103,
+ 0x81C, 0xF80A0103, 0x81C, 0xF70C0103, 0x81C, 0xF60E0103,
+ 0x81C, 0xF5100103, 0x81C, 0xF4120103, 0x81C, 0xF3140103,
+ 0x81C, 0xF2160103, 0x81C, 0xF1180103, 0x81C, 0xF01A0103,
+ 0x81C, 0xEE1C0103, 0x81C, 0xED1E0103, 0x81C, 0xEC200103,
+ 0x81C, 0xEB220103, 0x81C, 0xEA240103, 0x81C, 0xE9260103,
+ 0x81C, 0xE8280103, 0x81C, 0xE72A0103, 0x81C, 0xE62C0103,
+ 0x81C, 0xE52E0103, 0x81C, 0xE4300103, 0x81C, 0xE3320103,
+ 0x81C, 0xE2340103, 0x81C, 0xC5360103, 0x81C, 0xC4380103,
+ 0x81C, 0xC33A0103, 0x81C, 0xC23C0103, 0x81C, 0xA53E0103,
+ 0x81C, 0xA4400103, 0x81C, 0xA3420103, 0x81C, 0xA2440103,
+ 0x81C, 0xA1460103, 0x81C, 0x83480103, 0x81C, 0x824A0103,
+ 0x81C, 0x814C0103, 0x81C, 0x804E0103, 0x81C, 0x63500103,
+ 0x81C, 0x62520103, 0x81C, 0x61540103, 0x81C, 0x43560103,
+ 0x81C, 0x42580103, 0x81C, 0x415A0103, 0x81C, 0x405C0103,
+ 0x81C, 0x225E0103, 0x81C, 0x21600103, 0x81C, 0x20620103,
+ 0x81C, 0x03640103, 0x81C, 0x02660103, 0x81C, 0x01680103,
+ 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103,
+ 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103,
+ 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103,
+ 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x90002100, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xFD000103, 0x81C, 0xFC020103,
+ 0x81C, 0xFB040103, 0x81C, 0xFA060103, 0x81C, 0xF9080103,
+ 0x81C, 0xF80A0103, 0x81C, 0xF70C0103, 0x81C, 0xF60E0103,
+ 0x81C, 0xF5100103, 0x81C, 0xF4120103, 0x81C, 0xF3140103,
+ 0x81C, 0xF2160103, 0x81C, 0xF1180103, 0x81C, 0xF01A0103,
+ 0x81C, 0xEF1C0103, 0x81C, 0xEE1E0103, 0x81C, 0xED200103,
+ 0x81C, 0xEC220103, 0x81C, 0xEB240103, 0x81C, 0xEA260103,
+ 0x81C, 0xE9280103, 0x81C, 0xE82A0103, 0x81C, 0xE72C0103,
+ 0x81C, 0xE62E0103, 0x81C, 0xE5300103, 0x81C, 0xE4320103,
+ 0x81C, 0xE3340103, 0x81C, 0xE2360103, 0x81C, 0xC5380103,
+ 0x81C, 0xC43A0103, 0x81C, 0xC33C0103, 0x81C, 0xC23E0103,
+ 0x81C, 0xA5400103, 0x81C, 0xA4420103, 0x81C, 0xA3440103,
+ 0x81C, 0xA2460103, 0x81C, 0xA1480103, 0x81C, 0x834A0103,
+ 0x81C, 0x824C0103, 0x81C, 0x814E0103, 0x81C, 0x64500103,
+ 0x81C, 0x63520103, 0x81C, 0x62540103, 0x81C, 0x61560103,
+ 0x81C, 0x42580103, 0x81C, 0x415A0103, 0x81C, 0x405C0103,
+ 0x81C, 0x065E0103, 0x81C, 0x05600103, 0x81C, 0x04620103,
+ 0x81C, 0x03640103, 0x81C, 0x02660103, 0x81C, 0x01680103,
+ 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103,
+ 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103,
+ 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103,
+ 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x90002000, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xFE000103, 0x81C, 0xFD020103,
+ 0x81C, 0xFC040103, 0x81C, 0xFB060103, 0x81C, 0xFA080103,
+ 0x81C, 0xF90A0103, 0x81C, 0xF80C0103, 0x81C, 0xF70E0103,
+ 0x81C, 0xF6100103, 0x81C, 0xF5120103, 0x81C, 0xF4140103,
+ 0x81C, 0xF3160103, 0x81C, 0xF2180103, 0x81C, 0xF11A0103,
+ 0x81C, 0xF01C0103, 0x81C, 0xEF1E0103, 0x81C, 0xEE200103,
+ 0x81C, 0xED220103, 0x81C, 0xEC240103, 0x81C, 0xEB260103,
+ 0x81C, 0xEA280103, 0x81C, 0xE92A0103, 0x81C, 0xE82C0103,
+ 0x81C, 0xE72E0103, 0x81C, 0xE6300103, 0x81C, 0xE5320103,
+ 0x81C, 0xE4340103, 0x81C, 0xE3360103, 0x81C, 0xC6380103,
+ 0x81C, 0xC53A0103, 0x81C, 0xC43C0103, 0x81C, 0xC33E0103,
+ 0x81C, 0xA5400103, 0x81C, 0xA4420103, 0x81C, 0xA3440103,
+ 0x81C, 0xA2460103, 0x81C, 0xA1480103, 0x81C, 0xA04A0103,
+ 0x81C, 0x824C0103, 0x81C, 0x814E0103, 0x81C, 0x80500103,
+ 0x81C, 0x64520103, 0x81C, 0x63540103, 0x81C, 0x62560103,
+ 0x81C, 0x61580103, 0x81C, 0x605A0103, 0x81C, 0x235C0103,
+ 0x81C, 0x225E0103, 0x81C, 0x21600103, 0x81C, 0x20620103,
+ 0x81C, 0x03640103, 0x81C, 0x02660103, 0x81C, 0x01680103,
+ 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103,
+ 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103,
+ 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103,
+ 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0xA0000000, 0x00000000,
+ 0x81C, 0xFE000103, 0x81C, 0xFD020103, 0x81C, 0xFC040103,
+ 0x81C, 0xFB060103, 0x81C, 0xFA080103, 0x81C, 0xF90A0103,
+ 0x81C, 0xF80C0103, 0x81C, 0xF70E0103, 0x81C, 0xF6100103,
+ 0x81C, 0xF5120103, 0x81C, 0xF4140103, 0x81C, 0xF3160103,
+ 0x81C, 0xF2180103, 0x81C, 0xF11A0103, 0x81C, 0xF01C0103,
+ 0x81C, 0xEF1E0103, 0x81C, 0xEE200103, 0x81C, 0xED220103,
+ 0x81C, 0xEC240103, 0x81C, 0xEB260103, 0x81C, 0xEA280103,
+ 0x81C, 0xE92A0103, 0x81C, 0xE82C0103, 0x81C, 0xE72E0103,
+ 0x81C, 0xE6300103, 0x81C, 0xE5320103, 0x81C, 0xE4340103,
+ 0x81C, 0xE3360103, 0x81C, 0xC6380103, 0x81C, 0xC53A0103,
+ 0x81C, 0xC43C0103, 0x81C, 0xC33E0103, 0x81C, 0xA5400103,
+ 0x81C, 0xA4420103, 0x81C, 0xA3440103, 0x81C, 0xA2460103,
+ 0x81C, 0xA1480103, 0x81C, 0xA04A0103, 0x81C, 0x824C0103,
+ 0x81C, 0x814E0103, 0x81C, 0x80500103, 0x81C, 0x64520103,
+ 0x81C, 0x63540103, 0x81C, 0x62560103, 0x81C, 0x61580103,
+ 0x81C, 0x605A0103, 0x81C, 0x235C0103, 0x81C, 0x225E0103,
+ 0x81C, 0x21600103, 0x81C, 0x20620103, 0x81C, 0x03640103,
+ 0x81C, 0x02660103, 0x81C, 0x01680103, 0x81C, 0x006A0103,
+ 0x81C, 0x006C0103, 0x81C, 0x006E0103, 0x81C, 0x00700103,
+ 0x81C, 0x00720103, 0x81C, 0x00740103, 0x81C, 0x00760103,
+ 0x81C, 0x00780103, 0x81C, 0x007A0103, 0x81C, 0x007C0103,
+ 0x81C, 0x007E0103, 0xB0000000, 0x00000000, 0x8000100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x81C, 0xF8000203, 0x81C, 0xF7020203,
+ 0x81C, 0xF6040203, 0x81C, 0xF5060203, 0x81C, 0xF4080203,
+ 0x81C, 0xF30A0203, 0x81C, 0xF20C0203, 0x81C, 0xF10E0203,
+ 0x81C, 0xF0100203, 0x81C, 0xEF120203, 0x81C, 0xEE140203,
+ 0x81C, 0xED160203, 0x81C, 0xEC180203, 0x81C, 0xEB1A0203,
+ 0x81C, 0xEA1C0203, 0x81C, 0xE91E0203, 0x81C, 0xE8200203,
+ 0x81C, 0xE7220203, 0x81C, 0xE6240203, 0x81C, 0xE5260203,
+ 0x81C, 0xE4280203, 0x81C, 0xE32A0203, 0x81C, 0xC42C0203,
+ 0x81C, 0xC32E0203, 0x81C, 0xC2300203, 0x81C, 0xC1320203,
+ 0x81C, 0xA3340203, 0x81C, 0xA2360203, 0x81C, 0xA1380203,
+ 0x81C, 0xA03A0203, 0x81C, 0x823C0203, 0x81C, 0x813E0203,
+ 0x81C, 0x80400203, 0x81C, 0x65420203, 0x81C, 0x64440203,
+ 0x81C, 0x63460203, 0x81C, 0x62480203, 0x81C, 0x614A0203,
+ 0x81C, 0x424C0203, 0x81C, 0x414E0203, 0x81C, 0x40500203,
+ 0x81C, 0x22520203, 0x81C, 0x21540203, 0x81C, 0x20560203,
+ 0x81C, 0x04580203, 0x81C, 0x035A0203, 0x81C, 0x025C0203,
+ 0x81C, 0x015E0203, 0x81C, 0x00600203, 0x81C, 0x00620203,
+ 0x81C, 0x00640203, 0x81C, 0x00660203, 0x81C, 0x00680203,
+ 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203,
+ 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203,
+ 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203,
+ 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x9000100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x81C, 0xF9000203, 0x81C, 0xF8020203,
+ 0x81C, 0xF7040203, 0x81C, 0xF6060203, 0x81C, 0xF5080203,
+ 0x81C, 0xF40A0203, 0x81C, 0xF30C0203, 0x81C, 0xF20E0203,
+ 0x81C, 0xF1100203, 0x81C, 0xF0120203, 0x81C, 0xEF140203,
+ 0x81C, 0xEE160203, 0x81C, 0xED180203, 0x81C, 0xEC1A0203,
+ 0x81C, 0xEB1C0203, 0x81C, 0xEA1E0203, 0x81C, 0xE9200203,
+ 0x81C, 0xE8220203, 0x81C, 0xE7240203, 0x81C, 0xE6260203,
+ 0x81C, 0xE5280203, 0x81C, 0xC42A0203, 0x81C, 0xC32C0203,
+ 0x81C, 0xC22E0203, 0x81C, 0xC1300203, 0x81C, 0xC0320203,
+ 0x81C, 0xA3340203, 0x81C, 0xA2360203, 0x81C, 0xA1380203,
+ 0x81C, 0xA03A0203, 0x81C, 0x823C0203, 0x81C, 0x813E0203,
+ 0x81C, 0x80400203, 0x81C, 0x64420203, 0x81C, 0x63440203,
+ 0x81C, 0x62460203, 0x81C, 0x61480203, 0x81C, 0x604A0203,
+ 0x81C, 0x414C0203, 0x81C, 0x404E0203, 0x81C, 0x22500203,
+ 0x81C, 0x21520203, 0x81C, 0x20540203, 0x81C, 0x03560203,
+ 0x81C, 0x02580203, 0x81C, 0x015A0203, 0x81C, 0x005C0203,
+ 0x81C, 0x005E0203, 0x81C, 0x00600203, 0x81C, 0x00620203,
+ 0x81C, 0x00640203, 0x81C, 0x00660203, 0x81C, 0x00680203,
+ 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203,
+ 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203,
+ 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203,
+ 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x9000100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xF7000203, 0x81C, 0xF6020203,
+ 0x81C, 0xF5040203, 0x81C, 0xF4060203, 0x81C, 0xF3080203,
+ 0x81C, 0xF20A0203, 0x81C, 0xF10C0203, 0x81C, 0xF00E0203,
+ 0x81C, 0xEF100203, 0x81C, 0xEE120203, 0x81C, 0xED140203,
+ 0x81C, 0xEC160203, 0x81C, 0xEB180203, 0x81C, 0xEA1A0203,
+ 0x81C, 0xE91C0203, 0x81C, 0xE81E0203, 0x81C, 0xE7200203,
+ 0x81C, 0xE6220203, 0x81C, 0xE5240203, 0x81C, 0xE4260203,
+ 0x81C, 0xE3280203, 0x81C, 0xC42A0203, 0x81C, 0xC32C0203,
+ 0x81C, 0xC22E0203, 0x81C, 0xC1300203, 0x81C, 0xC0320203,
+ 0x81C, 0xA3340203, 0x81C, 0xA2360203, 0x81C, 0xA1380203,
+ 0x81C, 0xA03A0203, 0x81C, 0x823C0203, 0x81C, 0x813E0203,
+ 0x81C, 0x80400203, 0x81C, 0x63420203, 0x81C, 0x62440203,
+ 0x81C, 0x61460203, 0x81C, 0x60480203, 0x81C, 0x424A0203,
+ 0x81C, 0x414C0203, 0x81C, 0x404E0203, 0x81C, 0x06500203,
+ 0x81C, 0x05520203, 0x81C, 0x04540203, 0x81C, 0x03560203,
+ 0x81C, 0x02580203, 0x81C, 0x015A0203, 0x81C, 0x005C0203,
+ 0x81C, 0x005E0203, 0x81C, 0x00600203, 0x81C, 0x00620203,
+ 0x81C, 0x00640203, 0x81C, 0x00660203, 0x81C, 0x00680203,
+ 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203,
+ 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203,
+ 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203,
+ 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x9000200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xF7000203, 0x81C, 0xF6020203,
+ 0x81C, 0xF5040203, 0x81C, 0xF4060203, 0x81C, 0xF3080203,
+ 0x81C, 0xF20A0203, 0x81C, 0xF10C0203, 0x81C, 0xF00E0203,
+ 0x81C, 0xEF100203, 0x81C, 0xEE120203, 0x81C, 0xED140203,
+ 0x81C, 0xEC160203, 0x81C, 0xEB180203, 0x81C, 0xEA1A0203,
+ 0x81C, 0xE91C0203, 0x81C, 0xE81E0203, 0x81C, 0xE7200203,
+ 0x81C, 0xE6220203, 0x81C, 0xE5240203, 0x81C, 0xE4260203,
+ 0x81C, 0xE3280203, 0x81C, 0xC42A0203, 0x81C, 0xC32C0203,
+ 0x81C, 0xC22E0203, 0x81C, 0xC1300203, 0x81C, 0xC0320203,
+ 0x81C, 0xA3340203, 0x81C, 0xA2360203, 0x81C, 0xA1380203,
+ 0x81C, 0xA03A0203, 0x81C, 0x823C0203, 0x81C, 0x813E0203,
+ 0x81C, 0x80400203, 0x81C, 0x64420203, 0x81C, 0x63440203,
+ 0x81C, 0x62460203, 0x81C, 0x61480203, 0x81C, 0x604A0203,
+ 0x81C, 0x414C0203, 0x81C, 0x404E0203, 0x81C, 0x22500203,
+ 0x81C, 0x21520203, 0x81C, 0x20540203, 0x81C, 0x03560203,
+ 0x81C, 0x02580203, 0x81C, 0x015A0203, 0x81C, 0x005C0203,
+ 0x81C, 0x005E0203, 0x81C, 0x00600203, 0x81C, 0x00620203,
+ 0x81C, 0x00640203, 0x81C, 0x00660203, 0x81C, 0x00680203,
+ 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203,
+ 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203,
+ 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203,
+ 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x9000200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xF7000203, 0x81C, 0xF6020203,
+ 0x81C, 0xF5040203, 0x81C, 0xF4060203, 0x81C, 0xF3080203,
+ 0x81C, 0xF20A0203, 0x81C, 0xF10C0203, 0x81C, 0xF00E0203,
+ 0x81C, 0xEF100203, 0x81C, 0xEE120203, 0x81C, 0xED140203,
+ 0x81C, 0xEC160203, 0x81C, 0xEB180203, 0x81C, 0xEA1A0203,
+ 0x81C, 0xE91C0203, 0x81C, 0xE81E0203, 0x81C, 0xE7200203,
+ 0x81C, 0xE6220203, 0x81C, 0xE5240203, 0x81C, 0xE4260203,
+ 0x81C, 0xE3280203, 0x81C, 0xC42A0203, 0x81C, 0xC32C0203,
+ 0x81C, 0xC22E0203, 0x81C, 0xC1300203, 0x81C, 0xC0320203,
+ 0x81C, 0xA3340203, 0x81C, 0xA2360203, 0x81C, 0xA1380203,
+ 0x81C, 0xA03A0203, 0x81C, 0x823C0203, 0x81C, 0x813E0203,
+ 0x81C, 0x80400203, 0x81C, 0x64420203, 0x81C, 0x63440203,
+ 0x81C, 0x62460203, 0x81C, 0x61480203, 0x81C, 0x604A0203,
+ 0x81C, 0x414C0203, 0x81C, 0x404E0203, 0x81C, 0x22500203,
+ 0x81C, 0x21520203, 0x81C, 0x20540203, 0x81C, 0x03560203,
+ 0x81C, 0x02580203, 0x81C, 0x015A0203, 0x81C, 0x005C0203,
+ 0x81C, 0x005E0203, 0x81C, 0x00600203, 0x81C, 0x00620203,
+ 0x81C, 0x00640203, 0x81C, 0x00660203, 0x81C, 0x00680203,
+ 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203,
+ 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203,
+ 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203,
+ 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x90012100, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xFB000203, 0x81C, 0xFA020203,
+ 0x81C, 0xF9040203, 0x81C, 0xF8060203, 0x81C, 0xF7080203,
+ 0x81C, 0xF60A0203, 0x81C, 0xF50C0203, 0x81C, 0xF40E0203,
+ 0x81C, 0xF3100203, 0x81C, 0xF2120203, 0x81C, 0xF1140203,
+ 0x81C, 0xF0160203, 0x81C, 0xEF180203, 0x81C, 0xEE1A0203,
+ 0x81C, 0xED1C0203, 0x81C, 0xEC1E0203, 0x81C, 0xEB200203,
+ 0x81C, 0xEA220203, 0x81C, 0xE9240203, 0x81C, 0xE8260203,
+ 0x81C, 0xE7280203, 0x81C, 0xE62A0203, 0x81C, 0xE52C0203,
+ 0x81C, 0xE42E0203, 0x81C, 0xE3300203, 0x81C, 0xE2320203,
+ 0x81C, 0xC6340203, 0x81C, 0xC5360203, 0x81C, 0xC4380203,
+ 0x81C, 0xC33A0203, 0x81C, 0xC23C0203, 0x81C, 0xC13E0203,
+ 0x81C, 0xC0400203, 0x81C, 0xA3420203, 0x81C, 0xA2440203,
+ 0x81C, 0xA1460203, 0x81C, 0xA0480203, 0x81C, 0x824A0203,
+ 0x81C, 0x814C0203, 0x81C, 0x804E0203, 0x81C, 0x63500203,
+ 0x81C, 0x62520203, 0x81C, 0x61540203, 0x81C, 0x60560203,
+ 0x81C, 0x24580203, 0x81C, 0x235A0203, 0x81C, 0x225C0203,
+ 0x81C, 0x215E0203, 0x81C, 0x20600203, 0x81C, 0x03620203,
+ 0x81C, 0x02640203, 0x81C, 0x01660203, 0x81C, 0x00680203,
+ 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203,
+ 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203,
+ 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203,
+ 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x90001004, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xF8000203, 0x81C, 0xF7020203,
+ 0x81C, 0xF6040203, 0x81C, 0xF5060203, 0x81C, 0xF4080203,
+ 0x81C, 0xF30A0203, 0x81C, 0xF20C0203, 0x81C, 0xF10E0203,
+ 0x81C, 0xF0100203, 0x81C, 0xEF120203, 0x81C, 0xEE140203,
+ 0x81C, 0xED160203, 0x81C, 0xEC180203, 0x81C, 0xEB1A0203,
+ 0x81C, 0xEA1C0203, 0x81C, 0xE91E0203, 0x81C, 0xE8200203,
+ 0x81C, 0xE7220203, 0x81C, 0xE6240203, 0x81C, 0xE5260203,
+ 0x81C, 0xE4280203, 0x81C, 0xE32A0203, 0x81C, 0xC42C0203,
+ 0x81C, 0xC32E0203, 0x81C, 0xC2300203, 0x81C, 0xC1320203,
+ 0x81C, 0xA3340203, 0x81C, 0xA2360203, 0x81C, 0xA1380203,
+ 0x81C, 0xA03A0203, 0x81C, 0x823C0203, 0x81C, 0x813E0203,
+ 0x81C, 0x80400203, 0x81C, 0x65420203, 0x81C, 0x64440203,
+ 0x81C, 0x63460203, 0x81C, 0x62480203, 0x81C, 0x614A0203,
+ 0x81C, 0x424C0203, 0x81C, 0x414E0203, 0x81C, 0x40500203,
+ 0x81C, 0x22520203, 0x81C, 0x21540203, 0x81C, 0x20560203,
+ 0x81C, 0x04580203, 0x81C, 0x035A0203, 0x81C, 0x025C0203,
+ 0x81C, 0x015E0203, 0x81C, 0x00600203, 0x81C, 0x00620203,
+ 0x81C, 0x00640203, 0x81C, 0x00660203, 0x81C, 0x00680203,
+ 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203,
+ 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203,
+ 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203,
+ 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x90011000, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xFC000203, 0x81C, 0xFB020203,
+ 0x81C, 0xFA040203, 0x81C, 0xF9060203, 0x81C, 0xF8080203,
+ 0x81C, 0xF70A0203, 0x81C, 0xF60C0203, 0x81C, 0xF50E0203,
+ 0x81C, 0xF4100203, 0x81C, 0xF3120203, 0x81C, 0xF2140203,
+ 0x81C, 0xF1160203, 0x81C, 0xF0180203, 0x81C, 0xEE1A0203,
+ 0x81C, 0xED1C0203, 0x81C, 0xEC1E0203, 0x81C, 0xEB200203,
+ 0x81C, 0xEA220203, 0x81C, 0xE9240203, 0x81C, 0xE8260203,
+ 0x81C, 0xE7280203, 0x81C, 0xE62A0203, 0x81C, 0xE52C0203,
+ 0x81C, 0xE42E0203, 0x81C, 0xE3300203, 0x81C, 0xE2320203,
+ 0x81C, 0xC6340203, 0x81C, 0xC5360203, 0x81C, 0xC4380203,
+ 0x81C, 0xC33A0203, 0x81C, 0xA63C0203, 0x81C, 0xA53E0203,
+ 0x81C, 0xA4400203, 0x81C, 0xA3420203, 0x81C, 0xA2440203,
+ 0x81C, 0xA1460203, 0x81C, 0x83480203, 0x81C, 0x824A0203,
+ 0x81C, 0x814C0203, 0x81C, 0x804E0203, 0x81C, 0x63500203,
+ 0x81C, 0x62520203, 0x81C, 0x61540203, 0x81C, 0x42560203,
+ 0x81C, 0x41580203, 0x81C, 0x405A0203, 0x81C, 0x225C0203,
+ 0x81C, 0x215E0203, 0x81C, 0x20600203, 0x81C, 0x04620203,
+ 0x81C, 0x03640203, 0x81C, 0x02660203, 0x81C, 0x01680203,
+ 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203,
+ 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203,
+ 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203,
+ 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x90002100, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xFC000203, 0x81C, 0xFB020203,
+ 0x81C, 0xFA040203, 0x81C, 0xF9060203, 0x81C, 0xF8080203,
+ 0x81C, 0xF70A0203, 0x81C, 0xF60C0203, 0x81C, 0xF50E0203,
+ 0x81C, 0xF4100203, 0x81C, 0xF3120203, 0x81C, 0xF2140203,
+ 0x81C, 0xF1160203, 0x81C, 0xF0180203, 0x81C, 0xEF1A0203,
+ 0x81C, 0xEE1C0203, 0x81C, 0xED1E0203, 0x81C, 0xEC200203,
+ 0x81C, 0xEB220203, 0x81C, 0xEA240203, 0x81C, 0xE9260203,
+ 0x81C, 0xE8280203, 0x81C, 0xE72A0203, 0x81C, 0xE62C0203,
+ 0x81C, 0xE52E0203, 0x81C, 0xE4300203, 0x81C, 0xE3320203,
+ 0x81C, 0xE2340203, 0x81C, 0xE1360203, 0x81C, 0xC5380203,
+ 0x81C, 0xC43A0203, 0x81C, 0xC33C0203, 0x81C, 0xC23E0203,
+ 0x81C, 0xC1400203, 0x81C, 0xA3420203, 0x81C, 0xA2440203,
+ 0x81C, 0xA1460203, 0x81C, 0xA0480203, 0x81C, 0x834A0203,
+ 0x81C, 0x824C0203, 0x81C, 0x814E0203, 0x81C, 0x64500203,
+ 0x81C, 0x63520203, 0x81C, 0x62540203, 0x81C, 0x61560203,
+ 0x81C, 0x25580203, 0x81C, 0x245A0203, 0x81C, 0x235C0203,
+ 0x81C, 0x225E0203, 0x81C, 0x21600203, 0x81C, 0x04620203,
+ 0x81C, 0x03640203, 0x81C, 0x02660203, 0x81C, 0x01680203,
+ 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203,
+ 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203,
+ 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203,
+ 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x90002000, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xFC000203, 0x81C, 0xFB020203,
+ 0x81C, 0xFA040203, 0x81C, 0xF9060203, 0x81C, 0xF8080203,
+ 0x81C, 0xF70A0203, 0x81C, 0xF60C0203, 0x81C, 0xF50E0203,
+ 0x81C, 0xF4100203, 0x81C, 0xF3120203, 0x81C, 0xF2140203,
+ 0x81C, 0xF1160203, 0x81C, 0xF0180203, 0x81C, 0xEF1A0203,
+ 0x81C, 0xEE1C0203, 0x81C, 0xED1E0203, 0x81C, 0xEC200203,
+ 0x81C, 0xEB220203, 0x81C, 0xEA240203, 0x81C, 0xE9260203,
+ 0x81C, 0xE8280203, 0x81C, 0xE72A0203, 0x81C, 0xE62C0203,
+ 0x81C, 0xE52E0203, 0x81C, 0xE4300203, 0x81C, 0xE3320203,
+ 0x81C, 0xE2340203, 0x81C, 0xC6360203, 0x81C, 0xC5380203,
+ 0x81C, 0xC43A0203, 0x81C, 0xC33C0203, 0x81C, 0xA63E0203,
+ 0x81C, 0xA5400203, 0x81C, 0xA4420203, 0x81C, 0xA3440203,
+ 0x81C, 0xA2460203, 0x81C, 0xA1480203, 0x81C, 0x834A0203,
+ 0x81C, 0x824C0203, 0x81C, 0x814E0203, 0x81C, 0x64500203,
+ 0x81C, 0x63520203, 0x81C, 0x62540203, 0x81C, 0x61560203,
+ 0x81C, 0x60580203, 0x81C, 0x405A0203, 0x81C, 0x215C0203,
+ 0x81C, 0x205E0203, 0x81C, 0x03600203, 0x81C, 0x02620203,
+ 0x81C, 0x01640203, 0x81C, 0x00660203, 0x81C, 0x00680203,
+ 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203,
+ 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203,
+ 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203,
+ 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0xA0000000, 0x00000000,
+ 0x81C, 0xFD000203, 0x81C, 0xFC020203, 0x81C, 0xFB040203,
+ 0x81C, 0xFA060203, 0x81C, 0xF9080203, 0x81C, 0xF80A0203,
+ 0x81C, 0xF70C0203, 0x81C, 0xF60E0203, 0x81C, 0xF5100203,
+ 0x81C, 0xF4120203, 0x81C, 0xF3140203, 0x81C, 0xF2160203,
+ 0x81C, 0xF1180203, 0x81C, 0xF01A0203, 0x81C, 0xEF1C0203,
+ 0x81C, 0xEE1E0203, 0x81C, 0xED200203, 0x81C, 0xEC220203,
+ 0x81C, 0xEB240203, 0x81C, 0xEA260203, 0x81C, 0xE9280203,
+ 0x81C, 0xE82A0203, 0x81C, 0xE72C0203, 0x81C, 0xE62E0203,
+ 0x81C, 0xE5300203, 0x81C, 0xE4320203, 0x81C, 0xE3340203,
+ 0x81C, 0xC6360203, 0x81C, 0xC5380203, 0x81C, 0xC43A0203,
+ 0x81C, 0xC33C0203, 0x81C, 0xA63E0203, 0x81C, 0xA5400203,
+ 0x81C, 0xA4420203, 0x81C, 0xA3440203, 0x81C, 0xA2460203,
+ 0x81C, 0xA1480203, 0x81C, 0x834A0203, 0x81C, 0x824C0203,
+ 0x81C, 0x814E0203, 0x81C, 0x64500203, 0x81C, 0x63520203,
+ 0x81C, 0x62540203, 0x81C, 0x61560203, 0x81C, 0x60580203,
+ 0x81C, 0x235A0203, 0x81C, 0x225C0203, 0x81C, 0x215E0203,
+ 0x81C, 0x20600203, 0x81C, 0x03620203, 0x81C, 0x02640203,
+ 0x81C, 0x01660203, 0x81C, 0x00680203, 0x81C, 0x006A0203,
+ 0x81C, 0x006C0203, 0x81C, 0x006E0203, 0x81C, 0x00700203,
+ 0x81C, 0x00720203, 0x81C, 0x00740203, 0x81C, 0x00760203,
+ 0x81C, 0x00780203, 0x81C, 0x007A0203, 0x81C, 0x007C0203,
+ 0x81C, 0x007E0203, 0xB0000000, 0x00000000, 0x8000100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x81C, 0xF8000303, 0x81C, 0xF7020303,
+ 0x81C, 0xF6040303, 0x81C, 0xF5060303, 0x81C, 0xF4080303,
+ 0x81C, 0xF30A0303, 0x81C, 0xF20C0303, 0x81C, 0xF10E0303,
+ 0x81C, 0xF0100303, 0x81C, 0xEF120303, 0x81C, 0xEE140303,
+ 0x81C, 0xED160303, 0x81C, 0xEC180303, 0x81C, 0xEB1A0303,
+ 0x81C, 0xEA1C0303, 0x81C, 0xE91E0303, 0x81C, 0xCA200303,
+ 0x81C, 0xC9220303, 0x81C, 0xC8240303, 0x81C, 0xC7260303,
+ 0x81C, 0xC6280303, 0x81C, 0xC52A0303, 0x81C, 0xC42C0303,
+ 0x81C, 0xC32E0303, 0x81C, 0xC2300303, 0x81C, 0xC1320303,
+ 0x81C, 0xA3340303, 0x81C, 0xA2360303, 0x81C, 0xA1380303,
+ 0x81C, 0xA03A0303, 0x81C, 0x823C0303, 0x81C, 0x813E0303,
+ 0x81C, 0x80400303, 0x81C, 0x65420303, 0x81C, 0x64440303,
+ 0x81C, 0x63460303, 0x81C, 0x62480303, 0x81C, 0x614A0303,
+ 0x81C, 0x424C0303, 0x81C, 0x414E0303, 0x81C, 0x40500303,
+ 0x81C, 0x22520303, 0x81C, 0x21540303, 0x81C, 0x20560303,
+ 0x81C, 0x04580303, 0x81C, 0x035A0303, 0x81C, 0x025C0303,
+ 0x81C, 0x015E0303, 0x81C, 0x00600303, 0x81C, 0x00620303,
+ 0x81C, 0x00640303, 0x81C, 0x00660303, 0x81C, 0x00680303,
+ 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303,
+ 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303,
+ 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303,
+ 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x9000100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x81C, 0xF9000303, 0x81C, 0xF8020303,
+ 0x81C, 0xF7040303, 0x81C, 0xF6060303, 0x81C, 0xF5080303,
+ 0x81C, 0xF40A0303, 0x81C, 0xF30C0303, 0x81C, 0xF20E0303,
+ 0x81C, 0xF1100303, 0x81C, 0xF0120303, 0x81C, 0xEF140303,
+ 0x81C, 0xEE160303, 0x81C, 0xED180303, 0x81C, 0xEC1A0303,
+ 0x81C, 0xEB1C0303, 0x81C, 0xEA1E0303, 0x81C, 0xC9200303,
+ 0x81C, 0xC8220303, 0x81C, 0xC7240303, 0x81C, 0xC6260303,
+ 0x81C, 0xC5280303, 0x81C, 0xC42A0303, 0x81C, 0xC32C0303,
+ 0x81C, 0xC22E0303, 0x81C, 0xC1300303, 0x81C, 0xC0320303,
+ 0x81C, 0xA3340303, 0x81C, 0xA2360303, 0x81C, 0xA1380303,
+ 0x81C, 0xA03A0303, 0x81C, 0x823C0303, 0x81C, 0x813E0303,
+ 0x81C, 0x80400303, 0x81C, 0x64420303, 0x81C, 0x63440303,
+ 0x81C, 0x62460303, 0x81C, 0x61480303, 0x81C, 0x604A0303,
+ 0x81C, 0x414C0303, 0x81C, 0x404E0303, 0x81C, 0x22500303,
+ 0x81C, 0x21520303, 0x81C, 0x20540303, 0x81C, 0x03560303,
+ 0x81C, 0x02580303, 0x81C, 0x015A0303, 0x81C, 0x005C0303,
+ 0x81C, 0x005E0303, 0x81C, 0x00600303, 0x81C, 0x00620303,
+ 0x81C, 0x00640303, 0x81C, 0x00660303, 0x81C, 0x00680303,
+ 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303,
+ 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303,
+ 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303,
+ 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x9000100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xF7000303, 0x81C, 0xF6020303,
+ 0x81C, 0xF5040303, 0x81C, 0xF4060303, 0x81C, 0xF3080303,
+ 0x81C, 0xF20A0303, 0x81C, 0xF10C0303, 0x81C, 0xF00E0303,
+ 0x81C, 0xEF100303, 0x81C, 0xEE120303, 0x81C, 0xED140303,
+ 0x81C, 0xEC160303, 0x81C, 0xEB180303, 0x81C, 0xEA1A0303,
+ 0x81C, 0xE91C0303, 0x81C, 0xCA1E0303, 0x81C, 0xC9200303,
+ 0x81C, 0xC8220303, 0x81C, 0xC7240303, 0x81C, 0xC6260303,
+ 0x81C, 0xC5280303, 0x81C, 0xC42A0303, 0x81C, 0xC32C0303,
+ 0x81C, 0xC22E0303, 0x81C, 0xC1300303, 0x81C, 0xA4320303,
+ 0x81C, 0xA3340303, 0x81C, 0xA2360303, 0x81C, 0xA1380303,
+ 0x81C, 0xA03A0303, 0x81C, 0x823C0303, 0x81C, 0x813E0303,
+ 0x81C, 0x80400303, 0x81C, 0x64420303, 0x81C, 0x63440303,
+ 0x81C, 0x62460303, 0x81C, 0x61480303, 0x81C, 0x604A0303,
+ 0x81C, 0x414C0303, 0x81C, 0x404E0303, 0x81C, 0x06500303,
+ 0x81C, 0x05520303, 0x81C, 0x04540303, 0x81C, 0x03560303,
+ 0x81C, 0x02580303, 0x81C, 0x015A0303, 0x81C, 0x005C0303,
+ 0x81C, 0x005E0303, 0x81C, 0x00600303, 0x81C, 0x00620303,
+ 0x81C, 0x00640303, 0x81C, 0x00660303, 0x81C, 0x00680303,
+ 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303,
+ 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303,
+ 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303,
+ 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x9000200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xF7000303, 0x81C, 0xF6020303,
+ 0x81C, 0xF5040303, 0x81C, 0xF4060303, 0x81C, 0xF3080303,
+ 0x81C, 0xF20A0303, 0x81C, 0xF10C0303, 0x81C, 0xF00E0303,
+ 0x81C, 0xEF100303, 0x81C, 0xEE120303, 0x81C, 0xED140303,
+ 0x81C, 0xEC160303, 0x81C, 0xEB180303, 0x81C, 0xEA1A0303,
+ 0x81C, 0xE91C0303, 0x81C, 0xCA1E0303, 0x81C, 0xC9200303,
+ 0x81C, 0xC8220303, 0x81C, 0xC7240303, 0x81C, 0xC6260303,
+ 0x81C, 0xC5280303, 0x81C, 0xC42A0303, 0x81C, 0xC32C0303,
+ 0x81C, 0xC22E0303, 0x81C, 0xC1300303, 0x81C, 0xA4320303,
+ 0x81C, 0xA3340303, 0x81C, 0xA2360303, 0x81C, 0xA1380303,
+ 0x81C, 0xA03A0303, 0x81C, 0x823C0303, 0x81C, 0x813E0303,
+ 0x81C, 0x80400303, 0x81C, 0x64420303, 0x81C, 0x63440303,
+ 0x81C, 0x62460303, 0x81C, 0x61480303, 0x81C, 0x604A0303,
+ 0x81C, 0x414C0303, 0x81C, 0x404E0303, 0x81C, 0x22500303,
+ 0x81C, 0x21520303, 0x81C, 0x20540303, 0x81C, 0x03560303,
+ 0x81C, 0x02580303, 0x81C, 0x015A0303, 0x81C, 0x005C0303,
+ 0x81C, 0x005E0303, 0x81C, 0x00600303, 0x81C, 0x00620303,
+ 0x81C, 0x00640303, 0x81C, 0x00660303, 0x81C, 0x00680303,
+ 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303,
+ 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303,
+ 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303,
+ 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x9000200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xF7000303, 0x81C, 0xF6020303,
+ 0x81C, 0xF5040303, 0x81C, 0xF4060303, 0x81C, 0xF3080303,
+ 0x81C, 0xF20A0303, 0x81C, 0xF10C0303, 0x81C, 0xF00E0303,
+ 0x81C, 0xEF100303, 0x81C, 0xEE120303, 0x81C, 0xED140303,
+ 0x81C, 0xEC160303, 0x81C, 0xEB180303, 0x81C, 0xEA1A0303,
+ 0x81C, 0xE91C0303, 0x81C, 0xCA1E0303, 0x81C, 0xC9200303,
+ 0x81C, 0xC8220303, 0x81C, 0xC7240303, 0x81C, 0xC6260303,
+ 0x81C, 0xC5280303, 0x81C, 0xC42A0303, 0x81C, 0xC32C0303,
+ 0x81C, 0xC22E0303, 0x81C, 0xC1300303, 0x81C, 0xA4320303,
+ 0x81C, 0xA3340303, 0x81C, 0xA2360303, 0x81C, 0xA1380303,
+ 0x81C, 0xA03A0303, 0x81C, 0x823C0303, 0x81C, 0x813E0303,
+ 0x81C, 0x80400303, 0x81C, 0x64420303, 0x81C, 0x63440303,
+ 0x81C, 0x62460303, 0x81C, 0x61480303, 0x81C, 0x604A0303,
+ 0x81C, 0x414C0303, 0x81C, 0x404E0303, 0x81C, 0x22500303,
+ 0x81C, 0x21520303, 0x81C, 0x20540303, 0x81C, 0x03560303,
+ 0x81C, 0x02580303, 0x81C, 0x015A0303, 0x81C, 0x005C0303,
+ 0x81C, 0x005E0303, 0x81C, 0x00600303, 0x81C, 0x00620303,
+ 0x81C, 0x00640303, 0x81C, 0x00660303, 0x81C, 0x00680303,
+ 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303,
+ 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303,
+ 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303,
+ 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x90012100, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xFB000303, 0x81C, 0xFA020303,
+ 0x81C, 0xF9040303, 0x81C, 0xF8060303, 0x81C, 0xF7080303,
+ 0x81C, 0xF60A0303, 0x81C, 0xF50C0303, 0x81C, 0xF40E0303,
+ 0x81C, 0xF3100303, 0x81C, 0xF2120303, 0x81C, 0xF1140303,
+ 0x81C, 0xF0160303, 0x81C, 0xEF180303, 0x81C, 0xEE1A0303,
+ 0x81C, 0xED1C0303, 0x81C, 0xEC1E0303, 0x81C, 0xEB200303,
+ 0x81C, 0xEA220303, 0x81C, 0xE9240303, 0x81C, 0xE8260303,
+ 0x81C, 0xE7280303, 0x81C, 0xE62A0303, 0x81C, 0xE52C0303,
+ 0x81C, 0xE42E0303, 0x81C, 0xE3300303, 0x81C, 0xE2320303,
+ 0x81C, 0xC6340303, 0x81C, 0xC5360303, 0x81C, 0xC4380303,
+ 0x81C, 0xC33A0303, 0x81C, 0xC23C0303, 0x81C, 0xC13E0303,
+ 0x81C, 0xA4400303, 0x81C, 0xA3420303, 0x81C, 0xA2440303,
+ 0x81C, 0xA1460303, 0x81C, 0x83480303, 0x81C, 0x824A0303,
+ 0x81C, 0x814C0303, 0x81C, 0x804E0303, 0x81C, 0x63500303,
+ 0x81C, 0x62520303, 0x81C, 0x43540303, 0x81C, 0x42560303,
+ 0x81C, 0x41580303, 0x81C, 0x235A0303, 0x81C, 0x225C0303,
+ 0x81C, 0x215E0303, 0x81C, 0x20600303, 0x81C, 0x04620303,
+ 0x81C, 0x03640303, 0x81C, 0x02660303, 0x81C, 0x01680303,
+ 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303,
+ 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303,
+ 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303,
+ 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x90001004, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xF8000303, 0x81C, 0xF7020303,
+ 0x81C, 0xF6040303, 0x81C, 0xF5060303, 0x81C, 0xF4080303,
+ 0x81C, 0xF30A0303, 0x81C, 0xF20C0303, 0x81C, 0xF10E0303,
+ 0x81C, 0xF0100303, 0x81C, 0xEF120303, 0x81C, 0xEE140303,
+ 0x81C, 0xED160303, 0x81C, 0xEC180303, 0x81C, 0xEB1A0303,
+ 0x81C, 0xEA1C0303, 0x81C, 0xE91E0303, 0x81C, 0xCA200303,
+ 0x81C, 0xC9220303, 0x81C, 0xC8240303, 0x81C, 0xC7260303,
+ 0x81C, 0xC6280303, 0x81C, 0xC52A0303, 0x81C, 0xC42C0303,
+ 0x81C, 0xC32E0303, 0x81C, 0xC2300303, 0x81C, 0xC1320303,
+ 0x81C, 0xA3340303, 0x81C, 0xA2360303, 0x81C, 0xA1380303,
+ 0x81C, 0xA03A0303, 0x81C, 0x823C0303, 0x81C, 0x813E0303,
+ 0x81C, 0x80400303, 0x81C, 0x65420303, 0x81C, 0x64440303,
+ 0x81C, 0x63460303, 0x81C, 0x62480303, 0x81C, 0x614A0303,
+ 0x81C, 0x424C0303, 0x81C, 0x414E0303, 0x81C, 0x40500303,
+ 0x81C, 0x22520303, 0x81C, 0x21540303, 0x81C, 0x20560303,
+ 0x81C, 0x04580303, 0x81C, 0x035A0303, 0x81C, 0x025C0303,
+ 0x81C, 0x015E0303, 0x81C, 0x00600303, 0x81C, 0x00620303,
+ 0x81C, 0x00640303, 0x81C, 0x00660303, 0x81C, 0x00680303,
+ 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303,
+ 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303,
+ 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303,
+ 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x90011000, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xFB000303, 0x81C, 0xFA020303,
+ 0x81C, 0xF9040303, 0x81C, 0xF8060303, 0x81C, 0xF7080303,
+ 0x81C, 0xF60A0303, 0x81C, 0xF50C0303, 0x81C, 0xF40E0303,
+ 0x81C, 0xF3100303, 0x81C, 0xF2120303, 0x81C, 0xF1140303,
+ 0x81C, 0xF0160303, 0x81C, 0xEE180303, 0x81C, 0xED1A0303,
+ 0x81C, 0xEC1C0303, 0x81C, 0xEB1E0303, 0x81C, 0xEA200303,
+ 0x81C, 0xE9220303, 0x81C, 0xE8240303, 0x81C, 0xE7260303,
+ 0x81C, 0xE6280303, 0x81C, 0xE52A0303, 0x81C, 0xE42C0303,
+ 0x81C, 0xE32E0303, 0x81C, 0xE2300303, 0x81C, 0xE1320303,
+ 0x81C, 0xC6340303, 0x81C, 0xC5360303, 0x81C, 0xC4380303,
+ 0x81C, 0xC33A0303, 0x81C, 0xA63C0303, 0x81C, 0xA53E0303,
+ 0x81C, 0xA4400303, 0x81C, 0xA3420303, 0x81C, 0xA2440303,
+ 0x81C, 0xA1460303, 0x81C, 0x83480303, 0x81C, 0x824A0303,
+ 0x81C, 0x814C0303, 0x81C, 0x804E0303, 0x81C, 0x63500303,
+ 0x81C, 0x62520303, 0x81C, 0x61540303, 0x81C, 0x42560303,
+ 0x81C, 0x41580303, 0x81C, 0x405A0303, 0x81C, 0x225C0303,
+ 0x81C, 0x215E0303, 0x81C, 0x20600303, 0x81C, 0x04620303,
+ 0x81C, 0x03640303, 0x81C, 0x02660303, 0x81C, 0x01680303,
+ 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303,
+ 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303,
+ 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303,
+ 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x90002100, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xFB000303, 0x81C, 0xFA020303,
+ 0x81C, 0xF9040303, 0x81C, 0xF8060303, 0x81C, 0xF7080303,
+ 0x81C, 0xF60A0303, 0x81C, 0xF50C0303, 0x81C, 0xF40E0303,
+ 0x81C, 0xF3100303, 0x81C, 0xF2120303, 0x81C, 0xF1140303,
+ 0x81C, 0xF0160303, 0x81C, 0xEF180303, 0x81C, 0xEE1A0303,
+ 0x81C, 0xED1C0303, 0x81C, 0xEC1E0303, 0x81C, 0xEB200303,
+ 0x81C, 0xEA220303, 0x81C, 0xE9240303, 0x81C, 0xE8260303,
+ 0x81C, 0xE7280303, 0x81C, 0xE62A0303, 0x81C, 0xE52C0303,
+ 0x81C, 0xE42E0303, 0x81C, 0xE3300303, 0x81C, 0xE2320303,
+ 0x81C, 0xE1340303, 0x81C, 0xC5360303, 0x81C, 0xC4380303,
+ 0x81C, 0xC33A0303, 0x81C, 0xC23C0303, 0x81C, 0xC13E0303,
+ 0x81C, 0xA4400303, 0x81C, 0xA3420303, 0x81C, 0xA2440303,
+ 0x81C, 0xA1460303, 0x81C, 0x83480303, 0x81C, 0x824A0303,
+ 0x81C, 0x814C0303, 0x81C, 0x804E0303, 0x81C, 0x64500303,
+ 0x81C, 0x63520303, 0x81C, 0x62540303, 0x81C, 0x61560303,
+ 0x81C, 0x60580303, 0x81C, 0x235A0303, 0x81C, 0x225C0303,
+ 0x81C, 0x215E0303, 0x81C, 0x20600303, 0x81C, 0x04620303,
+ 0x81C, 0x03640303, 0x81C, 0x02660303, 0x81C, 0x01680303,
+ 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303,
+ 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303,
+ 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303,
+ 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x90002000, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xFC000303, 0x81C, 0xFB020303,
+ 0x81C, 0xFA040303, 0x81C, 0xF9060303, 0x81C, 0xF8080303,
+ 0x81C, 0xF70A0303, 0x81C, 0xF60C0303, 0x81C, 0xF50E0303,
+ 0x81C, 0xF4100303, 0x81C, 0xF3120303, 0x81C, 0xF2140303,
+ 0x81C, 0xF1160303, 0x81C, 0xF0180303, 0x81C, 0xEF1A0303,
+ 0x81C, 0xEE1C0303, 0x81C, 0xED1E0303, 0x81C, 0xEC200303,
+ 0x81C, 0xEB220303, 0x81C, 0xEA240303, 0x81C, 0xE9260303,
+ 0x81C, 0xE8280303, 0x81C, 0xE72A0303, 0x81C, 0xE62C0303,
+ 0x81C, 0xE52E0303, 0x81C, 0xE4300303, 0x81C, 0xE3320303,
+ 0x81C, 0xE2340303, 0x81C, 0xC6360303, 0x81C, 0xC5380303,
+ 0x81C, 0xC43A0303, 0x81C, 0xC33C0303, 0x81C, 0xA63E0303,
+ 0x81C, 0xA5400303, 0x81C, 0xA4420303, 0x81C, 0xA3440303,
+ 0x81C, 0xA2460303, 0x81C, 0x84480303, 0x81C, 0x834A0303,
+ 0x81C, 0x824C0303, 0x81C, 0x814E0303, 0x81C, 0x80500303,
+ 0x81C, 0x63520303, 0x81C, 0x62540303, 0x81C, 0x61560303,
+ 0x81C, 0x60580303, 0x81C, 0x225A0303, 0x81C, 0x055C0303,
+ 0x81C, 0x045E0303, 0x81C, 0x03600303, 0x81C, 0x02620303,
+ 0x81C, 0x01640303, 0x81C, 0x00660303, 0x81C, 0x00680303,
+ 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303,
+ 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303,
+ 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303,
+ 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0xA0000000, 0x00000000,
+ 0x81C, 0xFC000303, 0x81C, 0xFB020303, 0x81C, 0xFA040303,
+ 0x81C, 0xF9060303, 0x81C, 0xF8080303, 0x81C, 0xF70A0303,
+ 0x81C, 0xF60C0303, 0x81C, 0xF50E0303, 0x81C, 0xF4100303,
+ 0x81C, 0xF3120303, 0x81C, 0xF2140303, 0x81C, 0xF1160303,
+ 0x81C, 0xF0180303, 0x81C, 0xEF1A0303, 0x81C, 0xEE1C0303,
+ 0x81C, 0xED1E0303, 0x81C, 0xEC200303, 0x81C, 0xEB220303,
+ 0x81C, 0xEA240303, 0x81C, 0xE9260303, 0x81C, 0xE8280303,
+ 0x81C, 0xE72A0303, 0x81C, 0xE62C0303, 0x81C, 0xE52E0303,
+ 0x81C, 0xE4300303, 0x81C, 0xE3320303, 0x81C, 0xE2340303,
+ 0x81C, 0xC6360303, 0x81C, 0xC5380303, 0x81C, 0xC43A0303,
+ 0x81C, 0xC33C0303, 0x81C, 0xA63E0303, 0x81C, 0xA5400303,
+ 0x81C, 0xA4420303, 0x81C, 0xA3440303, 0x81C, 0xA2460303,
+ 0x81C, 0x84480303, 0x81C, 0x834A0303, 0x81C, 0x824C0303,
+ 0x81C, 0x814E0303, 0x81C, 0x80500303, 0x81C, 0x63520303,
+ 0x81C, 0x62540303, 0x81C, 0x61560303, 0x81C, 0x60580303,
+ 0x81C, 0x235A0303, 0x81C, 0x225C0303, 0x81C, 0x215E0303,
+ 0x81C, 0x20600303, 0x81C, 0x03620303, 0x81C, 0x02640303,
+ 0x81C, 0x01660303, 0x81C, 0x00680303, 0x81C, 0x006A0303,
+ 0x81C, 0x006C0303, 0x81C, 0x006E0303, 0x81C, 0x00700303,
+ 0x81C, 0x00720303, 0x81C, 0x00740303, 0x81C, 0x00760303,
+ 0x81C, 0x00780303, 0x81C, 0x007A0303, 0x81C, 0x007C0303,
+ 0x81C, 0x007E0303, 0xB0000000, 0x00000000, 0x8000100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x81C, 0xFF000403, 0x81C, 0xF5000403,
+ 0x81C, 0xF4020403, 0x81C, 0xF3040403, 0x81C, 0xF2060403,
+ 0x81C, 0xF1080403, 0x81C, 0xF00A0403, 0x81C, 0xEF0C0403,
+ 0x81C, 0xEE0E0403, 0x81C, 0xED100403, 0x81C, 0xEC120403,
+ 0x81C, 0xEB140403, 0x81C, 0xEA160403, 0x81C, 0xE9180403,
+ 0x81C, 0xE81A0403, 0x81C, 0xE71C0403, 0x81C, 0xE61E0403,
+ 0x81C, 0xE5200403, 0x81C, 0xE4220403, 0x81C, 0xE3240403,
+ 0x81C, 0xE2260403, 0x81C, 0xE1280403, 0x81C, 0xE02A0403,
+ 0x81C, 0xC32C0403, 0x81C, 0xC22E0403, 0x81C, 0xC1300403,
+ 0x81C, 0xC0320403, 0x81C, 0xA4340403, 0x81C, 0xA3360403,
+ 0x81C, 0xA2380403, 0x81C, 0xA13A0403, 0x81C, 0xA03C0403,
+ 0x81C, 0x823E0403, 0x81C, 0x81400403, 0x81C, 0x80420403,
+ 0x81C, 0x64440403, 0x81C, 0x63460403, 0x81C, 0x62480403,
+ 0x81C, 0x614A0403, 0x81C, 0x604C0403, 0x81C, 0x454E0403,
+ 0x81C, 0x44500403, 0x81C, 0x43520403, 0x81C, 0x42540403,
+ 0x81C, 0x41560403, 0x81C, 0x40580403, 0x81C, 0x055A0403,
+ 0x81C, 0x045C0403, 0x81C, 0x035E0403, 0x81C, 0x02600403,
+ 0x81C, 0x01620403, 0x81C, 0x00640403, 0x81C, 0x00660403,
+ 0x81C, 0x00680403, 0x81C, 0x006A0403, 0x81C, 0x006C0403,
+ 0x81C, 0x006E0403, 0x81C, 0x00700403, 0x81C, 0x00720403,
+ 0x81C, 0x00740403, 0x81C, 0x00760403, 0x81C, 0x00780403,
+ 0x81C, 0x007A0403, 0x81C, 0x007C0403, 0x81C, 0x007E0403,
+ 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x81C, 0xFF000403,
+ 0x81C, 0xF5000403, 0x81C, 0xF4020403, 0x81C, 0xF3040403,
+ 0x81C, 0xF2060403, 0x81C, 0xF1080403, 0x81C, 0xF00A0403,
+ 0x81C, 0xEF0C0403, 0x81C, 0xEE0E0403, 0x81C, 0xED100403,
+ 0x81C, 0xEC120403, 0x81C, 0xEB140403, 0x81C, 0xEA160403,
+ 0x81C, 0xE9180403, 0x81C, 0xE81A0403, 0x81C, 0xE71C0403,
+ 0x81C, 0xE61E0403, 0x81C, 0xE5200403, 0x81C, 0xE4220403,
+ 0x81C, 0xE3240403, 0x81C, 0xE2260403, 0x81C, 0xE1280403,
+ 0x81C, 0xE02A0403, 0x81C, 0xC32C0403, 0x81C, 0xC22E0403,
+ 0x81C, 0xC1300403, 0x81C, 0xC0320403, 0x81C, 0xA4340403,
+ 0x81C, 0xA3360403, 0x81C, 0xA2380403, 0x81C, 0xA13A0403,
+ 0x81C, 0xA03C0403, 0x81C, 0x823E0403, 0x81C, 0x81400403,
+ 0x81C, 0x80420403, 0x81C, 0x64440403, 0x81C, 0x63460403,
+ 0x81C, 0x62480403, 0x81C, 0x614A0403, 0x81C, 0x604C0403,
+ 0x81C, 0x454E0403, 0x81C, 0x44500403, 0x81C, 0x43520403,
+ 0x81C, 0x42540403, 0x81C, 0x41560403, 0x81C, 0x40580403,
+ 0x81C, 0x055A0403, 0x81C, 0x045C0403, 0x81C, 0x035E0403,
+ 0x81C, 0x02600403, 0x81C, 0x01620403, 0x81C, 0x00640403,
+ 0x81C, 0x00660403, 0x81C, 0x00680403, 0x81C, 0x006A0403,
+ 0x81C, 0x006C0403, 0x81C, 0x006E0403, 0x81C, 0x00700403,
+ 0x81C, 0x00720403, 0x81C, 0x00740403, 0x81C, 0x00760403,
+ 0x81C, 0x00780403, 0x81C, 0x007A0403, 0x81C, 0x007C0403,
+ 0x81C, 0x007E0403, 0x9000100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x81C, 0xFF000403, 0x81C, 0xF5000403, 0x81C, 0xF4020403,
+ 0x81C, 0xF3040403, 0x81C, 0xF2060403, 0x81C, 0xF1080403,
+ 0x81C, 0xF00A0403, 0x81C, 0xEF0C0403, 0x81C, 0xEE0E0403,
+ 0x81C, 0xED100403, 0x81C, 0xEC120403, 0x81C, 0xEB140403,
+ 0x81C, 0xEA160403, 0x81C, 0xE9180403, 0x81C, 0xE81A0403,
+ 0x81C, 0xE71C0403, 0x81C, 0xE61E0403, 0x81C, 0xE5200403,
+ 0x81C, 0xE4220403, 0x81C, 0xE3240403, 0x81C, 0xE2260403,
+ 0x81C, 0xE1280403, 0x81C, 0xE02A0403, 0x81C, 0xC32C0403,
+ 0x81C, 0xC22E0403, 0x81C, 0xC1300403, 0x81C, 0xC0320403,
+ 0x81C, 0xA4340403, 0x81C, 0xA3360403, 0x81C, 0xA2380403,
+ 0x81C, 0xA13A0403, 0x81C, 0xA03C0403, 0x81C, 0x823E0403,
+ 0x81C, 0x81400403, 0x81C, 0x80420403, 0x81C, 0x64440403,
+ 0x81C, 0x63460403, 0x81C, 0x62480403, 0x81C, 0x614A0403,
+ 0x81C, 0x604C0403, 0x81C, 0x454E0403, 0x81C, 0x44500403,
+ 0x81C, 0x43520403, 0x81C, 0x42540403, 0x81C, 0x41560403,
+ 0x81C, 0x40580403, 0x81C, 0x055A0403, 0x81C, 0x045C0403,
+ 0x81C, 0x035E0403, 0x81C, 0x02600403, 0x81C, 0x01620403,
+ 0x81C, 0x00640403, 0x81C, 0x00660403, 0x81C, 0x00680403,
+ 0x81C, 0x006A0403, 0x81C, 0x006C0403, 0x81C, 0x006E0403,
+ 0x81C, 0x00700403, 0x81C, 0x00720403, 0x81C, 0x00740403,
+ 0x81C, 0x00760403, 0x81C, 0x00780403, 0x81C, 0x007A0403,
+ 0x81C, 0x007C0403, 0x81C, 0x007E0403, 0x9000200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xFF000403, 0x81C, 0xF5000403,
+ 0x81C, 0xF4020403, 0x81C, 0xF3040403, 0x81C, 0xF2060403,
+ 0x81C, 0xF1080403, 0x81C, 0xF00A0403, 0x81C, 0xEF0C0403,
+ 0x81C, 0xEE0E0403, 0x81C, 0xED100403, 0x81C, 0xEC120403,
+ 0x81C, 0xEB140403, 0x81C, 0xEA160403, 0x81C, 0xE9180403,
+ 0x81C, 0xE81A0403, 0x81C, 0xE71C0403, 0x81C, 0xE61E0403,
+ 0x81C, 0xE5200403, 0x81C, 0xE4220403, 0x81C, 0xE3240403,
+ 0x81C, 0xE2260403, 0x81C, 0xE1280403, 0x81C, 0xE02A0403,
+ 0x81C, 0xC32C0403, 0x81C, 0xC22E0403, 0x81C, 0xC1300403,
+ 0x81C, 0xC0320403, 0x81C, 0xA4340403, 0x81C, 0xA3360403,
+ 0x81C, 0xA2380403, 0x81C, 0xA13A0403, 0x81C, 0xA03C0403,
+ 0x81C, 0x823E0403, 0x81C, 0x81400403, 0x81C, 0x80420403,
+ 0x81C, 0x64440403, 0x81C, 0x63460403, 0x81C, 0x62480403,
+ 0x81C, 0x614A0403, 0x81C, 0x604C0403, 0x81C, 0x454E0403,
+ 0x81C, 0x44500403, 0x81C, 0x43520403, 0x81C, 0x42540403,
+ 0x81C, 0x41560403, 0x81C, 0x40580403, 0x81C, 0x055A0403,
+ 0x81C, 0x045C0403, 0x81C, 0x035E0403, 0x81C, 0x02600403,
+ 0x81C, 0x01620403, 0x81C, 0x00640403, 0x81C, 0x00660403,
+ 0x81C, 0x00680403, 0x81C, 0x006A0403, 0x81C, 0x006C0403,
+ 0x81C, 0x006E0403, 0x81C, 0x00700403, 0x81C, 0x00720403,
+ 0x81C, 0x00740403, 0x81C, 0x00760403, 0x81C, 0x00780403,
+ 0x81C, 0x007A0403, 0x81C, 0x007C0403, 0x81C, 0x007E0403,
+ 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x81C, 0xFF000403,
+ 0x81C, 0xFF000403, 0x81C, 0xFF020403, 0x81C, 0xFE040403,
+ 0x81C, 0xFD060403, 0x81C, 0xFC080403, 0x81C, 0xFB0A0403,
+ 0x81C, 0xFA0C0403, 0x81C, 0xF90E0403, 0x81C, 0xF8100403,
+ 0x81C, 0xF7120403, 0x81C, 0xF6140403, 0x81C, 0xF5160403,
+ 0x81C, 0xF4180403, 0x81C, 0xF31A0403, 0x81C, 0xF21C0403,
+ 0x81C, 0xD51E0403, 0x81C, 0xD4200403, 0x81C, 0xD3220403,
+ 0x81C, 0xD2240403, 0x81C, 0xB6260403, 0x81C, 0xB5280403,
+ 0x81C, 0xB42A0403, 0x81C, 0xB32C0403, 0x81C, 0xB22E0403,
+ 0x81C, 0xB1300403, 0x81C, 0xB0320403, 0x81C, 0xAF340403,
+ 0x81C, 0xAE360403, 0x81C, 0xAD380403, 0x81C, 0xAC3A0403,
+ 0x81C, 0xAB3C0403, 0x81C, 0xAA3E0403, 0x81C, 0xA9400403,
+ 0x81C, 0xA8420403, 0x81C, 0xA7440403, 0x81C, 0xA6460403,
+ 0x81C, 0xA5480403, 0x81C, 0xA44A0403, 0x81C, 0xA34C0403,
+ 0x81C, 0x854E0403, 0x81C, 0x84500403, 0x81C, 0x83520403,
+ 0x81C, 0x82540403, 0x81C, 0x81560403, 0x81C, 0x80580403,
+ 0x81C, 0x485A0403, 0x81C, 0x475C0403, 0x81C, 0x465E0403,
+ 0x81C, 0x45600403, 0x81C, 0x44620403, 0x81C, 0x0A640403,
+ 0x81C, 0x09660403, 0x81C, 0x08680403, 0x81C, 0x076A0403,
+ 0x81C, 0x066C0403, 0x81C, 0x056E0403, 0x81C, 0x04700403,
+ 0x81C, 0x03720403, 0x81C, 0x02740403, 0x81C, 0x01760403,
+ 0x81C, 0x00780403, 0x81C, 0x007A0403, 0x81C, 0x007C0403,
+ 0x81C, 0x007E0403, 0x90012100, 0x00000000, 0x40000000, 0x00000000,
+ 0x81C, 0xFF000403, 0x81C, 0xFF000403, 0x81C, 0xFF020403,
+ 0x81C, 0xFE040403, 0x81C, 0xFD060403, 0x81C, 0xFC080403,
+ 0x81C, 0xFB0A0403, 0x81C, 0xFA0C0403, 0x81C, 0xF90E0403,
+ 0x81C, 0xF8100403, 0x81C, 0xF7120403, 0x81C, 0xF6140403,
+ 0x81C, 0xF5160403, 0x81C, 0xF4180403, 0x81C, 0xF31A0403,
+ 0x81C, 0xF21C0403, 0x81C, 0xD51E0403, 0x81C, 0xD4200403,
+ 0x81C, 0xD3220403, 0x81C, 0xD2240403, 0x81C, 0xB6260403,
+ 0x81C, 0xB5280403, 0x81C, 0xB42A0403, 0x81C, 0xB32C0403,
+ 0x81C, 0xB22E0403, 0x81C, 0xB1300403, 0x81C, 0xB0320403,
+ 0x81C, 0xAF340403, 0x81C, 0xAE360403, 0x81C, 0xAD380403,
+ 0x81C, 0xAC3A0403, 0x81C, 0xAB3C0403, 0x81C, 0xAA3E0403,
+ 0x81C, 0xA9400403, 0x81C, 0xA8420403, 0x81C, 0xA7440403,
+ 0x81C, 0xA6460403, 0x81C, 0xA5480403, 0x81C, 0xA44A0403,
+ 0x81C, 0xA34C0403, 0x81C, 0x854E0403, 0x81C, 0x84500403,
+ 0x81C, 0x83520403, 0x81C, 0x82540403, 0x81C, 0x81560403,
+ 0x81C, 0x80580403, 0x81C, 0x485A0403, 0x81C, 0x475C0403,
+ 0x81C, 0x465E0403, 0x81C, 0x45600403, 0x81C, 0x44620403,
+ 0x81C, 0x0A640403, 0x81C, 0x09660403, 0x81C, 0x08680403,
+ 0x81C, 0x076A0403, 0x81C, 0x066C0403, 0x81C, 0x056E0403,
+ 0x81C, 0x04700403, 0x81C, 0x03720403, 0x81C, 0x02740403,
+ 0x81C, 0x01760403, 0x81C, 0x00780403, 0x81C, 0x007A0403,
+ 0x81C, 0x007C0403, 0x81C, 0x007E0403, 0x90001004, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xFF000403, 0x81C, 0xF5000403,
+ 0x81C, 0xF4020403, 0x81C, 0xF3040403, 0x81C, 0xF2060403,
+ 0x81C, 0xF1080403, 0x81C, 0xF00A0403, 0x81C, 0xEF0C0403,
+ 0x81C, 0xEE0E0403, 0x81C, 0xED100403, 0x81C, 0xEC120403,
+ 0x81C, 0xEB140403, 0x81C, 0xEA160403, 0x81C, 0xE9180403,
+ 0x81C, 0xE81A0403, 0x81C, 0xE71C0403, 0x81C, 0xE61E0403,
+ 0x81C, 0xE5200403, 0x81C, 0xE4220403, 0x81C, 0xE3240403,
+ 0x81C, 0xE2260403, 0x81C, 0xE1280403, 0x81C, 0xE02A0403,
+ 0x81C, 0xC32C0403, 0x81C, 0xC22E0403, 0x81C, 0xC1300403,
+ 0x81C, 0xC0320403, 0x81C, 0xA4340403, 0x81C, 0xA3360403,
+ 0x81C, 0xA2380403, 0x81C, 0xA13A0403, 0x81C, 0xA03C0403,
+ 0x81C, 0x823E0403, 0x81C, 0x81400403, 0x81C, 0x80420403,
+ 0x81C, 0x64440403, 0x81C, 0x63460403, 0x81C, 0x62480403,
+ 0x81C, 0x614A0403, 0x81C, 0x604C0403, 0x81C, 0x454E0403,
+ 0x81C, 0x44500403, 0x81C, 0x43520403, 0x81C, 0x42540403,
+ 0x81C, 0x41560403, 0x81C, 0x40580403, 0x81C, 0x055A0403,
+ 0x81C, 0x045C0403, 0x81C, 0x035E0403, 0x81C, 0x02600403,
+ 0x81C, 0x01620403, 0x81C, 0x00640403, 0x81C, 0x00660403,
+ 0x81C, 0x00680403, 0x81C, 0x006A0403, 0x81C, 0x006C0403,
+ 0x81C, 0x006E0403, 0x81C, 0x00700403, 0x81C, 0x00720403,
+ 0x81C, 0x00740403, 0x81C, 0x00760403, 0x81C, 0x00780403,
+ 0x81C, 0x007A0403, 0x81C, 0x007C0403, 0x81C, 0x007E0403,
+ 0x90011000, 0x00000000, 0x40000000, 0x00000000, 0x81C, 0xFF000403,
+ 0x81C, 0xFF000403, 0x81C, 0xFF020403, 0x81C, 0xFE040403,
+ 0x81C, 0xFD060403, 0x81C, 0xFC080403, 0x81C, 0xFB0A0403,
+ 0x81C, 0xFA0C0403, 0x81C, 0xF90E0403, 0x81C, 0xF8100403,
+ 0x81C, 0xF7120403, 0x81C, 0xF6140403, 0x81C, 0xF5160403,
+ 0x81C, 0xF4180403, 0x81C, 0xF31A0403, 0x81C, 0xF21C0403,
+ 0x81C, 0xD51E0403, 0x81C, 0xD4200403, 0x81C, 0xD3220403,
+ 0x81C, 0xD2240403, 0x81C, 0xB6260403, 0x81C, 0xB5280403,
+ 0x81C, 0xB42A0403, 0x81C, 0xB32C0403, 0x81C, 0xB22E0403,
+ 0x81C, 0xB1300403, 0x81C, 0xB0320403, 0x81C, 0xAF340403,
+ 0x81C, 0xAE360403, 0x81C, 0xAD380403, 0x81C, 0xAC3A0403,
+ 0x81C, 0xAB3C0403, 0x81C, 0xAA3E0403, 0x81C, 0xA9400403,
+ 0x81C, 0xA8420403, 0x81C, 0xA7440403, 0x81C, 0xA6460403,
+ 0x81C, 0xA5480403, 0x81C, 0xA44A0403, 0x81C, 0xA34C0403,
+ 0x81C, 0x854E0403, 0x81C, 0x84500403, 0x81C, 0x83520403,
+ 0x81C, 0x82540403, 0x81C, 0x81560403, 0x81C, 0x80580403,
+ 0x81C, 0x485A0403, 0x81C, 0x475C0403, 0x81C, 0x465E0403,
+ 0x81C, 0x45600403, 0x81C, 0x44620403, 0x81C, 0x0A640403,
+ 0x81C, 0x09660403, 0x81C, 0x08680403, 0x81C, 0x076A0403,
+ 0x81C, 0x066C0403, 0x81C, 0x056E0403, 0x81C, 0x04700403,
+ 0x81C, 0x03720403, 0x81C, 0x02740403, 0x81C, 0x01760403,
+ 0x81C, 0x00780403, 0x81C, 0x007A0403, 0x81C, 0x007C0403,
+ 0x81C, 0x007E0403, 0x90002100, 0x00000000, 0x40000000, 0x00000000,
+ 0x81C, 0xFF000403, 0x81C, 0xFF000403, 0x81C, 0xFF020403,
+ 0x81C, 0xFE040403, 0x81C, 0xFD060403, 0x81C, 0xFC080403,
+ 0x81C, 0xFB0A0403, 0x81C, 0xFA0C0403, 0x81C, 0xF90E0403,
+ 0x81C, 0xF8100403, 0x81C, 0xF7120403, 0x81C, 0xF6140403,
+ 0x81C, 0xF5160403, 0x81C, 0xF4180403, 0x81C, 0xF31A0403,
+ 0x81C, 0xF21C0403, 0x81C, 0xD51E0403, 0x81C, 0xD4200403,
+ 0x81C, 0xD3220403, 0x81C, 0xD2240403, 0x81C, 0xB6260403,
+ 0x81C, 0xB5280403, 0x81C, 0xB42A0403, 0x81C, 0xB32C0403,
+ 0x81C, 0xB22E0403, 0x81C, 0xB1300403, 0x81C, 0xB0320403,
+ 0x81C, 0xAF340403, 0x81C, 0xAE360403, 0x81C, 0xAD380403,
+ 0x81C, 0xAC3A0403, 0x81C, 0xAB3C0403, 0x81C, 0xAA3E0403,
+ 0x81C, 0xA9400403, 0x81C, 0xA8420403, 0x81C, 0xA7440403,
+ 0x81C, 0xA6460403, 0x81C, 0xA5480403, 0x81C, 0xA44A0403,
+ 0x81C, 0xA34C0403, 0x81C, 0x854E0403, 0x81C, 0x84500403,
+ 0x81C, 0x83520403, 0x81C, 0x82540403, 0x81C, 0x81560403,
+ 0x81C, 0x80580403, 0x81C, 0x485A0403, 0x81C, 0x475C0403,
+ 0x81C, 0x465E0403, 0x81C, 0x45600403, 0x81C, 0x44620403,
+ 0x81C, 0x0A640403, 0x81C, 0x09660403, 0x81C, 0x08680403,
+ 0x81C, 0x076A0403, 0x81C, 0x066C0403, 0x81C, 0x056E0403,
+ 0x81C, 0x04700403, 0x81C, 0x03720403, 0x81C, 0x02740403,
+ 0x81C, 0x01760403, 0x81C, 0x00780403, 0x81C, 0x007A0403,
+ 0x81C, 0x007C0403, 0x81C, 0x007E0403, 0x90002000, 0x00000000,
+ 0x40000000, 0x00000000, 0x81C, 0xFF000403, 0x81C, 0xFF000403,
+ 0x81C, 0xFF020403, 0x81C, 0xFE040403, 0x81C, 0xFD060403,
+ 0x81C, 0xFC080403, 0x81C, 0xFB0A0403, 0x81C, 0xFA0C0403,
+ 0x81C, 0xF90E0403, 0x81C, 0xF8100403, 0x81C, 0xF7120403,
+ 0x81C, 0xF6140403, 0x81C, 0xF5160403, 0x81C, 0xF4180403,
+ 0x81C, 0xF31A0403, 0x81C, 0xF21C0403, 0x81C, 0xD51E0403,
+ 0x81C, 0xD4200403, 0x81C, 0xD3220403, 0x81C, 0xD2240403,
+ 0x81C, 0xB6260403, 0x81C, 0xB5280403, 0x81C, 0xB42A0403,
+ 0x81C, 0xB32C0403, 0x81C, 0xB22E0403, 0x81C, 0xB1300403,
+ 0x81C, 0xB0320403, 0x81C, 0xAF340403, 0x81C, 0xAE360403,
+ 0x81C, 0xAD380403, 0x81C, 0xAC3A0403, 0x81C, 0xAB3C0403,
+ 0x81C, 0xAA3E0403, 0x81C, 0xA9400403, 0x81C, 0xA8420403,
+ 0x81C, 0xA7440403, 0x81C, 0xA6460403, 0x81C, 0xA5480403,
+ 0x81C, 0xA44A0403, 0x81C, 0xA34C0403, 0x81C, 0x854E0403,
+ 0x81C, 0x84500403, 0x81C, 0x83520403, 0x81C, 0x82540403,
+ 0x81C, 0x81560403, 0x81C, 0x80580403, 0x81C, 0x485A0403,
+ 0x81C, 0x475C0403, 0x81C, 0x465E0403, 0x81C, 0x45600403,
+ 0x81C, 0x44620403, 0x81C, 0x0A640403, 0x81C, 0x09660403,
+ 0x81C, 0x08680403, 0x81C, 0x076A0403, 0x81C, 0x066C0403,
+ 0x81C, 0x056E0403, 0x81C, 0x04700403, 0x81C, 0x03720403,
+ 0x81C, 0x02740403, 0x81C, 0x01760403, 0x81C, 0x00780403,
+ 0x81C, 0x007A0403, 0x81C, 0x007C0403, 0x81C, 0x007E0403,
+ 0xA0000000, 0x00000000, 0x81C, 0xFF000403, 0x81C, 0xFF000403,
+ 0x81C, 0xFF020403, 0x81C, 0xFE040403, 0x81C, 0xFD060403,
+ 0x81C, 0xFC080403, 0x81C, 0xFB0A0403, 0x81C, 0xFA0C0403,
+ 0x81C, 0xF90E0403, 0x81C, 0xF8100403, 0x81C, 0xF7120403,
+ 0x81C, 0xF6140403, 0x81C, 0xF5160403, 0x81C, 0xF4180403,
+ 0x81C, 0xF31A0403, 0x81C, 0xF21C0403, 0x81C, 0xD51E0403,
+ 0x81C, 0xD4200403, 0x81C, 0xD3220403, 0x81C, 0xD2240403,
+ 0x81C, 0xB6260403, 0x81C, 0xB5280403, 0x81C, 0xB42A0403,
+ 0x81C, 0xB32C0403, 0x81C, 0xB22E0403, 0x81C, 0xB1300403,
+ 0x81C, 0xB0320403, 0x81C, 0xAF340403, 0x81C, 0xAE360403,
+ 0x81C, 0xAD380403, 0x81C, 0xAC3A0403, 0x81C, 0xAB3C0403,
+ 0x81C, 0xAA3E0403, 0x81C, 0xA9400403, 0x81C, 0xA8420403,
+ 0x81C, 0xA7440403, 0x81C, 0xA6460403, 0x81C, 0xA5480403,
+ 0x81C, 0xA44A0403, 0x81C, 0xA34C0403, 0x81C, 0x854E0403,
+ 0x81C, 0x84500403, 0x81C, 0x83520403, 0x81C, 0x82540403,
+ 0x81C, 0x81560403, 0x81C, 0x80580403, 0x81C, 0x485A0403,
+ 0x81C, 0x475C0403, 0x81C, 0x465E0403, 0x81C, 0x45600403,
+ 0x81C, 0x44620403, 0x81C, 0x0A640403, 0x81C, 0x09660403,
+ 0x81C, 0x08680403, 0x81C, 0x076A0403, 0x81C, 0x066C0403,
+ 0x81C, 0x056E0403, 0x81C, 0x04700403, 0x81C, 0x03720403,
+ 0x81C, 0x02740403, 0x81C, 0x01760403, 0x81C, 0x00780403,
+ 0x81C, 0x007A0403, 0x81C, 0x007C0403, 0x81C, 0x007E0403,
+ 0xB0000000, 0x00000000, 0xC50, 0x00000022, 0xC50, 0x00000020,
+ 0xE50, 0x00000022, 0xE50, 0x00000020,
+
+};
+
+void odm_read_and_config_mp_8822b_agc_tab(struct phy_dm_struct *dm)
+{
+ u32 i = 0;
+ u8 c_cond;
+ bool is_matched = true, is_skipped = false;
+ u32 array_len = sizeof(array_mp_8822b_agc_tab) / sizeof(u32);
+ u32 *array = array_mp_8822b_agc_tab;
+
+ u32 v1 = 0, v2 = 0, pre_v1 = 0, pre_v2 = 0;
+
+ ODM_RT_TRACE(dm, ODM_COMP_INIT,
+ "===> %s\n", __func__);
+
+ for (; (i + 1) < array_len; i = i + 2) {
+ v1 = array[i];
+ v2 = array[i + 1];
+
+ if (v1 & BIT(31)) { /* positive condition*/
+ c_cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28);
+ if (c_cond == COND_ENDIF) { /*end*/
+ is_matched = true;
+ is_skipped = false;
+ ODM_RT_TRACE(dm, ODM_COMP_INIT, "ENDIF\n");
+ } else if (c_cond == COND_ELSE) { /*else*/
+ is_matched = is_skipped ? false : true;
+ ODM_RT_TRACE(dm, ODM_COMP_INIT, "ELSE\n");
+ } else { /*if , else if*/
+ pre_v1 = v1;
+ pre_v2 = v2;
+ ODM_RT_TRACE(dm, ODM_COMP_INIT,
+ "IF or ELSE IF\n");
+ }
+ } else if (v1 & BIT(30)) { /*negative condition*/
+ if (is_skipped) {
+ is_matched = false;
+ continue;
+ }
+
+ if (check_positive(dm, pre_v1, pre_v2, v1, v2)) {
+ is_matched = true;
+ is_skipped = true;
+ } else {
+ is_matched = false;
+ is_skipped = false;
+ }
+ } else if (is_matched) {
+ odm_config_bb_agc_8822b(dm, v1, MASKDWORD, v2);
+ }
+ }
+}
+
+u32 odm_get_version_mp_8822b_agc_tab(void) { return 67; }
+
+/******************************************************************************
+ * phy_reg.TXT
+ ******************************************************************************/
+
+static u32 array_mp_8822b_phy_reg[] = {
+ 0x800, 0x9020D010, 0x804, 0x800181A0, 0x808, 0x0E028233,
+ 0x80C, 0x10000013, 0x810, 0x21101263, 0x814, 0x020C3D10,
+ 0x818, 0x84A10385, 0x81C, 0x1E1E081F, 0x820, 0x0001AAAA,
+ 0x824, 0x00030FE0, 0x828, 0x0000CCCC, 0x82C, 0x75CB7010,
+ 0x830, 0x79A0EA2A, 0x834, 0x072E6986, 0x838, 0x87766441,
+ 0x83C, 0x9194B2B6, 0x840, 0x171740E0, 0x844, 0x4D3D7CDB,
+ 0x848, 0x4AD0408B, 0x84C, 0x6AFBF7A5, 0x850, 0x28A74706,
+ 0x854, 0x0001520C, 0x858, 0x4060C000, 0x85C, 0x74010160,
+ 0x860, 0x68A7C321, 0x864, 0x79F27432, 0x868, 0x8CA7A314,
+ 0x86C, 0x778C2878, 0x870, 0x77777777, 0x874, 0x27612C2E,
+ 0x878, 0xC0003152, 0x87C, 0x5C8FC000, 0x880, 0x00000000,
+ 0x884, 0x00000000, 0x888, 0x00000000, 0x88C, 0x00000000,
+ 0x890, 0x00000000, 0x894, 0x00000000, 0x898, 0x00000000,
+ 0x89C, 0x00000000, 0x8A0, 0x00000013, 0x8A4, 0x7F7F7F7F,
+ 0x8A8, 0x2202033E, 0x8AC, 0xF00F000A, 0x8B0, 0x00000600,
+ 0x8B4, 0x000FC080, 0x8B8, 0xEC0057F7, 0x8BC, 0xACB520A3,
+ 0x8C0, 0xFFE04020, 0x8C4, 0x47C00000, 0x8C8, 0x000251A5,
+ 0x8CC, 0x08108000, 0x8D0, 0x0000B800, 0x8D4, 0x860308A0,
+ 0x8D8, 0x21095612, 0x8DC, 0x00000000, 0x8E0, 0x32D16777,
+ 0x8E4, 0x4C098935, 0x8E8, 0xFFFFC42C, 0x8EC, 0x99999999,
+ 0x8F0, 0x00009999, 0x8F4, 0x00D80FA1, 0x8F8, 0x40000080,
+ 0x8FC, 0x00000130, 0x900, 0x00800000, 0x904, 0x00000000,
+ 0x908, 0x00000000, 0x90C, 0xD3000000, 0x910, 0x0000FC00,
+ 0x914, 0xC6380000, 0x918, 0x1C1028C0, 0x91C, 0x64B11A1C,
+ 0x920, 0xE0767233, 0x924, 0x855A2500, 0x928, 0x4AB0E4E4,
+ 0x92C, 0xFFFEB200, 0x930, 0xFFFFFFFE, 0x934, 0x001FFFFF,
+ 0x938, 0x00008480, 0x93C, 0xE41C0642, 0x940, 0x0E470430,
+ 0x944, 0x00000000, 0x948, 0xAC000000, 0x94C, 0x10000083,
+ 0x950, 0x32010080, 0x954, 0x84510080, 0x958, 0x00000001,
+ 0x95C, 0x04248000, 0x960, 0x00000000, 0x964, 0x00000000,
+ 0x968, 0x00000000, 0x96C, 0x00000000, 0x970, 0x00001FFF,
+ 0x974, 0x44000FFF, 0x978, 0x00000000, 0x97C, 0x00000000,
+ 0x980, 0x00000000, 0x984, 0x00000000, 0x988, 0x00000000,
+ 0x98C, 0x23440000, 0x990, 0x27100000, 0x994, 0xFFFF0100,
+ 0x998, 0xFFFFFF5C, 0x99C, 0xFFFFFFFF, 0x9A0, 0x000000FF,
+ 0x9A4, 0x80000088, 0x9A8, 0x0C2F0000, 0x9AC, 0x01560000,
+ 0x9B0, 0x70000000, 0x9B4, 0x00000000, 0x9B8, 0x00000000,
+ 0x9BC, 0x00000000, 0x9C0, 0x00000000, 0x9C4, 0x00000000,
+ 0x9C8, 0x00000000, 0x9CC, 0x00000000, 0x9D0, 0x00000000,
+ 0x9D4, 0x00000000, 0x9D8, 0x00000000, 0x9DC, 0x00000000,
+ 0x9E0, 0x00000000, 0x9E4, 0x02000402, 0x9E8, 0x000022D4,
+ 0x9EC, 0x00000000, 0x9F0, 0x00010080, 0x9F4, 0x00000000,
+ 0x9F8, 0x00000000, 0x9FC, 0xEFFFF7F7, 0xA00, 0x00D047C8,
+ 0xA04, 0x81FF800C, 0xA08, 0x8C838300, 0xA0C, 0x2E20100F,
+ 0xA10, 0x9500BB78, 0xA14, 0x1114D028, 0xA18, 0x00881117,
+ 0xA1C, 0x89140F00, 0xA20, 0x84880000, 0xA24, 0x384F6577,
+ 0xA28, 0x00001525, 0xA2C, 0x00920000, 0xA70, 0x101FFF00,
+ 0xA74, 0x00000148, 0xA78, 0x00000900, 0xA7C, 0x225B0606,
+ 0xA80, 0x218675B2, 0xA84, 0x80208C00, 0xA88, 0x040C0000,
+ 0xA8C, 0x12345678, 0xA90, 0xABCDEF00, 0xA94, 0x001B1B89,
+ 0xA98, 0x030A0000, 0xA9C, 0x00060000, 0xAA0, 0x00000000,
+ 0xAA4, 0x0004000F, 0xAA8, 0x00000200, 0xB00, 0xE1000440,
+ 0xB04, 0x00800000, 0xB08, 0xFF02030B, 0xB0C, 0x01EAA406,
+ 0xB10, 0x00030690, 0xB14, 0x006000FA, 0xB18, 0x00000002,
+ 0xB1C, 0x00000002, 0xB20, 0x4B00001F, 0xB24, 0x4E8E3E40,
+ 0xB28, 0x03020100, 0xB2C, 0x07060504, 0xB30, 0x0B0A0908,
+ 0xB34, 0x0F0E0D0C, 0xB38, 0x13121110, 0xB3C, 0x0000003A,
+ 0xB40, 0x00000000, 0xB44, 0x80000000, 0xB48, 0x3F0000FA,
+ 0xB4C, 0x88C80020, 0xB50, 0x00000000, 0xB54, 0x00004241,
+ 0xB58, 0xE0008208, 0xB5C, 0x41EFFFF9, 0xB60, 0x00000000,
+ 0xB64, 0x00200063, 0xB68, 0x0000003A, 0xB6C, 0x00000102,
+ 0xB70, 0x4E6D1870, 0xB74, 0x03020100, 0xB78, 0x07060504,
+ 0xB7C, 0x0B0A0908, 0xB80, 0x0F0E0D0C, 0xB84, 0x13121110,
+ 0xB88, 0x00000000, 0xB8C, 0x00000000, 0xC00, 0x00000007,
+ 0xC04, 0x00000020, 0xC08, 0x60403231, 0xC0C, 0x00012345,
+ 0xC10, 0x00000100, 0xC14, 0x01000000, 0xC18, 0x00000000,
+ 0xC1C, 0x40040053, 0xC20, 0x40020103, 0xC24, 0x00000000,
+ 0xC28, 0x00000000, 0xC2C, 0x00000000, 0xC30, 0x00000000,
+ 0xC34, 0x00000000, 0xC38, 0x00000000, 0xC3C, 0x00000000,
+ 0xC40, 0x00000000, 0xC44, 0x00000000, 0xC48, 0x00000000,
+ 0xC4C, 0x00000000, 0xC50, 0x00000020, 0xC54, 0x00000000,
+ 0xC58, 0xD8020402, 0xC5C, 0xDE000120, 0xC68, 0x5979993F,
+ 0xC6C, 0x0000122A, 0xC70, 0x99795979, 0xC74, 0x99795979,
+ 0xC78, 0x99799979, 0xC7C, 0x99791979, 0xC80, 0x19791979,
+ 0xC84, 0x19791979, 0xC88, 0x00000000, 0xC8C, 0x07000000,
+ 0xC94, 0x01000100, 0xC98, 0x201C8000, 0xC9C, 0x00000000,
+ 0xCA0, 0x0000A555, 0xCA4, 0x08040201, 0xCA8, 0x80402010,
+ 0xCAC, 0x00000000, 0xCB0, 0x77777777, 0xCB4, 0x00007777,
+ 0xCB8, 0x00000000, 0xCBC, 0x00000000, 0xCC0, 0x00000000,
+ 0xCC4, 0x00000000, 0xCC8, 0x00000000, 0xCCC, 0x00000000,
+ 0xCD0, 0x00000000, 0xCD4, 0x00000000, 0xCD8, 0x00000000,
+ 0xCDC, 0x00000000, 0xCE0, 0x00000000, 0xCE4, 0x00000000,
+ 0xCE8, 0x00000000, 0xCEC, 0x00000000, 0xE00, 0x00000007,
+ 0xE04, 0x00000020, 0xE08, 0x60403231, 0xE0C, 0x00012345,
+ 0xE10, 0x00000100, 0xE14, 0x01000000, 0xE18, 0x00000000,
+ 0xE1C, 0x40040053, 0xE20, 0x40020103, 0xE24, 0x00000000,
+ 0xE28, 0x00000000, 0xE2C, 0x00000000, 0xE30, 0x00000000,
+ 0xE34, 0x00000000, 0xE38, 0x00000000, 0xE3C, 0x00000000,
+ 0xE40, 0x00000000, 0xE44, 0x00000000, 0xE48, 0x00000000,
+ 0xE4C, 0x00000000, 0xE50, 0x00000020, 0xE54, 0x00000000,
+ 0xE58, 0xD8020402, 0xE5C, 0xDE000120, 0xE68, 0x5979993F,
+ 0xE6C, 0x0000122A, 0xE70, 0x99795979, 0xE74, 0x99795979,
+ 0xE78, 0x99799979, 0xE7C, 0x99791979, 0xE80, 0x19791979,
+ 0xE84, 0x19791979, 0xE88, 0x00000000, 0xE8C, 0x07000000,
+ 0xE94, 0x01000100, 0xE98, 0x201C8000, 0xE9C, 0x00000000,
+ 0xEA0, 0x0000A555, 0xEA4, 0x08040201, 0xEA8, 0x80402010,
+ 0xEAC, 0x00000000, 0xEB0, 0x77777777, 0xEB4, 0x00007777,
+ 0xEB8, 0x00000000, 0xEBC, 0x00000000, 0xEC0, 0x00000000,
+ 0xEC4, 0x00000000, 0xEC8, 0x00000000, 0xECC, 0x00000000,
+ 0xED0, 0x00000000, 0xED4, 0x00000000, 0xED8, 0x00000000,
+ 0xEDC, 0x00000000, 0xEE0, 0x00000000, 0xEE4, 0x00000000,
+ 0xEE8, 0x00000000, 0xEEC, 0x00000000, 0x1900, 0x00000000,
+ 0x1904, 0x00238000, 0x1908, 0x00000000, 0x190C, 0x00000000,
+ 0x1910, 0x00000000, 0x1914, 0x00000000, 0x1918, 0x00000000,
+ 0x191C, 0x00000000, 0x1920, 0x00000000, 0x1924, 0x00000000,
+ 0x1928, 0x00000000, 0x192C, 0x00000000, 0x1930, 0x00000000,
+ 0x1934, 0x00000000, 0x1938, 0x00000000, 0x193C, 0x00000000,
+ 0x1940, 0x00000000, 0x1944, 0x00000000, 0x1948, 0x00000000,
+ 0x194C, 0x00000000, 0x1950, 0x00000000, 0x1954, 0x00000000,
+ 0x1958, 0x00000000, 0x195C, 0x00000000, 0x1960, 0x00000000,
+ 0x1964, 0x00000000, 0x1968, 0x00000000, 0x196C, 0x00000000,
+ 0x1970, 0x00000000, 0x1974, 0x00000000, 0x1978, 0x00000000,
+ 0x197C, 0x00000000, 0x1980, 0x00000000, 0x1984, 0x03000000,
+ 0x1988, 0x21401E88, 0x198C, 0x00004000, 0x1990, 0x00000000,
+ 0x1994, 0x00000000, 0x1998, 0x00000053, 0x199C, 0x00000000,
+ 0x19A0, 0x00000000, 0x19A4, 0x00000000, 0x19A8, 0x00000000,
+ 0x19AC, 0x0E47E47F, 0x19B0, 0x00000000, 0x19B4, 0x0E47E47F,
+ 0x19B8, 0x00000000, 0x19BC, 0x00000000, 0x19C0, 0x00000000,
+ 0x19C4, 0x00000000, 0x19C8, 0x00000000, 0x19CC, 0x00000000,
+ 0x19D0, 0x00000000, 0x19D4, 0xAAAAAAAA, 0x19D8, 0x00000AAA,
+ 0x19DC, 0x133E0F37, 0x19E0, 0x00000000, 0x19E4, 0x00000000,
+ 0x19E8, 0x00000000, 0x19EC, 0x00000000, 0x19F0, 0x00000000,
+ 0x19F4, 0x00000000, 0x19F8, 0x01A00000, 0x19FC, 0x00000000,
+ 0x1C00, 0x00000100, 0x1C04, 0x01000000, 0x1C08, 0x00000100,
+ 0x1C0C, 0x01000000, 0x1C10, 0x00000100, 0x1C14, 0x01000000,
+ 0x1C18, 0x00000100, 0x1C1C, 0x01000000, 0x1C20, 0x00000100,
+ 0x1C24, 0x01000000, 0x1C28, 0x00000100, 0x1C2C, 0x01000000,
+ 0x1C30, 0x00000100, 0x1C34, 0x01000000, 0x1C38, 0x00000000,
+ 0x1C3C, 0x00000000, 0x1C40, 0x000C0100, 0x1C44, 0x000000F3,
+ 0x1C48, 0x1A8249A8, 0x1C4C, 0x1461C826, 0x1C50, 0x0001469E,
+ 0x1C54, 0x58D158D1, 0x1C58, 0x04490088, 0x1C5C, 0x04004400,
+ 0x1C60, 0x00000000, 0x1C64, 0x04004400, 0x1C68, 0x00000100,
+ 0x1C6C, 0x01000000, 0x1C70, 0x00000100, 0x1C74, 0x01000000,
+ 0x1C78, 0x00000000, 0x1C7C, 0x00000010, 0x1C80, 0x5FFF5FFF,
+ 0x1C84, 0x5FFF5FFF, 0x1C88, 0x5FFF5FFF, 0x1C8C, 0x5FFF5FFF,
+ 0x1C90, 0x5FFF5FFF, 0x1C94, 0x5FFF5FFF, 0x1C98, 0x5FFF5FFF,
+ 0x1C9C, 0x5FFF5FFF, 0x1CA0, 0x00000100, 0x1CA4, 0x01000000,
+ 0x1CA8, 0x00000100, 0x1CAC, 0x5FFF5FFF, 0x1CB0, 0x00000100,
+ 0x1CB4, 0x01000000, 0x1CB8, 0x00000000, 0x1CBC, 0x00000000,
+ 0x1CC0, 0x00000100, 0x1CC4, 0x01000000, 0x1CC8, 0x00000100,
+ 0x1CCC, 0x01000000, 0x1CD0, 0x00000100, 0x1CD4, 0x01000000,
+ 0x1CD8, 0x00000100, 0x1CDC, 0x01000000, 0x1CE0, 0x00000100,
+ 0x1CE4, 0x01000000, 0x1CE8, 0x00000100, 0x1CEC, 0x01000000,
+ 0x1CF0, 0x00000100, 0x1CF4, 0x01000000, 0x1CF8, 0x00000000,
+ 0x1CFC, 0x00000000, 0xC60, 0x70038040, 0xC60, 0x70038040,
+ 0xC60, 0x70146040, 0xC60, 0x70246040, 0xC60, 0x70346040,
+ 0xC60, 0x70446040, 0xC60, 0x70532040, 0xC60, 0x70646040,
+ 0xC60, 0x70738040, 0xC60, 0x70838040, 0xC60, 0x70938040,
+ 0xC60, 0x70A38040, 0xC60, 0x70B36040, 0xC60, 0x70C06040,
+ 0xC60, 0x70D06040, 0xC60, 0x70E76040, 0xC60, 0x70F06040,
+ 0xE60, 0x70038040, 0xE60, 0x70038040, 0xE60, 0x70146040,
+ 0xE60, 0x70246040, 0xE60, 0x70346040, 0xE60, 0x70446040,
+ 0xE60, 0x70532040, 0xE60, 0x70646040, 0xE60, 0x70738040,
+ 0xE60, 0x70838040, 0xE60, 0x70938040, 0xE60, 0x70A38040,
+ 0xE60, 0x70B36040, 0xE60, 0x70C06040, 0xE60, 0x70D06040,
+ 0xE60, 0x70E76040, 0xE60, 0x70F06040, 0xC64, 0x00800000,
+ 0xC64, 0x08800001, 0xC64, 0x00800002, 0xC64, 0x00800003,
+ 0xC64, 0x00800004, 0xC64, 0x00800005, 0xC64, 0x00800006,
+ 0xC64, 0x08800007, 0xC64, 0x00004000, 0xE64, 0x00800000,
+ 0xE64, 0x08800001, 0xE64, 0x00800002, 0xE64, 0x00800003,
+ 0xE64, 0x00800004, 0xE64, 0x00800005, 0xE64, 0x00800006,
+ 0xE64, 0x08800007, 0xE64, 0x00004000, 0x1B00, 0xF8000008,
+ 0x1B00, 0xF80A7008, 0x1B00, 0xF8015008, 0x1B00, 0xF8000008,
+ 0x1B04, 0xE24629D2, 0x1B08, 0x00000080, 0x1B0C, 0x00000000,
+ 0x1B10, 0x00010C00, 0x1B14, 0x00000000, 0x1B18, 0x00292903,
+ 0x1B1C, 0xA2193C32, 0x1B20, 0x01840008, 0x1B24, 0x01860008,
+ 0x1B28, 0x80060300, 0x1B2C, 0x00000003, 0x1B30, 0x20000000,
+ 0x1B34, 0x00000800, 0x1B3C, 0x20000000, 0x1BC0, 0x01000000,
+ 0x1BCC, 0x00000000, 0x1B00, 0xF800000A, 0x1B1C, 0xA2193C32,
+ 0x1B20, 0x01840008, 0x1B24, 0x01860008, 0x1B28, 0x80060300,
+ 0x1B2C, 0x00000003, 0x1B30, 0x20000000, 0x1B34, 0x00000800,
+ 0x1B3C, 0x20000000, 0x1BC0, 0x01000000, 0x1BCC, 0x00000000,
+ 0x1B00, 0xF8000000, 0x1B80, 0x00000007, 0x1B80, 0x090A0005,
+ 0x1B80, 0x090A0007, 0x1B80, 0x0FFE0015, 0x1B80, 0x0FFE0017,
+ 0x1B80, 0x00220025, 0x1B80, 0x00220027, 0x1B80, 0x00040035,
+ 0x1B80, 0x00040037, 0x1B80, 0x05C00045, 0x1B80, 0x05C00047,
+ 0x1B80, 0x00070055, 0x1B80, 0x00070057, 0x1B80, 0x64000065,
+ 0x1B80, 0x64000067, 0x1B80, 0x00020075, 0x1B80, 0x00020077,
+ 0x1B80, 0x00080085, 0x1B80, 0x00080087, 0x1B80, 0x80000095,
+ 0x1B80, 0x80000097, 0x1B80, 0x090800A5, 0x1B80, 0x090800A7,
+ 0x1B80, 0x0F0200B5, 0x1B80, 0x0F0200B7, 0x1B80, 0x002200C5,
+ 0x1B80, 0x002200C7, 0x1B80, 0x000400D5, 0x1B80, 0x000400D7,
+ 0x1B80, 0x05C000E5, 0x1B80, 0x05C000E7, 0x1B80, 0x000700F5,
+ 0x1B80, 0x000700F7, 0x1B80, 0x64020105, 0x1B80, 0x64020107,
+ 0x1B80, 0x00020115, 0x1B80, 0x00020117, 0x1B80, 0x00040125,
+ 0x1B80, 0x00040127, 0x1B80, 0x4A000135, 0x1B80, 0x4A000137,
+ 0x1B80, 0x4B040145, 0x1B80, 0x4B040147, 0x1B80, 0x85030155,
+ 0x1B80, 0x85030157, 0x1B80, 0x40090165, 0x1B80, 0x40090167,
+ 0x1B80, 0xE0210175, 0x1B80, 0xE0210177, 0x1B80, 0x4B050185,
+ 0x1B80, 0x4B050187, 0x1B80, 0x86030195, 0x1B80, 0x86030197,
+ 0x1B80, 0x400B01A5, 0x1B80, 0x400B01A7, 0x1B80, 0xE02101B5,
+ 0x1B80, 0xE02101B7, 0x1B80, 0x4B0001C5, 0x1B80, 0x4B0001C7,
+ 0x1B80, 0x000701D5, 0x1B80, 0x000701D7, 0x1B80, 0x4C0001E5,
+ 0x1B80, 0x4C0001E7, 0x1B80, 0x000401F5, 0x1B80, 0x000401F7,
+ 0x1B80, 0x30000205, 0x1B80, 0x30000207, 0x1B80, 0xFE000215,
+ 0x1B80, 0xFE000217, 0x1B80, 0xFF000225, 0x1B80, 0xFF000227,
+ 0x1B80, 0xE1750235, 0x1B80, 0xE1750237, 0x1B80, 0xF00D0245,
+ 0x1B80, 0xF00D0247, 0x1B80, 0xF10D0255, 0x1B80, 0xF10D0257,
+ 0x1B80, 0xF20D0265, 0x1B80, 0xF20D0267, 0x1B80, 0xF30D0275,
+ 0x1B80, 0xF30D0277, 0x1B80, 0xF40D0285, 0x1B80, 0xF40D0287,
+ 0x1B80, 0xF50D0295, 0x1B80, 0xF50D0297, 0x1B80, 0xF60D02A5,
+ 0x1B80, 0xF60D02A7, 0x1B80, 0xF70D02B5, 0x1B80, 0xF70D02B7,
+ 0x1B80, 0xF80D02C5, 0x1B80, 0xF80D02C7, 0x1B80, 0xF90D02D5,
+ 0x1B80, 0xF90D02D7, 0x1B80, 0xFA0D02E5, 0x1B80, 0xFA0D02E7,
+ 0x1B80, 0xFB0D02F5, 0x1B80, 0xFB0D02F7, 0x1B80, 0x00010305,
+ 0x1B80, 0x00010307, 0x1B80, 0x303D0315, 0x1B80, 0x303D0317,
+ 0x1B80, 0x30550325, 0x1B80, 0x30550327, 0x1B80, 0x30A00335,
+ 0x1B80, 0x30A00337, 0x1B80, 0x30A30345, 0x1B80, 0x30A30347,
+ 0x1B80, 0x30570355, 0x1B80, 0x30570357, 0x1B80, 0x30620365,
+ 0x1B80, 0x30620367, 0x1B80, 0x306D0375, 0x1B80, 0x306D0377,
+ 0x1B80, 0x30AD0385, 0x1B80, 0x30AD0387, 0x1B80, 0x30A70395,
+ 0x1B80, 0x30A70397, 0x1B80, 0x30BB03A5, 0x1B80, 0x30BB03A7,
+ 0x1B80, 0x30C603B5, 0x1B80, 0x30C603B7, 0x1B80, 0x30D103C5,
+ 0x1B80, 0x30D103C7, 0x1B80, 0xE11403D5, 0x1B80, 0xE11403D7,
+ 0x1B80, 0x4D0403E5, 0x1B80, 0x4D0403E7, 0x1B80, 0x208003F5,
+ 0x1B80, 0x208003F7, 0x1B80, 0x00000405, 0x1B80, 0x00000407,
+ 0x1B80, 0x4D000415, 0x1B80, 0x4D000417, 0x1B80, 0x55070425,
+ 0x1B80, 0x55070427, 0x1B80, 0xE10C0435, 0x1B80, 0xE10C0437,
+ 0x1B80, 0xE10C0445, 0x1B80, 0xE10C0447, 0x1B80, 0x4D040455,
+ 0x1B80, 0x4D040457, 0x1B80, 0x20880465, 0x1B80, 0x20880467,
+ 0x1B80, 0x02000475, 0x1B80, 0x02000477, 0x1B80, 0x4D000485,
+ 0x1B80, 0x4D000487, 0x1B80, 0x550F0495, 0x1B80, 0x550F0497,
+ 0x1B80, 0xE10C04A5, 0x1B80, 0xE10C04A7, 0x1B80, 0x4F0204B5,
+ 0x1B80, 0x4F0204B7, 0x1B80, 0x4E0004C5, 0x1B80, 0x4E0004C7,
+ 0x1B80, 0x530204D5, 0x1B80, 0x530204D7, 0x1B80, 0x520104E5,
+ 0x1B80, 0x520104E7, 0x1B80, 0xE11004F5, 0x1B80, 0xE11004F7,
+ 0x1B80, 0x4D080505, 0x1B80, 0x4D080507, 0x1B80, 0x57100515,
+ 0x1B80, 0x57100517, 0x1B80, 0x57000525, 0x1B80, 0x57000527,
+ 0x1B80, 0x4D000535, 0x1B80, 0x4D000537, 0x1B80, 0x00010545,
+ 0x1B80, 0x00010547, 0x1B80, 0xE1140555, 0x1B80, 0xE1140557,
+ 0x1B80, 0x00010565, 0x1B80, 0x00010567, 0x1B80, 0x30770575,
+ 0x1B80, 0x30770577, 0x1B80, 0x00230585, 0x1B80, 0x00230587,
+ 0x1B80, 0xE1680595, 0x1B80, 0xE1680597, 0x1B80, 0x000205A5,
+ 0x1B80, 0x000205A7, 0x1B80, 0x54E905B5, 0x1B80, 0x54E905B7,
+ 0x1B80, 0x0BA605C5, 0x1B80, 0x0BA605C7, 0x1B80, 0x002305D5,
+ 0x1B80, 0x002305D7, 0x1B80, 0xE16805E5, 0x1B80, 0xE16805E7,
+ 0x1B80, 0x000205F5, 0x1B80, 0x000205F7, 0x1B80, 0x4D300605,
+ 0x1B80, 0x4D300607, 0x1B80, 0x30900615, 0x1B80, 0x30900617,
+ 0x1B80, 0x30730625, 0x1B80, 0x30730627, 0x1B80, 0x00220635,
+ 0x1B80, 0x00220637, 0x1B80, 0xE1680645, 0x1B80, 0xE1680647,
+ 0x1B80, 0x00020655, 0x1B80, 0x00020657, 0x1B80, 0x54E80665,
+ 0x1B80, 0x54E80667, 0x1B80, 0x0BA60675, 0x1B80, 0x0BA60677,
+ 0x1B80, 0x00220685, 0x1B80, 0x00220687, 0x1B80, 0xE1680695,
+ 0x1B80, 0xE1680697, 0x1B80, 0x000206A5, 0x1B80, 0x000206A7,
+ 0x1B80, 0x4D3006B5, 0x1B80, 0x4D3006B7, 0x1B80, 0x309006C5,
+ 0x1B80, 0x309006C7, 0x1B80, 0x63F106D5, 0x1B80, 0x63F106D7,
+ 0x1B80, 0xE11406E5, 0x1B80, 0xE11406E7, 0x1B80, 0xE16806F5,
+ 0x1B80, 0xE16806F7, 0x1B80, 0x63F40705, 0x1B80, 0x63F40707,
+ 0x1B80, 0xE1140715, 0x1B80, 0xE1140717, 0x1B80, 0xE1680725,
+ 0x1B80, 0xE1680727, 0x1B80, 0x0BA80735, 0x1B80, 0x0BA80737,
+ 0x1B80, 0x63F80745, 0x1B80, 0x63F80747, 0x1B80, 0xE1140755,
+ 0x1B80, 0xE1140757, 0x1B80, 0xE1680765, 0x1B80, 0xE1680767,
+ 0x1B80, 0x0BA90775, 0x1B80, 0x0BA90777, 0x1B80, 0x63FC0785,
+ 0x1B80, 0x63FC0787, 0x1B80, 0xE1140795, 0x1B80, 0xE1140797,
+ 0x1B80, 0xE16807A5, 0x1B80, 0xE16807A7, 0x1B80, 0x63FF07B5,
+ 0x1B80, 0x63FF07B7, 0x1B80, 0xE11407C5, 0x1B80, 0xE11407C7,
+ 0x1B80, 0xE16807D5, 0x1B80, 0xE16807D7, 0x1B80, 0x630007E5,
+ 0x1B80, 0x630007E7, 0x1B80, 0xE11407F5, 0x1B80, 0xE11407F7,
+ 0x1B80, 0xE1680805, 0x1B80, 0xE1680807, 0x1B80, 0x63030815,
+ 0x1B80, 0x63030817, 0x1B80, 0xE1140825, 0x1B80, 0xE1140827,
+ 0x1B80, 0xE1680835, 0x1B80, 0xE1680837, 0x1B80, 0xF4D40845,
+ 0x1B80, 0xF4D40847, 0x1B80, 0x63070855, 0x1B80, 0x63070857,
+ 0x1B80, 0xE1140865, 0x1B80, 0xE1140867, 0x1B80, 0xE1680875,
+ 0x1B80, 0xE1680877, 0x1B80, 0xF5DB0885, 0x1B80, 0xF5DB0887,
+ 0x1B80, 0x630B0895, 0x1B80, 0x630B0897, 0x1B80, 0xE11408A5,
+ 0x1B80, 0xE11408A7, 0x1B80, 0xE16808B5, 0x1B80, 0xE16808B7,
+ 0x1B80, 0x630E08C5, 0x1B80, 0x630E08C7, 0x1B80, 0xE11408D5,
+ 0x1B80, 0xE11408D7, 0x1B80, 0xE16808E5, 0x1B80, 0xE16808E7,
+ 0x1B80, 0x4D3008F5, 0x1B80, 0x4D3008F7, 0x1B80, 0x55010905,
+ 0x1B80, 0x55010907, 0x1B80, 0x57040915, 0x1B80, 0x57040917,
+ 0x1B80, 0x57000925, 0x1B80, 0x57000927, 0x1B80, 0x96000935,
+ 0x1B80, 0x96000937, 0x1B80, 0x57080945, 0x1B80, 0x57080947,
+ 0x1B80, 0x57000955, 0x1B80, 0x57000957, 0x1B80, 0x95000965,
+ 0x1B80, 0x95000967, 0x1B80, 0x4D000975, 0x1B80, 0x4D000977,
+ 0x1B80, 0x6C070985, 0x1B80, 0x6C070987, 0x1B80, 0x7B200995,
+ 0x1B80, 0x7B200997, 0x1B80, 0x7A0009A5, 0x1B80, 0x7A0009A7,
+ 0x1B80, 0x790009B5, 0x1B80, 0x790009B7, 0x1B80, 0x7F2009C5,
+ 0x1B80, 0x7F2009C7, 0x1B80, 0x7E0009D5, 0x1B80, 0x7E0009D7,
+ 0x1B80, 0x7D0009E5, 0x1B80, 0x7D0009E7, 0x1B80, 0x000109F5,
+ 0x1B80, 0x000109F7, 0x1B80, 0x62850A05, 0x1B80, 0x62850A07,
+ 0x1B80, 0xE1140A15, 0x1B80, 0xE1140A17, 0x1B80, 0x00010A25,
+ 0x1B80, 0x00010A27, 0x1B80, 0x5C320A35, 0x1B80, 0x5C320A37,
+ 0x1B80, 0xE1640A45, 0x1B80, 0xE1640A47, 0x1B80, 0xE1420A55,
+ 0x1B80, 0xE1420A57, 0x1B80, 0x00010A65, 0x1B80, 0x00010A67,
+ 0x1B80, 0x5C320A75, 0x1B80, 0x5C320A77, 0x1B80, 0x63F40A85,
+ 0x1B80, 0x63F40A87, 0x1B80, 0x62850A95, 0x1B80, 0x62850A97,
+ 0x1B80, 0x0BB00AA5, 0x1B80, 0x0BB00AA7, 0x1B80, 0xE1140AB5,
+ 0x1B80, 0xE1140AB7, 0x1B80, 0xE1680AC5, 0x1B80, 0xE1680AC7,
+ 0x1B80, 0x5C320AD5, 0x1B80, 0x5C320AD7, 0x1B80, 0x63FC0AE5,
+ 0x1B80, 0x63FC0AE7, 0x1B80, 0x62850AF5, 0x1B80, 0x62850AF7,
+ 0x1B80, 0x0BB10B05, 0x1B80, 0x0BB10B07, 0x1B80, 0xE1140B15,
+ 0x1B80, 0xE1140B17, 0x1B80, 0xE1680B25, 0x1B80, 0xE1680B27,
+ 0x1B80, 0x63030B35, 0x1B80, 0x63030B37, 0x1B80, 0xE1140B45,
+ 0x1B80, 0xE1140B47, 0x1B80, 0xE1680B55, 0x1B80, 0xE1680B57,
+ 0x1B80, 0xF7040B65, 0x1B80, 0xF7040B67, 0x1B80, 0x630B0B75,
+ 0x1B80, 0x630B0B77, 0x1B80, 0xE1140B85, 0x1B80, 0xE1140B87,
+ 0x1B80, 0xE1680B95, 0x1B80, 0xE1680B97, 0x1B80, 0x00010BA5,
+ 0x1B80, 0x00010BA7, 0x1B80, 0x30DF0BB5, 0x1B80, 0x30DF0BB7,
+ 0x1B80, 0x00230BC5, 0x1B80, 0x00230BC7, 0x1B80, 0xE16D0BD5,
+ 0x1B80, 0xE16D0BD7, 0x1B80, 0x00020BE5, 0x1B80, 0x00020BE7,
+ 0x1B80, 0x54E90BF5, 0x1B80, 0x54E90BF7, 0x1B80, 0x0BA60C05,
+ 0x1B80, 0x0BA60C07, 0x1B80, 0x00230C15, 0x1B80, 0x00230C17,
+ 0x1B80, 0xE16D0C25, 0x1B80, 0xE16D0C27, 0x1B80, 0x00020C35,
+ 0x1B80, 0x00020C37, 0x1B80, 0x4D100C45, 0x1B80, 0x4D100C47,
+ 0x1B80, 0x30900C55, 0x1B80, 0x30900C57, 0x1B80, 0x30D90C65,
+ 0x1B80, 0x30D90C67, 0x1B80, 0x00220C75, 0x1B80, 0x00220C77,
+ 0x1B80, 0xE16D0C85, 0x1B80, 0xE16D0C87, 0x1B80, 0x00020C95,
+ 0x1B80, 0x00020C97, 0x1B80, 0x54E80CA5, 0x1B80, 0x54E80CA7,
+ 0x1B80, 0x0BA60CB5, 0x1B80, 0x0BA60CB7, 0x1B80, 0x00220CC5,
+ 0x1B80, 0x00220CC7, 0x1B80, 0xE16D0CD5, 0x1B80, 0xE16D0CD7,
+ 0x1B80, 0x00020CE5, 0x1B80, 0x00020CE7, 0x1B80, 0x4D100CF5,
+ 0x1B80, 0x4D100CF7, 0x1B80, 0x30900D05, 0x1B80, 0x30900D07,
+ 0x1B80, 0x5C320D15, 0x1B80, 0x5C320D17, 0x1B80, 0x54F00D25,
+ 0x1B80, 0x54F00D27, 0x1B80, 0x67F10D35, 0x1B80, 0x67F10D37,
+ 0x1B80, 0xE1420D45, 0x1B80, 0xE1420D47, 0x1B80, 0xE16D0D55,
+ 0x1B80, 0xE16D0D57, 0x1B80, 0x67F40D65, 0x1B80, 0x67F40D67,
+ 0x1B80, 0xE1420D75, 0x1B80, 0xE1420D77, 0x1B80, 0xE16D0D85,
+ 0x1B80, 0xE16D0D87, 0x1B80, 0x5C320D95, 0x1B80, 0x5C320D97,
+ 0x1B80, 0x54F10DA5, 0x1B80, 0x54F10DA7, 0x1B80, 0x0BA80DB5,
+ 0x1B80, 0x0BA80DB7, 0x1B80, 0x67F80DC5, 0x1B80, 0x67F80DC7,
+ 0x1B80, 0xE1420DD5, 0x1B80, 0xE1420DD7, 0x1B80, 0xE16D0DE5,
+ 0x1B80, 0xE16D0DE7, 0x1B80, 0x5C320DF5, 0x1B80, 0x5C320DF7,
+ 0x1B80, 0x54F10E05, 0x1B80, 0x54F10E07, 0x1B80, 0x0BA90E15,
+ 0x1B80, 0x0BA90E17, 0x1B80, 0x67FC0E25, 0x1B80, 0x67FC0E27,
+ 0x1B80, 0xE1420E35, 0x1B80, 0xE1420E37, 0x1B80, 0xE16D0E45,
+ 0x1B80, 0xE16D0E47, 0x1B80, 0x67FF0E55, 0x1B80, 0x67FF0E57,
+ 0x1B80, 0xE1420E65, 0x1B80, 0xE1420E67, 0x1B80, 0xE16D0E75,
+ 0x1B80, 0xE16D0E77, 0x1B80, 0x5C320E85, 0x1B80, 0x5C320E87,
+ 0x1B80, 0x54F20E95, 0x1B80, 0x54F20E97, 0x1B80, 0x67000EA5,
+ 0x1B80, 0x67000EA7, 0x1B80, 0xE1420EB5, 0x1B80, 0xE1420EB7,
+ 0x1B80, 0xE16D0EC5, 0x1B80, 0xE16D0EC7, 0x1B80, 0x67030ED5,
+ 0x1B80, 0x67030ED7, 0x1B80, 0xE1420EE5, 0x1B80, 0xE1420EE7,
+ 0x1B80, 0xE16D0EF5, 0x1B80, 0xE16D0EF7, 0x1B80, 0xF9CC0F05,
+ 0x1B80, 0xF9CC0F07, 0x1B80, 0x67070F15, 0x1B80, 0x67070F17,
+ 0x1B80, 0xE1420F25, 0x1B80, 0xE1420F27, 0x1B80, 0xE16D0F35,
+ 0x1B80, 0xE16D0F37, 0x1B80, 0xFAD30F45, 0x1B80, 0xFAD30F47,
+ 0x1B80, 0x5C320F55, 0x1B80, 0x5C320F57, 0x1B80, 0x54F30F65,
+ 0x1B80, 0x54F30F67, 0x1B80, 0x670B0F75, 0x1B80, 0x670B0F77,
+ 0x1B80, 0xE1420F85, 0x1B80, 0xE1420F87, 0x1B80, 0xE16D0F95,
+ 0x1B80, 0xE16D0F97, 0x1B80, 0x670E0FA5, 0x1B80, 0x670E0FA7,
+ 0x1B80, 0xE1420FB5, 0x1B80, 0xE1420FB7, 0x1B80, 0xE16D0FC5,
+ 0x1B80, 0xE16D0FC7, 0x1B80, 0x4D100FD5, 0x1B80, 0x4D100FD7,
+ 0x1B80, 0x30900FE5, 0x1B80, 0x30900FE7, 0x1B80, 0x00010FF5,
+ 0x1B80, 0x00010FF7, 0x1B80, 0x7B241005, 0x1B80, 0x7B241007,
+ 0x1B80, 0x7A401015, 0x1B80, 0x7A401017, 0x1B80, 0x79001025,
+ 0x1B80, 0x79001027, 0x1B80, 0x55031035, 0x1B80, 0x55031037,
+ 0x1B80, 0x310C1045, 0x1B80, 0x310C1047, 0x1B80, 0x7B1C1055,
+ 0x1B80, 0x7B1C1057, 0x1B80, 0x7A401065, 0x1B80, 0x7A401067,
+ 0x1B80, 0x550B1075, 0x1B80, 0x550B1077, 0x1B80, 0x310C1085,
+ 0x1B80, 0x310C1087, 0x1B80, 0x7B201095, 0x1B80, 0x7B201097,
+ 0x1B80, 0x7A0010A5, 0x1B80, 0x7A0010A7, 0x1B80, 0x551310B5,
+ 0x1B80, 0x551310B7, 0x1B80, 0x740110C5, 0x1B80, 0x740110C7,
+ 0x1B80, 0x740010D5, 0x1B80, 0x740010D7, 0x1B80, 0x8E0010E5,
+ 0x1B80, 0x8E0010E7, 0x1B80, 0x000110F5, 0x1B80, 0x000110F7,
+ 0x1B80, 0x57021105, 0x1B80, 0x57021107, 0x1B80, 0x57001115,
+ 0x1B80, 0x57001117, 0x1B80, 0x97001125, 0x1B80, 0x97001127,
+ 0x1B80, 0x00011135, 0x1B80, 0x00011137, 0x1B80, 0x4F781145,
+ 0x1B80, 0x4F781147, 0x1B80, 0x53881155, 0x1B80, 0x53881157,
+ 0x1B80, 0xE1221165, 0x1B80, 0xE1221167, 0x1B80, 0x54801175,
+ 0x1B80, 0x54801177, 0x1B80, 0x54001185, 0x1B80, 0x54001187,
+ 0x1B80, 0xE1221195, 0x1B80, 0xE1221197, 0x1B80, 0x548111A5,
+ 0x1B80, 0x548111A7, 0x1B80, 0x540011B5, 0x1B80, 0x540011B7,
+ 0x1B80, 0xE12211C5, 0x1B80, 0xE12211C7, 0x1B80, 0x548211D5,
+ 0x1B80, 0x548211D7, 0x1B80, 0x540011E5, 0x1B80, 0x540011E7,
+ 0x1B80, 0xE12D11F5, 0x1B80, 0xE12D11F7, 0x1B80, 0xBF1D1205,
+ 0x1B80, 0xBF1D1207, 0x1B80, 0x301D1215, 0x1B80, 0x301D1217,
+ 0x1B80, 0xE1001225, 0x1B80, 0xE1001227, 0x1B80, 0xE1051235,
+ 0x1B80, 0xE1051237, 0x1B80, 0xE1091245, 0x1B80, 0xE1091247,
+ 0x1B80, 0xE1101255, 0x1B80, 0xE1101257, 0x1B80, 0xE1641265,
+ 0x1B80, 0xE1641267, 0x1B80, 0x55131275, 0x1B80, 0x55131277,
+ 0x1B80, 0xE10C1285, 0x1B80, 0xE10C1287, 0x1B80, 0x55151295,
+ 0x1B80, 0x55151297, 0x1B80, 0xE11012A5, 0x1B80, 0xE11012A7,
+ 0x1B80, 0xE16412B5, 0x1B80, 0xE16412B7, 0x1B80, 0x000112C5,
+ 0x1B80, 0x000112C7, 0x1B80, 0x54BF12D5, 0x1B80, 0x54BF12D7,
+ 0x1B80, 0x54C012E5, 0x1B80, 0x54C012E7, 0x1B80, 0x54A312F5,
+ 0x1B80, 0x54A312F7, 0x1B80, 0x54C11305, 0x1B80, 0x54C11307,
+ 0x1B80, 0x54A41315, 0x1B80, 0x54A41317, 0x1B80, 0x4C181325,
+ 0x1B80, 0x4C181327, 0x1B80, 0xBF071335, 0x1B80, 0xBF071337,
+ 0x1B80, 0x54C21345, 0x1B80, 0x54C21347, 0x1B80, 0x54A41355,
+ 0x1B80, 0x54A41357, 0x1B80, 0xBF041365, 0x1B80, 0xBF041367,
+ 0x1B80, 0x54C11375, 0x1B80, 0x54C11377, 0x1B80, 0x54A31385,
+ 0x1B80, 0x54A31387, 0x1B80, 0xBF011395, 0x1B80, 0xBF011397,
+ 0x1B80, 0xE17213A5, 0x1B80, 0xE17213A7, 0x1B80, 0x54DF13B5,
+ 0x1B80, 0x54DF13B7, 0x1B80, 0x000113C5, 0x1B80, 0x000113C7,
+ 0x1B80, 0x54BF13D5, 0x1B80, 0x54BF13D7, 0x1B80, 0x54E513E5,
+ 0x1B80, 0x54E513E7, 0x1B80, 0x050A13F5, 0x1B80, 0x050A13F7,
+ 0x1B80, 0x54DF1405, 0x1B80, 0x54DF1407, 0x1B80, 0x00011415,
+ 0x1B80, 0x00011417, 0x1B80, 0x7F201425, 0x1B80, 0x7F201427,
+ 0x1B80, 0x7E001435, 0x1B80, 0x7E001437, 0x1B80, 0x7D001445,
+ 0x1B80, 0x7D001447, 0x1B80, 0x55011455, 0x1B80, 0x55011457,
+ 0x1B80, 0x5C311465, 0x1B80, 0x5C311467, 0x1B80, 0xE10C1475,
+ 0x1B80, 0xE10C1477, 0x1B80, 0xE1101485, 0x1B80, 0xE1101487,
+ 0x1B80, 0x54801495, 0x1B80, 0x54801497, 0x1B80, 0x540014A5,
+ 0x1B80, 0x540014A7, 0x1B80, 0xE10C14B5, 0x1B80, 0xE10C14B7,
+ 0x1B80, 0xE11014C5, 0x1B80, 0xE11014C7, 0x1B80, 0x548114D5,
+ 0x1B80, 0x548114D7, 0x1B80, 0x540014E5, 0x1B80, 0x540014E7,
+ 0x1B80, 0xE10C14F5, 0x1B80, 0xE10C14F7, 0x1B80, 0xE1101505,
+ 0x1B80, 0xE1101507, 0x1B80, 0x54821515, 0x1B80, 0x54821517,
+ 0x1B80, 0x54001525, 0x1B80, 0x54001527, 0x1B80, 0xE12D1535,
+ 0x1B80, 0xE12D1537, 0x1B80, 0xBFE91545, 0x1B80, 0xBFE91547,
+ 0x1B80, 0x301D1555, 0x1B80, 0x301D1557, 0x1B80, 0x00231565,
+ 0x1B80, 0x00231567, 0x1B80, 0x7B201575, 0x1B80, 0x7B201577,
+ 0x1B80, 0x7A001585, 0x1B80, 0x7A001587, 0x1B80, 0x79001595,
+ 0x1B80, 0x79001597, 0x1B80, 0xE16815A5, 0x1B80, 0xE16815A7,
+ 0x1B80, 0x000215B5, 0x1B80, 0x000215B7, 0x1B80, 0x000115C5,
+ 0x1B80, 0x000115C7, 0x1B80, 0x002215D5, 0x1B80, 0x002215D7,
+ 0x1B80, 0x7B2015E5, 0x1B80, 0x7B2015E7, 0x1B80, 0x7A0015F5,
+ 0x1B80, 0x7A0015F7, 0x1B80, 0x79001605, 0x1B80, 0x79001607,
+ 0x1B80, 0xE1681615, 0x1B80, 0xE1681617, 0x1B80, 0x00021625,
+ 0x1B80, 0x00021627, 0x1B80, 0x00011635, 0x1B80, 0x00011637,
+ 0x1B80, 0x549F1645, 0x1B80, 0x549F1647, 0x1B80, 0x54FF1655,
+ 0x1B80, 0x54FF1657, 0x1B80, 0x54001665, 0x1B80, 0x54001667,
+ 0x1B80, 0x00011675, 0x1B80, 0x00011677, 0x1B80, 0x5C311685,
+ 0x1B80, 0x5C311687, 0x1B80, 0x07141695, 0x1B80, 0x07141697,
+ 0x1B80, 0x540016A5, 0x1B80, 0x540016A7, 0x1B80, 0x5C3216B5,
+ 0x1B80, 0x5C3216B7, 0x1B80, 0x000116C5, 0x1B80, 0x000116C7,
+ 0x1B80, 0x5C3216D5, 0x1B80, 0x5C3216D7, 0x1B80, 0x071416E5,
+ 0x1B80, 0x071416E7, 0x1B80, 0x540016F5, 0x1B80, 0x540016F7,
+ 0x1B80, 0x5C311705, 0x1B80, 0x5C311707, 0x1B80, 0x00011715,
+ 0x1B80, 0x00011717, 0x1B80, 0x4C981725, 0x1B80, 0x4C981727,
+ 0x1B80, 0x4C181735, 0x1B80, 0x4C181737, 0x1B80, 0x00011745,
+ 0x1B80, 0x00011747, 0x1B80, 0x5C321755, 0x1B80, 0x5C321757,
+ 0x1B80, 0x62841765, 0x1B80, 0x62841767, 0x1B80, 0x66861775,
+ 0x1B80, 0x66861777, 0x1B80, 0x6C031785, 0x1B80, 0x6C031787,
+ 0x1B80, 0x7B201795, 0x1B80, 0x7B201797, 0x1B80, 0x7A0017A5,
+ 0x1B80, 0x7A0017A7, 0x1B80, 0x790017B5, 0x1B80, 0x790017B7,
+ 0x1B80, 0x7F2017C5, 0x1B80, 0x7F2017C7, 0x1B80, 0x7E0017D5,
+ 0x1B80, 0x7E0017D7, 0x1B80, 0x7D0017E5, 0x1B80, 0x7D0017E7,
+ 0x1B80, 0x090117F5, 0x1B80, 0x090117F7, 0x1B80, 0x0C011805,
+ 0x1B80, 0x0C011807, 0x1B80, 0x0BA61815, 0x1B80, 0x0BA61817,
+ 0x1B80, 0x00011825, 0x1B80, 0x00011827, 0x1B80, 0x00000006,
+ 0x1B80, 0x00000002,
+
+};
+
+void odm_read_and_config_mp_8822b_phy_reg(struct phy_dm_struct *dm)
+{
+ u32 i = 0;
+ u8 c_cond;
+ bool is_matched = true, is_skipped = false;
+ u32 array_len = sizeof(array_mp_8822b_phy_reg) / sizeof(u32);
+ u32 *array = array_mp_8822b_phy_reg;
+
+ u32 v1 = 0, v2 = 0, pre_v1 = 0, pre_v2 = 0;
+
+ ODM_RT_TRACE(dm, ODM_COMP_INIT,
+ "===> %s\n", __func__);
+
+ for (; (i + 1) < array_len; i = i + 2) {
+ v1 = array[i];
+ v2 = array[i + 1];
+
+ if (v1 & BIT(31)) { /* positive condition*/
+ c_cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28);
+ if (c_cond == COND_ENDIF) { /*end*/
+ is_matched = true;
+ is_skipped = false;
+ ODM_RT_TRACE(dm, ODM_COMP_INIT, "ENDIF\n");
+ } else if (c_cond == COND_ELSE) { /*else*/
+ is_matched = is_skipped ? false : true;
+ ODM_RT_TRACE(dm, ODM_COMP_INIT, "ELSE\n");
+ } else { /*if , else if*/
+ pre_v1 = v1;
+ pre_v2 = v2;
+ ODM_RT_TRACE(dm, ODM_COMP_INIT,
+ "IF or ELSE IF\n");
+ }
+ } else if (v1 & BIT(30)) { /*negative condition*/
+ if (is_skipped) {
+ is_matched = false;
+ continue;
+ }
+
+ if (check_positive(dm, pre_v1, pre_v2, v1, v2)) {
+ is_matched = true;
+ is_skipped = true;
+ } else {
+ is_matched = false;
+ is_skipped = false;
+ }
+ } else if (is_matched) {
+ odm_config_bb_phy_8822b(dm, v1, MASKDWORD, v2);
+ }
+ }
+}
+
+u32 odm_get_version_mp_8822b_phy_reg(void) { return 67; }
+
+/******************************************************************************
+ * phy_reg_pg.TXT
+ ******************************************************************************/
+
+static u32 array_mp_8822b_phy_reg_pg[] = {
+ 0, 0, 0, 0x00000c20, 0xffffffff, 0x32343638,
+ 0, 0, 0, 0x00000c24, 0xffffffff, 0x36384042,
+ 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303234,
+ 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34363840,
+ 0, 0, 0, 0x00000c30, 0xffffffff, 0x26283032,
+ 0, 0, 1, 0x00000c34, 0xffffffff, 0x34363840,
+ 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283032,
+ 0, 0, 0, 0x00000c3c, 0xffffffff, 0x34363840,
+ 0, 0, 0, 0x00000c40, 0xffffffff, 0x26283032,
+ 0, 0, 0, 0x00000c44, 0xffffffff, 0x38402224,
+ 0, 0, 1, 0x00000c48, 0xffffffff, 0x30323436,
+ 0, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628,
+ 0, 1, 0, 0x00000e20, 0xffffffff, 0x32343638,
+ 0, 1, 0, 0x00000e24, 0xffffffff, 0x36384042,
+ 0, 1, 0, 0x00000e28, 0xffffffff, 0x28303234,
+ 0, 1, 0, 0x00000e2c, 0xffffffff, 0x34363840,
+ 0, 1, 0, 0x00000e30, 0xffffffff, 0x26283032,
+ 0, 1, 1, 0x00000e34, 0xffffffff, 0x34363840,
+ 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283032,
+ 0, 1, 0, 0x00000e3c, 0xffffffff, 0x34363840,
+ 0, 1, 0, 0x00000e40, 0xffffffff, 0x26283032,
+ 0, 1, 0, 0x00000e44, 0xffffffff, 0x38402224,
+ 0, 1, 1, 0x00000e48, 0xffffffff, 0x30323436,
+ 0, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628,
+ 1, 0, 0, 0x00000c24, 0xffffffff, 0x34363840,
+ 1, 0, 0, 0x00000c28, 0xffffffff, 0x26283032,
+ 1, 0, 0, 0x00000c2c, 0xffffffff, 0x32343638,
+ 1, 0, 0, 0x00000c30, 0xffffffff, 0x24262830,
+ 1, 0, 1, 0x00000c34, 0xffffffff, 0x32343638,
+ 1, 0, 1, 0x00000c38, 0xffffffff, 0x24262830,
+ 1, 0, 0, 0x00000c3c, 0xffffffff, 0x32343638,
+ 1, 0, 0, 0x00000c40, 0xffffffff, 0x24262830,
+ 1, 0, 0, 0x00000c44, 0xffffffff, 0x36382022,
+ 1, 0, 1, 0x00000c48, 0xffffffff, 0x28303234,
+ 1, 0, 1, 0x00000c4c, 0xffffffff, 0x20222426,
+ 1, 1, 0, 0x00000e24, 0xffffffff, 0x34363840,
+ 1, 1, 0, 0x00000e28, 0xffffffff, 0x26283032,
+ 1, 1, 0, 0x00000e2c, 0xffffffff, 0x32343638,
+ 1, 1, 0, 0x00000e30, 0xffffffff, 0x24262830,
+ 1, 1, 1, 0x00000e34, 0xffffffff, 0x32343638,
+ 1, 1, 1, 0x00000e38, 0xffffffff, 0x24262830,
+ 1, 1, 0, 0x00000e3c, 0xffffffff, 0x32343638,
+ 1, 1, 0, 0x00000e40, 0xffffffff, 0x24262830,
+ 1, 1, 0, 0x00000e44, 0xffffffff, 0x36382022,
+ 1, 1, 1, 0x00000e48, 0xffffffff, 0x28303234,
+ 1, 1, 1, 0x00000e4c, 0xffffffff, 0x20222426,
+};
+
+void odm_read_and_config_mp_8822b_phy_reg_pg(struct phy_dm_struct *dm)
+{
+ u32 i = 0;
+ u32 array_len = sizeof(array_mp_8822b_phy_reg_pg) / sizeof(u32);
+ u32 *array = array_mp_8822b_phy_reg_pg;
+
+ ODM_RT_TRACE(dm, ODM_COMP_INIT,
+ "===> %s\n", __func__);
+
+ dm->phy_reg_pg_version = 1;
+ dm->phy_reg_pg_value_type = PHY_REG_PG_EXACT_VALUE;
+
+ for (i = 0; i < array_len; i += 6) {
+ u32 v1 = array[i];
+ u32 v2 = array[i + 1];
+ u32 v3 = array[i + 2];
+ u32 v4 = array[i + 3];
+ u32 v5 = array[i + 4];
+ u32 v6 = array[i + 5];
+
+ odm_config_bb_phy_reg_pg_8822b(dm, v1, v2, v3, v4, v5, v6);
+ }
+}
diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_bb.h b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_bb.h
new file mode 100644
index 0000000..5343199
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_bb.h
@@ -0,0 +1,54 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+/*Image2HeaderVersion: 3.2*/
+#ifndef __INC_MP_BB_HW_IMG_8822B_H
+#define __INC_MP_BB_HW_IMG_8822B_H
+
+/******************************************************************************
+ * agc_tab.TXT
+ ******************************************************************************/
+
+void odm_read_and_config_mp_8822b_agc_tab(/* tc: Test Chip, mp: mp Chip*/
+ struct phy_dm_struct *dm);
+u32 odm_get_version_mp_8822b_agc_tab(void);
+
+/******************************************************************************
+ * phy_reg.TXT
+ ******************************************************************************/
+
+void odm_read_and_config_mp_8822b_phy_reg(/* tc: Test Chip, mp: mp Chip*/
+ struct phy_dm_struct *dm);
+u32 odm_get_version_mp_8822b_phy_reg(void);
+
+/******************************************************************************
+ * phy_reg_pg.TXT
+ ******************************************************************************/
+
+void odm_read_and_config_mp_8822b_phy_reg_pg(/* tc: Test Chip, mp: mp Chip*/
+ struct phy_dm_struct *dm);
+u32 odm_get_version_mp_8822b_phy_reg_pg(void);
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_mac.c b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_mac.c
new file mode 100644
index 0000000..1a9daed
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_mac.c
@@ -0,0 +1,222 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+/*Image2HeaderVersion: 3.2*/
+#include "../mp_precomp.h"
+#include "../phydm_precomp.h"
+
+static bool check_positive(struct phy_dm_struct *dm, const u32 condition1,
+ const u32 condition2, const u32 condition3,
+ const u32 condition4)
+{
+ u8 _board_type = ((dm->board_type & BIT(4)) >> 4) << 0 | /* _GLNA*/
+ ((dm->board_type & BIT(3)) >> 3) << 1 | /* _GPA*/
+ ((dm->board_type & BIT(7)) >> 7) << 2 | /* _ALNA*/
+ ((dm->board_type & BIT(6)) >> 6) << 3 | /* _APA */
+ ((dm->board_type & BIT(2)) >> 2) << 4; /* _BT*/
+
+ u32 cond1 = condition1, cond2 = condition2, cond3 = condition3,
+ cond4 = condition4;
+
+ u8 cut_version_for_para =
+ (dm->cut_version == ODM_CUT_A) ? 14 : dm->cut_version;
+ u8 pkg_type_for_para = (dm->package_type == 0) ? 14 : dm->package_type;
+
+ u32 driver1 = cut_version_for_para << 24 |
+ (dm->support_interface & 0xF0) << 16 |
+ dm->support_platform << 16 | pkg_type_for_para << 12 |
+ (dm->support_interface & 0x0F) << 8 | _board_type;
+
+ u32 driver2 = (dm->type_glna & 0xFF) << 0 | (dm->type_gpa & 0xFF) << 8 |
+ (dm->type_alna & 0xFF) << 16 |
+ (dm->type_apa & 0xFF) << 24;
+
+ u32 driver3 = 0;
+
+ u32 driver4 = (dm->type_glna & 0xFF00) >> 8 | (dm->type_gpa & 0xFF00) |
+ (dm->type_alna & 0xFF00) << 8 |
+ (dm->type_apa & 0xFF00) << 16;
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_INIT,
+ "===> %s (cond1, cond2, cond3, cond4) = (0x%X 0x%X 0x%X 0x%X)\n",
+ __func__, cond1, cond2, cond3, cond4);
+ ODM_RT_TRACE(
+ dm, ODM_COMP_INIT,
+ "===> %s (driver1, driver2, driver3, driver4) = (0x%X 0x%X 0x%X 0x%X)\n",
+ __func__, driver1, driver2, driver3, driver4);
+
+ ODM_RT_TRACE(dm, ODM_COMP_INIT,
+ " (Platform, Interface) = (0x%X, 0x%X)\n",
+ dm->support_platform, dm->support_interface);
+ ODM_RT_TRACE(dm, ODM_COMP_INIT,
+ " (Board, Package) = (0x%X, 0x%X)\n",
+ dm->board_type, dm->package_type);
+
+ /*============== value Defined Check ===============*/
+ /*QFN type [15:12] and cut version [27:24] need to do value check*/
+
+ if (((cond1 & 0x0000F000) != 0) &&
+ ((cond1 & 0x0000F000) != (driver1 & 0x0000F000)))
+ return false;
+ if (((cond1 & 0x0F000000) != 0) &&
+ ((cond1 & 0x0F000000) != (driver1 & 0x0F000000)))
+ return false;
+
+ /*=============== Bit Defined Check ================*/
+ /* We don't care [31:28] */
+
+ cond1 &= 0x00FF0FFF;
+ driver1 &= 0x00FF0FFF;
+
+ if ((cond1 & driver1) == cond1) {
+ u32 bit_mask = 0;
+
+ if ((cond1 & 0x0F) == 0) /* board_type is DONTCARE*/
+ return true;
+
+ if ((cond1 & BIT(0)) != 0) /*GLNA*/
+ bit_mask |= 0x000000FF;
+ if ((cond1 & BIT(1)) != 0) /*GPA*/
+ bit_mask |= 0x0000FF00;
+ if ((cond1 & BIT(2)) != 0) /*ALNA*/
+ bit_mask |= 0x00FF0000;
+ if ((cond1 & BIT(3)) != 0) /*APA*/
+ bit_mask |= 0xFF000000;
+
+ if (((cond2 & bit_mask) == (driver2 & bit_mask)) &&
+ ((cond4 & bit_mask) ==
+ (driver4 &
+ bit_mask))) /* board_type of each RF path is matched*/
+ return true;
+ else
+ return false;
+ } else {
+ return false;
+ }
+}
+
+/******************************************************************************
+ * mac_reg.TXT
+ ******************************************************************************/
+
+static u32 array_mp_8822b_mac_reg[] = {
+ 0x029, 0x000000F9, 0x420, 0x00000080, 0x421, 0x0000000F,
+ 0x428, 0x0000000A, 0x429, 0x00000010, 0x430, 0x00000000,
+ 0x431, 0x00000000, 0x432, 0x00000000, 0x433, 0x00000001,
+ 0x434, 0x00000004, 0x435, 0x00000005, 0x436, 0x00000007,
+ 0x437, 0x00000008, 0x43C, 0x00000004, 0x43D, 0x00000005,
+ 0x43E, 0x00000007, 0x43F, 0x00000008, 0x440, 0x0000005D,
+ 0x441, 0x00000001, 0x442, 0x00000000, 0x444, 0x00000010,
+ 0x445, 0x000000F0, 0x446, 0x00000001, 0x447, 0x000000FE,
+ 0x448, 0x00000000, 0x449, 0x00000000, 0x44A, 0x00000000,
+ 0x44B, 0x00000040, 0x44C, 0x00000010, 0x44D, 0x000000F0,
+ 0x44E, 0x0000003F, 0x44F, 0x00000000, 0x450, 0x00000000,
+ 0x451, 0x00000000, 0x452, 0x00000000, 0x453, 0x00000040,
+ 0x455, 0x00000070, 0x45E, 0x00000004, 0x49C, 0x00000010,
+ 0x49D, 0x000000F0, 0x49E, 0x00000000, 0x49F, 0x00000006,
+ 0x4A0, 0x000000E0, 0x4A1, 0x00000003, 0x4A2, 0x00000000,
+ 0x4A3, 0x00000040, 0x4A4, 0x00000015, 0x4A5, 0x000000F0,
+ 0x4A6, 0x00000000, 0x4A7, 0x00000006, 0x4A8, 0x000000E0,
+ 0x4A9, 0x00000000, 0x4AA, 0x00000000, 0x4AB, 0x00000000,
+ 0x7DA, 0x00000008, 0x1448, 0x00000006, 0x144A, 0x00000006,
+ 0x144C, 0x00000006, 0x144E, 0x00000006, 0x4C8, 0x000000FF,
+ 0x4C9, 0x00000008, 0x4CA, 0x00000020, 0x4CB, 0x00000020,
+ 0x4CC, 0x000000FF, 0x4CD, 0x000000FF, 0x4CE, 0x00000001,
+ 0x4CF, 0x00000008, 0x500, 0x00000026, 0x501, 0x000000A2,
+ 0x502, 0x0000002F, 0x503, 0x00000000, 0x504, 0x00000028,
+ 0x505, 0x000000A3, 0x506, 0x0000005E, 0x507, 0x00000000,
+ 0x508, 0x0000002B, 0x509, 0x000000A4, 0x50A, 0x0000005E,
+ 0x50B, 0x00000000, 0x50C, 0x0000004F, 0x50D, 0x000000A4,
+ 0x50E, 0x00000000, 0x50F, 0x00000000, 0x512, 0x0000001C,
+ 0x514, 0x0000000A, 0x516, 0x0000000A, 0x521, 0x0000002F,
+ 0x525, 0x0000004F, 0x551, 0x00000010, 0x559, 0x00000002,
+ 0x55C, 0x00000050, 0x55D, 0x000000FF, 0x577, 0x0000000B,
+ 0x5BE, 0x00000064, 0x605, 0x00000030, 0x608, 0x0000000E,
+ 0x609, 0x00000022, 0x60C, 0x00000018, 0x6A0, 0x000000FF,
+ 0x6A1, 0x000000FF, 0x6A2, 0x000000FF, 0x6A3, 0x000000FF,
+ 0x6A4, 0x000000FF, 0x6A5, 0x000000FF, 0x6DE, 0x00000084,
+ 0x620, 0x000000FF, 0x621, 0x000000FF, 0x622, 0x000000FF,
+ 0x623, 0x000000FF, 0x624, 0x000000FF, 0x625, 0x000000FF,
+ 0x626, 0x000000FF, 0x627, 0x000000FF, 0x638, 0x00000050,
+ 0x63C, 0x0000000A, 0x63D, 0x0000000A, 0x63E, 0x0000000E,
+ 0x63F, 0x0000000E, 0x640, 0x00000040, 0x642, 0x00000040,
+ 0x643, 0x00000000, 0x652, 0x000000C8, 0x66E, 0x00000005,
+ 0x718, 0x00000040, 0x7D4, 0x00000098,
+
+};
+
+void odm_read_and_config_mp_8822b_mac_reg(struct phy_dm_struct *dm)
+{
+ u32 i = 0;
+ u8 c_cond;
+ bool is_matched = true, is_skipped = false;
+ u32 array_len = sizeof(array_mp_8822b_mac_reg) / sizeof(u32);
+ u32 *array = array_mp_8822b_mac_reg;
+
+ u32 v1 = 0, v2 = 0, pre_v1 = 0, pre_v2 = 0;
+
+ ODM_RT_TRACE(dm, ODM_COMP_INIT,
+ "===> %s\n", __func__);
+
+ for (; (i + 1) < array_len; i = i + 2) {
+ v1 = array[i];
+ v2 = array[i + 1];
+
+ if (v1 & BIT(31)) { /* positive condition*/
+ c_cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28);
+ if (c_cond == COND_ENDIF) { /*end*/
+ is_matched = true;
+ is_skipped = false;
+ ODM_RT_TRACE(dm, ODM_COMP_INIT, "ENDIF\n");
+ } else if (c_cond == COND_ELSE) { /*else*/
+ is_matched = is_skipped ? false : true;
+ ODM_RT_TRACE(dm, ODM_COMP_INIT, "ELSE\n");
+ } else { /*if , else if*/
+ pre_v1 = v1;
+ pre_v2 = v2;
+ ODM_RT_TRACE(dm, ODM_COMP_INIT,
+ "IF or ELSE IF\n");
+ }
+ } else if (v1 & BIT(30)) { /*negative condition*/
+ if (is_skipped) {
+ is_matched = false;
+ continue;
+ }
+
+ if (check_positive(dm, pre_v1, pre_v2, v1, v2)) {
+ is_matched = true;
+ is_skipped = true;
+ } else {
+ is_matched = false;
+ is_skipped = false;
+ }
+ } else if (is_matched) {
+ odm_config_mac_8822b(dm, v1, (u8)v2);
+ }
+ }
+}
+
+u32 odm_get_version_mp_8822b_mac_reg(void) { return 67; }
diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_mac.h b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_mac.h
new file mode 100644
index 0000000..d02fdd7
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_mac.h
@@ -0,0 +1,38 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+/*Image2HeaderVersion: 3.2*/
+#ifndef __INC_MP_MAC_HW_IMG_8822B_H
+#define __INC_MP_MAC_HW_IMG_8822B_H
+
+/******************************************************************************
+ * mac_reg.TXT
+ ******************************************************************************/
+
+void odm_read_and_config_mp_8822b_mac_reg(/* tc: Test Chip, mp: mp Chip*/
+ struct phy_dm_struct *dm);
+u32 odm_get_version_mp_8822b_mac_reg(void);
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_rf.c b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_rf.c
new file mode 100644
index 0000000..84cdc06
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_rf.c
@@ -0,0 +1,4744 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+/*Image2HeaderVersion: 3.2*/
+#include "../mp_precomp.h"
+#include "../phydm_precomp.h"
+
+static bool check_positive(struct phy_dm_struct *dm, const u32 condition1,
+ const u32 condition2, const u32 condition3,
+ const u32 condition4)
+{
+ u8 _board_type = ((dm->board_type & BIT(4)) >> 4) << 0 | /* _GLNA*/
+ ((dm->board_type & BIT(3)) >> 3) << 1 | /* _GPA*/
+ ((dm->board_type & BIT(7)) >> 7) << 2 | /* _ALNA*/
+ ((dm->board_type & BIT(6)) >> 6) << 3 | /* _APA */
+ ((dm->board_type & BIT(2)) >> 2) << 4; /* _BT*/
+
+ u32 cond1 = condition1, cond2 = condition2, cond3 = condition3,
+ cond4 = condition4;
+
+ u8 cut_version_for_para =
+ (dm->cut_version == ODM_CUT_A) ? 14 : dm->cut_version;
+ u8 pkg_type_for_para = (dm->package_type == 0) ? 14 : dm->package_type;
+
+ u32 driver1 = cut_version_for_para << 24 |
+ (dm->support_interface & 0xF0) << 16 |
+ dm->support_platform << 16 | pkg_type_for_para << 12 |
+ (dm->support_interface & 0x0F) << 8 | _board_type;
+
+ u32 driver2 = (dm->type_glna & 0xFF) << 0 | (dm->type_gpa & 0xFF) << 8 |
+ (dm->type_alna & 0xFF) << 16 |
+ (dm->type_apa & 0xFF) << 24;
+
+ u32 driver3 = 0;
+
+ u32 driver4 = (dm->type_glna & 0xFF00) >> 8 | (dm->type_gpa & 0xFF00) |
+ (dm->type_alna & 0xFF00) << 8 |
+ (dm->type_apa & 0xFF00) << 16;
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_INIT,
+ "===> %s (cond1, cond2, cond3, cond4) = (0x%X 0x%X 0x%X 0x%X)\n",
+ __func__, cond1, cond2, cond3, cond4);
+ ODM_RT_TRACE(
+ dm, ODM_COMP_INIT,
+ "===> %s (driver1, driver2, driver3, driver4) = (0x%X 0x%X 0x%X 0x%X)\n",
+ __func__, driver1, driver2, driver3, driver4);
+
+ ODM_RT_TRACE(dm, ODM_COMP_INIT,
+ " (Platform, Interface) = (0x%X, 0x%X)\n",
+ dm->support_platform, dm->support_interface);
+ ODM_RT_TRACE(dm, ODM_COMP_INIT,
+ " (Board, Package) = (0x%X, 0x%X)\n",
+ dm->board_type, dm->package_type);
+
+ /*============== value Defined Check ===============*/
+ /*QFN type [15:12] and cut version [27:24] need to do value check*/
+
+ if (((cond1 & 0x0000F000) != 0) &&
+ ((cond1 & 0x0000F000) != (driver1 & 0x0000F000)))
+ return false;
+ if (((cond1 & 0x0F000000) != 0) &&
+ ((cond1 & 0x0F000000) != (driver1 & 0x0F000000)))
+ return false;
+
+ /*=============== Bit Defined Check ================*/
+ /* We don't care [31:28] */
+
+ cond1 &= 0x00FF0FFF;
+ driver1 &= 0x00FF0FFF;
+
+ if ((cond1 & driver1) == cond1) {
+ u32 bit_mask = 0;
+
+ if ((cond1 & 0x0F) == 0) /* board_type is DONTCARE*/
+ return true;
+
+ if ((cond1 & BIT(0)) != 0) /*GLNA*/
+ bit_mask |= 0x000000FF;
+ if ((cond1 & BIT(1)) != 0) /*GPA*/
+ bit_mask |= 0x0000FF00;
+ if ((cond1 & BIT(2)) != 0) /*ALNA*/
+ bit_mask |= 0x00FF0000;
+ if ((cond1 & BIT(3)) != 0) /*APA*/
+ bit_mask |= 0xFF000000;
+
+ if (((cond2 & bit_mask) == (driver2 & bit_mask)) &&
+ ((cond4 & bit_mask) ==
+ (driver4 &
+ bit_mask))) /* board_type of each RF path is matched*/
+ return true;
+ else
+ return false;
+ } else {
+ return false;
+ }
+}
+
+/******************************************************************************
+ * radioa.TXT
+ ******************************************************************************/
+
+static u32 array_mp_8822b_radioa[] = {
+ 0x000, 0x00030000, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x001, 0x0004002D, 0x9300100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x001, 0x0004002D, 0x9300100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x001, 0x0004002D, 0x9300200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x001, 0x0004002D, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x001, 0x0004002D, 0x9000100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x001, 0x0004002D, 0x9000100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x001, 0x0004002D, 0x9000200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x001, 0x0004002D, 0x9300200c, 0x00000000, 0x40000000, 0x00000000,
+ 0x001, 0x00040029, 0x93012100, 0x00000000, 0x40000000, 0x00000000,
+ 0x001, 0x00040029, 0x93002100, 0x00000000, 0x40000000, 0x00000000,
+ 0x001, 0x00040029, 0x9000200c, 0x00000000, 0x40000000, 0x00000000,
+ 0x001, 0x00040029, 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x001, 0x00040029, 0x93002000, 0x00000000, 0x40000000, 0x00000000,
+ 0x001, 0x00040029, 0x90002100, 0x00000000, 0x40000000, 0x00000000,
+ 0x001, 0x00040029, 0x90002000, 0x00000000, 0x40000000, 0x00000000,
+ 0x001, 0x00040029, 0xA0000000, 0x00000000, 0x001, 0x00040029,
+ 0xB0000000, 0x00000000, 0x018, 0x00010D24, 0x0EF, 0x00080000,
+ 0x033, 0x00000002, 0x03E, 0x0000003F, 0x03F, 0x000C0F4E,
+ 0x033, 0x00000001, 0x03E, 0x00000034, 0x03F, 0x0004080E,
+ 0x0EF, 0x00080000, 0x0DF, 0x00002449, 0x033, 0x00000024,
+ 0x03E, 0x0000003F, 0x03F, 0x00060FDE, 0x0EF, 0x00000000,
+ 0x0EF, 0x00080000, 0x033, 0x00000025, 0x03E, 0x00000037,
+ 0x03F, 0x0007EFCE, 0x0EF, 0x00000000, 0x0EF, 0x00080000,
+ 0x033, 0x00000026, 0x03E, 0x00000037, 0x03F, 0x000DEFCE,
+ 0x0EF, 0x00000000, 0x07F, 0x00000000, 0x8300100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x9300100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x9300100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x9300200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0x9000100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x9000100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x9000100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x9000200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0x9300200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0x93012100, 0x00000000,
+ 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0x93002100, 0x00000000,
+ 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0x93011000, 0x00000000,
+ 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x9000200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0x90001004, 0x00000000,
+ 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x93002000, 0x00000000,
+ 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0x93001000, 0x00000000,
+ 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x90002100, 0x00000000,
+ 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0x90002000, 0x00000000,
+ 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0xA0000000, 0x00000000,
+ 0x0B0, 0x000FF0F8, 0xB0000000, 0x00000000, 0x0B1, 0x0007DBE4,
+ 0x0B2, 0x000225D1, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x0B3, 0x000FC760, 0x9300100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x0B3, 0x000FC760, 0x9300100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x0B3, 0x000FC760, 0x9300200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x0B3, 0x000FC760, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x0B3, 0x000FC760, 0x9000100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x0B3, 0x000FC760, 0x9000100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x0B3, 0x000FC760, 0x9000200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x0B3, 0x000FC760, 0x9300200c, 0x00000000, 0x40000000, 0x00000000,
+ 0x0B3, 0x000FC760, 0x93012100, 0x00000000, 0x40000000, 0x00000000,
+ 0x0B3, 0x000FC760, 0x93002100, 0x00000000, 0x40000000, 0x00000000,
+ 0x0B3, 0x0007C330, 0xA0000000, 0x00000000, 0x0B3, 0x000FC760,
+ 0xB0000000, 0x00000000, 0x0B4, 0x00099DD0, 0x0B5, 0x000400FC,
+ 0x0B6, 0x000187F0, 0x0B7, 0x00030018, 0x0B8, 0x00080800,
+ 0x0B9, 0x00000000, 0x0BA, 0x00008000, 0x0BB, 0x00000000,
+ 0x0BC, 0x00040030, 0x0BD, 0x00000000, 0x0BE, 0x00000000,
+ 0x0BF, 0x00000000, 0x0C0, 0x00000000, 0x0C1, 0x00000000,
+ 0x0C2, 0x00000000, 0x0C3, 0x00000000, 0x0C4, 0x00002402,
+ 0x0C5, 0x00000009, 0x0C6, 0x00040299, 0x0C7, 0x00055555,
+ 0x0C8, 0x0000C16C, 0x0C9, 0x0001C140, 0x0CA, 0x00000000,
+ 0x0CB, 0x00000000, 0x0CC, 0x00000000, 0x0CD, 0x00000000,
+ 0x0CE, 0x00090C00, 0x0CF, 0x0006D200, 0x0DF, 0x00000009,
+ 0x018, 0x00010524, 0x089, 0x00000207, 0x8300100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x08A, 0x000FF186, 0x9300100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x08A, 0x000FE186, 0x9300100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x08A, 0x000FF186, 0x9300200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x08A, 0x000FF186, 0x9000100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x08A, 0x000FF186, 0x9000100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x08A, 0x000FE186, 0x9000100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x08A, 0x000FF186, 0x9000200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x08A, 0x000FF186, 0x9300200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x08A, 0x000FF186, 0x93012100, 0x00000000,
+ 0x40000000, 0x00000000, 0x08A, 0x000FF186, 0x93002100, 0x00000000,
+ 0x40000000, 0x00000000, 0x08A, 0x000FE186, 0xA0000000, 0x00000000,
+ 0x08A, 0x000FF186, 0xB0000000, 0x00000000, 0x08B, 0x00061E3C,
+ 0x08C, 0x000112C7, 0x08D, 0x000F4988, 0x08E, 0x00064D40,
+ 0x0EF, 0x00020000, 0x033, 0x00000007, 0x8300100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x03E, 0x00004080, 0x9300100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x93012100, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x93002100, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x93011000, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x9000200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x90001004, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0xA0000000, 0x00000000,
+ 0x03E, 0x00004000, 0xB0000000, 0x00000000, 0x8300100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93012100, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93002100, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000DFF86, 0x93011000, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x90001004, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93002000, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C0006, 0x93001000, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0xA0000000, 0x00000000,
+ 0x03F, 0x000C3186, 0xB0000000, 0x00000000, 0x033, 0x00000006,
+ 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00004080,
+ 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00004080,
+ 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004080,
+ 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004080,
+ 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00004080,
+ 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00004040,
+ 0xA0000000, 0x00000000, 0x03E, 0x00004080, 0xB0000000, 0x00000000,
+ 0x03F, 0x000C3186, 0x033, 0x00000005, 0x8300100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x03E, 0x000040C8, 0x9300100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x03E, 0x000040C8, 0x9300100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x000040C8, 0x9300200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x000040C8, 0x9000100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x03E, 0x000040C8, 0x9000100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x03E, 0x00004084, 0xA0000000, 0x00000000,
+ 0x03E, 0x000040C8, 0xB0000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x033, 0x00000004, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x03E, 0x00004190, 0x9300100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x03E, 0x00004190, 0x9300100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x03E, 0x00004190, 0x9300200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x03E, 0x00004190, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x03E, 0x00004190, 0x9000100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x03E, 0x00004108, 0xA0000000, 0x00000000, 0x03E, 0x00004190,
+ 0xB0000000, 0x00000000, 0x03F, 0x000C3186, 0x033, 0x00000003,
+ 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00004998,
+ 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00004998,
+ 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004998,
+ 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004998,
+ 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00004998,
+ 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x0000490C,
+ 0xA0000000, 0x00000000, 0x03E, 0x00004998, 0xB0000000, 0x00000000,
+ 0x03F, 0x000C3186, 0x033, 0x00000002, 0x8300100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x03E, 0x00005840, 0x9300100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x03E, 0x00005840, 0x9300100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00005840, 0x9300200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00005840, 0x9000100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x03E, 0x00005840, 0x9000100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x03E, 0x00005E00, 0xA0000000, 0x00000000,
+ 0x03E, 0x00005840, 0xB0000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x033, 0x00000001, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x03E, 0x000058C2, 0x9300100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x03E, 0x000058C2, 0x9300100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x03E, 0x000058C2, 0x9300200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x03E, 0x000058C2, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x03E, 0x000058C2, 0x9000100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x03E, 0x00005862, 0xA0000000, 0x00000000, 0x03E, 0x000058C2,
+ 0xB0000000, 0x00000000, 0x03F, 0x000C3186, 0x033, 0x00000000,
+ 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00005930,
+ 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00005930,
+ 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00005930,
+ 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00005930,
+ 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00005930,
+ 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00005948,
+ 0xA0000000, 0x00000000, 0x03E, 0x00005930, 0xB0000000, 0x00000000,
+ 0x03F, 0x000C3186, 0x033, 0x0000000F, 0x8300100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x03E, 0x00004080, 0x9300100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x03E, 0x00004080, 0x9000100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x93012100, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x93002100, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x93011000, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x9000200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x90001004, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0xA0000000, 0x00000000,
+ 0x03E, 0x00004000, 0xB0000000, 0x00000000, 0x8300100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93012100, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000DFF86, 0x93002100, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000DFF86, 0x93011000, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x90001004, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93002000, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C0006, 0x93001000, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0xA0000000, 0x00000000,
+ 0x03F, 0x000C3186, 0xB0000000, 0x00000000, 0x033, 0x0000000E,
+ 0x03E, 0x00004080, 0x03F, 0x000C3186, 0x033, 0x0000000D,
+ 0x03E, 0x000040C8, 0x03F, 0x000C3186, 0x033, 0x0000000C,
+ 0x03E, 0x00004190, 0x03F, 0x000C3186, 0x033, 0x0000000B,
+ 0x03E, 0x00004998, 0x03F, 0x000C3186, 0x033, 0x0000000A,
+ 0x03E, 0x00005840, 0x03F, 0x000C3186, 0x033, 0x00000009,
+ 0x03E, 0x000058C2, 0x03F, 0x000C3186, 0x033, 0x00000008,
+ 0x03E, 0x00005930, 0x03F, 0x000C3186, 0x033, 0x00000017,
+ 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00004040,
+ 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00004080,
+ 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040,
+ 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040,
+ 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00004040,
+ 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00004080,
+ 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040,
+ 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040,
+ 0x9300200c, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040,
+ 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004000,
+ 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004000,
+ 0x93011000, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004000,
+ 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040,
+ 0xA0000000, 0x00000000, 0x03E, 0x00004000, 0xB0000000, 0x00000000,
+ 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x9300200c, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x93011000, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x93002000, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C0006,
+ 0x93001000, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0xA0000000, 0x00000000, 0x03F, 0x000C3186, 0xB0000000, 0x00000000,
+ 0x033, 0x00000016, 0x03E, 0x00004080, 0x03F, 0x000C3186,
+ 0x033, 0x00000015, 0x03E, 0x000040C8, 0x03F, 0x000C3186,
+ 0x033, 0x00000014, 0x03E, 0x00004190, 0x03F, 0x000C3186,
+ 0x033, 0x00000013, 0x03E, 0x00004998, 0x03F, 0x000C3186,
+ 0x033, 0x00000012, 0x03E, 0x00005840, 0x03F, 0x000C3186,
+ 0x033, 0x00000011, 0x03E, 0x000058C2, 0x03F, 0x000C3186,
+ 0x033, 0x00000010, 0x03E, 0x00005930, 0x03F, 0x000C3186,
+ 0x0EF, 0x00000000, 0x0EF, 0x00004000, 0x033, 0x00000000,
+ 0x03F, 0x0000000A, 0x033, 0x00000001, 0x8300100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9300100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9300100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9300200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9000100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9000100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9000100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9000200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9300200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x93012100, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000005, 0x93002100, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000006, 0x93011000, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000005, 0x9000200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x90001004, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x93002000, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x93001000, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000005, 0x90002100, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x90002000, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0xA0000000, 0x00000000,
+ 0x03F, 0x00000005, 0xB0000000, 0x00000000, 0x033, 0x00000002,
+ 0x03F, 0x00000000, 0x0EF, 0x00000000, 0x018, 0x00000401,
+ 0x084, 0x00001209, 0x086, 0x000001A0, 0x8300100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9300100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9300100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9300200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9000100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9000100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9000100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9000200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x087, 0x00068080, 0xA0000000, 0x00000000,
+ 0x087, 0x000E8180, 0xB0000000, 0x00000000, 0x088, 0x00070020,
+ 0x0DE, 0x00000010, 0x0EF, 0x00008000, 0x033, 0x0000000F,
+ 0x03F, 0x0000003C, 0x033, 0x0000000E, 0x03F, 0x00000038,
+ 0x033, 0x0000000D, 0x03F, 0x00000030, 0x033, 0x0000000C,
+ 0x03F, 0x00000028, 0x033, 0x0000000B, 0x03F, 0x00000020,
+ 0x033, 0x0000000A, 0x03F, 0x00000018, 0x033, 0x00000009,
+ 0x03F, 0x00000010, 0x033, 0x00000008, 0x03F, 0x00000008,
+ 0x033, 0x00000007, 0x03F, 0x0000003C, 0x033, 0x00000006,
+ 0x03F, 0x00000038, 0x033, 0x00000005, 0x03F, 0x00000030,
+ 0x033, 0x00000004, 0x03F, 0x00000028, 0x033, 0x00000003,
+ 0x03F, 0x00000020, 0x033, 0x00000002, 0x03F, 0x00000018,
+ 0x033, 0x00000001, 0x03F, 0x00000010, 0x033, 0x00000000,
+ 0x03F, 0x00000008, 0x0EF, 0x00000000, 0x0B8, 0x00080A00,
+ 0x0B0, 0x000FF0FA, 0x0FE, 0x00000000, 0x0CA, 0x00080000,
+ 0x0C9, 0x0001C141, 0x0FE, 0x00000000, 0x0B0, 0x000FF0F8,
+ 0x018, 0x00018D24, 0xFFE, 0x00000000, 0xFFE, 0x00000000,
+ 0xFFE, 0x00000000, 0xFFE, 0x00000000, 0x018, 0x00010D24,
+ 0x01B, 0x00075A40, 0x0EE, 0x00000002, 0x033, 0x00000000,
+ 0x03F, 0x00000004, 0x033, 0x00000001, 0x03F, 0x00000004,
+ 0x033, 0x00000002, 0x03F, 0x00000004, 0x033, 0x00000003,
+ 0x03F, 0x00000004, 0x033, 0x00000004, 0x03F, 0x00000004,
+ 0x033, 0x00000005, 0x03F, 0x00000006, 0x033, 0x00000006,
+ 0x03F, 0x00000002, 0x033, 0x00000007, 0x03F, 0x00000000,
+ 0x0EE, 0x00000000, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x061, 0x0005D4A0, 0x062, 0x0000D203, 0x063, 0x00000062,
+ 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x061, 0x0005D4A0,
+ 0x062, 0x0000D203, 0x063, 0x00000062, 0x9300100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x061, 0x0005D4A0, 0x062, 0x0000D203,
+ 0x063, 0x00000062, 0x9300200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x061, 0x0005D2A1, 0x062, 0x0000D3A2, 0x063, 0x00000062,
+ 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x061, 0x0005D4A0,
+ 0x062, 0x0000D203, 0x063, 0x00000062, 0x9000100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x061, 0x0005D4A0, 0x062, 0x0000D203,
+ 0x063, 0x00000062, 0x9000100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x061, 0x0005D4A0, 0x062, 0x0000D203, 0x063, 0x00000062,
+ 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D2A1,
+ 0x062, 0x0000D3A2, 0x063, 0x00000062, 0x9300200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x061, 0x0005D2A1, 0x062, 0x0000D3A2,
+ 0x063, 0x00000062, 0x93012100, 0x00000000, 0x40000000, 0x00000000,
+ 0x061, 0x0005D301, 0x062, 0x0000D303, 0x063, 0x00000002,
+ 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D301,
+ 0x062, 0x0000D303, 0x063, 0x00000002, 0x93011000, 0x00000000,
+ 0x40000000, 0x00000000, 0x061, 0x0005D3D1, 0x062, 0x0000D3A2,
+ 0x063, 0x00000002, 0x9000200c, 0x00000000, 0x40000000, 0x00000000,
+ 0x061, 0x0005D2A1, 0x062, 0x0000D3A2, 0x063, 0x00000062,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D3D1,
+ 0x062, 0x0000D3A2, 0x063, 0x00000002, 0x93002000, 0x00000000,
+ 0x40000000, 0x00000000, 0x061, 0x0005D301, 0x062, 0x0000D303,
+ 0x063, 0x00000002, 0x93001000, 0x00000000, 0x40000000, 0x00000000,
+ 0x061, 0x0005D3D1, 0x062, 0x0000D3A2, 0x063, 0x00000002,
+ 0x90002100, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D301,
+ 0x062, 0x0000D303, 0x063, 0x00000002, 0x90002000, 0x00000000,
+ 0x40000000, 0x00000000, 0x061, 0x0005D301, 0x062, 0x0000D303,
+ 0x063, 0x00000002, 0xA0000000, 0x00000000, 0x061, 0x0005D3D0,
+ 0x062, 0x0000D303, 0x063, 0x00000002, 0xB0000000, 0x00000000,
+ 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x0EF, 0x00000200,
+ 0x030, 0x000004A3, 0x030, 0x000014A3, 0x030, 0x000024A3,
+ 0x030, 0x000034A3, 0x030, 0x000044A3, 0x030, 0x000054A3,
+ 0x030, 0x000064A3, 0x030, 0x000074A3, 0x030, 0x000084A3,
+ 0x030, 0x000094A3, 0x030, 0x0000A4A3, 0x030, 0x0000B4A3,
+ 0x0EF, 0x00000000, 0x9300100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000200, 0x030, 0x000004A3, 0x030, 0x000014A3,
+ 0x030, 0x000024A3, 0x030, 0x000034A3, 0x030, 0x000044A3,
+ 0x030, 0x000054A3, 0x030, 0x000064A3, 0x030, 0x000074A3,
+ 0x030, 0x000084A3, 0x030, 0x000094A3, 0x030, 0x0000A4A3,
+ 0x030, 0x0000B4A3, 0x0EF, 0x00000000, 0x9300100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x0EF, 0x00000200, 0x030, 0x000004A3,
+ 0x030, 0x000014A3, 0x030, 0x000024A3, 0x030, 0x000034A3,
+ 0x030, 0x000044A3, 0x030, 0x000054A3, 0x030, 0x000064A3,
+ 0x030, 0x000074A3, 0x030, 0x000084A3, 0x030, 0x000094A3,
+ 0x030, 0x0000A4A3, 0x030, 0x0000B4A3, 0x0EF, 0x00000000,
+ 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x0EF, 0x00000200,
+ 0x030, 0x000002A6, 0x030, 0x000012A6, 0x030, 0x000022A6,
+ 0x030, 0x000032A6, 0x030, 0x000042A6, 0x030, 0x000052A6,
+ 0x030, 0x000062A6, 0x030, 0x000072A6, 0x030, 0x000082A6,
+ 0x030, 0x000092A6, 0x030, 0x0000A2A6, 0x030, 0x0000B2A6,
+ 0x0EF, 0x00000000, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000200, 0x030, 0x000004A0, 0x030, 0x000014A0,
+ 0x030, 0x000024A0, 0x030, 0x000034A0, 0x030, 0x000044A0,
+ 0x030, 0x000054A0, 0x030, 0x000064A0, 0x030, 0x000074A0,
+ 0x030, 0x000084A0, 0x030, 0x000094A0, 0x030, 0x0000A4A0,
+ 0x030, 0x0000B4A0, 0x0EF, 0x00000000, 0x9000100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x0EF, 0x00000200, 0x030, 0x000004A0,
+ 0x030, 0x000014A0, 0x030, 0x000024A0, 0x030, 0x000034A0,
+ 0x030, 0x000044A0, 0x030, 0x000054A0, 0x030, 0x000064A0,
+ 0x030, 0x000074A0, 0x030, 0x000084A0, 0x030, 0x000094A0,
+ 0x030, 0x0000A4A0, 0x030, 0x0000B4A0, 0x0EF, 0x00000000,
+ 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x0EF, 0x00000200,
+ 0x030, 0x000004A0, 0x030, 0x000014A0, 0x030, 0x000024A0,
+ 0x030, 0x000034A0, 0x030, 0x000044A0, 0x030, 0x000054A0,
+ 0x030, 0x000064A0, 0x030, 0x000074A0, 0x030, 0x000084A0,
+ 0x030, 0x000094A0, 0x030, 0x0000A4A0, 0x030, 0x0000B4A0,
+ 0x0EF, 0x00000000, 0x9000200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000200, 0x030, 0x000002A1, 0x030, 0x000012A1,
+ 0x030, 0x000022A1, 0x030, 0x000032A1, 0x030, 0x000042A1,
+ 0x030, 0x000052A1, 0x030, 0x000062A1, 0x030, 0x000072A1,
+ 0x030, 0x000082A1, 0x030, 0x000092A1, 0x030, 0x0000A2A1,
+ 0x030, 0x0000B2A1, 0x0EF, 0x00000000, 0x9300200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x0EF, 0x00000200, 0x030, 0x000002A6,
+ 0x030, 0x000012A6, 0x030, 0x000022A6, 0x030, 0x000032A6,
+ 0x030, 0x000042A6, 0x030, 0x000052A6, 0x030, 0x000062A6,
+ 0x030, 0x000072A6, 0x030, 0x000082A6, 0x030, 0x000092A6,
+ 0x030, 0x0000A2A6, 0x030, 0x0000B2A6, 0x0EF, 0x00000000,
+ 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x0EF, 0x00000200,
+ 0x030, 0x00000384, 0x030, 0x00001384, 0x030, 0x00002384,
+ 0x030, 0x00003384, 0x030, 0x00004425, 0x030, 0x00005425,
+ 0x030, 0x00006425, 0x030, 0x00007425, 0x030, 0x000083A4,
+ 0x030, 0x000093A4, 0x030, 0x0000A3A4, 0x030, 0x0000B3A4,
+ 0x0EF, 0x00000000, 0x93002100, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000200, 0x030, 0x000003A3, 0x030, 0x000013A3,
+ 0x030, 0x000023A3, 0x030, 0x000033A3, 0x030, 0x00004355,
+ 0x030, 0x00005355, 0x030, 0x00006355, 0x030, 0x00007355,
+ 0x030, 0x00008314, 0x030, 0x00009314, 0x030, 0x0000A314,
+ 0x030, 0x0000B314, 0x0EF, 0x00000000, 0x93011000, 0x00000000,
+ 0x40000000, 0x00000000, 0x0EF, 0x00000200, 0x030, 0x000003A1,
+ 0x030, 0x000013A1, 0x030, 0x000023A1, 0x030, 0x000033A1,
+ 0x030, 0x000043A3, 0x030, 0x000053A3, 0x030, 0x000063A3,
+ 0x030, 0x000073A3, 0x030, 0x000083A5, 0x030, 0x000093A5,
+ 0x030, 0x0000A3A5, 0x030, 0x0000B3A5, 0x0EF, 0x00000000,
+ 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x0EF, 0x00000200,
+ 0x030, 0x000002A1, 0x030, 0x000012A1, 0x030, 0x000022A1,
+ 0x030, 0x000032A1, 0x030, 0x000042A1, 0x030, 0x000052A1,
+ 0x030, 0x000062A1, 0x030, 0x000072A1, 0x030, 0x000082A1,
+ 0x030, 0x000092A1, 0x030, 0x0000A2A1, 0x030, 0x0000B2A1,
+ 0x0EF, 0x00000000, 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000200, 0x030, 0x00000463, 0x030, 0x00001463,
+ 0x030, 0x00002463, 0x030, 0x00003463, 0x030, 0x00004545,
+ 0x030, 0x00005545, 0x030, 0x00006545, 0x030, 0x00007545,
+ 0x030, 0x00008565, 0x030, 0x00009565, 0x030, 0x0000A565,
+ 0x030, 0x0000B565, 0x0EF, 0x00000000, 0x93002000, 0x00000000,
+ 0x40000000, 0x00000000, 0x0EF, 0x00000200, 0x030, 0x00000303,
+ 0x030, 0x00001303, 0x030, 0x00002303, 0x030, 0x00003303,
+ 0x030, 0x000043A4, 0x030, 0x000053A4, 0x030, 0x000063A4,
+ 0x030, 0x000073A4, 0x030, 0x00008365, 0x030, 0x00009365,
+ 0x030, 0x0000A365, 0x030, 0x0000B365, 0x0EF, 0x00000000,
+ 0x93001000, 0x00000000, 0x40000000, 0x00000000, 0x0EF, 0x00000200,
+ 0x030, 0x000003A2, 0x030, 0x000013A2, 0x030, 0x000023A2,
+ 0x030, 0x000033A2, 0x030, 0x00004343, 0x030, 0x00005343,
+ 0x030, 0x00006343, 0x030, 0x00007343, 0x030, 0x00008364,
+ 0x030, 0x00009364, 0x030, 0x0000A364, 0x030, 0x0000B364,
+ 0x0EF, 0x00000000, 0x90002100, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000200, 0x030, 0x000003A0, 0x030, 0x000013A0,
+ 0x030, 0x000023A0, 0x030, 0x000033A0, 0x030, 0x00004430,
+ 0x030, 0x00005430, 0x030, 0x00006430, 0x030, 0x00007430,
+ 0x030, 0x00008372, 0x030, 0x00009372, 0x030, 0x0000A372,
+ 0x030, 0x0000B372, 0x0EF, 0x00000000, 0x90002000, 0x00000000,
+ 0x40000000, 0x00000000, 0x0EF, 0x00000200, 0x030, 0x000003A0,
+ 0x030, 0x000013A0, 0x030, 0x000023A0, 0x030, 0x000033A0,
+ 0x030, 0x000043A1, 0x030, 0x000053A1, 0x030, 0x000063A1,
+ 0x030, 0x000073A1, 0x030, 0x000083A2, 0x030, 0x000093A2,
+ 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, 0x0EF, 0x00000000,
+ 0xA0000000, 0x00000000, 0x0EF, 0x00000200, 0x030, 0x000003D0,
+ 0x030, 0x000013D0, 0x030, 0x000023D0, 0x030, 0x000033D0,
+ 0x030, 0x000043D0, 0x030, 0x000053D0, 0x030, 0x000063D0,
+ 0x030, 0x000073D0, 0x030, 0x000083D0, 0x030, 0x000093D0,
+ 0x030, 0x0000A3D0, 0x030, 0x0000B3D0, 0x0EF, 0x00000000,
+ 0xB0000000, 0x00000000, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000080, 0x030, 0x00000203, 0x030, 0x00001203,
+ 0x030, 0x00002203, 0x030, 0x00003203, 0x030, 0x00004203,
+ 0x030, 0x00005203, 0x030, 0x00006203, 0x030, 0x00007203,
+ 0x030, 0x00008203, 0x030, 0x00009203, 0x030, 0x0000A203,
+ 0x030, 0x0000B203, 0x9300100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000080, 0x030, 0x00000203, 0x030, 0x00001203,
+ 0x030, 0x00002203, 0x030, 0x00003203, 0x030, 0x00004203,
+ 0x030, 0x00005203, 0x030, 0x00006203, 0x030, 0x00007203,
+ 0x030, 0x00008203, 0x030, 0x00009203, 0x030, 0x0000A203,
+ 0x030, 0x0000B203, 0x9300100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000080, 0x030, 0x00000203, 0x030, 0x00001203,
+ 0x030, 0x00002203, 0x030, 0x00003203, 0x030, 0x00004203,
+ 0x030, 0x00005203, 0x030, 0x00006203, 0x030, 0x00007203,
+ 0x030, 0x00008203, 0x030, 0x00009203, 0x030, 0x0000A203,
+ 0x030, 0x0000B203, 0x9300200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2,
+ 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2,
+ 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2,
+ 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2,
+ 0x030, 0x0000B3A2, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000080, 0x030, 0x00000203, 0x030, 0x00001203,
+ 0x030, 0x00002203, 0x030, 0x00003203, 0x030, 0x00004203,
+ 0x030, 0x00005203, 0x030, 0x00006203, 0x030, 0x00007203,
+ 0x030, 0x00008203, 0x030, 0x00009203, 0x030, 0x0000A203,
+ 0x030, 0x0000B203, 0x9000100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000080, 0x030, 0x00000203, 0x030, 0x00001203,
+ 0x030, 0x00002203, 0x030, 0x00003203, 0x030, 0x00004203,
+ 0x030, 0x00005203, 0x030, 0x00006203, 0x030, 0x00007203,
+ 0x030, 0x00008203, 0x030, 0x00009203, 0x030, 0x0000A203,
+ 0x030, 0x0000B203, 0x9000100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000080, 0x030, 0x00000203, 0x030, 0x00001203,
+ 0x030, 0x00002203, 0x030, 0x00003203, 0x030, 0x00004203,
+ 0x030, 0x00005203, 0x030, 0x00006203, 0x030, 0x00007203,
+ 0x030, 0x00008203, 0x030, 0x00009203, 0x030, 0x0000A203,
+ 0x030, 0x0000B203, 0x9000200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2,
+ 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2,
+ 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2,
+ 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2,
+ 0x030, 0x0000B3A2, 0x9300200c, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2,
+ 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2,
+ 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2,
+ 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2,
+ 0x030, 0x0000B3A2, 0x93012100, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000080, 0x030, 0x000003A3, 0x030, 0x000013A3,
+ 0x030, 0x000023A3, 0x030, 0x000033A3, 0x030, 0x000043A3,
+ 0x030, 0x000053A3, 0x030, 0x000063A3, 0x030, 0x000073A3,
+ 0x030, 0x000083A3, 0x030, 0x000093A3, 0x030, 0x0000A3A3,
+ 0x030, 0x0000B3A3, 0x93002100, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2,
+ 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2,
+ 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2,
+ 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2,
+ 0x030, 0x0000B3A2, 0x93011000, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2,
+ 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2,
+ 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2,
+ 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2,
+ 0x030, 0x0000B3A2, 0x9000200c, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2,
+ 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2,
+ 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2,
+ 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2,
+ 0x030, 0x0000B3A2, 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2,
+ 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2,
+ 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2,
+ 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2,
+ 0x030, 0x0000B3A2, 0x93002000, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2,
+ 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2,
+ 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2,
+ 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2,
+ 0x030, 0x0000B3A2, 0x93001000, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2,
+ 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2,
+ 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2,
+ 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2,
+ 0x030, 0x0000B3A2, 0x90002100, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2,
+ 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2,
+ 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2,
+ 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2,
+ 0x030, 0x0000B3A2, 0x90002000, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2,
+ 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2,
+ 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2,
+ 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2,
+ 0x030, 0x0000B3A2, 0xA0000000, 0x00000000, 0x0EF, 0x00000080,
+ 0x030, 0x000003A2, 0x030, 0x000013A2, 0x030, 0x000023A2,
+ 0x030, 0x000033A2, 0x030, 0x000043A2, 0x030, 0x000053A2,
+ 0x030, 0x000063A2, 0x030, 0x000073A2, 0x030, 0x000083A2,
+ 0x030, 0x000093A2, 0x030, 0x0000A3A2, 0x030, 0x0000B3A2,
+ 0xB0000000, 0x00000000, 0x0EF, 0x00000000, 0x8300100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645,
+ 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000,
+ 0x030, 0x00005000, 0x030, 0x00006000, 0x9300100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645,
+ 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000,
+ 0x030, 0x00005000, 0x030, 0x00006000, 0x9300100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645,
+ 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000,
+ 0x030, 0x00005000, 0x030, 0x00006000, 0x9300200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645,
+ 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004777,
+ 0x030, 0x00005777, 0x030, 0x00006777, 0x9000100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645,
+ 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000,
+ 0x030, 0x00005000, 0x030, 0x00006000, 0x9000100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645,
+ 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000,
+ 0x030, 0x00005000, 0x030, 0x00006000, 0x9000100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645,
+ 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000,
+ 0x030, 0x00005000, 0x030, 0x00006000, 0x9000200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645,
+ 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000,
+ 0x030, 0x00005000, 0x030, 0x00006000, 0x9300200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645,
+ 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004777,
+ 0x030, 0x00005777, 0x030, 0x00006777, 0x93012100, 0x00000000,
+ 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000660,
+ 0x030, 0x00001443, 0x030, 0x00002221, 0x030, 0x00004777,
+ 0x030, 0x00005777, 0x030, 0x00006777, 0x93002100, 0x00000000,
+ 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000776,
+ 0x030, 0x00001455, 0x030, 0x00002325, 0x030, 0x00004777,
+ 0x030, 0x00005777, 0x030, 0x00006777, 0x93011000, 0x00000000,
+ 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000764,
+ 0x030, 0x00001632, 0x030, 0x00002421, 0x030, 0x00004000,
+ 0x030, 0x00005000, 0x030, 0x00006000, 0x9000200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645,
+ 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000,
+ 0x030, 0x00005000, 0x030, 0x00006000, 0x90001004, 0x00000000,
+ 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000764,
+ 0x030, 0x00001632, 0x030, 0x00002421, 0x030, 0x00004000,
+ 0x030, 0x00005000, 0x030, 0x00006000, 0x93002000, 0x00000000,
+ 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000777,
+ 0x030, 0x00001442, 0x030, 0x00002222, 0x030, 0x00004777,
+ 0x030, 0x00005777, 0x030, 0x00006777, 0x93001000, 0x00000000,
+ 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000764,
+ 0x030, 0x00001632, 0x030, 0x00002421, 0x030, 0x00004000,
+ 0x030, 0x00005000, 0x030, 0x00006000, 0x90002100, 0x00000000,
+ 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000775,
+ 0x030, 0x00001343, 0x030, 0x00002210, 0x030, 0x00004000,
+ 0x030, 0x00005000, 0x030, 0x00006000, 0x90002000, 0x00000000,
+ 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000775,
+ 0x030, 0x00001422, 0x030, 0x00002210, 0x030, 0x00004000,
+ 0x030, 0x00005000, 0x030, 0x00006000, 0xA0000000, 0x00000000,
+ 0x0EF, 0x00000040, 0x030, 0x00000764, 0x030, 0x00001632,
+ 0x030, 0x00002421, 0x030, 0x00004000, 0x030, 0x00005000,
+ 0x030, 0x00006000, 0xB0000000, 0x00000000, 0x0EF, 0x00000000,
+ 0x0EF, 0x00000800, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x033, 0x00000020, 0x03F, 0x00000007, 0x033, 0x00000021,
+ 0x03F, 0x0000000A, 0x033, 0x00000022, 0x03F, 0x0000000D,
+ 0x033, 0x00000023, 0x03F, 0x0000002A, 0x033, 0x00000024,
+ 0x03F, 0x0000002D, 0x033, 0x00000025, 0x03F, 0x00000030,
+ 0x033, 0x00000026, 0x03F, 0x0000006D, 0x033, 0x00000027,
+ 0x03F, 0x00000070, 0x033, 0x00000028, 0x03F, 0x000000ED,
+ 0x033, 0x00000029, 0x03F, 0x000000F0, 0x033, 0x0000002A,
+ 0x03F, 0x000000F3, 0x9300100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x033, 0x00000020, 0x03F, 0x00000007, 0x033, 0x00000021,
+ 0x03F, 0x0000000A, 0x033, 0x00000022, 0x03F, 0x0000000D,
+ 0x033, 0x00000023, 0x03F, 0x0000002A, 0x033, 0x00000024,
+ 0x03F, 0x0000002D, 0x033, 0x00000025, 0x03F, 0x00000030,
+ 0x033, 0x00000026, 0x03F, 0x0000006D, 0x033, 0x00000027,
+ 0x03F, 0x00000070, 0x033, 0x00000028, 0x03F, 0x000000ED,
+ 0x033, 0x00000029, 0x03F, 0x000000F0, 0x033, 0x0000002A,
+ 0x03F, 0x000000F3, 0x9300100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000020, 0x03F, 0x00000007, 0x033, 0x00000021,
+ 0x03F, 0x0000000A, 0x033, 0x00000022, 0x03F, 0x0000000D,
+ 0x033, 0x00000023, 0x03F, 0x0000002A, 0x033, 0x00000024,
+ 0x03F, 0x0000002D, 0x033, 0x00000025, 0x03F, 0x00000030,
+ 0x033, 0x00000026, 0x03F, 0x0000006D, 0x033, 0x00000027,
+ 0x03F, 0x00000070, 0x033, 0x00000028, 0x03F, 0x000000ED,
+ 0x033, 0x00000029, 0x03F, 0x000000F0, 0x033, 0x0000002A,
+ 0x03F, 0x000000F3, 0x9300200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000020, 0x03F, 0x00000005, 0x033, 0x00000021,
+ 0x03F, 0x00000008, 0x033, 0x00000022, 0x03F, 0x0000000B,
+ 0x033, 0x00000023, 0x03F, 0x0000000E, 0x033, 0x00000024,
+ 0x03F, 0x0000002B, 0x033, 0x00000025, 0x03F, 0x00000068,
+ 0x033, 0x00000026, 0x03F, 0x0000006B, 0x033, 0x00000027,
+ 0x03F, 0x0000006E, 0x033, 0x00000028, 0x03F, 0x00000071,
+ 0x033, 0x00000029, 0x03F, 0x00000074, 0x033, 0x0000002A,
+ 0x03F, 0x00000077, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x033, 0x00000020, 0x03F, 0x00000007, 0x033, 0x00000021,
+ 0x03F, 0x0000000A, 0x033, 0x00000022, 0x03F, 0x0000000D,
+ 0x033, 0x00000023, 0x03F, 0x0000002A, 0x033, 0x00000024,
+ 0x03F, 0x0000002D, 0x033, 0x00000025, 0x03F, 0x00000030,
+ 0x033, 0x00000026, 0x03F, 0x0000006D, 0x033, 0x00000027,
+ 0x03F, 0x00000070, 0x033, 0x00000028, 0x03F, 0x000000ED,
+ 0x033, 0x00000029, 0x03F, 0x000000F0, 0x033, 0x0000002A,
+ 0x03F, 0x000000F3, 0x9000100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x033, 0x00000020, 0x03F, 0x00000007, 0x033, 0x00000021,
+ 0x03F, 0x0000000A, 0x033, 0x00000022, 0x03F, 0x0000000D,
+ 0x033, 0x00000023, 0x03F, 0x0000002A, 0x033, 0x00000024,
+ 0x03F, 0x0000002D, 0x033, 0x00000025, 0x03F, 0x00000030,
+ 0x033, 0x00000026, 0x03F, 0x0000006D, 0x033, 0x00000027,
+ 0x03F, 0x00000070, 0x033, 0x00000028, 0x03F, 0x000000ED,
+ 0x033, 0x00000029, 0x03F, 0x000000F0, 0x033, 0x0000002A,
+ 0x03F, 0x000000F3, 0x9000100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000020, 0x03F, 0x00000007, 0x033, 0x00000021,
+ 0x03F, 0x0000000A, 0x033, 0x00000022, 0x03F, 0x0000000D,
+ 0x033, 0x00000023, 0x03F, 0x0000002A, 0x033, 0x00000024,
+ 0x03F, 0x0000002D, 0x033, 0x00000025, 0x03F, 0x00000030,
+ 0x033, 0x00000026, 0x03F, 0x0000006D, 0x033, 0x00000027,
+ 0x03F, 0x00000070, 0x033, 0x00000028, 0x03F, 0x000000ED,
+ 0x033, 0x00000029, 0x03F, 0x000000F0, 0x033, 0x0000002A,
+ 0x03F, 0x000000F3, 0x9000200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000020, 0x03F, 0x00000005, 0x033, 0x00000021,
+ 0x03F, 0x00000008, 0x033, 0x00000022, 0x03F, 0x0000000B,
+ 0x033, 0x00000023, 0x03F, 0x0000000E, 0x033, 0x00000024,
+ 0x03F, 0x0000002B, 0x033, 0x00000025, 0x03F, 0x00000068,
+ 0x033, 0x00000026, 0x03F, 0x0000006B, 0x033, 0x00000027,
+ 0x03F, 0x0000006E, 0x033, 0x00000028, 0x03F, 0x00000071,
+ 0x033, 0x00000029, 0x03F, 0x00000074, 0x033, 0x0000002A,
+ 0x03F, 0x00000077, 0x9300200c, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000020, 0x03F, 0x00000005, 0x033, 0x00000021,
+ 0x03F, 0x00000008, 0x033, 0x00000022, 0x03F, 0x0000000B,
+ 0x033, 0x00000023, 0x03F, 0x0000000E, 0x033, 0x00000024,
+ 0x03F, 0x0000002B, 0x033, 0x00000025, 0x03F, 0x00000068,
+ 0x033, 0x00000026, 0x03F, 0x0000006B, 0x033, 0x00000027,
+ 0x03F, 0x0000006E, 0x033, 0x00000028, 0x03F, 0x00000071,
+ 0x033, 0x00000029, 0x03F, 0x00000074, 0x033, 0x0000002A,
+ 0x03F, 0x00000077, 0x93012100, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000020, 0x03F, 0x00000C0C, 0x033, 0x00000021,
+ 0x03F, 0x00000C29, 0x033, 0x00000022, 0x03F, 0x00000C2C,
+ 0x033, 0x00000023, 0x03F, 0x00000C69, 0x033, 0x00000024,
+ 0x03F, 0x00000CA8, 0x033, 0x00000025, 0x03F, 0x00000CE8,
+ 0x033, 0x00000026, 0x03F, 0x00000CEB, 0x033, 0x00000027,
+ 0x03F, 0x00000CEE, 0x033, 0x00000028, 0x03F, 0x00000CF1,
+ 0x033, 0x00000029, 0x03F, 0x00000CF4, 0x033, 0x0000002A,
+ 0x03F, 0x00000CF7, 0x93002100, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000020, 0x03F, 0x0000042B, 0x033, 0x00000021,
+ 0x03F, 0x0000082A, 0x033, 0x00000022, 0x03F, 0x00000849,
+ 0x033, 0x00000023, 0x03F, 0x0000084C, 0x033, 0x00000024,
+ 0x03F, 0x00000C4C, 0x033, 0x00000025, 0x03F, 0x00000CA9,
+ 0x033, 0x00000026, 0x03F, 0x00000CEA, 0x033, 0x00000027,
+ 0x03F, 0x00000CED, 0x033, 0x00000028, 0x03F, 0x00000CF0,
+ 0x033, 0x00000029, 0x03F, 0x00000CF3, 0x033, 0x0000002A,
+ 0x03F, 0x00000CF6, 0x93011000, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000020, 0x03F, 0x00000C09, 0x033, 0x00000021,
+ 0x03F, 0x00000C0C, 0x033, 0x00000022, 0x03F, 0x00000C0F,
+ 0x033, 0x00000023, 0x03F, 0x00000C2C, 0x033, 0x00000024,
+ 0x03F, 0x00000C2F, 0x033, 0x00000025, 0x03F, 0x00000C8A,
+ 0x033, 0x00000026, 0x03F, 0x00000C8D, 0x033, 0x00000027,
+ 0x03F, 0x00000C90, 0x033, 0x00000028, 0x03F, 0x00000CD0,
+ 0x033, 0x00000029, 0x03F, 0x00000CF2, 0x033, 0x0000002A,
+ 0x03F, 0x00000CF5, 0x9000200c, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000020, 0x03F, 0x00000005, 0x033, 0x00000021,
+ 0x03F, 0x00000008, 0x033, 0x00000022, 0x03F, 0x0000000B,
+ 0x033, 0x00000023, 0x03F, 0x0000000E, 0x033, 0x00000024,
+ 0x03F, 0x0000002B, 0x033, 0x00000025, 0x03F, 0x00000068,
+ 0x033, 0x00000026, 0x03F, 0x0000006B, 0x033, 0x00000027,
+ 0x03F, 0x0000006E, 0x033, 0x00000028, 0x03F, 0x00000071,
+ 0x033, 0x00000029, 0x03F, 0x00000074, 0x033, 0x0000002A,
+ 0x03F, 0x00000077, 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000020, 0x03F, 0x00000C09, 0x033, 0x00000021,
+ 0x03F, 0x00000C0C, 0x033, 0x00000022, 0x03F, 0x00000C0F,
+ 0x033, 0x00000023, 0x03F, 0x00000C2C, 0x033, 0x00000024,
+ 0x03F, 0x00000C2F, 0x033, 0x00000025, 0x03F, 0x00000C8A,
+ 0x033, 0x00000026, 0x03F, 0x00000C8D, 0x033, 0x00000027,
+ 0x03F, 0x00000C90, 0x033, 0x00000028, 0x03F, 0x00000CD0,
+ 0x033, 0x00000029, 0x03F, 0x00000CF2, 0x033, 0x0000002A,
+ 0x03F, 0x00000CF5, 0x93002000, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000020, 0x03F, 0x00000429, 0x033, 0x00000021,
+ 0x03F, 0x00000828, 0x033, 0x00000022, 0x03F, 0x00000847,
+ 0x033, 0x00000023, 0x03F, 0x0000084A, 0x033, 0x00000024,
+ 0x03F, 0x00000C4B, 0x033, 0x00000025, 0x03F, 0x00000C8A,
+ 0x033, 0x00000026, 0x03F, 0x00000CEA, 0x033, 0x00000027,
+ 0x03F, 0x00000CED, 0x033, 0x00000028, 0x03F, 0x00000CF0,
+ 0x033, 0x00000029, 0x03F, 0x00000CF3, 0x033, 0x0000002A,
+ 0x03F, 0x00000CF6, 0x93001000, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000020, 0x03F, 0x00000C09, 0x033, 0x00000021,
+ 0x03F, 0x00000C0C, 0x033, 0x00000022, 0x03F, 0x00000C0F,
+ 0x033, 0x00000023, 0x03F, 0x00000C2C, 0x033, 0x00000024,
+ 0x03F, 0x00000C2F, 0x033, 0x00000025, 0x03F, 0x00000C8A,
+ 0x033, 0x00000026, 0x03F, 0x00000C8D, 0x033, 0x00000027,
+ 0x03F, 0x00000C90, 0x033, 0x00000028, 0x03F, 0x00000CD0,
+ 0x033, 0x00000029, 0x03F, 0x00000CF2, 0x033, 0x0000002A,
+ 0x03F, 0x00000CF5, 0x90002100, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000020, 0x03F, 0x0000042B, 0x033, 0x00000021,
+ 0x03F, 0x0000082A, 0x033, 0x00000022, 0x03F, 0x00000849,
+ 0x033, 0x00000023, 0x03F, 0x0000084C, 0x033, 0x00000024,
+ 0x03F, 0x00000C4C, 0x033, 0x00000025, 0x03F, 0x00000C8A,
+ 0x033, 0x00000026, 0x03F, 0x00000C8D, 0x033, 0x00000027,
+ 0x03F, 0x00000CEB, 0x033, 0x00000028, 0x03F, 0x00000CEE,
+ 0x033, 0x00000029, 0x03F, 0x00000CF1, 0x033, 0x0000002A,
+ 0x03F, 0x00000CF4, 0x90002000, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000020, 0x03F, 0x0000042B, 0x033, 0x00000021,
+ 0x03F, 0x0000082A, 0x033, 0x00000022, 0x03F, 0x00000849,
+ 0x033, 0x00000023, 0x03F, 0x0000084C, 0x033, 0x00000024,
+ 0x03F, 0x00000C4C, 0x033, 0x00000025, 0x03F, 0x00000C8A,
+ 0x033, 0x00000026, 0x03F, 0x00000C8D, 0x033, 0x00000027,
+ 0x03F, 0x00000CEB, 0x033, 0x00000028, 0x03F, 0x00000CEE,
+ 0x033, 0x00000029, 0x03F, 0x00000CF1, 0x033, 0x0000002A,
+ 0x03F, 0x00000CF4, 0xA0000000, 0x00000000, 0x033, 0x00000020,
+ 0x03F, 0x00000C09, 0x033, 0x00000021, 0x03F, 0x00000C0C,
+ 0x033, 0x00000022, 0x03F, 0x00000C0F, 0x033, 0x00000023,
+ 0x03F, 0x00000C2C, 0x033, 0x00000024, 0x03F, 0x00000C2F,
+ 0x033, 0x00000025, 0x03F, 0x00000C8A, 0x033, 0x00000026,
+ 0x03F, 0x00000C8D, 0x033, 0x00000027, 0x03F, 0x00000C90,
+ 0x033, 0x00000028, 0x03F, 0x00000CD0, 0x033, 0x00000029,
+ 0x03F, 0x00000CF2, 0x033, 0x0000002A, 0x03F, 0x00000CF5,
+ 0xB0000000, 0x00000000, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x033, 0x00000060, 0x03F, 0x00000007, 0x033, 0x00000061,
+ 0x03F, 0x0000000A, 0x033, 0x00000062, 0x03F, 0x0000000D,
+ 0x033, 0x00000063, 0x03F, 0x0000002A, 0x033, 0x00000064,
+ 0x03F, 0x0000002D, 0x033, 0x00000065, 0x03F, 0x00000030,
+ 0x033, 0x00000066, 0x03F, 0x0000006D, 0x033, 0x00000067,
+ 0x03F, 0x00000070, 0x033, 0x00000068, 0x03F, 0x000000ED,
+ 0x033, 0x00000069, 0x03F, 0x000000F0, 0x033, 0x0000006A,
+ 0x03F, 0x000000F3, 0x9300100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x033, 0x00000060, 0x03F, 0x00000007, 0x033, 0x00000061,
+ 0x03F, 0x0000000A, 0x033, 0x00000062, 0x03F, 0x0000000D,
+ 0x033, 0x00000063, 0x03F, 0x0000002A, 0x033, 0x00000064,
+ 0x03F, 0x0000002D, 0x033, 0x00000065, 0x03F, 0x00000030,
+ 0x033, 0x00000066, 0x03F, 0x0000006D, 0x033, 0x00000067,
+ 0x03F, 0x00000070, 0x033, 0x00000068, 0x03F, 0x000000ED,
+ 0x033, 0x00000069, 0x03F, 0x000000F0, 0x033, 0x0000006A,
+ 0x03F, 0x000000F3, 0x9300100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000060, 0x03F, 0x00000007, 0x033, 0x00000061,
+ 0x03F, 0x0000000A, 0x033, 0x00000062, 0x03F, 0x0000000D,
+ 0x033, 0x00000063, 0x03F, 0x0000002A, 0x033, 0x00000064,
+ 0x03F, 0x0000002D, 0x033, 0x00000065, 0x03F, 0x00000030,
+ 0x033, 0x00000066, 0x03F, 0x0000006D, 0x033, 0x00000067,
+ 0x03F, 0x00000070, 0x033, 0x00000068, 0x03F, 0x000000ED,
+ 0x033, 0x00000069, 0x03F, 0x000000F0, 0x033, 0x0000006A,
+ 0x03F, 0x000000F3, 0x9300200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000060, 0x03F, 0x00000005, 0x033, 0x00000061,
+ 0x03F, 0x00000008, 0x033, 0x00000062, 0x03F, 0x0000000B,
+ 0x033, 0x00000063, 0x03F, 0x0000000E, 0x033, 0x00000064,
+ 0x03F, 0x0000002B, 0x033, 0x00000065, 0x03F, 0x00000068,
+ 0x033, 0x00000066, 0x03F, 0x0000006B, 0x033, 0x00000067,
+ 0x03F, 0x0000006E, 0x033, 0x00000068, 0x03F, 0x00000071,
+ 0x033, 0x00000069, 0x03F, 0x00000074, 0x033, 0x0000006A,
+ 0x03F, 0x00000077, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x033, 0x00000060, 0x03F, 0x00000007, 0x033, 0x00000061,
+ 0x03F, 0x0000000A, 0x033, 0x00000062, 0x03F, 0x0000000D,
+ 0x033, 0x00000063, 0x03F, 0x0000002A, 0x033, 0x00000064,
+ 0x03F, 0x0000002D, 0x033, 0x00000065, 0x03F, 0x00000030,
+ 0x033, 0x00000066, 0x03F, 0x0000006D, 0x033, 0x00000067,
+ 0x03F, 0x00000070, 0x033, 0x00000068, 0x03F, 0x000000ED,
+ 0x033, 0x00000069, 0x03F, 0x000000F0, 0x033, 0x0000006A,
+ 0x03F, 0x000000F3, 0x9000100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x033, 0x00000060, 0x03F, 0x00000007, 0x033, 0x00000061,
+ 0x03F, 0x0000000A, 0x033, 0x00000062, 0x03F, 0x0000000D,
+ 0x033, 0x00000063, 0x03F, 0x0000002A, 0x033, 0x00000064,
+ 0x03F, 0x0000002D, 0x033, 0x00000065, 0x03F, 0x00000030,
+ 0x033, 0x00000066, 0x03F, 0x0000006D, 0x033, 0x00000067,
+ 0x03F, 0x00000070, 0x033, 0x00000068, 0x03F, 0x000000ED,
+ 0x033, 0x00000069, 0x03F, 0x000000F0, 0x033, 0x0000006A,
+ 0x03F, 0x000000F3, 0x9000100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000060, 0x03F, 0x00000007, 0x033, 0x00000061,
+ 0x03F, 0x0000000A, 0x033, 0x00000062, 0x03F, 0x0000000D,
+ 0x033, 0x00000063, 0x03F, 0x0000002A, 0x033, 0x00000064,
+ 0x03F, 0x0000002D, 0x033, 0x00000065, 0x03F, 0x00000030,
+ 0x033, 0x00000066, 0x03F, 0x0000006D, 0x033, 0x00000067,
+ 0x03F, 0x00000070, 0x033, 0x00000068, 0x03F, 0x000000ED,
+ 0x033, 0x00000069, 0x03F, 0x000000F0, 0x033, 0x0000006A,
+ 0x03F, 0x000000F3, 0x9000200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000060, 0x03F, 0x00000005, 0x033, 0x00000061,
+ 0x03F, 0x00000008, 0x033, 0x00000062, 0x03F, 0x0000000B,
+ 0x033, 0x00000063, 0x03F, 0x0000000E, 0x033, 0x00000064,
+ 0x03F, 0x0000002B, 0x033, 0x00000065, 0x03F, 0x00000068,
+ 0x033, 0x00000066, 0x03F, 0x0000006B, 0x033, 0x00000067,
+ 0x03F, 0x0000006E, 0x033, 0x00000068, 0x03F, 0x00000071,
+ 0x033, 0x00000069, 0x03F, 0x00000074, 0x033, 0x0000006A,
+ 0x03F, 0x00000077, 0x9300200c, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000060, 0x03F, 0x00000005, 0x033, 0x00000061,
+ 0x03F, 0x00000008, 0x033, 0x00000062, 0x03F, 0x0000000B,
+ 0x033, 0x00000063, 0x03F, 0x0000000E, 0x033, 0x00000064,
+ 0x03F, 0x0000002B, 0x033, 0x00000065, 0x03F, 0x00000068,
+ 0x033, 0x00000066, 0x03F, 0x0000006B, 0x033, 0x00000067,
+ 0x03F, 0x0000006E, 0x033, 0x00000068, 0x03F, 0x00000071,
+ 0x033, 0x00000069, 0x03F, 0x00000074, 0x033, 0x0000006A,
+ 0x03F, 0x00000077, 0x93012100, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000060, 0x03F, 0x0000080B, 0x033, 0x00000061,
+ 0x03F, 0x0000080E, 0x033, 0x00000062, 0x03F, 0x00000848,
+ 0x033, 0x00000063, 0x03F, 0x00000869, 0x033, 0x00000064,
+ 0x03F, 0x000008A9, 0x033, 0x00000065, 0x03F, 0x00000CE8,
+ 0x033, 0x00000066, 0x03F, 0x00000CEB, 0x033, 0x00000067,
+ 0x03F, 0x00000CEE, 0x033, 0x00000068, 0x03F, 0x00000CF1,
+ 0x033, 0x00000069, 0x03F, 0x00000CF4, 0x033, 0x0000006A,
+ 0x03F, 0x00000CF7, 0x93002100, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000060, 0x03F, 0x0000042B, 0x033, 0x00000061,
+ 0x03F, 0x0000082A, 0x033, 0x00000062, 0x03F, 0x00000849,
+ 0x033, 0x00000063, 0x03F, 0x0000084C, 0x033, 0x00000064,
+ 0x03F, 0x00000C4C, 0x033, 0x00000065, 0x03F, 0x00000CA9,
+ 0x033, 0x00000066, 0x03F, 0x00000CEA, 0x033, 0x00000067,
+ 0x03F, 0x00000CED, 0x033, 0x00000068, 0x03F, 0x00000CF0,
+ 0x033, 0x00000069, 0x03F, 0x00000CF3, 0x033, 0x0000006A,
+ 0x03F, 0x00000CF6, 0x93011000, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000060, 0x03F, 0x00000C0A, 0x033, 0x00000061,
+ 0x03F, 0x00000C0D, 0x033, 0x00000062, 0x03F, 0x00000C2A,
+ 0x033, 0x00000063, 0x03F, 0x00000C2D, 0x033, 0x00000064,
+ 0x03F, 0x00000C6A, 0x033, 0x00000065, 0x03F, 0x00000CAA,
+ 0x033, 0x00000066, 0x03F, 0x00000CAD, 0x033, 0x00000067,
+ 0x03F, 0x00000CB0, 0x033, 0x00000068, 0x03F, 0x00000CF1,
+ 0x033, 0x00000069, 0x03F, 0x00000CF4, 0x033, 0x0000006A,
+ 0x03F, 0x00000CF7, 0x9000200c, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000060, 0x03F, 0x00000005, 0x033, 0x00000061,
+ 0x03F, 0x00000008, 0x033, 0x00000062, 0x03F, 0x0000000B,
+ 0x033, 0x00000063, 0x03F, 0x0000000E, 0x033, 0x00000064,
+ 0x03F, 0x0000002B, 0x033, 0x00000065, 0x03F, 0x00000068,
+ 0x033, 0x00000066, 0x03F, 0x0000006B, 0x033, 0x00000067,
+ 0x03F, 0x0000006E, 0x033, 0x00000068, 0x03F, 0x00000071,
+ 0x033, 0x00000069, 0x03F, 0x00000074, 0x033, 0x0000006A,
+ 0x03F, 0x00000077, 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000060, 0x03F, 0x00000C0A, 0x033, 0x00000061,
+ 0x03F, 0x00000C0D, 0x033, 0x00000062, 0x03F, 0x00000C2A,
+ 0x033, 0x00000063, 0x03F, 0x00000C2D, 0x033, 0x00000064,
+ 0x03F, 0x00000C6A, 0x033, 0x00000065, 0x03F, 0x00000CAA,
+ 0x033, 0x00000066, 0x03F, 0x00000CAD, 0x033, 0x00000067,
+ 0x03F, 0x00000CB0, 0x033, 0x00000068, 0x03F, 0x00000CF1,
+ 0x033, 0x00000069, 0x03F, 0x00000CF4, 0x033, 0x0000006A,
+ 0x03F, 0x00000CF7, 0x93002000, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000060, 0x03F, 0x00000429, 0x033, 0x00000061,
+ 0x03F, 0x00000828, 0x033, 0x00000062, 0x03F, 0x00000847,
+ 0x033, 0x00000063, 0x03F, 0x0000084A, 0x033, 0x00000064,
+ 0x03F, 0x00000C4B, 0x033, 0x00000065, 0x03F, 0x00000C8A,
+ 0x033, 0x00000066, 0x03F, 0x00000CEA, 0x033, 0x00000067,
+ 0x03F, 0x00000CED, 0x033, 0x00000068, 0x03F, 0x00000CF0,
+ 0x033, 0x00000069, 0x03F, 0x00000CF3, 0x033, 0x0000006A,
+ 0x03F, 0x00000CF6, 0x93001000, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000060, 0x03F, 0x00000C0A, 0x033, 0x00000061,
+ 0x03F, 0x00000C0D, 0x033, 0x00000062, 0x03F, 0x00000C2A,
+ 0x033, 0x00000063, 0x03F, 0x00000C2D, 0x033, 0x00000064,
+ 0x03F, 0x00000C6A, 0x033, 0x00000065, 0x03F, 0x00000CAA,
+ 0x033, 0x00000066, 0x03F, 0x00000CAD, 0x033, 0x00000067,
+ 0x03F, 0x00000CB0, 0x033, 0x00000068, 0x03F, 0x00000CF1,
+ 0x033, 0x00000069, 0x03F, 0x00000CF4, 0x033, 0x0000006A,
+ 0x03F, 0x00000CF7, 0x90002100, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000060, 0x03F, 0x0000042C, 0x033, 0x00000061,
+ 0x03F, 0x0000082B, 0x033, 0x00000062, 0x03F, 0x0000084A,
+ 0x033, 0x00000063, 0x03F, 0x0000084D, 0x033, 0x00000064,
+ 0x03F, 0x00000C4D, 0x033, 0x00000065, 0x03F, 0x00000C8B,
+ 0x033, 0x00000066, 0x03F, 0x00000C8E, 0x033, 0x00000067,
+ 0x03F, 0x00000CEC, 0x033, 0x00000068, 0x03F, 0x00000CEF,
+ 0x033, 0x00000069, 0x03F, 0x00000CF2, 0x033, 0x0000006A,
+ 0x03F, 0x00000CF5, 0x90002000, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000060, 0x03F, 0x0000042C, 0x033, 0x00000061,
+ 0x03F, 0x0000082B, 0x033, 0x00000062, 0x03F, 0x0000084A,
+ 0x033, 0x00000063, 0x03F, 0x0000084D, 0x033, 0x00000064,
+ 0x03F, 0x00000C4D, 0x033, 0x00000065, 0x03F, 0x00000C8B,
+ 0x033, 0x00000066, 0x03F, 0x00000C8E, 0x033, 0x00000067,
+ 0x03F, 0x00000CEC, 0x033, 0x00000068, 0x03F, 0x00000CEF,
+ 0x033, 0x00000069, 0x03F, 0x00000CF2, 0x033, 0x0000006A,
+ 0x03F, 0x00000CF5, 0xA0000000, 0x00000000, 0x033, 0x00000060,
+ 0x03F, 0x00000C0A, 0x033, 0x00000061, 0x03F, 0x00000C0D,
+ 0x033, 0x00000062, 0x03F, 0x00000C2A, 0x033, 0x00000063,
+ 0x03F, 0x00000C2D, 0x033, 0x00000064, 0x03F, 0x00000C6A,
+ 0x033, 0x00000065, 0x03F, 0x00000CAA, 0x033, 0x00000066,
+ 0x03F, 0x00000CAD, 0x033, 0x00000067, 0x03F, 0x00000CB0,
+ 0x033, 0x00000068, 0x03F, 0x00000CF1, 0x033, 0x00000069,
+ 0x03F, 0x00000CF4, 0x033, 0x0000006A, 0x03F, 0x00000CF7,
+ 0xB0000000, 0x00000000, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x033, 0x000000A0, 0x03F, 0x00000007, 0x033, 0x000000A1,
+ 0x03F, 0x0000000A, 0x033, 0x000000A2, 0x03F, 0x0000000D,
+ 0x033, 0x000000A3, 0x03F, 0x0000002A, 0x033, 0x000000A4,
+ 0x03F, 0x0000002D, 0x033, 0x000000A5, 0x03F, 0x00000030,
+ 0x033, 0x000000A6, 0x03F, 0x0000006D, 0x033, 0x000000A7,
+ 0x03F, 0x00000070, 0x033, 0x000000A8, 0x03F, 0x000000ED,
+ 0x033, 0x000000A9, 0x03F, 0x000000F0, 0x033, 0x000000AA,
+ 0x03F, 0x000000F3, 0x9300100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x033, 0x000000A0, 0x03F, 0x00000007, 0x033, 0x000000A1,
+ 0x03F, 0x0000000A, 0x033, 0x000000A2, 0x03F, 0x0000000D,
+ 0x033, 0x000000A3, 0x03F, 0x0000002A, 0x033, 0x000000A4,
+ 0x03F, 0x0000002D, 0x033, 0x000000A5, 0x03F, 0x00000030,
+ 0x033, 0x000000A6, 0x03F, 0x0000006D, 0x033, 0x000000A7,
+ 0x03F, 0x00000070, 0x033, 0x000000A8, 0x03F, 0x000000ED,
+ 0x033, 0x000000A9, 0x03F, 0x000000F0, 0x033, 0x000000AA,
+ 0x03F, 0x000000F3, 0x9300100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x000000A0, 0x03F, 0x00000007, 0x033, 0x000000A1,
+ 0x03F, 0x0000000A, 0x033, 0x000000A2, 0x03F, 0x0000000D,
+ 0x033, 0x000000A3, 0x03F, 0x0000002A, 0x033, 0x000000A4,
+ 0x03F, 0x0000002D, 0x033, 0x000000A5, 0x03F, 0x00000030,
+ 0x033, 0x000000A6, 0x03F, 0x0000006D, 0x033, 0x000000A7,
+ 0x03F, 0x00000070, 0x033, 0x000000A8, 0x03F, 0x000000ED,
+ 0x033, 0x000000A9, 0x03F, 0x000000F0, 0x033, 0x000000AA,
+ 0x03F, 0x000000F3, 0x9300200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x000000A0, 0x03F, 0x00000005, 0x033, 0x000000A1,
+ 0x03F, 0x00000008, 0x033, 0x000000A2, 0x03F, 0x0000000B,
+ 0x033, 0x000000A3, 0x03F, 0x0000000E, 0x033, 0x000000A4,
+ 0x03F, 0x00000047, 0x033, 0x000000A5, 0x03F, 0x0000004A,
+ 0x033, 0x000000A6, 0x03F, 0x0000004D, 0x033, 0x000000A7,
+ 0x03F, 0x00000050, 0x033, 0x000000A8, 0x03F, 0x00000053,
+ 0x033, 0x000000A9, 0x03F, 0x00000056, 0x033, 0x000000AA,
+ 0x03F, 0x00000094, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x033, 0x000000A0, 0x03F, 0x00000007, 0x033, 0x000000A1,
+ 0x03F, 0x0000000A, 0x033, 0x000000A2, 0x03F, 0x0000000D,
+ 0x033, 0x000000A3, 0x03F, 0x0000002A, 0x033, 0x000000A4,
+ 0x03F, 0x0000002D, 0x033, 0x000000A5, 0x03F, 0x00000030,
+ 0x033, 0x000000A6, 0x03F, 0x0000006D, 0x033, 0x000000A7,
+ 0x03F, 0x00000070, 0x033, 0x000000A8, 0x03F, 0x000000ED,
+ 0x033, 0x000000A9, 0x03F, 0x000000F0, 0x033, 0x000000AA,
+ 0x03F, 0x000000F3, 0x9000100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x033, 0x000000A0, 0x03F, 0x00000007, 0x033, 0x000000A1,
+ 0x03F, 0x0000000A, 0x033, 0x000000A2, 0x03F, 0x0000000D,
+ 0x033, 0x000000A3, 0x03F, 0x0000002A, 0x033, 0x000000A4,
+ 0x03F, 0x0000002D, 0x033, 0x000000A5, 0x03F, 0x00000030,
+ 0x033, 0x000000A6, 0x03F, 0x0000006D, 0x033, 0x000000A7,
+ 0x03F, 0x00000070, 0x033, 0x000000A8, 0x03F, 0x000000ED,
+ 0x033, 0x000000A9, 0x03F, 0x000000F0, 0x033, 0x000000AA,
+ 0x03F, 0x000000F3, 0x9000100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x000000A0, 0x03F, 0x00000007, 0x033, 0x000000A1,
+ 0x03F, 0x0000000A, 0x033, 0x000000A2, 0x03F, 0x0000000D,
+ 0x033, 0x000000A3, 0x03F, 0x0000002A, 0x033, 0x000000A4,
+ 0x03F, 0x0000002D, 0x033, 0x000000A5, 0x03F, 0x00000030,
+ 0x033, 0x000000A6, 0x03F, 0x0000006D, 0x033, 0x000000A7,
+ 0x03F, 0x00000070, 0x033, 0x000000A8, 0x03F, 0x000000ED,
+ 0x033, 0x000000A9, 0x03F, 0x000000F0, 0x033, 0x000000AA,
+ 0x03F, 0x000000F3, 0x9000200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x000000A0, 0x03F, 0x00000005, 0x033, 0x000000A1,
+ 0x03F, 0x00000008, 0x033, 0x000000A2, 0x03F, 0x0000000B,
+ 0x033, 0x000000A3, 0x03F, 0x0000000E, 0x033, 0x000000A4,
+ 0x03F, 0x00000047, 0x033, 0x000000A5, 0x03F, 0x0000004A,
+ 0x033, 0x000000A6, 0x03F, 0x0000004D, 0x033, 0x000000A7,
+ 0x03F, 0x00000050, 0x033, 0x000000A8, 0x03F, 0x00000053,
+ 0x033, 0x000000A9, 0x03F, 0x00000056, 0x033, 0x000000AA,
+ 0x03F, 0x00000094, 0x9300200c, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x000000A0, 0x03F, 0x00000005, 0x033, 0x000000A1,
+ 0x03F, 0x00000008, 0x033, 0x000000A2, 0x03F, 0x0000000B,
+ 0x033, 0x000000A3, 0x03F, 0x0000000E, 0x033, 0x000000A4,
+ 0x03F, 0x00000047, 0x033, 0x000000A5, 0x03F, 0x0000004A,
+ 0x033, 0x000000A6, 0x03F, 0x0000004D, 0x033, 0x000000A7,
+ 0x03F, 0x00000050, 0x033, 0x000000A8, 0x03F, 0x00000053,
+ 0x033, 0x000000A9, 0x03F, 0x00000056, 0x033, 0x000000AA,
+ 0x03F, 0x00000094, 0x93012100, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x000000A0, 0x03F, 0x00000C0A, 0x033, 0x000000A1,
+ 0x03F, 0x00000C0D, 0x033, 0x000000A2, 0x03F, 0x00000C2A,
+ 0x033, 0x000000A3, 0x03F, 0x00000C2D, 0x033, 0x000000A4,
+ 0x03F, 0x00000C6A, 0x033, 0x000000A5, 0x03F, 0x00000CE8,
+ 0x033, 0x000000A6, 0x03F, 0x00000CEB, 0x033, 0x000000A7,
+ 0x03F, 0x00000CEE, 0x033, 0x000000A8, 0x03F, 0x00000CF1,
+ 0x033, 0x000000A9, 0x03F, 0x00000CF4, 0x033, 0x000000AA,
+ 0x03F, 0x00000CF7, 0x93002100, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x000000A0, 0x03F, 0x0000042A, 0x033, 0x000000A1,
+ 0x03F, 0x00000829, 0x033, 0x000000A2, 0x03F, 0x00000848,
+ 0x033, 0x000000A3, 0x03F, 0x0000084B, 0x033, 0x000000A4,
+ 0x03F, 0x00000C4C, 0x033, 0x000000A5, 0x03F, 0x00000CA9,
+ 0x033, 0x000000A6, 0x03F, 0x00000CEA, 0x033, 0x000000A7,
+ 0x03F, 0x00000CED, 0x033, 0x000000A8, 0x03F, 0x00000CF0,
+ 0x033, 0x000000A9, 0x03F, 0x00000CF3, 0x033, 0x000000AA,
+ 0x03F, 0x00000CF6, 0x93011000, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x000000A0, 0x03F, 0x00000C09, 0x033, 0x000000A1,
+ 0x03F, 0x00000C0C, 0x033, 0x000000A2, 0x03F, 0x00000C0F,
+ 0x033, 0x000000A3, 0x03F, 0x00000C2C, 0x033, 0x000000A4,
+ 0x03F, 0x00000C2F, 0x033, 0x000000A5, 0x03F, 0x00000C8A,
+ 0x033, 0x000000A6, 0x03F, 0x00000C8D, 0x033, 0x000000A7,
+ 0x03F, 0x00000C90, 0x033, 0x000000A8, 0x03F, 0x00000CEF,
+ 0x033, 0x000000A9, 0x03F, 0x00000CF2, 0x033, 0x000000AA,
+ 0x03F, 0x00000CF5, 0x9000200c, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x000000A0, 0x03F, 0x00000005, 0x033, 0x000000A1,
+ 0x03F, 0x00000008, 0x033, 0x000000A2, 0x03F, 0x0000000B,
+ 0x033, 0x000000A3, 0x03F, 0x0000000E, 0x033, 0x000000A4,
+ 0x03F, 0x00000047, 0x033, 0x000000A5, 0x03F, 0x0000004A,
+ 0x033, 0x000000A6, 0x03F, 0x0000004D, 0x033, 0x000000A7,
+ 0x03F, 0x00000050, 0x033, 0x000000A8, 0x03F, 0x00000053,
+ 0x033, 0x000000A9, 0x03F, 0x00000056, 0x033, 0x000000AA,
+ 0x03F, 0x00000094, 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x000000A0, 0x03F, 0x00000C09, 0x033, 0x000000A1,
+ 0x03F, 0x00000C0C, 0x033, 0x000000A2, 0x03F, 0x00000C0F,
+ 0x033, 0x000000A3, 0x03F, 0x00000C2C, 0x033, 0x000000A4,
+ 0x03F, 0x00000C2F, 0x033, 0x000000A5, 0x03F, 0x00000C8A,
+ 0x033, 0x000000A6, 0x03F, 0x00000C8D, 0x033, 0x000000A7,
+ 0x03F, 0x00000C90, 0x033, 0x000000A8, 0x03F, 0x00000CEF,
+ 0x033, 0x000000A9, 0x03F, 0x00000CF2, 0x033, 0x000000AA,
+ 0x03F, 0x00000CF5, 0x93002000, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x000000A0, 0x03F, 0x00000429, 0x033, 0x000000A1,
+ 0x03F, 0x00000828, 0x033, 0x000000A2, 0x03F, 0x00000847,
+ 0x033, 0x000000A3, 0x03F, 0x0000084A, 0x033, 0x000000A4,
+ 0x03F, 0x00000C4B, 0x033, 0x000000A5, 0x03F, 0x00000C8A,
+ 0x033, 0x000000A6, 0x03F, 0x00000CEA, 0x033, 0x000000A7,
+ 0x03F, 0x00000CED, 0x033, 0x000000A8, 0x03F, 0x00000CF0,
+ 0x033, 0x000000A9, 0x03F, 0x00000CF3, 0x033, 0x000000AA,
+ 0x03F, 0x00000CF6, 0x93001000, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x000000A0, 0x03F, 0x00000C09, 0x033, 0x000000A1,
+ 0x03F, 0x00000C0C, 0x033, 0x000000A2, 0x03F, 0x00000C0F,
+ 0x033, 0x000000A3, 0x03F, 0x00000C2C, 0x033, 0x000000A4,
+ 0x03F, 0x00000C2F, 0x033, 0x000000A5, 0x03F, 0x00000C8A,
+ 0x033, 0x000000A6, 0x03F, 0x00000C8D, 0x033, 0x000000A7,
+ 0x03F, 0x00000C90, 0x033, 0x000000A8, 0x03F, 0x00000CEF,
+ 0x033, 0x000000A9, 0x03F, 0x00000CF2, 0x033, 0x000000AA,
+ 0x03F, 0x00000CF5, 0x90002100, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x000000A0, 0x03F, 0x0000042A, 0x033, 0x000000A1,
+ 0x03F, 0x00000829, 0x033, 0x000000A2, 0x03F, 0x00000848,
+ 0x033, 0x000000A3, 0x03F, 0x0000084B, 0x033, 0x000000A4,
+ 0x03F, 0x00000C4C, 0x033, 0x000000A5, 0x03F, 0x00000C8A,
+ 0x033, 0x000000A6, 0x03F, 0x00000C8D, 0x033, 0x000000A7,
+ 0x03F, 0x00000CEB, 0x033, 0x000000A8, 0x03F, 0x00000CEE,
+ 0x033, 0x000000A9, 0x03F, 0x00000CF1, 0x033, 0x000000AA,
+ 0x03F, 0x00000CF4, 0x90002000, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x000000A0, 0x03F, 0x0000042A, 0x033, 0x000000A1,
+ 0x03F, 0x00000829, 0x033, 0x000000A2, 0x03F, 0x00000848,
+ 0x033, 0x000000A3, 0x03F, 0x0000084B, 0x033, 0x000000A4,
+ 0x03F, 0x00000C4C, 0x033, 0x000000A5, 0x03F, 0x00000C8A,
+ 0x033, 0x000000A6, 0x03F, 0x00000C8D, 0x033, 0x000000A7,
+ 0x03F, 0x00000CEB, 0x033, 0x000000A8, 0x03F, 0x00000CEE,
+ 0x033, 0x000000A9, 0x03F, 0x00000CF1, 0x033, 0x000000AA,
+ 0x03F, 0x00000CF4, 0xA0000000, 0x00000000, 0x033, 0x000000A0,
+ 0x03F, 0x00000C09, 0x033, 0x000000A1, 0x03F, 0x00000C0C,
+ 0x033, 0x000000A2, 0x03F, 0x00000C0F, 0x033, 0x000000A3,
+ 0x03F, 0x00000C2C, 0x033, 0x000000A4, 0x03F, 0x00000C2F,
+ 0x033, 0x000000A5, 0x03F, 0x00000C8A, 0x033, 0x000000A6,
+ 0x03F, 0x00000C8D, 0x033, 0x000000A7, 0x03F, 0x00000C90,
+ 0x033, 0x000000A8, 0x03F, 0x00000CEF, 0x033, 0x000000A9,
+ 0x03F, 0x00000CF2, 0x033, 0x000000AA, 0x03F, 0x00000CF5,
+ 0xB0000000, 0x00000000, 0x0EF, 0x00000000, 0x0EF, 0x00000400,
+ 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000000,
+ 0x03F, 0x0000047C, 0x033, 0x00000001, 0x03F, 0x0000047C,
+ 0x033, 0x00000002, 0x03F, 0x0000047C, 0x033, 0x00000003,
+ 0x03F, 0x0000047C, 0x9300100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x033, 0x00000000, 0x03F, 0x0000047C, 0x033, 0x00000001,
+ 0x03F, 0x0000047C, 0x033, 0x00000002, 0x03F, 0x0000047C,
+ 0x033, 0x00000003, 0x03F, 0x0000047C, 0x9300100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x0000047C,
+ 0x033, 0x00000001, 0x03F, 0x0000047C, 0x033, 0x00000002,
+ 0x03F, 0x0000047C, 0x033, 0x00000003, 0x03F, 0x0000047C,
+ 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000,
+ 0x03F, 0x0000047C, 0x033, 0x00000001, 0x03F, 0x0000047C,
+ 0x033, 0x00000002, 0x03F, 0x0000047C, 0x033, 0x00000003,
+ 0x03F, 0x0000047C, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x033, 0x00000000, 0x03F, 0x0000047C, 0x033, 0x00000001,
+ 0x03F, 0x0000047C, 0x033, 0x00000002, 0x03F, 0x0000047C,
+ 0x033, 0x00000003, 0x03F, 0x0000047C, 0x9000100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x0000047C,
+ 0x033, 0x00000001, 0x03F, 0x0000047C, 0x033, 0x00000002,
+ 0x03F, 0x0000047C, 0x033, 0x00000003, 0x03F, 0x0000047C,
+ 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000,
+ 0x03F, 0x0000047C, 0x033, 0x00000001, 0x03F, 0x0000047C,
+ 0x033, 0x00000002, 0x03F, 0x0000047C, 0x033, 0x00000003,
+ 0x03F, 0x0000047C, 0x9000200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000000, 0x03F, 0x0000047C, 0x033, 0x00000001,
+ 0x03F, 0x0000047C, 0x033, 0x00000002, 0x03F, 0x0000047C,
+ 0x033, 0x00000003, 0x03F, 0x0000047C, 0xA0000000, 0x00000000,
+ 0x033, 0x00000000, 0x03F, 0x000004BB, 0x033, 0x00000001,
+ 0x03F, 0x000004BB, 0x033, 0x00000002, 0x03F, 0x000004BB,
+ 0x033, 0x00000003, 0x03F, 0x000004BB, 0xB0000000, 0x00000000,
+ 0x0EF, 0x00000000, 0x0EF, 0x00000100, 0x8300100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00001726,
+ 0x033, 0x00000001, 0x03F, 0x00001726, 0x033, 0x00000002,
+ 0x03F, 0x00001726, 0x033, 0x00000003, 0x03F, 0x00001726,
+ 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000000,
+ 0x03F, 0x00001726, 0x033, 0x00000001, 0x03F, 0x00001726,
+ 0x033, 0x00000002, 0x03F, 0x00001726, 0x033, 0x00000003,
+ 0x03F, 0x00001726, 0x9300100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000000, 0x03F, 0x00001726, 0x033, 0x00000001,
+ 0x03F, 0x00001726, 0x033, 0x00000002, 0x03F, 0x00001726,
+ 0x033, 0x00000003, 0x03F, 0x00001726, 0x9300200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00001726,
+ 0x033, 0x00000001, 0x03F, 0x00001726, 0x033, 0x00000002,
+ 0x03F, 0x00001726, 0x033, 0x00000003, 0x03F, 0x00001726,
+ 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000000,
+ 0x03F, 0x00001726, 0x033, 0x00000001, 0x03F, 0x00001726,
+ 0x033, 0x00000002, 0x03F, 0x00001726, 0x033, 0x00000003,
+ 0x03F, 0x00001726, 0x9000100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x033, 0x00000000, 0x03F, 0x00001726, 0x033, 0x00000001,
+ 0x03F, 0x00001726, 0x033, 0x00000002, 0x03F, 0x00001726,
+ 0x033, 0x00000003, 0x03F, 0x00001726, 0x9000100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00001726,
+ 0x033, 0x00000001, 0x03F, 0x00001726, 0x033, 0x00000002,
+ 0x03F, 0x00001726, 0x033, 0x00000003, 0x03F, 0x00001726,
+ 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000,
+ 0x03F, 0x00001726, 0x033, 0x00000001, 0x03F, 0x00001726,
+ 0x033, 0x00000002, 0x03F, 0x00001726, 0x033, 0x00000003,
+ 0x03F, 0x00001726, 0xA0000000, 0x00000000, 0x033, 0x00000000,
+ 0x03F, 0x00000F34, 0x033, 0x00000001, 0x03F, 0x00000F34,
+ 0x033, 0x00000002, 0x03F, 0x00000F34, 0x033, 0x00000003,
+ 0x03F, 0x00000F34, 0xB0000000, 0x00000000, 0x0EF, 0x00000000,
+ 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x081, 0x0000F400,
+ 0x087, 0x00016040, 0x051, 0x00000808, 0x052, 0x00098002,
+ 0x053, 0x0000FA47, 0x054, 0x00058032, 0x056, 0x00051000,
+ 0x057, 0x0000CE0A, 0x058, 0x00082030, 0x9300100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x081, 0x0000F400, 0x087, 0x00016040,
+ 0x051, 0x00000808, 0x052, 0x00098002, 0x053, 0x0000FA47,
+ 0x054, 0x00058032, 0x056, 0x00051000, 0x057, 0x0000CE0A,
+ 0x058, 0x00082030, 0x9300100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x081, 0x0000F400, 0x087, 0x00016040, 0x051, 0x00000808,
+ 0x052, 0x00098002, 0x053, 0x0000FA47, 0x054, 0x00058032,
+ 0x056, 0x00051000, 0x057, 0x0000CE0A, 0x058, 0x00082030,
+ 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x081, 0x0000F400,
+ 0x087, 0x00016040, 0x051, 0x00000808, 0x052, 0x00098002,
+ 0x053, 0x0000FA47, 0x054, 0x00058032, 0x056, 0x00051000,
+ 0x057, 0x0000CE0A, 0x058, 0x00082030, 0x9000100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x081, 0x0000F400, 0x087, 0x00016040,
+ 0x051, 0x00000808, 0x052, 0x00098002, 0x053, 0x0000FA47,
+ 0x054, 0x00058032, 0x056, 0x00051000, 0x057, 0x0000CE0A,
+ 0x058, 0x00082030, 0x9000100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x081, 0x0000F400, 0x087, 0x00016040, 0x051, 0x00000808,
+ 0x052, 0x00098002, 0x053, 0x0000FA47, 0x054, 0x00058032,
+ 0x056, 0x00051000, 0x057, 0x0000CE0A, 0x058, 0x00082030,
+ 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x081, 0x0000F400,
+ 0x087, 0x00016040, 0x051, 0x00000808, 0x052, 0x00098002,
+ 0x053, 0x0000FA47, 0x054, 0x00058032, 0x056, 0x00051000,
+ 0x057, 0x0000CE0A, 0x058, 0x00082030, 0x9000200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x081, 0x0000F400, 0x087, 0x00016040,
+ 0x051, 0x00000808, 0x052, 0x00098002, 0x053, 0x0000FA47,
+ 0x054, 0x00058032, 0x056, 0x00051000, 0x057, 0x0000CE0A,
+ 0x058, 0x00082030, 0xA0000000, 0x00000000, 0x081, 0x0000F000,
+ 0x087, 0x00016040, 0x051, 0x00000C00, 0x052, 0x0007C241,
+ 0x053, 0x0001C069, 0x054, 0x00078032, 0x057, 0x0000CE0A,
+ 0x058, 0x00058750, 0xB0000000, 0x00000000, 0x0EF, 0x00000800,
+ 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000000,
+ 0x03F, 0x00000003, 0x033, 0x00000001, 0x03F, 0x00000006,
+ 0x033, 0x00000002, 0x03F, 0x00000009, 0x033, 0x00000003,
+ 0x03F, 0x00000026, 0x033, 0x00000004, 0x03F, 0x00000029,
+ 0x033, 0x00000005, 0x03F, 0x0000002C, 0x033, 0x00000006,
+ 0x03F, 0x0000002F, 0x033, 0x00000007, 0x03F, 0x00000033,
+ 0x033, 0x00000008, 0x03F, 0x00000036, 0x033, 0x00000009,
+ 0x03F, 0x00000039, 0x033, 0x0000000A, 0x03F, 0x0000003C,
+ 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000000,
+ 0x03F, 0x00000003, 0x033, 0x00000001, 0x03F, 0x00000006,
+ 0x033, 0x00000002, 0x03F, 0x00000009, 0x033, 0x00000003,
+ 0x03F, 0x00000026, 0x033, 0x00000004, 0x03F, 0x00000029,
+ 0x033, 0x00000005, 0x03F, 0x0000002C, 0x033, 0x00000006,
+ 0x03F, 0x0000002F, 0x033, 0x00000007, 0x03F, 0x00000033,
+ 0x033, 0x00000008, 0x03F, 0x00000036, 0x033, 0x00000009,
+ 0x03F, 0x00000039, 0x033, 0x0000000A, 0x03F, 0x0000003C,
+ 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000,
+ 0x03F, 0x00000003, 0x033, 0x00000001, 0x03F, 0x00000006,
+ 0x033, 0x00000002, 0x03F, 0x00000009, 0x033, 0x00000003,
+ 0x03F, 0x00000026, 0x033, 0x00000004, 0x03F, 0x00000029,
+ 0x033, 0x00000005, 0x03F, 0x0000002C, 0x033, 0x00000006,
+ 0x03F, 0x0000002F, 0x033, 0x00000007, 0x03F, 0x00000033,
+ 0x033, 0x00000008, 0x03F, 0x00000036, 0x033, 0x00000009,
+ 0x03F, 0x00000039, 0x033, 0x0000000A, 0x03F, 0x0000003C,
+ 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000,
+ 0x03F, 0x00000003, 0x033, 0x00000001, 0x03F, 0x00000006,
+ 0x033, 0x00000002, 0x03F, 0x00000009, 0x033, 0x00000003,
+ 0x03F, 0x00000026, 0x033, 0x00000004, 0x03F, 0x00000029,
+ 0x033, 0x00000005, 0x03F, 0x0000002C, 0x033, 0x00000006,
+ 0x03F, 0x0000002F, 0x033, 0x00000007, 0x03F, 0x00000033,
+ 0x033, 0x00000008, 0x03F, 0x00000036, 0x033, 0x00000009,
+ 0x03F, 0x00000039, 0x033, 0x0000000A, 0x03F, 0x0000003C,
+ 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000000,
+ 0x03F, 0x00000003, 0x033, 0x00000001, 0x03F, 0x00000006,
+ 0x033, 0x00000002, 0x03F, 0x00000009, 0x033, 0x00000003,
+ 0x03F, 0x00000026, 0x033, 0x00000004, 0x03F, 0x00000029,
+ 0x033, 0x00000005, 0x03F, 0x0000002C, 0x033, 0x00000006,
+ 0x03F, 0x0000002F, 0x033, 0x00000007, 0x03F, 0x00000033,
+ 0x033, 0x00000008, 0x03F, 0x00000036, 0x033, 0x00000009,
+ 0x03F, 0x00000039, 0x033, 0x0000000A, 0x03F, 0x0000003C,
+ 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000000,
+ 0x03F, 0x00000003, 0x033, 0x00000001, 0x03F, 0x00000006,
+ 0x033, 0x00000002, 0x03F, 0x00000009, 0x033, 0x00000003,
+ 0x03F, 0x00000026, 0x033, 0x00000004, 0x03F, 0x00000029,
+ 0x033, 0x00000005, 0x03F, 0x0000002C, 0x033, 0x00000006,
+ 0x03F, 0x0000002F, 0x033, 0x00000007, 0x03F, 0x00000033,
+ 0x033, 0x00000008, 0x03F, 0x00000036, 0x033, 0x00000009,
+ 0x03F, 0x00000039, 0x033, 0x0000000A, 0x03F, 0x0000003C,
+ 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000,
+ 0x03F, 0x00000003, 0x033, 0x00000001, 0x03F, 0x00000006,
+ 0x033, 0x00000002, 0x03F, 0x00000009, 0x033, 0x00000003,
+ 0x03F, 0x00000026, 0x033, 0x00000004, 0x03F, 0x00000029,
+ 0x033, 0x00000005, 0x03F, 0x0000002C, 0x033, 0x00000006,
+ 0x03F, 0x0000002F, 0x033, 0x00000007, 0x03F, 0x00000033,
+ 0x033, 0x00000008, 0x03F, 0x00000036, 0x033, 0x00000009,
+ 0x03F, 0x00000039, 0x033, 0x0000000A, 0x03F, 0x0000003C,
+ 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000,
+ 0x03F, 0x00000003, 0x033, 0x00000001, 0x03F, 0x00000006,
+ 0x033, 0x00000002, 0x03F, 0x00000009, 0x033, 0x00000003,
+ 0x03F, 0x00000026, 0x033, 0x00000004, 0x03F, 0x00000029,
+ 0x033, 0x00000005, 0x03F, 0x0000002C, 0x033, 0x00000006,
+ 0x03F, 0x0000002F, 0x033, 0x00000007, 0x03F, 0x00000033,
+ 0x033, 0x00000008, 0x03F, 0x00000036, 0x033, 0x00000009,
+ 0x03F, 0x00000039, 0x033, 0x0000000A, 0x03F, 0x0000003C,
+ 0xA0000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x0005142C,
+ 0x033, 0x00000001, 0x03F, 0x0005144B, 0x033, 0x00000002,
+ 0x03F, 0x0005144E, 0x033, 0x00000003, 0x03F, 0x00051C69,
+ 0x033, 0x00000004, 0x03F, 0x00051C6C, 0x033, 0x00000005,
+ 0x03F, 0x00051C6F, 0x033, 0x00000006, 0x03F, 0x00051CEB,
+ 0x033, 0x00000007, 0x03F, 0x00051CEE, 0x033, 0x00000008,
+ 0x03F, 0x00051CF1, 0x033, 0x00000009, 0x03F, 0x00051CF4,
+ 0x033, 0x0000000A, 0x03F, 0x00051CF7, 0xB0000000, 0x00000000,
+ 0x0EF, 0x00000000, 0x0EF, 0x00000010, 0x033, 0x00000000,
+ 0x008, 0x0009C060, 0x033, 0x00000001, 0x008, 0x0009C060,
+ 0x0EF, 0x00000000, 0x033, 0x000000A2, 0x0EF, 0x00080000,
+ 0x03E, 0x0000593F, 0x03F, 0x000C0F4F, 0x0EF, 0x00000000,
+ 0x033, 0x000000A3, 0x0EF, 0x00080000, 0x03E, 0x00005934,
+ 0x03F, 0x0005AFCF, 0x0EF, 0x00000000,
+
+};
+
+void odm_read_and_config_mp_8822b_radioa(struct phy_dm_struct *dm)
+{
+ u32 i = 0;
+ u8 c_cond;
+ bool is_matched = true, is_skipped = false;
+ u32 array_len = sizeof(array_mp_8822b_radioa) / sizeof(u32);
+ u32 *array = array_mp_8822b_radioa;
+
+ u32 v1 = 0, v2 = 0, pre_v1 = 0, pre_v2 = 0;
+
+ ODM_RT_TRACE(dm, ODM_COMP_INIT,
+ "===> %s\n", __func__);
+
+ for (; (i + 1) < array_len; i = i + 2) {
+ v1 = array[i];
+ v2 = array[i + 1];
+
+ if (v1 & BIT(31)) { /* positive condition*/
+ c_cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28);
+ if (c_cond == COND_ENDIF) { /*end*/
+ is_matched = true;
+ is_skipped = false;
+ ODM_RT_TRACE(dm, ODM_COMP_INIT, "ENDIF\n");
+ } else if (c_cond == COND_ELSE) { /*else*/
+ is_matched = is_skipped ? false : true;
+ ODM_RT_TRACE(dm, ODM_COMP_INIT, "ELSE\n");
+ } else { /*if , else if*/
+ pre_v1 = v1;
+ pre_v2 = v2;
+ ODM_RT_TRACE(dm, ODM_COMP_INIT,
+ "IF or ELSE IF\n");
+ }
+ } else if (v1 & BIT(30)) { /*negative condition*/
+ if (is_skipped) {
+ is_matched = false;
+ continue;
+ }
+
+ if (check_positive(dm, pre_v1, pre_v2, v1, v2)) {
+ is_matched = true;
+ is_skipped = true;
+ } else {
+ is_matched = false;
+ is_skipped = false;
+ }
+ } else if (is_matched) {
+ odm_config_rf_radio_a_8822b(dm, v1, v2);
+ }
+ }
+}
+
+u32 odm_get_version_mp_8822b_radioa(void) { return 67; }
+
+/******************************************************************************
+ * radiob.TXT
+ ******************************************************************************/
+
+static u32 array_mp_8822b_radiob[] = {
+ 0x000, 0x00030000, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x001, 0x0004002D, 0x9300100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x001, 0x0004002D, 0x9300100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x001, 0x0004002D, 0x9300200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x001, 0x0004002D, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x001, 0x0004002D, 0x9000100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x001, 0x0004002D, 0x9000100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x001, 0x0004002D, 0x9000200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x001, 0x0004002D, 0x9300200c, 0x00000000, 0x40000000, 0x00000000,
+ 0x001, 0x00040029, 0x93012100, 0x00000000, 0x40000000, 0x00000000,
+ 0x001, 0x00040029, 0x93002100, 0x00000000, 0x40000000, 0x00000000,
+ 0x001, 0x00040029, 0x9000200c, 0x00000000, 0x40000000, 0x00000000,
+ 0x001, 0x00040029, 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x001, 0x00040029, 0x93002000, 0x00000000, 0x40000000, 0x00000000,
+ 0x001, 0x00040029, 0x90002100, 0x00000000, 0x40000000, 0x00000000,
+ 0x001, 0x00040029, 0x90002000, 0x00000000, 0x40000000, 0x00000000,
+ 0x001, 0x00040029, 0xA0000000, 0x00000000, 0x001, 0x00040029,
+ 0xB0000000, 0x00000000, 0x018, 0x00010D24, 0x0EF, 0x00080000,
+ 0x033, 0x00000002, 0x03E, 0x0000003F, 0x03F, 0x000C0F4E,
+ 0x033, 0x00000001, 0x03E, 0x00000034, 0x03F, 0x0004080E,
+ 0x0EF, 0x00080000, 0x0DF, 0x00002449, 0x033, 0x00000024,
+ 0x03E, 0x0000003F, 0x03F, 0x00060FDE, 0x0EF, 0x00000000,
+ 0x0EF, 0x00080000, 0x033, 0x00000025, 0x03E, 0x00000037,
+ 0x03F, 0x0007EFCE, 0x0EF, 0x00000000, 0x0EF, 0x00080000,
+ 0x033, 0x00000026, 0x03E, 0x00000037, 0x03F, 0x000DEFCE,
+ 0x0EF, 0x00000000, 0x0DF, 0x00000009, 0x018, 0x00010524,
+ 0x089, 0x00000207, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x08A, 0x000FF186, 0x9300100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x08A, 0x000FE186, 0x9300100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x08A, 0x000FF186, 0x9300200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x08A, 0x000FF186, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x08A, 0x000FF186, 0x9000100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x08A, 0x000FE186, 0xA0000000, 0x00000000, 0x08A, 0x000FF186,
+ 0xB0000000, 0x00000000, 0x08B, 0x00061E3C, 0x08C, 0x000112C7,
+ 0x08D, 0x000F4988, 0x08E, 0x00064D40, 0x0EF, 0x00020000,
+ 0x033, 0x00000007, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x03E, 0x00004040, 0x9300100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x03E, 0x00004080, 0x9300100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x03E, 0x00004040, 0x9300200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x03E, 0x00004040, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x03E, 0x00004040, 0x9000100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x03E, 0x00004080, 0x9000100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x03E, 0x00004040, 0x9000200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x03E, 0x00004040, 0x9300200c, 0x00000000, 0x40000000, 0x00000000,
+ 0x03E, 0x00004040, 0x93012100, 0x00000000, 0x40000000, 0x00000000,
+ 0x03E, 0x00004000, 0x93002100, 0x00000000, 0x40000000, 0x00000000,
+ 0x03E, 0x00004000, 0x93011000, 0x00000000, 0x40000000, 0x00000000,
+ 0x03E, 0x00004000, 0x9000200c, 0x00000000, 0x40000000, 0x00000000,
+ 0x03E, 0x00004040, 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x03E, 0x00004040, 0x93002000, 0x00000000, 0x40000000, 0x00000000,
+ 0x03E, 0x00004000, 0xA0000000, 0x00000000, 0x03E, 0x00004000,
+ 0xB0000000, 0x00000000, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x03F, 0x000C3186, 0x9300100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x03F, 0x000C3186, 0x9300100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x03F, 0x000C3186, 0x9300200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x03F, 0x000C3186, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x03F, 0x000C3186, 0x9000100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x03F, 0x000C3186, 0x9000100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x03F, 0x000C3186, 0x9000200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x03F, 0x000C3186, 0x9300200c, 0x00000000, 0x40000000, 0x00000000,
+ 0x03F, 0x000C3186, 0x93012100, 0x00000000, 0x40000000, 0x00000000,
+ 0x03F, 0x000C3186, 0x93002100, 0x00000000, 0x40000000, 0x00000000,
+ 0x03F, 0x000C0006, 0x93011000, 0x00000000, 0x40000000, 0x00000000,
+ 0x03F, 0x000C3186, 0x9000200c, 0x00000000, 0x40000000, 0x00000000,
+ 0x03F, 0x000C3186, 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x03F, 0x000C3186, 0x93002000, 0x00000000, 0x40000000, 0x00000000,
+ 0x03F, 0x000C0006, 0x93001000, 0x00000000, 0x40000000, 0x00000000,
+ 0x03F, 0x000C3186, 0xA0000000, 0x00000000, 0x03F, 0x000C3186,
+ 0xB0000000, 0x00000000, 0x033, 0x00000006, 0x03E, 0x00004080,
+ 0x03F, 0x000C3186, 0x033, 0x00000005, 0x03E, 0x000040C8,
+ 0x03F, 0x000C3186, 0x033, 0x00000004, 0x03E, 0x00004190,
+ 0x03F, 0x000C3186, 0x033, 0x00000003, 0x03E, 0x00004998,
+ 0x03F, 0x000C3186, 0x033, 0x00000002, 0x03E, 0x00005840,
+ 0x03F, 0x000C3186, 0x033, 0x00000001, 0x03E, 0x000058C2,
+ 0x03F, 0x000C3186, 0x033, 0x00000000, 0x03E, 0x00005930,
+ 0x03F, 0x000C3186, 0x033, 0x0000000F, 0x8300100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x03E, 0x00004080, 0x9300100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x03E, 0x00004080, 0x9000100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x93012100, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x93002100, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x93011000, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x9000200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x90001004, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x93002000, 0x00000000,
+ 0x40000000, 0x00000000, 0x03E, 0x00004000, 0xA0000000, 0x00000000,
+ 0x03E, 0x00004000, 0xB0000000, 0x00000000, 0x8300100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93012100, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93002100, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93011000, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x90001004, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93002000, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C0006, 0x93001000, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0xA0000000, 0x00000000,
+ 0x03F, 0x000C3186, 0xB0000000, 0x00000000, 0x033, 0x0000000E,
+ 0x03E, 0x00004080, 0x03F, 0x000C3186, 0x033, 0x0000000D,
+ 0x03E, 0x000040C8, 0x03F, 0x000C3186, 0x033, 0x0000000C,
+ 0x03E, 0x00004190, 0x03F, 0x000C3186, 0x033, 0x0000000B,
+ 0x03E, 0x00004998, 0x03F, 0x000C3186, 0x033, 0x0000000A,
+ 0x03E, 0x00005840, 0x03F, 0x000C3186, 0x033, 0x00000009,
+ 0x03E, 0x000058C2, 0x03F, 0x000C3186, 0x033, 0x00000008,
+ 0x03E, 0x00005930, 0x03F, 0x000C3186, 0x033, 0x00000017,
+ 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00004040,
+ 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00004080,
+ 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040,
+ 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040,
+ 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00004040,
+ 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00004080,
+ 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040,
+ 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040,
+ 0x9300200c, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040,
+ 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004000,
+ 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004000,
+ 0x93011000, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004000,
+ 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040,
+ 0x93002000, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004000,
+ 0xA0000000, 0x00000000, 0x03E, 0x00004000, 0xB0000000, 0x00000000,
+ 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x9300200c, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000DFF86,
+ 0x93011000, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0x93002000, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C0006,
+ 0x93001000, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186,
+ 0xA0000000, 0x00000000, 0x03F, 0x000C3186, 0xB0000000, 0x00000000,
+ 0x033, 0x00000016, 0x03E, 0x00004080, 0x03F, 0x000C3186,
+ 0x033, 0x00000015, 0x03E, 0x000040C8, 0x03F, 0x000C3186,
+ 0x033, 0x00000014, 0x03E, 0x00004190, 0x03F, 0x000C3186,
+ 0x033, 0x00000013, 0x03E, 0x00004998, 0x03F, 0x000C3186,
+ 0x033, 0x00000012, 0x03E, 0x00005840, 0x03F, 0x000C3186,
+ 0x033, 0x00000011, 0x03E, 0x000058C2, 0x03F, 0x000C3186,
+ 0x033, 0x00000010, 0x03E, 0x00005930, 0x03F, 0x000C3186,
+ 0x0EF, 0x00000000, 0x0EF, 0x00004000, 0x033, 0x00000000,
+ 0x03F, 0x0000000A, 0x033, 0x00000001, 0x8300100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9300100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9300100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9300200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9000100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9000100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9000100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9000200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9300200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x93012100, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000002, 0x93002100, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x93011000, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000005, 0x9000200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x90001004, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x93002000, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x93001000, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000005, 0x90002100, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x90002000, 0x00000000,
+ 0x40000000, 0x00000000, 0x03F, 0x00000000, 0xA0000000, 0x00000000,
+ 0x03F, 0x00000005, 0xB0000000, 0x00000000, 0x033, 0x00000002,
+ 0x03F, 0x00000000, 0x0EF, 0x00000000, 0x018, 0x00000401,
+ 0x084, 0x00001209, 0x086, 0x000001A0, 0x8300100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9300100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9300100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9300200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9000100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9000100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9000100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9000200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x087, 0x00068080, 0xA0000000, 0x00000000,
+ 0x087, 0x000E8180, 0xB0000000, 0x00000000, 0x088, 0x00070020,
+ 0x0DE, 0x00000010, 0x0EF, 0x00008000, 0x033, 0x0000000F,
+ 0x03F, 0x0000003C, 0x033, 0x0000000E, 0x03F, 0x00000038,
+ 0x033, 0x0000000D, 0x03F, 0x00000030, 0x033, 0x0000000C,
+ 0x03F, 0x00000028, 0x033, 0x0000000B, 0x03F, 0x00000020,
+ 0x033, 0x0000000A, 0x03F, 0x00000018, 0x033, 0x00000009,
+ 0x03F, 0x00000010, 0x033, 0x00000008, 0x03F, 0x00000008,
+ 0x033, 0x00000007, 0x03F, 0x0000003C, 0x033, 0x00000006,
+ 0x03F, 0x00000038, 0x033, 0x00000005, 0x03F, 0x00000030,
+ 0x033, 0x00000004, 0x03F, 0x00000028, 0x033, 0x00000003,
+ 0x03F, 0x00000020, 0x033, 0x00000002, 0x03F, 0x00000018,
+ 0x033, 0x00000001, 0x03F, 0x00000010, 0x033, 0x00000000,
+ 0x03F, 0x00000008, 0x0EF, 0x00000000, 0x018, 0x00018D24,
+ 0xFFE, 0x00000000, 0xFFE, 0x00000000, 0xFFE, 0x00000000,
+ 0xFFE, 0x00000000, 0x018, 0x00010D24, 0x01B, 0x00075A40,
+ 0x0EE, 0x00000002, 0x033, 0x00000000, 0x03F, 0x00000004,
+ 0x033, 0x00000001, 0x03F, 0x00000004, 0x033, 0x00000002,
+ 0x03F, 0x00000004, 0x033, 0x00000003, 0x03F, 0x00000004,
+ 0x033, 0x00000004, 0x03F, 0x00000004, 0x033, 0x00000005,
+ 0x03F, 0x00000006, 0x033, 0x00000006, 0x03F, 0x00000002,
+ 0x033, 0x00000007, 0x03F, 0x00000000, 0x0EE, 0x00000000,
+ 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x061, 0x0005D4A0,
+ 0x062, 0x0000D203, 0x063, 0x00000062, 0x9300100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x061, 0x0005D4A0, 0x062, 0x0000D203,
+ 0x063, 0x00000062, 0x9300100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x061, 0x0005D4A0, 0x062, 0x0000D203, 0x063, 0x00000062,
+ 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D2A1,
+ 0x062, 0x0000D3A2, 0x063, 0x00000062, 0x9000100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x061, 0x0005D4A0, 0x062, 0x0000D203,
+ 0x063, 0x00000062, 0x9000100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x061, 0x0005D4A0, 0x062, 0x0000D203, 0x063, 0x00000062,
+ 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D4A0,
+ 0x062, 0x0000D203, 0x063, 0x00000062, 0x9000200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x061, 0x0005D2A1, 0x062, 0x0000D3A2,
+ 0x063, 0x00000062, 0x9300200c, 0x00000000, 0x40000000, 0x00000000,
+ 0x061, 0x0005D2A1, 0x062, 0x0000D3A2, 0x063, 0x00000062,
+ 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D2A1,
+ 0x062, 0x0000D3A2, 0x063, 0x00000002, 0x93002100, 0x00000000,
+ 0x40000000, 0x00000000, 0x061, 0x0005D2A1, 0x062, 0x0000D3A2,
+ 0x063, 0x00000002, 0x93011000, 0x00000000, 0x40000000, 0x00000000,
+ 0x061, 0x0005D3D1, 0x062, 0x0000D3A2, 0x063, 0x00000002,
+ 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D2A1,
+ 0x062, 0x0000D3A2, 0x063, 0x00000062, 0x90001004, 0x00000000,
+ 0x40000000, 0x00000000, 0x061, 0x0005D3D1, 0x062, 0x0000D3A2,
+ 0x063, 0x00000002, 0x93002000, 0x00000000, 0x40000000, 0x00000000,
+ 0x061, 0x0005D2A1, 0x062, 0x0000D3A2, 0x063, 0x00000002,
+ 0x93001000, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D3D1,
+ 0x062, 0x0000D3A2, 0x063, 0x00000002, 0x90002100, 0x00000000,
+ 0x40000000, 0x00000000, 0x061, 0x0005D2A1, 0x062, 0x0000D3A2,
+ 0x063, 0x00000002, 0x90002000, 0x00000000, 0x40000000, 0x00000000,
+ 0x061, 0x0005D2A1, 0x062, 0x0000D3A2, 0x063, 0x00000002,
+ 0xA0000000, 0x00000000, 0x061, 0x0005D3D0, 0x062, 0x0000D303,
+ 0x063, 0x00000002, 0xB0000000, 0x00000000, 0x0EF, 0x00000200,
+ 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x030, 0x000004A3,
+ 0x030, 0x000014A3, 0x030, 0x000024A3, 0x030, 0x000034A3,
+ 0x030, 0x000044A3, 0x030, 0x000054A3, 0x030, 0x000064A3,
+ 0x030, 0x000074A3, 0x030, 0x000084A3, 0x030, 0x000094A3,
+ 0x030, 0x0000A4A3, 0x030, 0x0000B4A3, 0x9300100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x030, 0x000004A3, 0x030, 0x000014A3,
+ 0x030, 0x000024A3, 0x030, 0x000034A3, 0x030, 0x000044A3,
+ 0x030, 0x000054A3, 0x030, 0x000064A3, 0x030, 0x000074A3,
+ 0x030, 0x000084A3, 0x030, 0x000094A3, 0x030, 0x0000A4A3,
+ 0x030, 0x0000B4A3, 0x9300100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x030, 0x000004A3, 0x030, 0x000014A3, 0x030, 0x000024A3,
+ 0x030, 0x000034A3, 0x030, 0x000044A3, 0x030, 0x000054A3,
+ 0x030, 0x000064A3, 0x030, 0x000074A3, 0x030, 0x000084A3,
+ 0x030, 0x000094A3, 0x030, 0x0000A4A3, 0x030, 0x0000B4A3,
+ 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000002A6,
+ 0x030, 0x000012A6, 0x030, 0x000022A6, 0x030, 0x000032A6,
+ 0x030, 0x000042A6, 0x030, 0x000052A6, 0x030, 0x000062A6,
+ 0x030, 0x000072A6, 0x030, 0x000082A6, 0x030, 0x000092A6,
+ 0x030, 0x0000A2A6, 0x030, 0x0000B2A6, 0x9000100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x030, 0x000004A0, 0x030, 0x000014A0,
+ 0x030, 0x000024A0, 0x030, 0x000034A0, 0x030, 0x000044A0,
+ 0x030, 0x000054A0, 0x030, 0x000064A0, 0x030, 0x000074A0,
+ 0x030, 0x000084A0, 0x030, 0x000094A0, 0x030, 0x0000A4A0,
+ 0x030, 0x0000B4A0, 0x9000100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x030, 0x000004A0, 0x030, 0x000014A0, 0x030, 0x000024A0,
+ 0x030, 0x000034A0, 0x030, 0x000044A0, 0x030, 0x000054A0,
+ 0x030, 0x000064A0, 0x030, 0x000074A0, 0x030, 0x000084A0,
+ 0x030, 0x000094A0, 0x030, 0x0000A4A0, 0x030, 0x0000B4A0,
+ 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000004A0,
+ 0x030, 0x000014A0, 0x030, 0x000024A0, 0x030, 0x000034A0,
+ 0x030, 0x000044A0, 0x030, 0x000054A0, 0x030, 0x000064A0,
+ 0x030, 0x000074A0, 0x030, 0x000084A0, 0x030, 0x000094A0,
+ 0x030, 0x0000A4A0, 0x030, 0x0000B4A0, 0x9000200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x030, 0x000002A1, 0x030, 0x000012A1,
+ 0x030, 0x000022A1, 0x030, 0x000032A1, 0x030, 0x000042A1,
+ 0x030, 0x000052A1, 0x030, 0x000062A1, 0x030, 0x000072A1,
+ 0x030, 0x000082A1, 0x030, 0x000092A1, 0x030, 0x0000A2A1,
+ 0x030, 0x0000B2A1, 0x9300200c, 0x00000000, 0x40000000, 0x00000000,
+ 0x030, 0x000002A6, 0x030, 0x000012A6, 0x030, 0x000022A6,
+ 0x030, 0x000032A6, 0x030, 0x000042A6, 0x030, 0x000052A6,
+ 0x030, 0x000062A6, 0x030, 0x000072A6, 0x030, 0x000082A6,
+ 0x030, 0x000092A6, 0x030, 0x0000A2A6, 0x030, 0x0000B2A6,
+ 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000002F4,
+ 0x030, 0x000012F4, 0x030, 0x000022F4, 0x030, 0x000032F4,
+ 0x030, 0x00004365, 0x030, 0x00005365, 0x030, 0x00006365,
+ 0x030, 0x00007365, 0x030, 0x000082A4, 0x030, 0x000092A4,
+ 0x030, 0x0000A2A4, 0x030, 0x0000B2A4, 0x93002100, 0x00000000,
+ 0x40000000, 0x00000000, 0x030, 0x000004A4, 0x030, 0x000014A4,
+ 0x030, 0x000024A4, 0x030, 0x000034A4, 0x030, 0x000043A4,
+ 0x030, 0x000053A4, 0x030, 0x000063A4, 0x030, 0x000073A4,
+ 0x030, 0x000083A5, 0x030, 0x000093A5, 0x030, 0x0000A3A5,
+ 0x030, 0x0000B3A5, 0x93011000, 0x00000000, 0x40000000, 0x00000000,
+ 0x030, 0x000003A1, 0x030, 0x000013A1, 0x030, 0x000023A1,
+ 0x030, 0x000033A1, 0x030, 0x000043A4, 0x030, 0x000053A4,
+ 0x030, 0x000063A4, 0x030, 0x000073A4, 0x030, 0x000083A6,
+ 0x030, 0x000093A6, 0x030, 0x0000A3A6, 0x030, 0x0000B3A6,
+ 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000002A1,
+ 0x030, 0x000012A1, 0x030, 0x000022A1, 0x030, 0x000032A1,
+ 0x030, 0x000042A1, 0x030, 0x000052A1, 0x030, 0x000062A1,
+ 0x030, 0x000072A1, 0x030, 0x000082A1, 0x030, 0x000092A1,
+ 0x030, 0x0000A2A1, 0x030, 0x0000B2A1, 0x90001004, 0x00000000,
+ 0x40000000, 0x00000000, 0x030, 0x00000382, 0x030, 0x00001382,
+ 0x030, 0x00002382, 0x030, 0x00003382, 0x030, 0x00004445,
+ 0x030, 0x00005445, 0x030, 0x00006445, 0x030, 0x00007445,
+ 0x030, 0x00008425, 0x030, 0x00009425, 0x030, 0x0000A425,
+ 0x030, 0x0000B425, 0x93002000, 0x00000000, 0x40000000, 0x00000000,
+ 0x030, 0x00000303, 0x030, 0x00001303, 0x030, 0x00002303,
+ 0x030, 0x00003303, 0x030, 0x000043A4, 0x030, 0x000053A4,
+ 0x030, 0x000063A4, 0x030, 0x000073A4, 0x030, 0x00008365,
+ 0x030, 0x00009365, 0x030, 0x0000A365, 0x030, 0x0000B365,
+ 0x93001000, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000003A1,
+ 0x030, 0x000013A1, 0x030, 0x000023A1, 0x030, 0x000033A1,
+ 0x030, 0x00004364, 0x030, 0x00005364, 0x030, 0x00006364,
+ 0x030, 0x00007364, 0x030, 0x00008564, 0x030, 0x00009564,
+ 0x030, 0x0000A564, 0x030, 0x0000B564, 0x90002100, 0x00000000,
+ 0x40000000, 0x00000000, 0x030, 0x000004A1, 0x030, 0x000014A1,
+ 0x030, 0x000024A1, 0x030, 0x000034A1, 0x030, 0x000043A1,
+ 0x030, 0x000053A1, 0x030, 0x000063A1, 0x030, 0x000073A1,
+ 0x030, 0x000083A1, 0x030, 0x000093A1, 0x030, 0x0000A3A1,
+ 0x030, 0x0000B3A1, 0x90002000, 0x00000000, 0x40000000, 0x00000000,
+ 0x030, 0x000004A0, 0x030, 0x000014A0, 0x030, 0x000024A0,
+ 0x030, 0x000034A0, 0x030, 0x000043A1, 0x030, 0x000053A1,
+ 0x030, 0x000063A1, 0x030, 0x000073A1, 0x030, 0x000083A2,
+ 0x030, 0x000093A2, 0x030, 0x0000A3A2, 0x030, 0x0000B3A2,
+ 0xA0000000, 0x00000000, 0x030, 0x000002D0, 0x030, 0x000012D0,
+ 0x030, 0x000022D0, 0x030, 0x000032D0, 0x030, 0x000042D0,
+ 0x030, 0x000052D0, 0x030, 0x000062D0, 0x030, 0x000072D0,
+ 0x030, 0x000082D0, 0x030, 0x000092D0, 0x030, 0x0000A2D0,
+ 0x030, 0x0000B2D0, 0xB0000000, 0x00000000, 0x0EF, 0x00000000,
+ 0x0EF, 0x00000080, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x030, 0x00000203, 0x030, 0x00001203, 0x030, 0x00002203,
+ 0x030, 0x00003203, 0x030, 0x00004203, 0x030, 0x00005203,
+ 0x030, 0x00006203, 0x030, 0x00007203, 0x030, 0x00008203,
+ 0x030, 0x00009203, 0x030, 0x0000A203, 0x030, 0x0000B203,
+ 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x030, 0x00000203,
+ 0x030, 0x00001203, 0x030, 0x00002203, 0x030, 0x00003203,
+ 0x030, 0x00004203, 0x030, 0x00005203, 0x030, 0x00006203,
+ 0x030, 0x00007203, 0x030, 0x00008203, 0x030, 0x00009203,
+ 0x030, 0x0000A203, 0x030, 0x0000B203, 0x9300100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x030, 0x00000203, 0x030, 0x00001203,
+ 0x030, 0x00002203, 0x030, 0x00003203, 0x030, 0x00004203,
+ 0x030, 0x00005203, 0x030, 0x00006203, 0x030, 0x00007203,
+ 0x030, 0x00008203, 0x030, 0x00009203, 0x030, 0x0000A203,
+ 0x030, 0x0000B203, 0x9300200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x030, 0x000003A2, 0x030, 0x000013A2, 0x030, 0x000023A2,
+ 0x030, 0x000033A2, 0x030, 0x000043A2, 0x030, 0x000053A2,
+ 0x030, 0x000063A2, 0x030, 0x000073A2, 0x030, 0x000083A2,
+ 0x030, 0x000093A2, 0x030, 0x0000A3A2, 0x030, 0x0000B3A2,
+ 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x030, 0x00000203,
+ 0x030, 0x00001203, 0x030, 0x00002203, 0x030, 0x00003203,
+ 0x030, 0x00004203, 0x030, 0x00005203, 0x030, 0x00006203,
+ 0x030, 0x00007203, 0x030, 0x00008203, 0x030, 0x00009203,
+ 0x030, 0x0000A203, 0x030, 0x0000B203, 0x9000100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x030, 0x00000203, 0x030, 0x00001203,
+ 0x030, 0x00002203, 0x030, 0x00003203, 0x030, 0x00004203,
+ 0x030, 0x00005203, 0x030, 0x00006203, 0x030, 0x00007203,
+ 0x030, 0x00008203, 0x030, 0x00009203, 0x030, 0x0000A203,
+ 0x030, 0x0000B203, 0x9000100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x030, 0x00000203, 0x030, 0x00001203, 0x030, 0x00002203,
+ 0x030, 0x00003203, 0x030, 0x00004203, 0x030, 0x00005203,
+ 0x030, 0x00006203, 0x030, 0x00007203, 0x030, 0x00008203,
+ 0x030, 0x00009203, 0x030, 0x0000A203, 0x030, 0x0000B203,
+ 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000003A2,
+ 0x030, 0x000013A2, 0x030, 0x000023A2, 0x030, 0x000033A2,
+ 0x030, 0x000043A2, 0x030, 0x000053A2, 0x030, 0x000063A2,
+ 0x030, 0x000073A2, 0x030, 0x000083A2, 0x030, 0x000093A2,
+ 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, 0x9300200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x030, 0x000003A2, 0x030, 0x000013A2,
+ 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2,
+ 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2,
+ 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2,
+ 0x030, 0x0000B3A2, 0x93012100, 0x00000000, 0x40000000, 0x00000000,
+ 0x030, 0x000003A3, 0x030, 0x000013A3, 0x030, 0x000023A3,
+ 0x030, 0x000033A3, 0x030, 0x000043A4, 0x030, 0x000053A4,
+ 0x030, 0x000063A4, 0x030, 0x000073A4, 0x030, 0x000083A3,
+ 0x030, 0x000093A3, 0x030, 0x0000A3A3, 0x030, 0x0000B3A3,
+ 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000003A2,
+ 0x030, 0x000013A2, 0x030, 0x000023A2, 0x030, 0x000033A2,
+ 0x030, 0x000043A2, 0x030, 0x000053A2, 0x030, 0x000063A2,
+ 0x030, 0x000073A2, 0x030, 0x000083A2, 0x030, 0x000093A2,
+ 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, 0x93011000, 0x00000000,
+ 0x40000000, 0x00000000, 0x030, 0x000003A2, 0x030, 0x000013A2,
+ 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2,
+ 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2,
+ 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2,
+ 0x030, 0x0000B3A2, 0x9000200c, 0x00000000, 0x40000000, 0x00000000,
+ 0x030, 0x000003A2, 0x030, 0x000013A2, 0x030, 0x000023A2,
+ 0x030, 0x000033A2, 0x030, 0x000043A2, 0x030, 0x000053A2,
+ 0x030, 0x000063A2, 0x030, 0x000073A2, 0x030, 0x000083A2,
+ 0x030, 0x000093A2, 0x030, 0x0000A3A2, 0x030, 0x0000B3A2,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000003A2,
+ 0x030, 0x000013A2, 0x030, 0x000023A2, 0x030, 0x000033A2,
+ 0x030, 0x000043A2, 0x030, 0x000053A2, 0x030, 0x000063A2,
+ 0x030, 0x000073A2, 0x030, 0x000083A2, 0x030, 0x000093A2,
+ 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, 0x93002000, 0x00000000,
+ 0x40000000, 0x00000000, 0x030, 0x000003A2, 0x030, 0x000013A2,
+ 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2,
+ 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2,
+ 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2,
+ 0x030, 0x0000B3A2, 0x93001000, 0x00000000, 0x40000000, 0x00000000,
+ 0x030, 0x000003A2, 0x030, 0x000013A2, 0x030, 0x000023A2,
+ 0x030, 0x000033A2, 0x030, 0x000043A2, 0x030, 0x000053A2,
+ 0x030, 0x000063A2, 0x030, 0x000073A2, 0x030, 0x000083A2,
+ 0x030, 0x000093A2, 0x030, 0x0000A3A2, 0x030, 0x0000B3A2,
+ 0x90002100, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000003A2,
+ 0x030, 0x000013A2, 0x030, 0x000023A2, 0x030, 0x000033A2,
+ 0x030, 0x000043A2, 0x030, 0x000053A2, 0x030, 0x000063A2,
+ 0x030, 0x000073A2, 0x030, 0x000083A2, 0x030, 0x000093A2,
+ 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, 0x90002000, 0x00000000,
+ 0x40000000, 0x00000000, 0x030, 0x000003A2, 0x030, 0x000013A2,
+ 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2,
+ 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2,
+ 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2,
+ 0x030, 0x0000B3A2, 0xA0000000, 0x00000000, 0x030, 0x000003A2,
+ 0x030, 0x000013A2, 0x030, 0x000023A2, 0x030, 0x000033A2,
+ 0x030, 0x000043A2, 0x030, 0x000053A2, 0x030, 0x000063A2,
+ 0x030, 0x000073A2, 0x030, 0x000083A2, 0x030, 0x000093A2,
+ 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, 0xB0000000, 0x00000000,
+ 0x0EF, 0x00000000, 0x0EF, 0x00000040, 0x8300100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x030, 0x00000645, 0x030, 0x00001333,
+ 0x030, 0x00002011, 0x030, 0x00004000, 0x030, 0x00005000,
+ 0x030, 0x00006000, 0x9300100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x030, 0x00000645, 0x030, 0x00001333, 0x030, 0x00002011,
+ 0x030, 0x00004000, 0x030, 0x00005000, 0x030, 0x00006000,
+ 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x00000645,
+ 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000,
+ 0x030, 0x00005000, 0x030, 0x00006000, 0x9300200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x030, 0x00000645, 0x030, 0x00001333,
+ 0x030, 0x00002011, 0x030, 0x00004777, 0x030, 0x00005777,
+ 0x030, 0x00006777, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x030, 0x00000645, 0x030, 0x00001333, 0x030, 0x00002011,
+ 0x030, 0x00004000, 0x030, 0x00005000, 0x030, 0x00006000,
+ 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x030, 0x00000645,
+ 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000,
+ 0x030, 0x00005000, 0x030, 0x00006000, 0x9000100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x030, 0x00000645, 0x030, 0x00001333,
+ 0x030, 0x00002011, 0x030, 0x00004000, 0x030, 0x00005000,
+ 0x030, 0x00006000, 0x9000200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x030, 0x00000645, 0x030, 0x00001333, 0x030, 0x00002011,
+ 0x030, 0x00004000, 0x030, 0x00005000, 0x030, 0x00006000,
+ 0x9300200c, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x00000645,
+ 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004777,
+ 0x030, 0x00005777, 0x030, 0x00006777, 0x93012100, 0x00000000,
+ 0x40000000, 0x00000000, 0x030, 0x00000660, 0x030, 0x00001341,
+ 0x030, 0x00002220, 0x030, 0x00004777, 0x030, 0x00005777,
+ 0x030, 0x00006777, 0x93002100, 0x00000000, 0x40000000, 0x00000000,
+ 0x030, 0x00000764, 0x030, 0x00001452, 0x030, 0x00002220,
+ 0x030, 0x00004777, 0x030, 0x00005777, 0x030, 0x00006777,
+ 0x93011000, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x00000764,
+ 0x030, 0x00001632, 0x030, 0x00002421, 0x030, 0x00004000,
+ 0x030, 0x00005000, 0x030, 0x00006000, 0x9000200c, 0x00000000,
+ 0x40000000, 0x00000000, 0x030, 0x00000645, 0x030, 0x00001333,
+ 0x030, 0x00002011, 0x030, 0x00004000, 0x030, 0x00005000,
+ 0x030, 0x00006000, 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x030, 0x00000764, 0x030, 0x00001632, 0x030, 0x00002421,
+ 0x030, 0x00004000, 0x030, 0x00005000, 0x030, 0x00006000,
+ 0x93002000, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x00000777,
+ 0x030, 0x00001442, 0x030, 0x00002222, 0x030, 0x00004777,
+ 0x030, 0x00005777, 0x030, 0x00006777, 0x93001000, 0x00000000,
+ 0x40000000, 0x00000000, 0x030, 0x00000764, 0x030, 0x00001632,
+ 0x030, 0x00002421, 0x030, 0x00004000, 0x030, 0x00005000,
+ 0x030, 0x00006000, 0x90002100, 0x00000000, 0x40000000, 0x00000000,
+ 0x030, 0x00000775, 0x030, 0x00001222, 0x030, 0x00002210,
+ 0x030, 0x00004000, 0x030, 0x00005000, 0x030, 0x00006000,
+ 0x90002000, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x00000775,
+ 0x030, 0x00001422, 0x030, 0x00002210, 0x030, 0x00004000,
+ 0x030, 0x00005000, 0x030, 0x00006000, 0xA0000000, 0x00000000,
+ 0x030, 0x00000764, 0x030, 0x00001632, 0x030, 0x00002421,
+ 0x030, 0x00004000, 0x030, 0x00005000, 0x030, 0x00006000,
+ 0xB0000000, 0x00000000, 0x0EF, 0x00000000, 0x0EF, 0x00000800,
+ 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000020,
+ 0x03F, 0x00000007, 0x033, 0x00000021, 0x03F, 0x0000000A,
+ 0x033, 0x00000022, 0x03F, 0x0000000D, 0x033, 0x00000023,
+ 0x03F, 0x0000002A, 0x033, 0x00000024, 0x03F, 0x0000002D,
+ 0x033, 0x00000025, 0x03F, 0x00000030, 0x033, 0x00000026,
+ 0x03F, 0x0000006D, 0x033, 0x00000027, 0x03F, 0x00000070,
+ 0x033, 0x00000028, 0x03F, 0x000000ED, 0x033, 0x00000029,
+ 0x03F, 0x000000F0, 0x033, 0x0000002A, 0x03F, 0x000000F3,
+ 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000020,
+ 0x03F, 0x00000007, 0x033, 0x00000021, 0x03F, 0x0000000A,
+ 0x033, 0x00000022, 0x03F, 0x0000000D, 0x033, 0x00000023,
+ 0x03F, 0x0000002A, 0x033, 0x00000024, 0x03F, 0x0000002D,
+ 0x033, 0x00000025, 0x03F, 0x00000030, 0x033, 0x00000026,
+ 0x03F, 0x0000006D, 0x033, 0x00000027, 0x03F, 0x00000070,
+ 0x033, 0x00000028, 0x03F, 0x000000ED, 0x033, 0x00000029,
+ 0x03F, 0x000000F0, 0x033, 0x0000002A, 0x03F, 0x000000F3,
+ 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020,
+ 0x03F, 0x00000007, 0x033, 0x00000021, 0x03F, 0x0000000A,
+ 0x033, 0x00000022, 0x03F, 0x0000000D, 0x033, 0x00000023,
+ 0x03F, 0x0000002A, 0x033, 0x00000024, 0x03F, 0x0000002D,
+ 0x033, 0x00000025, 0x03F, 0x00000030, 0x033, 0x00000026,
+ 0x03F, 0x0000006D, 0x033, 0x00000027, 0x03F, 0x00000070,
+ 0x033, 0x00000028, 0x03F, 0x000000ED, 0x033, 0x00000029,
+ 0x03F, 0x000000F0, 0x033, 0x0000002A, 0x03F, 0x000000F3,
+ 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020,
+ 0x03F, 0x00000005, 0x033, 0x00000021, 0x03F, 0x00000008,
+ 0x033, 0x00000022, 0x03F, 0x0000000B, 0x033, 0x00000023,
+ 0x03F, 0x0000000E, 0x033, 0x00000024, 0x03F, 0x0000002B,
+ 0x033, 0x00000025, 0x03F, 0x00000068, 0x033, 0x00000026,
+ 0x03F, 0x0000006B, 0x033, 0x00000027, 0x03F, 0x0000006E,
+ 0x033, 0x00000028, 0x03F, 0x00000071, 0x033, 0x00000029,
+ 0x03F, 0x00000074, 0x033, 0x0000002A, 0x03F, 0x00000077,
+ 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000020,
+ 0x03F, 0x00000007, 0x033, 0x00000021, 0x03F, 0x0000000A,
+ 0x033, 0x00000022, 0x03F, 0x0000000D, 0x033, 0x00000023,
+ 0x03F, 0x0000002A, 0x033, 0x00000024, 0x03F, 0x0000002D,
+ 0x033, 0x00000025, 0x03F, 0x00000030, 0x033, 0x00000026,
+ 0x03F, 0x0000006D, 0x033, 0x00000027, 0x03F, 0x00000070,
+ 0x033, 0x00000028, 0x03F, 0x000000ED, 0x033, 0x00000029,
+ 0x03F, 0x000000F0, 0x033, 0x0000002A, 0x03F, 0x000000F3,
+ 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000020,
+ 0x03F, 0x00000007, 0x033, 0x00000021, 0x03F, 0x0000000A,
+ 0x033, 0x00000022, 0x03F, 0x0000000D, 0x033, 0x00000023,
+ 0x03F, 0x0000002A, 0x033, 0x00000024, 0x03F, 0x0000002D,
+ 0x033, 0x00000025, 0x03F, 0x00000030, 0x033, 0x00000026,
+ 0x03F, 0x0000006D, 0x033, 0x00000027, 0x03F, 0x00000070,
+ 0x033, 0x00000028, 0x03F, 0x000000ED, 0x033, 0x00000029,
+ 0x03F, 0x000000F0, 0x033, 0x0000002A, 0x03F, 0x000000F3,
+ 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020,
+ 0x03F, 0x00000007, 0x033, 0x00000021, 0x03F, 0x0000000A,
+ 0x033, 0x00000022, 0x03F, 0x0000000D, 0x033, 0x00000023,
+ 0x03F, 0x0000002A, 0x033, 0x00000024, 0x03F, 0x0000002D,
+ 0x033, 0x00000025, 0x03F, 0x00000030, 0x033, 0x00000026,
+ 0x03F, 0x0000006D, 0x033, 0x00000027, 0x03F, 0x00000070,
+ 0x033, 0x00000028, 0x03F, 0x000000ED, 0x033, 0x00000029,
+ 0x03F, 0x000000F0, 0x033, 0x0000002A, 0x03F, 0x000000F3,
+ 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020,
+ 0x03F, 0x00000005, 0x033, 0x00000021, 0x03F, 0x00000008,
+ 0x033, 0x00000022, 0x03F, 0x0000000B, 0x033, 0x00000023,
+ 0x03F, 0x0000000E, 0x033, 0x00000024, 0x03F, 0x0000002B,
+ 0x033, 0x00000025, 0x03F, 0x00000068, 0x033, 0x00000026,
+ 0x03F, 0x0000006B, 0x033, 0x00000027, 0x03F, 0x0000006E,
+ 0x033, 0x00000028, 0x03F, 0x00000071, 0x033, 0x00000029,
+ 0x03F, 0x00000074, 0x033, 0x0000002A, 0x03F, 0x00000077,
+ 0x9300200c, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020,
+ 0x03F, 0x00000005, 0x033, 0x00000021, 0x03F, 0x00000008,
+ 0x033, 0x00000022, 0x03F, 0x0000000B, 0x033, 0x00000023,
+ 0x03F, 0x0000000E, 0x033, 0x00000024, 0x03F, 0x0000002B,
+ 0x033, 0x00000025, 0x03F, 0x00000068, 0x033, 0x00000026,
+ 0x03F, 0x0000006B, 0x033, 0x00000027, 0x03F, 0x0000006E,
+ 0x033, 0x00000028, 0x03F, 0x00000071, 0x033, 0x00000029,
+ 0x03F, 0x00000074, 0x033, 0x0000002A, 0x03F, 0x00000077,
+ 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020,
+ 0x03F, 0x00000828, 0x033, 0x00000021, 0x03F, 0x0000082B,
+ 0x033, 0x00000022, 0x03F, 0x00000868, 0x033, 0x00000023,
+ 0x03F, 0x00000889, 0x033, 0x00000024, 0x03F, 0x000008AA,
+ 0x033, 0x00000025, 0x03F, 0x00000CE8, 0x033, 0x00000026,
+ 0x03F, 0x00000CEB, 0x033, 0x00000027, 0x03F, 0x00000CEE,
+ 0x033, 0x00000028, 0x03F, 0x00000CF1, 0x033, 0x00000029,
+ 0x03F, 0x00000CF4, 0x033, 0x0000002A, 0x03F, 0x00000CF7,
+ 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020,
+ 0x03F, 0x0000042A, 0x033, 0x00000021, 0x03F, 0x00000829,
+ 0x033, 0x00000022, 0x03F, 0x00000848, 0x033, 0x00000023,
+ 0x03F, 0x0000084B, 0x033, 0x00000024, 0x03F, 0x00000C4C,
+ 0x033, 0x00000025, 0x03F, 0x00000C8B, 0x033, 0x00000026,
+ 0x03F, 0x00000CEA, 0x033, 0x00000027, 0x03F, 0x00000CED,
+ 0x033, 0x00000028, 0x03F, 0x00000CF0, 0x033, 0x00000029,
+ 0x03F, 0x00000CF3, 0x033, 0x0000002A, 0x03F, 0x00000CF6,
+ 0x93011000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020,
+ 0x03F, 0x00000C09, 0x033, 0x00000021, 0x03F, 0x00000C0C,
+ 0x033, 0x00000022, 0x03F, 0x00000C0F, 0x033, 0x00000023,
+ 0x03F, 0x00000C2C, 0x033, 0x00000024, 0x03F, 0x00000C2F,
+ 0x033, 0x00000025, 0x03F, 0x00000C8A, 0x033, 0x00000026,
+ 0x03F, 0x00000C8D, 0x033, 0x00000027, 0x03F, 0x00000C90,
+ 0x033, 0x00000028, 0x03F, 0x00000CD0, 0x033, 0x00000029,
+ 0x03F, 0x00000CF2, 0x033, 0x0000002A, 0x03F, 0x00000CF5,
+ 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020,
+ 0x03F, 0x00000005, 0x033, 0x00000021, 0x03F, 0x00000008,
+ 0x033, 0x00000022, 0x03F, 0x0000000B, 0x033, 0x00000023,
+ 0x03F, 0x0000000E, 0x033, 0x00000024, 0x03F, 0x0000002B,
+ 0x033, 0x00000025, 0x03F, 0x00000068, 0x033, 0x00000026,
+ 0x03F, 0x0000006B, 0x033, 0x00000027, 0x03F, 0x0000006E,
+ 0x033, 0x00000028, 0x03F, 0x00000071, 0x033, 0x00000029,
+ 0x03F, 0x00000074, 0x033, 0x0000002A, 0x03F, 0x00000077,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020,
+ 0x03F, 0x00000C09, 0x033, 0x00000021, 0x03F, 0x00000C0C,
+ 0x033, 0x00000022, 0x03F, 0x00000C0F, 0x033, 0x00000023,
+ 0x03F, 0x00000C2C, 0x033, 0x00000024, 0x03F, 0x00000C2F,
+ 0x033, 0x00000025, 0x03F, 0x00000C8A, 0x033, 0x00000026,
+ 0x03F, 0x00000C8D, 0x033, 0x00000027, 0x03F, 0x00000C90,
+ 0x033, 0x00000028, 0x03F, 0x00000CD0, 0x033, 0x00000029,
+ 0x03F, 0x00000CF2, 0x033, 0x0000002A, 0x03F, 0x00000CF5,
+ 0x93002000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020,
+ 0x03F, 0x00000429, 0x033, 0x00000021, 0x03F, 0x00000828,
+ 0x033, 0x00000022, 0x03F, 0x00000847, 0x033, 0x00000023,
+ 0x03F, 0x0000084A, 0x033, 0x00000024, 0x03F, 0x00000C4B,
+ 0x033, 0x00000025, 0x03F, 0x00000C8A, 0x033, 0x00000026,
+ 0x03F, 0x00000CEA, 0x033, 0x00000027, 0x03F, 0x00000CED,
+ 0x033, 0x00000028, 0x03F, 0x00000CF0, 0x033, 0x00000029,
+ 0x03F, 0x00000CF3, 0x033, 0x0000002A, 0x03F, 0x00000CF6,
+ 0x93001000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020,
+ 0x03F, 0x00000C09, 0x033, 0x00000021, 0x03F, 0x00000C0C,
+ 0x033, 0x00000022, 0x03F, 0x00000C0F, 0x033, 0x00000023,
+ 0x03F, 0x00000C2C, 0x033, 0x00000024, 0x03F, 0x00000C2F,
+ 0x033, 0x00000025, 0x03F, 0x00000C8A, 0x033, 0x00000026,
+ 0x03F, 0x00000C8D, 0x033, 0x00000027, 0x03F, 0x00000C90,
+ 0x033, 0x00000028, 0x03F, 0x00000CD0, 0x033, 0x00000029,
+ 0x03F, 0x00000CF2, 0x033, 0x0000002A, 0x03F, 0x00000CF5,
+ 0x90002100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020,
+ 0x03F, 0x0000042B, 0x033, 0x00000021, 0x03F, 0x0000082A,
+ 0x033, 0x00000022, 0x03F, 0x00000849, 0x033, 0x00000023,
+ 0x03F, 0x0000084C, 0x033, 0x00000024, 0x03F, 0x00000C4C,
+ 0x033, 0x00000025, 0x03F, 0x00000C8A, 0x033, 0x00000026,
+ 0x03F, 0x00000C8D, 0x033, 0x00000027, 0x03F, 0x00000CEB,
+ 0x033, 0x00000028, 0x03F, 0x00000CEE, 0x033, 0x00000029,
+ 0x03F, 0x00000CF1, 0x033, 0x0000002A, 0x03F, 0x00000CF4,
+ 0x90002000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020,
+ 0x03F, 0x0000042B, 0x033, 0x00000021, 0x03F, 0x0000082A,
+ 0x033, 0x00000022, 0x03F, 0x00000849, 0x033, 0x00000023,
+ 0x03F, 0x0000084C, 0x033, 0x00000024, 0x03F, 0x00000C4C,
+ 0x033, 0x00000025, 0x03F, 0x00000C8A, 0x033, 0x00000026,
+ 0x03F, 0x00000C8D, 0x033, 0x00000027, 0x03F, 0x00000CEB,
+ 0x033, 0x00000028, 0x03F, 0x00000CEE, 0x033, 0x00000029,
+ 0x03F, 0x00000CF1, 0x033, 0x0000002A, 0x03F, 0x00000CF4,
+ 0xA0000000, 0x00000000, 0x033, 0x00000020, 0x03F, 0x00000C09,
+ 0x033, 0x00000021, 0x03F, 0x00000C0C, 0x033, 0x00000022,
+ 0x03F, 0x00000C0F, 0x033, 0x00000023, 0x03F, 0x00000C2C,
+ 0x033, 0x00000024, 0x03F, 0x00000C2F, 0x033, 0x00000025,
+ 0x03F, 0x00000C8A, 0x033, 0x00000026, 0x03F, 0x00000C8D,
+ 0x033, 0x00000027, 0x03F, 0x00000C90, 0x033, 0x00000028,
+ 0x03F, 0x00000CD0, 0x033, 0x00000029, 0x03F, 0x00000CF2,
+ 0x033, 0x0000002A, 0x03F, 0x00000CF5, 0xB0000000, 0x00000000,
+ 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000060,
+ 0x03F, 0x00000007, 0x033, 0x00000061, 0x03F, 0x0000000A,
+ 0x033, 0x00000062, 0x03F, 0x0000000D, 0x033, 0x00000063,
+ 0x03F, 0x0000002A, 0x033, 0x00000064, 0x03F, 0x0000002D,
+ 0x033, 0x00000065, 0x03F, 0x00000030, 0x033, 0x00000066,
+ 0x03F, 0x0000006D, 0x033, 0x00000067, 0x03F, 0x00000070,
+ 0x033, 0x00000068, 0x03F, 0x000000ED, 0x033, 0x00000069,
+ 0x03F, 0x000000F0, 0x033, 0x0000006A, 0x03F, 0x000000F3,
+ 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000060,
+ 0x03F, 0x00000007, 0x033, 0x00000061, 0x03F, 0x0000000A,
+ 0x033, 0x00000062, 0x03F, 0x0000000D, 0x033, 0x00000063,
+ 0x03F, 0x0000002A, 0x033, 0x00000064, 0x03F, 0x0000002D,
+ 0x033, 0x00000065, 0x03F, 0x00000030, 0x033, 0x00000066,
+ 0x03F, 0x0000006D, 0x033, 0x00000067, 0x03F, 0x00000070,
+ 0x033, 0x00000068, 0x03F, 0x000000ED, 0x033, 0x00000069,
+ 0x03F, 0x000000F0, 0x033, 0x0000006A, 0x03F, 0x000000F3,
+ 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060,
+ 0x03F, 0x00000007, 0x033, 0x00000061, 0x03F, 0x0000000A,
+ 0x033, 0x00000062, 0x03F, 0x0000000D, 0x033, 0x00000063,
+ 0x03F, 0x0000002A, 0x033, 0x00000064, 0x03F, 0x0000002D,
+ 0x033, 0x00000065, 0x03F, 0x00000030, 0x033, 0x00000066,
+ 0x03F, 0x0000006D, 0x033, 0x00000067, 0x03F, 0x00000070,
+ 0x033, 0x00000068, 0x03F, 0x000000ED, 0x033, 0x00000069,
+ 0x03F, 0x000000F0, 0x033, 0x0000006A, 0x03F, 0x000000F3,
+ 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060,
+ 0x03F, 0x00000005, 0x033, 0x00000061, 0x03F, 0x00000008,
+ 0x033, 0x00000062, 0x03F, 0x0000000B, 0x033, 0x00000063,
+ 0x03F, 0x0000000E, 0x033, 0x00000064, 0x03F, 0x0000002B,
+ 0x033, 0x00000065, 0x03F, 0x00000068, 0x033, 0x00000066,
+ 0x03F, 0x0000006B, 0x033, 0x00000067, 0x03F, 0x0000006E,
+ 0x033, 0x00000068, 0x03F, 0x00000071, 0x033, 0x00000069,
+ 0x03F, 0x00000074, 0x033, 0x0000006A, 0x03F, 0x00000077,
+ 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000060,
+ 0x03F, 0x00000007, 0x033, 0x00000061, 0x03F, 0x0000000A,
+ 0x033, 0x00000062, 0x03F, 0x0000000D, 0x033, 0x00000063,
+ 0x03F, 0x0000002A, 0x033, 0x00000064, 0x03F, 0x0000002D,
+ 0x033, 0x00000065, 0x03F, 0x00000030, 0x033, 0x00000066,
+ 0x03F, 0x0000006D, 0x033, 0x00000067, 0x03F, 0x00000070,
+ 0x033, 0x00000068, 0x03F, 0x000000ED, 0x033, 0x00000069,
+ 0x03F, 0x000000F0, 0x033, 0x0000006A, 0x03F, 0x000000F3,
+ 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000060,
+ 0x03F, 0x00000007, 0x033, 0x00000061, 0x03F, 0x0000000A,
+ 0x033, 0x00000062, 0x03F, 0x0000000D, 0x033, 0x00000063,
+ 0x03F, 0x0000002A, 0x033, 0x00000064, 0x03F, 0x0000002D,
+ 0x033, 0x00000065, 0x03F, 0x00000030, 0x033, 0x00000066,
+ 0x03F, 0x0000006D, 0x033, 0x00000067, 0x03F, 0x00000070,
+ 0x033, 0x00000068, 0x03F, 0x000000ED, 0x033, 0x00000069,
+ 0x03F, 0x000000F0, 0x033, 0x0000006A, 0x03F, 0x000000F3,
+ 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060,
+ 0x03F, 0x00000007, 0x033, 0x00000061, 0x03F, 0x0000000A,
+ 0x033, 0x00000062, 0x03F, 0x0000000D, 0x033, 0x00000063,
+ 0x03F, 0x0000002A, 0x033, 0x00000064, 0x03F, 0x0000002D,
+ 0x033, 0x00000065, 0x03F, 0x00000030, 0x033, 0x00000066,
+ 0x03F, 0x0000006D, 0x033, 0x00000067, 0x03F, 0x00000070,
+ 0x033, 0x00000068, 0x03F, 0x000000ED, 0x033, 0x00000069,
+ 0x03F, 0x000000F0, 0x033, 0x0000006A, 0x03F, 0x000000F3,
+ 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060,
+ 0x03F, 0x00000005, 0x033, 0x00000061, 0x03F, 0x00000008,
+ 0x033, 0x00000062, 0x03F, 0x0000000B, 0x033, 0x00000063,
+ 0x03F, 0x0000000E, 0x033, 0x00000064, 0x03F, 0x0000002B,
+ 0x033, 0x00000065, 0x03F, 0x00000068, 0x033, 0x00000066,
+ 0x03F, 0x0000006B, 0x033, 0x00000067, 0x03F, 0x0000006E,
+ 0x033, 0x00000068, 0x03F, 0x00000071, 0x033, 0x00000069,
+ 0x03F, 0x00000074, 0x033, 0x0000006A, 0x03F, 0x00000077,
+ 0x9300200c, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060,
+ 0x03F, 0x00000005, 0x033, 0x00000061, 0x03F, 0x00000008,
+ 0x033, 0x00000062, 0x03F, 0x0000000B, 0x033, 0x00000063,
+ 0x03F, 0x0000000E, 0x033, 0x00000064, 0x03F, 0x0000002B,
+ 0x033, 0x00000065, 0x03F, 0x00000068, 0x033, 0x00000066,
+ 0x03F, 0x0000006B, 0x033, 0x00000067, 0x03F, 0x0000006E,
+ 0x033, 0x00000068, 0x03F, 0x00000071, 0x033, 0x00000069,
+ 0x03F, 0x00000074, 0x033, 0x0000006A, 0x03F, 0x00000077,
+ 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060,
+ 0x03F, 0x00000842, 0x033, 0x00000061, 0x03F, 0x00000845,
+ 0x033, 0x00000062, 0x03F, 0x00000866, 0x033, 0x00000063,
+ 0x03F, 0x000008A6, 0x033, 0x00000064, 0x03F, 0x000008C8,
+ 0x033, 0x00000065, 0x03F, 0x00000CE8, 0x033, 0x00000066,
+ 0x03F, 0x00000CEB, 0x033, 0x00000067, 0x03F, 0x00000CEE,
+ 0x033, 0x00000068, 0x03F, 0x00000CF1, 0x033, 0x00000069,
+ 0x03F, 0x00000CF4, 0x033, 0x0000006A, 0x03F, 0x00000CF7,
+ 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060,
+ 0x03F, 0x0000042A, 0x033, 0x00000061, 0x03F, 0x00000829,
+ 0x033, 0x00000062, 0x03F, 0x00000848, 0x033, 0x00000063,
+ 0x03F, 0x0000084B, 0x033, 0x00000064, 0x03F, 0x00000C69,
+ 0x033, 0x00000065, 0x03F, 0x00000CA9, 0x033, 0x00000066,
+ 0x03F, 0x00000CEA, 0x033, 0x00000067, 0x03F, 0x00000CED,
+ 0x033, 0x00000068, 0x03F, 0x00000CF0, 0x033, 0x00000069,
+ 0x03F, 0x00000CF3, 0x033, 0x0000006A, 0x03F, 0x00000CF6,
+ 0x93011000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060,
+ 0x03F, 0x00000C0A, 0x033, 0x00000061, 0x03F, 0x00000C0D,
+ 0x033, 0x00000062, 0x03F, 0x00000C2A, 0x033, 0x00000063,
+ 0x03F, 0x00000C2D, 0x033, 0x00000064, 0x03F, 0x00000C6A,
+ 0x033, 0x00000065, 0x03F, 0x00000CAA, 0x033, 0x00000066,
+ 0x03F, 0x00000CAD, 0x033, 0x00000067, 0x03F, 0x00000CB0,
+ 0x033, 0x00000068, 0x03F, 0x00000CF1, 0x033, 0x00000069,
+ 0x03F, 0x00000CF4, 0x033, 0x0000006A, 0x03F, 0x00000CF7,
+ 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060,
+ 0x03F, 0x00000005, 0x033, 0x00000061, 0x03F, 0x00000008,
+ 0x033, 0x00000062, 0x03F, 0x0000000B, 0x033, 0x00000063,
+ 0x03F, 0x0000000E, 0x033, 0x00000064, 0x03F, 0x0000002B,
+ 0x033, 0x00000065, 0x03F, 0x00000068, 0x033, 0x00000066,
+ 0x03F, 0x0000006B, 0x033, 0x00000067, 0x03F, 0x0000006E,
+ 0x033, 0x00000068, 0x03F, 0x00000071, 0x033, 0x00000069,
+ 0x03F, 0x00000074, 0x033, 0x0000006A, 0x03F, 0x00000077,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060,
+ 0x03F, 0x00000C0A, 0x033, 0x00000061, 0x03F, 0x00000C0D,
+ 0x033, 0x00000062, 0x03F, 0x00000C2A, 0x033, 0x00000063,
+ 0x03F, 0x00000C2D, 0x033, 0x00000064, 0x03F, 0x00000C6A,
+ 0x033, 0x00000065, 0x03F, 0x00000CAA, 0x033, 0x00000066,
+ 0x03F, 0x00000CAD, 0x033, 0x00000067, 0x03F, 0x00000CB0,
+ 0x033, 0x00000068, 0x03F, 0x00000CF1, 0x033, 0x00000069,
+ 0x03F, 0x00000CF4, 0x033, 0x0000006A, 0x03F, 0x00000CF7,
+ 0x93002000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060,
+ 0x03F, 0x00000429, 0x033, 0x00000061, 0x03F, 0x00000828,
+ 0x033, 0x00000062, 0x03F, 0x00000847, 0x033, 0x00000063,
+ 0x03F, 0x0000084A, 0x033, 0x00000064, 0x03F, 0x00000C4B,
+ 0x033, 0x00000065, 0x03F, 0x00000C8A, 0x033, 0x00000066,
+ 0x03F, 0x00000CEA, 0x033, 0x00000067, 0x03F, 0x00000CED,
+ 0x033, 0x00000068, 0x03F, 0x00000CF0, 0x033, 0x00000069,
+ 0x03F, 0x00000CF3, 0x033, 0x0000006A, 0x03F, 0x00000CF6,
+ 0x93001000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060,
+ 0x03F, 0x00000C0A, 0x033, 0x00000061, 0x03F, 0x00000C0D,
+ 0x033, 0x00000062, 0x03F, 0x00000C2A, 0x033, 0x00000063,
+ 0x03F, 0x00000C2D, 0x033, 0x00000064, 0x03F, 0x00000C6A,
+ 0x033, 0x00000065, 0x03F, 0x00000CAA, 0x033, 0x00000066,
+ 0x03F, 0x00000CAD, 0x033, 0x00000067, 0x03F, 0x00000CB0,
+ 0x033, 0x00000068, 0x03F, 0x00000CF1, 0x033, 0x00000069,
+ 0x03F, 0x00000CF4, 0x033, 0x0000006A, 0x03F, 0x00000CF7,
+ 0x90002100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060,
+ 0x03F, 0x0000042C, 0x033, 0x00000061, 0x03F, 0x0000082B,
+ 0x033, 0x00000062, 0x03F, 0x0000084A, 0x033, 0x00000063,
+ 0x03F, 0x0000084D, 0x033, 0x00000064, 0x03F, 0x00000C4E,
+ 0x033, 0x00000065, 0x03F, 0x00000C8C, 0x033, 0x00000066,
+ 0x03F, 0x00000C8F, 0x033, 0x00000067, 0x03F, 0x00000CEC,
+ 0x033, 0x00000068, 0x03F, 0x00000CEF, 0x033, 0x00000069,
+ 0x03F, 0x00000CF2, 0x033, 0x0000006A, 0x03F, 0x00000CF5,
+ 0x90002000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060,
+ 0x03F, 0x0000042C, 0x033, 0x00000061, 0x03F, 0x0000082B,
+ 0x033, 0x00000062, 0x03F, 0x0000084A, 0x033, 0x00000063,
+ 0x03F, 0x0000084D, 0x033, 0x00000064, 0x03F, 0x00000C4E,
+ 0x033, 0x00000065, 0x03F, 0x00000C8C, 0x033, 0x00000066,
+ 0x03F, 0x00000C8F, 0x033, 0x00000067, 0x03F, 0x00000CEC,
+ 0x033, 0x00000068, 0x03F, 0x00000CEF, 0x033, 0x00000069,
+ 0x03F, 0x00000CF2, 0x033, 0x0000006A, 0x03F, 0x00000CF5,
+ 0xA0000000, 0x00000000, 0x033, 0x00000060, 0x03F, 0x00000C0A,
+ 0x033, 0x00000061, 0x03F, 0x00000C0D, 0x033, 0x00000062,
+ 0x03F, 0x00000C2A, 0x033, 0x00000063, 0x03F, 0x00000C2D,
+ 0x033, 0x00000064, 0x03F, 0x00000C6A, 0x033, 0x00000065,
+ 0x03F, 0x00000CAA, 0x033, 0x00000066, 0x03F, 0x00000CAD,
+ 0x033, 0x00000067, 0x03F, 0x00000CB0, 0x033, 0x00000068,
+ 0x03F, 0x00000CF1, 0x033, 0x00000069, 0x03F, 0x00000CF4,
+ 0x033, 0x0000006A, 0x03F, 0x00000CF7, 0xB0000000, 0x00000000,
+ 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x000000A0,
+ 0x03F, 0x00000007, 0x033, 0x000000A1, 0x03F, 0x0000000A,
+ 0x033, 0x000000A2, 0x03F, 0x0000000D, 0x033, 0x000000A3,
+ 0x03F, 0x0000002A, 0x033, 0x000000A4, 0x03F, 0x0000002D,
+ 0x033, 0x000000A5, 0x03F, 0x00000030, 0x033, 0x000000A6,
+ 0x03F, 0x0000006D, 0x033, 0x000000A7, 0x03F, 0x00000070,
+ 0x033, 0x000000A8, 0x03F, 0x000000ED, 0x033, 0x000000A9,
+ 0x03F, 0x000000F0, 0x033, 0x000000AA, 0x03F, 0x000000F3,
+ 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x000000A0,
+ 0x03F, 0x00000007, 0x033, 0x000000A1, 0x03F, 0x0000000A,
+ 0x033, 0x000000A2, 0x03F, 0x0000000D, 0x033, 0x000000A3,
+ 0x03F, 0x0000002A, 0x033, 0x000000A4, 0x03F, 0x0000002D,
+ 0x033, 0x000000A5, 0x03F, 0x00000030, 0x033, 0x000000A6,
+ 0x03F, 0x0000006D, 0x033, 0x000000A7, 0x03F, 0x00000070,
+ 0x033, 0x000000A8, 0x03F, 0x000000ED, 0x033, 0x000000A9,
+ 0x03F, 0x000000F0, 0x033, 0x000000AA, 0x03F, 0x000000F3,
+ 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0,
+ 0x03F, 0x00000007, 0x033, 0x000000A1, 0x03F, 0x0000000A,
+ 0x033, 0x000000A2, 0x03F, 0x0000000D, 0x033, 0x000000A3,
+ 0x03F, 0x0000002A, 0x033, 0x000000A4, 0x03F, 0x0000002D,
+ 0x033, 0x000000A5, 0x03F, 0x00000030, 0x033, 0x000000A6,
+ 0x03F, 0x0000006D, 0x033, 0x000000A7, 0x03F, 0x00000070,
+ 0x033, 0x000000A8, 0x03F, 0x000000ED, 0x033, 0x000000A9,
+ 0x03F, 0x000000F0, 0x033, 0x000000AA, 0x03F, 0x000000F3,
+ 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0,
+ 0x03F, 0x00000005, 0x033, 0x000000A1, 0x03F, 0x00000008,
+ 0x033, 0x000000A2, 0x03F, 0x0000000B, 0x033, 0x000000A3,
+ 0x03F, 0x0000000E, 0x033, 0x000000A4, 0x03F, 0x00000047,
+ 0x033, 0x000000A5, 0x03F, 0x0000004A, 0x033, 0x000000A6,
+ 0x03F, 0x0000004D, 0x033, 0x000000A7, 0x03F, 0x00000050,
+ 0x033, 0x000000A8, 0x03F, 0x00000053, 0x033, 0x000000A9,
+ 0x03F, 0x00000056, 0x033, 0x000000AA, 0x03F, 0x00000094,
+ 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x000000A0,
+ 0x03F, 0x00000007, 0x033, 0x000000A1, 0x03F, 0x0000000A,
+ 0x033, 0x000000A2, 0x03F, 0x0000000D, 0x033, 0x000000A3,
+ 0x03F, 0x0000002A, 0x033, 0x000000A4, 0x03F, 0x0000002D,
+ 0x033, 0x000000A5, 0x03F, 0x00000030, 0x033, 0x000000A6,
+ 0x03F, 0x0000006D, 0x033, 0x000000A7, 0x03F, 0x00000070,
+ 0x033, 0x000000A8, 0x03F, 0x000000ED, 0x033, 0x000000A9,
+ 0x03F, 0x000000F0, 0x033, 0x000000AA, 0x03F, 0x000000F3,
+ 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x000000A0,
+ 0x03F, 0x00000007, 0x033, 0x000000A1, 0x03F, 0x0000000A,
+ 0x033, 0x000000A2, 0x03F, 0x0000000D, 0x033, 0x000000A3,
+ 0x03F, 0x0000002A, 0x033, 0x000000A4, 0x03F, 0x0000002D,
+ 0x033, 0x000000A5, 0x03F, 0x00000030, 0x033, 0x000000A6,
+ 0x03F, 0x0000006D, 0x033, 0x000000A7, 0x03F, 0x00000070,
+ 0x033, 0x000000A8, 0x03F, 0x000000ED, 0x033, 0x000000A9,
+ 0x03F, 0x000000F0, 0x033, 0x000000AA, 0x03F, 0x000000F3,
+ 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0,
+ 0x03F, 0x00000007, 0x033, 0x000000A1, 0x03F, 0x0000000A,
+ 0x033, 0x000000A2, 0x03F, 0x0000000D, 0x033, 0x000000A3,
+ 0x03F, 0x0000002A, 0x033, 0x000000A4, 0x03F, 0x0000002D,
+ 0x033, 0x000000A5, 0x03F, 0x00000030, 0x033, 0x000000A6,
+ 0x03F, 0x0000006D, 0x033, 0x000000A7, 0x03F, 0x00000070,
+ 0x033, 0x000000A8, 0x03F, 0x000000ED, 0x033, 0x000000A9,
+ 0x03F, 0x000000F0, 0x033, 0x000000AA, 0x03F, 0x000000F3,
+ 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0,
+ 0x03F, 0x00000005, 0x033, 0x000000A1, 0x03F, 0x00000008,
+ 0x033, 0x000000A2, 0x03F, 0x0000000B, 0x033, 0x000000A3,
+ 0x03F, 0x0000000E, 0x033, 0x000000A4, 0x03F, 0x00000047,
+ 0x033, 0x000000A5, 0x03F, 0x0000004A, 0x033, 0x000000A6,
+ 0x03F, 0x0000004D, 0x033, 0x000000A7, 0x03F, 0x00000050,
+ 0x033, 0x000000A8, 0x03F, 0x00000053, 0x033, 0x000000A9,
+ 0x03F, 0x00000056, 0x033, 0x000000AA, 0x03F, 0x00000094,
+ 0x9300200c, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0,
+ 0x03F, 0x00000005, 0x033, 0x000000A1, 0x03F, 0x00000008,
+ 0x033, 0x000000A2, 0x03F, 0x0000000B, 0x033, 0x000000A3,
+ 0x03F, 0x0000000E, 0x033, 0x000000A4, 0x03F, 0x00000047,
+ 0x033, 0x000000A5, 0x03F, 0x0000004A, 0x033, 0x000000A6,
+ 0x03F, 0x0000004D, 0x033, 0x000000A7, 0x03F, 0x00000050,
+ 0x033, 0x000000A8, 0x03F, 0x00000053, 0x033, 0x000000A9,
+ 0x03F, 0x00000056, 0x033, 0x000000AA, 0x03F, 0x00000094,
+ 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0,
+ 0x03F, 0x00000826, 0x033, 0x000000A1, 0x03F, 0x00000829,
+ 0x033, 0x000000A2, 0x03F, 0x0000082C, 0x033, 0x000000A3,
+ 0x03F, 0x0000082F, 0x033, 0x000000A4, 0x03F, 0x0000086C,
+ 0x033, 0x000000A5, 0x03F, 0x00000CE8, 0x033, 0x000000A6,
+ 0x03F, 0x00000CEB, 0x033, 0x000000A7, 0x03F, 0x00000CEE,
+ 0x033, 0x000000A8, 0x03F, 0x00000CF1, 0x033, 0x000000A9,
+ 0x03F, 0x00000CF4, 0x033, 0x000000AA, 0x03F, 0x00000CF7,
+ 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0,
+ 0x03F, 0x0000042A, 0x033, 0x000000A1, 0x03F, 0x00000829,
+ 0x033, 0x000000A2, 0x03F, 0x00000848, 0x033, 0x000000A3,
+ 0x03F, 0x0000084B, 0x033, 0x000000A4, 0x03F, 0x00000C4C,
+ 0x033, 0x000000A5, 0x03F, 0x00000CA9, 0x033, 0x000000A6,
+ 0x03F, 0x00000CEA, 0x033, 0x000000A7, 0x03F, 0x00000CED,
+ 0x033, 0x000000A8, 0x03F, 0x00000CF0, 0x033, 0x000000A9,
+ 0x03F, 0x00000CF3, 0x033, 0x000000AA, 0x03F, 0x00000CF6,
+ 0x93011000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0,
+ 0x03F, 0x00000C09, 0x033, 0x000000A1, 0x03F, 0x00000C0C,
+ 0x033, 0x000000A2, 0x03F, 0x00000C0F, 0x033, 0x000000A3,
+ 0x03F, 0x00000C2C, 0x033, 0x000000A4, 0x03F, 0x00000C2F,
+ 0x033, 0x000000A5, 0x03F, 0x00000C8A, 0x033, 0x000000A6,
+ 0x03F, 0x00000C8D, 0x033, 0x000000A7, 0x03F, 0x00000C90,
+ 0x033, 0x000000A8, 0x03F, 0x00000CEF, 0x033, 0x000000A9,
+ 0x03F, 0x00000CF2, 0x033, 0x000000AA, 0x03F, 0x00000CF5,
+ 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0,
+ 0x03F, 0x00000005, 0x033, 0x000000A1, 0x03F, 0x00000008,
+ 0x033, 0x000000A2, 0x03F, 0x0000000B, 0x033, 0x000000A3,
+ 0x03F, 0x0000000E, 0x033, 0x000000A4, 0x03F, 0x00000047,
+ 0x033, 0x000000A5, 0x03F, 0x0000004A, 0x033, 0x000000A6,
+ 0x03F, 0x0000004D, 0x033, 0x000000A7, 0x03F, 0x00000050,
+ 0x033, 0x000000A8, 0x03F, 0x00000053, 0x033, 0x000000A9,
+ 0x03F, 0x00000056, 0x033, 0x000000AA, 0x03F, 0x00000094,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0,
+ 0x03F, 0x00000C09, 0x033, 0x000000A1, 0x03F, 0x00000C0C,
+ 0x033, 0x000000A2, 0x03F, 0x00000C0F, 0x033, 0x000000A3,
+ 0x03F, 0x00000C2C, 0x033, 0x000000A4, 0x03F, 0x00000C2F,
+ 0x033, 0x000000A5, 0x03F, 0x00000C8A, 0x033, 0x000000A6,
+ 0x03F, 0x00000C8D, 0x033, 0x000000A7, 0x03F, 0x00000C90,
+ 0x033, 0x000000A8, 0x03F, 0x00000CEF, 0x033, 0x000000A9,
+ 0x03F, 0x00000CF2, 0x033, 0x000000AA, 0x03F, 0x00000CF5,
+ 0x93002000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0,
+ 0x03F, 0x00000429, 0x033, 0x000000A1, 0x03F, 0x00000828,
+ 0x033, 0x000000A2, 0x03F, 0x00000847, 0x033, 0x000000A3,
+ 0x03F, 0x0000084A, 0x033, 0x000000A4, 0x03F, 0x00000C4B,
+ 0x033, 0x000000A5, 0x03F, 0x00000C8A, 0x033, 0x000000A6,
+ 0x03F, 0x00000CEA, 0x033, 0x000000A7, 0x03F, 0x00000CED,
+ 0x033, 0x000000A8, 0x03F, 0x00000CF0, 0x033, 0x000000A9,
+ 0x03F, 0x00000CF3, 0x033, 0x000000AA, 0x03F, 0x00000CF6,
+ 0x93001000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0,
+ 0x03F, 0x00000C09, 0x033, 0x000000A1, 0x03F, 0x00000C0C,
+ 0x033, 0x000000A2, 0x03F, 0x00000C0F, 0x033, 0x000000A3,
+ 0x03F, 0x00000C2C, 0x033, 0x000000A4, 0x03F, 0x00000C2F,
+ 0x033, 0x000000A5, 0x03F, 0x00000C8A, 0x033, 0x000000A6,
+ 0x03F, 0x00000C8D, 0x033, 0x000000A7, 0x03F, 0x00000C90,
+ 0x033, 0x000000A8, 0x03F, 0x00000CEF, 0x033, 0x000000A9,
+ 0x03F, 0x00000CF2, 0x033, 0x000000AA, 0x03F, 0x00000CF5,
+ 0x90002100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0,
+ 0x03F, 0x0000042A, 0x033, 0x000000A1, 0x03F, 0x00000829,
+ 0x033, 0x000000A2, 0x03F, 0x00000848, 0x033, 0x000000A3,
+ 0x03F, 0x0000084B, 0x033, 0x000000A4, 0x03F, 0x00000C4C,
+ 0x033, 0x000000A5, 0x03F, 0x00000C8A, 0x033, 0x000000A6,
+ 0x03F, 0x00000C8D, 0x033, 0x000000A7, 0x03F, 0x00000CEC,
+ 0x033, 0x000000A8, 0x03F, 0x00000CEF, 0x033, 0x000000A9,
+ 0x03F, 0x00000CF2, 0x033, 0x000000AA, 0x03F, 0x00000CF5,
+ 0x90002000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0,
+ 0x03F, 0x0000042A, 0x033, 0x000000A1, 0x03F, 0x00000829,
+ 0x033, 0x000000A2, 0x03F, 0x00000848, 0x033, 0x000000A3,
+ 0x03F, 0x0000084B, 0x033, 0x000000A4, 0x03F, 0x00000C4C,
+ 0x033, 0x000000A5, 0x03F, 0x00000C8A, 0x033, 0x000000A6,
+ 0x03F, 0x00000C8D, 0x033, 0x000000A7, 0x03F, 0x00000CEC,
+ 0x033, 0x000000A8, 0x03F, 0x00000CEF, 0x033, 0x000000A9,
+ 0x03F, 0x00000CF2, 0x033, 0x000000AA, 0x03F, 0x00000CF5,
+ 0xA0000000, 0x00000000, 0x033, 0x000000A0, 0x03F, 0x00000C09,
+ 0x033, 0x000000A1, 0x03F, 0x00000C0C, 0x033, 0x000000A2,
+ 0x03F, 0x00000C0F, 0x033, 0x000000A3, 0x03F, 0x00000C2C,
+ 0x033, 0x000000A4, 0x03F, 0x00000C2F, 0x033, 0x000000A5,
+ 0x03F, 0x00000C8A, 0x033, 0x000000A6, 0x03F, 0x00000C8D,
+ 0x033, 0x000000A7, 0x03F, 0x00000C90, 0x033, 0x000000A8,
+ 0x03F, 0x00000CEF, 0x033, 0x000000A9, 0x03F, 0x00000CF2,
+ 0x033, 0x000000AA, 0x03F, 0x00000CF5, 0xB0000000, 0x00000000,
+ 0x0EF, 0x00000000, 0x0EF, 0x00000400, 0x8300100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x0000265A,
+ 0x033, 0x00000001, 0x03F, 0x0000265A, 0x033, 0x00000002,
+ 0x03F, 0x0000265A, 0x033, 0x00000003, 0x03F, 0x0000265A,
+ 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000000,
+ 0x03F, 0x0000265A, 0x033, 0x00000001, 0x03F, 0x0000265A,
+ 0x033, 0x00000002, 0x03F, 0x0000265A, 0x033, 0x00000003,
+ 0x03F, 0x0000265A, 0x9300100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000000, 0x03F, 0x0000265A, 0x033, 0x00000001,
+ 0x03F, 0x0000265A, 0x033, 0x00000002, 0x03F, 0x0000265A,
+ 0x033, 0x00000003, 0x03F, 0x0000265A, 0x9300200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x0000265A,
+ 0x033, 0x00000001, 0x03F, 0x0000265A, 0x033, 0x00000002,
+ 0x03F, 0x0000265A, 0x033, 0x00000003, 0x03F, 0x0000265A,
+ 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000000,
+ 0x03F, 0x0000265A, 0x033, 0x00000001, 0x03F, 0x0000265A,
+ 0x033, 0x00000002, 0x03F, 0x0000265A, 0x033, 0x00000003,
+ 0x03F, 0x0000265A, 0x9000100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x033, 0x00000000, 0x03F, 0x0000265A, 0x033, 0x00000001,
+ 0x03F, 0x0000265A, 0x033, 0x00000002, 0x03F, 0x0000265A,
+ 0x033, 0x00000003, 0x03F, 0x0000265A, 0x9000100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x0000265A,
+ 0x033, 0x00000001, 0x03F, 0x0000265A, 0x033, 0x00000002,
+ 0x03F, 0x0000265A, 0x033, 0x00000003, 0x03F, 0x0000265A,
+ 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000,
+ 0x03F, 0x0000265A, 0x033, 0x00000001, 0x03F, 0x0000265A,
+ 0x033, 0x00000002, 0x03F, 0x0000265A, 0x033, 0x00000003,
+ 0x03F, 0x0000265A, 0xA0000000, 0x00000000, 0x033, 0x00000000,
+ 0x03F, 0x000004BB, 0x033, 0x00000001, 0x03F, 0x000004BB,
+ 0x033, 0x00000002, 0x03F, 0x000004BB, 0x033, 0x00000003,
+ 0x03F, 0x000004BB, 0xB0000000, 0x00000000, 0x0EF, 0x00000000,
+ 0x0EF, 0x00000100, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x033, 0x00000000, 0x03F, 0x00000745, 0x033, 0x00000001,
+ 0x03F, 0x00000745, 0x033, 0x00000002, 0x03F, 0x00000745,
+ 0x033, 0x00000003, 0x03F, 0x00000745, 0x9300100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000745,
+ 0x033, 0x00000001, 0x03F, 0x00000745, 0x033, 0x00000002,
+ 0x03F, 0x00000745, 0x033, 0x00000003, 0x03F, 0x00000745,
+ 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000,
+ 0x03F, 0x00000745, 0x033, 0x00000001, 0x03F, 0x00000745,
+ 0x033, 0x00000002, 0x03F, 0x00000745, 0x033, 0x00000003,
+ 0x03F, 0x00000745, 0x9300200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000000, 0x03F, 0x00000745, 0x033, 0x00000001,
+ 0x03F, 0x00000745, 0x033, 0x00000002, 0x03F, 0x00000745,
+ 0x033, 0x00000003, 0x03F, 0x00000745, 0x9000100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000745,
+ 0x033, 0x00000001, 0x03F, 0x00000745, 0x033, 0x00000002,
+ 0x03F, 0x00000745, 0x033, 0x00000003, 0x03F, 0x00000745,
+ 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000000,
+ 0x03F, 0x00000745, 0x033, 0x00000001, 0x03F, 0x00000745,
+ 0x033, 0x00000002, 0x03F, 0x00000745, 0x033, 0x00000003,
+ 0x03F, 0x00000745, 0x9000100f, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000000, 0x03F, 0x00000745, 0x033, 0x00000001,
+ 0x03F, 0x00000745, 0x033, 0x00000002, 0x03F, 0x00000745,
+ 0x033, 0x00000003, 0x03F, 0x00000745, 0x9000200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000745,
+ 0x033, 0x00000001, 0x03F, 0x00000745, 0x033, 0x00000002,
+ 0x03F, 0x00000745, 0x033, 0x00000003, 0x03F, 0x00000745,
+ 0xA0000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000F34,
+ 0x033, 0x00000001, 0x03F, 0x00000F34, 0x033, 0x00000002,
+ 0x03F, 0x00000F34, 0x033, 0x00000003, 0x03F, 0x00000F34,
+ 0xB0000000, 0x00000000, 0x0EF, 0x00000000, 0x8300100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x081, 0x0000F400, 0x087, 0x00016040,
+ 0x051, 0x00000808, 0x052, 0x00098002, 0x053, 0x0000FA47,
+ 0x054, 0x00058032, 0x056, 0x00051000, 0x057, 0x0000CE0A,
+ 0x058, 0x00082030, 0x9300100f, 0x05050505, 0x40000000, 0x00000000,
+ 0x081, 0x0000F400, 0x087, 0x00016040, 0x051, 0x00000808,
+ 0x052, 0x00098002, 0x053, 0x0000FA47, 0x054, 0x00058032,
+ 0x056, 0x00051000, 0x057, 0x0000CE0A, 0x058, 0x00082030,
+ 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x081, 0x0000F400,
+ 0x087, 0x00016040, 0x051, 0x00000808, 0x052, 0x00098002,
+ 0x053, 0x0000FA47, 0x054, 0x00058032, 0x056, 0x00051000,
+ 0x057, 0x0000CE0A, 0x058, 0x00082030, 0x9300200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x081, 0x0000F400, 0x087, 0x00016040,
+ 0x051, 0x00000808, 0x052, 0x00098002, 0x053, 0x0000FA47,
+ 0x054, 0x00058032, 0x056, 0x00051000, 0x057, 0x0000CE0A,
+ 0x058, 0x00082030, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000,
+ 0x081, 0x0000F400, 0x087, 0x00016040, 0x051, 0x00000808,
+ 0x052, 0x00098002, 0x053, 0x0000FA47, 0x054, 0x00058032,
+ 0x056, 0x00051000, 0x057, 0x0000CE0A, 0x058, 0x00082030,
+ 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x081, 0x0000F400,
+ 0x087, 0x00016040, 0x051, 0x00000808, 0x052, 0x00098002,
+ 0x053, 0x0000FA47, 0x054, 0x00058032, 0x056, 0x00051000,
+ 0x057, 0x0000CE0A, 0x058, 0x00082030, 0x9000100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x081, 0x0000F400, 0x087, 0x00016040,
+ 0x051, 0x00000808, 0x052, 0x00098002, 0x053, 0x0000FA47,
+ 0x054, 0x00058032, 0x056, 0x00051000, 0x057, 0x0000CE0A,
+ 0x058, 0x00082030, 0x9000200f, 0x00000000, 0x40000000, 0x00000000,
+ 0x081, 0x0000F400, 0x087, 0x00016040, 0x051, 0x00000808,
+ 0x052, 0x00098002, 0x053, 0x0000FA47, 0x054, 0x00058032,
+ 0x056, 0x00051000, 0x057, 0x0000CE0A, 0x058, 0x00082030,
+ 0xA0000000, 0x00000000, 0x081, 0x0000F000, 0x087, 0x00016040,
+ 0x051, 0x00000C00, 0x052, 0x0007C241, 0x053, 0x0001C069,
+ 0x054, 0x00078032, 0x057, 0x0000CE0A, 0x058, 0x00058750,
+ 0xB0000000, 0x00000000, 0x0EF, 0x00000800, 0x8300100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000003,
+ 0x033, 0x00000001, 0x03F, 0x00000006, 0x033, 0x00000002,
+ 0x03F, 0x00000009, 0x033, 0x00000003, 0x03F, 0x00000026,
+ 0x033, 0x00000004, 0x03F, 0x00000029, 0x033, 0x00000005,
+ 0x03F, 0x0000002C, 0x033, 0x00000006, 0x03F, 0x0000002F,
+ 0x033, 0x00000007, 0x03F, 0x00000033, 0x033, 0x00000008,
+ 0x03F, 0x00000036, 0x033, 0x00000009, 0x03F, 0x00000039,
+ 0x033, 0x0000000A, 0x03F, 0x0000003C, 0x9300100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000003,
+ 0x033, 0x00000001, 0x03F, 0x00000006, 0x033, 0x00000002,
+ 0x03F, 0x00000009, 0x033, 0x00000003, 0x03F, 0x00000026,
+ 0x033, 0x00000004, 0x03F, 0x00000029, 0x033, 0x00000005,
+ 0x03F, 0x0000002C, 0x033, 0x00000006, 0x03F, 0x0000002F,
+ 0x033, 0x00000007, 0x03F, 0x00000033, 0x033, 0x00000008,
+ 0x03F, 0x00000036, 0x033, 0x00000009, 0x03F, 0x00000039,
+ 0x033, 0x0000000A, 0x03F, 0x0000003C, 0x9300100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000003,
+ 0x033, 0x00000001, 0x03F, 0x00000006, 0x033, 0x00000002,
+ 0x03F, 0x00000009, 0x033, 0x00000003, 0x03F, 0x00000026,
+ 0x033, 0x00000004, 0x03F, 0x00000029, 0x033, 0x00000005,
+ 0x03F, 0x0000002C, 0x033, 0x00000006, 0x03F, 0x0000002F,
+ 0x033, 0x00000007, 0x03F, 0x00000033, 0x033, 0x00000008,
+ 0x03F, 0x00000036, 0x033, 0x00000009, 0x03F, 0x00000039,
+ 0x033, 0x0000000A, 0x03F, 0x0000003C, 0x9300200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000003,
+ 0x033, 0x00000001, 0x03F, 0x00000006, 0x033, 0x00000002,
+ 0x03F, 0x00000009, 0x033, 0x00000003, 0x03F, 0x00000026,
+ 0x033, 0x00000004, 0x03F, 0x00000029, 0x033, 0x00000005,
+ 0x03F, 0x0000002C, 0x033, 0x00000006, 0x03F, 0x0000002F,
+ 0x033, 0x00000007, 0x03F, 0x00000033, 0x033, 0x00000008,
+ 0x03F, 0x00000036, 0x033, 0x00000009, 0x03F, 0x00000039,
+ 0x033, 0x0000000A, 0x03F, 0x0000003C, 0x9000100f, 0x0a0a0a0a,
+ 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000003,
+ 0x033, 0x00000001, 0x03F, 0x00000006, 0x033, 0x00000002,
+ 0x03F, 0x00000009, 0x033, 0x00000003, 0x03F, 0x00000026,
+ 0x033, 0x00000004, 0x03F, 0x00000029, 0x033, 0x00000005,
+ 0x03F, 0x0000002C, 0x033, 0x00000006, 0x03F, 0x0000002F,
+ 0x033, 0x00000007, 0x03F, 0x00000033, 0x033, 0x00000008,
+ 0x03F, 0x00000036, 0x033, 0x00000009, 0x03F, 0x00000039,
+ 0x033, 0x0000000A, 0x03F, 0x0000003C, 0x9000100f, 0x05050505,
+ 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000003,
+ 0x033, 0x00000001, 0x03F, 0x00000006, 0x033, 0x00000002,
+ 0x03F, 0x00000009, 0x033, 0x00000003, 0x03F, 0x00000026,
+ 0x033, 0x00000004, 0x03F, 0x00000029, 0x033, 0x00000005,
+ 0x03F, 0x0000002C, 0x033, 0x00000006, 0x03F, 0x0000002F,
+ 0x033, 0x00000007, 0x03F, 0x00000033, 0x033, 0x00000008,
+ 0x03F, 0x00000036, 0x033, 0x00000009, 0x03F, 0x00000039,
+ 0x033, 0x0000000A, 0x03F, 0x0000003C, 0x9000100f, 0x00000000,
+ 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000003,
+ 0x033, 0x00000001, 0x03F, 0x00000006, 0x033, 0x00000002,
+ 0x03F, 0x00000009, 0x033, 0x00000003, 0x03F, 0x00000026,
+ 0x033, 0x00000004, 0x03F, 0x00000029, 0x033, 0x00000005,
+ 0x03F, 0x0000002C, 0x033, 0x00000006, 0x03F, 0x0000002F,
+ 0x033, 0x00000007, 0x03F, 0x00000033, 0x033, 0x00000008,
+ 0x03F, 0x00000036, 0x033, 0x00000009, 0x03F, 0x00000039,
+ 0x033, 0x0000000A, 0x03F, 0x0000003C, 0x9000200f, 0x00000000,
+ 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000003,
+ 0x033, 0x00000001, 0x03F, 0x00000006, 0x033, 0x00000002,
+ 0x03F, 0x00000009, 0x033, 0x00000003, 0x03F, 0x00000026,
+ 0x033, 0x00000004, 0x03F, 0x00000029, 0x033, 0x00000005,
+ 0x03F, 0x0000002C, 0x033, 0x00000006, 0x03F, 0x0000002F,
+ 0x033, 0x00000007, 0x03F, 0x00000033, 0x033, 0x00000008,
+ 0x03F, 0x00000036, 0x033, 0x00000009, 0x03F, 0x00000039,
+ 0x033, 0x0000000A, 0x03F, 0x0000003C, 0xA0000000, 0x00000000,
+ 0x033, 0x00000000, 0x03F, 0x0005142C, 0x033, 0x00000001,
+ 0x03F, 0x0005142F, 0x033, 0x00000002, 0x03F, 0x00051432,
+ 0x033, 0x00000003, 0x03F, 0x00051C87, 0x033, 0x00000004,
+ 0x03F, 0x00051C8A, 0x033, 0x00000005, 0x03F, 0x00051C8D,
+ 0x033, 0x00000006, 0x03F, 0x00051CEB, 0x033, 0x00000007,
+ 0x03F, 0x00051CEE, 0x033, 0x00000008, 0x03F, 0x00051CF1,
+ 0x033, 0x00000009, 0x03F, 0x00051CF4, 0x033, 0x0000000A,
+ 0x03F, 0x00051CF7, 0xB0000000, 0x00000000, 0x0EF, 0x00000000,
+ 0x0EF, 0x00000010, 0x033, 0x00000000, 0x008, 0x0009C060,
+ 0x033, 0x00000001, 0x008, 0x0009C060, 0x0EF, 0x00000000,
+ 0x033, 0x000000A2, 0x0EF, 0x00080000, 0x03E, 0x0000593F,
+ 0x03F, 0x000C0F4F, 0x0EF, 0x00000000, 0x033, 0x000000A3,
+ 0x0EF, 0x00080000, 0x03E, 0x00005934, 0x03F, 0x0005AFCF,
+ 0x0EF, 0x00000000,
+
+};
+
+void odm_read_and_config_mp_8822b_radiob(struct phy_dm_struct *dm)
+{
+ u32 i = 0;
+ u8 c_cond;
+ bool is_matched = true, is_skipped = false;
+ u32 array_len = sizeof(array_mp_8822b_radiob) / sizeof(u32);
+ u32 *array = array_mp_8822b_radiob;
+
+ u32 v1 = 0, v2 = 0, pre_v1 = 0, pre_v2 = 0;
+
+ ODM_RT_TRACE(dm, ODM_COMP_INIT,
+ "===> %s\n", __func__);
+
+ for (; (i + 1) < array_len; i = i + 2) {
+ v1 = array[i];
+ v2 = array[i + 1];
+
+ if (v1 & BIT(31)) { /* positive condition*/
+ c_cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28);
+ if (c_cond == COND_ENDIF) { /*end*/
+ is_matched = true;
+ is_skipped = false;
+ ODM_RT_TRACE(dm, ODM_COMP_INIT, "ENDIF\n");
+ } else if (c_cond == COND_ELSE) { /*else*/
+ is_matched = is_skipped ? false : true;
+ ODM_RT_TRACE(dm, ODM_COMP_INIT, "ELSE\n");
+ } else { /*if , else if*/
+ pre_v1 = v1;
+ pre_v2 = v2;
+ ODM_RT_TRACE(dm, ODM_COMP_INIT,
+ "IF or ELSE IF\n");
+ }
+ } else if (v1 & BIT(30)) { /*negative condition*/
+ if (is_skipped) {
+ is_matched = false;
+ continue;
+ }
+
+ if (check_positive(dm, pre_v1, pre_v2, v1, v2)) {
+ is_matched = true;
+ is_skipped = true;
+ } else {
+ is_matched = false;
+ is_skipped = false;
+ }
+ } else if (is_matched) {
+ odm_config_rf_radio_b_8822b(dm, v1, v2);
+ }
+ }
+}
+
+u32 odm_get_version_mp_8822b_radiob(void) { return 67; }
+
+/******************************************************************************
+ * txpowertrack.TXT
+ ******************************************************************************/
+
+static u8 delta_swing_index_mp_5gb_n_txpwrtrack_8822b[][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 10,
+ 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15},
+ {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8,
+ 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14},
+ {0, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9,
+ 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14},
+};
+
+static u8 delta_swing_index_mp_5gb_p_txpwrtrack_8822b[][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 11,
+ 12, 13, 14, 15, 15, 16, 17, 18, 18, 19, 19, 19, 19, 19, 19},
+ {0, 1, 2, 2, 3, 4, 5, 6, 6, 7, 8, 8, 9, 9, 10,
+ 11, 12, 12, 13, 14, 15, 16, 17, 17, 18, 18, 18, 18, 18, 18},
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10,
+ 10, 11, 12, 13, 14, 15, 15, 16, 16, 17, 17, 17, 17, 17, 17},
+};
+
+static u8 delta_swing_index_mp_5ga_n_txpwrtrack_8822b[][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10,
+ 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15},
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9,
+ 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14},
+ {0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9,
+ 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14},
+};
+
+static u8 delta_swing_index_mp_5ga_p_txpwrtrack_8822b[][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11,
+ 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 20, 20, 20, 20},
+ {0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9,
+ 10, 11, 11, 12, 13, 14, 15, 16, 16, 17, 17, 18, 18, 18, 18},
+ {0, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10,
+ 11, 12, 12, 13, 14, 15, 15, 16, 17, 17, 18, 18, 18, 18, 18},
+};
+
+static u8 delta_swing_index_mp_2gb_n_txpwrtrack_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 13, 14, 15, 16, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18};
+
+static u8 delta_swing_index_mp_2gb_p_txpwrtrack_8822b[] = {
+ 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 11,
+ 12, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 22, 22};
+
+static u8 delta_swing_index_mp_2ga_n_txpwrtrack_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12,
+ 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18};
+
+static u8 delta_swing_index_mp_2ga_p_txpwrtrack_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
+ 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22};
+
+static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_8822b[] = {
+ 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 13, 14, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17};
+
+static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_8822b[] = {
+ 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 9, 10, 11,
+ 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22};
+
+static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18};
+
+static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
+ 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22};
+
+void odm_read_and_config_mp_8822b_txpowertrack(struct phy_dm_struct *dm)
+{
+ struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
+
+ ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n");
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p,
+ delta_swing_index_mp_2ga_p_txpwrtrack_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n,
+ delta_swing_index_mp_2ga_n_txpwrtrack_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p,
+ delta_swing_index_mp_2gb_p_txpwrtrack_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n,
+ delta_swing_index_mp_2gb_n_txpwrtrack_8822b,
+ DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p,
+ delta_swing_index_mp_2g_cck_a_p_txpwrtrack_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n,
+ delta_swing_index_mp_2g_cck_a_n_txpwrtrack_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p,
+ delta_swing_index_mp_2g_cck_b_p_txpwrtrack_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n,
+ delta_swing_index_mp_2g_cck_b_n_txpwrtrack_8822b,
+ DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p,
+ delta_swing_index_mp_5ga_p_txpwrtrack_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n,
+ delta_swing_index_mp_5ga_n_txpwrtrack_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p,
+ delta_swing_index_mp_5gb_p_txpwrtrack_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n,
+ delta_swing_index_mp_5gb_n_txpwrtrack_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+}
+
+/******************************************************************************
+ * txpowertrack_type0.TXT
+ ******************************************************************************/
+
+static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type0_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14, 14},
+ {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8,
+ 9, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15},
+};
+
+static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type0_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 15, 15},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 9, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 15},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 10, 10, 11, 12, 13, 14, 14, 15, 15, 15, 16, 16},
+};
+
+static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type0_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14, 14},
+};
+
+static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type0_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 9, 10, 10, 11, 12, 13, 13, 14, 14, 15, 15, 15},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 15, 15},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 15},
+};
+
+static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type0_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 13, 14, 15, 16, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18};
+
+static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type0_8822b[] = {
+ 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 11,
+ 12, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 22, 22};
+
+static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type0_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12,
+ 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18};
+
+static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type0_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
+ 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22};
+
+static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type0_8822b[] = {
+ 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 13, 14, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17};
+
+static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type0_8822b[] = {
+ 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 9, 10, 11,
+ 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22};
+
+static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type0_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18};
+
+static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type0_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
+ 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22};
+
+void odm_read_and_config_mp_8822b_txpowertrack_type0(struct phy_dm_struct *dm)
+{
+ struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
+
+ ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n");
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p,
+ delta_swing_index_mp_2ga_p_txpwrtrack_type0_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n,
+ delta_swing_index_mp_2ga_n_txpwrtrack_type0_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p,
+ delta_swing_index_mp_2gb_p_txpwrtrack_type0_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n,
+ delta_swing_index_mp_2gb_n_txpwrtrack_type0_8822b,
+ DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p,
+ delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type0_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n,
+ delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type0_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p,
+ delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type0_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n,
+ delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type0_8822b,
+ DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p,
+ delta_swing_index_mp_5ga_p_txpwrtrack_type0_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n,
+ delta_swing_index_mp_5ga_n_txpwrtrack_type0_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p,
+ delta_swing_index_mp_5gb_p_txpwrtrack_type0_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n,
+ delta_swing_index_mp_5gb_n_txpwrtrack_type0_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+}
+
+/******************************************************************************
+ * txpowertrack_type1.TXT
+ ******************************************************************************/
+
+static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type1_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 10,
+ 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15},
+ {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8,
+ 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14},
+ {0, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9,
+ 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14},
+};
+
+static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type1_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 11,
+ 12, 13, 14, 15, 15, 16, 17, 18, 18, 19, 19, 19, 19, 19, 19},
+ {0, 1, 2, 2, 3, 4, 5, 6, 6, 7, 8, 8, 9, 9, 10,
+ 11, 12, 12, 13, 14, 15, 16, 17, 17, 18, 18, 18, 18, 18, 18},
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10,
+ 10, 11, 12, 13, 14, 15, 15, 16, 16, 17, 17, 17, 17, 17, 17},
+};
+
+static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type1_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10,
+ 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15},
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9,
+ 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14},
+ {0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9,
+ 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14},
+};
+
+static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type1_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11,
+ 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 20, 20, 20, 20},
+ {0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9,
+ 10, 11, 11, 12, 13, 14, 15, 16, 16, 17, 17, 18, 18, 18, 18},
+ {0, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10,
+ 11, 12, 12, 13, 14, 15, 15, 16, 17, 17, 18, 18, 18, 18, 18},
+};
+
+static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type1_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 13, 14, 15, 16, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18};
+
+static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type1_8822b[] = {
+ 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 11,
+ 12, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 22, 22};
+
+static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type1_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12,
+ 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18};
+
+static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type1_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
+ 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22};
+
+static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type1_8822b[] = {
+ 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 13, 14, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17};
+
+static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type1_8822b[] = {
+ 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 9, 10, 11,
+ 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22};
+
+static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type1_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18};
+
+static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type1_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
+ 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22};
+
+void odm_read_and_config_mp_8822b_txpowertrack_type1(struct phy_dm_struct *dm)
+{
+ struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
+
+ ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n");
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p,
+ delta_swing_index_mp_2ga_p_txpwrtrack_type1_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n,
+ delta_swing_index_mp_2ga_n_txpwrtrack_type1_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p,
+ delta_swing_index_mp_2gb_p_txpwrtrack_type1_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n,
+ delta_swing_index_mp_2gb_n_txpwrtrack_type1_8822b,
+ DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p,
+ delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type1_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n,
+ delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type1_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p,
+ delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type1_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n,
+ delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type1_8822b,
+ DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p,
+ delta_swing_index_mp_5ga_p_txpwrtrack_type1_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n,
+ delta_swing_index_mp_5ga_n_txpwrtrack_type1_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p,
+ delta_swing_index_mp_5gb_p_txpwrtrack_type1_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n,
+ delta_swing_index_mp_5gb_n_txpwrtrack_type1_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+}
+
+/******************************************************************************
+ * txpowertrack_type2.TXT
+ ******************************************************************************/
+
+static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type2_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11,
+ 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22},
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11,
+ 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22},
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11,
+ 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22},
+};
+
+static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type2_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11,
+ 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23},
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11,
+ 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23},
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11,
+ 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23},
+};
+
+static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type2_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11,
+ 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22},
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11,
+ 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22},
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11,
+ 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22},
+};
+
+static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type2_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11,
+ 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23},
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11,
+ 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23},
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11,
+ 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23},
+};
+
+static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type2_8822b[] = {
+ 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
+ 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12};
+
+static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type2_8822b[] = {
+ 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15};
+
+static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type2_8822b[] = {
+ 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
+ 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12};
+
+static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type2_8822b[] = {
+ 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15};
+
+static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type2_8822b[] = {
+ 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
+ 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12};
+
+static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type2_8822b[] = {
+ 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15};
+
+static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type2_8822b[] = {
+ 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
+ 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12};
+
+static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type2_8822b[] = {
+ 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15};
+
+void odm_read_and_config_mp_8822b_txpowertrack_type2(struct phy_dm_struct *dm)
+{
+ struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
+
+ ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n");
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p,
+ delta_swing_index_mp_2ga_p_txpwrtrack_type2_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n,
+ delta_swing_index_mp_2ga_n_txpwrtrack_type2_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p,
+ delta_swing_index_mp_2gb_p_txpwrtrack_type2_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n,
+ delta_swing_index_mp_2gb_n_txpwrtrack_type2_8822b,
+ DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p,
+ delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type2_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n,
+ delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type2_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p,
+ delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type2_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n,
+ delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type2_8822b,
+ DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p,
+ delta_swing_index_mp_5ga_p_txpwrtrack_type2_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n,
+ delta_swing_index_mp_5ga_n_txpwrtrack_type2_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p,
+ delta_swing_index_mp_5gb_p_txpwrtrack_type2_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n,
+ delta_swing_index_mp_5gb_n_txpwrtrack_type2_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+}
+
+/******************************************************************************
+ * txpowertrack_type3_type5.TXT
+ ******************************************************************************/
+
+static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type3_type5_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15},
+};
+
+static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type3_type5_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8,
+ 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17},
+ {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8,
+ 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17},
+ {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8,
+ 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17},
+};
+
+static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type3_type5_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15},
+};
+
+static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type3_type5_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8,
+ 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17},
+ {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8,
+ 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17},
+ {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8,
+ 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17},
+};
+
+static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type3_type5_8822b[] = {
+ 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
+ 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12};
+
+static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type3_type5_8822b[] = {
+ 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15};
+
+static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type3_type5_8822b[] = {
+ 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
+ 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12};
+
+static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type3_type5_8822b[] = {
+ 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15};
+
+static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type3_type5_8822b[] = {
+ 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
+ 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12};
+
+static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type3_type5_8822b[] = {
+ 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15};
+
+static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type3_type5_8822b[] = {
+ 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
+ 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12};
+
+static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type3_type5_8822b[] = {
+ 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15};
+
+void odm_read_and_config_mp_8822b_txpowertrack_type3_type5(
+ struct phy_dm_struct *dm)
+{
+ struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
+
+ ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n");
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p,
+ delta_swing_index_mp_2ga_p_txpwrtrack_type3_type5_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n,
+ delta_swing_index_mp_2ga_n_txpwrtrack_type3_type5_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p,
+ delta_swing_index_mp_2gb_p_txpwrtrack_type3_type5_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n,
+ delta_swing_index_mp_2gb_n_txpwrtrack_type3_type5_8822b,
+ DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(
+ dm, cali_info->delta_swing_table_idx_2g_cck_a_p,
+ delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type3_type5_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(
+ dm, cali_info->delta_swing_table_idx_2g_cck_a_n,
+ delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type3_type5_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(
+ dm, cali_info->delta_swing_table_idx_2g_cck_b_p,
+ delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type3_type5_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(
+ dm, cali_info->delta_swing_table_idx_2g_cck_b_n,
+ delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type3_type5_8822b,
+ DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p,
+ delta_swing_index_mp_5ga_p_txpwrtrack_type3_type5_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n,
+ delta_swing_index_mp_5ga_n_txpwrtrack_type3_type5_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p,
+ delta_swing_index_mp_5gb_p_txpwrtrack_type3_type5_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n,
+ delta_swing_index_mp_5gb_n_txpwrtrack_type3_type5_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+}
+
+/******************************************************************************
+ * txpowertrack_type4.TXT
+ ******************************************************************************/
+
+static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type4_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11,
+ 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22},
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11,
+ 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22},
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11,
+ 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22},
+};
+
+static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type4_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11,
+ 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23},
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11,
+ 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23},
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11,
+ 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23},
+};
+
+static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type4_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11,
+ 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22},
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11,
+ 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22},
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11,
+ 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22},
+};
+
+static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type4_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11,
+ 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23},
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11,
+ 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23},
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11,
+ 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23},
+};
+
+static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type4_8822b[] = {
+ 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
+ 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12};
+
+static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type4_8822b[] = {
+ 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15};
+
+static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type4_8822b[] = {
+ 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
+ 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12};
+
+static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type4_8822b[] = {
+ 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15};
+
+static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type4_8822b[] = {
+ 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
+ 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12};
+
+static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type4_8822b[] = {
+ 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15};
+
+static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type4_8822b[] = {
+ 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
+ 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12};
+
+static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type4_8822b[] = {
+ 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15};
+
+void odm_read_and_config_mp_8822b_txpowertrack_type4(struct phy_dm_struct *dm)
+{
+ struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
+
+ ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n");
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p,
+ delta_swing_index_mp_2ga_p_txpwrtrack_type4_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n,
+ delta_swing_index_mp_2ga_n_txpwrtrack_type4_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p,
+ delta_swing_index_mp_2gb_p_txpwrtrack_type4_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n,
+ delta_swing_index_mp_2gb_n_txpwrtrack_type4_8822b,
+ DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p,
+ delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type4_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n,
+ delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type4_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p,
+ delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type4_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n,
+ delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type4_8822b,
+ DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p,
+ delta_swing_index_mp_5ga_p_txpwrtrack_type4_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n,
+ delta_swing_index_mp_5ga_n_txpwrtrack_type4_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p,
+ delta_swing_index_mp_5gb_p_txpwrtrack_type4_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n,
+ delta_swing_index_mp_5gb_n_txpwrtrack_type4_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+}
+
+/******************************************************************************
+ * txpowertrack_type6.TXT
+ ******************************************************************************/
+
+static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type6_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 10,
+ 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15},
+ {0, 1, 2, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 10,
+ 11, 12, 12, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16},
+ {0, 1, 2, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12,
+ 12, 13, 13, 14, 15, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17},
+};
+
+static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type6_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 11,
+ 12, 13, 14, 15, 15, 16, 17, 18, 18, 19, 19, 19, 19, 19, 19},
+ {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 9, 11, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 20, 21, 21, 21, 21, 21, 21},
+ {0, 1, 2, 3, 4, 5, 6, 6, 7, 7, 8, 9, 10, 11, 12,
+ 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 20, 20, 21, 21, 21},
+};
+
+static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type6_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11,
+ 12, 12, 13, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 17, 17},
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10,
+ 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 15, 15, 15},
+ {0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 9, 9, 10,
+ 11, 12, 12, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16},
+};
+
+static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type6_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 12,
+ 13, 14, 15, 15, 16, 17, 18, 19, 20, 20, 21, 21, 21, 21, 21},
+ {0, 1, 2, 2, 3, 4, 4, 5, 7, 7, 8, 9, 10, 11, 11,
+ 12, 13, 13, 14, 15, 16, 17, 18, 18, 19, 19, 20, 20, 21, 21},
+ {0, 1, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 14, 15, 16, 17, 17, 18, 19, 19, 20, 20, 20, 20, 20},
+};
+
+static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type6_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 13, 14, 15, 16, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18};
+
+static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type6_8822b[] = {
+ 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 11,
+ 12, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 22, 22};
+
+static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type6_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12,
+ 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18};
+
+static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type6_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
+ 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22};
+
+static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type6_8822b[] = {
+ 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 13, 14, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17};
+
+static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type6_8822b[] = {
+ 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 9, 10, 11,
+ 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22};
+
+static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type6_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18};
+
+static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type6_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
+ 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22};
+
+void odm_read_and_config_mp_8822b_txpowertrack_type6(struct phy_dm_struct *dm)
+{
+ struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
+
+ ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n");
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p,
+ delta_swing_index_mp_2ga_p_txpwrtrack_type6_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n,
+ delta_swing_index_mp_2ga_n_txpwrtrack_type6_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p,
+ delta_swing_index_mp_2gb_p_txpwrtrack_type6_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n,
+ delta_swing_index_mp_2gb_n_txpwrtrack_type6_8822b,
+ DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p,
+ delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type6_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n,
+ delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type6_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p,
+ delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type6_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n,
+ delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type6_8822b,
+ DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p,
+ delta_swing_index_mp_5ga_p_txpwrtrack_type6_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n,
+ delta_swing_index_mp_5ga_n_txpwrtrack_type6_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p,
+ delta_swing_index_mp_5gb_p_txpwrtrack_type6_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n,
+ delta_swing_index_mp_5gb_n_txpwrtrack_type6_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+}
+
+/******************************************************************************
+ * txpowertrack_type7.TXT
+ ******************************************************************************/
+
+static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type7_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 10,
+ 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15},
+ {0, 1, 2, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 10,
+ 11, 12, 12, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16},
+ {0, 1, 2, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12,
+ 12, 13, 13, 14, 15, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17},
+};
+
+static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type7_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 11,
+ 12, 13, 14, 15, 15, 16, 17, 18, 18, 19, 19, 19, 19, 19, 19},
+ {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 9, 11, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 20, 21, 21, 21, 21, 21, 21},
+ {0, 1, 2, 3, 4, 5, 6, 6, 7, 7, 8, 9, 10, 11, 12,
+ 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 20, 20, 21, 21, 21},
+};
+
+static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type7_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11,
+ 12, 12, 13, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 17, 17},
+ {0, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10,
+ 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 15, 15, 15},
+ {0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 9, 9, 10,
+ 11, 12, 12, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16},
+};
+
+static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type7_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 12,
+ 13, 14, 15, 15, 16, 17, 18, 19, 20, 20, 21, 21, 21, 21, 21},
+ {0, 1, 2, 2, 3, 4, 4, 5, 7, 7, 8, 9, 10, 11, 11,
+ 12, 13, 13, 14, 15, 16, 17, 18, 18, 19, 19, 20, 20, 21, 21},
+ {0, 1, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 14, 15, 16, 17, 17, 18, 19, 19, 20, 20, 20, 20, 20},
+};
+
+static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type7_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 13, 14, 15, 16, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18};
+
+static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type7_8822b[] = {
+ 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 11,
+ 12, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 22, 22};
+
+static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type7_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12,
+ 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18};
+
+static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type7_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
+ 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22};
+
+static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type7_8822b[] = {
+ 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 13, 14, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17};
+
+static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type7_8822b[] = {
+ 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 9, 10, 11,
+ 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22};
+
+static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type7_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18};
+
+static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type7_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
+ 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22};
+
+void odm_read_and_config_mp_8822b_txpowertrack_type7(struct phy_dm_struct *dm)
+{
+ struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
+
+ ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n");
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p,
+ delta_swing_index_mp_2ga_p_txpwrtrack_type7_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n,
+ delta_swing_index_mp_2ga_n_txpwrtrack_type7_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p,
+ delta_swing_index_mp_2gb_p_txpwrtrack_type7_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n,
+ delta_swing_index_mp_2gb_n_txpwrtrack_type7_8822b,
+ DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p,
+ delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type7_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n,
+ delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type7_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p,
+ delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type7_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n,
+ delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type7_8822b,
+ DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p,
+ delta_swing_index_mp_5ga_p_txpwrtrack_type7_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n,
+ delta_swing_index_mp_5ga_n_txpwrtrack_type7_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p,
+ delta_swing_index_mp_5gb_p_txpwrtrack_type7_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n,
+ delta_swing_index_mp_5gb_n_txpwrtrack_type7_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+}
+
+/******************************************************************************
+ * txpowertrack_type8.TXT
+ ******************************************************************************/
+
+static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type8_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15},
+};
+
+static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type8_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8,
+ 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17},
+ {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8,
+ 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17},
+ {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8,
+ 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17},
+};
+
+static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type8_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15},
+};
+
+static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type8_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8,
+ 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17},
+ {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8,
+ 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17},
+ {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8,
+ 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17},
+};
+
+static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type8_8822b[] = {
+ 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
+ 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12};
+
+static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type8_8822b[] = {
+ 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15};
+
+static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type8_8822b[] = {
+ 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
+ 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12};
+
+static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type8_8822b[] = {
+ 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15};
+
+static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type8_8822b[] = {
+ 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
+ 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12};
+
+static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type8_8822b[] = {
+ 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15};
+
+static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type8_8822b[] = {
+ 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
+ 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12};
+
+static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type8_8822b[] = {
+ 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15};
+
+void odm_read_and_config_mp_8822b_txpowertrack_type8(struct phy_dm_struct *dm)
+{
+ struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
+
+ ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n");
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p,
+ delta_swing_index_mp_2ga_p_txpwrtrack_type8_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n,
+ delta_swing_index_mp_2ga_n_txpwrtrack_type8_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p,
+ delta_swing_index_mp_2gb_p_txpwrtrack_type8_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n,
+ delta_swing_index_mp_2gb_n_txpwrtrack_type8_8822b,
+ DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p,
+ delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type8_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n,
+ delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type8_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p,
+ delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type8_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n,
+ delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type8_8822b,
+ DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p,
+ delta_swing_index_mp_5ga_p_txpwrtrack_type8_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n,
+ delta_swing_index_mp_5ga_n_txpwrtrack_type8_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p,
+ delta_swing_index_mp_5gb_p_txpwrtrack_type8_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n,
+ delta_swing_index_mp_5gb_n_txpwrtrack_type8_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+}
+
+/******************************************************************************
+ * txpowertrack_type9.TXT
+ ******************************************************************************/
+
+static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type9_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14, 14},
+ {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8,
+ 9, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15},
+};
+
+static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type9_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 15, 15},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 9, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 15},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 10, 10, 11, 12, 13, 14, 14, 15, 15, 15, 16, 16},
+};
+
+static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type9_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14, 14},
+};
+
+static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type9_8822b
+ [][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 9, 10, 10, 11, 12, 13, 13, 14, 14, 15, 15, 15},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 15, 15},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 15},
+};
+
+static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type9_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 13, 14, 15, 16, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18};
+
+static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type9_8822b[] = {
+ 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 11,
+ 12, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 22, 22};
+
+static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type9_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12,
+ 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18};
+
+static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type9_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
+ 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22};
+
+static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type9_8822b[] = {
+ 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 13, 14, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17};
+
+static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type9_8822b[] = {
+ 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 9, 10, 11,
+ 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22};
+
+static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type9_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18};
+
+static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type9_8822b[] = {
+ 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
+ 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22};
+
+void odm_read_and_config_mp_8822b_txpowertrack_type9(struct phy_dm_struct *dm)
+{
+ struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
+
+ ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n");
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p,
+ delta_swing_index_mp_2ga_p_txpwrtrack_type9_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n,
+ delta_swing_index_mp_2ga_n_txpwrtrack_type9_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p,
+ delta_swing_index_mp_2gb_p_txpwrtrack_type9_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n,
+ delta_swing_index_mp_2gb_n_txpwrtrack_type9_8822b,
+ DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p,
+ delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type9_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n,
+ delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type9_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p,
+ delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type9_8822b,
+ DELTA_SWINGIDX_SIZE);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n,
+ delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type9_8822b,
+ DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p,
+ delta_swing_index_mp_5ga_p_txpwrtrack_type9_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n,
+ delta_swing_index_mp_5ga_n_txpwrtrack_type9_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p,
+ delta_swing_index_mp_5gb_p_txpwrtrack_type9_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n,
+ delta_swing_index_mp_5gb_n_txpwrtrack_type9_8822b,
+ DELTA_SWINGIDX_SIZE * 3);
+}
+
+/******************************************************************************
+ * txpwr_lmt.TXT
+ ******************************************************************************/
+
+static const char *const array_mp_8822b_txpwr_lmt[] = {
+ "FCC", "2.4G", "20M", "CCK", "1T", "01", "32", "ETSI", "2.4G",
+ "20M", "CCK", "1T", "01", "28", "MKK", "2.4G", "20M", "CCK",
+ "1T", "01", "30", "FCC", "2.4G", "20M", "CCK", "1T", "02",
+ "32", "ETSI", "2.4G", "20M", "CCK", "1T", "02", "28", "MKK",
+ "2.4G", "20M", "CCK", "1T", "02", "30", "FCC", "2.4G", "20M",
+ "CCK", "1T", "03", "32", "ETSI", "2.4G", "20M", "CCK", "1T",
+ "03", "28", "MKK", "2.4G", "20M", "CCK", "1T", "03", "30",
+ "FCC", "2.4G", "20M", "CCK", "1T", "04", "32", "ETSI", "2.4G",
+ "20M", "CCK", "1T", "04", "28", "MKK", "2.4G", "20M", "CCK",
+ "1T", "04", "30", "FCC", "2.4G", "20M", "CCK", "1T", "05",
+ "32", "ETSI", "2.4G", "20M", "CCK", "1T", "05", "28", "MKK",
+ "2.4G", "20M", "CCK", "1T", "05", "30", "FCC", "2.4G", "20M",
+ "CCK", "1T", "06", "32", "ETSI", "2.4G", "20M", "CCK", "1T",
+ "06", "28", "MKK", "2.4G", "20M", "CCK", "1T", "06", "30",
+ "FCC", "2.4G", "20M", "CCK", "1T", "07", "32", "ETSI", "2.4G",
+ "20M", "CCK", "1T", "07", "28", "MKK", "2.4G", "20M", "CCK",
+ "1T", "07", "30", "FCC", "2.4G", "20M", "CCK", "1T", "08",
+ "32", "ETSI", "2.4G", "20M", "CCK", "1T", "08", "28", "MKK",
+ "2.4G", "20M", "CCK", "1T", "08", "30", "FCC", "2.4G", "20M",
+ "CCK", "1T", "09", "32", "ETSI", "2.4G", "20M", "CCK", "1T",
+ "09", "28", "MKK", "2.4G", "20M", "CCK", "1T", "09", "30",
+ "FCC", "2.4G", "20M", "CCK", "1T", "10", "32", "ETSI", "2.4G",
+ "20M", "CCK", "1T", "10", "28", "MKK", "2.4G", "20M", "CCK",
+ "1T", "10", "30", "FCC", "2.4G", "20M", "CCK", "1T", "11",
+ "32", "ETSI", "2.4G", "20M", "CCK", "1T", "11", "28", "MKK",
+ "2.4G", "20M", "CCK", "1T", "11", "30", "FCC", "2.4G", "20M",
+ "CCK", "1T", "12", "26", "ETSI", "2.4G", "20M", "CCK", "1T",
+ "12", "28", "MKK", "2.4G", "20M", "CCK", "1T", "12", "30",
+ "FCC", "2.4G", "20M", "CCK", "1T", "13", "20", "ETSI", "2.4G",
+ "20M", "CCK", "1T", "13", "28", "MKK", "2.4G", "20M", "CCK",
+ "1T", "13", "28", "FCC", "2.4G", "20M", "CCK", "1T", "14",
+ "63", "ETSI", "2.4G", "20M", "CCK", "1T", "14", "63", "MKK",
+ "2.4G", "20M", "CCK", "1T", "14", "32", "FCC", "2.4G", "20M",
+ "OFDM", "1T", "01", "26", "ETSI", "2.4G", "20M", "OFDM", "1T",
+ "01", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "01", "34",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "02", "30", "ETSI", "2.4G",
+ "20M", "OFDM", "1T", "02", "30", "MKK", "2.4G", "20M", "OFDM",
+ "1T", "02", "34", "FCC", "2.4G", "20M", "OFDM", "1T", "03",
+ "32", "ETSI", "2.4G", "20M", "OFDM", "1T", "03", "30", "MKK",
+ "2.4G", "20M", "OFDM", "1T", "03", "34", "FCC", "2.4G", "20M",
+ "OFDM", "1T", "04", "34", "ETSI", "2.4G", "20M", "OFDM", "1T",
+ "04", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "04", "34",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "05", "34", "ETSI", "2.4G",
+ "20M", "OFDM", "1T", "05", "30", "MKK", "2.4G", "20M", "OFDM",
+ "1T", "05", "34", "FCC", "2.4G", "20M", "OFDM", "1T", "06",
+ "34", "ETSI", "2.4G", "20M", "OFDM", "1T", "06", "30", "MKK",
+ "2.4G", "20M", "OFDM", "1T", "06", "34", "FCC", "2.4G", "20M",
+ "OFDM", "1T", "07", "34", "ETSI", "2.4G", "20M", "OFDM", "1T",
+ "07", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "07", "34",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "08", "34", "ETSI", "2.4G",
+ "20M", "OFDM", "1T", "08", "30", "MKK", "2.4G", "20M", "OFDM",
+ "1T", "08", "34", "FCC", "2.4G", "20M", "OFDM", "1T", "09",
+ "32", "ETSI", "2.4G", "20M", "OFDM", "1T", "09", "30", "MKK",
+ "2.4G", "20M", "OFDM", "1T", "09", "34", "FCC", "2.4G", "20M",
+ "OFDM", "1T", "10", "30", "ETSI", "2.4G", "20M", "OFDM", "1T",
+ "10", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "10", "34",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "11", "28", "ETSI", "2.4G",
+ "20M", "OFDM", "1T", "11", "30", "MKK", "2.4G", "20M", "OFDM",
+ "1T", "11", "34", "FCC", "2.4G", "20M", "OFDM", "1T", "12",
+ "22", "ETSI", "2.4G", "20M", "OFDM", "1T", "12", "30", "MKK",
+ "2.4G", "20M", "OFDM", "1T", "12", "34", "FCC", "2.4G", "20M",
+ "OFDM", "1T", "13", "14", "ETSI", "2.4G", "20M", "OFDM", "1T",
+ "13", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "13", "34",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "14", "63", "ETSI", "2.4G",
+ "20M", "OFDM", "1T", "14", "63", "MKK", "2.4G", "20M", "OFDM",
+ "1T", "14", "63", "FCC", "2.4G", "20M", "HT", "1T", "01",
+ "26", "ETSI", "2.4G", "20M", "HT", "1T", "01", "30", "MKK",
+ "2.4G", "20M", "HT", "1T", "01", "34", "FCC", "2.4G", "20M",
+ "HT", "1T", "02", "30", "ETSI", "2.4G", "20M", "HT", "1T",
+ "02", "30", "MKK", "2.4G", "20M", "HT", "1T", "02", "34",
+ "FCC", "2.4G", "20M", "HT", "1T", "03", "32", "ETSI", "2.4G",
+ "20M", "HT", "1T", "03", "30", "MKK", "2.4G", "20M", "HT",
+ "1T", "03", "34", "FCC", "2.4G", "20M", "HT", "1T", "04",
+ "34", "ETSI", "2.4G", "20M", "HT", "1T", "04", "30", "MKK",
+ "2.4G", "20M", "HT", "1T", "04", "34", "FCC", "2.4G", "20M",
+ "HT", "1T", "05", "34", "ETSI", "2.4G", "20M", "HT", "1T",
+ "05", "30", "MKK", "2.4G", "20M", "HT", "1T", "05", "34",
+ "FCC", "2.4G", "20M", "HT", "1T", "06", "34", "ETSI", "2.4G",
+ "20M", "HT", "1T", "06", "30", "MKK", "2.4G", "20M", "HT",
+ "1T", "06", "34", "FCC", "2.4G", "20M", "HT", "1T", "07",
+ "34", "ETSI", "2.4G", "20M", "HT", "1T", "07", "30", "MKK",
+ "2.4G", "20M", "HT", "1T", "07", "34", "FCC", "2.4G", "20M",
+ "HT", "1T", "08", "34", "ETSI", "2.4G", "20M", "HT", "1T",
+ "08", "30", "MKK", "2.4G", "20M", "HT", "1T", "08", "34",
+ "FCC", "2.4G", "20M", "HT", "1T", "09", "32", "ETSI", "2.4G",
+ "20M", "HT", "1T", "09", "30", "MKK", "2.4G", "20M", "HT",
+ "1T", "09", "34", "FCC", "2.4G", "20M", "HT", "1T", "10",
+ "30", "ETSI", "2.4G", "20M", "HT", "1T", "10", "30", "MKK",
+ "2.4G", "20M", "HT", "1T", "10", "34", "FCC", "2.4G", "20M",
+ "HT", "1T", "11", "26", "ETSI", "2.4G", "20M", "HT", "1T",
+ "11", "30", "MKK", "2.4G", "20M", "HT", "1T", "11", "34",
+ "FCC", "2.4G", "20M", "HT", "1T", "12", "20", "ETSI", "2.4G",
+ "20M", "HT", "1T", "12", "30", "MKK", "2.4G", "20M", "HT",
+ "1T", "12", "34", "FCC", "2.4G", "20M", "HT", "1T", "13",
+ "14", "ETSI", "2.4G", "20M", "HT", "1T", "13", "30", "MKK",
+ "2.4G", "20M", "HT", "1T", "13", "34", "FCC", "2.4G", "20M",
+ "HT", "1T", "14", "63", "ETSI", "2.4G", "20M", "HT", "1T",
+ "14", "63", "MKK", "2.4G", "20M", "HT", "1T", "14", "63",
+ "FCC", "2.4G", "20M", "HT", "2T", "01", "26", "ETSI", "2.4G",
+ "20M", "HT", "2T", "01", "18", "MKK", "2.4G", "20M", "HT",
+ "2T", "01", "30", "FCC", "2.4G", "20M", "HT", "2T", "02",
+ "28", "ETSI", "2.4G", "20M", "HT", "2T", "02", "18", "MKK",
+ "2.4G", "20M", "HT", "2T", "02", "30", "FCC", "2.4G", "20M",
+ "HT", "2T", "03", "30", "ETSI", "2.4G", "20M", "HT", "2T",
+ "03", "18", "MKK", "2.4G", "20M", "HT", "2T", "03", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "04", "30", "ETSI", "2.4G",
+ "20M", "HT", "2T", "04", "18", "MKK", "2.4G", "20M", "HT",
+ "2T", "04", "30", "FCC", "2.4G", "20M", "HT", "2T", "05",
+ "32", "ETSI", "2.4G", "20M", "HT", "2T", "05", "18", "MKK",
+ "2.4G", "20M", "HT", "2T", "05", "30", "FCC", "2.4G", "20M",
+ "HT", "2T", "06", "32", "ETSI", "2.4G", "20M", "HT", "2T",
+ "06", "18", "MKK", "2.4G", "20M", "HT", "2T", "06", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "07", "32", "ETSI", "2.4G",
+ "20M", "HT", "2T", "07", "18", "MKK", "2.4G", "20M", "HT",
+ "2T", "07", "30", "FCC", "2.4G", "20M", "HT", "2T", "08",
+ "30", "ETSI", "2.4G", "20M", "HT", "2T", "08", "18", "MKK",
+ "2.4G", "20M", "HT", "2T", "08", "30", "FCC", "2.4G", "20M",
+ "HT", "2T", "09", "30", "ETSI", "2.4G", "20M", "HT", "2T",
+ "09", "18", "MKK", "2.4G", "20M", "HT", "2T", "09", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "10", "28", "ETSI", "2.4G",
+ "20M", "HT", "2T", "10", "18", "MKK", "2.4G", "20M", "HT",
+ "2T", "10", "30", "FCC", "2.4G", "20M", "HT", "2T", "11",
+ "26", "ETSI", "2.4G", "20M", "HT", "2T", "11", "18", "MKK",
+ "2.4G", "20M", "HT", "2T", "11", "30", "FCC", "2.4G", "20M",
+ "HT", "2T", "12", "20", "ETSI", "2.4G", "20M", "HT", "2T",
+ "12", "18", "MKK", "2.4G", "20M", "HT", "2T", "12", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "13", "14", "ETSI", "2.4G",
+ "20M", "HT", "2T", "13", "18", "MKK", "2.4G", "20M", "HT",
+ "2T", "13", "30", "FCC", "2.4G", "20M", "HT", "2T", "14",
+ "63", "ETSI", "2.4G", "20M", "HT", "2T", "14", "63", "MKK",
+ "2.4G", "20M", "HT", "2T", "14", "63", "FCC", "2.4G", "40M",
+ "HT", "1T", "01", "63", "ETSI", "2.4G", "40M", "HT", "1T",
+ "01", "63", "MKK", "2.4G", "40M", "HT", "1T", "01", "63",
+ "FCC", "2.4G", "40M", "HT", "1T", "02", "63", "ETSI", "2.4G",
+ "40M", "HT", "1T", "02", "63", "MKK", "2.4G", "40M", "HT",
+ "1T", "02", "63", "FCC", "2.4G", "40M", "HT", "1T", "03",
+ "26", "ETSI", "2.4G", "40M", "HT", "1T", "03", "30", "MKK",
+ "2.4G", "40M", "HT", "1T", "03", "34", "FCC", "2.4G", "40M",
+ "HT", "1T", "04", "26", "ETSI", "2.4G", "40M", "HT", "1T",
+ "04", "30", "MKK", "2.4G", "40M", "HT", "1T", "04", "34",
+ "FCC", "2.4G", "40M", "HT", "1T", "05", "30", "ETSI", "2.4G",
+ "40M", "HT", "1T", "05", "30", "MKK", "2.4G", "40M", "HT",
+ "1T", "05", "34", "FCC", "2.4G", "40M", "HT", "1T", "06",
+ "32", "ETSI", "2.4G", "40M", "HT", "1T", "06", "30", "MKK",
+ "2.4G", "40M", "HT", "1T", "06", "34", "FCC", "2.4G", "40M",
+ "HT", "1T", "07", "30", "ETSI", "2.4G", "40M", "HT", "1T",
+ "07", "30", "MKK", "2.4G", "40M", "HT", "1T", "07", "34",
+ "FCC", "2.4G", "40M", "HT", "1T", "08", "26", "ETSI", "2.4G",
+ "40M", "HT", "1T", "08", "30", "MKK", "2.4G", "40M", "HT",
+ "1T", "08", "34", "FCC", "2.4G", "40M", "HT", "1T", "09",
+ "26", "ETSI", "2.4G", "40M", "HT", "1T", "09", "30", "MKK",
+ "2.4G", "40M", "HT", "1T", "09", "34", "FCC", "2.4G", "40M",
+ "HT", "1T", "10", "20", "ETSI", "2.4G", "40M", "HT", "1T",
+ "10", "30", "MKK", "2.4G", "40M", "HT", "1T", "10", "34",
+ "FCC", "2.4G", "40M", "HT", "1T", "11", "14", "ETSI", "2.4G",
+ "40M", "HT", "1T", "11", "30", "MKK", "2.4G", "40M", "HT",
+ "1T", "11", "34", "FCC", "2.4G", "40M", "HT", "1T", "12",
+ "63", "ETSI", "2.4G", "40M", "HT", "1T", "12", "63", "MKK",
+ "2.4G", "40M", "HT", "1T", "12", "63", "FCC", "2.4G", "40M",
+ "HT", "1T", "13", "63", "ETSI", "2.4G", "40M", "HT", "1T",
+ "13", "63", "MKK", "2.4G", "40M", "HT", "1T", "13", "63",
+ "FCC", "2.4G", "40M", "HT", "1T", "14", "63", "ETSI", "2.4G",
+ "40M", "HT", "1T", "14", "63", "MKK", "2.4G", "40M", "HT",
+ "1T", "14", "63", "FCC", "2.4G", "40M", "HT", "2T", "01",
+ "63", "ETSI", "2.4G", "40M", "HT", "2T", "01", "63", "MKK",
+ "2.4G", "40M", "HT", "2T", "01", "63", "FCC", "2.4G", "40M",
+ "HT", "2T", "02", "63", "ETSI", "2.4G", "40M", "HT", "2T",
+ "02", "63", "MKK", "2.4G", "40M", "HT", "2T", "02", "63",
+ "FCC", "2.4G", "40M", "HT", "2T", "03", "24", "ETSI", "2.4G",
+ "40M", "HT", "2T", "03", "18", "MKK", "2.4G", "40M", "HT",
+ "2T", "03", "30", "FCC", "2.4G", "40M", "HT", "2T", "04",
+ "24", "ETSI", "2.4G", "40M", "HT", "2T", "04", "18", "MKK",
+ "2.4G", "40M", "HT", "2T", "04", "30", "FCC", "2.4G", "40M",
+ "HT", "2T", "05", "26", "ETSI", "2.4G", "40M", "HT", "2T",
+ "05", "18", "MKK", "2.4G", "40M", "HT", "2T", "05", "30",
+ "FCC", "2.4G", "40M", "HT", "2T", "06", "28", "ETSI", "2.4G",
+ "40M", "HT", "2T", "06", "18", "MKK", "2.4G", "40M", "HT",
+ "2T", "06", "30", "FCC", "2.4G", "40M", "HT", "2T", "07",
+ "26", "ETSI", "2.4G", "40M", "HT", "2T", "07", "18", "MKK",
+ "2.4G", "40M", "HT", "2T", "07", "30", "FCC", "2.4G", "40M",
+ "HT", "2T", "08", "26", "ETSI", "2.4G", "40M", "HT", "2T",
+ "08", "18", "MKK", "2.4G", "40M", "HT", "2T", "08", "30",
+ "FCC", "2.4G", "40M", "HT", "2T", "09", "26", "ETSI", "2.4G",
+ "40M", "HT", "2T", "09", "18", "MKK", "2.4G", "40M", "HT",
+ "2T", "09", "30", "FCC", "2.4G", "40M", "HT", "2T", "10",
+ "20", "ETSI", "2.4G", "40M", "HT", "2T", "10", "18", "MKK",
+ "2.4G", "40M", "HT", "2T", "10", "30", "FCC", "2.4G", "40M",
+ "HT", "2T", "11", "14", "ETSI", "2.4G", "40M", "HT", "2T",
+ "11", "18", "MKK", "2.4G", "40M", "HT", "2T", "11", "30",
+ "FCC", "2.4G", "40M", "HT", "2T", "12", "63", "ETSI", "2.4G",
+ "40M", "HT", "2T", "12", "63", "MKK", "2.4G", "40M", "HT",
+ "2T", "12", "63", "FCC", "2.4G", "40M", "HT", "2T", "13",
+ "63", "ETSI", "2.4G", "40M", "HT", "2T", "13", "63", "MKK",
+ "2.4G", "40M", "HT", "2T", "13", "63", "FCC", "2.4G", "40M",
+ "HT", "2T", "14", "63", "ETSI", "2.4G", "40M", "HT", "2T",
+ "14", "63", "MKK", "2.4G", "40M", "HT", "2T", "14", "63",
+ "FCC", "5G", "20M", "OFDM", "1T", "36", "30", "ETSI", "5G",
+ "20M", "OFDM", "1T", "36", "32", "MKK", "5G", "20M", "OFDM",
+ "1T", "36", "30", "FCC", "5G", "20M", "OFDM", "1T", "40",
+ "32", "ETSI", "5G", "20M", "OFDM", "1T", "40", "32", "MKK",
+ "5G", "20M", "OFDM", "1T", "40", "30", "FCC", "5G", "20M",
+ "OFDM", "1T", "44", "32", "ETSI", "5G", "20M", "OFDM", "1T",
+ "44", "32", "MKK", "5G", "20M", "OFDM", "1T", "44", "30",
+ "FCC", "5G", "20M", "OFDM", "1T", "48", "32", "ETSI", "5G",
+ "20M", "OFDM", "1T", "48", "32", "MKK", "5G", "20M", "OFDM",
+ "1T", "48", "30", "FCC", "5G", "20M", "OFDM", "1T", "52",
+ "32", "ETSI", "5G", "20M", "OFDM", "1T", "52", "32", "MKK",
+ "5G", "20M", "OFDM", "1T", "52", "28", "FCC", "5G", "20M",
+ "OFDM", "1T", "56", "32", "ETSI", "5G", "20M", "OFDM", "1T",
+ "56", "32", "MKK", "5G", "20M", "OFDM", "1T", "56", "28",
+ "FCC", "5G", "20M", "OFDM", "1T", "60", "32", "ETSI", "5G",
+ "20M", "OFDM", "1T", "60", "32", "MKK", "5G", "20M", "OFDM",
+ "1T", "60", "28", "FCC", "5G", "20M", "OFDM", "1T", "64",
+ "28", "ETSI", "5G", "20M", "OFDM", "1T", "64", "32", "MKK",
+ "5G", "20M", "OFDM", "1T", "64", "28", "FCC", "5G", "20M",
+ "OFDM", "1T", "100", "26", "ETSI", "5G", "20M", "OFDM", "1T",
+ "100", "32", "MKK", "5G", "20M", "OFDM", "1T", "100", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "104", "32", "ETSI", "5G",
+ "20M", "OFDM", "1T", "104", "32", "MKK", "5G", "20M", "OFDM",
+ "1T", "104", "32", "FCC", "5G", "20M", "OFDM", "1T", "108",
+ "32", "ETSI", "5G", "20M", "OFDM", "1T", "108", "32", "MKK",
+ "5G", "20M", "OFDM", "1T", "108", "32", "FCC", "5G", "20M",
+ "OFDM", "1T", "112", "32", "ETSI", "5G", "20M", "OFDM", "1T",
+ "112", "32", "MKK", "5G", "20M", "OFDM", "1T", "112", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "116", "32", "ETSI", "5G",
+ "20M", "OFDM", "1T", "116", "32", "MKK", "5G", "20M", "OFDM",
+ "1T", "116", "32", "FCC", "5G", "20M", "OFDM", "1T", "120",
+ "32", "ETSI", "5G", "20M", "OFDM", "1T", "120", "32", "MKK",
+ "5G", "20M", "OFDM", "1T", "120", "32", "FCC", "5G", "20M",
+ "OFDM", "1T", "124", "32", "ETSI", "5G", "20M", "OFDM", "1T",
+ "124", "32", "MKK", "5G", "20M", "OFDM", "1T", "124", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "128", "32", "ETSI", "5G",
+ "20M", "OFDM", "1T", "128", "32", "MKK", "5G", "20M", "OFDM",
+ "1T", "128", "32", "FCC", "5G", "20M", "OFDM", "1T", "132",
+ "32", "ETSI", "5G", "20M", "OFDM", "1T", "132", "32", "MKK",
+ "5G", "20M", "OFDM", "1T", "132", "32", "FCC", "5G", "20M",
+ "OFDM", "1T", "136", "32", "ETSI", "5G", "20M", "OFDM", "1T",
+ "136", "32", "MKK", "5G", "20M", "OFDM", "1T", "136", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "140", "28", "ETSI", "5G",
+ "20M", "OFDM", "1T", "140", "32", "MKK", "5G", "20M", "OFDM",
+ "1T", "140", "32", "FCC", "5G", "20M", "OFDM", "1T", "144",
+ "28", "ETSI", "5G", "20M", "OFDM", "1T", "144", "32", "MKK",
+ "5G", "20M", "OFDM", "1T", "144", "63", "FCC", "5G", "20M",
+ "OFDM", "1T", "149", "32", "ETSI", "5G", "20M", "OFDM", "1T",
+ "149", "63", "MKK", "5G", "20M", "OFDM", "1T", "149", "63",
+ "FCC", "5G", "20M", "OFDM", "1T", "153", "32", "ETSI", "5G",
+ "20M", "OFDM", "1T", "153", "63", "MKK", "5G", "20M", "OFDM",
+ "1T", "153", "63", "FCC", "5G", "20M", "OFDM", "1T", "157",
+ "32", "ETSI", "5G", "20M", "OFDM", "1T", "157", "63", "MKK",
+ "5G", "20M", "OFDM", "1T", "157", "63", "FCC", "5G", "20M",
+ "OFDM", "1T", "161", "32", "ETSI", "5G", "20M", "OFDM", "1T",
+ "161", "63", "MKK", "5G", "20M", "OFDM", "1T", "161", "63",
+ "FCC", "5G", "20M", "OFDM", "1T", "165", "32", "ETSI", "5G",
+ "20M", "OFDM", "1T", "165", "63", "MKK", "5G", "20M", "OFDM",
+ "1T", "165", "63", "FCC", "5G", "20M", "HT", "1T", "36",
+ "30", "ETSI", "5G", "20M", "HT", "1T", "36", "32", "MKK",
+ "5G", "20M", "HT", "1T", "36", "28", "FCC", "5G", "20M",
+ "HT", "1T", "40", "32", "ETSI", "5G", "20M", "HT", "1T",
+ "40", "32", "MKK", "5G", "20M", "HT", "1T", "40", "28",
+ "FCC", "5G", "20M", "HT", "1T", "44", "32", "ETSI", "5G",
+ "20M", "HT", "1T", "44", "32", "MKK", "5G", "20M", "HT",
+ "1T", "44", "28", "FCC", "5G", "20M", "HT", "1T", "48",
+ "32", "ETSI", "5G", "20M", "HT", "1T", "48", "32", "MKK",
+ "5G", "20M", "HT", "1T", "48", "28", "FCC", "5G", "20M",
+ "HT", "1T", "52", "32", "ETSI", "5G", "20M", "HT", "1T",
+ "52", "32", "MKK", "5G", "20M", "HT", "1T", "52", "28",
+ "FCC", "5G", "20M", "HT", "1T", "56", "32", "ETSI", "5G",
+ "20M", "HT", "1T", "56", "32", "MKK", "5G", "20M", "HT",
+ "1T", "56", "28", "FCC", "5G", "20M", "HT", "1T", "60",
+ "32", "ETSI", "5G", "20M", "HT", "1T", "60", "32", "MKK",
+ "5G", "20M", "HT", "1T", "60", "28", "FCC", "5G", "20M",
+ "HT", "1T", "64", "28", "ETSI", "5G", "20M", "HT", "1T",
+ "64", "32", "MKK", "5G", "20M", "HT", "1T", "64", "28",
+ "FCC", "5G", "20M", "HT", "1T", "100", "26", "ETSI", "5G",
+ "20M", "HT", "1T", "100", "32", "MKK", "5G", "20M", "HT",
+ "1T", "100", "32", "FCC", "5G", "20M", "HT", "1T", "104",
+ "32", "ETSI", "5G", "20M", "HT", "1T", "104", "32", "MKK",
+ "5G", "20M", "HT", "1T", "104", "32", "FCC", "5G", "20M",
+ "HT", "1T", "108", "32", "ETSI", "5G", "20M", "HT", "1T",
+ "108", "32", "MKK", "5G", "20M", "HT", "1T", "108", "32",
+ "FCC", "5G", "20M", "HT", "1T", "112", "32", "ETSI", "5G",
+ "20M", "HT", "1T", "112", "32", "MKK", "5G", "20M", "HT",
+ "1T", "112", "32", "FCC", "5G", "20M", "HT", "1T", "116",
+ "32", "ETSI", "5G", "20M", "HT", "1T", "116", "32", "MKK",
+ "5G", "20M", "HT", "1T", "116", "32", "FCC", "5G", "20M",
+ "HT", "1T", "120", "32", "ETSI", "5G", "20M", "HT", "1T",
+ "120", "32", "MKK", "5G", "20M", "HT", "1T", "120", "32",
+ "FCC", "5G", "20M", "HT", "1T", "124", "32", "ETSI", "5G",
+ "20M", "HT", "1T", "124", "32", "MKK", "5G", "20M", "HT",
+ "1T", "124", "32", "FCC", "5G", "20M", "HT", "1T", "128",
+ "32", "ETSI", "5G", "20M", "HT", "1T", "128", "32", "MKK",
+ "5G", "20M", "HT", "1T", "128", "32", "FCC", "5G", "20M",
+ "HT", "1T", "132", "32", "ETSI", "5G", "20M", "HT", "1T",
+ "132", "32", "MKK", "5G", "20M", "HT", "1T", "132", "32",
+ "FCC", "5G", "20M", "HT", "1T", "136", "32", "ETSI", "5G",
+ "20M", "HT", "1T", "136", "32", "MKK", "5G", "20M", "HT",
+ "1T", "136", "32", "FCC", "5G", "20M", "HT", "1T", "140",
+ "26", "ETSI", "5G", "20M", "HT", "1T", "140", "32", "MKK",
+ "5G", "20M", "HT", "1T", "140", "32", "FCC", "5G", "20M",
+ "HT", "1T", "144", "26", "ETSI", "5G", "20M", "HT", "1T",
+ "144", "63", "MKK", "5G", "20M", "HT", "1T", "144", "63",
+ "FCC", "5G", "20M", "HT", "1T", "149", "32", "ETSI", "5G",
+ "20M", "HT", "1T", "149", "63", "MKK", "5G", "20M", "HT",
+ "1T", "149", "63", "FCC", "5G", "20M", "HT", "1T", "153",
+ "32", "ETSI", "5G", "20M", "HT", "1T", "153", "63", "MKK",
+ "5G", "20M", "HT", "1T", "153", "63", "FCC", "5G", "20M",
+ "HT", "1T", "157", "32", "ETSI", "5G", "20M", "HT", "1T",
+ "157", "63", "MKK", "5G", "20M", "HT", "1T", "157", "63",
+ "FCC", "5G", "20M", "HT", "1T", "161", "32", "ETSI", "5G",
+ "20M", "HT", "1T", "161", "63", "MKK", "5G", "20M", "HT",
+ "1T", "161", "63", "FCC", "5G", "20M", "HT", "1T", "165",
+ "32", "ETSI", "5G", "20M", "HT", "1T", "165", "63", "MKK",
+ "5G", "20M", "HT", "1T", "165", "63", "FCC", "5G", "20M",
+ "HT", "2T", "36", "28", "ETSI", "5G", "20M", "HT", "2T",
+ "36", "20", "MKK", "5G", "20M", "HT", "2T", "36", "22",
+ "FCC", "5G", "20M", "HT", "2T", "40", "30", "ETSI", "5G",
+ "20M", "HT", "2T", "40", "20", "MKK", "5G", "20M", "HT",
+ "2T", "40", "22", "FCC", "5G", "20M", "HT", "2T", "44",
+ "30", "ETSI", "5G", "20M", "HT", "2T", "44", "20", "MKK",
+ "5G", "20M", "HT", "2T", "44", "22", "FCC", "5G", "20M",
+ "HT", "2T", "48", "30", "ETSI", "5G", "20M", "HT", "2T",
+ "48", "20", "MKK", "5G", "20M", "HT", "2T", "48", "22",
+ "FCC", "5G", "20M", "HT", "2T", "52", "30", "ETSI", "5G",
+ "20M", "HT", "2T", "52", "20", "MKK", "5G", "20M", "HT",
+ "2T", "52", "22", "FCC", "5G", "20M", "HT", "2T", "56",
+ "30", "ETSI", "5G", "20M", "HT", "2T", "56", "20", "MKK",
+ "5G", "20M", "HT", "2T", "56", "22", "FCC", "5G", "20M",
+ "HT", "2T", "60", "30", "ETSI", "5G", "20M", "HT", "2T",
+ "60", "20", "MKK", "5G", "20M", "HT", "2T", "60", "22",
+ "FCC", "5G", "20M", "HT", "2T", "64", "28", "ETSI", "5G",
+ "20M", "HT", "2T", "64", "20", "MKK", "5G", "20M", "HT",
+ "2T", "64", "22", "FCC", "5G", "20M", "HT", "2T", "100",
+ "26", "ETSI", "5G", "20M", "HT", "2T", "100", "20", "MKK",
+ "5G", "20M", "HT", "2T", "100", "30", "FCC", "5G", "20M",
+ "HT", "2T", "104", "30", "ETSI", "5G", "20M", "HT", "2T",
+ "104", "20", "MKK", "5G", "20M", "HT", "2T", "104", "30",
+ "FCC", "5G", "20M", "HT", "2T", "108", "32", "ETSI", "5G",
+ "20M", "HT", "2T", "108", "20", "MKK", "5G", "20M", "HT",
+ "2T", "108", "30", "FCC", "5G", "20M", "HT", "2T", "112",
+ "32", "ETSI", "5G", "20M", "HT", "2T", "112", "20", "MKK",
+ "5G", "20M", "HT", "2T", "112", "30", "FCC", "5G", "20M",
+ "HT", "2T", "116", "32", "ETSI", "5G", "20M", "HT", "2T",
+ "116", "20", "MKK", "5G", "20M", "HT", "2T", "116", "30",
+ "FCC", "5G", "20M", "HT", "2T", "120", "32", "ETSI", "5G",
+ "20M", "HT", "2T", "120", "20", "MKK", "5G", "20M", "HT",
+ "2T", "120", "30", "FCC", "5G", "20M", "HT", "2T", "124",
+ "32", "ETSI", "5G", "20M", "HT", "2T", "124", "20", "MKK",
+ "5G", "20M", "HT", "2T", "124", "30", "FCC", "5G", "20M",
+ "HT", "2T", "128", "32", "ETSI", "5G", "20M", "HT", "2T",
+ "128", "20", "MKK", "5G", "20M", "HT", "2T", "128", "30",
+ "FCC", "5G", "20M", "HT", "2T", "132", "32", "ETSI", "5G",
+ "20M", "HT", "2T", "132", "20", "MKK", "5G", "20M", "HT",
+ "2T", "132", "30", "FCC", "5G", "20M", "HT", "2T", "136",
+ "30", "ETSI", "5G", "20M", "HT", "2T", "136", "20", "MKK",
+ "5G", "20M", "HT", "2T", "136", "30", "FCC", "5G", "20M",
+ "HT", "2T", "140", "26", "ETSI", "5G", "20M", "HT", "2T",
+ "140", "20", "MKK", "5G", "20M", "HT", "2T", "140", "30",
+ "FCC", "5G", "20M", "HT", "2T", "144", "26", "ETSI", "5G",
+ "20M", "HT", "2T", "144", "63", "MKK", "5G", "20M", "HT",
+ "2T", "144", "63", "FCC", "5G", "20M", "HT", "2T", "149",
+ "32", "ETSI", "5G", "20M", "HT", "2T", "149", "63", "MKK",
+ "5G", "20M", "HT", "2T", "149", "63", "FCC", "5G", "20M",
+ "HT", "2T", "153", "32", "ETSI", "5G", "20M", "HT", "2T",
+ "153", "63", "MKK", "5G", "20M", "HT", "2T", "153", "63",
+ "FCC", "5G", "20M", "HT", "2T", "157", "32", "ETSI", "5G",
+ "20M", "HT", "2T", "157", "63", "MKK", "5G", "20M", "HT",
+ "2T", "157", "63", "FCC", "5G", "20M", "HT", "2T", "161",
+ "32", "ETSI", "5G", "20M", "HT", "2T", "161", "63", "MKK",
+ "5G", "20M", "HT", "2T", "161", "63", "FCC", "5G", "20M",
+ "HT", "2T", "165", "32", "ETSI", "5G", "20M", "HT", "2T",
+ "165", "63", "MKK", "5G", "20M", "HT", "2T", "165", "63",
+ "FCC", "5G", "40M", "HT", "1T", "38", "22", "ETSI", "5G",
+ "40M", "HT", "1T", "38", "30", "MKK", "5G", "40M", "HT",
+ "1T", "38", "30", "FCC", "5G", "40M", "HT", "1T", "46",
+ "30", "ETSI", "5G", "40M", "HT", "1T", "46", "30", "MKK",
+ "5G", "40M", "HT", "1T", "46", "30", "FCC", "5G", "40M",
+ "HT", "1T", "54", "30", "ETSI", "5G", "40M", "HT", "1T",
+ "54", "30", "MKK", "5G", "40M", "HT", "1T", "54", "30",
+ "FCC", "5G", "40M", "HT", "1T", "62", "24", "ETSI", "5G",
+ "40M", "HT", "1T", "62", "30", "MKK", "5G", "40M", "HT",
+ "1T", "62", "30", "FCC", "5G", "40M", "HT", "1T", "102",
+ "24", "ETSI", "5G", "40M", "HT", "1T", "102", "30", "MKK",
+ "5G", "40M", "HT", "1T", "102", "30", "FCC", "5G", "40M",
+ "HT", "1T", "110", "30", "ETSI", "5G", "40M", "HT", "1T",
+ "110", "30", "MKK", "5G", "40M", "HT", "1T", "110", "30",
+ "FCC", "5G", "40M", "HT", "1T", "118", "30", "ETSI", "5G",
+ "40M", "HT", "1T", "118", "30", "MKK", "5G", "40M", "HT",
+ "1T", "118", "30", "FCC", "5G", "40M", "HT", "1T", "126",
+ "30", "ETSI", "5G", "40M", "HT", "1T", "126", "30", "MKK",
+ "5G", "40M", "HT", "1T", "126", "30", "FCC", "5G", "40M",
+ "HT", "1T", "134", "30", "ETSI", "5G", "40M", "HT", "1T",
+ "134", "30", "MKK", "5G", "40M", "HT", "1T", "134", "30",
+ "FCC", "5G", "40M", "HT", "1T", "142", "30", "ETSI", "5G",
+ "40M", "HT", "1T", "142", "63", "MKK", "5G", "40M", "HT",
+ "1T", "142", "63", "FCC", "5G", "40M", "HT", "1T", "151",
+ "30", "ETSI", "5G", "40M", "HT", "1T", "151", "63", "MKK",
+ "5G", "40M", "HT", "1T", "151", "63", "FCC", "5G", "40M",
+ "HT", "1T", "159", "30", "ETSI", "5G", "40M", "HT", "1T",
+ "159", "63", "MKK", "5G", "40M", "HT", "1T", "159", "63",
+ "FCC", "5G", "40M", "HT", "2T", "38", "20", "ETSI", "5G",
+ "40M", "HT", "2T", "38", "20", "MKK", "5G", "40M", "HT",
+ "2T", "38", "22", "FCC", "5G", "40M", "HT", "2T", "46",
+ "30", "ETSI", "5G", "40M", "HT", "2T", "46", "20", "MKK",
+ "5G", "40M", "HT", "2T", "46", "22", "FCC", "5G", "40M",
+ "HT", "2T", "54", "30", "ETSI", "5G", "40M", "HT", "2T",
+ "54", "20", "MKK", "5G", "40M", "HT", "2T", "54", "22",
+ "FCC", "5G", "40M", "HT", "2T", "62", "22", "ETSI", "5G",
+ "40M", "HT", "2T", "62", "20", "MKK", "5G", "40M", "HT",
+ "2T", "62", "22", "FCC", "5G", "40M", "HT", "2T", "102",
+ "22", "ETSI", "5G", "40M", "HT", "2T", "102", "20", "MKK",
+ "5G", "40M", "HT", "2T", "102", "30", "FCC", "5G", "40M",
+ "HT", "2T", "110", "30", "ETSI", "5G", "40M", "HT", "2T",
+ "110", "20", "MKK", "5G", "40M", "HT", "2T", "110", "30",
+ "FCC", "5G", "40M", "HT", "2T", "118", "30", "ETSI", "5G",
+ "40M", "HT", "2T", "118", "20", "MKK", "5G", "40M", "HT",
+ "2T", "118", "30", "FCC", "5G", "40M", "HT", "2T", "126",
+ "30", "ETSI", "5G", "40M", "HT", "2T", "126", "20", "MKK",
+ "5G", "40M", "HT", "2T", "126", "30", "FCC", "5G", "40M",
+ "HT", "2T", "134", "30", "ETSI", "5G", "40M", "HT", "2T",
+ "134", "20", "MKK", "5G", "40M", "HT", "2T", "134", "30",
+ "FCC", "5G", "40M", "HT", "2T", "142", "30", "ETSI", "5G",
+ "40M", "HT", "2T", "142", "63", "MKK", "5G", "40M", "HT",
+ "2T", "142", "63", "FCC", "5G", "40M", "HT", "2T", "151",
+ "30", "ETSI", "5G", "40M", "HT", "2T", "151", "63", "MKK",
+ "5G", "40M", "HT", "2T", "151", "63", "FCC", "5G", "40M",
+ "HT", "2T", "159", "30", "ETSI", "5G", "40M", "HT", "2T",
+ "159", "63", "MKK", "5G", "40M", "HT", "2T", "159", "63",
+ "FCC", "5G", "80M", "VHT", "1T", "42", "20", "ETSI", "5G",
+ "80M", "VHT", "1T", "42", "30", "MKK", "5G", "80M", "VHT",
+ "1T", "42", "28", "FCC", "5G", "80M", "VHT", "1T", "58",
+ "20", "ETSI", "5G", "80M", "VHT", "1T", "58", "30", "MKK",
+ "5G", "80M", "VHT", "1T", "58", "28", "FCC", "5G", "80M",
+ "VHT", "1T", "106", "20", "ETSI", "5G", "80M", "VHT", "1T",
+ "106", "30", "MKK", "5G", "80M", "VHT", "1T", "106", "30",
+ "FCC", "5G", "80M", "VHT", "1T", "122", "30", "ETSI", "5G",
+ "80M", "VHT", "1T", "122", "30", "MKK", "5G", "80M", "VHT",
+ "1T", "122", "30", "FCC", "5G", "80M", "VHT", "1T", "138",
+ "30", "ETSI", "5G", "80M", "VHT", "1T", "138", "63", "MKK",
+ "5G", "80M", "VHT", "1T", "138", "63", "FCC", "5G", "80M",
+ "VHT", "1T", "155", "30", "ETSI", "5G", "80M", "VHT", "1T",
+ "155", "63", "MKK", "5G", "80M", "VHT", "1T", "155", "63",
+ "FCC", "5G", "80M", "VHT", "2T", "42", "18", "ETSI", "5G",
+ "80M", "VHT", "2T", "42", "20", "MKK", "5G", "80M", "VHT",
+ "2T", "42", "22", "FCC", "5G", "80M", "VHT", "2T", "58",
+ "18", "ETSI", "5G", "80M", "VHT", "2T", "58", "20", "MKK",
+ "5G", "80M", "VHT", "2T", "58", "22", "FCC", "5G", "80M",
+ "VHT", "2T", "106", "20", "ETSI", "5G", "80M", "VHT", "2T",
+ "106", "20", "MKK", "5G", "80M", "VHT", "2T", "106", "30",
+ "FCC", "5G", "80M", "VHT", "2T", "122", "30", "ETSI", "5G",
+ "80M", "VHT", "2T", "122", "20", "MKK", "5G", "80M", "VHT",
+ "2T", "122", "30", "FCC", "5G", "80M", "VHT", "2T", "138",
+ "30", "ETSI", "5G", "80M", "VHT", "2T", "138", "63", "MKK",
+ "5G", "80M", "VHT", "2T", "138", "63", "FCC", "5G", "80M",
+ "VHT", "2T", "155", "30", "ETSI", "5G", "80M", "VHT", "2T",
+ "155", "63", "MKK", "5G", "80M", "VHT", "2T", "155", "63"};
+
+void odm_read_and_config_mp_8822b_txpwr_lmt(struct phy_dm_struct *dm)
+{
+ u32 i = 0;
+ u32 array_len = sizeof(array_mp_8822b_txpwr_lmt) / sizeof(u8 *);
+ u8 **array = (u8 **)array_mp_8822b_txpwr_lmt;
+
+ ODM_RT_TRACE(dm, ODM_COMP_INIT,
+ "===> %s\n", __func__);
+
+ for (i = 0; i < array_len; i += 7) {
+ u8 *regulation = array[i];
+ u8 *band = array[i + 1];
+ u8 *bandwidth = array[i + 2];
+ u8 *rate = array[i + 3];
+ u8 *rf_path = array[i + 4];
+ u8 *chnl = array[i + 5];
+ u8 *val = array[i + 6];
+
+ odm_config_bb_txpwr_lmt_8822b(dm, regulation, band, bandwidth,
+ rate, rf_path, chnl, val);
+ }
+}
+
+/******************************************************************************
+* txpwr_lmt_type5.TXT
+******************************************************************************/
+
+static const char *const array_mp_8822b_txpwr_lmt_type5[] = {
+ "FCC", "2.4G", "20M", "CCK", "1T", "01", "32", "ETSI", "2.4G",
+ "20M", "CCK", "1T", "01", "28", "MKK", "2.4G", "20M", "CCK",
+ "1T", "01", "30", "FCC", "2.4G", "20M", "CCK", "1T", "02",
+ "32", "ETSI", "2.4G", "20M", "CCK", "1T", "02", "28", "MKK",
+ "2.4G", "20M", "CCK", "1T", "02", "30", "FCC", "2.4G", "20M",
+ "CCK", "1T", "03", "32", "ETSI", "2.4G", "20M", "CCK", "1T",
+ "03", "28", "MKK", "2.4G", "20M", "CCK", "1T", "03", "30",
+ "FCC", "2.4G", "20M", "CCK", "1T", "04", "32", "ETSI", "2.4G",
+ "20M", "CCK", "1T", "04", "28", "MKK", "2.4G", "20M", "CCK",
+ "1T", "04", "30", "FCC", "2.4G", "20M", "CCK", "1T", "05",
+ "32", "ETSI", "2.4G", "20M", "CCK", "1T", "05", "28", "MKK",
+ "2.4G", "20M", "CCK", "1T", "05", "30", "FCC", "2.4G", "20M",
+ "CCK", "1T", "06", "32", "ETSI", "2.4G", "20M", "CCK", "1T",
+ "06", "28", "MKK", "2.4G", "20M", "CCK", "1T", "06", "30",
+ "FCC", "2.4G", "20M", "CCK", "1T", "07", "32", "ETSI", "2.4G",
+ "20M", "CCK", "1T", "07", "28", "MKK", "2.4G", "20M", "CCK",
+ "1T", "07", "30", "FCC", "2.4G", "20M", "CCK", "1T", "08",
+ "32", "ETSI", "2.4G", "20M", "CCK", "1T", "08", "28", "MKK",
+ "2.4G", "20M", "CCK", "1T", "08", "30", "FCC", "2.4G", "20M",
+ "CCK", "1T", "09", "32", "ETSI", "2.4G", "20M", "CCK", "1T",
+ "09", "28", "MKK", "2.4G", "20M", "CCK", "1T", "09", "30",
+ "FCC", "2.4G", "20M", "CCK", "1T", "10", "32", "ETSI", "2.4G",
+ "20M", "CCK", "1T", "10", "28", "MKK", "2.4G", "20M", "CCK",
+ "1T", "10", "30", "FCC", "2.4G", "20M", "CCK", "1T", "11",
+ "32", "ETSI", "2.4G", "20M", "CCK", "1T", "11", "28", "MKK",
+ "2.4G", "20M", "CCK", "1T", "11", "30", "FCC", "2.4G", "20M",
+ "CCK", "1T", "12", "26", "ETSI", "2.4G", "20M", "CCK", "1T",
+ "12", "28", "MKK", "2.4G", "20M", "CCK", "1T", "12", "30",
+ "FCC", "2.4G", "20M", "CCK", "1T", "13", "20", "ETSI", "2.4G",
+ "20M", "CCK", "1T", "13", "28", "MKK", "2.4G", "20M", "CCK",
+ "1T", "13", "28", "FCC", "2.4G", "20M", "CCK", "1T", "14",
+ "63", "ETSI", "2.4G", "20M", "CCK", "1T", "14", "63", "MKK",
+ "2.4G", "20M", "CCK", "1T", "14", "32", "FCC", "2.4G", "20M",
+ "OFDM", "1T", "01", "26", "ETSI", "2.4G", "20M", "OFDM", "1T",
+ "01", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "01", "34",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "02", "30", "ETSI", "2.4G",
+ "20M", "OFDM", "1T", "02", "30", "MKK", "2.4G", "20M", "OFDM",
+ "1T", "02", "34", "FCC", "2.4G", "20M", "OFDM", "1T", "03",
+ "32", "ETSI", "2.4G", "20M", "OFDM", "1T", "03", "30", "MKK",
+ "2.4G", "20M", "OFDM", "1T", "03", "34", "FCC", "2.4G", "20M",
+ "OFDM", "1T", "04", "34", "ETSI", "2.4G", "20M", "OFDM", "1T",
+ "04", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "04", "34",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "05", "34", "ETSI", "2.4G",
+ "20M", "OFDM", "1T", "05", "30", "MKK", "2.4G", "20M", "OFDM",
+ "1T", "05", "34", "FCC", "2.4G", "20M", "OFDM", "1T", "06",
+ "34", "ETSI", "2.4G", "20M", "OFDM", "1T", "06", "30", "MKK",
+ "2.4G", "20M", "OFDM", "1T", "06", "34", "FCC", "2.4G", "20M",
+ "OFDM", "1T", "07", "34", "ETSI", "2.4G", "20M", "OFDM", "1T",
+ "07", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "07", "34",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "08", "34", "ETSI", "2.4G",
+ "20M", "OFDM", "1T", "08", "30", "MKK", "2.4G", "20M", "OFDM",
+ "1T", "08", "34", "FCC", "2.4G", "20M", "OFDM", "1T", "09",
+ "32", "ETSI", "2.4G", "20M", "OFDM", "1T", "09", "30", "MKK",
+ "2.4G", "20M", "OFDM", "1T", "09", "34", "FCC", "2.4G", "20M",
+ "OFDM", "1T", "10", "30", "ETSI", "2.4G", "20M", "OFDM", "1T",
+ "10", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "10", "34",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "11", "28", "ETSI", "2.4G",
+ "20M", "OFDM", "1T", "11", "30", "MKK", "2.4G", "20M", "OFDM",
+ "1T", "11", "34", "FCC", "2.4G", "20M", "OFDM", "1T", "12",
+ "22", "ETSI", "2.4G", "20M", "OFDM", "1T", "12", "30", "MKK",
+ "2.4G", "20M", "OFDM", "1T", "12", "34", "FCC", "2.4G", "20M",
+ "OFDM", "1T", "13", "14", "ETSI", "2.4G", "20M", "OFDM", "1T",
+ "13", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "13", "34",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "14", "63", "ETSI", "2.4G",
+ "20M", "OFDM", "1T", "14", "63", "MKK", "2.4G", "20M", "OFDM",
+ "1T", "14", "63", "FCC", "2.4G", "20M", "HT", "1T", "01",
+ "26", "ETSI", "2.4G", "20M", "HT", "1T", "01", "30", "MKK",
+ "2.4G", "20M", "HT", "1T", "01", "34", "FCC", "2.4G", "20M",
+ "HT", "1T", "02", "30", "ETSI", "2.4G", "20M", "HT", "1T",
+ "02", "30", "MKK", "2.4G", "20M", "HT", "1T", "02", "34",
+ "FCC", "2.4G", "20M", "HT", "1T", "03", "32", "ETSI", "2.4G",
+ "20M", "HT", "1T", "03", "30", "MKK", "2.4G", "20M", "HT",
+ "1T", "03", "34", "FCC", "2.4G", "20M", "HT", "1T", "04",
+ "34", "ETSI", "2.4G", "20M", "HT", "1T", "04", "30", "MKK",
+ "2.4G", "20M", "HT", "1T", "04", "34", "FCC", "2.4G", "20M",
+ "HT", "1T", "05", "34", "ETSI", "2.4G", "20M", "HT", "1T",
+ "05", "30", "MKK", "2.4G", "20M", "HT", "1T", "05", "34",
+ "FCC", "2.4G", "20M", "HT", "1T", "06", "34", "ETSI", "2.4G",
+ "20M", "HT", "1T", "06", "30", "MKK", "2.4G", "20M", "HT",
+ "1T", "06", "34", "FCC", "2.4G", "20M", "HT", "1T", "07",
+ "34", "ETSI", "2.4G", "20M", "HT", "1T", "07", "30", "MKK",
+ "2.4G", "20M", "HT", "1T", "07", "34", "FCC", "2.4G", "20M",
+ "HT", "1T", "08", "34", "ETSI", "2.4G", "20M", "HT", "1T",
+ "08", "30", "MKK", "2.4G", "20M", "HT", "1T", "08", "34",
+ "FCC", "2.4G", "20M", "HT", "1T", "09", "32", "ETSI", "2.4G",
+ "20M", "HT", "1T", "09", "30", "MKK", "2.4G", "20M", "HT",
+ "1T", "09", "34", "FCC", "2.4G", "20M", "HT", "1T", "10",
+ "30", "ETSI", "2.4G", "20M", "HT", "1T", "10", "30", "MKK",
+ "2.4G", "20M", "HT", "1T", "10", "34", "FCC", "2.4G", "20M",
+ "HT", "1T", "11", "26", "ETSI", "2.4G", "20M", "HT", "1T",
+ "11", "30", "MKK", "2.4G", "20M", "HT", "1T", "11", "34",
+ "FCC", "2.4G", "20M", "HT", "1T", "12", "20", "ETSI", "2.4G",
+ "20M", "HT", "1T", "12", "30", "MKK", "2.4G", "20M", "HT",
+ "1T", "12", "34", "FCC", "2.4G", "20M", "HT", "1T", "13",
+ "14", "ETSI", "2.4G", "20M", "HT", "1T", "13", "30", "MKK",
+ "2.4G", "20M", "HT", "1T", "13", "34", "FCC", "2.4G", "20M",
+ "HT", "1T", "14", "63", "ETSI", "2.4G", "20M", "HT", "1T",
+ "14", "63", "MKK", "2.4G", "20M", "HT", "1T", "14", "63",
+ "FCC", "2.4G", "20M", "HT", "2T", "01", "26", "ETSI", "2.4G",
+ "20M", "HT", "2T", "01", "18", "MKK", "2.4G", "20M", "HT",
+ "2T", "01", "30", "FCC", "2.4G", "20M", "HT", "2T", "02",
+ "28", "ETSI", "2.4G", "20M", "HT", "2T", "02", "18", "MKK",
+ "2.4G", "20M", "HT", "2T", "02", "30", "FCC", "2.4G", "20M",
+ "HT", "2T", "03", "30", "ETSI", "2.4G", "20M", "HT", "2T",
+ "03", "18", "MKK", "2.4G", "20M", "HT", "2T", "03", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "04", "30", "ETSI", "2.4G",
+ "20M", "HT", "2T", "04", "18", "MKK", "2.4G", "20M", "HT",
+ "2T", "04", "30", "FCC", "2.4G", "20M", "HT", "2T", "05",
+ "32", "ETSI", "2.4G", "20M", "HT", "2T", "05", "18", "MKK",
+ "2.4G", "20M", "HT", "2T", "05", "30", "FCC", "2.4G", "20M",
+ "HT", "2T", "06", "32", "ETSI", "2.4G", "20M", "HT", "2T",
+ "06", "18", "MKK", "2.4G", "20M", "HT", "2T", "06", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "07", "32", "ETSI", "2.4G",
+ "20M", "HT", "2T", "07", "18", "MKK", "2.4G", "20M", "HT",
+ "2T", "07", "30", "FCC", "2.4G", "20M", "HT", "2T", "08",
+ "30", "ETSI", "2.4G", "20M", "HT", "2T", "08", "18", "MKK",
+ "2.4G", "20M", "HT", "2T", "08", "30", "FCC", "2.4G", "20M",
+ "HT", "2T", "09", "30", "ETSI", "2.4G", "20M", "HT", "2T",
+ "09", "18", "MKK", "2.4G", "20M", "HT", "2T", "09", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "10", "28", "ETSI", "2.4G",
+ "20M", "HT", "2T", "10", "18", "MKK", "2.4G", "20M", "HT",
+ "2T", "10", "30", "FCC", "2.4G", "20M", "HT", "2T", "11",
+ "26", "ETSI", "2.4G", "20M", "HT", "2T", "11", "18", "MKK",
+ "2.4G", "20M", "HT", "2T", "11", "30", "FCC", "2.4G", "20M",
+ "HT", "2T", "12", "20", "ETSI", "2.4G", "20M", "HT", "2T",
+ "12", "18", "MKK", "2.4G", "20M", "HT", "2T", "12", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "13", "14", "ETSI", "2.4G",
+ "20M", "HT", "2T", "13", "18", "MKK", "2.4G", "20M", "HT",
+ "2T", "13", "30", "FCC", "2.4G", "20M", "HT", "2T", "14",
+ "63", "ETSI", "2.4G", "20M", "HT", "2T", "14", "63", "MKK",
+ "2.4G", "20M", "HT", "2T", "14", "63", "FCC", "2.4G", "40M",
+ "HT", "1T", "01", "63", "ETSI", "2.4G", "40M", "HT", "1T",
+ "01", "63", "MKK", "2.4G", "40M", "HT", "1T", "01", "63",
+ "FCC", "2.4G", "40M", "HT", "1T", "02", "63", "ETSI", "2.4G",
+ "40M", "HT", "1T", "02", "63", "MKK", "2.4G", "40M", "HT",
+ "1T", "02", "63", "FCC", "2.4G", "40M", "HT", "1T", "03",
+ "26", "ETSI", "2.4G", "40M", "HT", "1T", "03", "30", "MKK",
+ "2.4G", "40M", "HT", "1T", "03", "34", "FCC", "2.4G", "40M",
+ "HT", "1T", "04", "26", "ETSI", "2.4G", "40M", "HT", "1T",
+ "04", "30", "MKK", "2.4G", "40M", "HT", "1T", "04", "34",
+ "FCC", "2.4G", "40M", "HT", "1T", "05", "30", "ETSI", "2.4G",
+ "40M", "HT", "1T", "05", "30", "MKK", "2.4G", "40M", "HT",
+ "1T", "05", "34", "FCC", "2.4G", "40M", "HT", "1T", "06",
+ "32", "ETSI", "2.4G", "40M", "HT", "1T", "06", "30", "MKK",
+ "2.4G", "40M", "HT", "1T", "06", "34", "FCC", "2.4G", "40M",
+ "HT", "1T", "07", "30", "ETSI", "2.4G", "40M", "HT", "1T",
+ "07", "30", "MKK", "2.4G", "40M", "HT", "1T", "07", "34",
+ "FCC", "2.4G", "40M", "HT", "1T", "08", "26", "ETSI", "2.4G",
+ "40M", "HT", "1T", "08", "30", "MKK", "2.4G", "40M", "HT",
+ "1T", "08", "34", "FCC", "2.4G", "40M", "HT", "1T", "09",
+ "26", "ETSI", "2.4G", "40M", "HT", "1T", "09", "30", "MKK",
+ "2.4G", "40M", "HT", "1T", "09", "34", "FCC", "2.4G", "40M",
+ "HT", "1T", "10", "20", "ETSI", "2.4G", "40M", "HT", "1T",
+ "10", "30", "MKK", "2.4G", "40M", "HT", "1T", "10", "34",
+ "FCC", "2.4G", "40M", "HT", "1T", "11", "14", "ETSI", "2.4G",
+ "40M", "HT", "1T", "11", "30", "MKK", "2.4G", "40M", "HT",
+ "1T", "11", "34", "FCC", "2.4G", "40M", "HT", "1T", "12",
+ "63", "ETSI", "2.4G", "40M", "HT", "1T", "12", "63", "MKK",
+ "2.4G", "40M", "HT", "1T", "12", "63", "FCC", "2.4G", "40M",
+ "HT", "1T", "13", "63", "ETSI", "2.4G", "40M", "HT", "1T",
+ "13", "63", "MKK", "2.4G", "40M", "HT", "1T", "13", "63",
+ "FCC", "2.4G", "40M", "HT", "1T", "14", "63", "ETSI", "2.4G",
+ "40M", "HT", "1T", "14", "63", "MKK", "2.4G", "40M", "HT",
+ "1T", "14", "63", "FCC", "2.4G", "40M", "HT", "2T", "01",
+ "63", "ETSI", "2.4G", "40M", "HT", "2T", "01", "63", "MKK",
+ "2.4G", "40M", "HT", "2T", "01", "63", "FCC", "2.4G", "40M",
+ "HT", "2T", "02", "63", "ETSI", "2.4G", "40M", "HT", "2T",
+ "02", "63", "MKK", "2.4G", "40M", "HT", "2T", "02", "63",
+ "FCC", "2.4G", "40M", "HT", "2T", "03", "24", "ETSI", "2.4G",
+ "40M", "HT", "2T", "03", "18", "MKK", "2.4G", "40M", "HT",
+ "2T", "03", "30", "FCC", "2.4G", "40M", "HT", "2T", "04",
+ "24", "ETSI", "2.4G", "40M", "HT", "2T", "04", "18", "MKK",
+ "2.4G", "40M", "HT", "2T", "04", "30", "FCC", "2.4G", "40M",
+ "HT", "2T", "05", "26", "ETSI", "2.4G", "40M", "HT", "2T",
+ "05", "18", "MKK", "2.4G", "40M", "HT", "2T", "05", "30",
+ "FCC", "2.4G", "40M", "HT", "2T", "06", "28", "ETSI", "2.4G",
+ "40M", "HT", "2T", "06", "18", "MKK", "2.4G", "40M", "HT",
+ "2T", "06", "30", "FCC", "2.4G", "40M", "HT", "2T", "07",
+ "26", "ETSI", "2.4G", "40M", "HT", "2T", "07", "18", "MKK",
+ "2.4G", "40M", "HT", "2T", "07", "30", "FCC", "2.4G", "40M",
+ "HT", "2T", "08", "26", "ETSI", "2.4G", "40M", "HT", "2T",
+ "08", "18", "MKK", "2.4G", "40M", "HT", "2T", "08", "30",
+ "FCC", "2.4G", "40M", "HT", "2T", "09", "26", "ETSI", "2.4G",
+ "40M", "HT", "2T", "09", "18", "MKK", "2.4G", "40M", "HT",
+ "2T", "09", "30", "FCC", "2.4G", "40M", "HT", "2T", "10",
+ "20", "ETSI", "2.4G", "40M", "HT", "2T", "10", "18", "MKK",
+ "2.4G", "40M", "HT", "2T", "10", "30", "FCC", "2.4G", "40M",
+ "HT", "2T", "11", "14", "ETSI", "2.4G", "40M", "HT", "2T",
+ "11", "18", "MKK", "2.4G", "40M", "HT", "2T", "11", "30",
+ "FCC", "2.4G", "40M", "HT", "2T", "12", "63", "ETSI", "2.4G",
+ "40M", "HT", "2T", "12", "63", "MKK", "2.4G", "40M", "HT",
+ "2T", "12", "63", "FCC", "2.4G", "40M", "HT", "2T", "13",
+ "63", "ETSI", "2.4G", "40M", "HT", "2T", "13", "63", "MKK",
+ "2.4G", "40M", "HT", "2T", "13", "63", "FCC", "2.4G", "40M",
+ "HT", "2T", "14", "63", "ETSI", "2.4G", "40M", "HT", "2T",
+ "14", "63", "MKK", "2.4G", "40M", "HT", "2T", "14", "63",
+ "FCC", "5G", "20M", "OFDM", "1T", "36", "30", "ETSI", "5G",
+ "20M", "OFDM", "1T", "36", "32", "MKK", "5G", "20M", "OFDM",
+ "1T", "36", "30", "FCC", "5G", "20M", "OFDM", "1T", "40",
+ "32", "ETSI", "5G", "20M", "OFDM", "1T", "40", "32", "MKK",
+ "5G", "20M", "OFDM", "1T", "40", "30", "FCC", "5G", "20M",
+ "OFDM", "1T", "44", "32", "ETSI", "5G", "20M", "OFDM", "1T",
+ "44", "32", "MKK", "5G", "20M", "OFDM", "1T", "44", "30",
+ "FCC", "5G", "20M", "OFDM", "1T", "48", "32", "ETSI", "5G",
+ "20M", "OFDM", "1T", "48", "32", "MKK", "5G", "20M", "OFDM",
+ "1T", "48", "30", "FCC", "5G", "20M", "OFDM", "1T", "52",
+ "32", "ETSI", "5G", "20M", "OFDM", "1T", "52", "32", "MKK",
+ "5G", "20M", "OFDM", "1T", "52", "28", "FCC", "5G", "20M",
+ "OFDM", "1T", "56", "32", "ETSI", "5G", "20M", "OFDM", "1T",
+ "56", "32", "MKK", "5G", "20M", "OFDM", "1T", "56", "28",
+ "FCC", "5G", "20M", "OFDM", "1T", "60", "32", "ETSI", "5G",
+ "20M", "OFDM", "1T", "60", "32", "MKK", "5G", "20M", "OFDM",
+ "1T", "60", "28", "FCC", "5G", "20M", "OFDM", "1T", "64",
+ "28", "ETSI", "5G", "20M", "OFDM", "1T", "64", "32", "MKK",
+ "5G", "20M", "OFDM", "1T", "64", "28", "FCC", "5G", "20M",
+ "OFDM", "1T", "100", "26", "ETSI", "5G", "20M", "OFDM", "1T",
+ "100", "32", "MKK", "5G", "20M", "OFDM", "1T", "100", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "104", "32", "ETSI", "5G",
+ "20M", "OFDM", "1T", "104", "32", "MKK", "5G", "20M", "OFDM",
+ "1T", "104", "32", "FCC", "5G", "20M", "OFDM", "1T", "108",
+ "32", "ETSI", "5G", "20M", "OFDM", "1T", "108", "32", "MKK",
+ "5G", "20M", "OFDM", "1T", "108", "32", "FCC", "5G", "20M",
+ "OFDM", "1T", "112", "32", "ETSI", "5G", "20M", "OFDM", "1T",
+ "112", "32", "MKK", "5G", "20M", "OFDM", "1T", "112", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "116", "32", "ETSI", "5G",
+ "20M", "OFDM", "1T", "116", "32", "MKK", "5G", "20M", "OFDM",
+ "1T", "116", "32", "FCC", "5G", "20M", "OFDM", "1T", "120",
+ "32", "ETSI", "5G", "20M", "OFDM", "1T", "120", "32", "MKK",
+ "5G", "20M", "OFDM", "1T", "120", "32", "FCC", "5G", "20M",
+ "OFDM", "1T", "124", "32", "ETSI", "5G", "20M", "OFDM", "1T",
+ "124", "32", "MKK", "5G", "20M", "OFDM", "1T", "124", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "128", "32", "ETSI", "5G",
+ "20M", "OFDM", "1T", "128", "32", "MKK", "5G", "20M", "OFDM",
+ "1T", "128", "32", "FCC", "5G", "20M", "OFDM", "1T", "132",
+ "32", "ETSI", "5G", "20M", "OFDM", "1T", "132", "32", "MKK",
+ "5G", "20M", "OFDM", "1T", "132", "32", "FCC", "5G", "20M",
+ "OFDM", "1T", "136", "32", "ETSI", "5G", "20M", "OFDM", "1T",
+ "136", "32", "MKK", "5G", "20M", "OFDM", "1T", "136", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "140", "28", "ETSI", "5G",
+ "20M", "OFDM", "1T", "140", "32", "MKK", "5G", "20M", "OFDM",
+ "1T", "140", "32", "FCC", "5G", "20M", "OFDM", "1T", "144",
+ "28", "ETSI", "5G", "20M", "OFDM", "1T", "144", "32", "MKK",
+ "5G", "20M", "OFDM", "1T", "144", "63", "FCC", "5G", "20M",
+ "OFDM", "1T", "149", "32", "ETSI", "5G", "20M", "OFDM", "1T",
+ "149", "63", "MKK", "5G", "20M", "OFDM", "1T", "149", "63",
+ "FCC", "5G", "20M", "OFDM", "1T", "153", "32", "ETSI", "5G",
+ "20M", "OFDM", "1T", "153", "63", "MKK", "5G", "20M", "OFDM",
+ "1T", "153", "63", "FCC", "5G", "20M", "OFDM", "1T", "157",
+ "32", "ETSI", "5G", "20M", "OFDM", "1T", "157", "63", "MKK",
+ "5G", "20M", "OFDM", "1T", "157", "63", "FCC", "5G", "20M",
+ "OFDM", "1T", "161", "32", "ETSI", "5G", "20M", "OFDM", "1T",
+ "161", "63", "MKK", "5G", "20M", "OFDM", "1T", "161", "63",
+ "FCC", "5G", "20M", "OFDM", "1T", "165", "32", "ETSI", "5G",
+ "20M", "OFDM", "1T", "165", "63", "MKK", "5G", "20M", "OFDM",
+ "1T", "165", "63", "FCC", "5G", "20M", "HT", "1T", "36",
+ "30", "ETSI", "5G", "20M", "HT", "1T", "36", "32", "MKK",
+ "5G", "20M", "HT", "1T", "36", "28", "FCC", "5G", "20M",
+ "HT", "1T", "40", "32", "ETSI", "5G", "20M", "HT", "1T",
+ "40", "32", "MKK", "5G", "20M", "HT", "1T", "40", "28",
+ "FCC", "5G", "20M", "HT", "1T", "44", "32", "ETSI", "5G",
+ "20M", "HT", "1T", "44", "32", "MKK", "5G", "20M", "HT",
+ "1T", "44", "28", "FCC", "5G", "20M", "HT", "1T", "48",
+ "32", "ETSI", "5G", "20M", "HT", "1T", "48", "32", "MKK",
+ "5G", "20M", "HT", "1T", "48", "28", "FCC", "5G", "20M",
+ "HT", "1T", "52", "32", "ETSI", "5G", "20M", "HT", "1T",
+ "52", "32", "MKK", "5G", "20M", "HT", "1T", "52", "28",
+ "FCC", "5G", "20M", "HT", "1T", "56", "32", "ETSI", "5G",
+ "20M", "HT", "1T", "56", "32", "MKK", "5G", "20M", "HT",
+ "1T", "56", "28", "FCC", "5G", "20M", "HT", "1T", "60",
+ "32", "ETSI", "5G", "20M", "HT", "1T", "60", "32", "MKK",
+ "5G", "20M", "HT", "1T", "60", "28", "FCC", "5G", "20M",
+ "HT", "1T", "64", "28", "ETSI", "5G", "20M", "HT", "1T",
+ "64", "32", "MKK", "5G", "20M", "HT", "1T", "64", "28",
+ "FCC", "5G", "20M", "HT", "1T", "100", "26", "ETSI", "5G",
+ "20M", "HT", "1T", "100", "32", "MKK", "5G", "20M", "HT",
+ "1T", "100", "32", "FCC", "5G", "20M", "HT", "1T", "104",
+ "32", "ETSI", "5G", "20M", "HT", "1T", "104", "32", "MKK",
+ "5G", "20M", "HT", "1T", "104", "32", "FCC", "5G", "20M",
+ "HT", "1T", "108", "32", "ETSI", "5G", "20M", "HT", "1T",
+ "108", "32", "MKK", "5G", "20M", "HT", "1T", "108", "32",
+ "FCC", "5G", "20M", "HT", "1T", "112", "32", "ETSI", "5G",
+ "20M", "HT", "1T", "112", "32", "MKK", "5G", "20M", "HT",
+ "1T", "112", "32", "FCC", "5G", "20M", "HT", "1T", "116",
+ "32", "ETSI", "5G", "20M", "HT", "1T", "116", "32", "MKK",
+ "5G", "20M", "HT", "1T", "116", "32", "FCC", "5G", "20M",
+ "HT", "1T", "120", "32", "ETSI", "5G", "20M", "HT", "1T",
+ "120", "32", "MKK", "5G", "20M", "HT", "1T", "120", "32",
+ "FCC", "5G", "20M", "HT", "1T", "124", "32", "ETSI", "5G",
+ "20M", "HT", "1T", "124", "32", "MKK", "5G", "20M", "HT",
+ "1T", "124", "32", "FCC", "5G", "20M", "HT", "1T", "128",
+ "32", "ETSI", "5G", "20M", "HT", "1T", "128", "32", "MKK",
+ "5G", "20M", "HT", "1T", "128", "32", "FCC", "5G", "20M",
+ "HT", "1T", "132", "32", "ETSI", "5G", "20M", "HT", "1T",
+ "132", "32", "MKK", "5G", "20M", "HT", "1T", "132", "32",
+ "FCC", "5G", "20M", "HT", "1T", "136", "32", "ETSI", "5G",
+ "20M", "HT", "1T", "136", "32", "MKK", "5G", "20M", "HT",
+ "1T", "136", "32", "FCC", "5G", "20M", "HT", "1T", "140",
+ "26", "ETSI", "5G", "20M", "HT", "1T", "140", "32", "MKK",
+ "5G", "20M", "HT", "1T", "140", "32", "FCC", "5G", "20M",
+ "HT", "1T", "144", "26", "ETSI", "5G", "20M", "HT", "1T",
+ "144", "63", "MKK", "5G", "20M", "HT", "1T", "144", "63",
+ "FCC", "5G", "20M", "HT", "1T", "149", "32", "ETSI", "5G",
+ "20M", "HT", "1T", "149", "63", "MKK", "5G", "20M", "HT",
+ "1T", "149", "63", "FCC", "5G", "20M", "HT", "1T", "153",
+ "32", "ETSI", "5G", "20M", "HT", "1T", "153", "63", "MKK",
+ "5G", "20M", "HT", "1T", "153", "63", "FCC", "5G", "20M",
+ "HT", "1T", "157", "32", "ETSI", "5G", "20M", "HT", "1T",
+ "157", "63", "MKK", "5G", "20M", "HT", "1T", "157", "63",
+ "FCC", "5G", "20M", "HT", "1T", "161", "32", "ETSI", "5G",
+ "20M", "HT", "1T", "161", "63", "MKK", "5G", "20M", "HT",
+ "1T", "161", "63", "FCC", "5G", "20M", "HT", "1T", "165",
+ "32", "ETSI", "5G", "20M", "HT", "1T", "165", "63", "MKK",
+ "5G", "20M", "HT", "1T", "165", "63", "FCC", "5G", "20M",
+ "HT", "2T", "36", "28", "ETSI", "5G", "20M", "HT", "2T",
+ "36", "20", "MKK", "5G", "20M", "HT", "2T", "36", "22",
+ "FCC", "5G", "20M", "HT", "2T", "40", "30", "ETSI", "5G",
+ "20M", "HT", "2T", "40", "20", "MKK", "5G", "20M", "HT",
+ "2T", "40", "22", "FCC", "5G", "20M", "HT", "2T", "44",
+ "30", "ETSI", "5G", "20M", "HT", "2T", "44", "20", "MKK",
+ "5G", "20M", "HT", "2T", "44", "22", "FCC", "5G", "20M",
+ "HT", "2T", "48", "30", "ETSI", "5G", "20M", "HT", "2T",
+ "48", "20", "MKK", "5G", "20M", "HT", "2T", "48", "22",
+ "FCC", "5G", "20M", "HT", "2T", "52", "30", "ETSI", "5G",
+ "20M", "HT", "2T", "52", "20", "MKK", "5G", "20M", "HT",
+ "2T", "52", "22", "FCC", "5G", "20M", "HT", "2T", "56",
+ "30", "ETSI", "5G", "20M", "HT", "2T", "56", "20", "MKK",
+ "5G", "20M", "HT", "2T", "56", "22", "FCC", "5G", "20M",
+ "HT", "2T", "60", "30", "ETSI", "5G", "20M", "HT", "2T",
+ "60", "20", "MKK", "5G", "20M", "HT", "2T", "60", "22",
+ "FCC", "5G", "20M", "HT", "2T", "64", "28", "ETSI", "5G",
+ "20M", "HT", "2T", "64", "20", "MKK", "5G", "20M", "HT",
+ "2T", "64", "22", "FCC", "5G", "20M", "HT", "2T", "100",
+ "26", "ETSI", "5G", "20M", "HT", "2T", "100", "20", "MKK",
+ "5G", "20M", "HT", "2T", "100", "30", "FCC", "5G", "20M",
+ "HT", "2T", "104", "30", "ETSI", "5G", "20M", "HT", "2T",
+ "104", "20", "MKK", "5G", "20M", "HT", "2T", "104", "30",
+ "FCC", "5G", "20M", "HT", "2T", "108", "32", "ETSI", "5G",
+ "20M", "HT", "2T", "108", "20", "MKK", "5G", "20M", "HT",
+ "2T", "108", "30", "FCC", "5G", "20M", "HT", "2T", "112",
+ "32", "ETSI", "5G", "20M", "HT", "2T", "112", "20", "MKK",
+ "5G", "20M", "HT", "2T", "112", "30", "FCC", "5G", "20M",
+ "HT", "2T", "116", "32", "ETSI", "5G", "20M", "HT", "2T",
+ "116", "20", "MKK", "5G", "20M", "HT", "2T", "116", "30",
+ "FCC", "5G", "20M", "HT", "2T", "120", "32", "ETSI", "5G",
+ "20M", "HT", "2T", "120", "20", "MKK", "5G", "20M", "HT",
+ "2T", "120", "30", "FCC", "5G", "20M", "HT", "2T", "124",
+ "32", "ETSI", "5G", "20M", "HT", "2T", "124", "20", "MKK",
+ "5G", "20M", "HT", "2T", "124", "30", "FCC", "5G", "20M",
+ "HT", "2T", "128", "32", "ETSI", "5G", "20M", "HT", "2T",
+ "128", "20", "MKK", "5G", "20M", "HT", "2T", "128", "30",
+ "FCC", "5G", "20M", "HT", "2T", "132", "32", "ETSI", "5G",
+ "20M", "HT", "2T", "132", "20", "MKK", "5G", "20M", "HT",
+ "2T", "132", "30", "FCC", "5G", "20M", "HT", "2T", "136",
+ "30", "ETSI", "5G", "20M", "HT", "2T", "136", "20", "MKK",
+ "5G", "20M", "HT", "2T", "136", "30", "FCC", "5G", "20M",
+ "HT", "2T", "140", "26", "ETSI", "5G", "20M", "HT", "2T",
+ "140", "20", "MKK", "5G", "20M", "HT", "2T", "140", "30",
+ "FCC", "5G", "20M", "HT", "2T", "144", "26", "ETSI", "5G",
+ "20M", "HT", "2T", "144", "63", "MKK", "5G", "20M", "HT",
+ "2T", "144", "63", "FCC", "5G", "20M", "HT", "2T", "149",
+ "32", "ETSI", "5G", "20M", "HT", "2T", "149", "63", "MKK",
+ "5G", "20M", "HT", "2T", "149", "63", "FCC", "5G", "20M",
+ "HT", "2T", "153", "32", "ETSI", "5G", "20M", "HT", "2T",
+ "153", "63", "MKK", "5G", "20M", "HT", "2T", "153", "63",
+ "FCC", "5G", "20M", "HT", "2T", "157", "32", "ETSI", "5G",
+ "20M", "HT", "2T", "157", "63", "MKK", "5G", "20M", "HT",
+ "2T", "157", "63", "FCC", "5G", "20M", "HT", "2T", "161",
+ "32", "ETSI", "5G", "20M", "HT", "2T", "161", "63", "MKK",
+ "5G", "20M", "HT", "2T", "161", "63", "FCC", "5G", "20M",
+ "HT", "2T", "165", "32", "ETSI", "5G", "20M", "HT", "2T",
+ "165", "63", "MKK", "5G", "20M", "HT", "2T", "165", "63",
+ "FCC", "5G", "40M", "HT", "1T", "38", "22", "ETSI", "5G",
+ "40M", "HT", "1T", "38", "30", "MKK", "5G", "40M", "HT",
+ "1T", "38", "30", "FCC", "5G", "40M", "HT", "1T", "46",
+ "30", "ETSI", "5G", "40M", "HT", "1T", "46", "30", "MKK",
+ "5G", "40M", "HT", "1T", "46", "30", "FCC", "5G", "40M",
+ "HT", "1T", "54", "30", "ETSI", "5G", "40M", "HT", "1T",
+ "54", "30", "MKK", "5G", "40M", "HT", "1T", "54", "30",
+ "FCC", "5G", "40M", "HT", "1T", "62", "24", "ETSI", "5G",
+ "40M", "HT", "1T", "62", "30", "MKK", "5G", "40M", "HT",
+ "1T", "62", "30", "FCC", "5G", "40M", "HT", "1T", "102",
+ "24", "ETSI", "5G", "40M", "HT", "1T", "102", "30", "MKK",
+ "5G", "40M", "HT", "1T", "102", "30", "FCC", "5G", "40M",
+ "HT", "1T", "110", "30", "ETSI", "5G", "40M", "HT", "1T",
+ "110", "30", "MKK", "5G", "40M", "HT", "1T", "110", "30",
+ "FCC", "5G", "40M", "HT", "1T", "118", "30", "ETSI", "5G",
+ "40M", "HT", "1T", "118", "30", "MKK", "5G", "40M", "HT",
+ "1T", "118", "30", "FCC", "5G", "40M", "HT", "1T", "126",
+ "30", "ETSI", "5G", "40M", "HT", "1T", "126", "30", "MKK",
+ "5G", "40M", "HT", "1T", "126", "30", "FCC", "5G", "40M",
+ "HT", "1T", "134", "30", "ETSI", "5G", "40M", "HT", "1T",
+ "134", "30", "MKK", "5G", "40M", "HT", "1T", "134", "30",
+ "FCC", "5G", "40M", "HT", "1T", "142", "30", "ETSI", "5G",
+ "40M", "HT", "1T", "142", "63", "MKK", "5G", "40M", "HT",
+ "1T", "142", "63", "FCC", "5G", "40M", "HT", "1T", "151",
+ "30", "ETSI", "5G", "40M", "HT", "1T", "151", "63", "MKK",
+ "5G", "40M", "HT", "1T", "151", "63", "FCC", "5G", "40M",
+ "HT", "1T", "159", "30", "ETSI", "5G", "40M", "HT", "1T",
+ "159", "63", "MKK", "5G", "40M", "HT", "1T", "159", "63",
+ "FCC", "5G", "40M", "HT", "2T", "38", "20", "ETSI", "5G",
+ "40M", "HT", "2T", "38", "20", "MKK", "5G", "40M", "HT",
+ "2T", "38", "22", "FCC", "5G", "40M", "HT", "2T", "46",
+ "30", "ETSI", "5G", "40M", "HT", "2T", "46", "20", "MKK",
+ "5G", "40M", "HT", "2T", "46", "22", "FCC", "5G", "40M",
+ "HT", "2T", "54", "30", "ETSI", "5G", "40M", "HT", "2T",
+ "54", "20", "MKK", "5G", "40M", "HT", "2T", "54", "22",
+ "FCC", "5G", "40M", "HT", "2T", "62", "22", "ETSI", "5G",
+ "40M", "HT", "2T", "62", "20", "MKK", "5G", "40M", "HT",
+ "2T", "62", "22", "FCC", "5G", "40M", "HT", "2T", "102",
+ "22", "ETSI", "5G", "40M", "HT", "2T", "102", "20", "MKK",
+ "5G", "40M", "HT", "2T", "102", "30", "FCC", "5G", "40M",
+ "HT", "2T", "110", "30", "ETSI", "5G", "40M", "HT", "2T",
+ "110", "20", "MKK", "5G", "40M", "HT", "2T", "110", "30",
+ "FCC", "5G", "40M", "HT", "2T", "118", "30", "ETSI", "5G",
+ "40M", "HT", "2T", "118", "20", "MKK", "5G", "40M", "HT",
+ "2T", "118", "30", "FCC", "5G", "40M", "HT", "2T", "126",
+ "30", "ETSI", "5G", "40M", "HT", "2T", "126", "20", "MKK",
+ "5G", "40M", "HT", "2T", "126", "30", "FCC", "5G", "40M",
+ "HT", "2T", "134", "30", "ETSI", "5G", "40M", "HT", "2T",
+ "134", "20", "MKK", "5G", "40M", "HT", "2T", "134", "30",
+ "FCC", "5G", "40M", "HT", "2T", "142", "30", "ETSI", "5G",
+ "40M", "HT", "2T", "142", "63", "MKK", "5G", "40M", "HT",
+ "2T", "142", "63", "FCC", "5G", "40M", "HT", "2T", "151",
+ "30", "ETSI", "5G", "40M", "HT", "2T", "151", "63", "MKK",
+ "5G", "40M", "HT", "2T", "151", "63", "FCC", "5G", "40M",
+ "HT", "2T", "159", "30", "ETSI", "5G", "40M", "HT", "2T",
+ "159", "63", "MKK", "5G", "40M", "HT", "2T", "159", "63",
+ "FCC", "5G", "80M", "VHT", "1T", "42", "20", "ETSI", "5G",
+ "80M", "VHT", "1T", "42", "30", "MKK", "5G", "80M", "VHT",
+ "1T", "42", "28", "FCC", "5G", "80M", "VHT", "1T", "58",
+ "20", "ETSI", "5G", "80M", "VHT", "1T", "58", "30", "MKK",
+ "5G", "80M", "VHT", "1T", "58", "28", "FCC", "5G", "80M",
+ "VHT", "1T", "106", "20", "ETSI", "5G", "80M", "VHT", "1T",
+ "106", "30", "MKK", "5G", "80M", "VHT", "1T", "106", "30",
+ "FCC", "5G", "80M", "VHT", "1T", "122", "30", "ETSI", "5G",
+ "80M", "VHT", "1T", "122", "30", "MKK", "5G", "80M", "VHT",
+ "1T", "122", "30", "FCC", "5G", "80M", "VHT", "1T", "138",
+ "30", "ETSI", "5G", "80M", "VHT", "1T", "138", "63", "MKK",
+ "5G", "80M", "VHT", "1T", "138", "63", "FCC", "5G", "80M",
+ "VHT", "1T", "155", "30", "ETSI", "5G", "80M", "VHT", "1T",
+ "155", "63", "MKK", "5G", "80M", "VHT", "1T", "155", "63",
+ "FCC", "5G", "80M", "VHT", "2T", "42", "18", "ETSI", "5G",
+ "80M", "VHT", "2T", "42", "20", "MKK", "5G", "80M", "VHT",
+ "2T", "42", "22", "FCC", "5G", "80M", "VHT", "2T", "58",
+ "18", "ETSI", "5G", "80M", "VHT", "2T", "58", "20", "MKK",
+ "5G", "80M", "VHT", "2T", "58", "22", "FCC", "5G", "80M",
+ "VHT", "2T", "106", "20", "ETSI", "5G", "80M", "VHT", "2T",
+ "106", "20", "MKK", "5G", "80M", "VHT", "2T", "106", "30",
+ "FCC", "5G", "80M", "VHT", "2T", "122", "30", "ETSI", "5G",
+ "80M", "VHT", "2T", "122", "20", "MKK", "5G", "80M", "VHT",
+ "2T", "122", "30", "FCC", "5G", "80M", "VHT", "2T", "138",
+ "30", "ETSI", "5G", "80M", "VHT", "2T", "138", "63", "MKK",
+ "5G", "80M", "VHT", "2T", "138", "63", "FCC", "5G", "80M",
+ "VHT", "2T", "155", "30", "ETSI", "5G", "80M", "VHT", "2T",
+ "155", "63", "MKK", "5G", "80M", "VHT", "2T", "155", "63"};
+
+void odm_read_and_config_mp_8822b_txpwr_lmt_type5(struct phy_dm_struct *dm)
+{
+ u32 i = 0;
+ u32 array_len = sizeof(array_mp_8822b_txpwr_lmt_type5) / sizeof(u8 *);
+ u8 **array = (u8 **)array_mp_8822b_txpwr_lmt_type5;
+
+ ODM_RT_TRACE(dm, ODM_COMP_INIT,
+ "===> odm_read_and_config_mp_8822b_txpwr_lmt_type5\n");
+
+ for (i = 0; i < array_len; i += 7) {
+ u8 *regulation = array[i];
+ u8 *band = array[i + 1];
+ u8 *bandwidth = array[i + 2];
+ u8 *rate = array[i + 3];
+ u8 *rf_path = array[i + 4];
+ u8 *chnl = array[i + 5];
+ u8 *val = array[i + 6];
+
+ odm_config_bb_txpwr_lmt_8822b(dm, regulation, band, bandwidth,
+ rate, rf_path, chnl, val);
+ }
+}
diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_rf.h b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_rf.h
new file mode 100644
index 0000000..1340fa9
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_rf.h
@@ -0,0 +1,129 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+/*Image2HeaderVersion: 3.2*/
+#ifndef __INC_MP_RF_HW_IMG_8822B_H
+#define __INC_MP_RF_HW_IMG_8822B_H
+
+/******************************************************************************
+ * radioa.TXT
+ ******************************************************************************/
+
+void odm_read_and_config_mp_8822b_radioa(struct phy_dm_struct *dm);
+u32 odm_get_version_mp_8822b_radioa(void);
+
+/******************************************************************************
+ * radiob.TXT
+ ******************************************************************************/
+
+void odm_read_and_config_mp_8822b_radiob(struct phy_dm_struct *dm);
+u32 odm_get_version_mp_8822b_radiob(void);
+
+/******************************************************************************
+ * txpowertrack.TXT
+ ******************************************************************************/
+
+void odm_read_and_config_mp_8822b_txpowertrack(struct phy_dm_struct *dm);
+u32 odm_get_version_mp_8822b_txpowertrack(void);
+
+/******************************************************************************
+ * txpowertrack_type0.TXT
+ ******************************************************************************/
+
+void odm_read_and_config_mp_8822b_txpowertrack_type0(struct phy_dm_struct *dm);
+u32 odm_get_version_mp_8822b_txpowertrack_type0(void);
+
+/******************************************************************************
+ * txpowertrack_type1.TXT
+ ******************************************************************************/
+
+void odm_read_and_config_mp_8822b_txpowertrack_type1(struct phy_dm_struct *dm);
+u32 odm_get_version_mp_8822b_txpowertrack_type1(void);
+
+/******************************************************************************
+ * txpowertrack_type2.TXT
+ ******************************************************************************/
+
+void odm_read_and_config_mp_8822b_txpowertrack_type2(struct phy_dm_struct *dm);
+u32 odm_get_version_mp_8822b_txpowertrack_type2(void);
+
+/******************************************************************************
+ * txpowertrack_type3_type5.TXT
+ ******************************************************************************/
+
+void odm_read_and_config_mp_8822b_txpowertrack_type3_type5(
+ struct phy_dm_struct *dm);
+u32 odm_get_version_mp_8822b_txpowertrack_type3_type5(void);
+
+/******************************************************************************
+ * txpowertrack_type4.TXT
+ ******************************************************************************/
+
+void odm_read_and_config_mp_8822b_txpowertrack_type4(struct phy_dm_struct *dm);
+u32 odm_get_version_mp_8822b_txpowertrack_type4(void);
+
+/******************************************************************************
+ * txpowertrack_type6.TXT
+ ******************************************************************************/
+
+void odm_read_and_config_mp_8822b_txpowertrack_type6(struct phy_dm_struct *dm);
+u32 odm_get_version_mp_8822b_txpowertrack_type6(void);
+
+/******************************************************************************
+ * txpowertrack_type7.TXT
+ ******************************************************************************/
+
+void odm_read_and_config_mp_8822b_txpowertrack_type7(struct phy_dm_struct *dm);
+u32 odm_get_version_mp_8822b_txpowertrack_type7(void);
+
+/******************************************************************************
+ * txpowertrack_type8.TXT
+ *****************************************************************************/
+
+void odm_read_and_config_mp_8822b_txpowertrack_type8(struct phy_dm_struct *dm);
+u32 odm_get_version_mp_8822b_txpowertrack_type8(void);
+
+/******************************************************************************
+ * txpowertrack_type9.TXT
+ ******************************************************************************/
+
+void odm_read_and_config_mp_8822b_txpowertrack_type9(struct phy_dm_struct *dm);
+u32 odm_get_version_mp_8822b_txpowertrack_type9(void);
+
+/******************************************************************************
+ * txpwr_lmt.TXT
+ ******************************************************************************/
+
+void odm_read_and_config_mp_8822b_txpwr_lmt(struct phy_dm_struct *dm);
+u32 odm_get_version_mp_8822b_txpwr_lmt(void);
+
+/******************************************************************************
+ * txpwr_lmt_type5.TXT
+ ******************************************************************************/
+
+void odm_read_and_config_mp_8822b_txpwr_lmt_type5(struct phy_dm_struct *dm);
+u32 odm_get_version_mp_8822b_txpwr_lmt_type5(void);
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/halphyrf_8822b.c b/drivers/staging/rtlwifi/phydm/rtl8822b/halphyrf_8822b.c
new file mode 100644
index 0000000..ae3e227
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/rtl8822b/halphyrf_8822b.c
@@ -0,0 +1,351 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../mp_precomp.h"
+#include "../phydm_precomp.h"
+
+static bool
+get_mix_mode_tx_agc_bb_swing_offset_8822b(void *dm_void,
+ enum pwrtrack_method method,
+ u8 rf_path, u8 tx_power_index_offest)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
+
+ u8 bb_swing_upper_bound = cali_info->default_ofdm_index + 10;
+ u8 bb_swing_lower_bound = 0;
+
+ s8 tx_agc_index = 0;
+ u8 tx_bb_swing_index = cali_info->default_ofdm_index;
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "Path_%d cali_info->absolute_ofdm_swing_idx[rf_path]=%d, tx_power_index_offest=%d\n",
+ rf_path, cali_info->absolute_ofdm_swing_idx[rf_path],
+ tx_power_index_offest);
+
+ if (tx_power_index_offest > 0XF)
+ tx_power_index_offest = 0XF;
+
+ if (cali_info->absolute_ofdm_swing_idx[rf_path] >= 0 &&
+ cali_info->absolute_ofdm_swing_idx[rf_path] <=
+ tx_power_index_offest) {
+ tx_agc_index = cali_info->absolute_ofdm_swing_idx[rf_path];
+ tx_bb_swing_index = cali_info->default_ofdm_index;
+ } else if (cali_info->absolute_ofdm_swing_idx[rf_path] >
+ tx_power_index_offest) {
+ tx_agc_index = tx_power_index_offest;
+ cali_info->remnant_ofdm_swing_idx[rf_path] =
+ cali_info->absolute_ofdm_swing_idx[rf_path] -
+ tx_power_index_offest;
+ tx_bb_swing_index = cali_info->default_ofdm_index +
+ cali_info->remnant_ofdm_swing_idx[rf_path];
+
+ if (tx_bb_swing_index > bb_swing_upper_bound)
+ tx_bb_swing_index = bb_swing_upper_bound;
+ } else {
+ tx_agc_index = 0;
+
+ if (cali_info->default_ofdm_index >
+ (cali_info->absolute_ofdm_swing_idx[rf_path] * (-1)))
+ tx_bb_swing_index =
+ cali_info->default_ofdm_index +
+ cali_info->absolute_ofdm_swing_idx[rf_path];
+ else
+ tx_bb_swing_index = bb_swing_lower_bound;
+
+ if (tx_bb_swing_index < bb_swing_lower_bound)
+ tx_bb_swing_index = bb_swing_lower_bound;
+ }
+
+ cali_info->absolute_ofdm_swing_idx[rf_path] = tx_agc_index;
+ cali_info->bb_swing_idx_ofdm[rf_path] = tx_bb_swing_index;
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "MixMode Offset Path_%d cali_info->absolute_ofdm_swing_idx[rf_path]=%d cali_info->bb_swing_idx_ofdm[rf_path]=%d tx_power_index_offest=%d\n",
+ rf_path, cali_info->absolute_ofdm_swing_idx[rf_path],
+ cali_info->bb_swing_idx_ofdm[rf_path], tx_power_index_offest);
+
+ return true;
+}
+
+void odm_tx_pwr_track_set_pwr8822b(void *dm_void, enum pwrtrack_method method,
+ u8 rf_path, u8 channel_mapped_index)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
+ u8 tx_power_index_offest = 0;
+ u8 tx_power_index = 0;
+
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ u8 channel = rtlphy->current_channel;
+ u8 band_width = rtlphy->current_chan_bw;
+ u8 tx_rate = 0xFF;
+
+ if (!dm->mp_mode) {
+ u16 rate = *dm->forced_data_rate;
+
+ if (!rate) /*auto rate*/
+ tx_rate = dm->tx_rate;
+ else /*force rate*/
+ tx_rate = (u8)rate;
+ }
+
+ ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, "Call:%s tx_rate=0x%X\n",
+ __func__, tx_rate);
+
+ ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
+ "pRF->default_ofdm_index=%d pRF->default_cck_index=%d\n",
+ cali_info->default_ofdm_index,
+ cali_info->default_cck_index);
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "pRF->absolute_ofdm_swing_idx=%d pRF->remnant_ofdm_swing_idx=%d pRF->absolute_cck_swing_idx=%d pRF->remnant_cck_swing_idx=%d rf_path=%d\n",
+ cali_info->absolute_ofdm_swing_idx[rf_path],
+ cali_info->remnant_ofdm_swing_idx[rf_path],
+ cali_info->absolute_cck_swing_idx[rf_path],
+ cali_info->remnant_cck_swing_idx, rf_path);
+
+ if (dm->number_linked_client != 0)
+ tx_power_index = odm_get_tx_power_index(
+ dm, (enum odm_rf_radio_path)rf_path, tx_rate,
+ band_width, channel);
+
+ if (tx_power_index >= 63)
+ tx_power_index = 63;
+
+ tx_power_index_offest = 63 - tx_power_index;
+
+ ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
+ "tx_power_index=%d tx_power_index_offest=%d rf_path=%d\n",
+ tx_power_index, tx_power_index_offest, rf_path);
+
+ if (method ==
+ BBSWING) { /*use for mp driver clean power tracking status*/
+ switch (rf_path) {
+ case ODM_RF_PATH_A:
+ odm_set_bb_reg(
+ dm, 0xC94, (BIT(29) | BIT(28) | BIT(27) |
+ BIT(26) | BIT(25)),
+ cali_info->absolute_ofdm_swing_idx[rf_path]);
+ odm_set_bb_reg(
+ dm, REG_A_TX_SCALE_JAGUAR, 0xFFE00000,
+ tx_scaling_table_jaguar
+ [cali_info
+ ->bb_swing_idx_ofdm[rf_path]]);
+ break;
+ case ODM_RF_PATH_B:
+ odm_set_bb_reg(
+ dm, 0xE94, (BIT(29) | BIT(28) | BIT(27) |
+ BIT(26) | BIT(25)),
+ cali_info->absolute_ofdm_swing_idx[rf_path]);
+ odm_set_bb_reg(
+ dm, REG_B_TX_SCALE_JAGUAR, 0xFFE00000,
+ tx_scaling_table_jaguar
+ [cali_info
+ ->bb_swing_idx_ofdm[rf_path]]);
+ break;
+
+ default:
+ break;
+ }
+ } else if (method == MIX_MODE) {
+ switch (rf_path) {
+ case ODM_RF_PATH_A:
+ get_mix_mode_tx_agc_bb_swing_offset_8822b(
+ dm, method, rf_path, tx_power_index_offest);
+ odm_set_bb_reg(
+ dm, 0xC94, (BIT(29) | BIT(28) | BIT(27) |
+ BIT(26) | BIT(25)),
+ cali_info->absolute_ofdm_swing_idx[rf_path]);
+ odm_set_bb_reg(
+ dm, REG_A_TX_SCALE_JAGUAR, 0xFFE00000,
+ tx_scaling_table_jaguar
+ [cali_info
+ ->bb_swing_idx_ofdm[rf_path]]);
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "TXAGC(0xC94)=0x%x BBSwing(0xc1c)=0x%x BBSwingIndex=%d rf_path=%d\n",
+ odm_get_bb_reg(dm, 0xC94,
+ (BIT(29) | BIT(28) | BIT(27) |
+ BIT(26) | BIT(25))),
+ odm_get_bb_reg(dm, 0xc1c, 0xFFE00000),
+ cali_info->bb_swing_idx_ofdm[rf_path], rf_path);
+ break;
+
+ case ODM_RF_PATH_B:
+ get_mix_mode_tx_agc_bb_swing_offset_8822b(
+ dm, method, rf_path, tx_power_index_offest);
+ odm_set_bb_reg(
+ dm, 0xE94, (BIT(29) | BIT(28) | BIT(27) |
+ BIT(26) | BIT(25)),
+ cali_info->absolute_ofdm_swing_idx[rf_path]);
+ odm_set_bb_reg(
+ dm, REG_B_TX_SCALE_JAGUAR, 0xFFE00000,
+ tx_scaling_table_jaguar
+ [cali_info
+ ->bb_swing_idx_ofdm[rf_path]]);
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_TX_PWR_TRACK,
+ "TXAGC(0xE94)=0x%x BBSwing(0xe1c)=0x%x BBSwingIndex=%d rf_path=%d\n",
+ odm_get_bb_reg(dm, 0xE94,
+ (BIT(29) | BIT(28) | BIT(27) |
+ BIT(26) | BIT(25))),
+ odm_get_bb_reg(dm, 0xe1c, 0xFFE00000),
+ cali_info->bb_swing_idx_ofdm[rf_path], rf_path);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void get_delta_swing_table_8822b(void *dm_void, u8 **temperature_up_a,
+ u8 **temperature_down_a, u8 **temperature_up_b,
+ u8 **temperature_down_b)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
+
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ u8 channel = rtlphy->current_channel;
+
+ *temperature_up_a = cali_info->delta_swing_table_idx_2ga_p;
+ *temperature_down_a = cali_info->delta_swing_table_idx_2ga_n;
+ *temperature_up_b = cali_info->delta_swing_table_idx_2gb_p;
+ *temperature_down_b = cali_info->delta_swing_table_idx_2gb_n;
+
+ if (channel >= 36 && channel <= 64) {
+ *temperature_up_a = cali_info->delta_swing_table_idx_5ga_p[0];
+ *temperature_down_a = cali_info->delta_swing_table_idx_5ga_n[0];
+ *temperature_up_b = cali_info->delta_swing_table_idx_5gb_p[0];
+ *temperature_down_b = cali_info->delta_swing_table_idx_5gb_n[0];
+ } else if (channel >= 100 && channel <= 144) {
+ *temperature_up_a = cali_info->delta_swing_table_idx_5ga_p[1];
+ *temperature_down_a = cali_info->delta_swing_table_idx_5ga_n[1];
+ *temperature_up_b = cali_info->delta_swing_table_idx_5gb_p[1];
+ *temperature_down_b = cali_info->delta_swing_table_idx_5gb_n[1];
+ } else if (channel >= 149 && channel <= 177) {
+ *temperature_up_a = cali_info->delta_swing_table_idx_5ga_p[2];
+ *temperature_down_a = cali_info->delta_swing_table_idx_5ga_n[2];
+ *temperature_up_b = cali_info->delta_swing_table_idx_5gb_p[2];
+ *temperature_down_b = cali_info->delta_swing_table_idx_5gb_n[2];
+ }
+}
+
+static void _phy_lc_calibrate_8822b(struct phy_dm_struct *dm)
+{
+ u32 lc_cal = 0, cnt = 0;
+
+ /*backup RF0x18*/
+ lc_cal = odm_get_rf_reg(dm, ODM_RF_PATH_A, RF_CHNLBW, RFREGOFFSETMASK);
+
+ /*Start LCK*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, RF_CHNLBW, RFREGOFFSETMASK,
+ lc_cal | 0x08000);
+
+ ODM_delay_ms(100);
+
+ for (cnt = 0; cnt < 100; cnt++) {
+ if (odm_get_rf_reg(dm, ODM_RF_PATH_A, RF_CHNLBW, 0x8000) != 0x1)
+ break;
+ ODM_delay_ms(10);
+ }
+
+ /*Recover channel number*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, RF_CHNLBW, RFREGOFFSETMASK, lc_cal);
+}
+
+void phy_lc_calibrate_8822b(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ bool is_start_cont_tx = false, is_single_tone = false,
+ is_carrier_suppression = false;
+ u64 start_time;
+ u64 progressing_time;
+
+ if (is_start_cont_tx || is_single_tone || is_carrier_suppression) {
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[LCK]continues TX ing !!! LCK return\n");
+ return;
+ }
+
+ start_time = odm_get_current_time(dm);
+ _phy_lc_calibrate_8822b(dm);
+ progressing_time = odm_get_progressing_time(dm, start_time);
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[LCK]LCK progressing_time = %lld\n", progressing_time);
+}
+
+void configure_txpower_track_8822b(struct txpwrtrack_cfg *config)
+{
+ config->swing_table_size_cck = TXSCALE_TABLE_SIZE;
+ config->swing_table_size_ofdm = TXSCALE_TABLE_SIZE;
+ config->threshold_iqk = IQK_THRESHOLD;
+ config->threshold_dpk = DPK_THRESHOLD;
+ config->average_thermal_num = AVG_THERMAL_NUM_8822B;
+ config->rf_path_count = MAX_PATH_NUM_8822B;
+ config->thermal_reg_addr = RF_T_METER_8822B;
+
+ config->odm_tx_pwr_track_set_pwr = odm_tx_pwr_track_set_pwr8822b;
+ config->do_iqk = do_iqk_8822b;
+ config->phy_lc_calibrate = phy_lc_calibrate_8822b;
+
+ config->get_delta_swing_table = get_delta_swing_table_8822b;
+}
+
+void phy_set_rf_path_switch_8822b(struct phy_dm_struct *dm, bool is_main)
+{
+ /*BY SY Request */
+ odm_set_bb_reg(dm, 0x4C, (BIT(24) | BIT(23)), 0x2);
+ odm_set_bb_reg(dm, 0x974, 0xff, 0xff);
+
+ /*odm_set_bb_reg(dm, 0x1991, 0x3, 0x0);*/
+ odm_set_bb_reg(dm, 0x1990, (BIT(9) | BIT(8)), 0x0);
+
+ /*odm_set_bb_reg(dm, 0xCBE, 0x8, 0x0);*/
+ odm_set_bb_reg(dm, 0xCBC, BIT(19), 0x0);
+
+ odm_set_bb_reg(dm, 0xCB4, 0xff, 0x77);
+
+ odm_set_bb_reg(dm, 0x70, MASKBYTE3, 0x0e);
+ odm_set_bb_reg(dm, 0x1704, MASKDWORD, 0x0000ff00);
+ odm_set_bb_reg(dm, 0x1700, MASKDWORD, 0xc00f0038);
+
+ if (is_main) {
+ /*odm_set_bb_reg(dm, 0xCBD, 0x3, 0x2); WiFi */
+ odm_set_bb_reg(dm, 0xCBC, (BIT(9) | BIT(8)), 0x2); /*WiFi */
+ } else {
+ /*odm_set_bb_reg(dm, 0xCBD, 0x3, 0x1); BT*/
+ odm_set_bb_reg(dm, 0xCBC, (BIT(9) | BIT(8)), 0x1); /*BT*/
+ }
+}
diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/halphyrf_8822b.h b/drivers/staging/rtlwifi/phydm/rtl8822b/halphyrf_8822b.h
new file mode 100644
index 0000000..4f3bfe3
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/rtl8822b/halphyrf_8822b.h
@@ -0,0 +1,45 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __HAL_PHY_RF_8822B_H__
+#define __HAL_PHY_RF_8822B_H__
+
+#define AVG_THERMAL_NUM_8822B 4
+#define RF_T_METER_8822B 0x42
+
+void configure_txpower_track_8822b(struct txpwrtrack_cfg *config);
+
+void odm_tx_pwr_track_set_pwr8822b(void *dm_void, enum pwrtrack_method method,
+ u8 rf_path, u8 channel_mapped_index);
+
+void get_delta_swing_table_8822b(void *dm_void, u8 **temperature_up_a,
+ u8 **temperature_down_a, u8 **temperature_up_b,
+ u8 **temperature_down_b);
+
+void phy_lc_calibrate_8822b(void *dm_void);
+
+void phy_set_rf_path_switch_8822b(struct phy_dm_struct *dm, bool is_main);
+
+#endif /* #ifndef __HAL_PHY_RF_8822B_H__ */
diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_hal_api8822b.c b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_hal_api8822b.c
new file mode 100644
index 0000000..26d1022
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_hal_api8822b.c
@@ -0,0 +1,1815 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../mp_precomp.h"
+#include "../phydm_precomp.h"
+
+/* ======================================================================== */
+/* These following functions can be used for PHY DM only*/
+
+static u32 reg82c_8822b;
+static u32 reg838_8822b;
+static u32 reg830_8822b;
+static u32 reg83c_8822b;
+static u32 rega20_8822b;
+static u32 rega24_8822b;
+static u32 rega28_8822b;
+static enum odm_bw bw_8822b;
+static u8 central_ch_8822b;
+
+static u32 cca_ifem_ccut[12][4] = {
+ /*20M*/
+ {0x75D97010, 0x75D97010, 0x75D97010, 0x75D97010}, /*Reg82C*/
+ {0x00000000, 0x79a0ea2c, 0x00000000, 0x00000000}, /*Reg830*/
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg838*/
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg83C*/
+ /*40M*/
+ {0x75D97010, 0x75D97010, 0x75D97010, 0x75D97010}, /*Reg82C*/
+ {0x00000000, 0x79a0ea2c, 0x00000000, 0x79a0ea28}, /*Reg830*/
+ {0x87765541, 0x87766341, 0x87765541, 0x87766341}, /*Reg838*/
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg83C*/
+ /*80M*/
+ {0x75C97010, 0x75C97010, 0x75C97010, 0x75C97010}, /*Reg82C*/
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg830*/
+ {0x00000000, 0x87746641, 0x00000000, 0x87746641}, /*Reg838*/
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000},
+}; /*Reg83C*/
+static u32 cca_efem_ccut[12][4] = {
+ /*20M*/
+ {0x75A76010, 0x75A76010, 0x75A76010, 0x75A75010}, /*Reg82C*/
+ {0x00000000, 0x79a0ea2c, 0x00000000, 0x00000000}, /*Reg830*/
+ {0x87766651, 0x87766431, 0x87766451, 0x87766431}, /*Reg838*/
+ {0x9194b2b9, 0x9194b2b9, 0x9194b2b9, 0x9194b2b9}, /*Reg83C*/
+ /*40M*/
+ {0x75A85010, 0x75A75010, 0x75A85010, 0x75A75010}, /*Reg82C*/
+ {0x00000000, 0x79a0ea2c, 0x00000000, 0x00000000}, /*Reg830*/
+ {0x87766431, 0x87766431, 0x87766431, 0x87766431}, /*Reg838*/
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg83C*/
+ /*80M*/
+ {0x76BA7010, 0x75BA7010, 0x76BA7010, 0x75BA7010}, /*Reg82C*/
+ {0x79a0ea28, 0x00000000, 0x79a0ea28, 0x00000000}, /*Reg830*/
+ {0x87766431, 0x87766431, 0x87766431, 0x87766431}, /*Reg838*/
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000},
+}; /*Reg83C*/
+static u32 cca_ifem_ccut_rfetype5[12][4] = {
+ /*20M*/
+ {0x75D97010, 0x75D97010, 0x75D97010, 0x75D97010}, /*Reg82C*/
+ {0x00000000, 0x79a0ea2c, 0x00000000, 0x00000000}, /*Reg830*/
+ {0x00000000, 0x00000000, 0x87766461, 0x87766461}, /*Reg838*/
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg83C*/
+ /*40M*/
+ {0x75D97010, 0x75D97010, 0x75D97010, 0x75D97010}, /*Reg82C*/
+ {0x00000000, 0x79a0ea2c, 0x00000000, 0x79a0ea28}, /*Reg830*/
+ {0x87765541, 0x87766341, 0x87765541, 0x87766341}, /*Reg838*/
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg83C*/
+ /*80M*/
+ {0x75C97010, 0x75C97010, 0x75C97010, 0x75C97010}, /*Reg82C*/
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg830*/
+ {0x00000000, 0x76666641, 0x00000000, 0x76666641}, /*Reg838*/
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000},
+}; /*Reg83C*/
+static u32 cca_ifem_ccut_rfetype3[12][4] = {
+ /*20M*/
+ {0x75D97010, 0x75D97010, 0x75D97010, 0x75D97010}, /*Reg82C*/
+ {0x00000000, 0x79a0ea2c, 0x00000000, 0x00000000}, /*Reg830*/
+ {0x00000000, 0x00000000, 0x87766461, 0x87766461}, /*Reg838*/
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg83C*/
+ /*40M*/
+ {0x75D97010, 0x75D97010, 0x75D97010, 0x75D97010}, /*Reg82C*/
+ {0x00000000, 0x79a0ea2c, 0x00000000, 0x79a0ea28}, /*Reg830*/
+ {0x87765541, 0x87766341, 0x87765541, 0x87766341}, /*Reg838*/
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg83C*/
+ /*80M*/
+ {0x75C97010, 0x75C97010, 0x75C97010, 0x75C97010}, /*Reg82C*/
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg830*/
+ {0x00000000, 0x76666641, 0x00000000, 0x76666641}, /*Reg838*/
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000},
+}; /*Reg83C*/
+
+static inline u32 phydm_check_bit_mask(u32 bit_mask, u32 data_original,
+ u32 data)
+{
+ u8 bit_shift;
+
+ if (bit_mask != 0xfffff) {
+ for (bit_shift = 0; bit_shift <= 19; bit_shift++) {
+ if (((bit_mask >> bit_shift) & 0x1) == 1)
+ break;
+ }
+ return ((data_original) & (~bit_mask)) | (data << bit_shift);
+ }
+ return data;
+}
+
+static bool phydm_rfe_8822b(struct phy_dm_struct *dm, u8 channel)
+{
+ if (dm->rfe_type == 4) {
+ /* Default setting is in PHY parameters */
+
+ if (channel <= 14) {
+ /* signal source */
+ odm_set_bb_reg(dm, 0xcb0, (MASKBYTE2 | MASKLWORD),
+ 0x745774);
+ odm_set_bb_reg(dm, 0xeb0, (MASKBYTE2 | MASKLWORD),
+ 0x745774);
+ odm_set_bb_reg(dm, 0xcb4, MASKBYTE1, 0x57);
+ odm_set_bb_reg(dm, 0xeb4, MASKBYTE1, 0x57);
+
+ /* inverse or not */
+ odm_set_bb_reg(dm, 0xcbc, (BIT(5) | BIT(4) | BIT(3) |
+ BIT(2) | BIT(1) | BIT(0)),
+ 0x8);
+ odm_set_bb_reg(dm, 0xcbc, (BIT(11) | BIT(10)), 0x2);
+ odm_set_bb_reg(dm, 0xebc, (BIT(5) | BIT(4) | BIT(3) |
+ BIT(2) | BIT(1) | BIT(0)),
+ 0x8);
+ odm_set_bb_reg(dm, 0xebc, (BIT(11) | BIT(10)), 0x2);
+
+ /* antenna switch table */
+ if ((dm->rx_ant_status == (ODM_RF_A | ODM_RF_B)) ||
+ (dm->tx_ant_status == (ODM_RF_A | ODM_RF_B))) {
+ /* 2TX or 2RX */
+ odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xf050);
+ odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xf050);
+ } else if (dm->rx_ant_status == dm->tx_ant_status) {
+ /* TXA+RXA or TXB+RXB */
+ odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xf055);
+ odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xf055);
+ } else {
+ /* TXB+RXA or TXA+RXB */
+ odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xf550);
+ odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xf550);
+ }
+
+ } else if (channel > 35) {
+ /* signal source */
+ odm_set_bb_reg(dm, 0xcb0, (MASKBYTE2 | MASKLWORD),
+ 0x477547);
+ odm_set_bb_reg(dm, 0xeb0, (MASKBYTE2 | MASKLWORD),
+ 0x477547);
+ odm_set_bb_reg(dm, 0xcb4, MASKBYTE1, 0x75);
+ odm_set_bb_reg(dm, 0xeb4, MASKBYTE1, 0x75);
+
+ /* inverse or not */
+ odm_set_bb_reg(dm, 0xcbc, (BIT(5) | BIT(4) | BIT(3) |
+ BIT(2) | BIT(1) | BIT(0)),
+ 0x0);
+ odm_set_bb_reg(dm, 0xcbc, (BIT(11) | BIT(10)), 0x0);
+ odm_set_bb_reg(dm, 0xebc, (BIT(5) | BIT(4) | BIT(3) |
+ BIT(2) | BIT(1) | BIT(0)),
+ 0x0);
+ odm_set_bb_reg(dm, 0xebc, (BIT(11) | BIT(10)), 0x0);
+
+ /* antenna switch table */
+ if ((dm->rx_ant_status == (ODM_RF_A | ODM_RF_B)) ||
+ (dm->tx_ant_status == (ODM_RF_A | ODM_RF_B))) {
+ /* 2TX or 2RX */
+ odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa501);
+ odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa501);
+ } else if (dm->rx_ant_status == dm->tx_ant_status) {
+ /* TXA+RXA or TXB+RXB */
+ odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa500);
+ odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa500);
+ } else {
+ /* TXB+RXA or TXA+RXB */
+ odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa005);
+ odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa005);
+ }
+ } else {
+ return false;
+ }
+
+ } else if ((dm->rfe_type == 1) || (dm->rfe_type == 2) ||
+ (dm->rfe_type == 7) || (dm->rfe_type == 9)) {
+ /* eFem */
+ if (((dm->cut_version == ODM_CUT_A) ||
+ (dm->cut_version == ODM_CUT_B)) &&
+ (dm->rfe_type < 2)) {
+ if (channel <= 14) {
+ /* signal source */
+ odm_set_bb_reg(dm, 0xcb0,
+ (MASKBYTE2 | MASKLWORD),
+ 0x704570);
+ odm_set_bb_reg(dm, 0xeb0,
+ (MASKBYTE2 | MASKLWORD),
+ 0x704570);
+ odm_set_bb_reg(dm, 0xcb4, MASKBYTE1, 0x45);
+ odm_set_bb_reg(dm, 0xeb4, MASKBYTE1, 0x45);
+ } else if (channel > 35) {
+ odm_set_bb_reg(dm, 0xcb0,
+ (MASKBYTE2 | MASKLWORD),
+ 0x174517);
+ odm_set_bb_reg(dm, 0xeb0,
+ (MASKBYTE2 | MASKLWORD),
+ 0x174517);
+ odm_set_bb_reg(dm, 0xcb4, MASKBYTE1, 0x45);
+ odm_set_bb_reg(dm, 0xeb4, MASKBYTE1, 0x45);
+ } else {
+ return false;
+ }
+
+ /* delay 400ns for PAPE */
+ odm_set_bb_reg(dm, 0x810,
+ MASKBYTE3 | BIT(20) | BIT(21) | BIT(22) |
+ BIT(23),
+ 0x211);
+
+ /* antenna switch table */
+ odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa555);
+ odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa555);
+
+ /* inverse or not */
+ odm_set_bb_reg(dm, 0xcbc, (BIT(5) | BIT(4) | BIT(3) |
+ BIT(2) | BIT(1) | BIT(0)),
+ 0x0);
+ odm_set_bb_reg(dm, 0xcbc, (BIT(11) | BIT(10)), 0x0);
+ odm_set_bb_reg(dm, 0xebc, (BIT(5) | BIT(4) | BIT(3) |
+ BIT(2) | BIT(1) | BIT(0)),
+ 0x0);
+ odm_set_bb_reg(dm, 0xebc, (BIT(11) | BIT(10)), 0x0);
+
+ ODM_RT_TRACE(
+ dm, ODM_PHY_CONFIG,
+ "%s: Using old RFE control pin setting for A-cut and B-cut\n",
+ __func__);
+ } else {
+ if (channel <= 14) {
+ /* signal source */
+ odm_set_bb_reg(dm, 0xcb0,
+ (MASKBYTE2 | MASKLWORD),
+ 0x705770);
+ odm_set_bb_reg(dm, 0xeb0,
+ (MASKBYTE2 | MASKLWORD),
+ 0x705770);
+ odm_set_bb_reg(dm, 0xcb4, MASKBYTE1, 0x57);
+ odm_set_bb_reg(dm, 0xeb4, MASKBYTE1, 0x57);
+ odm_set_bb_reg(dm, 0xcb8, BIT(4), 0);
+ odm_set_bb_reg(dm, 0xeb8, BIT(4), 0);
+ } else if (channel > 35) {
+ /* signal source */
+ odm_set_bb_reg(dm, 0xcb0,
+ (MASKBYTE2 | MASKLWORD),
+ 0x177517);
+ odm_set_bb_reg(dm, 0xeb0,
+ (MASKBYTE2 | MASKLWORD),
+ 0x177517);
+ odm_set_bb_reg(dm, 0xcb4, MASKBYTE1, 0x75);
+ odm_set_bb_reg(dm, 0xeb4, MASKBYTE1, 0x75);
+ odm_set_bb_reg(dm, 0xcb8, BIT(5), 0);
+ odm_set_bb_reg(dm, 0xeb8, BIT(5), 0);
+ } else {
+ return false;
+ }
+
+ /* inverse or not */
+ odm_set_bb_reg(dm, 0xcbc, (BIT(5) | BIT(4) | BIT(3) |
+ BIT(2) | BIT(1) | BIT(0)),
+ 0x0);
+ odm_set_bb_reg(dm, 0xcbc, (BIT(11) | BIT(10)), 0x0);
+ odm_set_bb_reg(dm, 0xebc, (BIT(5) | BIT(4) | BIT(3) |
+ BIT(2) | BIT(1) | BIT(0)),
+ 0x0);
+ odm_set_bb_reg(dm, 0xebc, (BIT(11) | BIT(10)), 0x0);
+
+ /* antenna switch table */
+ if ((dm->rx_ant_status == (ODM_RF_A | ODM_RF_B)) ||
+ (dm->tx_ant_status == (ODM_RF_A | ODM_RF_B))) {
+ /* 2TX or 2RX */
+ odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa501);
+ odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa501);
+ } else if (dm->rx_ant_status == dm->tx_ant_status) {
+ /* TXA+RXA or TXB+RXB */
+ odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa500);
+ odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa500);
+ } else {
+ /* TXB+RXA or TXA+RXB */
+ odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa005);
+ odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa005);
+ }
+ }
+ } else if ((dm->rfe_type == 0) || (dm->rfe_type == 3) ||
+ (dm->rfe_type == 5) || (dm->rfe_type == 6) ||
+ (dm->rfe_type == 8) || (dm->rfe_type == 10)) {
+ /* iFEM */
+ if (channel <= 14) {
+ /* signal source */
+
+ odm_set_bb_reg(dm, 0xcb0, (MASKBYTE2 | MASKLWORD),
+ 0x745774);
+ odm_set_bb_reg(dm, 0xeb0, (MASKBYTE2 | MASKLWORD),
+ 0x745774);
+ odm_set_bb_reg(dm, 0xcb4, MASKBYTE1, 0x57);
+ odm_set_bb_reg(dm, 0xeb4, MASKBYTE1, 0x57);
+
+ } else if (channel > 35) {
+ /* signal source */
+
+ odm_set_bb_reg(dm, 0xcb0, (MASKBYTE2 | MASKLWORD),
+ 0x477547);
+ odm_set_bb_reg(dm, 0xeb0, (MASKBYTE2 | MASKLWORD),
+ 0x477547);
+ odm_set_bb_reg(dm, 0xcb4, MASKBYTE1, 0x75);
+ odm_set_bb_reg(dm, 0xeb4, MASKBYTE1, 0x75);
+
+ } else {
+ return false;
+ }
+
+ /* inverse or not */
+ odm_set_bb_reg(dm, 0xcbc, (BIT(5) | BIT(4) | BIT(3) | BIT(2) |
+ BIT(1) | BIT(0)),
+ 0x0);
+ odm_set_bb_reg(dm, 0xcbc, (BIT(11) | BIT(10)), 0x0);
+ odm_set_bb_reg(dm, 0xebc, (BIT(5) | BIT(4) | BIT(3) | BIT(2) |
+ BIT(1) | BIT(0)),
+ 0x0);
+ odm_set_bb_reg(dm, 0xebc, (BIT(11) | BIT(10)), 0x0);
+
+ /* antenna switch table */
+ if (channel <= 14) {
+ if ((dm->rx_ant_status == (ODM_RF_A | ODM_RF_B)) ||
+ (dm->tx_ant_status == (ODM_RF_A | ODM_RF_B))) {
+ /* 2TX or 2RX */
+ odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa501);
+ odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa501);
+ } else if (dm->rx_ant_status == dm->tx_ant_status) {
+ /* TXA+RXA or TXB+RXB */
+ odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa500);
+ odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa500);
+ } else {
+ /* TXB+RXA or TXA+RXB */
+ odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa005);
+ odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa005);
+ }
+ } else if (channel > 35) {
+ odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa5a5);
+ odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa5a5);
+ }
+ }
+
+ /* chip top mux */
+ odm_set_bb_reg(dm, 0x64, BIT(29) | BIT(28), 0x3);
+ odm_set_bb_reg(dm, 0x4c, BIT(26) | BIT(25), 0x0);
+ odm_set_bb_reg(dm, 0x40, BIT(2), 0x1);
+
+ /* from s0 or s1 */
+ odm_set_bb_reg(dm, 0x1990,
+ (BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)),
+ 0x30);
+ odm_set_bb_reg(dm, 0x1990, (BIT(11) | BIT(10)), 0x3);
+
+ /* input or output */
+ odm_set_bb_reg(dm, 0x974,
+ (BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)),
+ 0x3f);
+ odm_set_bb_reg(dm, 0x974, (BIT(11) | BIT(10)), 0x3);
+
+ ODM_RT_TRACE(
+ dm, ODM_PHY_CONFIG,
+ "%s: Update RFE control pin setting (ch%d, tx_path 0x%x, rx_path 0x%x)\n",
+ __func__, channel, dm->tx_ant_status, dm->rx_ant_status);
+
+ return true;
+}
+
+static void phydm_ccapar_by_rfe_8822b(struct phy_dm_struct *dm)
+{
+ u32 cca_ifem[12][4], cca_efem[12][4];
+ u8 row, col;
+ u32 reg82c, reg830, reg838, reg83c;
+
+ if (dm->cut_version == ODM_CUT_A)
+ return;
+ {
+ odm_move_memory(dm, cca_efem, cca_efem_ccut, 48 * 4);
+ if (dm->rfe_type == 5)
+ odm_move_memory(dm, cca_ifem, cca_ifem_ccut_rfetype5,
+ 48 * 4);
+ else if (dm->rfe_type == 3)
+ odm_move_memory(dm, cca_ifem, cca_ifem_ccut_rfetype3,
+ 48 * 4);
+ else
+ odm_move_memory(dm, cca_ifem, cca_ifem_ccut, 48 * 4);
+
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s: Update CCA parameters for Ccut\n", __func__);
+ }
+
+ if (bw_8822b == ODM_BW20M)
+ row = 0;
+ else if (bw_8822b == ODM_BW40M)
+ row = 4;
+ else
+ row = 8;
+
+ if (central_ch_8822b <= 14) {
+ if ((dm->rx_ant_status == ODM_RF_A) ||
+ (dm->rx_ant_status == ODM_RF_B))
+ col = 0;
+ else
+ col = 1;
+ } else {
+ if ((dm->rx_ant_status == ODM_RF_A) ||
+ (dm->rx_ant_status == ODM_RF_B))
+ col = 2;
+ else
+ col = 3;
+ }
+
+ if ((dm->rfe_type == 1) || (dm->rfe_type == 4) || (dm->rfe_type == 6) ||
+ (dm->rfe_type == 7)) {
+ /*eFEM => RFE type 1 & RFE type 4 & RFE type 6 & RFE type 7*/
+ reg82c = (cca_efem[row][col] != 0) ? cca_efem[row][col] :
+ reg82c_8822b;
+ reg830 = (cca_efem[row + 1][col] != 0) ?
+ cca_efem[row + 1][col] :
+ reg830_8822b;
+ reg838 = (cca_efem[row + 2][col] != 0) ?
+ cca_efem[row + 2][col] :
+ reg838_8822b;
+ reg83c = (cca_efem[row + 3][col] != 0) ?
+ cca_efem[row + 3][col] :
+ reg83c_8822b;
+ } else if ((dm->rfe_type == 2) || (dm->rfe_type == 9)) {
+ /*5G eFEM, 2G iFEM => RFE type 2, 5G eFEM => RFE type 9 */
+ if (central_ch_8822b <= 14) {
+ reg82c = (cca_ifem[row][col] != 0) ?
+ cca_ifem[row][col] :
+ reg82c_8822b;
+ reg830 = (cca_ifem[row + 1][col] != 0) ?
+ cca_ifem[row + 1][col] :
+ reg830_8822b;
+ reg838 = (cca_ifem[row + 2][col] != 0) ?
+ cca_ifem[row + 2][col] :
+ reg838_8822b;
+ reg83c = (cca_ifem[row + 3][col] != 0) ?
+ cca_ifem[row + 3][col] :
+ reg83c_8822b;
+ } else {
+ reg82c = (cca_efem[row][col] != 0) ?
+ cca_efem[row][col] :
+ reg82c_8822b;
+ reg830 = (cca_efem[row + 1][col] != 0) ?
+ cca_efem[row + 1][col] :
+ reg830_8822b;
+ reg838 = (cca_efem[row + 2][col] != 0) ?
+ cca_efem[row + 2][col] :
+ reg838_8822b;
+ reg83c = (cca_efem[row + 3][col] != 0) ?
+ cca_efem[row + 3][col] :
+ reg83c_8822b;
+ }
+ } else {
+ /* iFEM =>RFE type 3 & RFE type 5 & RFE type 0 & RFE type 8 &
+ * RFE type 10
+ */
+ reg82c = (cca_ifem[row][col] != 0) ? cca_ifem[row][col] :
+ reg82c_8822b;
+ reg830 = (cca_ifem[row + 1][col] != 0) ?
+ cca_ifem[row + 1][col] :
+ reg830_8822b;
+ reg838 = (cca_ifem[row + 2][col] != 0) ?
+ cca_ifem[row + 2][col] :
+ reg838_8822b;
+ reg83c = (cca_ifem[row + 3][col] != 0) ?
+ cca_ifem[row + 3][col] :
+ reg83c_8822b;
+ }
+
+ odm_set_bb_reg(dm, 0x82c, MASKDWORD, reg82c);
+ odm_set_bb_reg(dm, 0x830, MASKDWORD, reg830);
+ odm_set_bb_reg(dm, 0x838, MASKDWORD, reg838);
+ odm_set_bb_reg(dm, 0x83c, MASKDWORD, reg83c);
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s: (Pkt%d, Intf%d, RFE%d), row = %d, col = %d\n",
+ __func__, dm->package_type, dm->support_interface,
+ dm->rfe_type, row, col);
+}
+
+static void phydm_ccapar_by_bw_8822b(struct phy_dm_struct *dm,
+ enum odm_bw bandwidth)
+{
+ u32 reg82c;
+
+ if (dm->cut_version != ODM_CUT_A)
+ return;
+
+ /* A-cut */
+ reg82c = odm_get_bb_reg(dm, 0x82c, MASKDWORD);
+
+ if (bandwidth == ODM_BW20M) {
+ /* 82c[15:12] = 4 */
+ /* 82c[27:24] = 6 */
+
+ reg82c &= (~(0x0f00f000));
+ reg82c |= ((0x4) << 12);
+ reg82c |= ((0x6) << 24);
+ } else if (bandwidth == ODM_BW40M) {
+ /* 82c[19:16] = 9 */
+ /* 82c[27:24] = 6 */
+
+ reg82c &= (~(0x0f0f0000));
+ reg82c |= ((0x9) << 16);
+ reg82c |= ((0x6) << 24);
+ } else if (bandwidth == ODM_BW80M) {
+ /* 82c[15:12] 7 */
+ /* 82c[19:16] b */
+ /* 82c[23:20] d */
+ /* 82c[27:24] 3 */
+
+ reg82c &= (~(0x0ffff000));
+ reg82c |= ((0xdb7) << 12);
+ reg82c |= ((0x3) << 24);
+ }
+
+ odm_set_bb_reg(dm, 0x82c, MASKDWORD, reg82c);
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): Update CCA parameters for Acut\n", __func__);
+}
+
+static void phydm_ccapar_by_rxpath_8822b(struct phy_dm_struct *dm)
+{
+ if (dm->cut_version != ODM_CUT_A)
+ return;
+
+ if ((dm->rx_ant_status == ODM_RF_A) ||
+ (dm->rx_ant_status == ODM_RF_B)) {
+ /* 838[7:4] = 8 */
+ /* 838[11:8] = 7 */
+ /* 838[15:12] = 6 */
+ /* 838[19:16] = 7 */
+ /* 838[23:20] = 7 */
+ /* 838[27:24] = 7 */
+ odm_set_bb_reg(dm, 0x838, 0x0ffffff0, 0x777678);
+ } else {
+ /* 838[7:4] = 3 */
+ /* 838[11:8] = 3 */
+ /* 838[15:12] = 6 */
+ /* 838[19:16] = 6 */
+ /* 838[23:20] = 7 */
+ /* 838[27:24] = 7 */
+ odm_set_bb_reg(dm, 0x838, 0x0ffffff0, 0x776633);
+ }
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): Update CCA parameters for Acut\n", __func__);
+}
+
+static void phydm_rxdfirpar_by_bw_8822b(struct phy_dm_struct *dm,
+ enum odm_bw bandwidth)
+{
+ if (bandwidth == ODM_BW40M) {
+ /* RX DFIR for BW40 */
+ odm_set_bb_reg(dm, 0x948, BIT(29) | BIT(28), 0x1);
+ odm_set_bb_reg(dm, 0x94c, BIT(29) | BIT(28), 0x0);
+ odm_set_bb_reg(dm, 0xc20, BIT(31), 0x0);
+ odm_set_bb_reg(dm, 0xe20, BIT(31), 0x0);
+ } else if (bandwidth == ODM_BW80M) {
+ /* RX DFIR for BW80 */
+ odm_set_bb_reg(dm, 0x948, BIT(29) | BIT(28), 0x2);
+ odm_set_bb_reg(dm, 0x94c, BIT(29) | BIT(28), 0x1);
+ odm_set_bb_reg(dm, 0xc20, BIT(31), 0x0);
+ odm_set_bb_reg(dm, 0xe20, BIT(31), 0x0);
+ } else {
+ /* RX DFIR for BW20, BW10 and BW5*/
+ odm_set_bb_reg(dm, 0x948, BIT(29) | BIT(28), 0x2);
+ odm_set_bb_reg(dm, 0x94c, BIT(29) | BIT(28), 0x2);
+ odm_set_bb_reg(dm, 0xc20, BIT(31), 0x1);
+ odm_set_bb_reg(dm, 0xe20, BIT(31), 0x1);
+ }
+}
+
+bool phydm_write_txagc_1byte_8822b(struct phy_dm_struct *dm, u32 power_index,
+ enum odm_rf_radio_path path, u8 hw_rate)
+{
+ u32 offset_txagc[2] = {0x1d00, 0x1d80};
+ u8 rate_idx = (hw_rate & 0xfc), i;
+ u8 rate_offset = (hw_rate & 0x3);
+ u32 txagc_content = 0x0;
+
+ /* For debug command only!!!! */
+
+ /* Error handling */
+ if ((path > ODM_RF_PATH_B) || (hw_rate > 0x53)) {
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): unsupported path (%d)\n", __func__, path);
+ return false;
+ }
+
+ /* For HW limitation, We can't write TXAGC once a byte. */
+ for (i = 0; i < 4; i++) {
+ if (i != rate_offset)
+ txagc_content =
+ txagc_content | (config_phydm_read_txagc_8822b(
+ dm, path, rate_idx + i)
+ << (i << 3));
+ else
+ txagc_content = txagc_content |
+ ((power_index & 0x3f) << (i << 3));
+ }
+ odm_set_bb_reg(dm, (offset_txagc[path] + rate_idx), MASKDWORD,
+ txagc_content);
+
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): path-%d rate index 0x%x (0x%x) = 0x%x\n", __func__,
+ path, hw_rate, (offset_txagc[path] + hw_rate),
+ power_index);
+ return true;
+}
+
+void phydm_init_hw_info_by_rfe_type_8822b(struct phy_dm_struct *dm)
+{
+ u16 mask_path_a = 0x0303;
+ u16 mask_path_b = 0x0c0c;
+ /*u16 mask_path_c = 0x3030;*/
+ /*u16 mask_path_d = 0xc0c0;*/
+
+ dm->is_init_hw_info_by_rfe = false;
+
+ if ((dm->rfe_type == 1) || (dm->rfe_type == 6) || (dm->rfe_type == 7)) {
+ odm_cmn_info_init(dm, ODM_CMNINFO_BOARD_TYPE,
+ (ODM_BOARD_EXT_LNA | ODM_BOARD_EXT_LNA_5G |
+ ODM_BOARD_EXT_PA | ODM_BOARD_EXT_PA_5G));
+
+ if (dm->rfe_type == 6) {
+ odm_cmn_info_init(
+ dm, ODM_CMNINFO_GPA,
+ (TYPE_GPA1 & (mask_path_a | mask_path_b)));
+ odm_cmn_info_init(
+ dm, ODM_CMNINFO_APA,
+ (TYPE_APA1 & (mask_path_a | mask_path_b)));
+ odm_cmn_info_init(
+ dm, ODM_CMNINFO_GLNA,
+ (TYPE_GLNA1 & (mask_path_a | mask_path_b)));
+ odm_cmn_info_init(
+ dm, ODM_CMNINFO_ALNA,
+ (TYPE_ALNA1 & (mask_path_a | mask_path_b)));
+ } else if (dm->rfe_type == 7) {
+ odm_cmn_info_init(
+ dm, ODM_CMNINFO_GPA,
+ (TYPE_GPA2 & (mask_path_a | mask_path_b)));
+ odm_cmn_info_init(
+ dm, ODM_CMNINFO_APA,
+ (TYPE_APA2 & (mask_path_a | mask_path_b)));
+ odm_cmn_info_init(
+ dm, ODM_CMNINFO_GLNA,
+ (TYPE_GLNA2 & (mask_path_a | mask_path_b)));
+ odm_cmn_info_init(
+ dm, ODM_CMNINFO_ALNA,
+ (TYPE_ALNA2 & (mask_path_a | mask_path_b)));
+ } else {
+ odm_cmn_info_init(
+ dm, ODM_CMNINFO_GPA,
+ (TYPE_GPA0 & (mask_path_a | mask_path_b)));
+ odm_cmn_info_init(
+ dm, ODM_CMNINFO_APA,
+ (TYPE_APA0 & (mask_path_a | mask_path_b)));
+ odm_cmn_info_init(
+ dm, ODM_CMNINFO_GLNA,
+ (TYPE_GLNA0 & (mask_path_a | mask_path_b)));
+ odm_cmn_info_init(
+ dm, ODM_CMNINFO_ALNA,
+ (TYPE_ALNA0 & (mask_path_a | mask_path_b)));
+ }
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_PACKAGE_TYPE, 1);
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_EXT_LNA, true);
+ odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_LNA, true);
+ odm_cmn_info_init(dm, ODM_CMNINFO_EXT_PA, true);
+ odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_PA, true);
+ } else if (dm->rfe_type == 2) {
+ odm_cmn_info_init(dm, ODM_CMNINFO_BOARD_TYPE,
+ (ODM_BOARD_EXT_LNA_5G | ODM_BOARD_EXT_PA_5G));
+ odm_cmn_info_init(dm, ODM_CMNINFO_APA,
+ (TYPE_APA0 & (mask_path_a | mask_path_b)));
+ odm_cmn_info_init(dm, ODM_CMNINFO_ALNA,
+ (TYPE_ALNA0 & (mask_path_a | mask_path_b)));
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_PACKAGE_TYPE, 2);
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_EXT_LNA, false);
+ odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_LNA, true);
+ odm_cmn_info_init(dm, ODM_CMNINFO_EXT_PA, false);
+ odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_PA, true);
+ } else if (dm->rfe_type == 9) {
+ odm_cmn_info_init(dm, ODM_CMNINFO_BOARD_TYPE,
+ (ODM_BOARD_EXT_LNA_5G));
+ odm_cmn_info_init(dm, ODM_CMNINFO_ALNA,
+ (TYPE_ALNA0 & (mask_path_a | mask_path_b)));
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_PACKAGE_TYPE, 1);
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_EXT_LNA, false);
+ odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_LNA, true);
+ odm_cmn_info_init(dm, ODM_CMNINFO_EXT_PA, false);
+ odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_PA, false);
+ } else if ((dm->rfe_type == 3) || (dm->rfe_type == 5)) {
+ /* RFE type 3: 8822BS\8822BU TFBGA iFEM */
+ /* RFE type 5: 8822BE TFBGA iFEM */
+ odm_cmn_info_init(dm, ODM_CMNINFO_BOARD_TYPE, 0);
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_PACKAGE_TYPE, 2);
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_EXT_LNA, false);
+ odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_LNA, false);
+ odm_cmn_info_init(dm, ODM_CMNINFO_EXT_PA, false);
+ odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_PA, false);
+ } else if (dm->rfe_type == 4) {
+ odm_cmn_info_init(dm, ODM_CMNINFO_BOARD_TYPE,
+ (ODM_BOARD_EXT_LNA | ODM_BOARD_EXT_LNA_5G |
+ ODM_BOARD_EXT_PA | ODM_BOARD_EXT_PA_5G));
+ odm_cmn_info_init(dm, ODM_CMNINFO_GPA,
+ (TYPE_GPA0 & (mask_path_a | mask_path_b)));
+ odm_cmn_info_init(dm, ODM_CMNINFO_APA,
+ (TYPE_APA0 & (mask_path_a | mask_path_b)));
+ odm_cmn_info_init(dm, ODM_CMNINFO_GLNA,
+ (TYPE_GLNA0 & (mask_path_a | mask_path_b)));
+ odm_cmn_info_init(dm, ODM_CMNINFO_ALNA,
+ (TYPE_ALNA0 & (mask_path_a | mask_path_b)));
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_PACKAGE_TYPE, 2);
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_EXT_LNA, true);
+ odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_LNA, true);
+ odm_cmn_info_init(dm, ODM_CMNINFO_EXT_PA, true);
+ odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_PA, true);
+ } else if (dm->rfe_type == 8) {
+ /* RFE type 8: TFBGA iFEM AP */
+ odm_cmn_info_init(dm, ODM_CMNINFO_BOARD_TYPE, 0);
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_PACKAGE_TYPE, 2);
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_EXT_LNA, false);
+ odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_LNA, false);
+ odm_cmn_info_init(dm, ODM_CMNINFO_EXT_PA, false);
+ odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_PA, false);
+ } else {
+ /* RFE Type 0 & 9 & 10: QFN iFEM */
+ odm_cmn_info_init(dm, ODM_CMNINFO_BOARD_TYPE, 0);
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_PACKAGE_TYPE, 1);
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_EXT_LNA, false);
+ odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_LNA, false);
+ odm_cmn_info_init(dm, ODM_CMNINFO_EXT_PA, false);
+ odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_PA, false);
+ }
+
+ dm->is_init_hw_info_by_rfe = true;
+
+ ODM_RT_TRACE(
+ dm, ODM_PHY_CONFIG,
+ "%s(): RFE type (%d), Board type (0x%x), Package type (%d)\n",
+ __func__, dm->rfe_type, dm->board_type, dm->package_type);
+ ODM_RT_TRACE(
+ dm, ODM_PHY_CONFIG,
+ "%s(): 5G ePA (%d), 5G eLNA (%d), 2G ePA (%d), 2G eLNA (%d)\n",
+ __func__, dm->ext_pa_5g, dm->ext_lna_5g, dm->ext_pa,
+ dm->ext_lna);
+ ODM_RT_TRACE(
+ dm, ODM_PHY_CONFIG,
+ "%s(): 5G PA type (%d), 5G LNA type (%d), 2G PA type (%d), 2G LNA type (%d)\n",
+ __func__, dm->type_apa, dm->type_alna, dm->type_gpa,
+ dm->type_glna);
+}
+
+s32 phydm_get_condition_number_8822B(struct phy_dm_struct *dm)
+{
+ s32 ret_val;
+
+ odm_set_bb_reg(dm, 0x1988, BIT(22), 0x1);
+ ret_val =
+ (s32)odm_get_bb_reg(dm, 0xf84, (BIT(17) | BIT(16) | MASKLWORD));
+
+ if (bw_8822b == 0) {
+ ret_val = ret_val << (8 - 4);
+ ret_val = ret_val / 234;
+ } else if (bw_8822b == 1) {
+ ret_val = ret_val << (7 - 4);
+ ret_val = ret_val / 108;
+ } else if (bw_8822b == 2) {
+ ret_val = ret_val << (6 - 4);
+ ret_val = ret_val / 52;
+ }
+
+ return ret_val;
+}
+
+/* ======================================================================== */
+
+/* ======================================================================== */
+/* These following functions can be used by driver*/
+
+u32 config_phydm_read_rf_reg_8822b(struct phy_dm_struct *dm,
+ enum odm_rf_radio_path rf_path, u32 reg_addr,
+ u32 bit_mask)
+{
+ u32 readback_value, direct_addr;
+ u32 offset_read_rf[2] = {0x2800, 0x2c00};
+ u32 power_RF[2] = {0x1c, 0xec};
+
+ /* Error handling.*/
+ if (rf_path > ODM_RF_PATH_B) {
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): unsupported path (%d)\n", __func__,
+ rf_path);
+ return INVALID_RF_DATA;
+ }
+
+ /* Error handling. Check if RF power is enable or not */
+ /* 0xffffffff means RF power is disable */
+ if (odm_get_mac_reg(dm, power_RF[rf_path], MASKBYTE3) != 0x7) {
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): Read fail, RF is disabled\n", __func__);
+ return INVALID_RF_DATA;
+ }
+
+ /* Calculate offset */
+ reg_addr &= 0xff;
+ direct_addr = offset_read_rf[rf_path] + (reg_addr << 2);
+
+ /* RF register only has 20bits */
+ bit_mask &= RFREGOFFSETMASK;
+
+ /* Read RF register directly */
+ readback_value = odm_get_bb_reg(dm, direct_addr, bit_mask);
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): RF-%d 0x%x = 0x%x, bit mask = 0x%x\n", __func__,
+ rf_path, reg_addr, readback_value, bit_mask);
+ return readback_value;
+}
+
+bool config_phydm_write_rf_reg_8822b(struct phy_dm_struct *dm,
+ enum odm_rf_radio_path rf_path,
+ u32 reg_addr, u32 bit_mask, u32 data)
+{
+ u32 data_and_addr = 0, data_original = 0;
+ u32 offset_write_rf[2] = {0xc90, 0xe90};
+ u32 power_RF[2] = {0x1c, 0xec};
+
+ /* Error handling.*/
+ if (rf_path > ODM_RF_PATH_B) {
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): unsupported path (%d)\n", __func__,
+ rf_path);
+ return false;
+ }
+
+ /* Read RF register content first */
+ reg_addr &= 0xff;
+ bit_mask = bit_mask & RFREGOFFSETMASK;
+
+ if (bit_mask != RFREGOFFSETMASK) {
+ data_original = config_phydm_read_rf_reg_8822b(
+ dm, rf_path, reg_addr, RFREGOFFSETMASK);
+
+ /* Error handling. RF is disabled */
+ if (!config_phydm_read_rf_check_8822b(data_original)) {
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): Write fail, RF is disable\n",
+ __func__);
+ return false;
+ }
+
+ /* check bit mask */
+ data = phydm_check_bit_mask(bit_mask, data_original, data);
+ } else if (odm_get_mac_reg(dm, power_RF[rf_path], MASKBYTE3) != 0x7) {
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): Write fail, RF is disabled\n", __func__);
+ return false;
+ }
+
+ /* Put write addr in [27:20] and write data in [19:00] */
+ data_and_addr = ((reg_addr << 20) | (data & 0x000fffff)) & 0x0fffffff;
+
+ /* Write operation */
+ odm_set_bb_reg(dm, offset_write_rf[rf_path], MASKDWORD, data_and_addr);
+ ODM_RT_TRACE(
+ dm, ODM_PHY_CONFIG,
+ "%s(): RF-%d 0x%x = 0x%x (original: 0x%x), bit mask = 0x%x\n",
+ __func__, rf_path, reg_addr, data, data_original, bit_mask);
+ return true;
+}
+
+bool config_phydm_write_txagc_8822b(struct phy_dm_struct *dm, u32 power_index,
+ enum odm_rf_radio_path path, u8 hw_rate)
+{
+ u32 offset_txagc[2] = {0x1d00, 0x1d80};
+ u8 rate_idx = (hw_rate & 0xfc);
+
+ /* Input need to be HW rate index, not driver rate index!!!! */
+
+ if (dm->is_disable_phy_api) {
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): disable PHY API for debug!!\n", __func__);
+ return true;
+ }
+
+ /* Error handling */
+ if ((path > ODM_RF_PATH_B) || (hw_rate > 0x53)) {
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): unsupported path (%d)\n", __func__, path);
+ return false;
+ }
+
+ /* driver need to construct a 4-byte power index */
+ odm_set_bb_reg(dm, (offset_txagc[path] + rate_idx), MASKDWORD,
+ power_index);
+
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): path-%d rate index 0x%x (0x%x) = 0x%x\n", __func__,
+ path, hw_rate, (offset_txagc[path] + hw_rate),
+ power_index);
+ return true;
+}
+
+u8 config_phydm_read_txagc_8822b(struct phy_dm_struct *dm,
+ enum odm_rf_radio_path path, u8 hw_rate)
+{
+ u8 read_back_data;
+
+ /* Input need to be HW rate index, not driver rate index!!!! */
+
+ /* Error handling */
+ if ((path > ODM_RF_PATH_B) || (hw_rate > 0x53)) {
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): unsupported path (%d)\n", __func__, path);
+ return INVALID_TXAGC_DATA;
+ }
+
+ /* Disable TX AGC report */
+ odm_set_bb_reg(dm, 0x1998, BIT(16), 0x0); /* need to check */
+
+ /* Set data rate index (bit0~6) and path index (bit7) */
+ odm_set_bb_reg(dm, 0x1998, MASKBYTE0, (hw_rate | (path << 7)));
+
+ /* Enable TXAGC report */
+ odm_set_bb_reg(dm, 0x1998, BIT(16), 0x1);
+
+ /* Read TX AGC report */
+ read_back_data = (u8)odm_get_bb_reg(dm, 0xd30, 0x7f0000);
+
+ /* Driver have to disable TXAGC report after reading TXAGC
+ * (ref. user guide v11)
+ */
+ odm_set_bb_reg(dm, 0x1998, BIT(16), 0x0);
+
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): path-%d rate index 0x%x = 0x%x\n", __func__, path,
+ hw_rate, read_back_data);
+ return read_back_data;
+}
+
+bool config_phydm_switch_band_8822b(struct phy_dm_struct *dm, u8 central_ch)
+{
+ u32 rf_reg18;
+ bool rf_reg_status = true;
+
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG, "%s()======================>\n",
+ __func__);
+
+ if (dm->is_disable_phy_api) {
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): disable PHY API for debug!!\n", __func__);
+ return true;
+ }
+
+ rf_reg18 = config_phydm_read_rf_reg_8822b(dm, ODM_RF_PATH_A, 0x18,
+ RFREGOFFSETMASK);
+ rf_reg_status =
+ rf_reg_status & config_phydm_read_rf_check_8822b(rf_reg18);
+
+ if (central_ch <= 14) {
+ /* 2.4G */
+
+ /* Enable CCK block */
+ odm_set_bb_reg(dm, 0x808, BIT(28), 0x1);
+
+ /* Disable MAC CCK check */
+ odm_set_bb_reg(dm, 0x454, BIT(7), 0x0);
+
+ /* Disable BB CCK check */
+ odm_set_bb_reg(dm, 0xa80, BIT(18), 0x0);
+
+ /*CCA Mask*/
+ odm_set_bb_reg(dm, 0x814, 0x0000FC00, 15); /*default value*/
+
+ /* RF band */
+ rf_reg18 = (rf_reg18 & (~(BIT(16) | BIT(9) | BIT(8))));
+
+ /* RxHP dynamic control */
+ if ((dm->rfe_type == 2) || (dm->rfe_type == 3) ||
+ (dm->rfe_type == 5)) {
+ odm_set_bb_reg(dm, 0x8cc, MASKDWORD, 0x08108492);
+ odm_set_bb_reg(dm, 0x8d8, MASKDWORD, 0x29095612);
+ }
+
+ } else if (central_ch > 35) {
+ /* 5G */
+
+ /* Enable BB CCK check */
+ odm_set_bb_reg(dm, 0xa80, BIT(18), 0x1);
+
+ /* Enable CCK check */
+ odm_set_bb_reg(dm, 0x454, BIT(7), 0x1);
+
+ /* Disable CCK block */
+ odm_set_bb_reg(dm, 0x808, BIT(28), 0x0);
+
+ /*CCA Mask*/
+ odm_set_bb_reg(dm, 0x814, 0x0000FC00, 15); /*default value*/
+
+ /* RF band */
+ rf_reg18 = (rf_reg18 & (~(BIT(16) | BIT(9) | BIT(8))));
+ rf_reg18 = (rf_reg18 | BIT(8) | BIT(16));
+
+ /* RxHP dynamic control */
+ if ((dm->rfe_type == 2) || (dm->rfe_type == 3) ||
+ (dm->rfe_type == 5)) {
+ odm_set_bb_reg(dm, 0x8cc, MASKDWORD, 0x08100000);
+ odm_set_bb_reg(dm, 0x8d8, MASKDWORD, 0x21095612);
+ }
+
+ } else {
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): Fail to switch band (ch: %d)\n", __func__,
+ central_ch);
+ return false;
+ }
+
+ rf_reg_status = rf_reg_status & config_phydm_write_rf_reg_8822b(
+ dm, ODM_RF_PATH_A, 0x18,
+ RFREGOFFSETMASK, rf_reg18);
+
+ if (dm->rf_type > ODM_1T1R)
+ rf_reg_status =
+ rf_reg_status & config_phydm_write_rf_reg_8822b(
+ dm, ODM_RF_PATH_B, 0x18,
+ RFREGOFFSETMASK, rf_reg18);
+
+ if (!phydm_rfe_8822b(dm, central_ch))
+ return false;
+
+ if (!rf_reg_status) {
+ ODM_RT_TRACE(
+ dm, ODM_PHY_CONFIG,
+ "%s(): Fail to switch band (ch: %d), because writing RF register is fail\n",
+ __func__, central_ch);
+ return false;
+ }
+
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): Success to switch band (ch: %d)\n", __func__,
+ central_ch);
+ return true;
+}
+
+bool config_phydm_switch_channel_8822b(struct phy_dm_struct *dm, u8 central_ch)
+{
+ struct dig_thres *dig_tab = &dm->dm_dig_table;
+ u32 rf_reg18 = 0, rf_reg_b8 = 0, rf_reg_be = 0xff;
+ bool rf_reg_status = true;
+ u8 low_band[15] = {0x7, 0x6, 0x6, 0x5, 0x0, 0x0, 0x7, 0xff,
+ 0x6, 0x5, 0x0, 0x0, 0x7, 0x6, 0x6};
+ u8 middle_band[23] = {0x6, 0x5, 0x0, 0x0, 0x7, 0x6, 0x6, 0xff,
+ 0x0, 0x0, 0x7, 0x6, 0x6, 0x5, 0x0, 0xff,
+ 0x7, 0x6, 0x6, 0x5, 0x0, 0x0, 0x7};
+ u8 high_band[15] = {0x5, 0x5, 0x0, 0x7, 0x7, 0x6, 0x5, 0xff,
+ 0x0, 0x7, 0x7, 0x6, 0x5, 0x5, 0x0};
+
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG, "%s()====================>\n",
+ __func__);
+
+ if (dm->is_disable_phy_api) {
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): disable PHY API for debug!!\n", __func__);
+ return true;
+ }
+
+ central_ch_8822b = central_ch;
+ rf_reg18 = config_phydm_read_rf_reg_8822b(dm, ODM_RF_PATH_A, 0x18,
+ RFREGOFFSETMASK);
+ rf_reg_status =
+ rf_reg_status & config_phydm_read_rf_check_8822b(rf_reg18);
+ rf_reg18 = (rf_reg18 & (~(BIT(18) | BIT(17) | MASKBYTE0)));
+
+ if (dm->cut_version == ODM_CUT_A) {
+ rf_reg_b8 = config_phydm_read_rf_reg_8822b(
+ dm, ODM_RF_PATH_A, 0xb8, RFREGOFFSETMASK);
+ rf_reg_status = rf_reg_status &
+ config_phydm_read_rf_check_8822b(rf_reg_b8);
+ }
+
+ /* Switch band and channel */
+ if (central_ch <= 14) {
+ /* 2.4G */
+
+ /* 1. RF band and channel*/
+ rf_reg18 = (rf_reg18 | central_ch);
+
+ /* 2. AGC table selection */
+ odm_set_bb_reg(dm, 0x958, 0x1f, 0x0);
+ dig_tab->agc_table_idx = 0x0;
+
+ /* 3. Set central frequency for clock offset tracking */
+ odm_set_bb_reg(dm, 0x860, 0x1ffe0000, 0x96a);
+
+ /* Fix A-cut LCK fail issue @ 5285MHz~5375MHz, 0xb8[19]=0x0 */
+ if (dm->cut_version == ODM_CUT_A)
+ rf_reg_b8 = rf_reg_b8 | BIT(19);
+
+ /* CCK TX filter parameters */
+ if (central_ch == 14) {
+ odm_set_bb_reg(dm, 0xa20, MASKHWORD, 0x8488);
+ odm_set_bb_reg(dm, 0xa24, MASKDWORD, 0x00006577);
+ odm_set_bb_reg(dm, 0xa28, MASKLWORD, 0x0000);
+ } else {
+ odm_set_bb_reg(dm, 0xa20, MASKHWORD,
+ (rega20_8822b >> 16));
+ odm_set_bb_reg(dm, 0xa24, MASKDWORD, rega24_8822b);
+ odm_set_bb_reg(dm, 0xa28, MASKLWORD,
+ (rega28_8822b & MASKLWORD));
+ }
+
+ } else if (central_ch > 35) {
+ /* 5G */
+
+ /* 1. RF band and channel*/
+ rf_reg18 = (rf_reg18 | central_ch);
+
+ /* 2. AGC table selection */
+ if ((central_ch >= 36) && (central_ch <= 64)) {
+ odm_set_bb_reg(dm, 0x958, 0x1f, 0x1);
+ dig_tab->agc_table_idx = 0x1;
+ } else if ((central_ch >= 100) && (central_ch <= 144)) {
+ odm_set_bb_reg(dm, 0x958, 0x1f, 0x2);
+ dig_tab->agc_table_idx = 0x2;
+ } else if (central_ch >= 149) {
+ odm_set_bb_reg(dm, 0x958, 0x1f, 0x3);
+ dig_tab->agc_table_idx = 0x3;
+ } else {
+ ODM_RT_TRACE(
+ dm, ODM_PHY_CONFIG,
+ "%s(): Fail to switch channel (AGC) (ch: %d)\n",
+ __func__, central_ch);
+ return false;
+ }
+
+ /* 3. Set central frequency for clock offset tracking */
+ if ((central_ch >= 36) && (central_ch <= 48)) {
+ odm_set_bb_reg(dm, 0x860, 0x1ffe0000, 0x494);
+ } else if ((central_ch >= 52) && (central_ch <= 64)) {
+ odm_set_bb_reg(dm, 0x860, 0x1ffe0000, 0x453);
+ } else if ((central_ch >= 100) && (central_ch <= 116)) {
+ odm_set_bb_reg(dm, 0x860, 0x1ffe0000, 0x452);
+ } else if ((central_ch >= 118) && (central_ch <= 177)) {
+ odm_set_bb_reg(dm, 0x860, 0x1ffe0000, 0x412);
+ } else {
+ ODM_RT_TRACE(
+ dm, ODM_PHY_CONFIG,
+ "%s(): Fail to switch channel (fc_area) (ch: %d)\n",
+ __func__, central_ch);
+ return false;
+ }
+
+ /* Fix A-cut LCK fail issue @ 5285MHz~5375MHz, 0xb8[19]=0x0 */
+ if (dm->cut_version == ODM_CUT_A) {
+ if ((central_ch >= 57) && (central_ch <= 75))
+ rf_reg_b8 = rf_reg_b8 & (~BIT(19));
+ else
+ rf_reg_b8 = rf_reg_b8 | BIT(19);
+ }
+ } else {
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): Fail to switch channel (ch: %d)\n",
+ __func__, central_ch);
+ return false;
+ }
+
+ /* Modify IGI for MP driver to aviod PCIE interference */
+ if (dm->mp_mode && ((dm->rfe_type == 3) || (dm->rfe_type == 5))) {
+ if (central_ch == 14)
+ odm_write_dig(dm, 0x26);
+ else
+ odm_write_dig(dm, 0x20);
+ }
+
+ /* Modify the setting of register 0xBE to reduce phase noise */
+ if (central_ch <= 14)
+ rf_reg_be = 0x0;
+ else if ((central_ch >= 36) && (central_ch <= 64))
+ rf_reg_be = low_band[(central_ch - 36) >> 1];
+ else if ((central_ch >= 100) && (central_ch <= 144))
+ rf_reg_be = middle_band[(central_ch - 100) >> 1];
+ else if ((central_ch >= 149) && (central_ch <= 177))
+ rf_reg_be = high_band[(central_ch - 149) >> 1];
+ else
+ rf_reg_be = 0xff;
+
+ if (rf_reg_be != 0xff) {
+ rf_reg_status =
+ rf_reg_status & config_phydm_write_rf_reg_8822b(
+ dm, ODM_RF_PATH_A, 0xbe,
+ (BIT(17) | BIT(16) | BIT(15)),
+ rf_reg_be);
+ } else {
+ ODM_RT_TRACE(
+ dm, ODM_PHY_CONFIG,
+ "%s(): Fail to switch channel (ch: %d, Phase noise)\n",
+ __func__, central_ch);
+ return false;
+ }
+
+ /* Fix channel 144 issue, ask by RFSI Alvin*/
+ /* 00 when freq < 5400; 01 when 5400<=freq<=5720; 10 when freq > 5720;
+ * 2G don't care
+ */
+ /* need to set 0xdf[18]=1 before writing RF18 when channel 144 */
+ if (central_ch == 144) {
+ rf_reg_status = rf_reg_status &
+ config_phydm_write_rf_reg_8822b(
+ dm, ODM_RF_PATH_A, 0xdf, BIT(18), 0x1);
+ rf_reg18 = (rf_reg18 | BIT(17));
+ } else {
+ rf_reg_status = rf_reg_status &
+ config_phydm_write_rf_reg_8822b(
+ dm, ODM_RF_PATH_A, 0xdf, BIT(18), 0x0);
+
+ if (central_ch > 144)
+ rf_reg18 = (rf_reg18 | BIT(18));
+ else if (central_ch >= 80)
+ rf_reg18 = (rf_reg18 | BIT(17));
+ }
+
+ rf_reg_status = rf_reg_status & config_phydm_write_rf_reg_8822b(
+ dm, ODM_RF_PATH_A, 0x18,
+ RFREGOFFSETMASK, rf_reg18);
+
+ if (dm->cut_version == ODM_CUT_A)
+ rf_reg_status =
+ rf_reg_status & config_phydm_write_rf_reg_8822b(
+ dm, ODM_RF_PATH_A, 0xb8,
+ RFREGOFFSETMASK, rf_reg_b8);
+
+ if (dm->rf_type > ODM_1T1R) {
+ rf_reg_status =
+ rf_reg_status & config_phydm_write_rf_reg_8822b(
+ dm, ODM_RF_PATH_B, 0x18,
+ RFREGOFFSETMASK, rf_reg18);
+
+ if (dm->cut_version == ODM_CUT_A)
+ rf_reg_status = rf_reg_status &
+ config_phydm_write_rf_reg_8822b(
+ dm, ODM_RF_PATH_B, 0xb8,
+ RFREGOFFSETMASK, rf_reg_b8);
+ }
+
+ if (!rf_reg_status) {
+ ODM_RT_TRACE(
+ dm, ODM_PHY_CONFIG,
+ "%s(): Fail to switch channel (ch: %d), because writing RF register is fail\n",
+ __func__, central_ch);
+ return false;
+ }
+
+ phydm_ccapar_by_rfe_8822b(dm);
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): Success to switch channel (ch: %d)\n", __func__,
+ central_ch);
+ return true;
+}
+
+bool config_phydm_switch_bandwidth_8822b(struct phy_dm_struct *dm,
+ u8 primary_ch_idx,
+ enum odm_bw bandwidth)
+{
+ u32 rf_reg18;
+ bool rf_reg_status = true;
+ u8 IGI = 0;
+
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG, "%s()===================>\n",
+ __func__);
+
+ if (dm->is_disable_phy_api) {
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): disable PHY API for debug!!\n", __func__);
+ return true;
+ }
+
+ /* Error handling */
+ if ((bandwidth >= ODM_BW_MAX) ||
+ ((bandwidth == ODM_BW40M) && (primary_ch_idx > 2)) ||
+ ((bandwidth == ODM_BW80M) && (primary_ch_idx > 4))) {
+ ODM_RT_TRACE(
+ dm, ODM_PHY_CONFIG,
+ "%s(): Fail to switch bandwidth (bw: %d, primary ch: %d)\n",
+ __func__, bandwidth, primary_ch_idx);
+ return false;
+ }
+
+ bw_8822b = bandwidth;
+ rf_reg18 = config_phydm_read_rf_reg_8822b(dm, ODM_RF_PATH_A, 0x18,
+ RFREGOFFSETMASK);
+ rf_reg_status =
+ rf_reg_status & config_phydm_read_rf_check_8822b(rf_reg18);
+
+ /* Switch bandwidth */
+ switch (bandwidth) {
+ case ODM_BW20M: {
+ /* Small BW([7:6]) = 0, primary channel ([5:2]) = 0,
+ * rf mode([1:0]) = 20M
+ */
+ odm_set_bb_reg(dm, 0x8ac, MASKBYTE0, ODM_BW20M);
+
+ /* ADC clock = 160M clock for BW20 */
+ odm_set_bb_reg(dm, 0x8ac, (BIT(9) | BIT(8)), 0x0);
+ odm_set_bb_reg(dm, 0x8ac, BIT(16), 0x1);
+
+ /* DAC clock = 160M clock for BW20 */
+ odm_set_bb_reg(dm, 0x8ac, (BIT(21) | BIT(20)), 0x0);
+ odm_set_bb_reg(dm, 0x8ac, BIT(28), 0x1);
+
+ /* ADC buffer clock */
+ odm_set_bb_reg(dm, 0x8c4, BIT(30), 0x1);
+
+ /* RF bandwidth */
+ rf_reg18 = (rf_reg18 | BIT(11) | BIT(10));
+
+ break;
+ }
+ case ODM_BW40M: {
+ /* Small BW([7:6]) = 0, primary channel ([5:2]) = sub-channel,
+ * rf mode([1:0]) = 40M
+ */
+ odm_set_bb_reg(dm, 0x8ac, MASKBYTE0,
+ (((primary_ch_idx & 0xf) << 2) | ODM_BW40M));
+
+ /* CCK primary channel */
+ if (primary_ch_idx == 1)
+ odm_set_bb_reg(dm, 0xa00, BIT(4), primary_ch_idx);
+ else
+ odm_set_bb_reg(dm, 0xa00, BIT(4), 0);
+
+ /* ADC clock = 160M clock for BW40 */
+ odm_set_bb_reg(dm, 0x8ac, (BIT(11) | BIT(10)), 0x0);
+ odm_set_bb_reg(dm, 0x8ac, BIT(17), 0x1);
+
+ /* DAC clock = 160M clock for BW20 */
+ odm_set_bb_reg(dm, 0x8ac, (BIT(23) | BIT(22)), 0x0);
+ odm_set_bb_reg(dm, 0x8ac, BIT(29), 0x1);
+
+ /* ADC buffer clock */
+ odm_set_bb_reg(dm, 0x8c4, BIT(30), 0x1);
+
+ /* RF bandwidth */
+ rf_reg18 = (rf_reg18 & (~(BIT(11) | BIT(10))));
+ rf_reg18 = (rf_reg18 | BIT(11));
+
+ break;
+ }
+ case ODM_BW80M: {
+ /* Small BW([7:6]) = 0, primary channel ([5:2]) = sub-channel,
+ * rf mode([1:0]) = 80M
+ */
+ odm_set_bb_reg(dm, 0x8ac, MASKBYTE0,
+ (((primary_ch_idx & 0xf) << 2) | ODM_BW80M));
+
+ /* ADC clock = 160M clock for BW80 */
+ odm_set_bb_reg(dm, 0x8ac, (BIT(13) | BIT(12)), 0x0);
+ odm_set_bb_reg(dm, 0x8ac, BIT(18), 0x1);
+
+ /* DAC clock = 160M clock for BW20 */
+ odm_set_bb_reg(dm, 0x8ac, (BIT(25) | BIT(24)), 0x0);
+ odm_set_bb_reg(dm, 0x8ac, BIT(30), 0x1);
+
+ /* ADC buffer clock */
+ odm_set_bb_reg(dm, 0x8c4, BIT(30), 0x1);
+
+ /* RF bandwidth */
+ rf_reg18 = (rf_reg18 & (~(BIT(11) | BIT(10))));
+ rf_reg18 = (rf_reg18 | BIT(10));
+
+ break;
+ }
+ case ODM_BW5M: {
+ /* Small BW([7:6]) = 1, primary channel ([5:2]) = 0,
+ * rf mode([1:0]) = 20M
+ */
+ odm_set_bb_reg(dm, 0x8ac, MASKBYTE0, (BIT(6) | ODM_BW20M));
+
+ /* ADC clock = 40M clock */
+ odm_set_bb_reg(dm, 0x8ac, (BIT(9) | BIT(8)), 0x2);
+ odm_set_bb_reg(dm, 0x8ac, BIT(16), 0x0);
+
+ /* DAC clock = 160M clock for BW20 */
+ odm_set_bb_reg(dm, 0x8ac, (BIT(21) | BIT(20)), 0x2);
+ odm_set_bb_reg(dm, 0x8ac, BIT(28), 0x0);
+
+ /* ADC buffer clock */
+ odm_set_bb_reg(dm, 0x8c4, BIT(30), 0x0);
+ odm_set_bb_reg(dm, 0x8c8, BIT(31), 0x1);
+
+ /* RF bandwidth */
+ rf_reg18 = (rf_reg18 | BIT(11) | BIT(10));
+
+ break;
+ }
+ case ODM_BW10M: {
+ /* Small BW([7:6]) = 1, primary channel ([5:2]) = 0,
+ * rf mode([1:0]) = 20M
+ */
+ odm_set_bb_reg(dm, 0x8ac, MASKBYTE0, (BIT(7) | ODM_BW20M));
+
+ /* ADC clock = 80M clock */
+ odm_set_bb_reg(dm, 0x8ac, (BIT(9) | BIT(8)), 0x3);
+ odm_set_bb_reg(dm, 0x8ac, BIT(16), 0x0);
+
+ /* DAC clock = 160M clock for BW20 */
+ odm_set_bb_reg(dm, 0x8ac, (BIT(21) | BIT(20)), 0x3);
+ odm_set_bb_reg(dm, 0x8ac, BIT(28), 0x0);
+
+ /* ADC buffer clock */
+ odm_set_bb_reg(dm, 0x8c4, BIT(30), 0x0);
+ odm_set_bb_reg(dm, 0x8c8, BIT(31), 0x1);
+
+ /* RF bandwidth */
+ rf_reg18 = (rf_reg18 | BIT(11) | BIT(10));
+
+ break;
+ }
+ default:
+ ODM_RT_TRACE(
+ dm, ODM_PHY_CONFIG,
+ "%s(): Fail to switch bandwidth (bw: %d, primary ch: %d)\n",
+ __func__, bandwidth, primary_ch_idx);
+ }
+
+ /* Write RF register */
+ rf_reg_status = rf_reg_status & config_phydm_write_rf_reg_8822b(
+ dm, ODM_RF_PATH_A, 0x18,
+ RFREGOFFSETMASK, rf_reg18);
+
+ if (dm->rf_type > ODM_1T1R)
+ rf_reg_status =
+ rf_reg_status & config_phydm_write_rf_reg_8822b(
+ dm, ODM_RF_PATH_B, 0x18,
+ RFREGOFFSETMASK, rf_reg18);
+
+ if (!rf_reg_status) {
+ ODM_RT_TRACE(
+ dm, ODM_PHY_CONFIG,
+ "%s(): Fail to switch bandwidth (bw: %d, primary ch: %d), because writing RF register is fail\n",
+ __func__, bandwidth, primary_ch_idx);
+ return false;
+ }
+
+ /* Modify RX DFIR parameters */
+ phydm_rxdfirpar_by_bw_8822b(dm, bandwidth);
+
+ /* Modify CCA parameters */
+ phydm_ccapar_by_bw_8822b(dm, bandwidth);
+ phydm_ccapar_by_rfe_8822b(dm);
+
+ /* Toggle RX path to avoid RX dead zone issue */
+ odm_set_bb_reg(dm, 0x808, MASKBYTE0, 0x0);
+ odm_set_bb_reg(dm, 0x808, MASKBYTE0,
+ (dm->rx_ant_status | (dm->rx_ant_status << 4)));
+
+ /* Toggle IGI to let RF enter RX mode */
+ IGI = (u8)odm_get_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm));
+ odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm), IGI - 2);
+ odm_set_bb_reg(dm, ODM_REG(IGI_B, dm), ODM_BIT(IGI, dm), IGI - 2);
+ odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm), IGI);
+ odm_set_bb_reg(dm, ODM_REG(IGI_B, dm), ODM_BIT(IGI, dm), IGI);
+
+ ODM_RT_TRACE(
+ dm, ODM_PHY_CONFIG,
+ "%s(): Success to switch bandwidth (bw: %d, primary ch: %d)\n",
+ __func__, bandwidth, primary_ch_idx);
+ return true;
+}
+
+bool config_phydm_switch_channel_bw_8822b(struct phy_dm_struct *dm,
+ u8 central_ch, u8 primary_ch_idx,
+ enum odm_bw bandwidth)
+{
+ /* Switch band */
+ if (!config_phydm_switch_band_8822b(dm, central_ch))
+ return false;
+
+ /* Switch channel */
+ if (!config_phydm_switch_channel_8822b(dm, central_ch))
+ return false;
+
+ /* Switch bandwidth */
+ if (!config_phydm_switch_bandwidth_8822b(dm, primary_ch_idx, bandwidth))
+ return false;
+
+ return true;
+}
+
+bool config_phydm_trx_mode_8822b(struct phy_dm_struct *dm,
+ enum odm_rf_path tx_path,
+ enum odm_rf_path rx_path, bool is_tx2_path)
+{
+ bool rf_reg_status = true;
+ u8 IGI;
+ u32 rf_reg33 = 0;
+ u16 counter = 0;
+
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG, "%s()=====================>\n",
+ __func__);
+
+ if (dm->is_disable_phy_api) {
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): disable PHY API for debug!!\n", __func__);
+ return true;
+ }
+
+ if ((tx_path & (~(ODM_RF_A | ODM_RF_B))) != 0) {
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): Wrong TX setting (TX: 0x%x)\n", __func__,
+ tx_path);
+ return false;
+ }
+
+ if ((rx_path & (~(ODM_RF_A | ODM_RF_B))) != 0) {
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): Wrong RX setting (RX: 0x%x)\n", __func__,
+ rx_path);
+ return false;
+ }
+
+ /* RF mode of path-A and path-B */
+ /* Cannot shut down path-A, beacause synthesizer will be shut down when
+ * path-A is in shut down mode
+ */
+ if ((tx_path | rx_path) & ODM_RF_A)
+ odm_set_bb_reg(dm, 0xc08, MASKLWORD, 0x3231);
+ else
+ odm_set_bb_reg(dm, 0xc08, MASKLWORD, 0x1111);
+
+ if ((tx_path | rx_path) & ODM_RF_B)
+ odm_set_bb_reg(dm, 0xe08, MASKLWORD, 0x3231);
+ else
+ odm_set_bb_reg(dm, 0xe08, MASKLWORD, 0x1111);
+
+ /* Set TX antenna by Nsts */
+ odm_set_bb_reg(dm, 0x93c, (BIT(19) | BIT(18)), 0x3);
+ odm_set_bb_reg(dm, 0x80c, (BIT(29) | BIT(28)), 0x1);
+
+ /* Control CCK TX path by 0xa07[7] */
+ odm_set_bb_reg(dm, 0x80c, BIT(30), 0x1);
+
+ /* TX logic map and TX path en for Nsts = 1, and CCK TX path*/
+ if (tx_path & ODM_RF_A) {
+ odm_set_bb_reg(dm, 0x93c, 0xfff00000, 0x001);
+ odm_set_bb_reg(dm, 0xa04, 0xf0000000, 0x8);
+ } else if (tx_path & ODM_RF_B) {
+ odm_set_bb_reg(dm, 0x93c, 0xfff00000, 0x002);
+ odm_set_bb_reg(dm, 0xa04, 0xf0000000, 0x4);
+ }
+
+ /* TX logic map and TX path en for Nsts = 2*/
+ if ((tx_path == ODM_RF_A) || (tx_path == ODM_RF_B))
+ odm_set_bb_reg(dm, 0x940, 0xfff0, 0x01);
+ else
+ odm_set_bb_reg(dm, 0x940, 0xfff0, 0x43);
+
+ /* TX path enable */
+ odm_set_bb_reg(dm, 0x80c, MASKBYTE0, ((tx_path << 4) | tx_path));
+
+ /* Tx2path for 1ss */
+ if (!((tx_path == ODM_RF_A) || (tx_path == ODM_RF_B))) {
+ if (is_tx2_path || dm->mp_mode) {
+ /* 2Tx for OFDM */
+ odm_set_bb_reg(dm, 0x93c, 0xfff00000, 0x043);
+
+ /* 2Tx for CCK */
+ odm_set_bb_reg(dm, 0xa04, 0xf0000000, 0xc);
+ }
+ }
+
+ /* Always disable MRC for CCK CCA */
+ odm_set_bb_reg(dm, 0xa2c, BIT(22), 0x0);
+
+ /* Always disable MRC for CCK barker */
+ odm_set_bb_reg(dm, 0xa2c, BIT(18), 0x0);
+
+ /* CCK RX 1st and 2nd path setting*/
+ if (rx_path & ODM_RF_A)
+ odm_set_bb_reg(dm, 0xa04, 0x0f000000, 0x0);
+ else if (rx_path & ODM_RF_B)
+ odm_set_bb_reg(dm, 0xa04, 0x0f000000, 0x5);
+
+ /* RX path enable */
+ odm_set_bb_reg(dm, 0x808, MASKBYTE0, ((rx_path << 4) | rx_path));
+
+ if ((rx_path == ODM_RF_A) || (rx_path == ODM_RF_B)) {
+ /* 1R */
+
+ /* Disable MRC for CCA */
+ /* odm_set_bb_reg(dm, 0xa2c, BIT22, 0x0); */
+
+ /* Disable MRC for barker */
+ /* odm_set_bb_reg(dm, 0xa2c, BIT18, 0x0); */
+
+ /* Disable CCK antenna diversity */
+ /* odm_set_bb_reg(dm, 0xa00, BIT15, 0x0); */
+
+ /* Disable Antenna weighting */
+ odm_set_bb_reg(dm, 0x1904, BIT(16), 0x0);
+ odm_set_bb_reg(dm, 0x800, BIT(28), 0x0);
+ odm_set_bb_reg(dm, 0x850, BIT(23), 0x0);
+ } else {
+ /* 2R */
+
+ /* Enable MRC for CCA */
+ /* odm_set_bb_reg(dm, 0xa2c, BIT22, 0x1); */
+
+ /* Enable MRC for barker */
+ /* odm_set_bb_reg(dm, 0xa2c, BIT18, 0x1); */
+
+ /* Disable CCK antenna diversity */
+ /* odm_set_bb_reg(dm, 0xa00, BIT15, 0x0); */
+
+ /* Enable Antenna weighting */
+ odm_set_bb_reg(dm, 0x1904, BIT(16), 0x1);
+ odm_set_bb_reg(dm, 0x800, BIT(28), 0x1);
+ odm_set_bb_reg(dm, 0x850, BIT(23), 0x1);
+ }
+
+ /* Update TXRX antenna status for PHYDM */
+ dm->tx_ant_status = (tx_path & 0x3);
+ dm->rx_ant_status = (rx_path & 0x3);
+
+ /* MP driver need to support path-B TX\RX */
+
+ while (1) {
+ counter++;
+ rf_reg_status =
+ rf_reg_status & config_phydm_write_rf_reg_8822b(
+ dm, ODM_RF_PATH_A, 0xef,
+ RFREGOFFSETMASK, 0x80000);
+ rf_reg_status =
+ rf_reg_status & config_phydm_write_rf_reg_8822b(
+ dm, ODM_RF_PATH_A, 0x33,
+ RFREGOFFSETMASK, 0x00001);
+
+ ODM_delay_us(2);
+ rf_reg33 = config_phydm_read_rf_reg_8822b(
+ dm, ODM_RF_PATH_A, 0x33, RFREGOFFSETMASK);
+
+ if ((rf_reg33 == 0x00001) &&
+ (config_phydm_read_rf_check_8822b(rf_reg33)))
+ break;
+ else if (counter == 100) {
+ ODM_RT_TRACE(
+ dm, ODM_PHY_CONFIG,
+ "%s(): Fail to set TRx mode setting, because writing RF mode table is fail\n",
+ __func__);
+ return false;
+ }
+ }
+
+ if ((dm->mp_mode) || *dm->antenna_test || (dm->normal_rx_path)) {
+ /* 0xef 0x80000 0x33 0x00001 0x3e 0x00034 0x3f 0x4080e
+ * 0xef 0x00000 suggested by Lucas
+ */
+ rf_reg_status =
+ rf_reg_status & config_phydm_write_rf_reg_8822b(
+ dm, ODM_RF_PATH_A, 0xef,
+ RFREGOFFSETMASK, 0x80000);
+ rf_reg_status =
+ rf_reg_status & config_phydm_write_rf_reg_8822b(
+ dm, ODM_RF_PATH_A, 0x33,
+ RFREGOFFSETMASK, 0x00001);
+ rf_reg_status =
+ rf_reg_status & config_phydm_write_rf_reg_8822b(
+ dm, ODM_RF_PATH_A, 0x3e,
+ RFREGOFFSETMASK, 0x00034);
+ rf_reg_status =
+ rf_reg_status & config_phydm_write_rf_reg_8822b(
+ dm, ODM_RF_PATH_A, 0x3f,
+ RFREGOFFSETMASK, 0x4080e);
+ rf_reg_status =
+ rf_reg_status & config_phydm_write_rf_reg_8822b(
+ dm, ODM_RF_PATH_A, 0xef,
+ RFREGOFFSETMASK, 0x00000);
+ ODM_RT_TRACE(
+ dm, ODM_PHY_CONFIG,
+ "%s(): MP mode or Antenna test mode!! support path-B TX and RX\n",
+ __func__);
+ } else {
+ /* 0xef 0x80000 0x33 0x00001 0x3e 0x00034 0x3f 0x4080c
+ * 0xef 0x00000
+ */
+ rf_reg_status =
+ rf_reg_status & config_phydm_write_rf_reg_8822b(
+ dm, ODM_RF_PATH_A, 0xef,
+ RFREGOFFSETMASK, 0x80000);
+ rf_reg_status =
+ rf_reg_status & config_phydm_write_rf_reg_8822b(
+ dm, ODM_RF_PATH_A, 0x33,
+ RFREGOFFSETMASK, 0x00001);
+ rf_reg_status =
+ rf_reg_status & config_phydm_write_rf_reg_8822b(
+ dm, ODM_RF_PATH_A, 0x3e,
+ RFREGOFFSETMASK, 0x00034);
+ rf_reg_status =
+ rf_reg_status & config_phydm_write_rf_reg_8822b(
+ dm, ODM_RF_PATH_A, 0x3f,
+ RFREGOFFSETMASK, 0x4080c);
+ rf_reg_status =
+ rf_reg_status & config_phydm_write_rf_reg_8822b(
+ dm, ODM_RF_PATH_A, 0xef,
+ RFREGOFFSETMASK, 0x00000);
+ ODM_RT_TRACE(
+ dm, ODM_PHY_CONFIG,
+ "%s(): Normal mode!! Do not support path-B TX and RX\n",
+ __func__);
+ }
+
+ rf_reg_status = rf_reg_status & config_phydm_write_rf_reg_8822b(
+ dm, ODM_RF_PATH_A, 0xef,
+ RFREGOFFSETMASK, 0x00000);
+
+ if (!rf_reg_status) {
+ ODM_RT_TRACE(
+ dm, ODM_PHY_CONFIG,
+ "%s(): Fail to set TRx mode setting (TX: 0x%x, RX: 0x%x), because writing RF register is fail\n",
+ __func__, tx_path, rx_path);
+ return false;
+ }
+
+ /* Toggle IGI to let RF enter RX mode,
+ * because BB doesn't send 3-wire command when RX path is enable
+ */
+ IGI = (u8)odm_get_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm));
+ odm_write_dig(dm, IGI - 2);
+ odm_write_dig(dm, IGI);
+
+ /* Modify CCA parameters */
+ phydm_ccapar_by_rxpath_8822b(dm);
+ phydm_ccapar_by_rfe_8822b(dm);
+ phydm_rfe_8822b(dm, central_ch_8822b);
+
+ ODM_RT_TRACE(
+ dm, ODM_PHY_CONFIG,
+ "%s(): Success to set TRx mode setting (TX: 0x%x, RX: 0x%x)\n",
+ __func__, tx_path, rx_path);
+ return true;
+}
+
+bool config_phydm_parameter_init(struct phy_dm_struct *dm,
+ enum odm_parameter_init type)
+{
+ if (type == ODM_PRE_SETTING) {
+ odm_set_bb_reg(dm, 0x808, (BIT(28) | BIT(29)), 0x0);
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): Pre setting: disable OFDM and CCK block\n",
+ __func__);
+ } else if (type == ODM_POST_SETTING) {
+ odm_set_bb_reg(dm, 0x808, (BIT(28) | BIT(29)), 0x3);
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG,
+ "%s(): Post setting: enable OFDM and CCK block\n",
+ __func__);
+ reg82c_8822b = odm_get_bb_reg(dm, 0x82c, MASKDWORD);
+ reg838_8822b = odm_get_bb_reg(dm, 0x838, MASKDWORD);
+ reg830_8822b = odm_get_bb_reg(dm, 0x830, MASKDWORD);
+ reg83c_8822b = odm_get_bb_reg(dm, 0x83c, MASKDWORD);
+ rega20_8822b = odm_get_bb_reg(dm, 0xa20, MASKDWORD);
+ rega24_8822b = odm_get_bb_reg(dm, 0xa24, MASKDWORD);
+ rega28_8822b = odm_get_bb_reg(dm, 0xa28, MASKDWORD);
+ } else {
+ ODM_RT_TRACE(dm, ODM_PHY_CONFIG, "%s(): Wrong type!!\n",
+ __func__);
+ return false;
+ }
+
+ return true;
+}
+
+/* ======================================================================== */
diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_hal_api8822b.h b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_hal_api8822b.h
new file mode 100644
index 0000000..279ef06
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_hal_api8822b.h
@@ -0,0 +1,84 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __INC_PHYDM_API_H_8822B__
+#define __INC_PHYDM_API_H_8822B__
+
+/*2016.08.01 (HW user guide version: R27, SW user guide version: R05,
+ * Modification: R31)
+ */
+#define PHY_CONFIG_VERSION_8822B "27.5.31"
+
+#define INVALID_RF_DATA 0xffffffff
+#define INVALID_TXAGC_DATA 0xff
+
+#define config_phydm_read_rf_check_8822b(data) (data != INVALID_RF_DATA)
+#define config_phydm_read_txagc_check_8822b(data) (data != INVALID_TXAGC_DATA)
+
+u32 config_phydm_read_rf_reg_8822b(struct phy_dm_struct *dm,
+ enum odm_rf_radio_path rf_path, u32 reg_addr,
+ u32 bit_mask);
+
+bool config_phydm_write_rf_reg_8822b(struct phy_dm_struct *dm,
+ enum odm_rf_radio_path rf_path,
+ u32 reg_addr, u32 bit_mask, u32 data);
+
+bool config_phydm_write_txagc_8822b(struct phy_dm_struct *dm, u32 power_index,
+ enum odm_rf_radio_path path, u8 hw_rate);
+
+u8 config_phydm_read_txagc_8822b(struct phy_dm_struct *dm,
+ enum odm_rf_radio_path path, u8 hw_rate);
+
+bool config_phydm_switch_band_8822b(struct phy_dm_struct *dm, u8 central_ch);
+
+bool config_phydm_switch_channel_8822b(struct phy_dm_struct *dm, u8 central_ch);
+
+bool config_phydm_switch_bandwidth_8822b(struct phy_dm_struct *dm,
+ u8 primary_ch_idx,
+ enum odm_bw bandwidth);
+
+bool config_phydm_switch_channel_bw_8822b(struct phy_dm_struct *dm,
+ u8 central_ch, u8 primary_ch_idx,
+ enum odm_bw bandwidth);
+
+bool config_phydm_trx_mode_8822b(struct phy_dm_struct *dm,
+ enum odm_rf_path tx_path,
+ enum odm_rf_path rx_path, bool is_tx2_path);
+
+bool config_phydm_parameter_init(struct phy_dm_struct *dm,
+ enum odm_parameter_init type);
+
+/* ======================================================================== */
+/* These following functions can be used for PHY DM only*/
+
+bool phydm_write_txagc_1byte_8822b(struct phy_dm_struct *dm, u32 power_index,
+ enum odm_rf_radio_path path, u8 hw_rate);
+
+void phydm_init_hw_info_by_rfe_type_8822b(struct phy_dm_struct *dm);
+
+s32 phydm_get_condition_number_8822B(struct phy_dm_struct *dm);
+
+/* ======================================================================== */
+
+#endif /* __INC_PHYDM_API_H_8822B__ */
diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_iqk_8822b.c b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_iqk_8822b.c
new file mode 100644
index 0000000..d320311
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_iqk_8822b.c
@@ -0,0 +1,1410 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../mp_precomp.h"
+#include "../phydm_precomp.h"
+
+/*---------------------------Define Local Constant---------------------------*/
+
+static bool _iqk_rx_iqk_by_path_8822b(void *, u8);
+
+static inline void phydm_set_iqk_info(struct phy_dm_struct *dm,
+ struct dm_iqk_info *iqk_info, u8 status)
+{
+ bool KFAIL = true;
+
+ while (1) {
+ KFAIL = _iqk_rx_iqk_by_path_8822b(dm, ODM_RF_PATH_A);
+ if (status == 0)
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]S0RXK KFail = 0x%x\n", KFAIL);
+ else if (status == 1)
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]S1RXK KFail = 0x%x\n", KFAIL);
+ if (iqk_info->rxiqk_step == 5) {
+ dm->rf_calibrate_info.iqk_step++;
+ iqk_info->rxiqk_step = 1;
+ if (KFAIL && status == 0)
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]S0RXK fail code: %d!!!\n",
+ iqk_info->rxiqk_fail_code
+ [0][ODM_RF_PATH_A]);
+ else if (KFAIL && status == 1)
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]S1RXK fail code: %d!!!\n",
+ iqk_info->rxiqk_fail_code
+ [0][ODM_RF_PATH_A]);
+ break;
+ }
+ }
+
+ iqk_info->kcount++;
+}
+
+static inline void phydm_init_iqk_information(struct dm_iqk_info *iqk_info)
+{
+ u8 i, j, k, m;
+
+ for (i = 0; i < 2; i++) {
+ iqk_info->iqk_channel[i] = 0x0;
+
+ for (j = 0; j < SS_8822B; j++) {
+ iqk_info->lok_idac[i][j] = 0x0;
+ iqk_info->rxiqk_agc[i][j] = 0x0;
+ iqk_info->bypass_iqk[i][j] = 0x0;
+
+ for (k = 0; k < 2; k++) {
+ iqk_info->iqk_fail_report[i][j][k] = true;
+ for (m = 0; m < 8; m++) {
+ iqk_info->iqk_cfir_real[i][j][k][m] =
+ 0x0;
+ iqk_info->iqk_cfir_imag[i][j][k][m] =
+ 0x0;
+ }
+ }
+
+ for (k = 0; k < 3; k++)
+ iqk_info->retry_count[i][j][k] = 0x0;
+ }
+ }
+}
+
+static inline void phydm_backup_iqk_information(struct dm_iqk_info *iqk_info)
+{
+ u8 i, j, k;
+
+ iqk_info->iqk_channel[1] = iqk_info->iqk_channel[0];
+ for (i = 0; i < 2; i++) {
+ iqk_info->lok_idac[1][i] = iqk_info->lok_idac[0][i];
+ iqk_info->rxiqk_agc[1][i] = iqk_info->rxiqk_agc[0][i];
+ iqk_info->bypass_iqk[1][i] = iqk_info->bypass_iqk[0][i];
+ iqk_info->rxiqk_fail_code[1][i] =
+ iqk_info->rxiqk_fail_code[0][i];
+ for (j = 0; j < 2; j++) {
+ iqk_info->iqk_fail_report[1][i][j] =
+ iqk_info->iqk_fail_report[0][i][j];
+ for (k = 0; k < 8; k++) {
+ iqk_info->iqk_cfir_real[1][i][j][k] =
+ iqk_info->iqk_cfir_real[0][i][j][k];
+ iqk_info->iqk_cfir_imag[1][i][j][k] =
+ iqk_info->iqk_cfir_imag[0][i][j][k];
+ }
+ }
+ }
+
+ for (i = 0; i < 4; i++) {
+ iqk_info->rxiqk_fail_code[0][i] = 0x0;
+ iqk_info->rxiqk_agc[0][i] = 0x0;
+ for (j = 0; j < 2; j++) {
+ iqk_info->iqk_fail_report[0][i][j] = true;
+ iqk_info->gs_retry_count[0][i][j] = 0x0;
+ }
+ for (j = 0; j < 3; j++)
+ iqk_info->retry_count[0][i][j] = 0x0;
+ }
+}
+
+static inline void phydm_set_iqk_cfir(struct phy_dm_struct *dm,
+ struct dm_iqk_info *iqk_info, u8 path)
+{
+ u8 idx, i;
+ u32 tmp;
+
+ for (idx = 0; idx < 2; idx++) {
+ odm_set_bb_reg(dm, 0x1b00, MASKDWORD, 0xf8000008 | path << 1);
+
+ if (idx == 0)
+ odm_set_bb_reg(dm, 0x1b0c, BIT(13) | BIT(12), 0x3);
+ else
+ odm_set_bb_reg(dm, 0x1b0c, BIT(13) | BIT(12), 0x1);
+
+ odm_set_bb_reg(dm, 0x1bd4,
+ BIT(20) | BIT(19) | BIT(18) | BIT(17) | BIT(16),
+ 0x10);
+
+ for (i = 0; i < 8; i++) {
+ odm_set_bb_reg(dm, 0x1bd8, MASKDWORD,
+ 0xe0000001 + (i * 4));
+ tmp = odm_get_bb_reg(dm, 0x1bfc, MASKDWORD);
+ iqk_info->iqk_cfir_real[0][path][idx][i] =
+ (tmp & 0x0fff0000) >> 16;
+ iqk_info->iqk_cfir_imag[0][path][idx][i] = tmp & 0xfff;
+ }
+ }
+}
+
+static inline void phydm_get_read_counter(struct phy_dm_struct *dm)
+{
+ u32 counter = 0x0;
+
+ while (1) {
+ if (((odm_read_4byte(dm, 0x1bf0) >> 24) == 0x7f) ||
+ (counter > 300))
+ break;
+
+ counter++;
+ ODM_delay_ms(1);
+ }
+
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, "[IQK]counter = %d\n", counter);
+}
+
+/*---------------------------Define Local Constant---------------------------*/
+
+void do_iqk_8822b(void *dm_void, u8 delta_thermal_index, u8 thermal_value,
+ u8 threshold)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ odm_reset_iqk_result(dm);
+
+ dm->rf_calibrate_info.thermal_value_iqk = thermal_value;
+
+ phy_iq_calibrate_8822b(dm, true);
+}
+
+static void _iqk_fill_iqk_report_8822b(void *dm_void, u8 channel)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct dm_iqk_info *iqk_info = &dm->IQK_info;
+ u32 tmp1 = 0x0, tmp2 = 0x0, tmp3 = 0x0;
+ u8 i;
+
+ for (i = 0; i < SS_8822B; i++) {
+ tmp1 = tmp1 +
+ ((iqk_info->iqk_fail_report[channel][i][TX_IQK] & 0x1)
+ << i);
+ tmp2 = tmp2 +
+ ((iqk_info->iqk_fail_report[channel][i][RX_IQK] & 0x1)
+ << (i + 4));
+ tmp3 = tmp3 + ((iqk_info->rxiqk_fail_code[channel][i] & 0x3)
+ << (i * 2 + 8));
+ }
+ odm_write_4byte(dm, 0x1b00, 0xf8000008);
+ odm_set_bb_reg(dm, 0x1bf0, 0x0000ffff, tmp1 | tmp2 | tmp3);
+
+ for (i = 0; i < 2; i++)
+ odm_write_4byte(
+ dm, 0x1be8 + (i * 4),
+ (iqk_info->rxiqk_agc[channel][(i * 2) + 1] << 16) |
+ iqk_info->rxiqk_agc[channel][i * 2]);
+}
+
+static void _iqk_backup_mac_bb_8822b(struct phy_dm_struct *dm, u32 *MAC_backup,
+ u32 *BB_backup, u32 *backup_mac_reg,
+ u32 *backup_bb_reg)
+{
+ u32 i;
+
+ for (i = 0; i < MAC_REG_NUM_8822B; i++)
+ MAC_backup[i] = odm_read_4byte(dm, backup_mac_reg[i]);
+
+ for (i = 0; i < BB_REG_NUM_8822B; i++)
+ BB_backup[i] = odm_read_4byte(dm, backup_bb_reg[i]);
+}
+
+static void _iqk_backup_rf_8822b(struct phy_dm_struct *dm, u32 RF_backup[][2],
+ u32 *backup_rf_reg)
+{
+ u32 i;
+
+ for (i = 0; i < RF_REG_NUM_8822B; i++) {
+ RF_backup[i][ODM_RF_PATH_A] = odm_get_rf_reg(
+ dm, ODM_RF_PATH_A, backup_rf_reg[i], RFREGOFFSETMASK);
+ RF_backup[i][ODM_RF_PATH_B] = odm_get_rf_reg(
+ dm, ODM_RF_PATH_B, backup_rf_reg[i], RFREGOFFSETMASK);
+ }
+}
+
+static void _iqk_agc_bnd_int_8822b(struct phy_dm_struct *dm)
+{
+ /*initialize RX AGC bnd, it must do after bbreset*/
+ odm_write_4byte(dm, 0x1b00, 0xf8000008);
+ odm_write_4byte(dm, 0x1b00, 0xf80a7008);
+ odm_write_4byte(dm, 0x1b00, 0xf8015008);
+ odm_write_4byte(dm, 0x1b00, 0xf8000008);
+}
+
+static void _iqk_bb_reset_8822b(struct phy_dm_struct *dm)
+{
+ bool cca_ing = false;
+ u32 count = 0;
+
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x0, RFREGOFFSETMASK, 0x10000);
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x0, RFREGOFFSETMASK, 0x10000);
+
+ while (1) {
+ odm_write_4byte(dm, 0x8fc, 0x0);
+ odm_set_bb_reg(dm, 0x198c, 0x7, 0x7);
+ cca_ing = (bool)odm_get_bb_reg(dm, 0xfa0, BIT(3));
+
+ if (count > 30)
+ cca_ing = false;
+
+ if (cca_ing) {
+ ODM_delay_ms(1);
+ count++;
+ } else {
+ odm_write_1byte(dm, 0x808, 0x0); /*RX ant off*/
+ odm_set_bb_reg(dm, 0xa04,
+ BIT(27) | BIT(26) | BIT(25) | BIT(24),
+ 0x0); /*CCK RX path off*/
+
+ /*BBreset*/
+ odm_set_bb_reg(dm, 0x0, BIT(16), 0x0);
+ odm_set_bb_reg(dm, 0x0, BIT(16), 0x1);
+
+ if (odm_get_bb_reg(dm, 0x660, BIT(16)))
+ odm_write_4byte(dm, 0x6b4, 0x89000006);
+ break;
+ }
+ }
+}
+
+static void _iqk_afe_setting_8822b(struct phy_dm_struct *dm, bool do_iqk)
+{
+ if (do_iqk) {
+ odm_write_4byte(dm, 0xc60, 0x50000000);
+ odm_write_4byte(dm, 0xc60, 0x70070040);
+ odm_write_4byte(dm, 0xe60, 0x50000000);
+ odm_write_4byte(dm, 0xe60, 0x70070040);
+
+ odm_write_4byte(dm, 0xc58, 0xd8000402);
+ odm_write_4byte(dm, 0xc5c, 0xd1000120);
+ odm_write_4byte(dm, 0xc6c, 0x00000a15);
+ odm_write_4byte(dm, 0xe58, 0xd8000402);
+ odm_write_4byte(dm, 0xe5c, 0xd1000120);
+ odm_write_4byte(dm, 0xe6c, 0x00000a15);
+ _iqk_bb_reset_8822b(dm);
+ } else {
+ odm_write_4byte(dm, 0xc60, 0x50000000);
+ odm_write_4byte(dm, 0xc60, 0x70038040);
+ odm_write_4byte(dm, 0xe60, 0x50000000);
+ odm_write_4byte(dm, 0xe60, 0x70038040);
+
+ odm_write_4byte(dm, 0xc58, 0xd8020402);
+ odm_write_4byte(dm, 0xc5c, 0xde000120);
+ odm_write_4byte(dm, 0xc6c, 0x0000122a);
+ odm_write_4byte(dm, 0xe58, 0xd8020402);
+ odm_write_4byte(dm, 0xe5c, 0xde000120);
+ odm_write_4byte(dm, 0xe6c, 0x0000122a);
+ }
+}
+
+static void _iqk_restore_mac_bb_8822b(struct phy_dm_struct *dm, u32 *MAC_backup,
+ u32 *BB_backup, u32 *backup_mac_reg,
+ u32 *backup_bb_reg)
+{
+ u32 i;
+
+ for (i = 0; i < MAC_REG_NUM_8822B; i++)
+ odm_write_4byte(dm, backup_mac_reg[i], MAC_backup[i]);
+ for (i = 0; i < BB_REG_NUM_8822B; i++)
+ odm_write_4byte(dm, backup_bb_reg[i], BB_backup[i]);
+}
+
+static void _iqk_restore_rf_8822b(struct phy_dm_struct *dm, u32 *backup_rf_reg,
+ u32 RF_backup[][2])
+{
+ u32 i;
+
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, RFREGOFFSETMASK, 0x0);
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, RFREGOFFSETMASK, 0x0);
+ /*0xdf[4]=0*/
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xdf, RFREGOFFSETMASK,
+ RF_backup[0][ODM_RF_PATH_A] & (~BIT(4)));
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xdf, RFREGOFFSETMASK,
+ RF_backup[0][ODM_RF_PATH_B] & (~BIT(4)));
+
+ for (i = 1; i < RF_REG_NUM_8822B; i++) {
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, backup_rf_reg[i],
+ RFREGOFFSETMASK, RF_backup[i][ODM_RF_PATH_A]);
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, backup_rf_reg[i],
+ RFREGOFFSETMASK, RF_backup[i][ODM_RF_PATH_B]);
+ }
+}
+
+static void _iqk_backup_iqk_8822b(struct phy_dm_struct *dm, u8 step)
+{
+ struct dm_iqk_info *iqk_info = &dm->IQK_info;
+ u8 path;
+ u16 iqk_apply[2] = {0xc94, 0xe94};
+
+ if (step == 0x0) {
+ phydm_backup_iqk_information(iqk_info);
+ } else {
+ iqk_info->iqk_channel[0] = iqk_info->rf_reg18;
+ for (path = 0; path < 2; path++) {
+ iqk_info->lok_idac[0][path] =
+ odm_get_rf_reg(dm, (enum odm_rf_radio_path)path,
+ 0x58, RFREGOFFSETMASK);
+ iqk_info->bypass_iqk[0][path] =
+ odm_get_bb_reg(dm, iqk_apply[path], MASKDWORD);
+
+ phydm_set_iqk_cfir(dm, iqk_info, path);
+ odm_set_bb_reg(dm, 0x1bd8, MASKDWORD, 0x0);
+ odm_set_bb_reg(dm, 0x1b0c, BIT(13) | BIT(12), 0x0);
+ }
+ }
+}
+
+static void _iqk_reload_iqk_setting_8822b(
+ struct phy_dm_struct *dm, u8 channel,
+ u8 reload_idx /*1: reload TX, 2: reload LO, TX, RX*/
+ )
+{
+ struct dm_iqk_info *iqk_info = &dm->IQK_info;
+ u8 i, path, idx;
+ u16 iqk_apply[2] = {0xc94, 0xe94};
+
+ for (path = 0; path < 2; path++) {
+ if (reload_idx == 2) {
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xdf,
+ BIT(4), 0x1);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x58,
+ RFREGOFFSETMASK,
+ iqk_info->lok_idac[channel][path]);
+ }
+
+ for (idx = 0; idx < reload_idx; idx++) {
+ odm_set_bb_reg(dm, 0x1b00, MASKDWORD,
+ 0xf8000008 | path << 1);
+ odm_set_bb_reg(dm, 0x1b2c, MASKDWORD, 0x7);
+ odm_set_bb_reg(dm, 0x1b38, MASKDWORD, 0x20000000);
+ odm_set_bb_reg(dm, 0x1b3c, MASKDWORD, 0x20000000);
+ odm_set_bb_reg(dm, 0x1bcc, MASKDWORD, 0x00000000);
+
+ if (idx == 0)
+ odm_set_bb_reg(dm, 0x1b0c, BIT(13) | BIT(12),
+ 0x3);
+ else
+ odm_set_bb_reg(dm, 0x1b0c, BIT(13) | BIT(12),
+ 0x1);
+
+ odm_set_bb_reg(dm, 0x1bd4, BIT(20) | BIT(19) | BIT(18) |
+ BIT(17) | BIT(16),
+ 0x10);
+
+ for (i = 0; i < 8; i++) {
+ odm_write_4byte(
+ dm, 0x1bd8,
+ ((0xc0000000 >> idx) + 0x3) + (i * 4) +
+ (iqk_info->iqk_cfir_real
+ [channel][path][idx][i]
+ << 9));
+ odm_write_4byte(
+ dm, 0x1bd8,
+ ((0xc0000000 >> idx) + 0x1) + (i * 4) +
+ (iqk_info->iqk_cfir_imag
+ [channel][path][idx][i]
+ << 9));
+ }
+ }
+ odm_set_bb_reg(dm, iqk_apply[path], MASKDWORD,
+ iqk_info->bypass_iqk[channel][path]);
+
+ odm_set_bb_reg(dm, 0x1bd8, MASKDWORD, 0x0);
+ odm_set_bb_reg(dm, 0x1b0c, BIT(13) | BIT(12), 0x0);
+ }
+}
+
+static bool _iqk_reload_iqk_8822b(struct phy_dm_struct *dm, bool reset)
+{
+ struct dm_iqk_info *iqk_info = &dm->IQK_info;
+ u8 i;
+ bool reload = false;
+
+ if (reset) {
+ for (i = 0; i < 2; i++)
+ iqk_info->iqk_channel[i] = 0x0;
+ } else {
+ iqk_info->rf_reg18 = odm_get_rf_reg(dm, ODM_RF_PATH_A, 0x18,
+ RFREGOFFSETMASK);
+
+ for (i = 0; i < 2; i++) {
+ if (iqk_info->rf_reg18 == iqk_info->iqk_channel[i]) {
+ _iqk_reload_iqk_setting_8822b(dm, i, 2);
+ _iqk_fill_iqk_report_8822b(dm, i);
+ ODM_RT_TRACE(
+ dm, ODM_COMP_CALIBRATION,
+ "[IQK]reload IQK result before!!!!\n");
+ reload = true;
+ }
+ }
+ }
+ return reload;
+}
+
+static void _iqk_rfe_setting_8822b(struct phy_dm_struct *dm, bool ext_pa_on)
+{
+ if (ext_pa_on) {
+ /*RFE setting*/
+ odm_write_4byte(dm, 0xcb0, 0x77777777);
+ odm_write_4byte(dm, 0xcb4, 0x00007777);
+ odm_write_4byte(dm, 0xcbc, 0x0000083B);
+ odm_write_4byte(dm, 0xeb0, 0x77777777);
+ odm_write_4byte(dm, 0xeb4, 0x00007777);
+ odm_write_4byte(dm, 0xebc, 0x0000083B);
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]external PA on!!!!\n");
+ } else {
+ /*RFE setting*/
+ odm_write_4byte(dm, 0xcb0, 0x77777777);
+ odm_write_4byte(dm, 0xcb4, 0x00007777);
+ odm_write_4byte(dm, 0xcbc, 0x00000100);
+ odm_write_4byte(dm, 0xeb0, 0x77777777);
+ odm_write_4byte(dm, 0xeb4, 0x00007777);
+ odm_write_4byte(dm, 0xebc, 0x00000100);
+ }
+}
+
+static void _iqk_rf_setting_8822b(struct phy_dm_struct *dm)
+{
+ u8 path;
+ u32 tmp;
+
+ odm_write_4byte(dm, 0x1b00, 0xf8000008);
+ odm_write_4byte(dm, 0x1bb8, 0x00000000);
+
+ for (path = 0; path < 2; path++) {
+ /*0xdf:B11 = 1,B4 = 0, B1 = 1*/
+ tmp = odm_get_rf_reg(dm, (enum odm_rf_radio_path)path, 0xdf,
+ RFREGOFFSETMASK);
+ tmp = (tmp & (~BIT(4))) | BIT(1) | BIT(11);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xdf,
+ RFREGOFFSETMASK, tmp);
+
+ /*release 0x56 TXBB*/
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x65,
+ RFREGOFFSETMASK, 0x09000);
+
+ if (*dm->band_type == ODM_BAND_5G) {
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xef,
+ BIT(19), 0x1);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x33,
+ RFREGOFFSETMASK, 0x00026);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x3e,
+ RFREGOFFSETMASK, 0x00037);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x3f,
+ RFREGOFFSETMASK, 0xdefce);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xef,
+ BIT(19), 0x0);
+ } else {
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xef,
+ BIT(19), 0x1);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x33,
+ RFREGOFFSETMASK, 0x00026);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x3e,
+ RFREGOFFSETMASK, 0x00037);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x3f,
+ RFREGOFFSETMASK, 0x5efce);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xef,
+ BIT(19), 0x0);
+ }
+ }
+}
+
+static void _iqk_configure_macbb_8822b(struct phy_dm_struct *dm)
+{
+ /*MACBB register setting*/
+ odm_write_1byte(dm, 0x522, 0x7f);
+ odm_set_bb_reg(dm, 0x550, BIT(11) | BIT(3), 0x0);
+ odm_set_bb_reg(dm, 0x90c, BIT(15),
+ 0x1); /*0x90c[15]=1: dac_buf reset selection*/
+ odm_set_bb_reg(dm, 0x9a4, BIT(31),
+ 0x0); /*0x9a4[31]=0: Select da clock*/
+ /*0xc94[0]=1, 0xe94[0]=1: let tx through iqk*/
+ odm_set_bb_reg(dm, 0xc94, BIT(0), 0x1);
+ odm_set_bb_reg(dm, 0xe94, BIT(0), 0x1);
+ /* 3-wire off*/
+ odm_write_4byte(dm, 0xc00, 0x00000004);
+ odm_write_4byte(dm, 0xe00, 0x00000004);
+}
+
+static void _iqk_lok_setting_8822b(struct phy_dm_struct *dm, u8 path)
+{
+ odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1);
+ odm_write_4byte(dm, 0x1bcc, 0x9);
+ odm_write_1byte(dm, 0x1b23, 0x00);
+
+ switch (*dm->band_type) {
+ case ODM_BAND_2_4G:
+ odm_write_1byte(dm, 0x1b2b, 0x00);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56,
+ RFREGOFFSETMASK, 0x50df2);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f,
+ RFREGOFFSETMASK, 0xadc00);
+ /* WE_LUT_TX_LOK*/
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xef, BIT(4),
+ 0x1);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x33,
+ BIT(1) | BIT(0), 0x0);
+ break;
+ case ODM_BAND_5G:
+ odm_write_1byte(dm, 0x1b2b, 0x80);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56,
+ RFREGOFFSETMASK, 0x5086c);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f,
+ RFREGOFFSETMASK, 0xa9c00);
+ /* WE_LUT_TX_LOK*/
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xef, BIT(4),
+ 0x1);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x33,
+ BIT(1) | BIT(0), 0x1);
+ break;
+ }
+}
+
+static void _iqk_txk_setting_8822b(struct phy_dm_struct *dm, u8 path)
+{
+ odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1);
+ odm_write_4byte(dm, 0x1bcc, 0x9);
+ odm_write_4byte(dm, 0x1b20, 0x01440008);
+
+ if (path == 0x0)
+ odm_write_4byte(dm, 0x1b00, 0xf800000a);
+ else
+ odm_write_4byte(dm, 0x1b00, 0xf8000008);
+ odm_write_4byte(dm, 0x1bcc, 0x3f);
+
+ switch (*dm->band_type) {
+ case ODM_BAND_2_4G:
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56,
+ RFREGOFFSETMASK, 0x50df2);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f,
+ RFREGOFFSETMASK, 0xadc00);
+ odm_write_1byte(dm, 0x1b2b, 0x00);
+ break;
+ case ODM_BAND_5G:
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56,
+ RFREGOFFSETMASK, 0x500ef);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f,
+ RFREGOFFSETMASK, 0xa9c00);
+ odm_write_1byte(dm, 0x1b2b, 0x80);
+ break;
+ }
+}
+
+static void _iqk_rxk1_setting_8822b(struct phy_dm_struct *dm, u8 path)
+{
+ odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1);
+
+ switch (*dm->band_type) {
+ case ODM_BAND_2_4G:
+ odm_write_1byte(dm, 0x1bcc, 0x9);
+ odm_write_1byte(dm, 0x1b2b, 0x00);
+ odm_write_4byte(dm, 0x1b20, 0x01450008);
+ odm_write_4byte(dm, 0x1b24, 0x01460c88);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56,
+ RFREGOFFSETMASK, 0x510e0);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f,
+ RFREGOFFSETMASK, 0xacc00);
+ break;
+ case ODM_BAND_5G:
+ odm_write_1byte(dm, 0x1bcc, 0x09);
+ odm_write_1byte(dm, 0x1b2b, 0x80);
+ odm_write_4byte(dm, 0x1b20, 0x00850008);
+ odm_write_4byte(dm, 0x1b24, 0x00460048);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56,
+ RFREGOFFSETMASK, 0x510e0);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f,
+ RFREGOFFSETMASK, 0xadc00);
+ break;
+ }
+}
+
+static void _iqk_rxk2_setting_8822b(struct phy_dm_struct *dm, u8 path,
+ bool is_gs)
+{
+ struct dm_iqk_info *iqk_info = &dm->IQK_info;
+
+ odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1);
+
+ switch (*dm->band_type) {
+ case ODM_BAND_2_4G:
+ if (is_gs)
+ iqk_info->tmp1bcc = 0x12;
+ odm_write_1byte(dm, 0x1bcc, iqk_info->tmp1bcc);
+ odm_write_1byte(dm, 0x1b2b, 0x00);
+ odm_write_4byte(dm, 0x1b20, 0x01450008);
+ odm_write_4byte(dm, 0x1b24, 0x01460848);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56,
+ RFREGOFFSETMASK, 0x510e0);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f,
+ RFREGOFFSETMASK, 0xa9c00);
+ break;
+ case ODM_BAND_5G:
+ if (is_gs) {
+ if (path == ODM_RF_PATH_A)
+ iqk_info->tmp1bcc = 0x12;
+ else
+ iqk_info->tmp1bcc = 0x09;
+ }
+ odm_write_1byte(dm, 0x1bcc, iqk_info->tmp1bcc);
+ odm_write_1byte(dm, 0x1b2b, 0x80);
+ odm_write_4byte(dm, 0x1b20, 0x00850008);
+ odm_write_4byte(dm, 0x1b24, 0x00460848);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56,
+ RFREGOFFSETMASK, 0x51060);
+ odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f,
+ RFREGOFFSETMASK, 0xa9c00);
+ break;
+ }
+}
+
+static bool _iqk_check_cal_8822b(struct phy_dm_struct *dm, u32 IQK_CMD)
+{
+ bool notready = true, fail = true;
+ u32 delay_count = 0x0;
+
+ while (notready) {
+ if (odm_read_4byte(dm, 0x1b00) == (IQK_CMD & 0xffffff0f)) {
+ fail = (bool)odm_get_bb_reg(dm, 0x1b08, BIT(26));
+ notready = false;
+ } else {
+ ODM_delay_ms(1);
+ delay_count++;
+ }
+
+ if (delay_count >= 50) {
+ fail = true;
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]IQK timeout!!!\n");
+ break;
+ }
+ }
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, "[IQK]delay count = 0x%x!!!\n",
+ delay_count);
+ return fail;
+}
+
+static bool _iqk_rx_iqk_gain_search_fail_8822b(struct phy_dm_struct *dm,
+ u8 path, u8 step)
+{
+ struct dm_iqk_info *iqk_info = &dm->IQK_info;
+ bool fail = true;
+ u32 IQK_CMD = 0x0, rf_reg0, tmp, bb_idx;
+ u8 IQMUX[4] = {0x9, 0x12, 0x1b, 0x24};
+ u8 idx;
+
+ for (idx = 0; idx < 4; idx++)
+ if (iqk_info->tmp1bcc == IQMUX[idx])
+ break;
+
+ odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1);
+ odm_write_4byte(dm, 0x1bcc, iqk_info->tmp1bcc);
+
+ if (step == RXIQK1)
+ ODM_RT_TRACE(
+ dm, ODM_COMP_CALIBRATION,
+ "[IQK]============ S%d RXIQK GainSearch ============\n",
+ path);
+
+ if (step == RXIQK1)
+ IQK_CMD = 0xf8000208 | (1 << (path + 4));
+ else
+ IQK_CMD = 0xf8000308 | (1 << (path + 4));
+
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, "[IQK]S%d GS%d_Trigger = 0x%x\n",
+ path, step, IQK_CMD);
+
+ odm_write_4byte(dm, 0x1b00, IQK_CMD);
+ odm_write_4byte(dm, 0x1b00, IQK_CMD + 0x1);
+ ODM_delay_ms(GS_delay_8822B);
+ fail = _iqk_check_cal_8822b(dm, IQK_CMD);
+
+ if (step == RXIQK2) {
+ rf_reg0 = odm_get_rf_reg(dm, (enum odm_rf_radio_path)path, 0x0,
+ RFREGOFFSETMASK);
+ odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1);
+ ODM_RT_TRACE(
+ dm, ODM_COMP_CALIBRATION,
+ "[IQK]S%d ==> RF0x0 = 0x%x, tmp1bcc = 0x%x, idx = %d, 0x1b3c = 0x%x\n",
+ path, rf_reg0, iqk_info->tmp1bcc, idx,
+ odm_read_4byte(dm, 0x1b3c));
+ tmp = (rf_reg0 & 0x1fe0) >> 5;
+ iqk_info->lna_idx = tmp >> 5;
+ bb_idx = tmp & 0x1f;
+ if (bb_idx == 0x1) {
+ if (iqk_info->lna_idx != 0x0)
+ iqk_info->lna_idx--;
+ else if (idx != 3)
+ idx++;
+ else
+ iqk_info->isbnd = true;
+ fail = true;
+ } else if (bb_idx == 0xa) {
+ if (idx != 0)
+ idx--;
+ else if (iqk_info->lna_idx != 0x7)
+ iqk_info->lna_idx++;
+ else
+ iqk_info->isbnd = true;
+ fail = true;
+ } else {
+ fail = false;
+ }
+
+ if (iqk_info->isbnd)
+ fail = false;
+
+ iqk_info->tmp1bcc = IQMUX[idx];
+
+ if (fail) {
+ odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1);
+ odm_write_4byte(
+ dm, 0x1b24,
+ (odm_read_4byte(dm, 0x1b24) & 0xffffe3ff) |
+ (iqk_info->lna_idx << 10));
+ }
+ }
+
+ return fail;
+}
+
+static bool _lok_one_shot_8822b(void *dm_void, u8 path)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct dm_iqk_info *iqk_info = &dm->IQK_info;
+ u8 delay_count = 0;
+ bool LOK_notready = false;
+ u32 LOK_temp = 0;
+ u32 IQK_CMD = 0x0;
+
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]==========S%d LOK ==========\n", path);
+
+ IQK_CMD = 0xf8000008 | (1 << (4 + path));
+
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, "[IQK]LOK_Trigger = 0x%x\n",
+ IQK_CMD);
+
+ odm_write_4byte(dm, 0x1b00, IQK_CMD);
+ odm_write_4byte(dm, 0x1b00, IQK_CMD + 1);
+ /*LOK: CMD ID = 0 {0xf8000018, 0xf8000028}*/
+ /*LOK: CMD ID = 0 {0xf8000019, 0xf8000029}*/
+ ODM_delay_ms(LOK_delay_8822B);
+
+ delay_count = 0;
+ LOK_notready = true;
+
+ while (LOK_notready) {
+ if (odm_read_4byte(dm, 0x1b00) == (IQK_CMD & 0xffffff0f))
+ LOK_notready = false;
+ else
+ LOK_notready = true;
+
+ if (LOK_notready) {
+ ODM_delay_ms(1);
+ delay_count++;
+ }
+
+ if (delay_count >= 50) {
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]S%d LOK timeout!!!\n", path);
+ break;
+ }
+ }
+
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]S%d ==> delay_count = 0x%x\n", path, delay_count);
+ if (ODM_COMP_CALIBRATION) {
+ if (!LOK_notready) {
+ LOK_temp =
+ odm_get_rf_reg(dm, (enum odm_rf_radio_path)path,
+ 0x58, RFREGOFFSETMASK);
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]0x58 = 0x%x\n", LOK_temp);
+ } else {
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]==>S%d LOK Fail!!!\n", path);
+ }
+ }
+ iqk_info->lok_fail[path] = LOK_notready;
+ return LOK_notready;
+}
+
+static bool _iqk_one_shot_8822b(void *dm_void, u8 path, u8 idx)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct dm_iqk_info *iqk_info = &dm->IQK_info;
+ u8 delay_count = 0;
+ bool notready = true, fail = true;
+ u32 IQK_CMD = 0x0;
+ u16 iqk_apply[2] = {0xc94, 0xe94};
+
+ if (idx == TXIQK)
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]============ S%d WBTXIQK ============\n",
+ path);
+ else if (idx == RXIQK1)
+ ODM_RT_TRACE(
+ dm, ODM_COMP_CALIBRATION,
+ "[IQK]============ S%d WBRXIQK STEP1============\n",
+ path);
+ else
+ ODM_RT_TRACE(
+ dm, ODM_COMP_CALIBRATION,
+ "[IQK]============ S%d WBRXIQK STEP2============\n",
+ path);
+
+ if (idx == TXIQK) {
+ IQK_CMD = 0xf8000008 | ((*dm->band_width + 4) << 8) |
+ (1 << (path + 4));
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]TXK_Trigger = 0x%x\n", IQK_CMD);
+ /*{0xf8000418, 0xf800042a} ==> 20 WBTXK (CMD = 4)*/
+ /*{0xf8000518, 0xf800052a} ==> 40 WBTXK (CMD = 5)*/
+ /*{0xf8000618, 0xf800062a} ==> 80 WBTXK (CMD = 6)*/
+ } else if (idx == RXIQK1) {
+ if (*dm->band_width == 2)
+ IQK_CMD = 0xf8000808 | (1 << (path + 4));
+ else
+ IQK_CMD = 0xf8000708 | (1 << (path + 4));
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]RXK1_Trigger = 0x%x\n", IQK_CMD);
+ /*{0xf8000718, 0xf800072a} ==> 20 WBTXK (CMD = 7)*/
+ /*{0xf8000718, 0xf800072a} ==> 40 WBTXK (CMD = 7)*/
+ /*{0xf8000818, 0xf800082a} ==> 80 WBTXK (CMD = 8)*/
+ } else if (idx == RXIQK2) {
+ IQK_CMD = 0xf8000008 | ((*dm->band_width + 9) << 8) |
+ (1 << (path + 4));
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]RXK2_Trigger = 0x%x\n", IQK_CMD);
+ /*{0xf8000918, 0xf800092a} ==> 20 WBRXK (CMD = 9)*/
+ /*{0xf8000a18, 0xf8000a2a} ==> 40 WBRXK (CMD = 10)*/
+ /*{0xf8000b18, 0xf8000b2a} ==> 80 WBRXK (CMD = 11)*/
+ odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1);
+ odm_write_4byte(dm, 0x1b24,
+ (odm_read_4byte(dm, 0x1b24) & 0xffffe3ff) |
+ ((iqk_info->lna_idx & 0x7) << 10));
+ }
+ odm_write_4byte(dm, 0x1b00, IQK_CMD);
+ odm_write_4byte(dm, 0x1b00, IQK_CMD + 0x1);
+ ODM_delay_ms(WBIQK_delay_8822B);
+
+ while (notready) {
+ if (odm_read_4byte(dm, 0x1b00) == (IQK_CMD & 0xffffff0f))
+ notready = false;
+ else
+ notready = true;
+
+ if (notready) {
+ ODM_delay_ms(1);
+ delay_count++;
+ } else {
+ fail = (bool)odm_get_bb_reg(dm, 0x1b08, BIT(26));
+ break;
+ }
+
+ if (delay_count >= 50) {
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]S%d IQK timeout!!!\n", path);
+ break;
+ }
+ }
+
+ if (dm->debug_components & ODM_COMP_CALIBRATION) {
+ odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1);
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]S%d ==> 0x1b00 = 0x%x, 0x1b08 = 0x%x\n",
+ path, odm_read_4byte(dm, 0x1b00),
+ odm_read_4byte(dm, 0x1b08));
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]S%d ==> delay_count = 0x%x\n", path,
+ delay_count);
+ if (idx != TXIQK)
+ ODM_RT_TRACE(
+ dm, ODM_COMP_CALIBRATION,
+ "[IQK]S%d ==> RF0x0 = 0x%x, RF0x56 = 0x%x\n",
+ path,
+ odm_get_rf_reg(dm, (enum odm_rf_radio_path)path,
+ 0x0, RFREGOFFSETMASK),
+ odm_get_rf_reg(dm, (enum odm_rf_radio_path)path,
+ 0x56, RFREGOFFSETMASK));
+ }
+
+ odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1);
+
+ if (idx == TXIQK)
+ if (fail)
+ odm_set_bb_reg(dm, iqk_apply[path], BIT(0), 0x0);
+
+ if (idx == RXIQK2) {
+ iqk_info->rxiqk_agc[0][path] =
+ (u16)(((odm_get_rf_reg(dm, (enum odm_rf_radio_path)path,
+ 0x0, RFREGOFFSETMASK) >>
+ 5) &
+ 0xff) |
+ (iqk_info->tmp1bcc << 8));
+
+ odm_write_4byte(dm, 0x1b38, 0x20000000);
+
+ if (!fail)
+ odm_set_bb_reg(dm, iqk_apply[path], (BIT(11) | BIT(10)),
+ 0x1);
+ else
+ odm_set_bb_reg(dm, iqk_apply[path], (BIT(11) | BIT(10)),
+ 0x0);
+ }
+
+ if (idx == TXIQK)
+ iqk_info->iqk_fail_report[0][path][TXIQK] = fail;
+ else
+ iqk_info->iqk_fail_report[0][path][RXIQK] = fail;
+
+ return fail;
+}
+
+static bool _iqk_rx_iqk_by_path_8822b(void *dm_void, u8 path)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct dm_iqk_info *iqk_info = &dm->IQK_info;
+ bool KFAIL = true, gonext;
+
+ switch (iqk_info->rxiqk_step) {
+ case 1: /*gain search_RXK1*/
+ _iqk_rxk1_setting_8822b(dm, path);
+ gonext = false;
+ while (1) {
+ KFAIL = _iqk_rx_iqk_gain_search_fail_8822b(dm, path,
+ RXIQK1);
+ if (KFAIL &&
+ (iqk_info->gs_retry_count[0][path][GSRXK1] < 2))
+ iqk_info->gs_retry_count[0][path][GSRXK1]++;
+ else if (KFAIL) {
+ iqk_info->rxiqk_fail_code[0][path] = 0;
+ iqk_info->rxiqk_step = 5;
+ gonext = true;
+ } else {
+ iqk_info->rxiqk_step++;
+ gonext = true;
+ }
+ if (gonext)
+ break;
+ }
+ break;
+ case 2: /*gain search_RXK2*/
+ _iqk_rxk2_setting_8822b(dm, path, true);
+ iqk_info->isbnd = false;
+ while (1) {
+ KFAIL = _iqk_rx_iqk_gain_search_fail_8822b(dm, path,
+ RXIQK2);
+ if (KFAIL &&
+ (iqk_info->gs_retry_count[0][path][GSRXK2] <
+ rxiqk_gs_limit)) {
+ iqk_info->gs_retry_count[0][path][GSRXK2]++;
+ } else {
+ iqk_info->rxiqk_step++;
+ break;
+ }
+ }
+ break;
+ case 3: /*RXK1*/
+ _iqk_rxk1_setting_8822b(dm, path);
+ gonext = false;
+ while (1) {
+ KFAIL = _iqk_one_shot_8822b(dm, path, RXIQK1);
+ if (KFAIL &&
+ (iqk_info->retry_count[0][path][RXIQK1] < 2))
+ iqk_info->retry_count[0][path][RXIQK1]++;
+ else if (KFAIL) {
+ iqk_info->rxiqk_fail_code[0][path] = 1;
+ iqk_info->rxiqk_step = 5;
+ gonext = true;
+ } else {
+ iqk_info->rxiqk_step++;
+ gonext = true;
+ }
+ if (gonext)
+ break;
+ }
+ break;
+ case 4: /*RXK2*/
+ _iqk_rxk2_setting_8822b(dm, path, false);
+ gonext = false;
+ while (1) {
+ KFAIL = _iqk_one_shot_8822b(dm, path, RXIQK2);
+ if (KFAIL &&
+ (iqk_info->retry_count[0][path][RXIQK2] < 2))
+ iqk_info->retry_count[0][path][RXIQK2]++;
+ else if (KFAIL) {
+ iqk_info->rxiqk_fail_code[0][path] = 2;
+ iqk_info->rxiqk_step = 5;
+ gonext = true;
+ } else {
+ iqk_info->rxiqk_step++;
+ gonext = true;
+ }
+ if (gonext)
+ break;
+ }
+ break;
+ }
+ return KFAIL;
+}
+
+static void _iqk_iqk_by_path_8822b(void *dm_void, bool segment_iqk)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct dm_iqk_info *iqk_info = &dm->IQK_info;
+ bool KFAIL = true;
+ u8 i, kcount_limit;
+
+ if (*dm->band_width == 2)
+ kcount_limit = kcount_limit_80m;
+ else
+ kcount_limit = kcount_limit_others;
+
+ while (1) {
+ switch (dm->rf_calibrate_info.iqk_step) {
+ case 1: /*S0 LOK*/
+ _iqk_lok_setting_8822b(dm, ODM_RF_PATH_A);
+ _lok_one_shot_8822b(dm, ODM_RF_PATH_A);
+ dm->rf_calibrate_info.iqk_step++;
+ break;
+ case 2: /*S1 LOK*/
+ _iqk_lok_setting_8822b(dm, ODM_RF_PATH_B);
+ _lok_one_shot_8822b(dm, ODM_RF_PATH_B);
+ dm->rf_calibrate_info.iqk_step++;
+ break;
+ case 3: /*S0 TXIQK*/
+ _iqk_txk_setting_8822b(dm, ODM_RF_PATH_A);
+ KFAIL = _iqk_one_shot_8822b(dm, ODM_RF_PATH_A, TXIQK);
+ iqk_info->kcount++;
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]S0TXK KFail = 0x%x\n", KFAIL);
+
+ if (KFAIL &&
+ (iqk_info->retry_count[0][ODM_RF_PATH_A][TXIQK] <
+ 3))
+ iqk_info->retry_count[0][ODM_RF_PATH_A]
+ [TXIQK]++;
+ else
+ dm->rf_calibrate_info.iqk_step++;
+ break;
+ case 4: /*S1 TXIQK*/
+ _iqk_txk_setting_8822b(dm, ODM_RF_PATH_B);
+ KFAIL = _iqk_one_shot_8822b(dm, ODM_RF_PATH_B, TXIQK);
+ iqk_info->kcount++;
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]S1TXK KFail = 0x%x\n", KFAIL);
+ if (KFAIL &&
+ iqk_info->retry_count[0][ODM_RF_PATH_B][TXIQK] < 3)
+ iqk_info->retry_count[0][ODM_RF_PATH_B]
+ [TXIQK]++;
+ else
+ dm->rf_calibrate_info.iqk_step++;
+ break;
+ case 5: /*S0 RXIQK*/
+ phydm_set_iqk_info(dm, iqk_info, 0);
+ break;
+ case 6: /*S1 RXIQK*/
+ phydm_set_iqk_info(dm, iqk_info, 1);
+ break;
+ }
+
+ if (dm->rf_calibrate_info.iqk_step == 7) {
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]==========LOK summary ==========\n");
+ ODM_RT_TRACE(
+ dm, ODM_COMP_CALIBRATION,
+ "[IQK]PathA_LOK_notready = %d, PathB_LOK1_notready = %d\n",
+ iqk_info->lok_fail[ODM_RF_PATH_A],
+ iqk_info->lok_fail[ODM_RF_PATH_B]);
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]==========IQK summary ==========\n");
+ ODM_RT_TRACE(
+ dm, ODM_COMP_CALIBRATION,
+ "[IQK]PathA_TXIQK_fail = %d, PathB_TXIQK_fail = %d\n",
+ iqk_info->iqk_fail_report[0][ODM_RF_PATH_A]
+ [TXIQK],
+ iqk_info->iqk_fail_report[0][ODM_RF_PATH_B]
+ [TXIQK]);
+ ODM_RT_TRACE(
+ dm, ODM_COMP_CALIBRATION,
+ "[IQK]PathA_RXIQK_fail = %d, PathB_RXIQK_fail = %d\n",
+ iqk_info->iqk_fail_report[0][ODM_RF_PATH_A]
+ [RXIQK],
+ iqk_info->iqk_fail_report[0][ODM_RF_PATH_B]
+ [RXIQK]);
+ ODM_RT_TRACE(
+ dm, ODM_COMP_CALIBRATION,
+ "[IQK]PathA_TXIQK_retry = %d, PathB_TXIQK_retry = %d\n",
+ iqk_info->retry_count[0][ODM_RF_PATH_A][TXIQK],
+ iqk_info->retry_count[0][ODM_RF_PATH_B][TXIQK]);
+ ODM_RT_TRACE(
+ dm, ODM_COMP_CALIBRATION,
+ "[IQK]PathA_RXK1_retry = %d, PathA_RXK2_retry = %d, PathB_RXK1_retry = %d, PathB_RXK2_retry = %d\n",
+ iqk_info->retry_count[0][ODM_RF_PATH_A][RXIQK1],
+ iqk_info->retry_count[0][ODM_RF_PATH_A][RXIQK2],
+ iqk_info->retry_count[0][ODM_RF_PATH_B][RXIQK1],
+ iqk_info->retry_count[0][ODM_RF_PATH_B]
+ [RXIQK2]);
+ ODM_RT_TRACE(
+ dm, ODM_COMP_CALIBRATION,
+ "[IQK]PathA_GS1_retry = %d, PathA_GS2_retry = %d, PathB_GS1_retry = %d, PathB_GS2_retry = %d\n",
+ iqk_info->gs_retry_count[0][ODM_RF_PATH_A]
+ [GSRXK1],
+ iqk_info->gs_retry_count[0][ODM_RF_PATH_A]
+ [GSRXK2],
+ iqk_info->gs_retry_count[0][ODM_RF_PATH_B]
+ [GSRXK1],
+ iqk_info->gs_retry_count[0][ODM_RF_PATH_B]
+ [GSRXK2]);
+ for (i = 0; i < 2; i++) {
+ odm_write_4byte(dm, 0x1b00,
+ 0xf8000008 | i << 1);
+ odm_write_4byte(dm, 0x1b2c, 0x7);
+ odm_write_4byte(dm, 0x1bcc, 0x0);
+ }
+ break;
+ }
+
+ if (segment_iqk && (iqk_info->kcount == kcount_limit))
+ break;
+ }
+}
+
+static void _iqk_start_iqk_8822b(struct phy_dm_struct *dm, bool segment_iqk)
+{
+ u32 tmp;
+
+ /*GNT_WL = 1*/
+ tmp = odm_get_rf_reg(dm, ODM_RF_PATH_A, 0x1, RFREGOFFSETMASK);
+ tmp = tmp | BIT(5) | BIT(0);
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x1, RFREGOFFSETMASK, tmp);
+
+ tmp = odm_get_rf_reg(dm, ODM_RF_PATH_B, 0x1, RFREGOFFSETMASK);
+ tmp = tmp | BIT(5) | BIT(0);
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x1, RFREGOFFSETMASK, tmp);
+
+ _iqk_iqk_by_path_8822b(dm, segment_iqk);
+}
+
+static void _iq_calibrate_8822b_init(void *dm_void)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+ struct dm_iqk_info *iqk_info = &dm->IQK_info;
+ u8 i, j;
+
+ if (iqk_info->iqk_times == 0) {
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]=====>PHY_IQCalibrate_8822B_Init\n");
+
+ for (i = 0; i < SS_8822B; i++) {
+ for (j = 0; j < 2; j++) {
+ iqk_info->lok_fail[i] = true;
+ iqk_info->iqk_fail[j][i] = true;
+ iqk_info->iqc_matrix[j][i] = 0x20000000;
+ }
+ }
+
+ phydm_init_iqk_information(iqk_info);
+ }
+}
+
+static void _phy_iq_calibrate_8822b(struct phy_dm_struct *dm, bool reset)
+{
+ u32 MAC_backup[MAC_REG_NUM_8822B], BB_backup[BB_REG_NUM_8822B],
+ RF_backup[RF_REG_NUM_8822B][SS_8822B];
+ u32 backup_mac_reg[MAC_REG_NUM_8822B] = {0x520, 0x550};
+ u32 backup_bb_reg[BB_REG_NUM_8822B] = {
+ 0x808, 0x90c, 0xc00, 0xcb0, 0xcb4, 0xcbc, 0xe00,
+ 0xeb0, 0xeb4, 0xebc, 0x1990, 0x9a4, 0xa04};
+ u32 backup_rf_reg[RF_REG_NUM_8822B] = {0xdf, 0x8f, 0x65, 0x0, 0x1};
+ bool segment_iqk = false, is_mp = false;
+
+ struct dm_iqk_info *iqk_info = &dm->IQK_info;
+
+ if (dm->mp_mode)
+ is_mp = true;
+ else if (dm->is_linked)
+ segment_iqk = true;
+
+ if (!is_mp)
+ if (_iqk_reload_iqk_8822b(dm, reset))
+ return;
+
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]==========IQK strat!!!!!==========\n");
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_CALIBRATION,
+ "[IQK]band_type = %s, band_width = %d, ExtPA2G = %d, ext_pa_5g = %d\n",
+ (*dm->band_type == ODM_BAND_5G) ? "5G" : "2G", *dm->band_width,
+ dm->ext_pa, dm->ext_pa_5g);
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]Interface = %d, cut_version = %x\n",
+ dm->support_interface, dm->cut_version);
+
+ iqk_info->iqk_times++;
+
+ iqk_info->kcount = 0;
+ dm->rf_calibrate_info.iqk_total_progressing_time = 0;
+ dm->rf_calibrate_info.iqk_step = 1;
+ iqk_info->rxiqk_step = 1;
+
+ _iqk_backup_iqk_8822b(dm, 0);
+ _iqk_backup_mac_bb_8822b(dm, MAC_backup, BB_backup, backup_mac_reg,
+ backup_bb_reg);
+ _iqk_backup_rf_8822b(dm, RF_backup, backup_rf_reg);
+
+ while (1) {
+ if (!is_mp)
+ dm->rf_calibrate_info.iqk_start_time =
+ odm_get_current_time(dm);
+
+ _iqk_configure_macbb_8822b(dm);
+ _iqk_afe_setting_8822b(dm, true);
+ _iqk_rfe_setting_8822b(dm, false);
+ _iqk_agc_bnd_int_8822b(dm);
+ _iqk_rf_setting_8822b(dm);
+
+ _iqk_start_iqk_8822b(dm, segment_iqk);
+
+ _iqk_afe_setting_8822b(dm, false);
+ _iqk_restore_mac_bb_8822b(dm, MAC_backup, BB_backup,
+ backup_mac_reg, backup_bb_reg);
+ _iqk_restore_rf_8822b(dm, backup_rf_reg, RF_backup);
+
+ if (!is_mp) {
+ dm->rf_calibrate_info.iqk_progressing_time =
+ odm_get_progressing_time(
+ dm,
+ dm->rf_calibrate_info.iqk_start_time);
+ dm->rf_calibrate_info.iqk_total_progressing_time +=
+ odm_get_progressing_time(
+ dm,
+ dm->rf_calibrate_info.iqk_start_time);
+ ODM_RT_TRACE(
+ dm, ODM_COMP_CALIBRATION,
+ "[IQK]IQK progressing_time = %lld ms\n",
+ dm->rf_calibrate_info.iqk_progressing_time);
+ }
+
+ if (dm->rf_calibrate_info.iqk_step == 7)
+ break;
+
+ iqk_info->kcount = 0;
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, "[IQK]delay 50ms!!!\n");
+ ODM_delay_ms(50);
+ };
+
+ _iqk_backup_iqk_8822b(dm, 1);
+ _iqk_fill_iqk_report_8822b(dm, 0);
+
+ if (!is_mp)
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]Total IQK progressing_time = %lld ms\n",
+ dm->rf_calibrate_info.iqk_total_progressing_time);
+
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]==========IQK end!!!!!==========\n");
+}
+
+static void _phy_iq_calibrate_by_fw_8822b(void *dm_void, u8 clear) {}
+
+/*IQK version:v3.3, NCTL v0.6*/
+/*1.The new gainsearch method for RXIQK*/
+/*2.The new format of IQK report register: 0x1be8/0x1bec*/
+/*3. add the option of segment IQK*/
+void phy_iq_calibrate_8822b(void *dm_void, bool clear)
+{
+ struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
+
+ dm->iqk_fw_offload = 0;
+
+ /*FW IQK*/
+ if (dm->iqk_fw_offload) {
+ if (!dm->rf_calibrate_info.is_iqk_in_progress) {
+ odm_acquire_spin_lock(dm, RT_IQK_SPINLOCK);
+ dm->rf_calibrate_info.is_iqk_in_progress = true;
+ odm_release_spin_lock(dm, RT_IQK_SPINLOCK);
+
+ dm->rf_calibrate_info.iqk_start_time =
+ odm_get_current_time(dm);
+
+ odm_write_4byte(dm, 0x1b00, 0xf8000008);
+ odm_set_bb_reg(dm, 0x1bf0, 0xff000000, 0xff);
+ ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
+ "[IQK]0x1bf0 = 0x%x\n",
+ odm_read_4byte(dm, 0x1bf0));
+
+ _phy_iq_calibrate_by_fw_8822b(dm, clear);
+ phydm_get_read_counter(dm);
+
+ dm->rf_calibrate_info.iqk_progressing_time =
+ odm_get_progressing_time(
+ dm,
+ dm->rf_calibrate_info.iqk_start_time);
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_CALIBRATION,
+ "[IQK]IQK progressing_time = %lld ms\n",
+ dm->rf_calibrate_info.iqk_progressing_time);
+
+ odm_acquire_spin_lock(dm, RT_IQK_SPINLOCK);
+ dm->rf_calibrate_info.is_iqk_in_progress = false;
+ odm_release_spin_lock(dm, RT_IQK_SPINLOCK);
+ } else {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_CALIBRATION,
+ "== Return the IQK CMD, because the IQK in Progress ==\n");
+ }
+
+ } else {
+ _iq_calibrate_8822b_init(dm_void);
+
+ if (!dm->rf_calibrate_info.is_iqk_in_progress) {
+ odm_acquire_spin_lock(dm, RT_IQK_SPINLOCK);
+ dm->rf_calibrate_info.is_iqk_in_progress = true;
+ odm_release_spin_lock(dm, RT_IQK_SPINLOCK);
+ if (dm->mp_mode)
+ dm->rf_calibrate_info.iqk_start_time =
+ odm_get_current_time(dm);
+
+ _phy_iq_calibrate_8822b(dm, clear);
+ if (dm->mp_mode) {
+ dm->rf_calibrate_info.iqk_progressing_time =
+ odm_get_progressing_time(
+ dm, dm->rf_calibrate_info
+ .iqk_start_time);
+ ODM_RT_TRACE(
+ dm, ODM_COMP_CALIBRATION,
+ "[IQK]IQK progressing_time = %lld ms\n",
+ dm->rf_calibrate_info
+ .iqk_progressing_time);
+ }
+ odm_acquire_spin_lock(dm, RT_IQK_SPINLOCK);
+ dm->rf_calibrate_info.is_iqk_in_progress = false;
+ odm_release_spin_lock(dm, RT_IQK_SPINLOCK);
+ } else {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_CALIBRATION,
+ "[IQK]== Return the IQK CMD, because the IQK in Progress ==\n");
+ }
+ }
+}
diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_iqk_8822b.h b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_iqk_8822b.h
new file mode 100644
index 0000000..ea19deb
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_iqk_8822b.h
@@ -0,0 +1,48 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __PHYDM_IQK_8822B_H__
+#define __PHYDM_IQK_8822B_H__
+
+/*--------------------------Define Parameters-------------------------------*/
+#define MAC_REG_NUM_8822B 2
+#define BB_REG_NUM_8822B 13
+#define RF_REG_NUM_8822B 5
+
+#define LOK_delay_8822B 2
+#define GS_delay_8822B 2
+#define WBIQK_delay_8822B 2
+
+#define TXIQK 0
+#define RXIQK 1
+#define SS_8822B 2
+
+/*------------------------End Define Parameters-------------------------------*/
+
+void do_iqk_8822b(void *dm_void, u8 delta_thermal_index, u8 thermal_value,
+ u8 threshold);
+
+void phy_iq_calibrate_8822b(void *dm_void, bool clear);
+
+#endif /* #ifndef __PHYDM_IQK_8822B_H__*/
diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_regconfig8822b.c b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_regconfig8822b.c
new file mode 100644
index 0000000..644fca8
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_regconfig8822b.c
@@ -0,0 +1,168 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../mp_precomp.h"
+#include "../phydm_precomp.h"
+
+void odm_config_rf_reg_8822b(struct phy_dm_struct *dm, u32 addr, u32 data,
+ enum odm_rf_radio_path RF_PATH, u32 reg_addr)
+{
+ if (addr == 0xffe) {
+ ODM_sleep_ms(50);
+ } else if (addr == 0xfe) {
+ ODM_delay_us(100);
+ } else {
+ odm_set_rf_reg(dm, RF_PATH, reg_addr, RFREGOFFSETMASK, data);
+
+ /* Add 1us delay between BB/RF register setting. */
+ ODM_delay_us(1);
+ }
+}
+
+void odm_config_rf_radio_a_8822b(struct phy_dm_struct *dm, u32 addr, u32 data)
+{
+ u32 content = 0x1000; /* RF_Content: radioa_txt */
+ u32 maskfor_phy_set = (u32)(content & 0xE000);
+
+ odm_config_rf_reg_8822b(dm, addr, data, ODM_RF_PATH_A,
+ addr | maskfor_phy_set);
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_INIT,
+ "===> odm_config_rf_with_header_file: [RadioA] %08X %08X\n",
+ addr, data);
+}
+
+void odm_config_rf_radio_b_8822b(struct phy_dm_struct *dm, u32 addr, u32 data)
+{
+ u32 content = 0x1001; /* RF_Content: radiob_txt */
+ u32 maskfor_phy_set = (u32)(content & 0xE000);
+
+ odm_config_rf_reg_8822b(dm, addr, data, ODM_RF_PATH_B,
+ addr | maskfor_phy_set);
+
+ ODM_RT_TRACE(
+ dm, ODM_COMP_INIT,
+ "===> odm_config_rf_with_header_file: [RadioB] %08X %08X\n",
+ addr, data);
+}
+
+void odm_config_mac_8822b(struct phy_dm_struct *dm, u32 addr, u8 data)
+{
+ odm_write_1byte(dm, addr, data);
+ ODM_RT_TRACE(
+ dm, ODM_COMP_INIT,
+ "===> odm_config_mac_with_header_file: [MAC_REG] %08X %08X\n",
+ addr, data);
+}
+
+void odm_update_agc_big_jump_lmt_8822b(struct phy_dm_struct *dm, u32 addr,
+ u32 data)
+{
+ struct dig_thres *dig_tab = &dm->dm_dig_table;
+ u8 rf_gain_idx = (u8)((data & 0xFF000000) >> 24);
+ u8 bb_gain_idx = (u8)((data & 0x00ff0000) >> 16);
+ u8 agc_table_idx = (u8)((data & 0x00000f00) >> 8);
+ static bool is_limit;
+
+ if (addr != 0x81c)
+ return;
+
+ if (bb_gain_idx > 0x3c) {
+ if ((rf_gain_idx == dig_tab->rf_gain_idx) && !is_limit) {
+ is_limit = true;
+ dig_tab->big_jump_lmt[agc_table_idx] = bb_gain_idx - 2;
+ ODM_RT_TRACE(
+ dm, ODM_COMP_DIG,
+ "===> [AGC_TAB] big_jump_lmt [%d] = 0x%x\n",
+ agc_table_idx,
+ dig_tab->big_jump_lmt[agc_table_idx]);
+ }
+ } else {
+ is_limit = false;
+ }
+
+ dig_tab->rf_gain_idx = rf_gain_idx;
+}
+
+void odm_config_bb_agc_8822b(struct phy_dm_struct *dm, u32 addr, u32 bitmask,
+ u32 data)
+{
+ odm_update_agc_big_jump_lmt_8822b(dm, addr, data);
+
+ odm_set_bb_reg(dm, addr, bitmask, data);
+
+ /* Add 1us delay between BB/RF register setting. */
+ ODM_delay_us(1);
+
+ ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> %s: [AGC_TAB] %08X %08X\n",
+ __func__, addr, data);
+}
+
+void odm_config_bb_phy_reg_pg_8822b(struct phy_dm_struct *dm, u32 band,
+ u32 rf_path, u32 tx_num, u32 addr,
+ u32 bitmask, u32 data)
+{
+ if (addr == 0xfe || addr == 0xffe) {
+ ODM_sleep_ms(50);
+ } else {
+ phy_store_tx_power_by_rate(dm->adapter, band, rf_path, tx_num,
+ addr, bitmask, data);
+ }
+ ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> %s: [PHY_REG] %08X %08X %08X\n",
+ __func__, addr, bitmask, data);
+}
+
+void odm_config_bb_phy_8822b(struct phy_dm_struct *dm, u32 addr, u32 bitmask,
+ u32 data)
+{
+ if (addr == 0xfe)
+ ODM_sleep_ms(50);
+ else if (addr == 0xfd)
+ ODM_delay_ms(5);
+ else if (addr == 0xfc)
+ ODM_delay_ms(1);
+ else if (addr == 0xfb)
+ ODM_delay_us(50);
+ else if (addr == 0xfa)
+ ODM_delay_us(5);
+ else if (addr == 0xf9)
+ ODM_delay_us(1);
+ else
+ odm_set_bb_reg(dm, addr, bitmask, data);
+
+ /* Add 1us delay between BB/RF register setting. */
+ ODM_delay_us(1);
+ ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> %s: [PHY_REG] %08X %08X\n",
+ __func__, addr, data);
+}
+
+void odm_config_bb_txpwr_lmt_8822b(struct phy_dm_struct *dm, u8 *regulation,
+ u8 *band, u8 *bandwidth, u8 *rate_section,
+ u8 *rf_path, u8 *channel, u8 *power_limit)
+{
+ phy_set_tx_power_limit(dm, regulation, band, bandwidth, rate_section,
+ rf_path, channel, power_limit);
+}
diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_regconfig8822b.h b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_regconfig8822b.h
new file mode 100644
index 0000000..4817cf6
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_regconfig8822b.h
@@ -0,0 +1,54 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __INC_ODM_REGCONFIG_H_8822B
+#define __INC_ODM_REGCONFIG_H_8822B
+
+void odm_config_rf_reg_8822b(struct phy_dm_struct *dm, u32 addr, u32 data,
+ enum odm_rf_radio_path RF_PATH, u32 reg_addr);
+
+void odm_config_rf_radio_a_8822b(struct phy_dm_struct *dm, u32 addr, u32 data);
+
+void odm_config_rf_radio_b_8822b(struct phy_dm_struct *dm, u32 addr, u32 data);
+
+void odm_config_mac_8822b(struct phy_dm_struct *dm, u32 addr, u8 data);
+
+void odm_update_agc_big_jump_lmt_8822b(struct phy_dm_struct *dm, u32 addr,
+ u32 data);
+
+void odm_config_bb_agc_8822b(struct phy_dm_struct *dm, u32 addr, u32 bitmask,
+ u32 data);
+
+void odm_config_bb_phy_reg_pg_8822b(struct phy_dm_struct *dm, u32 band,
+ u32 rf_path, u32 tx_num, u32 addr,
+ u32 bitmask, u32 data);
+
+void odm_config_bb_phy_8822b(struct phy_dm_struct *dm, u32 addr, u32 bitmask,
+ u32 data);
+
+void odm_config_bb_txpwr_lmt_8822b(struct phy_dm_struct *dm, u8 *regulation,
+ u8 *band, u8 *bandwidth, u8 *rate_section,
+ u8 *rf_path, u8 *channel, u8 *power_limit);
+
+#endif /* RTL8822B_SUPPORT == 1*/
diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_rtl8822b.c b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_rtl8822b.c
new file mode 100644
index 0000000..59adabda
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_rtl8822b.c
@@ -0,0 +1,225 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../mp_precomp.h"
+#include "../phydm_precomp.h"
+
+static void phydm_dynamic_switch_htstf_mumimo_8822b(struct phy_dm_struct *dm)
+{
+ /*if rssi > 40dBm, enable HT-STF gain controller,
+ *otherwise, if rssi < 40dBm, disable the controller
+ */
+ /*add by Chun-Hung Ho 20160711 */
+ if (dm->rssi_min >= 40)
+ odm_set_bb_reg(dm, 0x8d8, BIT(17), 0x1);
+ else if (dm->rssi_min < 35)
+ odm_set_bb_reg(dm, 0x8d8, BIT(17), 0x0);
+
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON, "%s, rssi_min = %d\n", __func__,
+ dm->rssi_min);
+}
+
+static void _set_tx_a_cali_value(struct phy_dm_struct *dm, u8 rf_path,
+ u8 offset, u8 tx_a_bias_offset)
+{
+ u32 modi_tx_a_value = 0;
+ u8 tmp1_byte = 0;
+ bool is_minus = false;
+ u8 comp_value = 0;
+
+ switch (offset) {
+ case 0x0:
+ odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X10124);
+ break;
+ case 0x1:
+ odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X10524);
+ break;
+ case 0x2:
+ odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X10924);
+ break;
+ case 0x3:
+ odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X10D24);
+ break;
+ case 0x4:
+ odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X30164);
+ break;
+ case 0x5:
+ odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X30564);
+ break;
+ case 0x6:
+ odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X30964);
+ break;
+ case 0x7:
+ odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X30D64);
+ break;
+ case 0x8:
+ odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X50195);
+ break;
+ case 0x9:
+ odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X50595);
+ break;
+ case 0xa:
+ odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X50995);
+ break;
+ case 0xb:
+ odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X50D95);
+ break;
+ default:
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON,
+ "Invalid TxA band offset...\n");
+ return;
+ }
+
+ /* Get TxA value */
+ modi_tx_a_value = odm_get_rf_reg(dm, rf_path, 0x61, 0xFFFFF);
+ tmp1_byte = (u8)modi_tx_a_value & (BIT(3) | BIT(2) | BIT(1) | BIT(0));
+
+ /* check how much need to calibration */
+ switch (tx_a_bias_offset) {
+ case 0xF6:
+ is_minus = true;
+ comp_value = 3;
+ break;
+
+ case 0xF4:
+ is_minus = true;
+ comp_value = 2;
+ break;
+
+ case 0xF2:
+ is_minus = true;
+ comp_value = 1;
+ break;
+
+ case 0xF3:
+ is_minus = false;
+ comp_value = 1;
+ break;
+
+ case 0xF5:
+ is_minus = false;
+ comp_value = 2;
+ break;
+
+ case 0xF7:
+ is_minus = false;
+ comp_value = 3;
+ break;
+
+ case 0xF9:
+ is_minus = false;
+ comp_value = 4;
+ break;
+
+ /* do nothing case */
+ case 0xF0:
+ default:
+ ODM_RT_TRACE(dm, ODM_COMP_COMMON,
+ "No need to do TxA bias current calibration\n");
+ return;
+ }
+
+ /* calc correct value to calibrate */
+ if (is_minus) {
+ if (tmp1_byte >= comp_value) {
+ tmp1_byte -= comp_value;
+ /*modi_tx_a_value += tmp1_byte;*/
+ } else {
+ tmp1_byte = 0;
+ }
+ } else {
+ tmp1_byte += comp_value;
+ if (tmp1_byte >= 7)
+ tmp1_byte = 7;
+ }
+
+ /* Write back to RF reg */
+ odm_set_rf_reg(dm, rf_path, 0x30, 0xFFFF,
+ (offset << 12 | (modi_tx_a_value & 0xFF0) | tmp1_byte));
+}
+
+static void _txa_bias_cali_4_each_path(struct phy_dm_struct *dm, u8 rf_path,
+ u8 efuse_value)
+{
+ /* switch on set TxA bias */
+ odm_set_rf_reg(dm, rf_path, 0xEF, 0xFFFFF, 0x200);
+
+ /* Set 12 sets of TxA value */
+ _set_tx_a_cali_value(dm, rf_path, 0x0, efuse_value);
+ _set_tx_a_cali_value(dm, rf_path, 0x1, efuse_value);
+ _set_tx_a_cali_value(dm, rf_path, 0x2, efuse_value);
+ _set_tx_a_cali_value(dm, rf_path, 0x3, efuse_value);
+ _set_tx_a_cali_value(dm, rf_path, 0x4, efuse_value);
+ _set_tx_a_cali_value(dm, rf_path, 0x5, efuse_value);
+ _set_tx_a_cali_value(dm, rf_path, 0x6, efuse_value);
+ _set_tx_a_cali_value(dm, rf_path, 0x7, efuse_value);
+ _set_tx_a_cali_value(dm, rf_path, 0x8, efuse_value);
+ _set_tx_a_cali_value(dm, rf_path, 0x9, efuse_value);
+ _set_tx_a_cali_value(dm, rf_path, 0xa, efuse_value);
+ _set_tx_a_cali_value(dm, rf_path, 0xb, efuse_value);
+
+ /* switch off set TxA bias */
+ odm_set_rf_reg(dm, rf_path, 0xEF, 0xFFFFF, 0x0);
+}
+
+/*
+ * for 8822B PCIE D-cut patch only
+ * Normal driver and MP driver need this patch
+ */
+
+void phydm_txcurrentcalibration(struct phy_dm_struct *dm)
+{
+ u8 efuse0x3D8, efuse0x3D7;
+ u32 orig_rf0x18_path_a = 0, orig_rf0x18_path_b = 0;
+
+ /* save original 0x18 value */
+ orig_rf0x18_path_a = odm_get_rf_reg(dm, ODM_RF_PATH_A, 0x18, 0xFFFFF);
+ orig_rf0x18_path_b = odm_get_rf_reg(dm, ODM_RF_PATH_B, 0x18, 0xFFFFF);
+
+ /* define efuse content */
+ efuse0x3D8 = dm->efuse0x3d8;
+ efuse0x3D7 = dm->efuse0x3d7;
+
+ /* check efuse content to judge whether need to calibration or not */
+ if (efuse0x3D7 == 0xFF) {
+ ODM_RT_TRACE(
+ dm, ODM_COMP_COMMON,
+ "efuse content 0x3D7 == 0xFF, No need to do TxA cali\n");
+ return;
+ }
+
+ /* write RF register for calibration */
+ _txa_bias_cali_4_each_path(dm, ODM_RF_PATH_A, efuse0x3D7);
+ _txa_bias_cali_4_each_path(dm, ODM_RF_PATH_B, efuse0x3D8);
+
+ /* restore original 0x18 value */
+ odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x18, 0xFFFFF, orig_rf0x18_path_a);
+ odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x18, 0xFFFFF, orig_rf0x18_path_b);
+}
+
+void phydm_hwsetting_8822b(struct phy_dm_struct *dm)
+{
+ phydm_dynamic_switch_htstf_mumimo_8822b(dm);
+}
diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_rtl8822b.h b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_rtl8822b.h
new file mode 100644
index 0000000..af91a6f
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_rtl8822b.h
@@ -0,0 +1,30 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __ODM_RTL8822B_H__
+#define __ODM_RTL8822B_H__
+
+void phydm_hwsetting_8822b(struct phy_dm_struct *dm);
+
+#endif /* #define __ODM_RTL8822B_H__ */
diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/version_rtl8822b.h b/drivers/staging/rtlwifi/phydm/rtl8822b/version_rtl8822b.h
new file mode 100644
index 0000000..ad0d32f
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/rtl8822b/version_rtl8822b.h
@@ -0,0 +1,34 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+/*RTL8822B PHY Parameters*/
+/*
+ * [Caution]
+ * Since 01/Aug/2015, the commit rules will be simplified.
+ * You do not need to fill up the version.h anymore,
+ * only the maintenance supervisor fills it before formal release.
+ */
+#define RELEASE_DATE_8822B 20161103
+#define COMMIT_BY_8822B "BB_JOE"
+#define RELEASE_VERSION_8822B 67
diff --git a/drivers/staging/rtlwifi/phydm/rtl_phydm.c b/drivers/staging/rtlwifi/phydm/rtl_phydm.c
new file mode 100644
index 0000000..85e490d
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/rtl_phydm.c
@@ -0,0 +1,874 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+#include <linux/module.h>
+
+static int _rtl_phydm_init_com_info(struct rtl_priv *rtlpriv,
+ enum odm_ic_type ic_type,
+ struct rtl_phydm_params *params)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ struct rtl_mac *mac = rtl_mac(rtlpriv);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
+ u8 odm_board_type = ODM_BOARD_DEFAULT;
+ u32 support_ability;
+ int i;
+
+ dm->adapter = (void *)rtlpriv;
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_PLATFORM, ODM_CE);
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_IC_TYPE, ic_type);
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_INTERFACE, ODM_ITRF_PCIE);
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_MP_TEST_CHIP, params->mp_chip);
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_PATCH_ID, rtlhal->oem_id);
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_BWIFI_TEST, 1);
+
+ if (rtlphy->rf_type == RF_1T1R)
+ odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_1T1R);
+ else if (rtlphy->rf_type == RF_1T2R)
+ odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_1T2R);
+ else if (rtlphy->rf_type == RF_2T2R)
+ odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_2T2R);
+ else if (rtlphy->rf_type == RF_2T2R_GREEN)
+ odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_2T2R_GREEN);
+ else if (rtlphy->rf_type == RF_2T3R)
+ odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_2T3R);
+ else if (rtlphy->rf_type == RF_2T4R)
+ odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_2T4R);
+ else if (rtlphy->rf_type == RF_3T3R)
+ odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_3T3R);
+ else if (rtlphy->rf_type == RF_3T4R)
+ odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_3T4R);
+ else if (rtlphy->rf_type == RF_4T4R)
+ odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_4T4R);
+ else
+ odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_XTXR);
+
+ /* 1 ======= BoardType: ODM_CMNINFO_BOARD_TYPE ======= */
+ if (rtlhal->external_lna_2g != 0) {
+ odm_board_type |= ODM_BOARD_EXT_LNA;
+ odm_cmn_info_init(dm, ODM_CMNINFO_EXT_LNA, 1);
+ }
+ if (rtlhal->external_lna_5g != 0) {
+ odm_board_type |= ODM_BOARD_EXT_LNA_5G;
+ odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_LNA, 1);
+ }
+ if (rtlhal->external_pa_2g != 0) {
+ odm_board_type |= ODM_BOARD_EXT_PA;
+ odm_cmn_info_init(dm, ODM_CMNINFO_EXT_PA, 1);
+ }
+ if (rtlhal->external_pa_5g != 0) {
+ odm_board_type |= ODM_BOARD_EXT_PA_5G;
+ odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_PA, 1);
+ }
+ if (rtlpriv->cfg->ops->get_btc_status())
+ odm_board_type |= ODM_BOARD_BT;
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_BOARD_TYPE, odm_board_type);
+ /* 1 ============== End of BoardType ============== */
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_GPA, rtlhal->type_gpa);
+ odm_cmn_info_init(dm, ODM_CMNINFO_APA, rtlhal->type_apa);
+ odm_cmn_info_init(dm, ODM_CMNINFO_GLNA, rtlhal->type_glna);
+ odm_cmn_info_init(dm, ODM_CMNINFO_ALNA, rtlhal->type_alna);
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_RFE_TYPE, rtlhal->rfe_type);
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_EXT_TRSW, 0);
+
+ /*Add by YuChen for kfree init*/
+ odm_cmn_info_init(dm, ODM_CMNINFO_REGRFKFREEENABLE, 2);
+ odm_cmn_info_init(dm, ODM_CMNINFO_RFKFREEENABLE, 0);
+
+ /*Antenna diversity relative parameters*/
+ odm_cmn_info_hook(dm, ODM_CMNINFO_ANT_DIV,
+ &rtlefuse->antenna_div_cfg);
+ odm_cmn_info_init(dm, ODM_CMNINFO_RF_ANTENNA_TYPE,
+ rtlefuse->antenna_div_type);
+ odm_cmn_info_init(dm, ODM_CMNINFO_BE_FIX_TX_ANT, 0);
+ odm_cmn_info_init(dm, ODM_CMNINFO_WITH_EXT_ANTENNA_SWITCH, 0);
+
+ /* (8822B) efuse 0x3D7 & 0x3D8 for TX PA bias */
+ odm_cmn_info_init(dm, ODM_CMNINFO_EFUSE0X3D7, params->efuse0x3d7);
+ odm_cmn_info_init(dm, ODM_CMNINFO_EFUSE0X3D8, params->efuse0x3d8);
+
+ /*Add by YuChen for adaptivity init*/
+ odm_cmn_info_hook(dm, ODM_CMNINFO_ADAPTIVITY,
+ &rtlpriv->phydm.adaptivity_en);
+ phydm_adaptivity_info_init(dm, PHYDM_ADAPINFO_CARRIER_SENSE_ENABLE,
+ false);
+ phydm_adaptivity_info_init(dm, PHYDM_ADAPINFO_DCBACKOFF, 0);
+ phydm_adaptivity_info_init(dm, PHYDM_ADAPINFO_DYNAMICLINKADAPTIVITY,
+ false);
+ phydm_adaptivity_info_init(dm, PHYDM_ADAPINFO_TH_L2H_INI, 0);
+ phydm_adaptivity_info_init(dm, PHYDM_ADAPINFO_TH_EDCCA_HL_DIFF, 0);
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_IQKFWOFFLOAD, 0);
+
+ /* Pointer reference */
+ odm_cmn_info_hook(dm, ODM_CMNINFO_TX_UNI,
+ &rtlpriv->stats.txbytesunicast);
+ odm_cmn_info_hook(dm, ODM_CMNINFO_RX_UNI,
+ &rtlpriv->stats.rxbytesunicast);
+ odm_cmn_info_hook(dm, ODM_CMNINFO_BAND, &rtlhal->current_bandtype);
+ odm_cmn_info_hook(dm, ODM_CMNINFO_FORCED_RATE,
+ &rtlpriv->phydm.forced_data_rate);
+ odm_cmn_info_hook(dm, ODM_CMNINFO_FORCED_IGI_LB,
+ &rtlpriv->phydm.forced_igi_lb);
+
+ odm_cmn_info_hook(dm, ODM_CMNINFO_SEC_CHNL_OFFSET,
+ &mac->cur_40_prime_sc);
+ odm_cmn_info_hook(dm, ODM_CMNINFO_BW, &rtlphy->current_chan_bw);
+ odm_cmn_info_hook(dm, ODM_CMNINFO_CHNL, &rtlphy->current_channel);
+
+ odm_cmn_info_hook(dm, ODM_CMNINFO_SCAN, &mac->act_scanning);
+ odm_cmn_info_hook(dm, ODM_CMNINFO_POWER_SAVING,
+ &ppsc->dot11_psmode); /* may add new boolean flag */
+ /*Add by Yuchen for phydm beamforming*/
+ odm_cmn_info_hook(dm, ODM_CMNINFO_TX_TP,
+ &rtlpriv->stats.txbytesunicast_inperiod_tp);
+ odm_cmn_info_hook(dm, ODM_CMNINFO_RX_TP,
+ &rtlpriv->stats.rxbytesunicast_inperiod_tp);
+ odm_cmn_info_hook(dm, ODM_CMNINFO_ANT_TEST,
+ &rtlpriv->phydm.antenna_test);
+ for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++)
+ odm_cmn_info_ptr_array_hook(dm, ODM_CMNINFO_STA_STATUS, i,
+ NULL);
+
+ phydm_init_debug_setting(dm);
+
+ odm_cmn_info_init(dm, ODM_CMNINFO_FAB_VER, params->fab_ver);
+ odm_cmn_info_init(dm, ODM_CMNINFO_CUT_VER, params->cut_ver);
+
+ /* after ifup, ability is updated again */
+ support_ability = ODM_RF_CALIBRATION | ODM_RF_TX_PWR_TRACK;
+ odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY, support_ability);
+
+ return 0;
+}
+
+static int rtl_phydm_init_priv(struct rtl_priv *rtlpriv,
+ struct rtl_phydm_params *params)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+ enum odm_ic_type ic;
+
+ if (IS_HARDWARE_TYPE_8822B(rtlpriv))
+ ic = ODM_RTL8822B;
+ else
+ return 0;
+
+ rtlpriv->phydm.internal =
+ kzalloc(sizeof(struct phy_dm_struct), GFP_KERNEL);
+
+ _rtl_phydm_init_com_info(rtlpriv, ic, params);
+
+ odm_init_all_timers(dm);
+
+ return 1;
+}
+
+static int rtl_phydm_deinit_priv(struct rtl_priv *rtlpriv)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+
+ odm_cancel_all_timers(dm);
+
+ kfree(rtlpriv->phydm.internal);
+ rtlpriv->phydm.internal = NULL;
+
+ return 0;
+}
+
+static bool rtl_phydm_load_txpower_by_rate(struct rtl_priv *rtlpriv)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+ enum hal_status status;
+
+ status = odm_config_bb_with_header_file(dm, CONFIG_BB_PHY_REG_PG);
+ if (status != HAL_STATUS_SUCCESS)
+ return false;
+
+ return true;
+}
+
+static bool rtl_phydm_load_txpower_limit(struct rtl_priv *rtlpriv)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+ enum hal_status status;
+
+ if (IS_HARDWARE_TYPE_8822B(rtlpriv)) {
+ odm_read_and_config_mp_8822b_txpwr_lmt(dm);
+ } else {
+ status = odm_config_rf_with_header_file(dm, CONFIG_RF_TXPWR_LMT,
+ 0);
+ if (status != HAL_STATUS_SUCCESS)
+ return false;
+ }
+
+ return true;
+}
+
+static int rtl_phydm_init_dm(struct rtl_priv *rtlpriv)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+ u32 support_ability = 0;
+
+ /* clang-format off */
+ support_ability = 0
+ | ODM_BB_DIG
+ | ODM_BB_RA_MASK
+ | ODM_BB_DYNAMIC_TXPWR
+ | ODM_BB_FA_CNT
+ | ODM_BB_RSSI_MONITOR
+ | ODM_BB_CCK_PD
+ /* | ODM_BB_PWR_SAVE*/
+ | ODM_BB_CFO_TRACKING
+ | ODM_MAC_EDCA_TURBO
+ | ODM_RF_TX_PWR_TRACK
+ | ODM_RF_CALIBRATION
+ | ODM_BB_NHM_CNT
+ /* | ODM_BB_PWR_TRAIN*/
+ ;
+ /* clang-format on */
+
+ odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY, support_ability);
+
+ odm_dm_init(dm);
+
+ return 0;
+}
+
+static int rtl_phydm_deinit_dm(struct rtl_priv *rtlpriv)
+{
+ return 0;
+}
+
+static int rtl_phydm_reset_dm(struct rtl_priv *rtlpriv)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+
+ odm_dm_reset(dm);
+
+ return 0;
+}
+
+static bool rtl_phydm_parameter_init(struct rtl_priv *rtlpriv, bool post)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+
+ if (IS_HARDWARE_TYPE_8822B(rtlpriv))
+ return config_phydm_parameter_init(dm, post ? ODM_POST_SETTING :
+ ODM_PRE_SETTING);
+
+ return false;
+}
+
+static bool rtl_phydm_phy_bb_config(struct rtl_priv *rtlpriv)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+ enum hal_status status;
+
+ status = odm_config_bb_with_header_file(dm, CONFIG_BB_PHY_REG);
+ if (status != HAL_STATUS_SUCCESS)
+ return false;
+
+ status = odm_config_bb_with_header_file(dm, CONFIG_BB_AGC_TAB);
+ if (status != HAL_STATUS_SUCCESS)
+ return false;
+
+ return true;
+}
+
+static bool rtl_phydm_phy_rf_config(struct rtl_priv *rtlpriv)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ enum hal_status status;
+ enum odm_rf_radio_path rfpath;
+
+ for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
+ status = odm_config_rf_with_header_file(dm, CONFIG_RF_RADIO,
+ rfpath);
+ if (status != HAL_STATUS_SUCCESS)
+ return false;
+ }
+
+ status = odm_config_rf_with_tx_pwr_track_header_file(dm);
+ if (status != HAL_STATUS_SUCCESS)
+ return false;
+
+ return true;
+}
+
+static bool rtl_phydm_phy_mac_config(struct rtl_priv *rtlpriv)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+ enum hal_status status;
+
+ status = odm_config_mac_with_header_file(dm);
+ if (status != HAL_STATUS_SUCCESS)
+ return false;
+
+ return true;
+}
+
+static bool rtl_phydm_trx_mode(struct rtl_priv *rtlpriv,
+ enum radio_mask tx_path, enum radio_mask rx_path,
+ bool is_tx2_path)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+
+ if (IS_HARDWARE_TYPE_8822B(rtlpriv))
+ return config_phydm_trx_mode_8822b(dm,
+ (enum odm_rf_path)tx_path,
+ (enum odm_rf_path)rx_path,
+ is_tx2_path);
+
+ return false;
+}
+
+static bool rtl_phydm_watchdog(struct rtl_priv *rtlpriv)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+ struct rtl_mac *mac = rtl_mac(rtlpriv);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
+ bool fw_current_inpsmode = false;
+ bool fw_ps_awake = true;
+ u8 is_linked = false;
+ u8 bsta_state = false;
+ u8 is_bt_enabled = false;
+
+ /* check whether do watchdog */
+ rtlpriv->cfg->ops->get_hw_reg(rtlpriv->hw, HW_VAR_FW_PSMODE_STATUS,
+ (u8 *)(&fw_current_inpsmode));
+ rtlpriv->cfg->ops->get_hw_reg(rtlpriv->hw, HW_VAR_FWLPS_RF_ON,
+ (u8 *)(&fw_ps_awake));
+ if (ppsc->p2p_ps_info.p2p_ps_mode)
+ fw_ps_awake = false;
+
+ if ((ppsc->rfpwr_state == ERFON) &&
+ ((!fw_current_inpsmode) && fw_ps_awake) &&
+ (!ppsc->rfchange_inprogress))
+ ;
+ else
+ return false;
+
+ /* update common info before doing watchdog */
+ if (mac->link_state >= MAC80211_LINKED) {
+ is_linked = true;
+ if (mac->vif && mac->vif->type == NL80211_IFTYPE_STATION)
+ bsta_state = true;
+ }
+
+ if (rtlpriv->cfg->ops->get_btc_status())
+ is_bt_enabled = !rtlpriv->btcoexist.btc_ops->btc_is_bt_disabled(
+ rtlpriv);
+
+ odm_cmn_info_update(dm, ODM_CMNINFO_LINK, is_linked);
+ odm_cmn_info_update(dm, ODM_CMNINFO_STATION_STATE, bsta_state);
+ odm_cmn_info_update(dm, ODM_CMNINFO_BT_ENABLED, is_bt_enabled);
+
+ /* do watchdog */
+ odm_dm_watchdog(dm);
+
+ return true;
+}
+
+static bool rtl_phydm_switch_band(struct rtl_priv *rtlpriv, u8 central_ch)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+
+ if (IS_HARDWARE_TYPE_8822B(rtlpriv))
+ return config_phydm_switch_band_8822b(dm, central_ch);
+
+ return false;
+}
+
+static bool rtl_phydm_switch_channel(struct rtl_priv *rtlpriv, u8 central_ch)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+
+ if (IS_HARDWARE_TYPE_8822B(rtlpriv))
+ return config_phydm_switch_channel_8822b(dm, central_ch);
+
+ return false;
+}
+
+static bool rtl_phydm_switch_bandwidth(struct rtl_priv *rtlpriv,
+ u8 primary_ch_idx,
+ enum ht_channel_width bandwidth)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+ enum odm_bw odm_bw = (enum odm_bw)bandwidth;
+
+ if (IS_HARDWARE_TYPE_8822B(rtlpriv))
+ return config_phydm_switch_bandwidth_8822b(dm, primary_ch_idx,
+ odm_bw);
+
+ return false;
+}
+
+static bool rtl_phydm_iq_calibrate(struct rtl_priv *rtlpriv)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+
+ if (IS_HARDWARE_TYPE_8822B(rtlpriv))
+ phy_iq_calibrate_8822b(dm, false);
+ else
+ return false;
+
+ return true;
+}
+
+static bool rtl_phydm_clear_txpowertracking_state(struct rtl_priv *rtlpriv)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+
+ odm_clear_txpowertracking_state(dm);
+
+ return true;
+}
+
+static bool rtl_phydm_pause_dig(struct rtl_priv *rtlpriv, bool pause)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+
+ if (pause)
+ odm_pause_dig(dm, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_0, 0x1e);
+ else /* resume */
+ odm_pause_dig(dm, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_0, 0xff);
+
+ return true;
+}
+
+static u32 rtl_phydm_read_rf_reg(struct rtl_priv *rtlpriv,
+ enum radio_path rfpath, u32 addr, u32 mask)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+ enum odm_rf_radio_path odm_rfpath = (enum odm_rf_radio_path)rfpath;
+
+ if (IS_HARDWARE_TYPE_8822B(rtlpriv))
+ return config_phydm_read_rf_reg_8822b(dm, odm_rfpath, addr,
+ mask);
+
+ return -1;
+}
+
+static bool rtl_phydm_write_rf_reg(struct rtl_priv *rtlpriv,
+ enum radio_path rfpath, u32 addr, u32 mask,
+ u32 data)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+ enum odm_rf_radio_path odm_rfpath = (enum odm_rf_radio_path)rfpath;
+
+ if (IS_HARDWARE_TYPE_8822B(rtlpriv))
+ return config_phydm_write_rf_reg_8822b(dm, odm_rfpath, addr,
+ mask, data);
+
+ return false;
+}
+
+static u8 rtl_phydm_read_txagc(struct rtl_priv *rtlpriv, enum radio_path rfpath,
+ u8 hw_rate)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+ enum odm_rf_radio_path odm_rfpath = (enum odm_rf_radio_path)rfpath;
+
+ if (IS_HARDWARE_TYPE_8822B(rtlpriv))
+ return config_phydm_read_txagc_8822b(dm, odm_rfpath, hw_rate);
+
+ return -1;
+}
+
+static bool rtl_phydm_write_txagc(struct rtl_priv *rtlpriv, u32 power_index,
+ enum radio_path rfpath, u8 hw_rate)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+ enum odm_rf_radio_path odm_rfpath = (enum odm_rf_radio_path)rfpath;
+
+ if (IS_HARDWARE_TYPE_8822B(rtlpriv))
+ return config_phydm_write_txagc_8822b(dm, power_index,
+ odm_rfpath, hw_rate);
+
+ return false;
+}
+
+static bool rtl_phydm_c2h_content_parsing(struct rtl_priv *rtlpriv, u8 cmd_id,
+ u8 cmd_len, u8 *content)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+
+ if (phydm_c2H_content_parsing(dm, cmd_id, cmd_len, content))
+ return true;
+
+ return false;
+}
+
+static bool rtl_phydm_query_phy_status(struct rtl_priv *rtlpriv, u8 *phystrpt,
+ struct ieee80211_hdr *hdr,
+ struct rtl_stats *pstatus)
+{
+ /* NOTE: phystrpt may be NULL, and need to fill default value */
+
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
+ struct rtl_mac *mac = rtl_mac(rtlpriv);
+ struct dm_per_pkt_info pktinfo; /* input of pydm */
+ struct dm_phy_status_info phy_info; /* output of phydm */
+ __le16 fc = hdr->frame_control;
+
+ /* fill driver pstatus */
+ ether_addr_copy(pstatus->psaddr, ieee80211_get_SA(hdr));
+
+ /* fill pktinfo */
+ memset(&pktinfo, 0, sizeof(pktinfo));
+
+ pktinfo.data_rate = pstatus->rate;
+
+ if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION) {
+ pktinfo.station_id = 0;
+ } else {
+ /* TODO: use rtl_find_sta() to find ID */
+ pktinfo.station_id = 0xFF;
+ }
+
+ pktinfo.is_packet_match_bssid =
+ (!ieee80211_is_ctl(fc) &&
+ (ether_addr_equal(mac->bssid,
+ ieee80211_has_tods(fc) ?
+ hdr->addr1 :
+ ieee80211_has_fromds(fc) ?
+ hdr->addr2 :
+ hdr->addr3)) &&
+ (!pstatus->hwerror) && (!pstatus->crc) && (!pstatus->icv));
+ pktinfo.is_packet_to_self =
+ pktinfo.is_packet_match_bssid &&
+ (ether_addr_equal(hdr->addr1, rtlefuse->dev_addr));
+ pktinfo.is_to_self = (!pstatus->icv) && (!pstatus->crc) &&
+ (ether_addr_equal(hdr->addr1, rtlefuse->dev_addr));
+ pktinfo.is_packet_beacon = (ieee80211_is_beacon(fc) ? true : false);
+
+ /* query phy status */
+ if (phystrpt)
+ odm_phy_status_query(dm, &phy_info, phystrpt, &pktinfo);
+ else
+ memset(&phy_info, 0, sizeof(phy_info));
+
+ /* copy phy_info from phydm to driver */
+ pstatus->rx_pwdb_all = phy_info.rx_pwdb_all;
+ pstatus->bt_rx_rssi_percentage = phy_info.bt_rx_rssi_percentage;
+ pstatus->recvsignalpower = phy_info.recv_signal_power;
+ pstatus->signalquality = phy_info.signal_quality;
+ pstatus->rx_mimo_signalquality[0] = phy_info.rx_mimo_signal_quality[0];
+ pstatus->rx_mimo_signalquality[1] = phy_info.rx_mimo_signal_quality[1];
+ pstatus->rx_packet_bw =
+ phy_info.band_width; /* HT_CHANNEL_WIDTH_20 <- ODM_BW20M */
+
+ /* fill driver pstatus */
+ pstatus->packet_matchbssid = pktinfo.is_packet_match_bssid;
+ pstatus->packet_toself = pktinfo.is_packet_to_self;
+ pstatus->packet_beacon = pktinfo.is_packet_beacon;
+
+ return true;
+}
+
+static u8 rtl_phydm_rate_id_mapping(struct rtl_priv *rtlpriv,
+ enum wireless_mode wireless_mode,
+ enum rf_type rf_type,
+ enum ht_channel_width bw)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+
+ return phydm_rate_id_mapping(dm, wireless_mode, rf_type, bw);
+}
+
+static bool rtl_phydm_get_ra_bitmap(struct rtl_priv *rtlpriv,
+ enum wireless_mode wireless_mode,
+ enum rf_type rf_type,
+ enum ht_channel_width bw,
+ u8 tx_rate_level, /* 0~6 */
+ u32 *tx_bitmap_msb,
+ u32 *tx_bitmap_lsb)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+ const u8 mimo_ps_enable = 0;
+ const u8 disable_cck_rate = 0;
+
+ phydm_update_hal_ra_mask(dm, wireless_mode, rf_type, bw, mimo_ps_enable,
+ disable_cck_rate, tx_bitmap_msb, tx_bitmap_lsb,
+ tx_rate_level);
+
+ return true;
+}
+
+static u8 _rtl_phydm_get_macid(struct rtl_priv *rtlpriv,
+ struct ieee80211_sta *sta)
+{
+ struct rtl_mac *mac = rtl_mac(rtlpriv);
+
+ if (mac->opmode == NL80211_IFTYPE_STATION ||
+ mac->opmode == NL80211_IFTYPE_MESH_POINT) {
+ return 0;
+ } else if (mac->opmode == NL80211_IFTYPE_AP ||
+ mac->opmode == NL80211_IFTYPE_ADHOC)
+ return sta->aid + 1;
+
+ return 0;
+}
+
+static bool rtl_phydm_add_sta(struct rtl_priv *rtlpriv,
+ struct ieee80211_sta *sta)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+ struct rtl_sta_info *sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+ u8 mac_id = _rtl_phydm_get_macid(rtlpriv, sta);
+
+ odm_cmn_info_ptr_array_hook(dm, ODM_CMNINFO_STA_STATUS, mac_id,
+ sta_entry);
+
+ return true;
+}
+
+static bool rtl_phydm_del_sta(struct rtl_priv *rtlpriv,
+ struct ieee80211_sta *sta)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+ u8 mac_id = _rtl_phydm_get_macid(rtlpriv, sta);
+
+ odm_cmn_info_ptr_array_hook(dm, ODM_CMNINFO_STA_STATUS, mac_id, NULL);
+
+ return true;
+}
+
+static u32 rtl_phydm_get_version(struct rtl_priv *rtlpriv)
+{
+ u32 ver = 0;
+
+ if (IS_HARDWARE_TYPE_8822B(rtlpriv))
+ ver = RELEASE_VERSION_8822B;
+
+ return ver;
+}
+
+static bool rtl_phydm_modify_ra_pcr_threshold(struct rtl_priv *rtlpriv,
+ u8 ra_offset_direction,
+ u8 ra_threshold_offset)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+
+ phydm_modify_RA_PCR_threshold(dm, ra_offset_direction,
+ ra_threshold_offset);
+
+ return true;
+}
+
+static u32 rtl_phydm_query_counter(struct rtl_priv *rtlpriv,
+ const char *info_type)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+ static const struct query_entry {
+ const char *query_name;
+ enum phydm_info_query query_id;
+ } query_table[] = {
+#define QUERY_ENTRY(name) {#name, name}
+ QUERY_ENTRY(PHYDM_INFO_FA_OFDM),
+ QUERY_ENTRY(PHYDM_INFO_FA_CCK),
+ QUERY_ENTRY(PHYDM_INFO_CCA_OFDM),
+ QUERY_ENTRY(PHYDM_INFO_CCA_CCK),
+ QUERY_ENTRY(PHYDM_INFO_CRC32_OK_CCK),
+ QUERY_ENTRY(PHYDM_INFO_CRC32_OK_LEGACY),
+ QUERY_ENTRY(PHYDM_INFO_CRC32_OK_HT),
+ QUERY_ENTRY(PHYDM_INFO_CRC32_OK_VHT),
+ QUERY_ENTRY(PHYDM_INFO_CRC32_ERROR_CCK),
+ QUERY_ENTRY(PHYDM_INFO_CRC32_ERROR_LEGACY),
+ QUERY_ENTRY(PHYDM_INFO_CRC32_ERROR_HT),
+ QUERY_ENTRY(PHYDM_INFO_CRC32_ERROR_VHT),
+ };
+#define QUERY_TABLE_SIZE ARRAY_SIZE(query_table)
+
+ int i;
+ const struct query_entry *entry;
+
+ if (!strcmp(info_type, "IQK_TOTAL"))
+ return dm->n_iqk_cnt;
+
+ if (!strcmp(info_type, "IQK_OK"))
+ return dm->n_iqk_ok_cnt;
+
+ if (!strcmp(info_type, "IQK_FAIL"))
+ return dm->n_iqk_fail_cnt;
+
+ for (i = 0; i < QUERY_TABLE_SIZE; i++) {
+ entry = &query_table[i];
+
+ if (!strcmp(info_type, entry->query_name))
+ return phydm_cmn_info_query(dm, entry->query_id);
+ }
+
+ pr_err("Unrecognized info_type:%s!!!!:\n", info_type);
+
+ return 0xDEADDEAD;
+}
+
+static bool rtl_phydm_debug_cmd(struct rtl_priv *rtlpriv, char *in, u32 in_len,
+ char *out, u32 out_len)
+{
+ struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
+
+ phydm_cmd(dm, in, in_len, 1, out, out_len);
+
+ return true;
+}
+
+static struct rtl_phydm_ops rtl_phydm_operation = {
+ /* init/deinit priv */
+ .phydm_init_priv = rtl_phydm_init_priv,
+ .phydm_deinit_priv = rtl_phydm_deinit_priv,
+ .phydm_load_txpower_by_rate = rtl_phydm_load_txpower_by_rate,
+ .phydm_load_txpower_limit = rtl_phydm_load_txpower_limit,
+
+ /* init hw */
+ .phydm_init_dm = rtl_phydm_init_dm,
+ .phydm_deinit_dm = rtl_phydm_deinit_dm,
+ .phydm_reset_dm = rtl_phydm_reset_dm,
+ .phydm_parameter_init = rtl_phydm_parameter_init,
+ .phydm_phy_bb_config = rtl_phydm_phy_bb_config,
+ .phydm_phy_rf_config = rtl_phydm_phy_rf_config,
+ .phydm_phy_mac_config = rtl_phydm_phy_mac_config,
+ .phydm_trx_mode = rtl_phydm_trx_mode,
+
+ /* watchdog */
+ .phydm_watchdog = rtl_phydm_watchdog,
+
+ /* channel */
+ .phydm_switch_band = rtl_phydm_switch_band,
+ .phydm_switch_channel = rtl_phydm_switch_channel,
+ .phydm_switch_bandwidth = rtl_phydm_switch_bandwidth,
+ .phydm_iq_calibrate = rtl_phydm_iq_calibrate,
+ .phydm_clear_txpowertracking_state =
+ rtl_phydm_clear_txpowertracking_state,
+ .phydm_pause_dig = rtl_phydm_pause_dig,
+
+ /* read/write reg */
+ .phydm_read_rf_reg = rtl_phydm_read_rf_reg,
+ .phydm_write_rf_reg = rtl_phydm_write_rf_reg,
+ .phydm_read_txagc = rtl_phydm_read_txagc,
+ .phydm_write_txagc = rtl_phydm_write_txagc,
+
+ /* RX */
+ .phydm_c2h_content_parsing = rtl_phydm_c2h_content_parsing,
+ .phydm_query_phy_status = rtl_phydm_query_phy_status,
+
+ /* TX */
+ .phydm_rate_id_mapping = rtl_phydm_rate_id_mapping,
+ .phydm_get_ra_bitmap = rtl_phydm_get_ra_bitmap,
+
+ /* STA */
+ .phydm_add_sta = rtl_phydm_add_sta,
+ .phydm_del_sta = rtl_phydm_del_sta,
+
+ /* BTC */
+ .phydm_get_version = rtl_phydm_get_version,
+ .phydm_modify_ra_pcr_threshold = rtl_phydm_modify_ra_pcr_threshold,
+ .phydm_query_counter = rtl_phydm_query_counter,
+
+ /* debug */
+ .phydm_debug_cmd = rtl_phydm_debug_cmd,
+};
+
+struct rtl_phydm_ops *rtl_phydm_get_ops_pointer(void)
+{
+ return &rtl_phydm_operation;
+}
+EXPORT_SYMBOL(rtl_phydm_get_ops_pointer);
+
+/* ********************************************************
+ * Define phydm callout function in below
+ * ********************************************************
+ */
+
+u8 phy_get_tx_power_index(void *adapter, u8 rf_path, u8 rate,
+ enum ht_channel_width bandwidth, u8 channel)
+{
+ /* rate: DESC_RATE1M */
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)adapter;
+
+ return rtlpriv->cfg->ops->get_txpower_index(rtlpriv->hw, rf_path, rate,
+ bandwidth, channel);
+}
+
+void phy_set_tx_power_index_by_rs(void *adapter, u8 ch, u8 path, u8 rs)
+{
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)adapter;
+
+ return rtlpriv->cfg->ops->set_tx_power_index_by_rs(rtlpriv->hw, ch,
+ path, rs);
+}
+
+void phy_store_tx_power_by_rate(void *adapter, u32 band, u32 rfpath, u32 txnum,
+ u32 regaddr, u32 bitmask, u32 data)
+{
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)adapter;
+
+ rtlpriv->cfg->ops->store_tx_power_by_rate(
+ rtlpriv->hw, band, rfpath, txnum, regaddr, bitmask, data);
+}
+
+void phy_set_tx_power_limit(void *dm, u8 *regulation, u8 *band, u8 *bandwidth,
+ u8 *rate_section, u8 *rf_path, u8 *channel,
+ u8 *power_limit)
+{
+ struct rtl_priv *rtlpriv =
+ (struct rtl_priv *)((struct phy_dm_struct *)dm)->adapter;
+
+ rtlpriv->cfg->ops->phy_set_txpower_limit(rtlpriv->hw, regulation, band,
+ bandwidth, rate_section,
+ rf_path, channel, power_limit);
+}
+
+void rtl_hal_update_ra_mask(void *adapter, struct rtl_sta_info *psta,
+ u8 rssi_level)
+{
+ struct rtl_priv *rtlpriv = (struct rtl_priv *)adapter;
+ struct ieee80211_sta *sta =
+ container_of((void *)psta, struct ieee80211_sta, drv_priv);
+
+ rtlpriv->cfg->ops->update_rate_tbl(rtlpriv->hw, sta, rssi_level, false);
+}
+
+MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
+MODULE_AUTHOR("Larry Finger <Larry.FInger@lwfinger.net>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core");
diff --git a/drivers/staging/rtlwifi/phydm/rtl_phydm.h b/drivers/staging/rtlwifi/phydm/rtl_phydm.h
new file mode 100644
index 0000000..483d241
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/rtl_phydm.h
@@ -0,0 +1,45 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __RTL_PHYDM_H__
+#define __RTL_PHYDM_H__
+
+struct rtl_phydm_ops *rtl_phydm_get_ops_pointer(void);
+
+#define rtlpriv_to_phydm(priv) \
+ ((struct phy_dm_struct *)((priv)->phydm.internal))
+
+u8 phy_get_tx_power_index(void *adapter, u8 rf_path, u8 rate,
+ enum ht_channel_width bandwidth, u8 channel);
+void phy_set_tx_power_index_by_rs(void *adapter, u8 ch, u8 path, u8 rs);
+void phy_store_tx_power_by_rate(void *adapter, u32 band, u32 rfpath, u32 txnum,
+ u32 regaddr, u32 bitmask, u32 data);
+void phy_set_tx_power_limit(void *dm, u8 *regulation, u8 *band, u8 *bandwidth,
+ u8 *rate_section, u8 *rf_path, u8 *channel,
+ u8 *power_limit);
+
+void rtl_hal_update_ra_mask(void *adapter, struct rtl_sta_info *psta,
+ u8 rssi_level);
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/txbf/halcomtxbf.h b/drivers/staging/rtlwifi/phydm/txbf/halcomtxbf.h
new file mode 100644
index 0000000..6cacca1
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/txbf/halcomtxbf.h
@@ -0,0 +1,67 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __HAL_COM_TXBF_H__
+#define __HAL_COM_TXBF_H__
+
+enum txbf_set_type {
+ TXBF_SET_SOUNDING_ENTER,
+ TXBF_SET_SOUNDING_LEAVE,
+ TXBF_SET_SOUNDING_RATE,
+ TXBF_SET_SOUNDING_STATUS,
+ TXBF_SET_SOUNDING_FW_NDPA,
+ TXBF_SET_SOUNDING_CLK,
+ TXBF_SET_TX_PATH_RESET,
+ TXBF_SET_GET_TX_RATE
+};
+
+enum txbf_get_type {
+ TXBF_GET_EXPLICIT_BEAMFORMEE,
+ TXBF_GET_EXPLICIT_BEAMFORMER,
+ TXBF_GET_MU_MIMO_STA,
+ TXBF_GET_MU_MIMO_AP
+};
+
+/* 2 HAL TXBF related */
+struct _HAL_TXBF_INFO {
+ u8 txbf_idx;
+ u8 ndpa_idx;
+ u8 BW;
+ u8 rate;
+
+ struct timer_list txbf_fw_ndpa_timer;
+};
+
+#define hal_com_txbf_beamform_init(dm_void) NULL
+#define hal_com_txbf_config_gtab(dm_void) NULL
+#define hal_com_txbf_enter_work_item_callback(_adapter) NULL
+#define hal_com_txbf_leave_work_item_callback(_adapter) NULL
+#define hal_com_txbf_fw_ndpa_work_item_callback(_adapter) NULL
+#define hal_com_txbf_clk_work_item_callback(_adapter) NULL
+#define hal_com_txbf_rate_work_item_callback(_adapter) NULL
+#define hal_com_txbf_fw_ndpa_timer_callback(_adapter) NULL
+#define hal_com_txbf_status_work_item_callback(_adapter) NULL
+#define hal_com_txbf_get(_adapter, _get_type, _pout_buf)
+
+#endif /* #ifndef __HAL_COM_TXBF_H__ */
diff --git a/drivers/staging/rtlwifi/phydm/txbf/haltxbf8822b.h b/drivers/staging/rtlwifi/phydm/txbf/haltxbf8822b.h
new file mode 100644
index 0000000..5c92c43
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/txbf/haltxbf8822b.h
@@ -0,0 +1,39 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __HAL_TXBF_8822B_H__
+#define __HAL_TXBF_8822B_H__
+
+#define hal_txbf_8822b_enter(dm_void, idx)
+#define hal_txbf_8822b_leave(dm_void, idx)
+#define hal_txbf_8822b_status(dm_void, idx)
+#define hal_txbf_8822b_fw_txbf(dm_void, idx)
+#define hal_txbf_8822b_config_gtab(dm_void)
+
+void phydm_8822btxbf_rfmode(void *dm_void, u8 su_bfee_cnt, u8 mu_bfee_cnt);
+
+void phydm_8822b_sutxbfer_workaroud(void *dm_void, bool enable_su_bfer, u8 nc,
+ u8 nr, u8 ng, u8 CB, u8 BW, bool is_vht);
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/txbf/haltxbfinterface.h b/drivers/staging/rtlwifi/phydm/txbf/haltxbfinterface.h
new file mode 100644
index 0000000..82aeac1
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/txbf/haltxbfinterface.h
@@ -0,0 +1,38 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __HAL_TXBF_INTERFACE_H__
+#define __HAL_TXBF_INTERFACE_H__
+
+#define beamforming_get_ndpa_frame(dm, _pdu_os)
+#define beamforming_get_report_frame(adapter, precv_frame) RT_STATUS_FAILURE
+#define send_fw_ht_ndpa_packet(dm_void, RA, BW)
+#define send_sw_ht_ndpa_packet(dm_void, RA, BW)
+#define send_fw_vht_ndpa_packet(dm_void, RA, AID, BW)
+#define send_sw_vht_ndpa_packet(dm_void, RA, AID, BW)
+#define send_sw_vht_gid_mgnt_frame(dm_void, RA, idx)
+#define send_sw_vht_bf_report_poll(dm_void, RA, is_final_poll)
+#define send_sw_vht_mu_ndpa_packet(dm_void, BW)
+
+#endif
diff --git a/drivers/staging/rtlwifi/phydm/txbf/haltxbfjaguar.h b/drivers/staging/rtlwifi/phydm/txbf/haltxbfjaguar.h
new file mode 100644
index 0000000..c5ddd9c
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/txbf/haltxbfjaguar.h
@@ -0,0 +1,36 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __HAL_TXBF_JAGUAR_H__
+#define __HAL_TXBF_JAGUAR_H__
+
+#define hal_txbf_8812a_set_ndpa_rate(dm_void, BW, rate)
+#define hal_txbf_jaguar_enter(dm_void, idx)
+#define hal_txbf_jaguar_leave(dm_void, idx)
+#define hal_txbf_jaguar_status(dm_void, idx)
+#define hal_txbf_jaguar_fw_txbf(dm_void, idx)
+#define hal_txbf_jaguar_patch(dm_void, operation)
+#define hal_txbf_jaguar_clk_8812a(dm_void)
+
+#endif /* #ifndef __HAL_TXBF_JAGUAR_H__ */
diff --git a/drivers/staging/rtlwifi/phydm/txbf/phydm_hal_txbf_api.h b/drivers/staging/rtlwifi/phydm/txbf/phydm_hal_txbf_api.h
new file mode 100644
index 0000000..41358fc
--- /dev/null
+++ b/drivers/staging/rtlwifi/phydm/txbf/phydm_hal_txbf_api.h
@@ -0,0 +1,41 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __PHYDM_HAL_TXBF_API_H__
+#define __PHYDM_HAL_TXBF_API_H__
+
+#define tx_bf_nr(a, b) ((a > b) ? (b) : (a))
+
+u8 beamforming_get_htndp_tx_rate(void *dm_void, u8 comp_steering_num_of_bfer);
+
+u8 beamforming_get_vht_ndp_tx_rate(void *dm_void, u8 comp_steering_num_of_bfer);
+
+u8 phydm_get_beamforming_sounding_info(void *dm_void, u16 *troughput,
+ u8 total_bfee_num, u8 *tx_rate);
+
+u8 phydm_get_ndpa_rate(void *dm_void);
+
+u8 phydm_get_mu_bfee_snding_decision(void *dm_void, u16 throughput);
+
+#endif
diff --git a/drivers/staging/rtlwifi/ps.c b/drivers/staging/rtlwifi/ps.c
new file mode 100644
index 0000000..9172cee
--- /dev/null
+++ b/drivers/staging/rtlwifi/ps.c
@@ -0,0 +1,1007 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2012 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "wifi.h"
+#include "base.h"
+#include "ps.h"
+#include <linux/export.h>
+#include "btcoexist/rtl_btc.h"
+
+bool rtl_ps_enable_nic(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
+
+ /*<1> reset trx ring */
+ if (rtlhal->interface == INTF_PCI)
+ rtlpriv->intf_ops->reset_trx_ring(hw);
+
+ if (is_hal_stop(rtlhal))
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ "Driver is already down!\n");
+
+ /*<2> Enable Adapter */
+ if (rtlpriv->cfg->ops->hw_init(hw))
+ return false;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,
+ &rtlmac->retry_long);
+ RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
+
+ /*<2.1> Switch Channel & Bandwidth to last rtl_op_config setting*/
+ rtlpriv->cfg->ops->switch_channel(hw);
+ rtlpriv->cfg->ops->set_channel_access(hw);
+ rtlpriv->cfg->ops->set_bw_mode(hw,
+ cfg80211_get_chandef_type(&hw->conf.chandef));
+
+ /*<3> Enable Interrupt */
+ rtlpriv->cfg->ops->enable_interrupt(hw);
+
+ /*<enable timer> */
+ rtl_watch_dog_timer_callback((unsigned long)hw);
+
+ return true;
+}
+
+bool rtl_ps_disable_nic(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ /*<1> Stop all timer */
+ rtl_deinit_deferred_work(hw);
+
+ /*<2> Disable Interrupt */
+ rtlpriv->cfg->ops->disable_interrupt(hw);
+ tasklet_kill(&rtlpriv->works.irq_tasklet);
+
+ /*<3> Disable Adapter */
+ rtlpriv->cfg->ops->hw_disable(hw);
+
+ return true;
+}
+
+static bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
+ enum rf_pwrstate state_toset,
+ u32 changesource)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ enum rf_pwrstate rtstate;
+ bool actionallowed = false;
+ u16 rfwait_cnt = 0;
+
+ /*Only one thread can change
+ *the RF state at one time, and others
+ *should wait to be executed.
+ */
+ while (true) {
+ spin_lock(&rtlpriv->locks.rf_ps_lock);
+ if (ppsc->rfchange_inprogress) {
+ spin_unlock(&rtlpriv->locks.rf_ps_lock);
+
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ "RF Change in progress! Wait to set..state_toset(%d).\n",
+ state_toset);
+
+ /* Set RF after the previous action is done. */
+ while (ppsc->rfchange_inprogress) {
+ rfwait_cnt++;
+ mdelay(1);
+ /*Wait too long, return false to avoid
+ *to be stuck here.
+ */
+ if (rfwait_cnt > 100)
+ return false;
+ }
+ } else {
+ ppsc->rfchange_inprogress = true;
+ spin_unlock(&rtlpriv->locks.rf_ps_lock);
+ break;
+ }
+ }
+
+ rtstate = ppsc->rfpwr_state;
+
+ switch (state_toset) {
+ case ERFON:
+ ppsc->rfoff_reason &= (~changesource);
+
+ if ((changesource == RF_CHANGE_BY_HW) &&
+ (ppsc->hwradiooff)) {
+ ppsc->hwradiooff = false;
+ }
+
+ if (!ppsc->rfoff_reason) {
+ ppsc->rfoff_reason = 0;
+ actionallowed = true;
+ }
+ break;
+ case ERFOFF:
+ if ((changesource == RF_CHANGE_BY_HW) && !ppsc->hwradiooff)
+ ppsc->hwradiooff = true;
+
+ ppsc->rfoff_reason |= changesource;
+ actionallowed = true;
+ break;
+ case ERFSLEEP:
+ ppsc->rfoff_reason |= changesource;
+ actionallowed = true;
+ break;
+ default:
+ pr_err("switch case %#x not processed\n", state_toset);
+ break;
+ }
+
+ if (actionallowed)
+ rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset);
+
+ spin_lock(&rtlpriv->locks.rf_ps_lock);
+ ppsc->rfchange_inprogress = false;
+ spin_unlock(&rtlpriv->locks.rf_ps_lock);
+
+ return actionallowed;
+}
+
+static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+ ppsc->swrf_processing = true;
+
+ if (ppsc->inactive_pwrstate == ERFON &&
+ rtlhal->interface == INTF_PCI) {
+ if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) &&
+ RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) &&
+ rtlhal->interface == INTF_PCI) {
+ rtlpriv->intf_ops->disable_aspm(hw);
+ RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
+ }
+ }
+
+ rtl_ps_set_rf_state(hw, ppsc->inactive_pwrstate,
+ RF_CHANGE_BY_IPS);
+
+ if (ppsc->inactive_pwrstate == ERFOFF &&
+ rtlhal->interface == INTF_PCI) {
+ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM &&
+ !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
+ rtlpriv->intf_ops->enable_aspm(hw);
+ RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
+ }
+ }
+
+ ppsc->swrf_processing = false;
+}
+
+void rtl_ips_nic_off_wq_callback(void *data)
+{
+ struct rtl_works *rtlworks =
+ container_of_dwork_rtl(data, struct rtl_works, ips_nic_off_wq);
+ struct ieee80211_hw *hw = rtlworks->hw;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ enum rf_pwrstate rtstate;
+
+ if (mac->opmode != NL80211_IFTYPE_STATION) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ "not station return\n");
+ return;
+ }
+
+ if (mac->p2p_in_use)
+ return;
+
+ if (mac->link_state > MAC80211_NOLINK)
+ return;
+
+ if (is_hal_stop(rtlhal))
+ return;
+
+ if (rtlpriv->sec.being_setkey)
+ return;
+
+ if (rtlpriv->cfg->ops->bt_coex_off_before_lps)
+ rtlpriv->cfg->ops->bt_coex_off_before_lps(hw);
+
+ if (ppsc->inactiveps) {
+ rtstate = ppsc->rfpwr_state;
+
+ /*
+ *Do not enter IPS in the following conditions:
+ *(1) RF is already OFF or Sleep
+ *(2) swrf_processing (indicates the IPS is still under going)
+ *(3) Connectted (only disconnected can trigger IPS)
+ *(4) IBSS (send Beacon)
+ *(5) AP mode (send Beacon)
+ *(6) monitor mode (rcv packet)
+ */
+
+ if (rtstate == ERFON &&
+ !ppsc->swrf_processing &&
+ (mac->link_state == MAC80211_NOLINK) &&
+ !mac->act_scanning) {
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+ "IPSEnter(): Turn off RF\n");
+
+ ppsc->inactive_pwrstate = ERFOFF;
+ ppsc->in_powersavemode = true;
+
+ /* call before RF off */
+ if (rtlpriv->cfg->ops->get_btc_status())
+ rtlpriv->btcoexist.btc_ops->btc_ips_notify(rtlpriv,
+ ppsc->inactive_pwrstate);
+
+ /*rtl_pci_reset_trx_ring(hw); */
+ _rtl_ps_inactive_ps(hw);
+ }
+ }
+}
+
+void rtl_ips_nic_off(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ /* because when link with ap, mac80211 will ask us
+ * to disable nic quickly after scan before linking,
+ * this will cause link failed, so we delay 100ms here
+ */
+ queue_delayed_work(rtlpriv->works.rtl_wq,
+ &rtlpriv->works.ips_nic_off_wq, MSECS(100));
+}
+
+/* NOTICE: any opmode should exc nic_on, or disable without
+ * nic_on may something wrong, like adhoc TP
+ */
+void rtl_ips_nic_on(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ enum rf_pwrstate rtstate;
+
+ cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq);
+
+ mutex_lock(&rtlpriv->locks.ips_mutex);
+ if (ppsc->inactiveps) {
+ rtstate = ppsc->rfpwr_state;
+
+ if (rtstate != ERFON &&
+ !ppsc->swrf_processing &&
+ ppsc->rfoff_reason <= RF_CHANGE_BY_IPS) {
+ ppsc->inactive_pwrstate = ERFON;
+ ppsc->in_powersavemode = false;
+ _rtl_ps_inactive_ps(hw);
+ /* call after RF on */
+ if (rtlpriv->phydm.ops)
+ rtlpriv->phydm.ops->phydm_reset_dm(rtlpriv);
+ if (rtlpriv->cfg->ops->get_btc_status())
+ rtlpriv->btcoexist.btc_ops->btc_ips_notify(rtlpriv,
+ ppsc->inactive_pwrstate);
+ }
+ }
+ mutex_unlock(&rtlpriv->locks.ips_mutex);
+}
+
+/*for FW LPS*/
+
+/*
+ *Determine if we can set Fw into PS mode
+ *in current condition.Return TRUE if it
+ *can enter PS mode.
+ */
+static bool rtl_get_fwlps_doze(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ u32 ps_timediff;
+
+ ps_timediff = jiffies_to_msecs(jiffies -
+ ppsc->last_delaylps_stamp_jiffies);
+
+ if (ps_timediff < 2000) {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ "Delay enter Fw LPS for DHCP, ARP, or EAPOL exchanging state\n");
+ return false;
+ }
+
+ if (mac->link_state != MAC80211_LINKED)
+ return false;
+
+ if (mac->opmode == NL80211_IFTYPE_ADHOC)
+ return false;
+
+ return true;
+}
+
+/* Change current and default preamble mode.*/
+void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ bool enter_fwlps;
+
+ if (mac->opmode == NL80211_IFTYPE_ADHOC)
+ return;
+
+ if (mac->link_state != MAC80211_LINKED)
+ return;
+
+ if (ppsc->dot11_psmode == rt_psmode && rt_psmode == EACTIVE)
+ return;
+
+ /* Update power save mode configured. */
+ ppsc->dot11_psmode = rt_psmode;
+
+ /*
+ *<FW control LPS>
+ *1. Enter PS mode
+ * Set RPWM to Fw to turn RF off and send H2C fw_pwrmode
+ * cmd to set Fw into PS mode.
+ *2. Leave PS mode
+ * Send H2C fw_pwrmode cmd to Fw to set Fw into Active
+ * mode and set RPWM to turn RF on.
+ */
+
+ if ((ppsc->fwctrl_lps) && ppsc->report_linked) {
+ if (ppsc->dot11_psmode == EACTIVE) {
+ RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+ "FW LPS leave ps_mode:%x\n",
+ FW_PS_ACTIVE_MODE);
+ enter_fwlps = false;
+ ppsc->pwr_mode = FW_PS_ACTIVE_MODE;
+ ppsc->smart_ps = 0;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_LPS_ACTION,
+ (u8 *)(&enter_fwlps));
+ if (ppsc->p2p_ps_info.opp_ps)
+ rtl_p2p_ps_cmd(hw, P2P_PS_ENABLE);
+
+ if (rtlpriv->cfg->ops->get_btc_status())
+ rtlpriv->btcoexist.btc_ops->btc_lps_notify(rtlpriv, rt_psmode);
+ } else {
+ if (rtl_get_fwlps_doze(hw)) {
+ RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+ "FW LPS enter ps_mode:%x\n",
+ ppsc->fwctrl_psmode);
+ if (rtlpriv->cfg->ops->get_btc_status())
+ rtlpriv->btcoexist.btc_ops->btc_lps_notify(rtlpriv, rt_psmode);
+ enter_fwlps = true;
+ ppsc->pwr_mode = ppsc->fwctrl_psmode;
+ ppsc->smart_ps = 2;
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_FW_LPS_ACTION,
+ (u8 *)(&enter_fwlps));
+
+ } else {
+ /* Reset the power save related parameters. */
+ ppsc->dot11_psmode = EACTIVE;
+ }
+ }
+ }
+}
+
+/* Interrupt safe routine to enter the leisure power save mode.*/
+static void rtl_lps_enter_core(struct ieee80211_hw *hw)
+{
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ if (!ppsc->fwctrl_lps)
+ return;
+
+ if (rtlpriv->sec.being_setkey)
+ return;
+
+ if (rtlpriv->link_info.busytraffic)
+ return;
+
+ /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */
+ if (mac->cnt_after_linked < 5)
+ return;
+
+ if (mac->opmode == NL80211_IFTYPE_ADHOC)
+ return;
+
+ if (mac->link_state != MAC80211_LINKED)
+ return;
+
+ mutex_lock(&rtlpriv->locks.lps_mutex);
+
+ /* Don't need to check (ppsc->dot11_psmode == EACTIVE), because
+ * bt_ccoexist may ask to enter lps.
+ * In normal case, this constraint move to rtl_lps_set_psmode().
+ */
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ "Enter 802.11 power save mode...\n");
+ rtl_lps_set_psmode(hw, EAUTOPS);
+
+ mutex_unlock(&rtlpriv->locks.lps_mutex);
+}
+
+/* Interrupt safe routine to leave the leisure power save mode.*/
+static void rtl_lps_leave_core(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ mutex_lock(&rtlpriv->locks.lps_mutex);
+
+ if (ppsc->fwctrl_lps) {
+ if (ppsc->dot11_psmode != EACTIVE) {
+ /*FIX ME */
+ /*rtlpriv->cfg->ops->enable_interrupt(hw); */
+
+ if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM &&
+ RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) &&
+ rtlhal->interface == INTF_PCI) {
+ rtlpriv->intf_ops->disable_aspm(hw);
+ RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
+ }
+
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ "Busy Traffic,Leave 802.11 power save..\n");
+
+ rtl_lps_set_psmode(hw, EACTIVE);
+ }
+ }
+ mutex_unlock(&rtlpriv->locks.lps_mutex);
+}
+
+/* For sw LPS*/
+void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct ieee80211_hdr *hdr = data;
+ struct ieee80211_tim_ie *tim_ie;
+ u8 *tim;
+ u8 tim_len;
+ bool u_buffed;
+ bool m_buffed;
+
+ if (mac->opmode != NL80211_IFTYPE_STATION)
+ return;
+
+ if (!rtlpriv->psc.swctrl_lps)
+ return;
+
+ if (rtlpriv->mac80211.link_state != MAC80211_LINKED)
+ return;
+
+ if (!rtlpriv->psc.sw_ps_enabled)
+ return;
+
+ if (rtlpriv->psc.fwctrl_lps)
+ return;
+
+ if (likely(!(hw->conf.flags & IEEE80211_CONF_PS)))
+ return;
+
+ /* check if this really is a beacon */
+ if (!ieee80211_is_beacon(hdr->frame_control))
+ return;
+
+ /* min. beacon length + FCS_LEN */
+ if (len <= 40 + FCS_LEN)
+ return;
+
+ /* and only beacons from the associated BSSID, please */
+ if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid))
+ return;
+
+ rtlpriv->psc.last_beacon = jiffies;
+
+ tim = rtl_find_ie(data, len - FCS_LEN, WLAN_EID_TIM);
+ if (!tim)
+ return;
+
+ if (tim[1] < sizeof(*tim_ie))
+ return;
+
+ tim_len = tim[1];
+ tim_ie = (struct ieee80211_tim_ie *)&tim[2];
+
+ if (!WARN_ON_ONCE(!hw->conf.ps_dtim_period))
+ rtlpriv->psc.dtim_counter = tim_ie->dtim_count;
+
+ /* Check whenever the PHY can be turned off again. */
+
+ /* 1. What about buffered unicast traffic for our AID? */
+ u_buffed = ieee80211_check_tim(tim_ie, tim_len,
+ rtlpriv->mac80211.assoc_id);
+
+ /* 2. Maybe the AP wants to send multicast/broadcast data? */
+ m_buffed = tim_ie->bitmap_ctrl & 0x01;
+ rtlpriv->psc.multi_buffered = m_buffed;
+
+ /* unicast will process by mac80211 through
+ * set ~IEEE80211_CONF_PS, So we just check
+ * multicast frames here
+ */
+ if (!m_buffed) {
+ /* back to low-power land. and delay is
+ * prevent null power save frame tx fail
+ */
+ queue_delayed_work(rtlpriv->works.rtl_wq,
+ &rtlpriv->works.ps_work, MSECS(5));
+ } else {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
+ "u_bufferd: %x, m_buffered: %x\n", u_buffed, m_buffed);
+ }
+}
+
+void rtl_swlps_rf_awake(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+ if (!rtlpriv->psc.swctrl_lps)
+ return;
+ if (mac->link_state != MAC80211_LINKED)
+ return;
+
+ if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM &&
+ RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
+ rtlpriv->intf_ops->disable_aspm(hw);
+ RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
+ }
+
+ mutex_lock(&rtlpriv->locks.lps_mutex);
+ rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS);
+ mutex_unlock(&rtlpriv->locks.lps_mutex);
+}
+
+void rtl_swlps_rfon_wq_callback(void *data)
+{
+ struct rtl_works *rtlworks =
+ container_of_dwork_rtl(data, struct rtl_works, ps_rfon_wq);
+ struct ieee80211_hw *hw = rtlworks->hw;
+
+ rtl_swlps_rf_awake(hw);
+}
+
+void rtl_swlps_rf_sleep(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ u8 sleep_intv;
+
+ if (!rtlpriv->psc.sw_ps_enabled)
+ return;
+
+ if ((rtlpriv->sec.being_setkey) ||
+ (mac->opmode == NL80211_IFTYPE_ADHOC))
+ return;
+
+ /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */
+ if ((mac->link_state != MAC80211_LINKED) || (mac->cnt_after_linked < 5))
+ return;
+
+ if (rtlpriv->link_info.busytraffic)
+ return;
+
+ spin_lock(&rtlpriv->locks.rf_ps_lock);
+ if (rtlpriv->psc.rfchange_inprogress) {
+ spin_unlock(&rtlpriv->locks.rf_ps_lock);
+ return;
+ }
+ spin_unlock(&rtlpriv->locks.rf_ps_lock);
+
+ mutex_lock(&rtlpriv->locks.lps_mutex);
+ rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS);
+ mutex_unlock(&rtlpriv->locks.lps_mutex);
+
+ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM &&
+ !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
+ rtlpriv->intf_ops->enable_aspm(hw);
+ RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
+ }
+
+ /* here is power save alg, when this beacon is DTIM
+ * we will set sleep time to dtim_period * n;
+ * when this beacon is not DTIM, we will set sleep
+ * time to sleep_intv = rtlpriv->psc.dtim_counter or
+ * MAX_SW_LPS_SLEEP_INTV(default set to 5)
+ */
+
+ if (rtlpriv->psc.dtim_counter == 0) {
+ if (hw->conf.ps_dtim_period == 1)
+ sleep_intv = hw->conf.ps_dtim_period * 2;
+ else
+ sleep_intv = hw->conf.ps_dtim_period;
+ } else {
+ sleep_intv = rtlpriv->psc.dtim_counter;
+ }
+
+ if (sleep_intv > MAX_SW_LPS_SLEEP_INTV)
+ sleep_intv = MAX_SW_LPS_SLEEP_INTV;
+
+ /* this print should always be dtim_conter = 0 &
+ * sleep = dtim_period, that meaons, we should
+ * awake before every dtim
+ */
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
+ "dtim_counter:%x will sleep :%d beacon_intv\n",
+ rtlpriv->psc.dtim_counter, sleep_intv);
+
+ /* we tested that 40ms is enough for sw & hw sw delay */
+ queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_rfon_wq,
+ MSECS(sleep_intv *
+ mac->vif->bss_conf.beacon_int - 40));
+}
+
+void rtl_lps_change_work_callback(struct work_struct *work)
+{
+ struct rtl_works *rtlworks =
+ container_of(work, struct rtl_works, lps_change_work);
+ struct ieee80211_hw *hw = rtlworks->hw;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ if (rtlpriv->enter_ps)
+ rtl_lps_enter_core(hw);
+ else
+ rtl_lps_leave_core(hw);
+}
+
+void rtl_lps_enter(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ if (!in_interrupt())
+ return rtl_lps_enter_core(hw);
+ rtlpriv->enter_ps = true;
+ schedule_work(&rtlpriv->works.lps_change_work);
+}
+
+void rtl_lps_leave(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ if (!in_interrupt())
+ return rtl_lps_leave_core(hw);
+ rtlpriv->enter_ps = false;
+ schedule_work(&rtlpriv->works.lps_change_work);
+}
+
+void rtl_swlps_wq_callback(void *data)
+{
+ struct rtl_works *rtlworks = container_of_dwork_rtl(data,
+ struct rtl_works,
+ ps_work);
+ struct ieee80211_hw *hw = rtlworks->hw;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ bool ps = false;
+
+ ps = (hw->conf.flags & IEEE80211_CONF_PS);
+
+ /* we can sleep after ps null send ok */
+ if (rtlpriv->psc.state_inap) {
+ rtl_swlps_rf_sleep(hw);
+
+ if (rtlpriv->psc.state && !ps) {
+ rtlpriv->psc.sleep_ms = jiffies_to_msecs(jiffies -
+ rtlpriv->psc.last_action);
+ }
+
+ if (ps)
+ rtlpriv->psc.last_slept = jiffies;
+
+ rtlpriv->psc.last_action = jiffies;
+ rtlpriv->psc.state = ps;
+ }
+}
+
+static void rtl_p2p_noa_ie(struct ieee80211_hw *hw, void *data,
+ unsigned int len)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct ieee80211_mgmt *mgmt = data;
+ struct rtl_p2p_ps_info *p2pinfo = &rtlpriv->psc.p2p_ps_info;
+ u8 *pos, *end, *ie;
+ u16 noa_len;
+ static u8 p2p_oui_ie_type[4] = {0x50, 0x6f, 0x9a, 0x09};
+ u8 noa_num, index, i, noa_index = 0;
+ bool find_p2p_ie = false, find_p2p_ps_ie = false;
+
+ pos = (u8 *)mgmt->u.beacon.variable;
+ end = data + len;
+ ie = NULL;
+
+ while (pos + 1 < end) {
+ if (pos + 2 + pos[1] > end)
+ return;
+
+ if (pos[0] == 221 && pos[1] > 4) {
+ if (memcmp(&pos[2], p2p_oui_ie_type, 4) == 0) {
+ ie = pos + 2 + 4;
+ break;
+ }
+ }
+ pos += 2 + pos[1];
+ }
+
+ if (!ie)
+ return;
+ find_p2p_ie = true;
+ /*to find noa ie*/
+ while (ie + 1 < end) {
+ noa_len = READEF2BYTE((__le16 *)&ie[1]);
+ if (ie + 3 + ie[1] > end)
+ return;
+
+ if (ie[0] == 12) {
+ find_p2p_ps_ie = true;
+ if ((noa_len - 2) % 13 != 0) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "P2P notice of absence: invalid length.%d\n",
+ noa_len);
+ return;
+ }
+ noa_num = (noa_len - 2) / 13;
+ noa_index = ie[3];
+ if (rtlpriv->psc.p2p_ps_info.p2p_ps_mode ==
+ P2P_PS_NONE || noa_index != p2pinfo->noa_index) {
+ RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD,
+ "update NOA ie.\n");
+ p2pinfo->noa_index = noa_index;
+ p2pinfo->opp_ps = (ie[4] >> 7);
+ p2pinfo->ctwindow = ie[4] & 0x7F;
+ p2pinfo->noa_num = noa_num;
+ index = 5;
+ for (i = 0; i < noa_num; i++) {
+ p2pinfo->noa_count_type[i] =
+ READEF1BYTE(ie + index);
+ index += 1;
+ p2pinfo->noa_duration[i] =
+ READEF4BYTE((__le32 *)ie + index);
+ index += 4;
+ p2pinfo->noa_interval[i] =
+ READEF4BYTE((__le32 *)ie + index);
+ index += 4;
+ p2pinfo->noa_start_time[i] =
+ READEF4BYTE((__le32 *)ie + index);
+ index += 4;
+ }
+
+ if (p2pinfo->opp_ps == 1) {
+ p2pinfo->p2p_ps_mode = P2P_PS_CTWINDOW;
+ /* Driver should wait LPS entering
+ * CTWindow
+ */
+ if (rtlpriv->psc.fw_current_inpsmode)
+ rtl_p2p_ps_cmd(hw,
+ P2P_PS_ENABLE);
+ } else if (p2pinfo->noa_num > 0) {
+ p2pinfo->p2p_ps_mode = P2P_PS_NOA;
+ rtl_p2p_ps_cmd(hw, P2P_PS_ENABLE);
+ } else if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) {
+ rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE);
+ }
+ }
+ break;
+ }
+ ie += 3 + noa_len;
+ }
+
+ if (find_p2p_ie) {
+ if ((p2pinfo->p2p_ps_mode > P2P_PS_NONE) &&
+ (!find_p2p_ps_ie))
+ rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE);
+ }
+}
+
+static void rtl_p2p_action_ie(struct ieee80211_hw *hw, void *data,
+ unsigned int len)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct ieee80211_mgmt *mgmt = data;
+ struct rtl_p2p_ps_info *p2pinfo = &rtlpriv->psc.p2p_ps_info;
+ u8 noa_num, index, i, noa_index = 0;
+ u8 *pos, *end, *ie;
+ u16 noa_len;
+ static u8 p2p_oui_ie_type[4] = {0x50, 0x6f, 0x9a, 0x09};
+
+ pos = (u8 *)&mgmt->u.action.category;
+ end = data + len;
+ ie = NULL;
+
+ if (pos[0] == 0x7f) {
+ if (memcmp(&pos[1], p2p_oui_ie_type, 4) == 0)
+ ie = pos + 3 + 4;
+ }
+
+ if (!ie)
+ return;
+
+ RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "action frame find P2P IE.\n");
+ /*to find noa ie*/
+ while (ie + 1 < end) {
+ noa_len = READEF2BYTE((__le16 *)&ie[1]);
+ if (ie + 3 + ie[1] > end)
+ return;
+
+ if (ie[0] == 12) {
+ RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "find NOA IE.\n");
+ RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_LOUD, "noa ie ",
+ ie, noa_len);
+ if ((noa_len - 2) % 13 != 0) {
+ RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD,
+ "P2P notice of absence: invalid length.%d\n",
+ noa_len);
+ return;
+ }
+ noa_num = (noa_len - 2) / 13;
+ noa_index = ie[3];
+ if (rtlpriv->psc.p2p_ps_info.p2p_ps_mode ==
+ P2P_PS_NONE || noa_index != p2pinfo->noa_index) {
+ p2pinfo->noa_index = noa_index;
+ p2pinfo->opp_ps = (ie[4] >> 7);
+ p2pinfo->ctwindow = ie[4] & 0x7F;
+ p2pinfo->noa_num = noa_num;
+ index = 5;
+ for (i = 0; i < noa_num; i++) {
+ p2pinfo->noa_count_type[i] =
+ READEF1BYTE(ie + index);
+ index += 1;
+ p2pinfo->noa_duration[i] =
+ READEF4BYTE((__le32 *)ie + index);
+ index += 4;
+ p2pinfo->noa_interval[i] =
+ READEF4BYTE((__le32 *)ie + index);
+ index += 4;
+ p2pinfo->noa_start_time[i] =
+ READEF4BYTE((__le32 *)ie + index);
+ index += 4;
+ }
+
+ if (p2pinfo->opp_ps == 1) {
+ p2pinfo->p2p_ps_mode = P2P_PS_CTWINDOW;
+ /* Driver should wait LPS entering
+ * CTWindow
+ */
+ if (rtlpriv->psc.fw_current_inpsmode)
+ rtl_p2p_ps_cmd(hw,
+ P2P_PS_ENABLE);
+ } else if (p2pinfo->noa_num > 0) {
+ p2pinfo->p2p_ps_mode = P2P_PS_NOA;
+ rtl_p2p_ps_cmd(hw, P2P_PS_ENABLE);
+ } else if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) {
+ rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE);
+ }
+ }
+ break;
+ }
+ ie += 3 + noa_len;
+ }
+}
+
+void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
+ struct rtl_p2p_ps_info *p2pinfo = &rtlpriv->psc.p2p_ps_info;
+
+ RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "p2p state %x\n", p2p_ps_state);
+ switch (p2p_ps_state) {
+ case P2P_PS_DISABLE:
+ p2pinfo->p2p_ps_state = p2p_ps_state;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
+ &p2p_ps_state);
+ p2pinfo->noa_index = 0;
+ p2pinfo->ctwindow = 0;
+ p2pinfo->opp_ps = 0;
+ p2pinfo->noa_num = 0;
+ p2pinfo->p2p_ps_mode = P2P_PS_NONE;
+ if (rtlps->fw_current_inpsmode) {
+ if (rtlps->smart_ps == 0) {
+ rtlps->smart_ps = 2;
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_H2C_FW_PWRMODE,
+ &rtlps->pwr_mode);
+ }
+ }
+ break;
+ case P2P_PS_ENABLE:
+ if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) {
+ p2pinfo->p2p_ps_state = p2p_ps_state;
+
+ if (p2pinfo->ctwindow > 0) {
+ if (rtlps->smart_ps != 0) {
+ rtlps->smart_ps = 0;
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_H2C_FW_PWRMODE,
+ &rtlps->pwr_mode);
+ }
+ }
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
+ &p2p_ps_state);
+ }
+ break;
+ case P2P_PS_SCAN:
+ case P2P_PS_SCAN_DONE:
+ case P2P_PS_ALLSTASLEEP:
+ if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) {
+ p2pinfo->p2p_ps_state = p2p_ps_state;
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
+ &p2p_ps_state);
+ }
+ break;
+ default:
+ break;
+ }
+ RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD,
+ "ctwindow %x oppps %x\n",
+ p2pinfo->ctwindow, p2pinfo->opp_ps);
+ RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD,
+ "count %x duration %x index %x interval %x start time %x noa num %x\n",
+ p2pinfo->noa_count_type[0],
+ p2pinfo->noa_duration[0],
+ p2pinfo->noa_index,
+ p2pinfo->noa_interval[0],
+ p2pinfo->noa_start_time[0],
+ p2pinfo->noa_num);
+ RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "end\n");
+}
+
+void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct ieee80211_hdr *hdr = data;
+
+ if (!mac->p2p)
+ return;
+ if (mac->link_state != MAC80211_LINKED)
+ return;
+ /* min. beacon length + FCS_LEN */
+ if (len <= 40 + FCS_LEN)
+ return;
+
+ /* and only beacons from the associated BSSID, please */
+ if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid))
+ return;
+
+ /* check if this really is a beacon */
+ if (!(ieee80211_is_beacon(hdr->frame_control) ||
+ ieee80211_is_probe_resp(hdr->frame_control) ||
+ ieee80211_is_action(hdr->frame_control)))
+ return;
+
+ if (ieee80211_is_action(hdr->frame_control))
+ rtl_p2p_action_ie(hw, data, len - FCS_LEN);
+ else
+ rtl_p2p_noa_ie(hw, data, len - FCS_LEN);
+}
diff --git a/drivers/staging/rtlwifi/ps.h b/drivers/staging/rtlwifi/ps.h
new file mode 100644
index 0000000..6c187da
--- /dev/null
+++ b/drivers/staging/rtlwifi/ps.h
@@ -0,0 +1,50 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2012 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __REALTEK_RTL_PCI_PS_H__
+#define __REALTEK_RTL_PCI_PS_H__
+
+#define MAX_SW_LPS_SLEEP_INTV 5
+
+bool rtl_ps_enable_nic(struct ieee80211_hw *hw);
+bool rtl_ps_disable_nic(struct ieee80211_hw *hw);
+void rtl_ips_nic_off(struct ieee80211_hw *hw);
+void rtl_ips_nic_on(struct ieee80211_hw *hw);
+void rtl_ips_nic_off_wq_callback(void *data);
+void rtl_lps_enter(struct ieee80211_hw *hw);
+void rtl_lps_leave(struct ieee80211_hw *hw);
+
+void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode);
+
+void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len);
+void rtl_swlps_wq_callback(void *data);
+void rtl_swlps_rfon_wq_callback(void *data);
+void rtl_swlps_rf_awake(struct ieee80211_hw *hw);
+void rtl_swlps_rf_sleep(struct ieee80211_hw *hw);
+void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state);
+void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len);
+void rtl_lps_change_work_callback(struct work_struct *work);
+
+#endif
diff --git a/drivers/staging/rtlwifi/pwrseqcmd.h b/drivers/staging/rtlwifi/pwrseqcmd.h
new file mode 100644
index 0000000..f411b7e
--- /dev/null
+++ b/drivers/staging/rtlwifi/pwrseqcmd.h
@@ -0,0 +1,94 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2012 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL8723E_PWRSEQCMD_H__
+#define __RTL8723E_PWRSEQCMD_H__
+
+#include "wifi.h"
+/*---------------------------------------------
+ * 3 The value of cmd: 4 bits
+ *---------------------------------------------
+ */
+#define PWR_CMD_READ 0x00
+#define PWR_CMD_WRITE 0x01
+#define PWR_CMD_POLLING 0x02
+#define PWR_CMD_DELAY 0x03
+#define PWR_CMD_END 0x04
+
+/* define the base address of each block */
+#define PWR_BASEADDR_MAC 0x00
+#define PWR_BASEADDR_USB 0x01
+#define PWR_BASEADDR_PCIE 0x02
+#define PWR_BASEADDR_SDIO 0x03
+
+#define PWR_INTF_SDIO_MSK BIT(0)
+#define PWR_INTF_USB_MSK BIT(1)
+#define PWR_INTF_PCI_MSK BIT(2)
+#define PWR_INTF_ALL_MSK (BIT(0) | BIT(1) | BIT(2) | BIT(3))
+
+#define PWR_FAB_TSMC_MSK BIT(0)
+#define PWR_FAB_UMC_MSK BIT(1)
+#define PWR_FAB_ALL_MSK (BIT(0) | BIT(1) | BIT(2) | BIT(3))
+
+#define PWR_CUT_TESTCHIP_MSK BIT(0)
+#define PWR_CUT_A_MSK BIT(1)
+#define PWR_CUT_B_MSK BIT(2)
+#define PWR_CUT_C_MSK BIT(3)
+#define PWR_CUT_D_MSK BIT(4)
+#define PWR_CUT_E_MSK BIT(5)
+#define PWR_CUT_F_MSK BIT(6)
+#define PWR_CUT_G_MSK BIT(7)
+#define PWR_CUT_ALL_MSK 0xFF
+
+enum pwrseq_delay_unit {
+ PWRSEQ_DELAY_US,
+ PWRSEQ_DELAY_MS,
+};
+
+struct wlan_pwr_cfg {
+ u16 offset;
+ u8 cut_msk;
+ u8 fab_msk:4;
+ u8 interface_msk:4;
+ u8 base:4;
+ u8 cmd:4;
+ u8 msk;
+ u8 value;
+};
+
+#define GET_PWR_CFG_OFFSET(__PWR_CMD) (__PWR_CMD.offset)
+#define GET_PWR_CFG_CUT_MASK(__PWR_CMD) (__PWR_CMD.cut_msk)
+#define GET_PWR_CFG_FAB_MASK(__PWR_CMD) (__PWR_CMD.fab_msk)
+#define GET_PWR_CFG_INTF_MASK(__PWR_CMD) (__PWR_CMD.interface_msk)
+#define GET_PWR_CFG_BASE(__PWR_CMD) (__PWR_CMD.base)
+#define GET_PWR_CFG_CMD(__PWR_CMD) (__PWR_CMD.cmd)
+#define GET_PWR_CFG_MASK(__PWR_CMD) (__PWR_CMD.msk)
+#define GET_PWR_CFG_VALUE(__PWR_CMD) (__PWR_CMD.value)
+
+bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version,
+ u8 fab_version, u8 interface_type,
+ struct wlan_pwr_cfg pwrcfgcmd[]);
+
+#endif
diff --git a/drivers/staging/rtlwifi/rc.c b/drivers/staging/rtlwifi/rc.c
new file mode 100644
index 0000000..65de0c7
--- /dev/null
+++ b/drivers/staging/rtlwifi/rc.c
@@ -0,0 +1,322 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2012 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "wifi.h"
+#include "base.h"
+#include "rc.h"
+
+/*
+ *Finds the highest rate index we can use
+ *if skb is special data like DHCP/EAPOL, we set should
+ *it to lowest rate CCK_1M, otherwise we set rate to
+ *highest rate based on wireless mode used for iwconfig
+ *show Tx rate.
+ */
+static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv,
+ struct ieee80211_sta *sta,
+ struct sk_buff *skb, bool not_data)
+{
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ struct rtl_sta_info *sta_entry = NULL;
+ u16 wireless_mode = 0;
+ u8 nss; /* NSS -1 */
+
+ if (get_rf_type(rtlphy) >= RF_4T4R)
+ nss = 3;
+ else if (get_rf_type(rtlphy) >= RF_3T3R)
+ nss = 2;
+ else if (get_rf_type(rtlphy) >= RF_2T2R)
+ nss = 1;
+ else
+ nss = 0;
+
+ /*
+ *this rate is no use for true rate, firmware
+ *will control rate at all it just used for
+ *1.show in iwconfig in B/G mode
+ *2.in rtl_get_tcb_desc when we check rate is
+ * 1M we will not use FW rate but user rate.
+ */
+
+ if (sta) {
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+ wireless_mode = sta_entry->wireless_mode;
+ }
+
+ if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true, false) ||
+ not_data) {
+ return 0;
+ }
+ if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+ if (wireless_mode == WIRELESS_MODE_B) {
+ return B_MODE_MAX_RIX;
+ } else if (wireless_mode == WIRELESS_MODE_G) {
+ return G_MODE_MAX_RIX;
+ } else if (wireless_mode == WIRELESS_MODE_N_24G) {
+ if (nss == 0)
+ return N_MODE_MCS7_RIX;
+ else
+ return N_MODE_MCS15_RIX;
+ } else if (wireless_mode == WIRELESS_MODE_AC_24G) {
+ if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
+ return AC_MODE_MCS8_RIX | (nss << 4);
+ else
+ return AC_MODE_MCS9_RIX | (nss << 4);
+ }
+ return 0;
+ }
+ if (wireless_mode == WIRELESS_MODE_A) {
+ return A_MODE_MAX_RIX;
+ } else if (wireless_mode == WIRELESS_MODE_N_5G) {
+ if (nss == 0)
+ return N_MODE_MCS7_RIX;
+ else
+ return N_MODE_MCS15_RIX;
+ } else if (wireless_mode == WIRELESS_MODE_AC_5G) {
+ if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
+ return AC_MODE_MCS8_RIX | (nss << 4);
+ else
+ return AC_MODE_MCS9_RIX | (nss << 4);
+ }
+ return 0;
+}
+
+static void _rtl_rc_rate_set_series(struct rtl_priv *rtlpriv,
+ struct ieee80211_sta *sta,
+ struct ieee80211_tx_rate *rate,
+ struct ieee80211_tx_rate_control *txrc,
+ u8 tries, s8 rix, int rtsctsenable,
+ bool not_data)
+{
+ struct rtl_mac *mac = rtl_mac(rtlpriv);
+ struct rtl_sta_info *sta_entry = NULL;
+ u16 wireless_mode = 0;
+ u8 sgi_20 = 0, sgi_40 = 0, sgi_80 = 0;
+
+ if (sta) {
+ sgi_20 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20;
+ sgi_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40;
+ sgi_80 = sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80;
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+ wireless_mode = sta_entry->wireless_mode;
+ }
+ rate->count = tries;
+ rate->idx = rix >= 0x00 ? rix : 0x00;
+ if (((rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE) ||
+ (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8822BE)) &&
+ wireless_mode == WIRELESS_MODE_AC_5G)
+ rate->idx |= 0x10;/*2NSS for 8812AE, 8822BE*/
+
+ if (!not_data) {
+ if (txrc->short_preamble)
+ rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
+ if (mac->opmode == NL80211_IFTYPE_AP ||
+ mac->opmode == NL80211_IFTYPE_ADHOC) {
+ if (sta && (sta->ht_cap.cap &
+ IEEE80211_HT_CAP_SUP_WIDTH_20_40))
+ rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
+ if (sta && (sta->vht_cap.vht_supported))
+ rate->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH;
+ } else {
+ if (mac->bw_80)
+ rate->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH;
+ else if (mac->bw_40)
+ rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
+ }
+
+ if (sgi_20 || sgi_40 || sgi_80)
+ rate->flags |= IEEE80211_TX_RC_SHORT_GI;
+ if (sta && sta->ht_cap.ht_supported &&
+ ((wireless_mode == WIRELESS_MODE_N_5G) ||
+ (wireless_mode == WIRELESS_MODE_N_24G)))
+ rate->flags |= IEEE80211_TX_RC_MCS;
+ if (sta && sta->vht_cap.vht_supported &&
+ (wireless_mode == WIRELESS_MODE_AC_5G ||
+ wireless_mode == WIRELESS_MODE_AC_24G ||
+ wireless_mode == WIRELESS_MODE_AC_ONLY))
+ rate->flags |= IEEE80211_TX_RC_VHT_MCS;
+ }
+}
+
+static void rtl_get_rate(void *ppriv, struct ieee80211_sta *sta,
+ void *priv_sta,
+ struct ieee80211_tx_rate_control *txrc)
+{
+ struct rtl_priv *rtlpriv = ppriv;
+ struct sk_buff *skb = txrc->skb;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_tx_rate *rates = tx_info->control.rates;
+ __le16 fc = rtl_get_fc(skb);
+ u8 try_per_rate, i, rix;
+ bool not_data = !ieee80211_is_data(fc);
+
+ if (rate_control_send_low(sta, priv_sta, txrc))
+ return;
+
+ rix = _rtl_rc_get_highest_rix(rtlpriv, sta, skb, not_data);
+ try_per_rate = 1;
+ _rtl_rc_rate_set_series(rtlpriv, sta, &rates[0], txrc,
+ try_per_rate, rix, 1, not_data);
+
+ if (!not_data) {
+ for (i = 1; i < 4; i++)
+ _rtl_rc_rate_set_series(rtlpriv, sta, &rates[i],
+ txrc, i, (rix - i), 1,
+ not_data);
+ }
+}
+
+static bool _rtl_tx_aggr_check(struct rtl_priv *rtlpriv,
+ struct rtl_sta_info *sta_entry, u16 tid)
+{
+ struct rtl_mac *mac = rtl_mac(rtlpriv);
+
+ if (mac->act_scanning)
+ return false;
+
+ if (mac->opmode == NL80211_IFTYPE_STATION &&
+ mac->cnt_after_linked < 3)
+ return false;
+
+ if (sta_entry->tids[tid].agg.agg_state == RTL_AGG_STOP)
+ return true;
+
+ return false;
+}
+
+/*mac80211 Rate Control callbacks*/
+static void rtl_tx_status(void *ppriv,
+ struct ieee80211_supported_band *sband,
+ struct ieee80211_sta *sta, void *priv_sta,
+ struct sk_buff *skb)
+{
+ struct rtl_priv *rtlpriv = ppriv;
+ struct rtl_mac *mac = rtl_mac(rtlpriv);
+ struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
+ __le16 fc = rtl_get_fc(skb);
+ struct rtl_sta_info *sta_entry;
+
+ if (!priv_sta || !ieee80211_is_data(fc))
+ return;
+
+ if (rtl_is_special_data(mac->hw, skb, true, true))
+ return;
+
+ if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
+ is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
+ return;
+
+ if (sta) {
+ /* Check if aggregation has to be enabled for this tid */
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+ if ((sta->ht_cap.ht_supported) &&
+ !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
+ if (ieee80211_is_data_qos(fc)) {
+ u8 tid = rtl_get_tid(skb);
+
+ if (_rtl_tx_aggr_check(rtlpriv, sta_entry,
+ tid)) {
+ sta_entry->tids[tid].agg.agg_state =
+ RTL_AGG_PROGRESS;
+ ieee80211_start_tx_ba_session(sta, tid,
+ 5000);
+ }
+ }
+ }
+ }
+}
+
+static void rtl_rate_init(void *ppriv,
+ struct ieee80211_supported_band *sband,
+ struct cfg80211_chan_def *chandef,
+ struct ieee80211_sta *sta, void *priv_sta)
+{
+}
+
+static void rtl_rate_update(void *ppriv,
+ struct ieee80211_supported_band *sband,
+ struct cfg80211_chan_def *chandef,
+ struct ieee80211_sta *sta, void *priv_sta,
+ u32 changed)
+{
+}
+
+static void *rtl_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ return rtlpriv;
+}
+
+static void rtl_rate_free(void *rtlpriv)
+{
+}
+
+static void *rtl_rate_alloc_sta(void *ppriv,
+ struct ieee80211_sta *sta, gfp_t gfp)
+{
+ struct rtl_priv *rtlpriv = ppriv;
+ struct rtl_rate_priv *rate_priv;
+
+ rate_priv = kzalloc(sizeof(*rate_priv), gfp);
+ if (!rate_priv) {
+ pr_err("Unable to allocate private rc structure\n");
+ return NULL;
+ }
+
+ rtlpriv->rate_priv = rate_priv;
+
+ return rate_priv;
+}
+
+static void rtl_rate_free_sta(void *rtlpriv,
+ struct ieee80211_sta *sta, void *priv_sta)
+{
+ struct rtl_rate_priv *rate_priv = priv_sta;
+
+ kfree(rate_priv);
+}
+
+static const struct rate_control_ops rtl_rate_ops = {
+ .name = "rtl_rc",
+ .alloc = rtl_rate_alloc,
+ .free = rtl_rate_free,
+ .alloc_sta = rtl_rate_alloc_sta,
+ .free_sta = rtl_rate_free_sta,
+ .rate_init = rtl_rate_init,
+ .rate_update = rtl_rate_update,
+ .tx_status = rtl_tx_status,
+ .get_rate = rtl_get_rate,
+};
+
+int rtl_rate_control_register(void)
+{
+ return ieee80211_rate_control_register(&rtl_rate_ops);
+}
+
+void rtl_rate_control_unregister(void)
+{
+ ieee80211_rate_control_unregister(&rtl_rate_ops);
+}
diff --git a/drivers/staging/rtlwifi/rc.h b/drivers/staging/rtlwifi/rc.h
new file mode 100644
index 0000000..dcc8520
--- /dev/null
+++ b/drivers/staging/rtlwifi/rc.h
@@ -0,0 +1,49 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2012 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL_RC_H__
+#define __RTL_RC_H__
+
+#define B_MODE_MAX_RIX 3
+#define G_MODE_MAX_RIX 11
+#define A_MODE_MAX_RIX 7
+
+/* in mac80211 mcs0-mcs15 is idx0-idx15*/
+#define N_MODE_MCS7_RIX 7
+#define N_MODE_MCS15_RIX 15
+
+/* in mac80211 vht mcs0-9 is in [3:0], nss is in [:4] */
+#define AC_MODE_MCS7_RIX 7
+#define AC_MODE_MCS8_RIX 8
+#define AC_MODE_MCS9_RIX 9
+
+struct rtl_rate_priv {
+ u8 ht_cap;
+};
+
+int rtl_rate_control_register(void);
+void rtl_rate_control_unregister(void);
+
+#endif
diff --git a/drivers/staging/rtlwifi/regd.c b/drivers/staging/rtlwifi/regd.c
new file mode 100644
index 0000000..e0a3ff8
--- /dev/null
+++ b/drivers/staging/rtlwifi/regd.c
@@ -0,0 +1,469 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2012 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "wifi.h"
+#include "regd.h"
+
+static struct country_code_to_enum_rd allcountries[] = {
+ {COUNTRY_CODE_FCC, "US"},
+ {COUNTRY_CODE_IC, "US"},
+ {COUNTRY_CODE_ETSI, "EC"},
+ {COUNTRY_CODE_SPAIN, "EC"},
+ {COUNTRY_CODE_FRANCE, "EC"},
+ {COUNTRY_CODE_MKK, "JP"},
+ {COUNTRY_CODE_MKK1, "JP"},
+ {COUNTRY_CODE_ISRAEL, "EC"},
+ {COUNTRY_CODE_TELEC, "JP"},
+ {COUNTRY_CODE_MIC, "JP"},
+ {COUNTRY_CODE_GLOBAL_DOMAIN, "JP"},
+ {COUNTRY_CODE_WORLD_WIDE_13, "EC"},
+ {COUNTRY_CODE_TELEC_NETGEAR, "EC"},
+ {COUNTRY_CODE_WORLD_WIDE_13_5G_ALL, "US"},
+};
+
+/*Only these channels all allow active
+ *scan on all world regulatory domains
+ */
+#define RTL819x_2GHZ_CH01_11 \
+ REG_RULE(2412 - 10, 2462 + 10, 40, 0, 20, 0)
+
+/*We enable active scan on these a case
+ *by case basis by regulatory domain
+ */
+#define RTL819x_2GHZ_CH12_13 \
+ REG_RULE(2467 - 10, 2472 + 10, 40, 0, 20,\
+ NL80211_RRF_PASSIVE_SCAN)
+
+#define RTL819x_2GHZ_CH14 \
+ REG_RULE(2484 - 10, 2484 + 10, 40, 0, 20, \
+ NL80211_RRF_PASSIVE_SCAN | \
+ NL80211_RRF_NO_OFDM)
+
+/* 5G chan 36 - chan 64*/
+#define RTL819x_5GHZ_5150_5350 \
+ REG_RULE(5150 - 10, 5350 + 10, 80, 0, 30, 0)
+/* 5G chan 100 - chan 165*/
+#define RTL819x_5GHZ_5470_5850 \
+ REG_RULE(5470 - 10, 5850 + 10, 80, 0, 30, 0)
+/* 5G chan 149 - chan 165*/
+#define RTL819x_5GHZ_5725_5850 \
+ REG_RULE(5725 - 10, 5850 + 10, 80, 0, 30, 0)
+
+#define RTL819x_5GHZ_ALL \
+ (RTL819x_5GHZ_5150_5350, RTL819x_5GHZ_5470_5850)
+
+static const struct ieee80211_regdomain rtl_regdom_11 = {
+ .n_reg_rules = 1,
+ .alpha2 = "99",
+ .reg_rules = {
+ RTL819x_2GHZ_CH01_11,
+ }
+};
+
+static const struct ieee80211_regdomain rtl_regdom_12_13 = {
+ .n_reg_rules = 2,
+ .alpha2 = "99",
+ .reg_rules = {
+ RTL819x_2GHZ_CH01_11,
+ RTL819x_2GHZ_CH12_13,
+ }
+};
+
+static const struct ieee80211_regdomain rtl_regdom_no_midband = {
+ .n_reg_rules = 3,
+ .alpha2 = "99",
+ .reg_rules = {
+ RTL819x_2GHZ_CH01_11,
+ RTL819x_5GHZ_5150_5350,
+ RTL819x_5GHZ_5725_5850,
+ }
+};
+
+static const struct ieee80211_regdomain rtl_regdom_60_64 = {
+ .n_reg_rules = 3,
+ .alpha2 = "99",
+ .reg_rules = {
+ RTL819x_2GHZ_CH01_11,
+ RTL819x_2GHZ_CH12_13,
+ RTL819x_5GHZ_5725_5850,
+ }
+};
+
+static const struct ieee80211_regdomain rtl_regdom_14_60_64 = {
+ .n_reg_rules = 4,
+ .alpha2 = "99",
+ .reg_rules = {
+ RTL819x_2GHZ_CH01_11,
+ RTL819x_2GHZ_CH12_13,
+ RTL819x_2GHZ_CH14,
+ RTL819x_5GHZ_5725_5850,
+ }
+};
+
+static const struct ieee80211_regdomain rtl_regdom_12_13_5g_all = {
+ .n_reg_rules = 4,
+ .alpha2 = "99",
+ .reg_rules = {
+ RTL819x_2GHZ_CH01_11,
+ RTL819x_2GHZ_CH12_13,
+ RTL819x_5GHZ_5150_5350,
+ RTL819x_5GHZ_5470_5850,
+ }
+};
+
+static const struct ieee80211_regdomain rtl_regdom_14 = {
+ .n_reg_rules = 3,
+ .alpha2 = "99",
+ .reg_rules = {
+ RTL819x_2GHZ_CH01_11,
+ RTL819x_2GHZ_CH12_13,
+ RTL819x_2GHZ_CH14,
+ }
+};
+
+static bool _rtl_is_radar_freq(u16 center_freq)
+{
+ return center_freq >= 5260 && center_freq <= 5700;
+}
+
+static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy,
+ enum nl80211_reg_initiator initiator)
+{
+ enum nl80211_band band;
+ struct ieee80211_supported_band *sband;
+ const struct ieee80211_reg_rule *reg_rule;
+ struct ieee80211_channel *ch;
+ unsigned int i;
+
+ for (band = 0; band < NUM_NL80211_BANDS; band++) {
+ if (!wiphy->bands[band])
+ continue;
+
+ sband = wiphy->bands[band];
+
+ for (i = 0; i < sband->n_channels; i++) {
+ ch = &sband->channels[i];
+ if (_rtl_is_radar_freq(ch->center_freq) ||
+ (ch->flags & IEEE80211_CHAN_RADAR))
+ continue;
+ if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
+ reg_rule = freq_reg_info(wiphy,
+ ch->center_freq);
+ if (IS_ERR(reg_rule))
+ continue;
+ /*
+ *If 11d had a rule for this channel ensure
+ *we enable adhoc/beaconing if it allows us to
+ *use it. Note that we would have disabled it
+ *by applying our static world regdomain by
+ *default during init, prior to calling our
+ *regulatory_hint().
+ */
+
+ if (!(reg_rule->flags & NL80211_RRF_NO_IBSS))
+ ch->flags &= ~IEEE80211_CHAN_NO_IBSS;
+ if (!(reg_rule->flags &
+ NL80211_RRF_PASSIVE_SCAN))
+ ch->flags &=
+ ~IEEE80211_CHAN_PASSIVE_SCAN;
+ } else {
+ if (ch->beacon_found)
+ ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN);
+ }
+ }
+ }
+}
+
+/* Allows active scan scan on Ch 12 and 13 */
+static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy,
+ enum nl80211_reg_initiator
+ initiator)
+{
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_channel *ch;
+ const struct ieee80211_reg_rule *reg_rule;
+
+ if (!wiphy->bands[NL80211_BAND_2GHZ])
+ return;
+ sband = wiphy->bands[NL80211_BAND_2GHZ];
+
+ /*
+ *If no country IE has been received always enable active scan
+ *on these channels. This is only done for specific regulatory SKUs
+ */
+ if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
+ ch = &sband->channels[11]; /* CH 12 */
+ if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+ ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+ ch = &sband->channels[12]; /* CH 13 */
+ if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+ ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+ return;
+ }
+
+ /*If a country IE has been received check its rule for this
+ *channel first before enabling active scan. The passive scan
+ *would have been enforced by the initial processing of our
+ *custom regulatory domain.
+ */
+
+ ch = &sband->channels[11]; /* CH 12 */
+ reg_rule = freq_reg_info(wiphy, ch->center_freq);
+ if (!IS_ERR(reg_rule)) {
+ if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
+ if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+ ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+ }
+
+ ch = &sband->channels[12]; /* CH 13 */
+ reg_rule = freq_reg_info(wiphy, ch->center_freq);
+ if (!IS_ERR(reg_rule)) {
+ if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
+ if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+ ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+ }
+}
+
+/*
+ *Always apply Radar/DFS rules on
+ *freq range 5260 MHz - 5700 MHz
+ */
+static void _rtl_reg_apply_radar_flags(struct wiphy *wiphy)
+{
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_channel *ch;
+ unsigned int i;
+
+ if (!wiphy->bands[NL80211_BAND_5GHZ])
+ return;
+
+ sband = wiphy->bands[NL80211_BAND_5GHZ];
+
+ for (i = 0; i < sband->n_channels; i++) {
+ ch = &sband->channels[i];
+ if (!_rtl_is_radar_freq(ch->center_freq))
+ continue;
+
+ /*
+ *We always enable radar detection/DFS on this
+ *frequency range. Additionally we also apply on
+ *this frequency range:
+ *- If STA mode does not yet have DFS supports disable
+ * active scanning
+ *- If adhoc mode does not support DFS yet then disable
+ * adhoc in the frequency.
+ *- If AP mode does not yet support radar detection/DFS
+ *do not allow AP mode
+ */
+ if (!(ch->flags & IEEE80211_CHAN_DISABLED))
+ ch->flags |= IEEE80211_CHAN_RADAR |
+ IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN;
+ }
+}
+
+static void _rtl_reg_apply_world_flags(struct wiphy *wiphy,
+ enum nl80211_reg_initiator initiator,
+ struct rtl_regulatory *reg)
+{
+ _rtl_reg_apply_beaconing_flags(wiphy, initiator);
+ _rtl_reg_apply_active_scan_flags(wiphy, initiator);
+}
+
+static void _rtl_dump_channel_map(struct wiphy *wiphy)
+{
+ enum nl80211_band band;
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_channel *ch;
+ unsigned int i;
+
+ for (band = 0; band < NUM_NL80211_BANDS; band++) {
+ if (!wiphy->bands[band])
+ continue;
+ sband = wiphy->bands[band];
+ for (i = 0; i < sband->n_channels; i++)
+ ch = &sband->channels[i];
+ }
+}
+
+static int _rtl_reg_notifier_apply(struct wiphy *wiphy,
+ struct regulatory_request *request,
+ struct rtl_regulatory *reg)
+{
+ /* We always apply this */
+ _rtl_reg_apply_radar_flags(wiphy);
+
+ switch (request->initiator) {
+ case NL80211_REGDOM_SET_BY_DRIVER:
+ case NL80211_REGDOM_SET_BY_CORE:
+ case NL80211_REGDOM_SET_BY_USER:
+ break;
+ case NL80211_REGDOM_SET_BY_COUNTRY_IE:
+ _rtl_reg_apply_world_flags(wiphy, request->initiator, reg);
+ break;
+ }
+
+ _rtl_dump_channel_map(wiphy);
+
+ return 0;
+}
+
+static const struct ieee80211_regdomain *_rtl_regdomain_select(
+ struct rtl_regulatory *reg)
+{
+ switch (reg->country_code) {
+ case COUNTRY_CODE_FCC:
+ return &rtl_regdom_no_midband;
+ case COUNTRY_CODE_IC:
+ return &rtl_regdom_11;
+ case COUNTRY_CODE_TELEC_NETGEAR:
+ return &rtl_regdom_60_64;
+ case COUNTRY_CODE_ETSI:
+ case COUNTRY_CODE_SPAIN:
+ case COUNTRY_CODE_FRANCE:
+ case COUNTRY_CODE_ISRAEL:
+ return &rtl_regdom_12_13;
+ case COUNTRY_CODE_MKK:
+ case COUNTRY_CODE_MKK1:
+ case COUNTRY_CODE_TELEC:
+ case COUNTRY_CODE_MIC:
+ return &rtl_regdom_14_60_64;
+ case COUNTRY_CODE_GLOBAL_DOMAIN:
+ return &rtl_regdom_14;
+ case COUNTRY_CODE_WORLD_WIDE_13:
+ case COUNTRY_CODE_WORLD_WIDE_13_5G_ALL:
+ return &rtl_regdom_12_13_5g_all;
+ default:
+ return &rtl_regdom_no_midband;
+ }
+}
+
+static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg,
+ struct wiphy *wiphy,
+ void (*reg_notifier)(struct wiphy *wiphy,
+ struct regulatory_request *
+ request))
+{
+ const struct ieee80211_regdomain *regd;
+
+ wiphy->reg_notifier = reg_notifier;
+
+ wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
+ wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG;
+ wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS;
+ regd = _rtl_regdomain_select(reg);
+ wiphy_apply_custom_regulatory(wiphy, regd);
+ _rtl_reg_apply_radar_flags(wiphy);
+ _rtl_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg);
+ return 0;
+}
+
+static struct country_code_to_enum_rd *_rtl_regd_find_country(u16 countrycode)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(allcountries); i++) {
+ if (allcountries[i].countrycode == countrycode)
+ return &allcountries[i];
+ }
+ return NULL;
+}
+
+static u8 channel_plan_to_country_code(u8 channelplan)
+{
+ switch (channelplan) {
+ case 0x20:
+ case 0x21:
+ return COUNTRY_CODE_WORLD_WIDE_13;
+ case 0x22:
+ return COUNTRY_CODE_IC;
+ case 0x25:
+ return COUNTRY_CODE_ETSI;
+ case 0x32:
+ return COUNTRY_CODE_TELEC_NETGEAR;
+ case 0x41:
+ return COUNTRY_CODE_GLOBAL_DOMAIN;
+ case 0x7f:
+ return COUNTRY_CODE_WORLD_WIDE_13_5G_ALL;
+ default:
+ return COUNTRY_CODE_MAX; /*Error*/
+ }
+}
+
+int rtl_regd_init(struct ieee80211_hw *hw,
+ void (*reg_notifier)(struct wiphy *wiphy,
+ struct regulatory_request *request))
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct wiphy *wiphy = hw->wiphy;
+ struct country_code_to_enum_rd *country = NULL;
+
+ if (!wiphy || !&rtlpriv->regd)
+ return -EINVAL;
+
+ /* init country_code from efuse channel plan */
+ rtlpriv->regd.country_code =
+ channel_plan_to_country_code(rtlpriv->efuse.channel_plan);
+
+ RT_TRACE(rtlpriv, COMP_REGD, DBG_DMESG,
+ "rtl: EEPROM regdomain: 0x%0x country code: %d\n",
+ rtlpriv->efuse.channel_plan, rtlpriv->regd.country_code);
+
+ if (rtlpriv->regd.country_code >= COUNTRY_CODE_MAX) {
+ RT_TRACE(rtlpriv, COMP_REGD, DBG_DMESG,
+ "rtl: EEPROM indicates invalid country code, world wide 13 should be used\n");
+
+ rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13;
+ }
+
+ country = _rtl_regd_find_country(rtlpriv->regd.country_code);
+
+ if (country) {
+ rtlpriv->regd.alpha2[0] = country->iso_name[0];
+ rtlpriv->regd.alpha2[1] = country->iso_name[1];
+ } else {
+ rtlpriv->regd.alpha2[0] = '0';
+ rtlpriv->regd.alpha2[1] = '0';
+ }
+
+ RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE,
+ "rtl: Country alpha2 being used: %c%c\n",
+ rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1]);
+
+ _rtl_regd_init_wiphy(&rtlpriv->regd, wiphy, reg_notifier);
+
+ return 0;
+}
+
+void rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
+{
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, "\n");
+
+ _rtl_reg_notifier_apply(wiphy, request, &rtlpriv->regd);
+}
diff --git a/drivers/staging/rtlwifi/regd.h b/drivers/staging/rtlwifi/regd.h
new file mode 100644
index 0000000..5626015
--- /dev/null
+++ b/drivers/staging/rtlwifi/regd.h
@@ -0,0 +1,63 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2012 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL_REGD_H__
+#define __RTL_REGD_H__
+
+/* for kernel 3.14 , both value are changed to IEEE80211_CHAN_NO_IR*/
+#define IEEE80211_CHAN_NO_IBSS IEEE80211_CHAN_NO_IR
+#define IEEE80211_CHAN_PASSIVE_SCAN IEEE80211_CHAN_NO_IR
+
+struct country_code_to_enum_rd {
+ u16 countrycode;
+ const char *iso_name;
+};
+
+enum country_code_type_t {
+ COUNTRY_CODE_FCC = 0,
+ COUNTRY_CODE_IC = 1,
+ COUNTRY_CODE_ETSI = 2,
+ COUNTRY_CODE_SPAIN = 3,
+ COUNTRY_CODE_FRANCE = 4,
+ COUNTRY_CODE_MKK = 5,
+ COUNTRY_CODE_MKK1 = 6,
+ COUNTRY_CODE_ISRAEL = 7,
+ COUNTRY_CODE_TELEC = 8,
+ COUNTRY_CODE_MIC = 9,
+ COUNTRY_CODE_GLOBAL_DOMAIN = 10,
+ COUNTRY_CODE_WORLD_WIDE_13 = 11,
+ COUNTRY_CODE_TELEC_NETGEAR = 12,
+ COUNTRY_CODE_WORLD_WIDE_13_5G_ALL = 13,
+
+ /*add new channel plan above this line */
+ COUNTRY_CODE_MAX
+};
+
+int rtl_regd_init(struct ieee80211_hw *hw,
+ void (*reg_notifier)(struct wiphy *wiphy,
+ struct regulatory_request *request));
+void rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
+
+#endif
diff --git a/drivers/staging/rtlwifi/rtl8822be/Makefile b/drivers/staging/rtlwifi/rtl8822be/Makefile
new file mode 100644
index 0000000..d535ff8
--- /dev/null
+++ b/drivers/staging/rtlwifi/rtl8822be/Makefile
@@ -0,0 +1,7 @@
+rtl8822be-objs := \
+ fw.o \
+ hw.o \
+ led.o \
+ phy.o \
+ sw.o \
+ trx.o
diff --git a/drivers/staging/rtlwifi/rtl8822be/def.h b/drivers/staging/rtlwifi/rtl8822be/def.h
new file mode 100644
index 0000000..7942ddf
--- /dev/null
+++ b/drivers/staging/rtlwifi/rtl8822be/def.h
@@ -0,0 +1,82 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL8822B_DEF_H__
+#define __RTL8822B_DEF_H__
+
+#define RX_DESC_NUM_8822BE 512
+
+#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
+#define HAL_PRIME_CHNL_OFFSET_LOWER 1
+#define HAL_PRIME_CHNL_OFFSET_UPPER 2
+
+#define RX_MPDU_QUEUE 0
+
+#define IS_HT_RATE(_rate) (_rate >= DESC_RATEMCS0)
+#define IS_CCK_RATE(_rate) (_rate >= DESC_RATE1M && _rate <= DESC_RATE11M)
+#define IS_OFDM_RATE(_rate) (_rate >= DESC_RATE6M && _rate <= DESC_RATE54M)
+#define IS_1T_RATE(_rate) \
+ ((_rate >= DESC_RATE1M && _rate <= DESC_RATEMCS7) || \
+ (_rate >= DESC_RATEVHT1SS_MCS0 && _rate <= DESC_RATEVHT1SS_MCS9))
+#define IS_2T_RATE(_rate) \
+ ((_rate >= DESC_RATEMCS8 && _rate <= DESC_RATEMCS15) || \
+ (_rate >= DESC_RATEVHT2SS_MCS0 && _rate <= DESC_RATEVHT2SS_MCS9))
+
+#define IS_1T_RATESEC(_rs) \
+ ((_rs == CCK) || (_rs == OFDM) || (_rs == HT_MCS0_MCS7) || \
+ (_rs == VHT_1SSMCS0_1SSMCS9))
+#define IS_2T_RATESEC(_rs) \
+ ((_rs == HT_MCS8_MCS15) || (_rs == VHT_2SSMCS0_2SSMCS9))
+
+enum rx_packet_type {
+ NORMAL_RX,
+ C2H_PACKET,
+};
+
+enum rtl_desc_qsel {
+ QSLT_BK = 0x2,
+ QSLT_BE = 0x0,
+ QSLT_VI = 0x5,
+ QSLT_VO = 0x7,
+ QSLT_BEACON = 0x10,
+ QSLT_HIGH = 0x11,
+ QSLT_MGNT = 0x12,
+ QSLT_CMD = 0x13,
+};
+
+enum vht_data_sc {
+ VHT_DATA_SC_DONOT_CARE = 0,
+ VHT_DATA_SC_20_UPPER_OF_80MHZ = 1,
+ VHT_DATA_SC_20_LOWER_OF_80MHZ = 2,
+ VHT_DATA_SC_20_UPPERST_OF_80MHZ = 3,
+ VHT_DATA_SC_20_LOWEST_OF_80MHZ = 4,
+ VHT_DATA_SC_20_RECV1 = 5,
+ VHT_DATA_SC_20_RECV2 = 6,
+ VHT_DATA_SC_20_RECV3 = 7,
+ VHT_DATA_SC_20_RECV4 = 8,
+ VHT_DATA_SC_40_UPPER_OF_80MHZ = 9,
+ VHT_DATA_SC_40_LOWER_OF_80MHZ = 10,
+};
+#endif
diff --git a/drivers/staging/rtlwifi/rtl8822be/fw.c b/drivers/staging/rtlwifi/rtl8822be/fw.c
new file mode 100644
index 0000000..8e24da1
--- /dev/null
+++ b/drivers/staging/rtlwifi/rtl8822be/fw.c
@@ -0,0 +1,968 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../pci.h"
+#include "../base.h"
+#include "reg.h"
+#include "def.h"
+#include "fw.h"
+
+static bool _rtl8822be_check_fw_read_last_h2c(struct ieee80211_hw *hw,
+ u8 boxnum)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 val_hmetfr;
+ bool result = false;
+
+ val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR_8822B);
+ if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
+ result = true;
+ return result;
+}
+
+static void _rtl8822be_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id,
+ u32 cmd_len, u8 *cmdbuffer)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ u8 boxnum;
+ u16 box_reg = 0, box_extreg = 0;
+ u8 u1b_tmp;
+ bool isfw_read;
+ u8 buf_index = 0;
+ bool bwrite_success = false;
+ u8 wait_h2c_limmit = 100;
+ u8 boxcontent[4], boxextcontent[4];
+ u32 h2c_waitcounter = 0;
+ unsigned long flag;
+ u8 idx;
+
+ /* 1. Prevent race condition in setting H2C cmd.
+ * (copy from MgntActSet_RF_State().)
+ */
+ while (true) {
+ spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
+ if (rtlhal->h2c_setinprogress) {
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+ "H2C set in progress! wait..H2C_ID=%d.\n",
+ element_id);
+
+ while (rtlhal->h2c_setinprogress) {
+ spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
+ flag);
+ h2c_waitcounter++;
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+ "Wait 100 us (%d times)...\n",
+ h2c_waitcounter);
+ udelay(100);
+
+ if (h2c_waitcounter > 1000)
+ return;
+ spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
+ flag);
+ }
+ spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
+ } else {
+ rtlhal->h2c_setinprogress = true;
+ spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
+ break;
+ }
+ }
+
+ while (!bwrite_success) {
+ /* 2. Find the last BOX number which has been writen. */
+ boxnum = rtlhal->last_hmeboxnum;
+ switch (boxnum) {
+ case 0:
+ box_reg = REG_HMEBOX0_8822B;
+ box_extreg = REG_HMEBOX_E0_8822B;
+ break;
+ case 1:
+ box_reg = REG_HMEBOX1_8822B;
+ box_extreg = REG_HMEBOX_E1_8822B;
+ break;
+ case 2:
+ box_reg = REG_HMEBOX2_8822B;
+ box_extreg = REG_HMEBOX_E2_8822B;
+ break;
+ case 3:
+ box_reg = REG_HMEBOX3_8822B;
+ box_extreg = REG_HMEBOX_E3_8822B;
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
+ "switch case not process\n");
+ break;
+ }
+
+ /* 3. Check if the box content is empty. */
+ u1b_tmp = rtl_read_byte(rtlpriv, REG_CR_8822B);
+
+ if (u1b_tmp == 0xea) {
+ if (rtl_read_byte(rtlpriv, REG_TXDMA_STATUS_8822B) ==
+ 0xea ||
+ rtl_read_byte(rtlpriv, REG_TXPKT_EMPTY_8822B) ==
+ 0xea)
+ rtl_write_byte(rtlpriv, REG_SYS_CFG1_8822B + 3,
+ 0xff);
+
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+ "REG_CR is unavaliable\n");
+ break;
+ }
+
+ wait_h2c_limmit = 100;
+ isfw_read = _rtl8822be_check_fw_read_last_h2c(hw, boxnum);
+ while (!isfw_read) {
+ wait_h2c_limmit--;
+ if (wait_h2c_limmit == 0) {
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_WARNING,
+ "Wait too long for FW clear MB%d!!!\n",
+ boxnum);
+ break;
+ }
+ udelay(10);
+ isfw_read =
+ _rtl8822be_check_fw_read_last_h2c(hw, boxnum);
+ u1b_tmp = rtl_read_byte(rtlpriv, 0x130);
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+ "Waiting for FW clear MB%d!!! 0x130 = %2x\n",
+ boxnum, u1b_tmp);
+ }
+
+ /* If Fw has not read the last H2C cmd,
+ * break and give up this H2C.
+ */
+ if (!isfw_read) {
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+ "Write H2C reg BOX[%d] fail,Fw don't read.\n",
+ boxnum);
+ break;
+ }
+ /* 4. Fill the H2C cmd into box */
+ memset(boxcontent, 0, sizeof(boxcontent));
+ memset(boxextcontent, 0, sizeof(boxextcontent));
+ boxcontent[0] = element_id;
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+ "Write element_id box_reg(%4x) = %2x\n", box_reg,
+ element_id);
+
+ switch (cmd_len) {
+ case 1:
+ case 2:
+ case 3:
+ /*boxcontent[0] &= ~(BIT(7));*/
+ memcpy((u8 *)(boxcontent) + 1, cmdbuffer + buf_index,
+ cmd_len);
+
+ for (idx = 0; idx < 4; idx++) {
+ rtl_write_byte(rtlpriv, box_reg + idx,
+ boxcontent[idx]);
+ }
+ break;
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ /*boxcontent[0] |= (BIT(7));*/
+ memcpy((u8 *)(boxextcontent), cmdbuffer + buf_index + 3,
+ cmd_len - 3);
+ memcpy((u8 *)(boxcontent) + 1, cmdbuffer + buf_index,
+ 3);
+
+ for (idx = 0; idx < 4; idx++) {
+ rtl_write_byte(rtlpriv, box_extreg + idx,
+ boxextcontent[idx]);
+ }
+
+ for (idx = 0; idx < 4; idx++) {
+ rtl_write_byte(rtlpriv, box_reg + idx,
+ boxcontent[idx]);
+ }
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
+ "switch case not process\n");
+ break;
+ }
+
+ bwrite_success = true;
+
+ rtlhal->last_hmeboxnum = boxnum + 1;
+ if (rtlhal->last_hmeboxnum == 4)
+ rtlhal->last_hmeboxnum = 0;
+
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+ "pHalData->last_hmeboxnum = %d\n",
+ rtlhal->last_hmeboxnum);
+ }
+
+ spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
+ rtlhal->h2c_setinprogress = false;
+ spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
+
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
+}
+
+void rtl8822be_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, u32 cmd_len,
+ u8 *cmdbuffer)
+{
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 tmp_cmdbuf[8];
+
+ if (!rtlhal->fw_ready) {
+ WARN_ONCE(true,
+ "return H2C cmd because of Fw download fail!!!\n");
+ return;
+ }
+
+ memset(tmp_cmdbuf, 0, 8);
+ memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
+
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
+ "h2c cmd: len=%d %02X%02X%02X%02X %02X%02X%02X%02X\n", cmd_len,
+ tmp_cmdbuf[2], tmp_cmdbuf[1], tmp_cmdbuf[0], element_id,
+ tmp_cmdbuf[6], tmp_cmdbuf[5], tmp_cmdbuf[4], tmp_cmdbuf[3]);
+
+ _rtl8822be_fill_h2c_command(hw, element_id, cmd_len, tmp_cmdbuf);
+}
+
+void rtl8822be_set_default_port_id_cmd(struct ieee80211_hw *hw)
+{
+ u8 h2c_set_default_port_id[H2C_DEFAULT_PORT_ID_LEN];
+
+ SET_H2CCMD_DFTPID_PORT_ID(h2c_set_default_port_id, 0);
+ SET_H2CCMD_DFTPID_MAC_ID(h2c_set_default_port_id, 0);
+
+ rtl8822be_fill_h2c_cmd(hw, H2C_8822B_DEFAULT_PORT_ID,
+ H2C_DEFAULT_PORT_ID_LEN,
+ h2c_set_default_port_id);
+}
+
+void rtl8822be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 u1_h2c_set_pwrmode[H2C_8822B_PWEMODE_LENGTH] = {0};
+ static u8 prev_h2c[H2C_8822B_PWEMODE_LENGTH] = {0};
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ u8 rlbm, power_state = 0, byte5 = 0;
+ u8 awake_intvl; /* DTIM = (awake_intvl - 1) */
+ u8 smart_ps = 0;
+ struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
+ bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ?
+ btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false);
+ bool bt_lps_on = (rtlpriv->cfg->ops->get_btc_status() ?
+ btc_ops->btc_is_bt_lps_on(rtlpriv) : false);
+
+ memset(u1_h2c_set_pwrmode, 0, H2C_8822B_PWEMODE_LENGTH);
+
+ if (bt_ctrl_lps)
+ mode = (bt_lps_on ? FW_PS_MIN_MODE : FW_PS_ACTIVE_MODE);
+
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n",
+ mode, bt_ctrl_lps);
+
+ switch (mode) {
+ case FW_PS_MIN_MODE:
+ rlbm = 0;
+ awake_intvl = 2;
+ smart_ps = ppsc->smart_ps;
+ break;
+ case FW_PS_MAX_MODE:
+ rlbm = 1;
+ awake_intvl = 2;
+ smart_ps = ppsc->smart_ps;
+ break;
+ case FW_PS_DTIM_MODE:
+ rlbm = 2;
+ awake_intvl = ppsc->reg_max_lps_awakeintvl;
+ /*
+ * hw->conf.ps_dtim_period or mac->vif->bss_conf.dtim_period
+ * is only used in swlps.
+ */
+ smart_ps = ppsc->smart_ps;
+ break;
+ case FW_PS_ACTIVE_MODE:
+ rlbm = 0;
+ awake_intvl = 1;
+ break;
+ default:
+ rlbm = 2;
+ awake_intvl = 4;
+ smart_ps = ppsc->smart_ps;
+ break;
+ }
+
+ if (rtlpriv->mac80211.p2p) {
+ awake_intvl = 2;
+ rlbm = 1;
+ }
+
+ if (mode == FW_PS_ACTIVE_MODE) {
+ byte5 = 0x40;
+ power_state = FW_PWR_STATE_ACTIVE;
+ } else {
+ if (bt_ctrl_lps) {
+ byte5 = btc_ops->btc_get_lps_val(rtlpriv);
+ power_state = btc_ops->btc_get_rpwm_val(rtlpriv);
+
+ if ((rlbm == 2) && (byte5 & BIT(4))) {
+ /* Keep awake interval to 1 to prevent from
+ * decreasing coex performance
+ */
+ awake_intvl = 2;
+ rlbm = 2;
+ }
+ smart_ps = 0;
+ } else {
+ byte5 = 0x40;
+ power_state = FW_PWR_STATE_RF_OFF;
+ }
+ }
+
+ SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
+ SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
+ SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, smart_ps);
+ SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode, awake_intvl);
+ SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
+ SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
+ SET_H2CCMD_PWRMODE_PARM_BYTE5(u1_h2c_set_pwrmode, byte5);
+
+ RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
+ "rtl8822be_set_fw_pwrmode(): u1_h2c_set_pwrmode\n",
+ u1_h2c_set_pwrmode, H2C_8822B_PWEMODE_LENGTH);
+ if (rtlpriv->cfg->ops->get_btc_status())
+ btc_ops->btc_record_pwr_mode(rtlpriv, u1_h2c_set_pwrmode,
+ H2C_8822B_PWEMODE_LENGTH);
+
+ if (!memcmp(prev_h2c, u1_h2c_set_pwrmode, H2C_8822B_PWEMODE_LENGTH))
+ return;
+ memcpy(prev_h2c, u1_h2c_set_pwrmode, H2C_8822B_PWEMODE_LENGTH);
+
+ rtl8822be_set_default_port_id_cmd(hw);
+ rtl8822be_fill_h2c_cmd(hw, H2C_8822B_SETPWRMODE,
+ H2C_8822B_PWEMODE_LENGTH, u1_h2c_set_pwrmode);
+}
+
+void rtl8822be_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus)
+{
+ u8 parm[4] = {0, 0, 0, 0};
+ /* parm[0]: bit0=0-->Disconnect, bit0=1-->Connect
+ * bit1=0-->update Media Status to MACID
+ * bit1=1-->update Media Status from MACID to MACID_End
+ * parm[1]: MACID, if this is INFRA_STA, MacID = 0
+ * parm[2]: MACID_End
+ * parm[3]: bit2-0: port ID
+ */
+
+ SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, mstatus);
+ SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
+
+ rtl8822be_fill_h2c_cmd(hw, H2C_8822B_MSRRPT, 4, parm);
+}
+
+static bool _rtl8822be_send_bcn_or_cmd_packet(struct ieee80211_hw *hw,
+ struct sk_buff *skb, u8 hw_queue)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl8192_tx_ring *ring;
+ struct rtl_tx_desc *pdesc;
+ struct rtl_tx_buffer_desc *pbd_desc;
+ unsigned long flags;
+ struct sk_buff *pskb = NULL;
+ u8 *pdesc_or_bddesc;
+ dma_addr_t dma_addr;
+
+ if (hw_queue != BEACON_QUEUE && hw_queue != H2C_QUEUE)
+ return false;
+
+ ring = &rtlpci->tx_ring[hw_queue];
+
+ spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
+
+ if (hw_queue == BEACON_QUEUE) {
+ pdesc = &ring->desc[0];
+ pbd_desc = &ring->buffer_desc[0];
+ pdesc_or_bddesc = (u8 *)pbd_desc;
+
+ /* free previous beacon queue */
+ pskb = __skb_dequeue(&ring->queue);
+
+ if (!pskb)
+ goto free_prev_skb_done;
+
+ dma_addr = rtlpriv->cfg->ops->get_desc(
+ hw, (u8 *)pbd_desc, true, HW_DESC_TXBUFF_ADDR);
+
+ pci_unmap_single(rtlpci->pdev, dma_addr, skb->len,
+ PCI_DMA_TODEVICE);
+ kfree_skb(pskb);
+
+free_prev_skb_done:
+ ;
+
+ } else { /* hw_queue == TXCMD_QUEUE */
+ if (rtlpriv->cfg->ops->get_available_desc(hw, hw_queue) == 0) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ "get_available_desc fail hw_queue=%d\n",
+ hw_queue);
+ spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock,
+ flags);
+ return false;
+ }
+
+ pdesc = &ring->desc[ring->cur_tx_wp];
+ pbd_desc = &ring->buffer_desc[ring->cur_tx_wp];
+ pdesc_or_bddesc = (u8 *)pdesc;
+ }
+
+ rtlpriv->cfg->ops->fill_tx_special_desc(hw, (u8 *)pdesc, (u8 *)pbd_desc,
+ skb, hw_queue);
+
+ __skb_queue_tail(&ring->queue, skb);
+
+ rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc_or_bddesc, true,
+ HW_DESC_OWN, (u8 *)&hw_queue);
+
+ spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+
+ rtlpriv->cfg->ops->tx_polling(hw, hw_queue);
+
+ return true;
+}
+
+bool rtl8822b_halmac_cb_write_data_rsvd_page(struct rtl_priv *rtlpriv, u8 *buf,
+ u32 size)
+{
+ struct sk_buff *skb = NULL;
+ u8 u1b_tmp;
+ int count;
+
+ skb = dev_alloc_skb(size);
+ memcpy((u8 *)skb_put(skb, size), buf, size);
+
+ if (!_rtl8822be_send_bcn_or_cmd_packet(rtlpriv->hw, skb, BEACON_QUEUE))
+ return false;
+
+ /* These code isn't actually need, because halmac will check
+ * BCN_VALID
+ */
+
+ /* Polling Beacon Queue to send Beacon */
+ u1b_tmp = rtl_read_byte(rtlpriv, REG_RX_RXBD_NUM_8822B + 1);
+ count = 0;
+ while ((count < 20) && (u1b_tmp & BIT(4))) {
+ count++;
+ udelay(10);
+ u1b_tmp = rtl_read_byte(rtlpriv, REG_RX_RXBD_NUM_8822B + 1);
+ }
+
+ if (count >= 20)
+ pr_err("%s polling beacon fail\n", __func__);
+
+ return true;
+}
+
+bool rtl8822b_halmac_cb_write_data_h2c(struct rtl_priv *rtlpriv, u8 *buf,
+ u32 size)
+{
+ struct sk_buff *skb = NULL;
+
+ /* without GFP_DMA, pci_map_single() may not work */
+ skb = __netdev_alloc_skb(NULL, size, GFP_ATOMIC | GFP_DMA);
+ memcpy((u8 *)skb_put(skb, size), buf, size);
+
+ return _rtl8822be_send_bcn_or_cmd_packet(rtlpriv->hw, skb, H2C_QUEUE);
+}
+
+/* Rsvd page HALMAC_RSVD_DRV_PGNUM_8822B occupies 16 page (2048 byte) */
+#define BEACON_PG 0 /* ->1 */
+#define PSPOLL_PG 2
+#define NULL_PG 3
+#define PROBERSP_PG 4 /* ->5 */
+#define QOS_NULL_PG 6
+#define BT_QOS_NULL_PG 7
+
+#define TOTAL_RESERVED_PKT_LEN 1024
+
+static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {/* page size = 128 */
+ /* page 0 beacon */
+ 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
+ 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65,
+ 0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B,
+ 0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06,
+ 0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32,
+ 0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C,
+ 0x09, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C,
+ 0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50,
+ 0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04,
+ 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00,
+
+ /* page 1 beacon */
+ 0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ /* page 2 ps-poll */
+ 0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B,
+ 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ /* page 3 null */
+ 0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B,
+ 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
+ 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ /* page 4 probe_resp */
+ 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
+ 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
+ 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
+ 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
+ 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
+ 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
+ 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
+ 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
+ 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
+ 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
+ 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ /* page 5 probe_resp */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1A, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ /* page 6 qos null data */
+ 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
+ 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
+ 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1A, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ /* page 7 BT-qos null data */
+ 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
+ 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
+ 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+void rtl8822be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct sk_buff *skb = NULL;
+
+ u32 totalpacketlen;
+ bool rtstatus;
+ u8 u1_rsvd_page_loc[7] = {0};
+ bool b_dlok = false;
+
+ u8 *beacon;
+ u8 *p_pspoll;
+ u8 *nullfunc;
+ u8 *p_probersp;
+ u8 *qosnull;
+ u8 *btqosnull;
+
+ memset(u1_rsvd_page_loc, 0, sizeof(u1_rsvd_page_loc));
+
+ /*---------------------------------------------------------
+ * (1) beacon
+ *---------------------------------------------------------
+ */
+ beacon = &reserved_page_packet[BEACON_PG * 128];
+ SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
+ SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
+
+ /*-------------------------------------------------------
+ * (2) ps-poll
+ *--------------------------------------------------------
+ */
+ p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
+ SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
+ SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
+ SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
+
+ SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1_rsvd_page_loc, PSPOLL_PG);
+
+ /*--------------------------------------------------------
+ * (3) null data
+ *---------------------------------------------------------
+ */
+ nullfunc = &reserved_page_packet[NULL_PG * 128];
+ SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
+ SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
+ SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
+
+ SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1_rsvd_page_loc, NULL_PG);
+
+ /*---------------------------------------------------------
+ * (4) probe response
+ *----------------------------------------------------------
+ */
+ p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
+ SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
+ SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
+ SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
+
+ SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1_rsvd_page_loc, PROBERSP_PG);
+
+ /*---------------------------------------------------------
+ * (5) QoS null data
+ *----------------------------------------------------------
+ */
+ qosnull = &reserved_page_packet[QOS_NULL_PG * 128];
+ SET_80211_HDR_ADDRESS1(qosnull, mac->bssid);
+ SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr);
+ SET_80211_HDR_ADDRESS3(qosnull, mac->bssid);
+
+ SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1_rsvd_page_loc, QOS_NULL_PG);
+
+ /*---------------------------------------------------------
+ * (6) BT QoS null data
+ *----------------------------------------------------------
+ */
+ btqosnull = &reserved_page_packet[BT_QOS_NULL_PG * 128];
+ SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid);
+ SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr);
+ SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid);
+
+ SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1_rsvd_page_loc,
+ BT_QOS_NULL_PG);
+
+ totalpacketlen = TOTAL_RESERVED_PKT_LEN;
+
+ RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
+ "rtl8822be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
+ &reserved_page_packet[0], totalpacketlen);
+ RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
+ "rtl8822be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
+ u1_rsvd_page_loc, 3);
+
+ skb = dev_alloc_skb(totalpacketlen);
+ memcpy((u8 *)skb_put(skb, totalpacketlen), &reserved_page_packet,
+ totalpacketlen);
+
+ rtstatus = _rtl8822be_send_bcn_or_cmd_packet(hw, skb, BEACON_QUEUE);
+
+ if (rtstatus)
+ b_dlok = true;
+
+ if (b_dlok) {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ "Set RSVD page location to Fw.\n");
+ RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C_RSVDPAGE:\n",
+ u1_rsvd_page_loc, 3);
+ rtl8822be_fill_h2c_cmd(hw, H2C_8822B_RSVDPAGE,
+ sizeof(u1_rsvd_page_loc),
+ u1_rsvd_page_loc);
+ } else
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ "Set RSVD page location to Fw FAIL!!!!!!.\n");
+}
+
+/* Should check FW support p2p or not. */
+static void rtl8822be_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw,
+ u8 ctwindow)
+{
+ u8 u1_ctwindow_period[1] = {ctwindow};
+
+ rtl8822be_fill_h2c_cmd(hw, H2C_8822B_P2P_PS_CTW_CMD, 1,
+ u1_ctwindow_period);
+}
+
+void rtl8822be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_p2p_ps_info *p2pinfo = &rtlps->p2p_ps_info;
+ struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
+ u8 i;
+ u16 ctwindow;
+ u32 start_time, tsf_low;
+
+ switch (p2p_ps_state) {
+ case P2P_PS_DISABLE:
+ RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
+ memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
+ break;
+ case P2P_PS_ENABLE:
+ RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
+ /* update CTWindow value. */
+ if (p2pinfo->ctwindow > 0) {
+ p2p_ps_offload->ctwindow_en = 1;
+ ctwindow = p2pinfo->ctwindow;
+ rtl8822be_set_p2p_ctw_period_cmd(hw, ctwindow);
+ }
+ /* hw only support 2 set of NoA */
+ for (i = 0; i < p2pinfo->noa_num; i++) {
+ /* To control the register setting for which NOA*/
+ rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
+ if (i == 0)
+ p2p_ps_offload->noa0_en = 1;
+ else
+ p2p_ps_offload->noa1_en = 1;
+ /* config P2P NoA Descriptor Register */
+ rtl_write_dword(rtlpriv, 0x5E0,
+ p2pinfo->noa_duration[i]);
+ rtl_write_dword(rtlpriv, 0x5E4,
+ p2pinfo->noa_interval[i]);
+
+ /*Get Current TSF value */
+ tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR_8822B);
+
+ start_time = p2pinfo->noa_start_time[i];
+ if (p2pinfo->noa_count_type[i] != 1) {
+ while (start_time <= (tsf_low + (50 * 1024))) {
+ start_time += p2pinfo->noa_interval[i];
+ if (p2pinfo->noa_count_type[i] != 255)
+ p2pinfo->noa_count_type[i]--;
+ }
+ }
+ rtl_write_dword(rtlpriv, 0x5E8, start_time);
+ rtl_write_dword(rtlpriv, 0x5EC,
+ p2pinfo->noa_count_type[i]);
+ }
+ if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) {
+ /* rst p2p circuit */
+ rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST_8822B, BIT(4));
+ p2p_ps_offload->offload_en = 1;
+
+ if (rtlpriv->mac80211.p2p == P2P_ROLE_GO) {
+ p2p_ps_offload->role = 1;
+ p2p_ps_offload->allstasleep = 0;
+ } else {
+ p2p_ps_offload->role = 0;
+ }
+ p2p_ps_offload->discovery = 0;
+ }
+ break;
+ case P2P_PS_SCAN:
+ RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
+ p2p_ps_offload->discovery = 1;
+ break;
+ case P2P_PS_SCAN_DONE:
+ RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
+ p2p_ps_offload->discovery = 0;
+ p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
+ break;
+ default:
+ break;
+ }
+
+ rtl8822be_fill_h2c_cmd(hw, H2C_8822B_P2P_PS_OFFLOAD, 1,
+ (u8 *)p2p_ps_offload);
+}
+
+static
+void rtl8822be_c2h_content_parsing_ext(struct ieee80211_hw *hw,
+ u8 c2h_sub_cmd_id,
+ u8 c2h_cmd_len,
+ u8 *c2h_content_buf)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_halmac_ops *halmac_ops;
+
+ switch (c2h_sub_cmd_id) {
+ case 0x0F:
+ RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
+ "[C2H], C2H_8822BE_TX_REPORT!\n");
+ rtl_tx_report_handler(hw, c2h_content_buf, c2h_cmd_len);
+ break;
+ default:
+ /* indicate c2h pkt + rx desc to halmac */
+ halmac_ops = rtlpriv->halmac.ops;
+ halmac_ops->halmac_c2h_handle(rtlpriv,
+ c2h_content_buf - 24 - 2 - 2,
+ c2h_cmd_len + 24 + 2 + 2);
+ break;
+ }
+}
+
+void rtl8822be_c2h_content_parsing(struct ieee80211_hw *hw, u8 c2h_cmd_id,
+ u8 c2h_cmd_len, u8 *tmp_buf)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
+
+ if (c2h_cmd_id == 0xFF) {
+ rtl8822be_c2h_content_parsing_ext(hw, tmp_buf[0],
+ c2h_cmd_len - 2,
+ tmp_buf + 2);
+ return;
+ }
+
+ switch (c2h_cmd_id) {
+ case C2H_8822B_DBG:
+ RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
+ "[C2H], C2H_8822BE_DBG!!\n");
+ break;
+ case C2H_8822B_TXBF:
+ RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
+ "[C2H], C2H_8822B_TXBF!!\n");
+ break;
+ case C2H_8822B_BT_INFO:
+ RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
+ "[C2H], C2H_8822BE_BT_INFO!!\n");
+ if (rtlpriv->cfg->ops->get_btc_status())
+ btc_ops->btc_btinfo_notify(rtlpriv, tmp_buf,
+ c2h_cmd_len);
+ break;
+ case C2H_8822B_BT_MP:
+ RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
+ "[C2H], C2H_8822BE_BT_MP!!\n");
+ if (rtlpriv->cfg->ops->get_btc_status())
+ btc_ops->btc_btmpinfo_notify(rtlpriv, tmp_buf,
+ c2h_cmd_len);
+ break;
+ default:
+ if (!rtlpriv->phydm.ops->phydm_c2h_content_parsing(
+ rtlpriv, c2h_cmd_id, c2h_cmd_len, tmp_buf))
+ break;
+
+ RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
+ "[C2H], Unknown packet!! CmdId(%#X)!\n", c2h_cmd_id);
+ break;
+ }
+}
+
+void rtl8822be_c2h_packet_handler(struct ieee80211_hw *hw, u8 *buffer, u8 len)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 c2h_cmd_id = 0, c2h_cmd_seq = 0, c2h_cmd_len = 0;
+ u8 *tmp_buf = NULL;
+
+ c2h_cmd_id = buffer[0];
+ c2h_cmd_seq = buffer[1];
+ c2h_cmd_len = len - 2;
+ tmp_buf = buffer + 2;
+
+ RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
+ "[C2H packet], c2hCmdId=0x%x, c2hCmdSeq=0x%x, c2hCmdLen=%d\n",
+ c2h_cmd_id, c2h_cmd_seq, c2h_cmd_len);
+
+ RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_TRACE,
+ "[C2H packet], Content Hex:\n", tmp_buf, c2h_cmd_len);
+
+ switch (c2h_cmd_id) {
+ case C2H_8822B_BT_INFO:
+ case C2H_8822B_BT_MP:
+ rtl_c2hcmd_enqueue(hw, c2h_cmd_id, c2h_cmd_len, tmp_buf);
+ break;
+ default:
+ rtl8822be_c2h_content_parsing(hw, c2h_cmd_id, c2h_cmd_len,
+ tmp_buf);
+ break;
+ }
+}
diff --git a/drivers/staging/rtlwifi/rtl8822be/fw.h b/drivers/staging/rtlwifi/rtl8822be/fw.h
new file mode 100644
index 0000000..3ad7a66
--- /dev/null
+++ b/drivers/staging/rtlwifi/rtl8822be/fw.h
@@ -0,0 +1,198 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL8822B__FW__H__
+#define __RTL8822B__FW__H__
+
+#define USE_OLD_WOWLAN_DEBUG_FW 0
+
+#define H2C_8822B_RSVDPAGE_LOC_LEN 5
+#define H2C_8822B_PWEMODE_LENGTH 7
+#define H2C_8822B_JOINBSSRPT_LENGTH 1
+#define H2C_8822B_AP_OFFLOAD_LENGTH 3
+#define H2C_8822B_WOWLAN_LENGTH 3
+#define H2C_8822B_KEEP_ALIVE_CTRL_LENGTH 3
+#if (USE_OLD_WOWLAN_DEBUG_FW == 0)
+#define H2C_8822B_REMOTE_WAKE_CTRL_LEN 1
+#else
+#define H2C_8822B_REMOTE_WAKE_CTRL_LEN 3
+#endif
+#define H2C_8822B_AOAC_GLOBAL_INFO_LEN 2
+#define H2C_8822B_AOAC_RSVDPAGE_LOC_LEN 7
+#define H2C_DEFAULT_PORT_ID_LEN 2
+
+/* Fw PS state for RPWM.
+ *BIT[2:0] = HW state
+ *BIT[3] = Protocol PS state, 1: register active state, 0: register sleep state
+ *BIT[4] = sub-state
+ */
+#define FW_PS_RF_ON BIT(2)
+#define FW_PS_REGISTER_ACTIVE BIT(3)
+
+#define FW_PS_ACK BIT(6)
+#define FW_PS_TOGGLE BIT(7)
+
+/* 8822B RPWM value*/
+/* BIT[0] = 1: 32k, 0: 40M*/
+#define FW_PS_CLOCK_OFF BIT(0) /* 32k */
+#define FW_PS_CLOCK_ON 0 /* 40M */
+
+#define FW_PS_STATE_MASK (0x0F)
+#define FW_PS_STATE_HW_MASK (0x07)
+#define FW_PS_STATE_INT_MASK (0x3F)
+
+#define FW_PS_STATE(x) (FW_PS_STATE_MASK & (x))
+
+#define FW_PS_STATE_ALL_ON_8822B (FW_PS_CLOCK_ON)
+#define FW_PS_STATE_RF_ON_8822B (FW_PS_CLOCK_ON)
+#define FW_PS_STATE_RF_OFF_8822B (FW_PS_CLOCK_ON)
+#define FW_PS_STATE_RF_OFF_LOW_PWR (FW_PS_CLOCK_OFF)
+
+/* For 8822B H2C PwrMode Cmd ID 5.*/
+#define FW_PWR_STATE_ACTIVE ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE))
+#define FW_PWR_STATE_RF_OFF 0
+
+#define FW_PS_IS_ACK(x) ((x) & FW_PS_ACK)
+
+#define IS_IN_LOW_POWER_STATE_8822B(fw_ps_state) \
+ (FW_PS_STATE(fw_ps_state) == FW_PS_CLOCK_OFF)
+
+#define FW_PWR_STATE_ACTIVE ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE))
+#define FW_PWR_STATE_RF_OFF 0
+
+enum rtl8822b_h2c_cmd {
+ H2C_8822B_RSVDPAGE = 0,
+ H2C_8822B_MSRRPT = 1,
+ H2C_8822B_SCAN = 2,
+ H2C_8822B_KEEP_ALIVE_CTRL = 3,
+ H2C_8822B_DISCONNECT_DECISION = 4,
+#if (USE_OLD_WOWLAN_DEBUG_FW == 1)
+ H2C_8822B_WO_WLAN = 5,
+#endif
+ H2C_8822B_INIT_OFFLOAD = 6,
+#if (USE_OLD_WOWLAN_DEBUG_FW == 1)
+ H2C_8822B_REMOTE_WAKE_CTRL = 7,
+#endif
+ H2C_8822B_AP_OFFLOAD = 8,
+ H2C_8822B_BCN_RSVDPAGE = 9,
+ H2C_8822B_PROBERSP_RSVDPAGE = 10,
+
+ H2C_8822B_SETPWRMODE = 0x20,
+ H2C_8822B_PS_TUNING_PARA = 0x21,
+ H2C_8822B_PS_TUNING_PARA2 = 0x22,
+ H2C_8822B_PS_LPS_PARA = 0x23,
+ H2C_8822B_P2P_PS_OFFLOAD = 024,
+ H2C_8822B_DEFAULT_PORT_ID = 0x2C,
+
+#if (USE_OLD_WOWLAN_DEBUG_FW == 0)
+ H2C_8822B_WO_WLAN = 0x80,
+ H2C_8822B_REMOTE_WAKE_CTRL = 0x81,
+ H2C_8822B_AOAC_GLOBAL_INFO = 0x82,
+ H2C_8822B_AOAC_RSVDPAGE = 0x83,
+#endif
+ H2C_8822B_MACID_CFG = 0x40,
+ H2C_8822B_RSSI_REPORT = 0x42,
+ H2C_8822B_MACID_CFG_3SS = 0x46,
+ /*Not defined CTW CMD for P2P yet*/
+ H2C_8822B_P2P_PS_CTW_CMD = 0x99,
+ MAX_8822B_H2CCMD
+};
+
+enum rtl8822b_c2h_evt {
+ C2H_8822B_DBG = 0x00,
+ C2H_8822B_LB = 0x01,
+ C2H_8822B_TXBF = 0x02,
+ C2H_8822B_TX_REPORT = 0x03,
+ C2H_8822B_BT_INFO = 0x09,
+ C2H_8822B_BT_MP = 0x0B,
+ C2H_8822B_RA_RPT = 0x0C,
+ MAX_8822B_C2HEVENT
+};
+
+/* H2C: 0x20 */
+#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 7, __val)
+#define SET_H2CCMD_PWRMODE_PARM_CLK_REQ(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE(__ph2ccmd, 7, 1, __val)
+#define SET_H2CCMD_PWRMODE_PARM_RLBM(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 1, 0, 4, __val)
+#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 1, 4, 4, __val)
+#define SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 2, 0, 8, __val)
+#define SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 3, 0, 1, __val)
+#define SET_H2CCMD_PWRMODE_PARM_BCN_EARLY_RPT(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 3, 2, 1, __val)
+#define SET_H2CCMD_PWRMODE_PARM_PORT_ID(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 3, 5, 3, __val)
+#define SET_H2CCMD_PWRMODE_PARM_PWR_STATE(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 4, 0, 8, __val)
+#define SET_H2CCMD_PWRMODE_PARM_BYTE5(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 5, 0, 8, __val)
+
+/* H2C: 0x00 */
+#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
+#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 1, 0, 8, __val)
+#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 2, 0, 8, __val)
+#define SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 3, 0, 8, __val)
+#define SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 4, 0, 8, __val)
+
+/* H2C: 0x01 */
+#define SET_H2CCMD_MSRRPT_PARM_OPMODE(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 1, __val)
+#define SET_H2CCMD_MSRRPT_PARM_MACID_IND(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE(__ph2ccmd, 1, 1, __val)
+#define SET_H2CCMD_MSRRPT_PARM_MACID(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE(__ph2ccmd + 1, 0, 8, __val)
+#define SET_H2CCMD_MSRRPT_PARM_MACID_END(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE(__ph2ccmd + 2, 0, 8, __val)
+
+/* H2C: 0x2C */
+#define SET_H2CCMD_DFTPID_PORT_ID(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE(((u8 *)(__ph2ccmd)), 0, 8, (__val))
+#define SET_H2CCMD_DFTPID_MAC_ID(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE(((u8 *)(__ph2ccmd)) + 1, 0, 8, (__val))
+
+void rtl8822be_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, u32 cmd_len,
+ u8 *cmdbuffer);
+void rtl8822be_set_default_port_id_cmd(struct ieee80211_hw *hw);
+void rtl8822be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
+void rtl8822be_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus);
+void rtl8822be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);
+void rtl8822be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state);
+void rtl8822be_c2h_packet_handler(struct ieee80211_hw *hw, u8 *buffer, u8 len);
+void rtl8822be_c2h_content_parsing(struct ieee80211_hw *hw, u8 c2h_cmd_id,
+ u8 c2h_cmd_len, u8 *tmp_buf);
+bool rtl8822b_halmac_cb_write_data_rsvd_page(struct rtl_priv *rtlpriv, u8 *buf,
+ u32 size);
+bool rtl8822b_halmac_cb_write_data_h2c(struct rtl_priv *rtlpriv, u8 *buf,
+ u32 size);
+#endif
diff --git a/drivers/staging/rtlwifi/rtl8822be/hw.c b/drivers/staging/rtlwifi/rtl8822be/hw.c
new file mode 100644
index 0000000..7438600
--- /dev/null
+++ b/drivers/staging/rtlwifi/rtl8822be/hw.c
@@ -0,0 +1,2441 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../efuse.h"
+#include "../base.h"
+#include "../regd.h"
+#include "../cam.h"
+#include "../ps.h"
+#include "../pci.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "fw.h"
+#include "led.h"
+#include "hw.h"
+
+#define LLT_CONFIG 5
+
+u8 rtl_channel5g[CHANNEL_MAX_NUMBER_5G] = {
+ 36, 38, 40, 42, 44, 46, 48, /* Band 1 */
+ 52, 54, 56, 58, 60, 62, 64, /* Band 2 */
+ 100, 102, 104, 106, 108, 110, 112, /* Band 3 */
+ 116, 118, 120, 122, 124, 126, 128, /* Band 3 */
+ 132, 134, 136, 138, 140, 142, 144, /* Band 3 */
+ 149, 151, 153, 155, 157, 159, 161, /* Band 4 */
+ 165, 167, 169, 171, 173, 175, 177}; /* Band 4 */
+u8 rtl_channel5g_80m[CHANNEL_MAX_NUMBER_5G_80M] = {42, 58, 106, 122,
+ 138, 155, 171};
+
+static void _rtl8822be_set_bcn_ctrl_reg(struct ieee80211_hw *hw, u8 set_bits,
+ u8 clear_bits)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtlpci->reg_bcn_ctrl_val |= set_bits;
+ rtlpci->reg_bcn_ctrl_val &= ~clear_bits;
+
+ rtl_write_byte(rtlpriv, REG_BCN_CTRL_8822B,
+ (u8)rtlpci->reg_bcn_ctrl_val);
+}
+
+static void _rtl8822be_stop_tx_beacon(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 tmp;
+
+ tmp = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL_8822B + 2);
+ rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL_8822B + 2, tmp & (~BIT(6)));
+ rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT_8822B + 1, 0x64);
+ tmp = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT_8822B + 2);
+ tmp &= ~(BIT(0));
+ rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT_8822B + 2, tmp);
+}
+
+static void _rtl8822be_resume_tx_beacon(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 tmp;
+
+ tmp = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL_8822B + 2);
+ rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL_8822B + 2, tmp | BIT(6));
+ rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT_8822B + 1, 0xff);
+ tmp = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT_8822B + 2);
+ tmp |= BIT(0);
+ rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT_8822B + 2, tmp);
+}
+
+static void _rtl8822be_enable_bcn_sub_func(struct ieee80211_hw *hw)
+{
+ _rtl8822be_set_bcn_ctrl_reg(hw, 0, BIT(1));
+}
+
+static void _rtl8822be_disable_bcn_sub_func(struct ieee80211_hw *hw)
+{
+ _rtl8822be_set_bcn_ctrl_reg(hw, BIT(1), 0);
+}
+
+static void _rtl8822be_set_fw_clock_on(struct ieee80211_hw *hw, u8 rpwm_val,
+ bool b_need_turn_off_ckk)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ u32 count = 0, isr_regaddr, content;
+ bool b_schedule_timer = b_need_turn_off_ckk;
+
+ if (!rtlhal->fw_ready)
+ return;
+ if (!rtlpriv->psc.fw_current_inpsmode)
+ return;
+
+ while (1) {
+ spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
+ if (rtlhal->fw_clk_change_in_progress) {
+ while (rtlhal->fw_clk_change_in_progress) {
+ spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
+ count++;
+ udelay(100);
+ if (count > 1000)
+ return;
+ spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
+ }
+ spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
+ } else {
+ rtlhal->fw_clk_change_in_progress = false;
+ spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
+ break;
+ }
+ }
+
+ if (IS_IN_LOW_POWER_STATE_8822B(rtlhal->fw_ps_state)) {
+ rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM,
+ (u8 *)(&rpwm_val));
+ if (FW_PS_IS_ACK(rpwm_val)) {
+ isr_regaddr = REG_HISR0_8822B;
+ content = rtl_read_dword(rtlpriv, isr_regaddr);
+ while (!(content & IMR_CPWM) && (count < 500)) {
+ udelay(50);
+ count++;
+ content = rtl_read_dword(rtlpriv, isr_regaddr);
+ }
+
+ if (content & IMR_CPWM) {
+ rtl_write_word(rtlpriv, isr_regaddr, 0x0100);
+ rtlhal->fw_ps_state = FW_PS_STATE_RF_ON_8822B;
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ "Receive CPWM INT!!! PSState = %X\n",
+ rtlhal->fw_ps_state);
+ }
+ }
+
+ spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
+ rtlhal->fw_clk_change_in_progress = false;
+ spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
+ if (b_schedule_timer) {
+ mod_timer(&rtlpriv->works.fw_clockoff_timer,
+ jiffies + MSECS(10));
+ }
+
+ } else {
+ spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
+ rtlhal->fw_clk_change_in_progress = false;
+ spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
+ }
+}
+
+static void _rtl8822be_set_fw_clock_off(struct ieee80211_hw *hw, u8 rpwm_val)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl8192_tx_ring *ring;
+ enum rf_pwrstate rtstate;
+ bool b_schedule_timer = false;
+ u8 queue;
+
+ if (!rtlhal->fw_ready)
+ return;
+ if (!rtlpriv->psc.fw_current_inpsmode)
+ return;
+ if (!rtlhal->allow_sw_to_change_hwclc)
+ return;
+
+ rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, (u8 *)(&rtstate));
+ if (rtstate == ERFOFF || rtlpriv->psc.inactive_pwrstate == ERFOFF)
+ return;
+
+ for (queue = 0; queue < RTL_PCI_MAX_TX_QUEUE_COUNT; queue++) {
+ ring = &rtlpci->tx_ring[queue];
+ if (skb_queue_len(&ring->queue)) {
+ b_schedule_timer = true;
+ break;
+ }
+ }
+
+ if (b_schedule_timer) {
+ mod_timer(&rtlpriv->works.fw_clockoff_timer,
+ jiffies + MSECS(10));
+ return;
+ }
+
+ if (FW_PS_STATE(rtlhal->fw_ps_state) != FW_PS_STATE_RF_OFF_LOW_PWR) {
+ spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
+ if (!rtlhal->fw_clk_change_in_progress) {
+ rtlhal->fw_clk_change_in_progress = true;
+ spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
+ rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val);
+ rtl_write_word(rtlpriv, REG_HISR0_8822B, 0x0100);
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
+ (u8 *)(&rpwm_val));
+ spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
+ rtlhal->fw_clk_change_in_progress = false;
+ spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
+ } else {
+ spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
+ mod_timer(&rtlpriv->works.fw_clockoff_timer,
+ jiffies + MSECS(10));
+ }
+ }
+}
+
+static void _rtl8822be_set_fw_ps_rf_on(struct ieee80211_hw *hw)
+{
+ u8 rpwm_val = 0;
+
+ rpwm_val |= (FW_PS_STATE_RF_OFF_8822B | FW_PS_ACK);
+ _rtl8822be_set_fw_clock_on(hw, rpwm_val, true);
+}
+
+static void _rtl8822be_set_fw_ps_rf_off_low_power(struct ieee80211_hw *hw)
+{
+ u8 rpwm_val = 0;
+
+ rpwm_val |= FW_PS_STATE_RF_OFF_LOW_PWR;
+ _rtl8822be_set_fw_clock_off(hw, rpwm_val);
+}
+
+void rtl8822be_fw_clk_off_timer_callback(unsigned long data)
+{
+ struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
+
+ _rtl8822be_set_fw_ps_rf_off_low_power(hw);
+}
+
+static void _rtl8822be_fwlps_leave(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ bool fw_current_inps = false;
+ u8 rpwm_val = 0, fw_pwrmode = FW_PS_ACTIVE_MODE;
+
+ if (ppsc->low_power_enable) {
+ rpwm_val = (FW_PS_STATE_ALL_ON_8822B | FW_PS_ACK); /* RF on */
+ _rtl8822be_set_fw_clock_on(hw, rpwm_val, false);
+ rtlhal->allow_sw_to_change_hwclc = false;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
+ (u8 *)(&fw_pwrmode));
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
+ (u8 *)(&fw_current_inps));
+ } else {
+ rpwm_val = FW_PS_STATE_ALL_ON_8822B; /* RF on */
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
+ (u8 *)(&rpwm_val));
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
+ (u8 *)(&fw_pwrmode));
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
+ (u8 *)(&fw_current_inps));
+ }
+}
+
+static void _rtl8822be_fwlps_enter(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ bool fw_current_inps = true;
+ u8 rpwm_val;
+
+ if (ppsc->low_power_enable) {
+ rpwm_val = FW_PS_STATE_RF_OFF_LOW_PWR; /* RF off */
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
+ (u8 *)(&fw_current_inps));
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
+ (u8 *)(&ppsc->fwctrl_psmode));
+ rtlhal->allow_sw_to_change_hwclc = true;
+ _rtl8822be_set_fw_clock_off(hw, rpwm_val);
+ } else {
+ rpwm_val = FW_PS_STATE_RF_OFF_8822B; /* RF off */
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
+ (u8 *)(&fw_current_inps));
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
+ (u8 *)(&ppsc->fwctrl_psmode));
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
+ (u8 *)(&rpwm_val));
+ }
+}
+
+void rtl8822be_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ switch (variable) {
+ case HW_VAR_RCR:
+ *((u32 *)(val)) = rtlpci->receive_config;
+ break;
+ case HW_VAR_RF_STATE:
+ *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state;
+ break;
+ case HW_VAR_FWLPS_RF_ON: {
+ enum rf_pwrstate rf_state;
+ u32 val_rcr;
+
+ rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE,
+ (u8 *)(&rf_state));
+ if (rf_state == ERFOFF) {
+ *((bool *)(val)) = true;
+ } else {
+ val_rcr = rtl_read_dword(rtlpriv, REG_RCR_8822B);
+ val_rcr &= 0x00070000;
+ if (val_rcr)
+ *((bool *)(val)) = false;
+ else
+ *((bool *)(val)) = true;
+ }
+ } break;
+ case HW_VAR_FW_PSMODE_STATUS:
+ *((bool *)(val)) = ppsc->fw_current_inpsmode;
+ break;
+ case HW_VAR_CORRECT_TSF: {
+ u64 tsf;
+ u32 *ptsf_low = (u32 *)&tsf;
+ u32 *ptsf_high = ((u32 *)&tsf) + 1;
+
+ *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR_8822B + 4));
+ *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR_8822B);
+
+ *((u64 *)(val)) = tsf;
+
+ } break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
+ "switch case not process %x\n", variable);
+ break;
+ }
+}
+
+static void _rtl8822be_download_rsvd_page(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 tmp_regcr, tmp_reg422;
+ u8 bcnvalid_reg /*, txbc_reg*/;
+ u8 count = 0, dlbcn_count = 0;
+ bool b_recover = false;
+
+ /*Set REG_CR_8822B bit 8. DMA beacon by SW.*/
+ tmp_regcr = rtl_read_byte(rtlpriv, REG_CR_8822B + 1);
+ rtl_write_byte(rtlpriv, REG_CR_8822B + 1, tmp_regcr | BIT(0));
+
+ /* Disable Hw protection for a time which revserd for Hw sending beacon.
+ * Fix download reserved page packet fail
+ * that access collision with the protection time.
+ * 2010.05.11. Added by tynli.
+ */
+ _rtl8822be_set_bcn_ctrl_reg(hw, 0, BIT(3));
+ _rtl8822be_set_bcn_ctrl_reg(hw, BIT(4), 0);
+
+ /* Set FWHW_TXQ_CTRL 0x422[6]=0 to
+ * tell Hw the packet is not a real beacon frame.
+ */
+ tmp_reg422 = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL_8822B + 2);
+ rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL_8822B + 2,
+ tmp_reg422 & (~BIT(6)));
+
+ if (tmp_reg422 & BIT(6))
+ b_recover = true;
+
+ do {
+ /* Clear beacon valid check bit */
+ bcnvalid_reg =
+ rtl_read_byte(rtlpriv, REG_FIFOPAGE_CTRL_2_8822B + 1);
+ bcnvalid_reg = bcnvalid_reg | BIT(7);
+ rtl_write_byte(rtlpriv, REG_FIFOPAGE_CTRL_2_8822B + 1,
+ bcnvalid_reg);
+
+ /* download rsvd page */
+ rtl8822be_set_fw_rsvdpagepkt(hw, false);
+
+ /* check rsvd page download OK. */
+ bcnvalid_reg =
+ rtl_read_byte(rtlpriv, REG_FIFOPAGE_CTRL_2_8822B + 1);
+
+ count = 0;
+ while (!(BIT(7) & bcnvalid_reg) && count < 20) {
+ count++;
+ udelay(50);
+ bcnvalid_reg = rtl_read_byte(
+ rtlpriv, REG_FIFOPAGE_CTRL_2_8822B + 1);
+ }
+
+ dlbcn_count++;
+ } while (!(BIT(7) & bcnvalid_reg) && dlbcn_count < 5);
+
+ if (!(BIT(7) & bcnvalid_reg))
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING,
+ "Download RSVD page failed!\n");
+
+ /* Enable Bcn */
+ _rtl8822be_set_bcn_ctrl_reg(hw, BIT(3), 0);
+ _rtl8822be_set_bcn_ctrl_reg(hw, 0, BIT(4));
+
+ if (b_recover)
+ rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL_8822B + 2,
+ tmp_reg422);
+}
+
+void rtl8822be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_efuse *efuse = rtl_efuse(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+ switch (variable) {
+ case HW_VAR_ETHER_ADDR:
+ rtlpriv->halmac.ops->halmac_set_mac_address(rtlpriv, 0, val);
+ break;
+ case HW_VAR_BASIC_RATE: {
+ u16 b_rate_cfg = ((u16 *)val)[0];
+
+ b_rate_cfg = b_rate_cfg & 0x15f;
+ b_rate_cfg |= 0x01;
+ b_rate_cfg = (b_rate_cfg | 0xd) & (~BIT(1));
+ rtl_write_byte(rtlpriv, REG_RRSR_8822B, b_rate_cfg & 0xff);
+ rtl_write_byte(rtlpriv, REG_RRSR_8822B + 1,
+ (b_rate_cfg >> 8) & 0xff);
+ } break;
+ case HW_VAR_BSSID:
+ rtlpriv->halmac.ops->halmac_set_bssid(rtlpriv, 0, val);
+ break;
+ case HW_VAR_SIFS:
+ rtl_write_byte(rtlpriv, REG_SIFS_8822B + 1, val[0]);
+ rtl_write_byte(rtlpriv, REG_SIFS_TRX_8822B + 1, val[1]);
+
+ rtl_write_byte(rtlpriv, REG_SPEC_SIFS_8822B + 1, val[0]);
+ rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS_8822B + 1, val[0]);
+
+ if (!mac->ht_enable)
+ rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM_8822B,
+ 0x0e0e);
+ else
+ rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM_8822B,
+ *((u16 *)val));
+ break;
+ case HW_VAR_SLOT_TIME: {
+ u8 e_aci;
+
+ RT_TRACE(rtlpriv, COMP_MLME, DBG_TRACE, "HW_VAR_SLOT_TIME %x\n",
+ val[0]);
+
+ rtl_write_byte(rtlpriv, REG_SLOT_8822B, val[0]);
+
+ for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
+ (u8 *)(&e_aci));
+ }
+ } break;
+ case HW_VAR_ACK_PREAMBLE: {
+ u8 reg_tmp;
+ u8 short_preamble = (bool)(*(u8 *)val);
+
+ reg_tmp = (rtlpriv->mac80211.cur_40_prime_sc) << 5;
+ if (short_preamble)
+ reg_tmp |= 0x80;
+ rtl_write_byte(rtlpriv, REG_RRSR_8822B + 2, reg_tmp);
+ rtlpriv->mac80211.short_preamble = short_preamble;
+ } break;
+ case HW_VAR_WPA_CONFIG:
+ rtl_write_byte(rtlpriv, REG_SECCFG_8822B, *((u8 *)val));
+ break;
+ case HW_VAR_AMPDU_FACTOR: {
+ u32 ampdu_len = (*((u8 *)val));
+
+ ampdu_len = (0x2000 << ampdu_len) - 1;
+ rtl_write_dword(rtlpriv, REG_AMPDU_MAX_LENGTH_8822B, ampdu_len);
+ } break;
+ case HW_VAR_AC_PARAM: {
+ u8 e_aci = *((u8 *)val);
+
+ if (mac->vif && mac->vif->bss_conf.assoc && !mac->act_scanning)
+ rtl8822be_set_qos(hw, e_aci);
+
+ if (rtlpci->acm_method != EACMWAY2_SW)
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,
+ (u8 *)(&e_aci));
+ } break;
+ case HW_VAR_ACM_CTRL: {
+ u8 e_aci = *((u8 *)val);
+ union aci_aifsn *aifs = (union aci_aifsn *)&mac->ac[0].aifs;
+
+ u8 acm = aifs->f.acm;
+ u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL_8822B);
+
+ acm_ctrl = acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1);
+
+ if (acm) {
+ switch (e_aci) {
+ case AC0_BE:
+ acm_ctrl |= ACMHW_BEQ_EN;
+ break;
+ case AC2_VI:
+ acm_ctrl |= ACMHW_VIQ_EN;
+ break;
+ case AC3_VO:
+ acm_ctrl |= ACMHW_VOQ_EN;
+ break;
+ default:
+ RT_TRACE(
+ rtlpriv, COMP_ERR, DBG_WARNING,
+ "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
+ acm);
+ break;
+ }
+ } else {
+ switch (e_aci) {
+ case AC0_BE:
+ acm_ctrl &= (~ACMHW_BEQ_EN);
+ break;
+ case AC2_VI:
+ acm_ctrl &= (~ACMHW_VIQ_EN);
+ break;
+ case AC3_VO:
+ acm_ctrl &= (~ACMHW_VOQ_EN);
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
+ "switch case not process\n");
+ break;
+ }
+ }
+
+ RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
+ "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n",
+ acm_ctrl);
+ rtl_write_byte(rtlpriv, REG_ACMHWCTRL_8822B, acm_ctrl);
+ } break;
+ case HW_VAR_RCR: {
+ rtl_write_dword(rtlpriv, REG_RCR_8822B, ((u32 *)(val))[0]);
+ rtlpci->receive_config = ((u32 *)(val))[0];
+ } break;
+ case HW_VAR_RETRY_LIMIT: {
+ u8 retry_limit = ((u8 *)(val))[0];
+
+ rtl_write_word(rtlpriv, REG_RETRY_LIMIT_8822B,
+ retry_limit << RETRY_LIMIT_SHORT_SHIFT |
+ retry_limit << RETRY_LIMIT_LONG_SHIFT);
+ } break;
+ case HW_VAR_DUAL_TSF_RST:
+ rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST_8822B,
+ (BIT(0) | BIT(1)));
+ break;
+ case HW_VAR_EFUSE_BYTES:
+ efuse->efuse_usedbytes = *((u16 *)val);
+ break;
+ case HW_VAR_EFUSE_USAGE:
+ efuse->efuse_usedpercentage = *((u8 *)val);
+ break;
+ case HW_VAR_IO_CMD:
+ rtl8822be_phy_set_io_cmd(hw, (*(enum io_type *)val));
+ break;
+ case HW_VAR_SET_RPWM:
+ break;
+ case HW_VAR_H2C_FW_PWRMODE:
+ rtl8822be_set_fw_pwrmode_cmd(hw, (*(u8 *)val));
+ break;
+ case HW_VAR_FW_PSMODE_STATUS:
+ ppsc->fw_current_inpsmode = *((bool *)val);
+ break;
+ case HW_VAR_RESUME_CLK_ON:
+ _rtl8822be_set_fw_ps_rf_on(hw);
+ break;
+ case HW_VAR_FW_LPS_ACTION: {
+ bool b_enter_fwlps = *((bool *)val);
+
+ if (b_enter_fwlps)
+ _rtl8822be_fwlps_enter(hw);
+ else
+ _rtl8822be_fwlps_leave(hw);
+ } break;
+ case HW_VAR_H2C_FW_JOINBSSRPT: {
+ u8 mstatus = (*(u8 *)val);
+
+ if (mstatus == RT_MEDIA_CONNECT) {
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL);
+ _rtl8822be_download_rsvd_page(hw);
+ }
+ rtl8822be_set_default_port_id_cmd(hw);
+ rtl8822be_set_fw_media_status_rpt_cmd(hw, mstatus);
+ } break;
+ case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
+ rtl8822be_set_p2p_ps_offload_cmd(hw, (*(u8 *)val));
+ break;
+ case HW_VAR_AID: {
+ u16 u2btmp;
+
+ u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT_8822B);
+ u2btmp &= 0xC000;
+ rtl_write_word(rtlpriv, REG_BCN_PSR_RPT_8822B,
+ (u2btmp | mac->assoc_id));
+ } break;
+ case HW_VAR_CORRECT_TSF: {
+ u8 btype_ibss = ((u8 *)(val))[0];
+
+ if (btype_ibss)
+ _rtl8822be_stop_tx_beacon(hw);
+
+ _rtl8822be_set_bcn_ctrl_reg(hw, 0, BIT(3));
+
+ rtl_write_dword(rtlpriv, REG_TSFTR_8822B,
+ (u32)(mac->tsf & 0xffffffff));
+ rtl_write_dword(rtlpriv, REG_TSFTR_8822B + 4,
+ (u32)((mac->tsf >> 32) & 0xffffffff));
+
+ _rtl8822be_set_bcn_ctrl_reg(hw, BIT(3), 0);
+
+ if (btype_ibss)
+ _rtl8822be_resume_tx_beacon(hw);
+ } break;
+ case HW_VAR_KEEP_ALIVE: {
+ u8 array[2];
+
+ array[0] = 0xff;
+ array[1] = *((u8 *)val);
+ rtl8822be_fill_h2c_cmd(hw, H2C_8822B_KEEP_ALIVE_CTRL, 2, array);
+ } break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
+ "switch case not process %x\n", variable);
+ break;
+ }
+}
+
+static void _rtl8822be_gen_refresh_led_state(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_led *led0 = &pcipriv->ledctl.sw_led0;
+
+ if (rtlpriv->rtlhal.up_first_time)
+ return;
+
+ if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
+ rtl8822be_sw_led_on(hw, led0);
+ else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT)
+ rtl8822be_sw_led_on(hw, led0);
+ else
+ rtl8822be_sw_led_off(hw, led0);
+}
+
+static bool _rtl8822be_init_trxbd(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ /*struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));*/
+
+ u8 bytetmp;
+ /*u16 wordtmp;*/
+ u32 dwordtmp;
+
+ /* Set TX/RX descriptor physical address -- HI part */
+ if (!rtlpriv->cfg->mod_params->dma64)
+ goto dma64_end;
+
+ rtl_write_dword(rtlpriv, REG_H2CQ_TXBD_DESA_8822B + 4,
+ ((u64)rtlpci->tx_ring[H2C_QUEUE].buffer_desc_dma) >>
+ 32);
+ rtl_write_dword(rtlpriv, REG_BCNQ_TXBD_DESA_8822B + 4,
+ ((u64)rtlpci->tx_ring[BEACON_QUEUE].buffer_desc_dma) >>
+ 32);
+ rtl_write_dword(rtlpriv, REG_MGQ_TXBD_DESA_8822B + 4,
+ (u64)rtlpci->tx_ring[MGNT_QUEUE].buffer_desc_dma >> 32);
+ rtl_write_dword(rtlpriv, REG_VOQ_TXBD_DESA_8822B + 4,
+ (u64)rtlpci->tx_ring[VO_QUEUE].buffer_desc_dma >> 32);
+ rtl_write_dword(rtlpriv, REG_VIQ_TXBD_DESA_8822B + 4,
+ (u64)rtlpci->tx_ring[VI_QUEUE].buffer_desc_dma >> 32);
+ rtl_write_dword(rtlpriv, REG_BEQ_TXBD_DESA_8822B + 4,
+ (u64)rtlpci->tx_ring[BE_QUEUE].buffer_desc_dma >> 32);
+ rtl_write_dword(rtlpriv, REG_BKQ_TXBD_DESA_8822B + 4,
+ (u64)rtlpci->tx_ring[BK_QUEUE].buffer_desc_dma >> 32);
+ rtl_write_dword(rtlpriv, REG_HI0Q_TXBD_DESA_8822B + 4,
+ (u64)rtlpci->tx_ring[HIGH_QUEUE].buffer_desc_dma >> 32);
+
+ rtl_write_dword(rtlpriv, REG_RXQ_RXBD_DESA_8822B + 4,
+ (u64)rtlpci->rx_ring[RX_MPDU_QUEUE].dma >> 32);
+
+dma64_end:
+ /* Set TX/RX descriptor physical address(from OS API). */
+ rtl_write_dword(rtlpriv, REG_H2CQ_TXBD_DESA_8822B,
+ ((u64)rtlpci->tx_ring[H2C_QUEUE].buffer_desc_dma) &
+ DMA_BIT_MASK(32));
+ rtl_write_dword(rtlpriv, REG_BCNQ_TXBD_DESA_8822B,
+ ((u64)rtlpci->tx_ring[BEACON_QUEUE].buffer_desc_dma) &
+ DMA_BIT_MASK(32));
+ rtl_write_dword(rtlpriv, REG_MGQ_TXBD_DESA_8822B,
+ (u64)rtlpci->tx_ring[MGNT_QUEUE].buffer_desc_dma &
+ DMA_BIT_MASK(32));
+ rtl_write_dword(rtlpriv, REG_VOQ_TXBD_DESA_8822B,
+ (u64)rtlpci->tx_ring[VO_QUEUE].buffer_desc_dma &
+ DMA_BIT_MASK(32));
+ rtl_write_dword(rtlpriv, REG_VIQ_TXBD_DESA_8822B,
+ (u64)rtlpci->tx_ring[VI_QUEUE].buffer_desc_dma &
+ DMA_BIT_MASK(32));
+ rtl_write_dword(rtlpriv, REG_BEQ_TXBD_DESA_8822B,
+ (u64)rtlpci->tx_ring[BE_QUEUE].buffer_desc_dma &
+ DMA_BIT_MASK(32));
+ dwordtmp = rtl_read_dword(rtlpriv, REG_BEQ_TXBD_DESA_8822B); /* need? */
+ rtl_write_dword(rtlpriv, REG_BKQ_TXBD_DESA_8822B,
+ (u64)rtlpci->tx_ring[BK_QUEUE].buffer_desc_dma &
+ DMA_BIT_MASK(32));
+ rtl_write_dword(rtlpriv, REG_HI0Q_TXBD_DESA_8822B,
+ (u64)rtlpci->tx_ring[HIGH_QUEUE].buffer_desc_dma &
+ DMA_BIT_MASK(32));
+
+ rtl_write_dword(rtlpriv, REG_RXQ_RXBD_DESA_8822B,
+ (u64)rtlpci->rx_ring[RX_MPDU_QUEUE].dma &
+ DMA_BIT_MASK(32));
+
+ /* Reset R/W point */
+ rtl_write_dword(rtlpriv, REG_BD_RWPTR_CLR_8822B, 0x3fffffff);
+
+ /* Reset the H2CQ R/W point index to 0 */
+ dwordtmp = rtl_read_dword(rtlpriv, REG_H2CQ_CSR_8822B);
+ rtl_write_dword(rtlpriv, REG_H2CQ_CSR_8822B,
+ (dwordtmp | BIT(8) | BIT(16)));
+
+ bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_8822B + 3);
+ rtl_write_byte(rtlpriv, REG_PCIE_CTRL_8822B + 3, bytetmp | 0xF7);
+
+ rtl_write_dword(rtlpriv, REG_INT_MIG_8822B, 0);
+
+ rtl_write_dword(rtlpriv, REG_MCUTST_I_8822B, 0x0);
+
+ rtl_write_word(rtlpriv, REG_H2CQ_TXBD_NUM_8822B,
+ TX_DESC_NUM_8822B |
+ ((RTL8822BE_SEG_NUM << 12) & 0x3000));
+ rtl_write_word(rtlpriv, REG_MGQ_TXBD_NUM_8822B,
+ TX_DESC_NUM_8822B |
+ ((RTL8822BE_SEG_NUM << 12) & 0x3000));
+ rtl_write_word(rtlpriv, REG_VOQ_TXBD_NUM_8822B,
+ TX_DESC_NUM_8822B |
+ ((RTL8822BE_SEG_NUM << 12) & 0x3000));
+ rtl_write_word(rtlpriv, REG_VIQ_TXBD_NUM_8822B,
+ TX_DESC_NUM_8822B |
+ ((RTL8822BE_SEG_NUM << 12) & 0x3000));
+ rtl_write_word(rtlpriv, REG_BEQ_TXBD_NUM_8822B,
+ TX_DESC_NUM_8822B |
+ ((RTL8822BE_SEG_NUM << 12) & 0x3000));
+ rtl_write_word(rtlpriv, REG_VOQ_TXBD_NUM_8822B,
+ TX_DESC_NUM_8822B |
+ ((RTL8822BE_SEG_NUM << 12) & 0x3000));
+ rtl_write_word(rtlpriv, REG_BKQ_TXBD_NUM_8822B,
+ TX_DESC_NUM_8822B |
+ ((RTL8822BE_SEG_NUM << 12) & 0x3000));
+ rtl_write_word(rtlpriv, REG_HI0Q_TXBD_NUM_8822B,
+ TX_DESC_NUM_8822B |
+ ((RTL8822BE_SEG_NUM << 12) & 0x3000));
+ rtl_write_word(rtlpriv, REG_HI1Q_TXBD_NUM_8822B,
+ TX_DESC_NUM_8822B |
+ ((RTL8822BE_SEG_NUM << 12) & 0x3000));
+ rtl_write_word(rtlpriv, REG_HI2Q_TXBD_NUM_8822B,
+ TX_DESC_NUM_8822B |
+ ((RTL8822BE_SEG_NUM << 12) & 0x3000));
+ rtl_write_word(rtlpriv, REG_HI3Q_TXBD_NUM_8822B,
+ TX_DESC_NUM_8822B |
+ ((RTL8822BE_SEG_NUM << 12) & 0x3000));
+ rtl_write_word(rtlpriv, REG_HI4Q_TXBD_NUM_8822B,
+ TX_DESC_NUM_8822B |
+ ((RTL8822BE_SEG_NUM << 12) & 0x3000));
+ rtl_write_word(rtlpriv, REG_HI5Q_TXBD_NUM_8822B,
+ TX_DESC_NUM_8822B |
+ ((RTL8822BE_SEG_NUM << 12) & 0x3000));
+ rtl_write_word(rtlpriv, REG_HI6Q_TXBD_NUM_8822B,
+ TX_DESC_NUM_8822B |
+ ((RTL8822BE_SEG_NUM << 12) & 0x3000));
+ rtl_write_word(rtlpriv, REG_HI7Q_TXBD_NUM_8822B,
+ TX_DESC_NUM_8822B |
+ ((RTL8822BE_SEG_NUM << 12) & 0x3000));
+ /*Rx*/
+ rtl_write_word(rtlpriv, REG_RX_RXBD_NUM_8822B,
+ RX_DESC_NUM_8822BE |
+ ((RTL8822BE_SEG_NUM << 13) & 0x6000) | 0x8000);
+
+ rtl_write_dword(rtlpriv, REG_BD_RWPTR_CLR_8822B, 0XFFFFFFFF);
+
+ _rtl8822be_gen_refresh_led_state(hw);
+
+ return true;
+}
+
+static void _rtl8822be_enable_aspm_back_door(struct ieee80211_hw *hw)
+{
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ u8 tmp;
+
+ if (!ppsc->support_backdoor)
+ return;
+
+ pci_read_config_byte(rtlpci->pdev, 0x70f, &tmp);
+ pci_write_config_byte(rtlpci->pdev, 0x70f, tmp | BIT(7));
+
+ pci_read_config_byte(rtlpci->pdev, 0x719, &tmp);
+ pci_write_config_byte(rtlpci->pdev, 0x719, tmp | BIT(3) | BIT(4));
+}
+
+void rtl8822be_enable_hw_security_config(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 sec_reg_value;
+ u8 tmp;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
+ rtlpriv->sec.pairwise_enc_algorithm,
+ rtlpriv->sec.group_enc_algorithm);
+
+ if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ "not open hw encryption\n");
+ return;
+ }
+
+ sec_reg_value = SCR_TX_ENC_ENABLE | SRC_RX_DEC_ENABLE;
+
+ if (rtlpriv->sec.use_defaultkey) {
+ sec_reg_value |= SCR_TX_USE_DK;
+ sec_reg_value |= SCR_RX_USE_DK;
+ }
+
+ sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
+
+ tmp = rtl_read_byte(rtlpriv, REG_CR_8822B + 1);
+ rtl_write_byte(rtlpriv, REG_CR_8822B + 1, tmp | BIT(1));
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "The SECR-value %x\n",
+ sec_reg_value);
+
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
+}
+
+static bool _rtl8822be_check_pcie_dma_hang(struct rtl_priv *rtlpriv)
+{
+ u8 tmp;
+
+ /* write reg 0x350 Bit[26]=1. Enable debug port. */
+ tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG_V1_8822B + 3);
+ if (!(tmp & BIT(2))) {
+ rtl_write_byte(rtlpriv, REG_DBI_FLAG_V1_8822B + 3,
+ (tmp | BIT(2)));
+ mdelay(100); /* Suggested by DD Justin_tsai. */
+ }
+
+ /* read reg 0x350 Bit[25] if 1 : RX hang
+ * read reg 0x350 Bit[24] if 1 : TX hang
+ */
+ tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG_V1_8822B + 3);
+ if ((tmp & BIT(0)) || (tmp & BIT(1))) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "CheckPcieDMAHang8822BE(): true!!\n");
+ return true;
+ } else {
+ return false;
+ }
+}
+
+static void _rtl8822be_reset_pcie_interface_dma(struct rtl_priv *rtlpriv,
+ bool mac_power_on)
+{
+ u8 tmp;
+ bool release_mac_rx_pause;
+ u8 backup_pcie_dma_pause;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "ResetPcieInterfaceDMA8822BE()\n");
+
+ /* Revise Note: Follow the document "PCIe RX DMA Hang Reset Flow_v03"
+ * released by SD1 Alan.
+ * 2013.05.07, by tynli.
+ */
+
+ /* 1. disable register write lock
+ * write 0x1C bit[1:0] = 2'h0
+ * write 0xCC bit[2] = 1'b1
+ */
+ tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL_8822B);
+ tmp &= ~(BIT(1) | BIT(0));
+ rtl_write_byte(rtlpriv, REG_RSV_CTRL_8822B, tmp);
+ tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2_8822B);
+ tmp |= BIT(2);
+ rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2_8822B, tmp);
+
+ /* 2. Check and pause TRX DMA
+ * write 0x284 bit[18] = 1'b1
+ * write 0x301 = 0xFF
+ */
+ tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL_8822B);
+ if (tmp & BIT(2)) {
+ /* Already pause before the function for another purpose. */
+ release_mac_rx_pause = false;
+ } else {
+ rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL_8822B,
+ (tmp | BIT(2)));
+ release_mac_rx_pause = true;
+ }
+
+ backup_pcie_dma_pause = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_8822B + 1);
+ if (backup_pcie_dma_pause != 0xFF)
+ rtl_write_byte(rtlpriv, REG_PCIE_CTRL_8822B + 1, 0xFF);
+
+ if (mac_power_on) {
+ /* 3. reset TRX function
+ * write 0x100 = 0x00
+ */
+ rtl_write_byte(rtlpriv, REG_CR_8822B, 0);
+ }
+
+ /* 4. Reset PCIe DMA
+ * write 0x003 bit[0] = 0
+ */
+ tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN_8822B + 1);
+ tmp &= ~(BIT(0));
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN_8822B + 1, tmp);
+
+ /* 5. Enable PCIe DMA
+ * write 0x003 bit[0] = 1
+ */
+ tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN_8822B + 1);
+ tmp |= BIT(0);
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN_8822B + 1, tmp);
+
+ if (mac_power_on) {
+ /* 6. enable TRX function
+ * write 0x100 = 0xFF
+ */
+ rtl_write_byte(rtlpriv, REG_CR_8822B, 0xFF);
+
+ /* We should init LLT & RQPN and
+ * prepare Tx/Rx descrptor address later
+ * because MAC function is reset.
+ */
+ }
+
+ /* 7. Restore PCIe autoload down bit
+ * write 0xF8 bit[17] = 1'b1
+ */
+ tmp = rtl_read_byte(rtlpriv, REG_SYS_STATUS2_8822B + 2);
+ tmp |= BIT(1);
+ rtl_write_byte(rtlpriv, REG_SYS_STATUS2_8822B + 2, tmp);
+
+ /* In MAC power on state, BB and RF maybe in ON state,
+ * if we release TRx DMA here
+ * it will cause packets to be started to Tx/Rx,
+ * so we release Tx/Rx DMA later.
+ */
+ if (!mac_power_on) {
+ /* 8. release TRX DMA
+ * write 0x284 bit[18] = 1'b0
+ * write 0x301 = 0x00
+ */
+ if (release_mac_rx_pause) {
+ tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL_8822B);
+ rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL_8822B,
+ (tmp & (~BIT(2))));
+ }
+ rtl_write_byte(rtlpriv, REG_PCIE_CTRL_8822B + 1,
+ backup_pcie_dma_pause);
+ }
+
+ /* 9. lock system register
+ * write 0xCC bit[2] = 1'b0
+ */
+ tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2_8822B);
+ tmp &= ~(BIT(2));
+ rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2_8822B, tmp);
+}
+
+int rtl8822be_hw_init(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ int err = 0;
+ u8 tmp_u1b;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, " Rtl8822BE hw init\n");
+ rtlpriv->rtlhal.being_init_adapter = true;
+ rtlpriv->intf_ops->disable_aspm(hw);
+
+ if (_rtl8822be_check_pcie_dma_hang(rtlpriv)) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "8822be dma hang!\n");
+ _rtl8822be_reset_pcie_interface_dma(rtlpriv,
+ rtlhal->mac_func_enable);
+ rtlhal->mac_func_enable = false;
+ }
+
+ /* init TRX BD */
+ _rtl8822be_init_trxbd(hw);
+
+ /* use halmac to init */
+ err = rtlpriv->halmac.ops->halmac_init_hal(rtlpriv);
+ if (err) {
+ pr_err("halmac_init_hal failed\n");
+ rtlhal->fw_ready = false;
+ return err;
+ }
+
+ rtlhal->fw_ready = true;
+
+ /* have to init after halmac init */
+ tmp_u1b = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_8822B + 2);
+ rtl_write_byte(rtlpriv, REG_PCIE_CTRL_8822B + 2, (tmp_u1b | BIT(4)));
+
+ /*rtl_write_word(rtlpriv, REG_PCIE_CTRL_8822B, 0x8000);*/
+ rtlhal->rx_tag = 0;
+
+ rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ_8822B, 0x4);
+
+ /*fw related variable initialize */
+ ppsc->fw_current_inpsmode = false;
+ rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON_8822B;
+ rtlhal->fw_clk_change_in_progress = false;
+ rtlhal->allow_sw_to_change_hwclc = false;
+ rtlhal->last_hmeboxnum = 0;
+
+ rtlphy->rfreg_chnlval[0] =
+ rtl_get_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK);
+ rtlphy->rfreg_chnlval[1] =
+ rtl_get_rfreg(hw, RF90_PATH_B, RF_CHNLBW, RFREG_OFFSET_MASK);
+ rtlphy->backup_rf_0x1a = (u32)rtl_get_rfreg(hw, RF90_PATH_A, RF_RX_G1,
+ RFREG_OFFSET_MASK);
+ rtlphy->rfreg_chnlval[0] =
+ (rtlphy->rfreg_chnlval[0] & 0xfffff3ff) | BIT(10) | BIT(11);
+
+ rtlhal->mac_func_enable = true;
+
+ if (rtlpriv->cfg->ops->get_btc_status())
+ rtlpriv->btcoexist.btc_ops->btc_power_on_setting(rtlpriv);
+
+ /* reset cam / set security */
+ rtl_cam_reset_all_entry(hw);
+ rtl8822be_enable_hw_security_config(hw);
+
+ /* check RCR/ICV bit */
+ rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV);
+ rtl_write_dword(rtlpriv, REG_RCR_8822B, rtlpci->receive_config);
+
+ /* clear rx ctrl frame */
+ rtl_write_word(rtlpriv, REG_RXFLTMAP1_8822B, 0);
+
+ ppsc->rfpwr_state = ERFON;
+
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
+ _rtl8822be_enable_aspm_back_door(hw);
+ rtlpriv->intf_ops->enable_aspm(hw);
+
+ if (rtlpriv->cfg->ops->get_btc_status())
+ rtlpriv->btcoexist.btc_ops->btc_init_hw_config(rtlpriv);
+ else
+ rtlpriv->btcoexist.btc_ops->btc_init_hw_config_wifi_only(
+ rtlpriv);
+
+ rtlpriv->rtlhal.being_init_adapter = false;
+
+ rtlpriv->phydm.ops->phydm_init_dm(rtlpriv);
+
+ /* clear ISR, and IMR will be on later */
+ rtl_write_dword(rtlpriv, REG_HISR0_8822B,
+ rtl_read_dword(rtlpriv, REG_HISR0_8822B));
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "end of Rtl8822BE hw init %x\n",
+ err);
+ return 0;
+}
+
+static u32 _rtl8822be_read_chip_version(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ /*enum version_8822b version = VERSION_UNKNOWN;*/
+ u32 version;
+ u32 value32;
+
+ rtlphy->rf_type = RF_2T2R;
+
+ value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG1_8822B);
+
+ version = value32;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Chip RF Type: %s\n",
+ (rtlphy->rf_type == RF_2T2R) ? "RF_2T2R" : "RF_1T1R");
+
+ return version;
+}
+
+static int _rtl8822be_set_media_status(struct ieee80211_hw *hw,
+ enum nl80211_iftype type)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 bt_msr = rtl_read_byte(rtlpriv, MSR);
+ enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
+ u8 mode = MSR_NOLINK;
+
+ bt_msr &= 0xfc;
+
+ switch (type) {
+ case NL80211_IFTYPE_UNSPECIFIED:
+ mode = MSR_NOLINK;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ "Set Network type to NO LINK!\n");
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_MESH_POINT:
+ mode = MSR_ADHOC;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ "Set Network type to Ad Hoc!\n");
+ break;
+ case NL80211_IFTYPE_STATION:
+ mode = MSR_INFRA;
+ ledaction = LED_CTL_LINK;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ "Set Network type to STA!\n");
+ break;
+ case NL80211_IFTYPE_AP:
+ mode = MSR_AP;
+ ledaction = LED_CTL_LINK;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ "Set Network type to AP!\n");
+ break;
+ default:
+ pr_err("Network type %d not support!\n", type);
+ return 1;
+ }
+
+ /* MSR_INFRA == Link in infrastructure network;
+ * MSR_ADHOC == Link in ad hoc network;
+ * Therefore, check link state is necessary.
+ *
+ * MSR_AP == AP mode; link state is not cared here.
+ */
+ if (mode != MSR_AP && rtlpriv->mac80211.link_state < MAC80211_LINKED) {
+ mode = MSR_NOLINK;
+ ledaction = LED_CTL_NO_LINK;
+ }
+
+ if (mode == MSR_NOLINK || mode == MSR_INFRA) {
+ _rtl8822be_stop_tx_beacon(hw);
+ _rtl8822be_enable_bcn_sub_func(hw);
+ } else if (mode == MSR_ADHOC || mode == MSR_AP) {
+ _rtl8822be_resume_tx_beacon(hw);
+ _rtl8822be_disable_bcn_sub_func(hw);
+ } else {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ "Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n",
+ mode);
+ }
+
+ rtl_write_byte(rtlpriv, (MSR), bt_msr | mode);
+ rtlpriv->cfg->ops->led_control(hw, ledaction);
+ if (mode == MSR_AP)
+ rtl_write_byte(rtlpriv, REG_BCNTCFG_8822B + 1, 0x00);
+ else
+ rtl_write_byte(rtlpriv, REG_BCNTCFG_8822B + 1, 0x66);
+ return 0;
+}
+
+void rtl8822be_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ u32 reg_rcr = rtlpci->receive_config;
+
+ if (rtlpriv->psc.rfpwr_state != ERFON)
+ return;
+
+ if (check_bssid) {
+ reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(&reg_rcr));
+ _rtl8822be_set_bcn_ctrl_reg(hw, 0, BIT(4));
+ } else if (!check_bssid) {
+ reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
+ _rtl8822be_set_bcn_ctrl_reg(hw, BIT(4), 0);
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(&reg_rcr));
+ }
+}
+
+int rtl8822be_set_network_type(struct ieee80211_hw *hw,
+ enum nl80211_iftype type)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ if (_rtl8822be_set_media_status(hw, type))
+ return -EOPNOTSUPP;
+
+ if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
+ if (type != NL80211_IFTYPE_AP &&
+ type != NL80211_IFTYPE_MESH_POINT)
+ rtl8822be_set_check_bssid(hw, true);
+ } else {
+ rtl8822be_set_check_bssid(hw, false);
+ }
+
+ return 0;
+}
+
+void rtl8822be_set_qos(struct ieee80211_hw *hw, int aci)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtlpriv);
+ u32 ac_param;
+
+ ac_param = rtl_get_hal_edca_param(hw, mac->vif, mac->mode,
+ &mac->edca_param[aci]);
+
+ switch (aci) {
+ case AC1_BK:
+ rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM_8822B, ac_param);
+ break;
+ case AC0_BE:
+ rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM_8822B, ac_param);
+ break;
+ case AC2_VI:
+ rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM_8822B, ac_param);
+ break;
+ case AC3_VO:
+ rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM_8822B, ac_param);
+ break;
+ default:
+ WARN_ONCE(true, "invalid aci: %d !\n", aci);
+ break;
+ }
+}
+
+void rtl8822be_enable_interrupt(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ rtl_write_dword(rtlpriv, REG_HIMR0_8822B,
+ rtlpci->irq_mask[0] & 0xFFFFFFFF);
+ rtl_write_dword(rtlpriv, REG_HIMR1_8822B,
+ rtlpci->irq_mask[1] & 0xFFFFFFFF);
+ rtl_write_dword(rtlpriv, REG_HIMR3_8822B,
+ rtlpci->irq_mask[3] & 0xFFFFFFFF);
+ rtlpci->irq_enabled = true;
+}
+
+void rtl8822be_disable_interrupt(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ rtl_write_dword(rtlpriv, REG_HIMR0_8822B, IMR_DISABLED);
+ rtl_write_dword(rtlpriv, REG_HIMR1_8822B, IMR_DISABLED);
+ rtl_write_dword(rtlpriv, REG_HIMR3_8822B, IMR_DISABLED);
+ rtlpci->irq_enabled = false;
+ /*synchronize_irq(rtlpci->pdev->irq);*/
+}
+
+void rtl8822be_card_disable(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ enum nl80211_iftype opmode;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "RTL8822be card disable\n");
+
+ RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
+
+ mac->link_state = MAC80211_NOLINK;
+ opmode = NL80211_IFTYPE_UNSPECIFIED;
+
+ _rtl8822be_set_media_status(hw, opmode);
+
+ if (rtlpriv->rtlhal.driver_is_goingto_unload ||
+ ppsc->rfoff_reason > RF_CHANGE_BY_PS)
+ rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
+
+ rtlpriv->phydm.ops->phydm_deinit_dm(rtlpriv);
+
+ rtlpriv->halmac.ops->halmac_deinit_hal(rtlpriv);
+
+ /* after power off we should do iqk again */
+ if (!rtlpriv->cfg->ops->get_btc_status())
+ rtlpriv->phy.iqk_initialized = false;
+}
+
+void rtl8822be_interrupt_recognized(struct ieee80211_hw *hw, u32 *p_inta,
+ u32 *p_intb, u32 *p_intc, u32 *p_intd)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ *p_inta =
+ rtl_read_dword(rtlpriv, REG_HISR0_8822B) & rtlpci->irq_mask[0];
+ rtl_write_dword(rtlpriv, REG_HISR0_8822B, *p_inta);
+
+ *p_intb =
+ rtl_read_dword(rtlpriv, REG_HISR1_8822B) & rtlpci->irq_mask[1];
+ rtl_write_dword(rtlpriv, REG_HISR1_8822B, *p_intb);
+
+ *p_intd =
+ rtl_read_dword(rtlpriv, REG_HISR3_8822B) & rtlpci->irq_mask[3];
+ rtl_write_dword(rtlpriv, REG_HISR3_8822B, *p_intd);
+}
+
+void rtl8822be_set_beacon_related_registers(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ u16 bcn_interval, atim_window;
+
+ bcn_interval = mac->beacon_interval;
+ atim_window = 2; /*FIX MERGE */
+ rtl8822be_disable_interrupt(hw);
+ rtl_write_word(rtlpriv, REG_ATIMWND_8822B, atim_window);
+ rtl_write_word(rtlpriv, REG_MBSSID_BCN_SPACE_8822B, bcn_interval);
+ rtl_write_word(rtlpriv, REG_BCNTCFG_8822B, 0x660f);
+ rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK_8822B, 0x18);
+ rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM_8822B, 0x18);
+ rtl_write_byte(rtlpriv, 0x606, 0x30);
+ rtlpci->reg_bcn_ctrl_val |= BIT(3);
+ rtl_write_byte(rtlpriv, REG_BCN_CTRL_8822B,
+ (u8)rtlpci->reg_bcn_ctrl_val);
+}
+
+void rtl8822be_set_beacon_interval(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ u16 bcn_interval = mac->beacon_interval;
+
+ RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, "beacon_interval:%d\n",
+ bcn_interval);
+ rtl_write_word(rtlpriv, REG_MBSSID_BCN_SPACE_8822B, bcn_interval);
+}
+
+void rtl8822be_update_interrupt_mask(struct ieee80211_hw *hw, u32 add_msr,
+ u32 rm_msr)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n",
+ add_msr, rm_msr);
+
+ if (add_msr)
+ rtlpci->irq_mask[0] |= add_msr;
+ if (rm_msr)
+ rtlpci->irq_mask[0] &= (~rm_msr);
+ rtl8822be_disable_interrupt(hw);
+ rtl8822be_enable_interrupt(hw);
+}
+
+static bool _rtl8822be_get_chnl_group(u8 chnl, u8 *group)
+{
+ bool in_24g;
+
+ if (chnl <= 14) {
+ in_24g = true;
+
+ if (chnl >= 1 && chnl <= 2)
+ *group = 0;
+ else if (chnl >= 3 && chnl <= 5)
+ *group = 1;
+ else if (chnl >= 6 && chnl <= 8)
+ *group = 2;
+ else if (chnl >= 9 && chnl <= 11)
+ *group = 3;
+ else if (chnl >= 12 && chnl <= 14)
+ *group = 4;
+ } else {
+ in_24g = false;
+
+ if (chnl >= 36 && chnl <= 42)
+ *group = 0;
+ else if (chnl >= 44 && chnl <= 48)
+ *group = 1;
+ else if (chnl >= 50 && chnl <= 58)
+ *group = 2;
+ else if (chnl >= 60 && chnl <= 64)
+ *group = 3;
+ else if (chnl >= 100 && chnl <= 106)
+ *group = 4;
+ else if (chnl >= 108 && chnl <= 114)
+ *group = 5;
+ else if (chnl >= 116 && chnl <= 122)
+ *group = 6;
+ else if (chnl >= 124 && chnl <= 130)
+ *group = 7;
+ else if (chnl >= 132 && chnl <= 138)
+ *group = 8;
+ else if (chnl >= 140 && chnl <= 144)
+ *group = 9;
+ else if (chnl >= 149 && chnl <= 155)
+ *group = 10;
+ else if (chnl >= 157 && chnl <= 161)
+ *group = 11;
+ else if (chnl >= 165 && chnl <= 171)
+ *group = 12;
+ else if (chnl >= 173 && chnl <= 177)
+ *group = 13;
+ }
+ return in_24g;
+}
+
+static inline bool power_valid(u8 power)
+{
+ if (power <= 63)
+ return true;
+
+ return false;
+}
+
+static inline s8 power_diff(s8 diff)
+{
+ /* bit sign number to 8 bit sign number */
+ if (diff & BIT(3))
+ diff |= 0xF0;
+
+ return diff;
+}
+
+static void _rtl8822be_read_power_value_fromprom(struct ieee80211_hw *hw,
+ struct txpower_info_2g *pwr2g,
+ struct txpower_info_5g *pwr5g,
+ bool autoload_fail, u8 *hwinfo)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 rf, addr = EEPROM_TX_PWR_INX_8822B, group, i = 0;
+ u8 power;
+ s8 diff;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "hal_ReadPowerValueFromPROM8822B(): PROMContent[0x%x]=0x%x\n",
+ (addr + 1), hwinfo[addr + 1]);
+ if (hwinfo[addr + 1] == 0xFF) /*YJ,add,120316*/
+ autoload_fail = true;
+
+ memset(pwr2g, 0, sizeof(struct txpower_info_2g));
+ memset(pwr5g, 0, sizeof(struct txpower_info_5g));
+
+ if (autoload_fail) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "auto load fail : Use Default value!\n");
+ for (rf = 0; rf < MAX_RF_PATH; rf++) {
+ /* 2.4G default value */
+ for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
+ pwr2g->index_cck_base[rf][group] = 0x2D;
+ pwr2g->index_bw40_base[rf][group] = 0x2D;
+ }
+ for (i = 0; i < MAX_TX_COUNT; i++) {
+ if (i == 0) {
+ pwr2g->bw20_diff[rf][0] = 0x02;
+ pwr2g->ofdm_diff[rf][0] = 0x04;
+ } else {
+ pwr2g->bw20_diff[rf][i] = 0xFE;
+ pwr2g->bw40_diff[rf][i] = 0xFE;
+ pwr2g->cck_diff[rf][i] = 0xFE;
+ pwr2g->ofdm_diff[rf][i] = 0xFE;
+ }
+ }
+
+ /*5G default value*/
+ for (group = 0; group < MAX_CHNL_GROUP_5G; group++)
+ pwr5g->index_bw40_base[rf][group] = 0x2A;
+
+ for (i = 0; i < MAX_TX_COUNT; i++) {
+ if (i == 0) {
+ pwr5g->ofdm_diff[rf][0] = 0x04;
+ pwr5g->bw20_diff[rf][0] = 0x00;
+ pwr5g->bw80_diff[rf][0] = 0xFE;
+ pwr5g->bw160_diff[rf][0] = 0xFE;
+ } else {
+ pwr5g->ofdm_diff[rf][i] = 0xFE;
+ pwr5g->bw20_diff[rf][i] = 0xFE;
+ pwr5g->bw40_diff[rf][i] = 0xFE;
+ pwr5g->bw80_diff[rf][i] = 0xFE;
+ pwr5g->bw160_diff[rf][i] = 0xFE;
+ }
+ }
+ }
+ return;
+ }
+
+ rtl_priv(hw)->efuse.txpwr_fromeprom = true;
+
+ for (rf = 0; rf < 2 /*MAX_RF_PATH*/; rf++) {
+ /*2.4G default value*/
+ for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
+ power = hwinfo[addr++];
+ if (power_valid(power))
+ pwr2g->index_cck_base[rf][group] = power;
+ }
+ for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++) {
+ power = hwinfo[addr++];
+ if (power_valid(power))
+ pwr2g->index_bw40_base[rf][group] = power;
+ }
+ for (i = 0; i < MAX_TX_COUNT; i++) {
+ if (i == 0) {
+ pwr2g->bw40_diff[rf][i] = 0;
+
+ diff = (hwinfo[addr] & 0xF0) >> 4;
+ pwr2g->bw20_diff[rf][i] = power_diff(diff);
+
+ diff = hwinfo[addr] & 0x0F;
+ pwr2g->ofdm_diff[rf][i] = power_diff(diff);
+
+ pwr2g->cck_diff[rf][i] = 0;
+
+ addr++;
+ } else {
+ diff = (hwinfo[addr] & 0xF0) >> 4;
+ pwr2g->bw40_diff[rf][i] = power_diff(diff);
+
+ diff = hwinfo[addr] & 0x0F;
+ pwr2g->bw20_diff[rf][i] = power_diff(diff);
+
+ addr++;
+
+ diff = (hwinfo[addr] & 0xF0) >> 4;
+ pwr2g->ofdm_diff[rf][i] = power_diff(diff);
+
+ diff = hwinfo[addr] & 0x0F;
+ pwr2g->cck_diff[rf][i] = power_diff(diff);
+
+ addr++;
+ }
+ }
+
+ /*5G default value*/
+ for (group = 0; group < MAX_CHNL_GROUP_5G; group++) {
+ power = hwinfo[addr++];
+ if (power_valid(power))
+ pwr5g->index_bw40_base[rf][group] = power;
+ }
+
+ for (i = 0; i < MAX_TX_COUNT; i++) {
+ if (i == 0) {
+ pwr5g->bw40_diff[rf][i] = 0;
+
+ diff = (hwinfo[addr] & 0xF0) >> 4;
+ pwr5g->bw20_diff[rf][i] = power_diff(diff);
+
+ diff = hwinfo[addr] & 0x0F;
+ pwr5g->ofdm_diff[rf][i] = power_diff(diff);
+
+ addr++;
+ } else {
+ diff = (hwinfo[addr] & 0xF0) >> 4;
+ pwr5g->bw40_diff[rf][i] = power_diff(diff);
+
+ diff = hwinfo[addr] & 0x0F;
+ pwr5g->bw20_diff[rf][i] = power_diff(diff);
+
+ addr++;
+ }
+ }
+
+ diff = (hwinfo[addr] & 0xF0) >> 4;
+ pwr5g->ofdm_diff[rf][1] = power_diff(diff);
+
+ diff = hwinfo[addr] & 0x0F;
+ pwr5g->ofdm_diff[rf][2] = power_diff(diff);
+
+ addr++;
+
+ diff = hwinfo[addr] & 0x0F;
+ pwr5g->ofdm_diff[rf][3] = power_diff(diff);
+
+ addr++;
+
+ for (i = 0; i < MAX_TX_COUNT; i++) {
+ diff = (hwinfo[addr] & 0xF0) >> 4;
+ pwr5g->bw80_diff[rf][i] = power_diff(diff);
+
+ diff = hwinfo[addr] & 0x0F;
+ pwr5g->bw160_diff[rf][i] = power_diff(diff);
+
+ addr++;
+ }
+ }
+}
+
+static void _rtl8822be_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
+ bool autoload_fail,
+ u8 *hwinfo)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_efuse *efu = rtl_efuse(rtl_priv(hw));
+ struct txpower_info_2g pwr2g;
+ struct txpower_info_5g pwr5g;
+ u8 channel5g[CHANNEL_MAX_NUMBER_5G] = {
+ 36, 38, 40, 42, 44, 46, 48, /* Band 1 */
+ 52, 54, 56, 58, 60, 62, 64, /* Band 2 */
+ 100, 102, 104, 106, 108, 110, 112, /* Band 3 */
+ 116, 118, 120, 122, 124, 126, 128, /* Band 3 */
+ 132, 134, 136, 138, 140, 142, 144, /* Band 3 */
+ 149, 151, 153, 155, 157, 159, 161, /* Band 4 */
+ 165, 167, 169, 171, 173, 175, 177}; /* Band 4 */
+ u8 channel5g_80m[CHANNEL_MAX_NUMBER_5G_80M] = {42, 58, 106, 122,
+ 138, 155, 171};
+ u8 rf, group;
+ u8 i;
+
+ _rtl8822be_read_power_value_fromprom(hw, &pwr2g, &pwr5g, autoload_fail,
+ hwinfo);
+
+ for (rf = 0; rf < MAX_RF_PATH; rf++) {
+ for (i = 0; i < CHANNEL_MAX_NUMBER_2G; i++) {
+ _rtl8822be_get_chnl_group(i + 1, &group);
+
+ if (i == CHANNEL_MAX_NUMBER_2G - 1) {
+ efu->txpwrlevel_cck[rf][i] =
+ pwr2g.index_cck_base[rf][5];
+ efu->txpwrlevel_ht40_1s[rf][i] =
+ pwr2g.index_bw40_base[rf][group];
+ } else {
+ efu->txpwrlevel_cck[rf][i] =
+ pwr2g.index_cck_base[rf][group];
+ efu->txpwrlevel_ht40_1s[rf][i] =
+ pwr2g.index_bw40_base[rf][group];
+ }
+ }
+ for (i = 0; i < CHANNEL_MAX_NUMBER_5G; i++) {
+ _rtl8822be_get_chnl_group(channel5g[i], &group);
+ efu->txpwr_5g_bw40base[rf][i] =
+ pwr5g.index_bw40_base[rf][group];
+ }
+ for (i = 0; i < CHANNEL_MAX_NUMBER_5G_80M; i++) {
+ u8 upper, lower;
+
+ _rtl8822be_get_chnl_group(channel5g_80m[i], &group);
+ upper = pwr5g.index_bw40_base[rf][group];
+ lower = pwr5g.index_bw40_base[rf][group + 1];
+
+ efu->txpwr_5g_bw80base[rf][i] = (upper + lower) / 2;
+ }
+ for (i = 0; i < MAX_TX_COUNT; i++) {
+ efu->txpwr_cckdiff[rf][i] = pwr2g.cck_diff[rf][i];
+ efu->txpwr_legacyhtdiff[rf][i] = pwr2g.ofdm_diff[rf][i];
+ efu->txpwr_ht20diff[rf][i] = pwr2g.bw20_diff[rf][i];
+ efu->txpwr_ht40diff[rf][i] = pwr2g.bw40_diff[rf][i];
+
+ efu->txpwr_5g_ofdmdiff[rf][i] = pwr5g.ofdm_diff[rf][i];
+ efu->txpwr_5g_bw20diff[rf][i] = pwr5g.bw20_diff[rf][i];
+ efu->txpwr_5g_bw40diff[rf][i] = pwr5g.bw40_diff[rf][i];
+ efu->txpwr_5g_bw80diff[rf][i] = pwr5g.bw80_diff[rf][i];
+ }
+ }
+
+ if (!autoload_fail)
+ efu->eeprom_thermalmeter = hwinfo[EEPROM_THERMAL_METER_8822B];
+ else
+ efu->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
+
+ if (efu->eeprom_thermalmeter == 0xff || autoload_fail) {
+ efu->apk_thermalmeterignore = true;
+ efu->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
+ }
+
+ efu->thermalmeter[0] = efu->eeprom_thermalmeter;
+ RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "thermalmeter = 0x%x\n",
+ efu->eeprom_thermalmeter);
+
+ if (!autoload_fail) {
+ efu->eeprom_regulatory =
+ hwinfo[EEPROM_RF_BOARD_OPTION_8822B] & 0x07;
+ if (hwinfo[EEPROM_RF_BOARD_OPTION_8822B] == 0xFF)
+ efu->eeprom_regulatory = 0;
+ } else {
+ efu->eeprom_regulatory = 0;
+ }
+ RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "eeprom_regulatory = 0x%x\n",
+ efu->eeprom_regulatory);
+}
+
+static void _rtl8822be_read_pa_type(struct ieee80211_hw *hw, u8 *hwinfo,
+ bool autoload_fail)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+
+ if (!autoload_fail) {
+ rtlhal->pa_type_2g = hwinfo[EEPROM_2G_5G_PA_TYPE_8822B];
+ rtlhal->lna_type_2g =
+ hwinfo[EEPROM_2G_LNA_TYPE_GAIN_SEL_AB_8822B];
+ if (rtlhal->pa_type_2g == 0xFF)
+ rtlhal->pa_type_2g = 0;
+ if (rtlhal->lna_type_2g == 0xFF)
+ rtlhal->lna_type_2g = 0;
+
+ rtlhal->external_pa_2g = (rtlhal->pa_type_2g & BIT(4)) ? 1 : 0;
+ rtlhal->external_lna_2g =
+ (rtlhal->lna_type_2g & BIT(3)) ? 1 : 0;
+
+ rtlhal->pa_type_5g = hwinfo[EEPROM_2G_5G_PA_TYPE_8822B];
+ rtlhal->lna_type_5g =
+ hwinfo[EEPROM_5G_LNA_TYPE_GAIN_SEL_AB_8822B];
+ if (rtlhal->pa_type_5g == 0xFF)
+ rtlhal->pa_type_5g = 0;
+ if (rtlhal->lna_type_5g == 0xFF)
+ rtlhal->lna_type_5g = 0;
+
+ rtlhal->external_pa_5g = (rtlhal->pa_type_5g & BIT(0)) ? 1 : 0;
+ rtlhal->external_lna_5g =
+ (rtlhal->lna_type_5g & BIT(3)) ? 1 : 0;
+ } else {
+ rtlhal->external_pa_2g = 0;
+ rtlhal->external_lna_2g = 0;
+ rtlhal->external_pa_5g = 0;
+ rtlhal->external_lna_5g = 0;
+ }
+}
+
+static void _rtl8822be_read_amplifier_type(struct ieee80211_hw *hw, u8 *hwinfo,
+ bool autoload_fail)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+
+ u8 ext_type_pa_2g_a =
+ (hwinfo[EEPROM_2G_LNA_TYPE_GAIN_SEL_AB_8822B] & BIT(2)) >>
+ 2; /* 0xBD[2] */
+ u8 ext_type_pa_2g_b =
+ (hwinfo[EEPROM_2G_LNA_TYPE_GAIN_SEL_AB_8822B] & BIT(6)) >>
+ 6; /* 0xBD[6] */
+ u8 ext_type_pa_5g_a =
+ (hwinfo[EEPROM_5G_LNA_TYPE_GAIN_SEL_AB_8822B] & BIT(2)) >>
+ 2; /* 0xBF[2] */
+ u8 ext_type_pa_5g_b =
+ (hwinfo[EEPROM_5G_LNA_TYPE_GAIN_SEL_AB_8822B] & BIT(6)) >>
+ 6; /* 0xBF[6] */
+ u8 ext_type_lna_2g_a = (hwinfo[EEPROM_2G_LNA_TYPE_GAIN_SEL_AB_8822B] &
+ (BIT(1) | BIT(0))) >>
+ 0; /* 0xBD[1:0] */
+ u8 ext_type_lna_2g_b = (hwinfo[EEPROM_2G_LNA_TYPE_GAIN_SEL_AB_8822B] &
+ (BIT(5) | BIT(4))) >>
+ 4; /* 0xBD[5:4] */
+ u8 ext_type_lna_5g_a = (hwinfo[EEPROM_5G_LNA_TYPE_GAIN_SEL_AB_8822B] &
+ (BIT(1) | BIT(0))) >>
+ 0; /* 0xBF[1:0] */
+ u8 ext_type_lna_5g_b = (hwinfo[EEPROM_5G_LNA_TYPE_GAIN_SEL_AB_8822B] &
+ (BIT(5) | BIT(4))) >>
+ 4; /* 0xBF[5:4] */
+
+ _rtl8822be_read_pa_type(hw, hwinfo, autoload_fail);
+
+ /* [2.4G] Path A and B are both extPA */
+ if ((rtlhal->pa_type_2g & (BIT(5) | BIT(4))) == (BIT(5) | BIT(4)))
+ rtlhal->type_gpa = ext_type_pa_2g_b << 2 | ext_type_pa_2g_a;
+
+ /* [5G] Path A and B are both extPA */
+ if ((rtlhal->pa_type_5g & (BIT(1) | BIT(0))) == (BIT(1) | BIT(0)))
+ rtlhal->type_apa = ext_type_pa_5g_b << 2 | ext_type_pa_5g_a;
+
+ /* [2.4G] Path A and B are both extLNA */
+ if ((rtlhal->lna_type_2g & (BIT(7) | BIT(3))) == (BIT(7) | BIT(3)))
+ rtlhal->type_glna = ext_type_lna_2g_b << 2 | ext_type_lna_2g_a;
+
+ /* [5G] Path A and B are both extLNA */
+ if ((rtlhal->lna_type_5g & (BIT(7) | BIT(3))) == (BIT(7) | BIT(3)))
+ rtlhal->type_alna = ext_type_lna_5g_b << 2 | ext_type_lna_5g_a;
+}
+
+static void _rtl8822be_read_rfe_type(struct ieee80211_hw *hw, u8 *hwinfo,
+ bool autoload_fail)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+
+ if (!autoload_fail)
+ rtlhal->rfe_type = hwinfo[EEPROM_RFE_OPTION_8822B];
+ else
+ rtlhal->rfe_type = 0;
+
+ if (rtlhal->rfe_type == 0xFF)
+ rtlhal->rfe_type = 0;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "RFE Type: 0x%2x\n",
+ rtlhal->rfe_type);
+}
+
+static void _rtl8822be_read_adapter_info(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ struct rtl_halmac_ops *halmac_ops = rtlpriv->halmac.ops;
+ u16 i, usvalue;
+ u8 *hwinfo;
+ u16 eeprom_id;
+ u32 efuse_size;
+ int err;
+
+ if (rtlefuse->epromtype != EEPROM_BOOT_EFUSE) {
+ pr_err("RTL8822B Not boot from efuse!!");
+ return;
+ }
+
+ /* read logical efuse size (normalely, 0x0300) */
+ err = halmac_ops->halmac_get_logical_efuse_size(rtlpriv, &efuse_size);
+
+ if (err || !efuse_size) {
+ pr_err("halmac_get_logical_efuse_size err=%d efuse_size=0x%X",
+ err, efuse_size);
+ efuse_size = HWSET_MAX_SIZE;
+ }
+
+ if (efuse_size > HWSET_MAX_SIZE) {
+ pr_err("halmac_get_logical_efuse_size efuse_size=0x%X > 0x%X",
+ efuse_size, HWSET_MAX_SIZE);
+ efuse_size = HWSET_MAX_SIZE;
+ }
+
+ /* read efuse */
+ hwinfo = kzalloc(efuse_size, GFP_KERNEL);
+
+ err = halmac_ops->halmac_read_logical_efuse_map(rtlpriv, hwinfo,
+ efuse_size);
+ if (err) {
+ pr_err("%s: <ERROR> fail to get efuse map!\n", __func__);
+ goto label_end;
+ }
+
+ /* copy to efuse_map (need?) */
+ memcpy(&rtlefuse->efuse_map[EFUSE_INIT_MAP][0], hwinfo,
+ EFUSE_MAX_LOGICAL_SIZE);
+ memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0], hwinfo,
+ EFUSE_MAX_LOGICAL_SIZE);
+
+ /* parse content */
+ RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP\n", hwinfo,
+ HWSET_MAX_SIZE);
+
+ eeprom_id = *((u16 *)&hwinfo[0]);
+ if (eeprom_id != RTL8822B_EEPROM_ID) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ "EEPROM ID(%#x) is invalid!!\n", eeprom_id);
+ rtlefuse->autoload_failflag = true;
+ } else {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
+ rtlefuse->autoload_failflag = false;
+ }
+
+ if (rtlefuse->autoload_failflag)
+ goto label_end;
+
+ /*VID DID SVID SDID*/
+ rtlefuse->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID];
+ rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID];
+ rtlefuse->eeprom_svid = *(u16 *)&hwinfo[EEPROM_SVID];
+ rtlefuse->eeprom_smid = *(u16 *)&hwinfo[EEPROM_SMID];
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROMId = 0x%4x\n", eeprom_id);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM VID = 0x%4x\n",
+ rtlefuse->eeprom_vid);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM DID = 0x%4x\n",
+ rtlefuse->eeprom_did);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM SVID = 0x%4x\n",
+ rtlefuse->eeprom_svid);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM SMID = 0x%4x\n",
+ rtlefuse->eeprom_smid);
+ /*customer ID*/
+ rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOM_ID_8822B];
+ if (rtlefuse->eeprom_oemid == 0xFF)
+ rtlefuse->eeprom_oemid = 0;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x\n",
+ rtlefuse->eeprom_oemid);
+ /*EEPROM version*/
+ rtlefuse->eeprom_version = *(u8 *)&hwinfo[EEPROM_VERSION_8822B];
+ /*mac address*/
+ for (i = 0; i < 6; i += 2) {
+ usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR_8822BE + i];
+ *((u16 *)(&rtlefuse->dev_addr[i])) = usvalue;
+ }
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "dev_addr: %pM\n",
+ rtlefuse->dev_addr);
+
+ /* channel plan */
+ rtlefuse->eeprom_channelplan =
+ *(u8 *)&hwinfo[EEPROM_CHANNEL_PLAN_8822B];
+
+ /* set channel plan from efuse */
+ rtlefuse->channel_plan = rtlefuse->eeprom_channelplan;
+ if (rtlefuse->channel_plan == 0xFF)
+ rtlefuse->channel_plan = 0x7f; /* use 2G + 5G as default */
+
+ /*tx power*/
+ _rtl8822be_read_txpower_info_from_hwpg(hw, rtlefuse->autoload_failflag,
+ hwinfo);
+
+ rtl8822be_read_bt_coexist_info_from_hwpg(
+ hw, rtlefuse->autoload_failflag, hwinfo);
+
+ /*amplifier type*/
+ _rtl8822be_read_amplifier_type(hw, hwinfo, rtlefuse->autoload_failflag);
+
+ /*rfe type*/
+ _rtl8822be_read_rfe_type(hw, hwinfo, rtlefuse->autoload_failflag);
+
+ /*board type*/
+ rtlefuse->board_type =
+ (((*(u8 *)&hwinfo[EEPROM_RF_BOARD_OPTION_8822B]) & 0xE0) >> 5);
+ if ((*(u8 *)&hwinfo[EEPROM_RF_BOARD_OPTION_8822B]) == 0xFF)
+ rtlefuse->board_type = 0;
+
+ if (rtlpriv->btcoexist.btc_info.btcoexist == 1)
+ rtlefuse->board_type |= BIT(2); /* ODM_BOARD_BT */
+
+ /* phydm maintain rtlhal->board_type and rtlhal->package_type */
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "board_type = 0x%x\n",
+ rtlefuse->board_type);
+ /*parse xtal*/
+ rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_8822B];
+ if (hwinfo[EEPROM_XTAL_8822B] == 0xFF)
+ rtlefuse->crystalcap = 0; /*0x20;*/
+
+ /*antenna diversity*/
+ rtlefuse->antenna_div_type = 0;
+ rtlefuse->antenna_div_cfg = 0;
+
+label_end:
+ kfree(hwinfo);
+}
+
+static void _rtl8822be_hal_customized_behavior(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ pcipriv->ledctl.led_opendrain = true;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "RT Customized ID: 0x%02X\n",
+ rtlhal->oem_id);
+}
+
+static void _rtl8822be_read_pa_bias(struct ieee80211_hw *hw,
+ struct rtl_phydm_params *params)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_halmac_ops *halmac_ops = rtlpriv->halmac.ops;
+ u32 size;
+ u8 *map = NULL;
+
+ /* fill default values */
+ params->efuse0x3d7 = 0xFF;
+ params->efuse0x3d8 = 0xFF;
+
+ if (halmac_ops->halmac_get_physical_efuse_size(rtlpriv, &size))
+ goto err;
+
+ map = kmalloc(size, GFP_KERNEL);
+ if (!map)
+ goto err;
+
+ if (halmac_ops->halmac_read_physical_efuse_map(rtlpriv, map, size))
+ goto err;
+
+ params->efuse0x3d7 = map[0x3d7];
+ params->efuse0x3d8 = map[0x3d8];
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "efuse0x3d7 = 0x%2x, efuse0x3d8 = 0x%2x\n",
+ params->efuse0x3d7, params->efuse0x3d8);
+
+err:
+ kfree(map);
+}
+
+void rtl8822be_read_eeprom_info(struct ieee80211_hw *hw,
+ struct rtl_phydm_params *params)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ u8 tmp_u1b;
+
+ rtlhal->version = _rtl8822be_read_chip_version(hw);
+
+ params->mp_chip = (rtlhal->version & BIT_RTL_ID_8822B) ? 0 : 1;
+ params->fab_ver = BIT_GET_VENDOR_ID_8822B(rtlhal->version) >> 2;
+ params->cut_ver = BIT_GET_CHIP_VER_8822B(rtlhal->version);
+
+ /* fab_ver mapping */
+ if (params->fab_ver == 2)
+ params->fab_ver = 1;
+ else if (params->fab_ver == 1)
+ params->fab_ver = 2;
+
+ /* read PA bias: params->efuse0x3d7/efuse0x3d8 */
+ _rtl8822be_read_pa_bias(hw, params);
+
+ if (get_rf_type(rtlphy) == RF_1T1R)
+ rtlpriv->dm.rfpath_rxenable[0] = true;
+ else
+ rtlpriv->dm.rfpath_rxenable[0] =
+ rtlpriv->dm.rfpath_rxenable[1] = true;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n",
+ rtlhal->version);
+ tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_EEPROM_CTRL_8822B);
+ if (tmp_u1b & BIT(4)) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");
+ rtlefuse->epromtype = EEPROM_93C46;
+ } else {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");
+ rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
+ }
+ if (tmp_u1b & BIT(5)) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
+ rtlefuse->autoload_failflag = false;
+ _rtl8822be_read_adapter_info(hw);
+ } else {
+ pr_err("Autoload ERR!!\n");
+ }
+ _rtl8822be_hal_customized_behavior(hw);
+
+ rtlphy->rfpath_rx_enable[0] = true;
+ if (rtlphy->rf_type == RF_2T2R)
+ rtlphy->rfpath_rx_enable[1] = true;
+}
+
+void rtl8822be_read_eeprom_info_dummy(struct ieee80211_hw *hw)
+{
+ /*
+ * 8822b use halmac, so
+ * move rtl8822be_read_eeprom_info() to rtl8822be_init_sw_vars()
+ * after halmac_init_adapter().
+ */
+}
+
+static u32 _rtl8822be_rate_to_bitmap_2ssvht(__le16 vht_rate)
+{
+ u8 i, j, tmp_rate;
+ u32 rate_bitmap = 0;
+
+ for (i = j = 0; i < 4; i += 2, j += 10) {
+ tmp_rate = (le16_to_cpu(vht_rate) >> i) & 3;
+
+ switch (tmp_rate) {
+ case 2:
+ rate_bitmap = rate_bitmap | (0x03ff << j);
+ break;
+
+ case 1:
+ rate_bitmap = rate_bitmap | (0x01ff << j);
+ break;
+
+ case 0:
+ rate_bitmap = rate_bitmap | (0x00ff << j);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return rate_bitmap;
+}
+
+static u8 _rtl8822be_get_vht_en(enum wireless_mode wirelessmode,
+ u32 ratr_bitmap)
+{
+ u8 ret = 0;
+
+ if (wirelessmode < WIRELESS_MODE_N_24G) {
+ ret = 0;
+ } else if (wirelessmode == WIRELESS_MODE_AC_24G) {
+ if (ratr_bitmap & 0xfff00000) /* Mix , 2SS */
+ ret = 3;
+ else /* Mix, 1SS */
+ ret = 2;
+ } else if (wirelessmode == WIRELESS_MODE_AC_5G) {
+ ret = 1;
+ } /* VHT */
+
+ return ret << 4;
+}
+
+static u8 _rtl8822be_get_ra_ldpc(struct ieee80211_hw *hw, u8 mac_id,
+ struct rtl_sta_info *sta_entry,
+ enum wireless_mode wirelessmode)
+{
+ u8 b_ldpc = 0;
+ /*not support ldpc, do not open*/
+ return b_ldpc << 2;
+}
+
+static u8 _rtl8822be_get_ra_rftype(struct ieee80211_hw *hw,
+ enum wireless_mode wirelessmode,
+ u32 ratr_bitmap)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ u8 rf_type = RF_1T1R;
+
+ if (rtlphy->rf_type == RF_1T1R) {
+ rf_type = RF_1T1R;
+ } else if (wirelessmode == WIRELESS_MODE_AC_5G ||
+ wirelessmode == WIRELESS_MODE_AC_24G ||
+ wirelessmode == WIRELESS_MODE_AC_ONLY) {
+ if (ratr_bitmap & 0xffc00000)
+ rf_type = RF_2T2R;
+ } else if (wirelessmode == WIRELESS_MODE_N_5G ||
+ wirelessmode == WIRELESS_MODE_N_24G) {
+ if (ratr_bitmap & 0xfff00000)
+ rf_type = RF_2T2R;
+ }
+
+ return rf_type;
+}
+
+static bool _rtl8822be_get_ra_shortgi(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u8 mac_id)
+{
+ bool b_short_gi = false;
+ u8 b_curshortgi_40mhz =
+ (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 1 : 0;
+ u8 b_curshortgi_20mhz =
+ (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 1 : 0;
+ u8 b_curshortgi_80mhz = 0;
+
+ b_curshortgi_80mhz =
+ (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80) ? 1 : 0;
+
+ if (mac_id == 99 /*MAC_ID_STATIC_FOR_BROADCAST_MULTICAST*/)
+ b_short_gi = false;
+
+ if (b_curshortgi_40mhz || b_curshortgi_80mhz || b_curshortgi_20mhz)
+ b_short_gi = true;
+
+ return b_short_gi;
+}
+
+static void rtl8822be_update_hal_rate_mask(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
+ u8 rssi_level, bool update_bw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_sta_info *sta_entry = NULL;
+ u32 ratr_bitmap, ratr_bitmap_msb = 0;
+ u8 ratr_index;
+ enum wireless_mode wirelessmode = 0;
+ u8 curtxbw_40mhz =
+ (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0;
+ bool b_shortgi = false;
+ u8 rate_mask[7];
+ u8 macid = 0;
+ u8 rf_type;
+
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+ wirelessmode = sta_entry->wireless_mode;
+
+ RT_TRACE(rtlpriv, COMP_RATR, DBG_LOUD, "wireless mode = 0x%x\n",
+ wirelessmode);
+ if (mac->opmode == NL80211_IFTYPE_STATION ||
+ mac->opmode == NL80211_IFTYPE_MESH_POINT) {
+ curtxbw_40mhz = mac->bw_40;
+ } else if (mac->opmode == NL80211_IFTYPE_AP ||
+ mac->opmode == NL80211_IFTYPE_ADHOC)
+ macid = sta->aid + 1;
+ if (wirelessmode == WIRELESS_MODE_N_5G ||
+ wirelessmode == WIRELESS_MODE_AC_5G ||
+ wirelessmode == WIRELESS_MODE_A)
+ ratr_bitmap = (sta->supp_rates[NL80211_BAND_5GHZ]) << 4;
+ else
+ ratr_bitmap = sta->supp_rates[NL80211_BAND_2GHZ];
+
+ if (mac->opmode == NL80211_IFTYPE_ADHOC)
+ ratr_bitmap = 0xfff;
+
+ if (wirelessmode == WIRELESS_MODE_N_24G ||
+ wirelessmode == WIRELESS_MODE_N_5G)
+ ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
+ sta->ht_cap.mcs.rx_mask[0] << 12);
+ else if (wirelessmode == WIRELESS_MODE_AC_24G ||
+ wirelessmode == WIRELESS_MODE_AC_5G ||
+ wirelessmode == WIRELESS_MODE_AC_ONLY)
+ ratr_bitmap |= _rtl8822be_rate_to_bitmap_2ssvht(
+ sta->vht_cap.vht_mcs.rx_mcs_map)
+ << 12;
+
+ b_shortgi = _rtl8822be_get_ra_shortgi(hw, sta, macid);
+ rf_type = _rtl8822be_get_ra_rftype(hw, wirelessmode, ratr_bitmap);
+
+ ratr_index = rtlpriv->phydm.ops->phydm_rate_id_mapping(
+ rtlpriv, wirelessmode, rf_type, rtlphy->current_chan_bw);
+ sta_entry->ratr_index = ratr_index;
+
+ rtlpriv->phydm.ops->phydm_get_ra_bitmap(
+ rtlpriv, wirelessmode, rf_type, rtlphy->current_chan_bw,
+ rssi_level, &ratr_bitmap_msb, &ratr_bitmap);
+
+ RT_TRACE(rtlpriv, COMP_RATR, DBG_LOUD, "ratr_bitmap :%x\n",
+ ratr_bitmap);
+
+ rate_mask[0] = macid;
+ rate_mask[1] = ratr_index | (b_shortgi ? 0x80 : 0x00);
+ rate_mask[2] =
+ rtlphy->current_chan_bw | ((!update_bw) << 3) |
+ _rtl8822be_get_vht_en(wirelessmode, ratr_bitmap) |
+ _rtl8822be_get_ra_ldpc(hw, macid, sta_entry, wirelessmode);
+
+ rate_mask[3] = (u8)(ratr_bitmap & 0x000000ff);
+ rate_mask[4] = (u8)((ratr_bitmap & 0x0000ff00) >> 8);
+ rate_mask[5] = (u8)((ratr_bitmap & 0x00ff0000) >> 16);
+ rate_mask[6] = (u8)((ratr_bitmap & 0xff000000) >> 24);
+
+ RT_TRACE(
+ rtlpriv, COMP_RATR, DBG_DMESG,
+ "Rate_index:%x, ratr_val:%08x, %02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ ratr_index, ratr_bitmap, rate_mask[0], rate_mask[1],
+ rate_mask[2], rate_mask[3], rate_mask[4], rate_mask[5],
+ rate_mask[6]);
+ rtl8822be_fill_h2c_cmd(hw, H2C_8822B_MACID_CFG, 7, rate_mask);
+
+ /* for h2c cmd 0x46, only modify cmd id & ra mask */
+ /* Keep rate_mask0~2 of cmd 0x40, but clear byte3 and later */
+ /* 8822B has no 3SS, so keep it zeros. */
+ memset(rate_mask + 3, 0, 4);
+
+ rtl8822be_fill_h2c_cmd(hw, H2C_8822B_MACID_CFG_3SS, 7, rate_mask);
+
+ _rtl8822be_set_bcn_ctrl_reg(hw, BIT(3), 0);
+}
+
+void rtl8822be_update_hal_rate_tbl(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u8 rssi_level,
+ bool update_bw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ if (rtlpriv->dm.useramask)
+ rtl8822be_update_hal_rate_mask(hw, sta, rssi_level, update_bw);
+}
+
+void rtl8822be_update_channel_access_setting(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ u16 sifs_timer;
+
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
+ (u8 *)&mac->slot_time);
+ if (!mac->ht_enable)
+ sifs_timer = 0x0a0a;
+ else
+ sifs_timer = 0x0e0e;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
+}
+
+bool rtl8822be_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
+{
+ *valid = 1;
+ return true;
+}
+
+void rtl8822be_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr,
+ bool is_group, u8 enc_algo, bool is_wepkey,
+ bool clear_all)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u8 *macaddr = p_macaddr;
+ u32 entry_id = 0;
+ bool is_pairwise = false;
+
+ static u8 cam_const_addr[4][6] = {
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
+ };
+ static u8 cam_const_broad[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+ if (clear_all) {
+ u8 idx = 0;
+ u8 cam_offset = 0;
+ u8 clear_number = 5;
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
+
+ for (idx = 0; idx < clear_number; idx++) {
+ rtl_cam_mark_invalid(hw, cam_offset + idx);
+ rtl_cam_empty_entry(hw, cam_offset + idx);
+
+ if (idx < 5) {
+ memset(rtlpriv->sec.key_buf[idx], 0,
+ MAX_KEY_LEN);
+ rtlpriv->sec.key_len[idx] = 0;
+ }
+ }
+
+ return;
+ }
+
+ switch (enc_algo) {
+ case WEP40_ENCRYPTION:
+ enc_algo = CAM_WEP40;
+ break;
+ case WEP104_ENCRYPTION:
+ enc_algo = CAM_WEP104;
+ break;
+ case TKIP_ENCRYPTION:
+ enc_algo = CAM_TKIP;
+ break;
+ case AESCCMP_ENCRYPTION:
+ enc_algo = CAM_AES;
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
+ "switch case %#x not processed\n", enc_algo);
+ enc_algo = CAM_TKIP;
+ break;
+ }
+
+ if (is_wepkey || rtlpriv->sec.use_defaultkey) {
+ macaddr = cam_const_addr[key_index];
+ entry_id = key_index;
+ } else {
+ if (is_group) {
+ macaddr = cam_const_broad;
+ entry_id = key_index;
+ } else {
+ if (mac->opmode == NL80211_IFTYPE_AP) {
+ entry_id =
+ rtl_cam_get_free_entry(hw, p_macaddr);
+ if (entry_id >= TOTAL_CAM_ENTRY) {
+ pr_err("Can not find free hwsecurity cam entry\n");
+ return;
+ }
+ } else {
+ entry_id = CAM_PAIRWISE_KEY_POSITION;
+ }
+
+ key_index = PAIRWISE_KEYIDX;
+ is_pairwise = true;
+ }
+ }
+
+ if (rtlpriv->sec.key_len[key_index] == 0) {
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ "delete one entry, entry_id is %d\n", entry_id);
+ if (mac->opmode == NL80211_IFTYPE_AP)
+ rtl_cam_del_entry(hw, p_macaddr);
+ rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
+ } else {
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "add one entry\n");
+ if (is_pairwise) {
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ "set Pairwise key\n");
+
+ rtl_cam_add_one_entry(hw, macaddr, key_index, entry_id,
+ enc_algo, CAM_CONFIG_NO_USEDK,
+ rtlpriv->sec.key_buf[key_index]);
+ } else {
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ "set group key\n");
+
+ if (mac->opmode == NL80211_IFTYPE_ADHOC) {
+ rtl_cam_add_one_entry(
+ hw, rtlefuse->dev_addr, PAIRWISE_KEYIDX,
+ CAM_PAIRWISE_KEY_POSITION, enc_algo,
+ CAM_CONFIG_NO_USEDK,
+ rtlpriv->sec.key_buf[entry_id]);
+ }
+
+ rtl_cam_add_one_entry(hw, macaddr, key_index, entry_id,
+ enc_algo, CAM_CONFIG_NO_USEDK,
+ rtlpriv->sec.key_buf[entry_id]);
+ }
+ }
+}
+
+void rtl8822be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
+ bool auto_load_fail, u8 *hwinfo)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 value;
+ u32 val32;
+
+ val32 = rtl_read_dword(rtlpriv, REG_WL_BT_PWR_CTRL_8822B);
+ if (val32 & BIT_BT_FUNC_EN_8822B)
+ rtlpriv->btcoexist.btc_info.btcoexist = 1;
+ else
+ rtlpriv->btcoexist.btc_info.btcoexist = 0;
+
+ if (!auto_load_fail) {
+ value = hwinfo[EEPROM_RF_BT_SETTING_8822B];
+
+ rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8822B;
+ rtlpriv->btcoexist.btc_info.ant_num =
+ (value & BIT(0) ? ANT_TOTAL_X1 : ANT_TOTAL_X2);
+ } else {
+ rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8822B;
+ rtlpriv->btcoexist.btc_info.ant_num = ANT_TOTAL_X2;
+ }
+}
+
+void rtl8822be_bt_reg_init(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ /* 0:Low, 1:High, 2:From Efuse. */
+ rtlpriv->btcoexist.reg_bt_iso = 2;
+ /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */
+ rtlpriv->btcoexist.reg_bt_sco = 3;
+ /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */
+ rtlpriv->btcoexist.reg_bt_sco = 0;
+}
+
+void rtl8822be_suspend(struct ieee80211_hw *hw) {}
+
+void rtl8822be_resume(struct ieee80211_hw *hw) {}
diff --git a/drivers/staging/rtlwifi/rtl8822be/hw.h b/drivers/staging/rtlwifi/rtl8822be/hw.h
new file mode 100644
index 0000000..a91c276
--- /dev/null
+++ b/drivers/staging/rtlwifi/rtl8822be/hw.h
@@ -0,0 +1,66 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL8822B_HW_H__
+#define __RTL8822B_HW_H__
+
+extern u8 rtl_channel5g[CHANNEL_MAX_NUMBER_5G];
+extern u8 rtl_channel5g_80m[CHANNEL_MAX_NUMBER_5G_80M];
+
+void rtl8822be_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
+void rtl8822be_read_eeprom_info(struct ieee80211_hw *hw,
+ struct rtl_phydm_params *params);
+void rtl8822be_read_eeprom_info_dummy(struct ieee80211_hw *hw);
+void rtl8822be_interrupt_recognized(struct ieee80211_hw *hw, u32 *p_inta,
+ u32 *p_intb, u32 *p_intc, u32 *p_intd);
+int rtl8822be_hw_init(struct ieee80211_hw *hw);
+void rtl8822be_card_disable(struct ieee80211_hw *hw);
+void rtl8822be_enable_interrupt(struct ieee80211_hw *hw);
+void rtl8822be_disable_interrupt(struct ieee80211_hw *hw);
+int rtl8822be_set_network_type(struct ieee80211_hw *hw,
+ enum nl80211_iftype type);
+void rtl8822be_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
+void rtl8822be_set_qos(struct ieee80211_hw *hw, int aci);
+void rtl8822be_set_beacon_related_registers(struct ieee80211_hw *hw);
+void rtl8822be_set_beacon_interval(struct ieee80211_hw *hw);
+void rtl8822be_update_interrupt_mask(struct ieee80211_hw *hw, u32 add_msr,
+ u32 rm_msr);
+void rtl8822be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
+void rtl8822be_update_hal_rate_tbl(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u8 rssi_level,
+ bool update_bw);
+void rtl8822be_update_channel_access_setting(struct ieee80211_hw *hw);
+bool rtl8822be_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid);
+void rtl8822be_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr,
+ bool is_group, u8 enc_algo, bool is_wepkey,
+ bool clear_all);
+void rtl8822be_enable_hw_security_config(struct ieee80211_hw *hw);
+void rtl8822be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
+ bool autoload_fail, u8 *hwinfo);
+void rtl8822be_bt_reg_init(struct ieee80211_hw *hw);
+void rtl8822be_suspend(struct ieee80211_hw *hw);
+void rtl8822be_resume(struct ieee80211_hw *hw);
+void rtl8822be_fw_clk_off_timer_callback(unsigned long data);
+#endif
diff --git a/drivers/staging/rtlwifi/rtl8822be/led.c b/drivers/staging/rtlwifi/rtl8822be/led.c
new file mode 100644
index 0000000..f4b5af8
--- /dev/null
+++ b/drivers/staging/rtlwifi/rtl8822be/led.c
@@ -0,0 +1,127 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../pci.h"
+#include "reg.h"
+#include "led.h"
+
+static void _rtl8822be_init_led(struct ieee80211_hw *hw, struct rtl_led *pled,
+ enum rtl_led_pin ledpin)
+{
+ pled->hw = hw;
+ pled->ledpin = ledpin;
+ pled->ledon = false;
+}
+
+void rtl8822be_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
+ REG_LEDCFG2_8822B, pled->ledpin);
+
+ switch (pled->ledpin) {
+ case LED_PIN_GPIO0:
+ break;
+ case LED_PIN_LED0:
+ break;
+ case LED_PIN_LED1:
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
+ "switch case not process\n");
+ break;
+ }
+ pled->ledon = true;
+}
+
+void rtl8822be_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
+ REG_LEDCFG2_8822B, pled->ledpin);
+
+ switch (pled->ledpin) {
+ case LED_PIN_GPIO0:
+ break;
+ case LED_PIN_LED0:
+ break;
+ case LED_PIN_LED1:
+
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
+ "switch case not process\n");
+ break;
+ }
+ pled->ledon = false;
+}
+
+void rtl8822be_init_sw_leds(struct ieee80211_hw *hw)
+{
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+
+ _rtl8822be_init_led(hw, &pcipriv->ledctl.sw_led0, LED_PIN_LED0);
+ _rtl8822be_init_led(hw, &pcipriv->ledctl.sw_led1, LED_PIN_LED1);
+}
+
+static void _rtl8822be_sw_led_control(struct ieee80211_hw *hw,
+ enum led_ctl_mode ledaction)
+{
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_led *led0 = &pcipriv->ledctl.sw_led0;
+
+ switch (ledaction) {
+ case LED_CTL_POWER_ON:
+ case LED_CTL_LINK:
+ case LED_CTL_NO_LINK:
+ rtl8822be_sw_led_on(hw, led0);
+ break;
+ case LED_CTL_POWER_OFF:
+ rtl8822be_sw_led_off(hw, led0);
+ break;
+ default:
+ break;
+ }
+}
+
+void rtl8822be_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+ if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) &&
+ (ledaction == LED_CTL_TX || ledaction == LED_CTL_RX ||
+ ledaction == LED_CTL_SITE_SURVEY || ledaction == LED_CTL_LINK ||
+ ledaction == LED_CTL_NO_LINK ||
+ ledaction == LED_CTL_START_TO_LINK ||
+ ledaction == LED_CTL_POWER_ON)) {
+ return;
+ }
+ RT_TRACE(rtlpriv, COMP_LED, DBG_TRACE, "ledaction %d,\n", ledaction);
+ _rtl8822be_sw_led_control(hw, ledaction);
+}
diff --git a/drivers/staging/rtlwifi/rtl8822be/led.h b/drivers/staging/rtlwifi/rtl8822be/led.h
new file mode 100644
index 0000000..9c0a229
--- /dev/null
+++ b/drivers/staging/rtlwifi/rtl8822be/led.h
@@ -0,0 +1,34 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL8822B_LED_H__
+#define __RTL8822B_LED_H__
+
+void rtl8822be_init_sw_leds(struct ieee80211_hw *hw);
+void rtl8822be_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled);
+void rtl8822be_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);
+void rtl8822be_led_control(struct ieee80211_hw *hw,
+ enum led_ctl_mode ledaction);
+#endif
diff --git a/drivers/staging/rtlwifi/rtl8822be/phy.c b/drivers/staging/rtlwifi/rtl8822be/phy.c
new file mode 100644
index 0000000..4cba2ad
--- /dev/null
+++ b/drivers/staging/rtlwifi/rtl8822be/phy.c
@@ -0,0 +1,2233 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../pci.h"
+#include "../ps.h"
+#include "../base.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "trx.h"
+#include "../btcoexist/halbt_precomp.h"
+#include "hw.h"
+#include "../efuse.h"
+
+static u32 _rtl8822be_phy_calculate_bit_shift(u32 bitmask);
+static void
+_rtl8822be_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw);
+
+static long _rtl8822be_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
+ enum wireless_mode wirelessmode,
+ u8 txpwridx);
+static void rtl8822be_phy_set_rf_on(struct ieee80211_hw *hw);
+static void rtl8822be_phy_set_io(struct ieee80211_hw *hw);
+
+static u8 cck_rates[] = {DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M, DESC_RATE11M};
+static u8 sizes_of_cck_retes = 4;
+static u8 ofdm_rates[] = {DESC_RATE6M, DESC_RATE9M, DESC_RATE12M,
+ DESC_RATE18M, DESC_RATE24M, DESC_RATE36M,
+ DESC_RATE48M, DESC_RATE54M};
+static u8 sizes_of_ofdm_retes = 8;
+static u8 ht_rates_1t[] = {DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2,
+ DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5,
+ DESC_RATEMCS6, DESC_RATEMCS7};
+static u8 sizes_of_ht_retes_1t = 8;
+static u8 ht_rates_2t[] = {DESC_RATEMCS8, DESC_RATEMCS9, DESC_RATEMCS10,
+ DESC_RATEMCS11, DESC_RATEMCS12, DESC_RATEMCS13,
+ DESC_RATEMCS14, DESC_RATEMCS15};
+static u8 sizes_of_ht_retes_2t = 8;
+static u8 vht_rates_1t[] = {DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1,
+ DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3,
+ DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5,
+ DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7,
+ DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9};
+static u8 vht_rates_2t[] = {DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1,
+ DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3,
+ DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5,
+ DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7,
+ DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9};
+static u8 sizes_of_vht_retes = 10;
+
+u32 rtl8822be_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr,
+ u32 bitmask)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 returnvalue, originalvalue, bitshift;
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n",
+ regaddr, bitmask);
+ originalvalue = rtl_read_dword(rtlpriv, regaddr);
+ bitshift = _rtl8822be_phy_calculate_bit_shift(bitmask);
+ returnvalue = (originalvalue & bitmask) >> bitshift;
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
+ bitmask, regaddr, originalvalue);
+
+ return returnvalue;
+}
+
+void rtl8822be_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
+ u32 data)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 originalvalue, bitshift;
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+ "regaddr(%#x), bitmask(%#x), data(%#x)\n", regaddr, bitmask,
+ data);
+
+ if (bitmask != MASKDWORD) {
+ originalvalue = rtl_read_dword(rtlpriv, regaddr);
+ bitshift = _rtl8822be_phy_calculate_bit_shift(bitmask);
+ data = ((originalvalue & (~bitmask)) |
+ ((data << bitshift) & bitmask));
+ }
+
+ rtl_write_dword(rtlpriv, regaddr, data);
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+ "regaddr(%#x), bitmask(%#x), data(%#x)\n", regaddr, bitmask,
+ data);
+}
+
+u32 rtl8822be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
+ u32 regaddr, u32 bitmask)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 /*original_value,*/ readback_value /*, bitshift*/;
+ unsigned long flags;
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+ "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", regaddr, rfpath,
+ bitmask);
+
+ spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
+
+ readback_value = rtlpriv->phydm.ops->phydm_read_rf_reg(
+ rtlpriv, rfpath, regaddr, bitmask);
+
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
+
+ return readback_value;
+}
+
+void rtl8822be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
+ u32 regaddr, u32 bitmask, u32 data)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ unsigned long flags;
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+ "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
+ regaddr, bitmask, data, rfpath);
+
+ spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
+
+ rtlpriv->phydm.ops->phydm_write_rf_reg(rtlpriv, rfpath, regaddr,
+ bitmask, data);
+
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+ "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
+ regaddr, bitmask, data, rfpath);
+}
+
+static u32 _rtl8822be_phy_calculate_bit_shift(u32 bitmask)
+{
+ u32 i;
+
+ for (i = 0; i <= 31; i++) {
+ if (((bitmask >> i) & 0x1) == 1)
+ break;
+ }
+ return i;
+}
+
+bool rtl8822be_halmac_cb_init_mac_register(struct rtl_priv *rtlpriv)
+{
+ return rtlpriv->phydm.ops->phydm_phy_mac_config(rtlpriv);
+}
+
+bool rtl8822be_phy_bb_config(struct ieee80211_hw *hw)
+{
+ bool rtstatus = true;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u8 crystal_cap;
+ /* u32 tmp; */
+
+ rtstatus = rtlpriv->phydm.ops->phydm_phy_bb_config(rtlpriv);
+
+ /* write 0x28[6:1] = 0x24[30:25] = CrystalCap */
+ crystal_cap = rtlefuse->crystalcap & 0x3F;
+ rtl_set_bbreg(hw, REG_AFE_XTAL_CTRL_8822B, 0x7E000000, crystal_cap);
+ rtl_set_bbreg(hw, REG_AFE_PLL_CTRL_8822B, 0x7E, crystal_cap);
+
+ /*rtlphy->reg_837 = rtl_read_byte(rtlpriv, 0x837);*/ /*unused*/
+
+ return rtstatus;
+}
+
+bool rtl8822be_phy_rf_config(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+
+ if (rtlphy->rf_type == RF_1T1R)
+ rtlphy->num_total_rfpath = 1;
+ else
+ rtlphy->num_total_rfpath = 2;
+
+ return rtlpriv->phydm.ops->phydm_phy_rf_config(rtlpriv);
+}
+
+bool rtl8822be_halmac_cb_init_bb_rf_register(struct rtl_priv *rtlpriv)
+{
+ struct ieee80211_hw *hw = rtlpriv->hw;
+ enum radio_mask txpath, rxpath;
+ bool tx2path;
+ bool ret = false;
+
+ _rtl8822be_phy_init_bb_rf_register_definition(hw);
+
+ rtlpriv->halmac.ops->halmac_phy_power_switch(rtlpriv, 1);
+
+ /* beofre bb/rf config */
+ rtlpriv->phydm.ops->phydm_parameter_init(rtlpriv, 0);
+
+ /* do bb/rf config */
+ if (rtl8822be_phy_bb_config(hw) && rtl8822be_phy_rf_config(hw))
+ ret = true;
+
+ /* after bb/rf config */
+ rtlpriv->phydm.ops->phydm_parameter_init(rtlpriv, 1);
+
+ /* set trx mode (keep it to be last, r17376) */
+ txpath = RF_MASK_A | RF_MASK_B;
+ rxpath = RF_MASK_A | RF_MASK_B;
+ tx2path = false;
+ ret = rtlpriv->phydm.ops->phydm_trx_mode(rtlpriv, txpath, rxpath,
+ tx2path);
+
+ return ret;
+}
+
+static void _rtl8822be_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+
+ u8 band, rfpath, txnum, rate;
+
+ for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
+ for (rfpath = 0; rfpath < TX_PWR_BY_RATE_NUM_RF; ++rfpath)
+ for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
+ for (rate = 0; rate < TX_PWR_BY_RATE_NUM_RATE;
+ ++rate)
+ rtlphy->tx_power_by_rate_offset
+ [band][rfpath][txnum][rate] = 0;
+}
+
+static void _rtl8822be_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw,
+ u8 band, u8 path,
+ u8 rate_section, u8 txnum,
+ u8 value)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+
+ if (path > RF90_PATH_D) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n",
+ path);
+ return;
+ }
+
+ if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "Invalid band %d in phy_SetTxPowerByRatBase()\n",
+ band);
+ return;
+ }
+
+ if (rate_section >= MAX_RATE_SECTION ||
+ (band == BAND_ON_5G && rate_section == CCK)) {
+ RT_TRACE(
+ rtlpriv, COMP_INIT, DBG_LOUD,
+ "Invalid rate_section %d in phy_SetTxPowerByRatBase()\n",
+ rate_section);
+ return;
+ }
+
+ if (band == BAND_ON_2_4G)
+ rtlphy->txpwr_by_rate_base_24g[path][txnum][rate_section] =
+ value;
+ else /* BAND_ON_5G */
+ rtlphy->txpwr_by_rate_base_5g[path][txnum][rate_section - 1] =
+ value;
+}
+
+static u8 _rtl8822be_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw,
+ u8 band, u8 path, u8 txnum,
+ u8 rate_section)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ u8 value;
+
+ if (path > RF90_PATH_D) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "Invalid Rf Path %d in phy_GetTxPowerByRatBase()\n",
+ path);
+ return 0;
+ }
+
+ if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "Invalid band %d in phy_GetTxPowerByRatBase()\n",
+ band);
+ return 0;
+ }
+
+ if (rate_section >= MAX_RATE_SECTION ||
+ (band == BAND_ON_5G && rate_section == CCK)) {
+ RT_TRACE(
+ rtlpriv, COMP_INIT, DBG_LOUD,
+ "Invalid rate_section %d in phy_GetTxPowerByRatBase()\n",
+ rate_section);
+ return 0;
+ }
+
+ if (band == BAND_ON_2_4G)
+ value = rtlphy->txpwr_by_rate_base_24g[path][txnum]
+ [rate_section];
+ else /* BAND_ON_5G */
+ value = rtlphy->txpwr_by_rate_base_5g[path][txnum]
+ [rate_section - 1];
+
+ return value;
+}
+
+static void _rtl8822be_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+
+ struct {
+ enum rtl_desc_rate rate;
+ enum rate_section section;
+ } rate_sec_base[] = {
+ {DESC_RATE11M, CCK},
+ {DESC_RATE54M, OFDM},
+ {DESC_RATEMCS7, HT_MCS0_MCS7},
+ {DESC_RATEMCS15, HT_MCS8_MCS15},
+ {DESC_RATEVHT1SS_MCS7, VHT_1SSMCS0_1SSMCS9},
+ {DESC_RATEVHT2SS_MCS7, VHT_2SSMCS0_2SSMCS9},
+ };
+
+ u8 band, path, rs, tx_num, base;
+ u8 rate, section;
+
+ for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
+ for (path = RF90_PATH_A; path <= RF90_PATH_B; path++) {
+ for (rs = 0; rs < MAX_RATE_SECTION; rs++) {
+ rate = rate_sec_base[rs].rate;
+ section = rate_sec_base[rs].section;
+
+ if (IS_1T_RATE(rate))
+ tx_num = RF_1TX;
+ else
+ tx_num = RF_2TX;
+
+ if (band == BAND_ON_5G &&
+ RX_HAL_IS_CCK_RATE(rate))
+ continue;
+
+ base = rtlphy->tx_power_by_rate_offset
+ [band][path][tx_num][rate];
+ _rtl8822be_phy_set_txpower_by_rate_base(
+ hw, band, path, section, tx_num, base);
+ }
+ }
+ }
+}
+
+static void __rtl8822be_phy_cross_reference_core(struct ieee80211_hw *hw,
+ u8 regulation, u8 bw,
+ u8 channel)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ u8 rs, ref_rs;
+ s8 pwrlmt, ref_pwrlmt;
+
+ for (rs = 0; rs < MAX_RATE_SECTION_NUM; ++rs) {
+ /*5G 20M 40M VHT and HT can cross reference*/
+ if (bw != HT_CHANNEL_WIDTH_20 && bw != HT_CHANNEL_WIDTH_20_40)
+ continue;
+
+ if (rs == HT_MCS0_MCS7)
+ ref_rs = VHT_1SSMCS0_1SSMCS9;
+ else if (rs == HT_MCS8_MCS15)
+ ref_rs = VHT_2SSMCS0_2SSMCS9;
+ else if (rs == VHT_1SSMCS0_1SSMCS9)
+ ref_rs = HT_MCS0_MCS7;
+ else if (rs == VHT_2SSMCS0_2SSMCS9)
+ ref_rs = HT_MCS8_MCS15;
+ else
+ continue;
+
+ ref_pwrlmt = rtlphy->txpwr_limit_5g[regulation][bw][ref_rs]
+ [channel][RF90_PATH_A];
+ if (ref_pwrlmt == MAX_POWER_INDEX)
+ continue;
+
+ pwrlmt = rtlphy->txpwr_limit_5g[regulation][bw][rs][channel]
+ [RF90_PATH_A];
+ if (pwrlmt != MAX_POWER_INDEX)
+ continue;
+
+ rtlphy->txpwr_limit_5g[regulation][bw][rs][channel]
+ [RF90_PATH_A] = ref_pwrlmt;
+ }
+}
+
+static void
+_rtl8822be_phy_cross_reference_ht_and_vht_txpower_limit(struct ieee80211_hw *hw)
+{
+ u8 regulation, bw, channel;
+
+ for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
+ for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) {
+ for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G;
+ ++channel) {
+ __rtl8822be_phy_cross_reference_core(
+ hw, regulation, bw, channel);
+ }
+ }
+ }
+}
+
+static void __rtl8822be_txpwr_limit_to_index_2g(struct ieee80211_hw *hw,
+ u8 regulation, u8 bw,
+ u8 channel)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ u8 bw40_pwr_base_dbm2_4G;
+ u8 rate_section;
+ s8 temp_pwrlmt;
+ enum rf_tx_num txnum;
+ s8 temp_value;
+ u8 rf_path;
+
+ for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM;
+ ++rate_section) {
+ /* obtain the base dBm values in 2.4G band
+ * CCK => 11M, OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15
+ */
+
+ temp_pwrlmt =
+ rtlphy->txpwr_limit_2_4g[regulation][bw][rate_section]
+ [channel][RF90_PATH_A];
+ txnum = IS_1T_RATESEC(rate_section) ? RF_1TX : RF_2TX;
+
+ if (temp_pwrlmt == MAX_POWER_INDEX)
+ continue;
+
+ for (rf_path = RF90_PATH_A; rf_path < MAX_RF_PATH_NUM;
+ ++rf_path) {
+ bw40_pwr_base_dbm2_4G =
+ _rtl8822be_phy_get_txpower_by_rate_base(
+ hw, BAND_ON_2_4G, rf_path, txnum,
+ rate_section);
+
+ temp_value = temp_pwrlmt - bw40_pwr_base_dbm2_4G;
+ rtlphy->txpwr_limit_2_4g[regulation][bw][rate_section]
+ [channel][rf_path] = temp_value;
+
+ RT_TRACE(
+ rtlpriv, COMP_INIT, DBG_TRACE,
+ "TxPwrLimit_2_4G[regulation %d][bw %d][rateSection %d][channel %d] = %d\n(TxPwrLimit in dBm %d - BW40PwrLmt2_4G[channel %d][rfPath %d] %d)\n",
+ regulation, bw, rate_section, channel,
+ rtlphy->txpwr_limit_2_4g[regulation][bw]
+ [rate_section][channel]
+ [rf_path],
+ (temp_pwrlmt == 63) ? 0 : temp_pwrlmt / 2,
+ channel, rf_path, bw40_pwr_base_dbm2_4G);
+ }
+ }
+}
+
+static void __rtl8822be_txpwr_limit_to_index_5g(struct ieee80211_hw *hw,
+ u8 regulation, u8 bw,
+ u8 channel)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ u8 bw40_pwr_base_dbm5G;
+ u8 rate_section;
+ s8 temp_pwrlmt;
+ enum rf_tx_num txnum;
+ s8 temp_value;
+ u8 rf_path;
+
+ for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM;
+ ++rate_section) {
+ /* obtain the base dBm values in 5G band
+ * OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15,
+ * VHT => 1SSMCS7, VHT 2T => 2SSMCS7
+ */
+
+ temp_pwrlmt =
+ rtlphy->txpwr_limit_5g[regulation][bw][rate_section]
+ [channel][RF90_PATH_A];
+ txnum = IS_1T_RATESEC(rate_section) ? RF_1TX : RF_2TX;
+
+ if (temp_pwrlmt == MAX_POWER_INDEX)
+ continue;
+
+ for (rf_path = RF90_PATH_A; rf_path < MAX_RF_PATH_NUM;
+ ++rf_path) {
+ bw40_pwr_base_dbm5G =
+ _rtl8822be_phy_get_txpower_by_rate_base(
+ hw, BAND_ON_5G, rf_path, txnum,
+ rate_section);
+
+ temp_value = temp_pwrlmt - bw40_pwr_base_dbm5G;
+ rtlphy->txpwr_limit_5g[regulation][bw][rate_section]
+ [channel][rf_path] = temp_value;
+
+ RT_TRACE(
+ rtlpriv, COMP_INIT, DBG_TRACE,
+ "TxPwrLimit_5G[regulation %d][bw %d][rateSection %d][channel %d] =%d\n(TxPwrLimit in dBm %d - BW40PwrLmt5G[chnl group %d][rfPath %d] %d)\n",
+ regulation, bw, rate_section, channel,
+ rtlphy->txpwr_limit_5g[regulation][bw]
+ [rate_section][channel]
+ [rf_path],
+ temp_pwrlmt, channel, rf_path,
+ bw40_pwr_base_dbm5G);
+ }
+ }
+}
+
+static void
+_rtl8822be_phy_convert_txpower_limit_to_power_index(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 regulation, bw, channel;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "=====> %s()\n", __func__);
+
+ _rtl8822be_phy_cross_reference_ht_and_vht_txpower_limit(hw);
+
+ for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
+ for (bw = 0; bw < MAX_2_4G_BANDWIDTH_NUM; ++bw) {
+ for (channel = 0; channel < CHANNEL_MAX_NUMBER_2G;
+ ++channel) {
+ __rtl8822be_txpwr_limit_to_index_2g(
+ hw, regulation, bw, channel);
+ }
+ }
+ }
+
+ for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
+ for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) {
+ for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G;
+ ++channel) {
+ __rtl8822be_txpwr_limit_to_index_5g(
+ hw, regulation, bw, channel);
+ }
+ }
+ }
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<===== %s()\n", __func__);
+}
+
+static void _rtl8822be_phy_init_txpower_limit(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ u8 i, j, k, l, m;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "=====> %s()!\n", __func__);
+
+ for (i = 0; i < MAX_REGULATION_NUM; ++i) {
+ for (j = 0; j < MAX_2_4G_BANDWIDTH_NUM; ++j)
+ for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
+ for (m = 0; m < CHANNEL_MAX_NUMBER_2G; ++m)
+ for (l = 0; l < MAX_RF_PATH_NUM; ++l)
+ rtlphy->txpwr_limit_2_4g[i][j]
+ [k][m]
+ [l] =
+ MAX_POWER_INDEX;
+ }
+ for (i = 0; i < MAX_REGULATION_NUM; ++i) {
+ for (j = 0; j < MAX_5G_BANDWIDTH_NUM; ++j)
+ for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
+ for (m = 0; m < CHANNEL_MAX_NUMBER_5G; ++m)
+ for (l = 0; l < MAX_RF_PATH_NUM; ++l)
+ rtlphy->txpwr_limit_5g[i][j][k]
+ [m][l] =
+ MAX_POWER_INDEX;
+ }
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "<===== %s()!\n", __func__);
+}
+
+static void
+_rtl8822be_phy_convert_txpower_dbm_to_relative_value(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+
+ u8 base = 0, i = 0, value = 0, band = 0, path = 0, txnum = 0;
+
+ for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band) {
+ for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
+ for (txnum = RF_1TX; txnum <= RF_2TX; ++txnum) {
+ /* CCK */
+ base = rtlphy->tx_power_by_rate_offset
+ [band][path][txnum]
+ [DESC_RATE11M];
+ for (i = 0; i < sizeof(cck_rates); ++i) {
+ value = rtlphy->tx_power_by_rate_offset
+ [band][path][txnum]
+ [cck_rates[i]];
+ rtlphy->tx_power_by_rate_offset
+ [band][path][txnum]
+ [cck_rates[i]] = value - base;
+ }
+
+ /* OFDM */
+ base = rtlphy->tx_power_by_rate_offset
+ [band][path][txnum]
+ [DESC_RATE54M];
+ for (i = 0; i < sizeof(ofdm_rates); ++i) {
+ value = rtlphy->tx_power_by_rate_offset
+ [band][path][txnum]
+ [ofdm_rates[i]];
+ rtlphy->tx_power_by_rate_offset
+ [band][path][txnum]
+ [ofdm_rates[i]] = value - base;
+ }
+
+ /* HT MCS0~7 */
+ base = rtlphy->tx_power_by_rate_offset
+ [band][path][txnum]
+ [DESC_RATEMCS7];
+ for (i = 0; i < sizeof(ht_rates_1t); ++i) {
+ value = rtlphy->tx_power_by_rate_offset
+ [band][path][txnum]
+ [ht_rates_1t[i]];
+ rtlphy->tx_power_by_rate_offset
+ [band][path][txnum]
+ [ht_rates_1t[i]] = value - base;
+ }
+
+ /* HT MCS8~15 */
+ base = rtlphy->tx_power_by_rate_offset
+ [band][path][txnum]
+ [DESC_RATEMCS15];
+ for (i = 0; i < sizeof(ht_rates_2t); ++i) {
+ value = rtlphy->tx_power_by_rate_offset
+ [band][path][txnum]
+ [ht_rates_2t[i]];
+ rtlphy->tx_power_by_rate_offset
+ [band][path][txnum]
+ [ht_rates_2t[i]] = value - base;
+ }
+
+ /* VHT 1SS */
+ base = rtlphy->tx_power_by_rate_offset
+ [band][path][txnum]
+ [DESC_RATEVHT1SS_MCS7];
+ for (i = 0; i < sizeof(vht_rates_1t); ++i) {
+ value = rtlphy->tx_power_by_rate_offset
+ [band][path][txnum]
+ [vht_rates_1t[i]];
+ rtlphy->tx_power_by_rate_offset
+ [band][path][txnum]
+ [vht_rates_1t[i]] =
+ value - base;
+ }
+
+ /* VHT 2SS */
+ base = rtlphy->tx_power_by_rate_offset
+ [band][path][txnum]
+ [DESC_RATEVHT2SS_MCS7];
+ for (i = 0; i < sizeof(vht_rates_2t); ++i) {
+ value = rtlphy->tx_power_by_rate_offset
+ [band][path][txnum]
+ [vht_rates_2t[i]];
+ rtlphy->tx_power_by_rate_offset
+ [band][path][txnum]
+ [vht_rates_2t[i]] =
+ value - base;
+ }
+ }
+ }
+ }
+
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, "<===%s()\n", __func__);
+}
+
+static void
+_rtl8822be_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw)
+{
+ /* copy rate_section from
+ * tx_power_by_rate_offset[][rate] to txpwr_by_rate_base_24g/_5g[][rs]
+ */
+ _rtl8822be_phy_store_txpower_by_rate_base(hw);
+
+ /* convert tx_power_by_rate_offset[] to relative value */
+ _rtl8822be_phy_convert_txpower_dbm_to_relative_value(hw);
+}
+
+/* string is in decimal */
+static bool _rtl8822be_get_integer_from_string(char *str, u8 *pint)
+{
+ u16 i = 0;
+ *pint = 0;
+
+ while (str[i] != '\0') {
+ if (str[i] >= '0' && str[i] <= '9') {
+ *pint *= 10;
+ *pint += (str[i] - '0');
+ } else {
+ return false;
+ }
+ ++i;
+ }
+
+ return true;
+}
+
+static bool _rtl8822be_eq_n_byte(u8 *str1, u8 *str2, u32 num)
+{
+ if (num == 0)
+ return false;
+ while (num > 0) {
+ num--;
+ if (str1[num] != str2[num])
+ return false;
+ }
+ return true;
+}
+
+static char _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(struct ieee80211_hw *hw,
+ u8 band, u8 channel)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ char channel_index = -1;
+ u8 i = 0;
+
+ if (band == BAND_ON_2_4G) {
+ channel_index = channel - 1;
+ } else if (band == BAND_ON_5G) {
+ for (i = 0; i < sizeof(rtl_channel5g) / sizeof(u8); ++i) {
+ if (rtl_channel5g[i] == channel)
+ channel_index = i;
+ }
+ } else {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Band %d in %s",
+ band, __func__);
+ }
+
+ if (channel_index == -1)
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ "Invalid Channel %d of Band %d in %s", channel, band,
+ __func__);
+
+ return channel_index;
+}
+
+void rtl8822be_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregulation,
+ u8 *pband, u8 *pbandwidth,
+ u8 *prate_section, u8 *prf_path,
+ u8 *pchannel, u8 *ppower_limit)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ u8 regulation = 0, bandwidth = 0, rate_section = 0, channel;
+ u8 channel_index;
+ char power_limit = 0, prev_power_limit, ret;
+
+ if (!_rtl8822be_get_integer_from_string((char *)pchannel, &channel) ||
+ !_rtl8822be_get_integer_from_string((char *)ppower_limit,
+ &power_limit)) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ "Illegal index of pwr_lmt table [chnl %d][val %d]\n",
+ channel, power_limit);
+ }
+
+ power_limit =
+ power_limit > MAX_POWER_INDEX ? MAX_POWER_INDEX : power_limit;
+
+ if (_rtl8822be_eq_n_byte(pregulation, (u8 *)("FCC"), 3))
+ regulation = 0;
+ else if (_rtl8822be_eq_n_byte(pregulation, (u8 *)("MKK"), 3))
+ regulation = 1;
+ else if (_rtl8822be_eq_n_byte(pregulation, (u8 *)("ETSI"), 4))
+ regulation = 2;
+ else if (_rtl8822be_eq_n_byte(pregulation, (u8 *)("WW13"), 4))
+ regulation = 3;
+
+ if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("CCK"), 3))
+ rate_section = CCK;
+ else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("OFDM"), 4))
+ rate_section = OFDM;
+ else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
+ _rtl8822be_eq_n_byte(prf_path, (u8 *)("1T"), 2))
+ rate_section = HT_MCS0_MCS7;
+ else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
+ _rtl8822be_eq_n_byte(prf_path, (u8 *)("2T"), 2))
+ rate_section = HT_MCS8_MCS15;
+ else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
+ _rtl8822be_eq_n_byte(prf_path, (u8 *)("1T"), 2))
+ rate_section = VHT_1SSMCS0_1SSMCS9;
+ else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
+ _rtl8822be_eq_n_byte(prf_path, (u8 *)("2T"), 2))
+ rate_section = VHT_2SSMCS0_2SSMCS9;
+
+ if (_rtl8822be_eq_n_byte(pbandwidth, (u8 *)("20M"), 3))
+ bandwidth = HT_CHANNEL_WIDTH_20;
+ else if (_rtl8822be_eq_n_byte(pbandwidth, (u8 *)("40M"), 3))
+ bandwidth = HT_CHANNEL_WIDTH_20_40;
+ else if (_rtl8822be_eq_n_byte(pbandwidth, (u8 *)("80M"), 3))
+ bandwidth = HT_CHANNEL_WIDTH_80;
+ else if (_rtl8822be_eq_n_byte(pbandwidth, (u8 *)("160M"), 4))
+ bandwidth = 3;
+
+ if (_rtl8822be_eq_n_byte(pband, (u8 *)("2.4G"), 4)) {
+ ret = _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(hw, BAND_ON_2_4G,
+ channel);
+
+ if (ret == -1)
+ return;
+
+ channel_index = ret;
+
+ prev_power_limit =
+ rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
+ [rate_section][channel_index]
+ [RF90_PATH_A];
+
+ if (power_limit < prev_power_limit)
+ rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
+ [rate_section][channel_index]
+ [RF90_PATH_A] = power_limit;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ "2.4G [regula %d][bw %d][sec %d][chnl %d][val %d]\n",
+ regulation, bandwidth, rate_section, channel_index,
+ rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
+ [rate_section][channel_index]
+ [RF90_PATH_A]);
+ } else if (_rtl8822be_eq_n_byte(pband, (u8 *)("5G"), 2)) {
+ ret = _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(hw, BAND_ON_5G,
+ channel);
+
+ if (ret == -1)
+ return;
+
+ channel_index = ret;
+
+ prev_power_limit =
+ rtlphy->txpwr_limit_5g[regulation][bandwidth]
+ [rate_section][channel_index]
+ [RF90_PATH_A];
+
+ if (power_limit < prev_power_limit)
+ rtlphy->txpwr_limit_5g[regulation][bandwidth]
+ [rate_section][channel_index]
+ [RF90_PATH_A] = power_limit;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ "5G: [regul %d][bw %d][sec %d][chnl %d][val %d]\n",
+ regulation, bandwidth, rate_section, channel,
+ rtlphy->txpwr_limit_5g[regulation][bandwidth]
+ [rate_section][channel_index]
+ [RF90_PATH_A]);
+
+ } else {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ "Cannot recognize the band info in %s\n", pband);
+ return;
+ }
+}
+
+bool rtl8822be_load_txpower_by_rate(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ bool rtstatus = true;
+
+ _rtl8822be_phy_init_tx_power_by_rate(hw);
+
+ rtstatus = rtlpriv->phydm.ops->phydm_load_txpower_by_rate(rtlpriv);
+
+ if (!rtstatus) {
+ pr_err("BB_PG Reg Fail!!");
+ return false;
+ }
+
+ _rtl8822be_phy_txpower_by_rate_configuration(hw);
+
+ return true;
+}
+
+bool rtl8822be_load_txpower_limit(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
+ bool rtstatus = true;
+
+ _rtl8822be_phy_init_txpower_limit(hw);
+
+ if (rtlefuse->eeprom_regulatory == 1)
+ ;
+ else
+ return true;
+
+ rtstatus = rtlpriv->phydm.ops->phydm_load_txpower_limit(rtlpriv);
+
+ if (!rtstatus) {
+ pr_err("RF TxPwr Limit Fail!!");
+ return false;
+ }
+
+ _rtl8822be_phy_convert_txpower_limit_to_power_index(hw);
+
+ return true;
+}
+
+static void _rtl8822be_get_rate_values_of_tx_power_by_rate(
+ struct ieee80211_hw *hw, u32 reg_addr, u32 bit_mask, u32 value,
+ u8 *rate, s8 *pwr_by_rate_val, u8 *rate_num)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 /*index = 0,*/ i = 0;
+
+ switch (reg_addr) {
+ case 0xE00: /*rTxAGC_A_Rate18_06:*/
+ case 0x830: /*rTxAGC_B_Rate18_06:*/
+ rate[0] = DESC_RATE6M;
+ rate[1] = DESC_RATE9M;
+ rate[2] = DESC_RATE12M;
+ rate[3] = DESC_RATE18M;
+ for (i = 0; i < 4; ++i) {
+ pwr_by_rate_val[i] =
+ (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((value >> (i * 8)) & 0xF));
+ }
+ *rate_num = 4;
+ break;
+
+ case 0xE04: /*rTxAGC_A_Rate54_24:*/
+ case 0x834: /*rTxAGC_B_Rate54_24:*/
+ rate[0] = DESC_RATE24M;
+ rate[1] = DESC_RATE36M;
+ rate[2] = DESC_RATE48M;
+ rate[3] = DESC_RATE54M;
+ for (i = 0; i < 4; ++i) {
+ pwr_by_rate_val[i] =
+ (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((value >> (i * 8)) & 0xF));
+ }
+ *rate_num = 4;
+ break;
+
+ case 0xE08: /*rTxAGC_A_CCK1_Mcs32:*/
+ rate[0] = DESC_RATE1M;
+ pwr_by_rate_val[0] = (s8)((((value >> (8 + 4)) & 0xF)) * 10 +
+ ((value >> 8) & 0xF));
+ *rate_num = 1;
+ break;
+
+ case 0x86C: /*rTxAGC_B_CCK11_A_CCK2_11:*/
+ if (bit_mask == 0xffffff00) {
+ rate[0] = DESC_RATE2M;
+ rate[1] = DESC_RATE5_5M;
+ rate[2] = DESC_RATE11M;
+ for (i = 1; i < 4; ++i) {
+ pwr_by_rate_val[i - 1] = (s8)(
+ (((value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((value >> (i * 8)) & 0xF));
+ }
+ *rate_num = 3;
+ } else if (bit_mask == 0x000000ff) {
+ rate[0] = DESC_RATE11M;
+ pwr_by_rate_val[0] = (s8)((((value >> 4) & 0xF)) * 10 +
+ (value & 0xF));
+ *rate_num = 1;
+ }
+ break;
+
+ case 0xE10: /*rTxAGC_A_Mcs03_Mcs00:*/
+ case 0x83C: /*rTxAGC_B_Mcs03_Mcs00:*/
+ rate[0] = DESC_RATEMCS0;
+ rate[1] = DESC_RATEMCS1;
+ rate[2] = DESC_RATEMCS2;
+ rate[3] = DESC_RATEMCS3;
+ for (i = 0; i < 4; ++i) {
+ pwr_by_rate_val[i] =
+ (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((value >> (i * 8)) & 0xF));
+ }
+ *rate_num = 4;
+ break;
+
+ case 0xE14: /*rTxAGC_A_Mcs07_Mcs04:*/
+ case 0x848: /*rTxAGC_B_Mcs07_Mcs04:*/
+ rate[0] = DESC_RATEMCS4;
+ rate[1] = DESC_RATEMCS5;
+ rate[2] = DESC_RATEMCS6;
+ rate[3] = DESC_RATEMCS7;
+ for (i = 0; i < 4; ++i) {
+ pwr_by_rate_val[i] =
+ (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((value >> (i * 8)) & 0xF));
+ }
+ *rate_num = 4;
+ break;
+
+ case 0xE18: /*rTxAGC_A_Mcs11_Mcs08:*/
+ case 0x84C: /*rTxAGC_B_Mcs11_Mcs08:*/
+ rate[0] = DESC_RATEMCS8;
+ rate[1] = DESC_RATEMCS9;
+ rate[2] = DESC_RATEMCS10;
+ rate[3] = DESC_RATEMCS11;
+ for (i = 0; i < 4; ++i) {
+ pwr_by_rate_val[i] =
+ (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((value >> (i * 8)) & 0xF));
+ }
+ *rate_num = 4;
+ break;
+
+ case 0xE1C: /*rTxAGC_A_Mcs15_Mcs12:*/
+ case 0x868: /*rTxAGC_B_Mcs15_Mcs12:*/
+ rate[0] = DESC_RATEMCS12;
+ rate[1] = DESC_RATEMCS13;
+ rate[2] = DESC_RATEMCS14;
+ rate[3] = DESC_RATEMCS15;
+ for (i = 0; i < 4; ++i) {
+ pwr_by_rate_val[i] =
+ (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((value >> (i * 8)) & 0xF));
+ }
+ *rate_num = 4;
+
+ break;
+
+ case 0x838: /*rTxAGC_B_CCK1_55_Mcs32:*/
+ rate[0] = DESC_RATE1M;
+ rate[1] = DESC_RATE2M;
+ rate[2] = DESC_RATE5_5M;
+ for (i = 1; i < 4; ++i) {
+ pwr_by_rate_val[i - 1] =
+ (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((value >> (i * 8)) & 0xF));
+ }
+ *rate_num = 3;
+ break;
+
+ case 0xC20:
+ case 0xE20:
+ case 0x1820:
+ case 0x1a20:
+ rate[0] = DESC_RATE1M;
+ rate[1] = DESC_RATE2M;
+ rate[2] = DESC_RATE5_5M;
+ rate[3] = DESC_RATE11M;
+ for (i = 0; i < 4; ++i) {
+ pwr_by_rate_val[i] =
+ (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((value >> (i * 8)) & 0xF));
+ }
+ *rate_num = 4;
+ break;
+
+ case 0xC24:
+ case 0xE24:
+ case 0x1824:
+ case 0x1a24:
+ rate[0] = DESC_RATE6M;
+ rate[1] = DESC_RATE9M;
+ rate[2] = DESC_RATE12M;
+ rate[3] = DESC_RATE18M;
+ for (i = 0; i < 4; ++i) {
+ pwr_by_rate_val[i] =
+ (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((value >> (i * 8)) & 0xF));
+ }
+ *rate_num = 4;
+ break;
+
+ case 0xC28:
+ case 0xE28:
+ case 0x1828:
+ case 0x1a28:
+ rate[0] = DESC_RATE24M;
+ rate[1] = DESC_RATE36M;
+ rate[2] = DESC_RATE48M;
+ rate[3] = DESC_RATE54M;
+ for (i = 0; i < 4; ++i) {
+ pwr_by_rate_val[i] =
+ (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((value >> (i * 8)) & 0xF));
+ }
+ *rate_num = 4;
+ break;
+
+ case 0xC2C:
+ case 0xE2C:
+ case 0x182C:
+ case 0x1a2C:
+ rate[0] = DESC_RATEMCS0;
+ rate[1] = DESC_RATEMCS1;
+ rate[2] = DESC_RATEMCS2;
+ rate[3] = DESC_RATEMCS3;
+ for (i = 0; i < 4; ++i) {
+ pwr_by_rate_val[i] =
+ (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((value >> (i * 8)) & 0xF));
+ }
+ *rate_num = 4;
+ break;
+
+ case 0xC30:
+ case 0xE30:
+ case 0x1830:
+ case 0x1a30:
+ rate[0] = DESC_RATEMCS4;
+ rate[1] = DESC_RATEMCS5;
+ rate[2] = DESC_RATEMCS6;
+ rate[3] = DESC_RATEMCS7;
+ for (i = 0; i < 4; ++i) {
+ pwr_by_rate_val[i] =
+ (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((value >> (i * 8)) & 0xF));
+ }
+ *rate_num = 4;
+ break;
+
+ case 0xC34:
+ case 0xE34:
+ case 0x1834:
+ case 0x1a34:
+ rate[0] = DESC_RATEMCS8;
+ rate[1] = DESC_RATEMCS9;
+ rate[2] = DESC_RATEMCS10;
+ rate[3] = DESC_RATEMCS11;
+ for (i = 0; i < 4; ++i) {
+ pwr_by_rate_val[i] =
+ (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((value >> (i * 8)) & 0xF));
+ }
+ *rate_num = 4;
+ break;
+
+ case 0xC38:
+ case 0xE38:
+ case 0x1838:
+ case 0x1a38:
+ rate[0] = DESC_RATEMCS12;
+ rate[1] = DESC_RATEMCS13;
+ rate[2] = DESC_RATEMCS14;
+ rate[3] = DESC_RATEMCS15;
+ for (i = 0; i < 4; ++i) {
+ pwr_by_rate_val[i] =
+ (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((value >> (i * 8)) & 0xF));
+ }
+ *rate_num = 4;
+ break;
+
+ case 0xC3C:
+ case 0xE3C:
+ case 0x183C:
+ case 0x1a3C:
+ rate[0] = DESC_RATEVHT1SS_MCS0;
+ rate[1] = DESC_RATEVHT1SS_MCS1;
+ rate[2] = DESC_RATEVHT1SS_MCS2;
+ rate[3] = DESC_RATEVHT1SS_MCS3;
+ for (i = 0; i < 4; ++i) {
+ pwr_by_rate_val[i] =
+ (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((value >> (i * 8)) & 0xF));
+ }
+ *rate_num = 4;
+ break;
+
+ case 0xC40:
+ case 0xE40:
+ case 0x1840:
+ case 0x1a40:
+ rate[0] = DESC_RATEVHT1SS_MCS4;
+ rate[1] = DESC_RATEVHT1SS_MCS5;
+ rate[2] = DESC_RATEVHT1SS_MCS6;
+ rate[3] = DESC_RATEVHT1SS_MCS7;
+ for (i = 0; i < 4; ++i) {
+ pwr_by_rate_val[i] =
+ (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((value >> (i * 8)) & 0xF));
+ }
+ *rate_num = 4;
+ break;
+
+ case 0xC44:
+ case 0xE44:
+ case 0x1844:
+ case 0x1a44:
+ rate[0] = DESC_RATEVHT1SS_MCS8;
+ rate[1] = DESC_RATEVHT1SS_MCS9;
+ rate[2] = DESC_RATEVHT2SS_MCS0;
+ rate[3] = DESC_RATEVHT2SS_MCS1;
+ for (i = 0; i < 4; ++i) {
+ pwr_by_rate_val[i] =
+ (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((value >> (i * 8)) & 0xF));
+ }
+ *rate_num = 4;
+ break;
+
+ case 0xC48:
+ case 0xE48:
+ case 0x1848:
+ case 0x1a48:
+ rate[0] = DESC_RATEVHT2SS_MCS2;
+ rate[1] = DESC_RATEVHT2SS_MCS3;
+ rate[2] = DESC_RATEVHT2SS_MCS4;
+ rate[3] = DESC_RATEVHT2SS_MCS5;
+ for (i = 0; i < 4; ++i) {
+ pwr_by_rate_val[i] =
+ (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((value >> (i * 8)) & 0xF));
+ }
+ *rate_num = 4;
+ break;
+
+ case 0xC4C:
+ case 0xE4C:
+ case 0x184C:
+ case 0x1a4C:
+ rate[0] = DESC_RATEVHT2SS_MCS6;
+ rate[1] = DESC_RATEVHT2SS_MCS7;
+ rate[2] = DESC_RATEVHT2SS_MCS8;
+ rate[3] = DESC_RATEVHT2SS_MCS9;
+ for (i = 0; i < 4; ++i) {
+ pwr_by_rate_val[i] =
+ (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((value >> (i * 8)) & 0xF));
+ }
+ *rate_num = 4;
+ break;
+
+ default:
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ "Invalid reg_addr 0x%x in %s()\n", reg_addr, __func__);
+ break;
+ };
+}
+
+void rtl8822be_store_tx_power_by_rate(struct ieee80211_hw *hw, u32 band,
+ u32 rfpath, u32 txnum, u32 regaddr,
+ u32 bitmask, u32 data)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ u8 i = 0, rates[4] = {0}, rate_num = 0;
+ s8 pwr_by_rate_val[4] = {0};
+
+ _rtl8822be_get_rate_values_of_tx_power_by_rate(
+ hw, regaddr, bitmask, data, rates, pwr_by_rate_val, &rate_num);
+
+ if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid Band %d\n",
+ band);
+ band = BAND_ON_2_4G;
+ }
+ if (rfpath >= MAX_RF_PATH) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid RfPath %d\n",
+ rfpath);
+ rfpath = MAX_RF_PATH - 1;
+ }
+ if (txnum >= MAX_RF_PATH) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid TxNum %d\n",
+ txnum);
+ txnum = MAX_RF_PATH - 1;
+ }
+
+ for (i = 0; i < rate_num; ++i) {
+ u8 rate_idx = rates[i];
+
+ if (IS_1T_RATE(rates[i]))
+ txnum = RF_1TX;
+ else if (IS_2T_RATE(rates[i]))
+ txnum = RF_2TX;
+ else
+ WARN_ON(1);
+
+ rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_idx] =
+ pwr_by_rate_val[i];
+
+ RT_TRACE(
+ rtlpriv, COMP_INIT, DBG_LOUD,
+ "TxPwrByRateOffset[Band %d][RfPath %d][TxNum %d][rate_idx %d] = 0x%x\n",
+ band, rfpath, txnum, rate_idx,
+ rtlphy->tx_power_by_rate_offset[band][rfpath][txnum]
+ [rate_idx]);
+ }
+}
+
+static void
+_rtl8822be_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+
+ rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
+ rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
+
+ rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
+ rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
+
+ rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
+ rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
+
+ rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = RA_LSSIWRITE_8822B;
+ rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = RB_LSSIWRITE_8822B;
+
+ rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RHSSIREAD_8822BE;
+ rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RHSSIREAD_8822BE;
+
+ rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RA_SIREAD_8822B;
+ rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RB_SIREAD_8822B;
+
+ rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = RA_PIREAD_8822B;
+ rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = RB_PIREAD_8822B;
+}
+
+void rtl8822be_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ u8 txpwr_level;
+ long txpwr_dbm;
+
+ txpwr_level = rtlphy->cur_cck_txpwridx;
+ txpwr_dbm = _rtl8822be_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B,
+ txpwr_level);
+ txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
+ if (_rtl8822be_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) >
+ txpwr_dbm)
+ txpwr_dbm = _rtl8822be_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
+ txpwr_level);
+ txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
+ if (_rtl8822be_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
+ txpwr_level) > txpwr_dbm)
+ txpwr_dbm = _rtl8822be_phy_txpwr_idx_to_dbm(
+ hw, WIRELESS_MODE_N_24G, txpwr_level);
+ *powerlevel = txpwr_dbm;
+}
+
+static bool _rtl8822be_phy_get_chnl_index(u8 channel, u8 *chnl_index)
+{
+ u8 rtl_channel5g[CHANNEL_MAX_NUMBER_5G] = {
+ 36, 38, 40, 42, 44, 46, 48, /* Band 1 */
+ 52, 54, 56, 58, 60, 62, 64, /* Band 2 */
+ 100, 102, 104, 106, 108, 110, 112, /* Band 3 */
+ 116, 118, 120, 122, 124, 126, 128, /* Band 3 */
+ 132, 134, 136, 138, 140, 142, 144, /* Band 3 */
+ 149, 151, 153, 155, 157, 159, 161, /* Band 4 */
+ 165, 167, 169, 171, 173, 175, 177}; /* Band 4 */
+ u8 i = 0;
+ bool in_24g = true;
+
+ if (channel <= 14) {
+ in_24g = true;
+ *chnl_index = channel - 1;
+ } else {
+ in_24g = false;
+
+ for (i = 0; i < CHANNEL_MAX_NUMBER_5G; ++i) {
+ if (rtl_channel5g[i] == channel) {
+ *chnl_index = i;
+ return in_24g;
+ }
+ }
+ }
+ return in_24g;
+}
+
+static char _rtl8822be_phy_get_world_wide_limit(char *limit_table)
+{
+ char min = limit_table[0];
+ u8 i = 0;
+
+ for (i = 0; i < MAX_REGULATION_NUM; ++i) {
+ if (limit_table[i] < min)
+ min = limit_table[i];
+ }
+ return min;
+}
+
+static char _rtl8822be_phy_get_txpower_limit(struct ieee80211_hw *hw, u8 band,
+ enum ht_channel_width bandwidth,
+ enum radio_path rf_path, u8 rate,
+ u8 channel)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ short regulation = -1, rate_section = -1, channel_index = -1;
+ char power_limit = MAX_POWER_INDEX;
+
+ if (rtlefuse->eeprom_regulatory == 2)
+ return MAX_POWER_INDEX;
+
+ regulation = TXPWR_LMT_WW;
+
+ switch (rate) {
+ case DESC_RATE1M:
+ case DESC_RATE2M:
+ case DESC_RATE5_5M:
+ case DESC_RATE11M:
+ rate_section = CCK;
+ break;
+
+ case DESC_RATE6M:
+ case DESC_RATE9M:
+ case DESC_RATE12M:
+ case DESC_RATE18M:
+ case DESC_RATE24M:
+ case DESC_RATE36M:
+ case DESC_RATE48M:
+ case DESC_RATE54M:
+ rate_section = OFDM;
+ break;
+
+ case DESC_RATEMCS0:
+ case DESC_RATEMCS1:
+ case DESC_RATEMCS2:
+ case DESC_RATEMCS3:
+ case DESC_RATEMCS4:
+ case DESC_RATEMCS5:
+ case DESC_RATEMCS6:
+ case DESC_RATEMCS7:
+ rate_section = HT_MCS0_MCS7;
+ break;
+
+ case DESC_RATEMCS8:
+ case DESC_RATEMCS9:
+ case DESC_RATEMCS10:
+ case DESC_RATEMCS11:
+ case DESC_RATEMCS12:
+ case DESC_RATEMCS13:
+ case DESC_RATEMCS14:
+ case DESC_RATEMCS15:
+ rate_section = HT_MCS8_MCS15;
+ break;
+
+ case DESC_RATEVHT1SS_MCS0:
+ case DESC_RATEVHT1SS_MCS1:
+ case DESC_RATEVHT1SS_MCS2:
+ case DESC_RATEVHT1SS_MCS3:
+ case DESC_RATEVHT1SS_MCS4:
+ case DESC_RATEVHT1SS_MCS5:
+ case DESC_RATEVHT1SS_MCS6:
+ case DESC_RATEVHT1SS_MCS7:
+ case DESC_RATEVHT1SS_MCS8:
+ case DESC_RATEVHT1SS_MCS9:
+ rate_section = VHT_1SSMCS0_1SSMCS9;
+ break;
+
+ case DESC_RATEVHT2SS_MCS0:
+ case DESC_RATEVHT2SS_MCS1:
+ case DESC_RATEVHT2SS_MCS2:
+ case DESC_RATEVHT2SS_MCS3:
+ case DESC_RATEVHT2SS_MCS4:
+ case DESC_RATEVHT2SS_MCS5:
+ case DESC_RATEVHT2SS_MCS6:
+ case DESC_RATEVHT2SS_MCS7:
+ case DESC_RATEVHT2SS_MCS8:
+ case DESC_RATEVHT2SS_MCS9:
+ rate_section = VHT_2SSMCS0_2SSMCS9;
+ break;
+
+ default:
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Wrong rate 0x%x\n",
+ rate);
+ break;
+ }
+
+ if (band == BAND_ON_5G && rate_section == 0)
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ "Wrong rate 0x%x: No CCK in 5G Band\n", rate);
+
+ /* workaround for wrong index combination to obtain tx power limit,
+ * OFDM only exists in BW 20M
+ */
+ if (rate_section == 1)
+ bandwidth = 0;
+
+ /* workaround for wrong index combination to obtain tx power limit,
+ * CCK table will only be given in BW 20M
+ */
+ if (rate_section == 0)
+ bandwidth = 0;
+
+ /* workaround for wrong indxe combination to obtain tx power limit,
+ * HT on 80M will reference to HT on 40M
+ */
+ if ((rate_section == 2 || rate_section == 3) && band == BAND_ON_5G &&
+ bandwidth == 2)
+ bandwidth = 1;
+
+ if (band == BAND_ON_2_4G)
+ channel_index = _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(
+ hw, BAND_ON_2_4G, channel);
+ else if (band == BAND_ON_5G)
+ channel_index = _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(
+ hw, BAND_ON_5G, channel);
+ else if (band == BAND_ON_BOTH)
+ ; /* BAND_ON_BOTH don't care temporarily */
+
+ if (band >= BANDMAX || regulation == -1 || bandwidth == -1 ||
+ rate_section == -1 || channel_index == -1) {
+ RT_TRACE(
+ rtlpriv, COMP_POWER, DBG_LOUD,
+ "Wrong index value to access power limit table [band %d][regulation %d][bandwidth %d][rf_path %d][rate_section %d][chnl %d]\n",
+ band, regulation, bandwidth, rf_path, rate_section,
+ channel_index);
+ return MAX_POWER_INDEX;
+ }
+
+ if (band == BAND_ON_2_4G) {
+ char limits[10] = {0};
+ u8 i = 0;
+
+ for (i = 0; i < 4; ++i)
+ limits[i] = rtlphy->txpwr_limit_2_4g[i][bandwidth]
+ [rate_section]
+ [channel_index]
+ [rf_path];
+
+ power_limit =
+ (regulation == TXPWR_LMT_WW) ?
+ _rtl8822be_phy_get_world_wide_limit(limits) :
+ rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
+ [rate_section]
+ [channel_index]
+ [rf_path];
+
+ } else if (band == BAND_ON_5G) {
+ char limits[10] = {0};
+ u8 i = 0;
+
+ for (i = 0; i < MAX_REGULATION_NUM; ++i)
+ limits[i] =
+ rtlphy->txpwr_limit_5g[i][bandwidth]
+ [rate_section]
+ [channel_index][rf_path];
+
+ power_limit =
+ (regulation == TXPWR_LMT_WW) ?
+ _rtl8822be_phy_get_world_wide_limit(limits) :
+ rtlphy->txpwr_limit_5g[regulation]
+ [channel_index]
+ [rate_section]
+ [channel_index][rf_path];
+ } else
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ "No power limit table of the specified band\n");
+
+ return power_limit;
+}
+
+static char
+_rtl8822be_phy_get_txpower_by_rate(struct ieee80211_hw *hw, u8 band, u8 path,
+ u8 rate /* enum rtl_desc8822b_rate */)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ u8 tx_num;
+ char tx_pwr_diff = 0;
+
+ if (band != BAND_ON_2_4G && band != BAND_ON_5G)
+ return tx_pwr_diff;
+
+ if (path > RF90_PATH_B)
+ return tx_pwr_diff;
+
+ if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
+ (rate >= DESC_RATEVHT2SS_MCS0 && rate <= DESC_RATEVHT2SS_MCS9))
+ tx_num = RF_2TX;
+ else
+ tx_num = RF_1TX;
+
+ tx_pwr_diff = (char)(rtlphy->tx_power_by_rate_offset[band][path][tx_num]
+ [rate] &
+ 0xff);
+
+ return tx_pwr_diff;
+}
+
+u8 rtl8822be_get_txpower_index(struct ieee80211_hw *hw, u8 path, u8 rate,
+ u8 bandwidth, u8 channel)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u8 index = (channel - 1);
+ u8 txpower = 0;
+ bool in_24g = false;
+ char limit;
+ char powerdiff_byrate = 0;
+
+ if (((rtlhal->current_bandtype == BAND_ON_2_4G) &&
+ (channel > 14 || channel < 1)) ||
+ ((rtlhal->current_bandtype == BAND_ON_5G) && (channel <= 14))) {
+ index = 0;
+ RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+ "Illegal channel!!\n");
+ }
+
+ /* 1. base tx power */
+ in_24g = _rtl8822be_phy_get_chnl_index(channel, &index);
+ if (in_24g) {
+ if (RX_HAL_IS_CCK_RATE(rate))
+ txpower = rtlefuse->txpwrlevel_cck[path][index];
+ else if (rate >= DESC_RATE6M)
+ txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
+ else
+ RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+ "invalid rate\n");
+
+ if (rate >= DESC_RATE6M && rate <= DESC_RATE54M &&
+ !RX_HAL_IS_CCK_RATE(rate))
+ txpower += rtlefuse->txpwr_legacyhtdiff[path][TX_1S];
+
+ if (bandwidth == HT_CHANNEL_WIDTH_20) {
+ if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
+ (rate >= DESC_RATEVHT1SS_MCS0 &&
+ rate <= DESC_RATEVHT2SS_MCS9))
+ txpower +=
+ rtlefuse->txpwr_ht20diff[path][TX_1S];
+ if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
+ (rate >= DESC_RATEVHT2SS_MCS0 &&
+ rate <= DESC_RATEVHT2SS_MCS9))
+ txpower +=
+ rtlefuse->txpwr_ht20diff[path][TX_2S];
+ } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
+ if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
+ (rate >= DESC_RATEVHT1SS_MCS0 &&
+ rate <= DESC_RATEVHT2SS_MCS9))
+ txpower +=
+ rtlefuse->txpwr_ht40diff[path][TX_1S];
+ if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
+ (rate >= DESC_RATEVHT2SS_MCS0 &&
+ rate <= DESC_RATEVHT2SS_MCS9))
+ txpower +=
+ rtlefuse->txpwr_ht40diff[path][TX_2S];
+ } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
+ if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
+ (rate >= DESC_RATEVHT1SS_MCS0 &&
+ rate <= DESC_RATEVHT2SS_MCS9))
+ txpower +=
+ rtlefuse->txpwr_ht40diff[path][TX_1S];
+ if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
+ (rate >= DESC_RATEVHT2SS_MCS0 &&
+ rate <= DESC_RATEVHT2SS_MCS9))
+ txpower +=
+ rtlefuse->txpwr_ht40diff[path][TX_2S];
+ }
+
+ } else {
+ if (rate >= DESC_RATE6M)
+ txpower = rtlefuse->txpwr_5g_bw40base[path][index];
+ else
+ RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_WARNING,
+ "INVALID Rate.\n");
+
+ if (rate >= DESC_RATE6M && rate <= DESC_RATE54M &&
+ !RX_HAL_IS_CCK_RATE(rate))
+ txpower += rtlefuse->txpwr_5g_ofdmdiff[path][TX_1S];
+
+ if (bandwidth == HT_CHANNEL_WIDTH_20) {
+ if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
+ (rate >= DESC_RATEVHT1SS_MCS0 &&
+ rate <= DESC_RATEVHT2SS_MCS9))
+ txpower += rtlefuse->txpwr_5g_bw20diff[path]
+ [TX_1S];
+ if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
+ (rate >= DESC_RATEVHT2SS_MCS0 &&
+ rate <= DESC_RATEVHT2SS_MCS9))
+ txpower += rtlefuse->txpwr_5g_bw20diff[path]
+ [TX_2S];
+ } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
+ if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
+ (rate >= DESC_RATEVHT1SS_MCS0 &&
+ rate <= DESC_RATEVHT2SS_MCS9))
+ txpower += rtlefuse->txpwr_5g_bw40diff[path]
+ [TX_1S];
+ if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
+ (rate >= DESC_RATEVHT2SS_MCS0 &&
+ rate <= DESC_RATEVHT2SS_MCS9))
+ txpower += rtlefuse->txpwr_5g_bw40diff[path]
+ [TX_2S];
+ } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
+ u8 i = 0;
+
+ for (i = 0; i < sizeof(rtl_channel5g_80m) / sizeof(u8);
+ ++i)
+ if (rtl_channel5g_80m[i] == channel)
+ index = i;
+
+ txpower = rtlefuse->txpwr_5g_bw80base[path][index];
+
+ if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
+ (rate >= DESC_RATEVHT1SS_MCS0 &&
+ rate <= DESC_RATEVHT2SS_MCS9))
+ txpower += rtlefuse->txpwr_5g_bw80diff[path]
+ [TX_1S];
+ if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
+ (rate >= DESC_RATEVHT2SS_MCS0 &&
+ rate <= DESC_RATEVHT2SS_MCS9))
+ txpower += rtlefuse->txpwr_5g_bw80diff[path]
+ [TX_2S];
+ }
+ }
+
+ /* 2. tx power by rate */
+ if (rtlefuse->eeprom_regulatory != 2)
+ powerdiff_byrate = _rtl8822be_phy_get_txpower_by_rate(
+ hw, (u8)(!in_24g), path, rate);
+
+ /* 3. tx power limit */
+ if (rtlefuse->eeprom_regulatory == 1)
+ limit = _rtl8822be_phy_get_txpower_limit(
+ hw, (u8)(!in_24g), bandwidth, path, rate,
+ channel);
+ else
+ limit = MAX_POWER_INDEX;
+
+ /* ----- */
+ powerdiff_byrate = powerdiff_byrate > limit ? limit : powerdiff_byrate;
+
+ txpower += powerdiff_byrate;
+
+ if (txpower > MAX_POWER_INDEX)
+ txpower = MAX_POWER_INDEX;
+
+ return txpower;
+}
+
+static void _rtl8822be_phy_set_txpower_index(struct ieee80211_hw *hw,
+ u8 power_index, u8 path, u8 rate)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 shift = 0;
+ static u32 index;
+
+ /*
+ * For 8822B, phydm api use 4 bytes txagc value
+ * driver must combine every four 1 byte to one 4 byte and send to phydm
+ */
+ shift = rate & 0x03;
+ index |= ((u32)power_index << (shift * 8));
+
+ if (shift == 3) {
+ rate = rate - 3;
+
+ if (!rtlpriv->phydm.ops->phydm_write_txagc(rtlpriv, index, path,
+ rate)) {
+ RT_TRACE(rtlpriv, COMP_TXAGC, DBG_LOUD,
+ "%s(index:%d, rfpath:%d, rate:0x%02x) fail\n",
+ __func__, index, path, rate);
+
+ WARN_ON(1);
+ }
+ index = 0;
+ }
+}
+
+static void _rtl8822be_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
+ u8 *array, u8 path,
+ u8 channel, u8 size)
+{
+ struct rtl_phy *rtlphy = &(rtl_priv(hw)->phy);
+ u8 i;
+ u8 power_index;
+
+ for (i = 0; i < size; i++) {
+ power_index = rtl8822be_get_txpower_index(
+ hw, path, array[i], rtlphy->current_chan_bw, channel);
+ _rtl8822be_phy_set_txpower_index(hw, power_index, path,
+ array[i]);
+ }
+}
+
+void rtl8822be_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
+ u8 channel, u8 path)
+{
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ /*
+ * Below order is *VERY* important!
+ * Because _rtl8822be_phy_set_txpower_index() do actually writing
+ * every four power values.
+ */
+ if (rtlhal->current_bandtype == BAND_ON_2_4G)
+ _rtl8822be_phy_set_txpower_level_by_path(
+ hw, cck_rates, path, channel, sizes_of_cck_retes);
+ _rtl8822be_phy_set_txpower_level_by_path(hw, ofdm_rates, path, channel,
+ sizes_of_ofdm_retes);
+ _rtl8822be_phy_set_txpower_level_by_path(hw, ht_rates_1t, path, channel,
+ sizes_of_ht_retes_1t);
+ _rtl8822be_phy_set_txpower_level_by_path(hw, ht_rates_2t, path, channel,
+ sizes_of_ht_retes_2t);
+ _rtl8822be_phy_set_txpower_level_by_path(hw, vht_rates_1t, path,
+ channel, sizes_of_vht_retes);
+ _rtl8822be_phy_set_txpower_level_by_path(hw, vht_rates_2t, path,
+ channel, sizes_of_vht_retes);
+}
+
+void rtl8822be_phy_set_tx_power_index_by_rs(struct ieee80211_hw *hw, u8 channel,
+ u8 path, enum rate_section rs)
+{
+ struct {
+ u8 *array;
+ u8 size;
+ } rs_ref[MAX_RATE_SECTION] = {
+ {cck_rates, sizes_of_cck_retes},
+ {ofdm_rates, sizes_of_ofdm_retes},
+ {ht_rates_1t, sizes_of_ht_retes_1t},
+ {ht_rates_2t, sizes_of_ht_retes_2t},
+ {vht_rates_1t, sizes_of_vht_retes},
+ {vht_rates_2t, sizes_of_vht_retes},
+ };
+
+ if (rs >= MAX_RATE_SECTION)
+ return;
+
+ _rtl8822be_phy_set_txpower_level_by_path(hw, rs_ref[rs].array, path,
+ channel, rs_ref[rs].size);
+}
+
+void rtl8822be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ u8 path = 0;
+
+ for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; ++path)
+ rtl8822be_phy_set_txpower_level_by_path(hw, channel, path);
+}
+
+static long _rtl8822be_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
+ enum wireless_mode wirelessmode,
+ u8 txpwridx)
+{
+ long offset;
+ long pwrout_dbm;
+
+ switch (wirelessmode) {
+ case WIRELESS_MODE_B:
+ offset = -7;
+ break;
+ case WIRELESS_MODE_G:
+ case WIRELESS_MODE_N_24G:
+ offset = -8;
+ break;
+ default:
+ offset = -8;
+ break;
+ }
+ pwrout_dbm = txpwridx / 2 + offset;
+ return pwrout_dbm;
+}
+
+void rtl8822be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ enum io_type iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
+
+ if (!is_hal_stop(rtlhal)) {
+ switch (operation) {
+ case SCAN_OPT_BACKUP_BAND0:
+ iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
+ (u8 *)&iotype);
+
+ break;
+ case SCAN_OPT_BACKUP_BAND1:
+ iotype = IO_CMD_PAUSE_BAND1_DM_BY_SCAN;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
+ (u8 *)&iotype);
+
+ break;
+ case SCAN_OPT_RESTORE:
+ iotype = IO_CMD_RESUME_DM_BY_SCAN;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
+ (u8 *)&iotype);
+ break;
+ default:
+ pr_err("Unknown Scan Backup operation.\n");
+ break;
+ }
+ }
+}
+
+static u8 _rtl8822be_phy_get_pri_ch_id(struct rtl_priv *rtlpriv)
+{
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ struct rtl_mac *mac = rtl_mac(rtlpriv);
+ u8 pri_ch_idx = 0;
+
+ if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) {
+ /* primary channel is at lower subband of 80MHz & 40MHz */
+ if ((mac->cur_40_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER) &&
+ (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER)) {
+ pri_ch_idx = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
+ /* primary channel is at
+ * lower subband of 80MHz & upper subband of 40MHz
+ */
+ } else if ((mac->cur_40_prime_sc ==
+ HAL_PRIME_CHNL_OFFSET_UPPER) &&
+ (mac->cur_80_prime_sc ==
+ HAL_PRIME_CHNL_OFFSET_LOWER)) {
+ pri_ch_idx = VHT_DATA_SC_20_LOWER_OF_80MHZ;
+ /* primary channel is at
+ * upper subband of 80MHz & lower subband of 40MHz
+ */
+ } else if ((mac->cur_40_prime_sc ==
+ HAL_PRIME_CHNL_OFFSET_LOWER) &&
+ (mac->cur_80_prime_sc ==
+ HAL_PRIME_CHNL_OFFSET_UPPER)) {
+ pri_ch_idx = VHT_DATA_SC_20_UPPER_OF_80MHZ;
+ /* primary channel is at
+ * upper subband of 80MHz & upper subband of 40MHz
+ */
+ } else if ((mac->cur_40_prime_sc ==
+ HAL_PRIME_CHNL_OFFSET_UPPER) &&
+ (mac->cur_80_prime_sc ==
+ HAL_PRIME_CHNL_OFFSET_UPPER)) {
+ pri_ch_idx = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
+ } else {
+ if (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER)
+ pri_ch_idx = VHT_DATA_SC_40_LOWER_OF_80MHZ;
+ else if (mac->cur_80_prime_sc ==
+ HAL_PRIME_CHNL_OFFSET_UPPER)
+ pri_ch_idx = VHT_DATA_SC_40_UPPER_OF_80MHZ;
+ }
+ } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
+ /* primary channel is at upper subband of 40MHz */
+ if (mac->cur_40_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER)
+ pri_ch_idx = VHT_DATA_SC_20_UPPER_OF_80MHZ;
+ /* primary channel is at lower subband of 40MHz */
+ else if (mac->cur_40_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER)
+ pri_ch_idx = VHT_DATA_SC_20_LOWER_OF_80MHZ;
+ else
+ ;
+ }
+
+ return pri_ch_idx;
+}
+
+void rtl8822be_phy_set_bw_mode(struct ieee80211_hw *hw,
+ enum nl80211_channel_type ch_type)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ u8 tmp_bw = rtlphy->current_chan_bw;
+
+ if (rtlphy->set_bwmode_inprogress)
+ return;
+ rtlphy->set_bwmode_inprogress = true;
+ if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
+ /* get primary channel index */
+ u8 pri_ch_idx = _rtl8822be_phy_get_pri_ch_id(rtlpriv);
+
+ /* 3.1 set MAC register */
+ rtlpriv->halmac.ops->halmac_set_bandwidth(
+ rtlpriv, rtlphy->current_channel, pri_ch_idx,
+ rtlphy->current_chan_bw);
+
+ /* 3.2 set BB/RF registet */
+ rtlpriv->phydm.ops->phydm_switch_bandwidth(
+ rtlpriv, pri_ch_idx, rtlphy->current_chan_bw);
+
+ if (!mac->act_scanning)
+ rtlpriv->phydm.ops->phydm_iq_calibrate(rtlpriv);
+
+ rtlphy->set_bwmode_inprogress = false;
+ } else {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ "FALSE driver sleep or unload\n");
+ rtlphy->set_bwmode_inprogress = false;
+ rtlphy->current_chan_bw = tmp_bw;
+ }
+}
+
+u8 rtl8822be_phy_sw_chnl(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ u32 timeout = 1000, timecount = 0;
+ u8 channel = rtlphy->current_channel;
+
+ if (rtlphy->sw_chnl_inprogress)
+ return 0;
+ if (rtlphy->set_bwmode_inprogress)
+ return 0;
+
+ if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
+ RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
+ "sw_chnl_inprogress false driver sleep or unload\n");
+ return 0;
+ }
+ while (rtlphy->lck_inprogress && timecount < timeout) {
+ mdelay(50);
+ timecount += 50;
+ }
+
+ if (rtlphy->current_channel > 14)
+ rtlhal->current_bandtype = BAND_ON_5G;
+ else if (rtlphy->current_channel <= 14)
+ rtlhal->current_bandtype = BAND_ON_2_4G;
+
+ if (rtlpriv->cfg->ops->get_btc_status())
+ rtlpriv->btcoexist.btc_ops->btc_switch_band_notify(
+ rtlpriv, rtlhal->current_bandtype, mac->act_scanning);
+ else
+ rtlpriv->btcoexist.btc_ops->btc_switch_band_notify_wifi_only(
+ rtlpriv, rtlhal->current_bandtype, mac->act_scanning);
+
+ rtlpriv->phydm.ops->phydm_switch_band(rtlpriv, rtlphy->current_channel);
+
+ rtlphy->sw_chnl_inprogress = true;
+ if (channel == 0)
+ channel = 1;
+
+ RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
+ "switch to channel%d, band type is %d\n",
+ rtlphy->current_channel, rtlhal->current_bandtype);
+
+ rtlpriv->phydm.ops->phydm_switch_channel(rtlpriv,
+ rtlphy->current_channel);
+
+ rtlpriv->phydm.ops->phydm_clear_txpowertracking_state(rtlpriv);
+
+ rtl8822be_phy_set_txpower_level(hw, rtlphy->current_channel);
+
+ RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
+ rtlphy->sw_chnl_inprogress = false;
+ return 1;
+}
+
+bool rtl8822be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ bool postprocessing = false;
+
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
+ "-->IO Cmd(%#x), set_io_inprogress(%d)\n", iotype,
+ rtlphy->set_io_inprogress);
+ do {
+ switch (iotype) {
+ case IO_CMD_RESUME_DM_BY_SCAN:
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
+ "[IO CMD] Resume DM after scan.\n");
+ postprocessing = true;
+ break;
+ case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
+ case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
+ "[IO CMD] Pause DM before scan.\n");
+ postprocessing = true;
+ break;
+ default:
+ pr_err("switch case not process\n");
+ break;
+ }
+ } while (false);
+ if (postprocessing && !rtlphy->set_io_inprogress) {
+ rtlphy->set_io_inprogress = true;
+ rtlphy->current_io_type = iotype;
+ } else {
+ return false;
+ }
+ rtl8822be_phy_set_io(hw);
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
+ return true;
+}
+
+static void rtl8822be_phy_set_io(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
+ "--->Cmd(%#x), set_io_inprogress(%d)\n",
+ rtlphy->current_io_type, rtlphy->set_io_inprogress);
+ switch (rtlphy->current_io_type) {
+ case IO_CMD_RESUME_DM_BY_SCAN:
+ break;
+ case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
+ break;
+ case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
+ break;
+ default:
+ pr_err("switch case not process\n");
+ break;
+ }
+ rtlphy->set_io_inprogress = false;
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "(%#x)\n",
+ rtlphy->current_io_type);
+}
+
+static void rtl8822be_phy_set_rf_on(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtl_write_byte(rtlpriv, REG_SPS0_CTRL_8822B, 0x2b);
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN_8822B, 0xE3);
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN_8822B, 0xE2);
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN_8822B, 0xE3);
+ rtl_write_byte(rtlpriv, REG_TXPAUSE_8822B, 0x00);
+}
+
+static bool _rtl8822be_phy_set_rf_power_state(struct ieee80211_hw *hw,
+ enum rf_pwrstate rfpwr_state)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ bool bresult = true;
+ u8 i, queue_id;
+ struct rtl8192_tx_ring *ring = NULL;
+
+ switch (rfpwr_state) {
+ case ERFON:
+ if ((ppsc->rfpwr_state == ERFOFF) &&
+ RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
+ bool rtstatus = false;
+ u32 initialize_count = 0;
+
+ do {
+ initialize_count++;
+ RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+ "IPS Set eRf nic enable\n");
+ rtstatus = rtl_ps_enable_nic(hw);
+ } while ((!rtstatus) && (initialize_count < 10));
+ RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
+ } else {
+ RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+ "Set ERFON slept:%d ms\n",
+ jiffies_to_msecs(jiffies -
+ ppsc->last_sleep_jiffies));
+ ppsc->last_awake_jiffies = jiffies;
+ rtl8822be_phy_set_rf_on(hw);
+ }
+ if (mac->link_state == MAC80211_LINKED)
+ rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK);
+ else
+ rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK);
+ break;
+ case ERFOFF:
+ for (queue_id = 0, i = 0;
+ queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
+ ring = &pcipriv->dev.tx_ring[queue_id];
+ if (queue_id == BEACON_QUEUE ||
+ skb_queue_len(&ring->queue) == 0) {
+ queue_id++;
+ continue;
+ } else {
+ RT_TRACE(
+ rtlpriv, COMP_ERR, DBG_WARNING,
+ "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
+ (i + 1), queue_id,
+ skb_queue_len(&ring->queue));
+
+ udelay(10);
+ i++;
+ }
+ if (i >= MAX_DOZE_WAITING_TIMES_9x) {
+ RT_TRACE(
+ rtlpriv, COMP_ERR, DBG_WARNING,
+ "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
+ MAX_DOZE_WAITING_TIMES_9x, queue_id,
+ skb_queue_len(&ring->queue));
+ break;
+ }
+ }
+
+ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
+ RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+ "IPS Set eRf nic disable\n");
+ rtl_ps_disable_nic(hw);
+ RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
+ } else {
+ if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
+ rtlpriv->cfg->ops->led_control(hw,
+ LED_CTL_NO_LINK);
+ } else {
+ rtlpriv->cfg->ops->led_control(
+ hw, LED_CTL_POWER_OFF);
+ }
+ }
+ break;
+ default:
+ pr_err("switch case not process\n");
+ bresult = false;
+ break;
+ }
+ if (bresult)
+ ppsc->rfpwr_state = rfpwr_state;
+ return bresult;
+}
+
+bool rtl8822be_phy_set_rf_power_state(struct ieee80211_hw *hw,
+ enum rf_pwrstate rfpwr_state)
+{
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+ bool bresult = false;
+
+ if (rfpwr_state == ppsc->rfpwr_state)
+ return bresult;
+ bresult = _rtl8822be_phy_set_rf_power_state(hw, rfpwr_state);
+ return bresult;
+}
diff --git a/drivers/staging/rtlwifi/rtl8822be/phy.h b/drivers/staging/rtlwifi/rtl8822be/phy.h
new file mode 100644
index 0000000..5c33f16
--- /dev/null
+++ b/drivers/staging/rtlwifi/rtl8822be/phy.h
@@ -0,0 +1,145 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL8822BE_PHY_H__
+#define __RTL8822BE_PHY_H__
+
+/* It must always set to 4, otherwise read
+ * efuse table sequence will be wrong.
+ */
+#define MAX_TX_COUNT 4
+#define TX_1S 0
+#define TX_2S 1
+#define TX_3S 2
+#define TX_4S 3
+
+#define MAX_POWER_INDEX 0x3F
+
+#define MAX_PRECMD_CNT 16
+#define MAX_RFDEPENDCMD_CNT 16
+#define MAX_POSTCMD_CNT 16
+
+#define MAX_DOZE_WAITING_TIMES_9x 64
+
+#define RT_CANNOT_IO(hw) false
+#define HIGHPOWER_RADIOA_ARRAYLEN 22
+
+#define IQK_ADDA_REG_NUM 16
+#define IQK_BB_REG_NUM 9
+#define MAX_TOLERANCE 5
+#define IQK_DELAY_TIME 10
+#define index_mapping_NUM 15
+
+#define APK_BB_REG_NUM 5
+#define APK_AFE_REG_NUM 16
+#define APK_CURVE_REG_NUM 4
+#define PATH_NUM 2
+
+#define LOOP_LIMIT 5
+#define MAX_STALL_TIME 50
+#define ANTENNA_DIVERSITY_VALUE 0x80
+#define MAX_TXPWR_IDX_NMODE_92S 63
+#define RESET_CNT_LIMIT 3
+
+#define IQK_ADDA_REG_NUM 16
+#define IQK_MAC_REG_NUM 4
+
+#define RF6052_MAX_PATH 2
+
+#define CT_OFFSET_MAC_ADDR 0X16
+
+#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A
+#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60
+#define CT_OFFSET_HT402S_TX_PWR_IDX_DIFF 0x66
+#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69
+#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C
+
+#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F
+#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72
+
+#define CT_OFFSET_CHANNEL_PLAH 0x75
+#define CT_OFFSET_THERMAL_METER 0x78
+#define CT_OFFSET_RF_OPTION 0x79
+#define CT_OFFSET_VERSION 0x7E
+#define CT_OFFSET_CUSTOMER_ID 0x7F
+
+#define RTL8822BE_MAX_PATH_NUM 2
+
+#define TARGET_CHNL_NUM_2G_5G_8822B 59
+
+u32 rtl8822be_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr,
+ u32 bitmask);
+void rtl8822be_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
+ u32 data);
+u32 rtl8822be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
+ u32 regaddr, u32 bitmask);
+void rtl8822be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
+ u32 regaddr, u32 bitmask, u32 data);
+bool rtl8822be_phy_bb_config(struct ieee80211_hw *hw);
+bool rtl8822be_phy_rf_config(struct ieee80211_hw *hw);
+bool rtl8822be_halmac_cb_init_mac_register(struct rtl_priv *rtlpriv);
+bool rtl8822be_halmac_cb_init_bb_rf_register(struct rtl_priv *rtlpriv);
+void rtl8822be_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel);
+void rtl8822be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
+void rtl8822be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation);
+void rtl8822be_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
+void rtl8822be_phy_set_bw_mode(struct ieee80211_hw *hw,
+ enum nl80211_channel_type ch_type);
+u8 rtl8822be_phy_sw_chnl(struct ieee80211_hw *hw);
+void rtl8822be_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery);
+void rtl8822be_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery);
+void rtl8822be_phy_ap_calibrate(struct ieee80211_hw *hw, char delta);
+void rtl8822be_phy_lc_calibrate(struct ieee80211_hw *hw);
+void rtl8822be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain);
+bool rtl8822be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
+ enum radio_path rfpath);
+bool rtl8822be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
+ enum radio_path rfpath);
+bool rtl8822be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
+bool rtl8822be_phy_set_rf_power_state(struct ieee80211_hw *hw,
+ enum rf_pwrstate rfpwr_state);
+void rtl8822be_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
+ u8 channel, u8 path);
+void rtl8822be_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
+ u8 thermal_value, u8 threshold);
+void rtl8822be_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
+ u8 thermal_value, u8 threshold);
+void rtl8822be_reset_iqk_result(struct ieee80211_hw *hw);
+
+u8 rtl8822be_get_txpower_index(struct ieee80211_hw *hw, u8 path, u8 rate,
+ u8 bandwidth, u8 channel);
+void rtl8822be_phy_set_tx_power_index_by_rs(struct ieee80211_hw *hw, u8 channel,
+ u8 path, enum rate_section rs);
+void rtl8822be_store_tx_power_by_rate(struct ieee80211_hw *hw, u32 band,
+ u32 rfpath, u32 txnum, u32 regaddr,
+ u32 bitmask, u32 data);
+void rtl8822be_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregulation,
+ u8 *pband, u8 *pbandwidth,
+ u8 *prate_section, u8 *prf_path,
+ u8 *pchannel, u8 *ppower_limit);
+bool rtl8822be_load_txpower_by_rate(struct ieee80211_hw *hw);
+bool rtl8822be_load_txpower_limit(struct ieee80211_hw *hw);
+
+#endif
diff --git a/drivers/staging/rtlwifi/rtl8822be/reg.h b/drivers/staging/rtlwifi/rtl8822be/reg.h
new file mode 100644
index 0000000..0dca5dc
--- /dev/null
+++ b/drivers/staging/rtlwifi/rtl8822be/reg.h
@@ -0,0 +1,1653 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL8822B_REG_H__
+#define __RTL8822B_REG_H__
+
+#include "../halmac/halmac_reg_8822b.h"
+#include "../halmac/halmac_bit_8822b.h"
+
+#define TXPKT_BUF_SELECT 0x69
+#define RXPKT_BUF_SELECT 0xA5
+#define DISABLE_TRXPKT_BUF_ACCESS 0x0
+
+/* Page 0 */
+#define REG_LEDCFG2_8822B 0x004E /* need review */
+#define REG_SPS0_CTRL_8822B 0x0011 /* need review: swlps */
+
+#define REG_EFUSE_ACCESS_8822B (REG_PMC_DBG_CTRL2_8822B + 3) /*0x00CF*/
+#define REG_AFE_XTAL_CTRL_8822B REG_AFE_CTRL1_8822B
+#define REG_AFE_PLL_CTRL_8822B REG_AFE_CTRL2_8822B
+
+/* Page 1 */
+
+#define MSR (REG_CR_8822B + 2)
+
+/* for MSR 0x102 */
+#define MSR_NOLINK 0x00
+#define MSR_ADHOC 0x01
+#define MSR_INFRA 0x02
+#define MSR_AP 0x03
+
+/*-----------------------------------------------------
+ *
+ * 0x0200h ~ 0x027Fh TXDMA Configuration
+ *
+ *-----------------------------------------------------
+ */
+
+/*-----------------------------------------------------
+ *
+ * 0x0280h ~ 0x02FFh RXDMA Configuration
+ *
+ *-----------------------------------------------------
+ */
+#define REG_RXDMA_CONTROL_8822B (REG_RXPKT_NUM_8822B + 2) /* 0x0286 */
+
+/*-----------------------------------------------------
+ *
+ * 0x0300h ~ 0x03FFh PCIe
+ *
+ *-----------------------------------------------------
+ */
+
+/* REG_HIMR3_8822B */
+#define IMR_H2CDOK BIT_SETH2CDOK_MASK_8822B
+
+/* spec version 11
+ *-----------------------------------------------------
+ *
+ * 0x0400h ~ 0x047Fh Protocol Configuration
+ *
+ *-----------------------------------------------------
+ */
+
+#define REG_MAX_AGGR_NUM_8822B (REG_PROT_MODE_CTRL_8822B + 2) /*0x04CA*/
+
+/* for RRSR 0x440 */
+#define RRSR_RSC_OFFSET 21
+#define RRSR_SHORT_OFFSET 23
+#define RRSR_RSC_BW_40M 0x600000
+#define RRSR_RSC_UPSUBCHNL 0x400000
+#define RRSR_RSC_LOWSUBCHNL 0x200000
+#define RRSR_1M BIT(0)
+#define RRSR_2M BIT(1)
+#define RRSR_5_5M BIT(2)
+#define RRSR_11M BIT(3)
+#define RRSR_6M BIT(4)
+#define RRSR_9M BIT(5)
+#define RRSR_12M BIT(6)
+#define RRSR_18M BIT(7)
+#define RRSR_24M BIT(8)
+#define RRSR_36M BIT(9)
+#define RRSR_48M BIT(10)
+#define RRSR_54M BIT(11)
+#define RRSR_MCS0 BIT(12)
+#define RRSR_MCS1 BIT(13)
+#define RRSR_MCS2 BIT(14)
+#define RRSR_MCS3 BIT(15)
+#define RRSR_MCS4 BIT(16)
+#define RRSR_MCS5 BIT(17)
+#define RRSR_MCS6 BIT(18)
+#define RRSR_MCS7 BIT(19)
+
+#define RRSR_ALL_CCK (RRSR_1M | RRSR_2M | RRSR_5_5M | RRSR_11M)
+#define RRSR_ALL_OFDM_AG \
+ (RRSR_6M | RRSR_9M | RRSR_12M | RRSR_18M | RRSR_24M | RRSR_36M | \
+ RRSR_48M | RRSR_54M)
+
+/*-----------------------------------------------------
+ *
+ * 0x0500h ~ 0x05FFh EDCA Configuration
+ *
+ *-----------------------------------------------------
+ */
+
+#define REG_SIFS_TRX_8822B (REG_SIFS_8822B + 2) /*0x0516*/
+
+/*-----------------------------------------------------
+ *
+ * 0x0600h ~ 0x07FFh WMAC Configuration
+ *
+ *-----------------------------------------------------
+ */
+
+#define RATR_1M 0x00000001
+#define RATR_2M 0x00000002
+#define RATR_55M 0x00000004
+#define RATR_11M 0x00000008
+#define RATR_6M 0x00000010
+#define RATR_9M 0x00000020
+#define RATR_12M 0x00000040
+#define RATR_18M 0x00000080
+#define RATR_24M 0x00000100
+#define RATR_36M 0x00000200
+#define RATR_48M 0x00000400
+#define RATR_54M 0x00000800
+#define RATR_MCS0 0x00001000
+#define RATR_MCS1 0x00002000
+#define RATR_MCS2 0x00004000
+#define RATR_MCS3 0x00008000
+#define RATR_MCS4 0x00010000
+#define RATR_MCS5 0x00020000
+#define RATR_MCS6 0x00040000
+#define RATR_MCS7 0x00080000
+#define RATR_MCS8 0x00100000
+#define RATR_MCS9 0x00200000
+#define RATR_MCS10 0x00400000
+#define RATR_MCS11 0x00800000
+#define RATR_MCS12 0x01000000
+#define RATR_MCS13 0x02000000
+#define RATR_MCS14 0x04000000
+#define RATR_MCS15 0x08000000
+
+#define RATE_1M BIT(0)
+#define RATE_2M BIT(1)
+#define RATE_5_5M BIT(2)
+#define RATE_11M BIT(3)
+#define RATE_6M BIT(4)
+#define RATE_9M BIT(5)
+#define RATE_12M BIT(6)
+#define RATE_18M BIT(7)
+#define RATE_24M BIT(8)
+#define RATE_36M BIT(9)
+#define RATE_48M BIT(10)
+#define RATE_54M BIT(11)
+#define RATE_MCS0 BIT(12)
+#define RATE_MCS1 BIT(13)
+#define RATE_MCS2 BIT(14)
+#define RATE_MCS3 BIT(15)
+#define RATE_MCS4 BIT(16)
+#define RATE_MCS5 BIT(17)
+#define RATE_MCS6 BIT(18)
+#define RATE_MCS7 BIT(19)
+#define RATE_MCS8 BIT(20)
+#define RATE_MCS9 BIT(21)
+#define RATE_MCS10 BIT(22)
+#define RATE_MCS11 BIT(23)
+#define RATE_MCS12 BIT(24)
+#define RATE_MCS13 BIT(25)
+#define RATE_MCS14 BIT(26)
+#define RATE_MCS15 BIT(27)
+
+/* CAM definition */
+
+#define CAM_NONE 0x0
+#define CAM_WEP40 0x01
+#define CAM_TKIP 0x02
+#define CAM_AES 0x04
+#define CAM_WEP104 0x05
+
+/*#define TOTAL_CAM_ENTRY 64*/
+/*#define HALF_CAM_ENTRY 32*/
+
+#define CAM_WRITE BIT(16)
+#define CAM_READ 0x00000000
+#define CAM_POLLINIG BIT(31)
+
+/*********************************************
+ * 8822BE IMR/ISR bits
+ *********************************************
+ */
+#define IMR_DISABLED 0x0
+/* IMR DW0(0x0060-0063) Bit 0-31 */
+#define IMR_TIMER2 BIT(31)
+#define IMR_TIMER1 BIT(30)
+#define IMR_PSTIMEOUT BIT(29)
+#define IMR_GTINT4 BIT(28)
+#define IMR_GTINT3 BIT(27)
+#define IMR_TBDER BIT(26)
+#define IMR_TBDOK BIT(25)
+#define IMR_TSF_BIT32_TOGGLE BIT(24)
+#define IMR_BCNDMAINT0 BIT(20)
+#define IMR_BCNDOK0 BIT(16)
+#define IMR_HSISR_IND_ON_INT BIT(15)
+#define IMR_BCNDMAINT_E BIT(14)
+#define IMR_ATIMEND BIT(12)
+#define IMR_HISR1_IND_INT BIT(11)
+#define IMR_C2HCMD BIT(10)
+#define IMR_CPWM2 BIT(9)
+#define IMR_CPWM BIT(8)
+#define IMR_HIGHDOK BIT(7)
+#define IMR_MGNTDOK BIT(6)
+#define IMR_BKDOK BIT(5)
+#define IMR_BEDOK BIT(4)
+#define IMR_VIDOK BIT(3)
+#define IMR_VODOK BIT(2)
+#define IMR_RDU BIT(1)
+#define IMR_ROK BIT(0)
+
+/* IMR DW1(0x00B4-00B7) Bit 0-31 */
+#define IMR_TXFIFO_TH_INT_8822B BIT_TXFIFO_TH_INT_8822B
+#define IMR_BTON_STS_UPDATE_MASK_8822B BIT_BTON_STS_UPDATE_MASK_8822B
+#define IMR_MCUERR BIT(28)
+#define IMR_BCNDMAINT7 BIT(27)
+#define IMR_BCNDMAINT6 BIT(26)
+#define IMR_BCNDMAINT5 BIT(25)
+#define IMR_BCNDMAINT4 BIT(24)
+#define IMR_BCNDMAINT3 BIT(23)
+#define IMR_BCNDMAINT2 BIT(22)
+#define IMR_BCNDMAINT1 BIT(21)
+#define IMR_BCNDOK7 BIT(20)
+#define IMR_BCNDOK6 BIT(19)
+#define IMR_BCNDOK5 BIT(18)
+#define IMR_BCNDOK4 BIT(17)
+#define IMR_BCNDOK3 BIT(16)
+#define IMR_BCNDOK2 BIT(15)
+#define IMR_BCNDOK1 BIT(14)
+#define IMR_ATIMEND_E BIT(13)
+#define IMR_ATIMEND BIT(12)
+#define IMR_TXERR BIT(11)
+#define IMR_RXERR BIT(10)
+#define IMR_TXFOVW BIT(9)
+#define IMR_RXFOVW BIT(8)
+#define IMR_CPU_MGQ_TXDONE_MSK_8822B BIT_CPU_MGQ_TXDONE_MSK_8822B
+#define IMR_PS_TIMER_C_MSK_8822B BIT_PS_TIMER_C_MSK_8822B
+#define IMR_PS_TIMER_B_MSK_8822B BIT_PS_TIMER_B_MSK_8822B
+#define IMR_PS_TIMER_A_MSK_8822B BIT_PS_TIMER_A_MSK_8822B
+#define IMR_CPUMGQ_TX_TIMER_MSK_8822B BIT_CPUMGQ_TX_TIMER_MSK_8822B
+
+/*********************************************
+ * 8822BE EFUSE definition
+ *********************************************
+ */
+#define HWSET_MAX_SIZE 1024
+#define EFUSE_MAX_SECTION 64
+#define EFUSE_REAL_CONTENT_LEN 1024
+#define EFUSE_OOB_PROTECT_BYTES 18
+
+#define EEPROM_DEFAULT_THERMALMETER 0x12
+
+#define RTL8822B_EEPROM_ID 0x8129
+
+#define PPG_BB_GAIN_2G_TXA_OFFSET_8822B 0xEE
+#define PPG_THERMAL_OFFSET_8822B 0xEF
+
+#define EEPROM_TX_PWR_INX_8822B 0x10
+
+#define EEPROM_CHANNEL_PLAN_8822B 0xB8
+#define EEPROM_XTAL_8822B 0xB9
+#define EEPROM_THERMAL_METER_8822B 0xBA
+#define EEPROM_IQK_LCK_8822B 0xBB
+#define EEPROM_2G_5G_PA_TYPE_8822B 0xBC
+/* PATH A & PATH B */
+#define EEPROM_2G_LNA_TYPE_GAIN_SEL_AB_8822B 0xBD
+/* PATH C & PATH D */
+#define EEPROM_2G_LNA_TYPE_GAIN_SEL_CD_8822B 0xBE
+/* PATH A & PATH B */
+#define EEPROM_5G_LNA_TYPE_GAIN_SEL_AB_8822B 0xBF
+/* PATH C & PATH D */
+#define EEPROM_5G_LNA_TYPE_GAIN_SEL_CD_8822B 0xC0
+
+#define EEPROM_RF_BOARD_OPTION_8822B 0xC1
+#define EEPROM_FEATURE_OPTION_8822B 0xC2
+#define EEPROM_RF_BT_SETTING_8822B 0xC3
+#define EEPROM_VERSION_8822B 0xC4
+#define EEPROM_CUSTOM_ID_8822B 0xC5
+#define EEPROM_TX_BBSWING_2G_8822B 0xC6
+#define EEPROM_TX_PWR_CALIBRATE_RATE_8822B 0xC8
+#define EEPROM_RF_ANTENNA_OPT_8822B 0xC9
+#define EEPROM_RFE_OPTION_8822B 0xCA
+#define EEPROM_COUNTRY_CODE_8822B 0xCB
+
+#define EEPROM_VID 0xD6
+#define EEPROM_DID 0xD8
+#define EEPROM_SVID 0xDA
+#define EEPROM_SMID 0xDC
+
+/* RTL8822BU */
+#define EEPROM_MAC_ADDR_8822BU 0x107
+#define EEPROM_VID_8822BU 0x100
+#define EEPROM_PID_8822BU 0x102
+#define EEPROM_USB_OPTIONAL_FUNCTION0_8822BU 0x104
+#define EEPROM_USB_MODE_8822BU 0x06
+
+/* RTL8822BS */
+#define EEPROM_MAC_ADDR_8822BS 0x11A
+
+/* RTL8822BE */
+#define EEPROM_MAC_ADDR_8822BE 0xD0
+
+/* ------------------------- */
+
+#define STOPBECON BIT(6)
+#define STOPHIGHT BIT(5)
+#define STOPMGT BIT(4)
+#define STOPVO BIT(3)
+#define STOPVI BIT(2)
+#define STOPBE BIT(1)
+#define STOPBK BIT(0)
+
+#define RCR_APPFCS BIT(31)
+#define RCR_APP_MIC BIT(30)
+#define RCR_APP_ICV BIT(29)
+#define RCR_APP_PHYST_RXFF BIT(28)
+#define RCR_APP_BA_SSN BIT(27)
+#define RCR_VHT_DACK BIT(26)
+#define RCR_ENMBID BIT(24)
+#define RCR_LSIGEN BIT(23)
+#define RCR_MFBEN BIT(22)
+#define RCR_HTC_LOC_CTRL BIT(14)
+#define RCR_AMF BIT(13)
+#define RCR_ACF BIT(12)
+#define RCR_ADF BIT(11)
+#define RCR_AICV BIT(9)
+#define RCR_ACRC32 BIT(8)
+#define RCR_CBSSID_BCN BIT(7)
+#define RCR_CBSSID_DATA BIT(6)
+#define RCR_CBSSID RCR_CBSSID_DATA
+#define RCR_APWRMGT BIT(5)
+#define RCR_ADD3 BIT(4)
+#define RCR_AB BIT(3)
+#define RCR_AM BIT(2)
+#define RCR_APM BIT(1)
+#define RCR_AAP BIT(0)
+#define RCR_MXDMA_OFFSET 8
+#define RCR_FIFO_OFFSET 13
+
+#define RSV_CTRL 0x001C
+#define RD_CTRL 0x0524
+
+#define REG_USB_INFO_8822B 0xFE17
+#define REG_USB_SPECIAL_OPTION_8822B 0xFE55
+#define REG_USB_DMA_AGG_TO_8822B 0xFE5B
+#define REG_USB_AGG_TO_8822B 0xFE5C
+#define REG_USB_AGG_TH_8822B 0xFE5D
+
+#define REG_USB_VID_8822B 0xFE60
+#define REG_USB_PID_8822B 0xFE62
+#define REG_USB_OPTIONAL_8822B 0xFE64
+#define REG_USB_CHIRP_K_8822B 0xFE65
+#define REG_USB_PHY_8822B 0xFE66
+#define REG_USB_MAC_ADDR_8822B 0xFE70
+#define REG_USB_HRPWM_8822B 0xFE58
+#define REG_USB_HCPWM_8822B 0xFE57
+
+#define SW18_FPWM BIT(3)
+
+#define ISO_MD2PP BIT(0)
+#define ISO_UA2USB BIT(1)
+#define ISO_UD2CORE BIT(2)
+#define ISO_PA2PCIE BIT(3)
+#define ISO_PD2CORE BIT(4)
+#define ISO_IP2MAC BIT(5)
+#define ISO_DIOP BIT(6)
+#define ISO_DIOE BIT(7)
+#define ISO_EB2CORE BIT(8)
+#define ISO_DIOR BIT(9)
+
+#define PWC_EV25V BIT(14)
+#define PWC_EV12V BIT(15)
+
+#define FEN_BBRSTB BIT(0)
+#define FEN_BB_GLB_RSTN BIT(1)
+#define FEN_USBA BIT(2)
+#define FEN_UPLL BIT(3)
+#define FEN_USBD BIT(4)
+#define FEN_DIO_PCIE BIT(5)
+#define FEN_PCIEA BIT(6)
+#define FEN_PPLL BIT(7)
+#define FEN_PCIED BIT(8)
+#define FEN_DIOE BIT(9)
+#define FEN_CPUEN BIT(10)
+#define FEN_DCORE BIT(11)
+#define FEN_ELDR BIT(12)
+#define FEN_DIO_RF BIT(13)
+#define FEN_HWPDN BIT(14)
+#define FEN_MREGEN BIT(15)
+
+#define PFM_LDALL BIT(0)
+#define PFM_ALDN BIT(1)
+#define PFM_LDKP BIT(2)
+#define PFM_WOWL BIT(3)
+#define EN_PDN BIT(4)
+#define PDN_PL BIT(5)
+#define APFM_ONMAC BIT(8)
+#define APFM_OFF BIT(9)
+#define APFM_RSM BIT(10)
+#define AFSM_HSUS BIT(11)
+#define AFSM_PCIE BIT(12)
+#define APDM_MAC BIT(13)
+#define APDM_HOST BIT(14)
+#define APDM_HPDN BIT(15)
+#define RDY_MACON BIT(16)
+#define SUS_HOST BIT(17)
+#define ROP_ALD BIT(20)
+#define ROP_PWR BIT(21)
+#define ROP_SPS BIT(22)
+#define SOP_MRST BIT(25)
+#define SOP_FUSE BIT(26)
+#define SOP_ABG BIT(27)
+#define SOP_AMB BIT(28)
+#define SOP_RCK BIT(29)
+#define SOP_A8M BIT(30)
+#define XOP_BTCK BIT(31)
+
+#define ANAD16V_EN BIT(0)
+#define ANA8M BIT(1)
+#define MACSLP BIT(4)
+#define LOADER_CLK_EN BIT(5)
+#define _80M_SSC_DIS BIT(7)
+#define _80M_SSC_EN_HO BIT(8)
+#define PHY_SSC_RSTB BIT(9)
+#define SEC_CLK_EN BIT(10)
+#define MAC_CLK_EN BIT(11)
+#define SYS_CLK_EN BIT(12)
+#define RING_CLK_EN BIT(13)
+
+#define BOOT_FROM_EEPROM BIT(4)
+#define EEPROM_EN BIT(5)
+
+#define AFE_BGEN BIT(0)
+#define AFE_MBEN BIT(1)
+#define MAC_ID_EN BIT(7)
+
+#define WLOCK_ALL BIT(0)
+#define WLOCK_00 BIT(1)
+#define WLOCK_04 BIT(2)
+#define WLOCK_08 BIT(3)
+#define WLOCK_40 BIT(4)
+#define R_DIS_PRST_0 BIT(5)
+#define R_DIS_PRST_1 BIT(6)
+#define LOCK_ALL_EN BIT(7)
+
+#define RF_EN BIT(0)
+#define RF_RSTB BIT(1)
+#define RF_SDMRSTB BIT(2)
+
+#define LDA15_EN BIT(0)
+#define LDA15_STBY BIT(1)
+#define LDA15_OBUF BIT(2)
+#define LDA15_REG_VOS BIT(3)
+#define _LDA15_VOADJ(x) (((x) & 0x7) << 4)
+
+#define LDV12_EN BIT(0)
+#define LDV12_SDBY BIT(1)
+#define LPLDO_HSM BIT(2)
+#define LPLDO_LSM_DIS BIT(3)
+#define _LDV12_VADJ(x) (((x) & 0xF) << 4)
+
+#define XTAL_EN BIT(0)
+#define XTAL_BSEL BIT(1)
+#define _XTAL_BOSC(x) (((x) & 0x3) << 2)
+#define _XTAL_CADJ(x) (((x) & 0xF) << 4)
+#define XTAL_GATE_USB BIT(8)
+#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9)
+#define XTAL_GATE_AFE BIT(11)
+#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12)
+#define XTAL_RF_GATE BIT(14)
+#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15)
+#define XTAL_GATE_DIG BIT(17)
+#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18)
+#define XTAL_BT_GATE BIT(20)
+#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21)
+#define _XTAL_GPIO(x) (((x) & 0x7) << 23)
+
+#define CKDLY_AFE BIT(26)
+#define CKDLY_USB BIT(27)
+#define CKDLY_DIG BIT(28)
+#define CKDLY_BT BIT(29)
+
+#define APLL_EN BIT(0)
+#define APLL_320_EN BIT(1)
+#define APLL_FREF_SEL BIT(2)
+#define APLL_EDGE_SEL BIT(3)
+#define APLL_WDOGB BIT(4)
+#define APLL_LPFEN BIT(5)
+
+#define APLL_REF_CLK_13MHZ 0x1
+#define APLL_REF_CLK_19_2MHZ 0x2
+#define APLL_REF_CLK_20MHZ 0x3
+#define APLL_REF_CLK_25MHZ 0x4
+#define APLL_REF_CLK_26MHZ 0x5
+#define APLL_REF_CLK_38_4MHZ 0x6
+#define APLL_REF_CLK_40MHZ 0x7
+
+#define APLL_320EN BIT(14)
+#define APLL_80EN BIT(15)
+#define APLL_1MEN BIT(24)
+
+#define ALD_EN BIT(18)
+#define EF_PD BIT(19)
+#define EF_FLAG BIT(31)
+
+#define EF_TRPT BIT(7)
+#define LDOE25_EN BIT(31)
+
+#define RSM_EN BIT(0)
+#define TIMER_EN BIT(4)
+
+#define TRSW0EN BIT(2)
+#define TRSW1EN BIT(3)
+#define EROM_EN BIT(4)
+#define EN_BT BIT(5)
+#define EN_UART BIT(8)
+#define UART_910 BIT(9)
+#define EN_PMAC BIT(10)
+#define SIC_SWRST BIT(11)
+#define EN_SIC BIT(12)
+#define SIC_23 BIT(13)
+#define EN_HDP BIT(14)
+#define SIC_LBK BIT(15)
+
+#define LED0PL BIT(4)
+#define LED1PL BIT(12)
+#define LED0DIS BIT(7)
+
+#define MCUFWDL_EN BIT(0)
+#define MCUFWDL_RDY BIT(1)
+#define FWDL_CHKSUM_RPT BIT(2)
+#define MACINI_RDY BIT(3)
+#define BBINI_RDY BIT(4)
+#define RFINI_RDY BIT(5)
+#define WINTINI_RDY BIT(6)
+#define CPRST BIT(23)
+
+#define XCLK_VLD BIT(0)
+#define ACLK_VLD BIT(1)
+#define UCLK_VLD BIT(2)
+#define PCLK_VLD BIT(3)
+#define PCIRSTB BIT(4)
+#define V15_VLD BIT(5)
+#define TRP_B15V_EN BIT(7)
+#define SIC_IDLE BIT(8)
+#define BD_MAC2 BIT(9)
+#define BD_MAC1 BIT(10)
+#define IC_MACPHY_MODE BIT(11)
+#define VENDOR_ID BIT(19)
+#define PAD_HWPD_IDN BIT(22)
+#define TRP_VAUX_EN BIT(23)
+#define TRP_BT_EN BIT(24)
+#define BD_PKG_SEL BIT(25)
+#define BD_HCI_SEL BIT(26)
+#define TYPE_ID BIT(27)
+
+#define CHIP_VER_RTL_MASK 0xF000
+#define CHIP_VER_RTL_SHIFT 12
+
+#define REG_LBMODE_8822B (REG_CR_8822B + 3)
+
+#define HCI_TXDMA_EN BIT(0)
+#define HCI_RXDMA_EN BIT(1)
+#define TXDMA_EN BIT(2)
+#define RXDMA_EN BIT(3)
+#define PROTOCOL_EN BIT(4)
+#define SCHEDULE_EN BIT(5)
+#define MACTXEN BIT(6)
+#define MACRXEN BIT(7)
+#define ENSWBCN BIT(8)
+#define ENSEC BIT(9)
+
+#define _NETTYPE(x) (((x) & 0x3) << 16)
+#define MASK_NETTYPE 0x30000
+#define NT_NO_LINK 0x0
+#define NT_LINK_AD_HOC 0x1
+#define NT_LINK_AP 0x2
+#define NT_AS_AP 0x3
+
+#define _LBMODE(x) (((x) & 0xF) << 24)
+#define MASK_LBMODE 0xF000000
+#define LOOPBACK_NORMAL 0x0
+#define LOOPBACK_IMMEDIATELY 0xB
+#define LOOPBACK_MAC_DELAY 0x3
+#define LOOPBACK_PHY 0x1
+#define LOOPBACK_DMA 0x7
+
+#define GET_RX_PAGE_SIZE(value) ((value) & 0xF)
+#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4)
+#define _PSRX_MASK 0xF
+#define _PSTX_MASK 0xF0
+#define _PSRX(x) (x)
+#define _PSTX(x) ((x) << 4)
+
+#define PBP_64 0x0
+#define PBP_128 0x1
+#define PBP_256 0x2
+#define PBP_512 0x3
+#define PBP_1024 0x4
+
+#define RXDMA_ARBBW_EN BIT(0)
+#define RXSHFT_EN BIT(1)
+#define RXDMA_AGG_EN BIT(2)
+#define QS_VO_QUEUE BIT(8)
+#define QS_VI_QUEUE BIT(9)
+#define QS_BE_QUEUE BIT(10)
+#define QS_BK_QUEUE BIT(11)
+#define QS_MANAGER_QUEUE BIT(12)
+#define QS_HIGH_QUEUE BIT(13)
+
+#define HQSEL_VOQ BIT(0)
+#define HQSEL_VIQ BIT(1)
+#define HQSEL_BEQ BIT(2)
+#define HQSEL_BKQ BIT(3)
+#define HQSEL_MGTQ BIT(4)
+#define HQSEL_HIQ BIT(5)
+
+#define _TXDMA_HIQ_MAP(x) (((x) & 0x3) << 14)
+#define _TXDMA_MGQ_MAP(x) (((x) & 0x3) << 12)
+#define _TXDMA_BKQ_MAP(x) (((x) & 0x3) << 10)
+#define _TXDMA_BEQ_MAP(x) (((x) & 0x3) << 8)
+#define _TXDMA_VIQ_MAP(x) (((x) & 0x3) << 6)
+#define _TXDMA_VOQ_MAP(x) (((x) & 0x3) << 4)
+
+#define QUEUE_LOW 1
+#define QUEUE_NORMAL 2
+#define QUEUE_HIGH 3
+
+#define _LLT_NO_ACTIVE 0x0
+#define _LLT_WRITE_ACCESS 0x1
+#define _LLT_READ_ACCESS 0x2
+
+#define _LLT_INIT_DATA(x) ((x) & 0xFF)
+#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8)
+#define _LLT_OP(x) (((x) & 0x3) << 30)
+#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3)
+
+#define BB_WRITE_READ_MASK (BIT(31) | BIT(30))
+#define BB_WRITE_EN BIT(30)
+#define BB_READ_EN BIT(31)
+
+#define _HPQ(x) ((x) & 0xFF)
+#define _LPQ(x) (((x) & 0xFF) << 8)
+#define _PUBQ(x) (((x) & 0xFF) << 16)
+#define _NPQ(x) ((x) & 0xFF)
+
+#define HPQ_PUBLIC_DIS BIT(24)
+#define LPQ_PUBLIC_DIS BIT(25)
+#define LD_RQPN BIT(31)
+
+#define BCN_VALID BIT(16)
+#define BCN_HEAD(x) (((x) & 0xFF) << 8)
+#define BCN_HEAD_MASK 0xFF00
+
+#define BLK_DESC_NUM_SHIFT 4
+#define BLK_DESC_NUM_MASK 0xF
+
+#define DROP_DATA_EN BIT(9)
+
+#define EN_AMPDU_RTY_NEW BIT(7)
+
+#define _INIRTSMCS_SEL(x) ((x) & 0x3F)
+
+#define _SPEC_SIFS_CCK(x) ((x) & 0xFF)
+#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8)
+
+#define RATE_REG_BITMAP_ALL 0xFFFFF
+
+#define _RRSC_BITMAP(x) ((x) & 0xFFFFF)
+
+#define _RRSR_RSC(x) (((x) & 0x3) << 21)
+#define RRSR_RSC_RESERVED 0x0
+#define RRSR_RSC_UPPER_SUBCHANNEL 0x1
+#define RRSR_RSC_LOWER_SUBCHANNEL 0x2
+#define RRSR_RSC_DUPLICATE_MODE 0x3
+
+#define USE_SHORT_G1 BIT(20)
+
+#define _AGGLMT_MCS0(x) ((x) & 0xF)
+#define _AGGLMT_MCS1(x) (((x) & 0xF) << 4)
+#define _AGGLMT_MCS2(x) (((x) & 0xF) << 8)
+#define _AGGLMT_MCS3(x) (((x) & 0xF) << 12)
+#define _AGGLMT_MCS4(x) (((x) & 0xF) << 16)
+#define _AGGLMT_MCS5(x) (((x) & 0xF) << 20)
+#define _AGGLMT_MCS6(x) (((x) & 0xF) << 24)
+#define _AGGLMT_MCS7(x) (((x) & 0xF) << 28)
+
+#define RETRY_LIMIT_SHORT_SHIFT 8
+#define RETRY_LIMIT_LONG_SHIFT 0
+
+#define _DARF_RC1(x) ((x) & 0x1F)
+#define _DARF_RC2(x) (((x) & 0x1F) << 8)
+#define _DARF_RC3(x) (((x) & 0x1F) << 16)
+#define _DARF_RC4(x) (((x) & 0x1F) << 24)
+#define _DARF_RC5(x) ((x) & 0x1F)
+#define _DARF_RC6(x) (((x) & 0x1F) << 8)
+#define _DARF_RC7(x) (((x) & 0x1F) << 16)
+#define _DARF_RC8(x) (((x) & 0x1F) << 24)
+
+#define _RARF_RC1(x) ((x) & 0x1F)
+#define _RARF_RC2(x) (((x) & 0x1F) << 8)
+#define _RARF_RC3(x) (((x) & 0x1F) << 16)
+#define _RARF_RC4(x) (((x) & 0x1F) << 24)
+#define _RARF_RC5(x) ((x) & 0x1F)
+#define _RARF_RC6(x) (((x) & 0x1F) << 8)
+#define _RARF_RC7(x) (((x) & 0x1F) << 16)
+#define _RARF_RC8(x) (((x) & 0x1F) << 24)
+
+#define AC_PARAM_TXOP_LIMIT_OFFSET 16
+#define AC_PARAM_ECW_MAX_OFFSET 12
+#define AC_PARAM_ECW_MIN_OFFSET 8
+#define AC_PARAM_AIFS_OFFSET 0
+
+#define _AIFS(x) (x)
+#define _ECW_MAX_MIN(x) ((x) << 8)
+#define _TXOP_LIMIT(x) ((x) << 16)
+
+#define _BCNIFS(x) ((x) & 0xFF)
+#define _BCNECW(x) ((((x) & 0xF)) << 8)
+
+#define _LRL(x) ((x) & 0x3F)
+#define _SRL(x) (((x) & 0x3F) << 8)
+
+#define _SIFS_CCK_CTX(x) ((x) & 0xFF)
+#define _SIFS_CCK_TRX(x) (((x) & 0xFF) << 8)
+
+#define _SIFS_OFDM_CTX(x) ((x) & 0xFF)
+#define _SIFS_OFDM_TRX(x) (((x) & 0xFF) << 8)
+
+#define _TBTT_PROHIBIT_HOLD(x) (((x) & 0xFF) << 8)
+
+#define DIS_EDCA_CNT_DWN BIT(11)
+
+#define EN_MBSSID BIT(1)
+#define EN_TXBCN_RPT BIT(2)
+#define EN_BCN_FUNCTION BIT(3)
+
+#define TSFTR_RST BIT(0)
+#define TSFTR1_RST BIT(1)
+
+#define STOP_BCNQ BIT(6)
+
+#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4)
+#define DIS_TSF_UDT0_TEST_CHIP BIT(5)
+
+#define ACMHW_HW_EN BIT(0)
+#define ACMHW_BEQ_EN BIT(1)
+#define ACMHW_VIQ_EN BIT(2)
+#define ACMHW_VOQ_EN BIT(3)
+#define ACMHW_BEQ_STATUS BIT(4)
+#define ACMHW_VIQ_STATUS BIT(5)
+#define ACMHW_VOQ_STATUS BIT(6)
+
+#define APSDOFF BIT(6)
+#define APSDOFF_STATUS BIT(7)
+
+#define BW_20MHZ BIT(2)
+
+#define RATE_BITMAP_ALL 0xFFFFF
+
+#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1
+
+#define TSFRST BIT(0)
+#define DIS_GCLK BIT(1)
+#define PAD_SEL BIT(2)
+#define PWR_ST BIT(6)
+#define PWRBIT_OW_EN BIT(7)
+#define ACRC BIT(8)
+#define CFENDFORM BIT(9)
+#define ICV BIT(10)
+
+#define AAP BIT(0)
+#define APM BIT(1)
+#define AM BIT(2)
+#define AB BIT(3)
+#define ADD3 BIT(4)
+#define APWRMGT BIT(5)
+#define CBSSID BIT(6)
+#define CBSSID_DATA BIT(6)
+#define CBSSID_BCN BIT(7)
+#define ACRC32 BIT(8)
+#define AICV BIT(9)
+#define ADF BIT(11)
+#define ACF BIT(12)
+#define AMF BIT(13)
+#define HTC_LOC_CTRL BIT(14)
+#define UC_DATA_EN BIT(16)
+#define BM_DATA_EN BIT(17)
+#define MFBEN BIT(22)
+#define LSIGEN BIT(23)
+#define EN_MBID BIT(24)
+#define APP_BASSN BIT(27)
+#define APP_PHYSTS BIT(28)
+#define APP_ICV BIT(29)
+#define APP_MIC BIT(30)
+#define APP_FCS BIT(31)
+
+#define _MIN_SPACE(x) ((x) & 0x7)
+#define _SHORT_GI_PADDING(x) (((x) & 0x1F) << 3)
+
+#define RXERR_TYPE_OFDM_PPDU 0
+#define RXERR_TYPE_OFDM_FALSE_ALARM 1
+#define RXERR_TYPE_OFDM_MPDU_OK 2
+#define RXERR_TYPE_OFDM_MPDU_FAIL 3
+#define RXERR_TYPE_CCK_PPDU 4
+#define RXERR_TYPE_CCK_FALSE_ALARM 5
+#define RXERR_TYPE_CCK_MPDU_OK 6
+#define RXERR_TYPE_CCK_MPDU_FAIL 7
+#define RXERR_TYPE_HT_PPDU 8
+#define RXERR_TYPE_HT_FALSE_ALARM 9
+#define RXERR_TYPE_HT_MPDU_TOTAL 10
+#define RXERR_TYPE_HT_MPDU_OK 11
+#define RXERR_TYPE_HT_MPDU_FAIL 12
+#define RXERR_TYPE_RX_FULL_DROP 15
+
+#define RXERR_COUNTER_MASK 0xFFFFF
+#define RXERR_RPT_RST BIT(27)
+#define _RXERR_RPT_SEL(type) ((type) << 28)
+
+#define SCR_TX_USE_DK BIT(0)
+#define SCR_RX_USE_DK BIT(1)
+#define SCR_TX_ENC_ENABLE BIT(2)
+#define SRC_RX_DEC_ENABLE BIT(3)
+#define SCR_SK_BY_A2 BIT(4)
+#define SCR_NO_SKMC BIT(5)
+#define SCR_TXBCUSEDK BIT(6)
+#define SCR_RXBCUSEDK BIT(7)
+
+#define USB_IS_HIGH_SPEED 0
+#define USB_IS_FULL_SPEED 1
+#define USB_SPEED_MASK BIT(5)
+
+#define USB_NORMAL_SIE_EP_MASK 0xF
+#define USB_NORMAL_SIE_EP_SHIFT 4
+
+#define USB_TEST_EP_MASK 0x30
+#define USB_TEST_EP_SHIFT 4
+
+#define USB_AGG_EN BIT(3)
+
+#define MAC_ADDR_LEN 6
+#define LAST_ENTRY_OF_TX_PKT_BUFFER 175
+
+#define POLLING_LLT_THRESHOLD 20
+#define POLLING_READY_TIMEOUT_COUNT 3000
+
+#define MAX_MSS_DENSITY_2T 0x13
+#define MAX_MSS_DENSITY_1T 0x0A
+
+#define EPROM_CMD_OPERATING_MODE_MASK ((1 << 7) | (1 << 6))
+#define EPROM_CMD_CONFIG 0x3
+#define EPROM_CMD_LOAD 1
+
+#define HAL_8822B_HW_GPIO_WPS_BIT BIT(2)
+
+/*-----------------------------------------------------
+ * BB / RF register
+ *-----------------------------------------------------
+ */
+
+#define RFPGA0_XA_HSSIPARAMETER1 0x820
+#define RFPGA0_XA_HSSIPARAMETER2 0x824
+#define RFPGA0_XB_HSSIPARAMETER1 0x828
+#define RFPGA0_XB_HSSIPARAMETER2 0x82c
+#define RCCAONSEC 0x838
+
+#define RFPGA0_XA_LSSIPARAMETER 0x840
+#define RFPGA0_XB_LSSIPARAMETER 0x844
+#define RL1PEAKTH 0x848
+
+#define RFPGA0_RFWAKEUPPARAMETER 0x850
+#define RFPGA0_RFSLEEPUPPARAMETER 0x854
+
+#define RFPGA0_XAB_SWITCHCONTROL 0x858
+#define RFPGA0_XCD_SWITCHCONTROL 0x85c
+
+#define RFPGA0_XA_RFINTERFACEOE 0x860
+#define RFC_AREA 0x860
+#define RFPGA0_XB_RFINTERFACEOE 0x864
+
+#define RFPGA0_XAB_RFINTERFACESW 0x870
+#define RFPGA0_XCD_RFINTERFACESW 0x874
+
+#define RFPGA0_XAB_RF_PARA_METER 0x878
+#define RFPGA0_XCD_RF_PARA_METER 0x87c
+
+#define RFPGA0_ANALOGPARAMETER1 0x880
+#define RFPGA0_ANALOGPARAMETER2 0x884
+#define RFPGA0_ANALOGPARAMETER3 0x888
+#define RFPGA0_ANALOGPARAMETER4 0x88c
+
+#define RFPGA0_XA_LSSIREADBACK 0x8a0
+#define RFPGA0_XB_LSSIREADBACK 0x8a4
+#define RFPGA0_XC_LSSIREADBACK 0x8a8
+/*#define RFPGA0_XD_LSSIREADBACK 0x8ac*/
+#define RRFMOD 0x8ac
+#define RHSSIREAD_8822BE 0x8b0
+
+#define RFPGA0_PSDREPORT 0x8b4
+#define TRANSCEIVEA_HSPI_READBACK 0x8b8
+#define TRANSCEIVEB_HSPI_READBACK 0x8bc
+/*#define REG_SC_CNT_8822B 0x8c4*/
+#define RADC_BUF_CLK 0x8c4
+#define RFPGA0_XAB_RFINTERFACERB 0x8e0
+#define RFPGA0_XCD_RFINTERFACERB 0x8e4
+
+/* PageB(0xB00) */
+
+/*Page C*/
+
+#define RA_TXPWRTRAING 0xc54
+#define RB_TXPWRTRAING 0xe54
+
+#define RA_LSSIWRITE_8822B 0xc90
+#define RB_LSSIWRITE_8822B 0xe90
+
+#define RA_PIREAD_8822B 0xd04
+#define RB_PIREAD_8822B 0xd44
+#define RA_SIREAD_8822B 0xd08
+#define RB_SIREAD_8822B 0xd48
+
+#define RZEBRA1_HSSIENABLE 0x0
+#define RZEBRA1_TRXENABLE1 0x1
+#define RZEBRA1_TRXENABLE2 0x2
+#define RZEBRA1_AGC 0x4
+#define RZEBRA1_CHARGEPUMP 0x5
+#define RZEBRA1_CHANNEL 0x7
+
+#define RZEBRA1_TXGAIN 0x8
+#define RZEBRA1_TXLPF 0x9
+#define RZEBRA1_RXLPF 0xb
+#define RZEBRA1_RXHPFCORNER 0xc
+
+#define RGLOBALCTRL 0
+#define RRTL8256_TXLPF 19
+#define RRTL8256_RXLPF 11
+#define RRTL8258_TXLPF 0x11
+#define RRTL8258_RXLPF 0x13
+#define RRTL8258_RSSILPF 0xa
+
+#define RF_AC 0x00
+
+#define RF_IQADJ_G1 0x01
+#define RF_IQADJ_G2 0x02
+#define RF_POW_TRSW 0x05
+
+#define RF_GAIN_RX 0x06
+#define RF_GAIN_TX 0x07
+
+#define RF_TXM_IDAC 0x08
+#define RF_BS_IQGEN 0x0F
+
+#define RF_MODE1 0x10
+#define RF_MODE2 0x11
+
+#define RF_RX_AGC_HP 0x12
+#define RF_TX_AGC 0x13
+#define RF_BIAS 0x14
+#define RF_IPA 0x15
+#define RF_POW_ABILITY 0x17
+#define RF_MODE_AG 0x18
+#define RRFCHANNEL 0x18
+#define RF_CHNLBW 0x18
+#define RF_TOP 0x19
+
+#define RF_RX_G1 0x1A
+#define RF_RX_G2 0x1B
+
+#define RF_RX_BB2 0x1C
+#define RF_RX_BB1 0x1D
+
+#define RF_RCK1 0x1E
+#define RF_RCK2 0x1F
+
+#define RF_TX_G1 0x20
+#define RF_TX_G2 0x21
+#define RF_TX_G3 0x22
+
+#define RF_TX_BB1 0x23
+#define RF_T_METER 0x42
+
+#define RF_SYN_G1 0x25
+#define RF_SYN_G2 0x26
+#define RF_SYN_G3 0x27
+#define RF_SYN_G4 0x28
+#define RF_SYN_G5 0x29
+#define RF_SYN_G6 0x2A
+#define RF_SYN_G7 0x2B
+#define RF_SYN_G8 0x2C
+
+#define RF_RCK_OS 0x30
+#define RF_TXPA_G1 0x31
+#define RF_TXPA_G2 0x32
+#define RF_TXPA_G3 0x33
+
+#define RF_TX_BIAS_A 0x35
+#define RF_TX_BIAS_D 0x36
+#define RF_LOBF_9 0x38
+#define RF_RXRF_A3 0x3C
+#define RF_TRSW 0x3F
+
+#define RF_TXRF_A2 0x41
+#define RF_TXPA_G4 0x46
+#define RF_TXPA_A4 0x4B
+
+#define RF_APK 0x63
+
+#define RF_WE_LUT 0xEF
+
+#define BBBRESETB 0x100
+#define BGLOBALRESETB 0x200
+#define BOFDMTXSTART 0x4
+#define BCCKTXSTART 0x8
+#define BCRC32DEBUG 0x100
+#define BPMACLOOPBACK 0x10
+#define BTXLSIG 0xffffff
+#define BOFDMTXRATE 0xf
+#define BOFDMTXRESERVED 0x10
+#define BOFDMTXLENGTH 0x1ffe0
+#define BOFDMTXPARITY 0x20000
+#define BTXHTSIG1 0xffffff
+#define BTXHTMCSRATE 0x7f
+#define BTXHTBW 0x80
+#define BTXHTLENGTH 0xffff00
+#define BTXHTSIG2 0xffffff
+#define BTXHTSMOOTHING 0x1
+#define BTXHTSOUNDING 0x2
+#define BTXHTRESERVED 0x4
+#define BTXHTAGGREATION 0x8
+#define BTXHTSTBC 0x30
+#define BTXHTADVANCECODING 0x40
+#define BTXHTSHORTGI 0x80
+#define BTXHTNUMBERHT_LTF 0x300
+#define BTXHTCRC8 0x3fc00
+#define BCOUNTERRESET 0x10000
+#define BNUMOFOFDMTX 0xffff
+#define BNUMOFCCKTX 0xffff0000
+#define BTXIDLEINTERVAL 0xffff
+#define BOFDMSERVICE 0xffff0000
+#define BTXMACHEADER 0xffffffff
+#define BTXDATAINIT 0xff
+#define BTXHTMODE 0x100
+#define BTXDATATYPE 0x30000
+#define BTXRANDOMSEED 0xffffffff
+#define BCCKTXPREAMBLE 0x1
+#define BCCKTXSFD 0xffff0000
+#define BCCKTXSIG 0xff
+#define BCCKTXSERVICE 0xff00
+#define BCCKLENGTHEXT 0x8000
+#define BCCKTXLENGHT 0xffff0000
+#define BCCKTXCRC16 0xffff
+#define BCCKTXSTATUS 0x1
+#define BOFDMTXSTATUS 0x2
+#define IS_BB_REG_OFFSET_92S(_offset) ((_offset >= 0x800) && (_offset <= 0xfff))
+
+#define BRFMOD 0x1
+#define BJAPANMODE 0x2
+#define BCCKTXSC 0x30
+/* Block & Path enable*/
+#define ROFDMCCKEN 0x808
+#define BCCKEN 0x10000000
+#define BOFDMEN 0x20000000
+/* Rx antenna*/
+#define RRXPATH 0x808
+#define BRXPATH 0xff
+/* Tx antenna*/
+#define RTXPATH 0x80c
+#define BTXPATH 0x0fffffff
+/* for cck rx path selection*/
+#define RCCK_RX 0xa04
+#define BCCK_RX 0x0c000000
+/* Use LSIG for VHT length*/
+#define RVHTLEN_USE_LSIG 0x8c3
+
+#define BOFDMRXADCPHASE 0x10000
+#define BOFDMTXDACPHASE 0x40000
+#define BXATXAGC 0x3f
+
+#define BXBTXAGC 0xf00
+#define BXCTXAGC 0xf000
+#define BXDTXAGC 0xf0000
+
+#define BPASTART 0xf0000000
+#define BTRSTART 0x00f00000
+#define BRFSTART 0x0000f000
+#define BBBSTART 0x000000f0
+#define BBBCCKSTART 0x0000000f
+#define BPAEND 0xf
+#define BTREND 0x0f000000
+#define BRFEND 0x000f0000
+#define BCCAMASK 0x000000f0
+#define BR2RCCAMASK 0x00000f00
+#define BHSSI_R2TDELAY 0xf8000000
+#define BHSSI_T2RDELAY 0xf80000
+#define BCONTXHSSI 0x400
+#define BIGFROMCCK 0x200
+#define BAGCADDRESS 0x3f
+#define BRXHPTX 0x7000
+#define BRXHP2RX 0x38000
+#define BRXHPCCKINI 0xc0000
+#define BAGCTXCODE 0xc00000
+#define BAGCRXCODE 0x300000
+
+#define B3WIREDATALENGTH 0x800
+#define B3WIREADDREAALENGTH 0x400
+
+#define B3WIRERFPOWERDOWN 0x1
+#define B5GPAPEPOLARITY 0x40000000
+#define B2GPAPEPOLARITY 0x80000000
+#define BRFSW_TXDEFAULTANT 0x3
+#define BRFSW_TXOPTIONANT 0x30
+#define BRFSW_RXDEFAULTANT 0x300
+#define BRFSW_RXOPTIONANT 0x3000
+#define BRFSI_3WIREDATA 0x1
+#define BRFSI_3WIRECLOCK 0x2
+#define BRFSI_3WIRELOAD 0x4
+#define BRFSI_3WIRERW 0x8
+#define BRFSI_3WIRE 0xf
+
+#define BRFSI_RFENV 0x10
+
+#define BRFSI_TRSW 0x20
+#define BRFSI_TRSWB 0x40
+#define BRFSI_ANTSW 0x100
+#define BRFSI_ANTSWB 0x200
+#define BRFSI_PAPE 0x400
+#define BRFSI_PAPE5G 0x800
+#define BBANDSELECT 0x1
+#define BHTSIG2_GI 0x80
+#define BHTSIG2_SMOOTHING 0x01
+#define BHTSIG2_SOUNDING 0x02
+#define BHTSIG2_AGGREATON 0x08
+#define BHTSIG2_STBC 0x30
+#define BHTSIG2_ADVCODING 0x40
+#define BHTSIG2_NUMOFHTLTF 0x300
+#define BHTSIG2_CRC8 0x3fc
+#define BHTSIG1_MCS 0x7f
+#define BHTSIG1_BANDWIDTH 0x80
+#define BHTSIG1_HTLENGTH 0xffff
+#define BLSIG_RATE 0xf
+#define BLSIG_RESERVED 0x10
+#define BLSIG_LENGTH 0x1fffe
+#define BLSIG_PARITY 0x20
+#define BCCKRXPHASE 0x4
+
+#define BLSSIREADADDRESS 0x7f800000
+#define BLSSIREADEDGE 0x80000000
+
+#define BLSSIREADBACKDATA 0xfffff
+
+#define BLSSIREADOKFLAG 0x1000
+#define BCCKSAMPLERATE 0x8
+#define BREGULATOR0STANDBY 0x1
+#define BREGULATORPLLSTANDBY 0x2
+#define BREGULATOR1STANDBY 0x4
+#define BPLLPOWERUP 0x8
+#define BDPLLPOWERUP 0x10
+#define BDA10POWERUP 0x20
+#define BAD7POWERUP 0x200
+#define BDA6POWERUP 0x2000
+#define BXTALPOWERUP 0x4000
+#define B40MDCLKPOWERUP 0x8000
+#define BDA6DEBUGMODE 0x20000
+#define BDA6SWING 0x380000
+
+#define BADCLKPHASE 0x4000000
+#define B80MCLKDELAY 0x18000000
+#define BAFEWATCHDOGENABLE 0x20000000
+
+#define BXTALCAP01 0xc0000000
+#define BXTALCAP23 0x3
+#define BXTALCAP92X 0x0f000000
+#define BXTALCAP 0x0f000000
+
+#define BINTDIFCLKENABLE 0x400
+#define BEXTSIGCLKENABLE 0x800
+#define BBANDGAP_MBIAS_POWERUP 0x10000
+#define BAD11SH_GAIN 0xc0000
+#define BAD11NPUT_RANGE 0x700000
+#define BAD110P_CURRENT 0x3800000
+#define BLPATH_LOOPBACK 0x4000000
+#define BQPATH_LOOPBACK 0x8000000
+#define BAFE_LOOPBACK 0x10000000
+#define BDA10_SWING 0x7e0
+#define BDA10_REVERSE 0x800
+#define BDA_CLK_SOURCE 0x1000
+#define BDA7INPUT_RANGE 0x6000
+#define BDA7_GAIN 0x38000
+#define BDA7OUTPUT_CM_MODE 0x40000
+#define BDA7INPUT_CM_MODE 0x380000
+#define BDA7CURRENT 0xc00000
+#define BREGULATOR_ADJUST 0x7000000
+#define BAD11POWERUP_ATTX 0x1
+#define BDA10PS_ATTX 0x10
+#define BAD11POWERUP_ATRX 0x100
+#define BDA10PS_ATRX 0x1000
+#define BCCKRX_AGC_FORMAT 0x200
+#define BPSDFFT_SAMPLE_POINT 0xc000
+#define BPSD_AVERAGE_NUM 0x3000
+#define BIQPATH_CONTROL 0xc00
+#define BPSD_FREQ 0x3ff
+#define BPSD_ANTENNA_PATH 0x30
+#define BPSD_IQ_SWITCH 0x40
+#define BPSD_RX_TRIGGER 0x400000
+#define BPSD_TX_TRIGGER 0x80000000
+#define BPSD_SINE_TONE_SCALE 0x7f000000
+#define BPSD_REPORT 0xffff
+
+#define BOFDM_TXSC 0x30000000
+#define BCCK_TXON 0x1
+#define BOFDM_TXON 0x2
+#define BDEBUG_PAGE 0xfff
+#define BDEBUG_ITEM 0xff
+#define BANTL 0x10
+#define BANT_NONHT 0x100
+#define BANT_HT1 0x1000
+#define BANT_HT2 0x10000
+#define BANT_HT1S1 0x100000
+#define BANT_NONHTS1 0x1000000
+
+#define BCCK_BBMODE 0x3
+#define BCCK_TXPOWERSAVING 0x80
+#define BCCK_RXPOWERSAVING 0x40
+
+#define BCCK_SIDEBAND 0x10
+
+#define BCCK_SCRAMBLE 0x8
+#define BCCK_ANTDIVERSITY 0x8000
+#define BCCK_CARRIER_RECOVERY 0x4000
+#define BCCK_TXRATE 0x3000
+#define BCCK_DCCANCEL 0x0800
+#define BCCK_ISICANCEL 0x0400
+#define BCCK_MATCH_FILTER 0x0200
+#define BCCK_EQUALIZER 0x0100
+#define BCCK_PREAMBLE_DETECT 0x800000
+#define BCCK_FAST_FALSECCA 0x400000
+#define BCCK_CH_ESTSTART 0x300000
+#define BCCK_CCA_COUNT 0x080000
+#define BCCK_CS_LIM 0x070000
+#define BCCK_BIST_MODE 0x80000000
+#define BCCK_CCAMASK 0x40000000
+#define BCCK_TX_DAC_PHASE 0x4
+#define BCCK_RX_ADC_PHASE 0x20000000
+#define BCCKR_CP_MODE 0x0100
+#define BCCK_TXDC_OFFSET 0xf0
+#define BCCK_RXDC_OFFSET 0xf
+#define BCCK_CCA_MODE 0xc000
+#define BCCK_FALSECS_LIM 0x3f00
+#define BCCK_CS_RATIO 0xc00000
+#define BCCK_CORGBIT_SEL 0x300000
+#define BCCK_PD_LIM 0x0f0000
+#define BCCK_NEWCCA 0x80000000
+#define BCCK_RXHP_OF_IG 0x8000
+#define BCCK_RXIG 0x7f00
+#define BCCK_LNA_POLARITY 0x800000
+#define BCCK_RX1ST_BAIN 0x7f0000
+#define BCCK_RF_EXTEND 0x20000000
+#define BCCK_RXAGC_SATLEVEL 0x1f000000
+#define BCCK_RXAGC_SATCOUNT 0xe0
+#define BCCK_RX_RF_SETTLE 0x1f
+#define BCCK_FIXED_RXAGC 0x8000
+#define BCCK_ANTENNA_POLARITY 0x2000
+#define BCCK_TXFILTER_TYPE 0x0c00
+#define BCCK_RXAGC_REPORTTYPE 0x0300
+#define BCCK_RXDAGC_EN 0x80000000
+#define BCCK_RXDAGC_PERIOD 0x20000000
+#define BCCK_RXDAGC_SATLEVEL 0x1f000000
+#define BCCK_TIMING_RECOVERY 0x800000
+#define BCCK_TXC0 0x3f0000
+#define BCCK_TXC1 0x3f000000
+#define BCCK_TXC2 0x3f
+#define BCCK_TXC3 0x3f00
+#define BCCK_TXC4 0x3f0000
+#define BCCK_TXC5 0x3f000000
+#define BCCK_TXC6 0x3f
+#define BCCK_TXC7 0x3f00
+#define BCCK_DEBUGPORT 0xff0000
+#define BCCK_DAC_DEBUG 0x0f000000
+#define BCCK_FALSEALARM_ENABLE 0x8000
+#define BCCK_FALSEALARM_READ 0x4000
+#define BCCK_TRSSI 0x7f
+#define BCCK_RXAGC_REPORT 0xfe
+#define BCCK_RXREPORT_ANTSEL 0x80000000
+#define BCCK_RXREPORT_MFOFF 0x40000000
+#define BCCK_RXREPORT_SQLOSS 0x20000000
+#define BCCK_RXREPORT_PKTLOSS 0x10000000
+#define BCCK_RXREPORT_LOCKEDBIT 0x08000000
+#define BCCK_RXREPORT_RATEERROR 0x04000000
+#define BCCK_RXREPORT_RXRATE 0x03000000
+#define BCCK_RXFA_COUNTER_LOWER 0xff
+#define BCCK_RXFA_COUNTER_UPPER 0xff000000
+#define BCCK_RXHPAGC_START 0xe000
+#define BCCK_RXHPAGC_FINAL 0x1c00
+#define BCCK_RXFALSEALARM_ENABLE 0x8000
+#define BCCK_FACOUNTER_FREEZE 0x4000
+#define BCCK_TXPATH_SEL 0x10000000
+#define BCCK_DEFAULT_RXPATH 0xc000000
+#define BCCK_OPTION_RXPATH 0x3000000
+
+#define BNUM_OFSTF 0x3
+#define BSHIFT_L 0xc0
+#define BGI_TH 0xc
+#define BRXPATH_A 0x1
+#define BRXPATH_B 0x2
+#define BRXPATH_C 0x4
+#define BRXPATH_D 0x8
+#define BTXPATH_A 0x1
+#define BTXPATH_B 0x2
+#define BTXPATH_C 0x4
+#define BTXPATH_D 0x8
+#define BTRSSI_FREQ 0x200
+#define BADC_BACKOFF 0x3000
+#define BDFIR_BACKOFF 0xc000
+#define BTRSSI_LATCH_PHASE 0x10000
+#define BRX_LDC_OFFSET 0xff
+#define BRX_QDC_OFFSET 0xff00
+#define BRX_DFIR_MODE 0x1800000
+#define BRX_DCNF_TYPE 0xe000000
+#define BRXIQIMB_A 0x3ff
+#define BRXIQIMB_B 0xfc00
+#define BRXIQIMB_C 0x3f0000
+#define BRXIQIMB_D 0xffc00000
+#define BDC_DC_NOTCH 0x60000
+#define BRXNB_NOTCH 0x1f000000
+#define BPD_TH 0xf
+#define BPD_TH_OPT2 0xc000
+#define BPWED_TH 0x700
+#define BIFMF_WIN_L 0x800
+#define BPD_OPTION 0x1000
+#define BMF_WIN_L 0xe000
+#define BBW_SEARCH_L 0x30000
+#define BWIN_ENH_L 0xc0000
+#define BBW_TH 0x700000
+#define BED_TH2 0x3800000
+#define BBW_OPTION 0x4000000
+#define BRADIO_TH 0x18000000
+#define BWINDOW_L 0xe0000000
+#define BSBD_OPTION 0x1
+#define BFRAME_TH 0x1c
+#define BFS_OPTION 0x60
+#define BDC_SLOPE_CHECK 0x80
+#define BFGUARD_COUNTER_DC_L 0xe00
+#define BFRAME_WEIGHT_SHORT 0x7000
+#define BSUB_TUNE 0xe00000
+#define BFRAME_DC_LENGTH 0xe000000
+#define BSBD_START_OFFSET 0x30000000
+#define BFRAME_TH_2 0x7
+#define BFRAME_GI2_TH 0x38
+#define BGI2_SYNC_EN 0x40
+#define BSARCH_SHORT_EARLY 0x300
+#define BSARCH_SHORT_LATE 0xc00
+#define BSARCH_GI2_LATE 0x70000
+#define BCFOANTSUM 0x1
+#define BCFOACC 0x2
+#define BCFOSTARTOFFSET 0xc
+#define BCFOLOOPBACK 0x70
+#define BCFOSUMWEIGHT 0x80
+#define BDAGCENABLE 0x10000
+#define BTXIQIMB_A 0x3ff
+#define BTXIQIMB_b 0xfc00
+#define BTXIQIMB_C 0x3f0000
+#define BTXIQIMB_D 0xffc00000
+#define BTXIDCOFFSET 0xff
+#define BTXIQDCOFFSET 0xff00
+#define BTXDFIRMODE 0x10000
+#define BTXPESUDO_NOISEON 0x4000000
+#define BTXPESUDO_NOISE_A 0xff
+#define BTXPESUDO_NOISE_B 0xff00
+#define BTXPESUDO_NOISE_C 0xff0000
+#define BTXPESUDO_NOISE_D 0xff000000
+#define BCCA_DROPOPTION 0x20000
+#define BCCA_DROPTHRES 0xfff00000
+#define BEDCCA_H 0xf
+#define BEDCCA_L 0xf0
+#define BLAMBDA_ED 0x300
+#define BRX_INITIALGAIN 0x7f
+#define BRX_ANTDIV_EN 0x80
+#define BRX_AGC_ADDRESS_FOR_LNA 0x7f00
+#define BRX_HIGHPOWER_FLOW 0x8000
+#define BRX_AGC_FREEZE_THRES 0xc0000
+#define BRX_FREEZESTEP_AGC1 0x300000
+#define BRX_FREEZESTEP_AGC2 0xc00000
+#define BRX_FREEZESTEP_AGC3 0x3000000
+#define BRX_FREEZESTEP_AGC0 0xc000000
+#define BRXRSSI_CMP_EN 0x10000000
+#define BRXQUICK_AGCEN 0x20000000
+#define BRXAGC_FREEZE_THRES_MODE 0x40000000
+#define BRX_OVERFLOW_CHECKTYPE 0x80000000
+#define BRX_AGCSHIFT 0x7f
+#define BTRSW_TRI_ONLY 0x80
+#define BPOWER_THRES 0x300
+#define BRXAGC_EN 0x1
+#define BRXAGC_TOGETHER_EN 0x2
+#define BRXAGC_MIN 0x4
+#define BRXHP_INI 0x7
+#define BRXHP_TRLNA 0x70
+#define BRXHP_RSSI 0x700
+#define BRXHP_BBP1 0x7000
+#define BRXHP_BBP2 0x70000
+#define BRXHP_BBP3 0x700000
+#define BRSSI_H 0x7f0000
+#define BRSSI_GEN 0x7f000000
+#define BRXSETTLE_TRSW 0x7
+#define BRXSETTLE_LNA 0x38
+#define BRXSETTLE_RSSI 0x1c0
+#define BRXSETTLE_BBP 0xe00
+#define BRXSETTLE_RXHP 0x7000
+#define BRXSETTLE_ANTSW_RSSI 0x38000
+#define BRXSETTLE_ANTSW 0xc0000
+#define BRXPROCESS_TIME_DAGC 0x300000
+#define BRXSETTLE_HSSI 0x400000
+#define BRXPROCESS_TIME_BBPPW 0x800000
+#define BRXANTENNA_POWER_SHIFT 0x3000000
+#define BRSSI_TABLE_SELECT 0xc000000
+#define BRXHP_FINAL 0x7000000
+#define BRXHPSETTLE_BBP 0x7
+#define BRXHTSETTLE_HSSI 0x8
+#define BRXHTSETTLE_RXHP 0x70
+#define BRXHTSETTLE_BBPPW 0x80
+#define BRXHTSETTLE_IDLE 0x300
+#define BRXHTSETTLE_RESERVED 0x1c00
+#define BRXHT_RXHP_EN 0x8000
+#define BRXAGC_FREEZE_THRES 0x30000
+#define BRXAGC_TOGETHEREN 0x40000
+#define BRXHTAGC_MIN 0x80000
+#define BRXHTAGC_EN 0x100000
+#define BRXHTDAGC_EN 0x200000
+#define BRXHT_RXHP_BBP 0x1c00000
+#define BRXHT_RXHP_FINAL 0xe0000000
+#define BRXPW_RADIO_TH 0x3
+#define BRXPW_RADIO_EN 0x4
+#define BRXMF_HOLD 0x3800
+#define BRXPD_DELAY_TH1 0x38
+#define BRXPD_DELAY_TH2 0x1c0
+#define BRXPD_DC_COUNT_MAX 0x600
+#define BRXPD_DELAY_TH 0x8000
+#define BRXPROCESS_DELAY 0xf0000
+#define BRXSEARCHRANGE_GI2_EARLY 0x700000
+#define BRXFRAME_FUARD_COUNTER_L 0x3800000
+#define BRXSGI_GUARD_L 0xc000000
+#define BRXSGI_SEARCH_L 0x30000000
+#define BRXSGI_TH 0xc0000000
+#define BDFSCNT0 0xff
+#define BDFSCNT1 0xff00
+#define BDFSFLAG 0xf0000
+#define BMF_WEIGHT_SUM 0x300000
+#define BMINIDX_TH 0x7f000000
+#define BDAFORMAT 0x40000
+#define BTXCH_EMU_ENABLE 0x01000000
+#define BTRSW_ISOLATION_A 0x7f
+#define BTRSW_ISOLATION_B 0x7f00
+#define BTRSW_ISOLATION_C 0x7f0000
+#define BTRSW_ISOLATION_D 0x7f000000
+#define BEXT_LNA_GAIN 0x7c00
+
+#define BSTBC_EN 0x4
+#define BANTENNA_MAPPING 0x10
+#define BNSS 0x20
+#define BCFO_ANTSUM_ID 0x200
+#define BPHY_COUNTER_RESET 0x8000000
+#define BCFO_REPORT_GET 0x4000000
+#define BOFDM_CONTINUE_TX 0x10000000
+#define BOFDM_SINGLE_CARRIER 0x20000000
+#define BOFDM_SINGLE_TONE 0x40000000
+#define BHT_DETECT 0x100
+#define BCFOEN 0x10000
+#define BCFOVALUE 0xfff00000
+#define BSIGTONE_RE 0x3f
+#define BSIGTONE_IM 0x7f00
+#define BCOUNTER_CCA 0xffff
+#define BCOUNTER_PARITYFAIL 0xffff0000
+#define BCOUNTER_RATEILLEGAL 0xffff
+#define BCOUNTER_CRC8FAIL 0xffff0000
+#define BCOUNTER_MCSNOSUPPORT 0xffff
+#define BCOUNTER_FASTSYNC 0xffff
+#define BSHORTCFO 0xfff
+#define BSHORTCFOT_LENGTH 12
+#define BSHORTCFOF_LENGTH 11
+#define BLONGCFO 0x7ff
+#define BLONGCFOT_LENGTH 11
+#define BLONGCFOF_LENGTH 11
+#define BTAILCFO 0x1fff
+#define BTAILCFOT_LENGTH 13
+#define BTAILCFOF_LENGTH 12
+#define BNOISE_EN_PWDB 0xffff
+#define BCC_POWER_DB 0xffff0000
+#define BMOISE_PWDB 0xffff
+#define BPOWERMEAST_LENGTH 10
+#define BPOWERMEASF_LENGTH 3
+#define BRX_HT_BW 0x1
+#define BRXSC 0x6
+#define BRX_HT 0x8
+#define BNB_INTF_DET_ON 0x1
+#define BINTF_WIN_LEN_CFG 0x30
+#define BNB_INTF_TH_CFG 0x1c0
+#define BRFGAIN 0x3f
+#define BTABLESEL 0x40
+#define BTRSW 0x80
+#define BRXSNR_A 0xff
+#define BRXSNR_B 0xff00
+#define BRXSNR_C 0xff0000
+#define BRXSNR_D 0xff000000
+#define BSNR_EVMT_LENGTH 8
+#define BSNR_EVMF_LENGTH 1
+#define BCSI1ST 0xff
+#define BCSI2ND 0xff00
+#define BRXEVM1ST 0xff0000
+#define BRXEVM2ND 0xff000000
+#define BSIGEVM 0xff
+#define BPWDB 0xff00
+#define BSGIEN 0x10000
+
+#define BSFACTOR_QMA1 0xf
+#define BSFACTOR_QMA2 0xf0
+#define BSFACTOR_QMA3 0xf00
+#define BSFACTOR_QMA4 0xf000
+#define BSFACTOR_QMA5 0xf0000
+#define BSFACTOR_QMA6 0xf0000
+#define BSFACTOR_QMA7 0xf00000
+#define BSFACTOR_QMA8 0xf000000
+#define BSFACTOR_QMA9 0xf0000000
+#define BCSI_SCHEME 0x100000
+
+#define BNOISE_LVL_TOP_SET 0x3
+#define BCHSMOOTH 0x4
+#define BCHSMOOTH_CFG1 0x38
+#define BCHSMOOTH_CFG2 0x1c0
+#define BCHSMOOTH_CFG3 0xe00
+#define BCHSMOOTH_CFG4 0x7000
+#define BMRCMODE 0x800000
+#define BTHEVMCFG 0x7000000
+
+#define BLOOP_FIT_TYPE 0x1
+#define BUPD_CFO 0x40
+#define BUPD_CFO_OFFDATA 0x80
+#define BADV_UPD_CFO 0x100
+#define BADV_TIME_CTRL 0x800
+#define BUPD_CLKO 0x1000
+#define BFC 0x6000
+#define BTRACKING_MODE 0x8000
+#define BPHCMP_ENABLE 0x10000
+#define BUPD_CLKO_LTF 0x20000
+#define BCOM_CH_CFO 0x40000
+#define BCSI_ESTI_MODE 0x80000
+#define BADV_UPD_EQZ 0x100000
+#define BUCHCFG 0x7000000
+#define BUPDEQZ 0x8000000
+
+#define BRX_PESUDO_NOISE_ON 0x20000000
+#define BRX_PESUDO_NOISE_A 0xff
+#define BRX_PESUDO_NOISE_B 0xff00
+#define BRX_PESUDO_NOISE_C 0xff0000
+#define BRX_PESUDO_NOISE_D 0xff000000
+#define BRX_PESUDO_NOISESTATE_A 0xffff
+#define BRX_PESUDO_NOISESTATE_B 0xffff0000
+#define BRX_PESUDO_NOISESTATE_C 0xffff
+#define BRX_PESUDO_NOISESTATE_D 0xffff0000
+
+#define BZEBRA1_HSSIENABLE 0x8
+#define BZEBRA1_TRXCONTROL 0xc00
+#define BZEBRA1_TRXGAINSETTING 0x07f
+#define BZEBRA1_RXCOUNTER 0xc00
+#define BZEBRA1_TXCHANGEPUMP 0x38
+#define BZEBRA1_RXCHANGEPUMP 0x7
+#define BZEBRA1_CHANNEL_NUM 0xf80
+#define BZEBRA1_TXLPFBW 0x400
+#define BZEBRA1_RXLPFBW 0x600
+
+#define BRTL8256REG_MODE_CTRL1 0x100
+#define BRTL8256REG_MODE_CTRL0 0x40
+#define BRTL8256REG_TXLPFBW 0x18
+#define BRTL8256REG_RXLPFBW 0x600
+
+#define BRTL8258_TXLPFBW 0xc
+#define BRTL8258_RXLPFBW 0xc00
+#define BRTL8258_RSSILPFBW 0xc0
+
+#define BBYTE0 0x1
+#define BBYTE1 0x2
+#define BBYTE2 0x4
+#define BBYTE3 0x8
+#define BWORD0 0x3
+#define BWORD1 0xc
+#define BWORD 0xf
+
+#define MASKBYTE0 0xff
+#define MASKBYTE1 0xff00
+#define MASKBYTE2 0xff0000
+#define MASKBYTE3 0xff000000
+#define MASKHWORD 0xffff0000
+#define MASKLWORD 0x0000ffff
+#define MASKDWORD 0xffffffff
+#define MASK12BITS 0xfff
+#define MASKH4BITS 0xf0000000
+#define MASKOFDM_D 0xffc00000
+#define MASKCCK 0x3f3f3f3f
+
+#define MASK4BITS 0x0f
+#define MASK20BITS 0xfffff
+#define RFREG_OFFSET_MASK 0xfffff
+
+#define BMASKBYTE0 0xff
+#define BMASKBYTE1 0xff00
+#define BMASKBYTE2 0xff0000
+#define BMASKBYTE3 0xff000000
+#define BMASKHWORD 0xffff0000
+#define BMASKLWORD 0x0000ffff
+#define BMASKDWORD 0xffffffff
+#define BMASK12BITS 0xfff
+#define BMASKH4BITS 0xf0000000
+#define BMASKOFDM_D 0xffc00000
+#define BMASKCCK 0x3f3f3f3f
+
+#define BRFREGOFFSETMASK 0xfffff
+
+/* WOL bit information */
+#define WOL_REASON_PTK_UPDATE BIT(0)
+#define WOL_REASON_GTK_UPDATE BIT(1)
+#define WOL_REASON_DISASSOC BIT(2)
+#define WOL_REASON_DEAUTH BIT(3)
+#define WOL_REASON_FW_DISCONNECT BIT(4)
+
+#endif
diff --git a/drivers/staging/rtlwifi/rtl8822be/sw.c b/drivers/staging/rtlwifi/rtl8822be/sw.c
new file mode 100644
index 0000000..91b784b
--- /dev/null
+++ b/drivers/staging/rtlwifi/rtl8822be/sw.c
@@ -0,0 +1,481 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../core.h"
+#include "../pci.h"
+#include "../base.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "hw.h"
+#include "sw.h"
+#include "fw.h"
+#include "trx.h"
+#include "led.h"
+#include "../btcoexist/rtl_btc.h"
+#include "../halmac/rtl_halmac.h"
+#include "../phydm/rtl_phydm.h"
+#include <linux/vmalloc.h>
+#include <linux/module.h>
+
+static void rtl8822be_init_aspm_vars(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ /*close ASPM for AMD defaultly */
+ rtlpci->const_amdpci_aspm = 0;
+
+ /*
+ * ASPM PS mode.
+ * 0 - Disable ASPM,
+ * 1 - Enable ASPM without Clock Req,
+ * 2 - Enable ASPM with Clock Req,
+ * 3 - Alwyas Enable ASPM with Clock Req,
+ * 4 - Always Enable ASPM without Clock Req.
+ * set default to RTL8822BE:3 RTL8822B:2
+ *
+ */
+ rtlpci->const_pci_aspm = 3;
+
+ /*Setting for PCI-E device */
+ rtlpci->const_devicepci_aspm_setting = 0x03;
+
+ /*Setting for PCI-E bridge */
+ rtlpci->const_hostpci_aspm_setting = 0x02;
+
+ /*
+ * In Hw/Sw Radio Off situation.
+ * 0 - Default,
+ * 1 - From ASPM setting without low Mac Pwr,
+ * 2 - From ASPM setting with low Mac Pwr,
+ * 3 - Bus D3
+ * set default to RTL8822BE:0 RTL8192SE:2
+ */
+ rtlpci->const_hwsw_rfoff_d3 = 0;
+
+ /*
+ * This setting works for those device with
+ * backdoor ASPM setting such as EPHY setting.
+ * 0 - Not support ASPM,
+ * 1 - Support ASPM,
+ * 2 - According to chipset.
+ */
+ rtlpci->const_support_pciaspm = rtlpriv->cfg->mod_params->aspm_support;
+}
+
+int rtl8822be_init_sw_vars(struct ieee80211_hw *hw)
+{
+ int err = 0;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ const char *fw_name;
+ struct rtl_phydm_params params;
+
+ rtl8822be_bt_reg_init(hw);
+ rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
+ rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer();
+ rtlpriv->halmac.ops = rtl_halmac_get_ops_pointer();
+ rtlpriv->halmac.ops->halmac_init_adapter(rtlpriv);
+
+ /* should after halmac_init_adapter() */
+ rtl8822be_read_eeprom_info(hw, &params);
+
+ /* need eeprom info */
+ rtlpriv->phydm.ops = rtl_phydm_get_ops_pointer();
+ rtlpriv->phydm.ops->phydm_init_priv(rtlpriv, &params);
+
+ rtlpriv->dm.dm_initialgain_enable = 1;
+ rtlpriv->dm.dm_flag = 0;
+ rtlpriv->dm.disable_framebursting = 0;
+ /*rtlpriv->dm.thermalvalue = 0;*/
+ rtlpriv->dm.useramask = 1; /* turn on RA */
+ rtlpci->transmit_config = CFENDFORM | BIT(15);
+
+ rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G;
+ /*following 2 is for register 5G band, refer to _rtl_init_mac80211()*/
+ rtlpriv->rtlhal.bandset = BAND_ON_BOTH;
+ rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY;
+
+ rtlpci->receive_config = (RCR_APPFCS |
+ RCR_APP_MIC |
+ RCR_APP_ICV |
+ RCR_APP_PHYST_RXFF |
+ RCR_VHT_DACK |
+ RCR_HTC_LOC_CTRL |
+ /*RCR_AMF |*/
+ RCR_CBSSID_BCN |
+ RCR_CBSSID_DATA |
+ /*RCR_ACF |*/
+ /*RCR_ADF |*/
+ /*RCR_AICV |*/
+ /*RCR_ACRC32 |*/
+ RCR_AB |
+ RCR_AM |
+ RCR_APM |
+ 0);
+
+ rtlpci->irq_mask[0] = (u32)(IMR_PSTIMEOUT |
+ /*IMR_TBDER |*/
+ /*IMR_TBDOK |*/
+ /*IMR_BCNDMAINT0 |*/
+ IMR_GTINT3 |
+ IMR_HSISR_IND_ON_INT |
+ IMR_C2HCMD |
+ IMR_HIGHDOK |
+ IMR_MGNTDOK |
+ IMR_BKDOK |
+ IMR_BEDOK |
+ IMR_VIDOK |
+ IMR_VODOK |
+ IMR_RDU |
+ IMR_ROK |
+ 0);
+
+ rtlpci->irq_mask[1] = (u32)(IMR_RXFOVW | IMR_TXFOVW | 0);
+ rtlpci->irq_mask[3] = (u32)(BIT_SETH2CDOK_MASK | 0);
+
+ /* for LPS & IPS */
+ rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
+ rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
+ rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
+ rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
+ if (rtlpriv->cfg->mod_params->disable_watchdog)
+ pr_info("watchdog disabled\n");
+ rtlpriv->psc.reg_fwctrl_lps = 2;
+ rtlpriv->psc.reg_max_lps_awakeintvl = 2;
+ /* for ASPM, you can close aspm through
+ * set const_support_pciaspm = 0
+ */
+ rtl8822be_init_aspm_vars(hw);
+
+ if (rtlpriv->psc.reg_fwctrl_lps == 1)
+ rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE;
+ else if (rtlpriv->psc.reg_fwctrl_lps == 2)
+ rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE;
+ else if (rtlpriv->psc.reg_fwctrl_lps == 3)
+ rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
+
+ /* for early mode */
+ rtlpriv->rtlhal.earlymode_enable = false;
+
+ /*low power */
+ rtlpriv->psc.low_power_enable = false;
+
+ /* for firmware buf */
+ rtlpriv->rtlhal.pfirmware = vzalloc(0x40000);
+ if (!rtlpriv->rtlhal.pfirmware) {
+ /*pr_err("Can't alloc buffer for fw\n");*/
+ return 1;
+ }
+
+ /* request fw */
+ fw_name = "rtlwifi/rtl8822befw.bin";
+
+ rtlpriv->max_fw_size = 0x40000;
+ pr_info("Using firmware %s\n", fw_name);
+ err = request_firmware_nowait(THIS_MODULE, 1, fw_name, rtlpriv->io.dev,
+ GFP_KERNEL, hw, rtl_fw_cb);
+ if (err) {
+ pr_err("Failed to request firmware!\n");
+ return 1;
+ }
+
+ /* init table of tx power by rate & limit */
+ rtl8822be_load_txpower_by_rate(hw);
+ rtl8822be_load_txpower_limit(hw);
+
+ return 0;
+}
+
+void rtl8822be_deinit_sw_vars(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtlpriv->halmac.ops->halmac_deinit_adapter(rtlpriv);
+ rtlpriv->phydm.ops->phydm_deinit_priv(rtlpriv);
+
+ if (rtlpriv->rtlhal.pfirmware) {
+ vfree(rtlpriv->rtlhal.pfirmware);
+ rtlpriv->rtlhal.pfirmware = NULL;
+ }
+}
+
+/* get bt coexist status */
+bool rtl8822be_get_btc_status(void)
+{
+ return true;
+}
+
+static void rtl8822be_phydm_watchdog(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 tmp;
+
+ tmp = rtl_read_dword(rtlpriv, 0xc00);
+ if (tmp & 0xFF000000) { /* Recover 0xC00: 0xF800000C --> 0x0000000C */
+ RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+ "found regaddr_c00=%08X\n", tmp);
+ tmp &= ~0xFF000000;
+ rtl_write_dword(rtlpriv, 0xc00, tmp);
+ RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+ "apply regaddr_c00=%08X\n", tmp);
+ }
+
+ rtlpriv->phydm.ops->phydm_watchdog(rtlpriv);
+}
+
+static struct rtl_hal_ops rtl8822be_hal_ops = {
+ .init_sw_vars = rtl8822be_init_sw_vars,
+ .deinit_sw_vars = rtl8822be_deinit_sw_vars,
+ .read_eeprom_info = rtl8822be_read_eeprom_info_dummy,
+ .interrupt_recognized = rtl8822be_interrupt_recognized,
+ .hw_init = rtl8822be_hw_init,
+ .hw_disable = rtl8822be_card_disable,
+ .hw_suspend = rtl8822be_suspend,
+ .hw_resume = rtl8822be_resume,
+ .enable_interrupt = rtl8822be_enable_interrupt,
+ .disable_interrupt = rtl8822be_disable_interrupt,
+ .set_network_type = rtl8822be_set_network_type,
+ .set_chk_bssid = rtl8822be_set_check_bssid,
+ .set_qos = rtl8822be_set_qos,
+ .set_bcn_reg = rtl8822be_set_beacon_related_registers,
+ .set_bcn_intv = rtl8822be_set_beacon_interval,
+ .update_interrupt_mask = rtl8822be_update_interrupt_mask,
+ .get_hw_reg = rtl8822be_get_hw_reg,
+ .set_hw_reg = rtl8822be_set_hw_reg,
+ .update_rate_tbl = rtl8822be_update_hal_rate_tbl,
+ .pre_fill_tx_bd_desc = rtl8822be_pre_fill_tx_bd_desc,
+ .rx_desc_buff_remained_cnt = rtl8822be_rx_desc_buff_remained_cnt,
+ .rx_check_dma_ok = rtl8822be_rx_check_dma_ok,
+ .fill_tx_desc = rtl8822be_tx_fill_desc,
+ .fill_tx_special_desc = rtl8822be_tx_fill_special_desc,
+ .query_rx_desc = rtl8822be_rx_query_desc,
+ .radio_onoff_checking = rtl8822be_gpio_radio_on_off_checking,
+ .switch_channel = rtl8822be_phy_sw_chnl,
+ .set_channel_access = rtl8822be_update_channel_access_setting,
+ .set_bw_mode = rtl8822be_phy_set_bw_mode,
+ .dm_watchdog = rtl8822be_phydm_watchdog,
+ .scan_operation_backup = rtl8822be_phy_scan_operation_backup,
+ .set_rf_power_state = rtl8822be_phy_set_rf_power_state,
+ .led_control = rtl8822be_led_control,
+ .set_desc = rtl8822be_set_desc,
+ .get_desc = rtl8822be_get_desc,
+ .is_tx_desc_closed = rtl8822be_is_tx_desc_closed,
+ .get_available_desc = rtl8822be_get_available_desc,
+ .tx_polling = rtl8822be_tx_polling,
+ .enable_hw_sec = rtl8822be_enable_hw_security_config,
+ .set_key = rtl8822be_set_key,
+ .init_sw_leds = rtl8822be_init_sw_leds,
+ .get_bbreg = rtl8822be_phy_query_bb_reg,
+ .set_bbreg = rtl8822be_phy_set_bb_reg,
+ .get_rfreg = rtl8822be_phy_query_rf_reg,
+ .set_rfreg = rtl8822be_phy_set_rf_reg,
+ .fill_h2c_cmd = rtl8822be_fill_h2c_cmd,
+ .set_default_port_id_cmd = rtl8822be_set_default_port_id_cmd,
+ .get_btc_status = rtl8822be_get_btc_status,
+ .rx_command_packet = rtl8822be_rx_command_packet,
+ .c2h_content_parsing = rtl8822be_c2h_content_parsing,
+ /* ops for halmac cb */
+ .halmac_cb_init_mac_register = rtl8822be_halmac_cb_init_mac_register,
+ .halmac_cb_init_bb_rf_register =
+ rtl8822be_halmac_cb_init_bb_rf_register,
+ .halmac_cb_write_data_rsvd_page =
+ rtl8822b_halmac_cb_write_data_rsvd_page,
+ .halmac_cb_write_data_h2c = rtl8822b_halmac_cb_write_data_h2c,
+ /* ops for phydm cb */
+ .get_txpower_index = rtl8822be_get_txpower_index,
+ .set_tx_power_index_by_rs = rtl8822be_phy_set_tx_power_index_by_rs,
+ .store_tx_power_by_rate = rtl8822be_store_tx_power_by_rate,
+ .phy_set_txpower_limit = rtl8822be_phy_set_txpower_limit,
+};
+
+static struct rtl_mod_params rtl8822be_mod_params = {
+ .sw_crypto = false,
+ .inactiveps = true,
+ .swctrl_lps = false,
+ .fwctrl_lps = true,
+ .msi_support = true,
+ .dma64 = false,
+ .aspm_support = 1,
+ .disable_watchdog = false,
+ .debug_level = 0,
+ .debug_mask = 0,
+};
+
+static struct rtl_hal_cfg rtl8822be_hal_cfg = {
+ .bar_id = 2,
+ .write_readback = false,
+ .name = "rtl8822be_pci",
+ .ops = &rtl8822be_hal_ops,
+ .mod_params = &rtl8822be_mod_params,
+ .spec_ver = RTL_SPEC_NEW_RATEID | RTL_SPEC_SUPPORT_VHT |
+ RTL_SPEC_NEW_FW_C2H,
+ .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL_8822B,
+ .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN_8822B,
+ .maps[SYS_CLK] = REG_SYS_CLK_CTRL_8822B,
+ .maps[MAC_RCR_AM] = AM,
+ .maps[MAC_RCR_AB] = AB,
+ .maps[MAC_RCR_ACRC32] = ACRC32,
+ .maps[MAC_RCR_ACF] = ACF,
+ .maps[MAC_RCR_AAP] = AAP,
+ .maps[MAC_HIMR] = REG_HIMR0_8822B,
+ .maps[MAC_HIMRE] = REG_HIMR1_8822B,
+
+ .maps[EFUSE_ACCESS] = REG_EFUSE_ACCESS_8822B,
+
+ .maps[EFUSE_TEST] = REG_LDO_EFUSE_CTRL_8822B,
+ .maps[EFUSE_CTRL] = REG_EFUSE_CTRL_8822B,
+ .maps[EFUSE_CLK] = 0,
+ .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL_8822B,
+ .maps[EFUSE_PWC_EV12V] = PWC_EV12V,
+ .maps[EFUSE_FEN_ELDR] = FEN_ELDR,
+ .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN,
+ .maps[EFUSE_ANA8M] = ANA8M,
+ .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE,
+ .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION,
+ .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN,
+ .maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES,
+
+ .maps[RWCAM] = REG_CAMCMD_8822B,
+ .maps[WCAMI] = REG_CAMWRITE_8822B,
+ .maps[RCAMO] = REG_CAMREAD_8822B,
+ .maps[CAMDBG] = REG_CAMDBG_8822B,
+ .maps[SECR] = REG_SECCFG_8822B,
+ .maps[SEC_CAM_NONE] = CAM_NONE,
+ .maps[SEC_CAM_WEP40] = CAM_WEP40,
+ .maps[SEC_CAM_TKIP] = CAM_TKIP,
+ .maps[SEC_CAM_AES] = CAM_AES,
+ .maps[SEC_CAM_WEP104] = CAM_WEP104,
+
+ .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6,
+ .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5,
+ .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4,
+ .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3,
+ .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2,
+ .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1,
+ /* .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8, */ /*need check*/
+ .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7,
+ .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6,
+ .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5,
+ .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4,
+ .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3,
+ .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2,
+ .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1,
+ /* .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2,*/
+ /* .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1,*/
+
+ .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW,
+ .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT,
+ .maps[RTL_IMR_BCNINT] = IMR_BCNDMAINT0,
+ .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW,
+ .maps[RTL_IMR_RDU] = IMR_RDU,
+ .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND,
+ .maps[RTL_IMR_H2CDOK] = IMR_H2CDOK,
+ .maps[RTL_IMR_BDOK] = IMR_BCNDOK0,
+ .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK,
+ .maps[RTL_IMR_TBDER] = IMR_TBDER,
+ .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK,
+ .maps[RTL_IMR_TBDOK] = IMR_TBDOK,
+ .maps[RTL_IMR_BKDOK] = IMR_BKDOK,
+ .maps[RTL_IMR_BEDOK] = IMR_BEDOK,
+ .maps[RTL_IMR_VIDOK] = IMR_VIDOK,
+ .maps[RTL_IMR_VODOK] = IMR_VODOK,
+ .maps[RTL_IMR_ROK] = IMR_ROK,
+ .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNDMAINT0 | IMR_TBDOK | IMR_TBDER),
+
+ .maps[RTL_RC_CCK_RATE1M] = DESC_RATE1M,
+ .maps[RTL_RC_CCK_RATE2M] = DESC_RATE2M,
+ .maps[RTL_RC_CCK_RATE5_5M] = DESC_RATE5_5M,
+ .maps[RTL_RC_CCK_RATE11M] = DESC_RATE11M,
+ .maps[RTL_RC_OFDM_RATE6M] = DESC_RATE6M,
+ .maps[RTL_RC_OFDM_RATE9M] = DESC_RATE9M,
+ .maps[RTL_RC_OFDM_RATE12M] = DESC_RATE12M,
+ .maps[RTL_RC_OFDM_RATE18M] = DESC_RATE18M,
+ .maps[RTL_RC_OFDM_RATE24M] = DESC_RATE24M,
+ .maps[RTL_RC_OFDM_RATE36M] = DESC_RATE36M,
+ .maps[RTL_RC_OFDM_RATE48M] = DESC_RATE48M,
+ .maps[RTL_RC_OFDM_RATE54M] = DESC_RATE54M,
+
+ .maps[RTL_RC_HT_RATEMCS7] = DESC_RATEMCS7,
+ .maps[RTL_RC_HT_RATEMCS15] = DESC_RATEMCS15,
+
+ /*VHT hightest rate*/
+ .maps[RTL_RC_VHT_RATE_1SS_MCS7] = DESC_RATEVHT1SS_MCS7,
+ .maps[RTL_RC_VHT_RATE_1SS_MCS8] = DESC_RATEVHT1SS_MCS8,
+ .maps[RTL_RC_VHT_RATE_1SS_MCS9] = DESC_RATEVHT1SS_MCS9,
+ .maps[RTL_RC_VHT_RATE_2SS_MCS7] = DESC_RATEVHT2SS_MCS7,
+ .maps[RTL_RC_VHT_RATE_2SS_MCS8] = DESC_RATEVHT2SS_MCS8,
+ .maps[RTL_RC_VHT_RATE_2SS_MCS9] = DESC_RATEVHT2SS_MCS9,
+};
+
+static const struct pci_device_id rtl8822be_pci_ids[] = {
+ {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xB822, rtl8822be_hal_cfg)},
+ {},
+};
+
+MODULE_DEVICE_TABLE(pci, rtl8822be_pci_ids);
+
+MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
+MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Realtek 8822BE 802.11n PCI wireless");
+MODULE_FIRMWARE("rtlwifi/rtl8822befw.bin");
+
+module_param_named(swenc, rtl8822be_mod_params.sw_crypto, bool, 0444);
+module_param_named(debug_level, rtl8822be_mod_params.debug_level, int, 0644);
+module_param_named(debug_mask, rtl8822be_mod_params.debug_mask, ullong, 0644);
+module_param_named(ips, rtl8822be_mod_params.inactiveps, bool, 0444);
+module_param_named(swlps, rtl8822be_mod_params.swctrl_lps, bool, 0444);
+module_param_named(fwlps, rtl8822be_mod_params.fwctrl_lps, bool, 0444);
+module_param_named(msi, rtl8822be_mod_params.msi_support, bool, 0444);
+module_param_named(dma64, rtl8822be_mod_params.dma64, bool, 0444);
+module_param_named(aspm, rtl8822be_mod_params.aspm_support, int, 0444);
+module_param_named(disable_watchdog, rtl8822be_mod_params.disable_watchdog,
+ bool, 0444);
+MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
+MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
+MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
+MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
+MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n");
+MODULE_PARM_DESC(dma64, "Set to 1 to use DMA 64 (default 0)\n");
+MODULE_PARM_DESC(aspm, "Set to 1 to enable ASPM (default 1)\n");
+MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)");
+MODULE_PARM_DESC(disable_watchdog,
+ "Set to 1 to disable the watchdog (default 0)\n");
+
+static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
+
+static struct pci_driver rtl8822be_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = rtl8822be_pci_ids,
+ .probe = rtl_pci_probe,
+ .remove = rtl_pci_disconnect,
+ .driver.pm = &rtlwifi_pm_ops,
+};
+
+module_pci_driver(rtl8822be_driver);
diff --git a/drivers/staging/rtlwifi/rtl8822be/sw.h b/drivers/staging/rtlwifi/rtl8822be/sw.h
new file mode 100644
index 0000000..931eba9
--- /dev/null
+++ b/drivers/staging/rtlwifi/rtl8822be/sw.h
@@ -0,0 +1,32 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL8822B_SW_H__
+#define __RTL8822B_SW_H__
+
+int rtl8822be_init_sw_vars(struct ieee80211_hw *hw);
+void rtl8822be_deinit_sw_vars(struct ieee80211_hw *hw);
+bool rtl8822be_get_btc_status(void);
+#endif
diff --git a/drivers/staging/rtlwifi/rtl8822be/trx.c b/drivers/staging/rtlwifi/rtl8822be/trx.c
new file mode 100644
index 0000000..38f80e4
--- /dev/null
+++ b/drivers/staging/rtlwifi/rtl8822be/trx.c
@@ -0,0 +1,1015 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../pci.h"
+#include "../base.h"
+#include "../stats.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "trx.h"
+#include "led.h"
+#include "fw.h"
+
+#include <linux/vermagic.h>
+
+static u8 _rtl8822be_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
+{
+ switch (hw_queue) {
+ case BEACON_QUEUE:
+ return QSLT_BEACON;
+ case H2C_QUEUE:
+ return QSLT_CMD;
+ case MGNT_QUEUE:
+ return QSLT_MGNT;
+ case HIGH_QUEUE:
+ return QSLT_HIGH;
+ default:
+ return skb->priority;
+ }
+}
+
+static void _rtl8822be_query_rxphystatus(struct ieee80211_hw *hw, u8 *phystrpt,
+ struct ieee80211_hdr *hdr,
+ struct rtl_stats *pstatus)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtlpriv->phydm.ops->phydm_query_phy_status(rtlpriv, phystrpt, hdr,
+ pstatus);
+
+ /* UI BSS List signal strength(in percentage),
+ * make it good looking, from 0~100.
+ */
+ pstatus->signalstrength =
+ (u8)(rtl_signal_scale_mapping(hw, pstatus->rx_pwdb_all));
+}
+
+static void _rtl8822be_translate_rx_signal_stuff(struct ieee80211_hw *hw,
+ struct sk_buff *skb,
+ struct rtl_stats *pstatus,
+ u8 *p_phystrpt)
+{
+ struct ieee80211_hdr *hdr;
+ u8 *tmp_buf;
+
+ tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift +
+ 24;
+
+ hdr = (struct ieee80211_hdr *)tmp_buf;
+
+ /* query phy status */
+ _rtl8822be_query_rxphystatus(hw, p_phystrpt, hdr, pstatus);
+
+ /* packet statistics */
+ if (pstatus->packet_beacon && pstatus->packet_matchbssid)
+ rtl_priv(hw)->dm.dbginfo.num_qry_beacon_pkt++;
+
+ if (pstatus->packet_matchbssid &&
+ ieee80211_is_data_qos(hdr->frame_control) &&
+ !is_multicast_ether_addr(ieee80211_get_DA(hdr))) {
+ struct ieee80211_qos_hdr *hdr_qos =
+ (struct ieee80211_qos_hdr *)tmp_buf;
+ u16 tid = le16_to_cpu(hdr_qos->qos_ctrl) & 0xf;
+
+ if (tid != 0 && tid != 3)
+ rtl_priv(hw)->dm.dbginfo.num_non_be_pkt++;
+ }
+
+ /* signal statistics */
+ if (p_phystrpt)
+ rtl_process_phyinfo(hw, tmp_buf, pstatus);
+}
+
+static void _rtl8822be_insert_emcontent(struct rtl_tcb_desc *ptcb_desc,
+ u8 *virtualaddress)
+{
+ u32 dwtmp = 0;
+
+ memset(virtualaddress, 0, 8);
+
+ SET_EARLYMODE_PKTNUM(virtualaddress, ptcb_desc->empkt_num);
+ if (ptcb_desc->empkt_num == 1) {
+ dwtmp = ptcb_desc->empkt_len[0];
+ } else {
+ dwtmp = ptcb_desc->empkt_len[0];
+ dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
+ dwtmp += ptcb_desc->empkt_len[1];
+ }
+ SET_EARLYMODE_LEN0(virtualaddress, dwtmp);
+
+ if (ptcb_desc->empkt_num <= 3) {
+ dwtmp = ptcb_desc->empkt_len[2];
+ } else {
+ dwtmp = ptcb_desc->empkt_len[2];
+ dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
+ dwtmp += ptcb_desc->empkt_len[3];
+ }
+ SET_EARLYMODE_LEN1(virtualaddress, dwtmp);
+ if (ptcb_desc->empkt_num <= 5) {
+ dwtmp = ptcb_desc->empkt_len[4];
+ } else {
+ dwtmp = ptcb_desc->empkt_len[4];
+ dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
+ dwtmp += ptcb_desc->empkt_len[5];
+ }
+ SET_EARLYMODE_LEN2_1(virtualaddress, dwtmp & 0xF);
+ SET_EARLYMODE_LEN2_2(virtualaddress, dwtmp >> 4);
+ if (ptcb_desc->empkt_num <= 7) {
+ dwtmp = ptcb_desc->empkt_len[6];
+ } else {
+ dwtmp = ptcb_desc->empkt_len[6];
+ dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
+ dwtmp += ptcb_desc->empkt_len[7];
+ }
+ SET_EARLYMODE_LEN3(virtualaddress, dwtmp);
+ if (ptcb_desc->empkt_num <= 9) {
+ dwtmp = ptcb_desc->empkt_len[8];
+ } else {
+ dwtmp = ptcb_desc->empkt_len[8];
+ dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
+ dwtmp += ptcb_desc->empkt_len[9];
+ }
+ SET_EARLYMODE_LEN4(virtualaddress, dwtmp);
+}
+
+static bool rtl8822be_get_rxdesc_is_ht(struct ieee80211_hw *hw, u8 *pdesc)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 rx_rate = 0;
+
+ rx_rate = GET_RX_DESC_RX_RATE(pdesc);
+
+ RT_TRACE(rtlpriv, COMP_RXDESC, DBG_LOUD, "rx_rate=0x%02x.\n", rx_rate);
+
+ if ((rx_rate >= DESC_RATEMCS0) && (rx_rate <= DESC_RATEMCS15))
+ return true;
+ else
+ return false;
+}
+
+static bool rtl8822be_get_rxdesc_is_vht(struct ieee80211_hw *hw, u8 *pdesc)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 rx_rate = 0;
+
+ rx_rate = GET_RX_DESC_RX_RATE(pdesc);
+
+ RT_TRACE(rtlpriv, COMP_RXDESC, DBG_LOUD, "rx_rate=0x%02x.\n", rx_rate);
+
+ if (rx_rate >= DESC_RATEVHT1SS_MCS0)
+ return true;
+ else
+ return false;
+}
+
+static u8 rtl8822be_get_rx_vht_nss(struct ieee80211_hw *hw, u8 *pdesc)
+{
+ u8 rx_rate = 0;
+ u8 vht_nss = 0;
+
+ rx_rate = GET_RX_DESC_RX_RATE(pdesc);
+
+ if ((rx_rate >= DESC_RATEVHT1SS_MCS0) &&
+ (rx_rate <= DESC_RATEVHT1SS_MCS9))
+ vht_nss = 1;
+ else if ((rx_rate >= DESC_RATEVHT2SS_MCS0) &&
+ (rx_rate <= DESC_RATEVHT2SS_MCS9))
+ vht_nss = 2;
+
+ return vht_nss;
+}
+
+bool rtl8822be_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *status,
+ struct ieee80211_rx_status *rx_status, u8 *pdesc,
+ struct sk_buff *skb)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 *p_phystrpt = NULL;
+ struct ieee80211_hdr *hdr;
+
+ u32 phystatus = GET_RX_DESC_PHYST(pdesc);
+
+ if (GET_RX_DESC_C2H(pdesc) == 0)
+ status->packet_report_type = NORMAL_RX;
+ else
+ status->packet_report_type = C2H_PACKET;
+
+ status->length = (u16)GET_RX_DESC_PKT_LEN(pdesc);
+ status->rx_drvinfo_size =
+ (u8)GET_RX_DESC_DRV_INFO_SIZE(pdesc) * RX_DRV_INFO_SIZE_UNIT;
+ status->rx_bufshift = (u8)(GET_RX_DESC_SHIFT(pdesc) & 0x03);
+ status->icv = (u16)GET_RX_DESC_ICV_ERR(pdesc);
+ status->crc = (u16)GET_RX_DESC_CRC32(pdesc);
+ status->hwerror = (status->crc | status->icv);
+ status->decrypted = !GET_RX_DESC_SWDEC(pdesc);
+ status->rate = (u8)GET_RX_DESC_RX_RATE(pdesc);
+ status->isampdu = (bool)(GET_RX_DESC_PAGGR(pdesc) == 1);
+ status->isfirst_ampdu = (bool)(GET_RX_DESC_PAGGR(pdesc) == 1);
+ status->timestamp_low = GET_RX_DESC_TSFL(pdesc);
+ status->is_ht = rtl8822be_get_rxdesc_is_ht(hw, pdesc);
+ status->is_vht = rtl8822be_get_rxdesc_is_vht(hw, pdesc);
+ status->vht_nss = rtl8822be_get_rx_vht_nss(hw, pdesc);
+ status->is_cck = RX_HAL_IS_CCK_RATE(status->rate);
+
+ status->macid = GET_RX_DESC_MACID(pdesc);
+ if (GET_RX_DESC_PATTERN_MATCH(pdesc))
+ status->wake_match = BIT(2);
+ else if (GET_RX_DESC_MAGIC_WAKE(pdesc))
+ status->wake_match = BIT(1);
+ else if (GET_RX_DESC_UNICAST_WAKE(pdesc))
+ status->wake_match = BIT(0);
+ else
+ status->wake_match = 0;
+ if (status->wake_match)
+ RT_TRACE(rtlpriv, COMP_RXDESC, DBG_LOUD,
+ "GGGGGGGGGGGGGet Wakeup Packet!! WakeMatch=%d\n",
+ status->wake_match);
+ rx_status->freq = hw->conf.chandef.chan->center_freq;
+ rx_status->band = hw->conf.chandef.chan->band;
+
+ if (phystatus)
+ p_phystrpt = (skb->data + status->rx_bufshift + 24);
+
+ hdr = (struct ieee80211_hdr *)(skb->data + status->rx_drvinfo_size +
+ status->rx_bufshift + 24);
+
+ if (status->crc)
+ rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
+
+ if (status->is_ht)
+ rx_status->encoding = RX_ENC_HT;
+ if (status->is_vht)
+ rx_status->encoding = RX_ENC_VHT;
+
+ rx_status->nss = status->vht_nss;
+
+ rx_status->flag |= RX_FLAG_MACTIME_START;
+
+ /* hw will set status->decrypted true, if it finds the
+ * frame is open data frame or mgmt frame.
+ */
+ /* So hw will not decryption robust management frame
+ * for IEEE80211w but still set status->decrypted
+ * true, so here we should set it back to undecrypted
+ * for IEEE80211w frame, and mac80211 sw will help
+ * to decrypt it
+ */
+ if (status->decrypted) {
+ if ((!_ieee80211_is_robust_mgmt_frame(hdr)) &&
+ (ieee80211_has_protected(hdr->frame_control)))
+ rx_status->flag |= RX_FLAG_DECRYPTED;
+ else
+ rx_status->flag &= ~RX_FLAG_DECRYPTED;
+ }
+
+ /* rate_idx: index of data rate into band's
+ * supported rates or MCS index if HT rates
+ * are use (RX_FLAG_HT)
+ */
+ /* Notice: this is diff with windows define */
+ rx_status->rate_idx = rtlwifi_rate_mapping(
+ hw, status->is_ht, status->is_vht, status->rate);
+
+ rx_status->mactime = status->timestamp_low;
+
+ _rtl8822be_translate_rx_signal_stuff(hw, skb, status, p_phystrpt);
+
+ /* below info. are filled by _rtl8822be_translate_rx_signal_stuff() */
+ if (!p_phystrpt)
+ goto label_no_physt;
+
+ rx_status->signal = status->recvsignalpower;
+
+ if (status->rx_packet_bw == HT_CHANNEL_WIDTH_20_40)
+ rx_status->bw = RATE_INFO_BW_40;
+ else if (status->rx_packet_bw == HT_CHANNEL_WIDTH_80)
+ rx_status->bw = RATE_INFO_BW_80;
+
+label_no_physt:
+
+ return true;
+}
+
+void rtl8822be_rx_check_dma_ok(struct ieee80211_hw *hw, u8 *header_desc,
+ u8 queue_index)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 first_seg;
+ u8 last_seg;
+ u16 total_len;
+ u16 read_cnt = 0;
+
+ if (!header_desc)
+ return;
+
+ do {
+ total_len = (u16)GET_RX_BUFFER_DESC_TOTAL_LENGTH(header_desc);
+ first_seg = (u8)GET_RX_BUFFER_DESC_FS(header_desc);
+ last_seg = (u8)GET_RX_BUFFER_DESC_LS(header_desc);
+
+ if (read_cnt++ > 20) {
+ RT_TRACE(rtlpriv, COMP_RECV, DBG_DMESG,
+ "RX chk DMA over %d times\n", read_cnt);
+ break;
+ }
+
+ } while (total_len == 0 && first_seg == 0 && last_seg == 0);
+}
+
+u16 rtl8822be_rx_desc_buff_remained_cnt(struct ieee80211_hw *hw, u8 queue_index)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u16 desc_idx_hw = 0, desc_idx_host = 0, remind_cnt = 0;
+ u32 tmp_4byte = 0;
+
+ u32 rw_mask = 0x1ff;
+
+ tmp_4byte = rtl_read_dword(rtlpriv, REG_RXQ_RXBD_IDX_8822B);
+ desc_idx_hw = (u16)((tmp_4byte >> 16) & rw_mask);
+ desc_idx_host = (u16)(tmp_4byte & rw_mask);
+
+ /* may be no data, donot rx */
+ if (desc_idx_hw == desc_idx_host)
+ return 0;
+
+ remind_cnt =
+ (desc_idx_hw > desc_idx_host) ?
+ (desc_idx_hw - desc_idx_host) :
+ (RX_DESC_NUM_8822BE - (desc_idx_host - desc_idx_hw));
+
+ rtlpci->rx_ring[queue_index].next_rx_rp = desc_idx_host;
+
+ return remind_cnt;
+}
+
+static u16 get_desc_address_from_queue_index(u16 queue_index)
+{
+ /*
+ * Note: Access these registers will take a lot of cost.
+ */
+ u16 desc_address = REG_BEQ_TXBD_IDX_8822B;
+
+ switch (queue_index) {
+ case BK_QUEUE:
+ desc_address = REG_BKQ_TXBD_IDX_8822B;
+ break;
+ case BE_QUEUE:
+ desc_address = REG_BEQ_TXBD_IDX_8822B;
+ break;
+ case VI_QUEUE:
+ desc_address = REG_VIQ_TXBD_IDX_8822B;
+ break;
+ case VO_QUEUE:
+ desc_address = REG_VOQ_TXBD_IDX_8822B;
+ break;
+ case BEACON_QUEUE:
+ desc_address = REG_BEQ_TXBD_IDX_8822B;
+ break;
+ case H2C_QUEUE:
+ desc_address = REG_H2CQ_TXBD_IDX_8822B;
+ break;
+ case MGNT_QUEUE:
+ desc_address = REG_MGQ_TXBD_IDX_8822B;
+ break;
+ case HIGH_QUEUE:
+ desc_address = REG_HI0Q_TXBD_IDX_8822B;
+ break;
+ case HCCA_QUEUE:
+ desc_address = REG_BEQ_TXBD_IDX_8822B;
+ break;
+ default:
+ break;
+ }
+ return desc_address;
+}
+
+/*free desc that can be used */
+u16 rtl8822be_get_available_desc(struct ieee80211_hw *hw, u8 q_idx)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[q_idx];
+
+ return calc_fifo_space(ring->cur_tx_rp, ring->cur_tx_wp,
+ TX_DESC_NUM_8822B);
+}
+
+void rtl8822be_pre_fill_tx_bd_desc(struct ieee80211_hw *hw, u8 *tx_bd_desc,
+ u8 *desc, u8 queue_index,
+ struct sk_buff *skb, dma_addr_t data_addr)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ u32 pkt_len = skb->len;
+ u16 desc_size = 48; /*tx desc size*/
+ u32 psblen = 0;
+ u32 total_packet_size = 0;
+ u16 current_bd_desc;
+ u8 i = 0;
+ /*u16 real_desc_size = 0x28;*/
+ u16 append_early_mode_size = 0;
+ u8 segmentnum = 1 << (RTL8822BE_SEG_NUM + 1);
+ dma_addr_t desc_dma_addr;
+ bool dma64 = rtlpriv->cfg->mod_params->dma64;
+
+ current_bd_desc = rtlpci->tx_ring[queue_index].cur_tx_wp;
+
+ total_packet_size = desc_size + pkt_len;
+
+ if (rtlpriv->rtlhal.earlymode_enable) {
+ if (queue_index < BEACON_QUEUE) {
+ append_early_mode_size = 8;
+ total_packet_size += append_early_mode_size;
+ }
+ }
+
+ /* page number (round up) */
+ psblen = (total_packet_size - 1) / 128 + 1;
+
+ /* tx desc addr */
+ desc_dma_addr = rtlpci->tx_ring[queue_index].dma +
+ (current_bd_desc * TX_DESC_SIZE);
+
+ /* Reset */
+ SET_TX_BUFF_DESC_LEN_0(tx_bd_desc, 0);
+ SET_TX_BUFF_DESC_PSB(tx_bd_desc, 0);
+ SET_TX_BUFF_DESC_OWN(tx_bd_desc, 0);
+
+ for (i = 1; i < segmentnum; i++) {
+ SET_TXBUFFER_DESC_LEN_WITH_OFFSET(tx_bd_desc, i, 0);
+ SET_TXBUFFER_DESC_AMSDU_WITH_OFFSET(tx_bd_desc, i, 0);
+ SET_TXBUFFER_DESC_ADD_LOW_WITH_OFFSET(tx_bd_desc, i, 0);
+ SET_TXBUFFER_DESC_ADD_HIGH_WITH_OFFSET(tx_bd_desc, i, 0, dma64);
+ }
+
+ /* Clear all status */
+ CLEAR_PCI_TX_DESC_CONTENT(desc, TX_DESC_SIZE);
+
+ if (rtlpriv->rtlhal.earlymode_enable) {
+ if (queue_index < BEACON_QUEUE)
+ SET_TX_BUFF_DESC_LEN_0(tx_bd_desc, desc_size + 8);
+ else
+ SET_TX_BUFF_DESC_LEN_0(tx_bd_desc, desc_size);
+ } else {
+ SET_TX_BUFF_DESC_LEN_0(tx_bd_desc, desc_size);
+ }
+ SET_TX_BUFF_DESC_PSB(tx_bd_desc, psblen);
+ SET_TX_BUFF_DESC_ADDR_LOW_0(tx_bd_desc, desc_dma_addr);
+ SET_TX_BUFF_DESC_ADDR_HIGH_0(tx_bd_desc, ((u64)desc_dma_addr >> 32),
+ dma64);
+
+ SET_TXBUFFER_DESC_LEN_WITH_OFFSET(tx_bd_desc, 1, pkt_len);
+ SET_TXBUFFER_DESC_AMSDU_WITH_OFFSET(tx_bd_desc, 1, 0);
+ SET_TXBUFFER_DESC_ADD_LOW_WITH_OFFSET(tx_bd_desc, 1, data_addr);
+ SET_TXBUFFER_DESC_ADD_HIGH_WITH_OFFSET(tx_bd_desc, 1,
+ ((u64)data_addr >> 32), dma64);
+
+ SET_TX_DESC_TXPKTSIZE(desc, (u16)(pkt_len));
+}
+
+static u8 rtl8822be_bw_mapping(struct ieee80211_hw *hw,
+ struct rtl_tcb_desc *ptcb_desc)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ u8 bw_setting_of_desc = 0;
+
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
+ "%s, current_chan_bw %d, packet_bw %d\n", __func__,
+ rtlphy->current_chan_bw, ptcb_desc->packet_bw);
+
+ if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) {
+ if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_80)
+ bw_setting_of_desc = 2;
+ else if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40)
+ bw_setting_of_desc = 1;
+ else
+ bw_setting_of_desc = 0;
+ } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
+ if ((ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40) ||
+ (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_80))
+ bw_setting_of_desc = 1;
+ else
+ bw_setting_of_desc = 0;
+ } else {
+ bw_setting_of_desc = 0;
+ }
+
+ return bw_setting_of_desc;
+}
+
+static u8 rtl8822be_sc_mapping(struct ieee80211_hw *hw,
+ struct rtl_tcb_desc *ptcb_desc)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ struct rtl_mac *mac = rtl_mac(rtlpriv);
+ u8 sc_setting_of_desc = 0;
+
+ if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) {
+ if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_80) {
+ sc_setting_of_desc = VHT_DATA_SC_DONOT_CARE;
+ } else if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40) {
+ if (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER)
+ sc_setting_of_desc =
+ VHT_DATA_SC_40_LOWER_OF_80MHZ;
+ else if (mac->cur_80_prime_sc ==
+ HAL_PRIME_CHNL_OFFSET_UPPER)
+ sc_setting_of_desc =
+ VHT_DATA_SC_40_UPPER_OF_80MHZ;
+ else
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_LOUD,
+ "%s: Not Correct Primary40MHz Setting\n",
+ __func__);
+ } else {
+ if ((mac->cur_40_prime_sc ==
+ HAL_PRIME_CHNL_OFFSET_LOWER) &&
+ (mac->cur_80_prime_sc ==
+ HAL_PRIME_CHNL_OFFSET_LOWER))
+ sc_setting_of_desc =
+ VHT_DATA_SC_20_LOWEST_OF_80MHZ;
+ else if ((mac->cur_40_prime_sc ==
+ HAL_PRIME_CHNL_OFFSET_UPPER) &&
+ (mac->cur_80_prime_sc ==
+ HAL_PRIME_CHNL_OFFSET_LOWER))
+ sc_setting_of_desc =
+ VHT_DATA_SC_20_LOWER_OF_80MHZ;
+ else if ((mac->cur_40_prime_sc ==
+ HAL_PRIME_CHNL_OFFSET_LOWER) &&
+ (mac->cur_80_prime_sc ==
+ HAL_PRIME_CHNL_OFFSET_UPPER))
+ sc_setting_of_desc =
+ VHT_DATA_SC_20_UPPER_OF_80MHZ;
+ else if ((mac->cur_40_prime_sc ==
+ HAL_PRIME_CHNL_OFFSET_UPPER) &&
+ (mac->cur_80_prime_sc ==
+ HAL_PRIME_CHNL_OFFSET_UPPER))
+ sc_setting_of_desc =
+ VHT_DATA_SC_20_UPPERST_OF_80MHZ;
+ else
+ RT_TRACE(
+ rtlpriv, COMP_SEND, DBG_LOUD,
+ "rtl8822be_sc_mapping: Not Correct Primary40MHz Setting\n");
+ }
+ } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
+ if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40) {
+ sc_setting_of_desc = VHT_DATA_SC_DONOT_CARE;
+ } else if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20) {
+ if (mac->cur_40_prime_sc ==
+ HAL_PRIME_CHNL_OFFSET_UPPER) {
+ sc_setting_of_desc =
+ VHT_DATA_SC_20_UPPER_OF_80MHZ;
+ } else if (mac->cur_40_prime_sc ==
+ HAL_PRIME_CHNL_OFFSET_LOWER) {
+ sc_setting_of_desc =
+ VHT_DATA_SC_20_LOWER_OF_80MHZ;
+ } else {
+ sc_setting_of_desc = VHT_DATA_SC_DONOT_CARE;
+ }
+ }
+ } else {
+ sc_setting_of_desc = VHT_DATA_SC_DONOT_CARE;
+ }
+
+ return sc_setting_of_desc;
+}
+
+void rtl8822be_tx_fill_desc(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
+ u8 *pdesc_tx, u8 *pbd_desc_tx,
+ struct ieee80211_tx_info *info,
+ struct ieee80211_sta *sta, struct sk_buff *skb,
+ u8 hw_queue, struct rtl_tcb_desc *ptcb_desc)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ u8 *pdesc = (u8 *)pdesc_tx;
+ u16 seq_number;
+ __le16 fc = hdr->frame_control;
+ u8 fw_qsel = _rtl8822be_map_hwqueue_to_fwqueue(skb, hw_queue);
+ bool firstseg =
+ ((hdr->seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
+ bool lastseg = ((hdr->frame_control &
+ cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
+ dma_addr_t mapping;
+ u8 short_gi = 0;
+
+ seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
+ rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc);
+ /* reserve 8 byte for AMPDU early mode */
+ if (rtlhal->earlymode_enable) {
+ skb_push(skb, EM_HDR_LEN);
+ memset(skb->data, 0, EM_HDR_LEN);
+ }
+ mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
+ PCI_DMA_TODEVICE);
+ if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "DMA mapping error");
+ return;
+ }
+
+ if (pbd_desc_tx)
+ rtl8822be_pre_fill_tx_bd_desc(hw, pbd_desc_tx, pdesc, hw_queue,
+ skb, mapping);
+
+ if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
+ firstseg = true;
+ lastseg = true;
+ }
+ if (firstseg) {
+ if (rtlhal->earlymode_enable) {
+ SET_TX_DESC_PKT_OFFSET(pdesc, 1);
+ SET_TX_DESC_OFFSET(pdesc,
+ USB_HWDESC_HEADER_LEN + EM_HDR_LEN);
+ if (ptcb_desc->empkt_num) {
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
+ "Insert 8 byte.pTcb->EMPktNum:%d\n",
+ ptcb_desc->empkt_num);
+ _rtl8822be_insert_emcontent(ptcb_desc,
+ (u8 *)(skb->data));
+ }
+ } else {
+ SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
+ }
+
+ /* tx report */
+ rtl_get_tx_report(ptcb_desc, pdesc, hw);
+
+ if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G &&
+ ptcb_desc->hw_rate < DESC_RATE6M) {
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_WARNING,
+ "hw_rate=0x%X is invalid in 5G\n",
+ ptcb_desc->hw_rate);
+ ptcb_desc->hw_rate = DESC_RATE6M;
+ }
+ SET_TX_DESC_DATARATE(pdesc, ptcb_desc->hw_rate);
+
+ if (ptcb_desc->hw_rate > DESC_RATEMCS0)
+ short_gi = (ptcb_desc->use_shortgi) ? 1 : 0;
+ else
+ short_gi = (ptcb_desc->use_shortpreamble) ? 1 : 0;
+
+ if (info->flags & IEEE80211_TX_CTL_AMPDU) {
+ SET_TX_DESC_AGG_EN(pdesc, 1);
+ SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x1F);
+ }
+ SET_TX_DESC_SW_SEQ(pdesc, seq_number);
+ SET_TX_DESC_RTSEN(pdesc, ((ptcb_desc->rts_enable &&
+ !ptcb_desc->cts_enable) ?
+ 1 :
+ 0));
+ SET_TX_DESC_HW_RTS_EN(pdesc, 0);
+ SET_TX_DESC_CTS2SELF(pdesc, ((ptcb_desc->cts_enable) ? 1 : 0));
+
+ SET_TX_DESC_RTSRATE(pdesc, ptcb_desc->rts_rate);
+ SET_TX_DESC_RTS_SC(pdesc, ptcb_desc->rts_sc);
+ SET_TX_DESC_RTS_SHORT(
+ pdesc,
+ ((ptcb_desc->rts_rate <= DESC_RATE54M) ?
+ (ptcb_desc->rts_use_shortpreamble ? 1 : 0) :
+ (ptcb_desc->rts_use_shortgi ? 1 : 0)));
+
+ if (ptcb_desc->tx_enable_sw_calc_duration)
+ SET_TX_DESC_NAVUSEHDR(pdesc, 1);
+
+ SET_TX_DESC_DATA_BW(pdesc, rtl8822be_bw_mapping(hw, ptcb_desc));
+ SET_TX_DESC_DATA_SC(pdesc, rtl8822be_sc_mapping(hw, ptcb_desc));
+
+ if (sta) {
+ u8 ampdu_density = sta->ht_cap.ampdu_density;
+
+ SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
+ }
+ if (info->control.hw_key) {
+ struct ieee80211_key_conf *key = info->control.hw_key;
+
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ case WLAN_CIPHER_SUITE_TKIP:
+ SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
+ break;
+ default:
+ SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
+ break;
+ }
+ }
+
+ SET_TX_DESC_QSEL(pdesc, fw_qsel);
+
+ if (rtlphy->current_channel > 14) {
+ /* OFDM 6M */
+ SET_TX_DESC_DATA_RTY_LOWEST_RATE(pdesc, 4);
+ SET_TX_DESC_RTS_RTY_LOWEST_RATE(pdesc, 4);
+ } else {
+ /* CCK 1M */
+ SET_TX_DESC_DATA_RTY_LOWEST_RATE(pdesc, 0);
+ SET_TX_DESC_RTS_RTY_LOWEST_RATE(pdesc, 0);
+ }
+ SET_TX_DESC_DISDATAFB(pdesc,
+ ptcb_desc->disable_ratefallback ? 1 : 0);
+ SET_TX_DESC_USE_RATE(pdesc, ptcb_desc->use_driver_rate ? 1 : 0);
+
+ /*SET_TX_DESC_PWR_STATUS(pdesc, pwr_status);*/
+ /* Set TxRate and RTSRate in TxDesc */
+ /* This prevent Tx initial rate of new-coming packets */
+ /* from being overwritten by retried packet rate.*/
+ if (!ptcb_desc->use_driver_rate) {
+ /*SET_TX_DESC_RTS_RATE(pdesc, 0x08); */
+ /* SET_TX_DESC_TX_RATE(pdesc, 0x0b); */
+ }
+ if (ieee80211_is_data_qos(fc)) {
+ if (mac->rdg_en) {
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
+ "Enable RDG function.\n");
+ SET_TX_DESC_RDG_EN(pdesc, 1);
+ SET_TX_DESC_HTC(pdesc, 1);
+ }
+ }
+
+ SET_TX_DESC_PORT_ID(pdesc, 0);
+ SET_TX_DESC_MULTIPLE_PORT(pdesc, 0);
+ }
+
+ SET_TX_DESC_LS(pdesc, (lastseg ? 1 : 0));
+ if (rtlpriv->dm.useramask) {
+ SET_TX_DESC_RATE_ID(pdesc, ptcb_desc->ratr_index);
+ SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id);
+ } else {
+ SET_TX_DESC_RATE_ID(pdesc, 0xC + ptcb_desc->ratr_index);
+ SET_TX_DESC_MACID(pdesc, ptcb_desc->ratr_index);
+ }
+
+ SET_TX_DESC_MOREFRAG(pdesc, (lastseg ? 0 : 1));
+ if (ptcb_desc->multicast || ptcb_desc->broadcast) {
+ SET_TX_DESC_BMC(pdesc, 1);
+ /* BMC must be not AGG */
+ SET_TX_DESC_AGG_EN(pdesc, 0);
+ }
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
+
+ /* debug purpose: used to check tx desc is correct or not */
+ /*rtlpriv->halmac.ops->halmac_chk_txdesc(rtlpriv, pdesc,
+ * skb->len + USB_HWDESC_HEADER_LEN);
+ */
+}
+
+void rtl8822be_tx_fill_special_desc(struct ieee80211_hw *hw, u8 *pdesc,
+ u8 *pbd_desc, struct sk_buff *skb,
+ u8 hw_queue)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ u8 fw_queue;
+ u8 txdesc_len = 48;
+
+ dma_addr_t mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
+ PCI_DMA_TODEVICE);
+
+ if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "DMA mapping error");
+ return;
+ }
+
+ rtl8822be_pre_fill_tx_bd_desc(hw, pbd_desc, pdesc, hw_queue, skb,
+ mapping);
+
+ /* it should be BEACON_QUEUE or H2C_QUEUE,
+ * so skb=NULL is safe to assert
+ */
+ fw_queue = _rtl8822be_map_hwqueue_to_fwqueue(NULL, hw_queue);
+
+ CLEAR_PCI_TX_DESC_CONTENT(pdesc, txdesc_len);
+
+ /* common part for BEACON and H2C */
+ SET_TX_DESC_TXPKTSIZE((u8 *)pdesc, (u16)(skb->len));
+
+ SET_TX_DESC_QSEL(pdesc, fw_queue);
+
+ if (hw_queue == H2C_QUEUE) {
+ /* fill H2C */
+ SET_TX_DESC_OFFSET(pdesc, 0);
+
+ } else {
+ /* fill beacon */
+ SET_TX_DESC_OFFSET(pdesc, txdesc_len);
+
+ SET_TX_DESC_DATARATE(pdesc, DESC_RATE1M);
+
+ SET_TX_DESC_SW_SEQ(pdesc, 0);
+
+ SET_TX_DESC_RATE_ID(pdesc, 7);
+ SET_TX_DESC_MACID(pdesc, 0);
+
+ SET_TX_DESC_LS(pdesc, 1);
+
+ SET_TX_DESC_OFFSET(pdesc, 48);
+
+ SET_TX_DESC_USE_RATE(pdesc, 1);
+ }
+
+ RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C Tx Cmd Content\n",
+ pdesc, txdesc_len);
+}
+
+void rtl8822be_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
+ u8 desc_name, u8 *val)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 q_idx = *val;
+ bool dma64 = rtlpriv->cfg->mod_params->dma64;
+
+ if (istx) {
+ switch (desc_name) {
+ case HW_DESC_OWN: {
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[q_idx];
+ u16 max_tx_desc = ring->entries;
+
+ if (q_idx == BEACON_QUEUE) {
+ /* in case of beacon, pdesc is BD desc. */
+ u8 *pbd_desc = pdesc;
+
+ ring->cur_tx_wp = 0;
+ ring->cur_tx_rp = 0;
+ SET_TX_BUFF_DESC_OWN(pbd_desc, 1);
+ return;
+ }
+
+ /* make sure tx desc is available by caller */
+ ring->cur_tx_wp = ((ring->cur_tx_wp + 1) % max_tx_desc);
+
+ rtl_write_word(
+ rtlpriv,
+ get_desc_address_from_queue_index(
+ q_idx),
+ ring->cur_tx_wp);
+ } break;
+ }
+ } else {
+ switch (desc_name) {
+ case HW_DESC_RX_PREPARE:
+ SET_RX_BUFFER_DESC_LS(pdesc, 0);
+ SET_RX_BUFFER_DESC_FS(pdesc, 0);
+ SET_RX_BUFFER_DESC_TOTAL_LENGTH(pdesc, 0);
+
+ SET_RX_BUFFER_DESC_DATA_LENGTH(
+ pdesc, MAX_RECEIVE_BUFFER_SIZE + RX_DESC_SIZE);
+
+ SET_RX_BUFFER_PHYSICAL_LOW(
+ pdesc, (*(dma_addr_t *)val) & DMA_BIT_MASK(32));
+ SET_RX_BUFFER_PHYSICAL_HIGH(
+ pdesc, ((u64)(*(dma_addr_t *)val) >> 32),
+ dma64);
+ break;
+ default:
+ WARN_ONCE(true, "ERR rxdesc :%d not process\n",
+ desc_name);
+ break;
+ }
+ }
+}
+
+u64 rtl8822be_get_desc(struct ieee80211_hw *hw,
+ u8 *pdesc, bool istx, u8 desc_name)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u64 ret = 0;
+ u8 *pbd_desc = pdesc;
+ bool dma64 = rtlpriv->cfg->mod_params->dma64;
+
+ if (istx) {
+ switch (desc_name) {
+ case HW_DESC_TXBUFF_ADDR:
+ ret = GET_TXBUFFER_DESC_ADDR_LOW(pbd_desc, 1);
+ ret |= (u64)GET_TXBUFFER_DESC_ADDR_HIGH(pbd_desc, 1,
+ dma64) << 32;
+ break;
+ default:
+ WARN_ONCE(true, "ERR txdesc :%d not process\n",
+ desc_name);
+ break;
+ }
+ } else {
+ switch (desc_name) {
+ case HW_DESC_RXPKT_LEN:
+ ret = GET_RX_DESC_PKT_LEN(pdesc);
+ break;
+ default:
+ WARN_ONCE(true, "ERR rxdesc :%d not process\n",
+ desc_name);
+ break;
+ }
+ }
+ return ret;
+}
+
+bool rtl8822be_is_tx_desc_closed(struct ieee80211_hw *hw, u8 hw_queue,
+ u16 index)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ bool ret = false;
+ struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue];
+ u16 cur_tx_rp, cur_tx_wp;
+ u16 tmp16;
+
+ /*
+ * design rule:
+ * idx <= cur_tx_rp <= hw_rp <= cur_tx_wp = hw_wp
+ */
+
+ if (index == ring->cur_tx_rp) {
+ /* update only if sw_rp reach hw_rp */
+ tmp16 = rtl_read_word(
+ rtlpriv,
+ get_desc_address_from_queue_index(hw_queue) + 2);
+
+ cur_tx_rp = tmp16 & 0x01ff;
+ cur_tx_wp = ring->cur_tx_wp;
+
+ /* don't need to update ring->cur_tx_wp */
+ ring->cur_tx_rp = cur_tx_rp;
+ }
+
+ if (index == ring->cur_tx_rp)
+ ret = false; /* no more */
+ else
+ ret = true; /* more */
+
+ if (hw_queue == BEACON_QUEUE)
+ ret = true;
+
+ if (rtlpriv->rtlhal.driver_is_goingto_unload ||
+ rtlpriv->psc.rfoff_reason > RF_CHANGE_BY_PS)
+ ret = true;
+
+ return ret;
+}
+
+void rtl8822be_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ if (hw_queue == BEACON_QUEUE) {
+ /* kick start */
+ rtl_write_byte(
+ rtlpriv, REG_RX_RXBD_NUM_8822B + 1,
+ rtl_read_byte(rtlpriv, REG_RX_RXBD_NUM_8822B + 1) |
+ BIT(4));
+ }
+}
+
+u32 rtl8822be_rx_command_packet(struct ieee80211_hw *hw,
+ const struct rtl_stats *status,
+ struct sk_buff *skb)
+{
+ u32 result = 0;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ switch (status->packet_report_type) {
+ case NORMAL_RX:
+ result = 0;
+ break;
+ case C2H_PACKET:
+ rtl8822be_c2h_packet_handler(hw, skb->data, (u8)skb->len);
+ result = 1;
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_RECV, DBG_TRACE,
+ "Unknown packet type %d\n",
+ status->packet_report_type);
+ break;
+ }
+
+ return result;
+}
diff --git a/drivers/staging/rtlwifi/rtl8822be/trx.h b/drivers/staging/rtlwifi/rtl8822be/trx.h
new file mode 100644
index 0000000..db769f3
--- /dev/null
+++ b/drivers/staging/rtlwifi/rtl8822be/trx.h
@@ -0,0 +1,165 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL8822B_TRX_H__
+#define __RTL8822B_TRX_H__
+
+#include "../halmac/halmac_tx_desc_nic.h"
+#include "../halmac/halmac_rx_desc_nic.h"
+
+#define TX_DESC_SIZE 64
+
+#define RX_DRV_INFO_SIZE_UNIT 8
+
+#define TX_DESC_NEXT_DESC_OFFSET 48
+#define USB_HWDESC_HEADER_LEN 48
+
+#define RX_DESC_SIZE 24
+#define MAX_RECEIVE_BUFFER_SIZE 8192
+
+#define SET_EARLYMODE_PKTNUM(__paddr, __val) \
+ SET_BITS_TO_LE_4BYTE(__paddr, 0, 4, __val)
+#define SET_EARLYMODE_LEN0(__paddr, __val) \
+ SET_BITS_TO_LE_4BYTE(__paddr, 4, 15, __val)
+#define SET_EARLYMODE_LEN1(__paddr, __val) \
+ SET_BITS_TO_LE_4BYTE(__paddr, 16, 2, __val)
+#define SET_EARLYMODE_LEN1_1(__paddr, __val) \
+ SET_BITS_TO_LE_4BYTE(__paddr, 19, 13, __val)
+#define SET_EARLYMODE_LEN1_2(__paddr, __val) \
+ SET_BITS_TO_LE_4BYTE(__paddr + 4, 0, 2, __val)
+#define SET_EARLYMODE_LEN2(__paddr, __val) \
+ SET_BITS_TO_LE_4BYTE(__paddr + 4, 2, 15, __val)
+#define SET_EARLYMODE_LEN2_1(__paddr, __val) \
+ SET_BITS_TO_LE_4BYTE(__paddr, 2, 4, __val)
+#define SET_EARLYMODE_LEN2_2(__paddr, __val) \
+ SET_BITS_TO_LE_4BYTE(__paddr + 4, 0, 8, __val)
+#define SET_EARLYMODE_LEN3(__paddr, __val) \
+ SET_BITS_TO_LE_4BYTE(__paddr + 4, 17, 15, __val)
+#define SET_EARLYMODE_LEN4(__paddr, __val) \
+ SET_BITS_TO_LE_4BYTE(__paddr + 4, 20, 12, __val)
+
+/* TX/RX buffer descriptor */
+
+/* for Txfilldescroptor8822be, fill the desc content. */
+#define SET_TXBUFFER_DESC_LEN_WITH_OFFSET(__pdesc, __offset, __val) \
+ SET_BITS_TO_LE_4BYTE((__pdesc) + ((__offset) * 16), 0, 16, __val)
+#define SET_TXBUFFER_DESC_AMSDU_WITH_OFFSET(__pdesc, __offset, __val) \
+ SET_BITS_TO_LE_4BYTE((__pdesc) + ((__offset) * 16), 31, 1, __val)
+#define SET_TXBUFFER_DESC_ADD_LOW_WITH_OFFSET(__pdesc, __offset, __val) \
+ SET_BITS_TO_LE_4BYTE((__pdesc) + ((__offset) * 16) + 4, 0, 32, __val)
+#define SET_TXBUFFER_DESC_ADD_HIGH_WITH_OFFSET(pbd, off, val, dma64) \
+ (dma64 ? SET_BITS_TO_LE_4BYTE((pbd) + ((off) * 16) + 8, 0, 32, val) : 0)
+#define GET_TXBUFFER_DESC_ADDR_LOW(__pdesc, __offset) \
+ LE_BITS_TO_4BYTE((__pdesc) + ((__offset) * 16) + 4, 0, 32)
+#define GET_TXBUFFER_DESC_ADDR_HIGH(pbd, off, dma64) \
+ (dma64 ? LE_BITS_TO_4BYTE((pbd) + ((off) * 16) + 8, 0, 32) : 0)
+
+/* Dword 0 */
+#define SET_TX_BUFF_DESC_LEN_0(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val)
+#define SET_TX_BUFF_DESC_PSB(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc, 16, 15, __val)
+#define SET_TX_BUFF_DESC_OWN(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
+
+/* Dword 1 */
+#define SET_TX_BUFF_DESC_ADDR_LOW_0(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE((__pdesc) + 4, 0, 32, __val)
+/* Dword 2 */
+#define SET_TX_BUFF_DESC_ADDR_HIGH_0(bdesc, val, dma64) \
+ SET_TXBUFFER_DESC_ADD_HIGH_WITH_OFFSET(bdesc, 0, val, dma64)
+/* Dword 3 / RESERVED 0 */
+
+/* RX buffer */
+
+/* DWORD 0 */
+#define SET_RX_BUFFER_DESC_DATA_LENGTH(__rx_status_desc, __val) \
+ SET_BITS_TO_LE_4BYTE(__rx_status_desc, 0, 14, __val)
+#define SET_RX_BUFFER_DESC_LS(__rx_status_desc, __val) \
+ SET_BITS_TO_LE_4BYTE(__rx_status_desc, 15, 1, __val)
+#define SET_RX_BUFFER_DESC_FS(__rx_status_desc, __val) \
+ SET_BITS_TO_LE_4BYTE(__rx_status_desc, 16, 1, __val)
+#define SET_RX_BUFFER_DESC_TOTAL_LENGTH(__rx_status_desc, __val) \
+ SET_BITS_TO_LE_4BYTE(__rx_status_desc, 16, 15, __val)
+
+#define GET_RX_BUFFER_DESC_OWN(__rx_status_desc) \
+ LE_BITS_TO_4BYTE(__rx_status_desc, 31, 1)
+#define GET_RX_BUFFER_DESC_LS(__rx_status_desc) \
+ LE_BITS_TO_4BYTE(__rx_status_desc, 15, 1)
+#define GET_RX_BUFFER_DESC_FS(__rx_status_desc) \
+ LE_BITS_TO_4BYTE(__rx_status_desc, 16, 1)
+#define GET_RX_BUFFER_DESC_TOTAL_LENGTH(__rx_status_desc) \
+ LE_BITS_TO_4BYTE(__rx_status_desc, 16, 15)
+
+/* DWORD 1 */
+#define SET_RX_BUFFER_PHYSICAL_LOW(__rx_status_desc, __val) \
+ SET_BITS_TO_LE_4BYTE(__rx_status_desc + 4, 0, 32, __val)
+
+/* DWORD 2 */
+#define SET_RX_BUFFER_PHYSICAL_HIGH(__rx_status_desc, __val, dma64) \
+ (dma64 ? SET_BITS_TO_LE_4BYTE((__rx_status_desc) + 8, 0, 32, __val) : 0)
+
+#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \
+ do { \
+ if (_size > TX_DESC_NEXT_DESC_OFFSET) \
+ memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \
+ else \
+ memset(__pdesc, 0, _size); \
+ } while (0)
+
+void rtl8822be_rx_check_dma_ok(struct ieee80211_hw *hw, u8 *header_desc,
+ u8 queue_index);
+u16 rtl8822be_rx_desc_buff_remained_cnt(struct ieee80211_hw *hw,
+ u8 queue_index);
+u16 rtl8822be_get_available_desc(struct ieee80211_hw *hw, u8 queue_index);
+void rtl8822be_pre_fill_tx_bd_desc(struct ieee80211_hw *hw, u8 *tx_bd_desc,
+ u8 *desc, u8 queue_index,
+ struct sk_buff *skb, dma_addr_t addr);
+
+void rtl8822be_tx_fill_desc(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
+ u8 *pdesc_tx, u8 *pbd_desc_tx,
+ struct ieee80211_tx_info *info,
+ struct ieee80211_sta *sta, struct sk_buff *skb,
+ u8 hw_queue, struct rtl_tcb_desc *ptcb_desc);
+void rtl8822be_tx_fill_special_desc(struct ieee80211_hw *hw, u8 *pdesc,
+ u8 *pbd_desc, struct sk_buff *skb,
+ u8 hw_queue);
+bool rtl8822be_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *status,
+ struct ieee80211_rx_status *rx_status, u8 *pdesc,
+ struct sk_buff *skb);
+void rtl8822be_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
+ u8 desc_name, u8 *val);
+u64 rtl8822be_get_desc(struct ieee80211_hw *hw,
+ u8 *pdesc, bool istx, u8 desc_name);
+bool rtl8822be_is_tx_desc_closed(struct ieee80211_hw *hw, u8 hw_queue,
+ u16 index);
+void rtl8822be_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
+void rtl8822be_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
+ bool firstseg, bool lastseg,
+ struct sk_buff *skb);
+u32 rtl8822be_rx_command_packet(struct ieee80211_hw *hw,
+ const struct rtl_stats *status,
+ struct sk_buff *skb);
+#endif
diff --git a/drivers/staging/rtlwifi/stats.c b/drivers/staging/rtlwifi/stats.c
new file mode 100644
index 0000000..96eb14c
--- /dev/null
+++ b/drivers/staging/rtlwifi/stats.c
@@ -0,0 +1,260 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2012 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#include "wifi.h"
+#include "stats.h"
+#include <linux/export.h>
+
+u8 rtl_query_rxpwrpercentage(s8 antpower)
+{
+ if ((antpower <= -100) || (antpower >= 20))
+ return 0;
+ else if (antpower >= 0)
+ return 100;
+ else
+ return 100 + antpower;
+}
+
+u8 rtl_evm_db_to_percentage(s8 value)
+{
+ s8 ret_val = clamp(-value, 0, 33) * 3;
+
+ if (ret_val == 99)
+ ret_val = 100;
+
+ return ret_val;
+}
+
+static long rtl_translate_todbm(struct ieee80211_hw *hw,
+ u8 signal_strength_index)
+{
+ long signal_power;
+
+ signal_power = (long)((signal_strength_index + 1) >> 1);
+ signal_power -= 95;
+ return signal_power;
+}
+
+long rtl_signal_scale_mapping(struct ieee80211_hw *hw, long currsig)
+{
+ long retsig;
+
+ if (currsig >= 61 && currsig <= 100)
+ retsig = 90 + ((currsig - 60) / 4);
+ else if (currsig >= 41 && currsig <= 60)
+ retsig = 78 + ((currsig - 40) / 2);
+ else if (currsig >= 31 && currsig <= 40)
+ retsig = 66 + (currsig - 30);
+ else if (currsig >= 21 && currsig <= 30)
+ retsig = 54 + (currsig - 20);
+ else if (currsig >= 5 && currsig <= 20)
+ retsig = 42 + (((currsig - 5) * 2) / 3);
+ else if (currsig == 4)
+ retsig = 36;
+ else if (currsig == 3)
+ retsig = 27;
+ else if (currsig == 2)
+ retsig = 18;
+ else if (currsig == 1)
+ retsig = 9;
+ else
+ retsig = currsig;
+
+ return retsig;
+}
+
+static void rtl_process_ui_rssi(struct ieee80211_hw *hw,
+ struct rtl_stats *pstatus)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+ u8 rfpath;
+ u32 last_rssi, tmpval;
+
+ if (!pstatus->packet_toself && !pstatus->packet_beacon)
+ return;
+
+ rtlpriv->stats.pwdb_all_cnt += pstatus->rx_pwdb_all;
+ rtlpriv->stats.rssi_calculate_cnt++;
+
+ if (rtlpriv->stats.ui_rssi.total_num++ >= PHY_RSSI_SLID_WIN_MAX) {
+ rtlpriv->stats.ui_rssi.total_num = PHY_RSSI_SLID_WIN_MAX;
+ last_rssi = rtlpriv->stats.ui_rssi.elements[
+ rtlpriv->stats.ui_rssi.index];
+ rtlpriv->stats.ui_rssi.total_val -= last_rssi;
+ }
+ rtlpriv->stats.ui_rssi.total_val += pstatus->signalstrength;
+ rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.index++] =
+ pstatus->signalstrength;
+ if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX)
+ rtlpriv->stats.ui_rssi.index = 0;
+ tmpval = rtlpriv->stats.ui_rssi.total_val /
+ rtlpriv->stats.ui_rssi.total_num;
+ rtlpriv->stats.signal_strength = rtl_translate_todbm(hw, (u8)tmpval);
+ pstatus->rssi = rtlpriv->stats.signal_strength;
+
+ if (pstatus->is_cck)
+ return;
+
+ for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
+ rfpath++) {
+ if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {
+ rtlpriv->stats.rx_rssi_percentage[rfpath] =
+ pstatus->rx_mimo_signalstrength[rfpath];
+ }
+ if (pstatus->rx_mimo_signalstrength[rfpath] >
+ rtlpriv->stats.rx_rssi_percentage[rfpath]) {
+ rtlpriv->stats.rx_rssi_percentage[rfpath] =
+ ((rtlpriv->stats.rx_rssi_percentage[rfpath] *
+ (RX_SMOOTH_FACTOR - 1)) +
+ (pstatus->rx_mimo_signalstrength[rfpath])) /
+ (RX_SMOOTH_FACTOR);
+ rtlpriv->stats.rx_rssi_percentage[rfpath] =
+ rtlpriv->stats.rx_rssi_percentage[rfpath] + 1;
+ } else {
+ rtlpriv->stats.rx_rssi_percentage[rfpath] =
+ ((rtlpriv->stats.rx_rssi_percentage[rfpath] *
+ (RX_SMOOTH_FACTOR - 1)) +
+ (pstatus->rx_mimo_signalstrength[rfpath])) /
+ (RX_SMOOTH_FACTOR);
+ }
+ rtlpriv->stats.rx_snr_db[rfpath] = pstatus->rx_snr[rfpath];
+ rtlpriv->stats.rx_evm_dbm[rfpath] =
+ pstatus->rx_mimo_evm_dbm[rfpath];
+ rtlpriv->stats.rx_cfo_short[rfpath] =
+ pstatus->cfo_short[rfpath];
+ rtlpriv->stats.rx_cfo_tail[rfpath] = pstatus->cfo_tail[rfpath];
+ }
+}
+
+static void rtl_update_rxsignalstatistics(struct ieee80211_hw *hw,
+ struct rtl_stats *pstatus)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ int weighting = 0;
+
+ if (rtlpriv->stats.recv_signal_power == 0)
+ rtlpriv->stats.recv_signal_power = pstatus->recvsignalpower;
+ if (pstatus->recvsignalpower > rtlpriv->stats.recv_signal_power)
+ weighting = 5;
+ else if (pstatus->recvsignalpower < rtlpriv->stats.recv_signal_power)
+ weighting = (-5);
+ rtlpriv->stats.recv_signal_power = (rtlpriv->stats.recv_signal_power *
+ 5 + pstatus->recvsignalpower + weighting) / 6;
+}
+
+static void rtl_process_pwdb(struct ieee80211_hw *hw, struct rtl_stats *pstatus)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_sta_info *drv_priv = NULL;
+ struct ieee80211_sta *sta = NULL;
+ long undec_sm_pwdb;
+
+ rcu_read_lock();
+ if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION)
+ sta = rtl_find_sta(hw, pstatus->psaddr);
+
+ /* adhoc or ap mode */
+ if (sta) {
+ drv_priv = (struct rtl_sta_info *)sta->drv_priv;
+ undec_sm_pwdb = drv_priv->rssi_stat.undec_sm_pwdb;
+ } else {
+ undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
+ }
+
+ if (undec_sm_pwdb < 0)
+ undec_sm_pwdb = pstatus->rx_pwdb_all;
+ if (pstatus->rx_pwdb_all > (u32)undec_sm_pwdb) {
+ undec_sm_pwdb = (((undec_sm_pwdb) *
+ (RX_SMOOTH_FACTOR - 1)) +
+ (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
+ undec_sm_pwdb = undec_sm_pwdb + 1;
+ } else {
+ undec_sm_pwdb = (((undec_sm_pwdb) *
+ (RX_SMOOTH_FACTOR - 1)) +
+ (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
+ }
+
+ if (sta)
+ drv_priv->rssi_stat.undec_sm_pwdb = undec_sm_pwdb;
+ else
+ rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb;
+ rcu_read_unlock();
+
+ rtl_update_rxsignalstatistics(hw, pstatus);
+}
+
+static void rtl_process_ui_link_quality(struct ieee80211_hw *hw,
+ struct rtl_stats *pstatus)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 last_evm, n_stream, tmpval;
+
+ if (pstatus->signalquality == 0)
+ return;
+
+ if (rtlpriv->stats.ui_link_quality.total_num++ >=
+ PHY_LINKQUALITY_SLID_WIN_MAX) {
+ rtlpriv->stats.ui_link_quality.total_num =
+ PHY_LINKQUALITY_SLID_WIN_MAX;
+ last_evm = rtlpriv->stats.ui_link_quality.elements[
+ rtlpriv->stats.ui_link_quality.index];
+ rtlpriv->stats.ui_link_quality.total_val -= last_evm;
+ }
+ rtlpriv->stats.ui_link_quality.total_val += pstatus->signalquality;
+ rtlpriv->stats.ui_link_quality.elements[
+ rtlpriv->stats.ui_link_quality.index++] =
+ pstatus->signalquality;
+ if (rtlpriv->stats.ui_link_quality.index >=
+ PHY_LINKQUALITY_SLID_WIN_MAX)
+ rtlpriv->stats.ui_link_quality.index = 0;
+ tmpval = rtlpriv->stats.ui_link_quality.total_val /
+ rtlpriv->stats.ui_link_quality.total_num;
+ rtlpriv->stats.signal_quality = tmpval;
+ rtlpriv->stats.last_sigstrength_inpercent = tmpval;
+ for (n_stream = 0; n_stream < 2; n_stream++) {
+ if (pstatus->rx_mimo_sig_qual[n_stream] != -1) {
+ if (rtlpriv->stats.rx_evm_percentage[n_stream] == 0) {
+ rtlpriv->stats.rx_evm_percentage[n_stream] =
+ pstatus->rx_mimo_sig_qual[n_stream];
+ }
+ rtlpriv->stats.rx_evm_percentage[n_stream] =
+ ((rtlpriv->stats.rx_evm_percentage[n_stream]
+ * (RX_SMOOTH_FACTOR - 1)) +
+ (pstatus->rx_mimo_sig_qual[n_stream] * 1)) /
+ (RX_SMOOTH_FACTOR);
+ }
+ }
+}
+
+void rtl_process_phyinfo(struct ieee80211_hw *hw, u8 *buffer,
+ struct rtl_stats *pstatus)
+{
+ if (!pstatus->packet_matchbssid)
+ return;
+
+ rtl_process_ui_rssi(hw, pstatus);
+ rtl_process_pwdb(hw, pstatus);
+ rtl_process_ui_link_quality(hw, pstatus);
+}
diff --git a/drivers/staging/rtlwifi/stats.h b/drivers/staging/rtlwifi/stats.h
new file mode 100644
index 0000000..bd0108f
--- /dev/null
+++ b/drivers/staging/rtlwifi/stats.h
@@ -0,0 +1,42 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2012 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL_STATS_H__
+#define __RTL_STATS_H__
+
+#define PHY_RSSI_SLID_WIN_MAX 100
+#define PHY_LINKQUALITY_SLID_WIN_MAX 20
+#define PHY_BEACON_RSSI_SLID_WIN_MAX 10
+
+/* Rx smooth factor */
+#define RX_SMOOTH_FACTOR 20
+
+u8 rtl_query_rxpwrpercentage(s8 antpower);
+u8 rtl_evm_db_to_percentage(s8 value);
+long rtl_signal_scale_mapping(struct ieee80211_hw *hw, long currsig);
+void rtl_process_phyinfo(struct ieee80211_hw *hw, u8 *buffer,
+ struct rtl_stats *pstatus);
+
+#endif
diff --git a/drivers/staging/rtlwifi/wifi.h b/drivers/staging/rtlwifi/wifi.h
new file mode 100644
index 0000000..eb91c13
--- /dev/null
+++ b/drivers/staging/rtlwifi/wifi.h
@@ -0,0 +1,3375 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2012 Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL_WIFI_H__
+#define __RTL_WIFI_H__
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/sched.h>
+#include <linux/firmware.h>
+#include <linux/etherdevice.h>
+#include <linux/vmalloc.h>
+#include <linux/usb.h>
+#include <net/mac80211.h>
+#include <linux/completion.h>
+#include "debug.h"
+
+#define MASKBYTE0 0xff
+#define MASKBYTE1 0xff00
+#define MASKBYTE2 0xff0000
+#define MASKBYTE3 0xff000000
+#define MASKHWORD 0xffff0000
+#define MASKLWORD 0x0000ffff
+#define MASKDWORD 0xffffffff
+#define MASK12BITS 0xfff
+#define MASKH4BITS 0xf0000000
+#define MASKOFDM_D 0xffc00000
+#define MASKCCK 0x3f3f3f3f
+
+#define MASK4BITS 0x0f
+#define MASK20BITS 0xfffff
+#define RFREG_OFFSET_MASK 0xfffff
+
+#define MASKBYTE0 0xff
+#define MASKBYTE1 0xff00
+#define MASKBYTE2 0xff0000
+#define MASKBYTE3 0xff000000
+#define MASKHWORD 0xffff0000
+#define MASKLWORD 0x0000ffff
+#define MASKDWORD 0xffffffff
+#define MASK12BITS 0xfff
+#define MASKH4BITS 0xf0000000
+#define MASKOFDM_D 0xffc00000
+#define MASKCCK 0x3f3f3f3f
+
+#define MASK4BITS 0x0f
+#define MASK20BITS 0xfffff
+#define RFREG_OFFSET_MASK 0xfffff
+
+#define RF_CHANGE_BY_INIT 0
+#define RF_CHANGE_BY_IPS BIT(28)
+#define RF_CHANGE_BY_PS BIT(29)
+#define RF_CHANGE_BY_HW BIT(30)
+#define RF_CHANGE_BY_SW BIT(31)
+
+#define IQK_ADDA_REG_NUM 16
+#define IQK_MAC_REG_NUM 4
+#define IQK_THRESHOLD 8
+
+#define MAX_KEY_LEN 61
+#define KEY_BUF_SIZE 5
+
+/* QoS related. */
+/*aci: 0x00 Best Effort*/
+/*aci: 0x01 Background*/
+/*aci: 0x10 Video*/
+/*aci: 0x11 Voice*/
+/*Max: define total number.*/
+#define AC0_BE 0
+#define AC1_BK 1
+#define AC2_VI 2
+#define AC3_VO 3
+#define AC_MAX 4
+#define QOS_QUEUE_NUM 4
+#define RTL_MAC80211_NUM_QUEUE 5
+#define REALTEK_USB_VENQT_MAX_BUF_SIZE 254
+#define RTL_USB_MAX_RX_COUNT 100
+#define QBSS_LOAD_SIZE 5
+#define MAX_WMMELE_LENGTH 64
+
+#define TOTAL_CAM_ENTRY 32
+
+/*slot time for 11g. */
+#define RTL_SLOT_TIME_9 9
+#define RTL_SLOT_TIME_20 20
+
+/*related to tcp/ip. */
+#define SNAP_SIZE 6
+#define PROTOC_TYPE_SIZE 2
+
+/*related with 802.11 frame*/
+#define MAC80211_3ADDR_LEN 24
+#define MAC80211_4ADDR_LEN 30
+
+#define CHANNEL_MAX_NUMBER (14 + 24 + 21) /* 14 is the max channel no */
+#define CHANNEL_MAX_NUMBER_2G 14
+#define CHANNEL_MAX_NUMBER_5G 49 /* Please refer to
+ *"phy_GetChnlGroup8812A" and
+ * "Hal_ReadTxPowerInfo8812A"
+ */
+#define CHANNEL_MAX_NUMBER_5G_80M 7
+#define CHANNEL_GROUP_MAX (3 + 9) /* ch1~3, 4~9, 10~14 = three groups */
+#define MAX_PG_GROUP 13
+#define CHANNEL_GROUP_MAX_2G 3
+#define CHANNEL_GROUP_IDX_5GL 3
+#define CHANNEL_GROUP_IDX_5GM 6
+#define CHANNEL_GROUP_IDX_5GH 9
+#define CHANNEL_GROUP_MAX_5G 9
+#define CHANNEL_MAX_NUMBER_2G 14
+#define AVG_THERMAL_NUM 8
+#define AVG_THERMAL_NUM_88E 4
+#define AVG_THERMAL_NUM_8723BE 4
+#define MAX_TID_COUNT 9
+
+/* for early mode */
+#define FCS_LEN 4
+#define EM_HDR_LEN 8
+
+enum rtl8192c_h2c_cmd {
+ H2C_AP_OFFLOAD = 0,
+ H2C_SETPWRMODE = 1,
+ H2C_JOINBSSRPT = 2,
+ H2C_RSVDPAGE = 3,
+ H2C_RSSI_REPORT = 5,
+ H2C_RA_MASK = 6,
+ H2C_MACID_PS_MODE = 7,
+ H2C_P2P_PS_OFFLOAD = 8,
+ H2C_MAC_MODE_SEL = 9,
+ H2C_PWRM = 15,
+ H2C_P2P_PS_CTW_CMD = 24,
+ MAX_H2CCMD
+};
+
+#define MAX_TX_COUNT 4
+#define MAX_REGULATION_NUM 4
+#define MAX_RF_PATH_NUM 4
+#define MAX_RATE_SECTION_NUM 6 /* = MAX_RATE_SECTION */
+#define MAX_2_4G_BANDWIDTH_NUM 4
+#define MAX_5G_BANDWIDTH_NUM 4
+#define MAX_RF_PATH 4
+#define MAX_CHNL_GROUP_24G 6
+#define MAX_CHNL_GROUP_5G 14
+
+#define TX_PWR_BY_RATE_NUM_BAND 2
+#define TX_PWR_BY_RATE_NUM_RF 4
+#define TX_PWR_BY_RATE_NUM_SECTION 12
+/* compatible with TX_PWR_BY_RATE_NUM_SECTION */
+#define TX_PWR_BY_RATE_NUM_RATE 84
+#define MAX_BASE_NUM_IN_PHY_REG_PG_24G 6 /* MAX_RATE_SECTION */
+#define MAX_BASE_NUM_IN_PHY_REG_PG_5G 5 /* MAX_RATE_SECTION -1 */
+
+#define BUFDESC_SEG_NUM 1 /* 0:2 seg, 1: 4 seg, 2: 8 seg */
+
+#define DEL_SW_IDX_SZ 30
+
+/* For now, it's just for 8192ee
+ * but not OK yet, keep it 0
+ */
+#define RTL8192EE_SEG_NUM BUFDESC_SEG_NUM
+#define RTL8822BE_SEG_NUM BUFDESC_SEG_NUM
+
+enum rf_tx_num {
+ RF_1TX = 0,
+ RF_2TX,
+ RF_MAX_TX_NUM,
+ RF_TX_NUM_NONIMPLEMENT,
+};
+
+#define PACKET_NORMAL 0
+#define PACKET_DHCP 1
+#define PACKET_ARP 2
+#define PACKET_EAPOL 3
+
+#define MAX_SUPPORT_WOL_PATTERN_NUM 16
+#define RSVD_WOL_PATTERN_NUM 1
+#define WKFMCAM_ADDR_NUM 6
+#define WKFMCAM_SIZE 24
+
+#define MAX_WOL_BIT_MASK_SIZE 16
+/* MIN LEN keeps 13 here */
+#define MIN_WOL_PATTERN_SIZE 13
+#define MAX_WOL_PATTERN_SIZE 128
+
+#define WAKE_ON_MAGIC_PACKET BIT(0)
+#define WAKE_ON_PATTERN_MATCH BIT(1)
+
+#define WOL_REASON_PTK_UPDATE BIT(0)
+#define WOL_REASON_GTK_UPDATE BIT(1)
+#define WOL_REASON_DISASSOC BIT(2)
+#define WOL_REASON_DEAUTH BIT(3)
+#define WOL_REASON_AP_LOST BIT(4)
+#define WOL_REASON_MAGIC_PKT BIT(5)
+#define WOL_REASON_UNICAST_PKT BIT(6)
+#define WOL_REASON_PATTERN_PKT BIT(7)
+#define WOL_REASON_RTD3_SSID_MATCH BIT(8)
+#define WOL_REASON_REALWOW_V2_WAKEUPPKT BIT(9)
+#define WOL_REASON_REALWOW_V2_ACKLOST BIT(10)
+
+struct rtlwifi_firmware_header {
+ __le16 signature;
+ u8 category;
+ u8 function;
+ __le16 version;
+ u8 subversion;
+ u8 rsvd1;
+ u8 month;
+ u8 date;
+ u8 hour;
+ u8 minute;
+ __le16 ramcodesize;
+ __le16 rsvd2;
+ __le32 svnindex;
+ __le32 rsvd3;
+ __le32 rsvd4;
+ __le32 rsvd5;
+};
+
+struct txpower_info_2g {
+ u8 index_cck_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G];
+ u8 index_bw40_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G];
+ /*If only one tx, only BW20 and OFDM are used.*/
+ u8 cck_diff[MAX_RF_PATH][MAX_TX_COUNT];
+ u8 ofdm_diff[MAX_RF_PATH][MAX_TX_COUNT];
+ u8 bw20_diff[MAX_RF_PATH][MAX_TX_COUNT];
+ u8 bw40_diff[MAX_RF_PATH][MAX_TX_COUNT];
+ u8 bw80_diff[MAX_RF_PATH][MAX_TX_COUNT];
+ u8 bw160_diff[MAX_RF_PATH][MAX_TX_COUNT];
+};
+
+struct txpower_info_5g {
+ u8 index_bw40_base[MAX_RF_PATH][MAX_CHNL_GROUP_5G];
+ /*If only one tx, only BW20, OFDM, BW80 and BW160 are used.*/
+ u8 ofdm_diff[MAX_RF_PATH][MAX_TX_COUNT];
+ u8 bw20_diff[MAX_RF_PATH][MAX_TX_COUNT];
+ u8 bw40_diff[MAX_RF_PATH][MAX_TX_COUNT];
+ u8 bw80_diff[MAX_RF_PATH][MAX_TX_COUNT];
+ u8 bw160_diff[MAX_RF_PATH][MAX_TX_COUNT];
+};
+
+enum rate_section {
+ CCK = 0,
+ OFDM,
+ HT_MCS0_MCS7,
+ HT_MCS8_MCS15,
+ VHT_1SSMCS0_1SSMCS9,
+ VHT_2SSMCS0_2SSMCS9,
+ MAX_RATE_SECTION,
+};
+
+enum intf_type {
+ INTF_PCI = 0,
+ INTF_USB = 1,
+};
+
+enum radio_path {
+ RF90_PATH_A = 0,
+ RF90_PATH_B = 1,
+ RF90_PATH_C = 2,
+ RF90_PATH_D = 3,
+};
+
+enum radio_mask {
+ RF_MASK_A = BIT(0),
+ RF_MASK_B = BIT(1),
+ RF_MASK_C = BIT(2),
+ RF_MASK_D = BIT(3),
+};
+
+enum regulation_txpwr_lmt {
+ TXPWR_LMT_FCC = 0,
+ TXPWR_LMT_MKK = 1,
+ TXPWR_LMT_ETSI = 2,
+ TXPWR_LMT_WW = 3,
+
+ TXPWR_LMT_MAX_REGULATION_NUM = 4
+};
+
+enum rt_eeprom_type {
+ EEPROM_93C46,
+ EEPROM_93C56,
+ EEPROM_BOOT_EFUSE,
+};
+
+enum ttl_status {
+ RTL_STATUS_INTERFACE_START = 0,
+};
+
+enum hardware_type {
+ HARDWARE_TYPE_RTL8192E,
+ HARDWARE_TYPE_RTL8192U,
+ HARDWARE_TYPE_RTL8192SE,
+ HARDWARE_TYPE_RTL8192SU,
+ HARDWARE_TYPE_RTL8192CE,
+ HARDWARE_TYPE_RTL8192CU,
+ HARDWARE_TYPE_RTL8192DE,
+ HARDWARE_TYPE_RTL8192DU,
+ HARDWARE_TYPE_RTL8723AE,
+ HARDWARE_TYPE_RTL8723U,
+ HARDWARE_TYPE_RTL8188EE,
+ HARDWARE_TYPE_RTL8723BE,
+ HARDWARE_TYPE_RTL8192EE,
+ HARDWARE_TYPE_RTL8821AE,
+ HARDWARE_TYPE_RTL8812AE,
+ HARDWARE_TYPE_RTL8822BE,
+
+ /* keep it last */
+ HARDWARE_TYPE_NUM
+};
+
+#define RTL_HW_TYPE(rtlpriv) (rtl_hal((struct rtl_priv *)rtlpriv)->hw_type)
+#define IS_NEW_GENERATION_IC(rtlpriv) \
+ (RTL_HW_TYPE(rtlpriv) >= HARDWARE_TYPE_RTL8192EE)
+#define IS_HARDWARE_TYPE_8192CE(rtlpriv) \
+ (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8192CE)
+#define IS_HARDWARE_TYPE_8812(rtlpriv) \
+ (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8812AE)
+#define IS_HARDWARE_TYPE_8821(rtlpriv) \
+ (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8821AE)
+#define IS_HARDWARE_TYPE_8723A(rtlpriv) \
+ (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8723AE)
+#define IS_HARDWARE_TYPE_8723B(rtlpriv) \
+ (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8723BE)
+#define IS_HARDWARE_TYPE_8192E(rtlpriv) \
+ (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8192EE)
+#define IS_HARDWARE_TYPE_8822B(rtlpriv) \
+ (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8822BE)
+
+#define RX_HAL_IS_CCK_RATE(rxmcs) \
+ ((rxmcs) == DESC_RATE1M || \
+ (rxmcs) == DESC_RATE2M || \
+ (rxmcs) == DESC_RATE5_5M || \
+ (rxmcs) == DESC_RATE11M)
+
+enum scan_operation_backup_opt {
+ SCAN_OPT_BACKUP = 0,
+ SCAN_OPT_BACKUP_BAND0 = 0,
+ SCAN_OPT_BACKUP_BAND1,
+ SCAN_OPT_RESTORE,
+ SCAN_OPT_MAX
+};
+
+/*RF state.*/
+enum rf_pwrstate {
+ ERFON,
+ ERFSLEEP,
+ ERFOFF
+};
+
+struct bb_reg_def {
+ u32 rfintfs;
+ u32 rfintfi;
+ u32 rfintfo;
+ u32 rfintfe;
+ u32 rf3wire_offset;
+ u32 rflssi_select;
+ u32 rftxgain_stage;
+ u32 rfhssi_para1;
+ u32 rfhssi_para2;
+ u32 rfsw_ctrl;
+ u32 rfagc_control1;
+ u32 rfagc_control2;
+ u32 rfrxiq_imbal;
+ u32 rfrx_afe;
+ u32 rftxiq_imbal;
+ u32 rftx_afe;
+ u32 rf_rb; /* rflssi_readback */
+ u32 rf_rbpi; /* rflssi_readbackpi */
+};
+
+enum io_type {
+ IO_CMD_PAUSE_DM_BY_SCAN = 0,
+ IO_CMD_PAUSE_BAND0_DM_BY_SCAN = 0,
+ IO_CMD_PAUSE_BAND1_DM_BY_SCAN = 1,
+ IO_CMD_RESUME_DM_BY_SCAN = 2,
+};
+
+enum hw_variables {
+ HW_VAR_ETHER_ADDR = 0x0,
+ HW_VAR_MULTICAST_REG = 0x1,
+ HW_VAR_BASIC_RATE = 0x2,
+ HW_VAR_BSSID = 0x3,
+ HW_VAR_MEDIA_STATUS = 0x4,
+ HW_VAR_SECURITY_CONF = 0x5,
+ HW_VAR_BEACON_INTERVAL = 0x6,
+ HW_VAR_ATIM_WINDOW = 0x7,
+ HW_VAR_LISTEN_INTERVAL = 0x8,
+ HW_VAR_CS_COUNTER = 0x9,
+ HW_VAR_DEFAULTKEY0 = 0xa,
+ HW_VAR_DEFAULTKEY1 = 0xb,
+ HW_VAR_DEFAULTKEY2 = 0xc,
+ HW_VAR_DEFAULTKEY3 = 0xd,
+ HW_VAR_SIFS = 0xe,
+ HW_VAR_R2T_SIFS = 0xf,
+ HW_VAR_DIFS = 0x10,
+ HW_VAR_EIFS = 0x11,
+ HW_VAR_SLOT_TIME = 0x12,
+ HW_VAR_ACK_PREAMBLE = 0x13,
+ HW_VAR_CW_CONFIG = 0x14,
+ HW_VAR_CW_VALUES = 0x15,
+ HW_VAR_RATE_FALLBACK_CONTROL = 0x16,
+ HW_VAR_CONTENTION_WINDOW = 0x17,
+ HW_VAR_RETRY_COUNT = 0x18,
+ HW_VAR_TR_SWITCH = 0x19,
+ HW_VAR_COMMAND = 0x1a,
+ HW_VAR_WPA_CONFIG = 0x1b,
+ HW_VAR_AMPDU_MIN_SPACE = 0x1c,
+ HW_VAR_SHORTGI_DENSITY = 0x1d,
+ HW_VAR_AMPDU_FACTOR = 0x1e,
+ HW_VAR_MCS_RATE_AVAILABLE = 0x1f,
+ HW_VAR_AC_PARAM = 0x20,
+ HW_VAR_ACM_CTRL = 0x21,
+ HW_VAR_DIS_REQ_QSIZE = 0x22,
+ HW_VAR_CCX_CHNL_LOAD = 0x23,
+ HW_VAR_CCX_NOISE_HISTOGRAM = 0x24,
+ HW_VAR_CCX_CLM_NHM = 0x25,
+ HW_VAR_TXOPLIMIT = 0x26,
+ HW_VAR_TURBO_MODE = 0x27,
+ HW_VAR_RF_STATE = 0x28,
+ HW_VAR_RF_OFF_BY_HW = 0x29,
+ HW_VAR_BUS_SPEED = 0x2a,
+ HW_VAR_SET_DEV_POWER = 0x2b,
+
+ HW_VAR_RCR = 0x2c,
+ HW_VAR_RATR_0 = 0x2d,
+ HW_VAR_RRSR = 0x2e,
+ HW_VAR_CPU_RST = 0x2f,
+ HW_VAR_CHECK_BSSID = 0x30,
+ HW_VAR_LBK_MODE = 0x31,
+ HW_VAR_AES_11N_FIX = 0x32,
+ HW_VAR_USB_RX_AGGR = 0x33,
+ HW_VAR_USER_CONTROL_TURBO_MODE = 0x34,
+ HW_VAR_RETRY_LIMIT = 0x35,
+ HW_VAR_INIT_TX_RATE = 0x36,
+ HW_VAR_TX_RATE_REG = 0x37,
+ HW_VAR_EFUSE_USAGE = 0x38,
+ HW_VAR_EFUSE_BYTES = 0x39,
+ HW_VAR_AUTOLOAD_STATUS = 0x3a,
+ HW_VAR_RF_2R_DISABLE = 0x3b,
+ HW_VAR_SET_RPWM = 0x3c,
+ HW_VAR_H2C_FW_PWRMODE = 0x3d,
+ HW_VAR_H2C_FW_JOINBSSRPT = 0x3e,
+ HW_VAR_H2C_FW_MEDIASTATUSRPT = 0x3f,
+ HW_VAR_H2C_FW_P2P_PS_OFFLOAD = 0x40,
+ HW_VAR_FW_PSMODE_STATUS = 0x41,
+ HW_VAR_INIT_RTS_RATE = 0x42,
+ HW_VAR_RESUME_CLK_ON = 0x43,
+ HW_VAR_FW_LPS_ACTION = 0x44,
+ HW_VAR_1X1_RECV_COMBINE = 0x45,
+ HW_VAR_STOP_SEND_BEACON = 0x46,
+ HW_VAR_TSF_TIMER = 0x47,
+ HW_VAR_IO_CMD = 0x48,
+
+ HW_VAR_RF_RECOVERY = 0x49,
+ HW_VAR_H2C_FW_UPDATE_GTK = 0x4a,
+ HW_VAR_WF_MASK = 0x4b,
+ HW_VAR_WF_CRC = 0x4c,
+ HW_VAR_WF_IS_MAC_ADDR = 0x4d,
+ HW_VAR_H2C_FW_OFFLOAD = 0x4e,
+ HW_VAR_RESET_WFCRC = 0x4f,
+
+ HW_VAR_HANDLE_FW_C2H = 0x50,
+ HW_VAR_DL_FW_RSVD_PAGE = 0x51,
+ HW_VAR_AID = 0x52,
+ HW_VAR_HW_SEQ_ENABLE = 0x53,
+ HW_VAR_CORRECT_TSF = 0x54,
+ HW_VAR_BCN_VALID = 0x55,
+ HW_VAR_FWLPS_RF_ON = 0x56,
+ HW_VAR_DUAL_TSF_RST = 0x57,
+ HW_VAR_SWITCH_EPHY_WOWLAN = 0x58,
+ HW_VAR_INT_MIGRATION = 0x59,
+ HW_VAR_INT_AC = 0x5a,
+ HW_VAR_RF_TIMING = 0x5b,
+
+ HAL_DEF_WOWLAN = 0x5c,
+ HW_VAR_MRC = 0x5d,
+ HW_VAR_KEEP_ALIVE = 0x5e,
+ HW_VAR_NAV_UPPER = 0x5f,
+
+ HW_VAR_MGT_FILTER = 0x60,
+ HW_VAR_CTRL_FILTER = 0x61,
+ HW_VAR_DATA_FILTER = 0x62,
+};
+
+enum rt_media_status {
+ RT_MEDIA_DISCONNECT = 0,
+ RT_MEDIA_CONNECT = 1
+};
+
+enum rt_oem_id {
+ RT_CID_DEFAULT = 0,
+ RT_CID_8187_ALPHA0 = 1,
+ RT_CID_8187_SERCOMM_PS = 2,
+ RT_CID_8187_HW_LED = 3,
+ RT_CID_8187_NETGEAR = 4,
+ RT_CID_WHQL = 5,
+ RT_CID_819X_CAMEO = 6,
+ RT_CID_819X_RUNTOP = 7,
+ RT_CID_819X_SENAO = 8,
+ RT_CID_TOSHIBA = 9,
+ RT_CID_819X_NETCORE = 10,
+ RT_CID_NETTRONIX = 11,
+ RT_CID_DLINK = 12,
+ RT_CID_PRONET = 13,
+ RT_CID_COREGA = 14,
+ RT_CID_819X_ALPHA = 15,
+ RT_CID_819X_SITECOM = 16,
+ RT_CID_CCX = 17,
+ RT_CID_819X_LENOVO = 18,
+ RT_CID_819X_QMI = 19,
+ RT_CID_819X_EDIMAX_BELKIN = 20,
+ RT_CID_819X_SERCOMM_BELKIN = 21,
+ RT_CID_819X_CAMEO1 = 22,
+ RT_CID_819X_MSI = 23,
+ RT_CID_819X_ACER = 24,
+ RT_CID_819X_HP = 27,
+ RT_CID_819X_CLEVO = 28,
+ RT_CID_819X_ARCADYAN_BELKIN = 29,
+ RT_CID_819X_SAMSUNG = 30,
+ RT_CID_819X_WNC_COREGA = 31,
+ RT_CID_819X_FOXCOON = 32,
+ RT_CID_819X_DELL = 33,
+ RT_CID_819X_PRONETS = 34,
+ RT_CID_819X_EDIMAX_ASUS = 35,
+ RT_CID_NETGEAR = 36,
+ RT_CID_PLANEX = 37,
+ RT_CID_CC_C = 38,
+};
+
+enum hw_descs {
+ HW_DESC_OWN,
+ HW_DESC_RXOWN,
+ HW_DESC_TX_NEXTDESC_ADDR,
+ HW_DESC_TXBUFF_ADDR,
+ HW_DESC_RXBUFF_ADDR,
+ HW_DESC_RXPKT_LEN,
+ HW_DESC_RXERO,
+ HW_DESC_RX_PREPARE,
+};
+
+enum prime_sc {
+ PRIME_CHNL_OFFSET_DONT_CARE = 0,
+ PRIME_CHNL_OFFSET_LOWER = 1,
+ PRIME_CHNL_OFFSET_UPPER = 2,
+};
+
+enum rf_type {
+ RF_1T1R = 0,
+ RF_1T2R = 1,
+ RF_2T2R = 2,
+ RF_2T2R_GREEN = 3,
+ RF_2T3R = 4,
+ RF_2T4R = 5,
+ RF_3T3R = 6,
+ RF_3T4R = 7,
+ RF_4T4R = 8,
+};
+
+enum ht_channel_width {
+ HT_CHANNEL_WIDTH_20 = 0,
+ HT_CHANNEL_WIDTH_20_40 = 1,
+ HT_CHANNEL_WIDTH_80 = 2,
+ HT_CHANNEL_WIDTH_MAX,
+};
+
+/* Ref: 802.11i spec D10.0 7.3.2.25.1
+ * Cipher Suites Encryption Algorithms
+ */
+enum rt_enc_alg {
+ NO_ENCRYPTION = 0,
+ WEP40_ENCRYPTION = 1,
+ TKIP_ENCRYPTION = 2,
+ RSERVED_ENCRYPTION = 3,
+ AESCCMP_ENCRYPTION = 4,
+ WEP104_ENCRYPTION = 5,
+ AESCMAC_ENCRYPTION = 6, /*IEEE802.11w */
+};
+
+enum rtl_hal_state {
+ _HAL_STATE_STOP = 0,
+ _HAL_STATE_START = 1,
+};
+
+enum rtl_desc_rate {
+ DESC_RATE1M = 0x00,
+ DESC_RATE2M = 0x01,
+ DESC_RATE5_5M = 0x02,
+ DESC_RATE11M = 0x03,
+
+ DESC_RATE6M = 0x04,
+ DESC_RATE9M = 0x05,
+ DESC_RATE12M = 0x06,
+ DESC_RATE18M = 0x07,
+ DESC_RATE24M = 0x08,
+ DESC_RATE36M = 0x09,
+ DESC_RATE48M = 0x0a,
+ DESC_RATE54M = 0x0b,
+
+ DESC_RATEMCS0 = 0x0c,
+ DESC_RATEMCS1 = 0x0d,
+ DESC_RATEMCS2 = 0x0e,
+ DESC_RATEMCS3 = 0x0f,
+ DESC_RATEMCS4 = 0x10,
+ DESC_RATEMCS5 = 0x11,
+ DESC_RATEMCS6 = 0x12,
+ DESC_RATEMCS7 = 0x13,
+ DESC_RATEMCS8 = 0x14,
+ DESC_RATEMCS9 = 0x15,
+ DESC_RATEMCS10 = 0x16,
+ DESC_RATEMCS11 = 0x17,
+ DESC_RATEMCS12 = 0x18,
+ DESC_RATEMCS13 = 0x19,
+ DESC_RATEMCS14 = 0x1a,
+ DESC_RATEMCS15 = 0x1b,
+ DESC_RATEMCS15_SG = 0x1c,
+ DESC_RATEMCS32 = 0x20,
+
+ DESC_RATEVHT1SS_MCS0 = 0x2c,
+ DESC_RATEVHT1SS_MCS1 = 0x2d,
+ DESC_RATEVHT1SS_MCS2 = 0x2e,
+ DESC_RATEVHT1SS_MCS3 = 0x2f,
+ DESC_RATEVHT1SS_MCS4 = 0x30,
+ DESC_RATEVHT1SS_MCS5 = 0x31,
+ DESC_RATEVHT1SS_MCS6 = 0x32,
+ DESC_RATEVHT1SS_MCS7 = 0x33,
+ DESC_RATEVHT1SS_MCS8 = 0x34,
+ DESC_RATEVHT1SS_MCS9 = 0x35,
+ DESC_RATEVHT2SS_MCS0 = 0x36,
+ DESC_RATEVHT2SS_MCS1 = 0x37,
+ DESC_RATEVHT2SS_MCS2 = 0x38,
+ DESC_RATEVHT2SS_MCS3 = 0x39,
+ DESC_RATEVHT2SS_MCS4 = 0x3a,
+ DESC_RATEVHT2SS_MCS5 = 0x3b,
+ DESC_RATEVHT2SS_MCS6 = 0x3c,
+ DESC_RATEVHT2SS_MCS7 = 0x3d,
+ DESC_RATEVHT2SS_MCS8 = 0x3e,
+ DESC_RATEVHT2SS_MCS9 = 0x3f,
+};
+
+enum rtl_var_map {
+ /*reg map */
+ SYS_ISO_CTRL = 0,
+ SYS_FUNC_EN,
+ SYS_CLK,
+ MAC_RCR_AM,
+ MAC_RCR_AB,
+ MAC_RCR_ACRC32,
+ MAC_RCR_ACF,
+ MAC_RCR_AAP,
+ MAC_HIMR,
+ MAC_HIMRE,
+ MAC_HSISR,
+
+ /*efuse map */
+ EFUSE_TEST,
+ EFUSE_CTRL,
+ EFUSE_CLK,
+ EFUSE_CLK_CTRL,
+ EFUSE_PWC_EV12V,
+ EFUSE_FEN_ELDR,
+ EFUSE_LOADER_CLK_EN,
+ EFUSE_ANA8M,
+ EFUSE_HWSET_MAX_SIZE,
+ EFUSE_MAX_SECTION_MAP,
+ EFUSE_REAL_CONTENT_SIZE,
+ EFUSE_OOB_PROTECT_BYTES_LEN,
+ EFUSE_ACCESS,
+
+ /*CAM map */
+ RWCAM,
+ WCAMI,
+ RCAMO,
+ CAMDBG,
+ SECR,
+ SEC_CAM_NONE,
+ SEC_CAM_WEP40,
+ SEC_CAM_TKIP,
+ SEC_CAM_AES,
+ SEC_CAM_WEP104,
+
+ /*IMR map */
+ RTL_IMR_BCNDMAINT6, /*Beacon DMA Interrupt 6 */
+ RTL_IMR_BCNDMAINT5, /*Beacon DMA Interrupt 5 */
+ RTL_IMR_BCNDMAINT4, /*Beacon DMA Interrupt 4 */
+ RTL_IMR_BCNDMAINT3, /*Beacon DMA Interrupt 3 */
+ RTL_IMR_BCNDMAINT2, /*Beacon DMA Interrupt 2 */
+ RTL_IMR_BCNDMAINT1, /*Beacon DMA Interrupt 1 */
+ RTL_IMR_BCNDOK8, /*Beacon Queue DMA OK Interrupt 8 */
+ RTL_IMR_BCNDOK7, /*Beacon Queue DMA OK Interrupt 7 */
+ RTL_IMR_BCNDOK6, /*Beacon Queue DMA OK Interrupt 6 */
+ RTL_IMR_BCNDOK5, /*Beacon Queue DMA OK Interrupt 5 */
+ RTL_IMR_BCNDOK4, /*Beacon Queue DMA OK Interrupt 4 */
+ RTL_IMR_BCNDOK3, /*Beacon Queue DMA OK Interrupt 3 */
+ RTL_IMR_BCNDOK2, /*Beacon Queue DMA OK Interrupt 2 */
+ RTL_IMR_BCNDOK1, /*Beacon Queue DMA OK Interrupt 1 */
+ RTL_IMR_TIMEOUT2, /*Timeout interrupt 2 */
+ RTL_IMR_TIMEOUT1, /*Timeout interrupt 1 */
+ RTL_IMR_TXFOVW, /*Transmit FIFO Overflow */
+ RTL_IMR_PSTIMEOUT, /*Power save time out interrupt */
+ RTL_IMR_BCNINT, /*Beacon DMA Interrupt 0 */
+ RTL_IMR_RXFOVW, /*Receive FIFO Overflow */
+ RTL_IMR_RDU, /*Receive Descriptor Unavailable */
+ RTL_IMR_ATIMEND, /*For 92C,ATIM Window End Interrupt */
+ RTL_IMR_H2CDOK, /*H2C Queue DMA OK Interrupt */
+ RTL_IMR_BDOK, /*Beacon Queue DMA OK Interrupt */
+ RTL_IMR_HIGHDOK, /*High Queue DMA OK Interrupt */
+ RTL_IMR_COMDOK, /*Command Queue DMA OK Interrupt*/
+ RTL_IMR_TBDOK, /*Transmit Beacon OK interrupt */
+ RTL_IMR_MGNTDOK, /*Management Queue DMA OK Interrupt */
+ RTL_IMR_TBDER, /*For 92C,Transmit Beacon Error Interrupt */
+ RTL_IMR_BKDOK, /*AC_BK DMA OK Interrupt */
+ RTL_IMR_BEDOK, /*AC_BE DMA OK Interrupt */
+ RTL_IMR_VIDOK, /*AC_VI DMA OK Interrupt */
+ RTL_IMR_VODOK, /*AC_VO DMA Interrupt */
+ RTL_IMR_ROK, /*Receive DMA OK Interrupt */
+ RTL_IMR_HSISR_IND, /*HSISR Interrupt*/
+ RTL_IBSS_INT_MASKS, /*(RTL_IMR_BCNINT | RTL_IMR_TBDOK |
+ * RTL_IMR_TBDER)
+ */
+ RTL_IMR_C2HCMD, /*fw interrupt*/
+
+ /*CCK Rates, TxHT = 0 */
+ RTL_RC_CCK_RATE1M,
+ RTL_RC_CCK_RATE2M,
+ RTL_RC_CCK_RATE5_5M,
+ RTL_RC_CCK_RATE11M,
+
+ /*OFDM Rates, TxHT = 0 */
+ RTL_RC_OFDM_RATE6M,
+ RTL_RC_OFDM_RATE9M,
+ RTL_RC_OFDM_RATE12M,
+ RTL_RC_OFDM_RATE18M,
+ RTL_RC_OFDM_RATE24M,
+ RTL_RC_OFDM_RATE36M,
+ RTL_RC_OFDM_RATE48M,
+ RTL_RC_OFDM_RATE54M,
+
+ RTL_RC_HT_RATEMCS7,
+ RTL_RC_HT_RATEMCS15,
+
+ RTL_RC_VHT_RATE_1SS_MCS7,
+ RTL_RC_VHT_RATE_1SS_MCS8,
+ RTL_RC_VHT_RATE_1SS_MCS9,
+ RTL_RC_VHT_RATE_2SS_MCS7,
+ RTL_RC_VHT_RATE_2SS_MCS8,
+ RTL_RC_VHT_RATE_2SS_MCS9,
+
+ /*keep it last */
+ RTL_VAR_MAP_MAX,
+};
+
+/*Firmware PS mode for control LPS.*/
+enum _fw_ps_mode {
+ FW_PS_ACTIVE_MODE = 0,
+ FW_PS_MIN_MODE = 1,
+ FW_PS_MAX_MODE = 2,
+ FW_PS_DTIM_MODE = 3,
+ FW_PS_VOIP_MODE = 4,
+ FW_PS_UAPSD_WMM_MODE = 5,
+ FW_PS_UAPSD_MODE = 6,
+ FW_PS_IBSS_MODE = 7,
+ FW_PS_WWLAN_MODE = 8,
+ FW_PS_PM_RADIO_OFF = 9,
+ FW_PS_PM_CARD_DISABLE = 10,
+};
+
+enum rt_psmode {
+ EACTIVE, /*Active/Continuous access. */
+ EMAXPS, /*Max power save mode. */
+ EFASTPS, /*Fast power save mode. */
+ EAUTOPS, /*Auto power save mode. */
+};
+
+/*LED related.*/
+enum led_ctl_mode {
+ LED_CTL_POWER_ON = 1,
+ LED_CTL_LINK = 2,
+ LED_CTL_NO_LINK = 3,
+ LED_CTL_TX = 4,
+ LED_CTL_RX = 5,
+ LED_CTL_SITE_SURVEY = 6,
+ LED_CTL_POWER_OFF = 7,
+ LED_CTL_START_TO_LINK = 8,
+ LED_CTL_START_WPS = 9,
+ LED_CTL_STOP_WPS = 10,
+};
+
+enum rtl_led_pin {
+ LED_PIN_GPIO0,
+ LED_PIN_LED0,
+ LED_PIN_LED1,
+ LED_PIN_LED2
+};
+
+/* QoS related.*/
+/* acm implementation method.*/
+enum acm_method {
+ EACMWAY0_SWANDHW = 0,
+ EACMWAY1_HW = 1,
+ EACMWAY2_SW = 2,
+};
+
+enum macphy_mode {
+ SINGLEMAC_SINGLEPHY = 0,
+ DUALMAC_DUALPHY,
+ DUALMAC_SINGLEPHY,
+};
+
+enum band_type {
+ BAND_ON_2_4G = 0,
+ BAND_ON_5G,
+ BAND_ON_BOTH,
+ BANDMAX
+};
+
+/* aci/aifsn Field.
+ * Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
+ */
+union aci_aifsn {
+ u8 char_data;
+
+ struct {
+ u8 aifsn:4;
+ u8 acm:1;
+ u8 aci:2;
+ u8 reserved:1;
+ } f; /* Field */
+};
+
+/*mlme related.*/
+enum wireless_mode {
+ WIRELESS_MODE_UNKNOWN = 0x00,
+ WIRELESS_MODE_A = 0x01,
+ WIRELESS_MODE_B = 0x02,
+ WIRELESS_MODE_G = 0x04,
+ WIRELESS_MODE_AUTO = 0x08,
+ WIRELESS_MODE_N_24G = 0x10,
+ WIRELESS_MODE_N_5G = 0x20,
+ WIRELESS_MODE_AC_5G = 0x40,
+ WIRELESS_MODE_AC_24G = 0x80,
+ WIRELESS_MODE_AC_ONLY = 0x100,
+ WIRELESS_MODE_MAX = 0x800
+};
+
+#define IS_WIRELESS_MODE_A(wirelessmode) \
+ (wirelessmode == WIRELESS_MODE_A)
+#define IS_WIRELESS_MODE_B(wirelessmode) \
+ (wirelessmode == WIRELESS_MODE_B)
+#define IS_WIRELESS_MODE_G(wirelessmode) \
+ (wirelessmode == WIRELESS_MODE_G)
+#define IS_WIRELESS_MODE_N_24G(wirelessmode) \
+ (wirelessmode == WIRELESS_MODE_N_24G)
+#define IS_WIRELESS_MODE_N_5G(wirelessmode) \
+ (wirelessmode == WIRELESS_MODE_N_5G)
+
+enum ratr_table_mode {
+ RATR_INX_WIRELESS_NGB = 0,
+ RATR_INX_WIRELESS_NG = 1,
+ RATR_INX_WIRELESS_NB = 2,
+ RATR_INX_WIRELESS_N = 3,
+ RATR_INX_WIRELESS_GB = 4,
+ RATR_INX_WIRELESS_G = 5,
+ RATR_INX_WIRELESS_B = 6,
+ RATR_INX_WIRELESS_MC = 7,
+ RATR_INX_WIRELESS_A = 8,
+ RATR_INX_WIRELESS_AC_5N = 8,
+ RATR_INX_WIRELESS_AC_24N = 9,
+};
+
+enum ratr_table_mode_new {
+ RATEID_IDX_BGN_40M_2SS = 0,
+ RATEID_IDX_BGN_40M_1SS = 1,
+ RATEID_IDX_BGN_20M_2SS_BN = 2,
+ RATEID_IDX_BGN_20M_1SS_BN = 3,
+ RATEID_IDX_GN_N2SS = 4,
+ RATEID_IDX_GN_N1SS = 5,
+ RATEID_IDX_BG = 6,
+ RATEID_IDX_G = 7,
+ RATEID_IDX_B = 8,
+ RATEID_IDX_VHT_2SS = 9,
+ RATEID_IDX_VHT_1SS = 10,
+ RATEID_IDX_MIX1 = 11,
+ RATEID_IDX_MIX2 = 12,
+ RATEID_IDX_VHT_3SS = 13,
+ RATEID_IDX_BGN_3SS = 14,
+};
+
+enum rtl_link_state {
+ MAC80211_NOLINK = 0,
+ MAC80211_LINKING = 1,
+ MAC80211_LINKED = 2,
+ MAC80211_LINKED_SCANNING = 3,
+};
+
+enum act_category {
+ ACT_CAT_QOS = 1,
+ ACT_CAT_DLS = 2,
+ ACT_CAT_BA = 3,
+ ACT_CAT_HT = 7,
+ ACT_CAT_WMM = 17,
+};
+
+enum ba_action {
+ ACT_ADDBAREQ = 0,
+ ACT_ADDBARSP = 1,
+ ACT_DELBA = 2,
+};
+
+enum rt_polarity_ctl {
+ RT_POLARITY_LOW_ACT = 0,
+ RT_POLARITY_HIGH_ACT = 1,
+};
+
+/* After 8188E, we use V2 reason define. 88C/8723A use V1 reason. */
+enum fw_wow_reason_v2 {
+ FW_WOW_V2_PTK_UPDATE_EVENT = 0x01,
+ FW_WOW_V2_GTK_UPDATE_EVENT = 0x02,
+ FW_WOW_V2_DISASSOC_EVENT = 0x04,
+ FW_WOW_V2_DEAUTH_EVENT = 0x08,
+ FW_WOW_V2_FW_DISCONNECT_EVENT = 0x10,
+ FW_WOW_V2_MAGIC_PKT_EVENT = 0x21,
+ FW_WOW_V2_UNICAST_PKT_EVENT = 0x22,
+ FW_WOW_V2_PATTERN_PKT_EVENT = 0x23,
+ FW_WOW_V2_RTD3_SSID_MATCH_EVENT = 0x24,
+ FW_WOW_V2_REALWOW_V2_WAKEUPPKT = 0x30,
+ FW_WOW_V2_REALWOW_V2_ACKLOST = 0x31,
+ FW_WOW_V2_REASON_MAX = 0xff,
+};
+
+enum wolpattern_type {
+ UNICAST_PATTERN = 0,
+ MULTICAST_PATTERN = 1,
+ BROADCAST_PATTERN = 2,
+ DONT_CARE_DA = 3,
+ UNKNOWN_TYPE = 4,
+};
+
+enum package_type {
+ PACKAGE_DEFAULT,
+ PACKAGE_QFN68,
+ PACKAGE_TFBGA90,
+ PACKAGE_TFBGA80,
+ PACKAGE_TFBGA79
+};
+
+enum rtl_spec_ver {
+ RTL_SPEC_NEW_RATEID = BIT(0), /* use ratr_table_mode_new */
+ RTL_SPEC_SUPPORT_VHT = BIT(1), /* support VHT */
+ RTL_SPEC_NEW_FW_C2H = BIT(2), /* new FW C2H (e.g. TX REPORT) */
+};
+
+struct octet_string {
+ u8 *octet;
+ u16 length;
+};
+
+struct rtl_hdr_3addr {
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 addr3[ETH_ALEN];
+ __le16 seq_ctl;
+ u8 payload[0];
+} __packed;
+
+struct rtl_info_element {
+ u8 id;
+ u8 len;
+ u8 data[0];
+} __packed;
+
+struct rtl_probe_rsp {
+ struct rtl_hdr_3addr header;
+ u32 time_stamp[2];
+ __le16 beacon_interval;
+ __le16 capability;
+ /* SSID, supported rates, FH params, DS params,
+ * CF params, IBSS params, TIM (if beacon), RSN
+ */
+ struct rtl_info_element info_element[0];
+} __packed;
+
+struct rtl_beacon_keys {
+ /*u8 ssid[32];*/
+ /*u32 ssid_len;*/
+ u8 bcn_channel;
+ __le16 ht_cap_info;
+ u8 ht_info_infos_0_sco; /* bit0 & bit1 in infos[0] is 2nd ch offset */
+ bool valid;
+};
+
+/*LED related.*/
+/*ledpin Identify how to implement this SW led.*/
+struct rtl_led {
+ void *hw;
+ enum rtl_led_pin ledpin;
+ bool ledon;
+};
+
+struct rtl_led_ctl {
+ bool led_opendrain;
+ struct rtl_led sw_led0;
+ struct rtl_led sw_led1;
+};
+
+struct rtl_qos_parameters {
+ __le16 cw_min;
+ __le16 cw_max;
+ u8 aifs;
+ u8 flag;
+ __le16 tx_op;
+} __packed;
+
+struct rt_smooth_data {
+ u32 elements[100]; /*array to store values */
+ u32 index; /*index to current array to store */
+ u32 total_num; /*num of valid elements */
+ u32 total_val; /*sum of valid elements */
+};
+
+struct false_alarm_statistics {
+ u32 cnt_parity_fail;
+ u32 cnt_rate_illegal;
+ u32 cnt_crc8_fail;
+ u32 cnt_mcs_fail;
+ u32 cnt_fast_fsync_fail;
+ u32 cnt_sb_search_fail;
+ u32 cnt_ofdm_fail;
+ u32 cnt_cck_fail;
+ u32 cnt_all;
+ u32 cnt_ofdm_cca;
+ u32 cnt_cck_cca;
+ u32 cnt_cca_all;
+ u32 cnt_bw_usc;
+ u32 cnt_bw_lsc;
+};
+
+struct init_gain {
+ u8 xaagccore1;
+ u8 xbagccore1;
+ u8 xcagccore1;
+ u8 xdagccore1;
+ u8 cca;
+
+};
+
+struct wireless_stats {
+ u64 txbytesunicast;
+ u64 txbytesmulticast;
+ u64 txbytesbroadcast;
+ u64 rxbytesunicast;
+
+ u64 txbytesunicast_inperiod;
+ u64 rxbytesunicast_inperiod;
+ u32 txbytesunicast_inperiod_tp;
+ u32 rxbytesunicast_inperiod_tp;
+ u64 txbytesunicast_last;
+ u64 rxbytesunicast_last;
+
+ long rx_snr_db[4];
+ /* Correct smoothed ss in Dbm, only used
+ * in driver to report real power now.
+ */
+ long recv_signal_power;
+ long signal_quality;
+ long last_sigstrength_inpercent;
+
+ u32 rssi_calculate_cnt;
+ u32 pwdb_all_cnt;
+
+ /* Transformed, in dbm. Beautified signal
+ * strength for UI, not correct.
+ */
+ long signal_strength;
+
+ u8 rx_rssi_percentage[4];
+ u8 rx_evm_dbm[4];
+ u8 rx_evm_percentage[2];
+
+ u16 rx_cfo_short[4];
+ u16 rx_cfo_tail[4];
+
+ struct rt_smooth_data ui_rssi;
+ struct rt_smooth_data ui_link_quality;
+};
+
+struct rate_adaptive {
+ u8 rate_adaptive_disabled;
+ u8 ratr_state;
+ u16 reserve;
+
+ u32 high_rssi_thresh_for_ra;
+ u32 high2low_rssi_thresh_for_ra;
+ u8 low2high_rssi_thresh_for_ra40m;
+ u32 low_rssi_thresh_for_ra40m;
+ u8 low2high_rssi_thresh_for_ra20m;
+ u32 low_rssi_thresh_for_ra20m;
+ u32 upper_rssi_threshold_ratr;
+ u32 middleupper_rssi_threshold_ratr;
+ u32 middle_rssi_threshold_ratr;
+ u32 middlelow_rssi_threshold_ratr;
+ u32 low_rssi_threshold_ratr;
+ u32 ultralow_rssi_threshold_ratr;
+ u32 low_rssi_threshold_ratr_40m;
+ u32 low_rssi_threshold_ratr_20m;
+ u8 ping_rssi_enable;
+ u32 ping_rssi_ratr;
+ u32 ping_rssi_thresh_for_ra;
+ u32 last_ratr;
+ u8 pre_ratr_state;
+ u8 ldpc_thres;
+ bool use_ldpc;
+ bool lower_rts_rate;
+ bool is_special_data;
+};
+
+struct regd_pair_mapping {
+ u16 reg_dmnenum;
+ u16 reg_5ghz_ctl;
+ u16 reg_2ghz_ctl;
+};
+
+struct dynamic_primary_cca {
+ u8 pricca_flag;
+ u8 intf_flag;
+ u8 intf_type;
+ u8 dup_rts_flag;
+ u8 monitor_flag;
+ u8 ch_offset;
+ u8 mf_state;
+};
+
+struct rtl_regulatory {
+ s8 alpha2[2];
+ u16 country_code;
+ u16 max_power_level;
+ u32 tp_scale;
+ u16 current_rd;
+ u16 current_rd_ext;
+ s16 power_limit;
+ struct regd_pair_mapping *regpair;
+};
+
+struct rtl_rfkill {
+ bool rfkill_state; /*0 is off, 1 is on */
+};
+
+/*for P2P PS**/
+#define P2P_MAX_NOA_NUM 2
+
+enum p2p_role {
+ P2P_ROLE_DISABLE = 0,
+ P2P_ROLE_DEVICE = 1,
+ P2P_ROLE_CLIENT = 2,
+ P2P_ROLE_GO = 3
+};
+
+enum p2p_ps_state {
+ P2P_PS_DISABLE = 0,
+ P2P_PS_ENABLE = 1,
+ P2P_PS_SCAN = 2,
+ P2P_PS_SCAN_DONE = 3,
+ P2P_PS_ALLSTASLEEP = 4, /* for P2P GO */
+};
+
+enum p2p_ps_mode {
+ P2P_PS_NONE = 0,
+ P2P_PS_CTWINDOW = 1,
+ P2P_PS_NOA = 2,
+ P2P_PS_MIX = 3, /* CTWindow and NoA */
+};
+
+struct rtl_p2p_ps_info {
+ enum p2p_ps_mode p2p_ps_mode; /* indicate p2p ps mode */
+ enum p2p_ps_state p2p_ps_state; /* indicate p2p ps state */
+ u8 noa_index; /* Identifies instance of Notice of Absence timing. */
+ /* Client traffic window. A period of time in TU after TBTT. */
+ u8 ctwindow;
+ u8 opp_ps; /* opportunistic power save. */
+ u8 noa_num; /* number of NoA descriptor in P2P IE. */
+ /* Count for owner, Type of client. */
+ u8 noa_count_type[P2P_MAX_NOA_NUM];
+ /* Max duration for owner, preferred or min acceptable duration
+ * for client.
+ */
+ u32 noa_duration[P2P_MAX_NOA_NUM];
+ /* Length of interval for owner, preferred or max acceptable intervali
+ * of client.
+ */
+ u32 noa_interval[P2P_MAX_NOA_NUM];
+ /* schedule in terms of the lower 4 bytes of the TSF timer. */
+ u32 noa_start_time[P2P_MAX_NOA_NUM];
+};
+
+struct p2p_ps_offload_t {
+ u8 offload_en:1;
+ u8 role:1; /* 1: Owner, 0: Client */
+ u8 ctwindow_en:1;
+ u8 noa0_en:1;
+ u8 noa1_en:1;
+ u8 allstasleep:1;
+ u8 discovery:1;
+ u8 reserved:1;
+};
+
+#define IQK_MATRIX_REG_NUM 8
+#define IQK_MATRIX_SETTINGS_NUM (1 + 24 + 21)
+
+struct iqk_matrix_regs {
+ bool iqk_done;
+ long value[1][IQK_MATRIX_REG_NUM];
+};
+
+struct phy_parameters {
+ u16 length;
+ u32 *pdata;
+};
+
+enum hw_param_tab_index {
+ PHY_REG_2T,
+ PHY_REG_1T,
+ PHY_REG_PG,
+ RADIOA_2T,
+ RADIOB_2T,
+ RADIOA_1T,
+ RADIOB_1T,
+ MAC_REG,
+ AGCTAB_2T,
+ AGCTAB_1T,
+ MAX_TAB
+};
+
+struct rtl_phy {
+ struct bb_reg_def phyreg_def[4]; /*Radio A/B/C/D */
+ struct init_gain initgain_backup;
+ enum io_type current_io_type;
+
+ u8 rf_mode;
+ u8 rf_type;
+ u8 current_chan_bw;
+ u8 max_ht_chan_bw;
+ u8 max_vht_chan_bw;
+ u8 set_bwmode_inprogress;
+ u8 sw_chnl_inprogress;
+ u8 sw_chnl_stage;
+ u8 sw_chnl_step;
+ u8 current_channel;
+ u8 h2c_box_num;
+ u8 set_io_inprogress;
+ u8 lck_inprogress;
+
+ /* record for power tracking */
+ s32 reg_e94;
+ s32 reg_e9c;
+ s32 reg_ea4;
+ s32 reg_eac;
+ s32 reg_eb4;
+ s32 reg_ebc;
+ s32 reg_ec4;
+ s32 reg_ecc;
+ u8 rfpienable;
+ u8 reserve_0;
+ u16 reserve_1;
+ u32 reg_c04, reg_c08, reg_874;
+ u32 adda_backup[16];
+ u32 iqk_mac_backup[IQK_MAC_REG_NUM];
+ u32 iqk_bb_backup[10];
+ bool iqk_initialized;
+
+ bool rfpath_rx_enable[MAX_RF_PATH];
+ u8 reg_837;
+ /* Dual mac */
+ bool need_iqk;
+ struct iqk_matrix_regs iqk_matrix[IQK_MATRIX_SETTINGS_NUM];
+
+ bool rfpi_enable;
+ bool iqk_in_progress;
+
+ u8 pwrgroup_cnt;
+ u8 cck_high_power;
+ /* this is for 88E & 8723A */
+ u32 mcs_txpwrlevel_origoffset[MAX_PG_GROUP][16];
+ /* MAX_PG_GROUP groups of pwr diff by rates */
+ u32 mcs_offset[MAX_PG_GROUP][16];
+ u32 tx_power_by_rate_offset[TX_PWR_BY_RATE_NUM_BAND]
+ [TX_PWR_BY_RATE_NUM_RF]
+ [TX_PWR_BY_RATE_NUM_RF]
+ [TX_PWR_BY_RATE_NUM_RATE];
+ /* compatible with TX_PWR_BY_RATE_NUM_SECTION*/
+ u8 txpwr_by_rate_base_24g[TX_PWR_BY_RATE_NUM_RF]
+ [TX_PWR_BY_RATE_NUM_RF]
+ [MAX_BASE_NUM_IN_PHY_REG_PG_24G];
+ u8 txpwr_by_rate_base_5g[TX_PWR_BY_RATE_NUM_RF]
+ [TX_PWR_BY_RATE_NUM_RF]
+ [MAX_BASE_NUM_IN_PHY_REG_PG_5G];
+ u8 default_initialgain[4];
+
+ /* the current Tx power level */
+ u8 cur_cck_txpwridx;
+ u8 cur_ofdm24g_txpwridx;
+ u8 cur_bw20_txpwridx;
+ u8 cur_bw40_txpwridx;
+
+ s8 txpwr_limit_2_4g[MAX_REGULATION_NUM]
+ [MAX_2_4G_BANDWIDTH_NUM]
+ [MAX_RATE_SECTION_NUM]
+ [CHANNEL_MAX_NUMBER_2G]
+ [MAX_RF_PATH_NUM];
+ s8 txpwr_limit_5g[MAX_REGULATION_NUM]
+ [MAX_5G_BANDWIDTH_NUM]
+ [MAX_RATE_SECTION_NUM]
+ [CHANNEL_MAX_NUMBER_5G]
+ [MAX_RF_PATH_NUM];
+
+ u32 rfreg_chnlval[2];
+ bool apk_done;
+ u32 reg_rf3c[2]; /* pathA / pathB */
+
+ u32 backup_rf_0x1a;/*92ee*/
+ /* bfsync */
+ u8 framesync;
+ u32 framesync_c34;
+
+ u8 num_total_rfpath;
+ struct phy_parameters hwparam_tables[MAX_TAB];
+ u16 rf_pathmap;
+
+ u8 hw_rof_enable; /*Enable GPIO[9] as WL RF HW PDn source*/
+ enum rt_polarity_ctl polarity_ctl;
+};
+
+#define MAX_TID_COUNT 9
+#define RTL_AGG_STOP 0
+#define RTL_AGG_PROGRESS 1
+#define RTL_AGG_START 2
+#define RTL_AGG_OPERATIONAL 3
+#define RTL_AGG_OFF 0
+#define RTL_AGG_ON 1
+#define RTL_RX_AGG_START 1
+#define RTL_RX_AGG_STOP 0
+#define RTL_AGG_EMPTYING_HW_QUEUE_ADDBA 2
+#define RTL_AGG_EMPTYING_HW_QUEUE_DELBA 3
+
+struct rtl_ht_agg {
+ u16 txq_id;
+ u16 wait_for_ba;
+ u16 start_idx;
+ u64 bitmap;
+ u32 rate_n_flags;
+ u8 agg_state;
+ u8 rx_agg_state;
+};
+
+struct rssi_sta {
+ /* for old dm */
+ long undec_sm_pwdb;
+ long undec_sm_cck;
+
+ /* for new phydm_mod */
+ s32 undecorated_smoothed_pwdb;
+ s32 undecorated_smoothed_cck;
+ s32 undecorated_smoothed_ofdm;
+ u8 ofdm_pkt;
+ u8 cck_pkt;
+ u16 cck_sum_power;
+ u8 is_send_rssi;
+ u64 packet_map;
+ u8 valid_bit;
+};
+
+struct rtl_tid_data {
+ u16 seq_number;
+ struct rtl_ht_agg agg;
+};
+
+struct rtl_sta_info {
+ struct list_head list;
+ struct rtl_tid_data tids[MAX_TID_COUNT];
+ /* just used for ap adhoc or mesh*/
+ struct rssi_sta rssi_stat;
+ u8 rssi_level;
+ u16 wireless_mode;
+ u8 ratr_index;
+ u8 mimo_ps;
+ u8 mac_addr[ETH_ALEN];
+} __packed;
+
+struct rtl_priv;
+struct rtl_io {
+ struct device *dev;
+ struct mutex bb_mutex;
+
+ /*PCI MEM map */
+ unsigned long pci_mem_end; /*shared mem end */
+ unsigned long pci_mem_start; /*shared mem start */
+
+ /*PCI IO map */
+ unsigned long pci_base_addr; /*device I/O address */
+
+ void (*write8_async)(struct rtl_priv *rtlpriv, u32 addr, u8 val);
+ void (*write16_async)(struct rtl_priv *rtlpriv, u32 addr, u16 val);
+ void (*write32_async)(struct rtl_priv *rtlpriv, u32 addr, u32 val);
+ void (*writeN_sync)(struct rtl_priv *rtlpriv, u32 addr, void *buf,
+ u16 len);
+
+ u8 (*read8_sync)(struct rtl_priv *rtlpriv, u32 addr);
+ u16 (*read16_sync)(struct rtl_priv *rtlpriv, u32 addr);
+ u32 (*read32_sync)(struct rtl_priv *rtlpriv, u32 addr);
+
+};
+
+struct rtl_mac {
+ u8 mac_addr[ETH_ALEN];
+ u8 mac80211_registered;
+ u8 beacon_enabled;
+
+ u32 tx_ss_num;
+ u32 rx_ss_num;
+
+ struct ieee80211_supported_band bands[NUM_NL80211_BANDS];
+ struct ieee80211_hw *hw;
+ struct ieee80211_vif *vif;
+ enum nl80211_iftype opmode;
+
+ /*Probe Beacon management */
+ struct rtl_tid_data tids[MAX_TID_COUNT];
+ enum rtl_link_state link_state;
+ struct rtl_beacon_keys cur_beacon_keys;
+ u8 new_beacon_cnt;
+
+ int n_channels;
+ int n_bitrates;
+
+ bool offchan_delay;
+ u8 p2p; /*using p2p role*/
+ bool p2p_in_use;
+
+ /*filters */
+ u32 rx_conf;
+ u16 rx_mgt_filter;
+ u16 rx_ctrl_filter;
+ u16 rx_data_filter;
+
+ bool act_scanning;
+ u8 cnt_after_linked;
+ bool skip_scan;
+
+ /* early mode */
+ /* skb wait queue */
+ struct sk_buff_head skb_waitq[MAX_TID_COUNT];
+
+ u8 ht_stbc_cap;
+ u8 ht_cur_stbc;
+
+ /*vht support*/
+ u8 vht_enable;
+ u8 bw_80;
+ u8 vht_cur_ldpc;
+ u8 vht_cur_stbc;
+ u8 vht_stbc_cap;
+ u8 vht_ldpc_cap;
+
+ /*RDG*/
+ bool rdg_en;
+
+ /*AP*/
+ u8 bssid[ETH_ALEN] __aligned(2);
+ u32 vendor;
+ u8 mcs[16]; /* 16 bytes mcs for HT rates. */
+ u32 basic_rates; /* b/g rates */
+ u8 ht_enable;
+ u8 sgi_40;
+ u8 sgi_20;
+ u8 bw_40;
+ u16 mode; /* wireless mode */
+ u8 slot_time;
+ u8 short_preamble;
+ u8 use_cts_protect;
+ u8 cur_40_prime_sc;
+ u8 cur_40_prime_sc_bk;
+ u8 cur_80_prime_sc;
+ u64 tsf;
+ u8 retry_short;
+ u8 retry_long;
+ u16 assoc_id;
+ bool hiddenssid;
+
+ /*IBSS*/
+ int beacon_interval;
+
+ /*AMPDU*/
+ u8 min_space_cfg; /*For Min spacing configurations */
+ u8 max_mss_density;
+ u8 current_ampdu_factor;
+ u8 current_ampdu_density;
+
+ /*QOS & EDCA */
+ struct ieee80211_tx_queue_params edca_param[RTL_MAC80211_NUM_QUEUE];
+ struct rtl_qos_parameters ac[AC_MAX];
+
+ /* counters */
+ u64 last_txok_cnt;
+ u64 last_rxok_cnt;
+ u32 last_bt_edca_ul;
+ u32 last_bt_edca_dl;
+};
+
+struct btdm_8723 {
+ bool all_off;
+ bool agc_table_en;
+ bool adc_back_off_on;
+ bool b2_ant_hid_en;
+ bool low_penalty_rate_adaptive;
+ bool rf_rx_lpf_shrink;
+ bool reject_aggre_pkt;
+ bool tra_tdma_on;
+ u8 tra_tdma_nav;
+ u8 tra_tdma_ant;
+ bool tdma_on;
+ u8 tdma_ant;
+ u8 tdma_nav;
+ u8 tdma_dac_swing;
+ u8 fw_dac_swing_lvl;
+ bool ps_tdma_on;
+ u8 ps_tdma_byte[5];
+ bool pta_on;
+ u32 val_0x6c0;
+ u32 val_0x6c8;
+ u32 val_0x6cc;
+ bool sw_dac_swing_on;
+ u32 sw_dac_swing_lvl;
+ u32 wlan_act_hi;
+ u32 wlan_act_lo;
+ u32 bt_retry_index;
+ bool dec_bt_pwr;
+ bool ignore_wlan_act;
+};
+
+struct bt_coexist_8723 {
+ u32 high_priority_tx;
+ u32 high_priority_rx;
+ u32 low_priority_tx;
+ u32 low_priority_rx;
+ u8 c2h_bt_info;
+ bool c2h_bt_info_req_sent;
+ bool c2h_bt_inquiry_page;
+ u32 bt_inq_page_start_time;
+ u8 bt_retry_cnt;
+ u8 c2h_bt_info_original;
+ u8 bt_inquiry_page_cnt;
+ struct btdm_8723 btdm;
+};
+
+struct rtl_hal {
+ struct ieee80211_hw *hw;
+ bool driver_is_goingto_unload;
+ bool up_first_time;
+ bool first_init;
+ bool being_init_adapter;
+ bool bbrf_ready;
+ bool mac_func_enable;
+ bool pre_edcca_enable;
+ struct bt_coexist_8723 hal_coex_8723;
+
+ enum intf_type interface;
+ u16 hw_type; /*92c or 92d or 92s and so on */
+ u8 ic_class;
+ u8 oem_id;
+ u32 version; /*version of chip */
+ u8 state; /*stop 0, start 1 */
+ u8 board_type;
+ u8 package_type;
+ u8 external_pa;
+
+ u8 pa_mode;
+ u8 pa_type_2g;
+ u8 pa_type_5g;
+ u8 lna_type_2g;
+ u8 lna_type_5g;
+ u8 external_pa_2g;
+ u8 external_lna_2g;
+ u8 external_pa_5g;
+ u8 external_lna_5g;
+ u8 type_glna;
+ u8 type_gpa;
+ u8 type_alna;
+ u8 type_apa;
+ u8 rfe_type;
+
+ /*firmware */
+ u32 fwsize;
+ u8 *pfirmware;
+ u16 fw_version;
+ u16 fw_subversion;
+ bool h2c_setinprogress;
+ u8 last_hmeboxnum;
+ bool fw_ready;
+ /*Reserve page start offset except beacon in TxQ. */
+ u8 fw_rsvdpage_startoffset;
+ u8 h2c_txcmd_seq;
+ u8 current_ra_rate;
+
+ /* FW Cmd IO related */
+ u16 fwcmd_iomap;
+ u32 fwcmd_ioparam;
+ bool set_fwcmd_inprogress;
+ u8 current_fwcmd_io;
+
+ struct p2p_ps_offload_t p2p_ps_offload;
+ bool fw_clk_change_in_progress;
+ bool allow_sw_to_change_hwclc;
+ u8 fw_ps_state;
+ /**/
+ bool driver_going2unload;
+
+ /*AMPDU init min space*/
+ u8 minspace_cfg; /*For Min spacing configurations */
+
+ /* Dual mac */
+ enum macphy_mode macphymode;
+ enum band_type current_bandtype; /* 0:2.4G, 1:5G */
+ enum band_type current_bandtypebackup;
+ enum band_type bandset;
+ /* dual MAC 0--Mac0 1--Mac1 */
+ u32 interfaceindex;
+ /* just for DualMac S3S4 */
+ u8 macphyctl_reg;
+ bool earlymode_enable;
+ u8 max_earlymode_num;
+ /* Dual mac*/
+ bool during_mac0init_radiob;
+ bool during_mac1init_radioa;
+ bool reloadtxpowerindex;
+ /* True if IMR or IQK have done
+ * for 2.4G in scan progress
+ */
+ bool load_imrandiqk_setting_for2g;
+
+ bool disable_amsdu_8k;
+ bool master_of_dmsp;
+ bool slave_of_dmsp;
+
+ u16 rx_tag;/*for 92ee*/
+ u8 rts_en;
+
+ /*for wowlan*/
+ bool wow_enable;
+ bool enter_pnp_sleep;
+ bool wake_from_pnp_sleep;
+ bool wow_enabled;
+ __kernel_time_t last_suspend_sec;
+ u32 wowlan_fwsize;
+ u8 *wowlan_firmware;
+
+ u8 hw_rof_enable; /*Enable GPIO[9] as WL RF HW PDn source*/
+
+ bool real_wow_v2_enable;
+ bool re_init_llt_table;
+};
+
+struct rtl_security {
+ /*default 0 */
+ bool use_sw_sec;
+
+ bool being_setkey;
+ bool use_defaultkey;
+ /*Encryption Algorithm for Unicast Packet */
+ enum rt_enc_alg pairwise_enc_algorithm;
+ /*Encryption Algorithm for Brocast/Multicast */
+ enum rt_enc_alg group_enc_algorithm;
+ /*Cam Entry Bitmap */
+ u32 hwsec_cam_bitmap;
+ u8 hwsec_cam_sta_addr[TOTAL_CAM_ENTRY][ETH_ALEN];
+ /* local Key buffer, indx 0 is for
+ * pairwise key 1-4 is for agoup key.
+ */
+ u8 key_buf[KEY_BUF_SIZE][MAX_KEY_LEN];
+ u8 key_len[KEY_BUF_SIZE];
+
+ /* The pointer of Pairwise Key,
+ * it always points to KeyBuf[4]
+ */
+ u8 *pairwise_key;
+};
+
+#define ASSOCIATE_ENTRY_NUM 33
+
+struct fast_ant_training {
+ u8 bssid[6];
+ u8 antsel_rx_keep_0;
+ u8 antsel_rx_keep_1;
+ u8 antsel_rx_keep_2;
+ u32 ant_sum[7];
+ u32 ant_cnt[7];
+ u32 ant_ave[7];
+ u8 fat_state;
+ u32 train_idx;
+ u8 antsel_a[ASSOCIATE_ENTRY_NUM];
+ u8 antsel_b[ASSOCIATE_ENTRY_NUM];
+ u8 antsel_c[ASSOCIATE_ENTRY_NUM];
+ u32 main_ant_sum[ASSOCIATE_ENTRY_NUM];
+ u32 aux_ant_sum[ASSOCIATE_ENTRY_NUM];
+ u32 main_ant_cnt[ASSOCIATE_ENTRY_NUM];
+ u32 aux_ant_cnt[ASSOCIATE_ENTRY_NUM];
+ u8 rx_idle_ant;
+ bool becomelinked;
+};
+
+struct dm_phy_dbg_info {
+ s8 rx_snrdb[4];
+ u64 num_qry_phy_status;
+ u64 num_qry_phy_status_cck;
+ u64 num_qry_phy_status_ofdm;
+ u16 num_qry_beacon_pkt;
+ u16 num_non_be_pkt;
+ s32 rx_evm[4];
+};
+
+struct rtl_dm {
+ /*PHY status for Dynamic Management */
+ long entry_min_undec_sm_pwdb;
+ long undec_sm_cck;
+ long undec_sm_pwdb; /*out dm */
+ long entry_max_undec_sm_pwdb;
+ s32 ofdm_pkt_cnt;
+ bool dm_initialgain_enable;
+ bool dynamic_txpower_enable;
+ bool current_turbo_edca;
+ bool is_any_nonbepkts; /*out dm */
+ bool is_cur_rdlstate;
+ bool txpower_trackinginit;
+ bool disable_framebursting;
+ bool cck_inch14;
+ bool txpower_tracking;
+ bool useramask;
+ bool rfpath_rxenable[4];
+ bool inform_fw_driverctrldm;
+ bool current_mrc_switch;
+ u8 txpowercount;
+ u8 powerindex_backup[6];
+
+ u8 thermalvalue_rxgain;
+ u8 thermalvalue_iqk;
+ u8 thermalvalue_lck;
+ u8 thermalvalue;
+ u8 last_dtp_lvl;
+ u8 thermalvalue_avg[AVG_THERMAL_NUM];
+ u8 thermalvalue_avg_index;
+ u8 tm_trigger;
+ bool done_txpower;
+ u8 dynamic_txhighpower_lvl; /*Tx high power level */
+ u8 dm_flag; /*Indicate each dynamic mechanism's status. */
+ u8 dm_flag_tmp;
+ u8 dm_type;
+ u8 dm_rssi_sel;
+ u8 txpower_track_control;
+ bool interrupt_migration;
+ bool disable_tx_int;
+ s8 ofdm_index[MAX_RF_PATH];
+ u8 default_ofdm_index;
+ u8 default_cck_index;
+ s8 cck_index;
+ s8 delta_power_index[MAX_RF_PATH];
+ s8 delta_power_index_last[MAX_RF_PATH];
+ s8 power_index_offset[MAX_RF_PATH];
+ s8 absolute_ofdm_swing_idx[MAX_RF_PATH];
+ s8 remnant_ofdm_swing_idx[MAX_RF_PATH];
+ s8 remnant_cck_idx;
+ bool modify_txagc_flag_path_a;
+ bool modify_txagc_flag_path_b;
+
+ bool one_entry_only;
+ struct dm_phy_dbg_info dbginfo;
+
+ /* Dynamic ATC switch */
+ bool atc_status;
+ bool large_cfo_hit;
+ bool is_freeze;
+ int cfo_tail[2];
+ int cfo_ave_pre;
+ int crystal_cap;
+ u8 cfo_threshold;
+ u32 packet_count;
+ u32 packet_count_pre;
+ u8 tx_rate;
+
+ /*88e tx power tracking*/
+ u8 swing_idx_ofdm[MAX_RF_PATH];
+ u8 swing_idx_ofdm_cur;
+ u8 swing_idx_ofdm_base[MAX_RF_PATH];
+ bool swing_flag_ofdm;
+ u8 swing_idx_cck;
+ u8 swing_idx_cck_cur;
+ u8 swing_idx_cck_base;
+ bool swing_flag_cck;
+
+ s8 swing_diff_2g;
+ s8 swing_diff_5g;
+
+ /* DMSP */
+ bool supp_phymode_switch;
+
+ /* DulMac */
+ struct fast_ant_training fat_table;
+
+ u8 resp_tx_path;
+ u8 path_sel;
+ u32 patha_sum;
+ u32 pathb_sum;
+ u32 patha_cnt;
+ u32 pathb_cnt;
+
+ u8 pre_channel;
+ u8 *p_channel;
+ u8 linked_interval;
+
+ u64 last_tx_ok_cnt;
+ u64 last_rx_ok_cnt;
+};
+
+#define EFUSE_MAX_LOGICAL_SIZE 512
+
+struct rtl_efuse {
+ bool autoload_ok;
+ bool bootfromefuse;
+ u16 max_physical_size;
+
+ u8 efuse_map[2][EFUSE_MAX_LOGICAL_SIZE];
+ u16 efuse_usedbytes;
+ u8 efuse_usedpercentage;
+#ifdef EFUSE_REPG_WORKAROUND
+ bool efuse_re_pg_sec1flag;
+ u8 efuse_re_pg_data[8];
+#endif
+
+ u8 autoload_failflag;
+ u8 autoload_status;
+
+ short epromtype;
+ u16 eeprom_vid;
+ u16 eeprom_did;
+ u16 eeprom_svid;
+ u16 eeprom_smid;
+ u8 eeprom_oemid;
+ u16 eeprom_channelplan;
+ u8 eeprom_version;
+ u8 board_type;
+ u8 external_pa;
+
+ u8 dev_addr[6];
+ u8 wowlan_enable;
+ u8 antenna_div_cfg;
+ u8 antenna_div_type;
+
+ bool txpwr_fromeprom;
+ u8 eeprom_crystalcap;
+ u8 eeprom_tssi[2];
+ u8 eeprom_tssi_5g[3][2]; /* for 5GL/5GM/5GH band. */
+ u8 eeprom_pwrlimit_ht20[CHANNEL_GROUP_MAX];
+ u8 eeprom_pwrlimit_ht40[CHANNEL_GROUP_MAX];
+ u8 eeprom_chnlarea_txpwr_cck[MAX_RF_PATH][CHANNEL_GROUP_MAX_2G];
+ u8 eeprom_chnlarea_txpwr_ht40_1s[MAX_RF_PATH][CHANNEL_GROUP_MAX];
+ u8 eprom_chnl_txpwr_ht40_2sdf[MAX_RF_PATH][CHANNEL_GROUP_MAX];
+
+ u8 internal_pa_5g[2]; /* pathA / pathB */
+ u8 eeprom_c9;
+ u8 eeprom_cc;
+
+ /*For power group */
+ u8 eeprom_pwrgroup[2][3];
+ u8 pwrgroup_ht20[2][CHANNEL_MAX_NUMBER];
+ u8 pwrgroup_ht40[2][CHANNEL_MAX_NUMBER];
+
+ u8 txpwrlevel_cck[MAX_RF_PATH][CHANNEL_MAX_NUMBER_2G];
+ /*For HT 40MHZ pwr */
+ u8 txpwrlevel_ht40_1s[MAX_RF_PATH][CHANNEL_MAX_NUMBER];
+ /*For HT 40MHZ pwr */
+ u8 txpwrlevel_ht40_2s[MAX_RF_PATH][CHANNEL_MAX_NUMBER];
+
+ /*--------------------------------------------------------*
+ * 8192CE\8192SE\8192DE\8723AE use the following 4 arrays,
+ * other ICs (8188EE\8723BE\8192EE\8812AE...)
+ * define new arrays in Windows code.
+ * BUT, in linux code, we use the same array for all ICs.
+ *
+ * The Correspondance relation between two arrays is:
+ * txpwr_cckdiff[][] == CCK_24G_Diff[][]
+ * txpwr_ht20diff[][] == BW20_24G_Diff[][]
+ * txpwr_ht40diff[][] == BW40_24G_Diff[][]
+ * txpwr_legacyhtdiff[][] == OFDM_24G_Diff[][]
+ *
+ * Sizes of these arrays are decided by the larger ones.
+ */
+ s8 txpwr_cckdiff[MAX_RF_PATH][CHANNEL_MAX_NUMBER];
+ s8 txpwr_ht20diff[MAX_RF_PATH][CHANNEL_MAX_NUMBER];
+ s8 txpwr_ht40diff[MAX_RF_PATH][CHANNEL_MAX_NUMBER];
+ s8 txpwr_legacyhtdiff[MAX_RF_PATH][CHANNEL_MAX_NUMBER];
+
+ u8 txpwr_5g_bw40base[MAX_RF_PATH][CHANNEL_MAX_NUMBER];
+ u8 txpwr_5g_bw80base[MAX_RF_PATH][CHANNEL_MAX_NUMBER_5G_80M];
+ s8 txpwr_5g_ofdmdiff[MAX_RF_PATH][MAX_TX_COUNT];
+ s8 txpwr_5g_bw20diff[MAX_RF_PATH][MAX_TX_COUNT];
+ s8 txpwr_5g_bw40diff[MAX_RF_PATH][MAX_TX_COUNT];
+ s8 txpwr_5g_bw80diff[MAX_RF_PATH][MAX_TX_COUNT];
+
+ u8 txpwr_safetyflag; /* Band edge enable flag */
+ u16 eeprom_txpowerdiff;
+ u8 legacy_httxpowerdiff; /* Legacy to HT rate power diff */
+ u8 antenna_txpwdiff[3];
+
+ u8 eeprom_regulatory;
+ u8 eeprom_thermalmeter;
+ u8 thermalmeter[2]; /*ThermalMeter, index 0 for RFIC0, 1 for RFIC1 */
+ u16 tssi_13dbm;
+ u8 crystalcap; /* CrystalCap. */
+ u8 delta_iqk;
+ u8 delta_lck;
+
+ u8 legacy_ht_txpowerdiff; /*Legacy to HT rate power diff */
+ bool apk_thermalmeterignore;
+
+ bool b1x1_recvcombine;
+ bool b1ss_support;
+
+ /*channel plan */
+ u8 channel_plan;
+};
+
+struct rtl_tx_report {
+ atomic_t sn;
+ u16 last_sent_sn;
+ unsigned long last_sent_time;
+ u16 last_recv_sn;
+};
+
+struct rtl_ps_ctl {
+ bool pwrdomain_protect;
+ bool in_powersavemode;
+ bool rfchange_inprogress;
+ bool swrf_processing;
+ bool hwradiooff;
+ /* just for PCIE ASPM
+ * If it supports ASPM, Offset[560h] = 0x40,
+ * otherwise Offset[560h] = 0x00.
+ */
+ bool support_aspm;
+ bool support_backdoor;
+
+ /*for LPS */
+ enum rt_psmode dot11_psmode; /*Power save mode configured. */
+ bool swctrl_lps;
+ bool leisure_ps;
+ bool fwctrl_lps;
+ u8 fwctrl_psmode;
+ /*For Fw control LPS mode */
+ u8 reg_fwctrl_lps;
+ /*Record Fw PS mode status. */
+ bool fw_current_inpsmode;
+ u8 reg_max_lps_awakeintvl;
+ bool report_linked;
+ bool low_power_enable;/*for 32k*/
+
+ /*for IPS */
+ bool inactiveps;
+
+ u32 rfoff_reason;
+
+ /*RF OFF Level */
+ u32 cur_ps_level;
+ u32 reg_rfps_level;
+
+ /*just for PCIE ASPM */
+ u8 const_amdpci_aspm;
+ bool pwrdown_mode;
+
+ enum rf_pwrstate inactive_pwrstate;
+ enum rf_pwrstate rfpwr_state; /*cur power state */
+
+ /* for SW LPS*/
+ bool sw_ps_enabled;
+ bool state;
+ bool state_inap;
+ bool multi_buffered;
+ u16 nullfunc_seq;
+ unsigned int dtim_counter;
+ unsigned int sleep_ms;
+ unsigned long last_sleep_jiffies;
+ unsigned long last_awake_jiffies;
+ unsigned long last_delaylps_stamp_jiffies;
+ unsigned long last_dtim;
+ unsigned long last_beacon;
+ unsigned long last_action;
+ unsigned long last_slept;
+
+ /*For P2P PS */
+ struct rtl_p2p_ps_info p2p_ps_info;
+ u8 pwr_mode;
+ u8 smart_ps;
+
+ /* wake up on line */
+ u8 wo_wlan_mode;
+ u8 arp_offload_enable;
+ u8 gtk_offload_enable;
+ /* Used for WOL, indicates the reason for waking event.*/
+ u32 wakeup_reason;
+ /* Record the last waking time for comparison with setting key. */
+ u64 last_wakeup_time;
+};
+
+struct rtl_stats {
+ u8 psaddr[ETH_ALEN];
+ u32 mac_time[2];
+ s8 rssi;
+ u8 signal;
+ u8 noise;
+ u8 rate; /* hw desc rate */
+ u8 received_channel;
+ u8 control;
+ u8 mask;
+ u8 freq;
+ u16 len;
+ u64 tsf;
+ u32 beacon_time;
+ u8 nic_type;
+ u16 length;
+ u8 signalquality; /*in 0-100 index. */
+ /*
+ * Real power in dBm for this packet,
+ * no beautification and aggregation.
+ */
+ s32 recvsignalpower;
+ s8 rxpower; /*in dBm Translate from PWdB */
+ u8 signalstrength; /*in 0-100 index. */
+ u16 hwerror:1;
+ u16 crc:1;
+ u16 icv:1;
+ u16 shortpreamble:1;
+ u16 antenna:1;
+ u16 decrypted:1;
+ u16 wakeup:1;
+ u32 timestamp_low;
+ u32 timestamp_high;
+ bool shift;
+
+ u8 rx_drvinfo_size;
+ u8 rx_bufshift;
+ bool isampdu;
+ bool isfirst_ampdu;
+ bool rx_is40mhzpacket;
+ u8 rx_packet_bw;
+ u32 rx_pwdb_all;
+ u8 rx_mimo_signalstrength[4]; /*in 0~100 index */
+ s8 rx_mimo_signalquality[4];
+ u8 rx_mimo_evm_dbm[4];
+ u16 cfo_short[4]; /* per-path's Cfo_short */
+ u16 cfo_tail[4];
+
+ s8 rx_mimo_sig_qual[4];
+ u8 rx_pwr[4]; /* per-path's pwdb */
+ u8 rx_snr[4]; /* per-path's SNR */
+ u8 bandwidth;
+ u8 bt_coex_pwr_adjust;
+ bool packet_matchbssid;
+ bool is_cck;
+ bool is_ht;
+ bool packet_toself;
+ bool packet_beacon; /*for rssi */
+ s8 cck_adc_pwdb[4]; /*for rx path selection */
+
+ bool is_vht;
+ bool is_short_gi;
+ u8 vht_nss;
+
+ u8 packet_report_type;
+
+ u32 macid;
+ u8 wake_match;
+ u32 bt_rx_rssi_percentage;
+ u32 macid_valid_entry[2];
+};
+
+struct rt_link_detect {
+ /* count for roaming */
+ u32 bcn_rx_inperiod;
+ u32 roam_times;
+
+ u32 num_tx_in4period[4];
+ u32 num_rx_in4period[4];
+
+ u32 num_tx_inperiod;
+ u32 num_rx_inperiod;
+
+ bool busytraffic;
+ bool tx_busy_traffic;
+ bool rx_busy_traffic;
+ bool higher_busytraffic;
+ bool higher_busyrxtraffic;
+
+ u32 tidtx_in4period[MAX_TID_COUNT][4];
+ u32 tidtx_inperiod[MAX_TID_COUNT];
+ bool higher_busytxtraffic[MAX_TID_COUNT];
+};
+
+struct rtl_tcb_desc {
+ u8 packet_bw:2;
+ u8 multicast:1;
+ u8 broadcast:1;
+
+ u8 rts_stbc:1;
+ u8 rts_enable:1;
+ u8 cts_enable:1;
+ u8 rts_use_shortpreamble:1;
+ u8 rts_use_shortgi:1;
+ u8 rts_sc:1;
+ u8 rts_bw:1;
+ u8 rts_rate;
+
+ u8 use_shortgi:1;
+ u8 use_shortpreamble:1;
+ u8 use_driver_rate:1;
+ u8 disable_ratefallback:1;
+
+ u8 use_spe_rpt:1;
+
+ u8 ratr_index;
+ u8 mac_id;
+ u8 hw_rate;
+
+ u8 last_inipkt:1;
+ u8 cmd_or_init:1;
+ u8 queue_index;
+
+ /* early mode */
+ u8 empkt_num;
+ /* The max value by HW */
+ u32 empkt_len[10];
+ bool tx_enable_sw_calc_duration;
+};
+
+struct rtl_wow_pattern {
+ u8 type;
+ u16 crc;
+ u32 mask[4];
+};
+
+struct rtl_hal_ops {
+ int (*init_sw_vars)(struct ieee80211_hw *hw);
+ void (*deinit_sw_vars)(struct ieee80211_hw *hw);
+ void (*read_chip_version)(struct ieee80211_hw *hw);
+ void (*read_eeprom_info)(struct ieee80211_hw *hw);
+ void (*interrupt_recognized)(struct ieee80211_hw *hw,
+ u32 *p_inta, u32 *p_intb,
+ u32 *p_intc, u32 *p_intd);
+ int (*hw_init)(struct ieee80211_hw *hw);
+ void (*hw_disable)(struct ieee80211_hw *hw);
+ void (*hw_suspend)(struct ieee80211_hw *hw);
+ void (*hw_resume)(struct ieee80211_hw *hw);
+ void (*enable_interrupt)(struct ieee80211_hw *hw);
+ void (*disable_interrupt)(struct ieee80211_hw *hw);
+ int (*set_network_type)(struct ieee80211_hw *hw,
+ enum nl80211_iftype type);
+ void (*set_chk_bssid)(struct ieee80211_hw *hw,
+ bool check_bssid);
+ void (*set_bw_mode)(struct ieee80211_hw *hw,
+ enum nl80211_channel_type ch_type);
+ u8 (*switch_channel)(struct ieee80211_hw *hw);
+ void (*set_qos)(struct ieee80211_hw *hw, int aci);
+ void (*set_bcn_reg)(struct ieee80211_hw *hw);
+ void (*set_bcn_intv)(struct ieee80211_hw *hw);
+ void (*update_interrupt_mask)(struct ieee80211_hw *hw,
+ u32 add_msr, u32 rm_msr);
+ void (*get_hw_reg)(struct ieee80211_hw *hw, u8 variable, u8 *val);
+ void (*set_hw_reg)(struct ieee80211_hw *hw, u8 variable, u8 *val);
+ void (*update_rate_tbl)(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u8 rssi_leve,
+ bool update_bw);
+ void (*pre_fill_tx_bd_desc)(struct ieee80211_hw *hw, u8 *tx_bd_desc,
+ u8 *desc, u8 queue_index,
+ struct sk_buff *skb, dma_addr_t addr);
+ void (*update_rate_mask)(struct ieee80211_hw *hw, u8 rssi_level);
+ u16 (*rx_desc_buff_remained_cnt)(struct ieee80211_hw *hw,
+ u8 queue_index);
+ void (*rx_check_dma_ok)(struct ieee80211_hw *hw, u8 *header_desc,
+ u8 queue_index);
+ void (*fill_tx_desc)(struct ieee80211_hw *hw,
+ struct ieee80211_hdr *hdr, u8 *pdesc_tx,
+ u8 *pbd_desc_tx,
+ struct ieee80211_tx_info *info,
+ struct ieee80211_sta *sta,
+ struct sk_buff *skb, u8 hw_queue,
+ struct rtl_tcb_desc *ptcb_desc);
+ void (*fill_fake_txdesc)(struct ieee80211_hw *hw, u8 *pdesc,
+ u32 buffer_len, bool bispspoll);
+ void (*fill_tx_cmddesc)(struct ieee80211_hw *hw, u8 *pdesc,
+ bool firstseg, bool lastseg,
+ struct sk_buff *skb);
+ void (*fill_tx_special_desc)(struct ieee80211_hw *hw,
+ u8 *pdesc, u8 *pbd_desc,
+ struct sk_buff *skb, u8 hw_queue);
+ bool (*query_rx_desc)(struct ieee80211_hw *hw,
+ struct rtl_stats *stats,
+ struct ieee80211_rx_status *rx_status,
+ u8 *pdesc, struct sk_buff *skb);
+ void (*set_channel_access)(struct ieee80211_hw *hw);
+ bool (*radio_onoff_checking)(struct ieee80211_hw *hw, u8 *valid);
+ void (*dm_watchdog)(struct ieee80211_hw *hw);
+ void (*scan_operation_backup)(struct ieee80211_hw *hw, u8 operation);
+ bool (*set_rf_power_state)(struct ieee80211_hw *hw,
+ enum rf_pwrstate rfpwr_state);
+ void (*led_control)(struct ieee80211_hw *hw,
+ enum led_ctl_mode ledaction);
+ void (*set_desc)(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
+ u8 desc_name, u8 *val);
+ u64 (*get_desc)(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
+ u8 desc_name);
+ bool (*is_tx_desc_closed)(struct ieee80211_hw *hw,
+ u8 hw_queue, u16 index);
+ void (*tx_polling)(struct ieee80211_hw *hw, u8 hw_queue);
+ void (*enable_hw_sec)(struct ieee80211_hw *hw);
+ void (*set_key)(struct ieee80211_hw *hw, u32 key_index,
+ u8 *macaddr, bool is_group, u8 enc_algo,
+ bool is_wepkey, bool clear_all);
+ void (*init_sw_leds)(struct ieee80211_hw *hw);
+ void (*deinit_sw_leds)(struct ieee80211_hw *hw);
+ u32 (*get_bbreg)(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask);
+ void (*set_bbreg)(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
+ u32 data);
+ u32 (*get_rfreg)(struct ieee80211_hw *hw, enum radio_path rfpath,
+ u32 regaddr, u32 bitmask);
+ void (*set_rfreg)(struct ieee80211_hw *hw, enum radio_path rfpath,
+ u32 regaddr, u32 bitmask, u32 data);
+ void (*linked_set_reg)(struct ieee80211_hw *hw);
+ void (*chk_switch_dmdp)(struct ieee80211_hw *hw);
+ void (*dualmac_easy_concurrent)(struct ieee80211_hw *hw);
+ void (*dualmac_switch_to_dmdp)(struct ieee80211_hw *hw);
+ bool (*phy_rf6052_config)(struct ieee80211_hw *hw);
+ void (*phy_rf6052_set_cck_txpower)(struct ieee80211_hw *hw,
+ u8 *powerlevel);
+ void (*phy_rf6052_set_ofdm_txpower)(struct ieee80211_hw *hw,
+ u8 *ppowerlevel, u8 channel);
+ bool (*config_bb_with_headerfile)(struct ieee80211_hw *hw,
+ u8 configtype);
+ bool (*config_bb_with_pgheaderfile)(struct ieee80211_hw *hw,
+ u8 configtype);
+ void (*phy_lc_calibrate)(struct ieee80211_hw *hw, bool is2t);
+ void (*phy_set_bw_mode_callback)(struct ieee80211_hw *hw);
+ void (*dm_dynamic_txpower)(struct ieee80211_hw *hw);
+ void (*c2h_command_handle)(struct ieee80211_hw *hw);
+ void (*bt_wifi_media_status_notify)(struct ieee80211_hw *hw,
+ bool mstate);
+ void (*bt_coex_off_before_lps)(struct ieee80211_hw *hw);
+ void (*fill_h2c_cmd)(struct ieee80211_hw *hw, u8 element_id,
+ u32 cmd_len, u8 *p_cmdbuffer);
+ void (*set_default_port_id_cmd)(struct ieee80211_hw *hw);
+ bool (*get_btc_status)(void);
+ bool (*is_fw_header)(struct rtlwifi_firmware_header *hdr);
+ u32 (*rx_command_packet)(struct ieee80211_hw *hw,
+ const struct rtl_stats *status,
+ struct sk_buff *skb);
+ void (*add_wowlan_pattern)(struct ieee80211_hw *hw,
+ struct rtl_wow_pattern *rtl_pattern,
+ u8 index);
+ u16 (*get_available_desc)(struct ieee80211_hw *hw, u8 q_idx);
+ void (*c2h_content_parsing)(struct ieee80211_hw *hw, u8 tag, u8 len,
+ u8 *val);
+ /* ops for halmac cb */
+ bool (*halmac_cb_init_mac_register)(struct rtl_priv *rtlpriv);
+ bool (*halmac_cb_init_bb_rf_register)(struct rtl_priv *rtlpriv);
+ bool (*halmac_cb_write_data_rsvd_page)(struct rtl_priv *rtlpriv,
+ u8 *buf, u32 size);
+ bool (*halmac_cb_write_data_h2c)(struct rtl_priv *rtlpriv, u8 *buf,
+ u32 size);
+ /* ops for phydm cb */
+ u8 (*get_txpower_index)(struct ieee80211_hw *hw, u8 path,
+ u8 rate, u8 bandwidth, u8 channel);
+ void (*set_tx_power_index_by_rs)(struct ieee80211_hw *hw,
+ u8 channel, u8 path,
+ enum rate_section rs);
+ void (*store_tx_power_by_rate)(struct ieee80211_hw *hw,
+ u32 band, u32 rfpath,
+ u32 txnum, u32 regaddr,
+ u32 bitmask, u32 data);
+ void (*phy_set_txpower_limit)(struct ieee80211_hw *hw, u8 *pregulation,
+ u8 *pband, u8 *pbandwidth,
+ u8 *prate_section, u8 *prf_path,
+ u8 *pchannel, u8 *ppower_limit);
+};
+
+struct rtl_intf_ops {
+ /*com */
+ void (*read_efuse_byte)(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf);
+ int (*adapter_start)(struct ieee80211_hw *hw);
+ void (*adapter_stop)(struct ieee80211_hw *hw);
+ bool (*check_buddy_priv)(struct ieee80211_hw *hw,
+ struct rtl_priv **buddy_priv);
+
+ int (*adapter_tx)(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
+ struct sk_buff *skb,
+ struct rtl_tcb_desc *ptcb_desc);
+ void (*flush)(struct ieee80211_hw *hw, u32 queues, bool drop);
+ int (*reset_trx_ring)(struct ieee80211_hw *hw);
+ bool (*waitq_insert)(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
+ struct sk_buff *skb);
+
+ /*pci */
+ void (*disable_aspm)(struct ieee80211_hw *hw);
+ void (*enable_aspm)(struct ieee80211_hw *hw);
+
+ /*usb */
+};
+
+struct rtl_mod_params {
+ /* default: 0,0 */
+ u64 debug_mask;
+ /* default: 0 = using hardware encryption */
+ bool sw_crypto;
+
+ /* default: 0 = DBG_EMERG (0)*/
+ int debug_level;
+
+ /* default: 1 = using no linked power save */
+ bool inactiveps;
+
+ /* default: 1 = using linked sw power save */
+ bool swctrl_lps;
+
+ /* default: 1 = using linked fw power save */
+ bool fwctrl_lps;
+
+ /* default: 0 = not using MSI interrupts mode
+ * submodules should set their own default value
+ */
+ bool msi_support;
+
+ /* default: 0 = dma 32 */
+ bool dma64;
+
+ /* default: 1 = enable aspm */
+ int aspm_support;
+
+ /* default 0: 1 means disable */
+ bool disable_watchdog;
+
+ /* default 0: 1 means do not disable interrupts */
+ bool int_clear;
+
+ /* select antenna */
+ int ant_sel;
+};
+
+struct rtl_hal_usbint_cfg {
+ /* data - rx */
+ u32 in_ep_num;
+ u32 rx_urb_num;
+ u32 rx_max_size;
+
+ /* op - rx */
+ void (*usb_rx_hdl)(struct ieee80211_hw *, struct sk_buff *);
+ void (*usb_rx_segregate_hdl)(struct ieee80211_hw *, struct sk_buff *,
+ struct sk_buff_head *);
+
+ /* tx */
+ void (*usb_tx_cleanup)(struct ieee80211_hw *, struct sk_buff *);
+ int (*usb_tx_post_hdl)(struct ieee80211_hw *, struct urb *,
+ struct sk_buff *);
+ struct sk_buff *(*usb_tx_aggregate_hdl)(struct ieee80211_hw *,
+ struct sk_buff_head *);
+
+ /* endpoint mapping */
+ int (*usb_endpoint_mapping)(struct ieee80211_hw *hw);
+ u16 (*usb_mq_to_hwq)(__le16 fc, u16 mac80211_queue_index);
+};
+
+struct rtl_hal_cfg {
+ u8 bar_id;
+ bool write_readback;
+ char *name;
+ char *alt_fw_name;
+ struct rtl_hal_ops *ops;
+ struct rtl_mod_params *mod_params;
+ struct rtl_hal_usbint_cfg *usb_interface_cfg;
+ enum rtl_spec_ver spec_ver;
+
+ /* this map used for some registers or vars
+ * defined int HAL but used in MAIN
+ */
+ u32 maps[RTL_VAR_MAP_MAX];
+
+};
+
+struct rtl_locks {
+ /* mutex */
+ struct mutex conf_mutex;
+ struct mutex ips_mutex; /* mutex for enter/leave IPS */
+ struct mutex lps_mutex; /* mutex for enter/leave LPS */
+
+ /*spin lock */
+ spinlock_t irq_th_lock;
+ spinlock_t h2c_lock;
+ spinlock_t rf_ps_lock;
+ spinlock_t rf_lock;
+ spinlock_t waitq_lock;
+ spinlock_t entry_list_lock;
+ spinlock_t usb_lock;
+ spinlock_t c2hcmd_lock;
+ spinlock_t scan_list_lock; /* lock for the scan list */
+
+ /*FW clock change */
+ spinlock_t fw_ps_lock;
+
+ /*Dual mac*/
+ spinlock_t cck_and_rw_pagea_lock;
+
+ spinlock_t iqk_lock;
+};
+
+struct rtl_works {
+ struct ieee80211_hw *hw;
+
+ /*timer */
+ struct timer_list watchdog_timer;
+ struct timer_list dualmac_easyconcurrent_retrytimer;
+ struct timer_list fw_clockoff_timer;
+ struct timer_list fast_antenna_training_timer;
+ /*task */
+ struct tasklet_struct irq_tasklet;
+ struct tasklet_struct irq_prepare_bcn_tasklet;
+
+ /*work queue */
+ struct workqueue_struct *rtl_wq;
+ struct delayed_work watchdog_wq;
+ struct delayed_work ips_nic_off_wq;
+ struct delayed_work c2hcmd_wq;
+
+ /* For SW LPS */
+ struct delayed_work ps_work;
+ struct delayed_work ps_rfon_wq;
+ struct delayed_work fwevt_wq;
+
+ struct work_struct lps_change_work;
+ struct work_struct fill_h2c_cmd;
+};
+
+struct rtl_debug {
+ /* add for debug */
+ struct dentry *debugfs_dir;
+ char debugfs_name[20];
+
+ char *msg_buf;
+};
+
+#define MIMO_PS_STATIC 0
+#define MIMO_PS_DYNAMIC 1
+#define MIMO_PS_NOLIMIT 3
+
+struct rtl_dualmac_easy_concurrent_ctl {
+ enum band_type currentbandtype_backfordmdp;
+ bool close_bbandrf_for_dmsp;
+ bool change_to_dmdp;
+ bool change_to_dmsp;
+ bool switch_in_process;
+};
+
+struct rtl_dmsp_ctl {
+ bool activescan_for_slaveofdmsp;
+ bool scan_for_anothermac_fordmsp;
+ bool scan_for_itself_fordmsp;
+ bool writedig_for_anothermacofdmsp;
+ u32 curdigvalue_for_anothermacofdmsp;
+ bool changecckpdstate_for_anothermacofdmsp;
+ u8 curcckpdstate_for_anothermacofdmsp;
+ bool changetxhighpowerlvl_for_anothermacofdmsp;
+ u8 curtxhighlvl_for_anothermacofdmsp;
+ long rssivalmin_for_anothermacofdmsp;
+};
+
+struct ps_t {
+ u8 pre_ccastate;
+ u8 cur_ccasate;
+ u8 pre_rfstate;
+ u8 cur_rfstate;
+ u8 initialize;
+ long rssi_val_min;
+};
+
+struct dig_t {
+ u32 rssi_lowthresh;
+ u32 rssi_highthresh;
+ u32 fa_lowthresh;
+ u32 fa_highthresh;
+ long last_min_undec_pwdb_for_dm;
+ long rssi_highpower_lowthresh;
+ long rssi_highpower_highthresh;
+ u32 recover_cnt;
+ u32 pre_igvalue;
+ u32 cur_igvalue;
+ long rssi_val;
+ u8 dig_enable_flag;
+ u8 dig_ext_port_stage;
+ u8 dig_algorithm;
+ u8 dig_twoport_algorithm;
+ u8 dig_dbgmode;
+ u8 dig_slgorithm_switch;
+ u8 cursta_cstate;
+ u8 presta_cstate;
+ u8 curmultista_cstate;
+ u8 stop_dig;
+ s8 back_val;
+ s8 back_range_max;
+ s8 back_range_min;
+ u8 rx_gain_max;
+ u8 rx_gain_min;
+ u8 min_undec_pwdb_for_dm;
+ u8 rssi_val_min;
+ u8 pre_cck_cca_thres;
+ u8 cur_cck_cca_thres;
+ u8 pre_cck_pd_state;
+ u8 cur_cck_pd_state;
+ u8 pre_cck_fa_state;
+ u8 cur_cck_fa_state;
+ u8 pre_ccastate;
+ u8 cur_ccasate;
+ u8 large_fa_hit;
+ u8 forbidden_igi;
+ u8 dig_state;
+ u8 dig_highpwrstate;
+ u8 cur_sta_cstate;
+ u8 pre_sta_cstate;
+ u8 cur_ap_cstate;
+ u8 pre_ap_cstate;
+ u8 cur_pd_thstate;
+ u8 pre_pd_thstate;
+ u8 cur_cs_ratiostate;
+ u8 pre_cs_ratiostate;
+ u8 backoff_enable_flag;
+ s8 backoffval_range_max;
+ s8 backoffval_range_min;
+ u8 dig_min_0;
+ u8 dig_min_1;
+ u8 bt30_cur_igi;
+ bool media_connect_0;
+ bool media_connect_1;
+
+ u32 antdiv_rssi_max;
+ u32 rssi_max;
+};
+
+struct rtl_global_var {
+ /* from this list we can get
+ * other adapter's rtl_priv
+ */
+ struct list_head glb_priv_list;
+ spinlock_t glb_list_lock;
+};
+
+#define IN_4WAY_TIMEOUT_TIME (30 * MSEC_PER_SEC) /* 30 seconds */
+
+struct rtl_btc_info {
+ u8 bt_type;
+ u8 btcoexist;
+ u8 ant_num;
+ u8 single_ant_path;
+
+ u8 ap_num;
+ bool in_4way;
+ unsigned long in_4way_ts;
+};
+
+struct bt_coexist_info {
+ struct rtl_btc_ops *btc_ops;
+ struct rtl_btc_info btc_info;
+ /* btc context */
+ void *btc_context;
+ void *wifi_only_context;
+ /* EEPROM BT info. */
+ u8 eeprom_bt_coexist;
+ u8 eeprom_bt_type;
+ u8 eeprom_bt_ant_num;
+ u8 eeprom_bt_ant_isol;
+ u8 eeprom_bt_radio_shared;
+
+ u8 bt_coexistence;
+ u8 bt_ant_num;
+ u8 bt_coexist_type;
+ u8 bt_state;
+ u8 bt_cur_state; /* 0:on, 1:off */
+ u8 bt_ant_isolation; /* 0:good, 1:bad */
+ u8 bt_pape_ctrl; /* 0:SW, 1:SW/HW dynamic */
+ u8 bt_service;
+ u8 bt_radio_shared_type;
+ u8 bt_rfreg_origin_1e;
+ u8 bt_rfreg_origin_1f;
+ u8 bt_rssi_state;
+ u32 ratio_tx;
+ u32 ratio_pri;
+ u32 bt_edca_ul;
+ u32 bt_edca_dl;
+
+ bool init_set;
+ bool bt_busy_traffic;
+ bool bt_traffic_mode_set;
+ bool bt_non_traffic_mode_set;
+
+ bool fw_coexist_all_off;
+ bool sw_coexist_all_off;
+ bool hw_coexist_all_off;
+ u32 cstate;
+ u32 previous_state;
+ u32 cstate_h;
+ u32 previous_state_h;
+
+ u8 bt_pre_rssi_state;
+ u8 bt_pre_rssi_state1;
+
+ u8 reg_bt_iso;
+ u8 reg_bt_sco;
+ bool balance_on;
+ u8 bt_active_zero_cnt;
+ bool cur_bt_disabled;
+ bool pre_bt_disabled;
+
+ u8 bt_profile_case;
+ u8 bt_profile_action;
+ bool bt_busy;
+ bool hold_for_bt_operation;
+ u8 lps_counter;
+};
+
+struct rtl_btc_ops {
+ void (*btc_init_variables)(struct rtl_priv *rtlpriv);
+ void (*btc_init_variables_wifi_only)(struct rtl_priv *rtlpriv);
+ void (*btc_deinit_variables)(struct rtl_priv *rtlpriv);
+ void (*btc_init_hal_vars)(struct rtl_priv *rtlpriv);
+ void (*btc_power_on_setting)(struct rtl_priv *rtlpriv);
+ void (*btc_init_hw_config)(struct rtl_priv *rtlpriv);
+ void (*btc_init_hw_config_wifi_only)(struct rtl_priv *rtlpriv);
+ void (*btc_ips_notify)(struct rtl_priv *rtlpriv, u8 type);
+ void (*btc_lps_notify)(struct rtl_priv *rtlpriv, u8 type);
+ void (*btc_scan_notify)(struct rtl_priv *rtlpriv, u8 scantype);
+ void (*btc_scan_notify_wifi_only)(struct rtl_priv *rtlpriv,
+ u8 scantype);
+ void (*btc_connect_notify)(struct rtl_priv *rtlpriv, u8 action);
+ void (*btc_mediastatus_notify)(struct rtl_priv *rtlpriv,
+ enum rt_media_status mstatus);
+ void (*btc_periodical)(struct rtl_priv *rtlpriv);
+ void (*btc_halt_notify)(struct rtl_priv *rtlpriv);
+ void (*btc_btinfo_notify)(struct rtl_priv *rtlpriv,
+ u8 *tmp_buf, u8 length);
+ void (*btc_btmpinfo_notify)(struct rtl_priv *rtlpriv,
+ u8 *tmp_buf, u8 length);
+ bool (*btc_is_limited_dig)(struct rtl_priv *rtlpriv);
+ bool (*btc_is_disable_edca_turbo)(struct rtl_priv *rtlpriv);
+ bool (*btc_is_bt_disabled)(struct rtl_priv *rtlpriv);
+ void (*btc_special_packet_notify)(struct rtl_priv *rtlpriv,
+ u8 pkt_type);
+ void (*btc_switch_band_notify)(struct rtl_priv *rtlpriv, u8 type,
+ bool scanning);
+ void (*btc_switch_band_notify_wifi_only)(struct rtl_priv *rtlpriv,
+ u8 type, bool scanning);
+ void (*btc_display_bt_coex_info)(struct rtl_priv *rtlpriv,
+ struct seq_file *m);
+ void (*btc_record_pwr_mode)(struct rtl_priv *rtlpriv, u8 *buf, u8 len);
+ u8 (*btc_get_lps_val)(struct rtl_priv *rtlpriv);
+ u8 (*btc_get_rpwm_val)(struct rtl_priv *rtlpriv);
+ bool (*btc_is_bt_ctrl_lps)(struct rtl_priv *rtlpriv);
+ void (*btc_get_ampdu_cfg)(struct rtl_priv *rtlpriv, u8 *reject_agg,
+ u8 *ctrl_agg_size, u8 *agg_size);
+ bool (*btc_is_bt_lps_on)(struct rtl_priv *rtlpriv);
+};
+
+struct rtl_halmac_ops {
+ int (*halmac_init_adapter)(struct rtl_priv *);
+ int (*halmac_deinit_adapter)(struct rtl_priv *);
+ int (*halmac_init_hal)(struct rtl_priv *);
+ int (*halmac_deinit_hal)(struct rtl_priv *);
+ int (*halmac_poweron)(struct rtl_priv *);
+ int (*halmac_poweroff)(struct rtl_priv *);
+
+ int (*halmac_phy_power_switch)(struct rtl_priv *rtlpriv, u8 enable);
+ int (*halmac_set_mac_address)(struct rtl_priv *rtlpriv, u8 hwport,
+ u8 *addr);
+ int (*halmac_set_bssid)(struct rtl_priv *rtlpriv, u8 hwport, u8 *addr);
+
+ int (*halmac_get_physical_efuse_size)(struct rtl_priv *rtlpriv,
+ u32 *size);
+ int (*halmac_read_physical_efuse_map)(struct rtl_priv *rtlpriv,
+ u8 *map, u32 size);
+ int (*halmac_get_logical_efuse_size)(struct rtl_priv *rtlpriv,
+ u32 *size);
+ int (*halmac_read_logical_efuse_map)(struct rtl_priv *rtlpriv, u8 *map,
+ u32 size);
+
+ int (*halmac_set_bandwidth)(struct rtl_priv *rtlpriv, u8 channel,
+ u8 pri_ch_idx, u8 bw);
+
+ int (*halmac_c2h_handle)(struct rtl_priv *rtlpriv, u8 *c2h, u32 size);
+
+ int (*halmac_chk_txdesc)(struct rtl_priv *rtlpriv, u8 *txdesc,
+ u32 size);
+};
+
+struct rtl_halmac_indicator {
+ struct completion *comp;
+ u32 wait_ms;
+
+ u8 *buffer;
+ u32 buf_size;
+ u32 ret_size;
+ u32 status;
+};
+
+struct rtl_halmac {
+ struct rtl_halmac_ops *ops; /* halmac ops (halmac.ko own this object) */
+ void *internal; /* internal context of halmac, i.e. PHALMAC_ADAPTER */
+ struct rtl_halmac_indicator *indicator; /* size=10 */
+
+ /* flags */
+ /*
+ * send_general_info
+ * 0: no need to call halmac_send_general_info()
+ * 1: need to call halmac_send_general_info()
+ */
+ u8 send_general_info;
+};
+
+struct rtl_phydm_params {
+ u8 mp_chip; /* 1: MP chip, 0: test chip */
+ u8 fab_ver; /* 0: TSMC, 1: UMC, ...*/
+ u8 cut_ver; /* 0: A, 1: B, ..., 10: K */
+ u8 efuse0x3d7; /* default: 0xff */
+ u8 efuse0x3d8; /* default: 0xff */
+};
+
+struct rtl_phydm_ops {
+ /* init/deinit priv */
+ int (*phydm_init_priv)(struct rtl_priv *rtlpriv,
+ struct rtl_phydm_params *params);
+ int (*phydm_deinit_priv)(struct rtl_priv *rtlpriv);
+ bool (*phydm_load_txpower_by_rate)(struct rtl_priv *rtlpriv);
+ bool (*phydm_load_txpower_limit)(struct rtl_priv *rtlpriv);
+
+ /* init hw */
+ int (*phydm_init_dm)(struct rtl_priv *rtlpriv);
+ int (*phydm_deinit_dm)(struct rtl_priv *rtlpriv);
+ int (*phydm_reset_dm)(struct rtl_priv *rtlpriv);
+ bool (*phydm_parameter_init)(struct rtl_priv *rtlpriv, bool post);
+ bool (*phydm_phy_bb_config)(struct rtl_priv *rtlpriv);
+ bool (*phydm_phy_rf_config)(struct rtl_priv *rtlpriv);
+ bool (*phydm_phy_mac_config)(struct rtl_priv *rtlpriv);
+ bool (*phydm_trx_mode)(struct rtl_priv *rtlpriv,
+ enum radio_mask tx_path, enum radio_mask rx_path,
+ bool is_tx2_path);
+ /* watchdog */
+ bool (*phydm_watchdog)(struct rtl_priv *rtlpriv);
+
+ /* channel */
+ bool (*phydm_switch_band)(struct rtl_priv *rtlpriv, u8 central_ch);
+ bool (*phydm_switch_channel)(struct rtl_priv *rtlpriv, u8 central_ch);
+ bool (*phydm_switch_bandwidth)(struct rtl_priv *rtlpriv,
+ u8 primary_ch_idx,
+ enum ht_channel_width width);
+ bool (*phydm_iq_calibrate)(struct rtl_priv *rtlpriv);
+ bool (*phydm_clear_txpowertracking_state)(struct rtl_priv *rtlpriv);
+ bool (*phydm_pause_dig)(struct rtl_priv *rtlpriv, bool pause);
+
+ /* read/write reg */
+ u32 (*phydm_read_rf_reg)(struct rtl_priv *rtlpriv,
+ enum radio_path rfpath,
+ u32 addr, u32 mask);
+ bool (*phydm_write_rf_reg)(struct rtl_priv *rtlpriv,
+ enum radio_path rfpath,
+ u32 addr, u32 mask, u32 data);
+ u8 (*phydm_read_txagc)(struct rtl_priv *rtlpriv,
+ enum radio_path rfpath, u8 hw_rate);
+ bool (*phydm_write_txagc)(struct rtl_priv *rtlpriv, u32 power_index,
+ enum radio_path rfpath, u8 hw_rate);
+
+ /* RX */
+ bool (*phydm_c2h_content_parsing)(struct rtl_priv *rtlpriv, u8 cmd_id,
+ u8 cmd_len, u8 *content);
+ bool (*phydm_query_phy_status)(struct rtl_priv *rtlpriv, u8 *phystrpt,
+ struct ieee80211_hdr *hdr,
+ struct rtl_stats *pstatus);
+
+ /* TX */
+ u8 (*phydm_rate_id_mapping)(struct rtl_priv *rtlpriv,
+ enum wireless_mode wireless_mode,
+ enum rf_type rf_type,
+ enum ht_channel_width bw);
+ bool (*phydm_get_ra_bitmap)(struct rtl_priv *rtlpriv,
+ enum wireless_mode wireless_mode,
+ enum rf_type rf_type,
+ enum ht_channel_width bw,
+ u8 tx_rate_level, /* 0~6 */
+ u32 *tx_bitmap_msb,
+ u32 *tx_bitmap_lsb);
+
+ /* STA */
+ bool (*phydm_add_sta)(struct rtl_priv *rtlpriv,
+ struct ieee80211_sta *sta);
+ bool (*phydm_del_sta)(struct rtl_priv *rtlpriv,
+ struct ieee80211_sta *sta);
+
+ /* BTC */
+ u32 (*phydm_get_version)(struct rtl_priv *rtlpriv);
+ bool (*phydm_modify_ra_pcr_threshold)(struct rtl_priv *rtlpriv,
+ u8 ra_offset_direction,
+ u8 ra_threshold_offset);
+ u32 (*phydm_query_counter)(struct rtl_priv *rtlpriv,
+ const char *info_type);
+
+ /* debug */
+ bool (*phydm_debug_cmd)(struct rtl_priv *rtlpriv, char *in, u32 in_len,
+ char *out, u32 out_len);
+
+};
+
+struct rtl_phydm {
+ struct rtl_phydm_ops *ops;/* phydm ops (phydm_mod.ko own this object) */
+ void *internal; /* internal context of phydm, i.e. PHY_DM_STRUCT */
+
+ u8 adaptivity_en;
+ /* debug */
+ u16 forced_data_rate;
+ u8 forced_igi_lb;
+ u8 antenna_test;
+};
+
+struct proxim {
+ bool proxim_on;
+
+ void *proximity_priv;
+ int (*proxim_rx)(struct ieee80211_hw *hw, struct rtl_stats *status,
+ struct sk_buff *skb);
+ u8 (*proxim_get_var)(struct ieee80211_hw *hw, u8 type);
+};
+
+struct rtl_c2hcmd {
+ struct list_head list;
+ u8 tag;
+ u8 len;
+ u8 *val;
+};
+
+struct rtl_bssid_entry {
+ struct list_head list;
+ u8 bssid[ETH_ALEN];
+ u32 age;
+};
+
+struct rtl_scan_list {
+ int num;
+ struct list_head list; /* sort by age */
+};
+
+struct rtl_priv {
+ struct ieee80211_hw *hw;
+ struct completion firmware_loading_complete;
+ struct list_head list;
+ struct rtl_priv *buddy_priv;
+ struct rtl_global_var *glb_var;
+ struct rtl_dualmac_easy_concurrent_ctl easy_concurrent_ctl;
+ struct rtl_dmsp_ctl dmsp_ctl;
+ struct rtl_locks locks;
+ struct rtl_works works;
+ struct rtl_mac mac80211;
+ struct rtl_hal rtlhal;
+ struct rtl_regulatory regd;
+ struct rtl_rfkill rfkill;
+ struct rtl_io io;
+ struct rtl_phy phy;
+ struct rtl_dm dm;
+ struct rtl_security sec;
+ struct rtl_efuse efuse;
+ struct rtl_led_ctl ledctl;
+ struct rtl_tx_report tx_report;
+ struct rtl_scan_list scan_list;
+ struct rtl_ps_ctl psc;
+ struct rate_adaptive ra;
+ struct dynamic_primary_cca primarycca;
+ struct wireless_stats stats;
+ struct rt_link_detect link_info;
+ struct false_alarm_statistics falsealm_cnt;
+ struct rtl_rate_priv *rate_priv;
+ /* sta entry list for ap adhoc or mesh */
+ struct list_head entry_list;
+ /* c2hcmd list for kthread level access */
+ struct list_head c2hcmd_list;
+ struct rtl_debug dbg;
+ int max_fw_size;
+
+ /*hal_cfg : for diff cards
+ *intf_ops : for diff interface usb/pcie
+ */
+ struct rtl_hal_cfg *cfg;
+ const struct rtl_intf_ops *intf_ops;
+
+ /* this var will be set by set_bit,
+ * and was used to indicate status of
+ * interface or hardware
+ */
+ unsigned long status;
+
+ /* tables for dm */
+ struct dig_t dm_digtable;
+ struct ps_t dm_pstable;
+
+ u32 reg_874;
+ u32 reg_c70;
+ u32 reg_85c;
+ u32 reg_a74;
+ bool reg_init; /* true if regs saved */
+ bool bt_operation_on;
+ __le32 *usb_data;
+ int usb_data_index;
+ bool initialized;
+ bool enter_ps; /* true when entering PS */
+ u8 rate_mask[5];
+
+ /* intel Proximity, should be alloc mem
+ * in intel Proximity module and can only
+ * be used in intel Proximity mode
+ */
+ struct proxim proximity;
+
+ /*for bt coexist use*/
+ struct bt_coexist_info btcoexist;
+
+ /* halmac for newer IC. (e.g. 8822B) */
+ struct rtl_halmac halmac;
+
+ /* phydm for newer IC. (e.g. 8822B) */
+ struct rtl_phydm phydm;
+
+ /* separate 92ee from other ICs,
+ * 92ee use new trx flow.
+ */
+ bool use_new_trx_flow;
+
+#ifdef CONFIG_PM
+ struct wiphy_wowlan_support wowlan;
+#endif
+ /* This must be the last item so
+ * that it points to the data allocated
+ * beyond this structure like:
+ * rtl_pci_priv or rtl_usb_priv
+ */
+ u8 priv[0] __aligned(sizeof(void *));
+};
+
+#define rtl_priv(hw) (((struct rtl_priv *)(hw)->priv))
+#define rtl_mac(rtlpriv) (&((rtlpriv)->mac80211))
+#define rtl_hal(rtlpriv) (&((rtlpriv)->rtlhal))
+#define rtl_efuse(rtlpriv) (&((rtlpriv)->efuse))
+#define rtl_psc(rtlpriv) (&((rtlpriv)->psc))
+
+/***************************************
+ * Bluetooth Co-existence Related
+ ***************************************/
+
+enum bt_ant_num {
+ ANT_X2 = 0,
+ ANT_X1 = 1,
+};
+
+enum bt_co_type {
+ BT_2WIRE = 0,
+ BT_ISSC_3WIRE = 1,
+ BT_ACCEL = 2,
+ BT_CSR_BC4 = 3,
+ BT_CSR_BC8 = 4,
+ BT_RTL8756 = 5,
+ BT_RTL8723A = 6,
+ BT_RTL8821A = 7,
+ BT_RTL8723B = 8,
+ BT_RTL8192E = 9,
+ BT_RTL8812A = 11,
+ BT_RTL8822B = 12,
+};
+
+enum bt_total_ant_num {
+ ANT_TOTAL_X2 = 0,
+ ANT_TOTAL_X1 = 1
+};
+
+enum bt_cur_state {
+ BT_OFF = 0,
+ BT_ON = 1,
+};
+
+enum bt_service_type {
+ BT_SCO = 0,
+ BT_A2DP = 1,
+ BT_HID = 2,
+ BT_HID_IDLE = 3,
+ BT_SCAN = 4,
+ BT_IDLE = 5,
+ BT_OTHER_ACTION = 6,
+ BT_BUSY = 7,
+ BT_OTHERBUSY = 8,
+ BT_PAN = 9,
+};
+
+enum bt_radio_shared {
+ BT_RADIO_SHARED = 0,
+ BT_RADIO_INDIVIDUAL = 1,
+};
+
+/****************************************
+ * mem access macro define start
+ * Call endian free function when
+ * 1. Read/write packet content.
+ * 2. Before write integer to IO.
+ * 3. After read integer from IO.
+ ***************************************/
+/* Convert little data endian to host ordering */
+#define EF1BYTE(_val) \
+ ((u8)(_val))
+#define EF2BYTE(_val) \
+ (le16_to_cpu(_val))
+#define EF4BYTE(_val) \
+ (le32_to_cpu(_val))
+
+/* Read data from memory */
+#define READEF1BYTE(_ptr) \
+ EF1BYTE(*((u8 *)(_ptr)))
+/* Read le16 data from memory and convert to host ordering */
+#define READEF2BYTE(_ptr) \
+ EF2BYTE(*(_ptr))
+#define READEF4BYTE(_ptr) \
+ EF4BYTE(*(_ptr))
+
+/* Create a bit mask
+ * Examples:
+ * BIT_LEN_MASK_32(0) => 0x00000000
+ * BIT_LEN_MASK_32(1) => 0x00000001
+ * BIT_LEN_MASK_32(2) => 0x00000003
+ * BIT_LEN_MASK_32(32) => 0xFFFFFFFF
+ */
+#define BIT_LEN_MASK_32(__bitlen) \
+ (0xFFFFFFFF >> (32 - (__bitlen)))
+#define BIT_LEN_MASK_16(__bitlen) \
+ (0xFFFF >> (16 - (__bitlen)))
+#define BIT_LEN_MASK_8(__bitlen) \
+ (0xFF >> (8 - (__bitlen)))
+
+/* Create an offset bit mask
+ * Examples:
+ * BIT_OFFSET_LEN_MASK_32(0, 2) => 0x00000003
+ * BIT_OFFSET_LEN_MASK_32(16, 2) => 0x00030000
+ */
+#define BIT_OFFSET_LEN_MASK_32(__bitoffset, __bitlen) \
+ (BIT_LEN_MASK_32(__bitlen) << (__bitoffset))
+#define BIT_OFFSET_LEN_MASK_16(__bitoffset, __bitlen) \
+ (BIT_LEN_MASK_16(__bitlen) << (__bitoffset))
+#define BIT_OFFSET_LEN_MASK_8(__bitoffset, __bitlen) \
+ (BIT_LEN_MASK_8(__bitlen) << (__bitoffset))
+
+/*Description:
+ * Return 4-byte value in host byte ordering from
+ * 4-byte pointer in little-endian system.
+ */
+#define LE_P4BYTE_TO_HOST_4BYTE(__pstart) \
+ (EF4BYTE(*((__le32 *)(__pstart))))
+#define LE_P2BYTE_TO_HOST_2BYTE(__pstart) \
+ (EF2BYTE(*((__le16 *)(__pstart))))
+#define LE_P1BYTE_TO_HOST_1BYTE(__pstart) \
+ (EF1BYTE(*((u8 *)(__pstart))))
+
+/* Description:
+ * Translate subfield (continuous bits in little-endian) of 4-byte
+ * value to host byte ordering.
+ */
+#define LE_BITS_TO_4BYTE(__pstart, __bitoffset, __bitlen) \
+ ( \
+ (LE_P4BYTE_TO_HOST_4BYTE(__pstart) >> (__bitoffset)) & \
+ BIT_LEN_MASK_32(__bitlen) \
+ )
+#define LE_BITS_TO_2BYTE(__pstart, __bitoffset, __bitlen) \
+ ( \
+ (LE_P2BYTE_TO_HOST_2BYTE(__pstart) >> (__bitoffset)) & \
+ BIT_LEN_MASK_16(__bitlen) \
+ )
+#define LE_BITS_TO_1BYTE(__pstart, __bitoffset, __bitlen) \
+ ( \
+ (LE_P1BYTE_TO_HOST_1BYTE(__pstart) >> (__bitoffset)) & \
+ BIT_LEN_MASK_8(__bitlen) \
+ )
+
+/* Description:
+ * Mask subfield (continuous bits in little-endian) of 4-byte value
+ * and return the result in 4-byte value in host byte ordering.
+ */
+#define LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) \
+ ( \
+ LE_P4BYTE_TO_HOST_4BYTE(__pstart) & \
+ (~BIT_OFFSET_LEN_MASK_32(__bitoffset, __bitlen)) \
+ )
+#define LE_BITS_CLEARED_TO_2BYTE(__pstart, __bitoffset, __bitlen) \
+ ( \
+ LE_P2BYTE_TO_HOST_2BYTE(__pstart) & \
+ (~BIT_OFFSET_LEN_MASK_16(__bitoffset, __bitlen)) \
+ )
+#define LE_BITS_CLEARED_TO_1BYTE(__pstart, __bitoffset, __bitlen) \
+ ( \
+ LE_P1BYTE_TO_HOST_1BYTE(__pstart) & \
+ (~BIT_OFFSET_LEN_MASK_8(__bitoffset, __bitlen)) \
+ )
+
+/* Description:
+ * Set subfield of little-endian 4-byte value to specified value.
+ */
+#define SET_BITS_TO_LE_4BYTE(__pstart, __bitoffset, __bitlen, __val) \
+ (*((__le32 *)(__pstart)) = \
+ cpu_to_le32( \
+ LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) | \
+ ((((u32)__val) & BIT_LEN_MASK_32(__bitlen)) << (__bitoffset)) \
+ ))
+#define SET_BITS_TO_LE_2BYTE(__pstart, __bitoffset, __bitlen, __val) \
+ (*((__le16 *)(__pstart)) = \
+ cpu_to_le16( \
+ LE_BITS_CLEARED_TO_2BYTE(__pstart, __bitoffset, __bitlen) | \
+ ((((u16)__val) & BIT_LEN_MASK_16(__bitlen)) << (__bitoffset)) \
+ ))
+#define SET_BITS_TO_LE_1BYTE(__pstart, __bitoffset, __bitlen, __val) \
+ (*((u8 *)(__pstart)) = EF1BYTE \
+ ( \
+ LE_BITS_CLEARED_TO_1BYTE(__pstart, __bitoffset, __bitlen) | \
+ ((((u8)__val) & BIT_LEN_MASK_8(__bitlen)) << (__bitoffset)) \
+ ))
+
+#define N_BYTE_ALIGNMENT(__value, __alignment) ((__alignment == 1) ? \
+ (__value) : (((__value + __alignment - 1) / \
+ __alignment) * __alignment))
+
+/****************************************
+ * mem access macro define end
+ ****************************************/
+
+#define byte(x, n) ((x >> (8 * n)) & 0xff)
+
+#define packet_get_type(_packet) (EF1BYTE((_packet).octet[0]) & 0xFC)
+#define RTL_WATCH_DOG_TIME 2000
+#define MSECS(t) msecs_to_jiffies(t)
+#define WLAN_FC_GET_VERS(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_VERS)
+#define WLAN_FC_GET_TYPE(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE)
+#define WLAN_FC_GET_STYPE(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE)
+#define WLAN_FC_MORE_DATA(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_MOREDATA)
+#define rtl_dm(rtlpriv) (&((rtlpriv)->dm))
+
+#define RT_RF_OFF_LEVL_ASPM BIT(0) /*PCI ASPM */
+#define RT_RF_OFF_LEVL_CLK_REQ BIT(1) /*PCI clock request */
+#define RT_RF_OFF_LEVL_PCI_D3 BIT(2) /*PCI D3 mode */
+/*NIC halt, re-initialize hw parameters*/
+#define RT_RF_OFF_LEVL_HALT_NIC BIT(3)
+#define RT_RF_OFF_LEVL_FREE_FW BIT(4) /*FW free, re-download the FW */
+#define RT_RF_OFF_LEVL_FW_32K BIT(5) /*FW in 32k */
+/*Always enable ASPM and Clock Req in initialization.*/
+#define RT_RF_PS_LEVEL_ALWAYS_ASPM BIT(6)
+/* no matter RFOFF or SLEEP we set PS_ASPM_LEVL*/
+#define RT_PS_LEVEL_ASPM BIT(7)
+/*When LPS is on, disable 2R if no packet is received or transmitted.*/
+#define RT_RF_LPS_DISALBE_2R BIT(30)
+#define RT_RF_LPS_LEVEL_ASPM BIT(31) /*LPS with ASPM */
+#define RT_IN_PS_LEVEL(ppsc, _ps_flg) \
+ ((ppsc->cur_ps_level & _ps_flg) ? true : false)
+#define RT_CLEAR_PS_LEVEL(ppsc, _ps_flg) \
+ (ppsc->cur_ps_level &= (~(_ps_flg)))
+#define RT_SET_PS_LEVEL(ppsc, _ps_flg) \
+ (ppsc->cur_ps_level |= _ps_flg)
+
+#define container_of_dwork_rtl(x, y, z) \
+ container_of(to_delayed_work(x), y, z)
+
+#define FILL_OCTET_STRING(_os, _octet, _len) \
+ (_os).octet = (u8 *)(_octet); \
+ (_os).length = (_len)
+
+#define CP_MACADDR(des, src) \
+ ((des)[0] = (src)[0], (des)[1] = (src)[1],\
+ (des)[2] = (src)[2], (des)[3] = (src)[3],\
+ (des)[4] = (src)[4], (des)[5] = (src)[5])
+
+#define LDPC_HT_ENABLE_RX BIT(0)
+#define LDPC_HT_ENABLE_TX BIT(1)
+#define LDPC_HT_TEST_TX_ENABLE BIT(2)
+#define LDPC_HT_CAP_TX BIT(3)
+
+#define STBC_HT_ENABLE_RX BIT(0)
+#define STBC_HT_ENABLE_TX BIT(1)
+#define STBC_HT_TEST_TX_ENABLE BIT(2)
+#define STBC_HT_CAP_TX BIT(3)
+
+#define LDPC_VHT_ENABLE_RX BIT(0)
+#define LDPC_VHT_ENABLE_TX BIT(1)
+#define LDPC_VHT_TEST_TX_ENABLE BIT(2)
+#define LDPC_VHT_CAP_TX BIT(3)
+
+#define STBC_VHT_ENABLE_RX BIT(0)
+#define STBC_VHT_ENABLE_TX BIT(1)
+#define STBC_VHT_TEST_TX_ENABLE BIT(2)
+#define STBC_VHT_CAP_TX BIT(3)
+
+extern u8 channel5g[CHANNEL_MAX_NUMBER_5G];
+
+extern u8 channel5g_80m[CHANNEL_MAX_NUMBER_5G_80M];
+
+static inline u8 rtl_read_byte(struct rtl_priv *rtlpriv, u32 addr)
+{
+ return rtlpriv->io.read8_sync(rtlpriv, addr);
+}
+
+static inline u16 rtl_read_word(struct rtl_priv *rtlpriv, u32 addr)
+{
+ return rtlpriv->io.read16_sync(rtlpriv, addr);
+}
+
+static inline u32 rtl_read_dword(struct rtl_priv *rtlpriv, u32 addr)
+{
+ return rtlpriv->io.read32_sync(rtlpriv, addr);
+}
+
+static inline void rtl_write_byte(struct rtl_priv *rtlpriv, u32 addr, u8 val8)
+{
+ rtlpriv->io.write8_async(rtlpriv, addr, val8);
+
+ if (rtlpriv->cfg->write_readback)
+ rtlpriv->io.read8_sync(rtlpriv, addr);
+}
+
+static inline void rtl_write_byte_with_val32(struct ieee80211_hw *hw,
+ u32 addr, u32 val8)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtl_write_byte(rtlpriv, addr, (u8)val8);
+}
+
+static inline void rtl_write_word(struct rtl_priv *rtlpriv, u32 addr, u16 val16)
+{
+ rtlpriv->io.write16_async(rtlpriv, addr, val16);
+
+ if (rtlpriv->cfg->write_readback)
+ rtlpriv->io.read16_sync(rtlpriv, addr);
+}
+
+static inline void rtl_write_dword(struct rtl_priv *rtlpriv,
+ u32 addr, u32 val32)
+{
+ rtlpriv->io.write32_async(rtlpriv, addr, val32);
+
+ if (rtlpriv->cfg->write_readback)
+ rtlpriv->io.read32_sync(rtlpriv, addr);
+}
+
+static inline u32 rtl_get_bbreg(struct ieee80211_hw *hw,
+ u32 regaddr, u32 bitmask)
+{
+ struct rtl_priv *rtlpriv = hw->priv;
+
+ return rtlpriv->cfg->ops->get_bbreg(hw, regaddr, bitmask);
+}
+
+static inline void rtl_set_bbreg(struct ieee80211_hw *hw, u32 regaddr,
+ u32 bitmask, u32 data)
+{
+ struct rtl_priv *rtlpriv = hw->priv;
+
+ rtlpriv->cfg->ops->set_bbreg(hw, regaddr, bitmask, data);
+}
+
+static inline void rtl_set_bbreg_with_dwmask(struct ieee80211_hw *hw,
+ u32 regaddr, u32 data)
+{
+ rtl_set_bbreg(hw, regaddr, 0xffffffff, data);
+}
+
+static inline u32 rtl_get_rfreg(struct ieee80211_hw *hw,
+ enum radio_path rfpath, u32 regaddr,
+ u32 bitmask)
+{
+ struct rtl_priv *rtlpriv = hw->priv;
+
+ return rtlpriv->cfg->ops->get_rfreg(hw, rfpath, regaddr, bitmask);
+}
+
+static inline void rtl_set_rfreg(struct ieee80211_hw *hw,
+ enum radio_path rfpath, u32 regaddr,
+ u32 bitmask, u32 data)
+{
+ struct rtl_priv *rtlpriv = hw->priv;
+
+ rtlpriv->cfg->ops->set_rfreg(hw, rfpath, regaddr, bitmask, data);
+}
+
+static inline bool is_hal_stop(struct rtl_hal *rtlhal)
+{
+ return (rtlhal->state == _HAL_STATE_STOP);
+}
+
+static inline void set_hal_start(struct rtl_hal *rtlhal)
+{
+ rtlhal->state = _HAL_STATE_START;
+}
+
+static inline void set_hal_stop(struct rtl_hal *rtlhal)
+{
+ rtlhal->state = _HAL_STATE_STOP;
+}
+
+static inline u8 get_rf_type(struct rtl_phy *rtlphy)
+{
+ return rtlphy->rf_type;
+}
+
+static inline struct ieee80211_hdr *rtl_get_hdr(struct sk_buff *skb)
+{
+ return (struct ieee80211_hdr *)(skb->data);
+}
+
+static inline __le16 rtl_get_fc(struct sk_buff *skb)
+{
+ return rtl_get_hdr(skb)->frame_control;
+}
+
+static inline u16 rtl_get_tid_h(struct ieee80211_hdr *hdr)
+{
+ return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK;
+}
+
+static inline u16 rtl_get_tid(struct sk_buff *skb)
+{
+ return rtl_get_tid_h(rtl_get_hdr(skb));
+}
+
+static inline struct ieee80211_sta *get_sta(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ const u8 *bssid)
+{
+ return ieee80211_find_sta(vif, bssid);
+}
+
+static inline struct ieee80211_sta *rtl_find_sta(struct ieee80211_hw *hw,
+ u8 *mac_addr)
+{
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+ return ieee80211_find_sta(mac->vif, mac_addr);
+}
+
+#endif
diff --git a/drivers/staging/rts5208/ms.c b/drivers/staging/rts5208/ms.c
index 482a29d..7cdce87 100644
--- a/drivers/staging/rts5208/ms.c
+++ b/drivers/staging/rts5208/ms.c
@@ -3064,7 +3064,8 @@ static int mspro_rw_multi_sector(struct scsi_cmnd *srb,
if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
chip->rw_need_retry = 0;
- dev_dbg(rtsx_dev(chip), "No card exist, exit mspro_rw_multi_sector\n");
+ dev_dbg(rtsx_dev(chip), "No card exist, exit %s\n",
+ __func__);
rtsx_trace(chip);
return STATUS_FAIL;
}
@@ -3101,7 +3102,7 @@ static int mspro_read_format_progress(struct rtsx_chip *chip,
u8 cnt, tmp;
u8 data[8];
- dev_dbg(rtsx_dev(chip), "mspro_read_format_progress, short_data_len = %d\n",
+ dev_dbg(rtsx_dev(chip), "%s, short_data_len = %d\n", __func__,
short_data_len);
retval = ms_switch_clock(chip);
diff --git a/drivers/staging/rts5208/rtsx.c b/drivers/staging/rts5208/rtsx.c
index b8177f5..53748d6 100644
--- a/drivers/staging/rts5208/rtsx.c
+++ b/drivers/staging/rts5208/rtsx.c
@@ -999,7 +999,7 @@ static int rtsx_probe(struct pci_dev *pci,
/* We come here if there are any problems */
errout:
- dev_err(&pci->dev, "rtsx_probe() failed\n");
+ dev_err(&pci->dev, "%s failed\n", __func__);
release_everything(dev);
return err;
@@ -1009,7 +1009,7 @@ static void rtsx_remove(struct pci_dev *pci)
{
struct rtsx_dev *dev = pci_get_drvdata(pci);
- dev_info(&pci->dev, "rtsx_remove() called\n");
+ dev_info(&pci->dev, "%s called\n", __func__);
quiesce_and_remove_host(dev);
release_everything(dev);
diff --git a/drivers/staging/rts5208/rtsx_chip.c b/drivers/staging/rts5208/rtsx_chip.c
index 7f4107b..4ad472d 100644
--- a/drivers/staging/rts5208/rtsx_chip.c
+++ b/drivers/staging/rts5208/rtsx_chip.c
@@ -616,8 +616,8 @@ int rtsx_reset_chip(struct rtsx_chip *chip)
else
retval = rtsx_pre_handle_sdio_new(chip);
- dev_dbg(rtsx_dev(chip), "chip->need_reset = 0x%x (rtsx_reset_chip)\n",
- (unsigned int)(chip->need_reset));
+ dev_dbg(rtsx_dev(chip), "chip->need_reset = 0x%x (%s)\n",
+ (unsigned int)(chip->need_reset), __func__);
#else /* HW_AUTO_SWITCH_SD_BUS */
retval = rtsx_pre_handle_sdio_old(chip);
#endif /* HW_AUTO_SWITCH_SD_BUS */
diff --git a/drivers/staging/rts5208/rtsx_scsi.c b/drivers/staging/rts5208/rtsx_scsi.c
index 36b5a11..a401b13 100644
--- a/drivers/staging/rts5208/rtsx_scsi.c
+++ b/drivers/staging/rts5208/rtsx_scsi.c
@@ -414,7 +414,7 @@ void set_sense_data(struct rtsx_chip *chip, unsigned int lun, u8 err_code,
sense->ascq = ascq;
if (sns_key_info0 != 0) {
sense->sns_key_info[0] = SKSV | sns_key_info0;
- sense->sns_key_info[1] = (sns_key_info1 & 0xf0) >> 8;
+ sense->sns_key_info[1] = (sns_key_info1 & 0xf0) >> 4;
sense->sns_key_info[2] = sns_key_info1 & 0x0f;
}
}
diff --git a/drivers/staging/rts5208/sd.c b/drivers/staging/rts5208/sd.c
index c2eb072..4033a2c 100644
--- a/drivers/staging/rts5208/sd.c
+++ b/drivers/staging/rts5208/sd.c
@@ -910,8 +910,8 @@ static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir)
int retval;
bool ddr_rx = false;
- dev_dbg(rtsx_dev(chip), "sd_change_phase (sample_point = %d, tune_dir = %d)\n",
- sample_point, tune_dir);
+ dev_dbg(rtsx_dev(chip), "%s (sample_point = %d, tune_dir = %d)\n",
+ __func__, sample_point, tune_dir);
if (tune_dir == TUNE_RX) {
SD_VP_CTL = SD_VPRX_CTL;
@@ -1225,8 +1225,8 @@ static int sd_check_switch_mode(struct rtsx_chip *chip, u8 mode, u8 func_group,
int retval;
u8 cmd[5], buf[64];
- dev_dbg(rtsx_dev(chip), "sd_check_switch_mode (mode = %d, func_group = %d, func_to_switch = %d)\n",
- mode, func_group, func_to_switch);
+ dev_dbg(rtsx_dev(chip), "%s (mode = %d, func_group = %d, func_to_switch = %d)\n",
+ __func__, mode, func_group, func_to_switch);
cmd[0] = 0x40 | SWITCH;
cmd[1] = mode;
@@ -1654,7 +1654,7 @@ static int sd_ddr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point)
return STATUS_SUCCESS;
}
-static int mmc_ddr_tunning_rx_cmd(struct rtsx_chip *chip, u8 sample_point)
+static int mmc_ddr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point)
{
struct sd_info *sd_card = &chip->sd_card;
int retval;
@@ -1933,7 +1933,7 @@ static int sd_tuning_rx(struct rtsx_chip *chip)
} else {
if (CHK_MMC_DDR52(sd_card)) {
- tuning_cmd = mmc_ddr_tunning_rx_cmd;
+ tuning_cmd = mmc_ddr_tuning_rx_cmd;
} else {
rtsx_trace(chip);
return STATUS_FAIL;
@@ -3575,8 +3575,8 @@ static int reset_mmc_only(struct rtsx_chip *chip)
return STATUS_FAIL;
}
- dev_dbg(rtsx_dev(chip), "In reset_mmc_only, sd_card->sd_type = 0x%x\n",
- sd_card->sd_type);
+ dev_dbg(rtsx_dev(chip), "In %s, sd_card->sd_type = 0x%x\n",
+ __func__, sd_card->sd_type);
return STATUS_SUCCESS;
}
@@ -3699,11 +3699,11 @@ int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector,
int retval;
if (srb->sc_data_direction == DMA_FROM_DEVICE) {
- dev_dbg(rtsx_dev(chip), "sd_rw: Read %d %s from 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "%s: Read %d %s from 0x%x\n", __func__,
sector_cnt, (sector_cnt > 1) ? "sectors" : "sector",
start_sector);
} else {
- dev_dbg(rtsx_dev(chip), "sd_rw: Write %d %s to 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "%s: Write %d %s to 0x%x\n", __func__,
sector_cnt, (sector_cnt > 1) ? "sectors" : "sector",
start_sector);
}
@@ -3921,7 +3921,8 @@ int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector,
rtsx_clear_sd_error(chip);
if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
chip->rw_need_retry = 0;
- dev_dbg(rtsx_dev(chip), "No card exist, exit sd_rw\n");
+ dev_dbg(rtsx_dev(chip), "No card exist, exit %s\n",
+ __func__);
rtsx_trace(chip);
return STATUS_FAIL;
}
@@ -3964,7 +3965,7 @@ RW_FAIL:
if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
chip->rw_need_retry = 0;
- dev_dbg(rtsx_dev(chip), "No card exist, exit sd_rw\n");
+ dev_dbg(rtsx_dev(chip), "No card exist, exit %s\n", __func__);
rtsx_trace(chip);
return STATUS_FAIL;
}
diff --git a/drivers/staging/rts5208/spi.c b/drivers/staging/rts5208/spi.c
index 8b8cd95..b5646b6 100644
--- a/drivers/staging/rts5208/spi.c
+++ b/drivers/staging/rts5208/spi.c
@@ -520,7 +520,7 @@ int spi_get_status(struct scsi_cmnd *srb, struct rtsx_chip *chip)
{
struct spi_info *spi = &chip->spi;
- dev_dbg(rtsx_dev(chip), "spi_get_status: err_code = 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "%s: err_code = 0x%x\n", __func__,
spi->err_code);
rtsx_stor_set_xfer_buf(&spi->err_code,
min_t(int, scsi_bufflen(srb), 1), srb);
@@ -543,8 +543,10 @@ int spi_set_parameter(struct scsi_cmnd *srb, struct rtsx_chip *chip)
spi->clk_div = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5];
spi->write_en = srb->cmnd[6];
- dev_dbg(rtsx_dev(chip), "spi_set_parameter: spi_clock = %d, clk_div = %d, write_en = %d\n",
- spi->spi_clock, spi->clk_div, spi->write_en);
+ dev_dbg(rtsx_dev(chip), "%s: ", __func__);
+ dev_dbg(rtsx_dev(chip), "spi_clock = %d, ", spi->spi_clock);
+ dev_dbg(rtsx_dev(chip), "clk_div = %d, ", spi->clk_div);
+ dev_dbg(rtsx_dev(chip), "write_en = %d\n", spi->write_en);
return STATUS_SUCCESS;
}
diff --git a/drivers/staging/rts5208/xd.c b/drivers/staging/rts5208/xd.c
index 74d36f9..11ea0c6 100644
--- a/drivers/staging/rts5208/xd.c
+++ b/drivers/staging/rts5208/xd.c
@@ -885,7 +885,7 @@ static int xd_init_l2p_tbl(struct rtsx_chip *chip)
struct xd_info *xd_card = &chip->xd_card;
int size, i;
- dev_dbg(rtsx_dev(chip), "xd_init_l2p_tbl: zone_cnt = %d\n",
+ dev_dbg(rtsx_dev(chip), "%s: zone_cnt = %d\n", __func__,
xd_card->zone_cnt);
if (xd_card->zone_cnt < 1) {
@@ -1026,7 +1026,8 @@ static u32 xd_get_l2p_tbl(struct rtsx_chip *chip, int zone_no, u16 log_off)
#ifdef XD_DELAY_WRITE
retval = xd_delay_write(chip);
if (retval != STATUS_SUCCESS) {
- dev_dbg(rtsx_dev(chip), "In xd_get_l2p_tbl, delay write fail!\n");
+ dev_dbg(rtsx_dev(chip), "In %s, delay write fail!\n",
+ __func__);
return BLK_NOT_FOUND;
}
#endif
@@ -1434,7 +1435,7 @@ static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no)
u16 cur_lst_page_logoff, ent_lst_page_logoff;
u8 redunt[11];
- dev_dbg(rtsx_dev(chip), "xd_build_l2p_tbl: %d\n", zone_no);
+ dev_dbg(rtsx_dev(chip), "%s: %d\n", __func__, zone_no);
if (!xd_card->zone) {
retval = xd_init_l2p_tbl(chip);
@@ -1774,8 +1775,10 @@ static int xd_finish_write(struct rtsx_chip *chip,
int retval, zone_no;
u16 log_off;
- dev_dbg(rtsx_dev(chip), "xd_finish_write, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x\n",
- old_blk, new_blk, log_blk);
+ dev_dbg(rtsx_dev(chip), "%s ", __func__);
+ dev_dbg(rtsx_dev(chip), "old_blk = 0x%x, ", old_blk);
+ dev_dbg(rtsx_dev(chip), "new_blk = 0x%x, ", new_blk);
+ dev_dbg(rtsx_dev(chip), "log_blk = 0x%x\n", log_blk);
if (page_off > xd_card->page_off) {
rtsx_trace(chip);
@@ -1960,7 +1963,7 @@ int xd_delay_write(struct rtsx_chip *chip)
int retval;
if (delay_write->delay_write_flag) {
- dev_dbg(rtsx_dev(chip), "xd_delay_write\n");
+ dev_dbg(rtsx_dev(chip), "%s\n", __func__);
retval = xd_switch_clock(chip);
if (retval != STATUS_SUCCESS) {
rtsx_trace(chip);
@@ -2002,7 +2005,7 @@ int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip,
xd_card->cleanup_counter = 0;
- dev_dbg(rtsx_dev(chip), "xd_rw: scsi_sg_count = %d\n",
+ dev_dbg(rtsx_dev(chip), "%s: scsi_sg_count = %d\n", __func__,
scsi_sg_count(srb));
ptr = (u8 *)scsi_sglist(srb);
diff --git a/drivers/staging/skein/skein_block.c b/drivers/staging/skein/skein_block.c
index 2566570..3bc25e1 100644
--- a/drivers/staging/skein/skein_block.c
+++ b/drivers/staging/skein/skein_block.c
@@ -21,329 +21,6 @@
#include "skein_base.h"
#include "skein_block.h"
-#ifndef SKEIN_USE_ASM
-#define SKEIN_USE_ASM (0) /* default is all C code (no ASM) */
-#endif
-
-#ifndef SKEIN_LOOP
-#define SKEIN_LOOP 001 /* default: unroll 256 and 512, but not 1024 */
-#endif
-
-#define BLK_BITS (WCNT * 64) /* some useful definitions for code here */
-#define KW_TWK_BASE (0)
-#define KW_KEY_BASE (3)
-#define ks (kw + KW_KEY_BASE)
-#define ts (kw + KW_TWK_BASE)
-
-#ifdef SKEIN_DEBUG
-#define debug_save_tweak(ctx) \
-{ \
- ctx->h.tweak[0] = ts[0]; \
- ctx->h.tweak[1] = ts[1]; \
-}
-#else
-#define debug_save_tweak(ctx)
-#endif
-
-#if !(SKEIN_USE_ASM & 256)
-#undef RCNT
-#define RCNT (SKEIN_256_ROUNDS_TOTAL / 8)
-#ifdef SKEIN_LOOP /* configure how much to unroll the loop */
-#define SKEIN_UNROLL_256 (((SKEIN_LOOP) / 100) % 10)
-#else
-#define SKEIN_UNROLL_256 (0)
-#endif
-
-#if SKEIN_UNROLL_256
-#if (RCNT % SKEIN_UNROLL_256)
-#error "Invalid SKEIN_UNROLL_256" /* sanity check on unroll count */
-#endif
-#endif
-#define ROUND256(p0, p1, p2, p3, ROT, r_num) \
- do { \
- X##p0 += X##p1; \
- X##p1 = rol64(X##p1, ROT##_0); \
- X##p1 ^= X##p0; \
- X##p2 += X##p3; \
- X##p3 = rol64(X##p3, ROT##_1); \
- X##p3 ^= X##p2; \
- } while (0)
-
-#if SKEIN_UNROLL_256 == 0
-#define R256(p0, p1, p2, p3, ROT, r_num) /* fully unrolled */ \
- ROUND256(p0, p1, p2, p3, ROT, r_num)
-
-#define I256(R) \
- do { \
- /* inject the key schedule value */ \
- X0 += ks[((R) + 1) % 5]; \
- X1 += ks[((R) + 2) % 5] + ts[((R) + 1) % 3]; \
- X2 += ks[((R) + 3) % 5] + ts[((R) + 2) % 3]; \
- X3 += ks[((R) + 4) % 5] + (R) + 1; \
- } while (0)
-#else
-/* looping version */
-#define R256(p0, p1, p2, p3, ROT, r_num) ROUND256(p0, p1, p2, p3, ROT, r_num)
-
-#define I256(R) \
- do { \
- /* inject the key schedule value */ \
- X0 += ks[r + (R) + 0]; \
- X1 += ks[r + (R) + 1] + ts[r + (R) + 0];\
- X2 += ks[r + (R) + 2] + ts[r + (R) + 1];\
- X3 += ks[r + (R) + 3] + r + (R); \
- /* rotate key schedule */ \
- ks[r + (R) + 4] = ks[r + (R) - 1]; \
- ts[r + (R) + 2] = ts[r + (R) - 1]; \
- } while (0)
-#endif
-#define R256_8_ROUNDS(R) \
- do { \
- R256(0, 1, 2, 3, R_256_0, 8 * (R) + 1); \
- R256(0, 3, 2, 1, R_256_1, 8 * (R) + 2); \
- R256(0, 1, 2, 3, R_256_2, 8 * (R) + 3); \
- R256(0, 3, 2, 1, R_256_3, 8 * (R) + 4); \
- I256(2 * (R)); \
- R256(0, 1, 2, 3, R_256_4, 8 * (R) + 5); \
- R256(0, 3, 2, 1, R_256_5, 8 * (R) + 6); \
- R256(0, 1, 2, 3, R_256_6, 8 * (R) + 7); \
- R256(0, 3, 2, 1, R_256_7, 8 * (R) + 8); \
- I256(2 * (R) + 1); \
- } while (0)
-
-#define R256_UNROLL_R(NN) \
- ((SKEIN_UNROLL_256 == 0 && \
- SKEIN_256_ROUNDS_TOTAL / 8 > (NN)) || \
- (SKEIN_UNROLL_256 > (NN)))
-
-#if (SKEIN_UNROLL_256 > 14)
-#error "need more unrolling in skein_256_process_block"
-#endif
-#endif
-
-#if !(SKEIN_USE_ASM & 512)
-#undef RCNT
-#define RCNT (SKEIN_512_ROUNDS_TOTAL / 8)
-
-#ifdef SKEIN_LOOP /* configure how much to unroll the loop */
-#define SKEIN_UNROLL_512 (((SKEIN_LOOP) / 10) % 10)
-#else
-#define SKEIN_UNROLL_512 (0)
-#endif
-
-#if SKEIN_UNROLL_512
-#if (RCNT % SKEIN_UNROLL_512)
-#error "Invalid SKEIN_UNROLL_512" /* sanity check on unroll count */
-#endif
-#endif
-#define ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \
- do { \
- X##p0 += X##p1; \
- X##p1 = rol64(X##p1, ROT##_0); \
- X##p1 ^= X##p0; \
- X##p2 += X##p3; \
- X##p3 = rol64(X##p3, ROT##_1); \
- X##p3 ^= X##p2; \
- X##p4 += X##p5; \
- X##p5 = rol64(X##p5, ROT##_2); \
- X##p5 ^= X##p4; \
- X##p6 += X##p7; \
- X##p7 = rol64(X##p7, ROT##_3); \
- X##p7 ^= X##p6; \
- } while (0)
-
-#if SKEIN_UNROLL_512 == 0
-#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) /* unrolled */ \
- ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num)
-
-#define I512(R) \
- do { \
- /* inject the key schedule value */ \
- X0 += ks[((R) + 1) % 9]; \
- X1 += ks[((R) + 2) % 9]; \
- X2 += ks[((R) + 3) % 9]; \
- X3 += ks[((R) + 4) % 9]; \
- X4 += ks[((R) + 5) % 9]; \
- X5 += ks[((R) + 6) % 9] + ts[((R) + 1) % 3]; \
- X6 += ks[((R) + 7) % 9] + ts[((R) + 2) % 3]; \
- X7 += ks[((R) + 8) % 9] + (R) + 1; \
- } while (0)
-
-#else /* looping version */
-#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \
- ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \
-
-#define I512(R) \
- do { \
- /* inject the key schedule value */ \
- X0 += ks[r + (R) + 0]; \
- X1 += ks[r + (R) + 1]; \
- X2 += ks[r + (R) + 2]; \
- X3 += ks[r + (R) + 3]; \
- X4 += ks[r + (R) + 4]; \
- X5 += ks[r + (R) + 5] + ts[r + (R) + 0]; \
- X6 += ks[r + (R) + 6] + ts[r + (R) + 1]; \
- X7 += ks[r + (R) + 7] + r + (R); \
- /* rotate key schedule */ \
- ks[r + (R) + 8] = ks[r + (R) - 1]; \
- ts[r + (R) + 2] = ts[r + (R) - 1]; \
- } while (0)
-#endif /* end of looped code definitions */
-#define R512_8_ROUNDS(R) /* do 8 full rounds */ \
- do { \
- R512(0, 1, 2, 3, 4, 5, 6, 7, R_512_0, 8 * (R) + 1); \
- R512(2, 1, 4, 7, 6, 5, 0, 3, R_512_1, 8 * (R) + 2); \
- R512(4, 1, 6, 3, 0, 5, 2, 7, R_512_2, 8 * (R) + 3); \
- R512(6, 1, 0, 7, 2, 5, 4, 3, R_512_3, 8 * (R) + 4); \
- I512(2 * (R)); \
- R512(0, 1, 2, 3, 4, 5, 6, 7, R_512_4, 8 * (R) + 5); \
- R512(2, 1, 4, 7, 6, 5, 0, 3, R_512_5, 8 * (R) + 6); \
- R512(4, 1, 6, 3, 0, 5, 2, 7, R_512_6, 8 * (R) + 7); \
- R512(6, 1, 0, 7, 2, 5, 4, 3, R_512_7, 8 * (R) + 8); \
- I512(2 * (R) + 1); /* and key injection */ \
- } while (0)
-#define R512_UNROLL_R(NN) \
- ((SKEIN_UNROLL_512 == 0 && \
- SKEIN_512_ROUNDS_TOTAL / 8 > (NN)) || \
- (SKEIN_UNROLL_512 > (NN)))
-
-#if (SKEIN_UNROLL_512 > 14)
-#error "need more unrolling in skein_512_process_block"
-#endif
-#endif
-
-#if !(SKEIN_USE_ASM & 1024)
-#undef RCNT
-#define RCNT (SKEIN_1024_ROUNDS_TOTAL / 8)
-#ifdef SKEIN_LOOP /* configure how much to unroll the loop */
-#define SKEIN_UNROLL_1024 ((SKEIN_LOOP) % 10)
-#else
-#define SKEIN_UNROLL_1024 (0)
-#endif
-
-#if (SKEIN_UNROLL_1024 != 0)
-#if (RCNT % SKEIN_UNROLL_1024)
-#error "Invalid SKEIN_UNROLL_1024" /* sanity check on unroll count */
-#endif
-#endif
-#define ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \
- pF, ROT, r_num) \
- do { \
- X##p0 += X##p1; \
- X##p1 = rol64(X##p1, ROT##_0); \
- X##p1 ^= X##p0; \
- X##p2 += X##p3; \
- X##p3 = rol64(X##p3, ROT##_1); \
- X##p3 ^= X##p2; \
- X##p4 += X##p5; \
- X##p5 = rol64(X##p5, ROT##_2); \
- X##p5 ^= X##p4; \
- X##p6 += X##p7; \
- X##p7 = rol64(X##p7, ROT##_3); \
- X##p7 ^= X##p6; \
- X##p8 += X##p9; \
- X##p9 = rol64(X##p9, ROT##_4); \
- X##p9 ^= X##p8; \
- X##pA += X##pB; \
- X##pB = rol64(X##pB, ROT##_5); \
- X##pB ^= X##pA; \
- X##pC += X##pD; \
- X##pD = rol64(X##pD, ROT##_6); \
- X##pD ^= X##pC; \
- X##pE += X##pF; \
- X##pF = rol64(X##pF, ROT##_7); \
- X##pF ^= X##pE; \
- } while (0)
-
-#if SKEIN_UNROLL_1024 == 0
-#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \
- ROT, rn) \
- ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \
- pF, ROT, rn) \
-
-#define I1024(R) \
- do { \
- /* inject the key schedule value */ \
- X00 += ks[((R) + 1) % 17]; \
- X01 += ks[((R) + 2) % 17]; \
- X02 += ks[((R) + 3) % 17]; \
- X03 += ks[((R) + 4) % 17]; \
- X04 += ks[((R) + 5) % 17]; \
- X05 += ks[((R) + 6) % 17]; \
- X06 += ks[((R) + 7) % 17]; \
- X07 += ks[((R) + 8) % 17]; \
- X08 += ks[((R) + 9) % 17]; \
- X09 += ks[((R) + 10) % 17]; \
- X10 += ks[((R) + 11) % 17]; \
- X11 += ks[((R) + 12) % 17]; \
- X12 += ks[((R) + 13) % 17]; \
- X13 += ks[((R) + 14) % 17] + ts[((R) + 1) % 3]; \
- X14 += ks[((R) + 15) % 17] + ts[((R) + 2) % 3]; \
- X15 += ks[((R) + 16) % 17] + (R) + 1; \
- } while (0)
-#else /* looping version */
-#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \
- ROT, rn) \
- ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \
- pF, ROT, rn) \
-
-#define I1024(R) \
- do { \
- /* inject the key schedule value */ \
- X00 += ks[r + (R) + 0]; \
- X01 += ks[r + (R) + 1]; \
- X02 += ks[r + (R) + 2]; \
- X03 += ks[r + (R) + 3]; \
- X04 += ks[r + (R) + 4]; \
- X05 += ks[r + (R) + 5]; \
- X06 += ks[r + (R) + 6]; \
- X07 += ks[r + (R) + 7]; \
- X08 += ks[r + (R) + 8]; \
- X09 += ks[r + (R) + 9]; \
- X10 += ks[r + (R) + 10]; \
- X11 += ks[r + (R) + 11]; \
- X12 += ks[r + (R) + 12]; \
- X13 += ks[r + (R) + 13] + ts[r + (R) + 0]; \
- X14 += ks[r + (R) + 14] + ts[r + (R) + 1]; \
- X15 += ks[r + (R) + 15] + r + (R); \
- /* rotate key schedule */ \
- ks[r + (R) + 16] = ks[r + (R) - 1]; \
- ts[r + (R) + 2] = ts[r + (R) - 1]; \
- } while (0)
-
-#endif
-#define R1024_8_ROUNDS(R) \
- do { \
- R1024(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, \
- 13, 14, 15, R1024_0, 8 * (R) + 1); \
- R1024(00, 09, 02, 13, 06, 11, 04, 15, 10, 07, 12, 03, 14, \
- 05, 08, 01, R1024_1, 8 * (R) + 2); \
- R1024(00, 07, 02, 05, 04, 03, 06, 01, 12, 15, 14, 13, 08, \
- 11, 10, 09, R1024_2, 8 * (R) + 3); \
- R1024(00, 15, 02, 11, 06, 13, 04, 09, 14, 01, 08, 05, 10, \
- 03, 12, 07, R1024_3, 8 * (R) + 4); \
- I1024(2 * (R)); \
- R1024(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, \
- 13, 14, 15, R1024_4, 8 * (R) + 5); \
- R1024(00, 09, 02, 13, 06, 11, 04, 15, 10, 07, 12, 03, 14, \
- 05, 08, 01, R1024_5, 8 * (R) + 6); \
- R1024(00, 07, 02, 05, 04, 03, 06, 01, 12, 15, 14, 13, 08, \
- 11, 10, 09, R1024_6, 8 * (R) + 7); \
- R1024(00, 15, 02, 11, 06, 13, 04, 09, 14, 01, 08, 05, 10, \
- 03, 12, 07, R1024_7, 8 * (R) + 8); \
- I1024(2 * (R) + 1); \
- } while (0)
-
-#define R1024_UNROLL_R(NN) \
- ((SKEIN_UNROLL_1024 == 0 && \
- SKEIN_1024_ROUNDS_TOTAL / 8 > (NN)) || \
- (SKEIN_UNROLL_1024 > (NN)))
-
-#if (SKEIN_UNROLL_1024 > 14)
-#error "need more unrolling in Skein_1024_Process_Block"
-#endif
-#endif
-
/***************************** SKEIN_256 ******************************/
#if !(SKEIN_USE_ASM & 256)
void skein_256_process_block(struct skein_256_ctx *ctx, const u8 *blk_ptr,
diff --git a/drivers/staging/skein/skein_block.h b/drivers/staging/skein/skein_block.h
index ec1baea..b3bb3d2 100644
--- a/drivers/staging/skein/skein_block.h
+++ b/drivers/staging/skein/skein_block.h
@@ -14,6 +14,329 @@
#include "skein_base.h" /* get the Skein API definitions */
+#ifndef SKEIN_USE_ASM
+#define SKEIN_USE_ASM (0) /* default is all C code (no ASM) */
+#endif
+
+#ifndef SKEIN_LOOP
+#define SKEIN_LOOP 001 /* default: unroll 256 and 512, but not 1024 */
+#endif
+
+#define BLK_BITS (WCNT * 64) /* some useful definitions for code here */
+#define KW_TWK_BASE (0)
+#define KW_KEY_BASE (3)
+#define ks (kw + KW_KEY_BASE)
+#define ts (kw + KW_TWK_BASE)
+
+#ifdef SKEIN_DEBUG
+#define debug_save_tweak(ctx) \
+{ \
+ ctx->h.tweak[0] = ts[0]; \
+ ctx->h.tweak[1] = ts[1]; \
+}
+#else
+#define debug_save_tweak(ctx)
+#endif
+
+#if !(SKEIN_USE_ASM & 256)
+#undef RCNT
+#define RCNT (SKEIN_256_ROUNDS_TOTAL / 8)
+#ifdef SKEIN_LOOP /* configure how much to unroll the loop */
+#define SKEIN_UNROLL_256 (((SKEIN_LOOP) / 100) % 10)
+#else
+#define SKEIN_UNROLL_256 (0)
+#endif
+
+#if SKEIN_UNROLL_256
+#if (RCNT % SKEIN_UNROLL_256)
+#error "Invalid SKEIN_UNROLL_256" /* sanity check on unroll count */
+#endif
+#endif
+#define ROUND256(p0, p1, p2, p3, ROT, r_num) \
+ do { \
+ X##p0 += X##p1; \
+ X##p1 = rol64(X##p1, ROT##_0); \
+ X##p1 ^= X##p0; \
+ X##p2 += X##p3; \
+ X##p3 = rol64(X##p3, ROT##_1); \
+ X##p3 ^= X##p2; \
+ } while (0)
+
+#if SKEIN_UNROLL_256 == 0
+#define R256(p0, p1, p2, p3, ROT, r_num) /* fully unrolled */ \
+ ROUND256(p0, p1, p2, p3, ROT, r_num)
+
+#define I256(R) \
+ do { \
+ /* inject the key schedule value */ \
+ X0 += ks[((R) + 1) % 5]; \
+ X1 += ks[((R) + 2) % 5] + ts[((R) + 1) % 3]; \
+ X2 += ks[((R) + 3) % 5] + ts[((R) + 2) % 3]; \
+ X3 += ks[((R) + 4) % 5] + (R) + 1; \
+ } while (0)
+#else
+/* looping version */
+#define R256(p0, p1, p2, p3, ROT, r_num) ROUND256(p0, p1, p2, p3, ROT, r_num)
+
+#define I256(R) \
+ do { \
+ /* inject the key schedule value */ \
+ X0 += ks[r + (R) + 0]; \
+ X1 += ks[r + (R) + 1] + ts[r + (R) + 0];\
+ X2 += ks[r + (R) + 2] + ts[r + (R) + 1];\
+ X3 += ks[r + (R) + 3] + r + (R); \
+ /* rotate key schedule */ \
+ ks[r + (R) + 4] = ks[r + (R) - 1]; \
+ ts[r + (R) + 2] = ts[r + (R) - 1]; \
+ } while (0)
+#endif
+#define R256_8_ROUNDS(R) \
+ do { \
+ R256(0, 1, 2, 3, R_256_0, 8 * (R) + 1); \
+ R256(0, 3, 2, 1, R_256_1, 8 * (R) + 2); \
+ R256(0, 1, 2, 3, R_256_2, 8 * (R) + 3); \
+ R256(0, 3, 2, 1, R_256_3, 8 * (R) + 4); \
+ I256(2 * (R)); \
+ R256(0, 1, 2, 3, R_256_4, 8 * (R) + 5); \
+ R256(0, 3, 2, 1, R_256_5, 8 * (R) + 6); \
+ R256(0, 1, 2, 3, R_256_6, 8 * (R) + 7); \
+ R256(0, 3, 2, 1, R_256_7, 8 * (R) + 8); \
+ I256(2 * (R) + 1); \
+ } while (0)
+
+#define R256_UNROLL_R(NN) \
+ ((SKEIN_UNROLL_256 == 0 && \
+ SKEIN_256_ROUNDS_TOTAL / 8 > (NN)) || \
+ (SKEIN_UNROLL_256 > (NN)))
+
+#if (SKEIN_UNROLL_256 > 14)
+#error "need more unrolling in skein_256_process_block"
+#endif
+#endif
+
+#if !(SKEIN_USE_ASM & 512)
+#undef RCNT
+#define RCNT (SKEIN_512_ROUNDS_TOTAL / 8)
+
+#ifdef SKEIN_LOOP /* configure how much to unroll the loop */
+#define SKEIN_UNROLL_512 (((SKEIN_LOOP) / 10) % 10)
+#else
+#define SKEIN_UNROLL_512 (0)
+#endif
+
+#if SKEIN_UNROLL_512
+#if (RCNT % SKEIN_UNROLL_512)
+#error "Invalid SKEIN_UNROLL_512" /* sanity check on unroll count */
+#endif
+#endif
+#define ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \
+ do { \
+ X##p0 += X##p1; \
+ X##p1 = rol64(X##p1, ROT##_0); \
+ X##p1 ^= X##p0; \
+ X##p2 += X##p3; \
+ X##p3 = rol64(X##p3, ROT##_1); \
+ X##p3 ^= X##p2; \
+ X##p4 += X##p5; \
+ X##p5 = rol64(X##p5, ROT##_2); \
+ X##p5 ^= X##p4; \
+ X##p6 += X##p7; \
+ X##p7 = rol64(X##p7, ROT##_3); \
+ X##p7 ^= X##p6; \
+ } while (0)
+
+#if SKEIN_UNROLL_512 == 0
+#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) /* unrolled */ \
+ ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num)
+
+#define I512(R) \
+ do { \
+ /* inject the key schedule value */ \
+ X0 += ks[((R) + 1) % 9]; \
+ X1 += ks[((R) + 2) % 9]; \
+ X2 += ks[((R) + 3) % 9]; \
+ X3 += ks[((R) + 4) % 9]; \
+ X4 += ks[((R) + 5) % 9]; \
+ X5 += ks[((R) + 6) % 9] + ts[((R) + 1) % 3]; \
+ X6 += ks[((R) + 7) % 9] + ts[((R) + 2) % 3]; \
+ X7 += ks[((R) + 8) % 9] + (R) + 1; \
+ } while (0)
+
+#else /* looping version */
+#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \
+ ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \
+
+#define I512(R) \
+ do { \
+ /* inject the key schedule value */ \
+ X0 += ks[r + (R) + 0]; \
+ X1 += ks[r + (R) + 1]; \
+ X2 += ks[r + (R) + 2]; \
+ X3 += ks[r + (R) + 3]; \
+ X4 += ks[r + (R) + 4]; \
+ X5 += ks[r + (R) + 5] + ts[r + (R) + 0]; \
+ X6 += ks[r + (R) + 6] + ts[r + (R) + 1]; \
+ X7 += ks[r + (R) + 7] + r + (R); \
+ /* rotate key schedule */ \
+ ks[r + (R) + 8] = ks[r + (R) - 1]; \
+ ts[r + (R) + 2] = ts[r + (R) - 1]; \
+ } while (0)
+#endif /* end of looped code definitions */
+#define R512_8_ROUNDS(R) /* do 8 full rounds */ \
+ do { \
+ R512(0, 1, 2, 3, 4, 5, 6, 7, R_512_0, 8 * (R) + 1); \
+ R512(2, 1, 4, 7, 6, 5, 0, 3, R_512_1, 8 * (R) + 2); \
+ R512(4, 1, 6, 3, 0, 5, 2, 7, R_512_2, 8 * (R) + 3); \
+ R512(6, 1, 0, 7, 2, 5, 4, 3, R_512_3, 8 * (R) + 4); \
+ I512(2 * (R)); \
+ R512(0, 1, 2, 3, 4, 5, 6, 7, R_512_4, 8 * (R) + 5); \
+ R512(2, 1, 4, 7, 6, 5, 0, 3, R_512_5, 8 * (R) + 6); \
+ R512(4, 1, 6, 3, 0, 5, 2, 7, R_512_6, 8 * (R) + 7); \
+ R512(6, 1, 0, 7, 2, 5, 4, 3, R_512_7, 8 * (R) + 8); \
+ I512(2 * (R) + 1); /* and key injection */ \
+ } while (0)
+#define R512_UNROLL_R(NN) \
+ ((SKEIN_UNROLL_512 == 0 && \
+ SKEIN_512_ROUNDS_TOTAL / 8 > (NN)) || \
+ (SKEIN_UNROLL_512 > (NN)))
+
+#if (SKEIN_UNROLL_512 > 14)
+#error "need more unrolling in skein_512_process_block"
+#endif
+#endif
+
+#if !(SKEIN_USE_ASM & 1024)
+#undef RCNT
+#define RCNT (SKEIN_1024_ROUNDS_TOTAL / 8)
+#ifdef SKEIN_LOOP /* configure how much to unroll the loop */
+#define SKEIN_UNROLL_1024 ((SKEIN_LOOP) % 10)
+#else
+#define SKEIN_UNROLL_1024 (0)
+#endif
+
+#if (SKEIN_UNROLL_1024 != 0)
+#if (RCNT % SKEIN_UNROLL_1024)
+#error "Invalid SKEIN_UNROLL_1024" /* sanity check on unroll count */
+#endif
+#endif
+#define ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \
+ pF, ROT, r_num) \
+ do { \
+ X##p0 += X##p1; \
+ X##p1 = rol64(X##p1, ROT##_0); \
+ X##p1 ^= X##p0; \
+ X##p2 += X##p3; \
+ X##p3 = rol64(X##p3, ROT##_1); \
+ X##p3 ^= X##p2; \
+ X##p4 += X##p5; \
+ X##p5 = rol64(X##p5, ROT##_2); \
+ X##p5 ^= X##p4; \
+ X##p6 += X##p7; \
+ X##p7 = rol64(X##p7, ROT##_3); \
+ X##p7 ^= X##p6; \
+ X##p8 += X##p9; \
+ X##p9 = rol64(X##p9, ROT##_4); \
+ X##p9 ^= X##p8; \
+ X##pA += X##pB; \
+ X##pB = rol64(X##pB, ROT##_5); \
+ X##pB ^= X##pA; \
+ X##pC += X##pD; \
+ X##pD = rol64(X##pD, ROT##_6); \
+ X##pD ^= X##pC; \
+ X##pE += X##pF; \
+ X##pF = rol64(X##pF, ROT##_7); \
+ X##pF ^= X##pE; \
+ } while (0)
+
+#if SKEIN_UNROLL_1024 == 0
+#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \
+ ROT, rn) \
+ ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \
+ pF, ROT, rn) \
+
+#define I1024(R) \
+ do { \
+ /* inject the key schedule value */ \
+ X00 += ks[((R) + 1) % 17]; \
+ X01 += ks[((R) + 2) % 17]; \
+ X02 += ks[((R) + 3) % 17]; \
+ X03 += ks[((R) + 4) % 17]; \
+ X04 += ks[((R) + 5) % 17]; \
+ X05 += ks[((R) + 6) % 17]; \
+ X06 += ks[((R) + 7) % 17]; \
+ X07 += ks[((R) + 8) % 17]; \
+ X08 += ks[((R) + 9) % 17]; \
+ X09 += ks[((R) + 10) % 17]; \
+ X10 += ks[((R) + 11) % 17]; \
+ X11 += ks[((R) + 12) % 17]; \
+ X12 += ks[((R) + 13) % 17]; \
+ X13 += ks[((R) + 14) % 17] + ts[((R) + 1) % 3]; \
+ X14 += ks[((R) + 15) % 17] + ts[((R) + 2) % 3]; \
+ X15 += ks[((R) + 16) % 17] + (R) + 1; \
+ } while (0)
+#else /* looping version */
+#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \
+ ROT, rn) \
+ ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \
+ pF, ROT, rn) \
+
+#define I1024(R) \
+ do { \
+ /* inject the key schedule value */ \
+ X00 += ks[r + (R) + 0]; \
+ X01 += ks[r + (R) + 1]; \
+ X02 += ks[r + (R) + 2]; \
+ X03 += ks[r + (R) + 3]; \
+ X04 += ks[r + (R) + 4]; \
+ X05 += ks[r + (R) + 5]; \
+ X06 += ks[r + (R) + 6]; \
+ X07 += ks[r + (R) + 7]; \
+ X08 += ks[r + (R) + 8]; \
+ X09 += ks[r + (R) + 9]; \
+ X10 += ks[r + (R) + 10]; \
+ X11 += ks[r + (R) + 11]; \
+ X12 += ks[r + (R) + 12]; \
+ X13 += ks[r + (R) + 13] + ts[r + (R) + 0]; \
+ X14 += ks[r + (R) + 14] + ts[r + (R) + 1]; \
+ X15 += ks[r + (R) + 15] + r + (R); \
+ /* rotate key schedule */ \
+ ks[r + (R) + 16] = ks[r + (R) - 1]; \
+ ts[r + (R) + 2] = ts[r + (R) - 1]; \
+ } while (0)
+
+#endif
+#define R1024_8_ROUNDS(R) \
+ do { \
+ R1024(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, \
+ 13, 14, 15, R1024_0, 8 * (R) + 1); \
+ R1024(00, 09, 02, 13, 06, 11, 04, 15, 10, 07, 12, 03, 14, \
+ 05, 08, 01, R1024_1, 8 * (R) + 2); \
+ R1024(00, 07, 02, 05, 04, 03, 06, 01, 12, 15, 14, 13, 08, \
+ 11, 10, 09, R1024_2, 8 * (R) + 3); \
+ R1024(00, 15, 02, 11, 06, 13, 04, 09, 14, 01, 08, 05, 10, \
+ 03, 12, 07, R1024_3, 8 * (R) + 4); \
+ I1024(2 * (R)); \
+ R1024(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, \
+ 13, 14, 15, R1024_4, 8 * (R) + 5); \
+ R1024(00, 09, 02, 13, 06, 11, 04, 15, 10, 07, 12, 03, 14, \
+ 05, 08, 01, R1024_5, 8 * (R) + 6); \
+ R1024(00, 07, 02, 05, 04, 03, 06, 01, 12, 15, 14, 13, 08, \
+ 11, 10, 09, R1024_6, 8 * (R) + 7); \
+ R1024(00, 15, 02, 11, 06, 13, 04, 09, 14, 01, 08, 05, 10, \
+ 03, 12, 07, R1024_7, 8 * (R) + 8); \
+ I1024(2 * (R) + 1); \
+ } while (0)
+
+#define R1024_UNROLL_R(NN) \
+ ((SKEIN_UNROLL_1024 == 0 && \
+ SKEIN_1024_ROUNDS_TOTAL / 8 > (NN)) || \
+ (SKEIN_UNROLL_1024 > (NN)))
+
+#if (SKEIN_UNROLL_1024 > 14)
+#error "need more unrolling in Skein_1024_Process_Block"
+#endif
+#endif
+
void skein_256_process_block(struct skein_256_ctx *ctx, const u8 *blk_ptr,
size_t blk_cnt, size_t byte_cnt_add);
void skein_512_process_block(struct skein_512_ctx *ctx, const u8 *blk_ptr,
diff --git a/drivers/staging/speakup/spk_ttyio.c b/drivers/staging/speakup/spk_ttyio.c
index fe340b0..4d7d8f2 100644
--- a/drivers/staging/speakup/spk_ttyio.c
+++ b/drivers/staging/speakup/spk_ttyio.c
@@ -7,11 +7,6 @@
#include "spk_types.h"
#include "spk_priv.h"
-#define DEV_PREFIX_LP "lp"
-
-static const char * const lp_supported[] = { "acntsa", "bns", "dummy",
- "txprt" };
-
struct spk_ldisc_data {
char buf;
struct semaphore sem;
@@ -20,6 +15,11 @@ struct spk_ldisc_data {
static struct spk_synth *spk_ttyio_synth;
static struct tty_struct *speakup_tty;
+/* mutex to protect against speakup_tty disappearing from underneath us while
+ * we are using it. this can happen when the device physically unplugged,
+ * while in use. it also serialises access to speakup_tty.
+ */
+static DEFINE_MUTEX(speakup_tty_mutex);
static int ser_to_dev(int ser, dev_t *dev_no)
{
@@ -36,24 +36,8 @@ static int get_dev_to_use(struct spk_synth *synth, dev_t *dev_no)
{
/* use ser only when dev is not specified */
if (strcmp(synth->dev_name, SYNTH_DEFAULT_DEV) ||
- synth->ser == SYNTH_DEFAULT_SER) {
- /* for /dev/lp* check if synth is supported */
- if (strncmp(synth->dev_name, DEV_PREFIX_LP,
- strlen(DEV_PREFIX_LP)) == 0)
- if (match_string(lp_supported, ARRAY_SIZE(lp_supported),
- synth->name) < 0) {
- int i;
-
- pr_err("speakup: lp* is only supported on:");
- for (i = 0; i < ARRAY_SIZE(lp_supported); i++)
- pr_cont(" %s", lp_supported[i]);
- pr_cont("\n");
-
- return -ENOTSUPP;
- }
-
+ synth->ser == SYNTH_DEFAULT_SER)
return tty_dev_name_to_number(synth->dev_name, dev_no);
- }
return ser_to_dev(synth->ser, dev_no);
}
@@ -81,8 +65,10 @@ static int spk_ttyio_ldisc_open(struct tty_struct *tty)
static void spk_ttyio_ldisc_close(struct tty_struct *tty)
{
+ mutex_lock(&speakup_tty_mutex);
kfree(speakup_tty->disc_data);
speakup_tty = NULL;
+ mutex_unlock(&speakup_tty_mutex);
}
static int spk_ttyio_receive_buf2(struct tty_struct *tty,
@@ -158,7 +144,7 @@ static int spk_ttyio_initialise_ldisc(struct spk_synth *synth)
if (ret)
return ret;
- tty = tty_open_by_driver(dev, NULL, NULL);
+ tty = tty_kopen(dev);
if (IS_ERR(tty))
return PTR_ERR(tty);
@@ -210,9 +196,11 @@ void spk_ttyio_unregister_ldisc(void)
static int spk_ttyio_out(struct spk_synth *in_synth, const char ch)
{
+ mutex_lock(&speakup_tty_mutex);
if (in_synth->alive && speakup_tty && speakup_tty->ops->write) {
int ret = speakup_tty->ops->write(speakup_tty, &ch, 1);
+ mutex_unlock(&speakup_tty_mutex);
if (ret == 0)
/* No room */
return 0;
@@ -228,17 +216,50 @@ static int spk_ttyio_out(struct spk_synth *in_synth, const char ch)
}
return 1;
}
+
+ mutex_unlock(&speakup_tty_mutex);
+ return 0;
+}
+
+static int check_tty(struct tty_struct *tty)
+{
+ if (!tty) {
+ pr_warn("%s: I/O error, deactivating speakup\n",
+ spk_ttyio_synth->long_name);
+ /* No synth any more, so nobody will restart TTYs, and we thus
+ * need to do it ourselves. Now that there is no synth we can
+ * let application flood anyway
+ */
+ spk_ttyio_synth->alive = 0;
+ speakup_start_ttys();
+ return 1;
+ }
+
return 0;
}
static void spk_ttyio_send_xchar(char ch)
{
+ mutex_lock(&speakup_tty_mutex);
+ if (check_tty(speakup_tty)) {
+ mutex_unlock(&speakup_tty_mutex);
+ return;
+ }
+
speakup_tty->ops->send_xchar(speakup_tty, ch);
+ mutex_unlock(&speakup_tty_mutex);
}
static void spk_ttyio_tiocmset(unsigned int set, unsigned int clear)
{
+ mutex_lock(&speakup_tty_mutex);
+ if (check_tty(speakup_tty)) {
+ mutex_unlock(&speakup_tty_mutex);
+ return;
+ }
+
speakup_tty->ops->tiocmset(speakup_tty, set, clear);
+ mutex_unlock(&speakup_tty_mutex);
}
static unsigned char ttyio_in(int timeout)
@@ -278,8 +299,16 @@ static unsigned char spk_ttyio_in_nowait(void)
static void spk_ttyio_flush_buffer(void)
{
+ mutex_lock(&speakup_tty_mutex);
+ if (check_tty(speakup_tty)) {
+ mutex_unlock(&speakup_tty_mutex);
+ return;
+ }
+
if (speakup_tty->ops->flush_buffer)
speakup_tty->ops->flush_buffer(speakup_tty);
+
+ mutex_unlock(&speakup_tty_mutex);
}
int spk_ttyio_synth_probe(struct spk_synth *synth)
@@ -308,7 +337,7 @@ void spk_ttyio_release(void)
tty_ldisc_flush(speakup_tty);
tty_unlock(speakup_tty);
- tty_release_struct(speakup_tty, speakup_tty->index);
+ tty_kclose(speakup_tty);
}
EXPORT_SYMBOL_GPL(spk_ttyio_release);
diff --git a/drivers/staging/typec/fusb302/Kconfig b/drivers/staging/typec/fusb302/Kconfig
index fce099f..48a4f2f 100644
--- a/drivers/staging/typec/fusb302/Kconfig
+++ b/drivers/staging/typec/fusb302/Kconfig
@@ -1,6 +1,6 @@
config TYPEC_FUSB302
tristate "Fairchild FUSB302 Type-C chip driver"
- depends on I2C
+ depends on I2C && POWER_SUPPLY
help
The Fairchild FUSB302 Type-C chip driver that works with
Type-C Port Controller Manager to provide USB PD and USB
diff --git a/drivers/staging/typec/fusb302/TODO b/drivers/staging/typec/fusb302/TODO
index 4933a1d..19b466e 100644
--- a/drivers/staging/typec/fusb302/TODO
+++ b/drivers/staging/typec/fusb302/TODO
@@ -4,3 +4,7 @@ fusb302:
- Find a non-hacky way to coordinate between PM and I2C access
- Documentation? The FUSB302 datasheet provides information on the chip to help
understand the code. But it may still be helpful to have a documentation.
+- We may want to replace the "fcs,max-snk-microvolt", "fcs,max-snk-microamp",
+ "fcs,max-snk-microwatt" and "fcs,operating-snk-microwatt" device(tree)
+ properties with properties which are part of a generic type-c controller
+ devicetree binding.
diff --git a/drivers/staging/typec/fusb302/fusb302.c b/drivers/staging/typec/fusb302/fusb302.c
index 03a3809..fc6a3cf 100644
--- a/drivers/staging/typec/fusb302/fusb302.c
+++ b/drivers/staging/typec/fusb302/fusb302.c
@@ -17,6 +17,7 @@
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/errno.h>
+#include <linux/extcon.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
@@ -27,6 +28,7 @@
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/pinctrl/consumer.h>
+#include <linux/power_supply.h>
#include <linux/proc_fs.h>
#include <linux/regulator/consumer.h>
#include <linux/sched/clock.h>
@@ -90,11 +92,13 @@ struct fusb302_chip {
struct i2c_client *i2c_client;
struct tcpm_port *tcpm_port;
struct tcpc_dev tcpc_dev;
+ struct tcpc_config tcpc_config;
struct regulator *vbus;
int gpio_int_n;
int gpio_int_n_irq;
+ struct extcon_dev *extcon;
struct workqueue_struct *wq;
struct delayed_work bc_lvl_handler;
@@ -105,6 +109,11 @@ struct fusb302_chip {
/* lock for sharing chip states */
struct mutex lock;
+ /* psy + psy status */
+ struct power_supply *psy;
+ u32 current_limit;
+ u32 supply_voltage;
+
/* chip status */
enum toggling_mode toggling_mode;
enum src_current_status src_current_status;
@@ -515,6 +524,38 @@ static int tcpm_get_vbus(struct tcpc_dev *dev)
return ret;
}
+static int tcpm_get_current_limit(struct tcpc_dev *dev)
+{
+ struct fusb302_chip *chip = container_of(dev, struct fusb302_chip,
+ tcpc_dev);
+ int current_limit = 0;
+ unsigned long timeout;
+
+ if (!chip->extcon)
+ return 0;
+
+ /*
+ * USB2 Charger detection may still be in progress when we get here,
+ * this can take upto 600ms, wait 800ms max.
+ */
+ timeout = jiffies + msecs_to_jiffies(800);
+ do {
+ if (extcon_get_state(chip->extcon, EXTCON_CHG_USB_SDP) == 1)
+ current_limit = 500;
+
+ if (extcon_get_state(chip->extcon, EXTCON_CHG_USB_CDP) == 1 ||
+ extcon_get_state(chip->extcon, EXTCON_CHG_USB_ACA) == 1)
+ current_limit = 1500;
+
+ if (extcon_get_state(chip->extcon, EXTCON_CHG_USB_DCP) == 1)
+ current_limit = 2000;
+
+ msleep(50);
+ } while (current_limit == 0 && time_before(jiffies, timeout));
+
+ return current_limit;
+}
+
static int fusb302_set_cc_pull(struct fusb302_chip *chip,
bool pull_up, bool pull_down)
{
@@ -841,11 +882,13 @@ static int tcpm_set_vbus(struct tcpc_dev *dev, bool on, bool charge)
chip->vbus_on = on;
fusb302_log(chip, "vbus := %s", on ? "On" : "Off");
}
- if (chip->charge_on == charge)
+ if (chip->charge_on == charge) {
fusb302_log(chip, "charge is already %s",
charge ? "On" : "Off");
- else
+ } else {
chip->charge_on = charge;
+ power_supply_changed(chip->psy);
+ }
done:
mutex_unlock(&chip->lock);
@@ -861,6 +904,11 @@ static int tcpm_set_current_limit(struct tcpc_dev *dev, u32 max_ma, u32 mv)
fusb302_log(chip, "current limit: %d ma, %d mv (not implemented)",
max_ma, mv);
+ chip->supply_voltage = mv;
+ chip->current_limit = max_ma;
+
+ power_supply_changed(chip->psy);
+
return 0;
}
@@ -1187,9 +1235,9 @@ static const struct tcpc_config fusb302_tcpc_config = {
.nr_src_pdo = ARRAY_SIZE(src_pdo),
.snk_pdo = snk_pdo,
.nr_snk_pdo = ARRAY_SIZE(snk_pdo),
- .max_snk_mv = 9000,
+ .max_snk_mv = 5000,
.max_snk_ma = 3000,
- .max_snk_mw = 27000,
+ .max_snk_mw = 15000,
.operating_snk_mw = 2500,
.type = TYPEC_PORT_DRP,
.default_role = TYPEC_SINK,
@@ -1198,9 +1246,9 @@ static const struct tcpc_config fusb302_tcpc_config = {
static void init_tcpc_dev(struct tcpc_dev *fusb302_tcpc_dev)
{
- fusb302_tcpc_dev->config = &fusb302_tcpc_config;
fusb302_tcpc_dev->init = tcpm_init;
fusb302_tcpc_dev->get_vbus = tcpm_get_vbus;
+ fusb302_tcpc_dev->get_current_limit = tcpm_get_current_limit;
fusb302_tcpc_dev->set_cc = tcpm_set_cc;
fusb302_tcpc_dev->get_cc = tcpm_get_cc;
fusb302_tcpc_dev->set_polarity = tcpm_set_polarity;
@@ -1646,6 +1694,43 @@ done:
return IRQ_HANDLED;
}
+static int fusb302_psy_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct fusb302_chip *chip = power_supply_get_drvdata(psy);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = chip->charge_on;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ val->intval = chip->supply_voltage * 1000; /* mV -> µV */
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_MAX:
+ val->intval = chip->current_limit * 1000; /* mA -> µA */
+ break;
+ default:
+ return -ENODATA;
+ }
+
+ return 0;
+}
+
+static enum power_supply_property fusb302_psy_properties[] = {
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_CURRENT_MAX,
+};
+
+static const struct power_supply_desc fusb302_psy_desc = {
+ .name = "fusb302-typec-source",
+ .type = POWER_SUPPLY_TYPE_USB_TYPE_C,
+ .properties = fusb302_psy_properties,
+ .num_properties = ARRAY_SIZE(fusb302_psy_properties),
+ .get_property = fusb302_psy_get_property,
+};
+
static int init_gpio(struct fusb302_chip *chip)
{
struct device_node *node;
@@ -1684,7 +1769,11 @@ static int fusb302_probe(struct i2c_client *client,
{
struct fusb302_chip *chip;
struct i2c_adapter *adapter;
+ struct device *dev = &client->dev;
+ struct power_supply_config cfg = {};
+ const char *name;
int ret = 0;
+ u32 v;
adapter = to_i2c_adapter(client->dev.parent);
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {
@@ -1699,8 +1788,43 @@ static int fusb302_probe(struct i2c_client *client,
chip->i2c_client = client;
i2c_set_clientdata(client, chip);
chip->dev = &client->dev;
+ chip->tcpc_config = fusb302_tcpc_config;
+ chip->tcpc_dev.config = &chip->tcpc_config;
mutex_init(&chip->lock);
+ if (!device_property_read_u32(dev, "fcs,max-sink-microvolt", &v))
+ chip->tcpc_config.max_snk_mv = v / 1000;
+
+ if (!device_property_read_u32(dev, "fcs,max-sink-microamp", &v))
+ chip->tcpc_config.max_snk_ma = v / 1000;
+
+ if (!device_property_read_u32(dev, "fcs,max-sink-microwatt", &v))
+ chip->tcpc_config.max_snk_mw = v / 1000;
+
+ if (!device_property_read_u32(dev, "fcs,operating-sink-microwatt", &v))
+ chip->tcpc_config.operating_snk_mw = v / 1000;
+
+ /*
+ * Devicetree platforms should get extcon via phandle (not yet
+ * supported). On ACPI platforms, we get the name from a device prop.
+ * This device prop is for kernel internal use only and is expected
+ * to be set by the platform code which also registers the i2c client
+ * for the fusb302.
+ */
+ if (device_property_read_string(dev, "fcs,extcon-name", &name) == 0) {
+ chip->extcon = extcon_get_extcon_dev(name);
+ if (!chip->extcon)
+ return -EPROBE_DEFER;
+ }
+
+ cfg.drv_data = chip;
+ chip->psy = devm_power_supply_register(dev, &fusb302_psy_desc, &cfg);
+ if (IS_ERR(chip->psy)) {
+ ret = PTR_ERR(chip->psy);
+ dev_err(chip->dev, "Error registering power-supply: %d\n", ret);
+ return ret;
+ }
+
ret = fusb302_debugfs_init(chip);
if (ret < 0)
return ret;
@@ -1719,9 +1843,13 @@ static int fusb302_probe(struct i2c_client *client,
goto destroy_workqueue;
}
- ret = init_gpio(chip);
- if (ret < 0)
- goto destroy_workqueue;
+ if (client->irq) {
+ chip->gpio_int_n_irq = client->irq;
+ } else {
+ ret = init_gpio(chip);
+ if (ret < 0)
+ goto destroy_workqueue;
+ }
chip->tcpm_port = tcpm_register_port(&client->dev, &chip->tcpc_dev);
if (IS_ERR(chip->tcpm_port)) {
diff --git a/drivers/staging/typec/pd.h b/drivers/staging/typec/pd.h
index 510ef72..30b32ad 100644
--- a/drivers/staging/typec/pd.h
+++ b/drivers/staging/typec/pd.h
@@ -278,6 +278,8 @@ static inline unsigned int rdo_max_power(u32 rdo)
#define PD_T_VCONN_SOURCE_ON 100
#define PD_T_SINK_REQUEST 100 /* 100 ms minimum */
#define PD_T_ERROR_RECOVERY 100 /* minimum 25 is insufficient */
+#define PD_T_SRCSWAPSTDBY 625 /* Maximum of 650ms */
+#define PD_T_NEWSRC 250 /* Maximum of 275ms */
#define PD_T_DRP_TRY 100 /* 75 - 150 ms */
#define PD_T_DRP_TRYWAIT 600 /* 400 - 800 ms */
diff --git a/drivers/staging/typec/tcpm.c b/drivers/staging/typec/tcpm.c
index 20eb4eb..8af62e7 100644
--- a/drivers/staging/typec/tcpm.c
+++ b/drivers/staging/typec/tcpm.c
@@ -17,6 +17,7 @@
#include <linux/completion.h>
#include <linux/debugfs.h>
#include <linux/device.h>
+#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
@@ -89,9 +90,11 @@
S(PR_SWAP_START), \
S(PR_SWAP_SRC_SNK_TRANSITION_OFF), \
S(PR_SWAP_SRC_SNK_SOURCE_OFF), \
+ S(PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED), \
S(PR_SWAP_SRC_SNK_SINK_ON), \
S(PR_SWAP_SNK_SRC_SINK_OFF), \
S(PR_SWAP_SNK_SRC_SOURCE_ON), \
+ S(PR_SWAP_SNK_SRC_SOURCE_ON_VBUS_RAMPED_UP), \
\
S(VCONN_SWAP_ACCEPT), \
S(VCONN_SWAP_SEND), \
@@ -104,10 +107,14 @@
\
S(SNK_TRY), \
S(SNK_TRY_WAIT), \
+ S(SNK_TRY_WAIT_DEBOUNCE), \
+ S(SNK_TRY_WAIT_DEBOUNCE_CHECK_VBUS), \
S(SRC_TRYWAIT), \
+ S(SRC_TRYWAIT_DEBOUNCE), \
S(SRC_TRYWAIT_UNATTACHED), \
\
S(SRC_TRY), \
+ S(SRC_TRY_WAIT), \
S(SRC_TRY_DEBOUNCE), \
S(SNK_TRYWAIT), \
S(SNK_TRYWAIT_DEBOUNCE), \
@@ -115,7 +122,8 @@
S(BIST_RX), \
\
S(ERROR_RECOVERY), \
- S(ERROR_RECOVERY_WAIT_OFF)
+ S(PORT_RESET), \
+ S(PORT_RESET_WAIT_OFF)
#define GENERATE_ENUM(e) e
#define GENERATE_STRING(s) #s
@@ -196,6 +204,7 @@ struct tcpm_port {
bool attached;
bool connected;
+ enum typec_port_type port_type;
bool vbus_present;
bool vbus_never_low;
bool vbus_source;
@@ -230,6 +239,7 @@ struct tcpm_port {
struct mutex swap_lock; /* swap command lock */
bool swap_pending;
+ bool non_pd_role_swap;
struct completion swap_complete;
int swap_status;
@@ -281,6 +291,9 @@ struct tcpm_port {
struct typec_altmode *partner_altmode[SVID_DISCOVERY_MAX];
struct typec_altmode *port_altmode[SVID_DISCOVERY_MAX];
+ /* Deadline in jiffies to exit src_try_wait state */
+ unsigned long max_wait;
+
#ifdef CONFIG_DEBUG_FS
struct dentry *dentry;
struct mutex logbuffer_lock; /* log buffer access lock */
@@ -325,19 +338,26 @@ struct pd_rx_event {
(tcpm_cc_is_audio((port)->cc2) && tcpm_cc_is_open((port)->cc1)))
#define tcpm_try_snk(port) \
- ((port)->try_snk_count == 0 && (port)->try_role == TYPEC_SINK)
+ ((port)->try_snk_count == 0 && (port)->try_role == TYPEC_SINK && \
+ (port)->port_type == TYPEC_PORT_DRP)
#define tcpm_try_src(port) \
- ((port)->try_src_count == 0 && (port)->try_role == TYPEC_SOURCE)
+ ((port)->try_src_count == 0 && (port)->try_role == TYPEC_SOURCE && \
+ (port)->port_type == TYPEC_PORT_DRP)
static enum tcpm_state tcpm_default_state(struct tcpm_port *port)
{
- if (port->try_role == TYPEC_SINK)
- return SNK_UNATTACHED;
- else if (port->try_role == TYPEC_SOURCE)
- return SRC_UNATTACHED;
- else if (port->tcpc->config->default_role == TYPEC_SINK)
+ if (port->port_type == TYPEC_PORT_DRP) {
+ if (port->try_role == TYPEC_SINK)
+ return SNK_UNATTACHED;
+ else if (port->try_role == TYPEC_SOURCE)
+ return SRC_UNATTACHED;
+ else if (port->tcpc->config->default_role == TYPEC_SINK)
+ return SNK_UNATTACHED;
+ /* Fall through to return SRC_UNATTACHED */
+ } else if (port->port_type == TYPEC_PORT_UFP) {
return SNK_UNATTACHED;
+ }
return SRC_UNATTACHED;
}
@@ -369,6 +389,7 @@ static bool tcpm_log_full(struct tcpm_port *port)
(port->logbuffer_head + 1) % LOG_BUFFER_ENTRIES;
}
+__printf(2, 0)
static void _tcpm_log(struct tcpm_port *port, const char *fmt, va_list args)
{
char tmpbuffer[LOG_BUFFER_ENTRY_SIZE];
@@ -415,6 +436,7 @@ abort:
mutex_unlock(&port->logbuffer_lock);
}
+__printf(2, 3)
static void tcpm_log(struct tcpm_port *port, const char *fmt, ...)
{
va_list args;
@@ -430,6 +452,7 @@ static void tcpm_log(struct tcpm_port *port, const char *fmt, ...)
va_end(args);
}
+__printf(2, 3)
static void tcpm_log_force(struct tcpm_port *port, const char *fmt, ...)
{
va_list args;
@@ -546,7 +569,9 @@ static void tcpm_debugfs_exit(struct tcpm_port *port)
#else
+__printf(2, 3)
static void tcpm_log(const struct tcpm_port *port, const char *fmt, ...) { }
+__printf(2, 3)
static void tcpm_log_force(struct tcpm_port *port, const char *fmt, ...) { }
static void tcpm_log_source_caps(struct tcpm_port *port) { }
static int tcpm_debugfs_init(const struct tcpm_port *port) { return 0; }
@@ -660,7 +685,10 @@ static u32 tcpm_get_current_limit(struct tcpm_port *port)
break;
case TYPEC_CC_RP_DEF:
default:
- limit = 0;
+ if (port->tcpc->get_current_limit)
+ limit = port->tcpc->get_current_limit(port->tcpc);
+ else
+ limit = 0;
break;
}
@@ -1015,8 +1043,7 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const __le32 *payload, int cnt,
if (port->data_role == TYPEC_DEVICE &&
port->nr_snk_vdo) {
for (i = 0; i < port->nr_snk_vdo; i++)
- response[i + 1]
- = cpu_to_le32(port->snk_vdo[i]);
+ response[i + 1] = port->snk_vdo[i];
rlen = port->nr_snk_vdo + 1;
}
break;
@@ -1367,6 +1394,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port,
tcpm_set_current_limit(port,
port->current_limit,
port->supply_voltage);
+ port->explicit_contract = true;
tcpm_set_state(port, SNK_READY, 0);
} else {
/*
@@ -1377,7 +1405,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port,
SNK_TRANSITION_SINK_VBUS, 0);
}
break;
- case PR_SWAP_SRC_SNK_SOURCE_OFF:
+ case PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED:
tcpm_set_state(port, PR_SWAP_SRC_SNK_SINK_ON, 0);
break;
case PR_SWAP_SNK_SRC_SINK_OFF:
@@ -1451,7 +1479,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port,
tcpm_set_state(port, SOFT_RESET, 0);
break;
case PD_CTRL_DR_SWAP:
- if (port->typec_caps.type != TYPEC_PORT_DRP) {
+ if (port->port_type != TYPEC_PORT_DRP) {
tcpm_queue_message(port, PD_MSG_CTRL_REJECT);
break;
}
@@ -1471,7 +1499,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port,
}
break;
case PD_CTRL_PR_SWAP:
- if (port->typec_caps.type != TYPEC_PORT_DRP) {
+ if (port->port_type != TYPEC_PORT_DRP) {
tcpm_queue_message(port, PD_MSG_CTRL_REJECT);
break;
}
@@ -1846,7 +1874,7 @@ static bool tcpm_start_drp_toggling(struct tcpm_port *port)
int ret;
if (port->tcpc->start_drp_toggling &&
- port->typec_caps.type == TYPEC_PORT_DRP) {
+ port->port_type == TYPEC_PORT_DRP) {
tcpm_log_force(port, "Start DRP toggling");
ret = port->tcpc->start_drp_toggling(port->tcpc,
tcpm_rp_cc(port));
@@ -2099,10 +2127,16 @@ static inline enum tcpm_state ready_state(struct tcpm_port *port)
static inline enum tcpm_state unattached_state(struct tcpm_port *port)
{
- if (port->pwr_role == TYPEC_SOURCE)
+ if (port->port_type == TYPEC_PORT_DRP) {
+ if (port->pwr_role == TYPEC_SOURCE)
+ return SRC_UNATTACHED;
+ else
+ return SNK_UNATTACHED;
+ } else if (port->port_type == TYPEC_PORT_DFP) {
return SRC_UNATTACHED;
- else
- return SNK_UNATTACHED;
+ }
+
+ return SNK_UNATTACHED;
}
static void tcpm_check_send_discover(struct tcpm_port *port)
@@ -2119,13 +2153,29 @@ static void tcpm_swap_complete(struct tcpm_port *port, int result)
if (port->swap_pending) {
port->swap_status = result;
port->swap_pending = false;
+ port->non_pd_role_swap = false;
complete(&port->swap_complete);
}
}
+static enum typec_pwr_opmode tcpm_get_pwr_opmode(enum typec_cc_status cc)
+{
+ switch (cc) {
+ case TYPEC_CC_RP_1_5:
+ return TYPEC_PWR_MODE_1_5A;
+ case TYPEC_CC_RP_3_0:
+ return TYPEC_PWR_MODE_3_0A;
+ case TYPEC_CC_RP_DEF:
+ default:
+ return TYPEC_PWR_MODE_USB;
+ }
+}
+
static void run_state_machine(struct tcpm_port *port)
{
int ret;
+ enum typec_pwr_opmode opmode;
+ unsigned int msecs;
port->enter_state = port->state;
switch (port->state) {
@@ -2133,14 +2183,15 @@ static void run_state_machine(struct tcpm_port *port)
break;
/* SRC states */
case SRC_UNATTACHED:
- tcpm_swap_complete(port, -ENOTCONN);
+ if (!port->non_pd_role_swap)
+ tcpm_swap_complete(port, -ENOTCONN);
tcpm_src_detach(port);
if (tcpm_start_drp_toggling(port)) {
tcpm_set_state(port, DRP_TOGGLING, 0);
break;
}
tcpm_set_cc(port, tcpm_rp_cc(port));
- if (port->typec_caps.type == TYPEC_PORT_DRP)
+ if (port->port_type == TYPEC_PORT_DRP)
tcpm_set_state(port, SNK_UNATTACHED, PD_T_DRP_SNK);
break;
case SRC_ATTACH_WAIT:
@@ -2171,25 +2222,43 @@ static void run_state_machine(struct tcpm_port *port)
tcpm_set_state(port, SNK_TRY_WAIT, PD_T_DRP_TRY);
break;
case SNK_TRY_WAIT:
+ if (tcpm_port_is_sink(port)) {
+ tcpm_set_state(port, SNK_TRY_WAIT_DEBOUNCE, 0);
+ } else {
+ tcpm_set_state(port, SRC_TRYWAIT, 0);
+ port->max_wait = 0;
+ }
+ break;
+ case SNK_TRY_WAIT_DEBOUNCE:
+ tcpm_set_state(port, SNK_TRY_WAIT_DEBOUNCE_CHECK_VBUS,
+ PD_T_PD_DEBOUNCE);
+ break;
+ case SNK_TRY_WAIT_DEBOUNCE_CHECK_VBUS:
if (port->vbus_present && tcpm_port_is_sink(port)) {
tcpm_set_state(port, SNK_ATTACHED, 0);
- break;
- }
- if (!tcpm_port_is_sink(port)) {
- tcpm_set_state(port, SRC_TRYWAIT,
- PD_T_PD_DEBOUNCE);
- break;
+ } else {
+ tcpm_set_state(port, SRC_TRYWAIT, 0);
+ port->max_wait = 0;
}
- /* No vbus, cc state is sink or open */
- tcpm_set_state(port, SRC_TRYWAIT_UNATTACHED, PD_T_DRP_TRYWAIT);
break;
case SRC_TRYWAIT:
tcpm_set_cc(port, tcpm_rp_cc(port));
- if (!port->vbus_present && tcpm_port_is_source(port))
- tcpm_set_state(port, SRC_ATTACHED, PD_T_CC_DEBOUNCE);
- else
+ if (port->max_wait == 0) {
+ port->max_wait = jiffies +
+ msecs_to_jiffies(PD_T_DRP_TRY);
tcpm_set_state(port, SRC_TRYWAIT_UNATTACHED,
PD_T_DRP_TRY);
+ } else {
+ if (time_is_after_jiffies(port->max_wait))
+ tcpm_set_state(port, SRC_TRYWAIT_UNATTACHED,
+ jiffies_to_msecs(port->max_wait -
+ jiffies));
+ else
+ tcpm_set_state(port, SNK_UNATTACHED, 0);
+ }
+ break;
+ case SRC_TRYWAIT_DEBOUNCE:
+ tcpm_set_state(port, SRC_ATTACHED, PD_T_CC_DEBOUNCE);
break;
case SRC_TRYWAIT_UNATTACHED:
tcpm_set_state(port, SNK_UNATTACHED, 0);
@@ -2201,7 +2270,8 @@ static void run_state_machine(struct tcpm_port *port)
ret < 0 ? 0 : PD_T_PS_SOURCE_ON);
break;
case SRC_STARTUP:
- typec_set_pwr_opmode(port->typec_port, TYPEC_PWR_MODE_USB);
+ opmode = tcpm_get_pwr_opmode(tcpm_rp_cc(port));
+ typec_set_pwr_opmode(port->typec_port, opmode);
port->pwr_opmode = TYPEC_PWR_MODE_USB;
port->caps_count = 0;
port->message_id = 0;
@@ -2262,8 +2332,8 @@ static void run_state_machine(struct tcpm_port *port)
#endif
port->try_src_count = 0;
+ tcpm_swap_complete(port, 0);
tcpm_typec_connect(port);
-
tcpm_check_send_discover(port);
/*
* 6.3.5
@@ -2273,14 +2343,11 @@ static void run_state_machine(struct tcpm_port *port)
* - The system is not operating in PD mode
* or
* - Both partners are connected using a Type-C connector
- * XXX How do we know that ?
+ *
+ * There is no actual need to send PD messages since the local
+ * port type-c and the spec does not clearly say whether PD is
+ * possible when type-c is connected to Type-A/B
*/
- if (port->pwr_opmode == TYPEC_PWR_MODE_PD &&
- !port->op_vsafe5v) {
- tcpm_pd_send_control(port, PD_CTRL_PING);
- tcpm_set_state_cond(port, SRC_READY,
- PD_T_SOURCE_ACTIVITY);
- }
break;
case SRC_WAIT_NEW_CAPABILITIES:
/* Nothing to do... */
@@ -2288,14 +2355,15 @@ static void run_state_machine(struct tcpm_port *port)
/* SNK states */
case SNK_UNATTACHED:
- tcpm_swap_complete(port, -ENOTCONN);
+ if (!port->non_pd_role_swap)
+ tcpm_swap_complete(port, -ENOTCONN);
tcpm_snk_detach(port);
if (tcpm_start_drp_toggling(port)) {
tcpm_set_state(port, DRP_TOGGLING, 0);
break;
}
tcpm_set_cc(port, TYPEC_CC_RD);
- if (port->typec_caps.type == TYPEC_PORT_DRP)
+ if (port->port_type == TYPEC_PORT_DRP)
tcpm_set_state(port, SRC_UNATTACHED, PD_T_DRP_SRC);
break;
case SNK_ATTACH_WAIT:
@@ -2320,39 +2388,52 @@ static void run_state_machine(struct tcpm_port *port)
0);
else
/* Wait for VBUS, but not forever */
- tcpm_set_state(port, SNK_UNATTACHED, PD_T_PS_SOURCE_ON);
+ tcpm_set_state(port, PORT_RESET, PD_T_PS_SOURCE_ON);
break;
case SRC_TRY:
port->try_src_count++;
tcpm_set_cc(port, tcpm_rp_cc(port));
- tcpm_set_state(port, SNK_TRYWAIT, PD_T_DRP_TRY);
+ port->max_wait = 0;
+ tcpm_set_state(port, SRC_TRY_WAIT, 0);
+ break;
+ case SRC_TRY_WAIT:
+ if (port->max_wait == 0) {
+ port->max_wait = jiffies +
+ msecs_to_jiffies(PD_T_DRP_TRY);
+ msecs = PD_T_DRP_TRY;
+ } else {
+ if (time_is_after_jiffies(port->max_wait))
+ msecs = jiffies_to_msecs(port->max_wait -
+ jiffies);
+ else
+ msecs = 0;
+ }
+ tcpm_set_state(port, SNK_TRYWAIT, msecs);
break;
case SRC_TRY_DEBOUNCE:
tcpm_set_state(port, SRC_ATTACHED, PD_T_PD_DEBOUNCE);
break;
case SNK_TRYWAIT:
tcpm_set_cc(port, TYPEC_CC_RD);
- tcpm_set_state(port, SNK_TRYWAIT_DEBOUNCE, PD_T_CC_DEBOUNCE);
+ tcpm_set_state(port, SNK_TRYWAIT_VBUS, PD_T_CC_DEBOUNCE);
break;
- case SNK_TRYWAIT_DEBOUNCE:
- if (port->vbus_present) {
+ case SNK_TRYWAIT_VBUS:
+ /*
+ * TCPM stays in this state indefinitely until VBUS
+ * is detected as long as Rp is not detected for
+ * more than a time period of tPDDebounce.
+ */
+ if (port->vbus_present && tcpm_port_is_sink(port)) {
tcpm_set_state(port, SNK_ATTACHED, 0);
break;
}
- if (tcpm_port_is_disconnected(port)) {
- tcpm_set_state(port, SNK_UNATTACHED,
- PD_T_PD_DEBOUNCE);
- break;
- }
- if (tcpm_port_is_source(port))
- tcpm_set_state(port, SRC_ATTACHED, 0);
- /* XXX Are we supposed to stay in this state ? */
+ if (!tcpm_port_is_sink(port))
+ tcpm_set_state(port, SNK_TRYWAIT_DEBOUNCE, 0);
break;
- case SNK_TRYWAIT_VBUS:
- tcpm_set_state(port, SNK_ATTACHED, PD_T_CC_DEBOUNCE);
+ case SNK_TRYWAIT_DEBOUNCE:
+ tcpm_set_state(port, SNK_UNATTACHED, PD_T_PD_DEBOUNCE);
break;
-
case SNK_ATTACHED:
ret = tcpm_snk_attach(port);
if (ret < 0)
@@ -2362,7 +2443,9 @@ static void run_state_machine(struct tcpm_port *port)
break;
case SNK_STARTUP:
/* XXX: callback into infrastructure */
- typec_set_pwr_opmode(port->typec_port, TYPEC_PWR_MODE_USB);
+ opmode = tcpm_get_pwr_opmode(port->polarity ?
+ port->cc2 : port->cc1);
+ typec_set_pwr_opmode(port->typec_port, opmode);
port->pwr_opmode = TYPEC_PWR_MODE_USB;
port->message_id = 0;
port->rx_msgid = -1;
@@ -2384,7 +2467,7 @@ static void run_state_machine(struct tcpm_port *port)
* see USB power delivery specification, section 8.3.3.6.1.5.1).
*/
tcpm_set_state(port, hard_reset_state(port),
- port->typec_caps.type == TYPEC_PORT_DRP ?
+ port->port_type == TYPEC_PORT_DRP ?
PD_T_DB_DETECT : PD_T_NO_RESPONSE);
break;
case SNK_DISCOVERY_DEBOUNCE:
@@ -2441,12 +2524,14 @@ static void run_state_machine(struct tcpm_port *port)
break;
case SNK_READY:
port->try_snk_count = 0;
- port->explicit_contract = true;
- typec_set_pwr_opmode(port->typec_port, TYPEC_PWR_MODE_PD);
- port->pwr_opmode = TYPEC_PWR_MODE_PD;
+ if (port->explicit_contract) {
+ typec_set_pwr_opmode(port->typec_port,
+ TYPEC_PWR_MODE_PD);
+ port->pwr_opmode = TYPEC_PWR_MODE_PD;
+ }
+ tcpm_swap_complete(port, 0);
tcpm_typec_connect(port);
-
tcpm_check_send_discover(port);
break;
@@ -2574,7 +2659,6 @@ static void run_state_machine(struct tcpm_port *port)
TYPEC_HOST);
port->send_discover = true;
}
- tcpm_swap_complete(port, 0);
tcpm_set_state(port, ready_state(port), 0);
break;
@@ -2602,11 +2686,17 @@ static void run_state_machine(struct tcpm_port *port)
case PR_SWAP_SRC_SNK_TRANSITION_OFF:
tcpm_set_vbus(port, false);
port->explicit_contract = false;
+ /* allow time for Vbus discharge, must be < tSrcSwapStdby */
tcpm_set_state(port, PR_SWAP_SRC_SNK_SOURCE_OFF,
- PD_T_PS_SOURCE_OFF);
+ PD_T_SRCSWAPSTDBY);
break;
case PR_SWAP_SRC_SNK_SOURCE_OFF:
tcpm_set_cc(port, TYPEC_CC_RD);
+ /* allow CC debounce */
+ tcpm_set_state(port, PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED,
+ PD_T_CC_DEBOUNCE);
+ break;
+ case PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED:
/*
* USB-PD standard, 6.2.1.4, Port Power Role:
* "During the Power Role Swap Sequence, for the initial Source
@@ -2622,7 +2712,6 @@ static void run_state_machine(struct tcpm_port *port)
tcpm_set_state_cond(port, SNK_UNATTACHED, PD_T_PS_SOURCE_ON);
break;
case PR_SWAP_SRC_SNK_SINK_ON:
- tcpm_swap_complete(port, 0);
tcpm_set_state(port, SNK_STARTUP, 0);
break;
case PR_SWAP_SNK_SRC_SINK_OFF:
@@ -2634,6 +2723,15 @@ static void run_state_machine(struct tcpm_port *port)
tcpm_set_cc(port, tcpm_rp_cc(port));
tcpm_set_vbus(port, true);
/*
+ * allow time VBUS ramp-up, must be < tNewSrc
+ * Also, this window overlaps with CC debounce as well.
+ * So, Wait for the max of two which is PD_T_NEWSRC
+ */
+ tcpm_set_state(port, PR_SWAP_SNK_SRC_SOURCE_ON_VBUS_RAMPED_UP,
+ PD_T_NEWSRC);
+ break;
+ case PR_SWAP_SNK_SRC_SOURCE_ON_VBUS_RAMPED_UP:
+ /*
* USB PD standard, 6.2.1.4:
* "Subsequent Messages initiated by the Policy Engine,
* such as the PS_RDY Message sent to indicate that Vbus
@@ -2642,7 +2740,6 @@ static void run_state_machine(struct tcpm_port *port)
*/
tcpm_set_pwr_role(port, TYPEC_SOURCE);
tcpm_pd_send_control(port, PD_CTRL_PS_RDY);
- tcpm_swap_complete(port, 0);
tcpm_set_state(port, SRC_STARTUP, 0);
break;
@@ -2672,12 +2769,10 @@ static void run_state_machine(struct tcpm_port *port)
case VCONN_SWAP_TURN_ON_VCONN:
tcpm_set_vconn(port, true);
tcpm_pd_send_control(port, PD_CTRL_PS_RDY);
- tcpm_swap_complete(port, 0);
tcpm_set_state(port, ready_state(port), 0);
break;
case VCONN_SWAP_TURN_OFF_VCONN:
tcpm_set_vconn(port, false);
- tcpm_swap_complete(port, 0);
tcpm_set_state(port, ready_state(port), 0);
break;
@@ -2704,13 +2799,15 @@ static void run_state_machine(struct tcpm_port *port)
break;
case ERROR_RECOVERY:
tcpm_swap_complete(port, -EPROTO);
+ tcpm_set_state(port, PORT_RESET, 0);
+ break;
+ case PORT_RESET:
tcpm_reset_port(port);
-
tcpm_set_cc(port, TYPEC_CC_OPEN);
- tcpm_set_state(port, ERROR_RECOVERY_WAIT_OFF,
+ tcpm_set_state(port, PORT_RESET_WAIT_OFF,
PD_T_ERROR_RECOVERY);
break;
- case ERROR_RECOVERY_WAIT_OFF:
+ case PORT_RESET_WAIT_OFF:
tcpm_set_state(port,
tcpm_default_state(port),
port->vbus_present ? PD_T_PS_SOURCE_OFF : 0);
@@ -2799,10 +2896,12 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1,
tcpm_set_state(port, SRC_ATTACH_WAIT, 0);
break;
case SRC_ATTACHED:
- if (tcpm_port_is_disconnected(port))
+ case SRC_SEND_CAPABILITIES:
+ case SRC_READY:
+ if (tcpm_port_is_disconnected(port) ||
+ !tcpm_port_is_source(port))
tcpm_set_state(port, SRC_UNATTACHED, 0);
break;
-
case SNK_UNATTACHED:
if (tcpm_port_is_sink(port))
tcpm_set_state(port, SNK_ATTACH_WAIT, 0);
@@ -2869,52 +2968,43 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1,
case SRC_TRYWAIT:
/* Hand over to state machine if needed */
if (!port->vbus_present && tcpm_port_is_source(port))
- new_state = SRC_ATTACHED;
- else
- new_state = SRC_TRYWAIT_UNATTACHED;
-
- if (new_state != port->delayed_state)
+ tcpm_set_state(port, SRC_TRYWAIT_DEBOUNCE, 0);
+ break;
+ case SRC_TRYWAIT_DEBOUNCE:
+ if (port->vbus_present || !tcpm_port_is_source(port))
tcpm_set_state(port, SRC_TRYWAIT, 0);
break;
- case SNK_TRY_WAIT:
- if (port->vbus_present && tcpm_port_is_sink(port)) {
- tcpm_set_state(port, SNK_ATTACHED, 0);
- break;
+ case SNK_TRY_WAIT_DEBOUNCE:
+ if (!tcpm_port_is_sink(port)) {
+ port->max_wait = 0;
+ tcpm_set_state(port, SRC_TRYWAIT, 0);
}
- if (!tcpm_port_is_sink(port))
- new_state = SRC_TRYWAIT;
- else
- new_state = SRC_TRYWAIT_UNATTACHED;
-
- if (new_state != port->delayed_state)
- tcpm_set_state(port, SNK_TRY_WAIT, 0);
break;
-
- case SRC_TRY:
- tcpm_set_state(port, SRC_TRY_DEBOUNCE, 0);
+ case SRC_TRY_WAIT:
+ if (tcpm_port_is_source(port))
+ tcpm_set_state(port, SRC_TRY_DEBOUNCE, 0);
break;
case SRC_TRY_DEBOUNCE:
- tcpm_set_state(port, SRC_TRY, 0);
+ tcpm_set_state(port, SRC_TRY_WAIT, 0);
break;
case SNK_TRYWAIT_DEBOUNCE:
- if (port->vbus_present) {
- tcpm_set_state(port, SNK_ATTACHED, 0);
- break;
- }
- if (tcpm_port_is_source(port)) {
- tcpm_set_state(port, SRC_ATTACHED, 0);
- break;
- }
- if (tcpm_port_is_disconnected(port) &&
- port->delayed_state != SNK_UNATTACHED)
+ if (tcpm_port_is_sink(port))
+ tcpm_set_state(port, SNK_TRYWAIT_VBUS, 0);
+ break;
+ case SNK_TRYWAIT_VBUS:
+ if (!tcpm_port_is_sink(port))
tcpm_set_state(port, SNK_TRYWAIT_DEBOUNCE, 0);
break;
-
+ case SNK_TRYWAIT:
+ /* Do nothing, waiting for tCCDebounce */
+ break;
case PR_SWAP_SNK_SRC_SINK_OFF:
case PR_SWAP_SRC_SNK_TRANSITION_OFF:
case PR_SWAP_SRC_SNK_SOURCE_OFF:
+ case PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED:
+ case PR_SWAP_SNK_SRC_SOURCE_ON:
/*
- * CC state change is expected here; we just turned off power.
+ * CC state change is expected in PR_SWAP
* Ignore it.
*/
break;
@@ -2928,12 +3018,11 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1,
static void _tcpm_pd_vbus_on(struct tcpm_port *port)
{
- enum tcpm_state new_state;
-
tcpm_log_force(port, "VBUS on");
port->vbus_present = true;
switch (port->state) {
case SNK_TRANSITION_SINK_VBUS:
+ port->explicit_contract = true;
tcpm_set_state(port, SNK_READY, 0);
break;
case SNK_DISCOVERY:
@@ -2959,27 +3048,28 @@ static void _tcpm_pd_vbus_on(struct tcpm_port *port)
/* Do nothing, waiting for timeout */
break;
case SRC_TRYWAIT:
- /* Hand over to state machine if needed */
- if (port->delayed_state != SRC_TRYWAIT_UNATTACHED)
- tcpm_set_state(port, SRC_TRYWAIT, 0);
+ /* Do nothing, Waiting for Rd to be detected */
break;
- case SNK_TRY_WAIT:
- if (tcpm_port_is_sink(port)) {
- tcpm_set_state(port, SNK_ATTACHED, 0);
- break;
- }
- if (!tcpm_port_is_sink(port))
- new_state = SRC_TRYWAIT;
- else
- new_state = SRC_TRYWAIT_UNATTACHED;
-
- if (new_state != port->delayed_state)
- tcpm_set_state(port, SNK_TRY_WAIT, 0);
+ case SRC_TRYWAIT_DEBOUNCE:
+ tcpm_set_state(port, SRC_TRYWAIT, 0);
+ break;
+ case SNK_TRY_WAIT_DEBOUNCE:
+ /* Do nothing, waiting for PD_DEBOUNCE to do be done */
break;
case SNK_TRYWAIT:
- tcpm_set_state(port, SNK_TRYWAIT_VBUS, 0);
+ /* Do nothing, waiting for tCCDebounce */
+ break;
+ case SNK_TRYWAIT_VBUS:
+ if (tcpm_port_is_sink(port))
+ tcpm_set_state(port, SNK_ATTACHED, 0);
+ break;
+ case SNK_TRYWAIT_DEBOUNCE:
+ /* Do nothing, waiting for Rp */
+ break;
+ case SRC_TRY_WAIT:
+ case SRC_TRY_DEBOUNCE:
+ /* Do nothing, waiting for sink detection */
break;
-
default:
break;
}
@@ -2987,8 +3077,6 @@ static void _tcpm_pd_vbus_on(struct tcpm_port *port)
static void _tcpm_pd_vbus_off(struct tcpm_port *port)
{
- enum tcpm_state new_state;
-
tcpm_log_force(port, "VBUS off");
port->vbus_present = false;
port->vbus_never_low = false;
@@ -3008,25 +3096,15 @@ static void _tcpm_pd_vbus_off(struct tcpm_port *port)
case SRC_TRYWAIT:
/* Hand over to state machine if needed */
if (tcpm_port_is_source(port))
- new_state = SRC_ATTACHED;
- else
- new_state = SRC_TRYWAIT_UNATTACHED;
- if (new_state != port->delayed_state)
- tcpm_set_state(port, SRC_TRYWAIT, 0);
+ tcpm_set_state(port, SRC_TRYWAIT_DEBOUNCE, 0);
break;
- case SNK_TRY_WAIT:
- if (!tcpm_port_is_sink(port))
- new_state = SRC_TRYWAIT;
- else
- new_state = SRC_TRYWAIT_UNATTACHED;
-
- if (new_state != port->delayed_state)
- tcpm_set_state(port, SNK_TRY_WAIT, 0);
+ case SNK_TRY_WAIT_DEBOUNCE:
+ /* Do nothing, waiting for PD_DEBOUNCE to do be done */
break;
+ case SNK_TRYWAIT:
case SNK_TRYWAIT_VBUS:
- tcpm_set_state(port, SNK_TRYWAIT, 0);
+ case SNK_TRYWAIT_DEBOUNCE:
break;
-
case SNK_ATTACH_WAIT:
tcpm_set_state(port, SNK_UNATTACHED, 0);
break;
@@ -3042,13 +3120,13 @@ static void _tcpm_pd_vbus_off(struct tcpm_port *port)
/* Do nothing, expected */
break;
- case ERROR_RECOVERY_WAIT_OFF:
- tcpm_set_state(port,
- port->pwr_role == TYPEC_SOURCE ?
- SRC_UNATTACHED : SNK_UNATTACHED,
- 0);
+ case PORT_RESET_WAIT_OFF:
+ tcpm_set_state(port, tcpm_default_state(port), 0);
+ break;
+ case SRC_TRY_WAIT:
+ case SRC_TRY_DEBOUNCE:
+ /* Do nothing, waiting for sink detection */
break;
-
default:
if (port->pwr_role == TYPEC_SINK &&
port->attached)
@@ -3142,7 +3220,7 @@ static int tcpm_dr_set(const struct typec_capability *cap,
mutex_lock(&port->swap_lock);
mutex_lock(&port->lock);
- if (port->typec_caps.type != TYPEC_PORT_DRP || !port->pd_capable) {
+ if (port->port_type != TYPEC_PORT_DRP) {
ret = -EINVAL;
goto port_unlock;
}
@@ -3163,15 +3241,35 @@ static int tcpm_dr_set(const struct typec_capability *cap,
* Reject data role swap request in this case.
*/
+ if (!port->pd_capable) {
+ /*
+ * If the partner is not PD capable, reset the port to
+ * trigger a role change. This can only work if a preferred
+ * role is configured, and if it matches the requested role.
+ */
+ if (port->try_role == TYPEC_NO_PREFERRED_ROLE ||
+ port->try_role == port->pwr_role) {
+ ret = -EINVAL;
+ goto port_unlock;
+ }
+ port->non_pd_role_swap = true;
+ tcpm_set_state(port, PORT_RESET, 0);
+ } else {
+ tcpm_set_state(port, DR_SWAP_SEND, 0);
+ }
+
port->swap_status = 0;
port->swap_pending = true;
reinit_completion(&port->swap_complete);
- tcpm_set_state(port, DR_SWAP_SEND, 0);
mutex_unlock(&port->lock);
- wait_for_completion(&port->swap_complete);
+ if (!wait_for_completion_timeout(&port->swap_complete,
+ msecs_to_jiffies(PD_ROLE_SWAP_TIMEOUT)))
+ ret = -ETIMEDOUT;
+ else
+ ret = port->swap_status;
- ret = port->swap_status;
+ port->non_pd_role_swap = false;
goto swap_unlock;
port_unlock:
@@ -3190,7 +3288,7 @@ static int tcpm_pr_set(const struct typec_capability *cap,
mutex_lock(&port->swap_lock);
mutex_lock(&port->lock);
- if (port->typec_caps.type != TYPEC_PORT_DRP) {
+ if (port->port_type != TYPEC_PORT_DRP) {
ret = -EINVAL;
goto port_unlock;
}
@@ -3204,31 +3302,18 @@ static int tcpm_pr_set(const struct typec_capability *cap,
goto port_unlock;
}
- if (!port->pd_capable) {
- /*
- * If the partner is not PD capable, reset the port to
- * trigger a role change. This can only work if a preferred
- * role is configured, and if it matches the requested role.
- */
- if (port->try_role == TYPEC_NO_PREFERRED_ROLE ||
- port->try_role == port->pwr_role) {
- ret = -EINVAL;
- goto port_unlock;
- }
- tcpm_set_state(port, HARD_RESET_SEND, 0);
- ret = 0;
- goto port_unlock;
- }
-
port->swap_status = 0;
port->swap_pending = true;
reinit_completion(&port->swap_complete);
tcpm_set_state(port, PR_SWAP_SEND, 0);
mutex_unlock(&port->lock);
- wait_for_completion(&port->swap_complete);
+ if (!wait_for_completion_timeout(&port->swap_complete,
+ msecs_to_jiffies(PD_ROLE_SWAP_TIMEOUT)))
+ ret = -ETIMEDOUT;
+ else
+ ret = port->swap_status;
- ret = port->swap_status;
goto swap_unlock;
port_unlock:
@@ -3263,9 +3348,12 @@ static int tcpm_vconn_set(const struct typec_capability *cap,
tcpm_set_state(port, VCONN_SWAP_SEND, 0);
mutex_unlock(&port->lock);
- wait_for_completion(&port->swap_complete);
+ if (!wait_for_completion_timeout(&port->swap_complete,
+ msecs_to_jiffies(PD_ROLE_SWAP_TIMEOUT)))
+ ret = -ETIMEDOUT;
+ else
+ ret = port->swap_status;
- ret = port->swap_status;
goto swap_unlock;
port_unlock:
@@ -3319,7 +3407,35 @@ static void tcpm_init(struct tcpm_port *port)
* Some adapters need a clean slate at startup, and won't recover
* otherwise. So do not try to be fancy and force a clean disconnect.
*/
- tcpm_set_state(port, ERROR_RECOVERY, 0);
+ tcpm_set_state(port, PORT_RESET, 0);
+}
+
+static int tcpm_port_type_set(const struct typec_capability *cap,
+ enum typec_port_type type)
+{
+ struct tcpm_port *port = typec_cap_to_tcpm(cap);
+
+ mutex_lock(&port->lock);
+ if (type == port->port_type)
+ goto port_unlock;
+
+ port->port_type = type;
+
+ if (!port->connected) {
+ tcpm_set_state(port, PORT_RESET, 0);
+ } else if (type == TYPEC_PORT_UFP) {
+ if (!(port->pwr_role == TYPEC_SINK &&
+ port->data_role == TYPEC_DEVICE))
+ tcpm_set_state(port, PORT_RESET, 0);
+ } else if (type == TYPEC_PORT_DFP) {
+ if (!(port->pwr_role == TYPEC_SOURCE &&
+ port->data_role == TYPEC_HOST))
+ tcpm_set_state(port, PORT_RESET, 0);
+ }
+
+port_unlock:
+ mutex_unlock(&port->lock);
+ return 0;
}
void tcpm_tcpc_reset(struct tcpm_port *port)
@@ -3469,9 +3585,10 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc)
port->typec_caps.pr_set = tcpm_pr_set;
port->typec_caps.vconn_set = tcpm_vconn_set;
port->typec_caps.try_role = tcpm_try_role;
+ port->typec_caps.port_type_set = tcpm_port_type_set;
port->partner_desc.identity = &port->partner_ident;
-
+ port->port_type = tcpc->config->type;
/*
* TODO:
* - alt_modes, set_alt_mode
@@ -3485,7 +3602,7 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc)
}
if (tcpc->config->alt_modes) {
- struct typec_altmode_desc *paltmode = tcpc->config->alt_modes;
+ const struct typec_altmode_desc *paltmode = tcpc->config->alt_modes;
i = 0;
while (paltmode->svid && i < ARRAY_SIZE(port->port_altmode)) {
diff --git a/drivers/staging/typec/tcpm.h b/drivers/staging/typec/tcpm.h
index 19c307d..7e9a6b7 100644
--- a/drivers/staging/typec/tcpm.h
+++ b/drivers/staging/typec/tcpm.h
@@ -34,7 +34,8 @@ enum typec_cc_polarity {
};
/* Time to wait for TCPC to complete transmit */
-#define PD_T_TCPC_TX_TIMEOUT 100
+#define PD_T_TCPC_TX_TIMEOUT 100 /* in ms */
+#define PD_ROLE_SWAP_TIMEOUT (MSEC_PER_SEC * 10)
enum tcpm_transmit_status {
TCPC_TX_SUCCESS = 0,
@@ -72,7 +73,7 @@ struct tcpc_config {
enum typec_role default_role;
bool try_role_hw; /* try.{src,snk} implemented in hardware */
- struct typec_altmode_desc *alt_modes;
+ const struct typec_altmode_desc *alt_modes;
};
enum tcpc_usb_switch {
@@ -108,6 +109,13 @@ struct tcpc_dev {
int (*init)(struct tcpc_dev *dev);
int (*get_vbus)(struct tcpc_dev *dev);
+ /*
+ * This optional callback gets called by the tcpm core when configured
+ * as a snk and cc=Rp-def. This allows the tcpm to provide a fallback
+ * current-limit detection method for the cc=Rp-def case. E.g. some
+ * tcpcs may include BC1.2 charger detection and use that in this case.
+ */
+ int (*get_current_limit)(struct tcpc_dev *dev);
int (*set_cc)(struct tcpc_dev *dev, enum typec_cc_status cc);
int (*get_cc)(struct tcpc_dev *dev, enum typec_cc_status *cc1,
enum typec_cc_status *cc2);
diff --git a/drivers/staging/unisys/Documentation/overview.txt b/drivers/staging/unisys/Documentation/overview.txt
index e0466bf..9ab30af 100644
--- a/drivers/staging/unisys/Documentation/overview.txt
+++ b/drivers/staging/unisys/Documentation/overview.txt
@@ -221,7 +221,7 @@ The following files exist under /sys/devices/visorbus<x>/vbus<x>:dev<y>:
The visorhba driver registers with visorbus as the function driver to
handle virtual scsi disk devices, specified using the
-VISOR_VHBA_CHANNEL_UUID type in the visorbus_register_visor_driver()
+VISOR_VHBA_CHANNEL_GUID type in the visorbus_register_visor_driver()
call. visorhba uses scsi_add_host() to expose a Linux block device
(e.g., /sys/block/) in the guest environment for each s-Par virtual device.
@@ -240,7 +240,7 @@ When compiled as a module, visorhba can be autoloaded by visorbus in
standard udev/systemd environments, as it includes the modules.alias
definition:
- "visorbus:"+VISOR_VHBA_CHANNEL_UUID_STR
+ "visorbus:"+VISOR_VHBA_CHANNEL_GUID_STR
i.e.:
@@ -252,7 +252,7 @@ i.e.:
The visornic driver registers with visorbus as the function driver to
handle virtual network devices, specified using the
-VISOR_VNIC_CHANNEL_UUID type in the visorbus_register_visor_driver()
+VISOR_VNIC_CHANNEL_GUID type in the visorbus_register_visor_driver()
call. visornic uses register_netdev() to expose a Linux device of class net
(e.g., /sys/class/net/) in the guest environment for each s-Par virtual
device.
@@ -270,7 +270,7 @@ When compiled as a module, visornic can be autoloaded by visorbus in
standard udev/systemd environments, as it includes the modules.alias
definition:
- "visorbus:"+VISOR_VNIC_CHANNEL_UUID_STR
+ "visorbus:"+VISOR_VNIC_CHANNEL_GUID_STR
i.e.:
@@ -282,7 +282,7 @@ i.e.:
The visorinput driver registers with visorbus as the function driver to
handle human input devices, specified using the
-VISOR_KEYBOARD_CHANNEL_UUID and VISOR_MOUSE_CHANNEL_UUID
+VISOR_KEYBOARD_CHANNEL_GUID and VISOR_MOUSE_CHANNEL_GUID
types in the visorbus_register_visor_driver() call. visorinput uses
input_register_device() to expose devices of class input
(e.g., /sys/class/input/) for virtual keyboard and virtual mouse devices.
@@ -307,8 +307,8 @@ When compiled as a module, visorinput can be autoloaded by visorbus in
standard udev/systemd environments, as it includes the modules.alias
definition:
- "visorbus:"+VISOR_MOUSE_CHANNEL_UUID_STR
- "visorbus:"+VISOR_KEYBOARD_CHANNEL_UUID_STR
+ "visorbus:"+VISOR_MOUSE_CHANNEL_GUID_STR
+ "visorbus:"+VISOR_KEYBOARD_CHANNEL_GUID_STR
i.e.:
diff --git a/drivers/staging/unisys/include/channel.h b/drivers/staging/unisys/include/channel.h
index 692efcb..2babe93 100644
--- a/drivers/staging/unisys/include/channel.h
+++ b/drivers/staging/unisys/include/channel.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
+/*
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -20,87 +21,48 @@
#include <linux/io.h>
#include <linux/uuid.h>
-#define __SUPERVISOR_CHANNEL_H__
-
#define SIGNATURE_16(A, B) ((A) | ((B) << 8))
#define SIGNATURE_32(A, B, C, D) \
(SIGNATURE_16(A, B) | (SIGNATURE_16(C, D) << 16))
-#define SIGNATURE_64(A, B, C, D, E, F, G, H) \
- (SIGNATURE_32(A, B, C, D) | ((u64)(SIGNATURE_32(E, F, G, H)) << 32))
-
-#ifndef COVER
-#define COVER(v, d) ((d) * DIV_ROUND_UP(v, d))
-#endif
-
#define VISOR_CHANNEL_SIGNATURE SIGNATURE_32('E', 'C', 'N', 'L')
+/*
+ * enum channel_serverstate
+ * @CHANNELSRV_UNINITIALIZED: Channel is in an undefined state.
+ * @CHANNELSRV_READY: Channel has been initialized by server.
+ */
enum channel_serverstate {
- CHANNELSRV_UNINITIALIZED = 0, /* channel is in an undefined state */
- CHANNELSRV_READY = 1 /* channel has been initialized by server */
+ CHANNELSRV_UNINITIALIZED = 0,
+ CHANNELSRV_READY = 1
};
+/*
+ * enum channel_clientstate
+ * @CHANNELCLI_DETACHED:
+ * @CHANNELCLI_DISABLED: Client can see channel but is NOT allowed to use it
+ * unless given TBD* explicit request
+ * (should actually be < DETACHED).
+ * @CHANNELCLI_ATTACHING: Legacy EFI client request for EFI server to attach.
+ * @CHANNELCLI_ATTACHED: Idle, but client may want to use channel any time.
+ * @CHANNELCLI_BUSY: Client either wants to use or is using channel.
+ * @CHANNELCLI_OWNED: "No worries" state - client can access channel
+ * anytime.
+ */
enum channel_clientstate {
CHANNELCLI_DETACHED = 0,
- CHANNELCLI_DISABLED = 1, /* client can see channel but is NOT
- * allowed to use it unless given TBD
- * explicit request (should actually be
- * < DETACHED)
- */
- CHANNELCLI_ATTACHING = 2, /* legacy EFI client request
- * for EFI server to attach
- */
- CHANNELCLI_ATTACHED = 3, /* idle, but client may want
- * to use channel any time
- */
- CHANNELCLI_BUSY = 4, /* client either wants to use or is
- * using channel
- */
- CHANNELCLI_OWNED = 5 /* "no worries" state - client can */
- /* access channel anytime */
+ CHANNELCLI_DISABLED = 1,
+ CHANNELCLI_ATTACHING = 2,
+ CHANNELCLI_ATTACHED = 3,
+ CHANNELCLI_BUSY = 4,
+ CHANNELCLI_OWNED = 5
};
-#define VISOR_CHANNEL_SERVER_READY(ch) \
- (readl(&(ch)->srv_state) == CHANNELSRV_READY)
-
-#define VISOR_VALID_CHANNELCLI_TRANSITION(o, n) \
- (((((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_DISABLED)) || \
- (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_DISABLED)) || \
- (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_DISABLED)) || \
- (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_DETACHED)) || \
- (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_DETACHED)) || \
- (((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_ATTACHING)) || \
- (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_ATTACHED)) || \
- (((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_ATTACHED)) || \
- (((o) == CHANNELCLI_BUSY) && ((n) == CHANNELCLI_ATTACHED)) || \
- (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_BUSY)) || \
- (((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_OWNED)) || \
- (((o) == CHANNELCLI_DISABLED) && ((n) == CHANNELCLI_OWNED)) || \
- (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_OWNED)) || \
- (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_OWNED)) || \
- (((o) == CHANNELCLI_BUSY) && ((n) == CHANNELCLI_OWNED)) || (0)) \
- ? (1) : (0))
-
-/* Values for VISORA_CHANNEL_PROTOCOL.CliErrorBoot: */
-/* throttling invalid boot channel statetransition error due to client
- * disabled
- */
-#define VISOR_CLIERRORBOOT_THROTTLEMSG_DISABLED 0x01
-
-/* throttling invalid boot channel statetransition error due to client
- * not attached
- */
-#define VISOR_CLIERRORBOOT_THROTTLEMSG_NOTATTACHED 0x02
-
-/* throttling invalid boot channel statetransition error due to busy channel */
-#define VISOR_CLIERRORBOOT_THROTTLEMSG_BUSY 0x04
-
-/* Values for VISOR_CHANNEL_PROTOCOL.Features: This define exists so
- * that windows guest can look at the FeatureFlags in the io channel,
- * and configure the windows driver to use interrupts or not based on
- * this setting. This flag is set in uislib after the
- * VISOR_VHBA_init_channel is called. All feature bits for all
- * channels should be defined here. The io channel feature bits are
- * defined right here
+/*
+ * Values for VISOR_CHANNEL_PROTOCOL.Features: This define exists so that
+ * a guest can look at the FeatureFlags in the io channel, and configure the
+ * driver to use interrupts or not based on this setting. All feature bits for
+ * all channels should be defined here. The io channel feature bits are defined
+ * below.
*/
#define VISOR_DRIVER_ENABLES_INTS (0x1ULL << 1)
#define VISOR_CHANNEL_IS_POLLING (0x1ULL << 3)
@@ -108,171 +70,124 @@ enum channel_clientstate {
#define VISOR_DRIVER_DISABLES_INTS (0x1ULL << 5)
#define VISOR_DRIVER_ENHANCED_RCVBUF_CHECKING (0x1ULL << 6)
-/* Common Channel Header */
+/*
+ * struct channel_header - Common Channel Header
+ * @signature: Signature.
+ * @legacy_state: DEPRECATED - being replaced by.
+ * @header_size: sizeof(struct channel_header).
+ * @size: Total size of this channel in bytes.
+ * @features: Flags to modify behavior.
+ * @chtype: Channel type: data, bus, control, etc..
+ * @partition_handle: ID of guest partition.
+ * @handle: Device number of this channel in client.
+ * @ch_space_offset: Offset in bytes to channel specific area.
+ * @version_id: Struct channel_header Version ID.
+ * @partition_index: Index of guest partition.
+ * @zone_uuid: Guid of Channel's zone.
+ * @cli_str_offset: Offset from channel header to null-terminated
+ * ClientString (0 if ClientString not present).
+ * @cli_state_boot: CHANNEL_CLIENTSTATE of pre-boot EFI client of this
+ * channel.
+ * @cmd_state_cli: CHANNEL_COMMANDSTATE (overloaded in Windows drivers, see
+ * ServerStateUp, ServerStateDown, etc).
+ * @cli_state_os: CHANNEL_CLIENTSTATE of Guest OS client of this channel.
+ * @ch_characteristic: CHANNEL_CHARACTERISTIC_<xxx>.
+ * @cmd_state_srv: CHANNEL_COMMANDSTATE (overloaded in Windows drivers, see
+ * ServerStateUp, ServerStateDown, etc).
+ * @srv_state: CHANNEL_SERVERSTATE.
+ * @cli_error_boot: Bits to indicate err states for boot clients, so err
+ * messages can be throttled.
+ * @cli_error_os: Bits to indicate err states for OS clients, so err
+ * messages can be throttled.
+ * @filler: Pad out to 128 byte cacheline.
+ * @recover_channel: Please add all new single-byte values below here.
+ */
struct channel_header {
- u64 signature; /* Signature */
- u32 legacy_state; /* DEPRECATED - being replaced by */
- /* SrvState, CliStateBoot, and CliStateOS below */
- u32 header_size; /* sizeof(struct channel_header) */
- u64 size; /* Total size of this channel in bytes */
- u64 features; /* Flags to modify behavior */
- uuid_le chtype; /* Channel type: data, bus, control, etc. */
- u64 partition_handle; /* ID of guest partition */
- u64 handle; /* Device number of this channel in client */
- u64 ch_space_offset; /* Offset in bytes to channel specific area */
- u32 version_id; /* struct channel_header Version ID */
- u32 partition_index; /* Index of guest partition */
- uuid_le zone_uuid; /* Guid of Channel's zone */
- u32 cli_str_offset; /* offset from channel header to
- * nul-terminated ClientString (0 if
- * ClientString not present)
- */
- u32 cli_state_boot; /* CHANNEL_CLIENTSTATE of pre-boot
- * EFI client of this channel
- */
- u32 cmd_state_cli; /* CHANNEL_COMMANDSTATE (overloaded in
- * Windows drivers, see ServerStateUp,
- * ServerStateDown, etc)
- */
- u32 cli_state_os; /* CHANNEL_CLIENTSTATE of Guest OS
- * client of this channel
- */
- u32 ch_characteristic; /* CHANNEL_CHARACTERISTIC_<xxx> */
- u32 cmd_state_srv; /* CHANNEL_COMMANDSTATE (overloaded in
- * Windows drivers, see ServerStateUp,
- * ServerStateDown, etc)
- */
- u32 srv_state; /* CHANNEL_SERVERSTATE */
- u8 cli_error_boot; /* bits to indicate err states for
- * boot clients, so err messages can
- * be throttled
- */
- u8 cli_error_os; /* bits to indicate err states for OS
- * clients, so err messages can be
- * throttled
- */
- u8 filler[1]; /* Pad out to 128 byte cacheline */
- /* Please add all new single-byte values below here */
+ u64 signature;
+ u32 legacy_state;
+ /* SrvState, CliStateBoot, and CliStateOS below */
+ u32 header_size;
+ u64 size;
+ u64 features;
+ guid_t chtype;
+ u64 partition_handle;
+ u64 handle;
+ u64 ch_space_offset;
+ u32 version_id;
+ u32 partition_index;
+ guid_t zone_guid;
+ u32 cli_str_offset;
+ u32 cli_state_boot;
+ u32 cmd_state_cli;
+ u32 cli_state_os;
+ u32 ch_characteristic;
+ u32 cmd_state_srv;
+ u32 srv_state;
+ u8 cli_error_boot;
+ u8 cli_error_os;
+ u8 filler[1];
u8 recover_channel;
} __packed;
#define VISOR_CHANNEL_ENABLE_INTS (0x1ULL << 0)
-/* Subheader for the Signal Type variation of the Common Channel */
+/*
+ * struct signal_queue_header - Subheader for the Signal Type variation of the
+ * Common Channel.
+ * @version: SIGNAL_QUEUE_HEADER Version ID.
+ * @chtype: Queue type: storage, network.
+ * @size: Total size of this queue in bytes.
+ * @sig_base_offset: Offset to signal queue area.
+ * @features: Flags to modify behavior.
+ * @num_sent: Total # of signals placed in this queue.
+ * @num_overflows: Total # of inserts failed due to full queue.
+ * @signal_size: Total size of a signal for this queue.
+ * @max_slots: Max # of slots in queue, 1 slot is always empty.
+ * @max_signals: Max # of signals in queue (MaxSignalSlots-1).
+ * @head: Queue head signal #.
+ * @num_received: Total # of signals removed from this queue.
+ * @tail: Queue tail signal.
+ * @reserved1: Reserved field.
+ * @reserved2: Reserved field.
+ * @client_queue:
+ * @num_irq_received: Total # of Interrupts received. This is incremented by the
+ * ISR in the guest windows driver.
+ * @num_empty: Number of times that visor_signal_remove is called and
+ * returned Empty Status.
+ * @errorflags: Error bits set during SignalReinit to denote trouble with
+ * client's fields.
+ * @filler: Pad out to 64 byte cacheline.
+ */
struct signal_queue_header {
/* 1st cache line */
- u32 version; /* SIGNAL_QUEUE_HEADER Version ID */
- u32 chtype; /* Queue type: storage, network */
- u64 size; /* Total size of this queue in bytes */
- u64 sig_base_offset; /* Offset to signal queue area */
- u64 features; /* Flags to modify behavior */
- u64 num_sent; /* Total # of signals placed in this queue */
- u64 num_overflows; /* Total # of inserts failed due to
- * full queue
- */
- u32 signal_size; /* Total size of a signal for this queue */
- u32 max_slots; /* Max # of slots in queue, 1 slot is
- * always empty
- */
- u32 max_signals; /* Max # of signals in queue
- * (MaxSignalSlots-1)
- */
- u32 head; /* Queue head signal # */
+ u32 version;
+ u32 chtype;
+ u64 size;
+ u64 sig_base_offset;
+ u64 features;
+ u64 num_sent;
+ u64 num_overflows;
+ u32 signal_size;
+ u32 max_slots;
+ u32 max_signals;
+ u32 head;
/* 2nd cache line */
- u64 num_received; /* Total # of signals removed from this queue */
- u32 tail; /* Queue tail signal */
- u32 reserved1; /* Reserved field */
- u64 reserved2; /* Reserved field */
+ u64 num_received;
+ u32 tail;
+ u32 reserved1;
+ u64 reserved2;
u64 client_queue;
- u64 num_irq_received; /* Total # of Interrupts received. This
- * is incremented by the ISR in the
- * guest windows driver
- */
- u64 num_empty; /* Number of times that visor_signal_remove
- * is called and returned Empty Status.
- */
- u32 errorflags; /* Error bits set during SignalReinit
- * to denote trouble with client's
- * fields
- */
- u8 filler[12]; /* Pad out to 64 byte cacheline */
+ u64 num_irq_received;
+ u64 num_empty;
+ u32 errorflags;
+ u8 filler[12];
} __packed;
-/* Generic function useful for validating any type of channel when it is
- * received by the client that will be accessing the channel.
- * Note that <logCtx> is only needed for callers in the EFI environment, and
- * is used to pass the EFI_DIAG_CAPTURE_PROTOCOL needed to log messages.
- */
-static inline int
-visor_check_channel(struct channel_header *ch,
- uuid_le expected_uuid,
- char *chname,
- u64 expected_min_bytes,
- u32 expected_version,
- u64 expected_signature)
-{
- if (uuid_le_cmp(expected_uuid, NULL_UUID_LE) != 0) {
- /* caller wants us to verify type GUID */
- if (uuid_le_cmp(ch->chtype, expected_uuid) != 0) {
- pr_err("Channel mismatch on channel=%s(%pUL) field=type expected=%pUL actual=%pUL\n",
- chname, &expected_uuid,
- &expected_uuid, &ch->chtype);
- return 0;
- }
- }
- if (expected_min_bytes > 0) { /* verify channel size */
- if (ch->size < expected_min_bytes) {
- pr_err("Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8Lx actual=0x%-8.8Lx\n",
- chname, &expected_uuid,
- (unsigned long long)expected_min_bytes,
- ch->size);
- return 0;
- }
- }
- if (expected_version > 0) { /* verify channel version */
- if (ch->version_id != expected_version) {
- pr_err("Channel mismatch on channel=%s(%pUL) field=version expected=0x%-8.8lx actual=0x%-8.8x\n",
- chname, &expected_uuid,
- (unsigned long)expected_version,
- ch->version_id);
- return 0;
- }
- }
- if (expected_signature > 0) { /* verify channel signature */
- if (ch->signature != expected_signature) {
- pr_err("Channel mismatch on channel=%s(%pUL) field=signature expected=0x%-8.8Lx actual=0x%-8.8Lx\n",
- chname, &expected_uuid,
- expected_signature, ch->signature);
- return 0;
- }
- }
- return 1;
-}
-
-/*
- * CHANNEL Guids
- */
-
+/* CHANNEL Guids */
/* {414815ed-c58c-11da-95a9-00e08161165f} */
-#define VISOR_VHBA_CHANNEL_UUID \
- UUID_LE(0x414815ed, 0xc58c, 0x11da, \
- 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f)
-static const uuid_le visor_vhba_channel_uuid = VISOR_VHBA_CHANNEL_UUID;
-#define VISOR_VHBA_CHANNEL_UUID_STR \
+#define VISOR_VHBA_CHANNEL_GUID \
+ GUID_INIT(0x414815ed, 0xc58c, 0x11da, \
+ 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f)
+#define VISOR_VHBA_CHANNEL_GUID_STR \
"414815ed-c58c-11da-95a9-00e08161165f"
-
-/* {8cd5994d-c58e-11da-95a9-00e08161165f} */
-#define VISOR_VNIC_CHANNEL_UUID \
- UUID_LE(0x8cd5994d, 0xc58e, 0x11da, \
- 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f)
-static const uuid_le visor_vnic_channel_uuid = VISOR_VNIC_CHANNEL_UUID;
-#define VISOR_VNIC_CHANNEL_UUID_STR \
- "8cd5994d-c58e-11da-95a9-00e08161165f"
-
-/* {72120008-4AAB-11DC-8530-444553544200} */
-#define VISOR_SIOVM_UUID \
- UUID_LE(0x72120008, 0x4AAB, 0x11DC, \
- 0x85, 0x30, 0x44, 0x45, 0x53, 0x54, 0x42, 0x00)
-static const uuid_le visor_siovm_uuid = VISOR_SIOVM_UUID;
-
#endif
diff --git a/drivers/staging/unisys/include/iochannel.h b/drivers/staging/unisys/include/iochannel.h
index c7cb3fb..a70760f 100644
--- a/drivers/staging/unisys/include/iochannel.h
+++ b/drivers/staging/unisys/include/iochannel.h
@@ -1,5 +1,19 @@
-/* Copyright (C) 2010 - 2016 UNISYS CORPORATION */
-/* All rights reserved. */
+/*
+ * Copyright (C) 2010 - 2016 UNISYS CORPORATION
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for more
+ * details.
+ */
+
#ifndef __IOCHANNEL_H__
#define __IOCHANNEL_H__
@@ -7,9 +21,7 @@
* Everything needed for IOPart-GuestPart communication is define in
* this file. Note: Everything is OS-independent because this file is
* used by Windows, Linux and possible EFI drivers.
- */
-
-/*
+ *
* Communication flow between the IOPart and GuestPart uses the channel headers
* channel state. The following states are currently being used:
* UNINIT(All Zeroes), CHANNEL_ATTACHING, CHANNEL_ATTACHED, CHANNEL_OPENED
@@ -30,14 +42,10 @@
*/
#include <linux/uuid.h>
+#include <linux/skbuff.h>
-#include <linux/dma-direction.h>
#include "channel.h"
-#define VISOR_VHBA_CHANNEL_SIGNATURE VISOR_CHANNEL_SIGNATURE
-#define VISOR_VNIC_CHANNEL_SIGNATURE VISOR_CHANNEL_SIGNATURE
-#define VISOR_VSWITCH_CHANNEL_SIGNATURE VISOR_CHANNEL_SIGNATURE
-
/*
* Must increment these whenever you insert or delete fields within this channel
* struct. Also increment whenever you change the meaning of fields within this
@@ -47,82 +55,73 @@
*/
#define VISOR_VHBA_CHANNEL_VERSIONID 2
#define VISOR_VNIC_CHANNEL_VERSIONID 2
-#define VISOR_VSWITCH_CHANNEL_VERSIONID 1
-
-#define VISOR_VHBA_CHANNEL_OK_CLIENT(ch) \
- (visor_check_channel(ch, visor_vhba_channel_uuid, \
- "vhba", MIN_IO_CHANNEL_SIZE, \
- VISOR_VHBA_CHANNEL_VERSIONID, \
- VISOR_VHBA_CHANNEL_SIGNATURE))
-
-#define VISOR_VNIC_CHANNEL_OK_CLIENT(ch) \
- (visor_check_channel(ch, visor_vnic_channel_uuid, \
- "vnic", MIN_IO_CHANNEL_SIZE, \
- VISOR_VNIC_CHANNEL_VERSIONID, \
- VISOR_VNIC_CHANNEL_SIGNATURE))
/*
* Everything necessary to handle SCSI & NIC traffic between Guest Partition and
* IO Partition is defined below.
*/
-/* Defines and enums. */
-#define MINNUM(a, b) (((a) < (b)) ? (a) : (b))
-#define MAXNUM(a, b) (((a) > (b)) ? (a) : (b))
-
-/* Define the two queues per data channel between iopart and ioguestparts. */
-/* Used by ioguestpart to 'insert' signals to iopart. */
+/*
+ * Define the two queues per data channel between iopart and ioguestparts.
+ * IOCHAN_TO_IOPART -- used by guest to 'insert' signals to iopart.
+ * IOCHAN_FROM_IOPART -- used by guest to 'remove' signals from IO part.
+ */
#define IOCHAN_TO_IOPART 0
-/* Used by ioguestpart to 'remove' signals from iopart, same previous queue. */
#define IOCHAN_FROM_IOPART 1
/* Size of cdb - i.e., SCSI cmnd */
#define MAX_CMND_SIZE 16
-#define MAX_SENSE_SIZE 64
+/* Unisys-specific DMA direction values */
+enum uis_dma_data_direction {
+ UIS_DMA_BIDIRECTIONAL = 0,
+ UIS_DMA_TO_DEVICE = 1,
+ UIS_DMA_FROM_DEVICE = 2,
+ UIS_DMA_NONE = 3
+};
+#define MAX_SENSE_SIZE 64
#define MAX_PHYS_INFO 64
-/* Various types of network packets that can be sent in cmdrsp. */
+/*
+ * enum net_types - Various types of network packets that can be sent in cmdrsp.
+ * @NET_RCV_POST: Submit buffer to hold receiving incoming packet.
+ * @NET_RCV: visornic -> uisnic. Incoming packet received.
+ * @NET_XMIT: uisnic -> visornic. For outgoing packet.
+ * @NET_XMIT_DONE: visornic -> uisnic. Outgoing packet xmitted.
+ * @NET_RCV_ENBDIS: uisnic -> visornic. Enable/Disable packet reception.
+ * @NET_RCV_ENBDIS_ACK: visornic -> uisnic. Acknowledge enable/disable packet.
+ * @NET_RCV_PROMISC: uisnic -> visornic. Enable/Disable promiscuous mode.
+ * @NET_CONNECT_STATUS: visornic -> uisnic. Indicate the loss or restoration of
+ * a network connection.
+ * @NET_MACADDR: uisnic -> visornic. Indicates the client has requested
+ * to update it's MAC address.
+ * @NET_MACADDR_ACK: MAC address acknowledge.
+ */
enum net_types {
- NET_RCV_POST = 0, /*
- * Submit buffer to hold receiving
- * incoming packet
- */
- /* visornic -> uisnic */
- NET_RCV, /* incoming packet received */
- /* uisnic -> visornic */
- NET_XMIT, /* for outgoing net packets */
- /* visornic -> uisnic */
- NET_XMIT_DONE, /* outgoing packet xmitted */
- /* uisnic -> visornic */
- NET_RCV_ENBDIS, /* enable/disable packet reception */
- /* visornic -> uisnic */
- NET_RCV_ENBDIS_ACK, /* acknowledge enable/disable packet */
- /* reception */
- /* uisnic -> visornic */
- NET_RCV_PROMISC, /* enable/disable promiscuous mode */
- /* visornic -> uisnic */
- NET_CONNECT_STATUS, /*
- * indicate the loss or restoration of a network
- * connection
- */
- /* uisnic -> visornic */
- NET_MACADDR, /*
- * Indicates the client has requested to update
- * it's MAC address
- */
- NET_MACADDR_ACK, /* MAC address acknowledge */
-
+ NET_RCV_POST = 0,
+ NET_RCV,
+ NET_XMIT,
+ NET_XMIT_DONE,
+ NET_RCV_ENBDIS,
+ NET_RCV_ENBDIS_ACK,
+ /* Reception */
+ NET_RCV_PROMISC,
+ NET_CONNECT_STATUS,
+ NET_MACADDR,
+ NET_MACADDR_ACK,
};
-#define ETH_MIN_DATA_SIZE 46 /* minimum eth data size */
+/* Minimum eth data size */
+#define ETH_MIN_DATA_SIZE 46
#define ETH_MIN_PACKET_SIZE (ETH_HLEN + ETH_MIN_DATA_SIZE)
-#define VISOR_ETH_MAX_MTU 16384 /* maximum data size */
+/* Maximum data size */
+#define VISOR_ETH_MAX_MTU 16384
#ifndef MAX_MACADDR_LEN
-#define MAX_MACADDR_LEN 6 /* number of bytes in MAC address */
+/* Number of bytes in MAC address */
+#define MAX_MACADDR_LEN 6
#endif
/* Various types of scsi task mgmt commands. */
@@ -154,12 +153,16 @@ struct guest_phys_info {
u64 length;
} __packed;
-#define GPI_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(struct guest_phys_info))
-
+/*
+ * struct uisscsi_dest
+ * @channel: Bus number.
+ * @id: Target number.
+ * @lun: Logical unit number.
+ */
struct uisscsi_dest {
- u32 channel; /* channel == bus number */
- u32 id; /* id == target number */
- u32 lun; /* lun == logical unit number */
+ u32 channel;
+ u32 id;
+ u32 lun;
} __packed;
struct vhba_wwnn {
@@ -168,61 +171,77 @@ struct vhba_wwnn {
} __packed;
/*
- * WARNING: Values stired in this structure must contain maximum counts (not
+ * struct vhba_config_max
+ * @max_channel: Maximum channel for devices attached to this bus.
+ * @max_id: Maximum SCSI ID for devices attached to bus.
+ * @max_lun: Maximum SCSI LUN for devices attached to bus.
+ * @cmd_per_lun: Maximum number of outstanding commands per LUN.
+ * @max_io_size: Maximum io size for devices attached to this bus. Max io size
+ * is often determined by the resource of the hba.
+ * e.g Max scatter gather list length * page size / sector size.
+ *
+ * WARNING: Values stored in this structure must contain maximum counts (not
* maximum values).
+ *
+ * 20 bytes
*/
-struct vhba_config_max {/* 20 bytes */
- u32 max_channel;/* maximum channel for devices attached to this bus */
- u32 max_id; /* maximum SCSI ID for devices attached to bus */
- u32 max_lun; /* maximum SCSI LUN for devices attached to bus */
- u32 cmd_per_lun;/* maximum number of outstanding commands per LUN */
- u32 max_io_size;/* maximum io size for devices attached to this bus */
- /* max io size is often determined by the resource of the hba. e.g */
- /* max scatter gather list length * page size / sector size */
+struct vhba_config_max {
+ u32 max_channel;
+ u32 max_id;
+ u32 max_lun;
+ u32 cmd_per_lun;
+ u32 max_io_size;
} __packed;
+/*
+ * struct uiscmdrsp_scsi
+ *
+ * @handle: The handle to the cmd that was received. Send it back as
+ * is in the rsp packet.
+ * @cmnd: The cdb for the command.
+ * @bufflen: Length of data to be transferred out or in.
+ * @guest_phys_entries: Number of entries in scatter-gather list.
+ * @struct gpi_list: Physical address information for each fragment.
+ * @data_dir: Direction of the data, if any.
+ * @struct vdest: Identifies the virtual hba, id, channel, lun to which
+ * cmd was sent.
+ * @linuxstat: Original Linux status used by Linux vdisk.
+ * @scsistat: The scsi status.
+ * @addlstat: Non-scsi status.
+ * @sensebuf: Sense info in case cmd failed. sensebuf holds the
+ * sense_data struct. See sense_data struct for more
+ * details.
+ * @*vdisk: Pointer to the vdisk to clean up when IO completes.
+ * @no_disk_result: Used to return no disk inquiry result when
+ * no_disk_result is set to 1
+ * scsi.scsistat is SAM_STAT_GOOD
+ * scsi.addlstat is 0
+ * scsi.linuxstat is SAM_STAT_GOOD
+ * That is, there is NO error.
+ */
struct uiscmdrsp_scsi {
- u64 handle; /* the handle to the cmd that was received */
- /* send it back as is in the rsp packet. */
- u8 cmnd[MAX_CMND_SIZE]; /* the cdb for the command */
- u32 bufflen; /* length of data to be transferred out or in */
- u16 guest_phys_entries; /* Number of entries in scatter-gather list */
- struct guest_phys_info gpi_list[MAX_PHYS_INFO]; /* physical address
- * information for each
- * fragment
- */
- enum dma_data_direction data_dir; /* direction of the data, if any */
- struct uisscsi_dest vdest; /* identifies the virtual hba, id, */
- /* channel, lun to which cmd was sent */
-
+ u64 handle;
+ u8 cmnd[MAX_CMND_SIZE];
+ u32 bufflen;
+ u16 guest_phys_entries;
+ struct guest_phys_info gpi_list[MAX_PHYS_INFO];
+ u32 data_dir;
+ struct uisscsi_dest vdest;
/* Needed to queue the rsp back to cmd originator. */
- int linuxstat; /* original Linux status used by Linux vdisk */
- u8 scsistat; /* the scsi status */
- u8 addlstat; /* non-scsi status */
+ int linuxstat;
+ u8 scsistat;
+ u8 addlstat;
#define ADDL_SEL_TIMEOUT 4
-
/* The following fields are need to determine the result of command. */
- u8 sensebuf[MAX_SENSE_SIZE]; /* sense info in case cmd failed; */
- /* sensebuf holds the sense_data struct; */
- /* See sense_data struct for more details. */
- void *vdisk; /* Pointer to the vdisk to clean up when IO completes. */
+ u8 sensebuf[MAX_SENSE_SIZE];
+ void *vdisk;
int no_disk_result;
- /*
- * Used to return no disk inquiry result
- * when no_disk_result is set to 1,
- * scsi.scsistat is SAM_STAT_GOOD
- * scsi.addlstat is 0
- * scsi.linuxstat is SAM_STAT_GOOD
- * That is, there is NO error.
- */
} __packed;
/*
* Defines to support sending correct inquiry result when no disk is
* configured.
- */
-
-/*
+ *
* From SCSI SPC2 -
*
* If the target is not capable of supporting a device on this logical unit, the
@@ -234,22 +253,35 @@ struct uiscmdrsp_scsi {
* connected to this logical unit.
*/
-#define DEV_NOT_CAPABLE 0x7f /*
- * peripheral qualifier of 0x3
- * peripheral type of 0x1f
- * specifies no device but target present
- */
-
-#define DEV_DISK_CAPABLE_NOT_PRESENT 0x20 /* peripheral qualifier of 0x1
- * peripheral type of 0 - disk
- * Specifies device capable, but
- * not present
- */
+/*
+ * Peripheral qualifier of 0x3
+ * Peripheral type of 0x1f
+ * Specifies no device but target present
+ */
+#define DEV_NOT_CAPABLE 0x7f
+/*
+ * Peripheral qualifier of 0x1
+ * Peripheral type of 0 - disk
+ * Specifies device capable, but not present
+ */
+#define DEV_DISK_CAPABLE_NOT_PRESENT 0x20
+/* HiSup = 1; shows support for report luns must be returned for lun 0. */
+#define DEV_HISUPPORT 0x10
-#define DEV_HISUPPORT 0x10 /*
- * HiSup = 1; shows support for report luns
- * must be returned for lun 0.
- */
+/*
+ * Peripheral qualifier of 0x3
+ * Peripheral type of 0x1f
+ * Specifies no device but target present
+ */
+#define DEV_NOT_CAPABLE 0x7f
+/*
+ * Peripheral qualifier of 0x1
+ * Peripheral type of 0 - disk
+ * Specifies device capable, but not present
+ */
+#define DEV_DISK_CAPABLE_NOT_PRESENT 0x20
+/* HiSup = 1; shows support for report luns must be returned for lun 0. */
+#define DEV_HISUPPORT 0x10
/*
* NOTE: Linux code assumes inquiry contains 36 bytes. Without checking length
@@ -258,11 +290,12 @@ struct uiscmdrsp_scsi {
* inquiry result.
*/
#define NO_DISK_INQUIRY_RESULT_LEN 36
-
-#define MIN_INQUIRY_RESULT_LEN 5 /* 5 bytes minimum for inquiry result */
+/* 5 bytes minimum for inquiry result */
+#define MIN_INQUIRY_RESULT_LEN 5
/* SCSI device version for no disk inquiry result */
-#define SCSI_SPC2_VER 4 /* indicates SCSI SPC2 (SPC3 is 5) */
+/* indicates SCSI SPC2 (SPC3 is 5) */
+#define SCSI_SPC2_VER 4
/* Struct and Defines to support sense information. */
@@ -297,35 +330,48 @@ struct sense_data {
u8 sense_key_specific[3];
} __packed;
+/*
+ * struct net_pkt_xmt
+ * @len: Full length of data in the packet.
+ * @num_frags: Number of fragments in frags containing data.
+ * @struct phys_info frags: Physical page information.
+ * @ethhdr: The ethernet header.
+ * @struct lincsum: These are needed for csum at uisnic end.
+ * @valid: 1 = struct is valid - else ignore.
+ * @hrawoffv: 1 = hwrafoff is valid.
+ * @nhrawoffv: 1 = nhwrafoff is valid.
+ * @protocol: Specifies packet protocol.
+ * @csum: Value used to set skb->csum at IOPart.
+ * @hrawoff: Value used to set skb->h.raw at IOPart. hrawoff points to
+ * the start of the TRANSPORT LAYER HEADER.
+ * @nhrawoff: Value used to set skb->nh.raw at IOPart. nhrawoff points to
+ * the start of the NETWORK LAYER HEADER.
+ *
+ * NOTE:
+ * The full packet is described in frags but the ethernet header is
+ * separately kept in ethhdr so that uisnic doesn't have "MAP" the
+ * guest memory to get to the header. uisnic needs ethhdr to
+ * determine how to route the packet.
+ */
struct net_pkt_xmt {
- int len; /* full length of data in the packet */
- int num_frags; /* number of fragments in frags containing data */
- struct phys_info frags[MAX_PHYS_INFO]; /* physical page information */
- char ethhdr[ETH_HLEN]; /* the ethernet header */
+ int len;
+ int num_frags;
+ struct phys_info frags[MAX_PHYS_INFO];
+ char ethhdr[ETH_HLEN];
struct {
- /* These are needed for csum at uisnic end */
- u8 valid; /* 1 = struct is valid - else ignore */
- u8 hrawoffv; /* 1 = hwrafoff is valid */
- u8 nhrawoffv; /* 1 = nhwrafoff is valid */
- __be16 protocol; /* specifies packet protocol */
- __wsum csum; /* value used to set skb->csum at IOPart */
- u32 hrawoff; /* value used to set skb->h.raw at IOPart */
- /* hrawoff points to the start of the TRANSPORT LAYER HEADER */
- u32 nhrawoff; /* value used to set skb->nh.raw at IOPart */
- /* nhrawoff points to the start of the NETWORK LAYER HEADER */
+ u8 valid;
+ u8 hrawoffv;
+ u8 nhrawoffv;
+ __be16 protocol;
+ __wsum csum;
+ u32 hrawoff;
+ u32 nhrawoff;
} lincsum;
-
- /*
- * NOTE:
- * The full packet is described in frags but the ethernet header is
- * separately kept in ethhdr so that uisnic doesn't have "MAP" the
- * guest memory to get to the header. uisnic needs ethhdr to
- * determine how to route the packet.
- */
} __packed;
struct net_pkt_xmtdone {
- u32 xmt_done_result; /* result of NET_XMIT */
+ /* Result of NET_XMIT */
+ u32 xmt_done_result;
} __packed;
/*
@@ -341,14 +387,12 @@ struct net_pkt_xmtdone {
((VISOR_ETH_MAX_MTU + ETH_HLEN + RCVPOST_BUF_SIZE - 1) \
/ RCVPOST_BUF_SIZE)
-/*
- * rcv buf size must be large enough to include ethernet data len + ethernet
+/* rcv buf size must be large enough to include ethernet data len + ethernet
* header len - we are choosing 2K because it is guaranteed to be describable.
*/
struct net_pkt_rcvpost {
/* Physical page information for the single fragment 2K rcv buf */
struct phys_info frag;
-
/*
* Ensures that receive posts are returned to the adapter which we sent
* them from originally.
@@ -358,172 +402,157 @@ struct net_pkt_rcvpost {
} __packed;
/*
+ * struct net_pkt_rcv
+ * @rcv_done_len: Length of the received data.
+ * @numrcvbufs: Contains the incoming data. Guest side MUST chain these
+ * together.
+ * @*rcvbuf: List of chained rcvbufa. Each entry is a receive buffer
+ * provided by NET_RCV_POST. NOTE: First rcvbuf in the
+ * chain will also be provided in net.buf.
+ * @unique_num:
+ * @rcvs_dropped_delta:
+ *
* The number of rcvbuf that can be chained is based on max mtu and size of each
* rcvbuf.
*/
struct net_pkt_rcv {
- u32 rcv_done_len; /* length of received data */
-
- /*
- * numrcvbufs: contain the incoming data; guest side MUST chain these
- * together.
- */
+ u32 rcv_done_len;
u8 numrcvbufs;
-
- void *rcvbuf[MAX_NET_RCV_CHAIN]; /* list of chained rcvbufs */
-
- /* Each entry is a receive buffer provided by NET_RCV_POST. */
- /* NOTE: first rcvbuf in the chain will also be provided in net.buf. */
+ void *rcvbuf[MAX_NET_RCV_CHAIN];
u64 unique_num;
u32 rcvs_dropped_delta;
} __packed;
struct net_pkt_enbdis {
void *context;
- u16 enable; /* 1 = enable, 0 = disable */
+ /* 1 = enable, 0 = disable */
+ u16 enable;
} __packed;
struct net_pkt_macaddr {
void *context;
- u8 macaddr[MAX_MACADDR_LEN]; /* 6 bytes */
+ /* 6 bytes */
+ u8 macaddr[MAX_MACADDR_LEN];
} __packed;
-/* cmd rsp packet used for VNIC network traffic */
+/*
+ * struct uiscmdrsp_net - cmd rsp packet used for VNIC network traffic.
+ * @enum type:
+ * @*buf:
+ * @union:
+ * @struct xmt: Used for NET_XMIT.
+ * @struct xmtdone: Used for NET_XMIT_DONE.
+ * @struct rcvpost: Used for NET_RCV_POST.
+ * @struct rcv: Used for NET_RCV.
+ * @struct enbdis: Used for NET_RCV_ENBDIS, NET_RCV_ENBDIS_ACK,
+ * NET_RCV_PROMSIC, and NET_CONNECT_STATUS.
+ * @struct macaddr:
+ */
struct uiscmdrsp_net {
enum net_types type;
void *buf;
union {
- struct net_pkt_xmt xmt; /* used for NET_XMIT */
- struct net_pkt_xmtdone xmtdone; /* used for NET_XMIT_DONE */
- struct net_pkt_rcvpost rcvpost; /* used for NET_RCV_POST */
- struct net_pkt_rcv rcv; /* used for NET_RCV */
- struct net_pkt_enbdis enbdis; /* used for NET_RCV_ENBDIS, */
- /* NET_RCV_ENBDIS_ACK, */
- /* NET_RCV_PROMSIC, */
- /* and NET_CONNECT_STATUS */
+ struct net_pkt_xmt xmt;
+ struct net_pkt_xmtdone xmtdone;
+ struct net_pkt_rcvpost rcvpost;
+ struct net_pkt_rcv rcv;
+ struct net_pkt_enbdis enbdis;
struct net_pkt_macaddr macaddr;
};
} __packed;
+/*
+ * struct uiscmdrsp_scsitaskmgmt
+ * @enum tasktype: The type of task.
+ * @struct vdest: The vdisk for which this task mgmt is generated.
+ * @handle: This is a handle that the guest has saved off for its
+ * own use. The handle value is preserved by iopart and
+ * returned as in task mgmt rsp.
+ * @notify_handle: For Linux guests, this is a pointer to wait_queue_head
+ * that a thread is waiting on to see if the taskmgmt
+ * command has completed. When the rsp is received by
+ * guest, the thread receiving the response uses this to
+ * notify the thread waiting for taskmgmt command
+ * completion. It's value is preserved by iopart and
+ * returned as in the task mgmt rsp.
+ * @notifyresult_handle: This is a handle to the location in the guest where
+ * the result of the taskmgmt command (result field) is
+ * saved to when the response is handled. It's value is
+ * preserved by iopart and returned as is in the task mgmt
+ * rsp.
+ * @result: Result of taskmgmt command - set by IOPart.
+ */
struct uiscmdrsp_scsitaskmgmt {
- /* The type of task. */
enum task_mgmt_types tasktype;
-
- /* The vdisk for which this task mgmt is generated. */
struct uisscsi_dest vdest;
-
- /*
- * This is a handle that the guest has saved off for its own use.
- * The handle value is preserved by iopart and returned as in task
- * mgmt rsp.
- */
u64 handle;
-
- /*
- * For Linux guests, this is a pointer to wait_queue_head that a
- * thread is waiting on to see if the taskmgmt command has completed.
- * When the rsp is received by guest, the thread receiving the
- * response uses this to notify the thread waiting for taskmgmt
- * command completion. It's value is preserved by iopart and returned
- * as in the task mgmt rsp.
- */
u64 notify_handle;
-
- /*
- * This is a handle to the location in the guest where the result of
- * the taskmgmt command (result field) is saved to when the response
- * is handled. It's value is preserved by iopart and returned as in
- * the task mgmt rsp.
- */
u64 notifyresult_handle;
-
- /* Result of taskmgmt command - set by IOPart - values are: */
char result;
#define TASK_MGMT_FAILED 0
} __packed;
-/* Used by uissd to send disk add/remove notifications to Guest. */
-/* Note that the vHba pointer is not used by the Client/Guest side. */
-struct uiscmdrsp_disknotify {
- u8 add; /* 0-remove, 1-add */
- void *v_hba; /* channel info to route msg */
- u32 channel, id, lun; /* SCSI Path of Disk to added or removed */
-} __packed;
-
/*
- * The following is used by virthba/vSCSI to send the Acquire/Release commands
- * to the IOVM.
+ * struct uiscmdrsp_disknotify - Used by uissd to send disk add/remove
+ * notifications to Guest.
+ * @add: 0-remove, 1-add.
+ * @*v_hba: Channel info to route msg.
+ * @channel: SCSI Path of Disk to added or removed.
+ * @id: SCSI Path of Disk to added or removed.
+ * @lun: SCSI Path of Disk to added or removed.
+ *
+ * Note that the vHba pointer is not used by the Client/Guest side.
*/
-struct uiscmdrsp_vdiskmgmt {
- /* The type of task */
- enum vdisk_mgmt_types vdisktype;
-
- /* The vdisk for which this task mgmt is generated */
- struct uisscsi_dest vdest;
-
- /*
- * This is a handle that the guest has saved off for its own use. It's
- * value is preserved by iopart and returned as in the task mgmt rsp.
- */
- u64 handle;
-
- /*
- * For Linux guests, this is a pointer to wait_queue_head that a
- * thread is waiting on to see if the tskmgmt command has completed.
- * When the rsp is received by guest, the thread receiving the
- * response uses this to notify the thread waiting for taskmgmt
- * command completion. It's value is preserved by iopart and returned
- * as in the task mgmt rsp.
- */
- u64 notify_handle;
-
- /*
- * Handle to the location in guest where the result of the
- * taskmgmt command (result field) is saved to when the response
- * is handled. It's value is preserved by iopart and returned as in
- * the task mgmt rsp.
- */
- u64 notifyresult_handle;
-
- /* Result of taskmgmt command - set by IOPart - values are: */
- char result;
+struct uiscmdrsp_disknotify {
+ u8 add;
+ void *v_hba;
+ u32 channel, id, lun;
} __packed;
/* Keeping cmd and rsp info in one structure for now cmd rsp packet for SCSI */
struct uiscmdrsp {
char cmdtype;
-
-/* Describes what type of information is in the struct */
+ /* Describes what type of information is in the struct */
#define CMD_SCSI_TYPE 1
#define CMD_NET_TYPE 2
#define CMD_SCSITASKMGMT_TYPE 3
#define CMD_NOTIFYGUEST_TYPE 4
-#define CMD_VDISKMGMT_TYPE 5
union {
struct uiscmdrsp_scsi scsi;
struct uiscmdrsp_net net;
struct uiscmdrsp_scsitaskmgmt scsitaskmgmt;
struct uiscmdrsp_disknotify disknotify;
- struct uiscmdrsp_vdiskmgmt vdiskmgmt;
};
/* Send the response when the cmd is done (scsi and scsittaskmgmt). */
void *private_data;
- struct uiscmdrsp *next; /* General Purpose Queue Link */
- struct uiscmdrsp *activeQ_next; /* Pointer to the nextactive commands */
- struct uiscmdrsp *activeQ_prev; /* Pointer to the prevactive commands */
+ /* General Purpose Queue Link */
+ struct uiscmdrsp *next;
+ /* Pointer to the nextactive commands */
+ struct uiscmdrsp *activeQ_next;
+ /* Pointer to the prevactive commands */
+ struct uiscmdrsp *activeQ_prev;
} __packed;
+/* total = 28 bytes */
struct iochannel_vhba {
- struct vhba_wwnn wwnn; /* 8 bytes */
- struct vhba_config_max max; /* 20 bytes */
-} __packed; /* total = 28 bytes */
+ /* 8 bytes */
+ struct vhba_wwnn wwnn;
+ /* 20 bytes */
+ struct vhba_config_max max;
+} __packed;
+
struct iochannel_vnic {
- u8 macaddr[6]; /* 6 bytes */
- u32 num_rcv_bufs; /* 4 bytes */
- u32 mtu; /* 4 bytes */
- uuid_le zone_uuid; /* 16 bytes */
+ /* 6 bytes */
+ u8 macaddr[6];
+ /* 4 bytes */
+ u32 num_rcv_bufs;
+ /* 4 bytes */
+ u32 mtu;
+ /* 16 bytes */
+ guid_t zone_guid;
} __packed;
+
/*
* This is just the header of the IO channel. It is assumed that directly after
* this header there is a large region of memory which contains the command and
@@ -544,10 +573,11 @@ struct visor_io_channel {
} __packed;
/* INLINE functions for initializing and accessing I/O data channels. */
-#define SIZEOF_CMDRSP (COVER(sizeof(struct uiscmdrsp), 64))
+#define SIZEOF_CMDRSP (64 * DIV_ROUND_UP(sizeof(struct uiscmdrsp), 64))
/* Use 4K page sizes when passing page info between Guest and IOPartition. */
#define PI_PAGE_SIZE 0x1000
#define PI_PAGE_MASK 0x0FFF
-#endif /* __IOCHANNEL_H__ */
+/* __IOCHANNEL_H__ */
+#endif
diff --git a/drivers/staging/unisys/include/visorbus.h b/drivers/staging/unisys/include/visorbus.h
index de06355..e4ee38c 100644
--- a/drivers/staging/unisys/include/visorbus.h
+++ b/drivers/staging/unisys/include/visorbus.h
@@ -1,5 +1,4 @@
-/* visorbus.h
- *
+/*
* Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
@@ -23,7 +22,6 @@
*
* There should be nothing in this file that is private to the visorbus
* bus implementation itself.
- *
*/
#ifndef __VISORBUS_H__
@@ -31,20 +29,16 @@
#include <linux/device.h>
#include <linux/module.h>
-#include <linux/poll.h>
-#include <linux/kernel.h>
-#include <linux/uuid.h>
-#include <linux/seq_file.h>
#include <linux/slab.h>
#include "channel.h"
-struct visor_driver;
struct visor_device;
extern struct bus_type visorbus_type;
typedef void (*visorbus_state_complete_func) (struct visor_device *dev,
int status);
+
struct visorchipset_state {
u32 created:1;
u32 attached:1;
@@ -54,11 +48,12 @@ struct visorchipset_state {
/* Remaining bits in this 32-bit word are unused. */
};
-/** This struct describes a specific Supervisor channel, by providing its
- * GUID, name, and sizes.
+/*
+ * This struct describes a specific Supervisor channel, by providing its
+ * GUID, name, and sizes.
*/
struct visor_channeltype_descriptor {
- const uuid_le guid;
+ const guid_t guid;
const char *name;
};
@@ -109,8 +104,7 @@ struct visor_driver {
struct device_driver driver;
};
-#define to_visor_driver(x) ((x) ? \
- (container_of(x, struct visor_driver, driver)) : (NULL))
+#define to_visor_driver(x) (container_of(x, struct visor_driver, driver))
/**
* struct visor_device - A device type for things "plugged" into the visorbus
@@ -125,8 +119,8 @@ struct visor_driver {
* activity.
* @being_removed: Indicates that the device is being removed from
* the bus. Private bus driver use only.
- * @visordriver_callback_lock: Used by the bus driver to lock when handling
- * channel events.
+ * @visordriver_callback_lock: Used by the bus driver to lock when adding and
+ * removing devices.
* @pausing: Indicates that a change towards a paused state.
* is in progress. Only modified by the bus driver.
* @resuming: Indicates that a change towards a running state
@@ -141,37 +135,42 @@ struct visor_driver {
* hypervisor requests.
* @vbus_hdr_info: A pointer to header info. Private use by bus
* driver.
- * @partition_uuid: Indicates client partion id. This should be the
+ * @partition_guid: Indicates client partion id. This should be the
* same across all visor_devices in the current
* guest. Private use by bus driver only.
*/
struct visor_device {
struct visorchannel *visorchannel;
- uuid_le channel_type_guid;
+ guid_t channel_type_guid;
/* These fields are for private use by the bus driver only. */
struct device device;
struct list_head list_all;
struct timer_list timer;
bool timer_active;
bool being_removed;
- struct mutex visordriver_callback_lock;
+ struct mutex visordriver_callback_lock; /* synchronize probe/remove */
bool pausing;
bool resuming;
u32 chipset_bus_no;
u32 chipset_dev_no;
struct visorchipset_state state;
- uuid_le inst;
+ guid_t inst;
u8 *name;
struct controlvm_message_header *pending_msg_hdr;
void *vbus_hdr_info;
- uuid_le partition_uuid;
+ guid_t partition_guid;
struct dentry *debugfs_dir;
struct dentry *debugfs_client_bus_info;
};
#define to_visor_device(x) container_of(x, struct visor_device, device)
+int visor_check_channel(struct channel_header *ch, struct device *dev,
+ const guid_t *expected_uuid, char *chname,
+ u64 expected_min_bytes, u32 expected_version,
+ u64 expected_signature);
+
int visorbus_register_visor_driver(struct visor_driver *drv);
void visorbus_unregister_visor_driver(struct visor_driver *drv);
int visorbus_read_channel(struct visor_device *dev,
@@ -183,7 +182,8 @@ int visorbus_write_channel(struct visor_device *dev,
int visorbus_enable_channel_interrupts(struct visor_device *dev);
void visorbus_disable_channel_interrupts(struct visor_device *dev);
-/* Levels of severity for diagnostic events, in order from lowest severity to
+/*
+ * Levels of severity for diagnostic events, in order from lowest severity to
* highest (i.e. fatal errors are the most severe, and should always be logged,
* but info events rarely need to be logged except during debugging). The
* values DIAG_SEVERITY_ENUM_BEGIN and DIAG_SEVERITY_ENUM_END are not valid
@@ -207,7 +207,7 @@ int visorchannel_signalremove(struct visorchannel *channel, u32 queue,
int visorchannel_signalinsert(struct visorchannel *channel, u32 queue,
void *msg);
bool visorchannel_signalempty(struct visorchannel *channel, u32 queue);
-uuid_le visorchannel_get_uuid(struct visorchannel *channel);
+const guid_t *visorchannel_get_guid(struct visorchannel *channel);
#define BUS_ROOT_DEVICE UINT_MAX
struct visor_device *visorbus_get_device_by_id(u32 bus_no, u32 dev_no,
diff --git a/drivers/staging/unisys/visorbus/controlvmchannel.h b/drivers/staging/unisys/visorbus/controlvmchannel.h
index ed045ef..32ff5c1 100644
--- a/drivers/staging/unisys/visorbus/controlvmchannel.h
+++ b/drivers/staging/unisys/visorbus/controlvmchannel.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 2010 - 2015 UNISYS CORPORATION
+/*
+ * Copyright (C) 2010 - 2015 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
@@ -19,60 +20,55 @@
#include "channel.h"
/* {2B3C2D10-7EF5-4ad8-B966-3448B7386B3D} */
-#define VISOR_CONTROLVM_CHANNEL_UUID \
- UUID_LE(0x2b3c2d10, 0x7ef5, 0x4ad8, \
- 0xb9, 0x66, 0x34, 0x48, 0xb7, 0x38, 0x6b, 0x3d)
+#define VISOR_CONTROLVM_CHANNEL_GUID \
+ GUID_INIT(0x2b3c2d10, 0x7ef5, 0x4ad8, \
+ 0xb9, 0x66, 0x34, 0x48, 0xb7, 0x38, 0x6b, 0x3d)
-#define VISOR_CONTROLVM_CHANNEL_SIGNATURE VISOR_CHANNEL_SIGNATURE
#define CONTROLVM_MESSAGE_MAX 64
-/* Must increment this whenever you insert or delete fields within
- * this channel struct. Also increment whenever you change the meaning
- * of fields within this channel struct so as to break pre-existing
- * software. Note that you can usually add fields to the END of the
- * channel struct withOUT needing to increment this.
+/*
+ * Must increment this whenever you insert or delete fields within this channel
+ * struct. Also increment whenever you change the meaning of fields within this
+ * channel struct so as to break pre-existing software. Note that you can
+ * usually add fields to the END of the channel struct withOUT needing to
+ * increment this.
*/
#define VISOR_CONTROLVM_CHANNEL_VERSIONID 1
-#define VISOR_CONTROLVM_CHANNEL_OK_CLIENT(ch) \
- (visor_check_channel(ch, \
- VISOR_CONTROLVM_CHANNEL_UUID, \
- "controlvm", \
- sizeof(struct visor_controlvm_channel), \
- VISOR_CONTROLVM_CHANNEL_VERSIONID, \
- VISOR_CONTROLVM_CHANNEL_SIGNATURE))
-
/* Defines for various channel queues */
-#define CONTROLVM_QUEUE_REQUEST 0
-#define CONTROLVM_QUEUE_RESPONSE 1
-#define CONTROLVM_QUEUE_EVENT 2
-#define CONTROLVM_QUEUE_ACK 3
+#define CONTROLVM_QUEUE_REQUEST 0
+#define CONTROLVM_QUEUE_RESPONSE 1
+#define CONTROLVM_QUEUE_EVENT 2
+#define CONTROLVM_QUEUE_ACK 3
/* Max num of messages stored during IOVM creation to be reused after crash */
#define CONTROLVM_CRASHMSG_MAX 2
+/*
+ * struct visor_segment_state
+ * @enabled: May enter other states.
+ * @active: Assigned to active partition.
+ * @alive: Configure message sent to service/server.
+ * @revoked: Similar to partition state ShuttingDown.
+ * @allocated: Memory (device/port number) has been selected by Command.
+ * @known: Has been introduced to the service/guest partition.
+ * @ready: Service/Guest partition has responded to introduction.
+ * @operating: Resource is configured and operating.
+ * @reserved: Natural alignment.
+ *
+ * Note: Don't use high bit unless we need to switch to ushort which is
+ * non-compliant.
+ */
struct visor_segment_state {
- /* Bit 0: May enter other states */
u16 enabled:1;
- /* Bit 1: Assigned to active partition */
u16 active:1;
- /* Bit 2: Configure message sent to service/server */
u16 alive:1;
- /* Bit 3: similar to partition state ShuttingDown */
u16 revoked:1;
- /* Bit 4: memory (device/port number) has been selected by Command */
u16 allocated:1;
- /* Bit 5: has been introduced to the service/guest partition */
u16 known:1;
- /* Bit 6: service/Guest partition has responded to introduction */
u16 ready:1;
- /* Bit 7: resource is configured and operating */
u16 operating:1;
- /* Natural alignment*/
u16 reserved:8;
-/* Note: don't use high bit unless we need to switch to ushort
- * which is non-compliant
- */
} __packed;
static const struct visor_segment_state segment_state_running = {
@@ -87,74 +83,101 @@ static const struct visor_segment_state segment_state_standby = {
1, 1, 0, 0, 1, 1, 1, 0
};
-/* Ids for commands that may appear in either queue of a ControlVm channel.
+/*
+ * enum controlvm_id
+ * @CONTROLVM_INVALID:
+ * @CONTROLVM_BUS_CREATE: CP --> SP, GP.
+ * @CONTROLVM_BUS_DESTROY: CP --> SP, GP.
+ * @CONTROLVM_BUS_CONFIGURE: CP --> SP.
+ * @CONTROLVM_BUS_CHANGESTATE: CP --> SP, GP.
+ * @CONTROLVM_BUS_CHANGESTATE_EVENT: SP, GP --> CP.
+ * @CONTROLVM_DEVICE_CREATE: CP --> SP, GP.
+ * @CONTROLVM_DEVICE_DESTROY: CP --> SP, GP.
+ * @CONTROLVM_DEVICE_CONFIGURE: CP --> SP.
+ * @CONTROLVM_DEVICE_CHANGESTATE: CP --> SP, GP.
+ * @CONTROLVM_DEVICE_CHANGESTATE_EVENT: SP, GP --> CP.
+ * @CONTROLVM_DEVICE_RECONFIGURE: CP --> Boot.
+ * @CONTROLVM_CHIPSET_INIT: CP --> SP, GP.
+ * @CONTROLVM_CHIPSET_STOP: CP --> SP, GP.
+ * @CONTROLVM_CHIPSET_READY: CP --> SP.
+ * @CONTROLVM_CHIPSET_SELFTEST: CP --> SP.
*
- * Commands that are initiated by the command partition (CP), by an IO or
- * console service partition (SP), or by a guest partition (GP)are:
- * - issued on the RequestQueue queue (q #0) in the ControlVm channel
- * - responded to on the ResponseQueue queue (q #1) in the ControlVm channel
+ * Ids for commands that may appear in either queue of a ControlVm channel.
*
- * Events that are initiated by an IO or console service partition (SP) or
- * by a guest partition (GP) are:
- * - issued on the EventQueue queue (q #2) in the ControlVm channel
- * - responded to on the EventAckQueue queue (q #3) in the ControlVm channel
+ * Commands that are initiated by the command partition (CP), by an IO or
+ * console service partition (SP), or by a guest partition (GP) are:
+ * - issued on the RequestQueue queue (q #0) in the ControlVm channel
+ * - responded to on the ResponseQueue queue (q #1) in the ControlVm channel
+ *
+ * Events that are initiated by an IO or console service partition (SP) or
+ * by a guest partition (GP) are:
+ * - issued on the EventQueue queue (q #2) in the ControlVm channel
+ * - responded to on the EventAckQueue queue (q #3) in the ControlVm channel
*/
enum controlvm_id {
CONTROLVM_INVALID = 0,
- /* SWITCH commands required Parameter: SwitchNumber */
- /* BUS commands required Parameter: BusNumber */
- CONTROLVM_BUS_CREATE = 0x101, /* CP --> SP, GP */
- CONTROLVM_BUS_DESTROY = 0x102, /* CP --> SP, GP */
- CONTROLVM_BUS_CONFIGURE = 0x104, /* CP --> SP */
- CONTROLVM_BUS_CHANGESTATE = 0x105, /* CP --> SP, GP */
- CONTROLVM_BUS_CHANGESTATE_EVENT = 0x106, /* SP, GP --> CP */
-/* DEVICE commands required Parameter: BusNumber, DeviceNumber */
-
- CONTROLVM_DEVICE_CREATE = 0x201, /* CP --> SP, GP */
- CONTROLVM_DEVICE_DESTROY = 0x202, /* CP --> SP, GP */
- CONTROLVM_DEVICE_CONFIGURE = 0x203, /* CP --> SP */
- CONTROLVM_DEVICE_CHANGESTATE = 0x204, /* CP --> SP, GP */
- CONTROLVM_DEVICE_CHANGESTATE_EVENT = 0x205, /* SP, GP --> CP */
- CONTROLVM_DEVICE_RECONFIGURE = 0x206, /* CP --> Boot */
-/* CHIPSET commands */
- CONTROLVM_CHIPSET_INIT = 0x301, /* CP --> SP, GP */
- CONTROLVM_CHIPSET_STOP = 0x302, /* CP --> SP, GP */
- CONTROLVM_CHIPSET_READY = 0x304, /* CP --> SP */
- CONTROLVM_CHIPSET_SELFTEST = 0x305, /* CP --> SP */
-
+ /*
+ * SWITCH commands required Parameter: SwitchNumber.
+ * BUS commands required Parameter: BusNumber
+ */
+ CONTROLVM_BUS_CREATE = 0x101,
+ CONTROLVM_BUS_DESTROY = 0x102,
+ CONTROLVM_BUS_CONFIGURE = 0x104,
+ CONTROLVM_BUS_CHANGESTATE = 0x105,
+ CONTROLVM_BUS_CHANGESTATE_EVENT = 0x106,
+ /* DEVICE commands required Parameter: BusNumber, DeviceNumber */
+ CONTROLVM_DEVICE_CREATE = 0x201,
+ CONTROLVM_DEVICE_DESTROY = 0x202,
+ CONTROLVM_DEVICE_CONFIGURE = 0x203,
+ CONTROLVM_DEVICE_CHANGESTATE = 0x204,
+ CONTROLVM_DEVICE_CHANGESTATE_EVENT = 0x205,
+ CONTROLVM_DEVICE_RECONFIGURE = 0x206,
+ /* CHIPSET commands */
+ CONTROLVM_CHIPSET_INIT = 0x301,
+ CONTROLVM_CHIPSET_STOP = 0x302,
+ CONTROLVM_CHIPSET_READY = 0x304,
+ CONTROLVM_CHIPSET_SELFTEST = 0x305,
};
+/*
+ * struct irq_info
+ * @reserved1: Natural alignment purposes
+ * @recv_irq_handle: Specifies interrupt handle. It is used to retrieve the
+ * corresponding interrupt pin from Monitor; and the interrupt
+ * pin is used to connect to the corresponding interrupt.
+ * Used by IOPart-GP only.
+ * @recv_irq_vector: Specifies interrupt vector. It, interrupt pin, and shared
+ * are used to connect to the corresponding interrupt.
+ * Used by IOPart-GP only.
+ * @recv_irq_shared: Specifies if the recvInterrupt is shared. It, interrupt
+ * pin and vector are used to connect to 0 = not shared;
+ * 1 = shared the corresponding interrupt.
+ * Used by IOPart-GP only.
+ * @reserved: Natural alignment purposes
+ */
struct irq_info {
u64 reserved1;
-
- /* specifies interrupt handle. It is used to retrieve the
- * corresponding interrupt pin from Monitor; and the
- * interrupt pin is used to connect to the corresponding
- * interrupt. Used by IOPart-GP only.
- */
u64 recv_irq_handle;
-
- /* specifies interrupt vector. It, interrupt pin, and shared are
- * used to connect to the corresponding interrupt. Used by
- * IOPart-GP only.
- */
u32 recv_irq_vector;
-
- /* specifies if the recvInterrupt is shared. It, interrupt pin
- * and vector are used to connect to 0 = not shared; 1 = shared.
- * the corresponding interrupt. Used by IOPart-GP only.
- */
u8 recv_irq_shared;
- u8 reserved[3]; /* Natural alignment purposes */
+ u8 reserved[3];
} __packed;
+/*
+ * struct efi_visor_indication
+ * @boot_to_fw_ui: Stop in UEFI UI
+ * @clear_nvram: Clear NVRAM
+ * @clear_cmos: Clear CMOS
+ * @boot_to_tool: Run install tool
+ * @reserved: Natural alignment
+ */
struct efi_visor_indication {
- u64 boot_to_fw_ui:1; /* Bit 0: Stop in uefi ui */
- u64 clear_nvram:1; /* Bit 1: Clear NVRAM */
- u64 clear_cmos:1; /* Bit 2: Clear CMOS */
- u64 boot_to_tool:1; /* Bit 3: Run install tool */
- /* remaining bits are available */
- u64 reserved:60; /* Natural alignment */
+ u64 boot_to_fw_ui:1;
+ u64 clear_nvram:1;
+ u64 clear_cmos:1;
+ u64 boot_to_tool:1;
+ /* Remaining bits are available */
+ u64 reserved:60;
} __packed;
enum visor_chipset_feature {
@@ -162,182 +185,248 @@ enum visor_chipset_feature {
VISOR_CHIPSET_FEATURE_PARA_HOTPLUG = 0x00000002,
};
-/* This is the common structure that is at the beginning of every
- * ControlVm message (both commands and responses) in any ControlVm
- * queue. Commands are easily distinguished from responses by
- * looking at the flags.response field.
+/*
+ * struct controlvm_message_header
+ * @id: See CONTROLVM_ID.
+ * @message_size: Includes size of this struct + size of message.
+ * @segment_index: Index of segment containing Vm message/information.
+ * @completion_status: Error status code or result of message completion.
+ * @struct flags:
+ * @failed: =1 in a response to signify failure.
+ * @response_expected: =1 in all messages that expect a response.
+ * @server: =1 in all bus & device-related messages where the
+ * message receiver is to act as the bus or device
+ * server.
+ * @test_message: =1 for testing use only (Control and Command
+ * ignore this).
+ * @partial_completion: =1 if there are forthcoming responses/acks
+ * associated with this message.
+ * @preserve: =1 this is to let us know to preserve channel
+ * contents.
+ * @writer_in_diag: =1 the DiagWriter is active in the Diagnostic
+ * Partition.
+ * @reserve: Natural alignment.
+ * @reserved: Natural alignment.
+ * @message_handle: Identifies the particular message instance.
+ * @payload_vm_offset: Offset of payload area from start of this instance.
+ * @payload_max_bytes: Maximum bytes allocated in payload area of ControlVm
+ * segment.
+ * @payload_bytes: Actual number of bytes of payload area to copy between
+ * IO/Command. If non-zero, there is a payload to copy.
+ *
+ * This is the common structure that is at the beginning of every
+ * ControlVm message (both commands and responses) in any ControlVm
+ * queue. Commands are easily distinguished from responses by
+ * looking at the flags.response field.
*/
struct controlvm_message_header {
- u32 id; /* See CONTROLVM_ID. */
- /* For requests, indicates the message type. */
- /* For responses, indicates the type of message we are responding to. */
-
- /* Includes size of this struct + size of message */
+ u32 id;
+ /*
+ * For requests, indicates the message type. For responses, indicates
+ * the type of message we are responding to.
+ */
u32 message_size;
- /* Index of segment containing Vm message/information */
u32 segment_index;
- /* Error status code or result of message completion */
u32 completion_status;
struct {
- /* =1 in a response to signify failure */
u32 failed:1;
- /* =1 in all messages that expect a response */
u32 response_expected:1;
- /* =1 in all bus & device-related messages where the message
- * receiver is to act as the bus or device server
- */
u32 server:1;
- /* =1 for testing use only (Control and Command ignore this */
u32 test_message:1;
- /* =1 if there are forthcoming responses/acks associated
- * with this message
- */
u32 partial_completion:1;
- /* =1 this is to let us know to preserve channel contents */
u32 preserve:1;
- /* =1 the DiagWriter is active in the Diagnostic Partition */
u32 writer_in_diag:1;
- /* Natural alignment */
u32 reserve:25;
} __packed flags;
- /* Natural alignment */
u32 reserved;
- /* Identifies the particular message instance */
u64 message_handle;
- /* request instances with the corresponding response instance. */
- /* Offset of payload area from start of this instance */
u64 payload_vm_offset;
- /* Maximum bytes allocated in payload area of ControlVm segment */
u32 payload_max_bytes;
- /* Actual number of bytes of payload area to copy between IO/Command */
u32 payload_bytes;
- /* if non-zero, there is a payload to copy. */
} __packed;
+/*
+ * struct controlvm_packet_device_create - For CONTROLVM_DEVICE_CREATE
+ * @bus_no: Bus # (0..n-1) from the msg receiver's end.
+ * @dev_no: Bus-relative (0..n-1) device number.
+ * @channel_addr: Guest physical address of the channel, which can be
+ * dereferenced by the receiver of this ControlVm command.
+ * @channel_bytes: Specifies size of the channel in bytes.
+ * @data_type_uuid: Specifies format of data in channel.
+ * @dev_inst_uuid: Instance guid for the device.
+ * @irq_info intr: Specifies interrupt information.
+ */
struct controlvm_packet_device_create {
- u32 bus_no; /* bus # (0..n-1) from the msg receiver's end */
- u32 dev_no; /* bus-relative (0..n-1) device number */
- /* Guest physical address of the channel, which can be dereferenced by
- * the receiver of this ControlVm command
- */
+ u32 bus_no;
+ u32 dev_no;
u64 channel_addr;
- u64 channel_bytes; /* specifies size of the channel in bytes */
- uuid_le data_type_uuid; /* specifies format of data in channel */
- uuid_le dev_inst_uuid; /* instance guid for the device */
- struct irq_info intr; /* specifies interrupt information */
-} __packed; /* for CONTROLVM_DEVICE_CREATE */
+ u64 channel_bytes;
+ guid_t data_type_guid;
+ guid_t dev_inst_guid;
+ struct irq_info intr;
+} __packed;
+/*
+ * struct controlvm_packet_device_configure - For CONTROLVM_DEVICE_CONFIGURE
+ * @bus_no: Bus number (0..n-1) from the msg receiver's perspective.
+ * @dev_no: Bus-relative (0..n-1) device number.
+ */
struct controlvm_packet_device_configure {
- /* bus # (0..n-1) from the msg receiver's perspective */
u32 bus_no;
- /* Control uses header SegmentIndex field to access bus number... */
- u32 dev_no; /* bus-relative (0..n-1) device number */
-} __packed; /* for CONTROLVM_DEVICE_CONFIGURE */
+ u32 dev_no;
+} __packed;
+/* Total 128 bytes */
struct controlvm_message_device_create {
struct controlvm_message_header header;
struct controlvm_packet_device_create packet;
-} __packed; /* total 128 bytes */
+} __packed;
+/* Total 56 bytes */
struct controlvm_message_device_configure {
struct controlvm_message_header header;
struct controlvm_packet_device_configure packet;
-} __packed; /* total 56 bytes */
+} __packed;
-/* This is the format for a message in any ControlVm queue. */
+/*
+ * struct controlvm_message_packet - This is the format for a message in any
+ * ControlVm queue.
+ * @struct create_bus: For CONTROLVM_BUS_CREATE.
+ * @bus_no: Bus # (0..n-1) from the msg receiver's perspective.
+ * @dev_count: Indicates the max number of devices on this bus.
+ * @channel_addr: Guest physical address of the channel, which can be
+ * dereferenced by the receiver of this ControlVM
+ * command.
+ * @channel_bytes: Size of the channel.
+ * @bus_data_type_uuid: Indicates format of data in bus channel.
+ * @bus_inst_uuid: Instance uuid for the bus.
+ *
+ * @struct destroy_bus: For CONTROLVM_BUS_DESTROY.
+ * @bus_no: Bus # (0..n-1) from the msg receiver's perspective.
+ * @reserved: Natural alignment purposes.
+ *
+ * @struct configure_bus: For CONTROLVM_BUS_CONFIGURE.
+ * @bus_no: Bus # (0..n-1) from the receiver's perspective.
+ * @reserved1: For alignment purposes.
+ * @guest_handle: This is used to convert guest physical address to
+ * physical address.
+ * @recv_bus_irq_handle: Specifies interrupt info. It is used by SP to
+ * register to receive interrupts from the CP. This
+ * interrupt is used for bus level notifications.
+ * The corresponding sendBusInterruptHandle is kept
+ * in CP.
+ *
+ * @struct create_device: For CONTROLVM_DEVICE_CREATE.
+ *
+ * @struct destroy_device: For CONTROLVM_DEVICE_DESTROY.
+ * @bus_no: Bus # (0..n-1) from the msg receiver's perspective.
+ * @dev_no: Bus-relative (0..n-1) device number.
+ *
+ * @struct configure_device: For CONTROLVM_DEVICE_CONFIGURE.
+ *
+ * @struct reconfigure_device: For CONTROLVM_DEVICE_RECONFIGURE.
+ * @bus_no: Bus # (0..n-1) from the msg receiver's perspective.
+ * @dev_no: Bus-relative (0..n-1) device number.
+ *
+ * @struct bus_change_state: For CONTROLVM_BUS_CHANGESTATE.
+ * @bus_no:
+ * @struct state:
+ * @reserved: Natural alignment purposes.
+ *
+ * @struct device_change_state: For CONTROLVM_DEVICE_CHANGESTATE.
+ * @bus_no:
+ * @dev_no:
+ * @struct state:
+ * @struct flags:
+ * @phys_device: =1 if message is for a physical device.
+ * @reserved: Natural alignment.
+ * @reserved1: Natural alignment.
+ * @reserved: Natural alignment purposes.
+ *
+ * @struct device_change_state_event: For CONTROLVM_DEVICE_CHANGESTATE_EVENT.
+ * @bus_no:
+ * @dev_no:
+ * @struct state:
+ * @reserved: Natural alignment purposes.
+ *
+ * @struct init_chipset: For CONTROLVM_CHIPSET_INIT.
+ * @bus_count: Indicates the max number of busses.
+ * @switch_count: Indicates the max number of switches.
+ * @enum features:
+ * @platform_number:
+ *
+ * @struct chipset_selftest: For CONTROLVM_CHIPSET_SELFTEST.
+ * @options: Reserved.
+ * @test: Bit 0 set to run embedded selftest.
+ *
+ * @addr: A physical address of something, that can be dereferenced by the
+ * receiver of this ControlVm command.
+ *
+ * @handle: A handle of something (depends on command id).
+ */
struct controlvm_message_packet {
union {
struct {
- /* bus # (0..n-1) from the msg receiver's perspective */
u32 bus_no;
- /* indicates the max number of devices on this bus */
u32 dev_count;
- /* Guest physical address of the channel, which can be
- * dereferenced by the receiver of this ControlVm command
- */
u64 channel_addr;
- u64 channel_bytes; /* size of the channel */
- /* indicates format of data in bus channel*/
- uuid_le bus_data_type_uuid;
- uuid_le bus_inst_uuid; /* instance uuid for the bus */
- } __packed create_bus; /* for CONTROLVM_BUS_CREATE */
+ u64 channel_bytes;
+ guid_t bus_data_type_guid;
+ guid_t bus_inst_guid;
+ } __packed create_bus;
struct {
- /* bus # (0..n-1) from the msg receiver's perspective */
u32 bus_no;
- u32 reserved; /* Natural alignment purposes */
- } __packed destroy_bus; /* for CONTROLVM_BUS_DESTROY */
+ u32 reserved;
+ } __packed destroy_bus;
struct {
- /* bus # (0..n-1) from the receiver's perspective */
u32 bus_no;
- u32 reserved1; /* for alignment purposes */
- /* This is used to convert guest physical address to physical address */
+ u32 reserved1;
u64 guest_handle;
u64 recv_bus_irq_handle;
- /* specifies interrupt info. It is used by SP
- * to register to receive interrupts from the
- * CP. This interrupt is used for bus level
- * notifications. The corresponding
- * sendBusInterruptHandle is kept in CP.
- */
- } __packed configure_bus; /* for CONTROLVM_BUS_CONFIGURE */
- /* for CONTROLVM_DEVICE_CREATE */
+ } __packed configure_bus;
struct controlvm_packet_device_create create_device;
struct {
- /* bus # (0..n-1) from the msg receiver's perspective */
u32 bus_no;
- u32 dev_no; /* bus-relative (0..n-1) device # */
- } __packed destroy_device; /* for CONTROLVM_DEVICE_DESTROY */
- /* for CONTROLVM_DEVICE_CONFIGURE */
+ u32 dev_no;
+ } __packed destroy_device;
struct controlvm_packet_device_configure configure_device;
struct {
- /* bus # (0..n-1) from the msg receiver's perspective */
u32 bus_no;
- u32 dev_no; /* bus-relative (0..n-1) device # */
+ u32 dev_no;
} __packed reconfigure_device;
- /* for CONTROLVM_DEVICE_RECONFIGURE */
struct {
u32 bus_no;
struct visor_segment_state state;
- u8 reserved[2]; /* Natural alignment purposes */
- } __packed bus_change_state; /* for CONTROLVM_BUS_CHANGESTATE */
+ u8 reserved[2];
+ } __packed bus_change_state;
struct {
u32 bus_no;
u32 dev_no;
struct visor_segment_state state;
struct {
- /* =1 if message is for a physical device */
u32 phys_device:1;
- u32 reserved:31; /* Natural alignment */
- u32 reserved1; /* Natural alignment */
+ u32 reserved:31;
+ u32 reserved1;
} __packed flags;
- u8 reserved[2]; /* Natural alignment purposes */
+ u8 reserved[2];
} __packed device_change_state;
- /* for CONTROLVM_DEVICE_CHANGESTATE */
struct {
u32 bus_no;
u32 dev_no;
struct visor_segment_state state;
- u8 reserved[6]; /* Natural alignment purposes */
+ u8 reserved[6];
} __packed device_change_state_event;
- /* for CONTROLVM_DEVICE_CHANGESTATE_EVENT */
struct {
- /* indicates the max number of busses */
u32 bus_count;
- /* indicates the max number of switches */
u32 switch_count;
enum visor_chipset_feature features;
- u32 platform_number; /* Platform Number */
- } __packed init_chipset; /* for CONTROLVM_CHIPSET_INIT */
+ u32 platform_number;
+ } __packed init_chipset;
struct {
- u32 options; /* reserved */
- u32 test; /* bit 0 set to run embedded selftest */
+ u32 options;
+ u32 test;
} __packed chipset_selftest;
- /* for CONTROLVM_CHIPSET_SELFTEST */
- /* a physical address of something, that can be dereferenced
- * by the receiver of this ControlVm command
- */
u64 addr;
- /* a handle of something (depends on command id) */
u64 handle;
};
} __packed;
@@ -348,93 +437,139 @@ struct controlvm_message {
struct controlvm_message_packet cmd;
} __packed;
+/*
+ * struct visor_controlvm_channel
+ * @struct header:
+ * @gp_controlvm: Guest phys addr of this channel.
+ * @gp_partition_tables: Guest phys addr of partition tables.
+ * @gp_diag_guest: Guest phys addr of diagnostic channel.
+ * @gp_boot_romdisk: Guest phys addr of (read* only) Boot
+ * ROM disk.
+ * @gp_boot_ramdisk: Guest phys addr of writable Boot RAM
+ * disk.
+ * @gp_acpi_table: Guest phys addr of acpi table.
+ * @gp_control_channel: Guest phys addr of control channel.
+ * @gp_diag_romdisk: Guest phys addr of diagnostic ROM disk.
+ * @gp_nvram: Guest phys addr of NVRAM channel.
+ * @request_payload_offset: Offset to request payload area.
+ * @event_payload_offset: Offset to event payload area.
+ * @request_payload_bytes: Bytes available in request payload area.
+ * @event_payload_bytes: Bytes available in event payload area.
+ * @control_channel_bytes:
+ * @nvram_channel_bytes: Bytes in PartitionNvram segment.
+ * @message_bytes: sizeof(CONTROLVM_MESSAGE).
+ * @message_count: CONTROLVM_MESSAGE_MAX.
+ * @gp_smbios_table: Guest phys addr of SMBIOS tables.
+ * @gp_physical_smbios_table: Guest phys addr of SMBIOS table.
+ * @gp_reserved: VISOR_MAX_GUESTS_PER_SERVICE.
+ * @virtual_guest_firmware_image_base: Guest physical address of EFI firmware
+ * image base.
+ * @virtual_guest_firmware_entry_point: Guest physical address of EFI firmware
+ * entry point.
+ * @virtual_guest_firmware_image_size: Guest EFI firmware image size.
+ * @virtual_guest_firmware_boot_base: GPA = 1MB where EFI firmware image is
+ * copied to.
+ * @virtual_guest_image_base:
+ * @virtual_guest_image_size:
+ * @prototype_control_channel_offset:
+ * @virtual_guest_partition_handle:
+ * @restore_action: Restore Action field to restore the
+ * guest partition.
+ * @dump_action: For Windows guests it shows if the
+ * visordisk is in dump mode.
+ * @nvram_fail_count:
+ * @saved_crash_message_count: = CONTROLVM_CRASHMSG_MAX.
+ * @saved_crash_message_offset: Offset to request payload area needed
+ * for crash dump.
+ * @installation_error: Type of error encountered during
+ * installation.
+ * @installation_text_id: Id of string to display.
+ * @installation_remaining_steps: Number of remaining installation steps
+ * (for progress bars).
+ * @tool_action: VISOR_TOOL_ACTIONS Installation Action
+ * field.
+ * @reserved: Alignment.
+ * @struct efi_visor_ind:
+ * @sp_reserved:
+ * @reserved2: Force signals to begin on 128-byte
+ * cache line.
+ * @struct request_queue: Guest partition uses this queue to send
+ * requests to Control.
+ * @struct response_queue: Control uses this queue to respond to
+ * service or guest partition request.
+ * @struct event_queue: Control uses this queue to send events
+ * to guest partition.
+ * @struct event_ack_queue: Service or guest partition uses this
+ * queue to ack Control events.
+ * @struct request_msg: Request fixed-size message pool -
+ * does not include payload.
+ * @struct response_msg: Response fixed-size message pool -
+ * does not include payload.
+ * @struct event_msg: Event fixed-size message pool -
+ * does not include payload.
+ * @struct event_ack_msg: Ack fixed-size message pool -
+ * does not include payload.
+ * @struct saved_crash_msg: Message stored during IOVM creation to
+ * be reused after crash.
+ */
struct visor_controlvm_channel {
struct channel_header header;
- u64 gp_controlvm; /* guest phys addr of this channel */
- u64 gp_partition_tables;/* guest phys addr of partition tables */
- u64 gp_diag_guest; /* guest phys addr of diagnostic channel */
- u64 gp_boot_romdisk;/* guest phys addr of (read* only) Boot ROM disk */
- u64 gp_boot_ramdisk;/* guest phys addr of writable Boot RAM disk */
- u64 gp_acpi_table; /* guest phys addr of acpi table */
- u64 gp_control_channel;/* guest phys addr of control channel */
- u64 gp_diag_romdisk;/* guest phys addr of diagnostic ROM disk */
- u64 gp_nvram; /* guest phys addr of NVRAM channel */
- u64 request_payload_offset; /* Offset to request payload area */
- u64 event_payload_offset; /* Offset to event payload area */
- /* Bytes available in request payload area */
+ u64 gp_controlvm;
+ u64 gp_partition_tables;
+ u64 gp_diag_guest;
+ u64 gp_boot_romdisk;
+ u64 gp_boot_ramdisk;
+ u64 gp_acpi_table;
+ u64 gp_control_channel;
+ u64 gp_diag_romdisk;
+ u64 gp_nvram;
+ u64 request_payload_offset;
+ u64 event_payload_offset;
u32 request_payload_bytes;
- u32 event_payload_bytes;/* Bytes available in event payload area */
+ u32 event_payload_bytes;
u32 control_channel_bytes;
- u32 nvram_channel_bytes; /* Bytes in PartitionNvram segment */
- u32 message_bytes; /* sizeof(CONTROLVM_MESSAGE) */
- u32 message_count; /* CONTROLVM_MESSAGE_MAX */
- u64 gp_smbios_table; /* guest phys addr of SMBIOS tables */
- u64 gp_physical_smbios_table; /* guest phys addr of SMBIOS table */
- /* VISOR_MAX_GUESTS_PER_SERVICE */
+ u32 nvram_channel_bytes;
+ u32 message_bytes;
+ u32 message_count;
+ u64 gp_smbios_table;
+ u64 gp_physical_smbios_table;
char gp_reserved[2688];
-
- /* guest physical address of EFI firmware image base */
u64 virtual_guest_firmware_image_base;
-
- /* guest physical address of EFI firmware entry point */
u64 virtual_guest_firmware_entry_point;
-
- /* guest EFI firmware image size */
u64 virtual_guest_firmware_image_size;
-
- /* GPA = 1MB where EFI firmware image is copied to */
u64 virtual_guest_firmware_boot_base;
u64 virtual_guest_image_base;
u64 virtual_guest_image_size;
u64 prototype_control_channel_offset;
u64 virtual_guest_partition_handle;
- /* Restore Action field to restore the guest partition */
u16 restore_action;
- /* For Windows guests it shows if the visordisk is in dump mode */
u16 dump_action;
u16 nvram_fail_count;
- u16 saved_crash_message_count; /* = CONTROLVM_CRASHMSG_MAX */
- /* Offset to request payload area needed for crash dump */
+ u16 saved_crash_message_count;
u32 saved_crash_message_offset;
- /* Type of error encountered during installation */
u32 installation_error;
- u32 installation_text_id; /* Id of string to display */
- /* Number of remaining installation steps (for progress bars) */
+ u32 installation_text_id;
u16 installation_remaining_steps;
- /* VISOR_TOOL_ACTIONS Installation Action field */
u8 tool_action;
- u8 reserved; /* alignment */
+ u8 reserved;
struct efi_visor_indication efi_visor_ind;
u32 sp_reserved;
- /* Force signals to begin on 128-byte cache line */
u8 reserved2[28];
- /* guest partition uses this queue to send requests to Control */
struct signal_queue_header request_queue;
- /* Control uses this queue to respond to service or guest
- * partition requests
- */
struct signal_queue_header response_queue;
- /* Control uses this queue to send events to guest partition */
struct signal_queue_header event_queue;
- /* Service or guest partition uses this queue to ack Control events */
struct signal_queue_header event_ack_queue;
- /* Request fixed-size message pool - does not include payload */
- struct controlvm_message request_msg[CONTROLVM_MESSAGE_MAX];
-
- /* Response fixed-size message pool - does not include payload */
- struct controlvm_message response_msg[CONTROLVM_MESSAGE_MAX];
-
- /* Event fixed-size message pool - does not include payload */
- struct controlvm_message event_msg[CONTROLVM_MESSAGE_MAX];
-
- /* Ack fixed-size message pool - does not include payload */
- struct controlvm_message event_ack_msg[CONTROLVM_MESSAGE_MAX];
-
- /* Message stored during IOVM creation to be reused after crash */
- struct controlvm_message saved_crash_msg[CONTROLVM_CRASHMSG_MAX];
+ struct controlvm_message request_msg[CONTROLVM_MESSAGE_MAX];
+ struct controlvm_message response_msg[CONTROLVM_MESSAGE_MAX];
+ struct controlvm_message event_msg[CONTROLVM_MESSAGE_MAX];
+ struct controlvm_message event_ack_msg[CONTROLVM_MESSAGE_MAX];
+ struct controlvm_message saved_crash_msg[CONTROLVM_CRASHMSG_MAX];
} __packed;
-/* The following header will be located at the beginning of PayloadVmOffset for
+/*
+ * struct visor_controlvm_parameters_header
+ *
+ * The following header will be located at the beginning of PayloadVmOffset for
* various ControlVm commands. The receiver of a ControlVm command with a
* PayloadVmOffset will dereference this address and then use connection_offset,
* initiator_offset, and target_offset to get the location of UTF-8 formatted
@@ -455,9 +590,10 @@ struct visor_controlvm_parameters_header {
u32 client_length;
u32 name_offset;
u32 name_length;
- uuid_le id;
+ guid_t id;
u32 revision;
- u32 reserved; /* Natural alignment */
+ /* Natural alignment */
+ u32 reserved;
} __packed;
/* General Errors------------------------------------------------------[0-99] */
@@ -467,72 +603,57 @@ struct visor_controlvm_parameters_header {
#define CONTROLVM_RESP_KMALLOC_FAILED 3
#define CONTROLVM_RESP_ID_UNKNOWN 4
#define CONTROLVM_RESP_ID_INVALID_FOR_CLIENT 5
-
/* CONTROLVM_INIT_CHIPSET-------------------------------------------[100-199] */
#define CONTROLVM_RESP_CLIENT_SWITCHCOUNT_NONZERO 100
#define CONTROLVM_RESP_EXPECTED_CHIPSET_INIT 101
-
/* Maximum Limit----------------------------------------------------[200-299] */
-#define CONTROLVM_RESP_ERROR_MAX_BUSES 201 /* BUS_CREATE */
-#define CONTROLVM_RESP_ERROR_MAX_DEVICES 202 /* DEVICE_CREATE */
+/* BUS_CREATE */
+#define CONTROLVM_RESP_ERROR_MAX_BUSES 201
+/* DEVICE_CREATE */
+#define CONTROLVM_RESP_ERROR_MAX_DEVICES 202
/* Payload and Parameter Related------------------------------------[400-499] */
-#define CONTROLVM_RESP_PAYLOAD_INVALID 400 /* SWITCH_ATTACHEXTPORT,
- * DEVICE_CONFIGURE
- */
-#define CONTROLVM_RESP_INITIATOR_PARAMETER_INVALID 401 /* Multiple */
-#define CONTROLVM_RESP_TARGET_PARAMETER_INVALID 402 /* DEVICE_CONFIGURE */
-#define CONTROLVM_RESP_CLIENT_PARAMETER_INVALID 403 /* DEVICE_CONFIGURE */
-/* Specified[Packet Structure] Value-------------------------------[500-599] */
-#define CONTROLVM_RESP_BUS_INVALID 500 /* SWITCH_ATTACHINTPORT,
- * BUS_CONFIGURE,
- * DEVICE_CREATE,
- * DEVICE_CONFIG
- * DEVICE_DESTROY
- */
-#define CONTROLVM_RESP_DEVICE_INVALID 501 /* SWITCH_ATTACHINTPORT*/
- /* DEVICE_CREATE,
- * DEVICE_CONFIGURE,
- * DEVICE_DESTROY
- */
-#define CONTROLVM_RESP_CHANNEL_INVALID 502 /* DEVICE_CREATE,
- * DEVICE_CONFIGURE
- */
-/* Partition Driver Callback Interface----------------------[600-699] */
-#define CONTROLVM_RESP_VIRTPCI_DRIVER_FAILURE 604 /* BUS_CREATE,
- * BUS_DESTROY,
- * DEVICE_CREATE,
- * DEVICE_DESTROY
- */
-/* Unable to invoke VIRTPCI callback */
-#define CONTROLVM_RESP_VIRTPCI_DRIVER_CALLBACK_ERROR 605 /* BUS_CREATE,
- * BUS_DESTROY,
- * DEVICE_CREATE,
- * DEVICE_DESTROY
- */
-/* VIRTPCI Callback returned error */
+/* SWITCH_ATTACHEXTPORT, DEVICE_CONFIGURE */
+#define CONTROLVM_RESP_PAYLOAD_INVALID 400
+/* Multiple */
+#define CONTROLVM_RESP_INITIATOR_PARAMETER_INVALID 401
+/* DEVICE_CONFIGURE */
+#define CONTROLVM_RESP_TARGET_PARAMETER_INVALID 402
+/* DEVICE_CONFIGURE */
+#define CONTROLVM_RESP_CLIENT_PARAMETER_INVALID 403
+/* Specified[Packet Structure] Value--------------------------------[500-599] */
+/* SWITCH_ATTACHINTPORT */
+/* BUS_CONFIGURE, DEVICE_CREATE, DEVICE_CONFIG, DEVICE_DESTROY */
+#define CONTROLVM_RESP_BUS_INVALID 500
+/* SWITCH_ATTACHINTPORT*/
+/* DEVICE_CREATE, DEVICE_CONFIGURE, DEVICE_DESTROY */
+#define CONTROLVM_RESP_DEVICE_INVALID 501
+/* DEVICE_CREATE, DEVICE_CONFIGURE */
+#define CONTROLVM_RESP_CHANNEL_INVALID 502
+/* Partition Driver Callback Interface------------------------------[600-699] */
+/* BUS_CREATE, BUS_DESTROY, DEVICE_CREATE, DEVICE_DESTROY */
+#define CONTROLVM_RESP_VIRTPCI_DRIVER_FAILURE 604
+/* Unable to invoke VIRTPCI callback. VIRTPCI Callback returned error. */
+/* BUS_CREATE, BUS_DESTROY, DEVICE_CREATE, DEVICE_DESTROY */
+#define CONTROLVM_RESP_VIRTPCI_DRIVER_CALLBACK_ERROR 605
+/* Generic device callback returned error. */
+/* SWITCH_ATTACHEXTPORT, SWITCH_DETACHEXTPORT, DEVICE_CONFIGURE */
#define CONTROLVM_RESP_GENERIC_DRIVER_CALLBACK_ERROR 606
- /* SWITCH_ATTACHEXTPORT,
- * SWITCH_DETACHEXTPORT
- * DEVICE_CONFIGURE
- */
-
-/* generic device callback returned error */
/* Bus Related------------------------------------------------------[700-799] */
-#define CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED 700 /* BUS_DESTROY */
+/* BUS_DESTROY */
+#define CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED 700
/* Channel Related--------------------------------------------------[800-899] */
-#define CONTROLVM_RESP_CHANNEL_TYPE_UNKNOWN 800 /* GET_CHANNELINFO,
- * DEVICE_DESTROY
- */
-#define CONTROLVM_RESP_CHANNEL_SIZE_TOO_SMALL 801 /* DEVICE_CREATE */
+/* GET_CHANNELINFO, DEVICE_DESTROY */
+#define CONTROLVM_RESP_CHANNEL_TYPE_UNKNOWN 800
+/* DEVICE_CREATE */
+#define CONTROLVM_RESP_CHANNEL_SIZE_TOO_SMALL 801
/* Chipset Shutdown Related---------------------------------------[1000-1099] */
#define CONTROLVM_RESP_CHIPSET_SHUTDOWN_FAILED 1000
#define CONTROLVM_RESP_CHIPSET_SHUTDOWN_ALREADY_ACTIVE 1001
-
/* Chipset Stop Related-------------------------------------------[1100-1199] */
#define CONTROLVM_RESP_CHIPSET_STOP_FAILED_BUS 1100
#define CONTROLVM_RESP_CHIPSET_STOP_FAILED_SWITCH 1101
-
/* Device Related-------------------------------------------------[1400-1499] */
#define CONTROLVM_RESP_DEVICE_UDEV_TIMEOUT 1400
-#endif /* __CONTROLVMCHANNEL_H__ */
+/* __CONTROLVMCHANNEL_H__ */
+#endif
diff --git a/drivers/staging/unisys/visorbus/vbuschannel.h b/drivers/staging/unisys/visorbus/vbuschannel.h
index 01d7d51..27e04de 100644
--- a/drivers/staging/unisys/visorbus/vbuschannel.h
+++ b/drivers/staging/unisys/visorbus/vbuschannel.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 2010 - 2015 UNISYS CORPORATION
+/*
+ * Copyright (C) 2010 - 2015 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
@@ -15,26 +16,26 @@
#ifndef __VBUSCHANNEL_H__
#define __VBUSCHANNEL_H__
-/* The vbus channel is the channel area provided via the BUS_CREATE controlvm
- * message for each virtual bus. This channel area is provided to both server
- * and client ends of the bus. The channel header area is initialized by
- * the server, and the remaining information is filled in by the client.
- * We currently use this for the client to provide various information about
- * the client devices and client drivers for the server end to see.
+/*
+ * The vbus channel is the channel area provided via the BUS_CREATE controlvm
+ * message for each virtual bus. This channel area is provided to both server
+ * and client ends of the bus. The channel header area is initialized by
+ * the server, and the remaining information is filled in by the client.
+ * We currently use this for the client to provide various information about
+ * the client devices and client drivers for the server end to see.
*/
+
#include <linux/uuid.h>
#include <linux/ctype.h>
#include "channel.h"
/* {193b331b-c58f-11da-95a9-00e08161165f} */
-#define VISOR_VBUS_CHANNEL_UUID \
- UUID_LE(0x193b331b, 0xc58f, 0x11da, \
- 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f)
-static const uuid_le visor_vbus_channel_uuid = VISOR_VBUS_CHANNEL_UUID;
+#define VISOR_VBUS_CHANNEL_GUID \
+ GUID_INIT(0x193b331b, 0xc58f, 0x11da, \
+ 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f)
-#define VISOR_VBUS_CHANNEL_SIGNATURE VISOR_CHANNEL_SIGNATURE
-
-/* Must increment this whenever you insert or delete fields within this channel
+/*
+ * Must increment this whenever you insert or delete fields within this channel
* struct. Also increment whenever you change the meaning of fields within this
* channel struct so as to break pre-existing software. Note that you can
* usually add fields to the END of the channel struct withOUT needing to
@@ -43,42 +44,63 @@ static const uuid_le visor_vbus_channel_uuid = VISOR_VBUS_CHANNEL_UUID;
#define VISOR_VBUS_CHANNEL_VERSIONID 1
/*
+ * struct visor_vbus_deviceinfo
+ * @devtype: Short string identifying the device type.
+ * @drvname: Driver .sys file name.
+ * @infostrs: Kernel vversion.
+ * @reserved: Pad size to 256 bytes.
+ *
* An array of this struct is present in the channel area for each vbus.
- * (See vbuschannel.h.)
- * It is filled in by the client side to provide info about the device
- * and driver from the client's perspective.
+ * (See vbuschannel.h.). It is filled in by the client side to provide info
+ * about the device and driver from the client's perspective.
*/
struct visor_vbus_deviceinfo {
- u8 devtype[16]; /* short string identifying the device type */
- u8 drvname[16]; /* driver .sys file name */
- u8 infostrs[96]; /* kernel version */
- u8 reserved[128]; /* pad size to 256 bytes */
+ u8 devtype[16];
+ u8 drvname[16];
+ u8 infostrs[96];
+ u8 reserved[128];
} __packed;
+/*
+ * struct visor_vbus_headerinfo
+ * @struct_bytes: Size of this struct in bytes.
+ * @device_info_struct_bytes: Size of VISOR_VBUS_DEVICEINFO.
+ * @dev_info_count: Num of items in DevInfo member. This is the
+ * allocated size.
+ * @chp_info_offset: Byte offset from beginning of this struct to the
+ * ChpInfo struct.
+ * @bus_info_offset: Byte offset from beginning of this struct to the
+ * BusInfo struct.
+ * @dev_info_offset: Byte offset from beginning of this struct to the
+ * DevInfo array.
+ * @reserved: Natural Alignment
+ */
struct visor_vbus_headerinfo {
- u32 struct_bytes; /* size of this struct in bytes */
- u32 device_info_struct_bytes; /* sizeof(VISOR_VBUS_DEVICEINFO) */
- u32 dev_info_count; /* num of items in DevInfo member */
- /* (this is the allocated size) */
- u32 chp_info_offset; /* byte offset from beginning of this struct */
- /* to the ChpInfo struct (below) */
- u32 bus_info_offset; /* byte offset from beginning of this struct */
- /* to the BusInfo struct (below) */
- u32 dev_info_offset; /* byte offset from beginning of this struct */
- /* to the DevInfo array (below) */
+ u32 struct_bytes;
+ u32 device_info_struct_bytes;
+ u32 dev_info_count;
+ u32 chp_info_offset;
+ u32 bus_info_offset;
+ u32 dev_info_offset;
u8 reserved[104];
} __packed;
+/*
+ * struct visor_vbus_channel
+ * @channel_header: Initialized by server.
+ * @hdr_info: Initialized by server.
+ * @chp_info: Describes client chipset device and driver.
+ * @bus_info: Describes client bus device and driver.
+ * @dev_info: Describes client device and driver for each device on the
+ * bus.
+ */
struct visor_vbus_channel {
- struct channel_header channel_header; /* initialized by server */
- struct visor_vbus_headerinfo hdr_info; /* initialized by server */
- /* the remainder of this channel is filled in by the client */
+ struct channel_header channel_header;
+ struct visor_vbus_headerinfo hdr_info;
+ /* The remainder of this channel is filled in by the client */
struct visor_vbus_deviceinfo chp_info;
- /* describes client chipset device and driver */
struct visor_vbus_deviceinfo bus_info;
- /* describes client bus device and driver */
struct visor_vbus_deviceinfo dev_info[0];
- /* describes client device and driver for each device on the bus */
} __packed;
#endif
diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c
index 1c785dd..2bc7ff7 100644
--- a/drivers/staging/unisys/visorbus/visorbus_main.c
+++ b/drivers/staging/unisys/visorbus/visorbus_main.c
@@ -1,5 +1,4 @@
-/* visorbus_main.c
- *
+/*
* Copyright � 2010 - 2015 UNISYS CORPORATION
* All rights reserved.
*
@@ -20,15 +19,14 @@
#include "visorbus.h"
#include "visorbus_private.h"
-#define MYDRVNAME "visorbus"
+static const guid_t visor_vbus_channel_guid = VISOR_VBUS_CHANNEL_GUID;
-/* Display string that is guaranteed to be no longer the 99 characters*/
+/* Display string that is guaranteed to be no longer the 99 characters */
#define LINESIZE 99
-
-#define CURRENT_FILE_PC VISOR_BUS_PC_visorbus_main_c
#define POLLJIFFIES_NORMALCHANNEL 10
-static bool initialized; /* stores whether bus_registration was successful */
+/* stores whether bus_registration was successful */
+static bool initialized;
static struct dentry *visorbus_debugfs_dir;
/*
@@ -40,11 +38,11 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct visor_device *vdev;
- uuid_le guid;
+ const guid_t *guid;
vdev = to_visor_device(dev);
- guid = visorchannel_get_uuid(vdev->visorchannel);
- return sprintf(buf, "visorbus:%pUl\n", &guid);
+ guid = visorchannel_get_guid(vdev->visorchannel);
+ return sprintf(buf, "visorbus:%pUl\n", guid);
}
static DEVICE_ATTR_RO(modalias);
@@ -53,15 +51,7 @@ static struct attribute *visorbus_dev_attrs[] = {
NULL,
};
-/* sysfs example for bridge-only sysfs files using device_type's */
-static const struct attribute_group visorbus_dev_group = {
- .attrs = visorbus_dev_attrs,
-};
-
-static const struct attribute_group *visorbus_dev_groups[] = {
- &visorbus_dev_group,
- NULL,
-};
+ATTRIBUTE_GROUPS(visorbus_dev);
/* filled in with info about parent chipset driver when we register with it */
static struct visor_vbus_deviceinfo chipset_driverinfo;
@@ -73,16 +63,70 @@ static LIST_HEAD(list_all_bus_instances);
/* list of visor_device structs, linked via .list_all */
static LIST_HEAD(list_all_device_instances);
-static int
-visorbus_uevent(struct device *xdev, struct kobj_uevent_env *env)
+/*
+ * Generic function useful for validating any type of channel when it is
+ * received by the client that will be accessing the channel.
+ * Note that <logCtx> is only needed for callers in the EFI environment, and
+ * is used to pass the EFI_DIAG_CAPTURE_PROTOCOL needed to log messages.
+ */
+int visor_check_channel(struct channel_header *ch,
+ struct device *dev,
+ const guid_t *expected_guid,
+ char *chname,
+ u64 expected_min_bytes,
+ u32 expected_version,
+ u64 expected_signature)
+{
+ if (!guid_is_null(expected_guid)) {
+ /* caller wants us to verify type GUID */
+ if (!guid_equal(&ch->chtype, expected_guid)) {
+ dev_err(dev, "Channel mismatch on channel=%s(%pUL) field=type expected=%pUL actual=%pUL\n",
+ chname, expected_guid, expected_guid,
+ &ch->chtype);
+ return 0;
+ }
+ }
+ /* verify channel size */
+ if (expected_min_bytes > 0) {
+ if (ch->size < expected_min_bytes) {
+ dev_err(dev, "Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8Lx actual=0x%-8.8Lx\n",
+ chname, expected_guid,
+ (unsigned long long)expected_min_bytes,
+ ch->size);
+ return 0;
+ }
+ }
+ /* verify channel version */
+ if (expected_version > 0) {
+ if (ch->version_id != expected_version) {
+ dev_err(dev, "Channel mismatch on channel=%s(%pUL) field=version expected=0x%-8.8lx actual=0x%-8.8x\n",
+ chname, expected_guid,
+ (unsigned long)expected_version,
+ ch->version_id);
+ return 0;
+ }
+ }
+ /* verify channel signature */
+ if (expected_signature > 0) {
+ if (ch->signature != expected_signature) {
+ dev_err(dev, "Channel mismatch on channel=%s(%pUL) field=signature expected=0x%-8.8Lx actual=0x%-8.8Lx\n",
+ chname, expected_guid, expected_signature,
+ ch->signature);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int visorbus_uevent(struct device *xdev, struct kobj_uevent_env *env)
{
struct visor_device *dev;
- uuid_le guid;
+ const guid_t *guid;
dev = to_visor_device(xdev);
- guid = visorchannel_get_uuid(dev->visorchannel);
+ guid = visorchannel_get_guid(dev->visorchannel);
- return add_uevent_var(env, "MODALIAS=visorbus:%pUl", &guid);
+ return add_uevent_var(env, "MODALIAS=visorbus:%pUl", guid);
}
/*
@@ -94,27 +138,21 @@ visorbus_uevent(struct device *xdev, struct kobj_uevent_env *env)
*
* Return: 1 iff the provided driver can control the specified device
*/
-static int
-visorbus_match(struct device *xdev, struct device_driver *xdrv)
+static int visorbus_match(struct device *xdev, struct device_driver *xdrv)
{
- uuid_le channel_type;
+ const guid_t *channel_type;
int i;
struct visor_device *dev;
struct visor_driver *drv;
dev = to_visor_device(xdev);
+ channel_type = visorchannel_get_guid(dev->visorchannel);
drv = to_visor_driver(xdrv);
- channel_type = visorchannel_get_uuid(dev->visorchannel);
-
if (!drv->channel_types)
return 0;
- for (i = 0;
- (uuid_le_cmp(drv->channel_types[i].guid, NULL_UUID_LE) != 0) ||
- (drv->channel_types[i].name);
- i++)
- if (uuid_le_cmp(drv->channel_types[i].guid,
- channel_type) == 0)
+ for (i = 0; !guid_is_null(&drv->channel_types[i].guid); i++)
+ if (guid_equal(&drv->channel_types[i].guid, channel_type))
return i + 1;
return 0;
@@ -122,7 +160,7 @@ visorbus_match(struct device *xdev, struct device_driver *xdrv)
/*
* This describes the TYPE of bus.
- * (Don't confuse this with an INSTANCE of the bus.)
+ * (Don't confuse this with an INSTANCE of the bus.)
*/
struct bus_type visorbus_type = {
.name = "visorbus",
@@ -137,8 +175,7 @@ struct bus_type visorbus_type = {
* involved with destroying the dev are complete
* @xdev: struct device for the bus being released
*/
-static void
-visorbus_release_busdevice(struct device *xdev)
+static void visorbus_release_busdevice(struct device *xdev)
{
struct visor_device *dev = dev_get_drvdata(xdev);
@@ -152,15 +189,11 @@ visorbus_release_busdevice(struct device *xdev)
* each child device instance
* @xdev: struct device for the visor device being released
*/
-static void
-visorbus_release_device(struct device *xdev)
+static void visorbus_release_device(struct device *xdev)
{
struct visor_device *dev = to_visor_device(xdev);
- if (dev->visorchannel) {
- visorchannel_destroy(dev->visorchannel);
- dev->visorchannel = NULL;
- }
+ visorchannel_destroy(dev->visorchannel);
kfree(dev);
}
@@ -229,7 +262,7 @@ static ssize_t typename_show(struct device *dev, struct device_attribute *attr,
struct device_driver *xdrv = dev->driver;
struct visor_driver *drv = NULL;
- if (!xbus || !xdrv)
+ if (!xdrv)
return 0;
i = xbus->match(dev, xdrv);
if (!i)
@@ -240,24 +273,16 @@ static ssize_t typename_show(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR_RO(typename);
static struct attribute *channel_attrs[] = {
- &dev_attr_physaddr.attr,
- &dev_attr_nbytes.attr,
- &dev_attr_clientpartition.attr,
- &dev_attr_typeguid.attr,
- &dev_attr_zoneguid.attr,
- &dev_attr_typename.attr,
- NULL
+ &dev_attr_physaddr.attr,
+ &dev_attr_nbytes.attr,
+ &dev_attr_clientpartition.attr,
+ &dev_attr_typeguid.attr,
+ &dev_attr_zoneguid.attr,
+ &dev_attr_typename.attr,
+ NULL
};
-static struct attribute_group channel_attr_grp = {
- .name = "channel",
- .attrs = channel_attrs,
-};
-
-static const struct attribute_group *visorbus_channel_groups[] = {
- &channel_attr_grp,
- NULL
-};
+ATTRIBUTE_GROUPS(channel);
/* end implementation of specific channel attributes */
@@ -270,7 +295,8 @@ static const struct attribute_group *visorbus_channel_groups[] = {
static ssize_t partition_handle_show(struct device *dev,
struct device_attribute *attr,
- char *buf) {
+ char *buf)
+{
struct visor_device *vdev = to_visor_device(dev);
u64 handle = visorchannel_get_clientpartition(vdev->visorchannel);
@@ -280,16 +306,18 @@ static DEVICE_ATTR_RO(partition_handle);
static ssize_t partition_guid_show(struct device *dev,
struct device_attribute *attr,
- char *buf) {
+ char *buf)
+{
struct visor_device *vdev = to_visor_device(dev);
- return sprintf(buf, "{%pUb}\n", &vdev->partition_uuid);
+ return sprintf(buf, "{%pUb}\n", &vdev->partition_guid);
}
static DEVICE_ATTR_RO(partition_guid);
static ssize_t partition_name_show(struct device *dev,
struct device_attribute *attr,
- char *buf) {
+ char *buf)
+{
struct visor_device *vdev = to_visor_device(dev);
return sprintf(buf, "%s\n", vdev->name);
@@ -298,7 +326,8 @@ static DEVICE_ATTR_RO(partition_name);
static ssize_t channel_addr_show(struct device *dev,
struct device_attribute *attr,
- char *buf) {
+ char *buf)
+{
struct visor_device *vdev = to_visor_device(dev);
u64 addr = visorchannel_get_physaddr(vdev->visorchannel);
@@ -308,7 +337,8 @@ static DEVICE_ATTR_RO(channel_addr);
static ssize_t channel_bytes_show(struct device *dev,
struct device_attribute *attr,
- char *buf) {
+ char *buf)
+{
struct visor_device *vdev = to_visor_device(dev);
u64 nbytes = visorchannel_get_nbytes(vdev->visorchannel);
@@ -318,7 +348,8 @@ static DEVICE_ATTR_RO(channel_bytes);
static ssize_t channel_id_show(struct device *dev,
struct device_attribute *attr,
- char *buf) {
+ char *buf)
+{
struct visor_device *vdev = to_visor_device(dev);
int len = 0;
@@ -330,24 +361,17 @@ static ssize_t channel_id_show(struct device *dev,
}
static DEVICE_ATTR_RO(channel_id);
-static struct attribute *dev_attrs[] = {
- &dev_attr_partition_handle.attr,
- &dev_attr_partition_guid.attr,
- &dev_attr_partition_name.attr,
- &dev_attr_channel_addr.attr,
- &dev_attr_channel_bytes.attr,
- &dev_attr_channel_id.attr,
- NULL
-};
-
-static struct attribute_group dev_attr_grp = {
- .attrs = dev_attrs,
+static struct attribute *visorbus_attrs[] = {
+ &dev_attr_partition_handle.attr,
+ &dev_attr_partition_guid.attr,
+ &dev_attr_partition_name.attr,
+ &dev_attr_channel_addr.attr,
+ &dev_attr_channel_bytes.attr,
+ &dev_attr_channel_id.attr,
+ NULL
};
-static const struct attribute_group *visorbus_groups[] = {
- &dev_attr_grp,
- NULL
-};
+ATTRIBUTE_GROUPS(visorbus);
/*
* BUS debugfs entries
@@ -355,6 +379,7 @@ static const struct attribute_group *visorbus_groups[] = {
* define & implement display of debugfs attributes under
* /sys/kernel/debug/visorbus/visorbus<n>.
*/
+
/*
* vbuschannel_print_devinfo() - format a struct visor_vbus_deviceinfo
* and write it to a seq_file
@@ -365,12 +390,12 @@ static const struct attribute_group *visorbus_groups[] = {
*
* Reads @devInfo, and writes it in human-readable notation to @seq.
*/
-static void
-vbuschannel_print_devinfo(struct visor_vbus_deviceinfo *devinfo,
- struct seq_file *seq, int devix)
+static void vbuschannel_print_devinfo(struct visor_vbus_deviceinfo *devinfo,
+ struct seq_file *seq, int devix)
{
+ /* uninitialized vbus device entry */
if (!isprint(devinfo->devtype[0]))
- return; /* uninitialized vbus device entry */
+ return;
if (devix >= 0)
seq_printf(seq, "[%d]", devix);
@@ -392,12 +417,11 @@ vbuschannel_print_devinfo(struct visor_vbus_deviceinfo *devinfo,
static int client_bus_info_debugfs_show(struct seq_file *seq, void *v)
{
- struct visor_device *vdev = seq->private;
- struct visorchannel *channel = vdev->visorchannel;
-
- int i;
+ int i = 0;
unsigned long off;
struct visor_vbus_deviceinfo dev_info;
+ struct visor_device *vdev = seq->private;
+ struct visorchannel *channel = vdev->visorchannel;
if (!channel)
return 0;
@@ -406,6 +430,7 @@ static int client_bus_info_debugfs_show(struct seq_file *seq, void *v)
"Client device / client driver info for %s partition (vbus #%u):\n",
((vdev->name) ? (char *)(vdev->name) : ""),
vdev->chipset_bus_no);
+
if (visorchannel_read(channel,
offsetof(struct visor_vbus_channel, chp_info),
&dev_info, sizeof(dev_info)) >= 0)
@@ -414,8 +439,8 @@ static int client_bus_info_debugfs_show(struct seq_file *seq, void *v)
offsetof(struct visor_vbus_channel, bus_info),
&dev_info, sizeof(dev_info)) >= 0)
vbuschannel_print_devinfo(&dev_info, seq, -1);
+
off = offsetof(struct visor_vbus_channel, dev_info);
- i = 0;
while (off + sizeof(dev_info) <= visorchannel_get_nbytes(channel)) {
if (visorchannel_read(channel, off, &dev_info,
sizeof(dev_info)) >= 0)
@@ -441,8 +466,7 @@ static const struct file_operations client_bus_info_debugfs_fops = {
.release = single_release,
};
-static void
-dev_periodic_work(unsigned long __opaque)
+static void dev_periodic_work(unsigned long __opaque)
{
struct visor_device *dev = (struct visor_device *)__opaque;
struct visor_driver *drv = to_visor_driver(dev->device.driver);
@@ -451,8 +475,7 @@ dev_periodic_work(unsigned long __opaque)
mod_timer(&dev->timer, jiffies + POLLJIFFIES_NORMALCHANNEL);
}
-static int
-dev_start_periodic_work(struct visor_device *dev)
+static int dev_start_periodic_work(struct visor_device *dev)
{
if (dev->being_removed || dev->timer_active)
return -EINVAL;
@@ -464,8 +487,7 @@ dev_start_periodic_work(struct visor_device *dev)
return 0;
}
-static void
-dev_stop_periodic_work(struct visor_device *dev)
+static void dev_stop_periodic_work(struct visor_device *dev)
{
if (!dev->timer_active)
return;
@@ -484,40 +506,39 @@ dev_stop_periodic_work(struct visor_device *dev)
*
* Return: 0 iff successful
*/
-static int
-visordriver_remove_device(struct device *xdev)
+static int visordriver_remove_device(struct device *xdev)
{
struct visor_device *dev;
struct visor_driver *drv;
dev = to_visor_device(xdev);
drv = to_visor_driver(xdev->driver);
+
mutex_lock(&dev->visordriver_callback_lock);
dev->being_removed = true;
- if (drv->remove)
- drv->remove(dev);
+ drv->remove(dev);
mutex_unlock(&dev->visordriver_callback_lock);
- dev_stop_periodic_work(dev);
+ dev_stop_periodic_work(dev);
put_device(&dev->device);
+
return 0;
}
-/**
+/*
* visorbus_unregister_visor_driver() - unregisters the provided driver
* @drv: the driver to unregister
*
* A visor function driver calls this function to unregister the driver,
* i.e., within its module_exit function.
*/
-void
-visorbus_unregister_visor_driver(struct visor_driver *drv)
+void visorbus_unregister_visor_driver(struct visor_driver *drv)
{
driver_unregister(&drv->driver);
}
EXPORT_SYMBOL_GPL(visorbus_unregister_visor_driver);
-/**
+/*
* visorbus_read_channel() - reads from the designated channel into
* the provided buffer
* @dev: the device whose channel is read from
@@ -530,15 +551,14 @@ EXPORT_SYMBOL_GPL(visorbus_unregister_visor_driver);
*
* Return: integer indicating success (zero) or failure (non-zero)
*/
-int
-visorbus_read_channel(struct visor_device *dev, unsigned long offset,
- void *dest, unsigned long nbytes)
+int visorbus_read_channel(struct visor_device *dev, unsigned long offset,
+ void *dest, unsigned long nbytes)
{
return visorchannel_read(dev->visorchannel, offset, dest, nbytes);
}
EXPORT_SYMBOL_GPL(visorbus_read_channel);
-/**
+/*
* visorbus_write_channel() - writes the provided buffer into the designated
* channel
* @dev: the device whose channel is written to
@@ -551,15 +571,14 @@ EXPORT_SYMBOL_GPL(visorbus_read_channel);
*
* Return: integer indicating success (zero) or failure (non-zero)
*/
-int
-visorbus_write_channel(struct visor_device *dev, unsigned long offset,
- void *src, unsigned long nbytes)
+int visorbus_write_channel(struct visor_device *dev, unsigned long offset,
+ void *src, unsigned long nbytes)
{
return visorchannel_write(dev->visorchannel, offset, src, nbytes);
}
EXPORT_SYMBOL_GPL(visorbus_write_channel);
-/**
+/*
* visorbus_enable_channel_interrupts() - enables interrupts on the
* designated device
* @dev: the device on which to enable interrupts
@@ -567,8 +586,7 @@ EXPORT_SYMBOL_GPL(visorbus_write_channel);
* Currently we don't yet have a real interrupt, so for now we just call the
* interrupt function periodically via a timer.
*/
-int
-visorbus_enable_channel_interrupts(struct visor_device *dev)
+int visorbus_enable_channel_interrupts(struct visor_device *dev)
{
struct visor_driver *drv = to_visor_driver(dev->device.driver);
@@ -581,13 +599,12 @@ visorbus_enable_channel_interrupts(struct visor_device *dev)
}
EXPORT_SYMBOL_GPL(visorbus_enable_channel_interrupts);
-/**
+/*
* visorbus_disable_channel_interrupts() - disables interrupts on the
* designated device
* @dev: the device on which to disable interrupts
*/
-void
-visorbus_disable_channel_interrupts(struct visor_device *dev)
+void visorbus_disable_channel_interrupts(struct visor_device *dev)
{
dev_stop_periodic_work(dev);
}
@@ -616,8 +633,7 @@ EXPORT_SYMBOL_GPL(visorbus_disable_channel_interrupts);
* Return: 0 if successful, otherwise the negative value returned by
* device_add() indicating the reason for failure
*/
-static int
-create_visor_device(struct visor_device *dev)
+int create_visor_device(struct visor_device *dev)
{
int err;
u32 chipset_bus_no = dev->chipset_bus_no;
@@ -625,7 +641,7 @@ create_visor_device(struct visor_device *dev)
mutex_init(&dev->visordriver_callback_lock);
dev->device.bus = &visorbus_type;
- dev->device.groups = visorbus_channel_groups;
+ dev->device.groups = channel_groups;
device_initialize(&dev->device);
dev->device.release = visorbus_release_device;
/* keep a reference just for us (now 2) */
@@ -664,7 +680,10 @@ create_visor_device(struct visor_device *dev)
goto err_put;
list_add_tail(&dev->list_all, &list_all_device_instances);
- return 0; /* success: reference kept via unmatched get_device() */
+ dev->state.created = 1;
+ visorbus_response(dev, err, CONTROLVM_DEVICE_CREATE);
+ /* success: reference kept via unmatched get_device() */
+ return 0;
err_put:
put_device(&dev->device);
@@ -672,26 +691,27 @@ err_put:
return err;
}
-static void
-remove_visor_device(struct visor_device *dev)
+void remove_visor_device(struct visor_device *dev)
{
list_del(&dev->list_all);
put_device(&dev->device);
device_unregister(&dev->device);
+ visorbus_response(dev, 0, CONTROLVM_DEVICE_DESTROY);
}
-static int
-get_vbus_header_info(struct visorchannel *chan,
- struct visor_vbus_headerinfo *hdr_info)
+static int get_vbus_header_info(struct visorchannel *chan,
+ struct device *dev,
+ struct visor_vbus_headerinfo *hdr_info)
{
int err;
if (!visor_check_channel(visorchannel_get_header(chan),
- visor_vbus_channel_uuid,
+ dev,
+ &visor_vbus_channel_guid,
"vbus",
sizeof(struct visor_vbus_channel),
VISOR_VBUS_CHANNEL_VERSIONID,
- VISOR_VBUS_CHANNEL_SIGNATURE))
+ VISOR_CHANNEL_SIGNATURE))
return -EINVAL;
err = visorchannel_read(chan, sizeof(struct channel_header), hdr_info,
@@ -722,10 +742,9 @@ get_vbus_header_info(struct visorchannel *chan,
* Returns no value since this is debug information and not needed for
* device functionality.
*/
-static void
-write_vbus_chp_info(struct visorchannel *chan,
- struct visor_vbus_headerinfo *hdr_info,
- struct visor_vbus_deviceinfo *info)
+static void write_vbus_chp_info(struct visorchannel *chan,
+ struct visor_vbus_headerinfo *hdr_info,
+ struct visor_vbus_deviceinfo *info)
{
int off = sizeof(struct channel_header) + hdr_info->chp_info_offset;
@@ -748,10 +767,9 @@ write_vbus_chp_info(struct visorchannel *chan,
* Returns no value since this is debug information and not needed for
* device functionality.
*/
-static void
-write_vbus_bus_info(struct visorchannel *chan,
- struct visor_vbus_headerinfo *hdr_info,
- struct visor_vbus_deviceinfo *info)
+static void write_vbus_bus_info(struct visorchannel *chan,
+ struct visor_vbus_headerinfo *hdr_info,
+ struct visor_vbus_deviceinfo *info)
{
int off = sizeof(struct channel_header) + hdr_info->bus_info_offset;
@@ -775,10 +793,10 @@ write_vbus_bus_info(struct visorchannel *chan,
* Returns no value since this is debug information and not needed for
* device functionality.
*/
-static void
-write_vbus_dev_info(struct visorchannel *chan,
- struct visor_vbus_headerinfo *hdr_info,
- struct visor_vbus_deviceinfo *info, unsigned int devix)
+static void write_vbus_dev_info(struct visorchannel *chan,
+ struct visor_vbus_headerinfo *hdr_info,
+ struct visor_vbus_deviceinfo *info,
+ unsigned int devix)
{
int off =
(sizeof(struct channel_header) + hdr_info->dev_info_offset) +
@@ -807,14 +825,13 @@ static void bus_device_info_init(
}
/*
- * fix_vbus_dev_info() - for a child device just created on a client bus, fill
- * in information about the driver that is controlling
- * this device into the appropriate slot within the
- * vbus channel of the bus instance
+ * publish_vbus_dev_info() - for a child device just created on a client bus,
+ * fill in information about the driver that is
+ * controlling this device into the appropriate slot
+ * within the vbus channel of the bus instance
* @visordev: struct visor_device for the desired device
*/
-static void
-fix_vbus_dev_info(struct visor_device *visordev)
+static void publish_vbus_dev_info(struct visor_device *visordev)
{
int i;
struct visor_device *bdev;
@@ -853,7 +870,6 @@ fix_vbus_dev_info(struct visor_device *visordev)
bus_device_info_init(&dev_info, chan_type_name, visordrv->name);
write_vbus_dev_info(bdev->visorchannel, hdr_info, &dev_info, dev_no);
-
write_vbus_chp_info(bdev->visorchannel, hdr_info, &chipset_driverinfo);
write_vbus_bus_info(bdev->visorchannel, hdr_info,
&clientbus_driverinfo);
@@ -874,18 +890,14 @@ fix_vbus_dev_info(struct visor_device *visordev)
* was successful with this device, otherwise a negative errno
* value indicating failure reason
*/
-static int
-visordriver_probe_device(struct device *xdev)
+static int visordriver_probe_device(struct device *xdev)
{
int res;
struct visor_driver *drv;
struct visor_device *dev;
- drv = to_visor_driver(xdev->driver);
dev = to_visor_device(xdev);
-
- if (!drv->probe)
- return -ENODEV;
+ drv = to_visor_driver(xdev->driver);
mutex_lock(&dev->visordriver_callback_lock);
dev->being_removed = false;
@@ -894,14 +906,14 @@ visordriver_probe_device(struct device *xdev)
if (res >= 0) {
/* success: reference kept via unmatched get_device() */
get_device(&dev->device);
- fix_vbus_dev_info(dev);
+ publish_vbus_dev_info(dev);
}
mutex_unlock(&dev->visordriver_callback_lock);
return res;
}
-/**
+/*
* visorbus_register_visor_driver() - registers the provided visor driver
* for handling one or more visor device
* types (channel_types)
@@ -952,8 +964,21 @@ visordriver_probe_device(struct device *xdev)
*/
int visorbus_register_visor_driver(struct visor_driver *drv)
{
+ /* can't register on a nonexistent bus */
if (!initialized)
- return -ENODEV; /* can't register on a nonexistent bus */
+ return -ENODEV;
+
+ if (!drv->probe)
+ return -EINVAL;
+
+ if (!drv->remove)
+ return -EINVAL;
+
+ if (!drv->pause)
+ return -EINVAL;
+
+ if (!drv->resume)
+ return -EINVAL;
drv->driver.name = drv->name;
drv->driver.bus = &visorbus_type;
@@ -985,8 +1010,7 @@ EXPORT_SYMBOL_GPL(visorbus_register_visor_driver);
* Return: 0 for success, otherwise negative errno value indicating reason for
* failure
*/
-static int
-visorbus_create_instance(struct visor_device *dev)
+int visorbus_create_instance(struct visor_device *dev)
{
int id = dev->chipset_bus_no;
int err;
@@ -1009,7 +1033,7 @@ visorbus_create_instance(struct visor_device *dev)
&client_bus_info_debugfs_fops);
dev_set_drvdata(&dev->device, dev);
- err = get_vbus_header_info(dev->visorchannel, hdr_info);
+ err = get_vbus_header_info(dev->visorchannel, &dev->device, hdr_info);
if (err < 0)
goto err_debugfs_dir;
@@ -1019,18 +1043,21 @@ visorbus_create_instance(struct visor_device *dev)
list_add_tail(&dev->list_all, &list_all_bus_instances);
+ dev->state.created = 1;
dev->vbus_hdr_info = (void *)hdr_info;
write_vbus_chp_info(dev->visorchannel, hdr_info,
&chipset_driverinfo);
write_vbus_bus_info(dev->visorchannel, hdr_info,
&clientbus_driverinfo);
+ visorbus_response(dev, err, CONTROLVM_BUS_CREATE);
+
return 0;
err_debugfs_dir:
debugfs_remove_recursive(dev->debugfs_dir);
kfree(hdr_info);
- dev_err(&dev->device, "visorbus_create_instance failed: %d\n", err);
+ dev_err(&dev->device, "%s failed: %d\n", __func__, err);
return err;
}
@@ -1038,8 +1065,7 @@ err_debugfs_dir:
* visorbus_remove_instance() - remove a device instance for the visorbus itself
* @dev: struct visor_device indentifying the bus to remove
*/
-static void
-visorbus_remove_instance(struct visor_device *dev)
+void visorbus_remove_instance(struct visor_device *dev)
{
/*
* Note that this will result in the release method for
@@ -1049,20 +1075,17 @@ visorbus_remove_instance(struct visor_device *dev)
* successfully been able to trace thru the code to see where/how
* release() gets called. But I know it does.
*/
- if (dev->visorchannel) {
- visorchannel_destroy(dev->visorchannel);
- dev->visorchannel = NULL;
- }
+ visorchannel_destroy(dev->visorchannel);
kfree(dev->vbus_hdr_info);
list_del(&dev->list_all);
device_unregister(&dev->device);
+ visorbus_response(dev, 0, CONTROLVM_BUS_DESTROY);
}
/*
* remove_all_visor_devices() - remove all child visorbus device instances
*/
-static void
-remove_all_visor_devices(void)
+static void remove_all_visor_devices(void)
{
struct list_head *listentry, *listtmp;
@@ -1074,50 +1097,6 @@ remove_all_visor_devices(void)
}
}
-int
-visorchipset_bus_create(struct visor_device *dev)
-{
- int err;
-
- err = visorbus_create_instance(dev);
-
- if (err < 0)
- return err;
-
- visorbus_create_response(dev, err);
-
- return 0;
-}
-
-void
-visorchipset_bus_destroy(struct visor_device *dev)
-{
- visorbus_remove_instance(dev);
- visorbus_destroy_response(dev, 0);
-}
-
-int
-visorchipset_device_create(struct visor_device *dev_info)
-{
- int err;
-
- err = create_visor_device(dev_info);
- if (err < 0)
- return err;
-
- visorbus_device_create_response(dev_info, err);
-
- return 0;
-}
-
-void
-visorchipset_device_destroy(struct visor_device *dev_info)
-{
- remove_visor_device(dev_info);
-
- visorbus_device_destroy_response(dev_info, 0);
-}
-
/*
* pause_state_change_complete() - the callback function to be called by a
* visorbus function driver when a
@@ -1127,15 +1106,14 @@ visorchipset_device_destroy(struct visor_device *dev_info)
* @status: 0 iff the pause state change completed successfully, otherwise
* a negative errno value indicating the reason for failure
*/
-static void
-pause_state_change_complete(struct visor_device *dev, int status)
+static void pause_state_change_complete(struct visor_device *dev, int status)
{
if (!dev->pausing)
return;
dev->pausing = false;
-
- visorbus_device_pause_response(dev, status);
+ visorbus_device_changestate_response(dev, status,
+ segment_state_standby);
}
/*
@@ -1147,8 +1125,7 @@ pause_state_change_complete(struct visor_device *dev, int status)
* @status: 0 iff the resume state change completed successfully, otherwise
* a negative errno value indicating the reason for failure
*/
-static void
-resume_state_change_complete(struct visor_device *dev, int status)
+static void resume_state_change_complete(struct visor_device *dev, int status)
{
if (!dev->resuming)
return;
@@ -1160,7 +1137,8 @@ resume_state_change_complete(struct visor_device *dev, int status)
* which will presumably want to send some sort of response to
* the initiator.
*/
- visorbus_device_resume_response(dev, status);
+ visorbus_device_changestate_response(dev, status,
+ segment_state_running);
}
/*
@@ -1174,34 +1152,28 @@ resume_state_change_complete(struct visor_device *dev, int status)
* via a callback function; see pause_state_change_complete() and
* resume_state_change_complete().
*/
-static int
-visorchipset_initiate_device_pause_resume(struct visor_device *dev,
- bool is_pause)
+static int visorchipset_initiate_device_pause_resume(struct visor_device *dev,
+ bool is_pause)
{
int err;
struct visor_driver *drv = NULL;
- drv = to_visor_driver(dev->device.driver);
- if (!drv)
- return -ENODEV;
-
+ /* If no driver associated with the device nothing to pause/resume */
+ if (!dev->device.driver)
+ return 0;
if (dev->pausing || dev->resuming)
return -EBUSY;
+ drv = to_visor_driver(dev->device.driver);
if (is_pause) {
- if (!drv->pause)
- return -EINVAL;
-
dev->pausing = true;
err = drv->pause(dev, pause_state_change_complete);
} else {
- /* The vbus_dev_info structure in the channel was been
- * cleared, make sure it is valid.
+ /*
+ * The vbus_dev_info structure in the channel was been cleared,
+ * make sure it is valid.
*/
- fix_vbus_dev_info(dev);
- if (!drv->resume)
- return -EINVAL;
-
+ publish_vbus_dev_info(dev);
dev->resuming = true;
err = drv->resume(dev, resume_state_change_complete);
}
@@ -1209,7 +1181,7 @@ visorchipset_initiate_device_pause_resume(struct visor_device *dev,
return err;
}
-/**
+/*
* visorchipset_device_pause() - start a pause operation for a visor device
* @dev_info: struct visor_device identifying the device being paused
*
@@ -1217,13 +1189,11 @@ visorchipset_initiate_device_pause_resume(struct visor_device *dev,
* that device. Success/failure result is returned asynchronously
* via a callback function; see pause_state_change_complete().
*/
-int
-visorchipset_device_pause(struct visor_device *dev_info)
+int visorchipset_device_pause(struct visor_device *dev_info)
{
int err;
err = visorchipset_initiate_device_pause_resume(dev_info, true);
-
if (err < 0) {
dev_info->pausing = false;
return err;
@@ -1232,7 +1202,7 @@ visorchipset_device_pause(struct visor_device *dev_info)
return 0;
}
-/**
+/*
* visorchipset_device_resume() - start a resume operation for a visor device
* @dev_info: struct visor_device identifying the device being resumed
*
@@ -1240,13 +1210,11 @@ visorchipset_device_pause(struct visor_device *dev_info)
* that device. Success/failure result is returned asynchronously
* via a callback function; see resume_state_change_complete().
*/
-int
-visorchipset_device_resume(struct visor_device *dev_info)
+int visorchipset_device_resume(struct visor_device *dev_info)
{
int err;
err = visorchipset_initiate_device_pause_resume(dev_info, false);
-
if (err < 0) {
dev_info->resuming = false;
return err;
@@ -1255,8 +1223,7 @@ visorchipset_device_resume(struct visor_device *dev_info)
return 0;
}
-int
-visorbus_init(void)
+int visorbus_init(void)
{
int err;
@@ -1271,14 +1238,12 @@ visorbus_init(void)
return err;
initialized = true;
-
bus_device_info_init(&chipset_driverinfo, "chipset", "visorchipset");
return 0;
}
-void
-visorbus_exit(void)
+void visorbus_exit(void)
{
struct list_head *listentry, *listtmp;
diff --git a/drivers/staging/unisys/visorbus/visorbus_private.h b/drivers/staging/unisys/visorbus/visorbus_private.h
index 98a5af1..e878d65 100644
--- a/drivers/staging/unisys/visorbus/visorbus_private.h
+++ b/drivers/staging/unisys/visorbus/visorbus_private.h
@@ -1,5 +1,4 @@
-/* visorbus_private.h
- *
+/*
* Copyright (C) 2010 - 2015 UNISYS CORPORATION
* All rights reserved.
*
@@ -22,36 +21,27 @@
#include "controlvmchannel.h"
#include "vbuschannel.h"
+#include "visorbus.h"
-/* TARGET_HOSTNAME specified as -DTARGET_HOSTNAME=\"thename\" on the
- * command line
- */
-
-int visorchipset_bus_create(struct visor_device *bus_info);
-void visorchipset_bus_destroy(struct visor_device *bus_info);
-int visorchipset_device_create(struct visor_device *dev_info);
-void visorchipset_device_destroy(struct visor_device *dev_info);
+int visorbus_create_instance(struct visor_device *dev);
+void visorbus_remove_instance(struct visor_device *bus_info);
+int create_visor_device(struct visor_device *dev_info);
+void remove_visor_device(struct visor_device *dev_info);
int visorchipset_device_pause(struct visor_device *dev_info);
int visorchipset_device_resume(struct visor_device *dev_info);
-void visorbus_create_response(struct visor_device *p, int response);
-void visorbus_destroy_response(struct visor_device *p, int response);
-void visorbus_device_create_response(struct visor_device *p, int response);
-void visorbus_device_destroy_response(struct visor_device *p, int response);
-void visorbus_device_resume_response(struct visor_device *p, int response);
-void visorbus_device_pause_response(struct visor_device *p, int response);
+void visorbus_response(struct visor_device *p, int response, int controlvm_id);
+void visorbus_device_changestate_response(struct visor_device *p, int response,
+ struct visor_segment_state state);
int visorbus_init(void);
void visorbus_exit(void);
/* visorchannel access functions */
-
-struct visorchannel *visorchannel_create(u64 physaddr,
- unsigned long channel_bytes,
- gfp_t gfp, uuid_le guid);
-struct visorchannel *visorchannel_create_with_lock(u64 physaddr,
- unsigned long channel_bytes,
- gfp_t gfp, uuid_le guid);
+struct visorchannel *visorchannel_create(u64 physaddr, gfp_t gfp,
+ const guid_t *guid);
+struct visorchannel *visorchannel_create_with_lock(u64 physaddr, gfp_t gfp,
+ const guid_t *guid);
void visorchannel_destroy(struct visorchannel *channel);
int visorchannel_read(struct visorchannel *channel, ulong offset,
void *dest, ulong nbytes);
@@ -64,6 +54,6 @@ char *visorchannel_zoneid(struct visorchannel *channel, char *s);
u64 visorchannel_get_clientpartition(struct visorchannel *channel);
int visorchannel_set_clientpartition(struct visorchannel *channel,
u64 partition_handle);
-char *visorchannel_uuid_id(uuid_le *guid, char *s);
+char *visorchannel_guid_id(const guid_t *guid, char *s);
void *visorchannel_get_header(struct visorchannel *channel);
#endif
diff --git a/drivers/staging/unisys/visorbus/visorchannel.c b/drivers/staging/unisys/visorbus/visorchannel.c
index 6885c2c..2a000fe 100644
--- a/drivers/staging/unisys/visorbus/visorchannel.c
+++ b/drivers/staging/unisys/visorbus/visorchannel.c
@@ -1,5 +1,4 @@
-/* visorchannel_funcs.c
- *
+/*
* Copyright (C) 2010 - 2015 UNISYS CORPORATION
* All rights reserved.
*
@@ -26,13 +25,13 @@
#include "visorbus_private.h"
#include "controlvmchannel.h"
-#define MYDRVNAME "visorchannel"
+#define VISOR_DRV_NAME "visorchannel"
#define VISOR_CONSOLEVIDEO_CHANNEL_GUID \
- UUID_LE(0x3cd6e705, 0xd6a2, 0x4aa5, \
- 0xad, 0x5c, 0x7b, 0x8, 0x88, 0x9d, 0xff, 0xe2)
+ GUID_INIT(0x3cd6e705, 0xd6a2, 0x4aa5, \
+ 0xad, 0x5c, 0x7b, 0x8, 0x88, 0x9d, 0xff, 0xe2)
-static const uuid_le visor_video_guid = VISOR_CONSOLEVIDEO_CHANNEL_GUID;
+static const guid_t visor_video_guid = VISOR_CONSOLEVIDEO_CHANNEL_GUID;
struct visorchannel {
u64 physaddr;
@@ -40,18 +39,21 @@ struct visorchannel {
void *mapped;
bool requested;
struct channel_header chan_hdr;
- uuid_le guid;
- bool needs_lock; /* channel creator knows if more than one */
- /* thread will be inserting or removing */
- spinlock_t insert_lock; /* protect head writes in chan_hdr */
- spinlock_t remove_lock; /* protect tail writes in chan_hdr */
-
- uuid_le type;
- uuid_le inst;
+ guid_t guid;
+ /*
+ * channel creator knows if more than one
+ * thread will be inserting or removing
+ */
+ bool needs_lock;
+ /* protect head writes in chan_hdr */
+ spinlock_t insert_lock;
+ /* protect tail writes in chan_hdr */
+ spinlock_t remove_lock;
+ guid_t type;
+ guid_t inst;
};
-void
-visorchannel_destroy(struct visorchannel *channel)
+void visorchannel_destroy(struct visorchannel *channel)
{
if (!channel)
return;
@@ -63,67 +65,58 @@ visorchannel_destroy(struct visorchannel *channel)
kfree(channel);
}
-u64
-visorchannel_get_physaddr(struct visorchannel *channel)
+u64 visorchannel_get_physaddr(struct visorchannel *channel)
{
return channel->physaddr;
}
-ulong
-visorchannel_get_nbytes(struct visorchannel *channel)
+ulong visorchannel_get_nbytes(struct visorchannel *channel)
{
return channel->nbytes;
}
-char *
-visorchannel_uuid_id(uuid_le *guid, char *s)
+char *visorchannel_guid_id(const guid_t *guid, char *s)
{
sprintf(s, "%pUL", guid);
return s;
}
-char *
-visorchannel_id(struct visorchannel *channel, char *s)
+char *visorchannel_id(struct visorchannel *channel, char *s)
{
- return visorchannel_uuid_id(&channel->guid, s);
+ return visorchannel_guid_id(&channel->guid, s);
}
-char *
-visorchannel_zoneid(struct visorchannel *channel, char *s)
+char *visorchannel_zoneid(struct visorchannel *channel, char *s)
{
- return visorchannel_uuid_id(&channel->chan_hdr.zone_uuid, s);
+ return visorchannel_guid_id(&channel->chan_hdr.zone_guid, s);
}
-u64
-visorchannel_get_clientpartition(struct visorchannel *channel)
+u64 visorchannel_get_clientpartition(struct visorchannel *channel)
{
return channel->chan_hdr.partition_handle;
}
-int
-visorchannel_set_clientpartition(struct visorchannel *channel,
- u64 partition_handle)
+int visorchannel_set_clientpartition(struct visorchannel *channel,
+ u64 partition_handle)
{
channel->chan_hdr.partition_handle = partition_handle;
return 0;
}
/**
- * visorchannel_get_uuid() - queries the UUID of the designated channel
+ * visorchannel_get_guid() - queries the GUID of the designated channel
* @channel: the channel to query
*
- * Return: the UUID of the provided channel
+ * Return: the GUID of the provided channel
*/
-uuid_le
-visorchannel_get_uuid(struct visorchannel *channel)
+const guid_t *visorchannel_get_guid(struct visorchannel *channel)
{
- return channel->guid;
+ return &channel->guid;
}
-EXPORT_SYMBOL_GPL(visorchannel_get_uuid);
+EXPORT_SYMBOL_GPL(visorchannel_get_guid);
-int
-visorchannel_read(struct visorchannel *channel, ulong offset,
- void *dest, ulong nbytes)
+int visorchannel_read(struct visorchannel *channel, ulong offset, void *dest,
+ ulong nbytes)
{
if (offset + nbytes > channel->nbytes)
return -EIO;
@@ -133,9 +126,8 @@ visorchannel_read(struct visorchannel *channel, ulong offset,
return 0;
}
-int
-visorchannel_write(struct visorchannel *channel, ulong offset,
- void *dest, ulong nbytes)
+int visorchannel_write(struct visorchannel *channel, ulong offset, void *dest,
+ ulong nbytes)
{
size_t chdr_size = sizeof(struct channel_header);
size_t copy_size;
@@ -154,8 +146,7 @@ visorchannel_write(struct visorchannel *channel, ulong offset,
return 0;
}
-void *
-visorchannel_get_header(struct visorchannel *channel)
+void *visorchannel_get_header(struct visorchannel *channel)
{
return &channel->chan_hdr;
}
@@ -164,17 +155,22 @@ visorchannel_get_header(struct visorchannel *channel)
* Return offset of a specific SIGNAL_QUEUE_HEADER from the beginning of a
* channel header
*/
-#define SIG_QUEUE_OFFSET(chan_hdr, q) \
- ((chan_hdr)->ch_space_offset + \
- ((q) * sizeof(struct signal_queue_header)))
+static int sig_queue_offset(struct channel_header *chan_hdr, int q)
+{
+ return ((chan_hdr)->ch_space_offset +
+ ((q) * sizeof(struct signal_queue_header)));
+}
/*
* Return offset of a specific queue entry (data) from the beginning of a
* channel header
*/
-#define SIG_DATA_OFFSET(chan_hdr, q, sig_hdr, slot) \
- (SIG_QUEUE_OFFSET(chan_hdr, q) + (sig_hdr)->sig_base_offset + \
- ((slot) * (sig_hdr)->signal_size))
+static int sig_data_offset(struct channel_header *chan_hdr, int q,
+ struct signal_queue_header *sig_hdr, int slot)
+{
+ return (sig_queue_offset(chan_hdr, q) + sig_hdr->sig_base_offset +
+ (slot * sig_hdr->signal_size));
+}
/*
* Write the contents of a specific field within a SIGNAL_QUEUE_HEADER back
@@ -182,48 +178,47 @@ visorchannel_get_header(struct visorchannel *channel)
*/
#define SIG_WRITE_FIELD(channel, queue, sig_hdr, FIELD) \
visorchannel_write(channel, \
- SIG_QUEUE_OFFSET(&channel->chan_hdr, queue) + \
+ sig_queue_offset(&channel->chan_hdr, queue) + \
offsetof(struct signal_queue_header, FIELD), \
&((sig_hdr)->FIELD), \
sizeof((sig_hdr)->FIELD))
-static int
-sig_read_header(struct visorchannel *channel, u32 queue,
- struct signal_queue_header *sig_hdr)
+static int sig_read_header(struct visorchannel *channel, u32 queue,
+ struct signal_queue_header *sig_hdr)
{
if (channel->chan_hdr.ch_space_offset < sizeof(struct channel_header))
return -EINVAL;
/* Read the appropriate SIGNAL_QUEUE_HEADER into local memory. */
return visorchannel_read(channel,
- SIG_QUEUE_OFFSET(&channel->chan_hdr, queue),
+ sig_queue_offset(&channel->chan_hdr, queue),
sig_hdr, sizeof(struct signal_queue_header));
}
-static int
-sig_read_data(struct visorchannel *channel, u32 queue,
- struct signal_queue_header *sig_hdr, u32 slot, void *data)
+static int sig_read_data(struct visorchannel *channel, u32 queue,
+ struct signal_queue_header *sig_hdr, u32 slot,
+ void *data)
{
- int signal_data_offset = SIG_DATA_OFFSET(&channel->chan_hdr, queue,
+ int signal_data_offset = sig_data_offset(&channel->chan_hdr, queue,
sig_hdr, slot);
return visorchannel_read(channel, signal_data_offset,
data, sig_hdr->signal_size);
}
-static int
-sig_write_data(struct visorchannel *channel, u32 queue,
- struct signal_queue_header *sig_hdr, u32 slot, void *data)
+static int sig_write_data(struct visorchannel *channel, u32 queue,
+ struct signal_queue_header *sig_hdr, u32 slot,
+ void *data)
{
- int signal_data_offset = SIG_DATA_OFFSET(&channel->chan_hdr, queue,
+ int signal_data_offset = sig_data_offset(&channel->chan_hdr, queue,
sig_hdr, slot);
return visorchannel_write(channel, signal_data_offset,
data, sig_hdr->signal_size);
}
-static int
-signalremove_inner(struct visorchannel *channel, u32 queue, void *msg)
+static int signalremove_inner(struct visorchannel *channel, u32 queue,
+ void *msg)
{
struct signal_queue_header sig_hdr;
int error;
@@ -246,9 +241,9 @@ signalremove_inner(struct visorchannel *channel, u32 queue, void *msg)
/*
* For each data field in SIGNAL_QUEUE_HEADER that was modified,
- * update host memory.
+ * update host memory. Required for channel sync.
*/
- mb(); /* required for channel synch */
+ mb();
error = SIG_WRITE_FIELD(channel, queue, &sig_hdr, tail);
if (error)
@@ -269,8 +264,8 @@ signalremove_inner(struct visorchannel *channel, u32 queue, void *msg)
*
* Return: integer error code indicating the status of the removal
*/
-int
-visorchannel_signalremove(struct visorchannel *channel, u32 queue, void *msg)
+int visorchannel_signalremove(struct visorchannel *channel, u32 queue,
+ void *msg)
{
int rc;
unsigned long flags;
@@ -287,8 +282,7 @@ visorchannel_signalremove(struct visorchannel *channel, u32 queue, void *msg)
}
EXPORT_SYMBOL_GPL(visorchannel_signalremove);
-static bool
-queue_empty(struct visorchannel *channel, u32 queue)
+static bool queue_empty(struct visorchannel *channel, u32 queue)
{
struct signal_queue_header sig_hdr;
@@ -307,8 +301,7 @@ queue_empty(struct visorchannel *channel, u32 queue)
* Return: boolean indicating whether any messages in the designated
* channel/queue are present
*/
-bool
-visorchannel_signalempty(struct visorchannel *channel, u32 queue)
+bool visorchannel_signalempty(struct visorchannel *channel, u32 queue)
{
bool rc;
unsigned long flags;
@@ -324,8 +317,8 @@ visorchannel_signalempty(struct visorchannel *channel, u32 queue)
}
EXPORT_SYMBOL_GPL(visorchannel_signalempty);
-static int
-signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg)
+static int signalinsert_inner(struct visorchannel *channel, u32 queue,
+ void *msg)
{
struct signal_queue_header sig_hdr;
int err;
@@ -351,9 +344,9 @@ signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg)
/*
* For each data field in SIGNAL_QUEUE_HEADER that was modified,
- * update host memory.
+ * update host memory. Required for channel sync.
*/
- mb(); /* required for channel synch */
+ mb();
err = SIG_WRITE_FIELD(channel, queue, &sig_hdr, head);
if (err)
@@ -370,17 +363,8 @@ signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg)
* for a data area in memory, but does NOT modify
* this data area
* @physaddr: physical address of start of channel
- * @channel_bytes: size of the channel in bytes; this may 0 if the channel has
- * already been initialized in memory (which is true for all
- * channels provided to guest environments by the s-Par
- * back-end), in which case the actual channel size will be
- * read from the channel header in memory
* @gfp: gfp_t to use when allocating memory for the data struct
- * @guid: uuid that identifies channel type; this may 0 if the channel
- * has already been initialized in memory (which is true for all
- * channels provided to guest environments by the s-Par
- * back-end), in which case the actual channel guid will be
- * read from the channel header in memory
+ * @guid: GUID that identifies channel type;
* @needs_lock: must specify true if you have multiple threads of execution
* that will be calling visorchannel methods of this
* visorchannel at the same time
@@ -388,9 +372,9 @@ signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg)
* Return: pointer to visorchannel that was created if successful,
* otherwise NULL
*/
-static struct visorchannel *
-visorchannel_create_guts(u64 physaddr, unsigned long channel_bytes,
- gfp_t gfp, uuid_le guid, bool needs_lock)
+static struct visorchannel *visorchannel_create_guts(u64 physaddr, gfp_t gfp,
+ const guid_t *guid,
+ bool needs_lock)
{
struct visorchannel *channel;
int err;
@@ -414,8 +398,8 @@ visorchannel_create_guts(u64 physaddr, unsigned long channel_bytes,
* this. Remember that we haven't requested it so we don't try to
* release later on.
*/
- channel->requested = request_mem_region(physaddr, size, MYDRVNAME);
- if (!channel->requested && uuid_le_cmp(guid, visor_video_guid))
+ channel->requested = request_mem_region(physaddr, size, VISOR_DRV_NAME);
+ if (!channel->requested && !guid_equal(guid, &visor_video_guid))
/* we only care about errors if this is not the video channel */
goto err_destroy_channel;
@@ -428,36 +412,29 @@ visorchannel_create_guts(u64 physaddr, unsigned long channel_bytes,
channel->physaddr = physaddr;
channel->nbytes = size;
- err = visorchannel_read(channel, 0, &channel->chan_hdr,
- sizeof(struct channel_header));
+ err = visorchannel_read(channel, 0, &channel->chan_hdr, size);
if (err)
goto err_destroy_channel;
-
- /* we had better be a CLIENT of this channel */
- if (channel_bytes == 0)
- channel_bytes = (ulong)channel->chan_hdr.size;
- if (uuid_le_cmp(guid, NULL_UUID_LE) == 0)
- guid = channel->chan_hdr.chtype;
+ size = (ulong)channel->chan_hdr.size;
memunmap(channel->mapped);
if (channel->requested)
release_mem_region(channel->physaddr, channel->nbytes);
channel->mapped = NULL;
- channel->requested = request_mem_region(channel->physaddr,
- channel_bytes, MYDRVNAME);
- if (!channel->requested && uuid_le_cmp(guid, visor_video_guid))
+ channel->requested = request_mem_region(channel->physaddr, size,
+ VISOR_DRV_NAME);
+ if (!channel->requested && !guid_equal(guid, &visor_video_guid))
/* we only care about errors if this is not the video channel */
goto err_destroy_channel;
- channel->mapped = memremap(channel->physaddr, channel_bytes,
- MEMREMAP_WB);
+ channel->mapped = memremap(channel->physaddr, size, MEMREMAP_WB);
if (!channel->mapped) {
- release_mem_region(channel->physaddr, channel_bytes);
+ release_mem_region(channel->physaddr, size);
goto err_destroy_channel;
}
- channel->nbytes = channel_bytes;
- channel->guid = guid;
+ channel->nbytes = size;
+ guid_copy(&channel->guid, guid);
return channel;
err_destroy_channel:
@@ -465,20 +442,16 @@ err_destroy_channel:
return NULL;
}
-struct visorchannel *
-visorchannel_create(u64 physaddr, unsigned long channel_bytes,
- gfp_t gfp, uuid_le guid)
+struct visorchannel *visorchannel_create(u64 physaddr, gfp_t gfp,
+ const guid_t *guid)
{
- return visorchannel_create_guts(physaddr, channel_bytes, gfp, guid,
- false);
+ return visorchannel_create_guts(physaddr, gfp, guid, false);
}
-struct visorchannel *
-visorchannel_create_with_lock(u64 physaddr, unsigned long channel_bytes,
- gfp_t gfp, uuid_le guid)
+struct visorchannel *visorchannel_create_with_lock(u64 physaddr, gfp_t gfp,
+ const guid_t *guid)
{
- return visorchannel_create_guts(physaddr, channel_bytes, gfp, guid,
- true);
+ return visorchannel_create_guts(physaddr, gfp, guid, true);
}
/**
@@ -490,8 +463,8 @@ visorchannel_create_with_lock(u64 physaddr, unsigned long channel_bytes,
*
* Return: integer error code indicating the status of the insertion
*/
-int
-visorchannel_signalinsert(struct visorchannel *channel, u32 queue, void *msg)
+int visorchannel_signalinsert(struct visorchannel *channel, u32 queue,
+ void *msg)
{
int rc;
unsigned long flags;
diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c
index 2215056..74cce4f 100644
--- a/drivers/staging/unisys/visorbus/visorchipset.c
+++ b/drivers/staging/unisys/visorbus/visorchipset.c
@@ -1,5 +1,4 @@
-/* visorchipset_main.c
- *
+/*
* Copyright (C) 2010 - 2015 UNISYS CORPORATION
* All rights reserved.
*
@@ -15,19 +14,18 @@
*/
#include <linux/acpi.h>
-#include <linux/ctype.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/nls.h>
-#include <linux/netdevice.h>
-#include <linux/uuid.h>
#include <linux/crash_dump.h>
#include "visorbus.h"
#include "visorbus_private.h"
-#include "vmcallinterface.h"
-#define CURRENT_FILE_PC VISOR_BUS_PC_visorchipset_c
+/* {72120008-4AAB-11DC-8530-444553544200} */
+#define VISOR_SIOVM_GUID GUID_INIT(0x72120008, 0x4AAB, 0x11DC, 0x85, 0x30, \
+ 0x44, 0x45, 0x53, 0x54, 0x42, 0x00)
+
+static const guid_t visor_vhba_channel_guid = VISOR_VHBA_CHANNEL_GUID;
+static const guid_t visor_siovm_guid = VISOR_SIOVM_GUID;
+static const guid_t visor_controlvm_channel_guid = VISOR_CONTROLVM_CHANNEL_GUID;
#define POLLJIFFIES_CONTROLVMCHANNEL_FAST 1
#define POLLJIFFIES_CONTROLVMCHANNEL_SLOW 100
@@ -42,9 +40,9 @@
#define UNISYS_VISOR_ID_EDX 0x34367261
/*
- * When the controlvm channel is idle for at least MIN_IDLE_SECONDS,
- * we switch to slow polling mode. As soon as we get a controlvm
- * message, we switch back to fast polling mode.
+ * When the controlvm channel is idle for at least MIN_IDLE_SECONDS, we switch
+ * to slow polling mode. As soon as we get a controlvm message, we switch back
+ * to fast polling mode.
*/
#define MIN_IDLE_SECONDS 10
@@ -54,15 +52,39 @@ struct parser_context {
u8 *curr;
unsigned long bytes_remaining;
bool byte_stream;
- char data[0];
+ struct visor_controlvm_parameters_header data;
};
-struct vmcall_controlvm_addr {
- struct vmcall_io_controlvm_addr_params params;
- int err;
- u64 physaddr;
+/* VMCALL_CONTROLVM_ADDR: Used by all guests, not just IO. */
+#define VMCALL_CONTROLVM_ADDR 0x0501
+
+enum vmcall_result {
+ VMCALL_RESULT_SUCCESS = 0,
+ VMCALL_RESULT_INVALID_PARAM = 1,
+ VMCALL_RESULT_DATA_UNAVAILABLE = 2,
+ VMCALL_RESULT_FAILURE_UNAVAILABLE = 3,
+ VMCALL_RESULT_DEVICE_ERROR = 4,
+ VMCALL_RESULT_DEVICE_NOT_READY = 5
};
+/*
+ * struct vmcall_io_controlvm_addr_params - Structure for IO VMCALLS. Has
+ * parameters to VMCALL_CONTROLVM_ADDR
+ * interface.
+ * @address: The Guest-relative physical address of the ControlVm channel.
+ * This VMCall fills this in with the appropriate address.
+ * Contents provided by this VMCALL (OUT).
+ * @channel_bytes: The size of the ControlVm channel in bytes This VMCall fills
+ * this in with the appropriate address. Contents provided by
+ * this VMCALL (OUT).
+ * @unused: Unused Bytes in the 64-Bit Aligned Struct.
+ */
+struct vmcall_io_controlvm_addr_params {
+ u64 address;
+ u32 channel_bytes;
+ u8 unused[4];
+} __packed;
+
struct visorchipset_device {
struct acpi_device *acpi_device;
unsigned long poll_jiffies;
@@ -80,7 +102,7 @@ struct visorchipset_device {
*/
struct controlvm_message controlvm_pending_msg;
bool controlvm_pending_msg_valid;
- struct vmcall_controlvm_addr controlvm_addr;
+ struct vmcall_io_controlvm_addr_params controlvm_params;
};
static struct visorchipset_device *chipset_dev;
@@ -124,7 +146,6 @@ static ssize_t toolaction_store(struct device *dev,
offsetof(struct visor_controlvm_channel,
tool_action),
&tool_action, sizeof(u8));
-
if (err)
return err;
return count;
@@ -143,7 +164,6 @@ static ssize_t boottotool_show(struct device *dev,
efi_visor_ind),
&efi_visor_indication,
sizeof(struct efi_visor_indication));
-
if (err)
return err;
return sprintf(buf, "%u\n", efi_visor_indication.boot_to_tool);
@@ -165,7 +185,6 @@ static ssize_t boottotool_store(struct device *dev,
efi_visor_ind),
&(efi_visor_indication),
sizeof(struct efi_visor_indication));
-
if (err)
return err;
return count;
@@ -184,7 +203,7 @@ static ssize_t error_show(struct device *dev, struct device_attribute *attr,
&error, sizeof(u32));
if (err)
return err;
- return sprintf(buf, "%i\n", error);
+ return sprintf(buf, "%u\n", error);
}
static ssize_t error_store(struct device *dev, struct device_attribute *attr,
@@ -219,7 +238,7 @@ static ssize_t textid_show(struct device *dev, struct device_attribute *attr,
if (err)
return err;
- return sprintf(buf, "%i\n", text_id);
+ return sprintf(buf, "%u\n", text_id);
}
static ssize_t textid_store(struct device *dev, struct device_attribute *attr,
@@ -277,67 +296,6 @@ static ssize_t remaining_steps_store(struct device *dev,
}
static DEVICE_ATTR_RW(remaining_steps);
-static uuid_le
-parser_id_get(struct parser_context *ctx)
-{
- struct visor_controlvm_parameters_header *phdr = NULL;
-
- phdr = (struct visor_controlvm_parameters_header *)(ctx->data);
- return phdr->id;
-}
-
-static void parser_done(struct parser_context *ctx)
-{
- chipset_dev->controlvm_payload_bytes_buffered -= ctx->param_bytes;
- kfree(ctx);
-}
-
-static void *
-parser_string_get(struct parser_context *ctx)
-{
- u8 *pscan;
- unsigned long nscan;
- int value_length = -1;
- void *value = NULL;
- int i;
-
- pscan = ctx->curr;
- nscan = ctx->bytes_remaining;
- if (nscan == 0)
- return NULL;
- if (!pscan)
- return NULL;
- for (i = 0, value_length = -1; i < nscan; i++)
- if (pscan[i] == '\0') {
- value_length = i;
- break;
- }
- if (value_length < 0) /* '\0' was not included in the length */
- value_length = nscan;
- value = kmalloc(value_length + 1, GFP_KERNEL);
- if (!value)
- return NULL;
- if (value_length > 0)
- memcpy(value, pscan, value_length);
- ((u8 *)(value))[value_length] = '\0';
- return value;
-}
-
-static void *
-parser_name_get(struct parser_context *ctx)
-{
- struct visor_controlvm_parameters_header *phdr = NULL;
-
- phdr = (struct visor_controlvm_parameters_header *)(ctx->data);
-
- if (phdr->name_offset + phdr->name_length > ctx->param_bytes)
- return NULL;
-
- ctx->curr = ctx->data + phdr->name_offset;
- ctx->bytes_remaining = phdr->name_length;
- return parser_string_get(ctx);
-}
-
struct visor_busdev {
u32 bus_no;
u32 dev_no;
@@ -347,11 +305,9 @@ static int match_visorbus_dev_by_id(struct device *dev, void *data)
{
struct visor_device *vdev = to_visor_device(dev);
struct visor_busdev *id = data;
- u32 bus_no = id->bus_no;
- u32 dev_no = id->dev_no;
- if ((vdev->chipset_bus_no == bus_no) &&
- (vdev->chipset_dev_no == dev_no))
+ if ((vdev->chipset_bus_no == id->bus_no) &&
+ (vdev->chipset_dev_no == id->dev_no))
return 1;
return 0;
@@ -364,9 +320,9 @@ struct visor_device *visorbus_get_device_by_id(u32 bus_no, u32 dev_no,
struct device *dev_start = NULL;
struct visor_device *vdev = NULL;
struct visor_busdev id = {
- .bus_no = bus_no,
- .dev_no = dev_no
- };
+ .bus_no = bus_no,
+ .dev_no = dev_no
+ };
if (from)
dev_start = &from->device;
@@ -377,9 +333,9 @@ struct visor_device *visorbus_get_device_by_id(u32 bus_no, u32 dev_no,
return vdev;
}
-static void
-controlvm_init_response(struct controlvm_message *msg,
- struct controlvm_message_header *msg_hdr, int response)
+static void controlvm_init_response(struct controlvm_message *msg,
+ struct controlvm_message_header *msg_hdr,
+ int response)
{
memset(msg, 0, sizeof(struct controlvm_message));
memcpy(&msg->hdr, msg_hdr, sizeof(struct controlvm_message_header));
@@ -392,10 +348,10 @@ controlvm_init_response(struct controlvm_message *msg,
}
}
-static int
-controlvm_respond_chipset_init(struct controlvm_message_header *msg_hdr,
- int response,
- enum visor_chipset_feature features)
+static int controlvm_respond_chipset_init(
+ struct controlvm_message_header *msg_hdr,
+ int response,
+ enum visor_chipset_feature features)
{
struct controlvm_message outmsg;
@@ -405,8 +361,7 @@ controlvm_respond_chipset_init(struct controlvm_message_header *msg_hdr,
CONTROLVM_QUEUE_REQUEST, &outmsg);
}
-static int
-chipset_init(struct controlvm_message *inmsg)
+static int chipset_init(struct controlvm_message *inmsg)
{
static int chipset_inited;
enum visor_chipset_feature features = 0;
@@ -421,15 +376,15 @@ chipset_init(struct controlvm_message *inmsg)
chipset_inited = 1;
/*
- * Set features to indicate we support parahotplug (if Command
- * also supports it).
+ * Set features to indicate we support parahotplug (if Command also
+ * supports it).
*/
features = inmsg->cmd.init_chipset.features &
VISOR_CHIPSET_FEATURE_PARA_HOTPLUG;
/*
- * Set the "reply" bit so Command knows this is a
- * features-aware driver.
+ * Set the "reply" bit so Command knows this is a features-aware
+ * driver.
*/
features |= VISOR_CHIPSET_FEATURE_REPLY;
@@ -440,9 +395,9 @@ out_respond:
return res;
}
-static int
-controlvm_respond(struct controlvm_message_header *msg_hdr, int response,
- struct visor_segment_state *state)
+static int controlvm_respond(struct controlvm_message_header *msg_hdr,
+ int response,
+ struct visor_segment_state *state)
{
struct controlvm_message outmsg;
@@ -464,8 +419,8 @@ enum crash_obj_type {
CRASH_BUS,
};
-static int
-save_crash_message(struct controlvm_message *msg, enum crash_obj_type cr_type)
+static int save_crash_message(struct controlvm_message *msg,
+ enum crash_obj_type cr_type)
{
u32 local_crash_msg_offset;
u16 local_crash_msg_count;
@@ -529,10 +484,9 @@ save_crash_message(struct controlvm_message *msg, enum crash_obj_type cr_type)
return 0;
}
-static int
-controlvm_responder(enum controlvm_id cmd_id,
- struct controlvm_message_header *pending_msg_hdr,
- int response)
+static int controlvm_responder(enum controlvm_id cmd_id,
+ struct controlvm_message_header *pending_msg_hdr,
+ int response)
{
if (!pending_msg_hdr)
return -EIO;
@@ -543,14 +497,12 @@ controlvm_responder(enum controlvm_id cmd_id,
return controlvm_respond(pending_msg_hdr, response, NULL);
}
-static int
-device_changestate_responder(enum controlvm_id cmd_id,
- struct visor_device *p, int response,
- struct visor_segment_state response_state)
+static int device_changestate_responder(
+ enum controlvm_id cmd_id,
+ struct visor_device *p, int response,
+ struct visor_segment_state response_state)
{
struct controlvm_message outmsg;
- u32 bus_no = p->chipset_bus_no;
- u32 dev_no = p->chipset_dev_no;
if (!p->pending_msg_hdr)
return -EIO;
@@ -559,16 +511,15 @@ device_changestate_responder(enum controlvm_id cmd_id,
controlvm_init_response(&outmsg, p->pending_msg_hdr, response);
- outmsg.cmd.device_change_state.bus_no = bus_no;
- outmsg.cmd.device_change_state.dev_no = dev_no;
+ outmsg.cmd.device_change_state.bus_no = p->chipset_bus_no;
+ outmsg.cmd.device_change_state.dev_no = p->chipset_dev_no;
outmsg.cmd.device_change_state.state = response_state;
return visorchannel_signalinsert(chipset_dev->controlvm_channel,
CONTROLVM_QUEUE_REQUEST, &outmsg);
}
-static int
-visorbus_create(struct controlvm_message *inmsg)
+static int visorbus_create(struct controlvm_message *inmsg)
{
struct controlvm_message_packet *cmd = &inmsg->cmd;
struct controlvm_message_header *pmsg_hdr = NULL;
@@ -580,7 +531,7 @@ visorbus_create(struct controlvm_message *inmsg)
bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL);
if (bus_info && (bus_info->state.created == 1)) {
dev_err(&chipset_dev->acpi_device->dev,
- "failed visorbus_create: already exists\n");
+ "failed %s: already exists\n", __func__);
err = -EEXIST;
goto err_respond;
}
@@ -595,7 +546,7 @@ visorbus_create(struct controlvm_message *inmsg)
bus_info->chipset_bus_no = bus_no;
bus_info->chipset_dev_no = BUS_ROOT_DEVICE;
- if (uuid_le_cmp(cmd->create_bus.bus_inst_uuid, visor_siovm_uuid) == 0) {
+ if (guid_equal(&cmd->create_bus.bus_inst_guid, &visor_siovm_guid)) {
err = save_crash_message(inmsg, CRASH_BUS);
if (err)
goto err_free_bus_info;
@@ -615,19 +566,17 @@ visorbus_create(struct controlvm_message *inmsg)
}
visorchannel = visorchannel_create(cmd->create_bus.channel_addr,
- cmd->create_bus.channel_bytes,
GFP_KERNEL,
- cmd->create_bus.bus_data_type_uuid);
-
+ &cmd->create_bus.bus_data_type_guid);
if (!visorchannel) {
err = -ENOMEM;
goto err_free_pending_msg;
}
+
bus_info->visorchannel = visorchannel;
- /* Response will be handled by visorchipset_bus_create */
- err = visorchipset_bus_create(bus_info);
- /* If visorchipset_bus_create didn't respond, need to respond here */
+ /* Response will be handled by visorbus_create_instance on success */
+ err = visorbus_create_instance(bus_info);
if (err)
goto err_destroy_channel;
@@ -648,8 +597,7 @@ err_respond:
return err;
}
-static int
-visorbus_destroy(struct controlvm_message *inmsg)
+static int visorbus_destroy(struct controlvm_message *inmsg)
{
struct controlvm_message_packet *cmd = &inmsg->cmd;
struct controlvm_message_header *pmsg_hdr = NULL;
@@ -683,8 +631,8 @@ visorbus_destroy(struct controlvm_message *inmsg)
bus_info->pending_msg_hdr = pmsg_hdr;
}
- /* Response will be handled by visorchipset_bus_destroy */
- visorchipset_bus_destroy(bus_info);
+ /* Response will be handled by visorbus_remove_instance */
+ visorbus_remove_instance(bus_info);
return 0;
err_respond:
@@ -693,9 +641,60 @@ err_respond:
return err;
}
-static int
-visorbus_configure(struct controlvm_message *inmsg,
- struct parser_context *parser_ctx)
+static const guid_t *parser_id_get(struct parser_context *ctx)
+{
+ return &ctx->data.id;
+}
+
+static void *parser_string_get(struct parser_context *ctx)
+{
+ u8 *pscan;
+ unsigned long nscan;
+ int value_length;
+ void *value;
+ int i;
+
+ pscan = ctx->curr;
+ if (!pscan)
+ return NULL;
+ nscan = ctx->bytes_remaining;
+ if (nscan == 0)
+ return NULL;
+
+ for (i = 0, value_length = -1; i < nscan; i++)
+ if (pscan[i] == '\0') {
+ value_length = i;
+ break;
+ }
+ /* '\0' was not included in the length */
+ if (value_length < 0)
+ value_length = nscan;
+
+ value = kmalloc(value_length + 1, GFP_KERNEL);
+ if (!value)
+ return NULL;
+ if (value_length > 0)
+ memcpy(value, pscan, value_length);
+ ((u8 *)(value))[value_length] = '\0';
+ return value;
+}
+
+static void *parser_name_get(struct parser_context *ctx)
+{
+ struct visor_controlvm_parameters_header *phdr = NULL;
+
+ phdr = &ctx->data;
+
+ if (phdr->name_offset + phdr->name_length > ctx->param_bytes)
+ return NULL;
+
+ ctx->curr = (char *)&phdr + phdr->name_offset;
+ ctx->bytes_remaining = phdr->name_length;
+ return parser_string_get(ctx);
+}
+
+static int visorbus_configure(struct controlvm_message *inmsg,
+ struct parser_context *parser_ctx)
{
struct controlvm_message_packet *cmd = &inmsg->cmd;
u32 bus_no;
@@ -707,10 +706,12 @@ visorbus_configure(struct controlvm_message *inmsg,
if (!bus_info) {
err = -EINVAL;
goto err_respond;
- } else if (bus_info->state.created == 0) {
+ }
+ if (bus_info->state.created == 0) {
err = -EINVAL;
goto err_respond;
- } else if (bus_info->pending_msg_hdr) {
+ }
+ if (bus_info->pending_msg_hdr) {
err = -EIO;
goto err_respond;
}
@@ -722,7 +723,9 @@ visorbus_configure(struct controlvm_message *inmsg,
goto err_respond;
if (parser_ctx) {
- bus_info->partition_uuid = parser_id_get(parser_ctx);
+ const guid_t *partition_guid = parser_id_get(parser_ctx);
+
+ guid_copy(&bus_info->partition_guid, partition_guid);
bus_info->name = parser_name_get(parser_ctx);
}
@@ -732,14 +735,13 @@ visorbus_configure(struct controlvm_message *inmsg,
err_respond:
dev_err(&chipset_dev->acpi_device->dev,
- "visorbus_configure exited with err: %d\n", err);
+ "%s exited with err: %d\n", __func__, err);
if (inmsg->hdr.flags.response_expected == 1)
controlvm_responder(inmsg->hdr.id, &inmsg->hdr, err);
return err;
}
-static int
-visorbus_device_create(struct controlvm_message *inmsg)
+static int visorbus_device_create(struct controlvm_message *inmsg)
{
struct controlvm_message_packet *cmd = &inmsg->cmd;
struct controlvm_message_header *pmsg_hdr = NULL;
@@ -757,7 +759,6 @@ visorbus_device_create(struct controlvm_message *inmsg)
err = -ENODEV;
goto err_respond;
}
-
if (bus_info->state.created == 0) {
dev_err(&chipset_dev->acpi_device->dev,
"bus not created, id: %d\n", bus_no);
@@ -781,17 +782,13 @@ visorbus_device_create(struct controlvm_message *inmsg)
dev_info->chipset_bus_no = bus_no;
dev_info->chipset_dev_no = dev_no;
- dev_info->inst = cmd->create_device.dev_inst_uuid;
-
- /* not sure where the best place to set the 'parent' */
+ guid_copy(&dev_info->inst, &cmd->create_device.dev_inst_guid);
dev_info->device.parent = &bus_info->device;
visorchannel =
visorchannel_create_with_lock(cmd->create_device.channel_addr,
- cmd->create_device.channel_bytes,
GFP_KERNEL,
- cmd->create_device.data_type_uuid);
-
+ &cmd->create_device.data_type_guid);
if (!visorchannel) {
dev_err(&chipset_dev->acpi_device->dev,
"failed to create visorchannel: %d/%d\n",
@@ -800,9 +797,8 @@ visorbus_device_create(struct controlvm_message *inmsg)
goto err_free_dev_info;
}
dev_info->visorchannel = visorchannel;
- dev_info->channel_type_guid = cmd->create_device.data_type_uuid;
- if (uuid_le_cmp(cmd->create_device.data_type_uuid,
- visor_vhba_channel_uuid) == 0) {
+ guid_copy(&dev_info->channel_type_guid, &cmd->create_device.data_type_guid);
+ if (guid_equal(&cmd->create_device.data_type_guid, &visor_vhba_channel_guid)) {
err = save_crash_message(inmsg, CRASH_DEV);
if (err)
goto err_destroy_visorchannel;
@@ -819,8 +815,8 @@ visorbus_device_create(struct controlvm_message *inmsg)
sizeof(struct controlvm_message_header));
dev_info->pending_msg_hdr = pmsg_hdr;
}
- /* visorchipset_device_create will send response */
- err = visorchipset_device_create(dev_info);
+ /* create_visor_device will send response */
+ err = create_visor_device(dev_info);
if (err)
goto err_destroy_visorchannel;
@@ -838,8 +834,7 @@ err_respond:
return err;
}
-static int
-visorbus_device_changestate(struct controlvm_message *inmsg)
+static int visorbus_device_changestate(struct controlvm_message *inmsg)
{
struct controlvm_message_packet *cmd = &inmsg->cmd;
struct controlvm_message_header *pmsg_hdr = NULL;
@@ -899,8 +894,7 @@ err_respond:
return err;
}
-static int
-visorbus_device_destroy(struct controlvm_message *inmsg)
+static int visorbus_device_destroy(struct controlvm_message *inmsg)
{
struct controlvm_message_packet *cmd = &inmsg->cmd;
struct controlvm_message_header *pmsg_hdr = NULL;
@@ -918,7 +912,6 @@ visorbus_device_destroy(struct controlvm_message *inmsg)
err = -EINVAL;
goto err_respond;
}
-
if (dev_info->pending_msg_hdr) {
/* only non-NULL if dev is still waiting on a response */
err = -EIO;
@@ -936,7 +929,8 @@ visorbus_device_destroy(struct controlvm_message *inmsg)
dev_info->pending_msg_hdr = pmsg_hdr;
}
- visorchipset_device_destroy(dev_info);
+ kfree(dev_info->name);
+ remove_visor_device(dev_info);
return 0;
err_respond:
@@ -954,8 +948,7 @@ err_respond:
* disable the specified device. The udev script then writes to
* /sys/devices/platform/visorchipset/parahotplug, which causes the
* parahotplug store functions to get called, at which point the
- * appropriate CONTROLVM message is retrieved from the list and responded
- * to.
+ * appropriate CONTROLVM message is retrieved from the list and responded to.
*/
#define PARAHOTPLUG_TIMEOUT_MS 2000
@@ -967,8 +960,7 @@ err_respond:
*
* Return: a unique integer value
*/
-static int
-parahotplug_next_id(void)
+static int parahotplug_next_id(void)
{
static atomic_t id = ATOMIC_INIT(0);
@@ -982,8 +974,7 @@ parahotplug_next_id(void)
*
* Return: expected expiration time (in jiffies)
*/
-static unsigned long
-parahotplug_next_expiration(void)
+static unsigned long parahotplug_next_expiration(void)
{
return jiffies + msecs_to_jiffies(PARAHOTPLUG_TIMEOUT_MS);
}
@@ -996,8 +987,8 @@ parahotplug_next_expiration(void)
*
* Return: the request containing the provided message
*/
-static struct parahotplug_request *
-parahotplug_request_create(struct controlvm_message *msg)
+static struct parahotplug_request *parahotplug_request_create(
+ struct controlvm_message *msg)
{
struct parahotplug_request *req;
@@ -1016,14 +1007,14 @@ parahotplug_request_create(struct controlvm_message *msg)
* parahotplug_request_destroy() - free a parahotplug_request
* @req: the request to deallocate
*/
-static void
-parahotplug_request_destroy(struct parahotplug_request *req)
+static void parahotplug_request_destroy(struct parahotplug_request *req)
{
kfree(req);
}
static LIST_HEAD(parahotplug_request_list);
-static DEFINE_SPINLOCK(parahotplug_request_list_lock); /* lock for above */
+/* lock for above */
+static DEFINE_SPINLOCK(parahotplug_request_list_lock);
/*
* parahotplug_request_complete() - mark request as complete
@@ -1036,8 +1027,7 @@ static DEFINE_SPINLOCK(parahotplug_request_list_lock); /* lock for above */
*
* Return: 0 on success or -EINVAL on failure
*/
-static int
-parahotplug_request_complete(int id, u16 active)
+static int parahotplug_request_complete(int id, u16 active)
{
struct list_head *pos;
struct list_head *tmp;
@@ -1146,7 +1136,7 @@ static struct attribute *visorchipset_parahotplug_attrs[] = {
NULL
};
-static struct attribute_group visorchipset_parahotplug_group = {
+static const struct attribute_group visorchipset_parahotplug_group = {
.name = "parahotplug",
.attrs = visorchipset_parahotplug_attrs
};
@@ -1164,8 +1154,7 @@ static const struct attribute_group *visorchipset_dev_groups[] = {
* Cause uevent to run the user level script to do the disable/enable specified
* in the parahotplug_request.
*/
-static int
-parahotplug_request_kickoff(struct parahotplug_request *req)
+static int parahotplug_request_kickoff(struct parahotplug_request *req)
{
struct controlvm_message_packet *cmd = &req->msg.cmd;
char env_cmd[40], env_id[40], env_state[40], env_bus[40], env_dev[40],
@@ -1194,14 +1183,12 @@ parahotplug_request_kickoff(struct parahotplug_request *req)
* off a udev script
* @inmsg: the message indicating whether to enable or disable
*/
-static int
-parahotplug_process_message(struct controlvm_message *inmsg)
+static int parahotplug_process_message(struct controlvm_message *inmsg)
{
struct parahotplug_request *req;
int err;
req = parahotplug_request_create(inmsg);
-
if (!req)
return -ENOMEM;
@@ -1220,10 +1207,9 @@ parahotplug_process_message(struct controlvm_message *inmsg)
}
/*
- * For disable messages, add the request to the
- * request list before kicking off the udev script. It
- * won't get responded to until the script has
- * indicated it's done.
+ * For disable messages, add the request to the request list before
+ * kicking off the udev script. It won't get responded to until the
+ * script has indicated it's done.
*/
spin_lock(&parahotplug_request_list_lock);
list_add_tail(&req->list, &parahotplug_request_list);
@@ -1247,8 +1233,7 @@ err_respond:
*
* Return: 0 on success, negative on failure
*/
-static int
-chipset_ready_uevent(struct controlvm_message_header *msg_hdr)
+static int chipset_ready_uevent(struct controlvm_message_header *msg_hdr)
{
int res;
@@ -1268,8 +1253,7 @@ chipset_ready_uevent(struct controlvm_message_header *msg_hdr)
*
* Return: 0 on success, negative on failure
*/
-static int
-chipset_selftest_uevent(struct controlvm_message_header *msg_hdr)
+static int chipset_selftest_uevent(struct controlvm_message_header *msg_hdr)
{
char env_selftest[20];
char *envp[] = { env_selftest, NULL };
@@ -1292,13 +1276,11 @@ chipset_selftest_uevent(struct controlvm_message_header *msg_hdr)
*
* Return: 0 on success, negative on failure
*/
-static int
-chipset_notready_uevent(struct controlvm_message_header *msg_hdr)
+static int chipset_notready_uevent(struct controlvm_message_header *msg_hdr)
{
- int res;
-
- res = kobject_uevent(&chipset_dev->acpi_device->dev.kobj,
+ int res = kobject_uevent(&chipset_dev->acpi_device->dev.kobj,
KOBJ_OFFLINE);
+
if (msg_hdr->flags.response_expected)
controlvm_respond(msg_hdr, res, NULL);
@@ -1321,13 +1303,12 @@ static int unisys_vmcall(unsigned long tuple, unsigned long param)
__asm__ __volatile__(".byte 0x00f, 0x001, 0x0c1" : "=a"(result) :
"a"(tuple), "b"(reg_ebx), "c"(reg_ecx));
-
if (result)
goto error;
return 0;
-
-error: /* Need to convert from VMCALL error codes to Linux */
+/* Need to convert from VMCALL error codes to Linux */
+error:
switch (result) {
case VMCALL_RESULT_INVALID_PARAM:
return -EINVAL;
@@ -1337,35 +1318,27 @@ error: /* Need to convert from VMCALL error codes to Linux */
return -EFAULT;
}
}
-static unsigned int
-issue_vmcall_io_controlvm_addr(u64 *control_addr, u32 *control_bytes)
-{
- chipset_dev->controlvm_addr.physaddr = virt_to_phys(
- &chipset_dev->controlvm_addr.params);
- chipset_dev->controlvm_addr.err = unisys_vmcall(VMCALL_CONTROLVM_ADDR,
- chipset_dev->controlvm_addr.physaddr);
- if (chipset_dev->controlvm_addr.err)
- return chipset_dev->controlvm_addr.err;
-
- *control_addr = chipset_dev->controlvm_addr.params.address;
- *control_bytes = chipset_dev->controlvm_addr.params.channel_bytes;
-
- return 0;
-}
-static u64 controlvm_get_channel_address(void)
+static int controlvm_channel_create(struct visorchipset_device *dev)
{
- u64 addr = 0;
- u32 size = 0;
-
- if (issue_vmcall_io_controlvm_addr(&addr, &size))
- return 0;
+ struct visorchannel *chan;
+ u64 addr;
+ int err;
- return addr;
+ err = unisys_vmcall(VMCALL_CONTROLVM_ADDR,
+ virt_to_phys(&dev->controlvm_params));
+ if (err)
+ return err;
+ addr = dev->controlvm_params.address;
+ chan = visorchannel_create_with_lock(addr, GFP_KERNEL,
+ &visor_controlvm_channel_guid);
+ if (!chan)
+ return -ENOMEM;
+ dev->controlvm_channel = chan;
+ return 0;
}
-static void
-setup_crash_devices_work_queue(struct work_struct *work)
+static void setup_crash_devices_work_queue(struct work_struct *work)
{
struct controlvm_message local_crash_bus_msg;
struct controlvm_message local_crash_dev_msg;
@@ -1444,87 +1417,44 @@ setup_crash_devices_work_queue(struct work_struct *work)
visorbus_device_create(&local_crash_dev_msg);
}
-void
-visorbus_create_response(struct visor_device *bus_info, int response)
+void visorbus_response(struct visor_device *bus_info, int response,
+ int controlvm_id)
{
- if (response >= 0)
- bus_info->state.created = 1;
-
- controlvm_responder(CONTROLVM_BUS_CREATE, bus_info->pending_msg_hdr,
- response);
+ controlvm_responder(controlvm_id, bus_info->pending_msg_hdr, response);
kfree(bus_info->pending_msg_hdr);
bus_info->pending_msg_hdr = NULL;
}
-void
-visorbus_destroy_response(struct visor_device *bus_info, int response)
-{
- controlvm_responder(CONTROLVM_BUS_DESTROY, bus_info->pending_msg_hdr,
- response);
-
- kfree(bus_info->pending_msg_hdr);
- bus_info->pending_msg_hdr = NULL;
-}
-
-void
-visorbus_device_create_response(struct visor_device *dev_info, int response)
-{
- if (response >= 0)
- dev_info->state.created = 1;
-
- controlvm_responder(CONTROLVM_DEVICE_CREATE, dev_info->pending_msg_hdr,
- response);
-
- kfree(dev_info->pending_msg_hdr);
- dev_info->pending_msg_hdr = NULL;
-}
-
-void
-visorbus_device_destroy_response(struct visor_device *dev_info, int response)
-{
- controlvm_responder(CONTROLVM_DEVICE_DESTROY, dev_info->pending_msg_hdr,
- response);
-
- kfree(dev_info->pending_msg_hdr);
- dev_info->pending_msg_hdr = NULL;
-}
-
-void
-visorbus_device_pause_response(struct visor_device *dev_info, int response)
+void visorbus_device_changestate_response(struct visor_device *dev_info,
+ int response,
+ struct visor_segment_state state)
{
device_changestate_responder(CONTROLVM_DEVICE_CHANGESTATE,
- dev_info, response,
- segment_state_standby);
+ dev_info, response, state);
kfree(dev_info->pending_msg_hdr);
dev_info->pending_msg_hdr = NULL;
}
-void
-visorbus_device_resume_response(struct visor_device *dev_info, int response)
+static void parser_done(struct parser_context *ctx)
{
- device_changestate_responder(CONTROLVM_DEVICE_CHANGESTATE,
- dev_info, response,
- segment_state_running);
-
- kfree(dev_info->pending_msg_hdr);
- dev_info->pending_msg_hdr = NULL;
+ chipset_dev->controlvm_payload_bytes_buffered -= ctx->param_bytes;
+ kfree(ctx);
}
-static struct parser_context *
-parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry)
+static struct parser_context *parser_init_stream(u64 addr, u32 bytes,
+ bool *retry)
{
- int allocbytes = sizeof(struct parser_context) + bytes;
+ int allocbytes;
struct parser_context *ctx;
+ void *mapping;
*retry = false;
- /*
- * alloc an 0 extra byte to ensure payload is
- * '\0'-terminated
- */
- allocbytes++;
+ /* alloc an extra byte to ensure payload is \0 terminated */
+ allocbytes = bytes + 1 + (sizeof(struct parser_context) -
+ sizeof(struct visor_controlvm_parameters_header));
if ((chipset_dev->controlvm_payload_bytes_buffered + bytes)
> MAX_CONTROLVM_PAYLOAD_BYTES) {
*retry = true;
@@ -1538,32 +1468,18 @@ parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry)
ctx->allocbytes = allocbytes;
ctx->param_bytes = bytes;
- ctx->curr = NULL;
- ctx->bytes_remaining = 0;
- ctx->byte_stream = false;
- if (local) {
- void *p;
-
- if (addr > virt_to_phys(high_memory - 1))
- goto err_finish_ctx;
- p = __va((unsigned long)(addr));
- memcpy(ctx->data, p, bytes);
- } else {
- void *mapping = memremap(addr, bytes, MEMREMAP_WB);
-
- if (!mapping)
- goto err_finish_ctx;
- memcpy(ctx->data, mapping, bytes);
- memunmap(mapping);
- }
-
+ mapping = memremap(addr, bytes, MEMREMAP_WB);
+ if (!mapping)
+ goto err_finish_ctx;
+ memcpy(&ctx->data, mapping, bytes);
+ memunmap(mapping);
ctx->byte_stream = true;
chipset_dev->controlvm_payload_bytes_buffered += ctx->param_bytes;
return ctx;
err_finish_ctx:
- parser_done(ctx);
+ kfree(ctx);
return NULL;
}
@@ -1580,19 +1496,16 @@ err_finish_ctx:
* which to copy out controlvm payload data.
* < 0 - error: ControlVM message was processed but an error occurred.
*/
-static int
-handle_command(struct controlvm_message inmsg, u64 channel_addr)
+static int handle_command(struct controlvm_message inmsg, u64 channel_addr)
{
struct controlvm_message_packet *cmd = &inmsg.cmd;
u64 parm_addr;
u32 parm_bytes;
struct parser_context *parser_ctx = NULL;
- bool local_addr;
struct controlvm_message ackmsg;
int err = 0;
/* create parsing context if necessary */
- local_addr = (inmsg.hdr.flags.test_message == 1);
parm_addr = channel_addr + inmsg.hdr.payload_vm_offset;
parm_bytes = inmsg.hdr.payload_bytes;
@@ -1601,25 +1514,19 @@ handle_command(struct controlvm_message inmsg, u64 channel_addr)
* within our OS-controlled memory. We need to know that, because it
* makes a difference in how we compute the virtual address.
*/
- if (parm_addr && parm_bytes) {
+ if (parm_bytes) {
bool retry = false;
- parser_ctx =
- parser_init_byte_stream(parm_addr, parm_bytes,
- local_addr, &retry);
+ parser_ctx = parser_init_stream(parm_addr, parm_bytes, &retry);
if (!parser_ctx && retry)
return -EAGAIN;
}
+ controlvm_init_response(&ackmsg, &inmsg.hdr, CONTROLVM_RESP_SUCCESS);
+ err = visorchannel_signalinsert(chipset_dev->controlvm_channel,
+ CONTROLVM_QUEUE_ACK, &ackmsg);
+ if (err)
+ return err;
- if (!local_addr) {
- controlvm_init_response(&ackmsg, &inmsg.hdr,
- CONTROLVM_RESP_SUCCESS);
- err = visorchannel_signalinsert(chipset_dev->controlvm_channel,
- CONTROLVM_QUEUE_ACK,
- &ackmsg);
- if (err)
- return err;
- }
switch (inmsg.hdr.id) {
case CONTROLVM_CHIPSET_INIT:
err = chipset_init(&inmsg);
@@ -1641,8 +1548,8 @@ handle_command(struct controlvm_message inmsg, u64 channel_addr)
err = parahotplug_process_message(&inmsg);
} else {
/*
- * save the hdr and cmd structures for later use
- * when sending back the response to Command
+ * save the hdr and cmd structures for later use when
+ * sending back the response to Command
*/
err = visorbus_device_changestate(&inmsg);
break;
@@ -1689,12 +1596,9 @@ handle_command(struct controlvm_message inmsg, u64 channel_addr)
*
* Return: 0 if valid message was retrieved or -error
*/
-static int
-read_controlvm_event(struct controlvm_message *msg)
+static int read_controlvm_event(struct controlvm_message *msg)
{
- int err;
-
- err = visorchannel_signalremove(chipset_dev->controlvm_channel,
+ int err = visorchannel_signalremove(chipset_dev->controlvm_channel,
CONTROLVM_QUEUE_EVENT, msg);
if (err)
return err;
@@ -1710,8 +1614,7 @@ read_controlvm_event(struct controlvm_message *msg)
* parahotplug_process_list() - remove any request from the list that's been on
* there too long and respond with an error
*/
-static void
-parahotplug_process_list(void)
+static void parahotplug_process_list(void)
{
struct list_head *pos;
struct list_head *tmp;
@@ -1737,8 +1640,7 @@ parahotplug_process_list(void)
spin_unlock(&parahotplug_request_list_lock);
}
-static void
-controlvm_periodic_work(struct work_struct *work)
+static void controlvm_periodic_work(struct work_struct *work)
{
struct controlvm_message inmsg;
int count = 0;
@@ -1756,9 +1658,8 @@ controlvm_periodic_work(struct work_struct *work)
if (chipset_dev->controlvm_pending_msg_valid) {
/*
- * we throttled processing of a prior
- * msg, so try to process it again
- * rather than reading a new one
+ * we throttled processing of a prior msg, so try to process
+ * it again rather than reading a new one
*/
inmsg = chipset_dev->controlvm_pending_msg;
chipset_dev->controlvm_pending_msg_valid = false;
@@ -1793,9 +1694,8 @@ schedule_out:
if (time_after(jiffies, chipset_dev->most_recent_message_jiffies +
(HZ * MIN_IDLE_SECONDS))) {
/*
- * it's been longer than MIN_IDLE_SECONDS since we
- * processed our last controlvm message; slow down the
- * polling
+ * it's been longer than MIN_IDLE_SECONDS since we processed
+ * our last controlvm message; slow down the polling
*/
if (chipset_dev->poll_jiffies !=
POLLJIFFIES_CONTROLVMCHANNEL_SLOW)
@@ -1812,41 +1712,36 @@ schedule_out:
chipset_dev->poll_jiffies);
}
-static int
-visorchipset_init(struct acpi_device *acpi_device)
+static int visorchipset_init(struct acpi_device *acpi_device)
{
int err = -ENODEV;
- u64 addr;
- uuid_le uuid = VISOR_CONTROLVM_CHANNEL_UUID;
struct visorchannel *controlvm_channel;
chipset_dev = kzalloc(sizeof(*chipset_dev), GFP_KERNEL);
if (!chipset_dev)
goto error;
- addr = controlvm_get_channel_address();
- if (!addr)
- goto error;
+ err = controlvm_channel_create(chipset_dev);
+ if (err)
+ goto error_free_chipset_dev;
acpi_device->driver_data = chipset_dev;
-
chipset_dev->acpi_device = acpi_device;
chipset_dev->poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_FAST;
- controlvm_channel = visorchannel_create_with_lock(addr,
- 0, GFP_KERNEL, uuid);
-
- if (!controlvm_channel)
- goto error_free_chipset_dev;
-
- chipset_dev->controlvm_channel = controlvm_channel;
err = sysfs_create_groups(&chipset_dev->acpi_device->dev.kobj,
visorchipset_dev_groups);
if (err < 0)
goto error_destroy_channel;
- if (!VISOR_CONTROLVM_CHANNEL_OK_CLIENT(
- visorchannel_get_header(controlvm_channel)))
+ controlvm_channel = chipset_dev->controlvm_channel;
+ if (!visor_check_channel(visorchannel_get_header(controlvm_channel),
+ &chipset_dev->acpi_device->dev,
+ &visor_controlvm_channel_guid,
+ "controlvm",
+ sizeof(struct visor_controlvm_channel),
+ VISOR_CONTROLVM_CHANNEL_VERSIONID,
+ VISOR_CHANNEL_SIGNATURE))
goto error_delete_groups;
/* if booting in a crash kernel */
@@ -1886,8 +1781,7 @@ error:
return err;
}
-static int
-visorchipset_exit(struct acpi_device *acpi_device)
+static int visorchipset_exit(struct acpi_device *acpi_device)
{
visorbus_exit();
cancel_delayed_work_sync(&chipset_dev->periodic_controlvm_work);
@@ -1928,9 +1822,8 @@ static __init int visorutil_spar_detect(void)
return (ebx == UNISYS_VISOR_ID_EBX) &&
(ecx == UNISYS_VISOR_ID_ECX) &&
(edx == UNISYS_VISOR_ID_EDX);
- } else {
- return 0;
}
+ return 0;
}
static int init_unisys(void)
diff --git a/drivers/staging/unisys/visorbus/vmcallinterface.h b/drivers/staging/unisys/visorbus/vmcallinterface.h
deleted file mode 100644
index cc70e1b..0000000
--- a/drivers/staging/unisys/visorbus/vmcallinterface.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Copyright (C) 2010 - 2015 UNISYS CORPORATION
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- */
-
-#ifndef __VMCALLINTERFACE_H__
-#define __VMCALLINTERFACE_H__
-
-enum vmcall_monitor_interface_method_tuple { /* VMCALL identification tuples */
- /* Note: when a new VMCALL is added:
- * - the 1st 2 hex digits correspond to one of the
- * VMCALL_MONITOR_INTERFACE types and
- * - the next 2 hex digits are the nth relative instance of within a
- * type
- * E.G. for VMCALL_VIRTPART_RECYCLE_PART,
- * - the 0x02 identifies it as a VMCALL_VIRTPART type and
- * - the 0x01 identifies it as the 1st instance of a VMCALL_VIRTPART
- * type of VMCALL
- */
- /* used by all Guests, not just IO */
- VMCALL_CONTROLVM_ADDR = 0x0501,
-};
-
-enum vmcall_result {
- VMCALL_RESULT_SUCCESS = 0,
- VMCALL_RESULT_INVALID_PARAM = 1,
- VMCALL_RESULT_DATA_UNAVAILABLE = 2,
- VMCALL_RESULT_FAILURE_UNAVAILABLE = 3,
- VMCALL_RESULT_DEVICE_ERROR = 4,
- VMCALL_RESULT_DEVICE_NOT_READY = 5
-};
-
-/* Structures for IO VMCALLs */
-/* Parameters to VMCALL_CONTROLVM_ADDR interface */
-struct vmcall_io_controlvm_addr_params {
- /* The Guest-relative physical address of the ControlVm channel. */
- /* This VMCall fills this in with the appropriate address. */
- u64 address; /* contents provided by this VMCALL (OUT) */
- /* the size of the ControlVm channel in bytes This VMCall fills this */
- /* in with the appropriate address. */
- u32 channel_bytes; /* contents provided by this VMCALL (OUT) */
- u8 unused[4]; /* Unused Bytes in the 64-Bit Aligned Struct */
-} __packed;
-
-#endif /* __VMCALLINTERFACE_H__ */
diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c b/drivers/staging/unisys/visorhba/visorhba_main.c
index a6e7a6b..8567e44 100644
--- a/drivers/staging/unisys/visorhba/visorhba_main.c
+++ b/drivers/staging/unisys/visorhba/visorhba_main.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2012 - 2015 UNISYS CORPORATION
+/*
+ * Copyright (c) 2012 - 2015 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -14,7 +15,6 @@
*/
#include <linux/debugfs.h>
-#include <linux/skbuff.h>
#include <linux/kthread.h>
#include <linux/idr.h>
#include <linux/seq_file.h>
@@ -39,16 +39,17 @@ static struct visor_channeltype_descriptor visorhba_channel_types[] = {
/* Note that the only channel type we expect to be reported by the
* bus driver is the VISOR_VHBA channel.
*/
- { VISOR_VHBA_CHANNEL_UUID, "sparvhba" },
- { NULL_UUID_LE, NULL }
+ { VISOR_VHBA_CHANNEL_GUID, "sparvhba" },
+ {}
};
MODULE_DEVICE_TABLE(visorbus, visorhba_channel_types);
-MODULE_ALIAS("visorbus:" VISOR_VHBA_CHANNEL_UUID_STR);
+MODULE_ALIAS("visorbus:" VISOR_VHBA_CHANNEL_GUID_STR);
struct visordisk_info {
u32 valid;
- u32 channel, id, lun; /* Disk Path */
+ /* Disk Path */
+ u32 channel, id, lun;
atomic_t ios_threshold;
atomic_t error_count;
struct visordisk_info *next;
@@ -56,8 +57,10 @@ struct visordisk_info {
struct scsipending {
struct uiscmdrsp cmdrsp;
- void *sent; /* The Data being tracked */
- char cmdtype; /* Type of pointer that is being stored */
+ /* The Data being tracked */
+ void *sent;
+ /* Type of pointer that is being stored */
+ char cmdtype;
};
/* Each scsi_host has a host_data area that contains this struct. */
@@ -71,7 +74,8 @@ struct visorhba_devdata {
struct scsipending pending[MAX_PENDING_REQUESTS];
/* Start search for next pending free slot here */
unsigned int nextinsert;
- spinlock_t privlock; /* lock to protect data in devdata */
+ /* lock to protect data in devdata */
+ spinlock_t privlock;
bool serverdown;
bool serverchangingstate;
unsigned long long acquire_failed_cnt;
@@ -108,18 +112,18 @@ struct visorhba_devices_open {
(iter->lun == match->lun))
/*
- * visor_thread_start - starts a thread for the device
- * @threadfn: Function the thread starts
- * @thrcontext: Context to pass to the thread, i.e. devdata
- * @name: string describing name of thread
+ * visor_thread_start - Starts a thread for the device
+ * @threadfn: Function the thread starts
+ * @thrcontext: Context to pass to the thread, i.e. devdata
+ * @name: String describing name of thread
*
- * Starts a thread for the device.
+ * Starts a thread for the device.
*
- * Return the task_struct * denoting the thread on success,
- * or NULL on failure
+ * Return: The task_struct * denoting the thread on success,
+ * or NULL on failure
*/
-static struct task_struct *visor_thread_start
-(int (*threadfn)(void *), void *thrcontext, char *name)
+static struct task_struct *visor_thread_start(int (*threadfn)(void *),
+ void *thrcontext, char *name)
{
struct task_struct *task;
@@ -132,27 +136,27 @@ static struct task_struct *visor_thread_start
}
/*
- * visor_thread_stop - stops the thread if it is running
+ * visor_thread_stop - Stops the thread if it is running
+ * @task: Description of process to stop
*/
static void visor_thread_stop(struct task_struct *task)
{
- if (!task)
- return; /* no thread running */
kthread_stop(task);
}
/*
- * add_scsipending_entry - save off io command that is pending in
- * Service Partition
- * @devdata: Pointer to devdata
- * @cmdtype: Specifies the type of command pending
- * @new: The command to be saved
+ * add_scsipending_entry - Save off io command that is pending in
+ * Service Partition
+ * @devdata: Pointer to devdata
+ * @cmdtype: Specifies the type of command pending
+ * @new: The command to be saved
*
- * Saves off the io command that is being handled by the Service
- * Partition so that it can be handled when it completes. If new is
- * NULL it is assumed the entry refers only to the cmdrsp.
- * Returns insert_location where entry was added,
- * -EBUSY if it can't
+ * Saves off the io command that is being handled by the Service
+ * Partition so that it can be handled when it completes. If new is
+ * NULL it is assumed the entry refers only to the cmdrsp.
+ *
+ * Return: Insert_location where entry was added on success,
+ * -EBUSY if it can't
*/
static int add_scsipending_entry(struct visorhba_devdata *devdata,
char cmdtype, void *new)
@@ -176,7 +180,8 @@ static int add_scsipending_entry(struct visorhba_devdata *devdata,
entry->cmdtype = cmdtype;
if (new)
entry->sent = new;
- else /* wants to send cmdrsp */
+ /* wants to send cmdrsp */
+ else
entry->sent = &entry->cmdrsp;
devdata->nextinsert = (insert_location + 1) % MAX_PENDING_REQUESTS;
spin_unlock_irqrestore(&devdata->privlock, flags);
@@ -185,15 +190,15 @@ static int add_scsipending_entry(struct visorhba_devdata *devdata,
}
/*
- * del_scsipending_ent - removes an entry from the pending array
- * @devdata: Device holding the pending array
- * @del: Entry to remove
+ * del_scsipending_ent - Removes an entry from the pending array
+ * @devdata: Device holding the pending array
+ * @del: Entry to remove
*
- * Removes the entry pointed at by del and returns it.
- * Returns the scsipending entry pointed at
+ * Removes the entry pointed at by del and returns it.
+ *
+ * Return: The scsipending entry pointed to on success, NULL on failure
*/
-static void *del_scsipending_ent(struct visorhba_devdata *devdata,
- int del)
+static void *del_scsipending_ent(struct visorhba_devdata *devdata, int del)
{
unsigned long flags;
void *sent;
@@ -203,7 +208,6 @@ static void *del_scsipending_ent(struct visorhba_devdata *devdata,
spin_lock_irqsave(&devdata->privlock, flags);
sent = devdata->pending[del].sent;
-
devdata->pending[del].cmdtype = 0;
devdata->pending[del].sent = NULL;
spin_unlock_irqrestore(&devdata->privlock, flags);
@@ -212,13 +216,14 @@ static void *del_scsipending_ent(struct visorhba_devdata *devdata,
}
/*
- * get_scsipending_cmdrsp - return the cmdrsp stored in a pending entry
- * @ddata: Device holding the pending array
- * @ent: Entry that stores the cmdrsp
+ * get_scsipending_cmdrsp - Return the cmdrsp stored in a pending entry
+ * @ddata: Device holding the pending array
+ * @ent: Entry that stores the cmdrsp
*
- * Each scsipending entry has a cmdrsp in it. The cmdrsp is only valid
- * if the "sent" field is not NULL
- * Returns a pointer to the cmdrsp.
+ * Each scsipending entry has a cmdrsp in it. The cmdrsp is only valid
+ * if the "sent" field is not NULL.
+ *
+ * Return: A pointer to the cmdrsp, NULL on failure
*/
static struct uiscmdrsp *get_scsipending_cmdrsp(struct visorhba_devdata *ddata,
int ent)
@@ -230,13 +235,15 @@ static struct uiscmdrsp *get_scsipending_cmdrsp(struct visorhba_devdata *ddata,
}
/*
- * simple_idr_get - associate a provided pointer with an int value
- * 1 <= value <= INT_MAX, and return this int value;
- * the pointer value can be obtained later by passing
- * this int value to idr_find()
- * @idrtable: the data object maintaining the pointer<-->int mappings
- * @p: the pointer value to be remembered
- * @lock: a spinlock used when exclusive access to idrtable is needed
+ * simple_idr_get - Associate a provided pointer with an int value
+ * 1 <= value <= INT_MAX, and return this int value;
+ * the pointer value can be obtained later by passing
+ * this int value to idr_find()
+ * @idrtable: The data object maintaining the pointer<-->int mappings
+ * @p: The pointer value to be remembered
+ * @lock: A spinlock used when exclusive access to idrtable is needed
+ *
+ * Return: The id number mapped to pointer 'p', 0 on failure
*/
static unsigned int simple_idr_get(struct idr *idrtable, void *p,
spinlock_t *lock)
@@ -249,16 +256,23 @@ static unsigned int simple_idr_get(struct idr *idrtable, void *p,
id = idr_alloc(idrtable, p, 1, INT_MAX, GFP_NOWAIT);
spin_unlock_irqrestore(lock, flags);
idr_preload_end();
+ /* failure */
if (id < 0)
- return 0; /* failure */
- return (unsigned int)(id); /* idr_alloc() guarantees > 0 */
+ return 0;
+ /* idr_alloc() guarantees > 0 */
+ return (unsigned int)(id);
}
/*
- * setup_scsitaskmgmt_handles - stash the necessary handles so that the
- * completion processing logic for a taskmgmt
- * cmd will be able to find who to wake up
- * and where to stash the result
+ * setup_scsitaskmgmt_handles - Stash the necessary handles so that the
+ * completion processing logic for a taskmgmt
+ * cmd will be able to find who to wake up
+ * and where to stash the result
+ * @idrtable: The data object maintaining the pointer<-->int mappings
+ * @lock: A spinlock used when exclusive access to idrtable is needed
+ * @cmdrsp: Response from the IOVM
+ * @event: The event handle to associate with an id
+ * @result: The location to place the result of the event handle into
*/
static void setup_scsitaskmgmt_handles(struct idr *idrtable, spinlock_t *lock,
struct uiscmdrsp *cmdrsp,
@@ -273,8 +287,10 @@ static void setup_scsitaskmgmt_handles(struct idr *idrtable, spinlock_t *lock,
}
/*
- * cleanup_scsitaskmgmt_handles - forget handles created by
- * setup_scsitaskmgmt_handles()
+ * cleanup_scsitaskmgmt_handles - Forget handles created by
+ * setup_scsitaskmgmt_handles()
+ * @idrtable: The data object maintaining the pointer<-->int mappings
+ * @cmdrsp: Response from the IOVM
*/
static void cleanup_scsitaskmgmt_handles(struct idr *idrtable,
struct uiscmdrsp *cmdrsp)
@@ -286,14 +302,15 @@ static void cleanup_scsitaskmgmt_handles(struct idr *idrtable,
}
/*
- * forward_taskmgmt_command - send taskmegmt command to the Service
- * Partition
- * @tasktype: Type of taskmgmt command
- * @scsidev: Scsidev that issued command
+ * forward_taskmgmt_command - Send taskmegmt command to the Service
+ * Partition
+ * @tasktype: Type of taskmgmt command
+ * @scsidev: Scsidev that issued command
*
- * Create a cmdrsp packet and send it to the Serivce Partition
- * that will service this request.
- * Returns whether the command was queued successfully or not.
+ * Create a cmdrsp packet and send it to the Serivce Partition
+ * that will service this request.
+ *
+ * Return: Int representing whether command was queued successfully or not
*/
static int forward_taskmgmt_command(enum task_mgmt_types tasktype,
struct scsi_cmnd *scsicmd)
@@ -365,11 +382,10 @@ err_del_scsipending_ent:
}
/*
- * visorhba_abort_handler - Send TASK_MGMT_ABORT_TASK
- * @scsicmd: The scsicmd that needs aborted
- *
- * Returns SUCCESS if inserted, failure otherwise
+ * visorhba_abort_handler - Send TASK_MGMT_ABORT_TASK
+ * @scsicmd: The scsicmd that needs aborted
*
+ * Return: SUCCESS if inserted, FAILED otherwise
*/
static int visorhba_abort_handler(struct scsi_cmnd *scsicmd)
{
@@ -390,10 +406,10 @@ static int visorhba_abort_handler(struct scsi_cmnd *scsicmd)
}
/*
- * visorhba_device_reset_handler - Send TASK_MGMT_LUN_RESET
- * @scsicmd: The scsicmd that needs aborted
+ * visorhba_device_reset_handler - Send TASK_MGMT_LUN_RESET
+ * @scsicmd: The scsicmd that needs aborted
*
- * Returns SUCCESS if inserted, failure otherwise
+ * Return: SUCCESS if inserted, FAILED otherwise
*/
static int visorhba_device_reset_handler(struct scsi_cmnd *scsicmd)
{
@@ -414,11 +430,11 @@ static int visorhba_device_reset_handler(struct scsi_cmnd *scsicmd)
}
/*
- * visorhba_bus_reset_handler - Send TASK_MGMT_TARGET_RESET for each
- * target on the bus
- * @scsicmd: The scsicmd that needs aborted
+ * visorhba_bus_reset_handler - Send TASK_MGMT_TARGET_RESET for each
+ * target on the bus
+ * @scsicmd: The scsicmd that needs aborted
*
- * Returns SUCCESS
+ * Return: SUCCESS if inserted, FAILED otherwise
*/
static int visorhba_bus_reset_handler(struct scsi_cmnd *scsicmd)
{
@@ -438,24 +454,22 @@ static int visorhba_bus_reset_handler(struct scsi_cmnd *scsicmd)
}
/*
- * visorhba_host_reset_handler - Not supported
- * @scsicmd: The scsicmd that needs aborted
+ * visorhba_host_reset_handler - Not supported
+ * @scsicmd: The scsicmd that needs to be aborted
*
- * Not supported, return SUCCESS
- * Returns SUCCESS
+ * Return: Not supported, return SUCCESS
*/
-static int
-visorhba_host_reset_handler(struct scsi_cmnd *scsicmd)
+static int visorhba_host_reset_handler(struct scsi_cmnd *scsicmd)
{
/* issue TASK_MGMT_TARGET_RESET for each target on each bus for host */
return SUCCESS;
}
/*
- * visorhba_get_info
- * @shp: Scsi host that is requesting information
+ * visorhba_get_info - Get information about SCSI device
+ * @shp: Scsi host that is requesting information
*
- * Returns string with info
+ * Return: String with visorhba information
*/
static const char *visorhba_get_info(struct Scsi_Host *shp)
{
@@ -464,19 +478,42 @@ static const char *visorhba_get_info(struct Scsi_Host *shp)
}
/*
- * visorhba_queue_command_lck -- queues command to the Service Partition
- * @scsicmd: Command to be queued
- * @vsiorhba_cmnd_done: Done command to call when scsicmd is returned
+ * dma_data_dir_linux_to_spar - convert dma_data_direction value to
+ * Unisys-specific equivalent
+ * @d: dma direction value to convert
+ *
+ * Returns the Unisys-specific dma direction value corresponding to @d
+ */
+static u32 dma_data_dir_linux_to_spar(enum dma_data_direction d)
+{
+ switch (d) {
+ case DMA_BIDIRECTIONAL:
+ return UIS_DMA_BIDIRECTIONAL;
+ case DMA_TO_DEVICE:
+ return UIS_DMA_TO_DEVICE;
+ case DMA_FROM_DEVICE:
+ return UIS_DMA_FROM_DEVICE;
+ case DMA_NONE:
+ return UIS_DMA_NONE;
+ default:
+ return UIS_DMA_NONE;
+ }
+}
+
+/*
+ * visorhba_queue_command_lck - Queues command to the Service Partition
+ * @scsicmd: Command to be queued
+ * @vsiorhba_cmnd_done: Done command to call when scsicmd is returned
*
- * Queues to scsicmd to the ServicePartition after converting it to a
- * uiscmdrsp structure.
+ * Queues to scsicmd to the ServicePartition after converting it to a
+ * uiscmdrsp structure.
*
- * Returns success if queued to the Service Partition, otherwise
- * failure.
+ * Return: 0 if successfully queued to the Service Partition, otherwise
+ * error code
*/
-static int
-visorhba_queue_command_lck(struct scsi_cmnd *scsicmd,
- void (*visorhba_cmnd_done)(struct scsi_cmnd *))
+static int visorhba_queue_command_lck(struct scsi_cmnd *scsicmd,
+ void (*visorhba_cmnd_done)
+ (struct scsi_cmnd *))
{
struct uiscmdrsp *cmdrsp;
struct scsi_device *scsidev = scsicmd->device;
@@ -494,12 +531,10 @@ visorhba_queue_command_lck(struct scsi_cmnd *scsicmd,
insert_location = add_scsipending_entry(devdata, CMD_SCSI_TYPE,
(void *)scsicmd);
-
if (insert_location < 0)
return SCSI_MLQUEUE_DEVICE_BUSY;
cmdrsp = get_scsipending_cmdrsp(devdata, insert_location);
-
cmdrsp->cmdtype = CMD_SCSI_TYPE;
/* save the pending insertion location. Deletion from pending
* will return the scsicmd pointer for completion
@@ -513,9 +548,9 @@ visorhba_queue_command_lck(struct scsi_cmnd *scsicmd,
cmdrsp->scsi.vdest.id = scsidev->id;
cmdrsp->scsi.vdest.lun = scsidev->lun;
/* save datadir */
- cmdrsp->scsi.data_dir = scsicmd->sc_data_direction;
+ cmdrsp->scsi.data_dir =
+ dma_data_dir_linux_to_spar(scsicmd->sc_data_direction);
memcpy(cmdrsp->scsi.cmnd, cdb, MAX_CMND_SIZE);
-
cmdrsp->scsi.bufflen = scsi_bufflen(scsicmd);
/* keep track of the max buffer length so far. */
@@ -555,13 +590,13 @@ static DEF_SCSI_QCMD(visorhba_queue_command)
#endif
/*
- * visorhba_slave_alloc - called when new disk is discovered
- * @scsidev: New disk
+ * visorhba_slave_alloc - Called when new disk is discovered
+ * @scsidev: New disk
*
- * Create a new visordisk_info structure and add it to our
- * list of vdisks.
+ * Create a new visordisk_info structure and add it to our
+ * list of vdisks.
*
- * Returns success when created, otherwise error.
+ * Return: 0 on success, -ENOMEM on failure.
*/
static int visorhba_slave_alloc(struct scsi_device *scsidev)
{
@@ -573,12 +608,14 @@ static int visorhba_slave_alloc(struct scsi_device *scsidev)
struct visorhba_devdata *devdata;
struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host;
+ /* even though we errored, treat as success */
devdata = (struct visorhba_devdata *)scsihost->hostdata;
if (!devdata)
- return 0; /* even though we errored, treat as success */
+ return 0;
+ /* already allocated return success */
for_each_vdisk_match(vdisk, devdata, scsidev)
- return 0; /* already allocated return success */
+ return 0;
tmpvdisk = kzalloc(sizeof(*tmpvdisk), GFP_ATOMIC);
if (!tmpvdisk)
@@ -592,11 +629,8 @@ static int visorhba_slave_alloc(struct scsi_device *scsidev)
}
/*
- * visorhba_slave_destroy - disk is going away
- * @scsidev: scsi device going away
- *
- * Disk is going away, clean up resources.
- * Returns void.
+ * visorhba_slave_destroy - Disk is going away, clean up resources.
+ * @scsidev: Scsi device to destroy
*/
static void visorhba_slave_destroy(struct scsi_device *scsidev)
{
@@ -635,10 +669,13 @@ static struct scsi_host_template visorhba_driver_template = {
};
/*
- * info_debugfs_show - debugfs interface to dump visorhba states
+ * info_debugfs_show - Debugfs interface to dump visorhba states
+ * @seq: The sequence file to write information to
+ * @v: Unused, but needed for use with seq file single_open invocation
+ *
+ * Presents a file in the debugfs tree named: /visorhba/vbus<x>:dev<y>/info.
*
- * This presents a file in the debugfs tree named:
- * /visorhba/vbus<x>:dev<y>/info
+ * Return: SUCCESS
*/
static int info_debugfs_show(struct seq_file *seq, void *v)
{
@@ -679,12 +716,13 @@ static const struct file_operations info_debugfs_fops = {
};
/*
- * complete_taskmgmt_command - complete task management
- * @cmdrsp: Response from the IOVM
+ * complete_taskmgmt_command - Complete task management
+ * @idrtable: The data object maintaining the pointer<-->int mappings
+ * @cmdrsp: Response from the IOVM
+ * @result: The result of the task management command
*
- * Service Partition returned the result of the task management
- * command. Wake up anyone waiting for it.
- * Returns void
+ * Service Partition returned the result of the task management
+ * command. Wake up anyone waiting for it.
*/
static void complete_taskmgmt_command(struct idr *idrtable,
struct uiscmdrsp *cmdrsp, int result)
@@ -693,7 +731,6 @@ static void complete_taskmgmt_command(struct idr *idrtable,
idr_find(idrtable, cmdrsp->scsitaskmgmt.notify_handle);
int *scsi_result_ptr =
idr_find(idrtable, cmdrsp->scsitaskmgmt.notifyresult_handle);
-
if (unlikely(!(wq && scsi_result_ptr))) {
pr_err("visorhba: no completion context; cmd will time out\n");
return;
@@ -708,13 +745,12 @@ static void complete_taskmgmt_command(struct idr *idrtable,
}
/*
- * visorhba_serverdown_complete - Called when we are done cleaning up
- * from serverdown
- * @work: work structure for this serverdown request
+ * visorhba_serverdown_complete - Called when we are done cleaning up
+ * from serverdown
+ * @devdata: Visorhba instance on which to complete serverdown
*
- * Called when we are done cleanning up from serverdown, stop processing
- * queue, fail pending IOs.
- * Returns void when finished cleaning up
+ * Called when we are done cleanning up from serverdown, stop processing
+ * queue, fail pending IOs.
*/
static void visorhba_serverdown_complete(struct visorhba_devdata *devdata)
{
@@ -758,12 +794,13 @@ static void visorhba_serverdown_complete(struct visorhba_devdata *devdata)
}
/*
- * visorhba_serverdown - Got notified that the IOVM is down
- * @devdata: visorhba that is being serviced by downed IOVM.
+ * visorhba_serverdown - Got notified that the IOVM is down
+ * @devdata: Visorhba that is being serviced by downed IOVM
+ *
+ * Something happened to the IOVM, return immediately and
+ * schedule cleanup work.
*
- * Something happened to the IOVM, return immediately and
- * schedule work cleanup work.
- * Return SUCCESS or EINVAL
+ * Return: 0 on success, -EINVAL on failure
*/
static int visorhba_serverdown(struct visorhba_devdata *devdata)
{
@@ -777,15 +814,14 @@ static int visorhba_serverdown(struct visorhba_devdata *devdata)
}
/*
- * do_scsi_linuxstat - scsi command returned linuxstat
- * @cmdrsp: response from IOVM
- * @scsicmd: Command issued.
+ * do_scsi_linuxstat - Scsi command returned linuxstat
+ * @cmdrsp: Response from IOVM
+ * @scsicmd: Command issued
*
- * Don't log errors for disk-not-present inquiries
- * Returns void
+ * Don't log errors for disk-not-present inquiries.
*/
-static void
-do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
+static void do_scsi_linuxstat(struct uiscmdrsp *cmdrsp,
+ struct scsi_cmnd *scsicmd)
{
struct visorhba_devdata *devdata;
struct visordisk_info *vdisk;
@@ -809,10 +845,10 @@ do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
}
}
-static int set_no_disk_inquiry_result(unsigned char *buf,
- size_t len, bool is_lun0)
+static int set_no_disk_inquiry_result(unsigned char *buf, size_t len,
+ bool is_lun0)
{
- if (!buf || len < NO_DISK_INQUIRY_RESULT_LEN)
+ if (len < NO_DISK_INQUIRY_RESULT_LEN)
return -EINVAL;
memset(buf, 0, NO_DISK_INQUIRY_RESULT_LEN);
buf[2] = SCSI_SPC2_VER;
@@ -828,15 +864,14 @@ static int set_no_disk_inquiry_result(unsigned char *buf,
}
/*
- * do_scsi_nolinuxstat - scsi command didn't have linuxstat
- * @cmdrsp: response from IOVM
- * @scsicmd: Command issued.
+ * do_scsi_nolinuxstat - Scsi command didn't have linuxstat
+ * @cmdrsp: Response from IOVM
+ * @scsicmd: Command issued
*
- * Handle response when no linuxstat was returned
- * Returns void
+ * Handle response when no linuxstat was returned.
*/
-static void
-do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
+static void do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp,
+ struct scsi_cmnd *scsicmd)
{
struct scsi_device *scsidev;
unsigned char *buf;
@@ -895,16 +930,15 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
}
/*
- * complete_scsi_command - complete a scsi command
- * @uiscmdrsp: Response from Service Partition
- * @scsicmd: The scsi command
+ * complete_scsi_command - Complete a scsi command
+ * @uiscmdrsp: Response from Service Partition
+ * @scsicmd: The scsi command
*
- * Response returned by the Service Partition, finish it and send
- * completion to the scsi midlayer.
- * Returns void.
+ * Response was returned by the Service Partition. Finish it and send
+ * completion to the scsi midlayer.
*/
-static void
-complete_scsi_command(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
+static void complete_scsi_command(struct uiscmdrsp *cmdrsp,
+ struct scsi_cmnd *scsicmd)
{
/* take what we need out of cmdrsp and complete the scsicmd */
scsicmd->result = cmdrsp->scsi.linuxstat;
@@ -917,24 +951,23 @@ complete_scsi_command(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
}
/*
- * drain_queue - pull responses out of iochannel
- * @cmdrsp: Response from the IOSP
- * @devdata: device that owns this iochannel
+ * drain_queue - Pull responses out of iochannel
+ * @cmdrsp: Response from the IOSP
+ * @devdata: Device that owns this iochannel
*
- * Pulls responses out of the iochannel and process the responses.
- * Restuns void
+ * Pulls responses out of the iochannel and process the responses.
*/
-static void
-drain_queue(struct uiscmdrsp *cmdrsp, struct visorhba_devdata *devdata)
+static void drain_queue(struct uiscmdrsp *cmdrsp,
+ struct visorhba_devdata *devdata)
{
struct scsi_cmnd *scsicmd;
while (1) {
+ /* queue empty */
if (visorchannel_signalremove(devdata->dev->visorchannel,
IOCHAN_FROM_IOPART,
cmdrsp))
- break; /* queue empty */
-
+ break;
if (cmdrsp->cmdtype == CMD_SCSI_TYPE) {
/* scsicmd location is returned by the
* deletion
@@ -959,12 +992,14 @@ drain_queue(struct uiscmdrsp *cmdrsp, struct visorhba_devdata *devdata)
}
/*
- * process_incoming_rsps - Process responses from IOSP
- * @v: void pointer to visorhba_devdata
+ * process_incoming_rsps - Process responses from IOSP
+ * @v: Void pointer to visorhba_devdata
*
- * Main function for the thread that processes the responses
- * from the IO Service Partition. When the queue is empty, wait
- * to check to see if it is full again.
+ * Main function for the thread that processes the responses
+ * from the IO Service Partition. When the queue is empty, wait
+ * to check to see if it is full again.
+ *
+ * Return: 0 on success, -ENOMEM on failure
*/
static int process_incoming_rsps(void *v)
{
@@ -991,14 +1026,15 @@ static int process_incoming_rsps(void *v)
}
/*
- * visorhba_pause - function to handle visorbus pause messages
- * @dev: device that is pausing.
- * @complete_func: function to call when finished
+ * visorhba_pause - Function to handle visorbus pause messages
+ * @dev: Device that is pausing
+ * @complete_func: Function to call when finished
+ *
+ * Something has happened to the IO Service Partition that is
+ * handling this device. Quiet this device and reset commands
+ * so that the Service Partition can be corrected.
*
- * Something has happened to the IO Service Partition that is
- * handling this device. Quiet this device and reset commands
- * so that the Service Partition can be corrected.
- * Returns SUCCESS
+ * Return: SUCCESS
*/
static int visorhba_pause(struct visor_device *dev,
visorbus_state_complete_func complete_func)
@@ -1011,13 +1047,14 @@ static int visorhba_pause(struct visor_device *dev,
}
/*
- * visorhba_resume - function called when the IO Service Partition is back
- * @dev: device that is pausing.
- * @complete_func: function to call when finished
+ * visorhba_resume - Function called when the IO Service Partition is back
+ * @dev: Device that is pausing
+ * @complete_func: Function to call when finished
*
- * Yay! The IO Service Partition is back, the channel has been wiped
- * so lets re-establish connection and start processing responses.
- * Returns 0 on success, error on failure.
+ * Yay! The IO Service Partition is back, the channel has been wiped
+ * so lets re-establish connection and start processing responses.
+ *
+ * Return: 0 on success, -EINVAL on failure
*/
static int visorhba_resume(struct visor_device *dev,
visorbus_state_complete_func complete_func)
@@ -1033,7 +1070,6 @@ static int visorhba_resume(struct visor_device *dev,
devdata->thread = visor_thread_start(process_incoming_rsps, devdata,
"vhba_incming");
-
devdata->serverdown = false;
devdata->serverchangingstate = false;
@@ -1041,11 +1077,12 @@ static int visorhba_resume(struct visor_device *dev,
}
/*
- * visorhba_probe - device has been discovered, do acquire
- * @dev: visor_device that was discovered
+ * visorhba_probe - Device has been discovered; do acquire
+ * @dev: visor_device that was discovered
*
- * A new HBA was discovered, do the initial connections of it.
- * Return 0 on success, otherwise error.
+ * A new HBA was discovered; do the initial connections of it.
+ *
+ * Return: 0 on success, otherwise error code
*/
static int visorhba_probe(struct visor_device *dev)
{
@@ -1139,11 +1176,10 @@ err_scsi_host_put:
}
/*
- * visorhba_remove - remove a visorhba device
- * @dev: Device to remove
+ * visorhba_remove - Remove a visorhba device
+ * @dev: Device to remove
*
- * Removes the visorhba device.
- * Returns void.
+ * Removes the visorhba device.
*/
static void visorhba_remove(struct visor_device *dev)
{
@@ -1181,10 +1217,12 @@ static struct visor_driver visorhba_driver = {
};
/*
- * visorhba_init - driver init routine
+ * visorhba_init - Driver init routine
+ *
+ * Initialize the visorhba driver and register it with visorbus
+ * to handle s-Par virtual host bus adapter.
*
- * Initialize the visorhba driver and register it with visorbus
- * to handle s-Par virtual host bus adapter.
+ * Return: 0 on success, error code otherwise
*/
static int visorhba_init(void)
{
@@ -1207,9 +1245,9 @@ cleanup_debugfs:
}
/*
- * visorhba_exit - driver exit routine
+ * visorhba_exit - Driver exit routine
*
- * Unregister driver from the bus and free up memory.
+ * Unregister driver from the bus and free up memory.
*/
static void visorhba_exit(void)
{
diff --git a/drivers/staging/unisys/visorinput/ultrainputreport.h b/drivers/staging/unisys/visorinput/ultrainputreport.h
index a4baea5..53975a0 100644
--- a/drivers/staging/unisys/visorinput/ultrainputreport.h
+++ b/drivers/staging/unisys/visorinput/ultrainputreport.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 2010 - 2015 UNISYS CORPORATION
+/*
+ * Copyright (C) 2010 - 2015 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
@@ -20,44 +21,35 @@
/* These defines identify mouse and keyboard activity which is specified by the
* firmware to the host using the cmsimpleinput protocol. @ingroup coretypes
*/
-#define INPUTACTION_XY_MOTION 1 /* only motion; arg1=x, arg2=y */
-#define INPUTACTION_MOUSE_BUTTON_DOWN 2 /* arg1: 1=left,2=center,3=right */
-#define INPUTACTION_MOUSE_BUTTON_UP 3 /* arg1: 1=left,2=center,3=right */
-#define INPUTACTION_MOUSE_BUTTON_CLICK 4 /* arg1: 1=left,2=center,3=right */
-#define INPUTACTION_MOUSE_BUTTON_DCLICK 5 /* arg1: 1=left,2=center,
- * 3=right
- */
-#define INPUTACTION_WHEEL_ROTATE_AWAY 6 /* arg1: wheel rotation away from
- * user
- */
-#define INPUTACTION_WHEEL_ROTATE_TOWARD 7 /* arg1: wheel rotation toward
- * user
- */
-#define INPUTACTION_KEY_DOWN 64 /* arg1: scancode, as follows:
- * If arg1 <= 0xff, it's a 1-byte
- * scancode and arg1 is that scancode.
- * If arg1 > 0xff, it's a 2-byte
- * scanecode, with the 1st byte in the
- * low 8 bits, and the 2nd byte in the
- * high 8 bits. E.g., the right ALT key
- * would appear as x'38e0'.
- */
-#define INPUTACTION_KEY_UP 65 /* arg1: scancode (in same format as
- * inputaction_keyDown)
- */
+ /* only motion; arg1=x, arg2=y */
+#define INPUTACTION_XY_MOTION 1
+/* arg1: 1=left,2=center,3=right */
+#define INPUTACTION_MOUSE_BUTTON_DOWN 2
+/* arg1: 1=left,2=center,3=right */
+#define INPUTACTION_MOUSE_BUTTON_UP 3
+/* arg1: 1=left,2=center,3=right */
+#define INPUTACTION_MOUSE_BUTTON_CLICK 4
+/* arg1: 1=left,2=center 3=right */
+#define INPUTACTION_MOUSE_BUTTON_DCLICK 5
+/* arg1: wheel rotation away from user */
+#define INPUTACTION_WHEEL_ROTATE_AWAY 6
+/* arg1: wheel rotation toward user */
+#define INPUTACTION_WHEEL_ROTATE_TOWARD 7
+/* arg1: scancode, as follows: If arg1 <= 0xff, it's a 1-byte scancode and arg1
+ * is that scancode. If arg1 > 0xff, it's a 2-byte scanecode, with the 1st
+ * byte in the low 8 bits, and the 2nd byte in the high 8 bits.
+ * E.g., the right ALT key would appear as x'38e0'.
+ */
+#define INPUTACTION_KEY_DOWN 64
+/* arg1: scancode (in same format as inputaction_keyDown) */
+#define INPUTACTION_KEY_UP 65
+/* arg1: scancode (in same format as inputaction_keyDown); MUST refer to one of
+ * the locking keys, like capslock, numlock, or scrolllock.
+ * arg2: 1 iff locking key should be in the LOCKED position (e.g., light is ON)
+ */
#define INPUTACTION_SET_LOCKING_KEY_STATE 66
- /* arg1: scancode (in same format
- * as inputaction_keyDown);
- * MUST refer to one of the
- * locking keys, like capslock,
- * numlock, or scrolllock
- * arg2: 1 iff locking key should be
- * in the LOCKED position
- * (e.g., light is ON)
- */
-#define INPUTACTION_KEY_DOWN_UP 67 /* arg1: scancode (in same format
- * as inputaction_keyDown)
- */
+/* arg1: scancode (in same format as inputaction_keyDown */
+#define INPUTACTION_KEY_DOWN_UP 67
struct visor_inputactivity {
u16 action;
diff --git a/drivers/staging/unisys/visorinput/visorinput.c b/drivers/staging/unisys/visorinput/visorinput.c
index 45bc340..9d8cbc5 100644
--- a/drivers/staging/unisys/visorinput/visorinput.c
+++ b/drivers/staging/unisys/visorinput/visorinput.c
@@ -1,5 +1,4 @@
-/* visorinput.c
- *
+/*
* Copyright (C) 2011 - 2015 UNISYS CORPORATION
* All rights reserved.
*
@@ -21,11 +20,8 @@
* standard way the Linux expects for input drivers.
*/
-#include <linux/buffer_head.h>
#include <linux/fb.h>
-#include <linux/fs.h>
#include <linux/input.h>
-#include <linux/uaccess.h>
#include <linux/kernel.h>
#include <linux/uuid.h>
@@ -33,16 +29,16 @@
#include "ultrainputreport.h"
/* Keyboard channel {c73416d0-b0b8-44af-b304-9d2ae99f1b3d} */
-#define VISOR_KEYBOARD_CHANNEL_UUID \
- UUID_LE(0xc73416d0, 0xb0b8, 0x44af, \
- 0xb3, 0x4, 0x9d, 0x2a, 0xe9, 0x9f, 0x1b, 0x3d)
-#define VISOR_KEYBOARD_CHANNEL_UUID_STR "c73416d0-b0b8-44af-b304-9d2ae99f1b3d"
+#define VISOR_KEYBOARD_CHANNEL_GUID \
+ GUID_INIT(0xc73416d0, 0xb0b8, 0x44af, \
+ 0xb3, 0x4, 0x9d, 0x2a, 0xe9, 0x9f, 0x1b, 0x3d)
+#define VISOR_KEYBOARD_CHANNEL_GUID_STR "c73416d0-b0b8-44af-b304-9d2ae99f1b3d"
/* Mouse channel {addf07d4-94a9-46e2-81c3-61abcdbdbd87} */
-#define VISOR_MOUSE_CHANNEL_UUID \
- UUID_LE(0xaddf07d4, 0x94a9, 0x46e2, \
- 0x81, 0xc3, 0x61, 0xab, 0xcd, 0xbd, 0xbd, 0x87)
-#define VISOR_MOUSE_CHANNEL_UUID_STR "addf07d4-94a9-46e2-81c3-61abcdbdbd87"
+#define VISOR_MOUSE_CHANNEL_GUID \
+ GUID_INIT(0xaddf07d4, 0x94a9, 0x46e2, \
+ 0x81, 0xc3, 0x61, 0xab, 0xcd, 0xbd, 0xbd, 0x87)
+#define VISOR_MOUSE_CHANNEL_GUID_STR "addf07d4-94a9-46e2-81c3-61abcdbdbd87"
#define PIXELS_ACROSS_DEFAULT 800
#define PIXELS_DOWN_DEFAULT 600
@@ -60,17 +56,19 @@ enum visorinput_device_type {
*/
struct visorinput_devdata {
struct visor_device *dev;
- struct mutex lock_visor_dev; /* lock for dev */
+ /* lock for dev */
+ struct mutex lock_visor_dev;
struct input_dev *visorinput_dev;
bool paused;
bool interrupts_enabled;
- unsigned int keycode_table_bytes; /* size of following array */
+ /* size of following array */
+ unsigned int keycode_table_bytes;
/* for keyboard devices: visorkbd_keycode[] + visorkbd_ext_keycode[] */
unsigned char keycode_table[0];
};
-static const uuid_le visor_keyboard_channel_uuid = VISOR_KEYBOARD_CHANNEL_UUID;
-static const uuid_le visor_mouse_channel_uuid = VISOR_MOUSE_CHANNEL_UUID;
+static const guid_t visor_keyboard_channel_guid = VISOR_KEYBOARD_CHANNEL_GUID;
+static const guid_t visor_mouse_channel_guid = VISOR_MOUSE_CHANNEL_GUID;
/*
* Borrowed from drivers/input/keyboard/atakbd.c
@@ -162,9 +160,8 @@ static const unsigned char visorkbd_keycode[KEYCODE_TABLE_BYTES] = {
[81] = KEY_KP3,
[82] = KEY_KP0,
[83] = KEY_KPDOT,
- [86] = KEY_102ND, /* enables UK backslash+pipe key,
- * and FR lessthan+greaterthan key
- */
+ /* enables UK backslash+pipe key and FR lessthan+greaterthan key */
+ [86] = KEY_102ND,
[87] = KEY_F11,
[88] = KEY_F12,
[90] = KEY_KPLEFTPAREN,
@@ -260,7 +257,6 @@ static void visorinput_close(struct input_dev *visorinput_dev)
* interrupts should be disabled so when we resume we will
* not re-enable them.
*/
-
mutex_lock(&devdata->lock_visor_dev);
devdata->interrupts_enabled = false;
if (devdata->paused)
@@ -276,15 +272,13 @@ out_unlock:
* we can use to deliver keyboard inputs to Linux. We of course do this when
* we see keyboard inputs coming in on a keyboard channel.
*/
-static struct input_dev *
-setup_client_keyboard(void *devdata, /* opaque on purpose */
- unsigned char *keycode_table)
+static struct input_dev *setup_client_keyboard(void *devdata,
+ unsigned char *keycode_table)
{
int i;
- struct input_dev *visorinput_dev;
+ struct input_dev *visorinput_dev = input_allocate_device();
- visorinput_dev = input_allocate_device();
if (!visorinput_dev)
return NULL;
@@ -302,7 +296,8 @@ setup_client_keyboard(void *devdata, /* opaque on purpose */
BIT_MASK(LED_SCROLLL) |
BIT_MASK(LED_NUML);
visorinput_dev->keycode = keycode_table;
- visorinput_dev->keycodesize = 1; /* sizeof(unsigned char) */
+ /* sizeof(unsigned char) */
+ visorinput_dev->keycodesize = 1;
visorinput_dev->keycodemax = KEYCODE_TABLE_BYTES;
for (i = 1; i < visorinput_dev->keycodemax; i++)
@@ -313,19 +308,18 @@ setup_client_keyboard(void *devdata, /* opaque on purpose */
visorinput_dev->open = visorinput_open;
visorinput_dev->close = visorinput_close;
- input_set_drvdata(visorinput_dev, devdata); /* pre input_register! */
+ /* pre input_register! */
+ input_set_drvdata(visorinput_dev, devdata);
return visorinput_dev;
}
-static struct input_dev *
-setup_client_mouse(void *devdata /* opaque on purpose */)
+static struct input_dev *setup_client_mouse(void *devdata)
{
- struct input_dev *visorinput_dev = NULL;
int xres, yres;
struct fb_info *fb0;
+ struct input_dev *visorinput_dev = input_allocate_device();
- visorinput_dev = input_allocate_device();
if (!visorinput_dev)
return NULL;
@@ -354,14 +348,16 @@ setup_client_mouse(void *devdata /* opaque on purpose */)
visorinput_dev->open = visorinput_open;
visorinput_dev->close = visorinput_close;
- input_set_drvdata(visorinput_dev, devdata); /* pre input_register! */
+ /* pre input_register! */
+ input_set_drvdata(visorinput_dev, devdata);
input_set_capability(visorinput_dev, EV_REL, REL_WHEEL);
return visorinput_dev;
}
-static struct visorinput_devdata *
-devdata_create(struct visor_device *dev, enum visorinput_device_type devtype)
+static struct visorinput_devdata *devdata_create(
+ struct visor_device *dev,
+ enum visorinput_device_type devtype)
{
struct visorinput_devdata *devdata = NULL;
unsigned int extra_bytes = 0;
@@ -446,16 +442,15 @@ err_kfree_devdata:
return NULL;
}
-static int
-visorinput_probe(struct visor_device *dev)
+static int visorinput_probe(struct visor_device *dev)
{
- uuid_le guid;
+ const guid_t *guid;
enum visorinput_device_type devtype;
- guid = visorchannel_get_uuid(dev->visorchannel);
- if (uuid_le_cmp(guid, visor_mouse_channel_uuid) == 0)
+ guid = visorchannel_get_guid(dev->visorchannel);
+ if (guid_equal(guid, &visor_mouse_channel_guid))
devtype = visorinput_mouse;
- else if (uuid_le_cmp(guid, visor_keyboard_channel_uuid) == 0)
+ else if (guid_equal(guid, &visor_keyboard_channel_guid))
devtype = visorinput_keyboard;
else
return -ENODEV;
@@ -465,15 +460,13 @@ visorinput_probe(struct visor_device *dev)
return 0;
}
-static void
-unregister_client_input(struct input_dev *visorinput_dev)
+static void unregister_client_input(struct input_dev *visorinput_dev)
{
if (visorinput_dev)
input_unregister_device(visorinput_dev);
}
-static void
-visorinput_remove(struct visor_device *dev)
+static void visorinput_remove(struct visor_device *dev)
{
struct visorinput_devdata *devdata = dev_get_drvdata(&dev->device);
@@ -499,9 +492,8 @@ visorinput_remove(struct visor_device *dev)
* Make it so the current locking state of the locking key indicated by
* <keycode> is as indicated by <desired_state> (1=locked, 0=unlocked).
*/
-static void
-handle_locking_key(struct input_dev *visorinput_dev,
- int keycode, int desired_state)
+static void handle_locking_key(struct input_dev *visorinput_dev, int keycode,
+ int desired_state)
{
int led;
@@ -533,17 +525,15 @@ handle_locking_key(struct input_dev *visorinput_dev,
* with 0xE0 in the low byte and the extended scancode value in the next
* higher byte.
*/
-static int
-scancode_to_keycode(int scancode)
+static int scancode_to_keycode(int scancode)
{
if (scancode > 0xff)
return visorkbd_ext_keycode[(scancode >> 8) & 0xff];
- return visorkbd_keycode[scancode];
+ return visorkbd_keycode[scancode];
}
-static int
-calc_button(int x)
+static int calc_button(int x)
{
switch (x) {
case 1:
@@ -562,15 +552,13 @@ calc_button(int x)
* client guest partition. It is called periodically so we can obtain inputs
* from the channel, and deliver them to the guest OS.
*/
-static void
-visorinput_channel_interrupt(struct visor_device *dev)
+static void visorinput_channel_interrupt(struct visor_device *dev)
{
struct visor_inputreport r;
int scancode, keycode;
struct input_dev *visorinput_dev;
int xmotion, ymotion, button;
int i;
-
struct visorinput_devdata *devdata = dev_get_drvdata(&dev->device);
if (!devdata)
@@ -626,7 +614,6 @@ visorinput_channel_interrupt(struct visor_device *dev)
if (button < 0)
break;
input_report_key(visorinput_dev, button, 1);
-
input_sync(visorinput_dev);
input_report_key(visorinput_dev, button, 0);
input_sync(visorinput_dev);
@@ -657,9 +644,8 @@ visorinput_channel_interrupt(struct visor_device *dev)
}
}
-static int
-visorinput_pause(struct visor_device *dev,
- visorbus_state_complete_func complete_func)
+static int visorinput_pause(struct visor_device *dev,
+ visorbus_state_complete_func complete_func)
{
int rc;
struct visorinput_devdata *devdata = dev_get_drvdata(&dev->device);
@@ -681,7 +667,6 @@ visorinput_pause(struct visor_device *dev,
* due to above, at this time no thread of execution will be
* in visorinput_channel_interrupt()
*/
-
devdata->paused = true;
complete_func(dev, 0);
rc = 0;
@@ -691,9 +676,8 @@ out:
return rc;
}
-static int
-visorinput_resume(struct visor_device *dev,
- visorbus_state_complete_func complete_func)
+static int visorinput_resume(struct visor_device *dev,
+ visorbus_state_complete_func complete_func)
{
int rc;
struct visorinput_devdata *devdata = dev_get_drvdata(&dev->device);
@@ -727,9 +711,9 @@ out:
/* GUIDS for all channel types supported by this driver. */
static struct visor_channeltype_descriptor visorinput_channel_types[] = {
- { VISOR_KEYBOARD_CHANNEL_UUID, "keyboard"},
- { VISOR_MOUSE_CHANNEL_UUID, "mouse"},
- { NULL_UUID_LE, NULL }
+ { VISOR_KEYBOARD_CHANNEL_GUID, "keyboard"},
+ { VISOR_MOUSE_CHANNEL_GUID, "mouse"},
+ {}
};
static struct visor_driver visorinput_driver = {
@@ -743,20 +727,8 @@ static struct visor_driver visorinput_driver = {
.resume = visorinput_resume,
};
-static int
-visorinput_init(void)
-{
- return visorbus_register_visor_driver(&visorinput_driver);
-}
-
-static void
-visorinput_cleanup(void)
-{
- visorbus_unregister_visor_driver(&visorinput_driver);
-}
-
-module_init(visorinput_init);
-module_exit(visorinput_cleanup);
+module_driver(visorinput_driver, visorbus_register_visor_driver,
+ visorbus_unregister_visor_driver);
MODULE_DEVICE_TABLE(visorbus, visorinput_channel_types);
@@ -764,5 +736,5 @@ MODULE_AUTHOR("Unisys");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("s-Par human input driver for virtual keyboard/mouse");
-MODULE_ALIAS("visorbus:" VISOR_MOUSE_CHANNEL_UUID_STR);
-MODULE_ALIAS("visorbus:" VISOR_KEYBOARD_CHANNEL_UUID_STR);
+MODULE_ALIAS("visorbus:" VISOR_MOUSE_CHANNEL_GUID_STR);
+MODULE_ALIAS("visorbus:" VISOR_KEYBOARD_CHANNEL_GUID_STR);
diff --git a/drivers/staging/unisys/visornic/visornic_main.c b/drivers/staging/unisys/visornic/visornic_main.c
index 2891622..dc390ea 100644
--- a/drivers/staging/unisys/visornic/visornic_main.c
+++ b/drivers/staging/unisys/visornic/visornic_main.c
@@ -37,22 +37,28 @@
#define NAPI_WEIGHT 64
/* GUIDS for director channel type supported by this driver. */
+/* {8cd5994d-c58e-11da-95a9-00e08161165f} */
+#define VISOR_VNIC_CHANNEL_GUID \
+ GUID_INIT(0x8cd5994d, 0xc58e, 0x11da, \
+ 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f)
+#define VISOR_VNIC_CHANNEL_GUID_STR \
+ "8cd5994d-c58e-11da-95a9-00e08161165f"
+
static struct visor_channeltype_descriptor visornic_channel_types[] = {
/* Note that the only channel type we expect to be reported by the
* bus driver is the VISOR_VNIC channel.
*/
- { VISOR_VNIC_CHANNEL_UUID, "ultravnic" },
- { NULL_UUID_LE, NULL }
+ { VISOR_VNIC_CHANNEL_GUID, "ultravnic" },
+ {}
};
MODULE_DEVICE_TABLE(visorbus, visornic_channel_types);
-/*
- * FIXME XXX: This next line of code must be fixed and removed before
+/* FIXME XXX: This next line of code must be fixed and removed before
* acceptance into the 'normal' part of the kernel. It is only here as a place
* holder to get module autoloading functionality working for visorbus. Code
* must be added to scripts/mode/file2alias.c, etc., to get this working
* properly.
*/
-MODULE_ALIAS("visorbus:" VISOR_VNIC_CHANNEL_UUID_STR);
+MODULE_ALIAS("visorbus:" VISOR_VNIC_CHANNEL_GUID_STR);
struct chanstat {
unsigned long got_rcv;
@@ -68,10 +74,67 @@ struct chanstat {
unsigned long extra_rcvbufs_sent;
};
+/* struct visornic_devdata
+ * @enabled: 0 disabled 1 enabled to receive.
+ * @enab_dis_acked: NET_RCV_ENABLE/DISABLE acked by IOPART.
+ * @struct *dev:
+ * @struct *netdev:
+ * @struct net_stats:
+ * @interrupt_rcvd:
+ * @rsp_queue:
+ * @struct **rcvbuf:
+ * @incarnation_id: incarnation_id lets IOPART know about
+ * re-birth.
+ * @old_flags: flags as they were prior to
+ * set_multicast_list.
+ * @usage: count of users.
+ * @num_rcv_bufs: number of rcv buffers the vnic will post.
+ * @num_rcv_bufs_could_not_alloc:
+ * @num_rcvbuf_in_iovm:
+ * @alloc_failed_in_if_needed_cnt:
+ * @alloc_failed_in_repost_rtn_cnt:
+ * @max_outstanding_net_xmits: absolute max number of outstanding xmits
+ * - should never hit this.
+ * @upper_threshold_net_xmits: high water mark for calling
+ * netif_stop_queue().
+ * @lower_threshold_net_xmits: high water mark for calling
+ * netif_wake_queue().
+ * @struct xmitbufhead: xmitbufhead - head of the xmit buffer list
+ * sent to the IOPART end.
+ * @server_down_complete_func:
+ * @struct timeout_reset:
+ * @struct *cmdrsp_rcv: cmdrsp_rcv is used for posting/unposting rcv
+ * buffers.
+ * @struct *xmit_cmdrsp: xmit_cmdrsp - issues NET_XMIT - only one
+ * active xmit at a time.
+ * @server_down: IOPART is down.
+ * @server_change_state: Processing SERVER_CHANGESTATE msg.
+ * @going_away: device is being torn down.
+ * @struct *eth_debugfs_dir:
+ * @interrupts_rcvd:
+ * @interrupts_notme:
+ * @interrupts_disabled:
+ * @busy_cnt:
+ * @priv_lock: spinlock to access devdata structures.
+ * @flow_control_upper_hits:
+ * @flow_control_lower_hits:
+ * @n_rcv0: # rcvs of 0 buffers.
+ * @n_rcv1: # rcvs of 1 buffers.
+ * @n_rcv2: # rcvs of 2 buffers.
+ * @n_rcvx: # rcvs of >2 buffers.
+ * @found_repost_rcvbuf_cnt: # repost_rcvbuf_cnt.
+ * @repost_found_skb_cnt: # of found the skb.
+ * @n_repost_deficit: # of lost rcv buffers.
+ * @bad_rcv_buf: # of unknown rcv skb not freed.
+ * @n_rcv_packets_not_accepted: # bogs rcv packets.
+ * @queuefullmsg_logged:
+ * @struct chstat:
+ * @struct irq_poll_timer:
+ * @struct napi:
+ * @struct cmdrsp:
+ */
struct visornic_devdata {
- /* 0 disabled 1 enabled to receive */
unsigned short enabled;
- /* NET_RCV_ENABLE/DISABLE acked by IOPART */
unsigned short enab_dis_acked;
struct visor_device *dev;
@@ -80,59 +143,50 @@ struct visornic_devdata {
atomic_t interrupt_rcvd;
wait_queue_head_t rsp_queue;
struct sk_buff **rcvbuf;
- /* incarnation_id lets IOPART know about re-birth */
u64 incarnation_id;
- /* flags as they were prior to set_multicast_list */
unsigned short old_flags;
- atomic_t usage; /* count of users */
+ atomic_t usage;
- /* number of rcv buffers the vnic will post */
int num_rcv_bufs;
int num_rcv_bufs_could_not_alloc;
atomic_t num_rcvbuf_in_iovm;
unsigned long alloc_failed_in_if_needed_cnt;
unsigned long alloc_failed_in_repost_rtn_cnt;
- /* absolute max number of outstanding xmits - should never hit this */
unsigned long max_outstanding_net_xmits;
- /* high water mark for calling netif_stop_queue() */
unsigned long upper_threshold_net_xmits;
- /* high water mark for calling netif_wake_queue() */
unsigned long lower_threshold_net_xmits;
- /* xmitbufhead - head of the xmit buffer list sent to the IOPART end */
struct sk_buff_head xmitbufhead;
visorbus_state_complete_func server_down_complete_func;
struct work_struct timeout_reset;
- /* cmdrsp_rcv is used for posting/unposting rcv buffers */
struct uiscmdrsp *cmdrsp_rcv;
- /* xmit_cmdrsp - issues NET_XMIT - only one active xmit at a time */
struct uiscmdrsp *xmit_cmdrsp;
-
- bool server_down; /* IOPART is down */
- bool server_change_state; /* Processing SERVER_CHANGESTATE msg */
- bool going_away; /* device is being torn down */
+ bool server_down;
+ bool server_change_state;
+ bool going_away;
struct dentry *eth_debugfs_dir;
u64 interrupts_rcvd;
u64 interrupts_notme;
u64 interrupts_disabled;
u64 busy_cnt;
- spinlock_t priv_lock; /* spinlock to access devdata structures */
+ /* spinlock to access devdata structures. */
+ spinlock_t priv_lock;
/* flow control counter */
u64 flow_control_upper_hits;
u64 flow_control_lower_hits;
/* debug counters */
- unsigned long n_rcv0; /* # rcvs of 0 buffers */
- unsigned long n_rcv1; /* # rcvs of 1 buffers */
- unsigned long n_rcv2; /* # rcvs of 2 buffers */
- unsigned long n_rcvx; /* # rcvs of >2 buffers */
- unsigned long found_repost_rcvbuf_cnt; /* # repost_rcvbuf_cnt */
- unsigned long repost_found_skb_cnt; /* # of found the skb */
- unsigned long n_repost_deficit; /* # of lost rcv buffers */
- unsigned long bad_rcv_buf; /* # of unknown rcv skb not freed */
- unsigned long n_rcv_packets_not_accepted;/* # bogs rcv packets */
+ unsigned long n_rcv0;
+ unsigned long n_rcv1;
+ unsigned long n_rcv2;
+ unsigned long n_rcvx;
+ unsigned long found_repost_rcvbuf_cnt;
+ unsigned long repost_found_skb_cnt;
+ unsigned long n_repost_deficit;
+ unsigned long bad_rcv_buf;
+ unsigned long n_rcv_packets_not_accepted;
int queuefullmsg_logged;
struct chanstat chstat;
@@ -142,12 +196,11 @@ struct visornic_devdata {
};
/* Returns next non-zero index on success or 0 on failure (i.e. out of room). */
-static u16
-add_physinfo_entries(u64 inp_pfn, u16 inp_off, u32 inp_len, u16 index,
- u16 max_pi_arr_entries, struct phys_info pi_arr[])
+static u16 add_physinfo_entries(u64 inp_pfn, u16 inp_off, u16 inp_len,
+ u16 index, u16 max_pi_arr_entries,
+ struct phys_info pi_arr[])
{
- u32 len;
- u16 i, firstlen;
+ u16 i, len, firstlen;
firstlen = PI_PAGE_SIZE - inp_off;
if (inp_len <= firstlen) {
@@ -171,29 +224,27 @@ add_physinfo_entries(u64 inp_pfn, u16 inp_off, u32 inp_len, u16 index,
pi_arr[index].pi_len = firstlen;
} else {
pi_arr[index + i].pi_off = 0;
- pi_arr[index + i].pi_len =
- (u16)MINNUM(len, (u32)PI_PAGE_SIZE);
+ pi_arr[index + i].pi_len = min_t(u16, len,
+ PI_PAGE_SIZE);
}
}
return index + i;
}
-/*
- * visor_copy_fragsinfo_from_skb(
- * @skb_in: skbuff that we are pulling the frags from
- * @firstfraglen: length of first fragment in skb
- * @frags_max: max len of frags array
- * @frags: frags array filled in on output
+/* visor_copy_fragsinfo_from_skb - copy fragment list in the SKB to a phys_info
+ * array that the IOPART understands
+ * @skb: Skbuff that we are pulling the frags from.
+ * @firstfraglen: Length of first fragment in skb.
+ * @frags_max: Max len of frags array.
+ * @frags: Frags array filled in on output.
*
- * Copy the fragment list in the SKB to a phys_info
- * array that the IOPART understands.
- * Return value indicates number of entries filled in frags
- * Negative values indicate an error.
+ * Return: Positive integer indicating number of entries filled in frags on
+ * success, negative integer on error.
*/
-static int
-visor_copy_fragsinfo_from_skb(struct sk_buff *skb, unsigned int firstfraglen,
- unsigned int frags_max,
- struct phys_info frags[])
+static int visor_copy_fragsinfo_from_skb(struct sk_buff *skb,
+ unsigned int firstfraglen,
+ unsigned int frags_max,
+ struct phys_info frags[])
{
unsigned int count = 0, frag, size, offset = 0, numfrags;
unsigned int total_count;
@@ -239,11 +290,10 @@ visor_copy_fragsinfo_from_skb(struct sk_buff *skb, unsigned int firstfraglen,
for (frag = 0; frag < numfrags; frag++) {
count = add_physinfo_entries(page_to_pfn(
- skb_frag_page(&skb_shinfo(skb)->frags[frag])),
- skb_shinfo(skb)->frags[frag].
- page_offset,
- skb_shinfo(skb)->frags[frag].
- size, count, frags_max, frags);
+ skb_frag_page(&skb_shinfo(skb)->frags[frag])),
+ skb_shinfo(skb)->frags[frag].page_offset,
+ skb_shinfo(skb)->frags[frag].size, count,
+ frags_max, frags);
/* add_physinfo_entries only returns
* zero if the frags array is out of room
* That should never happen because we
@@ -287,21 +337,15 @@ static const struct file_operations debugfs_enable_ints_fops = {
.write = enable_ints_write,
};
-/*
- * visornic_serverdown_complete - IOPART went down, pause device
- * @work: Work queue it was scheduled on
+/* visornic_serverdown_complete - pause device following IOPART going down
+ * @devdata: Device managed by IOPART.
*
- * The IO partition has gone down and we need to do some cleanup
- * for when it comes back. Treat the IO partition as the link
- * being down.
- * Returns void.
+ * The IO partition has gone down, and we need to do some cleanup for when it
+ * comes back. Treat the IO partition as the link being down.
*/
-static void
-visornic_serverdown_complete(struct visornic_devdata *devdata)
+static void visornic_serverdown_complete(struct visornic_devdata *devdata)
{
- struct net_device *netdev;
-
- netdev = devdata->netdev;
+ struct net_device *netdev = devdata->netdev;
/* Stop polling for interrupts */
del_timer_sync(&devdata->irq_poll_timer);
@@ -322,17 +366,17 @@ visornic_serverdown_complete(struct visornic_devdata *devdata)
devdata->server_down_complete_func = NULL;
}
-/*
- * visornic_serverdown - Command has notified us that IOPART is down
- * @devdata: device that is being managed by IOPART
+/* visornic_serverdown - Command has notified us that IOPART is down
+ * @devdata: Device managed by IOPART.
+ * @complete_func: Function to call when finished.
+ *
+ * Schedule the work needed to handle the server down request. Make sure we
+ * haven't already handled the server change state event.
*
- * Schedule the work needed to handle the server down request. Make
- * sure we haven't already handled the server change state event.
- * Returns 0 if we scheduled the work, -EINVAL on error.
+ * Return: 0 if we scheduled the work, negative integer on error.
*/
-static int
-visornic_serverdown(struct visornic_devdata *devdata,
- visorbus_state_complete_func complete_func)
+static int visornic_serverdown(struct visornic_devdata *devdata,
+ visorbus_state_complete_func complete_func)
{
unsigned long flags;
int err;
@@ -369,16 +413,15 @@ err_unlock:
return err;
}
-/*
- * alloc_rcv_buf - alloc rcv buffer to be given to the IO Partition.
- * @netdev: network adapter the rcv bufs are attached too.
+/* alloc_rcv_buf - alloc rcv buffer to be given to the IO Partition
+ * @netdev: Network adapter the rcv bufs are attached too.
*
- * Create an sk_buff (rcv_buf) that will be passed to the IO Partition
- * so that it can write rcv data into our memory space.
- * Return pointer to sk_buff
+ * Create an sk_buff (rcv_buf) that will be passed to the IO Partition
+ * so that it can write rcv data into our memory space.
+ *
+ * Return: Pointer to sk_buff.
*/
-static struct sk_buff *
-alloc_rcv_buf(struct net_device *netdev)
+static struct sk_buff *alloc_rcv_buf(struct net_device *netdev)
{
struct sk_buff *skb;
@@ -400,18 +443,15 @@ alloc_rcv_buf(struct net_device *netdev)
return skb;
}
-/*
- * post_skb - post a skb to the IO Partition.
- * @cmdrsp: cmdrsp packet to be send to the IO Partition
- * @devdata: visornic_devdata to post the skb too
- * @skb: skb to give to the IO partition
+/* post_skb - post a skb to the IO Partition
+ * @cmdrsp: Cmdrsp packet to be send to the IO Partition.
+ * @devdata: visornic_devdata to post the skb to.
+ * @skb: Skb to give to the IO partition.
*
- * Send the skb to the IO Partition.
- * Returns 0 or error
+ * Return: 0 on success, negative integer on error.
*/
-static int
-post_skb(struct uiscmdrsp *cmdrsp,
- struct visornic_devdata *devdata, struct sk_buff *skb)
+static int post_skb(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata,
+ struct sk_buff *skb)
{
int err;
@@ -437,23 +477,20 @@ post_skb(struct uiscmdrsp *cmdrsp,
atomic_inc(&devdata->num_rcvbuf_in_iovm);
devdata->chstat.sent_post++;
-
return 0;
}
-/*
- * send_enbdis - send NET_RCV_ENBDIS to IO Partition
- * @netdev: netdevice we are enable/disable, used as context
- * return value
- * @state: enable = 1/disable = 0
- * @devdata: visornic device we are enabling/disabling
+/* send_enbdis - Send NET_RCV_ENBDIS to IO Partition
+ * @netdev: Netdevice we are enabling/disabling, used as context return value.
+ * @state: Enable = 1/disable = 0.
+ * @devdata: Visornic device we are enabling/disabling.
+ *
+ * Send the enable/disable message to the IO Partition.
*
- * Send the enable/disable message to the IO Partition.
- * Returns 0 or error
+ * Return: 0 on success, negative integer on error.
*/
-static int
-send_enbdis(struct net_device *netdev, int state,
- struct visornic_devdata *devdata)
+static int send_enbdis(struct net_device *netdev, int state,
+ struct visornic_devdata *devdata)
{
int err;
@@ -470,19 +507,17 @@ send_enbdis(struct net_device *netdev, int state,
return 0;
}
-/*
- * visornic_disable_with_timeout - Disable network adapter
- * @netdev: netdevice to disable
- * @timeout: timeout to wait for disable
+/* visornic_disable_with_timeout - disable network adapter
+ * @netdev: netdevice to disable.
+ * @timeout: Timeout to wait for disable.
*
- * Disable the network adapter and inform the IO Partition that we
- * are disabled, reclaim memory from rcv bufs.
- * Returns 0 on success, negative for failure of IO Partition
- * responding.
+ * Disable the network adapter and inform the IO Partition that we are disabled.
+ * Reclaim memory from rcv bufs.
*
+ * Return: 0 on success, negative integer on failure of IO Partition responding.
*/
-static int
-visornic_disable_with_timeout(struct net_device *netdev, const int timeout)
+static int visornic_disable_with_timeout(struct net_device *netdev,
+ const int timeout)
{
struct visornic_devdata *devdata = netdev_priv(netdev);
int i;
@@ -493,7 +528,8 @@ visornic_disable_with_timeout(struct net_device *netdev, const int timeout)
/* send a msg telling the other end we are stopping incoming pkts */
spin_lock_irqsave(&devdata->priv_lock, flags);
devdata->enabled = 0;
- devdata->enab_dis_acked = 0; /* must wait for ack */
+ /* must wait for ack */
+ devdata->enab_dis_acked = 0;
spin_unlock_irqrestore(&devdata->priv_lock, flags);
/* send disable and wait for ack -- don't hold lock when sending
@@ -560,16 +596,16 @@ visornic_disable_with_timeout(struct net_device *netdev, const int timeout)
return 0;
}
-/*
- * init_rcv_bufs -- initialize receive bufs and send them to the IO Part
- * @netdev: struct netdevice
- * @devdata: visornic_devdata
+/* init_rcv_bufs - initialize receive buffs and send them to the IO Partition
+ * @netdev: struct netdevice.
+ * @devdata: visornic_devdata.
+ *
+ * Allocate rcv buffers and post them to the IO Partition.
*
- * Allocate rcv buffers and post them to the IO Partition.
- * Return 0 for success, and negative for failure.
+ * Return: 0 on success, negative integer on failure.
*/
-static int
-init_rcv_bufs(struct net_device *netdev, struct visornic_devdata *devdata)
+static int init_rcv_bufs(struct net_device *netdev,
+ struct visornic_devdata *devdata)
{
int i, j, count, err;
@@ -578,10 +614,12 @@ init_rcv_bufs(struct net_device *netdev, struct visornic_devdata *devdata)
*/
for (i = 0; i < devdata->num_rcv_bufs; i++) {
devdata->rcvbuf[i] = alloc_rcv_buf(netdev);
+ /* if we failed to allocate one let us stop */
if (!devdata->rcvbuf[i])
- break; /* if we failed to allocate one let us stop */
+ break;
}
- if (i == 0) /* couldn't even allocate one -- bail out */
+ /* couldn't even allocate one -- bail out */
+ if (i == 0)
return -ENOMEM;
count = i;
@@ -624,17 +662,17 @@ init_rcv_bufs(struct net_device *netdev, struct visornic_devdata *devdata)
return 0;
}
-/*
- * visornic_enable_with_timeout - send enable to IO Part
- * @netdev: struct net_device
- * @timeout: Time to wait for the ACK from the enable
+/* visornic_enable_with_timeout - send enable to IO Partition
+ * @netdev: struct net_device.
+ * @timeout: Time to wait for the ACK from the enable.
*
- * Sends enable to IOVM, inits, and posts receive buffers to IOVM
- * timeout is defined in msecs (timeout of 0 specifies infinite wait)
- * Return 0 for success, negative for failure.
+ * Sends enable to IOVM and inits, and posts receive buffers to IOVM. Timeout is
+ * defined in msecs (timeout of 0 specifies infinite wait).
+ *
+ * Return: 0 on success, negative integer on failure.
*/
-static int
-visornic_enable_with_timeout(struct net_device *netdev, const int timeout)
+static int visornic_enable_with_timeout(struct net_device *netdev,
+ const int timeout)
{
int err = 0;
struct visornic_devdata *devdata = netdev_priv(netdev);
@@ -695,20 +733,17 @@ visornic_enable_with_timeout(struct net_device *netdev, const int timeout)
}
netif_start_queue(netdev);
-
return 0;
}
-/*
- * visornic_timeout_reset - handle xmit timeout resets
- * @work work item that scheduled the work
+/* visornic_timeout_reset - handle xmit timeout resets
+ * @work: Work item that scheduled the work.
*
- * Transmit Timeouts are typically handled by resetting the
- * device for our virtual NIC we will send a Disable and Enable
- * to the IOVM. If it doesn't respond we will trigger a serverdown.
+ * Transmit timeouts are typically handled by resetting the device for our
+ * virtual NIC; we will send a disable and enable to the IOVM. If it doesn't
+ * respond, we will trigger a serverdown.
*/
-static void
-visornic_timeout_reset(struct work_struct *work)
+static void visornic_timeout_reset(struct work_struct *work)
{
struct visornic_devdata *devdata;
struct net_device *netdev;
@@ -742,41 +777,36 @@ call_serverdown:
rtnl_unlock();
}
-/*
- * visornic_open - Enable the visornic device and mark the queue started
- * @netdev: netdevice to start
+/* visornic_open - enable the visornic device and mark the queue started
+ * @netdev: netdevice to start.
*
- * Enable the device and start the transmit queue.
- * Return 0 for success
+ * Enable the device and start the transmit queue.
+ *
+ * Return: 0 on success.
*/
-static int
-visornic_open(struct net_device *netdev)
+static int visornic_open(struct net_device *netdev)
{
visornic_enable_with_timeout(netdev, VISORNIC_INFINITE_RSP_WAIT);
-
return 0;
}
-/*
- * visornic_close - Disables the visornic device and stops the queues
- * @netdev: netdevice to start
+/* visornic_close - disables the visornic device and stops the queues
+ * @netdev: netdevice to stop.
*
- * Disable the device and stop the transmit queue.
- * Return 0 for success
+ * Disable the device and stop the transmit queue.
+ *
+ * Return 0 on success.
*/
-static int
-visornic_close(struct net_device *netdev)
+static int visornic_close(struct net_device *netdev)
{
visornic_disable_with_timeout(netdev, VISORNIC_INFINITE_RSP_WAIT);
-
return 0;
}
-/*
- * devdata_xmits_outstanding - compute outstanding xmits
- * @devdata: visornic_devdata for device
+/* devdata_xmits_outstanding - compute outstanding xmits
+ * @devdata: visornic_devdata for device
*
- * Return value is the number of outstanding xmits.
+ * Return: Long integer representing the number of outstanding xmits.
*/
static unsigned long devdata_xmits_outstanding(struct visornic_devdata *devdata)
{
@@ -787,14 +817,13 @@ static unsigned long devdata_xmits_outstanding(struct visornic_devdata *devdata)
+ devdata->chstat.sent_xmit + 1);
}
-/*
- * vnic_hit_high_watermark
- * @devdata: indicates visornic device we are checking
- * @high_watermark: max num of unacked xmits we will tolerate,
- * before we will start throttling
+/* vnic_hit_high_watermark
+ * @devdata: Indicates visornic device we are checking.
+ * @high_watermark: Max num of unacked xmits we will tolerate before we will
+ * start throttling.
*
- * Returns true iff the number of unacked xmits sent to
- * the IO partition is >= high_watermark.
+ * Return: True iff the number of unacked xmits sent to the IO Partition is >=
+ * high_watermark. False otherwise.
*/
static bool vnic_hit_high_watermark(struct visornic_devdata *devdata,
ulong high_watermark)
@@ -802,15 +831,13 @@ static bool vnic_hit_high_watermark(struct visornic_devdata *devdata,
return (devdata_xmits_outstanding(devdata) >= high_watermark);
}
-/*
- * vnic_hit_low_watermark
- * @devdata: indicates visornic device we are checking
- * @low_watermark: we will wait until the num of unacked xmits
- * drops to this value or lower before we start
- * transmitting again
+/* vnic_hit_low_watermark
+ * @devdata: Indicates visornic device we are checking.
+ * @low_watermark: We will wait until the num of unacked xmits drops to this
+ * value or lower before we start transmitting again.
*
- * Returns true iff the number of unacked xmits sent to
- * the IO partition is <= low_watermark.
+ * Return: True iff the number of unacked xmits sent to the IO Partition is <=
+ * low_watermark.
*/
static bool vnic_hit_low_watermark(struct visornic_devdata *devdata,
ulong low_watermark)
@@ -818,20 +845,18 @@ static bool vnic_hit_low_watermark(struct visornic_devdata *devdata,
return (devdata_xmits_outstanding(devdata) <= low_watermark);
}
-/*
- * visornic_xmit - send a packet to the IO Partition
- * @skb: Packet to be sent
- * @netdev: net device the packet is being sent from
+/* visornic_xmit - send a packet to the IO Partition
+ * @skb: Packet to be sent.
+ * @netdev: Net device the packet is being sent from.
+ *
+ * Convert the skb to a cmdrsp so the IO Partition can understand it, and send
+ * the XMIT command to the IO Partition for processing. This function is
+ * protected from concurrent calls by a spinlock xmit_lock in the net_device
+ * struct. As soon as the function returns, it can be called again.
*
- * Convert the skb to a cmdrsp so the IO Partition can understand it.
- * Send the XMIT command to the IO Partition for processing. This
- * function is protected from concurrent calls by a spinlock xmit_lock
- * in the net_device struct, but as soon as the function returns it
- * can be called again.
- * Returns NETDEV_TX_OK.
+ * Return: NETDEV_TX_OK.
*/
-static int
-visornic_xmit(struct sk_buff *skb, struct net_device *netdev)
+static int visornic_xmit(struct sk_buff *skb, struct net_device *netdev)
{
struct visornic_devdata *devdata;
int len, firstfraglen, padlen;
@@ -938,6 +963,7 @@ visornic_xmit(struct sk_buff *skb, struct net_device *netdev)
* - everything else will be pass in frags & DMA'ed
*/
memcpy(cmdrsp->net.xmt.ethhdr, skb->data, ETH_HLEN);
+
/* copy frags info - from skb->data we need to only provide access
* beyond eth header
*/
@@ -991,46 +1017,39 @@ visornic_xmit(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_OK;
}
-/*
- * visornic_get_stats - returns net_stats of the visornic device
- * @netdev: netdevice
+/* visornic_get_stats - returns net_stats of the visornic device
+ * @netdev: netdevice.
*
- * Returns the net_device_stats for the device
+ * Return: Pointer to the net_device_stats struct for the device.
*/
-static struct net_device_stats *
-visornic_get_stats(struct net_device *netdev)
+static struct net_device_stats *visornic_get_stats(struct net_device *netdev)
{
struct visornic_devdata *devdata = netdev_priv(netdev);
return &devdata->net_stats;
}
-/*
- * visornic_change_mtu - changes mtu of device.
- * @netdev: netdevice
- * @new_mtu: value of new mtu
+/* visornic_change_mtu - changes mtu of device
+ * @netdev: netdevice.
+ * @new_mtu: Value of new mtu.
+ *
+ * The device's MTU cannot be changed by system; it must be changed via a
+ * CONTROLVM message. All vnics and pnics in a switch have to have the same MTU
+ * for everything to work. Currently not supported.
*
- * MTU cannot be changed by system, must be changed via
- * CONTROLVM message. All vnics and pnics in a switch have
- * to have the same MTU for everything to work.
- * Currently not supported.
- * Returns EINVAL
+ * Return: -EINVAL.
*/
-static int
-visornic_change_mtu(struct net_device *netdev, int new_mtu)
+static int visornic_change_mtu(struct net_device *netdev, int new_mtu)
{
return -EINVAL;
}
-/*
- * visornic_set_multi - changes mtu of device.
- * @netdev: netdevice
+/* visornic_set_multi - set visornic device flags
+ * @netdev: netdevice.
*
- * Only flag we support currently is IFF_PROMISC
- * Returns void
+ * The only flag we currently support is IFF_PROMISC.
*/
-static void
-visornic_set_multi(struct net_device *netdev)
+static void visornic_set_multi(struct net_device *netdev)
{
struct uiscmdrsp *cmdrsp;
struct visornic_devdata *devdata = netdev_priv(netdev);
@@ -1062,16 +1081,13 @@ out_save_flags:
devdata->old_flags = netdev->flags;
}
-/*
- * visornic_xmit_timeout - request to timeout the xmit
- * @netdev
+/* visornic_xmit_timeout - request to timeout the xmit
+ * @netdev: netdevice.
*
- * Queue the work and return. Make sure we have not already
- * been informed the IO Partition is gone, if it is gone
- * we will already timeout the xmits.
+ * Queue the work and return. Make sure we have not already been informed that
+ * the IO Partition is gone; if so, we will have already timed-out the xmits.
*/
-static void
-visornic_xmit_timeout(struct net_device *netdev)
+static void visornic_xmit_timeout(struct net_device *netdev)
{
struct visornic_devdata *devdata = netdev_priv(netdev);
unsigned long flags;
@@ -1097,20 +1113,20 @@ visornic_xmit_timeout(struct net_device *netdev)
spin_unlock_irqrestore(&devdata->priv_lock, flags);
}
-/*
- * repost_return - repost rcv bufs that have come back
- * @cmdrsp: io channel command struct to post
- * @devdata: visornic devdata for the device
- * @skb: skb
- * @netdev: netdevice
+/* repost_return - repost rcv bufs that have come back
+ * @cmdrsp: IO channel command struct to post.
+ * @devdata: Visornic devdata for the device.
+ * @skb: Socket buffer.
+ * @netdev: netdevice.
+ *
+ * Repost rcv buffers that have been returned to us when we are finished
+ * with them.
*
- * Repost rcv buffers that have been returned to us when
- * we are finished with them.
- * Returns 0 for success, -1 for error.
+ * Return: 0 for success, negative integer on error.
*/
-static int
-repost_return(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata,
- struct sk_buff *skb, struct net_device *netdev)
+static int repost_return(struct uiscmdrsp *cmdrsp,
+ struct visornic_devdata *devdata,
+ struct sk_buff *skb, struct net_device *netdev)
{
struct net_pkt_rcv copy;
int i = 0, cc, numreposted;
@@ -1174,16 +1190,15 @@ repost_return(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata,
return status;
}
-/*
- * visornic_rx - Handle receive packets coming back from IO Part
- * @cmdrsp: Receive packet returned from IO Part
+/* visornic_rx - handle receive packets coming back from IO Partition
+ * @cmdrsp: Receive packet returned from IO Partition.
*
- * Got a receive packet back from the IO Part, handle it and send
- * it up the stack.
- * Returns 1 iff an skb was received, otherwise 0
+ * Got a receive packet back from the IO Partition; handle it and send it up
+ * the stack.
+
+ * Return: 1 iff an skb was received, otherwise 0.
*/
-static int
-visornic_rx(struct uiscmdrsp *cmdrsp)
+static int visornic_rx(struct uiscmdrsp *cmdrsp)
{
struct visornic_devdata *devdata;
struct sk_buff *skb, *prev, *curr;
@@ -1236,7 +1251,8 @@ visornic_rx(struct uiscmdrsp *cmdrsp)
* firstfrag & set data_len to show rest see if we have to chain
* frag_list.
*/
- if (skb->len > RCVPOST_BUF_SIZE) { /* do PRECAUTIONARY check */
+ /* do PRECAUTIONARY check */
+ if (skb->len > RCVPOST_BUF_SIZE) {
if (cmdrsp->net.rcv.numrcvbufs < 2) {
if (repost_return(cmdrsp, devdata, skb, netdev) < 0)
dev_err(&devdata->netdev->dev,
@@ -1244,23 +1260,24 @@ visornic_rx(struct uiscmdrsp *cmdrsp)
return 0;
}
/* length rcvd is greater than firstfrag in this skb rcv buf */
- skb->tail += RCVPOST_BUF_SIZE; /* amount in skb->data */
- skb->data_len = skb->len - RCVPOST_BUF_SIZE; /* amount that
- * will be in
- * frag_list
- */
+ /* amount in skb->data */
+ skb->tail += RCVPOST_BUF_SIZE;
+ /* amount that will be in frag_list */
+ skb->data_len = skb->len - RCVPOST_BUF_SIZE;
} else {
/* data fits in this skb - no chaining - do
* PRECAUTIONARY check
*/
- if (cmdrsp->net.rcv.numrcvbufs != 1) { /* should be 1 */
+ /* should be 1 */
+ if (cmdrsp->net.rcv.numrcvbufs != 1) {
if (repost_return(cmdrsp, devdata, skb, netdev) < 0)
dev_err(&devdata->netdev->dev,
"repost_return failed");
return 0;
}
skb->tail += skb->len;
- skb->data_len = 0; /* nothing rcvd in frag_list */
+ /* nothing rcvd in frag_list */
+ skb->data_len = 0;
}
off = skb_tail_pointer(skb) - skb->data;
@@ -1286,7 +1303,8 @@ visornic_rx(struct uiscmdrsp *cmdrsp)
cc < cmdrsp->net.rcv.numrcvbufs; cc++) {
curr = (struct sk_buff *)cmdrsp->net.rcv.rcvbuf[cc];
curr->next = NULL;
- if (!prev) /* start of list- set head */
+ /* start of list- set head */
+ if (!prev)
skb_shinfo(skb)->frag_list = curr;
else
prev->next = curr;
@@ -1314,18 +1332,18 @@ visornic_rx(struct uiscmdrsp *cmdrsp)
* sets up skb->pkt_type & it also PULLS out the eth header
*/
skb->protocol = eth_type_trans(skb, netdev);
-
eth = eth_hdr(skb);
-
skb->csum = 0;
skb->ip_summed = CHECKSUM_NONE;
do {
+ /* accept all packets */
if (netdev->flags & IFF_PROMISC)
- break; /* accept all packets */
+ break;
if (skb->pkt_type == PACKET_BROADCAST) {
+ /* accept all broadcast packets */
if (netdev->flags & IFF_BROADCAST)
- break; /* accept all broadcast packets */
+ break;
} else if (skb->pkt_type == PACKET_MULTICAST) {
if ((netdev->flags & IFF_MULTICAST) &&
(netdev_mc_count(netdev))) {
@@ -1367,8 +1385,7 @@ visornic_rx(struct uiscmdrsp *cmdrsp)
*/
skb = NULL;
- /*
- * whether the packet got dropped or handled, the skb is freed by
+ /* whether the packet got dropped or handled, the skb is freed by
* kernel code, so we shouldn't free it. but we should repost a
* new rcv buffer.
*/
@@ -1376,29 +1393,25 @@ visornic_rx(struct uiscmdrsp *cmdrsp)
return 1;
}
-/*
- * devdata_initialize - Initialize devdata structure
- * @devdata: visornic_devdata structure to initialize
- * #dev: visorbus_deviced it belongs to
+/* devdata_initialize - initialize devdata structure
+ * @devdata: visornic_devdata structure to initialize.
+ * @dev: visorbus_device it belongs to.
*
- * Setup initial values for the visornic based on channel and default
- * values.
- * Returns a pointer to the devdata structure
+ * Setup initial values for the visornic, based on channel and default values.
+ *
+ * Return: A pointer to the devdata structure.
*/
-static struct visornic_devdata *
-devdata_initialize(struct visornic_devdata *devdata, struct visor_device *dev)
+static struct visornic_devdata *devdata_initialize(
+ struct visornic_devdata *devdata,
+ struct visor_device *dev)
{
devdata->dev = dev;
devdata->incarnation_id = get_jiffies_64();
return devdata;
}
-/*
- * devdata_release - Frees up references in devdata
- * @devdata: struct to clean up
- *
- * Frees up references in devdata.
- * Returns void
+/* devdata_release - free up references in devdata
+ * @devdata: Struct to clean up.
*/
static void devdata_release(struct visornic_devdata *devdata)
{
@@ -1570,15 +1583,10 @@ static const struct file_operations debugfs_info_fops = {
.read = info_debugfs_read,
};
-/*
- * send_rcv_posts_if_needed
- * @devdata: visornic device
- *
- * Send receive buffers to the IO Partition.
- * Returns void
+/* send_rcv_posts_if_needed - send receive buffers to the IO Partition.
+ * @devdata: Visornic device.
*/
-static int
-send_rcv_posts_if_needed(struct visornic_devdata *devdata)
+static void send_rcv_posts_if_needed(struct visornic_devdata *devdata)
{
int i;
struct net_device *netdev;
@@ -1588,7 +1596,7 @@ send_rcv_posts_if_needed(struct visornic_devdata *devdata)
/* don't do this until vnic is marked ready */
if (!(devdata->enabled && devdata->enab_dis_acked))
- return 0;
+ return;
netdev = devdata->netdev;
rcv_bufs_allocated = 0;
@@ -1617,16 +1625,14 @@ send_rcv_posts_if_needed(struct visornic_devdata *devdata)
}
}
devdata->num_rcv_bufs_could_not_alloc -= rcv_bufs_allocated;
- return 0;
}
-/*
- * drain_resp_queue - drains and ignores all messages from the resp queue
- * @cmdrsp: io channel command response message
- * @devdata: visornic device to drain
+/* drain_resp_queue - drains and ignores all messages from the resp queue
+ * @cmdrsp: IO channel command response message.
+ * @devdata: Visornic device to drain.
*/
-static void
-drain_resp_queue(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata)
+static void drain_resp_queue(struct uiscmdrsp *cmdrsp,
+ struct visornic_devdata *devdata)
{
while (!visorchannel_signalremove(devdata->dev->visorchannel,
IOCHAN_FROM_IOPART,
@@ -1634,30 +1640,31 @@ drain_resp_queue(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata)
;
}
-/*
- * service_resp_queue - drains the response queue
- * @cmdrsp: io channel command response message
- * @devdata: visornic device to drain
+/* service_resp_queue - drain the response queue
+ * @cmdrsp: IO channel command response message.
+ * @devdata: Visornic device to drain.
+ * @rx_work_done:
+ * @budget:
*
- * Drain the response queue of any responses from the IO partition.
- * Process the responses as we get them.
- * Returns when response queue is empty or when the thread stops.
+ * Drain the response queue of any responses from the IO Partition. Process the
+ * responses as we get them.
*/
-static void
-service_resp_queue(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata,
- int *rx_work_done, int budget)
+static void service_resp_queue(struct uiscmdrsp *cmdrsp,
+ struct visornic_devdata *devdata,
+ int *rx_work_done, int budget)
{
unsigned long flags;
struct net_device *netdev;
while (*rx_work_done < budget) {
- /* TODO: CLIENT ACQUIRE -- Don't really need this at the
- * moment
- */
+ /* TODO: CLIENT ACQUIRE -- Don't really need this at the
+ * moment
+ */
+ /* queue empty */
if (visorchannel_signalremove(devdata->dev->visorchannel,
IOCHAN_FROM_IOPART,
cmdrsp))
- break; /* queue empty */
+ break;
switch (cmdrsp->net.type) {
case NET_RCV:
@@ -1740,12 +1747,8 @@ static int visornic_poll(struct napi_struct *napi, int budget)
struct visornic_devdata,
napi);
int rx_count = 0;
- int err;
-
- err = send_rcv_posts_if_needed(devdata);
- if (err)
- return err;
+ send_rcv_posts_if_needed(devdata);
service_resp_queue(devdata->cmdrsp, devdata, &rx_count, budget);
/* If there aren't any more packets to receive stop the poll */
@@ -1755,16 +1758,13 @@ static int visornic_poll(struct napi_struct *napi, int budget)
return rx_count;
}
-/*
- * poll_for_irq - Checks the status of the response queue.
- * @v: void pointer to the visronic devdata
+/* poll_for_irq - checks the status of the response queue
+ * @v: Void pointer to the visronic devdata struct.
*
- * Main function of the vnic_incoming thread. Periodically check the
- * response queue and drain it if needed.
- * Returns when thread has stopped.
+ * Main function of the vnic_incoming thread. Periodically check the response
+ * queue and drain it if needed.
*/
-static void
-poll_for_irq(unsigned long v)
+static void poll_for_irq(unsigned long v)
{
struct visornic_devdata *devdata = (struct visornic_devdata *)v;
@@ -1778,13 +1778,13 @@ poll_for_irq(unsigned long v)
mod_timer(&devdata->irq_poll_timer, msecs_to_jiffies(2));
}
-/*
- * visornic_probe - probe function for visornic devices
- * @dev: The visor device discovered
+/* visornic_probe - probe function for visornic devices
+ * @dev: The visor device discovered.
+ *
+ * Called when visorbus discovers a visornic device on its bus. It creates a new
+ * visornic ethernet adapter.
*
- * Called when visorbus discovers a visornic device on its
- * bus. It creates a new visornic ethernet adapter.
- * Returns 0 or negative for error.
+ * Return: 0 on success, or negative integer on error.
*/
static int visornic_probe(struct visor_device *dev)
{
@@ -1831,7 +1831,8 @@ static int visornic_probe(struct visor_device *dev)
dev_set_drvdata(&dev->device, devdata);
init_waitqueue_head(&devdata->rsp_queue);
spin_lock_init(&devdata->priv_lock);
- devdata->enabled = 0; /* not yet */
+ /* not yet */
+ devdata->enabled = 0;
atomic_set(&devdata->usage, 1);
/* Setup rcv bufs */
@@ -1852,9 +1853,10 @@ static int visornic_probe(struct visor_device *dev)
goto cleanup_netdev;
}
- /* set the net_xmit outstanding threshold */
- /* always leave two slots open but you should have 3 at a minimum */
- /* note that max_outstanding_net_xmits must be > 0 */
+ /* set the net_xmit outstanding threshold
+ * always leave two slots open but you should have 3 at a minimum
+ * note that max_outstanding_net_xmits must be > 0
+ */
devdata->max_outstanding_net_xmits =
max_t(unsigned long, 3, ((devdata->num_rcv_bufs / 3) - 2));
devdata->upper_threshold_net_xmits =
@@ -1972,28 +1974,25 @@ cleanup_netdev:
return err;
}
-/*
- * host_side_disappeared - IO part is gone.
- * @devdata: device object
+/* host_side_disappeared - IO Partition is gone
+ * @devdata: Device object.
*
- * IO partition servicing this device is gone, do cleanup
- * Returns void.
+ * IO partition servicing this device is gone; do cleanup.
*/
static void host_side_disappeared(struct visornic_devdata *devdata)
{
unsigned long flags;
spin_lock_irqsave(&devdata->priv_lock, flags);
- devdata->dev = NULL; /* indicate device destroyed */
+ /* indicate device destroyed */
+ devdata->dev = NULL;
spin_unlock_irqrestore(&devdata->priv_lock, flags);
}
-/*
- * visornic_remove - Called when visornic dev goes away
- * @dev: visornic device that is being removed
+/* visornic_remove - called when visornic dev goes away
+ * @dev: Visornic device that is being removed.
*
- * Called when DEVICE_DESTROY gets called to remove device.
- * Returns void
+ * Called when DEVICE_DESTROY gets called to remove device.
*/
static void visornic_remove(struct visor_device *dev)
{
@@ -2023,8 +2022,8 @@ static void visornic_remove(struct visor_device *dev)
cancel_work_sync(&devdata->timeout_reset);
debugfs_remove_recursive(devdata->eth_debugfs_dir);
-
- unregister_netdev(netdev); /* this will call visornic_close() */
+ /* this will call visornic_close() */
+ unregister_netdev(netdev);
del_timer_sync(&devdata->irq_poll_timer);
netif_napi_del(&devdata->napi);
@@ -2035,18 +2034,17 @@ static void visornic_remove(struct visor_device *dev)
free_netdev(netdev);
}
-/*
- * visornic_pause - Called when IO Part disappears
- * @dev: visornic device that is being serviced
- * @complete_func: call when finished.
+/* visornic_pause - called when IO Part disappears
+ * @dev: Visornic device that is being serviced.
+ * @complete_func: Call when finished.
+ *
+ * Called when the IO Partition has gone down. Need to free up resources and
+ * wait for IO partition to come back. Mark link as down and don't attempt any
+ * DMA. When we have freed memory, call the complete_func so that Command knows
+ * we are done. If we don't call complete_func, the IO Partition will never
+ * come back.
*
- * Called when the IO Partition has gone down. Need to free
- * up resources and wait for IO partition to come back. Mark
- * link as down and don't attempt any DMA. When we have freed
- * memory call the complete_func so that Command knows we are
- * done. If we don't call complete_func, IO part will never
- * come back.
- * Returns 0 for success.
+ * Return: 0 on success.
*/
static int visornic_pause(struct visor_device *dev,
visorbus_state_complete_func complete_func)
@@ -2057,15 +2055,14 @@ static int visornic_pause(struct visor_device *dev,
return 0;
}
-/*
- * visornic_resume - Called when IO part has recovered
- * @dev: visornic device that is being serviced
- * @compelte_func: call when finished
+/* visornic_resume - called when IO Partition has recovered
+ * @dev: Visornic device that is being serviced.
+ * @compelte_func: Call when finished.
+ *
+ * Called when the IO partition has recovered. Re-establish connection to the IO
+ * Partition and set the link up. Okay to do DMA again.
*
- * Called when the IO partition has recovered. Reestablish
- * connection to the IO part and set the link up. Okay to do
- * DMA again.
- * Returns 0 for success.
+ * Returns 0 for success, negative integer on error.
*/
static int visornic_resume(struct visor_device *dev,
visorbus_state_complete_func complete_func)
@@ -2127,12 +2124,12 @@ static struct visor_driver visornic_driver = {
.channel_interrupt = NULL,
};
-/*
- * visornic_init - Init function
+/* visornic_init - init function
*
- * Init function for the visornic driver. Do initial driver setup
- * and wait for devices.
- * Returns 0 for success, negative for error.
+ * Init function for the visornic driver. Do initial driver setup and wait
+ * for devices.
+ *
+ * Return: 0 on success, negative integer on error.
*/
static int visornic_init(void)
{
@@ -2160,19 +2157,16 @@ static int visornic_init(void)
cleanup_debugfs:
debugfs_remove_recursive(visornic_debugfs_dir);
-
return err;
}
-/*
- * visornic_cleanup - driver exit routine
+/* visornic_cleanup - driver exit routine
*
- * Unregister driver from the bus and free up memory.
+ * Unregister driver from the bus and free up memory.
*/
static void visornic_cleanup(void)
{
visorbus_unregister_visor_driver(&visornic_driver);
-
debugfs_remove_recursive(visornic_debugfs_dir);
}
diff --git a/drivers/staging/vboxvideo/Kconfig b/drivers/staging/vboxvideo/Kconfig
index a52746f..1f4182e 100644
--- a/drivers/staging/vboxvideo/Kconfig
+++ b/drivers/staging/vboxvideo/Kconfig
@@ -2,11 +2,14 @@ config DRM_VBOXVIDEO
tristate "Virtual Box Graphics Card"
depends on DRM && X86 && PCI
select DRM_KMS_HELPER
+ select DRM_TTM
+ select GENERIC_ALLOCATOR
help
This is a KMS driver for the virtual Graphics Card used in
Virtual Box virtual machines.
- Although it is possible to builtin this module, it is advised
- to build this driver as a module, so that it can be updated
- independently of the kernel. Select M to built this driver as a
- module and add support for these devices via drm/kms interfaces.
+ Although it is possible to build this driver built-in to the
+ kernel, it is advised to build it as a module, so that it can
+ be updated independently of the kernel. Select M to build this
+ driver as a module and add support for these devices via drm/kms
+ interfaces.
diff --git a/drivers/staging/vboxvideo/TODO b/drivers/staging/vboxvideo/TODO
index ce76430..bd381d8 100644
--- a/drivers/staging/vboxvideo/TODO
+++ b/drivers/staging/vboxvideo/TODO
@@ -5,5 +5,5 @@ TODO:
-Extend this TODO with the results of that review
Please send any patches to Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
-Hans de Goede <hdegoede@redhat.com> and
-Michael Thayer <michael.thayer@oracle.com>.
+Hans de Goede <hdegoede@redhat.com>, Michael Thayer <michael.thayer@oracle.com>
+and dri-devel@lists.freedesktop.org .
diff --git a/drivers/staging/vboxvideo/vbox_drv.c b/drivers/staging/vboxvideo/vbox_drv.c
index 92ae156..e18642e 100644
--- a/drivers/staging/vboxvideo/vbox_drv.c
+++ b/drivers/staging/vboxvideo/vbox_drv.c
@@ -36,7 +36,7 @@
#include "vbox_drv.h"
-int vbox_modeset = -1;
+static int vbox_modeset = -1;
MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
module_param_named(modeset, vbox_modeset, int, 0400);
@@ -232,7 +232,6 @@ static struct drm_driver driver = {
.lastclose = vbox_driver_lastclose,
.master_set = vbox_master_set,
.master_drop = vbox_master_drop,
- .set_busid = drm_pci_set_busid,
.fops = &vbox_fops,
.irq_handler = vbox_irq_handler,
@@ -270,12 +269,12 @@ static int __init vbox_init(void)
if (vbox_modeset == 0)
return -EINVAL;
- return drm_pci_init(&driver, &vbox_pci_driver);
+ return pci_register_driver(&vbox_pci_driver);
}
static void __exit vbox_exit(void)
{
- drm_pci_exit(&driver, &vbox_pci_driver);
+ pci_unregister_driver(&vbox_pci_driver);
}
module_init(vbox_init);
diff --git a/drivers/staging/vboxvideo/vbox_fb.c b/drivers/staging/vboxvideo/vbox_fb.c
index 35f6d9f..8aed248 100644
--- a/drivers/staging/vboxvideo/vbox_fb.c
+++ b/drivers/staging/vboxvideo/vbox_fb.c
@@ -45,144 +45,20 @@
#include "vbox_drv.h"
#include "vboxvideo.h"
-#define VBOX_DIRTY_DELAY (HZ / 30)
-/**
- * Tell the host about dirty rectangles to update.
- */
-static void vbox_dirty_update(struct vbox_fbdev *fbdev,
- int x, int y, int width, int height)
-{
- struct drm_gem_object *obj;
- struct vbox_bo *bo;
- int ret = -EBUSY;
- bool store_for_later = false;
- int x2, y2;
- unsigned long flags;
- struct drm_clip_rect rect;
-
- obj = fbdev->afb.obj;
- bo = gem_to_vbox_bo(obj);
-
- /*
- * try and reserve the BO, if we fail with busy
- * then the BO is being moved and we should
- * store up the damage until later.
- */
- if (drm_can_sleep())
- ret = vbox_bo_reserve(bo, true);
- if (ret) {
- if (ret != -EBUSY)
- return;
-
- store_for_later = true;
- }
-
- x2 = x + width - 1;
- y2 = y + height - 1;
- spin_lock_irqsave(&fbdev->dirty_lock, flags);
-
- if (fbdev->y1 < y)
- y = fbdev->y1;
- if (fbdev->y2 > y2)
- y2 = fbdev->y2;
- if (fbdev->x1 < x)
- x = fbdev->x1;
- if (fbdev->x2 > x2)
- x2 = fbdev->x2;
-
- if (store_for_later) {
- fbdev->x1 = x;
- fbdev->x2 = x2;
- fbdev->y1 = y;
- fbdev->y2 = y2;
- spin_unlock_irqrestore(&fbdev->dirty_lock, flags);
- return;
- }
-
- fbdev->x1 = INT_MAX;
- fbdev->y1 = INT_MAX;
- fbdev->x2 = 0;
- fbdev->y2 = 0;
-
- spin_unlock_irqrestore(&fbdev->dirty_lock, flags);
-
- /*
- * Not sure why the original code subtracted 1 here, but I will keep
- * it that way to avoid unnecessary differences.
- */
- rect.x1 = x;
- rect.x2 = x2 + 1;
- rect.y1 = y;
- rect.y2 = y2 + 1;
- vbox_framebuffer_dirty_rectangles(&fbdev->afb.base, &rect, 1);
-
- vbox_bo_unreserve(bo);
-}
-
-#ifdef CONFIG_FB_DEFERRED_IO
-static void vbox_deferred_io(struct fb_info *info, struct list_head *pagelist)
-{
- struct vbox_fbdev *fbdev = info->par;
- unsigned long start, end, min, max;
- struct page *page;
- int y1, y2;
-
- min = ULONG_MAX;
- max = 0;
- list_for_each_entry(page, pagelist, lru) {
- start = page->index << PAGE_SHIFT;
- end = start + PAGE_SIZE - 1;
- min = min(min, start);
- max = max(max, end);
- }
-
- if (min < max) {
- y1 = min / info->fix.line_length;
- y2 = (max / info->fix.line_length) + 1;
- DRM_INFO("%s: Calling dirty update: 0, %d, %d, %d\n",
- __func__, y1, info->var.xres, y2 - y1 - 1);
- vbox_dirty_update(fbdev, 0, y1, info->var.xres, y2 - y1 - 1);
- }
-}
-
+#ifdef CONFIG_DRM_KMS_FB_HELPER
static struct fb_deferred_io vbox_defio = {
- .delay = VBOX_DIRTY_DELAY,
- .deferred_io = vbox_deferred_io,
+ .delay = HZ / 30,
+ .deferred_io = drm_fb_helper_deferred_io,
};
#endif
-static void vbox_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
-{
- struct vbox_fbdev *fbdev = info->par;
-
- sys_fillrect(info, rect);
- vbox_dirty_update(fbdev, rect->dx, rect->dy, rect->width, rect->height);
-}
-
-static void vbox_copyarea(struct fb_info *info, const struct fb_copyarea *area)
-{
- struct vbox_fbdev *fbdev = info->par;
-
- sys_copyarea(info, area);
- vbox_dirty_update(fbdev, area->dx, area->dy, area->width, area->height);
-}
-
-static void vbox_imageblit(struct fb_info *info, const struct fb_image *image)
-{
- struct vbox_fbdev *fbdev = info->par;
-
- sys_imageblit(info, image);
- vbox_dirty_update(fbdev, image->dx, image->dy, image->width,
- image->height);
-}
-
static struct fb_ops vboxfb_ops = {
.owner = THIS_MODULE,
.fb_check_var = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
- .fb_fillrect = vbox_fillrect,
- .fb_copyarea = vbox_copyarea,
- .fb_imageblit = vbox_imageblit,
+ .fb_fillrect = drm_fb_helper_sys_fillrect,
+ .fb_copyarea = drm_fb_helper_sys_copyarea,
+ .fb_imageblit = drm_fb_helper_sys_imageblit,
.fb_pan_display = drm_fb_helper_pan_display,
.fb_blank = drm_fb_helper_blank,
.fb_setcmap = drm_fb_helper_setcmap,
@@ -219,7 +95,6 @@ static int vboxfb_create(struct drm_fb_helper *helper,
struct DRM_MODE_FB_CMD mode_cmd;
struct drm_framebuffer *fb;
struct fb_info *info;
- struct device *device = &dev->pdev->dev;
struct drm_gem_object *gobj;
struct vbox_bo *bo;
int size, ret;
@@ -263,16 +138,16 @@ static int vboxfb_create(struct drm_fb_helper *helper,
return ret;
}
- info = framebuffer_alloc(0, device);
- if (!info)
- return -ENOMEM;
+ info = drm_fb_helper_alloc_fbi(helper);
+ if (IS_ERR(info))
+ return -PTR_ERR(info);
+
info->par = fbdev;
fbdev->size = size;
fb = &fbdev->afb.base;
fbdev->helper.fb = fb;
- fbdev->helper.fbdev = info;
strcpy(info->fix.id, "vboxdrmfb");
@@ -284,17 +159,10 @@ static int vboxfb_create(struct drm_fb_helper *helper,
FBINFO_MISC_ALWAYS_SETPAR;
info->fbops = &vboxfb_ops;
- ret = fb_alloc_cmap(&info->cmap, 256, 0);
- if (ret)
- return -ENOMEM;
-
/*
* This seems to be done for safety checking that the framebuffer
* is not registered twice by different drivers.
*/
- info->apertures = alloc_apertures(1);
- if (!info->apertures)
- return -ENOMEM;
info->apertures->ranges[0].base = pci_resource_start(dev->pdev, 0);
info->apertures->ranges[0].size = pci_resource_len(dev->pdev, 0);
@@ -305,7 +173,7 @@ static int vboxfb_create(struct drm_fb_helper *helper,
info->screen_base = bo->kmap.virtual;
info->screen_size = size;
-#ifdef CONFIG_FB_DEFERRED_IO
+#ifdef CONFIG_DRM_KMS_FB_HELPER
info->fbdefio = &vbox_defio;
fb_deferred_io_init(info);
#endif
@@ -317,22 +185,7 @@ static int vboxfb_create(struct drm_fb_helper *helper,
return 0;
}
-static void vbox_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno)
-{
-}
-
-static void vbox_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
- u16 *blue, int regno)
-{
- *red = regno;
- *green = regno;
- *blue = regno;
-}
-
static struct drm_fb_helper_funcs vbox_fb_helper_funcs = {
- .gamma_set = vbox_fb_gamma_set,
- .gamma_get = vbox_fb_gamma_get,
.fb_probe = vboxfb_create,
};
@@ -342,6 +195,11 @@ void vbox_fbdev_fini(struct drm_device *dev)
struct vbox_fbdev *fbdev = vbox->fbdev;
struct vbox_framebuffer *afb = &fbdev->afb;
+#ifdef CONFIG_DRM_KMS_FB_HELPER
+ if (fbdev->helper.fbdev && fbdev->helper.fbdev->fbdefio)
+ fb_deferred_io_cleanup(fbdev->helper.fbdev);
+#endif
+
drm_fb_helper_unregister_fbi(&fbdev->helper);
if (afb->obj) {
@@ -358,7 +216,7 @@ void vbox_fbdev_fini(struct drm_device *dev)
vbox_bo_unpin(bo);
vbox_bo_unreserve(bo);
}
- drm_gem_object_unreference_unlocked(afb->obj);
+ drm_gem_object_put_unlocked(afb->obj);
afb->obj = NULL;
}
drm_fb_helper_fini(&fbdev->helper);
diff --git a/drivers/staging/vboxvideo/vbox_main.c b/drivers/staging/vboxvideo/vbox_main.c
index d0c6ec7..80bd039 100644
--- a/drivers/staging/vboxvideo/vbox_main.c
+++ b/drivers/staging/vboxvideo/vbox_main.c
@@ -40,7 +40,7 @@ static void vbox_user_framebuffer_destroy(struct drm_framebuffer *fb)
struct vbox_framebuffer *vbox_fb = to_vbox_framebuffer(fb);
if (vbox_fb->obj)
- drm_gem_object_unreference_unlocked(vbox_fb->obj);
+ drm_gem_object_put_unlocked(vbox_fb->obj);
drm_framebuffer_cleanup(fb);
kfree(fb);
@@ -198,7 +198,7 @@ static struct drm_framebuffer *vbox_user_framebuffer_create(
err_free_vbox_fb:
kfree(vbox_fb);
err_unref_obj:
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ERR_PTR(ret);
}
@@ -472,7 +472,7 @@ int vbox_dumb_create(struct drm_file *file,
return ret;
ret = drm_gem_handle_create(file, gobj, &handle);
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
if (ret)
return ret;
@@ -525,7 +525,7 @@ vbox_dumb_mmap_offset(struct drm_file *file,
bo = gem_to_vbox_bo(obj);
*offset = vbox_bo_mmap_offset(bo);
- drm_gem_object_unreference(obj);
+ drm_gem_object_put(obj);
ret = 0;
out_unlock:
diff --git a/drivers/staging/vboxvideo/vbox_mode.c b/drivers/staging/vboxvideo/vbox_mode.c
index f2b85f3..257a778 100644
--- a/drivers/staging/vboxvideo/vbox_mode.c
+++ b/drivers/staging/vboxvideo/vbox_mode.c
@@ -54,14 +54,12 @@ static void vbox_do_modeset(struct drm_crtc *crtc,
struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
struct vbox_private *vbox;
int width, height, bpp, pitch;
- unsigned int crtc_id;
u16 flags;
s32 x_offset, y_offset;
vbox = crtc->dev->dev_private;
width = mode->hdisplay ? mode->hdisplay : 640;
height = mode->vdisplay ? mode->vdisplay : 480;
- crtc_id = vbox_crtc->crtc_id;
bpp = crtc->enabled ? CRTC_FB(crtc)->format->cpp[0] * 8 : 32;
pitch = crtc->enabled ? CRTC_FB(crtc)->pitches[0] : width * bpp / 8;
x_offset = vbox->single_framebuffer ? crtc->x : vbox_crtc->x_hint;
@@ -134,10 +132,6 @@ static int vbox_set_view(struct drm_crtc *crtc)
return 0;
}
-static void vbox_crtc_load_lut(struct drm_crtc *crtc)
-{
-}
-
static void vbox_crtc_dpms(struct drm_crtc *crtc, int mode)
{
struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
@@ -330,7 +324,6 @@ static const struct drm_crtc_helper_funcs vbox_crtc_helper_funcs = {
.mode_set = vbox_crtc_mode_set,
/* .mode_set_base = vbox_crtc_mode_set_base, */
.disable = vbox_crtc_disable,
- .load_lut = vbox_crtc_load_lut,
.prepare = vbox_crtc_prepare,
.commit = vbox_crtc_commit,
};
@@ -578,9 +571,6 @@ static int vbox_mode_valid(struct drm_connector *connector,
static void vbox_connector_destroy(struct drm_connector *connector)
{
- struct vbox_connector *vbox_connector;
-
- vbox_connector = to_vbox_connector(connector);
drm_connector_unregister(connector);
drm_connector_cleanup(connector);
kfree(connector);
@@ -817,7 +807,7 @@ out_unmap_bo:
out_unreserve_bo:
vbox_bo_unreserve(bo);
out_unref_obj:
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
diff --git a/drivers/staging/vboxvideo/vbox_ttm.c b/drivers/staging/vboxvideo/vbox_ttm.c
index 34a905d..4eb410a 100644
--- a/drivers/staging/vboxvideo/vbox_ttm.c
+++ b/drivers/staging/vboxvideo/vbox_ttm.c
@@ -230,7 +230,7 @@ static void vbox_ttm_tt_unpopulate(struct ttm_tt *ttm)
ttm_pool_unpopulate(ttm);
}
-struct ttm_bo_driver vbox_bo_driver = {
+static struct ttm_bo_driver vbox_bo_driver = {
.ttm_tt_create = vbox_ttm_tt_create,
.ttm_tt_populate = vbox_ttm_tt_populate,
.ttm_tt_unpopulate = vbox_ttm_tt_unpopulate,
diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c
index 3637ddf..94654c0 100644
--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c
+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c
@@ -20,7 +20,7 @@
#include "bcm2835.h"
/* hardware definition */
-static struct snd_pcm_hardware snd_bcm2835_playback_hw = {
+static const struct snd_pcm_hardware snd_bcm2835_playback_hw = {
.info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
@@ -36,7 +36,7 @@ static struct snd_pcm_hardware snd_bcm2835_playback_hw = {
.periods_max = 128,
};
-static struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = {
+static const struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = {
.info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
@@ -438,7 +438,7 @@ static int snd_bcm2835_pcm_lib_ioctl(struct snd_pcm_substream *substream,
}
/* operators */
-static struct snd_pcm_ops snd_bcm2835_playback_ops = {
+static const struct snd_pcm_ops snd_bcm2835_playback_ops = {
.open = snd_bcm2835_playback_open,
.close = snd_bcm2835_playback_close,
.ioctl = snd_bcm2835_pcm_lib_ioctl,
@@ -450,7 +450,7 @@ static struct snd_pcm_ops snd_bcm2835_playback_ops = {
.ack = snd_bcm2835_pcm_ack,
};
-static struct snd_pcm_ops snd_bcm2835_playback_spdif_ops = {
+static const struct snd_pcm_ops snd_bcm2835_playback_spdif_ops = {
.open = snd_bcm2835_playback_spdif_open,
.close = snd_bcm2835_playback_close,
.ioctl = snd_bcm2835_pcm_lib_ioctl,
diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
index a11e047..be936b8 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -642,7 +642,7 @@ static void bm2835_mmal_unlock(struct vb2_queue *vq)
mutex_unlock(&dev->mutex);
}
-static struct vb2_ops bm2835_mmal_video_qops = {
+static const struct vb2_ops bm2835_mmal_video_qops = {
.queue_setup = queue_setup,
.buf_prepare = buffer_prepare,
.buf_queue = buffer_queue,
@@ -1456,7 +1456,7 @@ static const struct v4l2_file_operations camera0_fops = {
.mmap = vb2_fop_mmap,
};
-static struct video_device vdev_template = {
+static const struct video_device vdev_template = {
.name = "camera0",
.fops = &camera0_fops,
.ioctl_ops = &camera0_ioctl_ops,
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c
index 7fa0310..2e52f07 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c
@@ -51,7 +51,7 @@ int vchiu_queue_init(VCHIU_QUEUE_T *queue, int size)
sema_init(&queue->pop, 0);
sema_init(&queue->push, 0);
- queue->storage = kzalloc(size * sizeof(VCHIQ_HEADER_T *), GFP_KERNEL);
+ queue->storage = kcalloc(size, sizeof(VCHIQ_HEADER_T *), GFP_KERNEL);
if (!queue->storage) {
vchiu_queue_delete(queue);
return 0;
diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c
index f5db2b3..14034e3 100644
--- a/drivers/staging/vt6655/card.c
+++ b/drivers/staging/vt6655/card.c
@@ -649,19 +649,19 @@ static unsigned short CARDwGetOFDMControlRate(struct vnt_private *priv,
pr_debug("BASIC RATE: %X\n", priv->basic_rates);
if (!CARDbIsOFDMinBasicRate((void *)priv)) {
- pr_debug("CARDwGetOFDMControlRate:(NO OFDM) %d\n", wRateIdx);
+ pr_debug("%s:(NO OFDM) %d\n", __func__, wRateIdx);
if (wRateIdx > RATE_24M)
wRateIdx = RATE_24M;
return wRateIdx;
}
while (ui > RATE_11M) {
if (priv->basic_rates & ((u32)0x1 << ui)) {
- pr_debug("CARDwGetOFDMControlRate : %d\n", ui);
+ pr_debug("%s : %d\n", __func__, ui);
return (unsigned short)ui;
}
ui--;
}
- pr_debug("CARDwGetOFDMControlRate: 6M\n");
+ pr_debug("%s: 6M\n", __func__);
return (unsigned short)RATE_24M;
}
diff --git a/drivers/staging/vt6655/mac.c b/drivers/staging/vt6655/mac.c
index 4aaa99b..f7550b2 100644
--- a/drivers/staging/vt6655/mac.c
+++ b/drivers/staging/vt6655/mac.c
@@ -809,7 +809,7 @@ void MACvSetKeyEntry(struct vnt_private *priv, unsigned short wKeyCtl,
if (byLocalID <= 1)
return;
- pr_debug("MACvSetKeyEntry\n");
+ pr_debug("%s\n", __func__);
offset = MISCFIFO_KEYETRY0;
offset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h
index 4832666..74715c8 100644
--- a/drivers/staging/vt6656/device.h
+++ b/drivers/staging/vt6656/device.h
@@ -83,7 +83,7 @@
#define CONFIG_PATH "/etc/vntconfiguration.dat"
#define MAX_UINTS 8
-#define OPTION_DEFAULT { [0 ... MAX_UINTS-1] = -1}
+#define OPTION_DEFAULT { [0 ... MAX_UINTS - 1] = -1}
#define DUPLICATE_RX_CACHE_LENGTH 5
diff --git a/drivers/staging/vt6656/firmware.c b/drivers/staging/vt6656/firmware.c
index 282f665..093a604 100644
--- a/drivers/staging/vt6656/firmware.c
+++ b/drivers/staging/vt6656/firmware.c
@@ -65,7 +65,7 @@ int vnt_download_firmware(struct vnt_private *priv)
status = vnt_control_out(priv,
0,
- 0x1200+ii,
+ 0x1200 + ii,
0x0000,
length,
buffer);
diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h
index 906d345..cfc6c21 100644
--- a/drivers/staging/vt6656/key.h
+++ b/drivers/staging/vt6656/key.h
@@ -46,6 +46,6 @@
int vnt_key_init_table(struct vnt_private *priv);
int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
- struct ieee80211_vif *vif, struct ieee80211_key_conf *key);
+ struct ieee80211_vif *vif, struct ieee80211_key_conf *key);
#endif /* __KEY_H__ */
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index 095b855..cc6d877 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -419,8 +419,7 @@ static bool vnt_alloc_bufs(struct vnt_private *priv)
int ii;
for (ii = 0; ii < priv->num_tx_context; ii++) {
- tx_context = kmalloc(sizeof(struct vnt_usb_send_context),
- GFP_KERNEL);
+ tx_context = kmalloc(sizeof(*tx_context), GFP_KERNEL);
if (!tx_context)
goto free_tx;
@@ -437,7 +436,7 @@ static bool vnt_alloc_bufs(struct vnt_private *priv)
}
for (ii = 0; ii < priv->num_rcb; ii++) {
- priv->rcb[ii] = kzalloc(sizeof(struct vnt_rcb), GFP_KERNEL);
+ priv->rcb[ii] = kzalloc(sizeof(*priv->rcb[ii]), GFP_KERNEL);
if (!priv->rcb[ii]) {
dev_err(&priv->usb->dev,
"failed to allocate rcb no %d\n", ii);
diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c
index e322b7d..c466e06 100644
--- a/drivers/staging/vt6656/power.c
+++ b/drivers/staging/vt6656/power.c
@@ -74,16 +74,15 @@ void vnt_enable_power_saving(struct vnt_private *priv, u16 listen_interval)
vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_GO2DOZE);
if (listen_interval >= 2) {
-
/* clear always listen beacon */
vnt_mac_reg_bits_off(priv, MAC_REG_PSCTL, PSCTL_ALBCN);
/* first time set listen next beacon */
vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_LNBCN);
- } else
-
+ } else {
/* always listen beacon */
vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_ALBCN);
+ }
dev_dbg(&priv->usb->dev, "PS:Power Saving Mode Enable...\n");
}
@@ -100,7 +99,6 @@ void vnt_enable_power_saving(struct vnt_private *priv, u16 listen_interval)
void vnt_disable_power_saving(struct vnt_private *priv)
{
-
/* disable power saving hw function */
vnt_control_out(priv, MESSAGE_TYPE_DISABLE_PS, 0,
0, 0, NULL);
diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c
index 23581af..3a9d19a 100644
--- a/drivers/staging/vt6656/rf.c
+++ b/drivers/staging/vt6656/rf.c
@@ -611,7 +611,7 @@ int vnt_rf_write_embedded(struct vnt_private *priv, u32 data)
reg_data[3] = (u8)(data >> 24);
vnt_control_out(priv, MESSAGE_TYPE_WRITE_IFRF,
- 0, 0, ARRAY_SIZE(reg_data), reg_data);
+ 0, 0, ARRAY_SIZE(reg_data), reg_data);
return true;
}
@@ -643,9 +643,9 @@ int vnt_rf_setpower(struct vnt_private *priv, u32 rate, u32 channel)
case RATE_48M:
case RATE_54M:
if (channel > CB_MAX_CHANNEL_24G)
- power = priv->ofdm_a_pwr_tbl[channel-15];
+ power = priv->ofdm_a_pwr_tbl[channel - 15];
else
- power = priv->ofdm_pwr_tbl[channel-1];
+ power = priv->ofdm_pwr_tbl[channel - 1];
break;
}
diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c
index dc11a05..23eaef4 100644
--- a/drivers/staging/vt6656/usbpipe.c
+++ b/drivers/staging/vt6656/usbpipe.c
@@ -44,7 +44,7 @@
#define USB_CTL_WAIT 500 /* ms */
int vnt_control_out(struct vnt_private *priv, u8 request, u16 value,
- u16 index, u16 length, u8 *buffer)
+ u16 index, u16 length, u8 *buffer)
{
int status = 0;
u8 *usb_buffer;
@@ -82,7 +82,7 @@ void vnt_control_out_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 data)
}
int vnt_control_in(struct vnt_private *priv, u8 request, u16 value,
- u16 index, u16 length, u8 *buffer)
+ u16 index, u16 length, u8 *buffer)
{
int status;
u8 *usb_buffer;
diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c
index 2568dfc..7b62065 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -1963,7 +1963,7 @@ static s32 Handle_Get_InActiveTime(struct wilc_vif *vif,
wilc_get_vif_idx(vif));
if (result) {
- netdev_err(vif->ndev, "Failed to SET incative time\n");
+ netdev_err(vif->ndev, "Failed to SET inactive time\n");
return -EFAULT;
}
@@ -1976,7 +1976,7 @@ static s32 Handle_Get_InActiveTime(struct wilc_vif *vif,
wilc_get_vif_idx(vif));
if (result) {
- netdev_err(vif->ndev, "Failed to get incative time\n");
+ netdev_err(vif->ndev, "Failed to get inactive time\n");
return -EFAULT;
}
diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c
index dbb3e24..119f345 100644
--- a/drivers/staging/wilc1000/linux_wlan.c
+++ b/drivers/staging/wilc1000/linux_wlan.c
@@ -283,7 +283,8 @@ int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc)
static int linux_wlan_txq_task(void *vp)
{
- int ret, txq_count;
+ int ret;
+ u32 txq_count;
struct wilc_vif *vif;
struct wilc *wl;
struct net_device *dev = vp;
@@ -812,7 +813,7 @@ _fail_wilc_wlan_:
wilc_wlan_cleanup(dev);
_fail_locks_:
wlan_deinit_locks(dev);
- netdev_err(dev, "WLAN Iinitialization FAILED\n");
+ netdev_err(dev, "WLAN initialization FAILED\n");
} else {
netdev_dbg(dev, "wilc1000 already initialized\n");
}
diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
index 68fd5b3..ac5aaaf 100644
--- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
+++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
@@ -214,48 +214,39 @@ static u32 get_rssi_avg(struct network_info *network_info)
return rssi_v;
}
-static void refresh_scan(void *user_void, u8 all, bool direct_scan)
+static void refresh_scan(struct wilc_priv *priv, bool direct_scan)
{
- struct wilc_priv *priv;
- struct wiphy *wiphy;
- struct cfg80211_bss *bss = NULL;
+ struct wiphy *wiphy = priv->dev->ieee80211_ptr->wiphy;
int i;
- int rssi = 0;
-
- priv = user_void;
- wiphy = priv->dev->ieee80211_ptr->wiphy;
for (i = 0; i < last_scanned_cnt; i++) {
struct network_info *network_info;
+ s32 freq;
+ struct ieee80211_channel *channel;
+ int rssi;
+ struct cfg80211_bss *bss;
network_info = &last_scanned_shadow[i];
- if (!network_info->found || all) {
- s32 freq;
- struct ieee80211_channel *channel;
-
- if (network_info) {
- freq = ieee80211_channel_to_frequency((s32)network_info->ch, NL80211_BAND_2GHZ);
- channel = ieee80211_get_channel(wiphy, freq);
-
- rssi = get_rssi_avg(network_info);
- if (memcmp("DIRECT-", network_info->ssid, 7) ||
- direct_scan) {
- bss = cfg80211_inform_bss(wiphy,
- channel,
- CFG80211_BSS_FTYPE_UNKNOWN,
- network_info->bssid,
- network_info->tsf_hi,
- network_info->cap_info,
- network_info->beacon_period,
- (const u8 *)network_info->ies,
- (size_t)network_info->ies_len,
- (s32)rssi * 100,
- GFP_KERNEL);
- cfg80211_put_bss(wiphy, bss);
- }
- }
- }
+ if (!memcmp("DIRECT-", network_info->ssid, 7) && !direct_scan)
+ continue;
+
+ freq = ieee80211_channel_to_frequency((s32)network_info->ch,
+ NL80211_BAND_2GHZ);
+ channel = ieee80211_get_channel(wiphy, freq);
+ rssi = get_rssi_avg(network_info);
+ bss = cfg80211_inform_bss(wiphy,
+ channel,
+ CFG80211_BSS_FTYPE_UNKNOWN,
+ network_info->bssid,
+ network_info->tsf_hi,
+ network_info->cap_info,
+ network_info->beacon_period,
+ (const u8 *)network_info->ies,
+ (size_t)network_info->ies_len,
+ (s32)rssi * 100,
+ GFP_KERNEL);
+ cfg80211_put_bss(wiphy, bss);
}
}
@@ -442,7 +433,7 @@ static void CfgScanResult(enum scan_event scan_event,
}
}
} else if (scan_event == SCAN_EVENT_DONE) {
- refresh_scan(priv, 1, false);
+ refresh_scan(priv, false);
mutex_lock(&priv->scan_req_lock);
@@ -466,7 +457,7 @@ static void CfgScanResult(enum scan_event scan_event,
};
update_scan_time();
- refresh_scan(priv, 1, false);
+ refresh_scan(priv, false);
cfg80211_scan_done(priv->pstrScanReq, &info);
priv->bCfgScanning = false;
@@ -540,7 +531,7 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
}
if (bNeedScanRefresh)
- refresh_scan(priv, 1, true);
+ refresh_scan(priv, true);
}
cfg80211_connect_result(dev, pstrConnectInfo->bssid,
diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
index c89bf43..7a36561 100644
--- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h
+++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
@@ -227,8 +227,8 @@ int wilc1000_wlan_init(struct net_device *dev, struct wilc_vif *vif);
void wilc_frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset);
void wilc_mac_indicate(struct wilc *wilc, int flag);
void wilc_netdev_cleanup(struct wilc *wilc);
-int wilc_netdev_init(struct wilc **wilc, struct device *, int io_type, int gpio,
- const struct wilc_hif_func *ops);
+int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type,
+ int gpio, const struct wilc_hif_func *ops);
void wilc1000_wlan_deinit(struct net_device *dev);
void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size);
int wilc_wlan_get_firmware(struct net_device *dev);
diff --git a/drivers/staging/wlan-ng/hfa384x.h b/drivers/staging/wlan-ng/hfa384x.h
index 018db22..f5a3a1c 100644
--- a/drivers/staging/wlan-ng/hfa384x.h
+++ b/drivers/staging/wlan-ng/hfa384x.h
@@ -413,8 +413,8 @@ struct hfa384x_join_request_data {
/*-- Configuration Record: authenticateStation (data portion only) --*/
struct hfa384x_authenticate_station_data {
u8 address[ETH_ALEN];
- u16 status;
- u16 algorithm;
+ __le16 status;
+ __le16 algorithm;
} __packed;
/*-- Configuration Record: WPAData (data portion only) --*/
@@ -445,9 +445,9 @@ struct hfa384x_downloadbuffer {
/*-- Information Record: commsquality --*/
struct hfa384x_commsquality {
- u16 cq_curr_bss;
- u16 asl_curr_bss;
- u16 anl_curr_fc;
+ __le16 cq_curr_bss;
+ __le16 asl_curr_bss;
+ __le16 anl_curr_fc;
} __packed;
/*-- Information Record: dmbcommsquality --*/
@@ -598,51 +598,51 @@ struct hfa384x_rx_frame {
/*-- Inquiry Frame, Diagnose: Communication Tallies --*/
struct hfa384x_comm_tallies_16 {
- u16 txunicastframes;
- u16 txmulticastframes;
- u16 txfragments;
- u16 txunicastoctets;
- u16 txmulticastoctets;
- u16 txdeferredtrans;
- u16 txsingleretryframes;
- u16 txmultipleretryframes;
- u16 txretrylimitexceeded;
- u16 txdiscards;
- u16 rxunicastframes;
- u16 rxmulticastframes;
- u16 rxfragments;
- u16 rxunicastoctets;
- u16 rxmulticastoctets;
- u16 rxfcserrors;
- u16 rxdiscardsnobuffer;
- u16 txdiscardswrongsa;
- u16 rxdiscardswepundecr;
- u16 rxmsginmsgfrag;
- u16 rxmsginbadmsgfrag;
+ __le16 txunicastframes;
+ __le16 txmulticastframes;
+ __le16 txfragments;
+ __le16 txunicastoctets;
+ __le16 txmulticastoctets;
+ __le16 txdeferredtrans;
+ __le16 txsingleretryframes;
+ __le16 txmultipleretryframes;
+ __le16 txretrylimitexceeded;
+ __le16 txdiscards;
+ __le16 rxunicastframes;
+ __le16 rxmulticastframes;
+ __le16 rxfragments;
+ __le16 rxunicastoctets;
+ __le16 rxmulticastoctets;
+ __le16 rxfcserrors;
+ __le16 rxdiscardsnobuffer;
+ __le16 txdiscardswrongsa;
+ __le16 rxdiscardswepundecr;
+ __le16 rxmsginmsgfrag;
+ __le16 rxmsginbadmsgfrag;
} __packed;
struct hfa384x_comm_tallies_32 {
- u32 txunicastframes;
- u32 txmulticastframes;
- u32 txfragments;
- u32 txunicastoctets;
- u32 txmulticastoctets;
- u32 txdeferredtrans;
- u32 txsingleretryframes;
- u32 txmultipleretryframes;
- u32 txretrylimitexceeded;
- u32 txdiscards;
- u32 rxunicastframes;
- u32 rxmulticastframes;
- u32 rxfragments;
- u32 rxunicastoctets;
- u32 rxmulticastoctets;
- u32 rxfcserrors;
- u32 rxdiscardsnobuffer;
- u32 txdiscardswrongsa;
- u32 rxdiscardswepundecr;
- u32 rxmsginmsgfrag;
- u32 rxmsginbadmsgfrag;
+ __le32 txunicastframes;
+ __le32 txmulticastframes;
+ __le32 txfragments;
+ __le32 txunicastoctets;
+ __le32 txmulticastoctets;
+ __le32 txdeferredtrans;
+ __le32 txsingleretryframes;
+ __le32 txmultipleretryframes;
+ __le32 txretrylimitexceeded;
+ __le32 txdiscards;
+ __le32 rxunicastframes;
+ __le32 rxmulticastframes;
+ __le32 rxfragments;
+ __le32 rxunicastoctets;
+ __le32 rxmulticastoctets;
+ __le32 rxfcserrors;
+ __le32 rxdiscardsnobuffer;
+ __le32 txdiscardswrongsa;
+ __le32 rxdiscardswepundecr;
+ __le32 rxmsginmsgfrag;
+ __le32 rxmsginbadmsgfrag;
} __packed;
/*-- Inquiry Frame, Diagnose: Scan Results & Subfields--*/
@@ -711,7 +711,7 @@ struct hfa384x_hscan_result {
#define HFA384x_LINK_ASSOCFAIL ((u16)6)
struct hfa384x_link_status {
- u16 linkstatus;
+ __le16 linkstatus;
} __packed;
/*-- Unsolicited Frame, MAC Mgmt: AssociationStatus (--*/
@@ -733,13 +733,13 @@ struct hfa384x_assoc_status {
struct hfa384x_auth_request {
u8 sta_addr[ETH_ALEN];
- u16 algorithm;
+ __le16 algorithm;
} __packed;
/*-- Unsolicited Frame, MAC Mgmt: PSUserCount (AP Only) --*/
struct hfa384x_ps_user_count {
- u16 usercnt;
+ __le16 usercnt;
} __packed;
struct hfa384x_key_id_changed {
diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c
index ee5fa86..d1e8218 100644
--- a/drivers/staging/wlan-ng/hfa384x_usb.c
+++ b/drivers/staging/wlan-ng/hfa384x_usb.c
@@ -1344,16 +1344,14 @@ hfa384x_docmd(struct hfa384x *hw,
if (result != 0) {
kfree(ctlx);
} else if (mode == DOWAIT) {
- struct usbctlx_cmd_completor completor;
+ struct usbctlx_cmd_completor cmd_completor;
+ struct usbctlx_completor *completor;
- result =
- hfa384x_usbctlx_complete_sync(hw, ctlx,
- init_cmd_completor(&completor,
- &ctlx->
- inbuf.
- cmdresp,
- &cmd->
- result));
+ completor = init_cmd_completor(&cmd_completor,
+ &ctlx->inbuf.cmdresp,
+ &cmd->result);
+
+ result = hfa384x_usbctlx_complete_sync(hw, ctlx, completor);
}
done:
diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c
index fc8ad33..c1b6d42 100644
--- a/drivers/staging/wlan-ng/p80211conv.c
+++ b/drivers/staging/wlan-ng/p80211conv.c
@@ -213,6 +213,7 @@ int skb_ether_to_p80211(struct wlandevice *wlandev, u32 ethconv,
netdev_warn(wlandev->netdev,
"Host en-WEP failed, dropping frame (%d).\n",
foo);
+ kfree(p80211_wep->data);
return 2;
}
fc |= cpu_to_le16(WLAN_SET_FC_ISWEP(1));
diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c
index 021fb23..0f50365 100644
--- a/drivers/staging/wlan-ng/p80211netdev.c
+++ b/drivers/staging/wlan-ng/p80211netdev.c
@@ -258,7 +258,7 @@ static int p80211_convert_to_ether(struct wlandevice *wlandev,
return 0;
}
- netdev_dbg(wlandev->netdev, "p80211_convert_to_ether failed.\n");
+ netdev_dbg(wlandev->netdev, "%s failed.\n", __func__);
return CONV_TO_ETHER_FAILED;
}
diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c
index 1a0c786..344bec8 100644
--- a/drivers/staging/wlan-ng/prism2fw.c
+++ b/drivers/staging/wlan-ng/prism2fw.c
@@ -1016,7 +1016,8 @@ static int writeimage(struct wlandevice *wlandev, struct imgchunk *fchunk,
kfree(rstmsg);
kfree(rwrmsg);
netdev_err(wlandev->netdev,
- "writeimage: no memory for firmware download, aborting download\n");
+ "%s: no memory for firmware download, aborting download\n",
+ __func__);
return -ENOMEM;
}
@@ -1058,15 +1059,15 @@ static int writeimage(struct wlandevice *wlandev, struct imgchunk *fchunk,
result = prism2mgmt_ramdl_state(wlandev, rstmsg);
if (result) {
netdev_err(wlandev->netdev,
- "writeimage state enable failed w/ result=%d, aborting download\n",
- result);
+ "%s state enable failed w/ result=%d, aborting download\n",
+ __func__, result);
goto free_result;
}
resultcode = rstmsg->resultcode.data;
if (resultcode != P80211ENUM_resultcode_success) {
netdev_err(wlandev->netdev,
- "writeimage()->xxxdl_state msg indicates failure, w/ resultcode=%d, aborting download.\n",
- resultcode);
+ "%s()->xxxdl_state msg indicates failure, w/ resultcode=%d, aborting download.\n",
+ __func__, resultcode);
result = 1;
goto free_result;
}
@@ -1102,14 +1103,14 @@ static int writeimage(struct wlandevice *wlandev, struct imgchunk *fchunk,
/* Check the results */
if (result) {
netdev_err(wlandev->netdev,
- "writeimage chunk write failed w/ result=%d, aborting download\n",
- result);
+ "%s chunk write failed w/ result=%d, aborting download\n",
+ __func__, result);
goto free_result;
}
resultcode = rstmsg->resultcode.data;
if (resultcode != P80211ENUM_resultcode_success) {
- pr_err("writeimage()->xxxdl_write msg indicates failure, w/ resultcode=%d, aborting download.\n",
- resultcode);
+ pr_err("%s()->xxxdl_write msg indicates failure, w/ resultcode=%d, aborting download.\n",
+ __func__, resultcode);
result = 1;
goto free_result;
}
@@ -1124,15 +1125,15 @@ static int writeimage(struct wlandevice *wlandev, struct imgchunk *fchunk,
result = prism2mgmt_ramdl_state(wlandev, rstmsg);
if (result) {
netdev_err(wlandev->netdev,
- "writeimage state disable failed w/ result=%d, aborting download\n",
- result);
+ "%s state disable failed w/ result=%d, aborting download\n",
+ __func__, result);
goto free_result;
}
resultcode = rstmsg->resultcode.data;
if (resultcode != P80211ENUM_resultcode_success) {
netdev_err(wlandev->netdev,
- "writeimage()->xxxdl_state msg indicates failure, w/ resultcode=%d, aborting download.\n",
- resultcode);
+ "%s()->xxxdl_state msg indicates failure, w/ resultcode=%d, aborting download.\n",
+ __func__, resultcode);
result = 1;
goto free_result;
}
diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c
index e16da34..c9df450 100644
--- a/drivers/staging/wlan-ng/prism2sta.c
+++ b/drivers/staging/wlan-ng/prism2sta.c
@@ -991,9 +991,9 @@ static void prism2sta_inf_tallies(struct wlandevice *wlandev,
struct hfa384x_inf_frame *inf)
{
struct hfa384x *hw = wlandev->priv;
- u16 *src16;
+ __le16 *src16;
u32 *dst;
- u32 *src32;
+ __le32 *src32;
int i;
int cnt;
@@ -1005,12 +1005,12 @@ static void prism2sta_inf_tallies(struct wlandevice *wlandev,
cnt = sizeof(struct hfa384x_comm_tallies_32) / sizeof(u32);
if (inf->framelen > 22) {
dst = (u32 *)&hw->tallies;
- src32 = (u32 *)&inf->info.commtallies32;
+ src32 = (__le32 *)&inf->info.commtallies32;
for (i = 0; i < cnt; i++, dst++, src32++)
*dst += le32_to_cpu(*src32);
} else {
dst = (u32 *)&hw->tallies;
- src16 = (u16 *)&inf->info.commtallies16;
+ src16 = (__le16 *)&inf->info.commtallies16;
for (i = 0; i < cnt; i++, dst++, src16++)
*dst += le16_to_cpu(*src16);
}
@@ -1136,7 +1136,7 @@ static void prism2sta_inf_chinforesults(struct wlandevice *wlandev,
unsigned int i, n;
hw->channel_info.results.scanchannels =
- le16_to_cpu(inf->info.chinforesult.scanchannels);
+ inf->info.chinforesult.scanchannels;
for (i = 0, n = 0; i < HFA384x_CHINFORESULT_MAX; i++) {
struct hfa384x_ch_info_result_sub *result;
@@ -1147,16 +1147,16 @@ static void prism2sta_inf_chinforesults(struct wlandevice *wlandev,
continue;
result = &inf->info.chinforesult.result[n];
- chan = le16_to_cpu(result->chid) - 1;
+ chan = result->chid - 1;
if (chan < 0 || chan >= HFA384x_CHINFORESULT_MAX)
continue;
chinforesult = &hw->channel_info.results.result[chan];
chinforesult->chid = chan;
- chinforesult->anl = le16_to_cpu(result->anl);
- chinforesult->pnl = le16_to_cpu(result->pnl);
- chinforesult->active = le16_to_cpu(result->active);
+ chinforesult->anl = result->anl;
+ chinforesult->pnl = result->pnl;
+ chinforesult->active = result->active;
pr_debug("chinfo: channel %d, %s level (avg/peak)=%d/%d dB, pcf %d\n",
chan + 1,
@@ -1447,7 +1447,7 @@ static void prism2sta_inf_linkstatus(struct wlandevice *wlandev,
{
struct hfa384x *hw = wlandev->priv;
- hw->link_status_new = le16_to_cpu(inf->info.linkstatus.linkstatus);
+ hw->link_status_new = inf->info.linkstatus.linkstatus;
schedule_work(&hw->link_bh);
}
@@ -1561,7 +1561,7 @@ static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev,
*/
ether_addr_copy(rec.address, inf->info.authreq.sta_addr);
- rec.status = P80211ENUM_status_unspec_failure;
+ rec.status = cpu_to_le16(P80211ENUM_status_unspec_failure);
/*
* Authenticate based on the access mode.
@@ -1578,7 +1578,7 @@ static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev,
for (i = 0; i < hw->authlist.cnt; i++)
if (ether_addr_equal(rec.address,
hw->authlist.addr[i])) {
- rec.status = P80211ENUM_status_successful;
+ rec.status = cpu_to_le16(P80211ENUM_status_successful);
break;
}
@@ -1590,7 +1590,7 @@ static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev,
* Allow all authentications.
*/
- rec.status = P80211ENUM_status_successful;
+ rec.status = cpu_to_le16(P80211ENUM_status_successful);
break;
case WLAN_ACCESS_ALLOW:
@@ -1615,7 +1615,7 @@ static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev,
for (i = 0; i < cnt; i++, addr += ETH_ALEN)
if (ether_addr_equal(rec.address, addr)) {
- rec.status = P80211ENUM_status_successful;
+ rec.status = cpu_to_le16(P80211ENUM_status_successful);
break;
}
@@ -1641,11 +1641,11 @@ static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev,
addr = hw->deny.addr1[0];
}
- rec.status = P80211ENUM_status_successful;
+ rec.status = cpu_to_le16(P80211ENUM_status_successful);
for (i = 0; i < cnt; i++, addr += ETH_ALEN)
if (ether_addr_equal(rec.address, addr)) {
- rec.status = P80211ENUM_status_unspec_failure;
+ rec.status = cpu_to_le16(P80211ENUM_status_unspec_failure);
break;
}
@@ -1663,7 +1663,7 @@ static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev,
added = 0;
- if (rec.status == P80211ENUM_status_successful) {
+ if (rec.status == cpu_to_le16(P80211ENUM_status_successful)) {
for (i = 0; i < hw->authlist.cnt; i++)
if (ether_addr_equal(rec.address,
hw->authlist.addr[i]))
@@ -1671,7 +1671,7 @@ static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev,
if (i >= hw->authlist.cnt) {
if (hw->authlist.cnt >= WLAN_AUTH_MAX) {
- rec.status = P80211ENUM_status_ap_full;
+ rec.status = cpu_to_le16(P80211ENUM_status_ap_full);
} else {
ether_addr_copy(
hw->authlist.addr[hw->authlist.cnt],
@@ -1688,7 +1688,6 @@ static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev,
* it was added.
*/
- rec.status = cpu_to_le16(rec.status);
rec.algorithm = inf->info.authreq.algorithm;
result = hfa384x_drvr_setconfig(hw, HFA384x_RID_AUTHENTICATESTA,
diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig
index 9510305..873e0ba 100644
--- a/drivers/tty/Kconfig
+++ b/drivers/tty/Kconfig
@@ -392,6 +392,9 @@ config PPC_EARLY_DEBUG_EHV_BC_HANDLE
config GOLDFISH_TTY
tristate "Goldfish TTY Driver"
depends on GOLDFISH
+ select SERIAL_CORE
+ select SERIAL_CORE_CONSOLE
+ select SERIAL_EARLYCON
help
Console and system TTY driver for the Goldfish virtual platform.
diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c
index 61fe8d6..a1c7125 100644
--- a/drivers/tty/ehv_bytechan.c
+++ b/drivers/tty/ehv_bytechan.c
@@ -122,7 +122,7 @@ static int find_console_handle(void)
stdout_irq = irq_of_parse_and_map(np, 0);
if (stdout_irq == NO_IRQ) {
- pr_err("ehv-bc: no 'interrupts' property in %s node\n", np->full_name);
+ pr_err("ehv-bc: no 'interrupts' property in %pOF node\n", np);
return 0;
}
diff --git a/drivers/tty/goldfish.c b/drivers/tty/goldfish.c
index 996bd47..381e981 100644
--- a/drivers/tty/goldfish.c
+++ b/drivers/tty/goldfish.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2007 Google, Inc.
* Copyright (C) 2012 Intel, Inc.
+ * Copyright (C) 2017 Imagination Technologies Ltd.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -22,21 +23,23 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/goldfish.h>
-
-enum {
- GOLDFISH_TTY_PUT_CHAR = 0x00,
- GOLDFISH_TTY_BYTES_READY = 0x04,
- GOLDFISH_TTY_CMD = 0x08,
-
- GOLDFISH_TTY_DATA_PTR = 0x10,
- GOLDFISH_TTY_DATA_LEN = 0x14,
- GOLDFISH_TTY_DATA_PTR_HIGH = 0x18,
-
- GOLDFISH_TTY_CMD_INT_DISABLE = 0,
- GOLDFISH_TTY_CMD_INT_ENABLE = 1,
- GOLDFISH_TTY_CMD_WRITE_BUFFER = 2,
- GOLDFISH_TTY_CMD_READ_BUFFER = 3,
-};
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
+#include <linux/serial_core.h>
+
+/* Goldfish tty register's offsets */
+#define GOLDFISH_TTY_REG_BYTES_READY 0x04
+#define GOLDFISH_TTY_REG_CMD 0x08
+#define GOLDFISH_TTY_REG_DATA_PTR 0x10
+#define GOLDFISH_TTY_REG_DATA_LEN 0x14
+#define GOLDFISH_TTY_REG_DATA_PTR_HIGH 0x18
+#define GOLDFISH_TTY_REG_VERSION 0x20
+
+/* Goldfish tty commands */
+#define GOLDFISH_TTY_CMD_INT_DISABLE 0
+#define GOLDFISH_TTY_CMD_INT_ENABLE 1
+#define GOLDFISH_TTY_CMD_WRITE_BUFFER 2
+#define GOLDFISH_TTY_CMD_READ_BUFFER 3
struct goldfish_tty {
struct tty_port port;
@@ -45,6 +48,8 @@ struct goldfish_tty {
u32 irq;
int opencount;
struct console console;
+ u32 version;
+ struct device *dev;
};
static DEFINE_MUTEX(goldfish_tty_lock);
@@ -53,38 +58,107 @@ static u32 goldfish_tty_line_count = 8;
static u32 goldfish_tty_current_line_count;
static struct goldfish_tty *goldfish_ttys;
-static void goldfish_tty_do_write(int line, const char *buf, unsigned count)
+static void do_rw_io(struct goldfish_tty *qtty,
+ unsigned long address,
+ unsigned int count,
+ int is_write)
{
unsigned long irq_flags;
- struct goldfish_tty *qtty = &goldfish_ttys[line];
void __iomem *base = qtty->base;
+
spin_lock_irqsave(&qtty->lock, irq_flags);
- gf_write_ptr(buf, base + GOLDFISH_TTY_DATA_PTR,
- base + GOLDFISH_TTY_DATA_PTR_HIGH);
- writel(count, base + GOLDFISH_TTY_DATA_LEN);
- writel(GOLDFISH_TTY_CMD_WRITE_BUFFER, base + GOLDFISH_TTY_CMD);
+ gf_write_ptr((void *)address, base + GOLDFISH_TTY_REG_DATA_PTR,
+ base + GOLDFISH_TTY_REG_DATA_PTR_HIGH);
+ writel(count, base + GOLDFISH_TTY_REG_DATA_LEN);
+
+ if (is_write)
+ writel(GOLDFISH_TTY_CMD_WRITE_BUFFER,
+ base + GOLDFISH_TTY_REG_CMD);
+ else
+ writel(GOLDFISH_TTY_CMD_READ_BUFFER,
+ base + GOLDFISH_TTY_REG_CMD);
+
spin_unlock_irqrestore(&qtty->lock, irq_flags);
}
+static void goldfish_tty_rw(struct goldfish_tty *qtty,
+ unsigned long addr,
+ unsigned int count,
+ int is_write)
+{
+ dma_addr_t dma_handle;
+ enum dma_data_direction dma_dir;
+
+ dma_dir = (is_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+ if (qtty->version > 0) {
+ /*
+ * Goldfish TTY for Ranchu platform uses
+ * physical addresses and DMA for read/write operations
+ */
+ unsigned long addr_end = addr + count;
+
+ while (addr < addr_end) {
+ unsigned long pg_end = (addr & PAGE_MASK) + PAGE_SIZE;
+ unsigned long next =
+ pg_end < addr_end ? pg_end : addr_end;
+ unsigned long avail = next - addr;
+
+ /*
+ * Map the buffer's virtual address to the DMA address
+ * so the buffer can be accessed by the device.
+ */
+ dma_handle = dma_map_single(qtty->dev, (void *)addr,
+ avail, dma_dir);
+
+ if (dma_mapping_error(qtty->dev, dma_handle)) {
+ dev_err(qtty->dev, "tty: DMA mapping error.\n");
+ return;
+ }
+ do_rw_io(qtty, dma_handle, avail, is_write);
+
+ /*
+ * Unmap the previously mapped region after
+ * the completion of the read/write operation.
+ */
+ dma_unmap_single(qtty->dev, dma_handle, avail, dma_dir);
+
+ addr += avail;
+ }
+ } else {
+ /*
+ * Old style Goldfish TTY used on the Goldfish platform
+ * uses virtual addresses.
+ */
+ do_rw_io(qtty, addr, count, is_write);
+ }
+}
+
+static void goldfish_tty_do_write(int line, const char *buf,
+ unsigned int count)
+{
+ struct goldfish_tty *qtty = &goldfish_ttys[line];
+ unsigned long address = (unsigned long)(void *)buf;
+
+ goldfish_tty_rw(qtty, address, count, 1);
+}
+
static irqreturn_t goldfish_tty_interrupt(int irq, void *dev_id)
{
struct goldfish_tty *qtty = dev_id;
void __iomem *base = qtty->base;
- unsigned long irq_flags;
+ unsigned long address;
unsigned char *buf;
u32 count;
- count = readl(base + GOLDFISH_TTY_BYTES_READY);
+ count = readl(base + GOLDFISH_TTY_REG_BYTES_READY);
if (count == 0)
return IRQ_NONE;
count = tty_prepare_flip_string(&qtty->port, &buf, count);
- spin_lock_irqsave(&qtty->lock, irq_flags);
- gf_write_ptr(buf, base + GOLDFISH_TTY_DATA_PTR,
- base + GOLDFISH_TTY_DATA_PTR_HIGH);
- writel(count, base + GOLDFISH_TTY_DATA_LEN);
- writel(GOLDFISH_TTY_CMD_READ_BUFFER, base + GOLDFISH_TTY_CMD);
- spin_unlock_irqrestore(&qtty->lock, irq_flags);
+
+ address = (unsigned long)(void *)buf;
+ goldfish_tty_rw(qtty, address, count, 0);
+
tty_schedule_flip(&qtty->port);
return IRQ_HANDLED;
}
@@ -93,7 +167,7 @@ static int goldfish_tty_activate(struct tty_port *port, struct tty_struct *tty)
{
struct goldfish_tty *qtty = container_of(port, struct goldfish_tty,
port);
- writel(GOLDFISH_TTY_CMD_INT_ENABLE, qtty->base + GOLDFISH_TTY_CMD);
+ writel(GOLDFISH_TTY_CMD_INT_ENABLE, qtty->base + GOLDFISH_TTY_REG_CMD);
return 0;
}
@@ -101,7 +175,7 @@ static void goldfish_tty_shutdown(struct tty_port *port)
{
struct goldfish_tty *qtty = container_of(port, struct goldfish_tty,
port);
- writel(GOLDFISH_TTY_CMD_INT_DISABLE, qtty->base + GOLDFISH_TTY_CMD);
+ writel(GOLDFISH_TTY_CMD_INT_DISABLE, qtty->base + GOLDFISH_TTY_REG_CMD);
}
static int goldfish_tty_open(struct tty_struct *tty, struct file *filp)
@@ -136,7 +210,7 @@ static int goldfish_tty_chars_in_buffer(struct tty_struct *tty)
{
struct goldfish_tty *qtty = &goldfish_ttys[tty->index];
void __iomem *base = qtty->base;
- return readl(base + GOLDFISH_TTY_BYTES_READY);
+ return readl(base + GOLDFISH_TTY_REG_BYTES_READY);
}
static void goldfish_tty_console_write(struct console *co, const char *b,
@@ -227,7 +301,7 @@ static void goldfish_tty_delete_driver(void)
static int goldfish_tty_probe(struct platform_device *pdev)
{
struct goldfish_tty *qtty;
- int ret = -EINVAL;
+ int ret = -ENODEV;
struct resource *r;
struct device *ttydev;
void __iomem *base;
@@ -235,16 +309,22 @@ static int goldfish_tty_probe(struct platform_device *pdev)
unsigned int line;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (r == NULL)
- return -EINVAL;
+ if (!r) {
+ pr_err("goldfish_tty: No MEM resource available!\n");
+ return -ENOMEM;
+ }
base = ioremap(r->start, 0x1000);
- if (base == NULL)
- pr_err("goldfish_tty: unable to remap base\n");
+ if (!base) {
+ pr_err("goldfish_tty: Unable to ioremap base!\n");
+ return -ENOMEM;
+ }
r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (r == NULL)
+ if (!r) {
+ pr_err("goldfish_tty: No IRQ resource available!\n");
goto err_unmap;
+ }
irq = r->start;
@@ -255,13 +335,17 @@ static int goldfish_tty_probe(struct platform_device *pdev)
else
line = pdev->id;
- if (line >= goldfish_tty_line_count)
- goto err_create_driver_failed;
+ if (line >= goldfish_tty_line_count) {
+ pr_err("goldfish_tty: Reached maximum tty number of %d.\n",
+ goldfish_tty_current_line_count);
+ ret = -ENOMEM;
+ goto err_unlock;
+ }
if (goldfish_tty_current_line_count == 0) {
ret = goldfish_tty_create_driver();
if (ret)
- goto err_create_driver_failed;
+ goto err_unlock;
}
goldfish_tty_current_line_count++;
@@ -271,17 +355,45 @@ static int goldfish_tty_probe(struct platform_device *pdev)
qtty->port.ops = &goldfish_port_ops;
qtty->base = base;
qtty->irq = irq;
+ qtty->dev = &pdev->dev;
+
+ /*
+ * Goldfish TTY device used by the Goldfish emulator
+ * should identify itself with 0, forcing the driver
+ * to use virtual addresses. Goldfish TTY device
+ * on Ranchu emulator (qemu2) returns 1 here and
+ * driver will use physical addresses.
+ */
+ qtty->version = readl(base + GOLDFISH_TTY_REG_VERSION);
+
+ /*
+ * Goldfish TTY device on Ranchu emulator (qemu2)
+ * will use DMA for read/write IO operations.
+ */
+ if (qtty->version > 0) {
+ /*
+ * Initialize dma_mask to 32-bits.
+ */
+ if (!pdev->dev.dma_mask)
+ pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+ ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
+ if (ret) {
+ dev_err(&pdev->dev, "No suitable DMA available.\n");
+ goto err_dec_line_count;
+ }
+ }
- writel(GOLDFISH_TTY_CMD_INT_DISABLE, base + GOLDFISH_TTY_CMD);
+ writel(GOLDFISH_TTY_CMD_INT_DISABLE, base + GOLDFISH_TTY_REG_CMD);
ret = request_irq(irq, goldfish_tty_interrupt, IRQF_SHARED,
- "goldfish_tty", qtty);
- if (ret)
- goto err_request_irq_failed;
-
+ "goldfish_tty", qtty);
+ if (ret) {
+ pr_err("goldfish_tty: No IRQ available!\n");
+ goto err_dec_line_count;
+ }
ttydev = tty_port_register_device(&qtty->port, goldfish_tty_driver,
- line, &pdev->dev);
+ line, &pdev->dev);
if (IS_ERR(ttydev)) {
ret = PTR_ERR(ttydev);
goto err_tty_register_device_failed;
@@ -301,11 +413,11 @@ static int goldfish_tty_probe(struct platform_device *pdev)
err_tty_register_device_failed:
free_irq(irq, qtty);
-err_request_irq_failed:
+err_dec_line_count:
goldfish_tty_current_line_count--;
if (goldfish_tty_current_line_count == 0)
goldfish_tty_delete_driver();
-err_create_driver_failed:
+err_unlock:
mutex_unlock(&goldfish_tty_lock);
err_unmap:
iounmap(base);
@@ -330,6 +442,30 @@ static int goldfish_tty_remove(struct platform_device *pdev)
return 0;
}
+static void gf_early_console_putchar(struct uart_port *port, int ch)
+{
+ __raw_writel(ch, port->membase);
+}
+
+static void gf_early_write(struct console *con, const char *s, unsigned int n)
+{
+ struct earlycon_device *dev = con->data;
+
+ uart_console_write(&dev->port, s, n, gf_early_console_putchar);
+}
+
+static int __init gf_earlycon_setup(struct earlycon_device *device,
+ const char *opt)
+{
+ if (!device->port.membase)
+ return -ENODEV;
+
+ device->con->write = gf_early_write;
+ return 0;
+}
+
+OF_EARLYCON_DECLARE(early_gf_tty, "google,goldfish-tty", gf_earlycon_setup);
+
static const struct of_device_id goldfish_tty_of_match[] = {
{ .compatible = "google,goldfish-tty", },
{},
diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig
index b8d5ea0..fec457e 100644
--- a/drivers/tty/hvc/Kconfig
+++ b/drivers/tty/hvc/Kconfig
@@ -4,7 +4,7 @@ config HVC_DRIVER
bool
help
Generic "hypervisor virtual console" infrastructure for various
- hypervisors (pSeries, iSeries, Xen, lguest).
+ hypervisors (pSeries, iSeries, Xen).
It will automatically be selected if one of the back-end console drivers
is selected.
diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c
index 5107993..16331a9 100644
--- a/drivers/tty/hvc/hvc_opal.c
+++ b/drivers/tty/hvc/hvc_opal.c
@@ -179,8 +179,8 @@ static int hvc_opal_probe(struct platform_device *dev)
proto = HV_PROTOCOL_HVSI;
ops = &hvc_opal_hvsi_ops;
} else {
- pr_err("hvc_opal: Unknown protocol for %s\n",
- dev->dev.of_node->full_name);
+ pr_err("hvc_opal: Unknown protocol for %pOF\n",
+ dev->dev.of_node);
return -ENXIO;
}
@@ -204,14 +204,14 @@ static int hvc_opal_probe(struct platform_device *dev)
/* Instanciate now to establish a mapping index==vtermno */
hvc_instantiate(termno, termno, ops);
} else {
- pr_err("hvc_opal: Device %s has duplicate terminal number #%d\n",
- dev->dev.of_node->full_name, termno);
+ pr_err("hvc_opal: Device %pOF has duplicate terminal number #%d\n",
+ dev->dev.of_node, termno);
return -ENXIO;
}
- pr_info("hvc%d: %s protocol on %s%s\n", termno,
+ pr_info("hvc%d: %s protocol on %pOF%s\n", termno,
proto == HV_PROTOCOL_RAW ? "raw" : "hvsi",
- dev->dev.of_node->full_name,
+ dev->dev.of_node,
boot ? " (boot console)" : "");
irq = irq_of_parse_and_map(dev->dev.of_node, 0);
@@ -222,8 +222,8 @@ static int hvc_opal_probe(struct platform_device *dev)
}
if (!irq) {
- pr_err("hvc_opal: Unable to map interrupt for device %s\n",
- dev->dev.of_node->full_name);
+ pr_err("hvc_opal: Unable to map interrupt for device %pOF\n",
+ dev->dev.of_node);
return irq;
}
diff --git a/drivers/tty/hvc/hvc_vio.c b/drivers/tty/hvc/hvc_vio.c
index b05dc50..653f9927 100644
--- a/drivers/tty/hvc/hvc_vio.c
+++ b/drivers/tty/hvc/hvc_vio.c
@@ -53,7 +53,7 @@
static const char hvc_driver_name[] = "hvc_console";
-static struct vio_device_id hvc_driver_table[] = {
+static const struct vio_device_id hvc_driver_table[] = {
{"serial", "hvterm1"},
#ifndef HVC_OLD_HVSI
{"serial", "hvterm-protocol"},
@@ -312,12 +312,12 @@ static int hvc_vio_probe(struct vio_dev *vdev,
proto = HV_PROTOCOL_HVSI;
ops = &hvterm_hvsi_ops;
} else {
- pr_err("hvc_vio: Unknown protocol for %s\n", vdev->dev.of_node->full_name);
+ pr_err("hvc_vio: Unknown protocol for %pOF\n", vdev->dev.of_node);
return -ENXIO;
}
- pr_devel("hvc_vio_probe() device %s, using %s protocol\n",
- vdev->dev.of_node->full_name,
+ pr_devel("hvc_vio_probe() device %pOF, using %s protocol\n",
+ vdev->dev.of_node,
proto == HV_PROTOCOL_RAW ? "raw" : "hvsi");
/* Is it our boot one ? */
diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c
index 79cc5be..63c29fe 100644
--- a/drivers/tty/hvc/hvcs.c
+++ b/drivers/tty/hvc/hvcs.c
@@ -189,7 +189,7 @@ MODULE_VERSION(HVCS_DRIVER_VERSION);
* that will cause echoing or we'll go into recursive loop echoing chars back
* and forth with the console drivers.
*/
-static struct ktermios hvcs_tty_termios = {
+static const struct ktermios hvcs_tty_termios = {
.c_iflag = IGNBRK | IGNPAR,
.c_oflag = OPOST,
.c_cflag = B38400 | CS8 | CREAD | HUPCL,
@@ -675,7 +675,7 @@ static int khvcsd(void *unused)
return 0;
}
-static struct vio_device_id hvcs_driver_table[] = {
+static const struct vio_device_id hvcs_driver_table[] = {
{"serial-server", "hvterm2"},
{ "", "" }
};
diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c
index b70187b..61ecdd6 100644
--- a/drivers/tty/isicom.c
+++ b/drivers/tty/isicom.c
@@ -150,7 +150,7 @@
static int isicom_probe(struct pci_dev *, const struct pci_device_id *);
static void isicom_remove(struct pci_dev *);
-static struct pci_device_id isicom_pci_tbl[] = {
+static const struct pci_device_id isicom_pci_tbl[] = {
{ PCI_DEVICE(VENDOR_ID, 0x2028) },
{ PCI_DEVICE(VENDOR_ID, 0x2051) },
{ PCI_DEVICE(VENDOR_ID, 0x2052) },
diff --git a/drivers/tty/mips_ejtag_fdc.c b/drivers/tty/mips_ejtag_fdc.c
index 234123b..a2dab3f 100644
--- a/drivers/tty/mips_ejtag_fdc.c
+++ b/drivers/tty/mips_ejtag_fdc.c
@@ -1110,7 +1110,7 @@ out:
return ret;
}
-static struct mips_cdmm_device_id mips_ejtag_fdc_tty_ids[] = {
+static const struct mips_cdmm_device_id mips_ejtag_fdc_tty_ids[] = {
{ .type = 0xfd },
{ }
};
diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c
index 3b251f4e..7f3d4cb 100644
--- a/drivers/tty/moxa.c
+++ b/drivers/tty/moxa.c
@@ -88,7 +88,7 @@ static char *moxa_brdname[] =
};
#ifdef CONFIG_PCI
-static struct pci_device_id moxa_pcibrds[] = {
+static const struct pci_device_id moxa_pcibrds[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C218),
.driver_data = MOXA_BOARD_C218_PCI },
{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C320),
diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c
index 8bd6fb6..1c0c955 100644
--- a/drivers/tty/mxser.c
+++ b/drivers/tty/mxser.c
@@ -145,7 +145,7 @@ static const struct mxser_cardinfo mxser_cards[] = {
/* driver_data correspond to the lines in the structure above
see also ISA probe function before you change something */
-static struct pci_device_id mxser_pcibrds[] = {
+static const struct pci_device_id mxser_pcibrds[] = {
{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C168), .driver_data = 3 },
{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C104), .driver_data = 4 },
{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132), .driver_data = 8 },
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 2afe5fc..0a3c966 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -2607,6 +2607,14 @@ static int gsmld_ioctl(struct tty_struct *tty, struct file *file,
}
}
+#ifdef CONFIG_COMPAT
+static long gsmld_compat_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ return gsmld_ioctl(tty, file, cmd, arg);
+}
+#endif
+
/*
* Network interface
*
@@ -2818,6 +2826,9 @@ static struct tty_ldisc_ops tty_ldisc_packet = {
.flush_buffer = gsmld_flush_buffer,
.read = gsmld_read,
.write = gsmld_write,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = gsmld_compat_ioctl,
+#endif
.ioctl = gsmld_ioctl,
.poll = gsmld_poll,
.receive_buf = gsmld_receive_buf,
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
index a6d5164..26dcb3b 100644
--- a/drivers/tty/pty.c
+++ b/drivers/tty/pty.c
@@ -742,6 +742,11 @@ static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty)
}
}
+static void pty_show_fdinfo(struct tty_struct *tty, struct seq_file *m)
+{
+ seq_printf(m, "tty-index:\t%d\n", tty->index);
+}
+
static const struct tty_operations ptm_unix98_ops = {
.lookup = ptm_unix98_lookup,
.install = pty_unix98_install,
@@ -756,7 +761,8 @@ static const struct tty_operations ptm_unix98_ops = {
.ioctl = pty_unix98_ioctl,
.compat_ioctl = pty_unix98_compat_ioctl,
.resize = pty_resize,
- .cleanup = pty_cleanup
+ .cleanup = pty_cleanup,
+ .show_fdinfo = pty_show_fdinfo,
};
static const struct tty_operations pty_unix98_ops = {
diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index ae1aaa0..c68fb3a 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -363,7 +363,7 @@ static int of_serdev_register_devices(struct serdev_controller *ctrl)
if (!of_get_property(node, "compatible", NULL))
continue;
- dev_dbg(&ctrl->dev, "adding child %s\n", node->full_name);
+ dev_dbg(&ctrl->dev, "adding child %pOF\n", node);
serdev = serdev_device_alloc(ctrl);
if (!serdev)
diff --git a/drivers/tty/serial/21285.c b/drivers/tty/serial/21285.c
index 9b208bd..804632b 100644
--- a/drivers/tty/serial/21285.c
+++ b/drivers/tty/serial/21285.c
@@ -334,7 +334,7 @@ static int serial21285_verify_port(struct uart_port *port, struct serial_struct
return ret;
}
-static struct uart_ops serial21285_ops = {
+static const struct uart_ops serial21285_ops = {
.tx_empty = serial21285_tx_empty,
.get_mctrl = serial21285_get_mctrl,
.set_mctrl = serial21285_set_mctrl,
diff --git a/drivers/tty/serial/8250/8250_aspeed_vuart.c b/drivers/tty/serial/8250/8250_aspeed_vuart.c
index 822be49..33a8013 100644
--- a/drivers/tty/serial/8250/8250_aspeed_vuart.c
+++ b/drivers/tty/serial/8250/8250_aspeed_vuart.c
@@ -223,12 +223,13 @@ static int aspeed_vuart_probe(struct platform_device *pdev)
if (IS_ERR(vuart->clk)) {
dev_warn(&pdev->dev,
"clk or clock-frequency not defined\n");
- return PTR_ERR(vuart->clk);
+ rc = PTR_ERR(vuart->clk);
+ goto err_sysfs_remove;
}
rc = clk_prepare_enable(vuart->clk);
if (rc < 0)
- return rc;
+ goto err_sysfs_remove;
clk = clk_get_rate(vuart->clk);
}
@@ -286,6 +287,8 @@ static int aspeed_vuart_probe(struct platform_device *pdev)
err_clk_disable:
clk_disable_unprepare(vuart->clk);
irq_dispose_mapping(port.port.irq);
+err_sysfs_remove:
+ sysfs_remove_group(&vuart->dev->kobj, &aspeed_vuart_attr_group);
return rc;
}
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index 1aab301..d29b512a 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -497,6 +497,11 @@ static void univ8250_rsa_support(struct uart_ops *ops)
#define univ8250_rsa_support(x) do { } while (0)
#endif /* CONFIG_SERIAL_8250_RSA */
+static inline void serial8250_apply_quirks(struct uart_8250_port *up)
+{
+ up->port.quirks |= skip_txen_test ? UPQ_NO_TXEN_TEST : 0;
+}
+
static void __init serial8250_isa_init_ports(void)
{
struct uart_8250_port *up;
@@ -577,9 +582,7 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev)
up->port.dev = dev;
- if (skip_txen_test)
- up->port.flags |= UPF_NO_TXEN_TEST;
-
+ serial8250_apply_quirks(up);
uart_add_one_port(drv, &up->port);
}
}
@@ -1006,9 +1009,6 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
if (up->port.dev)
uart->port.dev = up->port.dev;
- if (skip_txen_test)
- uart->port.flags |= UPF_NO_TXEN_TEST;
-
if (up->port.flags & UPF_FIXED_TYPE)
uart->port.type = up->port.type;
@@ -1048,6 +1048,7 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
serial8250_isa_config(0, &uart->port,
&uart->capabilities);
+ serial8250_apply_quirks(uart);
ret = uart_add_one_port(&serial8250_reg,
&uart->port);
if (ret == 0)
@@ -1092,11 +1093,10 @@ void serial8250_unregister_port(int line)
uart_remove_one_port(&serial8250_reg, &uart->port);
if (serial8250_isa_devs) {
uart->port.flags &= ~UPF_BOOT_AUTOCONF;
- if (skip_txen_test)
- uart->port.flags |= UPF_NO_TXEN_TEST;
uart->port.type = PORT_UNKNOWN;
uart->port.dev = &serial8250_isa_devs->dev;
uart->capabilities = 0;
+ serial8250_apply_quirks(uart);
uart_add_one_port(&serial8250_reg, &uart->port);
} else {
uart->port.dev = NULL;
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index 787b116..7e63899 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -529,7 +529,7 @@ static int dw8250_probe(struct platform_device *pdev)
}
}
- data->rst = devm_reset_control_get_optional(dev, NULL);
+ data->rst = devm_reset_control_get_optional_exclusive(dev, NULL);
if (IS_ERR(data->rst)) {
err = PTR_ERR(data->rst);
goto err_pclk;
diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c
index 82fc48e..af72ec3 100644
--- a/drivers/tty/serial/8250/8250_early.c
+++ b/drivers/tty/serial/8250/8250_early.c
@@ -37,7 +37,7 @@
#include <asm/io.h>
#include <asm/serial.h>
-static unsigned int __init serial8250_early_in(struct uart_port *port, int offset)
+static unsigned int serial8250_early_in(struct uart_port *port, int offset)
{
int reg_offset = offset;
offset <<= port->regshift;
@@ -60,7 +60,7 @@ static unsigned int __init serial8250_early_in(struct uart_port *port, int offse
}
}
-static void __init serial8250_early_out(struct uart_port *port, int offset, int value)
+static void serial8250_early_out(struct uart_port *port, int offset, int value)
{
int reg_offset = offset;
offset <<= port->regshift;
@@ -89,7 +89,7 @@ static void __init serial8250_early_out(struct uart_port *port, int offset, int
#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
-static void __init serial_putc(struct uart_port *port, int c)
+static void serial_putc(struct uart_port *port, int c)
{
unsigned int status;
@@ -103,7 +103,7 @@ static void __init serial_putc(struct uart_port *port, int c)
}
}
-static void __init early_serial8250_write(struct console *console,
+static void early_serial8250_write(struct console *console,
const char *s, unsigned int count)
{
struct earlycon_device *device = console->data;
diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c
index c6360fb..c556247 100644
--- a/drivers/tty/serial/8250/8250_exar.c
+++ b/drivers/tty/serial/8250/8250_exar.c
@@ -601,7 +601,7 @@ static const struct exar8250_board pbn_exar_XR17V8358 = {
(kernel_ulong_t)&bd \
}
-static struct pci_device_id exar_pci_tbl[] = {
+static const struct pci_device_id exar_pci_tbl[] = {
CONNECT_DEVICE(XR17C152, UART_2_232, pbn_connect),
CONNECT_DEVICE(XR17C154, UART_4_232, pbn_connect),
CONNECT_DEVICE(XR17C158, UART_8_232, pbn_connect),
diff --git a/drivers/tty/serial/8250/8250_gsc.c b/drivers/tty/serial/8250/8250_gsc.c
index 63306de..df2931e 100644
--- a/drivers/tty/serial/8250/8250_gsc.c
+++ b/drivers/tty/serial/8250/8250_gsc.c
@@ -80,7 +80,7 @@ static int __init serial_init_chip(struct parisc_device *dev)
return 0;
}
-static struct parisc_device_id serial_tbl[] = {
+static const struct parisc_device_id serial_tbl[] __initconst = {
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00075 },
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008c },
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008d },
@@ -94,7 +94,7 @@ static struct parisc_device_id serial_tbl[] = {
* which only knows about Lasi and then a second which will find all the
* other serial ports. HPUX ignores this problem.
*/
-static struct parisc_device_id lasi_tbl[] = {
+static const struct parisc_device_id lasi_tbl[] __initconst = {
{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03B, 0x0008C }, /* C1xx/C1xxL */
{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03C, 0x0008C }, /* B132L */
{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03D, 0x0008C }, /* B160L */
@@ -110,13 +110,13 @@ static struct parisc_device_id lasi_tbl[] = {
MODULE_DEVICE_TABLE(parisc, serial_tbl);
-static struct parisc_driver lasi_driver = {
+static struct parisc_driver lasi_driver __refdata = {
.name = "serial_1",
.id_table = lasi_tbl,
.probe = serial_init_chip,
};
-static struct parisc_driver serial_driver = {
+static struct parisc_driver serial_driver __refdata = {
.name = "serial",
.id_table = serial_tbl,
.probe = serial_init_chip,
diff --git a/drivers/tty/serial/8250/8250_ingenic.c b/drivers/tty/serial/8250/8250_ingenic.c
index 4d9dc10..464389b 100644
--- a/drivers/tty/serial/8250/8250_ingenic.c
+++ b/drivers/tty/serial/8250/8250_ingenic.c
@@ -50,17 +50,17 @@ static const struct of_device_id of_match[];
static struct earlycon_device *early_device;
-static uint8_t __init early_in(struct uart_port *port, int offset)
+static uint8_t early_in(struct uart_port *port, int offset)
{
return readl(port->membase + (offset << 2));
}
-static void __init early_out(struct uart_port *port, int offset, uint8_t value)
+static void early_out(struct uart_port *port, int offset, uint8_t value)
{
writel(value, port->membase + (offset << 2));
}
-static void __init ingenic_early_console_putc(struct uart_port *port, int c)
+static void ingenic_early_console_putc(struct uart_port *port, int c)
{
uint8_t lsr;
@@ -71,7 +71,7 @@ static void __init ingenic_early_console_putc(struct uart_port *port, int c)
early_out(port, UART_TX, c);
}
-static void __init ingenic_early_console_write(struct console *console,
+static void ingenic_early_console_write(struct console *console,
const char *s, unsigned int count)
{
uart_console_write(&early_device->port, s, count,
diff --git a/drivers/tty/serial/8250/8250_men_mcb.c b/drivers/tty/serial/8250/8250_men_mcb.c
new file mode 100644
index 0000000..3089778
--- /dev/null
+++ b/drivers/tty/serial/8250/8250_men_mcb.c
@@ -0,0 +1,118 @@
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mcb.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+#include <uapi/linux/serial_core.h>
+
+struct serial_8250_men_mcb_data {
+ struct uart_8250_port uart;
+ int line;
+};
+
+/*
+ * The Z125 16550-compatible UART has no fixed base clock assigned
+ * So, depending on the board we're on, we need to adjust the
+ * parameter in order to really set the correct baudrate, and
+ * do so if possible without user interaction
+ */
+static u32 men_z125_lookup_uartclk(struct mcb_device *mdev)
+{
+ /* use default value if board is not available below */
+ u32 clkval = 1041666;
+
+ dev_info(&mdev->dev, "%s on board %s\n",
+ dev_name(&mdev->dev),
+ mdev->bus->name);
+ if (strncmp(mdev->bus->name, "F075", 4) == 0)
+ clkval = 1041666;
+ else if (strncmp(mdev->bus->name, "F216", 4) == 0)
+ clkval = 1843200;
+ else if (strncmp(mdev->bus->name, "G215", 4) == 0)
+ clkval = 1843200;
+ else
+ dev_info(&mdev->dev,
+ "board not detected, using default uartclk\n");
+
+ clkval = clkval << 4;
+
+ return clkval;
+}
+
+static int serial_8250_men_mcb_probe(struct mcb_device *mdev,
+ const struct mcb_device_id *id)
+{
+ struct serial_8250_men_mcb_data *data;
+ struct resource *mem;
+
+ data = devm_kzalloc(&mdev->dev,
+ sizeof(struct serial_8250_men_mcb_data),
+ GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ mcb_set_drvdata(mdev, data);
+ data->uart.port.dev = mdev->dma_dev;
+ spin_lock_init(&data->uart.port.lock);
+
+ data->uart.port.type = PORT_16550;
+ data->uart.port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE;
+ data->uart.port.iotype = UPIO_MEM;
+ data->uart.port.uartclk = men_z125_lookup_uartclk(mdev);
+ data->uart.port.regshift = 0;
+ data->uart.port.fifosize = 60;
+
+ mem = mcb_get_resource(mdev, IORESOURCE_MEM);
+ if (mem == NULL)
+ return -ENXIO;
+
+ data->uart.port.irq = mcb_get_irq(mdev);
+
+ data->uart.port.membase = devm_ioremap_resource(&mdev->dev, mem);
+ if (IS_ERR(data->uart.port.membase))
+ return PTR_ERR_OR_ZERO(data->uart.port.membase);
+
+ data->uart.port.mapbase = (unsigned long) mem->start;
+ data->uart.port.iobase = data->uart.port.mapbase;
+
+ /* ok, register the port */
+ data->line = serial8250_register_8250_port(&data->uart);
+ if (data->line < 0)
+ return data->line;
+
+ dev_info(&mdev->dev, "found 16Z125 UART: ttyS%d\n", data->line);
+
+ return 0;
+}
+
+static void serial_8250_men_mcb_remove(struct mcb_device *mdev)
+{
+ struct serial_8250_men_mcb_data *data = mcb_get_drvdata(mdev);
+
+ if (data)
+ serial8250_unregister_port(data->line);
+}
+
+static const struct mcb_device_id serial_8250_men_mcb_ids[] = {
+ { .device = 0x7d },
+ { }
+};
+MODULE_DEVICE_TABLE(mcb, serial_8250_men_mcb_ids);
+
+static struct mcb_driver mcb_driver = {
+ .driver = {
+ .name = "8250_men_mcb",
+ .owner = THIS_MODULE,
+ },
+ .probe = serial_8250_men_mcb_probe,
+ .remove = serial_8250_men_mcb_remove,
+ .id_table = serial_8250_men_mcb_ids,
+};
+module_mcb_driver(mcb_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MEN 16z125 8250 UART driver");
+MODULE_AUTHOR("Michael Moese <michael.moese@men.de");
+MODULE_ALIAS("mcb:16z125");
diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c
index ce0cc47..fb45770 100644
--- a/drivers/tty/serial/8250/8250_mtk.c
+++ b/drivers/tty/serial/8250/8250_mtk.c
@@ -171,10 +171,7 @@ static int mtk8250_probe_of(struct platform_device *pdev, struct uart_port *p,
}
data->bus_clk = devm_clk_get(&pdev->dev, "bus");
- if (IS_ERR(data->bus_clk))
- return PTR_ERR(data->bus_clk);
-
- return 0;
+ return PTR_ERR_OR_ZERO(data->bus_clk);
}
static int mtk8250_probe(struct platform_device *pdev)
diff --git a/drivers/tty/serial/8250/8250_of.c b/drivers/tty/serial/8250/8250_of.c
index 0cf95fd..1222c00 100644
--- a/drivers/tty/serial/8250/8250_of.c
+++ b/drivers/tty/serial/8250/8250_of.c
@@ -18,6 +18,7 @@
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
+#include <linux/pm_runtime.h>
#include <linux/clk.h>
#include <linux/reset.h>
@@ -65,6 +66,10 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
int ret;
memset(port, 0, sizeof *port);
+
+ pm_runtime_enable(&ofdev->dev);
+ pm_runtime_get_sync(&ofdev->dev);
+
if (of_property_read_u32(np, "clock-frequency", &clk)) {
/* Get clk rate through clk driver if present */
@@ -72,12 +77,13 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
if (IS_ERR(info->clk)) {
dev_warn(&ofdev->dev,
"clk or clock-frequency not defined\n");
- return PTR_ERR(info->clk);
+ ret = PTR_ERR(info->clk);
+ goto err_pmruntime;
}
ret = clk_prepare_enable(info->clk);
if (ret < 0)
- return ret;
+ goto err_pmruntime;
clk = clk_get_rate(info->clk);
}
@@ -88,7 +94,7 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
ret = of_address_to_resource(np, 0, &resource);
if (ret) {
dev_warn(&ofdev->dev, "invalid address\n");
- goto out;
+ goto err_unprepare;
}
spin_lock_init(&port->lock);
@@ -130,23 +136,23 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
dev_warn(&ofdev->dev, "unsupported reg-io-width (%d)\n",
prop);
ret = -EINVAL;
- goto out;
+ goto err_dispose;
}
}
info->rst = devm_reset_control_get_optional_shared(&ofdev->dev, NULL);
if (IS_ERR(info->rst))
- goto out;
+ goto err_dispose;
ret = reset_control_deassert(info->rst);
if (ret)
- goto out;
+ goto err_dispose;
port->type = type;
port->uartclk = clk;
port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP
| UPF_FIXED_PORT | UPF_FIXED_TYPE;
- if (of_find_property(np, "no-loopback-test", NULL))
+ if (of_property_read_bool(np, "no-loopback-test"))
port->flags |= UPF_SKIP_TEST;
port->dev = &ofdev->dev;
@@ -167,9 +173,13 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
port->handle_irq = fsl8250_handle_irq;
return 0;
-out:
- if (info->clk)
- clk_disable_unprepare(info->clk);
+err_dispose:
+ irq_dispose_mapping(port->irq);
+err_unprepare:
+ clk_disable_unprepare(info->clk);
+err_pmruntime:
+ pm_runtime_put_sync(&ofdev->dev);
+ pm_runtime_disable(&ofdev->dev);
return ret;
}
@@ -190,7 +200,7 @@ static int of_platform_serial_probe(struct platform_device *ofdev)
if (!match)
return -EINVAL;
- if (of_find_property(ofdev->dev.of_node, "used-by-rtas", NULL))
+ if (of_property_read_bool(ofdev->dev.of_node, "used-by-rtas"))
return -EBUSY;
info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -201,7 +211,7 @@ static int of_platform_serial_probe(struct platform_device *ofdev)
memset(&port8250, 0, sizeof(port8250));
ret = of_platform_serial_setup(ofdev, port_type, &port8250.port, info);
if (ret)
- goto out;
+ goto err_free;
if (port8250.port.fifosize)
port8250.capabilities = UART_CAP_FIFO;
@@ -217,15 +227,19 @@ static int of_platform_serial_probe(struct platform_device *ofdev)
ret = serial8250_register_8250_port(&port8250);
if (ret < 0)
- goto out;
+ goto err_dispose;
info->type = port_type;
info->line = ret;
platform_set_drvdata(ofdev, info);
return 0;
-out:
- kfree(info);
+err_dispose:
irq_dispose_mapping(port8250.port.irq);
+ pm_runtime_put_sync(&ofdev->dev);
+ pm_runtime_disable(&ofdev->dev);
+ clk_disable_unprepare(info->clk);
+err_free:
+ kfree(info);
return ret;
}
@@ -239,8 +253,9 @@ static int of_platform_serial_remove(struct platform_device *ofdev)
serial8250_unregister_port(info->line);
reset_control_assert(info->rst);
- if (info->clk)
- clk_disable_unprepare(info->clk);
+ pm_runtime_put_sync(&ofdev->dev);
+ pm_runtime_disable(&ofdev->dev);
+ clk_disable_unprepare(info->clk);
kfree(info);
return 0;
}
@@ -254,9 +269,10 @@ static int of_serial_suspend(struct device *dev)
serial8250_suspend_port(info->line);
- if (info->clk && (!uart_console(port) || console_suspend_enabled))
+ if (!uart_console(port) || console_suspend_enabled) {
+ pm_runtime_put_sync(dev);
clk_disable_unprepare(info->clk);
-
+ }
return 0;
}
@@ -266,8 +282,10 @@ static int of_serial_resume(struct device *dev)
struct uart_8250_port *port8250 = serial8250_get_port(info->line);
struct uart_port *port = &port8250->port;
- if (info->clk && (!uart_console(port) || console_suspend_enabled))
+ if (!uart_console(port) || console_suspend_enabled) {
+ pm_runtime_get_sync(dev);
clk_prepare_enable(info->clk);
+ }
serial8250_resume_port(info->line);
@@ -295,6 +313,8 @@ static const struct of_device_id of_platform_serial_table[] = {
.data = (void *)PORT_ALTR_16550_F64, },
{ .compatible = "altr,16550-FIFO128",
.data = (void *)PORT_ALTR_16550_F128, },
+ { .compatible = "mediatek,mtk-btif",
+ .data = (void *)PORT_MTK_BTIF, },
{ .compatible = "mrvl,mmp-uart",
.data = (void *)PORT_XSCALE, },
{ .compatible = "ti,da830-uart", .data = (void *)PORT_DA830, },
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
index 00e51a0..0c101a7 100644
--- a/drivers/tty/serial/8250/8250_pci.c
+++ b/drivers/tty/serial/8250/8250_pci.c
@@ -1548,7 +1548,7 @@ static int skip_tx_en_setup(struct serial_private *priv,
const struct pciserial_board *board,
struct uart_8250_port *port, int idx)
{
- port->port.flags |= UPF_NO_TXEN_TEST;
+ port->port.quirks |= UPQ_NO_TXEN_TEST;
dev_dbg(&priv->dev->dev,
"serial8250: skipping TxEn test for device [%04x:%04x] subsystem [%04x:%04x]\n",
priv->dev->vendor, priv->dev->device,
@@ -3384,17 +3384,8 @@ static const struct pci_device_id blacklist[] = {
{ PCI_VDEVICE(COMMTECH, PCI_ANY_ID), },
};
-/*
- * Given a complete unknown PCI device, try to use some heuristics to
- * guess what the configuration might be, based on the pitiful PCI
- * serial specs. Returns 0 on success, 1 on failure.
- */
-static int
-serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board)
+static int serial_pci_is_class_communication(struct pci_dev *dev)
{
- const struct pci_device_id *bldev;
- int num_iomem, num_port, first_port = -1, i;
-
/*
* If it is not a communications device or the programming
* interface is greater than 6, give up.
@@ -3407,6 +3398,13 @@ serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board)
(dev->class & 0xff) > 6)
return -ENODEV;
+ return 0;
+}
+
+static int serial_pci_is_blacklisted(struct pci_dev *dev)
+{
+ const struct pci_device_id *bldev;
+
/*
* Do not access blacklisted devices that are known not to
* feature serial ports or are handled by other modules.
@@ -3419,6 +3417,19 @@ serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board)
return -ENODEV;
}
+ return 0;
+}
+
+/*
+ * Given a complete unknown PCI device, try to use some heuristics to
+ * guess what the configuration might be, based on the pitiful PCI
+ * serial specs. Returns 0 on success, -ENODEV on failure.
+ */
+static int
+serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board)
+{
+ int num_iomem, num_port, first_port = -1, i;
+
num_iomem = num_port = 0;
for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) {
if (pci_resource_flags(dev, i) & IORESOURCE_IO) {
@@ -3639,6 +3650,14 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
board = &pci_boards[ent->driver_data];
+ rc = serial_pci_is_class_communication(dev);
+ if (rc)
+ return rc;
+
+ rc = serial_pci_is_blacklisted(dev);
+ if (rc)
+ return rc;
+
rc = pcim_enable_device(dev);
pci_save_state(dev);
if (rc)
@@ -3723,7 +3742,7 @@ static int pciserial_resume_one(struct device *dev)
static SIMPLE_DEV_PM_OPS(pciserial_pm_ops, pciserial_suspend_one,
pciserial_resume_one);
-static struct pci_device_id serial_pci_tbl[] = {
+static const struct pci_device_id serial_pci_tbl[] = {
/* Advantech use PCI_DEVICE_ID_ADVANTECH_PCI3620 (0x3620) as 'PCI_SUBVENDOR_ID' */
{ PCI_VENDOR_ID_ADVANTECH, PCI_DEVICE_ID_ADVANTECH_PCI3620,
PCI_DEVICE_ID_ADVANTECH_PCI3620, 0x0001, 0, 0,
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index a5fe0e6..f0cc04f 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -37,7 +37,7 @@
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/pm_runtime.h>
-#include <linux/timer.h>
+#include <linux/ktime.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -289,6 +289,14 @@ static const struct serial8250_config uart_config[] = {
.rxtrig_bytes = {1, 4, 8, 14},
.flags = UART_CAP_FIFO | UART_CAP_AFE,
},
+ [PORT_MTK_BTIF] = {
+ .name = "MediaTek BTIF",
+ .fifo_size = 16,
+ .tx_loadsz = 16,
+ .fcr = UART_FCR_ENABLE_FIFO |
+ UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT,
+ .flags = UART_CAP_FIFO,
+ },
};
/* Uart divisor latch read */
@@ -553,8 +561,8 @@ static inline void serial8250_em485_rts_after_send(struct uart_8250_port *p)
serial8250_out_MCR(p, mcr);
}
-static void serial8250_em485_handle_start_tx(unsigned long arg);
-static void serial8250_em485_handle_stop_tx(unsigned long arg);
+static enum hrtimer_restart serial8250_em485_handle_start_tx(struct hrtimer *t);
+static enum hrtimer_restart serial8250_em485_handle_stop_tx(struct hrtimer *t);
void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p)
{
@@ -609,12 +617,14 @@ int serial8250_em485_init(struct uart_8250_port *p)
if (!p->em485)
return -ENOMEM;
- setup_timer(&p->em485->stop_tx_timer,
- serial8250_em485_handle_stop_tx, (unsigned long)p);
- setup_timer(&p->em485->start_tx_timer,
- serial8250_em485_handle_start_tx, (unsigned long)p);
+ hrtimer_init(&p->em485->stop_tx_timer, CLOCK_MONOTONIC,
+ HRTIMER_MODE_REL);
+ hrtimer_init(&p->em485->start_tx_timer, CLOCK_MONOTONIC,
+ HRTIMER_MODE_REL);
+ p->em485->stop_tx_timer.function = &serial8250_em485_handle_stop_tx;
+ p->em485->start_tx_timer.function = &serial8250_em485_handle_start_tx;
+ p->em485->port = p;
p->em485->active_timer = NULL;
-
serial8250_em485_rts_after_send(p);
return 0;
@@ -639,8 +649,8 @@ void serial8250_em485_destroy(struct uart_8250_port *p)
if (!p->em485)
return;
- del_timer(&p->em485->start_tx_timer);
- del_timer(&p->em485->stop_tx_timer);
+ hrtimer_cancel(&p->em485->start_tx_timer);
+ hrtimer_cancel(&p->em485->stop_tx_timer);
kfree(p->em485);
p->em485 = NULL;
@@ -1435,22 +1445,33 @@ static void __do_stop_tx_rs485(struct uart_8250_port *p)
serial_port_out(&p->port, UART_IER, p->ier);
}
}
-
-static void serial8250_em485_handle_stop_tx(unsigned long arg)
+static enum hrtimer_restart serial8250_em485_handle_stop_tx(struct hrtimer *t)
{
- struct uart_8250_port *p = (struct uart_8250_port *)arg;
- struct uart_8250_em485 *em485 = p->em485;
+ struct uart_8250_em485 *em485;
+ struct uart_8250_port *p;
unsigned long flags;
+ em485 = container_of(t, struct uart_8250_em485, stop_tx_timer);
+ p = em485->port;
+
serial8250_rpm_get(p);
spin_lock_irqsave(&p->port.lock, flags);
- if (em485 &&
- em485->active_timer == &em485->stop_tx_timer) {
+ if (em485->active_timer == &em485->stop_tx_timer) {
__do_stop_tx_rs485(p);
em485->active_timer = NULL;
}
spin_unlock_irqrestore(&p->port.lock, flags);
serial8250_rpm_put(p);
+ return HRTIMER_NORESTART;
+}
+
+static void start_hrtimer_ms(struct hrtimer *hrt, unsigned long msec)
+{
+ long sec = msec / 1000;
+ long nsec = (msec % 1000) * 1000000;
+ ktime_t t = ktime_set(sec, nsec);
+
+ hrtimer_start(hrt, t, HRTIMER_MODE_REL);
}
static void __stop_tx_rs485(struct uart_8250_port *p)
@@ -1463,8 +1484,8 @@ static void __stop_tx_rs485(struct uart_8250_port *p)
*/
if (p->port.rs485.delay_rts_after_send > 0) {
em485->active_timer = &em485->stop_tx_timer;
- mod_timer(&em485->stop_tx_timer, jiffies +
- p->port.rs485.delay_rts_after_send * HZ / 1000);
+ start_hrtimer_ms(&em485->stop_tx_timer,
+ p->port.rs485.delay_rts_after_send);
} else {
__do_stop_tx_rs485(p);
}
@@ -1494,8 +1515,8 @@ static inline void __stop_tx(struct uart_8250_port *p)
if ((lsr & BOTH_EMPTY) != BOTH_EMPTY)
return;
- del_timer(&em485->start_tx_timer);
em485->active_timer = NULL;
+ hrtimer_cancel(&em485->start_tx_timer);
__stop_tx_rs485(p);
}
@@ -1558,8 +1579,9 @@ static inline void start_tx_rs485(struct uart_port *port)
if (!(up->port.rs485.flags & SER_RS485_RX_DURING_TX))
serial8250_stop_rx(&up->port);
- del_timer(&em485->stop_tx_timer);
em485->active_timer = NULL;
+ if (hrtimer_is_queued(&em485->stop_tx_timer))
+ hrtimer_cancel(&em485->stop_tx_timer);
mcr = serial8250_in_MCR(up);
if (!!(up->port.rs485.flags & SER_RS485_RTS_ON_SEND) !=
@@ -1572,8 +1594,8 @@ static inline void start_tx_rs485(struct uart_port *port)
if (up->port.rs485.delay_rts_before_send > 0) {
em485->active_timer = &em485->start_tx_timer;
- mod_timer(&em485->start_tx_timer, jiffies +
- up->port.rs485.delay_rts_before_send * HZ / 1000);
+ start_hrtimer_ms(&em485->start_tx_timer,
+ up->port.rs485.delay_rts_before_send);
return;
}
}
@@ -1581,19 +1603,22 @@ static inline void start_tx_rs485(struct uart_port *port)
__start_tx(port);
}
-static void serial8250_em485_handle_start_tx(unsigned long arg)
+static enum hrtimer_restart serial8250_em485_handle_start_tx(struct hrtimer *t)
{
- struct uart_8250_port *p = (struct uart_8250_port *)arg;
- struct uart_8250_em485 *em485 = p->em485;
+ struct uart_8250_em485 *em485;
+ struct uart_8250_port *p;
unsigned long flags;
+ em485 = container_of(t, struct uart_8250_em485, start_tx_timer);
+ p = em485->port;
+
spin_lock_irqsave(&p->port.lock, flags);
- if (em485 &&
- em485->active_timer == &em485->start_tx_timer) {
+ if (em485->active_timer == &em485->start_tx_timer) {
__start_tx(&p->port);
em485->active_timer = NULL;
}
spin_unlock_irqrestore(&p->port.lock, flags);
+ return HRTIMER_NORESTART;
}
static void serial8250_start_tx(struct uart_port *port)
@@ -2304,7 +2329,7 @@ int serial8250_do_startup(struct uart_port *port)
* test if we receive TX irq. This way, we'll never enable
* UART_BUG_TXEN.
*/
- if (up->port.flags & UPF_NO_TXEN_TEST)
+ if (up->port.quirks & UPQ_NO_TXEN_TEST)
goto dont_test_tx_en;
/*
diff --git a/drivers/tty/serial/8250/8250_uniphier.c b/drivers/tty/serial/8250/8250_uniphier.c
index 746680e..8a10b10 100644
--- a/drivers/tty/serial/8250/8250_uniphier.c
+++ b/drivers/tty/serial/8250/8250_uniphier.c
@@ -29,12 +29,13 @@
* - MMIO32 (regshift = 2)
* - FCR is not at 2, but 3
* - LCR and MCR are not at 3 and 4, they share 4
+ * - No SCR (Instead, CHAR can be used as a scratch register)
* - Divisor latch at 9, no divisor latch access bit
*/
#define UNIPHIER_UART_REGSHIFT 2
-/* bit[15:8] = CHAR (not used), bit[7:0] = FCR */
+/* bit[15:8] = CHAR, bit[7:0] = FCR */
#define UNIPHIER_UART_CHAR_FCR (3 << (UNIPHIER_UART_REGSHIFT))
/* bit[15:8] = LCR, bit[7:0] = MCR */
#define UNIPHIER_UART_LCR_MCR (4 << (UNIPHIER_UART_REGSHIFT))
@@ -72,13 +73,18 @@ OF_EARLYCON_DECLARE(uniphier, "socionext,uniphier-uart",
/*
* The register map is slightly different from that of 8250.
- * IO callbacks must be overridden for correct access to FCR, LCR, and MCR.
+ * IO callbacks must be overridden for correct access to FCR, LCR, MCR and SCR.
*/
static unsigned int uniphier_serial_in(struct uart_port *p, int offset)
{
unsigned int valshift = 0;
switch (offset) {
+ case UART_SCR:
+ /* No SCR for this hardware. Use CHAR as a scratch register */
+ valshift = 8;
+ offset = UNIPHIER_UART_CHAR_FCR;
+ break;
case UART_LCR:
valshift = 8;
/* fall through */
@@ -91,8 +97,8 @@ static unsigned int uniphier_serial_in(struct uart_port *p, int offset)
}
/*
- * The return value must be masked with 0xff because LCR and MCR reside
- * in the same register that must be accessed by 32-bit write/read.
+ * The return value must be masked with 0xff because some registers
+ * share the same offset that must be accessed by 32-bit write/read.
* 8 or 16 bit access to this hardware result in unexpected behavior.
*/
return (readl(p->membase + offset) >> valshift) & 0xff;
@@ -101,9 +107,13 @@ static unsigned int uniphier_serial_in(struct uart_port *p, int offset)
static void uniphier_serial_out(struct uart_port *p, int offset, int value)
{
unsigned int valshift = 0;
- bool normal = true;
+ bool normal = false;
switch (offset) {
+ case UART_SCR:
+ /* No SCR for this hardware. Use CHAR as a scratch register */
+ valshift = 8;
+ /* fall through */
case UART_FCR:
offset = UNIPHIER_UART_CHAR_FCR;
break;
@@ -114,10 +124,10 @@ static void uniphier_serial_out(struct uart_port *p, int offset, int value)
/* fall through */
case UART_MCR:
offset = UNIPHIER_UART_LCR_MCR;
- normal = false;
break;
default:
offset <<= UNIPHIER_UART_REGSHIFT;
+ normal = true;
break;
}
@@ -169,7 +179,7 @@ static int uniphier_of_serial_setup(struct device *dev, struct uart_port *port,
dev_err(dev, "failed to get alias id\n");
return ret;
}
- port->line = priv->line = ret;
+ port->line = ret;
/* Get clk rate through clk driver */
priv->clk = devm_clk_get(dev, NULL);
@@ -249,8 +259,8 @@ static int uniphier_uart_probe(struct platform_device *pdev)
up.dl_read = uniphier_serial_dl_read;
up.dl_write = uniphier_serial_dl_write;
- ret = serial8250_register_8250_port(&up);
- if (ret < 0) {
+ priv->line = serial8250_register_8250_port(&up);
+ if (priv->line < 0) {
dev_err(dev, "failed to register 8250 port\n");
clk_disable_unprepare(priv->clk);
return ret;
@@ -271,6 +281,40 @@ static int uniphier_uart_remove(struct platform_device *pdev)
return 0;
}
+static int __maybe_unused uniphier_uart_suspend(struct device *dev)
+{
+ struct uniphier8250_priv *priv = dev_get_drvdata(dev);
+ struct uart_8250_port *up = serial8250_get_port(priv->line);
+
+ serial8250_suspend_port(priv->line);
+
+ if (!uart_console(&up->port) || console_suspend_enabled)
+ clk_disable_unprepare(priv->clk);
+
+ return 0;
+}
+
+static int __maybe_unused uniphier_uart_resume(struct device *dev)
+{
+ struct uniphier8250_priv *priv = dev_get_drvdata(dev);
+ struct uart_8250_port *up = serial8250_get_port(priv->line);
+ int ret;
+
+ if (!uart_console(&up->port) || console_suspend_enabled) {
+ ret = clk_prepare_enable(priv->clk);
+ if (ret)
+ return ret;
+ }
+
+ serial8250_resume_port(priv->line);
+
+ return 0;
+}
+
+static const struct dev_pm_ops uniphier_uart_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(uniphier_uart_suspend, uniphier_uart_resume)
+};
+
static const struct of_device_id uniphier_uart_match[] = {
{ .compatible = "socionext,uniphier-uart" },
{ /* sentinel */ }
@@ -283,6 +327,7 @@ static struct platform_driver uniphier_uart_platform_driver = {
.driver = {
.name = "uniphier-uart",
.of_match_table = uniphier_uart_match,
+ .pm = &uniphier_uart_pm_ops,
},
};
module_platform_driver(uniphier_uart_platform_driver);
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index a1161ec..a5c0ef1 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -155,6 +155,17 @@ config SERIAL_8250_CS
If unsure, say N.
+config SERIAL_8250_MEN_MCB
+ tristate "MEN Z125 UART device support"
+ depends on MCB && SERIAL_8250
+ help
+ This enables support for FPGA based UARTs found on many MEN
+ boards. This driver enables support for the Z125 UARTs.
+
+ To compile this driver as a module, chose M here: the
+ module will be called 8250_men_mcb.
+
+
config SERIAL_8250_NR_UARTS
int "Maximum number of 8250/16550 serial ports"
depends on SERIAL_8250
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
index a44a99a..6a18d2d 100644
--- a/drivers/tty/serial/8250/Makefile
+++ b/drivers/tty/serial/8250/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o
obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o
+obj-$(CONFIG_SERIAL_8250_MEN_MCB) += 8250_men_mcb.o
obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o
obj-$(CONFIG_SERIAL_8250_OMAP) += 8250_omap.o
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 1f096e2..b788fee 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1689,7 +1689,7 @@ config SERIAL_MVEBU_CONSOLE
Otherwise, say 'N'.
config SERIAL_OWL
- bool "Actions Semi Owl serial port support"
+ tristate "Actions Semi Owl serial port support"
depends on ARCH_ACTIONS || COMPILE_TEST
select SERIAL_CORE
help
@@ -1705,7 +1705,7 @@ config SERIAL_OWL_CONSOLE
default y
help
Say 'Y' here if you wish to use Actions Semiconductor S500/S900 UART
- as the system console. Only earlycon is implemented currently.
+ as the system console.
endmenu
diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c
index 24180ad..9ec4b8d 100644
--- a/drivers/tty/serial/amba-pl010.c
+++ b/drivers/tty/serial/amba-pl010.c
@@ -814,7 +814,7 @@ static int pl010_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(pl010_dev_pm_ops, pl010_suspend, pl010_resume);
-static struct amba_id pl010_ids[] = {
+static const struct amba_id pl010_ids[] = {
{
.id = 0x00041010,
.mask = 0x000fffff,
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index 1888d16..111e6a9 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -128,7 +128,7 @@ static struct vendor_data vendor_arm = {
.get_fifosize = get_fifosize_arm,
};
-static struct vendor_data vendor_sbsa = {
+static const struct vendor_data vendor_sbsa = {
.reg_offset = pl011_std_offsets,
.fr_busy = UART01x_FR_BUSY,
.fr_dsr = UART01x_FR_DSR,
@@ -143,7 +143,7 @@ static struct vendor_data vendor_sbsa = {
};
#ifdef CONFIG_ACPI_SPCR_TABLE
-static struct vendor_data vendor_qdt_qdf2400_e44 = {
+static const struct vendor_data vendor_qdt_qdf2400_e44 = {
.reg_offset = pl011_std_offsets,
.fr_busy = UART011_FR_TXFE,
.fr_dsr = UART01x_FR_DSR,
@@ -2787,7 +2787,7 @@ static struct platform_driver arm_sbsa_uart_platform_driver = {
},
};
-static struct amba_id pl011_ids[] = {
+static const struct amba_id pl011_ids[] = {
{
.id = 0x00041011,
.mask = 0x000fffff,
diff --git a/drivers/tty/serial/apbuart.c b/drivers/tty/serial/apbuart.c
index 75eb083..dd60ed9 100644
--- a/drivers/tty/serial/apbuart.c
+++ b/drivers/tty/serial/apbuart.c
@@ -325,7 +325,7 @@ static int apbuart_verify_port(struct uart_port *port,
return ret;
}
-static struct uart_ops grlib_apbuart_ops = {
+static const struct uart_ops grlib_apbuart_ops = {
.tx_empty = apbuart_tx_empty,
.set_mctrl = apbuart_set_mctrl,
.get_mctrl = apbuart_get_mctrl,
diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c
index 5ac06fc..77fe306 100644
--- a/drivers/tty/serial/arc_uart.c
+++ b/drivers/tty/serial/arc_uart.c
@@ -549,8 +549,8 @@ static struct console arc_console = {
.data = &arc_uart_driver
};
-static __init void arc_early_serial_write(struct console *con, const char *s,
- unsigned int n)
+static void arc_early_serial_write(struct console *con, const char *s,
+ unsigned int n)
{
struct earlycon_device *dev = con->data;
diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c
index f6bcc19..9ac142c 100644
--- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c
@@ -1123,7 +1123,7 @@ static void cpm_put_poll_char(struct uart_port *port,
}
#endif /* CONFIG_CONSOLE_POLL */
-static struct uart_ops cpm_uart_pops = {
+static const struct uart_ops cpm_uart_pops = {
.tx_empty = cpm_uart_tx_empty,
.set_mctrl = cpm_uart_set_mctrl,
.get_mctrl = cpm_uart_get_mctrl,
diff --git a/drivers/tty/serial/earlycon.c b/drivers/tty/serial/earlycon.c
index c365154..98928f0 100644
--- a/drivers/tty/serial/earlycon.c
+++ b/drivers/tty/serial/earlycon.c
@@ -220,7 +220,7 @@ static int __init param_setup_earlycon(char *buf)
if (IS_ENABLED(CONFIG_ACPI_SPCR_TABLE)) {
earlycon_init_is_deferred = true;
return 0;
- } else {
+ } else if (!buf) {
return early_init_dt_scan_chosen_stdout();
}
}
@@ -282,7 +282,12 @@ int __init of_setup_earlycon(const struct earlycon_id *match,
}
}
+ val = of_get_flat_dt_prop(node, "current-speed", NULL);
+ if (val)
+ early_console_dev.baud = be32_to_cpu(*val);
+
if (options) {
+ early_console_dev.baud = simple_strtoul(options, NULL, 0);
strlcpy(early_console_dev.options, options,
sizeof(early_console_dev.options));
}
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 898dcb0..849c1f9 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -117,7 +117,7 @@
#define UARTSFIFO_TXOF 0x02
#define UARTSFIFO_RXUF 0x01
-/* 32-bit register defination */
+/* 32-bit register definition */
#define UARTBAUD 0x00
#define UARTSTAT 0x04
#define UARTCTRL 0x08
@@ -521,6 +521,57 @@ static int lpuart_poll_get_char(struct uart_port *port)
return readb(port->membase + UARTDR);
}
+static int lpuart32_poll_init(struct uart_port *port)
+{
+ unsigned long flags;
+ struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
+ u32 temp;
+
+ sport->port.fifosize = 0;
+
+ spin_lock_irqsave(&sport->port.lock, flags);
+
+ /* Disable Rx & Tx */
+ writel(0, sport->port.membase + UARTCTRL);
+
+ temp = readl(sport->port.membase + UARTFIFO);
+
+ /* Enable Rx and Tx FIFO */
+ writel(temp | UARTFIFO_RXFE | UARTFIFO_TXFE,
+ sport->port.membase + UARTFIFO);
+
+ /* flush Tx and Rx FIFO */
+ writel(UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH,
+ sport->port.membase + UARTFIFO);
+
+ /* explicitly clear RDRF */
+ if (readl(sport->port.membase + UARTSTAT) & UARTSTAT_RDRF) {
+ readl(sport->port.membase + UARTDATA);
+ writel(UARTFIFO_RXUF, sport->port.membase + UARTFIFO);
+ }
+
+ /* Enable Rx and Tx */
+ writel(UARTCTRL_RE | UARTCTRL_TE, sport->port.membase + UARTCTRL);
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+
+ return 0;
+}
+
+static void lpuart32_poll_put_char(struct uart_port *port, unsigned char c)
+{
+ while (!(readl(port->membase + UARTSTAT) & UARTSTAT_TDRE))
+ barrier();
+
+ writel(c, port->membase + UARTDATA);
+}
+
+static int lpuart32_poll_get_char(struct uart_port *port)
+{
+ if (!(readl(port->membase + UARTSTAT) & UARTSTAT_RDRF))
+ return NO_POLL_CHAR;
+
+ return readl(port->membase + UARTDATA);
+}
#endif
static inline void lpuart_transmit_buffer(struct lpuart_port *sport)
@@ -1025,6 +1076,11 @@ static int lpuart_config_rs485(struct uart_port *port,
~(UARTMODEM_TXRTSPOL | UARTMODEM_TXRTSE);
writeb(modem, sport->port.membase + UARTMODEM);
+ /* clear unsupported configurations */
+ rs485->delay_rts_before_send = 0;
+ rs485->delay_rts_after_send = 0;
+ rs485->flags &= ~SER_RS485_RX_DURING_TX;
+
if (rs485->flags & SER_RS485_ENABLED) {
/* Enable auto RS-485 RTS mode */
modem |= UARTMODEM_TXRTSE;
@@ -1782,6 +1838,11 @@ static const struct uart_ops lpuart32_pops = {
.config_port = lpuart_config_port,
.verify_port = lpuart_verify_port,
.flush_buffer = lpuart_flush_buffer,
+#if defined(CONFIG_CONSOLE_POLL)
+ .poll_init = lpuart32_poll_init,
+ .poll_get_char = lpuart32_poll_get_char,
+ .poll_put_char = lpuart32_poll_put_char,
+#endif
};
static struct lpuart_port *lpuart_ports[UART_NR];
@@ -2203,6 +2264,7 @@ static int lpuart_suspend(struct device *dev)
{
struct lpuart_port *sport = dev_get_drvdata(dev);
unsigned long temp;
+ bool irq_wake;
if (lpuart_is_32(sport)) {
/* disable Rx/Tx and interrupts */
@@ -2218,6 +2280,9 @@ static int lpuart_suspend(struct device *dev)
uart_suspend_port(&lpuart_reg, &sport->port);
+ /* uart_suspend_port() might set wakeup flag */
+ irq_wake = irqd_is_wakeup_set(irq_get_irq_data(sport->port.irq));
+
if (sport->lpuart_dma_rx_use) {
/*
* EDMA driver during suspend will forcefully release any
@@ -2226,7 +2291,7 @@ static int lpuart_suspend(struct device *dev)
* cannot resume as as expected, hence gracefully release the
* Rx DMA path before suspend and start Rx DMA path on resume.
*/
- if (sport->port.irq_wake) {
+ if (irq_wake) {
del_timer_sync(&sport->lpuart_timer);
lpuart_dma_rx_free(&sport->port);
}
@@ -2241,7 +2306,7 @@ static int lpuart_suspend(struct device *dev)
dmaengine_terminate_all(sport->dma_tx_chan);
}
- if (sport->port.suspended && !sport->port.irq_wake)
+ if (sport->port.suspended && !irq_wake)
clk_disable_unprepare(sport->clk);
return 0;
@@ -2250,9 +2315,10 @@ static int lpuart_suspend(struct device *dev)
static int lpuart_resume(struct device *dev)
{
struct lpuart_port *sport = dev_get_drvdata(dev);
+ bool irq_wake = irqd_is_wakeup_set(irq_get_irq_data(sport->port.irq));
unsigned long temp;
- if (sport->port.suspended && !sport->port.irq_wake)
+ if (sport->port.suspended && !irq_wake)
clk_prepare_enable(sport->clk);
if (lpuart_is_32(sport)) {
@@ -2269,7 +2335,7 @@ static int lpuart_resume(struct device *dev)
}
if (sport->lpuart_dma_rx_use) {
- if (sport->port.irq_wake) {
+ if (irq_wake) {
if (!lpuart_start_rx_dma(sport))
rx_dma_timer_init(sport);
else
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 80934e7..dfeff39 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -226,7 +226,6 @@ struct imx_port {
dma_cookie_t rx_cookie;
unsigned int tx_bytes;
unsigned int dma_tx_nents;
- wait_queue_head_t dma_wait;
unsigned int saved_reg[10];
bool context_saved;
};
@@ -458,7 +457,10 @@ static inline void imx_transmit_buffer(struct imx_port *sport)
}
}
- while (!uart_circ_empty(xmit) && !sport->dma_is_txing &&
+ if (sport->dma_is_txing)
+ return;
+
+ while (!uart_circ_empty(xmit) &&
!(readl(sport->port.membase + uts_reg(sport)) & UTS_TXFULL)) {
/* send xmit->buf[xmit->tail]
* out the port here */
@@ -498,20 +500,12 @@ static void dma_tx_callback(void *data)
sport->dma_is_txing = 0;
- spin_unlock_irqrestore(&sport->port.lock, flags);
-
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(&sport->port);
- if (waitqueue_active(&sport->dma_wait)) {
- wake_up(&sport->dma_wait);
- dev_dbg(sport->port.dev, "exit in %s.\n", __func__);
- return;
- }
-
- spin_lock_irqsave(&sport->port.lock, flags);
if (!uart_circ_empty(xmit) && !uart_tx_stopped(&sport->port))
imx_dma_tx(sport);
+
spin_unlock_irqrestore(&sport->port.lock, flags);
}
@@ -1208,8 +1202,6 @@ static void imx_enable_dma(struct imx_port *sport)
{
unsigned long temp;
- init_waitqueue_head(&sport->dma_wait);
-
/* set UCR1 */
temp = readl(sport->port.membase + UCR1);
temp |= UCR1_RDMAEN | UCR1_TDMAEN | UCR1_ATDMAEN;
@@ -2332,6 +2324,7 @@ static int imx_serial_port_suspend(struct device *dev)
serial_imx_enable_wakeup(sport, true);
uart_suspend_port(&imx_reg, &sport->port);
+ disable_irq(sport->port.irq);
/* Needed to enable clock in suspend_noirq */
return clk_prepare(sport->clk_ipg);
@@ -2346,6 +2339,7 @@ static int imx_serial_port_resume(struct device *dev)
serial_imx_enable_wakeup(sport, false);
uart_resume_port(&imx_reg, &sport->port);
+ enable_irq(sport->port.irq);
clk_unprepare(sport->clk_ipg);
diff --git a/drivers/tty/serial/jsm/jsm_driver.c b/drivers/tty/serial/jsm/jsm_driver.c
index a119f11..102d499 100644
--- a/drivers/tty/serial/jsm/jsm_driver.c
+++ b/drivers/tty/serial/jsm/jsm_driver.c
@@ -304,7 +304,7 @@ static void jsm_remove_one(struct pci_dev *pdev)
kfree(brd);
}
-static struct pci_device_id jsm_pci_tbl[] = {
+static const struct pci_device_id jsm_pci_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2DB9), 0, 0, 0 },
{ PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2DB9PRI), 0, 0, 1 },
{ PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2RJ45), 0, 0, 2 },
diff --git a/drivers/tty/serial/m32r_sio.c b/drivers/tty/serial/m32r_sio.c
index 218b711..5b3bd95 100644
--- a/drivers/tty/serial/m32r_sio.c
+++ b/drivers/tty/serial/m32r_sio.c
@@ -854,7 +854,7 @@ m32r_sio_verify_port(struct uart_port *port, struct serial_struct *ser)
return 0;
}
-static struct uart_ops m32r_sio_pops = {
+static const struct uart_ops m32r_sio_pops = {
.tx_empty = m32r_sio_tx_empty,
.set_mctrl = m32r_sio_set_mctrl,
.get_mctrl = m32r_sio_get_mctrl,
diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 42e4a4c..07c0f98 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -424,7 +424,7 @@ static void meson_uart_config_port(struct uart_port *port, int flags)
}
}
-static struct uart_ops meson_uart_ops = {
+static const struct uart_ops meson_uart_ops = {
.set_mctrl = meson_uart_set_mctrl,
.get_mctrl = meson_uart_get_mctrl,
.tx_empty = meson_uart_tx_empty,
diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c
index 3970d6a..791c4c7 100644
--- a/drivers/tty/serial/mpc52xx_uart.c
+++ b/drivers/tty/serial/mpc52xx_uart.c
@@ -1347,7 +1347,7 @@ mpc52xx_uart_verify_port(struct uart_port *port, struct serial_struct *ser)
}
-static struct uart_ops mpc52xx_uart_ops = {
+static const struct uart_ops mpc52xx_uart_ops = {
.tx_empty = mpc52xx_uart_tx_empty,
.set_mctrl = mpc52xx_uart_set_mctrl,
.get_mctrl = mpc52xx_uart_get_mctrl,
@@ -1634,8 +1634,8 @@ mpc52xx_console_setup(struct console *co, char *options)
return -EINVAL;
}
- pr_debug("Console on ttyPSC%x is %s\n",
- co->index, mpc52xx_uart_nodes[co->index]->full_name);
+ pr_debug("Console on ttyPSC%x is %pOF\n",
+ co->index, mpc52xx_uart_nodes[co->index]);
/* Fetch register locations */
ret = of_address_to_resource(np, 0, &res);
@@ -1755,8 +1755,8 @@ static int mpc52xx_uart_of_probe(struct platform_device *op)
break;
if (idx >= MPC52xx_PSC_MAXNUM)
return -EINVAL;
- pr_debug("Found %s assigned to ttyPSC%x\n",
- mpc52xx_uart_nodes[idx]->full_name, idx);
+ pr_debug("Found %pOF assigned to ttyPSC%x\n",
+ mpc52xx_uart_nodes[idx], idx);
/* set the uart clock to the input clock of the psc, the different
* prescalers are taken into account in the set_baudrate() methods
@@ -1881,8 +1881,8 @@ mpc52xx_uart_of_enumerate(void)
for (i = 0; i < MPC52xx_PSC_MAXNUM; i++) {
if (mpc52xx_uart_nodes[i])
- pr_debug("%s assigned to ttyPSC%x\n",
- mpc52xx_uart_nodes[i]->full_name, i);
+ pr_debug("%pOF assigned to ttyPSC%x\n",
+ mpc52xx_uart_nodes[i], i);
}
}
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index 6788e75..1db79ee 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -1175,11 +1175,6 @@ static int msm_startup(struct uart_port *port)
snprintf(msm_port->name, sizeof(msm_port->name),
"msm_serial%d", port->line);
- ret = request_irq(port->irq, msm_uart_irq, IRQF_TRIGGER_HIGH,
- msm_port->name, port);
- if (unlikely(ret))
- return ret;
-
msm_init_clock(port);
if (likely(port->fifosize > 12))
@@ -1206,7 +1201,21 @@ static int msm_startup(struct uart_port *port)
msm_request_rx_dma(msm_port, msm_port->uart.mapbase);
}
+ ret = request_irq(port->irq, msm_uart_irq, IRQF_TRIGGER_HIGH,
+ msm_port->name, port);
+ if (unlikely(ret))
+ goto err_irq;
+
return 0;
+
+err_irq:
+ if (msm_port->is_uartdm)
+ msm_release_dma(msm_port);
+
+ clk_disable_unprepare(msm_port->pclk);
+ clk_disable_unprepare(msm_port->clk);
+
+ return ret;
}
static void msm_shutdown(struct uart_port *port)
diff --git a/drivers/tty/serial/mux.c b/drivers/tty/serial/mux.c
index 8a4be4b..2bff69e 100644
--- a/drivers/tty/serial/mux.c
+++ b/drivers/tty/serial/mux.c
@@ -427,7 +427,7 @@ static struct console mux_console = {
#define MUX_CONSOLE NULL
#endif
-static struct uart_ops mux_pops = {
+static const struct uart_ops mux_pops = {
.tx_empty = mux_tx_empty,
.set_mctrl = mux_set_mctrl,
.get_mctrl = mux_get_mctrl,
@@ -503,7 +503,7 @@ static int __init mux_probe(struct parisc_device *dev)
return 0;
}
-static int mux_remove(struct parisc_device *dev)
+static int __exit mux_remove(struct parisc_device *dev)
{
int i, j;
int port_count = (long)dev_get_drvdata(&dev->dev);
@@ -536,13 +536,13 @@ static int mux_remove(struct parisc_device *dev)
* This table only contains the parisc_device_id of known builtin mux
* devices. All other mux cards will be detected by the generic mux_tbl.
*/
-static struct parisc_device_id builtin_mux_tbl[] = {
+static const struct parisc_device_id builtin_mux_tbl[] __initconst = {
{ HPHW_A_DIRECT, HVERSION_REV_ANY_ID, 0x15, 0x0000D }, /* All K-class */
{ HPHW_A_DIRECT, HVERSION_REV_ANY_ID, 0x44, 0x0000D }, /* E35, E45, and E55 */
{ 0, }
};
-static struct parisc_device_id mux_tbl[] = {
+static const struct parisc_device_id mux_tbl[] __initconst = {
{ HPHW_A_DIRECT, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0000D },
{ 0, }
};
@@ -550,18 +550,18 @@ static struct parisc_device_id mux_tbl[] = {
MODULE_DEVICE_TABLE(parisc, builtin_mux_tbl);
MODULE_DEVICE_TABLE(parisc, mux_tbl);
-static struct parisc_driver builtin_serial_mux_driver = {
+static struct parisc_driver builtin_serial_mux_driver __refdata = {
.name = "builtin_serial_mux",
.id_table = builtin_mux_tbl,
.probe = mux_probe,
- .remove = mux_remove,
+ .remove = __exit_p(mux_remove),
};
-static struct parisc_driver serial_mux_driver = {
+static struct parisc_driver serial_mux_driver __refdata = {
.name = "serial_mux",
.id_table = mux_tbl,
.probe = mux_probe,
- .remove = mux_remove,
+ .remove = __exit_p(mux_remove),
};
/**
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index 1ea05ac..7754053 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -1235,21 +1235,20 @@ out:
#ifdef CONFIG_SERIAL_OMAP_CONSOLE
#ifdef CONFIG_SERIAL_EARLYCON
-static unsigned int __init omap_serial_early_in(struct uart_port *port,
- int offset)
+static unsigned int omap_serial_early_in(struct uart_port *port, int offset)
{
offset <<= port->regshift;
return readw(port->membase + offset);
}
-static void __init omap_serial_early_out(struct uart_port *port, int offset,
- int value)
+static void omap_serial_early_out(struct uart_port *port, int offset,
+ int value)
{
offset <<= port->regshift;
writew(value, port->membase + offset);
}
-static void __init omap_serial_early_putc(struct uart_port *port, int c)
+static void omap_serial_early_putc(struct uart_port *port, int c)
{
unsigned int status;
@@ -1262,8 +1261,8 @@ static void __init omap_serial_early_putc(struct uart_port *port, int c)
omap_serial_early_out(port, UART_TX, c);
}
-static void __init early_omap_serial_write(struct console *console,
- const char *s, unsigned int count)
+static void early_omap_serial_write(struct console *console, const char *s,
+ unsigned int count)
{
struct earlycon_device *device = console->data;
struct uart_port *port = &device->port;
diff --git a/drivers/tty/serial/owl-uart.c b/drivers/tty/serial/owl-uart.c
index 1b80087..b9c85936 100644
--- a/drivers/tty/serial/owl-uart.c
+++ b/drivers/tty/serial/owl-uart.c
@@ -20,6 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <linux/clk.h>
#include <linux/console.h>
#include <linux/delay.h>
#include <linux/io.h>
@@ -28,22 +29,66 @@
#include <linux/platform_device.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+
+#define OWL_UART_PORT_NUM 7
+#define OWL_UART_DEV_NAME "ttyOWL"
#define OWL_UART_CTL 0x000
+#define OWL_UART_RXDAT 0x004
#define OWL_UART_TXDAT 0x008
#define OWL_UART_STAT 0x00c
+#define OWL_UART_CTL_DWLS_MASK GENMASK(1, 0)
+#define OWL_UART_CTL_DWLS_5BITS (0x0 << 0)
+#define OWL_UART_CTL_DWLS_6BITS (0x1 << 0)
+#define OWL_UART_CTL_DWLS_7BITS (0x2 << 0)
+#define OWL_UART_CTL_DWLS_8BITS (0x3 << 0)
+#define OWL_UART_CTL_STPS_2BITS BIT(2)
+#define OWL_UART_CTL_PRS_MASK GENMASK(6, 4)
+#define OWL_UART_CTL_PRS_NONE (0x0 << 4)
+#define OWL_UART_CTL_PRS_ODD (0x4 << 4)
+#define OWL_UART_CTL_PRS_MARK (0x5 << 4)
+#define OWL_UART_CTL_PRS_EVEN (0x6 << 4)
+#define OWL_UART_CTL_PRS_SPACE (0x7 << 4)
+#define OWL_UART_CTL_AFE BIT(12)
#define OWL_UART_CTL_TRFS_TX BIT(14)
#define OWL_UART_CTL_EN BIT(15)
+#define OWL_UART_CTL_RXDE BIT(16)
+#define OWL_UART_CTL_TXDE BIT(17)
#define OWL_UART_CTL_RXIE BIT(18)
#define OWL_UART_CTL_TXIE BIT(19)
+#define OWL_UART_CTL_LBEN BIT(20)
#define OWL_UART_STAT_RIP BIT(0)
#define OWL_UART_STAT_TIP BIT(1)
+#define OWL_UART_STAT_RXER BIT(2)
+#define OWL_UART_STAT_TFER BIT(3)
+#define OWL_UART_STAT_RXST BIT(4)
+#define OWL_UART_STAT_RFEM BIT(5)
#define OWL_UART_STAT_TFFU BIT(6)
-#define OWL_UART_STAT_TRFL_MASK (0x1f << 11)
+#define OWL_UART_STAT_CTSS BIT(7)
+#define OWL_UART_STAT_RTSS BIT(8)
+#define OWL_UART_STAT_TFES BIT(10)
+#define OWL_UART_STAT_TRFL_MASK GENMASK(16, 11)
#define OWL_UART_STAT_UTBB BIT(17)
+static struct uart_driver owl_uart_driver;
+
+struct owl_uart_info {
+ unsigned int tx_fifosize;
+};
+
+struct owl_uart_port {
+ struct uart_port port;
+ struct clk *clk;
+};
+
+#define to_owl_uart_port(prt) container_of(prt, struct owl_uart_port, prt)
+
+static struct owl_uart_port *owl_uart_ports[OWL_UART_PORT_NUM];
+
static inline void owl_uart_write(struct uart_port *port, u32 val, unsigned int off)
{
writel(val, port->membase + off);
@@ -54,6 +99,397 @@ static inline u32 owl_uart_read(struct uart_port *port, unsigned int off)
return readl(port->membase + off);
}
+static void owl_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+ u32 ctl;
+
+ ctl = owl_uart_read(port, OWL_UART_CTL);
+
+ if (mctrl & TIOCM_LOOP)
+ ctl |= OWL_UART_CTL_LBEN;
+ else
+ ctl &= ~OWL_UART_CTL_LBEN;
+
+ owl_uart_write(port, ctl, OWL_UART_CTL);
+}
+
+static unsigned int owl_uart_get_mctrl(struct uart_port *port)
+{
+ unsigned int mctrl = TIOCM_CAR | TIOCM_DSR;
+ u32 stat, ctl;
+
+ ctl = owl_uart_read(port, OWL_UART_CTL);
+ stat = owl_uart_read(port, OWL_UART_STAT);
+ if (stat & OWL_UART_STAT_RTSS)
+ mctrl |= TIOCM_RTS;
+ if ((stat & OWL_UART_STAT_CTSS) || !(ctl & OWL_UART_CTL_AFE))
+ mctrl |= TIOCM_CTS;
+ return mctrl;
+}
+
+static unsigned int owl_uart_tx_empty(struct uart_port *port)
+{
+ unsigned long flags;
+ u32 val;
+ unsigned int ret;
+
+ spin_lock_irqsave(&port->lock, flags);
+
+ val = owl_uart_read(port, OWL_UART_STAT);
+ ret = (val & OWL_UART_STAT_TFES) ? TIOCSER_TEMT : 0;
+
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ return ret;
+}
+
+static void owl_uart_stop_rx(struct uart_port *port)
+{
+ u32 val;
+
+ val = owl_uart_read(port, OWL_UART_CTL);
+ val &= ~(OWL_UART_CTL_RXIE | OWL_UART_CTL_RXDE);
+ owl_uart_write(port, val, OWL_UART_CTL);
+
+ val = owl_uart_read(port, OWL_UART_STAT);
+ val |= OWL_UART_STAT_RIP;
+ owl_uart_write(port, val, OWL_UART_STAT);
+}
+
+static void owl_uart_stop_tx(struct uart_port *port)
+{
+ u32 val;
+
+ val = owl_uart_read(port, OWL_UART_CTL);
+ val &= ~(OWL_UART_CTL_TXIE | OWL_UART_CTL_TXDE);
+ owl_uart_write(port, val, OWL_UART_CTL);
+
+ val = owl_uart_read(port, OWL_UART_STAT);
+ val |= OWL_UART_STAT_TIP;
+ owl_uart_write(port, val, OWL_UART_STAT);
+}
+
+static void owl_uart_start_tx(struct uart_port *port)
+{
+ u32 val;
+
+ if (uart_tx_stopped(port)) {
+ owl_uart_stop_tx(port);
+ return;
+ }
+
+ val = owl_uart_read(port, OWL_UART_STAT);
+ val |= OWL_UART_STAT_TIP;
+ owl_uart_write(port, val, OWL_UART_STAT);
+
+ val = owl_uart_read(port, OWL_UART_CTL);
+ val |= OWL_UART_CTL_TXIE;
+ owl_uart_write(port, val, OWL_UART_CTL);
+}
+
+static void owl_uart_send_chars(struct uart_port *port)
+{
+ struct circ_buf *xmit = &port->state->xmit;
+ unsigned int ch;
+
+ if (uart_tx_stopped(port))
+ return;
+
+ if (port->x_char) {
+ while (!(owl_uart_read(port, OWL_UART_STAT) & OWL_UART_STAT_TFFU))
+ cpu_relax();
+ owl_uart_write(port, port->x_char, OWL_UART_TXDAT);
+ port->icount.tx++;
+ port->x_char = 0;
+ }
+
+ while (!(owl_uart_read(port, OWL_UART_STAT) & OWL_UART_STAT_TFFU)) {
+ if (uart_circ_empty(xmit))
+ break;
+
+ ch = xmit->buf[xmit->tail];
+ owl_uart_write(port, ch, OWL_UART_TXDAT);
+ xmit->tail = (xmit->tail + 1) & (SERIAL_XMIT_SIZE - 1);
+ port->icount.tx++;
+ }
+
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(port);
+
+ if (uart_circ_empty(xmit))
+ owl_uart_stop_tx(port);
+}
+
+static void owl_uart_receive_chars(struct uart_port *port)
+{
+ u32 stat, val;
+
+ val = owl_uart_read(port, OWL_UART_CTL);
+ val &= ~OWL_UART_CTL_TRFS_TX;
+ owl_uart_write(port, val, OWL_UART_CTL);
+
+ stat = owl_uart_read(port, OWL_UART_STAT);
+ while (!(stat & OWL_UART_STAT_RFEM)) {
+ char flag = TTY_NORMAL;
+
+ if (stat & OWL_UART_STAT_RXER)
+ port->icount.overrun++;
+
+ if (stat & OWL_UART_STAT_RXST) {
+ /* We are not able to distinguish the error type. */
+ port->icount.brk++;
+ port->icount.frame++;
+
+ stat &= port->read_status_mask;
+ if (stat & OWL_UART_STAT_RXST)
+ flag = TTY_PARITY;
+ } else
+ port->icount.rx++;
+
+ val = owl_uart_read(port, OWL_UART_RXDAT);
+ val &= 0xff;
+
+ if ((stat & port->ignore_status_mask) == 0)
+ tty_insert_flip_char(&port->state->port, val, flag);
+
+ stat = owl_uart_read(port, OWL_UART_STAT);
+ }
+
+ spin_unlock(&port->lock);
+ tty_flip_buffer_push(&port->state->port);
+ spin_lock(&port->lock);
+}
+
+static irqreturn_t owl_uart_irq(int irq, void *dev_id)
+{
+ struct uart_port *port = dev_id;
+ unsigned long flags;
+ u32 stat;
+
+ spin_lock_irqsave(&port->lock, flags);
+
+ stat = owl_uart_read(port, OWL_UART_STAT);
+
+ if (stat & OWL_UART_STAT_RIP)
+ owl_uart_receive_chars(port);
+
+ if (stat & OWL_UART_STAT_TIP)
+ owl_uart_send_chars(port);
+
+ stat = owl_uart_read(port, OWL_UART_STAT);
+ stat |= OWL_UART_STAT_RIP | OWL_UART_STAT_TIP;
+ owl_uart_write(port, stat, OWL_UART_STAT);
+
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+static void owl_uart_shutdown(struct uart_port *port)
+{
+ u32 val;
+ unsigned long flags;
+
+ spin_lock_irqsave(&port->lock, flags);
+
+ val = owl_uart_read(port, OWL_UART_CTL);
+ val &= ~(OWL_UART_CTL_TXIE | OWL_UART_CTL_RXIE
+ | OWL_UART_CTL_TXDE | OWL_UART_CTL_RXDE | OWL_UART_CTL_EN);
+ owl_uart_write(port, val, OWL_UART_CTL);
+
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ free_irq(port->irq, port);
+}
+
+static int owl_uart_startup(struct uart_port *port)
+{
+ u32 val;
+ unsigned long flags;
+ int ret;
+
+ ret = request_irq(port->irq, owl_uart_irq, IRQF_TRIGGER_HIGH,
+ "owl-uart", port);
+ if (ret)
+ return ret;
+
+ spin_lock_irqsave(&port->lock, flags);
+
+ val = owl_uart_read(port, OWL_UART_STAT);
+ val |= OWL_UART_STAT_RIP | OWL_UART_STAT_TIP
+ | OWL_UART_STAT_RXER | OWL_UART_STAT_TFER | OWL_UART_STAT_RXST;
+ owl_uart_write(port, val, OWL_UART_STAT);
+
+ val = owl_uart_read(port, OWL_UART_CTL);
+ val |= OWL_UART_CTL_RXIE | OWL_UART_CTL_TXIE;
+ val |= OWL_UART_CTL_EN;
+ owl_uart_write(port, val, OWL_UART_CTL);
+
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ return 0;
+}
+
+static void owl_uart_change_baudrate(struct owl_uart_port *owl_port,
+ unsigned long baud)
+{
+ clk_set_rate(owl_port->clk, baud * 8);
+}
+
+static void owl_uart_set_termios(struct uart_port *port,
+ struct ktermios *termios,
+ struct ktermios *old)
+{
+ struct owl_uart_port *owl_port = to_owl_uart_port(port);
+ unsigned int baud;
+ u32 ctl;
+ unsigned long flags;
+
+ spin_lock_irqsave(&port->lock, flags);
+
+ ctl = owl_uart_read(port, OWL_UART_CTL);
+
+ ctl &= ~OWL_UART_CTL_DWLS_MASK;
+ switch (termios->c_cflag & CSIZE) {
+ case CS5:
+ ctl |= OWL_UART_CTL_DWLS_5BITS;
+ break;
+ case CS6:
+ ctl |= OWL_UART_CTL_DWLS_6BITS;
+ break;
+ case CS7:
+ ctl |= OWL_UART_CTL_DWLS_7BITS;
+ break;
+ case CS8:
+ default:
+ ctl |= OWL_UART_CTL_DWLS_8BITS;
+ break;
+ }
+
+ if (termios->c_cflag & CSTOPB)
+ ctl |= OWL_UART_CTL_STPS_2BITS;
+ else
+ ctl &= ~OWL_UART_CTL_STPS_2BITS;
+
+ ctl &= ~OWL_UART_CTL_PRS_MASK;
+ if (termios->c_cflag & PARENB) {
+ if (termios->c_cflag & CMSPAR) {
+ if (termios->c_cflag & PARODD)
+ ctl |= OWL_UART_CTL_PRS_MARK;
+ else
+ ctl |= OWL_UART_CTL_PRS_SPACE;
+ } else if (termios->c_cflag & PARODD)
+ ctl |= OWL_UART_CTL_PRS_ODD;
+ else
+ ctl |= OWL_UART_CTL_PRS_EVEN;
+ } else
+ ctl |= OWL_UART_CTL_PRS_NONE;
+
+ if (termios->c_cflag & CRTSCTS)
+ ctl |= OWL_UART_CTL_AFE;
+ else
+ ctl &= ~OWL_UART_CTL_AFE;
+
+ owl_uart_write(port, ctl, OWL_UART_CTL);
+
+ baud = uart_get_baud_rate(port, termios, old, 9600, 3200000);
+ owl_uart_change_baudrate(owl_port, baud);
+
+ /* Don't rewrite B0 */
+ if (tty_termios_baud_rate(termios))
+ tty_termios_encode_baud_rate(termios, baud, baud);
+
+ port->read_status_mask |= OWL_UART_STAT_RXER;
+ if (termios->c_iflag & INPCK)
+ port->read_status_mask |= OWL_UART_STAT_RXST;
+
+ uart_update_timeout(port, termios->c_cflag, baud);
+
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void owl_uart_release_port(struct uart_port *port)
+{
+ struct platform_device *pdev = to_platform_device(port->dev);
+ struct resource *res;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return;
+
+ if (port->flags & UPF_IOREMAP) {
+ devm_release_mem_region(port->dev, port->mapbase,
+ resource_size(res));
+ devm_iounmap(port->dev, port->membase);
+ port->membase = NULL;
+ }
+}
+
+static int owl_uart_request_port(struct uart_port *port)
+{
+ struct platform_device *pdev = to_platform_device(port->dev);
+ struct resource *res;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENXIO;
+
+ if (!devm_request_mem_region(port->dev, port->mapbase,
+ resource_size(res), dev_name(port->dev)))
+ return -EBUSY;
+
+ if (port->flags & UPF_IOREMAP) {
+ port->membase = devm_ioremap_nocache(port->dev, port->mapbase,
+ resource_size(res));
+ if (!port->membase)
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+static const char *owl_uart_type(struct uart_port *port)
+{
+ return (port->type == PORT_OWL) ? "owl-uart" : NULL;
+}
+
+static int owl_uart_verify_port(struct uart_port *port,
+ struct serial_struct *ser)
+{
+ if (port->type != PORT_OWL)
+ return -EINVAL;
+
+ if (port->irq != ser->irq)
+ return -EINVAL;
+
+ return 0;
+}
+
+static void owl_uart_config_port(struct uart_port *port, int flags)
+{
+ if (flags & UART_CONFIG_TYPE) {
+ port->type = PORT_OWL;
+ owl_uart_request_port(port);
+ }
+}
+
+static const struct uart_ops owl_uart_ops = {
+ .set_mctrl = owl_uart_set_mctrl,
+ .get_mctrl = owl_uart_get_mctrl,
+ .tx_empty = owl_uart_tx_empty,
+ .start_tx = owl_uart_start_tx,
+ .stop_rx = owl_uart_stop_rx,
+ .stop_tx = owl_uart_stop_tx,
+ .startup = owl_uart_startup,
+ .shutdown = owl_uart_shutdown,
+ .set_termios = owl_uart_set_termios,
+ .type = owl_uart_type,
+ .config_port = owl_uart_config_port,
+ .request_port = owl_uart_request_port,
+ .release_port = owl_uart_release_port,
+ .verify_port = owl_uart_verify_port,
+};
+
#ifdef CONFIG_SERIAL_OWL_CONSOLE
static void owl_console_putchar(struct uart_port *port, int ch)
@@ -110,6 +546,57 @@ static void owl_uart_port_write(struct uart_port *port, const char *s,
local_irq_restore(flags);
}
+static void owl_uart_console_write(struct console *co, const char *s,
+ u_int count)
+{
+ struct owl_uart_port *owl_port;
+
+ owl_port = owl_uart_ports[co->index];
+ if (!owl_port)
+ return;
+
+ owl_uart_port_write(&owl_port->port, s, count);
+}
+
+static int owl_uart_console_setup(struct console *co, char *options)
+{
+ struct owl_uart_port *owl_port;
+ int baud = 115200;
+ int bits = 8;
+ int parity = 'n';
+ int flow = 'n';
+
+ if (co->index < 0 || co->index >= OWL_UART_PORT_NUM)
+ return -EINVAL;
+
+ owl_port = owl_uart_ports[co->index];
+ if (!owl_port || !owl_port->port.membase)
+ return -ENODEV;
+
+ if (options)
+ uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+ return uart_set_options(&owl_port->port, co, baud, parity, bits, flow);
+}
+
+static struct console owl_uart_console = {
+ .name = OWL_UART_DEV_NAME,
+ .write = owl_uart_console_write,
+ .device = uart_console_device,
+ .setup = owl_uart_console_setup,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+ .data = &owl_uart_driver,
+};
+
+static int __init owl_uart_console_init(void)
+{
+ register_console(&owl_uart_console);
+
+ return 0;
+}
+console_initcall(owl_uart_console_init);
+
static void owl_uart_early_console_write(struct console *co,
const char *s,
u_int count)
@@ -132,4 +619,148 @@ owl_uart_early_console_setup(struct earlycon_device *device, const char *opt)
OF_EARLYCON_DECLARE(owl, "actions,owl-uart",
owl_uart_early_console_setup);
-#endif /* CONFIG_SERIAL_OWL_CONSOLE */
+#define OWL_UART_CONSOLE (&owl_uart_console)
+#else
+#define OWL_UART_CONSOLE NULL
+#endif
+
+static struct uart_driver owl_uart_driver = {
+ .owner = THIS_MODULE,
+ .driver_name = "owl-uart",
+ .dev_name = OWL_UART_DEV_NAME,
+ .nr = OWL_UART_PORT_NUM,
+ .cons = OWL_UART_CONSOLE,
+};
+
+static const struct owl_uart_info owl_s500_info = {
+ .tx_fifosize = 16,
+};
+
+static const struct owl_uart_info owl_s900_info = {
+ .tx_fifosize = 32,
+};
+
+static const struct of_device_id owl_uart_dt_matches[] = {
+ { .compatible = "actions,s500-uart", .data = &owl_s500_info },
+ { .compatible = "actions,s900-uart", .data = &owl_s900_info },
+ { }
+};
+MODULE_DEVICE_TABLE(of, owl_uart_dt_matches);
+
+static int owl_uart_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *match;
+ const struct owl_uart_info *info = NULL;
+ struct resource *res_mem;
+ struct owl_uart_port *owl_port;
+ int ret, irq;
+
+ if (pdev->dev.of_node) {
+ pdev->id = of_alias_get_id(pdev->dev.of_node, "serial");
+ match = of_match_node(owl_uart_dt_matches, pdev->dev.of_node);
+ if (match)
+ info = match->data;
+ }
+
+ if (pdev->id < 0 || pdev->id >= OWL_UART_PORT_NUM) {
+ dev_err(&pdev->dev, "id %d out of range\n", pdev->id);
+ return -EINVAL;
+ }
+
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res_mem) {
+ dev_err(&pdev->dev, "could not get mem\n");
+ return -ENODEV;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "could not get irq\n");
+ return irq;
+ }
+
+ if (owl_uart_ports[pdev->id]) {
+ dev_err(&pdev->dev, "port %d already allocated\n", pdev->id);
+ return -EBUSY;
+ }
+
+ owl_port = devm_kzalloc(&pdev->dev, sizeof(*owl_port), GFP_KERNEL);
+ if (!owl_port)
+ return -ENOMEM;
+
+ owl_port->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(owl_port->clk)) {
+ dev_err(&pdev->dev, "could not get clk\n");
+ return PTR_ERR(owl_port->clk);
+ }
+
+ owl_port->port.dev = &pdev->dev;
+ owl_port->port.line = pdev->id;
+ owl_port->port.type = PORT_OWL;
+ owl_port->port.iotype = UPIO_MEM;
+ owl_port->port.mapbase = res_mem->start;
+ owl_port->port.irq = irq;
+ owl_port->port.uartclk = clk_get_rate(owl_port->clk);
+ if (owl_port->port.uartclk == 0) {
+ dev_err(&pdev->dev, "clock rate is zero\n");
+ return -EINVAL;
+ }
+ owl_port->port.flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_LOW_LATENCY;
+ owl_port->port.x_char = 0;
+ owl_port->port.fifosize = (info) ? info->tx_fifosize : 16;
+ owl_port->port.ops = &owl_uart_ops;
+
+ owl_uart_ports[pdev->id] = owl_port;
+ platform_set_drvdata(pdev, owl_port);
+
+ ret = uart_add_one_port(&owl_uart_driver, &owl_port->port);
+ if (ret)
+ owl_uart_ports[pdev->id] = NULL;
+
+ return ret;
+}
+
+static int owl_uart_remove(struct platform_device *pdev)
+{
+ struct owl_uart_port *owl_port = platform_get_drvdata(pdev);
+
+ uart_remove_one_port(&owl_uart_driver, &owl_port->port);
+ owl_uart_ports[pdev->id] = NULL;
+
+ return 0;
+}
+
+static struct platform_driver owl_uart_platform_driver = {
+ .probe = owl_uart_probe,
+ .remove = owl_uart_remove,
+ .driver = {
+ .name = "owl-uart",
+ .of_match_table = owl_uart_dt_matches,
+ },
+};
+
+static int __init owl_uart_init(void)
+{
+ int ret;
+
+ ret = uart_register_driver(&owl_uart_driver);
+ if (ret)
+ return ret;
+
+ ret = platform_driver_register(&owl_uart_platform_driver);
+ if (ret)
+ uart_unregister_driver(&owl_uart_driver);
+
+ return ret;
+}
+
+static void __init owl_uart_exit(void)
+{
+ platform_driver_unregister(&owl_uart_platform_driver);
+ uart_unregister_driver(&owl_uart_driver);
+}
+
+module_init(owl_uart_init);
+module_exit(owl_uart_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c
index d3796dc..ae8cfc8 100644
--- a/drivers/tty/serial/pch_uart.c
+++ b/drivers/tty/serial/pch_uart.c
@@ -46,11 +46,6 @@ enum {
PCH_UART_HANDLED_LS_INT_SHIFT,
};
-enum {
- PCH_UART_8LINE,
- PCH_UART_2LINE,
-};
-
#define PCH_UART_DRIVER_DEVICE "ttyPCH"
/* Set the max number of UART port
@@ -267,7 +262,7 @@ struct eg20t_port {
/**
* struct pch_uart_driver_data - private data structure for UART-DMA
- * @port_type: The number of DMA channel
+ * @port_type: The type of UART port
* @line_no: UART port line number (0, 1, 2...)
*/
struct pch_uart_driver_data {
@@ -290,17 +285,17 @@ enum pch_uart_num_t {
};
static struct pch_uart_driver_data drv_dat[] = {
- [pch_et20t_uart0] = {PCH_UART_8LINE, 0},
- [pch_et20t_uart1] = {PCH_UART_2LINE, 1},
- [pch_et20t_uart2] = {PCH_UART_2LINE, 2},
- [pch_et20t_uart3] = {PCH_UART_2LINE, 3},
- [pch_ml7213_uart0] = {PCH_UART_8LINE, 0},
- [pch_ml7213_uart1] = {PCH_UART_2LINE, 1},
- [pch_ml7213_uart2] = {PCH_UART_2LINE, 2},
- [pch_ml7223_uart0] = {PCH_UART_8LINE, 0},
- [pch_ml7223_uart1] = {PCH_UART_2LINE, 1},
- [pch_ml7831_uart0] = {PCH_UART_8LINE, 0},
- [pch_ml7831_uart1] = {PCH_UART_2LINE, 1},
+ [pch_et20t_uart0] = {PORT_PCH_8LINE, 0},
+ [pch_et20t_uart1] = {PORT_PCH_2LINE, 1},
+ [pch_et20t_uart2] = {PORT_PCH_2LINE, 2},
+ [pch_et20t_uart3] = {PORT_PCH_2LINE, 3},
+ [pch_ml7213_uart0] = {PORT_PCH_8LINE, 0},
+ [pch_ml7213_uart1] = {PORT_PCH_2LINE, 1},
+ [pch_ml7213_uart2] = {PORT_PCH_2LINE, 2},
+ [pch_ml7223_uart0] = {PORT_PCH_8LINE, 0},
+ [pch_ml7223_uart1] = {PORT_PCH_2LINE, 1},
+ [pch_ml7831_uart0] = {PORT_PCH_8LINE, 0},
+ [pch_ml7831_uart1] = {PORT_PCH_2LINE, 1},
};
#ifdef CONFIG_SERIAL_PCH_UART_CONSOLE
@@ -1777,10 +1772,10 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev,
goto init_port_free_txbuf;
switch (port_type) {
- case PORT_UNKNOWN:
+ case PORT_PCH_8LINE:
fifosize = 256; /* EG20T/ML7213: UART0 */
break;
- case PORT_8250:
+ case PORT_PCH_2LINE:
fifosize = 64; /* EG20T:UART1~3 ML7213: UART1~2*/
break;
default:
@@ -1804,7 +1799,7 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev,
priv->fifo_size = fifosize;
priv->uartclk = pch_uart_get_uartclk();
- priv->port_type = PORT_MAX_8250 + port_type + 1;
+ priv->port_type = port_type;
priv->port.dev = &pdev->dev;
priv->port.iobase = iobase;
priv->port.membase = NULL;
@@ -1862,8 +1857,7 @@ static void pch_uart_exit_port(struct eg20t_port *priv)
{
#ifdef CONFIG_DEBUG_FS
- if (priv->debugfs)
- debugfs_remove(priv->debugfs);
+ debugfs_remove(priv->debugfs);
#endif
uart_remove_one_port(&pch_uart_driver, &priv->port);
free_page((unsigned long)priv->rxbuf.buf);
diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c
index 0da5294..6ccdd01 100644
--- a/drivers/tty/serial/pmac_zilog.c
+++ b/drivers/tty/serial/pmac_zilog.c
@@ -1671,8 +1671,8 @@ static int __init pmz_probe(void)
if (!node_a && !node_b) {
of_node_put(node_a);
of_node_put(node_b);
- printk(KERN_ERR "pmac_zilog: missing node %c for escc %s\n",
- (!node_a) ? 'a' : 'b', node_p->full_name);
+ printk(KERN_ERR "pmac_zilog: missing node %c for escc %pOF\n",
+ (!node_a) ? 'a' : 'b', node_p);
continue;
}
diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c
index d92a150..cf9b736 100644
--- a/drivers/tty/serial/serial-tegra.c
+++ b/drivers/tty/serial/serial-tegra.c
@@ -1310,7 +1310,7 @@ static int tegra_uart_probe(struct platform_device *pdev)
return PTR_ERR(tup->uart_clk);
}
- tup->rst = devm_reset_control_get(&pdev->dev, "serial");
+ tup->rst = devm_reset_control_get_exclusive(&pdev->dev, "serial");
if (IS_ERR(tup->rst)) {
dev_err(&pdev->dev, "Couldn't get the reset\n");
return PTR_ERR(tup->rst);
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index f534a40..3a14ccc 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -36,7 +36,7 @@
#include <linux/delay.h>
#include <linux/mutex.h>
-#include <asm/irq.h>
+#include <linux/irq.h>
#include <linux/uaccess.h>
/*
@@ -165,6 +165,27 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear)
#define uart_set_mctrl(port, set) uart_update_mctrl(port, set, 0)
#define uart_clear_mctrl(port, clear) uart_update_mctrl(port, 0, clear)
+static void uart_port_dtr_rts(struct uart_port *uport, int raise)
+{
+ int rs485_on = uport->rs485_config &&
+ (uport->rs485.flags & SER_RS485_ENABLED);
+ int RTS_after_send = !!(uport->rs485.flags & SER_RS485_RTS_AFTER_SEND);
+
+ if (raise) {
+ if (rs485_on && !RTS_after_send) {
+ uart_set_mctrl(uport, TIOCM_DTR);
+ uart_clear_mctrl(uport, TIOCM_RTS);
+ } else {
+ uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS);
+ }
+ } else {
+ unsigned int clear = TIOCM_DTR;
+
+ clear |= (!rs485_on || !RTS_after_send) ? TIOCM_RTS : 0;
+ uart_clear_mctrl(uport, clear);
+ }
+}
+
/*
* Startup the port. This will be called once per open. All calls
* will be serialised by the per-port mutex.
@@ -214,7 +235,7 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state,
* port is open and ready to respond.
*/
if (init_hw && C_BAUD(tty))
- uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR);
+ uart_port_dtr_rts(uport, 1);
}
/*
@@ -272,7 +293,7 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state)
uport->cons->cflag = tty->termios.c_cflag;
if (!tty || C_HUPCL(tty))
- uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS);
+ uart_port_dtr_rts(uport, 0);
uart_port_shutdown(port);
}
@@ -744,7 +765,7 @@ static int uart_get_info(struct tty_port *port, struct serial_struct *retinfo)
if (HIGH_BITS_OFFSET)
retinfo->port_high = (long) uport->iobase >> HIGH_BITS_OFFSET;
retinfo->irq = uport->irq;
- retinfo->flags = uport->flags;
+ retinfo->flags = (__force int)uport->flags;
retinfo->xmit_fifo_size = uport->fifosize;
retinfo->baud_base = uport->uartclk / 16;
retinfo->close_delay = jiffies_to_msecs(port->close_delay) / 10;
@@ -818,7 +839,7 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port,
new_info->type != uport->type);
old_flags = uport->flags;
- new_flags = new_info->flags;
+ new_flags = (__force upf_t)new_info->flags;
old_custom_divisor = uport->custom_divisor;
if (!capable(CAP_SYS_ADMIN)) {
@@ -1658,7 +1679,7 @@ static int uart_carrier_raised(struct tty_port *port)
return 0;
}
-static void uart_dtr_rts(struct tty_port *port, int onoff)
+static void uart_dtr_rts(struct tty_port *port, int raise)
{
struct uart_state *state = container_of(port, struct uart_state, port);
struct uart_port *uport;
@@ -1666,12 +1687,7 @@ static void uart_dtr_rts(struct tty_port *port, int onoff)
uport = uart_port_ref(state);
if (!uport)
return;
-
- if (onoff)
- uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS);
- else
- uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS);
-
+ uart_port_dtr_rts(uport, raise);
uart_port_deref(uport);
}
@@ -2083,8 +2099,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
tty_dev = device_find_child(uport->dev, &match, serial_match_port);
if (tty_dev && device_may_wakeup(tty_dev)) {
- if (!enable_irq_wake(uport->irq))
- uport->irq_wake = 1;
+ enable_irq_wake(uport->irq);
put_device(tty_dev);
mutex_unlock(&port->mutex);
return 0;
@@ -2147,10 +2162,8 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
tty_dev = device_find_child(uport->dev, &match, serial_match_port);
if (!uport->suspended && device_may_wakeup(tty_dev)) {
- if (uport->irq_wake) {
+ if (irqd_is_wakeup_set(irq_get_irq_data((uport->irq))))
disable_irq_wake(uport->irq);
- uport->irq_wake = 0;
- }
put_device(tty_dev);
mutex_unlock(&port->mutex);
return 0;
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index e08b16b..784dd42 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -3073,8 +3073,7 @@ static struct plat_sci_port *sci_parse_dt(struct platform_device *pdev,
p->type = SCI_OF_TYPE(match->data);
p->regtype = SCI_OF_REGTYPE(match->data);
- if (of_find_property(np, "uart-has-rtscts", NULL))
- sp->has_rtscts = true;
+ sp->has_rtscts = of_property_read_bool(np, "uart-has-rtscts");
return p;
}
diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c
index 90996ad..e902494 100644
--- a/drivers/tty/serial/sprd_serial.c
+++ b/drivers/tty/serial/sprd_serial.c
@@ -63,6 +63,7 @@
/* interrupt clear register */
#define SPRD_ICLR 0x0014
+#define SPRD_ICLR_TIMEOUT BIT(13)
/* line control register */
#define SPRD_LCR 0x0018
@@ -298,7 +299,8 @@ static irqreturn_t sprd_handle_irq(int irq, void *dev_id)
return IRQ_NONE;
}
- serial_out(port, SPRD_ICLR, ~0);
+ if (ims & SPRD_IMSR_TIMEOUT)
+ serial_out(port, SPRD_ICLR, SPRD_ICLR_TIMEOUT);
if (ims & (SPRD_IMSR_RX_FIFO_FULL |
SPRD_IMSR_BREAK_DETECT | SPRD_IMSR_TIMEOUT))
@@ -729,8 +731,8 @@ static int sprd_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
- dev_err(&pdev->dev, "not provide irq resource\n");
- return -ENODEV;
+ dev_err(&pdev->dev, "not provide irq resource: %d\n", irq);
+ return irq;
}
up->irq = irq;
diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c
index 6b0ca65..b313a79 100644
--- a/drivers/tty/serial/st-asc.c
+++ b/drivers/tty/serial/st-asc.c
@@ -310,7 +310,7 @@ static void asc_receive_chars(struct uart_port *port)
if (mode == ASC_CTL_MODE_8BIT || mode == ASC_CTL_MODE_8BIT_PAR)
ignore_pe = true;
- if (port->irq_wake)
+ if (irqd_is_wakeup_set(irq_get_irq_data(port->irq)))
pm_wakeup_event(tport->tty->dev, 0);
while ((status = asc_in(port, ASC_STA)) & ASC_STA_RBF) {
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 0338562..03a58326 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) Maxime Coquelin 2015
+ * Copyright (C) STMicroelectronics SA 2017
* Authors: Maxime Coquelin <mcoquelin.stm32@gmail.com>
* Gerald Baeza <gerald.baeza@st.com>
* License terms: GNU General Public License (GPL), version 2
@@ -25,6 +26,7 @@
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <linux/pm_wakeirq.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
#include <linux/spinlock.h>
@@ -110,14 +112,13 @@ static void stm32_receive_chars(struct uart_port *port, bool threaded)
unsigned long c;
u32 sr;
char flag;
- static int last_res = RX_BUF_L;
- if (port->irq_wake)
+ if (irqd_is_wakeup_set(irq_get_irq_data(port->irq)))
pm_wakeup_event(tport->tty->dev, 0);
- while (stm32_pending_rx(port, &sr, &last_res, threaded)) {
+ while (stm32_pending_rx(port, &sr, &stm32_port->last_res, threaded)) {
sr |= USART_SR_DUMMY_RX;
- c = stm32_get_char(port, &sr, &last_res);
+ c = stm32_get_char(port, &sr, &stm32_port->last_res);
flag = TTY_NORMAL;
port->icount.rx++;
@@ -202,7 +203,7 @@ static void stm32_transmit_chars_pio(struct uart_port *port)
ret = readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr,
isr,
(isr & USART_SR_TXE),
- 10, 100);
+ 10, 100000);
if (ret)
dev_err(port->dev, "tx empty not set\n");
@@ -326,6 +327,10 @@ static irqreturn_t stm32_interrupt(int irq, void *ptr)
sr = readl_relaxed(port->membase + ofs->isr);
+ if ((sr & USART_SR_WUF) && (ofs->icr != UNDEF_REG))
+ writel_relaxed(USART_ICR_WUCF,
+ port->membase + ofs->icr);
+
if ((sr & USART_SR_RXNE) && !(stm32_port->rx_ch))
stm32_receive_chars(port, false);
@@ -442,6 +447,7 @@ static int stm32_startup(struct uart_port *port)
{
struct stm32_port *stm32_port = to_stm32_port(port);
struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+ struct stm32_usart_config *cfg = &stm32_port->info->cfg;
const char *name = to_platform_device(port->dev)->name;
u32 val;
int ret;
@@ -452,7 +458,18 @@ static int stm32_startup(struct uart_port *port)
if (ret)
return ret;
+ if (cfg->has_wakeup && stm32_port->wakeirq >= 0) {
+ ret = dev_pm_set_dedicated_wake_irq(port->dev,
+ stm32_port->wakeirq);
+ if (ret) {
+ free_irq(port->irq, port);
+ return ret;
+ }
+ }
+
val = USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;
+ if (stm32_port->fifoen)
+ val |= USART_CR1_FIFOEN;
stm32_set_bits(port, ofs->cr1, val);
return 0;
@@ -467,8 +484,11 @@ static void stm32_shutdown(struct uart_port *port)
val = USART_CR1_TXEIE | USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;
val |= BIT(cfg->uart_enable_bit);
+ if (stm32_port->fifoen)
+ val |= USART_CR1_FIFOEN;
stm32_clr_bits(port, ofs->cr1, val);
+ dev_pm_clear_wake_irq(port->dev);
free_irq(port->irq, port);
}
@@ -496,6 +516,8 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
cr1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE;
cr1 |= BIT(cfg->uart_enable_bit);
+ if (stm32_port->fifoen)
+ cr1 |= USART_CR1_FIFOEN;
cr2 = 0;
cr3 = 0;
@@ -518,7 +540,7 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
port->status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS);
if (cflag & CRTSCTS) {
port->status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS;
- cr3 |= USART_CR3_CTSE;
+ cr3 |= USART_CR3_CTSE | USART_CR3_RTSE;
}
usartdiv = DIV_ROUND_CLOSEST(port->uartclk, baud);
@@ -659,6 +681,8 @@ static int stm32_init_port(struct stm32_port *stm32port,
port->ops = &stm32_uart_ops;
port->dev = &pdev->dev;
port->irq = platform_get_irq(pdev, 0);
+ stm32port->wakeirq = platform_get_irq(pdev, 1);
+ stm32port->fifoen = stm32port->info->cfg.has_fifo;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
port->membase = devm_ioremap_resource(&pdev->dev, res);
@@ -678,8 +702,10 @@ static int stm32_init_port(struct stm32_port *stm32port,
return ret;
stm32port->port.uartclk = clk_get_rate(stm32port->clk);
- if (!stm32port->port.uartclk)
+ if (!stm32port->port.uartclk) {
+ clk_disable_unprepare(stm32port->clk);
ret = -EINVAL;
+ }
return ret;
}
@@ -693,8 +719,10 @@ static struct stm32_port *stm32_of_get_stm32_port(struct platform_device *pdev)
return NULL;
id = of_alias_get_id(np, "serial");
- if (id < 0)
- id = 0;
+ if (id < 0) {
+ dev_err(&pdev->dev, "failed to get alias id, errno %d\n", id);
+ return NULL;
+ }
if (WARN_ON(id >= STM32_MAX_PORTS))
return NULL;
@@ -702,6 +730,7 @@ static struct stm32_port *stm32_of_get_stm32_port(struct platform_device *pdev)
stm32_ports[id].hw_flow_control = of_property_read_bool(np,
"st,hw-flow-ctrl");
stm32_ports[id].port.line = id;
+ stm32_ports[id].last_res = RX_BUF_L;
return &stm32_ports[id];
}
@@ -711,6 +740,8 @@ static const struct of_device_id stm32_match[] = {
{ .compatible = "st,stm32-uart", .data = &stm32f4_info},
{ .compatible = "st,stm32f7-usart", .data = &stm32f7_info},
{ .compatible = "st,stm32f7-uart", .data = &stm32f7_info},
+ { .compatible = "st,stm32h7-usart", .data = &stm32h7_info},
+ { .compatible = "st,stm32h7-uart", .data = &stm32h7_info},
{},
};
@@ -860,9 +891,15 @@ static int stm32_serial_probe(struct platform_device *pdev)
if (ret)
return ret;
+ if (stm32port->info->cfg.has_wakeup && stm32port->wakeirq >= 0) {
+ ret = device_init_wakeup(&pdev->dev, true);
+ if (ret)
+ goto err_uninit;
+ }
+
ret = uart_add_one_port(&stm32_usart_driver, &stm32port->port);
if (ret)
- return ret;
+ goto err_nowup;
ret = stm32_of_dma_rx_probe(stm32port, pdev);
if (ret)
@@ -875,6 +912,15 @@ static int stm32_serial_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, &stm32port->port);
return 0;
+
+err_nowup:
+ if (stm32port->info->cfg.has_wakeup && stm32port->wakeirq >= 0)
+ device_init_wakeup(&pdev->dev, false);
+
+err_uninit:
+ clk_disable_unprepare(stm32port->clk);
+
+ return ret;
}
static int stm32_serial_remove(struct platform_device *pdev)
@@ -882,6 +928,7 @@ static int stm32_serial_remove(struct platform_device *pdev)
struct uart_port *port = platform_get_drvdata(pdev);
struct stm32_port *stm32_port = to_stm32_port(port);
struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+ struct stm32_usart_config *cfg = &stm32_port->info->cfg;
stm32_clr_bits(port, ofs->cr3, USART_CR3_DMAR);
@@ -903,6 +950,9 @@ static int stm32_serial_remove(struct platform_device *pdev)
TX_BUF_L, stm32_port->tx_buf,
stm32_port->tx_dma_buf);
+ if (cfg->has_wakeup && stm32_port->wakeirq >= 0)
+ device_init_wakeup(&pdev->dev, false);
+
clk_disable_unprepare(stm32_port->clk);
return uart_remove_one_port(&stm32_usart_driver, port);
@@ -1008,11 +1058,66 @@ static struct uart_driver stm32_usart_driver = {
.cons = STM32_SERIAL_CONSOLE,
};
+#ifdef CONFIG_PM_SLEEP
+static void stm32_serial_enable_wakeup(struct uart_port *port, bool enable)
+{
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+ struct stm32_usart_config *cfg = &stm32_port->info->cfg;
+ u32 val;
+
+ if (!cfg->has_wakeup || stm32_port->wakeirq < 0)
+ return;
+
+ if (enable) {
+ stm32_clr_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit));
+ stm32_set_bits(port, ofs->cr1, USART_CR1_UESM);
+ val = readl_relaxed(port->membase + ofs->cr3);
+ val &= ~USART_CR3_WUS_MASK;
+ /* Enable Wake up interrupt from low power on start bit */
+ val |= USART_CR3_WUS_START_BIT | USART_CR3_WUFIE;
+ writel_relaxed(val, port->membase + ofs->cr3);
+ stm32_set_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit));
+ } else {
+ stm32_clr_bits(port, ofs->cr1, USART_CR1_UESM);
+ }
+}
+
+static int stm32_serial_suspend(struct device *dev)
+{
+ struct uart_port *port = dev_get_drvdata(dev);
+
+ uart_suspend_port(&stm32_usart_driver, port);
+
+ if (device_may_wakeup(dev))
+ stm32_serial_enable_wakeup(port, true);
+ else
+ stm32_serial_enable_wakeup(port, false);
+
+ return 0;
+}
+
+static int stm32_serial_resume(struct device *dev)
+{
+ struct uart_port *port = dev_get_drvdata(dev);
+
+ if (device_may_wakeup(dev))
+ stm32_serial_enable_wakeup(port, false);
+
+ return uart_resume_port(&stm32_usart_driver, port);
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static const struct dev_pm_ops stm32_serial_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(stm32_serial_suspend, stm32_serial_resume)
+};
+
static struct platform_driver stm32_serial_driver = {
.probe = stm32_serial_probe,
.remove = stm32_serial_remove,
.driver = {
.name = DRIVER_NAME,
+ .pm = &stm32_serial_pm_ops,
.of_match_table = of_match_ptr(stm32_match),
},
};
diff --git a/drivers/tty/serial/stm32-usart.h b/drivers/tty/serial/stm32-usart.h
index cd97ceb..ffc0c52 100644
--- a/drivers/tty/serial/stm32-usart.h
+++ b/drivers/tty/serial/stm32-usart.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) Maxime Coquelin 2015
+ * Copyright (C) STMicroelectronics SA 2017
* Authors: Maxime Coquelin <mcoquelin.stm32@gmail.com>
* Gerald Baeza <gerald_baeza@yahoo.fr>
* License terms: GNU General Public License (GPL), version 2
@@ -24,6 +25,8 @@ struct stm32_usart_offsets {
struct stm32_usart_config {
u8 uart_enable_bit; /* USART_CR1_UE */
bool has_7bits_data;
+ bool has_wakeup;
+ bool has_fifo;
};
struct stm32_usart_info {
@@ -74,6 +77,28 @@ struct stm32_usart_info stm32f7_info = {
}
};
+struct stm32_usart_info stm32h7_info = {
+ .ofs = {
+ .cr1 = 0x00,
+ .cr2 = 0x04,
+ .cr3 = 0x08,
+ .brr = 0x0c,
+ .gtpr = 0x10,
+ .rtor = 0x14,
+ .rqr = 0x18,
+ .isr = 0x1c,
+ .icr = 0x20,
+ .rdr = 0x24,
+ .tdr = 0x28,
+ },
+ .cfg = {
+ .uart_enable_bit = 0,
+ .has_7bits_data = true,
+ .has_wakeup = true,
+ .has_fifo = true,
+ }
+};
+
/* USART_SR (F4) / USART_ISR (F7) */
#define USART_SR_PE BIT(0)
#define USART_SR_FE BIT(1)
@@ -93,6 +118,7 @@ struct stm32_usart_info stm32f7_info = {
#define USART_SR_BUSY BIT(16) /* F7 */
#define USART_SR_CMF BIT(17) /* F7 */
#define USART_SR_SBKF BIT(18) /* F7 */
+#define USART_SR_WUF BIT(20) /* H7 */
#define USART_SR_TEACK BIT(21) /* F7 */
#define USART_SR_ERR_MASK (USART_SR_LBD | USART_SR_ORE | \
USART_SR_FE | USART_SR_PE)
@@ -113,6 +139,7 @@ struct stm32_usart_info stm32f7_info = {
/* USART_CR1 */
#define USART_CR1_SBK BIT(0)
#define USART_CR1_RWU BIT(1) /* F4 */
+#define USART_CR1_UESM BIT(1) /* H7 */
#define USART_CR1_RE BIT(2)
#define USART_CR1_TE BIT(3)
#define USART_CR1_IDLEIE BIT(4)
@@ -134,6 +161,7 @@ struct stm32_usart_info stm32f7_info = {
#define USART_CR1_EOBIE BIT(27) /* F7 */
#define USART_CR1_M1 BIT(28) /* F7 */
#define USART_CR1_IE_MASK (GENMASK(8, 4) | BIT(14) | BIT(26) | BIT(27))
+#define USART_CR1_FIFOEN BIT(29) /* H7 */
/* USART_CR2 */
#define USART_CR2_ADD_MASK GENMASK(3, 0) /* F4 */
@@ -175,6 +203,9 @@ struct stm32_usart_info stm32f7_info = {
#define USART_CR3_DEM BIT(14) /* F7 */
#define USART_CR3_DEP BIT(15) /* F7 */
#define USART_CR3_SCARCNT_MASK GENMASK(19, 17) /* F7 */
+#define USART_CR3_WUS_MASK GENMASK(21, 20) /* H7 */
+#define USART_CR3_WUS_START_BIT BIT(21) /* H7 */
+#define USART_CR3_WUFIE BIT(22) /* H7 */
/* USART_GTPR */
#define USART_GTPR_PSC_MASK GENMASK(7, 0)
@@ -203,9 +234,10 @@ struct stm32_usart_info stm32f7_info = {
#define USART_ICR_RTOCF BIT(11) /* F7 */
#define USART_ICR_EOBCF BIT(12) /* F7 */
#define USART_ICR_CMCF BIT(17) /* F7 */
+#define USART_ICR_WUCF BIT(20) /* H7 */
#define STM32_SERIAL_NAME "ttyS"
-#define STM32_MAX_PORTS 6
+#define STM32_MAX_PORTS 8
#define RX_BUF_L 200 /* dma rx buffer length */
#define RX_BUF_P RX_BUF_L /* dma rx buffer period */
@@ -221,8 +253,11 @@ struct stm32_port {
struct dma_chan *tx_ch; /* dma tx channel */
dma_addr_t tx_dma_buf; /* dma tx buffer bus address */
unsigned char *tx_buf; /* dma tx buffer cpu address */
+ int last_res;
bool tx_dma_busy; /* dma tx busy */
bool hw_flow_control;
+ bool fifoen;
+ int wakeirq;
};
static struct stm32_port stm32_ports[STM32_MAX_PORTS];
diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c
index b5e3195..653a076 100644
--- a/drivers/tty/serial/sunsab.c
+++ b/drivers/tty/serial/sunsab.c
@@ -819,7 +819,7 @@ static int sunsab_verify_port(struct uart_port *port, struct serial_struct *ser)
return -EINVAL;
}
-static struct uart_ops sunsab_pops = {
+static const struct uart_ops sunsab_pops = {
.tx_empty = sunsab_tx_empty,
.set_mctrl = sunsab_set_mctrl,
.get_mctrl = sunsab_get_mctrl,
diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c
index 72df2e1..95d34d7 100644
--- a/drivers/tty/serial/sunsu.c
+++ b/drivers/tty/serial/sunsu.c
@@ -958,7 +958,7 @@ sunsu_type(struct uart_port *port)
return uart_config[type].name;
}
-static struct uart_ops sunsu_pops = {
+static const struct uart_ops sunsu_pops = {
.tx_empty = sunsu_tx_empty,
.set_mctrl = sunsu_set_mctrl,
.get_mctrl = sunsu_get_mctrl,
@@ -1212,8 +1212,8 @@ static int sunsu_kbd_ms_init(struct uart_sunsu_port *up)
if (up->port.type == PORT_UNKNOWN)
return -ENODEV;
- printk("%s: %s port at %llx, irq %u\n",
- up->port.dev->of_node->full_name,
+ printk("%pOF: %s port at %llx, irq %u\n",
+ up->port.dev->of_node,
(up->su_type == SU_PORT_KBD) ? "Keyboard" : "Mouse",
(unsigned long long) up->port.mapbase,
up->port.irq);
diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c
index 481eb29..55b7027 100644
--- a/drivers/tty/serial/ucc_uart.c
+++ b/drivers/tty/serial/ucc_uart.c
@@ -1085,7 +1085,7 @@ static int qe_uart_verify_port(struct uart_port *port,
*
* Details on these functions can be found in Documentation/serial/driver
*/
-static struct uart_ops qe_uart_pops = {
+static const struct uart_ops qe_uart_pops = {
.tx_empty = qe_uart_tx_empty,
.set_mctrl = qe_uart_set_mctrl,
.get_mctrl = qe_uart_get_mctrl,
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index fde55dc..31a630a 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -1163,7 +1163,7 @@ static void cdns_uart_console_putchar(struct uart_port *port, int ch)
writel(ch, port->membase + CDNS_UART_FIFO);
}
-static void __init cdns_early_write(struct console *con, const char *s,
+static void cdns_early_write(struct console *con, const char *s,
unsigned n)
{
struct earlycon_device *dev = con->data;
diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c
index 3fafc5a..3be9811 100644
--- a/drivers/tty/synclink.c
+++ b/drivers/tty/synclink.c
@@ -884,7 +884,7 @@ static int synclink_init_one (struct pci_dev *dev,
const struct pci_device_id *ent);
static void synclink_remove_one (struct pci_dev *dev);
-static struct pci_device_id synclink_pci_tbl[] = {
+static const struct pci_device_id synclink_pci_tbl[] = {
{ PCI_VENDOR_ID_MICROGATE, PCI_DEVICE_ID_MICROGATE_USC, PCI_ANY_ID, PCI_ANY_ID, },
{ PCI_VENDOR_ID_MICROGATE, 0x0210, PCI_ANY_ID, PCI_ANY_ID, },
{ 0, }, /* terminate list */
diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c
index 529c6e3..636b8ae 100644
--- a/drivers/tty/synclink_gt.c
+++ b/drivers/tty/synclink_gt.c
@@ -95,7 +95,7 @@ MODULE_LICENSE("GPL");
#define MGSL_MAGIC 0x5401
#define MAX_DEVICES 32
-static struct pci_device_id pci_table[] = {
+static const struct pci_device_id pci_table[] = {
{PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
{PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT2_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
{PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT4_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c
index 9b4fb02..4fed9e7 100644
--- a/drivers/tty/synclinkmp.c
+++ b/drivers/tty/synclinkmp.c
@@ -479,7 +479,7 @@ static char *driver_version = "$Revision: 4.38 $";
static int synclinkmp_init_one(struct pci_dev *dev,const struct pci_device_id *ent);
static void synclinkmp_remove_one(struct pci_dev *dev);
-static struct pci_device_id synclinkmp_pci_tbl[] = {
+static const struct pci_device_id synclinkmp_pci_tbl[] = {
{ PCI_VENDOR_ID_MICROGATE, PCI_DEVICE_ID_MICROGATE_SCA, PCI_ANY_ID, PCI_ANY_ID, },
{ 0, }, /* terminate list */
};
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
index 4e7a4e9..f8eba1c5 100644
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -362,6 +362,32 @@ int tty_insert_flip_string_flags(struct tty_port *port,
EXPORT_SYMBOL(tty_insert_flip_string_flags);
/**
+ * __tty_insert_flip_char - Add one character to the tty buffer
+ * @port: tty port
+ * @ch: character
+ * @flag: flag byte
+ *
+ * Queue a single byte to the tty buffering, with an optional flag.
+ * This is the slow path of tty_insert_flip_char.
+ */
+int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag)
+{
+ struct tty_buffer *tb;
+ int flags = (flag == TTY_NORMAL) ? TTYB_NORMAL : 0;
+
+ if (!__tty_buffer_request_room(port, 1, flags))
+ return 0;
+
+ tb = port->buf.tail;
+ if (~tb->flags & TTYB_NORMAL)
+ *flag_buf_ptr(tb, tb->used) = flag;
+ *char_buf_ptr(tb, tb->used++) = ch;
+
+ return 1;
+}
+EXPORT_SYMBOL(__tty_insert_flip_char);
+
+/**
* tty_schedule_flip - push characters to ldisc
* @port: tty port to push from
*
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 10c4038..94cccb6 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -280,7 +280,7 @@ static int check_tty_count(struct tty_struct *tty, const char *routine)
{
#ifdef CHECK_TTY_COUNT
struct list_head *p;
- int count = 0;
+ int count = 0, kopen_count = 0;
spin_lock(&tty->files_lock);
list_for_each(p, &tty->tty_files) {
@@ -291,10 +291,12 @@ static int check_tty_count(struct tty_struct *tty, const char *routine)
tty->driver->subtype == PTY_TYPE_SLAVE &&
tty->link && tty->link->count)
count++;
- if (tty->count != count) {
- tty_warn(tty, "%s: tty->count(%d) != #fd's(%d)\n",
- routine, tty->count, count);
- return count;
+ if (tty_port_kopened(tty->port))
+ kopen_count++;
+ if (tty->count != (count + kopen_count)) {
+ tty_warn(tty, "%s: tty->count(%d) != (#fd's(%d) + #kopen's(%d))\n",
+ routine, tty->count, count, kopen_count);
+ return (count + kopen_count);
}
#endif
return 0;
@@ -462,6 +464,14 @@ static int hung_up_tty_fasync(int fd, struct file *file, int on)
return -ENOTTY;
}
+static void tty_show_fdinfo(struct seq_file *m, struct file *file)
+{
+ struct tty_struct *tty = file_tty(file);
+
+ if (tty && tty->ops && tty->ops->show_fdinfo)
+ tty->ops->show_fdinfo(tty, m);
+}
+
static const struct file_operations tty_fops = {
.llseek = no_llseek,
.read = tty_read,
@@ -472,6 +482,7 @@ static const struct file_operations tty_fops = {
.open = tty_open,
.release = tty_release,
.fasync = tty_fasync,
+ .show_fdinfo = tty_show_fdinfo,
};
static const struct file_operations console_fops = {
@@ -1513,6 +1524,38 @@ static int tty_release_checks(struct tty_struct *tty, int idx)
}
/**
+ * tty_kclose - closes tty opened by tty_kopen
+ * @tty: tty device
+ *
+ * Performs the final steps to release and free a tty device. It is the
+ * same as tty_release_struct except that it also resets TTY_PORT_KOPENED
+ * flag on tty->port.
+ */
+void tty_kclose(struct tty_struct *tty)
+{
+ /*
+ * Ask the line discipline code to release its structures
+ */
+ tty_ldisc_release(tty);
+
+ /* Wait for pending work before tty destruction commmences */
+ tty_flush_works(tty);
+
+ tty_debug_hangup(tty, "freeing structure\n");
+ /*
+ * The release_tty function takes care of the details of clearing
+ * the slots and preserving the termios structure. The tty_unlock_pair
+ * should be safe as we keep a kref while the tty is locked (so the
+ * unlock never unlocks a freed tty).
+ */
+ mutex_lock(&tty_mutex);
+ tty_port_set_kopened(tty->port, 0);
+ release_tty(tty, tty->index);
+ mutex_unlock(&tty_mutex);
+}
+EXPORT_SYMBOL_GPL(tty_kclose);
+
+/**
* tty_release_struct - release a tty struct
* @tty: tty device
* @idx: index of the tty
@@ -1786,6 +1829,56 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp,
}
/**
+ * tty_kopen - open a tty device for kernel
+ * @device: dev_t of device to open
+ *
+ * Opens tty exclusively for kernel. Performs the driver lookup,
+ * makes sure it's not already opened and performs the first-time
+ * tty initialization.
+ *
+ * Returns the locked initialized &tty_struct
+ *
+ * Claims the global tty_mutex to serialize:
+ * - concurrent first-time tty initialization
+ * - concurrent tty driver removal w/ lookup
+ * - concurrent tty removal from driver table
+ */
+struct tty_struct *tty_kopen(dev_t device)
+{
+ struct tty_struct *tty;
+ struct tty_driver *driver = NULL;
+ int index = -1;
+
+ mutex_lock(&tty_mutex);
+ driver = tty_lookup_driver(device, NULL, &index);
+ if (IS_ERR(driver)) {
+ mutex_unlock(&tty_mutex);
+ return ERR_CAST(driver);
+ }
+
+ /* check whether we're reopening an existing tty */
+ tty = tty_driver_lookup_tty(driver, NULL, index);
+ if (IS_ERR(tty))
+ goto out;
+
+ if (tty) {
+ /* drop kref from tty_driver_lookup_tty() */
+ tty_kref_put(tty);
+ tty = ERR_PTR(-EBUSY);
+ } else { /* tty_init_dev returns tty with the tty_lock held */
+ tty = tty_init_dev(driver, index);
+ if (IS_ERR(tty))
+ goto out;
+ tty_port_set_kopened(tty->port, 1);
+ }
+out:
+ mutex_unlock(&tty_mutex);
+ tty_driver_kref_put(driver);
+ return tty;
+}
+EXPORT_SYMBOL_GPL(tty_kopen);
+
+/**
* tty_open_by_driver - open a tty device
* @device: dev_t of device to open
* @inode: inode of device file
@@ -1801,7 +1894,7 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp,
* - concurrent tty driver removal w/ lookup
* - concurrent tty removal from driver table
*/
-struct tty_struct *tty_open_by_driver(dev_t device, struct inode *inode,
+static struct tty_struct *tty_open_by_driver(dev_t device, struct inode *inode,
struct file *filp)
{
struct tty_struct *tty;
@@ -1824,6 +1917,12 @@ struct tty_struct *tty_open_by_driver(dev_t device, struct inode *inode,
}
if (tty) {
+ if (tty_port_kopened(tty->port)) {
+ tty_kref_put(tty);
+ mutex_unlock(&tty_mutex);
+ tty = ERR_PTR(-EBUSY);
+ goto out;
+ }
mutex_unlock(&tty_mutex);
retval = tty_lock_interruptible(tty);
tty_kref_put(tty); /* drop kref from tty_driver_lookup_tty() */
@@ -1846,7 +1945,6 @@ out:
tty_driver_kref_put(driver);
return tty;
}
-EXPORT_SYMBOL_GPL(tty_open_by_driver);
/**
* tty_open - open a tty device
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
index d65a64c..5160a4a 100644
--- a/drivers/usb/atm/cxacru.c
+++ b/drivers/usb/atm/cxacru.c
@@ -43,7 +43,6 @@
#include "usbatm.h"
#define DRIVER_AUTHOR "Roman Kagan, David Woodhouse, Duncan Sands, Simon Arlott"
-#define DRIVER_VERSION "0.4"
#define DRIVER_DESC "Conexant AccessRunner ADSL USB modem driver"
static const char cxacru_driver_name[] = "cxacru";
@@ -1380,4 +1379,3 @@ module_usb_driver(cxacru_usb_driver);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
-MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c
index 5083eb5..3676adb 100644
--- a/drivers/usb/atm/speedtch.c
+++ b/drivers/usb/atm/speedtch.c
@@ -40,8 +40,7 @@
#include "usbatm.h"
#define DRIVER_AUTHOR "Johan Verrept, Duncan Sands <duncan.sands@free.fr>"
-#define DRIVER_VERSION "1.10"
-#define DRIVER_DESC "Alcatel SpeedTouch USB driver version " DRIVER_VERSION
+#define DRIVER_DESC "Alcatel SpeedTouch USB driver"
static const char speedtch_driver_name[] = "speedtch";
@@ -738,7 +737,7 @@ static int speedtch_post_reset(struct usb_interface *intf)
** USB **
**********/
-static struct usb_device_id speedtch_usb_ids[] = {
+static const struct usb_device_id speedtch_usb_ids[] = {
{USB_DEVICE(0x06b9, 0x4061)},
{}
};
@@ -962,4 +961,3 @@ module_usb_driver(speedtch_usb_driver);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
-MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
index df67815..ba76163 100644
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -2212,7 +2212,7 @@ static int uea_boot(struct uea_softc *sc)
ret = usb_submit_urb(sc->urb_int, GFP_KERNEL);
if (ret < 0) {
uea_err(INS_TO_USBDEV(sc),
- "urb submition failed with error %d\n", ret);
+ "urb submission failed with error %d\n", ret);
goto err1;
}
@@ -2522,7 +2522,7 @@ static struct attribute *attrs[] = {
&dev_attr_stat_firmid.attr,
NULL,
};
-static struct attribute_group attr_grp = {
+static const struct attribute_group attr_grp = {
.attrs = attrs,
};
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c
index 3e80aa3b..8607af7 100644
--- a/drivers/usb/atm/usbatm.c
+++ b/drivers/usb/atm/usbatm.c
@@ -93,8 +93,7 @@ static int usbatm_print_packet(struct usbatm_data *instance, const unsigned char
#endif
#define DRIVER_AUTHOR "Johan Verrept, Duncan Sands <duncan.sands@free.fr>"
-#define DRIVER_VERSION "1.10"
-#define DRIVER_DESC "Generic USB ATM/DSL I/O, version " DRIVER_VERSION
+#define DRIVER_DESC "Generic USB ATM/DSL I/O"
static const char usbatm_driver_name[] = "usbatm";
@@ -174,7 +173,7 @@ static int usbatm_atm_ioctl(struct atm_dev *atm_dev, unsigned int cmd, void __us
static int usbatm_atm_send(struct atm_vcc *vcc, struct sk_buff *skb);
static int usbatm_atm_proc_read(struct atm_dev *atm_dev, loff_t *pos, char *page);
-static struct atmdev_ops usbatm_atm_devops = {
+static const struct atmdev_ops usbatm_atm_devops = {
.dev_close = usbatm_atm_dev_close,
.open = usbatm_atm_open,
.close = usbatm_atm_close,
@@ -1315,7 +1314,6 @@ module_exit(usbatm_usb_exit);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
-MODULE_VERSION(DRIVER_VERSION);
/************
** debug **
diff --git a/drivers/usb/atm/xusbatm.c b/drivers/usb/atm/xusbatm.c
index a87597f..c73c1ec 100644
--- a/drivers/usb/atm/xusbatm.c
+++ b/drivers/usb/atm/xusbatm.c
@@ -228,4 +228,3 @@ module_exit(xusbatm_exit);
MODULE_AUTHOR("Roman Kagan, Duncan Sands");
MODULE_DESCRIPTION("Driver for USB ADSL modems initialized in userspace");
MODULE_LICENSE("GPL");
-MODULE_VERSION("0.1");
diff --git a/drivers/usb/c67x00/c67x00-hcd.c b/drivers/usb/c67x00/c67x00-hcd.c
index c2d1396..30d3f34 100644
--- a/drivers/usb/c67x00/c67x00-hcd.c
+++ b/drivers/usb/c67x00/c67x00-hcd.c
@@ -305,7 +305,7 @@ static int c67x00_hcd_get_frame(struct usb_hcd *hcd)
return temp_val ? (temp_val - 1) : HOST_FRAME_MASK;
}
-static struct hc_driver c67x00_hc_driver = {
+static const struct hc_driver c67x00_hc_driver = {
.description = "c67x00-hcd",
.product_desc = "Cypress C67X00 Host Controller",
.hcd_priv_size = sizeof(struct c67x00_hcd),
diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile
index 39fca57..ddcbddf 100644
--- a/drivers/usb/chipidea/Makefile
+++ b/drivers/usb/chipidea/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_USB_CHIPIDEA) += ci_hdrc_zevio.o
obj-$(CONFIG_USB_CHIPIDEA_PCI) += ci_hdrc_pci.o
obj-$(CONFIG_USB_CHIPIDEA_OF) += usbmisc_imx.o ci_hdrc_imx.o
+obj-$(CONFIG_USB_CHIPIDEA_OF) += ci_hdrc_tegra.o
diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index 0bdfcdc..bb62612 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -251,7 +251,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
if (ret)
goto err_mux;
- ulpi_node = of_find_node_by_name(pdev->dev.of_node, "ulpi");
+ ulpi_node = of_find_node_by_name(of_node_get(pdev->dev.of_node), "ulpi");
if (ulpi_node) {
phy_node = of_get_next_available_child(ulpi_node, NULL);
ci->hsic = of_device_is_compatible(phy_node, "qcom,usb-hsic-phy");
diff --git a/drivers/usb/chipidea/ci_hdrc_pci.c b/drivers/usb/chipidea/ci_hdrc_pci.c
index b635ab6..39414e4 100644
--- a/drivers/usb/chipidea/ci_hdrc_pci.c
+++ b/drivers/usb/chipidea/ci_hdrc_pci.c
@@ -170,5 +170,4 @@ module_pci_driver(ci_hdrc_pci_driver);
MODULE_AUTHOR("MIPS - David Lopo <dlopo@chipidea.mips.com>");
MODULE_DESCRIPTION("MIPS CI13XXX USB Peripheral Controller");
MODULE_LICENSE("GPL");
-MODULE_VERSION("June 2008");
MODULE_ALIAS("platform:ci13xxx_pci");
diff --git a/drivers/usb/chipidea/ci_hdrc_tegra.c b/drivers/usb/chipidea/ci_hdrc_tegra.c
new file mode 100644
index 0000000..bfcee27
--- /dev/null
+++ b/drivers/usb/chipidea/ci_hdrc_tegra.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2016, NVIDIA Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/reset.h>
+
+#include <linux/usb/chipidea.h>
+
+#include "ci.h"
+
+struct tegra_udc {
+ struct ci_hdrc_platform_data data;
+ struct platform_device *dev;
+
+ struct usb_phy *phy;
+ struct clk *clk;
+};
+
+struct tegra_udc_soc_info {
+ unsigned long flags;
+};
+
+static const struct tegra_udc_soc_info tegra20_udc_soc_info = {
+ .flags = CI_HDRC_REQUIRES_ALIGNED_DMA,
+};
+
+static const struct tegra_udc_soc_info tegra30_udc_soc_info = {
+ .flags = 0,
+};
+
+static const struct tegra_udc_soc_info tegra114_udc_soc_info = {
+ .flags = 0,
+};
+
+static const struct tegra_udc_soc_info tegra124_udc_soc_info = {
+ .flags = 0,
+};
+
+static const struct of_device_id tegra_udc_of_match[] = {
+ {
+ .compatible = "nvidia,tegra20-udc",
+ .data = &tegra20_udc_soc_info,
+ }, {
+ .compatible = "nvidia,tegra30-udc",
+ .data = &tegra30_udc_soc_info,
+ }, {
+ .compatible = "nvidia,tegra114-udc",
+ .data = &tegra114_udc_soc_info,
+ }, {
+ .compatible = "nvidia,tegra124-udc",
+ .data = &tegra124_udc_soc_info,
+ }, {
+ /* sentinel */
+ }
+};
+MODULE_DEVICE_TABLE(of, tegra_udc_of_match);
+
+static int tegra_udc_probe(struct platform_device *pdev)
+{
+ const struct tegra_udc_soc_info *soc;
+ struct tegra_udc *udc;
+ int err;
+
+ udc = devm_kzalloc(&pdev->dev, sizeof(*udc), GFP_KERNEL);
+ if (!udc)
+ return -ENOMEM;
+
+ soc = of_device_get_match_data(&pdev->dev);
+ if (!soc) {
+ dev_err(&pdev->dev, "failed to match OF data\n");
+ return -EINVAL;
+ }
+
+ udc->phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0);
+ if (IS_ERR(udc->phy)) {
+ err = PTR_ERR(udc->phy);
+ dev_err(&pdev->dev, "failed to get PHY: %d\n", err);
+ return err;
+ }
+
+ udc->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(udc->clk)) {
+ err = PTR_ERR(udc->clk);
+ dev_err(&pdev->dev, "failed to get clock: %d\n", err);
+ return err;
+ }
+
+ err = clk_prepare_enable(udc->clk);
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to enable clock: %d\n", err);
+ return err;
+ }
+
+ /*
+ * Tegra's USB PHY driver doesn't implement optional phy_init()
+ * hook, so we have to power on UDC controller before ChipIdea
+ * driver initialization kicks in.
+ */
+ usb_phy_set_suspend(udc->phy, 0);
+
+ /* setup and register ChipIdea HDRC device */
+ udc->data.name = "tegra-udc";
+ udc->data.flags = soc->flags;
+ udc->data.usb_phy = udc->phy;
+ udc->data.capoffset = DEF_CAPOFFSET;
+
+ udc->dev = ci_hdrc_add_device(&pdev->dev, pdev->resource,
+ pdev->num_resources, &udc->data);
+ if (IS_ERR(udc->dev)) {
+ err = PTR_ERR(udc->dev);
+ dev_err(&pdev->dev, "failed to add HDRC device: %d\n", err);
+ goto fail_power_off;
+ }
+
+ platform_set_drvdata(pdev, udc);
+
+ return 0;
+
+fail_power_off:
+ usb_phy_set_suspend(udc->phy, 1);
+ clk_disable_unprepare(udc->clk);
+ return err;
+}
+
+static int tegra_udc_remove(struct platform_device *pdev)
+{
+ struct tegra_udc *udc = platform_get_drvdata(pdev);
+
+ usb_phy_set_suspend(udc->phy, 1);
+ clk_disable_unprepare(udc->clk);
+
+ return 0;
+}
+
+static struct platform_driver tegra_udc_driver = {
+ .driver = {
+ .name = "tegra-udc",
+ .of_match_table = tegra_udc_of_match,
+ },
+ .probe = tegra_udc_probe,
+ .remove = tegra_udc_remove,
+};
+module_platform_driver(tegra_udc_driver);
+
+MODULE_DESCRIPTION("NVIDIA Tegra USB device mode driver");
+MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
+MODULE_ALIAS("platform:tegra-udc");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/chipidea/ci_hdrc_usb2.c b/drivers/usb/chipidea/ci_hdrc_usb2.c
index d162cc0..99425db 100644
--- a/drivers/usb/chipidea/ci_hdrc_usb2.c
+++ b/drivers/usb/chipidea/ci_hdrc_usb2.c
@@ -52,6 +52,8 @@ static int ci_hdrc_usb2_probe(struct platform_device *pdev)
if (!ci_pdata) {
ci_pdata = devm_kmalloc(dev, sizeof(*ci_pdata), GFP_KERNEL);
+ if (!ci_pdata)
+ return -ENOMEM;
*ci_pdata = ci_default_pdata; /* struct copy */
}
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index b17ed3a..43ea5fb 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -736,7 +736,7 @@ static int ci_extcon_register(struct ci_hdrc *ci)
id = &ci->platdata->id_extcon;
id->ci = ci;
- if (!IS_ERR(id->edev)) {
+ if (!IS_ERR_OR_NULL(id->edev)) {
ret = devm_extcon_register_notifier(ci->dev, id->edev,
EXTCON_USB_HOST, &id->nb);
if (ret < 0) {
@@ -747,7 +747,7 @@ static int ci_extcon_register(struct ci_hdrc *ci)
vbus = &ci->platdata->vbus_extcon;
vbus->ci = ci;
- if (!IS_ERR(vbus->edev)) {
+ if (!IS_ERR_OR_NULL(vbus->edev)) {
ret = devm_extcon_register_notifier(ci->dev, vbus->edev,
EXTCON_USB, &vbus->nb);
if (ret < 0) {
@@ -887,7 +887,7 @@ static struct attribute *ci_attrs[] = {
NULL,
};
-static struct attribute_group ci_attr_group = {
+static const struct attribute_group ci_attr_group = {
.attrs = ci_attrs,
};
diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c
index 949183e..5ea0246 100644
--- a/drivers/usb/chipidea/otg_fsm.c
+++ b/drivers/usb/chipidea/otg_fsm.c
@@ -193,7 +193,7 @@ static struct attribute *inputs_attrs[] = {
NULL,
};
-static struct attribute_group inputs_attr_group = {
+static const struct attribute_group inputs_attr_group = {
.name = "inputs",
.attrs = inputs_attrs,
};
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index d68b125..fe8a905 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -944,7 +944,6 @@ isr_setup_status_complete(struct usb_ep *ep, struct usb_request *req)
*/
static int isr_setup_status_phase(struct ci_hdrc *ci)
{
- int retval;
struct ci_hw_ep *hwep;
/*
@@ -960,9 +959,7 @@ static int isr_setup_status_phase(struct ci_hdrc *ci)
ci->status->context = ci;
ci->status->complete = isr_setup_status_complete;
- retval = _ep_queue(&hwep->ep, ci->status, GFP_ATOMIC);
-
- return retval;
+ return _ep_queue(&hwep->ep, ci->status, GFP_ATOMIC);
}
/**
@@ -1899,6 +1896,9 @@ static int udc_start(struct ci_hdrc *ci)
ci->gadget.name = ci->platdata->name;
ci->gadget.otg_caps = otg_caps;
+ if (ci->platdata->flags & CI_HDRC_REQUIRES_ALIGNED_DMA)
+ ci->gadget.quirk_avoids_skb_reserve = 1;
+
if (ci->is_otg && (otg_caps->hnp_support || otg_caps->srp_support ||
otg_caps->adp_support))
ci->gadget.is_otg = 1;
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 8f97224..5aacea1 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -26,10 +26,6 @@
#include <asm/unaligned.h>
#include <linux/usb/cdc-wdm.h>
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v0.03"
#define DRIVER_AUTHOR "Oliver Neukum"
#define DRIVER_DESC "USB Abstract Control Model driver for USB WCM Device Management"
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c
index 578f424..6ebfabf 100644
--- a/drivers/usb/class/usbtmc.c
+++ b/drivers/usb/class/usbtmc.c
@@ -1085,7 +1085,7 @@ static struct attribute *capability_attrs[] = {
NULL,
};
-static struct attribute_group capability_attr_grp = {
+static const struct attribute_group capability_attr_grp = {
.attrs = capability_attrs,
};
@@ -1151,7 +1151,7 @@ static struct attribute *data_attrs[] = {
NULL,
};
-static struct attribute_group data_attr_grp = {
+static const struct attribute_group data_attr_grp = {
.attrs = data_attrs,
};
diff --git a/drivers/usb/common/common.c b/drivers/usb/common/common.c
index 5ef8da6..552ff7a 100644
--- a/drivers/usb/common/common.c
+++ b/drivers/usb/common/common.c
@@ -190,10 +190,7 @@ EXPORT_SYMBOL_GPL(of_usb_get_dr_mode_by_phy);
*/
bool of_usb_host_tpl_support(struct device_node *np)
{
- if (of_find_property(np, "tpl-support", NULL))
- return true;
-
- return false;
+ return of_property_read_bool(np, "tpl-support");
}
EXPORT_SYMBOL_GPL(of_usb_host_tpl_support);
@@ -227,8 +224,8 @@ int of_usb_update_otg_caps(struct device_node *np,
otg_caps->otg_rev = otg_rev;
break;
default:
- pr_err("%s: unsupported otg-rev: 0x%x\n",
- np->full_name, otg_rev);
+ pr_err("%pOF: unsupported otg-rev: 0x%x\n",
+ np, otg_rev);
return -EINVAL;
}
} else {
@@ -240,11 +237,11 @@ int of_usb_update_otg_caps(struct device_node *np,
otg_caps->otg_rev = 0;
}
- if (of_find_property(np, "hnp-disable", NULL))
+ if (of_property_read_bool(np, "hnp-disable"))
otg_caps->hnp_support = false;
- if (of_find_property(np, "srp-disable", NULL))
+ if (of_property_read_bool(np, "srp-disable"))
otg_caps->srp_support = false;
- if (of_find_property(np, "adp-disable", NULL) ||
+ if (of_property_read_bool(np, "adp-disable") ||
(otg_caps->otg_rev < 0x0200))
otg_caps->adp_support = false;
diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
index 930e8f3..4aa5195 100644
--- a/drivers/usb/common/ulpi.c
+++ b/drivers/usb/common/ulpi.c
@@ -135,7 +135,7 @@ static void ulpi_dev_release(struct device *dev)
kfree(to_ulpi_dev(dev));
}
-static struct device_type ulpi_dev_type = {
+static const struct device_type ulpi_dev_type = {
.name = "ulpi_device",
.groups = ulpi_dev_attr_groups,
.release = ulpi_dev_release,
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index ebe2759..318bb3b 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -210,7 +210,7 @@ static void usbdev_vm_close(struct vm_area_struct *vma)
dec_usb_memory_use_count(usbm, &usbm->vma_use_count);
}
-static struct vm_operations_struct usbdev_vm_ops = {
+static const struct vm_operations_struct usbdev_vm_ops = {
.open = usbdev_vm_open,
.close = usbdev_vm_close
};
@@ -623,6 +623,8 @@ static void async_completed(struct urb *urb)
if (as->status < 0 && as->bulk_addr && as->status != -ECONNRESET &&
as->status != -ENOENT)
cancel_bulk_urbs(ps, as->bulk_addr);
+
+ wake_up(&ps->wait);
spin_unlock(&ps->lock);
if (signr) {
@@ -630,8 +632,6 @@ static void async_completed(struct urb *urb)
put_pid(pid);
put_cred(cred);
}
-
- wake_up(&ps->wait);
}
static void destroy_async(struct usb_dev_state *ps, struct list_head *list)
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 7f277b0..75ad671 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -972,7 +972,7 @@ static struct attribute *usb_bus_attrs[] = {
NULL,
};
-static struct attribute_group usb_bus_attr_group = {
+static const struct attribute_group usb_bus_attr_group = {
.name = NULL, /* we want them in the same directory */
.attrs = usb_bus_attrs,
};
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 822f8c5..41eaf0b 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2614,7 +2614,7 @@ static unsigned hub_is_wusb(struct usb_hub *hub)
#define SET_CONFIG_TRIES (2 * (use_both_schemes + 1))
#define USE_NEW_SCHEME(i) ((i) / 2 == (int)old_scheme_first)
-#define HUB_ROOT_RESET_TIME 50 /* times are in msec */
+#define HUB_ROOT_RESET_TIME 60 /* times are in msec */
#define HUB_SHORT_RESET_TIME 10
#define HUB_BH_RESET_TIME 50
#define HUB_LONG_RESET_TIME 200
@@ -4342,6 +4342,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
enum usb_device_speed oldspeed = udev->speed;
const char *speed;
int devnum = udev->devnum;
+ const char *driver_name;
/* root hub ports have a slightly longer reset period
* (from USB 2.0 spec, section 7.1.7.5)
@@ -4409,11 +4410,23 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
else
speed = usb_speed_string(udev->speed);
+ /*
+ * The controller driver may be NULL if the controller device
+ * is the middle device between platform device and roothub.
+ * This middle device may not need a device driver due to
+ * all hardware control can be at platform device driver, this
+ * platform device is usually a dual-role USB controller device.
+ */
+ if (udev->bus->controller->driver)
+ driver_name = udev->bus->controller->driver->name;
+ else
+ driver_name = udev->bus->sysdev->driver->name;
+
if (udev->speed < USB_SPEED_SUPER)
dev_info(&udev->dev,
"%s %s USB device number %d using %s\n",
(udev->config) ? "reset" : "new", speed,
- devnum, udev->bus->controller->driver->name);
+ devnum, driver_name);
/* Set up TT records, if needed */
if (hdev->tt) {
@@ -4545,7 +4558,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
"%s SuperSpeed%s USB device number %d using %s\n",
(udev->config) ? "reset" : "new",
(udev->speed == USB_SPEED_SUPER_PLUS) ? "Plus" : "",
- devnum, udev->bus->controller->driver->name);
+ devnum, driver_name);
}
/* cope with hardware quirkiness:
diff --git a/drivers/usb/core/ledtrig-usbport.c b/drivers/usb/core/ledtrig-usbport.c
index 16c19a3..1af8779 100644
--- a/drivers/usb/core/ledtrig-usbport.c
+++ b/drivers/usb/core/ledtrig-usbport.c
@@ -149,8 +149,8 @@ static bool usbport_trig_port_observed(struct usbport_trig_data *usbport_data,
count = of_count_phandle_with_args(led_np, "trigger-sources",
"#trigger-source-cells");
if (count < 0) {
- dev_warn(dev, "Failed to get trigger sources for %s\n",
- led_np->full_name);
+ dev_warn(dev, "Failed to get trigger sources for %pOF\n",
+ led_np);
return false;
}
@@ -205,6 +205,7 @@ static int usbport_trig_add_port(struct usbport_trig_data *usbport_data,
}
snprintf(port->port_name, len, "%s-port%d", hub_name, portnum);
+ sysfs_attr_init(&port->attr.attr);
port->attr.attr.name = port->port_name;
port->attr.attr.mode = S_IRUSR | S_IWUSR;
port->attr.show = usbport_trig_port_show;
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 574da2b..82806e3 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -57,8 +57,9 @@ static const struct usb_device_id usb_quirk_list[] = {
/* Microsoft LifeCam-VX700 v2.0 */
{ USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME },
- /* Logitech HD Pro Webcams C920 and C930e */
+ /* Logitech HD Pro Webcams C920, C920-C and C930e */
{ USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT },
+ { USB_DEVICE(0x046d, 0x0841), .driver_info = USB_QUIRK_DELAY_INIT },
{ USB_DEVICE(0x046d, 0x0843), .driver_info = USB_QUIRK_DELAY_INIT },
/* Logitech ConferenceCam CC3000e */
@@ -217,6 +218,9 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x1a0a, 0x0200), .driver_info =
USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
+ /* Corsair Strafe RGB */
+ { USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT },
+
/* Acer C120 LED Projector */
{ USB_DEVICE(0x1de1, 0xc102), .driver_info = USB_QUIRK_NO_LPM },
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index dfc68ed..d930bfd 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -113,7 +113,7 @@ static ssize_t devspec_show(struct device *dev, struct device_attribute *attr,
{
struct device_node *of_node = dev->of_node;
- return sprintf(buf, "%s\n", of_node_full_name(of_node));
+ return sprintf(buf, "%pOF\n", of_node);
}
static DEVICE_ATTR_RO(devspec);
#endif
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
index c4066cd..0d8e09c 100644
--- a/drivers/usb/dwc2/gadget.c
+++ b/drivers/usb/dwc2/gadget.c
@@ -4179,7 +4179,7 @@ static int dwc2_hsotg_ep_sethalt_lock(struct usb_ep *ep, int value)
return ret;
}
-static struct usb_ep_ops dwc2_hsotg_ep_ops = {
+static const struct usb_ep_ops dwc2_hsotg_ep_ops = {
.enable = dwc2_hsotg_ep_enable,
.disable = dwc2_hsotg_ep_disable,
.alloc_request = dwc2_hsotg_ep_alloc_request,
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 740c7e8..c263114 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4388,6 +4388,9 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
spin_lock_irqsave(&hsotg->lock, flags);
+ if (dwc2_is_device_mode(hsotg))
+ goto unlock;
+
if (hsotg->lx_state != DWC2_L0)
goto unlock;
@@ -4446,6 +4449,9 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd)
spin_lock_irqsave(&hsotg->lock, flags);
+ if (dwc2_is_device_mode(hsotg))
+ goto unlock;
+
if (hsotg->lx_state != DWC2_L2)
goto unlock;
diff --git a/drivers/usb/dwc3/dwc3-keystone.c b/drivers/usb/dwc3/dwc3-keystone.c
index 12ee23f..d2ed952 100644
--- a/drivers/usb/dwc3/dwc3-keystone.c
+++ b/drivers/usb/dwc3/dwc3-keystone.c
@@ -15,7 +15,6 @@
* GNU General Public License for more details.
*/
-#include <linux/clk.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
@@ -23,6 +22,7 @@
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/of_platform.h>
+#include <linux/pm_runtime.h>
/* USBSS register offsets */
#define USBSS_REVISION 0x0000
@@ -41,7 +41,6 @@
struct dwc3_keystone {
struct device *dev;
- struct clk *clk;
void __iomem *usbss;
};
@@ -106,17 +105,13 @@ static int kdwc3_probe(struct platform_device *pdev)
if (IS_ERR(kdwc->usbss))
return PTR_ERR(kdwc->usbss);
- kdwc->clk = devm_clk_get(kdwc->dev, "usb");
- if (IS_ERR(kdwc->clk)) {
- dev_err(kdwc->dev, "unable to get usb clock\n");
- return PTR_ERR(kdwc->clk);
- }
+ pm_runtime_enable(kdwc->dev);
- error = clk_prepare_enable(kdwc->clk);
+ error = pm_runtime_get_sync(kdwc->dev);
if (error < 0) {
- dev_err(kdwc->dev, "unable to enable usb clock, error %d\n",
+ dev_err(kdwc->dev, "pm_runtime_get_sync failed, error %d\n",
error);
- return error;
+ goto err_irq;
}
irq = platform_get_irq(pdev, 0);
@@ -147,7 +142,8 @@ static int kdwc3_probe(struct platform_device *pdev)
err_core:
kdwc3_disable_irqs(kdwc);
err_irq:
- clk_disable_unprepare(kdwc->clk);
+ pm_runtime_put_sync(kdwc->dev);
+ pm_runtime_disable(kdwc->dev);
return error;
}
@@ -167,7 +163,9 @@ static int kdwc3_remove(struct platform_device *pdev)
kdwc3_disable_irqs(kdwc);
device_for_each_child(&pdev->dev, NULL, kdwc3_remove_core);
- clk_disable_unprepare(kdwc->clk);
+ pm_runtime_put_sync(kdwc->dev);
+ pm_runtime_disable(kdwc->dev);
+
platform_set_drvdata(pdev, NULL);
return 0;
diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c
index fe414e7..4cef7d4 100644
--- a/drivers/usb/dwc3/dwc3-of-simple.c
+++ b/drivers/usb/dwc3/dwc3-of-simple.c
@@ -25,7 +25,6 @@
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/clk.h>
-#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/pm_runtime.h>
@@ -96,7 +95,8 @@ static int dwc3_of_simple_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, simple);
simple->dev = dev;
- ret = dwc3_of_simple_clk_init(simple, of_clk_get_parent_count(np));
+ ret = dwc3_of_simple_clk_init(simple, of_count_phandle_with_args(np,
+ "clocks", "#clock-cells"));
if (ret)
return ret;
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index f5aaa0c..3530795 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -478,8 +478,8 @@ static int dwc3_omap_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
- dev_err(dev, "missing IRQ resource\n");
- return -EINVAL;
+ dev_err(dev, "missing IRQ resource: %d\n", irq);
+ return irq;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index 7e995df..54343fb 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -345,7 +345,7 @@ static int dwc3_pci_resume(struct device *dev)
}
#endif /* CONFIG_PM_SLEEP */
-static struct dev_pm_ops dwc3_pci_dev_pm_ops = {
+static const struct dev_pm_ops dwc3_pci_dev_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(dwc3_pci_suspend, dwc3_pci_resume)
SET_RUNTIME_PM_OPS(dwc3_pci_runtime_suspend, dwc3_pci_runtime_resume,
NULL)
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 35cc641..31cce78 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -130,7 +130,7 @@ config USB_GADGET_STORAGE_NUM_BUFFERS
config U_SERIAL_CONSOLE
bool "Serial gadget console support"
- depends on USB_G_SERIAL
+ depends on USB_U_SERIAL
help
It supports the serial gadget can be used as a console.
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index d21874b..9990944 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -961,10 +961,9 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
/* In the meantime, endpoint got disabled or changed. */
ret = -ESHUTDOWN;
} else if (halt) {
- /* Halt */
- if (likely(epfile->ep == ep) && !WARN_ON(!ep->ep))
- usb_ep_set_halt(ep->ep);
- ret = -EBADMSG;
+ ret = usb_ep_set_halt(ep->ep);
+ if (!ret)
+ ret = -EBADMSG;
} else if (unlikely(data_len == -EINVAL)) {
/*
* Sanity Check: even though data_len can't be used
diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c
index 5eea448..d8e359e 100644
--- a/drivers/usb/gadget/function/f_hid.c
+++ b/drivers/usb/gadget/function/f_hid.c
@@ -44,6 +44,7 @@ struct f_hidg {
/* configuration */
unsigned char bInterfaceSubClass;
unsigned char bInterfaceProtocol;
+ unsigned char protocol;
unsigned short report_desc_length;
char *report_desc;
unsigned short report_length;
@@ -527,7 +528,9 @@ static int hidg_setup(struct usb_function *f,
case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
| HID_REQ_GET_PROTOCOL):
VDBG(cdev, "get_protocol\n");
- goto stall;
+ length = min_t(unsigned int, length, 1);
+ ((u8 *) req->buf)[0] = hidg->protocol;
+ goto respond;
break;
case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
@@ -539,6 +542,17 @@ static int hidg_setup(struct usb_function *f,
case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
| HID_REQ_SET_PROTOCOL):
VDBG(cdev, "set_protocol\n");
+ if (value > HID_REPORT_PROTOCOL)
+ goto stall;
+ length = 0;
+ /*
+ * We assume that programs implementing the Boot protocol
+ * are also compatible with the Report Protocol
+ */
+ if (hidg->bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT) {
+ hidg->protocol = value;
+ goto respond;
+ }
goto stall;
break;
@@ -768,6 +782,7 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
/* set descriptor dynamic values */
hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass;
hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol;
+ hidg->protocol = HID_REPORT_PROTOCOL;
hidg_ss_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
hidg_ss_in_comp_desc.wBytesPerInterval =
cpu_to_le16(hidg->report_length);
diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c
index a5719f2..5d3d794 100644
--- a/drivers/usb/gadget/function/f_midi.c
+++ b/drivers/usb/gadget/function/f_midi.c
@@ -98,6 +98,7 @@ struct f_midi {
DECLARE_KFIFO_PTR(in_req_fifo, struct usb_request *);
spinlock_t transmit_lock;
unsigned int in_last_port;
+ unsigned char free_ref;
struct gmidi_in_port in_ports_array[/* in_ports */];
};
@@ -108,6 +109,7 @@ static inline struct f_midi *func_to_midi(struct usb_function *f)
}
static void f_midi_transmit(struct f_midi *midi);
+static void f_midi_rmidi_free(struct snd_rawmidi *rmidi);
DECLARE_UAC_AC_HEADER_DESCRIPTOR(1);
DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1);
@@ -163,6 +165,13 @@ static struct usb_endpoint_descriptor bulk_out_desc = {
.bmAttributes = USB_ENDPOINT_XFER_BULK,
};
+static struct usb_ss_ep_comp_descriptor bulk_out_ss_comp_desc = {
+ .bLength = sizeof(bulk_out_ss_comp_desc),
+ .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
+ /* .bMaxBurst = 0, */
+ /* .bmAttributes = 0, */
+};
+
/* B.5.2 Class-specific MS Bulk OUT Endpoint Descriptor */
static struct usb_ms_endpoint_descriptor_16 ms_out_desc = {
/* .bLength = DYNAMIC */
@@ -180,6 +189,13 @@ static struct usb_endpoint_descriptor bulk_in_desc = {
.bmAttributes = USB_ENDPOINT_XFER_BULK,
};
+static struct usb_ss_ep_comp_descriptor bulk_in_ss_comp_desc = {
+ .bLength = sizeof(bulk_in_ss_comp_desc),
+ .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
+ /* .bMaxBurst = 0, */
+ /* .bmAttributes = 0, */
+};
+
/* B.6.2 Class-specific MS Bulk IN Endpoint Descriptor */
static struct usb_ms_endpoint_descriptor_16 ms_in_desc = {
/* .bLength = DYNAMIC */
@@ -755,13 +771,13 @@ static void f_midi_out_trigger(struct snd_rawmidi_substream *substream, int up)
clear_bit(substream->number, &midi->out_triggered);
}
-static struct snd_rawmidi_ops gmidi_in_ops = {
+static const struct snd_rawmidi_ops gmidi_in_ops = {
.open = f_midi_in_open,
.close = f_midi_in_close,
.trigger = f_midi_in_trigger,
};
-static struct snd_rawmidi_ops gmidi_out_ops = {
+static const struct snd_rawmidi_ops gmidi_out_ops = {
.open = f_midi_out_open,
.close = f_midi_out_close,
.trigger = f_midi_out_trigger
@@ -818,6 +834,8 @@ static int f_midi_register_card(struct f_midi *midi)
SNDRV_RAWMIDI_INFO_INPUT |
SNDRV_RAWMIDI_INFO_DUPLEX;
rmidi->private_data = midi;
+ rmidi->private_free = f_midi_rmidi_free;
+ midi->free_ref++;
/*
* Yes, rawmidi OUTPUT = USB IN, and rawmidi INPUT = USB OUT.
@@ -853,7 +871,7 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
struct usb_composite_dev *cdev = c->cdev;
struct f_midi *midi = func_to_midi(f);
struct usb_string *us;
- int status, n, jack = 1, i = 0;
+ int status, n, jack = 1, i = 0, endpoint_descriptor_index = 0;
midi->gadget = cdev->gadget;
tasklet_init(&midi->tasklet, f_midi_in_tasklet, (unsigned long) midi);
@@ -895,7 +913,7 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
goto fail;
/* allocate temporary function list */
- midi_function = kcalloc((MAX_PORTS * 4) + 9, sizeof(*midi_function),
+ midi_function = kcalloc((MAX_PORTS * 4) + 11, sizeof(*midi_function),
GFP_KERNEL);
if (!midi_function) {
status = -ENOMEM;
@@ -985,6 +1003,7 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
ms_in_desc.bNumEmbMIDIJack = midi->out_ports;
/* ... and add them to the list */
+ endpoint_descriptor_index = i;
midi_function[i++] = (struct usb_descriptor_header *) &bulk_out_desc;
midi_function[i++] = (struct usb_descriptor_header *) &ms_out_desc;
midi_function[i++] = (struct usb_descriptor_header *) &bulk_in_desc;
@@ -1009,13 +1028,34 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
goto fail_f_midi;
}
+ if (gadget_is_superspeed(c->cdev->gadget)) {
+ bulk_in_desc.wMaxPacketSize = cpu_to_le16(1024);
+ bulk_out_desc.wMaxPacketSize = cpu_to_le16(1024);
+ i = endpoint_descriptor_index;
+ midi_function[i++] = (struct usb_descriptor_header *)
+ &bulk_out_desc;
+ midi_function[i++] = (struct usb_descriptor_header *)
+ &bulk_out_ss_comp_desc;
+ midi_function[i++] = (struct usb_descriptor_header *)
+ &ms_out_desc;
+ midi_function[i++] = (struct usb_descriptor_header *)
+ &bulk_in_desc;
+ midi_function[i++] = (struct usb_descriptor_header *)
+ &bulk_in_ss_comp_desc;
+ midi_function[i++] = (struct usb_descriptor_header *)
+ &ms_in_desc;
+ f->ss_descriptors = usb_copy_descriptors(midi_function);
+ if (!f->ss_descriptors)
+ goto fail_f_midi;
+ }
+
kfree(midi_function);
return 0;
fail_f_midi:
kfree(midi_function);
- usb_free_descriptors(f->hs_descriptors);
+ usb_free_all_descriptors(f);
fail:
f_midi_unregister_card(midi);
fail_register:
@@ -1197,14 +1237,21 @@ static void f_midi_free(struct usb_function *f)
midi = func_to_midi(f);
opts = container_of(f->fi, struct f_midi_opts, func_inst);
- kfree(midi->id);
mutex_lock(&opts->lock);
- kfifo_free(&midi->in_req_fifo);
- kfree(midi);
- --opts->refcnt;
+ if (!--midi->free_ref) {
+ kfree(midi->id);
+ kfifo_free(&midi->in_req_fifo);
+ kfree(midi);
+ --opts->refcnt;
+ }
mutex_unlock(&opts->lock);
}
+static void f_midi_rmidi_free(struct snd_rawmidi *rmidi)
+{
+ f_midi_free(rmidi->private_data);
+}
+
static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f)
{
struct usb_composite_dev *cdev = f->config->cdev;
@@ -1219,7 +1266,7 @@ static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f)
card = midi->card;
midi->card = NULL;
if (card)
- snd_card_free(card);
+ snd_card_free_when_closed(card);
usb_free_all_descriptors(f);
}
@@ -1263,6 +1310,7 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi)
midi->buflen = opts->buflen;
midi->qlen = opts->qlen;
midi->in_last_port = 0;
+ midi->free_ref = 1;
status = kfifo_alloc(&midi->in_req_fifo, midi->qlen, GFP_KERNEL);
if (status)
diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c
index 24e34cf..45b334c 100644
--- a/drivers/usb/gadget/function/f_ncm.c
+++ b/drivers/usb/gadget/function/f_ncm.c
@@ -925,8 +925,6 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
*/
ncm->port.is_zlp_ok =
gadget_is_zlp_supported(cdev->gadget);
- ncm->port.no_skb_reserve =
- gadget_avoids_skb_reserve(cdev->gadget);
ncm->port.cdc_filter = DEFAULT_FILTER;
DBG(cdev, "activate ncm\n");
net = gether_connect(&ncm->port);
diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c
index 16562e4..e1d5853 100644
--- a/drivers/usb/gadget/function/f_rndis.c
+++ b/drivers/usb/gadget/function/f_rndis.c
@@ -691,6 +691,10 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
f->os_desc_table[0].os_desc = &rndis_opts->rndis_os_desc;
}
+ rndis_iad_descriptor.bFunctionClass = rndis_opts->class;
+ rndis_iad_descriptor.bFunctionSubClass = rndis_opts->subclass;
+ rndis_iad_descriptor.bFunctionProtocol = rndis_opts->protocol;
+
/*
* in drivers/usb/gadget/configfs.c:configfs_composite_bind()
* configurations are bound in sequence with list_for_each_entry,
@@ -866,11 +870,23 @@ USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(rndis);
/* f_rndis_opts_ifname */
USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(rndis);
+/* f_rndis_opts_class */
+USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(rndis, class);
+
+/* f_rndis_opts_subclass */
+USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(rndis, subclass);
+
+/* f_rndis_opts_protocol */
+USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(rndis, protocol);
+
static struct configfs_attribute *rndis_attrs[] = {
&rndis_opts_attr_dev_addr,
&rndis_opts_attr_host_addr,
&rndis_opts_attr_qmult,
&rndis_opts_attr_ifname,
+ &rndis_opts_attr_class,
+ &rndis_opts_attr_subclass,
+ &rndis_opts_attr_protocol,
NULL,
};
@@ -916,6 +932,10 @@ static struct usb_function_instance *rndis_alloc_inst(void)
}
INIT_LIST_HEAD(&opts->rndis_os_desc.ext_prop);
+ opts->class = rndis_iad_descriptor.bFunctionClass;
+ opts->subclass = rndis_iad_descriptor.bFunctionSubClass;
+ opts->protocol = rndis_iad_descriptor.bFunctionProtocol;
+
descs[0] = &opts->rndis_os_desc;
names[0] = "rndis";
config_group_init_type_name(&opts->func_inst.group, "",
diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c
index 5dd73b9..3971bba 100644
--- a/drivers/usb/gadget/function/u_audio.c
+++ b/drivers/usb/gadget/function/u_audio.c
@@ -79,7 +79,7 @@ struct snd_uac_chip {
unsigned int p_framesize;
};
-static struct snd_pcm_hardware uac_pcm_hardware = {
+static const struct snd_pcm_hardware uac_pcm_hardware = {
.info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER
| SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID
| SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
@@ -354,7 +354,7 @@ static int uac_pcm_null(struct snd_pcm_substream *substream)
return 0;
}
-static struct snd_pcm_ops uac_pcm_ops = {
+static const struct snd_pcm_ops uac_pcm_ops = {
.open = uac_pcm_open,
.close = uac_pcm_null,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c
index a8b40d0..bdbc3fd 100644
--- a/drivers/usb/gadget/function/u_ether.c
+++ b/drivers/usb/gadget/function/u_ether.c
@@ -1073,7 +1073,7 @@ struct net_device *gether_connect(struct gether *link)
if (result == 0) {
dev->zlp = link->is_zlp_ok;
- dev->no_skb_reserve = link->no_skb_reserve;
+ dev->no_skb_reserve = gadget_avoids_skb_reserve(dev->gadget);
DBG(dev, "qlen %d\n", qlen(dev->gadget, dev->qmult));
dev->header_len = link->header_len;
diff --git a/drivers/usb/gadget/function/u_ether.h b/drivers/usb/gadget/function/u_ether.h
index 81d94a7..c77145b 100644
--- a/drivers/usb/gadget/function/u_ether.h
+++ b/drivers/usb/gadget/function/u_ether.h
@@ -64,7 +64,6 @@ struct gether {
struct usb_ep *out_ep;
bool is_zlp_ok;
- bool no_skb_reserve;
u16 cdc_filter;
diff --git a/drivers/usb/gadget/function/u_ether_configfs.h b/drivers/usb/gadget/function/u_ether_configfs.h
index c71133d..e4c3f84a 100644
--- a/drivers/usb/gadget/function/u_ether_configfs.h
+++ b/drivers/usb/gadget/function/u_ether_configfs.h
@@ -153,4 +153,39 @@ out: \
\
CONFIGFS_ATTR_RO(_f_##_opts_, ifname)
+#define USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(_f_, _n_) \
+ static ssize_t _f_##_opts_##_n_##_show(struct config_item *item,\
+ char *page) \
+ { \
+ struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \
+ int ret; \
+ \
+ mutex_lock(&opts->lock); \
+ ret = sprintf(page, "%02x\n", opts->_n_); \
+ mutex_unlock(&opts->lock); \
+ \
+ return ret; \
+ } \
+ \
+ static ssize_t _f_##_opts_##_n_##_store(struct config_item *item,\
+ const char *page, \
+ size_t len) \
+ { \
+ struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \
+ int ret; \
+ u8 val; \
+ \
+ mutex_lock(&opts->lock); \
+ ret = sscanf(page, "%02hhx", &val); \
+ if (ret > 0) { \
+ opts->_n_ = val; \
+ ret = len; \
+ } \
+ mutex_unlock(&opts->lock); \
+ \
+ return ret; \
+ } \
+ \
+ CONFIGFS_ATTR(_f_##_opts_, _n_)
+
#endif /* __U_ETHER_CONFIGFS_H */
diff --git a/drivers/usb/gadget/function/u_rndis.h b/drivers/usb/gadget/function/u_rndis.h
index 4eafd50..a35ee3c 100644
--- a/drivers/usb/gadget/function/u_rndis.h
+++ b/drivers/usb/gadget/function/u_rndis.h
@@ -29,6 +29,10 @@ struct f_rndis_opts {
struct usb_os_desc rndis_os_desc;
char rndis_ext_compat_id[16];
+ u8 class;
+ u8 subclass;
+ u8 protocol;
+
/*
* Read/write access to configfs attributes is handled by configfs.
*
diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c
index 9b0805f..4176216 100644
--- a/drivers/usb/gadget/function/u_serial.c
+++ b/drivers/usb/gadget/function/u_serial.c
@@ -537,7 +537,7 @@ static void gs_rx_push(unsigned long _port)
}
/* push data to (open) tty */
- if (req->actual) {
+ if (req->actual && tty) {
char *packet = req->buf;
unsigned size = req->actual;
unsigned n;
diff --git a/drivers/usb/gadget/legacy/webcam.c b/drivers/usb/gadget/legacy/webcam.c
index f9661cd..82c13fc 100644
--- a/drivers/usb/gadget/legacy/webcam.c
+++ b/drivers/usb/gadget/legacy/webcam.c
@@ -436,5 +436,4 @@ module_usb_composite_driver(webcam_driver);
MODULE_AUTHOR("Laurent Pinchart");
MODULE_DESCRIPTION("Webcam Video Gadget");
MODULE_LICENSE("GPL");
-MODULE_VERSION("0.1.0");
diff --git a/drivers/usb/gadget/udc/bdc/Kconfig b/drivers/usb/gadget/udc/bdc/Kconfig
index eb8b553..c74ac25 100644
--- a/drivers/usb/gadget/udc/bdc/Kconfig
+++ b/drivers/usb/gadget/udc/bdc/Kconfig
@@ -1,6 +1,7 @@
config USB_BDC_UDC
tristate "Broadcom USB3.0 device controller IP driver(BDC)"
depends on USB_GADGET && HAS_DMA
+ default ARCH_BRCMSTB
help
BDC is Broadcom's USB3.0 device controller IP. If your SOC has a BDC IP
diff --git a/drivers/usb/gadget/udc/bdc/bdc.h b/drivers/usb/gadget/udc/bdc/bdc.h
index 916d471..6df0352 100644
--- a/drivers/usb/gadget/udc/bdc/bdc.h
+++ b/drivers/usb/gadget/udc/bdc/bdc.h
@@ -27,8 +27,8 @@
#include <linux/usb/gadget.h>
#include <asm/unaligned.h>
-#define BRCM_BDC_NAME "bdc_usb3"
-#define BRCM_BDC_DESC "BDC device controller driver"
+#define BRCM_BDC_NAME "bdc"
+#define BRCM_BDC_DESC "Broadcom USB Device Controller driver"
#define DMA_ADDR_INVALID (~(dma_addr_t)0)
@@ -83,14 +83,14 @@
#define BDC_DVCSA 0x50
#define BDC_DVCSB 0x54
-#define BDC_EPSTS0(n) (0x60 + (n * 0x10))
-#define BDC_EPSTS1(n) (0x64 + (n * 0x10))
-#define BDC_EPSTS2(n) (0x68 + (n * 0x10))
-#define BDC_EPSTS3(n) (0x6c + (n * 0x10))
-#define BDC_EPSTS4(n) (0x70 + (n * 0x10))
-#define BDC_EPSTS5(n) (0x74 + (n * 0x10))
-#define BDC_EPSTS6(n) (0x78 + (n * 0x10))
-#define BDC_EPSTS7(n) (0x7c + (n * 0x10))
+#define BDC_EPSTS0 0x60
+#define BDC_EPSTS1 0x64
+#define BDC_EPSTS2 0x68
+#define BDC_EPSTS3 0x6c
+#define BDC_EPSTS4 0x70
+#define BDC_EPSTS5 0x74
+#define BDC_EPSTS6 0x78
+#define BDC_EPSTS7 0x7c
#define BDC_SRRBAL(n) (0x200 + (n * 0x10))
#define BDC_SRRBAH(n) (0x204 + (n * 0x10))
#define BDC_SRRINT(n) (0x208 + (n * 0x10))
@@ -413,6 +413,9 @@ struct bdc {
/* device lock */
spinlock_t lock;
+ /* generic phy */
+ struct phy **phys;
+ int num_phys;
/* num of endpoints for a particular instantiation of IP */
unsigned int num_eps;
/*
@@ -454,6 +457,7 @@ struct bdc {
* Func Wake packet every 2.5 secs. Refer to USB3 spec section 8.5.6.4
*/
struct delayed_work func_wake_notify;
+ struct clk *clk;
};
static inline u32 bdc_readl(void __iomem *base, u32 offset)
diff --git a/drivers/usb/gadget/udc/bdc/bdc_core.c b/drivers/usb/gadget/udc/bdc/bdc_core.c
index e9bd8d4..7a8af4b 100644
--- a/drivers/usb/gadget/udc/bdc/bdc_core.c
+++ b/drivers/usb/gadget/udc/bdc/bdc_core.c
@@ -24,9 +24,11 @@
#include <linux/dma-mapping.h>
#include <linux/dmapool.h>
#include <linux/of.h>
+#include <linux/phy/phy.h>
#include <linux/moduleparam.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
+#include <linux/clk.h>
#include "bdc.h"
#include "bdc_dbg.h"
@@ -444,6 +446,43 @@ static int bdc_hw_init(struct bdc *bdc)
return 0;
}
+static int bdc_phy_init(struct bdc *bdc)
+{
+ int phy_num;
+ int ret;
+
+ for (phy_num = 0; phy_num < bdc->num_phys; phy_num++) {
+ ret = phy_init(bdc->phys[phy_num]);
+ if (ret)
+ goto err_exit_phy;
+ ret = phy_power_on(bdc->phys[phy_num]);
+ if (ret) {
+ phy_exit(bdc->phys[phy_num]);
+ goto err_exit_phy;
+ }
+ }
+
+ return 0;
+
+err_exit_phy:
+ while (--phy_num >= 0) {
+ phy_power_off(bdc->phys[phy_num]);
+ phy_exit(bdc->phys[phy_num]);
+ }
+
+ return ret;
+}
+
+static void bdc_phy_exit(struct bdc *bdc)
+{
+ int phy_num;
+
+ for (phy_num = 0; phy_num < bdc->num_phys; phy_num++) {
+ phy_power_off(bdc->phys[phy_num]);
+ phy_exit(bdc->phys[phy_num]);
+ }
+}
+
static int bdc_probe(struct platform_device *pdev)
{
struct bdc *bdc;
@@ -452,12 +491,29 @@ static int bdc_probe(struct platform_device *pdev)
int irq;
u32 temp;
struct device *dev = &pdev->dev;
+ struct clk *clk;
+ int phy_num;
dev_dbg(dev, "%s()\n", __func__);
+
+ clk = devm_clk_get(dev, "sw_usbd");
+ if (IS_ERR(clk)) {
+ dev_info(dev, "Clock not found in Device Tree\n");
+ clk = NULL;
+ }
+
+ ret = clk_prepare_enable(clk);
+ if (ret) {
+ dev_err(dev, "could not enable clock\n");
+ return ret;
+ }
+
bdc = devm_kzalloc(dev, sizeof(*bdc), GFP_KERNEL);
if (!bdc)
return -ENOMEM;
+ bdc->clk = clk;
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
bdc->regs = devm_ioremap_resource(dev, res);
if (IS_ERR(bdc->regs)) {
@@ -473,35 +529,66 @@ static int bdc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, bdc);
bdc->irq = irq;
bdc->dev = dev;
- dev_dbg(bdc->dev, "bdc->regs: %p irq=%d\n", bdc->regs, bdc->irq);
+ dev_dbg(dev, "bdc->regs: %p irq=%d\n", bdc->regs, bdc->irq);
+
+ bdc->num_phys = of_count_phandle_with_args(dev->of_node,
+ "phys", "#phy-cells");
+ if (bdc->num_phys > 0) {
+ bdc->phys = devm_kcalloc(dev, bdc->num_phys,
+ sizeof(struct phy *), GFP_KERNEL);
+ if (!bdc->phys)
+ return -ENOMEM;
+ } else {
+ bdc->num_phys = 0;
+ }
+ dev_info(dev, "Using %d phy(s)\n", bdc->num_phys);
+
+ for (phy_num = 0; phy_num < bdc->num_phys; phy_num++) {
+ bdc->phys[phy_num] = devm_of_phy_get_by_index(
+ dev, dev->of_node, phy_num);
+ if (IS_ERR(bdc->phys[phy_num])) {
+ ret = PTR_ERR(bdc->phys[phy_num]);
+ dev_err(bdc->dev,
+ "BDC phy specified but not found:%d\n", ret);
+ return ret;
+ }
+ }
+
+ ret = bdc_phy_init(bdc);
+ if (ret) {
+ dev_err(bdc->dev, "BDC phy init failure:%d\n", ret);
+ return ret;
+ }
temp = bdc_readl(bdc->regs, BDC_BDCCAP1);
if ((temp & BDC_P64) &&
!dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) {
- dev_dbg(bdc->dev, "Using 64-bit address\n");
+ dev_dbg(dev, "Using 64-bit address\n");
} else {
- ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
if (ret) {
- dev_err(bdc->dev, "No suitable DMA config available, abort\n");
+ dev_err(dev,
+ "No suitable DMA config available, abort\n");
return -ENOTSUPP;
}
- dev_dbg(bdc->dev, "Using 32-bit address\n");
+ dev_dbg(dev, "Using 32-bit address\n");
}
ret = bdc_hw_init(bdc);
if (ret) {
- dev_err(bdc->dev, "BDC init failure:%d\n", ret);
- return ret;
+ dev_err(dev, "BDC init failure:%d\n", ret);
+ goto phycleanup;
}
ret = bdc_udc_init(bdc);
if (ret) {
- dev_err(bdc->dev, "BDC Gadget init failure:%d\n", ret);
+ dev_err(dev, "BDC Gadget init failure:%d\n", ret);
goto cleanup;
}
return 0;
cleanup:
bdc_hw_exit(bdc);
-
+phycleanup:
+ bdc_phy_exit(bdc);
return ret;
}
@@ -513,13 +600,56 @@ static int bdc_remove(struct platform_device *pdev)
dev_dbg(bdc->dev, "%s ()\n", __func__);
bdc_udc_exit(bdc);
bdc_hw_exit(bdc);
+ bdc_phy_exit(bdc);
+ clk_disable_unprepare(bdc->clk);
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int bdc_suspend(struct device *dev)
+{
+ struct bdc *bdc = dev_get_drvdata(dev);
+ clk_disable_unprepare(bdc->clk);
return 0;
}
+static int bdc_resume(struct device *dev)
+{
+ struct bdc *bdc = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(bdc->clk);
+ if (ret) {
+ dev_err(bdc->dev, "err enabling the clock\n");
+ return ret;
+ }
+ ret = bdc_reinit(bdc);
+ if (ret) {
+ dev_err(bdc->dev, "err in bdc reinit\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+#endif /* CONFIG_PM_SLEEP */
+
+static SIMPLE_DEV_PM_OPS(bdc_pm_ops, bdc_suspend,
+ bdc_resume);
+
+static const struct of_device_id bdc_of_match[] = {
+ { .compatible = "brcm,bdc-v0.16" },
+ { .compatible = "brcm,bdc" },
+ { /* sentinel */ }
+};
+
static struct platform_driver bdc_driver = {
.driver = {
.name = BRCM_BDC_NAME,
+ .owner = THIS_MODULE,
+ .pm = &bdc_pm_ops,
+ .of_match_table = bdc_of_match,
},
.probe = bdc_probe,
.remove = bdc_remove,
diff --git a/drivers/usb/gadget/udc/bdc/bdc_dbg.c b/drivers/usb/gadget/udc/bdc/bdc_dbg.c
index 5945dbc..ac98f6f 100644
--- a/drivers/usb/gadget/udc/bdc/bdc_dbg.c
+++ b/drivers/usb/gadget/udc/bdc/bdc_dbg.c
@@ -40,28 +40,28 @@ void bdc_dump_epsts(struct bdc *bdc)
{
u32 temp;
- temp = bdc_readl(bdc->regs, BDC_EPSTS0(0));
+ temp = bdc_readl(bdc->regs, BDC_EPSTS0);
dev_vdbg(bdc->dev, "BDC_EPSTS0:0x%08x\n", temp);
- temp = bdc_readl(bdc->regs, BDC_EPSTS1(0));
+ temp = bdc_readl(bdc->regs, BDC_EPSTS1);
dev_vdbg(bdc->dev, "BDC_EPSTS1:0x%x\n", temp);
- temp = bdc_readl(bdc->regs, BDC_EPSTS2(0));
+ temp = bdc_readl(bdc->regs, BDC_EPSTS2);
dev_vdbg(bdc->dev, "BDC_EPSTS2:0x%08x\n", temp);
- temp = bdc_readl(bdc->regs, BDC_EPSTS3(0));
+ temp = bdc_readl(bdc->regs, BDC_EPSTS3);
dev_vdbg(bdc->dev, "BDC_EPSTS3:0x%08x\n", temp);
- temp = bdc_readl(bdc->regs, BDC_EPSTS4(0));
+ temp = bdc_readl(bdc->regs, BDC_EPSTS4);
dev_vdbg(bdc->dev, "BDC_EPSTS4:0x%08x\n", temp);
- temp = bdc_readl(bdc->regs, BDC_EPSTS5(0));
+ temp = bdc_readl(bdc->regs, BDC_EPSTS5);
dev_vdbg(bdc->dev, "BDC_EPSTS5:0x%08x\n", temp);
- temp = bdc_readl(bdc->regs, BDC_EPSTS6(0));
+ temp = bdc_readl(bdc->regs, BDC_EPSTS6);
dev_vdbg(bdc->dev, "BDC_EPSTS6:0x%08x\n", temp);
- temp = bdc_readl(bdc->regs, BDC_EPSTS7(0));
+ temp = bdc_readl(bdc->regs, BDC_EPSTS7);
dev_vdbg(bdc->dev, "BDC_EPSTS7:0x%08x\n", temp);
}
diff --git a/drivers/usb/gadget/udc/bdc/bdc_ep.c b/drivers/usb/gadget/udc/bdc/bdc_ep.c
index ff1ef24..bfd8f7a 100644
--- a/drivers/usb/gadget/udc/bdc/bdc_ep.c
+++ b/drivers/usb/gadget/udc/bdc/bdc_ep.c
@@ -777,9 +777,9 @@ static int ep_dequeue(struct bdc_ep *ep, struct bdc_req *req)
*/
/* The current hw dequeue pointer */
- tmp_32 = bdc_readl(bdc->regs, BDC_EPSTS0(0));
+ tmp_32 = bdc_readl(bdc->regs, BDC_EPSTS0);
deq_ptr_64 = tmp_32;
- tmp_32 = bdc_readl(bdc->regs, BDC_EPSTS1(0));
+ tmp_32 = bdc_readl(bdc->regs, BDC_EPSTS1);
deq_ptr_64 |= ((u64)tmp_32 << 32);
/* we have the dma addr of next bd that will be fetched by hardware */
diff --git a/drivers/usb/gadget/udc/bdc/bdc_udc.c b/drivers/usb/gadget/udc/bdc/bdc_udc.c
index aae7458..c843461 100644
--- a/drivers/usb/gadget/udc/bdc/bdc_udc.c
+++ b/drivers/usb/gadget/udc/bdc/bdc_udc.c
@@ -249,6 +249,7 @@ void bdc_sr_uspc(struct bdc *bdc, struct bdc_sr *sreport)
disconn = true;
else if ((uspc & BDC_PCS) && !BDC_PST(uspc))
connected = true;
+ clear_flags |= BDC_PCC;
}
/* Change in VBus and VBus is present */
@@ -259,16 +260,16 @@ void bdc_sr_uspc(struct bdc *bdc, struct bdc_sr *sreport)
bdc_softconn(bdc);
usb_gadget_set_state(&bdc->gadget, USB_STATE_POWERED);
}
- clear_flags = BDC_VBC;
+ clear_flags |= BDC_VBC;
} else if ((uspc & BDC_PRS) || (uspc & BDC_PRC) || disconn) {
/* Hot reset, warm reset, 2.0 bus reset or disconn */
dev_dbg(bdc->dev, "Port reset or disconn\n");
bdc_uspc_disconnected(bdc, disconn);
- clear_flags = BDC_PCC|BDC_PCS|BDC_PRS|BDC_PRC;
+ clear_flags |= BDC_PRC;
} else if ((uspc & BDC_PSC) && (uspc & BDC_PCS)) {
/* Change in Link state */
handle_link_state_change(bdc, uspc);
- clear_flags = BDC_PSC|BDC_PCS;
+ clear_flags |= BDC_PSC;
}
/*
diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
index e6f04ee..75c51ca 100644
--- a/drivers/usb/gadget/udc/core.c
+++ b/drivers/usb/gadget/udc/core.c
@@ -812,6 +812,8 @@ int usb_gadget_map_request_by_dev(struct device *dev,
dev_err(dev, "failed to map buffer\n");
return -EFAULT;
}
+
+ req->dma_mapped = 1;
}
return 0;
@@ -836,9 +838,10 @@ void usb_gadget_unmap_request_by_dev(struct device *dev,
is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
req->num_mapped_sgs = 0;
- } else {
+ } else if (req->dma_mapped) {
dma_unmap_single(dev, req->dma, req->length,
is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+ req->dma_mapped = 0;
}
}
EXPORT_SYMBOL_GPL(usb_gadget_unmap_request_by_dev);
@@ -1130,6 +1133,7 @@ static int check_pending_gadget_drivers(struct usb_udc *udc)
* @release: a gadget release function.
*
* Returns zero on success, negative errno otherwise.
+ * Calls the gadget release function in the latter case.
*/
int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
void (*release)(struct device *dev))
@@ -1137,10 +1141,6 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
struct usb_udc *udc;
int ret = -ENOMEM;
- udc = kzalloc(sizeof(*udc), GFP_KERNEL);
- if (!udc)
- goto err1;
-
dev_set_name(&gadget->dev, "gadget");
INIT_WORK(&gadget->work, usb_gadget_state_work);
gadget->dev.parent = parent;
@@ -1150,7 +1150,13 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
else
gadget->dev.release = usb_udc_nop_release;
- ret = device_register(&gadget->dev);
+ device_initialize(&gadget->dev);
+
+ udc = kzalloc(sizeof(*udc), GFP_KERNEL);
+ if (!udc)
+ goto err1;
+
+ ret = device_add(&gadget->dev);
if (ret)
goto err2;
@@ -1197,10 +1203,10 @@ err3:
device_del(&gadget->dev);
err2:
- put_device(&gadget->dev);
kfree(udc);
err1:
+ put_device(&gadget->dev);
return ret;
}
EXPORT_SYMBOL_GPL(usb_add_gadget_udc_release);
diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c
index 3c37603..a030d79 100644
--- a/drivers/usb/gadget/udc/dummy_hcd.c
+++ b/drivers/usb/gadget/udc/dummy_hcd.c
@@ -2776,7 +2776,7 @@ static int __init init(void)
if (retval < 0) {
i--;
while (i >= 0)
- platform_device_del(the_udc_pdev[i]);
+ platform_device_del(the_udc_pdev[i--]);
goto err_add_udc;
}
}
diff --git a/drivers/usb/gadget/udc/fsl_qe_udc.c b/drivers/usb/gadget/udc/fsl_qe_udc.c
index 303328ce..a3e72d6 100644
--- a/drivers/usb/gadget/udc/fsl_qe_udc.c
+++ b/drivers/usb/gadget/udc/fsl_qe_udc.c
@@ -62,7 +62,7 @@ static const char *const ep_name[] = {
"ep3",
};
-static struct usb_endpoint_descriptor qe_ep0_desc = {
+static const struct usb_endpoint_descriptor qe_ep0_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
diff --git a/drivers/usb/gadget/udc/mv_udc_core.c b/drivers/usb/gadget/udc/mv_udc_core.c
index 8a708d0..4103bf7 100644
--- a/drivers/usb/gadget/udc/mv_udc_core.c
+++ b/drivers/usb/gadget/udc/mv_udc_core.c
@@ -39,7 +39,6 @@
#include "mv_udc.h"
#define DRIVER_DESC "Marvell PXA USB Device Controller driver"
-#define DRIVER_VERSION "8 Nov 2010"
#define ep_dir(ep) (((ep)->ep_num == 0) ? \
((ep)->udc->ep0_dir) : ((ep)->direction))
@@ -2427,5 +2426,4 @@ module_platform_driver(udc_driver);
MODULE_ALIAS("platform:mv-udc");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_AUTHOR("Chao Xie <chao.xie@marvell.com>");
-MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c
index e1de8fe..df37c1e 100644
--- a/drivers/usb/gadget/udc/renesas_usb3.c
+++ b/drivers/usb/gadget/udc/renesas_usb3.c
@@ -8,6 +8,7 @@
* the Free Software Foundation; version 2 of the License.
*/
+#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
@@ -20,6 +21,8 @@
#include <linux/pm_runtime.h>
#include <linux/sizes.h>
#include <linux/slab.h>
+#include <linux/sys_soc.h>
+#include <linux/uaccess.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
@@ -347,6 +350,7 @@ struct renesas_usb3 {
bool workaround_for_vbus;
bool extcon_host; /* check id and set EXTCON_USB_HOST */
bool extcon_usb; /* check vbus and set EXTCON_USB */
+ bool forced_b_device;
};
#define gadget_to_renesas_usb3(_gadget) \
@@ -663,7 +667,9 @@ static void usb3_mode_config(struct renesas_usb3 *usb3, bool host, bool a_dev)
spin_lock_irqsave(&usb3->lock, flags);
usb3_set_mode(usb3, host);
usb3_vbus_out(usb3, a_dev);
- if (!host && a_dev) /* for A-Peripheral */
+ /* for A-Peripheral or forced B-device mode */
+ if ((!host && a_dev) ||
+ (usb3->workaround_for_vbus && usb3->forced_b_device))
usb3_connect(usb3);
spin_unlock_irqrestore(&usb3->lock, flags);
}
@@ -677,7 +683,7 @@ static void usb3_check_id(struct renesas_usb3 *usb3)
{
usb3->extcon_host = usb3_is_a_device(usb3);
- if (usb3->extcon_host)
+ if (usb3->extcon_host && !usb3->forced_b_device)
usb3_mode_config(usb3, true, true);
else
usb3_mode_config(usb3, false, false);
@@ -2192,7 +2198,7 @@ static void renesas_usb3_ep_fifo_flush(struct usb_ep *_ep)
}
}
-static struct usb_ep_ops renesas_usb3_ep_ops = {
+static const struct usb_ep_ops renesas_usb3_ep_ops = {
.enable = renesas_usb3_ep_enable,
.disable = renesas_usb3_ep_disable,
@@ -2283,6 +2289,9 @@ static ssize_t role_store(struct device *dev, struct device_attribute *attr,
if (!usb3->driver)
return -ENODEV;
+ if (usb3->forced_b_device)
+ return -EBUSY;
+
if (!strncmp(buf, "host", strlen("host")))
new_mode_is_host = true;
else if (!strncmp(buf, "peripheral", strlen("peripheral")))
@@ -2310,6 +2319,70 @@ static ssize_t role_show(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_RW(role);
+static int renesas_usb3_b_device_show(struct seq_file *s, void *unused)
+{
+ struct renesas_usb3 *usb3 = s->private;
+
+ seq_printf(s, "%d\n", usb3->forced_b_device);
+
+ return 0;
+}
+
+static int renesas_usb3_b_device_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, renesas_usb3_b_device_show, inode->i_private);
+}
+
+static ssize_t renesas_usb3_b_device_write(struct file *file,
+ const char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct seq_file *s = file->private_data;
+ struct renesas_usb3 *usb3 = s->private;
+ char buf[32];
+
+ if (!usb3->driver)
+ return -ENODEV;
+
+ if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
+ return -EFAULT;
+
+ if (!strncmp(buf, "1", 1))
+ usb3->forced_b_device = true;
+ else
+ usb3->forced_b_device = false;
+
+ /* Let this driver call usb3_connect() anyway */
+ usb3_check_id(usb3);
+
+ return count;
+}
+
+static const struct file_operations renesas_usb3_b_device_fops = {
+ .open = renesas_usb3_b_device_open,
+ .write = renesas_usb3_b_device_write,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static void renesas_usb3_debugfs_init(struct renesas_usb3 *usb3,
+ struct device *dev)
+{
+ struct dentry *root, *file;
+
+ root = debugfs_create_dir(dev_name(dev), NULL);
+ if (IS_ERR_OR_NULL(root)) {
+ dev_info(dev, "%s: Can't create the root\n", __func__);
+ return;
+ }
+
+ file = debugfs_create_file("b_device", 0644, root, usb3,
+ &renesas_usb3_b_device_fops);
+ if (!file)
+ dev_info(dev, "%s: Can't create debugfs mode\n", __func__);
+}
+
/*------- platform_driver ------------------------------------------------*/
static int renesas_usb3_remove(struct platform_device *pdev)
{
@@ -2432,22 +2505,40 @@ static void renesas_usb3_init_ram(struct renesas_usb3 *usb3, struct device *dev,
}
}
-static const struct renesas_usb3_priv renesas_usb3_priv_r8a7795 = {
+static const struct renesas_usb3_priv renesas_usb3_priv_r8a7795_es1 = {
.ramsize_per_ramif = SZ_16K,
.num_ramif = 2,
.ramsize_per_pipe = SZ_4K,
.workaround_for_vbus = true,
};
+static const struct renesas_usb3_priv renesas_usb3_priv_gen3 = {
+ .ramsize_per_ramif = SZ_16K,
+ .num_ramif = 4,
+ .ramsize_per_pipe = SZ_4K,
+};
+
static const struct of_device_id usb3_of_match[] = {
{
.compatible = "renesas,r8a7795-usb3-peri",
- .data = &renesas_usb3_priv_r8a7795,
+ .data = &renesas_usb3_priv_gen3,
+ },
+ {
+ .compatible = "renesas,rcar-gen3-usb3-peri",
+ .data = &renesas_usb3_priv_gen3,
},
{ },
};
MODULE_DEVICE_TABLE(of, usb3_of_match);
+static const struct soc_device_attribute renesas_usb3_quirks_match[] = {
+ {
+ .soc_id = "r8a7795", .revision = "ES1.*",
+ .data = &renesas_usb3_priv_r8a7795_es1,
+ },
+ { /* sentinel */ },
+};
+
static const unsigned int renesas_usb3_cable[] = {
EXTCON_USB,
EXTCON_USB_HOST,
@@ -2461,15 +2552,23 @@ static int renesas_usb3_probe(struct platform_device *pdev)
const struct of_device_id *match;
int irq, ret;
const struct renesas_usb3_priv *priv;
+ const struct soc_device_attribute *attr;
match = of_match_node(usb3_of_match, pdev->dev.of_node);
if (!match)
return -ENODEV;
- priv = match->data;
+
+ attr = soc_device_match(renesas_usb3_quirks_match);
+ if (attr)
+ priv = attr->data;
+ else
+ priv = match->data;
irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- return -ENODEV;
+ if (irq < 0) {
+ dev_err(&pdev->dev, "Failed to get IRQ: %d\n", irq);
+ return irq;
+ }
usb3 = devm_kzalloc(&pdev->dev, sizeof(*usb3), GFP_KERNEL);
if (!usb3)
@@ -2527,6 +2626,8 @@ static int renesas_usb3_probe(struct platform_device *pdev)
usb3->workaround_for_vbus = priv->workaround_for_vbus;
+ renesas_usb3_debugfs_init(usb3, &pdev->dev);
+
dev_info(&pdev->dev, "probed\n");
return 0;
diff --git a/drivers/usb/gadget/udc/s3c2410_udc.c b/drivers/usb/gadget/udc/s3c2410_udc.c
index 4643a01..394abd5 100644
--- a/drivers/usb/gadget/udc/s3c2410_udc.c
+++ b/drivers/usb/gadget/udc/s3c2410_udc.c
@@ -51,7 +51,6 @@
#include "s3c2410_udc.h"
#define DRIVER_DESC "S3C2410 USB Device Controller Gadget"
-#define DRIVER_VERSION "29 Apr 2007"
#define DRIVER_AUTHOR "Herbert Pötzl <herbert@13thfloor.at>, " \
"Arnaud Patard <arnaud.patard@rtp-net.org>"
@@ -1996,7 +1995,7 @@ static int __init udc_init(void)
{
int retval;
- dprintk(DEBUG_NORMAL, "%s: version %s\n", gadget_name, DRIVER_VERSION);
+ dprintk(DEBUG_NORMAL, "%s\n", gadget_name);
s3c2410_udc_debugfs_root = debugfs_create_dir(gadget_name, NULL);
if (IS_ERR(s3c2410_udc_debugfs_root)) {
@@ -2027,5 +2026,4 @@ module_exit(udc_exit);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index 4a08b70..d025cc0 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -642,7 +642,7 @@ static int ehci_start_port_reset(struct usb_hcd *hcd, unsigned port)
#define ehci_start_port_reset NULL
#endif /* CONFIG_USB_OTG */
-static struct ehci_driver_overrides ehci_fsl_overrides __initdata = {
+static const struct ehci_driver_overrides ehci_fsl_overrides __initconst = {
.extra_priv_size = sizeof(struct ehci_fsl),
.reset = ehci_fsl_setup,
};
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index 94ea9ff..4d30853 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -130,8 +130,8 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
- dev_err(dev, "EHCI irq failed\n");
- return -ENODEV;
+ dev_err(dev, "EHCI irq failed: %d\n", irq);
+ return irq;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c
index e90ddb5..ba557cd 100644
--- a/drivers/usb/host/fsl-mph-dr-of.c
+++ b/drivers/usb/host/fsl-mph-dr-of.c
@@ -55,8 +55,8 @@ static struct fsl_usb2_dev_data *get_dr_mode_data(struct device_node *np)
return &dr_mode_data[i];
}
}
- pr_warn("%s: Invalid 'dr_mode' property, fallback to host mode\n",
- np->full_name);
+ pr_warn("%pOF: Invalid 'dr_mode' property, fallback to host mode\n",
+ np);
return &dr_mode_data[0]; /* mode not specified, use host */
}
diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c
index 1db0626..da3b180 100644
--- a/drivers/usb/host/hwa-hc.c
+++ b/drivers/usb/host/hwa-hc.c
@@ -614,7 +614,7 @@ error:
return result;
}
-static struct hc_driver hwahc_hc_driver = {
+static const struct hc_driver hwahc_hc_driver = {
.description = "hwa-hcd",
.product_desc = "Wireless USB HWA host controller",
.hcd_priv_size = sizeof(struct hwahc) - sizeof(struct usb_hcd),
@@ -860,7 +860,7 @@ static void hwahc_disconnect(struct usb_interface *usb_iface)
usb_put_hcd(usb_hcd);
}
-static struct usb_device_id hwahc_id_table[] = {
+static const struct usb_device_id hwahc_id_table[] = {
/* Alereon 5310 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x13dc, 0x5310, 0xe0, 0x02, 0x01),
.driver_info = WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC |
diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c
index f542045..39ae7fb 100644
--- a/drivers/usb/host/imx21-hcd.c
+++ b/drivers/usb/host/imx21-hcd.c
@@ -1779,7 +1779,7 @@ static void imx21_hc_stop(struct usb_hcd *hcd)
/* Driver glue */
/* =========================================== */
-static struct hc_driver imx21_hc_driver = {
+static const struct hc_driver imx21_hc_driver = {
.description = hcd_name,
.product_desc = "IMX21 USB Host Controller",
.hcd_priv_size = sizeof(struct imx21),
@@ -1849,8 +1849,10 @@ static int imx21_probe(struct platform_device *pdev)
if (!res)
return -ENODEV;
irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- return -ENXIO;
+ if (irq < 0) {
+ dev_err(&pdev->dev, "Failed to get IRQ: %d\n", irq);
+ return irq;
+ }
hcd = usb_create_hcd(&imx21_hc_driver,
&pdev->dev, dev_name(&pdev->dev));
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index d089b3f..73fec38 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -1511,7 +1511,7 @@ static int isp116x_bus_resume(struct usb_hcd *hcd)
#endif
-static struct hc_driver isp116x_hc_driver = {
+static const struct hc_driver isp116x_hc_driver = {
.description = hcd_name,
.product_desc = "ISP116x Host Controller",
.hcd_priv_size = sizeof(struct isp116x),
diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c
index 0f2b4b3..9b7e307 100644
--- a/drivers/usb/host/isp1362-hcd.c
+++ b/drivers/usb/host/isp1362-hcd.c
@@ -2591,7 +2591,7 @@ static int isp1362_hc_start(struct usb_hcd *hcd)
/*-------------------------------------------------------------------------*/
-static struct hc_driver isp1362_hc_driver = {
+static const struct hc_driver isp1362_hc_driver = {
.description = hcd_name,
.product_desc = "ISP1362 Host Controller",
.hcd_priv_size = sizeof(struct isp1362_hcd),
diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c
index 369869a..0ece9a9 100644
--- a/drivers/usb/host/max3421-hcd.c
+++ b/drivers/usb/host/max3421-hcd.c
@@ -1811,7 +1811,7 @@ max3421_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
{
}
-static struct hc_driver max3421_hcd_desc = {
+static const struct hc_driver max3421_hcd_desc = {
.description = "max3421",
.product_desc = DRIVER_DESC,
.hcd_priv_size = sizeof(struct max3421_hcd),
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index c8f3864..658d9d1 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -142,29 +142,30 @@ static int amd_chipset_sb_type_init(struct amd_chipset_info *pinfo)
pinfo->sb_type.gen = AMD_CHIPSET_SB700;
else if (rev >= 0x40 && rev <= 0x4f)
pinfo->sb_type.gen = AMD_CHIPSET_SB800;
- }
- pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD,
- 0x145c, NULL);
- if (pinfo->smbus_dev) {
- pinfo->sb_type.gen = AMD_CHIPSET_TAISHAN;
} else {
pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD,
PCI_DEVICE_ID_AMD_HUDSON2_SMBUS, NULL);
- if (!pinfo->smbus_dev) {
- pinfo->sb_type.gen = NOT_AMD_CHIPSET;
- return 0;
+ if (pinfo->smbus_dev) {
+ rev = pinfo->smbus_dev->revision;
+ if (rev >= 0x11 && rev <= 0x14)
+ pinfo->sb_type.gen = AMD_CHIPSET_HUDSON2;
+ else if (rev >= 0x15 && rev <= 0x18)
+ pinfo->sb_type.gen = AMD_CHIPSET_BOLTON;
+ else if (rev >= 0x39 && rev <= 0x3a)
+ pinfo->sb_type.gen = AMD_CHIPSET_YANGTZE;
+ } else {
+ pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD,
+ 0x145c, NULL);
+ if (pinfo->smbus_dev) {
+ rev = pinfo->smbus_dev->revision;
+ pinfo->sb_type.gen = AMD_CHIPSET_TAISHAN;
+ } else {
+ pinfo->sb_type.gen = NOT_AMD_CHIPSET;
+ return 0;
+ }
}
-
- rev = pinfo->smbus_dev->revision;
- if (rev >= 0x11 && rev <= 0x14)
- pinfo->sb_type.gen = AMD_CHIPSET_HUDSON2;
- else if (rev >= 0x15 && rev <= 0x18)
- pinfo->sb_type.gen = AMD_CHIPSET_BOLTON;
- else if (rev >= 0x39 && rev <= 0x3a)
- pinfo->sb_type.gen = AMD_CHIPSET_YANGTZE;
}
-
pinfo->sb_type.rev = rev;
return 1;
}
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index 7bf78be..5e5fc9d 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -2312,7 +2312,7 @@ static int r8a66597_bus_resume(struct usb_hcd *hcd)
#define r8a66597_bus_resume NULL
#endif
-static struct hc_driver r8a66597_hc_driver = {
+static const struct hc_driver r8a66597_hc_driver = {
.description = hcd_name,
.hcd_priv_size = sizeof(struct r8a66597),
.irq = r8a66597_irq,
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index fd2a114..24ad1d6 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -1554,7 +1554,7 @@ sl811h_start(struct usb_hcd *hcd)
/*-------------------------------------------------------------------------*/
-static struct hc_driver sl811h_hc_driver = {
+static const struct hc_driver sl811h_hc_driver = {
.description = hcd_name,
.hcd_priv_size = sizeof(struct sl811),
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c
index 43d5293..c38855a 100644
--- a/drivers/usb/host/u132-hcd.c
+++ b/drivers/usb/host/u132-hcd.c
@@ -2941,7 +2941,7 @@ static int u132_bus_resume(struct usb_hcd *hcd)
#define u132_bus_suspend NULL
#define u132_bus_resume NULL
#endif
-static struct hc_driver u132_hc_driver = {
+static const struct hc_driver u132_hc_driver = {
.description = hcd_name,
.hcd_priv_size = sizeof(struct u132),
.irq = NULL,
diff --git a/drivers/usb/host/whci/hcd.c b/drivers/usb/host/whci/hcd.c
index 5b3603c..cf84269 100644
--- a/drivers/usb/host/whci/hcd.c
+++ b/drivers/usb/host/whci/hcd.c
@@ -213,7 +213,7 @@ static void whc_endpoint_reset(struct usb_hcd *usb_hcd,
}
-static struct hc_driver whc_hc_driver = {
+static const struct hc_driver whc_hc_driver = {
.description = "whci-hcd",
.product_desc = "Wireless host controller",
.hcd_priv_size = sizeof(struct whc) - sizeof(struct usb_hcd),
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 00721e8..ad89a6d 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -1179,6 +1179,39 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
break;
}
+ /*
+ * For xHCI 1.1 according to section 4.19.1.2.4.1 a
+ * root hub port's transition to compliance mode upon
+ * detecting LFPS timeout may be controlled by an
+ * Compliance Transition Enabled (CTE) flag (not
+ * software visible). This flag is set by writing 0xA
+ * to PORTSC PLS field which will allow transition to
+ * compliance mode the next time LFPS timeout is
+ * encountered. A warm reset will clear it.
+ *
+ * The CTE flag is only supported if the HCCPARAMS2 CTC
+ * flag is set, otherwise, the compliance substate is
+ * automatically entered as on 1.0 and prior.
+ */
+ if (link_state == USB_SS_PORT_LS_COMP_MOD) {
+ if (!HCC2_CTC(xhci->hcc_params2)) {
+ xhci_dbg(xhci, "CTC flag is 0, port already supports entering compliance mode\n");
+ break;
+ }
+
+ if ((temp & PORT_CONNECT)) {
+ xhci_warn(xhci, "Can't set compliance mode when port is connected\n");
+ goto error;
+ }
+
+ xhci_dbg(xhci, "Enable compliance mode transition for port %d\n",
+ wIndex);
+ xhci_set_link_state(xhci, port_array, wIndex,
+ link_state);
+ temp = readl(port_array[wIndex]);
+ break;
+ }
+
/* Software should not attempt to set
* port link state above '3' (U3) and the port
* must be enabled.
@@ -1521,15 +1554,14 @@ static bool xhci_port_missing_cas_quirk(int port_index,
int xhci_bus_resume(struct usb_hcd *hcd)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
- int max_ports, port_index;
- __le32 __iomem **port_array;
struct xhci_bus_state *bus_state;
- u32 temp;
+ __le32 __iomem **port_array;
unsigned long flags;
- unsigned long port_was_suspended = 0;
- bool need_usb2_u3_exit = false;
+ int max_ports, port_index;
int slot_id;
int sret;
+ u32 next_state;
+ u32 temp, portsc;
max_ports = xhci_get_ports(hcd, &port_array);
bus_state = &xhci->bus_state[hcd_index(hcd)];
@@ -1548,68 +1580,77 @@ int xhci_bus_resume(struct usb_hcd *hcd)
temp &= ~CMD_EIE;
writel(temp, &xhci->op_regs->command);
+ /* bus specific resume for ports we suspended at bus_suspend */
+ if (hcd->speed >= HCD_USB3)
+ next_state = XDEV_U0;
+ else
+ next_state = XDEV_RESUME;
+
port_index = max_ports;
while (port_index--) {
- /* Check whether need resume ports. If needed
- resume port and disable remote wakeup */
- u32 temp;
-
- temp = readl(port_array[port_index]);
+ portsc = readl(port_array[port_index]);
/* warm reset CAS limited ports stuck in polling/compliance */
if ((xhci->quirks & XHCI_MISSING_CAS) &&
(hcd->speed >= HCD_USB3) &&
xhci_port_missing_cas_quirk(port_index, port_array)) {
xhci_dbg(xhci, "reset stuck port %d\n", port_index);
+ clear_bit(port_index, &bus_state->bus_suspended);
continue;
}
- if (DEV_SUPERSPEED_ANY(temp))
- temp &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS);
- else
- temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
- if (test_bit(port_index, &bus_state->bus_suspended) &&
- (temp & PORT_PLS_MASK)) {
- set_bit(port_index, &port_was_suspended);
- if (!DEV_SUPERSPEED_ANY(temp)) {
- xhci_set_link_state(xhci, port_array,
- port_index, XDEV_RESUME);
- need_usb2_u3_exit = true;
+ /* resume if we suspended the link, and it is still suspended */
+ if (test_bit(port_index, &bus_state->bus_suspended))
+ switch (portsc & PORT_PLS_MASK) {
+ case XDEV_U3:
+ portsc = xhci_port_state_to_neutral(portsc);
+ portsc &= ~PORT_PLS_MASK;
+ portsc |= PORT_LINK_STROBE | next_state;
+ break;
+ case XDEV_RESUME:
+ /* resume already initiated */
+ break;
+ default:
+ /* not in a resumeable state, ignore it */
+ clear_bit(port_index,
+ &bus_state->bus_suspended);
+ break;
}
- } else
- writel(temp, port_array[port_index]);
- }
-
- if (need_usb2_u3_exit) {
- spin_unlock_irqrestore(&xhci->lock, flags);
- msleep(USB_RESUME_TIMEOUT);
- spin_lock_irqsave(&xhci->lock, flags);
+ /* disable wake for all ports, write new link state if needed */
+ portsc &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS);
+ writel(portsc, port_array[port_index]);
}
- port_index = max_ports;
- while (port_index--) {
- if (!(port_was_suspended & BIT(port_index)))
- continue;
- /* Clear PLC to poll it later after XDEV_U0 */
- xhci_test_and_clear_bit(xhci, port_array, port_index, PORT_PLC);
- xhci_set_link_state(xhci, port_array, port_index, XDEV_U0);
+ /* USB2 specific resume signaling delay and U0 link state transition */
+ if (hcd->speed < HCD_USB3) {
+ if (bus_state->bus_suspended) {
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ msleep(USB_RESUME_TIMEOUT);
+ spin_lock_irqsave(&xhci->lock, flags);
+ }
+ for_each_set_bit(port_index, &bus_state->bus_suspended,
+ BITS_PER_LONG) {
+ /* Clear PLC to poll it later for U0 transition */
+ xhci_test_and_clear_bit(xhci, port_array, port_index,
+ PORT_PLC);
+ xhci_set_link_state(xhci, port_array, port_index,
+ XDEV_U0);
+ }
}
- port_index = max_ports;
- while (port_index--) {
- if (!(port_was_suspended & BIT(port_index)))
- continue;
- /* Poll and Clear PLC */
+ /* poll for U0 link state complete, both USB2 and USB3 */
+ for_each_set_bit(port_index, &bus_state->bus_suspended, BITS_PER_LONG) {
sret = xhci_handshake(port_array[port_index], PORT_PLC,
PORT_PLC, 10 * 1000);
- if (sret)
+ if (sret) {
xhci_warn(xhci, "port %d resume PLC timeout\n",
port_index);
+ continue;
+ }
xhci_test_and_clear_bit(xhci, port_array, port_index, PORT_PLC);
slot_id = xhci_find_slot_id_by_port(hcd, xhci, port_index + 1);
if (slot_id)
xhci_ring_device(xhci, slot_id);
}
-
(void) readl(&xhci->op_regs->command);
bus_state->next_statechange = jiffies + msecs_to_jiffies(5);
diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
index 67d5dc7..8fb6065 100644
--- a/drivers/usb/host/xhci-mtk.c
+++ b/drivers/usb/host/xhci-mtk.c
@@ -795,6 +795,7 @@ static const struct dev_pm_ops xhci_mtk_pm_ops = {
#ifdef CONFIG_OF
static const struct of_device_id mtk_xhci_of_match[] = {
{ .compatible = "mediatek,mt8173-xhci"},
+ { .compatible = "mediatek,mtk-xhci"},
{ },
};
MODULE_DEVICE_TABLE(of, mtk_xhci_of_match);
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index c04144b..163bafd 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -107,14 +107,6 @@ static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen2 = {
};
static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen3 = {
- .firmware_name = XHCI_RCAR_FIRMWARE_NAME_V2,
- .init_quirk = xhci_rcar_init_quirk,
- .plat_start = xhci_rcar_start,
- .resume_quirk = xhci_rcar_resume_quirk,
-};
-
-static const struct xhci_plat_priv xhci_plat_renesas_rcar_r8a7796 = {
- .firmware_name = XHCI_RCAR_FIRMWARE_NAME_V3,
.init_quirk = xhci_rcar_init_quirk,
.plat_start = xhci_rcar_start,
.resume_quirk = xhci_rcar_resume_quirk,
@@ -145,7 +137,7 @@ static const struct of_device_id usb_xhci_of_match[] = {
.data = &xhci_plat_renesas_rcar_gen3,
}, {
.compatible = "renesas,xhci-r8a7796",
- .data = &xhci_plat_renesas_rcar_r8a7796,
+ .data = &xhci_plat_renesas_rcar_gen3,
}, {
.compatible = "renesas,rcar-gen2-xhci",
.data = &xhci_plat_renesas_rcar_gen2,
diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c
index 0727822..198bc18 100644
--- a/drivers/usb/host/xhci-rcar.c
+++ b/drivers/usb/host/xhci-rcar.c
@@ -13,13 +13,15 @@
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/usb/phy.h>
+#include <linux/sys_soc.h>
#include "xhci.h"
#include "xhci-plat.h"
#include "xhci-rcar.h"
/*
-* - The V3 firmware is for r8a7796 (with good performance).
+* - The V3 firmware is for r8a7796 (with good performance) and r8a7795 es2.0
+* or later.
* - The V2 firmware can be used on both r8a7795 (es1.x) and r8a7796.
* - The V2 firmware is possible to use on R-Car Gen2. However, the V2 causes
* performance degradation. So, this driver continues to use the V1 if R-Car
@@ -67,6 +69,26 @@ MODULE_FIRMWARE(XHCI_RCAR_FIRMWARE_NAME_V3);
#define RCAR_USB3_RX_POL_VAL BIT(21)
#define RCAR_USB3_TX_POL_VAL BIT(4)
+/* For soc_device_attribute */
+#define RCAR_XHCI_FIRMWARE_V2 BIT(0) /* FIRMWARE V2 */
+#define RCAR_XHCI_FIRMWARE_V3 BIT(1) /* FIRMWARE V3 */
+
+static const struct soc_device_attribute rcar_quirks_match[] = {
+ {
+ .soc_id = "r8a7795", .revision = "ES1.*",
+ .data = (void *)RCAR_XHCI_FIRMWARE_V2,
+ },
+ {
+ .soc_id = "r8a7795",
+ .data = (void *)RCAR_XHCI_FIRMWARE_V3,
+ },
+ {
+ .soc_id = "r8a7796",
+ .data = (void *)RCAR_XHCI_FIRMWARE_V3,
+ },
+ { /* sentinel */ },
+};
+
static void xhci_rcar_start_gen2(struct usb_hcd *hcd)
{
/* LCLK Select */
@@ -122,9 +144,23 @@ static int xhci_rcar_download_firmware(struct usb_hcd *hcd)
int retval, index, j, time;
int timeout = 10000;
u32 data, val, temp;
+ u32 quirks = 0;
+ const struct soc_device_attribute *attr;
+ const char *firmware_name;
+
+ attr = soc_device_match(rcar_quirks_match);
+ if (attr)
+ quirks = (uintptr_t)attr->data;
+
+ if (quirks & RCAR_XHCI_FIRMWARE_V2)
+ firmware_name = XHCI_RCAR_FIRMWARE_NAME_V2;
+ else if (quirks & RCAR_XHCI_FIRMWARE_V3)
+ firmware_name = XHCI_RCAR_FIRMWARE_NAME_V3;
+ else
+ firmware_name = priv->firmware_name;
/* request R-Car USB3.0 firmware */
- retval = request_firmware(&fw, priv->firmware_name, dev);
+ retval = request_firmware(&fw, firmware_name, dev);
if (retval)
return retval;
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index cc368ad..a944365 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1572,7 +1572,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
{
struct usb_hcd *hcd;
u32 port_id;
- u32 temp, temp1;
+ u32 portsc, cmd_reg;
int max_ports;
int slot_id;
unsigned int faked_port_index;
@@ -1636,26 +1636,28 @@ static void handle_port_status(struct xhci_hcd *xhci,
/* Find the faked port hub number */
faked_port_index = find_faked_portnum_from_hw_portnum(hcd, xhci,
port_id);
+ portsc = readl(port_array[faked_port_index]);
+
+ trace_xhci_handle_port_status(faked_port_index, portsc);
- temp = readl(port_array[faked_port_index]);
if (hcd->state == HC_STATE_SUSPENDED) {
xhci_dbg(xhci, "resume root hub\n");
usb_hcd_resume_root_hub(hcd);
}
- if (hcd->speed >= HCD_USB3 && (temp & PORT_PLS_MASK) == XDEV_INACTIVE)
+ if (hcd->speed >= HCD_USB3 && (portsc & PORT_PLS_MASK) == XDEV_INACTIVE)
bus_state->port_remote_wakeup &= ~(1 << faked_port_index);
- if ((temp & PORT_PLC) && (temp & PORT_PLS_MASK) == XDEV_RESUME) {
+ if ((portsc & PORT_PLC) && (portsc & PORT_PLS_MASK) == XDEV_RESUME) {
xhci_dbg(xhci, "port resume event for port %d\n", port_id);
- temp1 = readl(&xhci->op_regs->command);
- if (!(temp1 & CMD_RUN)) {
+ cmd_reg = readl(&xhci->op_regs->command);
+ if (!(cmd_reg & CMD_RUN)) {
xhci_warn(xhci, "xHC is not running.\n");
goto cleanup;
}
- if (DEV_SUPERSPEED_ANY(temp)) {
+ if (DEV_SUPERSPEED_ANY(portsc)) {
xhci_dbg(xhci, "remote wake SS port %d\n", port_id);
/* Set a flag to say the port signaled remote wakeup,
* so we can tell the difference between the end of
@@ -1683,8 +1685,8 @@ static void handle_port_status(struct xhci_hcd *xhci,
}
}
- if ((temp & PORT_PLC) && (temp & PORT_PLS_MASK) == XDEV_U0 &&
- DEV_SUPERSPEED_ANY(temp)) {
+ if ((portsc & PORT_PLC) && (portsc & PORT_PLS_MASK) == XDEV_U0 &&
+ DEV_SUPERSPEED_ANY(portsc)) {
xhci_dbg(xhci, "resume SS port %d finished\n", port_id);
/* We've just brought the device into U0 through either the
* Resume state after a device remote wakeup, or through the
@@ -1714,7 +1716,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
* RExit to a disconnect state). If so, let the the driver know it's
* out of the RExit state.
*/
- if (!DEV_SUPERSPEED_ANY(temp) &&
+ if (!DEV_SUPERSPEED_ANY(portsc) &&
test_and_clear_bit(faked_port_index,
&bus_state->rexit_ports)) {
complete(&bus_state->rexit_done[faked_port_index]);
diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h
index 8ce96de..f20753b 100644
--- a/drivers/usb/host/xhci-trace.h
+++ b/drivers/usb/host/xhci-trace.h
@@ -453,6 +453,29 @@ DEFINE_EVENT(xhci_log_ring, xhci_inc_deq,
TP_PROTO(struct xhci_ring *ring),
TP_ARGS(ring)
);
+
+DECLARE_EVENT_CLASS(xhci_log_portsc,
+ TP_PROTO(u32 portnum, u32 portsc),
+ TP_ARGS(portnum, portsc),
+ TP_STRUCT__entry(
+ __field(u32, portnum)
+ __field(u32, portsc)
+ ),
+ TP_fast_assign(
+ __entry->portnum = portnum;
+ __entry->portsc = portsc;
+ ),
+ TP_printk("port-%d: %s",
+ __entry->portnum,
+ xhci_decode_portsc(__entry->portsc)
+ )
+);
+
+DEFINE_EVENT(xhci_log_portsc, xhci_handle_port_status,
+ TP_PROTO(u32 portnum, u32 portsc),
+ TP_ARGS(portnum, portsc)
+);
+
#endif /* __XHCI_TRACE_H */
/* this part must be outside header guard */
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index e3e9352..2abaa4d 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -311,12 +311,19 @@ struct xhci_op_regs {
*/
#define PORT_PLS_MASK (0xf << 5)
#define XDEV_U0 (0x0 << 5)
+#define XDEV_U1 (0x1 << 5)
#define XDEV_U2 (0x2 << 5)
#define XDEV_U3 (0x3 << 5)
+#define XDEV_DISABLED (0x4 << 5)
+#define XDEV_RXDETECT (0x5 << 5)
#define XDEV_INACTIVE (0x6 << 5)
#define XDEV_POLLING (0x7 << 5)
-#define XDEV_COMP_MODE (0xa << 5)
+#define XDEV_RECOVERY (0x8 << 5)
+#define XDEV_HOT_RESET (0x9 << 5)
+#define XDEV_COMP_MODE (0xa << 5)
+#define XDEV_TEST_MODE (0xb << 5)
#define XDEV_RESUME (0xf << 5)
+
/* true: port has power (see HCC_PPC) */
#define PORT_POWER (1 << 9)
/* bits 10:13 indicate device speed:
@@ -2392,6 +2399,87 @@ static inline const char *xhci_decode_slot_context(u32 info, u32 info2,
return str;
}
+
+static inline const char *xhci_portsc_link_state_string(u32 portsc)
+{
+ switch (portsc & PORT_PLS_MASK) {
+ case XDEV_U0:
+ return "U0";
+ case XDEV_U1:
+ return "U1";
+ case XDEV_U2:
+ return "U2";
+ case XDEV_U3:
+ return "U3";
+ case XDEV_DISABLED:
+ return "Disabled";
+ case XDEV_RXDETECT:
+ return "RxDetect";
+ case XDEV_INACTIVE:
+ return "Inactive";
+ case XDEV_POLLING:
+ return "Polling";
+ case XDEV_RECOVERY:
+ return "Recovery";
+ case XDEV_HOT_RESET:
+ return "Hot Reset";
+ case XDEV_COMP_MODE:
+ return "Compliance mode";
+ case XDEV_TEST_MODE:
+ return "Test mode";
+ case XDEV_RESUME:
+ return "Resume";
+ default:
+ break;
+ }
+ return "Unknown";
+}
+
+static inline const char *xhci_decode_portsc(u32 portsc)
+{
+ static char str[256];
+ int ret;
+
+ ret = sprintf(str, "%s %s %s Link:%s ",
+ portsc & PORT_POWER ? "Powered" : "Powered-off",
+ portsc & PORT_CONNECT ? "Connected" : "Not-connected",
+ portsc & PORT_PE ? "Enabled" : "Disabled",
+ xhci_portsc_link_state_string(portsc));
+
+ if (portsc & PORT_OC)
+ ret += sprintf(str + ret, "OverCurrent ");
+ if (portsc & PORT_RESET)
+ ret += sprintf(str + ret, "In-Reset ");
+
+ ret += sprintf(str + ret, "Change: ");
+ if (portsc & PORT_CSC)
+ ret += sprintf(str + ret, "CSC ");
+ if (portsc & PORT_PEC)
+ ret += sprintf(str + ret, "PEC ");
+ if (portsc & PORT_WRC)
+ ret += sprintf(str + ret, "WRC ");
+ if (portsc & PORT_OCC)
+ ret += sprintf(str + ret, "OCC ");
+ if (portsc & PORT_RC)
+ ret += sprintf(str + ret, "PRC ");
+ if (portsc & PORT_PLC)
+ ret += sprintf(str + ret, "PLC ");
+ if (portsc & PORT_CEC)
+ ret += sprintf(str + ret, "CEC ");
+ if (portsc & PORT_CAS)
+ ret += sprintf(str + ret, "CAS ");
+
+ ret += sprintf(str + ret, "Wake: ");
+ if (portsc & PORT_WKCONN_E)
+ ret += sprintf(str + ret, "WCE ");
+ if (portsc & PORT_WKDISC_E)
+ ret += sprintf(str + ret, "WDE ");
+ if (portsc & PORT_WKOC_E)
+ ret += sprintf(str + ret, "WOE ");
+
+ return str;
+}
+
static inline const char *xhci_ep_state_string(u8 state)
{
switch (state) {
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
index a4dbb0c..0b21ba7 100644
--- a/drivers/usb/image/microtek.c
+++ b/drivers/usb/image/microtek.c
@@ -137,10 +137,6 @@
#include "microtek.h"
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v0.4.3"
#define DRIVER_AUTHOR "John Fremlin <vii@penguinpowered.com>, Oliver Neukum <Oliver.Neukum@lrz.uni-muenchen.de>"
#define DRIVER_DESC "Microtek Scanmaker X6 USB scanner driver"
diff --git a/drivers/usb/isp1760/isp1760-hcd.c b/drivers/usb/isp1760/isp1760-hcd.c
index ac31d19..8e59e0c 100644
--- a/drivers/usb/isp1760/isp1760-hcd.c
+++ b/drivers/usb/isp1760/isp1760-hcd.c
@@ -396,7 +396,6 @@ static int handshake(struct usb_hcd *hcd, u32 reg,
/* reset a non-running (STS_HALT == 1) controller */
static int ehci_reset(struct usb_hcd *hcd)
{
- int retval;
struct isp1760_hcd *priv = hcd_to_priv(hcd);
u32 command = reg_read32(hcd->regs, HC_USBCMD);
@@ -405,9 +404,8 @@ static int ehci_reset(struct usb_hcd *hcd)
reg_write32(hcd->regs, HC_USBCMD, command);
hcd->state = HC_STATE_HALT;
priv->next_statechange = jiffies;
- retval = handshake(hcd, HC_USBCMD,
- CMD_RESET, 0, 250 * 1000);
- return retval;
+
+ return handshake(hcd, HC_USBCMD, CMD_RESET, 0, 250 * 1000);
}
static struct isp1760_qh *qh_alloc(gfp_t flags)
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c
index dfd54ea..1c0ada7 100644
--- a/drivers/usb/misc/adutux.c
+++ b/drivers/usb/misc/adutux.c
@@ -29,8 +29,6 @@
#include <linux/mutex.h>
#include <linux/uaccess.h>
-/* Version Information */
-#define DRIVER_VERSION "v0.0.13"
#define DRIVER_AUTHOR "John Homppi"
#define DRIVER_DESC "adutux (see www.ontrak.net)"
diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c
index 15d4e64..abec6e6 100644
--- a/drivers/usb/misc/chaoskey.c
+++ b/drivers/usb/misc/chaoskey.c
@@ -42,12 +42,10 @@ static int chaoskey_rng_read(struct hwrng *rng, void *data,
dev_err(&(usb_if)->dev, format, ## arg)
/* Version Information */
-#define DRIVER_VERSION "v0.1"
#define DRIVER_AUTHOR "Keith Packard, keithp@keithp.com"
#define DRIVER_DESC "Altus Metrum ChaosKey driver"
#define DRIVER_SHORT "chaoskey"
-MODULE_VERSION(DRIVER_VERSION);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
diff --git a/drivers/usb/misc/cytherm.c b/drivers/usb/misc/cytherm.c
index 9d8bb8d..63207c4 100644
--- a/drivers/usb/misc/cytherm.c
+++ b/drivers/usb/misc/cytherm.c
@@ -20,7 +20,6 @@
#include <linux/module.h>
#include <linux/usb.h>
-#define DRIVER_VERSION "v1.0"
#define DRIVER_AUTHOR "Erik Rigtorp"
#define DRIVER_DESC "Cypress USB Thermometer driver"
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c
index 8291499..424ff12 100644
--- a/drivers/usb/misc/ftdi-elan.c
+++ b/drivers/usb/misc/ftdi-elan.c
@@ -305,9 +305,9 @@ static int ftdi_elan_command_engine(struct usb_ftdi *ftdi);
static int ftdi_elan_respond_engine(struct usb_ftdi *ftdi);
static int ftdi_elan_hcd_init(struct usb_ftdi *ftdi)
{
- int result;
if (ftdi->platform_dev.dev.parent)
return -EBUSY;
+
ftdi_elan_get_kref(ftdi);
ftdi->platform_data.potpg = 100;
ftdi->platform_data.reset = NULL;
@@ -324,8 +324,8 @@ static int ftdi_elan_hcd_init(struct usb_ftdi *ftdi)
request_module("u132_hcd");
dev_info(&ftdi->udev->dev, "registering '%s'\n",
ftdi->platform_dev.name);
- result = platform_device_register(&ftdi->platform_dev);
- return result;
+
+ return platform_device_register(&ftdi->platform_dev);
}
static void ftdi_elan_abandon_completions(struct usb_ftdi *ftdi)
@@ -857,7 +857,7 @@ static char *have_ed_set_response(struct usb_ftdi *ftdi,
target->actual = 0;
target->non_null = (ed_length >> 15) & 0x0001;
target->repeat_number = (ed_length >> 11) & 0x000F;
- if (ed_type == 0x02) {
+ if (ed_type == 0x02 || ed_type == 0x03) {
if (payload == 0 || target->abandoning > 0) {
target->abandoning = 0;
mutex_unlock(&ftdi->u132_lock);
@@ -873,31 +873,6 @@ static char *have_ed_set_response(struct usb_ftdi *ftdi,
mutex_unlock(&ftdi->u132_lock);
return b;
}
- } else if (ed_type == 0x03) {
- if (payload == 0 || target->abandoning > 0) {
- target->abandoning = 0;
- mutex_unlock(&ftdi->u132_lock);
- ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response,
- payload);
- ftdi->received = 0;
- ftdi->expected = 4;
- ftdi->ed_found = 0;
- return ftdi->response;
- } else {
- ftdi->expected = 4 + payload;
- ftdi->ed_found = 1;
- mutex_unlock(&ftdi->u132_lock);
- return b;
- }
- } else if (ed_type == 0x01) {
- target->abandoning = 0;
- mutex_unlock(&ftdi->u132_lock);
- ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response,
- payload);
- ftdi->received = 0;
- ftdi->expected = 4;
- ftdi->ed_found = 0;
- return ftdi->response;
} else {
target->abandoning = 0;
mutex_unlock(&ftdi->u132_lock);
diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c
index 81fcbf0..39d8fed 100644
--- a/drivers/usb/misc/idmouse.c
+++ b/drivers/usb/misc/idmouse.c
@@ -33,8 +33,6 @@
#define HEADER "P5 225 289 255 "
#define IMGSIZE ((WIDTH * HEIGHT) + sizeof(HEADER)-1)
-/* version information */
-#define DRIVER_VERSION "0.6"
#define DRIVER_SHORT "idmouse"
#define DRIVER_AUTHOR "Florian 'Floe' Echtler <echtler@fs.tum.de>"
#define DRIVER_DESC "Siemens ID Mouse FingerTIP Sensor Driver"
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
index 7ca4c7e..be58813 100644
--- a/drivers/usb/misc/iowarrior.c
+++ b/drivers/usb/misc/iowarrior.c
@@ -21,10 +21,8 @@
#include <linux/poll.h>
#include <linux/usb/iowarrior.h>
-/* Version Information */
-#define DRIVER_VERSION "v0.4.0"
#define DRIVER_AUTHOR "Christian Lucht <lucht@codemercs.com>"
-#define DRIVER_DESC "USB IO-Warrior driver (Linux 2.6.x)"
+#define DRIVER_DESC "USB IO-Warrior driver"
#define USB_VENDOR_ID_CODEMERCS 1984
/* low speed iowarrior */
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c
index 9d9487c..680bddb 100644
--- a/drivers/usb/misc/ldusb.c
+++ b/drivers/usb/misc/ldusb.c
@@ -112,7 +112,6 @@ static const struct usb_device_id ld_usb_table[] = {
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, ld_usb_table);
-MODULE_VERSION("V0.14");
MODULE_AUTHOR("Michael Hund <mhund@ld-didactic.de>");
MODULE_DESCRIPTION("LD USB Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c
index 0782ac6..5628f67 100644
--- a/drivers/usb/misc/legousbtower.c
+++ b/drivers/usb/misc/legousbtower.c
@@ -88,8 +88,6 @@
#include <linux/poll.h>
-/* Version Information */
-#define DRIVER_VERSION "v0.96"
#define DRIVER_AUTHOR "Juergen Stuber <starblue@sourceforge.net>"
#define DRIVER_DESC "LEGO USB Tower Driver"
diff --git a/drivers/usb/misc/lvstest.c b/drivers/usb/misc/lvstest.c
index 2142132..ddddd63 100644
--- a/drivers/usb/misc/lvstest.c
+++ b/drivers/usb/misc/lvstest.c
@@ -178,6 +178,25 @@ static ssize_t hot_reset_store(struct device *dev,
}
static DEVICE_ATTR_WO(hot_reset);
+static ssize_t warm_reset_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct usb_interface *intf = to_usb_interface(dev);
+ struct usb_device *hdev = interface_to_usbdev(intf);
+ struct lvs_rh *lvs = usb_get_intfdata(intf);
+ int ret;
+
+ ret = lvs_rh_set_port_feature(hdev, lvs->portnum,
+ USB_PORT_FEAT_BH_PORT_RESET);
+ if (ret < 0) {
+ dev_err(dev, "can't issue warm reset %d\n", ret);
+ return ret;
+ }
+
+ return count;
+}
+static DEVICE_ATTR_WO(warm_reset);
+
static ssize_t u2_timeout_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
@@ -274,13 +293,35 @@ free_desc:
}
static DEVICE_ATTR_WO(get_dev_desc);
+static ssize_t enable_compliance_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct usb_interface *intf = to_usb_interface(dev);
+ struct usb_device *hdev = interface_to_usbdev(intf);
+ struct lvs_rh *lvs = usb_get_intfdata(intf);
+ int ret;
+
+ ret = lvs_rh_set_port_feature(hdev,
+ lvs->portnum | USB_SS_PORT_LS_COMP_MOD << 3,
+ USB_PORT_FEAT_LINK_STATE);
+ if (ret < 0) {
+ dev_err(dev, "can't enable compliance mode %d\n", ret);
+ return ret;
+ }
+
+ return count;
+}
+static DEVICE_ATTR_WO(enable_compliance);
+
static struct attribute *lvs_attributes[] = {
&dev_attr_get_dev_desc.attr,
&dev_attr_u1_timeout.attr,
&dev_attr_u2_timeout.attr,
&dev_attr_hot_reset.attr,
+ &dev_attr_warm_reset.attr,
&dev_attr_u3_entry.attr,
&dev_attr_u3_exit.attr,
+ &dev_attr_enable_compliance.attr,
NULL
};
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c
index b106ce7..ddfebb14 100644
--- a/drivers/usb/misc/rio500.c
+++ b/drivers/usb/misc/rio500.c
@@ -43,10 +43,6 @@
#include "rio500_usb.h"
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v1.1"
#define DRIVER_AUTHOR "Cesar Miquel <miquel@df.uba.ar>"
#define DRIVER_DESC "USB Rio 500 driver"
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c
index 440d7fe..30774e0 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.c
+++ b/drivers/usb/misc/sisusbvga/sisusb.c
@@ -610,13 +610,11 @@ static int sisusb_write_memio_byte(struct sisusb_usb_data *sisusb, int type,
u32 addr, u8 data)
{
struct sisusb_packet packet;
- int ret;
packet.header = (1 << (addr & 3)) | (type << 6);
packet.address = addr & ~3;
packet.data = data << ((addr & 3) << 3);
- ret = sisusb_send_packet(sisusb, 10, &packet);
- return ret;
+ return sisusb_send_packet(sisusb, 10, &packet);
}
static int sisusb_write_memio_word(struct sisusb_usb_data *sisusb, int type,
@@ -1333,13 +1331,11 @@ static int sisusb_write_pci_config(struct sisusb_usb_data *sisusb,
int regnum, u32 data)
{
struct sisusb_packet packet;
- int ret;
packet.header = 0x008f;
packet.address = regnum | 0x10000;
packet.data = data;
- ret = sisusb_send_packet(sisusb, 10, &packet);
- return ret;
+ return sisusb_send_packet(sisusb, 10, &packet);
}
static int sisusb_read_pci_config(struct sisusb_usb_data *sisusb,
@@ -2982,14 +2978,11 @@ err_out:
static long sisusb_compat_ioctl(struct file *f, unsigned int cmd,
unsigned long arg)
{
- long retval;
-
switch (cmd) {
case SISUSB_GET_CONFIG_SIZE:
case SISUSB_GET_CONFIG:
case SISUSB_COMMAND:
- retval = sisusb_ioctl(f, cmd, arg);
- return retval;
+ return sisusb_ioctl(f, cmd, arg);
default:
return -ENOIOCTLCMD;
diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c
index 9795457..1862ed1 100644
--- a/drivers/usb/misc/trancevibrator.c
+++ b/drivers/usb/misc/trancevibrator.c
@@ -25,8 +25,6 @@
#include <linux/module.h>
#include <linux/usb.h>
-/* Version Information */
-#define DRIVER_VERSION "v1.1"
#define DRIVER_AUTHOR "Sam Hocevar, sam@zoy.org"
#define DRIVER_DESC "PlayStation 2 Trance Vibrator driver"
diff --git a/drivers/usb/misc/usb251xb.c b/drivers/usb/misc/usb251xb.c
index 91f66d68..135c91c 100644
--- a/drivers/usb/misc/usb251xb.c
+++ b/drivers/usb/misc/usb251xb.c
@@ -114,7 +114,6 @@
#define DRIVER_NAME "usb251xb"
#define DRIVER_DESC "Microchip USB 2.0 Hi-Speed Hub Controller"
-#define DRIVER_VERSION "1.0"
struct usb251xb {
struct device *dev;
diff --git a/drivers/usb/misc/usbsevseg.c b/drivers/usb/misc/usbsevseg.c
index 388fae6..3f6a280 100644
--- a/drivers/usb/misc/usbsevseg.c
+++ b/drivers/usb/misc/usbsevseg.c
@@ -330,7 +330,7 @@ static struct attribute *dev_attrs[] = {
NULL
};
-static struct attribute_group dev_attr_grp = {
+static const struct attribute_group dev_attr_grp = {
.attrs = dev_attrs,
};
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c
index 5947373..8a13b2f 100644
--- a/drivers/usb/misc/uss720.c
+++ b/drivers/usb/misc/uss720.c
@@ -52,10 +52,6 @@
#include <linux/slab.h>
#include <linux/sched/signal.h>
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v0.6"
#define DRIVER_AUTHOR "Thomas M. Sailer, t.sailer@alumni.ethz.ch"
#define DRIVER_DESC "USB Parport Cable driver for Cables using the Lucent Technologies USS720 Chip"
@@ -816,8 +812,7 @@ static int __init uss720_init(void)
if (retval)
goto out;
- printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
- DRIVER_DESC "\n");
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n");
printk(KERN_INFO KBUILD_MODNAME ": NOTE: this is a special purpose "
"driver to allow nonstandard\n");
printk(KERN_INFO KBUILD_MODNAME ": protocols (eg. bitbang) over "
diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h
index 7b6dc23..b26fffc 100644
--- a/drivers/usb/mtu3/mtu3.h
+++ b/drivers/usb/mtu3/mtu3.h
@@ -288,6 +288,7 @@ static inline struct ssusb_mtk *dev_to_ssusb(struct device *dev)
* MTU3_U3_IP_SLOT_DEFAULT for U3 IP
* @may_wakeup: means device's remote wakeup is enabled
* @is_self_powered: is reported in device status and the config descriptor
+ * @delayed_status: true when function drivers ask for delayed status
* @ep0_req: dummy request used while handling standard USB requests
* for GET_STATUS and SET_SEL
* @setup_buf: ep0 response buffer for GET_STATUS and SET_SEL requests
@@ -327,6 +328,7 @@ struct mtu3 {
unsigned u1_enable:1;
unsigned u2_enable:1;
unsigned is_u3_ip:1;
+ unsigned delayed_status:1;
u8 address;
u8 test_mode_nr;
diff --git a/drivers/usb/mtu3/mtu3_dr.c b/drivers/usb/mtu3/mtu3_dr.c
index 11a0d3b..5602561 100644
--- a/drivers/usb/mtu3/mtu3_dr.c
+++ b/drivers/usb/mtu3/mtu3_dr.c
@@ -322,23 +322,65 @@ static const struct file_operations ssusb_mode_fops = {
.release = single_release,
};
+static int ssusb_vbus_show(struct seq_file *sf, void *unused)
+{
+ struct ssusb_mtk *ssusb = sf->private;
+ struct otg_switch_mtk *otg_sx = &ssusb->otg_switch;
+
+ seq_printf(sf, "vbus state: %s\n(echo on/off)\n",
+ regulator_is_enabled(otg_sx->vbus) ? "on" : "off");
+
+ return 0;
+}
+
+static int ssusb_vbus_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ssusb_vbus_show, inode->i_private);
+}
+
+static ssize_t ssusb_vbus_write(struct file *file,
+ const char __user *ubuf, size_t count, loff_t *ppos)
+{
+ struct seq_file *sf = file->private_data;
+ struct ssusb_mtk *ssusb = sf->private;
+ struct otg_switch_mtk *otg_sx = &ssusb->otg_switch;
+ char buf[16];
+ bool enable;
+
+ if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
+ return -EFAULT;
+
+ if (kstrtobool(buf, &enable)) {
+ dev_err(ssusb->dev, "wrong setting\n");
+ return -EINVAL;
+ }
+
+ ssusb_set_vbus(otg_sx, enable);
+
+ return count;
+}
+
+static const struct file_operations ssusb_vbus_fops = {
+ .open = ssusb_vbus_open,
+ .write = ssusb_vbus_write,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
static void ssusb_debugfs_init(struct ssusb_mtk *ssusb)
{
struct dentry *root;
- struct dentry *file;
root = debugfs_create_dir(dev_name(ssusb->dev), usb_debug_root);
- if (IS_ERR_OR_NULL(root)) {
- if (!root)
- dev_err(ssusb->dev, "create debugfs root failed\n");
+ if (!root) {
+ dev_err(ssusb->dev, "create debugfs root failed\n");
return;
}
ssusb->dbgfs_root = root;
- file = debugfs_create_file("mode", S_IRUGO | S_IWUSR, root,
- ssusb, &ssusb_mode_fops);
- if (!file)
- dev_dbg(ssusb->dev, "create debugfs mode failed\n");
+ debugfs_create_file("mode", 0644, root, ssusb, &ssusb_mode_fops);
+ debugfs_create_file("vbus", 0644, root, ssusb, &ssusb_vbus_fops);
}
static void ssusb_debugfs_exit(struct ssusb_mtk *ssusb)
diff --git a/drivers/usb/mtu3/mtu3_gadget.c b/drivers/usb/mtu3/mtu3_gadget.c
index 9dd2441..434fca5 100644
--- a/drivers/usb/mtu3/mtu3_gadget.c
+++ b/drivers/usb/mtu3/mtu3_gadget.c
@@ -663,6 +663,7 @@ int mtu3_gadget_setup(struct mtu3 *mtu)
mtu->g.sg_supported = 0;
mtu->g.name = MTU3_DRIVER_NAME;
mtu->is_active = 0;
+ mtu->delayed_status = false;
mtu3_gadget_init_eps(mtu);
@@ -727,4 +728,7 @@ void mtu3_gadget_reset(struct mtu3 *mtu)
mtu->address = 0;
mtu->ep0_state = MU3D_EP0_STATE_SETUP;
mtu->may_wakeup = 0;
+ mtu->u1_enable = 0;
+ mtu->u2_enable = 0;
+ mtu->delayed_status = false;
}
diff --git a/drivers/usb/mtu3/mtu3_gadget_ep0.c b/drivers/usb/mtu3/mtu3_gadget_ep0.c
index 2d7427b..958d74d 100644
--- a/drivers/usb/mtu3/mtu3_gadget_ep0.c
+++ b/drivers/usb/mtu3/mtu3_gadget_ep0.c
@@ -16,6 +16,8 @@
*
*/
+#include <linux/usb/composite.h>
+
#include "mtu3.h"
/* ep0 is always mtu3->in_eps[0] */
@@ -150,6 +152,7 @@ static void ep0_stall_set(struct mtu3_ep *mep0, bool set, u32 pktrdy)
csr = (csr & ~EP0_SENDSTALL) | EP0_SENTSTALL;
mtu3_writel(mtu->mac_base, U3D_EP0CSR, csr);
+ mtu->delayed_status = false;
mtu->ep0_state = MU3D_EP0_STATE_SETUP;
dev_dbg(mtu->dev, "ep0: %s STALL, ep0_state: %s\n",
@@ -656,6 +659,9 @@ stall:
finish:
if (mtu->test_mode) {
; /* nothing to do */
+ } else if (handled == USB_GADGET_DELAYED_STATUS) {
+ /* handle the delay STATUS phase till receive ep_queue on ep0 */
+ mtu->delayed_status = true;
} else if (le16_to_cpu(setup.wLength) == 0) { /* no data stage */
mtu3_writel(mbase, U3D_EP0CSR,
@@ -775,9 +781,6 @@ static int ep0_queue(struct mtu3_ep *mep, struct mtu3_request *mreq)
dev_dbg(mtu->dev, "%s %s (ep0_state: %s), len#%d\n", __func__,
mep->name, decode_ep0_state(mtu), mreq->request.length);
- if (!list_empty(&mep->req_list))
- return -EBUSY;
-
switch (mtu->ep0_state) {
case MU3D_EP0_STATE_SETUP:
case MU3D_EP0_STATE_RX: /* control-OUT data */
@@ -789,6 +792,20 @@ static int ep0_queue(struct mtu3_ep *mep, struct mtu3_request *mreq)
return -EINVAL;
}
+ if (mtu->delayed_status) {
+ u32 csr;
+
+ mtu->delayed_status = false;
+ csr = mtu3_readl(mtu->mac_base, U3D_EP0CSR) & EP0_W1C_BITS;
+ csr |= EP0_SETUPPKTRDY | EP0_DATAEND;
+ mtu3_writel(mtu->mac_base, U3D_EP0CSR, csr);
+ /* needn't giveback the request for handling delay STATUS */
+ return 0;
+ }
+
+ if (!list_empty(&mep->req_list))
+ return -EBUSY;
+
list_add_tail(&mreq->list, &mep->req_list);
/* sequence #1, IN ... start writing the data */
diff --git a/drivers/usb/mtu3/mtu3_host.c b/drivers/usb/mtu3/mtu3_host.c
index cd4d010..e42d308 100644
--- a/drivers/usb/mtu3/mtu3_host.c
+++ b/drivers/usb/mtu3/mtu3_host.c
@@ -258,8 +258,8 @@ int ssusb_host_init(struct ssusb_mtk *ssusb, struct device_node *parent_dn)
ret = of_platform_populate(parent_dn, NULL, NULL, parent_dev);
if (ret) {
- dev_dbg(parent_dev, "failed to create child devices at %s\n",
- parent_dn->full_name);
+ dev_dbg(parent_dev, "failed to create child devices at %pOF\n",
+ parent_dn);
return ret;
}
diff --git a/drivers/usb/mtu3/mtu3_hw_regs.h b/drivers/usb/mtu3/mtu3_hw_regs.h
index 2123672..06b2966 100644
--- a/drivers/usb/mtu3/mtu3_hw_regs.h
+++ b/drivers/usb/mtu3/mtu3_hw_regs.h
@@ -462,10 +462,12 @@
#define SSUSB_U3_PORT_DIS BIT(0)
/* U3D_SSUSB_U2_CTRL_0P */
+#define SSUSB_U2_PORT_VBUSVALID BIT(9)
#define SSUSB_U2_PORT_OTG_SEL BIT(7)
-#define SSUSB_U2_PORT_HOST_SEL BIT(2)
+#define SSUSB_U2_PORT_HOST BIT(2)
#define SSUSB_U2_PORT_PDN BIT(1)
#define SSUSB_U2_PORT_DIS BIT(0)
+#define SSUSB_U2_PORT_HOST_SEL (SSUSB_U2_PORT_VBUSVALID | SSUSB_U2_PORT_HOST)
/* U3D_SSUSB_DEV_RST_CTRL */
#define SSUSB_DEV_SW_RST BIT(0)
diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c
index 0d3ebb3..088e3e6 100644
--- a/drivers/usb/mtu3/mtu3_plat.c
+++ b/drivers/usb/mtu3/mtu3_plat.c
@@ -500,6 +500,7 @@ static const struct dev_pm_ops mtu3_pm_ops = {
static const struct of_device_id mtu3_of_match[] = {
{.compatible = "mediatek,mt8173-mtu3",},
+ {.compatible = "mediatek,mtu3",},
{},
};
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 87cbd56..0296920 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1156,8 +1156,8 @@ static struct musb_fifo_cfg mode_2_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, },
{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, },
{ .hw_ep_num = 2, .style = FIFO_RX, .maxpacket = 512, },
-{ .hw_ep_num = 3, .style = FIFO_RXTX, .maxpacket = 256, },
-{ .hw_ep_num = 4, .style = FIFO_RXTX, .maxpacket = 256, },
+{ .hw_ep_num = 3, .style = FIFO_RXTX, .maxpacket = 960, },
+{ .hw_ep_num = 4, .style = FIFO_RXTX, .maxpacket = 1024, },
};
/* mode 3 - fits in 4KB */
@@ -2671,6 +2671,13 @@ static int musb_suspend(struct device *dev)
{
struct musb *musb = dev_to_musb(dev);
unsigned long flags;
+ int ret;
+
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0) {
+ pm_runtime_put_noidle(dev);
+ return ret;
+ }
musb_platform_disable(musb);
musb_disable_interrupts(musb);
@@ -2721,14 +2728,6 @@ static int musb_resume(struct device *dev)
if ((devctl & mask) != (musb->context.devctl & mask))
musb->port1_status = 0;
- /*
- * The USB HUB code expects the device to be in RPM_ACTIVE once it came
- * out of suspend
- */
- pm_runtime_disable(dev);
- pm_runtime_set_active(dev);
- pm_runtime_enable(dev);
-
musb_start(musb);
spin_lock_irqsave(&musb->lock, flags);
@@ -2738,6 +2737,9 @@ static int musb_resume(struct device *dev)
error);
spin_unlock_irqrestore(&musb->lock, flags);
+ pm_runtime_mark_last_busy(dev);
+ pm_runtime_put_autosuspend(dev);
+
return 0;
}
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 9f22c5b..c748f4a 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -465,6 +465,30 @@ static inline struct musb *gadget_to_musb(struct usb_gadget *g)
return container_of(g, struct musb, g);
}
+static inline char *musb_ep_xfertype_string(u8 type)
+{
+ char *s;
+
+ switch (type) {
+ case USB_ENDPOINT_XFER_CONTROL:
+ s = "ctrl";
+ break;
+ case USB_ENDPOINT_XFER_ISOC:
+ s = "iso";
+ break;
+ case USB_ENDPOINT_XFER_BULK:
+ s = "bulk";
+ break;
+ case USB_ENDPOINT_XFER_INT:
+ s = "int";
+ break;
+ default:
+ s = "";
+ break;
+ }
+ return s;
+}
+
#ifdef CONFIG_BLACKFIN
static inline int musb_read_fifosize(struct musb *musb,
struct musb_hw_ep *hw_ep, u8 epnum)
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index bc6a9be..f6b5266 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -1015,13 +1015,20 @@ static int dsps_suspend(struct device *dev)
const struct dsps_musb_wrapper *wrp = glue->wrp;
struct musb *musb = platform_get_drvdata(glue->musb);
void __iomem *mbase;
-
- del_timer_sync(&glue->timer);
+ int ret;
if (!musb)
/* This can happen if the musb device is in -EPROBE_DEFER */
return 0;
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0) {
+ pm_runtime_put_noidle(dev);
+ return ret;
+ }
+
+ del_timer_sync(&glue->timer);
+
mbase = musb->ctrl_base;
glue->context.control = musb_readl(mbase, wrp->control);
glue->context.epintr = musb_readl(mbase, wrp->epintr_set);
@@ -1060,6 +1067,8 @@ static int dsps_resume(struct device *dev)
musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE)
dsps_mod_timer(glue, -1);
+ pm_runtime_put(dev);
+
return 0;
}
#endif
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 1acc486..bc6d171 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -1105,11 +1105,7 @@ static int musb_gadget_enable(struct usb_ep *ep,
pr_debug("%s periph: enabled %s for %s %s, %smaxpacket %d\n",
musb_driver_name, musb_ep->end_point.name,
- ({ char *s; switch (musb_ep->type) {
- case USB_ENDPOINT_XFER_BULK: s = "bulk"; break;
- case USB_ENDPOINT_XFER_INT: s = "int"; break;
- default: s = "iso"; break;
- } s; }),
+ musb_ep_xfertype_string(musb_ep->type),
musb_ep->is_in ? "IN" : "OUT",
musb_ep->dma ? "dma, " : "",
musb_ep->packet_sz);
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 3344ffd..b17450a 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -2152,6 +2152,10 @@ static int musb_schedule(
(USB_SPEED_HIGH == qh->dev->speed) ? 8 : 4;
goto success;
} else if (best_end < 0) {
+ dev_err(musb->controller,
+ "%s hwep alloc failed for %dx%d\n",
+ musb_ep_xfertype_string(qh->type),
+ qh->hb_mult, qh->maxpacket);
return -ENOSPC;
}
@@ -2244,6 +2248,10 @@ static int musb_urb_enqueue(
ok = (usb_pipein(urb->pipe) && musb->hb_iso_rx)
|| (usb_pipeout(urb->pipe) && musb->hb_iso_tx);
if (!ok) {
+ dev_err(musb->controller,
+ "high bandwidth %s (%dx%d) not supported\n",
+ musb_ep_xfertype_string(qh->type),
+ qh->hb_mult, qh->maxpacket & 0x7ff);
ret = -EMSGSIZE;
goto done;
}
diff --git a/drivers/usb/phy/phy-mv-usb.c b/drivers/usb/phy/phy-mv-usb.c
index 697a741..0e31569 100644
--- a/drivers/usb/phy/phy-mv-usb.c
+++ b/drivers/usb/phy/phy-mv-usb.c
@@ -29,10 +29,8 @@
#include "phy-mv-usb.h"
#define DRIVER_DESC "Marvell USB OTG transceiver driver"
-#define DRIVER_VERSION "Jan 20, 2010"
MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
static const char driver_name[] = "mv-otg";
@@ -650,7 +648,7 @@ static struct attribute *inputs_attrs[] = {
NULL,
};
-static struct attribute_group inputs_attr_group = {
+static const struct attribute_group inputs_attr_group = {
.name = "inputs",
.attrs = inputs_attrs,
};
diff --git a/drivers/usb/phy/phy-qcom-8x16-usb.c b/drivers/usb/phy/phy-qcom-8x16-usb.c
index b6a83a5..679afea 100644
--- a/drivers/usb/phy/phy-qcom-8x16-usb.c
+++ b/drivers/usb/phy/phy-qcom-8x16-usb.c
@@ -270,12 +270,9 @@ static int phy_8x16_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, qphy);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return -EINVAL;
-
- qphy->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
- if (!qphy->regs)
- return -ENOMEM;
+ qphy->regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(qphy->regs))
+ return PTR_ERR(qphy->regs);
phy = &qphy->phy;
phy->dev = &pdev->dev;
diff --git a/drivers/usb/phy/phy-tahvo.c b/drivers/usb/phy/phy-tahvo.c
index a31c868..8babd31 100644
--- a/drivers/usb/phy/phy-tahvo.c
+++ b/drivers/usb/phy/phy-tahvo.c
@@ -326,7 +326,7 @@ static struct attribute *tahvo_attributes[] = {
NULL
};
-static struct attribute_group tahvo_attr_group = {
+static const struct attribute_group tahvo_attr_group = {
.attrs = tahvo_attributes,
};
diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c
index 032f5af..89f4ac4 100644
--- a/drivers/usb/phy/phy.c
+++ b/drivers/usb/phy/phy.c
@@ -18,6 +18,18 @@
#include <linux/usb/phy.h>
+/* Default current range by charger type. */
+#define DEFAULT_SDP_CUR_MIN 2
+#define DEFAULT_SDP_CUR_MAX 500
+#define DEFAULT_SDP_CUR_MIN_SS 150
+#define DEFAULT_SDP_CUR_MAX_SS 900
+#define DEFAULT_DCP_CUR_MIN 500
+#define DEFAULT_DCP_CUR_MAX 5000
+#define DEFAULT_CDP_CUR_MIN 1500
+#define DEFAULT_CDP_CUR_MAX 5000
+#define DEFAULT_ACA_CUR_MIN 1500
+#define DEFAULT_ACA_CUR_MAX 5000
+
static LIST_HEAD(phy_list);
static LIST_HEAD(phy_bind_list);
static DEFINE_SPINLOCK(phy_lock);
@@ -77,6 +89,221 @@ static struct usb_phy *__of_usb_find_phy(struct device_node *node)
return ERR_PTR(-EPROBE_DEFER);
}
+static void usb_phy_set_default_current(struct usb_phy *usb_phy)
+{
+ usb_phy->chg_cur.sdp_min = DEFAULT_SDP_CUR_MIN;
+ usb_phy->chg_cur.sdp_max = DEFAULT_SDP_CUR_MAX;
+ usb_phy->chg_cur.dcp_min = DEFAULT_DCP_CUR_MIN;
+ usb_phy->chg_cur.dcp_max = DEFAULT_DCP_CUR_MAX;
+ usb_phy->chg_cur.cdp_min = DEFAULT_CDP_CUR_MIN;
+ usb_phy->chg_cur.cdp_max = DEFAULT_CDP_CUR_MAX;
+ usb_phy->chg_cur.aca_min = DEFAULT_ACA_CUR_MIN;
+ usb_phy->chg_cur.aca_max = DEFAULT_ACA_CUR_MAX;
+}
+
+/**
+ * usb_phy_notify_charger_work - notify the USB charger state
+ * @work - the charger work to notify the USB charger state
+ *
+ * This work can be issued when USB charger state has been changed or
+ * USB charger current has been changed, then we can notify the current
+ * what can be drawn to power user and the charger state to userspace.
+ *
+ * If we get the charger type from extcon subsystem, we can notify the
+ * charger state to power user automatically by usb_phy_get_charger_type()
+ * issuing from extcon subsystem.
+ *
+ * If we get the charger type from ->charger_detect() instead of extcon
+ * subsystem, the usb phy driver should issue usb_phy_set_charger_state()
+ * to set charger state when the charger state has been changed.
+ */
+static void usb_phy_notify_charger_work(struct work_struct *work)
+{
+ struct usb_phy *usb_phy = container_of(work, struct usb_phy, chg_work);
+ char uchger_state[50] = { 0 };
+ char *envp[] = { uchger_state, NULL };
+ unsigned int min, max;
+
+ switch (usb_phy->chg_state) {
+ case USB_CHARGER_PRESENT:
+ usb_phy_get_charger_current(usb_phy, &min, &max);
+
+ atomic_notifier_call_chain(&usb_phy->notifier, max, usb_phy);
+ snprintf(uchger_state, ARRAY_SIZE(uchger_state),
+ "USB_CHARGER_STATE=%s", "USB_CHARGER_PRESENT");
+ break;
+ case USB_CHARGER_ABSENT:
+ usb_phy_set_default_current(usb_phy);
+
+ atomic_notifier_call_chain(&usb_phy->notifier, 0, usb_phy);
+ snprintf(uchger_state, ARRAY_SIZE(uchger_state),
+ "USB_CHARGER_STATE=%s", "USB_CHARGER_ABSENT");
+ break;
+ default:
+ dev_warn(usb_phy->dev, "Unknown USB charger state: %d\n",
+ usb_phy->chg_state);
+ return;
+ }
+
+ kobject_uevent_env(&usb_phy->dev->kobj, KOBJ_CHANGE, envp);
+}
+
+static void __usb_phy_get_charger_type(struct usb_phy *usb_phy)
+{
+ if (extcon_get_state(usb_phy->edev, EXTCON_CHG_USB_SDP) > 0) {
+ usb_phy->chg_type = SDP_TYPE;
+ usb_phy->chg_state = USB_CHARGER_PRESENT;
+ } else if (extcon_get_state(usb_phy->edev, EXTCON_CHG_USB_CDP) > 0) {
+ usb_phy->chg_type = CDP_TYPE;
+ usb_phy->chg_state = USB_CHARGER_PRESENT;
+ } else if (extcon_get_state(usb_phy->edev, EXTCON_CHG_USB_DCP) > 0) {
+ usb_phy->chg_type = DCP_TYPE;
+ usb_phy->chg_state = USB_CHARGER_PRESENT;
+ } else if (extcon_get_state(usb_phy->edev, EXTCON_CHG_USB_ACA) > 0) {
+ usb_phy->chg_type = ACA_TYPE;
+ usb_phy->chg_state = USB_CHARGER_PRESENT;
+ } else {
+ usb_phy->chg_type = UNKNOWN_TYPE;
+ usb_phy->chg_state = USB_CHARGER_ABSENT;
+ }
+
+ schedule_work(&usb_phy->chg_work);
+}
+
+/**
+ * usb_phy_get_charger_type - get charger type from extcon subsystem
+ * @nb -the notifier block to determine charger type
+ * @state - the cable state
+ * @data - private data
+ *
+ * Determin the charger type from extcon subsystem which also means the
+ * charger state has been chaned, then we should notify this event.
+ */
+static int usb_phy_get_charger_type(struct notifier_block *nb,
+ unsigned long state, void *data)
+{
+ struct usb_phy *usb_phy = container_of(nb, struct usb_phy, type_nb);
+
+ __usb_phy_get_charger_type(usb_phy);
+ return NOTIFY_OK;
+}
+
+/**
+ * usb_phy_set_charger_current - set the USB charger current
+ * @usb_phy - the USB phy to be used
+ * @mA - the current need to be set
+ *
+ * Usually we only change the charger default current when USB finished the
+ * enumeration as one SDP charger. As one SDP charger, usb_phy_set_power()
+ * will issue this function to change charger current when after setting USB
+ * configuration, or suspend/resume USB. For other type charger, we should
+ * use the default charger current and we do not suggest to issue this function
+ * to change the charger current.
+ *
+ * When USB charger current has been changed, we need to notify the power users.
+ */
+void usb_phy_set_charger_current(struct usb_phy *usb_phy, unsigned int mA)
+{
+ switch (usb_phy->chg_type) {
+ case SDP_TYPE:
+ if (usb_phy->chg_cur.sdp_max == mA)
+ return;
+
+ usb_phy->chg_cur.sdp_max = (mA > DEFAULT_SDP_CUR_MAX_SS) ?
+ DEFAULT_SDP_CUR_MAX_SS : mA;
+ break;
+ case DCP_TYPE:
+ if (usb_phy->chg_cur.dcp_max == mA)
+ return;
+
+ usb_phy->chg_cur.dcp_max = (mA > DEFAULT_DCP_CUR_MAX) ?
+ DEFAULT_DCP_CUR_MAX : mA;
+ break;
+ case CDP_TYPE:
+ if (usb_phy->chg_cur.cdp_max == mA)
+ return;
+
+ usb_phy->chg_cur.cdp_max = (mA > DEFAULT_CDP_CUR_MAX) ?
+ DEFAULT_CDP_CUR_MAX : mA;
+ break;
+ case ACA_TYPE:
+ if (usb_phy->chg_cur.aca_max == mA)
+ return;
+
+ usb_phy->chg_cur.aca_max = (mA > DEFAULT_ACA_CUR_MAX) ?
+ DEFAULT_ACA_CUR_MAX : mA;
+ break;
+ default:
+ return;
+ }
+
+ schedule_work(&usb_phy->chg_work);
+}
+EXPORT_SYMBOL_GPL(usb_phy_set_charger_current);
+
+/**
+ * usb_phy_get_charger_current - get the USB charger current
+ * @usb_phy - the USB phy to be used
+ * @min - the minimum current
+ * @max - the maximum current
+ *
+ * Usually we will notify the maximum current to power user, but for some
+ * special case, power user also need the minimum current value. Then the
+ * power user can issue this function to get the suitable current.
+ */
+void usb_phy_get_charger_current(struct usb_phy *usb_phy,
+ unsigned int *min, unsigned int *max)
+{
+ switch (usb_phy->chg_type) {
+ case SDP_TYPE:
+ *min = usb_phy->chg_cur.sdp_min;
+ *max = usb_phy->chg_cur.sdp_max;
+ break;
+ case DCP_TYPE:
+ *min = usb_phy->chg_cur.dcp_min;
+ *max = usb_phy->chg_cur.dcp_max;
+ break;
+ case CDP_TYPE:
+ *min = usb_phy->chg_cur.cdp_min;
+ *max = usb_phy->chg_cur.cdp_max;
+ break;
+ case ACA_TYPE:
+ *min = usb_phy->chg_cur.aca_min;
+ *max = usb_phy->chg_cur.aca_max;
+ break;
+ default:
+ *min = 0;
+ *max = 0;
+ break;
+ }
+}
+EXPORT_SYMBOL_GPL(usb_phy_get_charger_current);
+
+/**
+ * usb_phy_set_charger_state - set the USB charger state
+ * @usb_phy - the USB phy to be used
+ * @state - the new state need to be set for charger
+ *
+ * The usb phy driver can issue this function when the usb phy driver
+ * detected the charger state has been changed, in this case the charger
+ * type should be get from ->charger_detect().
+ */
+void usb_phy_set_charger_state(struct usb_phy *usb_phy,
+ enum usb_charger_state state)
+{
+ if (usb_phy->chg_state == state || !usb_phy->charger_detect)
+ return;
+
+ usb_phy->chg_state = state;
+ if (usb_phy->chg_state == USB_CHARGER_PRESENT)
+ usb_phy->chg_type = usb_phy->charger_detect(usb_phy);
+ else
+ usb_phy->chg_type = UNKNOWN_TYPE;
+
+ schedule_work(&usb_phy->chg_work);
+}
+EXPORT_SYMBOL_GPL(usb_phy_set_charger_state);
+
static void devm_usb_phy_release(struct device *dev, void *res)
{
struct usb_phy *phy = *(struct usb_phy **)res;
@@ -124,6 +351,44 @@ static int usb_add_extcon(struct usb_phy *x)
"register VBUS notifier failed\n");
return ret;
}
+ } else {
+ x->type_nb.notifier_call = usb_phy_get_charger_type;
+
+ ret = devm_extcon_register_notifier(x->dev, x->edev,
+ EXTCON_CHG_USB_SDP,
+ &x->type_nb);
+ if (ret) {
+ dev_err(x->dev,
+ "register extcon USB SDP failed.\n");
+ return ret;
+ }
+
+ ret = devm_extcon_register_notifier(x->dev, x->edev,
+ EXTCON_CHG_USB_CDP,
+ &x->type_nb);
+ if (ret) {
+ dev_err(x->dev,
+ "register extcon USB CDP failed.\n");
+ return ret;
+ }
+
+ ret = devm_extcon_register_notifier(x->dev, x->edev,
+ EXTCON_CHG_USB_DCP,
+ &x->type_nb);
+ if (ret) {
+ dev_err(x->dev,
+ "register extcon USB DCP failed.\n");
+ return ret;
+ }
+
+ ret = devm_extcon_register_notifier(x->dev, x->edev,
+ EXTCON_CHG_USB_ACA,
+ &x->type_nb);
+ if (ret) {
+ dev_err(x->dev,
+ "register extcon USB ACA failed.\n");
+ return ret;
+ }
}
if (x->id_nb.notifier_call) {
@@ -145,6 +410,13 @@ static int usb_add_extcon(struct usb_phy *x)
}
}
+ usb_phy_set_default_current(x);
+ INIT_WORK(&x->chg_work, usb_phy_notify_charger_work);
+ x->chg_type = UNKNOWN_TYPE;
+ x->chg_state = USB_CHARGER_DEFAULT;
+ if (x->type_nb.notifier_call)
+ __usb_phy_get_charger_type(x);
+
return 0;
}
@@ -302,8 +574,8 @@ struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev,
node = of_parse_phandle(dev->of_node, phandle, index);
if (!node) {
- dev_dbg(dev, "failed to get %s phandle in %s node\n", phandle,
- dev->of_node->full_name);
+ dev_dbg(dev, "failed to get %s phandle in %pOF node\n", phandle,
+ dev->of_node);
return ERR_PTR(-ENODEV);
}
phy = devm_usb_get_phy_by_node(dev, node, NULL);
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c
index 2c8161b..c068b67 100644
--- a/drivers/usb/renesas_usbhs/mod_gadget.c
+++ b/drivers/usb/renesas_usbhs/mod_gadget.c
@@ -764,7 +764,7 @@ static int usbhsg_ep_set_wedge(struct usb_ep *ep)
return __usbhsg_ep_set_halt_wedge(ep, 1, 1);
}
-static struct usb_ep_ops usbhsg_ep_ops = {
+static const struct usb_ep_ops usbhsg_ep_ops = {
.enable = usbhsg_ep_enable,
.disable = usbhsg_ep_disable,
@@ -1082,7 +1082,6 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv)
ret = -ENOMEM;
goto usbhs_mod_gadget_probe_err_gpriv;
}
- spin_lock_init(&uep->lock);
gpriv->transceiver = usb_get_phy(USB_PHY_TYPE_UNDEFINED);
dev_info(dev, "%stransceiver found\n",
@@ -1132,6 +1131,7 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv)
uep->ep.name = uep->ep_name;
uep->ep.ops = &usbhsg_ep_ops;
INIT_LIST_HEAD(&uep->ep.ep_list);
+ spin_lock_init(&uep->lock);
/* init DCP */
if (usbhsg_is_dcp(uep)) {
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c
index dfb346e..e256351 100644
--- a/drivers/usb/renesas_usbhs/mod_host.c
+++ b/drivers/usb/renesas_usbhs/mod_host.c
@@ -1285,7 +1285,7 @@ static int usbhsh_bus_nop(struct usb_hcd *hcd)
return 0;
}
-static struct hc_driver usbhsh_driver = {
+static const struct hc_driver usbhsh_driver = {
.description = usbhsh_hcd_name,
.hcd_priv_size = sizeof(struct usbhsh_hpriv),
diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c
index 9396a8c..d811f05 100644
--- a/drivers/usb/renesas_usbhs/pipe.c
+++ b/drivers/usb/renesas_usbhs/pipe.c
@@ -401,7 +401,7 @@ static int usbhsp_setup_pipecfg(struct usbhs_pipe *pipe, int is_host,
u16 dir = 0;
u16 epnum = 0;
u16 shtnak = 0;
- u16 type_array[] = {
+ static const u16 type_array[] = {
[USB_ENDPOINT_XFER_BULK] = TYPE_BULK,
[USB_ENDPOINT_XFER_INT] = TYPE_INT,
[USB_ENDPOINT_XFER_ISOC] = TYPE_ISO,
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index fe12315..54bfef1 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -2016,13 +2016,11 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(TPLINK_VENDOR_ID, 0x9000), /* TP-Link MA260 */
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
{ USB_DEVICE(CHANGHONG_VENDOR_ID, CHANGHONG_PRODUCT_CH690) },
- { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d01, 0xff, 0x02, 0x01) }, /* D-Link DWM-156 (variant) */
- { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d01, 0xff, 0x00, 0x00) }, /* D-Link DWM-156 (variant) */
- { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d02, 0xff, 0x02, 0x01) },
- { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d02, 0xff, 0x00, 0x00) },
- { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x02, 0x01) },
- { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) },
+ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d01, 0xff) }, /* D-Link DWM-156 (variant) */
+ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d02, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d03, 0xff) },
{ USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d04, 0xff) }, /* D-Link DWM-158 */
+ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d0e, 0xff) }, /* D-Link DWM-157 C1 */
{ USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e19, 0xff), /* D-Link DWM-221 B1 */
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
{ USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e35, 0xff), /* D-Link DWM-222 */
diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c
index 4176d1a..ec83b3b 100644
--- a/drivers/usb/storage/realtek_cr.c
+++ b/drivers/usb/storage/realtek_cr.c
@@ -47,7 +47,6 @@
MODULE_DESCRIPTION("Driver for Realtek USB Card Reader");
MODULE_AUTHOR("wwang <wei_wang@realsil.com.cn>");
MODULE_LICENSE("GPL");
-MODULE_VERSION("1.03");
static int auto_delink_en = 1;
module_param(auto_delink_en, int, S_IRUGO | S_IWUSR);
diff --git a/drivers/usb/usbip/stub_main.c b/drivers/usb/usbip/stub_main.c
index 660180a..7170404 100644
--- a/drivers/usb/usbip/stub_main.c
+++ b/drivers/usb/usbip/stub_main.c
@@ -302,7 +302,6 @@ static int __init usbip_host_init(void)
goto err_create_file;
}
- pr_info(DRIVER_DESC " v" USBIP_VERSION "\n");
return ret;
err_create_file:
@@ -335,4 +334,3 @@ module_exit(usbip_host_exit);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
-MODULE_VERSION(USBIP_VERSION);
diff --git a/drivers/usb/usbip/usbip_common.c b/drivers/usb/usbip/usbip_common.c
index cab2b71..2281f35 100644
--- a/drivers/usb/usbip/usbip_common.c
+++ b/drivers/usb/usbip/usbip_common.c
@@ -763,7 +763,6 @@ static int __init usbip_core_init(void)
{
int ret;
- pr_info(DRIVER_DESC " v" USBIP_VERSION "\n");
ret = usbip_init_eh();
if (ret)
return ret;
@@ -783,4 +782,3 @@ module_exit(usbip_core_exit);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
-MODULE_VERSION(USBIP_VERSION);
diff --git a/drivers/usb/usbip/usbip_common.h b/drivers/usb/usbip/usbip_common.h
index f8573a5..3050fc9 100644
--- a/drivers/usb/usbip/usbip_common.h
+++ b/drivers/usb/usbip/usbip_common.h
@@ -34,8 +34,6 @@
#include <linux/sched/task.h>
#include <uapi/linux/usbip.h>
-#define USBIP_VERSION "1.0.0"
-
#undef pr_fmt
#ifdef DEBUG
diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c
index 2c4b2fd..11b9a22 100644
--- a/drivers/usb/usbip/vhci_hcd.c
+++ b/drivers/usb/usbip/vhci_hcd.c
@@ -1274,7 +1274,7 @@ static int vhci_free_streams(struct usb_hcd *hcd, struct usb_device *udev,
return 0;
}
-static struct hc_driver vhci_hc_driver = {
+static const struct hc_driver vhci_hc_driver = {
.description = driver_name,
.product_desc = driver_desc,
.hcd_priv_size = sizeof(struct vhci_hcd),
@@ -1516,7 +1516,6 @@ static int __init vhci_hcd_init(void)
}
}
- pr_info(DRIVER_DESC " v" USBIP_VERSION "\n");
return ret;
err_add_hcd:
@@ -1542,4 +1541,3 @@ module_exit(vhci_hcd_exit);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
-MODULE_VERSION(USBIP_VERSION);
diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c
index 5778b64..1b9f60a 100644
--- a/drivers/usb/usbip/vhci_sysfs.c
+++ b/drivers/usb/usbip/vhci_sysfs.c
@@ -366,7 +366,11 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr,
sockfd_put(socket);
dev_err(dev, "port %d already used\n", rhport);
- return -EINVAL;
+ /*
+ * Will be retried from userspace
+ * if there's another free port.
+ */
+ return -EBUSY;
}
dev_info(dev, "pdev(%u) rhport(%u) sockfd(%d)\n",
diff --git a/drivers/usb/wusbcore/cbaf.c b/drivers/usb/wusbcore/cbaf.c
index fb70cbef..aa4e440 100644
--- a/drivers/usb/wusbcore/cbaf.c
+++ b/drivers/usb/wusbcore/cbaf.c
@@ -586,7 +586,7 @@ static struct attribute *cbaf_dev_attrs[] = {
NULL,
};
-static struct attribute_group cbaf_dev_attr_group = {
+static const struct attribute_group cbaf_dev_attr_group = {
.name = NULL, /* we want them in the same directory */
.attrs = cbaf_dev_attrs,
};
diff --git a/drivers/usb/wusbcore/dev-sysfs.c b/drivers/usb/wusbcore/dev-sysfs.c
index d4de56b..78212f8 100644
--- a/drivers/usb/wusbcore/dev-sysfs.c
+++ b/drivers/usb/wusbcore/dev-sysfs.c
@@ -114,7 +114,7 @@ static struct attribute *wusb_dev_attrs[] = {
NULL,
};
-static struct attribute_group wusb_dev_attr_group = {
+static const struct attribute_group wusb_dev_attr_group = {
.name = NULL, /* we want them in the same directory */
.attrs = wusb_dev_attrs,
};
diff --git a/drivers/usb/wusbcore/wusbhc.c b/drivers/usb/wusbcore/wusbhc.c
index a273a91..5338e42 100644
--- a/drivers/usb/wusbcore/wusbhc.c
+++ b/drivers/usb/wusbcore/wusbhc.c
@@ -244,7 +244,7 @@ static struct attribute *wusbhc_attrs[] = {
NULL,
};
-static struct attribute_group wusbhc_attr_group = {
+static const struct attribute_group wusbhc_attr_group = {
.name = NULL, /* we want them in the same directory */
.attrs = wusbhc_attrs,
};
diff --git a/drivers/uwb/lc-rc.c b/drivers/uwb/lc-rc.c
index 97ee1b4..b0816c7 100644
--- a/drivers/uwb/lc-rc.c
+++ b/drivers/uwb/lc-rc.c
@@ -228,7 +228,7 @@ static struct attribute *rc_attrs[] = {
NULL,
};
-static struct attribute_group rc_attr_group = {
+static const struct attribute_group rc_attr_group = {
.attrs = rc_attrs,
};
diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c
index 7da1ad0..d1d3796 100644
--- a/drivers/video/console/sticore.c
+++ b/drivers/video/console/sticore.c
@@ -281,7 +281,7 @@ static void sti_rom_copy(unsigned long base, unsigned long count, void *dest)
static char default_sti_path[21] __read_mostly;
#ifndef MODULE
-static int sti_setup(char *str)
+static int __init sti_setup(char *str)
{
if (str)
strlcpy (default_sti_path, str, sizeof (default_sti_path));
@@ -941,7 +941,7 @@ static void sticore_check_for_default_sti(struct sti_struct *sti, char *path)
* in the additional address field addr[1] while on
* older Systems the PDC stores it in page0->proc_sti
*/
-static int sticore_pa_init(struct parisc_device *dev)
+static int __init sticore_pa_init(struct parisc_device *dev)
{
char pa_path[21];
struct sti_struct *sti = NULL;
@@ -1009,7 +1009,7 @@ static int sticore_pci_init(struct pci_dev *pd, const struct pci_device_id *ent)
}
-static void sticore_pci_remove(struct pci_dev *pd)
+static void __exit sticore_pci_remove(struct pci_dev *pd)
{
BUG();
}
@@ -1029,7 +1029,7 @@ static struct pci_driver pci_sti_driver = {
.name = "sti",
.id_table = sti_pci_tbl,
.probe = sticore_pci_init,
- .remove = sticore_pci_remove,
+ .remove = __exit_p(sticore_pci_remove),
};
static struct parisc_device_id sti_pa_tbl[] = {
@@ -1037,8 +1037,9 @@ static struct parisc_device_id sti_pa_tbl[] = {
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00085 },
{ 0, }
};
+MODULE_DEVICE_TABLE(parisc, sti_pa_tbl);
-static struct parisc_driver pa_sti_driver = {
+static struct parisc_driver pa_sti_driver __refdata = {
.name = "sti",
.id_table = sti_pa_tbl,
.probe = sticore_pa_init,
diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
index 7a42238..25e862c 100644
--- a/drivers/video/fbdev/core/fbmem.c
+++ b/drivers/video/fbdev/core/fbmem.c
@@ -32,6 +32,7 @@
#include <linux/device.h>
#include <linux/efi.h>
#include <linux/fb.h>
+#include <linux/mem_encrypt.h>
#include <asm/fb.h>
@@ -1396,6 +1397,12 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
mutex_lock(&info->mm_lock);
if (fb->fb_mmap) {
int res;
+
+ /*
+ * The framebuffer needs to be accessed decrypted, be sure
+ * SME protection is removed ahead of the call
+ */
+ vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
res = fb->fb_mmap(info, vma);
mutex_unlock(&info->mm_lock);
return res;
@@ -1421,6 +1428,11 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
mutex_unlock(&info->mm_lock);
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+ /*
+ * The framebuffer needs to be accessed decrypted, be sure
+ * SME protection is removed
+ */
+ vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
fb_pgprotect(file, vma, start);
return vm_iomap_memory(vma, start, len);
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c b/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
index 156a254..ec78d61 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
@@ -664,7 +664,7 @@ static int hdmi_audio_register(struct device *dev)
{
struct omap_hdmi_audio_pdata pdata = {
.dev = dev,
- .dss_version = omapdss_get_version(),
+ .version = 4,
.audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp),
.ops = &hdmi_audio_ops,
};
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c b/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c
index 4da36bc..2e2fcc3 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c
@@ -695,7 +695,7 @@ static int hdmi_audio_register(struct device *dev)
{
struct omap_hdmi_audio_pdata pdata = {
.dev = dev,
- .dss_version = omapdss_get_version(),
+ .version = 5,
.audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp),
.ops = &hdmi_audio_ops,
};
diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c
index dc0e8d9..6f8c0b9 100644
--- a/drivers/video/fbdev/uvesafb.c
+++ b/drivers/video/fbdev/uvesafb.c
@@ -1860,19 +1860,18 @@ static int uvesafb_setup(char *options)
}
#endif /* !MODULE */
-static ssize_t show_v86d(struct device_driver *dev, char *buf)
+static ssize_t v86d_show(struct device_driver *dev, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%s\n", v86d_path);
}
-static ssize_t store_v86d(struct device_driver *dev, const char *buf,
+static ssize_t v86d_store(struct device_driver *dev, const char *buf,
size_t count)
{
strncpy(v86d_path, buf, PATH_MAX);
return count;
}
-
-static DRIVER_ATTR(v86d, S_IRUGO | S_IWUSR, show_v86d, store_v86d);
+static DRIVER_ATTR_RW(v86d);
static int uvesafb_init(void)
{
diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
index 623f723..cff773f 100644
--- a/drivers/virtio/Kconfig
+++ b/drivers/virtio/Kconfig
@@ -2,8 +2,8 @@ config VIRTIO
tristate
---help---
This option is selected by any driver which implements the virtio
- bus, such as CONFIG_VIRTIO_PCI, CONFIG_VIRTIO_MMIO, CONFIG_LGUEST,
- CONFIG_RPMSG or CONFIG_S390_GUEST.
+ bus, such as CONFIG_VIRTIO_PCI, CONFIG_VIRTIO_MMIO, CONFIG_RPMSG
+ or CONFIG_S390_GUEST.
menu "Virtio drivers"
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index 2d43118..1ab4bd1 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -1653,10 +1653,8 @@ void xen_callback_vector(void)
return;
}
pr_info("Xen HVM callback vector for event delivery is enabled\n");
- /* in the restore case the vector has already been allocated */
- if (!test_bit(HYPERVISOR_CALLBACK_VECTOR, used_vectors))
- alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR,
- xen_hvm_callback_vector);
+ alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR,
+ xen_hvm_callback_vector);
}
}
#else
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
index f3bf8f4..8236059 100644
--- a/drivers/xen/gntdev.c
+++ b/drivers/xen/gntdev.c
@@ -484,13 +484,6 @@ static void mn_invl_range_start(struct mmu_notifier *mn,
mutex_unlock(&priv->lock);
}
-static void mn_invl_page(struct mmu_notifier *mn,
- struct mm_struct *mm,
- unsigned long address)
-{
- mn_invl_range_start(mn, mm, address, address + PAGE_SIZE);
-}
-
static void mn_release(struct mmu_notifier *mn,
struct mm_struct *mm)
{
@@ -522,7 +515,6 @@ static void mn_release(struct mmu_notifier *mn,
static const struct mmu_notifier_ops gntdev_mmu_ops = {
.release = mn_release,
- .invalidate_page = mn_invl_page,
.invalidate_range_start = mn_invl_range_start,
};
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c
index 6331a95..9e480fd 100644
--- a/drivers/xen/xen-pciback/pci_stub.c
+++ b/drivers/xen/xen-pciback/pci_stub.c
@@ -1172,8 +1172,8 @@ out:
return err;
}
-static ssize_t pcistub_slot_add(struct device_driver *drv, const char *buf,
- size_t count)
+static ssize_t new_slot_store(struct device_driver *drv, const char *buf,
+ size_t count)
{
int domain, bus, slot, func;
int err;
@@ -1189,10 +1189,10 @@ out:
err = count;
return err;
}
-static DRIVER_ATTR(new_slot, S_IWUSR, NULL, pcistub_slot_add);
+static DRIVER_ATTR_WO(new_slot);
-static ssize_t pcistub_slot_remove(struct device_driver *drv, const char *buf,
- size_t count)
+static ssize_t remove_slot_store(struct device_driver *drv, const char *buf,
+ size_t count)
{
int domain, bus, slot, func;
int err;
@@ -1208,9 +1208,9 @@ out:
err = count;
return err;
}
-static DRIVER_ATTR(remove_slot, S_IWUSR, NULL, pcistub_slot_remove);
+static DRIVER_ATTR_WO(remove_slot);
-static ssize_t pcistub_slot_show(struct device_driver *drv, char *buf)
+static ssize_t slots_show(struct device_driver *drv, char *buf)
{
struct pcistub_device_id *pci_dev_id;
size_t count = 0;
@@ -1231,9 +1231,9 @@ static ssize_t pcistub_slot_show(struct device_driver *drv, char *buf)
return count;
}
-static DRIVER_ATTR(slots, S_IRUSR, pcistub_slot_show, NULL);
+static DRIVER_ATTR_RO(slots);
-static ssize_t pcistub_irq_handler_show(struct device_driver *drv, char *buf)
+static ssize_t irq_handlers_show(struct device_driver *drv, char *buf)
{
struct pcistub_device *psdev;
struct xen_pcibk_dev_data *dev_data;
@@ -1260,11 +1260,10 @@ static ssize_t pcistub_irq_handler_show(struct device_driver *drv, char *buf)
spin_unlock_irqrestore(&pcistub_devices_lock, flags);
return count;
}
-static DRIVER_ATTR(irq_handlers, S_IRUSR, pcistub_irq_handler_show, NULL);
+static DRIVER_ATTR_RO(irq_handlers);
-static ssize_t pcistub_irq_handler_switch(struct device_driver *drv,
- const char *buf,
- size_t count)
+static ssize_t irq_handler_state_store(struct device_driver *drv,
+ const char *buf, size_t count)
{
struct pcistub_device *psdev;
struct xen_pcibk_dev_data *dev_data;
@@ -1301,11 +1300,10 @@ out:
err = count;
return err;
}
-static DRIVER_ATTR(irq_handler_state, S_IWUSR, NULL,
- pcistub_irq_handler_switch);
+static DRIVER_ATTR_WO(irq_handler_state);
-static ssize_t pcistub_quirk_add(struct device_driver *drv, const char *buf,
- size_t count)
+static ssize_t quirks_store(struct device_driver *drv, const char *buf,
+ size_t count)
{
int domain, bus, slot, func, reg, size, mask;
int err;
@@ -1323,7 +1321,7 @@ out:
return err;
}
-static ssize_t pcistub_quirk_show(struct device_driver *drv, char *buf)
+static ssize_t quirks_show(struct device_driver *drv, char *buf)
{
int count = 0;
unsigned long flags;
@@ -1366,11 +1364,10 @@ out:
return count;
}
-static DRIVER_ATTR(quirks, S_IRUSR | S_IWUSR, pcistub_quirk_show,
- pcistub_quirk_add);
+static DRIVER_ATTR_RW(quirks);
-static ssize_t permissive_add(struct device_driver *drv, const char *buf,
- size_t count)
+static ssize_t permissive_store(struct device_driver *drv, const char *buf,
+ size_t count)
{
int domain, bus, slot, func;
int err;
@@ -1431,8 +1428,7 @@ static ssize_t permissive_show(struct device_driver *drv, char *buf)
spin_unlock_irqrestore(&pcistub_devices_lock, flags);
return count;
}
-static DRIVER_ATTR(permissive, S_IRUSR | S_IWUSR, permissive_show,
- permissive_add);
+static DRIVER_ATTR_RW(permissive);
static void pcistub_exit(void)
{
OpenPOWER on IntegriCloud